From 7a64c4b29bd8e08ee91185a111a38005a64f924c Mon Sep 17 00:00:00 2001 From: Leonardo Lontra Date: Sun, 3 Apr 2016 22:37:03 -0300 Subject: [PATCH 01/26] sunxi_wdt: change pr_info("%s, write reg 0x%08x\n", __func__, (u32)&wdt_reg->ctrl); and pr_info("%s, write 0x%08x to mode reg 0x%08x, actual timeout %d sec\n", __func__, temp, (u32)&wdt_reg->mode, temp2); to pr_debug (causing flood on kern.log) gc2035.c: framerate to 15fps --- build/sun8iw7p1smp_lobo_defconfig | 361 +- build/sun8iw7p1smp_lobo_defconfig.old | 365 +- build/sun8iw7p1smp_lobo_defconfig.old- | 3263 +++++++++++++++++ build_linux_kernel.sh | 8 +- build_mali_driver.sh | 6 +- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 368 +- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35517 -> 35565 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 242 +- .../arm/mach-sunxi/power/brom/resumes.map | 10 +- .../media/video/sunxi-vfe/device/camera.h | 1 + .../media/video/sunxi-vfe/device/gc2035.c | 352 +- .../drivers/net/ethernet/sunxi/eth/Kconfig | 8 - .../net/ethernet/sunxi/eth/sunxi_geth.c | 37 +- linux-3.4/drivers/watchdog/sunxi_wdt.c | 9 +- .../src/devicedrv/mali/.tmp_versions/mali.mod | 4 +- .../driver/src/devicedrv/mali/Module.symvers | 42 +- .../src/devicedrv/ump/.tmp_versions/ump.mod | 4 +- .../driver/src/devicedrv/ump/Module.symvers | 18 +- .../mali_drm/.tmp_versions/mali_drm.mod | 4 +- 19 files changed, 3687 insertions(+), 1415 deletions(-) create mode 100644 build/sun8iw7p1smp_lobo_defconfig.old- diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 0d518cb3..c4629549 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 3.4.39-01-lobo Kernel Configuration +# Linux/arm 3.4.39-02-lobo Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=8 initcall_debug=0 console=ttyS0,115200 console=tty0 init=/init" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -620,9 +620,7 @@ CONFIG_IP_MULTIPLE_TABLES=y # CONFIG_IP_ROUTE_VERBOSE is not set # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y -# CONFIG_NET_IPGRE_BROADCAST is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set @@ -755,7 +753,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y # CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ECN=y # CONFIG_NETFILTER_XT_MATCH_ESP is not set -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=y CONFIG_NETFILTER_XT_MATCH_HL=y CONFIG_NETFILTER_XT_MATCH_IPRANGE=y @@ -1143,45 +1141,9 @@ CONFIG_EEPROM_93CX6=m # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=m @@ -1206,7 +1168,6 @@ CONFIG_DM_RAID=m # CONFIG_DM_UEVENT is not set # CONFIG_DM_FLAKEY is not set # CONFIG_DM_VERITY is not set -# CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_NET_CORE=y # CONFIG_BONDING is not set @@ -1277,7 +1238,6 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y @@ -1902,7 +1862,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=y +CONFIG_SUNXI_WDT=m # # USB-based Watchdog Cards @@ -1981,9 +1941,8 @@ CONFIG_MEDIA_SUPPORT=y # CONFIG_MEDIA_CONTROLLER is not set CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_DVB_CORE=m -# CONFIG_DVB_NET is not set -CONFIG_VIDEO_MEDIA=m +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y # # Multimedia drivers @@ -1991,15 +1950,15 @@ CONFIG_VIDEO_MEDIA=m CONFIG_RC_CORE=y CONFIG_LIRC=y CONFIG_RC_MAP=y -CONFIG_IR_NEC_DECODER=y -CONFIG_IR_RC5_DECODER=y -CONFIG_IR_RC6_DECODER=y -CONFIG_IR_JVC_DECODER=y -CONFIG_IR_SONY_DECODER=y -CONFIG_IR_RC5_SZ_DECODER=y -CONFIG_IR_SANYO_DECODER=y -CONFIG_IR_MCE_KBD_DECODER=y -CONFIG_IR_LIRC_CODEC=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set # CONFIG_RC_ATI_REMOTE is not set # CONFIG_IR_IMON is not set # CONFIG_IR_MCEUSB is not set @@ -2008,7 +1967,7 @@ CONFIG_IR_LIRC_CODEC=y # CONFIG_RC_LOOPBACK is not set # CONFIG_IR_GPIO_CIR is not set # CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER=y CONFIG_MEDIA_TUNER_CUSTOMISE=y # @@ -2039,7 +1998,6 @@ CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_VIDEO_V4L2=y CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_TVEEPROM=m CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set @@ -2137,57 +2095,10 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y CONFIG_V4L_USB_DRIVERS=y CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_GL860=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_GSPCA is not set # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_TLG2300 is not set # CONFIG_VIDEO_CX231XX is not set # CONFIG_VIDEO_TM6000 is not set # CONFIG_VIDEO_USBVISION is not set @@ -2205,216 +2116,7 @@ CONFIG_VIDEO_SUNXI_VFE=m CONFIG_CSI_VFE=m # CONFIG_V4L_MEM2MEM_DRIVERS is not set CONFIG_AW_TSC=y -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_KEENE is not set -# CONFIG_RADIO_TEA5764 is not set -# CONFIG_RADIO_SAA7706H is not set -# CONFIG_RADIO_TEF6862 is not set -# CONFIG_RADIO_WL1273 is not set - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_DVB_MAX_ADAPTERS=8 -# CONFIG_DVB_DYNAMIC_MINORS is not set -CONFIG_DVB_CAPTURE_DRIVERS=y -CONFIG_TTPCI_EEPROM=m - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_FRIIO=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_IT913X=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_SMS_SIANO_MDTV=m - -# -# Siano module components -# -# CONFIG_SMS_USB_DRV is not set -# CONFIG_SMS_SDIO_DRV is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported DVB Frontends -# -CONFIG_DVB_FE_CUSTOMISE=y - -# -# Customise DVB Frontends -# - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_MB86A16=m -CONFIG_DVB_TDA10071=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_S5H1432=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DIB9000=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_EC100=m -CONFIG_DVB_HD29L2=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_RTL2830=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6405=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_LGS8GL5=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_IT913X_FE=m -CONFIG_DVB_M88RS2000=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_RADIO_ADAPTERS is not set CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y # @@ -2690,29 +2392,12 @@ CONFIG_USB_ACM=m # # also be needed; see USB_STORAGE Help for more info # -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_REALTEK=y -CONFIG_REALTEK_AUTOPM=y -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_ONETOUCH=y -CONFIG_USB_STORAGE_KARMA=y -CONFIG_USB_STORAGE_CYPRESS_ATACB=y -CONFIG_USB_STORAGE_ENE_UB6250=y # CONFIG_USB_LIBUSUAL is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set # # USB port drivers @@ -3084,9 +2769,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 32e22f63..c4629549 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 3.4.39-01-lobo Kernel Configuration +# Linux/arm 3.4.39-02-lobo Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=8 initcall_debug=0 console=ttyS0,115200 console=tty0 init=/init" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -620,9 +620,7 @@ CONFIG_IP_MULTIPLE_TABLES=y # CONFIG_IP_ROUTE_VERBOSE is not set # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y -# CONFIG_NET_IPGRE_BROADCAST is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set @@ -755,7 +753,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y # CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ECN=y # CONFIG_NETFILTER_XT_MATCH_ESP is not set -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=y CONFIG_NETFILTER_XT_MATCH_HL=y CONFIG_NETFILTER_XT_MATCH_IPRANGE=y @@ -1143,45 +1141,9 @@ CONFIG_EEPROM_93CX6=m # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=m @@ -1196,17 +1158,16 @@ CONFIG_MD_MULTIPATH=m CONFIG_BLK_DEV_DM=y # CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=y -# CONFIG_DM_SNAPSHOT is not set +CONFIG_DM_SNAPSHOT=m # CONFIG_DM_THIN_PROVISIONING is not set # CONFIG_DM_MIRROR is not set -# CONFIG_DM_RAID is not set +CONFIG_DM_RAID=m # CONFIG_DM_ZERO is not set # CONFIG_DM_MULTIPATH is not set # CONFIG_DM_DELAY is not set # CONFIG_DM_UEVENT is not set # CONFIG_DM_FLAKEY is not set # CONFIG_DM_VERITY is not set -# CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_NET_CORE=y # CONFIG_BONDING is not set @@ -1277,7 +1238,6 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y @@ -1902,7 +1862,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=y +CONFIG_SUNXI_WDT=m # # USB-based Watchdog Cards @@ -1981,9 +1941,8 @@ CONFIG_MEDIA_SUPPORT=y # CONFIG_MEDIA_CONTROLLER is not set CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_DVB_CORE=m -# CONFIG_DVB_NET is not set -CONFIG_VIDEO_MEDIA=m +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y # # Multimedia drivers @@ -1991,15 +1950,15 @@ CONFIG_VIDEO_MEDIA=m CONFIG_RC_CORE=y CONFIG_LIRC=y CONFIG_RC_MAP=y -CONFIG_IR_NEC_DECODER=y -CONFIG_IR_RC5_DECODER=y -CONFIG_IR_RC6_DECODER=y -CONFIG_IR_JVC_DECODER=y -CONFIG_IR_SONY_DECODER=y -CONFIG_IR_RC5_SZ_DECODER=y -CONFIG_IR_SANYO_DECODER=y -CONFIG_IR_MCE_KBD_DECODER=y -CONFIG_IR_LIRC_CODEC=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set # CONFIG_RC_ATI_REMOTE is not set # CONFIG_IR_IMON is not set # CONFIG_IR_MCEUSB is not set @@ -2008,7 +1967,7 @@ CONFIG_IR_LIRC_CODEC=y # CONFIG_RC_LOOPBACK is not set # CONFIG_IR_GPIO_CIR is not set # CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER=y CONFIG_MEDIA_TUNER_CUSTOMISE=y # @@ -2039,7 +1998,6 @@ CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_VIDEO_V4L2=y CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_TVEEPROM=m CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set @@ -2137,57 +2095,10 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y CONFIG_V4L_USB_DRIVERS=y CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_GL860=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_GSPCA is not set # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_TLG2300 is not set # CONFIG_VIDEO_CX231XX is not set # CONFIG_VIDEO_TM6000 is not set # CONFIG_VIDEO_USBVISION is not set @@ -2205,216 +2116,7 @@ CONFIG_VIDEO_SUNXI_VFE=m CONFIG_CSI_VFE=m # CONFIG_V4L_MEM2MEM_DRIVERS is not set CONFIG_AW_TSC=y -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_KEENE is not set -# CONFIG_RADIO_TEA5764 is not set -# CONFIG_RADIO_SAA7706H is not set -# CONFIG_RADIO_TEF6862 is not set -# CONFIG_RADIO_WL1273 is not set - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_DVB_MAX_ADAPTERS=8 -# CONFIG_DVB_DYNAMIC_MINORS is not set -CONFIG_DVB_CAPTURE_DRIVERS=y -CONFIG_TTPCI_EEPROM=m - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_FRIIO=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_IT913X=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_SMS_SIANO_MDTV=m - -# -# Siano module components -# -# CONFIG_SMS_USB_DRV is not set -# CONFIG_SMS_SDIO_DRV is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported DVB Frontends -# -CONFIG_DVB_FE_CUSTOMISE=y - -# -# Customise DVB Frontends -# - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_MB86A16=m -CONFIG_DVB_TDA10071=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_S5H1432=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DIB9000=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_EC100=m -CONFIG_DVB_HD29L2=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_RTL2830=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6405=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_LGS8GL5=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_IT913X_FE=m -CONFIG_DVB_M88RS2000=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_RADIO_ADAPTERS is not set CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y # @@ -2690,29 +2392,12 @@ CONFIG_USB_ACM=m # # also be needed; see USB_STORAGE Help for more info # -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_REALTEK=y -CONFIG_REALTEK_AUTOPM=y -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_ONETOUCH=y -CONFIG_USB_STORAGE_KARMA=y -CONFIG_USB_STORAGE_CYPRESS_ATACB=y -CONFIG_USB_STORAGE_ENE_UB6250=y # CONFIG_USB_LIBUSUAL is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set # # USB port drivers @@ -3084,9 +2769,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y diff --git a/build/sun8iw7p1smp_lobo_defconfig.old- b/build/sun8iw7p1smp_lobo_defconfig.old- new file mode 100644 index 00000000..3049fa80 --- /dev/null +++ b/build/sun8iw7p1smp_lobo_defconfig.old- @@ -0,0 +1,3263 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.4.39-02-lobo Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_NEED_MACH_IO_H=y +CONFIG_NEED_MACH_MEMORY_H=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="sun8i" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_FHANDLE=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y +# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y +CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="output/rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=0 +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# System MMU +# +CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 +CONFIG_ARCH_SUN8I=y +# CONFIG_ARCH_SUN9I is not set +# CONFIG_ARCH_SUN8IW1 is not set +# CONFIG_ARCH_SUN8IW3 is not set +# CONFIG_ARCH_SUN8IW5 is not set +# CONFIG_ARCH_SUN8IW6 is not set +CONFIG_ARCH_SUN8IW7=y +# CONFIG_ARCH_SUN8IW8 is not set +# CONFIG_ARCH_SUN8IW9 is not set +CONFIG_ARCH_SUN8IW7P1=y +# CONFIG_FPGA_V4_PLATFORM is not set +# CONFIG_FPGA_V7_PLATFORM is not set +CONFIG_EVB_PLATFORM=y + +# +# Power management +# + +# +# Common Features Selection +# + +# +# Boot Options +# +# CONFIG_SUNXI_TRUSTZONE is not set +CONFIG_HOMLET_PLATFORM=y +# CONFIG_SUNXI_BOOTUP_EXTEND is not set +CONFIG_SUNXI_OOPS_HOOK=y + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +CONFIG_ARM_GIC=y +# CONFIG_FIQ_DEBUGGER is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_NR_GPIO=2048 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y + +# +# Boot options +# +# CONFIG_USE_OF is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +# CONFIG_CMDLINE_EXTEND is not set +CONFIG_CMDLINE_FORCE=y +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y + +# +# ARM CPU frequency scaling drivers +# +CONFIG_ARM_SUNXI_CPUFREQ=y +# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set +# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_WAKELOCK is not set +CONFIG_SCENELOCK=y +CONFIG_USER_SCENELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_APM_EMULATION=y +CONFIG_PM_CLK=y +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE_DEMUX=y +CONFIG_NET_IPGRE=y +# CONFIG_NET_IPGRE_BROADCAST is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +# CONFIG_IPV6_ROUTE_INFO is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_NET_ACTIVITY_STATS=y +CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_BROADCAST=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ECN=y +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=y +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_NF_NAT_PROTO_DCCP=y +CONFIG_NF_NAT_PROTO_GRE=y +CONFIG_NF_NAT_PROTO_UDPLITE=y +CONFIG_NF_NAT_PROTO_SCTP=y +CONFIG_NF_NAT_FTP=y +CONFIG_NF_NAT_IRC=y +CONFIG_NF_NAT_TFTP=y +CONFIG_NF_NAT_AMANDA=y +CONFIG_NF_NAT_PPTP=y +CONFIG_NF_NAT_H323=y +# CONFIG_NF_NAT_SIP is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=y +# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +CONFIG_NET_SCH_HTB=y +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_INGRESS is not set +# CONFIG_NET_SCH_PLUG is not set + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_U32=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +# CONFIG_NET_EMATCH_CMP is not set +# CONFIG_NET_EMATCH_NBYTE is not set +# CONFIG_NET_EMATCH_U32 is not set +# CONFIG_NET_EMATCH_META is not set +# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_GACT is not set +# CONFIG_NET_ACT_MIRRED is not set +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_NETPRIO_CGROUP is not set +CONFIG_BQL=y +CONFIG_HAVE_BPF_JIT=y +# CONFIG_BPF_JIT is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_RTKH5=y +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_BCM_BT_LPM=m +CONFIG_RTL_BT_LPM=m +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# +CONFIG_SUNXI_ARISC=y + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_RESERVE_BASE=0x43400000 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=0 +CONFIG_CMA_AREAS=7 +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +# CONFIG_SW_SYNC_USER is not set + +# +# Bus devices +# +CONFIG_SUNXI_MBUS=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SUNXI_VIBRATOR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +CONFIG_UID_STAT=y +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SUNXI_BROM_READ is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +# CONFIG_SW_3G_MODULE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MULTICORE_RAID456 is not set +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=m +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_MIRROR is not set +CONFIG_DM_RAID=m +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +CONFIG_MII=y +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +CONFIG_VETH=m + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_NET_VENDOR_SUNXI=y +CONFIG_SUNXI_GETH=y +CONFIG_GETH_SCRIPT_SYS=y +CONFIG_GETH_CLK_SYS=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPTP=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_QF9700=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=m +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_RTL8187=m +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +# CONFIG_ATH_COMMON is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BCMDHD=m +CONFIG_BCMDHD_FW_PATH=y +CONFIG_BCMDHD_NVRAM_PATH=y +CONFIG_BCMDHD_CONFIG_PATH=y +CONFIG_BCMDHD_OOB=y +# CONFIG_BCMDHD_SDIO_IRQ is not set +# CONFIG_AP6210 is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +# CONFIG_RT2500USB is not set +# CONFIG_RT73USB is not set +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_DEBUG=y +CONFIG_RTL8192C_COMMON=m +# CONFIG_WL1251 is not set +# CONFIG_WL12XX_MENU is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +CONFIG_RTL8188EU=m +CONFIG_RTL8189ES=m +CONFIG_RTL8723BS=m + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_APMPOWER is not set +# CONFIG_INPUT_KEYRESET is not set +CONFIG_INPUT_SW_DEVICE=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_SUNXI=y +CONFIG_IR_RX_SUNXI=m +# CONFIG_SUNXI_ANYIR_SUPPORT is not set +# CONFIG_IR_TX_SUNXI is not set +# CONFIG_SUNXI_GPIO_KEY is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_TOUCHSCREEN_GT82X=m +# CONFIG_TOUCHSCREEN_SUN6I_TS is not set +CONFIG_TOUCHSCREEN_FT5X_TS=m +CONFIG_TOUCHSCREEN_GT9XX_TS=m +CONFIG_TOUCHSCREEN_GT9XXF_TS=m +CONFIG_TOUCHSCREEN_GSLX680=m +CONFIG_TOUCHSCREEN_GSLX680NEW=m +CONFIG_TOUCHSCREEN_AW5X06_TS=m +CONFIG_TOUCHSCREEN_GT818_TS=m +CONFIG_TOUCHSCREEN_TU_TS=m +CONFIG_TOUCHSCREEN_ICN83XX_TS=m +CONFIG_INPUT_MISC=y +# CONFIG_E_COMPASS_L3M303D is not set +# CONFIG_E_COMPASS_FXOS8700 is not set +# CONFIG_E_COMPASS_AKM8963 is not set +# CONFIG_GYR_L3GD20 is not set +# CONFIG_GYR_BMG160 is not set +CONFIG_INPUT_LTR501ALS=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_CMA3000 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +CONFIG_SERIAL_SUNXI=y +CONFIG_SERIAL_SUNXI_CONSOLE=y +# CONFIG_SERIAL_DEBUG is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_RAMOOPS is not set +# CONFIG_SUNXI_D7S is not set +CONFIG_SUNXI_CMATESET=y +# CONFIG_SUNXI_ARISC_TEST is not set +# CONFIG_SUNXI_MODULE is not set +# CONFIG_SUNXI_TIMER_TEST is not set +# CONFIG_SUNXI_DMA_TEST is not set +CONFIG_SUNXI_SCR=m +CONFIG_SUNXI_DI=m +CONFIG_SUNXI_SOC_INFO=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_SUNXI=y +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_SUNXI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUNXI_DEBUG is not set +# CONFIG_SUNXI_PINCTRL_TEST is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_GPIO_SUNXI=m +CONFIG_W1=m +CONFIG_W1_SUNXI=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_KIONIX is not set +# CONFIG_SENSORS_MMA7660 is not set +# CONFIG_SENSORS_MMA865x is not set +# CONFIG_SENSORS_MMA8452 is not set +# CONFIG_SENSORS_AFA750 is not set +# CONFIG_SENSORS_BMA250 is not set +# CONFIG_SENSORS_LIS3DH_ACC is not set +# CONFIG_SENSORS_LIS3DE_ACC is not set +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set + +# +# INA219 drivers +# +# CONFIG_SENSORS_INA219 is not set +# CONFIG_SENSORS_DUMMY_ACC is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_FAIR_SHARE is not set +CONFIG_STEP_WISE=y +# CONFIG_USER_SPACE is not set +# CONFIG_SUNXI_THERMAL_DYNAMIC is not set +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_BUDGET_THERMAL=y +CONFIG_SUNXI_THERMAL=y +CONFIG_SUNXI_BUDGET_COOLING=y +# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_SUNXI_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_AC100 is not set +# CONFIG_MFD_AC200 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_REGULATOR is not set +CONFIG_PWM=y +CONFIG_PWM_SUNXI=m +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_MAP=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_CUSTOMISE=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +# CONFIG_VIDEO_IR_I2C is not set + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_AK881X is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SR030PC30 is not set + +# +# Flash devices +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_VIDEO_SUNXI_VFE=m +CONFIG_CSI_VFE=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_AW_TSC=y +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_USB_KEENE is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +# CONFIG_RADIO_WL1273 is not set + +# +# Texas Instruments WL128x FM driver (ST based) +# +CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_UDL is not set +CONFIG_ION=y +CONFIG_ION_SUNXI=y +CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# + +# +# Video support for sunxi +# +CONFIG_FB_CONSOLE_SUNXI=y +CONFIG_DISP2_SUNXI=y +CONFIG_HDMI_DISP2_SUNXI=y +CONFIG_TV_DISP2_SUNXI=m +# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set +CONFIG_DISP2_SUNXI_DEBUG=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y +CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y +CONFIG_SND_SUN8IW7_SNDCODEC=y +# CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE is not set +CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y +CONFIG_SND_SUN8IW7_HDMIPCM=y +CONFIG_SND_SUNXI_SOC_SPDIF=m +# CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE is not set +# CONFIG_SND_SUN8IW7_AUDIOHUB is not set +# CONFIG_SND_SUNXI_SOC_SUPPORT_AUDIO_RAW is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_UHID=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_REMOTE_WAKEUP is not set +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +CONFIG_HID_PRODIKEYS=y +# CONFIG_HID_CYPRESS is not set +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EMS_FF=y +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_EZKEY is not set +CONFIG_HID_HOLTEK=y +# CONFIG_HOLTEK_FF is not set +CONFIG_HID_KEYTOUCH=y +# CONFIG_HID_KYE is not set +CONFIG_HID_UCLOGIC=y +CONFIG_HID_WALTOP=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LCPOWER=y +CONFIG_HID_LOGITECH=y +# CONFIG_HID_LOGITECH_DJ is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIWHEELS_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +CONFIG_HID_PRIMAX=y +CONFIG_HID_ROCCAT=y +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SPEEDLINK=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +# CONFIG_HID_TIVO is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set +CONFIG_HID_ZYDACRON=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_SUNXI is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_SUNXI_HCD=y +CONFIG_USB_SUNXI_HCD0=y +CONFIG_USB_SUNXI_HCI=y +CONFIG_USB_SUNXI_EHCI0=y +CONFIG_USB_SUNXI_EHCI1=y +CONFIG_USB_SUNXI_OHCI0=y +CONFIG_USB_SUNXI_OHCI1=y +CONFIG_USB_SUNXI_EHCI2=y +CONFIG_USB_SUNXI_OHCI2=y +CONFIG_USB_SUNXI_EHCI3=y +CONFIG_USB_SUNXI_OHCI3=y +CONFIG_USB_SUNXI_HSIC=y +# CONFIG_SW_USB_3G is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_SUNXI_UDC0=y +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_SUNXI_USB=y +CONFIG_USB_SUNXI_USB_MANAGER=y +# CONFIG_USB_SUNXI_USB0_NULL is not set +# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set +# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set +CONFIG_USB_SUNXI_USB0_OTG=y +CONFIG_USB_SUNXI_USB_DEBUG=y +CONFIG_USB_SUNXI_HOST=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +# CONFIG_MMC_CLKGATE is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_DW is not set +CONFIG_MMC_SUNXI=y +# CONFIG_MMC_DEBUG_SUNXI is not set +CONFIG_MMC_PRE_DBGLVL_SUNXI=0 +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_SUNXI_LEDS=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_OT200 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SUNXI=y +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +CONFIG_SUNXI_DMA=y +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y +CONFIG_COMMON_CLK_DEBUG=y + +# +# SUNXI Clock Configuration +# +CONFIG_SUNXI_CLK_DEFAULT_INIT=y +CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y +CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 +CONFIG_AHB1_CLK_DFT_VALUE=200000000 +CONFIG_APB1_CLK_DFT_VALUE=100000000 + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_MMIO=y +CONFIG_SUNXI_TIMER=y +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_DRAM_FREQ=y +# CONFIG_DRAM_FREQ_BSP_TEST is not set +# CONFIG_GATOR_PERF is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=y +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFS_FSCACHE is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_FAULT_INJECTION=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_FSCACHE is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=20 +CONFIG_RCU_CPU_STALL_VERBOSE=y +CONFIG_RCU_CPU_STALL_INFO=y +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_ASYNC_RAID6_TEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +# CONFIG_TEST_KSTRTOX is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_RODATA is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_SUNXI_UART0=y +# CONFIG_DEBUG_SUNXI_UART1 is not set +# CONFIG_DEBUG_SUNXI_UART2 is not set +# CONFIG_DEBUG_LL_UART_NONE is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +CONFIG_EARLY_PRINTK=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_TRUSTED_LITTLE_KERNEL is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_SUNXI=m +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_AVERAGE=y +# CONFIG_CORDIC is not set diff --git a/build_linux_kernel.sh b/build_linux_kernel.sh index 7e3b1351..3b3981ec 100755 --- a/build_linux_kernel.sh +++ b/build_linux_kernel.sh @@ -73,7 +73,7 @@ make_kernel() { echo "Building kernel for OPI-${1} (${2}) ..." echo " Configuring ..." - make ARCH=arm CROSS_COMPILE=${cross_comp}- sun8iw7p1smp_lobo_defconfig > ../kbuild_${1}_${2}.log 2>&1 + make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- sun8iw7p1smp_lobo_defconfig > ../kbuild_${1}_${2}.log 2>&1 if [ $? -ne 0 ]; then echo " Error: KERNEL NOT BUILT." exit 1 @@ -94,12 +94,12 @@ make_kernel() { # export modules to output echo " Exporting modules ..." rm -rf output/lib/* - make ARCH=arm CROSS_COMPILE=${cross_comp}- INSTALL_MOD_PATH=output modules_install >> ../kbuild_${1}_${2}.log 2>&1 + make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- INSTALL_MOD_PATH=output modules_install >> ../kbuild_${1}_${2}.log 2>&1 if [ $? -ne 0 ] || [ ! -f arch/arm/boot/uImage ]; then echo " Error." fi echo " Exporting firmware ..." - make ARCH=arm CROSS_COMPILE=${cross_comp}- INSTALL_MOD_PATH=output firmware_install >> ../kbuild_${1}_${2}.log 2>&1 + make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- INSTALL_MOD_PATH=output firmware_install >> ../kbuild_${1}_${2}.log 2>&1 if [ $? -ne 0 ] || [ ! -f arch/arm/boot/uImage ]; then echo " Error." fi @@ -132,7 +132,7 @@ make_kernel() { if [ "${1}" = "clean" ]; then echo "Cleaning..." - make ARCH=arm CROSS_COMPILE=${cross_comp}- mrproper > /dev/null 2>&1 + make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- mrproper > /dev/null 2>&1 if [ $? -ne 0 ]; then echo " Error." fi diff --git a/build_mali_driver.sh b/build_mali_driver.sh index 5e8bdf56..8a707475 100755 --- a/build_mali_driver.sh +++ b/build_mali_driver.sh @@ -33,17 +33,17 @@ export MOD_DIR=${LICHEE_KDIR}/output/lib/modules/${KERNEL_VERSION} export KDIR cd modules/mali -make ARCH=arm CROSS_COMPILE=${cross_comp}- clean >> ../malibuild.log 2>&1 +make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- clean >> ../malibuild.log 2>&1 if [ $? -ne 0 ]; then echo " Error: clean." exit 1 fi -make ARCH=arm CROSS_COMPILE=${cross_comp}- build >> ../malibuild.log 2>&1 +make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- build >> ../malibuild.log 2>&1 if [ $? -ne 0 ]; then echo " Error: build." exit 1 fi -make ARCH=arm CROSS_COMPILE=${cross_comp}- install >> ../malibuild.log 2>&1 +make -j $(nproc) ARCH=arm CROSS_COMPILE=${cross_comp}- install >> ../malibuild.log 2>&1 if [ $? -ne 0 ]; then echo " Error: install." exit 1 diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index 6cca9b89..c4629549 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 3.4.39-01-lobo Kernel Configuration +# Linux/arm 3.4.39-02-lobo Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=8 initcall_debug=0 console=ttyS0,115200 console=tty0 init=/init" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -620,9 +620,7 @@ CONFIG_IP_MULTIPLE_TABLES=y # CONFIG_IP_ROUTE_VERBOSE is not set # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y -# CONFIG_NET_IPGRE_BROADCAST is not set +# CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set @@ -755,7 +753,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y # CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ECN=y # CONFIG_NETFILTER_XT_MATCH_ESP is not set -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=y CONFIG_NETFILTER_XT_MATCH_HL=y CONFIG_NETFILTER_XT_MATCH_IPRANGE=y @@ -1143,45 +1141,9 @@ CONFIG_EEPROM_93CX6=m # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=m @@ -1206,7 +1168,6 @@ CONFIG_DM_RAID=m # CONFIG_DM_UEVENT is not set # CONFIG_DM_FLAKEY is not set # CONFIG_DM_VERITY is not set -# CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_NET_CORE=y # CONFIG_BONDING is not set @@ -1247,7 +1208,6 @@ CONFIG_NET_VENDOR_SUNXI=y CONFIG_SUNXI_GETH=y CONFIG_GETH_SCRIPT_SYS=y CONFIG_GETH_CLK_SYS=y -CONFIG_GMAC_PHY_POWER=y CONFIG_PHYLIB=y # @@ -1278,7 +1238,6 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPTP=y CONFIG_PPPOL2TP=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y @@ -1903,7 +1862,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=y +CONFIG_SUNXI_WDT=m # # USB-based Watchdog Cards @@ -1982,9 +1941,8 @@ CONFIG_MEDIA_SUPPORT=y # CONFIG_MEDIA_CONTROLLER is not set CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_DVB_CORE=m -# CONFIG_DVB_NET is not set -CONFIG_VIDEO_MEDIA=m +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y # # Multimedia drivers @@ -1992,15 +1950,15 @@ CONFIG_VIDEO_MEDIA=m CONFIG_RC_CORE=y CONFIG_LIRC=y CONFIG_RC_MAP=y -CONFIG_IR_NEC_DECODER=y -CONFIG_IR_RC5_DECODER=y -CONFIG_IR_RC6_DECODER=y -CONFIG_IR_JVC_DECODER=y -CONFIG_IR_SONY_DECODER=y -CONFIG_IR_RC5_SZ_DECODER=y -CONFIG_IR_SANYO_DECODER=y -CONFIG_IR_MCE_KBD_DECODER=y -CONFIG_IR_LIRC_CODEC=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set # CONFIG_RC_ATI_REMOTE is not set # CONFIG_IR_IMON is not set # CONFIG_IR_MCEUSB is not set @@ -2009,7 +1967,7 @@ CONFIG_IR_LIRC_CODEC=y # CONFIG_RC_LOOPBACK is not set # CONFIG_IR_GPIO_CIR is not set # CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER=y CONFIG_MEDIA_TUNER_CUSTOMISE=y # @@ -2040,7 +1998,6 @@ CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_VIDEO_V4L2=y CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_TVEEPROM=m CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set @@ -2138,57 +2095,10 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y CONFIG_V4L_USB_DRIVERS=y CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_GL860=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_GSPCA is not set # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_TLG2300 is not set # CONFIG_VIDEO_CX231XX is not set # CONFIG_VIDEO_TM6000 is not set # CONFIG_VIDEO_USBVISION is not set @@ -2206,216 +2116,7 @@ CONFIG_VIDEO_SUNXI_VFE=m CONFIG_CSI_VFE=m # CONFIG_V4L_MEM2MEM_DRIVERS is not set CONFIG_AW_TSC=y -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_KEENE is not set -# CONFIG_RADIO_TEA5764 is not set -# CONFIG_RADIO_SAA7706H is not set -# CONFIG_RADIO_TEF6862 is not set -# CONFIG_RADIO_WL1273 is not set - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_DVB_MAX_ADAPTERS=8 -# CONFIG_DVB_DYNAMIC_MINORS is not set -CONFIG_DVB_CAPTURE_DRIVERS=y -CONFIG_TTPCI_EEPROM=m - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_FRIIO=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_IT913X=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_SMS_SIANO_MDTV=m - -# -# Siano module components -# -# CONFIG_SMS_USB_DRV is not set -# CONFIG_SMS_SDIO_DRV is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported DVB Frontends -# -CONFIG_DVB_FE_CUSTOMISE=y - -# -# Customise DVB Frontends -# - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_MB86A16=m -CONFIG_DVB_TDA10071=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_S5H1432=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DIB9000=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_EC100=m -CONFIG_DVB_HD29L2=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_RTL2830=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6405=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_LGS8GL5=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_IT913X_FE=m -CONFIG_DVB_M88RS2000=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_RADIO_ADAPTERS is not set CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y # @@ -2665,12 +2366,12 @@ CONFIG_USB_SUNXI_HCD0=y CONFIG_USB_SUNXI_HCI=y CONFIG_USB_SUNXI_EHCI0=y CONFIG_USB_SUNXI_EHCI1=y -# CONFIG_USB_SUNXI_OHCI0 is not set +CONFIG_USB_SUNXI_OHCI0=y CONFIG_USB_SUNXI_OHCI1=y CONFIG_USB_SUNXI_EHCI2=y -# CONFIG_USB_SUNXI_OHCI2 is not set +CONFIG_USB_SUNXI_OHCI2=y CONFIG_USB_SUNXI_EHCI3=y -# CONFIG_USB_SUNXI_OHCI3 is not set +CONFIG_USB_SUNXI_OHCI3=y CONFIG_USB_SUNXI_HSIC=y # CONFIG_SW_USB_3G is not set # CONFIG_USB_MUSB_HDRC is not set @@ -2691,29 +2392,12 @@ CONFIG_USB_ACM=m # # also be needed; see USB_STORAGE Help for more info # -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_REALTEK=y -CONFIG_REALTEK_AUTOPM=y -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_USBAT=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_ONETOUCH=y -CONFIG_USB_STORAGE_KARMA=y -CONFIG_USB_STORAGE_CYPRESS_ATACB=y -CONFIG_USB_STORAGE_ENE_UB6250=y # CONFIG_USB_LIBUSUAL is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set # # USB port drivers @@ -3085,9 +2769,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 0ac1637ab6bbf5fc231d31d1703d76b87e444d9d..9a7be50dac11a2fa10c37622f772a32a843d3a18 100755 GIT binary patch delta 549 zcmdlxmFewNrU?p+Up6WpZ>ayvz`($m2qe}5@f|1zQVdLtZ1O;gnGHxVs+)sFIAlQ- z6RRsDh+@|SQYeSM(sF|JPW%%P=b{k$TncK`v;`h`arS{!5~>>2Da}Y zo+C(tDNUJ$O&+M4(Fr2S!)6JRbcXN**ye+HE)bpwn*)gF$_KJtS%OU)#B+o2WZ1$$ zJa-6Bfz21h^MLSF*lZ@BZPZha2HE443Y6jW2N|Ji4H94lJDp1o$Yz*2S+2>=GAA`Z zFR>^kU*9FQIJ+djKtDA%DK(`eKR-u5zbG*;J+&ayJGCe;HAmkc%nk6=h444GHl1VC zFU>2?OwUVAQAo~6EMiE@%t?*UNKH(MFDuSt$VtshFUepiC{2QkO`h43=&7HPpPQ;r zw#E86nR%rZy2g4Yn?+hhm>6$O)@)a1+&0;_U7gW$a%sCdt6vKPL*C?tK+!#ukG88b iDYQ*~*RIAGFZ-RZ>WFDz`(#*0VIro_zn~UDF!A+w#z_@nGHxVs+)sFI4*)H zCRSZW5XCMCq*z#3GxJIqn1K=ujM{M^c@}nYpad&7kZr(d_YX+1Ed|Ls1cPLi8QAWF zc#a?mrZi<1Hg=$DMkk0Q51Tef(iy@NVA}@bxj=X#Y)3#mS3Z#K$`Wj{Af6k9C&QKt z;<-b33T!DLo(F`d!lp9$Y@?pCGsqsVRGiJ z9-184uFN=Za&5ahqv7PG?dq&%Ees4{lP>~AdnSKvS7-XrI$5qmjZtH=Ylk|c$K+ff Qxn%NGAZfCBZ-)UB0FUi%B>(^b diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst index 8f148098..cb52a0e5 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst @@ -75,64 +75,64 @@ Disassembly of section .debug_info: 0: 0000013d andeq r0, r0, sp, lsr r1 4: 00000002 andeq r0, r0, r2 8: 01040000 mrseq r0, (UNDEF: 4) - c: 000000e5 andeq r0, r0, r5, ror #1 - 10: 00007801 andeq r7, r0, r1, lsl #16 - 14: 00003200 andeq r3, r0, r0, lsl #4 + c: 000000fd strdeq r0, [r0], -sp + 10: 00006101 andeq r6, r0, r1, lsl #2 + 14: 0000ad00 andeq sl, r0, r0, lsl #26 18: 0000dc00 andeq sp, r0, r0, lsl #24 1c: 0000dc00 andeq sp, r0, r0, lsl #24 20: 00000000 andeq r0, r0, r0 24: 06010200 streq r0, [r1], -r0, lsl #4 - 28: 000000d3 ldrdeq r0, [r0], -r3 + 28: 0000001f andeq r0, r0, pc, lsl r0 2c: 00000603 andeq r0, r0, r3, lsl #12 30: 37270100 strcc r0, [r7, -r0, lsl #2]! 34: 02000000 andeq r0, r0, #0 - 38: 00d10801 sbcseq r0, r1, r1, lsl #16 + 38: 001d0801 andseq r0, sp, r1, lsl #16 3c: 02020000 andeq r0, r2, #0 - 40: 00012d05 andeq r2, r1, r5, lsl #26 + 40: 00014505 andeq r4, r1, r5, lsl #10 44: 07020200 streq r0, [r2, -r0, lsl #4] - 48: 00000111 andeq r0, r0, r1, lsl r1 + 48: 00000129 andeq r0, r0, r9, lsr #2 4c: 69050404 stmdbvs r5, {r2, sl} 50: 0300746e movweq r7, #1134 ; 0x46e 54: 00000000 andeq r0, r0, r0 58: 005e2b01 subseq r2, lr, r1, lsl #22 5c: 04020000 streq r0, [r2], #-0 - 60: 00011707 andeq r1, r1, r7, lsl #14 + 60: 00012f07 andeq r2, r1, r7, lsl #30 64: 000b0500 andeq r0, fp, r0, lsl #10 68: 01300000 teqeq r0, r0 6c: 0000fe3e andeq pc, r0, lr, lsr lr ; - 70: 00a50600 adceq r0, r5, r0, lsl #12 + 70: 008e0600 addeq r0, lr, r0, lsl #12 74: 40010000 andmi r0, r1, r0 78: 00000053 andeq r0, r0, r3, asr r0 7c: 06002302 streq r2, [r0], -r2, lsl #6 - 80: 000000df ldrdeq r0, [r0], -pc ; + 80: 000000f7 strdeq r0, [r0], -r7 84: 00fe4101 rscseq r4, lr, r1, lsl #2 88: 23020000 movwcs r0, #8192 ; 0x2000 - 8c: 01070604 tsteq r7, r4, lsl #12 + 8c: 011f0604 tsteq pc, r4, lsl #12 90: 42010000 andmi r0, r1, #0 94: 00000053 andeq r0, r0, r3, asr r0 98: 060c2302 streq r2, [ip], -r2, lsl #6 - 9c: 0000002b andeq r0, r0, fp, lsr #32 + 9c: 00000039 andeq r0, r0, r9, lsr r0 a0: 00534301 subseq r4, r3, r1, lsl #6 a4: 23020000 movwcs r0, #8192 ; 0x2000 - a8: 00b60610 adcseq r0, r6, r0, lsl r6 + a8: 009f0610 addseq r0, pc, r0, lsl r6 ; ac: 44010000 strmi r0, [r1], #-0 b0: 00000053 andeq r0, r0, r3, asr r0 b4: 06142302 ldreq r2, [r4], -r2, lsl #6 - b8: 000000c4 andeq r0, r0, r4, asr #1 + b8: 00000040 andeq r0, r0, r0, asr #32 bc: 010e4501 tsteq lr, r1, lsl #10 c0: 23020000 movwcs r0, #8192 ; 0x2000 - c4: 001d0618 andseq r0, sp, r8, lsl r6 + c4: 002b0618 eoreq r0, fp, r8, lsl r6 c8: 46010000 strmi r0, [r1], -r0 cc: 0000010e andeq r0, r0, lr, lsl #2 d0: 061c2302 ldreq r2, [ip], -r2, lsl #6 - d4: 0000006d andeq r0, r0, sp, rrx + d4: 00000056 andeq r0, r0, r6, asr r0 d8: 010e4701 tsteq lr, r1, lsl #14 dc: 23020000 movwcs r0, #8192 ; 0x2000 - e0: 00640620 rsbeq r0, r4, r0, lsr #12 + e0: 004d0620 subeq r0, sp, r0, lsr #12 e4: 48010000 stmdami r1, {} ; e8: 0000010e andeq r0, r0, lr, lsl #2 ec: 06242302 strteq r2, [r4], -r2, lsl #6 - f0: 00000124 andeq r0, r0, r4, lsr #2 + f0: 0000013c andeq r0, r0, ip, lsr r1 f4: 00fe4901 rscseq r4, lr, r1, lsl #18 f8: 23020000 movwcs r0, #8192 ; 0x2000 fc: 2c070028 stccs 0, cr0, [r7], {40} ; 0x28 @@ -143,16 +143,16 @@ Disassembly of section .debug_info: 110: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0} 114: 08000001 stmdaeq r0, {r0} 118: 0000005e andeq r0, r0, lr, asr r0 - 11c: 43030003 movwmi r0, #12291 ; 0x3003 + 11c: 5b030003 blpl c0130 <__bss_end+0xc0054> 120: 01000001 tsteq r0, r1 124: 0000654a andeq r6, r0, sl, asr #10 - 128: 01370900 teqeq r7, r0, lsl #18 + 128: 014f0900 cmpeq pc, r0, lsl #18 12c: 25020000 strcs r0, [r2, #-0] 130: 0000013b andeq r0, r0, fp, lsr r1 134: 00030501 andeq r0, r3, r1, lsl #10 138: 0a000000 beq 140 <__bss_end+0x64> 13c: 0000011e andeq r0, r0, lr, lsl r1 - 140: 00007d00 andeq r7, r0, r0, lsl #26 + 140: 00009500 andeq r9, r0, r0, lsl #10 144: 7f000200 svcvc 0x00000200 148: 04000000 streq r0, [r0], #-0 14c: 00007b01 andeq r7, r0, r1, lsl #22 @@ -170,21 +170,27 @@ Disassembly of section .debug_info: 17c: 2e73656d cdpcs 5, 7, cr6, cr3, cr13, {3} 180: 682f0053 stmdavs pc!, {r0, r1, r4, r6} ; 184: 2f656d6f svccs 0x00656d6f - 188: 6f426f4c svcvs 0x00426f4c - 18c: 61525f32 cmpvs r2, r2, lsr pc - 190: 2f6f6e7a svccs 0x006f6e7a - 194: 6e61724f cdpvs 2, 6, cr7, cr1, cr15, {2} - 198: 49506567 ldmdbmi r0, {r0, r1, r2, r5, r6, r8, sl, sp, lr}^ - 19c: 72656b2f rsbvc r6, r5, #48128 ; 0xbc00 - 1a0: 5f6c656e svcpl 0x006c656e - 1a4: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} - 1a8: 696c2f39 stmdbvs ip!, {r0, r3, r4, r5, r8, r9, sl, fp, sp}^ - 1ac: 2d78756e cfldr64cs mvdx7, [r8, #-440]! ; 0xfffffe48 - 1b0: 00342e33 eorseq r2, r4, r3, lsr lr - 1b4: 20554e47 subscs r4, r5, r7, asr #28 - 1b8: 32205341 eorcc r5, r0, #67108865 ; 0x4000001 - 1bc: 0032322e eorseq r3, r2, lr, lsr #4 - 1c0: Address 0x000001c0 is out of bounds. + 188: 6e6f656c cdpvs 5, 6, cr6, cr15, cr12, {3} + 18c: 6f647261 svcvs 0x00647261 + 190: 7365442f cmnvc r5, #788529152 ; 0x2f000000 + 194: 706f746b rsbvc r7, pc, fp, ror #8 + 198: 626d652f rsbvs r6, sp, #197132288 ; 0xbc00000 + 19c: 6f746465 svcvs 0x00746465 + 1a0: 6f2f6c6f svcvs 0x002f6c6f + 1a4: 676e6172 ; instruction: 0x676e6172 + 1a8: 4b697065 blmi 1a5c344 <__bss_end+0x1a5c268> + 1ac: 656e7265 strbvs r7, [lr, #-613]! ; 0x265 + 1b0: 724f2f6c subvc r2, pc, #432 ; 0x1b0 + 1b4: 65676e61 strbvs r6, [r7, #-3681]! ; 0xe61 + 1b8: 4b2d4950 blmi b52700 <__bss_end+0xb52624> + 1bc: 656e7265 strbvs r7, [lr, #-613]! ; 0x265 + 1c0: 696c2f6c stmdbvs ip!, {r2, r3, r5, r6, r8, r9, sl, fp, sp}^ + 1c4: 2d78756e cfldr64cs mvdx7, [r8, #-440]! ; 0xfffffe48 + 1c8: 00342e33 eorseq r2, r4, r3, lsr lr + 1cc: 20554e47 subscs r4, r5, r7, asr #28 + 1d0: 32205341 eorcc r5, r0, #67108865 ; 0x4000001 + 1d4: 0032322e eorseq r3, r2, lr, lsr #4 + 1d8: Address 0x000001d8 is out of bounds. Disassembly of section .debug_abbrev: @@ -310,85 +316,91 @@ Disassembly of section .debug_str: 10: 665f656d ldrbvs r6, [pc], -sp, ror #10 14: 5f656c69 svcpl 0x00656c69 18: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 1c: 6c696600 stclvs 6, cr6, [r9], #-0 - 20: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - 24: 765f6461 ldrbvc r6, [pc], -r1, ror #8 - 28: 6c006e73 stcvs 14, cr6, [r0], {115} ; 0x73 - 2c: 74676e65 strbtvc r6, [r7], #-3685 ; 0xe65 - 30: 682f0068 stmdavs pc!, {r3, r5, r6} ; - 34: 2f656d6f svccs 0x00656d6f - 38: 6f426f4c svcvs 0x00426f4c - 3c: 61525f32 cmpvs r2, r2, lsr pc - 40: 2f6f6e7a svccs 0x006f6e7a - 44: 6e61724f cdpvs 2, 6, cr7, cr1, cr15, {2} - 48: 49506567 ldmdbmi r0, {r0, r1, r2, r5, r6, r8, sl, sp, lr}^ - 4c: 72656b2f rsbvc r6, r5, #48128 ; 0xbc00 - 50: 5f6c656e svcpl 0x006c656e - 54: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} - 58: 696c2f39 stmdbvs ip!, {r0, r3, r4, r5, r8, r9, sl, fp, sp}^ - 5c: 2d78756e cfldr64cs mvdx7, [r8, #-440]! ; 0xfffffe48 - 60: 00342e33 eorseq r2, r4, r3, lsr lr - 64: 4e4f4765 cdpmi 7, 4, cr4, cr15, cr5, {3} - 68: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} - 6c: 73655200 cmnvc r5, #0 - 70: 5f656d75 svcpl 0x00656d75 - 74: 006e7376 rsbeq r7, lr, r6, ror r3 - 78: 68637261 stmdavs r3!, {r0, r5, r6, r9, ip, sp, lr}^ - 7c: 6d72612f ldfvse f6, [r2, #-188]! ; 0xffffff44 - 80: 63616d2f cmnvs r1, #3008 ; 0xbc0 - 84: 75732d68 ldrbvc r2, [r3, #-3432]! ; 0xd68 - 88: 2f69786e svccs 0x0069786e - 8c: 65776f70 ldrbvs r6, [r7, #-3952]! ; 0xf70 - 90: 72622f72 rsbvc r2, r2, #456 ; 0x1c8 - 94: 722f6d6f eorvc r6, pc, #7104 ; 0x1bc0 - 98: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 9c: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - a0: 632e6461 teqvs lr, #1627389952 ; 0x61000000 - a4: 6d756a00 vldmdbvs r5!, {s13-s12} - a8: 6e695f70 mcrvs 15, 3, r5, cr9, cr0, {3} - ac: 75727473 ldrbvc r7, [r2, #-1139]! ; 0x473 - b0: 6f697463 svcvs 0x00697463 - b4: 7570006e ldrbvc r0, [r0, #-110]! ; 0x6e - b8: 65685f62 strbvs r5, [r8, #-3938]! ; 0xf62 - bc: 735f6461 cmpvc pc, #1627389952 ; 0x61000000 - c0: 00657a69 rsbeq r7, r5, r9, ror #20 - c4: 5f627570 svcpl 0x00627570 - c8: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - cc: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} - d0: 736e7500 cmnvc lr, #0 - d4: 656e6769 strbvs r6, [lr, #-1897]! ; 0x769 - d8: 68632064 stmdavs r3!, {r2, r5, r6, sp}^ - dc: 6d007261 sfmvs f7, 4, [r0, #-388] ; 0xfffffe7c - e0: 63696761 cmnvs r9, #25427968 ; 0x1840000 - e4: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 - e8: 34204320 strtcc r4, [r0], #-800 ; 0x320 - ec: 332e362e teqcc lr, #48234496 ; 0x2e00000 - f0: 31303220 teqcc r0, r0, lsr #4 - f4: 30323032 eorscc r3, r2, r2, lsr r0 - f8: 70282031 eorvc r2, r8, r1, lsr r0 - fc: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 - 100: 7361656c cmnvc r1, #452984832 ; 0x1b000000 - 104: 63002965 movwvs r2, #2405 ; 0x965 - 108: 6b636568 blvs 18d96b0 <__bss_end+0x18d95d4> - 10c: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 - 110: 6f687300 svcvs 0x00687300 - 114: 75207472 strvc r7, [r0, #-1138]! ; 0x472 - 118: 6769736e strbvs r7, [r9, -lr, ror #6]! - 11c: 2064656e rsbcs r6, r4, lr, ror #10 - 120: 00746e69 rsbseq r6, r4, r9, ror #28 - 124: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 - 128: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 - 12c: 6f687300 svcvs 0x00687300 - 130: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} - 134: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 - 138: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 13c: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - 140: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 - 144: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 148: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ - 14c: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 150: 5f646165 svcpl 0x00646165 - 154: Address 0x00000154 is out of bounds. + 1c: 736e7500 cmnvc lr, #0 + 20: 656e6769 strbvs r6, [lr, #-1897]! ; 0x769 + 24: 68632064 stmdavs r3!, {r2, r5, r6, sp}^ + 28: 66007261 strvs r7, [r0], -r1, ror #4 + 2c: 5f656c69 svcpl 0x00656c69 + 30: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + 34: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} + 38: 6e656c00 cdpvs 12, 6, cr6, cr5, cr0, {0} + 3c: 00687467 rsbeq r7, r8, r7, ror #8 + 40: 5f627570 svcpl 0x00627570 + 44: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + 48: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} + 4c: 4f476500 svcmi 0x00476500 + 50: 73765f4e cmnvc r6, #312 ; 0x138 + 54: 6552006e ldrbvs r0, [r2, #-110] ; 0x6e + 58: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 + 5c: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} + 60: 63726100 cmnvs r2, #0 + 64: 72612f68 rsbvc r2, r1, #416 ; 0x1a0 + 68: 616d2f6d cmnvs sp, sp, ror #30 + 6c: 732d6863 teqvc sp, #6488064 ; 0x630000 + 70: 69786e75 ldmdbvs r8!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ + 74: 776f702f strbvc r7, [pc, -pc, lsr #32]! + 78: 622f7265 eorvs r7, pc, #1342177286 ; 0x50000006 + 7c: 2f6d6f72 svccs 0x006d6f72 + 80: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 + 84: 685f656d ldmdavs pc, {r0, r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 88: 2e646165 powcssz f6, f4, f5 + 8c: 756a0063 strbvc r0, [sl, #-99]! ; 0x63 + 90: 695f706d ldmdbvs pc, {r0, r2, r3, r5, r6, ip, sp, lr}^ ; + 94: 7274736e rsbsvc r7, r4, #-1207959551 ; 0xb8000001 + 98: 69746375 ldmdbvs r4!, {r0, r2, r4, r5, r6, r8, r9, sp, lr}^ + 9c: 70006e6f andvc r6, r0, pc, ror #28 + a0: 685f6275 ldmdavs pc, {r0, r2, r4, r5, r6, r9, sp, lr}^ ; + a4: 5f646165 svcpl 0x00646165 + a8: 657a6973 ldrbvs r6, [sl, #-2419]! ; 0x973 + ac: 6f682f00 svcvs 0x00682f00 + b0: 6c2f656d cfstr32vs mvfx6, [pc], #-436 ; ffffff04 <__bss_end+0xfffffe28> + b4: 616e6f65 cmnvs lr, r5, ror #30 + b8: 2f6f6472 svccs 0x006f6472 + bc: 6b736544 blvs 1cd95d4 <__bss_end+0x1cd94f8> + c0: 2f706f74 svccs 0x00706f74 + c4: 65626d65 strbvs r6, [r2, #-3429]! ; 0xd65 + c8: 6f6f7464 svcvs 0x006f7464 + cc: 726f2f6c rsbvc r2, pc, #432 ; 0x1b0 + d0: 65676e61 strbvs r6, [r7, #-3681]! ; 0xe61 + d4: 654b6970 strbvs r6, [fp, #-2416] ; 0x970 + d8: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 + dc: 61724f2f cmnvs r2, pc, lsr #30 + e0: 5065676e rsbpl r6, r5, lr, ror #14 + e4: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 + e8: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 + ec: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} + f0: 332d7875 teqcc sp, #7667712 ; 0x750000 + f4: 6d00342e cfstrsvs mvf3, [r0, #-184] ; 0xffffff48 + f8: 63696761 cmnvs r9, #25427968 ; 0x1840000 + fc: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 + 100: 34204320 strtcc r4, [r0], #-800 ; 0x320 + 104: 332e362e teqcc lr, #48234496 ; 0x2e00000 + 108: 31303220 teqcc r0, r0, lsr #4 + 10c: 30323032 eorscc r3, r2, r2, lsr r0 + 110: 70282031 eorvc r2, r8, r1, lsr r0 + 114: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 + 118: 7361656c cmnvc r1, #452984832 ; 0x1b000000 + 11c: 63002965 movwvs r2, #2405 ; 0x965 + 120: 6b636568 blvs 18d96c8 <__bss_end+0x18d95ec> + 124: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 + 128: 6f687300 svcvs 0x00687300 + 12c: 75207472 strvc r7, [r0, #-1138]! ; 0x472 + 130: 6769736e strbvs r7, [r9, -lr, ror #6]! + 134: 2064656e rsbcs r6, r4, lr, ror #10 + 138: 00746e69 rsbseq r6, r4, r9, ror #28 + 13c: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 + 140: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 + 144: 6f687300 svcvs 0x00687300 + 148: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} + 14c: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 + 150: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 154: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 + 158: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 + 15c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 160: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 164: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 168: 5f646165 svcpl 0x00646165 + 16c: Address 0x0000016c is out of bounds. Disassembly of section .comment: diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 0f0e1778..90fd67ef 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -62,9 +62,9 @@ LOAD arch/arm/mach-sunxi/power/brom/resumes.o LOAD arch/arm/mach-sunxi/power/brom/resume_head.o OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) -.debug_info 0x00000000 0x1c2 +.debug_info 0x00000000 0x1da .debug_info 0x00000000 0x141 arch/arm/mach-sunxi/power/brom/resume_head.o - .debug_info 0x00000141 0x81 arch/arm/mach-sunxi/power/brom/resumes.o + .debug_info 0x00000141 0x99 arch/arm/mach-sunxi/power/brom/resumes.o .debug_abbrev 0x00000000 0x93 .debug_abbrev 0x00000000 0x7f arch/arm/mach-sunxi/power/brom/resume_head.o @@ -74,9 +74,9 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o .debug_line 0x0000007b 0x8a arch/arm/mach-sunxi/power/brom/resumes.o -.debug_str 0x00000000 0x156 - .debug_str 0x00000000 0x156 arch/arm/mach-sunxi/power/brom/resume_head.o - 0x16f (size before relaxing) +.debug_str 0x00000000 0x16e + .debug_str 0x00000000 0x16e arch/arm/mach-sunxi/power/brom/resume_head.o + 0x187 (size before relaxing) .comment 0x00000000 0x64 .comment 0x00000000 0x64 arch/arm/mach-sunxi/power/brom/resume_head.o diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h index 0a7d7c6d..a066c990 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h @@ -85,6 +85,7 @@ struct sensor_info { struct v4l2_fract tpf; struct sensor_win_size *current_wins; struct flash_dev_info *fl_dev_info; + u8 clkrc; /* Clock divider value */ }; #endif //__CAMERA__H__ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index 1d3eb0e7..689efad9 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -49,6 +49,7 @@ MODULE_LICENSE("GPL"); #define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING +#define REG_CLKRC 0xfa #define V4L2_IDENT_SENSOR 0x2035 //define the voltage level of control signal @@ -67,14 +68,14 @@ MODULE_LICENSE("GPL"); /* * Our nominal (default) frame rate. */ -#define SENSOR_FRAME_RATE 8 +#define SENSOR_FRAME_RATE 15 /* * The gc2035 sits on i2c with ID 0x78 */ -#define I2C_ADDR 0x78 +#define I2C_ADDR 0x78 #define SENSOR_NAME "gc2035" /* * Information we maintain about a known sensor. @@ -113,11 +114,12 @@ static struct regval_list sensor_default_regs[] = { {0xf7 , 0x15}, //pll enable {0xf8 , 0x85}, + {0xfe , 0x00}, -{0x82 , 0x00}, -{0xb3 , 0x60}, -{0xb4 , 0x40}, -{0xb5 , 0x60}, +{0x82 , 0x00}, //00 +{0xb3 , 0x60}, //60 +{0xb4 , 0x40}, //60 40 +{0xb5 , 0x60}, //60 {0x03 , 0x02}, {0x04 , 0x80}, @@ -131,18 +133,20 @@ static struct regval_list sensor_default_regs[] = { ///////////analog///////////// {0x0a , 0x00}, //row start +{0x0b , 0x10}, //row start {0x0c , 0x00}, //col start -{0x0d , 0x04}, -{0x0e , 0xc0}, +{0x0d , 0x04}, //4d0 = 1232 +{0x0e , 0xe0}, //d0/b0/d0/c0 {0x0f , 0x06}, //Window setting -{0x10 , 0x58}, -{0x17 , 0x14}, //[0]mirror [1]flip +{0x10 , 0x58}, //40/50/58 +{0x17 , 0x14}, //[0]mirror [1]flip [4]better colour -{0x18 , 0x0a}, //0a 2012.10.26 +//{0x18 , 0x0a}, //0a 2012.10.26 +{0x18 , 0x0f}, //0a 2012.10.26 {0x19 , 0x0a}, //AD pipe number -{0x1a, 0x01}, //CISCTL mode4 +{0x1a , 0x01}, //CISCTL mode4 {0x1b , 0x8b}, {0x1c , 0x05}, //added {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias @@ -151,54 +155,56 @@ static struct regval_list sensor_default_regs[] = { {0x21 , 0x0f}, //[6:4]rsg {0x22 , 0xf0}, //[3:0]vref 0xf0 {0x23 , 0xc3}, //f3//ADC_r -{0x24 , 0x15}, //pad drive <=36MHz, use 0x00 is ok +{0x24 , 0x17}, //pad drive <=36MHz, use 0x00 is ok //AEC {0xfe , 0x01}, -{0x11 , 0x20},//AEC_out_slope , 0x -{0x1f , 0xa0},//max_post_gain -{0x20 , 0x40},//max_pre_gain -{0x47 , 0x30},//AEC_outdoor_th -{0x0b , 0x10},// +{0x11 , 0x20},//20 AEC_out_slope , 0x +{0x1f , 0xc0},//80 max_post_gain +{0x20 , 0x60},//40 max_pre_gain +{0x47 , 0x80},//30 AEC_outdoor_th +{0x0b , 0x13},//10 {0x13 , 0x75},//y_target {0xfe , 0x00}, - +{0xfe , 0x00}, +{0xfe , 0x00}, {0x05 , 0x01},//hb -{0x06 , 0x11}, +{0x06 , 0x0d}, {0x07 , 0x00},//vb -{0x08 , 0x50}, +{0x08 , 0x40}, + {0xfe , 0x01}, {0x27 , 0x00},//step -{0x28 , 0xa0}, -{0x29 , 0x05},//level1 +{0x28 , 0xa0},//a0 +{0x29 , 0x05},// level 0 12.5 {0x2a , 0x00}, -{0x2b , 0x05},//level2 +{0x2b , 0x05},// level 1 12.5 {0x2c , 0x00}, -{0x2d , 0x06},//6e8//level3 -{0x2e , 0xe0}, -{0x2f , 0x0a},//level4 -{0x30 , 0x00}, -{0x3e , 0x40}, +{0x2d , 0x05},// level 2 12.5 640/10fps +{0x2e , 0x00}, +{0x2f , 0x08},// level 3 7.5 +{0x30 , 0x20}, + {0xfe , 0x00}, {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x {0xb6 , 0x03}, //AEC enable {0xfe , 0x00}, /////////BLK////// -{0x3f , 0x00}, //prc close -{0x40 , 0x77},// -{0x42 , 0x7f}, -{0x43 , 0x30}, -{0x5c , 0x08}, -{0x5e , 0x20}, -{0x5f , 0x20}, -{0x60 , 0x20}, -{0x61 , 0x20}, -{0x62 , 0x20}, -{0x63 , 0x20}, -{0x64 , 0x20}, -{0x65 , 0x20}, +{0x3f, 0x00}, //prc close +{0x40, 0x77},// +{0x42, 0x7f}, +{0x43, 0x30}, +{0x5c, 0x08}, +{0x5e, 0x20}, +{0x5f, 0x20}, +{0x60, 0x20}, +{0x61, 0x20}, +{0x62, 0x20}, +{0x63, 0x20}, +{0x64, 0x20}, +{0x65, 0x20}, ///block//////////// {0x80 , 0xff}, @@ -211,63 +217,63 @@ static struct regval_list sensor_default_regs[] = { {0xc0 , 0x40},//Yuv bypass //////lsc///////////// -{0xfe , 0x01}, -{0xc2 , 0x38}, -{0xc3 , 0x25}, -{0xc4 , 0x21}, -{0xc8 , 0x19}, -{0xc9 , 0x12}, -{0xca , 0x0e}, -{0xbc , 0x43}, -{0xbd , 0x18}, -{0xbe , 0x1b}, -{0xb6 , 0x40}, -{0xb7 , 0x2e}, -{0xb8 , 0x26}, -{0xc5 , 0x05}, -{0xc6 , 0x03}, -{0xc7 , 0x04}, -{0xcb , 0x00}, -{0xcc , 0x00}, -{0xcd , 0x00}, -{0xbf , 0x14}, -{0xc0 , 0x22}, -{0xc1 , 0x1b}, -{0xb9 , 0x00}, -{0xba , 0x05}, -{0xbb , 0x05}, -{0xaa , 0x35}, -{0xab , 0x33}, -{0xac , 0x33}, -{0xad , 0x25}, -{0xae , 0x22}, -{0xaf , 0x27}, -{0xb0 , 0x1d}, -{0xb1 , 0x20}, -{0xb2 , 0x22}, -{0xb3 , 0x14}, -{0xb4 , 0x15}, -{0xb5 , 0x16}, -{0xd0 , 0x00}, -{0xd2 , 0x07}, -{0xd3 , 0x08}, -{0xd8 , 0x00}, -{0xda , 0x13}, -{0xdb , 0x17}, -{0xdc , 0x00}, -{0xde , 0x0a}, -{0xdf , 0x08}, -{0xd4 , 0x00}, -{0xd6 , 0x00}, -{0xd7 , 0x0c}, -{0xa4 , 0x00}, -{0xa5 , 0x00}, -{0xa6 , 0x00}, -{0xa7 , 0x00}, -{0xa8 , 0x00}, -{0xa9 , 0x00}, -{0xa1 , 0x80}, -{0xa2 , 0x80}, +{0xfe,0x01}, +{0xc2,0x21}, +{0xc3,0x1a}, +{0xc4,0x13}, +{0xc8,0x17}, +{0xc9,0x0f}, +{0xca,0x00}, +{0xbc,0x36}, +{0xbd,0x2b}, +{0xbe,0x17}, +{0xb6,0x39}, +{0xb7,0x21}, +{0xb8,0x1c}, +{0xc5,0x00}, +{0xc6,0x00}, +{0xc7,0x00}, +{0xcb,0x00}, +{0xcc,0x0c}, +{0xcd,0x15}, +{0xbf,0x00}, +{0xc0,0x00}, +{0xc1,0x00}, +{0xb9,0x00}, +{0xba,0x00}, +{0xbb,0x00}, +{0xaa,0x15}, +{0xab,0x15}, +{0xac,0x15}, +{0xad,0x14}, +{0xae,0x13}, +{0xaf,0x12}, +{0xb0,0x1b}, +{0xb1,0x14}, +{0xb2,0x14}, +{0xb3,0x1f}, +{0xb4,0x12}, +{0xb5,0x13}, +{0xd0,0x00}, +{0xd2,0x00}, +{0xd3,0x0c}, +{0xd8,0x00}, +{0xda,0x00}, +{0xdb,0x13}, +{0xdc,0x00}, +{0xde,0x00}, +{0xdf,0x25}, +{0xd4,0x00}, +{0xd6,0x00}, +{0xd7,0x12}, +{0xa4,0x00}, +{0xa5,0x00}, +{0xa6,0x00}, +{0xa7,0x00}, +{0xa8,0x00}, +{0xa9,0x00}, +{0xa1,0x80}, +{0xa2,0x80}, //////////cc////////////// {0xfe , 0x02}, @@ -590,27 +596,30 @@ static struct regval_list sensor_default_regs[] = { /////////awb end ///////////// ///==========asde -{0xfe , 0x01}, -{0x21 , 0xbf}, -{0xfe , 0x02}, -{0xa4 , 0x00},// -{0xa5 , 0x40}, //lsc_th -{0xa2 , 0xa0}, //lsc_dec_slope -{0xa6 , 0x80}, //dd_th -{0xa7 , 0x80}, //ot_th -{0xab , 0x31}, // -{0xa9 , 0x6f}, // -{0xb0 , 0x99}, //0x//edge effect slope low -{0xb1 , 0x34},//edge effect slope low -{0xb3 , 0xf0}, //saturation dec slope -{0xde , 0xb6}, // -{0x38 , 0x0f}, // -{0x39 , 0x60}, // -{0xfe , 0x00}, -{0x81 , 0x26}, -{0xfe , 0x02}, -{0x83 , 0x00},// -{0x84 , 0x45},// +{0xfe, 0x01}, +{0x21, 0xbf}, +{0xfe, 0x02}, +{0xa4, 0x00},// +{0xa5, 0x40}, //lsc_th +{0xa2, 0xa0}, //lsc_dec_slope +{0x86, 0x27},//add for DPC travis 20140505 +{0x8a, 0x33},//add for DPC travis 20140505 +{0x8d, 0x85},//add for DPC travis 20140505 +{0xa6, 0xf0},//80//change for DPC travis 20140505 +{0xa7, 0x80}, //ot_th +{0xab, 0x31}, // +{0xa9, 0x6f}, // +{0xb0, 0x99}, //0x//edge effect slope low +{0xb1, 0x34},//edge effect slope low +{0xb3, 0x80}, //saturation dec slope +{0xde, 0xb6}, // +{0x38, 0x0f}, // +{0x39, 0x60}, // +{0xfe, 0x00}, +{0x81, 0x26}, +{0xfe, 0x02}, +{0x83, 0x00},// +{0x84, 0x45},// ////////////YCP////////// {0xd1 , 0x34},//saturation_cb {0xd2 , 0x34},//saturation_Cr @@ -669,13 +678,12 @@ static struct regval_list sensor_default_regs[] = { {0x36 , 0xe0}, {0x37 , 0xff}, /////1600x1200size// -{0xfe , 0x00},// -{0x90 , 0x01}, //0x//crop enable -{0x94 , 0x04}, -{0x95 , 0x04}, //0x//1600x1200 -{0x96 , 0xb0}, -{0x97 , 0x06}, -{0x98 , 0x40}, +{0xfe, 0x00},// +{0x90, 0x01}, //0x//crop enable +{0x95, 0x04}, //0x//1600x1200 +{0x96, 0xb0}, +{0x97, 0x06}, +{0x98, 0x40}, {0xfe , 0x03}, {0x42 , 0x40}, @@ -684,6 +692,7 @@ static struct regval_list sensor_default_regs[] = { {0x40 , 0x40}, //00 {0x17 , 0x00}, //widv {0xfe , 0x00}, + ////output DVP///// {0xfe , 0x00}, {0x82 , 0xfe}, // fe @@ -692,13 +701,13 @@ static struct regval_list sensor_default_regs[] = { {0xf4 , 0x00}, {0xf5 , 0x30}, ////////sabsumple 800X600////// -{0xfe , 0x00}, -{0xb6 , 0x03}, -{0xfa , 0x00}, +{0xfe , 0x00}, +{0xb6 , 0x03}, +{0xfa , 0x00}, {0xc8 , 0x00},//close scaler {0x99 , 0x22},// 1/2 subsample -{0x9a , 0x07}, +{0x9a , 0x07}, {0x9b , 0x00}, {0x9c , 0x00}, {0x9d , 0x00}, @@ -806,11 +815,11 @@ static struct regval_list sensor_svga_regs[] = { {0xfe,0x00}, {0xb6,0x03}, -{0xfa , 0x00}, +{0xfa,0x00}, {0xc8,0x00},//close scaler {0x99,0x22},// 1/2 subsample -{0x9a , 0x07}, +{0x9a,0x07}, {0x9b,0x00}, {0x9c,0x00}, {0x9d,0x00}, @@ -911,7 +920,7 @@ static struct regval_list sensor_wb_auto_regs[] = { {0xb3, 0x61}, {0xb4, 0x40}, {0xb5, 0x61}, - {0xff, 0xff}, + {0xff, 0xff}, }; static struct regval_list sensor_wb_incandescence_regs[] = { @@ -963,7 +972,7 @@ static struct regval_list sensor_wb_cloud_regs[] = { {0xb3, 0x58}, {0xb4, 0x40}, {0xb5, 0x50}, - {0xff, 0xff}, + {0xff, 0xff}, }; static struct regval_list sensor_wb_shade[] = { @@ -2655,7 +2664,6 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { struct v4l2_captureparm *cp = &parms->parm.capture; - struct sensor_info *info = to_state(sd); if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -2663,54 +2671,36 @@ static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) memset(cp, 0, sizeof(struct v4l2_captureparm)); cp->capability = V4L2_CAP_TIMEPERFRAME; cp->timeperframe.numerator = 1; - - if (info->width > SVGA_WIDTH && info->height > SVGA_HEIGHT) { - cp->timeperframe.denominator = SENSOR_FRAME_RATE/2; - } - else { - cp->timeperframe.denominator = SENSOR_FRAME_RATE; - } - + cp->timeperframe.denominator = SENSOR_FRAME_RATE; return 0; } static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { -// struct v4l2_captureparm *cp = &parms->parm.capture; -// struct v4l2_fract *tpf = &cp->timeperframe; -// struct sensor_info *info = to_state(sd); -// int div; - -// if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -// return -EINVAL; -// if (cp->extendedmode != 0) -// return -EINVAL; - -// if (tpf->numerator == 0 || tpf->denominator == 0) -// div = 1; /* Reset to full rate */ -// else { -// if (info->width > SVGA_WIDTH && info->height > SVGA_HEIGHT) { -// div = (tpf->numerator*SENSOR_FRAME_RATE/2)/tpf->denominator; -// } -// else { -// div = (tpf->numerator*SENSOR_FRAME_RATE)/tpf->denominator; -// } -// } -// -// if (div == 0) -// div = 1; -// else if (div > 8) -// div = 8; -// -// switch() -// -// info->clkrc = (info->clkrc & 0x80) | div; -// tpf->numerator = 1; -// tpf->denominator = sensor_FRAME_RATE/div; -// -// sensor_write(sd, REG_CLKRC, info->clkrc); - //return -EINVAL; - return 0; + struct v4l2_captureparm *cp = &parms->parm.capture; + struct sensor_info *info = to_state(sd); + struct v4l2_fract *tpf = &cp->timeperframe; + int div; + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (cp->extendedmode != 0) + return -EINVAL; + + if (tpf->numerator == 0 || tpf->denominator == 0) + div = 1; // Reset to full rate + else + div = (tpf->numerator*SENSOR_FRAME_RATE)/tpf->denominator; + + if (div == 0) + div = 1; + else if (div > 8) + div = 8; + info->clkrc = (info->clkrc & 0x80) | div; + tpf->numerator = 1; + tpf->denominator = SENSOR_FRAME_RATE/div; + sensor_write(sd, REG_CLKRC, info->clkrc); + return 0; } @@ -2998,7 +2988,7 @@ static int sensor_probe(struct i2c_client *client, info->autowb = 1; info->wb = 0; info->clrfx = 0; -// info->clkrc = 1; /* 30fps */ + info->clkrc = 1; /* 30fps */ return 0; } @@ -3040,4 +3030,4 @@ static __exit void exit_sensor(void) } module_init(init_sensor); -module_exit(exit_sensor); +module_exit(exit_sensor); \ No newline at end of file diff --git a/linux-3.4/drivers/net/ethernet/sunxi/eth/Kconfig b/linux-3.4/drivers/net/ethernet/sunxi/eth/Kconfig index af930df0..13787db7 100755 --- a/linux-3.4/drivers/net/ethernet/sunxi/eth/Kconfig +++ b/linux-3.4/drivers/net/ethernet/sunxi/eth/Kconfig @@ -35,13 +35,5 @@ config GETH_PHY_POWER If external PHY power is exist, and it want to be controled, select it. If not, it mean the power of PHY already on. -config GMAC_PHY_POWER - bool "External PHY power control" - depends on SUNXI_GETH - default y - ---help--- - If external PHY power is exist, and it want to be controled, - select it. If not, it mean the power of PHY already on. - endif diff --git a/linux-3.4/drivers/net/ethernet/sunxi/eth/sunxi_geth.c b/linux-3.4/drivers/net/ethernet/sunxi/eth/sunxi_geth.c index 96be5a38..7c48f7b0 100755 --- a/linux-3.4/drivers/net/ethernet/sunxi/eth/sunxi_geth.c +++ b/linux-3.4/drivers/net/ethernet/sunxi/eth/sunxi_geth.c @@ -154,9 +154,6 @@ struct geth_priv { spinlock_t lock; spinlock_t tx_lock; -#ifdef CONFIG_GMAC_PHY_POWER - u32 gpio_power_hd; -#endif }; #ifdef CONFIG_GETH_PHY_POWER @@ -198,11 +195,6 @@ static void desc_print(struct dma_desc *desc, int size) static int geth_power_on(struct geth_priv *priv) { int value; - -#ifdef CONFIG_GMAC_PHY_POWER - gpio_set_value(priv->gpio_power_hd, 1); -#endif - #ifdef CONFIG_GETH_PHY_POWER struct regulator **regu; int ret = 0, i = 0; @@ -266,11 +258,6 @@ static int geth_power_on(struct geth_priv *priv) static void geth_power_off(struct geth_priv *priv) { int value; - -#ifdef CONFIG_GMAC_PHY_POWER - gpio_set_value(priv->gpio_power_hd, 0); -#endif - #ifdef CONFIG_GETH_PHY_POWER struct regulator **regu = priv->power; int i = 0; @@ -1620,13 +1607,7 @@ static int geth_sys_request(struct platform_device *pdev) struct geth_priv *priv = netdev_priv(ndev); int ret = 0; struct resource *res; - -#ifdef CONFIG_GMAC_PHY_POWER - script_item_value_type_e type; - script_item_u item; - int req_status; -#endif - + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "geth_extclk"); if (unlikely(!res)){ ret = -ENODEV; @@ -1700,22 +1681,6 @@ static int geth_sys_request(struct platform_device *pdev) } } #endif - -#ifdef CONFIG_GMAC_PHY_POWER && CONFIG_GETH_SCRIPT_SYS - type = script_get_item("gmac_phy_power", "gmac_phy_power_en", &item); - if (SCIRPT_ITEM_VALUE_TYPE_PIO != type) { - pr_err("script_get_item return type err\n"); - return -EFAULT; - } - /*request gpio*/ - req_status = gpio_request(item.gpio.gpio, NULL); - if (0 != req_status) { - pr_err("request gpio failed!\n"); - } - gpio_direction_output(item.gpio.gpio, 1); - priv->gpio_power_hd = item.gpio.gpio; - #endif - return 0; pin_err: diff --git a/linux-3.4/drivers/watchdog/sunxi_wdt.c b/linux-3.4/drivers/watchdog/sunxi_wdt.c index ecbf6009..8320991b 100755 --- a/linux-3.4/drivers/watchdog/sunxi_wdt.c +++ b/linux-3.4/drivers/watchdog/sunxi_wdt.c @@ -58,7 +58,8 @@ #define WDT_FUNC TO_WHOLE_SYSTEM #endif /* CONFIG_ARCH_SUN9I */ -#define MAX_TIMEOUT 16 /* max 16 seconds */ +#define MAX_TIMEOUT 15 /* max 15 seconds */ +#define WATCHDOG_NOWAYOUT 1 static struct platform_device *platform_device; static bool is_active, expect_release; @@ -214,7 +215,7 @@ static int wdt_restart(void) } #endif - pr_info("%s, write reg 0x%08x\n", __func__, (u32)&wdt_reg->ctrl); + pr_debug("%s, write reg 0x%08x\n", __func__, (u32)&wdt_reg->ctrl); writel((0xA57 << 1) | (1 << 0), &wdt_reg->ctrl); return 0; } @@ -240,7 +241,7 @@ static int wdt_set_tmout(int timeout_in_sec) writel(temp, &wdt_reg->mode); temp2 = interv_to_timeout(interv); - pr_info("%s, write 0x%08x to mode reg 0x%08x, actual timeout %d sec\n", + pr_debug("%s, write 0x%08x to mode reg 0x%08x, actual timeout %d sec\n", __func__, temp, (u32)&wdt_reg->mode, temp2); return interv; } @@ -262,7 +263,7 @@ static int wdt_enable(bool ben) else temp &= 0xFE; writel(temp, &wdt_reg->mode); - pr_info("%s, write reg 0x%08x val 0x%08x\n", __func__, (u32)&wdt_reg->mode, temp); + pr_debug("%s, write reg 0x%08x val 0x%08x\n", __func__, (u32)&wdt_reg->mode, temp); return 0; } diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod index 5a6044ce..9ef9275f 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod @@ -1,2 +1,2 @@ -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers index 9bee3964..db85f2e1 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers @@ -1,21 +1,21 @@ -0x62c42e0c _mali_profiling_get_api_version /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x8164b1cc ump_dd_handle_create_from_secure_id /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xb9ac0503 mali_set_user_setting /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x94289922 mali_pmu_powerdown /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x2a7049ed mali_perf_set_num_pp_cores /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x0d8ccbae mali_dev_resume /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x7c2fb465 mali_dev_pause /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8224b12 mali_get_user_setting /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x428fd838 _mali_profiling_set_event /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xcdcdf6bf _mali_profiling_get_l2_counters /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x4580d143 _mali_profiling_control /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x706fc943 mali_pmu_powerup /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xdcd285aa _mali_profiling_get_mali_version /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x62c42e0c _mali_profiling_get_api_version /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xb9ac0503 mali_set_user_setting /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x94289922 mali_pmu_powerdown /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x2a7049ed mali_perf_set_num_pp_cores /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x0d8ccbae mali_dev_resume /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x7c2fb465 mali_dev_pause /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8224b12 mali_get_user_setting /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x428fd838 _mali_profiling_set_event /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xcdcdf6bf _mali_profiling_get_l2_counters /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x4580d143 _mali_profiling_control /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x706fc943 mali_pmu_powerup /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xdcd285aa _mali_profiling_get_mali_version /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod index f5433d5e..79a1b25e 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod @@ -1,2 +1,2 @@ -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers index 9207cb57..020ed34a 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers @@ -1,9 +1,9 @@ -0x8164b1cc ump_dd_handle_create_from_secure_id /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod index 4bfe793a..96c6764e 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod @@ -1,2 +1,2 @@ -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko -/home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /home/LoBo2_Razno/OrangePI/kernel_3.4.9/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko +/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o From cecec660a3af2f44b39791660f48df2b4367bef7 Mon Sep 17 00:00:00 2001 From: Leonardo Lontra Date: Mon, 4 Apr 2016 21:31:38 -0300 Subject: [PATCH 02/26] gc2035: It supports the following resolutions 800x600 / 640x480 / 320x240 @ 20fps --- .../media/video/sunxi-vfe/device/gc2035.c | 115 ++++++++++++------ 1 file changed, 78 insertions(+), 37 deletions(-) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index 689efad9..d7e02531 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -18,12 +18,11 @@ #include "camera.h" -MODULE_AUTHOR("raymonxiu"); -MODULE_DESCRIPTION("A low-level driver for GalaxyCore gc2035 sensors"); +MODULE_AUTHOR("raymonxiu / leonardo lontra"); +MODULE_DESCRIPTION("A low-level driver for GalaxyCore gc2035 sensors\n\t\tWorks fine with 800x600 / 640x480 / 320x240 @ 20fps"); MODULE_LICENSE("GPL"); - //for internel driver debug #define DEV_DBG_EN 0 #if(DEV_DBG_EN == 1) @@ -45,7 +44,7 @@ MODULE_LICENSE("GPL"); } //define module timing -#define MCLK (24*1000*1000) +#define MCLK (34*1000*1000) #define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING @@ -68,7 +67,7 @@ MODULE_LICENSE("GPL"); /* * Our nominal (default) frame rate. */ -#define SENSOR_FRAME_RATE 15 +#define SENSOR_FRAME_RATE 20 @@ -680,17 +679,18 @@ static struct regval_list sensor_default_regs[] = { /////1600x1200size// {0xfe, 0x00},// {0x90, 0x01}, //0x//crop enable +{0x94, 0x04}, {0x95, 0x04}, //0x//1600x1200 {0x96, 0xb0}, {0x97, 0x06}, {0x98, 0x40}, {0xfe , 0x03}, +{0x40 , 0x40}, //00 +{0x41 , 0x02}, // Pclk_polarity {0x42 , 0x40}, -{0x43 , 0x06}, //output buf width -{0x41 , 0x02}, // Pclk_polarity -{0x40 , 0x40}, //00 -{0x17 , 0x00}, //widv +{0x43 , 0x06}, //output buf width +{0x17 , 0x01}, //widv {0xfe , 0x00}, ////output DVP///// @@ -700,28 +700,6 @@ static struct regval_list sensor_default_regs[] = { {0xf3 , 0xff}, {0xf4 , 0x00}, {0xf5 , 0x30}, - ////////sabsumple 800X600////// -{0xfe , 0x00}, -{0xb6 , 0x03}, -{0xfa , 0x00}, - -{0xc8 , 0x00},//close scaler -{0x99 , 0x22},// 1/2 subsample -{0x9a , 0x07}, -{0x9b , 0x00}, -{0x9c , 0x00}, -{0x9d , 0x00}, -{0x9e , 0x00}, -{0x9f , 0x00}, -{0xa0 , 0x00}, -{0xa1 , 0x00}, -{0xa2 , 0x00}, - -{0x90 , 0x01}, //crop enable -{0x95 , 0x02}, -{0x96 , 0x58}, -{0x97 , 0x03}, -{0x98 , 0x20}, #if 1 ///////// re zao/// @@ -741,7 +719,8 @@ static struct regval_list sensor_default_regs[] = { {0xb0 , 0x88}, {0x38 , 0x0b}, {0x39 , 0x30}, -{0xfe , 0x00}, +{0xfe , 0x00}, + {0x87 , 0xb0}, //// small RGB gamma//// @@ -810,7 +789,7 @@ static struct regval_list sensor_uxga_regs[] ={ }; -/* 800X600 SVGA,30fps*/ +/* 800X600 SVGA,20fps*/ static struct regval_list sensor_svga_regs[] = { {0xfe,0x00}, @@ -836,6 +815,58 @@ static struct regval_list sensor_svga_regs[] = {0x98,0x20}, }; +/* 640x480 VGA,20fps*/ +static struct regval_list sensor_vga_regs[] = +{ +{0xfe,0x00}, +{0xb6,0x03}, +{0xfa,0x00}, +{0xc8,0x02}, //close scaler + +{0x99,0x22},// 1/2 subsample +{0x9a,0x06}, +{0x9b,0x00}, +{0x9c,0x00}, +{0x9d,0x00}, +{0x9e,0x00}, +{0x9f,0x00}, +{0xa0,0x00}, +{0xa1,0x00}, +{0xa2,0x00}, + +{0x90,0x01}, //crop enable +{0x95,0x02}, +{0x96,0x58}, +{0x97,0x03}, +{0x98,0x20}, +}; + +/* 320x240 QVGA,20fps*/ +static struct regval_list sensor_qvga_regs[] = +{ +{0xfe,0x00}, +{0xb6,0x03}, +{0xfa,0x00}, +{0xc8,0x02}, //close scaler + +{0x99,0x44},// 1/2 subsample +{0x9a,0x06}, +{0x9b,0x00}, +{0x9c,0x00}, +{0x9d,0x00}, +{0x9e,0x00}, +{0x9f,0x00}, +{0xa0,0x00}, +{0xa1,0x00}, +{0xa2,0x00}, + +{0x90,0x01}, //crop enable +{0x95,0x02}, +{0x96,0x58}, +{0x97,0x03}, +{0x98,0x20}, +}; + ////1280*720---init---/// //static struct regval_list Gc2015_sensor_hd720_regs[] = { // @@ -2457,7 +2488,6 @@ sensor_win_sizes[] = { .set_size = NULL, }, /* VGA */ - /* { .width = VGA_WIDTH, .height = VGA_HEIGHT, @@ -2467,7 +2497,18 @@ sensor_win_sizes[] = { .regs_size = ARRAY_SIZE(sensor_vga_regs), .set_size = NULL, }, - */ + /* QVGA */ + { + .width = QVGA_WIDTH, + .height = QVGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_qvga_regs, + .regs_size = ARRAY_SIZE(sensor_qvga_regs), + .set_size = NULL, + }, + + }; #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) @@ -2580,7 +2621,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, if (ret) return ret; - if((wsize->width==1600)&&(wsize->height==1200)) //capture mode >640*480 + if((wsize->width==UXGA_WIDTH)&&(wsize->height==UXGA_HEIGHT)) //capture mode >640*480 { // printk(" read 2035 exptime 11111111\n" ); @@ -2621,7 +2662,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, ////////// #if 1 - if((wsize->width==1600)&&(wsize->height==1200)) + if((wsize->width==UXGA_WIDTH)&&(wsize->height==UXGA_HEIGHT)) { From 4ded62db01874caf7e8a84848869c8ce05752049 Mon Sep 17 00:00:00 2001 From: Leonardo Lontra Date: Mon, 2 May 2016 10:49:40 -0300 Subject: [PATCH 03/26] added rtl8192cu-fixes added v4l2loopback io scheduler (default: noop) governor (default: ondemand) --- build/sun8iw7p1smp_lobo_defconfig | 15 +- build/sun8iw7p1smp_lobo_defconfig.old | 13 +- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 15 +- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35565 -> 35129 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 96 +- .../arm/mach-sunxi/power/brom/resumes.map | 13 +- .../media/video/sunxi-vfe/device/gc2035.c | 8 +- rtl8192cu-fixes/.gitignore | 8 + .../8192cu-disable-power-management.conf | 7 + rtl8192cu-fixes/Makefile | 635 + rtl8192cu-fixes/README.md | 75 + rtl8192cu-fixes/blacklist-native-rtl8192.conf | 6 + rtl8192cu-fixes/clean | 5 + rtl8192cu-fixes/core/efuse/rtw_efuse.c | 1147 ++ rtl8192cu-fixes/core/rtw_ap.c | 2940 ++++ rtl8192cu-fixes/core/rtw_br_ext.c | 1699 ++ rtl8192cu-fixes/core/rtw_cmd.c | 3035 ++++ rtl8192cu-fixes/core/rtw_debug.c | 1337 ++ rtl8192cu-fixes/core/rtw_eeprom.c | 423 + rtl8192cu-fixes/core/rtw_ieee80211.c | 1915 +++ rtl8192cu-fixes/core/rtw_io.c | 464 + rtl8192cu-fixes/core/rtw_ioctl_query.c | 196 + rtl8192cu-fixes/core/rtw_ioctl_rtl.c | 1031 ++ rtl8192cu-fixes/core/rtw_ioctl_set.c | 1494 ++ rtl8192cu-fixes/core/rtw_iol.c | 263 + rtl8192cu-fixes/core/rtw_mlme.c | 3967 +++++ rtl8192cu-fixes/core/rtw_mlme_ext.c | 13600 ++++++++++++++++ rtl8192cu-fixes/core/rtw_mp.c | 1324 ++ rtl8192cu-fixes/core/rtw_mp_ioctl.c | 2954 ++++ rtl8192cu-fixes/core/rtw_p2p.c | 5294 ++++++ rtl8192cu-fixes/core/rtw_pwrctrl.c | 1540 ++ rtl8192cu-fixes/core/rtw_recv.c | 4289 +++++ rtl8192cu-fixes/core/rtw_rf.c | 95 + rtl8192cu-fixes/core/rtw_security.c | 3115 ++++ rtl8192cu-fixes/core/rtw_sreset.c | 352 + rtl8192cu-fixes/core/rtw_sta_mgt.c | 848 + rtl8192cu-fixes/core/rtw_tdls.c | 2941 ++++ rtl8192cu-fixes/core/rtw_wlan_util.c | 2305 +++ rtl8192cu-fixes/core/rtw_xmit.c | 4156 +++++ rtl8192cu-fixes/dkms.conf | 6 + rtl8192cu-fixes/hal/HalPwrSeqCmd.c | 177 + rtl8192cu-fixes/hal/dm.c | 314 + rtl8192cu-fixes/hal/dm.h | 30 + rtl8192cu-fixes/hal/hal_com.c | 371 + rtl8192cu-fixes/hal/hal_intf.c | 546 + rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c | 1159 ++ rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c | 5056 ++++++ .../hal/rtl8192c/rtl8192c_hal_init.c | 3628 +++++ rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c | 1207 ++ .../hal/rtl8192c/rtl8192c_phycfg.c | 4841 ++++++ .../hal/rtl8192c/rtl8192c_rf6052.c | 1031 ++ .../hal/rtl8192c/rtl8192c_rxdesc.c | 876 + .../hal/rtl8192c/rtl8192c_sreset.c | 94 + rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c | 63 + .../hal/rtl8192c/usb/Hal8192CUHWImg.c | 8758 ++++++++++ .../hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c | 2564 +++ .../hal/rtl8192c/usb/rtl8192cu_led.c | 2675 +++ .../hal/rtl8192c/usb/rtl8192cu_recv.c | 229 + .../hal/rtl8192c/usb/rtl8192cu_xmit.c | 1150 ++ .../hal/rtl8192c/usb/usb_halinit.c | 6261 +++++++ rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c | 1207 ++ .../hal/rtl8192c/usb/usb_ops_linux.c | 1536 ++ rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c | 1265 ++ rtl8192cu-fixes/include/Hal8192CEHWImg.h | 85 + rtl8192cu-fixes/include/Hal8192CPhyCfg.h | 428 + rtl8192cu-fixes/include/Hal8192CPhyReg.h | 1123 ++ rtl8192cu-fixes/include/Hal8192CUHWImg.h | 105 + .../include/Hal8192CUHWImg_wowlan.h | 34 + rtl8192cu-fixes/include/Hal8192DEHWImg.h | 66 + rtl8192cu-fixes/include/Hal8192DPhyCfg.h | 528 + rtl8192cu-fixes/include/Hal8192DPhyReg.h | 1171 ++ rtl8192cu-fixes/include/Hal8192DUHWImg.h | 66 + .../include/Hal8192DUHWImg_wowlan.h | 30 + rtl8192cu-fixes/include/HalPwrSeqCmd.h | 137 + rtl8192cu-fixes/include/autoconf.h | 336 + rtl8192cu-fixes/include/basic_types.h | 321 + .../include/byteorder/big_endian.h | 87 + rtl8192cu-fixes/include/byteorder/generic.h | 212 + .../include/byteorder/little_endian.h | 89 + rtl8192cu-fixes/include/byteorder/swab.h | 140 + rtl8192cu-fixes/include/byteorder/swabb.h | 156 + rtl8192cu-fixes/include/circ_buf.h | 27 + rtl8192cu-fixes/include/cmd_osdep.h | 36 + rtl8192cu-fixes/include/drv_conf.h | 78 + rtl8192cu-fixes/include/drv_types.h | 662 + rtl8192cu-fixes/include/drv_types_ce.h | 92 + rtl8192cu-fixes/include/drv_types_linux.h | 25 + rtl8192cu-fixes/include/drv_types_sdio.h | 70 + rtl8192cu-fixes/include/drv_types_xp.h | 95 + rtl8192cu-fixes/include/ethernet.h | 41 + rtl8192cu-fixes/include/h2clbk.h | 35 + rtl8192cu-fixes/include/hal_com.h | 146 + rtl8192cu-fixes/include/hal_intf.h | 432 + rtl8192cu-fixes/include/ieee80211.h | 1580 ++ rtl8192cu-fixes/include/ieee80211_ext.h | 477 + rtl8192cu-fixes/include/if_ether.h | 112 + rtl8192cu-fixes/include/ioctl_cfg80211.h | 180 + rtl8192cu-fixes/include/ip.h | 141 + rtl8192cu-fixes/include/linux/wireless.h | 90 + rtl8192cu-fixes/include/mlme_osdep.h | 40 + rtl8192cu-fixes/include/mp_custom_oid.h | 353 + rtl8192cu-fixes/include/nic_spec.h | 47 + rtl8192cu-fixes/include/osdep_ce_service.h | 171 + rtl8192cu-fixes/include/osdep_intf.h | 155 + rtl8192cu-fixes/include/osdep_service.h | 1815 +++ rtl8192cu-fixes/include/pci_hal.h | 168 + rtl8192cu-fixes/include/pci_ops.h | 60 + rtl8192cu-fixes/include/pci_osintf.h | 33 + rtl8192cu-fixes/include/recv_osdep.h | 58 + rtl8192cu-fixes/include/rtl8192c_cmd.h | 153 + rtl8192cu-fixes/include/rtl8192c_dm.h | 516 + rtl8192cu-fixes/include/rtl8192c_event.h | 28 + rtl8192cu-fixes/include/rtl8192c_hal.h | 937 ++ rtl8192cu-fixes/include/rtl8192c_led.h | 42 + rtl8192cu-fixes/include/rtl8192c_recv.h | 184 + rtl8192cu-fixes/include/rtl8192c_rf.h | 92 + rtl8192cu-fixes/include/rtl8192c_spec.h | 1865 +++ rtl8192cu-fixes/include/rtl8192c_sreset.h | 32 + rtl8192cu-fixes/include/rtl8192c_xmit.h | 129 + rtl8192cu-fixes/include/rtl8192d_cmd.h | 142 + rtl8192cu-fixes/include/rtl8192d_dm.h | 420 + rtl8192cu-fixes/include/rtl8192d_hal.h | 1126 ++ rtl8192cu-fixes/include/rtl8192d_led.h | 43 + rtl8192cu-fixes/include/rtl8192d_recv.h | 187 + rtl8192cu-fixes/include/rtl8192d_rf.h | 97 + rtl8192cu-fixes/include/rtl8192d_spec.h | 1841 +++ rtl8192cu-fixes/include/rtl8192d_xmit.h | 145 + rtl8192cu-fixes/include/rtw_android.h | 90 + rtl8192cu-fixes/include/rtw_ap.h | 64 + rtl8192cu-fixes/include/rtw_br_ext.h | 76 + rtl8192cu-fixes/include/rtw_byteorder.h | 40 + rtl8192cu-fixes/include/rtw_cmd.h | 1167 ++ rtl8192cu-fixes/include/rtw_debug.h | 538 + rtl8192cu-fixes/include/rtw_eeprom.h | 152 + rtl8192cu-fixes/include/rtw_efuse.h | 124 + rtl8192cu-fixes/include/rtw_event.h | 154 + rtl8192cu-fixes/include/rtw_ht.h | 50 + rtl8192cu-fixes/include/rtw_io.h | 504 + rtl8192cu-fixes/include/rtw_ioctl.h | 269 + rtl8192cu-fixes/include/rtw_ioctl_query.h | 36 + rtl8192cu-fixes/include/rtw_ioctl_rtl.h | 83 + rtl8192cu-fixes/include/rtw_ioctl_set.h | 79 + rtl8192cu-fixes/include/rtw_iol.h | 89 + rtl8192cu-fixes/include/rtw_led.h | 217 + rtl8192cu-fixes/include/rtw_mlme.h | 844 + rtl8192cu-fixes/include/rtw_mlme_ext.h | 963 ++ rtl8192cu-fixes/include/rtw_mp.h | 712 + rtl8192cu-fixes/include/rtw_mp_ioctl.h | 596 + rtl8192cu-fixes/include/rtw_mp_phy_regdef.h | 1097 ++ rtl8192cu-fixes/include/rtw_p2p.h | 161 + rtl8192cu-fixes/include/rtw_pwrctrl.h | 362 + rtl8192cu-fixes/include/rtw_qos.h | 40 + rtl8192cu-fixes/include/rtw_recv.h | 731 + rtl8192cu-fixes/include/rtw_rf.h | 152 + rtl8192cu-fixes/include/rtw_security.h | 447 + rtl8192cu-fixes/include/rtw_sreset.h | 74 + rtl8192cu-fixes/include/rtw_tdls.h | 143 + rtl8192cu-fixes/include/rtw_version.h | 1 + rtl8192cu-fixes/include/rtw_xmit.h | 754 + rtl8192cu-fixes/include/sta_info.h | 432 + rtl8192cu-fixes/include/usb_hal.h | 37 + rtl8192cu-fixes/include/usb_ops.h | 110 + rtl8192cu-fixes/include/usb_ops_linux.h | 63 + rtl8192cu-fixes/include/usb_osintf.h | 38 + rtl8192cu-fixes/include/usb_vendor_req.h | 59 + rtl8192cu-fixes/include/wifi.h | 1246 ++ rtl8192cu-fixes/include/wlan_bssdef.h | 703 + rtl8192cu-fixes/include/xmit_osdep.h | 95 + rtl8192cu-fixes/installer.sh | 2 + rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c | 5489 +++++++ rtl8192cu-fixes/os_dep/linux/ioctl_linux.c | 11909 ++++++++++++++ rtl8192cu-fixes/os_dep/linux/mlme_linux.c | 586 + rtl8192cu-fixes/os_dep/linux/os_intfs.c | 2758 ++++ rtl8192cu-fixes/os_dep/linux/pci_intf.c | 1997 +++ rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c | 24 + rtl8192cu-fixes/os_dep/linux/recv_linux.c | 448 + rtl8192cu-fixes/os_dep/linux/rtw_android.c | 839 + rtl8192cu-fixes/os_dep/linux/usb_intf.c | 1660 ++ rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c | 649 + rtl8192cu-fixes/os_dep/linux/xmit_linux.c | 421 + rtl8192cu-fixes/os_dep/osdep_service.c | 2300 +++ rtl8192cu-fixes/runwpa | 20 + v4l2loopback | 1 + 183 files changed, 171542 insertions(+), 129 deletions(-) create mode 100644 rtl8192cu-fixes/.gitignore create mode 100644 rtl8192cu-fixes/8192cu-disable-power-management.conf create mode 100644 rtl8192cu-fixes/Makefile create mode 100644 rtl8192cu-fixes/README.md create mode 100644 rtl8192cu-fixes/blacklist-native-rtl8192.conf create mode 100644 rtl8192cu-fixes/clean create mode 100755 rtl8192cu-fixes/core/efuse/rtw_efuse.c create mode 100755 rtl8192cu-fixes/core/rtw_ap.c create mode 100755 rtl8192cu-fixes/core/rtw_br_ext.c create mode 100755 rtl8192cu-fixes/core/rtw_cmd.c create mode 100755 rtl8192cu-fixes/core/rtw_debug.c create mode 100755 rtl8192cu-fixes/core/rtw_eeprom.c create mode 100755 rtl8192cu-fixes/core/rtw_ieee80211.c create mode 100755 rtl8192cu-fixes/core/rtw_io.c create mode 100755 rtl8192cu-fixes/core/rtw_ioctl_query.c create mode 100755 rtl8192cu-fixes/core/rtw_ioctl_rtl.c create mode 100755 rtl8192cu-fixes/core/rtw_ioctl_set.c create mode 100755 rtl8192cu-fixes/core/rtw_iol.c create mode 100755 rtl8192cu-fixes/core/rtw_mlme.c create mode 100755 rtl8192cu-fixes/core/rtw_mlme_ext.c create mode 100755 rtl8192cu-fixes/core/rtw_mp.c create mode 100755 rtl8192cu-fixes/core/rtw_mp_ioctl.c create mode 100755 rtl8192cu-fixes/core/rtw_p2p.c create mode 100755 rtl8192cu-fixes/core/rtw_pwrctrl.c create mode 100755 rtl8192cu-fixes/core/rtw_recv.c create mode 100755 rtl8192cu-fixes/core/rtw_rf.c create mode 100755 rtl8192cu-fixes/core/rtw_security.c create mode 100755 rtl8192cu-fixes/core/rtw_sreset.c create mode 100755 rtl8192cu-fixes/core/rtw_sta_mgt.c create mode 100755 rtl8192cu-fixes/core/rtw_tdls.c create mode 100755 rtl8192cu-fixes/core/rtw_wlan_util.c create mode 100755 rtl8192cu-fixes/core/rtw_xmit.c create mode 100644 rtl8192cu-fixes/dkms.conf create mode 100755 rtl8192cu-fixes/hal/HalPwrSeqCmd.c create mode 100755 rtl8192cu-fixes/hal/dm.c create mode 100755 rtl8192cu-fixes/hal/dm.h create mode 100755 rtl8192cu-fixes/hal/hal_com.c create mode 100755 rtl8192cu-fixes/hal/hal_intf.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c create mode 100755 rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c create mode 100755 rtl8192cu-fixes/include/Hal8192CEHWImg.h create mode 100755 rtl8192cu-fixes/include/Hal8192CPhyCfg.h create mode 100755 rtl8192cu-fixes/include/Hal8192CPhyReg.h create mode 100755 rtl8192cu-fixes/include/Hal8192CUHWImg.h create mode 100755 rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h create mode 100755 rtl8192cu-fixes/include/Hal8192DEHWImg.h create mode 100755 rtl8192cu-fixes/include/Hal8192DPhyCfg.h create mode 100755 rtl8192cu-fixes/include/Hal8192DPhyReg.h create mode 100755 rtl8192cu-fixes/include/Hal8192DUHWImg.h create mode 100755 rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h create mode 100755 rtl8192cu-fixes/include/HalPwrSeqCmd.h create mode 100755 rtl8192cu-fixes/include/autoconf.h create mode 100755 rtl8192cu-fixes/include/basic_types.h create mode 100755 rtl8192cu-fixes/include/byteorder/big_endian.h create mode 100755 rtl8192cu-fixes/include/byteorder/generic.h create mode 100755 rtl8192cu-fixes/include/byteorder/little_endian.h create mode 100755 rtl8192cu-fixes/include/byteorder/swab.h create mode 100755 rtl8192cu-fixes/include/byteorder/swabb.h create mode 100755 rtl8192cu-fixes/include/circ_buf.h create mode 100755 rtl8192cu-fixes/include/cmd_osdep.h create mode 100755 rtl8192cu-fixes/include/drv_conf.h create mode 100755 rtl8192cu-fixes/include/drv_types.h create mode 100755 rtl8192cu-fixes/include/drv_types_ce.h create mode 100755 rtl8192cu-fixes/include/drv_types_linux.h create mode 100755 rtl8192cu-fixes/include/drv_types_sdio.h create mode 100755 rtl8192cu-fixes/include/drv_types_xp.h create mode 100755 rtl8192cu-fixes/include/ethernet.h create mode 100755 rtl8192cu-fixes/include/h2clbk.h create mode 100755 rtl8192cu-fixes/include/hal_com.h create mode 100755 rtl8192cu-fixes/include/hal_intf.h create mode 100755 rtl8192cu-fixes/include/ieee80211.h create mode 100755 rtl8192cu-fixes/include/ieee80211_ext.h create mode 100755 rtl8192cu-fixes/include/if_ether.h create mode 100755 rtl8192cu-fixes/include/ioctl_cfg80211.h create mode 100755 rtl8192cu-fixes/include/ip.h create mode 100755 rtl8192cu-fixes/include/linux/wireless.h create mode 100755 rtl8192cu-fixes/include/mlme_osdep.h create mode 100755 rtl8192cu-fixes/include/mp_custom_oid.h create mode 100755 rtl8192cu-fixes/include/nic_spec.h create mode 100755 rtl8192cu-fixes/include/osdep_ce_service.h create mode 100755 rtl8192cu-fixes/include/osdep_intf.h create mode 100755 rtl8192cu-fixes/include/osdep_service.h create mode 100755 rtl8192cu-fixes/include/pci_hal.h create mode 100755 rtl8192cu-fixes/include/pci_ops.h create mode 100755 rtl8192cu-fixes/include/pci_osintf.h create mode 100755 rtl8192cu-fixes/include/recv_osdep.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_cmd.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_dm.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_event.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_hal.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_led.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_recv.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_rf.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_spec.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_sreset.h create mode 100755 rtl8192cu-fixes/include/rtl8192c_xmit.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_cmd.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_dm.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_hal.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_led.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_recv.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_rf.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_spec.h create mode 100755 rtl8192cu-fixes/include/rtl8192d_xmit.h create mode 100755 rtl8192cu-fixes/include/rtw_android.h create mode 100755 rtl8192cu-fixes/include/rtw_ap.h create mode 100755 rtl8192cu-fixes/include/rtw_br_ext.h create mode 100755 rtl8192cu-fixes/include/rtw_byteorder.h create mode 100755 rtl8192cu-fixes/include/rtw_cmd.h create mode 100755 rtl8192cu-fixes/include/rtw_debug.h create mode 100755 rtl8192cu-fixes/include/rtw_eeprom.h create mode 100755 rtl8192cu-fixes/include/rtw_efuse.h create mode 100755 rtl8192cu-fixes/include/rtw_event.h create mode 100755 rtl8192cu-fixes/include/rtw_ht.h create mode 100755 rtl8192cu-fixes/include/rtw_io.h create mode 100755 rtl8192cu-fixes/include/rtw_ioctl.h create mode 100755 rtl8192cu-fixes/include/rtw_ioctl_query.h create mode 100755 rtl8192cu-fixes/include/rtw_ioctl_rtl.h create mode 100755 rtl8192cu-fixes/include/rtw_ioctl_set.h create mode 100755 rtl8192cu-fixes/include/rtw_iol.h create mode 100755 rtl8192cu-fixes/include/rtw_led.h create mode 100755 rtl8192cu-fixes/include/rtw_mlme.h create mode 100755 rtl8192cu-fixes/include/rtw_mlme_ext.h create mode 100755 rtl8192cu-fixes/include/rtw_mp.h create mode 100755 rtl8192cu-fixes/include/rtw_mp_ioctl.h create mode 100755 rtl8192cu-fixes/include/rtw_mp_phy_regdef.h create mode 100755 rtl8192cu-fixes/include/rtw_p2p.h create mode 100755 rtl8192cu-fixes/include/rtw_pwrctrl.h create mode 100755 rtl8192cu-fixes/include/rtw_qos.h create mode 100755 rtl8192cu-fixes/include/rtw_recv.h create mode 100755 rtl8192cu-fixes/include/rtw_rf.h create mode 100755 rtl8192cu-fixes/include/rtw_security.h create mode 100755 rtl8192cu-fixes/include/rtw_sreset.h create mode 100755 rtl8192cu-fixes/include/rtw_tdls.h create mode 100644 rtl8192cu-fixes/include/rtw_version.h create mode 100755 rtl8192cu-fixes/include/rtw_xmit.h create mode 100755 rtl8192cu-fixes/include/sta_info.h create mode 100755 rtl8192cu-fixes/include/usb_hal.h create mode 100755 rtl8192cu-fixes/include/usb_ops.h create mode 100755 rtl8192cu-fixes/include/usb_ops_linux.h create mode 100755 rtl8192cu-fixes/include/usb_osintf.h create mode 100755 rtl8192cu-fixes/include/usb_vendor_req.h create mode 100755 rtl8192cu-fixes/include/wifi.h create mode 100755 rtl8192cu-fixes/include/wlan_bssdef.h create mode 100755 rtl8192cu-fixes/include/xmit_osdep.h create mode 100644 rtl8192cu-fixes/installer.sh create mode 100755 rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c create mode 100755 rtl8192cu-fixes/os_dep/linux/ioctl_linux.c create mode 100755 rtl8192cu-fixes/os_dep/linux/mlme_linux.c create mode 100755 rtl8192cu-fixes/os_dep/linux/os_intfs.c create mode 100755 rtl8192cu-fixes/os_dep/linux/pci_intf.c create mode 100755 rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c create mode 100755 rtl8192cu-fixes/os_dep/linux/recv_linux.c create mode 100755 rtl8192cu-fixes/os_dep/linux/rtw_android.c create mode 100755 rtl8192cu-fixes/os_dep/linux/usb_intf.c create mode 100755 rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c create mode 100755 rtl8192cu-fixes/os_dep/linux/xmit_linux.c create mode 100755 rtl8192cu-fixes/os_dep/osdep_service.c create mode 100755 rtl8192cu-fixes/runwpa create mode 160000 v4l2loopback diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index c4629549..d0e65c24 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -237,9 +237,9 @@ CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -2666,7 +2666,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=y +CONFIG_RTC_DRV_SUNXI=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -2984,8 +2984,7 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index c4629549..3f15ff9e 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -237,9 +237,9 @@ CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -2984,8 +2984,7 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index c4629549..d0e65c24 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -237,9 +237,9 @@ CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set # CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -2666,7 +2666,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=y +CONFIG_RTC_DRV_SUNXI=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -2984,8 +2984,7 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 9a7be50dac11a2fa10c37622f772a32a843d3a18..f9b2a111f638a4185c61ecec9ed99702562b49b3 100755 GIT binary patch delta 169 zcmaDmm1*ZBrU?qd9jy!?z-q#vz`(?y!NASHvC;Td3z$%mW0`P}_N6&!;VjP#6*7#JHS%Qn>uG72&Xun95>F*0*VbEt9%vreAb zRL2gogNea@^5Q0=Kn8}Q)Z)_IRG=XYj6iV)Rwj_y%qJNb^+CWGL>TBZE9wDB0}#gu zMlkc}=`-`|f#jLpnwa_Yn3xzC88?eJvoWcFOp*a&CI&~KsVpEa*v)IeEC?}KrZt;S zFC{gpG(A4CC^0WRwRmEo_T&w%HjK9>zim}!-PQ#3;bhS^Wj4=dpu-p^+qEe%`L#?= zYExs{(>l4UP0dmP=oe!oGr?W}^0R>$#s*180M#jg7*N15`CywkYXwlWYVzGSW!@_t w3=9*18n}V-LX&yhrI}K?CTq1%(^b diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst index cb52a0e5..3ff15e18 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst @@ -152,46 +152,7 @@ Disassembly of section .debug_info: 134: 00030501 andeq r0, r3, r1, lsl #10 138: 0a000000 beq 140 <__bss_end+0x64> 13c: 0000011e andeq r0, r0, lr, lsl r1 - 140: 00009500 andeq r9, r0, r0, lsl #10 - 144: 7f000200 svcvc 0x00000200 - 148: 04000000 streq r0, [r0], #-0 - 14c: 00007b01 andeq r7, r0, r1, lsl #22 - 150: 00003000 andeq r3, r0, r0 - 154: 0000dc00 andeq sp, r0, r0, lsl #24 - 158: 63726100 cmnvs r2, #0 - 15c: 72612f68 rsbvc r2, r1, #416 ; 0x1a0 - 160: 616d2f6d cmnvs sp, sp, ror #30 - 164: 732d6863 teqvc sp, #6488064 ; 0x630000 - 168: 69786e75 ldmdbvs r8!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ - 16c: 776f702f strbvc r7, [pc, -pc, lsr #32]! - 170: 622f7265 eorvs r7, pc, #1342177286 ; 0x50000006 - 174: 2f6d6f72 svccs 0x006d6f72 - 178: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 - 17c: 2e73656d cdpcs 5, 7, cr6, cr3, cr13, {3} - 180: 682f0053 stmdavs pc!, {r0, r1, r4, r6} ; - 184: 2f656d6f svccs 0x00656d6f - 188: 6e6f656c cdpvs 5, 6, cr6, cr15, cr12, {3} - 18c: 6f647261 svcvs 0x00647261 - 190: 7365442f cmnvc r5, #788529152 ; 0x2f000000 - 194: 706f746b rsbvc r7, pc, fp, ror #8 - 198: 626d652f rsbvs r6, sp, #197132288 ; 0xbc00000 - 19c: 6f746465 svcvs 0x00746465 - 1a0: 6f2f6c6f svcvs 0x002f6c6f - 1a4: 676e6172 ; instruction: 0x676e6172 - 1a8: 4b697065 blmi 1a5c344 <__bss_end+0x1a5c268> - 1ac: 656e7265 strbvs r7, [lr, #-613]! ; 0x265 - 1b0: 724f2f6c subvc r2, pc, #432 ; 0x1b0 - 1b4: 65676e61 strbvs r6, [r7, #-3681]! ; 0xe61 - 1b8: 4b2d4950 blmi b52700 <__bss_end+0xb52624> - 1bc: 656e7265 strbvs r7, [lr, #-613]! ; 0x265 - 1c0: 696c2f6c stmdbvs ip!, {r2, r3, r5, r6, r8, r9, sl, fp, sp}^ - 1c4: 2d78756e cfldr64cs mvdx7, [r8, #-440]! ; 0xfffffe48 - 1c8: 00342e33 eorseq r2, r4, r3, lsr lr - 1cc: 20554e47 subscs r4, r5, r7, asr #28 - 1d0: 32205341 eorcc r5, r0, #67108865 ; 0x4000001 - 1d4: 0032322e eorseq r3, r2, lr, lsr #4 - 1d8: Address 0x000001d8 is out of bounds. - + ... Disassembly of section .debug_abbrev: @@ -227,12 +188,7 @@ Disassembly of section .debug_abbrev: 70: 020c3f13 andeq r3, ip, #76 ; 0x4c 74: 0a00000a beq a4 78: 13490026 movtne r0, #36902 ; 0x9026 - 7c: 01000000 mrseq r0, (UNDEF: 0) - 80: 06100011 ; instruction: 0x06100011 - 84: 01120111 tsteq r2, r1, lsl r1 - 88: 081b0803 ldmdaeq fp, {r0, r1, fp} - 8c: 05130825 ldreq r0, [r3, #-2085] ; 0x825 - 90: Address 0x00000090 is out of bounds. + 7c: Address 0x0000007c is out of bounds. Disassembly of section .debug_line: @@ -268,42 +224,7 @@ Disassembly of section .debug_line: 6c: 5f656d75 svcpl 0x00656d75 70: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 74: 0200632e andeq r6, r0, #-1207959552 ; 0xb8000000 - 78: 86000000 strhi r0, [r0], -r0 - 7c: 02000000 andeq r0, r0, #0 - 80: 00003f00 andeq r3, r0, r0, lsl #30 - 84: fb010200 blx 4088e <__bss_end+0x407b2> - 88: 01000d0e tsteq r0, lr, lsl #26 - 8c: 00010101 andeq r0, r1, r1, lsl #2 - 90: 00010000 andeq r0, r1, r0 - 94: 72610100 rsbvc r0, r1, #0 - 98: 612f6863 teqvs pc, r3, ror #16 - 9c: 6d2f6d72 stcvs 13, cr6, [pc, #-456]! ; fffffedc <__bss_end+0xfffffe00> - a0: 2d686361 stclcs 3, cr6, [r8, #-388]! ; 0xfffffe7c - a4: 786e7573 stmdavc lr!, {r0, r1, r4, r5, r6, r8, sl, ip, sp, lr}^ - a8: 6f702f69 svcvs 0x00702f69 - ac: 2f726577 svccs 0x00726577 - b0: 6d6f7262 sfmvs f7, 2, [pc, #-392]! ; ffffff30 <__bss_end+0xfffffe54> - b4: 65720000 ldrbvs r0, [r2, #-0]! - b8: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 - bc: 00532e73 subseq r2, r3, r3, ror lr - c0: 00000001 andeq r0, r0, r1 - c4: 30020500 andcc r0, r2, r0, lsl #10 - c8: 03000000 movweq r0, #0 - cc: 2f0100c9 svccs 0x000100c9 - d0: 2f2f2f2f svccs 0x002f2f2f - d4: 2f2f2f33 svccs 0x002f2f33 - d8: 032f302f teqeq pc, #47 ; 0x2f - dc: 302f2e21 eorcc r2, pc, r1, lsr #28 - e0: 2f2f302f svccs 0x002f302f - e4: 2f322f2f svccs 0x00322f2f - e8: 322f2f2f eorcc r2, pc, #188 ; 0xbc - ec: 032f2f2f teqeq pc, #188 ; 0xbc - f0: 032f2e0c teqeq pc, #192 ; 0xc0 - f4: 2f2f2e0f svccs 0x002f2e0f - f8: 4603302f strmi r3, [r3], -pc, lsr #32 - fc: 2e0e0382 cdpcs 3, 0, cr0, cr14, cr2, {4} - 100: 01000202 tsteq r0, r2, lsl #4 - 104: Address 0x00000104 is out of bounds. + 78: Address 0x00000078 is out of bounds. Disassembly of section .debug_str: @@ -449,14 +370,3 @@ Disassembly of section .ARM.attributes: 2c: 22021e03 andcs r1, r2, #48 ; 0x30 30: Address 0x00000030 is out of bounds. - -Disassembly of section .debug_aranges: - -00000000 <.debug_aranges>: - 0: 0000001c andeq r0, r0, ip, lsl r0 - 4: 01410002 cmpeq r1, r2 - 8: 00040000 andeq r0, r4, r0 - c: 00000000 andeq r0, r0, r0 - 10: 00000030 andeq r0, r0, r0, lsr r0 - 14: 000000ac andeq r0, r0, ip, lsr #1 - ... diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 90fd67ef..9e7e898f 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -62,17 +62,14 @@ LOAD arch/arm/mach-sunxi/power/brom/resumes.o LOAD arch/arm/mach-sunxi/power/brom/resume_head.o OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) -.debug_info 0x00000000 0x1da +.debug_info 0x00000000 0x141 .debug_info 0x00000000 0x141 arch/arm/mach-sunxi/power/brom/resume_head.o - .debug_info 0x00000141 0x99 arch/arm/mach-sunxi/power/brom/resumes.o -.debug_abbrev 0x00000000 0x93 +.debug_abbrev 0x00000000 0x7f .debug_abbrev 0x00000000 0x7f arch/arm/mach-sunxi/power/brom/resume_head.o - .debug_abbrev 0x0000007f 0x14 arch/arm/mach-sunxi/power/brom/resumes.o -.debug_line 0x00000000 0x105 +.debug_line 0x00000000 0x7b .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o - .debug_line 0x0000007b 0x8a arch/arm/mach-sunxi/power/brom/resumes.o .debug_str 0x00000000 0x16e .debug_str 0x00000000 0x16e arch/arm/mach-sunxi/power/brom/resume_head.o @@ -93,7 +90,3 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) 0x00000000 0x35 arch/arm/mach-sunxi/power/brom/resume_head.o .ARM.attributes 0x00000035 0x21 arch/arm/mach-sunxi/power/brom/resumes.o - -.debug_aranges 0x00000000 0x20 - .debug_aranges - 0x00000000 0x20 arch/arm/mach-sunxi/power/brom/resumes.o diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index d7e02531..83b73da9 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -2722,6 +2722,7 @@ static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) struct sensor_info *info = to_state(sd); struct v4l2_fract *tpf = &cp->timeperframe; int div; + int clkrc = 1; if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -2737,10 +2738,11 @@ static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) div = 1; else if (div > 8) div = 8; - info->clkrc = (info->clkrc & 0x80) | div; + + clkrc = (clkrc & 0x80) | div; tpf->numerator = 1; tpf->denominator = SENSOR_FRAME_RATE/div; - sensor_write(sd, REG_CLKRC, info->clkrc); + sensor_write(sd, REG_CLKRC, clkrc); return 0; } @@ -3029,7 +3031,7 @@ static int sensor_probe(struct i2c_client *client, info->autowb = 1; info->wb = 0; info->clrfx = 0; - info->clkrc = 1; /* 30fps */ + //info->clkrc = 1; /* 30fps */ return 0; } diff --git a/rtl8192cu-fixes/.gitignore b/rtl8192cu-fixes/.gitignore new file mode 100644 index 00000000..587103df --- /dev/null +++ b/rtl8192cu-fixes/.gitignore @@ -0,0 +1,8 @@ +*.cmd +*.o +*.ko +*.mod.c +.tmp_versions +Module.symvers +modules.order + diff --git a/rtl8192cu-fixes/8192cu-disable-power-management.conf b/rtl8192cu-fixes/8192cu-disable-power-management.conf new file mode 100644 index 00000000..e90f3e53 --- /dev/null +++ b/rtl8192cu-fixes/8192cu-disable-power-management.conf @@ -0,0 +1,7 @@ +# Disable power management in the 8192cu driver. This works around a bug in +# some hardware where the device never wakes back up. +# Credit goes to Saqib Razaq (https://github.com/s-razaq) for the fix. + +# rtw_power_mgnt=0 disables power saving +# rtw_enusbss=0 disables USB autosuspend +options 8192cu rtw_power_mgnt=0 rtw_enusbss=0 diff --git a/rtl8192cu-fixes/Makefile b/rtl8192cu-fixes/Makefile new file mode 100644 index 00000000..dfbe076b --- /dev/null +++ b/rtl8192cu-fixes/Makefile @@ -0,0 +1,635 @@ +EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) +EXTRA_CFLAGS += -O1 +#EXTRA_CFLAGS += -O3 +#EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Wextra +#EXTRA_CFLAGS += -Werror +#EXTRA_CFLAGS += -pedantic +#EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes + +EXTRA_CFLAGS += -Wno-unused-variable +EXTRA_CFLAGS += -Wno-unused-value +EXTRA_CFLAGS += -Wno-unused-label +EXTRA_CFLAGS += -Wno-unused-parameter +EXTRA_CFLAGS += -Wno-unused-function +EXTRA_CFLAGS += -Wno-unused + +EXTRA_CFLAGS += -Wno-uninitialized + +EXTRA_CFLAGS += -I$(src)/include + +CONFIG_AUTOCFG_CP = n + +CONFIG_RTL8192C = y +CONFIG_RTL8192D = n +CONFIG_RTL8723A = n + +CONFIG_USB_HCI = y +CONFIG_PCI_HCI = n +CONFIG_SDIO_HCI = n + +CONFIG_MP_INCLUDED = n +CONFIG_POWER_SAVING = y +CONFIG_USB_AUTOSUSPEND = n +CONFIG_HW_PWRP_DETECTION = n +CONFIG_WIFI_TEST = n +CONFIG_BT_COEXISTENCE = n +CONFIG_RTL8192CU_REDEFINE_1X1 = n +CONFIG_INTEL_WIDI = n +CONFIG_WAKE_ON_WLAN = n + +CONFIG_PLATFORM_I386_PC = n +CONFIG_PLATFORM_TI_AM3517 = n +CONFIG_PLATFORM_ANDROID_X86 = n +CONFIG_PLATFORM_JB_X86 = n +CONFIG_PLATFORM_ARM_S3C2K4 = n +CONFIG_PLATFORM_ARM_PXA2XX = n +CONFIG_PLATFORM_ARM_S3C6K4 = n +CONFIG_PLATFORM_MIPS_RMI = n +CONFIG_PLATFORM_RTD2880B = n +CONFIG_PLATFORM_MIPS_AR9132 = n +CONFIG_PLATFORM_RTK_DMP = n +CONFIG_PLATFORM_MIPS_PLM = n +CONFIG_PLATFORM_MSTAR389 = n +CONFIG_PLATFORM_MT53XX = n +CONFIG_PLATFORM_ARM_MX51_241H = n +CONFIG_PLATFORM_FS_MX61 = n +CONFIG_PLATFORM_ACTIONS_ATJ227X = n +CONFIG_PLATFORM_TEGRA3_CARDHU = n +CONFIG_PLATFORM_TEGRA4_DALMORE = n +CONFIG_PLATFORM_ARM_TCC8900 = n +CONFIG_PLATFORM_ARM_TCC8920 = n +CONFIG_PLATFORM_ARM_TCC8920_JB42 = n +CONFIG_PLATFORM_ARM_RK2818 = n +CONFIG_PLATFORM_ARM_TI_PANDA = n +CONFIG_PLATFORM_MIPS_JZ4760 = n +CONFIG_PLATFORM_DMP_PHILIPS = n +CONFIG_PLATFORM_TI_DM365 = n +CONFIG_PLATFORM_MN10300 = n +CONFIG_PLATFORM_MSTAR_TITANIA12 = n +CONFIG_PLATFORM_MSTAR_A3 = n +CONFIG_PLATFORM_ARM_SUNxI = n +CONFIG_PLATFORM_ARM_SUN6I = n +CONFIG_PLATFORM_ARM_SUN8I = y + +CONFIG_DRVEXT_MODULE = n + +export TopDIR ?= $(shell pwd) + + +ifeq ($(CONFIG_RTL8192C), y) + +RTL871X = rtl8192c + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8192cu +FW_FILES := hal/$(RTL871X)/usb/Hal8192CUHWImg.o +ifneq ($(CONFIG_WAKE_ON_WLAN), n) +FW_FILES += hal/$(RTL871X)/usb/Hal8192CUHWImg_wowlan.o +endif +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8192ce +FW_FILES := hal/$(RTL871X)/pci/Hal8192CEHWImg.o +endif + +CHIP_FILES := \ + hal/$(RTL871X)/$(RTL871X)_sreset.o \ + hal/$(RTL871X)/$(RTL871X)_xmit.o +CHIP_FILES += $(FW_FILES) +endif + +ifeq ($(CONFIG_RTL8192D), y) + +RTL871X = rtl8192d + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8192du +FW_FILES := hal/$(RTL871X)/usb/Hal8192DUHWImg.o +ifneq ($(CONFIG_WAKE_ON_WLAN), n) +FW_FILES += hal/$(RTL871X)/usb/Hal8192DUHWImg_wowlan.o +endif +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8192de +FW_FILES := hal/$(RTL871X)/pci/Hal8192DEHWImg.o +endif + +CHIP_FILES := \ + hal/$(RTL871X)/$(RTL871X)_xmit.o +CHIP_FILES += $(FW_FILES) +endif + +ifeq ($(CONFIG_RTL8723A), y) + +RTL871X = rtl8723a + +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8723as +FW_FILES := hal/$(RTL871X)/sdio/Hal8723SHWImg.o +endif + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8723au +FW_FILES := hal/$(RTL871X)/usb/Hal8723UHWImg.o +endif + +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8723ae +FW_FILES := hal/$(RTL871X)/pci/Hal8723EHWImg.o +endif + +PWRSEQ_FILES := hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8723PwrSeq.o + +CHIP_FILES += $(FW_FILES) $(PWRSEQ_FILES) + +endif + +ifeq ($(CONFIG_SDIO_HCI), y) +HCI_NAME = sdio +endif + +ifeq ($(CONFIG_USB_HCI), y) +HCI_NAME = usb +endif + +ifeq ($(CONFIG_PCI_HCI), y) +HCI_NAME = pci +endif + + +_OS_INTFS_FILES := os_dep/osdep_service.o \ + os_dep/linux/os_intfs.o \ + os_dep/linux/$(HCI_NAME)_intf.o \ + os_dep/linux/$(HCI_NAME)_ops_linux.o \ + os_dep/linux/ioctl_linux.o \ + os_dep/linux/xmit_linux.o \ + os_dep/linux/mlme_linux.o \ + os_dep/linux/recv_linux.o \ + os_dep/linux/ioctl_cfg80211.o \ + os_dep/linux/rtw_android.o + + +_HAL_INTFS_FILES := hal/hal_intf.o \ + hal/hal_com.o \ + hal/dm.o \ + hal/$(RTL871X)/$(RTL871X)_hal_init.o \ + hal/$(RTL871X)/$(RTL871X)_phycfg.o \ + hal/$(RTL871X)/$(RTL871X)_rf6052.o \ + hal/$(RTL871X)/$(RTL871X)_dm.o \ + hal/$(RTL871X)/$(RTL871X)_rxdesc.o \ + hal/$(RTL871X)/$(RTL871X)_cmd.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 + +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +endif + +ifeq ($(CONFIG_MP_INCLUDED), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_mp.o +endif + +_HAL_INTFS_FILES += $(CHIP_FILES) + + +ifeq ($(CONFIG_AUTOCFG_CP), y) +$(shell cp $(TopDIR)/autoconf_$(RTL871X)_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) +endif + + +ifeq ($(CONFIG_USB_HCI), y) +ifeq ($(CONFIG_USB_AUTOSUSPEND), y) +EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND +endif +endif + +ifeq ($(CONFIG_POWER_SAVING), y) +EXTRA_CFLAGS += -DCONFIG_POWER_SAVING +endif + +ifeq ($(CONFIG_HW_PWRP_DETECTION), y) +EXTRA_CFLAGS += -DCONFIG_HW_PWRP_DETECTION +endif + +ifeq ($(CONFIG_WIFI_TEST), y) +EXTRA_CFLAGS += -DCONFIG_WIFI_TEST +endif + +ifeq ($(CONFIG_BT_COEXISTENCE), y) +EXTRA_CFLAGS += -DCONFIG_BT_COEXISTENCE +endif + +ifeq ($(CONFIG_RTL8192CU_REDEFINE_1X1), y) +EXTRA_CFLAGS += -DRTL8192C_RECONFIG_TO_1T1R +endif + +ifeq ($(CONFIG_WAKE_ON_WLAN), y) +EXTRA_CFLAGS += -DCONFIG_WAKE_ON_WLAN +endif + +ifeq ($(CONFIG_INTEL_WIDI), y) +EXTRA_CFLAGS += -DCONFIG_INTEL_WIDI +endif + +ifeq ($(CONFIG_PLATFORM_I386_PC), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) +ARCH ?= $(SUBARCH) +CROSS_COMPILE ?= +KVER := $(shell uname -r) +KSRC := /lib/modules/$(KVER)/build +MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/ +INSTALL_PREFIX := +endif + +ifeq ($(CONFIG_PLATFORM_TI_AM3517), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_SHUTTLE +CROSS_COMPILE := arm-eabi- +KSRC := $(shell pwd)/../../../Android/kernel +ARCH := arm +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR_TITANIA12), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_PLATFORM_MSTAR_TITANIA12 +ARCH:=mips +CROSS_COMPILE:= /usr/src/Mstar_kernel/mips-4.3/bin/mips-linux-gnu- +KVER:= 2.6.28.9 +KSRC:= /usr/src/Mstar_kernel/2.6.28.9/ +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR_A3), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_PLATFORM_MSTAR_A3 +ARCH:=arm +CROSS_COMPILE:= arm-none-linux-gnueabi- +KVER:= 2.6.35.11 +KSRC:= /home/gary/PERFORCE/THEALE/RedLion/2.6.35.11/ +MODULE_NAME = wlan +endif + +ifeq ($(CONFIG_PLATFORM_ANDROID_X86), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) +ARCH := $(SUBARCH) +CROSS_COMPILE := /media/DATA-2/android-x86/ics-x86_20120130/prebuilt/linux-x86/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu- +KSRC := /media/DATA-2/android-x86/ics-x86_20120130/out/target/product/generic_x86/obj/kernel +MODULE_NAME :=wlan +endif + +ifeq ($(CONFIG_PLATFORM_JB_X86), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +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) +CROSS_COMPILE := /home/android_sdk/android-x86_JB/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7/bin/i686-linux-android- +KSRC := /home/android_sdk/android-x86_JB/out/target/product/x86/obj/kernel/ +MODULE_NAME :=wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_PXA2XX), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 2.6.34.1 +KSRC ?= /usr/src/linux-2.6.34.1 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-linux- +KVER := 2.6.24.7_$(ARCH) +KSRC := /usr/src/kernels/linux-$(KVER) +endif + +ifeq ($(CONFIG_PLATFORM_ARM_S3C6K4), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 2.6.34.1 +KSRC ?= /usr/src/linux-2.6.34.1 +endif + +ifeq ($(CONFIG_PLATFORM_RTD2880B), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN -DCONFIG_PLATFORM_RTD2880B +ARCH:= +CROSS_COMPILE:= +KVER:= +KSRC:= +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_RMI), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH:=mips +CROSS_COMPILE:=mipsisa32r2-uclibc- +KVER:= +KSRC:= /root/work/kernel_realtek +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_PLM), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN +ARCH:=mips +CROSS_COMPILE:=mipsisa32r2-uclibc- +KVER:= +KSRC:= /root/work/kernel_realtek +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR389), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR389 +ARCH:=mips +CROSS_COMPILE:= mips-linux-gnu- +KVER:= 2.6.28.10 +KSRC:= /home/mstar/mstar_linux/2.6.28.9/ +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_AR9132), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN +ARCH := mips +CROSS_COMPILE := mips-openwrt-linux- +KSRC := /home/alex/test_openwrt/tmp/linux-2.6.30.9 +endif + +ifeq ($(CONFIG_PLATFORM_DMP_PHILIPS), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM +ARCH := mips +#CROSS_COMPILE:=/usr/local/msdk-4.3.6-mips-EL-2.6.12.6-0.9.30.3/bin/mipsel-linux- +CROSS_COMPILE:=/usr/local/toolchain_mipsel/bin/mipsel-linux- +KSRC ?=/usr/local/Jupiter/linux-2.6.12 +endif + +ifeq ($(CONFIG_PLATFORM_RTK_DMP), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM +ARCH:=mips +CROSS_COMPILE:=mipsel-linux- +KVER:= +KSRC ?= /usr/src/DMP_Kernel/jupiter/linux-2.6.12 +endif + +ifeq ($(CONFIG_PLATFORM_MT53XX), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MT53XX +ARCH:= arm +CROSS_COMPILE:= arm11_mtk_le- +KVER:= 2.6.27 +KSRC?= /proj/mtk00802/BD_Compare/BDP/Dev/BDP_V301/BDP_Linux/linux-2.6.27 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_MX51_241H), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_WISTRON_PLATFORM +ARCH := arm +CROSS_COMPILE := /opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi- +KVER := 2.6.31 +KSRC ?= /lib/modules/2.6.31-770-g0e46b52/source +endif + +ifeq ($(CONFIG_PLATFORM_FS_MX61), y) +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 +endif + + + +ifeq ($(CONFIG_PLATFORM_ACTIONS_ATJ227X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ACTIONS_ATJ227X +ARCH := mips +CROSS_COMPILE := /home/cnsd4/project/actions/tools-2.6.27/bin/mipsel-linux-gnu- +KVER := 2.6.27 +KSRC := /home/cnsd4/project/actions/linux-2.6.27.28 +endif + +ifeq ($(CONFIG_PLATFORM_TI_DM365), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_TI_DM365 +ARCH := arm +CROSS_COMPILE := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le- +KVER := 2.6.18 +KSRC := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/lsp/ti-davinci/linux-dm365 +endif + +ifeq ($(CONFIG_PLATFORM_TEGRA3_CARDHU), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_P2P_IPS +ARCH := arm +CROSS_COMPILE := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/out/target/product/cardhu/obj/KERNEL +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_TEGRA4_DALMORE), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_P2P_IPS +ARCH := arm +CROSS_COMPILE := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +KSRC := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/out/target/product/dalmore/obj/KERNEL +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8900), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/SDK_2304_20110613/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/SDK_2304_20110613/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8920), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8920_JB42), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# 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 +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_RK2818), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS -DCONFIG_MINIMAL_MEMORY_USAGE +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 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TI_PANDA), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN #-DCONFIG_MINIMAL_MEMORY_USAGE +ARCH := arm +#CROSS_COMPILE := /media/DATA-1/aosp/ics-aosp_20111227/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +#KSRC := /media/DATA-1/aosp/android-omap-panda-3.0_20120104 +CROSS_COMPILE := /media/DATA-1/android-4.0/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /media/DATA-1/android-4.0/panda_kernel/omap +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_JZ4760), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_MINIMAL_MEMORY_USAGE +ARCH ?= mips +CROSS_COMPILE ?= /mnt/sdb5/Ingenic/Umido/mips-4.3/bin/mips-linux-gnu- +KSRC ?= /mnt/sdb5/Ingenic/Umido/kernel +endif + +#Add setting for MN10300 +ifeq ($(CONFIG_PLATFORM_MN10300), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MN10300 +ARCH := mn10300 +CROSS_COMPILE := mn10300-linux- +KVER := 2.6.32.2 +KSRC := /home/winuser/work/Plat_sLD2T_V3010/usr/src/linux-2.6.32.2 +INSTALL_PREFIX := +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUNxI), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ARM_SUNxI +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 3.0.8 +#KSRC:= ../lichee/linux-3.0/ +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN6I +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +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 +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 3.3.0 +#KSRC:= ../lichee/linux-3.3/ +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN8I), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN8I +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +EXTRA_CFLAGS += -DCONFIG_LOAD_PHY_PARA_FROM_FILE +# sobe 2 wlans +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 +EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_P2P_IPS +ARCH := arm +CROSS_COMPILE := ../brandy/gcc-linaro/bin/arm-linux-gnueabi- +KVER := 3.4 +KSRC:= ../linux-3.4/ +endif + +ifneq ($(USER_MODULE_NAME),) +MODULE_NAME := $(USER_MODULE_NAME) +endif + +ifeq ($(CONFIG_MP_INCLUDED), y) +MODULE_NAME := $(MODULE_NAME)_mp +EXTRA_CFLAGS += -DCONFIG_MP_INCLUDED +endif + + +ifneq ($(KERNELRELEASE),) + + +rtk_core := core/rtw_cmd.o \ + core/rtw_security.o \ + core/rtw_debug.o \ + core/rtw_io.o \ + core/rtw_ioctl_query.o \ + core/rtw_ioctl_set.o \ + core/rtw_ieee80211.o \ + core/rtw_mlme.o \ + core/rtw_mlme_ext.o \ + core/rtw_wlan_util.o \ + core/rtw_pwrctrl.o \ + core/rtw_rf.o \ + core/rtw_recv.o \ + core/rtw_sta_mgt.o \ + core/rtw_ap.o \ + core/rtw_xmit.o \ + core/rtw_p2p.o \ + core/rtw_tdls.o \ + core/rtw_br_ext.o \ + core/rtw_iol.o \ + core/rtw_sreset.o + +$(MODULE_NAME)-y += $(rtk_core) + +$(MODULE_NAME)-$(CONFIG_INTEL_WIDI) += core/rtw_intel_widi.o + +$(MODULE_NAME)-y += core/efuse/rtw_efuse.o + +$(MODULE_NAME)-y += $(_HAL_INTFS_FILES) + +$(MODULE_NAME)-y += $(_OS_INTFS_FILES) + +$(MODULE_NAME)-$(CONFIG_MP_INCLUDED) += core/rtw_mp.o \ + core/rtw_mp_ioctl.o + +obj-$(CONFIG_RTL8192CU) := $(MODULE_NAME).o + +else + +export CONFIG_RTL8192CU = m + +all: modules + +modules: + $(MAKE) -j $(shell nproc) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules + +strip: + $(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded + +install: + install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) + /sbin/depmod -a ${KVER} + +uninstall: + rm -f $(MODDESTDIR)/$(MODULE_NAME).ko + /sbin/depmod -a ${KVER} + + +config_r: + @echo "make config" + /bin/bash script/Configure script/config.in + +.PHONY: modules clean + +clean: + rm -fr *.mod.c *.mod *.o .*.cmd *.ko *~ + rm .tmp_versions -fr ; rm Module.symvers -fr + rm -fr Module.markers ; rm -fr modules.order + cd core/efuse ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd hal/$(RTL871X)/$(HCI_NAME) ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd hal/$(RTL871X) ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko +endif + diff --git a/rtl8192cu-fixes/README.md b/rtl8192cu-fixes/README.md new file mode 100644 index 00000000..c484059b --- /dev/null +++ b/rtl8192cu-fixes/README.md @@ -0,0 +1,75 @@ +This is a repackaging of Realtek's own 8192CU USB WiFi driver for Ubuntu 13.10 and later. + +Compatibility +============= + +These devices are known to work with this driver: +- Belkin N300 +- TP-Link TL-WN823N +- TRENDnet TEW-648UBM N150 + +These devices are known not to be supported: +- Alfa AWUS036NHR +- TP-Link WN8200ND + +As a rule of thumb, this driver generally works with devices that use the RTL8192CU chipset, and some devices that use the RTL8188CUS, RTL8188CE-VAU and RTL8188RU chipsets too, though it's more hit and miss. + +Devices that use dual antennas are known not to work well. This appears to be an issue in the upstream Realtek driver. + +Installation +============ + +Ensure you have the necessary prerequisites installed: + + sudo apt-get update + sudo apt-get install git linux-headers-generic build-essential dkms + +Clone this repository: + + git clone https://github.com/pvaret/rtl8192cu-fixes.git + +Set it up as a DKMS module: + + sudo dkms add ./rtl8192cu-fixes + +Build and install it: + + sudo dkms install 8192cu/1.10 + +Refresh the module list: + + sudo depmod -a + +Ensure the native (and broken) kernel driver is blacklisted: + + sudo cp ./rtl8192cu-fixes/blacklist-native-rtl8192.conf /etc/modprobe.d/ + +And reboot. You're done. + +Other distributions +=================== + +The instructions above should work in every Debian-based distribution. So long as you can install the prerequisites on your own, everything after the line that contains `apt-get` should work in other distributions as well. + +On Gentoo, you can disregard the instructions above and just install the following ebuild: https://gitweb.gentoo.org/dev/maksbotan.git/tree/sys-kernel/rtl8192cu-fixes/rtl8192cu-fixes-9999.ebuild + +Troubleshooting +=============== + +There is a known issue with power management on some hardware. If your WiFi connection drops after a few minutes, install the following module setting file to disable power management in your WiFi interface: + + sudo cp ./rtl8192cu-fixes/8192cu-disable-power-management.conf /etc/modprobe.d/ + +And then reboot. + +Current status +============== + +As it currently stands, the driver doesn't populate /proc with informational data from the driver. The API for /proc has changed in recent kernels, and the driver has not been ported to the new API. + +Credits +======= + +This repository was initially based on Timothy Phillips's work as published here: https://code.google.com/p/realtek-8188cus-wireless-drivers-3444749-ubuntu-1304/, though no longer. + +Thanks go to Saqib Razaq (@s-razaq) for the power management workaround. diff --git a/rtl8192cu-fixes/blacklist-native-rtl8192.conf b/rtl8192cu-fixes/blacklist-native-rtl8192.conf new file mode 100644 index 00000000..73bf61fc --- /dev/null +++ b/rtl8192cu-fixes/blacklist-native-rtl8192.conf @@ -0,0 +1,6 @@ +## This file ships with the rtl8192-fixes DKMS module. +## Keep the native (and currently broken) kernel driver from loading so ours +## is used instead: +install rtl8192cu /bin/false +install rtl8192c_common /bin/false +install rtlwifi /bin/false diff --git a/rtl8192cu-fixes/clean b/rtl8192cu-fixes/clean new file mode 100644 index 00000000..87664218 --- /dev/null +++ b/rtl8192cu-fixes/clean @@ -0,0 +1,5 @@ +#!/bin/bash +rmmod 8192cu +rmmod 8192ce +rmmod 8192du +rmmod 8192de diff --git a/rtl8192cu-fixes/core/efuse/rtw_efuse.c b/rtl8192cu-fixes/core/efuse/rtw_efuse.c new file mode 100755 index 00000000..3d341acc --- /dev/null +++ b/rtl8192cu-fixes/core/efuse/rtw_efuse.c @@ -0,0 +1,1147 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_EFUSE_C_ + +#include +#include +#include + +#include + + + +/*------------------------Define local variable------------------------------*/ +u8 fakeEfuseBank=0; +u32 fakeEfuseUsedBytes=0; +u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]={0}; +u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]={0}; +u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]={0}; + +u32 BTEfuseUsedBytes=0; +u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0}; +u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0}; + +u32 fakeBTEfuseUsedBytes=0; +u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0}; +u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0}; +/*------------------------Define local variable------------------------------*/ + +//------------------------------------------------------------------------------ +#define REG_EFUSE_CTRL 0x0030 +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +//------------------------------------------------------------------------------ + +BOOLEAN +Efuse_Read1ByteFromFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u8 *Value ); +BOOLEAN +Efuse_Read1ByteFromFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u8 *Value ) +{ + if(Offset >= EFUSE_MAX_HW_SIZE) + { + return _FALSE; + } + //DbgPrint("Read fake content, offset = %d\n", Offset); + if(fakeEfuseBank == 0) + *Value = fakeEfuseContent[Offset]; + else + *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset]; + return _TRUE; +} + +BOOLEAN +Efuse_Write1ByteToFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value ); +BOOLEAN +Efuse_Write1ByteToFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value ) +{ + if(Offset >= EFUSE_MAX_HW_SIZE) + { + return _FALSE; + } + if(fakeEfuseBank == 0) + fakeEfuseContent[Offset] = Value; + else + { + fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value; + } + return _TRUE; +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_PowerSwitch + * + * Overview: When we want to enable write operation, we should change to + * pwr on state. When we stop write, we should switch to 500k mode + * and disable LDO 2.5V. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/17/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +Efuse_PowerSwitch( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState); +} + +/*----------------------------------------------------------------------------- + * Function: efuse_GetCurrentSize + * + * Overview: Get current efuse size!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u16 +Efuse_GetCurrentSize( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest) +{ + u16 ret=0; + + ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest); + + return ret; +} + +/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ +u8 +Efuse_CalculateWordCnts(IN u8 word_en) +{ + u8 word_cnts = 0; + if(!(word_en & BIT(0))) word_cnts++; // 0 : write enable + if(!(word_en & BIT(1))) word_cnts++; + if(!(word_en & BIT(2))) word_cnts++; + if(!(word_en & BIT(3))) word_cnts++; + return word_cnts; +} + +// +// Description: +// Execute E-Fuse read byte operation. +// Refered from SD1 Richard. +// +// Assumption: +// 1. Boot from E-Fuse and successfully auto-load. +// 2. PASSIVE_LEVEL (USB interface) +// +// Created by Roger, 2008.10.21. +// +VOID +ReadEFuseByte( + PADAPTER Adapter, + u16 _offset, + u8 *pbuf, + IN BOOLEAN bPseudoTest) +{ + u32 value32; + u8 readbyte; + u16 retry; + //u32 start=rtw_get_current_time(); + + if(bPseudoTest) + { + Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); + return; + } + + //Write Address + rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff)); + readbyte = rtw_read8(Adapter, EFUSE_CTRL+2); + rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); + + //Write bit 32 0 + readbyte = rtw_read8(Adapter, EFUSE_CTRL+3); + rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f)); + + //Check bit 32 read-ready + retry = 0; + value32 = rtw_read32(Adapter, EFUSE_CTRL); + //while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) + while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) + { + value32 = rtw_read32(Adapter, EFUSE_CTRL); + retry++; + } + + // 20100205 Joseph: Add delay suggested by SD1 Victor. + // This fix the problem that Efuse read error in high temperature condition. + // Designer says that there shall be some delay after ready bit is set, or the + // result will always stay on last data we read. + rtw_udelay_os(50); + value32 = rtw_read32(Adapter, EFUSE_CTRL); + + *pbuf = (u8)(value32 & 0xff); + //DBG_871X("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start)); + +} + + +// +// Description: +// 1. Execute E-Fuse read byte operation according as map offset and +// save to E-Fuse table. +// 2. Refered from SD1 Richard. +// +// Assumption: +// 1. Boot from E-Fuse and successfully auto-load. +// 2. PASSIVE_LEVEL (USB interface) +// +// Created by Roger, 2008.10.21. +// +// 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. +// 2. Add efuse utilization collect. +// 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 +// write addr must be after sec5. +// + +VOID +efuse_ReadEFuse( + PADAPTER Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ); +VOID +efuse_ReadEFuse( + PADAPTER Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ) +{ + Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); +} + +VOID +EFUSE_GetEfuseDefinition( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u8 type, + OUT void *pOut, + IN BOOLEAN bPseudoTest + ) +{ + pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest); +} + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Read1Byte + * + * Overview: Copy from WMAC fot EFUSE read 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ +u8 +EFUSE_Read1Byte( + IN PADAPTER Adapter, + IN u16 Address) +{ + u8 data; + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k=0; + u16 contentLen=0; + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE); + + if (Address < contentLen) //E-fuse 512Byte + { + //Write E-fuse Register address bit0~7 + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + //Write E-fuse Register address bit8~9 + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + //Write 0x30[31]=0 + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp & 0x7F; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + //Wait Write-ready (0x30[31]=1) + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while(!(Bytetemp & 0x80)) + { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if(k==1000) + { + k=0; + break; + } + } + data=rtw_read8(Adapter, EFUSE_CTRL); + return data; + } + else + return 0xFF; + +}/* EFUSE_Read1Byte */ + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Write1Byte + * + * Overview: Copy from WMAC fot EFUSE write 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ + +void +EFUSE_Write1Byte( + IN PADAPTER Adapter, + IN u16 Address, + IN u8 Value); +void +EFUSE_Write1Byte( + IN PADAPTER Adapter, + IN u16 Address, + IN u8 Value) +{ + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k=0; + u16 contentLen=0; + + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value)); + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE); + + if( Address < contentLen) //E-fuse 512Byte + { + rtw_write8(Adapter, EFUSE_CTRL, Value); + + //Write E-fuse Register address bit0~7 + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + + //Write E-fuse Register address bit8~9 + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + //Write 0x30[31]=1 + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp | 0x80; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + //Wait Write-ready (0x30[31]=0) + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while(Bytetemp & 0x80) + { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if(k==100) + { + k=0; + break; + } + } + } +}/* EFUSE_Write1Byte */ + +/* 11/16/2008 MH Read one byte from real Efuse. */ +u8 +efuse_OneByteRead( + IN PADAPTER pAdapter, + IN u16 addr, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 tmpidx = 0; + u8 bResult; + + if(bPseudoTest) + { + bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data); + return bResult; + } + // -----------------e-fuse reg ctrl --------------------------------- + //address + rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff)); + rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) | + (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC )); + + rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);//read cmd + + while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3))&&(tmpidx<100)) + { + tmpidx++; + } + if(tmpidx<100) + { + *data=rtw_read8(pAdapter, EFUSE_CTRL); + bResult = _TRUE; + } + else + { + *data = 0xff; + bResult = _FALSE; + } + return bResult; +} + +/* 11/16/2008 MH Write one byte to reald Efuse. */ +u8 +efuse_OneByteWrite( + IN PADAPTER pAdapter, + IN u16 addr, + IN u8 data, + IN BOOLEAN bPseudoTest) +{ + u8 tmpidx = 0; + u8 bResult; + + if(bPseudoTest) + { + bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data); + return bResult; + } + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data=%x\n", addr, data)); + + //return 0; + + // -----------------e-fuse reg ctrl --------------------------------- + //address + rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff)); + rtw_write8(pAdapter, EFUSE_CTRL+2, + (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC )|(u8)((addr>>8)&0x03) ); + rtw_write8(pAdapter, EFUSE_CTRL, data);//data + + rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);//write cmd + + while((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100) ){ + tmpidx++; + } + + if(tmpidx<100) + { + bResult = _TRUE; + } + else + { + bResult = _FALSE; + } + + return bResult; +} + +int +Efuse_PgPacketRead( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest); + + return ret; +} + +int +Efuse_PgPacketWrite(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret; + + ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: efuse_WordEnableDataRead + * + * Overview: Read allowed word in current efuse section data. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * 11/21/2008 MHC Fix Write bug when we only enable late word. + * + *---------------------------------------------------------------------------*/ +void +efuse_WordEnableDataRead(IN u8 word_en, + IN u8 *sourdata, + IN u8 *targetdata) +{ + if (!(word_en&BIT(0))) + { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + if (!(word_en&BIT(1))) + { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + if (!(word_en&BIT(2))) + { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + if (!(word_en&BIT(3))) + { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + + +u8 +Efuse_WordEnableDataWrite( IN PADAPTER pAdapter, + IN u16 efuse_addr, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 ret=0; + + ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); + + return ret; +} + +static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value) +{ + return efuse_OneByteRead(padapter,address, value, _FALSE); +} + +static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value) +{ + return efuse_OneByteWrite(padapter,address, *value, _FALSE); +} + +/* + * read/wirte raw efuse data + */ +u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data) +{ + int i = 0; + u16 real_content_len = 0, max_available_size = 0; + u8 res = _FAIL ; + u8 (*rw8)(PADAPTER, u16, u8*); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&real_content_len, _FALSE); + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if (start_addr > real_content_len) + return _FAIL; + + if (_TRUE == bWrite) { + if ((start_addr + cnts) > max_available_size) + return _FAIL; + rw8 = &efuse_write8; + } else + rw8 = &efuse_read8; + + Efuse_PowerSwitch(padapter, bWrite, _TRUE); + + // e-fuse one byte read / write + for (i = 0; i < cnts; i++) { + if (start_addr >= real_content_len) { + res = _FAIL; + break; + } + + res = rw8(padapter, start_addr++, data++); + if (_FAIL == res) break; + } + + Efuse_PowerSwitch(padapter, bWrite, _FALSE); + + return res; +} +//------------------------------------------------------------------------------ +u16 efuse_GetMaxSize(PADAPTER padapter) +{ + u16 max_size; + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE); + return max_size; +} +//------------------------------------------------------------------------------ +u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size) +{ + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE); + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} +//------------------------------------------------------------------------------ +u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + + efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE); + + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} +//------------------------------------------------------------------------------ +u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ + u8 offset, word_en; + u8 *map; + u8 newdata[PGPKT_DATA_SIZE]; + s32 i, j, idx; + u8 ret = _SUCCESS; + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + map = rtw_zmalloc(mapLen); + if(map == NULL){ + return _FAIL; + } + + ret = rtw_efuse_map_read(padapter, 0, mapLen, map); + if (ret == _FAIL) goto exit; + + Efuse_PowerSwitch(padapter, _TRUE, _TRUE); + + offset = (addr >> 3); + word_en = 0xF; + _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE); + i = addr & 0x7; // index of one package + j = 0; // index of new package + idx = 0; // data index + + if (i & 0x1) { + // odd start + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i-1] = map[addr+idx-1]; + newdata[i] = data[idx]; + } + i++; + idx++; + } + do { + for (; i < PGPKT_DATA_SIZE; i += 2) + { + if (cnts == idx) break; + if ((cnts - idx) == 1) { + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = map[addr+idx+1]; + } + idx++; + break; + } else { + if ((data[idx] != map[addr+idx]) || + (data[idx+1] != map[addr+idx+1])) + { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = data[idx + 1]; + } + idx += 2; + } + if (idx == cnts) break; + } + + if (word_en != 0xF) { + ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE); + DBG_871X("offset=%x \n",offset); + DBG_871X("word_en=%x \n",word_en); + + for(i=0;iefuse_eeprom_data[Offset]; + +} // EFUSE_ShadowRead1Byte + +//---------------Read Two Bytes +static VOID +efuse_ShadowRead2Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u16 *Value) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + +} // EFUSE_ShadowRead2Byte + +//---------------Read Four Bytes +static VOID +efuse_ShadowRead4Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u32 *Value) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16; + *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24; + +} // efuse_ShadowRead4Byte + + +/*----------------------------------------------------------------------------- + * Function: efuse_ShadowWrite1Byte + * efuse_ShadowWrite2Byte + * efuse_ShadowWrite4Byte + * + * Overview: Write efuse modify map by one/two/four byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +#ifdef PLATFORM +static VOID +efuse_ShadowWrite1Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value); +#endif //PLATFORM +static VOID +efuse_ShadowWrite1Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + pEEPROM->efuse_eeprom_data[Offset] = Value; + +} // efuse_ShadowWrite1Byte + +//---------------Write Two Bytes +static VOID +efuse_ShadowWrite2Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u16 Value) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + pEEPROM->efuse_eeprom_data[Offset] = Value&0x00FF; + pEEPROM->efuse_eeprom_data[Offset+1] = Value>>8; + +} // efuse_ShadowWrite1Byte + +//---------------Write Four Bytes +static VOID +efuse_ShadowWrite4Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u32 Value) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + pEEPROM->efuse_eeprom_data[Offset] = (u8)(Value&0x000000FF); + pEEPROM->efuse_eeprom_data[Offset+1] = (u8)((Value>>8)&0x0000FF); + pEEPROM->efuse_eeprom_data[Offset+2] = (u8)((Value>>16)&0x00FF); + pEEPROM->efuse_eeprom_data[Offset+3] = (u8)((Value>>24)&0xFF); + +} // efuse_ShadowWrite1Byte + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowMapUpdate + * + * Overview: Transfer current EFUSE content to shadow init and modify map. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/13/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void EFUSE_ShadowMapUpdate( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest); + + if (pEEPROM->bautoload_fail_flag == _TRUE) + { + _rtw_memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); + } + else + { + #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + if(_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM)) { + #endif + + Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest); + + #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM); + } + #endif + } + + //PlatformMoveMemory((PVOID)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], + //(PVOID)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); +}// EFUSE_ShadowMapUpdate + + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowRead + * + * Overview: Read from efuse init map !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +EFUSE_ShadowRead( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 *Value ) +{ + if (Type == 1) + efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); + else if (Type == 2) + efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); + else if (Type == 4) + efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); + +} // EFUSE_ShadowRead + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowWrite + * + * Overview: Write efuse modify map for later update operation to use!!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +EFUSE_ShadowWrite( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 Value); +VOID +EFUSE_ShadowWrite( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 Value) +{ +#if (MP_DRIVER == 0) + return; +#endif + + if (Type == 1) + efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value); + else if (Type == 2) + efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value); + else if (Type == 4) + efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value); + +} // EFUSE_ShadowWrite + +VOID +Efuse_InitSomeVar( + IN PADAPTER pAdapter + ); +VOID +Efuse_InitSomeVar( + IN PADAPTER pAdapter + ) +{ + u8 i; + + _rtw_memset((PVOID)&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE); + _rtw_memset((PVOID)&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN); + _rtw_memset((PVOID)&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN); + + for(i=0; i + + int isAdaptorInfoFileValid(void) +{ + return _TRUE; +} + +int storeAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv) +{ + int ret =_SUCCESS; + + if(path && eeprom_priv) { + ret = rtw_store_to_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE); + if(ret == EEPROM_MAX_SIZE) + ret = _SUCCESS; + else + ret = _FAIL; + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = _FAIL; + } + return ret; +} + +int retriveAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv) +{ + int ret = _SUCCESS; + mm_segment_t oldfs; + struct file *fp; + + if(path && eeprom_priv) { + + ret = rtw_retrive_from_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE); + + if(ret == EEPROM_MAX_SIZE) + ret = _SUCCESS; + else + ret = _FAIL; + + #if 0 + if(isAdaptorInfoFileValid()) { + return 0; + } else { + return _FAIL; + } + #endif + + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = _FAIL; + } + return ret; +} +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE +#endif //PLATFORM_LINUX + + diff --git a/rtl8192cu-fixes/core/rtw_ap.c b/rtl8192cu-fixes/core/rtw_ap.c new file mode 100755 index 00000000..559b8546 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_ap.c @@ -0,0 +1,2940 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_AP_C_ + +#include +#include +#include +#include + + +#ifdef CONFIG_AP_MODE + +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WMM_OUI[]; +extern unsigned char WPS_OUI[]; +extern unsigned char P2P_OUI[]; +extern unsigned char WFD_OUI[]; + +void init_mlme_ap_info(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + + _rtw_spinlock_init(&pmlmepriv->bcn_update_lock); + + //for ACL + _rtw_init_queue(&pacl_list->acl_node_q); + + //pmlmeext->bstart_bss = _FALSE; + + start_ap_mode(padapter); +} + +void free_mlme_ap_info(_adapter *padapter) +{ + _irqL irqL; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //stop_ap_mode(padapter); + + pmlmepriv->update_bcn = _FALSE; + pmlmeext->bstart_bss = _FALSE; + + rtw_sta_flush(padapter); + + pmlmeinfo->state = _HW_STATE_NOLINK_; + + //free_assoc_sta_resources + rtw_free_all_stainfo(padapter); + + //free bc/mc sta_info + psta = rtw_get_bcmc_stainfo(padapter); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + + _rtw_spinlock_free(&pmlmepriv->bcn_update_lock); + +} + +static void update_BCNTIM(_adapter *padapter) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); + unsigned char *pie = pnetwork_mlmeext->IEs; + + //DBG_871X("%s\n", __FUNCTION__); + + //update TIM IE + //if(pstapriv->tim_bitmap) + if(_TRUE) + { + u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; + u16 tim_bitmap_le; + uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; + + tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap); + + p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); + if (p != NULL && tim_ielen>0) + { + tim_ielen += 2; + + premainder_ie = p+tim_ielen; + + tim_ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen; + + //append TIM IE from dst_ie offset + dst_ie = p; + } + else + { + tim_ielen = 0; + + //calucate head_len + offset = _FIXED_IE_LENGTH_; + + /* get ssid_ie len */ + p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + offset += tmp_len+2; + + // get supported rates len + p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + { + offset += tmp_len+2; + } + + //DS Parameter Set IE, len=3 + offset += 3; + + premainder_ie = pie + offset; + + remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; + + //append TIM IE from offset + dst_ie = pie + offset; + + } + + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + *dst_ie++=_TIM_IE_; + + if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc)) + tim_ielen = 5; + else + tim_ielen = 4; + + *dst_ie++= tim_ielen; + + *dst_ie++=0;//DTIM count + *dst_ie++=1;//DTIM peroid + + if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames + *dst_ie++ = BIT(0);//bitmap ctrl + else + *dst_ie++ = 0; + + if(tim_ielen==4) + { + *dst_ie++ = *(u8*)&tim_bitmap_le; + } + else if(tim_ielen==5) + { + _rtw_memcpy(dst_ie, &tim_bitmap_le, 2); + dst_ie+=2; + } + + //copy remainder IE + if(pbackup_remainder_ie) + { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork_mlmeext->IELength = offset + remainder_ielen; + + } + +#ifndef CONFIG_INTERRUPT_BASED_TXBCN +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + set_tx_beacon_cmd(padapter); +#endif +#endif //!CONFIG_INTERRUPT_BASED_TXBCN + + +} + +void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 bmatch = _FALSE; + u8 *pie = pnetwork->IEs; + u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; + u32 i, offset, ielen, ie_offset, remainder_ielen = 0; + + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); + + if (pIE->ElementID > index) + { + break; + } + else if(pIE->ElementID == index) // already exist the same IE + { + p = (u8 *)pIE; + ielen = pIE->Length; + bmatch = _TRUE; + break; + } + + p = (u8 *)pIE; + ielen = pIE->Length; + i += (pIE->Length + 2); + } + + if (p != NULL && ielen>0) + { + ielen += 2; + + premainder_ie = p+ielen; + + ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork->IELength - ie_offset - ielen; + + if(bmatch) + dst_ie = p; + else + dst_ie = (p+ielen); + } + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + *dst_ie++=index; + *dst_ie++=len; + + _rtw_memcpy(dst_ie, data, len); + dst_ie+=len; + + //copy remainder IE + if(pbackup_remainder_ie) + { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork->IELength = offset + remainder_ielen; +} + +void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index) +{ + u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; + uint offset, ielen, ie_offset, remainder_ielen = 0; + u8 *pie = pnetwork->IEs; + + p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_); + if (p != NULL && ielen>0) + { + ielen += 2; + + premainder_ie = p+ielen; + + ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork->IELength - ie_offset - ielen; + + dst_ie = p; + } + else { + return; + } + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + //copy remainder IE + if(pbackup_remainder_ie) + { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork->IELength = offset + remainder_ielen; +} + + +u8 chk_sta_is_alive(struct sta_info *psta); +u8 chk_sta_is_alive(struct sta_info *psta) +{ + u8 ret = _FALSE; + #ifdef DBG_EXPIRATION_CHK + DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n" + , MAC_ARG(psta->hwaddr) + , psta->rssi_stat.UndecoratedSmoothedPWDB + //, STA_RX_PKTS_ARG(psta) + , STA_RX_PKTS_DIFF_ARG(psta) + , psta->expire_to + , psta->state&WIFI_SLEEP_STATE?"PS, ":"" + , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":"" + , psta->sleepq_len + ); + #endif + + //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta)) + if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) + { + #if 0 + if(psta->state&WIFI_SLEEP_STATE) + ret = _TRUE; + #endif + } + else + { + ret = _TRUE; + } + + sta_update_last_rx_pkts(psta); + + return ret; +} + +void expire_timeout_chk(_adapter *padapter) +{ + _irqL irqL; + _list *phead, *plist; + u8 updated; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + int i; + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + + phead = &pstapriv->auth_list; + plist = get_next(phead); + + //check auth_queue + #ifdef DBG_EXPIRATION_CHK + if (rtw_end_of_queue_search(phead, plist) == _FALSE) { + DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt); + } + #endif + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, auth_list); + plist = get_next(plist); + + if(psta->expire_to>0) + { + psta->expire_to--; + if (psta->expire_to == 0) + { + rtw_list_delete(&psta->auth_list); + pstapriv->auth_list_cnt--; + + DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n", + psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]); + + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + } + } + + } + + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + psta = NULL; + + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + #ifdef DBG_EXPIRATION_CHK + if (rtw_end_of_queue_search(phead, plist) == _FALSE) { + DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt); + } + #endif + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + if (chk_sta_is_alive(psta) || !psta->expire_to) { + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; + #ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; + #endif // CONFIG_TX_MCAST2UNI + } else { + psta->expire_to--; + } + +#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_TX_MCAST2UNI + if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) { + // check sta by delba(addba) for 11n STA + // ToDo: use CCX report to check for all STAs + //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking); + + if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) { + DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2); + psta->under_exist_checking = 0; + psta->expire_to = 0; + } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) { + DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2); + psta->under_exist_checking = 1; + //tear down TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + } + } +#endif // CONFIG_TX_MCAST2UNI +#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK + + if (psta->expire_to <= 0) + { + #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (padapter->registrypriv.wifi_spec == 1) + { + psta->expire_to = pstapriv->expire_to; + continue; + } + + if (psta->state & WIFI_SLEEP_STATE) { + if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { + //to check if alive by another methods if staion is at ps mode. + psta->expire_to = pstapriv->expire_to; + psta->state |= WIFI_STA_ALIVE_CHK_STATE; + + //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr)); + + //to update bcn with tim_bitmap for this station + pstapriv->tim_bitmap |= BIT(psta->aid); + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + + if(!pmlmeext->active_keep_alive_check) + continue; + } + } + + if (pmlmeext->active_keep_alive_check) { + int stainfo_offset; + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + + continue; + } + #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); + updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING); + } + else + { + /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ + if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt) + && padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME/pstapriv->asoc_list_cnt/2) + ){ + DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__ + , MAC_ARG(psta->hwaddr) + , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt); + wakeup_sta_to_xmit(padapter, psta); + } + } + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +if (chk_alive_num) { + + u8 backup_oper_channel=0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + /* switch to correct channel of current network before issue keep-alive frames */ + if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { + backup_oper_channel = rtw_get_oper_ch(padapter); + SelectChannel(padapter, pmlmeext->cur_channel); + } + + /* issue null data to check sta alive*/ + for (i = 0; i < chk_alive_num; i++) { + + int ret = _FAIL; + + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + if(!(psta->state &_FW_LINKED)) + continue; + + if (psta->state & WIFI_SLEEP_STATE) + ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); + else + ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); + + psta->keep_alive_trycnt++; + if (ret == _SUCCESS) + { + DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr)); + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; + continue; + } + else if (psta->keep_alive_trycnt <= 3) + { + DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt); + psta->expire_to = 1; + continue; + } + + psta->keep_alive_trycnt = 0; + + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + + if (backup_oper_channel>0) /* back to the original operation channel */ + SelectChannel(padapter, backup_oper_channel); +} +#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + + associated_clients_update(padapter, updated); +} + + +static void add_RATid(_adapter *padapter, struct sta_info *psta) +{ + int i; + u8 rf_type; + u32 init_rate=0; + unsigned char sta_band = 0, raid, shortGIrate = _FALSE; + unsigned char limit; + unsigned int tx_ra_bitmap=0; + struct ht_priv *psta_ht = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + + + if(psta) + psta_ht = &psta->htpriv; + else + return; + + //b/g mode ra_bitmap + for (i=0; ibssrateset); i++) + { + if (psta->bssrateset[i]) + tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f); + } + + //n mode ra_bitmap + if(psta_ht->ht_option) + { + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if(rf_type == RF_2T2R) + limit=16;// 2R + else + limit=8;// 1R + + for (i=0; iht_cap.supp_mcs_set[i/8] & BIT(i%8)) + tx_ra_bitmap |= BIT(i+12); + } + + //max short GI rate + shortGIrate = psta_ht->sgi; + } + + +#if 0//gtest + if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R) + { + //is this a 2r STA? + if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid))) + { + priv->pshare->has_2r_sta |= BIT(pstat->aid); + if(rtw_read16(padapter, 0x102501f6) != 0xffff) + { + rtw_write16(padapter, 0x102501f6, 0xffff); + reset_1r_sta_RA(priv, 0xffff); + Switch_1SS_Antenna(priv, 3); + } + } + else// bg or 1R STA? + { + if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0) + { + if(rtw_read16(padapter, 0x102501f6) != 0x7777) + { // MCS7 SGI + rtw_write16(padapter, 0x102501f6,0x7777); + reset_1r_sta_RA(priv, 0x7777); + Switch_1SS_Antenna(priv, 2); + } + } + } + + } + + if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3)) + { + if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper) + pstat->rssi_level = 1; + else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) || + ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) && + (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) && + (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_)))) + pstat->rssi_level = 2; + else + pstat->rssi_level = 3; + } + + // rate adaptive by rssi + if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len) + { + if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R)) + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x100f0000; + break; + case 2: + pstat->tx_ra_bitmap &= 0x100ff000; + break; + case 3: + if (priv->pshare->is_40m_bw) + pstat->tx_ra_bitmap &= 0x100ff005; + else + pstat->tx_ra_bitmap &= 0x100ff001; + + break; + } + } + else + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x1f0f0000; + break; + case 2: + pstat->tx_ra_bitmap &= 0x1f0ff000; + break; + case 3: + if (priv->pshare->is_40m_bw) + pstat->tx_ra_bitmap &= 0x000ff005; + else + pstat->tx_ra_bitmap &= 0x000ff001; + + break; + } + + // Don't need to mask high rates due to new rate adaptive parameters + //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta + // pstat->tx_ra_bitmap &= 0x81ffffff; + + // NIC driver will report not supporting MCS15 and MCS14 in asoc req + //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta) + // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14 + } + } + else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat)) + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x00000f00; + break; + case 2: + pstat->tx_ra_bitmap &= 0x00000ff0; + break; + case 3: + pstat->tx_ra_bitmap &= 0x00000ff5; + break; + } + } + else + { + pstat->tx_ra_bitmap &= 0x0000000d; + } + + // disable tx short GI when station cannot rx MCS15(AP is 2T2R) + // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R) + // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate + if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) || + (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R))) + { + pstat->tx_ra_bitmap &= ~BIT(28); + } +#endif + + if ( pcur_network->Configuration.DSConfig > 14 ) { + // 5G band + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_5N | WIRELESS_11A; + else + sta_band |= WIRELESS_11A; + } else { + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; + else if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11G |WIRELESS_11B; + else + sta_band |= WIRELESS_11B; + } + + raid = networktype_to_raid(sta_band); + init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f; + + if (psta->aid < NUM_STA) + { + u8 arg = 0; + + arg = psta->mac_id&0x1f; + + arg |= BIT(7);//support entry 2~31 + + if (shortGIrate==_TRUE) + arg |= BIT(5); + + tx_ra_bitmap |= ((raid<<28)&0xf0000000); + + DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x, arg=0x%x\n", + __FUNCTION__ , psta->mac_id, raid ,tx_ra_bitmap, arg); + + //bitmap[0:27] = tx_rate_bitmap + //bitmap[28:31]= Rate Adaptive id + //arg[0:4] = macid + //arg[5] = Short GI + rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg); + + if (shortGIrate==_TRUE) + init_rate |= BIT(6); + + //set ra_id, init_rate + psta->raid = raid; + psta->init_rate = init_rate; + + } + else + { + DBG_871X("station aid %d exceed the max number\n", psta->aid); + } + +} + +static void update_bmc_sta(_adapter *padapter) +{ + _irqL irqL; + u32 init_rate=0; + unsigned char network_type, raid; + int i, supportRateNum = 0; + unsigned int tx_ra_bitmap=0; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); + + if(psta) + { + psta->aid = 0;//default set to 0 + //psta->mac_id = psta->aid+4; + psta->mac_id = psta->aid + 1; + + psta->qos_option = 0; + psta->htpriv.ht_option = _FALSE; + + psta->ieee8021x_blocked = 0; + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this. + + + + //prepare for add_RATid + supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates); + network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, 1); + + _rtw_memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum); + psta->bssratelen = supportRateNum; + + //b/g mode ra_bitmap + for (i=0; ibssrateset[i]) + tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f); + } + + if ( pcur_network->Configuration.DSConfig > 14 ) { + //force to A mode. 5G doesn't support CCK rates + network_type = WIRELESS_11A; + tx_ra_bitmap = 0x150; // 6, 12, 24 Mbps + } else { + //force to b mode + network_type = WIRELESS_11B; + tx_ra_bitmap = 0xf; + } + + //tx_ra_bitmap = update_basic_rate(pcur_network->SupportedRates, supportRateNum); + + raid = networktype_to_raid(network_type); + init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f; + + //DBG_871X("Add id %d val %08x to ratr for bmc sta\n", psta->aid, tx_ra_bitmap); + + //if(pHalData->fw_ractrl == _TRUE) + { + u8 arg = 0; + + arg = psta->mac_id&0x1f; + + arg |= BIT(7); + + //if (shortGIrate==_TRUE) + // arg |= BIT(5); + + tx_ra_bitmap |= ((raid<<28)&0xf0000000); + + DBG_871X("update_bmc_sta, mask=0x%x, arg=0x%x\n", tx_ra_bitmap, arg); + + //bitmap[0:27] = tx_rate_bitmap + //bitmap[28:31]= Rate Adaptive id + //arg[0:4] = macid + //arg[5] = Short GI + rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg); + + } + + //set ra_id, init_rate + psta->raid = raid; + psta->init_rate = init_rate; + + _enter_critical_bh(&psta->lock, &irqL); + psta->state = _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + } + else + { + DBG_871X("add_RATid_bmc_sta error!\n"); + } + +} + +//notes: +//AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode +//MAC_ID = AID+1 for sta in ap/adhoc mode +//MAC_ID = 1 for bc/mc for sta/ap/adhoc +//MAC_ID = 0 for bssid for sta/ap/adhoc +//CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1; + +void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; + struct ht_priv *phtpriv_sta = &psta->htpriv; + + //set intf_tag to if1 + //psta->intf_tag = 0; + + //psta->mac_id = psta->aid+4; + psta->mac_id = psta->aid+1; + + if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X) + psta->ieee8021x_blocked = _TRUE; + else + psta->ieee8021x_blocked = _FALSE; + + + //update sta's cap + + //ERP + VCS_update(padapter, psta); + + //HT related cap + if(phtpriv_sta->ht_option) + { + //check if sta supports rx ampdu + phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; + + //check if sta support s Short GI + if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) + { + phtpriv_sta->sgi = _TRUE; + } + + // bwmode + if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) + { + //phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40; + phtpriv_sta->bwmode = pmlmeext->cur_bwmode; + phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; + + } + + psta->qos_option = _TRUE; + + } + else + { + phtpriv_sta->ampdu_enable = _FALSE; + + phtpriv_sta->sgi = _FALSE; + phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; + phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + //Rx AMPDU + send_delba(padapter, 0, psta->hwaddr);// recipient + + //TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + phtpriv_sta->agg_enable_bitmap = 0x0;//reset + phtpriv_sta->candidate_tid_bitmap = 0x0;//reset + + + //todo: init other variables + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + + //add ratid + //add_RATid(padapter, psta);//move to ap_sta_info_defer_update() + + + _enter_critical_bh(&psta->lock, &irqL); + psta->state |= _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + +} + +static void update_hw_ht_param(_adapter *padapter) +{ + unsigned char max_AMPDU_len; + unsigned char min_MPDU_spacing; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X("%s\n", __FUNCTION__); + + + //handle A-MPDU parameter field + /* + AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + AMPDU_para [4:2]:Min MPDU Start Spacing + */ + max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); + + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; + +} + +static void start_bss_network(_adapter *padapter, u8 *pbuf) +{ + u8 *p; + u8 val8, cur_channel, cur_bwmode, cur_ch_offset; + u16 bcn_interval; + u32 acparm; + int ie_len; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv* psecuritypriv=&(padapter->securitypriv); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); + struct HT_info_element *pht_info=NULL; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#endif //CONFIG_P2P + u8 cbw40_enable=0; + u8 change_band = _FALSE; + //DBG_871X("%s\n", __FUNCTION__); + + bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; + cur_channel = pnetwork->Configuration.DSConfig; + cur_bwmode = HT_CHANNEL_WIDTH_20;; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + + //check if there is wps ie, + //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, + //and at first time the security ie ( RSN/WPA IE) will not include in beacon. + if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL)) + { + pmlmeext->bstart_bss = _TRUE; + } + + //todo: update wmm, ht cap + //pmlmeinfo->WMM_enable; + //pmlmeinfo->HT_enable; + if(pmlmepriv->qospriv.qos_option) + pmlmeinfo->WMM_enable = _TRUE; + + if(pmlmepriv->htpriv.ht_option) + { + pmlmeinfo->WMM_enable = _TRUE; + pmlmeinfo->HT_enable = _TRUE; + //pmlmeinfo->HT_info_enable = _TRUE; + //pmlmeinfo->HT_caps_enable = _TRUE; + + update_hw_ht_param(padapter); + } + + + if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time + { + //WEP Key will be set before this function, do not clear CAM. + if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) + flush_all_cam_entry(padapter); //clear CAM + } + + //set MSR to AP_Mode + Set_MSR(padapter, _HW_STATE_AP_); + + //Set BSSID REG + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress); + + //Set EDCA param reg +#ifdef CONFIG_CONCURRENT_MODE + acparm = 0x005ea42b; +#else + acparm = 0x002F3217; // VO +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E4317; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + //acparm = 0x00105320; // BE + acparm = 0x005ea42b; + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A444; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + + //Set Security + val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + //Beacon Control related register + rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval)); + + if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time + { + u32 initialgain; + + initialgain = 0x1e; + + + //disable dynamic functions, such as high power, DIG + //Save_DM_Func_Flag(padapter); + //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type > PRIMARY_ADAPTER) + { + if(rtw_buddy_adapter_up(padapter)) + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + + //turn on dynamic functions on PRIMARY_ADAPTER, dynamic functions only runs at PRIMARY_ADAPTER + Switch_DM_Func(pbuddy_adapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + } + } + else +#endif + { + //turn on dynamic functions + Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + + rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + } + + } + + //set channel, bwmode + p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + + if( pmlmeext->cur_channel > 14 ) + { + if( pregpriv->cbw40_enable & BIT(1) ) + cbw40_enable = 1; + } + else + if( pregpriv->cbw40_enable & BIT(0) ) + cbw40_enable = 1; + + if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) + { + //switch to the 40M Hz mode + //pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + cur_bwmode = HT_CHANNEL_WIDTH_40; + switch (pht_info->infos[0] & 0x3) + { + case 1: + //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case 3: + //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + } + + } + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode); +#else + //TODO: need to judge the phy parameters on concurrent mode for single phy + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); +#ifdef CONFIG_CONCURRENT_MODE + if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + } + else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)//only second adapter can enter AP Mode + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + //To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter + DBG_871X("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n"); + DBG_871X("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + DBG_871X("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + if((cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) || + (cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14)) + change_band = _TRUE; + + cur_channel = pbuddy_mlmeext->cur_channel; + if(cur_bwmode == HT_CHANNEL_WIDTH_40) + { + if(pht_info) + pht_info->infos[0] &= ~(BIT(0)|BIT(1)); + + if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + + //to update cur_ch_offset value in beacon + if(pht_info) + { + switch(cur_ch_offset) + { + case HAL_PRIME_CHNL_OFFSET_LOWER: + pht_info->infos[0] |= 0x1; + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + pht_info->infos[0] |= 0x3; + break; + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + default: + break; + } + } + + } + else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) + { + cur_bwmode = HT_CHANNEL_WIDTH_20; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if(cur_channel>0 && cur_channel<5) + { + if(pht_info) + pht_info->infos[0] |= 0x1; + + cur_bwmode = HT_CHANNEL_WIDTH_40; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } + + if(cur_channel>7 && cur_channel<(14+1)) + { + if(pht_info) + pht_info->infos[0] |= 0x3; + + cur_bwmode = HT_CHANNEL_WIDTH_40; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } + + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + } + + } + + // to update channel value in beacon + pnetwork->Configuration.DSConfig = cur_channel; + p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if(p && ie_len>0) + *(p + 2) = cur_channel; + + if(pht_info) + pht_info->primary_channel = cur_channel; + + //set buddy adapter channel, bandwidth, offeset to current adapter + pmlmeext->cur_channel = cur_channel; + pmlmeext->cur_bwmode = cur_bwmode; + pmlmeext->cur_ch_offset = cur_ch_offset; + + //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE + if(change_band == _TRUE) + change_band_update_ie(padapter, pnetwork); + } +#else + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); +#endif //CONFIG_CONCURRENT_MODE + + DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + // + pmlmeext->cur_channel = cur_channel; + pmlmeext->cur_bwmode = cur_bwmode; + pmlmeext->cur_ch_offset = cur_ch_offset; +#endif //CONFIG_DUALMAC_CONCURRENT + pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type; + + //update cur_wireless_mode + update_wireless_mode(padapter); + + //update RRSR after set channel and bandwidth + UpdateBrateTbl(padapter, pnetwork->SupportedRates); + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); + + //udpate capability after cur_wireless_mode updated + update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork)); + + //let pnetwork_mlmeext == pnetwork_mlme. + _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); + +#ifdef CONFIG_P2P + _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength); + pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength; +#endif //CONFIG_P2P + + if(_TRUE == pmlmeext->bstart_bss) + { + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + +#ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will tx beacon when bcn interrupt coming in. +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + //issue beacon frame + if(send_beacon(padapter)==_FAIL) + { + DBG_871X("issue_beacon, fail!\n"); + } +#endif +#endif //!CONFIG_INTERRUPT_BASED_TXBCN + + } + + + //update bc/mc sta_info + update_bmc_sta(padapter); + + //pmlmeext->bstart_bss = _TRUE; + +} + +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) +{ + int ret=_SUCCESS; + u8 *p; + u8 *pHT_caps_ie=NULL; + u8 *pHT_info_ie=NULL; + struct sta_info *psta = NULL; + u16 cap, ht_cap=_FALSE; + uint ie_len = 0; + int group_cipher, pairwise_cipher; + u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; + int supportRateNum = 0; + u8 OUI1[] = {0x00, 0x50, 0xf2,0x01}; + u8 wps_oui[4]={0x0,0x50,0xf2,0x04}; + u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ie = pbss_network->IEs; + + + /* SSID */ + /* Supported rates */ + /* DS Params */ + /* WLAN_EID_COUNTRY */ + /* ERP Information element */ + /* Extended supported rates */ + /* WPA/WPA2 */ + /* Wi-Fi Wireless Multimedia Extensions */ + /* ht_capab, ht_oper */ + /* WPS IE */ + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return _FAIL; + + + if(len>MAX_IE_SZ) + return _FAIL; + + pbss_network->IELength = len; + + _rtw_memset(ie, 0, MAX_IE_SZ); + + _rtw_memcpy(ie, pbuf, pbss_network->IELength); + + + if(pbss_network->InfrastructureMode!=Ndis802_11APMode) + return _FAIL; + + pbss_network->Rssi = 0; + + _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN); + + //beacon interval + p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability + //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); + pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p); + + //capability + //cap = *(unsigned short *)rtw_get_capability_from_ie(ie); + //cap = le16_to_cpu(cap); + cap = RTW_GET_LE16(ie); + + //SSID + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); + pbss_network->Ssid.SsidLength = ie_len; + } + + //chnnel + channel = 0; + pbss_network->Configuration.Length = 0; + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + channel = *(p + 2); + + pbss_network->Configuration.DSConfig = channel; + + + _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); + // get supported rates + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + { + _rtw_memcpy(supportRate, p+2, ie_len); + supportRateNum = ie_len; + } + + //get ext_supported rates + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); + if (p != NULL) + { + _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len); + supportRateNum += ie_len; + + } + + network_type = rtw_check_network_type(supportRate, supportRateNum, channel); + + rtw_set_supported_rate(pbss_network->SupportedRates, network_type); + + + //parsing ERP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p); + } + + //update privacy/security + if (cap & BIT(4)) + pbss_network->Privacy = 1; + else + pbss_network->Privacy = 0; + + psecuritypriv->wpa_psk = 0; + + //wpa2 + group_cipher = 0; pairwise_cipher = 0; + psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; + psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + + psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x + psecuritypriv->wpa_psk |= BIT(1); + + psecuritypriv->wpa2_group_cipher = group_cipher; + psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; +#if 0 + switch(group_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa2_group_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa2_group_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa2_group_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa2_group_cipher = _WEP104_; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa2_pairwise_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa2_pairwise_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa2_pairwise_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa2_pairwise_cipher = _WEP104_; + break; + } +#endif + } + + } + + //wpa + ie_len = 0; + group_cipher = 0; pairwise_cipher = 0; + psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; + psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; + for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) + { + p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if ((p) && (_rtw_memcmp(p+2, OUI1, 4))) + { + if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + + psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x + + psecuritypriv->wpa_psk |= BIT(0); + + psecuritypriv->wpa_group_cipher = group_cipher; + psecuritypriv->wpa_pairwise_cipher = pairwise_cipher; + +#if 0 + switch(group_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa_group_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa_group_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa_group_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa_group_cipher = _WEP104_; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa_pairwise_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa_pairwise_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa_pairwise_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa_pairwise_cipher = _WEP104_; + break; + } +#endif + } + + break; + + } + + if ((p == NULL) || (ie_len == 0)) + { + break; + } + + } + + //wmm + ie_len = 0; + pmlmepriv->qospriv.qos_option = 0; + if(pregistrypriv->wmm_enable) + { + for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) + { + p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6)) + { + pmlmepriv->qospriv.qos_option = 1; + + *(p+8) |= BIT(7);//QoS Info, support U-APSD + + /* disable all ACM bits since the WMM admission control is not supported */ + *(p + 10) &= ~BIT(4); /* BE */ + *(p + 14) &= ~BIT(4); /* BK */ + *(p + 18) &= ~BIT(4); /* VI */ + *(p + 22) &= ~BIT(4); /* VO */ + + break; + } + + if ((p == NULL) || (ie_len == 0)) + { + break; + } + } + } + + //parsing HT_CAP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + u8 rf_type; + + struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2); + + pHT_caps_ie=p; + + + ht_cap = _TRUE; + network_type |= WIRELESS_11_24N; + + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) || + (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) + { + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + } + else + { + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + } + + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); //set Max Rx AMPDU size to 64K + + if(rf_type == RF_1T1R) + { + pht_cap->supp_mcs_set[0] = 0xff; + pht_cap->supp_mcs_set[1] = 0x0; + } + + _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len); + + } + + //parsing HT_INFO_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + pHT_info_ie=p; + } + + switch(network_type) + { + case WIRELESS_11B: + pbss_network->NetworkTypeInUse = Ndis802_11DS; + break; + case WIRELESS_11G: + case WIRELESS_11BG: + case WIRELESS_11G_24N: + case WIRELESS_11BG_24N: + pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; + break; + case WIRELESS_11A: + pbss_network->NetworkTypeInUse = Ndis802_11OFDM5; + break; + default : + pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; + break; + } + + pmlmepriv->cur_network.network_type = network_type; + + + pmlmepriv->htpriv.ht_option = _FALSE; +#ifdef CONFIG_80211N_HT + if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || + (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP)) + { + //todo: + //ht_cap = _FALSE; + } + + //ht_cap + if(pregistrypriv->ht_enable && ht_cap==_TRUE) + { + pmlmepriv->htpriv.ht_option = _TRUE; + pmlmepriv->qospriv.qos_option = 1; + + if(pregistrypriv->ampdu_enable==1) + { + pmlmepriv->htpriv.ampdu_enable = _TRUE; + } + + HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie); + + HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie); + } +#endif + + + pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network); + + //issue beacon to start bss network + start_bss_network(padapter, (u8*)pbss_network); + + + //alloc sta_info for ap itself + psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress); + if(!psta) + { + psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress); + if (psta == NULL) + { + return _FAIL; + } + } + psta->state |= WIFI_AP_STATE; //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 + rtw_indicate_connect( padapter); + + pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon + + //update bc/mc sta_info + //update_bmc_sta(padapter); + + return ret; + +} + +void rtw_set_macaddr_acl(_adapter *padapter, int mode) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + DBG_871X("%s, mode=%d\n", __func__, mode); + + pacl_list->mode = mode; +} + +int rtw_acl_add_sta(_adapter *padapter, u8 *addr) +{ + _irqL irqL; + _list *plist, *phead; + u8 added = _FALSE; + int i, ret=0; + struct rtw_wlan_acl_node *paclnode; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr)); + + if((NUM_ACL-1) < pacl_list->num) + return (-1); + + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + added = _TRUE; + DBG_871X("%s, sta has been added\n", __func__); + break; + } + } + } + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + + if(added == _TRUE) + return ret; + + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + for(i=0; i< NUM_ACL; i++) + { + paclnode = &pacl_list->aclnode[i]; + + if(paclnode->valid == _FALSE) + { + _rtw_init_listhead(&paclnode->list); + + _rtw_memcpy(paclnode->addr, addr, ETH_ALEN); + + paclnode->valid = _TRUE; + + rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q)); + + pacl_list->num++; + + break; + } + } + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + return ret; +} + +int rtw_acl_remove_sta(_adapter *padapter, u8 *addr) +{ + _irqL irqL; + _list *plist, *phead; + int i, ret=0; + struct rtw_wlan_acl_node *paclnode; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr)); + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + paclnode->valid = _FALSE; + + rtw_list_delete(&paclnode->list); + + pacl_list->num--; + } + } + } + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + + return ret; + +} + +#ifdef CONFIG_NATIVEAP_MLME + +static void update_bcn_fixed_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_erpinfo_ie(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + unsigned char *p, *ie = pnetwork->IEs; + u32 len = 0; + + DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable); + + if(!pmlmeinfo->ERP_enable) + return; + + //parsing ERP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(p && len>0) + { + PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p; + + if (pmlmepriv->num_sta_non_erp == 1) + pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION; + else + pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION); + + if(pmlmepriv->num_sta_no_short_preamble > 0) + pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE; + else + pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE); + + ERP_IE_handler(padapter, pIE); + } + +} + +static void update_bcn_htcap_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_htinfo_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_rsn_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wpa_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wmm_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wps_ie(_adapter *padapter) +{ + u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL; + uint wps_ielen=0, wps_offset, remainder_ielen; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + unsigned char *ie = pnetwork->IEs; + u32 ielen = pnetwork->IELength; + + + DBG_871X("%s\n", __FUNCTION__); + + pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen); + + if(pwps_ie==NULL || wps_ielen==0) + return; + + wps_offset = (uint)(pwps_ie-ie); + + premainder_ie = pwps_ie + wps_ielen; + + remainder_ielen = ielen - wps_offset - wps_ielen; + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + + pwps_ie_src = pmlmepriv->wps_beacon_ie; + if(pwps_ie_src == NULL) + return; + + + wps_ielen = (uint)pwps_ie_src[1];//to get ie data len + if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ) + { + _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2); + pwps_ie += (wps_ielen+2); + + if(pbackup_remainder_ie) + _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); + + //update IELength + pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen; + } + + if(pbackup_remainder_ie) + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + +} + +static void update_bcn_p2p_ie(_adapter *padapter) +{ + +} + +static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui) +{ + DBG_871X("%s\n", __FUNCTION__); + + if(_rtw_memcmp(RTW_WPA_OUI, oui, 4)) + { + update_bcn_wpa_ie(padapter); + } + else if(_rtw_memcmp(WMM_OUI, oui, 4)) + { + update_bcn_wmm_ie(padapter); + } + else if(_rtw_memcmp(WPS_OUI, oui, 4)) + { + update_bcn_wps_ie(padapter); + } + else if(_rtw_memcmp(P2P_OUI, oui, 4)) + { + update_bcn_p2p_ie(padapter); + } + else + { + DBG_871X("unknown OUI type!\n"); + } + + +} + +void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv; + struct mlme_ext_priv *pmlmeext; + //struct mlme_ext_info *pmlmeinfo; + + //DBG_871X("%s\n", __FUNCTION__); + + if(!padapter) + return; + + pmlmepriv = &(padapter->mlmepriv); + pmlmeext = &(padapter->mlmeextpriv); + //pmlmeinfo = &(pmlmeext->mlmext_info); + + if(_FALSE == pmlmeext->bstart_bss) + return; + + _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); + + switch(ie_id) + { + case 0xFF: + + update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability + + break; + + case _TIM_IE_: + + update_BCNTIM(padapter); + + break; + + case _ERPINFO_IE_: + + update_bcn_erpinfo_ie(padapter); + + break; + + case _HT_CAPABILITY_IE_: + + update_bcn_htcap_ie(padapter); + + break; + + case _RSN_IE_2_: + + update_bcn_rsn_ie(padapter); + + break; + + case _HT_ADD_INFO_IE_: + + update_bcn_htinfo_ie(padapter); + + break; + + case _VENDOR_SPECIFIC_IE_: + + update_bcn_vendor_spec_ie(padapter, oui); + + break; + + default: + break; + } + + pmlmepriv->update_bcn = _TRUE; + + _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); + +#ifndef CONFIG_INTERRUPT_BASED_TXBCN +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + if(tx) + { + //send_beacon(padapter);//send_beacon must execute on TSR level + set_tx_beacon_cmd(padapter); + } +#else + { + //PCI will issue beacon when BCN interrupt occurs. + } +#endif +#endif //!CONFIG_INTERRUPT_BASED_TXBCN + +} + +#ifdef CONFIG_80211N_HT + +/* +op_mode +Set to 0 (HT pure) under the followign conditions + - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or + - all STAs in the BSS are 20 MHz HT in 20 MHz BSS +Set to 1 (HT non-member protection) if there may be non-HT STAs + in both the primary and the secondary channel +Set to 2 if only HT STAs are associated in BSS, + however and at least one 20 MHz HT STA is associated +Set to 3 (HT mixed mode) when one or more non-HT STAs are associated + (currently non-GF HT station is considered as non-HT STA also) +*/ +static int rtw_ht_operation_update(_adapter *padapter) +{ + u16 cur_op_mode, new_op_mode; + int op_mode_changes = 0; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; + + if(pmlmepriv->htpriv.ht_option == _TRUE) + return 0; + + //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) + // return 0; + + DBG_871X("%s current operation mode=0x%X\n", + __FUNCTION__, pmlmepriv->ht_op_mode); + + if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) + && pmlmepriv->num_sta_ht_no_gf) { + pmlmepriv->ht_op_mode |= + HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; + op_mode_changes++; + } else if ((pmlmepriv->ht_op_mode & + HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && + pmlmepriv->num_sta_ht_no_gf == 0) { + pmlmepriv->ht_op_mode &= + ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; + op_mode_changes++; + } + + if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && + (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) { + pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; + op_mode_changes++; + } else if ((pmlmepriv->ht_op_mode & + HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && + (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) { + pmlmepriv->ht_op_mode &= + ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; + op_mode_changes++; + } + + /* Note: currently we switch to the MIXED op mode if HT non-greenfield + * station is associated. Probably it's a theoretical case, since + * it looks like all known HT STAs support greenfield. + */ + new_op_mode = 0; + if (pmlmepriv->num_sta_no_ht || + (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)) + new_op_mode = OP_MODE_MIXED; + else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH) + && pmlmepriv->num_sta_ht_20mhz) + new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED; + else if (pmlmepriv->olbc_ht) + new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS; + else + new_op_mode = OP_MODE_PURE; + + cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK; + if (cur_op_mode != new_op_mode) { + pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK; + pmlmepriv->ht_op_mode |= new_op_mode; + op_mode_changes++; + } + + DBG_871X("%s new operation mode=0x%X changes=%d\n", + __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes); + + return op_mode_changes; + +} + +#endif /* CONFIG_80211N_HT */ + +void associated_clients_update(_adapter *padapter, u8 updated) +{ + //update associcated stations cap. + if(updated == _TRUE) + { + _irqL irqL; + _list *phead, *plist; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + VCS_update(padapter, psta); + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + +} + +/* called > TSR LEVEL for USB or SDIO Interface*/ +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta) +{ + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + +#if 0 + if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && + !psta->no_short_preamble_set) { + psta->no_short_preamble_set = 1; + pmlmepriv->num_sta_no_short_preamble++; + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 1)) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + + if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) + { + if(!psta->no_short_preamble_set) + { + psta->no_short_preamble_set = 1; + + pmlmepriv->num_sta_no_short_preamble++; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 1)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + else + { + if(psta->no_short_preamble_set) + { + psta->no_short_preamble_set = 0; + + pmlmepriv->num_sta_no_short_preamble--; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 0)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + +#if 0 + if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) { + psta->nonerp_set = 1; + pmlmepriv->num_sta_non_erp++; + if (pmlmepriv->num_sta_non_erp == 1) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + if(psta->flags & WLAN_STA_NONERP) + { + if(!psta->nonerp_set) + { + psta->nonerp_set = 1; + + pmlmepriv->num_sta_non_erp++; + + if (pmlmepriv->num_sta_non_erp == 1) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + } + else + { + if(psta->nonerp_set) + { + psta->nonerp_set = 0; + + pmlmepriv->num_sta_non_erp--; + + if (pmlmepriv->num_sta_non_erp == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + } + + +#if 0 + if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) && + !psta->no_short_slot_time_set) { + psta->no_short_slot_time_set = 1; + pmlmepriv->num_sta_no_short_slot_time++; + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 1)) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) + { + if(!psta->no_short_slot_time_set) + { + psta->no_short_slot_time_set = 1; + + pmlmepriv->num_sta_no_short_slot_time++; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 1)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + else + { + if(psta->no_short_slot_time_set) + { + psta->no_short_slot_time_set = 0; + + pmlmepriv->num_sta_no_short_slot_time--; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 0)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + } + +#ifdef CONFIG_80211N_HT + + if (psta->flags & WLAN_STA_HT) + { + u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); + + DBG_871X("HT: STA " MAC_FMT " HT Capabilities " + "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab); + + if (psta->no_ht_set) { + psta->no_ht_set = 0; + pmlmepriv->num_sta_no_ht--; + } + + if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) { + if (!psta->no_ht_gf_set) { + psta->no_ht_gf_set = 1; + pmlmepriv->num_sta_ht_no_gf++; + } + DBG_871X("%s STA " MAC_FMT " - no " + "greenfield, num of non-gf stations %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_ht_no_gf); + } + + if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) { + if (!psta->ht_20mhz_set) { + psta->ht_20mhz_set = 1; + pmlmepriv->num_sta_ht_20mhz++; + } + DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, " + "num of 20MHz HT STAs %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_ht_20mhz); + } + + } + else + { + if (!psta->no_ht_set) { + psta->no_ht_set = 1; + pmlmepriv->num_sta_no_ht++; + } + if(pmlmepriv->htpriv.ht_option == _TRUE) { + DBG_871X("%s STA " MAC_FMT + " - no HT, num of non-HT stations %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_no_ht); + } + } + + if (rtw_ht_operation_update(padapter) > 0) + { + update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE); + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE); + } + +#endif /* CONFIG_80211N_HT */ + + //update associcated stations cap. + associated_clients_update(padapter, beacon_updated); + + DBG_871X("%s, updated=%d\n", __func__, beacon_updated); + +} + +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta) +{ + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + if(!psta) + return beacon_updated; + + if (psta->no_short_preamble_set) { + psta->no_short_preamble_set = 0; + pmlmepriv->num_sta_no_short_preamble--; + if (pmlmeext->cur_wireless_mode > WIRELESS_11B + && pmlmepriv->num_sta_no_short_preamble == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + + if (psta->nonerp_set) { + psta->nonerp_set = 0; + pmlmepriv->num_sta_non_erp--; + if (pmlmepriv->num_sta_non_erp == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + if (psta->no_short_slot_time_set) { + psta->no_short_slot_time_set = 0; + pmlmepriv->num_sta_no_short_slot_time--; + if (pmlmeext->cur_wireless_mode > WIRELESS_11B + && pmlmepriv->num_sta_no_short_slot_time == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + +#ifdef CONFIG_80211N_HT + + if (psta->no_ht_gf_set) { + psta->no_ht_gf_set = 0; + pmlmepriv->num_sta_ht_no_gf--; + } + + if (psta->no_ht_set) { + psta->no_ht_set = 0; + pmlmepriv->num_sta_no_ht--; + } + + if (psta->ht_20mhz_set) { + psta->ht_20mhz_set = 0; + pmlmepriv->num_sta_ht_20mhz--; + } + + if (rtw_ht_operation_update(padapter) > 0) + { + update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE); + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE); + } + +#endif /* CONFIG_80211N_HT */ + + //update associcated stations cap. + //associated_clients_update(padapter, beacon_updated); //move it to avoid deadlock + + DBG_871X("%s, updated=%d\n", __func__, beacon_updated); + + return beacon_updated; + +} + +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason) +{ + _irqL irqL; + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + if(!psta) + return beacon_updated; + + if (active == _TRUE) + { +#ifdef CONFIG_80211N_HT + //tear down Rx AMPDU + send_delba(padapter, 0, psta->hwaddr);// recipient + + //tear down TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + +#endif //CONFIG_80211N_HT + + issue_deauth(padapter, psta->hwaddr, reason); + } + + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + + + //report_del_sta_event(padapter, psta->hwaddr, reason); + + //clear cam entry / key + //clear_cam_entry(padapter, (psta->mac_id + 3)); + rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)(psta->mac_id + 3), _TRUE); + + + _enter_critical_bh(&psta->lock, &irqL); + psta->state &= ~_FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + #ifdef CONFIG_IOCTL_CFG80211 + if (1) { + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason); + #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */ + #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + } else + #endif //CONFIG_IOCTL_CFG80211 + { + rtw_indicate_sta_disassoc_event(padapter, psta); + } + + report_del_sta_event(padapter, psta->hwaddr, reason); + + beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); + + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + + return beacon_updated; + +} + +int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset) +{ + _irqL irqL; + _list *phead, *plist; + int ret=0; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return ret; + + DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + /* for each sta in asoc_queue */ + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset); + psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); + + return ret; +} + +int rtw_sta_flush(_adapter *padapter) +{ + _irqL irqL; + _list *phead, *plist; + int ret=0; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + int i; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return ret; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + /* Remove sta from asoc_list */ + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + + /* Keep sta for ap_free_sta() beyond this asoc_list loop */ + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + + /* For each sta in chk_alive_list, call ap_free_sta */ + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING); + } + + issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); + + associated_clients_update(padapter, _TRUE); + + return ret; + +} + +/* called > TSR LEVEL for USB or SDIO Interface*/ +void sta_info_update(_adapter *padapter, struct sta_info *psta) +{ + int flags = psta->flags; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + + //update wmm cap. + if(WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if(pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + +#ifdef CONFIG_80211N_HT + //update 802.11n ht cap. + if(WLAN_STA_HT&flags) + { + psta->htpriv.ht_option = _TRUE; + psta->qos_option = 1; + } + else + { + psta->htpriv.ht_option = _FALSE; + } + + if(pmlmepriv->htpriv.ht_option == _FALSE) + psta->htpriv.ht_option = _FALSE; +#endif + + + update_sta_info_apmode(padapter, psta); + + +} + +/* called >= TSR LEVEL for USB or SDIO Interface*/ +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta) +{ + if(psta->state & _FW_LINKED) + { + //add ratid + add_RATid(padapter, psta); + } +} + +/* restore hw setting from sw data structures */ +void rtw_ap_restore_network(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_info *psta; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + _irqL irqL; + _list *phead, *plist; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + int i; + + rtw_setopmode_cmd(padapter, Ndis802_11APMode); + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network); + + if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) + { + /* restore group key, WEP keys is restored in ips_leave() */ + rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0); + } + + /* per sta pairwise key and settings */ + if((padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_) && + (padapter->securitypriv.dot11PrivacyAlgrthm != _AES_)) { + return; + } + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + + if (psta == NULL) { + DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter)); + } else if (psta->state &_FW_LINKED) { + Update_RA_Entry(padapter, psta->mac_id); + //pairwise key + rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); + } + } + +} + +void start_ap_mode(_adapter *padapter) +{ + int i; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + pmlmepriv->update_bcn = _FALSE; + + //init_mlme_ap_info(padapter); + pmlmeext->bstart_bss = _FALSE; + + pmlmepriv->num_sta_non_erp = 0; + + pmlmepriv->num_sta_no_short_slot_time = 0; + + pmlmepriv->num_sta_no_short_preamble = 0; + + pmlmepriv->num_sta_ht_no_gf = 0; + + pmlmepriv->num_sta_no_ht = 0; + + pmlmepriv->num_sta_ht_20mhz = 0; + + pmlmepriv->olbc = _FALSE; + + pmlmepriv->olbc_ht = _FALSE; + +#ifdef CONFIG_80211N_HT + pmlmepriv->ht_op_mode = 0; +#endif + + for(i=0; ista_aid[i] = NULL; + + 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; + pacl_list->mode = 0; + for(i = 0; i < NUM_ACL; i++) + { + _rtw_init_listhead(&pacl_list->aclnode[i].list); + pacl_list->aclnode[i].valid = _FALSE; + } + +} + +void stop_ap_mode(_adapter *padapter) +{ + _irqL irqL; + _list *phead, *plist; + struct rtw_wlan_acl_node *paclnode; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + pmlmepriv->update_bcn = _FALSE; + pmlmeext->bstart_bss = _FALSE; + //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock); + + //reset and init security priv , this can refine with rtw_reset_securitypriv + _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + + //for ACL + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(paclnode->valid == _TRUE) + { + paclnode->valid = _FALSE; + + rtw_list_delete(&paclnode->list); + + pacl_list->num--; + } + } + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num); + + rtw_sta_flush(padapter); + + //free_assoc_sta_resources + rtw_free_all_stainfo(padapter); + + psta = rtw_get_bcmc_stainfo(padapter); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + rtw_init_bcmc_stainfo(padapter); + + rtw_free_mlme_priv_ie_data(pmlmepriv); + +} + +#endif //CONFIG_NATIVEAP_MLME +#endif //CONFIG_AP_MODE + diff --git a/rtl8192cu-fixes/core/rtw_br_ext.c b/rtl8192cu-fixes/core/rtw_br_ext.c new file mode 100755 index 00000000..6bb924e0 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_br_ext.c @@ -0,0 +1,1699 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_BR_EXT_C_ + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#endif + +#if 1 // rtw_wifi_driver +#include +#include +#include "rtw_br_ext.h" +#else // rtw_wifi_driver +#include "./8192cd_cfg.h" + +#ifndef __KERNEL__ +#include "./sys-support.h" +#endif + +#include "./8192cd.h" +#include "./8192cd_headers.h" +#include "./8192cd_br_ext.h" +#include "./8192cd_debug.h" +#endif // rtw_wifi_driver + +#ifdef CL_IPV6_PASS +#ifdef __KERNEL__ +#include +#include +#include +#include +#endif +#endif + +#ifdef CONFIG_BR_EXT + +//#define BR_EXT_DEBUG + +#define NAT25_IPV4 01 +#define NAT25_IPV6 02 +#define NAT25_IPX 03 +#define NAT25_APPLE 04 +#define NAT25_PPPOE 05 + +#define RTL_RELAY_TAG_LEN (ETH_ALEN) +#define TAG_HDR_LEN 4 + +#define MAGIC_CODE 0x8186 +#define MAGIC_CODE_LEN 2 +#define WAIT_TIME_PPPOE 5 // waiting time for pppoe server in sec + +/*----------------------------------------------------------------- + How database records network address: + 0 1 2 3 4 5 6 7 8 9 10 + |----|----|----|----|----|----|----|----|----|----|----| + IPv4 |type| | IP addr | + IPX |type| Net addr | Node addr | + IPX |type| Net addr |Sckt addr| + Apple |type| Network |node| + PPPoE |type| SID | AC MAC | +-----------------------------------------------------------------*/ + + +//Find a tag in pppoe frame and return the pointer +static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) +{ + unsigned char *cur_ptr, *start_ptr; + unsigned short tagLen, tagType; + + start_ptr = cur_ptr = (unsigned char *)ph->tag; + while((cur_ptr - start_ptr) < ntohs(ph->length)) { + // prevent un-alignment access + tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); + tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); + if(tagType == type) + return cur_ptr; + cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; + } + return 0; +} + + +static __inline__ int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) +{ + struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); + int data_len; + + data_len = tag->tag_len + TAG_HDR_LEN; + if (skb_tailroom(skb) < data_len) { + _DEBUG_ERR("skb_tailroom() failed in add SID tag!\n"); + return -1; + } + + skb_put(skb, data_len); + // have a room for new tag + memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length)); + ph->length = htons(ntohs(ph->length) + data_len); + memcpy((unsigned char *)ph->tag, tag, data_len); + return data_len; +} + +static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) +{ + int tail_len; + unsigned long end, tail; + + if ((src+len) > skb_tail_pointer(skb) || skb->len < len) + return -1; + + tail = (unsigned long)skb_tail_pointer(skb); + end = (unsigned long)src+len; + if (tail < end) + return -1; + + tail_len = (int)(tail-end); + if (tail_len > 0) + memmove(src, src+len, tail_len); + + skb_trim(skb, skb->len-len); + return 0; +} + +static __inline__ unsigned long __nat25_timeout(_adapter *priv) +{ + unsigned long timeout; + + timeout = jiffies - NAT25_AGEING_TIME*HZ; + + return timeout; +} + + +static __inline__ int __nat25_has_expired(_adapter *priv, + struct nat25_network_db_entry *fdb) +{ + if(time_before_eq(fdb->ageing_timer, __nat25_timeout(priv))) + return 1; + + return 0; +} + + +static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, + unsigned int *ipAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPV4; + memcpy(networkAddr+7, (unsigned char *)ipAddr, 4); +} + + +static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr+5, ipxNodeAddr, 6); +} + + +static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr+5, (unsigned char *)ipxSocketAddr, 2); +} + + +static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr, + unsigned short *network, unsigned char *node) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_APPLE; + memcpy(networkAddr+1, (unsigned char *)network, 2); + networkAddr[3] = *node; +} + + +static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, + unsigned char *ac_mac, unsigned short *sid) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_PPPOE; + memcpy(networkAddr+1, (unsigned char *)sid, 2); + memcpy(networkAddr+3, (unsigned char *)ac_mac, 6); +} + + +#ifdef CL_IPV6_PASS +static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, + unsigned int *ipAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPV6; + memcpy(networkAddr+1, (unsigned char *)ipAddr, 16); +} + + +static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) +{ + while (len > 0) { + if (*data == tag && *(data+1) == len8b && len >= len8b*8) + return data+2; + + len -= (*(data+1))*8; + data += (*(data+1))*8; + } + return NULL; +} + + +static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac) +{ + struct icmp6hdr *icmphdr = (struct icmp6hdr *)data; + unsigned char *mac; + + if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) { + 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", + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) { + 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", + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { + 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", + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { + 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", + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_REDIRECT) { + 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", + 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); + return 1; + } + } + } + return 0; +} + + +static void convert_ipv6_mac_to_mc(struct sk_buff *skb) +{ + struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); + unsigned char *dst_mac = skb->data; + + //dst_mac[0] = 0xff; + //dst_mac[1] = 0xff; + /*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/ + dst_mac[0] = 0x33; + dst_mac[1] = 0x33; + memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4); + #if defined(__LINUX_2_6__) + /*modified by qinjunjie,warning:should not remove next line*/ + skb->pkt_type = PACKET_MULTICAST; + #endif +} +#endif /* CL_IPV6_PASS */ + + +static __inline__ int __nat25_network_hash(unsigned char *networkAddr) +{ + if(networkAddr[0] == NAT25_IPV4) + { + unsigned long x; + + x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_IPX) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ + networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_APPLE) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_PPPOE) + { + unsigned long x; + + x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; + + return x & (NAT25_HASH_SIZE - 1); + } +#ifdef CL_IPV6_PASS + else if(networkAddr[0] == NAT25_IPV6) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ + networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ + networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ + networkAddr[16]; + + return x & (NAT25_HASH_SIZE - 1); + } +#endif + else + { + unsigned long x = 0; + int i; + + for (i=0; ibr_ext_lock, &irqL); + + ent->next_hash = priv->nethash[hash]; + if(ent->next_hash != NULL) + ent->next_hash->pprev_hash = &ent->next_hash; + priv->nethash[hash] = ent; + ent->pprev_hash = &priv->nethash[hash]; + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static __inline__ void __network_hash_unlink(struct nat25_network_db_entry *ent) +{ + // Caller must _enter_critical_bh already! + //_irqL irqL; + //_enter_critical_bh(&priv->br_ext_lock, &irqL); + + *(ent->pprev_hash) = ent->next_hash; + if(ent->next_hash != NULL) + ent->next_hash->pprev_hash = ent->pprev_hash; + ent->next_hash = NULL; + ent->pprev_hash = NULL; + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static int __nat25_db_network_lookup_and_replace(_adapter *priv, + struct sk_buff *skb, unsigned char *networkAddr) +{ + struct nat25_network_db_entry *db; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + db = priv->nethash[__nat25_network_hash(networkAddr)]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) + { + if(!__nat25_has_expired(priv, db)) + { + // replace the destination mac address + memcpy(skb->data, db->macAddr, ETH_ALEN); + 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" + "%02x%02x%02x%02x%02x%02x\n", + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10], + db->networkAddr[11], + db->networkAddr[12], + db->networkAddr[13], + db->networkAddr[14], + 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", + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10]); +#endif + } + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return 1; + } + + db = db->next_hash; + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return 0; +} + + +static void __nat25_db_network_insert(_adapter *priv, + unsigned char *macAddr, unsigned char *networkAddr) +{ + struct nat25_network_db_entry *db; + int hash; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + hash = __nat25_network_hash(networkAddr); + db = priv->nethash[hash]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) + { + memcpy(db->macAddr, macAddr, ETH_ALEN); + db->ageing_timer = jiffies; + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return; + } + + db = db->next_hash; + } + + db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db)); + if(db == NULL) { + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return; + } + + memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); + memcpy(db->macAddr, macAddr, ETH_ALEN); + atomic_set(&db->use_count, 1); + db->ageing_timer = jiffies; + + __network_hash_link(priv, db, hash); + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static void __nat25_db_print(_adapter *priv) +{ + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + +#ifdef BR_EXT_DEBUG + static int counter = 0; + int i, j; + struct nat25_network_db_entry *db; + + counter++; + if((counter % 16) != 0) + return; + + for(i=0, j=0; inethash[i]; + + while (db != NULL) + { +#ifdef CL_IPV6_PASS + panic_printk("NAT25: DB(%d) H(%02d) C(%d) 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", + j, + i, + atomic_read(&db->use_count), + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10], + db->networkAddr[11], + db->networkAddr[12], + db->networkAddr[13], + db->networkAddr[14], + db->networkAddr[15], + db->networkAddr[16]); +#else + panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + j, + i, + atomic_read(&db->use_count), + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10]); +#endif + j++; + + db = db->next_hash; + } + } +#endif + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + + + +/* + * NAT2.5 interface + */ + +void nat25_db_cleanup(_adapter *priv) +{ + int i; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + for(i=0; inethash[i]; + while (f != NULL) { + struct nat25_network_db_entry *g; + + g = f->next_hash; + if(priv->scdb_entry == f) + { + memset(priv->scdb_mac, 0, ETH_ALEN); + memset(priv->scdb_ip, 0, 4); + priv->scdb_entry = NULL; + } + __network_hash_unlink(f); + rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); + + f = g; + } + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +void nat25_db_expire(_adapter *priv) +{ + int i; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + //if(!priv->ethBrExtInfo.nat25_disable) + { + for (i=0; inethash[i]; + + while (f != NULL) + { + struct nat25_network_db_entry *g; + g = f->next_hash; + + if(__nat25_has_expired(priv, f)) + { + if(atomic_dec_and_test(&f->use_count)) + { +#ifdef BR_EXT_DEBUG +#ifdef CL_IPV6_PASS + panic_printk("NAT25 Expire H(%02d) 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", + i, + f->macAddr[0], + f->macAddr[1], + f->macAddr[2], + f->macAddr[3], + f->macAddr[4], + f->macAddr[5], + f->networkAddr[0], + f->networkAddr[1], + f->networkAddr[2], + f->networkAddr[3], + f->networkAddr[4], + f->networkAddr[5], + f->networkAddr[6], + f->networkAddr[7], + f->networkAddr[8], + f->networkAddr[9], + f->networkAddr[10], + f->networkAddr[11], + f->networkAddr[12], + f->networkAddr[13], + f->networkAddr[14], + f->networkAddr[15], + f->networkAddr[16]); +#else + + panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + i, + f->macAddr[0], + f->macAddr[1], + f->macAddr[2], + f->macAddr[3], + f->macAddr[4], + f->macAddr[5], + f->networkAddr[0], + f->networkAddr[1], + f->networkAddr[2], + f->networkAddr[3], + f->networkAddr[4], + f->networkAddr[5], + f->networkAddr[6], + f->networkAddr[7], + f->networkAddr[8], + f->networkAddr[9], + f->networkAddr[10]); +#endif +#endif + if(priv->scdb_entry == f) + { + memset(priv->scdb_mac, 0, ETH_ALEN); + memset(priv->scdb_ip, 0, 4); + priv->scdb_entry = NULL; + } + __network_hash_unlink(f); + rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); + } + } + + f = g; + } + } + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +#ifdef SUPPORT_TX_MCAST2UNI +static int checkIPMcAndReplace(_adapter *priv, struct sk_buff *skb, unsigned int *dst_ip) +{ + struct stat_info *pstat; + struct list_head *phead, *plist; + int i; + + phead = &priv->asoc_list; + plist = phead->next; + + while (plist != phead) { + pstat = list_entry(plist, struct stat_info, asoc_list); + plist = plist->next; + + if (pstat->ipmc_num == 0) + continue; + + for (i=0; iipmc[i].used && !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip)+1, 3)) { + memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN); + return 1; + } + } + } + return 0; +} +#endif + +int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) +{ + unsigned short protocol; + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + + if(skb == NULL) + return -1; + + if((method <= NAT25_MIN) || (method >= NAT25_MAX)) + return -1; + + protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); + + /*---------------------------------------------------*/ + /* Handle IP frame */ + /*---------------------------------------------------*/ + if(protocol == __constant_htons(ETH_P_IP)) + { + struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + + if(((unsigned char*)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) + { + DEBUG_WARN("NAT25: malformed IP packet !\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + { + //some muticast with source IP is all zero, maybe other case is illegal + //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); + __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); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DEBUG_INFO("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)) + == (WIFI_STATION_STATE|WIFI_ASOC_STATE)) && + !checkIPMcAndReplace(priv, skb, &iph->daddr)) || + (OPMODE & WIFI_ADHOC_STATE))) +#endif + { + __nat25_generate_ipv4_network_addr(networkAddr, &iph->daddr); + + 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"); + 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"); + 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"); + netdev_br_init(priv->pnetdev); + } + memcpy(skb->data, priv->br_mac, ETH_ALEN); + } + } + } + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle ARP frame */ + /*---------------------------------------------------*/ + else if(protocol == __constant_htons(ETH_P_ARP)) + { + struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); + unsigned char *arp_ptr = (unsigned char *)(arp + 1); + unsigned int *sender, *target; + + if(arp->ar_pro != __constant_htons(ETH_P_IP)) + { + DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro)); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return 0; // skb_copy for all ARP frame + + case NAT25_INSERT: + { + DEBUG_INFO("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 + memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); + + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + + __nat25_generate_ipv4_network_addr(networkAddr, sender); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DEBUG_INFO("NAT25: Lookup ARP\n"); + + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + arp_ptr += (arp->ar_hln + arp->ar_pln); + target = (unsigned int *)arp_ptr; + + __nat25_generate_ipv4_network_addr(networkAddr, target); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // change to ARP target mac address to Lookup result + arp_ptr = (unsigned char *)(arp + 1); + arp_ptr += (arp->ar_hln + arp->ar_pln); + memcpy(arp_ptr, skb->data, ETH_ALEN); + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle IPX and Apple Talk frame */ + /*---------------------------------------------------*/ + else if((protocol == __constant_htons(ETH_P_IPX)) || + (protocol <= __constant_htons(ETH_FRAME_LEN))) + { + unsigned char ipx_header[2] = {0xFF, 0xFF}; + struct ipxhdr *ipx = NULL; + struct elapaarp *ea = NULL; + struct ddpehdr *ddp = NULL; + unsigned char *framePtr = skb->data + ETH_HLEN; + + if(protocol == __constant_htons(ETH_P_IPX)) + { + DEBUG_INFO("NAT25: Protocol=IPX (Ethernet II)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else if(protocol <= __constant_htons(ETH_FRAME_LEN)) + { + if(!memcmp(ipx_header, framePtr, 2)) + { + DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else + { + unsigned char ipx_8022_type = 0xE0; + unsigned char snap_8022_type = 0xAA; + + if(*framePtr == snap_8022_type) + { + unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; // IPX SNAP ID + unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; // Apple Talk AARP SNAP ID + unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; // Apple Talk DDP SNAP ID + + framePtr += 3; // eliminate the 802.2 header + + if(!memcmp(ipx_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + DEBUG_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else if(!memcmp(aarp_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + ea = (struct elapaarp *)framePtr; + } + else if(!memcmp(ddp_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + ddp = (struct ddpehdr *)framePtr; + } + else + { + DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], + framePtr[1], framePtr[2], framePtr[3], framePtr[4]); + return -1; + } + } + else if(*framePtr == ipx_8022_type) + { + framePtr += 3; // eliminate the 802.2 header + + if(!memcmp(ipx_header, framePtr, 2)) + { + DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else + return -1; + } + else + return -1; + } + } + else + return -1; + + /* IPX */ + if(ipx != NULL) + { + switch(method) + { + case NAT25_CHECK: + if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) + { + DEBUG_INFO("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", + ipx->ipx_dest.net, + ipx->ipx_dest.node[0], + ipx->ipx_dest.node[1], + ipx->ipx_dest.node[2], + ipx->ipx_dest.node[3], + ipx->ipx_dest.node[4], + ipx->ipx_dest.node[5], + ipx->ipx_dest.sock, + ipx->ipx_source.net, + ipx->ipx_source.node[0], + ipx->ipx_source.node[1], + ipx->ipx_source.node[2], + ipx->ipx_source.node[3], + ipx->ipx_source.node[4], + ipx->ipx_source.node[5], + ipx->ipx_source.sock); + + if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) + { + DEBUG_INFO("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); + + // change IPX source node addr to wlan STA address + memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); + } + else + { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); + } + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + if(!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) + { + DEBUG_INFO("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); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // replace IPX destination node addr with Lookup destination MAC addr + memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); + } + else + { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + } + return 0; + + default: + return -1; + } + } + + /* AARP */ + else if(ea != NULL) + { + /* Sanity check fields. */ + if(ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) + { + DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return 0; + + case NAT25_INSERT: + { + // 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", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DEBUG_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // change to AARP destination mac address to Lookup result + memcpy(ea->hw_dst, skb->data, ETH_ALEN); + } + return 0; + + default: + return -1; + } + } + + /* DDP */ + else if(ddp != NULL) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + { + DEBUG_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DEBUG_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + return 0; + + default: + return -1; + } + } + + return -1; + } + + /*---------------------------------------------------*/ + /* Handle PPPoE frame */ + /*---------------------------------------------------*/ + else if((protocol == __constant_htons(ETH_P_PPP_DISC)) || + (protocol == __constant_htons(ETH_P_PPP_SES))) + { + struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); + unsigned short *pMagic; + + switch(method) + { + case NAT25_CHECK: + if (ph->sid == 0) + return 0; + return 1; + + case NAT25_INSERT: + if(ph->sid == 0) // Discovery phase according to tag + { + if(ph->code == PADI_CODE || ph->code == PADR_CODE) + { + if (priv->ethBrExtInfo.addPPPoETag) { + struct pppoe_tag *tag, *pOldTag; + unsigned char tag_buf[40]; + int old_tag_len=0; + + tag = (struct pppoe_tag *)tag_buf; + pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); + if (pOldTag) { // if SID existed, copy old value and delete it + old_tag_len = ntohs(pOldTag->tag_len); + if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { + DEBUG_ERR("SID tag length too long!\n"); + return -1; + } + + memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, + pOldTag->tag_data, old_tag_len); + + if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); + } + + tag->tag_type = PTT_RELAY_SID; + tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); + + // insert the magic_code+client mac in relay tag + pMagic = (unsigned short *)tag->tag_data; + *pMagic = htons(MAGIC_CODE); + memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); + + //Add relay tag + if(__nat25_add_pppoe_tag(skb, tag) < 0) + return -1; + + DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", + (ph->code == PADI_CODE ? "PADI" : "PADR")); + } + else { // not add relay tag + if (priv->pppoe_connection_in_progress && + memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { + DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); + return -2; + } + + if (priv->pppoe_connection_in_progress == 0) + memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); + + priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; + } + } + else + return -1; + } + else // session phase + { + DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); + + __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + + if (!priv->ethBrExtInfo.addPPPoETag && + priv->pppoe_connection_in_progress && + !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) + priv->pppoe_connection_in_progress = 0; + } + return 0; + + case NAT25_LOOKUP: + if(ph->code == PADO_CODE || ph->code == PADS_CODE) + { + if (priv->ethBrExtInfo.addPPPoETag) { + struct pppoe_tag *tag; + unsigned char *ptr; + unsigned short tagType, tagLen; + int offset=0; + + if((ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID))) == 0) { + DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n"); + return -1; + } + + tag = (struct pppoe_tag *)ptr; + tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); + tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); + + if((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) { + DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); + return -1; + } + + pMagic = (unsigned short *)tag->tag_data; + if (ntohs(*pMagic) != MAGIC_CODE) { + DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n", + (ph->code == PADO_CODE ? "PADO" : "PADS")); + return -1; + } + + memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN); + + if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN) + offset = TAG_HDR_LEN; + + if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset)); + 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", + (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); + } + else { // not add relay tag + if (!priv->pppoe_connection_in_progress) { + DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n"); + return -1; + } + memcpy(skb->data, priv->pppoe_addr, ETH_ALEN); + priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; + } + } + else { + if(ph->sid != 0) + { + DEBUG_INFO("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); + + __nat25_db_print(priv); + } + else + return -1; + + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle EAP frame */ + /*---------------------------------------------------*/ + else if(protocol == __constant_htons(0x888e)) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + return 0; + + case NAT25_LOOKUP: + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle C-Media proprietary frame */ + /*---------------------------------------------------*/ + else if((protocol == __constant_htons(0xe2ae)) || + (protocol == __constant_htons(0xe2af))) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + return 0; + + case NAT25_LOOKUP: + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle IPV6 frame */ + /*---------------------------------------------------*/ +#ifdef CL_IPV6_PASS + else if(protocol == __constant_htons(ETH_P_IPV6)) + { + struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); + + if (sizeof(*iph) >= (skb->len - ETH_HLEN)) + { + DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + if (skb->data[0] & 1) + return 0; + return -1; + + case NAT25_INSERT: + { + DEBUG_INFO("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], + iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); + + if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); + + if (iph->nexthdr == IPPROTO_ICMPV6 && + skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { + if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), + skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { + struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); + hdr->icmp6_cksum = 0; + hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, + iph->payload_len, + IPPROTO_ICMPV6, + csum_partial((__u8 *)hdr, iph->payload_len, 0)); + } + } + } + } + return 0; + + case NAT25_LOOKUP: + DEBUG_INFO("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], + iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); + + + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); + if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { +#ifdef SUPPORT_RX_UNI2MCAST + if (iph->daddr.s6_addr[0] == 0xff) + convert_ipv6_mac_to_mc(skb); +#endif + } + return 0; + + default: + return -1; + } + } +#endif // CL_IPV6_PASS + + return -1; +} + + +int nat25_handle_frame(_adapter *priv, struct sk_buff *skb) +{ +#ifdef BR_EXT_DEBUG + if((!priv->ethBrExtInfo.nat25_disable) && (!(skb->data[0] & 1))) + { + panic_printk("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n", + skb->data[0], + skb->data[1], + skb->data[2], + skb->data[3], + skb->data[4], + skb->data[5], + skb->data[6], + skb->data[7], + skb->data[8], + skb->data[9], + skb->data[10], + skb->data[11]); + } +#endif + + if(!(skb->data[0] & 1)) + { + int is_vlan_tag=0, i, retval=0; + unsigned short vlan_hdr=0; + + if (*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2)); + skb_pull(skb, 4); + } + + if (!priv->ethBrExtInfo.nat25_disable) + { + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + /* + * This function look up the destination network address from + * the NAT2.5 database. Return value = -1 means that the + * corresponding network protocol is NOT support. + */ + if (!priv->ethBrExtInfo.nat25sc_disable && + (*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) && + !memcmp(priv->scdb_ip, skb->data+ETH_HLEN+16, 4)) { + memcpy(skb->data, priv->scdb_mac, ETH_ALEN); + + _exit_critical_bh(&priv->br_ext_lock, &irqL); + } + else { + _exit_critical_bh(&priv->br_ext_lock, &irqL); + + retval = nat25_db_handle(priv, skb, NAT25_LOOKUP); + } + } + else { + if (((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) && + !memcmp(priv->br_ip, skb->data+ETH_HLEN+16, 4)) || + ((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_ARP)) && + !memcmp(priv->br_ip, skb->data+ETH_HLEN+24, 4))) { + // for traffic to upper TCP/IP + retval = nat25_db_handle(priv, skb, NAT25_LOOKUP); + } + } + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr; + } + + if(retval == -1) { + //DEBUG_ERR("NAT25: Lookup fail!\n"); + return -1; + } + } + + return 0; +} + +#if 0 +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", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + rtl8192cd_set_hwaddr(priv->dev, &sa); +} + + +int mac_clone_handle_frame(_adapter *priv, struct sk_buff *skb) +{ + if(priv->ethBrExtInfo.macclone_enable && !priv->macclone_completed) + { + if(!(skb->data[ETH_ALEN] & 1)) //// check any other particular MAC add + { + if(memcmp(skb->data+ETH_ALEN, GET_MY_HWADDR(priv), ETH_ALEN) && + ((priv->dev->br_port) && + memcmp(skb->data+ETH_ALEN, priv->br_mac, ETH_ALEN))) + { + mac_clone(priv, skb->data+ETH_ALEN); + priv->macclone_completed = 1; + } + } + } + + return 0; +} +#endif // 0 + +#define SERVER_PORT 67 +#define CLIENT_PORT 68 +#define DHCP_MAGIC 0x63825363 +#define BROADCAST_FLAG 0x8000 + +struct dhcpMessage { + u_int8_t op; + u_int8_t htype; + u_int8_t hlen; + u_int8_t hops; + u_int32_t xid; + u_int16_t secs; + u_int16_t flags; + u_int32_t ciaddr; + u_int32_t yiaddr; + u_int32_t siaddr; + u_int32_t giaddr; + u_int8_t chaddr[16]; + u_int8_t sname[64]; + u_int8_t file[128]; + u_int32_t cookie; + u_int8_t options[308]; /* 312 - cookie */ +}; + +void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb) +{ + if(skb == NULL) + return; + + if(!priv->ethBrExtInfo.dhcp_bcst_disable) + { + unsigned short protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); + + if(protocol == __constant_htons(ETH_P_IP)) // IP + { + struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + + if(iph->protocol == IPPROTO_UDP) // UDP + { + struct udphdr *udph = (struct udphdr *)((SIZE_PTR)iph + (iph->ihl << 2)); + + if((udph->source == __constant_htons(CLIENT_PORT)) + && (udph->dest == __constant_htons(SERVER_PORT))) // DHCP request + { + struct dhcpMessage *dhcph = + (struct dhcpMessage *)((SIZE_PTR)udph + sizeof(struct udphdr)); + + if(dhcph->cookie == __constant_htonl(DHCP_MAGIC)) // match magic word + { + if(!(dhcph->flags & htons(BROADCAST_FLAG))) // if not broadcast + { + register int sum = 0; + + DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n"); + // or BROADCAST flag + dhcph->flags |= htons(BROADCAST_FLAG); + // recalculate checksum + sum = ~(udph->check) & 0xffff; + sum += dhcph->flags; + while(sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + udph->check = ~sum; + } + } + } + } + } + } +} + + +void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, + unsigned char *ipAddr) +{ + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + struct nat25_network_db_entry *db; + int hash; + //_irqL irqL; + //_enter_critical_bh(&priv->br_ext_lock, &irqL); + + __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); + hash = __nat25_network_hash(networkAddr); + db = priv->nethash[hash]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { + //_exit_critical_bh(&priv->br_ext_lock, &irqL); + return (void *)db; + } + + db = db->next_hash; + } + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); + return NULL; +} + +#endif // CONFIG_BR_EXT diff --git a/rtl8192cu-fixes/core/rtw_cmd.c b/rtl8192cu-fixes/core/rtw_cmd.c new file mode 100755 index 00000000..f906eb34 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_cmd.c @@ -0,0 +1,3035 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_CMD_C_ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BR_EXT +#include +#endif //CONFIG_BR_EXT +/* +Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. +No irqsave is necessary. +*/ + +sint _rtw_init_cmd_priv (struct cmd_priv *pcmdpriv) +{ + sint res=_SUCCESS; + +_func_enter_; + + _rtw_init_sema(&(pcmdpriv->cmd_queue_sema), 0); + //_rtw_init_sema(&(pcmdpriv->cmd_done_sema), 0); + _rtw_init_sema(&(pcmdpriv->terminate_cmdthread_sema), 0); + + + _rtw_init_queue(&(pcmdpriv->cmd_queue)); + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + + pcmdpriv->cmd_seq = 1; + + pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); + + if (pcmdpriv->cmd_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + + pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ( (SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); + + pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); + + if (pcmdpriv->rsp_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + + pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ( (SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); + + pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0; + +exit: + +_func_exit_; + + return res; + +} + +#ifdef CONFIG_C2H_WK +static void c2h_wk_callback(_workitem *work); +#endif +sint _rtw_init_evt_priv(struct evt_priv *pevtpriv) +{ + sint res=_SUCCESS; + +_func_enter_; + +#ifdef CONFIG_H2CLBK + _rtw_init_sema(&(pevtpriv->lbkevt_done), 0); + pevtpriv->lbkevt_limit = 0; + pevtpriv->lbkevt_num = 0; + pevtpriv->cmdevt_parm = NULL; +#endif + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + ATOMIC_SET(&pevtpriv->event_seq, 0); + pevtpriv->evt_done_cnt = 0; + +#ifdef CONFIG_EVENT_THREAD_MODE + + _rtw_init_sema(&(pevtpriv->evt_notify), 0); + _rtw_init_sema(&(pevtpriv->terminate_evtthread_sema), 0); + + pevtpriv->evt_allocated_buf = rtw_zmalloc(MAX_EVTSZ + 4); + if (pevtpriv->evt_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 - ((unsigned int)(pevtpriv->evt_allocated_buf) & 3); + + +#ifdef CONFIG_SDIO_HCI + pevtpriv->allocated_c2h_mem = rtw_zmalloc(C2H_MEM_SZ +4); + + if (pevtpriv->allocated_c2h_mem == NULL){ + res= _FAIL; + goto exit; + } + + pevtpriv->c2h_mem = pevtpriv->allocated_c2h_mem + 4\ + - ( (u32)(pevtpriv->allocated_c2h_mem) & 3); +#ifdef PLATFORM_OS_XP + pevtpriv->pc2h_mdl= IoAllocateMdl((u8 *)pevtpriv->c2h_mem, C2H_MEM_SZ , FALSE, FALSE, NULL); + + if(pevtpriv->pc2h_mdl == NULL){ + res= _FAIL; + goto exit; + } + MmBuildMdlForNonPagedPool(pevtpriv->pc2h_mdl); +#endif +#endif //end of CONFIG_SDIO_HCI + + _rtw_init_queue(&(pevtpriv->evt_queue)); + +exit: + +#endif //end of CONFIG_EVENT_THREAD_MODE + +#ifdef CONFIG_C2H_WK + _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); + pevtpriv->c2h_wk_alive = _FALSE; + pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1); +#endif + +_func_exit_; + + return res; +} + +void _rtw_free_evt_priv (struct evt_priv *pevtpriv) +{ +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("+_rtw_free_evt_priv \n")); + +#ifdef CONFIG_EVENT_THREAD_MODE + _rtw_free_sema(&(pevtpriv->evt_notify)); + _rtw_free_sema(&(pevtpriv->terminate_evtthread_sema)); + + + if (pevtpriv->evt_allocated_buf) + rtw_mfree(pevtpriv->evt_allocated_buf, MAX_EVTSZ + 4); +#endif + +#ifdef CONFIG_C2H_WK + _cancel_workitem_sync(&pevtpriv->c2h_wk); + while(pevtpriv->c2h_wk_alive) + rtw_msleep_os(10); + + while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { + void *c2h; + if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL + && c2h != (void *)pevtpriv) { + rtw_mfree(c2h, 16); + } + } + rtw_cbuf_free(pevtpriv->c2h_queue); +#endif + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n")); + +_func_exit_; + +} + +void _rtw_free_cmd_priv (struct cmd_priv *pcmdpriv) +{ +_func_enter_; + + if(pcmdpriv){ + _rtw_spinlock_free(&(pcmdpriv->cmd_queue.lock)); + _rtw_free_sema(&(pcmdpriv->cmd_queue_sema)); + //_rtw_free_sema(&(pcmdpriv->cmd_done_sema)); + _rtw_free_sema(&(pcmdpriv->terminate_cmdthread_sema)); + + if (pcmdpriv->cmd_allocated_buf) + rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ); + + if (pcmdpriv->rsp_allocated_buf) + rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4); + } +_func_exit_; +} + +/* +Calling Context: + +rtw_enqueue_cmd can only be called between kernel thread, +since only spin_lock is used. + +ISR/Call-Back functions can't call this sub-function. + +*/ + +sint _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj) +{ + _irqL irqL; + +_func_enter_; + + if (obj == NULL) + goto exit; + + //_enter_critical_bh(&queue->lock, &irqL); + _enter_critical(&queue->lock, &irqL); + + rtw_list_insert_tail(&obj->list, &queue->queue); + + //_exit_critical_bh(&queue->lock, &irqL); + _exit_critical(&queue->lock, &irqL); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +struct cmd_obj *_rtw_dequeue_cmd(_queue *queue) +{ + _irqL irqL; + struct cmd_obj *obj; + +_func_enter_; + + //_enter_critical_bh(&(queue->lock), &irqL); + _enter_critical(&queue->lock, &irqL); + if (rtw_is_list_empty(&(queue->queue))) + obj = NULL; + else + { + obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list); + rtw_list_delete(&obj->list); + } + + //_exit_critical_bh(&(queue->lock), &irqL); + _exit_critical(&queue->lock, &irqL); + +_func_exit_; + + return obj; +} + +u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) +{ + u32 res; +_func_enter_; + res = _rtw_init_cmd_priv (pcmdpriv); +_func_exit_; + return res; +} + +u32 rtw_init_evt_priv (struct evt_priv *pevtpriv) +{ + int res; +_func_enter_; + res = _rtw_init_evt_priv(pevtpriv); +_func_exit_; + return res; +} + +void rtw_free_evt_priv (struct evt_priv *pevtpriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_evt_priv\n")); + _rtw_free_evt_priv(pevtpriv); +_func_exit_; +} + +void rtw_free_cmd_priv (struct cmd_priv *pcmdpriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_cmd_priv\n")); + _rtw_free_cmd_priv(pcmdpriv); +_func_exit_; +} + +int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); +int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) +{ + u8 bAllow = _FALSE; //set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE + + #ifdef SUPPORT_HW_RFOFF_DETECTED + //To decide allow or not + if( (pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) + &&(!pcmdpriv->padapter->registrypriv.usbss_enable) + ) + { + if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ) + { + struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; + if(pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) + { + //DBG_871X("==>enqueue POWER_SAVING_CTRL_WK_CID\n"); + bAllow = _TRUE; + } + } + } + #endif + + if(cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) + bAllow = _TRUE; + + if( (pcmdpriv->padapter->hw_init_completed ==_FALSE && bAllow == _FALSE) + || pcmdpriv->cmdthd_running== _FALSE //com_thread not running + ) + { + //DBG_871X("%s:%s: drop cmdcode:%u, hw_init_completed:%u, cmdthd_running:%u\n", caller_func, __FUNCTION__, + // cmd_obj->cmdcode, + // pcmdpriv->padapter->hw_init_completed, + // pcmdpriv->cmdthd_running + //); + + return _FAIL; + } + return _SUCCESS; +} + + + +u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) +{ + int res = _FAIL; + PADAPTER padapter = pcmdpriv->padapter; + +_func_enter_; + + if (cmd_obj == NULL) { + goto exit; + } + + cmd_obj->padapter = padapter; + +#ifdef CONFIG_CONCURRENT_MODE + //change pcmdpriv to primary's pcmdpriv + if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter) + pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv); +#endif + + if( _FAIL == (res=rtw_cmd_filter(pcmdpriv, cmd_obj)) ) { + rtw_free_cmd_obj(cmd_obj); + goto exit; + } + + res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); + + if(res == _SUCCESS) + _rtw_up_sema(&pcmdpriv->cmd_queue_sema); + +exit: + +_func_exit_; + + return res; +} + +struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) +{ + struct cmd_obj *cmd_obj; + +_func_enter_; + + cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); + +_func_exit_; + return cmd_obj; +} + +void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) +{ +_func_enter_; + pcmdpriv->cmd_done_cnt++; + //_rtw_up_sema(&(pcmdpriv->cmd_done_sema)); +_func_exit_; +} + +void rtw_free_cmd_obj(struct cmd_obj *pcmd) +{ +_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->rsp!=NULL) + { + if(pcmd->rspsz!= 0) + { + //free rsp in cmd_obj + rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz); + } + } + + //free cmd_obj + rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj)); + +_func_exit_; +} + +void rtw_stop_cmd_thread(_adapter *adapter) +{ + if(adapter->cmdThread && adapter->cmdpriv.cmdthd_running == _TRUE + && adapter->cmdpriv.stop_req == 0) + { + adapter->cmdpriv.stop_req = 1; + _rtw_up_sema(&adapter->cmdpriv.cmd_queue_sema); + _rtw_down_sema(&adapter->cmdpriv.terminate_cmdthread_sema); + } +} + +thread_return rtw_cmd_thread(thread_context context) +{ + u8 ret; + struct cmd_obj *pcmd; + u8 *pcmdbuf, *prspbuf; + u8 (*cmd_hdl)(_adapter *padapter, u8* pbuf); + void (*pcmd_callback)(_adapter *dev, struct cmd_obj *pcmd); + _adapter *padapter = (_adapter *)context; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + +_func_enter_; + + thread_enter("RTW_CMD_THREAD"); + + pcmdbuf = pcmdpriv->cmd_buf; + prspbuf = pcmdpriv->rsp_buf; + + pcmdpriv->stop_req = 0; + pcmdpriv->cmdthd_running=_TRUE; + _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("start r871x rtw_cmd_thread !!!!\n")); + + while(1) + { + if ((_rtw_down_sema(&(pcmdpriv->cmd_queue_sema))) == _FAIL) { + LOG_LEVEL(_drv_err_, FUNC_ADPT_FMT" _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break\n", FUNC_ADPT_ARG(padapter)); + break; + } + + if (pcmdpriv->stop_req) { + LOG_LEVEL(_drv_err_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req); + break; + } + +#ifdef CONFIG_LPS_LCLK + if (rtw_register_cmd_alive(padapter) != _SUCCESS) + { + continue; + } +#endif + +_next: + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved == _TRUE)) + { + LOG_LEVEL(_drv_err_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", + __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); + break; + } + + if(!(pcmd = rtw_dequeue_cmd(pcmdpriv))) { +#ifdef CONFIG_LPS_LCLK + rtw_unregister_cmd_alive(padapter); +#endif + continue; + } + + if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) ) + { + pcmd->res = H2C_DROPPED; + goto post_process; + } + + if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) ) { + rtw_free_cmd_obj(pcmd); + continue; + } + + pcmdpriv->cmd_issued_cnt++; + + pcmd->cmdsz = _RND4((pcmd->cmdsz));//_RND4 + + _rtw_memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); + + if(pcmd->cmdcode <= (sizeof(wlancmds) /sizeof(struct cmd_hdl))) + { + cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; + + if (cmd_hdl) + { + ret = cmd_hdl(pcmd->padapter, pcmdbuf); + pcmd->res = ret; + } + + pcmdpriv->cmd_seq++; + } + else + { + pcmd->res = H2C_PARAMETERS_ERROR; + } + + cmd_hdl = NULL; + +post_process: + + //call callback function for post-processed + if(pcmd->cmdcode <= (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback))) + { + pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; + if(pcmd_callback == NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("mlme_cmd_hdl(): pcmd_callback=0x%p, cmdcode=0x%x\n", pcmd_callback, pcmd->cmdcode)); + rtw_free_cmd_obj(pcmd); + } + else + { + //todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL) + pcmd_callback(pcmd->padapter, pcmd);//need conider that free cmd_obj in rtw_cmd_callback + } + } + + flush_signals_thread(); + + goto _next; + + } + pcmdpriv->cmdthd_running=_FALSE; + + + // free all cmd_obj resources + do{ + pcmd = rtw_dequeue_cmd(pcmdpriv); + if(pcmd==NULL) + break; + + //DBG_871X("%s: leaving... drop cmdcode:%u\n", __FUNCTION__, pcmd->cmdcode); + + rtw_free_cmd_obj(pcmd); + }while(1); + + _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); + +_func_exit_; + + thread_exit(); + +} + + +#ifdef CONFIG_EVENT_THREAD_MODE +u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj) +{ + _irqL irqL; + int res; + _queue *queue = &pevtpriv->evt_queue; + +_func_enter_; + + res = _SUCCESS; + + if (obj == NULL) { + res = _FAIL; + goto exit; + } + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_insert_tail(&obj->list, &queue->queue); + + _exit_critical_bh(&queue->lock, &irqL); + + //rtw_evt_notify_isr(pevtpriv); + +exit: + +_func_exit_; + + return res; +} + +struct evt_obj *rtw_dequeue_evt(_queue *queue) +{ + _irqL irqL; + struct evt_obj *pevtobj; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (rtw_is_list_empty(&(queue->queue))) + pevtobj = NULL; + else + { + pevtobj = LIST_CONTAINOR(get_next(&(queue->queue)), struct evt_obj, list); + rtw_list_delete(&pevtobj->list); + } + + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; + + return pevtobj; +} + +void rtw_free_evt_obj(struct evt_obj *pevtobj) +{ +_func_enter_; + + if(pevtobj->parmbuf) + rtw_mfree((unsigned char*)pevtobj->parmbuf, pevtobj->evtsz); + + rtw_mfree((unsigned char*)pevtobj, sizeof(struct evt_obj)); + +_func_exit_; +} + +void rtw_evt_notify_isr(struct evt_priv *pevtpriv) +{ +_func_enter_; + pevtpriv->evt_done_cnt++; + _rtw_up_sema(&(pevtpriv->evt_notify)); +_func_exit_; +} +#endif + + +/* +u8 rtw_setstandby_cmd(unsigned char *adapter) +*/ +u8 rtw_setstandby_cmd(_adapter *padapter, uint action) +{ + struct cmd_obj* ph2c; + struct usb_suspend_parm* psetusbsuspend; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + + u8 ret = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + ret = _FAIL; + goto exit; + } + + psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm)); + if (psetusbsuspend == NULL) { + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + ret = _FAIL; + goto exit; + } + + psetusbsuspend->action = action; + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); + + ret = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return ret; +} + +/* +rtw_sitesurvey_cmd(~) + ### NOTE:#### (!!!!) + MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock +*/ +u8 rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *ssid, int ssid_num, + struct rtw_ieee80211_channel *ch, int ch_num) +{ + u8 res = _FAIL; + struct cmd_obj *ph2c; + struct sitesurvey_parm *psurveyPara; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + +#ifdef CONFIG_LPS + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE){ + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); + } +#endif + +#ifdef CONFIG_P2P_PS + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1); + } +#endif // CONFIG_P2P_PS + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) + return _FAIL; + + psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm)); + if (psurveyPara == NULL) { + rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj)); + return _FAIL; + } + + rtw_free_network_queue(padapter, _FALSE); + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("\nflush network queue\n\n")); + + init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + + /* psurveyPara->bsslimit = 48; */ + psurveyPara->scan_mode = pmlmepriv->scan_mode; + + /* prepare ssid list */ + if (ssid) { + int i; + for (i=0; issid[i], &ssid[i], sizeof(NDIS_802_11_SSID)); + psurveyPara->ssid_num++; + if (0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter), + psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength); + } + } + } + + /* prepare channel list */ + if (ch) { + int i; + for (i=0; ich[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); + psurveyPara->ch_num++; + if (0) + DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), + psurveyPara->ch[i].hw_value); + } + } + } + + set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + if(res == _SUCCESS) { + + pmlmepriv->scan_start_time = rtw_get_current_time(); + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + if (padapter->pbuddy_adapter == NULL ) + goto full_scan_timeout; + if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) + _set_timer(&pmlmepriv->scan_to_timer, + SURVEY_TO * ( padapter->mlmeextpriv.max_chan_nums + ( padapter->mlmeextpriv.max_chan_nums / RTW_SCAN_NUM_OF_CH ) * RTW_STAY_AP_CH_MILLISECOND ) + 1000 ); + else +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE +full_scan_timeout: + _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); + + rtw_led_control(padapter, LED_CTL_SITE_SURVEY); + + pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec + } else { + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + } + +_func_exit_; + + return res; +} + +u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset) +{ + struct cmd_obj* ph2c; + struct setdatarate_parm* pbsetdataratepara; + struct cmd_priv* pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm)); + if (pbsetdataratepara == NULL) { + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); +#ifdef MP_FIRMWARE_OFFLOAD + pbsetdataratepara->curr_rateidx = *(u32*)rateset; +// _rtw_memcpy(pbsetdataratepara, rateset, sizeof(u32)); +#else + pbsetdataratepara->mac_id = 5; + _rtw_memcpy(pbsetdataratepara->datarates, rateset, NumRates); +#endif + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset) +{ + struct cmd_obj* ph2c; + struct setbasicrate_parm* pssetbasicratepara; + struct cmd_priv* pcmdpriv=&padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res= _FAIL; + goto exit; + } + pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm)); + + if (pssetbasicratepara == NULL) { + rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); + + _rtw_memcpy(pssetbasicratepara->basicrates, rateset, NumRates); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; +} + + +/* +unsigned char rtw_setphy_cmd(unsigned char *adapter) + +1. be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program +2. for AdHoc/Ap mode or mp mode? + +*/ +u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch) +{ + struct cmd_obj* ph2c; + struct setphy_parm* psetphypara; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +// struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +// struct registry_priv* pregistry_priv = &padapter->registrypriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm)); + + if(psetphypara==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem)); + + psetphypara->modem = modem; + psetphypara->rfchannel = ch; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val) +{ + struct cmd_obj* ph2c; + struct writeBB_parm* pwritebbparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm)); + + if(pwritebbparm==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); + + pwritebbparm->offset = offset; + pwritebbparm->value = val; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_getbbreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +{ + struct cmd_obj* ph2c; + struct readBB_parm* prdbbparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res=_FAIL; + goto exit; + } + prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm)); + + if(prdbbparm ==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + return _FAIL; + } + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg); + ph2c->parmbuf = (unsigned char *)prdbbparm; + ph2c->cmdsz = sizeof(struct readBB_parm); + ph2c->rsp = pval; + ph2c->rspsz = sizeof(struct readBB_rsp); + + prdbbparm ->offset = offset; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_setrfreg_cmd(_adapter *padapter, u8 offset, u32 val) +{ + struct cmd_obj* ph2c; + struct writeRF_parm* pwriterfparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm)); + + if(pwriterfparm==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); + + pwriterfparm->offset = offset; + pwriterfparm->value = val; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_getrfreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +{ + struct cmd_obj* ph2c; + struct readRF_parm* prdrfparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm)); + if(prdrfparm ==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg); + ph2c->parmbuf = (unsigned char *)prdrfparm; + ph2c->cmdsz = sizeof(struct readRF_parm); + ph2c->rsp = pval; + ph2c->rspsz = sizeof(struct readRF_rsp); + + prdrfparm ->offset = offset; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} + +void rtw_getbbrfreg_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _func_enter_; + + //rtw_free_cmd_obj(pcmd); + rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); + rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); + +#ifdef CONFIG_MP_INCLUDED + padapter->mppriv.workparam.bcompleted= _TRUE; +#endif +_func_exit_; +} + +void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _func_enter_; + + rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); + rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); + +#ifdef CONFIG_MP_INCLUDED + padapter->mppriv.workparam.bcompleted= _TRUE; +#endif + +_func_exit_; +} + +u8 rtw_createbss_cmd(_adapter *padapter) +{ + struct cmd_obj* pcmd; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network; + u8 res=_SUCCESS; + +_func_enter_; + + rtw_led_control(padapter, LED_CTL_START_TO_LINK); + + if (pmlmepriv->assoc_ssid.SsidLength == 0){ + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for Any SSid:%s\n",pmlmepriv->assoc_ssid.Ssid)); + } else { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + } + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; + goto exit; + } + + _rtw_init_listhead(&pcmd->list); + pcmd->cmdcode = _CreateBss_CMD_; + pcmd->parmbuf = (unsigned char *)pdev_network; + pcmd->cmdsz = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX*)pdev_network); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + pdev_network->Length = pcmd->cmdsz; + +#ifdef CONFIG_RTL8712 + //notes: translate IELength & Length after assign the Length to cmdsz; + pdev_network->Length = cpu_to_le32(pcmd->cmdsz); + pdev_network->IELength = cpu_to_le32(pdev_network->IELength); + pdev_network->Ssid.SsidLength = cpu_to_le32(pdev_network->Ssid.SsidLength); +#endif + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_createbss_cmd_ex(_adapter *padapter, unsigned char *pbss, unsigned int sz) +{ + struct cmd_obj* pcmd; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; + goto exit; + } + + _rtw_init_listhead(&pcmd->list); + pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); + pcmd->parmbuf = pbss; + pcmd->cmdsz = sz; + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork) +{ + u8 *auth, res = _SUCCESS; + uint t_len = 0; + WLAN_BSSID_EX *psecnetwork; + struct cmd_obj *pcmd; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +_func_enter_; + + rtw_led_control(padapter, LED_CTL_START_TO_LINK); + + if (pmlmepriv->assoc_ssid.SsidLength == 0){ + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); + } else { + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid=[%s]\n", pmlmepriv->assoc_ssid.Ssid)); + } + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res=_FAIL; + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); + goto exit; + } + /* // for IEs is pointer + t_len = sizeof (ULONG) + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) + + sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + + sizeof (NDIS_802_11_CONFIGURATION) + + sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) + + sizeof (NDIS_802_11_RATES_EX)+ sizeof(WLAN_PHY_INFO)+ sizeof (ULONG) + MAX_IE_SZ; + */ + //for IEs is fix buf size + t_len = sizeof(WLAN_BSSID_EX); + + + //for hidden ap to set fw_state here + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != _TRUE) + { + switch(ndis_network_mode) + { + case Ndis802_11IBSS: + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + break; + + case Ndis802_11Infrastructure: + set_fwstate(pmlmepriv, WIFI_STATION_STATE); + break; + + case Ndis802_11APMode: + case Ndis802_11AutoUnknown: + case Ndis802_11InfrastructureMax: + break; + + } + } + + psecnetwork=(WLAN_BSSID_EX *)&psecuritypriv->sec_bss; + if(psecnetwork==NULL) + { + if(pcmd !=NULL) + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + + res=_FAIL; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork==NULL!!!\n")); + + goto exit; + } + + _rtw_memset(psecnetwork, 0, t_len); + + _rtw_memcpy(psecnetwork, &pnetwork->network, get_WLAN_BSSID_EX_sz(&pnetwork->network)); + + auth=&psecuritypriv->authenticator_ie[0]; + psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength; + + if((psecnetwork->IELength-12) < (256-1)) { + _rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12); + } else { + _rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); + } + + psecnetwork->IELength = 0; + // Added by Albert 2009/02/18 + // If the the driver wants to use the bssid to create the connection. + // If not, we have to copy the connecting AP's MAC address to it so that + // the driver just has the bssid information for PMKIDList searching. + + if ( pmlmepriv->assoc_by_bssid == _FALSE ) + { + _rtw_memcpy( &pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN ); + } + + psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); + + + pqospriv->qos_option = 0; + + if(pregistrypriv->wmm_enable) + { + u32 tmp_len; + + tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); + + if (psecnetwork->IELength != tmp_len) + { + psecnetwork->IELength = tmp_len; + pqospriv->qos_option = 1; //There is WMM IE in this corresp. beacon + } + else + { + pqospriv->qos_option = 0;//There is no WMM IE in this corresp. beacon + } + } + +#ifdef CONFIG_80211N_HT + phtpriv->ht_option = _FALSE; + if(pregistrypriv->ht_enable) + { + // Added by Albert 2010/06/23 + // For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. + // Especially for Realtek 8192u SoftAP. + if ( ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_ ) && + ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_ ) && + ( padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_ )) + { + //rtw_restructure_ht_ie + rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], + pnetwork->network.IELength, &psecnetwork->IELength, (u8)psecnetwork->Configuration.DSConfig ); + } + } + +#endif + + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); + + #if 0 + psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength; + + if(psecnetwork->IELength < (256-1)) + { + _rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], psecnetwork->IELength); + } + else + { + _rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], (256-1)); + } + #endif + + pcmd->cmdsz = get_WLAN_BSSID_EX_sz(psecnetwork);//get cmdsz before endian conversion + +#ifdef CONFIG_RTL8712 + //wlan_network endian conversion + psecnetwork->Length = cpu_to_le32(psecnetwork->Length); + psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength); + psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy); + psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi); + psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse); + psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow); + psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod); + psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig); + psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime); + psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern); + psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet); + psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length); + psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length); + psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode); + psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength); +#endif + + _rtw_init_listhead(&pcmd->list); + pcmd->cmdcode = _JoinBss_CMD_;//GEN_CMD_CODE(_JoinBss) + pcmd->parmbuf = (unsigned char *)psecnetwork; + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_disassoc_cmd(_adapter*padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ +{ + struct cmd_obj *cmdobj = NULL; + struct disconnect_parm *param = NULL; + struct cmd_priv *cmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n")); + + /* prepare cmd parameter */ + param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param)); + if (param == NULL) { + res = _FAIL; + goto exit; + } + param->deauth_timeout_ms = deauth_timeout_ms; + + if (enqueue) { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; + rtw_mfree((u8 *)param, sizeof(*param)); + goto exit; + } + init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); + res = rtw_enqueue_cmd(cmdpriv, cmdobj); + } else { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) + res = _FAIL; + rtw_mfree((u8 *)param, sizeof(*param)); + } + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) +{ + struct cmd_obj* ph2c; + struct setopmode_parm* psetop; + + struct cmd_priv *pcmdpriv= &padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FALSE; + goto exit; + } + psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm)); + + if(psetop==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FALSE; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); + psetop->mode = (u8)networktype; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct set_stakey_rsp *psetstakey_rsp = NULL; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct sta_info* sta = (struct sta_info* )psta; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + ph2c->rsp = (u8 *) psetstakey_rsp; + ph2c->rspsz = sizeof(struct set_stakey_rsp); + + _rtw_memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){ +#ifdef CONFIG_TDLS + if(sta->tdls_sta_state&TDLS_LINKED_STATE) + psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy; + else +#endif //CONFIG_TDLS + psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm; + }else{ + GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE); + } + + if (unicast_key == _TRUE) { +#ifdef CONFIG_TDLS + if(sta->tdls_sta_state&TDLS_LINKED_STATE) + _rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, 16); + else +#endif //CONFIG_TDLS + _rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); + } else { + _rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); + } + + //jeff: set this becasue at least sw key is ready + padapter->securitypriv.busetkipkey=_TRUE; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_clearstakey_cmd(_adapter *padapter, u8 *psta, u8 entry, u8 enqueue) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct set_stakey_rsp *psetstakey_rsp = NULL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct sta_info* sta = (struct sta_info* )psta; + u8 res=_SUCCESS; + +_func_enter_; + + if(!enqueue) + { + clear_cam_entry(padapter, entry); + } + else + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + ph2c->rsp = (u8 *) psetstakey_rsp; + ph2c->rspsz = sizeof(struct set_stakey_rsp); + + _rtw_memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); + + psetstakey_para->algorithm = _NO_PRIVACY_; + + psetstakey_para->id = entry; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + } + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table) +{ + struct cmd_obj* ph2c; + struct setratable_parm * psetrttblparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm)); + + if(psetrttblparm==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); + + _rtw_memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; + +} + +u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval) +{ + struct cmd_obj* ph2c; + struct getratable_parm * pgetrttblparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm)); + + if(pgetrttblparm==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + +// init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable); + ph2c->parmbuf = (unsigned char *)pgetrttblparm; + ph2c->cmdsz = sizeof(struct getratable_parm); + ph2c->rsp = (u8*)pval; + ph2c->rspsz = sizeof(struct getratable_rsp); + + pgetrttblparm ->rsvd = 0x0; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; + +} + +u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr) +{ + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct cmd_obj* ph2c; + struct set_assocsta_parm *psetassocsta_para; + struct set_stakey_rsp *psetassocsta_rsp = NULL; + + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm)); + if(psetassocsta_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp)); + if(psetassocsta_rsp==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm)); + return _FAIL; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); + ph2c->rsp = (u8 *) psetassocsta_rsp; + ph2c->rspsz = sizeof(struct set_assocsta_rsp); + + _rtw_memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + } + +u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr) +{ + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct cmd_obj* ph2c; + struct addBaReq_parm *paddbareq_parm; + + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm)); + if(paddbareq_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + paddbareq_parm->tid = tid; + _rtw_memcpy(paddbareq_parm->addr, addr, ETH_ALEN); + + init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); + + //DBG_871X("rtw_addbareq_cmd, tid=%d\n", tid); + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} +//add for CONFIG_IEEE80211W, none 11w can use it +u8 rtw_reset_securitypriv_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV; + pdrvextra_cmd_parm->type_size = 0; + pdrvextra_cmd_parm->pbuf = (u8 *)padapter; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + +u8 rtw_free_assoc_resources_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES; + pdrvextra_cmd_parm->type_size = 0; + pdrvextra_cmd_parm->pbuf = (u8 *)padapter; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + + +u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + goto exit; + + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter) + pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv); +#endif + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; + pdrvextra_cmd_parm->type_size = 0; + pdrvextra_cmd_parm->pbuf = (u8 *)padapter; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + +u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) +{ + struct cmd_obj *pcmdobj; + struct set_ch_parm *set_ch_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); + + /* check input parameter */ + + /* prepare cmd parameter */ + set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm)); + if (set_ch_parm == NULL) { + res= _FAIL; + goto exit; + } + set_ch_parm->ch = ch; + set_ch_parm->bw = bw; + set_ch_parm->ch_offset = ch_offset; + + if (enqueue) { + /* need enqueue, prepare cmd_obj and enqueue */ + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + } else { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) ) + res = _FAIL; + + rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); + } + + /* do something based on res... */ + +exit: + + DBG_871X(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); + +_func_exit_; + + return res; +} + +u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue) +{ + struct cmd_obj* pcmdobj; + struct SetChannelPlan_param *setChannelPlan_param; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n")); + + //check input parameter + if(!rtw_is_channel_plan_valid(chplan)) { + res = _FAIL; + goto exit; + } + + //prepare cmd parameter + setChannelPlan_param = (struct SetChannelPlan_param *)rtw_zmalloc(sizeof(struct SetChannelPlan_param)); + if(setChannelPlan_param == NULL) { + res= _FAIL; + goto exit; + } + setChannelPlan_param->channel_plan=chplan; + + if(enqueue) + { + //need enqueue, prepare cmd_obj and enqueue + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + } + else + { + //no need to enqueue, do the cmd hdl directly and free cmd parameter + if( H2C_SUCCESS !=set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) ) + res = _FAIL; + + rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param)); + } + + //do something based on res... + if(res == _SUCCESS) + padapter->mlmepriv.ChannelPlan = chplan; + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_led_blink_cmd(_adapter*padapter, PLED_871x pLed) +{ + struct cmd_obj* pcmdobj; + struct LedBlink_param *ledBlink_param; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + ledBlink_param = (struct LedBlink_param *)rtw_zmalloc(sizeof(struct LedBlink_param)); + if(ledBlink_param == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + ledBlink_param->pLed=pLed; + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no) +{ + struct cmd_obj* pcmdobj; + struct SetChannelSwitch_param*setChannelSwitch_param; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct SetChannelSwitch_param)); + if(setChannelSwitch_param == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + setChannelSwitch_param->new_ch_no=new_ch_no; + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option) +{ + struct cmd_obj* pcmdobj; + struct TDLSoption_param *TDLSoption; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + +#ifdef CONFIG_TDLS + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_tdls_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + TDLSoption= (struct TDLSoption_param *)rtw_zmalloc(sizeof(struct TDLSoption_param)); + if(TDLSoption == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_spinlock(&(padapter->tdlsinfo.cmd_lock)); + _rtw_memcpy(TDLSoption->addr, addr, 6); + TDLSoption->option = option; + _rtw_spinunlock(&(padapter->tdlsinfo.cmd_lock)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +#endif //CONFIG_TDLS + +exit: + + +_func_exit_; + + return res; +} + +static void traffic_status_watchdog(_adapter *padapter) +{ +#ifdef CONFIG_LPS + u8 bEnterPS; +#endif + u16 BusyThreshold = 100; + u8 bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE; + u8 bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo); +#endif //CONFIG_TDLS + + RT_LINK_DETECT_T * link_detect = &pmlmepriv->LinkDetectInfo; + + // + // Determine if our traffic is busy now + // + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) + { + + // if we raise bBusyTraffic in last watchdog, using lower threshold. + if (pmlmepriv->LinkDetectInfo.bBusyTraffic) + BusyThreshold = 75; + if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold ) + { + bBusyTraffic = _TRUE; + + if(pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold) + bRxBusyTraffic = _TRUE; + + if(pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) + bTxBusyTraffic = _TRUE; + } + + // Higher Tx/Rx data. + if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000 ) + { + bHigherBusyTraffic = _TRUE; + + // Extremely high Rx data. + if(pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 5000) + bHigherBusyRxTraffic = _TRUE; + + // Extremely high Tx data. + if(pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 5000) + bHigherBusyTxTraffic = _TRUE; + } + +#ifdef CONFIG_TRAFFIC_PROTECT +#define TX_ACTIVE_TH 2 +#define RX_ACTIVE_TH 1 +#define TRAFFIC_PROTECT_PERIOD_MS 4500 + + if (link_detect->NumTxOkInPeriod > TX_ACTIVE_TH + || link_detect->NumRxUnicastOkInPeriod > RX_ACTIVE_TH) { + + LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT" acqiure wake_lock for %u ms(tx:%d,rx_unicast:%d)\n", + FUNC_ADPT_ARG(padapter), + TRAFFIC_PROTECT_PERIOD_MS, + link_detect->NumTxOkInPeriod, + link_detect->NumRxUnicastOkInPeriod); + + rtw_lock_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS); + } +#endif + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_AUTOSETUP + if( ( ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD ) == 0 ) //TDLS_WATCHDOG_PERIOD * 2sec, periodically sending + issue_tdls_dis_req( padapter, NULL ); + ptdlsinfo->watchdog_count++; +#endif //CONFIG_TDLS_AUTOSETUP +#endif //CONFIG_TDLS + +#ifdef CONFIG_LPS + // check traffic for powersaving. + if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) + { + //DBG_871X("Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); + bEnterPS= _FALSE; + } + else + { + bEnterPS= _TRUE; + } + + // LeisurePS only work in infra mode. + if(bEnterPS) + { + LPS_Enter(padapter); + } + else + { + LPS_Leave(padapter); + } +#endif + } + else + { +#ifdef CONFIG_LPS + LPS_Leave(padapter); +#endif + } + + pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; + pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; + +} + +void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz); +void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz) +{ + struct mlme_priv *pmlmepriv; + + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + return; + + if((void*)padapter != (void*)pbuf && padapter->pbuddy_adapter == NULL) + return; + + padapter = (_adapter *)pbuf; + + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + return; + + pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + expire_timeout_chk(padapter); + } +#endif +#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK + + #ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_xmit_status_check(padapter); + #endif + + //if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE) + { + linked_status_chk(padapter); + traffic_status_watchdog(padapter); + } + + rtw_hal_dm_watchdog(padapter); + + //check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); + +} + +#ifdef CONFIG_LPS + +void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type); +void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 mstatus; + +_func_enter_; + + if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) + || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + { + return; + } + + switch(lps_ctrl_type) + { + case LPS_CTRL_SCAN: + //DBG_871X("LPS_CTRL_SCAN \n"); + LeaveAllPowerSaveMode(padapter); + break; + case LPS_CTRL_JOINBSS: + //DBG_871X("LPS_CTRL_JOINBSS \n"); + LPS_Leave(padapter); + break; + case LPS_CTRL_CONNECT: + //DBG_871X("LPS_CTRL_CONNECT \n"); + mstatus = 1; + // Reset LPS Setting + padapter->pwrctrlpriv.LpsIdleCount = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); + break; + case LPS_CTRL_DISCONNECT: + //DBG_871X("LPS_CTRL_DISCONNECT \n"); + mstatus = 0; + LPS_Leave(padapter); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); + break; + case LPS_CTRL_SPECIAL_PACKET: + //DBG_871X("LPS_CTRL_SPECIAL_PACKET \n"); + pwrpriv->DelayLPSLastTimeStamp = rtw_get_current_time(); + LPS_Leave(padapter); + break; + + default: + break; + } + +_func_exit_; +} + +u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + //struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + u8 res = _SUCCESS; + +_func_enter_; + + //if(!pwrctrlpriv->bLeisurePs) + // return res; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type != IFACE_PORT0) + return res; +#endif + + if(enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; + pdrvextra_cmd_parm->type_size = lps_ctrl_type; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else + { + lps_ctrl_wk_hdl(padapter, lps_ctrl_type); + } + +exit: + +_func_exit_; + + return res; + +} + +#endif +#ifdef CONFIG_ANTENNA_DIVERSITY + +void antenna_select_wk_hdl(_adapter *padapter, u8 antenna) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna)); +} + +u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 bSupportAntDiv = _FALSE; + u8 res = _SUCCESS; + +_func_enter_; + rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv)); + if(_FALSE == bSupportAntDiv ) return res; + + if(_TRUE == enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID; + pdrvextra_cmd_parm->type_size = antenna; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else{ + antenna_select_wk_hdl(padapter,antenna ); + } +exit: + +_func_exit_; + + return res; + +} +#endif + +void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz); +void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz) +{ + rtw_ps_processor(padapter); +} + +//add for CONFIG_IEEE80211W, none 11w can use it +void reset_securitypriv_hdl(_adapter *padapter) +{ + rtw_reset_securitypriv(padapter); +} + +void free_assoc_resources_hdl(_adapter *padapter) +{ + rtw_free_assoc_resources(padapter, 1); +} + +#ifdef CONFIG_P2P +u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType ) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + return res; + } + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID; + pdrvextra_cmd_parm->type_size = intCmdType; // As the command tppe. + pdrvextra_cmd_parm->pbuf = NULL; // Must be NULL here + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} +#endif //CONFIG_P2P + +u8 rtw_ps_cmd(_adapter*padapter) +{ + struct cmd_obj *ppscmd; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res = _SUCCESS; +_func_enter_; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER) + goto exit; +#endif + + ppscmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ppscmd==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ppscmd); + +exit: + +_func_exit_; + + return res; + +} + +#ifdef CONFIG_AP_MODE + +static void rtw_chk_hi_queue_hdl(_adapter *padapter) +{ + int cnt=0; + struct sta_info *psta_bmc; + struct sta_priv *pstapriv = &padapter->stapriv; + + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if(!psta_bmc) + return; + + + if(psta_bmc->sleepq_len==0) + { + while((rtw_read32(padapter, 0x414)&0x00ffff00)!=0) + { + rtw_msleep_os(100); + + cnt++; + + if(cnt>10) + break; + } + + if(cnt<=10) + { + pstapriv->tim_bitmap &= ~BIT(0); + pstapriv->sta_dz_bitmap &= ~BIT(0); + + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + } + } + +} + +u8 rtw_chk_hi_queue_cmd(_adapter*padapter) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; + pdrvextra_cmd_parm->type_size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} +#endif + +u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = C2H_WK_CID; + pdrvextra_cmd_parm->type_size = c2h_evt?16:0; + pdrvextra_cmd_parm->pbuf = c2h_evt; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; +} + +s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter) +{ + s32 ret = _FAIL; + u8 buf[16]; + + if (!c2h_evt) { + /* No c2h event in cmd_obj, read c2h event before handling*/ + if (c2h_evt_read(adapter, buf) == _SUCCESS) { + c2h_evt = (struct c2h_evt_hdr *)buf; + + if (filter && filter(c2h_evt->id) == _FALSE) + goto exit; + + ret = rtw_hal_c2h_handler(adapter, c2h_evt); + } + } else { + + if (filter && filter(c2h_evt->id) == _FALSE) + goto exit; + + ret = rtw_hal_c2h_handler(adapter, c2h_evt); + } +exit: + return ret; +} + +#ifdef CONFIG_C2H_WK +static void c2h_wk_callback(_workitem *work) +{ + struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); + _adapter *adapter = container_of(evtpriv, _adapter, evtpriv); + struct c2h_evt_hdr *c2h_evt; + c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); + + evtpriv->c2h_wk_alive = _TRUE; + + while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { + if ((c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) { + /* This C2H event is read, clear it */ + c2h_evt_clear(adapter); + } else if ((c2h_evt = (struct c2h_evt_hdr *)rtw_malloc(16)) != NULL) { + /* This C2H event is not read, read & clear now */ + if (c2h_evt_read(adapter, (u8*)c2h_evt) != _SUCCESS) + continue; + } + + /* Special pointer to trigger c2h_evt_clear only */ + if ((void *)c2h_evt == (void *)evtpriv) + continue; + + if (!c2h_evt_exist(c2h_evt)) { + rtw_mfree((u8*)c2h_evt, 16); + continue; + } + + if (ccx_id_filter(c2h_evt->id) == _TRUE) { + /* Handle CCX report here */ + rtw_hal_c2h_handler(adapter, c2h_evt); + rtw_mfree((u8*)c2h_evt, 16); + } else { + /* Enqueue into cmd_thread for others */ + rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); + } + } + + evtpriv->c2h_wk_alive = _FALSE; +} +#endif + +u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct drvextra_cmd_parm *pdrvextra_cmd; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + pdrvextra_cmd = (struct drvextra_cmd_parm*)pbuf; + + switch(pdrvextra_cmd->ec_id) + { + case DYNAMIC_CHK_WK_CID: + dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); + break; + case POWER_SAVING_CTRL_WK_CID: + power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); + break; +#ifdef CONFIG_LPS + case LPS_CTRL_WK_CID: + lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size); + break; +#endif +#ifdef CONFIG_ANTENNA_DIVERSITY + case ANT_SELECT_WK_CID: + antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size); + break; +#endif +#ifdef CONFIG_P2P_PS + case P2P_PS_WK_CID: + p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size); + break; +#endif // CONFIG_P2P_PS + case P2P_PROTO_WK_CID: + // Commented by Albert 2011/07/01 + // I used the type_size as the type command + p2p_protocol_wk_hdl( padapter, pdrvextra_cmd->type_size ); + break; +#ifdef CONFIG_AP_MODE + case CHECK_HIQ_WK_CID: + rtw_chk_hi_queue_hdl(padapter); + break; +#endif //CONFIG_AP_MODE +#ifdef CONFIG_INTEL_WIDI + case INTEl_WIDI_WK_CID: + intel_widi_wk_hdl(padapter, pdrvextra_cmd->type_size, pdrvextra_cmd->pbuf); + break; +#endif //CONFIG_INTEL_WIDI + //add for CONFIG_IEEE80211W, none 11w can use it + case RESET_SECURITYPRIV: + reset_securitypriv_hdl(padapter); + break; + case FREE_ASSOC_RESOURCES: + free_assoc_resources_hdl(padapter); + break; + case C2H_WK_CID: + c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL); + break; + + default: + break; + } + + + if(pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size>0) + { + rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); + } + + + return H2C_SUCCESS; + +} + +void rtw_survey_cmd_callback(_adapter* padapter , struct cmd_obj *pcmd) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(pcmd->res == H2C_DROPPED) + { + //TODO: cancel timer and do timeout handler directly... + //need to make timeout handlerOS independent + _set_timer(&pmlmepriv->scan_to_timer, 1); + } + else if (pcmd->res != H2C_SUCCESS) { + _set_timer(&pmlmepriv->scan_to_timer, 1); + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); + } + + // free cmd + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} +void rtw_disassoc_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if (pcmd->res != H2C_SUCCESS) + { + _enter_critical_bh(&pmlmepriv->lock, &irqL); + set_fwstate(pmlmepriv, _FW_LINKED); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n.")); + + goto exit; + } +#ifdef CONFIG_BR_EXT + else //clear bridge database + nat25_db_cleanup(padapter); +#endif //CONFIG_BR_EXT + + // free cmd + rtw_free_cmd_obj(pcmd); + +exit: + +_func_exit_; +} + + +void rtw_joinbss_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(pcmd->res == H2C_DROPPED) + { + //TODO: cancel timer and do timeout handler directly... + //need to make timeout handlerOS independent + _set_timer(&pmlmepriv->assoc_timer, 1); + } + else if(pcmd->res != H2C_SUCCESS) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); + _set_timer(&pmlmepriv->assoc_timer, 1); + } + + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} + +void rtw_createbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd) +{ + _irqL irqL; + u8 timer_cancelled; + struct sta_info *psta = NULL; + struct wlan_network *pwlan = NULL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)pcmd->parmbuf; + struct wlan_network *tgt_network = &(pmlmepriv->cur_network); + +_func_enter_; + + if((pcmd->res != H2C_SUCCESS)) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: rtw_createbss_cmd_callback Fail ************\n\n.")); + _set_timer(&pmlmepriv->assoc_timer, 1 ); + } + + _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + +#ifdef CONFIG_FW_MLMLE + //endian_convert + pnetwork->Length = le32_to_cpu(pnetwork->Length); + pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); + pnetwork->Privacy =le32_to_cpu(pnetwork->Privacy); + pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); + pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse); + pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow); + //pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod); + pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig); + pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); + pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); + pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); + pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length); + pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length); + pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode); + pnetwork->IELength = le32_to_cpu(pnetwork->IELength); +#endif + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) ) + { + psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); + if(!psta) + { + psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); + if (psta == NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nCan't alloc sta_info when createbss_cmd_callback\n")); + goto createbss_cmd_fail ; + } + } + + rtw_indicate_connect( padapter); + } + else + { + _irqL irqL; + + pwlan = _rtw_alloc_network(pmlmepriv); + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + if ( pwlan == NULL) + { + pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); + if( pwlan == NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n Error: can't get pwlan in rtw_joinbss_event_callback \n")); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto createbss_cmd_fail; + } + pwlan->last_scanned = rtw_get_current_time(); + } + else + { + rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); + } + + pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork); + _rtw_memcpy(&(pwlan->network), pnetwork, pnetwork->Length); + //pwlan->fixed = _TRUE; + + //rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); + + // copy pdev_network information to pmlmepriv->cur_network + _rtw_memcpy(&tgt_network->network, pnetwork, (get_WLAN_BSSID_EX_sz(pnetwork))); + + // reset DSConfig + //tgt_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->Configuration.DSConfig); + + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + +#if 0 + if((pmlmepriv->fw_state) & WIFI_AP_STATE) + { + psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); + + if (psta == NULL) { // for AP Mode & Adhoc Master Mode + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nCan't alloc sta_info when createbss_cmd_callback\n")); + goto createbss_cmd_fail ; + } + + rtw_indicate_connect( padapter); + } + else { + + //rtw_indicate_disconnect(dev); + } +#endif + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + // we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) + + } + +createbss_cmd_fail: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + rtw_free_cmd_obj(pcmd); + +_func_exit_; + +} + + + +void rtw_setstaKey_cmdrsp_callback(_adapter* padapter , struct cmd_obj *pcmd) +{ + + struct sta_priv * pstapriv = &padapter->stapriv; + struct set_stakey_rsp* psetstakey_rsp = (struct set_stakey_rsp*) (pcmd->rsp); + struct sta_info* psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); + +_func_enter_; + + if(psta==NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info \n\n")); + goto exit; + } + + //psta->aid = psta->mac_id = psetstakey_rsp->keyid; //CAM_ID(CAM_ENTRY) + +exit: + + rtw_free_cmd_obj(pcmd); + +_func_exit_; + +} +void rtw_setassocsta_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _irqL irqL; + struct sta_priv * pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct set_assocsta_parm* passocsta_parm = (struct set_assocsta_parm*)(pcmd->parmbuf); + struct set_assocsta_rsp* passocsta_rsp = (struct set_assocsta_rsp*) (pcmd->rsp); + struct sta_info* psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); + +_func_enter_; + + if(psta==NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info \n\n")); + goto exit; + } + + psta->aid = psta->mac_id = passocsta_rsp->cam_id; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)) + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + set_fwstate(pmlmepriv, _FW_LINKED); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} + +void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); +void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ +_func_enter_; + + rtw_free_cmd_obj(pcmd); +#ifdef CONFIG_MP_INCLUDED + padapter->mppriv.workparam.bcompleted=_TRUE; +#endif + +_func_exit_; + +} + diff --git a/rtl8192cu-fixes/core/rtw_debug.c b/rtl8192cu-fixes/core/rtw_debug.c new file mode 100755 index 00000000..f70fcb7b --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_debug.c @@ -0,0 +1,1337 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_DEBUG_C_ + + +#include +#include <../hal/dm.h> + +//#ifdef CONFIG_DEBUG_RTL871X + + u32 GlobalDebugLevel = _drv_err_; + + u64 GlobalDebugComponents = \ + _module_rtl871x_xmit_c_ | + _module_xmit_osdep_c_ | + _module_rtl871x_recv_c_ | + _module_recv_osdep_c_ | + _module_rtl871x_mlme_c_ | + _module_mlme_osdep_c_ | + _module_rtl871x_sta_mgt_c_ | + _module_rtl871x_cmd_c_ | + _module_cmd_osdep_c_ | + _module_rtl871x_io_c_ | + _module_io_osdep_c_ | + _module_os_intfs_c_| + _module_rtl871x_security_c_| + _module_rtl871x_eeprom_c_| + _module_hal_init_c_| + _module_hci_hal_init_c_| + _module_rtl871x_ioctl_c_| + _module_rtl871x_ioctl_set_c_| + _module_rtl871x_ioctl_query_c_| + _module_rtl871x_pwrctrl_c_| + _module_hci_intfs_c_| + _module_hci_ops_c_| + _module_hci_ops_os_c_| + _module_rtl871x_ioctl_os_c| + _module_rtl8712_cmd_c_| + _module_hal_xmit_c_| + _module_rtl8712_recv_c_ | + _module_mp_ | + _module_efuse_; + +//#endif + +#ifdef CONFIG_PROC_DEBUG +#include + +int proc_get_drv_version(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + + len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION); + + *eof = 1; + return len; +} + +int proc_get_log_level(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + len += snprintf(page + len, count - len, + "log_level:%d\n", + GlobalDebugLevel + ); + + *eof = 1; + return len; +} + +int proc_set_log_level(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 is_signal_dbg; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d ", &is_signal_dbg); + + if( is_signal_dbg >= 0 && is_signal_dbg < 10 ) + { + GlobalDebugLevel= is_signal_dbg; + printk("%d\n", GlobalDebugLevel); + } + } + + return count; + +} + +#ifdef DBG_MEM_ALLOC +int proc_get_mstat(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + int len = 0; + + len += _rtw_mstat_dump(page+len, count-len); + *eof = 1; + + return len; +} +#endif /* DBG_MEM_ALLOC */ + +int proc_get_write_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + *eof = 1; + return 0; +} + +int proc_set_write_reg(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 addr, val, len; + + if (count < 3) + { + DBG_871X("argument size is less than 3\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) { + DBG_871X("invalid write_reg parameter!\n"); + return count; + } + + switch(len) + { + case 1: + rtw_write8(padapter, addr, (u8)val); + break; + case 2: + rtw_write16(padapter, addr, (u16)val); + break; + case 4: + rtw_write32(padapter, addr, val); + break; + default: + DBG_871X("error write length=%d", len); + break; + } + + } + + return count; + +} + +static u32 proc_get_read_addr=0xeeeeeeee; +static u32 proc_get_read_len=0x4; + +int proc_get_read_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + int len = 0; + + if(proc_get_read_addr==0xeeeeeeee) + { + *eof = 1; + return len; + } + + switch(proc_get_read_len) + { + case 1: + len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr)); + break; + case 2: + len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr)); + break; + case 4: + len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr)); + break; + default: + len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len); + break; + } + + *eof = 1; + return len; + +} + +int proc_set_read_reg(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char tmp[16]; + u32 addr, len; + + if (count < 2) + { + DBG_871X("argument size is less than 2\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + + proc_get_read_addr = addr; + + proc_get_read_len = len; + } + + return count; + +} + +int proc_get_fwstate(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv)); + + *eof = 1; + return len; +} + +int proc_get_sec_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + int len = 0; + + len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, + psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); + + *eof = 1; + return len; +} + +int proc_get_mlmext_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + int len = 0; + + len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state); + + *eof = 1; + return len; +} + +int proc_get_qos_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option); + + *eof = 1; + return len; + +} + +int proc_get_ht_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option); + + *eof = 1; + return len; +} + +int proc_get_rf_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + int len = 0; + + len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n" + "oper_ch=%d, oper_bw=%d, oper_ch_offet=%d\n", + pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, + rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter)); + *eof = 1; + + return len; +} + +int proc_get_ap_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct sta_info *psta; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct sta_priv *pstapriv = &padapter->stapriv; + int len = 0; + + psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(psta) + { + int i; + struct recv_reorder_ctrl *preorder_ctrl; + + len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid); + len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); + len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); + len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); + + for(i=0;i<16;i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + if(preorder_ctrl->enable) + { + len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq); + } + } + + } + else + { + len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); + } + + *eof = 1; + return len; + +} + +int proc_get_adapter_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n", + padapter->bSurpriseRemoved, padapter->bDriverStopped); + + *eof = 1; + return len; + +} + +int proc_get_trx_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + int i; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct hw_xmit *phwxmit; + int len = 0; + + len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d" + ", free_ext_xmitbuf_cnt=%d, free_xframe_ext_cnt=%d" + ", free_recvframe_cnt=%d\n", + pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, + pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt, + precvpriv->free_recvframe_cnt); +#ifdef CONFIG_USB_HCI + len += snprintf(page + len, count - len, "rx_urb_pending_cnt=%d\n", precvpriv->rx_pending_cnt); +#endif + + len += snprintf(page + len, count - len, "recvbuf_skb_alloc_fail_cnt=%d\n", precvpriv->recvbuf_skb_alloc_fail_cnt); + len += snprintf(page + len, count - len, "recvbuf_null_cnt=%d\n", precvpriv->recvbuf_null_cnt); + len += snprintf(page + len, count - len, "read_port_complete_EINPROGRESS_cnt=%d\n", precvpriv->read_port_complete_EINPROGRESS_cnt); + len += snprintf(page + len, count - len, "read_port_complete_other_urb_err_cnt=%d\n", precvpriv->read_port_complete_other_urb_err_cnt); + len += snprintf(page + len, count - len, "hw_init_completed=%d\n", padapter->hw_init_completed); +#ifdef CONFIG_USB_HCI + len += snprintf(page + len, count - len, "continual_urb_error=%d\n", atomic_read(&pdvobj->continual_urb_error)); +#endif + + for(i = 0; i < 4; i++) + { + phwxmit = pxmitpriv->hwxmits + i; + len += snprintf(page + len, count - len, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); + } + + *eof = 1; + return len; + +} + + + +int proc_get_mac_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); + + for(i=0x0;i<0x300;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + + *eof = 1; + return len; + +} + +int proc_get_mac_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); + memset(page, 0, count); + for(i=0x300;i<0x600;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + + *eof = 1; + return len; + +} + +int proc_get_mac_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= MAC REG =======\n"); + + for(i=0x600;i<0x800;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + + *eof = 1; + return len; + +} + +int proc_get_bb_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); + for(i=0x800;i<0xB00;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + *eof = 1; + return len; +} + +int proc_get_bb_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); + for(i=0xB00;i<0xE00;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + *eof = 1; + return len; +} + +int proc_get_bb_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1; + + len += snprintf(page + len, count - len, "\n======= BB REG =======\n"); + for(i=0xE00;i<0x1000;i+=4) + { + if(j%4==1) len += snprintf(page + len, count - len,"0x%02x",i); + len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) len += snprintf(page + len, count - len,"\n"); + } + *eof = 1; + return len; +} + +int proc_get_rf_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1,path; + u32 value; + + len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); + path = 1; + len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path); + for(i=0;i<0xC0;i++) + { + //value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord); + value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); + if(j%4==1) len += snprintf(page + len, count - len, "0x%02x ",i); + len += snprintf(page + len, count - len, " 0x%08x ",value); + if((j++)%4==0) len += snprintf(page + len, count - len, "\n"); + } + + *eof = 1; + return len; +} + + +int proc_get_rf_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1,path; + u32 value; + + len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); + path = 1; + len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path); + for(i=0xC0;i<0x100;i++) + { + //value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord); + value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); + if(j%4==1) len += snprintf(page + len, count - len, "0x%02x ",i); + len += snprintf(page + len, count - len, " 0x%08x ",value); + if((j++)%4==0) len += snprintf(page + len, count - len, "\n"); + } + *eof = 1; + return len; +} + + +int proc_get_rf_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1,path; + u32 value; + + len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); + path = 2; + len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path); + for(i=0;i<0xC0;i++) + { + //value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord); + value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); + if(j%4==1) len += snprintf(page + len, count - len, "0x%02x ",i); + len += snprintf(page + len, count - len, " 0x%08x ",value); + if((j++)%4==0) len += snprintf(page + len, count - len, "\n"); + } + + *eof = 1; + return len; +} + + +int proc_get_rf_reg_dump4(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + int i,j=1,path; + u32 value; + + len += snprintf(page + len, count - len, "\n======= RF REG =======\n"); + path = 2; + len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path); + for(i=0xC0;i<0x100;i++) + { + //value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord); + value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff); + if(j%4==1) len += snprintf(page + len, count - len, "0x%02x ",i); + len += snprintf(page + len, count - len, " 0x%08x ",value); + if((j++)%4==0) len += snprintf(page + len, count - len, "\n"); + } + *eof = 1; + return len; +} + + + +int proc_get_rx_signal(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + len += snprintf(page + len, count - len, + "rssi:%d\n" + "rxpwdb:%d\n" + "signal_strength:%u\n" + "signal_qual:%u\n" + "noise:%u\n", + padapter->recvpriv.rssi, + padapter->recvpriv.rxpwdb, + padapter->recvpriv.signal_strength, + padapter->recvpriv.signal_qual, + padapter->recvpriv.noise + ); + + *eof = 1; + return len; +} + +int proc_set_rx_signal(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 is_signal_dbg, signal_strength; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); + + is_signal_dbg = is_signal_dbg==0?0:1; + + if(is_signal_dbg && num!=2) + return count; + + signal_strength = signal_strength>100?100:signal_strength; + signal_strength = signal_strength<0?0:signal_strength; + + padapter->recvpriv.is_signal_dbg = is_signal_dbg; + padapter->recvpriv.signal_strength_dbg=signal_strength; + + if(is_signal_dbg) + DBG_871X("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); + else + DBG_871X("set %s\n", "HW_SIGNAL_STRENGTH"); + + } + + return count; + +} + +int proc_get_ht_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + int len = 0; + + if(pregpriv) + len += snprintf(page + len, count - len, + "%d\n", + pregpriv->ht_enable + ); + + *eof = 1; + return len; +} + +int proc_set_ht_enable(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode >= 0 && mode < 2 ) + { + pregpriv->ht_enable= mode; + printk("ht_enable=%d\n", pregpriv->ht_enable); + } + } + + return count; + +} + + +int proc_get_cbw40_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + int len = 0; + + if(pregpriv) + len += snprintf(page + len, count - len, + "%d\n", + pregpriv->cbw40_enable + ); + + *eof = 1; + return len; +} + +int proc_set_cbw40_enable(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode >= 0 && mode < 2 ) + { + pregpriv->cbw40_enable= mode; + printk("cbw40_enable=%d\n", mode); + } + } + + return count; + +} + +int proc_get_ampdu_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + int len = 0; + + if(pregpriv) + len += snprintf(page + len, count - len, + "%d\n", + pregpriv->ampdu_enable + ); + + *eof = 1; + return len; +} + +int proc_set_ampdu_enable(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode >= 0 && mode < 3 ) + { + pregpriv->ampdu_enable= mode; + printk("ampdu_enable=%d\n", mode); + } + } + + return count; + +} + + +int proc_get_two_path_rssi(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + int len = 0; + + if(padapter) + len += snprintf(page + len, count - len, + "%d %d\n", + padapter->recvpriv.RxRssi[0], + padapter->recvpriv.RxRssi[1] + ); + + *eof = 1; + return len; +} + +int proc_get_rx_stbc(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + + int len = 0; + + if(pregpriv) + len += snprintf(page + len, count - len, + "%d\n", + pregpriv->rx_stbc + ); + + *eof = 1; + return len; +} + +int proc_set_rx_stbc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && (mode == 0 || mode == 1|| mode == 2|| mode == 3)) + { + pregpriv->rx_stbc= mode; + printk("rx_stbc=%d\n", mode); + } + } + + return count; + +} + +int proc_get_vid(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u16 VID=0; + int len = 0; + + rtw_hal_get_hwreg(padapter, HW_VAR_VID, (u8 *)&VID); + len += snprintf(page + len, count - len, + "%04x\n", + VID + ); + + *eof = 1; + return len; +} + +int proc_get_pid(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u16 PID=0; + int len = 0; + + rtw_hal_get_hwreg(padapter, HW_VAR_PID, (u8 *)&PID); + len += snprintf(page + len, count - len, + "%04x\n", + PID + ); + + *eof = 1; + return len; +} + +int proc_get_rssi_disp(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + *eof = 1; + return 0; +} + +int proc_set_rssi_disp(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 enable=0; + + if (count < 1) + { + DBG_8192C("argument size is less than 1\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x", &enable); + + if (num != 1) { + DBG_8192C("invalid set_rssi_disp parameter!\n"); + return count; + } + + if(enable) + { + DBG_8192C("Turn On Rx RSSI Display Function\n"); + padapter->bRxRSSIDisplay = enable ; + } + else + { + DBG_8192C("Turn Off Rx RSSI Display Function\n"); + padapter->bRxRSSIDisplay = 0 ; + } + + } + + return count; + +} + + +#ifdef CONFIG_AP_MODE + +int proc_get_all_sta_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + _irqL irqL; + struct sta_info *psta; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapter->stapriv; + int i, j; + _list *plist, *phead; + struct recv_reorder_ctrl *preorder_ctrl; + int len = 0; + + + len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); + + _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(extra_arg == psta->aid) + { + len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); + len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); + len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); + len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len); + len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability); + len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags); + len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk); + len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); + len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); + len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info); + len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); + + for(j=0;j<16;j++) + { + preorder_ctrl = &psta->recvreorder_ctrl[j]; + if(preorder_ctrl->enable) + { + len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq); + } + } + + } + + } + + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + *eof = 1; + return len; + +} + +#endif + +#ifdef DBG_MEMORY_LEAK +#include +extern atomic_t _malloc_cnt;; +extern atomic_t _malloc_size;; + +int proc_get_malloc_cnt(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + + int len = 0; + + len += snprintf(page + len, count - len, "_malloc_cnt=%d\n", atomic_read(&_malloc_cnt)); + len += snprintf(page + len, count - len, "_malloc_size=%d\n", atomic_read(&_malloc_size)); + + *eof = 1; + return len; +} +#endif /* DBG_MEMORY_LEAK */ + +#ifdef CONFIG_FIND_BEST_CHANNEL +int proc_get_best_channel(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + int len = 0; + u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0; + + for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + if ( pmlmeext->channel_set[i].ChannelNum == 1) + index_24G = i; + if ( pmlmeext->channel_set[i].ChannelNum == 36) + index_5G = i; + } + + for (i=0; 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 ) { + index_24G = i; + best_channel_24G = pmlmeext->channel_set[i].ChannelNum; + } + } + + // 5G + if ( pmlmeext->channel_set[i].ChannelNum >= 36 + && pmlmeext->channel_set[i].ChannelNum < 140 ) { + // Find primary channel + if ( (( pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } + + if ( pmlmeext->channel_set[i].ChannelNum >= 149 + && pmlmeext->channel_set[i].ChannelNum < 165) { + // find primary channel + if ( (( pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } +#if 1 // debug + len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n", + pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count); +#endif + } + + len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G); + len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G); + + *eof = 1; + return len; + +} + +int proc_set_best_channel(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + char tmp[32]; + + if(count < 1) + return -EFAULT; + + if(buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) + { + int i; + for(i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) + { + pmlmeext->channel_set[i].rx_count = 0; + } + + DBG_871X("set %s\n", "Clean Best Channel Count"); + } + + return count; +} +#endif /* CONFIG_FIND_BEST_CHANNEL */ + +#if defined(DBG_CONFIG_ERROR_DETECT) +#include +int proc_get_sreset(char *page, char **start, off_t offset, int count, int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + int len = 0; + + *eof = 1; + return len; +} + +int proc_set_sreset(struct file *file, const char *buffer, unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + s32 trigger_point; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%d", &trigger_point); + + if (trigger_point == SRESET_TGP_NULL) + rtw_hal_sreset_reset(padapter); + else + sreset_set_trigger_point(padapter, trigger_point); + } + + return count; + +} +#endif /* DBG_CONFIG_ERROR_DETECT */ + +#ifdef CONFIG_DM_ADAPTIVITY +int proc_get_dm_adaptivity(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + int len = 0; + + len += dm_adaptivity_get_parm_str(padapter, page, count); + + *eof = 1; + return len; +} + +int proc_set_dm_adaptivity(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct net_device *dev = (struct net_device *)data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 TH_L2H_ini; + s8 TH_EDCCA_HL_diff; + u32 IGI_Base; + int ForceEDCCA; + u8 AdapEn_RSSI; + u8 IGI_LowerBound; + + if (count < 1) + return -EFAULT; + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x %hhd %x %d %hhu %hhu", + &TH_L2H_ini, &TH_EDCCA_HL_diff, &IGI_Base, &ForceEDCCA, &AdapEn_RSSI, &IGI_LowerBound); + + if (num != 6) + return count; + + dm_adaptivity_set_parm(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)IGI_Base, (bool)ForceEDCCA, AdapEn_RSSI, IGI_LowerBound); + } + + return count; +} +#endif /* CONFIG_DM_ADAPTIVITY */ + +#endif + diff --git a/rtl8192cu-fixes/core/rtw_eeprom.c b/rtl8192cu-fixes/core/rtw_eeprom.c new file mode 100755 index 00000000..fd07d64d --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_eeprom.c @@ -0,0 +1,423 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_EEPROM_C_ + +#include +#include +#include + +void up_clk(_adapter* padapter, u16 *x) +{ +_func_enter_; + *x = *x | _EESK; + rtw_write8(padapter, EE_9346CR, (u8)*x); + rtw_udelay_os(CLOCK_RATE); + +_func_exit_; + +} + +void down_clk(_adapter * padapter, u16 *x ) +{ +_func_enter_; + *x = *x & ~_EESK; + rtw_write8(padapter, EE_9346CR, (u8)*x); + rtw_udelay_os(CLOCK_RATE); +_func_exit_; +} + +void shift_out_bits(_adapter * padapter, u16 data, u16 count) +{ + u16 x,mask; +_func_enter_; + + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + mask = 0x01 << (count - 1); + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDO | _EEDI); + + do + { + x &= ~_EEDI; + if(data & mask) + x |= _EEDI; + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + rtw_write8(padapter, EE_9346CR, (u8)x); + rtw_udelay_os(CLOCK_RATE); + up_clk(padapter, &x); + down_clk(padapter, &x); + mask = mask >> 1; + } while(mask); + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x &= ~_EEDI; + rtw_write8(padapter, EE_9346CR, (u8)x); +out: +_func_exit_; +} + +u16 shift_in_bits (_adapter * padapter) +{ + u16 x,d=0,i; +_func_enter_; + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + + x &= ~( _EEDO | _EEDI); + d = 0; + + for(i=0; i<16; i++) + { + d = d << 1; + up_clk(padapter, &x); + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDI); + if(x & _EEDO) + d |= 1; + + down_clk(padapter, &x); + } +out: +_func_exit_; + + return d; +} + +void standby(_adapter * padapter ) +{ + u8 x; +_func_enter_; + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EECS | _EESK); + rtw_write8(padapter, EE_9346CR,x); + + rtw_udelay_os(CLOCK_RATE); + x |= _EECS; + rtw_write8(padapter, EE_9346CR, x); + rtw_udelay_os(CLOCK_RATE); +_func_exit_; +} + +u16 wait_eeprom_cmd_done(_adapter* padapter) +{ + u8 x; + u16 i,res=_FALSE; +_func_enter_; + standby(padapter ); + for (i=0; i<200; i++) + { + x = rtw_read8(padapter, EE_9346CR); + if (x & _EEDO){ + res=_TRUE; + goto exit; + } + rtw_udelay_os(CLOCK_RATE); + } +exit: +_func_exit_; + return res; +} + +void eeprom_clean(_adapter * padapter) +{ + u16 x; +_func_enter_; + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x &= ~(_EECS | _EEDI); + rtw_write8(padapter, EE_9346CR, (u8)x); + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + up_clk(padapter, &x); + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + down_clk(padapter, &x); +out: +_func_exit_; +} + +void eeprom_write16(_adapter * padapter, u16 reg, u16 data) +{ + u8 x; +#ifdef CONFIG_RTL8712 + u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new; + tmp8_ori=rtw_read8(padapter, 0x102502f1); + tmp8_new=tmp8_ori & 0xf7; + if(tmp8_ori != tmp8_new){ + rtw_write8(padapter, 0x102502f1, tmp8_new); + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n")); + } + tmp8_clk_ori=rtw_read8(padapter,0x10250003); + tmp8_clk_new=tmp8_clk_ori|0x20; + if(tmp8_clk_new!=tmp8_clk_ori){ + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n")); + rtw_write8(padapter, 0x10250003, tmp8_clk_new); + } +#endif +_func_enter_; + + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, x); + + shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); + + if(padapter->EepromAddressSize==8) //CF+ and SDIO + shift_out_bits(padapter, 0, 6); + else //USB + shift_out_bits(padapter, 0, 4); + + standby( padapter); + +// Commented out by rcnjko, 2004.0 +// // Erase this particular word. Write the erase opcode and register +// // number in that order. The opcode is 3bits in length; reg is 6 bits long. +// shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3); +// shift_out_bits(Adapter, reg, Adapter->EepromAddressSize); +// +// if (wait_eeprom_cmd_done(Adapter ) == FALSE) +// { +// return; +// } + + + standby(padapter ); + + // write the new word to the EEPROM + + // send the write opcode the EEPORM + shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); + + // select which word in the EEPROM that we are writing to. + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + // write the data to the selected EEPROM word. + shift_out_bits(padapter, data, 16); + + if (wait_eeprom_cmd_done(padapter ) == _FALSE) + { + + goto exit; + } + + standby(padapter ); + + shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); + shift_out_bits(padapter, reg, 4); + + eeprom_clean(padapter ); +exit: +#ifdef CONFIG_RTL8712 + if(tmp8_clk_new!=tmp8_clk_ori) + rtw_write8(padapter, 0x10250003, tmp8_clk_ori); + if(tmp8_new!=tmp8_ori) + rtw_write8(padapter, 0x102502f1, tmp8_ori); + +#endif +_func_exit_; + return; +} + +u16 eeprom_read16(_adapter * padapter, u16 reg) //ReadEEprom +{ + + u16 x; + u16 data=0; +#ifdef CONFIG_RTL8712 + u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new; + tmp8_ori= rtw_read8(padapter, 0x102502f1); + tmp8_new = tmp8_ori & 0xf7; + if(tmp8_ori != tmp8_new){ + rtw_write8(padapter, 0x102502f1, tmp8_new); + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n")); + } + tmp8_clk_ori=rtw_read8(padapter,0x10250003); + tmp8_clk_new=tmp8_clk_ori|0x20; + if(tmp8_clk_new!=tmp8_clk_ori){ + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n")); + rtw_write8(padapter, 0x10250003, tmp8_clk_new); + } +#endif +_func_enter_; + + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + // select EEPROM, reset bits, set _EECS + x = rtw_read8(padapter, EE_9346CR); + + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, (unsigned char)x); + + // write the read opcode and register number in that order + // The opcode is 3bits in length, reg is 6 bits long + shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + // Now read the data (16 bits) in from the selected EEPROM word + data = shift_in_bits(padapter); + + eeprom_clean(padapter); +out: +#ifdef CONFIG_RTL8712 + if(tmp8_clk_new!=tmp8_clk_ori) + rtw_write8(padapter, 0x10250003, tmp8_clk_ori); + if(tmp8_new!=tmp8_ori) + rtw_write8(padapter, 0x102502f1, tmp8_ori); + +#endif +_func_exit_; + return data; + + +} + + + + +//From even offset +void eeprom_read_sz(_adapter * padapter, u16 reg, u8* data, u32 sz) +{ + + u16 x, data16; + u32 i; +_func_enter_; + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + // select EEPROM, reset bits, set _EECS + x = rtw_read8(padapter, EE_9346CR); + + if(padapter->bSurpriseRemoved==_TRUE){ + RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, (unsigned char)x); + + // write the read opcode and register number in that order + // The opcode is 3bits in length, reg is 6 bits long + shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + + for(i=0; i>8; + } + + eeprom_clean(padapter); +out: +_func_exit_; + + + +} + + +//addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg) +u8 eeprom_read(_adapter * padapter, u32 addr_off, u8 sz, u8* rbuf) +{ + u8 quotient, remainder, addr_2align_odd; + u16 reg, stmp , i=0, idx = 0; +_func_enter_; + reg = (u16)(addr_off >> 1); + addr_2align_odd = (u8)(addr_off & 0x1); + + if(addr_2align_odd) //read that start at high part: e.g 1,3,5,7,9,... + { + stmp = eeprom_read16(padapter, reg); + rbuf[idx++] = (u8) ((stmp>>8)&0xff); //return hogh-part of the short + reg++; sz--; + } + + quotient = sz >> 1; + remainder = sz & 0x1; + + for( i=0 ; i < quotient; i++) + { + stmp = eeprom_read16(padapter, reg+i); + rbuf[idx++] = (u8) (stmp&0xff); + rbuf[idx++] = (u8) ((stmp>>8)&0xff); + } + + reg = reg+i; + if(remainder){ //end of read at lower part of short : 0,2,4,6,... + stmp = eeprom_read16(padapter, reg); + rbuf[idx] = (u8)(stmp & 0xff); + } +_func_exit_; + return _TRUE; +} + + + +VOID read_eeprom_content(_adapter * padapter) +{ + +_func_enter_; + + +_func_exit_; +} + diff --git a/rtl8192cu-fixes/core/rtw_ieee80211.c b/rtl8192cu-fixes/core/rtw_ieee80211.c new file mode 100755 index 00000000..6305ba3f --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_ieee80211.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 + * + * + ******************************************************************************/ +#define _IEEE80211_C + +#include +#include +#include +#include +#include + +u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; +u16 RTW_WPA_VERSION = 1; +u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; +u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; +u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; +u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; +u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; +u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; +u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; +u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; +u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; + +u16 RSN_VERSION_BSD = 1; +u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; +u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; +u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; +u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; +u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; +u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; +u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; +u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; +//----------------------------------------------------------- +// for adhoc-master to generate ie and provide supported-rate to fw +//----------------------------------------------------------- + +static u8 WIFI_CCKRATES[] = +{(IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK)}; + +static u8 WIFI_OFDMRATES[] = +{(IEEE80211_OFDM_RATE_6MB), + (IEEE80211_OFDM_RATE_9MB), + (IEEE80211_OFDM_RATE_12MB), + (IEEE80211_OFDM_RATE_18MB), + (IEEE80211_OFDM_RATE_24MB), + IEEE80211_OFDM_RATE_36MB, + IEEE80211_OFDM_RATE_48MB, + IEEE80211_OFDM_RATE_54MB}; + + +int rtw_get_bit_value_from_ieee_value(u8 val) +{ + unsigned char dot11_rate_table[]={2,4,11,22,12,18,24,36,48,72,96,108,0}; // last element must be zero!! + + int i=0; + while(dot11_rate_table[i] != 0) { + if (dot11_rate_table[i] == val) + return BIT(i); + i++; + } + return 0; +} + +uint rtw_is_cckrates_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + i++; + } + + return _FALSE; +} + +uint rtw_is_cckratesonly_included(u8 *rate) +{ + u32 i = 0; + + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + + return _FALSE; + + i++; + } + + return _TRUE; + +} + +int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) +{ + if (channel > 14) + { + if ((rtw_is_cckrates_included(rate)) == _TRUE) + return WIRELESS_INVALID; + else + return WIRELESS_11A; + } + else // could be pure B, pure G, or B/G + { + if ((rtw_is_cckratesonly_included(rate)) == _TRUE) + return WIRELESS_11B; + else if((rtw_is_cckrates_included(rate)) == _TRUE) + return WIRELESS_11BG; + else + return WIRELESS_11G; + } + +} + +u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, + unsigned int *frlen) +{ + _rtw_memcpy((void *)pbuf, (void *)source, len); + *frlen = *frlen + len; + return (pbuf + len); +} + +// rtw_set_ie will update frame length +u8 *rtw_set_ie +( + u8 *pbuf, + sint index, + uint len, + u8 *source, + uint *frlen //frame length +) +{ +_func_enter_; + *pbuf = (u8)index; + + *(pbuf + 1) = (u8)len; + + if (len > 0) + _rtw_memcpy((void *)(pbuf + 2), (void *)source, len); + + *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, + u8 new_ch, u8 ch_switch_cnt) +{ + u8 ie_data[3]; + + ie_data[0] = ch_switch_mode; + ie_data[1] = new_ch; + ie_data[2] = ch_switch_cnt; + return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len); +} + +inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset) +{ + if (ch_offset == SCN) + return HAL_PRIME_CHNL_OFFSET_DONT_CARE; + else if(ch_offset == SCA) + return HAL_PRIME_CHNL_OFFSET_UPPER; + else if(ch_offset == SCB) + return HAL_PRIME_CHNL_OFFSET_LOWER; + + return HAL_PRIME_CHNL_OFFSET_DONT_CARE; +} + +inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset) +{ + if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) + return SCN; + else if(ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + return SCB; + else if(ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + return SCA; + + return SCN; +} + +inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset) +{ + return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET, 1, &secondary_ch_offset, buf_len); +} + +inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, + u8 flags, u16 reason, u16 precedence) +{ + u8 ie_data[6]; + + ie_data[0] = ttl; + ie_data[1] = flags; + RTW_PUT_LE16((u8*)&ie_data[2], reason); + RTW_PUT_LE16((u8*)&ie_data[4], precedence); + + return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); +} + +/*---------------------------------------------------------------------------- +index: the information element id index, limit is the limit for search +-----------------------------------------------------------------------------*/ +u8 *rtw_get_ie(u8 *pbuf, sint index, sint *len, sint limit) +{ + sint tmp,i; + u8 *p; +_func_enter_; + if (limit < 1){ + _func_exit_; + return NULL; + } + + p = pbuf; + i = 0; + *len = 0; + while(1) + { + if (*p == index) + { + *len = *(p + 1); + return (p); + } + else + { + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); + } + if (i >= limit) + break; + } +_func_exit_; + return NULL; +} + +/** + * rtw_get_ie_ex - Search specific IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @eid: Element ID to match + * @oui: OUI to match + * @oui_len: OUI length + * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE + * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE + * + * Returns: The address of the specific IE found, or NULL + */ +u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen) +{ + uint cnt; + u8 *target_ie = NULL; + + + if(ielen) + *ielen = 0; + + if(!in_ie || in_len<=0) + return target_ie; + + cnt = 0; + + while(cnt 12) + break; + + i++; + } +_func_exit_; + return i; +} + +int rtw_generate_ie(struct registry_priv *pregistrypriv) +{ + u8 wireless_mode; + int sz = 0, rateLen; + WLAN_BSSID_EX* pdev_network = &pregistrypriv->dev_network; + u8* ie = pdev_network->IEs; + +_func_enter_; + + //timestamp will be inserted by hardware + sz += 8; + ie += sz; + + //beacon interval : 2bytes + *(u16*)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);//BCN_INTERVAL; + sz += 2; + ie += 2; + + //capability info + *(u16*)ie = 0; + + *(u16*)ie |= cpu_to_le16(cap_IBSS); + + if(pregistrypriv->preamble == PREAMBLE_SHORT) + *(u16*)ie |= cpu_to_le16(cap_ShortPremble); + + if (pdev_network->Privacy) + *(u16*)ie |= cpu_to_le16(cap_Privacy); + + sz += 2; + ie += 2; + + //SSID + ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); + + //supported rates + if(pregistrypriv->wireless_mode == WIRELESS_11ABGN) + { + if(pdev_network->Configuration.DSConfig > 14) + wireless_mode = WIRELESS_11A_5N; + else + wireless_mode = WIRELESS_11BG_24N; + } + else + { + wireless_mode = pregistrypriv->wireless_mode; + } + + rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode) ; + + rateLen = rtw_get_rateset_len(pdev_network->SupportedRates); + + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz); + //ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); + } + else + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz); + } + + //DS parameter set + ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz); + + + //IBSS Parameter Set + + ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz); + + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); + } + + + //HT Cap. + if(((pregistrypriv->wireless_mode&WIRELESS_11_5N)||(pregistrypriv->wireless_mode&WIRELESS_11_24N)) + && (pregistrypriv->ht_enable==_TRUE)) + { + //todo: + } + + //pdev_network->IELength = sz; //update IELength + +_func_exit_; + + //return _SUCCESS; + + return sz; + +} + +unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) +{ + int len; + u16 val16; + unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; + u8 *pbuf = pie; + + while(1) + { + pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit); + + if (pbuf) { + + //check if oui matches... + if (_rtw_memcmp((pbuf + 2), wpa_oui_type, sizeof (wpa_oui_type)) == _FALSE) { + + goto check_next_ie; + } + + //check version... + _rtw_memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16)); + + val16 = le16_to_cpu(val16); + if (val16 != 0x0001) + goto check_next_ie; + + *wpa_ie_len = *(pbuf + 1); + + return pbuf; + } + else { + + *wpa_ie_len = 0; + return NULL; + } + +check_next_ie: + + limit -= (2 + len); + + if (limit <= 0) + break; + + pbuf += (2 + len); + } + + *wpa_ie_len = 0; + + return NULL; +} + +unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit) +{ + + return rtw_get_ie(pie, _WPA2_IE_ID_,rsn_ie_len, limit); + +} + +int rtw_get_wpa_cipher_suite(u8 *s) +{ + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_NONE; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP40; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_TKIP; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_CCMP; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP104; + + return 0; +} + +int rtw_get_wpa2_cipher_suite(u8 *s) +{ + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_NONE; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP40; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_TKIP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_CCMP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP104; + + return 0; +} + + +int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher) +{ + int i, ret=_SUCCESS; + int left, count; + u8 *pos; + + if (wpa_ie_len <= 0) { + /* No WPA IE - fail silently */ + return _FAIL; + } + + + if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) || + (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != _TRUE) ) + { + return _FAIL; + } + + pos = wpa_ie; + + pos += 8; + left = wpa_ie_len - 8; + + + //group_cipher + if (left >= WPA_SELECTOR_LEN) { + + *group_cipher = rtw_get_wpa_cipher_suite(pos); + + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + + } + else if (left > 0) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); + + return _FAIL; + } + + + //pairwise_cipher + if (left >= 2) + { + //count = le16_to_cpu(*(u16*)pos); + count = RTW_GET_LE16(pos); + pos += 2; + left -= 2; + + if (count == 0 || left < count * WPA_SELECTOR_LEN) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " + "count %u left %u", __FUNCTION__, count, left)); + return _FAIL; + } + + for (i = 0; i < count; i++) + { + *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); + + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + } + + } + else if (left == 1) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); + return _FAIL; + } + + + return ret; + +} + +int rtw_parse_wpa2_ie(u8* rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher) +{ + int i, ret=_SUCCESS; + int left, count; + u8 *pos; + + if (rsn_ie_len <= 0) { + /* No RSN IE - fail silently */ + return _FAIL; + } + + + if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2))) + { + return _FAIL; + } + + pos = rsn_ie; + pos += 4; + left = rsn_ie_len - 4; + + //group_cipher + if (left >= RSN_SELECTOR_LEN) { + + *group_cipher = rtw_get_wpa2_cipher_suite(pos); + + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + + } else if (left > 0) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); + return _FAIL; + } + + //pairwise_cipher + if (left >= 2) + { + //count = le16_to_cpu(*(u16*)pos); + count = RTW_GET_LE16(pos); + pos += 2; + left -= 2; + + if (count == 0 || left < count * RSN_SELECTOR_LEN) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " + "count %u left %u", __FUNCTION__, count, left)); + return _FAIL; + } + + for (i = 0; i < count; i++) + { + *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); + + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + } + + } + else if (left == 1) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); + + return _FAIL; + } + + + return ret; + +} + +int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len) +{ + u8 authmode, sec_idx, i; + u8 wpa_oui[4]={0x0,0x50,0xf2,0x01}; + uint cnt; + +_func_enter_; + + //Search required WPA or WPA2 IE and copy to sec_ie[ ] + + cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); + + sec_idx=0; + + while(cnt found WPS_IE.....\n"); + *wps_ielen = ie_ptr[1]+2; + match=_TRUE; + } + return match; +} + +/** + * rtw_get_wps_ie - Search WPS IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie + * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE + * + * Returns: The address of the WPS IE found, or NULL + */ +u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) +{ + uint cnt; + u8 *wpsie_ptr=NULL; + u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04}; + + if(wps_ielen) + *wps_ielen = 0; + + if(!in_ie || in_len<=0) + return wpsie_ptr; + + cnt = 0; + + while(cntwpa_ie = pos; + elems->wpa_ie_len = elen; + break; + case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ + if (elen < 5) { + DBG_871X("short WME " + "information element ignored " + "(len=%lu)\n", + (unsigned long) elen); + return -1; + } + switch (pos[4]) { + case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: + case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: + elems->wme = pos; + elems->wme_len = elen; + break; + case WME_OUI_SUBTYPE_TSPEC_ELEMENT: + elems->wme_tspec = pos; + elems->wme_tspec_len = elen; + break; + default: + DBG_871X("unknown WME " + "information element ignored " + "(subtype=%d len=%lu)\n", + pos[4], (unsigned long) elen); + return -1; + } + break; + case 4: + /* Wi-Fi Protected Setup (WPS) IE */ + elems->wps_ie = pos; + elems->wps_ie_len = elen; + break; + default: + DBG_871X("Unknown Microsoft " + "information element ignored " + "(type=%d len=%lu)\n", + pos[3], (unsigned long) elen); + return -1; + } + break; + + case OUI_BROADCOM: + switch (pos[3]) { + case VENDOR_HT_CAPAB_OUI_TYPE: + elems->vendor_ht_cap = pos; + elems->vendor_ht_cap_len = elen; + break; + default: + DBG_871X("Unknown Broadcom " + "information element ignored " + "(type=%d len=%lu)\n", + pos[3], (unsigned long) elen); + return -1; + } + break; + + default: + DBG_871X("unknown vendor specific information " + "element ignored (vendor OUI %02x:%02x:%02x " + "len=%lu)\n", + pos[0], pos[1], pos[2], (unsigned long) elen); + return -1; + } + + return 0; + +} + +/** + * ieee802_11_parse_elems - Parse information elements in management frames + * @start: Pointer to the start of IEs + * @len: Length of IE buffer in octets + * @elems: Data structure for parsed elements + * @show_errors: Whether to show parsing errors in debug log + * Returns: Parsing result + */ +ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, + struct rtw_ieee802_11_elems *elems, + int show_errors) +{ + uint left = len; + u8 *pos = start; + int unknown = 0; + + _rtw_memset(elems, 0, sizeof(*elems)); + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) { + if (show_errors) { + DBG_871X("IEEE 802.11 element " + "parse failed (id=%d elen=%d " + "left=%lu)\n", + id, elen, (unsigned long) left); + } + return ParseFailed; + } + + switch (id) { + case WLAN_EID_SSID: + elems->ssid = pos; + elems->ssid_len = elen; + break; + case WLAN_EID_SUPP_RATES: + elems->supp_rates = pos; + elems->supp_rates_len = elen; + break; + case WLAN_EID_FH_PARAMS: + elems->fh_params = pos; + elems->fh_params_len = elen; + break; + case WLAN_EID_DS_PARAMS: + elems->ds_params = pos; + elems->ds_params_len = elen; + break; + case WLAN_EID_CF_PARAMS: + elems->cf_params = pos; + elems->cf_params_len = elen; + break; + case WLAN_EID_TIM: + elems->tim = pos; + elems->tim_len = elen; + break; + case WLAN_EID_IBSS_PARAMS: + elems->ibss_params = pos; + elems->ibss_params_len = elen; + break; + case WLAN_EID_CHALLENGE: + elems->challenge = pos; + elems->challenge_len = elen; + break; + case WLAN_EID_ERP_INFO: + elems->erp_info = pos; + elems->erp_info_len = elen; + break; + case WLAN_EID_EXT_SUPP_RATES: + elems->ext_supp_rates = pos; + elems->ext_supp_rates_len = elen; + break; + case WLAN_EID_VENDOR_SPECIFIC: + if (rtw_ieee802_11_parse_vendor_specific(pos, elen, + elems, + show_errors)) + unknown++; + break; + case WLAN_EID_RSN: + elems->rsn_ie = pos; + elems->rsn_ie_len = elen; + break; + case WLAN_EID_PWR_CAPABILITY: + elems->power_cap = pos; + elems->power_cap_len = elen; + break; + case WLAN_EID_SUPPORTED_CHANNELS: + elems->supp_channels = pos; + elems->supp_channels_len = elen; + break; + case WLAN_EID_MOBILITY_DOMAIN: + elems->mdie = pos; + elems->mdie_len = elen; + break; + case WLAN_EID_FAST_BSS_TRANSITION: + elems->ftie = pos; + elems->ftie_len = elen; + break; + case WLAN_EID_TIMEOUT_INTERVAL: + elems->timeout_int = pos; + elems->timeout_int_len = elen; + break; + case WLAN_EID_HT_CAP: + elems->ht_capabilities = pos; + elems->ht_capabilities_len = elen; + break; + case WLAN_EID_HT_OPERATION: + elems->ht_operation = pos; + elems->ht_operation_len = elen; + break; + default: + unknown++; + if (!show_errors) + break; + DBG_871X("IEEE 802.11 element parse " + "ignored unknown element (id=%d elen=%d)\n", + id, elen); + break; + } + + left -= elen; + pos += elen; + } + + if (left) + return ParseFailed; + + return unknown ? ParseUnknown : ParseOK; + +} + +static u8 key_char2num(u8 ch); +static u8 key_char2num(u8 ch) +{ + if((ch>='0')&&(ch<='9')) + return ch - '0'; + else if ((ch>='a')&&(ch<='f')) + return ch - 'a' + 10; + else if ((ch>='A')&&(ch<='F')) + return ch - 'A' + 10; + else + return 0xff; +} + +u8 str_2char2num(u8 hch, u8 lch); +u8 str_2char2num(u8 hch, u8 lch) +{ + return ((key_char2num(hch) * 10 ) + key_char2num(lch)); +} + +u8 key_2char2num(u8 hch, u8 lch); +u8 key_2char2num(u8 hch, u8 lch) +{ + return ((key_char2num(hch) << 4) | key_char2num(lch)); +} + +u8 convert_ip_addr(u8 hch, u8 mch, u8 lch) +{ + return ((key_char2num(hch) * 100) + (key_char2num(mch) * 10 ) + key_char2num(lch)); +} + +extern char* rtw_initmac; +void rtw_macaddr_cfg(u8 *mac_addr) +{ + u8 mac[ETH_ALEN]; + if(mac_addr == NULL) return; + + if ( rtw_initmac ) + { // Users specify the mac address + int jj,kk; + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk+ 1]); + } + _rtw_memcpy(mac_addr, mac, ETH_ALEN); + } + 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) && + (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] = 0x00; + mac[5] = 0x00; + // use default mac addresss + _rtw_memcpy(mac_addr, mac, ETH_ALEN); + DBG_871X("MAC Address from efuse error, assign default one !!!\n"); + } + + DBG_871X("rtw_macaddr_cfg MAC Address = "MAC_FMT"\n", MAC_ARG(mac_addr)); +} + +void dump_ies(u8 *buf, u32 buf_len) { + u8* pos = (u8*)buf; + u8 id, len; + + while(pos-buf<=buf_len){ + id = *pos; + len = *(pos+1); + + DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); + #ifdef CONFIG_P2P + dump_p2p_ie(pos, len); + #endif + dump_wps_ie(pos, len); + + pos+=(2+len); + } +} + +void dump_wps_ie(u8 *ie, u32 ie_len) { + u8* pos = (u8*)ie; + u16 id; + u16 len; + + u8 *wps_ie; + uint wps_ielen; + + wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen); + if(wps_ie != ie || wps_ielen == 0) + return; + + pos+=6; + while(pos-ie < ie_len){ + id = RTW_GET_BE16(pos); + len = RTW_GET_BE16(pos + 2); + + DBG_871X("%s ID:0x%04x, LEN:%u\n", __FUNCTION__, id, len); + + pos+=(4+len); + } +} + +#ifdef CONFIG_P2P +/** + * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies. + * @in_ie: Pointer of the first p2p ie + * @in_len: Total len of muiltiple p2p ies + * Returns: Length of merged p2p ie length + */ +u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 }; + int i=0; + int j=0, len=0; + + while( i < in_len) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i); + + if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) ) + { + len += pIE->Length-4; // 4 is P2P OUI length, don't count it in this loop + } + + i += (pIE->Length + 2); + } + + return len + 4; // Append P2P OUI length at last. +} + +/** + * rtw_p2p_merge_ies - Merge muitiple p2p ies into one + * @in_ie: Pointer of the first p2p ie + * @in_len: Total len of muiltiple p2p ies + * @merge_ie: Pointer of merged ie + * Returns: Length of merged p2p ie + */ +int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 len = 0; + u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 }; + u8 ELOUI[6] = { 0xDD, 0x00, 0x50, 0x6f, 0x9a, 0x09 }; //EID;Len;OUI, Len would copy at the end of function + int i=0; + + if( merge_ie != NULL) + { + //Set first P2P OUI + _rtw_memcpy(merge_ie, ELOUI, 6); + merge_ie += 6; + + while( i < in_len) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i); + + // Take out the rest of P2P OUIs + if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) ) + { + _rtw_memcpy( merge_ie, pIE->data +4, pIE->Length -4); + len += pIE->Length-4; + merge_ie += pIE->Length-4; + } + + i += (pIE->Length + 2); + } + + return len + 4; // 4 is for P2P OUI + + } + + return 0; +} + +void dump_p2p_ie(u8 *ie, u32 ie_len) { + u8* pos = (u8*)ie; + u8 id; + u16 len; + + u8 *p2p_ie; + uint p2p_ielen; + + p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen); + if(p2p_ie != ie || p2p_ielen == 0) + return; + + pos+=6; + while(pos-ie < ie_len){ + id = *pos; + len = RTW_GET_LE16(pos+1); + + DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len); + + pos+=(3+len); + } +} + +/** + * rtw_get_p2p_ie - Search P2P IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie + * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE + * + * Returns: The address of the P2P IE found, or NULL + */ +u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen) +{ + uint cnt = 0; + u8 *p2p_ie_ptr; + u8 eid, p2p_oui[4]={0x50,0x6F,0x9A,0x09}; + + if ( p2p_ielen != NULL ) + *p2p_ielen = 0; + + while(cnt MAX_IE_SZ)) { +#ifdef PLATFORM_LINUX + dump_stack(); +#endif + return NULL; + } + if( ( eid == _VENDOR_SPECIFIC_IE_ ) && ( _rtw_memcmp( &in_ie[cnt+2], p2p_oui, 4) == _TRUE ) ) + { + p2p_ie_ptr = in_ie + cnt; + + if ( p2p_ie != NULL ) + { + _rtw_memcpy( p2p_ie, &in_ie[ cnt ], in_ie[ cnt + 1 ] + 2 ); + } + + if ( p2p_ielen != NULL ) + { + *p2p_ielen = in_ie[ cnt + 1 ] + 2; + } + + return p2p_ie_ptr; + + break; + } + else + { + cnt += in_ie[ cnt + 1 ] +2; //goto next + } + + } + + return NULL; + +} + +/** + * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE + * @p2p_ie: Address of P2P IE to search + * @p2p_ielen: Length limit from p2p_ie + * @target_attr_id: The attribute ID of P2P attribute to search + * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr + * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute + * + * Returns: the address of the specific WPS attribute found, or NULL + */ +u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr) +{ + u8 *attr_ptr = NULL; + u8 *target_attr_ptr = NULL; + u8 p2p_oui[4]={0x50,0x6F,0x9A,0x09}; + + if(len_attr) + *len_attr = 0; + + if ( !p2p_ie || ( p2p_ie[0] != _VENDOR_SPECIFIC_IE_ ) || + ( _rtw_memcmp( p2p_ie + 2, p2p_oui , 4 ) != _TRUE ) ) + { + return attr_ptr; + } + + // 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) + attr_ptr = p2p_ie + 6; //goto first attr + + while(attr_ptr - p2p_ie < p2p_ielen) + { + // 3 = 1(Attribute ID) + 2(Length) + u8 attr_id = *attr_ptr; + u16 attr_data_len = RTW_GET_LE16(attr_ptr + 1); + u16 attr_len = attr_data_len + 3; + + //DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __FUNCTION__, attr_ptr, attr_id, attr_data_len); + if( attr_id == target_attr_id ) + { + target_attr_ptr = attr_ptr; + + if(buf_attr) + _rtw_memcpy(buf_attr, attr_ptr, attr_len); + + if(len_attr) + *len_attr = attr_len; + + break; + } + else + { + attr_ptr += attr_len; //goto next + } + + } + + return target_attr_ptr; +} + +/** + * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE + * @p2p_ie: Address of P2P IE to search + * @p2p_ielen: Length limit from p2p_ie + * @target_attr_id: The attribute ID of P2P attribute to search + * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content + * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content + * + * Returns: the address of the specific P2P attribute content found, or NULL + */ +u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content) +{ + u8 *attr_ptr; + u32 attr_len; + + if(len_content) + *len_content = 0; + + attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len); + + if(attr_ptr && attr_len) + { + if(buf_content) + _rtw_memcpy(buf_content, attr_ptr+3, attr_len-3); + + if(len_content) + *len_content = attr_len-3; + + return attr_ptr+3; + } + + return NULL; +} + +u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr) +{ + u32 a_len; + + *pbuf = attr_id; + + //*(u16*)(pbuf + 1) = cpu_to_le16(attr_len); + RTW_PUT_LE16(pbuf + 1, attr_len); + + if(pdata_attr) + _rtw_memcpy(pbuf + 3, pdata_attr, attr_len); + + a_len = attr_len + 3; + + return a_len; +} + +static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id) +{ + u8 *target_attr; + u32 target_attr_len; + uint ielen = ielen_ori; + int index=0; + + while(1) { + target_attr=rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len); + if(target_attr && target_attr_len) + { + u8 *next_attr = target_attr+target_attr_len; + uint remain_len = ielen-(next_attr-ie); + //dump_ies(ie, ielen); + #if 0 + DBG_871X("[%d] ie:%p, ielen:%u\n" + "target_attr:%p, target_attr_len:%u\n" + "next_attr:%p, remain_len:%u\n" + , index++ + , ie, ielen + , target_attr, target_attr_len + , next_attr, remain_len + ); + #endif + + _rtw_memset(target_attr, 0, target_attr_len); + _rtw_memcpy(target_attr, next_attr, remain_len); + _rtw_memset(target_attr+remain_len, 0, target_attr_len); + *(ie+1) -= target_attr_len; + ielen-=target_attr_len; + } + else + { + //if(index>0) + // dump_ies(ie, ielen); + break; + } + } + + return ielen; +} + +void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) +{ + u8 *p2p_ie; + uint p2p_ielen, p2p_ielen_ori; + int cnt; + + 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(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_); + } + #endif + + p2p_ielen=rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id); + if(p2p_ielen != p2p_ielen_ori) { + + u8 *next_ie_ori = p2p_ie+p2p_ielen_ori; + u8 *next_ie = p2p_ie+p2p_ielen; + uint remain_len = bss_ex->IELength-(next_ie_ori-bss_ex->IEs); + + _rtw_memcpy(next_ie, next_ie_ori, remain_len); + _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 + } + } +} + +#endif //CONFIG_P2P + +#ifdef CONFIG_WFD +int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen) +{ + int match; + uint cnt = 0; + u8 eid, wfd_oui[4]={0x50,0x6F,0x9A,0x0A}; + + + match=_FALSE; + + if ( in_len < 0 ) + { + return match; + } + + while(cnt 1 byte for attribute ID field, 2 bytes for length field + if(attr_content) + _rtw_memcpy( attr_content, &wfd_ie[ cnt + 3 ], attrlen ); + + if(attr_contentlen) + *attr_contentlen = attrlen; + + cnt += attrlen + 3; + + match = _TRUE; + break; + } + else + { + cnt += attrlen + 3; //goto next + } + + } + + return match; + +} +#endif // CONFIG_WFD + +//Baron adds to avoid FreeBSD warning +int ieee80211_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +int ieee80211_get_hdrlen(u16 fc) +{ + int hdrlen = 24; + + switch (WLAN_FC_GET_TYPE(fc)) { + case RTW_IEEE80211_FTYPE_DATA: + if (fc & RTW_IEEE80211_STYPE_QOS_DATA) + hdrlen += 2; + if ((fc & RTW_IEEE80211_FCTL_FROMDS) && (fc & RTW_IEEE80211_FCTL_TODS)) + hdrlen += 6; /* Addr4 */ + break; + case RTW_IEEE80211_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case RTW_IEEE80211_STYPE_CTS: + case RTW_IEEE80211_STYPE_ACK: + hdrlen = 10; + break; + default: + hdrlen = 16; + break; + } + break; + } + + return hdrlen; +} + +//show MCS rate, unit: 100Kbps +u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char * MCS_rate) +{ + u16 max_rate = 0; + + if(rf_type == RF_1T1R) + { + if(MCS_rate[0] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650); + else if(MCS_rate[0] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585); + else if(MCS_rate[0] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520); + else if(MCS_rate[0] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390); + else if(MCS_rate[0] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260); + else if(MCS_rate[0] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195); + else if(MCS_rate[0] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130); + else if(MCS_rate[0] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65); + } + else + { + if(MCS_rate[1]) + { + if(MCS_rate[1] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI_40)?3000:2700):((short_GI_20)?1444:1300); + else if(MCS_rate[1] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI_40)?2700:2430):((short_GI_20)?1300:1170); + else if(MCS_rate[1] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI_40)?2400:2160):((short_GI_20)?1156:1040); + else if(MCS_rate[1] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1800:1620):((short_GI_20)?867:780); + else if(MCS_rate[1] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520); + else if(MCS_rate[1] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390); + else if(MCS_rate[1] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260); + else if(MCS_rate[1] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130); + } + else + { + if(MCS_rate[0] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650); + else if(MCS_rate[0] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585); + else if(MCS_rate[0] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520); + else if(MCS_rate[0] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390); + else if(MCS_rate[0] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260); + else if(MCS_rate[0] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195); + else if(MCS_rate[0] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130); + else if(MCS_rate[0] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65); + } + } + return max_rate; +} + +int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8* category, u8 *action) +{ + const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u16 fc; + u8 c, a; + + fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); + + if ((fc & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)) + != (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION) + ) + { + return _FALSE; + } + + c = frame_body[0]; + + switch(c) { + case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */ + break; + default: + a = frame_body[1]; + } + + if (category) + *category = c; + if (action) + *action = a; + + return _TRUE; +} + +static const char *_action_public_str[] = { + "ACT_PUB_BSSCOEXIST", + "ACT_PUB_DSE_ENABLE", + "ACT_PUB_DSE_DEENABLE", + "ACT_PUB_DSE_REG_LOCATION", + "ACT_PUB_EXT_CHL_SWITCH", + "ACT_PUB_DSE_MSR_REQ", + "ACT_PUB_DSE_MSR_RPRT", + "ACT_PUB_MP", + "ACT_PUB_DSE_PWR_CONSTRAINT", + "ACT_PUB_VENDOR", + "ACT_PUB_GAS_INITIAL_REQ", + "ACT_PUB_GAS_INITIAL_RSP", + "ACT_PUB_GAS_COMEBACK_REQ", + "ACT_PUB_GAS_COMEBACK_RSP", + "ACT_PUB_TDLS_DISCOVERY_RSP", + "ACT_PUB_LOCATION_TRACK", + "ACT_PUB_RSVD", +}; + +const char *action_public_str(u8 action) +{ + action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action; + return _action_public_str[action]; +} + diff --git a/rtl8192cu-fixes/core/rtw_io.c b/rtl8192cu-fixes/core/rtw_io.c new file mode 100755 index 00000000..4ffaa50d --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_io.c @@ -0,0 +1,464 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/* + +The purpose of rtw_io.c + +a. provides the API + +b. provides the protocol engine + +c. provides the software interface between caller and the hardware interface + + +Compiler Flag Option: + +1. CONFIG_SDIO_HCI: + a. USE_SYNC_IRP: Only sync operations are provided. + b. USE_ASYNC_IRP:Both sync/async operations are provided. + +2. CONFIG_USB_HCI: + a. USE_ASYNC_IRP: Both sync/async operations are provided. + +3. CONFIG_CFIO_HCI: + b. USE_SYNC_IRP: Only sync operations are provided. + + +Only sync read/rtw_write_mem operations are provided. + +jackson@realtek.com.tw + +*/ + +#define _RTW_IO_C_ +#include +#include +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) +#error "Shall be Linux or Windows, but not both!\n" +#endif + +#ifdef CONFIG_SDIO_HCI +#include +#endif + +#ifdef CONFIG_USB_HCI +#include +#endif + +#ifdef CONFIG_PCI_HCI +#include +#endif + + +u8 _rtw_read8(_adapter *adapter, u32 addr) +{ + u8 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read8 = pintfhdl->io_ops._read8; + + r_val = _read8(pintfhdl, addr); + _func_exit_; + return r_val; +} + +u16 _rtw_read16(_adapter *adapter, u32 addr) +{ + u16 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read16 = pintfhdl->io_ops._read16; + + r_val = _read16(pintfhdl, addr); + _func_exit_; + return r_val; +} + +u32 _rtw_read32(_adapter *adapter, u32 addr) +{ + u32 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read32 = pintfhdl->io_ops._read32; + + r_val = _read32(pintfhdl, addr); + _func_exit_; + return r_val; + +} + +int _rtw_write8(_adapter *adapter, u32 addr, u8 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int ret; + _func_enter_; + _write8 = pintfhdl->io_ops._write8; + + ret = _write8(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write16(_adapter *adapter, u32 addr, u16 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int ret; + _func_enter_; + _write16 = pintfhdl->io_ops._write16; + + ret = _write16(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write32(_adapter *adapter, u32 addr, u32 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int ret; + _func_enter_; + _write32 = pintfhdl->io_ops._write32; + + ret = _write32(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} + +int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf)); + int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata); + int ret; + _func_enter_; + _writeN = pintfhdl->io_ops._writeN; + + ret = _writeN(pintfhdl, addr,length,pdata); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int ret; + _func_enter_; + _write8_async = pintfhdl->io_ops._write8_async; + + ret = _write8_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int ret; + _func_enter_; + _write16_async = pintfhdl->io_ops._write16_async; + + ret = _write16_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int ret; + _func_enter_; + _write32_async = pintfhdl->io_ops._write32_async; + + ret = _write32_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE)) + { + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); + return; + } + + _read_mem = pintfhdl->io_ops._read_mem; + + _read_mem(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + _write_mem = pintfhdl->io_ops._write_mem; + + _write_mem(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE)) + { + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); + return; + } + + _read_port = pintfhdl->io_ops._read_port; + + _read_port(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_read_port_cancel(_adapter *adapter) +{ + void (*_read_port_cancel)(struct intf_hdl *pintfhdl); + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _read_port_cancel = pintfhdl->io_ops._read_port_cancel; + + if(_read_port_cancel) + _read_port_cancel(pintfhdl); + +} + +u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u32 ret = _SUCCESS; + + _func_enter_; + + _write_port = pintfhdl->io_ops._write_port; + + ret = _write_port(pintfhdl, addr, cnt, pmem); + + _func_exit_; + + return ret; +} + +u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms) +{ + int ret = _SUCCESS; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem; + struct submit_ctx sctx; + + rtw_sctx_init(&sctx, timeout_ms); + pxmitbuf->sctx = &sctx; + + ret = _rtw_write_port(adapter, addr, cnt, pmem); + + if (ret == _SUCCESS) + ret = rtw_sctx_wait(&sctx); + + return ret; +} + +void _rtw_write_port_cancel(_adapter *adapter) +{ + void (*_write_port_cancel)(struct intf_hdl *pintfhdl); + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _write_port_cancel = pintfhdl->io_ops._write_port_cancel; + + if(_write_port_cancel) + _write_port_cancel(pintfhdl); + +} + +int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops)) +{ + struct io_priv *piopriv = &padapter->iopriv; + struct intf_hdl *pintf = &piopriv->intf; + + if (set_intf_ops == NULL) + return _FAIL; + + piopriv->padapter = padapter; + pintf->padapter = padapter; + pintf->pintf_dev = adapter_to_dvobj(padapter); + + set_intf_ops(&pintf->io_ops); + + return _SUCCESS; +} + +#ifdef DBG_IO + +u16 read_sniff_ranges[][2] = { + //{0x550, 0x551}, +}; + +u16 write_sniff_ranges[][2] = { + //{0x550, 0x551}, + //{0x4c, 0x4c}, +}; + +int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2; +int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2; + +bool match_read_sniff_ranges(u16 addr, u16 len) +{ + int i; + for (i = 0; i read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1]) + return _TRUE; + } + + return _FALSE; +} + +bool match_write_sniff_ranges(u16 addr, u16 len) +{ + int i; + for (i = 0; i write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1]) + return _TRUE; + } + + return _FALSE; +} + +u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u8 val = _rtw_read8(adapter, addr); + + if (match_read_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val); + + return val; +} + +u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u16 val = _rtw_read16(adapter, addr); + + if (match_read_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val); + + return val; +} + +u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u32 val = _rtw_read32(adapter, addr); + + if (match_read_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val); + + return val; +} + +int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val); + + return _rtw_write8(adapter, addr, val); +} +int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val); + + return _rtw_write16(adapter, addr, val); +} +int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val); + + return _rtw_write32(adapter, addr, val); +} +int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, length)) + DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length); + + return _rtw_writeN(adapter, addr, length, data); +} +#endif + + diff --git a/rtl8192cu-fixes/core/rtw_ioctl_query.c b/rtl8192cu-fixes/core/rtw_ioctl_query.c new file mode 100755 index 00000000..06018867 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_ioctl_query.c @@ -0,0 +1,196 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_QUERY_C_ + +#include +#include +#include +#include +#include + + +#ifdef PLATFORM_WINDOWS +// +// Added for WPA2-PSK, by Annie, 2005-09-20. +// +u8 +query_802_11_capability( + _adapter* Adapter, + u8* pucBuf, + u32 * pulOutLen +) +{ + static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] = + { + {Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled}, + {Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled}, + {Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled}, + {Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled}, + {Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled} + }; + static ULONG ulNumOfPairSupported = sizeof(szAuthEnc)/sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION); + NDIS_802_11_CAPABILITY * pCap = (NDIS_802_11_CAPABILITY *)pucBuf; + u8* pucAuthEncryptionSupported = (u8*) pCap->AuthenticationEncryptionSupported; + + + pCap->Length = sizeof(NDIS_802_11_CAPABILITY); + if(ulNumOfPairSupported > 1 ) + pCap->Length += (ulNumOfPairSupported-1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION); + + pCap->Version = 2; + pCap->NoOfPMKIDs = NUM_PMKID_CACHE; + pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported; + + if( sizeof (szAuthEnc) <= 240 ) // 240 = 256 - 4*4 // SecurityInfo.szCapability: only 256 bytes in size. + { + _rtw_memcpy( pucAuthEncryptionSupported, (u8*)szAuthEnc, sizeof (szAuthEnc) ); + *pulOutLen = pCap->Length; + return _TRUE; + } + else + { + *pulOutLen = 0; + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("_query_802_11_capability(): szAuthEnc size is too large.\n")); + return _FALSE; + } +} + +u8 query_802_11_association_information( _adapter *padapter,PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo) +{ + struct wlan_network *tgt_network; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv *psecuritypriv=&(padapter->securitypriv); + WLAN_BSSID_EX *psecnetwork=(WLAN_BSSID_EX*)&(psecuritypriv->sec_bss); + u8 * pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + unsigned char i,*auth_ie,*supp_ie; + + //NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); + _rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); + //pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + + //------------------------------------------------------ + // Association Request related information + //------------------------------------------------------ + // Req_1. AvailableRequestFixedIEs + if(psecnetwork!=NULL){ + + pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES|NDIS_802_11_AI_REQFI_CURRENTAPADDRESS; + pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short)* & psecnetwork->IEs[10]; + _rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress, + & psecnetwork->MacAddress, 6); + + pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + + if(check_fwstate( pmlmepriv, _FW_UNDER_LINKING|_FW_LINKED)==_TRUE) + { + + if(psecuritypriv->ndisauthtype>=Ndis802_11AuthModeWPA2) + pDest[0] =48; //RSN Information Element + else + pDest[0] =221; //WPA(SSN) Information Element + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n Adapter->ndisauthtype==Ndis802_11AuthModeWPA)?0xdd:0x30 [%d]",pDest[0])); + supp_ie=&psecuritypriv->supplicant_ie[0]; + for(i=0;inetwork.IELength=%d\n\n", i,(int)psecnetwork->IELength)); + while((iRequestIELength += (2 + supp_ie[1+i]);// (2 + psecnetwork->IEs[1+i]+4); + + } + + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n psecnetwork != NULL,fwstate==_FW_UNDER_LINKING \n")); + + } + + + //------------------------------------------------------ + // Association Response related information + //------------------------------------------------------ + + if(check_fwstate( pmlmepriv, _FW_LINKED)==_TRUE) + { + tgt_network =&(pmlmepriv->cur_network); + if(tgt_network!=NULL){ + pAssocInfo->AvailableResponseFixedIEs = + NDIS_802_11_AI_RESFI_CAPABILITIES + |NDIS_802_11_AI_RESFI_ASSOCIATIONID + ; + + pAssocInfo->ResponseFixedIEs.Capabilities =(unsigned short)* & tgt_network->network.IEs[10]; + pAssocInfo->ResponseFixedIEs.StatusCode = 0; + pAssocInfo->ResponseFixedIEs.AssociationId =(unsigned short) tgt_network->aid; + + pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+pAssocInfo->RequestIELength; + auth_ie=&psecuritypriv->authenticator_ie[0]; + + for(i=0;i0){ + _rtw_memcpy((u8 *)&pDest[0],&auth_ie[1],i); + pAssocInfo->ResponseIELength =i; + } + + + pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength; + + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n tgt_network != NULL,fwstate==_FW_LINKED \n")); + } + } + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n exit query_802_11_association_information \n")); +_func_exit_; + + return _TRUE; +} +#endif + diff --git a/rtl8192cu-fixes/core/rtw_ioctl_rtl.c b/rtl8192cu-fixes/core/rtw_ioctl_rtl.c new file mode 100755 index 00000000..31b4704d --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_ioctl_rtl.c @@ -0,0 +1,1031 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_RTL_C_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MP_INCLUDED +#include +#include +#endif + +struct oid_obj_priv oid_rtl_seg_01_01[] = +{ + {1, &oid_null_function}, //0x80 + {1, &oid_null_function}, //0x81 + {1, &oid_null_function}, //0x82 + {1, &oid_null_function}, //0x83//OID_RT_SET_SNIFFER_MODE + {1, &oid_rt_get_signal_quality_hdl}, //0x84 + {1, &oid_rt_get_small_packet_crc_hdl}, //0x85 + {1, &oid_rt_get_middle_packet_crc_hdl}, //0x86 + {1, &oid_rt_get_large_packet_crc_hdl}, //0x87 + {1, &oid_rt_get_tx_retry_hdl}, //0x88 + {1, &oid_rt_get_rx_retry_hdl}, //0x89 + {1, &oid_rt_pro_set_fw_dig_state_hdl}, //0x8A + {1, &oid_rt_pro_set_fw_ra_state_hdl} , //0x8B + {1, &oid_null_function}, //0x8C + {1, &oid_null_function}, //0x8D + {1, &oid_null_function}, //0x8E + {1, &oid_null_function}, //0x8F + {1, &oid_rt_get_rx_total_packet_hdl}, //0x90 + {1, &oid_rt_get_tx_beacon_ok_hdl}, //0x91 + {1, &oid_rt_get_tx_beacon_err_hdl}, //0x92 + {1, &oid_rt_get_rx_icv_err_hdl}, //0x93 + {1, &oid_rt_set_encryption_algorithm_hdl}, //0x94 + {1, &oid_null_function}, //0x95 + {1, &oid_rt_get_preamble_mode_hdl}, //0x96 + {1, &oid_null_function}, //0x97 + {1, &oid_rt_get_ap_ip_hdl}, //0x98 + {1, &oid_rt_get_channelplan_hdl}, //0x99 + {1, &oid_rt_set_preamble_mode_hdl}, //0x9A + {1, &oid_rt_set_bcn_intvl_hdl}, //0x9B + {1, &oid_null_function}, //0x9C + {1, &oid_rt_dedicate_probe_hdl}, //0x9D + {1, &oid_null_function}, //0x9E + {1, &oid_null_function}, //0x9F + {1, &oid_null_function}, //0xA0 + {1, &oid_null_function}, //0xA1 + {1, &oid_null_function}, //0xA2 + {1, &oid_null_function}, //0xA3 + {1, &oid_null_function}, //0xA4 + {1, &oid_null_function}, //0xA5 + {1, &oid_null_function}, //0xA6 + {1, &oid_rt_get_total_tx_bytes_hdl}, //0xA7 + {1, &oid_rt_get_total_rx_bytes_hdl}, //0xA8 + {1, &oid_rt_current_tx_power_level_hdl}, //0xA9 + {1, &oid_rt_get_enc_key_mismatch_count_hdl}, //0xAA + {1, &oid_rt_get_enc_key_match_count_hdl}, //0xAB + {1, &oid_rt_get_channel_hdl}, //0xAC + {1, &oid_rt_set_channelplan_hdl}, //0xAD + {1, &oid_rt_get_hardware_radio_off_hdl}, //0xAE + {1, &oid_null_function}, //0xAF + {1, &oid_null_function}, //0xB0 + {1, &oid_null_function}, //0xB1 + {1, &oid_null_function}, //0xB2 + {1, &oid_null_function}, //0xB3 + {1, &oid_rt_get_key_mismatch_hdl}, //0xB4 + {1, &oid_null_function}, //0xB5 + {1, &oid_null_function}, //0xB6 + {1, &oid_null_function}, //0xB7 + {1, &oid_null_function}, //0xB8 + {1, &oid_null_function}, //0xB9 + {1, &oid_null_function}, //0xBA + {1, &oid_rt_supported_wireless_mode_hdl}, //0xBB + {1, &oid_rt_get_channel_list_hdl}, //0xBC + {1, &oid_rt_get_scan_in_progress_hdl}, //0xBD + {1, &oid_null_function}, //0xBE + {1, &oid_null_function}, //0xBF + {1, &oid_null_function}, //0xC0 + {1, &oid_rt_forced_data_rate_hdl}, //0xC1 + {1, &oid_rt_wireless_mode_for_scan_list_hdl}, //0xC2 + {1, &oid_rt_get_bss_wireless_mode_hdl}, //0xC3 + {1, &oid_rt_scan_with_magic_packet_hdl}, //0xC4 + {1, &oid_null_function}, //0xC5 + {1, &oid_null_function}, //0xC6 + {1, &oid_null_function}, //0xC7 + {1, &oid_null_function}, //0xC8 + {1, &oid_null_function}, //0xC9 + {1, &oid_null_function}, //0xCA + {1, &oid_null_function}, //0xCB + {1, &oid_null_function}, //0xCC + {1, &oid_null_function}, //0xCD + {1, &oid_null_function}, //0xCE + {1, &oid_null_function}, //0xCF + +}; + +struct oid_obj_priv oid_rtl_seg_01_03[] = +{ + {1, &oid_rt_ap_get_associated_station_list_hdl}, //0x00 + {1, &oid_null_function}, //0x01 + {1, &oid_rt_ap_switch_into_ap_mode_hdl}, //0x02 + {1, &oid_null_function}, //0x03 + {1, &oid_rt_ap_supported_hdl}, //0x04 + {1, &oid_rt_ap_set_passphrase_hdl}, //0x05 + +}; + +struct oid_obj_priv oid_rtl_seg_01_11[] = +{ + {1, &oid_null_function}, //0xC0 OID_RT_PRO_RX_FILTER + {1, &oid_null_function}, //0xC1 OID_CE_USB_WRITE_REGISTRY + {1, &oid_null_function}, //0xC2 OID_CE_USB_READ_REGISTRY + {1, &oid_null_function}, //0xC3 OID_RT_PRO_SET_INITIAL_GAIN + {1, &oid_null_function}, //0xC4 OID_RT_PRO_SET_BB_RF_STANDBY_MODE + {1, &oid_null_function}, //0xC5 OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE + {1, &oid_null_function}, //0xC6 OID_RT_PRO_SET_TX_CHARGE_PUMP + {1, &oid_null_function}, //0xC7 OID_RT_PRO_SET_RX_CHARGE_PUMP + {1, &oid_rt_pro_rf_write_registry_hdl}, //0xC8 + {1, &oid_rt_pro_rf_read_registry_hdl}, //0xC9 + {1, &oid_null_function} //0xCA OID_RT_PRO_QUERY_RF_TYPE + +}; + +struct oid_obj_priv oid_rtl_seg_03_00[] = +{ + {1, &oid_null_function}, //0x00 + {1, &oid_rt_get_connect_state_hdl}, //0x01 + {1, &oid_null_function}, //0x02 + {1, &oid_null_function}, //0x03 + {1, &oid_rt_set_default_key_id_hdl}, //0x04 + + +}; + + +//************** oid_rtl_seg_01_01 section start ************** + +NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + + _func_enter_; + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len >= sizeof(struct setdig_parm)) + { + //DEBUG_ERR(("===> oid_rt_pro_set_fw_dig_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); + if(!rtw_setfwdig_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf ))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_NOT_ACCEPTED; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv* poid_par_priv) +{ + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + + _func_enter_; + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + + _irqlevel_changed_(&oldirql,LOWER); + + if(poid_par_priv->information_buf_len >= sizeof(struct setra_parm)) + { + //DEBUG_ERR(("===> oid_rt_pro_set_fw_ra_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); + if(!rtw_setfwra_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf ))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_NOT_ACCEPTED; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + //DEBUG_ERR(("<**********************oid_rt_get_signal_quality_hdl \n")); + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + +#if 0 + if(pMgntInfo->mAssoc || pMgntInfo->mIbss) + { + ulInfo = pAdapter->RxStats.SignalQuality; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + ulInfo = 0xffffffff; // It stands for -1 in 4-byte integer. + } + break; +#endif + + return status; +} + +//------------------------------------------------------------------------------ + +NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_smallpacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_middlepacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_largepacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_pkts + padapter->recvpriv.rx_drop; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(u32)) + { + //_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); + *(uint *)poid_par_priv->information_buf = padapter->recvpriv.rx_icv_err; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG preamblemode = 0 ; + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + if(padapter->registrypriv.preamble == PREAMBLE_LONG) + preamblemode = 0; + else if (padapter->registrypriv.preamble == PREAMBLE_AUTO) + preamblemode = 1; + else if (padapter->registrypriv.preamble == PREAMBLE_SHORT) + preamblemode = 2; + + + *(ULONG *)poid_par_priv->information_buf = preamblemode ; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + struct eeprom_priv* peeprompriv = &padapter->eeprompriv; + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + *(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan ; + + return status; +} +NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + struct eeprom_priv* peeprompriv = &padapter->eeprompriv; + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf ; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG preamblemode = 0; + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + preamblemode = *(ULONG *)poid_par_priv->information_buf ; + if( preamblemode == 0) + padapter->registrypriv.preamble = PREAMBLE_LONG; + else if (preamblemode==1 ) + padapter->registrypriv.preamble = PREAMBLE_AUTO; + else if ( preamblemode==2 ) + padapter->registrypriv.preamble = PREAMBLE_SHORT; + + *(ULONG *)poid_par_priv->information_buf = preamblemode ; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + *(u64 *)poid_par_priv->information_buf = padapter->xmitpriv.tx_bytes; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + //_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); + *(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_bytes; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + NDIS_802_11_CONFIGURATION *pnic_Config; + + ULONG channelnum; + + _func_enter_; + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + pnic_Config = &pmlmepriv->cur_network.network.Configuration; + else + pnic_Config = &padapter->registrypriv.dev_network.Configuration; + + channelnum = pnic_Config->DSConfig; + *(ULONG *)poid_par_priv->information_buf = channelnum; + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + _func_exit_; + + + + return status; +} +NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG ulInfo = 0 ; + //DEBUG_ERR(("<**********************oid_rt_supported_wireless_mode_hdl \n")); + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len >= sizeof(ULONG)){ + ulInfo |= 0x0100; //WIRELESS_MODE_B + ulInfo |= 0x0200; //WIRELESS_MODE_G + ulInfo |= 0x0400; //WIRELESS_MODE_A + + *(ULONG *) poid_par_priv->information_buf = ulInfo; + //DEBUG_ERR(("<===oid_rt_supported_wireless_mode %x\n",ulInfo)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else{ + status = NDIS_STATUS_INVALID_LENGTH; + } + + return status; +} +NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + + +NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +//************** oid_rtl_seg_01_01 section end ************** + +//************** oid_rtl_seg_01_03 section start ************** +NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +//************** oid_rtl_seg_01_03 section end ************** + +//**************** oid_rtl_seg_01_11 section start **************** +NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + _func_enter_; + //DEBUG_ERR(("<**********************oid_rt_pro_rf_write_registry_hdl \n")); + if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3)) + { + //RegOffsetValue - The offset of RF register to write. + //RegDataWidth - The data width of RF register to write. + //RegDataValue - The value to write. + //RegOffsetValue = *((unsigned long*)InformationBuffer); + //RegDataWidth = *((unsigned long*)InformationBuffer+1); + //RegDataValue = *((unsigned long*)InformationBuffer+2); + if(!rtw_setrfreg_cmd(Adapter, + *(unsigned char*)poid_par_priv->information_buf, + (unsigned long)(*((unsigned long*)poid_par_priv->information_buf+2)))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_INVALID_LENGTH; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; + + return status; +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + _func_enter_; + + //DEBUG_ERR(("<**********************oid_rt_pro_rf_read_registry_hdl \n")); + if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3)) + { + if(Adapter->mppriv.act_in_progress == _TRUE) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + else + { + //init workparam + Adapter->mppriv.act_in_progress = _TRUE; + Adapter->mppriv.workparam.bcompleted= _FALSE; + Adapter->mppriv.workparam.act_type = MPT_READ_RF; + Adapter->mppriv.workparam.io_offset = *(unsigned long*)poid_par_priv->information_buf; + Adapter->mppriv.workparam.io_value = 0xcccccccc; + + //RegOffsetValue - The offset of RF register to read. + //RegDataWidth - The data width of RF register to read. + //RegDataValue - The value to read. + //RegOffsetValue = *((unsigned long*)InformationBuffer); + //RegDataWidth = *((unsigned long*)InformationBuffer+1); + //RegDataValue = *((unsigned long*)InformationBuffer+2); + if(!rtw_getrfreg_cmd(Adapter, + *(unsigned char*)poid_par_priv->information_buf, + (unsigned char*)&Adapter->mppriv.workparam.io_value)) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + } + + + } + else { + status = NDIS_STATUS_INVALID_LENGTH; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} + +//**************** oid_rtl_seg_01_11 section end**************** + + +//************** oid_rtl_seg_03_00 section start ************** +enum _CONNECT_STATE_{ + CHECKINGSTATUS, + ASSOCIATED, + ADHOCMODE, + NOTASSOCIATED +}; + +NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + ULONG ulInfo; + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + // nStatus==0 CheckingStatus + // nStatus==1 Associated + // nStatus==2 AdHocMode + // nStatus==3 NotAssociated + + if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + ulInfo = CHECKINGSTATUS; + else if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + ulInfo = ASSOCIATED; + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)== _TRUE) + ulInfo = ADHOCMODE; + else + ulInfo = NOTASSOCIATED ; + + *(ULONG *)poid_par_priv->information_buf = ulInfo; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +#if 0 + // Rearrange the order to let the UI still shows connection when scan is in progress + RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("===> Query OID_RT_GET_CONNECT_STATE.\n")); + if(pMgntInfo->mAssoc) + ulInfo = 1; + else if(pMgntInfo->mIbss) + ulInfo = 2; + else if(pMgntInfo->bScanInProgress) + ulInfo = 0; + else + ulInfo = 3; + ulInfoLen = sizeof(ULONG); + RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("<=== Query OID_RT_GET_CONNECT_STATE: %d\n", ulInfo)); +#endif + + return status; +} + +NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//************** oid_rtl_seg_03_00 section end ************** diff --git a/rtl8192cu-fixes/core/rtw_ioctl_set.c b/rtl8192cu-fixes/core/rtw_ioctl_set.c new file mode 100755 index 00000000..e67f2191 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_ioctl_set.c @@ -0,0 +1,1494 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_SET_C_ + + +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_HCI +#include +#include +#endif +#ifdef CONFIG_SDIO_HCI +#include +#endif + +extern void indicate_wx_scan_complete_event(_adapter *padapter); + +#define IS_MAC_ADDRESS_BROADCAST(addr) \ +( \ + ( (addr[0] == 0xff) && (addr[1] == 0xff) && \ + (addr[2] == 0xff) && (addr[3] == 0xff) && \ + (addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \ +) + +u8 rtw_validate_bssid(u8 *bssid) +{ + u8 ret = _TRUE; + + if (is_zero_mac_addr(bssid) + || is_broadcast_mac_addr(bssid) + || is_multicast_mac_addr(bssid) + ) { + ret = _FALSE; + } + + return ret; +} + +u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid) +{ + u8 i; + u8 ret=_TRUE; + +_func_enter_; + + if (ssid->SsidLength > 32) { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n")); + ret= _FALSE; + goto exit; + } + +#ifdef CONFIG_VALIDATE_SSID + for(i = 0; i < ssid->SsidLength; i++) + { + //wifi, printable ascii code must be supported + if(!( (ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e) )){ + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n")); + ret= _FALSE; + break; + } + } +#endif /* CONFIG_VALIDATE_SSID */ + +exit: + +_func_exit_; + + return ret; +} + +u8 rtw_do_join(_adapter * padapter); +u8 rtw_do_join(_adapter * padapter) +{ + _irqL irqL; + _list *plist, *phead; + u8* pibss = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + u8 ret=_SUCCESS; + +_func_enter_; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + plist = get_next(phead); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n rtw_do_join: phead = %p; plist = %p \n\n\n", phead, plist)); + + pmlmepriv->cur_network.join_res = -2; + + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + pmlmepriv->pscanned = plist; + + pmlmepriv->to_join = _TRUE; + + if(_rtw_queue_empty(queue)== _TRUE) + { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + //when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty + //we try to issue sitesurvey firstly + + if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE + || rtw_to_roaming(padapter) > 0 + ) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_do_join(): site survey if scanned_queue is empty\n.")); + // submit site_survey_cmd + if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_do_join(): site survey return error\n.")); + } + } + + goto exit; + } + else + { + int select_ret; + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS) + { + pmlmepriv->to_join = _FALSE; + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + } + else if(ret == 2)//there is no need to wait for join + { + ret = _SUCCESS; + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + rtw_indicate_connect(padapter); + } + else + { + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) + { + // submit createbss_cmd to change to a ADHOC_MASTER + + //pmlmepriv->lock has been acquired by caller... + WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network); + + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + + pibss = padapter->registrypriv.dev_network.MacAddress; + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(padapter); + + rtw_generate_random_ibss(pibss); + + if(rtw_createbss_cmd(padapter)!=_SUCCESS) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: rtw_createbss_cmd status FAIL*** \n ")); + ret = _FALSE; + goto exit; + } + + pmlmepriv->to_join = _FALSE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n ")); + + } + else + { + // can't associate ; reset under-linking + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + +#if 0 + if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) + { + if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) + { + // for funk to do roaming + // funk will reconnect, but funk will not sitesurvey before reconnect + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming")); + if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) + rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); + } + + } +#endif + + //when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue + //we try to issue sitesurvey firstly + if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE + || rtw_to_roaming(padapter) > 0 + ) + { + //DBG_871X("rtw_do_join() when no desired bss in scanning queue \n"); + if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("do_join(): site survey return error\n.")); + } + } + + + } + + } + + } + +exit: + +_func_exit_; + + return ret; +} + +#ifdef PLATFORM_WINDOWS +u8 rtw_pnp_set_power_wakeup(_adapter* padapter) +{ + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_wakeup!!!\n")); + + res = rtw_setstandby_cmd(padapter, 0); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_wakeup!!!\n")); + +_func_exit_; + + return res; +} + +u8 rtw_pnp_set_power_sleep(_adapter* padapter) +{ + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_sleep!!!\n")); + //DbgPrint("+rtw_pnp_set_power_sleep\n"); + + res = rtw_setstandby_cmd(padapter, 1); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_sleep!!!\n")); + +_func_exit_; + + return res; +} + +u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults) +{ +_func_enter_; + + switch( reloadDefaults) + { + case Ndis802_11ReloadWEPKeys: + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("SetInfo OID_802_11_RELOAD_DEFAULTS : Ndis802_11ReloadWEPKeys\n")); + break; + } + + // SecClearAllKeys(Adapter); + // 8711 CAM was not for En/Decrypt only + // so, we can't clear all keys. + // should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM + + //TO DO... + +_func_exit_; + + return _TRUE; +} + +u8 set_802_11_test(_adapter* padapter, NDIS_802_11_TEST *test) +{ + u8 ret=_TRUE; + +_func_enter_; + + switch(test->Type) + { + case 1: + NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8); + NdisMIndicateStatusComplete(padapter->hndis_adapter); + break; + + case 2: + NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI)); + NdisMIndicateStatusComplete(padapter->hndis_adapter); + break; + + default: + ret=_FALSE; + break; + } + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_pmkid(_adapter* padapter, NDIS_802_11_PMKID *pmkid) +{ + u8 ret=_SUCCESS; + + return ret; +} + +#endif + +u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) +{ + _irqL irqL; + u8 status=_SUCCESS; + u32 cur_time = 0; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, + ("+rtw_set_802_11_bssid: bssid="MAC_FMT"\n", MAC_ARG(bssid) )); + + if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || + (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) + { + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + + DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); + + if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) + { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) + goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. + } else { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) )); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) )); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); + pmlmepriv->assoc_by_bssid=_TRUE; + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("rtw_set_802_11_bssid: status=%d\n", status)); + +_func_exit_; + + return status; +} + +u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) +{ + _irqL irqL; + u8 status = _SUCCESS; + u32 cur_time = 0; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *pnetwork = &pmlmepriv->cur_network; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, + ("+rtw_set_802_11_ssid: ssid=[%s] fw_state=0x%08x\n", + ssid->Ssid, get_fwstate(pmlmepriv))); + + if(padapter->hw_init_completed==_FALSE){ + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, + ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); + + if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && + (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) + { + if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("Set SSID is the same ssid, fw_state=0x%08x\n", + get_fwstate(pmlmepriv))); + + if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE) + { + //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + else + { + goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. + } + } +#ifdef CONFIG_LPS + else { + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); + } +#endif + } + else + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + if (rtw_validate_ssid(ssid) == _FALSE) { + status = _FAIL; + goto release_mlme_lock; + } + + _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); + pmlmepriv->assoc_by_bssid=_FALSE; + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("-rtw_set_802_11_ssid: status=%d\n", status)); + +_func_exit_; + + return status; + +} + +u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid) +{ + _irqL irqL; + u8 status = _SUCCESS; + u32 cur_time = 0; + bool bssid_valid = _TRUE; + bool ssid_valid = _TRUE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if (!ssid || rtw_validate_ssid(ssid) == _FALSE) + ssid_valid = _FALSE; + + if (!bssid || rtw_validate_bssid(bssid) == _FALSE) + bssid_valid = _FALSE; + + if (ssid_valid == _FALSE && bssid_valid == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n", + FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid); + status = _FAIL; + goto exit; + } + + if(padapter->hw_init_completed==_FALSE){ + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT" fw_state=0x%08x\n", + FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + if (ssid && ssid_valid) + _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); + + if (bssid && bssid_valid) { + _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); + pmlmepriv->assoc_by_bssid = _TRUE; + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + +_func_exit_; + + return status; +} + +/* +rtw_set_802_11_infrastructure_mode(~) + ### NOTE:#### (!!!!) + MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock and scanned_queue->lock in sequence +*/ +u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter, + NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode); + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_, + ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n", + *pold_state, networktype, get_fwstate(pmlmepriv))); + + if(*pold_state != networktype) + { + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!")); + //DBG_871X("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); + + if(*pold_state==Ndis802_11APMode) + { + //change to other mode from Ndis802_11APMode + cur_network->join_res = -1; + +#ifdef CONFIG_NATIVEAP_MLME + stop_ap_mode(padapter); +#endif + } + + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS)) + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) ) + rtw_free_assoc_resources(padapter, 0); + + if((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS)) + { + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + rtw_indicate_disconnect(padapter); //will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not + } + } + + *pold_state = networktype; + + _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); + + switch(networktype) + { + case Ndis802_11IBSS: + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + break; + + case Ndis802_11Infrastructure: + set_fwstate(pmlmepriv, WIFI_STATION_STATE); + break; + + case Ndis802_11APMode: + set_fwstate(pmlmepriv, WIFI_AP_STATE); +#ifdef CONFIG_NATIVEAP_MLME + start_ap_mode(padapter); + //rtw_indicate_connect(padapter); +#endif + + break; + + case Ndis802_11AutoUnknown: + case Ndis802_11InfrastructureMax: + break; + } + + //SecClearAllKeys(adapter); + + //RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", + // get_fwstate(pmlmepriv) )); + + } + +_func_exit_; + + return _TRUE; +} + + +u8 rtw_set_802_11_disassociate(_adapter *padapter) +{ + _irqL irqL; + struct mlme_priv * pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n")); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + rtw_indicate_disconnect(padapter); + //modify for CONFIG_IEEE80211W, none 11w can use it + rtw_free_assoc_resources_cmd(padapter); + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +_func_exit_; + + return _TRUE; +} + +u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + u8 res=_TRUE; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("+rtw_set_802_11_bssid_list_scan(), fw_state=%x\n", get_fwstate(pmlmepriv))); + + if (padapter == NULL) { + res=_FALSE; + goto exit; + } + if (padapter->hw_init_completed==_FALSE){ + res = _FALSE; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n===rtw_set_802_11_bssid_list_scan:hw_init_completed==_FALSE===\n")); + goto exit; + } + + if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) || + (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) + { + // Scan or linking is in progress, do nothing. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv))); + res = _TRUE; + + if(check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))== _TRUE){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n")); + } else { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###pmlmepriv->sitesurveyctrl.traffic_busy==_TRUE\n\n")); + } + } else { + if (rtw_is_scan_deny(padapter)) { + DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter)); + indicate_wx_scan_complete_event(padapter); + return _SUCCESS; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + } +exit: + +_func_exit_; + + return res; +} + +u8 rtw_set_802_11_authentication_mode(_adapter* padapter, NDIS_802_11_AUTHENTICATION_MODE authmode) +{ + struct security_priv *psecuritypriv = &padapter->securitypriv; + int res; + u8 ret; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_auth.mode(): mode=%x\n", authmode)); + + psecuritypriv->ndisauthtype=authmode; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d", psecuritypriv->ndisauthtype)); + + if(psecuritypriv->ndisauthtype>3) + psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_8021X; + + res=rtw_set_auth(padapter,psecuritypriv); + + if(res==_SUCCESS) + ret=_TRUE; + else + ret=_FALSE; + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_add_wep(_adapter* padapter, NDIS_802_11_WEP *wep){ + + u8 bdefaultkey; + u8 btransmitkey; + sint keyid,res; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + u8 ret=_SUCCESS; + +_func_enter_; + + bdefaultkey=(wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; //for ??? + btransmitkey= (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; //for ??? + keyid=wep->KeyIndex & 0x3fffffff; + + if(keyid>4) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MgntActrtw_set_802_11_add_wep:keyid>4=>fail\n")); + ret=_FALSE; + goto exit; + } + + switch(wep->KeyLength) + { + case 5: + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=5\n")); + break; + case 13: + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=13\n")); + break; + default: + psecuritypriv->dot11PrivacyAlgrthm=_NO_PRIVACY_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n")); + break; + } + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:befor memcpy, wep->KeyLength=0x%x wep->KeyIndex=0x%x keyid =%x\n",wep->KeyLength,wep->KeyIndex,keyid)); + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial),wep->KeyLength); + + psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength; + + psecuritypriv->dot11PrivacyKeyIndex=keyid; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x \n", + psecuritypriv->dot11DefKey[keyid].skey[0],psecuritypriv->dot11DefKey[keyid].skey[1],psecuritypriv->dot11DefKey[keyid].skey[2], + psecuritypriv->dot11DefKey[keyid].skey[3],psecuritypriv->dot11DefKey[keyid].skey[4],psecuritypriv->dot11DefKey[keyid].skey[5], + psecuritypriv->dot11DefKey[keyid].skey[6],psecuritypriv->dot11DefKey[keyid].skey[7],psecuritypriv->dot11DefKey[keyid].skey[8], + psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11], + psecuritypriv->dot11DefKey[keyid].skey[12])); + + res=rtw_set_key(padapter,psecuritypriv, keyid, 1); + + if(res==_FAIL) + ret= _FALSE; +exit: + +_func_exit_; + + return ret; + +} + +u8 rtw_set_802_11_remove_wep(_adapter* padapter, u32 keyindex){ + + u8 ret=_SUCCESS; + +_func_enter_; + + if (keyindex >= 0x80000000 || padapter == NULL){ + + ret=_FALSE; + goto exit; + + } + else + { + int res; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + if( keyindex < 4 ){ + + _rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16); + + res=rtw_set_key(padapter,psecuritypriv,keyindex, 0); + + psecuritypriv->dot11DefKeylen[keyindex]=0; + + if(res==_FAIL) + ret=_FAIL; + + } + else + { + ret=_FAIL; + } + + } + +exit: + +_func_exit_; + + return ret; + +} + +u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){ + + uint encryptionalgo; + u8 * pbssid; + struct sta_info *stainfo; + u8 bgroup = _FALSE; + u8 bgrouptkey = _FALSE;//can be remove later + u8 ret=_SUCCESS; + +_func_enter_; + + if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ + + // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, + // it must fail the request and return NDIS_STATUS_INVALID_DATA. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex)); + ret= _FAIL; + goto exit; + } + + if(key->KeyIndex & 0x40000000) + { + // Pairwise key + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid); + + if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n")); + encryptionalgo=stainfo->dot118021XPrivacy; + } + else{ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n")); + encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; + } + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo )); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm)); + + if((stainfo!=NULL)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); + } + + if(key->KeyIndex & 0x000000FF){ + // The key index is specified in the lower 8 bits by values of zero to 255. + // The key index should be set to zero for a Pairwise key, and the driver should fail with + // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n")); + ret= _FAIL; + goto exit; + } + + // check BSSID + if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n")); + ret= _FALSE; + goto exit; + } + + // Check key length for TKIP. + //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) + if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); + ret=_FAIL; + goto exit; + + } + + // Check key length for AES. + if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { + // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. + if(key->KeyLength == 32) { + key->KeyLength = 16; + } else { + ret= _FAIL; + goto exit; + } + } + + // Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. + if( (encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); + ret=_FAIL; + goto exit; + } + + bgroup = _FALSE; + + // Check the pairwise key. Added by Annie, 2005-07-06. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + + } + else + { + // Group key - KeyIndex(BIT30==0) + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); + + + // when add wep key through add key and didn't assigned encryption type before + if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0)) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy)); + + switch(key->KeyLength) + { + case 5: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + case 13: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + default: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + } + + encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); + + } + else + { + encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength)); + + } + + if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n")); + ret= _FAIL; + goto exit; + } + + // Check key length for TKIP + if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); + ret= _FAIL; + goto exit; + + } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { + + // Check key length for AES + // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); + ret= _FAIL; + goto exit; + } + + // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. + if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { + key->KeyLength = 16; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) ); + } + + if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 + bgrouptkey = _TRUE; + } + + if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE)) + { + bgrouptkey = _TRUE; + } + + bgroup = _TRUE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") ); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") ); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + + } + + // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). + if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) + { + u8 ret; + u32 keyindex; + u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; + NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); + + wep->Length = len; + keyindex = key->KeyIndex&0x7fffffff; + wep->KeyIndex = keyindex ; + wep->KeyLength = key->KeyLength; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n")); + + _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); + _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); + + padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; + padapter->securitypriv.dot11PrivacyKeyIndex=keyindex; + + ret = rtw_set_802_11_add_wep(padapter, wep); + + goto exit; + + } + + if(key->KeyIndex & 0x20000000){ + // SetRSC + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n")); + if(bgroup == _TRUE) + { + NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; + _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); + } + else + { + NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; + _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); + } + + } + + // Indicate this key idx is used for TX + // Save the key in KeyMaterial + if(bgroup == _TRUE) // Group transmit key + { + int res; + + if(bgrouptkey == _TRUE) + { + padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex; + } + + if((key->KeyIndex&0x3) == 0){ + ret = _FAIL; + goto exit; + } + + _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + + if((key->KeyIndex & 0x10000000)) + { + _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); + _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); + + } + else + { + _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); + _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); + + } + + //set group key by index + _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); + + key->KeyIndex=key->KeyIndex & 0x03; + + padapter->securitypriv.binstallGrpkey=_TRUE; + + padapter->securitypriv.bcheck_grpkey=_FALSE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key")); + + res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1); + + if(res==_FAIL) + ret= _FAIL; + + goto exit; + + } + else // Pairwise Key + { + u8 res; + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); + + if(stainfo!=NULL) + { + _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer + + _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); + + if(encryptionalgo== _TKIP_) + { + padapter->securitypriv.busetkipkey=_FALSE; + + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n")); + + // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] + if((key->KeyIndex & 0x10000000)){ + _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); + _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); + + } else { + _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); + _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); + + } + + } + else if(encryptionalgo == _AES_) + { + + } + + + //Set key to CAM through H2C command + if(bgrouptkey)//never go to here + { + res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n")); + } + else{ + res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); + } + + if(res ==_FALSE) + ret= _FAIL; + + } + + } + +exit: + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_remove_key(_adapter* padapter, NDIS_802_11_REMOVE_KEY *key){ + + uint encryptionalgo; + u8 * pbssid; + struct sta_info *stainfo; + u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE: _TRUE; + u8 keyIndex = (u8)key->KeyIndex & 0x03; + u8 ret=_SUCCESS; + +_func_enter_; + + if ((key->KeyIndex & 0xbffffffc) > 0) { + ret=_FAIL; + goto exit; + } + + if (bgroup == _TRUE) { + encryptionalgo= padapter->securitypriv.dot118021XGrpPrivacy; + // clear group key by index + //NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN); + //Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0; + + _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16); + + //! \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. + + } else { + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); + if(stainfo !=NULL){ + encryptionalgo=stainfo->dot118021XPrivacy; + + // clear key by BSSID + _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16); + + //! \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. + + } + else{ + ret= _FAIL; + goto exit; + } + } + +exit: + +_func_exit_; + + return _TRUE; + +} + +/* +* rtw_get_cur_max_rate - +* @adapter: pointer to _adapter structure +* +* Return 0 or 100Kbps +*/ +u16 rtw_get_cur_max_rate(_adapter *adapter) +{ + int i = 0; + u8 *p; + u16 rate = 0, max_rate = 0; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct registry_priv *pregistrypriv = &adapter->registrypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; +#ifdef CONFIG_80211N_HT + struct rtw_ieee80211_ht_cap *pht_capie; + u8 rf_type = 0; + u8 bw_40MHz=0, short_GI_20=0, short_GI_40=0; + u16 mcs_rate=0; + u32 ht_ielen = 0; +#endif + +#ifdef CONFIG_MP_INCLUDED + if (adapter->registrypriv.mp_mode == 1) + { + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + return 0; + } +#endif + + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)) + return 0; + +#ifdef CONFIG_80211N_HT + if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) { + p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12); + if(p && ht_ielen>0) + { + 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; + //cur_bwmod is updated by beacon, pmlmeinfo is updated by association response + bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1:0; + + //short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0; + short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0; + short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0; + + rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + max_rate = rtw_mcs_rate( + rf_type, + bw_40MHz & (pregistrypriv->cbw40_enable), + short_GI_20, + short_GI_40, + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate + ); + } + } + else +#endif //CONFIG_80211N_HT + { + while( (pcur_bss->SupportedRates[i]!=0) && (pcur_bss->SupportedRates[i]!=0xFF)) + { + rate = pcur_bss->SupportedRates[i]&0x7F; + if(rate>max_rate) + max_rate = rate; + i++; + } + + max_rate = max_rate*10/2; + } + + return max_rate; +} + +/* +* rtw_set_scan_mode - +* @adapter: pointer to _adapter structure +* @scan_mode: +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode) +{ + if(scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE) + return _FAIL; + + adapter->mlmepriv.scan_mode = scan_mode; + + return _SUCCESS; +} + +/* +* rtw_set_channel_plan - +* @adapter: pointer to _adapter structure +* @channel_plan: +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) +{ + struct registry_priv *pregistrypriv = &adapter->registrypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + //handle by cmd_thread to sync with scan operation + return rtw_set_chplan_cmd(adapter, channel_plan, 1); +} + +/* +* rtw_set_country - +* @adapter: pointer to _adapter structure +* @country_code: string of country code +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_country(_adapter *adapter, const char *country_code) +{ + int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G; + + DBG_871X("%s country_code:%s\n", __func__, country_code); + + //TODO: should have a table to match country code and RT_CHANNEL_DOMAIN + //TODO: should consider 2-character and 3-character country code + if(0 == strcmp(country_code, "US")) + channel_plan = RT_CHANNEL_DOMAIN_FCC; + else if(0 == strcmp(country_code, "EU")) + channel_plan = RT_CHANNEL_DOMAIN_ETSI; + else if(0 == strcmp(country_code, "JP")) + channel_plan = RT_CHANNEL_DOMAIN_MKK; + else if(0 == strcmp(country_code, "CN")) + channel_plan = RT_CHANNEL_DOMAIN_CHINA; + else + DBG_871X("%s unknown country_code:%s\n", __FUNCTION__, country_code); + + return rtw_set_channel_plan(adapter, channel_plan); +} + +/* +* rtw_set_band - +* @adapter: pointer to _adapter structure +* @band: band to set +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_band(_adapter *adapter, enum _BAND band) +{ + if (rtw_band_valid(band)) { + DBG_871X(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band); + adapter->setband = band; + return _SUCCESS; + } + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band); + return _FAIL; +} + diff --git a/rtl8192cu-fixes/core/rtw_iol.c b/rtl8192cu-fixes/core/rtw_iol.c new file mode 100755 index 00000000..872cc423 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_iol.c @@ -0,0 +1,263 @@ +/****************************************************************************** + * + * 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 + +#ifdef CONFIG_IOL +struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) +{ + struct xmit_frame *xmit_frame; + struct xmit_buf *xmitbuf; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); + +#if 1 + if ((xmit_frame = rtw_alloc_xmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__); + goto exit; + } + + if ((xmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL) + { + DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__); + rtw_free_xmitframe(pxmitpriv, xmit_frame); + xmit_frame=NULL; + goto exit; + } + + xmit_frame->frame_tag = MGNT_FRAMETAG; + xmit_frame->pxmitbuf = xmitbuf; + xmit_frame->buf_addr = xmitbuf->pbuf; + xmitbuf->priv_data = xmit_frame; + + pattrib = &xmit_frame->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = 0x10; + pattrib->pktlen = pattrib->last_txcmdsz = 0; + +#else + if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__); + } + else { + pattrib = &xmit_frame->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = 0x10; + pattrib->pktlen = pattrib->last_txcmdsz = 0; + } +#endif + +exit: + return xmit_frame; +} + + +int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) +{ + struct pkt_attrib *pattrib = &xmit_frame->attrib; + u16 buf_offset; + u32 ori_len; + +//Todo: bulkout without this offset +#ifdef CONFIG_USB_HCI + buf_offset = TXDESC_OFFSET; +#else + buf_offset = 0; +#endif + + ori_len = buf_offset+pattrib->pktlen; + + //check if the io_buf can accommodate new cmds + if(ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) { + DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__ + , ori_len + cmd_len + 8, MAX_XMITBUF_SZ); + return _FAIL; + } + + _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len); + pattrib->pktlen += cmd_len; + pattrib->last_txcmdsz += cmd_len; + + //DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); + + return _SUCCESS; +} + +int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) +{ + IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)page_boundary); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0}; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0}; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0}; + u8* pos = (u8 *)&cmd; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +#ifdef DBG_IO +int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value); +} + +int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value); +} + +int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value); +} +#endif + +int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) +{ + IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)us); + + //DBG_871X("%s %u\n", __FUNCTION__, us); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) +{ + IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)ms); + + //DBG_871X("%s %u\n", __FUNCTION__, ms); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) +{ + struct pkt_attrib *pattrib = &xmit_frame->attrib; + u16 buf_offset; + u32 ori_len; + IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0}; + +//Todo: bulkout without this offset +#ifdef CONFIG_USB_HCI + buf_offset = TXDESC_OFFSET; +#else + buf_offset = 0; +#endif + + ori_len = buf_offset+pattrib->pktlen; + + //check if the io_buf can accommodate new cmds + if(ori_len + 8 > MAX_XMITBUF_SZ) { + DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate end cmd\n", __FUNCTION__ + , ori_len + 8, MAX_XMITBUF_SZ); + return _FAIL; + } + + _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, (u8*)&end_cmd, 8); + pattrib->pktlen += 8; + pattrib->last_txcmdsz += 8; + + //DBG_871X("%s ori:%u + 8 = %u\n", __FUNCTION__ , ori_len, buf_offset+pattrib->pktlen); + + return _SUCCESS; +} + +int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms) +{ + return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms); +} + +int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms) +{ + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(adapter)) == NULL) + return _FAIL; + + if(rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num<<3) == _FAIL) + return _FAIL; + + return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms); +} + +int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms) +{ + IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0}; + return rtw_IOL_exec_cmd_array_sync(adapter, (u8*)&end_cmd, 1, max_wating_ms); +} + +bool rtw_IOL_applied(ADAPTER *adapter) +{ + if(adapter->registrypriv.force_iol) + return _TRUE; + +#ifdef CONFIG_USB_HCI + if(!adapter_to_dvobj(adapter)->ishighspeed) + return _TRUE; +#endif + + return _FALSE; +} + +#endif //CONFIG_IOL + diff --git a/rtl8192cu-fixes/core/rtw_mlme.c b/rtl8192cu-fixes/core/rtw_mlme.c new file mode 100755 index 00000000..00edd9cc --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_mlme.c @@ -0,0 +1,3967 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MLME_C_ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void indicate_wx_scan_complete_event(_adapter *padapter); +extern u8 rtw_do_join(_adapter * padapter); + +#ifdef CONFIG_DISABLE_MCS13TO15 +extern unsigned char MCS_rate_2R_MCS13TO15_OFF[16]; +extern unsigned char MCS_rate_2R[16]; +#else //CONFIG_DISABLE_MCS13TO15 +extern unsigned char MCS_rate_2R[16]; +#endif //CONFIG_DISABLE_MCS13TO15 +extern unsigned char MCS_rate_1R[16]; + +sint _rtw_init_mlme_priv (_adapter* padapter) +{ + sint i; + u8 *pbuf; + struct wlan_network *pnetwork; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + sint res = _SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); + + pmlmepriv->nic_hdl = (u8 *)padapter; + + pmlmepriv->pscanned = NULL; + pmlmepriv->fw_state = 0; + pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown; + pmlmepriv->scan_mode=SCAN_ACTIVE;// 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) + + _rtw_spinlock_init(&(pmlmepriv->lock)); + _rtw_init_queue(&(pmlmepriv->free_bss_pool)); + _rtw_init_queue(&(pmlmepriv->scanned_queue)); + + set_scanned_network_val(pmlmepriv, 0); + + _rtw_memset(&pmlmepriv->assoc_ssid,0,sizeof(NDIS_802_11_SSID)); + + pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); + + if (pbuf == NULL){ + res=_FAIL; + goto exit; + } + pmlmepriv->free_bss_buf = pbuf; + + pnetwork = (struct wlan_network *)pbuf; + + for(i = 0; i < MAX_BSS_CNT; i++) + { + _rtw_init_listhead(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue)); + + pnetwork++; + } + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + + rtw_clear_scan_deny(padapter); + + rtw_init_mlme_timer(padapter); + +exit: + +_func_exit_; + + return res; +} + +void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv); +void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv) +{ + _rtw_spinlock_free(&pmlmepriv->lock); + _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock)); + _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock)); +} + +static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) +{ + if(*ppie) + { + rtw_mfree(*ppie, *plen); + *plen = 0; + *ppie=NULL; + } +} + +void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) +{ +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); + rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); + + rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); +#endif + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) + rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); +#endif + +} + +void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv) +{ +_func_enter_; + + rtw_free_mlme_priv_ie_data(pmlmepriv); + + if(pmlmepriv){ + rtw_mfree_mlme_priv_lock (pmlmepriv); + + if (pmlmepriv->free_bss_buf) { + rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network)); + } + } +_func_exit_; +} + +sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork) +{ + _irqL irqL; + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_insert_tail(&pnetwork->list, &queue->queue); + + _exit_critical_bh(&queue->lock, &irqL); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +struct wlan_network *_rtw_dequeue_network(_queue *queue) +{ + _irqL irqL; + + struct wlan_network *pnetwork; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (_rtw_queue_empty(queue) == _TRUE) + + pnetwork = NULL; + + else + { + pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list); + + rtw_list_delete(&(pnetwork->list)); + } + + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; + + return pnetwork; +} + +struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv )//(_queue *free_queue) +{ + _irqL irqL; + struct wlan_network *pnetwork; + _queue *free_queue = &pmlmepriv->free_bss_pool; + _list* plist = NULL; + +_func_enter_; + + _enter_critical_bh(&free_queue->lock, &irqL); + + if (_rtw_queue_empty(free_queue) == _TRUE) { + pnetwork=NULL; + goto exit; + } + plist = get_next(&(free_queue->queue)); + + pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list); + + rtw_list_delete(&pnetwork->list); + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist)); + pnetwork->network_type = 0; + pnetwork->fixed = _FALSE; + pnetwork->last_scanned = rtw_get_current_time(); + pnetwork->aid=0; + pnetwork->join_res=0; + + pmlmepriv->num_of_scanned ++; + +exit: + _exit_critical_bh(&free_queue->lock, &irqL); + +_func_exit_; + + return pnetwork; +} + +void _rtw_free_network(struct mlme_priv *pmlmepriv ,struct wlan_network *pnetwork, u8 isfreeall) +{ + u32 curr_time, delta_time; + u32 lifetime = SCANQUEUE_LIFETIME; + _irqL irqL; + _queue *free_queue = &(pmlmepriv->free_bss_pool); + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + if (pnetwork->fixed == _TRUE) + goto exit; + + curr_time = rtw_get_current_time(); + + if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) ) + lifetime = 1; + + if(!isfreeall) + { +#ifdef PLATFORM_WINDOWS + + delta_time = (curr_time -pnetwork->last_scanned)/10; + + if(delta_time < lifetime*1000000)// unit:usec + { + goto exit; + } + +#endif + +#ifdef PLATFORM_LINUX + + delta_time = (curr_time -pnetwork->last_scanned)/HZ; + + if(delta_time < lifetime)// unit:sec + { + goto exit; + } + +#endif + +#ifdef PLATFORM_FREEBSD + //i think needs to check again + delta_time = (curr_time -pnetwork->last_scanned)/hz; + + if(delta_time < lifetime)// unit:sec + { + goto exit; + } + +#endif + } + + _enter_critical_bh(&free_queue->lock, &irqL); + + rtw_list_delete(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list),&(free_queue->queue)); + + pmlmepriv->num_of_scanned --; + + + //DBG_871X("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid); + + _exit_critical_bh(&free_queue->lock, &irqL); + +exit: + +_func_exit_; + +} + +void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) +{ + + _queue *free_queue = &(pmlmepriv->free_bss_pool); + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + if (pnetwork->fixed == _TRUE) + goto exit; + + //_enter_critical(&free_queue->lock, &irqL); + + rtw_list_delete(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue)); + + pmlmepriv->num_of_scanned --; + + //_exit_critical(&free_queue->lock, &irqL); + +exit: + +_func_exit_; + +} + + +/* + return the wlan_network with the matching addr + + Shall be calle under atomic context... to avoid possible racing condition... +*/ +struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr) +{ + + //_irqL irqL; + _list *phead, *plist; + struct wlan_network *pnetwork = NULL; + u8 zero_addr[ETH_ALEN] = {0,0,0,0,0,0}; + +_func_enter_; + + if(_rtw_memcmp(zero_addr, addr, ETH_ALEN)){ + pnetwork=NULL; + goto exit; + } + + //_enter_critical_bh(&scanned_queue->lock, &irqL); + + phead = get_list_head(scanned_queue); + plist = get_next(phead); + + while (plist != phead) + { + pnetwork = LIST_CONTAINOR(plist, struct wlan_network ,list); + + if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) + break; + + plist = get_next(plist); + } + + if(plist == phead) + pnetwork = NULL; + + //_exit_critical_bh(&scanned_queue->lock, &irqL); + +exit: + +_func_exit_; + + return pnetwork; + +} + + +void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall) +{ + _irqL irqL; + _list *phead, *plist; + struct wlan_network *pnetwork; + struct mlme_priv* pmlmepriv = &padapter->mlmepriv; + _queue *scanned_queue = &pmlmepriv->scanned_queue; + +_func_enter_; + + + _enter_critical_bh(&scanned_queue->lock, &irqL); + + phead = get_list_head(scanned_queue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + plist = get_next(plist); + + _rtw_free_network(pmlmepriv,pnetwork, isfreeall); + + } + + _exit_critical_bh(&scanned_queue->lock, &irqL); + +_func_exit_; + +} + + + + +sint rtw_if_up(_adapter *padapter) { + + sint res; +_func_enter_; + + if( padapter->bDriverStopped || padapter->bSurpriseRemoved || + (check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _FALSE)){ + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + res=_FALSE; + } + else + res= _TRUE; + +_func_exit_; + return res; +} + + +void rtw_generate_random_ibss(u8* pibss) +{ + u32 curtime = rtw_get_current_time(); + +_func_enter_; + pibss[0] = 0x02; //in ad-hoc mode bit1 must set to 1 + pibss[1] = 0x11; + pibss[2] = 0x87; + pibss[3] = (u8)(curtime & 0xff) ;//p[0]; + pibss[4] = (u8)((curtime>>8) & 0xff) ;//p[1]; + pibss[5] = (u8)((curtime>>16) & 0xff) ;//p[2]; +_func_exit_; + return; +} + +u8 *rtw_get_capability_from_ie(u8 *ie) +{ + return (ie + 8 + 2); +} + + +u16 rtw_get_capability(WLAN_BSSID_EX *bss) +{ + u16 val; +_func_enter_; + + _rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2); + +_func_exit_; + return le16_to_cpu(val); +} + +u8 *rtw_get_timestampe_from_ie(u8 *ie) +{ + return (ie + 0); +} + +u8 *rtw_get_beacon_interval_from_ie(u8 *ie) +{ + return (ie + 8); +} + + +int rtw_init_mlme_priv (_adapter *padapter)//(struct mlme_priv *pmlmepriv) +{ + int res; +_func_enter_; + res = _rtw_init_mlme_priv(padapter);// (pmlmepriv); +_func_exit_; + return res; +} + +void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_mlme_priv\n")); + _rtw_free_mlme_priv (pmlmepriv); +_func_exit_; +} + +int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); +int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork) +{ + int res; +_func_enter_; + res = _rtw_enqueue_network(queue, pnetwork); +_func_exit_; + return res; +} + + +#ifndef PLATFORM_FREEBSD //Baron +static struct wlan_network *rtw_dequeue_network(_queue *queue) +{ + struct wlan_network *pnetwork; +_func_enter_; + pnetwork = _rtw_dequeue_network(queue); +_func_exit_; + return pnetwork; +} +#endif //PLATFORM_FREEBSD + +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv ); +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv )//(_queue *free_queue) +{ + struct wlan_network *pnetwork; +_func_enter_; + pnetwork = _rtw_alloc_network(pmlmepriv); +_func_exit_; + return pnetwork; +} + +void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall); +void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall)//(struct wlan_network *pnetwork, _queue *free_queue) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid)); + _rtw_free_network(pmlmepriv, pnetwork, is_freeall); +_func_exit_; +} + +void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork ); +void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork ) +{ +_func_enter_; + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid)); + _rtw_free_network_nolock(pmlmepriv, pnetwork); +_func_exit_; +} + + +void rtw_free_network_queue(_adapter* dev, u8 isfreeall) +{ +_func_enter_; + _rtw_free_network_queue(dev, isfreeall); +_func_exit_; +} + +/* + return the wlan_network with the matching addr + + Shall be calle under atomic context... to avoid possible racing condition... +*/ +struct wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr) +{ + struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr); + + return pnetwork; +} + +int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork) +{ + int ret=_TRUE; + struct security_priv *psecuritypriv = &adapter->securitypriv; + + if ( (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) && + ( pnetwork->network.Privacy == 0 ) ) + { + ret=_FALSE; + } + else if((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ ) && + ( pnetwork->network.Privacy == 1 ) ) + { + ret=_FALSE; + } + else + { + ret=_TRUE; + } + + return ret; + +} + +inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b); +inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b) +{ + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(%s,%d)(%s,%d)\n", + // a->Ssid.Ssid,a->Ssid.SsidLength,b->Ssid.Ssid,b->Ssid.SsidLength)); + return (a->Ssid.SsidLength == b->Ssid.SsidLength) + && _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength)==_TRUE; +} + +int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst) +{ + u16 s_cap, d_cap; + +_func_enter_; + +#ifdef PLATFORM_OS_XP + if ( ((uint)dst) <= 0x7fffffff || + ((uint)src) <= 0x7fffffff || + ((uint)&s_cap) <= 0x7fffffff || + ((uint)&d_cap) <= 0x7fffffff) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n@@@@ error address of dst\n")); + + KeBugCheckEx(0x87110000, (ULONG_PTR)dst, (ULONG_PTR)src,(ULONG_PTR)&s_cap, (ULONG_PTR)&d_cap); + + return _FALSE; + } +#endif + + + _rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2); + _rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2); + + + s_cap = le16_to_cpu(s_cap); + d_cap = le16_to_cpu(d_cap); + +_func_exit_; + + return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && + // (src->Configuration.DSConfig == dst->Configuration.DSConfig) && + ( (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) && + ( (_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) && + ((s_cap & WLAN_CAPABILITY_IBSS) == + (d_cap & WLAN_CAPABILITY_IBSS)) && + ((s_cap & WLAN_CAPABILITY_BSS) == + (d_cap & WLAN_CAPABILITY_BSS))); + +} + +struct wlan_network * rtw_get_oldest_wlan_network(_queue *scanned_queue) +{ + _list *plist, *phead; + + + struct wlan_network *pwlan = NULL; + struct wlan_network *oldest = NULL; +_func_enter_; + phead = get_list_head(scanned_queue); + + plist = get_next(phead); + + while(1) + { + + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pwlan= LIST_CONTAINOR(plist, struct wlan_network, list); + + if(pwlan->fixed!=_TRUE) + { + if (oldest == NULL ||time_after(oldest->last_scanned, pwlan->last_scanned)) + oldest = pwlan; + } + + plist = get_next(plist); + } +_func_exit_; + return oldest; + +} + +static void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, + _adapter * padapter, bool update_ie) +{ + u8 ss_ori = dst->PhyInfo.SignalStrength; + u8 sq_ori = dst->PhyInfo.SignalQuality; + long rssi_ori = dst->Rssi; + + u8 ss_smp = src->PhyInfo.SignalStrength; + u8 sq_smp = src->PhyInfo.SignalQuality; + long rssi_smp = src->Rssi; + + u8 ss_final; + u8 sq_final; + long rssi_final; + +_func_enter_; + +#ifdef CONFIG_ANTENNA_DIVERSITY + rtw_hal_antdiv_rssi_compared(padapter, dst, src); //this will update src.Rssi, need consider again +#endif + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1 + if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n" + , FUNC_ADPT_ARG(padapter) + , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig + ,ss_ori, sq_ori, rssi_ori + ,ss_smp, sq_smp, rssi_smp + ); + } + #endif + + /* The rule below is 1/5 for sample value, 4/5 for history value */ + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { + /* Take the recvpriv's value for the connected AP*/ + ss_final = padapter->recvpriv.signal_strength; + sq_final = padapter->recvpriv.signal_qual; + /* the rssi value here is undecorated, and will be used for antenna diversity */ + if(sq_smp != 101) /* from the right channel */ + rssi_final = (src->Rssi+dst->Rssi*4)/5; + else + rssi_final = rssi_ori; + } + else { + if(sq_smp != 101) { /* from the right channel */ + ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5; + sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5; + rssi_final = (src->Rssi+dst->Rssi*4)/5; + } else { + /* bss info not receving from the right channel, use the original RX signal infos */ + ss_final = dst->PhyInfo.SignalStrength; + sq_final = dst->PhyInfo.SignalQuality; + rssi_final = dst->Rssi; + } + + } + + if (update_ie) + _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src)); + + dst->PhyInfo.SignalStrength = ss_final; + dst->PhyInfo.SignalQuality = sq_final; + dst->Rssi = rssi_final; + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1 + if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n" + , FUNC_ADPT_ARG(padapter) + , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi); + } + #endif + +#if 0 // old codes, may be useful one day... +// DBG_871X("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi); + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) + { + + //DBG_871X("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal); + if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) + { + padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index]; + padapter->recvpriv.signal_qual_data.total_val -= last_evm; + } + padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi); + + padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi); + if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX) + padapter->recvpriv.signal_qual_data.index = 0; + + //DBG_871X("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi); + + // <1> Showed on UI for user,in percentage. + tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num; + padapter->recvpriv.signal=(u8)tmpVal;//Link quality + + src->Rssi= translate_percentage_to_dbm(padapter->recvpriv.signal) ; + } + else{ +// DBG_871X("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi); + src->Rssi=(src->Rssi +dst->Rssi)/2;//dBM + } + +// DBG_871X("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal); + +#endif + +_func_exit_; +} + +static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +_func_enter_; + +#ifdef PLATFORM_OS_XP + if ((unsigned long)(&(pmlmepriv->cur_network.network)) < 0x7ffffff) + { + KeBugCheckEx(0x87111c1c, (ULONG_PTR)(&(pmlmepriv->cur_network.network)), 0, 0,0); + } +#endif + + if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork))) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n"); + + //if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) + { + update_network(&(pmlmepriv->cur_network.network), pnetwork,adapter, _TRUE); + rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), + pmlmepriv->cur_network.network.IELength); + } + } + +_func_exit_; + +} + + +/* + +Caller must hold pmlmepriv->lock first. + + +*/ +void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target) +{ + _irqL irqL; + _list *plist, *phead; + ULONG bssid_ex_sz; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + struct wlan_network *oldest = NULL; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + if ((unsigned long)(pnetwork) < 0x7ffffff) + { +#ifdef PLATFORM_OS_XP + KeBugCheckEx(0x87111c1c, (ULONG_PTR)pnetwork, 0, 0,0); +#endif + } + + if (is_same_network(&(pnetwork->network), target)) + break; + + if ((oldest == ((struct wlan_network *)0)) || + time_after(oldest->last_scanned, pnetwork->last_scanned)) + oldest = pnetwork; + + plist = get_next(plist); + + } + + + /* If we didn't find a match, then get a new network slot to initialize + * with this beacon's information */ + if (rtw_end_of_queue_search(phead,plist)== _TRUE) { + + if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) { + /* If there are no more slots, expire the oldest */ + //list_del_init(&oldest->list); + pnetwork = oldest; + +#ifdef CONFIG_ANTENNA_DIVERSITY + //target->PhyInfo.Optimum_antenna = pHalData->CurAntenna;//optimum_antenna=>For antenna diversity + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna)); +#endif + _rtw_memcpy(&(pnetwork->network), target, get_WLAN_BSSID_EX_sz(target)); + //pnetwork->last_scanned = rtw_get_current_time(); + // variable initialize + pnetwork->fixed = _FALSE; + pnetwork->last_scanned = rtw_get_current_time(); + + pnetwork->network_type = 0; + pnetwork->aid=0; + pnetwork->join_res=0; + + /* bss info not receving from the right channel */ + if (pnetwork->network.PhyInfo.SignalQuality == 101) + pnetwork->network.PhyInfo.SignalQuality = 0; + } + else { + /* Otherwise just pull from the free list */ + + pnetwork = rtw_alloc_network(pmlmepriv); // will update scan_time + + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n")); + goto exit; + } + + bssid_ex_sz = get_WLAN_BSSID_EX_sz(target); + target->Length = bssid_ex_sz; +#ifdef CONFIG_ANTENNA_DIVERSITY + //target->PhyInfo.Optimum_antenna = pHalData->CurAntenna; + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna)); +#endif + _rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz ); + + pnetwork->last_scanned = rtw_get_current_time(); + + /* bss info not receving from the right channel */ + if (pnetwork->network.PhyInfo.SignalQuality == 101) + pnetwork->network.PhyInfo.SignalQuality = 0; + + rtw_list_insert_tail(&(pnetwork->list),&(queue->queue)); + + } + } + else { + /* we have an entry and we are going to update it. But this entry may + * be already expired. In this case we do the same as we found a new + * net and call the new_net handler + */ + bool update_ie = _TRUE; + + pnetwork->last_scanned = rtw_get_current_time(); + + //target.Reserved[0]==1, means that scaned network is a bcn frame. + if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1)) + update_ie = _FALSE; + + update_network(&(pnetwork->network), target,adapter, update_ie); + } + +exit: + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; +} + +void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork); +void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &(((_adapter *)adapter)->mlmepriv); + //_queue *queue = &(pmlmepriv->scanned_queue); + +_func_enter_; + + //_enter_critical_bh(&queue->lock, &irqL); + + #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO) + rtw_WLAN_BSSID_EX_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); + #endif + + update_current_network(adapter, pnetwork); + + rtw_update_scanned_network(adapter, pnetwork); + + //_exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; +} + +//select the desired network based on the capability of the (i)bss. +// check items: (1) security +// (2) network_type +// (3) WMM +// (4) HT +// (5) others +int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork); +int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u32 desired_encmode; + u32 privacy; + + //u8 wps_ie[512]; + uint wps_ielen; + + int bselected = _TRUE; + + desired_encmode = psecuritypriv->ndisencryptstatus; + privacy = pnetwork->network.Privacy; + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + if(rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!=NULL) + { + return _TRUE; + } + else + { + return _FALSE; + } + } + if (adapter->registrypriv.wifi_spec == 1) //for correct flow of 8021X to do.... + { + u8 *p=NULL; + uint ie_len=0; + + if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) + bselected = _FALSE; + + if ( psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { + p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_)); + if (p && ie_len>0) { + bselected = _TRUE; + } else { + bselected = _FALSE; + } + } + } + + + if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) { + DBG_871X("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy); + bselected = _FALSE; + } + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) + bselected = _FALSE; + } + + + return bselected; +} + +/* TODO: Perry : For Power Management */ +void rtw_atimdone_event_callback(_adapter *adapter , u8 *pbuf) +{ + +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n")); +_func_exit_; + return; +} + + +void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + u32 len; + WLAN_BSSID_EX *pnetwork; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +_func_enter_; + + pnetwork = (WLAN_BSSID_EX *)pbuf; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_callback, ssid=%s\n", pnetwork->Ssid.Ssid)); + +#ifdef CONFIG_RTL8712 + //endian_convert + pnetwork->Length = le32_to_cpu(pnetwork->Length); + pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); + pnetwork->Privacy =le32_to_cpu( pnetwork->Privacy); + pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); + pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse); + pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow); + pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod); + pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig); + pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); + pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); + pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); + pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length); + pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length); + pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode); + pnetwork->IELength = le32_to_cpu(pnetwork->IELength); +#endif + + len = get_WLAN_BSSID_EX_sz(pnetwork); + if(len > (sizeof(WLAN_BSSID_EX))) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n ****rtw_survey_event_callback: return a wrong bss ***\n")); + return; + } + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + // update IBSS_network 's timestamp + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"rtw_survey_event_callback : WIFI_ADHOC_MASTER_STATE \n\n"); + if(_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) + { + struct wlan_network* ibss_wlan = NULL; + _irqL irqL; + + _rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8); + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress); + if(ibss_wlan) + { + _rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto exit; + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + } + } + + // lock pmlmepriv->lock when you accessing network_q + if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE) + { + if( pnetwork->Ssid.Ssid[0] == 0 ) + { + pnetwork->Ssid.SsidLength = 0; + } + rtw_add_network(adapter, pnetwork); + } + +exit: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +_func_exit_; + + return; +} + + + +void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + u8 timer_cancelled = _FALSE; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +#ifdef CONFIG_MLME_EXT + + mlmeext_surveydone_event_callback(adapter); + +#endif + +_func_enter_; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if(pmlmepriv->wps_probe_req_ie) + { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv))); + + if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY)) + { + //u8 timer_cancelled; + + timer_cancelled = _TRUE; + //_cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + } + else { + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("nic status =%x, survey done event comes too late!\n", get_fwstate(pmlmepriv))); + } + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + if(timer_cancelled) + _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&adapter->recvpriv); + #endif + + if(pmlmepriv->to_join == _TRUE) + { + if((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) ) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)==_FALSE) + { + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS) + { + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT ); + } + else + { + WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network); + u8 *pibss = adapter->registrypriv.dev_network.MacAddress; + + //pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;//because don't set assoc_timer + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("switching to adhoc master\n")); + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(adapter); + rtw_generate_random_ibss(pibss); + + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + + if(rtw_createbss_cmd(adapter)!=_SUCCESS) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error=>rtw_createbss_cmd status FAIL\n")); + } + + pmlmepriv->to_join = _FALSE; + } + } + } + else + { + int s_ret; + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + pmlmepriv->to_join = _FALSE; + if(_SUCCESS == (s_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))) + { + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + } + else if(s_ret == 2)//there is no need to wait for join + { + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + rtw_indicate_connect(adapter); + } + else + { + DBG_871X("try_to_join, but select scanning queue fail, to_roaming:%d\n", rtw_to_roaming(adapter)); + #ifdef CONFIG_LAYER2_ROAMING + if (rtw_to_roaming(adapter) != 0) { + if( --pmlmepriv->to_roaming == 0 + || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0) + ) { + rtw_set_roaming(adapter, 0); +#ifdef CONFIG_INTEL_WIDI + if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + rtw_free_assoc_resources(adapter, 1); + rtw_indicate_disconnect(adapter); + } else { + pmlmepriv->to_join = _TRUE; + } + } + #endif + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + } + } + } + + indicate_wx_scan_complete_event(adapter); + //DBG_871X("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time)); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +#ifdef CONFIG_P2P_PS + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0); + } +#endif // CONFIG_P2P_PS + + rtw_os_xmit_schedule(adapter); +#ifdef CONFIG_CONCURRENT_MODE + rtw_os_xmit_schedule(adapter->pbuddy_adapter); +#endif +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_resume_xmit(adapter); +#endif + +#ifdef CONFIG_DRVEXT_MODULE_WSC + drvext_surveydone_callback(&adapter->drvextpriv); +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT +#ifdef CONFIG_INTEL_WIDI + if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_NONE) +#endif + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + if(pmlmeext->sitesurvey_res.bss_cnt == 0){ + rtw_hal_sreset_reset(adapter); + } + } +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_surveydone_event_callback(adapter); +#endif //CONFIG_IOCTL_CFG80211 + +_func_exit_; + +} + +void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf) +{ + +} + +void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf) +{ + +} + +static void free_scanqueue(struct mlme_priv *pmlmepriv) +{ + _irqL irqL, irqL0; + _queue *free_queue = &pmlmepriv->free_bss_pool; + _queue *scan_queue = &pmlmepriv->scanned_queue; + _list *plist, *phead, *ptemp; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n")); + _enter_critical_bh(&scan_queue->lock, &irqL0); + _enter_critical_bh(&free_queue->lock, &irqL); + + phead = get_list_head(scan_queue); + plist = get_next(phead); + + while (plist != phead) + { + ptemp = get_next(plist); + rtw_list_delete(plist); + rtw_list_insert_tail(plist, &free_queue->queue); + plist =ptemp; + pmlmepriv->num_of_scanned --; + } + + _exit_critical_bh(&free_queue->lock, &irqL); + _exit_critical_bh(&scan_queue->lock, &irqL0); + +_func_exit_; +} + +/* +*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock +*/ +void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue) +{ + _irqL irqL; + struct wlan_network* pwlan = NULL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct sta_priv *pstapriv = &adapter->stapriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#endif //CONFIG_TDLS +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress="MAC_FMT" ssid=%s\n", + MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid)); + + if(check_fwstate( pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) + { + struct sta_info* psta; + + psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress); + +#ifdef CONFIG_TDLS + if(ptdlsinfo->setup_state != TDLS_STATE_NONE) + { + 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); + } + else +#endif //CONFIG_TDLS + { + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + } + + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + } + + if(check_fwstate( pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) + { + struct sta_info* psta; + + rtw_free_all_stainfo(adapter); + + psta = rtw_get_bcmc_stainfo(adapter); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + rtw_init_bcmc_stainfo(adapter); + } + + if(lock_scanned_queue) + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + if(pwlan) + { + pwlan->fixed = _FALSE; +#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); + } +#endif //CONFIG_P2P + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_assoc_resources : pwlan== NULL \n\n")); + } + + + if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count== 1)) + /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/) + { + rtw_free_network_nolock(pmlmepriv, pwlan); + } + + if(lock_scanned_queue) + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + adapter->securitypriv.key_mask = 0; + +_func_exit_; + +} + +/* +*rtw_indicate_connect: the caller has to lock pmlmepriv->lock +*/ +void rtw_indicate_connect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n")); + + pmlmepriv->to_join = _FALSE; + + if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_LINK, 0); +#endif + set_fwstate(pmlmepriv, _FW_LINKED); + + rtw_led_control(padapter, LED_CTL_LINK); + +#ifdef CONFIG_DRVEXT_MODULE + if(padapter->drvextpriv.enable_wpa) + { + indicate_l2_connect(padapter); + } + else +#endif + { + rtw_os_indicate_connect(padapter); + } + + } + + rtw_set_roaming(padapter, 0); + +#ifdef CONFIG_INTEL_WIDI + if(padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + + rtw_set_scan_deny(padapter, 3000); + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv))); + +_func_exit_; + +} + + +/* +*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock +*/ +void rtw_indicate_disconnect( _adapter *padapter ) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n")); + + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS); + + if(rtw_to_roaming(padapter) > 0) + _clr_fwstate_(pmlmepriv, _FW_LINKED); + + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED) + || (rtw_to_roaming(padapter) <= 0) + ) + { + rtw_os_indicate_disconnect(padapter); + + //set ips_deny_time to avoid enter IPS before LPS leave + padapter->pwrctrlpriv.ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(3000); + + _clr_fwstate_(pmlmepriv, _FW_LINKED); + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + rtw_clear_scan_deny(padapter); + + } + +#ifdef CONFIG_P2P_PS + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); +#endif // CONFIG_P2P_PS + +#ifdef CONFIG_LPS +#ifdef CONFIG_WOWLAN + if(padapter->pwrctrlpriv.wowlan_mode==_FALSE) +#endif //CONFIG_WOWLAN + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1); + +#endif + +_func_exit_; +} + +inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted) +{ + rtw_os_indicate_scan_done(padapter, aborted); +} + +void rtw_scan_abort(_adapter *adapter) +{ + u32 cnt=0; + u32 start; + 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) { + + if (adapter->bDriverStopped || adapter->bSurpriseRemoved) + break; + + DBG_871X(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); + rtw_msleep_os(20); + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved) + DBG_871X(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev)); + #ifdef CONFIG_PLATFORM_MSTAR + //_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + set_survey_timer(pmlmeext, 0); + _set_timer(&pmlmepriv->scan_to_timer, 50); + #endif + rtw_indicate_scan_done(adapter, _TRUE); + } + pmlmeext->scan_abort = _FALSE; +} + +static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork) +{ + int i; + struct sta_info *bmc_sta, *psta=NULL; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress); + if(psta==NULL) { + psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress); + } + + if(psta) //update ptarget_sta + { + DBG_871X("%s\n", __FUNCTION__); + + psta->aid = pnetwork->join_res; +#ifdef CONFIG_CONCURRENT_MODE + + if(PRIMARY_ADAPTER == padapter->adapter_type) + psta->mac_id=0; + else + psta->mac_id=2; +#else + psta->mac_id=0; +#endif + + psta->raid = networktype_to_raid(pmlmeext->cur_wireless_mode); + + //security related + if(padapter->securitypriv.dot11AuthAlgrthm== dot11AuthAlgrthm_8021X) + { + padapter->securitypriv.binstallGrpkey=_FALSE; + padapter->securitypriv.busetkipkey=_FALSE; + padapter->securitypriv.bgrpkey_handshake=_FALSE; + + psta->ieee8021x_blocked=_TRUE; + psta->dot118021XPrivacy=padapter->securitypriv.dot11PrivacyAlgrthm; + + _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype)); + + _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype)); + + _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48)); +#ifdef CONFIG_IEEE80211W + _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof (union pn48)); +#endif //CONFIG_IEEE80211W + _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48)); + } + + // Commented by Albert 2012/07/21 + // When doing the WPS, the wps_ie_len won't equal to 0 + // And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. + if ( padapter->securitypriv.wps_ie_len != 0 ) + { + psta->ieee8021x_blocked=_TRUE; + padapter->securitypriv.wps_ie_len = 0; + } + + + //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info + //if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff + //todo: check if AP can send A-MPDU packets + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &psta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + + + bmc_sta = rtw_get_bcmc_stainfo(padapter); + if(bmc_sta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + } + + + //misc. + update_sta_info(padapter, psta); + + } + + return psta; + +} + +//pnetwork : returns from rtw_joinbss_event_callback +//ptarget_wlan: found from scanned_queue +static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + + DBG_871X("%s\n", __FUNCTION__); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\nfw_state:%x, BSSID:"MAC_FMT"\n" + ,get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress))); + + + // why not use ptarget_wlan?? + _rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length); + + cur_network->aid = pnetwork->join_res; + + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength; + padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality; + //the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) + padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength); + #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1 + DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u" + "\n" + , FUNC_ADPT_ARG(padapter) + , padapter->recvpriv.signal_strength + , padapter->recvpriv.rssi + , padapter->recvpriv.signal_qual + ); + #endif +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + + //update fw_state //will clr _FW_UNDER_LINKING here indirectly + switch(pnetwork->network.InfrastructureMode) + { + case Ndis802_11Infrastructure: + + if(pmlmepriv->fw_state&WIFI_UNDER_WPS) + pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS; + else + pmlmepriv->fw_state = WIFI_STATION_STATE; + + break; + case Ndis802_11IBSS: + pmlmepriv->fw_state = WIFI_ADHOC_STATE; + break; + default: + pmlmepriv->fw_state = WIFI_NULL_STATE; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Invalid network_mode\n")); + break; + } + + rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), + (cur_network->network.IELength)); + +#ifdef CONFIG_80211N_HT + rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig); +#endif + + +} + +//Notes: the fucntion could be > passive_level (the same context as Rx tasklet) +//pnetwork : returns from rtw_joinbss_event_callback +//ptarget_wlan: found from scanned_queue +//if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. +//if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. +//if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL). +// +//#define REJOIN +void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL,irqL2; + static u8 retry=0; + u8 timer_cancelled; + struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct wlan_network *pnetwork = (struct wlan_network *)pbuf; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; + unsigned int the_same_macaddr = _FALSE; + +_func_enter_; + +#ifdef CONFIG_RTL8712 + //endian_convert + pnetwork->join_res = le32_to_cpu(pnetwork->join_res); + pnetwork->network_type = le32_to_cpu(pnetwork->network_type); + pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); + pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength); + pnetwork->network.Privacy =le32_to_cpu( pnetwork->network.Privacy); + pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); + pnetwork->network.NetworkTypeInUse =le32_to_cpu(pnetwork->network.NetworkTypeInUse) ; + pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); + pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); + pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig); + pnetwork->network.Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime); + pnetwork->network.Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern); + pnetwork->network.Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); + pnetwork->network.Configuration.FHConfig.Length=le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); + pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length); + pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode); + pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength ); +#endif + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("joinbss event call back received with res=%d\n", pnetwork->join_res)); + + rtw_get_encrypt_decrypt_from_registrypriv(adapter); + + + if (pmlmepriv->assoc_ssid.SsidLength == 0) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@ joinbss event call back for Any SSid\n")); + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + } + + the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); + + pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network); + if(pnetwork->network.Length > sizeof(WLAN_BSSID_EX)) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n")); + goto ignore_joinbss_callback; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_joinbss_event_callback !! _enter_critical \n")); + + if(pnetwork->join_res > 0) + { + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + retry = 0; + if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING) ) + { + //s1. find ptarget_wlan + if(check_fwstate(pmlmepriv, _FW_LINKED) ) + { + if(the_same_macaddr == _TRUE) + { + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + } + else + { + pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + if(pcur_wlan) pcur_wlan->fixed = _FALSE; + + pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(pcur_sta){ + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + rtw_free_stainfo(adapter, pcur_sta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + } + + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){ + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + } + } + + } + else + { + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){ + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + } + } + + //s2. update cur_network + if(ptarget_wlan) + { + rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't find ptarget_wlan when joinbss_event callback\n")); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + + + //s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); + if(ptarget_sta==NULL) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't update stainfo when joinbss_event callback\n")); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + } + + //s4. indicate connect + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + rtw_indicate_connect(adapter); + } + else + { + //adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv))); + } + + + //s5. Cancle assoc_timer + _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("Cancle assoc_timer\n")); + + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv))); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + } + else if(pnetwork->join_res == -4) + { + rtw_reset_securitypriv(adapter); + _set_timer(&pmlmepriv->assoc_timer, 1); + + //rtw_free_assoc_resources(adapter, 1); + + if((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv))); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + } + + } + else //if join_res < 0 (join fails), then try again + { + + #ifdef REJOIN + res = _FAIL; + if(retry < 2) { + res = rtw_select_and_join_from_scanned_queue(pmlmepriv); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_select_and_join_from_scanned_queue again! res:%d\n",res)); + } + + if(res == _SUCCESS) + { + //extend time of assoc_timer + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + retry++; + } + else if(res == 2)//there is no need to wait for join + { + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + rtw_indicate_connect(adapter); + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Set Assoc_Timer = 1; can't find match ssid in scanned_q \n")); + #endif + + _set_timer(&pmlmepriv->assoc_timer, 1); + //rtw_free_assoc_resources(adapter, 1); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + #ifdef REJOIN + retry = 0; + } + #endif + } + +ignore_joinbss_callback: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + _func_exit_; +} + +void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf) +{ + struct wlan_network *pnetwork = (struct wlan_network *)pbuf; + +_func_enter_; + + mlmeext_joinbss_event_callback(adapter, pnetwork->join_res); + + rtw_os_xmit_schedule(adapter); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_os_xmit_schedule(adapter->pbuddy_adapter); +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_resume_xmit(adapter); +#endif + +_func_exit_; +} + +void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + struct sta_info *psta; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct stassoc_event *pstassoc = (struct stassoc_event*)pbuf; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *ptarget_wlan = NULL; + +_func_enter_; + + if(rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE) + return; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); + if(psta) + { +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef COMPAT_KERNEL_RELEASE + +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + u8 *passoc_req = NULL; + u32 assoc_req_len; + + _enter_critical_bh(&psta->lock, &irqL); + if(psta->passoc_req && psta->assoc_req_len>0) + { + passoc_req = rtw_zmalloc(psta->assoc_req_len); + if(passoc_req) + { + assoc_req_len = psta->assoc_req_len; + _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); + + rtw_mfree(psta->passoc_req , psta->assoc_req_len); + psta->passoc_req = NULL; + psta->assoc_req_len = 0; + } + } + _exit_critical_bh(&psta->lock, &irqL); + + if(passoc_req && assoc_req_len>0) + { + rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len); + + rtw_mfree(passoc_req, assoc_req_len); + } +#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) +#endif //CONFIG_IOCTL_CFG80211 + + //bss_cap_update_on_sta_join(adapter, psta); + //sta_info_update(adapter, psta); + ap_sta_info_defer_update(adapter, psta); + } + + goto exit; + } +#endif + + psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); + if( psta != NULL) + { + //the sta have been in sta_info_queue => do nothing + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue \n")); + + goto exit; //(between drv has received this event before and fw have not yet to set key to CAM_ENTRY) + } + + psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); + if (psta == NULL) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't alloc sta_info when rtw_stassoc_event_callback\n")); + goto exit; + } + + //to do : init sta_info variable + psta->qos_option = 0; + psta->mac_id = (uint)pstassoc->cam_id; + //psta->aid = (uint)pstassoc->cam_id; + + if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X) + psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm; + + psta->ieee8021x_blocked = _FALSE; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) ) + { + if(adapter->stapriv.asoc_sta_count== 2) + { + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + // a sta + bc/mc_stainfo (not Ibss_stainfo) + rtw_indicate_connect(adapter); + } + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + + mlmeext_sta_add_event_callback(adapter, psta); + +#ifdef CONFIG_RTL8711 + //submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta + rtw_setstakey_cmd(adapter, (unsigned char*)psta, _FALSE); +#endif + +exit: + +_func_exit_; + +} + +void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL,irqL2; + struct sta_info *psta; + struct wlan_network* pwlan = NULL; + WLAN_BSSID_EX *pdev_network=NULL; + u8* pibss = NULL; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct stadel_event *pstadel = (struct stadel_event*)pbuf; + struct sta_priv *pstapriv = &adapter->stapriv; + struct wlan_network *tgt_network = &(pmlmepriv->cur_network); + +_func_enter_; + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef COMPAT_KERNEL_RELEASE + +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16*)pstadel->rsvd); +#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) +#endif //CONFIG_IOCTL_CFG80211 + + return; + } + + + mlmeext_sta_del_event_callback(adapter); + + _enter_critical_bh(&pmlmepriv->lock, &irqL2); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) ) + { + #ifdef CONFIG_LAYER2_ROAMING + if (rtw_to_roaming(adapter) > 0) + pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */ + else if (rtw_to_roaming(adapter) == 0) + rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times); +#ifdef CONFIG_INTEL_WIDI + if(adapter->mlmepriv.widi_state != INTEL_WIDI_STATE_CONNECTED) +#endif // CONFIG_INTEL_WIDI + if(*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK) + rtw_set_roaming(adapter, 0); /* don't roam */ + #endif + + rtw_free_uc_swdec_pending_queue(adapter); + + rtw_free_assoc_resources(adapter, 1); + rtw_indicate_disconnect(adapter); + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + // remove the network entry in scanned_queue + pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + if (pwlan) { + pwlan->fixed = _FALSE; + rtw_free_network_nolock(pmlmepriv, pwlan); + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + _rtw_roaming(adapter, tgt_network); + +#ifdef CONFIG_INTEL_WIDI + if (!rtw_to_roaming(adapter)) + process_intel_widi_disconnect(adapter, 1); +#endif // CONFIG_INTEL_WIDI + } + + if ( check_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE) || + check_fwstate(pmlmepriv,WIFI_ADHOC_STATE)) + { + psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); + + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo) + { + //rtw_indicate_disconnect(adapter);//removed@20091105 + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + //free old ibss network + //pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); + pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + if(pwlan) + { + pwlan->fixed = _FALSE; + rtw_free_network_nolock(pmlmepriv, pwlan); + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + //re-create ibss + pdev_network = &(adapter->registrypriv.dev_network); + pibss = adapter->registrypriv.dev_network.MacAddress; + + _rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network)); + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(adapter); + + rtw_generate_random_ibss(pibss); + + if(check_fwstate(pmlmepriv,WIFI_ADHOC_STATE)) + { + set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); + } + + if(rtw_createbss_cmd(adapter)!=_SUCCESS) + { + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL*** \n ")); + + } + + + } + + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL2); + +_func_exit_; + +} + + +void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf) +{ +#ifdef CONFIG_LPS_LCLK + struct reportpwrstate_parm *preportpwrstate; +#endif + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_cpwm_event_callback !!!\n")); +#ifdef CONFIG_LPS_LCLK + preportpwrstate = (struct reportpwrstate_parm*)pbuf; + preportpwrstate->state |= (u8)(padapter->pwrctrlpriv.cpwm_tog + 0x80); + cpwm_int_hdl(padapter, preportpwrstate); +#endif + +_func_exit_; + +} + +/* +* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss +* @adapter: pointer to _adapter structure +*/ +void _rtw_join_timeout_handler (_adapter *adapter) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; +#ifdef CONFIG_LAYER2_ROAMING + int do_join_r; +#endif //CONFIG_LAYER2_ROAMING + +#if 0 + if (adapter->bDriverStopped == _TRUE){ + _rtw_up_sema(&pmlmepriv->assoc_terminate); + return; + } +#endif + +_func_enter_; +#ifdef PLATFORM_FREEBSD + rtw_mtx_lock(NULL); + if (callout_pending(&adapter->mlmepriv.assoc_timer.callout)) { + /* callout was reset */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + if (!callout_active(&adapter->mlmepriv.assoc_timer.callout)) { + /* callout was stopped */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + callout_deactivate(&adapter->mlmepriv.assoc_timer.callout); + + +#endif + + DBG_871X("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv)); + + if(adapter->bDriverStopped ||adapter->bSurpriseRemoved) + return; + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + #ifdef CONFIG_LAYER2_ROAMING + if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */ + while(1) { + pmlmepriv->to_roaming--; + if (rtw_to_roaming(adapter) != 0) { /* try another */ + DBG_871X("%s try another roaming\n", __FUNCTION__); + if( _SUCCESS!=(do_join_r=rtw_do_join(adapter)) ) { + DBG_871X("%s roaming do_join return %d\n", __FUNCTION__ ,do_join_r); + continue; + } + break; + } else { +#ifdef CONFIG_INTEL_WIDI + if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + DBG_871X("%s We've try roaming but fail\n", __FUNCTION__); + rtw_indicate_disconnect(adapter); + break; + } + } + + } else + #endif + { + rtw_indicate_disconnect(adapter); + free_scanqueue(pmlmepriv);//??? + +#ifdef CONFIG_IOCTL_CFG80211 + //indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED + rtw_cfg80211_indicate_disconnect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + +#ifdef CONFIG_DRVEXT_MODULE_WSC + drvext_assoc_fail_indicate(&adapter->drvextpriv); +#endif +#ifdef PLATFORM_FREEBSD + rtw_mtx_unlock(NULL); +#endif + +_func_exit_; + +} + +/* +* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey +* @adapter: pointer to _adapter structure +*/ +void rtw_scan_timeout_handler (_adapter *adapter) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + DBG_871X(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + rtw_indicate_scan_done(adapter, _TRUE); + +} + +static void rtw_auto_scan_handler(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + + //auto site survey per 60sec + if(pmlmepriv->scan_interval >0) + { + pmlmepriv->scan_interval--; + if(pmlmepriv->scan_interval==0) + { +/* + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_871X("exit %s when _FW_UNDER_SURVEY|_FW_UNDER_LINKING -> \n", __FUNCTION__); + return; + } + + if(pmlmepriv->sitesurveyctrl.traffic_busy == _TRUE) + { + DBG_871X("%s exit cause traffic_busy(%x)\n",__FUNCTION__, pmlmepriv->sitesurveyctrl.traffic_busy); + return; + } +*/ + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + { + if ((check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) || + (padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)) + { + DBG_871X("%s, but buddy_intf is under scanning or linking or BusyTraffic\n", __FUNCTION__); + return; + } + } +#endif + + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); + + pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec + + } + + } + +} + +void rtw_dynamic_check_timer_handlder(_adapter *adapter) +{ +#ifdef CONFIG_AP_MODE + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; +#endif //CONFIG_AP_MODE + struct registry_priv *pregistrypriv = &adapter->registrypriv; +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = adapter->pbuddy_adapter; +#endif + + if(!adapter) + return; + + if(adapter->hw_init_completed == _FALSE) + return; + + if ((adapter->bDriverStopped == _TRUE)||(adapter->bSurpriseRemoved== _TRUE)) + return; + + +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter) + { + if(adapter->net_closed == _TRUE && pbuddy_adapter->net_closed == _TRUE) + { + return; + } + } + else +#endif //CONFIG_CONCURRENT_MODE + if(adapter->net_closed == _TRUE) + { + return; + } + + rtw_dynamic_chk_wk_cmd(adapter); + + if(pregistrypriv->wifi_spec==1) + { +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) +#endif + { + //auto site survey + rtw_auto_scan_handler(adapter); + } + } + +#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + expire_timeout_chk(adapter); + } +#endif +#endif //!CONFIG_ACTIVE_KEEP_ALIVE_CHECK + +#ifdef CONFIG_BR_EXT + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if( adapter->pnetdev->br_port +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if( rcu_dereference(adapter->pnetdev->rx_handler_data) +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) + { + // expire NAT2.5 entry + void nat25_db_expire(_adapter *priv); + nat25_db_expire(adapter); + + if (adapter->pppoe_connection_in_progress > 0) { + adapter->pppoe_connection_in_progress--; + } + + // due to rtw_dynamic_check_timer_handlder() is called every 2 seconds + if (adapter->pppoe_connection_in_progress > 0) { + adapter->pppoe_connection_in_progress--; + } + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + +#endif // CONFIG_BR_EXT + +} + + +#ifdef CONFIG_SET_SCAN_DENY_TIMER +inline bool rtw_is_scan_deny(_adapter *adapter) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; + return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE; +} + +inline void rtw_clear_scan_deny(_adapter *adapter) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; + ATOMIC_SET(&mlmepriv->set_scan_deny, 0); + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter)); +} + +void rtw_set_scan_deny_timer_hdl(_adapter *adapter) +{ + rtw_clear_scan_deny(adapter); +} + +void rtw_set_scan_deny(_adapter *adapter, u32 ms) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; +#ifdef CONFIG_CONCURRENT_MODE + struct mlme_priv *b_mlmepriv; +#endif + + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter)); + ATOMIC_SET(&mlmepriv->set_scan_deny, 1); + _set_timer(&mlmepriv->set_scan_deny_timer, ms); + +#ifdef CONFIG_CONCURRENT_MODE + if (!adapter->pbuddy_adapter) + return; + + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter)); + b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv; + ATOMIC_SET(&b_mlmepriv->set_scan_deny, 1); + _set_timer(&b_mlmepriv->set_scan_deny_timer, ms); +#endif + +} +#endif + +#if defined(IEEE80211_SCAN_RESULT_EXPIRE) +#define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 //3000 -1000 +#else +#define RTW_SCAN_RESULT_EXPIRE 2000 +#endif + +#ifndef PLATFORM_FREEBSD +/* +* Select a new join candidate from the original @param candidate and @param competitor +* @return _TRUE: candidate is updated +* @return _FALSE: candidate is not updated +*/ +static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv + , struct wlan_network **candidate, struct wlan_network *competitor) +{ + int updated = _FALSE; + _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv); + + + //check bssid, if needed + if(pmlmepriv->assoc_by_bssid==_TRUE) { + if(_rtw_memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN) ==_FALSE) + goto exit; + } + + //check ssid, if needed + if(pmlmepriv->assoc_ssid.Ssid && pmlmepriv->assoc_ssid.SsidLength) { + if( competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength + || _rtw_memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength) == _FALSE + ) + goto exit; + } + + if(rtw_is_desired_network(adapter, competitor) == _FALSE) + goto exit; + +#ifdef CONFIG_LAYER2_ROAMING + if(rtw_to_roaming(adapter) > 0) { + if( rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE + || is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == _FALSE + ) + goto exit; + } +#endif + + if(*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) + { + *candidate = competitor; + updated = _TRUE; + } + +#if 0 + if(pmlmepriv->assoc_by_bssid==_TRUE) { // associate with bssid + if( (*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) + && _rtw_memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)==_TRUE + ) { + *candidate = competitor; + updated = _TRUE; + } + } else if (pmlmepriv->assoc_ssid.SsidLength == 0 ) { // associate with ssid, but ssidlength is 0 + if( (*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) ) { + *candidate = competitor; + updated = _TRUE; + } + } else +#ifdef CONFIG_LAYER2_ROAMING + if(rtw_to_roaming(adapter)) { // roaming + if( (*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) + && is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) + //&&(!is_same_network(&competitor->network, &pmlmepriv->cur_network.network)) + && rtw_get_passing_time_ms((u32)competitor->last_scanned) < RTW_SCAN_RESULT_EXPIRE + && rtw_is_desired_network(adapter, competitor) + ) { + *candidate = competitor; + updated = _TRUE; + } + + } else +#endif + { // associate with ssid + if( (*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) + && (competitor->network.Ssid.SsidLength==pmlmepriv->assoc_ssid.SsidLength) + &&((_rtw_memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) == _TRUE) + && rtw_is_desired_network(adapter, competitor) + ) { + *candidate = competitor; + updated = _TRUE; + } + } +#endif + + if(updated){ + DBG_871X("[by_bssid:%u][assoc_ssid:%s]" + #ifdef CONFIG_LAYER2_ROAMING + "[to_roaming:%u] " + #endif + "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n", + pmlmepriv->assoc_by_bssid, + pmlmepriv->assoc_ssid.Ssid, + #ifdef CONFIG_LAYER2_ROAMING + rtw_to_roaming(adapter), + #endif + (*candidate)->network.Ssid.Ssid, + MAC_ARG((*candidate)->network.MacAddress), + (*candidate)->network.Configuration.DSConfig, + (int)(*candidate)->network.Rssi + ); + } + +exit: + return updated; +} + +/* +Calling context: +The caller of the sub-routine will be in critical section... + +The caller must hold the following spinlock + +pmlmepriv->lock + + +*/ + +int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv ) +{ + _irqL irqL; + int ret; + _list *phead; + _adapter *adapter; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + struct wlan_network *candidate = NULL; + u8 bSupportAntDiv = _FALSE; + +_func_enter_; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + adapter = (_adapter *)pmlmepriv->nic_hdl; + + pmlmepriv->pscanned = get_next( phead ); + + while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) { + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__)); + ret = _FAIL; + goto exit; + } + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + #if 0 + DBG_871X("MacAddress:"MAC_FMT" ssid:%s\n", MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Ssid.Ssid); + #endif + + rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); + + } + + if(candidate == NULL) { + DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__); + ret = _FAIL; + goto exit; + } else { + DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__, + candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress), + candidate->network.Configuration.DSConfig); + } + + + // check for situation of _FW_LINKED + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + DBG_871X("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__); + + #if 0 // for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... + if(is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) + { + DBG_871X("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__); + + rtw_indicate_connect(adapter);//rtw_indicate_connect again + + ret = 2; + goto exit; + } + else + #endif + { + rtw_disassoc_cmd(adapter, 0, _TRUE); + rtw_indicate_disconnect(adapter); + rtw_free_assoc_resources(adapter, 0); + } + } + + #ifdef CONFIG_ANTENNA_DIVERSITY + rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv)); + if(_TRUE == bSupportAntDiv) + { + u8 CurrentAntenna; + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna)); + DBG_871X("#### Opt_Ant_(%s) , cur_Ant(%s)\n", + (2==candidate->network.PhyInfo.Optimum_antenna)?"A":"B", + (2==CurrentAntenna)?"A":"B" + ); + } + #endif + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + ret = rtw_joinbss_cmd(adapter, candidate); + +exit: + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +_func_exit_; + + return ret; +} +#else +int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv ) +{ + _irqL irqL; + _list *phead; +#ifdef CONFIG_ANTENNA_DIVERSITY + u8 CurrentAntenna; +#endif + unsigned char *dst_ssid, *src_ssid; + _adapter *adapter; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + struct wlan_network *pnetwork_max_rssi = NULL; + #ifdef CONFIG_LAYER2_ROAMING + struct wlan_network * roaming_candidate=NULL; + u32 cur_time=rtw_get_current_time(); + #endif + +_func_enter_; + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + adapter = (_adapter *)pmlmepriv->nic_hdl; + + pmlmepriv->pscanned = get_next( phead ); + + while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) { + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(2)rtw_select_and_join_from_scanned_queue return _FAIL:(pnetwork==NULL)\n")); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return _FAIL; + } + + dst_ssid = pnetwork->network.Ssid.Ssid; + src_ssid = pmlmepriv->assoc_ssid.Ssid; + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + #if 0 + DBG_871X("MacAddress:"MAC_FMT" ssid:%s\n", MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Ssid.Ssid); + #endif + + if(pmlmepriv->assoc_by_bssid==_TRUE) + { + if(_rtw_memcmp(pnetwork->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)==_TRUE) + { + //remove the condition @ 20081125 + //if((pmlmepriv->cur_network.network.InfrastructureMode==Ndis802_11AutoUnknown)|| + // pmlmepriv->cur_network.network.InfrastructureMode == pnetwork->network.InfrastructureMode) + // goto ask_for_joinbss; + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) + { + //DBG_871X("select_and_join(1): _FW_LINKED and is same network, it needn't join again\n"); + + rtw_indicate_connect(adapter);//rtw_indicate_connect again + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return 2; + } + else + { + rtw_disassoc_cmd(adapter, 0, _TRUE); + rtw_indicate_disconnect(adapter); + rtw_free_assoc_resources(adapter, 0); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ask_for_joinbss; + + } + } + else + { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ask_for_joinbss; + } + + } + + } else if (pmlmepriv->assoc_ssid.SsidLength == 0) { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ask_for_joinbss;//anyway, join first selected(dequeued) pnetwork if ssid_len=0 + + #ifdef CONFIG_LAYER2_ROAMING + } else if (rtw_to_roaming(adapter) > 0) { + + if( (roaming_candidate == NULL ||roaming_candidate->network.Rssinetwork.Rssi ) + && is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network) + //&&(!is_same_network(&pnetwork->network, &pmlmepriv->cur_network.network)) + && rtw_get_time_interval_ms((u32)pnetwork->last_scanned,cur_time) < 5000 + ) { + roaming_candidate = pnetwork; + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_, + DBG_871X + ("roaming_candidate???: %s("MAC_FMT")\n", + roaming_candidate->network.Ssid.Ssid, MAC_ARG(roaming_candidate->network.MacAddress) ) + //) + ; + } + continue; + #endif + + } else if ( (pnetwork->network.Ssid.SsidLength==pmlmepriv->assoc_ssid.SsidLength) + &&((_rtw_memcmp(dst_ssid, src_ssid, pmlmepriv->assoc_ssid.SsidLength)) == _TRUE) + ) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("dst_ssid=%s, src_ssid=%s \n", dst_ssid, src_ssid)); +#ifdef CONFIG_ANTENNA_DIVERSITY + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna)); + DBG_871X("#### dst_ssid=(%s) Opt_Ant_(%s) , cur_Ant(%s)\n", dst_ssid, + (2==pnetwork->network.PhyInfo.Optimum_antenna)?"A":"B", + (2==CurrentAntenna)?"A":"B"); +#endif + //remove the condition @ 20081125 + //if((pmlmepriv->cur_network.network.InfrastructureMode==Ndis802_11AutoUnknown)|| + // pmlmepriv->cur_network.network.InfrastructureMode == pnetwork->network.InfrastructureMode) + //{ + // _rtw_memcpy(pmlmepriv->assoc_bssid, pnetwork->network.MacAddress, ETH_ALEN); + // goto ask_for_joinbss; + //} + + if(pmlmepriv->assoc_by_rssi==_TRUE)//if the ssid is the same, select the bss which has the max rssi + { + if( NULL==pnetwork_max_rssi|| pnetwork->network.Rssi > pnetwork_max_rssi->network.Rssi) + pnetwork_max_rssi = pnetwork; + } + else if(rtw_is_desired_network(adapter, pnetwork) == _TRUE) + { + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { +#if 0 + if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) + { + DBG_871X("select_and_join(2): _FW_LINKED and is same network, it needn't join again\n"); + + rtw_indicate_connect(adapter);//rtw_indicate_connect again + + return 2; + } + else +#endif + { + rtw_disassoc_cmd(adapter, 0, _TRUE); + //rtw_indicate_disconnect(adapter);// + rtw_free_assoc_resources(adapter, 0); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ask_for_joinbss; + } + } + else + { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ask_for_joinbss; + } + + } + + + } + + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + #ifdef CONFIG_LAYER2_ROAMING + if(rtw_to_roaming(adapter) > 0 && roaming_candidate ){ + pnetwork=roaming_candidate; + DBG_871X("select_and_join_from_scanned_queue: roaming_candidate: %s("MAC_FMT")\n", + pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress)); + goto ask_for_joinbss; + } + #endif + + if((pmlmepriv->assoc_by_rssi==_TRUE) && (pnetwork_max_rssi!=NULL)) + { + pnetwork = pnetwork_max_rssi; + DBG_871X("select_and_join_from_scanned_queue: pnetwork_max_rssi: %s("MAC_FMT")\n", + pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress)); + goto ask_for_joinbss; + } + + DBG_871X("(1)rtw_select_and_join_from_scanned_queue return _FAIL\n"); + +_func_exit_; + + return _FAIL; + +ask_for_joinbss: + +_func_exit_; + + return rtw_joinbss_cmd(adapter, pnetwork); + +} +#endif //PLATFORM_FREEBSD + + +sint rtw_set_auth(_adapter * adapter,struct security_priv *psecuritypriv) +{ + struct cmd_obj* pcmd; + struct setauth_parm *psetauthparm; + struct cmd_priv *pcmdpriv=&(adapter->cmdpriv); + sint res=_SUCCESS; + +_func_enter_; + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; //try again + goto exit; + } + + psetauthparm=(struct setauth_parm*)rtw_zmalloc(sizeof(struct setauth_parm)); + if(psetauthparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm)); + psetauthparm->mode=(unsigned char)psecuritypriv->dot11AuthAlgrthm; + + pcmd->cmdcode = _SetAuth_CMD_; + pcmd->parmbuf = (unsigned char *)psetauthparm; + pcmd->cmdsz = (sizeof(struct setauth_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("after enqueue set_auth_cmd, auth_mode=%x\n", psecuritypriv->dot11AuthAlgrthm)); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; + +} + + +sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx) +{ + u8 keylen; + struct cmd_obj *pcmd; + struct setkey_parm *psetkeyparm; + struct cmd_priv *pcmdpriv = &(adapter->cmdpriv); + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + sint res=_SUCCESS; + +_func_enter_; + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; //try again + goto exit; + } + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm)); + + if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){ + psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n", psetkeyparm->algorithm)); + } + else{ + psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n", psetkeyparm->algorithm)); + + } + psetkeyparm->keyid = (u8)keyid;//0~3 + psetkeyparm->set_tx = set_tx; + if (is_wep_enc(psetkeyparm->algorithm)) + psecuritypriv->key_mask |= BIT(psetkeyparm->keyid); + + DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid, psecuritypriv->key_mask); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid)); + + switch(psetkeyparm->algorithm){ + + case _WEP40_: + keylen=5; + _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + break; + case _WEP104_: + keylen=13; + _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + break; + case _TKIP_: + keylen=16; + _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); + psetkeyparm->grpkey=1; + break; + case _AES_: + keylen=16; + _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); + psetkeyparm->grpkey=1; + break; + default: + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",psecuritypriv->dot11PrivacyAlgrthm)); + res= _FAIL; + goto exit; + } + + + pcmd->cmdcode = _SetKey_CMD_; + pcmd->parmbuf = (u8 *)psetkeyparm; + pcmd->cmdsz = (sizeof(struct setkey_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + //_rtw_init_sema(&(pcmd->cmd_sem), 0); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: +_func_exit_; + return res; + +} + + +//adjust IEs for rtw_joinbss_cmd in WMM +int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len) +{ + unsigned int ielength=0; + unsigned int i, j; + + i = 12; //after the fixed IE + while(i=0 :if there is pre-auth key, and return the entry id +// +// + +static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid) +{ + struct security_priv *psecuritypriv=&Adapter->securitypriv; + int i=0; + + do + { + if( ( psecuritypriv->PMKIDList[i].bUsed ) && + ( _rtw_memcmp( psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN ) == _TRUE ) ) + { + break; + } + else + { + i++; + //continue; + } + + }while(isecuritypriv; + + 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 + + } + return (ie_len); + +} +sint rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie, u8 *out_ie, uint in_len) +{ + u8 authmode, securitytype, match; + u8 sec_ie[255], uncst_oui[4], bkup_ie[255]; + u8 wpa_oui[4]={0x0, 0x50, 0xf2, 0x01}; + uint ielength, cnt, remove_cnt; + int iEntry; + + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct security_priv *psecuritypriv=&adapter->securitypriv; + uint ndisauthmode=psecuritypriv->ndisauthtype; + uint ndissecuritytype = psecuritypriv->ndisencryptstatus; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n", + ndisauthmode, ndissecuritytype)); + + //copy fixed ie only + _rtw_memcpy(out_ie, in_ie,12); + ielength=12; + if((ndisauthmode==Ndis802_11AuthModeWPA)||(ndisauthmode==Ndis802_11AuthModeWPAPSK)) + authmode=_WPA_IE_ID_; + if((ndisauthmode==Ndis802_11AuthModeWPA2)||(ndisauthmode==Ndis802_11AuthModeWPA2PSK)) + authmode=_WPA2_IE_ID_; + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + _rtw_memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); + + ielength += psecuritypriv->wps_ie_len; + } + else if((authmode==_WPA_IE_ID_)||(authmode==_WPA2_IE_ID_)) + { + //copy RSN or SSN + _rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2); + /* debug for CONFIG_IEEE80211W + { + int jj; + printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2); + for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++) + printk(" %02x ", psecuritypriv->supplicant_ie[jj]); + printk("\n"); + }*/ + ielength+=psecuritypriv->supplicant_ie[1]+2; + rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); + +#ifdef CONFIG_DRVEXT_MODULE + drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie); +#endif + } + + iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); + if(iEntry<0) + { + return ielength; + } + else + { + if(authmode == _WPA2_IE_ID_) + { + ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength); + } + } + +_func_exit_; + + return ielength; +} + +void rtw_init_registrypriv_dev_network( _adapter* adapter) +{ + struct registry_priv* pregistrypriv = &adapter->registrypriv; + struct eeprom_priv* peepriv = &adapter->eeprompriv; + WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network; + u8 *myhwaddr = myid(peepriv); + +_func_enter_; + + _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); + + _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID)); + + pdev_network->Configuration.Length=sizeof(NDIS_802_11_CONFIGURATION); + pdev_network->Configuration.BeaconPeriod = 100; + pdev_network->Configuration.FHConfig.Length = 0; + pdev_network->Configuration.FHConfig.HopPattern = 0; + pdev_network->Configuration.FHConfig.HopSet = 0; + pdev_network->Configuration.FHConfig.DwellTime = 0; + + +_func_exit_; + +} + +void rtw_update_registrypriv_dev_network(_adapter* adapter) +{ + int sz=0; + struct registry_priv* pregistrypriv = &adapter->registrypriv; + WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network; + struct security_priv* psecuritypriv = &adapter->securitypriv; + struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; + //struct xmit_priv *pxmitpriv = &adapter->xmitpriv; + +_func_enter_; + +#if 0 + pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; + pxmitpriv->vcs = pregistrypriv->vcs_type; + pxmitpriv->vcs_type = pregistrypriv->vcs_type; + //pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; + pxmitpriv->frag_len = pregistrypriv->frag_thresh; + + adapter->qospriv.qos_option = pregistrypriv->wmm_enable; +#endif + + pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; // adhoc no 802.1x + + pdev_network->Rssi = 0; + + switch(pregistrypriv->wireless_mode) + { + case WIRELESS_11B: + pdev_network->NetworkTypeInUse = (Ndis802_11DS); + break; + case WIRELESS_11G: + case WIRELESS_11BG: + case WIRELESS_11_24N: + case WIRELESS_11G_24N: + case WIRELESS_11BG_24N: + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); + break; + case WIRELESS_11A: + case WIRELESS_11A_5N: + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5); + break; + case WIRELESS_11ABGN: + if(pregistrypriv->channel > 14) + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5); + else + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); + break; + default : + // TODO + break; + } + + pdev_network->Configuration.DSConfig = (pregistrypriv->channel); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig)); + + if(cur_network->network.InfrastructureMode == Ndis802_11IBSS) + pdev_network->Configuration.ATIMWindow = (0); + + pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode); + + // 1. Supported rates + // 2. IE + + //rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; // will be called in rtw_generate_ie + sz = rtw_generate_ie(pregistrypriv); + + pdev_network->IELength = sz; + + pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pdev_network); + + //notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); + //pdev_network->IELength = cpu_to_le32(sz); + +_func_exit_; + +} + +void rtw_get_encrypt_decrypt_from_registrypriv(_adapter* adapter) +{ +_func_enter_; + + +_func_exit_; + +} + +//the fucntion is at passive_level +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 + + pmlmepriv->num_FortyMHzIntolerant = 0; + + pmlmepriv->num_sta_no_ht = 0; + + phtpriv->ampdu_enable = _FALSE;//reset to disabled + +#ifdef CONFIG_USB_HCI + // TH=1 => means that invalidate usb rx aggregation + // TH=0 => means that validate usb rx aggregation, use init value. + if(phtpriv->ht_option) + { + if(padapter->registrypriv.wifi_spec==1) + threshold = 1; + else + threshold = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } + else + { + threshold = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } +#endif + +#endif + +} + + +#ifdef CONFIG_80211N_HT + +//the fucntion is >= passive_level +unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel) +{ + u32 ielen, out_len; + unsigned char *p, *pframe; + struct rtw_ieee80211_ht_cap ht_capie; + unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + u8 cbw40_enable = 0; + + phtpriv->ht_option = _FALSE; + + p = rtw_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12); + + if(p && ielen>0) + { + if(pqospriv->qos_option == 0) + { + out_len = *pout_len; + pframe = rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_, + _WMM_IE_Length_, WMM_IE, pout_len); + + pqospriv->qos_option = 1; + } + + out_len = *pout_len; + + _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap)); + + ht_capie.cap_info = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_TX_STBC | + IEEE80211_HT_CAP_DSSSCCK40; + //if insert module set only support 20MHZ, don't add the 40MHZ and SGI_40 + if( channel > 14 ) + { + if( pregpriv->cbw40_enable & BIT(1) ) + cbw40_enable = 1; + } + else + if( pregpriv->cbw40_enable & BIT(0) ) + cbw40_enable = 1; + + if ( cbw40_enable != 0 ) + ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH | IEEE80211_HT_CAP_SGI_40; + + + + { + u32 rx_packet_offset, max_recvbuf_sz; + rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); + rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); + //if(max_recvbuf_sz-rx_packet_offset>(8191-256)) { + // DBG_871X("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__); + // ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU; + //} + } + + ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03); + + 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); + + + pframe = rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, + sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, pout_len); + + + //_rtw_memcpy(out_ie+out_len, p, ielen+2);//gtest + //*pout_len = *pout_len + (ielen+2); + + + phtpriv->ht_option = _TRUE; + + p = rtw_get_ie(in_ie+12, _HT_ADD_INFO_IE_, &ielen, in_len-12); + if(p && (ielen==sizeof(struct ieee80211_ht_addt_info))) + { + out_len = *pout_len; + pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len); + } + + } + + return (phtpriv->ht_option); + +} + +//the fucntion is > passive_level (in critical_section) +void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) +{ + u8 *p, max_ampdu_sz; + int len; + //struct sta_info *bmc_sta, *psta; + struct rtw_ieee80211_ht_cap *pht_capie; + struct ieee80211_ht_addt_info *pht_addtinfo; + //struct recv_reorder_ctrl *preorder_ctrl; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + //struct recv_priv *precvpriv = &padapter->recvpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + //struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 cbw40_enable=0; + + if(!phtpriv->ht_option) + return; + + if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable)) + return; + + DBG_871X("+rtw_update_ht_cap()\n"); + + //maybe needs check if ap supports rx ampdu. + if((phtpriv->ampdu_enable==_FALSE) &&(pregistrypriv->ampdu_enable==1)) + { + //In the wifi cert. test, the test Lab should turn off the AP's RX AMPDU. client doen't need to close the TX AMPDU + /*if(pregistrypriv->wifi_spec==1) + { + phtpriv->ampdu_enable = _FALSE; + } + else*/ + { + phtpriv->ampdu_enable = _TRUE; + } + } + else if(pregistrypriv->ampdu_enable==2) + { + phtpriv->ampdu_enable = _TRUE; + } + + + //check Max Rx A-MPDU Size + len = 0; + p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs)); + if(p && len>0) + { + pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2); + max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR); + max_ampdu_sz = 1 << (max_ampdu_sz+3); // max_ampdu_sz (kbytes); + + //DBG_871X("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); + phtpriv->rx_ampdu_maxlen = max_ampdu_sz; + + } + + + len=0; + p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs)); + if(p && len>0) + { + pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2); + //todo: + } + + if( channel > 14 ) + { + if( pregistrypriv->cbw40_enable & BIT(1) ) + cbw40_enable = 1; + } + else + if( pregistrypriv->cbw40_enable & BIT(0) ) + cbw40_enable = 1; + + + //update cur_bwmode & cur_ch_offset + if ((cbw40_enable) && + (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && + (pmlmeinfo->HT_info.infos[0] & BIT(2))) + { + int i; + u8 rf_type; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + //update the MCS rates + for (i = 0; i < 16; i++) + { + if((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) + { + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + } + else + { + #ifdef CONFIG_DISABLE_MCS13TO15 + if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 ) + { + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R_MCS13TO15_OFF[i]; + } + else + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; + #else + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; + #endif //CONFIG_DISABLE_MCS13TO15 + } + #ifdef RTL8192C_RECONFIG_TO_1T1R + { + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + } + #endif + + if(pregistrypriv->special_rf_path) + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + + } + //switch to the 40M Hz mode accoring to the AP + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) + { + case HT_EXTCHNL_OFFSET_UPPER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case HT_EXTCHNL_OFFSET_LOWER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + } + + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; + + + +#if 0 //move to rtw_update_sta_info_client() + //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info + //if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff + //todo: check if AP can send A-MPDU packets + bmc_sta = rtw_get_bcmc_stainfo(padapter); + if(bmc_sta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + } + + psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress); + if(psta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &psta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + } +#endif + +} + +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + u8 issued; + int priority; + struct sta_info *psta=NULL; + struct ht_priv *phtpriv; + struct pkt_attrib *pattrib =&pxmitframe->attrib; + s32 bmcst = IS_MCAST(pattrib->ra); + + if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE)) + return; + + priority = pattrib->priority; + + if (pattrib->psta) + psta = pattrib->psta; + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return; + } + + + phtpriv = &psta->htpriv; + + if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) + { + issued = (phtpriv->agg_enable_bitmap>>priority)&0x1; + issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1; + + if(0==issued) + { + DBG_871X("rtw_issue_addbareq_cmd, p=%d\n", priority); + psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); + rtw_addbareq_cmd(padapter,(u8) priority, pattrib->ra); + } + } + +} + +#endif + +#ifdef CONFIG_LAYER2_ROAMING +inline void rtw_set_roaming(_adapter *adapter, u8 to_roaming) +{ + if (to_roaming == 0) + adapter->mlmepriv.to_join = _FALSE; + adapter->mlmepriv.to_roaming = to_roaming; +} + +inline u8 rtw_to_roaming(_adapter *adapter) +{ + return adapter->mlmepriv.to_roaming; +} + +void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _rtw_roaming(padapter, tgt_network); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} +void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + int do_join_r; + + struct wlan_network *pnetwork; + + if(tgt_network != NULL) + pnetwork = tgt_network; + else + pnetwork = &pmlmepriv->cur_network; + + if(0 < rtw_to_roaming(padapter)) { + DBG_871X("roaming from %s("MAC_FMT"), length:%d\n", + pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress), + pnetwork->network.Ssid.SsidLength); + _rtw_memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID)); + + pmlmepriv->assoc_by_bssid = _FALSE; + + while(1) { + if( _SUCCESS==(do_join_r=rtw_do_join(padapter)) ) { + break; + } else { + DBG_871X("roaming do_join return %d\n", do_join_r); + pmlmepriv->to_roaming--; + + if(0< rtw_to_roaming(padapter)) { + continue; + } else { + DBG_871X("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__,__LINE__); + rtw_indicate_disconnect(padapter); + break; + } + } + } + } + +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +sint rtw_buddy_adapter_up(_adapter *padapter) +{ + sint res = _FALSE; + + if(padapter == NULL) + return res; + + + if(padapter->pbuddy_adapter == NULL) + { + res = _FALSE; + } + else if( (padapter->pbuddy_adapter->bDriverStopped) || (padapter->pbuddy_adapter->bSurpriseRemoved) || + (padapter->pbuddy_adapter->bup == _FALSE) || (padapter->pbuddy_adapter->hw_init_completed == _FALSE)) + { + res = _FALSE; + } + else + { + res = _TRUE; + } + + return res; + +} + +sint check_buddy_fwstate(_adapter *padapter, sint state) +{ + if(padapter == NULL) + return _FALSE; + + if(padapter->pbuddy_adapter == NULL) + return _FALSE; + + if ((state == WIFI_FW_NULL_STATE) && + (padapter->pbuddy_adapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE)) + return _TRUE; + + if (padapter->pbuddy_adapter->mlmepriv.fw_state & state) + return _TRUE; + + return _FALSE; +} +#endif //CONFIG_CONCURRENT_MODE + diff --git a/rtl8192cu-fixes/core/rtw_mlme_ext.c b/rtl8192cu-fixes/core/rtw_mlme_ext.c new file mode 100755 index 00000000..d29a20c3 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_mlme_ext.c @@ -0,0 +1,13600 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_MLME_EXT_C_ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mlme_handler mlme_sta_tbl[]={ + {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, + {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, + {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, + {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, + {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, + {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, + + /*---------------------------------------------------------- + below 2 are reserved + -----------------------------------------------------------*/ + {0, "DoReserved", &DoReserved}, + {0, "DoReserved", &DoReserved}, + {WIFI_BEACON, "OnBeacon", &OnBeacon}, + {WIFI_ATIM, "OnATIM", &OnAtim}, + {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, + {WIFI_AUTH, "OnAuth", &OnAuthClient}, + {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, + {WIFI_ACTION, "OnAction", &OnAction}, +}; + +#ifdef _CONFIG_NATIVEAP_MLME_ +struct mlme_handler mlme_ap_tbl[]={ + {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, + {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, + {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, + {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, + {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, + {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, + + /*---------------------------------------------------------- + below 2 are reserved + -----------------------------------------------------------*/ + {0, "DoReserved", &DoReserved}, + {0, "DoReserved", &DoReserved}, + {WIFI_BEACON, "OnBeacon", &OnBeacon}, + {WIFI_ATIM, "OnATIM", &OnAtim}, + {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, + {WIFI_AUTH, "OnAuth", &OnAuth}, + {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, + {WIFI_ACTION, "OnAction", &OnAction}, +}; +#endif + +struct action_handler OnAction_tbl[]={ + {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, + {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos}, + {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls}, + {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, + {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, + {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, + {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, + {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, +#ifdef CONFIG_IEEE80211W + {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query}, +#else + {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved}, +#endif //CONFIG_IEEE80211W + //add for CONFIG_IEEE80211W + {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved}, + {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved}, + {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm}, + {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p}, +}; + + +u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0}; + +/************************************************** +OUI definitions for the vendor specific IE +***************************************************/ +unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; +unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; +unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; +unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09}; +unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A}; + +unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; +unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + +unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; +unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; + +extern unsigned char REALTEK_96B_IE[]; + +/******************************************************** +MCS rate definitions +*********************************************************/ +#ifdef CONFIG_DISABLE_MCS13TO15 +unsigned char MCS_rate_2R_MCS13TO15_OFF[16] = {0xff, 0x1f, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +#else //CONFIG_DISABLE_MCS13TO15 +unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +#endif //CONFIG_DISABLE_MCS13TO15 +unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + +/******************************************************** +ChannelPlan definitions +*********************************************************/ +/*static RT_CHANNEL_PLAN DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = { + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},32}, // 0x00, RT_CHANNEL_DOMAIN_FCC + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},31}, // 0x01, RT_CHANNEL_DOMAIN_IC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x02, RT_CHANNEL_DOMAIN_ETSI + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x03, RT_CHANNEL_DOMAIN_SPAIN + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x04, RT_CHANNEL_DOMAIN_FRANCE + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x05, RT_CHANNEL_DOMAIN_MKK + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x06, RT_CHANNEL_DOMAIN_MKK1 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, // 0x07, RT_CHANNEL_DOMAIN_ISRAEL + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // 0x08, RT_CHANNEL_DOMAIN_TELEC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 + {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},26}, // 0x0B, RT_CHANNEL_DOMAIN_TAIWAN + {{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18}, // 0x0C, RT_CHANNEL_DOMAIN_CHINA + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, // 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},31}, // 0x0E, RT_CHANNEL_DOMAIN_KOREA + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, // 0x0F, RT_CHANNEL_DOMAIN_TURKEY + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x10, RT_CHANNEL_DOMAIN_JAPAN + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,149,153,157,161,165},20}, // 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48},17}, // 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},37}, // 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G + {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,149,153,157,161,165},19}, // 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS +};*/ + +static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 + {{1,2,3,4,5,6,7,8,9,10,11},11}, // 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 + {{10,11,12,13},4}, // 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 + {{},0}, // 0x05, RT_CHANNEL_DOMAIN_2G_NULL +}; + +static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = { + {{},0}, // 0x00, RT_CHANNEL_DOMAIN_5G_NULL + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165},22}, // 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 + {{36,40,44,48,149,153,157,161,165},9}, // 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 + {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 + {{36,40,44,48,52,56,60,64,149,153,157,161},12}, // 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 + {{149,153,157,161,165},5}, // 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 + {{36,40,44,48,52,56,60,64},8}, // 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20}, // 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},20}, // 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 + {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 + {{36,40,44,48,52,56,60,64},8}, // 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 + {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 + {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, // 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 + {{56,60,64,149,153,157,161,165},8}, // 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 + + //===== 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}, // 0x11, RT_CHANNEL_DOMAIN_5G_FCC + {{36,40,44,48},4}, // 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS + {{36,40,44,48,149,153,157,161},8}, // 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS +}; + +static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { + //===== 0x00 ~ 0x1F , Old Define ===== + {0x02,0x11}, //0x00, RT_CHANNEL_DOMAIN_FCC + {0x02,0x0A}, //0x01, RT_CHANNEL_DOMAIN_IC + {0x01,0x01}, //0x02, RT_CHANNEL_DOMAIN_ETSI + {0x01,0x00}, //0x03, RT_CHANNEL_DOMAIN_SPAIN + {0x01,0x00}, //0x04, RT_CHANNEL_DOMAIN_FRANCE + {0x03,0x00}, //0x05, RT_CHANNEL_DOMAIN_MKK + {0x03,0x00}, //0x06, RT_CHANNEL_DOMAIN_MKK1 + {0x01,0x09}, //0x07, RT_CHANNEL_DOMAIN_ISRAEL + {0x03,0x09}, //0x08, RT_CHANNEL_DOMAIN_TELEC + {0x03,0x00}, //0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN + {0x00,0x00}, //0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 + {0x02,0x0F}, //0x0B, RT_CHANNEL_DOMAIN_TAIWAN + {0x01,0x08}, //0x0C, RT_CHANNEL_DOMAIN_CHINA + {0x02,0x06}, //0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO + {0x02,0x0B}, //0x0E, RT_CHANNEL_DOMAIN_KOREA + {0x02,0x09}, //0x0F, RT_CHANNEL_DOMAIN_TURKEY + {0x01,0x01}, //0x10, RT_CHANNEL_DOMAIN_JAPAN + {0x02,0x05}, //0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS + {0x01,0x12}, //0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS + {0x00,0x04}, //0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G + {0x02,0x10}, //0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS + {0x00,0x12}, //0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS + {0x00,0x13}, //0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS + {0x03,0x12}, //0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS + {0x05,0x08}, //0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS + {0x02,0x08}, //0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS + {0x00,0x00}, //0x1A, + {0x00,0x00}, //0x1B, + {0x00,0x00}, //0x1C, + {0x00,0x00}, //0x1D, + {0x00,0x00}, //0x1E, + {0x05,0x04}, //0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G + //===== 0x20 ~ 0x7F ,New Define ===== + {0x00,0x00}, //0x20, RT_CHANNEL_DOMAIN_WORLD_NULL + {0x01,0x00}, //0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL + {0x02,0x00}, //0x22, RT_CHANNEL_DOMAIN_FCC1_NULL + {0x03,0x00}, //0x23, RT_CHANNEL_DOMAIN_MKK1_NULL + {0x04,0x00}, //0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL + {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,0x05}, //0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 + {0x00,0x00}, //0x2A, + {0x00,0x00}, //0x2B, + {0x00,0x00}, //0x2C, + {0x00,0x00}, //0x2D, + {0x00,0x00}, //0x2E, + {0x00,0x00}, //0x2F, + {0x00,0x06}, //0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 + {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 + {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 + {0x00,0x00}, //0x3A, + {0x00,0x00}, //0x3B, + {0x00,0x00}, //0x3C, + {0x00,0x00}, //0x3D, + {0x00,0x00}, //0x3E, + {0x00,0x00}, //0x3F, + {0x02,0x10}, //0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 +}; + +static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; //use the conbination for max channel numbers + +/* + * Search the @param ch in given @param ch_set + * @ch_set: the given channel set + * @ch: the given channel number + * + * return the index of channel_num in channel_set, -1 if not found + */ +int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch) +{ + int i; + for(i=0;ch_set[i].ChannelNum!=0;i++){ + if(ch == ch_set[i].ChannelNum) + break; + } + + if(i >= ch_set[i].ChannelNum) + return -1; + return i; +} + +/* + * Check the @param ch is fit with setband setting of @param adapter + * @adapter: the given adapter + * @ch: the given channel number + * + * return _TRUE when check valid, _FALSE not valid + */ +bool rtw_mlme_band_check(_adapter *adapter, const u32 ch) +{ + if (adapter->setband == GHZ24_50 /* 2.4G and 5G */ + || (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */ + || (adapter->setband == GHZ_50 && ch > 35) /* 5G only */ + ) { + return _TRUE; + } + return _FALSE; +} + +/**************************************************************************** + +Following are the initialization functions for WiFi MLME + +*****************************************************************************/ + +int init_hw_mlme_ext(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + //set_opmode_cmd(padapter, infra_client_with_mlme);//removed + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + return _SUCCESS; +} + +static void init_mlme_ext_priv_value(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //unsigned char default_channel_set[MAX_CHANNEL_NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0}; + 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,}; + + ATOMIC_SET(&pmlmeext->event_seq, 0); + pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode +#ifdef CONFIG_IEEE80211W + pmlmeext->sa_query_seq = 0; + pmlmeext->mgnt_80211w_IPN=0; + pmlmeext->mgnt_80211w_IPN_rx=0; +#endif //CONFIG_IEEE80211W + pmlmeext->cur_channel = padapter->registrypriv.channel; + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + pmlmeext->retry = 0; + + pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; + + //_rtw_memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len); + //_rtw_memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM); + _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates); + _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); + + if(pmlmeext->cur_channel > 14) + pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB; + else + pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; + + pmlmeext->sitesurvey_res.state = SCAN_DISABLE; + pmlmeext->sitesurvey_res.channel_idx = 0; + pmlmeext->sitesurvey_res.bss_cnt = 0; + pmlmeext->scan_abort = _FALSE; + + pmlmeinfo->state = WIFI_FW_NULL_STATE; + pmlmeinfo->reauth_count = 0; + pmlmeinfo->reassoc_count = 0; + pmlmeinfo->link_count = 0; + pmlmeinfo->auth_seq = 0; + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; + pmlmeinfo->key_index = 0; + pmlmeinfo->iv = 0; + + pmlmeinfo->enc_algo = _NO_PRIVACY_; + pmlmeinfo->authModeToggle = 0; + + _rtw_memset(pmlmeinfo->chg_txt, 0, 128); + + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + pmlmeinfo->preamble_mode = PREAMBLE_AUTO; + + pmlmeinfo->dialogToken = 0; + + pmlmeext->action_public_rxseq = 0xffff; + pmlmeext->action_public_dialog_token = 0xff; +} + +static int has_channel(RT_CHANNEL_INFO *channel_set, + u8 chanset_size, + u8 chan) { + int i; + + for (i = 0; i < chanset_size; i++) { + if (channel_set[i].ChannelNum == chan) { + return 1; + } + } + + return 0; +} + +static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set, + u8 chanset_size, + struct p2p_channels *channel_list) { + + struct p2p_oper_class_map op_class[] = { + { IEEE80211G, 81, 1, 13, 1, BW20 }, + { IEEE80211G, 82, 14, 14, 1, BW20 }, +#if 0 /* Do not enable HT40 on 2 GHz */ + { IEEE80211G, 83, 1, 9, 1, BW40PLUS }, + { IEEE80211G, 84, 5, 13, 1, BW40MINUS }, +#endif + { IEEE80211A, 115, 36, 48, 4, BW20 }, + { IEEE80211A, 116, 36, 44, 8, BW40PLUS }, + { IEEE80211A, 117, 40, 48, 8, BW40MINUS }, + { IEEE80211A, 124, 149, 161, 4, BW20 }, + { IEEE80211A, 125, 149, 169, 4, BW20 }, + { IEEE80211A, 126, 149, 157, 8, BW40PLUS }, + { IEEE80211A, 127, 153, 161, 8, BW40MINUS }, + { -1, 0, 0, 0, 0, BW20 } + }; + + int cla, op; + + cla = 0; + + for (op = 0; op_class[op].op_class; op++) { + u8 ch; + struct p2p_oper_class_map *o = &op_class[op]; + struct p2p_reg_class *reg = NULL; + + for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { + if (!has_channel(channel_set, chanset_size, ch)) { + continue; + } + + if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) + continue; + + if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) && + ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) + continue; + + if (reg == NULL) { + reg = &channel_list->reg_class[cla]; + cla++; + reg->reg_class = o->op_class; + reg->channels = 0; + } + reg->channel[reg->channels] = ch; + reg->channels++; + } + } + channel_list->reg_classes = cla; + +} + +static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set) +{ + u8 index,chanset_size = 0; + u8 b5GBand = _FALSE, b2_4GBand = _FALSE; + u8 Index2G = 0, Index5G=0; + + _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM); + + if(ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) + { + DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan); + return chanset_size; + } + + if(padapter->registrypriv.wireless_mode & WIRELESS_11G) + { + b2_4GBand = _TRUE; + if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) + Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; + else + Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; + } + + if(padapter->registrypriv.wireless_mode & WIRELESS_11A) + { + b5GBand = _TRUE; + if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) + Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G; + else + Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G; + } + + if(b2_4GBand) + { + for(index=0;index= 1 && channel_set[chanset_size].ChannelNum <= 11) + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } + else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan || + RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan || + RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan + { + if(channel_set[chanset_size].ChannelNum <= 11) + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + else + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } + else + { + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + } + + chanset_size++; + } + } + + if(b5GBand) + { + for(index=0;index= 149 ) + { + if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + else + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + } + else + { + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } + chanset_size++; +#else /* CONFIG_DFS */ + if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48 + || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) { + channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index]; + if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + else + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum); + chanset_size++; + } +#endif /* CONFIG_DFS */ + } + } + + return chanset_size; +} + +int init_mlme_ext_priv(_adapter* padapter) +{ + int res = _SUCCESS; + struct registry_priv* pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); + + pmlmeext->padapter = padapter; + + //fill_fwpriv(padapter, &(pmlmeext->fwpriv)); + + init_mlme_ext_priv_value(padapter); + pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq; + + init_mlme_ext_timer(padapter); + +#ifdef CONFIG_AP_MODE + init_mlme_ap_info(padapter); +#endif + + pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set); + init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); + + pmlmeext->chan_scan_time = SURVEY_TO; + pmlmeext->mlmeext_init = _TRUE; + + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + pmlmeext->active_keep_alive_check = _TRUE; +#endif + + return res; + +} + +void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext) +{ + _adapter *padapter = pmlmeext->padapter; + + if (!padapter) + return; + + if (padapter->bDriverStopped == _TRUE) + { + _cancel_timer_ex(&pmlmeext->survey_timer); + _cancel_timer_ex(&pmlmeext->link_timer); + //_cancel_timer_ex(&pmlmeext->ADDBA_timer); + } +} + +static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len) +{ // if the channel is same, return 0. else return channel differential + uint len; + u8 channel; + u8 *p; + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_); + if (p) + { + channel = *(p + 2); + if(padapter->mlmeextpriv.cur_channel >= channel) + { + return (padapter->mlmeextpriv.cur_channel - channel); + } + else + { + return (channel-padapter->mlmeextpriv.cur_channel); + } + } + else + { + return 0; + } +} + +static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame) +{ + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 *pframe = precv_frame->u.hdr.rx_data; + + if(ptable->func) + { + //receive the frames that ra(a1) is my address or ra(a1) is bc address. + if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && + !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) + { + return; + } + + ptable->func(padapter, precv_frame); + } + +} + +void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) +{ + int index; + struct mlme_handler *ptable; +#ifdef CONFIG_AP_MODE + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //CONFIG_AP_MODE + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 *pframe = precv_frame->u.hdr.rx_data; + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, + ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n", + GetFrameType(pframe), GetFrameSubType(pframe))); + +#if 0 + { + u8 *pbuf; + pbuf = GetAddr1Ptr(pframe); + DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + pbuf = GetAddr2Ptr(pframe); + DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + pbuf = GetAddr3Ptr(pframe); + DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + } +#endif + + if (GetFrameType(pframe) != WIFI_MGT_TYPE) + { + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe))); + return; + } + + //receive the frames that ra(a1) is my address or ra(a1) is bc address. + if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && + !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) + { + return; + } + + ptable = mlme_sta_tbl; + + index = GetFrameSubType(pframe) >> 4; + +#ifdef CONFIG_TDLS + if((index << 4)==WIFI_ACTION){ + //category==RTW_WLAN_CATEGORY_PUBLIC, action==TDLS_DISCOVERY_RESPONSE + if(*(pframe + IEEE80211_MGMT_HDR_LEN ) == RTW_WLAN_CATEGORY_PUBLIC + && *(pframe + IEEE80211_MGMT_HDR_LEN + 1) == TDLS_DISCOVERY_RESPONSE ) + { + DBG_871X("recv tdls discovery response frame\n"); + On_TDLS_Dis_Rsp(padapter, precv_frame); + } + } +#endif //CONFIG_TDLS + + if (index > 13) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index)); + return; + } + ptable += index; + +#if 1 + if (psta != NULL) + { + if (GetRetry(pframe)) + { + if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) + { + /* drop the duplicate management frame */ + DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num); + return; + } + } + psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num; + } +#else + + if(GetRetry(pframe)) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n")); + //return; + } +#endif + +#ifdef CONFIG_AP_MODE + switch (GetFrameSubType(pframe)) + { + case WIFI_AUTH: + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + ptable->func = &OnAuth; + else + ptable->func = &OnAuthClient; + //pass through + case WIFI_ASSOCREQ: + case WIFI_REASSOCREQ: + _mgt_dispatcher(padapter, ptable, precv_frame); +#ifdef CONFIG_HOSTAPD_MLME + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_hostapd_mlme_rx(padapter, precv_frame); +#endif + break; + case WIFI_PROBEREQ: + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_HOSTAPD_MLME + rtw_hostapd_mlme_rx(padapter, precv_frame); +#else + _mgt_dispatcher(padapter, ptable, precv_frame); +#endif + } + else + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + case WIFI_BEACON: + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + case WIFI_ACTION: + //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + default: + _mgt_dispatcher(padapter, ptable, precv_frame); + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_hostapd_mlme_rx(padapter, precv_frame); + break; + } +#else + + _mgt_dispatcher(padapter, ptable, precv_frame); + +#endif + +} + +#ifdef CONFIG_P2P +u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da) +{ + bool response = _TRUE; + +#ifdef CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE + || padapter->mlmepriv.wps_probe_resp_ie == NULL + || padapter->mlmepriv.p2p_probe_resp_ie == NULL + ) + { + DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n", + wdev_to_priv(padapter->rtw_wdev)->p2p_enabled, + padapter->mlmepriv.wps_probe_resp_ie, + padapter->mlmepriv.p2p_probe_resp_ie); + response = _FALSE; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_WEXT ) + { + // do nothing if the device name is empty + if ( !padapter->wdinfo.device_name_len ) + { + response = _FALSE; + } + } + + if (response == _TRUE) + issue_probersp_p2p( padapter, da); + + return _SUCCESS; +} +#endif //CONFIG_P2P + + +/**************************************************************************** + +Following are the callback functions for each subtype of the management frames + +*****************************************************************************/ + +unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ielen; + unsigned char *p; + 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 = &(pmlmeinfo->network); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 is_valid_p2p_probereq = _FALSE; + +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + u8 wifi_test_chk_rate = 1; + + if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && + !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) + ) + { + // Commented by Albert 2011/03/17 + // mcs_rate = 0 -> CCK 1M rate + // mcs_rate = 1 -> CCK 2M rate + // mcs_rate = 2 -> CCK 5.5M rate + // mcs_rate = 3 -> CCK 11M rate + // In the P2P mode, the driver should not support the CCK rate + + // 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->mcs_rate <= 3 ) + { + wifi_test_chk_rate = 0; + } +#endif //CONFIG_WIFI_TEST + + if( wifi_test_chk_rate == 1 ) + { + if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE) + { + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) + { + p2p_listen_state_process( padapter, get_sa(pframe)); + + return _SUCCESS; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + goto _continue; + } + } + } + } + +_continue: +#endif //CONFIG_P2P + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + return _SUCCESS; + } + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE && + check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE) + { + return _SUCCESS; + } + + + //DBG_871X("+OnProbeReq\n"); + +#ifdef CONFIG_AUTO_AP_MODE + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + pmlmepriv->cur_network.join_res == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + u8 *mac_addr, *peer_addr; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A}; + //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + if(!p || ielen !=14) + goto _non_rc_device; + + if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI))) + goto _non_rc_device; + + if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN)) + { + DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__, + MAC_ARG(get_sa(pframe)), MAC_ARG(p+6)); + + goto _non_rc_device; + } + + DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe))); + + //new a station + psta = rtw_get_stainfo(pstapriv, get_sa(pframe)); + if (psta == NULL) + { + // allocate a new one + DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe))); + psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe)); + if (psta == NULL) + { + //TODO: + DBG_871X(" Exceed the upper limit of supported clients...\n"); + return _SUCCESS; + } + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list)) + { + psta->expire_to = pstapriv->expire_to; + rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list); + pstapriv->asoc_list_cnt++; + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + //generate pairing ID + mac_addr = myid(&(padapter->eeprompriv)); + peer_addr = psta->hwaddr; + psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5])); + + //update peer stainfo + psta->isrc = _TRUE; + //psta->aid = 0; + //psta->mac_id = 2; + + /* get a unique AID */ + if (psta->aid > 0) { + DBG_871X("old AID %d\n", psta->aid); + } else { + for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++) + if (pstapriv->sta_aid[psta->aid - 1] == NULL) + break; + + if (psta->aid > pstapriv->max_num_sta) { + psta->aid = 0; + DBG_871X("no room for more AIDs\n"); + return _SUCCESS; + } else { + pstapriv->sta_aid[psta->aid - 1] = psta; + DBG_871X("allocate new AID = (%d)\n", psta->aid); + } + } + + psta->qos_option = 1; + psta->htpriv.ht_option = _TRUE; + psta->ieee8021x_blocked = _FALSE; + psta->htpriv.ampdu_enable = _FALSE; + psta->htpriv.sgi = _FALSE; + psta->htpriv.bwmode = HT_CHANNEL_WIDTH_20; + psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + //rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE); + + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + _enter_critical_bh(&psta->lock, &irqL); + psta->state |= _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + report_add_sta_event(padapter, psta->hwaddr, psta->aid); + + } + + issue_probersp(padapter, get_sa(pframe), _FALSE); + + return _SUCCESS; + + } + +_non_rc_device: + + return _SUCCESS; +#endif //CONFIG_AUTO_AP_MODE + + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process probe req + return _SUCCESS; + } +#endif + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + + //check (wildcard) SSID + if (p != NULL) + { + if(is_valid_p2p_probereq == _TRUE) + { + goto _issue_probersp; + } + + if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) + || (ielen == 0 && pmlmeinfo->hidden_ssid_mode) + ) + { + return _SUCCESS; + } + +_issue_probersp: + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + pmlmepriv->cur_network.join_res == _TRUE) + { + //DBG_871X("+issue_probersp during ap mode\n"); + issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); + } + + } + + return _SUCCESS; + +} + +unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct sta_info *psta; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) + { + if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) + { + pwdinfo->tx_prov_disc_info.benable = _FALSE; + issue_p2p_provision_request( padapter, + pwdinfo->tx_prov_disc_info.ssid.Ssid, + pwdinfo->tx_prov_disc_info.ssid.SsidLength, + pwdinfo->tx_prov_disc_info.peerDevAddr ); + } + else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) ) + { + pwdinfo->tx_prov_disc_info.benable = _FALSE; + issue_p2p_provision_request( padapter, + NULL, + 0, + pwdinfo->tx_prov_disc_info.peerDevAddr ); + } + } + } + return _SUCCESS; + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + if ( _TRUE == pwdinfo->nego_req_info.benable ) + { + DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ ); + if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + pwdinfo->nego_req_info.benable = _FALSE; + issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr); + } + } + } + else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) ) + { + if ( _TRUE == pwdinfo->invitereq_info.benable ) + { + DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ ); + if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + pwdinfo->invitereq_info.benable = _FALSE; + issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr ); + } + } + } +#endif + + + if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) + { + report_survey_event(padapter, precv_frame); +#ifdef CONFIG_CONCURRENT_MODE + report_survey_event(padapter->pbuddy_adapter, precv_frame); +#endif +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_report_survey_event(padapter, precv_frame); +#endif + return _SUCCESS; + } + + #if 0 //move to validate_recv_mgnt_frame + if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) + { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL) + { + psta->sta_stats.rx_mgnt_pkts++; + } + } + } + #endif + + return _SUCCESS; + +} + +unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) +{ + int cam_idx; + struct sta_info *psta; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 *p = NULL; + u32 ielen = 0; + +#ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR + p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_); + if ((p != NULL) && (ielen > 0)) + { + if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) + { + /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ + DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe))); + *(p + 1) = ielen - 1; + } + } +#endif + + if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) + { + report_survey_event(padapter, precv_frame); +#ifdef CONFIG_CONCURRENT_MODE + report_survey_event(padapter->pbuddy_adapter, precv_frame); +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_report_survey_event(padapter, precv_frame); +#endif + + return _SUCCESS; + } + + if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) + { + if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) + { + //check the vendor of the assoc AP + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr)); +#ifdef CONFIG_P2P_PS + // do P2P PS Before link ? , ToDo + //process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); +#endif // CONFIG_P2P_PS + + //update TSF Value + update_TSF(pmlmeext, pframe, len); + + //start auth + start_clnt_auth(padapter); + + return _SUCCESS; + } + + if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + { + if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL) + { + #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL + //Merge from 8712 FW code + if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0) + { // join wrong channel, deauth and reconnect + issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING); + + report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL); + pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS); + return _SUCCESS; + } + #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL + + //update WMM, ERP in the beacon + //todo: the timer is used instead of the number of the beacon received + if ((sta_rx_pkts(psta) & 0xf) == 0) + { + //DBG_871X("update_bcn_info\n"); + update_beacon_info(padapter, pframe, len, psta); + } + +#ifdef CONFIG_DFS + process_csa_ie(padapter, pframe, len); //channel switch announcement +#endif //CONFIG_DFS + +#ifdef CONFIG_P2P_PS + //if(psta->ieee8021x_blocked == _FALSE) // do not allow P2P PS during EAPOL handshake ? + process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); +#endif //CONFIG_P2P_PS + + #if 0 //move to validate_recv_mgnt_frame + psta->sta_stats.rx_mgnt_pkts++; + #endif + } + } + else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL) + { + //update WMM, ERP in the beacon + //todo: the timer is used instead of the number of the beacon received + if ((sta_rx_pkts(psta) & 0xf) == 0) + { + //DBG_871X("update_bcn_info\n"); + update_beacon_info(padapter, pframe, len, psta); + } + + #if 0 //move to validate_recv_mgnt_frame + psta->sta_stats.rx_mgnt_pkts++; + #endif + } + else + { + //allocate a new CAM entry for IBSS station + if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA) + { + goto _END_ONBEACON_; + } + + //get supported rate + if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) + { + pmlmeinfo->FW_sta_info[cam_idx].status = 0; + goto _END_ONBEACON_; + } + + //update TSF Value + update_TSF(pmlmeext, pframe, len); + + //report sta add event + report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); + } + } + } + +_END_ONBEACON_: + + return _SUCCESS; + +} + +unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + _irqL irqL; + unsigned int auth_mode, seq, ie_len; + unsigned char *sa, *p; + u16 algorithm; + int status; + static struct sta_info stat; + struct sta_info *pstat=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process auth request; + return _SUCCESS; + } +#endif //CONFIG_CONCURRENT_MODE + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return _FAIL; + + DBG_871X("+OnAuth\n"); + + sa = GetAddr2Ptr(pframe); + + auth_mode = psecuritypriv->dot11AuthAlgrthm; + seq = cpu_to_le16(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + 2)); + algorithm = cpu_to_le16(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN)); + + if (GetPrivacy(pframe)) + { +#if 0 //TODO: SW rtw_wep_decrypt + if (SWCRYPTO) + { + status = rtw_wep_decrypt(priv, pframe, pfrinfo->pktlen, + priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm); + if (status == FALSE) + { + SAVE_INT_AND_CLI(flags); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"wep-decrypt a Auth frame error!\n"); + status = _STATS_CHALLENGE_FAIL_; + goto auth_fail; + } + } + + seq = cpu_to_le16(*(unsigned short *)((unsigned int)pframe + WLAN_HDR_A3_LEN + 4 + 2)); + algorithm = cpu_to_le16(*(unsigned short *)((unsigned int)pframe + WLAN_HDR_A3_LEN + 4)); +#endif + } + + + DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq); + + if (auth_mode == 2 && + psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && + psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) + auth_mode = 0; + + if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled + (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled + { + DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n", + algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); + + status = _STATS_NO_SUPP_ALG_; + + goto auth_fail; + } + +#if 0 //ACL control + phead = &priv->wlan_acl_list; + plist = phead->next; + //check sa + if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected. + res = FAIL; + else + res = SUCCESS; + + while(plist != phead) + { + paclnode = list_entry(plist, struct rtw_wlan_acl_node, list); + plist = plist->next; + if (!memcmp((void *)sa, paclnode->addr, 6)) { + if (paclnode->mode & 2) { // deny + res = FAIL; + break; + } + else { + res = SUCCESS; + break; + } + } + } + + if (res != SUCCESS) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n"); + return FAIL; + } +#else + if(rtw_access_ctrl(padapter, sa) == _FALSE) + { + status = _STATS_UNABLE_HANDLE_STA_; + goto auth_fail; + } +#endif + + pstat = rtw_get_stainfo(pstapriv, sa); + if (pstat == NULL) + { + // allocate a new one + DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa)); + pstat = rtw_alloc_stainfo(pstapriv, sa); + if (pstat == NULL) + { + DBG_871X(" Exceed the upper limit of supported clients...\n"); + status = _STATS_UNABLE_HANDLE_STA_; + goto auth_fail; + } + + pstat->state = WIFI_FW_AUTH_NULL; + pstat->auth_seq = 0; + + //pstat->flags = 0; + //pstat->capability = 0; + } + else + { + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE) + { + rtw_list_delete(&pstat->asoc_list); + pstapriv->asoc_list_cnt--; + if (pstat->expire_to > 0) + { + //TODO: STA re_auth within expire_to + } + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + if (seq==1) { + //TODO: STA re_auth and auth timeout + } + } + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + if (rtw_is_list_empty(&pstat->auth_list)) + { + rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list); + pstapriv->auth_list_cnt++; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + if (pstat->auth_seq == 0) + pstat->expire_to = pstapriv->auth_to; + + if ((pstat->auth_seq + 1) != seq) + { + DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + + if (algorithm==0 && (auth_mode == 0 || auth_mode == 2)) + { + if (seq == 1) + { + pstat->state &= ~WIFI_FW_AUTH_NULL; + pstat->state |= WIFI_FW_AUTH_SUCCESS; + pstat->expire_to = pstapriv->assoc_to; + pstat->authalg = algorithm; + } + else + { + DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + } + else // shared system or auto authentication + { + if (seq == 1) + { + //prepare for the challenging txt... + + //get_random_bytes((void *)pstat->chg_txt, 128);//TODO: + + pstat->state &= ~WIFI_FW_AUTH_NULL; + pstat->state |= WIFI_FW_AUTH_STATE; + pstat->authalg = algorithm; + pstat->auth_seq = 2; + } + else if (seq == 3) + { + //checking for challenging txt... + DBG_871X("checking for challenging txt...\n"); + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len, + len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); + + if((p==NULL) || (ie_len<=0)) + { + DBG_871X("auth rejected because challenge failure!(1)\n"); + status = _STATS_CHALLENGE_FAIL_; + goto auth_fail; + } + + if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) + { + pstat->state &= (~WIFI_FW_AUTH_STATE); + pstat->state |= WIFI_FW_AUTH_SUCCESS; + // challenging txt is correct... + pstat->expire_to = pstapriv->assoc_to; + } + else + { + DBG_871X("auth rejected because challenge failure!\n"); + status = _STATS_CHALLENGE_FAIL_; + goto auth_fail; + } + } + else + { + DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + } + + + // Now, we are going to issue_auth... + pstat->auth_seq = seq + 1; + +#ifdef CONFIG_NATIVEAP_MLME + issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); +#endif + + if (pstat->state & WIFI_FW_AUTH_SUCCESS) + pstat->auth_seq = 0; + + + return _SUCCESS; + +auth_fail: + + if(pstat) + rtw_free_stainfo(padapter , pstat); + + pstat = &stat; + _rtw_memset((char *)pstat, '\0', sizeof(stat)); + pstat->auth_seq = 2; + _rtw_memcpy(pstat->hwaddr, sa, 6); + +#ifdef CONFIG_NATIVEAP_MLME + issue_auth(padapter, pstat, (unsigned short)status); +#endif + +#endif + return _FAIL; + +} + +unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int seq, len, status, algthm, offset; + unsigned char *p; + unsigned int go2asoc = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; + + DBG_871X("%s\n", __FUNCTION__); + + //check A1 matches or not + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) + return _SUCCESS; + + if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) + return _SUCCESS; + + offset = (GetPrivacy(pframe))? 4: 0; + + algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset)); + seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); + status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4)); + + if (status != 0) + { + DBG_871X("clnt auth fail, status: %d\n", status); + if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) + { + if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; + else + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; + //pmlmeinfo->reauth_count = 0; + } + + set_link_timer(pmlmeext, 1); + goto authclnt_fail; + } + + if (seq == 2) + { + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + { + // legendary shared system + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len, + pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); + + if (p == NULL) + { + //DBG_871X("marc: no challenge text?\n"); + goto authclnt_fail; + } + + _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); + pmlmeinfo->auth_seq = 3; + issue_auth(padapter, NULL, 0); + set_link_timer(pmlmeext, REAUTH_TO); + + return _SUCCESS; + } + else + { + // open system + go2asoc = 1; + } + } + else if (seq == 4) + { + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + { + go2asoc = 1; + } + else + { + goto authclnt_fail; + } + } + else + { + // this is also illegal + //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq); + goto authclnt_fail; + } + + if (go2asoc) + { + start_clnt_assoc(padapter); + return _SUCCESS; + } + +authclnt_fail: + + //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); + + return _FAIL; + +} + +unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + _irqL irqL; + u16 capab_info, listen_interval; + struct rtw_ieee802_11_elems elems; + struct sta_info *pstat; + unsigned char reassoc, *p, *pos, *wpa_ie; + unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; + int i, ie_len, wpa_ie_len, left; + unsigned char supportRate[16]; + int supportRateNum; + unsigned short status = _STATS_SUCCESSFUL_; + unsigned short frame_type, ie_offset=0; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 p2p_status_code = P2P_STATUS_SUCCESS; + u8 *p2pie; + u32 p2pielen = 0; +#ifdef CONFIG_WFD + u8 wfd_ie[ 128 ] = { 0x00 }; + u32 wfd_ielen = 0; +#endif // CONFIG_WFD +#endif //CONFIG_P2P + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process assoc request; + return _SUCCESS; + } +#endif //CONFIG_CONCURRENT_MODE + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return _FAIL; + + frame_type = GetFrameSubType(pframe); + if (frame_type == WIFI_ASSOCREQ) + { + reassoc = 0; + ie_offset = _ASOCREQ_IE_OFFSET_; + } + else // WIFI_REASSOCREQ + { + reassoc = 1; + ie_offset = _REASOCREQ_IE_OFFSET_; + } + + + if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) { + DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)" + "\n", reassoc, (unsigned long)pkt_len); + return _FAIL; + } + + pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (pstat == (struct sta_info *)NULL) + { + status = _RSON_CLS2_; + goto asoc_class2_error; + } + + capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN); + //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); + listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2); + + left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset); + pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset); + + + DBG_871X("%s\n", __FUNCTION__); + + // check if this stat has been successfully authenticated/assocated + if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) + { + if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) + { + status = _RSON_CLS2_; + goto asoc_class2_error; + } + else + { + pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); + pstat->state |= WIFI_FW_ASSOC_STATE; + } + } + else + { + pstat->state &= (~WIFI_FW_AUTH_SUCCESS); + pstat->state |= WIFI_FW_ASSOC_STATE; + } + + +#if 0// todo:tkip_countermeasures + if (hapd->tkip_countermeasures) { + resp = WLAN_REASON_MICHAEL_MIC_FAILURE; + goto fail; + } +#endif + + pstat->capability = capab_info; + +#if 0//todo: + //check listen_interval + if (listen_interval > hapd->conf->max_listen_interval) { + hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_DEBUG, + "Too large Listen Interval (%d)", + listen_interval); + resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; + goto fail; + } + + pstat->listen_interval = listen_interval; +#endif + + //now parse all ieee802_11 ie to point to elems + if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || + !elems.ssid) { + DBG_871X("STA " MAC_FMT " sent invalid association request\n", + MAC_ARG(pstat->hwaddr)); + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + + + // now we should check all the fields... + // checking SSID + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len, + pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p == NULL) + { + status = _STATS_FAILURE_; + } + + if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq + status = _STATS_FAILURE_; + else + { + // check if ssid match + if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) + status = _STATS_FAILURE_; + + if (ie_len != cur->Ssid.SsidLength) + status = _STATS_FAILURE_; + } + + if(_STATS_SUCCESSFUL_ != status) + goto OnAssocReqFail; + + // check if the supported rate is ok + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p == NULL) { + DBG_871X("Rx a sta assoc-req which supported rate is empty!\n"); + // use our own rate set as statoin used + //_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); + //supportRateNum = AP_BSSRATE_LEN; + + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + else { + _rtw_memcpy(supportRate, p+2, ie_len); + supportRateNum = ie_len; + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len, + pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p != NULL) { + + if(supportRateNum<=sizeof(supportRate)) + { + _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len); + supportRateNum += ie_len; + } + } + } + + //todo: mask supportRate between AP & STA -> move to update raid + //get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); + + //update station supportRate + pstat->bssratelen = supportRateNum; + _rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum); + + + //check RSN/WPA/WPS + pstat->dot8021xalg = 0; + pstat->wpa_psk = 0; + pstat->wpa_group_cipher = 0; + pstat->wpa2_group_cipher = 0; + pstat->wpa_pairwise_cipher = 0; + pstat->wpa2_pairwise_cipher = 0; + _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); + if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { + + int group_cipher=0, pairwise_cipher=0; + + wpa_ie = elems.rsn_ie; + wpa_ie_len = elems.rsn_ie_len; + + if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + pstat->dot8021xalg = 1;//psk, todo:802.1x + pstat->wpa_psk |= BIT(1); + + pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher; + pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher; + + if(!pstat->wpa2_group_cipher) + status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + + if(!pstat->wpa2_pairwise_cipher) + status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; + } + else + { + status = WLAN_STATUS_INVALID_IE; + } + + } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { + + int group_cipher=0, pairwise_cipher=0; + + wpa_ie = elems.wpa_ie; + wpa_ie_len = elems.wpa_ie_len; + + if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + pstat->dot8021xalg = 1;//psk, todo:802.1x + pstat->wpa_psk |= BIT(0); + + pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher; + pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher; + + if(!pstat->wpa_group_cipher) + status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + + if(!pstat->wpa_pairwise_cipher) + status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; + + } + else + { + status = WLAN_STATUS_INVALID_IE; + } + + } else { + wpa_ie = NULL; + wpa_ie_len = 0; + } + + if(_STATS_SUCCESSFUL_ != status) + goto OnAssocReqFail; + + pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); + //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS + if(wpa_ie == NULL) { + if (elems.wps_ie) { + DBG_871X("STA included WPS IE in " + "(Re)Association Request - assume WPS is " + "used\n"); + pstat->flags |= WLAN_STA_WPS; + //wpabuf_free(sta->wps_ie); + //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, + // elems.wps_ie_len - 4); + } else { + DBG_871X("STA did not include WPA/RSN IE " + "in (Re)Association Request - possible WPS " + "use\n"); + pstat->flags |= WLAN_STA_MAYBE_WPS; + } + + + // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready + // that the selected registrar of AP is _FLASE + if((psecuritypriv->wpa_psk >0) + && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) + { + if(pmlmepriv->wps_beacon_ie) + { + u8 selected_registrar = 0; + + rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL); + + if(!selected_registrar) + { + DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n"); + + status = _STATS_UNABLE_HANDLE_STA_; + + goto OnAssocReqFail; + } + } + } + + } + else + { + int copy_len; + + if(psecuritypriv->wpa_psk == 0) + { + DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association " + "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr)); + + status = WLAN_STATUS_INVALID_IE; + + goto OnAssocReqFail; + + } + + if (elems.wps_ie) { + DBG_871X("STA included WPS IE in " + "(Re)Association Request - WPS is " + "used\n"); + pstat->flags |= WLAN_STA_WPS; + copy_len=0; + } + else + { + copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2); + } + + + if(copy_len>0) + _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len); + + } + + + // check if there is WMM IE & support WWM-PS + pstat->flags &= ~WLAN_STA_WME; + pstat->qos_option = 0; + pstat->qos_info = 0; + pstat->has_legacy_ac = _TRUE; + pstat->uapsd_vo = 0; + pstat->uapsd_vi = 0; + pstat->uapsd_be = 0; + pstat->uapsd_bk = 0; + if (pmlmepriv->qospriv.qos_option) + { + p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; + for (;;) + { + p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p != NULL) { + if (_rtw_memcmp(p+2, WMM_IE, 6)) { + + pstat->flags |= WLAN_STA_WME; + + pstat->qos_option = 1; + pstat->qos_info = *(p+8); + + pstat->max_sp_len = (pstat->qos_info>>5)&0x3; + + if((pstat->qos_info&0xf) !=0xf) + pstat->has_legacy_ac = _TRUE; + else + pstat->has_legacy_ac = _FALSE; + + if(pstat->qos_info&0xf) + { + if(pstat->qos_info&BIT(0)) + pstat->uapsd_vo = BIT(0)|BIT(1); + else + pstat->uapsd_vo = 0; + + if(pstat->qos_info&BIT(1)) + pstat->uapsd_vi = BIT(0)|BIT(1); + else + pstat->uapsd_vi = 0; + + if(pstat->qos_info&BIT(2)) + pstat->uapsd_bk = BIT(0)|BIT(1); + else + pstat->uapsd_bk = 0; + + if(pstat->qos_info&BIT(3)) + pstat->uapsd_be = BIT(0)|BIT(1); + else + pstat->uapsd_be = 0; + + } + + break; + } + } + else { + break; + } + p = p + ie_len + 2; + } + } + + +#ifdef CONFIG_80211N_HT + /* save HT capabilities in the sta object */ + _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap)); + if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) + { + pstat->flags |= WLAN_STA_HT; + + pstat->flags |= WLAN_STA_WME; + + _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap)); + + } else + pstat->flags &= ~WLAN_STA_HT; + + + if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT)) + { + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + + + if ((pstat->flags & WLAN_STA_HT) && + ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || + (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) + { + DBG_871X("HT: " MAC_FMT " tried to " + "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr)); + + //status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; + //goto OnAssocReqFail; + } +#endif /* CONFIG_80211N_HT */ + + // + //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//? + pstat->flags |= WLAN_STA_NONERP; + for (i = 0; i < pstat->bssratelen; i++) { + if ((pstat->bssrateset[i] & 0x7f) > 22) { + pstat->flags &= ~WLAN_STA_NONERP; + break; + } + } + + if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + pstat->flags |= WLAN_STA_SHORT_PREAMBLE; + else + pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; + + + + if (status != _STATS_SUCCESSFUL_) + goto OnAssocReqFail; + +#ifdef CONFIG_P2P + pstat->is_p2p_device = _FALSE; + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen))) + { + pstat->is_p2p_device = _TRUE; + if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0) + { + pstat->p2p_status_code = p2p_status_code; + status = _STATS_CAP_FAIL_; + goto OnAssocReqFail; + } + } +#ifdef CONFIG_WFD + if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen )) + { + u8 attr_content[ 10 ] = { 0x00 }; + u32 attr_contentlen = 0; + + DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ ); + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + } + } +#endif + } + pstat->p2p_status_code = p2p_status_code; +#endif //CONFIG_P2P + + //TODO: identify_proprietary_vendor_ie(); + // Realtek proprietary IE + // identify if this is Broadcom sta + // identify if this is ralink sta + // Customer proprietary IE + + + + /* get a unique AID */ + if (pstat->aid > 0) { + DBG_871X(" old AID %d\n", pstat->aid); + } else { + for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) + if (pstapriv->sta_aid[pstat->aid - 1] == NULL) + break; + + //if (pstat->aid > NUM_STA) { + if (pstat->aid > pstapriv->max_num_sta) { + + pstat->aid = 0; + + DBG_871X(" no room for more AIDs\n"); + + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + + goto OnAssocReqFail; + + + } else { + pstapriv->sta_aid[pstat->aid - 1] = pstat; + DBG_871X("allocate new AID = (%d)\n", pstat->aid); + } + } + + + pstat->state &= (~WIFI_FW_ASSOC_STATE); + pstat->state |= WIFI_FW_ASSOC_SUCCESS; + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + if (!rtw_is_list_empty(&pstat->auth_list)) + { + rtw_list_delete(&pstat->auth_list); + pstapriv->auth_list_cnt--; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&pstat->asoc_list)) + { + pstat->expire_to = pstapriv->expire_to; + rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list); + pstapriv->asoc_list_cnt++; + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + // now the station is qualified to join our BSS... + if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status)) + { +#ifdef CONFIG_NATIVEAP_MLME + //.1 bss_cap_update & sta_info_update + bss_cap_update_on_sta_join(padapter, pstat); + sta_info_update(padapter, pstat); + + //issue assoc rsp before notify station join event. + if (frame_type == WIFI_ASSOCREQ) + issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); + else + issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); + + //.2 - report to upper layer + DBG_871X("indicate_sta_join_event to upper layer - hostapd\n"); + +#ifdef CONFIG_IOCTL_CFG80211 + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len); + #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + _enter_critical_bh(&pstat->lock, &irqL); + if(pstat->passoc_req) + { + rtw_mfree(pstat->passoc_req, pstat->assoc_req_len); + pstat->passoc_req = NULL; + pstat->assoc_req_len = 0; + } + + pstat->passoc_req = rtw_zmalloc(pkt_len); + if(pstat->passoc_req) + { + _rtw_memcpy(pstat->passoc_req, pframe, pkt_len); + pstat->assoc_req_len = pkt_len; + } + _exit_critical_bh(&pstat->lock, &irqL); + #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) +#else + rtw_indicate_sta_assoc_event(padapter, pstat); +#endif //CONFIG_IOCTL_CFG80211 + + //.3-(1) report sta add event + report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); + +/* + //issue assoc rsp before notify station join event. + if (frame_type == WIFI_ASSOCREQ) + issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); + else + issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); +*/ + +#endif + } + + return _SUCCESS; + +asoc_class2_error: + +#ifdef CONFIG_NATIVEAP_MLME + issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); +#endif + + return _FAIL; + +OnAssocReqFail: + + +#ifdef CONFIG_NATIVEAP_MLME + pstat->aid = 0; + if (frame_type == WIFI_ASSOCREQ) + issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); + else + issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); +#endif + + +#endif /* CONFIG_AP_MODE */ + + return _FAIL; + +} + +unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame) +{ + uint i; + int res; + unsigned short status; + PNDIS_802_11_VARIABLE_IEs pIE; + 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 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; + + DBG_871X("%s\n", __FUNCTION__); + + //check A1 matches or not + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) + return _SUCCESS; + + if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) + return _SUCCESS; + + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + return _SUCCESS; + + _cancel_timer_ex(&pmlmeext->link_timer); + + //status + if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0) + { + DBG_871X("assoc reject, status code: %d\n", status); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + res = -4; + goto report_assoc_result; + } + + //get capabilities + pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + //set slot time + pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20; + + //AID + res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff); + + //following are moved to join event callback function + //to handle HT, WMM, rate adaptive, update MAC reg + //for not to handle the synchronous IO in the tasklet + for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM + { + WMM_param_handler(padapter, pIE); + } +#if defined(CONFIG_P2P) && defined(CONFIG_WFD) + else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD + { + DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ ); + WFD_info_handler( padapter, pIE ); + } +#endif + break; + + case _HT_CAPABILITY_IE_: //HT caps + HT_caps_handler(padapter, pIE); + break; + + case _HT_EXTRA_INFO_IE_: //HT info + HT_info_handler(padapter, pIE); + break; + + case _ERPINFO_IE_: + ERP_IE_handler(padapter, pIE); + + default: + break; + } + + i += (pIE->Length + 2); + } + + pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + + //Update Basic Rate Table for spec, 2010-12-28 , by thomas + UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); + +#ifdef CONFIG_IOCTL_CFG80211 + if (!rtw_cfg80211_check_bss(padapter)) { + DBG_871X("rtw_cfg80211_check_bss() : BSS not found !!\n"); + res = -2; + goto report_assoc_result; + } +#endif + +report_assoc_result: + if (res > 0) { + rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); + } else { + rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); + } + + report_join_res(padapter, res); + return _SUCCESS; +} + +unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned short reason; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //check A3 + if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + +#ifdef CONFIG_P2P + if ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason); + +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr2Ptr(pframe))); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if(psta) + { + u8 updated; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, reason); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated); + } + + + return _SUCCESS; + } + else +#endif + { + int ignore_received_deauth = 0; + + // Commented by Albert 20130604 + // Before sending the auth frame to start the STA/GC mode connection with AP/GO, + // we will send the deauth first. + // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. + // Added the following code to avoid this case. + if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) || + ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) ) + { + if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ) + { + ignore_received_deauth = 1; + } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { + // TODO: 802.11r + ignore_received_deauth = 1; + } + } + + DBG_871X("%s, STA:" MAC_FMT ", ignore = %d\n", __FUNCTION__, MAC_ARG(GetAddr3Ptr(pframe)), ignore_received_deauth); + if ( 0 == ignore_received_deauth ) + { + receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason); + } + } + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + return _SUCCESS; + +} + +unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned short reason; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //check A3 + if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + +#ifdef CONFIG_P2P + if ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason); + +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr2Ptr(pframe))); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if(psta) + { + u8 updated; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, reason); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated); + } + + return _SUCCESS; + } + else +#endif + { + DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr3Ptr(pframe))); + + receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); + } + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + return _SUCCESS; + +} + +unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame) +{ + DBG_871X("%s\n", __FUNCTION__); + return _SUCCESS; +} + +unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len) +{ + unsigned int ret = _FAIL; + struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info); + + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { + ret = _SUCCESS; + goto exit; + } + + if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { + + int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1; + int ch_offset = -1; + u8 bwmode; + struct ieee80211_info_element *ie; + + DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n", + FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr)); + + for_each_ie(ie, ies, ies_len) { + if (ie->id == WLAN_EID_CHANNEL_SWITCH) { + ch_switch_mode = ie->data[0]; + ch = ie->data[1]; + ch_switch_cnt = ie->data[2]; + DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n", + ch_switch_mode, ch, ch_switch_cnt); + } + else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) { + ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]); + DBG_871X("ch_offset:%d\n", ch_offset); + } + } + + if (ch == -1) + return _SUCCESS; + + if (ch_offset == -1) + bwmode = mlmeext->cur_bwmode; + else + bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ? + HT_CHANNEL_WIDTH_20 : HT_CHANNEL_WIDTH_40; + + ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset; + + /* todo: + * 1. the decision of channel switching + * 2. things after channel switching + */ + + ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE); + } + +exit: + return ret; +} + +unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + u8 category; + u8 action; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + + if (!psta) + goto exit; + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) + goto exit; + + action = frame_body[1]; + switch (action) { + case RTW_WLAN_ACTION_SPCT_MSR_REQ: + case RTW_WLAN_ACTION_SPCT_MSR_RPRT: + case RTW_WLAN_ACTION_SPCT_TPC_REQ: + case RTW_WLAN_ACTION_SPCT_TPC_RPRT: + break; + case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: + #ifdef CONFIG_SPCT_CH_SWITCH + ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2], + frame_len-(frame_body-pframe)-2); + #endif + break; + default: + break; + } + +exit: + return ret; +} + +unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *addr; + struct sta_info *psta=NULL; + struct recv_reorder_ctrl *preorder_ctrl; + unsigned char *frame_body; + unsigned char category, action; + unsigned short tid, status, reason_code = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + struct sta_priv *pstapriv = &padapter->stapriv; + + //check RA matches or not + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode + return _SUCCESS; + +/* + //check A1 matches or not + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) + return _SUCCESS; +*/ + DBG_871X("%s\n", __FUNCTION__); + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + return _SUCCESS; + + addr = GetAddr2Ptr(pframe); + psta = rtw_get_stainfo(pstapriv, addr); + + if(psta==NULL) + return _SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack + { +#ifdef CONFIG_TDLS + if((psta->tdls_sta_state & TDLS_LINKED_STATE) && + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE) ) + { + //do nothing; just don't want to return _SUCCESS; + } + else +#endif //CONFIG_TDLS + if (!pmlmeinfo->HT_enable) + { + return _SUCCESS; + } + + action = frame_body[1]; + DBG_871X("%s, action=%d\n", __FUNCTION__, action); + switch (action) + { + case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request + + _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request)); + //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); + process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr); + + if(pmlmeinfo->bAcceptAddbaReq == _TRUE) + { + issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0); + } + else + { + issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);//reject ADDBA Req + } + + break; + + case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response + + //status = frame_body[3] | (frame_body[4] << 8); //endian issue + status = RTW_GET_LE16(&frame_body[3]); + tid = ((frame_body[5] >> 2) & 0x7); + + if (status == 0) + { //successful + DBG_871X("agg_enable for TID=%d\n", tid); + psta->htpriv.agg_enable_bitmap |= 1 << tid; + psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); + } + else + { + psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + } + + //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); + break; + + case RTW_WLAN_ACTION_DELBA: //DELBA + if ((frame_body[3] & BIT(3)) == 0) + { + psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); + psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); + + //reason_code = frame_body[4] | (frame_body[5] << 8); + reason_code = RTW_GET_LE16(&frame_body[4]); + } + else if((frame_body[3] & BIT(3)) == BIT(3)) + { + tid = (frame_body[3] >> 4) & 0x0F; + + preorder_ctrl = &psta->recvreorder_ctrl[tid]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + } + + DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code); + //todo: how to notify the host while receiving DELETE BA + break; + + default: + break; + } + } + + return _SUCCESS; +} + +#ifdef CONFIG_P2P + +static int get_reg_classes_full_count(struct p2p_channels channel_list) { + int cnt = 0; + int i; + + for (i = 0; i < channel_list.reg_classes; i++) { + cnt += channel_list.reg_class[i].channels; + } + + return cnt; +} + +static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt ) +{ + int i = 0; + + *p24g_cnt = 0; + *p5gl_cnt = 0; + *p5gh_cnt = 0; + + for( i = 0; i < pmlmeext->max_chan_nums; i++ ) + { + if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 ) + { + (*p24g_cnt)++; + } + else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) ) + { + // Just include the channel 36, 40, 44, 48 channels for 5G low + (*p5gl_cnt)++; + } + else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) ) + { + // Just include the channel 149, 153, 157, 161 channels for 5G high + (*p5gh_cnt)++; + } + } +} + +void issue_p2p_GO_request(_adapter *padapter, u8* raddr) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_REQ; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 wpsielen = 0, p2pielen = 0, i; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value + pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen)); + + + + // 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 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC ); + } + else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); + } + else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC ); + } + + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->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 20110306 + // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes + // 1. P2P Capability + // 2. Group Owner Intent + // 3. Configuration Timeout + // 4. Listen Channel + // 5. Extended Listen Timing + // 6. Intended P2P Interface Address + // 7. Channel List + // 8. P2P Device Info + // 9. Operating Channel + + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + 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: + // Todo the tie breaker bit. + 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 + + + // Listen Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_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->listen_channel; // listening channel number + + + // Extended Listen Timing ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + + // 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; + + // 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 + + // 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; + + + // 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 + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + + +void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_RESP; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + uint wpsielen = 0; + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh; + u16 len_channellist_attr = 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); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); + +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result ); + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame. + pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen)); + + // Commented by Albert 20110328 + // Try to get the device password ID from the WPS IE of group negotiation request frame + // WiFi Direct test plan 5.1.15 + rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); + rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + _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; + + // Commented by Kurt 20120113 + // If some device wants to do p2p handshake without sending prov_disc_req + // We have to get peer_req_cm from here. + if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) ) + { + if ( wps_devicepassword_id == WPS_DPID_USER_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + } + else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + } + else + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + } + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->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: + p2pie[ p2pielen++ ] = result; + + // 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, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_CONF; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 wpsielen = 0, p2pielen = 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); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->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 20110306 + // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes + // 1. Status + // 2. P2P Capability + // 3. Operating Channel + // 4. Channel List + // 5. Group ID ( if this WiFi is GO ) + + // P2P Status + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_STATUS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = result; + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + 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; + } + + + // 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; + + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ) + { + if ( pwdinfo->peer_operating_ch <= 14 ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x51; + } + else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x73; + } + else + { + // Operating Class + p2pie[ p2pielen++ ] = 0x7c; + } + + p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch; + } + else + { + 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; // Use the listen channel as the operating channel + } + + + // Channel List + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST; + + *(u16*) ( p2pie + p2pielen ) = 6; + p2pielen += 2; + + // 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; + + // Value: + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ) + { + if ( pwdinfo->peer_operating_ch <= 14 ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x51; + } + else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x73; + } + else + { + // Operating Class + p2pie[ p2pielen++ ] = 0x7c; + } + p2pie[ p2pielen++ ] = 1; + p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch; + } + else + { + 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++ ] = 1; + p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel + } + + 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, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_invitation_request(_adapter *padapter, u8* raddr ) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_INVIT_REQ; + u8 p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + u8 dialogToken = 3; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_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 + + 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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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 20101011 + // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes + // 1. Configuration Timeout + // 2. Invitation Flags + // 3. Operating Channel ( Only GO ) + // 4. P2P Group BSSID ( Should be included if I am the GO ) + // 5. Channel List + // 6. P2P Group ID + // 7. P2P Device Info + + // 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 + + // Invitation Flags + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT; + + + // 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->invitereq_info.operating_ch <= 14 ) + p2pie[ p2pielen++ ] = 0x51; + else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) ) + p2pie[ p2pielen++ ] = 0x73; + else + p2pie[ p2pielen++ ] = 0x7c; + + // Channel Number + p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number + + if ( _rtw_memcmp( myid( &padapter->eeprompriv ), pwdinfo->invitereq_info.go_bssid, ETH_ALEN ) ) + { + // 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, pwdinfo->invitereq_info.go_bssid, 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 + + + // P2P Group ID + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen ); + p2pielen += 2; + + // Value: + // P2P Device Address for GO + _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN ); + p2pielen += ETH_ALEN; + + // SSID + _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen ); + p2pielen += pwdinfo->invitereq_info.ssidlen; + + + // 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( WPS_CONFIG_METHOD_DISPLAY ); + 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; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_INVIT_RESP; + u8 p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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: + // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. + // Sent the event receiving the P2P Invitation Req frame to DMP UI. + // DMP had to compare the MAC address to find out the profile. + // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. + // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req + // to NB to rebuild the persistent group. + p2pie[ p2pielen++ ] = status_code; + + // 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 + + 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 + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr ) +{ + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = 1; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_REQ; + u8 wpsie[ 100 ] = { 0x00 }; + u8 wpsielen = 0; + u32 p2pielen = 0; +#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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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, pdev_raddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr ); + + pframe += p2pielen; + pattrib->pktlen += p2pielen; + + 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 + + // 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->tx_prov_disc_info.wps_config_method_request ); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + + +u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo ) +{ + u8 i, match_result = 0; + + DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]); + + for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ ) + { + DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]); + if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) ) + { + match_result = 1; + DBG_871X( "[%s] Match!\n", __FUNCTION__ ); + break; + } + } + + return (match_result ); +} + +void issue_probersp_p2p(_adapter *padapter, unsigned char *da) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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; +#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 + + //DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; + + mac = myid(&(padapter->eeprompriv)); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, da, 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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = pattrib->hdrlen; + pframe += pattrib->hdrlen; + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); + pframe += 2; + pattrib->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; + pattrib->pktlen += 2; + + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen); + +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && 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); + pattrib->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); + pattrib->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_RTK_WIDI ); + wpsielen += 2; + + // OUI + *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI ); + wpsielen += 4; + + // Sub Category ID + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP ); + 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, &pattrib->pktlen ); + + + p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe); + pframe += p2pielen; + pattrib->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; + pattrib->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); + pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len; + pframe += pmlmepriv->wfd_probe_resp_ie_len; + } +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac; + unsigned char bssrate[NumRates]; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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}; + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u16 wpsielen = 0, p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //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; + + mac = myid(&(padapter->eeprompriv)); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + if (da) { + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN); + } else { + if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) ) + { + // This two flags will be set when this is only the P2P client mode. + _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); + } + else + { + // broadcast probe request frame + _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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_PROBEREQ); + + pframe += sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen)); + } + else + { + pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen)); + } + // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); + +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL ) + { + //WPS IE + _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; + pframe += pmlmepriv->wps_probe_req_ie_len; + + //P2P IE + _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len; + pframe += pmlmepriv->p2p_probe_req_ie_len; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + + // WPS IE + // Noted by Albert 20110221 + // 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 + + if( pmlmepriv->wps_probe_req_ie == NULL ) + { + // 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; + + // 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; + } + + // 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; + + // 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 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: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110221 + // According to the P2P Specification, the probe request frame should contain 5 P2P attributes + // 1. P2P Capability + // 2. P2P Device ID if this probe request wants to find the specific P2P device + // 3. Listen Channel + // 4. Extended Listen Timing + // 5. Operating Channel if this WiFi is working as the group owner now + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + // Listen Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_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->listen_channel; // listen channel + + + // Extended Listen Timing + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) ) + { + // Operating Channel (if this WiFi is working as the group owner now) + // 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 + + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + + if( pmlmepriv->wps_probe_req_ie != NULL ) + { + //WPS IE + _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; + pframe += pmlmepriv->wps_probe_req_ie_len; + } + } + +#ifdef CONFIG_WFD +#ifdef CONFIG_IOCTL_CFG80211 + if ( _TRUE == pwdinfo->wfd_info->wfd_enable ) +#endif + { + wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } +#ifdef CONFIG_IOCTL_CFG80211 + else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0) + { + //WFD IE + _rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len; + pframe += pmlmepriv->wfd_probe_req_ie_len; + } +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz)); + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +inline void issue_probereq_p2p(_adapter *adapter, u8 *da) +{ + _issue_probereq_p2p(adapter, da, _FALSE); +} + +int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + + do + { + ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE); + + i++; + + if (adapter->bDriverStopped || adapter->bSurpriseRemoved) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((iu.hdr.adapter; + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + u8 *frame = recv_frame->u.hdr.rx_data; + u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | + (recv_frame->u.hdr.attrib.frag_num & 0xf); + + if (GetRetry(frame)) { + if (token >= 0) { + if ((seq_ctrl == mlmeext->action_public_rxseq) + && (token == mlmeext->action_public_dialog_token)) + { + DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n", + FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token); + return _FAIL; + } + } else { + if (seq_ctrl == mlmeext->action_public_rxseq) { + DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n", + FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq); + return _FAIL; + } + } + } + + mlmeext->action_public_rxseq = seq_ctrl; + + if (token >= 0) + mlmeext->action_public_dialog_token = token; + + return _SUCCESS; +} + +unsigned int on_action_public_p2p(union recv_frame *precv_frame) +{ + _adapter *padapter = precv_frame->u.hdr.adapter; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 *frame_body; + u8 dialogToken=0; +#ifdef CONFIG_P2P + u8 *p2p_ie; + u32 p2p_ielen, wps_ielen; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 result = P2P_STATUS_SUCCESS; + u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 *merged_p2pie = NULL; + u32 merged_p2p_ielen = 0; +#endif //CONFIG_P2P + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + dialogToken = frame_body[7]; + + if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) + return _FAIL; + +#ifdef CONFIG_P2P + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) + { + rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len); + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + // Do nothing if the driver doesn't enable the P2P function. + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + return _SUCCESS; + + len -= sizeof(struct rtw_ieee80211_hdr_3addr); + + switch( frame_body[ 6 ] )//OUI Subtype + { + case P2P_GO_NEGO_REQ: + { + DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) + { + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + } + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + // Commented by Albert 20110526 + // In this case, this means the previous nego fail doesn't be reset yet. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + // Restore the previous p2p state + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + } +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Kurt 20110902 + //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + + // Commented by Kurt 20120113 + // Get peer_dev_addr here if peer doesn't issue prov_disc frame. + if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) ); + _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); + + result = process_p2p_group_negotation_req( pwdinfo, frame_body, len ); + issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result ); +#ifdef CONFIG_INTEL_WIDI + if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) ) + { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL); + } +#endif //CONFIG_INTEL_WIDI + + // Commented by Albert 20110718 + // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. +#ifdef CONFIG_CONCURRENT_MODE + // Commented by Albert 20120107 + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); +#else // CONFIG_CONCURRENT_MODE + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); +#endif // CONFIG_CONCURRENT_MODE + break; + } + case P2P_GO_NEGO_RESP: + { + DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + // Commented by Albert 20110425 + // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + pwdinfo->nego_req_info.benable = _FALSE; + result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len); + issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result); + if ( P2P_STATUS_SUCCESS == result ) + { + if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT ) + { + pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch; + #ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1; + pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6; + pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11; + #endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH ); + } + } + + // Reset the dialog token for group negotiation frames. + pwdinfo->negotiation_dialog_token = 1; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); + } + } + else + { + DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__); + } + + break; + } + case P2P_GO_NEGO_CONF: + { + DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__); + result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len); + if ( P2P_STATUS_SUCCESS == result ) + { + if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT ) + { + pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch; + #ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1; + pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6; + pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11; + #endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH ); + } + } + break; + } + case P2P_INVIT_REQ: + { + // Added by Albert 2010/10/05 + // Received the P2P Invite Request frame. + + DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ ); + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + // Parse the necessary information from the P2P Invitation Request frame. + // For example: The MAC address of sending this P2P Invitation Request frame. + u32 attr_contentlen = 0; + u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + struct group_id_info group_id; + u8 invitation_flag = 0; + + merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_); + + merged_p2pie = rtw_malloc(merged_p2p_ielen); + if (merged_p2pie == NULL) + { + DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__); + goto exit; + } + _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen); + + merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie); + + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen); + if ( attr_contentlen ) + { + + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen); + // Commented by Albert 20120510 + // Copy to the pwdinfo->p2p_peer_interface_addr. + // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. + // #> iwpriv wlan0 p2p_get peer_ifa + // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. + + if ( attr_contentlen ) + { + DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], + pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3], + pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] ); + } + + if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT ) + { + // Re-invoke the persistent group. + + _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) ); + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen); + if ( attr_contentlen ) + { + if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) ) + { + // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO ); + status_code = P2P_STATUS_SUCCESS; + } + else + { + // The p2p device sending this p2p invitation request wants to be the persistent GO. + if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) ) + { + u8 operatingch_info[5] = { 0x00 }; + + if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 ) + { + // The operating channel is acceptable for this device. + pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4]; + #ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1; + pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6; + pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11; + #endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + status_code = P2P_STATUS_SUCCESS; + } + else + { + // The operating channel isn't supported by this device. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE ); + status_code = P2P_STATUS_FAIL_NO_COMMON_CH; + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); + } + } + else + { + // Commented by Albert 20121130 + // Intel will use the different P2P IE to store the operating channel information + // Workaround for Intel WiDi 3.5 + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + status_code = P2P_STATUS_SUCCESS; + } + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + #ifdef CONFIG_INTEL_WIDI + _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + #endif //CONFIG_INTEL_WIDI + + status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; + } + } + } + else + { + DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + } + else + { + // Received the invitation to join a P2P group. + + _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) ); + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen); + if ( attr_contentlen ) + { + if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) ) + { + // In this case, the GO can't be myself. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + else + { + // The p2p device sending this p2p invitation request wants to join an existing P2P group + // Commented by Albert 2012/06/28 + // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. + // The peer device address should be the destination address for the provisioning discovery request. + // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. + // The peer interface address should be the address for WPS mac address + _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN ); + status_code = P2P_STATUS_SUCCESS; + } + } + else + { + DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + } + } + else + { + DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + + DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code ); + + pwdinfo->inviteresp_info.token = frame_body[ 7 ]; + issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code ); + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); + } +#ifdef CONFIG_INTEL_WIDI + if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) ) + { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL); + } +#endif //CONFIG_INTEL_WIDI + break; + } + case P2P_INVIT_RESP: + { + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + + DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + pwdinfo->invitereq_info.benable = _FALSE; + + if ( attr_content == P2P_STATUS_SUCCESS ) + { + if ( _rtw_memcmp( pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv ), ETH_ALEN )) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO ); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK ); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + + if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); + } + break; + } + case P2P_DEVDISC_REQ: + + process_p2p_devdisc_req(pwdinfo, pframe, len); + + break; + + case P2P_DEVDISC_RESP: + + process_p2p_devdisc_resp(pwdinfo, pframe, len); + + break; + + case P2P_PROVISION_DISC_REQ: + DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ ); + process_p2p_provdisc_req(pwdinfo, pframe, len); + _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); + + //20110902 Kurt + //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ); + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); +#ifdef CONFIG_INTEL_WIDI + if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) ) + { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL); + } +#endif //CONFIG_INTEL_WIDI + break; + + case P2P_PROVISION_DISC_RESP: + // Commented by Albert 20110707 + // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? + DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ ); + // Commented by Albert 20110426 + // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP); + process_p2p_provdisc_resp(pwdinfo, pframe); + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); + break; + + } + } +#endif //CONFIG_P2P + +exit: + + if(merged_p2pie) + { + rtw_mfree(merged_p2pie, merged_p2p_ielen); + } + + return _SUCCESS; +} + +unsigned int on_action_public_vendor(union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + + if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) { + ret = on_action_public_p2p(precv_frame); + } + + return ret; +} + +unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 token; + _adapter *adapter = precv_frame->u.hdr.adapter; + int cnt = 0; + char msg[64]; + + token = frame_body[2]; + + if (rtw_action_public_decache(precv_frame, token) == _FAIL) + goto exit; + + #ifdef CONFIG_IOCTL_CFG80211 + cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token); + rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg); + #endif + + ret = _SUCCESS; + +exit: + return ret; +} + +unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 category, action; + + /* check RA matches or not */ + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN)) + goto exit; + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_PUBLIC) + goto exit; + + action = frame_body[1]; + switch (action) { + case ACT_PUBLIC_VENDOR: + ret = on_action_public_vendor(precv_frame); + break; + default: + ret = on_action_public_default(precv_frame, action); + break; + } + +exit: + return ret; +} + +unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +#ifdef CONFIG_IEEE80211W +unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *pframe = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned short tid; + //Baron + + DBG_871X("OnAction_sa_query\n"); + + switch (pframe[WLAN_HDR_A3_LEN+1]) + { + case 0: //SA Query req + _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short)); + DBG_871X("OnAction_sa_query request,action=%d, tid=%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid); + issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid); + break; + + case 1: //SA Query rsp + _cancel_timer_ex(&pmlmeext->sa_query_timer); + DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]); + break; + default: + break; + } + if(0) + { + int pp; + printk("pattrib->pktlen = %d =>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", pframe[pp]); + printk("\n"); + } + + return _SUCCESS; +} +#endif //CONFIG_IEEE80211W + +unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_P2P + u8 *frame_body; + u8 category, OUI_Subtype, dialogToken=0; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X("%s\n", __FUNCTION__); + + //check RA matches or not + if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode + return _SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_P2P) + return _SUCCESS; + + if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI ) + return _SUCCESS; + +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + rtw_cfg80211_rx_action_p2p(padapter, pframe, len); + return _SUCCESS; + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + len -= sizeof(struct rtw_ieee80211_hdr_3addr); + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + + switch(OUI_Subtype) + { + case P2P_NOTICE_OF_ABSENCE: + + break; + + case P2P_PRESENCE_REQUEST: + + process_p2p_presence_req(pwdinfo, pframe, len); + + break; + + case P2P_PRESENCE_RESPONSE: + + break; + + case P2P_GO_DISC_REQUEST: + + break; + + default: + break; + + } + } +#endif //CONFIG_P2P + + return _SUCCESS; + +} + +unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame) +{ + int i; + unsigned char category; + struct action_handler *ptable; + unsigned char *frame_body; + u8 *pframe = precv_frame->u.hdr.rx_data; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + + for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++) + { + ptable = &OnAction_tbl[i]; + + if(category == ptable->num) + ptable->func(padapter, precv_frame); + + } + + return _SUCCESS; + +} + +unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame) +{ + + //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); + return _SUCCESS; +} + +struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once) +{ + struct xmit_frame *pmgntframe; + struct xmit_buf *pxmitbuf; + + if (once) + pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv); + else + pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once); + goto exit; + } + + if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) { + DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter)); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pmgntframe = NULL; + goto exit; + } + + pmgntframe->frame_tag = MGNT_FRAMETAG; + pmgntframe->pxmitbuf = pxmitbuf; + pmgntframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pmgntframe; + +exit: + return pmgntframe; + +} + +inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) +{ + return _alloc_mgtxmitframe(pxmitpriv, _FALSE); +} + +inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv) +{ + return _alloc_mgtxmitframe(pxmitpriv, _TRUE); +} + + +/**************************************************************************** + +Following are some TX fuctions for WiFi MLME + +*****************************************************************************/ + +void update_mgnt_tx_rate(_adapter *padapter, u8 rate) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + pmlmeext->tx_rate = rate; + + //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate); +} + +void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + _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->pktlen = 0; + + if(pmlmeext->cur_wireless_mode & WIRELESS_11B) + pattrib->raid = 6;//b mode + else + pattrib->raid = 5;//a/g mode + + pattrib->encrypt = _NO_PRIVACY_; + pattrib->bswenc = _FALSE; + + pattrib->qos_en = _FALSE; + pattrib->ht_en = _FALSE; + pattrib->bwmode = HT_CHANNEL_WIDTH_20; + pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pattrib->sgi = _FALSE; + + pattrib->seqnum = pmlmeext->mgnt_seq; + + pattrib->retry_ctrl = _TRUE; + +} + +void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + if(padapter->bSurpriseRemoved == _TRUE || + padapter->bDriverStopped == _TRUE) + { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return; + } + + rtw_hal_mgnt_xmit(padapter, pmgntframe); +} + +s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) +{ + s32 ret = _FAIL; + _irqL irqL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; + struct submit_ctx sctx; + + if(padapter->bSurpriseRemoved == _TRUE || + padapter->bDriverStopped == _TRUE) + { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return ret; + } + + rtw_sctx_init(&sctx, timeout_ms); + pxmitbuf->sctx = &sctx; + + ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); + + if (ret == _SUCCESS) + ret = rtw_sctx_wait(&sctx); + + _enter_critical(&pxmitpriv->lock_sctx, &irqL); + pxmitbuf->sctx = NULL; + _exit_critical(&pxmitpriv->lock_sctx, &irqL); + + return ret; +} + +s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe) +{ +#ifdef CONFIG_XMIT_ACK + s32 ret = _FAIL; + u32 timeout_ms = 500;// 500ms + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + #ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter && !padapter->isprimary) + pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv); + #endif + + if(padapter->bSurpriseRemoved == _TRUE || + padapter->bDriverStopped == _TRUE) + { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return -1; + } + + _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); + pxmitpriv->ack_tx = _TRUE; + + pmgntframe->ack_report = 1; + if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { + ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); + } + + pxmitpriv->ack_tx = _FALSE; + _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); + + return ret; +#else //!CONFIG_XMIT_ACK + dump_mgntframe(padapter, pmgntframe); + rtw_msleep_os(50); + return _SUCCESS; +#endif //!CONFIG_XMIT_ACK +} + +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; +} + +void issue_beacon(_adapter *padapter) +{ + 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); +#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_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 + + + //DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__); + return; + } +#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) + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->qsel = 0x10; + + _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, 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); + pattrib->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(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && 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; + pattrib->pktlen += wps_offset; + + _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len); + pframe += pmlmepriv->wps_beacon_ie_len; + pattrib->pktlen += pmlmepriv->wps_beacon_ie_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->pktlen += remainder_ielen; + } + else + { + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pattrib->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); + pattrib->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; + pattrib->pktlen += insert_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->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); + pattrib->pktlen += (cur_network->IELength+len_diff); + } + + { + 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); + } + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + u32 len; +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && 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; + pattrib->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; + pattrib->pktlen += len; +#endif //CONFIG_WFD + } +#endif //CONFIG_P2P + + goto _issue_bcn; + + } + + //below for ad-hoc mode + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // capability info: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->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), &pattrib->pktlen); + + //ERP IE + pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); + } + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->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) + + if ((pattrib->pktlen + TXDESC_SIZE) > 512) + { + DBG_871X("beacon frame too large\n"); + return; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz); + + dump_mgntframe(padapter, pmgntframe); + +} + +void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac, *bssid; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + u8 *pwps_ie; + uint wps_ielen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + unsigned int rate_len; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD +#endif //CONFIG_P2P + + //DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__); + return; + } + + + //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; + + mac = myid(&(padapter->eeprompriv)); + bssid = cur_network->MacAddress; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = pattrib->hdrlen; + pframe += pattrib->hdrlen; + + + if(cur_network->IELength>MAX_IE_SZ) + return; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen); + + //inerset & update wps_probe_resp_ie + if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0)) + { + uint wps_offset, remainder_ielen; + u8 *premainder_ie; + + wps_offset = (uint)(pwps_ie - cur_network->IEs); + + premainder_ie = pwps_ie + wps_ielen; + + remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; + + _rtw_memcpy(pframe, cur_network->IEs, wps_offset); + pframe += wps_offset; + pattrib->pktlen += wps_offset; + + wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len + if((wps_offset+wps_ielen+2)<=MAX_IE_SZ) + { + _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2); + pframe += wps_ielen+2; + pattrib->pktlen += wps_ielen+2; + } + + if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ) + { + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->pktlen += remainder_ielen; + } + } + else + { + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pattrib->pktlen += cur_network->IELength; + } + + /* retrieve SSID IE from cur_network->Ssid */ + { + u8 *ssid_ie; + sint ssid_ielen; + sint ssid_ielen_diff; + u8 buf[MAX_IE_SZ]; + u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr); + + ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen, + (pframe-ies)-_FIXED_IE_LENGTH_); + + ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen; + + if (ssid_ie && cur_network->Ssid.SsidLength) { + uint remainder_ielen; + u8 *remainder_ie; + remainder_ie = ssid_ie+2; + remainder_ielen = (pframe-remainder_ie); + + LOG_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter)); + if (remainder_ielen > MAX_IE_SZ) { + remainder_ielen = MAX_IE_SZ; + } + + _rtw_memcpy(buf, remainder_ie, remainder_ielen); + _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen); + *(ssid_ie+1) = cur_network->Ssid.SsidLength; + _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength); + + pframe += ssid_ielen_diff; + pattrib->pktlen += ssid_ielen_diff; + } + } + } + else +#endif + { + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // capability info: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + //below for ad-hoc mode + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->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), &pattrib->pktlen); + + //ERP IE + pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); + } + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); + } + + + //todo:HT for adhoc + + } + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /*&& is_valid_p2p_probereq*/) + { + u32 len; +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() + len = pmlmepriv->p2p_go_probe_resp_ie_len; + if(pmlmepriv->p2p_go_probe_resp_ie && len>0) + _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len); + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + len = build_probe_resp_p2p_ie(pwdinfo, pframe); + } + + pframe += len; + pattrib->pktlen += len; + +#ifdef CONFIG_WFD +#ifdef CONFIG_IOCTL_CFG80211 + if(_TRUE == pwdinfo->wfd_info->wfd_enable) +#endif //CONFIG_IOCTL_CFG80211 + { + len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0); + } +#ifdef CONFIG_IOCTL_CFG80211 + else + { + len = 0; + if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0) + { + len = pmlmepriv->wfd_probe_resp_ie_len; + _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len); + } + } +#endif //CONFIG_IOCTL_CFG80211 + pframe += len; + pattrib->pktlen += len; +#endif //CONFIG_WFD + + } +#endif //CONFIG_P2P + + +#ifdef CONFIG_AUTO_AP_MODE +{ + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("(%s)\n", __FUNCTION__); + + //check rc station + psta = rtw_get_stainfo(pstapriv, da); + if (psta && psta->isrc && psta->pid>0) + { + u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A}; + u8 RC_INFO[14] = {0}; + //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] + u16 cu_ch = (u16)cur_network->Configuration.DSConfig; + + DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__, + psta->pid, MAC_ARG(psta->hwaddr), cu_ch); + + //append vendor specific ie + _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI)); + _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN); + _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2); + _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2); + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen); + } +} +#endif //CONFIG_AUTO_AP_MODE + + + pattrib->last_txcmdsz = pattrib->pktlen; + + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + 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}; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n")); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //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; + + mac = myid(&(padapter->eeprompriv)); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + if (da) + { + // unicast probe request frame + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN); + } + else + { + // broadcast probe request frame + _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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_PROBEREQ); + + pframe += sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + if(pssid) + pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); + else + pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen)); + + get_rate_set(padapter, bssrate, &bssrate_len); + + 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 + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + +#if 0 + //add wps_ie for wps2.0 + if(pmlmepriv->probereq_wpsie_len>0 && pmlmepriv->probereq_wpsie_lenprobereq_wpsie, pmlmepriv->probereq_wpsie_len); + pframe += pmlmepriv->probereq_wpsie_len; + pattrib->pktlen += pmlmepriv->probereq_wpsie_len; + //pmlmepriv->probereq_wpsie_len = 0 ;//reset to zero + } +#else + //add wps_ie for wps2.0 + if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) + { + _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); + pframe += pmlmepriv->wps_probe_req_ie_len; + pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; + //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero + } +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz)); + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da) +{ + _issue_probereq(padapter, pssid, da, _FALSE); +} + +int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, + int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + + do + { + ret = _issue_probereq(padapter, pssid, da, 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((ixmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_AUTH); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + + if(psta)// for AP mode + { +#ifdef CONFIG_NATIVEAP_MLME + + _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + + // setting auth algo number + val16 = (u16)psta->authalg; + + if(status != _STATS_SUCCESSFUL_) + val16 = 0; + + if (val16) { + val16 = cpu_to_le16(val16); + use_shared_key = 1; + } + + pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting auth seq number + val16 =(u16)psta->auth_seq; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting status code... + val16 = status; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // added challenging text... + if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen)); + } +#endif + } + else + { + _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); + + // setting auth algo number + val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key + if (val16) { + val16 = cpu_to_le16(val16); + use_shared_key = 1; + } + //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); + + //setting IV for auth seq #3 + if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); + val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); + val32 = cpu_to_le32(val32); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen)); + + pattrib->iv_len = 4; + } + + pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting auth seq number + val16 = pmlmeinfo->auth_seq; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + + // setting status code... + val16 = status; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // then checking to see if sending challenging text... + if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen)); + + SetPrivacy(fctrl); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pattrib->encrypt = _WEP40_; + + pattrib->icv_len = 4; + + pattrib->pktlen += pattrib->icv_len; + + } + + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + rtw_wep_encrypt(padapter, (u8 *)pmgntframe); + + dump_mgntframe(padapter, pmgntframe); + + return; +} + + +void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) +{ +#ifdef CONFIG_AP_MODE + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + unsigned char *pbuf, *pframe; + unsigned short val; + unsigned short *fctrl; + 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); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + u8 *ie = pnetwork->IEs; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD +#endif //CONFIG_P2P + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); + _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) + SetFrameSubType(pwlanhdr, pkt_type); + else + return; + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen += pattrib->hdrlen; + pframe += pattrib->hdrlen; + + //capability + val = *(unsigned short *)rtw_get_capability_from_ie(ie); + + pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen)); + + status = cpu_to_le16(status); + pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen)); + + val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); + pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen)); + + if (pstat->bssratelen <= 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen)); + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen)); + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen)); + } + +#ifdef CONFIG_80211N_HT + if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) + { + uint ie_len=0; + + //FILL HT CAP INFO IE + //p = hostapd_eid_ht_capabilities_info(hapd, p); + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + + //FILL HT ADD INFO IE + //p = hostapd_eid_ht_operation(hapd, p); + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + + } +#endif + + //FILL WMM IE + if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) + { + uint ie_len=0; + unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + + for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2)) + { + pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6)) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + + break; + } + + if ((pbuf == NULL) || (ie_len == 0)) + { + break; + } + } + + } + + + if (pmlmeinfo->assoc_AP_vendor == realtekAP) + { + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen)); + } + + //add WPS IE ie for wps 2.0 + if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0) + { + _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); + + pframe += pmlmepriv->wps_assoc_resp_ie_len; + pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; + } + +#ifdef CONFIG_P2P + if( padapter->wdinfo.driver_interface == DRIVER_WEXT ) + { + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) + { + u32 len; + + len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code); + + pframe += len; + pattrib->pktlen += len; + } + } +#ifdef CONFIG_WFD + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) +#ifdef CONFIG_IOCTL_CFG80211 + && (_TRUE == pwdinfo->wfd_info->wfd_enable) +#endif //CONFIG_IOCTL_CFG80211 + ) + { + wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } +#endif //CONFIG_WFD +#endif //CONFIG_P2P + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +#endif +} + +void issue_assocreq(_adapter *padapter) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe, *p; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned short val16; + unsigned int i, j, ie_len, index=0; + unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates]; + PNDIS_802_11_VARIABLE_IEs pIE; + struct registry_priv *pregpriv = &padapter->registrypriv; + 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, sta_bssrate_len = 0; + u8 cbw40_enable = 0; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 p2pie[ 255 ] = { 0x00 }; + u16 p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif //CONFIG_WFD +#endif //CONFIG_P2P + +#ifdef CONFIG_DFS + u16 cap; + u8 pow_cap_ele[2] = { 0x00 }; + u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel +#endif //CONFIG_DFS + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + //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, 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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_ASSOCREQ); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + //caps + +#ifdef CONFIG_DFS + _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + if(pmlmeext->cur_channel > 14) + cap |= BIT(8); //Spectrum Mgmt. Enabled + _rtw_memcpy(pframe, &cap, 2); +#else + _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); +#endif //CONFIG_DFS + + pframe += 2; + pattrib->pktlen += 2; + + //listen interval + //todo: listen interval for power saving + val16 = cpu_to_le16(3); + _rtw_memcpy(pframe ,(unsigned char *)&val16, 2); + pframe += 2; + pattrib->pktlen += 2; + + //SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen)); + + //supported rate & extended supported rate + +#if 1 // Check if the AP's supported rates are also supported by STA. + get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); + //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len); + + if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK) + { + sta_bssrate_len = 4; + } + + + //for (i = 0; i < sta_bssrate_len; i++) { + // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); + //} + + for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { + if (pmlmeinfo->network.SupportedRates[i] == 0) break; + DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]); + } + + + for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { + if (pmlmeinfo->network.SupportedRates[i] == 0) break; + + + // Check if the AP's supported rates are also supported by STA. + for (j=0; j < sta_bssrate_len; j++) { + // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP + if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK) + == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) { + //DBG_871X("match i = %d, j=%d\n", i, j); + break; + } else { + //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); + } + } + + if (j == sta_bssrate_len) { + // the rate is not supported by STA + DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]); + } else { + // the rate is supported by STA + bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; + } + } + + bssrate_len = index; + DBG_871X("bssrate_len = %d\n", bssrate_len); + +#else // Check if the AP's supported rates are also supported by STA. +#if 0 + get_rate_set(padapter, bssrate, &bssrate_len); +#else + for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) { + if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break; + + if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP + break; + + bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len]; + } +#endif +#endif // Check if the AP's supported rates are also supported by STA. + + if (bssrate_len == 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) + { + 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 + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + +#ifdef CONFIG_DFS + if(pmlmeext->cur_channel > 14) + { + pow_cap_ele[0] = 13; // Minimum transmit power capability + pow_cap_ele[1] = 21; // Maximum transmit power capability + pframe = rtw_set_ie(pframe, _POW_CAP_IE_, 2, pow_cap_ele, &(pattrib->pktlen)); + + //supported channels + do{ + if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 ) + { + sup_ch[0] = 1; //First channel number + sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel + } + else + { + sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; + sup_ch[idx_5g++] = 1; + } + sup_ch_idx++; + } + while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 ); + pframe = rtw_set_ie(pframe, _SUPPORTED_CH_IE_, idx_5g, sup_ch, &(pattrib->pktlen)); + } +#endif //CONFIG_DFS + + //RSN + p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if (p != NULL) + { + pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen)); + } + +#ifdef CONFIG_80211N_HT + //HT caps + if(padapter->mlmepriv.htpriv.ht_option==_TRUE) + { + p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if ((p != NULL) && (!(is_ap_in_tkip(padapter)))) + { + _rtw_memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element)); + + //to disable 40M Hz support while gd_bw_40MHz_en = 0 + if( pmlmeext->cur_channel > 14) + { + if(pregpriv->cbw40_enable & BIT(1) ) + cbw40_enable=1; + } + else + if(pregpriv->cbw40_enable & BIT(0) ) + cbw40_enable=1; + + if (cbw40_enable == 0) + { + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1))); + } + else + { + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1); + } + + //todo: disable SM power save mode + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + //switch (pregpriv->rf_config) + switch(rf_type) + { + case RF_1T1R: + + if(pregpriv->rx_stbc) + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream + + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16); + break; + + case RF_2T2R: + case RF_1T2R: + default: + + + if(pregpriv->special_rf_path) + { + if(pregpriv->rx_stbc) + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16); + break; + } + + if((pregpriv->rx_stbc == 0x3) ||//enable for 2.4/5 GHz + ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || //enable for 2.4GHz + ((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || //enable for 5GHz + (pregpriv->wifi_spec==1)) + { + DBG_871X("declare supporting RX STBC\n"); + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);//RX STBC two spatial stream + } + #ifdef CONFIG_DISABLE_MCS13TO15 + if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1)) + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16); + else + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16); + #else //CONFIG_DISABLE_MCS13TO15 + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16); + #endif //CONFIG_DISABLE_MCS13TO15 + break; + } +#ifdef RTL8192C_RECONFIG_TO_1T1R + { + if(pregpriv->rx_stbc) + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream + + _rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16); + } +#endif + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info); + pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen)); + + } + } +#endif + + //vendor specific IE, such as WPA, WMM, WPS + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) || + (_rtw_memcmp(pIE->data, WMM_OUI, 4)) || + (_rtw_memcmp(pIE->data, WPS_OUI, 4))) + { + if(!padapter->registrypriv.wifi_spec) + { + //Commented by Kurt 20110629 + //In some older APs, WPS handshake + //would be fail if we append vender extensions informations to AP + if(_rtw_memcmp(pIE->data, WPS_OUI, 4)){ + pIE->Length=14; + } + } + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen)); + } + break; + + default: + break; + } + + i += (pIE->Length + 2); + } + + if (pmlmeinfo->assoc_AP_vendor == realtekAP) + { + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen)); + } + +#ifdef CONFIG_P2P + +#ifdef CONFIG_IOCTL_CFG80211 + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0) + { + _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len); + pframe += pmlmepriv->p2p_assoc_req_ie_len; + pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + // Should add the P2P IE in the association request frame. + // P2P OUI + + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20101109 + // According to the P2P Specification, the association request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Extended Listen Timing + // 3. Device Info + // Commented by Albert 20110516 + // 4. P2P Interface + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + // Extended Listen Timing + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // 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. + if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) || + ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) ) + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); + } + else + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC ); + } + + 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; + + // P2P Interface + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D ); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address + p2pielen += ETH_ALEN; + + p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count + + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List + p2pielen += ETH_ALEN; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + //wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe); + //pframe += wfdielen; + //pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + } + } + +#endif //CONFIG_P2P + +#ifdef CONFIG_WFD +#ifdef CONFIG_IOCTL_CFG80211 + if ( _TRUE == pwdinfo->wfd_info->wfd_enable ) +#endif //CONFIG_IOCTL_CFG80211 + { + wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } +#ifdef CONFIG_IOCTL_CFG80211 + else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0) + { + //WFD IE + _rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len); + pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len; + pframe += pmlmepriv->wfd_assoc_req_ie_len; + } +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + + ret = _SUCCESS; + +exit: + if (ret == _SUCCESS) + rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); + else + rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); + + return; +} + +//when wait_ack is ture, this function shoule be called at process context +static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct xmit_priv *pxmitpriv; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + + //DBG_871X("%s:%d\n", __FUNCTION__, power_mode); + + if(!padapter) + goto exit; + + pxmitpriv = &(padapter->xmitpriv); + pmlmeext = &(padapter->mlmeextpriv); + pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _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; + + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + SetFrDs(fctrl); + } + else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + SetToDs(fctrl); + } + + if (power_mode) + { + SetPwrMgt(fctrl); + } + + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if(wait_ack) + { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } + else + { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + + +//when wait_ms >0 , this function shoule be called at process context +//da == NULL for station mode +int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + /* da == NULL, assum it's null data for sta to ap*/ + if (da == NULL) + da = get_my_bssid(&(pmlmeinfo->network)); + + do + { + ret = _issue_nulldata(padapter, da, power_mode, 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((ixmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + + pattrib->hdrlen +=2; + pattrib->qos_en = _TRUE; + pattrib->eosp = 1; + pattrib->ack_policy = 0; + pattrib->mdata = 0; + + _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; + + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + SetFrDs(fctrl); + } + else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + SetToDs(fctrl); + } + + if(pattrib->mdata) + SetMData(fctrl); + + qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); + + SetPriority(qc, tid); + + SetEOSP(qc, pattrib->eosp); + + SetAckpolicy(qc, pattrib->ack_policy); + + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if(wait_ack) + { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } + else + { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +//when wait_ms >0 , this function shoule be called at process context +//da == NULL for station mode +int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + /* da == NULL, assum it's null data for sta to ap*/ + if (da == NULL) + da = get_my_bssid(&(pmlmeinfo->network)); + + do + { + ret = _issue_qos_nulldata(padapter, da, tid, 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((ixmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int ret = _FAIL; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + +#ifdef CONFIG_P2P + if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_DEAUTH); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(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; + } + +exit: + return ret; +} + +int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason) +{ + DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + return _issue_deauth(padapter, da, reason, _FALSE); +} + +int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt, + int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + + do + { + ret = _issue_deauth(padapter, da, reason, 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((ixmitpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return; + + //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, ra, ETH_ALEN); /* RA */ + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */ + _rtw_memcpy(pwlanhdr->addr3, ra, 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 */ + { + u8 category, action; + category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT; + action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH; + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + } + + pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0); + pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen), + hal_ch_offset_to_secondary_ch_offset(ch_offset)); + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +#ifdef CONFIG_IEEE80211W +void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid) +{ + u8 category = RTW_WLAN_CATEGORY_SA_QUERY; + u16 reason_code; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__); + return; + } + + //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; + + if(raddr) + _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); + else + _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, 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); + pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); + + switch (action) + { + case 0: //SA Query req + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen); + pmlmeext->sa_query_seq++; + //send sa query request to AP, AP should reply sa query response in 1 second + set_sa_query_timer(pmlmeext, 1000); + break; + + case 1: //SA Query rsp + tid = cpu_to_le16(tid); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen); + break; + default: + break; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); +} +#endif //CONFIG_IEEE80211W + +void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status) +{ + u8 category = RTW_WLAN_CATEGORY_BACK; + u16 start_seq; + u16 BA_para_set; + u16 reason_code; + u16 BA_timeout_value; + u16 BA_starting_seqctrl; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + + + DBG_871X("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + status = cpu_to_le16(status); + + + if (category == 3) + { + switch (action) + { + case 0: //ADDBA req + do { + pmlmeinfo->dialogToken++; + } while (pmlmeinfo->dialogToken == 0); + pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen)); + + BA_para_set = (0x1002 | ((status & 0xf) << 2)); //immediate ack & 64 buffer size + //sys_mib.BA_para_set = 0x0802; //immediate ack & 32 buffer size + BA_para_set = cpu_to_le16(BA_para_set); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + + //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms) + BA_timeout_value = 5000;//~ 5ms + BA_timeout_value = cpu_to_le16(BA_timeout_value); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen)); + + //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) + if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL) + { + start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1; + + DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07); + + psta->BA_starting_seqctrl[status & 0x07] = start_seq; + + BA_starting_seqctrl = start_seq << 4; + } + + BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen)); + break; + + case 1: //ADDBA rsp + pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen)); + + //BA_para_set = cpu_to_le16((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size + BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size + + if(pregpriv->ampdu_amsdu==0)//disabled + BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0)); + else if(pregpriv->ampdu_amsdu==1)//enabled + BA_para_set = cpu_to_le16(BA_para_set | BIT(0)); + else //auto + BA_para_set = cpu_to_le16(BA_para_set); + + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen)); + break; + case 2://DELBA + BA_para_set = (status & 0x1F) << 3; + BA_para_set = cpu_to_le16(BA_para_set); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + + reason_code = 37;//Requested from peer STA as it does not want to use the mechanism + reason_code = cpu_to_le16(reason_code); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen)); + break; + default: + break; + } + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); +} + +static void issue_action_BSSCoexistPacket(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + unsigned char category, action; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct wlan_network *pnetwork = NULL; + 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); + _queue *queue = &(pmlmepriv->scanned_queue); + u8 InfoContent[16] = {0}; + u8 ICS[8][15]; + + if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0)) + return; + + if(_TRUE == pmlmeinfo->bwmode_updated) + return; + + + DBG_871X("%s\n", __FUNCTION__); + + + category = RTW_WLAN_CATEGORY_PUBLIC; + action = ACT_PUBLIC_BSSCOEXIST; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, 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, 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + + // + if(pmlmepriv->num_FortyMHzIntolerant>0) + { + u8 iedata=0; + + iedata |= BIT(2);//20 MHz BSS Width Request + + pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); + + } + + + // + _rtw_memset(ICS, 0, sizeof(ICS)); + if(pmlmepriv->num_sta_no_ht>0) + { + int i; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + int len; + u8 *p; + WLAN_BSSID_EX *pbss_network; + + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + plist = get_next(plist); + + pbss_network = (WLAN_BSSID_EX *)&pnetwork->network; + + p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); + if((p==NULL) || (len==0))//non-HT + { + if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14)) + continue; + + ICS[0][pbss_network->Configuration.DSConfig]=1; + + if(ICS[0][0] == 0) + ICS[0][0] = 1; + } + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + + for(i= 0;i<8;i++) + { + if(ICS[i][0] == 1) + { + int j, k = 0; + + InfoContent[k] = i; + //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); + k++; + + for(j=1;j<=14;j++) + { + if(ICS[i][j]==1) + { + if(k<16) + { + InfoContent[k] = j; //channel number + //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); + k++; + } + } + } + + pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen)); + + } + + } + + + } + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + //struct recv_reorder_ctrl *preorder_ctrl; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u16 tid; + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + return _SUCCESS; + + psta = rtw_get_stainfo(pstapriv, addr); + if(psta==NULL) + return _SUCCESS; + + //DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR"); + + if(initiator==0) // recipient + { + for(tid = 0;tidrecvreorder_ctrl[tid].enable == _TRUE) + { + DBG_871X("rx agg disable tid(%d)\n",tid); + issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F)); + psta->recvreorder_ctrl[tid].enable = _FALSE; + psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + psta->recvreorder_ctrl[tid].indicate_seq); + #endif + } + } + } + else if(initiator == 1)// originator + { + //DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); + for(tid = 0;tidhtpriv.agg_enable_bitmap & BIT(tid)) + { + DBG_871X("tx agg disable tid(%d)\n",tid); + issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) ); + psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); + + } + } + } + + return _SUCCESS; + +} + +unsigned int send_beacon(_adapter *padapter) +{ + u8 bxmitok = _FALSE; + int issue=0; + int poll = 0; +//#ifdef CONFIG_CONCURRENT_MODE + //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + //_adapter *pbuddy_adapter = padapter->pbuddy_adapter; + //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); +//#endif + +#ifdef CONFIG_PCI_HCI + + //DBG_871X("%s\n", __FUNCTION__); + + issue_beacon(padapter); + + return _SUCCESS; + +#endif + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u32 start = rtw_get_current_time(); + + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); + do{ + issue_beacon(padapter); + issue++; + do { + rtw_yield_os(); + rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); + poll++; + }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); + + }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); + + if(padapter->bSurpriseRemoved || padapter->bDriverStopped) + { + return _FAIL; + } + if(_FALSE == bxmitok) + { + DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start)); + return _FAIL; + } + else + { + u32 passing_time = rtw_get_passing_time_ms(start); + + if(passing_time > 100 || issue > 3) + DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); + //else + // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); + + return _SUCCESS; + } + +#endif + +} + +/**************************************************************************** + +Following are some utitity fuctions for WiFi MLME + +*****************************************************************************/ + +BOOLEAN IsLegal5GChannel( + IN PADAPTER Adapter, + IN u8 channel) +{ + + int i=0; + u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58, + 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122, + 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159, + 161,163,165}; + for(i=0;imlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u32 initialgain = 0; + u8 restore_initial_gain = 1; + +#ifdef CONFIG_P2P + +#ifdef CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + u8 stay_buddy_ch = 0; +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + +#endif //CONFIG_CONCURRENT_MODE + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + static unsigned char prev_survey_channel = 0; + static unsigned int p2p_scan_count = 0; + + + if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) ) + { + if ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) + { + survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; + } + else + { + survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx]; + } + ScanType = SCAN_ACTIVE; + } + else if(rtw_p2p_findphase_ex_is_social(pwdinfo)) + { + // Commented by Albert 2011/06/03 + // The driver is in the find phase, it should go through the social channel. + int ch_set_idx; + survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx]; + ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel); + if (ch_set_idx >= 0) + ScanType = pmlmeext->channel_set[ch_set_idx].ScanType; + else + ScanType = SCAN_ACTIVE; + } + else +#endif //CONFIG_P2P + { + struct rtw_ieee80211_channel *ch; + if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) { + ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx]; + survey_channel = ch->hw_value; + ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; + } + } + + if (0) + DBG_871X(FUNC_ADPT_FMT" ch:%u(cnt:%u,idx:%d) at %dms, %c%c%c\n" + , FUNC_ADPT_ARG(padapter) + , survey_channel + , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx + , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) + , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P' + , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' ' + ); + + if(survey_channel != 0) + { + //PAUSE 4-AC Queue when site_survey + //rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); + //val8 |= 0x0f; + //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + 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 ) + stay_buddy_ch = 2; + pmlmeinfo->scan_cnt++; + } + } +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE +#endif //CONFIG_CONCURRENT_MODE + if(pmlmeext->sitesurvey_res.channel_idx == 0) + { + set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + else + { + SelectChannel(padapter, survey_channel); + } + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + if( stay_buddy_ch == 1 ) + { + val8 = 0; //survey done + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_LINKED)) + { + update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE); + } + } + else if( stay_buddy_ch == 2 ) + { + val8 = 1; //under site survey + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + + if(ScanType == SCAN_ACTIVE) //obey the channel plan setting... + { + #ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) + ) + { + issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter, NULL); + } + else + #endif //CONFIG_P2P + { + int i; + for(i=0;isitesurvey_res.ssid[i].SsidLength) { + //todo: to issue two probe req??? + issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + //rtw_msleep_os(SURVEY_TO>>1); + issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + } else { + break; + } + } + + if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { + //todo: to issue two probe req??? + issue_probereq(padapter, NULL, NULL); + //rtw_msleep_os(SURVEY_TO>>1); + issue_probereq(padapter, NULL, NULL); + } + } + } + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + if( stay_buddy_ch == 1 ) + set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND ); + else +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); + + } + else + { + + // channel number is 0 or this channel is not valid. + +#ifdef CONFIG_CONCURRENT_MODE + u8 cur_channel; + u8 cur_bwmode; + u8 cur_ch_offset; + + if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) + { + if (0) + DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset); + } + #ifdef CONFIG_IOCTL_CFG80211 + else if(padapter->pbuddy_adapter + && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211 + && wdev_to_priv(pbuddy_adapter->rtw_wdev)->p2p_enabled + && rtw_p2p_chk_state(&pbuddy_adapter->wdinfo, P2P_STATE_LISTEN) + ) + { + cur_channel = pbuddy_adapter->wdinfo.listen_channel; + cur_bwmode = pbuddy_mlmeext->cur_bwmode; + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + } + #endif + else + { + cur_channel = pmlmeext->cur_channel; + cur_bwmode = pmlmeext->cur_bwmode; + cur_ch_offset = pmlmeext->cur_ch_offset; + } +#endif + + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) + { + if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) ) + { + // Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. + // This will let the following flow to run the scanning end. + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); + } + #ifdef CONFIG_DBG_P2P + DBG_871X( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt ); + #endif + } + + if(rtw_p2p_findphase_ex_is_needed(pwdinfo)) + { + // Set the P2P State to the listen state of find phase and set the current channel to the listen channel + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN); + pmlmeext->sitesurvey_res.state = SCAN_DISABLE; + + //turn on dynamic functions + Restore_DM_Func_Flag(padapter); + //Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + + _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) ); + } + else +#endif //CONFIG_P2P + { + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + pmlmeinfo->scan_cnt = 0; +#endif //CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE + +#ifdef CONFIG_ANTENNA_DIVERSITY + // 20100721:Interrupt scan operation here. + // For SW antenna diversity before link, it needs to switch to another antenna and scan again. + // It compares the scan result and select beter one to do connection. + if(rtw_hal_antdiv_before_linked(padapter)) + { + pmlmeext->sitesurvey_res.bss_cnt = 0; + pmlmeext->sitesurvey_res.channel_idx = -1; + pmlmeext->chan_scan_time = SURVEY_TO /2; + set_survey_timer(pmlmeext, pmlmeext->chan_scan_time); + return; + } +#endif + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) + { + #ifdef CONFIG_CONCURRENT_MODE + if( pwdinfo->driver_interface == DRIVER_WEXT ) + { + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 ); + } + } + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + #else + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + #endif + } + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); +#endif //CONFIG_P2P + + pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; + + //switch back to the original channel + //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); + + { +#ifdef CONFIG_CONCURRENT_MODE + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); +#else +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_set_channel_bwmode_survey_done(padapter); +#else + if( pwdinfo->driver_interface == DRIVER_WEXT ) + { + if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) ) + { + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + else + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } + else if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } +#endif //CONFIG_DUALMAC_CONCURRENT +#endif //CONFIG_CONCURRENT_MODE + } + + //flush 4-AC Queue after site_survey + //val8 = 0; + //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); + + val8 = 0; //survey done + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + //config MSR + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + + +#ifdef CONFIG_IOCTL_CFG80211 + if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE) + { + restore_initial_gain = 0; + } +#endif //CONFIG_IOCTL_CFG80211 + + if(restore_initial_gain == 1) + { + initialgain = 0xff; //restore RX GAIN + rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + } + + //turn on dynamic functions + Restore_DM_Func_Flag(padapter); + //Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + + if (is_client_associated_to_ap(padapter) == _TRUE) + { + issue_nulldata(padapter, NULL, 0, 3, 500); + +#ifdef CONFIG_CONCURRENT_MODE + if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE) + { + DBG_871X("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n"); + + issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500); + } +#endif + } +#ifdef CONFIG_CONCURRENT_MODE + else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE) + { + issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500); + } +#endif + + report_surveydone_event(padapter); + + pmlmeext->chan_scan_time = SURVEY_TO; + pmlmeext->sitesurvey_res.state = SCAN_DISABLE; + + issue_action_BSSCoexistPacket(padapter); + issue_action_BSSCoexistPacket(padapter); + issue_action_BSSCoexistPacket(padapter); + + } + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_LINKED)) + { + + DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + DBG_871X("restart pbuddy_adapter's beacon\n"); + + update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE); + } +#endif + + } + + return; + +} + +//collect bss info from Beacon and Probe response frames. +u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid) +{ + int i; + u32 len; + u8 *p; + u16 val16, subtype; + u8 *pframe = precv_frame->u.hdr.rx_data; + u32 packet_len = precv_frame->u.hdr.len; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); + + if (len > MAX_IE_SZ) + { + //DBG_871X("IE too long for survey event\n"); + return _FAIL; + } + + _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX)); + + subtype = GetFrameSubType(pframe); + + if(subtype==WIFI_BEACON) + bssid->Reserved[0] = 1; + else + bssid->Reserved[0] = 0; + + bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len; + + //below is to copy the information element + bssid->IELength = len; + _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); + + //get the signal strength + bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.signal_qual;//in percentage + bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.signal_strength;//in percentage + bssid->Rssi = precv_frame->u.hdr.attrib.RecvSignalPower; // in dBM.raw data + +#ifdef CONFIG_ANTENNA_DIVERSITY + //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna)); + rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna); +#endif + + // checking SSID + if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL) + { + DBG_871X("marc: cannot find SSID for survey event\n"); + return _FAIL; + } + + if (*(p + 1)) + { + if (len > NDIS_802_11_LENGTH_SSID) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); + bssid->Ssid.SsidLength = *(p + 1); + } + else + { + bssid->Ssid.SsidLength = 0; + } + + _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); + + //checking rate info... + i = 0; + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (p != NULL) + { + if (len > NDIS_802_11_LENGTH_RATES_EX) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->SupportedRates, (p + 2), len); + i = len; + } + + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (p != NULL) + { + if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len); + } + + //todo: +#if 0 + if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B) + { + bssid->NetworkTypeInUse = Ndis802_11DS; + } + else +#endif + { + bssid->NetworkTypeInUse = Ndis802_11OFDM24; + } + + if (bssid->IELength < 12) + return _FAIL; + + // Checking for DSConfig + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + + bssid->Configuration.DSConfig = 0; + bssid->Configuration.Length = 0; + + if (p) + { + bssid->Configuration.DSConfig = *(p + 2); + } + else + {// In 5G, some ap do not have DSSET IE + // checking HT info for channel + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if(p) + { + struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); + bssid->Configuration.DSConfig = HT_info->primary_channel; + } + else + { // use current channel + bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); + } + } + + _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); + bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod); + + val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid); + + if (val16 & BIT(0)) + { + bssid->InfrastructureMode = Ndis802_11Infrastructure; + _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); + } + else + { + bssid->InfrastructureMode = Ndis802_11IBSS; + _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); + } + + if (val16 & BIT(4)) + bssid->Privacy = 1; + else + bssid->Privacy = 0; + + bssid->Configuration.ATIMWindow = 0; + + //20/40 BSS Coexistence check + if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated)) + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if(p && len>0) + { + struct HT_caps_element *pHT_caps; + pHT_caps = (struct HT_caps_element *)(p + 2); + + if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14)) + { + pmlmepriv->num_FortyMHzIntolerant++; + } + } + else + { + pmlmepriv->num_sta_no_ht++; + } + + } + +#ifdef CONFIG_INTEL_WIDI + //process_intel_widi_query_or_tigger(padapter, bssid); + if(process_intel_widi_query_or_tigger(padapter, bssid)) + { + return _FAIL; + } +#endif // CONFIG_INTEL_WIDI + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1 + if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n" + , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig + , rtw_get_oper_ch(padapter) + , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi + ); + } + #endif + + // mark bss info receving from nearby channel as SignalQuality 101 + if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) + { + bssid->PhyInfo.SignalQuality= 101; + } + + return _SUCCESS; +} + +void start_create_ibss(_adapter* padapter) +{ + unsigned short caps; + u8 val8; + u8 join_type; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; + pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); + + //update wireless mode + update_wireless_mode(padapter); + + //udpate capability + caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork); + update_capinfo(padapter, caps); + if(caps&cap_IBSS)//adhoc master + { + //set_opmode_cmd(padapter, adhoc);//removed + + val8 = 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + //switch channel + //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); + set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + + beacon_timing_control(padapter); + + //set msr to WIFI_FW_ADHOC_STATE + pmlmeinfo->state = WIFI_FW_ADHOC_STATE; + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + + //issue beacon + if(send_beacon(padapter)==_FAIL) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n")); + + report_join_res(padapter, -1); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + } + else + { + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); + join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + + report_join_res(padapter, 1); + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + } + } + else + { + DBG_871X("start_create_ibss, invalid cap:%x\n", caps); + return; + } + +} + +void start_clnt_join(_adapter* padapter) +{ + unsigned short caps; + u8 val8; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + + //update wireless mode + update_wireless_mode(padapter); + + //udpate capability + caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork); + update_capinfo(padapter, caps); + if (caps&cap_ESS) + { + Set_MSR(padapter, WIFI_FW_STATION_STATE); + + val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + #ifdef CONFIG_DEAUTH_BEFORE_CONNECT + // Because of AP's not receiving deauth before + // AP may: 1)not response auth or 2)deauth us after link is complete + // issue deauth before issuing auth to deal with the situation + + // Commented by Albert 2012/07/21 + // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. + { + #ifdef CONFIG_P2P + _queue *queue = &(padapter->mlmepriv.scanned_queue); + _list *head = get_list_head(queue); + _list *pos = get_next(head); + struct wlan_network *scanned = NULL; + u8 ie_offset = 0; + _irqL irqL; + bool has_p2p_ie = _FALSE; + + _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL); + + for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) { + + scanned = LIST_CONTAINOR(pos, struct wlan_network, list); + if(scanned==NULL) + rtw_warn_on(1); + + if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE + && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE + ) { + ie_offset = (scanned->network.Reserved[0] == 2? 0:12); + if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL)) + has_p2p_ie = _TRUE; + break; + } + } + + _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL); + + if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE) + #endif /* CONFIG_P2P */ + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100); + } + #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */ + + //here wait for receiving the beacon to start auth + //and enable a timer + set_link_timer(pmlmeext, decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval)); + + pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; + } + else if (caps&cap_IBSS) //adhoc client + { + Set_MSR(padapter, WIFI_FW_ADHOC_STATE); + + val8 = 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + //switch channel + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + beacon_timing_control(padapter); + + pmlmeinfo->state = WIFI_FW_ADHOC_STATE; + + report_join_res(padapter, 1); + } + else + { + //DBG_871X("marc: invalid cap:%x\n", caps); + return; + } + +} + +void start_clnt_auth(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + _cancel_timer_ex(&pmlmeext->link_timer); + + pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); + pmlmeinfo->state |= WIFI_FW_AUTH_STATE; + + pmlmeinfo->auth_seq = 1; + pmlmeinfo->reauth_count = 0; + pmlmeinfo->reassoc_count = 0; + pmlmeinfo->link_count = 0; + pmlmeext->retry = 0; + + + issue_auth(padapter, NULL, 0); + + set_link_timer(pmlmeext, REAUTH_TO); + +} + + +void start_clnt_assoc(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + _cancel_timer_ex(&pmlmeext->link_timer); + + pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); + pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); + + issue_assocreq(padapter); + + set_link_timer(pmlmeext, REASSOC_TO); +} + +unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //check A3 + if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + + DBG_871X("%s\n", __FUNCTION__); + + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_del_sta_event(padapter, MacAddr, reason); + + } + else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -2); + } + } + + return _SUCCESS; +} + +#ifdef CONFIG_80211D +static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) +{ + struct registry_priv *pregistrypriv; + struct mlme_ext_priv *pmlmeext; + RT_CHANNEL_INFO *chplan_new; + u8 channel; + u8 i; + + + pregistrypriv = &padapter->registrypriv; + pmlmeext = &padapter->mlmeextpriv; + + // Adjust channel plan by AP Country IE + if (pregistrypriv->enable80211d && + (!pmlmeext->update_channel_plan_by_ap_done)) + { + u8 *ie, *p; + u32 len; + RT_CHANNEL_PLAN chplan_ap; + RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM]; + u8 country[4]; + u8 fcn; // first channel number + u8 noc; // number of channel + u8 j, k; + + ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (!ie) return; + if (len < 6) return; + + ie += 2; + p = ie; + ie += len; + + _rtw_memset(country, 0, 4); + _rtw_memcpy(country, p, 3); + p += 3; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: 802.11d country=%s\n", __FUNCTION__, country)); + + i = 0; + while ((ie - p) >= 3) + { + fcn = *(p++); + noc = *(p++); + p++; + + for (j = 0; j < noc; j++) + { + if (fcn <= 14) channel = fcn + j; // 2.4 GHz + else channel = fcn + j*4; // 5 GHz + + chplan_ap.Channel[i++] = channel; + } + } + chplan_ap.Len = i; + +#ifdef CONFIG_DEBUG_RTL871X +#ifdef PLATFORM_LINUX + i = 0; + printk("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid); + while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) + { + printk("%02d,", chplan_ap.Channel[i]); + i++; + } + printk("}\n"); +#endif +#endif + + _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); +#ifdef CONFIG_DEBUG_RTL871X +#ifdef PLATFORM_LINUX + i = 0; + printk("%s: STA channel plan {", __func__); + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + printk("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a'); + i++; + } + printk("}\n"); +#endif +#endif + + _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); + chplan_new = pmlmeext->channel_set; + + i = j = k = 0; + if (pregistrypriv->wireless_mode & WIRELESS_11G) + { + do { + if ((i == MAX_CHANNEL_NUM) || + (chplan_sta[i].ChannelNum == 0) || + (chplan_sta[i].ChannelNum > 14)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + i++; + j++; + k++; + } + else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } while (1); + + // change AP not support channel to Passive scan + while ((i < MAX_CHANNEL_NUM) && + (chplan_sta[i].ChannelNum != 0) && + (chplan_sta[i].ChannelNum <= 14)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + + // add channel AP supported + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } + else + { + // keep original STA 2.4G channel plan + while ((i < MAX_CHANNEL_NUM) && + (chplan_sta[i].ChannelNum != 0) && + (chplan_sta[i].ChannelNum <= 14)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + chplan_new[k].ScanType = chplan_sta[i].ScanType; + i++; + k++; + } + + // skip AP 2.4G channel plan + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) + { + j++; + } + } + + if (pregistrypriv->wireless_mode & WIRELESS_11A) + { + do { + if ((i == MAX_CHANNEL_NUM) || + (chplan_sta[i].ChannelNum == 0)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + i++; + j++; + k++; + } + else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } while (1); + + // change AP not support channel to Passive scan + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + + // add channel AP supported + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } + else + { + // keep original STA 5G channel plan + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + chplan_new[k].ScanType = chplan_sta[i].ScanType; + i++; + k++; + } + } + + pmlmeext->update_channel_plan_by_ap_done = 1; + +#ifdef CONFIG_DEBUG_RTL871X +#ifdef PLATFORM_LINUX + k = 0; + printk("%s: new STA channel plan {", __func__); + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) + { + printk("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c'); + k++; + } + printk("}\n"); +#endif +#endif + +#if 0 + // recover the right channel index + channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; + k = 0; + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) + { + if (chplan_new[k].ChannelNum == channel) { + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: change mlme_ext sitesurvey channel index from %d to %d\n", + __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k)); + pmlmeext->sitesurvey_res.channel_idx = k; + break; + } + k++; + } +#endif + } + + // If channel is used by AP, set channel scan type to active + channel = bssid->Configuration.DSConfig; + chplan_new = pmlmeext->channel_set; + i = 0; + while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) + { + if (chplan_new[i].ChannelNum == channel) + { + if (chplan_new[i].ScanType == SCAN_PASSIVE) + { + //5G Bnad 2, 3 (DFS) doesn't change to active scan + if(channel >= 52 && channel <= 144) + break; + + chplan_new[i].ScanType = SCAN_ACTIVE; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: change channel %d scan type from passive to active\n", + __FUNCTION__, channel)); + } + break; + } + i++; + } +} +#endif + +/**************************************************************************** + +Following are the functions to report events + +*****************************************************************************/ + +void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct survey_event *psurvey_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext; + struct cmd_priv *pcmdpriv; + //u8 *pframe = precv_frame->u.hdr.rx_data; + //uint len = precv_frame->u.hdr.len; + + if(!padapter) + return; + + pmlmeext = &padapter->mlmeextpriv; + pcmdpriv = &padapter->cmdpriv; + + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct survey_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + + if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + rtw_mfree((u8 *)pevtcmd, cmdsz); + return; + } + +#ifdef CONFIG_80211D + process_80211d(padapter, &psurvey_evt->bss); +#endif + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + pmlmeext->sitesurvey_res.bss_cnt++; + + return; + +} + +void report_surveydone_event(_adapter *padapter) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct surveydone_event *psurveydone_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct surveydone_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; + + DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter)); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; + +} + +void report_join_res(_adapter *padapter, int res) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct joinbss_event *pjoinbss_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct joinbss_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX)); + pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; + + DBG_871X("report_join_res(%d)\n", res); + + + rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); + + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; + +} + +void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct sta_info *psta; + int mac_id; + struct stadel_event *pdel_sta_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct stadel_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); + _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2); + + + psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); + if(psta) + mac_id = (int)psta->mac_id; + else + mac_id = (-1); + + pdel_sta_evt->mac_id = mac_id; + + DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; +} + +void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct stassoc_event *padd_sta_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct stassoc_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN); + padd_sta_evt->cam_id = cam_idx; + + DBG_871X("report_add_sta_event: add STA\n"); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; +} + + +/**************************************************************************** + +Following are the event callback functions + +*****************************************************************************/ + +//for sta/adhoc mode +void update_sta_info(_adapter *padapter, struct sta_info *psta) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //ERP + VCS_update(padapter, psta); + + + //HT + if(pmlmepriv->htpriv.ht_option) + { + psta->htpriv.ht_option = _TRUE; + + psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; + + if (support_short_GI(padapter, &(pmlmeinfo->HT_caps))) + psta->htpriv.sgi = _TRUE; + + psta->qos_option = _TRUE; + + } + else + { + psta->htpriv.ht_option = _FALSE; + + psta->htpriv.ampdu_enable = _FALSE; + + psta->htpriv.sgi = _FALSE; + + psta->qos_option = _FALSE; + + } + + psta->htpriv.bwmode = pmlmeext->cur_bwmode; + psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; + + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + + + //QoS + if(pmlmepriv->qospriv.qos_option) + psta->qos_option = _TRUE; + + + psta->state = _FW_LINKED; + +} + +void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res) +{ + struct sta_info *psta, *psta_bmc; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 join_type; + + if(join_res < 0) + { + join_type = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); + + //restore to initial setting. + update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); +#if 0 //temply remove +#ifdef CONFIG_INTEL_WIDI +#ifdef DBG_CONFIG_ERROR_DETECT + DBG_871X("%s(): do silentreset\n",__FUNCTION__); + rtw_hal_sreset_reset(padapter); +#endif +#endif +#endif + goto exit_mlmeext_joinbss_event_callback; + } + + if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + //for bc/mc + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if(psta_bmc) + { + pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc; + update_bmc_sta_support_rate(padapter, psta_bmc->mac_id); + Update_RA_Entry(padapter, psta_bmc->mac_id); + } + } + + + //turn on dynamic functions + Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); + + // update IOT-releated issue + update_IOT_info(padapter); + + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); + + //BCN interval + rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); + + //udpate capability + update_capinfo(padapter, pmlmeinfo->capability); + + //WMM, Update EDCA param + WMMOnAssocRsp(padapter); + + //HT + HTOnAssocRsp(padapter); + +#ifndef CONFIG_CONCURRENT_MODE + // Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined. + //Set cur_channel&cur_bwmode&cur_ch_offset + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); +#endif + + psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); + if (psta) //only for infra. mode + { + pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; + + //DBG_871X("set_sta_rate\n"); + + //set per sta rate after updating HT cap. + set_sta_rate(padapter, psta); + } + + join_type = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + // correcting TSF + correct_TSF(padapter, pmlmeext); + + //set_link_timer(pmlmeext, DISCONNECT_TO); + } + +#ifdef CONFIG_LPS + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); +#endif + +exit_mlmeext_joinbss_event_callback: + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_handle_join_done(padapter, join_res); +#endif +#ifdef CONFIG_CONCURRENT_MODE + concurrent_chk_joinbss_done(padapter, join_res); +#endif + + DBG_871X("=>%s\n", __FUNCTION__); + +} + +void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 join_type; + + DBG_871X("%s\n", __FUNCTION__); + + if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1 + { + //nothing to do + } + else//adhoc client + { + //update TSF Value + //update_TSF(pmlmeext, pframe, len); + + // correcting TSF + correct_TSF(padapter, pmlmeext); + + //start beacon + if(send_beacon(padapter)==_FAIL) + { + pmlmeinfo->FW_sta_info[psta->mac_id].status = 0; + + pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE; + + return; + } + + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + + } + + join_type = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + } + + pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; + + //rate radaptive + Update_RA_Entry(padapter, psta->mac_id); + + //update adhoc sta_info + update_sta_info(padapter, psta); + +} + +void mlmeext_sta_del_event_callback(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) + { + //set_opmode_cmd(padapter, infra_client_with_mlme); + + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0); + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); + + //restore to initial setting. + update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_set_channel_bwmode_disconnect(padapter); +#else +#ifdef CONFIG_CONCURRENT_MODE + if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE) + { +#endif //CONFIG_CONCURRENT_MODE + + //switch to the 20M Hz mode after disconnect + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + +#ifdef CONFIG_CONCURRENT_MODE + } +#endif //CONFIG_CONCURRENT_MODE +#endif //CONFIG_DUALMAC_CONCURRENT + + flush_all_cam_entry(padapter); + + pmlmeinfo->state = WIFI_FW_NULL_STATE; + + //set MSR to no link state -> infra. mode + Set_MSR(padapter, _HW_STATE_STATION_); + + _cancel_timer_ex(&pmlmeext->link_timer); + + } + +} + +/**************************************************************************** + +Following are the functions for the timer handlers + +*****************************************************************************/ +void _linked_rx_signal_strehgth_display(_adapter *padapter); +void _linked_rx_signal_strehgth_display(_adapter *padapter) +{ + int UndecoratedSmoothedPWDB; + +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + DBG_871X("============ pbuddy_adapter linked status check ===================\n"); + DBG_871X("buddy_adapter_type=%d\n", pbuddy_adapter->adapter_type); + DBG_871X("pbuddy_adapter pathA Rx SNRdb:%d\n",pbuddy_adapter->recvpriv.RxSNRdB[0]); + DBG_871X("pbuddy_adapter pathA Rx PWDB:%d\n",pbuddy_adapter->recvpriv.rxpwdb); + DBG_871X("pbuddy_adapter pathA Rx RSSI:%d,pathB Rx RSSI:%d\n" + ,pbuddy_adapter->recvpriv.RxRssi[0],pbuddy_adapter->recvpriv.RxRssi[1]); + rtw_hal_get_def_var(pbuddy_adapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + DBG_871X("pbuddy_adapter UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB); + DBG_871X("Rx RSSI:%d\n",pbuddy_adapter->recvpriv.rssi); + DBG_871X("Rx Signal_strength:%d\n",pbuddy_adapter->recvpriv.signal_strength); + DBG_871X("Rx Signal_qual:%d \n",pbuddy_adapter->recvpriv.signal_qual); + DBG_871X("============ linked status check ===================\n"); + DBG_871X("adapter_type=%d\n", padapter->adapter_type); +#else //CONFIG_CONCURRENT_MODE + DBG_871X("============ linked status check ===================\n"); +#endif //CONFIG_CONCURRENT_MODE + DBG_871X("pathA Rx SNRdb:%d, pathB Rx SNRdb:%d\n",padapter->recvpriv.RxSNRdB[0], padapter->recvpriv.RxSNRdB[1]); + DBG_871X("pathA Rx PWDB:%d\n",padapter->recvpriv.rxpwdb); + DBG_871X("pathA Rx RSSI:%d,pathB Rx RSSI:%d\n",padapter->recvpriv.RxRssi[0],padapter->recvpriv.RxRssi[1]); + rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB); + DBG_871X("Rx RSSI:%d\n",padapter->recvpriv.rssi); + DBG_871X("Rx Signal_strength:%d\n",padapter->recvpriv.signal_strength); + DBG_871X("Rx Signal_qual:%d \n",padapter->recvpriv.signal_qual); + if ( check_fwstate( &padapter->mlmepriv, _FW_LINKED )) + { + DBG_871X("bw mode: %d, channel: %d\n", padapter->mlmeextpriv.cur_bwmode, padapter->mlmeextpriv.cur_channel ); + DBG_871X("received bytes = %d\n", (u32) (padapter->recvpriv.rx_bytes - padapter->recvpriv.last_rx_bytes ) ); + } + DBG_871X("============ linked status check ===================\n"); + DBG_871X(" DIG PATH-A(0x%02x), PATH-B(0x%02x)\n",rtw_read8(padapter,0xc50),rtw_read8(padapter,0xc58)); + DBG_871X(" OFDM -Alarm DA2(0x%04x),DA4(0x%04x),DA6(0x%04x),DA8(0x%04x)\n", + rtw_read16(padapter,0xDA2),rtw_read16(padapter,0xDA4),rtw_read16(padapter,0xDA6),rtw_read16(padapter,0xDA8)); + + DBG_871X(" CCK -Alarm A5B(0x%02x),A5C(0x%02x)\n",rtw_read8(padapter,0xA5B),rtw_read8(padapter,0xA5C)); + DBG_871X(" FalseAlmCnt_all(%d)\n",padapter->recvpriv.FalseAlmCnt_all); + +} + +u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) +{ + u8 ret = _FALSE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + #ifdef DBG_EXPIRATION_CHK + DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu" + /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/ + ", retry:%u\n" + , FUNC_ADPT_ARG(padapter) + , STA_RX_PKTS_DIFF_ARG(psta) + , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts + , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts + /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts + , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts + , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts + , pmlmeinfo->bcn_interval*/ + , pmlmeext->retry + ); + + DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter) + , padapter->xmitpriv.tx_pkts + , pmlmeinfo->link_count + ); + #endif + + if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) + && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) + && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta) + ) + { + ret = _FALSE; + } + else + { + ret = _TRUE; + } + + sta_update_last_rx_pkts(psta); + + return ret; +} + +void linked_status_chk(_adapter *padapter) +{ + u32 i; + struct sta_info *psta; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; + + if(padapter->bRxRSSIDisplay) + _linked_rx_signal_strehgth_display(padapter); + + #ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_linked_status_check(padapter); + #endif + + if (is_client_associated_to_ap(padapter)) + { + //linked infrastructure client mode + + int tx_chk = _SUCCESS, rx_chk = _SUCCESS; + int rx_chk_limit; + + #if defined(DBG_ROAMING_TEST) + rx_chk_limit = 1; + #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) + rx_chk_limit = 4; + #else + rx_chk_limit = 8; + #endif + + // Marked by Kurt 20130715 + // For WiDi 3.5 and later on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. + // todo: To check why rx_chk would be _FALSE under miracast session. + //#ifdef CONFIG_INTEL_WIDI + //if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE) + // rx_chk_limit = 1; + //#endif + + if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) + { + bool is_p2p_enable = _FALSE; + #ifdef CONFIG_P2P + is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE); + #endif + + if (chk_ap_is_alive(padapter, psta) == _FALSE) + rx_chk = _FAIL; + + if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) + tx_chk = _FAIL; + + #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) { + u8 backup_oper_channel=0; + + /* switch to correct channel of current network before issue keep-alive frames */ + if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { + backup_oper_channel = rtw_get_oper_ch(padapter); + SelectChannel(padapter, pmlmeext->cur_channel); + } + + if (rx_chk != _SUCCESS) + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1); + + if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) { + tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); + /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */ + if (tx_chk == _SUCCESS && !is_p2p_enable) + rx_chk = _SUCCESS; + } + + /* back to the original operation channel */ + if(backup_oper_channel>0) + SelectChannel(padapter, backup_oper_channel); + + } + else + #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + { + if (rx_chk != _SUCCESS) { + if (pmlmeext->retry == 0) { + #ifdef DBG_EXPIRATION_CHK + DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry); + #endif + issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); + issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); + issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress); + } + } + + if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) { + #ifdef DBG_EXPIRATION_CHK + DBG_871X("%s issue_nulldata 0\n", __FUNCTION__); + #endif + tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0); + } + } + + if (rx_chk == _FAIL) { + pmlmeext->retry++; + if (pmlmeext->retry > rx_chk_limit) { + DBG_871X(FUNC_ADPT_FMT" disconnect or roaming\n", + FUNC_ADPT_ARG(padapter)); + receive_disconnect(padapter, pmlmeinfo->network.MacAddress + , WLAN_REASON_EXPIRATION_CHK); + return; + } + } else { + pmlmeext->retry = 0; + } + + if (tx_chk == _FAIL) { + pmlmeinfo->link_count &= 0xf; + } else { + pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; + pmlmeinfo->link_count = 0; + } + + } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) + } + else if (is_client_associated_to_ibss(padapter)) + { + //linked IBSS mode + //for each assoc list entry to check the rx pkt counter + for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) + { + if (pmlmeinfo->FW_sta_info[i].status == 1) + { + psta = pmlmeinfo->FW_sta_info[i].psta; + + if(NULL==psta) continue; + + if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) + { + + if(pmlmeinfo->FW_sta_info[i].retry<3) + { + pmlmeinfo->FW_sta_info[i].retry++; + } + else + { + pmlmeinfo->FW_sta_info[i].retry = 0; + pmlmeinfo->FW_sta_info[i].status = 0; + report_del_sta_event(padapter, psta->hwaddr + , 65535// indicate disconnect caused by no rx + ); + } + } + else + { + pmlmeinfo->FW_sta_info[i].retry = 0; + pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta); + } + } + } + + //set_link_timer(pmlmeext, DISCONNECT_TO); + + } + +} + +void survey_timer_hdl(_adapter *padapter) +{ + struct cmd_obj *ph2c; + struct sitesurvey_parm *psurveyPara; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + + //DBG_871X("marc: survey timer\n"); +#ifdef PLATFORM_FREEBSD + rtw_mtx_lock(NULL); + if (callout_pending(&padapter->mlmeextpriv.survey_timer.callout)) { + /* callout was reset */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + if (!callout_active(&padapter->mlmeextpriv.survey_timer.callout)) { + /* callout was stopped */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + callout_deactivate(&padapter->mlmeextpriv.survey_timer.callout); + + +#endif + + //issue rtw_sitesurvey_cmd + if (pmlmeext->sitesurvey_res.state > SCAN_START) + { + if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS) + { +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH ) +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + pmlmeext->sitesurvey_res.channel_idx++; + } + + if(pmlmeext->scan_abort == _TRUE) + { + #ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) + { + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); + pmlmeext->sitesurvey_res.channel_idx = 3; + DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__ + , pmlmeext->sitesurvey_res.channel_idx + , pwdinfo->find_phase_state_exchange_cnt + ); + } + else + #endif + { + pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; + DBG_871X("%s idx:%d\n", __FUNCTION__ + , pmlmeext->sitesurvey_res.channel_idx + ); + } + + pmlmeext->scan_abort = _FALSE;//reset + } + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + goto exit_survey_timer_hdl; + } + + if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL) + { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + goto exit_survey_timer_hdl; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + rtw_enqueue_cmd(pcmdpriv, ph2c); + } + + +exit_survey_timer_hdl: +#ifdef PLATFORM_FREEBSD + rtw_mtx_unlock(NULL); +#endif + + return; +} + +void link_timer_hdl(_adapter *padapter) +{ + //static unsigned int rx_pkt = 0; + //static u64 tx_cnt = 0; + //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + //struct sta_priv *pstapriv = &padapter->stapriv; + +#ifdef PLATFORM_FREEBSD + rtw_mtx_lock(NULL); + if (callout_pending(&padapter->mlmeextpriv.survey_timer.callout)) { + /* callout was reset */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + if (!callout_active(&padapter->mlmeextpriv.survey_timer.callout)) { + /* callout was stopped */ + //mtx_unlock(&sc->sc_mtx); + rtw_mtx_unlock(NULL); + return; + } + callout_deactivate(&padapter->mlmeextpriv.survey_timer.callout); + + +#endif + + if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) + { + DBG_871X("link_timer_hdl:no beacon while connecting\n"); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -3); + } + else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) + { + //re-auth timer + if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) + { + //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) + //{ + pmlmeinfo->state = 0; + report_join_res(padapter, -1); + return; + //} + //else + //{ + // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; + // pmlmeinfo->reauth_count = 0; + //} + } + + DBG_871X("link_timer_hdl: auth timeout and try again\n"); + pmlmeinfo->auth_seq = 1; + issue_auth(padapter, NULL, 0); + set_link_timer(pmlmeext, REAUTH_TO); + } + else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) + { + //re-assoc timer + if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -2); + return; + } + + DBG_871X("link_timer_hdl: assoc timeout and try again\n"); + issue_assocreq(padapter); + set_link_timer(pmlmeext, REASSOC_TO); + } +#if 0 + else if (is_client_associated_to_ap(padapter)) + { + //linked infrastructure client mode + if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) + { + /*to monitor whether the AP is alive or not*/ + if (rx_pkt == psta->sta_stats.rx_pkts) + { + receive_disconnect(padapter, pmlmeinfo->network.MacAddress); + return; + } + else + { + rx_pkt = psta->sta_stats.rx_pkts; + set_link_timer(pmlmeext, DISCONNECT_TO); + } + + //update the EDCA paramter according to the Tx/RX mode + update_EDCA_param(padapter); + + /*to send the AP a nulldata if no frame is xmitted in order to keep alive*/ + if (pmlmeinfo->link_count++ == 0) + { + tx_cnt = pxmitpriv->tx_pkts; + } + else if ((pmlmeinfo->link_count & 0xf) == 0) + { + if (tx_cnt == pxmitpriv->tx_pkts) + { + issue_nulldata(padapter, NULL, 0, 0, 0); + } + + tx_cnt = pxmitpriv->tx_pkts; + } + } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) + } + else if (is_client_associated_to_ibss(padapter)) + { + //linked IBSS mode + //for each assoc list entry to check the rx pkt counter + for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) + { + if (pmlmeinfo->FW_sta_info[i].status == 1) + { + psta = pmlmeinfo->FW_sta_info[i].psta; + + if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts) + { + pmlmeinfo->FW_sta_info[i].status = 0; + report_del_sta_event(padapter, psta->hwaddr); + } + else + { + pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts; + } + } + } + + set_link_timer(pmlmeext, DISCONNECT_TO); + } +#endif + +#ifdef PLATFORM_FREEBSD + rtw_mtx_unlock(NULL); +#endif + + return; +} + +void addba_timer_hdl(struct sta_info *psta) +{ + struct ht_priv *phtpriv; + + if(!psta) + return; + + phtpriv = &psta->htpriv; + + if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) + { + if(phtpriv->candidate_tid_bitmap) + phtpriv->candidate_tid_bitmap=0x0; + + } +} + +#ifdef CONFIG_IEEE80211W +void sa_query_timer_hdl(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv * pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + //disconnect + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + rtw_disassoc_cmd(padapter, 0, _TRUE); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + DBG_871X("SA query timeout disconnect\n"); +} +#endif //CONFIG_IEEE80211W + +u8 NULL_hdl(_adapter *padapter, u8 *pbuf) +{ + return H2C_SUCCESS; +} + +#ifdef CONFIG_AUTO_AP_MODE +void rtw_start_auto_ap(_adapter *adapter) +{ + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode); + + rtw_setopmode_cmd(adapter, Ndis802_11APMode); +} + +static int rtw_auto_ap_start_beacon(_adapter *adapter) +{ + int ret=0; + u8 *pbuf = NULL; + uint len; + u8 supportRate[16]; + int sz = 0, rateLen; + u8 * ie; + u8 wireless_mode, oper_channel; + u8 ssid[3] = {0}; //hidden ssid + u32 ssid_len = sizeof(ssid); + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + + len = 128; + pbuf = rtw_zmalloc(len); + if(!pbuf) + return -ENOMEM; + + + //generate beacon + ie = pbuf; + + //timestamp will be inserted by hardware + sz += 8; + ie += sz; + + //beacon interval : 2bytes + *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100; + sz += 2; + ie += 2; + + //capability info + *(u16*)ie = 0; + *(u16*)ie |= cpu_to_le16(cap_ESS); + *(u16*)ie |= cpu_to_le16(cap_ShortPremble); + //*(u16*)ie |= cpu_to_le16(cap_Privacy); + sz += 2; + ie += 2; + + //SSID + ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz); + + //supported rates + wireless_mode = WIRELESS_11BG_24N; + rtw_set_supported_rate(supportRate, wireless_mode) ; + rateLen = rtw_get_rateset_len(supportRate); + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz); + } + else + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz); + } + + + //DS parameter set + if(check_buddy_fwstate(adapter, _FW_LINKED) && + check_buddy_fwstate(adapter, WIFI_STATION_STATE)) + { + PADAPTER pbuddy_adapter = adapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + oper_channel = pbuddy_mlmeext->cur_channel; + } + else + { + oper_channel = adapter_to_dvobj(adapter)->oper_channel; + } + ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz); + + //ext supported rates + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz); + } + + DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz); + + //lunch ap mode & start to issue beacon + if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) + { + + } + else + { + ret = -EINVAL; + } + + + rtw_mfree(pbuf, len); + + return ret; + +} +#endif//CONFIG_AUTO_AP_MODE + +u8 setopmode_hdl(_adapter *padapter, u8 *pbuf) +{ + u8 type; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; + + if(psetop->mode == Ndis802_11APMode) + { + pmlmeinfo->state = WIFI_FW_AP_STATE; + type = _HW_STATE_AP_; +#ifdef CONFIG_NATIVEAP_MLME + //start_ap_mode(padapter); +#endif + } + else if(psetop->mode == Ndis802_11Infrastructure) + { + pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state + pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE + type = _HW_STATE_STATION_; + } + else if(psetop->mode == Ndis802_11IBSS) + { + type = _HW_STATE_ADHOC_; + } + else + { + type = _HW_STATE_NOLINK_; + } + + rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); + //Set_NETYPE0_MSR(padapter, type); + +#ifdef CONFIG_AUTO_AP_MODE + if(psetop->mode == Ndis802_11APMode) + rtw_auto_ap_start_beacon(padapter); +#endif + + return H2C_SUCCESS; + +} + +u8 createbss_hdl(_adapter *padapter, u8 *pbuf) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; + u32 initialgain; + + + if(pparm->network.InfrastructureMode == Ndis802_11APMode) + { +#ifdef CONFIG_AP_MODE + + if(pmlmeinfo->state == WIFI_FW_AP_STATE) + { + //todo: + return H2C_SUCCESS; + } +#endif + } + + //below is for ad-hoc master + if(pparm->network.InfrastructureMode == Ndis802_11IBSS) + { + rtw_joinbss_reset(padapter); + + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pmlmeinfo->ERP_enable = 0; + pmlmeinfo->WMM_enable = 0; + pmlmeinfo->HT_enable = 0; + pmlmeinfo->HT_caps_enable = 0; + pmlmeinfo->HT_info_enable = 0; + 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)); + + //cancel link timer + _cancel_timer_ex(&pmlmeext->link_timer); + + //clear CAM + flush_all_cam_entry(padapter); + + _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); + pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength; + + if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength + return H2C_PARAMETERS_ERROR; + + _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength); + + start_create_ibss(padapter); + + } + + return H2C_SUCCESS; + +} + +u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) +{ + u8 join_type; + PNDIS_802_11_VARIABLE_IEs pIE; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); +#ifdef CONFIG_ANTENNA_DIVERSITY + struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; +#endif //CONFIG_ANTENNA_DIVERSITY + u32 initialgain, i; + u8 cbw40_enable=0; + //u32 acparm; + + //check already connecting to AP or not + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + if (pmlmeinfo->state & WIFI_FW_STATION_STATE) + { + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100); + } + + pmlmeinfo->state = WIFI_FW_NULL_STATE; + + //clear CAM + flush_all_cam_entry(padapter); + + _cancel_timer_ex(&pmlmeext->link_timer); + + //set MSR to nolink -> infra. mode + //Set_MSR(padapter, _HW_STATE_NOLINK_); + Set_MSR(padapter, _HW_STATE_STATION_); + + + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0); + } + +#ifdef CONFIG_ANTENNA_DIVERSITY + rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE); +#endif + + rtw_joinbss_reset(padapter); + + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pmlmeinfo->ERP_enable = 0; + pmlmeinfo->WMM_enable = 0; + pmlmeinfo->HT_enable = 0; + pmlmeinfo->HT_caps_enable = 0; + pmlmeinfo->HT_info_enable = 0; + pmlmeinfo->agg_enable_bitmap = 0; + pmlmeinfo->candidate_tid_bitmap = 0; + pmlmeinfo->bwmode_updated = _FALSE; + //pmlmeinfo->assoc_AP_vendor = maxAP; + + _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); + pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength; + + if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength + return H2C_PARAMETERS_ERROR; + + _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength); + + pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; + pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); + + //Check AP vendor to move rtw_joinbss_cmd() + //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); + + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_://Get WMM IE. + if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) ) + { + pmlmeinfo->WMM_enable = 1; + } + break; + + case _HT_CAPABILITY_IE_: //Get HT Cap IE. + pmlmeinfo->HT_caps_enable = 1; + break; + + case _HT_EXTRA_INFO_IE_: //Get HT Info IE. + pmlmeinfo->HT_info_enable = 1; + + //spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz +//#if !defined(CONFIG_CONCURRENT_MODE) && !defined(CONFIG_DUALMAC_CONCURRENT) +// if(pmlmeinfo->assoc_AP_vendor == ciscoAP) +//#endif + { + struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data); + + if( pnetwork->Configuration.DSConfig > 14 ) + { + if( pregpriv->cbw40_enable & BIT(1) ) + cbw40_enable = 1; + } + else + if( pregpriv->cbw40_enable & BIT(0) ) + cbw40_enable = 1; + + if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) + { + //switch to the 40M Hz mode according to the AP + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + switch (pht_info->infos[0] & 0x3) + { + case 1: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case 3: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + DBG_871X("set ch/bw before connected\n"); + } + } + break; + + default: + break; + } + + i += (pIE->Length + 2); + } +#if 0 + if (padapter->registrypriv.wifi_spec) { + // for WiFi test, follow WMM test plan spec + acparm = 0x002F431C; // VO + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E541C; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + acparm = 0x0000A525; // BE + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A549; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + + // for WiFi test, mixed mode with intel STA under bg mode throughput issue + if (padapter->mlmepriv.htpriv.ht_option == _FALSE){ + acparm = 0x00004320; + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + } + } + else { + acparm = 0x002F3217; // VO + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E4317; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + acparm = 0x00105320; // BE + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A444; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + } +#endif + + /* check channel, bandwidth, offset and switch */ +#ifdef CONFIG_DUALMAC_CONCURRENT + if(dc_handle_join_request(padapter) == _FAIL) { + DBG_871X("dc_handle_join_request fail !!!\n"); + return H2C_SUCCESS; + } + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); +#else //NON CONFIG_DUALMAC_CONCURRENT + if(rtw_chk_start_clnt_join(padapter) == _FAIL) { + report_join_res(padapter, (-4)); + return H2C_SUCCESS; + } +#endif + + //disable dynamic functions, such as high power, DIG + //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)); + + + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); + join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + + //cancel link timer + _cancel_timer_ex(&pmlmeext->link_timer); + + start_clnt_join(padapter); + + return H2C_SUCCESS; + +} + +u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct disconnect_parm *param = (struct disconnect_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + u8 val8; + + if (is_client_associated_to_ap(padapter)) + { + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); + } + + //set_opmode_cmd(padapter, infra_client_with_mlme); + + //pmlmeinfo->state = WIFI_FW_NULL_STATE; + + + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0); + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); + + //restore to initial setting. + update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //Stop BCN + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); + } + + + //set MSR to no link state -> infra. mode + Set_MSR(padapter, _HW_STATE_STATION_); + + pmlmeinfo->state = WIFI_FW_NULL_STATE; + +#ifdef CONFIG_DUALMAC_CONCURRENT + dc_set_channel_bwmode_disconnect(padapter); +#else +#ifdef CONFIG_CONCURRENT_MODE + if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE) + { +#endif //CONFIG_CONCURRENT_MODE + //switch to the 20M Hz mode after disconnect + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); +#ifdef CONFIG_CONCURRENT_MODE + } +#endif //CONFIG_CONCURRENT_MODE +#endif //CONFIG_DUALMAC_CONCURRENT + + flush_all_cam_entry(padapter); + + _cancel_timer_ex(&pmlmeext->link_timer); + + rtw_free_uc_swdec_pending_queue(padapter); + + 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) +{ + int i, j; + int scan_ch_num = 0; + int set_idx; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + /* clear first */ + _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num); + + /* acquire channels from in */ + j = 0; + for (i=0;ichannel_set, in[i].hw_value)) >=0 + && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE + ) + { + if (j >= out_num) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", + FUNC_ADPT_ARG(padapter), out_num); + break; + } + + _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); + + if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) + out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; + + j++; + } + if(j>=out_num) + break; + } + + /* if out is empty, use channel_set as default */ + if(j == 0) { + for (i=0;imax_chan_nums;i++) { + + if (0) + DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum); + + if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) { + + if (j >= out_num) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", + FUNC_ADPT_ARG(padapter), out_num); + break; + } + + out[j].hw_value = pmlmeext->channel_set[i].ChannelNum; + + if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) + out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN; + + j++; + } + } + } + + return j; +} + +u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; + u8 bdelayscan = _FALSE; + u8 val8; + u32 initialgain; + u32 i; + u8 write_initial_gain = 1; + +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif + + if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) + { +#ifdef CONFIG_CONCURRENT_MODE + //for first time sitesurvey_cmd + rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); +#endif //CONFIG_CONCURRENT_MODE + + pmlmeext->sitesurvey_res.state = SCAN_START; + pmlmeext->sitesurvey_res.bss_cnt = 0; + pmlmeext->sitesurvey_res.channel_idx = 0; + + for(i=0;issid[i].SsidLength) { + _rtw_memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); + pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength; + } else { + pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0; + } + } + + pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter + , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT + , pparm->ch, pparm->ch_num + ); + + pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; + +#ifdef CONFIG_DUALMAC_CONCURRENT + bdelayscan = dc_handle_site_survey(padapter); +#endif + + //issue null data if associating to the AP + if (is_client_associated_to_ap(padapter) == _TRUE) + { + pmlmeext->sitesurvey_res.state = SCAN_TXNULL; + + issue_nulldata(padapter, NULL, 1, 3, 500); + +#ifdef CONFIG_CONCURRENT_MODE + if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE) + { + DBG_871X("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n"); + + issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); + } +#endif + bdelayscan = _TRUE; + } +#ifdef CONFIG_CONCURRENT_MODE + else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE) + { + #ifdef CONFIG_TDLS + if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1) + { + issue_tunneled_probe_req(padapter->pbuddy_adapter); + } + #endif //CONFIG_TDLS + + pmlmeext->sitesurvey_res.state = SCAN_TXNULL; + + issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); + + bdelayscan = _TRUE; + } +#endif + if(bdelayscan) + { + //delay 50ms to protect nulldata(1). + set_survey_timer(pmlmeext, 50); + return H2C_SUCCESS; + } + } + + if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) + { +#ifdef CONFIG_FIND_BEST_CHANNEL +#if 0 + for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + pmlmeext->channel_set[i].rx_count = 0; + } +#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 + if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + write_initial_gain = 0; + } + else +#endif //CONFIG_IOCTL_CFG80211 + if ( !rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) + initialgain = 0x28; + else +#endif //CONFIG_P2P + initialgain = 0x17; + + if(write_initial_gain == 1) + rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); + + //set MSR to no link state + Set_MSR(padapter, _HW_STATE_NOLINK_); + + val8 = 1; //under site survey + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + pmlmeext->sitesurvey_res.state = SCAN_PROCESS; + } + + site_survey(padapter); + + return H2C_SUCCESS; + +} + +u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct setauth_parm *pparm = (struct setauth_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (pparm->mode < 4) + { + pmlmeinfo->auth_algo = pparm->mode; + } + + return H2C_SUCCESS; +} + +u8 setkey_hdl(_adapter *padapter, u8 *pbuf) +{ + unsigned short ctrl; + struct setkey_parm *pparm = (struct setkey_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + //main tx key for wep. + if(pparm->set_tx) + pmlmeinfo->key_index = pparm->keyid; + + //write cam + ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; + + write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key); + + //allow multicast packets to driver + rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr); + + return H2C_SUCCESS; +} + +u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf) +{ + u16 ctrl=0; + u8 cam_id;//cam_entry + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; +#endif //CONFIG_TDLS + + //cam_entry: + //0~3 for default key + + //for concurrent mode (ap+sta): + //default key is disable, using sw encrypt/decrypt + //cam_entry = 4 //for sta mode (macid=0) + //cam_entry(macid+3) = 5 ~ N//for ap mode (aid=1~N, macid=2 ~N) + + //for concurrent mode (sta+sta): + //default key is disable, using sw encrypt/decrypt + //cam_entry = 4 //mapping to macid=0 + //cam_entry = 5 //mapping to macid=2 + +#ifdef CONFIG_CONCURRENT_MODE + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; + + psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); + + if(psta && psta->mac_id==2) + { + cam_id = 5; + } + else + { + cam_id = 4; + } +/* + if(padapter->iface_type > PRIMARY_IFACE) + { + cam_id = 5; + } + else + { + cam_id = 4; + } +*/ + } +#else + cam_id = 4; +#endif + + + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + if(pparm->algorithm == _NO_PRIVACY_) // clear cam entry + { + clear_cam_entry(padapter, pparm->id); + return H2C_SUCCESS_RSP; + } + + psta = rtw_get_stainfo(pstapriv, pparm->addr); + if(psta) + { + ctrl = (BIT(15) | ((pparm->algorithm) << 2)); + + DBG_871X("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm); + + if((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4))) + { + DBG_871X("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id); + return H2C_REJECTED; + } + + cam_id = (psta->mac_id + 3);//0~3 for default key, cmd_id=macid + 3, macid=aid+1; + + DBG_871X("Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0], + pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4], + pparm->addr[5], cam_id); + + write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); + + return H2C_SUCCESS_RSP; + + } + else + { + DBG_871X("r871x_set_stakey_hdl(): sta has been free\n"); + return H2C_REJECTED; + } + + } + + //below for sta mode + + if(pparm->algorithm == _NO_PRIVACY_) // clear cam entry + { + clear_cam_entry(padapter, pparm->id); + return H2C_SUCCESS; + } + + ctrl = BIT(15) | ((pparm->algorithm) << 2); + +#ifdef CONFIG_TDLS + if(ptdlsinfo->clear_cam!=0){ + clear_cam_entry(padapter, ptdlsinfo->clear_cam); + ptdlsinfo->clear_cam=0; + + return H2C_SUCCESS; + } + + psta = rtw_get_stainfo(pstapriv, pparm->addr);//Get TDLS Peer STA + if( psta->tdls_sta_state&TDLS_LINKED_STATE ){ + write_cam(padapter, psta->mac_id, ctrl, pparm->addr, pparm->key); + } + else +#endif //CONFIG_TDLS + write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); + + pmlmeinfo->enc_algo = pparm->algorithm; + + return H2C_SUCCESS; +} + +u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); + + if(!psta) + return H2C_SUCCESS; + + + if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || + ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pmlmeinfo->ADDBA_retry_count = 0; + //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); + //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); + issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); + //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); + _set_timer(&psta->addba_retry_timer, ADDBA_TO); + } +#ifdef CONFIG_TDLS + else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&& + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE) ) + { + issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); + //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); + _set_timer(&psta->addba_retry_timer, ADDBA_TO); + } +#endif //CONFIG + else + { + psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); + } + + return H2C_SUCCESS; +} + +u8 set_tx_beacon_cmd(_adapter* padapter) +{ + struct cmd_obj *ph2c; + struct Tx_Beacon_param *ptxBeacon_parm; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 res = _SUCCESS; + int len_diff = 0; + +_func_enter_; + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + res= _FAIL; + goto exit; + } + + if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL) + { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX)); + + len_diff = update_hidden_ssid( + ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_ + , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_ + , pmlmeinfo->hidden_ssid_mode + ); + ptxBeacon_parm->network.IELength += len_diff; + + init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + +exit: + +_func_exit_; + + return res; +} + + +u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf) +{ + u8 evt_code, evt_seq; + u16 evt_sz; + uint *peventbuf; + void (*event_callback)(_adapter *dev, u8 *pbuf); + struct evt_priv *pevt_priv = &(padapter->evtpriv); + + peventbuf = (uint*)pbuf; + evt_sz = (u16)(*peventbuf&0xffff); + evt_seq = (u8)((*peventbuf>>24)&0x7f); + evt_code = (u8)((*peventbuf>>16)&0xff); + + + #ifdef CHECK_EVENT_SEQ + // checking event sequence... + if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) ) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f))); + + pevt_priv->event_seq = (evt_seq+1)&0x7f; + + goto _abort_event_; + } + #endif + + // checking if event code is valid + if (evt_code >= MAX_C2HEVT) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code)); + goto _abort_event_; + } + + // checking if event size match the event parm size + if ((wlanevents[evt_code].parmsize != 0) && + (wlanevents[evt_code].parmsize != evt_sz)) + { + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n", + evt_code, wlanevents[evt_code].parmsize, evt_sz)); + goto _abort_event_; + + } + + ATOMIC_INC(&pevt_priv->event_seq); + + peventbuf += 2; + + if(peventbuf) + { + event_callback = wlanevents[evt_code].event_callback; + event_callback(padapter, (u8*)peventbuf); + + pevt_priv->evt_done_cnt++; + } + + +_abort_event_: + + + return H2C_SUCCESS; + +} + +u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf) +{ + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + return H2C_SUCCESS; +} + +u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) +{ + if(send_beacon(padapter)==_FAIL) + { + DBG_871X("issue_beacon, fail!\n"); + return H2C_PARAMETERS_ERROR; + } +#ifdef CONFIG_AP_MODE + else //tx bc/mc frames after update TIM + { + _irqL irqL; + struct sta_info *psta_bmc; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + + //for BC/MC Frames + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if(!psta_bmc) + return H2C_SUCCESS; + + if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0)) + { +#ifndef CONFIG_PCI_HCI + rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows +#endif + //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta_bmc->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta_bmc->sleepq_len--; + if(psta_bmc->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + pxmitframe->attrib.triggered=1; + + pxmitframe->attrib.qsel = 0x11;//HIQ + +#if 0 + _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + +#endif + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + //pstapriv->tim_bitmap &= ~BIT(0); + + } + + //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + } + + } +#endif + + return H2C_SUCCESS; + +} + +void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork) +{ + u8 network_type,rate_len, total_rate_len,remainder_rate_len; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 erpinfo=0x4; + + //DBG_871X("%s\n", __FUNCTION__); + + if(pmlmeext->cur_channel >= 36) + { + network_type = WIRELESS_11A; + total_rate_len = IEEE80211_NUM_OFDM_RATESLEN; + DBG_871X("%s(): change to 5G Band\n",__FUNCTION__); + rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_); + } + else + { + network_type = WIRELESS_11BG; + total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN; + DBG_871X("%s(): change to 2.4G Band\n",__FUNCTION__); + rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1); + } + + rtw_set_supported_rate(pnetwork->SupportedRates, network_type); + + UpdateBrateTbl(padapter, pnetwork->SupportedRates); + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); + + if(total_rate_len > 8) + { + rate_len = 8; + remainder_rate_len = total_rate_len - 8; + } + else + { + rate_len = total_rate_len; + remainder_rate_len = 0; + } + + rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len); + + if(remainder_rate_len) + { + rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len); + } + else + { + rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_); + } +} + + +#ifdef CONFIG_DUALMAC_CONCURRENT +void dc_SelectChannel(_adapter *padapter, unsigned char channel) +{ + PADAPTER ptarget_adapter; + + if( (padapter->pbuddy_adapter != NULL) && + (padapter->DualMacConcurrent == _TRUE) && + (padapter->adapter_type == SECONDARY_ADAPTER)) + { + // only mac0 could control BB&RF + ptarget_adapter = padapter->pbuddy_adapter; + } + else + { + ptarget_adapter = padapter; + } + + _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL); + + rtw_hal_set_chan(ptarget_adapter, channel); + + _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL); +} + +void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset) +{ + PADAPTER ptarget_adapter; + + if( (padapter->pbuddy_adapter != NULL) && + (padapter->DualMacConcurrent == _TRUE) && + (padapter->adapter_type == SECONDARY_ADAPTER)) + { + // only mac0 could control BB&RF + ptarget_adapter = padapter->pbuddy_adapter; + } + else + { + ptarget_adapter = padapter; + } + + _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL); + + rtw_hal_set_bwmode(ptarget_adapter, (HT_CHANNEL_WIDTH)bwmode, channel_offset); + + _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL); +} + +void dc_set_channel_bwmode_disconnect(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + if((check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) != _TRUE) + { + //switch to the 20M Hz mode after disconnect + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } + } + else + { + //switch to the 20M Hz mode after disconnect + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } +} + +u8 dc_handle_join_request(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = NULL; + struct mlme_priv *pbuddy_mlmepriv = NULL; + u8 ret = _SUCCESS; + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + + if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel || + pmlmeext->cur_bwmode != pbuddy_mlmeext->cur_bwmode || + pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) + { + if((check_fwstate(pbuddy_mlmepriv, WIFI_AP_STATE)) == _TRUE) + { + //issue deauth to all stas if if2 is at ap mode + rtw_sta_flush(pbuddy_adapter); + + //rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_CHECK_TXBUF, 0); + } + else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE) + { + if(pmlmeext->cur_channel == pbuddy_mlmeext->cur_channel) + { + // HT_CHANNEL_WIDTH_40 or HT_CHANNEL_WIDTH_20 but channel offset is different + if((pmlmeext->cur_bwmode == pbuddy_mlmeext->cur_bwmode) && + (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) ) + { + report_join_res(padapter, -4); + ret = _FAIL; + } + } + else + { + report_join_res(padapter, -4); + ret = _FAIL; + } + } + } + else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE) + { + issue_nulldata(pbuddy_adapter, NULL, 1, 0, 0); + } + } + + return ret; +} + +void dc_handle_join_done(_adapter *padapter, u8 join_res) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + struct mlme_ext_priv *pbuddy_mlmeext = NULL; + struct mlme_ext_info *pbuddy_mlmeinfo = NULL; + WLAN_BSSID_EX *pbuddy_network_mlmeext = NULL; + u8 change_band = _FALSE; + + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info); + pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network); + + if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) + { + //restart and update beacon + DBG_871X("after join, current adapter, CH=%d, BW=%d, offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + + if(join_res >= 0) + { + u8 *p; + int ie_len; + struct HT_info_element *pht_info=NULL; + + if((pbuddy_mlmeext->cur_channel <= 14 && pmlmeext->cur_channel >= 36) || + (pbuddy_mlmeext->cur_channel >= 36 && pmlmeext->cur_channel <= 14)) + { + change_band = _TRUE; + } + + //sync channel/bwmode/ch_offset with another adapter + pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel; + + if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present + } + + if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset; + + //to update cur_ch_offset value in beacon + if( pht_info ) + { + switch(pmlmeext->cur_ch_offset) + { + case HAL_PRIME_CHNL_OFFSET_LOWER: + pht_info->infos[0] |= 0x1; + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + pht_info->infos[0] |= 0x3; + break; + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + default: + break; + } + } + } + else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) + { + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if(pmlmeext->cur_channel>0 && pmlmeext->cur_channel<5) + { + if(pht_info) + pht_info->infos[0] |= 0x1; + + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } + + if(pmlmeext->cur_channel>7 && pmlmeext->cur_channel<(14+1)) + { + if(pht_info) + pht_info->infos[0] |= 0x3; + + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } + + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + } + } + + // to update channel value in beacon + pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel; + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if(p && ie_len>0) + *(p + 2) = pmlmeext->cur_channel; + + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + pht_info->primary_channel = pmlmeext->cur_channel; + } + + // update mlmepriv's cur_network + _rtw_memcpy(&pbuddy_mlmepriv->cur_network.network, pbuddy_network_mlmeext, pbuddy_network_mlmeext->Length); + } + else + { + // switch back to original channel/bwmode/ch_offset; + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + } + + DBG_871X("after join, another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + + if(change_band == _TRUE) + change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext); + + DBG_871X("update pbuddy_adapter's beacon\n"); + + update_beacon(pbuddy_adapter, 0, NULL, _TRUE); + } + else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE) + { + if((pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) && + (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)) + { + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + } + + issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0); + } + } +} + +sint dc_check_fwstate(_adapter *padapter, sint fw_state) +{ + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + + if(padapter->pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + + return check_fwstate(pbuddy_mlmepriv, fw_state); + } + + return _FALSE; +} + +u8 dc_handle_site_survey(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + + // only mac0 can do scan request, help issue nulldata(1) for mac1 + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE) + { + pmlmeext->sitesurvey_res.state = SCAN_TXNULL; + + issue_nulldata(pbuddy_adapter, NULL, 1, 2, 0); + + return _TRUE; + } + } + + return _FALSE; +} + +void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame) +{ + if(padapter->pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + report_survey_event(padapter->pbuddy_adapter, precv_frame); + } +} + +void dc_set_channel_bwmode_survey_done(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + struct mlme_ext_priv *pbuddy_mlmeext = NULL; + struct mlme_ext_info *pbuddy_mlmeinfo = NULL; + u8 cur_channel; + u8 cur_bwmode; + u8 cur_ch_offset; + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info); + + if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) + { + if(check_fwstate(pmlmepriv, _FW_LINKED) && + (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)) + { + cur_channel = pmlmeext->cur_channel; + cur_bwmode = pmlmeext->cur_bwmode; + cur_ch_offset = pmlmeext->cur_ch_offset; + } + else + { + cur_channel = pbuddy_mlmeext->cur_channel; + cur_bwmode = pbuddy_mlmeext->cur_bwmode; + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + } + } + else + { + cur_channel = pmlmeext->cur_channel; + cur_bwmode = pmlmeext->cur_bwmode; + cur_ch_offset = pmlmeext->cur_ch_offset; + } + + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + + if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE) + { + //issue null data + issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0); + } + + if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) + { + + DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + DBG_871X("restart pbuddy_adapter's beacon\n"); + + update_beacon(pbuddy_adapter, 0, NULL, _TRUE); + } + } + else + { + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } +} + +void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode) +{ + u8 *p; + u8 val8, cur_channel, cur_bwmode, cur_ch_offset, change_band; + int ie_len; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct HT_info_element *pht_info=NULL; + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + struct mlme_ext_priv *pbuddy_mlmeext = NULL; + + DBG_871X("dualmac_concurrent_ap_set_channel_bwmode ==>\n"); + + cur_channel = channel; + cur_bwmode = bwmode; + cur_ch_offset = channel_offset; + change_band = _FALSE; + + p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + } + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + if(!check_fwstate(pbuddy_mlmepriv, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + } + else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)==_TRUE) + { + //To sync cur_channel/cur_bwmode/cur_ch_offset with another adapter + DBG_871X("Another iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n"); + DBG_871X("Another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + DBG_871X("Current adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + cur_channel = pbuddy_mlmeext->cur_channel; + if(cur_bwmode == HT_CHANNEL_WIDTH_40) + { + if(pht_info) + pht_info->infos[0] &= ~(BIT(0)|BIT(1)); + + if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + + //to update cur_ch_offset value in beacon + if(pht_info) + { + switch(cur_ch_offset) + { + case HAL_PRIME_CHNL_OFFSET_LOWER: + pht_info->infos[0] |= 0x1; + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + pht_info->infos[0] |= 0x3; + break; + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + default: + break; + } + } + } + else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) + { + cur_bwmode = HT_CHANNEL_WIDTH_20; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if(cur_channel>0 && cur_channel<5) + { + if(pht_info) + pht_info->infos[0] |= 0x1; + + cur_bwmode = HT_CHANNEL_WIDTH_40; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } + + if(cur_channel>7 && cur_channel<(14+1)) + { + if(pht_info) + pht_info->infos[0] |= 0x3; + + cur_bwmode = HT_CHANNEL_WIDTH_40; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } + + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + } + } + + // to update channel value in beacon + pnetwork->Configuration.DSConfig = cur_channel; + p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if(p && ie_len>0) + *(p + 2) = cur_channel; + + if(pht_info) + pht_info->primary_channel = cur_channel; + } + } + else + { + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); + } + + DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset); + + if((channel <= 14 && cur_channel >= 36) || + (channel >= 36 && cur_channel <= 14)) + { + change_band = _TRUE; + } + + pmlmeext->cur_channel = cur_channel; + pmlmeext->cur_bwmode = cur_bwmode; + pmlmeext->cur_ch_offset = cur_ch_offset; + + if(change_band == _TRUE) + change_band_update_ie(padapter, pnetwork); + + DBG_871X("dualmac_concurrent_ap_set_channel_bwmode <==\n"); +} + +void dc_resume_xmit(_adapter *padapter) +{ + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + DBG_871X("dc_resume_xmit, resume pbuddy_adapter Tx\n"); + rtw_os_xmit_schedule(pbuddy_adapter); + } +} + +u8 dc_check_xmit(_adapter *padapter) +{ + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = NULL; + + if(pbuddy_adapter != NULL && + padapter->DualMacConcurrent == _TRUE) + { + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_871X("dc_check_xmit pbuddy_adapter is under survey or under linking\n"); + return _FALSE; + } + } + + return _TRUE; +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state) +{ + PADAPTER pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext; + struct mlme_ext_info *pbuddy_mlmeinfo; + + if(padapter == NULL) + return _FALSE; + + pbuddy_adapter = padapter->pbuddy_adapter; + + if(pbuddy_adapter == NULL) + return _FALSE; + + + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info); + + if((pbuddy_mlmeinfo->state&0x03) == state) + return _TRUE; + + return _FALSE; + +} + +void concurrent_chk_joinbss_done(_adapter *padapter, int join_res) +{ + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + PADAPTER pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext; + struct mlme_ext_info *pbuddy_mlmeinfo; + WLAN_BSSID_EX *pbuddy_network_mlmeext; + + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &(pmlmeext->mlmext_info); + + + if(!rtw_buddy_adapter_up(padapter)) + { + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + return; + } + + pbuddy_adapter = padapter->pbuddy_adapter; + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info); + pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network); + + if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) + { + //restart and update beacon + + DBG_871X("after join,primary adapter, CH=%d, BW=%d, offset=%d\n" + , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + + + if(join_res >= 0) + { + u8 *p; + int ie_len; + u8 change_band = _FALSE; + struct HT_info_element *pht_info=NULL; + + if((pmlmeext->cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) || + (pmlmeext->cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14)) + change_band = _TRUE; + + //sync channel/bwmode/ch_offset with primary adapter + pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel; + if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + pht_info->infos[0] &= ~(BIT(0)|BIT(1)); //no secondary channel is present + } + + if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + { + pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset; + + //to update cur_ch_offset value in beacon + if( pht_info ) + { + switch(pmlmeext->cur_ch_offset) + { + case HAL_PRIME_CHNL_OFFSET_LOWER: + pht_info->infos[0] |= 0x1; + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + pht_info->infos[0] |= 0x3; + break; + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + default: + break; + } + + } + + } + else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) + { + if(pmlmeext->cur_channel>=1 && pmlmeext->cur_channel<=4) + { + if(pht_info) + pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE; + + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } + else if(pmlmeext->cur_channel>=5 && pmlmeext->cur_channel<=14) + { + if(pht_info) + pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; + + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } + else + { + switch(pmlmeext->cur_channel) + { + case 36: + case 44: + case 52: + case 60: + case 100: + case 108: + case 116: + case 124: + case 132: + case 149: + case 157: + { + if(pht_info) + pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE; + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + } + case 40: + case 48: + case 56: + case 64: + case 104: + case 112: + case 120: + case 128: + case 136: + case 153: + case 161: + { + if(pht_info) + pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; + + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + } + default: + if(pht_info) + pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; + pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; + pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + + } + + } + + } + + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + } + else + { + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } + + + // to update channel value in beacon + pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel; + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if(p && ie_len>0) + *(p + 2) = pmlmeext->cur_channel; + + p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if( p && ie_len) + { + pht_info = (struct HT_info_element *)(p+2); + pht_info->primary_channel = pmlmeext->cur_channel; + } + + //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE + if(change_band == _TRUE) + change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext); + } + else + { + // switch back to original channel/bwmode/ch_offset; + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + } + + DBG_871X("after join, second adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + + DBG_871X("update pbuddy_adapter's beacon\n"); + + update_beacon(pbuddy_adapter, 0, NULL, _TRUE); + + } + else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && + check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) + { + if(join_res >= 0) + { + pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel; + if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + else + set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + else + { + // switch back to original channel/bwmode/ch_offset; + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + } + } + else + { + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + } + +} +#endif //CONFIG_CONCURRENT_MODE + +int rtw_chk_start_clnt_join(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + unsigned char cur_ch = pmlmeext->cur_channel; + unsigned char cur_bw = pmlmeext->cur_bwmode; + unsigned char cur_ch_offset = pmlmeext->cur_ch_offset; + bool chbw_allow = _TRUE; + bool connect_allow = _TRUE; + +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext; + struct mlme_ext_info *pbuddy_pmlmeinfo; + struct mlme_priv *pbuddy_mlmepriv; + + if (!rtw_buddy_adapter_up(padapter)) { + goto start_join_set_ch_bw; + } + + pbuddy_adapter = padapter->pbuddy_adapter; + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info); + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + + if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE + { + DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)" + ", "ADPT_FMT" AP mode(ch=%d, bw=%d, ch_offset=%d)\n", + ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, + ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + + if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel) + { + chbw_allow = _FALSE; + } + else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) && + (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) && + (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)) + { + chbw_allow = _FALSE; + } + else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) && + (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)) + { + cur_ch = pmlmeext->cur_channel; + cur_bw = pbuddy_mlmeext->cur_bwmode; + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + } + + DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow); + if (chbw_allow == _FALSE) { + #ifdef CONFIG_SPCT_CH_SWITCH + if (1) { + rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset); + } else + #endif + { + //issue deauth to all stas if if2 is at ap mode + rtw_sta_flush(pbuddy_adapter); + } + rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + } + } + else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE && + check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client + { + DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)" + ", "ADPT_FMT" STA mode(ch=%d, bw=%d, ch_offset=%d)\n", + ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, + ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset); + + if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel) + { + chbw_allow = _FALSE; + } + else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) && + (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)) + { + cur_bw = HT_CHANNEL_WIDTH_40; + cur_ch_offset = pbuddy_mlmeext->cur_ch_offset; + } + else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) && + (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) && + (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)) + { + chbw_allow = _FALSE; + } + + connect_allow = chbw_allow; + + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + /* wlan0-sta mode has higher priority than p2p0-p2p client */ + if (!rtw_p2p_chk_state(&(pbuddy_adapter->wdinfo), P2P_STATE_NONE) + && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211) + { + connect_allow = _TRUE; + } + #endif /* CONFIG_P2P && CONFIG_IOCTL_CFG80211 */ + + DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow); + if (connect_allow == _TRUE && chbw_allow == _FALSE) { + /* disconnect buddy's connection */ + rtw_disassoc_cmd(pbuddy_adapter, 500, _FALSE); + rtw_indicate_disconnect(pbuddy_adapter); + rtw_free_assoc_resources(pbuddy_adapter, 1); + } + } + +start_join_set_ch_bw: +#endif /* CONFIG_CONCURRENT_MODE */ + + if (connect_allow == _TRUE) { + DBG_871X("start_join_set_ch_bw: ch=%d, bwmode=%d, ch_offset=%d\n", cur_ch, cur_bw, cur_ch_offset); + set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw); + } + + return connect_allow == _TRUE ? _SUCCESS : _FAIL; +} + +/* Find union about ch, bw, ch_offset of all linked interfaces */ +int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + int i; + u8 ch_ret = 0; + u8 bw_ret = HT_CHANNEL_WIDTH_20; + u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + int num = 0; + + if (ch) *ch = 0; + if (bw) *bw = HT_CHANNEL_WIDTH_20; + if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + for (i = 0; iiface_nums; i++) { + iface = dvobj->padapters[i]; + mlmeext = &iface->mlmeextpriv; + + if (!check_fwstate(&iface->mlmepriv, _FW_LINKED)) + continue; + + if (num == 0) { + ch_ret = mlmeext->cur_channel; + bw_ret = mlmeext->cur_bwmode; + offset_ret = mlmeext->cur_ch_offset; + num++; + continue; + } + + if (ch_ret != mlmeext->cur_channel) { + num = 0; + break; + } + + if (bw_ret < mlmeext->cur_bwmode) { + bw_ret = mlmeext->cur_bwmode; + offset_ret = mlmeext->cur_ch_offset; + } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) { + num = 0; + break; + } + + num++; + } + + if (num) { + if (ch) *ch = ch_ret; + if (bw) *bw = bw_ret; + if (offset) *offset = offset_ret; + } + + return num; +} + +u8 set_ch_hdl(_adapter *padapter, u8 *pbuf) +{ + struct set_ch_parm *set_ch_parm; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + set_ch_parm = (struct set_ch_parm *)pbuf; + + DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), + set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); + + pmlmeext->cur_channel = set_ch_parm->ch; + pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; + pmlmeext->cur_bwmode = set_ch_parm->bw; + + set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); + + return H2C_SUCCESS; +} + +u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct SetChannelPlan_param *setChannelPlan_param; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + setChannelPlan_param = (struct SetChannelPlan_param *)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); + + return H2C_SUCCESS; +} + +u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct LedBlink_param *ledBlink_param; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + ledBlink_param = (struct LedBlink_param *)pbuf; + + #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD + BlinkHandler(ledBlink_param->pLed); + #endif + + return H2C_SUCCESS; +} + +u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf) +{ +#ifdef CONFIG_DFS + struct SetChannelSwitch_param *setChannelSwitch_param; + struct SetChannelPlan_param *setChannelPlan_param; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u8 new_ch_no; + u8 gval8 = 0x00, sval8 = 0xff; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf; + new_ch_no = setChannelSwitch_param->new_ch_no; + + rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8); + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8); + + DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no); + SelectChannel(padapter, new_ch_no); + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8); + + rtw_free_network_queue(padapter, _TRUE); + rtw_indicate_disconnect(padapter); + + if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) { + DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no); + } + + return H2C_SUCCESS; +#else + return H2C_REJECTED; +#endif //CONFIG_DFS + +} + +// TDLS_WRCR : write RCR DATA BIT +// TDLS_SD_PTI : issue peer traffic indication +// TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure +// TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame +// TDLS_DONE_CH_SEN: channel sensing and report candidate channel +// TDLS_OFF_CH : first time set channel to off channel +// TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel +// TDLS_P_OFF_CH : periodically go to off channel +// TDLS_P_BASE_CH : periodically go back to base channel +// TDLS_RS_RCR : restore RCR +// TDLS_CKALV_PH1 : check alive timer phase1 +// TDLS_CKALV_PH2 : check alive timer phase2 +// TDLS_FREE_STA : free tdls sta +u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf) +{ +#ifdef CONFIG_TDLS + _irqL irqL; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct TDLSoption_param *TDLSoption; + struct sta_info *ptdls_sta; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u8 survey_channel, i, min, option; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + TDLSoption = (struct TDLSoption_param *)pbuf; + + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr ); + option = TDLSoption->option; + + if( ptdls_sta == NULL ) + { + if( option != TDLS_RS_RCR ) + return H2C_REJECTED; + } + + //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + DBG_871X("[%s] option:%d\n", __FUNCTION__, option); + + switch(option){ + case TDLS_WRCR: + //As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 + //such we can receive all kinds of data frames. + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0); + DBG_871X("TDLS with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr)); + + pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta; + //set TDLS sta rate. + set_sta_rate(padapter, ptdls_sta); + break; + case TDLS_SD_PTI: + issue_tdls_peer_traffic_indication(padapter, ptdls_sta); + break; + case TDLS_CS_OFF: + _cancel_timer_ex(&ptdls_sta->base_ch_timer); + _cancel_timer_ex(&ptdls_sta->off_ch_timer); + SelectChannel(padapter, pmlmeext->cur_channel); + ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE | + TDLS_PEER_AT_OFF_STATE | + TDLS_AT_OFF_CH_STATE); + DBG_871X("go back to base channel\n "); + issue_nulldata(padapter, NULL, 0, 0, 0); + break; + case TDLS_INIT_CH_SEN: + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_INIT_CH_SEN, 0); + pmlmeext->sitesurvey_res.channel_idx = 0; + ptdls_sta->option = TDLS_DONE_CH_SEN; + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN); + break; + case TDLS_DONE_CH_SEN: + survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; + if(survey_channel){ + SelectChannel(padapter, survey_channel); + ptdlsinfo->cur_channel = survey_channel; + pmlmeext->sitesurvey_res.channel_idx++; + _set_timer(&ptdls_sta->option_timer, SURVEY_TO); + }else{ + SelectChannel(padapter, pmlmeext->cur_channel); + + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_DONE_CH_SEN, 0); + + if(ptdlsinfo->ch_sensing==1){ + ptdlsinfo->ch_sensing=0; + ptdlsinfo->cur_channel=1; + min=ptdlsinfo->collect_pkt_num[0]; + for(i=1; i ptdlsinfo->collect_pkt_num[i]){ + ptdlsinfo->cur_channel=i+1; + min=ptdlsinfo->collect_pkt_num[i]; + } + ptdlsinfo->collect_pkt_num[i]=0; + } + ptdlsinfo->collect_pkt_num[0]=0; + ptdlsinfo->candidate_ch=ptdlsinfo->cur_channel; + DBG_871X("TDLS channel sensing done, candidate channel: %02x\n", ptdlsinfo->candidate_ch); + ptdlsinfo->cur_channel=0; + + } + + if(ptdls_sta->tdls_sta_state & TDLS_PEER_SLEEP_STATE){ + ptdls_sta->tdls_sta_state |= TDLS_APSD_CHSW_STATE; + }else{ + //send null data with pwrbit==1 before send ch_switching_req to peer STA. + issue_nulldata(padapter, NULL, 1, 0, 0); + + ptdls_sta->tdls_sta_state |= TDLS_CH_SW_INITIATOR_STATE; + + issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr); + DBG_871X("issue tdls ch switch req\n"); + } + } + break; + case TDLS_OFF_CH: + issue_nulldata(padapter, NULL, 1, 0, 0); + SelectChannel(padapter, ptdls_sta->off_ch); + + DBG_871X("change channel to tar ch:%02x\n", ptdls_sta->off_ch); + ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE; + ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE); + _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time); + break; + case TDLS_BASE_CH: + _cancel_timer_ex(&ptdls_sta->base_ch_timer); + _cancel_timer_ex(&ptdls_sta->off_ch_timer); + SelectChannel(padapter, pmlmeext->cur_channel); + ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE | + TDLS_PEER_AT_OFF_STATE | + TDLS_AT_OFF_CH_STATE); + DBG_871X("go back to base channel\n "); + issue_nulldata(padapter, NULL, 0, 0, 0); + _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time); + break; + case TDLS_P_OFF_CH: + SelectChannel(padapter, pmlmeext->cur_channel); + issue_nulldata(padapter, NULL, 0, 0, 0); + DBG_871X("change channel to base ch:%02x\n", pmlmeext->cur_channel); + ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE| TDLS_AT_OFF_CH_STATE); + _set_timer(&ptdls_sta->off_ch_timer, TDLS_STAY_TIME); + break; + case TDLS_P_BASE_CH: + issue_nulldata(ptdls_sta->padapter, NULL, 1, 0, 0); + SelectChannel(padapter, ptdls_sta->off_ch); + DBG_871X("change channel to off ch:%02x\n", ptdls_sta->off_ch); + ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE; + if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE){ + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0); + } + _set_timer(&ptdls_sta->base_ch_timer, TDLS_STAY_TIME); + break; + case TDLS_RS_RCR: + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0); + DBG_871X("wirte REG_RCR, set bit6 on\n"); + break; + case TDLS_CKALV_PH1: + _set_timer(&ptdls_sta->alive_timer2, TDLS_ALIVE_TIMER_PH2); + break; + case TDLS_CKALV_PH2: + _set_timer(&ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1); + break; + case TDLS_FREE_STA: + free_tdls_sta(padapter, ptdls_sta); + break; + + } + + //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + + return H2C_SUCCESS; +#else + return H2C_REJECTED; +#endif //CONFIG_TDLS + +} + diff --git a/rtl8192cu-fixes/core/rtw_mp.c b/rtl8192cu-fixes/core/rtw_mp.c new file mode 100755 index 00000000..9af42cdc --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_mp.c @@ -0,0 +1,1324 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MP_C_ + +#include + +#ifdef PLATFORM_FREEBSD +#include /* for RFHIGHPID */ +#endif + +#ifdef CONFIG_RTL8712 +#include +#endif +#ifdef CONFIG_RTL8192C +#include +#endif +#ifdef CONFIG_RTL8192D +#include +#endif +#ifdef CONFIG_RTL8723A +#include +#endif + + +#ifdef CONFIG_MP_INCLUDED + +u32 read_macreg(_adapter *padapter, u32 addr, u32 sz) +{ + u32 val = 0; + + switch(sz) + { + case 1: + val = rtw_read8(padapter, addr); + break; + case 2: + val = rtw_read16(padapter, addr); + break; + case 4: + val = rtw_read32(padapter, addr); + break; + default: + val = 0xffffffff; + break; + } + + return val; + +} + +void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz) +{ + switch(sz) + { + case 1: + rtw_write8(padapter, addr, (u8)val); + break; + case 2: + rtw_write16(padapter, addr, (u16)val); + break; + case 4: + rtw_write32(padapter, addr, val); + break; + default: + break; + } + +} + +u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask) +{ + return rtw_hal_read_bbreg(padapter, addr, bitmask); +} + +void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val) +{ + rtw_hal_write_bbreg(padapter, addr, bitmask, val); +} + +u32 _read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask) +{ + return rtw_hal_read_rfreg(padapter, (RF_RADIO_PATH_E)rfpath, addr, bitmask); +} + +void _write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val) +{ + rtw_hal_write_rfreg(padapter, (RF_RADIO_PATH_E)rfpath, addr, bitmask, val); +} + +u32 read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr) +{ + return _read_rfreg(padapter, (RF_RADIO_PATH_E)rfpath, addr, bRFRegOffsetMask); +} + +void write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 val) +{ + _write_rfreg(padapter, (RF_RADIO_PATH_E)rfpath, addr, bRFRegOffsetMask, val); +} + +static void _init_mp_priv_(struct mp_priv *pmp_priv) +{ + WLAN_BSSID_EX *pnetwork; + + _rtw_memset(pmp_priv, 0, sizeof(struct mp_priv)); + + pmp_priv->mode = MP_OFF; + + pmp_priv->channel = 1; + pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20; + pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pmp_priv->rateidx = MPT_RATE_1M; + pmp_priv->txpoweridx = 0x2A; + + pmp_priv->antenna_tx = ANTENNA_A; + pmp_priv->antenna_rx = ANTENNA_AB; + + pmp_priv->check_mp_pkt = 0; + + pmp_priv->tx_pktcount = 0; + + pmp_priv->rx_pktcount = 0; + pmp_priv->rx_crcerrpktcount = 0; + + pmp_priv->network_macaddr[0] = 0x00; + pmp_priv->network_macaddr[1] = 0xE0; + pmp_priv->network_macaddr[2] = 0x4C; + pmp_priv->network_macaddr[3] = 0x87; + pmp_priv->network_macaddr[4] = 0x66; + pmp_priv->network_macaddr[5] = 0x55; + + pnetwork = &pmp_priv->mp_network.network; + _rtw_memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN); + + pnetwork->Ssid.SsidLength = 8; + _rtw_memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength); +} + +#ifdef PLATFORM_WINDOWS +/* +void mp_wi_callback( + IN NDIS_WORK_ITEM* pwk_item, + IN PVOID cntx + ) +{ + _adapter* padapter =(_adapter *)cntx; + struct mp_priv *pmppriv=&padapter->mppriv; + struct mp_wi_cntx *pmp_wi_cntx=&pmppriv->wi_cntx; + + // Execute specified action. + if(pmp_wi_cntx->curractfunc != NULL) + { + LARGE_INTEGER cur_time; + ULONGLONG start_time, end_time; + NdisGetCurrentSystemTime(&cur_time); // driver version + start_time = cur_time.QuadPart/10; // The return value is in microsecond + + pmp_wi_cntx->curractfunc(padapter); + + NdisGetCurrentSystemTime(&cur_time); // driver version + end_time = cur_time.QuadPart/10; // The return value is in microsecond + + RT_TRACE(_module_mp_, _drv_info_, + ("WorkItemActType: %d, time spent: %I64d us\n", + pmp_wi_cntx->param.act_type, (end_time-start_time))); + } + + NdisAcquireSpinLock(&(pmp_wi_cntx->mp_wi_lock)); + pmp_wi_cntx->bmp_wi_progress= _FALSE; + NdisReleaseSpinLock(&(pmp_wi_cntx->mp_wi_lock)); + + if (pmp_wi_cntx->bmpdrv_unload) + { + NdisSetEvent(&(pmp_wi_cntx->mp_wi_evt)); + } + +} +*/ + +static int init_mp_priv_by_os(struct mp_priv *pmp_priv) +{ + struct mp_wi_cntx *pmp_wi_cntx; + + if (pmp_priv == NULL) return _FAIL; + + pmp_priv->rx_testcnt = 0; + pmp_priv->rx_testcnt1 = 0; + pmp_priv->rx_testcnt2 = 0; + + pmp_priv->tx_testcnt = 0; + pmp_priv->tx_testcnt1 = 0; + + pmp_wi_cntx = &pmp_priv->wi_cntx + pmp_wi_cntx->bmpdrv_unload = _FALSE; + pmp_wi_cntx->bmp_wi_progress = _FALSE; + pmp_wi_cntx->curractfunc = NULL; + + return _SUCCESS; +} +#endif + +#ifdef PLATFORM_LINUX +static int init_mp_priv_by_os(struct mp_priv *pmp_priv) +{ + int i, res; + struct mp_xmit_frame *pmp_xmitframe; + + if (pmp_priv == NULL) return _FAIL; + + _rtw_init_queue(&pmp_priv->free_mp_xmitqueue); + + pmp_priv->pallocated_mp_xmitframe_buf = NULL; + pmp_priv->pallocated_mp_xmitframe_buf = rtw_zmalloc(NR_MP_XMITFRAME * sizeof(struct mp_xmit_frame) + 4); + if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) { + res = _FAIL; + goto _exit_init_mp_priv; + } + + pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + 4 - ((uint) (pmp_priv->pallocated_mp_xmitframe_buf) & 3); + + pmp_xmitframe = (struct mp_xmit_frame*)pmp_priv->pmp_xmtframe_buf; + + for (i = 0; i < NR_MP_XMITFRAME; i++) + { + _rtw_init_listhead(&pmp_xmitframe->list); + rtw_list_insert_tail(&pmp_xmitframe->list, &pmp_priv->free_mp_xmitqueue.queue); + + pmp_xmitframe->pkt = NULL; + pmp_xmitframe->frame_tag = MP_FRAMETAG; + pmp_xmitframe->padapter = pmp_priv->papdater; + + pmp_xmitframe++; + } + + pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; + + res = _SUCCESS; + +_exit_init_mp_priv: + + return res; +} +#endif + +static void mp_init_xmit_attrib(struct mp_tx *pmptx, PADAPTER padapter) +{ + struct pkt_attrib *pattrib; + struct tx_desc *desc; + + // init xmitframe attribute + pattrib = &pmptx->attrib; + _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib)); + desc = &pmptx->desc; + _rtw_memset(desc, 0, TXDESC_SIZE); + + pattrib->ether_type = 0x8712; + //_rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN); +// _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN); +// pattrib->pctrl = 0; +// pattrib->dhcp_pkt = 0; +// pattrib->pktlen = 0; + pattrib->ack_policy = 0; +// pattrib->pkt_hdrlen = ETH_HLEN; + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA; + pattrib->priority = 0; + pattrib->qsel = pattrib->priority; +// do_queue_select(padapter, pattrib); + pattrib->nr_frags = 1; + pattrib->encrypt = 0; + pattrib->bswenc = _FALSE; + pattrib->qos_en = _FALSE; +} + +s32 init_mp_priv(PADAPTER padapter) +{ + struct mp_priv *pmppriv = &padapter->mppriv; + + _init_mp_priv_(pmppriv); + pmppriv->papdater = padapter; + + pmppriv->tx.stop = 1; + mp_init_xmit_attrib(&pmppriv->tx, padapter); + + switch (padapter->registrypriv.rf_config) { + case RF_1T1R: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_A; + break; + case RF_1T2R: + default: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T2R: + case RF_2T2R_GREEN: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T4R: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_ABCD; + break; + } + + return _SUCCESS; +} + +void free_mp_priv(struct mp_priv *pmp_priv) +{ + if (pmp_priv->pallocated_mp_xmitframe_buf) { + rtw_mfree(pmp_priv->pallocated_mp_xmitframe_buf, 0); + pmp_priv->pallocated_mp_xmitframe_buf = NULL; + } + pmp_priv->pmp_xmtframe_buf = NULL; +} + +#ifdef CONFIG_RTL8192C +#define PHY_IQCalibrate(a,b) rtl8192c_PHY_IQCalibrate(a,b) +#define PHY_LCCalibrate(a) rtl8192c_PHY_LCCalibrate(a) +#define dm_CheckTXPowerTracking(a) rtl8192c_dm_CheckTXPowerTracking(a) +#define PHY_SetRFPathSwitch(a,b) rtl8192c_PHY_SetRFPathSwitch(a,b) +#endif + +#ifdef CONFIG_RTL8192D +#define PHY_IQCalibrate(a) rtl8192d_PHY_IQCalibrate(a) +#define PHY_LCCalibrate(a) rtl8192d_PHY_LCCalibrate(a) +#define dm_CheckTXPowerTracking(a) rtl8192d_dm_CheckTXPowerTracking(a) +#define PHY_SetRFPathSwitch(a,b) rtl8192d_PHY_SetRFPathSwitch(a,b) +#endif + +s32 +MPT_InitializeAdapter( + IN PADAPTER pAdapter, + IN u8 Channel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + s32 rtStatus = _SUCCESS; + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + u32 ledsetting; + + //------------------------------------------------------------------------- + // HW Initialization for 8190 MPT. + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // SW Initialization for 8190 MP. + //------------------------------------------------------------------------- + pMptCtx->bMptDrvUnload = _FALSE; + pMptCtx->bMassProdTest = _FALSE; + pMptCtx->bMptIndexEven = _TRUE; //default gain index is -6.0db + + /* Init mpt event. */ +#if 0 // for Windows + NdisInitializeEvent( &(pMptCtx->MptWorkItemEvent) ); + NdisAllocateSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); + + PlatformInitializeWorkItem( + Adapter, + &(pMptCtx->MptWorkItem), + (RT_WORKITEM_CALL_BACK)MPT_WorkItemCallback, + (PVOID)Adapter, + "MptWorkItem"); +#endif + pMptCtx->bMptWorkItemInProgress = _FALSE; + pMptCtx->CurrMptAct = NULL; + //------------------------------------------------------------------------- + +#if 1 + // Don't accept any packets + rtw_write32(pAdapter, REG_RCR, 0); +#else + // Accept CRC error and destination address + pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP); + rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); +#endif + +#if 0 + // If EEPROM or EFUSE is empty,we assign as RF 2T2R for MP. + if (pHalData->AutoloadFailFlag == TRUE) + { + pHalData->RF_Type = RF_2T2R; + } +#endif + ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); + rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS); + +#ifdef CONFIG_RTL8192C + PHY_IQCalibrate(pAdapter, _FALSE); + dm_CheckTXPowerTracking(pAdapter); //trigger thermal meter + PHY_LCCalibrate(pAdapter); +#endif + +#ifdef CONFIG_RTL8192D + PHY_IQCalibrate(pAdapter); + dm_CheckTXPowerTracking(pAdapter); //trigger thermal meter + PHY_LCCalibrate(pAdapter); +#endif + +#ifdef CONFIG_PCI_HCI + PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //Wifi default use Main +#else + +#ifdef CONFIG_RTL8192C +#if 1 + if (pHalData->BoardType == BOARD_MINICARD) + PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //default use Main +#else + if(pAdapter->HalFunc.GetInterfaceSelectionHandler(pAdapter) == INTF_SEL2_MINICARD ) + PHY_SetRFPathSwitch(Adapter, pAdapter->MgntInfo.bDefaultAntenna); //default use Main +#endif + +#endif + +#endif + + pMptCtx->backup0xc50 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); + pMptCtx->backup0xc58 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); + pMptCtx->backup0xc30 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); + + return rtStatus; +} + +/*----------------------------------------------------------------------------- + * Function: MPT_DeInitAdapter() + * + * Overview: Extra DeInitialization for Mass Production Test. + * + * Input: PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/08/2007 MHC Create Version 0. + * 05/18/2007 MHC Add normal driver MPHalt code. + * + *---------------------------------------------------------------------------*/ +VOID +MPT_DeInitAdapter( + IN PADAPTER pAdapter + ) +{ + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + + pMptCtx->bMptDrvUnload = _TRUE; +#if 0 // for Windows + PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) ); + + while(pMptCtx->bMptWorkItemInProgress) + { + if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50)) + { + break; + } + } + NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); +#endif +} + +static u8 mpt_ProStartTest(PADAPTER padapter) +{ + PMPT_CONTEXT pMptCtx = &padapter->mppriv.MptCtx; + + pMptCtx->bMassProdTest = _TRUE; + pMptCtx->bStartContTx = _FALSE; + pMptCtx->bCckContTx = _FALSE; + pMptCtx->bOfdmContTx = _FALSE; + pMptCtx->bSingleCarrier = _FALSE; + pMptCtx->bCarrierSuppression = _FALSE; + pMptCtx->bSingleTone = _FALSE; + + return _SUCCESS; +} + +/* + * General use + */ +s32 SetPowerTracking(PADAPTER padapter, u8 enable) +{ + + Hal_SetPowerTracking( padapter, enable ); + return 0; +} + +void GetPowerTracking(PADAPTER padapter, u8 *enable) +{ + Hal_GetPowerTracking( padapter, enable ); +} + +static void disable_dm(PADAPTER padapter) +{ +#ifndef CONFIG_RTL8723A + u8 v8; +#endif + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + + //3 1. disable firmware dynamic mechanism + // disable Power Training, Rate Adaptive +#ifdef CONFIG_RTL8723A + SetBcnCtrlReg(padapter, 0, EN_BCN_FUNCTION); +#else + v8 = rtw_read8(padapter, REG_BCN_CTRL); + v8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, v8); +#endif + + //3 2. disable driver dynamic mechanism + // disable Dynamic Initial Gain + // disable High Power + // disable Power Tracking + Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); + + // enable APK, LCK and IQK but disable power tracking + pdmpriv->TxPowerTrackControl = _FALSE; + Switch_DM_Func(padapter, DYNAMIC_FUNC_SS, _TRUE); +} + +//This function initializes the DUT to the MP test mode +s32 mp_start_test(PADAPTER padapter) +{ + WLAN_BSSID_EX bssid; + struct sta_info *psta; + u32 length; + u8 val8; + + _irqL irqL; + s32 res = _SUCCESS; + + struct mp_priv *pmppriv = &padapter->mppriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + + + //3 disable dynamic mechanism + disable_dm(padapter); + + //3 0. update mp_priv +#if defined (CONFIG_RTL8192C) || defined (CONFIG_RTL8192D) + if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) { +// HAL_DATA_TYPE *phal = GET_HAL_DATA(padapter); +// switch (phal->rf_type) { + switch (GET_RF_TYPE(padapter)) { + case RF_1T1R: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_A; + break; + case RF_1T2R: + default: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T2R: + case RF_2T2R_GREEN: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T4R: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_ABCD; + break; + } + } +#endif + mpt_ProStartTest(padapter); + + //3 1. initialize a new WLAN_BSSID_EX +// _rtw_memset(&bssid, 0, sizeof(WLAN_BSSID_EX)); + _rtw_memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN); + bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc"); + _rtw_memcpy(bssid.Ssid.Ssid, (u8*)"mp_pseudo_adhoc", bssid.Ssid.SsidLength); + bssid.InfrastructureMode = Ndis802_11IBSS; + bssid.NetworkTypeInUse = Ndis802_11DS; + bssid.IELength = 0; + + length = get_WLAN_BSSID_EX_sz(&bssid); + if (length % 4) + bssid.Length = ((length >> 2) + 1) << 2; //round up to multiple of 4 bytes. + else + bssid.Length = length; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + goto end_of_mp_start_test; + + //init mp_start_test status + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + rtw_disassoc_cmd(padapter, 500, _TRUE); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + } + pmppriv->prev_fw_state = get_fwstate(pmlmepriv); + pmlmepriv->fw_state = WIFI_MP_STATE; +#if 0 + if (pmppriv->mode == _LOOPBOOK_MODE_) { + set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); //append txdesc + RT_TRACE(_module_mp_, _drv_notice_, ("+start mp in Lookback mode\n")); + } else { + RT_TRACE(_module_mp_, _drv_notice_, ("+start mp in normal mode\n")); + } +#endif + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + //3 2. create a new psta for mp driver + //clear psta in the cur_network, if any + psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress); + if (psta == NULL) { + RT_TRACE(_module_mp_, _drv_err_, ("mp_start_test: Can't alloc sta_info!\n")); + pmlmepriv->fw_state = pmppriv->prev_fw_state; + res = _FAIL; + goto end_of_mp_start_test; + } + + //3 3. join psudo AdHoc + tgt_network->join_res = 1; + tgt_network->aid = psta->aid = 1; + _rtw_memcpy(&tgt_network->network, &bssid, length); + + rtw_indicate_connect(padapter); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + +end_of_mp_start_test: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + if (res == _SUCCESS) + { + // set MSR to WIFI_FW_ADHOC_STATE +#if defined (CONFIG_RTL8192C) || defined (CONFIG_RTL8192D) + val8 = rtw_read8(padapter, MSR) & 0xFC; // 0x0102 + val8 |= WIFI_FW_ADHOC_STATE; + rtw_write8(padapter, MSR, val8); // Link in ad hoc network +#endif + +#if !defined (CONFIG_RTL8192C) && !defined (CONFIG_RTL8192D) + rtw_write8(padapter, MSR, 1); // Link in ad hoc network + rtw_write8(padapter, RCR, 0); // RCR : disable all pkt, 0x10250048 + rtw_write8(padapter, RCR+2, 0x57); // RCR disable Check BSSID, 0x1025004a + + // disable RX filter map , mgt frames will put in RX FIFO 0 + rtw_write16(padapter, RXFLTMAP0, 0x0); // 0x10250116 + + val8 = rtw_read8(padapter, EE_9346CR); // 0x1025000A + if (!(val8 & _9356SEL))//boot from EFUSE + efuse_change_max_size(padapter); +#endif + } + + return res; +} +//------------------------------------------------------------------------------ +//This function change the DUT from the MP test mode into normal mode +void mp_stop_test(PADAPTER padapter) +{ + struct mp_priv *pmppriv = &padapter->mppriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + struct sta_info *psta; + + _irqL irqL; + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE) + goto end_of_mp_stop_test; + + //3 1. disconnect psudo AdHoc + rtw_indicate_disconnect(padapter); + + //3 2. clear psta used in mp test mode. +// rtw_free_assoc_resources(padapter, 1); + psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + //3 3. return to normal state (default:station mode) + pmlmepriv->fw_state = pmppriv->prev_fw_state; // WIFI_STATION_STATE; + + //flush the cur_network + _rtw_memset(tgt_network, 0, sizeof(struct wlan_network)); + + _clr_fwstate_(pmlmepriv, WIFI_MP_STATE); + +end_of_mp_stop_test: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} +/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ +#if 0 +//#ifdef CONFIG_USB_HCI +static VOID mpt_AdjustRFRegByRateByChan92CU(PADAPTER pAdapter, u8 RateIdx, u8 Channel, u8 BandWidthID) +{ + u8 eRFPath; + u32 rfReg0x26; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + + if (RateIdx < MPT_RATE_6M) { // CCK rate,for 88cu + rfReg0x26 = 0xf400; + } + else if ((RateIdx >= MPT_RATE_6M) && (RateIdx <= MPT_RATE_54M)) {// OFDM rate,for 88cu + if ((4 == Channel) || (8 == Channel) || (12 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + else if ((RateIdx >= MPT_RATE_MCS0) && (RateIdx <= MPT_RATE_MCS15)) {// MCS 20M ,for 88cu // MCS40M rate,for 88cu + + if (HT_CHANNEL_WIDTH_20 == BandWidthID) { + if ((4 == Channel) || (8 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + else{ + if ((4 == Channel) || (8 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + } + +// RT_TRACE(COMP_CMD, DBG_LOUD, ("\n mpt_AdjustRFRegByRateByChan92CU():Chan:%d Rate=%d rfReg0x26:0x%08x\n",Channel, RateIdx,rfReg0x26)); + for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { + write_rfreg(pAdapter, eRFPath, RF_SYN_G2, rfReg0x26); + } +} +#endif +/*----------------------------------------------------------------------------- + * Function: mpt_SwitchRfSetting + * + * Overview: Change RF Setting when we siwthc channel/rate/BW for MP. + * + * Input: IN PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series. + * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3. + * + *---------------------------------------------------------------------------*/ +static void mpt_SwitchRfSetting(PADAPTER pAdapter) +{ + Hal_mpt_SwitchRfSetting(pAdapter); + } + +/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ +static void MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14) +{ + Hal_MPT_CCKTxPowerAdjust(Adapter,bInCH14); +} + +static void MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven) +{ + Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter,beven); + } + +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ + +/* + * SetChannel + * Description + * Use H2C command to change channel, + * not only modify rf register, but also other setting need to be done. + */ +void SetChannel(PADAPTER pAdapter) +{ + Hal_SetChannel(pAdapter); + +} + +/* + * Notice + * Switch bandwitdth may change center frequency(channel) + */ +void SetBandwidth(PADAPTER pAdapter) +{ + Hal_SetBandwidth(pAdapter); + +} + +static void SetCCKTxPower(PADAPTER pAdapter, u8 *TxPower) +{ + Hal_SetCCKTxPower(pAdapter,TxPower); +} + +static void SetOFDMTxPower(PADAPTER pAdapter, u8 *TxPower) +{ + Hal_SetOFDMTxPower(pAdapter,TxPower); + } + + +void SetAntenna(PADAPTER pAdapter) + { + Hal_SetAntenna(pAdapter); +} + +void SetAntennaPathPower(PADAPTER pAdapter) +{ + Hal_SetAntennaPathPower(pAdapter); +} + +void SetTxPower(PADAPTER pAdapter) +{ + Hal_SetTxPower(pAdapter); + } + +void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset) +{ + u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D,tmpAGC; + + TxAGCOffset_B = (ulTxAGCOffset&0x000000ff); + TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8); + TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16); + + tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B); + write_bbreg(pAdapter, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC); +} + +void SetDataRate(PADAPTER pAdapter) +{ + Hal_SetDataRate(pAdapter); +} + +#if !defined (CONFIG_RTL8192C) && !defined (CONFIG_RTL8192D) +/*------------------------------Define structure----------------------------*/ +typedef struct _R_ANTENNA_SELECT_OFDM { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; +#endif + +s32 SetThermalMeter(PADAPTER pAdapter, u8 target_ther) +{ + return Hal_SetThermalMeter( pAdapter, target_ther); +} + +static void TriggerRFThermalMeter(PADAPTER pAdapter) +{ + Hal_TriggerRFThermalMeter(pAdapter); +} + +static u8 ReadRFThermalMeter(PADAPTER pAdapter) +{ + return Hal_ReadRFThermalMeter(pAdapter); +} + +void GetThermalMeter(PADAPTER pAdapter, u8 *value) +{ + Hal_GetThermalMeter(pAdapter,value); +} + +void SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) +{ + Hal_SetSingleCarrierTx(pAdapter,bStart); +} + +void SetSingleToneTx(PADAPTER pAdapter, u8 bStart) +{ + Hal_SetSingleToneTx(pAdapter,bStart); +} + +void SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) +{ + Hal_SetCarrierSuppressionTx(pAdapter, bStart); +} + +void SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart) + { + Hal_SetCCKContinuousTx(pAdapter,bStart); + } + +void SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart) + { + Hal_SetOFDMContinuousTx( pAdapter, bStart); +}/* mpt_StartOfdmContTx */ + +void SetContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + Hal_SetContinuousTx(pAdapter,bStart); +} + +//------------------------------------------------------------------------------ +static void dump_mpframe(PADAPTER padapter, struct xmit_frame *pmpframe) +{ + rtw_hal_mgnt_xmit(padapter, pmpframe); +} + +static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) +{ + struct xmit_frame *pmpframe; + struct xmit_buf *pxmitbuf; + + if ((pmpframe = rtw_alloc_xmitframe(pxmitpriv)) == NULL) + { + return NULL; + } + + if ((pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL) + { + rtw_free_xmitframe(pxmitpriv, pmpframe); + return NULL; + } + + pmpframe->frame_tag = MP_FRAMETAG; + + pmpframe->pxmitbuf = pxmitbuf; + + pmpframe->buf_addr = pxmitbuf->pbuf; + + pxmitbuf->priv_data = pmpframe; + + return pmpframe; + +} + +static thread_return mp_xmit_packet_thread(thread_context context) +{ + struct xmit_frame *pxmitframe; + struct mp_tx *pmptx; + struct mp_priv *pmp_priv; + struct xmit_priv *pxmitpriv; + PADAPTER padapter; + + pmp_priv = (struct mp_priv *)context; + pmptx = &pmp_priv->tx; + padapter = pmp_priv->papdater; + pxmitpriv = &(padapter->xmitpriv); + + thread_enter("RTW_MP_THREAD"); + + DBG_871X("%s:pkTx Start\n", __func__); + while (1) { + pxmitframe = alloc_mp_xmitframe(pxmitpriv); + if (pxmitframe == NULL) { + if (pmptx->stop || + padapter->bSurpriseRemoved || + padapter->bDriverStopped) { + goto exit; + } + else { + rtw_msleep_os(1); + continue; + } + } + + _rtw_memcpy((u8 *)(pxmitframe->buf_addr+TXDESC_OFFSET), pmptx->buf, pmptx->write_size); + _rtw_memcpy(&(pxmitframe->attrib), &(pmptx->attrib), sizeof(struct pkt_attrib)); + + dump_mpframe(padapter, pxmitframe); + + pmptx->sended++; + pmp_priv->tx_pktcount++; + + if (pmptx->stop || + padapter->bSurpriseRemoved || + padapter->bDriverStopped) + goto exit; + if ((pmptx->count != 0) && + (pmptx->count == pmptx->sended)) + goto exit; + + flush_signals_thread(); + } + +exit: + //DBG_871X("%s:pkTx Exit\n", __func__); + rtw_mfree(pmptx->pallocated_buf, pmptx->buf_size); + pmptx->pallocated_buf = NULL; + pmptx->stop = 1; + + thread_exit(); +} + +void fill_txdesc_for_mp(PADAPTER padapter, struct tx_desc *ptxdesc) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + _rtw_memcpy(ptxdesc, &(pmp_priv->tx.desc), TXDESC_SIZE); +} + +void SetPacketTx(PADAPTER padapter) +{ + u8 *ptr, *pkt_start, *pkt_end; + u32 pkt_size; + struct tx_desc *desc; + struct rtw_ieee80211_hdr *hdr; + u8 payload; + s32 bmcast; + struct pkt_attrib *pattrib; + struct mp_priv *pmp_priv; + + + pmp_priv = &padapter->mppriv; + if (pmp_priv->tx.stop) return; + pmp_priv->tx.sended = 0; + pmp_priv->tx.stop = 0; + pmp_priv->tx_pktcount = 0; + + //3 1. update_attrib() + pattrib = &pmp_priv->tx.attrib; + _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + bmcast = IS_MCAST(pattrib->ra); + if (bmcast) { + pattrib->mac_id = 1; + pattrib->psta = rtw_get_bcmc_stainfo(padapter); + } else { + pattrib->mac_id = 0; + pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + } + + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; + + //3 2. allocate xmit buffer + pkt_size = pattrib->last_txcmdsz; + + if (pmp_priv->tx.pallocated_buf) + rtw_mfree(pmp_priv->tx.pallocated_buf, pmp_priv->tx.buf_size); + pmp_priv->tx.write_size = pkt_size; + pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ; + pmp_priv->tx.pallocated_buf = rtw_zmalloc(pmp_priv->tx.buf_size); + if (pmp_priv->tx.pallocated_buf == NULL) { + DBG_871X("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size); + return; + } + pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ); + ptr = pmp_priv->tx.buf; + + desc = &(pmp_priv->tx.desc); + _rtw_memset(desc, 0, TXDESC_SIZE); + pkt_start = ptr; + pkt_end = pkt_start + pkt_size; + + //3 3. init TX descriptor + // offset 0 + //desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); // packet size + //desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); + //desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); //32 bytes for TX Desc + //if (bmcast) desc->txdw0 |= cpu_to_le32(BMC); // broadcast packet + + // offset 4 + desc->txdw1 |= cpu_to_le32(BK); // don't aggregate(AMPDU) + desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x1F); //CAM_ID(MAC_ID) + desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); // Queue Select, TID + desc->txdw1 |= cpu_to_le32((pattrib->raid << Rate_ID_SHT) & 0x000F0000); // Rate Adaptive ID + + // offset 8 + // offset 12 + //desc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0xffff0000); + + // offset 16 + //desc->txdw4 |= cpu_to_le32(QoS); + desc->txdw4 |= cpu_to_le32(HW_SEQ_EN); + desc->txdw4 |= cpu_to_le32(USERATE); + desc->txdw4 |= cpu_to_le32(DISDATAFB); + + if( pmp_priv->preamble ){ + if (pmp_priv->rateidx <= MPT_RATE_54M) + desc->txdw4 |= cpu_to_le32(DATA_SHORT); // CCK Short Preamble + } + if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40) + desc->txdw4 |= cpu_to_le32(DATA_BW); + + // offset 20 + desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F); + + if( pmp_priv->preamble ){ + if (pmp_priv->rateidx > MPT_RATE_54M) + desc->txdw5 |= cpu_to_le32(SGI); // MCS Short Guard Interval + } + desc->txdw5 |= cpu_to_le32(0x0001FF00); // DATA/RTS Rate Fallback Limit + + //3 4. make wlan header, make_wlanhdr() + hdr = (struct rtw_ieee80211_hdr *)pkt_start; + SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); + _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA + _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA + _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID + + //3 5. make payload + ptr = pkt_start + pattrib->hdrlen; + + switch (pmp_priv->tx.payload) { + case 0: + payload = 0x00; + break; + case 1: + payload = 0x5a; + break; + case 2: + payload = 0xa5; + break; + case 3: + payload = 0xff; + break; + default: + payload = 0x00; + break; + } + + _rtw_memset(ptr, payload, pkt_end - ptr); + + //3 6. start thread +#ifdef PLATFORM_LINUX + pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD"); + if (IS_ERR(pmp_priv->tx.PktTxThread)) + DBG_871X("Create PktTx Thread Fail !!!!!\n"); +#endif +#ifdef PLATFORM_FREEBSD +{ + struct proc *p; + struct thread *td; + pmp_priv->tx.PktTxThread = kproc_kthread_add(mp_xmit_packet_thread, pmp_priv, + &p, &td, RFHIGHPID, 0, "MPXmitThread", "MPXmitThread"); + + if (pmp_priv->tx.PktTxThread < 0) + DBG_871X("Create PktTx Thread Fail !!!!!\n"); +} +#endif +} + +void SetPacketRx(PADAPTER pAdapter, u8 bStartRx) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + if(bStartRx) + { + pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS; + + pHalData->ReceiveConfig |= ACRC32; + + rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); + + // Accept all data frames + rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF); + } + else + { + rtw_write32(pAdapter, REG_RCR, 0); + } +} + +void ResetPhyRxPktCount(PADAPTER pAdapter) +{ + u32 i, phyrx_set = 0; + + for (i = 0; i <= 0xF; i++) { + phyrx_set = 0; + phyrx_set |= _RXERR_RPT_SEL(i); //select + phyrx_set |= RXERR_RPT_RST; // set counter to zero + rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); + } +} + +static u32 GetPhyRxPktCounts(PADAPTER pAdapter, u32 selbit) +{ + //selection + u32 phyrx_set = 0, count = 0; + + phyrx_set = _RXERR_RPT_SEL(selbit & 0xF); + rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); + + //Read packet count + count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK; + + return count; +} + +u32 GetPhyRxPktReceived(PADAPTER pAdapter) +{ + u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; + + OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK); + CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK); + HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK); + + return OFDM_cnt + CCK_cnt + HT_cnt; +} + +u32 GetPhyRxPktCRC32Error(PADAPTER pAdapter) +{ + u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; + + OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL); + CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL); + HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL); + + return OFDM_cnt + CCK_cnt + HT_cnt; +} + +//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 +static u32 GetPSDData(PADAPTER pAdapter, u32 point) +{ + int psd_val; + + + psd_val = rtw_read32(pAdapter, 0x808); + psd_val &= 0xFFBFFC00; + psd_val |= point; + + rtw_write32(pAdapter, 0x808, psd_val); + rtw_mdelay_os(1); + psd_val |= 0x00400000; + + rtw_write32(pAdapter, 0x808, psd_val); + rtw_mdelay_os(1); + psd_val = rtw_read32(pAdapter, 0x8B4); + + psd_val &= 0x0000FFFF; + + return psd_val; +} + +/* + * pts start_point_min stop_point_max + * 128 64 64 + 128 = 192 + * 256 128 128 + 256 = 384 + * 512 256 256 + 512 = 768 + * 1024 512 512 + 1024 = 1536 + * + */ +u32 mp_query_psd(PADAPTER pAdapter, u8 *data) +{ + u32 i, psd_pts=0, psd_start=0, psd_stop=0; + u32 psd_data=0; + +#ifdef PLATFORM_LINUX + if (!netif_running(pAdapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! interface not opened!\n")); + return 0; + } +#endif + + if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! not in MP mode!\n")); + return 0; + } + + if (strlen(data) == 0) { //default value + psd_pts = 128; + psd_start = 64; + psd_stop = 128; + } else { + sscanf(data, "pts=%d,start=%d,stop=%d", &psd_pts, &psd_start, &psd_stop); + } + + _rtw_memset(data, '\0', sizeof(data)); + + i = psd_start; + while (i < psd_stop) + { + if (i >= psd_pts) { + psd_data = GetPSDData(pAdapter, i-psd_pts); + } else { + psd_data = GetPSDData(pAdapter, i); + } + sprintf(data, "%s%x ", data, psd_data); + i++; + } + + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(100); + #else + rtw_mdelay_os(100); + #endif + + return strlen(data)+1; +} + +#endif + diff --git a/rtl8192cu-fixes/core/rtw_mp_ioctl.c b/rtl8192cu-fixes/core/rtw_mp_ioctl.c new file mode 100755 index 00000000..b941e2ce --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_mp_ioctl.c @@ -0,0 +1,2954 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MP_IOCTL_C_ + +#include +#include +#include +#include + +//#include +#include + + +//**************** oid_rtl_seg_81_85 section start **************** +NDIS_STATUS oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) { + Adapter->registrypriv.wireless_mode = *(u8*)poid_par_priv->information_buf; + } else if (poid_par_priv->type_of_oid == QUERY_OID) { + *(u8*)poid_par_priv->information_buf = Adapter->registrypriv.wireless_mode; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_info_, ("-query Wireless Mode=%d\n", Adapter->registrypriv.wireless_mode)); + } else { + status = NDIS_STATUS_NOT_ACCEPTED; + } + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_87_80 section start **************** +NDIS_STATUS oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct bb_reg_param *pbbreg; + u16 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_write_bb_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); + + offset = (u16)(pbbreg->offset) & 0xFFF; //0ffset :0x800~0xfff + if (offset < BB_REG_BASE_ADDR) offset |= BB_REG_BASE_ADDR; + + value = pbbreg->value; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_write_bb_reg_hdl: offset=0x%03X value=0x%08X\n", + offset, value)); + + _irqlevel_changed_(&oldirql, LOWER); + write_bbreg(Adapter, offset, 0xFFFFFFFF, value); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct bb_reg_param *pbbreg; + u16 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_bb_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); + + offset = (u16)(pbbreg->offset) & 0xFFF; //0ffset :0x800~0xfff + if (offset < BB_REG_BASE_ADDR) offset |= BB_REG_BASE_ADDR; + + _irqlevel_changed_(&oldirql, LOWER); + value = read_bbreg(Adapter, offset, 0xFFFFFFFF); + _irqlevel_changed_(&oldirql, RAISE); + + pbbreg->value = value; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_read_bb_reg_hdl: offset=0x%03X value:0x%08X\n", + offset, value)); +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct rf_reg_param *pbbreg; + u8 path; + u8 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_write_rf_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); + + if (pbbreg->path >= MAX_RF_PATH_NUMS) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->offset > 0xFF) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->value > 0xFFFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + path = (u8)pbbreg->path; + offset = (u8)pbbreg->offset; + value = pbbreg->value; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_write_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n", + path, offset, value)); + + _irqlevel_changed_(&oldirql, LOWER); + write_rfreg(Adapter, path, offset, value); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct rf_reg_param *pbbreg; + u8 path; + u8 offset; + u32 value; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_rf_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); + + if (pbbreg->path >= MAX_RF_PATH_NUMS) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->offset > 0xFF) + return NDIS_STATUS_NOT_ACCEPTED; + + path = (u8)pbbreg->path; + offset = (u8)pbbreg->offset; + + _irqlevel_changed_(&oldirql, LOWER); + value = read_rfreg(Adapter, path, offset); + _irqlevel_changed_(&oldirql, RAISE); + + pbbreg->value = value; + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_read_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n", + path, offset, value)); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_87_00 section end**************** +//------------------------------------------------------------------------------ + +//**************** oid_rtl_seg_81_80_00 section start **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 ratevalue;//4 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_set_data_rate_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + ratevalue = *((u32*)poid_par_priv->information_buf);//4 + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_data_rate_hdl: data rate idx=%d\n", ratevalue)); + if (ratevalue >= MPT_RATE_LAST) + return NDIS_STATUS_INVALID_DATA; + + Adapter->mppriv.rateidx = ratevalue; + + _irqlevel_changed_(&oldirql, LOWER); + SetDataRate(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 mode; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_start_test_hdl\n")); + + if (Adapter->registrypriv.mp_mode == 0) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + //IQCalibrateBcut(Adapter); + + mode = *((u32*)poid_par_priv->information_buf); + Adapter->mppriv.mode = mode;// 1 for loopback + + if (mp_start_test(Adapter) == _FAIL) { + status = NDIS_STATUS_NOT_ACCEPTED; + goto exit; + } + +exit: + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, ("-oid_rt_pro_start_test_hdl: mp_mode=%d\n", Adapter->mppriv.mode)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_STOP_TEST\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + mp_stop_test(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, ("-Set OID_RT_PRO_STOP_TEST\n")); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 Channel; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_channel_direct_call_hdl\n")); + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == QUERY_OID) { + *((u32*)poid_par_priv->information_buf) = Adapter->mppriv.channel; + return NDIS_STATUS_SUCCESS; + } + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + Channel = *((u32*)poid_par_priv->information_buf); + RT_TRACE(_module_mp_, _drv_notice_, ("oid_rt_pro_set_channel_direct_call_hdl: Channel=%d\n", Channel)); + if (Channel > 14) + return NDIS_STATUS_NOT_ACCEPTED; + Adapter->mppriv.channel = Channel; + + _irqlevel_changed_(&oldirql, LOWER); + SetChannel(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u16 bandwidth; + u16 channel_offset; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_set_bandwidth_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + bandwidth = *((u32*)poid_par_priv->information_buf);//4 + channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (bandwidth != HT_CHANNEL_WIDTH_40) + bandwidth = HT_CHANNEL_WIDTH_20; + padapter->mppriv.bandwidth = (u8)bandwidth; + padapter->mppriv.prime_channel_offset = (u8)channel_offset; + + _irqlevel_changed_(&oldirql, LOWER); + SetBandwidth(padapter); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_set_bandwidth_hdl: bandwidth=%d channel_offset=%d\n", + bandwidth, channel_offset)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 antenna; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_antenna_bb_hdl\n")); + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) + { + antenna = *(u32*)poid_par_priv->information_buf; + + Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); + Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_antenna_bb_hdl: tx_ant=0x%04x rx_ant=0x%04x\n", + Adapter->mppriv.antenna_tx, Adapter->mppriv.antenna_rx)); + + _irqlevel_changed_(&oldirql, LOWER); + SetAntenna(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + } else { + antenna = (Adapter->mppriv.antenna_tx << 16)|Adapter->mppriv.antenna_rx; + *(u32*)poid_par_priv->information_buf = antenna; + } + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 tx_pwr_idx; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_set_tx_power_control_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + tx_pwr_idx = *((u32*)poid_par_priv->information_buf); + if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) + return NDIS_STATUS_NOT_ACCEPTED; + + Adapter->mppriv.txpoweridx = (u8)tx_pwr_idx; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_tx_power_control_hdl: idx=0x%2x\n", + Adapter->mppriv.txpoweridx)); + + _irqlevel_changed_(&oldirql, LOWER); + SetTxPower(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +//------------------------------------------------------------------------------ +//**************** oid_rtl_seg_81_80_20 section start **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid !=QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.tx_pktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_query_rx_packet_received_hdl.\n")); + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.rx_pktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_alert_, ("recv_ok:%d \n",Adapter->mppriv.rx_pktcount)); + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_query_rx_packet_crc32_error_hdl.\n")); + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.rx_crcerrpktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_alert_, ("recv_err:%d \n",Adapter->mppriv.rx_crcerrpktcount)); + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ + +NDIS_STATUS oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_reset_tx_packet_sent_hdl.\n")); + Adapter->mppriv.tx_pktcount = 0; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + Adapter->mppriv.rx_pktcount = 0; + Adapter->mppriv.rx_crcerrpktcount = 0; + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql, LOWER); + ResetPhyRxPktCount(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_get_phy_rx_packet_received_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(ULONG)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + *(ULONG*)poid_par_priv->information_buf = GetPhyRxPktReceived(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, ("-oid_rt_get_phy_rx_packet_received_hdl: recv_ok=%d\n", *(ULONG*)poid_par_priv->information_buf)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_get_phy_rx_packet_crc32_error_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + + if (poid_par_priv->information_buf_len != sizeof(ULONG)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + *(ULONG*)poid_par_priv->information_buf = GetPhyRxPktCRC32Error(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_get_phy_rx_packet_crc32_error_hdl: recv_err=%d\n", *(ULONG*)poid_par_priv->information_buf)); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_80_20 section end **************** +NDIS_STATUS oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_continuous_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetContinuousTx(Adapter,(u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_alert_, ("+oid_rt_pro_set_single_carrier_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetSingleCarrierTx(Adapter, (u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_carrier_suppression_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetCarrierSuppressionTx(Adapter, (u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_alert_, ("+oid_rt_pro_set_single_tone_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetSingleToneTx(Adapter,(u8)bStartTest); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_modulation_hdl(struct oid_par_priv* poid_par_priv) +{ + return 0; +} + +NDIS_STATUS oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv) +{ + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_hal_set_hwreg(Adapter, HW_VAR_TRIGGER_GPIO_0, 0); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_80_00 section end **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PNDIS_802_11_SSID pssid; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = (u32)sizeof(NDIS_802_11_SSID); + *poid_par_priv->bytes_rw = 0; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + pssid = (PNDIS_802_11_SSID)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (mp_start_joinbss(Adapter, pssid) == _FAIL) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = sizeof(NDIS_802_11_SSID); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pRW_Reg RegRWStruct; + u32 offset, width; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_pro_read_register_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RegRWStruct = (pRW_Reg)poid_par_priv->information_buf; + offset = RegRWStruct->offset; + width = RegRWStruct->width; + + if (offset > 0xFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + switch (width) { + case 1: + RegRWStruct->value = rtw_read8(Adapter, offset); + break; + case 2: + RegRWStruct->value = rtw_read16(Adapter, offset); + break; + default: + width = 4; + RegRWStruct->value = rtw_read32(Adapter, offset); + break; + } + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_read_register_hdl: offset:0x%04X value:0x%X\n", + offset, RegRWStruct->value)); + + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = width; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pRW_Reg RegRWStruct; + u32 offset, width, value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_pro_write_register_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RegRWStruct = (pRW_Reg)poid_par_priv->information_buf; + offset = RegRWStruct->offset; + width = RegRWStruct->width; + value = RegRWStruct->value; + + if (offset > 0xFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + switch (RegRWStruct->width) + { + case 1: + if (value > 0xFF) { + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + rtw_write8(padapter, offset, (u8)value); + break; + case 2: + if (value > 0xFFFF) { + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + rtw_write16(padapter, offset, (u16)value); + break; + case 4: + rtw_write32(padapter, offset, value); + break; + default: + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_write_register_hdl: offset=0x%08X width=%d value=0x%X\n", + offset, width, value)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pBurst_RW_Reg pBstRwReg; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_burst_read_register_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pBstRwReg = (pBurst_RW_Reg)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_read_mem(padapter, pBstRwReg->offset, (u32)pBstRwReg->len, pBstRwReg->Data); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_burst_read_register_hdl\n")); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pBurst_RW_Reg pBstRwReg; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_burst_write_register_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pBstRwReg = (pBurst_RW_Reg)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_write_mem(padapter, pBstRwReg->offset, (u32)pBstRwReg->len, pBstRwReg->Data); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_burst_write_register_hdl\n")); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + + TX_CMD_Desc *TxCmd_Info; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RT_TRACE(_module_mp_, _drv_info_, ("+Set OID_RT_PRO_WRITE_TXCMD\n")); + + TxCmd_Info=(TX_CMD_Desc*)poid_par_priv->information_buf; + + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:Addr=%.8X\n", TxCmd_Info->offset)); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:1.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[0])); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:2.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[1])); + RT_TRACE(_module_mp_, _drv_info_, (("WRITE_TXCMD:3.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[2])); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:4.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[3])); + + _irqlevel_changed_(&oldirql, LOWER); + + rtw_write32(Adapter, TxCmd_Info->offset + 0, (unsigned int)TxCmd_Info->TxCMD.value[0]); + rtw_write32(Adapter, TxCmd_Info->offset + 4, (unsigned int)TxCmd_Info->TxCMD.value[1]); + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-Set OID_RT_PRO_WRITE_TXCMD: status=0x%08X\n", status)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pEEPROM_RWParam pEEPROM; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+Query OID_RT_PRO_READ16_EEPROM\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pEEPROM = (pEEPROM_RWParam)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + pEEPROM->value = eeprom_read16(padapter, (u16)(pEEPROM->offset >> 1)); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-Query OID_RT_PRO_READ16_EEPROM: offset=0x%x value=0x%x\n", + pEEPROM->offset, pEEPROM->value)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write16_eeprom_hdl (struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pEEPROM_RWParam pEEPROM; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_WRITE16_EEPROM\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pEEPROM = (pEEPROM_RWParam)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + eeprom_write16(padapter, (u16)(pEEPROM->offset >> 1), pEEPROM->value); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct mp_wiparam *pwi_param; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam)) + return NDIS_STATUS_INVALID_LENGTH; + + if (Adapter->mppriv.workparam.bcompleted == _FALSE) + return NDIS_STATUS_NOT_ACCEPTED; + + pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf; + + _rtw_memcpy(pwi_param, &Adapter->mppriv.workparam, sizeof(struct mp_wiparam)); + Adapter->mppriv.act_in_progress = _FALSE; +// RT_TRACE(_module_mp_, _drv_info_, ("rf:%x\n", pwiparam->IoValue)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro8711_pkt_loss_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(uint)*2) { + RT_TRACE(_module_mp_, _drv_err_, ("-oid_rt_pro8711_pkt_loss_hdl: buf_len=%d\n", (int)poid_par_priv->information_buf_len)); + return NDIS_STATUS_INVALID_LENGTH; + } + + if (*(uint*)poid_par_priv->information_buf == 1)//init==1 + Adapter->mppriv.rx_pktloss = 0; + + *((uint*)poid_par_priv->information_buf+1) = Adapter->mppriv.rx_pktloss; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + struct io_queue *pio_queue = (struct io_queue *)Adapter->pio_queue; + struct intf_hdl *pintfhdl = &pio_queue->intf; + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +#ifdef CONFIG_SDIO_HCI + void (*_attrib_read)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); +#endif + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Query OID_RT_RD_ATTRIB_MEM\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + +#ifdef CONFIG_SDIO_HCI + _irqlevel_changed_(&oldirql, LOWER); +{ + u32 *plmem = (u32*)poid_par_priv->information_buf+2; + _attrib_read = pintfhdl->io_ops._attrib_read; + _attrib_read(pintfhdl, *((u32*)poid_par_priv->information_buf), + *((u32*)poid_par_priv->information_buf+1), (u8*)plmem); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; +} + _irqlevel_changed_(&oldirql, RAISE); +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + struct io_queue *pio_queue = (struct io_queue *)Adapter->pio_queue; + struct intf_hdl *pintfhdl = &pio_queue->intf; + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +#ifdef CONFIG_SDIO_HCI + void (*_attrib_write)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); +#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + +#ifdef CONFIG_SDIO_HCI + _irqlevel_changed_(&oldirql, LOWER); +{ + u32 *plmem = (u32*)poid_par_priv->information_buf + 2; + _attrib_write = pintfhdl->io_ops._attrib_write; + _attrib_write(pintfhdl, *(u32*)poid_par_priv->information_buf, + *((u32*)poid_par_priv->information_buf+1), (u8*)plmem); +} + _irqlevel_changed_(&oldirql, RAISE); +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+OID_RT_PRO_SET_RF_INTFS\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setrfintfs_cmd(Adapter, *(unsigned char*)poid_par_priv->information_buf) == _FAIL) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _rtw_memcpy(poid_par_priv->information_buf, (unsigned char*)&Adapter->mppriv.rxstat, sizeof(struct recv_stat)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PCFG_DBG_MSG_STRUCT pdbg_msg; + +_func_enter_; + +// RT_TRACE(0xffffffffff,_drv_alert_,("===> oid_rt_pro_cfg_debug_message_hdl.\n")); + +#if 0//#ifdef CONFIG_DEBUG_RTL871X + + pdbg_msg = (PCFG_DBG_MSG_STRUCT)(poid_par_priv->information_buf); + + if (poid_par_priv->type_of_oid == SET_OID) { + RT_TRACE(0xffffffffff, _drv_alert_, + ("===>Set level :0x%08x, H32:0x%08x L32:0x%08x\n", + pdbg_msg->DebugLevel, pdbg_msg->DebugComponent_H32, pdbg_msg->DebugComponent_L32)); + + GlobalDebugLevel = pdbg_msg->DebugLevel; + GlobalDebugComponents = (pdbg_msg->DebugComponent_H32 << 32) | pdbg_msg->DebugComponent_L32; + RT_TRACE(0xffffffffff, _drv_alert_, + ("===> Set level :0x%08x, component:0x%016x\n", + GlobalDebugLevel, (u32)GlobalDebugComponents)); + } else { + pdbg_msg->DebugLevel = GlobalDebugLevel; + pdbg_msg->DebugComponent_H32 = (u32)(GlobalDebugComponents >> 32); + pdbg_msg->DebugComponent_L32 = (u32)GlobalDebugComponents; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(0xffffffffff, _drv_alert_, + ("===>Query level:0x%08x H32:0x%08x L32:0x%08x\n", + (u32)pdbg_msg->DebugLevel, (u32)pdbg_msg->DebugComponent_H32, (u32)pdbg_msg->DebugComponent_L32)); + } + +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv) +{ + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+OID_RT_PRO_SET_DATA_RATE_EX\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setdatarate_cmd(Adapter, poid_par_priv->information_buf) !=_SUCCESS) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + u8 thermal = 0; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_get_thermal_meter_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + GetThermalMeter(Adapter, &thermal); + _irqlevel_changed_(&oldirql, RAISE); + + *(u32*)poid_par_priv->information_buf = (u32)thermal; + *poid_par_priv->bytes_rw = sizeof(u32); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_tssi_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (Adapter->mppriv.act_in_progress == _TRUE) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + //init workparam + Adapter->mppriv.act_in_progress = _TRUE; + Adapter->mppriv.workparam.bcompleted = _FALSE; + Adapter->mppriv.workparam.act_type = MPT_READ_TSSI; + Adapter->mppriv.workparam.io_offset = 0; + Adapter->mppriv.workparam.io_value = 0xFFFFFFFF; + + _irqlevel_changed_(&oldirql, LOWER); + + if (!rtw_gettssi_cmd(Adapter,0, (u8*)&Adapter->mppriv.workparam.io_value)) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + +_func_enter_; + +// if (poid_par_priv->type_of_oid != SET_OID) +// return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + if (poid_par_priv->type_of_oid == SET_OID) { + u8 enable; + + enable = *(u8*)poid_par_priv->information_buf; + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_set_power_tracking_hdl: enable=%d\n", enable)); + + SetPowerTracking(Adapter, enable); + } else { + GetPowerTracking(Adapter, (u8*)poid_par_priv->information_buf); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 ratevalue; + u8 datarates[NumRates]; + int i; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+OID_RT_PRO_SET_BASIC_RATE\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; +#if 0 + ratevalue = *((u32*)poid_par_priv->information_buf); + + for (i = 0; i < NumRates; i++) { + if (ratevalue == mpdatarate[i]) + datarates[i] = mpdatarate[i]; + else + datarates[i] = 0xff; + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_info_, ("basicrate_inx=%d\n", datarates[i])); + } + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setbasicrate_cmd(padapter, datarates) != _SUCCESS) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); +#endif + RT_TRACE(_module_mp_, _drv_notice_, + ("-OID_RT_PRO_SET_BASIC_RATE: status=0x%08X\n", status)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < 8) + return NDIS_STATUS_INVALID_LENGTH; + + *poid_par_priv->bytes_rw = 8; + _rtw_memcpy(poid_par_priv->information_buf, &(Adapter->pwrctrlpriv.pwr_mode), 8); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_qry_pwrstate_hdl: pwr_mode=%d smart_ps=%d\n", + Adapter->pwrctrlpriv.pwr_mode, Adapter->pwrctrlpriv.smart_ps)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + uint pwr_mode, smart_ps; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_SET_PWRSTATE\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_rw = 0; + *poid_par_priv->bytes_needed = 8; + + if (poid_par_priv->information_buf_len < 8) + return NDIS_STATUS_INVALID_LENGTH; + + pwr_mode = *(uint *)(poid_par_priv->information_buf); + smart_ps = *(uint *)((int)poid_par_priv->information_buf + 4); + + *poid_par_priv->bytes_rw = 8; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct setratable_parm *prate_table; + u8 res; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = sizeof(struct setratable_parm); + if (poid_par_priv->information_buf_len < sizeof(struct setratable_parm)) + return NDIS_STATUS_INVALID_LENGTH; + + prate_table = (struct setratable_parm*)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + res = rtw_setrttbl_cmd(Adapter, prate_table); + _irqlevel_changed_(&oldirql, RAISE); + + if (res == _FAIL) + status = NDIS_STATUS_FAILURE; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + #if 0 + struct mp_wi_cntx *pmp_wi_cntx=&(Adapter->mppriv.wi_cntx); + u8 res=_SUCCESS; + DEBUG_INFO(("===> Set OID_RT_PRO_H2C_GET_RATE_TABLE.\n")); + + if(pmp_wi_cntx->bmp_wi_progress ==_TRUE){ + DEBUG_ERR(("\n mp workitem is progressing, not allow to set another workitem right now!!!\n")); + Status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + else{ + pmp_wi_cntx->bmp_wi_progress=_TRUE; + pmp_wi_cntx->param.bcompleted=_FALSE; + pmp_wi_cntx->param.act_type=MPT_GET_RATE_TABLE; + pmp_wi_cntx->param.io_offset=0x0; + pmp_wi_cntx->param.bytes_cnt=sizeof(struct getratable_rsp); + pmp_wi_cntx->param.io_value=0xffffffff; + + res=rtw_getrttbl_cmd(Adapter,(struct getratable_rsp *)pmp_wi_cntx->param.data); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + if(res != _SUCCESS) + { + Status = NDIS_STATUS_NOT_ACCEPTED; + } + } + DEBUG_INFO(("\n <=== Set OID_RT_PRO_H2C_GET_RATE_TABLE.\n")); + #endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//**************** oid_rtl_seg_87_12_00 section start **************** +NDIS_STATUS oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + struct security_priv *psecuritypriv = &Adapter->securitypriv; + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + ENCRY_CTRL_STATE encry_mode; + + + *poid_par_priv->bytes_needed = sizeof(u8); + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) + { + encry_mode = *((u8*)poid_par_priv->information_buf); + switch (encry_mode) + { + case HW_CONTROL: + #if 0 + Adapter->registrypriv.software_decrypt=_FALSE; + Adapter->registrypriv.software_encrypt=_FALSE; + #else + psecuritypriv->sw_decrypt = _FALSE; + psecuritypriv->sw_encrypt = _FALSE; + #endif + break; + case SW_CONTROL: + #if 0 + Adapter->registrypriv.software_decrypt=_TRUE; + Adapter->registrypriv.software_encrypt=_TRUE; + #else + psecuritypriv->sw_decrypt = _TRUE; + psecuritypriv->sw_encrypt = _TRUE; + #endif + break; + case HW_ENCRY_SW_DECRY: + #if 0 + Adapter->registrypriv.software_decrypt=_TRUE; + Adapter->registrypriv.software_encrypt=_FALSE; + #else + psecuritypriv->sw_decrypt = _TRUE; + psecuritypriv->sw_encrypt = _FALSE; + #endif + break; + case SW_ENCRY_HW_DECRY: + #if 0 + Adapter->registrypriv.software_decrypt=_FALSE; + Adapter->registrypriv.software_encrypt=_TRUE; + #else + psecuritypriv->sw_decrypt = _FALSE; + psecuritypriv->sw_encrypt = _TRUE; + #endif + break; + } + + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_notice_, + ("-oid_rt_pro_encryption_ctrl_hdl: SET encry_mode=0x%x sw_encrypt=0x%x sw_decrypt=0x%x\n", + encry_mode, psecuritypriv->sw_encrypt, psecuritypriv->sw_decrypt)); + } + else { + #if 0 + if (Adapter->registrypriv.software_encrypt == _FALSE) { + if (Adapter->registrypriv.software_decrypt == _FALSE) + encry_mode = HW_CONTROL; + else + encry_mode = HW_ENCRY_SW_DECRY; + } + else { + if (Adapter->registrypriv.software_decrypt == _FALSE) + encry_mode = SW_ENCRY_HW_DECRY; + else + encry_mode = SW_CONTROL; + } + #else + + if ((psecuritypriv->sw_encrypt == _FALSE) && (psecuritypriv->sw_decrypt == _FALSE)) + encry_mode = HW_CONTROL; + else if ((psecuritypriv->sw_encrypt == _FALSE) && (psecuritypriv->sw_decrypt == _TRUE)) + encry_mode = HW_ENCRY_SW_DECRY; + else if ((psecuritypriv->sw_encrypt == _TRUE) && (psecuritypriv->sw_decrypt == _FALSE)) + encry_mode = SW_ENCRY_HW_DECRY; + else if ((psecuritypriv->sw_encrypt == _TRUE) && (psecuritypriv->sw_decrypt == _TRUE)) + encry_mode = SW_CONTROL; + + #endif + + *(u8*)poid_par_priv->information_buf = encry_mode; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_encryption_ctrl_hdl: QUERY encry_mode=0x%x\n", + encry_mode)); + } + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct sta_info *psta = NULL; + UCHAR *macaddr; + + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = ETH_ALEN; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + macaddr = (UCHAR *) poid_par_priv->information_buf ; + + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_notice_, + ("OID_RT_PRO_ADD_STA_INFO: addr="MAC_FMT"\n", MAC_ARG(macaddr) )); + + _irqlevel_changed_(&oldirql, LOWER); + + psta = rtw_get_stainfo(&Adapter->stapriv, macaddr); + + if (psta == NULL) { // the sta have been in sta_info_queue => do nothing + psta = rtw_alloc_stainfo(&Adapter->stapriv, macaddr); + + if (psta == NULL) { + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("Can't alloc sta_info when OID_RT_PRO_ADD_STA_INFO\n")); + status = NDIS_STATUS_FAILURE; + } + } else { //(between drv has received this event before and fw have not yet to set key to CAM_ENTRY) + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_err_, + ("Error: OID_RT_PRO_ADD_STA_INFO: sta has been in sta_hash_queue \n")); + } + + _irqlevel_changed_(&oldirql, RAISE); + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct sta_info *psta = NULL; + UCHAR *macaddr; + + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = ETH_ALEN; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + macaddr = (UCHAR *) poid_par_priv->information_buf ; + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_notice_, + ("+OID_RT_PRO_ADD_STA_INFO: addr="MAC_FMT"\n", MAC_ARG(macaddr) )); + + psta = rtw_get_stainfo(&Adapter->stapriv, macaddr); + if (psta != NULL) { + _enter_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + rtw_free_stainfo(Adapter, psta); + _exit_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + } + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +#if 0 +#include +static u32 mp_query_drv_var(_adapter *padapter, u8 offset, u32 var) +{ +#ifdef CONFIG_SDIO_HCI + + if (offset == 1) { + u16 tmp_blk_num; + tmp_blk_num = rtw_read16(padapter, SDIO_RX0_RDYBLK_NUM); + RT_TRACE(_module_mp_, _drv_err_, ("Query Information, mp_query_drv_var SDIO_RX0_RDYBLK_NUM=0x%x adapter_to_dvobj(padapter)->rxblknum=0x%x\n", tmp_blk_num, adapter_to_dvobj(padapter)->rxblknum)); + if (adapter_to_dvobj(padapter)->rxblknum != tmp_blk_num) { + RT_TRACE(_module_mp_,_drv_err_, ("Query Information, mp_query_drv_var call recv rx\n")); + // sd_recv_rxfifo(padapter); + } + } + +#if 0 + if(offset <=100){ //For setting data rate and query data rate + if(offset==100){ //For query data rate + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d): query rate=0x%.2x \n",offset,padapter->registrypriv.tx_rate)); + var=padapter->registrypriv.tx_rate; + + } + else if(offset<0x1d){ //For setting data rate + padapter->registrypriv.tx_rate=offset; + var=padapter->registrypriv.tx_rate; + padapter->registrypriv.use_rate=_TRUE; + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d): set rate=0x%.2x \n",offset,padapter->registrypriv.tx_rate)); + } + else{ //not use the data rate + padapter->registrypriv.use_rate=_FALSE; + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d) out of rate range\n",offset)); + } + } + else if (offset<=110){ //for setting debug level + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d) for set debug level\n",offset)); + if(offset==110){ //For query data rate + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d): query dbg level=0x%.2x \n",offset,padapter->registrypriv.dbg_level)); + padapter->registrypriv.dbg_level=GlobalDebugLevel; + var=padapter->registrypriv.dbg_level; + } + else if(offset<110 && offset>100){ + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d): set dbg level=0x%.2x \n",offset,offset-100)); + padapter->registrypriv.dbg_level=GlobalDebugLevel=offset-100; + var=padapter->registrypriv.dbg_level; + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var(_drv_emerg_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_alert_, (" mp_query_drv_var(_drv_alert_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_crit_, (" mp_query_drv_var(_drv_crit_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_err_, (" mp_query_drv_var(_drv_err_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_warning_, (" mp_query_drv_var(_drv_warning_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_notice_, (" mp_query_drv_var(_drv_notice_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_info_, (" mp_query_drv_var(_drv_info_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_debug_, (" mp_query_drv_var(_drv_debug_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + + } + } + else if(offset >110 &&offset <116){ + if(115==offset){ + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var(_drv_emerg_): offset(%d): query TRX access type: [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + } + else { + switch(offset){ + case 111: + adapter_to_dvobj(padapter)->tx_block_mode=1; + adapter_to_dvobj(padapter)->rx_block_mode=1; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX block/RX block) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 112: + adapter_to_dvobj(padapter)->tx_block_mode=1; + adapter_to_dvobj(padapter)->rx_block_mode=0; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX block/RX byte) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 113: + adapter_to_dvobj(padapter)->tx_block_mode=0; + adapter_to_dvobj(padapter)->rx_block_mode=1; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX byte/RX block) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 114: + adapter_to_dvobj(padapter)->tx_block_mode=0; + adapter_to_dvobj(padapter)->rx_block_mode=0; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX byte/RX byte) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + default : + break; + + } + + } + + } + else if(offset>=127){ + u64 prnt_dbg_comp; + u8 chg_idx; + u64 tmp_dbg_comp; + chg_idx=offset-0x80; + tmp_dbg_comp=BIT(chg_idx); + prnt_dbg_comp=padapter->registrypriv.dbg_component= GlobalDebugComponents; + RT_TRACE(_module_mp_, _drv_emerg_, (" 1: mp_query_drv_var: offset(%d;0x%x):for dbg conpoment prnt_dbg_comp=0x%.16x GlobalDebugComponents=0x%.16x padapter->registrypriv.dbg_component=0x%.16x\n",offset,offset,prnt_dbg_comp,GlobalDebugComponents,padapter->registrypriv.dbg_component)); + if(offset==127){ + // prnt_dbg_comp=padapter->registrypriv.dbg_component= GlobalDebugComponents; + var=(u32)(padapter->registrypriv.dbg_component); + RT_TRACE(0xffffffff, _drv_emerg_, ("2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) \n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_, ("2-1: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, ("2-2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + + } + else{ + RT_TRACE(0xffffffff, _drv_emerg_, ("3: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) chg_idx=%d\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp,chg_idx)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_,("3-1: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) chg_idx=%d\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp,chg_idx));// ("3-1: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment=0x%x chg_idx=%d or0x%x BIT(chg_idx[%d]=0x%x)\n",offset,offset,prnt_dbg_comp,chg_idx,chg_idx,(chg_idx),tmp_dbg_comp) + prnt_dbg_comp=GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, ("3-2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + + if(GlobalDebugComponents&tmp_dbg_comp){ + //this bit is already set, now clear it + GlobalDebugComponents=GlobalDebugComponents&(~tmp_dbg_comp); + } + else{ + //this bit is not set, now set it. + GlobalDebugComponents =GlobalDebugComponents|tmp_dbg_comp; + } + RT_TRACE(0xffffffff, _drv_emerg_, ("4: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment tmp_dbg_comp=0x%x GlobalDebugComponents=0x%x(l) 0x%x(h)",offset,offset,tmp_dbg_comp,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_, ("4-1: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment tmp_dbg_comp=0x%x GlobalDebugComponents=0x%x(l) 0x%x(h)",offset,offset,tmp_dbg_comp,prnt_dbg_comp)); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_emerg_, ("0: mp_query_drv_var(_module_rtl871x_xmit_c_:0): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,prnt_dbg_comp)); + RT_TRACE(_module_xmit_osdep_c_, _drv_emerg_, ("1: mp_query_drv_var(_module_xmit_osdep_c_:1): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_recv_c_, _drv_emerg_, ("2: mp_query_drv_var(_module_rtl871x_recv_c_:2): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_recv_osdep_c_, _drv_emerg_, ("3: mp_query_drv_var(_module_recv_osdep_c_:3): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_emerg_, ("4: mp_query_drv_var(_module_rtl871x_mlme_c_:4): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_mlme_osdep_c_, _drv_emerg_, (" 5:mp_query_drv_var(_module_mlme_osdep_c_:5): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_emerg_, ("6: mp_query_drv_var(_module_rtl871x_sta_mgt_c_:6): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_emerg_, ("7: mp_query_drv_var(_module_rtl871x_cmd_c_:7): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_cmd_osdep_c_, _drv_emerg_, ("8: mp_query_drv_var(_module_cmd_osdep_c_:8): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_io_c_, _drv_emerg_, ("9: mp_query_drv_var(_module_rtl871x_io_c_:9): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_io_osdep_c_, _drv_emerg_, ("10: mp_query_drv_var(_module_io_osdep_c_:10): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_os_intfs_c_, _drv_emerg_, ("11: mp_query_drv_var(_module_os_intfs_c_:11): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_security_c_, _drv_emerg_, ("12: mp_query_drv_var(_module_rtl871x_security_c_:12): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_emerg_, ("13: mp_query_drv_var(_module_rtl871x_eeprom_c_:13): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hal_init_c_, _drv_emerg_, ("14: mp_query_drv_var(_module_hal_init_c_:14): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_hal_init_c_, _drv_emerg_, ("15: mp_query_drv_var(_module_hci_hal_init_c_:15): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_emerg_, ("16: mp_query_drv_var(_module_rtl871x_ioctl_c_:16): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_emerg_, ("17: mp_query_drv_var(_module_rtl871x_ioctl_set_c_:17): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_query_c_, _drv_emerg_, ("18: mp_query_drv_var(_module_rtl871x_ioctl_query_c_:18): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_emerg_, ("19: mp_query_drv_var(_module_rtl871x_pwrctrl_c_:19): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_intfs_c_, _drv_emerg_, ("20: mp_query_drv_var(_module_hci_intfs_c_:20): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_ops_c_, _drv_emerg_, ("21: mp_query_drv_var(_module_hci_ops_c_:21): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_osdep_service_c_, _drv_emerg_, ("22: mp_query_drv_var(_module_osdep_service_c_:22): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_mp_, _drv_emerg_, ("23: mp_query_drv_var(_module_mp_:23): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_ops_os_c_, _drv_emerg_, ("24: mp_query_drv_var(_module_hci_ops_os_c_:24): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + var=(u32)(GlobalDebugComponents); + //GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, (" ==mp_query_drv_var(_module_mp_): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + + } + } + else{ + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d) >110\n",offset)); + } +#endif +#endif + + return var; +} +#endif + +NDIS_STATUS oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + DR_VARIABLE_STRUCT *pdrv_var; + + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = sizeof(DR_VARIABLE_STRUCT); + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Query Information, OID_RT_PRO_QUERY_DR_VARIABLE\n")); + + pdrv_var = (struct _DR_VARIABLE_STRUCT_ *)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset, pdrv_var->variable); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_query_dr_variable_hdl: offset=0x%x valule=0x%x\n", + pdrv_var->offset, pdrv_var->variable)); + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + RT_TRACE(_module_mp_, _drv_err_, ("oid_rt_pro_rx_packet_type_hdl...................\n")); + + if (poid_par_priv->information_buf_len < sizeof (UCHAR)) { + status = NDIS_STATUS_INVALID_LENGTH; + *poid_par_priv->bytes_needed = sizeof(UCHAR); + return status; + } + + if (poid_par_priv->type_of_oid == SET_OID) { + Adapter->mppriv.rx_with_status = *(UCHAR *) poid_par_priv->information_buf; + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_, ("Query Information, OID_RT_PRO_RX_PACKET_TYPE:%d \n",\ + Adapter->mppriv.rx_with_status)); + + //*(u32 *)&Adapter->eeprompriv.mac_addr[0]=rtw_read32(Adapter, 0x10250050); + //*(u16 *)&Adapter->eeprompriv.mac_addr[4]=rtw_read16(Adapter, 0x10250054); + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("MAC addr=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x \n", + Adapter->eeprompriv.mac_addr[0],Adapter->eeprompriv.mac_addr[1],Adapter->eeprompriv.mac_addr[2],\ + Adapter->eeprompriv.mac_addr[3],Adapter->eeprompriv.mac_addr[4],Adapter->eeprompriv.mac_addr[5])); + + } + else { + *(UCHAR *) poid_par_priv->information_buf = Adapter->mppriv.rx_with_status; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_, ("Query Information, OID_RT_PRO_RX_PACKET_TYPE:%d \n", \ + Adapter->mppriv.rx_with_status)); + + //*(u32 *)&Adapter->eeprompriv.mac_addr[0]=rtw_read32(Adapter, 0x10250050); + //*(u16 *)&Adapter->eeprompriv.mac_addr[4]=rtw_read16(Adapter, 0x10250054); + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("MAC addr=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x \n", + Adapter->eeprompriv.mac_addr[0],Adapter->eeprompriv.mac_addr[1],Adapter->eeprompriv.mac_addr[2],\ + Adapter->eeprompriv.mac_addr[3],Adapter->eeprompriv.mac_addr[4],Adapter->eeprompriv.mac_addr[5])); + } +#endif + + return NDIS_STATUS_SUCCESS; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PEFUSE_ACCESS_STRUCT pefuse; + u8 *data; + u16 addr = 0, cnts = 0, max_available_size = 0; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(EFUSE_ACCESS_STRUCT)) + return NDIS_STATUS_INVALID_LENGTH; + + pefuse = (PEFUSE_ACCESS_STRUCT)poid_par_priv->information_buf; + addr = pefuse->start_addr; + cnts = pefuse->cnts; + data = pefuse->data; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_read_efuse_hd: buf_len=%ld addr=%d cnts=%d\n", + poid_par_priv->information_buf_len, addr, cnts)); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_read_efuse_hdl: parameter error!\n")); + return NDIS_STATUS_NOT_ACCEPTED; + } + + _irqlevel_changed_(&oldirql, LOWER); + if (rtw_efuse_access(Adapter, _FALSE, addr, cnts, data) == _FAIL) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_read_efuse_hdl: rtw_efuse_access FAIL!\n")); + status = NDIS_STATUS_FAILURE; + } else + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PEFUSE_ACCESS_STRUCT pefuse; + u8 *data; + u16 addr = 0, cnts = 0, max_available_size = 0; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pefuse = (PEFUSE_ACCESS_STRUCT)poid_par_priv->information_buf; + addr = pefuse->start_addr; + cnts = pefuse->cnts; + data = pefuse->data; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_write_efuse_hdl: buf_len=%ld addr=0x%04x cnts=%d\n", + poid_par_priv->information_buf_len, addr, cnts)); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_write_efuse_hdl: parameter error")); + return NDIS_STATUS_NOT_ACCEPTED; + } + + _irqlevel_changed_(&oldirql, LOWER); + if (rtw_efuse_access(Adapter, _TRUE, addr, cnts, data) == _FAIL) + status = NDIS_STATUS_FAILURE; + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PPGPKT_STRUCT ppgpkt; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + +// RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_rw_efuse_pgpkt_hdl\n")); + + *poid_par_priv->bytes_rw = 0; + + if (poid_par_priv->information_buf_len < sizeof(PGPKT_STRUCT)) + return NDIS_STATUS_INVALID_LENGTH; + + ppgpkt = (PPGPKT_STRUCT)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (poid_par_priv->type_of_oid == QUERY_OID) + { + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_rw_efuse_pgpkt_hdl: Read offset=0x%x\n",\ + ppgpkt->offset)); + + Efuse_PowerSwitch(Adapter, _FALSE, _TRUE); + if (Efuse_PgPacketRead(Adapter, ppgpkt->offset, ppgpkt->data, _FALSE) == _TRUE) + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + else + status = NDIS_STATUS_FAILURE; + Efuse_PowerSwitch(Adapter, _FALSE, _FALSE); + } else { + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_rw_efuse_pgpkt_hdl: Write offset=0x%x word_en=0x%x\n",\ + ppgpkt->offset, ppgpkt->word_en)); + + Efuse_PowerSwitch(Adapter, _TRUE, _TRUE); + if (Efuse_PgPacketWrite(Adapter, ppgpkt->offset, ppgpkt->word_en, ppgpkt->data, _FALSE) == _TRUE) + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + else + status = NDIS_STATUS_FAILURE; + Efuse_PowerSwitch(Adapter, _TRUE, _FALSE); + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_rw_efuse_pgpkt_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u16 size; + u8 ret; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf = size; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } else + status = NDIS_STATUS_FAILURE; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + *(u32*)poid_par_priv->information_buf = efuse_GetMaxSize(Adapter); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_get_efuse_max_size_hdl: size=%d status=0x%08X\n", + *(int*)poid_par_priv->information_buf, status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_efuse_hdl\n")); + + if (poid_par_priv->type_of_oid == QUERY_OID) + status = oid_rt_pro_read_efuse_hdl(poid_par_priv); + else + status = oid_rt_pro_write_efuse_hdl(poid_par_priv); + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_efuse_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 *data; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + u16 mapLen=0; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_efuse_map_hdl\n")); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + *poid_par_priv->bytes_rw = 0; + + if (poid_par_priv->information_buf_len < mapLen) + return NDIS_STATUS_INVALID_LENGTH; + + data = (u8*)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (poid_par_priv->type_of_oid == QUERY_OID) + { + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_efuse_map_hdl: READ\n")); + + if (rtw_efuse_map_read(Adapter, 0, mapLen, data) == _SUCCESS) + *poid_par_priv->bytes_rw = mapLen; + else { + RT_TRACE(_module_mp_, _drv_err_, + ("oid_rt_pro_efuse_map_hdl: READ fail\n")); + status = NDIS_STATUS_FAILURE; + } + } else { + // SET_OID + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_efuse_map_hdl: WRITE\n")); + + if (rtw_efuse_map_write(Adapter, 0, mapLen, data) == _SUCCESS) + *poid_par_priv->bytes_rw = mapLen; + else { + RT_TRACE(_module_mp_, _drv_err_, + ("oid_rt_pro_efuse_map_hdl: WRITE fail\n")); + status = NDIS_STATUS_FAILURE; + } + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_efuse_map_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + + u32 crystal_cap = 0; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf);//4 + if (crystal_cap > 0xf) + return NDIS_STATUS_NOT_ACCEPTED; + + Adapter->mppriv.curr_crystalcap = crystal_cap; + + _irqlevel_changed_(&oldirql,LOWER); + SetCrystalCap(Adapter); + _irqlevel_changed_(&oldirql,RAISE); + +_func_exit_; + +#endif + return status; +} + +NDIS_STATUS oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 rx_pkt_type; +// u32 rcr_val32; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +// PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_set_rx_packet_type_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + rx_pkt_type = *((u8*)poid_par_priv->information_buf);//4 + + RT_TRACE(_module_mp_, _drv_info_, ("rx_pkt_type: %x\n",rx_pkt_type )); +#if 0 + _irqlevel_changed_(&oldirql, LOWER); +#if 0 + rcr_val8 = rtw_read8(Adapter, 0x10250048);//RCR + rcr_val8 &= ~(RCR_AB|RCR_AM|RCR_APM|RCR_AAP); + + if(rx_pkt_type == RX_PKT_BROADCAST){ + rcr_val8 |= (RCR_AB | RCR_ACRC32 ); + } + else if(rx_pkt_type == RX_PKT_DEST_ADDR){ + rcr_val8 |= (RCR_AAP| RCR_AM |RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_PHY_MATCH){ + rcr_val8 |= (RCR_APM|RCR_ACRC32); + } + else{ + rcr_val8 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + } + rtw_write8(padapter, 0x10250048,rcr_val8); +#else + rcr_val32 = rtw_read32(padapter, RCR);//RCR = 0x10250048 + rcr_val32 &= ~(RCR_CBSSID|RCR_AB|RCR_AM|RCR_APM|RCR_AAP); +#if 0 + if(rx_pkt_type == RX_PKT_BROADCAST){ + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_DEST_ADDR){ + //rcr_val32 |= (RCR_CBSSID|RCR_AAP|RCR_AM|RCR_ACRC32); + rcr_val32 |= (RCR_CBSSID|RCR_APM|RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_PHY_MATCH){ + rcr_val32 |= (RCR_APM|RCR_ACRC32); + //rcr_val32 |= (RCR_AAP|RCR_ACRC32); + } + else{ + rcr_val32 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + } +#else + switch (rx_pkt_type) + { + case RX_PKT_BROADCAST : + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + break; + case RX_PKT_DEST_ADDR : + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + break; + case RX_PKT_PHY_MATCH: + rcr_val32 |= (RCR_APM|RCR_ACRC32); + break; + default: + rcr_val32 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + break; + } + + if (rx_pkt_type == RX_PKT_DEST_ADDR) { + padapter->mppriv.check_mp_pkt = 1; + } else { + padapter->mppriv.check_mp_pkt = 0; + } +#endif + rtw_write32(padapter, RCR, rcr_val32); + +#endif + _irqlevel_changed_(&oldirql, RAISE); +#endif +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + u32 txagc; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + txagc = *(u32*)poid_par_priv->information_buf; + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_set_tx_agc_offset_hdl: 0x%08x\n", txagc)); + + _irqlevel_changed_(&oldirql, LOWER); + SetTxAGCOffset(Adapter, txagc); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +NDIS_STATUS oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + struct mp_priv *pmppriv = &Adapter->mppriv; + u32 type; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf; + + if (_LOOPBOOK_MODE_ == type) { + pmppriv->mode = type; + set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); //append txdesc + RT_TRACE(_module_mp_, _drv_info_, ("test mode change to loopback mode:0x%08x.\n", get_fwstate(pmlmepriv))); + } else if (_2MAC_MODE_ == type){ + pmppriv->mode = type; + _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE); + RT_TRACE(_module_mp_, _drv_info_, ("test mode change to 2mac mode:0x%08x.\n", get_fwstate(pmlmepriv))); + } else + status = NDIS_STATUS_NOT_ACCEPTED; + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) +{ + PMP_XMIT_PARM pparm; + PADAPTER padapter; + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + + RT_TRACE(_module_mp_, _drv_notice_, ("+%s\n", __func__)); + + pparm = (PMP_XMIT_PARM)poid_par_priv->information_buf; + padapter = (PADAPTER)poid_par_priv->adapter_context; + pmp_priv = &padapter->mppriv; + + if (poid_par_priv->type_of_oid == QUERY_OID) { + pparm->enable = !pmp_priv->tx.stop; + pparm->count = pmp_priv->tx.sended; + } else { + if (pparm->enable == 0) { + pmp_priv->tx.stop = 1; + } else if (pmp_priv->tx.stop == 1) { + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = pparm->count; + pmp_priv->tx.payload = pparm->payload_type; + pattrib = &pmp_priv->tx.attrib; + pattrib->pktlen = pparm->length; + _rtw_memcpy(pattrib->dst, pparm->da, ETH_ALEN); + SetPacketTx(padapter); + } else + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + +#if 0 +unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) +{ + unsigned char *pframe, *pmp_pkt; + struct ethhdr *pethhdr; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + int llc_sz, payload_len; + struct mp_xmit_frame *pxframe= NULL; + struct mp_xmit_packet *pmp_xmitpkt = (struct mp_xmit_packet*)param; + u8 addr3[] = {0x02, 0xE0, 0x4C, 0x87, 0x66, 0x55}; + +// DBG_871X("+mp_ioctl_xmit_packet_hdl\n"); + + pxframe = alloc_mp_xmitframe(&padapter->mppriv); + if (pxframe == NULL) + { + DEBUG_ERR(("Can't alloc pmpframe %d:%s\n", __LINE__, __FILE__)); + return -1; + } + + //mp_xmit_pkt + payload_len = pmp_xmitpkt->len - 14; + pmp_pkt = (unsigned char*)pmp_xmitpkt->mem; + pethhdr = (struct ethhdr *)pmp_pkt; + + //DBG_871X("payload_len=%d, pkt_mem=0x%x\n", pmp_xmitpkt->len, (void*)pmp_xmitpkt->mem); + + //DBG_871X("pxframe=0x%x\n", (void*)pxframe); + //DBG_871X("pxframe->mem=0x%x\n", (void*)pxframe->mem); + + //update attribute + pattrib = &pxframe->attrib; + memset((u8 *)(pattrib), 0, sizeof (struct pkt_attrib)); + pattrib->pktlen = pmp_xmitpkt->len; + pattrib->ether_type = ntohs(pethhdr->h_proto); + pattrib->hdrlen = 24; + pattrib->nr_frags = 1; + pattrib->priority = 0; +#ifndef CONFIG_MP_LINUX + if(IS_MCAST(pethhdr->h_dest)) + pattrib->mac_id = 4; + else + pattrib->mac_id = 5; +#else + pattrib->mac_id = 5; +#endif + + // + memset(pxframe->mem, 0 , WLANHDR_OFFSET); + pframe = (u8 *)(pxframe->mem) + WLANHDR_OFFSET; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + SetFrameSubType(pframe, WIFI_DATA); + + _rtw_memcpy(pwlanhdr->addr1, pethhdr->h_dest, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pethhdr->h_source, ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr3, addr3, ETH_ALEN); + + pwlanhdr->seq_ctl = 0; + pframe += pattrib->hdrlen; + + llc_sz= rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + + _rtw_memcpy(pframe, (void*)(pmp_pkt+14), payload_len); + + pattrib->last_txcmdsz = pattrib->hdrlen + llc_sz + payload_len; + + DEBUG_INFO(("issuing mp_xmit_frame, tx_len=%d, ether_type=0x%x\n", pattrib->last_txcmdsz, pattrib->ether_type)); + xmit_mp_frame(padapter, pxframe); + + return _SUCCESS; +} +#endif +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 bpwrup; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#ifdef PLATFORM_LINUX +#ifdef CONFIG_SDIO_HCI + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); +#endif +#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + RT_TRACE(_module_mp_, _drv_info_, + ("\n ===> Setoid_rt_set_power_down_hdl.\n")); + + _irqlevel_changed_(&oldirql, LOWER); + + bpwrup = *(u8 *)poid_par_priv->information_buf; + //CALL the power_down function +#ifdef PLATFORM_LINUX +#ifdef CONFIG_SDIO_HCI + dev_power_down(padapter,bpwrup); +#endif +#endif + _irqlevel_changed_(&oldirql, RAISE); + + //DEBUG_ERR(("\n <=== Query OID_RT_PRO_READ_REGISTER. + // Add:0x%08x Width:%d Value:0x%08x\n",RegRWStruct->offset,RegRWStruct->width,RegRWStruct->value)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); +//#ifdef PLATFORM_OS_XP +// _irqL oldirql; +//#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if (poid_par_priv->information_buf_len < sizeof(u32)) { + status = NDIS_STATUS_INVALID_LENGTH; + return status; + } + + RT_TRACE(_module_mp_, _drv_info_, + ("\n ===> oid_rt_get_power_mode_hdl.\n")); + +// _irqlevel_changed_(&oldirql, LOWER); + *(int*)poid_par_priv->information_buf = Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; +// _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + diff --git a/rtl8192cu-fixes/core/rtw_p2p.c b/rtl8192cu-fixes/core/rtw_p2p.c new file mode 100755 index 00000000..66c5f96d --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_p2p.c @@ -0,0 +1,5294 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_P2P_C_ + +#include +#include +#include + +#ifdef CONFIG_P2P + +int rtw_p2p_is_channel_list_ok( u8 desired_ch, u8* ch_list, u8 ch_cnt ) +{ + int found = 0, i = 0; + + for( i = 0; i < ch_cnt; i++ ) + { + if ( ch_list[ i ] == desired_ch ) + { + found = 1; + break; + } + } + return( found ); +} + +int is_any_client_associated(_adapter *padapter) +{ + return padapter->stapriv.asoc_list_cnt ? _TRUE : _FALSE; +} + +static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + _irqL irqL; + _list *phead, *plist; + u32 len=0; + u16 attr_len = 0; + u8 tmplen, *pdata_attr, *pstart, *pcur; + struct sta_info *psta = NULL; + _adapter *padapter = pwdinfo->padapter; + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN); + + pstart = pdata_attr; + pcur = pdata_attr; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //look up sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + + if(psta->is_p2p_device) + { + tmplen = 0; + + pcur++; + + //P2P device address + _rtw_memcpy(pcur, psta->dev_addr, ETH_ALEN); + pcur += ETH_ALEN; + + //P2P interface address + _rtw_memcpy(pcur, psta->hwaddr, ETH_ALEN); + pcur += ETH_ALEN; + + *pcur = psta->dev_cap; + pcur++; + + //*(u16*)(pcur) = cpu_to_be16(psta->config_methods); + RTW_PUT_BE16(pcur, psta->config_methods); + pcur += 2; + + _rtw_memcpy(pcur, psta->primary_dev_type, 8); + pcur += 8; + + *pcur = psta->num_of_secdev_type; + pcur++; + + _rtw_memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8); + pcur += psta->num_of_secdev_type*8; + + if(psta->dev_name_len>0) + { + //*(u16*)(pcur) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME); + pcur += 2; + + //*(u16*)(pcur) = cpu_to_be16( psta->dev_name_len ); + RTW_PUT_BE16(pcur, psta->dev_name_len); + pcur += 2; + + _rtw_memcpy(pcur, psta->dev_name, psta->dev_name_len); + pcur += psta->dev_name_len; + } + + + tmplen = (u8)(pcur-pstart); + + *pstart = (tmplen-1); + + attr_len += tmplen; + + //pstart += tmplen; + pstart = pcur; + + } + + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + if(attr_len>0) + { + len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr); + } + + rtw_mfree(pdata_attr, MAX_P2P_IE_LEN); + + return len; + +} + +static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_DISC_REQUEST; + u8 dialogToken=0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); + + 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); + + //Build P2P action frame header + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + //there is no IE in this P2P action frame + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_DEVDISC_RESP; + u8 p2pie[8] = { 0x00 }; + u32 p2pielen = 0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN); + + 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); + + //Build P2P public action frame header + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //Build P2P IE + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // P2P_ATTR_STATUS + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8* raddr, u8* frame_body, u16 config_method) +{ + _adapter *padapter = pwdinfo->padapter; + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = frame_body[7]; // The Dialog Token of provisioning discovery request frame. + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_RESP; + u8 wpsie[ 100 ] = { 0x00 }; + u8 wpsielen = 0; +#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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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: + //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); + RTW_PUT_BE16(wpsie + wpsielen, config_method); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PRESENCE_RESPONSE; + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u8 noa_attr_content[32] = { 0x00 }; + u32 p2pielen = 0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); + + 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); + + //Build P2P action frame header + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //Add P2P IE header + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + //Add Status attribute in P2P IE + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); + + //Add NoA attribute in P2P IE + noa_attr_content[0] = 0x1;//index + noa_attr_content[1] = 0x0;//CTWindow and OppPS Parameters + + //todo: Notice of Absence Descriptor(s) + + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content); + + + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen)); + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u16 capability=0; + u32 len=0, p2pielen = 0; + + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + + // According to the P2P Specification, the beacon frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. P2P Device ID + // 3. Notice of Absence ( NOA ) + + // P2P Capability ATTR + // Type: + // Length: + // Value: + // Device Capability Bitmap, 1 byte + // Be able to participate in additional P2P Groups and + // support the P2P Invitation Procedure + // Group Capability Bitmap, 1 byte + capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY; + capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8); + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + capability |= (P2P_GRPCAP_GROUP_FORMATION<<8); + + capability = cpu_to_le16(capability); + + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8*)&capability); + + + // P2P Device ID ATTR + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr); + + + // Notice of Absence ATTR + // Type: + // Length: + // Value: + + //go_add_noa_attr(pwdinfo); + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + +#ifdef CONFIG_WFD +u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the beacon frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + if ( is_any_client_associated( pwdinfo->padapter ) ) + { + // WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD ); + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + } + + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + + if ( 1 == pwdinfo->wfd_tdls_enable ) + { + // WFD primary sink + available for WFD session + WiFi TDLS mode + WSC ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | + WFD_DEVINFO_SESSION_AVAIL | + WFD_DEVINFO_WSD | + WFD_DEVINFO_PC_TDLS ); + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSC ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | + WFD_DEVINFO_SESSION_AVAIL | + WFD_DEVINFO_WSD ); + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe response frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + // 4. WFD Session Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + + if ( _TRUE == pwdinfo->session_available ) + { + if ( P2P_ROLE_GO == pwdinfo->role ) + { + if ( is_any_client_associated( pwdinfo->padapter ) ) + { + if ( pwdinfo->wfd_tdls_enable ) + { + // TDLS mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + // WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + // available for WFD session + TDLS mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD |WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_TDLS + if ( ( tunneled == 0 ) && ( padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1 ) ) + { + // Alternative MAC Address ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ALTER_MAC; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, ETH_ALEN ); + wfdielen += 2; + + // Value: + // Alternative MAC Address + _rtw_memcpy( wfdie + wfdielen, &padapter->pbuddy_adapter->eeprompriv.mac_addr[ 0 ], ETH_ALEN ); + // This mac address is used to make the WFD session when TDLS is enable. + + wfdielen += ETH_ALEN; + } +#endif // CONFIG_TDLS +#endif // CONFIG_CONCURRENT_MODE + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = NULL; + struct mlme_priv *pmlmepriv = NULL; + struct wifi_display_info *pwfd_info = NULL; + + // WFD OUI + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + return 0; + } + + padapter = pwdinfo->padapter; + pmlmepriv = &padapter->mlmepriv; + pwfd_info = padapter->wdinfo.wfd_info; + + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD ); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + + return len; + +} + +#endif //CONFIG_WFD + +u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; +#ifdef CONFIG_INTEL_WIDI + struct mlme_priv *pmlmepriv = &(pwdinfo->padapter->mlmepriv); + u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 }; + u8 widi_version = 0, i = 0; + + if( _rtw_memcmp( pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE ) + { + widi_version = 35; + } + else if( pmlmepriv->num_p2p_sdt != 0 ) + { + widi_version = 40; + } +#endif //CONFIG_INTEL_WIDI + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20100907 + // According to the P2P Specification, the probe response frame should contain 5 P2P attributes + // 1. P2P Capability + // 2. Extended Listen Timing + // 3. Notice of Absence ( NOA ) ( Only GO needs this ) + // 4. Device Info + // 5. Group Info ( Only GO need this ) + + // P2P Capability ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION; + + p2pielen++; + } + else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) ) + { + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + } + + // Extended Listen Timing ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0004); + p2pielen += 2; + + // Value: + // Availability Period + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); + p2pielen += 2; + + // Availability Interval + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); + p2pielen += 2; + + + // Notice of Absence ATTR + // Type: + // Length: + // Value: + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + //go_add_noa_attr(pwdinfo); + } + + // Device Info ATTR + // 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 ); +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 35 ) + { + RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len); + } + else if( widi_version == 40 ) + { + RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 * pmlmepriv->num_p2p_sdt + pwdinfo->device_name_len); + } + else +#endif //CONFIG_INTEL_WIDI + RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + // P2P Device Address + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, 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 ); + RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); + p2pielen += 2; + +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 40 ) + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_cid ); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_scid); + p2pielen += 2; + } + else +#endif //CONFIG_INTEL_WIDI + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); + p2pielen += 2; + } + + // Number of Secondary Device Types +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 35 ) + { + p2pie[ p2pielen++ ] = 0x01; + + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_DISPLAYS); + p2pielen += 2; + + RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI); + p2pielen += 4; + + RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK); + p2pielen += 2; + } + else if( widi_version == 40 ) + { + p2pie[ p2pielen++ ] = pmlmepriv->num_p2p_sdt; + for( ; i < pmlmepriv->num_p2p_sdt; i++ ) + { + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_cid[i]); + p2pielen += 2; + + RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI); + p2pielen += 4; + + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_scid[i]); + p2pielen += 2; + } + } + else +#endif //CONFIG_INTEL_WIDI + p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List + + // Device Name + // Type: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); + p2pielen += 2; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); + RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len ); + p2pielen += pwdinfo->device_name_len; + + // Group Info ATTR + // Type: + // Length: + // Value: + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen); + } + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + +u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr ) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110301 + // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Device Info + // 3. Group ID ( When joining an operating P2P Group ) + + // P2P Capability ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + + // Device Info ATTR + // 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 ); + RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + // P2P Device Address + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); + p2pielen += ETH_ALEN; + + // Config Method + // This field should be big endian. Noted by P2P specification. + if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC ) + { + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC); + } + else + { + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY); + } + + p2pielen += 2; + + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, 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 ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); + p2pielen += 2; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); + RTW_PUT_BE16(p2pie + p2pielen, 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_CLIENT) ) + { + // Added by Albert 2011/05/19 + // In this case, the pdev_raddr is the device address of the group owner. + + // P2P Group ID ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + ussidlen ); + RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pdev_raddr, ETH_ALEN ); + p2pielen += ETH_ALEN; + + _rtw_memcpy( p2pie + p2pielen, pssid, ussidlen ); + p2pielen += ussidlen; + + } + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + + +u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // According to the P2P Specification, the Association response frame should contain 2 P2P attributes + // 1. Status + // 2. Extended Listen Timing (optional) + + + // Status ATTR + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code); + + + // Extended Listen Timing ATTR + // Type: + // Length: + // Value: + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + return len; + +} + +u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u32 len=0; + + return len; +} + +u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *p; + u32 ret=_FALSE; + u8 *p2pie; + u32 p2pielen = 0; + int ssid_len=0, rate_cnt = 0; + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + if ( rate_cnt <= 4 ) + { + int i, g_rate =0; + + for( i = 0; i < rate_cnt; i++ ) + { + if ( ( ( *( p + 2 + i ) & 0xff ) != 0x02 ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x04 ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x0B ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x16 ) ) + { + g_rate = 1; + } + } + + if ( g_rate == 0 ) + { + // There is no OFDM rate included in SupportedRates IE of this probe request frame + // The driver should response this probe request. + return ret; + } + } + else + { + // rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. + // We should proceed the following check for this probe request. + } + + // Added comments by Albert 20100906 + // There are several items we should check here. + // 1. This probe request frame must contain the P2P IE. (Done) + // 2. This probe request frame must contain the wildcard SSID. (Done) + // 3. Wildcard BSSID. (Todo) + // 4. Destination Address. ( Done in mgt_dispatcher function ) + // 5. Requested Device Type in WSC IE. (Todo) + // 6. Device ID attribute in P2P IE. (Todo) + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + ssid_len &= 0xff; // Just last 1 byte is valid for ssid len of the probe request + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if((p2pie=rtw_get_p2p_ie( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen))) + { + if ( (p != NULL) && _rtw_memcmp( ( void * ) ( p+2 ), ( void * ) pwdinfo->p2p_wildcard_ssid , 7 )) + { + //todo: + //Check Requested Device Type attributes in WSC IE. + //Check Device ID attribute in P2P IE + + ret = _TRUE; + } + else if ( (p != NULL) && ( ssid_len == 0 ) ) + { + ret = _TRUE; + } + } + else + { + //non -p2p device + } + + } + + + return ret; + +} + +u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta) +{ + u8 status_code = P2P_STATUS_SUCCESS; + u8 *pbuf, *pattr_content=NULL; + u32 attr_contentlen = 0; + u16 cap_attr=0; + unsigned short frame_type, ie_offset=0; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + + if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + return P2P_STATUS_FAIL_REQUEST_UNABLE; + + frame_type = GetFrameSubType(pframe); + if (frame_type == WIFI_ASSOCREQ) + { + ie_offset = _ASOCREQ_IE_OFFSET_; + } + else // WIFI_REASSOCREQ + { + ie_offset = _REASOCREQ_IE_OFFSET_; + } + + ies = pframe + WLAN_HDR_A3_LEN + ie_offset; + ies_len = len - WLAN_HDR_A3_LEN - ie_offset; + + p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen); + + if ( !p2p_ie ) + { + DBG_8192C( "[%s] P2P IE not Found!!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INVALID_PARAM; + } + else + { + DBG_8192C( "[%s] P2P IE Found!!\n", __FUNCTION__ ); + } + + while ( p2p_ie ) + { + //Check P2P Capability ATTR + if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) ) + { + DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); + cap_attr = le16_to_cpu(cap_attr); + psta->dev_cap = cap_attr&0xff; + } + + //Check Extended Listen Timing ATTR + + + //Check P2P Device Info ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint*)&attr_contentlen)) + { + DBG_8192C( "[%s] Got P2P DEVICE INFO Attr!!\n", __FUNCTION__ ); + pattr_content = pbuf = rtw_zmalloc(attr_contentlen); + if(pattr_content) + { + u8 num_of_secdev_type; + u16 dev_name_len; + + + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint*)&attr_contentlen); + + _rtw_memcpy(psta->dev_addr, pattr_content, ETH_ALEN);//P2P Device Address + + pattr_content += ETH_ALEN; + + _rtw_memcpy(&psta->config_methods, pattr_content, 2);//Config Methods + psta->config_methods = be16_to_cpu(psta->config_methods); + + pattr_content += 2; + + _rtw_memcpy(psta->primary_dev_type, pattr_content, 8); + + pattr_content += 8; + + num_of_secdev_type = *pattr_content; + pattr_content += 1; + + if(num_of_secdev_type==0) + { + psta->num_of_secdev_type = 0; + } + else + { + u32 len; + + psta->num_of_secdev_type = num_of_secdev_type; + + len = (sizeof(psta->secdev_types_list)<(num_of_secdev_type*8)) ? (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8); + + _rtw_memcpy(psta->secdev_types_list, pattr_content, len); + + pattr_content += (num_of_secdev_type*8); + } + + + //dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8); + psta->dev_name_len=0; + if(WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(u16*)pattr_content)) + { + dev_name_len = be16_to_cpu(*(u16*)(pattr_content+2)); + + psta->dev_name_len = (sizeof(psta->dev_name)dev_name):dev_name_len; + + _rtw_memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len); + } + + rtw_mfree(pbuf, attr_contentlen); + + } + + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + return status_code; + +} + +u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *frame_body; + u8 status, dialogToken; + struct sta_info *psta = NULL; + _adapter *padapter = pwdinfo->padapter; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *p2p_ie; + u32 p2p_ielen = 0; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + dialogToken = frame_body[7]; + status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; + + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + u8 groupid[ 38 ] = { 0x00 }; + u8 dev_addr[ETH_ALEN] = { 0x00 }; + u32 attr_contentlen = 0; + + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) + { + if(_rtw_memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) && + _rtw_memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len)) + { + attr_contentlen=0; + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) + { + _irqL irqL; + _list *phead, *plist; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //look up sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + if(psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) && + _rtw_memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) + { + + //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + //issue GO Discoverability Request + issue_group_disc_req(pwdinfo, psta->hwaddr); + //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + status = P2P_STATUS_SUCCESS; + + break; + } + else + { + status = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + else + { + status = P2P_STATUS_FAIL_INVALID_PARAM; + } + + } + else + { + status = P2P_STATUS_FAIL_INVALID_PARAM; + } + + } + + } + + + //issue Device Discoverability Response + issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); + + + return (status==P2P_STATUS_SUCCESS) ? _TRUE:_FALSE; + +} + +u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + return _TRUE; +} + +u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + u8 *frame_body; + u8 *wpsie; + uint wps_ielen = 0, attr_contentlen = 0; + u16 uconfig_method = 0; + + + frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + if ( (wpsie=rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) ) + { + if ( rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_CONF_METHOD , ( u8* ) &uconfig_method, &attr_contentlen) ) + { + uconfig_method = be16_to_cpu( uconfig_method ); + switch( uconfig_method ) + { + case WPS_CM_DISPLYA: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + break; + } + case WPS_CM_LABEL: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3 ); + break; + } + case WPS_CM_PUSH_BUTTON: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + break; + } + case WPS_CM_KEYPAD: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + break; + } + } + issue_p2p_provision_resp( pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method); + } + } + DBG_871X( "[%s] config method = %s\n", __FUNCTION__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req ); + return _TRUE; + +} + +u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe) +{ + + return _TRUE; +} + +u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list) +{ + u8 i = 0, j = 0; + u8 temp = 0; + u8 ch_no = 0; + ch_content += 3; + ch_cnt -= 3; + + while( ch_cnt > 0) + { + ch_content += 1; + ch_cnt -= 1; + temp = *ch_content; + for( i = 0 ; i < temp ; i++, j++ ) + { + peer_ch_list[j] = *( ch_content + 1 + i ); + } + ch_content += (temp + 1); + ch_cnt -= (temp + 1); + ch_no += temp ; + } + + return ch_no; +} + +u8 rtw_p2p_check_peer_oper_ch(struct mlme_ext_priv *pmlmeext, u8 ch) +{ + u8 i = 0; + + for( i = 0; i < pmlmeext->max_chan_nums; i++ ) + { + if ( pmlmeext->channel_set[ i ].ChannelNum == ch ) + { + return _SUCCESS; + } + } + + return _FAIL; +} + +u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned) +{ + int i = 0, j = 0, temp = 0; + u8 ch_no = 0; + + for( i = 0; i < peer_ch_num; i++ ) + { + for( j = temp; j < pmlmeext->max_chan_nums; j++ ) + { + if( *( peer_ch_list + i ) == pmlmeext->channel_set[ j ].ChannelNum ) + { + ch_list_inclusioned[ ch_no++ ] = *( peer_ch_list + i ); + temp = j; + break; + } + } + } + + return ch_no; +} + +u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + _adapter *padapter = pwdinfo->padapter; + u8 result = P2P_STATUS_SUCCESS; + u32 p2p_ielen = 0, wps_ielen = 0; + u8 * ies; + u32 ies_len; + u8 *p2p_ie; + u8 *wpsie; + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; +#ifdef CONFIG_WFD + u8 wfd_ie[ 128 ] = { 0x00 }; + u32 wfd_ielen = 0; +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#endif // CONFIG_TDLS +#endif // CONFIG_WFD +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = pwdinfo->padapter->pbuddy_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 + + if ( (wpsie=rtw_get_wps_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) ) + { + // Commented by Kurt 20120113 + // If some device wants to do p2p handshake without sending prov_disc_req + // We have to get peer_req_cm from here. + if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) ) + { + rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + if ( wps_devicepassword_id == WPS_DPID_USER_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + } + else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + } + else + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + } + } + } + else + { + DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + return( result ); + } + + if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO ) + { + result = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY); + return( result ); + } + + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + if ( !p2p_ie ) + { + DBG_871X( "[%s] P2P IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + + while ( p2p_ie ) + { + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + u8 ch_content[100] = { 0x00 }; + uint ch_cnt = 0; + u8 peer_ch_list[100] = { 0x00 }; + u8 peer_ch_num = 0; + u8 ch_list_inclusioned[100] = { 0x00 }; + u8 ch_num_inclusioned = 0; + u16 cap_attr; + + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); + + //Check P2P Capability ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) ) + { + cap_attr = le16_to_cpu(cap_attr); + +#if defined(CONFIG_WFD) && defined(CONFIG_TDLS) + if(!(cap_attr & P2P_GRPCAP_INTRABSS) ) + ptdlsinfo->ap_prohibited = _TRUE; +#endif //defined(CONFIG_WFD) && defined(CONFIG_TDLS) + } + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) ) + { + DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 ); + pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values. + + if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) ) + { + // Try to match the tie breaker value + if ( pwdinfo->intent == P2P_MAX_INTENT ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; + } + else + { + if ( attr_content & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + } + else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + // Store the group id information. + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen ); + } + } + + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) ) + { + if ( attr_contentlen != ETH_ALEN ) + { + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + } + } + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt) ) + { + peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list); + ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); + + if( ch_num_inclusioned == 0) + { + DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel, + ch_list_inclusioned, ch_num_inclusioned) ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; + attr_contentlen = 0; + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + peer_operating_ch = operatingch_info[4]; + } + + if ( rtw_p2p_is_channel_list_ok( peer_operating_ch, + ch_list_inclusioned, ch_num_inclusioned) ) + { + /** + * Change our operating channel as peer's for compatibility. + */ + pwdinfo->operating_channel = peer_operating_ch; + DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel); + } + else + { + // Take first channel of ch_list_inclusioned as operating channel + pwdinfo->operating_channel = ch_list_inclusioned[0]; + DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel); + } + } + + } + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } + +#ifdef CONFIG_WFD + // Added by Albert 20110823 + // Try to get the TCP port information when receiving the negotiation request. + if ( rtw_get_wfd_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen ) ) + { + u8 attr_content[ 10 ] = { 0x00 }; + u32 attr_contentlen = 0; + + DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ ); + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + } + } +#endif // CONFIG_WFD + + return( result ); +} + +u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + _adapter *padapter = pwdinfo->padapter; + u8 result = P2P_STATUS_SUCCESS; + u32 p2p_ielen, wps_ielen; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; +#ifdef CONFIG_WFD + u8 wfd_ie[ 128 ] = { 0x00 }; + u32 wfd_ielen = 0; +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#endif // CONFIG_TDLS +#endif // CONFIG_WFD + + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + // Be able to know which one is the P2P GO and which one is P2P client. + + if ( rtw_get_wps_ie( ies, ies_len, NULL, &wps_ielen) ) + { + + } + else + { + DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + if ( !p2p_ie ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + } + else + { + + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + u8 operatingch_info[5] = { 0x00 }; + uint ch_cnt = 0; + u8 ch_content[100] = { 0x00 }; + u8 groupid[ 38 ]; + u16 cap_attr; + u8 peer_ch_list[100] = { 0x00 }; + u8 peer_ch_num = 0; + u8 ch_list_inclusioned[100] = { 0x00 }; + u8 ch_num_inclusioned = 0; + + while ( p2p_ie ) // Found the P2P IE. + { + + //Check P2P Capability ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) ) + { + cap_attr = le16_to_cpu(cap_attr); +#if defined(CONFIG_WFD) && defined(CONFIG_TDLS) + if(!(cap_attr & P2P_GRPCAP_INTRABSS) ) + ptdlsinfo->ap_prohibited = _TRUE; +#endif //defined(CONFIG_WFD) && defined(CONFIG_TDLS) + } + + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + if ( attr_content == P2P_STATUS_SUCCESS ) + { + // Do nothing. + } + else + { + if ( P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content ) { + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY); + } else { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = attr_content; + break; + } + } + + // Try to get the peer's interface address + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) ) + { + if ( attr_contentlen != ETH_ALEN ) + { + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + } + } + + // Try to get the peer's intent and tie breaker value. + attr_content = 0x00; + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) ) + { + DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 ); + pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values. + + if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) ) + { + // Try to match the tie breaker value + if ( pwdinfo->intent == P2P_MAX_INTENT ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + if ( attr_content & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + } + else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + // Store the group id information. + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen ); + + } + } + + // Try to get the operation channel information + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) + { + DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] ); + pwdinfo->peer_operating_ch = operatingch_info[4]; + } + + // Try to get the channel list information + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len ) ) + { + DBG_871X( "[%s] channel list attribute found, len = %d\n", __FUNCTION__, pwdinfo->channel_list_attr_len ); + + peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list); + ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); + + if( ch_num_inclusioned == 0) + { + DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel, + ch_list_inclusioned, ch_num_inclusioned) ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; + attr_contentlen = 0; + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + peer_operating_ch = operatingch_info[4]; + } + + if ( rtw_p2p_is_channel_list_ok( peer_operating_ch, + ch_list_inclusioned, ch_num_inclusioned) ) + { + /** + * Change our operating channel as peer's for compatibility. + */ + pwdinfo->operating_channel = peer_operating_ch; + DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel); + } + else + { + // Take first channel of ch_list_inclusioned as operating channel + pwdinfo->operating_channel = ch_list_inclusioned[0]; + DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel); + } + } + + } + } + + } + else + { + DBG_871X( "[%s] channel list attribute not found!\n", __FUNCTION__); + } + + // Try to get the group id information if peer is GO + attr_contentlen = 0; + _rtw_memset( groupid, 0x00, 38 ); + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) ) + { + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN ); + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } + + } + +#ifdef CONFIG_WFD + // Added by Albert 20111122 + // Try to get the TCP port information when receiving the negotiation response. + if ( rtw_get_wfd_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wfd_ie, &wfd_ielen ) ) + { + u8 attr_content[ 10 ] = { 0x00 }; + u32 attr_contentlen = 0; + + DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ ); + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + } + } +#endif // CONFIG_WFD + + return( result ); + +} + +u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + u8 result = P2P_STATUS_SUCCESS; + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + while ( p2p_ie ) // Found the P2P IE. + { + u8 attr_content = 0x00, operatingch_info[5] = { 0x00 }; + u8 groupid[ 38 ] = { 0x00 }; + u32 attr_contentlen = 0; + + pwdinfo->negotiation_dialog_token = 1; + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + result = attr_content; + + if ( attr_content == P2P_STATUS_SUCCESS ) + { + u8 bcancelled = 0; + + _cancel_timer( &pwdinfo->restore_p2p_state_timer, &bcancelled ); + + // Commented by Albert 20100911 + // Todo: Need to handle the case which both Intents are the same. + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + if ( ( pwdinfo->intent ) > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else if ( ( pwdinfo->intent ) < ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + // Have to compare the Tie Breaker + if ( pwdinfo->peer_intent & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(pwdinfo->padapter , _FW_LINKED ) ) + { + // Switch back to the AP channel soon. + _set_timer( &pwdinfo->ap_p2p_switch_timer, 100 ); + } +#endif + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + } + + // Try to get the group id information + attr_contentlen = 0; + _rtw_memset( groupid, 0x00, 38 ); + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) ) + { + DBG_871X( "[%s] Ssid = %s, ssidlen = %d\n", __FUNCTION__, &groupid[ETH_ALEN], (u32)strlen(&groupid[ETH_ALEN]) ); + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN ); + } + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] ); + pwdinfo->peer_operating_ch = operatingch_info[4]; + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + return( result ); +} + +u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *frame_body; + u8 dialogToken=0; + u8 status = P2P_STATUS_SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + dialogToken = frame_body[6]; + + //todo: check NoA attribute + + issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); + + return _TRUE; +} + +void find_phase_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + NDIS_802_11_SSID ssid; + _irqL irqL; + u8 _status = 0; + +_func_enter_; + + _rtw_memset((unsigned char*)&ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ); + ssid.SsidLength = P2P_WILDCARD_SSID_LEN; + + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _status = rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + +_func_exit_; +} + +void p2p_concurrent_handler( _adapter* padapter ); + +void restore_p2p_state_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + } + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP)) + { + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + } +#endif + + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) + { +#ifdef CONFIG_CONCURRENT_MODE + p2p_concurrent_handler( padapter ); +#else + // In the P2P client mode, the driver should not switch back to its listen channel + // because this P2P client should stay at the operating channel of P2P GO. + set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); +#endif + } +_func_exit_; +} + +void pre_tx_invitereq_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +void pre_tx_provdisc_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +void pre_tx_negoreq_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +#ifdef CONFIG_CONCURRENT_MODE +void p2p_concurrent_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + //_adapter *pbuddy_adapter = padapter->pbuddy_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; + u8 val8; +_func_enter_; + + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel; + + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel); + + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + else if( pwdinfo->driver_interface == DRIVER_WEXT ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + // Now, the driver stays on the AP's channel. + // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. + if ( pwdinfo->ext_listen_period > 0 ) + { + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period ); + + if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) + { + // Will switch to listen channel so that need to send the NULL data with PW bit to AP. + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + 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 ); + } + } + else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || + ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) ) + { + // Now, the driver is in the listen state of P2P mode. + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval ); + + // Commented by Albert 2012/11/01 + // If the AP's channel is the same as the listen channel, we should still be in the listen state + // Other P2P device is still able to find this device out even this device is in the AP's channel. + // So, configure this device to be able to receive the probe request frame and set it to listen state. + 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)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + + // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) + { + // The driver had finished the P2P handshake successfully. + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE) + { + /* + val8 = 1; + set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + */ + } + } + } + else + { + set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + +_func_exit_; +} +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +static void ro_ch_handler(_adapter *padapter) +{ + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ch, bw, offset; +_func_enter_; + + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + if (0) + DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->listen_channel) { + ch = pwdinfo->listen_channel; + bw = HT_CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else { + ch = pcfg80211_wdinfo->restore_channel; + bw = HT_CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + + set_channel_bwmode(padapter, ch, offset, bw); + + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + + pcfg80211_wdinfo->is_ro_ch = _FALSE; + + DBG_871X("cfg80211_remain_on_channel_expired\n"); + + rtw_cfg80211_remain_on_channel_expired(padapter, + pcfg80211_wdinfo->remain_on_ch_cookie, + &pcfg80211_wdinfo->remain_on_ch_channel, + pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL); + +_func_exit_; +} + +static void ro_ch_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev); + + //printk("%s \n", __FUNCTION__); + +#ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); +#endif + + p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK); +} + +static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while ( p2p_ie ) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) + { + *(pattr+4) = ch; + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +} + +static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; ipbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; ipbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) { + if (*(pattr+4) == buddy_ch) { + DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch); + fit = _TRUE; + break; + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +#endif + return fit; +} + +static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len) +{ +#ifdef CONFIG_CONCURRENT_MODE + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while ( p2p_ie ) + { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) + { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while(attr_contentlen>0) + { + num_of_ch = *(pattr_temp+1); + + for(i=0; icur_channel;//forcing to the same channel + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + } + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) + { + *(pattr+4) = pbuddy_mlmeext->cur_channel;//forcing to the same channel + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + +#endif +} + +#ifdef CONFIG_WFD +void rtw_append_wfd_ie(_adapter *padapter, u8 *buf, u32* len) +{ + unsigned char *frame_body; + u8 category, action, OUI_Subtype, dialogToken=0; + u32 wfdielen = 0; + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + + frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); + category = frame_body[0]; + + if(category == RTW_WLAN_CATEGORY_PUBLIC) + { + action = frame_body[1]; + if (action == ACT_PUBLIC_VENDOR + && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE + ) + { + OUI_Subtype = frame_body[6]; + dialogToken = frame_body[7]; + switch( OUI_Subtype )//OUI Subtype + { + case P2P_GO_NEGO_REQ: + { + wfdielen = build_nego_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_GO_NEGO_RESP: + { + wfdielen = build_nego_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_GO_NEGO_CONF: + { + wfdielen = build_nego_confirm_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_INVIT_REQ: + { + wfdielen = build_invitation_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_INVIT_RESP: + { + wfdielen = build_invitation_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_DEVDISC_REQ: + break; + case P2P_DEVDISC_RESP: + + break; + case P2P_PROVISION_DISC_REQ: + { + wfdielen = build_provdisc_req_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + case P2P_PROVISION_DISC_RESP: + { + wfdielen = build_provdisc_resp_wfd_ie( &padapter->wdinfo, buf + ( *len ) ); + (*len) += wfdielen; + break; + } + default: + + break; + } + + } + + } + else if(category == RTW_WLAN_CATEGORY_P2P) + { + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n", + cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken); +#endif + + switch(OUI_Subtype) + { + case P2P_NOTICE_OF_ABSENCE: + + break; + case P2P_PRESENCE_REQUEST: + + break; + case P2P_PRESENCE_RESPONSE: + + break; + case P2P_GO_DISC_REQUEST: + + break; + default: + + break; + } + + } + else + { + DBG_871X("%s, action frame category=%d\n", __func__, category); + //is_p2p_frame = (-1); + } + + return; +} +#endif + +u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len) +{ + uint attr_contentlen = 0; + u8 *pattr = NULL; + int w_sz = 0; + u8 ch_cnt = 0; + u8 ch_list[40]; + bool continuous = _FALSE; + + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) { + int i, j; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + _rtw_memset(ch_list, 0, 40); + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; i=ch_cnt) + ch_list[ch_cnt++] = *(pattr_temp+2+i); + + } + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + + for (j=0;j>1 == resp >>1) + return req&0x01 ? _TRUE : _FALSE; + else if (req>>1 > resp>>1) + return _TRUE; + else + return _FALSE; +} + +int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) +{ + int is_p2p_frame = (-1); + unsigned char *frame_body; + u8 category, action, OUI_Subtype, dialogToken=0; + u8 *p2p_ie = NULL; + uint p2p_ielen = 0; + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + int status = -1; + u8 ch_list_buf[128] = {'\0'}; + int op_ch = -1; + int listen_ch = -1; + u8 intent = 0; + + frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); + category = frame_body[0]; + //just for check + if(category == RTW_WLAN_CATEGORY_PUBLIC) + { + action = frame_body[1]; + if (action == ACT_PUBLIC_VENDOR + && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE + ) + { + OUI_Subtype = frame_body[6]; + dialogToken = frame_body[7]; + is_p2p_frame = OUI_Subtype; + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_PUBLIC: ACT_PUBLIC_VENDOR, OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n", + cpu_to_be32( *( ( u32* ) ( frame_body + 2 ) ) ), OUI_Subtype, dialogToken); + #endif + + p2p_ie = rtw_get_p2p_ie( + (u8 *)buf+sizeof(struct rtw_ieee80211_hdr_3addr)+_PUBLIC_ACTION_IE_OFFSET_, + len-sizeof(struct rtw_ieee80211_hdr_3addr)-_PUBLIC_ACTION_IE_OFFSET_, + NULL, &p2p_ielen); + + switch( OUI_Subtype )//OUI Subtype + { + u8 *cont; + uint cont_len; + case P2P_GO_NEGO_REQ: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + + if (tx) { + #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 + if(pwdev_priv->provdisc_req_issued == _FALSE) { + rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len); + pwdev_priv->provdisc_req_issued = _TRUE; + rtw_msleep_os(200); + } + #endif //CONFIG_DRV_ISSUE_PROV_REQ + + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, NULL, &cont_len))) + listen_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + + if (nego_info->token != dialogToken) + rtw_wdev_nego_info_init(nego_info); + + _rtw_memcpy(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + nego_info->active = tx ? 1 : 0; + nego_info->token = dialogToken; + nego_info->req_op_ch = op_ch; + nego_info->req_listen_ch = listen_ch; + nego_info->req_intent = intent; + nego_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, listen_ch:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", listen_ch, op_ch, ch_list_buf); + + if (!tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + + break; + } + case P2P_GO_NEGO_RESP: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 0 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->rsp_op_ch= op_ch; + nego_info->rsp_intent = intent; + nego_info->state = 1; + if (status != 0) + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf); + + if (!tx) { + pwdev_priv->provdisc_req_issued = _FALSE; + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + + break; + } + case P2P_GO_NEGO_CONF: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + bool is_go = _FALSE; + + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 1 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->conf_op_ch = (op_ch==-1) ? 0 : op_ch; + nego_info->state = 2; + + if (status == 0) { + if (rtw_p2p_nego_intent_compare(nego_info->req_intent, nego_info->rsp_intent) && tx) + is_go = _TRUE; + } + + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { + } + + break; + } + case P2P_INVIT_REQ: + { + struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; + int flags = -1; + + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, NULL, &cont_len))) + flags = *cont; + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + + if (invit_info->token != dialogToken) + rtw_wdev_invit_info_init(invit_info); + + _rtw_memcpy(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + invit_info->active = tx ? 1 : 0; + invit_info->token = dialogToken; + invit_info->flags = (flags==-1) ? 0x0 : flags; + invit_info->req_op_ch= op_ch; + invit_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf); + + if (!tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) { + if (op_ch != -1 && rtw_chk_p2pie_op_ch_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" op_ch:%u has no intersect with buddy\n", FUNC_ADPT_ARG(padapter), op_ch); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } else if (rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + } + #endif + } + + break; + } + case P2P_INVIT_RESP: + { + struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; + + if (tx) { + #ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED)) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + { +#ifdef CONFIG_P2P_INVITE_IOT + if(tx && *cont==7) + { + DBG_871X("TX_P2P_INVITE_RESP, status is no common channel, change to unknown group\n"); + *cont = 8; //unknow group status + } +#endif //CONFIG_P2P_INVITE_IOT + status = *cont; + } + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + + if (invit_info->token == dialogToken && invit_info->state == 0 + && _rtw_memcmp(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + invit_info->status = (status==-1) ? 0xff : status; + invit_info->rsp_op_ch= op_ch; + invit_info->state = 1; + invit_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { + } + + break; + } + case P2P_DEVDISC_REQ: + DBG_871X("RTW_%s:P2P_DEVDISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + break; + case P2P_DEVDISC_RESP: + cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len); + DBG_871X("RTW_%s:P2P_DEVDISC_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1); + break; + case P2P_PROVISION_DISC_REQ: + { + size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr); + u8 *p2p_ie; + uint p2p_ielen = 0; + uint contentlen = 0; + + DBG_871X("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + + //if(tx) + { + pwdev_priv->provdisc_req_issued = _FALSE; + + if( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen))) + { + + if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, NULL, &contentlen)) + { + pwdev_priv->provdisc_req_issued = _FALSE;//case: p2p_client join p2p GO + } + else + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("provdisc_req_issued is _TRUE\n"); + #endif //CONFIG_DEBUG_CFG80211 + pwdev_priv->provdisc_req_issued = _TRUE;//case: p2p_devices connection before Nego req. + } + + } + } + } + break; + case P2P_PROVISION_DISC_RESP: + DBG_871X("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + break; + default: + DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", OUI_Subtype, dialogToken); + break; + } + + } + + } + else if(category == RTW_WLAN_CATEGORY_P2P) + { + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n", + cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken); + #endif + + is_p2p_frame = OUI_Subtype; + + switch(OUI_Subtype) + { + case P2P_NOTICE_OF_ABSENCE: + DBG_871X("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_PRESENCE_REQUEST: + DBG_871X("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_PRESENCE_RESPONSE: + DBG_871X("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_GO_DISC_REQUEST: + DBG_871X("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + default: + DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", OUI_Subtype, dialogToken); + break; + } + + } + else + { + DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category); + } + + return is_p2p_frame; +} + +void rtw_init_cfg80211_wifidirect_info( _adapter* padapter) +{ + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info) ); + + _init_timer( &pcfg80211_wdinfo->remain_on_ch_timer, padapter->pnetdev, ro_ch_timer_process, padapter ); +} +#endif //CONFIG_IOCTL_CFG80211 + +void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType) +{ + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + +_func_enter_; + + switch(intCmdType) + { + case P2P_FIND_PHASE_WK: + { + find_phase_handler( padapter ); + break; + } + case P2P_RESTORE_STATE_WK: + { + restore_p2p_state_handler( padapter ); + break; + } + case P2P_PRE_TX_PROVDISC_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_provdisc_handler( padapter ); + } +#else + pre_tx_provdisc_handler( padapter ); +#endif + break; + } + case P2P_PRE_TX_INVITEREQ_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_invitereq_handler( padapter ); + } +#else + pre_tx_invitereq_handler( padapter ); +#endif + break; + } + case P2P_PRE_TX_NEGOREQ_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_negoreq_handler( padapter ); + } +#else + pre_tx_negoreq_handler( padapter ); +#endif + break; + } +#ifdef CONFIG_P2P +#ifdef CONFIG_CONCURRENT_MODE + case P2P_AP_P2P_CH_SWITCH_PROCESS_WK: + { + p2p_concurrent_handler( padapter ); + break; + } +#endif +#endif +#ifdef CONFIG_IOCTL_CFG80211 + case P2P_RO_CH_WK: + { + ro_ch_handler( padapter ); + break; + } +#endif //CONFIG_IOCTL_CFG80211 + + } + +_func_exit_; +} + +#ifdef CONFIG_P2P_PS +void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength) +{ + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2 + u32 attr_contentlen = 0; + + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 find_p2p = _FALSE, find_p2p_ps = _FALSE; + u8 noa_offset, noa_num, noa_index; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + return; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type != IFACE_PORT0) + return; +#endif + if(IELength <= _BEACON_IE_OFFSET_) + return; + + ies = IEs + _BEACON_IE_OFFSET_; + ies_len = IELength - _BEACON_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen); + + while(p2p_ie) + { + find_p2p = _TRUE; + // Get Notice of Absence IE. + if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) + { + find_p2p_ps = _TRUE; + noa_index = noa_attr[0]; + + if( (pwdinfo->p2p_ps_mode == P2P_PS_NONE) || + (noa_index != pwdinfo->noa_index) )// if index change, driver should reconfigure related setting. + { + pwdinfo->noa_index = noa_index; + pwdinfo->opp_ps = noa_attr[1] >> 7; + pwdinfo->ctwindow = noa_attr[1] & 0x7F; + + noa_offset = 2; + noa_num = 0; + // NoA length should be n*(13) + 2 + if(attr_contentlen > 2) + { + while(noa_offset < attr_contentlen) + { + //_rtw_memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); + pwdinfo->noa_count[noa_num] = noa_attr[noa_offset]; + noa_offset += 1; + + _rtw_memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + _rtw_memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + _rtw_memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + noa_num++; + } + } + pwdinfo->noa_num = noa_num; + + if( pwdinfo->opp_ps == 1 ) + { + pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + // driver should wait LPS for entering CTWindow + if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE) + { + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); + } + } + else if( pwdinfo->noa_num > 0 ) + { + pwdinfo->p2p_ps_mode = P2P_PS_NOA; + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); + } + else if( pwdinfo->p2p_ps_mode > P2P_PS_NONE) + { + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); + } + } + + break; // find target, just break. + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + if(find_p2p == _TRUE) + { + if( (pwdinfo->p2p_ps_mode > P2P_PS_NONE) && (find_p2p_ps == _FALSE) ) + { + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); + } + } + +_func_exit_; +} + +void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + +_func_enter_; + + switch(p2p_ps_state) + { + case P2P_PS_DISABLE: + pwdinfo->p2p_ps_state = p2p_ps_state; + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + + pwdinfo->noa_index = 0; + pwdinfo->ctwindow = 0; + pwdinfo->opp_ps = 0; + pwdinfo->noa_num = 0; + pwdinfo->p2p_ps_mode = P2P_PS_NONE; + if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE) + { + if(pwrpriv->smart_ps == 0) + { + pwrpriv->smart_ps = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode))); + } + } + break; + case P2P_PS_ENABLE: + if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { + pwdinfo->p2p_ps_state = p2p_ps_state; + + if( pwdinfo->ctwindow > 0 ) + { + if(pwrpriv->smart_ps != 0) + { + pwrpriv->smart_ps = 0; + DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode))); + } + } + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + } + break; + case P2P_PS_SCAN: + case P2P_PS_SCAN_DONE: + case P2P_PS_ALLSTASLEEP: + if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { + pwdinfo->p2p_ps_state = p2p_ps_state; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + } + break; + default: + break; + } + +_func_exit_; +} + +u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) +#ifdef CONFIG_CONCURRENT_MODE + || (padapter->iface_type != IFACE_PORT0) +#endif + ) + { + return res; + } + + if(enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID; + pdrvextra_cmd_parm->type_size = p2p_ps_state; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else + { + p2p_ps_wk_hdl(padapter, p2p_ps_state); + } + +exit: + +_func_exit_; + + return res; + +} +#endif // CONFIG_P2P_PS + +static void reset_ch_sitesurvey_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + // Reset the operation channel information + pwdinfo->rx_invitereq_info.operation_ch[0] = 0; +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[1] = 0; + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; +} + +static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + // Reset the operation channel information + pwdinfo->p2p_info.operation_ch[0] = 0; +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[1] = 0; + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 0; +} + +static void restore_p2p_state_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + p2p_protocol_wk_cmd( adapter, P2P_RESTORE_STATE_WK ); +} + +static void pre_tx_scan_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *) FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 _status = 0; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + // Commented by Albert 20110805 + // Todo: Use the issuing probe request directly instead of using the rtw_sitesurvey_cmd!! + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) // the provision discovery request frame is trigger to send or not + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK ); + //issue_probereq_p2p(adapter, NULL); + //_set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + } + else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + if ( _TRUE == pwdinfo->nego_req_info.benable ) + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK ); + //issue_probereq_p2p(adapter, NULL); + //_set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + } + else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) ) + { + if ( _TRUE == pwdinfo->invitereq_info.benable ) + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK ); + } + } + else + { + DBG_8192C( "[%s] p2p_state is %d, ignore!!\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +static void find_phase_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + adapter->wdinfo.find_phase_state_exchange_cnt++; + + p2p_protocol_wk_cmd( adapter, P2P_FIND_PHASE_WK ); +} + +#ifdef CONFIG_CONCURRENT_MODE +void ap_p2p_switch_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev); +#endif + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + +#ifdef CONFIG_IOCTL_CFG80211 + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + p2p_protocol_wk_cmd( adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK ); +} +#endif + +void reset_global_wifidirect_info( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo; + + pwdinfo = &padapter->wdinfo; + pwdinfo->persistent_supported = 0; + pwdinfo->session_available = _TRUE; + pwdinfo->wfd_tdls_enable = 0; + pwdinfo->wfd_tdls_weaksec = 0; +} + +#ifdef CONFIG_WFD +int rtw_init_wifi_display_info(_adapter* padapter) +{ + int res = _SUCCESS; + struct wifi_display_info *pwfd_info = &padapter->wfd_info; + + // Used in P2P and TDLS + pwfd_info->rtsp_ctrlport = 554; + pwfd_info->peer_rtsp_ctrlport = 0; // Reset to 0 + pwfd_info->wfd_enable = _FALSE; + pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK; + pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY; + + // Used in P2P + pwfd_info->peer_session_avail = _TRUE; + pwfd_info->wfd_pc = _FALSE; + + // Used in TDLS + _rtw_memset( pwfd_info->ip_address, 0x00, 4 ); + _rtw_memset( pwfd_info->peer_ip_address, 0x00, 4 ); + return res; + +} +#endif //CONFIG_WFD + +void rtw_init_wifidirect_timers(_adapter* padapter) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + _init_timer( &pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter ); + _init_timer( &pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter ); + _init_timer( &pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter ); + _init_timer( &pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter ); + _init_timer( &pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter ); +#ifdef CONFIG_CONCURRENT_MODE + _init_timer( &pwdinfo->ap_p2p_switch_timer, padapter->pnetdev, ap_p2p_switch_timer_process, padapter ); +#endif +} + +void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + /*init device&interface address */ + if (dev_addr) { + _rtw_memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN); + } + if (iface_addr) { + _rtw_memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN); + } +#endif +} + +void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role) +{ + struct wifidirect_info *pwdinfo; +#ifdef CONFIG_WFD + struct wifi_display_info *pwfd_info = &padapter->wfd_info; +#endif +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct wifidirect_info *pbuddy_wdinfo; + struct mlme_priv *pbuddy_mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext; +#endif + + pwdinfo = &padapter->wdinfo; + + pwdinfo->padapter = padapter; + + // 1, 6, 11 are the social channel defined in the WiFi Direct specification. + pwdinfo->social_chan[0] = 1; + pwdinfo->social_chan[1] = 6; + pwdinfo->social_chan[2] = 11; + pwdinfo->social_chan[3] = 0; // channel 0 for scanning ending in site survey function. + +#ifdef CONFIG_CONCURRENT_MODE + if (pbuddy_adapter) { + pbuddy_wdinfo = &pbuddy_adapter->wdinfo; + pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + } + + if ( ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) && + ( ( pbuddy_mlmeext->cur_channel == 1) || ( pbuddy_mlmeext->cur_channel == 6 ) || ( pbuddy_mlmeext->cur_channel == 11 ) ) + ) + { + // Use the AP's channel as the listen channel + // This will avoid the channel switch between AP's channel and listen channel. + pwdinfo->listen_channel = pbuddy_mlmeext->cur_channel; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + // Use the channel 11 as the listen channel + pwdinfo->listen_channel = 11; + } + + if (role == P2P_ROLE_DEVICE) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + #ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + } + else + #endif + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + } + pwdinfo->intent = 1; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN); + } + else if (role == P2P_ROLE_CLIENT) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 1; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + } + else if (role == P2P_ROLE_GO) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 15; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + } + +// Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) + pwdinfo->support_rate[0] = 0x8c; // 6(B) + pwdinfo->support_rate[1] = 0x92; // 9(B) + pwdinfo->support_rate[2] = 0x18; // 12 + pwdinfo->support_rate[3] = 0x24; // 18 + pwdinfo->support_rate[4] = 0x30; // 24 + pwdinfo->support_rate[5] = 0x48; // 36 + pwdinfo->support_rate[6] = 0x60; // 48 + pwdinfo->support_rate[7] = 0x6c; // 54 + + _rtw_memcpy( ( void* ) pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7 ); + + _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN ); + pwdinfo->device_name_len = 0; + + _rtw_memset( &pwdinfo->invitereq_info, 0x00, sizeof( struct tx_invite_req_info ) ); + pwdinfo->invitereq_info.token = 3; // Token used for P2P invitation request frame. + + _rtw_memset( &pwdinfo->inviteresp_info, 0x00, sizeof( struct tx_invite_resp_info ) ); + pwdinfo->inviteresp_info.token = 0; + + pwdinfo->profileindex = 0; + _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM ); + + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + + pwdinfo->listen_dwell = ( u8 ) (( rtw_get_current_time() % 3 ) + 1); + //DBG_8192C( "[%s] listen_dwell time is %d00ms\n", __FUNCTION__, pwdinfo->listen_dwell ); + + _rtw_memset( &pwdinfo->tx_prov_disc_info, 0x00, sizeof( struct tx_provdisc_req_info ) ); + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE; + + _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) ); + + pwdinfo->device_password_id_for_nego = WPS_DPID_PBC; + pwdinfo->negotiation_dialog_token = 1; + + _rtw_memset( pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN ); + pwdinfo->nego_ssidlen = 0; + + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; +#ifdef CONFIG_WFD + pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC; + pwdinfo->wfd_info = pwfd_info; +#else + pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD; +#endif //CONFIG_WFD + pwdinfo->channel_list_attr_len = 0; + _rtw_memset( pwdinfo->channel_list_attr, 0x00, 100 ); + + _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4 ); + _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3 ); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->ext_listen_interval = 1000; //The interval to be available with legacy AP during p2p0-find/scan + pwdinfo->ext_listen_period = 3000; //The time period to be available for P2P during nego +#else //!CONFIG_IOCTL_CFG80211 + //pwdinfo->ext_listen_interval = 3000; + //pwdinfo->ext_listen_period = 400; + pwdinfo->ext_listen_interval = 1000; + pwdinfo->ext_listen_period = 1000; +#endif //!CONFIG_IOCTL_CFG80211 +#endif + +// Commented by Kurt 20130319 +// For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + + pwdinfo->wfd_tdls_enable = 0; + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + _rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN ); + + pwdinfo->rx_invitereq_info.operation_ch[0] = 0; + pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; + pwdinfo->rx_invitereq_info.operation_ch[4] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; + pwdinfo->p2p_info.operation_ch[0] = 0; + pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; + pwdinfo->p2p_info.operation_ch[4] = 0; +#endif //P2P_OP_CHECK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 0; +} + +#ifdef CONFIG_DBG_P2P + +/** + * rtw_p2p_role_txt - Get the p2p role name as a text string + * @role: P2P role + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_role_txt(enum P2P_ROLE role) +{ + switch (role) { + case P2P_ROLE_DISABLE: + return "P2P_ROLE_DISABLE"; + case P2P_ROLE_DEVICE: + return "P2P_ROLE_DEVICE"; + case P2P_ROLE_CLIENT: + return "P2P_ROLE_CLIENT"; + case P2P_ROLE_GO: + return "P2P_ROLE_GO"; + default: + return "UNKNOWN"; + } +} + +/** + * rtw_p2p_state_txt - Get the p2p state name as a text string + * @state: P2P state + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_state_txt(enum P2P_STATE state) +{ + switch (state) { + case P2P_STATE_NONE: + return "P2P_STATE_NONE"; + case P2P_STATE_IDLE: + return "P2P_STATE_IDLE"; + case P2P_STATE_LISTEN: + return "P2P_STATE_LISTEN"; + case P2P_STATE_SCAN: + return "P2P_STATE_SCAN"; + case P2P_STATE_FIND_PHASE_LISTEN: + return "P2P_STATE_FIND_PHASE_LISTEN"; + case P2P_STATE_FIND_PHASE_SEARCH: + return "P2P_STATE_FIND_PHASE_SEARCH"; + case P2P_STATE_TX_PROVISION_DIS_REQ: + return "P2P_STATE_TX_PROVISION_DIS_REQ"; + case P2P_STATE_RX_PROVISION_DIS_RSP: + return "P2P_STATE_RX_PROVISION_DIS_RSP"; + case P2P_STATE_RX_PROVISION_DIS_REQ: + return "P2P_STATE_RX_PROVISION_DIS_REQ"; + case P2P_STATE_GONEGO_ING: + return "P2P_STATE_GONEGO_ING"; + case P2P_STATE_GONEGO_OK: + return "P2P_STATE_GONEGO_OK"; + case P2P_STATE_GONEGO_FAIL: + return "P2P_STATE_GONEGO_FAIL"; + case P2P_STATE_RECV_INVITE_REQ_MATCH: + return "P2P_STATE_RECV_INVITE_REQ_MATCH"; + case P2P_STATE_PROVISIONING_ING: + return "P2P_STATE_PROVISIONING_ING"; + case P2P_STATE_PROVISIONING_DONE: + return "P2P_STATE_PROVISIONING_DONE"; + case P2P_STATE_TX_INVITE_REQ: + return "P2P_STATE_TX_INVITE_REQ"; + case P2P_STATE_RX_INVITE_RESP_OK: + return "P2P_STATE_RX_INVITE_RESP_OK"; + case P2P_STATE_RECV_INVITE_REQ_DISMATCH: + return "P2P_STATE_RECV_INVITE_REQ_DISMATCH"; + case P2P_STATE_RECV_INVITE_REQ_GO: + return "P2P_STATE_RECV_INVITE_REQ_GO"; + case P2P_STATE_RECV_INVITE_REQ_JOIN: + return "P2P_STATE_RECV_INVITE_REQ_JOIN"; + case P2P_STATE_RX_INVITE_RESP_FAIL: + return "P2P_STATE_RX_INVITE_RESP_FAIL"; + case P2P_STATE_RX_INFOR_NOREADY: + return "P2P_STATE_RX_INFOR_NOREADY"; + case P2P_STATE_TX_INFOR_NOREADY: + return "P2P_STATE_TX_INFOR_NOREADY"; + default: + return "UNKNOWN"; + } +} + +void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line) +{ + if(!_rtw_p2p_chk_state(wdinfo, state)) { + enum P2P_STATE old_state = _rtw_p2p_state(wdinfo); + _rtw_p2p_set_state(wdinfo, state); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line + , rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) + ); + } +} +void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line) +{ + if(_rtw_p2p_pre_state(wdinfo) != state) { + enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo); + _rtw_p2p_set_pre_state(wdinfo, state); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line + , rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) + ); + } +} +#if 0 +void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line) +{ + if(wdinfo->pre_p2p_state != -1) { + DBG_871X("[CONFIG_DBG_P2P]%s:%d restore from %s to %s\n", caller, line + , p2p_state_str[wdinfo->p2p_state], p2p_state_str[wdinfo->pre_p2p_state] + ); + _rtw_p2p_restore_state(wdinfo); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d restore no pre state, cur state %s\n", caller, line + , p2p_state_str[wdinfo->p2p_state] + ); + } +} +#endif +void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line) +{ + if(wdinfo->role != role) { + enum P2P_ROLE old_role = wdinfo->role; + _rtw_p2p_set_role(wdinfo, role); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line + , rtw_p2p_role_txt(old_role), rtw_p2p_role_txt(wdinfo->role) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line + , rtw_p2p_role_txt(wdinfo->role) + ); + } +} +#endif //CONFIG_DBG_P2P + + +int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) +{ + int ret = _SUCCESS; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + + if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO) + { + u8 channel, ch_offset; + u16 bwmode; + +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo; + // Commented by Albert 2011/12/30 + // The driver just supports 1 P2P group operation. + // So, this function will do nothing if the buddy adapter had enabled the P2P function. + if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) + { + // The buddy adapter had enabled the P2P function. + return ret; + } +#endif //CONFIG_CONCURRENT_MODE + + //leave IPS/Autosuspend + if (_FAIL == rtw_pwr_wakeup(padapter)) { + ret = _FAIL; + goto exit; + } + + + // Added by Albert 2011/03/22 + // In the P2P mode, the driver should not support the b mode. + // So, the Tx packet shouldn't use the CCK rate + update_tx_basic_rate(padapter, WIRELESS_11AGN); + + //Enable P2P function + init_wifidirect_info(padapter, role); + } + else if (role == P2P_ROLE_DISABLE) + { +#ifdef CONFIG_INTEL_WIDI + if( padapter->mlmepriv.p2p_reject_disable == _TRUE ) + return ret; +#endif //CONFIG_INTEL_WIDI + + if (_FAIL == rtw_pwr_wakeup(padapter)) { + ret = _FAIL; + goto exit; + } + + //Disable P2P function + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey); + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey2); + reset_ch_sitesurvey_timer_process( padapter ); + reset_ch_sitesurvey_timer_process2( padapter ); + #ifdef CONFIG_CONCURRENT_MODE + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer); + #endif + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE); + _rtw_memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info)); + } + + //Restore to initial setting. + update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); + +#ifdef CONFIG_INTEL_WIDI + rtw_reset_widi_info(padapter); +#endif //CONFIG_INTEL_WIDI + + //For WiDi purpose. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + + } + +exit: + return ret; +} + +#endif //CONFIG_P2P + diff --git a/rtl8192cu-fixes/core/rtw_pwrctrl.c b/rtl8192cu-fixes/core/rtw_pwrctrl.c new file mode 100755 index 00000000..d1c11fa6 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_pwrctrl.c @@ -0,0 +1,1540 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_PWRCTRL_C_ + +#include +#include +#include +#include + + +#ifdef CONFIG_IPS +void _ips_enter(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + + pwrpriv->bips_processing = _TRUE; + + // syn ips_mode with request + pwrpriv->ips_mode = pwrpriv->ips_mode_req; + + pwrpriv->ips_enter_cnts++; + DBG_871X("==>ips_enter cnts:%d\n",pwrpriv->ips_enter_cnts); + + if(rf_off == pwrpriv->change_rfpwrstate) + { + if(pwrpriv->ips_mode == IPS_LEVEL_2) + pwrpriv->bkeepfwalive = _TRUE; + + rtw_ips_pwr_down(padapter); + pwrpriv->rf_pwrstate = rf_off; + } + pwrpriv->bips_processing = _FALSE; + +} + +void ips_enter(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrpriv->lock); + _ips_enter(padapter); + _exit_pwrlock(&pwrpriv->lock); +} + +int _ips_leave(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + int result = _SUCCESS; + + if((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing)) + { + pwrpriv->bips_processing = _TRUE; + pwrpriv->change_rfpwrstate = rf_on; + pwrpriv->ips_leave_cnts++; + DBG_871X("==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts); + + if ((result = rtw_ips_pwr_up(padapter)) == _SUCCESS) { + pwrpriv->rf_pwrstate = rf_on; + } + + DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtw_read32(padapter,0x4c)); + pwrpriv->bips_processing = _FALSE; + + pwrpriv->bkeepfwalive = _FALSE; + } + + return result; +} + +int ips_leave(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + int ret; + + _enter_pwrlock(&pwrpriv->lock); + ret = _ips_leave(padapter); + _exit_pwrlock(&pwrpriv->lock); + + return ret; +} +#endif /* CONFIG_IPS */ + +#ifdef CONFIG_AUTOSUSPEND +extern void autosuspend_enter(_adapter* padapter); +extern int autoresume_enter(_adapter* padapter); +#endif + +#ifdef SUPPORT_HW_RFOFF_DETECTED +int rtw_hw_suspend(_adapter *padapter ); +int rtw_hw_resume(_adapter *padapter); +#endif + +bool rtw_pwr_unassociated_idle(_adapter *adapter) +{ + _adapter *buddy = adapter->pbuddy_adapter; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(adapter->wdinfo); +#ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &adapter->cfg80211_wdinfo; +#endif +#endif + + bool ret = _FALSE; + + if (adapter->pwrctrlpriv.ips_deny_time >= rtw_get_current_time()) { + //DBG_871X("%s ips_deny_time\n", __func__); + goto exit; + } + + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) + || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(pmlmepriv, WIFI_AP_STATE) + || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P_IPS) + || pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) + #endif + ) { + goto exit; + } + + /* consider buddy, if exist */ + if (buddy) { + struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv); + #ifdef CONFIG_P2P + struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo); + #ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *b_pcfg80211_wdinfo = &buddy->cfg80211_wdinfo; + #endif + #endif + + if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) + || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(b_pmlmepriv, WIFI_AP_STATE) + || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P_IPS) + || b_pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE) + #endif + ) { + goto exit; + } + } + +#ifdef CONFIG_INTEL_PROXIM + if(adapter->proximity.proxim_on==_TRUE){ + return; + } +#endif + + ret = _TRUE; + +exit: + return ret; +} + +#if defined (PLATFORM_LINUX)||defined (PLATFORM_FREEBSD) +void rtw_ps_processor(_adapter*padapter) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); +#endif //CONFIG_P2P + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +#ifdef SUPPORT_HW_RFOFF_DETECTED + rt_rf_power_state rfpwrstate; +#endif //SUPPORT_HW_RFOFF_DETECTED + + pwrpriv->ps_processing = _TRUE; + +#ifdef SUPPORT_HW_RFOFF_DETECTED + if(pwrpriv->bips_processing == _TRUE) + goto exit; + + //DBG_871X("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca)); + if(padapter->pwrctrlpriv.bHWPwrPindetect) + { + #ifdef CONFIG_AUTOSUSPEND + if(padapter->registrypriv.usbss_enable) + { + if(pwrpriv->rf_pwrstate == rf_on) + { + if(padapter->net_closed == _TRUE) + pwrpriv->ps_flag = _TRUE; + + rfpwrstate = RfOnOffDetect(padapter); + DBG_871X("@@@@- #1 %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off"); + if(rfpwrstate!= pwrpriv->rf_pwrstate) + { + if(rfpwrstate == rf_off) + { + pwrpriv->change_rfpwrstate = rf_off; + + pwrpriv->bkeepfwalive = _TRUE; + pwrpriv->brfoffbyhw = _TRUE; + + autosuspend_enter(padapter); + } + } + } + } + else + #endif //CONFIG_AUTOSUSPEND + { + rfpwrstate = RfOnOffDetect(padapter); + DBG_871X("@@@@- #2 %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off"); + + if(rfpwrstate!= pwrpriv->rf_pwrstate) + { + if(rfpwrstate == rf_off) + { + pwrpriv->change_rfpwrstate = rf_off; + pwrpriv->brfoffbyhw = _TRUE; + padapter->bCardDisableWOHSM = _TRUE; + rtw_hw_suspend(padapter ); + } + else + { + pwrpriv->change_rfpwrstate = rf_on; + rtw_hw_resume(padapter ); + } + DBG_871X("current rf_pwrstate(%s)\n",(pwrpriv->rf_pwrstate == rf_off)?"rf_off":"rf_on"); + } + } + pwrpriv->pwr_state_check_cnts ++; + } +#endif //SUPPORT_HW_RFOFF_DETECTED + + if (pwrpriv->ips_mode_req == IPS_NONE + #ifdef CONFIG_CONCURRENT_MODE + || padapter->pbuddy_adapter->pwrctrlpriv.ips_mode_req == IPS_NONE + #endif + ) + goto exit; + + if (rtw_pwr_unassociated_idle(padapter) == _FALSE) + goto exit; + + if((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4)==0)) + { + DBG_871X("==>%s .fw_state(%x)\n",__FUNCTION__,get_fwstate(pmlmepriv)); + pwrpriv->change_rfpwrstate = rf_off; + + #ifdef CONFIG_AUTOSUSPEND + if(padapter->registrypriv.usbss_enable) + { + if(pwrpriv->bHWPwrPindetect) + pwrpriv->bkeepfwalive = _TRUE; + + if(padapter->net_closed == _TRUE) + pwrpriv->ps_flag = _TRUE; + + padapter->bCardDisableWOHSM = _TRUE; + autosuspend_enter(padapter); + } + else if(pwrpriv->bHWPwrPindetect) + { + } + else + #endif //CONFIG_AUTOSUSPEND + { + #ifdef CONFIG_IPS + ips_enter(padapter); + #endif + } + } +exit: + rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); + pwrpriv->ps_processing = _FALSE; + return; +} + +void pwr_state_check_handler(void *FunctionContext); +void pwr_state_check_handler(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + rtw_ps_cmd(padapter); +} +#endif + + +#ifdef CONFIG_LPS +/* + * + * Parameters + * padapter + * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 + * + */ +void rtw_set_rpwm(PADAPTER padapter, u8 pslv) +{ + u8 rpwm; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + +_func_enter_; + + pslv = PS_STATE(pslv); + + if (pwrpriv->rpwm == pslv) { + RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_, + ("%s: Already set rpwm[0x%02x]!\n", __FUNCTION__, pslv)); + return; + } + + if ((padapter->bDriverStopped == _TRUE) || + (padapter->bSurpriseRemoved == _TRUE)) { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n", + __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved)); + return; + } + + rpwm = pslv | pwrpriv->tog; +#ifdef CONFIG_LPS_LCLK + if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2)) + rpwm |= PS_ACK; +#endif + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm)); + + pwrpriv->rpwm = pslv; + + rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); + + pwrpriv->tog += 0x80; + + if (!(rpwm & PS_ACK)) pwrpriv->cpwm = pslv; + +_func_exit_; +} + +u8 PS_RDY_CHECK(_adapter * padapter); +u8 PS_RDY_CHECK(_adapter * padapter) +{ + u32 curr_time, delta_time; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + curr_time = rtw_get_current_time(); + + delta_time = curr_time -pwrpriv->DelayLPSLastTimeStamp; + + if(delta_time < LPS_DELAY_TIME) + { + return _FALSE; + } + + if ((check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) || + (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_UNDER_WPS) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ) + return _FALSE; + + if(_TRUE == pwrpriv->bInSuspend ) + return _FALSE; + + if( (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == _FALSE) ) + { + DBG_871X("Group handshake still in progress !!!\n"); + return _FALSE; + } + +#ifdef CONFIG_IOCTL_CFG80211 + if (!rtw_cfg80211_pwr_mgmt(padapter)) + return _FALSE; +#endif + + return _TRUE; +} + +void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); +#endif //CONFIG_P2P +#ifdef CONFIG_TDLS + struct sta_priv *pstapriv = &padapter->stapriv; + _irqL irqL; + int i, j; + _list *plist, *phead; + struct sta_info *ptdls_sta; +#endif //CONFIG_TDLS + +_func_enter_; + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("%s: PowerMode=%d Smart_PS=%d\n", + __FUNCTION__, ps_mode, smart_ps)); + + if(ps_mode > PM_Card_Disable) { + RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode)); + return; + } + + if((pwrpriv->pwr_mode == ps_mode) && + (pwrpriv->smart_ps == smart_ps)){ + return; + } + + //if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + if(ps_mode == PS_MODE_ACTIVE) + { +#ifdef CONFIG_P2P_PS + if(pwdinfo->opp_ps == 0) +#endif // CONFIG_P2P_PS + { +#ifdef CONFIG_LPS_LCLK + _enter_pwrlock(&pwrpriv->lock); +#endif + DBG_871X("rtw_set_ps_mode(): Busy Traffic , Leave 802.11 power save..\n"); + +#ifdef CONFIG_TDLS + _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) + { + ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE ) + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0); + plist = get_next(plist); + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); +#endif //CONFIG_TDLS + + pwrpriv->smart_ps = smart_ps; + pwrpriv->pwr_mode = ps_mode; + + rtw_set_rpwm(padapter, PS_STATE_S4); +#ifdef CONFIG_LPS_LCLK +{ + u32 n = 0; + while (pwrpriv->cpwm != PS_STATE_S4) { + n++; + if (n == 10000) break; + if (padapter->bSurpriseRemoved == _TRUE) break; + rtw_msleep_os(1); + } + if (n == 10000) + printk(KERN_ERR "%s: wait CPWM to S4 too long! cpwm=0x%02x\n", __func__, pwrpriv->cpwm); +} +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + pwrpriv->bFwCurrentInPSMode = _FALSE; +#ifdef CONFIG_LPS_LCLK + _exit_pwrlock(&pwrpriv->lock); +#endif + } + } + else + { + if(PS_RDY_CHECK(padapter)) + { +#ifdef CONFIG_LPS_LCLK + _enter_pwrlock(&pwrpriv->lock); +#endif + DBG_871X("rtw_set_ps_mode(): Enter 802.11 power save mode...\n"); + +#ifdef CONFIG_TDLS + _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) + { + ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE ) + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 1); + plist = get_next(plist); + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); +#endif //CONFIG_TDLS + + pwrpriv->smart_ps = smart_ps; + pwrpriv->pwr_mode = ps_mode; + pwrpriv->bFwCurrentInPSMode = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); +#ifdef CONFIG_P2P_PS + // Set CTWindow after LPS + if(pwdinfo->opp_ps == 1) + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0); +#endif // CONFIG_P2P_PS +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->alives == 0) + rtw_set_rpwm(padapter, PS_STATE_S0); +#else + rtw_set_rpwm(padapter, PS_STATE_S2); +#endif +#ifdef CONFIG_LPS_LCLK + _exit_pwrlock(&pwrpriv->lock); +#endif + } + //else + //{ + // pwrpriv->pwr_mode = PS_MODE_ACTIVE; + //} + } + +_func_exit_; +} + + +// +// Description: +// Enter the leisure power save mode. +// +void LPS_Enter(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _adapter *buddy = padapter->pbuddy_adapter; + +_func_enter_; + +// DBG_871X("+LeisurePSEnter\n"); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type != IFACE_PORT0) + return; /* Skip power saving for concurrent mode port 1*/ + + /* consider buddy, if exist */ + if (buddy) { + struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv); + #ifdef CONFIG_P2P + struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo); + #ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *b_pcfg80211_wdinfo = &buddy->cfg80211_wdinfo; + #endif + #endif + + if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) + || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(b_pmlmepriv, WIFI_AP_STATE) + || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_P2P_IPS) + || b_pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE) + #endif + || rtw_is_scan_deny(buddy) + ) { + return; + } + } +#endif + +#ifdef CONFIG_INTEL_PROXIM + if(padapter->proximity.proxim_on==_TRUE){ + return; + } +#endif + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) || + (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ) + return; + + if(_TRUE == pwrpriv->bInSuspend ) + return ; + + if (pwrpriv->bLeisurePs) + { + // Idle for a while if we connect to AP a while ago. + if(pwrpriv->LpsIdleCount >= 2) // 4 Sec + { + if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + { + rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, 2); + } + } + else + pwrpriv->LpsIdleCount++; + } + +// DBG_871X("-LeisurePSEnter\n"); + +_func_exit_; +} + + +// +// Description: +// Leave the leisure power save mode. +// +void LPS_Leave(PADAPTER padapter) +{ +#define LPS_LEAVE_TIMEOUT_MS 100 + + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + u32 start_time; + BOOLEAN bAwake = _FALSE; + +_func_enter_; + +// DBG_871X("+LeisurePSLeave\n"); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type != IFACE_PORT0) + return; /* Skip power saving for concurrent mode port 1*/ +#endif + + if (pwrpriv->bLeisurePs) + { + if(pwrpriv->pwr_mode != PS_MODE_ACTIVE) + { + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0); + + if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + { + start_time = rtw_get_current_time(); + while(1) + { + rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bAwake)); + + if(bAwake || padapter->bSurpriseRemoved) + break; + + if(rtw_get_passing_time_ms(start_time)>LPS_LEAVE_TIMEOUT_MS) + { + DBG_871X("Wait for FW LPS leave more than %u ms!!!\n", LPS_LEAVE_TIMEOUT_MS); + break; + } + rtw_usleep_os(100); + } + } + } + } + + +// DBG_871X("-LeisurePSLeave\n"); + +_func_exit_; +} + +#endif + +// +// Description: Leave all power save mode: LPS, FwLPS, IPS if needed. +// Move code to function by tynli. 2010.03.26. +// +void LeaveAllPowerSaveMode(IN PADAPTER Adapter) +{ + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + +_func_enter_; + + //DBG_871X("%s.....\n",__FUNCTION__); + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { //connect +#ifdef CONFIG_P2P_PS + p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, 0); +#endif // CONFIG_P2P_PS +#ifdef CONFIG_LPS + //DBG_871X("==> leave LPS.......\n"); + LPS_Leave(Adapter); +#endif + } + else + { + if(Adapter->pwrctrlpriv.rf_pwrstate== rf_off) + { + #ifdef CONFIG_AUTOSUSPEND + if(Adapter->registrypriv.usbss_enable) + { + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev); + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;//autosuspend disabled by the user + #endif + } + else + #endif + { + /* + #ifdef CONFIG_IPS + if(_FALSE == ips_leave(Adapter)) + { + DBG_871X("======> ips_leave fail.............\n"); + } + #endif + */ + } + } + } + +_func_exit_; +} + +#ifdef CONFIG_LPS_LCLK +/* + * Caller:ISR handler... + * + * This will be called when CPWM interrupt is up. + * + * using to update cpwn of drv; and drv willl make a decision to up or down pwr level + */ +void cpwm_int_hdl( + PADAPTER padapter, + struct reportpwrstate_parm *preportpwrstate) +{ + struct pwrctrl_priv *pwrpriv; + + +_func_enter_; + + pwrpriv = &padapter->pwrctrlpriv; +#if 0 + if (pwrpriv->cpwm_tog == (preportpwrstate->state & PS_TOGGLE)) { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("cpwm_int_hdl: tog(old)=0x%02x cpwm(new)=0x%02x toggle bit didn't change!?\n", + pwrpriv->cpwm_tog, preportpwrstate->state)); + goto exit; + } +#endif +// _enter_pwrlock(&pwrpriv->lock); + + pwrpriv->cpwm = PS_STATE(preportpwrstate->state); + pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE; + + if (pwrpriv->cpwm >= PS_STATE_S2) { + if (pwrpriv->alives & CMD_ALIVE) + _rtw_up_sema(&padapter->cmdpriv.cmd_queue_sema); + + if (pwrpriv->alives & XMIT_ALIVE) + _rtw_up_sema(&padapter->xmitpriv.xmit_sema); + } + +// _exit_pwrlock(&pwrpriv->lock); + +exit: + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("cpwm_int_hdl: cpwm=0x%02x\n", pwrpriv->cpwm)); + +_func_exit_; +} + +__inline static void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +{ + pwrctrl->alives |= tag; +} + +__inline static void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +{ + pwrctrl->alives &= ~tag; +} + +/* + * Caller: rtw_xmit_thread + * + * Check if the fw_pwrstate is okay for xmit. + * If not (cpwm is less than S3), then the sub-routine + * will raise the cpwm to be greater than or equal to S3. + * + * Calling Context: Passive + * + * Return Value: + * _SUCCESS rtw_xmit_thread can write fifo/txcmd afterwards. + * _FAIL rtw_xmit_thread can not do anything. + */ +s32 rtw_register_tx_alive(PADAPTER padapter) +{ + s32 res; + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + res = _SUCCESS; + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, XMIT_ALIVE); + + if (pwrctrl->bFwCurrentInPSMode == _TRUE) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("rtw_register_tx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm < PS_STATE_S2) { + if (pwrctrl->rpwm < PS_STATE_S2) + rtw_set_rpwm(padapter, PS_STATE_S2); + res = _FAIL; + } + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return res; +} + +/* + * Caller: rtw_cmd_thread + * + * Check if the fw_pwrstate is okay for issuing cmd. + * If not (cpwm should be is less than S2), then the sub-routine + * will raise the cpwm to be greater than or equal to S2. + * + * Calling Context: Passive + * + * Return Value: + * _SUCCESS rtw_cmd_thread can issue cmds to firmware afterwards. + * _FAIL rtw_cmd_thread can not do anything. + */ +s32 rtw_register_cmd_alive(PADAPTER padapter) +{ + s32 res; + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + res = _SUCCESS; + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, CMD_ALIVE); + + if (pwrctrl->bFwCurrentInPSMode == _TRUE) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_cmd_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm < PS_STATE_S2) { + if (pwrctrl->rpwm < PS_STATE_S2) + rtw_set_rpwm(padapter, PS_STATE_S2); + res = _FAIL; + } + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return res; +} + +/* + * Caller: rx_isr + * + * Calling Context: Dispatch/ISR + * + * Return Value: + * _SUCCESS + * _FAIL + */ +s32 rtw_register_rx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, RECV_ALIVE); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_rx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return _SUCCESS; +} + +/* + * Caller: evt_isr or evt_thread + * + * Calling Context: Dispatch/ISR or Passive + * + * Return Value: + * _SUCCESS + * _FAIL + */ +s32 rtw_register_evt_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, EVT_ALIVE); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_evt_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return _SUCCESS; +} + +/* + * Caller: ISR + * + * If ISR's txdone, + * No more pkts for TX, + * Then driver shall call this fun. to power down firmware again. + */ +void rtw_unregister_tx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, XMIT_ALIVE); + + if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) && + (pwrctrl->bFwCurrentInPSMode == _TRUE)) + { + if ((pwrctrl->alives == 0) && + (pwrctrl->cpwm > PS_STATE_S0)) + { + rtw_set_rpwm(padapter, PS_STATE_S0); + } + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_tx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +/* + * Caller: ISR + * + * If all commands have been done, + * and no more command to do, + * then driver shall call this fun. to power down firmware again. + */ +void rtw_unregister_cmd_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, CMD_ALIVE); + + if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) && + (pwrctrl->bFwCurrentInPSMode == _TRUE)) + { + if ((pwrctrl->alives == 0) && + (pwrctrl->cpwm > PS_STATE_S0)) + { + rtw_set_rpwm(padapter, PS_STATE_S0); + } + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_cmd_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +/* + * Caller: ISR + */ +void rtw_unregister_rx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, RECV_ALIVE); + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_rx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +void rtw_unregister_evt_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = &padapter->pwrctrlpriv; + + unregister_task_alive(pwrctrl, EVT_ALIVE); + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_evt_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} +#endif /* CONFIG_LPS_LCLK */ + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +static void resume_workitem_callback(struct work_struct *work); +#endif //CONFIG_RESUME_IN_WORKQUEUE + +void rtw_init_pwrctrl_priv(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + +_func_enter_; + +#ifdef PLATFORM_WINDOWS + pwrctrlpriv->pnp_current_pwr_state=NdisDeviceStateD0; +#endif + + _init_pwrlock(&pwrctrlpriv->lock); + pwrctrlpriv->rf_pwrstate = rf_on; + pwrctrlpriv->ips_enter_cnts=0; + pwrctrlpriv->ips_leave_cnts=0; + + pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode; + pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode; + + pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; + pwrctrlpriv->pwr_state_check_cnts = 0; + pwrctrlpriv->bInternalAutoSuspend = _FALSE; + pwrctrlpriv->bInSuspend = _FALSE; + pwrctrlpriv->bkeepfwalive = _FALSE; + +#ifdef CONFIG_AUTOSUSPEND +#ifdef SUPPORT_HW_RFOFF_DETECTED + pwrctrlpriv->pwr_state_check_interval = (pwrctrlpriv->bHWPwrPindetect) ?1000:2000; +#endif +#endif + + pwrctrlpriv->LpsIdleCount = 0; + //pwrctrlpriv->FWCtrlPSMode =padapter->registrypriv.power_mgnt;// PS_MODE_MIN; + pwrctrlpriv->power_mgnt =padapter->registrypriv.power_mgnt;// PS_MODE_MIN; + pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?_TRUE:_FALSE; + + pwrctrlpriv->bFwCurrentInPSMode = _FALSE; + + pwrctrlpriv->cpwm = PS_STATE_S4; + + pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; + + + pwrctrlpriv->smart_ps = 0; + + pwrctrlpriv->tog = 0x80; + +#ifdef PLATFORM_LINUX + _init_timer(&(pwrctrlpriv->pwr_state_check_timer), padapter->pnetdev, pwr_state_check_handler, (u8 *)padapter); +#endif + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + _init_workitem(&pwrctrlpriv->resume_work, resume_workitem_callback, NULL); + pwrctrlpriv->rtw_workqueue = create_singlethread_workqueue("rtw_workqueue"); + #endif //CONFIG_RESUME_IN_WORKQUEUE + + #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + pwrctrlpriv->early_suspend.suspend = NULL; + rtw_register_early_suspend(pwrctrlpriv); + #endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER + + +_func_exit_; + +} + + +void rtw_free_pwrctrl_priv(PADAPTER adapter) +{ + struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv; + +_func_enter_; + + //_rtw_memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); + + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + if (pwrctrlpriv->rtw_workqueue) { + flush_workqueue(pwrctrlpriv->rtw_workqueue); + destroy_workqueue(pwrctrlpriv->rtw_workqueue); + } + #endif + + + #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + rtw_unregister_early_suspend(pwrctrlpriv); + #endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER + + _free_pwrlock(&pwrctrlpriv->lock); + +_func_exit_; +} + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) +extern int rtw_resume_process(_adapter *padapter); +#endif +static void resume_workitem_callback(struct work_struct *work) +{ + struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, resume_work); + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + + DBG_871X("%s\n",__FUNCTION__); + + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + rtw_resume_process(adapter); + #endif + +} + +void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv) +{ + // accquire system's suspend lock preventing from falliing asleep while resume in workqueue + rtw_lock_suspend(); + + #if 1 + queue_work(pwrpriv->rtw_workqueue, &pwrpriv->resume_work); + #else + _set_workitem(&pwrpriv->resume_work); + #endif +} +#endif //CONFIG_RESUME_IN_WORKQUEUE + +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) +inline bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv) +{ + return (pwrpriv->early_suspend.suspend) ? _TRUE : _FALSE; +} + +inline bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv) +{ + return (pwrpriv->do_late_resume) ? _TRUE : _FALSE; +} + +inline void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable) +{ + pwrpriv->do_late_resume = enable; +} +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) +extern int rtw_resume_process(_adapter *padapter); +#endif +static void rtw_early_suspend(struct early_suspend *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + DBG_871X("%s\n",__FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); +} + +static void rtw_late_resume(struct early_suspend *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + + DBG_871X("%s\n",__FUNCTION__); + if(pwrpriv->do_late_resume) { + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + rtw_set_do_late_resume(pwrpriv, _FALSE); + rtw_resume_process(adapter); + #endif + } +} + +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + +#if defined(CONFIG_CONCURRENT_MODE) + if (adapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + DBG_871X("%s\n", __FUNCTION__); + + //jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit + pwrpriv->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20; + pwrpriv->early_suspend.suspend = rtw_early_suspend; + pwrpriv->early_suspend.resume = rtw_late_resume; + register_early_suspend(&pwrpriv->early_suspend); + + +} + +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + +#if defined(CONFIG_CONCURRENT_MODE) + if (adapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); + + if (pwrpriv->early_suspend.suspend) + unregister_early_suspend(&pwrpriv->early_suspend); + + pwrpriv->early_suspend.suspend = NULL; + pwrpriv->early_suspend.resume = NULL; +} +#endif //CONFIG_HAS_EARLYSUSPEND + +#ifdef CONFIG_ANDROID_POWER +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) +extern int rtw_resume_process(PADAPTER padapter); +#endif +static void rtw_early_suspend(android_early_suspend_t *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + DBG_871X("%s\n",__FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); +} + +static void rtw_late_resume(android_early_suspend_t *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + + DBG_871X("%s\n",__FUNCTION__); + if(pwrpriv->do_late_resume) { + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) + rtw_set_do_late_resume(pwrpriv, _FALSE); + rtw_resume_process(adapter); + #endif + } +} + +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + +#if defined(CONFIG_CONCURRENT_MODE) + if (adapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + DBG_871X("%s\n", __FUNCTION__); + + //jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit + pwrpriv->early_suspend.level = ANDROID_EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20; + pwrpriv->early_suspend.suspend = rtw_early_suspend; + pwrpriv->early_suspend.resume = rtw_late_resume; + android_register_early_suspend(&pwrpriv->early_suspend); +} + +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv); + +#if defined(CONFIG_CONCURRENT_MODE) + if (adapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); + + if (pwrpriv->early_suspend.suspend) + android_unregister_early_suspend(&pwrpriv->early_suspend); + + pwrpriv->early_suspend.suspend = NULL; + pwrpriv->early_suspend.resume = NULL; +} +#endif //CONFIG_ANDROID_POWER + +u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val) +{ + u8 bResult = _TRUE; + + rtw_hal_intf_ps_func(padapter,efunc_id,val); + + return bResult; +} + + +inline void rtw_set_ips_deny(_adapter *padapter, u32 ms) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms); +} + +/* +* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend +* @adapter: pointer to _adapter structure +* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup +* Return _SUCCESS or _FAIL +*/ +int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + int ret = _SUCCESS; + u32 start = rtw_get_current_time(); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) + LeaveAllPowerSaveMode(padapter->pbuddy_adapter); + + if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){ + padapter = padapter->pbuddy_adapter; + pwrpriv = &padapter->pwrctrlpriv; + pmlmepriv = &padapter->mlmepriv; + } +#endif + + if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); + + if (pwrpriv->ps_processing) { + DBG_871X("%s wait ps_processing...\n", __func__); + while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) + rtw_msleep_os(10); + if (pwrpriv->ps_processing) + DBG_871X("%s wait ps_processing timeout\n", __func__); + else + DBG_871X("%s wait ps_processing done\n", __func__); + } + +#ifdef DBG_CONFIG_ERROR_DETECT + if (rtw_hal_sreset_inprogress(padapter)) { + DBG_871X("%s wait sreset_inprogress...\n", __func__); + while (rtw_hal_sreset_inprogress(padapter) && rtw_get_passing_time_ms(start) <= 4000) + rtw_msleep_os(10); + if (rtw_hal_sreset_inprogress(padapter)) + DBG_871X("%s wait sreset_inprogress timeout\n", __func__); + else + DBG_871X("%s wait sreset_inprogress done\n", __func__); + } +#endif + + if (pwrpriv->bInternalAutoSuspend == _FALSE && pwrpriv->bInSuspend) { + DBG_871X("%s wait bInSuspend...\n", __func__); + while (pwrpriv->bInSuspend + && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv)) + || (rtw_get_passing_time_ms(start) <= 500 && rtw_is_do_late_resume(pwrpriv))) + ) { + rtw_msleep_os(10); + } + if (pwrpriv->bInSuspend) + DBG_871X("%s wait bInSuspend timeout\n", __func__); + else + DBG_871X("%s wait bInSuspend done\n", __func__); + } + + //System suspend is not allowed to wakeup + if((pwrpriv->bInternalAutoSuspend == _FALSE) && (_TRUE == pwrpriv->bInSuspend )){ + ret = _FAIL; + goto exit; + } + + //block??? + if((pwrpriv->bInternalAutoSuspend == _TRUE) && (padapter->net_closed == _TRUE)) { + ret = _FAIL; + goto exit; + } + + //I think this should be check in IPS, LPS, autosuspend functions... + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + ret = _SUCCESS; + goto exit; + } + + if(rf_off == pwrpriv->rf_pwrstate ) + { +#ifdef CONFIG_USB_HCI +#ifdef CONFIG_AUTOSUSPEND + if(pwrpriv->brfoffbyhw==_TRUE) + { + DBG_8192C("hw still in rf_off state ...........\n"); + ret = _FAIL; + goto exit; + } + else if(padapter->registrypriv.usbss_enable) + { + DBG_8192C("%s call autoresume_enter....\n",__FUNCTION__); + if(_FAIL == autoresume_enter(padapter)) + { + DBG_8192C("======> autoresume fail.............\n"); + ret = _FAIL; + goto exit; + } + } + else +#endif +#endif + { +#ifdef CONFIG_IPS + DBG_8192C("%s call ips_leave....\n",__FUNCTION__); + if(_FAIL == ips_leave(padapter)) + { + DBG_8192C("======> ips_leave fail.............\n"); + ret = _FAIL; + goto exit; + } +#endif + } + } + + //TODO: the following checking need to be merged... + if(padapter->bDriverStopped + || !padapter->bup + || !padapter->hw_init_completed + ){ + DBG_8192C("%s: bDriverStopped=%d, bup=%d, hw_init_completed=%u\n" + , caller + , padapter->bDriverStopped + , padapter->bup + , padapter->hw_init_completed); + ret= _FALSE; + goto exit; + } + +exit: + if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); + return ret; + +} + +int rtw_pm_set_lps(_adapter *padapter, u8 mode) +{ + int ret = 0; + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + + if ( mode < PS_MODE_NUM ) + { + if(pwrctrlpriv->power_mgnt !=mode) + { + if(PS_MODE_ACTIVE == mode) + { + LeaveAllPowerSaveMode(padapter); + } + else + { + pwrctrlpriv->LpsIdleCount = 2; + } + pwrctrlpriv->power_mgnt = mode; + pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?_TRUE:_FALSE; + } + } + else + { + ret = -EINVAL; + } + + return ret; +} + +int rtw_pm_set_ips(_adapter *padapter, u8 mode) +{ + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + + if( mode == IPS_NORMAL || mode == IPS_LEVEL_2 ) { + rtw_ips_mode_req(pwrctrlpriv, mode); + DBG_871X("%s %s\n", __FUNCTION__, mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2"); + return 0; + } + else if(mode ==IPS_NONE){ + rtw_ips_mode_req(pwrctrlpriv, mode); + DBG_871X("%s %s\n", __FUNCTION__, "IPS_NONE"); + if((padapter->bSurpriseRemoved ==0)&&(_FAIL == rtw_pwr_wakeup(padapter)) ) + return -EFAULT; + } + else { + return -EINVAL; + } + return 0; +} + + diff --git a/rtl8192cu-fixes/core/rtw_recv.c b/rtl8192cu-fixes/core/rtw_recv.c new file mode 100755 index 00000000..2cc8faa0 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_recv.c @@ -0,0 +1,4289 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_RECV_C_ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_HCI +#include +#endif + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#include +#include + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS +void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS); +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + +void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) +{ + + +_func_enter_; + + _rtw_memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv)); + + _rtw_spinlock_init(&psta_recvpriv->lock); + + //for(i=0; iblk_strms[i]); + + _rtw_init_queue(&psta_recvpriv->defrag_q); + +_func_exit_; + +} + +sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter) +{ + sint i; + + union recv_frame *precvframe; + + sint res=_SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv)); + + _rtw_spinlock_init(&precvpriv->lock); + + _rtw_init_queue(&precvpriv->free_recv_queue); + _rtw_init_queue(&precvpriv->recv_pending_queue); + _rtw_init_queue(&precvpriv->uc_swdec_pending_queue); + + precvpriv->adapter = padapter; + + precvpriv->free_recvframe_cnt = NR_RECVFRAME; + + rtw_os_recv_resource_init(precvpriv, padapter); + + precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); + + if(precvpriv->pallocated_frame_buf==NULL){ + res= _FAIL; + goto exit; + } + //_rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); + + precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ); + //precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - + // ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); + + precvframe = (union recv_frame*) precvpriv->precv_frame_buf; + + + for(i=0; i < NR_RECVFRAME ; i++) + { + _rtw_init_listhead(&(precvframe->u.list)); + + rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue)); + + res = rtw_os_recv_resource_alloc(padapter, precvframe); + + precvframe->u.hdr.adapter =padapter; + precvframe++; + + } + +#ifdef CONFIG_USB_HCI + + precvpriv->rx_pending_cnt=1; + + _rtw_init_sema(&precvpriv->allrxreturnevt, 0); + +#endif + + res = rtw_hal_init_recv_priv(padapter); + + precvpriv->recvbuf_skb_alloc_fail_cnt = 0; + precvpriv->recvbuf_null_cnt = 0; + precvpriv->read_port_complete_EINPROGRESS_cnt = 0; + precvpriv->read_port_complete_other_urb_err_cnt = 0; + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + #ifdef PLATFORM_LINUX + _init_timer(&precvpriv->signal_stat_timer, padapter->pnetdev, RTW_TIMER_HDL_NAME(signal_stat), padapter); + #elif defined(PLATFORM_OS_CE) || defined(PLATFORM_WINDOWS) + _init_timer(&precvpriv->signal_stat_timer, padapter->hndis_adapter, RTW_TIMER_HDL_NAME(signal_stat), padapter); + #endif + + precvpriv->signal_stat_sampling_interval = 1000; //ms + //precvpriv->signal_stat_converging_constant = 5000; //ms + + rtw_set_signal_stat_timer(precvpriv); +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +exit: + +_func_exit_; + + return res; + +} + +void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv); +void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv) +{ + _rtw_spinlock_free(&precvpriv->lock); +#ifdef CONFIG_RECV_THREAD_MODE + _rtw_free_sema(&precvpriv->recv_sema); + _rtw_free_sema(&precvpriv->terminate_recvthread_sema); +#endif + + _rtw_spinlock_free(&precvpriv->free_recv_queue.lock); + _rtw_spinlock_free(&precvpriv->recv_pending_queue.lock); + + _rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock); + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + _rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock); +#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX +} + +void _rtw_free_recv_priv (struct recv_priv *precvpriv) +{ + _adapter *padapter = precvpriv->adapter; + +_func_enter_; + + rtw_free_uc_swdec_pending_queue(padapter); + + rtw_mfree_recv_priv_lock(precvpriv); + + rtw_os_recv_resource_free(precvpriv); + + if(precvpriv->pallocated_frame_buf) { + rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); + } + + rtw_hal_free_recv_priv(padapter); + +_func_exit_; + +} + +union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue) +{ + + union recv_frame *precvframe; + _list *plist, *phead; + _adapter *padapter; + struct recv_priv *precvpriv; +_func_enter_; + + if(_rtw_queue_empty(pfree_recv_queue) == _TRUE) + { + precvframe = NULL; + } + else + { + phead = get_list_head(pfree_recv_queue); + + plist = get_next(phead); + + precvframe = LIST_CONTAINOR(plist, union recv_frame, u); + + rtw_list_delete(&precvframe->u.hdr.list); + padapter=precvframe->u.hdr.adapter; + if(padapter !=NULL){ + precvpriv=&padapter->recvpriv; + if(pfree_recv_queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt--; + } + } + +_func_exit_; + + return precvframe; + +} + +union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue) +{ + _irqL irqL; + union recv_frame *precvframe; + + _enter_critical_bh(&pfree_recv_queue->lock, &irqL); + + precvframe = _rtw_alloc_recvframe(pfree_recv_queue); + + _exit_critical_bh(&pfree_recv_queue->lock, &irqL); + + return precvframe; +} + +void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv) +{ + /* Perry: This can be removed */ + _rtw_init_listhead(&precvframe->u.hdr.list); + + precvframe->u.hdr.len=0; +} + +int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue) +{ + _irqL irqL; + _adapter *padapter=precvframe->u.hdr.adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + +_func_enter_; + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type > PRIMARY_ADAPTER) + { + padapter = padapter->pbuddy_adapter;//get primary_padapter + precvpriv = &padapter->recvpriv; + pfree_recv_queue = &precvpriv->free_recv_queue; + precvframe->u.hdr.adapter = padapter; + } +#endif + + +#ifdef PLATFORM_WINDOWS + rtw_os_read_port(padapter, precvframe->u.hdr.precvbuf); +#endif + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) + + if(precvframe->u.hdr.pkt) + { +#ifdef CONFIG_BSD_RX_USE_MBUF + m_freem(precvframe->u.hdr.pkt); +#else // CONFIG_BSD_RX_USE_MBUF + rtw_skb_free(precvframe->u.hdr.pkt);//free skb by driver +#endif // CONFIG_BSD_RX_USE_MBUF + precvframe->u.hdr.pkt = NULL; + } + +#endif //defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) + + _enter_critical_bh(&pfree_recv_queue->lock, &irqL); + + rtw_list_delete(&(precvframe->u.hdr.list)); + + rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue)); + + if(padapter !=NULL){ + if(pfree_recv_queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt++; + } + + _exit_critical_bh(&pfree_recv_queue->lock, &irqL); + +_func_exit_; + + return _SUCCESS; + +} + + + + +sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + + _adapter *padapter=precvframe->u.hdr.adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + +_func_enter_; + + //_rtw_init_listhead(&(precvframe->u.hdr.list)); + rtw_list_delete(&(precvframe->u.hdr.list)); + + + rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue)); + + if (padapter != NULL) { + if (queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt++; + } + +_func_exit_; + + return _SUCCESS; +} + +sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + sint ret; + _irqL irqL; + + //_spinlock(&pfree_recv_queue->lock); + _enter_critical_bh(&queue->lock, &irqL); + ret = _rtw_enqueue_recvframe(precvframe, queue); + //_rtw_spinunlock(&pfree_recv_queue->lock); + _exit_critical_bh(&queue->lock, &irqL); + + return ret; +} + +/* +sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + return rtw_free_recvframe(precvframe, queue); +} +*/ + + + + +/* +caller : defrag ; recvframe_chk_defrag in recv_thread (passive) +pframequeue: defrag_queue : will be accessed in recv_thread (passive) + +using spinlock to protect + +*/ + +void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue) +{ + union recv_frame *precvframe; + _list *plist, *phead; + +_func_enter_; + _rtw_spinlock(&pframequeue->lock); + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + precvframe = LIST_CONTAINOR(plist, union recv_frame, u); + + plist = get_next(plist); + + //rtw_list_delete(&precvframe->u.hdr.list); // will do this in rtw_free_recvframe() + + rtw_free_recvframe(precvframe, pfree_recv_queue); + } + + _rtw_spinunlock(&pframequeue->lock); + +_func_exit_; + +} + +u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter) +{ + u32 cnt = 0; + union recv_frame *pending_frame; + while((pending_frame=rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { + rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); + DBG_871X("%s: dequeue uc_swdec_pending_queue\n", __func__); + cnt++; + } + + return cnt; +} + + +sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue) +{ + _irqL irqL; + + _enter_critical(&queue->lock, &irqL); + + rtw_list_delete(&precvbuf->list); + rtw_list_insert_head(&precvbuf->list, get_list_head(queue)); + + _exit_critical(&queue->lock, &irqL); + + return _SUCCESS; +} + +sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue) +{ + _irqL irqL; + + _enter_critical(&queue->lock, &irqL); + + rtw_list_delete(&precvbuf->list); + + rtw_list_insert_tail(&precvbuf->list, get_list_head(queue)); + + _exit_critical(&queue->lock, &irqL); + + + return _SUCCESS; + +} + +struct recv_buf *rtw_dequeue_recvbuf (_queue *queue) +{ + _irqL irqL; + struct recv_buf *precvbuf; + _list *plist, *phead; + + _enter_critical(&queue->lock, &irqL); + + if(_rtw_queue_empty(queue) == _TRUE) + { + precvbuf = NULL; + } + else + { + phead = get_list_head(queue); + + plist = get_next(phead); + + precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list); + + rtw_list_delete(&precvbuf->list); + + } + + _exit_critical(&queue->lock, &irqL); + + + return precvbuf; + +} + +sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe); +sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe){ + + sint i,res=_SUCCESS; + u32 datalen; + u8 miccode[8]; + u8 bmic_err=_FALSE,brpt_micerror = _TRUE; + u8 *pframe, *payload,*pframemic; + u8 *mickey; + //u8 *iv,rxdata_key_idx=0; + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib=&precvframe->u.hdr.attrib; + struct security_priv *psecuritypriv=&adapter->securitypriv; + + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); +_func_enter_; + + stainfo=rtw_get_stainfo(&adapter->stapriv ,&prxattrib->ta[0]); + + if(prxattrib->encrypt ==_TKIP_) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:prxattrib->encrypt ==_TKIP_\n")); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:da=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2],prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5])); + + //calculate mic code + if(stainfo!= NULL) + { + if(IS_MCAST(prxattrib->ra)) + { + //mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0]; + //iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; + //rxdata_key_idx =( ((iv[3])>>6)&0x3) ; + mickey=&psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0]; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic: bcmc key \n")); + //DBG_871X("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n", + // psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx); + + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n")); + DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"); + goto exit; + } + } + else{ + mickey=&stainfo->dot11tkiprxmickey.skey[0]; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic: unicast key \n")); + } + + datalen=precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;//icv_len included the mic code + pframe=precvframe->u.hdr.rx_data; + payload=pframe+prxattrib->hdrlen+prxattrib->iv_len; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n",prxattrib->iv_len,prxattrib->icv_len)); + + //rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data + + rtw_seccalctkipmic(mickey,pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data + + pframemic=payload+datalen; + + bmic_err=_FALSE; + + for(i=0;i<8;i++){ + if(miccode[i] != *(pframemic+i)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ",i,miccode[i],i,*(pframemic+i))); + bmic_err=_TRUE; + } + } + + + if(bmic_err==_TRUE){ + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-8)-*(pframemic-1)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + *(pframemic-8),*(pframemic-7),*(pframemic-6),*(pframemic-5),*(pframemic-4),*(pframemic-3),*(pframemic-2),*(pframemic-1))); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-16)-*(pframemic-9)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + *(pframemic-16),*(pframemic-15),*(pframemic-14),*(pframemic-13),*(pframemic-12),*(pframemic-11),*(pframemic-10),*(pframemic-9))); + + { + uint i; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet (len=%d)======\n",precvframe->u.hdr.len)); + for(i=0;iu.hdr.len;i=i+8){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x", + *(precvframe->u.hdr.rx_data+i),*(precvframe->u.hdr.rx_data+i+1), + *(precvframe->u.hdr.rx_data+i+2),*(precvframe->u.hdr.rx_data+i+3), + *(precvframe->u.hdr.rx_data+i+4),*(precvframe->u.hdr.rx_data+i+5), + *(precvframe->u.hdr.rx_data+i+6),*(precvframe->u.hdr.rx_data+i+7))); + } + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet end [len=%d]======\n",precvframe->u.hdr.len)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n hrdlen=%d, \n",prxattrib->hdrlen)); + } + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ra=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey=%d ", + prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2], + prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5],psecuritypriv->binstallGrpkey)); + + // double check key_index for some timing issue , + // cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue + if((IS_MCAST(prxattrib->ra)==_TRUE) && (prxattrib->key_index != pmlmeinfo->key_index )) + brpt_micerror = _FALSE; + + if(brpt_micerror == _TRUE) + { + rtw_handle_tkip_mic_err(adapter,(u8)IS_MCAST(prxattrib->ra)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" mic error :prxattrib->bdecrypted=%d \n", brpt_micerror)); + DBG_871X(" mic error :brpt_micerror=%d\n", brpt_micerror); + } + + res=_FAIL; + + } + else{ + //mic checked ok + if((psecuritypriv->bcheck_grpkey ==_FALSE)&&(IS_MCAST(prxattrib->ra)==_TRUE)){ + psecuritypriv->bcheck_grpkey =_TRUE; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->bcheck_grpkey =_TRUE")); + } + } + + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n")); + } + + recvframe_pull_tail(precvframe, 8); + + } + +exit: + +_func_exit_; + + return res; + +} + +//decrypt and set the ivlen,icvlen of the recv_frame +union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame); +union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame) +{ + + struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + union recv_frame *return_packet=precv_frame; + u32 res=_SUCCESS; +_func_enter_; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n",prxattrib->bdecrypted,prxattrib->encrypt)); + + if(prxattrib->encrypt>0) + { + u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen; + prxattrib->key_index = ( ((iv[3])>>6)&0x3) ; + + if(prxattrib->key_index > WEP_KEYS) + { + DBG_871X("prxattrib->key_index(%d) > WEP_KEYS \n", prxattrib->key_index); + + switch(prxattrib->encrypt){ + case _WEP40_: + case _WEP104_: + prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex; + break; + case _TKIP_: + case _AES_: + default: + prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; + break; + } + } + } + + if((prxattrib->encrypt>0) && ((prxattrib->bdecrypted==0) ||(psecuritypriv->sw_decrypt==_TRUE))) + { + +#ifdef CONFIG_CONCURRENT_MODE + if(!IS_MCAST(prxattrib->ra))//bc/mc packets use sw decryption for concurrent mode +#endif + psecuritypriv->hw_decrypted=_FALSE; + + #ifdef DBG_RX_DECRYPTOR + DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n" + , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted); + #endif + + switch(prxattrib->encrypt){ + case _WEP40_: + case _WEP104_: + rtw_wep_decrypt(padapter, (u8 *)precv_frame); + break; + case _TKIP_: + res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); + break; + case _AES_: + res = rtw_aes_decrypt(padapter, (u8 * )precv_frame); + break; + default: + break; + } + } + else if(prxattrib->bdecrypted==1 + && prxattrib->encrypt >0 + && (psecuritypriv->busetkipkey==1 || prxattrib->encrypt !=_TKIP_ ) + ) + { +#if 0 + if((prxstat->icv==1)&&(prxattrib->encrypt!=_AES_)) + { + psecuritypriv->hw_decrypted=_FALSE; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->hw_decrypted=_FALSE")); + + rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue); + + return_packet=NULL; + + } + else +#endif + { + psecuritypriv->hw_decrypted=_TRUE; + #ifdef DBG_RX_DECRYPTOR + DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n" + , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted); + #endif + + } + } + else { + #ifdef DBG_RX_DECRYPTOR + DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, psecuritypriv->hw_decrypted:%d\n" + , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted); + #endif + } + + if(res == _FAIL) + { + rtw_free_recvframe(return_packet,&padapter->recvpriv.free_recv_queue); + return_packet = NULL; + + } + //recvframe_chkmic(adapter, precv_frame); //move to recvframme_defrag function + +_func_exit_; + + return return_packet; + +} +//###set the security information in the recv_frame +union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame); +union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame) +{ + u8 *psta_addr,*ptr; + uint auth_alg; + struct recv_frame_hdr *pfhdr; + struct sta_info * psta; + struct sta_priv *pstapriv ; + union recv_frame * prtnframe; + u16 ether_type=0; + u16 eapol_type = 0x888e;//for Funia BD's WPA issue + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + +_func_enter_; + + pstapriv = &adapter->stapriv; + ptr = get_recvframe_data(precv_frame); + pfhdr = &precv_frame->u.hdr; + psta_addr = pfhdr->attrib.ta; + psta = rtw_get_stainfo(pstapriv, psta_addr); + + auth_alg = adapter->securitypriv.dot11AuthAlgrthm; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:adapter->securitypriv.dot11AuthAlgrthm= 0x%d\n",adapter->securitypriv.dot11AuthAlgrthm)); + + if(auth_alg==2) + { + if ((psta!=NULL) && (psta->ieee8021x_blocked)) + { + //blocked + //only accept EAPOL frame + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==1\n")); + + prtnframe=precv_frame; + + //get ether_type + ptr=ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE; + _rtw_memcpy(ðer_type,ptr, 2); + ether_type= ntohs((unsigned short )ether_type); + + if (ether_type == eapol_type) { + prtnframe=precv_frame; + } + else { + //free this frame + rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue); + prtnframe=NULL; + } + } + else + { + //allowed + //check decryption status, and decrypt the frame if needed + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==0\n")); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:precv_frame->hdr.attrib.privacy=%x\n",precv_frame->u.hdr.attrib.privacy)); + + if(pattrib->bdecrypted==0) + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:prxstat->decrypted=%x\n", pattrib->bdecrypted)); + + prtnframe=precv_frame; + //check is the EAPOL frame or not (Rekey) + if(ether_type == eapol_type){ + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("########portctrl:ether_type == 0x888e\n")); + //check Rekey + + prtnframe=precv_frame; + } + else{ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("########portctrl:ether_type = 0x%.4x\n",ether_type)); + } + } + } + else + { + prtnframe=precv_frame; + } + +_func_exit_; + + return prtnframe; + +} + +sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache); +sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache) +{ + sint tid = precv_frame->u.hdr.attrib.priority; + + u16 seq_ctrl = ( (precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | + (precv_frame->u.hdr.attrib.frag_num & 0xf); + +_func_enter_; + + if(tid>15) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl, tid)); + + return _FAIL; + } + + if(1)//if(bretry) + { + if(seq_ctrl == prxcache->tid_rxseq[tid]) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, seq_ctrl=0x%x, tid=0x%x, tid_rxseq=0x%x\n", seq_ctrl, tid, prxcache->tid_rxseq[tid])); + + return _FAIL; + } + } + + prxcache->tid_rxseq[tid] = seq_ctrl; + +_func_exit_; + + return _SUCCESS; + +} + +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame); +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + unsigned char pwrbit; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL; + + psta = rtw_get_stainfo(pstapriv, pattrib->src); + + pwrbit = GetPwrMgt(ptr); + + if(psta) + { + if(pwrbit) + { + if(!(psta->state & WIFI_SLEEP_STATE)) + { + //psta->state |= WIFI_SLEEP_STATE; + //pstapriv->sta_dz_bitmap |= BIT(psta->aid); + + stop_sta_xmit(padapter, psta); + + //DBG_871X("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); + } + } + else + { + if(psta->state & WIFI_SLEEP_STATE) + { + //psta->state ^= WIFI_SLEEP_STATE; + //pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); + + wakeup_sta_to_xmit(padapter, psta); + + //DBG_871X("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); + } + } + + } + +#endif +} + +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame); +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL; + + psta = rtw_get_stainfo(pstapriv, pattrib->src); + + if(!psta) return; + +#ifdef CONFIG_TDLS + if( !(psta->tdls_sta_state & TDLS_LINKED_STATE ) ) + { +#endif //CONFIG_TDLS + + if(!psta->qos_option) + return; + + if(!(psta->qos_info&0xf)) + return; + +#ifdef CONFIG_TDLS + } +#endif //CONFIG_TDLS + + if(psta->state&WIFI_SLEEP_STATE) + { + u8 wmmps_ac=0; + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + if(wmmps_ac) + { + if(psta->sleepq_ac_len>0) + { + //process received triggered frame + xmit_delivery_enabled_frames(padapter, psta); + } + else + { + //issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) + issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0); + } + } + + } + + +#endif + +} + +#ifdef CONFIG_TDLS +sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + sint ret = _SUCCESS; + u8 *paction = get_recvframe_data(precv_frame); + u8 category_field = 1; +#ifdef CONFIG_WFD + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a }; +#endif //CONFIG_WFD + struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo); + + //point to action field + paction+=pattrib->hdrlen + + pattrib->iv_len + + SNAP_SIZE + + ETH_TYPE_LEN + + PAYLOAD_TYPE_LEN + + category_field; + + if(ptdlsinfo->enable == 0) + { + DBG_871X("recv tdls frame, " + "but tdls haven't enabled\n"); + ret = _FAIL; + return ret; + } + + switch(*paction){ + case TDLS_SETUP_REQUEST: + DBG_871X("recv tdls setup request frame\n"); + ret=On_TDLS_Setup_Req(adapter, precv_frame); + break; + case TDLS_SETUP_RESPONSE: + DBG_871X("recv tdls setup response frame\n"); + ret=On_TDLS_Setup_Rsp(adapter, precv_frame); + break; + case TDLS_SETUP_CONFIRM: + DBG_871X("recv tdls setup confirm frame\n"); + ret=On_TDLS_Setup_Cfm(adapter, precv_frame); + break; + case TDLS_TEARDOWN: + DBG_871X("recv tdls teardown, free sta_info\n"); + ret=On_TDLS_Teardown(adapter, precv_frame); + break; + case TDLS_DISCOVERY_REQUEST: + DBG_871X("recv tdls discovery request frame\n"); + ret=On_TDLS_Dis_Req(adapter, precv_frame); + break; + case TDLS_PEER_TRAFFIC_RESPONSE: + DBG_871X("recv tdls peer traffic response frame\n"); + ret=On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); + break; + case TDLS_CHANNEL_SWITCH_REQUEST: + DBG_871X("recv tdls channel switch request frame\n"); + ret=On_TDLS_Ch_Switch_Req(adapter, precv_frame); + break; + case TDLS_CHANNEL_SWITCH_RESPONSE: + DBG_871X("recv tdls channel switch response frame\n"); + ret=On_TDLS_Ch_Switch_Rsp(adapter, precv_frame); + break; +#ifdef CONFIG_WFD + case 0x50: //First byte of WFA OUI + if( _rtw_memcmp(WFA_OUI, (paction), 3) ) + { + if( *(paction + 3) == 0x04) //Probe request frame + { + //WFDTDLS: for sigma test, do not setup direct link automatically + ptdlsinfo->dev_discovered = 1; + DBG_871X("recv tunneled probe request frame\n"); + issue_tunneled_probe_rsp(adapter, precv_frame); + } + if( *(paction + 3) == 0x05) //Probe response frame + { + //WFDTDLS: for sigma test, do not setup direct link automatically + ptdlsinfo->dev_discovered = 1; + DBG_871X("recv tunneled probe response frame\n"); + } + } + break; +#endif //CONFIG_WFD + default: + DBG_871X("receive TDLS frame but not supported\n"); + ret=_FAIL; + break; + } + +exit: + return ret; + +} +#endif //CONFIG_TDLS + +void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta); +void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta) +{ + int sz; + struct sta_info *psta = NULL; + struct stainfo_stats *pstats = NULL; + struct rx_pkt_attrib *pattrib = & prframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + + sz = get_recvframe_len(prframe); + precvpriv->rx_bytes += sz; + + padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; + + if( (!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))){ + padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++; + } + + if(sta) + psta = sta; + else + psta = prframe->u.hdr.psta; + + if(psta) + { + pstats = &psta->sta_stats; + + pstats->rx_data_pkts++; + pstats->rx_bytes += sz; + } + +} + +sint sta2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta +); +sint sta2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta +) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + sint ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = myid(&adapter->eeprompriv); + u8 * sta_addr = NULL; + sint bmcast = IS_MCAST(pattrib->dst); + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; + struct sta_info *ptdls_sta=NULL; + u8 *psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + u8 *pframe_body = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN; +#endif //CONFIG_TDLS + +_func_enter_; + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + + // filter packets that SA is myself or multicast or broadcast + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n")); + ret= _FAIL; + goto exit; + } + + if( (!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast) ){ + ret= _FAIL; + goto exit; + } + + if( _rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) ) { + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->src; + + } + else if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { +#ifdef CONFIG_TDLS + //direct link data transfer + if(ptdlsinfo->setup_state == TDLS_LINKED_STATE){ + ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src); + if(ptdls_sta==NULL) + { + ret=_FAIL; + goto exit; + } + else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE) + { + //drop QoS-SubType Data, including QoS NULL, excluding QoS-Data + if( (GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE )== WIFI_QOS_DATA_TYPE) + { + if(GetFrameSubType(ptr)&(BIT(4)|BIT(5)|BIT(6))) + { + DBG_871X("drop QoS-Sybtype Data\n"); + ret= _FAIL; + goto exit; + } + } + // filter packets that SA is myself or multicast or broadcast + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){ + ret= _FAIL; + goto exit; + } + // da should be for me + if((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast)) + { + ret= _FAIL; + goto exit; + } + // check BSSID + if( _rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) ) + { + ret= _FAIL; + goto exit; + } + + //process UAPSD tdls sta + process_pwrbit_data(adapter, precv_frame); + + // if NULL-frame, check pwrbit + if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL) + { + //NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA + if(GetPwrMgt(ptr)) + { + DBG_871X("TDLS: recv peer null frame with pwr bit 1\n"); + ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; + } + // it would be triggered when we are off channel and receiving NULL DATA + // we can confirm that peer STA is at off channel + else if(ptdls_sta->tdls_sta_state&TDLS_CH_SWITCH_ON_STATE) + { + if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE) + { + issue_nulldata_to_TDLS_peer_STA(adapter, ptdls_sta, 0); + ptdls_sta->tdls_sta_state |= TDLS_PEER_AT_OFF_STATE; + On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); + } + } + + ret= _FAIL; + goto exit; + } + //receive some of all TDLS management frames, process it at ON_TDLS + if((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2))){ + ret= OnTDLS(adapter, precv_frame); + goto exit; + } + + } + + sta_addr = pattrib->src; + + } + else +#endif //CONFIG_TDLS + { + // For Station mode, sa and bssid should always be BSSID, and DA is my mac-address + if(!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN) ) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("bssid != TA under STATION_MODE; drop pkt\n")); + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->bssid; + } + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + if (bmcast) + { + // For AP mode, if DA == MCAST, then BSSID should be also MCAST + if (!IS_MCAST(pattrib->bssid)){ + ret= _FAIL; + goto exit; + } + } + else // not mc-frame + { + // For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID + if(!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->src; + } + + } + else if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + _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); + + sta_addr = mybssid; + } + else + { + ret = _FAIL; + } + + + + if(bmcast) + *psta = rtw_get_bcmc_stainfo(adapter); + else + *psta = rtw_get_stainfo(pstapriv, sta_addr); // get ap_info + +#ifdef CONFIG_TDLS + if(ptdls_sta != NULL) + *psta = ptdls_sta; +#endif //CONFIG_TDLS + + + if (*psta == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under sta2sta_data_frame ; drop pkt\n")); +#ifdef CONFIG_MP_INCLUDED + if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + adapter->mppriv.rx_pktloss++; +#endif + ret= _FAIL; + goto exit; + } + +exit: +_func_exit_; + return ret; + +} + +sint ap2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ); +sint ap2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + sint ret = _SUCCESS; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = myid(&adapter->eeprompriv); + sint bmcast = IS_MCAST(pattrib->dst); + +_func_enter_; + + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE + || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE ) + ) + { + + // filter packets that SA is myself or multicast or broadcast + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s SA=%x:%x:%x:%x:%x:%x, myhwaddr= %x:%x:%x:%x:%x:%x\n", __FUNCTION__, + pattrib->src[0], pattrib->src[1], pattrib->src[2], + pattrib->src[3], pattrib->src[4], pattrib->src[5], + *(myhwaddr), *(myhwaddr+1), *(myhwaddr+2), + *(myhwaddr+3), *(myhwaddr+4), *(myhwaddr+5)); + #endif + ret= _FAIL; + goto exit; + } + + // da should be for me + if((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast)) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_, + (" ap2sta_data_frame: compare DA fail; DA="MAC_FMT"\n", MAC_ARG(pattrib->dst))); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s DA="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst)); + #endif + ret= _FAIL; + goto exit; + } + + + // check BSSID + if( _rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) ) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_, + (" ap2sta_data_frame: compare BSSID fail ; BSSID="MAC_FMT"\n", MAC_ARG(pattrib->bssid))); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("mybssid="MAC_FMT"\n", MAC_ARG(mybssid))); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s BSSID="MAC_FMT", mybssid="MAC_FMT"\n", + __FUNCTION__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid)); + DBG_871X( "this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddy_adapter->adapter_type ); + #endif + + if(!bmcast) + { + DBG_871X("issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); + issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + + ret= _FAIL; + goto exit; + } + + if(bmcast) + *psta = rtw_get_bcmc_stainfo(adapter); + else + *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get ap_info + + if (*psta == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ap2sta: can't get psta under STATION_MODE ; drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __FUNCTION__); + #endif + ret= _FAIL; + goto exit; + } + + if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + } + + if (GetFrameSubType(ptr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, precv_frame, *psta); + ret = RTW_RX_HANDLED; + goto exit; + } + + } + else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ) + { + _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 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + /* Special case */ + ret = RTW_RX_HANDLED; + goto exit; + } + else + { + if(_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)&& (!bmcast)) + { + *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get sta_info + if (*psta == NULL) + { + DBG_871X("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); + + issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + } + + ret = _FAIL; + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__, get_fwstate(pmlmepriv)); + #endif + } + +exit: + +_func_exit_; + + return ret; + +} + +sint sta2ap_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ); +sint sta2ap_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + unsigned char *mybssid = get_bssid(pmlmepriv); + sint ret=_SUCCESS; + +_func_enter_; + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + //For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR + if(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) + { + ret= _FAIL; + goto exit; + } + + *psta = rtw_get_stainfo(pstapriv, pattrib->src); + if (*psta == NULL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under AP_MODE; drop pkt\n")); + DBG_871X("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); + + issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + + ret = RTW_RX_HANDLED; + goto exit; + } + + process_pwrbit_data(adapter, precv_frame); + + if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + process_wmmps_data(adapter, precv_frame); + } + + if (GetFrameSubType(ptr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, precv_frame, *psta); + ret = RTW_RX_HANDLED; + goto exit; + } + } + else { + u8 *myhwaddr = myid(&adapter->eeprompriv); + if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { + ret = RTW_RX_HANDLED; + goto exit; + } + DBG_871X("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); + issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + ret = RTW_RX_HANDLED; + goto exit; + } + +exit: + +_func_exit_; + + return ret; + +} + +sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame); +sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + //uint len = precv_frame->u.hdr.len; + + //DBG_871X("+validate_recv_ctrl_frame\n"); + + if (GetFrameType(pframe) != WIFI_CTRL_TYPE) + { + return _FAIL; + } + + //receive the frames that ra(a1) is my address + if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN)) + { + return _FAIL; + } + + //only handle ps-poll + if(GetFrameSubType(pframe) == WIFI_PSPOLL) + { + u16 aid; + u8 wmmps_ac=0; + struct sta_info *psta=NULL; + + aid = GetAid(pframe); + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + + if((psta==NULL) || (psta->aid!=aid)) + { + return _FAIL; + } + + //for rx pkt statistics + psta->sta_stats.rx_ctrl_pkts++; + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(0); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(0); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(0); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(0); + break; + } + + if(wmmps_ac) + return _FAIL; + + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + DBG_871X("%s alive check-rx ps-poll\n", __func__); + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } + + if((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) + { + _irqL irqL; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta->sleepq_len--; + + if(psta->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + pxmitframe->attrib.triggered = 1; + + //DBG_871X("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + +#if 0 + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta->sleep_q.lock, &irqL); +#endif + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + if(psta->sleepq_len==0) + { + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //DBG_871X("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap); + + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + } + else + { + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + //DBG_871X("no buffered packets to xmit\n"); + if(pstapriv->tim_bitmap&BIT(psta->aid)) + { + if(psta->sleepq_len==0) + { + DBG_871X("no buffered packets to xmit\n"); + + //issue nulldata with More data bit = 0 to indicate we have no buffered packets + issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); + } + else + { + DBG_871X("error!psta->sleepq_len=%d\n", psta->sleepq_len); + psta->sleepq_len=0; + } + + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + } + + } + + } + + } + +#endif + + return _FAIL; + +} + +union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame); +sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame); +sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame) +{ + //struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n")); + +#if 0 + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_NATIVEAP_MLME + mgt_dispatcher(padapter, precv_frame); +#else + rtw_hostapd_mlme_rx(padapter, precv_frame); +#endif + } + else + { + mgt_dispatcher(padapter, precv_frame); + } +#endif + + precv_frame = recvframe_chk_defrag(padapter, precv_frame); + if (precv_frame == NULL) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,("%s: fragment packet\n",__FUNCTION__)); + return _SUCCESS; + } + + { + //for rx pkt statistics + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data)); + if (psta) { + psta->sta_stats.rx_mgnt_pkts++; + if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON) + psta->sta_stats.rx_beacon_pkts++; + else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ) + psta->sta_stats.rx_probereq_pkts++; + else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) { + if (_rtw_memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == _TRUE) + psta->sta_stats.rx_probersp_pkts++; + else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)) + || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))) + psta->sta_stats.rx_probersp_bm_pkts++; + else + psta->sta_stats.rx_probersp_uo_pkts++; + } + } + } + +#ifdef CONFIG_INTEL_PROXIM + if(padapter->proximity.proxim_on==_TRUE) + { + struct rx_pkt_attrib * pattrib=&precv_frame->u.hdr.attrib; + struct recv_stat* prxstat=( struct recv_stat * ) precv_frame->u.hdr.rx_head ; + u8 * pda,*psa,*pbssid,*ptr; + ptr=precv_frame->u.hdr.rx_data; + 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); + break; + + case 1: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + break; + + case 2: + _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + break; + + case 3: + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n")); + break; + + default: + break; + + } + pattrib->priority=0; + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24; + + padapter->proximity.proxim_rx(padapter,precv_frame); + } +#endif + mgt_dispatcher(padapter, precv_frame); + + return _SUCCESS; + +} + +sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame); +sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) +{ + u8 bretry; + u8 *psa, *pda, *pbssid; + struct sta_info *psta = NULL; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct security_priv *psecuritypriv = &adapter->securitypriv; + sint ret = _SUCCESS; +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#endif //CONFIG_TDLS + +_func_enter_; + + bretry = GetRetry(ptr); + pda = get_da(ptr); + psa = get_sa(ptr); + pbssid = get_hdr_bssid(ptr); + + if(pbssid == NULL){ + ret= _FAIL; + goto exit; + } + + _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(adapter, precv_frame, &psta); + break; + + case 1: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + ret = ap2sta_data_frame(adapter, precv_frame, &psta); + break; + + case 2: + _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + ret = sta2ap_data_frame(adapter, precv_frame, &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; + + } + + if(ret ==_FAIL){ + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __FUNCTION__, pattrib->to_fr_ds, ret); + #endif + goto exit; + } else if (ret == RTW_RX_HANDLED) { + goto exit; + } + + + if(psta==NULL){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" after to_fr_ds_chk; psta==NULL \n")); + ret= _FAIL; + goto exit; + } + + //psta->rssi = prxcmd->rssi; + //psta->signal_quality= prxcmd->sq; + precv_frame->u.hdr.psta = psta; + + + pattrib->amsdu=0; + pattrib->ack_policy = 0; + //parsing QC field + if(pattrib->qos == 1) + { + pattrib->priority = GetPriority((ptr + 24)); + pattrib->ack_policy = GetAckpolicy((ptr + 24)); + pattrib->amsdu = GetAMsdu((ptr + 24)); + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 32 : 26; + + if(pattrib->priority!=0 && pattrib->priority!=3) + { + adapter->recvpriv.bIsAnyNonBEPkts = _TRUE; + } + } + else + { + pattrib->priority=0; + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24; + } + + + if(pattrib->order)//HT-CTRL 11n + { + pattrib->hdrlen += 4; + } + + precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; + + // decache, drop duplicate recv packets + if(recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decache : drop pkt\n")); + ret= _FAIL; + goto exit; + } + +#if 0 + if(psta->tdls_sta_state & TDLS_LINKED_STATE ) + { + if(psta->dot118021XPrivacy==_AES_) + pattrib->encrypt=psta->dot118021XPrivacy; + } +#endif //CONFIG_TDLS + + if(pattrib->privacy){ + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("validate_recv_data_frame:pattrib->privacy=%x\n", pattrib->privacy)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n ^^^^^^^^^^^IS_MCAST(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib->ra[0],IS_MCAST(pattrib->ra))); + +#ifdef CONFIG_TDLS + if((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy==_AES_)) + { + pattrib->encrypt=psta->dot118021XPrivacy; + } + else +#endif //CONFIG_TDLS + GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra)); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n pattrib->encrypt=%d\n",pattrib->encrypt)); + + SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); + } + else + { + pattrib->encrypt = 0; + pattrib->iv_len = pattrib->icv_len = 0; + } + +exit: + +_func_exit_; + + return ret; +} + +#ifdef CONFIG_IEEE80211W +static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_frame) +{ + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + u8 *ptr = precv_frame->u.hdr.rx_data; + u8 type; + u8 subtype; + + type = GetFrameType(ptr); + subtype = GetFrameSubType(ptr); //bit(7)~bit(2) + + //only support station mode + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) + && adapter->securitypriv.binstallBIPkey == _TRUE) + { + //unicast management frame decrypt + if(pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) && + (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) + { + u8 *ppp, *mgmt_DATA; + u32 data_len=0; + ppp = GetAddr2Ptr(ptr); + + pattrib->bdecrypted = 0; + pattrib->encrypt = _AES_; + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + //set iv and icv length + SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); + //actual management data frame body + data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + mgmt_DATA = rtw_zmalloc(data_len); + if(mgmt_DATA == NULL) + { + DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__); + goto validate_80211w_fail; + } + /*//dump the packet content before decrypt + { + int pp; + printk("pattrib->pktlen = %d =>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", ptr[pp]); + printk("\n"); + }*/ + + precv_frame = decryptor(adapter, precv_frame); + //save actual management data frame body + _rtw_memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len); + //overwrite the iv field + _rtw_memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len); + //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 + { + int pp; + printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", ptr[pp]); + printk("\n"); + }*/ + if(!precv_frame) + { + DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __FUNCTION__); + goto validate_80211w_fail; + } + } + else if(IS_MCAST(GetAddr1Ptr(ptr)) && + (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) + { + sint BIP_ret = _SUCCESS; + //verify BIP MME IE of broadcast/multicast de-auth/disassoc packet + BIP_ret = rtw_BIP_verify(adapter, (u8 * )precv_frame); + if(BIP_ret == _FAIL) + { + //DBG_871X("802.11w BIP verify fail\n"); + goto validate_80211w_fail; + } + 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); + goto validate_80211w_fail; + } + }//802.11w protect + else + { + if(subtype == WIFI_ACTION) + { + //according 802.11-2012 standard, these five types are not robust types + if( ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) + { + DBG_871X("action frame category=%d should robust\n", ptr[WLAN_HDR_A3_LEN]); + goto validate_80211w_fail; + } + } + 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); + goto validate_80211w_fail; + } + } + } + return _SUCCESS; + +validate_80211w_fail: + return _FAIL; + +} +#endif //CONFIG_IEEE80211W + +sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame); +sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame) +{ + //shall check frame subtype, to / from ds, da, bssid + + //then call check if rx seq/frag. duplicated. + + u8 type; + u8 subtype; + sint retval = _SUCCESS; + + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + + u8 *ptr = precv_frame->u.hdr.rx_data; + u8 ver =(unsigned char) (*ptr)&0x3 ; +#ifdef CONFIG_FIND_BEST_CHANNEL + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; +#endif + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#endif //CONFIG_TDLS + +_func_enter_; + + +#ifdef CONFIG_FIND_BEST_CHANNEL + if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { + int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter)); + if (ch_set_idx >= 0) + pmlmeext->channel_set[ch_set_idx].rx_count++; + } +#endif + +#ifdef CONFIG_TDLS + if(ptdlsinfo->ch_sensing==1 && ptdlsinfo->cur_channel !=0){ + ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel-1]++; + } +#endif //CONFIG_TDLS + +#ifdef RTK_DMP_PLATFORM + if ( 0 ) + { + DBG_871X("++\n"); + { + int i; + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + + } + DBG_871X("--\n"); + } +#endif //RTK_DMP_PLATFORM + + //add version chk + if(ver!=0){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! (ver!=0)\n")); + retval= _FAIL; + goto exit; + } + + type = GetFrameType(ptr); + subtype = GetFrameSubType(ptr); //bit(7)~bit(2) + + 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 0 //for debug + +if(pHalData->bDumpRxPkt ==1){ + int i; + DBG_871X("############################# \n"); + + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + DBG_871X("############################# \n"); +} +else if(pHalData->bDumpRxPkt ==2){ + if(type== WIFI_MGT_TYPE){ + int i; + DBG_871X("############################# \n"); + + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + DBG_871X("############################# \n"); + } +} +else if(pHalData->bDumpRxPkt ==3){ + if(type== WIFI_DATA_TYPE){ + int i; + DBG_871X("############################# \n"); + + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + DBG_871X("############################# \n"); + } +} + +#endif + switch (type) + { + case WIFI_MGT_TYPE: //mgnt +#ifdef CONFIG_IEEE80211W + if(validate_80211w_mgmt(adapter, precv_frame) == _FAIL) + { + retval = _FAIL; + break; + } +#endif //CONFIG_IEEE80211W + + retval = validate_recv_mgnt_frame(adapter, precv_frame); + if (retval == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_mgnt_frame fail\n")); + } + retval = _FAIL; // only data frame return _SUCCESS + break; + case WIFI_CTRL_TYPE: //ctrl + retval = validate_recv_ctrl_frame(adapter, precv_frame); + if (retval == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_ctrl_frame fail\n")); + } + retval = _FAIL; // only data frame return _SUCCESS + break; + case WIFI_DATA_TYPE: //data + rtw_led_control(adapter, LED_CTL_RX); + pattrib->qos = (subtype & BIT(7))? 1:0; + retval = validate_recv_data_frame(adapter, precv_frame); + if (retval == _FAIL) + { + struct recv_priv *precvpriv = &adapter->recvpriv; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail\n")); + precvpriv->rx_drop++; + } + break; + default: + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! type=0x%x\n", type)); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type=0x%x\n", type); + #endif + retval = _FAIL; + break; + } + +exit: + +_func_exit_; + + return retval; +} + + +//remove the wlanhdr and add the eth_hdr +#if 1 + +sint wlanhdr_to_ethhdr ( union recv_frame *precvframe); +sint wlanhdr_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; + + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) + { + ptr += rmv_len ; + *ptr = 0x87; + *(ptr+1) = 0x12; + + eth_type = 0x8712; + // append rx status for mp test packets + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); + _rtw_memcpy(ptr, get_rxmem(precvframe), 24); + ptr+=24; + } + else { + 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); + } + +_func_exit_; + return ret; + +} + +#else + +sint wlanhdr_to_ethhdr ( union recv_frame *precvframe) +{ + sint rmv_len; + u16 eth_type; + 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; + struct _vlan *pvlan = NULL; + +_func_enter_; + + psnap=(struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); + psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + if (psnap->dsap==0xaa && psnap->ssap==0xaa && psnap->ctrl==0x03) + { + if (_rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)) + bsnaphdr=_TRUE;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042; + else if (_rtw_memcmp(psnap->oui, SNAP_HDR_APPLETALK_DDP, WLAN_IEEE_OUI_LEN) && + _rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_DDP, 2) ) + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK; + else if (_rtw_memcmp( psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN)) + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL; + else { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("drop pkt due to invalid frame format!\n")); + ret= _FAIL; + goto exit; + } + + } else + bsnaphdr=_FALSE;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS; + + rmv_len = pattrib->hdrlen + pattrib->iv_len +(bsnaphdr?SNAP_SIZE:0); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n", pattrib->hdrlen, pattrib->iv_len)); + + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + ptr += rmv_len ; + *ptr = 0x87; + *(ptr+1) = 0x12; + + //back to original pointer + ptr -= rmv_len; + } + + ptr += rmv_len ; + + _rtw_memcpy(ð_type, ptr, 2); + eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type + ptr +=2; + + if(pattrib->encrypt){ + recvframe_pull_tail(precvframe, pattrib->icv_len); + } + + if(eth_type == 0x8100) //vlan + { + pvlan = (struct _vlan *) ptr; + + //eth_type = get_vlan_encap_proto(pvlan); + //eth_type = pvlan->h_vlan_encapsulated_proto;//? + rmv_len += 4; + ptr+=4; + } + + if(eth_type==0x0800)//ip + { + //struct iphdr* piphdr = (struct iphdr*) ptr; + //__u8 tos = (unsigned char)(pattrib->priority & 0xff); + + //piphdr->tos = tos; + + //if (piphdr->protocol == 0x06) + //{ + // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", precvframe->u.hdr.len)); + //} + } + else if(eth_type==0x8712)// append rx status for mp test packets + { + //ptr -= 16; + //_rtw_memcpy(ptr, get_rxmem(precvframe), 16); + } + else + { +#ifdef PLATFORM_OS_XP + NDIS_PACKET_8021Q_INFO VlanPriInfo; + UINT32 UserPriority = precvframe->u.hdr.attrib.priority; + UINT32 VlanID = (pvlan!=NULL ? get_vlan_id(pvlan) : 0 ); + + VlanPriInfo.Value = // Get current value. + NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo); + + VlanPriInfo.TagHeader.UserPriority = UserPriority; + VlanPriInfo.TagHeader.VlanId = VlanID ; + + VlanPriInfo.TagHeader.CanonicalFormatId = 0; // Should be zero. + VlanPriInfo.TagHeader.Reserved = 0; // Should be zero. + NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo) = VlanPriInfo.Value; +#endif + } + + if(eth_type==0x8712)// append rx status for mp test packets + { + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); + _rtw_memcpy(ptr, get_rxmem(precvframe), 24); + ptr+=24; + } + else + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)); + + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); + + eth_type = htons((unsigned short)eth_type) ; + _rtw_memcpy(ptr+12, ð_type, 2); + +exit: + +_func_exit_; + + return ret; +} +#endif + + +#ifdef CONFIG_SDIO_HCI +#ifdef PLATFORM_LINUX +static void recvframe_expand_pkt( + PADAPTER padapter, + union recv_frame *prframe) +{ + struct recv_frame_hdr *pfhdr; + _pkt *ppkt; + u8 shift_sz; + u32 alloc_sz; + + + pfhdr = &prframe->u.hdr; + + // 6 is for IP header 8 bytes alignment in QoS packet case. + if (pfhdr->attrib.qos) + shift_sz = 6; + else + shift_sz = 0; + + // for first fragment packet, need to allocate + // (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet + // 8 is for skb->data 8 bytes alignment. +// alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); + alloc_sz = 1664; // round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment + + //3 1. alloc new skb + // prepare extra space for 4 bytes alignment + ppkt = rtw_skb_alloc(alloc_sz); + + if (!ppkt) return; // no way to expand + + //3 2. Prepare new skb to replace & release old skb + // force ppkt->data at 8-byte alignment address + skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7)); + // force ip_hdr at 8-byte alignment address according to shift_sz + skb_reserve(ppkt, shift_sz); + + // copy data to new pkt + _rtw_memcpy(skb_put(ppkt, pfhdr->len), pfhdr->rx_data, pfhdr->len); + + rtw_skb_free(pfhdr->pkt); + + // attach new pkt to recvframe + pfhdr->pkt = ppkt; + pfhdr->rx_head = ppkt->head; + pfhdr->rx_data = ppkt->data; + pfhdr->rx_tail = skb_tail_pointer(ppkt); + pfhdr->rx_end = skb_end_pointer(ppkt); +} +#else +#warning "recvframe_expand_pkt not implement, defrag may crash system" +#endif +#endif + +//perform defrag +union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q); +union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q) +{ + _list *plist, *phead; + u8 *data,wlanhdr_offset; + u8 curfragnum; + struct recv_frame_hdr *pfhdr,*pnfhdr; + union recv_frame* prframe, *pnextrframe; + _queue *pfree_recv_queue; + +_func_enter_; + + curfragnum=0; + pfree_recv_queue=&adapter->recvpriv.free_recv_queue; + + phead = get_list_head(defrag_q); + plist = get_next(phead); + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pfhdr=&prframe->u.hdr; + rtw_list_delete(&(prframe->u.list)); + + if(curfragnum!=pfhdr->attrib.frag_num) + { + //the first fragment number must be 0 + //free the whole queue + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + + return NULL; + } + +#ifdef CONFIG_SDIO_HCI + recvframe_expand_pkt(adapter, prframe); +#endif + + curfragnum++; + + plist= get_list_head(defrag_q); + + plist = get_next(plist); + + data=get_recvframe_data(prframe); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u); + pnfhdr=&pnextrframe->u.hdr; + + + //check the fragment sequence (2nd ~n fragment frame) + + if(curfragnum!=pnfhdr->attrib.frag_num) + { + //the fragment number must be increasing (after decache) + //release the defrag_q & prframe + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + return NULL; + } + + curfragnum++; + + //copy the 2nd~n fragment frame's payload to the first fragment + //get the 2nd~last fragment frame's payload + + wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; + + recvframe_pull(pnextrframe, wlanhdr_offset); + + //append to first fragment frame's tail (if privacy frame, pull the ICV) + recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); + + //memcpy + _rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); + + recvframe_put(prframe, pnfhdr->len); + + pfhdr->attrib.icv_len=pnfhdr->attrib.icv_len; + plist = get_next(plist); + + }; + + //free the defrag_q queue and return the prframe + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Performance defrag!!!!!\n")); + +_func_exit_; + + return prframe; +} + +//check if need to defrag, if needed queue the frame to defrag_q +union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame) +{ + u8 ismfrag; + u8 fragnum; + u8 *psta_addr; + struct recv_frame_hdr *pfhdr; + struct sta_info *psta; + struct sta_priv *pstapriv; + _list *phead; + union recv_frame *prtnframe = NULL; + _queue *pfree_recv_queue, *pdefrag_q; + +_func_enter_; + + pstapriv = &padapter->stapriv; + + pfhdr = &precv_frame->u.hdr; + + pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + + //need to define struct of wlan header frame ctrl + ismfrag = pfhdr->attrib.mfrag; + fragnum = pfhdr->attrib.frag_num; + + psta_addr = pfhdr->attrib.ta; + psta = rtw_get_stainfo(pstapriv, psta_addr); + if (psta == NULL) + { + u8 type = GetFrameType(pfhdr->rx_data); + if (type != WIFI_DATA_TYPE) { + psta = rtw_get_bcmc_stainfo(padapter); + pdefrag_q = &psta->sta_recvpriv.defrag_q; + } else + pdefrag_q = NULL; + } + else + pdefrag_q = &psta->sta_recvpriv.defrag_q; + + if ((ismfrag==0) && (fragnum==0)) + { + prtnframe = precv_frame;//isn't a fragment frame + } + + if (ismfrag==1) + { + //0~(n-1) fragment frame + //enqueue to defraf_g + if(pdefrag_q != NULL) + { + if(fragnum==0) + { + //the first fragment + if(_rtw_queue_empty(pdefrag_q) == _FALSE) + { + //free current defrag_q + rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue); + } + } + + + //Then enqueue the 0~(n-1) fragment into the defrag_q + + //_rtw_spinlock(&pdefrag_q->lock); + phead = get_list_head(pdefrag_q); + rtw_list_insert_tail(&pfhdr->list, phead); + //_rtw_spinunlock(&pdefrag_q->lock); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum)); + + prtnframe=NULL; + + } + else + { + //can't find this ta's defrag_queue, so free this recv_frame + rtw_free_recvframe(precv_frame, pfree_recv_queue); + prtnframe=NULL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum)); + } + + } + + if((ismfrag==0)&&(fragnum!=0)) + { + //the last fragment frame + //enqueue the last fragment + if(pdefrag_q != NULL) + { + //_rtw_spinlock(&pdefrag_q->lock); + phead = get_list_head(pdefrag_q); + rtw_list_insert_tail(&pfhdr->list,phead); + //_rtw_spinunlock(&pdefrag_q->lock); + + //call recvframe_defrag to defrag + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("defrag: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum)); + precv_frame = recvframe_defrag(padapter, pdefrag_q); + prtnframe=precv_frame; + + } + else + { + //can't find this ta's defrag_queue, so free this recv_frame + rtw_free_recvframe(precv_frame, pfree_recv_queue); + prtnframe=NULL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum)); + } + + } + + + if((prtnframe!=NULL)&&(prtnframe->u.hdr.attrib.privacy)) + { + //after defrag we must check tkip mic code + if(recvframe_chkmic(padapter, prtnframe)==_FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic(padapter, prtnframe)==_FAIL\n")); + rtw_free_recvframe(prtnframe,pfree_recv_queue); + prtnframe=NULL; + } + } + +_func_exit_; + + return prtnframe; + +} + +#define ENDIAN_FREE 1 + +int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe); +int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) +{ +#if defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD) //for amsdu TP improvement,Creator: Thomas + int a_len, padding_len; + u16 eth_type, nSubframe_Length; + u8 nr_subframes, i; + unsigned char *pdata; + struct rx_pkt_attrib *pattrib; +#ifndef PLATFORM_FREEBSD + unsigned char *data_ptr; + _pkt *sub_skb,*subframes[MAX_SUBFRAME_COUNT]; +#endif //PLATFORM_FREEBSD + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &(precvpriv->free_recv_queue); + int ret = _SUCCESS; +#ifdef PLATFORM_FREEBSD + struct mbuf *sub_m=NULL, *subframes[MAX_SUBFRAME_COUNT]; + u8 *ptr,offset; +#endif //PLATFORM_FREEBSD + nr_subframes = 0; + + pattrib = &prframe->u.hdr.attrib; + + recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); + + if(prframe->u.hdr.attrib.iv_len >0) + { + recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); + } + + a_len = prframe->u.hdr.len; + + pdata = prframe->u.hdr.rx_data; + + while(a_len > ETH_HLEN) { + + /* Offset 12 denote 2 mac address */ +#ifdef ENDIAN_FREE + //nSubframe_Length = ntohs(*((u16*)(pdata + 12))); + nSubframe_Length = RTW_GET_BE16(pdata + 12); +#else // ENDIAN_FREE + nSubframe_Length = *((u16*)(pdata + 12)); + //==m==>change the length order + nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8); + //ntohs(nSubframe_Length); +#endif // ENDIAN_FREE + + if( a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length) ) { + DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n",a_len,nSubframe_Length); + goto exit; + } + +#ifndef PLATFORM_FREEBSD + /* move the data point to data content */ + pdata += ETH_HLEN; + a_len -= ETH_HLEN; + + /* Allocate new skb for releasing to upper layer */ +#ifdef CONFIG_SKB_COPY + sub_skb = rtw_skb_alloc(nSubframe_Length + 12); + if(sub_skb) + { + skb_reserve(sub_skb, 12); + data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); + _rtw_memcpy(data_ptr, pdata, nSubframe_Length); + } + else +#endif // CONFIG_SKB_COPY + { + sub_skb = rtw_skb_clone(prframe->u.hdr.pkt); + if(sub_skb) + { + sub_skb->data = pdata; + sub_skb->len = nSubframe_Length; + skb_set_tail_pointer(sub_skb, nSubframe_Length); + } + else + { + DBG_871X("rtw_skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes); + break; + } + } + +#else // PLATFORM_FREEBSD + + //PLATFORM_FREEBSD + //Allocate a mbuff, + //sub_m =m_devget(pdata, nSubframe_Length+12, 12, padapter->pifp,NULL); + sub_m =m_devget(pdata, nSubframe_Length+ETH_HLEN, ETHER_ALIGN, padapter->pifp,NULL); + + pdata += ETH_HLEN; + a_len -= ETH_HLEN; +#endif // PLATFORM_FREEBSD + +#ifndef PLATFORM_FREEBSD + //sub_skb->dev = padapter->pnetdev; + subframes[nr_subframes++] = sub_skb; +#else //PLATFORM_FREEBSD + //PLATFORM_FREEBSD + subframes[nr_subframes++] = sub_m; +#endif //PLATFORM_FREEBSD + + if(nr_subframes >= MAX_SUBFRAME_COUNT) { + DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n"); + break; + } + + pdata += nSubframe_Length; + a_len -= nSubframe_Length; + if(a_len != 0) { + padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1)); + if(padding_len == 4) { + padding_len = 0; + } + + if(a_len < padding_len) { + goto exit; + } + pdata += padding_len; + a_len -= padding_len; + } + } + + for(i=0; idata[6]); + eth_type = RTW_GET_BE16(&sub_skb->data[6]); +#else // ENDIAN_FREE + eth_type = (sub_skb->data[6] << 8) | sub_skb->data[7]; +#endif // ENDIAN_FREE + if (sub_skb->len >= 8 && + ((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) && + eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || + _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE) )) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + _rtw_memcpy(skb_push(sub_skb, 2), &len, 2); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); + } + + /* Indicat the packets to upper layer */ + if (sub_skb) { + //memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); + +#ifdef CONFIG_BR_EXT + // Insert NAT2.5 RX here! + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + void *br_port = NULL; + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + + + if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) + { + int nat25_handle_frame(_adapter *priv, struct sk_buff *skb); + if (nat25_handle_frame(padapter, sub_skb) == -1) { + //priv->ext_stats.rx_data_drops++; + //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); + //return FAIL; + +#if 1 + // bypass this frame to upper layer!! +#else + rtw_skb_free(sub_skb); + continue; +#endif + } + } +#endif // CONFIG_BR_EXT + + sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev); + sub_skb->dev = padapter->pnetdev; + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { + sub_skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + sub_skb->ip_summed = CHECKSUM_NONE; + } +#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ + sub_skb->ip_summed = CHECKSUM_NONE; +#endif //CONFIG_TCP_CSUM_OFFLOAD_RX + + rtw_netif_rx(padapter->pnetdev, sub_skb); + } +#else //PLATFORM_FREEBSD + + //PLATFORM_FREEBSD + sub_m = subframes[i]; + ptr=mtod(sub_m, u8 *); + offset=ETH_HLEN; + /* convert hdr + possible LLC headers into Ethernet header */ +#ifdef ENDIAN_FREE + eth_type = ntohs(*(u16*)&ptr[offset+6]); +#else // ENDIAN_FREE + eth_type = ( ptr[offset+6] << 8) | ptr[offset+7]; +#endif // ENDIAN_FREE + if (sub_m->m_pkthdr.len >= ETH_HLEN+8 && + ((_rtw_memcmp(ptr+ETH_HLEN, rtw_rfc1042_header, SNAP_SIZE) && + eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || + _rtw_memcmp(ptr+ETH_HLEN, rtw_bridge_tunnel_header, SNAP_SIZE) )) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + offset+=SNAP_SIZE; + _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->src, ETH_ALEN); + offset-=ETH_ALEN; + _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->dst, ETH_ALEN); + offset-=ETH_ALEN; + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_m->m_pkthdr.len-offset); + _rtw_memcpy(&ptr[offset- 2], &len, 2); + offset-=2; + _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->src, ETH_ALEN); + offset-=ETH_ALEN; + _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->dst, ETH_ALEN); + offset-=ETH_ALEN; + } + + m_adj(sub_m,offset); + + /* Indicat the packets to upper layer */ + if (sub_m) { + +#if 0 +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { + sub_skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + sub_skb->ip_summed = CHECKSUM_NONE; + } +#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ + sub_skb->ip_summed = CHECKSUM_NONE; +#endif //CONFIG_TCP_CSUM_OFFLOAD_RX +#endif //0 + + if ( ((u32)(mtod(sub_m, caddr_t) + 14) % 4) != 0) + printf("%s()-%d: mtod(sub_m) = %p\n", __FUNCTION__, __LINE__, mtod(sub_m, caddr_t)); +#ifdef CONFIG_RX_INDICATE_QUEUE + IF_ENQUEUE(&precvpriv->rx_indicate_queue, sub_m); + if (_IF_QLEN(&precvpriv->rx_indicate_queue) <= 1) { + taskqueue_enqueue(taskqueue_thread, &precvpriv->rx_indicate_tasklet); + } +#else // CONFIG_RX_INDICATE_QUEUE + (*padapter->pifp->if_input)(padapter->pifp, sub_m); +#endif // CONFIG_RX_INDICATE_QUEUE + } + +#endif //PLATFORM_FREEBSD + } + +exit: + + prframe->u.hdr.len=0; + rtw_free_recvframe(prframe, pfree_recv_queue);//free this recv_frame + + return ret; +#else // || defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD) +#ifdef PLATFORM_WINDOWS + _irqL irql; +#endif //PLATFORM_WINDOWS + unsigned char *ptr, *pdata, *pbuf, *psnap_type; + union recv_frame *pnrframe, *pnrframe_new; + int a_len, mv_len, padding_len; + u16 eth_type, type_len; + u8 bsnaphdr; + struct ieee80211_snap_hdr *psnap; + struct _vlan *pvlan; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &(precvpriv->free_recv_queue); + int ret = _SUCCESS; +#ifdef PLATFORM_WINDOWS + struct recv_buf *precvbuf = prframe->u.hdr.precvbuf; +#endif //PLATFORM_WINDOWS + a_len = prframe->u.hdr.len - prframe->u.hdr.attrib.hdrlen; + + recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); + + if(prframe->u.hdr.attrib.iv_len >0) + { + recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); + } + + pdata = prframe->u.hdr.rx_data; + + prframe->u.hdr.len=0; + + pnrframe = prframe; + + + do{ + + mv_len=0; + pnrframe->u.hdr.rx_data = pnrframe->u.hdr.rx_tail = pdata; + ptr = pdata; + + + _rtw_memcpy(pnrframe->u.hdr.attrib.dst, ptr, ETH_ALEN); + ptr+=ETH_ALEN; + _rtw_memcpy(pnrframe->u.hdr.attrib.src, ptr, ETH_ALEN); + ptr+=ETH_ALEN; + + _rtw_memcpy(&type_len, ptr, 2); + type_len= ntohs((unsigned short )type_len); + ptr +=2; + mv_len += ETH_HLEN; + + recvframe_put(pnrframe, type_len+ETH_HLEN);//update tail; + + if(pnrframe->u.hdr.rx_data >= pnrframe->u.hdr.rx_tail || type_len<8) + { + //panic("pnrframe->u.hdr.rx_data >= pnrframe->u.hdr.rx_tail || type_len<8\n"); + + rtw_free_recvframe(pnrframe, pfree_recv_queue); + + goto exit; + } + + psnap=(struct ieee80211_snap_hdr *)(ptr); + psnap_type=ptr+SNAP_SIZE; + if (psnap->dsap==0xaa && psnap->ssap==0xaa && psnap->ctrl==0x03) + { + if ( _rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)) + { + bsnaphdr=_TRUE;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042; + } + else if (_rtw_memcmp(psnap->oui, SNAP_HDR_APPLETALK_DDP, WLAN_IEEE_OUI_LEN) && + _rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_DDP, 2) ) + { + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK; + } + else if (_rtw_memcmp( psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN)) + { + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL; + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("drop pkt due to invalid frame format!\n")); + + //KeBugCheckEx(0x87123333, 0xe0, 0x4c, 0x87, 0xdd); + + //panic("0x87123333, 0xe0, 0x4c, 0x87, 0xdd\n"); + + rtw_free_recvframe(pnrframe, pfree_recv_queue); + + goto exit; + } + + } + else + { + bsnaphdr=_FALSE;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS; + } + + ptr += (bsnaphdr?SNAP_SIZE:0); + _rtw_memcpy(ð_type, ptr, 2); + eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type + + mv_len+= 2+(bsnaphdr?SNAP_SIZE:0); + ptr += 2;//now move to iphdr; + + pvlan = NULL; + if(eth_type == 0x8100) //vlan + { + pvlan = (struct _vlan *)ptr; + ptr+=4; + mv_len+=4; + } + + if(eth_type==0x0800)//ip + { + struct iphdr* piphdr = (struct iphdr*)ptr; + + + if (piphdr->protocol == 0x06) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", pnrframe->u.hdr.len)); + } + } +#ifdef PLATFORM_OS_XP + else + { + NDIS_PACKET_8021Q_INFO VlanPriInfo; + UINT32 UserPriority = pnrframe->u.hdr.attrib.priority; + UINT32 VlanID = (pvlan!=NULL ? get_vlan_id(pvlan) : 0 ); + + VlanPriInfo.Value = // Get current value. + NDIS_PER_PACKET_INFO_FROM_PACKET(pnrframe->u.hdr.pkt, Ieee8021QInfo); + + VlanPriInfo.TagHeader.UserPriority = UserPriority; + VlanPriInfo.TagHeader.VlanId = VlanID; + + VlanPriInfo.TagHeader.CanonicalFormatId = 0; // Should be zero. + VlanPriInfo.TagHeader.Reserved = 0; // Should be zero. + NDIS_PER_PACKET_INFO_FROM_PACKET(pnrframe->u.hdr.pkt, Ieee8021QInfo) = VlanPriInfo.Value; + + } +#endif //PLATFORM_OS_XP + + pbuf = recvframe_pull(pnrframe, (mv_len-sizeof(struct ethhdr))); + + _rtw_memcpy(pbuf, pnrframe->u.hdr.attrib.dst, ETH_ALEN); + _rtw_memcpy(pbuf+ETH_ALEN, pnrframe->u.hdr.attrib.src, ETH_ALEN); + + eth_type = htons((unsigned short)eth_type) ; + _rtw_memcpy(pbuf+12, ð_type, 2); + + padding_len = (4) - ((type_len + ETH_HLEN)&(4-1)); + + a_len -= (type_len + ETH_HLEN + padding_len) ; + + +#if 0 + + if(a_len > ETH_HLEN) + { + pnrframe_new = rtw_alloc_recvframe(pfree_recv_queue); + if(pnrframe_new) + { + _pkt *pskb_copy; + unsigned int copy_len = pnrframe->u.hdr.len; + + _rtw_init_listhead(&pnrframe_new->u.hdr.list); + + pskb_copy = rtw_skb_alloc(copy_len+64); + + if(pskb_copy==NULL) + { + DBG_871X("amsdu_to_msdu:can not all(ocate memory for skb copy\n"); + } + + pnrframe_new->u.hdr.pkt = pskb_copy; + + _rtw_memcpy(pskb_copy->data, pnrframe->u.hdr.rx_data, copy_len); + + pnrframe_new->u.hdr.rx_data = pnrframe->u.hdr.rx_data; + pnrframe_new->u.hdr.rx_tail = pnrframe->u.hdr.rx_data + copy_len; + + + if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE)) + { + rtw_recv_indicatepkt(padapter, pnrframe_new);//indicate this recv_frame + } + else + { + rtw_free_recvframe(pnrframe_new, pfree_recv_queue);//free this recv_frame + } + + } + else + { + DBG_871X("amsdu_to_msdu:can not allocate memory for pnrframe_new\n"); + } + + } + else + { + if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE)) + { + rtw_recv_indicatepkt(padapter, pnrframe);//indicate this recv_frame + } + else + { + rtw_free_recvframe(pnrframe, pfree_recv_queue);//free this recv_frame + } + + pnrframe = NULL; + + } + +#else // 0 + + //padding_len = (4) - ((type_len + ETH_HLEN)&(4-1)); + + //a_len -= (type_len + ETH_HLEN + padding_len) ; + + pnrframe_new = NULL; + + + if(a_len > ETH_HLEN) + { + pnrframe_new = rtw_alloc_recvframe(pfree_recv_queue); + + if(pnrframe_new) + { + + + //pnrframe_new->u.hdr.precvbuf = precvbuf;//precvbuf is assigned before call rtw_init_recvframe() + //rtw_init_recvframe(pnrframe_new, precvpriv); + { +#ifdef PLATFORM_LINUX + _pkt *pskb = pnrframe->u.hdr.pkt; +#endif //PLATFORM_LINUX + _rtw_init_listhead(&pnrframe_new->u.hdr.list); + + pnrframe_new->u.hdr.len=0; + +#ifdef PLATFORM_LINUX + if(pskb) + { + pnrframe_new->u.hdr.pkt = rtw_skb_clone(pskb); + } +#endif //PLATFORM_LINUX + + } + + pdata += (type_len + ETH_HLEN + padding_len); + pnrframe_new->u.hdr.rx_head = pnrframe_new->u.hdr.rx_data = pnrframe_new->u.hdr.rx_tail = pdata; + pnrframe_new->u.hdr.rx_end = pdata + a_len + padding_len;// + +#ifdef PLATFORM_WINDOWS + pnrframe_new->u.hdr.precvbuf=precvbuf; + _enter_critical_bh(&precvbuf->recvbuf_lock, &irql); + precvbuf->ref_cnt++; + _exit_critical_bh(&precvbuf->recvbuf_lock, &irql); +#endif //PLATFORM_WINDOWS + + } + else + { + //panic("pnrframe_new=%x\n", pnrframe_new); + } + } + + + if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE) ) + { + rtw_recv_indicatepkt(padapter, pnrframe);//indicate this recv_frame + } + else + { + rtw_free_recvframe(pnrframe, pfree_recv_queue);//free this recv_frame + } + + + pnrframe = NULL; + if(pnrframe_new) + { + pnrframe = pnrframe_new; + } + + +#endif // end defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD) + + }while(pnrframe); + +exit: + + return ret; +#endif +} + +int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num); +int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) +{ + u8 wsize = preorder_ctrl->wsize_b; + u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;//% 4096; + + // Rx Reorder initialize condition. + if (preorder_ctrl->indicate_seq == 0xFFFF) + { + preorder_ctrl->indicate_seq = seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + + //DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq); + } + + //DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + // Drop out the packet which SeqNum is smaller than WinStart + if( SN_LESS(seq_num, preorder_ctrl->indicate_seq) ) + { + //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); + //DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__, + preorder_ctrl->indicate_seq, seq_num); + #endif + + + return _FALSE; + } + + // + // Sliding window manipulation. Conditions includes: + // 1. Incoming SeqNum is equal to WinStart =>Window shift 1 + // 2. Incoming SeqNum is larger than the WinEnd => Window shift N + // + if( SN_EQUAL(seq_num, preorder_ctrl->indicate_seq) ) + { + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + } + else if(SN_LESS(wend, seq_num)) + { + //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); + //DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + // boundary situation, when seq_num cross 0xFFF + if(seq_num >= (wsize - 1)) + preorder_ctrl->indicate_seq = seq_num + 1 -wsize; + else + preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; + + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + } + + //DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + return _TRUE; +} + +int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe); +int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe) +{ + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + _list *phead, *plist; + union recv_frame *pnextrframe; + struct rx_pkt_attrib *pnextattrib; + + //DbgPrint("+enqueue_reorder_recvframe()\n"); + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); + pnextattrib = &pnextrframe->u.hdr.attrib; + + if(SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) + { + plist = get_next(plist); + } + else if( SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) + { + //Duplicate entry is found!! Do not insert current entry. + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); + + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + return _FALSE; + } + else + { + break; + } + + //DbgPrint("enqueue_reorder_recvframe():while\n"); + + } + + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + rtw_list_delete(&(prframe->u.hdr.list)); + + rtw_list_insert_tail(&(prframe->u.hdr.list), plist); + + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); + return _TRUE; + +} + +int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced); +int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced) +{ + //_irqL irql; + //u8 bcancelled; + _list *phead, *plist; + union recv_frame *prframe; + struct rx_pkt_attrib *pattrib; + //u8 index = 0; + int bPktInBuf = _FALSE; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + //DbgPrint("+recv_indicatepkts_in_order\n"); + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + +#if 0 + // Check if there is any other indication thread running. + if(pTS->RxIndicateState == RXTS_INDICATE_PROCESSING) + return; +#endif + + // Handling some condition for forced indicate case. + if(bforced==_TRUE) + { + if(rtw_is_list_empty(phead)) + { + // _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + return _TRUE; + } + + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pattrib = &prframe->u.hdr.attrib; + preorder_ctrl->indicate_seq = pattrib->seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + } + + // Prepare indication list and indication. + // Check if there is any packet need indicate. + while(!rtw_is_list_empty(phead)) + { + + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pattrib = &prframe->u.hdr.attrib; + + if(!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, + ("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n", + preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu)); + +#if 0 + // This protect buffer from overflow. + if(index >= REORDER_WIN_SIZE) + { + RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!! \n")); + bPktInBuf = TRUE; + break; + } +#endif + + plist = get_next(plist); + rtw_list_delete(&(prframe->u.hdr.list)); + + if(SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) + { + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + } + +#if 0 + index++; + if(index==1) + { + //Cancel previous pending timer. + //PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer); + if(bforced!=_TRUE) + { + //DBG_871X("_cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);\n"); + _cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled); + } + } +#endif + + //Set this as a lock to make sure that only one thread is indicating packet. + //pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; + + // Indicate packets + //RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!! \n")); + + + //indicate this recv_frame + //DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num); + if(!pattrib->amsdu) + { + //DBG_871X("recv_indicatepkts_in_order, amsdu!=1, indicate_seq=%d, seq_num=%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num); + + if ((padapter->bDriverStopped == _FALSE) && + (padapter->bSurpriseRemoved == _FALSE)) + { + + rtw_recv_indicatepkt(padapter, prframe);//indicate this recv_frame + + } + } + else if(pattrib->amsdu==1) + { + if(amsdu_to_msdu(padapter, prframe)!=_SUCCESS) + { + rtw_free_recvframe(prframe, &precvpriv->free_recv_queue); + } + } + else + { + //error condition; + } + + + //Update local variables. + bPktInBuf = _FALSE; + + } + else + { + bPktInBuf = _TRUE; + break; + } + + //DbgPrint("recv_indicatepkts_in_order():while\n"); + + } + + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + +/* + //Release the indication lock and set to new indication step. + if(bPktInBuf) + { + // Set new pending timer. + //pTS->RxIndicateState = RXTS_INDICATE_REORDER; + //PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime); + //DBG_871X("_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME)\n"); + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + } + else + { + //pTS->RxIndicateState = RXTS_INDICATE_IDLE; + } +*/ + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + //return _TRUE; + return bPktInBuf; + +} + +int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe); +int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe) +{ + _irqL irql; + int retval = _SUCCESS; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + if(!pattrib->amsdu) + { + //s1. + wlanhdr_to_ethhdr(prframe); + + //if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/ + // || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0)) + if (pattrib->qos!=1) + { + if ((padapter->bDriverStopped == _FALSE) && + (padapter->bSurpriseRemoved == _FALSE)) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n" )); + + rtw_recv_indicatepkt(padapter, prframe); + return _SUCCESS; + + } + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__); + #endif + + return _FAIL; + + } + + if (preorder_ctrl->enable == _FALSE) + { + //indicate this recv_frame + preorder_ctrl->indicate_seq = pattrib->seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + rtw_recv_indicatepkt(padapter, prframe); + + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + return _SUCCESS; + } + +#ifndef CONFIG_RECV_REORDERING_CTRL + //indicate this recv_frame + rtw_recv_indicatepkt(padapter, prframe); + return _SUCCESS; +#endif + + } + else if(pattrib->amsdu==1) //temp filter -> means didn't support A-MSDUs in a A-MPDU + { + if (preorder_ctrl->enable == _FALSE) + { + preorder_ctrl->indicate_seq = pattrib->seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + retval = amsdu_to_msdu(padapter, prframe); + + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + if(retval != _SUCCESS){ + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__); + #endif + } + + return retval; + } + } + else + { + + } + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irql); + + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, + ("recv_indicatepkt_reorder: indicate=%d seq=%d\n", + preorder_ctrl->indicate_seq, pattrib->seq_num)); + + //s2. check if winstart_b(indicate_seq) needs to been updated + if(!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) + { + //pHTInfo->RxReorderDropCounter++; + //ReturnRFDList(Adapter, pRfd); + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("RxReorderIndicatePacket() ==> Packet Drop!!\n")); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //return _FAIL; + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__); + #endif +#if 0 + rtw_recv_indicatepkt(padapter, prframe); + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + + goto _success_exit; +#else + goto _err_exit; +#endif + } + + + //s3. Insert all packet into Reorder Queue to maintain its ordering. + if(!enqueue_reorder_recvframe(preorder_ctrl, prframe)) + { + //DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //return _FAIL; + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__); + #endif + goto _err_exit; + } + + + //s4. + // Indication process. + // After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets + // with the SeqNum smaller than latest WinStart and buffer other packets. + // + // For Rx Reorder condition: + // 1. All packets with SeqNum smaller than WinStart => Indicate + // 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. + // + + //recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); + if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE)==_TRUE) + { + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + } + else + { + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + } + + +_success_exit: + + return _SUCCESS; + +_err_exit: + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + + return _FAIL; +} + + +void rtw_reordering_ctrl_timeout_handler(void *pcontext) +{ + _irqL irql; + struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; + _adapter *padapter = preorder_ctrl->padapter; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + + if(padapter->bDriverStopped ||padapter->bSurpriseRemoved) + { + return; + } + + //DBG_871X("+rtw_reordering_ctrl_timeout_handler()=>\n"); + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irql); + + if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE)==_TRUE) + { + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + } + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + +} + +int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe); +int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe) +{ + int retval = _SUCCESS; + //struct recv_priv *precvpriv = &padapter->recvpriv; + //struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_TDLS + struct sta_info *psta = prframe->u.hdr.psta; +#endif //CONFIG_TDLS + +#ifdef CONFIG_80211N_HT + + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + +#ifdef CONFIG_TDLS + if( (phtpriv->ht_option==_TRUE) || + ((psta->tdls_sta_state & TDLS_LINKED_STATE) && + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE))) //B/G/N Mode +#else + if(phtpriv->ht_option==_TRUE) //B/G/N Mode +#endif //CONFIG_TDLS + { + //prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; + + if(recv_indicatepkt_reorder(padapter, prframe)!=_SUCCESS)// including perform A-MPDU Rx Ordering Buffer Control + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__); + #endif + + if ((padapter->bDriverStopped == _FALSE) && + (padapter->bSurpriseRemoved == _FALSE)) + { + retval = _FAIL; + return retval; + } + } + } + else //B/G mode +#endif + { + 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 ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE)) + { + //indicate this recv_frame + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n" )); + rtw_recv_indicatepkt(padapter, prframe); + + + } + else + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n" )); + + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + retval = _FAIL; + return retval; + } + + } + + return retval; + +} + +int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) +{ + int ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + +#ifdef CONFIG_MP_INCLUDED + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //CONFIG_MP_INCLUDED + +#ifdef CONFIG_MP_INCLUDED + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) + { + if (pattrib->crc_err == 1) + padapter->mppriv.rx_crcerrpktcount++; + else + padapter->mppriv.rx_pktcount++; + + 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; + } + } +#endif + + //check the frame crtl field and decache + ret = validate_recv_frame(padapter, rframe); + if (ret != _SUCCESS) + { + 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 + goto exit; + } + +exit: + return ret; +} + +int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe) +{ + int ret = _SUCCESS; + union recv_frame *orig_prframe = prframe; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + +#ifdef CONFIG_MP_INCLUDED + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //CONFIG_MP_INCLUDED + +#ifdef CONFIG_TDLS + u8 *psnap_type, *pcategory; + struct sta_info *ptdls_sta = NULL; +#endif //CONFIG_TDLS + + + // DATA FRAME + rtw_led_control(padapter, LED_CTL_RX); + + prframe = decryptor(padapter, prframe); + if (prframe == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decryptor: drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __FUNCTION__); + #endif + ret = _FAIL; + goto _recv_data_drop; + } + +#if 0 + if ( padapter->adapter_type == PRIMARY_ADAPTER ) + { + DBG_871X("+++\n"); + { + int i; + u8 *ptr = get_recvframe_data(prframe); + for(i=0; i<140;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + + } + DBG_871X("---\n"); + } +#endif //RTK_DMP_PLATFORM + +#ifdef CONFIG_TDLS + //check TDLS frame + psnap_type = get_recvframe_data(orig_prframe); + psnap_type+=pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN; + + if((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN)) && + ((*pcategory==RTW_WLAN_CATEGORY_TDLS) || (*pcategory==RTW_WLAN_CATEGORY_P2P))){ + ret = OnTDLS(padapter, prframe); //all of functions will return _FAIL + goto _exit_recv_func; + } +#endif //CONFIG_TDLS + + prframe = recvframe_chk_defrag(padapter, prframe); + if(prframe==NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chk_defrag: drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __FUNCTION__); + #endif + goto _recv_data_drop; + } + + prframe=portctrl(padapter, prframe); + if (prframe == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("portctrl: drop pkt \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __FUNCTION__); + #endif + ret = _FAIL; + goto _recv_data_drop; + } + +#ifdef CONFIG_TDLS + if(padapter->tdlsinfo.setup_state == TDLS_LINKED_STATE) + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src); + count_rx_stats(padapter, prframe, ptdls_sta); +#else + count_rx_stats(padapter, prframe, NULL); +#endif //CONFIG_TDLS + +#ifdef CONFIG_80211N_HT + + ret = process_recv_indicatepkts(padapter, prframe); + if (ret != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recv_func: process_recv_indicatepkts fail! \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recv_func: process_recv_indicatepkts fail!\n", __FUNCTION__); + #endif + rtw_free_recvframe(orig_prframe, pfree_recv_queue);//free this recv_frame + goto _recv_data_drop; + } + +#else // CONFIG_80211N_HT + + if (!pattrib->amsdu) + { + ret = wlanhdr_to_ethhdr (prframe); + 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(orig_prframe, pfree_recv_queue);//free this recv_frame + goto _recv_data_drop; + } + + 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, prframe); + if (ret != _SUCCESS) + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__); + #endif + goto _recv_data_drop; + } + } + 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(orig_prframe, pfree_recv_queue); //free this recv_frame + } + + } + else if(pattrib->amsdu==1) + { + + ret = amsdu_to_msdu(padapter, prframe); + if(ret != _SUCCESS) + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__); + #endif + rtw_free_recvframe(orig_prframe, pfree_recv_queue); + goto _recv_data_drop; + } + } + else + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__); + #endif + goto _recv_data_drop; + } +#endif // CONFIG_80211N_HT + +_exit_recv_func: + return ret; + +_recv_data_drop: + precvpriv->rx_drop++; + return ret; +} + + +int recv_func(_adapter *padapter, union recv_frame *rframe); +int recv_func(_adapter *padapter, union recv_frame *rframe) +{ + int ret; + struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib; + struct recv_priv *recvpriv = &padapter->recvpriv; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + + /* check if need to handle uc_swdec_pending_queue*/ + if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) + { + union recv_frame *pending_frame; + _irqL irqL; + + while((pending_frame=rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) { + if (recv_func_posthandle(padapter, pending_frame) == _SUCCESS) + DBG_871X("%s: dequeue uc_swdec_pending_queue\n", __func__); + } + } + + ret = recv_func_prehandle(padapter, rframe); + + if(ret == _SUCCESS) { + + /* check if need to enqueue into uc_swdec_pending_queue*/ + if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && + !IS_MCAST(prxattrib->ra) && prxattrib->encrypt>0 && + (prxattrib->bdecrypted == 0 ||psecuritypriv->sw_decrypt == _TRUE) && + !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) && + !psecuritypriv->busetkipkey) { + rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); + DBG_871X("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); + goto exit; + } + + ret = recv_func_posthandle(padapter, rframe); + } + +exit: + return ret; +} + + +s32 rtw_recv_entry(union recv_frame *precvframe) +{ + _adapter *padapter; + struct recv_priv *precvpriv; + s32 ret=_SUCCESS; + +_func_enter_; + +// RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n")); + + padapter = precvframe->u.hdr.adapter; + + precvpriv = &padapter->recvpriv; + + + if ((ret = recv_func(padapter, precvframe)) == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("rtw_recv_entry: recv_func return fail!!!\n")); + goto _recv_entry_drop; + } + + + precvpriv->rx_pkts++; + +_func_exit_; + + return ret; + +_recv_entry_drop: + +#ifdef CONFIG_MP_INCLUDED + padapter->mppriv.rx_pktloss = precvpriv->rx_drop; +#endif + + //RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n")); + +_func_exit_; + + return ret; +} + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS +void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS){ + _adapter *adapter = (_adapter *)FunctionContext; + struct recv_priv *recvpriv = &adapter->recvpriv; + + u32 tmp_s, tmp_q; + u8 avg_signal_strength = 0; + u8 avg_signal_qual = 0; + u32 num_signal_strength = 0; + u32 num_signal_qual = 0; + u8 _alpha = 3; // this value is based on converging_constant = 5000 and sampling_interval = 1000 + + if(adapter->recvpriv.is_signal_dbg) { + //update the user specific value, signal_strength_dbg, to signal_strength, rssi + adapter->recvpriv.signal_strength= adapter->recvpriv.signal_strength_dbg; + adapter->recvpriv.rssi=(s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); + } else { + + if(recvpriv->signal_strength_data.update_req == 0) {// update_req is clear, means we got rx + avg_signal_strength = recvpriv->signal_strength_data.avg_val; + num_signal_strength = recvpriv->signal_strength_data.total_num; + // after avg_vals are accquired, we can re-stat the signal values + recvpriv->signal_strength_data.update_req = 1; + } + + if(recvpriv->signal_qual_data.update_req == 0) {// update_req is clear, means we got rx + avg_signal_qual = recvpriv->signal_qual_data.avg_val; + num_signal_qual = recvpriv->signal_qual_data.total_num; + // after avg_vals are accquired, we can re-stat the signal values + recvpriv->signal_qual_data.update_req = 1; + } + + if (num_signal_strength == 0) { + if (rtw_get_on_cur_ch_time(adapter) == 0 + || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval + ) { + goto set_timer; + } + } + + if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE + || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE + ) { + goto set_timer; + } + + #ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE) + goto set_timer; + #endif + + //update value of signal_strength, rssi, signal_qual + tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength); + if(tmp_s %_alpha) + tmp_s = tmp_s/_alpha + 1; + else + tmp_s = tmp_s/_alpha; + if(tmp_s>100) + tmp_s = 100; + + tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual); + if(tmp_q %_alpha) + tmp_q = tmp_q/_alpha + 1; + else + tmp_q = tmp_q/_alpha; + if(tmp_q>100) + tmp_q = 100; + + recvpriv->signal_strength = tmp_s; + recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); + recvpriv->signal_qual = tmp_q; + + #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1 + DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u" + ", num_signal_strength:%u, num_signal_qual:%u" + ", on_cur_ch_ms:%d" + "\n" + , FUNC_ADPT_ARG(adapter) + , recvpriv->signal_strength + , recvpriv->rssi + , recvpriv->signal_qual + , num_signal_strength, num_signal_qual + , rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0 + ); + #endif + } + +set_timer: + rtw_set_signal_stat_timer(recvpriv); + +} +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + + diff --git a/rtl8192cu-fixes/core/rtw_rf.c b/rtl8192cu-fixes/core/rtw_rf.c new file mode 100755 index 00000000..7ae86351 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_rf.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_RF_C_ + +#include +#include +#include +#include +#include + + +struct ch_freq { + u32 channel; + u32 frequency; +}; + +struct ch_freq ch_freq_map[] = { + {1, 2412},{2, 2417},{3, 2422},{4, 2427},{5, 2432}, + {6, 2437},{7, 2442},{8, 2447},{9, 2452},{10, 2457}, + {11, 2462},{12, 2467},{13, 2472},{14, 2484}, + /* UNII */ + {36, 5180},{40, 5200},{44, 5220},{48, 5240},{52, 5260}, + {56, 5280},{60, 5300},{64, 5320},{149, 5745},{153, 5765}, + {157, 5785},{161, 5805},{165, 5825},{167, 5835},{169, 5845}, + {171, 5855},{173, 5865}, + /* HiperLAN2 */ + {100, 5500},{104, 5520},{108, 5540},{112, 5560},{116, 5580}, + {120, 5600},{124, 5620},{128, 5640},{132, 5660},{136, 5680}, + {140, 5700}, + /* Japan MMAC */ + {34, 5170},{38, 5190},{42, 5210},{46, 5230}, + /* Japan */ + {184, 4920},{188, 4940},{192, 4960},{196, 4980}, + {208, 5040},/* Japan, means J08 */ + {212, 5060},/* Japan, means J12 */ + {216, 5080},/* Japan, means J16 */ +}; + +int ch_freq_map_num = (sizeof(ch_freq_map) / sizeof(struct ch_freq)); + +u32 rtw_ch2freq(u32 channel) +{ + u8 i; + u32 freq = 0; + + for (i = 0; i < ch_freq_map_num; i++) + { + if (channel == ch_freq_map[i].channel) + { + freq = ch_freq_map[i].frequency; + break; + } + } + if (i == ch_freq_map_num) + freq = 2412; + + return freq; +} + +u32 rtw_freq2ch(u32 freq) +{ + u8 i; + u32 ch = 0; + + for (i = 0; i < ch_freq_map_num; i++) + { + if (freq == ch_freq_map[i].frequency) + { + ch = ch_freq_map[i].channel; + break; + } + } + if (i == ch_freq_map_num) + ch = 1; + + return ch; +} + diff --git a/rtl8192cu-fixes/core/rtw_security.c b/rtl8192cu-fixes/core/rtw_security.c new file mode 100755 index 00000000..8fa8ed51 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_security.c @@ -0,0 +1,3115 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_SECURITY_C_ + +#include +#include +#include +#include +#include + + +//=====WEP related===== + +#define CRC32_POLY 0x04c11db7 + +struct arc4context +{ + u32 x; + u32 y; + u8 state[256]; +}; + + +static void arcfour_init(struct arc4context *parc4ctx, u8 * key,u32 key_len) +{ + u32 t, u; + u32 keyindex; + u32 stateindex; + u8 * state; + u32 counter; +_func_enter_; + state = parc4ctx->state; + parc4ctx->x = 0; + parc4ctx->y = 0; + for (counter = 0; counter < 256; counter++) + state[counter] = (u8)counter; + keyindex = 0; + stateindex = 0; + for (counter = 0; counter < 256; counter++) + { + t = state[counter]; + stateindex = (stateindex + key[keyindex] + t) & 0xff; + u = state[stateindex]; + state[stateindex] = (u8)t; + state[counter] = (u8)u; + if (++keyindex >= key_len) + keyindex = 0; + } +_func_exit_; +} +static u32 arcfour_byte( struct arc4context *parc4ctx) +{ + u32 x; + u32 y; + u32 sx, sy; + u8 * state; +_func_enter_; + state = parc4ctx->state; + x = (parc4ctx->x + 1) & 0xff; + sx = state[x]; + y = (sx + parc4ctx->y) & 0xff; + sy = state[y]; + parc4ctx->x = x; + parc4ctx->y = y; + state[y] = (u8)sx; + state[x] = (u8)sy; +_func_exit_; + return state[(sx + sy) & 0xff]; +} + + +static void arcfour_encrypt( struct arc4context *parc4ctx, + u8 * dest, + u8 * src, + u32 len) +{ + u32 i; +_func_enter_; + for (i = 0; i < len; i++) + dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); +_func_exit_; +} + +static sint bcrc32initialized = 0; +static u32 crc32_table[256]; + + +static u8 crc32_reverseBit( u8 data) +{ + return( (u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01) ); +} + +static void crc32_init(void) +{ +_func_enter_; + if (bcrc32initialized == 1) + goto exit; + else{ + sint i, j; + u32 c; + u8 *p=(u8 *)&c, *p1; + u8 k; + + c = 0x12340000; + + for (i = 0; i < 256; ++i) + { + k = crc32_reverseBit((u8)i); + for (c = ((u32)k) << 24, j = 8; j > 0; --j){ + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + } + p1 = (u8 *)&crc32_table[i]; + + p1[0] = crc32_reverseBit(p[3]); + p1[1] = crc32_reverseBit(p[2]); + p1[2] = crc32_reverseBit(p[1]); + p1[3] = crc32_reverseBit(p[0]); + } + bcrc32initialized= 1; + } +exit: +_func_exit_; +} + +static u32 getcrc32(u8 *buf, sint len) +{ + u8 *p; + u32 crc; +_func_enter_; + if (bcrc32initialized == 0) crc32_init(); + + crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ + + for (p = buf; len > 0; ++p, --len) + { + crc = crc32_table[ (crc ^ *p) & 0xff] ^ (crc >> 8); + } +_func_exit_; + return ~crc; /* transmit complement, per CRC-32 spec */ +} + + +/* + Need to consider the fragment situation +*/ +void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe) +{ // exclude ICV + + unsigned char crc[4]; + struct arc4context mycontext; + + sint curfragnum,length; + u32 keylength; + + u8 *pframe, *payload,*iv; //,*wepkey + u8 wepkey[16]; + struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + +_func_enter_; + + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return; + +#ifdef CONFIG_USB_TX_AGGREGATION + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET; +#endif + + //start to encrypt each fragment + if((pattrib->encrypt==_WEP40_)||(pattrib->encrypt==_WEP104_)) + { + keylength=psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex]; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++) + { + iv=pframe+pattrib->hdrlen; + _rtw_memcpy(&wepkey[0], iv, 3); + _rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0],keylength); + payload=pframe+pattrib->iv_len+pattrib->hdrlen; + + if((curfragnum+1)==pattrib->nr_frags) + { //the last fragment + + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length)); + + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + } + else + { + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length)); + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + pframe+=pxmitpriv->frag_len; + pframe=(u8 *)RND4((SIZE_PTR)(pframe)); + + } + + } + + } + +_func_exit_; + +} + +void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe) +{ + // exclude ICV + u8 crc[4]; + struct arc4context mycontext; + sint length; + u32 keylength; + u8 *pframe, *payload,*iv,wepkey[16]; + u8 keyindex; + struct rx_pkt_attrib *prxattrib = &(((union recv_frame*)precvframe)->u.hdr.attrib); + struct security_priv *psecuritypriv=&padapter->securitypriv; + +_func_enter_; + + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + + //start to decrypt recvframe + if((prxattrib->encrypt==_WEP40_)||(prxattrib->encrypt==_WEP104_)) + { + iv=pframe+prxattrib->hdrlen; + //keyindex=(iv[3]&0x3); + keyindex = prxattrib->key_index; + keylength=psecuritypriv->dot11DefKeylen[keyindex]; + _rtw_memcpy(&wepkey[0], iv, 3); + //_rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0],keylength); + _rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0],keylength); + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + + payload=pframe+prxattrib->iv_len+prxattrib->hdrlen; + + //decrypt payload include icv + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + + //calculate icv and compare the icv + *((u32 *)crc)=le32_to_cpu(getcrc32(payload,length-4)); + + if(crc[3]!=payload[length-1] || crc[2]!=payload[length-2] || crc[1]!=payload[length-3] || crc[0]!=payload[length-4]) + { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n", + crc[3],payload[length-1],crc[2],payload[length-2],crc[1],payload[length-3],crc[0],payload[length-4])); + } + + } + +_func_exit_; + + return; + +} + +//3 =====TKIP related===== + +static u32 secmicgetuint32( u8 * p ) +// Convert from Byte[] to Us4Byte32 in a portable way +{ + s32 i; + u32 res = 0; +_func_enter_; + for( i=0; i<4; i++ ) + { + res |= ((u32)(*p++)) << (8*i); + } +_func_exit_; + return res; +} + +static void secmicputuint32( u8 * p, u32 val ) +// Convert from Us4Byte32 to Byte[] in a portable way +{ + long i; +_func_enter_; + for( i=0; i<4; i++ ) + { + *p++ = (u8) (val & 0xff); + val >>= 8; + } +_func_exit_; +} + +static void secmicclear(struct mic_data *pmicdata) +{ +// Reset the state to the empty message. +_func_enter_; + pmicdata->L = pmicdata->K0; + pmicdata->R = pmicdata->K1; + pmicdata->nBytesInM = 0; + pmicdata->M = 0; +_func_exit_; +} + +void rtw_secmicsetkey(struct mic_data *pmicdata, u8 * key ) +{ + // Set the key +_func_enter_; + pmicdata->K0 = secmicgetuint32( key ); + pmicdata->K1 = secmicgetuint32( key + 4 ); + // and reset the message + secmicclear(pmicdata); +_func_exit_; +} + +void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b ) +{ +_func_enter_; + // Append the byte to our word-sized buffer + pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM); + pmicdata->nBytesInM++; + // Process the word if it is full. + if( pmicdata->nBytesInM >= 4 ) + { + pmicdata->L ^= pmicdata->M; + pmicdata->R ^= ROL32( pmicdata->L, 17 ); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ROL32( pmicdata->L, 3 ); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ROR32( pmicdata->L, 2 ); + pmicdata->L += pmicdata->R; + // Clear the buffer + pmicdata->M = 0; + pmicdata->nBytesInM = 0; + } +_func_exit_; +} + +void rtw_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes ) +{ +_func_enter_; + // This is simple + while( nbytes > 0 ) + { + rtw_secmicappendbyte(pmicdata, *src++ ); + nbytes--; + } +_func_exit_; +} + +void rtw_secgetmic(struct mic_data *pmicdata, u8 * dst ) +{ +_func_enter_; + // Append the minimum padding + rtw_secmicappendbyte(pmicdata, 0x5a ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + // and then zeroes until the length is a multiple of 4 + while( pmicdata->nBytesInM != 0 ) + { + rtw_secmicappendbyte(pmicdata, 0 ); + } + // The appendByte function has already computed the result. + secmicputuint32( dst, pmicdata->L ); + secmicputuint32( dst+4, pmicdata->R ); + // Reset to the empty message. + secmicclear(pmicdata); +_func_exit_; +} + + +void rtw_seccalctkipmic(u8 * key,u8 *header,u8 *data,u32 data_len,u8 *mic_code, u8 pri) +{ + + struct mic_data micdata; + u8 priority[4]={0x0,0x0,0x0,0x0}; +_func_enter_; + rtw_secmicsetkey(&micdata, key); + priority[0]=pri; + + /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ + if(header[1]&1){ //ToDS==1 + rtw_secmicappend(&micdata, &header[16], 6); //DA + if(header[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &header[24], 6); + else + rtw_secmicappend(&micdata, &header[10], 6); + } + else{ //ToDS==0 + rtw_secmicappend(&micdata, &header[4], 6); //DA + if(header[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &header[16], 6); + else + rtw_secmicappend(&micdata, &header[10], 6); + + } + rtw_secmicappend(&micdata, &priority[0], 4); + + + rtw_secmicappend(&micdata, data, data_len); + + rtw_secgetmic(&micdata,mic_code); +_func_exit_; +} + + + + +/* macros for extraction/creation of unsigned char/unsigned short values */ +#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) +#define Lo8(v16) ((u8)( (v16) & 0x00FF)) +#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) +#define Lo16(v32) ((u16)( (v32) & 0xFFFF)) +#define Hi16(v32) ((u16)(((v32) >>16) & 0xFFFF)) +#define Mk16(hi,lo) ((lo) ^ (((u16)(hi)) << 8)) + +/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ +#define TK16(N) Mk16(tk[2*(N)+1],tk[2*(N)]) + +/* S-box lookup: 16 bits --> 16 bits */ +#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) + +/* fixed algorithm "parameters" */ +#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ +#define TA_SIZE 6 /* 48-bit transmitter address */ +#define TK_SIZE 16 /* 128-bit temporal key */ +#define P1K_SIZE 10 /* 80-bit Phase1 key */ +#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ + + +/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ +static const unsigned short Sbox1[2][256]= /* Sbox for hash (can be in ROM) */ +{ { + 0xC6A5,0xF884,0xEE99,0xF68D,0xFF0D,0xD6BD,0xDEB1,0x9154, + 0x6050,0x0203,0xCEA9,0x567D,0xE719,0xB562,0x4DE6,0xEC9A, + 0x8F45,0x1F9D,0x8940,0xFA87,0xEF15,0xB2EB,0x8EC9,0xFB0B, + 0x41EC,0xB367,0x5FFD,0x45EA,0x23BF,0x53F7,0xE496,0x9B5B, + 0x75C2,0xE11C,0x3DAE,0x4C6A,0x6C5A,0x7E41,0xF502,0x834F, + 0x685C,0x51F4,0xD134,0xF908,0xE293,0xAB73,0x6253,0x2A3F, + 0x080C,0x9552,0x4665,0x9D5E,0x3028,0x37A1,0x0A0F,0x2FB5, + 0x0E09,0x2436,0x1B9B,0xDF3D,0xCD26,0x4E69,0x7FCD,0xEA9F, + 0x121B,0x1D9E,0x5874,0x342E,0x362D,0xDCB2,0xB4EE,0x5BFB, + 0xA4F6,0x764D,0xB761,0x7DCE,0x527B,0xDD3E,0x5E71,0x1397, + 0xA6F5,0xB968,0x0000,0xC12C,0x4060,0xE31F,0x79C8,0xB6ED, + 0xD4BE,0x8D46,0x67D9,0x724B,0x94DE,0x98D4,0xB0E8,0x854A, + 0xBB6B,0xC52A,0x4FE5,0xED16,0x86C5,0x9AD7,0x6655,0x1194, + 0x8ACF,0xE910,0x0406,0xFE81,0xA0F0,0x7844,0x25BA,0x4BE3, + 0xA2F3,0x5DFE,0x80C0,0x058A,0x3FAD,0x21BC,0x7048,0xF104, + 0x63DF,0x77C1,0xAF75,0x4263,0x2030,0xE51A,0xFD0E,0xBF6D, + 0x814C,0x1814,0x2635,0xC32F,0xBEE1,0x35A2,0x88CC,0x2E39, + 0x9357,0x55F2,0xFC82,0x7A47,0xC8AC,0xBAE7,0x322B,0xE695, + 0xC0A0,0x1998,0x9ED1,0xA37F,0x4466,0x547E,0x3BAB,0x0B83, + 0x8CCA,0xC729,0x6BD3,0x283C,0xA779,0xBCE2,0x161D,0xAD76, + 0xDB3B,0x6456,0x744E,0x141E,0x92DB,0x0C0A,0x486C,0xB8E4, + 0x9F5D,0xBD6E,0x43EF,0xC4A6,0x39A8,0x31A4,0xD337,0xF28B, + 0xD532,0x8B43,0x6E59,0xDAB7,0x018C,0xB164,0x9CD2,0x49E0, + 0xD8B4,0xACFA,0xF307,0xCF25,0xCAAF,0xF48E,0x47E9,0x1018, + 0x6FD5,0xF088,0x4A6F,0x5C72,0x3824,0x57F1,0x73C7,0x9751, + 0xCB23,0xA17C,0xE89C,0x3E21,0x96DD,0x61DC,0x0D86,0x0F85, + 0xE090,0x7C42,0x71C4,0xCCAA,0x90D8,0x0605,0xF701,0x1C12, + 0xC2A3,0x6A5F,0xAEF9,0x69D0,0x1791,0x9958,0x3A27,0x27B9, + 0xD938,0xEB13,0x2BB3,0x2233,0xD2BB,0xA970,0x0789,0x33A7, + 0x2DB6,0x3C22,0x1592,0xC920,0x8749,0xAAFF,0x5078,0xA57A, + 0x038F,0x59F8,0x0980,0x1A17,0x65DA,0xD731,0x84C6,0xD0B8, + 0x82C3,0x29B0,0x5A77,0x1E11,0x7BCB,0xA8FC,0x6DD6,0x2C3A, + }, + + + { /* second half of table is unsigned char-reversed version of first! */ + 0xA5C6,0x84F8,0x99EE,0x8DF6,0x0DFF,0xBDD6,0xB1DE,0x5491, + 0x5060,0x0302,0xA9CE,0x7D56,0x19E7,0x62B5,0xE64D,0x9AEC, + 0x458F,0x9D1F,0x4089,0x87FA,0x15EF,0xEBB2,0xC98E,0x0BFB, + 0xEC41,0x67B3,0xFD5F,0xEA45,0xBF23,0xF753,0x96E4,0x5B9B, + 0xC275,0x1CE1,0xAE3D,0x6A4C,0x5A6C,0x417E,0x02F5,0x4F83, + 0x5C68,0xF451,0x34D1,0x08F9,0x93E2,0x73AB,0x5362,0x3F2A, + 0x0C08,0x5295,0x6546,0x5E9D,0x2830,0xA137,0x0F0A,0xB52F, + 0x090E,0x3624,0x9B1B,0x3DDF,0x26CD,0x694E,0xCD7F,0x9FEA, + 0x1B12,0x9E1D,0x7458,0x2E34,0x2D36,0xB2DC,0xEEB4,0xFB5B, + 0xF6A4,0x4D76,0x61B7,0xCE7D,0x7B52,0x3EDD,0x715E,0x9713, + 0xF5A6,0x68B9,0x0000,0x2CC1,0x6040,0x1FE3,0xC879,0xEDB6, + 0xBED4,0x468D,0xD967,0x4B72,0xDE94,0xD498,0xE8B0,0x4A85, + 0x6BBB,0x2AC5,0xE54F,0x16ED,0xC586,0xD79A,0x5566,0x9411, + 0xCF8A,0x10E9,0x0604,0x81FE,0xF0A0,0x4478,0xBA25,0xE34B, + 0xF3A2,0xFE5D,0xC080,0x8A05,0xAD3F,0xBC21,0x4870,0x04F1, + 0xDF63,0xC177,0x75AF,0x6342,0x3020,0x1AE5,0x0EFD,0x6DBF, + 0x4C81,0x1418,0x3526,0x2FC3,0xE1BE,0xA235,0xCC88,0x392E, + 0x5793,0xF255,0x82FC,0x477A,0xACC8,0xE7BA,0x2B32,0x95E6, + 0xA0C0,0x9819,0xD19E,0x7FA3,0x6644,0x7E54,0xAB3B,0x830B, + 0xCA8C,0x29C7,0xD36B,0x3C28,0x79A7,0xE2BC,0x1D16,0x76AD, + 0x3BDB,0x5664,0x4E74,0x1E14,0xDB92,0x0A0C,0x6C48,0xE4B8, + 0x5D9F,0x6EBD,0xEF43,0xA6C4,0xA839,0xA431,0x37D3,0x8BF2, + 0x32D5,0x438B,0x596E,0xB7DA,0x8C01,0x64B1,0xD29C,0xE049, + 0xB4D8,0xFAAC,0x07F3,0x25CF,0xAFCA,0x8EF4,0xE947,0x1810, + 0xD56F,0x88F0,0x6F4A,0x725C,0x2438,0xF157,0xC773,0x5197, + 0x23CB,0x7CA1,0x9CE8,0x213E,0xDD96,0xDC61,0x860D,0x850F, + 0x90E0,0x427C,0xC471,0xAACC,0xD890,0x0506,0x01F7,0x121C, + 0xA3C2,0x5F6A,0xF9AE,0xD069,0x9117,0x5899,0x273A,0xB927, + 0x38D9,0x13EB,0xB32B,0x3322,0xBBD2,0x70A9,0x8907,0xA733, + 0xB62D,0x223C,0x9215,0x20C9,0x4987,0xFFAA,0x7850,0x7AA5, + 0x8F03,0xF859,0x8009,0x171A,0xDA65,0x31D7,0xC684,0xB8D0, + 0xC382,0xB029,0x775A,0x111E,0xCB7B,0xFCA8,0xD66D,0x3A2C, + } +}; + + /* +********************************************************************** +* Routine: Phase 1 -- generate P1K, given TA, TK, IV32 +* +* Inputs: +* tk[] = temporal key [128 bits] +* ta[] = transmitter's MAC address [ 48 bits] +* iv32 = upper 32 bits of IV [ 32 bits] +* Output: +* p1k[] = Phase 1 key [ 80 bits] +* +* Note: +* This function only needs to be called every 2**16 packets, +* although in theory it could be called every packet. +* +********************************************************************** +*/ +static void phase1(u16 *p1k,const u8 *tk,const u8 *ta,u32 iv32) +{ + sint i; +_func_enter_; + /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ + p1k[0] = Lo16(iv32); + p1k[1] = Hi16(iv32); + p1k[2] = Mk16(ta[1],ta[0]); /* use TA[] as little-endian */ + p1k[3] = Mk16(ta[3],ta[2]); + p1k[4] = Mk16(ta[5],ta[4]); + + /* Now compute an unbalanced Feistel cipher with 80-bit block */ + /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ + for (i=0; i < PHASE1_LOOP_CNT ;i++) + { /* Each add operation here is mod 2**16 */ + p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0)); + p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2)); + p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4)); + p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6)); + p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0)); + p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ + } +_func_exit_; +} + + +/* +********************************************************************** +* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 +* +* Inputs: +* tk[] = Temporal key [128 bits] +* p1k[] = Phase 1 output key [ 80 bits] +* iv16 = low 16 bits of IV counter [ 16 bits] +* Output: +* rc4key[] = the key used to encrypt the packet [128 bits] +* +* Note: +* The value {TA,IV32,IV16} for Phase1/Phase2 must be unique +* across all packets using the same key TK value. Then, for a +* given value of TK[], this TKIP48 construction guarantees that +* the final RC4KEY value is unique across all packets. +* +* Suggested implementation optimization: if PPK[] is "overlaid" +* appropriately on RC4KEY[], there is no need for the final +* for loop below that copies the PPK[] result into RC4KEY[]. +* +********************************************************************** +*/ +static void phase2(u8 *rc4key,const u8 *tk,const u16 *p1k,u16 iv16) +{ + sint i; + u16 PPK[6]; /* temporary key for mixing */ +_func_enter_; + /* Note: all adds in the PPK[] equations below are mod 2**16 */ + for (i=0;i<5;i++) PPK[i]=p1k[i]; /* first, copy P1K to PPK */ + PPK[5] = p1k[4] +iv16; /* next, add in IV16 */ + + /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ + PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ + PPK[1] += _S_(PPK[0] ^ TK16(1)); + PPK[2] += _S_(PPK[1] ^ TK16(2)); + PPK[3] += _S_(PPK[2] ^ TK16(3)); + PPK[4] += _S_(PPK[3] ^ TK16(4)); + PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ + + /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ + PPK[0] += RotR1(PPK[5] ^ TK16(6)); + PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ + PPK[2] += RotR1(PPK[1]); + PPK[3] += RotR1(PPK[2]); + PPK[4] += RotR1(PPK[3]); + PPK[5] += RotR1(PPK[4]); + /* Note: At this point, for a given key TK[0..15], the 96-bit output */ + /* value PPK[0..5] is guaranteed to be unique, as a function */ + /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */ + /* is now a keyed permutation of {TA,IV32,IV16}. */ + + /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ + rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ + rc4key[1] =(Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ + rc4key[2] = Lo8(iv16); + rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); + + + /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ + for (i=0;i<6;i++) + { + rc4key[4+2*i] = Lo8(PPK[i]); + rc4key[5+2*i] = Hi8(PPK[i]); + } +_func_exit_; +} + + +//The hlen isn't include the IV +u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe) +{ // exclude ICV + u16 pnl; + u32 pnh; + u8 rc4key[16]; + u8 ttkey[16]; + u8 crc[4]; + struct arc4context mycontext; + sint curfragnum,length; + u32 prwskeylen; + + u8 *pframe, *payload,*iv,*prwskey; + union pn48 dot11txpn; + struct sta_info *stainfo; + struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + u32 res=_SUCCESS; +_func_enter_; + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET; +#endif + + //4 start to encrypt each fragment + if(pattrib->encrypt==_TKIP_){ + + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } + + if (stainfo!=NULL){ + + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_encrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(pattrib->ra)) + { + prwskey=psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + } + else + { + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + } + + prwskeylen=16; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + iv=pframe+pattrib->hdrlen; + payload=pframe+pattrib->iv_len+pattrib->hdrlen; + + GET_TKIP_PN(iv, dot11txpn); + + pnl=(u16)(dot11txpn.val); + pnh=(u32)(dot11txpn.val>>16); + + phase1((u16 *)&ttkey[0],prwskey,&pattrib->ta[0],pnh); + + phase2(&rc4key[0],prwskey,(u16 *)&ttkey[0],pnl); + + if((curfragnum+1)==pattrib->nr_frags){ //4 the last fragment + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + RT_TRACE(_module_rtl871x_security_c_,_drv_info_,("pattrib->iv_len =%x, pattrib->icv_len =%x\n", pattrib->iv_len,pattrib->icv_len)); + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));/* modified by Amy*/ + + arcfour_init(&mycontext, rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));/* modified by Amy*/ + arcfour_init(&mycontext,rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + pframe+=pxmitpriv->frag_len; + pframe=(u8 *)RND4((SIZE_PTR)(pframe)); + + } + } + + + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_encrypt: stainfo==NULL!!!\n")); + DBG_871X("%s, psta==NUL\n", __func__); + res=_FAIL; + } + + } +_func_exit_; + return res; + +} + + +//The hlen isn't include the IV +u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe) +{ // exclude ICV + u16 pnl; + u32 pnh; + u8 rc4key[16]; + u8 ttkey[16]; + u8 crc[4]; + struct arc4context mycontext; + sint length; + u32 prwskeylen; + + u8 *pframe, *payload,*iv,*prwskey; + union pn48 dot11txpn; + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; +// struct recv_priv *precvpriv=&padapter->recvpriv; + u32 res=_SUCCESS; + +_func_enter_; + + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + + //4 start to decrypt recvframe + if(prxattrib->encrypt==_TKIP_){ + + stainfo=rtw_get_stainfo(&padapter->stapriv ,&prxattrib->ta[0] ); + if (stainfo!=NULL){ + + if(IS_MCAST(prxattrib->ra)) + { + static u32 start = 0; + static u32 no_gkey_bc_cnt = 0; + static u32 no_gkey_mc_cnt = 0; + + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + + if (start == 0) + start = rtw_get_current_time(); + + if (is_broadcast_mac_addr(prxattrib->ra)) + no_gkey_bc_cnt++; + else + no_gkey_mc_cnt++; + + if (rtw_get_passing_time_ms(start) > 1000) { + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = rtw_get_current_time(); + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + } + goto exit; + } + + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = 0; + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + + //DBG_871X("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n"); + //prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + prwskeylen=16; + } + else + { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_decrypt: stainfo!=NULL!!!\n")); + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + prwskeylen=16; + } + + iv=pframe+prxattrib->hdrlen; + payload=pframe+prxattrib->iv_len+prxattrib->hdrlen; + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + + GET_TKIP_PN(iv, dot11txpn); + + pnl=(u16)(dot11txpn.val); + pnh=(u32)(dot11txpn.val>>16); + + phase1((u16 *)&ttkey[0],prwskey,&prxattrib->ta[0],pnh); + phase2(&rc4key[0],prwskey,(unsigned short *)&ttkey[0],pnl); + + //4 decrypt payload include icv + + arcfour_init(&mycontext, rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + + *((u32 *)crc)=le32_to_cpu(getcrc32(payload,length-4)); + + if(crc[3]!=payload[length-1] || crc[2]!=payload[length-2] || crc[1]!=payload[length-3] || crc[0]!=payload[length-4]) + { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n", + crc[3],payload[length-1],crc[2],payload[length-2],crc[1],payload[length-3],crc[0],payload[length-4])); + res=_FAIL; + } + + + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_decrypt: stainfo==NULL!!!\n")); + res=_FAIL; + } + + } +_func_exit_; +exit: + return res; + +} + + +//3 =====AES related===== + + + +#define MAX_MSG_SIZE 2048 +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + + static u8 sbox_table[256] = + { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + }; + +/*****************************/ +/**** Function Prototypes ****/ +/*****************************/ + +static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); +static void construct_mic_iv( + u8 *mic_header1, + sint qc_exists, + sint a4_exists, + u8 *mpdu, + uint payload_length, + u8 * pn_vector, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void construct_mic_header1( + u8 *mic_header1, + sint header_length, + u8 *mpdu, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void construct_mic_header2( + u8 *mic_header2, + u8 *mpdu, + sint a4_exists, + sint qc_exists); +static void construct_ctr_preload( + u8 *ctr_preload, + sint a4_exists, + sint qc_exists, + u8 *mpdu, + u8 *pn_vector, + sint c, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void xor_128(u8 *a, u8 *b, u8 *out); +static void xor_32(u8 *a, u8 *b, u8 *out); +static u8 sbox(u8 a); +static void next_key(u8 *key, sint round); +static void byte_sub(u8 *in, u8 *out); +static void shift_row(u8 *in, u8 *out); +static void mix_column(u8 *in, u8 *out); +#ifndef PLATFORM_FREEBSD +static void add_round_key( u8 *shiftrow_in, + u8 *mcol_in, + u8 *block_in, + sint round, + u8 *out); +#endif //PLATFORM_FREEBSD +static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); + + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +static void xor_128(u8 *a, u8 *b, u8 *out) +{ + sint i; +_func_enter_; + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +_func_exit_; +} + + +static void xor_32(u8 *a, u8 *b, u8 *out) +{ + sint i; +_func_enter_; + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +_func_exit_; +} + + +static u8 sbox(u8 a) +{ + return sbox_table[(sint)a]; +} + + +static void next_key(u8 *key, sint round) +{ + u8 rcon; + u8 sbox_key[4]; + u8 rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; +_func_enter_; + sbox_key[0] = sbox(key[13]); + sbox_key[1] = sbox(key[14]); + sbox_key[2] = sbox(key[15]); + sbox_key[3] = sbox(key[12]); + + rcon = rcon_table[round]; + + xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon; + + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); +_func_exit_; +} + + +static void byte_sub(u8 *in, u8 *out) +{ + sint i; +_func_enter_; + for (i=0; i< 16; i++) + { + out[i] = sbox(in[i]); + } +_func_exit_; +} + + +static void shift_row(u8 *in, u8 *out) +{ +_func_enter_; + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; +_func_exit_; +} + + +static void mix_column(u8 *in, u8 *out) +{ + sint i; + u8 add1b[4]; + u8 add1bf7[4]; + u8 rotl[4]; + u8 swap_halfs[4]; + u8 andf7[4]; + u8 rotr[4]; + u8 temp[4]; + u8 tempb[4]; +_func_enter_; + for (i=0 ; i<4; i++) + { + if ((in[i] & 0x80)== 0x80) + add1b[i] = 0x1b; + else + add1b[i] = 0x00; + } + + swap_halfs[0] = in[2]; /* Swap halfs */ + swap_halfs[1] = in[3]; + swap_halfs[2] = in[0]; + swap_halfs[3] = in[1]; + + rotl[0] = in[3]; /* Rotate left 8 bits */ + rotl[1] = in[0]; + rotl[2] = in[1]; + rotl[3] = in[2]; + + andf7[0] = in[0] & 0x7f; + andf7[1] = in[1] & 0x7f; + andf7[2] = in[2] & 0x7f; + andf7[3] = in[3] & 0x7f; + + for (i = 3; i>0; i--) /* logical shift left 1 bit */ + { + andf7[i] = andf7[i] << 1; + if ((andf7[i-1] & 0x80) == 0x80) + { + andf7[i] = (andf7[i] | 0x01); + } + } + andf7[0] = andf7[0] << 1; + andf7[0] = andf7[0] & 0xfe; + + xor_32(add1b, andf7, add1bf7); + + xor_32(in, add1bf7, rotr); + + temp[0] = rotr[0]; /* Rotate right 8 bits */ + rotr[0] = rotr[1]; + rotr[1] = rotr[2]; + rotr[2] = rotr[3]; + rotr[3] = temp[0]; + + xor_32(add1bf7, rotr, temp); + xor_32(swap_halfs, rotl,tempb); + xor_32(temp, tempb, out); +_func_exit_; +} + + +static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) +{ + sint round; + sint i; + u8 intermediatea[16]; + u8 intermediateb[16]; + u8 round_key[16]; +_func_enter_; + for(i=0; i<16; i++) round_key[i] = key[i]; + + for (round = 0; round < 11; round++) + { + if (round == 0) + { + xor_128(round_key, data, ciphertext); + next_key(round_key, round); + } + else if (round == 10) + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + xor_128(intermediateb, round_key, ciphertext); + } + else /* 1 - 9 */ + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + mix_column(&intermediateb[0], &intermediatea[0]); + mix_column(&intermediateb[4], &intermediatea[4]); + mix_column(&intermediateb[8], &intermediatea[8]); + mix_column(&intermediateb[12], &intermediatea[12]); + xor_128(intermediatea, round_key, ciphertext); + next_key(round_key, round); + } + } +_func_exit_; +} + + +/************************************************/ +/* construct_mic_iv() */ +/* Builds the MIC IV from header fields and PN */ +/* Baron think the function is construct CCM */ +/* nonce */ +/************************************************/ +static void construct_mic_iv( + u8 *mic_iv, + sint qc_exists, + sint a4_exists, + u8 *mpdu, + uint payload_length, + u8 *pn_vector, + uint frtype// add for CONFIG_IEEE80211W, none 11w also can use + ) +{ + sint i; +_func_enter_; + mic_iv[0] = 0x59; + if (qc_exists && a4_exists) mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ + if (qc_exists && !a4_exists) mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ + if (!qc_exists) mic_iv[1] = 0x00; +#ifdef CONFIG_IEEE80211W + //802.11w management frame should set management bit(4) + if(frtype == WIFI_MGT_TYPE) + mic_iv[1] |= BIT(4); +#endif //CONFIG_IEEE80211W + for (i = 2; i < 8; i++) + mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ + #ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */ + #else + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ + #endif + mic_iv[14] = (unsigned char) (payload_length / 256); + mic_iv[15] = (unsigned char) (payload_length % 256); +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header1() */ +/* Builds the first MIC header block from */ +/* header fields. */ +/* Build AAD SC,A1,A2 */ +/************************************************/ +static void construct_mic_header1( + u8 *mic_header1, + sint header_length, + u8 *mpdu, + uint frtype// add for CONFIG_IEEE80211W, none 11w also can use + ) +{ +_func_enter_; + mic_header1[0] = (u8)((header_length - 2) / 256); + mic_header1[1] = (u8)((header_length - 2) % 256); +#ifdef CONFIG_IEEE80211W + //802.11w management frame don't AND subtype bits 4,5,6 of frame control field + if(frtype == WIFI_MGT_TYPE) + mic_header1[2] = mpdu[0]; + else +#endif //CONFIG_IEEE80211W + mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ + + mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ + mic_header1[4] = mpdu[4]; /* A1 */ + mic_header1[5] = mpdu[5]; + mic_header1[6] = mpdu[6]; + mic_header1[7] = mpdu[7]; + mic_header1[8] = mpdu[8]; + mic_header1[9] = mpdu[9]; + mic_header1[10] = mpdu[10]; /* A2 */ + mic_header1[11] = mpdu[11]; + mic_header1[12] = mpdu[12]; + mic_header1[13] = mpdu[13]; + mic_header1[14] = mpdu[14]; + mic_header1[15] = mpdu[15]; +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/************************************************/ +static void construct_mic_header2( + u8 *mic_header2, + u8 *mpdu, + sint a4_exists, + sint qc_exists + ) +{ + sint i; +_func_enter_; + for (i = 0; i<16; i++) mic_header2[i]=0x00; + + mic_header2[0] = mpdu[16]; /* A3 */ + mic_header2[1] = mpdu[17]; + mic_header2[2] = mpdu[18]; + mic_header2[3] = mpdu[19]; + mic_header2[4] = mpdu[20]; + mic_header2[5] = mpdu[21]; + + //mic_header2[6] = mpdu[22] & 0xf0; /* SC */ + mic_header2[6] = 0x00; + mic_header2[7] = 0x00; /* mpdu[23]; */ + + + if (!qc_exists && a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + } + + if (qc_exists && !a4_exists) + { + mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ + mic_header2[9] = mpdu[25] & 0x00; + } + + if (qc_exists && a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + mic_header2[14] = mpdu[30] & 0x0f; + mic_header2[15] = mpdu[31] & 0x00; + } + +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/* Baron think the function is construct CCM */ +/* nonce */ +/************************************************/ +static void construct_ctr_preload( + u8 *ctr_preload, + sint a4_exists, + sint qc_exists, + u8 *mpdu, + u8 *pn_vector, + sint c, + uint frtype // add for CONFIG_IEEE80211W, none 11w also can use + ) +{ + sint i = 0; +_func_enter_; + for (i=0; i<16; i++) ctr_preload[i] = 0x00; + i = 0; + + ctr_preload[0] = 0x01; /* flag */ + if (qc_exists && a4_exists) + ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ + if (qc_exists && !a4_exists) + ctr_preload[1] = mpdu[24] & 0x0f; +#ifdef CONFIG_IEEE80211W + //802.11w management frame should set management bit(4) + if(frtype == WIFI_MGT_TYPE) + ctr_preload[1] |= BIT(4); +#endif //CONFIG_IEEE80211W + for (i = 2; i < 8; i++) + ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ + #ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */ + #else + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ + #endif + ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */ + ctr_preload[15] = (unsigned char) (c % 256); +_func_exit_; +} + + +/************************************/ +/* bitwise_xor() */ +/* A 128 bit, bitwise exclusive or */ +/************************************/ +static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) +{ + sint i; +_func_enter_; + for (i=0; i<16; i++) + { + out[i] = ina[i] ^ inb[i]; + } +_func_exit_; +} + + +static sint aes_cipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) +{ +// /*static*/ unsigned char message[MAX_MSG_SIZE]; + uint qc_exists, a4_exists, i, j, payload_remainder, + num_blocks, payload_index; + + u8 pn_vector[6]; + u8 mic_iv[16]; + u8 mic_header1[16]; + u8 mic_header2[16]; + u8 ctr_preload[16]; + + /* Intermediate Buffers */ + u8 chain_buffer[16]; + u8 aes_out[16]; + u8 padded_buffer[16]; + u8 mic[8]; +// uint offset = 0; + uint frtype = GetFrameType(pframe); + uint frsubtype = GetFrameSubType(pframe); + +_func_enter_; + frsubtype=frsubtype>>4; + + + _rtw_memset((void *)mic_iv, 0, 16); + _rtw_memset((void *)mic_header1, 0, 16); + _rtw_memset((void *)mic_header2, 0, 16); + _rtw_memset((void *)ctr_preload, 0, 16); + _rtw_memset((void *)chain_buffer, 0, 16); + _rtw_memset((void *)aes_out, 0, 16); + _rtw_memset((void *)padded_buffer, 0, 16); + + if ((hdrlen == WLAN_HDR_A3_LEN )||(hdrlen == WLAN_HDR_A3_QOS_LEN)) + a4_exists = 0; + else + a4_exists = 1; + + if ( + ((frtype|frsubtype) == WIFI_DATA_CFACK) || + ((frtype|frsubtype) == WIFI_DATA_CFPOLL)|| + ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) + { + qc_exists = 1; + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + } + // add for CONFIG_IEEE80211W, none 11w also can use + else if ((frtype == WIFI_DATA) && + ((frsubtype == 0x08) || + (frsubtype == 0x09)|| + (frsubtype == 0x0a)|| + (frsubtype == 0x0b))) + { + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + qc_exists = 1; + } + else + qc_exists = 0; + + pn_vector[0]=pframe[hdrlen]; + pn_vector[1]=pframe[hdrlen+1]; + pn_vector[2]=pframe[hdrlen+4]; + pn_vector[3]=pframe[hdrlen+5]; + pn_vector[4]=pframe[hdrlen+6]; + pn_vector[5]=pframe[hdrlen+7]; + + construct_mic_iv( + mic_iv, + qc_exists, + a4_exists, + pframe, //message, + plen, + pn_vector, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + construct_mic_header1( + mic_header1, + hdrlen, + pframe, //message + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + construct_mic_header2( + mic_header2, + pframe, //message, + a4_exists, + qc_exists + ); + + + payload_remainder = plen % 16; + num_blocks = plen / 16; + + /* Find start of payload */ + payload_index = (hdrlen + 8); + + /* Calculate MIC */ + aes128k128d(key, mic_iv, aes_out); + bitwise_xor(aes_out, mic_header1, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + bitwise_xor(aes_out, mic_header2, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + for (i = 0; i < num_blocks; i++) + { + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);//bitwise_xor(aes_out, &message[payload_index], chain_buffer); + + payload_index += 16; + aes128k128d(key, chain_buffer, aes_out); + } + + /* Add on the final payload block if it needs padding */ + if (payload_remainder > 0) + { + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index++];//padded_buffer[j] = message[payload_index++]; + } + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + } + + for (j = 0 ; j < 8; j++) mic[j] = aes_out[j]; + + /* Insert MIC into payload */ + for (j = 0; j < 8; j++) + pframe[payload_index+j] = mic[j]; //message[payload_index+j] = mic[j]; + + payload_index = hdrlen + 8; + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, //message, + pn_vector, + i+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);//bitwise_xor(aes_out, &message[payload_index], chain_buffer); + for (j=0; j<16;j++) pframe[payload_index++] = chain_buffer[j];//for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, //message, + pn_vector, + num_blocks+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index+j];//padded_buffer[j] = message[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; jattrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + +// uint offset = 0; + u32 res=_SUCCESS; +_func_enter_; + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET; +#endif + + //4 start to encrypt each fragment + if((pattrib->encrypt==_AES_)){ + + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } + + if (stainfo!=NULL){ + + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_encrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(pattrib->ra)) + { + prwskey=psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + } + else + { + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + } + +#ifdef CONFIG_TDLS //swencryption + { + struct sta_info *ptdls_sta; + ptdls_sta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->dst[0] ); + if((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) ) + { + DBG_871X("[%s] for tdls link\n", __FUNCTION__); + prwskey=&ptdls_sta->tpk.tk[0]; + } + } +#endif //CONFIG_TDLS + + prwskeylen=16; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + + if((curfragnum+1)==pattrib->nr_frags){ //4 the last fragment + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + + aes_cipher(prwskey,pattrib->hdrlen,pframe, length); + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + + aes_cipher(prwskey,pattrib->hdrlen,pframe, length); + pframe+=pxmitpriv->frag_len; + pframe=(u8*)RND4((SIZE_PTR)(pframe)); + + } + } + + + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_encrypt: stainfo==NULL!!!\n")); + DBG_871X("%s, psta==NUL\n", __func__); + res=_FAIL; + } + + } + + + +_func_exit_; + return res; +} + +static sint aes_decipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) +{ + static u8 message[MAX_MSG_SIZE]; + uint qc_exists, a4_exists, i, j, payload_remainder, + num_blocks, payload_index; + sint res = _SUCCESS; + u8 pn_vector[6]; + u8 mic_iv[16]; + u8 mic_header1[16]; + u8 mic_header2[16]; + u8 ctr_preload[16]; + + /* Intermediate Buffers */ + u8 chain_buffer[16]; + u8 aes_out[16]; + u8 padded_buffer[16]; + u8 mic[8]; + + +// uint offset = 0; + uint frtype = GetFrameType(pframe); + uint frsubtype = GetFrameSubType(pframe); +_func_enter_; + frsubtype=frsubtype>>4; + + + _rtw_memset((void *)mic_iv, 0, 16); + _rtw_memset((void *)mic_header1, 0, 16); + _rtw_memset((void *)mic_header2, 0, 16); + _rtw_memset((void *)ctr_preload, 0, 16); + _rtw_memset((void *)chain_buffer, 0, 16); + _rtw_memset((void *)aes_out, 0, 16); + _rtw_memset((void *)padded_buffer, 0, 16); + + //start to decrypt the payload + + num_blocks = (plen-8) / 16; //(plen including LLC, payload_length and mic ) + + payload_remainder = (plen-8) % 16; + + pn_vector[0] = pframe[hdrlen]; + pn_vector[1] = pframe[hdrlen+1]; + pn_vector[2] = pframe[hdrlen+4]; + pn_vector[3] = pframe[hdrlen+5]; + pn_vector[4] = pframe[hdrlen+6]; + pn_vector[5] = pframe[hdrlen+7]; + + if ((hdrlen == WLAN_HDR_A3_LEN )||(hdrlen == WLAN_HDR_A3_QOS_LEN)) + a4_exists = 0; + else + a4_exists = 1; + + if ( + ((frtype|frsubtype) == WIFI_DATA_CFACK) || + ((frtype|frsubtype) == WIFI_DATA_CFPOLL)|| + ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) + { + qc_exists = 1; + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + }//only for data packet . add for CONFIG_IEEE80211W, none 11w also can use + else if ((frtype == WIFI_DATA) && + ((frsubtype == 0x08) || + (frsubtype == 0x09)|| + (frsubtype == 0x0a)|| + (frsubtype == 0x0b))) + { + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + qc_exists = 1; + } + else + qc_exists = 0; + + + // now, decrypt pframe with hdrlen offset and plen long + + payload_index = hdrlen + 8; // 8 is for extiv + + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, + pn_vector, + i+1, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); + + for (j=0; j<16;j++) pframe[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, + pn_vector, + num_blocks+1, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; j 0) + { + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = message[payload_index++]; + } + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + } + + for (j = 0 ; j < 8; j++) mic[j] = aes_out[j]; + + /* Insert MIC into payload */ + for (j = 0; j < 8; j++) + message[payload_index+j] = mic[j]; + + payload_index = hdrlen + 8; + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + message, + pn_vector, + i+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &message[payload_index], chain_buffer); + for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + message, + pn_vector, + num_blocks+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = message[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; ju.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; +// struct recv_priv *precvpriv=&padapter->recvpriv; + u32 res=_SUCCESS; +_func_enter_; + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + //4 start to encrypt each fragment + if((prxattrib->encrypt==_AES_)){ + + stainfo=rtw_get_stainfo(&padapter->stapriv ,&prxattrib->ta[0] ); + if (stainfo!=NULL){ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_decrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(prxattrib->ra)) + { + //in concurrent we should use sw descrypt in group key, so we remove this message + //DBG_871X("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); + //prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + DBG_8192C("%s:rx bc/mc packets,but didn't install group key!!!!!!!!!!\n",__FUNCTION__); + goto exit; + } + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + + if(psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) + { + DBG_871X("not match packet_index=%d, install_index=%d \n" + , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); + res=_FAIL; + goto exit; + } + } + else + { + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + } + + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + /*// add for CONFIG_IEEE80211W, debug + if(0) + printk("@@@@@@@@@@@@@@@@@@ length=%d, prxattrib->hdrlen=%d, prxattrib->pkt_len=%d \n" + , length, prxattrib->hdrlen, prxattrib->pkt_len); + if(0) + { + int no; + //test print PSK + printk("PSK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", prwskey[no]); + printk("\n"); + } + if(0) + { + int no; + //test print PSK + printk("frame:\n"); + for(no=0;nopkt_len;no++) + printk(" %02x ", pframe[no]); + printk("\n"); + }*/ + + res= aes_decipher(prwskey,prxattrib->hdrlen,pframe, length); + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_encrypt: stainfo==NULL!!!\n")); + res=_FAIL; + } + + } +_func_exit_; +exit: + return res; +} + +#ifdef CONFIG_IEEE80211W +u32 rtw_BIP_verify(_adapter *padapter, u8 *precvframe) +{ + struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + u8 *pframe; + u8 *BIP_AAD, *p; + u32 res=_FAIL; + uint len, ori_len; + struct rtw_ieee80211_hdr *pwlanhdr; + u8 mic[16]; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE; + BIP_AAD = rtw_zmalloc(ori_len); + + if(BIP_AAD == NULL) + { + DBG_871X("BIP AAD allocate fail\n"); + return _FAIL; + } + //PKT start + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + //mapping to wlan header + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //save the frame body + MME + _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN); + //find MME IE pointer + p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN); + //Baron + if(p) + { + u16 keyid=0; + u64 temp_ipn=0; + //save packet number + _rtw_memcpy(&temp_ipn, p+4, 6); + temp_ipn = le64_to_cpu(temp_ipn); + //BIP packet number should bigger than previous BIP packet + if(temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx) + { + DBG_871X("replay BIP packet\n"); + goto BIP_exit; + } + //copy key index + _rtw_memcpy(&keyid, p+2, 2); + keyid = le16_to_cpu(keyid); + if(keyid != padapter->securitypriv.dot11wBIPKeyid) + { + DBG_871X("BIP key index error!\n"); + goto BIP_exit; + } + //clear the MIC field of MME to zero + _rtw_memset(p+2+len-8, 0, 8); + + //conscruct AAD, copy frame control field + _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); + ClearRetry(BIP_AAD); + ClearPwrMgt(BIP_AAD); + ClearMData(BIP_AAD); + //conscruct AAD, copy address 1 to address 3 + _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + + if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey + , BIP_AAD, ori_len, mic)) + goto BIP_exit; + + /*//management packet content + { + int pp; + DBG_871X("pkt: "); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", pframe[pp]); + DBG_871X("\n"); + //BIP AAD + management frame body + MME(MIC is zero) + DBG_871X("AAD+PKT: "); + for(pp=0;pp< ori_len; pp++) + DBG_871X(" %02x ", BIP_AAD[pp]); + DBG_871X("\n"); + //show the MIC result + DBG_871X("mic: "); + for(pp=0;pp<16; pp++) + DBG_871X(" %02x ", mic[pp]); + DBG_871X("\n"); + } + */ + //MIC field should be last 8 bytes of packet (packet without FCS) + if(_rtw_memcmp(mic, pframe+pattrib->pkt_len-8, 8)) + { + pmlmeext->mgnt_80211w_IPN_rx = temp_ipn; + res=_SUCCESS; + } + else + DBG_871X("BIP MIC error!\n"); + + } + else + res = RTW_RX_HANDLED; +BIP_exit: + + rtw_mfree(BIP_AAD, ori_len); + return res; +} +#endif //CONFIG_IEEE80211W + +#ifndef PLATFORM_FREEBSD +/* compress 512-bits */ +static int sha256_compress(struct sha256_state *md, unsigned char *buf) +{ + u32 S[8], W[64], t0, t1; + u32 t; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + +/* Initialize the hash state */ +static void sha256_init(struct sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +static int sha256_process(struct sha256_state *md, unsigned char *in, + unsigned long inlen) +{ + unsigned long n; +#define block_size 64 + + if (md->curlen > sizeof(md->buf)) + return -1; + + while (inlen > 0) { + if (md->curlen == 0 && inlen >= block_size) { + if (sha256_compress(md, (unsigned char *) in) < 0) + return -1; + md->length += block_size * 8; + in += block_size; + inlen -= block_size; + } else { + n = MIN(inlen, (block_size - md->curlen)); + _rtw_memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == block_size) { + if (sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * block_size; + md->curlen = 0; + } + } + } + + return 0; +} + + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +static int sha256_done(struct sha256_state *md, unsigned char *out) +{ + int i; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char) 0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char) 0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char) 0; + } + + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + + return 0; +} + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) +{ + struct sha256_state ctx; + size_t i; + + sha256_init(&ctx); + for (i = 0; i < num_elem; i++) + if (sha256_process(&ctx, addr[i], len[i])) + return -1; + if (sha256_done(&ctx, mac)) + return -1; + return 0; +} + +static u8 os_strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + +static int os_memcmp(void *s1, void *s2, u8 n) +{ + unsigned char *p1 = s1, *p2 = s2; + + if (n == 0) + return 0; + + while (*p1 == *p2) { + p1++; + p2++; + n--; + if (n == 0) + return 0; + } + + return *p1 - *p2; +} + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + */ +static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem, + u8 *addr[], size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) { + sha256_vector(1, &key, &key_len, tk); + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + _rtw_memset(k_pad, 0, sizeof(k_pad)); + _rtw_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + sha256_vector(1 + num_elem, _addr, _len, mac); + + _rtw_memset(k_pad, 0, sizeof(k_pad)); + _rtw_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = 32; + sha256_vector(2, _addr, _len, mac); +} +#endif //PLATFORM_FREEBSD +/** + * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * + * This function is used to derive new, cryptographically separate keys from a + * given key. + */ +#ifndef PLATFORM_FREEBSD //Baron +static void sha256_prf(u8 *key, size_t key_len, char *label, + u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + u16 counter = 1; + size_t pos, plen; + u8 hash[SHA256_MAC_LEN]; + u8 *addr[4]; + size_t len[4]; + u8 counter_le[2], length_le[2]; + + addr[0] = counter_le; + len[0] = 2; + addr[1] = (u8 *) label; + len[1] = os_strlen(label); + addr[2] = data; + len[2] = data_len; + addr[3] = length_le; + len[3] = sizeof(length_le); + + WPA_PUT_LE16(length_le, buf_len * 8); + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + WPA_PUT_LE16(counter_le, counter); + if (plen >= SHA256_MAC_LEN) { + hmac_sha256_vector(key, key_len, 4, addr, len, + &buf[pos]); + pos += SHA256_MAC_LEN; + } else { + hmac_sha256_vector(key, key_len, 4, addr, len, hash); + _rtw_memcpy(&buf[pos], hash, plen); + break; + } + counter++; + } +} +#endif //PLATFORM_FREEBSD Baron + +/* AES tables*/ +const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +const u8 Td4s[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +const u8 rcons[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +#ifndef PLATFORM_FREEBSD //Baron +static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]) +{ + int i; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + for (i = 0; i < 10; i++) { + temp = rk[3]; + rk[4] = rk[0] ^ + TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^ + RCON(i); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + rk += 4; + } +} + +static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + int Nr = 10; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ +d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ +d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ +d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; + PUTU32(ct , s0); + s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; + PUTU32(ct + 12, s3); +} + +static void * aes_encrypt_init(u8 *key, size_t len) +{ + u32 *rk; + if (len != 16) + return NULL; + rk = (u32*)rtw_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + rijndaelKeySetupEnc(rk, key); + return rk; +} + +static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt) +{ + rijndaelEncrypt(ctx, plain, crypt); +} + + +static void gf_mulx(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + +static void aes_encrypt_deinit(void *ctx) +{ + _rtw_memset(ctx, 0, AES_PRIV_SIZE); + rtw_mfree(ctx, AES_PRIV_SIZE); +} + + +/** + * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 + * @key: 128-bit key for the hash operation + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +static int omac1_aes_128_vector(u8 *key, size_t num_elem, + u8 *addr[], size_t *len, u8 *mac) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + u8 *pos, *end; + size_t i, e, left, total_len; + + ctx = aes_encrypt_init(key, 16); + if (ctx == NULL) + return -1; + _rtw_memset(cbc, 0, AES_BLOCK_SIZE); + + total_len = 0; + for (e = 0; e < num_elem; e++) + total_len += len[e]; + left = total_len; + + e = 0; + pos = addr[0]; + end = pos + len[0]; + + while (left >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + if (left > AES_BLOCK_SIZE) + aes_128_encrypt(ctx, cbc, cbc); + left -= AES_BLOCK_SIZE; + } + + _rtw_memset(pad, 0, AES_BLOCK_SIZE); + aes_128_encrypt(ctx, pad, pad); + gf_mulx(pad); + + if (left || total_len == 0) { + for (i = 0; i < left; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + cbc[left] ^= 0x80; + gf_mulx(pad); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + pad[i] ^= cbc[i]; + aes_128_encrypt(ctx, pad, mac); + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) + * @key: 128-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ //modify for CONFIG_IEEE80211W +int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_128_vector(key, 1, &data, &data_len, mac); +} +#endif //PLATFORM_FREEBSD Baron + +#ifdef CONFIG_TDLS +void wpa_tdls_generate_tpk(_adapter *padapter, struct sta_info *psta) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 *SNonce = psta->SNonce; + u8 *ANonce = psta->ANonce; + + u8 key_input[SHA256_MAC_LEN]; + u8 *nonce[2]; + size_t len[2]; + u8 data[3 * ETH_ALEN]; + + /* IEEE Std 802.11z-2010 8.5.9.1: + * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) + */ + len[0] = 32; + len[1] = 32; + if (os_memcmp(SNonce, ANonce, 32) < 0) { + nonce[0] = SNonce; + nonce[1] = ANonce; + } else { + nonce[0] = ANonce; + nonce[1] = SNonce; + } + + sha256_vector(2, nonce, len, key_input); + + /* + * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK", + * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY) + * TODO: is N_KEY really included in KDF Context and if so, in which + * presentation format (little endian 16-bit?) is it used? It gets + * added by the KDF anyway.. + */ + + if (os_memcmp(myid(&(padapter->eeprompriv)), psta->hwaddr, ETH_ALEN) < 0) { + _rtw_memcpy(data, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, psta->hwaddr, ETH_ALEN); + } else { + _rtw_memcpy(data, psta->hwaddr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, myid(&(padapter->eeprompriv)), ETH_ALEN); + } + _rtw_memcpy(data + 2 * ETH_ALEN, get_bssid(pmlmepriv), ETH_ALEN); + + sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *) &psta->tpk, sizeof(psta->tpk)); + + +} + +/** + * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC + * @kck: TPK-KCK + * @lnkid: Pointer to the beginning of Link Identifier IE + * @rsnie: Pointer to the beginning of RSN IE used for handshake + * @timeoutie: Pointer to the beginning of Timeout IE used for handshake + * @ftie: Pointer to the beginning of FT IE + * @mic: Pointer for writing MIC + * + * Calculate MIC for TDLS frame. + */ +int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie, + u8 *mic) +{ + u8 *buf, *pos; + struct wpa_tdls_ftie *_ftie; + struct wpa_tdls_lnkid *_lnkid; + int ret; + int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + 2 + rsnie[1] + + 2 + timeoutie[1] + 2 + ftie[1]; + buf = rtw_zmalloc(len); + if (!buf) { + DBG_871X("TDLS: No memory for MIC calculation\n"); + return -1; + } + + pos = buf; + _lnkid = (struct wpa_tdls_lnkid *) lnkid; + /* 1) TDLS initiator STA MAC address */ + _rtw_memcpy(pos, _lnkid->init_sta, ETH_ALEN); + pos += ETH_ALEN; + /* 2) TDLS responder STA MAC address */ + _rtw_memcpy(pos, _lnkid->resp_sta, ETH_ALEN); + pos += ETH_ALEN; + /* 3) Transaction Sequence number */ + *pos++ = trans_seq; + /* 4) Link Identifier IE */ + _rtw_memcpy(pos, lnkid, 2 + lnkid[1]); + pos += 2 + lnkid[1]; + /* 5) RSN IE */ + _rtw_memcpy(pos, rsnie, 2 + rsnie[1]); + pos += 2 + rsnie[1]; + /* 6) Timeout Interval IE */ + _rtw_memcpy(pos, timeoutie, 2 + timeoutie[1]); + pos += 2 + timeoutie[1]; + /* 7) FTIE, with the MIC field of the FTIE set to 0 */ + _rtw_memcpy(pos, ftie, 2 + ftie[1]); + _ftie = (struct wpa_tdls_ftie *) pos; + _rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN); + pos += 2 + ftie[1]; + + ret = omac1_aes_128(kck, buf, pos - buf, mic); + rtw_mfree(buf, len); + return ret; + +} + +int tdls_verify_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie) +{ + u8 *buf, *pos; + int len; + u8 mic[16]; + int ret; + u8 *rx_ftie, *tmp_ftie; + + if (lnkid == NULL || rsnie == NULL || + timeoutie == NULL || ftie == NULL){ + return 0; + } + + len = 2 * ETH_ALEN + 1 + 2 + 18 + 2 + *(rsnie+1) + 2 + *(timeoutie+1) + 2 + *(ftie+1); + + buf = rtw_zmalloc(len); + if (buf == NULL) + return 0; + + pos = buf; + /* 1) TDLS initiator STA MAC address */ + _rtw_memcpy(pos, lnkid + ETH_ALEN + 2, ETH_ALEN); + pos += ETH_ALEN; + /* 2) TDLS responder STA MAC address */ + _rtw_memcpy(pos, lnkid + 2 * ETH_ALEN + 2, ETH_ALEN); + pos += ETH_ALEN; + /* 3) Transaction Sequence number */ + *pos++ = trans_seq; + /* 4) Link Identifier IE */ + _rtw_memcpy(pos, lnkid, 2 + 18); + pos += 2 + 18; + /* 5) RSN IE */ + _rtw_memcpy(pos, rsnie, 2 + *(rsnie+1)); + pos += 2 + *(rsnie+1); + /* 6) Timeout Interval IE */ + _rtw_memcpy(pos, timeoutie, 2 + *(timeoutie+1)); + pos += 2 + *(timeoutie+1); + /* 7) FTIE, with the MIC field of the FTIE set to 0 */ + _rtw_memcpy(pos, ftie, 2 + *(ftie+1)); + pos += 2; + tmp_ftie = (u8 *) (pos+2); + _rtw_memset(tmp_ftie, 0, 16); + pos += *(ftie+1); + + ret = omac1_aes_128(kck, buf, pos - buf, mic); + rtw_mfree(buf, len); + if (ret) + return 0; + rx_ftie = ftie+4; + + if (os_memcmp(mic, rx_ftie, 16) == 0) { + //Valid MIC + return 1; + } + + //Invalid MIC + DBG_871X( "[%s] Invalid MIC\n", __FUNCTION__); + return 0; + +} +#endif //CONFIG_TDLS + +#ifdef PLATFORM_WINDOWS +void rtw_use_tkipkey_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ) +#endif +#ifdef PLATFORM_LINUX +void rtw_use_tkipkey_handler(void *FunctionContext) +#endif +#ifdef PLATFORM_FREEBSD +void rtw_use_tkipkey_handler(void *FunctionContext) +#endif +{ + _adapter *padapter = (_adapter *)FunctionContext; + + +_func_enter_; + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler ^^^\n")); + +/* + if(padapter->bDriverStopped ||padapter->bSurpriseRemoved){ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler (padapter->bDriverStopped %d)(padapter->bSurpriseRemoved %d)^^^\n",padapter->bDriverStopped,padapter->bSurpriseRemoved)); + + return; + } + */ + + padapter->securitypriv.busetkipkey=_TRUE; + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler padapter->securitypriv.busetkipkey=%d^^^\n",padapter->securitypriv.busetkipkey)); + +_func_exit_; + +} + +/* Restore HW wep key setting according to key_mask */ +void rtw_sec_restore_wep_key(_adapter *adapter) +{ + struct security_priv* securitypriv=&(adapter->securitypriv); + sint keyid; + + if((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) { + for(keyid=0;keyid<4;keyid++){ + if(securitypriv->key_mask & BIT(keyid)){ + if(keyid == securitypriv->dot11PrivacyKeyIndex) + rtw_set_key(adapter,securitypriv, keyid, 1); + else + rtw_set_key(adapter,securitypriv, keyid, 0); + } + } + } +} + +u8 rtw_handle_tkip_countermeasure(_adapter* adapter, const char *caller) +{ + struct security_priv* securitypriv=&(adapter->securitypriv); + u8 status = _SUCCESS; + + if (securitypriv->btkip_countermeasure == _TRUE) { + u32 passing_ms = rtw_get_passing_time_ms(securitypriv->btkip_countermeasure_time); + if (passing_ms > 60*1000) { + LOG_LEVEL(_drv_info_, "%s("ADPT_FMT") countermeasure time:%ds > 60s \n", + caller, ADPT_ARG(adapter), passing_ms/1000); + securitypriv->btkip_countermeasure = _FALSE; + securitypriv->btkip_countermeasure_time = 0; + } else { + LOG_LEVEL(_drv_warning_, "%s("ADPT_FMT") countermeasure time:%ds < 60s \n", + caller, ADPT_ARG(adapter), passing_ms/1000); + status = _FAIL; + } + } + + return status; +} + diff --git a/rtl8192cu-fixes/core/rtw_sreset.c b/rtl8192cu-fixes/core/rtw_sreset.c new file mode 100755 index 00000000..e08b1f73 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_sreset.c @@ -0,0 +1,352 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + +void sreset_init_value(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + _rtw_mutex_init(&psrtpriv->silentreset_mutex); + psrtpriv->silent_reset_inprogress = _FALSE; + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + psrtpriv->last_tx_time =0; + psrtpriv->last_tx_complete_time =0; +#endif +} +void sreset_reset_value(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + psrtpriv->silent_reset_inprogress = _FALSE; + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + psrtpriv->last_tx_time =0; + psrtpriv->last_tx_complete_time =0; +#endif +} + +u8 sreset_get_wifi_status(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + u8 status = WIFI_STATUS_SUCCESS; + u32 val32 = 0; + _irqL irqL; + if(psrtpriv->silent_reset_inprogress == _TRUE) + { + return status; + } + val32 =rtw_read32(padapter,REG_TXDMA_STATUS); + if(val32==0xeaeaeaea){ + psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST; + } + else if(val32!=0){ + DBG_8192C("txdmastatu(%x)\n",val32); + psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR; + } + + if(WIFI_STATUS_SUCCESS !=psrtpriv->Wifi_Error_Status) + { + DBG_8192C("==>%s error_status(0x%x) \n",__FUNCTION__,psrtpriv->Wifi_Error_Status); + status = (psrtpriv->Wifi_Error_Status &( ~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL))); + } + DBG_8192C("==> %s wifi_status(0x%x)\n",__FUNCTION__,status); + + //status restore + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + + return status; +#else + return WIFI_STATUS_SUCCESS; +#endif +} + +void sreset_set_wifi_error_status(_adapter *padapter, u32 status) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.Wifi_Error_Status = status; +#endif +} + +void sreset_set_trigger_point(_adapter *padapter, s32 tgp) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.dbg_trigger_point = tgp; +#endif +} + +bool sreset_inprogress(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_RESET) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + return pHalData->srestpriv.silent_reset_inprogress; +#else + return _FALSE; +#endif +} + +void sreset_restore_security_station(_adapter *padapter) +{ + u8 EntryId = 0; + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_info *psta; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; + + { + u8 val8; + + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) { + val8 = 0xcc; + #ifdef CONFIG_WAPI_SUPPORT + } else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) { + //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. + val8 = 0x4c; + #endif + } else { + val8 = 0xcf; + } + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + } + + #if 0 + if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) || + ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ )) + { + + for(EntryId=0; EntryId<4; EntryId++) + { + if(EntryId == psecuritypriv->dot11PrivacyKeyIndex) + rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1); + else + rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0); + } + + } + else + #endif + if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) + { + psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + } + else + { + //pairwise key + rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); + //group key + rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0); + } + } +} + +void sreset_restore_network_station(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + #if 0 + { + //======================================================= + // reset related register of Beacon control + + //set MSR to nolink + Set_MSR(padapter, _HW_STATE_NOLINK_); + // reject all data frame + rtw_write16(padapter, REG_RXFLTMAP2,0x00); + //reset TSF + rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1))); + + // disable update TSF + SetBcnCtrlReg(padapter, BIT(4), 0); + + //======================================================= + } + #endif + + rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure); + + { + u8 threshold; + #ifdef CONFIG_USB_HCI + // TH=1 => means that invalidate usb rx aggregation + // TH=0 => means that validate usb rx aggregation, use init value. + if(mlmepriv->htpriv.ht_option) { + if(padapter->registrypriv.wifi_spec==1) + threshold = 1; + else + threshold = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } else { + threshold = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } + #endif + } + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + //disable dynamic functions, such as high power, DIG + //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); + + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); + + { + u8 join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + } + + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + + mlmeext_joinbss_event_callback(padapter, 1); + //restore Sequence No. + rtw_write8(padapter,0x4dc,padapter->xmitpriv.nqos_ssn); + + sreset_restore_security_station(padapter); +} + +void sreset_restore_network_status(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + sreset_restore_network_station(padapter); + } else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + rtw_ap_restore_network(padapter); + } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + } else { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + } +} + +void sreset_stop_adapter(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if (padapter == NULL) + return; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + if (!rtw_netif_queue_stopped(padapter->pnetdev)) + rtw_netif_stop_queue(padapter->pnetdev); + + rtw_cancel_all_timer(padapter); + + /* TODO: OS and HCI independent */ + #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI) + tasklet_kill(&pxmitpriv->xmit_tasklet); + #endif + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + rtw_scan_abort(padapter); + + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) + _rtw_join_timeout_handler(padapter); + +} + +void sreset_start_adapter(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if (padapter == NULL) + return; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + if (check_fwstate(pmlmepriv, _FW_LINKED)) { + sreset_restore_network_status(padapter); + } + + /* TODO: OS and HCI independent */ + #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI) + 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); + +} + +void sreset_reset(_adapter *padapter) +{ +#ifdef DBG_CONFIG_ERROR_RESET + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + u32 start = rtw_get_current_time(); + + DBG_871X("%s\n", __FUNCTION__); + + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + + _enter_pwrlock(&pwrpriv->lock); + + psrtpriv->silent_reset_inprogress = _TRUE; + pwrpriv->change_rfpwrstate = rf_off; + + sreset_stop_adapter(padapter); + #ifdef CONFIG_CONCURRENT_MODE + sreset_stop_adapter(padapter->pbuddy_adapter); + #endif + + #ifdef CONFIG_IPS + _ips_enter(padapter); + _ips_leave(padapter); + #endif + + sreset_start_adapter(padapter); + #ifdef CONFIG_CONCURRENT_MODE + sreset_start_adapter(padapter->pbuddy_adapter); + #endif + + psrtpriv->silent_reset_inprogress = _FALSE; + + _exit_pwrlock(&pwrpriv->lock); + + DBG_871X("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start)); +#endif +} + diff --git a/rtl8192cu-fixes/core/rtw_sta_mgt.c b/rtl8192cu-fixes/core/rtw_sta_mgt.c new file mode 100755 index 00000000..f818a0c0 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_sta_mgt.c @@ -0,0 +1,848 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_STA_MGT_C_ + +#include +#include +#include +#include +#include +#include + + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#include + +void _rtw_init_stainfo(struct sta_info *psta); +void _rtw_init_stainfo(struct sta_info *psta) +{ + +_func_enter_; + + _rtw_memset((u8 *)psta, 0, sizeof (struct sta_info)); + + _rtw_spinlock_init(&psta->lock); + _rtw_init_listhead(&psta->list); + _rtw_init_listhead(&psta->hash_list); + //_rtw_init_listhead(&psta->asoc_list); + //_rtw_init_listhead(&psta->sleep_list); + //_rtw_init_listhead(&psta->wakeup_list); + + _rtw_init_queue(&psta->sleep_q); + psta->sleepq_len = 0; + + _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); + _rtw_init_sta_recv_priv(&psta->sta_recvpriv); + +#ifdef CONFIG_AP_MODE + + _rtw_init_listhead(&psta->asoc_list); + + _rtw_init_listhead(&psta->auth_list); + + psta->expire_to = 0; + + psta->flags = 0; + + psta->capability = 0; + + psta->bpairwise_key_installed = _FALSE; + + +#ifdef CONFIG_NATIVEAP_MLME + psta->nonerp_set = 0; + psta->no_short_slot_time_set = 0; + psta->no_short_preamble_set = 0; + psta->no_ht_gf_set = 0; + psta->no_ht_set = 0; + psta->ht_20mhz_set = 0; +#endif + +#ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; +#endif // CONFIG_TX_MCAST2UNI + + psta->keep_alive_trycnt = 0; + +#endif // CONFIG_AP_MODE + +_func_exit_; + +} + +u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) +{ + struct sta_info *psta; + s32 i; + +_func_enter_; + + pstapriv->pallocated_stainfo_buf = rtw_zvmalloc (sizeof(struct sta_info) * NUM_STA+ 4); + + if(!pstapriv->pallocated_stainfo_buf) + return _FAIL; + + pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - + ((SIZE_PTR)(pstapriv->pallocated_stainfo_buf ) & 3); + + _rtw_init_queue(&pstapriv->free_sta_queue); + + _rtw_spinlock_init(&pstapriv->sta_hash_lock); + + //_rtw_init_queue(&pstapriv->asoc_q); + pstapriv->asoc_sta_count = 0; + _rtw_init_queue(&pstapriv->sleep_q); + _rtw_init_queue(&pstapriv->wakeup_q); + + psta = (struct sta_info *)(pstapriv->pstainfo_buf); + + + for(i = 0; i < NUM_STA; i++) + { + _rtw_init_stainfo(psta); + + _rtw_init_listhead(&(pstapriv->sta_hash[i])); + + rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue)); + + psta++; + } + + + +#ifdef CONFIG_AP_MODE + + pstapriv->sta_dz_bitmap = 0; + pstapriv->tim_bitmap = 0; + + _rtw_init_listhead(&pstapriv->asoc_list); + _rtw_init_listhead(&pstapriv->auth_list); + _rtw_spinlock_init(&pstapriv->asoc_list_lock); + _rtw_spinlock_init(&pstapriv->auth_list_lock); + pstapriv->asoc_list_cnt = 0; + pstapriv->auth_list_cnt = 0; + + pstapriv->auth_to = 3; // 3*2 = 6 sec + pstapriv->assoc_to = 3; + //pstapriv->expire_to = 900;// 900*2 = 1800 sec = 30 min, expire after no any traffic. + //pstapriv->expire_to = 30;// 30*2 = 60 sec = 1 min, expire after no any traffic. +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + pstapriv->expire_to = 3; // 3*2 = 6 sec +#else + pstapriv->expire_to = 60;// 60*2 = 120 sec = 2 min, expire after no any traffic. +#endif + pstapriv->max_num_sta = NUM_STA; + +#endif + +_func_exit_; + + return _SUCCESS; + +} + +inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) +{ + int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info); + + if (!stainfo_offset_valid(offset)) + DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset); + + return offset; +} + +inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) +{ + if (!stainfo_offset_valid(offset)) + DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset); + + return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); +} + +void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv); +void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv) +{ +_func_enter_; + + _rtw_spinlock_free(&psta_xmitpriv->lock); + + _rtw_spinlock_free(&(psta_xmitpriv->be_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock)); +_func_exit_; +} + +static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv) +{ +_func_enter_; + + _rtw_spinlock_free(&psta_recvpriv->lock); + + _rtw_spinlock_free(&(psta_recvpriv->defrag_q.lock)); + +_func_exit_; + +} + +void rtw_mfree_stainfo(struct sta_info *psta); +void rtw_mfree_stainfo(struct sta_info *psta) +{ +_func_enter_; + + if(&psta->lock != NULL) + _rtw_spinlock_free(&psta->lock); + + _rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv); + _rtw_free_sta_recv_priv_lock(&psta->sta_recvpriv); + +_func_exit_; +} + + +// this function is used to free the memory of lock || sema for all stainfos +void rtw_mfree_all_stainfo(struct sta_priv *pstapriv ); +void rtw_mfree_all_stainfo(struct sta_priv *pstapriv ) +{ + _irqL irqL; + _list *plist, *phead; + struct sta_info *psta = NULL; + +_func_enter_; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + phead = get_list_head(&pstapriv->free_sta_queue); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info ,list); + plist = get_next(plist); + + rtw_mfree_stainfo(psta); + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + +_func_exit_; + +} + +void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv); +void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv) +{ +#ifdef CONFIG_AP_MODE + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; +#endif + + rtw_mfree_all_stainfo(pstapriv); //be done before free sta_hash_lock + + _rtw_spinlock_free(&pstapriv->free_sta_queue.lock); + + _rtw_spinlock_free(&pstapriv->sta_hash_lock); + _rtw_spinlock_free(&pstapriv->wakeup_q.lock); + _rtw_spinlock_free(&pstapriv->sleep_q.lock); + +#ifdef CONFIG_AP_MODE + _rtw_spinlock_free(&pstapriv->asoc_list_lock); + _rtw_spinlock_free(&pstapriv->auth_list_lock); + _rtw_spinlock_free(&pacl_list->acl_node_q.lock); +#endif + +} + +u32 _rtw_free_sta_priv(struct sta_priv *pstapriv) +{ + _irqL irqL; + _list *phead, *plist; + struct sta_info *psta = NULL; + struct recv_reorder_ctrl *preorder_ctrl; + int index; + +_func_enter_; + if(pstapriv){ + + /* delete all reordering_ctrl_timer */ + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for(index = 0; index < NUM_STA; index++) + { + phead = &(pstapriv->sta_hash[index]); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + int i; + psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list); + plist = get_next(plist); + + for(i=0; i < 16 ; i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + /*===============================*/ + + rtw_mfree_sta_priv_lock(pstapriv); + + if(pstapriv->pallocated_stainfo_buf) { + rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4); + } + } + +_func_exit_; + return _SUCCESS; +} + + +//struct sta_info *rtw_alloc_stainfo(_queue *pfree_sta_queue, unsigned char *hwaddr) +struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) +{ + _irqL irqL, irqL2; + uint tmp_aid; + s32 index; + _list *phash_list; + struct sta_info *psta; + _queue *pfree_sta_queue; + struct recv_reorder_ctrl *preorder_ctrl; + int i = 0; + u16 wRxSeqInitialValue = 0xffff; + +_func_enter_; + + pfree_sta_queue = &pstapriv->free_sta_queue; + + //_enter_critical_bh(&(pfree_sta_queue->lock), &irqL); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + + if (_rtw_queue_empty(pfree_sta_queue) == _TRUE) + { + //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + psta = NULL; + } + else + { + psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list); + + rtw_list_delete(&(psta->list)); + + //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); + + tmp_aid = psta->aid; + + _rtw_init_stainfo(psta); + + _rtw_memcpy(psta->hwaddr, hwaddr, ETH_ALEN); + + index = wifi_mac_hash(hwaddr); + + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("rtw_alloc_stainfo: index = %x", index)); + + if(index >= NUM_STA){ + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("ERROR=> rtw_alloc_stainfo: index >= NUM_STA")); + psta= NULL; + goto exit; + } + phash_list = &(pstapriv->sta_hash[index]); + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + + rtw_list_insert_tail(&psta->hash_list, phash_list); + + pstapriv->asoc_sta_count ++ ; + + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + +// Commented by Albert 2009/08/13 +// For the SMC router, the sequence number of first packet of WPS handshake will be 0. +// In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. +// So, we initialize the tid_rxseq variable as the 0xffff. + + for( i = 0; i < 16; i++ ) + { + _rtw_memcpy( &psta->sta_recvpriv.rxcache.tid_rxseq[ i ], &wRxSeqInitialValue, 2 ); + } + + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc number_%d stainfo with hwaddr = %x %x %x %x %x %x \n", + pstapriv->asoc_sta_count , hwaddr[0], hwaddr[1], hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5])); + + init_addba_retry_timer(pstapriv->padapter, psta); + +#ifdef CONFIG_TDLS + psta->padapter = pstapriv->padapter; + init_TPK_timer(pstapriv->padapter, psta); + init_ch_switch_timer(pstapriv->padapter, psta); + init_base_ch_timer(pstapriv->padapter, psta); + init_off_ch_timer(pstapriv->padapter, psta); + init_handshake_timer(pstapriv->padapter, psta); + init_tdls_alive_timer(pstapriv->padapter, psta); +#endif //CONFIG_TDLS + + //for A-MPDU Rx reordering buffer control + for(i=0; i < 16 ; i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + + preorder_ctrl->padapter = pstapriv->padapter; + + preorder_ctrl->enable = _FALSE; + + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + //preorder_ctrl->wsize_b = (NR_RECVBUFF-2); + preorder_ctrl->wsize_b = 64;//64; + + _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue); + + rtw_init_recv_timer(preorder_ctrl); + } + + + //init for DM + psta->rssi_stat.UndecoratedSmoothedPWDB = 0; + psta->rssi_stat.UndecoratedSmoothedCCK = (-1); + + /* init for the sequence number of received management frame */ + psta->RxMgmtFrameSeqNum = 0xffff; + } + +exit: + + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + +_func_exit_; + + return psta; + + +} + + +// using pstapriv->sta_hash_lock to protect +u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) +{ + int i; + _irqL irqL0; + _queue *pfree_sta_queue; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_xmit_priv *pstaxmitpriv; + struct xmit_priv *pxmitpriv= &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct hw_xmit *phwxmit; + + +_func_enter_; + + if (psta == NULL) + goto exit; + + + _enter_critical_bh(&psta->lock, &irqL0); + psta->state &= ~_FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL0); + + pfree_sta_queue = &pstapriv->free_sta_queue; + + + pstaxmitpriv = &psta->sta_xmitpriv; + + //rtw_list_delete(&psta->sleep_list); + + //rtw_list_delete(&psta->wakeup_list); + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); + psta->sleepq_len = 0; + + //vo + //_enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits; + phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt; + pstaxmitpriv->vo_q.qcnt = 0; + //_exit_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); + + //vi + //_enter_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits+1; + phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt; + pstaxmitpriv->vi_q.qcnt = 0; + //_exit_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0); + + //be + //_enter_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->be_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits+2; + phwxmit->accnt -= pstaxmitpriv->be_q.qcnt; + pstaxmitpriv->be_q.qcnt = 0; + //_exit_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0); + + //bk + //_enter_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); + phwxmit = pxmitpriv->hwxmits+3; + phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt; + pstaxmitpriv->bk_q.qcnt = 0; + //_exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); + + _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); + //_rtw_init_sta_recv_priv(&psta->sta_recvpriv); + + _cancel_timer_ex(&psta->addba_retry_timer); + +#ifdef CONFIG_TDLS + _cancel_timer_ex(&psta->TPK_timer); + _cancel_timer_ex(&psta->option_timer); + _cancel_timer_ex(&psta->base_ch_timer); + _cancel_timer_ex(&psta->off_ch_timer); + _cancel_timer_ex(&psta->alive_timer1); + _cancel_timer_ex(&psta->alive_timer2); +#endif //CONFIG_TDLS + + //for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer + for(i=0; i < 16 ; i++) + { + _irqL irqL; + _list *phead, *plist; + union recv_frame *prframe; + _queue *ppending_recvframe_queue; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + + preorder_ctrl = &psta->recvreorder_ctrl[i]; + + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + + + ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irqL); + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + + while(!rtw_is_list_empty(phead)) + { + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + + plist = get_next(plist); + + rtw_list_delete(&(prframe->u.hdr.list)); + + rtw_free_recvframe(prframe, pfree_recv_queue); + } + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irqL); + + } + + +#ifdef CONFIG_AP_MODE + +/* + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL0); + rtw_list_delete(&psta->asoc_list); + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL0); +*/ + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL0); + if (!rtw_is_list_empty(&psta->auth_list)) { + rtw_list_delete(&psta->auth_list); + pstapriv->auth_list_cnt--; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL0); + + psta->expire_to = 0; + + psta->sleepq_ac_len = 0; + psta->qos_info = 0; + + psta->max_sp_len = 0; + psta->uapsd_bk = 0; + psta->uapsd_be = 0; + psta->uapsd_vi = 0; + psta->uapsd_vo = 0; + + psta->has_legacy_ac = 0; + +#ifdef CONFIG_NATIVEAP_MLME + + pstapriv->sta_dz_bitmap &=~BIT(psta->aid); + pstapriv->tim_bitmap &=~BIT(psta->aid); + + //rtw_indicate_sta_disassoc_event(padapter, psta); + + if ((psta->aid >0)&&(pstapriv->sta_aid[psta->aid - 1] == psta)) + { + pstapriv->sta_aid[psta->aid - 1] = NULL; + psta->aid = 0; + } + +#endif // CONFIG_NATIVEAP_MLME + +#ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; +#endif // CONFIG_TX_MCAST2UNI + +#endif // CONFIG_AP_MODE + + _rtw_spinlock_free(&psta->lock); + + //_enter_critical_bh(&(pfree_sta_queue->lock), &irqL0); + rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue)); + //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL0); + +exit: + +_func_exit_; + + return _SUCCESS; + +} + +// free all stainfo which in sta_hash[all] +void rtw_free_all_stainfo(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + s32 index; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info* pbcmc_stainfo =rtw_get_bcmc_stainfo( padapter); + +_func_enter_; + + if(pstapriv->asoc_sta_count==1) + goto exit; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for(index=0; index< NUM_STA; index++) + { + phead = &(pstapriv->sta_hash[index]); + 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(pbcmc_stainfo!=psta) + rtw_free_stainfo(padapter , psta); + + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + +exit: + +_func_exit_; + +} + +/* any station allocated can be searched by hash list */ +struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) +{ + + _irqL irqL; + + _list *plist, *phead; + + struct sta_info *psta = NULL; + + u32 index; + + u8 *addr; + + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + +_func_enter_; + + if(hwaddr==NULL) + return NULL; + + if(IS_MCAST(hwaddr)) + { + addr = bc_addr; + } + else + { + addr = hwaddr; + } + + index = wifi_mac_hash(addr); + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + phead = &(pstapriv->sta_hash[index]); + plist = get_next(phead); + + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + + psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if ((_rtw_memcmp(psta->hwaddr, addr, ETH_ALEN))== _TRUE) + { // if found the matched address + break; + } + psta=NULL; + plist = get_next(plist); + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); +_func_exit_; + return psta; + +} + +u32 rtw_init_bcmc_stainfo(_adapter* padapter) +{ + + struct sta_info *psta; + struct tx_servq *ptxservq; + u32 res=_SUCCESS; + NDIS_802_11_MAC_ADDRESS bcast_addr= {0xff,0xff,0xff,0xff,0xff,0xff}; + + struct sta_priv *pstapriv = &padapter->stapriv; + //_queue *pstapending = &padapter->xmitpriv.bm_pending; + +_func_enter_; + + psta = rtw_alloc_stainfo(pstapriv, bcast_addr); + + if(psta==NULL){ + res=_FAIL; + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("rtw_alloc_stainfo fail")); + goto exit; + } + + // default broadcast & multicast use macid 1 + psta->mac_id = 1; + + ptxservq= &(psta->sta_xmitpriv.be_q); + +/* + _enter_critical(&pstapending->lock, &irqL0); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(pstapending)); + + _exit_critical(&pstapending->lock, &irqL0); +*/ + +exit: +_func_exit_; + return _SUCCESS; + +} + + +struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter) +{ + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +_func_enter_; + psta = rtw_get_stainfo(pstapriv, bc_addr); +_func_exit_; + return psta; + +} + +u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr) +{ + u8 res = _TRUE; +#ifdef CONFIG_AP_MODE + _irqL irqL; + _list *plist, *phead; + struct rtw_wlan_acl_node *paclnode; + u8 match = _FALSE; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, mac_addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + match = _TRUE; + break; + } + } + } + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + + if(pacl_list->mode == 1)//accept unless in deny list + { + res = (match == _TRUE) ? _FALSE:_TRUE; + } + else if(pacl_list->mode == 2)//deny unless in accept list + { + res = (match == _TRUE) ? _TRUE:_FALSE; + } + else + { + res = _TRUE; + } + +#endif + + return res; + +} + diff --git a/rtl8192cu-fixes/core/rtw_tdls.c b/rtl8192cu-fixes/core/rtw_tdls.c new file mode 100755 index 00000000..e8c4d4cc --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_tdls.c @@ -0,0 +1,2941 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_TDLS_C_ + +#include +#include +#include +#include + +#ifdef CONFIG_TDLS +extern unsigned char MCS_rate_2R[16]; +extern unsigned char MCS_rate_1R[16]; +extern void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame); +extern s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe); + +void rtw_reset_tdls_info(_adapter* padapter) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + ptdlsinfo->ap_prohibited = _FALSE; + ptdlsinfo->setup_state = TDLS_STATE_NONE; + ptdlsinfo->sta_cnt = 0; + ptdlsinfo->sta_maximum = _FALSE; + ptdlsinfo->macid_index= 6; + ptdlsinfo->clear_cam= 0; + ptdlsinfo->ch_sensing = 0; + ptdlsinfo->cur_channel = 0; + ptdlsinfo->candidate_ch = 1; //when inplement channel switching, default candidate channel is 1 + ptdlsinfo->watchdog_count = 0; + ptdlsinfo->dev_discovered = 0; + +#ifdef CONFIG_WFD + ptdlsinfo->wfd_info = &padapter->wfd_info; +#endif //CONFIG_WFD +} + +int rtw_init_tdls_info(_adapter* padapter) +{ + int res = _SUCCESS; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + ptdlsinfo->enable = 1; + rtw_reset_tdls_info(padapter); + + _rtw_spinlock_init(&ptdlsinfo->cmd_lock); + _rtw_spinlock_init(&ptdlsinfo->hdl_lock); + + return res; + +} + +void rtw_free_tdls_info(struct tdls_info *ptdlsinfo) +{ + _rtw_spinlock_free(&ptdlsinfo->cmd_lock); + _rtw_spinlock_free(&ptdlsinfo->hdl_lock); + + _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) ); + +} + +void issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, struct sta_info *ptdls_sta, unsigned int power_mode) +{ + 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 ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; +// SetToDs(fctrl); + if (power_mode) + { + SetPwrMgt(fctrl); + } + + _rtw_memcpy(pwlanhdr->addr1, ptdls_sta->hwaddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]; + SetSeqNum(pwlanhdr, pattrib->seqnum); + + SetFrameSubType(pframe, WIFI_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + + return; +} + +s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib) +{ + + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + + s32 res=_SUCCESS; + sint bmcast; + + bmcast = IS_MCAST(pattrib->ra); + + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + if (psta == NULL) { + res =_FAIL; + goto exit; + } + + pattrib->mac_id = psta->mac_id; + + pattrib->psta = psta; + + pattrib->ack_policy = 0; + // get ether_hdr_len + pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag + + if (pqospriv->qos_option && psta->qos_option) { + pattrib->priority = 1; //tdls management frame should be AC_BK + pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->subtype = WIFI_QOS_DATA_TYPE; + } else { + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA_TYPE; + pattrib->priority = 0; + } + + if (psta->ieee8021x_blocked == _TRUE) + { + pattrib->encrypt = 0; + } + else + { + GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); + + switch(psecuritypriv->dot11AuthAlgrthm) + { + case dot11AuthAlgrthm_Open: + case dot11AuthAlgrthm_Shared: + case dot11AuthAlgrthm_Auto: + pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex; + break; + case dot11AuthAlgrthm_8021X: + pattrib->key_idx = 0; + break; + default: + pattrib->key_idx = 0; + break; + } + } + + switch (pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + pattrib->iv_len = 4; + pattrib->icv_len = 4; + break; + case _TKIP_: + pattrib->iv_len = 8; + pattrib->icv_len = 4; + if(padapter->securitypriv.busetkipkey==_FAIL) + { + res =_FAIL; + goto exit; + } + break; + case _AES_: + pattrib->iv_len = 8; + pattrib->icv_len = 8; + break; + default: + pattrib->iv_len = 0; + pattrib->icv_len = 0; + break; + } + + if (pattrib->encrypt && + ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) + { + pattrib->bswenc = _TRUE; + } else { + pattrib->bswenc = _FALSE; + } + + //qos_en, ht_en, init rate, ,bw, ch_offset, sgi + pattrib->qos_en = psta->qos_option; + pattrib->ht_en = psta->htpriv.ht_option; + pattrib->raid = psta->raid; + pattrib->bwmode = psta->htpriv.bwmode; + pattrib->ch_offset = psta->htpriv.ch_offset; + pattrib->sgi= psta->htpriv.sgi; + pattrib->ampdu_en = _FALSE; + + //if(pattrib->ht_en && psta->htpriv.ampdu_enable) + //{ + // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) + // pattrib->ampdu_en = _TRUE; + //} + +exit: + + return res; +} + +void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_priv *pstapriv = &padapter->stapriv; + _irqL irqL; + + //free peer sta_info + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if(ptdlsinfo->sta_cnt != 0) + ptdlsinfo->sta_cnt--; + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if( ptdlsinfo->sta_cnt < (NUM_STA - 2) ) // -2: AP + BC/MC sta + { + ptdlsinfo->sta_maximum = _FALSE; + _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) ); + } + //ready to clear cam + if(ptdls_sta->mac_id!=0){ + ptdlsinfo->clear_cam=ptdls_sta->mac_id; + rtw_setstakey_cmd(padapter, (u8 *)ptdls_sta, _TRUE); + } + + if(ptdlsinfo->sta_cnt==0){ + rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR); + ptdlsinfo->setup_state=TDLS_STATE_NONE; + } + else + DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt); + + rtw_free_stainfo(padapter, ptdls_sta); + +} + +// cam entry will be the same as mac_id +void rtw_tdls_set_mac_id(struct tdls_info *ptdlsinfo, struct sta_info *ptdls_sta) +{ + if(ptdls_sta->mac_id==0) + { + ptdls_sta->mac_id = ptdlsinfo->macid_index; + if( (++ptdlsinfo->macid_index) > (NUM_STA -2) ) + ptdlsinfo->macid_index= TDLS_INI_MACID_ENTRY; + } +} + +//TDLS encryption(if needed) will always be CCMP +void rtw_tdls_set_key(_adapter *adapter, struct rx_pkt_attrib *prx_pkt_attrib, struct sta_info *ptdls_sta) +{ + if(prx_pkt_attrib->encrypt) + { + ptdls_sta->dot118021XPrivacy=_AES_; + rtw_setstakey_cmd(adapter, (u8*)ptdls_sta, _TRUE); + } +} + +void rtw_tdls_process_ht_cap(_adapter *adapter, struct sta_info *ptdls_sta, u8 *data, u8 Length) +{ + /* save HT capabilities in the sta object */ + _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap)); + if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap) ) + { + ptdls_sta->flags |= WLAN_STA_HT; + + ptdls_sta->flags |= WLAN_STA_WME; + + _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap)); + + } else + ptdls_sta->flags &= ~WLAN_STA_HT; + + if(ptdls_sta->flags & WLAN_STA_HT) + { + if(adapter->registrypriv.ht_enable == _TRUE) + { + ptdls_sta->htpriv.ht_option = _TRUE; + } + else + { + ptdls_sta->htpriv.ht_option = _FALSE; + ptdls_sta->stat_code = _STATS_FAILURE_; + } + } + + //HT related cap + if(ptdls_sta->htpriv.ht_option) + { + //check if sta supports rx ampdu + if(adapter->registrypriv.ampdu_enable==1) + ptdls_sta->htpriv.ampdu_enable = _TRUE; + + //check if sta support s Short GI + if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) + { + ptdls_sta->htpriv.sgi = _TRUE; + } + + // bwmode would still followed AP's setting + if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) + { + ptdls_sta->htpriv.bwmode = adapter->mlmeextpriv.cur_bwmode; + ptdls_sta->htpriv.ch_offset = adapter->mlmeextpriv.cur_ch_offset; + } + } +} + +u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + struct rtw_ieee80211_ht_cap ht_capie; + u8 rf_type; + + //HT capabilities + _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap)); + + ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |IEEE80211_HT_CAP_SGI_20 |IEEE80211_HT_CAP_SM_PS | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC |IEEE80211_HT_CAP_DSSSCCK40; + + { + u32 rx_packet_offset, max_recvbuf_sz; + rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); + rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); + if(max_recvbuf_sz-rx_packet_offset>(8191-256)) + ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU; + } + + ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03); + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + switch(rf_type) + { + case RF_1T1R: + ht_capie.cap_info |= 0x0100;//RX STBC One spatial stream + _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_1R, 16); + break; + + case RF_2T2R: + case RF_1T2R: + default: + ht_capie.cap_info|= 0x0200;//RX STBC two spatial stream + _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_2R, 16); + break; + } + + return(rtw_set_ie(pframe, _HT_CAPABILITY_IE_, + sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, &(pattrib->pktlen))); +} + +u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 sup_ch[ 30 * 2 ] = { 0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel + do{ + if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 ) + { + sup_ch[0] = 1; //First channel number + sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel + } + else + { + sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; + sup_ch[idx_5g++] = 1; + } + + sup_ch_idx++; + } + while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 ); + return(rtw_set_ie(pframe, _SUPPORTED_CH_IE_, idx_5g, sup_ch, &(pattrib->pktlen))); +} + +#ifdef CONFIG_WFD +void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length) +{ + u8 wfd_ie[ 128 ] = { 0x00 }; + u32 wfd_ielen = 0; + u32 wfd_offset = 0; + // Try to get the TCP port information when receiving the negotiation response. + // + + wfd_offset = 0; + wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen ); + while( wfd_offset ) + { + u8 attr_content[ 10 ] = { 0x00 }; + u32 attr_contentlen = 0; + int i; + + DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ ); + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport ); + } + + _rtw_memset( attr_content, 0x00, 10); + attr_contentlen = 0; + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4); + DBG_871X( "[%s] Peer IP = %02u.%02u.%02u.%02u \n", __FUNCTION__, + ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1], + ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3] + ); + } + wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen ); + } +} + +void issue_tunneled_probe_req(_adapter *padapter) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN); + + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_REQ) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} + +void issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN); + + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_RSP) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} +#endif //CONFIG_WFD + +void issue_tdls_setup_req(_adapter *padapter, u8 *mac_addr) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta= NULL; + _irqL irqL; + static u8 dialogtoken = 0; + u32 timeout_interval= TPK_RESEND_COUNT * 1000; //retry timer should set at least 301 sec, using TPK_count counting 301 times. + + if(ptdlsinfo->ap_prohibited == _TRUE) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + + //init peer sta_info + ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr); + if(ptdls_sta==NULL) + { + ptdls_sta = rtw_alloc_stainfo(pstapriv, mac_addr); + if(ptdls_sta) + { + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) + ptdlsinfo->sta_cnt++; + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta + { + ptdlsinfo->sta_maximum = _TRUE; + } + } + else + { + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + } + + if(ptdls_sta){ + ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE; + //for tdls; ptdls_sta->aid is used to fill dialogtoken + ptdls_sta->dialog = dialogtoken; + dialogtoken = (dialogtoken+1)%256; + ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval; + _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME ); + } + + pattrib->qsel=pattrib->priority; + if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_REQUEST) !=_SUCCESS ){ + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} + +void issue_tdls_teardown(_adapter *padapter, u8 *mac_addr) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta=NULL; + _irqL irqL; + + ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr); + if(ptdls_sta==NULL){ + DBG_871X("issue tdls teardown unsuccessful\n"); + return; + }else{ + ptdls_sta->tdls_sta_state=TDLS_STATE_NONE; + } + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_TEARDOWN) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + + if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){ + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF); + } + + if( ptdls_sta->timer_flag == 1 ) + { + _enter_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL); + ptdls_sta->timer_flag = 2; + _exit_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL); + } + else + rtw_tdls_cmd(padapter, mac_addr, TDLS_FREE_STA ); + + +exit: + + return; +} + +void issue_tdls_dis_req(_adapter *padapter, u8 *mac_addr) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + if(mac_addr == NULL) + _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN); + else + _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN); + + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_DISCOVERY_REQUEST) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + DBG_871X("issue tdls dis req\n"); + +exit: + + return; +} + +void issue_tdls_setup_rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib; + _irqL irqL; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_RESPONSE) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; + +} + +void issue_tdls_setup_cfm(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct sta_info *ptdls_sta=NULL; + _irqL irqL; + + struct rx_pkt_attrib *rx_pkt_pattrib = & precv_frame->u.hdr.attrib; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_CONFIRM) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; + +} + +//TDLS Discovery Response frame is a management action frame +void issue_tdls_dis_rsp(_adapter *padapter, union recv_frame *precv_frame, u8 dialog) +{ + 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 rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; + + // unicast probe request frame + _rtw_memcpy(pwlanhdr->addr1, rx_pkt_pattrib->src, ETH_ALEN); + _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr3, rx_pkt_pattrib->bssid, ETH_ALEN); + _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN); + + 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); + + rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, dialog); + + pattrib->nr_frags = 1; + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; +} + +void issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + + static u8 dialogtoken=0; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + //for tdls; pattrib->nr_frags is used to fill dialogtoken + ptdls_sta->dialog = dialogtoken; + dialogtoken = (dialogtoken+1)%256; + //PTI frame's priority should be AC_VO + pattrib->priority = 7; + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel=pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_PEER_TRAFFIC_INDICATION) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} + +void issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + + pattrib->qsel=pattrib->priority; + if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_REQUEST) !=_SUCCESS ){ + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} + +void issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + + _irqL irqL; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + pattrib->pctrl =0; + + _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN); + + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + + pattrib->qsel=pattrib->priority; +/* + _enter_critical_bh(&pxmitpriv->lock, &irqL); + if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){ + _exit_critical_bh(&pxmitpriv->lock, &irqL); + return _FALSE; + } +*/ + if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_RESPONSE) !=_SUCCESS ){ + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + rtw_dump_xframe(padapter, pmgntframe); + +exit: + + return; +} + +sint On_TDLS_Dis_Rsp(_adapter *adapter, union recv_frame *precv_frame) +{ + struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(adapter->stapriv), get_bssid(&(adapter->mlmepriv))); + struct recv_priv *precvpriv = &(adapter->recvpriv); + u8 *ptr = precv_frame->u.hdr.rx_data, *psa; + struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib); + struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo); + u8 empty_addr[ETH_ALEN] = { 0x00 }; + int UndecoratedSmoothedPWDB; + + + //WFDTDLS: for sigma test, not to setup direct link automatically + ptdlsinfo->dev_discovered = 1; + +#ifdef CONFIG_TDLS_AUTOSETUP + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(&(adapter->stapriv), psa); + + if(ptdls_sta != NULL) + { + ptdls_sta->tdls_sta_state |= TDLS_ALIVE_STATE; + + //Record the tdls sta with lowest signal strength + if( (ptdlsinfo->sta_maximum == _TRUE) && (ptdls_sta->alive_count >= 1) ) + { + if( _rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN) ) + { + _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN); + ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll; + } + else + { + if( ptdlsinfo->ss_record.RxPWDBAll < pattrib->RxPWDBAll ) + { + _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN); + ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll; + } + } + } + + } + else + { + if( ptdlsinfo->sta_maximum == _TRUE) + { + if( _rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN ) ) + { + //All traffics are busy, do not set up another direct link. + return _FAIL; + } + else + { + if( pattrib->RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll ) + { + issue_tdls_teardown(adapter, ptdlsinfo->ss_record.macaddr); + } + else + { + return _FAIL; + } + } + } + + rtw_hal_get_def_var(adapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + + if( pattrib->RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB); + { + DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->RxPWDBAll, UndecoratedSmoothedPWDB); + issue_tdls_setup_req(adapter, psa); + } + } +#endif //CONFIG_TDLS_AUTOSETUP + + return _SUCCESS; +} + +sint On_TDLS_Setup_Req(_adapter *adapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; + u8 *psa, *pmyid; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct security_priv *psecuritypriv = &adapter->securitypriv; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *prsnie, *ppairwise_cipher; + u8 i, k, pairwise_count; + u8 ccmp_have=0, rsnie_have=0; + u16 j; + u8 SNonce[32]; + u32 *timeout_interval; + sint parsing_length; //frame body length, without icv_len + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 5; + unsigned char supportRate[16]; + int supportRateNum = 0; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + pmyid=myid(&(adapter->eeprompriv)); + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + if(ptdlsinfo->ap_prohibited == _TRUE) + { + goto exit; + } + + if(ptdls_sta==NULL){ + ptdls_sta = rtw_alloc_stainfo(pstapriv, psa); + }else{ + if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){ + //If the direct link is already set up + //Process as re-setup after tear down + DBG_871X("re-setup a direct link\n"); + } + //already receiving TDLS setup request + else if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){ + DBG_871X("receive duplicated TDLS setup request frame in handshaking\n"); + goto exit; + } + //When receiving and sending setup_req to the same link at the same time, STA with higher MAC_addr would be initiator + //following is to check out MAC_addr + else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){ + DBG_871X("receive setup_req after sending setup_req\n"); + for (i=0;i<6;i++){ + if(*(pmyid+i)==*(psa+i)){ + } + else if(*(pmyid+i)>*(psa+i)){ + goto exit; + }else if(*(pmyid+i)<*(psa+i)){ + ptdls_sta->tdls_sta_state=TDLS_INITIATOR_STATE; + break; + } + } + } + } + + if(ptdls_sta) + { + ptdls_sta->dialog = *(ptr+2); //copy dialog token + ptdls_sta->stat_code = 0; + + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _SUPPORTEDRATES_IE_: + _rtw_memcpy(supportRate, pIE->data, pIE->Length); + supportRateNum = pIE->Length; + break; + case _COUNTRY_IE_: + break; + case _EXT_SUPPORTEDRATES_IE_: + if(supportRateNum<=sizeof(supportRate)) + { + _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length); + supportRateNum += pIE->Length; + } + break; + case _SUPPORTED_CH_IE_: + break; + case _RSN_IE_2_: + rsnie_have=1; + if(prx_pkt_attrib->encrypt){ + prsnie=(u8*)pIE; + //check whether initiator STA has CCMP pairwise_cipher. + ppairwise_cipher=prsnie+10; + _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 1); + for(k=0;kstat_code=72; + } + } + break; + case _EXT_CAP_IE_: + break; + case _VENDOR_SPECIFIC_IE_: + break; + case _FTIE_: + if(prx_pkt_attrib->encrypt) + _rtw_memcpy(SNonce, (ptr+j+52), 32); + break; + case _TIMEOUT_ITVL_IE_: + if(prx_pkt_attrib->encrypt) + timeout_interval = (u32 *)(ptr+j+3); + break; + case _RIC_Descriptor_IE_: + break; + case _HT_CAPABILITY_IE_: + rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length); + break; + case EID_BSSCoexistence: + break; + case _LINK_ID_IE_: + if(_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE) + { + //not in the same BSS + ptdls_sta->stat_code=7; + } + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + //update station supportRate + ptdls_sta->bssratelen = supportRateNum; + _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum); + + //check status code + //if responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject + if(ptdls_sta->stat_code == 0 ) + { + if(rsnie_have && (prx_pkt_attrib->encrypt==0)){ + //security disabled + ptdls_sta->stat_code = 5; + }else if(rsnie_have==0 && (prx_pkt_attrib->encrypt)){ + //request haven't RSNIE + ptdls_sta->stat_code = 38; + } + +#ifdef CONFIG_WFD + //WFD test plan version 0.18.2 test item 5.1.5 + //SoUT does not use TDLS if AP uses weak security + if ( adapter->wdinfo.wfd_tdls_enable ) + { + if(rsnie_have && (prx_pkt_attrib->encrypt != _AES_)) + { + ptdls_sta->stat_code = 5; + } + } +#endif //CONFIG_WFD + } + + ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE; + if(prx_pkt_attrib->encrypt){ + _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32); + _rtw_memcpy(&(ptdls_sta->TDLS_PeerKey_Lifetime), timeout_interval, 4); + } + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) + ptdlsinfo->sta_cnt++; + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta + { + ptdlsinfo->sta_maximum = _TRUE; + } + +#ifdef CONFIG_WFD + rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE); +#endif // CONFIG_WFD + + } + else + { + goto exit; + } + + issue_tdls_setup_rsp(adapter, precv_frame); + + if(ptdls_sta->stat_code==0) + { + _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME); + } + else //status code!=0 ; setup unsuccess + { + free_tdls_sta(adapter, ptdls_sta); + } + +exit: + + return _FAIL; +} + +sint On_TDLS_Setup_Rsp(_adapter *adapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + u16 stat_code; + sint parsing_length; //frame body length, without icv_len + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =7; + u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher; + u16 pairwise_count, j, k; + u8 verify_ccmp=0; + unsigned char supportRate[16]; + int supportRateNum = 0; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + if ( NULL == ptdls_sta ) + { + return _FAIL; + } + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -TYPE_LENGTH_FIELD_SIZE + -1 + -FIXED_IE; + + _rtw_memcpy(&stat_code, ptr+2, 2); + + if(stat_code!=0) + { + DBG_871X( "[%s] status_code = %d, free_tdls_sta\n", __FUNCTION__, stat_code ); + free_tdls_sta(adapter, ptdls_sta); + return _FAIL; + } + + stat_code = 0; + + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _SUPPORTEDRATES_IE_: + _rtw_memcpy(supportRate, pIE->data, pIE->Length); + supportRateNum = pIE->Length; + break; + case _COUNTRY_IE_: + break; + case _EXT_SUPPORTEDRATES_IE_: + if(supportRateNum<=sizeof(supportRate)) + { + _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length); + supportRateNum += pIE->Length; + } + break; + case _SUPPORTED_CH_IE_: + break; + case _RSN_IE_2_: + prsnie=(u8*)pIE; + //check whether responder STA has CCMP pairwise_cipher. + ppairwise_cipher=prsnie+10; + _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2); + for(k=0;kANonce, (ptr+j+20), 32); + break; + case _TIMEOUT_ITVL_IE_: + ptimeout_ie=(u8*)pIE; + break; + case _RIC_Descriptor_IE_: + break; + case _HT_CAPABILITY_IE_: + rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length); + break; + case EID_BSSCoexistence: + break; + case _LINK_ID_IE_: + plinkid_ie=(u8*)pIE; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + //update station supportRate + ptdls_sta->bssratelen = supportRateNum; + _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum); + +#ifdef CONFIG_WFD + rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE); +#endif // CONFIG_WFD + + if(stat_code != 0) + { + ptdls_sta->stat_code = stat_code; + } + else + { + if(prx_pkt_attrib->encrypt) + { + if(verify_ccmp==1) + { + wpa_tdls_generate_tpk(adapter, ptdls_sta); + ptdls_sta->stat_code=0; + if(tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie)==0) //0: Invalid, 1: valid + { + free_tdls_sta(adapter, ptdls_sta); + return _FAIL; + } + } + else + { + ptdls_sta->stat_code=72; //invalide contents of RSNIE + } + + }else{ + ptdls_sta->stat_code=0; + } + } + + DBG_871X("issue_tdls_setup_cfm\n"); + issue_tdls_setup_cfm(adapter, precv_frame); + + if(ptdls_sta->stat_code==0) + { + ptdlsinfo->setup_state = TDLS_LINKED_STATE; + + if( ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE ) + { + ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; + _cancel_timer_ex( &ptdls_sta->handshake_timer); +#ifdef CONFIG_TDLS_AUTOCHECKALIVE + _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1); +#endif //CONFIG_TDLS_AUTOSETUP + } + + rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta); + rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta); + + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR); + + } + else //status code!=0 ; setup unsuccessful + { + free_tdls_sta(adapter, ptdls_sta); + } + + return _FAIL; + +} + +sint On_TDLS_Setup_Cfm(_adapter *adapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + u16 stat_code; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =5; + u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher; + u16 j, pairwise_count; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + _rtw_memcpy(&stat_code, ptr+2, 2); + + if(stat_code!=0){ + DBG_871X( "[%s] stat_code = %d\n, free_tdls_sta", __FUNCTION__, stat_code ); + free_tdls_sta(adapter, ptdls_sta); + return _FAIL; + } + + if(prx_pkt_attrib->encrypt){ + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _RSN_IE_2_: + prsnie=(u8*)pIE; + break; + case _VENDOR_SPECIFIC_IE_: + break; + case _FTIE_: + pftie=(u8*)pIE; + break; + case _TIMEOUT_ITVL_IE_: + ptimeout_ie=(u8*)pIE; + break; + case _HT_EXTRA_INFO_IE_: + break; + case _LINK_ID_IE_: + plinkid_ie=(u8*)pIE; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + //verify mic in FTIE MIC field + if(tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie)==0){ //0: Invalid, 1: Valid + free_tdls_sta(adapter, ptdls_sta); + return _FAIL; + } + + } + + ptdlsinfo->setup_state = TDLS_LINKED_STATE; + if( ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE ) + { + ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE; + _cancel_timer_ex( &ptdls_sta->handshake_timer); +#ifdef CONFIG_TDLS_AUTOCHECKALIVE + _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1); +#endif //CONFIG_TDLS_AUTOCHECKALIVE + } + + rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta); + rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta); + + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR); + + return _FAIL; + +} + +sint On_TDLS_Dis_Req(_adapter *adapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct sta_info *psta_ap; + u8 *ptr = precv_frame->u.hdr.rx_data; + sint parsing_length; //frame body length, without icv_len + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 3, *dst, *pdialog = NULL; + u16 j; + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1; + pdialog=ptr+2; + + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -TYPE_LENGTH_FIELD_SIZE + -1 + -FIXED_IE; + + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _LINK_ID_IE_: + psta_ap = rtw_get_stainfo(pstapriv, pIE->data); + if(psta_ap == NULL) + { + goto exit; + } + dst = pIE->data + 12; + if( (MacAddr_isBcst(dst) == _FALSE) && (_rtw_memcmp(myid(&(adapter->eeprompriv)), dst, 6) == _FALSE) ) + { + goto exit; + } + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + //check frame contents + + issue_tdls_dis_rsp(adapter, precv_frame, *(pdialog) ); + +exit: + + return _FAIL; + +} + +sint On_TDLS_Teardown(_adapter *adapter, union recv_frame *precv_frame) +{ + u8 *psa; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &adapter->stapriv; + struct sta_info *ptdls_sta= NULL; + _irqL irqL; + + psa = get_sa(ptr); + + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + if(ptdls_sta!=NULL){ + if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){ + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF); + } + free_tdls_sta(adapter, ptdls_sta); + } + + return _FAIL; + +} + +u8 TDLS_check_ch_state(uint state){ + if( (state & TDLS_CH_SWITCH_ON_STATE) && + (state & TDLS_AT_OFF_CH_STATE) && + (state & TDLS_PEER_AT_OFF_STATE) ){ + + if(state & TDLS_PEER_SLEEP_STATE) + return 2; //U-APSD + ch. switch + else + return 1; //ch. switch + }else + return 0; +} + +//we process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here +sint On_TDLS_Peer_Traffic_Rsp(_adapter *adapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + //get peer sta infomation + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src); + u8 wmmps_ac=0, state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state); + int i; + + ptdls_sta->sta_stats.rx_data_pkts++; + + //receive peer traffic response frame, sleeping STA wakes up + //ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_SLEEP_STATE); + process_wmmps_data( adapter, precv_frame); + + // if noticed peer STA wakes up by receiving peer traffic response + // and we want to do channel swtiching, then we will transmit channel switch request first + if(ptdls_sta->tdls_sta_state & TDLS_APSD_CHSW_STATE){ + issue_tdls_ch_switch_req(adapter, pattrib->src); + ptdls_sta->tdls_sta_state &= ~(TDLS_APSD_CHSW_STATE); + return _FAIL; + } + + //check 4-AC queue bit + if(ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk) + wmmps_ac=1; + + //if it's a direct link and have buffered frame + if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){ + if(wmmps_ac && state) + { + _irqL irqL; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + + _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + xmitframe_phead = get_list_head(&ptdls_sta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + //transmit buffered frames + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + xmitframe_plist = get_next(xmitframe_plist); + rtw_list_delete(&pxmitframe->list); + + ptdls_sta->sleepq_len--; + if(ptdls_sta->sleepq_len>0){ + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + }else{ + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + //pxmitframe->attrib.triggered = 1; //maybe doesn't need in TDLS + if(rtw_hal_xmit(adapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(adapter, pxmitframe); + } + + } + + if(ptdls_sta->sleepq_len==0) + { + DBG_871X("no buffered packets for tdls to xmit\n"); + //on U-APSD + CH. switch state, when there is no buffered date to xmit, + // we should go back to base channel + if(state==2){ + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF); + }else if(ptdls_sta->tdls_sta_state&TDLS_SW_OFF_STATE){ + ptdls_sta->tdls_sta_state &= ~(TDLS_SW_OFF_STATE); + ptdlsinfo->candidate_ch= pmlmeext->cur_channel; + issue_tdls_ch_switch_req(adapter, pattrib->src); + DBG_871X("issue tdls ch switch req back to base channel\n"); + } + + } + else + { + DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len); + ptdls_sta->sleepq_len=0; + } + + _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + } + + } + + return _FAIL; +} + +sint On_TDLS_Ch_Switch_Req(_adapter *adapter, union recv_frame *precv_frame) +{ + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =3; + u16 j; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + ptdls_sta->off_ch = *(ptr+2); + + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _COUNTRY_IE_: + break; + case _CH_SWTICH_ANNOUNCE_: + break; + case _LINK_ID_IE_: + break; + case _CH_SWITCH_TIMING_: + _rtw_memcpy(&ptdls_sta->ch_switch_time, pIE->data, 2); + _rtw_memcpy(&ptdls_sta->ch_switch_timeout, pIE->data+2, 2); + default: + break; + } + + j += (pIE->Length + 2); + + } + + //todo: check status + ptdls_sta->stat_code=0; + ptdls_sta->tdls_sta_state |= TDLS_CH_SWITCH_ON_STATE; + + issue_nulldata(adapter, NULL, 1, 0, 0); + + issue_tdls_ch_switch_rsp(adapter, psa); + + DBG_871X("issue tdls channel switch response\n"); + + if((ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE) && ptdls_sta->off_ch==pmlmeext->cur_channel){ + DBG_871X("back to base channel %x\n", pmlmeext->cur_channel); + ptdls_sta->option=7; + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_BASE_CH); + }else{ + ptdls_sta->option=6; + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH); + } + return _FAIL; +} + +sint On_TDLS_Ch_Switch_Rsp(_adapter *adapter, union recv_frame *precv_frame) +{ + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =4; + u16 stat_code, j, switch_time, switch_timeout; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + //if channel switch is running and receiving Unsolicited TDLS Channel Switch Response, + //it will go back to base channel and terminate this channel switch procedure + if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE ){ + if(pmlmeext->cur_channel==ptdls_sta->off_ch){ + DBG_871X("back to base channel %x\n", pmlmeext->cur_channel); + ptdls_sta->option=7; + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH); + }else{ + DBG_871X("receive unsolicited channel switch response \n"); + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF); + } + return _FAIL; + } + + //avoiding duplicated or unconditional ch. switch. rsp + if((ptdls_sta->tdls_sta_state & TDLS_CH_SW_INITIATOR_STATE) != TDLS_CH_SW_INITIATOR_STATE) + return _FAIL; + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + _rtw_memcpy(&stat_code, ptr+2, 2); + + if(stat_code!=0){ + return _FAIL; + } + + //parsing information element + for(j=FIXED_IE; jElementID) + { + case _LINK_ID_IE_: + break; + case _CH_SWITCH_TIMING_: + _rtw_memcpy(&switch_time, pIE->data, 2); + if(switch_time > ptdls_sta->ch_switch_time) + _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2); + + _rtw_memcpy(&switch_timeout, pIE->data+2, 2); + if(switch_timeout > ptdls_sta->ch_switch_timeout) + _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2); + + default: + break; + } + + j += (pIE->Length + 2); + + } + + ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SW_INITIATOR_STATE); + ptdls_sta->tdls_sta_state |=TDLS_CH_SWITCH_ON_STATE; + + //goto set_channel_workitem_callback() + ptdls_sta->option=6; + rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH); + + return _FAIL; +} + +#ifdef CONFIG_WFD +void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen ) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info; + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 wfdielen = 0; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL + | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + // Local IP Address ATTR + wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0005); + wfdielen += 2; + + // Version: + // 0x01: Version1;IPv4 + wfdie[ wfdielen++ ] = 0x01; + + // IPv4 Address + _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 ); + wfdielen += 4; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen); + +} +#endif //CONFIG_WFD + +void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst); + + u8 payload_type = 0x02; + u8 category = RTW_WLAN_CATEGORY_TDLS; + u8 action = TDLS_SETUP_REQUEST; + u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; //Use NDIS_802_11_LENGTH_RATES_EX in order to call func.rtw_set_supported_rate + int bssrate_len = 0, i = 0 ; + u8 more_supportedrates = 0; + unsigned int ie_len; + u8 *p; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 link_id_addr[18] = {0}; + u8 iedata=0; + u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel + u8 timeout_itvl[5]; //set timeout interval to maximum value + u32 time; + + //SNonce + if(pattrib->encrypt){ + for(i=0;i<8;i++){ + time=rtw_get_current_time(); + _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4); + } + } + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, dialog token + 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, &(ptdls_sta->dialog), &(pattrib->pktlen)); + + //capability + _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + + if(pattrib->encrypt) + *pframe =*pframe | BIT(4); + pframe += 2; + pattrib->pktlen += 2; + + //supported rates + rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N); + bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN; + + if (bssrate_len > 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen)); + more_supportedrates = 1; + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + + //country(optional) + //extended supported rates + if(more_supportedrates==1){ + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); + } + + //supported channels + pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib); + + // SRC IE + pframe = rtw_set_ie( pframe, _SRC_IE_, 16, TDLS_SRC, &(pattrib->pktlen)); + + //RSNIE + if(pattrib->encrypt) + pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen)); + + //extended capabilities + pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen)); + + //QoS capability(WMM_IE) + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen)); + + + if(pattrib->encrypt){ + //FTIE + _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0 + _rtw_memset(pframe, _FTIE_, 1); //version + _rtw_memset((pframe+1), 82, 1); //length + _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32); + pframe += 84; + pattrib->pktlen += 84; + + //Timeout interval + timeout_itvl[0]=0x02; + _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4); + pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } + + //Sup_reg_classes(optional) + //HT capabilities + pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib); + + //20/40 BSS coexistence + if(pmlmepriv->num_FortyMHzIntolerant>0) + iedata |= BIT(2);//20 MHz BSS Width Request + pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + +#ifdef CONFIG_WFD + wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) ); +#endif //CONFIG_WFD + +} + +void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_SETUP_RESPONSE; + unsigned char bssrate[NDIS_802_11_LENGTH_RATES_EX]; + int bssrate_len = 0; + u8 more_supportedrates = 0; + unsigned int ie_len; + unsigned char *p; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 link_id_addr[18] = {0}; + u8 iedata=0; + u8 timeout_itvl[5]; //setup response timeout interval will copy from request + u8 ANonce[32]; //maybe it can put in ontdls_req + u8 k; //for random ANonce + u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic; + u32 time; + + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst); + + if(ptdls_sta == NULL ) + { + DBG_871X("[%s] %d\n", __FUNCTION__, __LINE__); + return; + } + + if(pattrib->encrypt){ + for(k=0;k<8;k++){ + time=rtw_get_current_time(); + _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4); + } + } + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, status code + 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, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen)); + + if(ptdls_sta->stat_code!=0) //invalid setup request + { + DBG_871X("ptdls_sta->stat_code:%04x \n", ptdls_sta->stat_code); + return; + } + + //dialog token + pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen)); + + //capability + _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + + if(pattrib->encrypt ) + *pframe =*pframe | BIT(4); + pframe += 2; + pattrib->pktlen += 2; + + //supported rates + rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N); + bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN; + + if (bssrate_len > 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen)); + more_supportedrates = 1; + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + + //country(optional) + //extended supported rates + if(more_supportedrates==1){ + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); + } + + //supported channels + pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib); + + // SRC IE + pframe = rtw_set_ie(pframe, _SRC_IE_ , 16, TDLS_SRC, &(pattrib->pktlen)); + + //RSNIE + if(pattrib->encrypt){ + prsnie = pframe; + pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen)); + } + + //extended capabilities + pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen)); + + //QoS capability(WMM_IE) + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen)); + + if(pattrib->encrypt){ + wpa_tdls_generate_tpk(padapter, ptdls_sta); + + //FTIE + pftie = pframe; + pftie_mic = pframe+4; + _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0 + _rtw_memset(pframe, _FTIE_, 1); //version + _rtw_memset((pframe+1), 82, 1); //length + _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32); + _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32); + pframe += 84; + pattrib->pktlen += 84; + + //Timeout interval + ptimeout_ie = pframe; + timeout_itvl[0]=0x02; + _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4); + pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } + + //Sup_reg_classes(optional) + //HT capabilities + pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib); + + //20/40 BSS coexistence + if(pmlmepriv->num_FortyMHzIntolerant>0) + iedata |= BIT(2);//20 MHz BSS Width Request + pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); + + //Link identifier + plinkid_ie = pframe; + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->dst, 6); + _rtw_memcpy((link_id_addr+12), pattrib->src, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + + //fill FTIE mic + if(pattrib->encrypt) + wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic); + +#ifdef CONFIG_WFD + wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) ); +#endif //CONFIG_WFD + +} + +void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst); + + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_SETUP_CONFIRM; + u8 more_supportedrates = 0; + unsigned int ie_len; + unsigned char *p; + u8 timeout_itvl[5]; //set timeout interval to maximum value + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 link_id_addr[18] = {0}; + u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, status code, dialog token + 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, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen)); + + if(ptdls_sta->stat_code!=0) //invalid setup request + return; + + //RSNIE + if(pattrib->encrypt){ + prsnie = pframe; + pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen)); + } + + //EDCA param set; WMM param ele. + if(pattrib->encrypt){ + //FTIE + pftie = pframe; + pftie_mic = pframe+4; + _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0 + _rtw_memset(pframe, _FTIE_, 1); //version + _rtw_memset((pframe+1), 82, 1); //length + _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32); + _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32); + pframe += 84; + pattrib->pktlen += 84; + + //Timeout interval + ptimeout_ie = pframe; + timeout_itvl[0]=0x02; + _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4); + ptdls_sta->TPK_count=0; + _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT); + pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } + + //HT operation; todo + //Link identifier + plinkid_ie = pframe; + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + + //fill FTIE mic + if(pattrib->encrypt) + wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic); + +} + +void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_TEARDOWN; + u8 link_id_addr[18] = {0}; + + struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst); + struct sta_priv *pstapriv = &padapter->stapriv; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, reason code + 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, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen)); + + //Link identifier + if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){ + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){ + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->dst, 6); + _rtw_memcpy((link_id_addr+12), pattrib->src, 6); + } + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + +} + +void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 payload_type = 0x02; + u8 category = RTW_WLAN_CATEGORY_TDLS; + u8 action = TDLS_DISCOVERY_REQUEST; + u8 link_id_addr[18] = {0}; + static u8 dialogtoken=0; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, reason code + 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, &(dialogtoken), &(pattrib->pktlen)); + dialogtoken = (dialogtoken+1)%256; + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + +} + +void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + u8 category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = TDLS_DISCOVERY_RESPONSE; + u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; + int bssrate_len = 0; + u8 more_supportedrates = 0; + u8 *p; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 link_id_addr[18] = {0}; + u8 iedata=0; + u8 timeout_itvl[5]; //set timeout interval to maximum value + u32 timeout_interval= TPK_RESEND_COUNT * 1000; + + //category, action, dialog token + 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, &(dialog), &(pattrib->pktlen)); + + //capability + _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + + if(pattrib->encrypt) + *pframe =*pframe | BIT(4); + pframe += 2; + pattrib->pktlen += 2; + + //supported rates + rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N); + bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN; + + if (bssrate_len > 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen)); + more_supportedrates = 1; + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + + //extended supported rates + if(more_supportedrates==1){ + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); + } + + //supported channels + pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib); + + //RSNIE + if(pattrib->encrypt) + pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen)); + + //extended capability + pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen)); + + if(pattrib->encrypt){ + //FTIE + _rtw_memset(pframe, 0, 84); //All fields shall be set to 0 + _rtw_memset(pframe, _FTIE_, 1); //version + _rtw_memset((pframe+1), 82, 1); //length + pframe += 84; + pattrib->pktlen += 84; + + //Timeout interval + timeout_itvl[0]=0x02; + _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4); + pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } + + //Sup_reg_classes(optional) + //HT capabilities + pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib); + + //20/40 BSS coexistence + if(pmlmepriv->num_FortyMHzIntolerant>0) + iedata |= BIT(2);//20 MHz BSS Width Request + pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->dst, 6); + _rtw_memcpy((link_id_addr+12), pattrib->src, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + +} + +void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_PEER_TRAFFIC_INDICATION; + + u8 link_id_addr[18] = {0}; + u8 AC_queue=0; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, reason code + 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, &(ptdls_sta->dialog), &(pattrib->pktlen)); + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + + //PTI control + //PU buffer status + if(ptdls_sta->uapsd_bk&BIT(1)) + AC_queue=BIT(0); + if(ptdls_sta->uapsd_be&BIT(1)) + AC_queue=BIT(1); + if(ptdls_sta->uapsd_vi&BIT(1)) + AC_queue=BIT(2); + if(ptdls_sta->uapsd_vo&BIT(1)) + AC_queue=BIT(3); + pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen)); + +} + +void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_CHANNEL_SWITCH_REQUEST; + u8 link_id_addr[18] = {0}; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + u8 ch_switch_timing[4] = {0}; + u16 switch_time= CH_SWITCH_TIME, switch_timeout=CH_SWITCH_TIMEOUT; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, target_ch + 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, &(ptdlsinfo->candidate_ch), &(pattrib->pktlen)); + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + + //ch switch timing + _rtw_memcpy(ch_switch_timing, &switch_time, 2); + _rtw_memcpy(ch_switch_timing+2, &switch_timeout, 2); + pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen)); + + //update ch switch attrib to sta_info + ptdls_sta->off_ch=ptdlsinfo->candidate_ch; + ptdls_sta->ch_switch_time=switch_time; + ptdls_sta->ch_switch_timeout=switch_timeout; + +} + +void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 payload_type = 0x02; + unsigned char category = RTW_WLAN_CATEGORY_TDLS; + unsigned char action = TDLS_CHANNEL_SWITCH_RESPONSE; + u8 link_id_addr[18] = {0}; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u8 ch_switch_timing[4] = {0}; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, action, status_code + 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, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen)); + + //Link identifier + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); + + //ch switch timing + _rtw_memcpy(ch_switch_timing, &ptdls_sta->ch_switch_time, 2); + _rtw_memcpy(ch_switch_timing+2, &ptdls_sta->ch_switch_timeout, 2); + pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen)); + +} + +#ifdef CONFIG_WFD +void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo; + u8 payload_type = 0x02; + u8 category = RTW_WLAN_CATEGORY_P2P; + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a}; + u8 probe_req = 4; + u8 wfdielen = 0; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, OUI, frame_body_type + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen)); + + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) + { + wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + +} + +void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo; + u8 payload_type = 0x02; + u8 category = RTW_WLAN_CATEGORY_P2P; + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a}; + u8 probe_rsp = 5; + u8 wfdielen = 0; + + //payload type + pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); + //category, OUI, frame_body_type + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen)); + + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) + { + wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + +} +#endif //CONFIG_WFD + +void _TPK_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + + ptdls_sta->TPK_count++; + //TPK_timer set 1000 as default + //retry timer should set at least 301 sec. + if(ptdls_sta->TPK_count==TPK_RESEND_COUNT){ + ptdls_sta->TPK_count=0; + issue_tdls_setup_req(ptdls_sta->padapter, ptdls_sta->hwaddr); + } + + _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT); +} + +void init_TPK_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + + _init_timer(&psta->TPK_timer, padapter->pnetdev, _TPK_timer_hdl, psta); +} + +// TDLS_DONE_CH_SEN: channel sensing and report candidate channel +// TDLS_OFF_CH: first time set channel to off channel +// TDLS_BASE_CH: when go back to the channel linked with AP, send null data to peer STA as an indication +void _ch_switch_timer_hdl(void *FunctionContext) +{ + + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + + if( ptdls_sta->option == TDLS_DONE_CH_SEN ){ + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN); + }else if( ptdls_sta->option == TDLS_OFF_CH ){ + issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0); + _set_timer(&ptdls_sta->base_ch_timer, 500); + }else if( ptdls_sta->option == TDLS_BASE_CH){ + issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0); + } +} + +void init_ch_switch_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->option_timer, padapter->pnetdev, _ch_switch_timer_hdl, psta); +} + +void _base_ch_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_OFF_CH); +} + +void init_base_ch_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->base_ch_timer, padapter->pnetdev, _base_ch_timer_hdl, psta); +} + +void _off_ch_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_BASE_CH ); +} + +void init_off_ch_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->off_ch_timer, padapter->pnetdev, _off_ch_timer_hdl, psta); +} + +void _tdls_handshake_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + + if(ptdls_sta != NULL) + { + if( !(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) ) + { + DBG_871X("tdls handshake time out\n"); + free_tdls_sta(ptdls_sta->padapter, ptdls_sta); + } + } +} + +void init_handshake_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta); +} + +//Check tdls peer sta alive. +void _tdls_alive_timer_phase1_hdl(void *FunctionContext) +{ + _irqL irqL; + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL); + ptdls_sta->timer_flag = 1; + _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL); + + ptdls_sta->tdls_sta_state &= (~TDLS_ALIVE_STATE); + + DBG_871X("issue_tdls_dis_req to check alive\n"); + issue_tdls_dis_req( padapter, ptdls_sta->hwaddr); + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH1); + sta_update_last_rx_pkts(ptdls_sta); + + if ( ptdls_sta->timer_flag == 2 ) + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA); + else + { + _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL); + ptdls_sta->timer_flag = 0; + _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL); + } + +} + +void _tdls_alive_timer_phase2_hdl(void *FunctionContext) +{ + _irqL irqL; + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + ptdls_sta->timer_flag = 1; + _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL); + + if( (ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) && + (sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta)) ) + { + DBG_871X("TDLS STA ALIVE, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n", + sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta)); + + ptdls_sta->alive_count = 0; + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2); + } + else + { + if( !(ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) ) + DBG_871X("TDLS STA TOO FAR\n"); + if( !(sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta))) + DBG_871X("TDLS LINK WITH LOW TRAFFIC, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n", + sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta)); + + ptdls_sta->alive_count++; + if( ptdls_sta->alive_count == TDLS_ALIVE_COUNT ) + { + ptdls_sta->stat_code = _RSON_TDLS_TEAR_TOOFAR_; + issue_tdls_teardown(padapter, ptdls_sta->hwaddr); + } + else + { + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2); + } + } + + if ( ptdls_sta->timer_flag == 2 ) + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA); + else + { + _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + ptdls_sta->timer_flag = 0; + _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL); +} + +} + +void init_tdls_alive_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->alive_timer1, padapter->pnetdev, _tdls_alive_timer_phase1_hdl, psta); + _init_timer(&psta->alive_timer2, padapter->pnetdev, _tdls_alive_timer_phase2_hdl, psta); +} + +int update_sgi_tdls(_adapter *padapter, struct sta_info *psta) +{ + struct ht_priv *psta_ht = NULL; + psta_ht = &psta->htpriv; + + if(psta_ht->ht_option) + { + return psta_ht->sgi; + } + else + return _FALSE; +} + +u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta) +{ + int i; + u8 rf_type, id; + unsigned char sta_band = 0; + unsigned char limit; + unsigned int tx_ra_bitmap=0; + struct ht_priv *psta_ht = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + + psta_ht = &psta->htpriv; + //b/g mode ra_bitmap + for (i=0; ibssrateset); i++) + { + if (psta->bssrateset[i]) + tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f); + } + + //n mode ra_bitmap + if(psta_ht->ht_option) + { + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if(rf_type == RF_2T2R) + limit=16;// 2R + else + limit=8;// 1R + + for (i=0; iht_cap.supp_mcs_set[i/8] & BIT(i%8)) + tx_ra_bitmap |= BIT(i+12); + } + } + + if ( pcur_network->Configuration.DSConfig > 14 ) { + // 5G band + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_5N | WIRELESS_11A; + else + sta_band |= WIRELESS_11A; + } else { + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; + else if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11G |WIRELESS_11B; + else + sta_band |= WIRELESS_11B; + } + + id = networktype_to_raid(sta_band); + tx_ra_bitmap |= ((id<<28)&0xf0000000); + return tx_ra_bitmap; +} + +#endif //CONFIG_TDLS + diff --git a/rtl8192cu-fixes/core/rtw_wlan_util.c b/rtl8192cu-fixes/core/rtw_wlan_util.c new file mode 100755 index 00000000..56dac60d --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_wlan_util.c @@ -0,0 +1,2305 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_WLAN_UTIL_C_ + +#include +#include +#include +#include + + +unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f}; +unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74}; + +unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18}; +unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7}; +unsigned char BROADCOM_OUI3[] = {0x00, 0x05, 0xb5}; + +unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96}; +unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43}; +unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43}; +unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c}; +unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5}; + +unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; + +extern unsigned char MCS_rate_2R[16]; +#ifdef CONFIG_DISABLE_MCS13TO15 +extern unsigned char MCS_rate_2R_MCS13TO15_OFF[16]; +#endif //CONFIG_DISABLE_MCS13TO15 +extern unsigned char MCS_rate_1R[16]; +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WPA_TKIP_CIPHER[4]; +extern unsigned char RSN_TKIP_CIPHER[4]; + +#define R2T_PHY_DELAY (0) + +//#define WAIT_FOR_BCN_TO_MIN (3000) +#define WAIT_FOR_BCN_TO_MIN (6000) +#define WAIT_FOR_BCN_TO_MAX (20000) + +static u8 rtw_basic_rate_cck[4] = { + IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK +}; + +static u8 rtw_basic_rate_ofdm[3] = { + IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK +}; + +static u8 rtw_basic_rate_mix[7] = { + IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK +}; + + +int cckrates_included(unsigned char *rate, int ratelen) +{ + int i; + + for(i = 0; i < ratelen; i++) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + } + + return _FALSE; + +} + +int cckratesonly_included(unsigned char *rate, int ratelen) +{ + int i; + + for(i = 0; i < ratelen; i++) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + return _FALSE; + } + + return _TRUE; +} + +unsigned char networktype_to_raid(unsigned char network_type) +{ + unsigned char raid; + + switch(network_type) + { + case WIRELESS_11B: + raid = 6; + break; + case WIRELESS_11A: + case WIRELESS_11G: + raid = 5; + break; + case WIRELESS_11BG: + raid = 4; + break; + case WIRELESS_11_24N: + case WIRELESS_11_5N: + raid = 3; + break; + case WIRELESS_11A_5N: + case WIRELESS_11G_24N: + raid = 1; + break; + case WIRELESS_11BG_24N: + raid = 0; + break; + default: + raid = 4; + break; + + } + + return raid; + +} + +int judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen) +{ + int network_type = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + if(pmlmeext->cur_channel > 14) + { + if (pmlmeinfo->HT_enable) + { + network_type = WIRELESS_11_5N; + } + + network_type |= WIRELESS_11A; + } + else + { + if (pmlmeinfo->HT_enable) + { + network_type = WIRELESS_11_24N; + } + + if ((cckratesonly_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11B; + } + else if((cckrates_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11BG; + } + else + { + network_type |= WIRELESS_11G; + } + } + + return network_type; +} + +unsigned char ratetbl_val_2wifirate(unsigned char rate); +unsigned char ratetbl_val_2wifirate(unsigned char rate) +{ + unsigned char val = 0; + + switch (rate & 0x7f) + { + case 0: + val = IEEE80211_CCK_RATE_1MB; + break; + + case 1: + val = IEEE80211_CCK_RATE_2MB; + break; + + case 2: + val = IEEE80211_CCK_RATE_5MB; + break; + + case 3: + val = IEEE80211_CCK_RATE_11MB; + break; + + case 4: + val = IEEE80211_OFDM_RATE_6MB; + break; + + case 5: + val = IEEE80211_OFDM_RATE_9MB; + break; + + case 6: + val = IEEE80211_OFDM_RATE_12MB; + break; + + case 7: + val = IEEE80211_OFDM_RATE_18MB; + break; + + case 8: + val = IEEE80211_OFDM_RATE_24MB; + break; + + case 9: + val = IEEE80211_OFDM_RATE_36MB; + break; + + case 10: + val = IEEE80211_OFDM_RATE_48MB; + break; + + case 11: + val = IEEE80211_OFDM_RATE_54MB; + break; + + } + + return val; + +} + +int is_basicrate(_adapter *padapter, unsigned char rate); +int is_basicrate(_adapter *padapter, unsigned char rate) +{ + int i; + unsigned char val; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + for(i = 0; i < NumRates; i++) + { + val = pmlmeext->basicrate[i]; + + if ((val != 0xff) && (val != 0xfe)) + { + if (rate == ratetbl_val_2wifirate(val)) + { + return _TRUE; + } + } + } + + return _FALSE; +} + +unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset); +unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset) +{ + int i; + unsigned char rate; + unsigned int len = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + for (i = 0; i < NumRates; i++) + { + rate = pmlmeext->datarate[i]; + + switch (rate) + { + case 0xff: + return len; + + case 0xfe: + continue; + + default: + rate = ratetbl_val_2wifirate(rate); + + if (is_basicrate(padapter, rate) == _TRUE) + { + rate |= IEEE80211_BASIC_RATE_MASK; + } + + rateset[len] = rate; + len++; + break; + } + } + return len; +} + + +void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len) +{ + unsigned char supportedrates[NumRates]; + + _rtw_memset(supportedrates, 0, NumRates); + *bssrate_len = ratetbl2rateset(padapter, supportedrates); + _rtw_memcpy(pbssrate, supportedrates, *bssrate_len); +} + +void UpdateBrateTbl( + IN PADAPTER Adapter, + IN u8 *mBratesOS +) +{ + u8 i; + u8 rate; + + // 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. + for(i=0;ipbuddy_adapter; + if(pbuddy_adapter) + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag)); +#endif + + rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag)); + +} + +void Restore_DM_Func_Flag(_adapter *padapter) +{ + u8 bSaveFlag = _FALSE; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + if(pbuddy_adapter) + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag)); +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag)); +} + +void Switch_DM_Func(_adapter *padapter, u8 mode, u8 enable) +{ +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; +#endif + + if(enable == _TRUE) + { +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter) + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode)); +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode)); + } + else + { +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter) + rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); + } + +#if 0 + u8 val8; + + val8 = rtw_read8(padapter, FW_DYNAMIC_FUN_SWITCH); + + if(enable == _TRUE) + { + rtw_write8(padapter, FW_DYNAMIC_FUN_SWITCH, (val8 | mode)); + } + else + { + rtw_write8(padapter, FW_DYNAMIC_FUN_SWITCH, (val8 & mode)); + } +#endif + +} + +static void Set_NETYPE1_MSR(_adapter *padapter, u8 type) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS1, (u8 *)(&type)); +} + +static void Set_NETYPE0_MSR(_adapter *padapter, u8 type) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); +} + +void Set_MSR(_adapter *padapter, u8 type) +{ +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type == IFACE_PORT1) + { + Set_NETYPE1_MSR(padapter, type); + } + else +#endif + { + Set_NETYPE0_MSR(padapter, type); + } +} + +inline u8 rtw_get_oper_ch(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_channel; +} + +inline void rtw_set_oper_ch(_adapter *adapter, u8 ch) +{ + if (adapter_to_dvobj(adapter)->oper_channel != ch) + adapter_to_dvobj(adapter)->on_oper_ch_time = rtw_get_current_time(); + + adapter_to_dvobj(adapter)->oper_channel = ch; +} + +inline u8 rtw_get_oper_bw(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_bwmode; +} + +inline void rtw_set_oper_bw(_adapter *adapter, u8 bw) +{ + adapter_to_dvobj(adapter)->oper_bwmode = bw; +} + +inline u8 rtw_get_oper_choffset(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_ch_offset; +} + +inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset) +{ + adapter_to_dvobj(adapter)->oper_ch_offset = offset; +} + +inline u32 rtw_get_on_oper_ch_time(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->on_oper_ch_time; +} + +inline u32 rtw_get_on_cur_ch_time(_adapter *adapter) +{ + if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel) + return adapter_to_dvobj(adapter)->on_oper_ch_time; + else + return 0; +} + +void SelectChannel(_adapter *padapter, unsigned char channel) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + +#ifdef CONFIG_DUALMAC_CONCURRENT + //saved channel info + rtw_set_oper_ch(padapter, channel); + dc_SelectChannel(padapter, channel); +#else //CONFIG_DUALMAC_CONCURRENT + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + + //saved channel info + rtw_set_oper_ch(padapter, channel); + + rtw_hal_set_chan(padapter, channel); + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + +#endif // CONFIG_DUALMAC_CONCURRENT +} + +void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + +#ifdef CONFIG_DUALMAC_CONCURRENT + //saved bw info + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + dc_SetBWMode(padapter, bwmode, channel_offset); +#else //CONFIG_DUALMAC_CONCURRENT + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL); + + //saved bw info + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + + rtw_hal_set_bwmode(padapter, (HT_CHANNEL_WIDTH)bwmode, channel_offset); + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL); + +#endif // CONFIG_DUALMAC_CONCURRENT +} + +void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode) +{ + u8 center_ch; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if ( padapter->bNotifyChannelChange ) + { + DBG_871X( "[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode ); + } + + if((bwmode == HT_CHANNEL_WIDTH_20)||(channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) + { + //SelectChannel(padapter, channel); + center_ch = channel; + } + else + { + //switch to the proper channel + if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + { + //SelectChannel(padapter, channel + 2); + center_ch = channel + 2; + } + else + { + //SelectChannel(padapter, channel - 2); + center_ch = channel - 2; + } + } + + //set Channel , must be independant for correct co_ch value/ +#ifdef CONFIG_DUALMAC_CONCURRENT + //saved channel/bw info + rtw_set_oper_ch(padapter, channel); + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + dc_SelectChannel(padapter, center_ch);// set center channel +#else //CONFIG_DUALMAC_CONCURRENT + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + + //saved channel/bw info + rtw_set_oper_ch(padapter, channel); + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + + rtw_hal_set_chan(padapter, center_ch); + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + +#endif // CONFIG_DUALMAC_CONCURRENT + + + //set BandWidth + SetBWMode(padapter, bwmode, channel_offset); + +} + +int get_bsstype(unsigned short capability) +{ + if (capability & BIT(0)) + { + return WIFI_FW_AP_STATE; + } + else if (capability & BIT(1)) + { + return WIFI_FW_ADHOC_STATE; + } + else + { + return 0; + } +} + +__inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork) +{ + return (pnetwork->MacAddress); +} + +u16 get_beacon_interval(WLAN_BSSID_EX *bss) +{ + unsigned short val; + _rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2); + + return le16_to_cpu(val); + +} + +int is_client_associated_to_ap(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + + if(!padapter) + return _FAIL; + + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)) + { + return _TRUE; + } + else + { + return _FAIL; + } +} + +int is_client_associated_to_ibss(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) + { + return _TRUE; + } + else + { + return _FAIL; + } +} + +int is_IBSS_empty(_adapter *padapter) +{ + unsigned int i; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) + { + if (pmlmeinfo->FW_sta_info[i].status == 1) + { + return _FAIL; + } + } + + return _TRUE; + +} + +unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval) +{ + if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN) + { + return WAIT_FOR_BCN_TO_MIN; + } + else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX) + { + return WAIT_FOR_BCN_TO_MAX; + } + else + { + return ((bcn_interval << 2)); + } +} + +void CAM_empty_entry( + PADAPTER Adapter, + u8 ucIndex +) +{ + rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex)); +} + +void invalidate_cam_all(_adapter *padapter) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0); +} +#if 0 +static u32 _ReadCAM(_adapter *padapter ,u32 addr) +{ + u32 count = 0, cmd; + cmd = CAM_POLLINIG |addr ; + rtw_write32(padapter, RWCAM, cmd); + + do{ + if(0 == (rtw_read32(padapter,REG_CAMCMD) & CAM_POLLINIG)){ + break; + } + }while(count++ < 100); + + return rtw_read32(padapter,REG_CAMREAD); +} +void read_cam(_adapter *padapter ,u8 entry) +{ + u32 j,count = 0, addr, cmd; + addr = entry << 3; + + printk("********* DUMP CAM Entry_#%02d***************\n",entry); + for (j = 0; j < 6; j++) + { + cmd = _ReadCAM(padapter ,addr+j); + printk("offset:0x%02x => 0x%08x \n",addr+j,cmd); + } + printk("*********************************\n"); +} +#endif + +void write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key) +{ + unsigned int i, val, addr; + //unsigned int cmd; + int j; + u32 cam_val[2]; + + addr = entry << 3; + + for (j = 5; j >= 0; j--) + { + switch (j) + { + case 0: + val = (ctrl | (mac[0] << 16) | (mac[1] << 24) ); + break; + + case 1: + val = (mac[2] | ( mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24)); + break; + + default: + i = (j - 2) << 2; + val = (key[i] | (key[i+1] << 8) | (key[i+2] << 16) | (key[i+3] << 24)); + break; + + } + + cam_val[0] = val; + cam_val[1] = addr + (unsigned int)j; + + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val); + + //rtw_write32(padapter, WCAMI, val); + + //cmd = CAM_POLLINIG | CAM_WRITE | (addr + j); + //rtw_write32(padapter, RWCAM, cmd); + + //DBG_871X("%s=> cam write: %x, %x\n",__FUNCTION__, cmd, val); + + } + +} + +void clear_cam_entry(_adapter *padapter, u8 entry) +{ +#if 0 + u32 addr, val=0; + u32 cam_val[2]; + + addr = entry << 3; + + + cam_val[0] = val; + cam_val[1] = addr + (unsigned int)0; + + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val); + + + + cam_val[0] = val; + cam_val[1] = addr + (unsigned int)1; + + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val); +#else + + unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00}; + + write_cam(padapter, entry, 0, null_sta, null_key); + +#endif +} + +int allocate_fw_sta_entry(_adapter *padapter) +{ + unsigned int mac_id; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) + { + if (pmlmeinfo->FW_sta_info[mac_id].status == 0) + { + pmlmeinfo->FW_sta_info[mac_id].status = 1; + pmlmeinfo->FW_sta_info[mac_id].retry = 0; + break; + } + } + + return mac_id; +} + +void flush_all_cam_entry(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +#ifdef CONFIG_CONCURRENT_MODE + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + //if(check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_)) + if(check_buddy_fwstate(padapter, _FW_LINKED) == _FALSE) + { + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0); + } + else + { + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; + u8 cam_id;//cam_entry + + psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); + if(psta) { + if(psta->state & WIFI_AP_STATE) + {} //clear cam when ap free per sta_info + else { + if(psta->mac_id==2) + cam_id = 5; + else + cam_id = 4; + } + //clear_cam_entry(padapter, cam_id); + rtw_clearstakey_cmd(padapter, (u8*)psta, cam_id, _FALSE); + } + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + //clear cam when ap free per sta_info + } + } +#else //CONFIG_CONCURRENT_MODE + + rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0); + +#endif //CONFIG_CONCURRENT_MODE + + _rtw_memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info)); + +} + +#if defined(CONFIG_P2P) && defined(CONFIG_WFD) +int WFD_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wifidirect_info *pwdinfo; + u8 wfd_ie[ 128 ] = { 0x00 }; + u32 wfd_ielen = 0; + + + pwdinfo = &padapter->wdinfo; + if ( rtw_get_wfd_ie( ( u8* ) pIE, pIE->Length, wfd_ie, &wfd_ielen ) ) + { + u8 attr_content[ 10 ] = { 0x00 }; + u32 attr_contentlen = 0; + + printk( "[%s] Found WFD IE\n", __FUNCTION__ ); + rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen); + if ( attr_contentlen ) + { + pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + return( _TRUE ); + } + } + else + { + printk( "[%s] NO WFD IE\n", __FUNCTION__ ); + + } + return( _FAIL ); +} +#endif + +int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + //struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pmlmepriv->qospriv.qos_option==0) + { + pmlmeinfo->WMM_enable = 0; + return _FAIL; + } + + pmlmeinfo->WMM_enable = 1; + _rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); + return _TRUE; + + /*if (pregpriv->wifi_spec == 1) + { + if (pmlmeinfo->WMM_enable == 1) + { + //todo: compare the parameter set count & decide wheher to update or not + return _FAIL; + } + else + { + pmlmeinfo->WMM_enable = 1; + _rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); + return _TRUE; + } + } + else + { + pmlmeinfo->WMM_enable = 0; + return _FAIL; + }*/ + +} + +void WMMOnAssocRsp(_adapter *padapter) +{ + u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; + u8 acm_mask; + u16 TXOP; + u32 acParm, i; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (pmlmeinfo->WMM_enable == 0) + { + padapter->mlmepriv.acm_mask = 0; + return; + } + + acm_mask = 0; + + if( pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + for (i = 0; i < 4; i++) + { + ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03; + ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01; + + //AIFS = AIFSN * slot time + SIFS - r2t phy delay + AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime; + + ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f); + ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4; + TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit); + + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + + switch (ACI) + { + case 0x0: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(1):0); + break; + + case 0x1: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); + //acm_mask |= (ACM? BIT(0):0); + break; + + case 0x2: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(2):0); + break; + + case 0x3: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(3):0); + break; + } + + DBG_871X("WMM(%x): %x, %x\n", ACI, ACM, acParm); + } + + if(padapter->registrypriv.acm_method == 1) + rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask)); + else + padapter->mlmepriv.acm_mask = acm_mask; + + return; +} + +static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + unsigned char new_bwmode; + unsigned char new_ch_offset; + struct HT_info_element *pHT_info; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + u8 cbw40_enable=0; + + if(!pIE) + return; + + if(phtpriv->ht_option == _FALSE) return; + + if(pIE->Length > sizeof(struct HT_info_element)) + return; + + pHT_info = (struct HT_info_element *)pIE->data; + + if (pmlmeext->cur_channel > 14) { + if (pregistrypriv->cbw40_enable & BIT(1)) + cbw40_enable = 1; + } else { + if (pregistrypriv->cbw40_enable & BIT(0)) + cbw40_enable = 1; + } + + if((pHT_info->infos[0] & BIT(2)) && cbw40_enable ) + { + new_bwmode = HT_CHANNEL_WIDTH_40; + + switch (pHT_info->infos[0] & 0x3) + { + case 1: + new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case 3: + new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + } + else + { + new_bwmode = HT_CHANNEL_WIDTH_20; + new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + + if((new_bwmode!= pmlmeext->cur_bwmode) || (new_ch_offset!=pmlmeext->cur_ch_offset)) + { + pmlmeinfo->bwmode_updated = _TRUE; + + pmlmeext->cur_bwmode = new_bwmode; + pmlmeext->cur_ch_offset = new_ch_offset; + + //update HT info also + HT_info_handler(padapter, pIE); + } + else + { + pmlmeinfo->bwmode_updated = _FALSE; + } + + + if(_TRUE == pmlmeinfo->bwmode_updated) + { + struct sta_info *psta; + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + + //update ap's stainfo + psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); + if(psta) + { + struct ht_priv *phtpriv_sta = &psta->htpriv; + + if(phtpriv_sta->ht_option) + { + // bwmode + phtpriv_sta->bwmode = pmlmeext->cur_bwmode; + phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; + } + else + { + phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20; + phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + } + + //pmlmeinfo->bwmode_updated = _FALSE;//bwmode_updated done, reset it! + + } + +} + +void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + unsigned int i; + u8 rf_type; + u8 max_AMPDU_len, min_MPDU_spacing; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + if(pIE==NULL) return; + + if(phtpriv->ht_option == _FALSE) return; + + pmlmeinfo->HT_caps_enable = 1; + + for (i = 0; i < (pIE->Length); i++) + { + if (i != 2) + { + // Commented by Albert 2010/07/12 + // Got the endian issue here. + pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]); + } + else + { + //modify from fw by Thomas 2010/11/17 + if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3)) + { + max_AMPDU_len = (pIE->data[i] & 0x3); + } + else + { + max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3); + } + + 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); + } + else + { + min_MPDU_spacing = (pIE->data[i] & 0x1c); + } + + pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; + } + } + + // Commented by Albert 2010/07/12 + // Have to handle the endian issue after copying. + // HT_ext_caps didn't be used yet. + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info ); + pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps ); + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + //update the MCS rates + for (i = 0; i < 16; i++) + { + if((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) + { + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + } + else + { + #ifdef CONFIG_DISABLE_MCS13TO15 + if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && (pregistrypriv->wifi_spec!=1)) + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R_MCS13TO15_OFF[i]; + else + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; + #else + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i]; + #endif //CONFIG_DISABLE_MCS13TO15 + } + #ifdef RTL8192C_RECONFIG_TO_1T1R + { + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + } + #endif + + if(pregistrypriv->special_rf_path) + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + + } + + return; +} + +void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + + if(pIE==NULL) return; + + if(phtpriv->ht_option == _FALSE) return; + + + if(pIE->Length > sizeof(struct HT_info_element)) + return; + + pmlmeinfo->HT_info_enable = 1; + _rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length); + + return; +} + +void HTOnAssocRsp(_adapter *padapter) +{ + unsigned char max_AMPDU_len; + unsigned char min_MPDU_spacing; + //struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) + { + pmlmeinfo->HT_enable = 1; + } + else + { + pmlmeinfo->HT_enable = 0; + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + return; + } + + //handle A-MPDU parameter field + /* + AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + AMPDU_para [4:2]:Min MPDU Start Spacing + */ + max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); + +#if 0 //move to rtw_update_ht_cap() + if ((pregpriv->cbw40_enable) && + (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && + (pmlmeinfo->HT_info.infos[0] & BIT(2))) + { + //switch to the 40M Hz mode accoring to the AP + pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40; + switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) + { + case HT_EXTCHNL_OFFSET_UPPER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case HT_EXTCHNL_OFFSET_LOWER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); + } +#endif + + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + +#if 0 //move to rtw_update_ht_cap() + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; +#endif + +} + +void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pIE->Length>1) + return; + + pmlmeinfo->ERP_enable = 1; + _rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length); +} + +void VCS_update(_adapter *padapter, struct sta_info *psta) +{ + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + switch (pregpriv->vrtl_carrier_sense)/* 0:off 1:on 2:auto */ + { + case 0: //off + psta->rtsen = 0; + psta->cts2self = 0; + break; + + case 1: //on + if (pregpriv->vcs_type == 1) /* 1:RTS/CTS 2:CTS to self */ + { + psta->rtsen = 1; + psta->cts2self = 0; + } + else + { + psta->rtsen = 0; + psta->cts2self = 1; + } + break; + + case 2: //auto + default: + if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) + { + if (pregpriv->vcs_type == 1) + { + psta->rtsen = 1; + psta->cts2self = 0; + } + else + { + psta->rtsen = 0; + psta->cts2self = 1; + } + } + else + { + psta->rtsen = 0; + psta->cts2self = 0; + } + break; + } +} + +#ifdef CONFIG_TDLS +int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len) +{ + u8 tdls_prohibited_bit = 0x40; //bit(38); TDLS_prohibited + + if(pkt_len < 5) + { + return _FALSE; + } + + pframe += 4; + if( (*pframe) & tdls_prohibited_bit ) + return _TRUE; + + return _FALSE; +} +#endif //CONFIG_TDLS + +void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) +{ + unsigned int i; + unsigned int len; + PNDIS_802_11_VARIABLE_IEs pIE; + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; //bit(38): TDLS_prohibited +#endif //CONFIG_TDLS + + len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); + + for (i = 0; i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); + + switch (pIE->ElementID) + { +#if 0 + case _VENDOR_SPECIFIC_IE_: + //todo: to update WMM paramter set while receiving beacon + if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM + { + (WMM_param_handler(padapter, pIE))? WMMOnAssocRsp(padapter): 0; + } + break; +#endif + + case _HT_EXTRA_INFO_IE_: //HT info + //HT_info_handler(padapter, pIE); + bwmode_update_check(padapter, pIE); + break; + + case _ERPINFO_IE_: + ERP_IE_handler(padapter, pIE); + VCS_update(padapter, psta); + break; + +#ifdef CONFIG_TDLS + case _EXT_CAP_IE_: + if( check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE ) + ptdlsinfo->ap_prohibited = _TRUE; + break; +#endif //CONFIG_TDLS + default: + break; + } + + i += (pIE->Length + 2); + } +} + +#ifdef CONFIG_DFS +void process_csa_ie(_adapter *padapter, u8 *pframe, uint pkt_len) +{ + unsigned int i; + unsigned int len; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 new_ch_no = 0; + + len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); + + for (i = 0; i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); + + switch (pIE->ElementID) + { + case _CH_SWTICH_ANNOUNCE_: + _rtw_memcpy(&new_ch_no, pIE->data+1, 1); + rtw_set_csa_cmd(padapter, new_ch_no); + break; + + default: + break; + } + + i += (pIE->Length + 2); + } +} +#endif //CONFIG_DFS + +unsigned int is_ap_in_tkip(_adapter *padapter) +{ + u32 i; + PNDIS_802_11_VARIABLE_IEs pIE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + + if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) + { + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))) + { + return _TRUE; + } + break; + + case _RSN_IE_2_: + if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4)) + { + return _TRUE; + } + + default: + break; + } + + i += (pIE->Length + 2); + } + + return _FALSE; + } + else + { + return _FALSE; + } + +} + +int wifirate2_ratetbl_inx(unsigned char rate); +int wifirate2_ratetbl_inx(unsigned char rate) +{ + int inx = 0; + rate = rate & 0x7f; + + switch (rate) + { + case 54*2: + inx = 11; + break; + + case 48*2: + inx = 10; + break; + + case 36*2: + inx = 9; + break; + + case 24*2: + inx = 8; + break; + + case 18*2: + inx = 7; + break; + + case 12*2: + inx = 6; + break; + + case 9*2: + inx = 5; + break; + + case 6*2: + inx = 4; + break; + + case 11*2: + inx = 3; + break; + case 11: + inx = 2; + break; + + case 2*2: + inx = 1; + break; + + case 1*2: + inx = 0; + break; + + } + return inx; +} + +unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz) +{ + unsigned int i, num_of_rate; + unsigned int mask = 0; + + num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz; + + for (i = 0; i < num_of_rate; i++) + { + if ((*(ptn + i)) & 0x80) + { + mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); + } + } + return mask; +} + +unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz) +{ + unsigned int i, num_of_rate; + unsigned int mask = 0; + + num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz; + + for (i = 0; i < num_of_rate; i++) + { + mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); + } + + return mask; +} + +unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps) +{ + unsigned int mask = 0; + + mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20)); + + return mask; +} + +int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps) +{ + unsigned char bit_offset; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (!(pmlmeinfo->HT_enable)) + return _FAIL; + + if ((pmlmeinfo->assoc_AP_vendor == ralinkAP)) + return _FAIL; + + bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40)? 6: 5; + + if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset)) + { + return _SUCCESS; + } + else + { + return _FAIL; + } +} + +unsigned char get_highest_rate_idx(u32 mask) +{ + int i; + unsigned char rate_idx=0; + + for(i=27; i>=0; i--) + { + if(mask & BIT(i)) + { + rate_idx = i; + break; + } + } + + return rate_idx; +} + +unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps); +unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps) +{ + int i, mcs_rate; + + mcs_rate = (pHT_caps->u.HT_cap_element.MCS_rate[0] | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 8)); + + for (i = 15; i >= 0; i--) + { + if (mcs_rate & (0x1 << i)) + { + break; + } + } + + return i; +} + +void Update_RA_Entry(_adapter *padapter, u32 mac_id) +{ + rtw_hal_update_ra_mask(padapter, mac_id); +} + +void enable_rate_adaptive(_adapter *padapter, u32 mac_id); +void enable_rate_adaptive(_adapter *padapter, u32 mac_id) +{ + Update_RA_Entry(padapter, mac_id); +} + +void set_sta_rate(_adapter *padapter, struct sta_info *psta) +{ + //rate adaptive + enable_rate_adaptive(padapter, psta->mac_id); +} + +// Update RRSR and Rate for USERATE +void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode) +{ + NDIS_802_11_RATES_EX supported_rates; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; + + // Added by Albert 2011/03/22 + // In the P2P mode, the driver should not support the b mode. + // So, the Tx packet shouldn't use the CCK rate + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; +#endif //CONFIG_P2P +#ifdef CONFIG_INTEL_WIDI + if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE) + return; +#endif //CONFIG_INTEL_WIDI + + _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX); + + //clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band. + if(pmlmeext->cur_channel > 14) + wirelessmode &= ~(WIRELESS_11B); + + if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) { + _rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4); + } else if (wirelessmode & WIRELESS_11B) { + _rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7); + } else { + _rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3); + } + + if (wirelessmode & WIRELESS_11B) + update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); + else + update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); + + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates); +} + +unsigned char check_assoc_AP(u8 *pframe, uint len) +{ + unsigned int i; + PNDIS_802_11_VARIABLE_IEs pIE; + + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3))) + { + DBG_871X("link to Artheros AP\n"); + return atherosAP; + } + else if ((_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3)) + || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3)) + || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3))) + { + DBG_871X("link to Broadcom AP\n"); + return broadcomAP; + } + else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3)) + { + DBG_871X("link to Marvell AP\n"); + return marvellAP; + } + else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3)) + { + DBG_871X("link to Ralink AP\n"); + return ralinkAP; + } + else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3)) + { + DBG_871X("link to Cisco AP\n"); + return ciscoAP; + } + else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3)) + { + DBG_871X("link to Realtek 96B\n"); + return realtekAP; + } + else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI,3)) + { + DBG_871X("link to Airgo Cap\n"); + return airgocapAP; + } + else + { + break; + } + + default: + break; + } + + i += (pIE->Length + 2); + } + + DBG_871X("link to new AP\n"); + return unknownAP; +} + +void update_IOT_info(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + switch (pmlmeinfo->assoc_AP_vendor) + { + case marvellAP: + pmlmeinfo->turboMode_cts2self = 1; + pmlmeinfo->turboMode_rtsen = 0; + break; + + case ralinkAP: + pmlmeinfo->turboMode_cts2self = 0; + pmlmeinfo->turboMode_rtsen = 1; + //disable high power + Switch_DM_Func(padapter, (~DYNAMIC_FUNC_HP), _FALSE); + break; + case realtekAP: + //rtw_write16(padapter, 0x4cc, 0xffff); + //rtw_write16(padapter, 0x546, 0x01c0); + //disable high power + Switch_DM_Func(padapter, (~DYNAMIC_FUNC_HP), _FALSE); + break; + default: + pmlmeinfo->turboMode_cts2self = 0; + pmlmeinfo->turboMode_rtsen = 1; + break; + } + +} + +void update_capinfo(PADAPTER Adapter, u16 updateCap) +{ + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + BOOLEAN ShortPreamble; + + // Check preamble mode, 2005.01.06, by rcnjko. + // Mark to update preamble value forever, 2008.03.18 by lanhsin + //if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO ) + { + + if(updateCap & cShortPreamble) + { // Short Preamble + if(pmlmeinfo->preamble_mode != PREAMBLE_SHORT) // PREAMBLE_LONG or PREAMBLE_AUTO + { + ShortPreamble = _TRUE; + pmlmeinfo->preamble_mode = PREAMBLE_SHORT; + rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble ); + } + } + else + { // Long Preamble + if(pmlmeinfo->preamble_mode != PREAMBLE_LONG) // PREAMBLE_SHORT or PREAMBLE_AUTO + { + ShortPreamble = _FALSE; + pmlmeinfo->preamble_mode = PREAMBLE_LONG; + rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble ); + } + } + } + + if ( updateCap & cIBSS ) { + //Filen: See 802.11-2007 p.91 + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + else + { + //Filen: See 802.11-2007 p.90 + if( pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) + { + if( (updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */) + { // Short Slot Time + if(pmlmeinfo->slotTime != SHORT_SLOT_TIME) + { + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + } + } + else + { // Long Slot Time + if(pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME) + { + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + } + } + else if( pmlmeext->cur_wireless_mode & (WIRELESS_11A | WIRELESS_11_5N)) + { + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + } + else + { + //B Mode + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + } + + rtw_hal_set_hwreg( Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime ); + +} + +void update_wireless_mode(_adapter *padapter) +{ + u8 init_rate=0; + int ratelen, network_type = 0; + u32 SIFS_Timer, mask; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + unsigned char *rate = cur_network->SupportedRates; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; +#endif //CONFIG_CONCURRENT_MODE + + ratelen = rtw_get_rateset_len(cur_network->SupportedRates); + + if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) + { + pmlmeinfo->HT_enable = 1; + } + + if(pmlmeext->cur_channel > 14) + { + if (pmlmeinfo->HT_enable) + { + network_type = WIRELESS_11_5N; + } + + network_type |= WIRELESS_11A; + } + else + { + if (pmlmeinfo->HT_enable) + { + network_type = WIRELESS_11_24N; + } + + if ((cckratesonly_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11B; + } + else if((cckrates_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11BG; + } + else + { + network_type |= WIRELESS_11G; + } + } + + pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode; + + //For STA mode, driver need to modify initial data rate, or MAC will use wrong tx rate. + //Modified by Thomas 2012-12-3 + mask = update_supported_rate(cur_network->SupportedRates, ratelen); + init_rate = get_highest_rate_idx(mask)&0x3f; + rtw_hal_set_hwreg( padapter, HW_VAR_INIT_DATA_RATE, (u8 *)&init_rate); + +/* + if((pmlmeext->cur_wireless_mode==WIRELESS_11G) || + (pmlmeext->cur_wireless_mode==WIRELESS_11BG))//WIRELESS_MODE_G) + SIFS_Timer = 0x0a0a;//CCK + else + SIFS_Timer = 0x0e0e;//pHalData->SifsTime; //OFDM +*/ + + SIFS_Timer = 0x0a0a0808; //0x0808 -> for CCK, 0x0a0a -> for OFDM + //change this value if having IOT issues. + + rtw_hal_set_hwreg( padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); + + if (pmlmeext->cur_wireless_mode & WIRELESS_11B) + update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); + else + { + update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter && (pmlmeext->cur_wireless_mode & WIRELESS_11A)) + update_mgnt_tx_rate(pbuddy_adapter, IEEE80211_OFDM_RATE_6MB); +#endif //CONFIG_CONCURRENT_MODE + } +} + +void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value); +void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value) +{ +#if 0 + struct cmd_obj *ph2c; + struct reg_rw_parm *pwriteMacPara; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + if ((pwriteMacPara = (struct reg_rw_parm*)rtw_malloc(sizeof(struct reg_rw_parm))) == NULL) + { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + return; + } + + pwriteMacPara->rw = 1; + pwriteMacPara->addr = addr; + pwriteMacPara->value = value; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG)); + rtw_enqueue_cmd(pcmdpriv, ph2c); +#endif +} + +void update_bmc_sta_support_rate(_adapter *padapter, u32 mac_id) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pmlmeext->cur_wireless_mode & WIRELESS_11B) + { + // Only B, B/G, and B/G/N AP could use CCK rate + _rtw_memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4); + } + else + { + _rtw_memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3); + } +} + +int update_sta_support_rate(_adapter *padapter, u8* pvar_ie, uint var_ie_len, int cam_idx) +{ + unsigned int ie_len; + PNDIS_802_11_VARIABLE_IEs pIE; + int supportRateNum = 0; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + pIE = (PNDIS_802_11_VARIABLE_IEs)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len); + if (pIE == NULL) + { + return _FAIL; + } + + _rtw_memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len); + supportRateNum = ie_len; + + pIE = (PNDIS_802_11_VARIABLE_IEs)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len); + if (pIE) + { + _rtw_memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len); + } + + return _SUCCESS; + +} + +void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr) +{ + struct sta_info *psta; + u16 tid, start_seq, param; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_priv *pstapriv = &padapter->stapriv; + struct ADDBA_request *preq = (struct ADDBA_request*)paddba_req; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + psta = rtw_get_stainfo(pstapriv, addr); + + if(psta) + { + start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4; + + param = le16_to_cpu(preq->BA_para_set); + tid = (param>>2)&0x0f; + + preorder_ctrl = &psta->recvreorder_ctrl[tid]; + + #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ + preorder_ctrl->indicate_seq = start_seq; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, start_seq); + #endif + #else + preorder_ctrl->indicate_seq = 0xffff; + #endif + + preorder_ctrl->enable =(pmlmeinfo->bAcceptAddbaReq == _TRUE)? _TRUE :_FALSE; + } + +} + +void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) +{ + u8* pIE; + u32 *pbuf; + + pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + pbuf = (u32*)pIE; + + pmlmeext->TSFValue = le32_to_cpu(*(pbuf+1)); + + pmlmeext->TSFValue = pmlmeext->TSFValue << 32; + + pmlmeext->TSFValue |= le32_to_cpu(*pbuf); +} + +void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, 0); +} + +void beacon_timing_control(_adapter *padapter) +{ + rtw_hal_bcn_related_reg_setting(padapter); +} + +#if 0 +unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame) +{ + unsigned short ATIMWindow; + unsigned char *pframe; + struct tx_desc *ptxdesc; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned int rate_len, len = 0; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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}; + + _rtw_memset(beacon_frame, 0, 256); + + pframe = beacon_frame + TXDESC_SIZE; + + 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); + + SetFrameSubType(pframe, WIFI_BEACON); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + len = sizeof(struct rtw_ieee80211_hdr_3addr); + + //timestamp will be inserted by hardware + pframe += 8; + len += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + len += 2; + + // capability info: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + len += 2; + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len); + + // 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, &len); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len); + + // IBSS Parameter Set... + //ATIMWindow = cur->Configuration.ATIMWindow; + ATIMWindow = 0; + pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len); + + //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), &len); + } + + if ((len + TXDESC_SIZE) > 256) + { + //DBG_871X("marc: beacon frame too large\n"); + return 0; + } + + //fill the tx descriptor + ptxdesc = (struct tx_desc *)beacon_frame; + + //offset 0 + ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff); + ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); //default = 32 bytes for TX Desc + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00); + + //offset 8 + ptxdesc->txdw2 |= cpu_to_le32(BMC); + ptxdesc->txdw2 |= cpu_to_le32(BK); + + //offset 16 + ptxdesc->txdw4 = 0x80000000; + + //offset 20 + ptxdesc->txdw5 = 0x00000000; //1M + + return (len + TXDESC_SIZE); +} +#endif + +static _adapter *pbuddy_padapter = NULL; + +int rtw_handle_dualmac(_adapter *adapter, bool init) +{ + int status = _SUCCESS; + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + + if (!IS_HARDWARE_TYPE_8192D(adapter)) + goto exit; + + if (init) { + rtw_hal_get_def_var(adapter, HAL_DEF_DUAL_MAC_MODE, &dvobj->DualMacMode); + if (dvobj->DualMacMode == _TRUE) { + // temply disable IPS For 92D-VC + adapter->registrypriv.ips_mode = IPS_NONE; + } + + /* For SMSP on 92DU-VC, driver do not probe another Interface. */ + if ((dvobj->DualMacMode != _TRUE) && (dvobj->InterfaceNumber != 0)) { + DBG_871X("%s(): Do not init another Interface because SMSP\n",__FUNCTION__); + status = _FAIL; + goto exit; + } + +#ifndef CONFIG_CONCURRENT_MODE + if (dvobj->DualMacMode == _TRUE) { + if (pbuddy_padapter == NULL) { + pbuddy_padapter = adapter; + DBG_871X("%s(): pbuddy_padapter == NULL, Set pbuddy_padapter\n",__FUNCTION__); + } else { + adapter->pbuddy_adapter = pbuddy_padapter; + pbuddy_padapter->pbuddy_adapter = adapter; + // clear global value + pbuddy_padapter = NULL; + DBG_871X("%s(): pbuddy_padapter exist, Exchange Information\n",__FUNCTION__); + } + } + +#ifdef CONFIG_DUALMAC_CONCURRENT + if (dvobj->InterfaceNumber == 0) { + //set adapter_type/iface type + adapter->isprimary = _TRUE; + adapter->adapter_type = PRIMARY_ADAPTER; + adapter->iface_type = IFACE_PORT0; + DBG_871X("%s(): PRIMARY_ADAPTER\n",__FUNCTION__); + } else { + //set adapter_type/iface type + adapter->isprimary = _FALSE; + adapter->adapter_type = SECONDARY_ADAPTER; + adapter->iface_type = IFACE_PORT1; + DBG_871X("%s(): SECONDARY_ADAPTER\n",__FUNCTION__); + } +#endif +#endif + }else { + pbuddy_padapter = NULL; + } +exit: + return status; +} + diff --git a/rtl8192cu-fixes/core/rtw_xmit.c b/rtl8192cu-fixes/core/rtw_xmit.c new file mode 100755 index 00000000..18f1fdb3 --- /dev/null +++ b/rtl8192cu-fixes/core/rtw_xmit.c @@ -0,0 +1,4156 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_XMIT_C_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) +#error "Shall be Linux or Windows, but not both!\n" +#endif + +#ifdef PLATFORM_WINDOWS +#include +#endif + +#ifdef CONFIG_USB_HCI +#include +#endif + + +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; + +static void _init_txservq(struct tx_servq *ptxservq) +{ +_func_enter_; + _rtw_init_listhead(&ptxservq->tx_pending); + _rtw_init_queue(&ptxservq->sta_pending); + ptxservq->qcnt = 0; +_func_exit_; +} + + +void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) +{ + +_func_enter_; + + _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv)); + + _rtw_spinlock_init(&psta_xmitpriv->lock); + + //for(i = 0 ; i < MAX_NUMBLKS; i++) + // _init_txservq(&(psta_xmitpriv->blk_q[i])); + + _init_txservq(&psta_xmitpriv->be_q); + _init_txservq(&psta_xmitpriv->bk_q); + _init_txservq(&psta_xmitpriv->vi_q); + _init_txservq(&psta_xmitpriv->vo_q); + _rtw_init_listhead(&psta_xmitpriv->legacy_dz); + _rtw_init_listhead(&psta_xmitpriv->apsd); + +_func_exit_; + +} + +s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter) +{ + int i; + struct xmit_buf *pxmitbuf; + struct xmit_frame *pxframe; + sint res=_SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); + + _rtw_spinlock_init(&pxmitpriv->lock); + _rtw_spinlock_init(&pxmitpriv->lock_sctx); + _rtw_init_sema(&pxmitpriv->xmit_sema, 0); + _rtw_init_sema(&pxmitpriv->terminate_xmitthread_sema, 0); + + /* + Please insert all the queue initializaiton using _rtw_init_queue below + */ + + pxmitpriv->adapter = padapter; + + //for(i = 0 ; i < MAX_NUMBLKS; i++) + // _rtw_init_queue(&pxmitpriv->blk_strms[i]); + + _rtw_init_queue(&pxmitpriv->be_pending); + _rtw_init_queue(&pxmitpriv->bk_pending); + _rtw_init_queue(&pxmitpriv->vi_pending); + _rtw_init_queue(&pxmitpriv->vo_pending); + _rtw_init_queue(&pxmitpriv->bm_pending); + + //_rtw_init_queue(&pxmitpriv->legacy_dz_queue); + //_rtw_init_queue(&pxmitpriv->apsd_queue); + + _rtw_init_queue(&pxmitpriv->free_xmit_queue); + + /* + Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME, + and initialize free_xmit_frame below. + Please also apply free_txobj to link_up all the xmit_frames... + */ + + pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4); + + if (pxmitpriv->pallocated_frame_buf == NULL){ + pxmitpriv->pxmit_frame_buf =NULL; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_frame fail!\n")); + res= _FAIL; + goto exit; + } + pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4); + //pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - + // ((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3); + + pxframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf; + + for (i = 0; i < NR_XMITFRAME; i++) + { + _rtw_init_listhead(&(pxframe->list)); + + pxframe->padapter = padapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue)); + + pxframe++; + } + + pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; + + pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; + + + //init xmit_buf + _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue); + _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue); + + pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4); + + if (pxmitpriv->pallocated_xmitbuf == NULL){ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_buf fail!\n")); + res= _FAIL; + goto exit; + } + + pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4); + //pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - + // ((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3); + + pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmitbuf; + + for (i = 0; i < NR_XMITBUFF; i++) + { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->ext_tag = _FALSE; + +/* + pxmitbuf->pallocated_buf = rtw_zmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ); + if (pxmitbuf->pallocated_buf == NULL) + { + res = _FAIL; + goto exit; + } + + pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); + //pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -((SIZE_PTR) (pxmitbuf->pallocated_buf) &(XMITBUF_ALIGN_SZ-1)); +*/ + + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) == _FAIL) { + res= _FAIL; + goto exit; + } + +#ifdef CONFIG_SDIO_HCI + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + + pxmitbuf->flags = XMIT_VO_QUEUE; + + rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); + #ifdef DBG_XMIT_BUF + pxmitbuf->no=i; + #endif + + pxmitbuf++; + + } + + pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; + + /* init xframe_ext queue, the same count as extbuf */ + _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue); + + pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4); + + if (pxmitpriv->xframe_ext_alloc_addr == NULL){ + pxmitpriv->xframe_ext = NULL; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xframe_ext fail!\n")); + res= _FAIL; + goto exit; + } + pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4); + pxframe = (struct xmit_frame*)pxmitpriv->xframe_ext; + + for (i = 0; i < NR_XMIT_EXTBUFF; i++) { + _rtw_init_listhead(&(pxframe->list)); + + pxframe->padapter = padapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + pxframe->ext_tag = 1; + + rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue)); + + pxframe++; + } + pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF; + + // Init xmit extension buff + _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); + + pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4); + + if (pxmitpriv->pallocated_xmit_extbuf == NULL){ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_extbuf fail!\n")); + res= _FAIL; + goto exit; + } + + pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4); + + pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmit_extbuf; + + for (i = 0; i < NR_XMIT_EXTBUFF; i++) + { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->ext_tag = _TRUE; + +/* + pxmitbuf->pallocated_buf = rtw_zmalloc(MAX_XMIT_EXTBUF_SZ); + if (pxmitbuf->pallocated_buf == NULL) + { + res = _FAIL; + goto exit; + } + + pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), 4); +*/ + + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ)) == _FAIL) { + res= _FAIL; + goto exit; + } + +#ifdef CONFIG_SDIO_HCI + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + + rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue)); + #ifdef DBG_XMIT_BUF + pxmitbuf->no=i; + #endif + pxmitbuf++; + + } + + pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF; + + rtw_alloc_hwxmits(padapter); + rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); + +#ifdef CONFIG_USB_HCI + pxmitpriv->txirp_cnt=1; + + _rtw_init_sema(&(pxmitpriv->tx_retevt), 0); + + //per AC pending irp + pxmitpriv->beq_cnt = 0; + pxmitpriv->bkq_cnt = 0; + pxmitpriv->viq_cnt = 0; + pxmitpriv->voq_cnt = 0; +#endif + + +#ifdef CONFIG_XMIT_ACK + pxmitpriv->ack_tx = _FALSE; + _rtw_mutex_init(&pxmitpriv->ack_tx_mutex); + rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0); +#endif + + rtw_hal_init_xmit_priv(padapter); + +exit: + +_func_exit_; + + return res; +} + +void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv); +void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv) +{ + _rtw_spinlock_free(&pxmitpriv->lock); + _rtw_free_sema(&pxmitpriv->xmit_sema); + _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema); + + _rtw_spinlock_free(&pxmitpriv->be_pending.lock); + _rtw_spinlock_free(&pxmitpriv->bk_pending.lock); + _rtw_spinlock_free(&pxmitpriv->vi_pending.lock); + _rtw_spinlock_free(&pxmitpriv->vo_pending.lock); + _rtw_spinlock_free(&pxmitpriv->bm_pending.lock); + + //_rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); + //_rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); + + _rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock); + _rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock); + _rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock); +} + + +void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv) +{ + int i; + _adapter *padapter = pxmitpriv->adapter; + struct xmit_frame *pxmitframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; + + _func_enter_; + + rtw_hal_free_xmit_priv(padapter); + + rtw_mfree_xmit_priv_lock(pxmitpriv); + + if(pxmitpriv->pxmit_frame_buf==NULL) + goto out; + + for(i=0; ipallocated_buf) + // rtw_mfree(pxmitbuf->pallocated_buf, MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ); + + pxmitbuf++; + } + + if(pxmitpriv->pallocated_frame_buf) { + rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4); + } + + + if(pxmitpriv->pallocated_xmitbuf) { + rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4); + } + + /* free xframe_ext queue, the same count as extbuf */ + if ((pxmitframe = (struct xmit_frame*)pxmitpriv->xframe_ext)) { + for (i=0; ixframe_ext_alloc_addr) + rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4); + _rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock); + + // free xmit extension buff + _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock); + + pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; + for(i=0; ipallocated_buf) + // rtw_mfree(pxmitbuf->pallocated_buf, MAX_XMIT_EXTBUF_SZ); + + pxmitbuf++; + } + + if(pxmitpriv->pallocated_xmit_extbuf) { + rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4); + } + + rtw_free_hwxmits(padapter); + +#ifdef CONFIG_XMIT_ACK + _rtw_mutex_free(&pxmitpriv->ack_tx_mutex); +#endif + +out: + +_func_exit_; + +} + +static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + u32 sz; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *psta = pattrib->psta; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return; + } + + if (pattrib->nr_frags != 1) + { + sz = padapter->xmitpriv.frag_len; + } + else //no frag + { + sz = pattrib->last_txcmdsz; + } + + // (1) RTS_Threshold is compared to the MPDU, not MSDU. + // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. + // Other fragments are protected by previous fragment. + // So we only need to check the length of first fragment. + if(pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) + { + if(sz > padapter->registrypriv.rts_thresh) + { + pattrib->vcs_mode = RTS_CTS; + } + else + { + if(psta->rtsen) + pattrib->vcs_mode = RTS_CTS; + else if(psta->cts2self) + pattrib->vcs_mode = CTS_TO_SELF; + else + pattrib->vcs_mode = NONE_VCS; + } + } + else + { + while (_TRUE) + { +#if 0 //Todo + //check IOT action + if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) + { + pattrib->vcs_mode = CTS_TO_SELF; + pattrib->rts_rate = MGN_24M; + break; + } + else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE)) + { + pattrib->vcs_mode = RTS_CTS; + pattrib->rts_rate = MGN_24M; + break; + } +#endif + + //IOT action + if((pmlmeinfo->assoc_AP_vendor == atherosAP) && (pattrib->ampdu_en==_TRUE) && + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )) + { + pattrib->vcs_mode = CTS_TO_SELF; + break; + } + + + //check ERP protection + if(psta->rtsen || psta->cts2self) + { + if(psta->rtsen) + pattrib->vcs_mode = RTS_CTS; + else if(psta->cts2self) + pattrib->vcs_mode = CTS_TO_SELF; + + break; + } + + //check HT op mode + if(pattrib->ht_en) + { + u8 HTOpMode = pmlmeinfo->HT_protection; + if((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) || + (!pmlmeext->cur_bwmode && HTOpMode == 3) ) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + } + + //check rts + if(sz > padapter->registrypriv.rts_thresh) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + + //to do list: check MIMO power save condition. + + //check AMPDU aggregation for TXOP + if(pattrib->ampdu_en==_TRUE) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + + pattrib->vcs_mode = NONE_VCS; + break; + } + } +} + +static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta) +{ + /*if(psta->rtsen) + pattrib->vcs_mode = RTS_CTS; + else if(psta->cts2self) + pattrib->vcs_mode = CTS_TO_SELF; + else + pattrib->vcs_mode = NONE_VCS;*/ + + pattrib->mdata = 0; + pattrib->eosp = 0; + pattrib->triggered=0; + + //qos_en, ht_en, init rate, ,bw, ch_offset, sgi + pattrib->qos_en = psta->qos_option; + pattrib->ht_en = psta->htpriv.ht_option; + pattrib->raid = psta->raid; + pattrib->bwmode = psta->htpriv.bwmode; + pattrib->ch_offset = psta->htpriv.ch_offset; + pattrib->sgi= psta->htpriv.sgi; + pattrib->ampdu_en = _FALSE; + + //if(pattrib->ht_en && psta->htpriv.ampdu_enable) + //{ + // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) + // pattrib->ampdu_en = _TRUE; + //} + + + pattrib->retry_ctrl = _FALSE; + +} + +u8 qos_acm(u8 acm_mask, u8 priority) +{ + u8 change_priority = priority; + + switch (priority) + { + case 0: + case 3: + if(acm_mask & BIT(1)) + change_priority = 1; + break; + case 1: + case 2: + break; + case 4: + case 5: + if(acm_mask & BIT(2)) + change_priority = 0; + break; + case 6: + case 7: + if(acm_mask & BIT(3)) + change_priority = 5; + break; + default: + DBG_871X("qos_acm(): invalid pattrib->priority: %d!!!\n", priority); + break; + } + + return change_priority; +} + +static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) +{ + struct ethhdr etherhdr; + struct iphdr ip_hdr; + s32 UserPriority = 0; + + + _rtw_open_pktfile(ppktfile->pkt, ppktfile); + _rtw_pktfile_read(ppktfile, (unsigned char*)ðerhdr, ETH_HLEN); + + // get UserPriority from IP hdr + if (pattrib->ether_type == 0x0800) { + _rtw_pktfile_read(ppktfile, (u8*)&ip_hdr, sizeof(ip_hdr)); +// UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; + UserPriority = ip_hdr.tos >> 5; + } else if (pattrib->ether_type == 0x888e) { + // "When priority processing of data frames is supported, + // a STA's SME should send EAPOL-Key frames at the highest priority." + UserPriority = 7; + } + + pattrib->priority = UserPriority; + pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->subtype = WIFI_QOS_DATA_TYPE; +} + +static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattrib) +{ + uint i; + struct pkt_file pktfile; + struct sta_info *psta = NULL; + struct ethhdr etherhdr; + + sint bmcast; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + sint res = _SUCCESS; + + _func_enter_; + + _rtw_open_pktfile(pkt, &pktfile); + i = _rtw_pktfile_read(&pktfile, (u8*)ðerhdr, ETH_HLEN); + + pattrib->ether_type = ntohs(etherhdr.h_proto); + + + _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); + _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); + + pattrib->pctrl = 0; + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + } + else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + } + else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); + } + + pattrib->pktlen = pktfile.pkt_len; + + if (ETH_P_IP == pattrib->ether_type) + { + // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time + // to prevent DHCP protocol fail + u8 tmp[24]; + _rtw_pktfile_read(&pktfile, &tmp[0], 24); + pattrib->dhcp_pkt = 0; + if (pktfile.pkt_len > 282) {//MINIMUM_DHCP_PACKET_SIZE) { + if (ETH_P_IP == pattrib->ether_type) {// IP header + if (((tmp[21] == 68) && (tmp[23] == 67)) || + ((tmp[21] == 67) && (tmp[23] == 68))) { + // 68 : UDP BOOTP client + // 67 : UDP BOOTP server + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("======================update_attrib: get DHCP Packet \n")); + // Use low rate to send DHCP packet. + //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) + //{ + // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m + // tcb_desc->bTxDisableRateFallBack = false; + //} + //else + // pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate; + //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); + pattrib->dhcp_pkt = 1; + } + } + } + } + + if ( (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) + { + rtw_set_scan_deny(padapter, 3000); + } + +#ifdef CONFIG_LPS + // If EAPOL , ARP , OR DHCP packet, driver must be in active mode. + if ( (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) + { + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1); + } +#endif + + bmcast = IS_MCAST(pattrib->ra); + + // get sta_info + if (bmcast) { + psta = rtw_get_bcmc_stainfo(padapter); + } else { + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + if (psta == NULL) { // if we cannot get psta => drrp the pkt + RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra))); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra)); + #endif + res =_FAIL; + goto exit; + } + else if((check_fwstate(pmlmepriv, WIFI_AP_STATE)==_TRUE)&&(!(psta->state & _FW_LINKED))) + { + res =_FAIL; + goto exit; + } + } + + if (psta) + { + pattrib->mac_id = psta->mac_id; + pattrib->psta = psta; + } + else + { + // if we cannot get psta => drop the pkt + RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra))); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __FUNCTION__, MAC_ARG(pattrib->ra)); + #endif + res = _FAIL; + goto exit; + } + + pattrib->ack_policy = 0; + // get ether_hdr_len + pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag + + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA_TYPE; + pattrib->priority = 0; + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) + { + if(psta->qos_option) + set_qos(&pktfile, pattrib); + } + else + { + if(pqospriv->qos_option) + { + set_qos(&pktfile, pattrib); + + if(pmlmepriv->acm_mask != 0) + { + pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority); + } + } + } + + //pattrib->priority = 5; //force to used VI queue, for testing + + if (psta->ieee8021x_blocked == _TRUE) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\n psta->ieee8021x_blocked == _TRUE \n")); + + pattrib->encrypt = 0; + + if((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npsta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n",pattrib->ether_type)); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n", __FUNCTION__,pattrib->ether_type); + #endif + res = _FAIL; + goto exit; + } + } + else + { + GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); + + switch(psecuritypriv->dot11AuthAlgrthm) + { + case dot11AuthAlgrthm_Open: + case dot11AuthAlgrthm_Shared: + case dot11AuthAlgrthm_Auto: + pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex; + break; + case dot11AuthAlgrthm_8021X: + if(bmcast) + pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid; + else + pattrib->key_idx = 0; + break; + default: + pattrib->key_idx = 0; + break; + } + + + } + + switch (pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + pattrib->iv_len = 4; + pattrib->icv_len = 4; + break; + + case _TKIP_: + pattrib->iv_len = 8; + pattrib->icv_len = 4; + + if(padapter->securitypriv.busetkipkey==_FAIL) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npadapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", padapter->securitypriv.busetkipkey)); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s padapter->securitypriv.busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, padapter->securitypriv.busetkipkey); + #endif + res =_FAIL; + goto exit; + } + + break; + case _AES_: + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\n pattrib->encrypt=%d (_AES_)\n",pattrib->encrypt)); + pattrib->iv_len = 8; + pattrib->icv_len = 8; + break; + + default: + pattrib->iv_len = 0; + pattrib->icv_len = 0; + break; + } + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, + ("update_attrib: encrypt=%d securitypriv.sw_encrypt=%d\n", + pattrib->encrypt, padapter->securitypriv.sw_encrypt)); + + if (pattrib->encrypt && + ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) + { + pattrib->bswenc = _TRUE; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_, + ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc=_TRUE\n", + pattrib->encrypt, padapter->securitypriv.sw_encrypt)); + } else { + pattrib->bswenc = _FALSE; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("update_attrib: bswenc=_FALSE\n")); + } + +#ifdef CONFIG_CONCURRENT_MODE + if((pattrib->encrypt && bmcast) || (pattrib->encrypt ==_WEP40_) || (pattrib->encrypt ==_WEP104_)) + { + pattrib->bswenc = _TRUE;//force using sw enc. + } +#endif + + rtw_set_tx_chksum_offload(pkt, pattrib); + + update_attrib_phy_info(pattrib, psta); + +exit: + +_func_exit_; + + return res; +} + +static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe){ + sint curfragnum,length; + u8 *pframe, *payload,mic[8]; + struct mic_data micdata; + struct sta_info *stainfo; + struct qos_priv *pqospriv= &(padapter->mlmepriv.qospriv); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + u8 priority[4]={0x0,0x0,0x0,0x0}; + sint bmcst = IS_MCAST(pattrib->ra); + + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]); + } + + if(stainfo==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } + +_func_enter_; + + if(pattrib->encrypt ==_TKIP_)//if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) + { + //encode mic code + if(stainfo!= NULL){ + u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; + +#ifdef CONFIG_USB_TX_AGGREGATION + pframe = pxmitframe->buf_addr + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); +#else + pframe = pxmitframe->buf_addr + TXDESC_OFFSET; +#endif + + if(bmcst) + { + if(_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)==_TRUE){ + //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); + //rtw_msleep_os(10); + return _FAIL; + } + //start to calculate the mic code + rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey); + } + else + { + if(_rtw_memcmp(&stainfo->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){ + //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); + //rtw_msleep_os(10); + return _FAIL; + } + //start to calculate the mic code + rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]); + } + + if(pframe[1]&1){ //ToDS==1 + rtw_secmicappend(&micdata, &pframe[16], 6); //DA + if(pframe[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &pframe[24], 6); + else + rtw_secmicappend(&micdata, &pframe[10], 6); + } + else{ //ToDS==0 + rtw_secmicappend(&micdata, &pframe[4], 6); //DA + if(pframe[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &pframe[16], 6); + else + rtw_secmicappend(&micdata, &pframe[10], 6); + + } + + //if(pqospriv->qos_option==1) + if(pattrib->qos_en) + priority[0]=(u8)pxmitframe->attrib.priority; + + + rtw_secmicappend(&micdata, &priority[0], 4); + + payload=pframe; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + payload=(u8 *)RND4((SIZE_PTR)(payload)); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("===curfragnum=%d, pframe= 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n", + curfragnum,*payload, *(payload+1),*(payload+2),*(payload+3),*(payload+4),*(payload+5),*(payload+6),*(payload+7))); + + payload=payload+pattrib->hdrlen+pattrib->iv_len; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",curfragnum,pattrib->hdrlen,pattrib->iv_len)); + if((curfragnum+1)==pattrib->nr_frags){ + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0); + rtw_secmicappend(&micdata, payload,length); + payload=payload+length; + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0); + rtw_secmicappend(&micdata, payload, length); + payload=payload+length+pattrib->icv_len; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d length=%d pattrib->icv_len=%d",curfragnum,length,pattrib->icv_len)); + } + } + rtw_secgetmic(&micdata,&(mic[0])); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: before add mic code!!!\n")); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n",pattrib->last_txcmdsz)); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: mic[0]=0x%.2x ,mic[1]=0x%.2x ,mic[2]=0x%.2x ,mic[3]=0x%.2x \n\ + mic[4]=0x%.2x ,mic[5]=0x%.2x ,mic[6]=0x%.2x ,mic[7]=0x%.2x !!!!\n", + mic[0],mic[1],mic[2],mic[3],mic[4],mic[5],mic[6],mic[7])); + //add mic code and add the mic code length in last_txcmdsz + + _rtw_memcpy(payload, &(mic[0]),8); + pattrib->last_txcmdsz+=8; + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("\n ========last pkt========\n")); + payload=payload-pattrib->last_txcmdsz+8; + for(curfragnum=0;curfragnumlast_txcmdsz;curfragnum=curfragnum+8) + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,(" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ", + *(payload+curfragnum), *(payload+curfragnum+1), *(payload+curfragnum+2),*(payload+curfragnum+3), + *(payload+curfragnum+4),*(payload+curfragnum+5),*(payload+curfragnum+6),*(payload+curfragnum+7))); + } + else{ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n")); + } + } + +_func_exit_; + + return _SUCCESS; +} + +static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe){ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + //struct security_priv *psecuritypriv=&padapter->securitypriv; + +_func_enter_; + + //if((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) + if(pattrib->bswenc) + { + //DBG_871X("start xmitframe_swencrypt\n"); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_alert_,("### xmitframe_swencrypt\n")); + switch(pattrib->encrypt){ + case _WEP40_: + case _WEP104_: + rtw_wep_encrypt(padapter, (u8 *)pxmitframe); + break; + case _TKIP_: + rtw_tkip_encrypt(padapter, (u8 *)pxmitframe); + break; + case _AES_: + rtw_aes_encrypt(padapter, (u8 * )pxmitframe); + break; + default: + break; + } + + } else { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_notice_,("### xmitframe_hwencrypt\n")); + } + +_func_exit_; + + return _SUCCESS; +} + +s32 rtw_make_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) +{ + u16 *qc; + + struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv = &pmlmepriv->qospriv; + u8 qos_option = _FALSE; +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta=NULL, *psta_backup=NULL; + u8 direct_link=0; +#endif //CONFIG_TDLS + + sint res = _SUCCESS; + u16 *fctrl = &pwlanhdr->frame_ctl; + + struct sta_info *psta; + + sint bmcst = IS_MCAST(pattrib->ra); + +_func_enter_; + + if (pattrib->psta) { + psta = pattrib->psta; + } else { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + if(bmcst) { + psta = rtw_get_bcmc_stainfo(padapter); + } else { + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } + + _rtw_memset(hdr, 0, WLANHDR_OFFSET); + + SetFrameSubType(fctrl, pattrib->subtype); + + if (pattrib->subtype & WIFI_DATA_TYPE) + { + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) { + //to_ds = 1, fr_ds = 0; +#ifdef CONFIG_TDLS + if((ptdlsinfo->setup_state == TDLS_LINKED_STATE)){ + ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + if((ptdls_sta!=NULL)&&(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)&&(pattrib->ether_type!=0x0806)){ + //TDLS data transfer, ToDS=0, FrDs=0 + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + direct_link=1; + }else{ + // 1.Data transfer to AP + // 2.Arp pkt will relayed by AP + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } + }else +#endif //CONFIG_TDLS + { + //Data transfer to AP + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } + + if (pqospriv->qos_option) + qos_option = _TRUE; + + } + else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ) { + //to_ds = 0, fr_ds = 1; + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + + if(psta->qos_option) + qos_option = _TRUE; + } + else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + + if(psta->qos_option) + qos_option = _TRUE; + } + else { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv))); + res = _FAIL; + goto exit; + } + + if(pattrib->mdata) + SetMData(fctrl); + + if (pattrib->encrypt) + SetPrivacy(fctrl); + + if (qos_option) + { + qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); + + if (pattrib->priority) + SetPriority(qc, pattrib->priority); + + SetEOSP(qc, pattrib->eosp); + + SetAckpolicy(qc, pattrib->ack_policy); + } + + //TODO: fill HT Control Field + + //Update Seq Num will be handled by f/w + { + if(psta){ +#ifdef CONFIG_TDLS + if(direct_link==1) + { + psta_backup = psta; + psta = ptdls_sta; + } +#endif //CONFIG_TDLS + + psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + + pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; + + SetSeqNum(hdr, pattrib->seqnum); + + + //check if enable ampdu + if(pattrib->ht_en && psta->htpriv.ampdu_enable) + { + if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) + pattrib->ampdu_en = _TRUE; + } + + //re-check if enable ampdu by BA_starting_seqctrl + if(pattrib->ampdu_en == _TRUE) + { + u16 tx_seq; + + tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f]; + + //check BA_starting_seqctrl + if(SN_LESS(pattrib->seqnum, tx_seq)) + { + //DBG_871X("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); + pattrib->ampdu_en = _FALSE;//AGG BK + } + else if(SN_EQUAL(pattrib->seqnum, tx_seq)) + { + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff; + + pattrib->ampdu_en = _TRUE;//AGG EN + } + else + { + //DBG_871X("tx ampdu over run\n"); + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff; + pattrib->ampdu_en = _TRUE;//AGG EN + } + + } + +#ifdef CONFIG_TDLS + if(direct_link==1) + { + if (pattrib->encrypt){ + pattrib->encrypt= _AES_; + pattrib->iv_len=8; + pattrib->icv_len=8; + } + + //qos_en, ht_en, init rate, ,bw, ch_offset, sgi + //pattrib->qos_en = ptdls_sta->qos_option; + pattrib->ht_en = ptdls_sta->htpriv.ht_option; + pattrib->raid = ptdls_sta->raid; + pattrib->bwmode = ptdls_sta->htpriv.bwmode; + pattrib->ch_offset = ptdls_sta->htpriv.ch_offset; + pattrib->sgi= ptdls_sta->htpriv.sgi; + + pattrib->mac_id = ptdls_sta->mac_id; + + psta = psta_backup; + } +#endif //CONFIG_TDLS + + } + } + + } + else + { + + } + +exit: + +_func_exit_; + + return res; +} + +s32 rtw_txframes_pending(_adapter *padapter) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE)); +} + +s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib) +{ + struct sta_info *psta; + struct tx_servq *ptxservq; + int priority = pattrib->priority; + + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]); + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return 0; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return 0; + } + + switch(priority) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + break; + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + break; + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + break; + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + break; + + } + + return ptxservq->qcnt; +} + +#ifdef CONFIG_TDLS + +int rtw_build_tdls_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 action) +{ + int res=_SUCCESS; + + switch(action){ + case TDLS_SETUP_REQUEST: + rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe); + break; + case TDLS_SETUP_RESPONSE: + rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe); + break; + case TDLS_SETUP_CONFIRM: + rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe); + break; + case TDLS_TEARDOWN: + rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe); + break; + case TDLS_DISCOVERY_REQUEST: + rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe); + break; + case TDLS_PEER_TRAFFIC_INDICATION: + rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe); + break; + case TDLS_CHANNEL_SWITCH_REQUEST: + rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe); + break; + case TDLS_CHANNEL_SWITCH_RESPONSE: + rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe); + break; +#ifdef CONFIG_WFD + case TUNNELED_PROBE_REQ: + rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe); + break; + case TUNNELED_PROBE_RSP: + rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe); + break; +#endif //CONFIG_WFD + default: + res=_FAIL; + break; + } + + return res; +} + +s32 rtw_make_tdls_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, u8 action) +{ + u16 *qc; + struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv = &pmlmepriv->qospriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL, *ptdls_sta=NULL; + u8 tdls_seq=0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + sint res = _SUCCESS; + u16 *fctrl = &pwlanhdr->frame_ctl; + +_func_enter_; + + _rtw_memset(hdr, 0, WLANHDR_OFFSET); + + SetFrameSubType(fctrl, pattrib->subtype); + + switch(action){ + case TDLS_SETUP_REQUEST: + case TDLS_SETUP_RESPONSE: + case TDLS_SETUP_CONFIRM: + case TDLS_TEARDOWN: //directly to peer STA or via AP + case TDLS_PEER_TRAFFIC_INDICATION: + case TDLS_PEER_PSM_REQUEST: //directly to peer STA or via AP + case TUNNELED_PROBE_REQ: + case TUNNELED_PROBE_RSP: + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + break; + case TDLS_CHANNEL_SWITCH_REQUEST: + case TDLS_CHANNEL_SWITCH_RESPONSE: + case TDLS_PEER_PSM_RESPONSE: + case TDLS_PEER_TRAFFIC_RESPONSE: + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + tdls_seq=1; + break; + case TDLS_DISCOVERY_REQUEST: //unicast: directly to peer sta, Bcast: via AP + if(_rtw_memcmp(pattrib->dst, baddr, ETH_ALEN) ) + { + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } + else + { + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + tdls_seq=1; + } + break; + } + + if (pattrib->encrypt) + SetPrivacy(fctrl); + + if (pqospriv->qos_option) + { + qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); + if (pattrib->priority) + SetPriority(qc, pattrib->priority); + SetAckpolicy(qc, pattrib->ack_policy); + } + + psta = pattrib->psta; + + // 1. update seq_num per link by sta_info + // 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len + if(tdls_seq==1){ + ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst); + if(ptdls_sta){ + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]; + SetSeqNum(hdr, pattrib->seqnum); + + if (pattrib->encrypt){ + pattrib->encrypt= _AES_; + pattrib->iv_len=8; + pattrib->icv_len=8; + } + }else{ + res=_FAIL; + goto exit; + } + }else if(psta){ + psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; + SetSeqNum(hdr, pattrib->seqnum); + } + + +exit: + +_func_exit_; + + return res; +} + +s32 rtw_xmit_tdls_coalesce(_adapter * padapter, struct xmit_frame * pxmitframe, u8 action) +{ + s32 llc_sz; + + u8 *pframe, *mem_start; + + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 *pbuf_start; + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _SUCCESS; + +_func_enter_; + + if (pattrib->psta) { + psta = pattrib->psta; + } else { + if(bmcst) { + psta = rtw_get_bcmc_stainfo(padapter); + } else { + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + } + + if(psta==NULL) + return _FAIL; + + if (pxmitframe->buf_addr == NULL) + return _FAIL; + + pbuf_start = pxmitframe->buf_addr; + mem_start = pbuf_start + TXDESC_OFFSET; + + if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, action) == _FAIL) { + res = _FAIL; + goto exit; + } + + pframe = mem_start; + pframe += pattrib->hdrlen; + + //adding icv, if necessary... + if (pattrib->iv_len) + { + if (psta != NULL) + { + switch(pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + break; + case _TKIP_: + if(bmcst) + TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + TKIP_IV(pattrib->iv, psta->dot11txpn, 0); + break; + case _AES_: + if(bmcst) + AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + AES_IV(pattrib->iv, psta->dot11txpn, 0); + break; + } + } + + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + pframe += pattrib->iv_len; + + } + + llc_sz = rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + + //pattrib->pktlen will be counted in rtw_build_tdls_ies + pattrib->pktlen = 0; + + rtw_build_tdls_ies(padapter, pxmitframe, pframe, action); + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + pframe += pattrib->pktlen; + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + + pattrib->nr_frags = 1; + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz + + ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen; + + if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) + { + goto exit; + } + + xmitframe_swencrypt(padapter, pxmitframe); + + update_attrib_vcs_info(padapter, pxmitframe); + +exit: + +_func_exit_; + + return res; +} +#endif //CONFIG_TDLS + +/* + * Calculate wlan 802.11 packet MAX size from pkt_attrib + * This function doesn't consider fragment case + */ +u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib) +{ + u32 len = 0; + + len = pattrib->hdrlen + pattrib->iv_len; // WLAN Header and IV + len += SNAP_SIZE + sizeof(u16); // LLC + len += pattrib->pktlen; + if (pattrib->encrypt == _TKIP_) len += 8; // MIC + len += pattrib->icv_len; // ICV + + return len; +} + +/* + +This sub-routine will perform all the following: + +1. remove 802.3 header. +2. create wlan_header, based on the info in pxmitframe +3. append sta's iv/ext-iv +4. append LLC +5. move frag chunk from pframe to pxmitframe->mem +6. apply sw-encrypt, if necessary. + +*/ +s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe) +{ + struct pkt_file pktfile; + + s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; + + SIZE_PTR addr; + + u8 *pframe, *mem_start; + + struct sta_info *psta; + //struct sta_priv *pstapriv = &padapter->stapriv; + //struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + u8 *pbuf_start; + + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _SUCCESS; + +_func_enter_; + + if (pattrib->psta) + { + psta = pattrib->psta; + } else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + + if(psta==NULL) + { + + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } + + if (pxmitframe->buf_addr == NULL){ + DBG_8192C("==> %s buf_addr==NULL \n",__FUNCTION__); + return _FAIL; + } + + pbuf_start = pxmitframe->buf_addr; + +#ifdef CONFIG_USB_TX_AGGREGATION + mem_start = pbuf_start + TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); +#else + mem_start = pbuf_start + TXDESC_OFFSET; +#endif + + if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n")); + res = _FAIL; + goto exit; + } + + _rtw_open_pktfile(pkt, &pktfile); + _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); + + frg_inx = 0; + frg_len = pxmitpriv->frag_len - 4;//2346-4 = 2342 + + while (1) + { + llc_sz = 0; + + mpdu_len = frg_len; + + pframe = mem_start; + + SetMFrag(mem_start); + + pframe += pattrib->hdrlen; + mpdu_len -= pattrib->hdrlen; + + //adding icv, if necessary... + if (pattrib->iv_len) + { + //if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) + // psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + //else + // psta = rtw_get_stainfo(pstapriv, pattrib->ra); + + if (psta != NULL) + { + switch(pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + break; + case _TKIP_: + if(bmcst) + TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + TKIP_IV(pattrib->iv, psta->dot11txpn, 0); + break; + case _AES_: + if(bmcst) + AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + AES_IV(pattrib->iv, psta->dot11txpn, 0); + break; + } + } + + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, + ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n", + padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3))); + + pframe += pattrib->iv_len; + + mpdu_len -= pattrib->iv_len; + } + + if (frg_inx == 0) { + llc_sz = rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + mpdu_len -= llc_sz; + } + + if ((pattrib->icv_len >0) && (pattrib->bswenc)) { + mpdu_len -= pattrib->icv_len; + } + + + if (bmcst) { + // don't do fragment to broadcat/multicast packets + mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen); + } else { + mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len); + } + + pframe += mem_sz; + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + + frg_inx++; + + if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) + { + pattrib->nr_frags = frg_inx; + + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags==1)? llc_sz:0) + + ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz; + + ClearMFrag(mem_start); + + break; + } else { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __FUNCTION__)); + } + + addr = (SIZE_PTR)(pframe); + + mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET; + _rtw_memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen); + } + + if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) + { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n")); + res = _FAIL; + goto exit; + } + + xmitframe_swencrypt(padapter, pxmitframe); + + if(bmcst == _FALSE) + update_attrib_vcs_info(padapter, pxmitframe); + else + pattrib->vcs_mode = NONE_VCS; + +exit: + +_func_exit_; + + return res; +} + +#ifdef CONFIG_IEEE80211W +//broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption +s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe) +{ + struct pkt_file pktfile; + s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; + SIZE_PTR addr; + u8 *pframe, *mem_start = NULL, *tmp_buf=NULL; + u8 hw_hdr_offset, subtype ; + struct sta_info *psta = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 *pbuf_start; + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _FAIL; + u8 *BIP_AAD=NULL; + u8 *MGMT_body=NULL; + + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct rtw_ieee80211_hdr *pwlanhdr; + u8 MME[_MME_IE_LENGTH_]; + + _irqL irqL; + u32 ori_len; + mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + +_func_enter_; + ori_len = BIP_AAD_SIZE+pattrib->pktlen; + tmp_buf = BIP_AAD = rtw_zmalloc(ori_len); + subtype = GetFrameSubType(pframe); //bit(7)~bit(2) + + if(BIP_AAD == NULL) + return _FAIL; + + _enter_critical_bh(&padapter->security_key_mutex, &irqL); + + //only support station mode + if(!check_fwstate(pmlmepriv, WIFI_STATION_STATE) || !check_fwstate(pmlmepriv, _FW_LINKED)) + goto xmitframe_coalesce_success; + + //IGTK key is not install, it may not support 802.11w + if(padapter->securitypriv.binstallBIPkey != _TRUE) + { + DBG_871X("no instll BIP key\n"); + goto xmitframe_coalesce_success; + } + //station mode doesn't need TX BIP, just ready the code + if(bmcst) + { + int frame_body_len; + u8 mic[16]; + + _rtw_memset(MME, 0, 18); + + //other types doesn't need the BIP + if(GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC) + goto xmitframe_coalesce_fail; + + MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pattrib->pktlen; + + //octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 + MME[0]=padapter->securitypriv.dot11wBIPKeyid; + //copy packet number + _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6); + //increase the packet number + pmlmeext->mgnt_80211w_IPN++; + + //add MME IE with MIC all zero, MME string doesn't include element id and length + pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen)); + pattrib->last_txcmdsz = pattrib->pktlen; + // total frame length - header length + frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr); + + //conscruct AAD, copy frame control field + _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); + ClearRetry(BIP_AAD); + ClearPwrMgt(BIP_AAD); + ClearMData(BIP_AAD); + //conscruct AAD, copy address 1 to address 3 + _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + //copy management fram body + _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len); + /*//dump total packet include MME with zero MIC + { + int i; + printk("Total packet: "); + for(i=0; i < BIP_AAD_SIZE+frame_body_len; i++) + printk(" %02x ", BIP_AAD[i]); + printk("\n"); + }*/ + //calculate mic + if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey + , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic)) + goto xmitframe_coalesce_fail; + + /*//dump calculated mic result + { + int i; + printk("Calculated mic result: "); + for(i=0; i<16; i++) + printk(" %02x ", mic[i]); + printk("\n"); + }*/ + //copy right BIP mic value, total is 128bits, we use the 0~63 bits + _rtw_memcpy(pframe-8, mic, 8); + /*/dump all packet after mic ok + { + int pp; + printk("pattrib->pktlen = %d \n", pattrib->pktlen); + for(pp=0;pp< pattrib->pktlen; pp++) + printk(" %02x ", mem_start[pp]); + printk("\n"); + }*/ + } + else //unicast mgmt frame TX + { + //start to encrypt mgmt frame + if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || + subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) + { + if (pattrib->psta) + psta = pattrib->psta; + else + { + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + + if(psta==NULL) + { + + DBG_871X("%s, psta==NUL\n", __func__); + goto xmitframe_coalesce_fail; + } + + if(!(psta->state & _FW_LINKED) || pxmitframe->buf_addr==NULL) + { + DBG_871X("%s, not _FW_LINKED or addr null\n", __func__); + goto xmitframe_coalesce_fail; + } + + //DBG_871X("%s, action frame category=%d \n", __func__, pframe[WLAN_HDR_A3_LEN]); + //according 802.11-2012 standard, these five types are not robust types + if(subtype == WIFI_ACTION && + (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P)) + goto xmitframe_coalesce_fail; + //before encrypt dump the management packet content + /*{ + int i; + printk("Management pkt: "); + for(i=0; ipktlen; i++) + printk(" %02x ", pframe[i]); + printk("=======\n"); + }*/ + if(pattrib->encrypt>0) + _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16); + //bakeup original management packet + _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen); + //move to data portion + pframe += pattrib->hdrlen; + + //802.11w unicast management packet must be _AES_ + pattrib->iv_len = 8; + //it's MIC of AES + pattrib->icv_len = 8; + + switch(pattrib->encrypt) + { + case _AES_: + //set AES IV header + AES_IV(pattrib->iv, psta->dot11wtxpn, 0); + break; + default: + goto xmitframe_coalesce_fail; + } + //insert iv header into management frame + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + pframe += pattrib->iv_len; + //copy mgmt data portion after CCMP header + _rtw_memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen); + //move pframe to end of mgmt pkt + pframe += pattrib->pktlen-pattrib->hdrlen; + //add 8 bytes CCMP IV header to length + pattrib->pktlen += pattrib->iv_len; + /*//dump management packet include AES IV header + { + int i; + printk("Management pkt + IV: "); + //for(i=0; ipktlen; i++) + //printk(" %02x ", mem_start[i]); + printk("@@@@@@@@@@@@@\n"); + }*/ + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + //add 8 bytes MIC + pattrib->pktlen += pattrib->icv_len; + //set final tx command size + pattrib->last_txcmdsz = pattrib->pktlen; + + //set protected bit must be beofre SW encrypt + SetPrivacy(mem_start); + /*//dump management packet include AES header + { + int i; + printk("prepare to enc Management pkt + IV: "); + for(i=0; ipktlen; i++) + printk(" %02x ", mem_start[i]); + printk("@@@@@@@@@@@@@\n"); + }*/ + //software encrypt + xmitframe_swencrypt(padapter, pxmitframe); + } + } + +xmitframe_coalesce_success: + _exit_critical_bh(&padapter->security_key_mutex, &irqL); + rtw_mfree(BIP_AAD, ori_len); +_func_exit_; + return _SUCCESS; + +xmitframe_coalesce_fail: + _exit_critical_bh(&padapter->security_key_mutex, &irqL); + rtw_mfree(BIP_AAD, ori_len); +_func_exit_; + + return _FAIL; +} +#endif //CONFIG_IEEE80211W + +/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header + * IEEE LLC/SNAP header contains 8 octets + * First 3 octets comprise the LLC portion + * SNAP portion, 5 octets, is divided into two fields: + * Organizationally Unique Identifier(OUI), 3 octets, + * type, defined by that organization, 2 octets. + */ +s32 rtw_put_snap(u8 *data, u16 h_proto) +{ + struct ieee80211_snap_hdr *snap; + u8 *oui; + +_func_enter_; + + snap = (struct ieee80211_snap_hdr *)data; + snap->dsap = 0xaa; + snap->ssap = 0xaa; + snap->ctrl = 0x03; + + if (h_proto == 0x8137 || h_proto == 0x80f3) + oui = P802_1H_OUI; + else + oui = RFC1042_OUI; + + snap->oui[0] = oui[0]; + snap->oui[1] = oui[1]; + snap->oui[2] = oui[2]; + + *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + +_func_exit_; + + return SNAP_SIZE + sizeof(u16); +} + +void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len) +{ + + uint protection; + u8 *perp; + sint erp_len; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + +_func_enter_; + + switch(pxmitpriv->vcs_setting) + { + case DISABLE_VCS: + pxmitpriv->vcs = NONE_VCS; + break; + + case ENABLE_VCS: + break; + + case AUTO_VCS: + default: + perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len); + if(perp == NULL) + { + pxmitpriv->vcs = NONE_VCS; + } + else + { + protection = (*(perp + 2)) & BIT(1); + if (protection) + { + if(pregistrypriv->vcs_type == RTS_CTS) + pxmitpriv->vcs = RTS_CTS; + else + pxmitpriv->vcs = CTS_TO_SELF; + } + else + pxmitpriv->vcs = NONE_VCS; + } + + break; + + } + +_func_exit_; + +} + +void rtw_count_tx_stats(_adapter *padapter, struct xmit_frame *pxmitframe, int sz) +{ + struct sta_info *psta = NULL; + struct stainfo_stats *pstats = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) + { + pxmitpriv->tx_bytes += sz; +#ifdef CONFIG_USB_TX_AGGREGATION + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num; +#else + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++; +#endif + + psta = pxmitframe->attrib.psta; + + if(psta) + { + pstats = &psta->sta_stats; +#ifdef CONFIG_USB_TX_AGGREGATION + pstats->tx_pkts += pxmitframe->agg_num; +#else + pstats->tx_pkts++; +#endif + pstats->tx_bytes += sz; + } + } + +} + +struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_buf *pxmitbuf = NULL; + _list *plist, *phead; + _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; + +_func_enter_; + + _enter_critical(&pfree_queue->lock, &irqL); + + if(_rtw_queue_empty(pfree_queue) == _TRUE) { + pxmitbuf = NULL; + } else { + + phead = get_list_head(pfree_queue); + + plist = get_next(phead); + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + + rtw_list_delete(&(pxmitbuf->list)); + } + + if (pxmitbuf != NULL) + { + pxmitpriv->free_xmit_extbuf_cnt--; + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF ALLOC no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt); + #endif + + + pxmitbuf->priv_data = NULL; + +#ifdef CONFIG_SDIO_HCI + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif +#ifdef CONFIG_PCI_HCI + pxmitbuf->len = 0; +#endif + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); + } + + } + + _exit_critical(&pfree_queue->lock, &irqL); + +_func_exit_; + + return pxmitbuf; +} + +s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + _irqL irqL; + _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; + +_func_enter_; + + if(pxmitbuf==NULL) + { + return _FAIL; + } + + _enter_critical(&pfree_queue->lock, &irqL); + + rtw_list_delete(&pxmitbuf->list); + + rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue)); + pxmitpriv->free_xmit_extbuf_cnt++; + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF FREE no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmit_extbuf_cnt); + #endif + + _exit_critical(&pfree_queue->lock, &irqL); + +_func_exit_; + + return _SUCCESS; +} + +struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_buf *pxmitbuf = NULL; + _list *plist, *phead; + _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; + +_func_enter_; + + //DBG_871X("+rtw_alloc_xmitbuf\n"); + + _enter_critical(&pfree_xmitbuf_queue->lock, &irqL); + + if(_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE) { + pxmitbuf = NULL; + } else { + + phead = get_list_head(pfree_xmitbuf_queue); + + plist = get_next(phead); + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + + rtw_list_delete(&(pxmitbuf->list)); + } + + if (pxmitbuf != NULL) + { + pxmitpriv->free_xmitbuf_cnt--; + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt); + #endif + //DBG_871X("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); + + pxmitbuf->priv_data = NULL; + +#ifdef CONFIG_SDIO_HCI + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif +#ifdef CONFIG_PCI_HCI + pxmitbuf->len = 0; +#endif + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); + } + } + #ifdef DBG_XMIT_BUF + else + { + DBG_871X("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n"); + } + #endif + + _exit_critical(&pfree_xmitbuf_queue->lock, &irqL); + +_func_exit_; + + return pxmitbuf; +} + +s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + _irqL irqL; + _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; + +_func_enter_; + + //DBG_871X("+rtw_free_xmitbuf\n"); + + if(pxmitbuf==NULL) + { + return _FAIL; + } + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE); + } + + if(pxmitbuf->ext_tag) + { + rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf); + } + else + { + _enter_critical(&pfree_xmitbuf_queue->lock, &irqL); + + rtw_list_delete(&pxmitbuf->list); + + rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue)); + + pxmitpriv->free_xmitbuf_cnt++; + //DBG_871X("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmitbuf_cnt); + #endif + _exit_critical(&pfree_xmitbuf_queue->lock, &irqL); + } + +_func_exit_; + + return _SUCCESS; +} + +void rtw_init_xmitframe(struct xmit_frame *pxframe) +{ + if (pxframe != NULL)//default value setting + { + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib)); + //pxframe->attrib.psta = NULL; + + pxframe->frame_tag = DATA_FRAMETAG; + +#ifdef CONFIG_USB_HCI + pxframe->pkt = NULL; + pxframe->pkt_offset = 1;//default use pkt_offset to fill tx desc + +#ifdef CONFIG_USB_TX_AGGREGATION + pxframe->agg_num = 1; +#endif + +#endif //#ifdef CONFIG_USB_HCI + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxframe->pg_num = 1; + pxframe->agg_num = 1; +#endif + +#ifdef CONFIG_XMIT_ACK + pxframe->ack_report = 0; +#endif + + } +} + +/* +Calling context: +1. OS_TXENTRY +2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) + +If we turn on USE_RXTHREAD, then, no need for critical section. +Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... + +Must be very very cautious... + +*/ +struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)//(_queue *pfree_xmit_queue) +{ + /* + Please remember to use all the osdep_service api, + and lock/unlock or _enter/_exit critical to protect + pfree_xmit_queue + */ + + _irqL irqL; + struct xmit_frame *pxframe = NULL; + _list *plist, *phead; + _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; +#ifdef PLATFORM_LINUX + _adapter *padapter = pxmitpriv->adapter; +#endif //PLATFORM_LINUX + +_func_enter_; + + _enter_critical_bh(&pfree_xmit_queue->lock, &irqL); + + if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt)); + pxframe = NULL; + } else { + phead = get_list_head(pfree_xmit_queue); + + plist = get_next(phead); + + pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + rtw_list_delete(&(pxframe->list)); + pxmitpriv->free_xmitframe_cnt--; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt)); + } + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) + if(pxmitpriv->free_xmitframe_cnt==1) + { + if (!rtw_netif_queue_stopped(padapter->pnetdev)) + rtw_netif_stop_queue(padapter->pnetdev); + } +#endif +#endif + + _exit_critical_bh(&pfree_xmit_queue->lock, &irqL); + + rtw_init_xmitframe(pxframe); + +_func_exit_; + + return pxframe; +} + +struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_frame *pxframe = NULL; + _list *plist, *phead; + _queue *queue = &pxmitpriv->free_xframe_ext_queue; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (_rtw_queue_empty(queue) == _TRUE) { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt)); + pxframe = NULL; + } else { + phead = get_list_head(queue); + plist = get_next(phead); + pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + rtw_list_delete(&(pxframe->list)); + pxmitpriv->free_xframe_ext_cnt--; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt)); + } + + _exit_critical_bh(&queue->lock, &irqL); + + rtw_init_xmitframe(pxframe); + +_func_exit_; + + return pxframe; +} + +struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv) +{ + struct xmit_frame *pxframe = NULL; + u8 *alloc_addr; + + alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4); + + if (alloc_addr == NULL) + goto exit; + + pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4); + pxframe->alloc_addr = alloc_addr; + + pxframe->padapter = pxmitpriv->adapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + rtw_init_xmitframe(pxframe); + + DBG_871X("################## %s ##################\n", __func__); + +exit: + return pxframe; +} + +s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + _queue *queue; + _adapter *padapter = pxmitpriv->adapter; + _pkt *pndis_pkt = NULL; + +_func_enter_; + + if (pxmitframe == NULL) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe==NULL!!!!!!!!!!\n")); + goto exit; + } + + if (pxmitframe->pkt){ + pndis_pkt = pxmitframe->pkt; + pxmitframe->pkt = NULL; + } + + if (pxmitframe->alloc_addr) { + DBG_871X("################## %s with alloc_addr ##################\n", __func__); + rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4); + goto check_pkt_complete; + } + + if (pxmitframe->ext_tag == 0) + queue = &pxmitpriv->free_xmit_queue; + else if(pxmitframe->ext_tag == 1) + queue = &pxmitpriv->free_xframe_ext_queue; + else + {} + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_delete(&pxmitframe->list); + rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue)); + if (pxmitframe->ext_tag == 0) { + pxmitpriv->free_xmitframe_cnt++; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt)); + } else if(pxmitframe->ext_tag == 1) { + pxmitpriv->free_xframe_ext_cnt++; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt)); + } else { + } + + _exit_critical_bh(&queue->lock, &irqL); + +check_pkt_complete: + + if(pndis_pkt) + rtw_os_pkt_complete(padapter, pndis_pkt); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue) +{ + _irqL irqL; + _list *plist, *phead; + struct xmit_frame *pxmitframe; + +_func_enter_; + + _enter_critical_bh(&(pframequeue->lock), &irqL); + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + plist = get_next(plist); + + rtw_free_xmitframe(pxmitpriv,pxmitframe); + + } + _exit_critical_bh(&(pframequeue->lock), &irqL); + +_func_exit_; +} + +s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) + { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, + ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n")); +// pxmitframe->pkt = NULL; + return _FAIL; + } + + return _SUCCESS; +} + +static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue) +{ + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + + xmitframe_phead = get_list_head(pframe_queue); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + +/*#ifdef RTK_DMP_PLATFORM +#ifdef CONFIG_USB_TX_AGGREGATION + if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2)) + { + pxmitframe = NULL; + + tasklet_schedule(&pxmitpriv->xmit_tasklet); + + break; + } +#endif +#endif*/ + rtw_list_delete(&pxmitframe->list); + + ptxservq->qcnt--; + + break; + + pxmitframe = NULL; + + } + + return pxmitframe; +} + +struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry) +{ + _irqL irqL0; + _list *sta_plist, *sta_phead; + struct hw_xmit *phwxmit; + struct tx_servq *ptxservq = NULL; + _queue *pframe_queue = NULL; + struct xmit_frame *pxmitframe = NULL; + _adapter *padapter = pxmitpriv->adapter; + struct registry_priv *pregpriv = &padapter->registrypriv; + int i, inx[4]; +#ifdef CONFIG_USB_HCI +// int j, tmp, acirp_cnt[4]; +#endif + +_func_enter_; + + inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; + + if(pregpriv->wifi_spec==1) + { + int j, tmp, acirp_cnt[4]; +#if 0 + if(flagsvo, 1->vi, 2->be, 3->bk. + acirp_cnt[0] = pxmitpriv->voq_cnt; + acirp_cnt[1] = pxmitpriv->viq_cnt; + acirp_cnt[2] = pxmitpriv->beq_cnt; + acirp_cnt[3] = pxmitpriv->bkq_cnt; + + for(i=0; i<4; i++) + { + for(j=i+1; j<4; j++) + { + if(acirp_cnt[j]lock, &irqL0); + + for(i = 0; i < entry; i++) + { + phwxmit = phwxmit_i + inx[i]; + + //_enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + sta_phead = get_list_head(phwxmit->sta_queue); + sta_plist = get_next(sta_phead); + + while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) + { + + ptxservq= LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending); + + pframe_queue = &ptxservq->sta_pending; + + pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue); + + if(pxmitframe) + { + phwxmit->accnt--; + + //Remove sta node when there is no pending packets. + if(_rtw_queue_empty(pframe_queue)) //must be done after get_next and before break + rtw_list_delete(&ptxservq->tx_pending); + + //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + goto exit; + } + + sta_plist = get_next(sta_plist); + + } + + //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + } + +exit: + + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + +_func_exit_; + + return pxmitframe; +} + +#if 1 +struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac) +{ + struct tx_servq *ptxservq=NULL; + +_func_enter_; + + switch (up) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + *(ac) = 3; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n")); + break; + + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + *(ac) = 1; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n")); + break; + + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + *(ac) = 0; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n")); + break; + + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + *(ac) = 2; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n")); + break; + + } + +_func_exit_; + + return ptxservq; +} +#else +__inline static struct tx_servq *rtw_get_sta_pending + (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up) +{ + struct tx_servq *ptxservq; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + +_func_enter_; + +#ifdef CONFIG_RTL8711 + + if(IS_MCAST(psta->hwaddr)) + { + ptxservq = &(psta->sta_xmitpriv.be_q); // we will use be_q to queue bc/mc frames in BCMC_stainfo + *ppstapending = &padapter->xmitpriv.bm_pending; + } + else +#endif + { + switch (up) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + *ppstapending = &padapter->xmitpriv.bk_pending; + (phwxmits+3)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n")); + break; + + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + *ppstapending = &padapter->xmitpriv.vi_pending; + (phwxmits+1)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n")); + break; + + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + *ppstapending = &padapter->xmitpriv.vo_pending; + (phwxmits+0)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n")); + break; + + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + *ppstapending = &padapter->xmitpriv.be_pending; + (phwxmits+2)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n")); + break; + + } + + } + +_func_exit_; + + return ptxservq; +} +#endif + +/* + * Will enqueue pxmitframe to the proper queue, + * and indicate it to xx_pending list..... + */ +s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + //_irqL irqL0; + u8 ac_index; + struct sta_info *psta; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + sint res = _SUCCESS; + +_func_enter_; + + if (pattrib->psta) { + psta = pattrib->psta; + } else { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + } + + if (psta == NULL) { + res = _FAIL; + DBG_8192C("rtw_xmit_classifier: psta == NULL\n"); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("rtw_xmit_classifier: psta == NULL\n")); + goto exit; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } + + ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); + + //_enter_critical(&pstapending->lock, &irqL0); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) { + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue)); + } + + //_enter_critical(&ptxservq->sta_pending.lock, &irqL1); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); + ptxservq->qcnt++; + phwxmits[ac_index].accnt++; + + //_exit_critical(&ptxservq->sta_pending.lock, &irqL1); + + //_exit_critical(&pstapending->lock, &irqL0); + +exit: + +_func_exit_; + + return res; +} + +void rtw_alloc_hwxmits(_adapter *padapter) +{ + struct hw_xmit *hwxmits; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; + + pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry); + + hwxmits = pxmitpriv->hwxmits; + + if(pxmitpriv->hwxmit_entry == 5) + { + //pxmitpriv->bmc_txqueue.head = 0; + //hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; + hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; + + //pxmitpriv->vo_txqueue.head = 0; + //hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; + hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; + + //pxmitpriv->vi_txqueue.head = 0; + //hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; + hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; + + //pxmitpriv->bk_txqueue.head = 0; + //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; + hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + + //pxmitpriv->be_txqueue.head = 0; + //hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; + hwxmits[4] .sta_queue = &pxmitpriv->be_pending; + + } + else if(pxmitpriv->hwxmit_entry == 4) + { + + //pxmitpriv->vo_txqueue.head = 0; + //hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; + hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; + + //pxmitpriv->vi_txqueue.head = 0; + //hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; + hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; + + //pxmitpriv->be_txqueue.head = 0; + //hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; + hwxmits[2] .sta_queue = &pxmitpriv->be_pending; + + //pxmitpriv->bk_txqueue.head = 0; + //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; + hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + } + else + { + + + } + + +} + +void rtw_free_hwxmits(_adapter *padapter) +{ + struct hw_xmit *hwxmits; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + hwxmits = pxmitpriv->hwxmits; + if(hwxmits) + rtw_mfree((u8 *)hwxmits, (sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry)); +} + +void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry) +{ + sint i; +_func_enter_; + for(i = 0; i < entry; i++, phwxmit++) + { + //_rtw_spinlock_init(&phwxmit->xmit_lock); + //_rtw_init_listhead(&phwxmit->pending); + //phwxmit->txcmdcnt = 0; + phwxmit->accnt = 0; + } +_func_exit_; +} + +#ifdef CONFIG_BR_EXT +int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + //if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb); + int res, is_vlan_tag=0, i, do_nat25=1; + unsigned short vlan_hdr=0; + void *br_port = NULL; + + //mac_clone_handle_frame(priv, skb); + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + _enter_critical_bh(&padapter->br_ext_lock, &irqL); + if ( !(skb->data[0] & 1) && + br_port && + memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) && + *((unsigned short *)(skb->data+MACADDRLEN*2)) != __constant_htons(ETH_P_8021Q) && + *((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP) && + !memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) { + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + padapter->scdb_entry->ageing_timer = jiffies; + _exit_critical_bh(&padapter->br_ext_lock, &irqL); + } + else + //if (!priv->pmib->ethBrExtInfo.nat25_disable) + { +// if (priv->dev->br_port && +// !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { +#if 1 + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2)); + skb_pull(skb, 4); + } + //if SA == br_mac && skb== IP => copy SIP to br_ip ?? why + if (!memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) && + (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP))) + memcpy(padapter->br_ip, skb->data+WLAN_ETHHDR_LEN+12, 4); + + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)) { + if (memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN)) { + void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr); + + if ((padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, + skb->data+MACADDRLEN, skb->data+WLAN_ETHHDR_LEN+12)) != NULL) { + memcpy(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN); + memcpy(padapter->scdb_ip, skb->data+WLAN_ETHHDR_LEN+12, 4); + padapter->scdb_entry->ageing_timer = jiffies; + do_nat25 = 0; + } + } + else { + if (padapter->scdb_entry) { + padapter->scdb_entry->ageing_timer = jiffies; + do_nat25 = 0; + } + else { + memset(padapter->scdb_mac, 0, MACADDRLEN); + memset(padapter->scdb_ip, 0, 4); + } + } + } + _exit_critical_bh(&padapter->br_ext_lock, &irqL); +#endif // 1 + if (do_nat25) + { + int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method); + if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) { + struct sk_buff *newskb; + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr; + } + + newskb = rtw_skb_copy(skb); + if (newskb == NULL) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n"); + //goto stop_proc; + return -1; + } + rtw_skb_free(skb); + + *pskb = skb = newskb; + if (is_vlan_tag) { + vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2)); + skb_pull(skb, 4); + } + } + + if (skb_is_nonlinear(skb)) + DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__); + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + res = skb_linearize(skb, GFP_ATOMIC); +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + res = skb_linearize(skb); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + if (res < 0) { + DEBUG_ERR("TX DROP: skb_linearize fail!\n"); + //goto free_and_stop; + return -1; + } + + res = nat25_db_handle(padapter, skb, NAT25_INSERT); + if (res < 0) { + if (res == -2) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: nat25_db_handle fail!\n"); + //goto free_and_stop; + return -1; + + } + // we just print warning message and let it go + //DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); + //return -1; // return -1 will cause system crash on 2011/08/30! + return 0; + } + } + + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + + dhcp_flag_bcast(padapter, skb); + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr; + } + } +#if 0 + else{ + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + } + + if(is_vlan_tag){ + if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data)){ + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + } + }else + { + if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data)){ + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + } + } + } +#endif // 0 + + // check if SA is equal to our MAC + if (memcmp(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n", + skb->data[6],skb->data[7],skb->data[8],skb->data[9],skb->data[10],skb->data[11]); + //goto free_and_stop; + return -1; + } + } + return 0; +} +#endif // CONFIG_BR_EXT + +static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib) +{ + u8 qsel; + + qsel = pattrib->priority; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("### do_queue_select priority=%d ,qsel = %d\n",pattrib->priority ,qsel)); + +#ifdef CONFIG_CONCURRENT_MODE +// if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) +// qsel = 7;// +#endif + + pattrib->qsel = qsel; +} + +/* + * The main transmit(tx) entry + * + * Return + * 1 enqueue + * 0 success, hardware will handle this xmit frame(packet) + * <0 fail + */ +s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) +{ + static u32 start = 0; + static u32 drop_cnt = 0; +#ifdef CONFIG_AP_MODE + _irqL irqL0; +#endif + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_frame *pxmitframe = NULL; +#ifdef CONFIG_BR_EXT + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + void *br_port = NULL; +#endif // CONFIG_BR_EXT + + s32 res; + + if (start == 0) + start = rtw_get_current_time(); + + pxmitframe = rtw_alloc_xmitframe(pxmitpriv); + + if (rtw_get_passing_time_ms(start) > 2000) { + if (drop_cnt) + DBG_871X("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt); + start = rtw_get_current_time(); + drop_cnt = 0; + } + + if (pxmitframe == NULL) { + drop_cnt ++; + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n")); + return -1; + } + +#ifdef CONFIG_BR_EXT + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + + if( br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + res = rtw_br_client_tx(padapter, ppkt); + if (res == -1) + { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + return -1; + } + } + +#endif // CONFIG_BR_EXT + + res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); + if (res == _FAIL) { + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n")); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__); + #endif + rtw_free_xmitframe(pxmitpriv, pxmitframe); + return -1; + } + pxmitframe->pkt = *ppkt; + + rtw_led_control(padapter, LED_CTL_TX); + + do_queue_select(padapter, &pxmitframe->attrib); + +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) + { + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + return 1; + } + _exit_critical_bh(&pxmitpriv->lock, &irqL0); +#endif + + if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE) + return 1; + + return 0; +} + +#ifdef CONFIG_TDLS +sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + sint ret=_FALSE; + + _irqL irqL; + struct sta_info *ptdls_sta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + int i; + + ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst); + if(ptdls_sta==NULL){ + return ret; + }else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE){ + + if(pattrib->triggered==1) + { + ret = _TRUE; + return ret; + } + + _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + if(ptdls_sta->state&WIFI_SLEEP_STATE) + { + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q)); + + ptdls_sta->sleepq_len++; + ptdls_sta->sleepq_ac_len++; + + //indicate 4-AC queue bit in TDLS peer traffic indication + switch(pattrib->priority) + { + case 1: + case 2: + ptdls_sta->uapsd_bk = ptdls_sta->uapsd_bk | BIT(1); + break; + case 4: + case 5: + ptdls_sta->uapsd_vi = ptdls_sta->uapsd_vi | BIT(1); + break; + case 6: + case 7: + ptdls_sta->uapsd_vo = ptdls_sta->uapsd_vo | BIT(1); + break; + case 0: + case 3: + default: + ptdls_sta->uapsd_be = ptdls_sta->uapsd_be | BIT(1); + break; + } + + if(ptdls_sta->sleepq_len==1) + { + //transmit TDLS PTI via AP + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_SD_PTI); + } + ret = _TRUE; + + } + + _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + } + + return ret; + +} +#endif //CONFIG_TDLS + +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) + +sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + sint ret=_FALSE; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + sint bmcst = IS_MCAST(pattrib->ra); +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + if( ptdlsinfo->setup_state == TDLS_LINKED_STATE ) + { + ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe); + return ret; + } +#endif //CONFIG_TDLS + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) + return ret; + + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(pstapriv, pattrib->ra); + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FALSE; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FALSE; + } + + if(pattrib->triggered==1) + { + //DBG_871X("directly xmit pspoll_triggered packet\n"); + + //pattrib->triggered=0; + + if(bmcst) + pattrib->qsel = 0x11;//HIQ + + + return ret; + } + + + if(bmcst) + { + _enter_critical_bh(&psta->sleep_q.lock, &irqL); + + if(pstapriv->sta_dz_bitmap)//if anyone sta is in ps mode + { + //pattrib->qsel = 0x11;//HIQ + + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); + + psta->sleepq_len++; + + pstapriv->tim_bitmap |= BIT(0);// + pstapriv->sta_dz_bitmap |= BIT(0); + + //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + + update_beacon(padapter, _TIM_IE_, NULL, _FALSE);//tx bc/mc packets after upate bcn + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + + ret = _TRUE; + + } + + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + + return ret; + + } + + + _enter_critical_bh(&psta->sleep_q.lock, &irqL); + + if(psta->state&WIFI_SLEEP_STATE) + { + u8 wmmps_ac=0; + + if(pstapriv->sta_dz_bitmap&BIT(psta->aid)) + { + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); + + psta->sleepq_len++; + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(0); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(0); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(0); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(0); + break; + } + + if(wmmps_ac) + psta->sleepq_ac_len++; + + if(((psta->has_legacy_ac) && (!wmmps_ac)) ||((!psta->has_legacy_ac)&&(wmmps_ac))) + { + pstapriv->tim_bitmap |= BIT(psta->aid); + + //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + + if(psta->sleepq_len==1) + { + //DBG_871X("sleepq_len==1, update BCNTIM\n"); + //upate BCN for TIM IE + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + } + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + + //if(psta->sleepq_len > (NR_XMITFRAME>>3)) + //{ + // wakeup_sta_to_xmit(padapter, psta); + //} + + ret = _TRUE; + + } + + } + + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + + return ret; + +} + +static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue) +{ + sint ret; + _list *plist, *phead; + u8 ac_index; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib; + struct xmit_frame *pxmitframe; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + plist = get_next(plist); + + ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); + + if(_TRUE == ret) + { + pattrib = &pxmitframe->attrib; + + ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); + + ptxservq->qcnt--; + phwxmits[ac_index].accnt--; + } + else + { + //DBG_871X("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); + } + + } + +} + +void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL0; + struct sta_info *psta_bmc; + struct sta_xmit_priv *pstaxmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + pstaxmitpriv = &psta->sta_xmitpriv; + + //for BC/MC Frames + psta_bmc = rtw_get_bcmc_stainfo(padapter); + + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + psta->state |= WIFI_SLEEP_STATE; + +#ifdef CONFIG_TDLS + if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) ) +#endif //CONFIG_TDLS + pstapriv->sta_dz_bitmap |= BIT(psta->aid); + + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); + +#ifdef CONFIG_TDLS + if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) ) + { + if( psta_bmc != NULL ) + { +#endif //CONFIG_TDLS + + + //for BC/MC Frames + pstaxmitpriv = &psta_bmc->sta_xmitpriv; + dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); + + +#ifdef CONFIG_TDLS + } + } +#endif //CONFIG_TDLS + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + + +} + +void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + u8 update_mask=0, wmmps_ac=0; + struct sta_info *psta_bmc; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + psta_bmc = rtw_get_bcmc_stainfo(padapter); + + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + switch(pxmitframe->attrib.priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + psta->sleepq_len--; + if(psta->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + if(wmmps_ac) + { + psta->sleepq_ac_len--; + if(psta->sleepq_ac_len>0) + { + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + } + else + { + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + } + + pxmitframe->attrib.triggered = 1; + +/* + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta->sleep_q.lock, &irqL); +*/ + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + + } + + //for BC/MC Frames + if(!psta_bmc) + goto _exit; + + if((pstapriv->sta_dz_bitmap&0xfffe) == 0x0)//no any sta in ps mode + { + xmitframe_phead = get_list_head(&psta_bmc->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta_bmc->sleepq_len--; + if(psta_bmc->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + + pxmitframe->attrib.triggered = 1; +/* + _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + +*/ + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + } + + if(psta_bmc->sleepq_len==0) + { + pstapriv->tim_bitmap &= ~BIT(0); + pstapriv->sta_dz_bitmap &= ~BIT(0); + + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_mask |= BIT(1); + } + + } + + if(psta->sleepq_len==0) + { +#ifdef CONFIG_TDLS + if( psta->tdls_sta_state & TDLS_LINKED_STATE ) + { + if(psta->state&WIFI_SLEEP_STATE) + psta->state ^= WIFI_SLEEP_STATE; + + goto _exit; + } +#endif //CONFIG_TDLS + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_mask = BIT(0); + + if(psta->state&WIFI_SLEEP_STATE) + psta->state ^= WIFI_SLEEP_STATE; + + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } + + pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); + } + +_exit: + + //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + if(update_mask) + { + //update_BCNTIM(padapter); + //printk("%s => call update_beacon\n",__FUNCTION__); + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + } + +} + +void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + u8 wmmps_ac=0; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + switch(pxmitframe->attrib.priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + if(!wmmps_ac) + continue; + + rtw_list_delete(&pxmitframe->list); + + psta->sleepq_len--; + psta->sleepq_ac_len--; + + if(psta->sleepq_ac_len>0) + { + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + } + else + { + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + + pxmitframe->attrib.triggered = 1; + +/* + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } +*/ + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + if((psta->sleepq_ac_len==0) && (!psta->has_legacy_ac) && (wmmps_ac)) + { +#ifdef CONFIG_TDLS + if(psta->tdls_sta_state & TDLS_LINKED_STATE ) + { + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + return; + } +#endif //CONFIG_TDLS + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _FALSE); + //update_mask = BIT(0); + } + + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + +} + +#endif + +void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms) +{ + sctx->timeout_ms = timeout_ms; + sctx->submit_time= rtw_get_current_time(); +#ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */ + init_completion(&sctx->done); +#endif + sctx->status = RTW_SCTX_SUBMITTED; +} + +int rtw_sctx_wait(struct submit_ctx *sctx) +{ + int ret = _FAIL; + unsigned long expire; + int status = 0; + +#ifdef PLATFORM_LINUX + expire= sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT; + if (!wait_for_completion_timeout(&sctx->done, expire)) { + /* timeout, do something?? */ + status = RTW_SCTX_DONE_TIMEOUT; + DBG_871X("%s timeout\n", __func__); + } else { + status = sctx->status; + } +#endif + + if (status == RTW_SCTX_DONE_SUCCESS) { + ret = _SUCCESS; + } + + return ret; +} + +bool rtw_sctx_chk_waring_status(int status) +{ + switch(status) { + case RTW_SCTX_DONE_UNKNOWN: + case RTW_SCTX_DONE_BUF_ALLOC: + case RTW_SCTX_DONE_BUF_FREE: + + case RTW_SCTX_DONE_DRV_STOP: + case RTW_SCTX_DONE_DEV_REMOVE: + return _TRUE; + default: + return _FALSE; + } +} + +void rtw_sctx_done_err(struct submit_ctx **sctx, int status) +{ + if (*sctx) { + if (rtw_sctx_chk_waring_status(status)) + DBG_871X("%s status:%d\n", __func__, status); + (*sctx)->status = status; + #ifdef PLATFORM_LINUX + complete(&((*sctx)->done)); + #endif + *sctx = NULL; + } +} + +void rtw_sctx_done(struct submit_ctx **sctx) +{ + rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); +} + +#ifdef CONFIG_XMIT_ACK + +#ifdef CONFIG_XMIT_ACK_POLLING +s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter); + +/** + * rtw_ack_tx_polling - + * @pxmitpriv: xmit_priv to address ack_tx_ops + * @timeout_ms: timeout msec + * + * Init ack_tx_ops and then do c2h_evt_hdl() and polling ack_tx_ops repeatedly + * till tx report or timeout + * Returns: _SUCCESS if TX report ok, _FAIL for others + */ +int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms) +{ + int ret = _FAIL; + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv); + + pack_tx_ops->submit_time = rtw_get_current_time(); + pack_tx_ops->timeout_ms = timeout_ms; + pack_tx_ops->status = RTW_SCTX_SUBMITTED; + + do { + c2h_evt_hdl(adapter, NULL, rtw_hal_c2h_id_filter_ccx(adapter)); + if (pack_tx_ops->status != RTW_SCTX_SUBMITTED) + break; + + if (adapter->bDriverStopped) { + pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP; + break; + } + if (adapter->bSurpriseRemoved) { + pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE; + break; + } + + rtw_msleep_os(10); + } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms); + + if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) { + pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT; + DBG_871X("%s timeout\n", __func__); + } + + if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS) + ret = _SUCCESS; + + return ret; +} +#endif + +int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms) +{ +#ifdef CONFIG_XMIT_ACK_POLLING + return rtw_ack_tx_polling(pxmitpriv, timeout_ms); +#else + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + + pack_tx_ops->submit_time = rtw_get_current_time(); + pack_tx_ops->timeout_ms = timeout_ms; + pack_tx_ops->status = RTW_SCTX_SUBMITTED; + + return rtw_sctx_wait(pack_tx_ops); +#endif +} + +void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status) +{ + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + + if (pxmitpriv->ack_tx) { + rtw_sctx_done_err(&pack_tx_ops, status); + } else { + DBG_871X("%s ack_tx not set\n", __func__); + } +} +#endif //CONFIG_XMIT_ACK + diff --git a/rtl8192cu-fixes/dkms.conf b/rtl8192cu-fixes/dkms.conf new file mode 100644 index 00000000..f19384f5 --- /dev/null +++ b/rtl8192cu-fixes/dkms.conf @@ -0,0 +1,6 @@ +PACKAGE_NAME="8192cu" +PACKAGE_VERSION="1.10" +BUILT_MODULE_NAME="8192cu" +DEST_MODULE_LOCATION="/kernel/drivers/net/wireless/" +REMAKE_INITRD="yes" +AUTOINSTALL="yes" diff --git a/rtl8192cu-fixes/hal/HalPwrSeqCmd.c b/rtl8192cu-fixes/hal/HalPwrSeqCmd.c new file mode 100755 index 00000000..c59bb664 --- /dev/null +++ b/rtl8192cu-fixes/hal/HalPwrSeqCmd.c @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/*++ +Copyright (c) Realtek Semiconductor Corp. All rights reserved. + +Module Name: + HalPwrSeqCmd.c + +Abstract: + Implement HW Power sequence configuration CMD handling routine for Realtek devices. + +Major Change History: + When Who What + ---------- --------------- ------------------------------- + 2011-10-26 Lucas Modify to be compatible with SD4-CE driver. + 2011-07-07 Roger Create. + +--*/ +#include +#include + + +// +// Description: +// This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. +// +// Assumption: +// We should follow specific format which was released from HW SD. +// +// 2011.07.07, added by Roger. +// +u8 HalPwrSeqCmdParsing( + PADAPTER padapter, + u8 CutVersion, + u8 FabVersion, + u8 InterfaceType, + WLAN_PWR_CFG PwrSeqCmd[]) +{ + WLAN_PWR_CFG PwrCfgCmd = {0}; + u8 bPollingBit = _FALSE; + u32 AryIdx = 0; + u8 value = 0; + u32 offset = 0; + u32 pollingCount = 0; // polling autoload done. + u32 maxPollingCnt = 5000; + + do { + PwrCfgCmd = PwrSeqCmd[AryIdx]; + + RT_TRACE(_module_hal_init_c_ , _drv_info_, + ("HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n", + GET_PWR_CFG_OFFSET(PwrCfgCmd), + GET_PWR_CFG_CUT_MASK(PwrCfgCmd), + GET_PWR_CFG_FAB_MASK(PwrCfgCmd), + GET_PWR_CFG_INTF_MASK(PwrCfgCmd), + GET_PWR_CFG_BASE(PwrCfgCmd), + GET_PWR_CFG_CMD(PwrCfgCmd), + GET_PWR_CFG_MASK(PwrCfgCmd), + GET_PWR_CFG_VALUE(PwrCfgCmd))); + + //2 Only Handle the command whose FAB, CUT, and Interface are matched + if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && + (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && + (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) + { + switch (GET_PWR_CFG_CMD(PwrCfgCmd)) + { + case PWR_CMD_READ: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n")); + break; + + case PWR_CMD_WRITE: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")); + offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); + +#ifdef CONFIG_SDIO_HCI + // + // We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface + // 2011.07.07. + // + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + { + // Read Back SDIO Local value + value = SdioLocalCmd52Read1Byte(padapter, offset); + + value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); + value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); + + // Write Back SDIO Local value + SdioLocalCmd52Write1Byte(padapter, offset, value); + } + else +#endif + { + // Read the value from system register + value = rtw_read8(padapter, offset); + + value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); + value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); + + // Write the value back to sytem register + rtw_write8(padapter, offset, value); + } + break; + + case PWR_CMD_POLLING: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")); + + bPollingBit = _FALSE; + offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); + + do { +#ifdef CONFIG_SDIO_HCI + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + value = SdioLocalCmd52Read1Byte(padapter, offset); + else +#endif + value = rtw_read8(padapter, offset); + + value &= GET_PWR_CFG_MASK(PwrCfgCmd); + if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd))) + bPollingBit = _TRUE; + else + rtw_udelay_os(10); + + if (pollingCount++ > maxPollingCnt) { + RT_TRACE(_module_hal_init_c_ , _drv_err_, ("Fail to polling Offset[%#x]\n", offset)); + return _FALSE; + } + } while (!bPollingBit); + + break; + + case PWR_CMD_DELAY: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")); + if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) + rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)); + else + rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000); + break; + + case PWR_CMD_END: + // When this command is parsed, end the process + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n")); + return _TRUE; + break; + + default: + RT_TRACE(_module_hal_init_c_ , _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n")); + break; + } + } + + AryIdx++;//Add Array Index + }while(1); + + return _TRUE; +} + + diff --git a/rtl8192cu-fixes/hal/dm.c b/rtl8192cu-fixes/hal/dm.c new file mode 100755 index 00000000..f0afda74 --- /dev/null +++ b/rtl8192cu-fixes/hal/dm.c @@ -0,0 +1,314 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 + +#ifdef CONFIG_RTL8192C +#include +#endif + +#ifdef CONFIG_RTL8192D +#include +#endif + +bool rtw_adapter_linked(_adapter *adapter) +{ + bool linked = _FALSE; + struct mlme_priv *mlmepriv = &adapter->mlmepriv; + + if( (check_fwstate(mlmepriv, WIFI_AP_STATE) == _TRUE) || + (check_fwstate(mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + if(adapter->stapriv.asoc_sta_count > 2) + linked = _TRUE; + } + else{//Station mode + if(check_fwstate(mlmepriv, _FW_LINKED)== _TRUE) + linked = _TRUE; + } + + return linked; +} + +bool dm_linked(_adapter *adapter) +{ + bool linked; + + if ((linked = rtw_adapter_linked(adapter))) + goto exit; + +#ifdef CONFIG_CONCURRENT_MODE + if ((adapter = adapter->pbuddy_adapter) == NULL) + goto exit; + linked = rtw_adapter_linked(adapter); +#endif + +exit: + return linked; +} + +#if 0 +void dm_enable_EDCCA(_adapter *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))) + { + rtw_write8(adapter,rOFDM0_ECCAThreshold,0x00); + rtw_write8(adapter,rOFDM0_ECCAThreshold+2,0xFD); + + } + else*/ + { + rtw_write8(adapter,rOFDM0_ECCAThreshold,0x03); + rtw_write8(adapter,rOFDM0_ECCAThreshold+2,0x00); + } +} + +void dm_disable_EDCCA(_adapter *adapter) +{ + // Disable EDCCA.. + rtw_write8(adapter, rOFDM0_ECCAThreshold, 0x7f); + rtw_write8(adapter, 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 dm_dynamic_EDCCA(_adapter *pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *dmpriv = &pHalData->dmpriv; + u8 RegC50, RegC58; + + RegC50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); + RegC58 = (u8)PHY_QueryBBReg(pAdapter, 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(!dmpriv->bPreEdccaEnable) + { + dm_enable_EDCCA(pAdapter); + dmpriv->bPreEdccaEnable = _TRUE; + } + + } + else if((RegC50 < 0x25 && RegC58 < 0x25) + /*|| (pDM_Odm->SupportICType == ODM_RTL8188E && RegC50 < 0x25)*/ + ) + { + if(dmpriv->bPreEdccaEnable) + { + dm_disable_EDCCA(pAdapter); + dmpriv->bPreEdccaEnable = _FALSE; + } + } +} +#endif + +#define DM_ADAPTIVITY_VER "ADAPTIVITY_V001" + +int dm_adaptivity_get_parm_str(_adapter *pAdapter, char *buf, int len) +{ +#ifdef CONFIG_DM_ADAPTIVITY + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *dmpriv = &pHalData->dmpriv; + + return snprintf(buf, len, DM_ADAPTIVITY_VER"\n" + "TH_L2H_ini\tTH_EDCCA_HL_diff\tIGI_Base\tForceEDCCA\tAdapEn_RSSI\tIGI_LowerBound\n" + "0x%02x\t%d\t0x%02x\t%d\t%u\t%u\n", + (u8)dmpriv->TH_L2H_ini, + dmpriv->TH_EDCCA_HL_diff, + dmpriv->IGI_Base, + dmpriv->ForceEDCCA, + dmpriv->AdapEn_RSSI, + dmpriv->IGI_LowerBound + ); +#endif /* CONFIG_DM_ADAPTIVITY */ + return 0; +} + +void dm_adaptivity_set_parm(_adapter *pAdapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff, + s8 IGI_Base, bool ForceEDCCA, u8 AdapEn_RSSI, u8 IGI_LowerBound) +{ +#ifdef CONFIG_DM_ADAPTIVITY + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *dmpriv = &pHalData->dmpriv; + + dmpriv->TH_L2H_ini = TH_L2H_ini; + dmpriv->TH_EDCCA_HL_diff = TH_EDCCA_HL_diff; + dmpriv->IGI_Base = IGI_Base; + dmpriv->ForceEDCCA = ForceEDCCA; + dmpriv->AdapEn_RSSI = AdapEn_RSSI; + dmpriv->IGI_LowerBound = IGI_LowerBound; + +#endif /* CONFIG_DM_ADAPTIVITY */ +} + +void dm_adaptivity_init(_adapter *pAdapter) +{ +#ifdef CONFIG_DM_ADAPTIVITY + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *dmpriv = &pHalData->dmpriv; + + /* + if(pDM_Odm->SupportICType == ODM_RTL8723B) + { + pDM_Odm->TH_L2H_ini = 0xf8; // -8 + } + if((pDM_Odm->SupportICType == ODM_RTL8192E)&&(pDM_Odm->SupportInterface == ODM_ITRF_PCIE)) + { + pDM_Odm->TH_L2H_ini = 0xf0; // -16 + } + else */ + { + dmpriv->TH_L2H_ini = 0xf9; // -7 + } + + dmpriv->TH_EDCCA_HL_diff = 7; + dmpriv->IGI_Base = 0x32; + dmpriv->IGI_target = 0x1c; + dmpriv->ForceEDCCA = 0; + dmpriv->AdapEn_RSSI = 20; + dmpriv->IGI_LowerBound = 0; + + //Reg524[11]=0 is easily to transmit packets during adaptivity test + PHY_SetBBReg(pAdapter, 0x524, BIT11, 1); // stop counting if EDCCA is asserted + +#endif /* CONFIG_DM_ADAPTIVITY */ +} + +void dm_adaptivity(_adapter *pAdapter) +{ +#ifdef CONFIG_DM_ADAPTIVITY + s8 TH_L2H_dmc, TH_H2L_dmc; + s8 TH_L2H, TH_H2L, Diff, IGI_target; + u32 value32; + BOOLEAN EDCCA_State; + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *dmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &dmpriv->DM_DigTable; + u8 IGI = pDigTable->CurIGValue; + u8 RSSI_Min = pDigTable->Rssi_val_min; + HT_CHANNEL_WIDTH BandWidth = pHalData->CurrentChannelBW; + + if (!(dmpriv->DMFlag & DYNAMIC_FUNC_ADAPTIVITY)) + { + LOG_LEVEL(_drv_info_, "Go to odm_DynamicEDCCA() \n"); + // Add by Neil Chen to enable edcca to MP Platform + // Adjust EDCCA. + /*if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + dm_dynamic_EDCCA(pAdapter); + */ + return; + } + LOG_LEVEL(_drv_info_, "odm_Adaptivity() =====> \n"); + + LOG_LEVEL(_drv_info_, "ForceEDCCA=%d, IGI_Base=0x%x, TH_L2H_ini = %d, TH_EDCCA_HL_diff = %d, AdapEn_RSSI = %d\n", + dmpriv->ForceEDCCA, dmpriv->IGI_Base, dmpriv->TH_L2H_ini, dmpriv->TH_EDCCA_HL_diff, dmpriv->AdapEn_RSSI); + + /*if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + PHY_SetBBReg(0x800, BIT10, 0); //ADC_mask enable + */ + + if(!dm_linked(pAdapter) || pHalData->CurrentChannel > 149) /* Band4 doesn't need adaptivity */ + { + /*if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)*/ + { + PHY_SetBBReg(pAdapter,rOFDM0_ECCAThreshold, bMaskByte0, 0x7f); + PHY_SetBBReg(pAdapter,rOFDM0_ECCAThreshold, bMaskByte2, 0x7f); + } + /*else + { + ODM_SetBBReg(pDM_Odm, rFPGA0_XB_LSSIReadBack, 0xFFFF, (0x7f<<8) | 0x7f); + }*/ + return; + } + + if(!dmpriv->ForceEDCCA) + { + if(RSSI_Min > dmpriv->AdapEn_RSSI) + EDCCA_State = 1; + else if(RSSI_Min < (dmpriv->AdapEn_RSSI - 5)) + EDCCA_State = 0; + } + else + EDCCA_State = 1; + //if((pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) && (*pDM_Odm->pBandType == BAND_ON_5G)) + //IGI_target = pDM_Odm->IGI_Base; + //else + { + + if(BandWidth == HT_CHANNEL_WIDTH_20) //CHANNEL_WIDTH_20 + IGI_target = dmpriv->IGI_Base; + else if(BandWidth == HT_CHANNEL_WIDTH_40) + IGI_target = dmpriv->IGI_Base + 2; + /*else if(*pDM_Odm->pBandWidth == ODM_BW80M) + IGI_target = pDM_Odm->IGI_Base + 6;*/ + else + IGI_target = dmpriv->IGI_Base; + } + + dmpriv->IGI_target = (u8)IGI_target; + + LOG_LEVEL(_drv_info_, "BandWidth=%s, IGI_target=0x%x, EDCCA_State=%d\n", + (BandWidth==HT_CHANNEL_WIDTH_40)?"40M":"20M", IGI_target, EDCCA_State); + + if(EDCCA_State == 1) + { + Diff = IGI_target -(s8)IGI; + TH_L2H_dmc = dmpriv->TH_L2H_ini + Diff; + if(TH_L2H_dmc > 10) TH_L2H_dmc = 10; + TH_H2L_dmc = TH_L2H_dmc - dmpriv->TH_EDCCA_HL_diff; + } + else + { + TH_L2H_dmc = 0x7f; + TH_H2L_dmc = 0x7f; + } + + LOG_LEVEL(_drv_info_, "IGI=0x%x, TH_L2H_dmc = %d, TH_H2L_dmc = %d\n", + IGI, TH_L2H_dmc, TH_H2L_dmc); + + /*if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES)*/ + { + PHY_SetBBReg(pAdapter,rOFDM0_ECCAThreshold, bMaskByte0, (u8)TH_L2H_dmc); + PHY_SetBBReg(pAdapter,rOFDM0_ECCAThreshold, bMaskByte2, (u8)TH_H2L_dmc); + } + /*else + PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIReadBack, 0xFFFF, ((u8)TH_H2L_dmc<<8) | (u8)TH_L2H_dmc);*/ + +skip_dm: + return; +#endif /* CONFIG_DM_ADAPTIVITY */ +} + diff --git a/rtl8192cu-fixes/hal/dm.h b/rtl8192cu-fixes/hal/dm.h new file mode 100755 index 00000000..17c3de65 --- /dev/null +++ b/rtl8192cu-fixes/hal/dm.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __DM_H__ +#define __DM_H__ + +int dm_adaptivity_get_parm_str(_adapter *pAdapter, char *buf, int len); +void dm_adaptivity_set_parm(_adapter *pAdapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff, + s8 IGI_Base, bool ForceEDCCA, u8 AdapEn_RSSI, u8 IGI_LowerBound); +void dm_adaptivity_init(_adapter *pAdapter); +void dm_adaptivity(_adapter *pAdapter); + +#endif /* __DM_H__ */ diff --git a/rtl8192cu-fixes/hal/hal_com.c b/rtl8192cu-fixes/hal/hal_com.c new file mode 100755 index 00000000..4dcafd65 --- /dev/null +++ b/rtl8192cu-fixes/hal/hal_com.c @@ -0,0 +1,371 @@ +/****************************************************************************** + * + * 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 +#include +#include + +#include +#include + +#ifdef CONFIG_RTL8192C +#include +#endif +#ifdef CONFIG_RTL8192D +#include +#endif + +#define _HAL_COM_C_ + +//============================================================ +// Global var +//============================================================ +u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D] = { + 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 + 0x0f00003c,// 37, -12.5dB + 0x0e400039,// 38, -13.0dB + 0x0d800036,// 39, -13.5dB + 0x0cc00033,// 40, -14.0dB + 0x0c000030,// 41, -14.5dB + 0x0b40002d,// 42, -15.0dB +}; + + +u8 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 + {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 +}; + + +u8 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 + {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 +}; + + +#ifdef CONFIG_CHIP_VER_INTEGRATION +void dump_chip_info(HAL_VERSION ChipVersion) +{ + if(IS_81XXC(ChipVersion)){ + DBG_871X("Chip Version Info: %s_",IS_92C_SERIAL(ChipVersion)?"CHIP_8192C":"CHIP_8188C"); + } + else if(IS_92D(ChipVersion)){ + DBG_871X("Chip Version Info: CHIP_8192D_"); + } + else if(IS_8723_SERIES(ChipVersion)){ + DBG_871X("Chip Version Info: CHIP_8723A_"); + } + else if(IS_8188E(ChipVersion)){ + DBG_871X("Chip Version Info: CHIP_8188E_"); + } + + DBG_871X("%s_",IS_NORMAL_CHIP(ChipVersion)?"Normal_Chip":"Test_Chip"); + DBG_871X("%s_",IS_CHIP_VENDOR_TSMC(ChipVersion)?"TSMC":"UMC"); + if(IS_A_CUT(ChipVersion)) DBG_871X("A_CUT_"); + else if(IS_B_CUT(ChipVersion)) DBG_871X("B_CUT_"); + else if(IS_C_CUT(ChipVersion)) DBG_871X("C_CUT_"); + else if(IS_D_CUT(ChipVersion)) DBG_871X("D_CUT_"); + else if(IS_E_CUT(ChipVersion)) DBG_871X("E_CUT_"); + else DBG_871X("UNKNOWN_CUT(%d)_",ChipVersion.CUTVersion); + + if(IS_1T1R(ChipVersion)) DBG_871X("1T1R_"); + else if(IS_1T2R(ChipVersion)) DBG_871X("1T2R_"); + else if(IS_2T2R(ChipVersion)) DBG_871X("2T2R_"); + else DBG_871X("UNKNOWN_RFTYPE(%d)_",ChipVersion.RFType); + + + DBG_871X("RomVer(%d)\n",ChipVersion.ROMVer); +} + +#endif + +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +u8 //return the final channel plan decision +hal_com_get_channel_plan( + IN PADAPTER padapter, + IN u8 hw_channel_plan, //channel plan from HW (efuse/eeprom) + IN u8 sw_channel_plan, //channel plan from SW (registry/module param) + IN u8 def_channel_plan, //channel plan used when the former two is invalid + IN BOOLEAN AutoLoadFail + ) +{ + u8 swConfig; + u8 chnlPlan; + + swConfig = _TRUE; + if (!AutoLoadFail) + { + if (!rtw_is_channel_plan_valid(sw_channel_plan)) + swConfig = _FALSE; + if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) + swConfig = _FALSE; + } + + if (swConfig == _TRUE) + chnlPlan = sw_channel_plan; + else + chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK); + + if (!rtw_is_channel_plan_valid(chnlPlan)) + chnlPlan = def_channel_plan; + + return chnlPlan; +} + +u8 MRateToHwRate(u8 rate) +{ + u8 ret = DESC_RATE1M; + + switch(rate) + { + // CCK and OFDM non-HT rates + case IEEE80211_CCK_RATE_1MB: ret = DESC_RATE1M; break; + case IEEE80211_CCK_RATE_2MB: ret = DESC_RATE2M; break; + case IEEE80211_CCK_RATE_5MB: ret = DESC_RATE5_5M; break; + case IEEE80211_CCK_RATE_11MB: ret = DESC_RATE11M; break; + case IEEE80211_OFDM_RATE_6MB: ret = DESC_RATE6M; break; + case IEEE80211_OFDM_RATE_9MB: ret = DESC_RATE9M; break; + case IEEE80211_OFDM_RATE_12MB: ret = DESC_RATE12M; break; + case IEEE80211_OFDM_RATE_18MB: ret = DESC_RATE18M; break; + case IEEE80211_OFDM_RATE_24MB: ret = DESC_RATE24M; break; + case IEEE80211_OFDM_RATE_36MB: ret = DESC_RATE36M; break; + case IEEE80211_OFDM_RATE_48MB: ret = DESC_RATE48M; break; + case IEEE80211_OFDM_RATE_54MB: ret = DESC_RATE54M; break; + + // HT rates since here + //case MGN_MCS0: ret = DESC_RATEMCS0; break; + //case MGN_MCS1: ret = DESC_RATEMCS1; break; + //case MGN_MCS2: ret = DESC_RATEMCS2; break; + //case MGN_MCS3: ret = DESC_RATEMCS3; break; + //case MGN_MCS4: ret = DESC_RATEMCS4; break; + //case MGN_MCS5: ret = DESC_RATEMCS5; break; + //case MGN_MCS6: ret = DESC_RATEMCS6; break; + //case MGN_MCS7: ret = DESC_RATEMCS7; break; + + default: break; + } + + return ret; +} + +void HalSetBrateCfg( + IN PADAPTER Adapter, + IN u8 *mBratesOS, + OUT u16 *pBrateCfg) +{ + u8 i, is_brate, brate; + + for(i=0;ieeprompriv.mac_addr); +#ifdef CONFIG_CONCURRENT_MODE + if (adapter->pbuddy_adapter) + rtw_hal_set_hwreg(adapter->pbuddy_adapter, HW_VAR_MAC_ADDR, adapter->pbuddy_adapter->eeprompriv.mac_addr); +#endif +} + +/* +* C2H event format: +* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID +* BITS [127:120] [119:16] [15:8] [7:4] [3:0] +*/ + +void c2h_evt_clear(_adapter *adapter) +{ + rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); +} + +s32 c2h_evt_read(_adapter *adapter, u8 *buf) +{ + s32 ret = _FAIL; + struct c2h_evt_hdr *c2h_evt; + int i; + u8 trigger; + + if (buf == NULL) + goto exit; + + trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); + + if (trigger == C2H_EVT_HOST_CLOSE) { + goto exit; /* Not ready */ + } else if (trigger != C2H_EVT_FW_CLOSE) { + goto clear_evt; /* Not a valid value */ + } + + c2h_evt = (struct c2h_evt_hdr *)buf; + + _rtw_memset(c2h_evt, 0, 16); + + *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); + *(buf+1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ", + &c2h_evt , sizeof(c2h_evt)); + + if (0) { + DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__ + , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger); + } + + /* Read the content */ + for (i = 0; i < c2h_evt->plen; i++) + c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n", + c2h_evt->payload, c2h_evt->plen); + + ret = _SUCCESS; + +clear_evt: + /* + * Clear event to notify FW we have read the command. + * If this field isn't clear, the FW won't update the next command message. + */ + c2h_evt_clear(adapter); +exit: + return ret; +} + diff --git a/rtl8192cu-fixes/hal/hal_intf.c b/rtl8192cu-fixes/hal/hal_intf.c new file mode 100755 index 00000000..6c56e72d --- /dev/null +++ b/rtl8192cu-fixes/hal/hal_intf.c @@ -0,0 +1,546 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ + +#define _HAL_INTF_C_ +#include +#include +#include +#include + +#include + +#ifdef CONFIG_SDIO_HCI + #include +#elif defined(CONFIG_USB_HCI) + #include +#elif defined(CONFIG_GSPI_HCI) + #include +#endif + +void rtw_hal_chip_configure(_adapter *padapter) +{ + if(padapter->HalFunc.intf_chip_configure) + padapter->HalFunc.intf_chip_configure(padapter); +} + +void rtw_hal_read_chip_info(_adapter *padapter) +{ + if(padapter->HalFunc.read_adapter_info) + padapter->HalFunc.read_adapter_info(padapter); +} + +void rtw_hal_read_chip_version(_adapter *padapter) +{ + if(padapter->HalFunc.read_chip_version) + padapter->HalFunc.read_chip_version(padapter); +} + +void rtw_hal_def_value_init(_adapter *padapter) +{ + if(padapter->HalFunc.init_default_value) + padapter->HalFunc.init_default_value(padapter); +} + +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) +{ + if(padapter->HalFunc.dm_init) + padapter->HalFunc.dm_init(padapter); +} + +void rtw_hal_dm_deinit(_adapter *padapter) +{ + // cancel dm timer + if(padapter->HalFunc.dm_deinit) + padapter->HalFunc.dm_deinit(padapter); +} + +void rtw_hal_sw_led_init(_adapter *padapter) +{ + if(padapter->HalFunc.InitSwLeds) + padapter->HalFunc.InitSwLeds(padapter); +} + +void rtw_hal_sw_led_deinit(_adapter *padapter) +{ + if(padapter->HalFunc.DeInitSwLeds) + padapter->HalFunc.DeInitSwLeds(padapter); +} + +uint rtw_hal_init(_adapter *padapter) +{ + uint status = _SUCCESS; + + if(padapter->hw_init_completed == _TRUE) + { + DBG_871X("rtw_hal_init: hw_init_completed == _TRUE\n"); + goto success; + } +#ifdef CONFIG_DEINIT_BEFORE_INIT + status = padapter->HalFunc.hal_deinit(padapter); + if(status != _SUCCESS){ + DBG_871X("rtw_hal_init: hal_deinit before hal_init FAIL !!\n"); + goto fail; + } +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + // before init mac0, driver must init mac1 first to avoid usb rx error. + if((padapter->pbuddy_adapter != NULL) && (padapter->DualMacConcurrent == _TRUE) + && (padapter->adapter_type == PRIMARY_ADAPTER)) + { + if(padapter->pbuddy_adapter->hw_init_completed == _TRUE) + { + DBG_871X("rtw_hal_init: pbuddy_adapter hw_init_completed == _TRUE\n"); + } + else + { +#ifdef CONFIG_DEINIT_BEFORE_INIT + status = padapter->HalFunc.hal_deinit(padapter->pbuddy_adapter); + if(status != _SUCCESS){ + DBG_871X("rtw_hal_init: hal_deinit before hal_init FAIL !!(pbuddy_adapter)\n"); + goto fail; + } +#endif + status = padapter->HalFunc.hal_init(padapter->pbuddy_adapter); + if(status == _SUCCESS){ + padapter->pbuddy_adapter->hw_init_completed = _TRUE; + } + else{ + padapter->pbuddy_adapter->hw_init_completed = _FALSE; + RT_TRACE(_module_hal_init_c_,_drv_err_,("rtw_hal_init: hal__init fail(pbuddy_adapter)\n")); + goto fail; + } + } + } +#else + if(adapter_to_dvobj(padapter)->DualMacMode == _TRUE) + { + if(padapter->pbuddy_adapter != NULL) { + if(padapter->pbuddy_adapter->hw_init_completed == _FALSE) + { +#ifdef CONFIG_DEINIT_BEFORE_INIT + status = padapter->HalFunc.hal_deinit(padapter->pbuddy_adapter); + if(status != _SUCCESS){ + DBG_871X("rtw_hal_init: hal_deinit before hal_init FAIL !!(pbuddy_adapter)\n"); + goto fail; + } +#endif + status = padapter->HalFunc.hal_init(padapter->pbuddy_adapter); + if(status == _SUCCESS){ + padapter->pbuddy_adapter->hw_init_completed = _TRUE; + } + else{ + padapter->pbuddy_adapter->hw_init_completed = _FALSE; + RT_TRACE(_module_hal_init_c_,_drv_err_,("rtw_hal_init: hal__init fail for another interface\n")); + } + } + } + } +#endif + + padapter->hw_init_completed=_FALSE; + + status = padapter->HalFunc.hal_init(padapter); + + if(status == _SUCCESS){ + padapter->hw_init_completed = _TRUE; + } + else{ + padapter->hw_init_completed = _FALSE; + RT_TRACE(_module_hal_init_c_,_drv_err_,("rtw_hal_init: hal__init fail\n")); + goto fail; + } + +success: + + if (padapter->registrypriv.notch_filter == 1) + rtw_hal_notch_filter(padapter, 1); + + rtw_hal_reset_security_engine(padapter); + + rtw_sec_restore_wep_key(padapter); + + init_hw_mlme_ext(padapter); + +fail: + + RT_TRACE(_module_hal_init_c_,_drv_err_,("-rtl871x_hal_init:status=0x%x\n",status)); + + return status; +} + +uint rtw_hal_deinit(_adapter *padapter) +{ + uint status = _SUCCESS; + +_func_enter_; + + status = padapter->HalFunc.hal_deinit(padapter); + + if(status == _SUCCESS){ + padapter->hw_init_completed = _FALSE; + } + else + { + RT_TRACE(_module_hal_init_c_,_drv_err_,("\n rtw_hal_deinit: hal_init fail\n")); + } + +_func_exit_; + + return status; +} + +void rtw_hal_set_hwreg(_adapter *padapter, u8 variable, u8 *val) +{ + if (padapter->HalFunc.SetHwRegHandler) + padapter->HalFunc.SetHwRegHandler(padapter, variable, val); +} + +void rtw_hal_get_hwreg(_adapter *padapter, u8 variable, u8 *val) +{ + if (padapter->HalFunc.GetHwRegHandler) + padapter->HalFunc.GetHwRegHandler(padapter, variable, val); +} + +u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue) +{ + if(padapter->HalFunc.SetHalDefVarHandler) + return padapter->HalFunc.SetHalDefVarHandler(padapter,eVariable,pValue); + return _FAIL; +} + +u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue) +{ + if(padapter->HalFunc.GetHalDefVarHandler) + return padapter->HalFunc.GetHalDefVarHandler(padapter,eVariable,pValue); + return _FAIL; +} + +void rtw_hal_enable_interrupt(_adapter *padapter) +{ + if (padapter->HalFunc.enable_interrupt) + padapter->HalFunc.enable_interrupt(padapter); + else + DBG_871X("%s: HalFunc.enable_interrupt is NULL!\n", __FUNCTION__); + +} +void rtw_hal_disable_interrupt(_adapter *padapter) +{ + if (padapter->HalFunc.disable_interrupt) + padapter->HalFunc.disable_interrupt(padapter); + else + DBG_871X("%s: HalFunc.disable_interrupt is NULL!\n", __FUNCTION__); + +} + +u32 rtw_hal_inirp_init(_adapter *padapter) +{ + u32 rst = _FAIL; + if(padapter->HalFunc.inirp_init) + rst = padapter->HalFunc.inirp_init(padapter); + else + DBG_871X(" %s HalFunc.inirp_init is NULL!!!\n",__FUNCTION__); + return rst; +} + +u32 rtw_hal_inirp_deinit(_adapter *padapter) +{ + + if(padapter->HalFunc.inirp_deinit) + return padapter->HalFunc.inirp_deinit(padapter); + + return _FAIL; + +} + +u8 rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val) +{ + if(padapter->HalFunc.interface_ps_func) + return padapter->HalFunc.interface_ps_func(padapter,efunc_id,val); + return _FAIL; +} + +s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + if(padapter->HalFunc.hal_xmitframe_enqueue) + return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); + + return _FALSE; +} + +s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + if(padapter->HalFunc.hal_xmit) + return padapter->HalFunc.hal_xmit(padapter, pxmitframe); + + return _FALSE; +} + +s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + s32 ret = _FAIL; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + _rtw_memcpy(pmgntframe->attrib.ra, pwlanhdr->addr1, ETH_ALEN); + +#ifdef CONFIG_IEEE80211W + if(padapter->securitypriv.binstallBIPkey == _TRUE) + { + if(IS_MCAST(pmgntframe->attrib.ra)) + { + pmgntframe->attrib.encrypt = _BIP_; + //pmgntframe->attrib.bswenc = _TRUE; + } + else + { + pmgntframe->attrib.encrypt = _AES_; + pmgntframe->attrib.bswenc = _TRUE; + } + rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe); + } +#endif //CONFIG_IEEE80211W + + if(padapter->HalFunc.mgnt_xmit) + ret = padapter->HalFunc.mgnt_xmit(padapter, pmgntframe); + return ret; +} + +s32 rtw_hal_init_xmit_priv(_adapter *padapter) +{ + if(padapter->HalFunc.init_xmit_priv != NULL) + return padapter->HalFunc.init_xmit_priv(padapter); + return _FAIL; +} + +void rtw_hal_free_xmit_priv(_adapter *padapter) +{ + if(padapter->HalFunc.free_xmit_priv != NULL) + padapter->HalFunc.free_xmit_priv(padapter); +} + +s32 rtw_hal_init_recv_priv(_adapter *padapter) +{ + if(padapter->HalFunc.init_recv_priv) + return padapter->HalFunc.init_recv_priv(padapter); + + return _FAIL; +} + +void rtw_hal_free_recv_priv(_adapter *padapter) +{ + if(padapter->HalFunc.free_recv_priv) + padapter->HalFunc.free_recv_priv(padapter); +} + +void rtw_hal_update_ra_mask(_adapter *padapter, u32 mac_id) +{ + if(padapter->HalFunc.UpdateRAMaskHandler) + padapter->HalFunc.UpdateRAMaskHandler(padapter,mac_id); +} + +void rtw_hal_add_ra_tid(_adapter *padapter, u32 bitmap, u8 arg) +{ + if(padapter->HalFunc.Add_RateATid) + padapter->HalFunc.Add_RateATid(padapter, bitmap, arg); +} + +u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask) +{ + u32 data = 0; + if (padapter->HalFunc.read_bbreg) + data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask); + return data; +} + +void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data) +{ + if (padapter->HalFunc.write_bbreg) + padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data); +} + +u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask) +{ + u32 data = 0; + if (padapter->HalFunc.read_rfreg) + data = padapter->HalFunc.read_rfreg(padapter, eRFPath, RegAddr, BitMask); + return data; +} + +void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data) +{ + if (padapter->HalFunc.write_rfreg) + padapter->HalFunc.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data); +} + +s32 rtw_hal_interrupt_handler(_adapter *padapter) +{ + if(padapter->HalFunc.interrupt_handler) + return padapter->HalFunc.interrupt_handler(padapter); + return _FAIL; +} + +void rtw_hal_set_bwmode(_adapter *padapter, HT_CHANNEL_WIDTH Bandwidth, u8 Offset) +{ + if(padapter->HalFunc.set_bwmode_handler) + padapter->HalFunc.set_bwmode_handler(padapter, Bandwidth, Offset); +} + +void rtw_hal_set_chan(_adapter *padapter, u8 channel) +{ + if(padapter->HalFunc.set_channel_handler) + padapter->HalFunc.set_channel_handler(padapter, channel); +} + +void rtw_hal_dm_watchdog(_adapter *padapter) +{ + if(padapter->HalFunc.hal_dm_watchdog) + padapter->HalFunc.hal_dm_watchdog(padapter); +} + +void rtw_hal_bcn_related_reg_setting(_adapter *padapter) +{ + if(padapter->HalFunc.SetBeaconRelatedRegistersHandler) + padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter); +} + +#ifdef CONFIG_ANTENNA_DIVERSITY +u8 rtw_hal_antdiv_before_linked(_adapter *padapter) +{ + if (padapter->HalFunc.AntDivBeforeLinkHandler) + return padapter->HalFunc.AntDivBeforeLinkHandler(padapter); + return _FALSE; +} + +void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src) +{ + if (padapter->HalFunc.AntDivCompareHandler) + padapter->HalFunc.AntDivCompareHandler(padapter, dst, src); +} +#endif + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt) +{ + if (padapter->HalFunc.hostap_mgnt_xmit_entry) + return padapter->HalFunc.hostap_mgnt_xmit_entry(padapter, pkt); + return _FAIL; +} +#endif //CONFIG_HOSTAPD_MLME + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtw_hal_sreset_init(_adapter *padapter) +{ + if(padapter->HalFunc.sreset_init_value) + padapter->HalFunc.sreset_init_value(padapter); +} + +void rtw_hal_sreset_reset(_adapter *padapter) +{ + padapter = GET_PRIMARY_ADAPTER(padapter); + + if(padapter->HalFunc.silentreset) + padapter->HalFunc.silentreset(padapter); +} + +void rtw_hal_sreset_reset_value(_adapter *padapter) +{ + if(padapter->HalFunc.sreset_reset_value) + padapter->HalFunc.sreset_reset_value(padapter); +} + +void rtw_hal_sreset_xmit_status_check(_adapter *padapter) +{ +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + if(padapter->HalFunc.sreset_xmit_status_check) + padapter->HalFunc.sreset_xmit_status_check(padapter); +} + +void rtw_hal_sreset_linked_status_check(_adapter *padapter) +{ + if(padapter->HalFunc.sreset_linked_status_check) + padapter->HalFunc.sreset_linked_status_check(padapter); +} + +u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter) +{ + u8 status = 0; + if(padapter->HalFunc.sreset_get_wifi_status) + status = padapter->HalFunc.sreset_get_wifi_status(padapter); + return status; +} + +bool rtw_hal_sreset_inprogress(_adapter *padapter) +{ + bool inprogress = _FALSE; + + padapter = GET_PRIMARY_ADAPTER(padapter); + + if(padapter->HalFunc.sreset_inprogress) + inprogress = padapter->HalFunc.sreset_inprogress(padapter); + return inprogress; +} +#endif //DBG_CONFIG_ERROR_DETECT + +#ifdef CONFIG_IOL +int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms) +{ + if (adapter->HalFunc.IOL_exec_cmds_sync) + return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms); + return _FAIL; +} +#endif + +void rtw_hal_notch_filter(_adapter *adapter, bool enable) +{ + if(adapter->HalFunc.hal_notch_filter) + adapter->HalFunc.hal_notch_filter(adapter,enable); +} + +void rtw_hal_reset_security_engine(_adapter * adapter) +{ + if(adapter->HalFunc.hal_reset_security_engine) + adapter->HalFunc.hal_reset_security_engine(adapter); +} + +s32 rtw_hal_c2h_handler(_adapter *adapter, struct c2h_evt_hdr *c2h_evt) +{ + s32 ret = _FAIL; + if (adapter->HalFunc.c2h_handler) + ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); + return ret; +} + +c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *adapter) +{ + return adapter->HalFunc.c2h_id_filter_ccx; +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c new file mode 100755 index 00000000..33921e2e --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c @@ -0,0 +1,1159 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8192C_CMD_C_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define RTL92C_MAX_H2C_BOX_NUMS 4 +#define RTL92C_MAX_CMD_LEN 5 +#define MESSAGE_BOX_SIZE 4 +#define EX_MESSAGE_BOX_SIZE 2 + +static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num) +{ + u8 read_down = _FALSE; + int retry_cnts = 100; + + u8 valid; + +// DBG_8192C(" _is_fw_read_cmd_down ,isnormal_chip(%x),reg_1cc(%x),msg_box(%d)...\n",isvern,rtw_read8(padapter,REG_HMETFR),msgbox_num); + + do{ + valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num); + if(0 == valid ){ + read_down = _TRUE; + } + }while( (!read_down) && (retry_cnts--)); + + return read_down; + +} + + +/***************************************** +* H2C Msg format : +*| 31 - 8 |7 | 6 - 0 | +*| h2c_msg |Ext_bit |CMD_ID | +* +******************************************/ +int rtl8192c_FillH2CCmd(_adapter* padapter, u8 ElementID, u32 CmdLen, u8* pCmdBuffer) +{ + u8 bcmd_down = _FALSE; + int retry_cnts = 100; + u8 h2c_box_num; + u32 msgbox_addr; + u32 msgbox_ex_addr; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u32 h2c_cmd = 0; + u16 h2c_cmd_ex = 0; + int ret = _FAIL; + +_func_enter_; + + padapter = GET_PRIMARY_ADAPTER(padapter); + pHalData = GET_HAL_DATA(padapter); + + if(padapter->bFWReady == _FALSE) + { + DBG_8192C("FillH2CCmd(): return H2C cmd because fw is not ready\n"); + return ret; + } + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); + + if(!pCmdBuffer){ + goto exit; + } + if(CmdLen > RTL92C_MAX_CMD_LEN){ + goto exit; + } + //pay attention to if race condition happened in H2C cmd setting. + do{ + h2c_box_num = pHalData->LastHMEBoxNum; + + if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){ + DBG_8192C(" fw read cmd failed...\n"); + goto exit; + } + + if(CmdLen<=3) + { + _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen ); + } + else{ + _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer, EX_MESSAGE_BOX_SIZE); + _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer+2,( CmdLen-EX_MESSAGE_BOX_SIZE)); + *(u8*)(&h2c_cmd) |= BIT(7); + } + + *(u8*)(&h2c_cmd) |= ElementID; + + if(h2c_cmd & BIT(7)){ + msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num *EX_MESSAGE_BOX_SIZE); + h2c_cmd_ex = cpu_to_le16( h2c_cmd_ex ); + rtw_write16(padapter, msgbox_ex_addr, h2c_cmd_ex); + } + msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE); + h2c_cmd = cpu_to_le32( h2c_cmd ); + rtw_write32(padapter,msgbox_addr, h2c_cmd); + + bcmd_down = _TRUE; + + // DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" + // ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); + + pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL92C_MAX_H2C_BOX_NUMS ; + + }while((!bcmd_down) && (retry_cnts--)); +/* + if(bcmd_down) + DBG_8192C("H2C Cmd exe down. \n" ); + else + DBG_8192C("H2C Cmd exe failed. \n" ); +*/ + ret = _SUCCESS; + +exit: + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); + +_func_exit_; + + return ret; + +} + +u8 rtl8192c_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf) +{ + u8 ElementID, CmdLen; + u8 *pCmdBuffer; + struct cmd_msg_parm *pcmdmsg; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + pcmdmsg = (struct cmd_msg_parm*)pbuf; + ElementID = pcmdmsg->eid; + CmdLen = pcmdmsg->sz; + pCmdBuffer = pcmdmsg->buf; + + rtl8192c_FillH2CCmd(padapter, ElementID, CmdLen, pCmdBuffer); + + return H2C_SUCCESS; +} + +#if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED) +u8 rtl8192c_set_FwSelectSuspend_cmd(_adapter *padapter ,u8 bfwpoll, u16 period) +{ + u8 res=_SUCCESS; + struct H2C_SS_RFOFF_PARAM param; + DBG_8192C("==>%s bfwpoll(%x)\n",__FUNCTION__,bfwpoll); + param.gpio_period = period;//Polling GPIO_11 period time + param.ROFOn = (_TRUE == bfwpoll)?1:0; + rtl8192c_FillH2CCmd(padapter, SELECTIVE_SUSPEND_ROF_CMD, sizeof(param), (u8*)(¶m)); + return res; +} +#endif //CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED + +u8 rtl8192c_set_rssi_cmd(_adapter*padapter, u8 *param) +{ + u8 res=_SUCCESS; + +_func_enter_; + + *((u32*) param ) = cpu_to_le32( *((u32*) param ) ); + + rtl8192c_FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param); + +_func_exit_; + + return res; +} + +u8 rtl8192c_set_raid_cmd(_adapter*padapter, u32 mask, u8 arg) +{ + u8 buf[5]; + u8 res=_SUCCESS; + +_func_enter_; + + _rtw_memset(buf, 0, 5); + mask = cpu_to_le32( mask ); + _rtw_memcpy(buf, &mask, 4); + buf[4] = arg; + + rtl8192c_FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf); + +_func_exit_; + + return res; + +} + +//bitmap[0:27] = tx_rate_bitmap +//bitmap[28:31]= Rate Adaptive id +//arg[0:4] = macid +//arg[5] = Short GI +void rtl8192c_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8 arg) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + if(pHalData->fw_ractrl == _TRUE) + { + rtl8192c_set_raid_cmd(pAdapter, bitmap, arg); + } + else + { + u8 macid, init_rate, shortGIrate=_FALSE; + + init_rate = get_highest_rate_idx(bitmap&0x0fffffff)&0x3f; + + macid = arg&0x1f; + + shortGIrate = (arg&BIT(5)) ? _TRUE:_FALSE; + + if (shortGIrate==_TRUE) + init_rate |= BIT(6); + + rtw_write8(pAdapter, (REG_INIDATA_RATE_SEL+macid), (u8)init_rate); + } + +} + +void rtl8192c_set_FwPwrMode_cmd(_adapter*padapter, u8 Mode) +{ + SETPWRMODE_PARM H2CSetPwrMode; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + +_func_enter_; + + DBG_871X("%s(): Mode = %d, SmartPS = %d\n", __FUNCTION__,Mode,pwrpriv->smart_ps); + + H2CSetPwrMode.Mode = Mode; + + H2CSetPwrMode.SmartPS = pwrpriv->smart_ps; + + H2CSetPwrMode.BcnPassTime = 1;//pPSC->RegMaxLPSAwakeIntvl; + + rtl8192c_FillH2CCmd(padapter, SET_PWRMODE_EID, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode); + +_func_exit_; +} + +void ConstructBeacon(_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); + +} + +void ConstructPSPoll(_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; +} + +void ConstructNullFunctionData(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN 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); + + SetFrameSubType(pframe, WIFI_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + *pLength = pktlen; +} + +void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u8 *mac, *bssid; + u32 pktlen; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + + + //DBG_871X("%s\n", __FUNCTION__); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + mac = myid(&(padapter->eeprompriv)); + bssid = cur_network->MacAddress; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pktlen; + + if(cur_network->IELength>MAX_IE_SZ) + return; + + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pktlen += cur_network->IELength; + + *pLength = pktlen; +} + +// +// Description: In normal chip, we should send some packet to Hw which will be used by Fw +// in FW LPS mode. The function is to fill the Tx descriptor of this packets, then +// Fw can tell Hw to send these packet derectly. +// Added by tynli. 2009.10.15. +// +static VOID +FillFakeTxDescriptor92C( + IN PADAPTER Adapter, + IN u8* pDesc, + IN u32 BufferLen, + IN BOOLEAN IsPsPoll +) +{ + struct tx_desc *ptxdesc = (struct tx_desc *)pDesc; + + // Clear all status + _rtw_memset(pDesc, 0, 32); + + //offset 0 + ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg; + + ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<txdw1 |= cpu_to_le32(NAVUSEHDR); + } + else + { + ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number + ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. + } + + //offset 16 + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + +#ifdef CONFIG_USB_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.). + rtl8192cu_cal_txdesc_chksum(ptxdesc); +#endif + + //RT_PRINT_DATA(COMP_CMD, DBG_TRACE, "TxFillCmdDesc8192C(): H2C Tx Cmd Content ----->\n", pDesc, TX_DESC_SIZE); +} + +// To check if reserved page content is destroyed by beacon beacuse beacon is too large. +// 2010.06.23. Added by tynli. +VOID +CheckFwRsvdPageContent( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE* pHalData = GET_HAL_DATA(Adapter); + u32 MaxBcnPageNum; + + if(pHalData->FwRsvdPageStartOffset != 0) + { + /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize); + RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset), + ("CheckFwRsvdPageContent(): The reserved page content has been"\ + "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!", + MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/ + } +} + +// +// 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: +// bDLFinished - 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. +static void SetFwRsvdPagePkt(PADAPTER Adapter, BOOLEAN bDLFinished) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u32 BeaconLength, ProbeRspLength, PSPollLength, NullFunctionDataLength; + u8 *ReservedPagePacket; + u8 PageNum=0, U1bTmp, TxDescLen=0, TxDescOffset=0; + u16 BufIndex=0; + u32 TotalPacketLen; + RSVDPAGE_LOC RsvdPageLoc; + BOOLEAN bDLOK = _FALSE; + + DBG_871X("%s\n", __FUNCTION__); + + ReservedPagePacket = (u8*)rtw_malloc(1000); + if(ReservedPagePacket == NULL){ + DBG_871X("%s(): alloc ReservedPagePacket fail !!!\n", __FUNCTION__); + return; + } + + _rtw_memset(ReservedPagePacket, 0, 1000); + + TxDescLen = 32;//TX_DESC_SIZE; + +#ifdef CONFIG_USB_HCI + BufIndex = TXDESC_OFFSET; + TxDescOffset = TxDescLen+8; //Shift index for 8 bytes because the dummy bytes in the first descipstor. +#else + BufIndex = 0; + TxDescOffset = 0; +#endif + + //(1) beacon + ConstructBeacon(Adapter,&ReservedPagePacket[BufIndex],&BeaconLength); + + //DBG_8192C("SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: BCN\n", &ReservedPagePacket[BufIndex], (BeaconLength+BufIndex)); + +//-------------------------------------------------------------------- + + // 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. + U1bTmp = (u8)PageNum_128(BeaconLength+TxDescLen); + PageNum += U1bTmp; + // To reserved 2 pages for beacon buffer. 2010.06.24. + if(PageNum == 1) + PageNum+=1; + pHalData->FwRsvdPageStartOffset = PageNum; + + BufIndex = (PageNum*128) + TxDescOffset; + + //(2) ps-poll + ConstructPSPoll(Adapter, &ReservedPagePacket[BufIndex],&PSPollLength); + + FillFakeTxDescriptor92C(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE); + + //DBG_8192C("SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PS-POLL\n", &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen)); + + RsvdPageLoc.LocPsPoll = PageNum; + +//------------------------------------------------------------------ + + U1bTmp = (u8)PageNum_128(PSPollLength+TxDescLen); + PageNum += U1bTmp; + + BufIndex = (PageNum*128) + TxDescOffset; + + //(3) null data + ConstructNullFunctionData( + Adapter, + &ReservedPagePacket[BufIndex], + &NullFunctionDataLength, + get_my_bssid(&(pmlmeinfo->network)), + _FALSE); + + FillFakeTxDescriptor92C(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], NullFunctionDataLength, _FALSE); + + RsvdPageLoc.LocNullData = PageNum; + + //DBG_8192C("SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: NULL DATA \n", &ReservedPagePacket[BufIndex-TxDescLen], (NullFunctionDataLength+TxDescLen)); +//------------------------------------------------------------------ + + U1bTmp = (u8)PageNum_128(NullFunctionDataLength+TxDescLen); + PageNum += U1bTmp; + + BufIndex = (PageNum*128) + TxDescOffset; + + //(4) probe response + ConstructProbeRsp( + Adapter, + &ReservedPagePacket[BufIndex], + &ProbeRspLength, + get_my_bssid(&(pmlmeinfo->network)), + _FALSE); + + FillFakeTxDescriptor92C(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE); + + RsvdPageLoc.LocProbeRsp = PageNum; + + //DBG_8192C("SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PROBE RSP \n", &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength-TxDescLen)); + +//------------------------------------------------------------------ + + U1bTmp = (u8)PageNum_128(ProbeRspLength+TxDescLen); + + PageNum += U1bTmp; + + TotalPacketLen = (PageNum*128); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + pattrib->qsel = 0x10; + pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescLen; + _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); + + rtw_hal_mgnt_xmit(Adapter, pmgntframe); + + bDLOK = _TRUE; + + if(bDLOK) + { + DBG_871X("Set RSVD page location to Fw.\n"); + rtl8192c_FillH2CCmd(Adapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); + } + + rtw_mfree(ReservedPagePacket,1000); + +} + +void rtl8192c_set_FwJoinBssReport_cmd(_adapter* padapter, u8 mstatus) +{ + JOINBSSRPT_PARM JoinBssRptParm; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +_func_enter_; + + DBG_871X("%s mstatus(%x)\n", __FUNCTION__,mstatus); + + if(mstatus == 1) + { + BOOLEAN bRecover = _FALSE; + + // 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(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid)); + // Do not set TSF again here or vWiFi beacon DMA INT will not work. + //correct_TSF(padapter, pmlmeext); + // Hw sequende enable by dedault. 2010.06.23. by tynli. + //rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); + //rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); + + //set REG_CR bit 8 + //U1bTmp = rtw_read8(padapter, REG_CR+1); + rtw_write8(padapter, REG_CR+1, 0x03); + + // 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. + //SetBcnCtrlReg(padapter, 0, BIT3); + //SetBcnCtrlReg(padapter, BIT4, 0); + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(3))); + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(4)); + + // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. + if(pHalData->RegFwHwTxQCtrl&BIT6) + bRecover = _TRUE; + + // To tell Hw the packet is not a real beacon frame. + //U1bTmp = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2); + rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT6))); + pHalData->RegFwHwTxQCtrl &= (~BIT6); + SetFwRsvdPagePkt(padapter, 0); + + // 2010.05.11. Added by tynli. + //SetBcnCtrlReg(padapter, BIT3, 0); + //SetBcnCtrlReg(padapter, 0, BIT4); + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(3)); + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(4))); + + // 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(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT6)); + pHalData->RegFwHwTxQCtrl |= BIT6; + } + + // Clear CR[8] or beacon packet will not be send to TxBuf anymore. + rtw_write8(padapter, REG_CR+1, 0x02); + } + + JoinBssRptParm.OpMode = mstatus; + + rtl8192c_FillH2CCmd(padapter, JOINBSS_RPT_EID, sizeof(JoinBssRptParm), (u8 *)&JoinBssRptParm); + +_func_exit_; +} + +#ifdef CONFIG_P2P_PS +void rtl8192c_set_p2p_ctw_period_cmd(_adapter* padapter, u8 ctwindow) +{ + struct P2P_PS_CTWPeriod_t p2p_ps_ctw; + + p2p_ps_ctw.CTWPeriod = ctwindow; + + rtl8192c_FillH2CCmd(padapter, P2P_PS_CTW_CMD_EID, 1, (u8 *)(&p2p_ps_ctw)); + +} + +void rtl8192c_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + +_func_enter_; + + switch(p2p_ps_state) + { + case P2P_PS_DISABLE: + DBG_8192C("P2P_PS_DISABLE \n"); + _rtw_memset(p2p_ps_offload, 0 ,1); + break; + case P2P_PS_ENABLE: + DBG_8192C("P2P_PS_ENABLE \n"); + // update CTWindow value. + if( pwdinfo->ctwindow > 0 ) + { + p2p_ps_offload->CTWindow_En = 1; + ctwindow = pwdinfo->ctwindow; + if(IS_HARDWARE_TYPE_8723A(padapter)) + { + //rtw_write16(padapter, REG_ATIMWND, ctwindow); + } + else + { + rtl8192c_set_p2p_ctw_period_cmd(padapter, ctwindow); + } + } + + // hw only support 2 set of NoA + for( i=0 ; inoa_num ; i++) + { + // To control the register setting for which NOA + rtw_write8(padapter, 0x5CF, (i << 4)); + if(i == 0) + p2p_ps_offload->NoA0_En = 1; + else + p2p_ps_offload->NoA1_En = 1; + + // config P2P NoA Descriptor Register + rtw_write32(padapter, 0x5E0, pwdinfo->noa_duration[i]); + + rtw_write32(padapter, 0x5E4, pwdinfo->noa_interval[i]); + + //Get Current TSF value + tsf_low = rtw_read32(padapter, REG_TSFTR); + + start_time = pwdinfo->noa_start_time[i]; + if(pwdinfo->noa_count[i] != 1) + { + while( start_time <= (tsf_low+(50*1024) ) ) + { + start_time += pwdinfo->noa_interval[i]; + if(pwdinfo->noa_count[i] != 255) + pwdinfo->noa_count[i]--; + } + } + //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,start_time); + rtw_write32(padapter, 0x5E8, start_time); + + rtw_write8(padapter, 0x5EC, pwdinfo->noa_count[i]); + } + + if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) ) + { + // rst p2p circuit + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->Offload_En = 1; + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + p2p_ps_offload->role= 1; + p2p_ps_offload->AllStaSleep = 0; + } + else + { + p2p_ps_offload->role= 0; + } + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + DBG_8192C("P2P_PS_SCAN \n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + DBG_8192C("P2P_PS_SCAN_DONE \n"); + p2p_ps_offload->discovery = 0; + pwdinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8192c_FillH2CCmd(padapter, P2P_PS_OFFLOAD_EID, 1, (u8 *)p2p_ps_offload); + +_func_exit_; + +} +#endif // CONFIG_P2P_PS + +#ifdef CONFIG_IOL +#include +int rtl8192c_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms) +{ + IO_OFFLOAD_LOC IoOffloadLoc; + u32 start_time = rtw_get_current_time(); + u32 passing_time_ms; + u8 polling_ret; + int ret = _FAIL; + + if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) + goto exit; + + dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms); + + IoOffloadLoc.LocCmd = 0; + if(_SUCCESS != rtl8192c_FillH2CCmd(adapter, H2C_92C_IO_OFFLOAD, sizeof(IO_OFFLOAD_LOC), (u8 *)&IoOffloadLoc)) + goto exit; + + //polling if the IO offloading is done + while( (passing_time_ms=rtw_get_passing_time_ms(start_time)) <= max_wating_ms) { + #if 0 //C2H + if(0xff == rtw_read8(adapter, REG_C2HEVT_CLEAR)) + break; + #else// 0x1c3 + if(0x00 != (polling_ret=rtw_read8(adapter, 0x1c3))) + break; + #endif + rtw_msleep_os(5); + } + #if 0 //debug + DBG_871X("IOL %s, polling_ret:0x%02x, 0x1c0=0x%08x, 0x1c4=0x%08x, 0x1cc=0x%08x, 0x1e8=0x%08x, 0x130=0x%08x, 0x134=0x%08x\n" + , polling_ret==0xff?"success":"error" + , polling_ret + , rtw_read32(adapter, 0x1c0) + , rtw_read32(adapter, 0x1c4) + , rtw_read32(adapter, 0x1cc) + , rtw_read32(adapter, 0x1e8) + , rtw_read32(adapter, 0x130) + , rtw_read32(adapter, 0x134) + ); + rtw_write32(adapter, 0x1c0, 0x0); + #endif + + if(polling_ret == 0xff) + ret =_SUCCESS; + else { + DBG_871X("IOL %s, polling_ret:0x%02x\n" + //", 0x1c0=0x%08x, 0x1c4=0x%08x, 0x1cc=0x%08x, 0x1e8=0x%08x, 0x130=0x%08x, 0x134=0x%08x\n" + , polling_ret==0xff?"success":"error" + , polling_ret + //, rtw_read32(adapter, 0x1c0) + //, rtw_read32(adapter, 0x1c4) + //, rtw_read32(adapter, 0x1cc) + //, rtw_read32(adapter, 0x1e8) + //, rtw_read32(adapter, 0x130) + //, rtw_read32(adapter, 0x134) + ); + #if 0 //debug + rtw_write16(adapter, 0x1c4, 0x0000); + rtw_msleep_os(10); + DBG_871X("after reset, 0x1c4=0x%08x\n", rtw_read32(adapter, 0x1c4)); + #endif + + } + + { + #if 0 //C2H + u32 c2h_evt; + int i; + c2h_evt = rtw_read32(adapter, REG_C2HEVT_MSG_NORMAL); + DBG_871X("%s io-offloading complete, in %ums: 0x%08x\n", __FUNCTION__, passing_time_ms, c2h_evt); + rtw_write8(adapter, REG_C2HEVT_CLEAR, 0x0); + #else// 0x1c3 + DBG_871X("IOL %s complete in %ums\n", __FUNCTION__, passing_time_ms); + rtw_write8(adapter, 0x1c3, 0x0); + #endif + } + +exit: + return ret; + +} +#endif //CONFIG_IOL + + +#ifdef CONFIG_BEACON_DISABLE_OFFLOAD +/* + rtl8192c_dis_beacon_fun_cmd() + This function shall only be called by PORT1. + PORT0's beacon function can't be disabled, because it's used by RA function in FW/HW. + + // Still has the REG_BCN_CTRL_1 modified by unknowned party issue in case of Primary Interface + PORT1 combination. +*/ +u8 rtl8192c_dis_beacon_fun_cmd(_adapter* padapter) +{ + u8 buf[2]; + u8 res=_SUCCESS; + +_func_enter_; + + _rtw_memset(buf, 0, sizeof(buf)); + + if (padapter->iface_type == IFACE_PORT0) { + //buf[0] = 0x1; + DBG_871X("%s(): ERROR! padapter->iface_type = %d\n", __FUNCTION__, padapter->iface_type); + return _FAIL; + } else + buf[1] = 0x1; + + rtl8192c_FillH2CCmd(padapter, H2C_92C_DISABLE_BCN_FUNC, 2, buf); + +_func_exit_; + + return res; + +} +#endif // CONFIG_BEACON_DISABLE_OFFLOAD + + +#ifdef CONFIG_TSF_RESET_OFFLOAD +/* + ask FW to Reset sync register at Beacon early interrupt +*/ +u8 rtl8192c_reset_tsf(_adapter *padapter, u8 reset_port ) +{ + u8 buf[2]; + u8 res=_SUCCESS; + +_func_enter_; + if (IFACE_PORT0==reset_port) { + buf[0] = 0x1; buf[1] = 0; + + } else{ + buf[0] = 0x0; buf[1] = 0x1; + } + rtl8192c_FillH2CCmd(padapter, H2C_92C_RESET_TSF, 2, buf); +_func_exit_; + + return res; +} + +int reset_tsf(PADAPTER Adapter, u8 reset_port ) +{ + u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0; + u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ? + REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1; + + rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */ + reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt); + rtl8192c_reset_tsf(Adapter, reset_port); + + while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) { + rtw_msleep_os(100); + loop_cnt++; + reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt); + } + + return(loop_cnt >= 10) ? _FAIL : _TRUE; +} + + +#endif // CONFIG_TSF_RESET_OFFLOAD + +#ifdef CONFIG_WOWLAN + +void rtl8192c_set_wowlan_cmd(_adapter* padapter) +{ + u8 res=_SUCCESS; + SETWOWLAN_PARM pwowlan_parm; + struct pwrctrl_priv *pwrpriv=&padapter->pwrctrlpriv; + +_func_enter_; + + pwowlan_parm.mode =0; + pwowlan_parm.gpio_index=0; + pwowlan_parm.gpio_duration=0; + pwowlan_parm.second_mode =0; + pwowlan_parm.reserve=0; + + if(pwrpriv->wowlan_mode ==_TRUE){ + pwowlan_parm.mode |=FW_WOWLAN_FUN_EN; + //printk("\n %s 1.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode ); + if(pwrpriv->wowlan_pattern ==_TRUE){ + pwowlan_parm.mode |= FW_WOWLAN_PATTERN_MATCH; + //printk("\n %s 2.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode ); + } + if(pwrpriv->wowlan_magic ==_TRUE){ + pwowlan_parm.mode |=FW_WOWLAN_MAGIC_PKT; + //printk("\n %s 3.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode ); + } + if(pwrpriv->wowlan_unicast ==_TRUE){ + pwowlan_parm.mode |=FW_WOWLAN_UNICAST; + //printk("\n %s 4.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode ); + } + //WOWLAN_GPIO_ACTIVE means GPIO high active + //pwowlan_parm.mode |=FW_WOWLAN_GPIO_ACTIVE; + pwowlan_parm.mode |=FW_WOWLAN_REKEY_WAKEUP; + pwowlan_parm.mode |=FW_WOWLAN_DEAUTH_WAKEUP; + + rtl8192c_set_FwJoinBssReport_cmd( padapter, 1); + + //GPIO3 + pwowlan_parm.gpio_index=3; + + //duration unit is 64us + pwowlan_parm.gpio_duration=0xff; + // + pwowlan_parm.second_mode|=FW_WOWLAN_GPIO_WAKEUP_EN; + //printk("\n %s 5.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode ); + { u8 *ptr=(u8 *)&pwowlan_parm; + printk("\n %s H2C_WO_WLAN=%x %02x:%02x:%02x:%02x:%02x \n",__FUNCTION__,H2C_WO_WLAN_CMD,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4] ); + } + rtl8192c_FillH2CCmd(padapter, H2C_WO_WLAN_CMD, 4, (u8 *)&pwowlan_parm); + + //keep alive period = 3 * 10 BCN interval + pwowlan_parm.mode =3; + pwowlan_parm.gpio_index=3; + rtl8192c_FillH2CCmd(padapter, KEEP_ALIVE_CONTROL_CMD, 2, (u8 *)&pwowlan_parm); + printk("%s after KEEP_ALIVE_CONTROL_CMD register 0x81=%x \n",__FUNCTION__,rtw_read8(padapter, 0x81)); + + pwowlan_parm.mode =1; + pwowlan_parm.gpio_index=0; + pwowlan_parm.gpio_duration=0; + rtl8192c_FillH2CCmd(padapter, DISCONNECT_DECISION_CTRL_CMD, 3, (u8 *)&pwowlan_parm); + printk("%s after DISCONNECT_DECISION_CTRL_CMD register 0x81=%x \n",__FUNCTION__,rtw_read8(padapter, 0x81)); + + //enable GPIO wakeup + pwowlan_parm.mode =1; + pwowlan_parm.gpio_index=0; + pwowlan_parm.gpio_duration=0; + rtl8192c_FillH2CCmd(padapter, REMOTE_WAKE_CTRL_CMD, 3, (u8 *)&pwowlan_parm); + } + else + rtl8192c_FillH2CCmd(padapter, H2C_WO_WLAN_CMD, 3, (u8 *)&pwowlan_parm); + + +_func_exit_; + + return ; + +} + +#endif //CONFIG_WOWLAN + + + + + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c new file mode 100755 index 00000000..6e5634cf --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c @@ -0,0 +1,5056 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +//============================================================ +// Description: +// +// This file is for 92CE/92CU dynamic mechanism only +// +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include +#include +#include +#include + +#include +#include "../dm.h" +#ifdef CONFIG_INTEL_PROXIM +#include "../proxim/intel_proxim.h" +#endif +//============================================================ +// Global var +//============================================================ +static u32 EDCAParam[maxAP][3] = +{ // UL DL + {0x5ea322, 0x00a630, 0x00a44f}, //atheros AP + {0x5ea32b, 0x5ea42b, 0x5e4322}, //broadcom AP + {0x3ea430, 0x00a630, 0x3ea44f}, //cisco AP + {0x5ea44f, 0x00a44f, 0x5ea42b}, //marvell AP + {0x5ea422, 0x00a44f, 0x00a44f}, //ralink AP + //{0x5ea44f, 0x5ea44f, 0x5ea44f}, //realtek AP + {0xa44f, 0x5ea44f, 0x5e431c}, //realtek AP + {0x5ea42b, 0xa630, 0x5e431c}, //airgocap AP + {0x5ea42b, 0x5ea42b, 0x5ea42b}, //unknown AP +// {0x5e4322, 0x00a44f, 0x5ea44f}, //unknown AP +}; + + +/*----------------------------------------------------------------------------- + * Function: dm_DIGInit() + * + * Overview: Set DIG scheme init value. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * + *---------------------------------------------------------------------------*/ +static void dm_DIGInit( + IN PADAPTER pAdapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + + pDigTable->Dig_Enable_Flag = _TRUE; + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX; + + pDigTable->CurIGValue = 0x20; + pDigTable->PreIGValue = 0x0; + + pDigTable->CurSTAConnectState = pDigTable->PreSTAConnectState = DIG_STA_DISCONNECT; + pDigTable->CurMultiSTAConnectState = DIG_MultiSTA_DISCONNECT; + + pDigTable->RssiLowThresh = DM_DIG_THRESH_LOW; + pDigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; + + pDigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; + pDigTable->FAHighThresh = DM_FALSEALARM_THRESH_HIGH; + + + pDigTable->rx_gain_range_max = DM_DIG_MAX; + pDigTable->rx_gain_range_min = DM_DIG_MIN; + pDigTable->rx_gain_range_min_nolink = 0; + + pDigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; + pDigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; + pDigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; + + pDigTable->PreCCKPDState = CCK_PD_STAGE_MAX; + pDigTable->CurCCKPDState = CCK_PD_STAGE_LowRssi; + + pDigTable->ForbiddenIGI = DM_DIG_MIN; + pDigTable->LargeFAHit = 0; + pDigTable->Recover_cnt = 0; + pdmpriv->DIG_Dynamic_MIN = 0x25; //for FUNAI_TV +} + + +static u8 dm_initial_gain_MinPWDB( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + int Rssi_val_min = 0; + + if((pDigTable->CurMultiSTAConnectState == DIG_MultiSTA_CONNECT) && + (pDigTable->CurSTAConnectState == DIG_STA_CONNECT) ) + { + if(pdmpriv->EntryMinUndecoratedSmoothedPWDB != 0) +#ifdef CONFIG_CONCURRENT_MODE + Rssi_val_min = (pdmpriv->UndecoratedSmoothedPWDB+pdmpriv->EntryMinUndecoratedSmoothedPWDB)/2; +#else + Rssi_val_min = (pdmpriv->EntryMinUndecoratedSmoothedPWDB > pdmpriv->UndecoratedSmoothedPWDB)? + pdmpriv->UndecoratedSmoothedPWDB:pdmpriv->EntryMinUndecoratedSmoothedPWDB; +#endif //CONFIG_CONCURRENT_MODE + else + Rssi_val_min = pdmpriv->UndecoratedSmoothedPWDB; + } + else if(pDigTable->CurSTAConnectState == DIG_STA_CONNECT || + pDigTable->CurSTAConnectState == DIG_STA_BEFORE_CONNECT) + Rssi_val_min = pdmpriv->UndecoratedSmoothedPWDB; + else if(pDigTable->CurMultiSTAConnectState == DIG_MultiSTA_CONNECT) + Rssi_val_min = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + + //printk("%s CurMultiSTAConnectState(0x%02x) UndecoratedSmoothedPWDB(%d),EntryMinUndecoratedSmoothedPWDB(%d)\n" + //,__FUNCTION__,pDigTable->CurSTAConnectState, + //pdmpriv->UndecoratedSmoothedPWDB,pdmpriv->EntryMinUndecoratedSmoothedPWDB); + + return (u8)Rssi_val_min; +} + + +static VOID +dm_FalseAlarmCounterStatistics( + IN PADAPTER Adapter + ) +{ + u32 ret_value; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pdmpriv->FalseAlmCnt); +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; +#endif //CONFIG_CONCURRENT_MODE + + ret_value = PHY_QueryBBReg(Adapter, rOFDM_PHYCounter1, bMaskDWord); + FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); + + ret_value = PHY_QueryBBReg(Adapter, rOFDM_PHYCounter2, bMaskDWord); + FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); + FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); + ret_value = PHY_QueryBBReg(Adapter, rOFDM_PHYCounter3, bMaskDWord); + FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); + ret_value = PHY_QueryBBReg(Adapter, rOFDM0_FrameSync, bMaskDWord); + FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); + FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); + + 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; + + + //hold cck counter + PHY_SetBBReg(Adapter, rCCK0_FalseAlarmReport, BIT(14), 1); + + ret_value = PHY_QueryBBReg(Adapter, rCCK0_FACounterLower, bMaskByte0); + FalseAlmCnt->Cnt_Cck_fail = ret_value; + + ret_value = PHY_QueryBBReg(Adapter, rCCK0_FACounterUpper, bMaskByte3); + FalseAlmCnt->Cnt_Cck_fail += (ret_value& 0xff)<<8; + + FalseAlmCnt->Cnt_all = ( FalseAlmCnt->Cnt_Parity_Fail + + FalseAlmCnt->Cnt_Rate_Illegal + + FalseAlmCnt->Cnt_Crc8_fail + + FalseAlmCnt->Cnt_Mcs_fail + + FalseAlmCnt->Cnt_Cck_fail); + + Adapter->recvpriv.FalseAlmCnt_all = FalseAlmCnt->Cnt_all; +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter) + pbuddy_adapter->recvpriv.FalseAlmCnt_all = FalseAlmCnt->Cnt_all; +#endif //CONFIG_CONCURRENT_MODE + + //reset false alarm counter registers + PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0x08000000, 1); + PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0x08000000, 0); + //reset cck counter + PHY_SetBBReg(Adapter, rCCK0_FalseAlarmReport, 0x0000c000, 0); + //enable cck counter + PHY_SetBBReg(Adapter, rCCK0_FalseAlarmReport, 0x0000c000, 2); + + //RT_TRACE( COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %ld, Cnt_Rate_Illegal = %ld, Cnt_Crc8_fail = %ld, Cnt_Mcs_fail = %ld\n", + // FalseAlmCnt->Cnt_Parity_Fail, FalseAlmCnt->Cnt_Rate_Illegal, FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail) ); + //RT_TRACE( COMP_DIG, DBG_LOUD, ("Cnt_Ofdm_fail = %ld, Cnt_Cck_fail = %ld, Cnt_all = %ld\n", + // FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_all) ); + //RT_TRACE( COMP_DIG, DBG_LOUD, ("Cnt_Ofdm_fail = %ld, Cnt_Cck_fail = %ld, Cnt_all = %ld\n", + // FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_all) ); +} + + +static VOID +DM_Write_DIG( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(pAdapter)) + { + PADAPTER pbuddy_adapter = pAdapter->pbuddy_adapter; + PHAL_DATA_TYPE pbuddy_HalData = GET_HAL_DATA(pbuddy_adapter); + struct dm_priv *pbuddy_dmpriv = &pbuddy_HalData->dmpriv; + DIG_T *pbuddy_DigTable = &pbuddy_dmpriv->DM_DigTable; + + //sync IGValue + pbuddy_DigTable->PreIGValue = pDigTable->PreIGValue; + pbuddy_DigTable->CurIGValue = pDigTable->CurIGValue; + } +#endif //CONFIG_CONCURRENT_MODE + + + //RT_TRACE( COMP_DIG, DBG_LOUD, ("CurIGValue = 0x%lx, PreIGValue = 0x%lx, BackoffVal = %d\n", + // DM_DigTable.CurIGValue, DM_DigTable.PreIGValue, DM_DigTable.BackoffVal)); + + if (pDigTable->Dig_Enable_Flag == _FALSE) + { + //RT_TRACE( COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); + pDigTable->PreIGValue = 0x17; + return; + } + + if( (pDigTable->PreIGValue != pDigTable->CurIGValue) || ( pAdapter->bForceWriteInitGain ) ) + { + // Set initial gain. + //PHY_SetBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0, pDigTable->CurIGValue); + //PHY_SetBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0, pDigTable->CurIGValue); + //printk("%s DIG(0x%02x)\n",__FUNCTION__,pDigTable->CurIGValue); + +#if defined CONFIG_WIDI_DIG_3E && defined CONFIG_INTEL_WIDI + if( pAdapter->mlmepriv.widi_enable == _TRUE ) + { + PHY_SetBBReg(pAdapter, rOFDM0_XAAGCCore1, 0x7f, 0x3e); + PHY_SetBBReg(pAdapter, rOFDM0_XBAGCCore1, 0x7f, 0x3e); + } + else +#endif //defined CONFIG_WIDI_DIG_3E && defined CONFIG_INTEL_WIDI + { + PHY_SetBBReg(pAdapter, rOFDM0_XAAGCCore1, 0x7f, pDigTable->CurIGValue); + PHY_SetBBReg(pAdapter, rOFDM0_XBAGCCore1, 0x7f, pDigTable->CurIGValue); + } + pDigTable->PreIGValue = pDigTable->CurIGValue; + } +} + + +static VOID +dm_CtrlInitGainByFA( + IN PADAPTER pAdapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pdmpriv->FalseAlmCnt); + + u8 value_IGI = pDigTable->CurIGValue; + + if(FalseAlmCnt->Cnt_all < DM_DIG_FA_TH0) + value_IGI --; + else if(FalseAlmCnt->Cnt_all < DM_DIG_FA_TH1) + value_IGI += 0; + else if(FalseAlmCnt->Cnt_all < DM_DIG_FA_TH2) + value_IGI ++; + else if(FalseAlmCnt->Cnt_all >= DM_DIG_FA_TH2) + value_IGI +=2; + + if(value_IGI > DM_DIG_FA_UPPER) + value_IGI = DM_DIG_FA_UPPER; + if(value_IGI < DM_DIG_FA_LOWER) + value_IGI = DM_DIG_FA_LOWER; + + if(FalseAlmCnt->Cnt_all > 10000) + value_IGI = DM_DIG_FA_UPPER; + + pDigTable->CurIGValue = value_IGI; + + DM_Write_DIG(pAdapter); + +} + +#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV +VOID dm_CtrlInitGainByRssi( IN PADAPTER pAdapter) +{ + + u32 isBT; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pdmpriv->FalseAlmCnt); +#ifdef CONFIG_DM_ADAPTIVITY + u8 Adap_IGI_Upper = pdmpriv->IGI_target + 30 + (u8) pdmpriv->TH_L2H_ini -(u8) pdmpriv->TH_EDCCA_HL_diff; +#endif + + //modify DIG upper bound + if((pDigTable->Rssi_val_min + 20) > DM_DIG_MAX ) + pDigTable->rx_gain_range_max = DM_DIG_MAX; + else + pDigTable->rx_gain_range_max = pDigTable->Rssi_val_min + 20; + + //modify DIG lower bound + if((FalseAlmCnt->Cnt_all > 500)&&(pdmpriv->DIG_Dynamic_MIN < 0x25)) + pdmpriv->DIG_Dynamic_MIN++; + if((FalseAlmCnt->Cnt_all < 500)&&(pdmpriv->DIG_Dynamic_MIN > DM_DIG_MIN)) + pdmpriv->DIG_Dynamic_MIN--; + if((pDigTable->Rssi_val_min < 8) && (pdmpriv->DIG_Dynamic_MIN > DM_DIG_MIN)) + pdmpriv->DIG_Dynamic_MIN--; + + //modify DIG lower bound, deal with abnorally large false alarm + if(FalseAlmCnt->Cnt_all > 10000) + { + //RT_TRACE(COMP_DIG, DBG_LOUD, ("dm_DIG(): Abnornally false alarm case. \n")); + pDigTable->LargeFAHit++; + if(pDigTable->ForbiddenIGI < pDigTable->CurIGValue) + { + pDigTable->ForbiddenIGI = pDigTable->CurIGValue; + pDigTable->LargeFAHit = 1; + } + if(pDigTable->LargeFAHit >= 3) + { + if((pDigTable->ForbiddenIGI+1) >pDigTable->rx_gain_range_max) + pDigTable->rx_gain_range_min = pDigTable->rx_gain_range_max; + else + pDigTable->rx_gain_range_min = (pDigTable->ForbiddenIGI + 1); + pDigTable->Recover_cnt = 3600; //3600=2hr + } + } + else + { + //Recovery mechanism for IGI lower bound + if(pDigTable->Recover_cnt != 0){ + pDigTable->Recover_cnt --; + } + else + { + if(pDigTable->LargeFAHit == 0 ) + { + if((pDigTable->ForbiddenIGI -1) < pdmpriv->DIG_Dynamic_MIN) //DM_DIG_MIN) + { + pDigTable->ForbiddenIGI = pdmpriv->DIG_Dynamic_MIN; //DM_DIG_MIN; + pDigTable->rx_gain_range_min = pdmpriv->DIG_Dynamic_MIN; //DM_DIG_MIN; + } + else + { + pDigTable->ForbiddenIGI --; + pDigTable->rx_gain_range_min = (pDigTable->ForbiddenIGI + 1); + } + } + else if(pDigTable->LargeFAHit == 3 ) + { + pDigTable->LargeFAHit = 0; + } + } + } + #ifdef CONFIG_USB_HCI + if(FalseAlmCnt->Cnt_all < 250) + { +#endif + //DBG_8192C("===> dm_CtrlInitGainByRssi, Enter DIG by SS mode\n"); + + isBT = rtw_read8(pAdapter, 0x4fd) & 0x01; + + if(!isBT){ + + if(FalseAlmCnt->Cnt_all > pDigTable->FAHighThresh) + { + if((pDigTable->BackoffVal -2) < pDigTable->BackoffVal_range_min) + pDigTable->BackoffVal = pDigTable->BackoffVal_range_min; + else + pDigTable->BackoffVal -= 2; + } + else if(FalseAlmCnt->Cnt_all < pDigTable->FALowThresh) + { + if((pDigTable->BackoffVal+2) > pDigTable->BackoffVal_range_max) + pDigTable->BackoffVal = pDigTable->BackoffVal_range_max; + else + pDigTable->BackoffVal +=2; + } + } + else + pDigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; + + pDigTable->CurIGValue = pDigTable->Rssi_val_min+10-pDigTable->BackoffVal; + + //DBG_8192C("Rssi_val_min = %x BackoffVal %x\n",pDigTable->Rssi_val_min, pDigTable->BackoffVal); +#ifdef CONFIG_USB_HCI + } + else + { + //DBG_8192C("===> dm_CtrlInitGainByRssi, Enter DIG by FA mode\n"); + //DBG_8192C("RSSI = 0x%x", pDigTable->Rssi_val_min); + + //Adjust initial gain by false alarm + if(FalseAlmCnt->Cnt_all > 1000) + pDigTable->CurIGValue = pDigTable ->PreIGValue+2; + else if (FalseAlmCnt->Cnt_all > 750) + pDigTable->CurIGValue = pDigTable->PreIGValue+1; + else if(FalseAlmCnt->Cnt_all < 500) + pDigTable->CurIGValue = pDigTable->PreIGValue-1; + } +#endif + + //Check initial gain by upper/lower bound + if(pDigTable->CurIGValue >pDigTable->rx_gain_range_max) + pDigTable->CurIGValue = pDigTable->rx_gain_range_max; + + if(pDigTable->CurIGValue < pDigTable->rx_gain_range_min) + pDigTable->CurIGValue = pDigTable->rx_gain_range_min; + +#ifdef CONFIG_DM_ADAPTIVITY + if(pdmpriv->DMFlag & DYNAMIC_FUNC_ADAPTIVITY) + { + if(pDigTable->CurIGValue > Adap_IGI_Upper) + pDigTable->CurIGValue = Adap_IGI_Upper; + + if(pdmpriv->IGI_LowerBound != 0) + { + if(pDigTable->CurIGValue < pdmpriv->IGI_LowerBound) + pDigTable->CurIGValue = pdmpriv->IGI_LowerBound; + } + LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT": pdmpriv->IGI_LowerBound = %d\n", + FUNC_ADPT_ARG(pAdapter), pdmpriv->IGI_LowerBound); + } +#endif /* CONFIG_DM_ADAPTIVITY */ + + //printk("%s => rx_gain_range_max(0x%02x) rx_gain_range_min(0x%02x)\n",__FUNCTION__, + // pDigTable->rx_gain_range_max,pDigTable->rx_gain_range_min); + //printk("%s CurIGValue(0x%02x) <====\n",__FUNCTION__,pDigTable->CurIGValue ); + + DM_Write_DIG(pAdapter); + +} +#else +static VOID dm_CtrlInitGainByRssi(IN PADAPTER pAdapter) +{ + u32 isBT; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pdmpriv->FalseAlmCnt); + u8 RSSI_tmp = dm_initial_gain_MinPWDB(pAdapter); +#ifdef CONFIG_DM_ADAPTIVITY + u8 Adap_IGI_Upper = pdmpriv->IGI_target + 30 + (u8) pdmpriv->TH_L2H_ini -(u8) pdmpriv->TH_EDCCA_HL_diff; +#endif + + //modify DIG upper bound + if((pDigTable->Rssi_val_min + 20) > DM_DIG_MAX ) + pDigTable->rx_gain_range_max = DM_DIG_MAX; + else + pDigTable->rx_gain_range_max = pDigTable->Rssi_val_min + 20; + //printk("%s Rssi_val_min(0x%02x),rx_gain_range_max(0x%02x)\n",__FUNCTION__,pDigTable->Rssi_val_min,pDigTable->rx_gain_range_max); + //modify DIG lower bound, deal with abnorally large false alarm + if(FalseAlmCnt->Cnt_all > 10000) + { + //RT_TRACE(COMP_DIG, DBG_LOUD, ("dm_DIG(): Abnornally false alarm case. \n")); + + pDigTable->LargeFAHit++; + if(pDigTable->ForbiddenIGI < pDigTable->CurIGValue) + { + pDigTable->ForbiddenIGI = pDigTable->CurIGValue; + pDigTable->LargeFAHit = 1; + } + + if(pDigTable->LargeFAHit >= 3) + { + if((pDigTable->ForbiddenIGI+1) > pDigTable->rx_gain_range_max) + pDigTable->rx_gain_range_min = pDigTable->rx_gain_range_max; + else + pDigTable->rx_gain_range_min = (pDigTable->ForbiddenIGI + 1); + pDigTable->Recover_cnt = 3600; //3600=2hr + } + } + else + { + //Recovery mechanism for IGI lower bound + if(pDigTable->Recover_cnt != 0) + pDigTable->Recover_cnt --; + else + { + if(pDigTable->LargeFAHit == 0 ) + { + if((pDigTable->ForbiddenIGI -1) < DM_DIG_MIN) + { + pDigTable->ForbiddenIGI = DM_DIG_MIN; + pDigTable->rx_gain_range_min = DM_DIG_MIN; + } + else + { + pDigTable->ForbiddenIGI --; + pDigTable->rx_gain_range_min = (pDigTable->ForbiddenIGI + 1); + } + } + else if(pDigTable->LargeFAHit == 3 ) + { + pDigTable->LargeFAHit = 0; + } + } + } + + //RT_TRACE(COMP_DIG, DBG_LOUD, ("DM_DigTable.ForbiddenIGI = 0x%x, DM_DigTable.LargeFAHit = 0x%x\n",pDigTable->ForbiddenIGI, pDigTable->LargeFAHit)); + //RT_TRACE(COMP_DIG, DBG_LOUD, ("DM_DigTable.rx_gain_range_max = 0x%x, DM_DigTable.rx_gain_range_min = 0x%x\n",pDigTable->rx_gain_range_max, pDigTable->rx_gain_range_min)); + +#ifdef CONFIG_USB_HCI + if(FalseAlmCnt->Cnt_all < 250) + { +#endif + //DBG_8192C("===> dm_CtrlInitGainByRssi, Enter DIG by SS mode\n"); + + isBT = rtw_read8(pAdapter, 0x4fd) & 0x01; + + if(!isBT){ + + if(FalseAlmCnt->Cnt_all > pDigTable->FAHighThresh) + { + if((pDigTable->BackoffVal -2) < pDigTable->BackoffVal_range_min) + pDigTable->BackoffVal = pDigTable->BackoffVal_range_min; + else + pDigTable->BackoffVal -= 2; + } + else if(FalseAlmCnt->Cnt_all < pDigTable->FALowThresh) + { + if((pDigTable->BackoffVal+2) > pDigTable->BackoffVal_range_max) + pDigTable->BackoffVal = pDigTable->BackoffVal_range_max; + else + pDigTable->BackoffVal +=2; + } + } + else + pDigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; + + pDigTable->CurIGValue = pDigTable->Rssi_val_min+10-pDigTable->BackoffVal; + + //DBG_8192C("Rssi_val_min = %x BackoffVal %x\n",pDigTable->Rssi_val_min, pDigTable->BackoffVal); +#ifdef CONFIG_USB_HCI + } + else + { + //DBG_8192C("===> dm_CtrlInitGainByRssi, Enter DIG by FA mode\n"); + //DBG_8192C("RSSI = 0x%x", pDigTable->Rssi_val_min); + + //Adjust initial gain by false alarm + if(FalseAlmCnt->Cnt_all > 1000) + pDigTable->CurIGValue = pDigTable ->PreIGValue+2; + else if (FalseAlmCnt->Cnt_all > 750) + pDigTable->CurIGValue = pDigTable->PreIGValue+1; + else if(FalseAlmCnt->Cnt_all < 500) + pDigTable->CurIGValue = pDigTable->PreIGValue-1; + } +#endif + + if(RSSI_tmp <= DM_DIG_MIN) + pDigTable->rx_gain_range_min = DM_DIG_MIN; + else if(RSSI_tmp >= DM_DIG_MAX) + pDigTable->rx_gain_range_min = DM_DIG_MAX; + else + pDigTable->rx_gain_range_min = RSSI_tmp; + + + //Check initial gain by upper/lower bound + if(pDigTable->CurIGValue >pDigTable->rx_gain_range_max) + pDigTable->CurIGValue = pDigTable->rx_gain_range_max; + + if(pDigTable->CurIGValue < pDigTable->rx_gain_range_min) + pDigTable->CurIGValue = pDigTable->rx_gain_range_min; + +#ifdef CONFIG_DM_ADAPTIVITY + if(pdmpriv->DMFlag & DYNAMIC_FUNC_ADAPTIVITY) + { + if(pDigTable->CurIGValue > Adap_IGI_Upper) + pDigTable->CurIGValue = Adap_IGI_Upper; + + if(pdmpriv->IGI_LowerBound != 0) + { + if(pDigTable->CurIGValue < pdmpriv->IGI_LowerBound) + pDigTable->CurIGValue = pdmpriv->IGI_LowerBound; + } + LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT": pdmpriv->IGI_LowerBound = %d\n", + FUNC_ADPT_ARG(pAdapter), pdmpriv->IGI_LowerBound); + } +#endif /* CONFIG_DM_ADAPTIVITY */ + + //printk("%s => rx_gain_range_max(0x%02x) rx_gain_range_min(0x%02x)\n",__FUNCTION__, + // pDigTable->rx_gain_range_max,pDigTable->rx_gain_range_min); + //printk("%s CurIGValue(0x%02x) <====\n",__FUNCTION__,pDigTable->CurIGValue ); + + DM_Write_DIG(pAdapter); + +} +#endif + +static VOID +dm_initial_gain_Multi_STA( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &(pAdapter->mlmepriv); + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + int rssi_strength = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + BOOLEAN bMulti_STA = _FALSE; + +#ifdef CONFIG_CONCURRENT_MODE + //AP Mode + if(check_buddy_fwstate(pAdapter, WIFI_AP_STATE) == _TRUE && (rssi_strength !=0)) + { + bMulti_STA = _TRUE; + } + else if(pDigTable->CurMultiSTAConnectState == DIG_MultiSTA_CONNECT && rssi_strength==0) //STA+STA MODE + { + bMulti_STA = _TRUE; + rssi_strength = pdmpriv->UndecoratedSmoothedPWDB; + } +#endif //CONFIG_CONCURRENT_MODE + + + //ADHOC and AP Mode + if(check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + bMulti_STA = _TRUE; + } + + + if((bMulti_STA == _FALSE) + || (pDigTable->CurSTAConnectState == DIG_STA_DISCONNECT)) + { + pdmpriv->binitialized = _FALSE; + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX; + return; + } + else if(pdmpriv->binitialized == _FALSE) + { + pdmpriv->binitialized = _TRUE; + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_0; + pDigTable->CurIGValue = 0x20; + DM_Write_DIG(pAdapter); + } + + // Initial gain control by ap mode + if(pDigTable->CurMultiSTAConnectState == DIG_MultiSTA_CONNECT) + { + if ( (rssi_strength < pDigTable->RssiLowThresh) && + (pDigTable->Dig_Ext_Port_Stage != DIG_EXT_PORT_STAGE_1)) + { + // Set to dig value to 0x20 for Luke's opinion after disable dig + if(pDigTable->Dig_Ext_Port_Stage == DIG_EXT_PORT_STAGE_2) + { + pDigTable->CurIGValue = 0x20; + DM_Write_DIG(pAdapter); + } + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_1; + } + else if (rssi_strength > pDigTable->RssiHighThresh) + { + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_2; + dm_CtrlInitGainByFA(pAdapter); + } + } + else if(pDigTable->Dig_Ext_Port_Stage != DIG_EXT_PORT_STAGE_0) + { + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_0; + pDigTable->CurIGValue = 0x20; + DM_Write_DIG(pAdapter); + } + + //RT_TRACE( COMP_DIG, DBG_LOUD, ("CurMultiSTAConnectState = %x Dig_Ext_Port_Stage %x\n", + // DM_DigTable.CurMultiSTAConnectState, DM_DigTable.Dig_Ext_Port_Stage)); +} + +static VOID +dm_initial_gain_STA_beforelinked( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + PFALSE_ALARM_STATISTICS pFalseAlmCnt = &(pdmpriv->FalseAlmCnt); + + //CurrentIGI = pDM_DigTable->rx_gain_range_min;//pDM_DigTable->CurIGValue = pDM_DigTable->rx_gain_range_min + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): DIG BeforeLink\n")); + //2012.03.30 LukeLee: enable DIG before link but with very high thresholds + // Updated by Albert 2012/09/27 + // Copy the same rule from 8192du code. + if( pFalseAlmCnt->Cnt_all > 2000 ) + pDigTable->CurIGValue += 2; + else if ( ( pFalseAlmCnt->Cnt_all > 1000 ) && ( pFalseAlmCnt->Cnt_all <= 1000 ) ) + pDigTable->CurIGValue += 1; + else if(pFalseAlmCnt->Cnt_all < 500) + pDigTable->CurIGValue -= 1; + + //Check initial gain by upper/lower bound + if(pDigTable->CurIGValue >pDigTable->rx_gain_range_max) + pDigTable->CurIGValue = pDigTable->rx_gain_range_max; + + if(pDigTable->CurIGValue < pDigTable->rx_gain_range_min) + pDigTable->CurIGValue = pDigTable->rx_gain_range_min; + + printk("%s ==> FalseAlmCnt->Cnt_all:%d CurIGValue:0x%02x \n",__FUNCTION__,pFalseAlmCnt->Cnt_all ,pDigTable->CurIGValue); +} + +static VOID +dm_initial_gain_STA( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + //RT_TRACE( COMP_DIG, DBG_LOUD, ("PreSTAConnectState = %x, CurSTAConnectState = %x\n", + // DM_DigTable.PreSTAConnectState, DM_DigTable.CurSTAConnectState)); + + + if(pDigTable->PreSTAConnectState == pDigTable->CurSTAConnectState|| + pDigTable->CurSTAConnectState == DIG_STA_BEFORE_CONNECT || + pDigTable->CurSTAConnectState == DIG_STA_CONNECT) + { + // beforeconnect -> beforeconnect or connect -> connect + // (dis)connect -> beforeconnect + // disconnect -> connecct or beforeconnect -> connect + if(pDigTable->CurSTAConnectState != DIG_STA_DISCONNECT) + { + pDigTable->Rssi_val_min = dm_initial_gain_MinPWDB(pAdapter); + dm_CtrlInitGainByRssi(pAdapter); + } +#if 0 + else if((wdev_to_priv(pAdapter->rtw_wdev))->p2p_enabled == _TRUE + && pAdapter->wdinfo.driver_interface == DRIVER_CFG80211) + { + //pDigTable->CurIGValue = 0x30; + DM_Write_DIG(pAdapter); + } +#endif + else{ // pDigTable->CurSTAConnectState == DIG_STA_DISCONNECT + #ifdef CONFIG_BEFORE_LINKED_DIG + //printk("%s==> ##1 CurIGI(0x%02x),PreIGValue(0x%02x) \n",__FUNCTION__,pDigTable->CurIGValue,pDigTable->PreIGValue ); + dm_initial_gain_STA_beforelinked(pAdapter); + DM_Write_DIG(pAdapter); + #endif //CONFIG_BEFORE_LINKED_DIG + } + } + else + { + // connect -> disconnect or beforeconnect -> disconnect + pDigTable->Rssi_val_min = 0; + pDigTable->Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX; + pDigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; + pDigTable->CurIGValue = 0x20; + pDigTable->PreIGValue = 0; + #ifdef CONFIG_BEFORE_LINKED_DIG + //printk("%s==> ##2 CurIGI(0x%02x),PreIGValue(0x%02x) \n",__FUNCTION__,pDigTable->CurIGValue,pDigTable->PreIGValue ); + dm_initial_gain_STA_beforelinked(pAdapter); + #endif //CONFIG_BEFORE_LINKED_DIG + + + DM_Write_DIG(pAdapter); + } + +} + + +static void dm_CCK_PacketDetectionThresh( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PFALSE_ALARM_STATISTICS FalseAlmCnt = &(pdmpriv->FalseAlmCnt); + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + if(pDigTable->CurSTAConnectState == DIG_STA_CONNECT) + { + pDigTable->Rssi_val_min = dm_initial_gain_MinPWDB(pAdapter); + if(pDigTable->PreCCKPDState == CCK_PD_STAGE_LowRssi) + { + if(pDigTable->Rssi_val_min <= 25) + pDigTable->CurCCKPDState = CCK_PD_STAGE_LowRssi; + else + pDigTable->CurCCKPDState = CCK_PD_STAGE_HighRssi; + } + else{ + if(pDigTable->Rssi_val_min <= 20) + pDigTable->CurCCKPDState = CCK_PD_STAGE_LowRssi; + else + pDigTable->CurCCKPDState = CCK_PD_STAGE_HighRssi; + } + } + else + pDigTable->CurCCKPDState=CCK_PD_STAGE_MAX; + + if(pDigTable->PreCCKPDState != pDigTable->CurCCKPDState) + { + if((pDigTable->CurCCKPDState == CCK_PD_STAGE_LowRssi)|| + (pDigTable->CurCCKPDState == CCK_PD_STAGE_MAX)) + { + PHY_SetBBReg(pAdapter, rCCK0_CCA, bMaskByte2, 0x83); + + //PHY_SetBBReg(pAdapter, rCCK0_System, bMaskByte1, 0x40); + //if(IS_92C_SERIAL(pHalData->VersionID)) + //PHY_SetBBReg(pAdapter, rCCK0_FalseAlarmReport , bMaskByte2, 0xd7); + } + else + { + PHY_SetBBReg(pAdapter, rCCK0_CCA, bMaskByte2, 0xcd); + //PHY_SetBBReg(pAdapter,rCCK0_System, bMaskByte1, 0x47); + //if(IS_92C_SERIAL(pHalData->VersionID)) + //PHY_SetBBReg(pAdapter, rCCK0_FalseAlarmReport , bMaskByte2, 0xd3); + } + + pDigTable->PreCCKPDState = pDigTable->CurCCKPDState; + } + + //RT_TRACE( COMP_DIG, DBG_LOUD, ("CCKPDStage=%x\n",pDigTable->CurCCKPDState)); + //RT_TRACE( COMP_DIG, DBG_LOUD, ("is92C=%x\n",IS_92C_SERIAL(pHalData->VersionID))); + +} + + +static void +dm_CtrlInitGainByTwoPort( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &(pAdapter->mlmepriv); + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + { +#ifdef CONFIG_IOCTL_CFG80211 + if((wdev_to_priv(pAdapter->rtw_wdev))->p2p_enabled == _TRUE) + { + } + else +#endif + return; + } + + // Decide the current status and if modify initial gain or not + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + { + pDigTable->CurSTAConnectState = DIG_STA_BEFORE_CONNECT; + } + else if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + pDigTable->CurSTAConnectState = DIG_STA_CONNECT; + } + else + { + pDigTable->CurSTAConnectState = DIG_STA_DISCONNECT; + } + + + pDigTable->CurMultiSTAConnectState = DIG_MultiSTA_DISCONNECT; + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + if((is_IBSS_empty(pAdapter)==_FAIL) && (pAdapter->stapriv.asoc_sta_count > 2)) + pDigTable->CurMultiSTAConnectState = DIG_MultiSTA_CONNECT; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + if(pAdapter->stapriv.asoc_sta_count > 2) + pDigTable->CurMultiSTAConnectState = DIG_MultiSTA_CONNECT; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(pAdapter, WIFI_AP_STATE) == _TRUE) + { + PADAPTER pbuddy_adapter = pAdapter->pbuddy_adapter; + + if(pbuddy_adapter->stapriv.asoc_sta_count > 2) + { + pDigTable->CurSTAConnectState = DIG_STA_CONNECT; + pDigTable->CurMultiSTAConnectState = DIG_MultiSTA_CONNECT; + } + } + else if(check_buddy_fwstate(pAdapter, WIFI_STATION_STATE) == _TRUE && + check_buddy_fwstate(pAdapter, _FW_LINKED) == _TRUE) + { + pDigTable->CurSTAConnectState = DIG_STA_CONNECT; + + } +#endif //CONFIG_CONCURRENT_MODE + + + dm_initial_gain_STA(pAdapter); + dm_initial_gain_Multi_STA(pAdapter); + //Baron temp DIG solution for DMP + //dm_CtrlInitGainByFA(pAdapter); + + dm_CCK_PacketDetectionThresh(pAdapter); + + pDigTable->PreSTAConnectState = pDigTable->CurSTAConnectState; + +} + + +static void dm_DIG( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + //Read 0x0c50; Initial gain + pDigTable->PreIGValue = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); + + //RTPRINT(FDM, DM_Monitor, ("dm_DIG() ==>\n")); + + if(pdmpriv->bDMInitialGainEnable == _FALSE) + return; + + //if(pDigTable->Dig_Enable_Flag == _FALSE) + // return; + + if(!(pdmpriv->DMFlag & DYNAMIC_FUNC_DIG)) + return; + + //RTPRINT(FDM, DM_Monitor, ("dm_DIG() progress \n")); + + dm_CtrlInitGainByTwoPort(pAdapter); + + //RTPRINT(FDM, DM_Monitor, ("dm_DIG() <==\n")); +} + +static void dm_SavePowerIndex(IN PADAPTER Adapter) +{ + u8 index; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for(index = 0; index< 6; index++) + pdmpriv->PowerIndex_backup[index] = rtw_read8(Adapter, Power_Index_REG[index]); +} + +static void dm_RestorePowerIndex(IN PADAPTER Adapter) +{ + u8 index; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for(index = 0; index< 6; index++) + rtw_write8(Adapter, Power_Index_REG[index], pdmpriv->PowerIndex_backup[index]); +} + +static void dm_WritePowerIndex( + IN PADAPTER Adapter, + IN u8 Value) +{ + u8 index; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for(index = 0; index< 6; index++) + rtw_write8(Adapter, Power_Index_REG[index], Value); +} + +static void dm_InitDynamicTxPower(IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + +#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 + { + dm_SavePowerIndex(Adapter); + pdmpriv->bDynamicTxPowerEnable = _TRUE; + } + else +#else + pdmpriv->bDynamicTxPowerEnable = _FALSE; +#endif + + pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal; + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; +} + + +static void dm_DynamicTxPower(IN PADAPTER 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; + + // If dynamic high power is disabled. + if(!(pdmpriv->DMFlag & DYNAMIC_FUNC_HP) ) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + return; + } + + // STA not connected and AP not connected + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) && + (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + { + //RT_TRACE(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; + } +#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 +{ + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) // Default port + { + //todo: AP Mode + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //RT_TRACE(COMP_HIPWR, DBG_LOUD, ("AP Client PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + else + { + UndecoratedSmoothedPWDB = pdmpriv->UndecoratedSmoothedPWDB; + //RT_TRACE(COMP_HIPWR, DBG_LOUD, ("STA Default Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + } + else // associated entry pwdb + { + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //RT_TRACE(COMP_HIPWR, DBG_LOUD, ("AP Ext Port PWDB = 0x%x \n", UndecoratedSmoothedPWDB)); + } + + if(UndecoratedSmoothedPWDB >= TX_POWER_NEAR_FIELD_THRESH_LVL2) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Level2; + //RT_TRACE(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; + //RT_TRACE(COMP_HIPWR, DBG_LOUD, ("TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + } + else if(UndecoratedSmoothedPWDB < (TX_POWER_NEAR_FIELD_THRESH_LVL1-5)) + { + pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; + //RT_TRACE(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 + dm_RestorePowerIndex(Adapter); + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) + dm_WritePowerIndex(Adapter, 0x14); + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + dm_WritePowerIndex(Adapter, 0x10); + } + pdmpriv->LastDTPLvl = pdmpriv->DynamicTxHighPowerLvl; + +} + + +static VOID +DM_ChangeDynamicInitGainThresh( + IN PADAPTER pAdapter, + IN u32 DM_Type, + IN u32 DM_Value) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + + if (DM_Type == DIG_TYPE_THRESH_HIGH) + { + pDigTable->RssiHighThresh = DM_Value; + } + else if (DM_Type == DIG_TYPE_THRESH_LOW) + { + pDigTable->RssiLowThresh = DM_Value; + } + else if (DM_Type == DIG_TYPE_ENABLE) + { + pDigTable->Dig_Enable_Flag = _TRUE; + } + else if (DM_Type == DIG_TYPE_DISABLE) + { + pDigTable->Dig_Enable_Flag = _FALSE; + } + else if (DM_Type == DIG_TYPE_BACKOFF) + { + if(DM_Value > 30) + DM_Value = 30; + pDigTable->BackoffVal = (u8)DM_Value; + } + else if(DM_Type == DIG_TYPE_RX_GAIN_MIN) + { + if(DM_Value == 0) + DM_Value = 0x1; + pDigTable->rx_gain_range_min = (u8)DM_Value; + } + else if(DM_Type == DIG_TYPE_RX_GAIN_MAX) + { + if(DM_Value > 0x50) + DM_Value = 0x50; + pDigTable->rx_gain_range_max = (u8)DM_Value; + } +} /* DM_ChangeDynamicInitGainThresh */ + + +static VOID PWDB_Monitor( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + int i; + int tmpEntryMaxPWDB=0, tmpEntryMinPWDB=0xff; + u8 sta_cnt=0; + u32 PWDB_rssi[NUM_STA]={0};//[0~15]:MACID, [16~31]:PWDB_rssi + + if(check_fwstate(&Adapter->mlmepriv, _FW_LINKED) != _TRUE) + return; + + + if(check_fwstate(&Adapter->mlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + _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; + + PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16)); + } + + } + + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + + + if(pHalData->fw_ractrl == _TRUE) + { + // Report every sta's RSSI to FW + for(i=0; i< sta_cnt; i++) + { + rtl8192c_set_rssi_cmd(Adapter, (u8*)&PWDB_rssi[i]); + } + } + + } + + + + 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; + } + + + if(check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) + { + + if(pHalData->fw_ractrl == _TRUE) + { + u32 param = (u32)(pdmpriv->UndecoratedSmoothedPWDB<<16); + + param |= 0;//macid=0 for sta mode; + + rtl8192c_set_rssi_cmd(Adapter, (u8*)¶m); + } + } + +} + + +static void +DM_InitEdcaTurbo( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + pHalData->bCurrentTurboEDCA = _FALSE; + Adapter->recvpriv.bIsAnyNonBEPkts = _FALSE; + +} + + +static void +dm_CheckEdcaTurbo( + IN PADAPTER Adapter + ) +{ + u32 trafficIndex; + u32 edca_param; + u64 cur_tx_bytes = 0; + u64 cur_rx_bytes = 0; + u8 bbtchange = _FALSE; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + 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); +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); +#endif + + + if ((pregpriv->wifi_spec == 1) || (pmlmeinfo->HT_enable == 0)) + { + goto dm_CheckEdcaTurbo_EXIT; + } + + if (pmlmeinfo->assoc_AP_vendor >= maxAP) + { + goto dm_CheckEdcaTurbo_EXIT; + } + +#ifdef CONFIG_BT_COEXIST + if(pbtpriv->BT_Coexist) + { + if( (pbtpriv->BT_EDCA[UP_LINK]!=0) || (pbtpriv->BT_EDCA[DOWN_LINK]!=0)) + { + bbtchange = _TRUE; + } + } +#endif + + // Check if the status needs to be changed. + if((bbtchange) || (!precvpriv->bIsAnyNonBEPkts) ) + { + cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; + cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; + + //traffic, TX or RX + if((pmlmeinfo->assoc_AP_vendor == ralinkAP)||(pmlmeinfo->assoc_AP_vendor == atherosAP)) + { + 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 ((pdmpriv->prv_traffic_idx != trafficIndex) || (!pHalData->bCurrentTurboEDCA)) + { +#ifdef CONFIG_BT_COEXIST + if(_TRUE == bbtchange) + { + edca_param = pbtpriv->BT_EDCA[trafficIndex]; + } + else +#endif + { +#if 0 + //adjust EDCA parameter for BE queue + edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; +#else + + if((pmlmeinfo->assoc_AP_vendor == ciscoAP) && (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) + { + edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; + } + else + { + edca_param = EDCAParam[unknownAP][trafficIndex]; + } +#endif + } + +#ifdef CONFIG_PCI_HCI + if(IS_92C_SERIAL(pHalData->VersionID)) + { + edca_param = 0x60a42b; + } + else + { + edca_param = 0x6ea42b; + } +#endif + rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); + + pdmpriv->prv_traffic_idx = trafficIndex; + } + + pHalData->bCurrentTurboEDCA = _TRUE; + } + else + { + // + // Turn Off EDCA turbo here. + // Restore original EDCA according to the declaration of AP. + // + if(pHalData->bCurrentTurboEDCA) + { + rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); + pHalData->bCurrentTurboEDCA = _FALSE; + } + } + +dm_CheckEdcaTurbo_EXIT: + // Set variables for next time. + precvpriv->bIsAnyNonBEPkts = _FALSE; + pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes; + precvpriv->last_rx_bytes = precvpriv->rx_bytes; + +} + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 + +static VOID +dm_TXPowerTrackingCallback_ThermalMeter_92C( + IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, delta_HP, TimeOut = 100; + int ele_A, ele_D, TempCCk, X, value32; + int Y, ele_C; + s8 OFDM_index[2], CCK_index = 0, OFDM_index_old[2], CCK_index_old = 0; + int i = 0; + BOOLEAN is2T = IS_92C_SERIAL(pHalData->VersionID); + +#if MP_DRIVER == 1 + PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx); + u8 *TxPwrLevel = pMptCtx->TxPwrLevel; +#endif + u8 OFDM_min_index = 6, rf; //OFDM BB Swing should be less than +3.0dB, which is required by Arthur +#if 0 + u32 DPK_delta_mapping[2][DPK_DELTA_MAPPING_NUM] = { + {0x1c, 0x1c, 0x1d, 0x1d, 0x1e, + 0x1f, 0x00, 0x00, 0x01, 0x01, + 0x02, 0x02, 0x03}, + {0x1c, 0x1d, 0x1e, 0x1e, 0x1e, + 0x1f, 0x00, 0x00, 0x01, 0x02, + 0x02, 0x03, 0x03}}; +#endif +#ifdef CONFIG_USB_HCI + u8 ThermalValue_HP_count = 0; + u32 ThermalValue_HP = 0; + s32 index_mapping_HP[index_mapping_HP_NUM] = { + 0, 1, 3, 4, 6, + 7, 9, 10, 12, 13, + 15, 16, 18, 19, 21 + }; + + s8 index_HP; +#endif + + pdmpriv->TXPowerTrackingCallbackCnt++; //cosa add for debug + pdmpriv->bTXPowerTrackingInit = _TRUE; + + if(pHalData->CurrentChannel == 14 && !pdmpriv->bCCKinCH14) + pdmpriv->bCCKinCH14 = _TRUE; + else if(pHalData->CurrentChannel != 14 && pdmpriv->bCCKinCH14) + pdmpriv->bCCKinCH14 = _FALSE; + + //DBG_8192C("===>dm_TXPowerTrackingCallback_ThermalMeter_92C\n"); + + ThermalValue = (u8)PHY_QueryRFReg(Adapter, RF_PATH_A, RF_T_METER, 0x1f); // 0x24: RF Reg[4:0] + + //DBG_8192C("\n\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n",ThermalValue,pdmpriv->ThermalValue, pHalData->EEPROMThermalMeter); + + rtl8192c_PHY_APCalibrate(Adapter, (ThermalValue - pHalData->EEPROMThermalMeter)); + + if(is2T) + rf = 2; + else + rf = 1; + + if(ThermalValue) + { +// if(!pHalData->ThermalValue) + { + //Query OFDM path A default setting + ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D; + for(i=0; ibCCKinCH14) + { + if(_rtw_memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch14[i][2], 4)==_TRUE) + { + CCK_index_old =(u8)i; + //DBG_8192C("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch 14 %d\n", rCCK0_TxFilter2, TempCCk, CCK_index_old, pdmpriv->bCCKinCH14); + break; + } + } + else + { + if(_rtw_memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch1_Ch13[i][2], 4)==_TRUE) + { + CCK_index_old =(u8)i; + //DBG_8192C("Initial reg0x%x = 0x%x, CCK_index=0x%x, ch14 %d\n", rCCK0_TxFilter2, TempCCk, CCK_index_old, pdmpriv->bCCKinCH14); + break; + } + } + } + + if(!pdmpriv->ThermalValue) + { + pdmpriv->ThermalValue = pHalData->EEPROMThermalMeter; + pdmpriv->ThermalValue_LCK = ThermalValue; + pdmpriv->ThermalValue_IQK = ThermalValue; + pdmpriv->ThermalValue_DPK = pHalData->EEPROMThermalMeter; + +#ifdef CONFIG_USB_HCI + for(i = 0; i < rf; i++) + pdmpriv->OFDM_index_HP[i] = pdmpriv->OFDM_index[i] = OFDM_index_old[i]; + pdmpriv->CCK_index_HP = pdmpriv->CCK_index = CCK_index_old; +#else + for(i = 0; i < rf; i++) + pdmpriv->OFDM_index[i] = OFDM_index_old[i]; + pdmpriv->CCK_index = CCK_index_old; +#endif + } + +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType == BOARD_USB_High_PA) + { + pdmpriv->ThermalValue_HP[pdmpriv->ThermalValue_HP_index] = ThermalValue; + pdmpriv->ThermalValue_HP_index++; + if(pdmpriv->ThermalValue_HP_index == HP_THERMAL_NUM) + pdmpriv->ThermalValue_HP_index = 0; + + for(i = 0; i < HP_THERMAL_NUM; i++) + { + if(pdmpriv->ThermalValue_HP[i]) + { + ThermalValue_HP += pdmpriv->ThermalValue_HP[i]; + ThermalValue_HP_count++; + } + } + + if(ThermalValue_HP_count) + ThermalValue = (u8)(ThermalValue_HP / ThermalValue_HP_count); + } +#endif + } + + delta = (ThermalValue > pdmpriv->ThermalValue)?(ThermalValue - pdmpriv->ThermalValue):(pdmpriv->ThermalValue - ThermalValue); +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType == BOARD_USB_High_PA) + { + if(pdmpriv->bDoneTxpower) + delta_HP = (ThermalValue > pdmpriv->ThermalValue)?(ThermalValue - pdmpriv->ThermalValue):(pdmpriv->ThermalValue - ThermalValue); + else + delta_HP = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue); + } + else +#endif + { + delta_HP = 0; + } + delta_LCK = (ThermalValue > pdmpriv->ThermalValue_LCK)?(ThermalValue - pdmpriv->ThermalValue_LCK):(pdmpriv->ThermalValue_LCK - ThermalValue); + delta_IQK = (ThermalValue > pdmpriv->ThermalValue_IQK)?(ThermalValue - pdmpriv->ThermalValue_IQK):(pdmpriv->ThermalValue_IQK - ThermalValue); + + //DBG_8192C("Readback Thermal Meter = 0x%lx pre thermal meter 0x%lx EEPROMthermalmeter 0x%lx delta 0x%lx delta_LCK 0x%lx delta_IQK 0x%lx\n", ThermalValue, pHalData->ThermalValue, pHalData->EEPROMThermalMeter, delta, delta_LCK, delta_IQK); + + if(delta_LCK > 1) + { + pdmpriv->ThermalValue_LCK = ThermalValue; + rtl8192c_PHY_LCCalibrate(Adapter); + } + + if((delta > 0 || delta_HP > 0) && pdmpriv->TxPowerTrackControl) + { +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType == BOARD_USB_High_PA) + { + pdmpriv->bDoneTxpower = _TRUE; + delta_HP = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue); + + if(delta_HP > index_mapping_HP_NUM-1) + index_HP = index_mapping_HP[index_mapping_HP_NUM-1]; + else + index_HP = index_mapping_HP[delta_HP]; + + if(ThermalValue > pHalData->EEPROMThermalMeter) //set larger Tx power + { + for(i = 0; i < rf; i++) + OFDM_index[i] = pdmpriv->OFDM_index_HP[i] - index_HP; + CCK_index = pdmpriv->CCK_index_HP -index_HP; + } + else + { + for(i = 0; i < rf; i++) + OFDM_index[i] = pdmpriv->OFDM_index_HP[i] + index_HP; + CCK_index = pdmpriv->CCK_index_HP + index_HP; + } + + delta_HP = (ThermalValue > pdmpriv->ThermalValue)?(ThermalValue - pdmpriv->ThermalValue):(pdmpriv->ThermalValue - ThermalValue); + + } + else +#endif + { + if(ThermalValue > pdmpriv->ThermalValue) + { + for(i = 0; i < rf; i++) + pdmpriv->OFDM_index[i] -= delta; + pdmpriv->CCK_index -= delta; + } + else + { + for(i = 0; i < rf; i++) + pdmpriv->OFDM_index[i] += delta; + pdmpriv->CCK_index += delta; + } + } + + /*if(is2T) + { + DBG_8192C("temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n", + pdmpriv->OFDM_index[0], pdmpriv->OFDM_index[1], pdmpriv->CCK_index); + } + else + { + DBG_8192C("temp OFDM_A_index=0x%x, CCK_index=0x%x\n", + pdmpriv->OFDM_index[0], pdmpriv->CCK_index); + }*/ + + //no adjust +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType != BOARD_USB_High_PA) +#endif + { + if(ThermalValue > pHalData->EEPROMThermalMeter) + { + for(i = 0; i < rf; i++) + OFDM_index[i] = pdmpriv->OFDM_index[i]+1; + CCK_index = pdmpriv->CCK_index+1; + } + else + { + for(i = 0; i < rf; i++) + OFDM_index[i] = pdmpriv->OFDM_index[i]; + CCK_index = pdmpriv->CCK_index; + } + +#if MP_DRIVER == 1 + for(i = 0; i < rf; i++) + { + if(TxPwrLevel[i] >=0 && TxPwrLevel[i] <=26) + { + if(ThermalValue > pHalData->EEPROMThermalMeter) + { + if (delta < 5) + OFDM_index[i] -= 1; + else + OFDM_index[i] -= 2; + } + else if(delta > 5 && ThermalValue < pHalData->EEPROMThermalMeter) + { + OFDM_index[i] += 1; + } + } + else if (TxPwrLevel[i] >= 27 && TxPwrLevel[i] <= 32 && ThermalValue > pHalData->EEPROMThermalMeter) + { + if (delta < 5) + OFDM_index[i] -= 1; + else + OFDM_index[i] -= 2; + } + else if (TxPwrLevel[i] >= 32 && TxPwrLevel[i] <= 38 && ThermalValue > pHalData->EEPROMThermalMeter && delta > 5) + { + OFDM_index[i] -= 1; + } + } + + { + if(TxPwrLevel[i] >=0 && TxPwrLevel[i] <=26) + { + if(ThermalValue > pHalData->EEPROMThermalMeter) + { + if (delta < 5) + CCK_index -= 1; + else + CCK_index -= 2; + } + else if(delta > 5 && ThermalValue < pHalData->EEPROMThermalMeter) + { + CCK_index += 1; + } + } + else if (TxPwrLevel[i] >= 27 && TxPwrLevel[i] <= 32 && ThermalValue > pHalData->EEPROMThermalMeter) + { + if (delta < 5) + CCK_index -= 1; + else + CCK_index -= 2; + } + else if (TxPwrLevel[i] >= 32 && TxPwrLevel[i] <= 38 && ThermalValue > pHalData->EEPROMThermalMeter && delta > 5) + { + CCK_index -= 1; + } + } +#endif + } + + for(i = 0; i < rf; i++) + { + if(OFDM_index[i] > (OFDM_TABLE_SIZE_92C-1)) + OFDM_index[i] = (OFDM_TABLE_SIZE_92C-1); + else if (OFDM_index[i] < OFDM_min_index) + OFDM_index[i] = OFDM_min_index; + } + + if(CCK_index > (CCK_TABLE_SIZE-1)) + CCK_index = (CCK_TABLE_SIZE-1); + else if (CCK_index < 0) + CCK_index = 0; + + /*if(is2T) + { + DBG_8192C("new OFDM_A_index=0x%x, OFDM_B_index=0x%x, CCK_index=0x%x\n", + OFDM_index[0], OFDM_index[1], CCK_index); + } + else + { + DBG_8192C("new OFDM_A_index=0x%x, CCK_index=0x%x\n", + OFDM_index[0], CCK_index); + }*/ + } + + if(pdmpriv->TxPowerTrackControl && (delta != 0 || delta_HP != 0)) + { + //Adujst OFDM Ant_A according to IQK result + ele_D = (OFDMSwingTable[OFDM_index[0]] & 0xFFC00000)>>22; + X = pdmpriv->RegE94; + Y = pdmpriv->RegE9C; + + if(X != 0) + { + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + ele_A = ((X * ele_D)>>8)&0x000003FF; + + //new element C = element D x Y + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + ele_C = ((Y * ele_D)>>8)&0x000003FF; + + //wirte new elements A, C, D to regC80 and regC94, element B is always 0 + value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A; + PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C&0x000003C0)>>6; + PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32); + + value32 = ((X * ele_D)>>7)&0x01; + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT31, value32); + + value32 = ((Y * ele_D)>>7)&0x01; + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT29, value32); + + } + else + { + PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[OFDM_index[0]]); + PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00); + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT31|BIT29, 0x00); + } + + //RTPRINT(FINIT, INIT_IQK, ("TxPwrTracking path A: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x\n", X, Y, ele_A, ele_C, ele_D)); + + //Adjust CCK according to IQK result + if(!pdmpriv->bCCKinCH14){ + rtw_write8(Adapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]); + rtw_write8(Adapter, 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]); + rtw_write8(Adapter, 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]); + rtw_write8(Adapter, 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]); + rtw_write8(Adapter, 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]); + rtw_write8(Adapter, 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]); + rtw_write8(Adapter, 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]); + rtw_write8(Adapter, 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]); + } + else{ + rtw_write8(Adapter, 0xa22, CCKSwingTable_Ch14[CCK_index][0]); + rtw_write8(Adapter, 0xa23, CCKSwingTable_Ch14[CCK_index][1]); + rtw_write8(Adapter, 0xa24, CCKSwingTable_Ch14[CCK_index][2]); + rtw_write8(Adapter, 0xa25, CCKSwingTable_Ch14[CCK_index][3]); + rtw_write8(Adapter, 0xa26, CCKSwingTable_Ch14[CCK_index][4]); + rtw_write8(Adapter, 0xa27, CCKSwingTable_Ch14[CCK_index][5]); + rtw_write8(Adapter, 0xa28, CCKSwingTable_Ch14[CCK_index][6]); + rtw_write8(Adapter, 0xa29, CCKSwingTable_Ch14[CCK_index][7]); + } + + if(is2T) + { + ele_D = (OFDMSwingTable[(u8)OFDM_index[1]] & 0xFFC00000)>>22; + + //new element A = element D x X + X = pdmpriv->RegEB4; + Y = pdmpriv->RegEBC; + + if(X != 0){ + if ((X & 0x00000200) != 0) //consider minus + X = X | 0xFFFFFC00; + ele_A = ((X * ele_D)>>8)&0x000003FF; + + //new element C = element D x Y + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + ele_C = ((Y * ele_D)>>8)&0x00003FF; + + //wirte new elements A, C, D to regC88 and regC9C, element B is always 0 + value32=(ele_D<<22)|((ele_C&0x3F)<<16) |ele_A; + PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C&0x000003C0)>>6; + PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32); + + value32 = ((X * ele_D)>>7)&0x01; + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT27, value32); + + value32 = ((Y * ele_D)>>7)&0x01; + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT25, value32); + + } + else{ + PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable[OFDM_index[1]]); + PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); + PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT27|BIT25, 0x00); + } + + //DBG_8192C("TxPwrTracking path B: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x\n", X, Y, ele_A, ele_C, ele_D); + } + + /* + DBG_8192C("TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", \ + PHY_QueryBBReg(Adapter, 0xc80, bMaskDWord),\ + PHY_QueryBBReg(Adapter, 0xc94, bMaskDWord), \ + PHY_QueryRFReg(Adapter, RF_PATH_A, 0x24, bMaskDWord)); + */ + } + +#if MP_DRIVER == 1 + if(delta_IQK > 1) +#else + if(delta_IQK > 3) +#endif + { + pdmpriv->ThermalValue_IQK = ThermalValue; + rtl8192c_PHY_IQCalibrate(Adapter,_FALSE); + } + + //update thermal meter value + if(pdmpriv->TxPowerTrackControl) + pdmpriv->ThermalValue = ThermalValue; + + } + + //DBG_8192C("<===dm_TXPowerTrackingCallback_ThermalMeter_92C\n"); + + pdmpriv->TXPowercount = 0; + +} + + +static VOID +dm_InitializeTXPowerTracking_ThermalMeter( + IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + //pMgntInfo->bTXPowerTracking = _TRUE; + pdmpriv->TXPowercount = 0; + pdmpriv->bTXPowerTrackingInit = _FALSE; + pdmpriv->ThermalValue = 0; + +#if (MP_DRIVER != 1) //for mp driver, turn off txpwrtracking as default + pdmpriv->TxPowerTrackControl = _TRUE; +#endif + + MSG_8192C("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); +} + + +static VOID +DM_InitializeTXPowerTracking( + IN PADAPTER Adapter) +{ + dm_InitializeTXPowerTracking_ThermalMeter(Adapter); +} + +// +// Description: +// - Dispatch TxPower Tracking direct call ONLY for 92s. +// - We shall NOT schedule Workitem within PASSIVE LEVEL, which will cause system resource +// leakage under some platform. +// +// Assumption: +// PASSIVE_LEVEL when this routine is called. +// +// Added by Roger, 2009.06.18. +// +static VOID +DM_TXPowerTracking92CDirectCall( + IN PADAPTER Adapter) +{ + dm_TXPowerTrackingCallback_ThermalMeter_92C(Adapter); +} + +static VOID +dm_CheckTXPowerTracking_ThermalMeter( + IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + //u1Byte TxPowerCheckCnt = 5; //10 sec + + //if(!pMgntInfo->bTXPowerTracking /*|| (!pdmpriv->TxPowerTrackControl && pdmpriv->bAPKdone)*/) + if(!(pdmpriv->DMFlag & DYNAMIC_FUNC_SS)) + { + return; + } + + if(!pdmpriv->TM_Trigger) //at least delay 1 sec + { + //pHalData->TxPowerCheckCnt++; //cosa add for debug + PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); + //DBG_8192C("Trigger 92C Thermal Meter!!\n"); + + pdmpriv->TM_Trigger = 1; + return; + + } + else + { + //DBG_8192C("Schedule TxPowerTracking direct call!!\n"); + DM_TXPowerTracking92CDirectCall(Adapter); //Using direct call is instead, added by Roger, 2009.06.18. + pdmpriv->TM_Trigger = 0; + } + +} + + +VOID +rtl8192c_dm_CheckTXPowerTracking( + IN PADAPTER Adapter) +{ + dm_CheckTXPowerTracking_ThermalMeter(Adapter); +} + +#ifdef CONFIG_BT_COEXIST +static BOOLEAN BT_BTStateChange(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + struct registry_priv *registry_par = &Adapter->registrypriv; + + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + u32 Polling, Ratio_Tx, Ratio_PRI; + u32 BT_Tx, BT_PRI; + u8 BT_State; + static u8 ServiceTypeCnt = 0; + u8 CurServiceType; + static u8 LastServiceType = BT_Idle; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) + return _FALSE; + + BT_State = rtw_read8(Adapter, 0x4fd); +/* + temp = PlatformEFIORead4Byte(Adapter, 0x488); + BT_Tx = (u2Byte)(((temp<<8)&0xff00)+((temp>>8)&0xff)); + BT_PRI = (u2Byte)(((temp>>8)&0xff00)+((temp>>24)&0xff)); + + temp = PlatformEFIORead4Byte(Adapter, 0x48c); + Polling = ((temp<<8)&0xff000000) + ((temp>>8)&0x00ff0000) + + ((temp<<8)&0x0000ff00) + ((temp>>8)&0x000000ff); + +*/ + BT_Tx = rtw_read32(Adapter, 0x488); + + DBG_8192C("Ratio 0x488 =%x\n", BT_Tx); + BT_Tx =BT_Tx & 0x00ffffff; + //RTPRINT(FBT, BT_TRACE, ("Ratio BT_Tx =%x\n", BT_Tx)); + + BT_PRI = rtw_read32(Adapter, 0x48c); + + DBG_8192C("Ratio 0x48c =%x\n", BT_PRI); + BT_PRI =BT_PRI & 0x00ffffff; + //RTPRINT(FBT, BT_TRACE, ("Ratio BT_PRI =%x\n", BT_PRI)); + + + Polling = rtw_read32(Adapter, 0x490); + //RTPRINT(FBT, BT_TRACE, ("Ratio 0x490 =%x\n", Polling)); + + + if(BT_Tx==0xffffffff && BT_PRI==0xffffffff && Polling==0xffffffff && BT_State==0xff) + return _FALSE; + + BT_State &= BIT0; + + if(BT_State != pbtpriv->BT_CUR_State) + { + pbtpriv->BT_CUR_State = BT_State; + + if(registry_par->bt_sco == 3) + { + ServiceTypeCnt = 0; + + pbtpriv->BT_Service = BT_Idle; + + DBG_8192C("BT_%s\n", BT_State?"ON":"OFF"); + + BT_State = BT_State | + ((pbtpriv->BT_Ant_isolation==1)?0:BIT1) |BIT2; + + rtw_write8(Adapter, 0x4fd, BT_State); + DBG_8192C("BT set 0x4fd to %x\n", BT_State); + } + + return _TRUE; + } + DBG_8192C("bRegBT_Sco = %d\n",registry_par->bt_sco); + + Ratio_Tx = BT_Tx*1000/Polling; + Ratio_PRI = BT_PRI*1000/Polling; + + pbtpriv->Ratio_Tx=Ratio_Tx; + pbtpriv->Ratio_PRI=Ratio_PRI; + + DBG_8192C("Ratio_Tx=%d\n", Ratio_Tx); + DBG_8192C("Ratio_PRI=%d\n", Ratio_PRI); + + + if(BT_State && registry_par->bt_sco==3) + { + DBG_8192C("bt_sco ==3 Follow Counter\n"); +// if(BT_Tx==0xffff && BT_PRI==0xffff && Polling==0xffffffff) +// { +// ServiceTypeCnt = 0; +// return FALSE; +// } +// else + { + /* + Ratio_Tx = BT_Tx*1000/Polling; + Ratio_PRI = BT_PRI*1000/Polling; + + pHalData->bt_coexist.Ratio_Tx=Ratio_Tx; + pHalData->bt_coexist.Ratio_PRI=Ratio_PRI; + + RTPRINT(FBT, BT_TRACE, ("Ratio_Tx=%d\n", Ratio_Tx)); + RTPRINT(FBT, BT_TRACE, ("Ratio_PRI=%d\n", Ratio_PRI)); + + */ + if((Ratio_Tx < 30) && (Ratio_PRI < 30)) + CurServiceType = BT_Idle; + else if((Ratio_PRI > 110) && (Ratio_PRI < 250)) + CurServiceType = BT_SCO; + else if((Ratio_Tx >= 200)&&(Ratio_PRI >= 200)) + CurServiceType = BT_Busy; + else if((Ratio_Tx >=350) && (Ratio_Tx < 500)) + CurServiceType = BT_OtherBusy; + else if(Ratio_Tx >=500) + CurServiceType = BT_PAN; + else + CurServiceType=BT_OtherAction; + } + +/* if(pHalData->bt_coexist.bStopCount) + { + ServiceTypeCnt=0; + pHalData->bt_coexist.bStopCount=FALSE; + } +*/ +// if(CurServiceType == BT_OtherBusy) + { + ServiceTypeCnt=2; + LastServiceType=CurServiceType; + } +#if 0 + else if(CurServiceType == LastServiceType) + { + if(ServiceTypeCnt<3) + ServiceTypeCnt++; + } + else + { + ServiceTypeCnt = 0; + LastServiceType = CurServiceType; + } +#endif + + if(ServiceTypeCnt==2) + { + pbtpriv->BT_Service = LastServiceType; + BT_State = BT_State | + ((pbtpriv->BT_Ant_isolation==1)?0:BIT1) | + //((pbtpriv->BT_Service==BT_SCO)?0:BIT2); + ((pbtpriv->BT_Service!=BT_Idle)?0:BIT2); + + //if(pbtpriv->BT_Service==BT_Busy) + // BT_State&= ~(BIT2); + + if(pbtpriv->BT_Service==BT_SCO) + { + DBG_8192C("BT TYPE Set to ==> BT_SCO\n"); + } + else if(pbtpriv->BT_Service==BT_Idle) + { + DBG_8192C("BT TYPE Set to ==> BT_Idle\n"); + } + else if(pbtpriv->BT_Service==BT_OtherAction) + { + DBG_8192C("BT TYPE Set to ==> BT_OtherAction\n"); + } + else if(pbtpriv->BT_Service==BT_Busy) + { + DBG_8192C("BT TYPE Set to ==> BT_Busy\n"); + } + else if(pbtpriv->BT_Service==BT_PAN) + { + DBG_8192C("BT TYPE Set to ==> BT_PAN\n"); + } + else + { + DBG_8192C("BT TYPE Set to ==> BT_OtherBusy\n"); + } + + //Add interrupt migration when bt is not in idel state (no traffic). + //suggestion by Victor. + if(pbtpriv->BT_Service!=BT_Idle)//EDCA_VI_PARAM modify + { + + rtw_write16(Adapter, 0x504, 0x0ccc); + rtw_write8(Adapter, 0x506, 0x54); + rtw_write8(Adapter, 0x507, 0x54); + + } + else + { + rtw_write8(Adapter, 0x506, 0x00); + rtw_write8(Adapter, 0x507, 0x00); + } + + rtw_write8(Adapter, 0x4fd, BT_State); + DBG_8192C("BT_SCO set 0x4fd to %x\n", BT_State); + return _TRUE; + } + } + + return _FALSE; + +} + +static BOOLEAN +BT_WifiConnectChange( + IN PADAPTER Adapter + ) +{ + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); +// PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + static BOOLEAN bMediaConnect = _FALSE; + + //if(!pMgntInfo->bMediaConnect || MgntRoamingInProgress(pMgntInfo)) + if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) + { + bMediaConnect = _FALSE; + } + else + { + if(!bMediaConnect) + { + bMediaConnect = _TRUE; + return _TRUE; + } + bMediaConnect = _TRUE; + } + + return _FALSE; +} + +#define BT_RSSI_STATE_NORMAL_POWER BIT0 +#define BT_RSSI_STATE_AMDPU_OFF BIT1 +#define BT_RSSI_STATE_SPECIAL_LOW BIT2 +#define BT_RSSI_STATE_BG_EDCA_LOW BIT3 + +static s32 GET_UNDECORATED_AVERAGE_RSSI(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + s32 average_rssi; + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) + { + average_rssi = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + } + else + { + average_rssi = pdmpriv->UndecoratedSmoothedPWDB; + } + return average_rssi; +} + +static u8 BT_RssiStateChange( + IN PADAPTER Adapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + //PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + s32 UndecoratedSmoothedPWDB; + u8 CurrBtRssiState = 0x00; + + + + + //if(pMgntInfo->bMediaConnect) // Default port + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + UndecoratedSmoothedPWDB = GET_UNDECORATED_AVERAGE_RSSI(Adapter); + } + else // associated entry pwdb + { + if(pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0) + UndecoratedSmoothedPWDB = 100; // No any RSSI information. Assume to be MAX. + else + UndecoratedSmoothedPWDB = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + } + + // Check RSSI to determine HighPower/NormalPower state for BT coexistence. + if(UndecoratedSmoothedPWDB >= 67) + CurrBtRssiState &= (~BT_RSSI_STATE_NORMAL_POWER); + else if(UndecoratedSmoothedPWDB < 62) + CurrBtRssiState |= BT_RSSI_STATE_NORMAL_POWER; + + // Check RSSI to determine AMPDU setting for BT coexistence. + if(UndecoratedSmoothedPWDB >= 40) + CurrBtRssiState &= (~BT_RSSI_STATE_AMDPU_OFF); + else if(UndecoratedSmoothedPWDB <= 32) + CurrBtRssiState |= BT_RSSI_STATE_AMDPU_OFF; + + // Marked RSSI state. It will be used to determine BT coexistence setting later. + if(UndecoratedSmoothedPWDB < 35) + CurrBtRssiState |= BT_RSSI_STATE_SPECIAL_LOW; + else + CurrBtRssiState &= (~BT_RSSI_STATE_SPECIAL_LOW); + + // Check BT state related to BT_Idle in B/G mode. + if(UndecoratedSmoothedPWDB < 15) + CurrBtRssiState |= BT_RSSI_STATE_BG_EDCA_LOW; + else + CurrBtRssiState &= (~BT_RSSI_STATE_BG_EDCA_LOW); + + if(CurrBtRssiState != pbtpriv->BtRssiState) + { + pbtpriv->BtRssiState = CurrBtRssiState; + return _TRUE; + } + else + { + return _FALSE; + } +} + +static void dm_BTCoexist(PADAPTER Adapter ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct mlme_ext_info *pmlmeinfo = &Adapter->mlmeextpriv.mlmext_info; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + //PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + //PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + + //PRX_TS_RECORD pRxTs = NULL; + u8 BT_gpio_mux; + + BOOLEAN bWifiConnectChange, bBtStateChange,bRssiStateChange; + + if(pbtpriv->bCOBT == _FALSE) return; + + if(!( pdmpriv->DMFlag & DYNAMIC_FUNC_BT)) return; + + if( (pbtpriv->BT_Coexist) &&(pbtpriv->BT_CoexistType == BT_CSR_BC4) && (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) ) + { + bWifiConnectChange = BT_WifiConnectChange(Adapter); + bBtStateChange = BT_BTStateChange(Adapter); + bRssiStateChange = BT_RssiStateChange(Adapter); + + DBG_8192C("bWifiConnectChange %d, bBtStateChange %d,bRssiStateChange %d\n", + bWifiConnectChange,bBtStateChange,bRssiStateChange); + + // add by hpfan for debug message + BT_gpio_mux = rtw_read8(Adapter, REG_GPIO_MUXCFG); + DBG_8192C("BTCoexit Reg_0x40 (%2x)\n", BT_gpio_mux); + + if( bWifiConnectChange ||bBtStateChange ||bRssiStateChange ) + { + if(pbtpriv->BT_CUR_State) + { + + // Do not allow receiving A-MPDU aggregation. + if(pbtpriv->BT_Ampdu)// 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. + { + + if(pmlmeinfo->assoc_AP_vendor == ciscoAP) + { + if(pbtpriv->BT_Service!=BT_Idle) + { + if(pmlmeinfo->bAcceptAddbaReq) + { + DBG_8192C("BT_Disallow AMPDU \n"); + pmlmeinfo->bAcceptAddbaReq = _FALSE; + send_delba(Adapter,0, get_my_bssid(&(pmlmeinfo->network))); + } + } + else + { + if(!pmlmeinfo->bAcceptAddbaReq) + { + DBG_8192C("BT_Allow AMPDU RSSI >=40\n"); + pmlmeinfo->bAcceptAddbaReq = _TRUE; + } + } + } + else + { + if(!pmlmeinfo->bAcceptAddbaReq) + { + DBG_8192C("BT_Allow AMPDU BT Idle\n"); + pmlmeinfo->bAcceptAddbaReq = _TRUE; + } + } + } + +#if 0 + else if((pHalData->bt_coexist.BT_Service==BT_SCO) || (pHalData->bt_coexist.BT_Service==BT_Busy)) + { + if(pHalData->bt_coexist.BtRssiState & BT_RSSI_STATE_AMDPU_OFF) + { + if(pMgntInfo->bBT_Ampdu && pHTInfo->bAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Disallow AMPDU RSSI <=32\n")); + pHTInfo->bAcceptAddbaReq = FALSE; + if(GetTs(Adapter, (PTS_COMMON_INFO*)(&pRxTs), pMgntInfo->Bssid, 0, RX_DIR, FALSE)) + TsInitDelBA(Adapter, (PTS_COMMON_INFO)pRxTs, RX_DIR); + } + } + else + { + if(pMgntInfo->bBT_Ampdu && !pHTInfo->bAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU RSSI >=40\n")); + pHTInfo->bAcceptAddbaReq = TRUE; + } + } + } + else + { + if(pMgntInfo->bBT_Ampdu && !pHTInfo->bAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU BT not in SCO or BUSY\n")); + pHTInfo->bAcceptAddbaReq = TRUE; + } + } +#endif + + if(pbtpriv->BT_Ant_isolation) + { + DBG_8192C("BT_IsolationLow\n"); + +// 20100427 Joseph: Do not adjust Rate adaptive for BT coexist suggested by SD3. +#if 0 + RTPRINT(FBT, BT_TRACE, ("BT_Update Rate table\n")); + if(pMgntInfo->bUseRAMask) + { + // 20100407 Joseph: Fix rate adaptive modification for BT coexist. + // This fix is not complete yet. It shall also consider VWifi and Adhoc case, + // which connect with multiple STAs. + Adapter->HalFunc.UpdateHalRAMaskHandler( + Adapter, + FALSE, + 0, + NULL, + NULL, + pMgntInfo->RateAdaptive.RATRState, + RAMask_Normal); + } + else + { + Adapter->HalFunc.UpdateHalRATRTableHandler( + Adapter, + &pMgntInfo->dot11OperationalRateSet, + pMgntInfo->dot11HTOperationalRateSet,NULL); + } +#endif + + // 20100415 Joseph: Modify BT coexist mechanism suggested by Yaying. + // Now we only enable HW BT coexist when BT in "Busy" state. + if(1)//pMgntInfo->LinkDetectInfo.NumRecvDataInPeriod >= 20) + { + if((pmlmeinfo->assoc_AP_vendor == ciscoAP) && + pbtpriv->BT_Service==BT_OtherAction) + { + DBG_8192C("BT_Turn ON Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0xa0); + } + else + { + if((pbtpriv->BT_Service==BT_Busy) && + (pbtpriv->BtRssiState & BT_RSSI_STATE_NORMAL_POWER)) + { + DBG_8192C("BT_Turn ON Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0xa0); + } + else if((pbtpriv->BT_Service==BT_OtherAction) && + (pbtpriv->BtRssiState & BT_RSSI_STATE_SPECIAL_LOW)) + { + DBG_8192C("BT_Turn ON Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0xa0); + } + else if(pbtpriv->BT_Service==BT_PAN) + { + DBG_8192C("BT_Turn ON Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0x00); + } + else + { + DBG_8192C("BT_Turn OFF Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0x00); + } + } + } + else + { + DBG_8192C("BT: There is no Wifi traffic!! Turn off Coexist\n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0x00); + } + + if(1)//pMgntInfo->LinkDetectInfo.NumRecvDataInPeriod >= 20) + { + if(pbtpriv->BT_Service==BT_PAN) + { + DBG_8192C("BT_Turn ON Coexist(Reg0x44 = 0x10100)\n"); + rtw_write32(Adapter, REG_GPIO_PIN_CTRL, 0x10100); + } + else + { + DBG_8192C("BT_Turn OFF Coexist(Reg0x44 = 0x0)\n"); + rtw_write32(Adapter, REG_GPIO_PIN_CTRL, 0x0); + } + } + else + { + DBG_8192C("BT: There is no Wifi traffic!! Turn off Coexist(Reg0x44 = 0x0)\n"); + rtw_write32(Adapter, REG_GPIO_PIN_CTRL, 0x0); + } + + // 20100430 Joseph: Integrate the BT coexistence EDCA tuning here. + if(pbtpriv->BtRssiState & BT_RSSI_STATE_NORMAL_POWER) + { + if(pbtpriv->BT_Service==BT_OtherBusy) + { + //pbtpriv->BtEdcaUL = 0x5ea72b; + //pbtpriv->BtEdcaDL = 0x5ea72b; + pbtpriv->BT_EDCA[UP_LINK] = 0x5ea72b; + pbtpriv->BT_EDCA[DOWN_LINK] = 0x5ea72b; + + DBG_8192C("BT in BT_OtherBusy state Tx (%d) >350 parameter(0x%x) = 0x%x\n", pbtpriv->Ratio_Tx ,REG_EDCA_BE_PARAM, 0x5ea72b); + } + else if(pbtpriv->BT_Service==BT_Busy) + { + //pbtpriv->BtEdcaUL = 0x5eb82f; + //pbtpriv->BtEdcaDL = 0x5eb82f; + + pbtpriv->BT_EDCA[UP_LINK] = 0x5eb82f; + pbtpriv->BT_EDCA[DOWN_LINK] = 0x5eb82f; + + DBG_8192C("BT in BT_Busy state parameter(0x%x) = 0x%x\n", REG_EDCA_BE_PARAM, 0x5eb82f); + } + else if(pbtpriv->BT_Service==BT_SCO) + { + if(pbtpriv->Ratio_Tx>160) + { + //pbtpriv->BtEdcaUL = 0x5ea72f; + //pbtpriv->BtEdcaDL = 0x5ea72f; + pbtpriv->BT_EDCA[UP_LINK] = 0x5ea72f; + pbtpriv->BT_EDCA[DOWN_LINK] = 0x5ea72f; + DBG_8192C("BT in BT_SCO state Tx (%d) >160 parameter(0x%x) = 0x%x\n",pbtpriv->Ratio_Tx, REG_EDCA_BE_PARAM, 0x5ea72f); + } + else + { + //pbtpriv->BtEdcaUL = 0x5ea32b; + //pbtpriv->BtEdcaDL = 0x5ea42b; + + pbtpriv->BT_EDCA[UP_LINK] = 0x5ea32b; + pbtpriv->BT_EDCA[DOWN_LINK] = 0x5ea42b; + + DBG_8192C("BT in BT_SCO state Tx (%d) <160 parameter(0x%x) = 0x%x\n", pbtpriv->Ratio_Tx,REG_EDCA_BE_PARAM, 0x5ea32f); + } + } + else + { + // BT coexistence mechanism does not control EDCA parameter. + //pbtpriv->BtEdcaUL = 0; + //pbtpriv->BtEdcaDL = 0; + + pbtpriv->BT_EDCA[UP_LINK] = 0; + pbtpriv->BT_EDCA[DOWN_LINK] = 0; + DBG_8192C("BT in State %d and parameter(0x%x) use original setting.\n",pbtpriv->BT_Service, REG_EDCA_BE_PARAM); + } + + if((pbtpriv->BT_Service!=BT_Idle) && + (pmlmeext->cur_wireless_mode == WIRELESS_MODE_G) && + (pbtpriv->BtRssiState & BT_RSSI_STATE_BG_EDCA_LOW)) + { + //pbtpriv->BtEdcaUL = 0x5eb82b; + //pbtpriv->BtEdcaDL = 0x5eb82b; + + pbtpriv->BT_EDCA[UP_LINK] = 0x5eb82b; + pbtpriv->BT_EDCA[DOWN_LINK] = 0x5eb82b; + + DBG_8192C("BT set parameter(0x%x) = 0x%x\n", REG_EDCA_BE_PARAM, 0x5eb82b); + } + } + else + { + // BT coexistence mechanism does not control EDCA parameter. + //pbtpriv->BtEdcaUL = 0; + //pbtpriv->BtEdcaDL = 0; + + pbtpriv->BT_EDCA[UP_LINK] = 0; + pbtpriv->BT_EDCA[DOWN_LINK] = 0; + } + + // 20100415 Joseph: Set RF register 0x1E and 0x1F for BT coexist suggested by Yaying. + if(pbtpriv->BT_Service!=BT_Idle) + { + DBG_8192C("BT Set RfReg0x1E[7:4] = 0x%x \n", 0xf); + PHY_SetRFReg(Adapter, PathA, 0x1e, 0xf0, 0xf); + //RTPRINT(FBT, BT_TRACE, ("BT Set RfReg0x1E[7:4] = 0x%x \n", 0xf)); + //PHY_SetRFReg(Adapter, PathA, 0x1f, 0xf0, 0xf); + } + else + { + DBG_8192C("BT Set RfReg0x1E[7:4] = 0x%x \n",pbtpriv->BtRfRegOrigin1E); + PHY_SetRFReg(Adapter, PathA, 0x1e, 0xf0, pbtpriv->BtRfRegOrigin1E); + //RTPRINT(FBT, BT_TRACE, ("BT Set RfReg0x1F[7:4] = 0x%x \n", pHalData->bt_coexist.BtRfRegOrigin1F)); + //PHY_SetRFReg(Adapter, PathA, 0x1f, 0xf0, pHalData->bt_coexist.BtRfRegOrigin1F); + } + } + else + { + DBG_8192C("BT_IsolationHigh\n"); + // Do nothing. + } + } + else + { + + if(pbtpriv->BT_Ampdu && !pmlmeinfo->bAcceptAddbaReq) + { + DBG_8192C("BT_Allow AMPDU bt is off\n"); + pmlmeinfo->bAcceptAddbaReq = _TRUE; + } + + DBG_8192C("BT_Turn OFF Coexist bt is off \n"); + rtw_write8(Adapter, REG_GPIO_MUXCFG, 0x00); + + DBG_8192C("BT Set RfReg0x1E[7:4] = 0x%x \n", pbtpriv->BtRfRegOrigin1E); + PHY_SetRFReg(Adapter, PathA, 0x1e, 0xf0, pbtpriv->BtRfRegOrigin1E); + //RTPRINT(FBT, BT_TRACE, ("BT Set RfReg0x1F[7:4] = 0x%x \n", pHalData->bt_coexist.BtRfRegOrigin1F)); + //PHY_SetRFReg(Adapter, PathA, 0x1f, 0xf0, pHalData->bt_coexist.BtRfRegOrigin1F); + + // BT coexistence mechanism does not control EDCA parameter since BT is disabled. + //pbtpriv->BtEdcaUL = 0; + //pbtpriv->BtEdcaDL = 0; + pbtpriv->BT_EDCA[UP_LINK] = 0; + pbtpriv->BT_EDCA[DOWN_LINK] = 0; + + +// 20100427 Joseph: Do not adjust Rate adaptive for BT coexist suggested by SD3. +#if 0 + RTPRINT(FBT, BT_TRACE, ("BT_Update Rate table\n")); + if(pMgntInfo->bUseRAMask) + { + // 20100407 Joseph: Fix rate adaptive modification for BT coexist. + // This fix is not complete yet. It shall also consider VWifi and Adhoc case, + // which connect with multiple STAs. + Adapter->HalFunc.UpdateHalRAMaskHandler( + Adapter, + FALSE, + 0, + NULL, + NULL, + pMgntInfo->RateAdaptive.RATRState, + RAMask_Normal); + } + else + { + Adapter->HalFunc.UpdateHalRATRTableHandler( + Adapter, + &pMgntInfo->dot11OperationalRateSet, + pMgntInfo->dot11HTOperationalRateSet,NULL); + } +#endif + } + } + } +} + +static void dm_InitBtCoexistDM( PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + + if( !pbtpriv->BT_Coexist ) return; + + pbtpriv->BtRfRegOrigin1E = (u8)PHY_QueryRFReg(Adapter, PathA, 0x1e, 0xf0); + pbtpriv->BtRfRegOrigin1F = (u8)PHY_QueryRFReg(Adapter, PathA, 0x1f, 0xf0); +} + +void rtl8192c_set_dm_bt_coexist(_adapter *padapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + + pbtpriv->bCOBT = bStart; + send_delba(padapter,0, get_my_bssid(&(pmlmeinfo->network))); + send_delba(padapter,1, get_my_bssid(&(pmlmeinfo->network))); + +} + +void rtl8192c_issue_delete_ba(_adapter *padapter, u8 dir) +{ + struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; + DBG_8192C("issue_delete_ba : %s...\n",(dir==0)?"RX_DIR":"TX_DIR"); + send_delba(padapter,dir, get_my_bssid(&(pmlmeinfo->network))); +} + +#endif + +#if 0//def CONFIG_PCI_HCI + +BOOLEAN +BT_BTStateChange( + IN PADAPTER Adapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + u4Byte temp, Polling, Ratio_Tx, Ratio_PRI; + u4Byte BT_Tx, BT_PRI; + u1Byte BT_State; + static u1Byte ServiceTypeCnt = 0; + u1Byte CurServiceType; + static u1Byte LastServiceType = BT_Idle; + + if(!pMgntInfo->bMediaConnect) + return FALSE; + + BT_State = PlatformEFIORead1Byte(Adapter, 0x4fd); +/* + temp = PlatformEFIORead4Byte(Adapter, 0x488); + BT_Tx = (u2Byte)(((temp<<8)&0xff00)+((temp>>8)&0xff)); + BT_PRI = (u2Byte)(((temp>>8)&0xff00)+((temp>>24)&0xff)); + + temp = PlatformEFIORead4Byte(Adapter, 0x48c); + Polling = ((temp<<8)&0xff000000) + ((temp>>8)&0x00ff0000) + + ((temp<<8)&0x0000ff00) + ((temp>>8)&0x000000ff); + +*/ + BT_Tx = PlatformEFIORead4Byte(Adapter, 0x488); + + RTPRINT(FBT, BT_TRACE, ("Ratio 0x488 =%x\n", BT_Tx)); + BT_Tx =BT_Tx & 0x00ffffff; + //RTPRINT(FBT, BT_TRACE, ("Ratio BT_Tx =%x\n", BT_Tx)); + + BT_PRI = PlatformEFIORead4Byte(Adapter, 0x48c); + + RTPRINT(FBT, BT_TRACE, ("Ratio Ratio 0x48c =%x\n", BT_PRI)); + BT_PRI =BT_PRI & 0x00ffffff; + //RTPRINT(FBT, BT_TRACE, ("Ratio BT_PRI =%x\n", BT_PRI)); + + + Polling = PlatformEFIORead4Byte(Adapter, 0x490); + //RTPRINT(FBT, BT_TRACE, ("Ratio 0x490 =%x\n", Polling)); + + + if(BT_Tx==0xffffffff && BT_PRI==0xffffffff && Polling==0xffffffffff && BT_State==0xff) + return FALSE; + + BT_State &= BIT0; + + if(BT_State != pHalData->bt_coexist.BT_CUR_State) + { + pHalData->bt_coexist.BT_CUR_State = BT_State; + + if(pMgntInfo->bRegBT_Sco == 3) + { + ServiceTypeCnt = 0; + + pHalData->bt_coexist.BT_Service = BT_Idle; + + RTPRINT(FBT, BT_TRACE, ("BT_%s\n", BT_State?"ON":"OFF")); + + BT_State = BT_State | + ((pHalData->bt_coexist.BT_Ant_isolation==1)?0:BIT1) |BIT2; + + PlatformEFIOWrite1Byte(Adapter, 0x4fd, BT_State); + RTPRINT(FBT, BT_TRACE, ("BT set 0x4fd to %x\n", BT_State)); + } + + return TRUE; + } + RTPRINT(FBT, BT_TRACE, ("bRegBT_Sco %d\n", pMgntInfo->bRegBT_Sco)); + + Ratio_Tx = BT_Tx*1000/Polling; + Ratio_PRI = BT_PRI*1000/Polling; + + pHalData->bt_coexist.Ratio_Tx=Ratio_Tx; + pHalData->bt_coexist.Ratio_PRI=Ratio_PRI; + + RTPRINT(FBT, BT_TRACE, ("Ratio_Tx=%d\n", Ratio_Tx)); + RTPRINT(FBT, BT_TRACE, ("Ratio_PRI=%d\n", Ratio_PRI)); + + + if(BT_State && pMgntInfo->bRegBT_Sco==3) + { + RTPRINT(FBT, BT_TRACE, ("bRegBT_Sco ==3 Follow Counter\n")); +// if(BT_Tx==0xffff && BT_PRI==0xffff && Polling==0xffffffff) +// { +// ServiceTypeCnt = 0; +// return FALSE; +// } +// else + { + /* + Ratio_Tx = BT_Tx*1000/Polling; + Ratio_PRI = BT_PRI*1000/Polling; + + pHalData->bt_coexist.Ratio_Tx=Ratio_Tx; + pHalData->bt_coexist.Ratio_PRI=Ratio_PRI; + + RTPRINT(FBT, BT_TRACE, ("Ratio_Tx=%d\n", Ratio_Tx)); + RTPRINT(FBT, BT_TRACE, ("Ratio_PRI=%d\n", Ratio_PRI)); + + */ + if((Ratio_Tx <= 50) && (Ratio_PRI <= 50)) + CurServiceType = BT_Idle; + else if((Ratio_PRI > 150) && (Ratio_PRI < 200)) + CurServiceType = BT_SCO; + else if((Ratio_Tx >= 200)&&(Ratio_PRI >= 200)) + CurServiceType = BT_Busy; + else if(Ratio_Tx >= 350) + CurServiceType = BT_OtherBusy; + else + CurServiceType=BT_OtherAction; + + } +/* if(pHalData->bt_coexist.bStopCount) + { + ServiceTypeCnt=0; + pHalData->bt_coexist.bStopCount=FALSE; + } +*/ + if(CurServiceType == BT_OtherBusy) + { + ServiceTypeCnt=2; + LastServiceType=CurServiceType; + } + else if(CurServiceType == LastServiceType) + { + if(ServiceTypeCnt<3) + ServiceTypeCnt++; + } + else + { + ServiceTypeCnt = 0; + LastServiceType = CurServiceType; + } + + if(ServiceTypeCnt==2) + { + pHalData->bt_coexist.BT_Service = LastServiceType; + BT_State = BT_State | + ((pHalData->bt_coexist.BT_Ant_isolation==1)?0:BIT1) | + ((pHalData->bt_coexist.BT_Service==BT_SCO)?0:BIT2); + + if(pHalData->bt_coexist.BT_Service==BT_Busy) + BT_State&= ~(BIT2); + + if(pHalData->bt_coexist.BT_Service==BT_SCO) + { + RTPRINT(FBT, BT_TRACE, ("BT TYPE Set to ==> BT_SCO\n")); + } + else if(pHalData->bt_coexist.BT_Service==BT_Idle) + { + RTPRINT(FBT, BT_TRACE, ("BT TYPE Set to ==> BT_Idle\n")); + } + else if(pHalData->bt_coexist.BT_Service==BT_OtherAction) + { + RTPRINT(FBT, BT_TRACE, ("BT TYPE Set to ==> BT_OtherAction\n")); + } + else if(pHalData->bt_coexist.BT_Service==BT_Busy) + { + RTPRINT(FBT, BT_TRACE, ("BT TYPE Set to ==> BT_Busy\n")); + } + else + { + RTPRINT(FBT, BT_TRACE, ("BT TYPE Set to ==> BT_OtherBusy\n")); + } + + //Add interrupt migration when bt is not in idel state (no traffic). + //suggestion by Victor. + if(pHalData->bt_coexist.BT_Service!=BT_Idle) + { + + PlatformEFIOWrite2Byte(Adapter, 0x504, 0x0ccc); + PlatformEFIOWrite1Byte(Adapter, 0x506, 0x54); + PlatformEFIOWrite1Byte(Adapter, 0x507, 0x54); + + } + else + { + PlatformEFIOWrite1Byte(Adapter, 0x506, 0x00); + PlatformEFIOWrite1Byte(Adapter, 0x507, 0x00); + } + + PlatformEFIOWrite1Byte(Adapter, 0x4fd, BT_State); + RTPRINT(FBT, BT_TRACE, ("BT_SCO set 0x4fd to %x\n", BT_State)); + return TRUE; + } + } + + return FALSE; + +} + +BOOLEAN +BT_WifiConnectChange( + IN PADAPTER Adapter + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + static BOOLEAN bMediaConnect = FALSE; + + if(!pMgntInfo->bMediaConnect || MgntRoamingInProgress(pMgntInfo)) + { + bMediaConnect = FALSE; + } + else + { + if(!bMediaConnect) + { + bMediaConnect = TRUE; + return TRUE; + } + bMediaConnect = TRUE; + } + + return FALSE; +} + +BOOLEAN +BT_RSSIChangeWithAMPDU( + IN PADAPTER Adapter + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(!Adapter->pNdisCommon->bRegBT_Ampdu || !Adapter->pNdisCommon->bRegAcceptAddbaReq) + return FALSE; + + RTPRINT(FBT, BT_TRACE, ("RSSI is %d\n",pHalData->UndecoratedSmoothedPWDB)); + + if((pHalData->UndecoratedSmoothedPWDB<=32) && pMgntInfo->pHTInfo->bAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Disallow AMPDU RSSI <=32 Need change\n")); + return TRUE; + + } + else if((pHalData->UndecoratedSmoothedPWDB>=40) && !pMgntInfo->pHTInfo->bAcceptAddbaReq ) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU RSSI >=40, Need change\n")); + return TRUE; + } + else + return FALSE; + +} + + +VOID +dm_BTCoexist( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + static u1Byte LastTxPowerLvl = 0xff; + PRX_TS_RECORD pRxTs = NULL; + + BOOLEAN bWifiConnectChange, bBtStateChange,bRSSIChangeWithAMPDU; + + if( (pHalData->bt_coexist.BluetoothCoexist) && + (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4) && + (!ACTING_AS_AP(Adapter)) ) + { + bWifiConnectChange = BT_WifiConnectChange(Adapter); + bBtStateChange = BT_BTStateChange(Adapter); + bRSSIChangeWithAMPDU = BT_RSSIChangeWithAMPDU(Adapter); + RTPRINT(FBT, BT_TRACE, ("bWifiConnectChange %d, bBtStateChange %d,LastTxPowerLvl %x, DynamicTxHighPowerLvl %x\n", + bWifiConnectChange,bBtStateChange,LastTxPowerLvl,pHalData->DynamicTxHighPowerLvl)); + if( bWifiConnectChange ||bBtStateChange || + (LastTxPowerLvl != pHalData->DynamicTxHighPowerLvl) ||bRSSIChangeWithAMPDU) + { + LastTxPowerLvl = pHalData->DynamicTxHighPowerLvl; + + if(pHalData->bt_coexist.BT_CUR_State) + { + // Do not allow receiving A-MPDU aggregation. + if((pHalData->bt_coexist.BT_Service==BT_SCO) || (pHalData->bt_coexist.BT_Service==BT_Busy)) + { + if(pHalData->UndecoratedSmoothedPWDB<=32) + { + if(Adapter->pNdisCommon->bRegBT_Ampdu && Adapter->pNdisCommon->bRegAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Disallow AMPDU RSSI <=32\n")); + pMgntInfo->pHTInfo->bAcceptAddbaReq = FALSE; + if(GetTs(Adapter, (PTS_COMMON_INFO*)(&pRxTs), pMgntInfo->Bssid, 0, RX_DIR, FALSE)) + TsInitDelBA(Adapter, (PTS_COMMON_INFO)pRxTs, RX_DIR); + } + } + else if(pHalData->UndecoratedSmoothedPWDB>=40) + { + if(Adapter->pNdisCommon->bRegBT_Ampdu && Adapter->pNdisCommon->bRegAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU RSSI >=40\n")); + pMgntInfo->pHTInfo->bAcceptAddbaReq = TRUE; + } + } + } + else + { + if(Adapter->pNdisCommon->bRegBT_Ampdu && Adapter->pNdisCommon->bRegAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU BT not in SCO or BUSY\n")); + pMgntInfo->pHTInfo->bAcceptAddbaReq = TRUE; + } + } + + if(pHalData->bt_coexist.BT_Ant_isolation) + { + RTPRINT(FBT, BT_TRACE, ("BT_IsolationLow\n")); + RTPRINT(FBT, BT_TRACE, ("BT_Update Rate table\n")); + Adapter->HalFunc.UpdateHalRATRTableHandler( + Adapter, + &pMgntInfo->dot11OperationalRateSet, + pMgntInfo->dot11HTOperationalRateSet,NULL); + + if(pHalData->bt_coexist.BT_Service==BT_SCO) + { + + RTPRINT(FBT, BT_TRACE, ("BT_Turn OFF Coexist with SCO \n")); + PlatformEFIOWrite1Byte(Adapter, REG_GPIO_MUXCFG, 0x14); + } + else if(pHalData->DynamicTxHighPowerLvl == TxHighPwrLevel_Normal) + { + RTPRINT(FBT, BT_TRACE, ("BT_Turn ON Coexist\n")); + PlatformEFIOWrite1Byte(Adapter, REG_GPIO_MUXCFG, 0xb4); + } + else + { + RTPRINT(FBT, BT_TRACE, ("BT_Turn OFF Coexist\n")); + PlatformEFIOWrite1Byte(Adapter, REG_GPIO_MUXCFG, 0x14); + } + } + else + { + RTPRINT(FBT, BT_TRACE, ("BT_IsolationHigh\n")); + // Do nothing. + } + } + else + { + if(Adapter->pNdisCommon->bRegBT_Ampdu && Adapter->pNdisCommon->bRegAcceptAddbaReq) + { + RTPRINT(FBT, BT_TRACE, ("BT_Allow AMPDU bt is off\n")); + pMgntInfo->pHTInfo->bAcceptAddbaReq = TRUE; + } + + RTPRINT(FBT, BT_TRACE, ("BT_Turn OFF Coexist bt is off \n")); + PlatformEFIOWrite1Byte(Adapter, REG_GPIO_MUXCFG, 0x14); + + RTPRINT(FBT, BT_TRACE, ("BT_Update Rate table\n")); + Adapter->HalFunc.UpdateHalRATRTableHandler( + Adapter, + &pMgntInfo->dot11OperationalRateSet, + pMgntInfo->dot11HTOperationalRateSet,NULL); + } + } + } +} +#endif + + +/*----------------------------------------------------------------------------- + * Function: dm_CheckRfCtrlGPIO() + * + * Overview: Copy 8187B template for 9xseries. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/10/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static VOID +dm_CheckRfCtrlGPIO( + IN PADAPTER Adapter + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +#if defined (CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) + #ifdef CONFIG_USB_HCI + // 2010/08/12 MH Add for CU selective suspend. + PRT_USB_DEVICE pDevice = GET_RT_USB_DEVICE(Adapter); + #else + PRT_SDIO_DEVICE pDevice = GET_RT_SDIO_DEVICE(Adapter); + #endif +#endif + + if(!Adapter->MgntInfo.PowerSaveControl.bGpioRfSw) + return; + + RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO \n")); + +#if defined (CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) + // Walk around for DTM test, we will not enable HW - radio on/off because r/w + // page 1 register before Lextra bus is enabled cause system fails when resuming + // from S4. 20080218, Emily + if(Adapter->bInHctTest) + return; + +//#if ((HAL_CODE_BASE == RTL8192_S) ) + //Adapter->HalFunc.GPIOChangeRFHandler(Adapter, GPIORF_POLLING); +//#else + // 2010/07/27 MH Only Minicard and support selective suspend, we can not turn off all MAC power to + // stop 8051. For dongle and minicard, we both support selective suspend mode. + //if(pDevice->RegUsbSS && Adapter->HalFunc.GetInterfaceSelectionHandler(Adapter) == INTF_SEL2_MINICARD) + + // + // 2010/08/12 MH We support severl power consumption combination as below. + // + // Power consumption combination + // SS Enable: (LPS disable + IPS + SW/HW radio off) + // 1. Dongle + PDN (support HW radio off) + // 2. Dongle + Normal (No HW radio off) + // 3. MiniCard + PDN (support HW radio off) + // 4. MiniCard + Normal (support HW radio off) + // + // SS Disable: (LPS + IPS + SW/HW radio off) + // 1. Dongle + PDN (support HW radio off) + // 2. Dongle + Normal (No HW radio off) + // 3. MiniCard + PDN (support HW radio off) + // 4. MiniCard + Normal (support HW radio off) + // + // For Power down module detection. We need to read power register no matter + // dongle or minicard, we will add the item is the detection method. + // + // + //vivi add du case + if ((IS_HARDWARE_TYPE_8192CU(Adapter)||IS_HARDWARE_TYPE_8192DU(Adapter)) + && pDevice->RegUsbSS) + { + RT_TRACE(COMP_RF, DBG_LOUD, ("USB SS Enabled\n")); + if (SUPPORT_HW_RADIO_DETECT(Adapter)) + { // Support HW radio detection + RT_TRACE(COMP_RF, DBG_LOUD, ("USB Card Type 2/3/4 support GPIO Detect\n")); + GpioDetectTimerStart(Adapter); + } + else + { // Dongle does not support HW radio detection.?? In the fufure?? + RT_TRACE(COMP_RF, DBG_LOUD, ("USB DONGLE Non-GPIO-Detect\n")); + } + } + else if (IS_HARDWARE_TYPE_8192CU(Adapter) || + IS_HARDWARE_TYPE_8723AU(Adapter)|| + IS_HARDWARE_TYPE_8192DU(Adapter) || + IS_HARDWARE_TYPE_8723AS(Adapter)) + { // Not support Selective suspend + RT_TRACE(COMP_RF, DBG_LOUD, ("USB SS Disable\n")); + if (SUPPORT_HW_RADIO_DETECT(Adapter)) + { + RT_TRACE(COMP_RF, DBG_LOUD, ("USB Card Type 2/3/4 support GPIO Detect\n")); + PlatformScheduleWorkItem( &(pHalData->GPIOChangeRFWorkItem) ); + } + else + { + RT_TRACE(COMP_RF, DBG_LOUD, ("USB DONGLE Non-GPIO-Detect\n")); + } + } + else + { // CE only support noemal HW radio detection now. Support timers GPIO detection in SE/CU. + PlatformScheduleWorkItem( &(pHalData->GPIOChangeRFWorkItem) ); + } +//#endif +#else if defined CONFIG_PCI_HCI + if(Adapter->bInHctTest) + return; + + // CE only support noemal HW radio detection now. We support timers GPIO detection in SE. + PlatformScheduleWorkItem( &(pHalData->GPIOChangeRFWorkItem) ); +#endif +#endif +} /* dm_CheckRfCtrlGPIO */ + +static VOID +dm_InitRateAdaptiveMask( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PRATE_ADAPTIVE pRA = (PRATE_ADAPTIVE)&pdmpriv->RateAdaptive; + + pRA->RATRState = DM_RATR_STA_INIT; + pRA->PreRATRState = DM_RATR_STA_INIT; + + if (pdmpriv->DM_Type == DM_Type_ByDriver) + pdmpriv->bUseRAMask = _TRUE; + else + pdmpriv->bUseRAMask = _FALSE; +} + +/*----------------------------------------------------------------------------- + * Function: dm_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. + * + *---------------------------------------------------------------------------*/ +static VOID +dm_RefreshRateAdaptiveMask( IN PADAPTER pAdapter) +{ +#if 0 + PADAPTER pTargetAdapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMGNT_INFO pMgntInfo = &(ADJUST_TO_ADAPTIVE_ADAPTER(pAdapter, TRUE)->MgntInfo); + PRATE_ADAPTIVE pRA = (PRATE_ADAPTIVE)&pMgntInfo->RateAdaptive; + u4Byte LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; + + if(pAdapter->bDriverStopped) + { + RT_TRACE(COMP_RATR, DBG_TRACE, ("<---- dm_RefreshRateAdaptiveMask(): driver is going to unload\n")); + return; + } + + if(!pMgntInfo->bUseRAMask) + { + RT_TRACE(COMP_RATR, DBG_LOUD, ("<---- dm_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(pAdapter->MgntInfo.mAssoc && (!ACTING_AS_AP(pAdapter))) + { + + // decide rastate according to rssi + switch (pRA->PreRATRState) + { + case DM_RATR_STA_HIGH: + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 20; + break; + + case DM_RATR_STA_MIDDLE: + HighRSSIThreshForRA = 55; + LowRSSIThreshForRA = 20; + break; + + case DM_RATR_STA_LOW: + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 25; + break; + + default: + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 20; + break; + } + + if(pHalData->UndecoratedSmoothedPWDB > (s4Byte)HighRSSIThreshForRA) + pRA->RATRState = DM_RATR_STA_HIGH; + else if(pHalData->UndecoratedSmoothedPWDB > (s4Byte)LowRSSIThreshForRA) + pRA->RATRState = DM_RATR_STA_MIDDLE; + else + pRA->RATRState = DM_RATR_STA_LOW; + + if(pRA->PreRATRState != pRA->RATRState) + { + RT_PRINT_ADDR(COMP_RATR, DBG_LOUD, ("Target AP addr : "), pMgntInfo->Bssid); + RT_TRACE(COMP_RATR, DBG_LOUD, ("RSSI = %d\n", pHalData->UndecoratedSmoothedPWDB)); + RT_TRACE(COMP_RATR, DBG_LOUD, ("RSSI_LEVEL = %d\n", pRA->RATRState)); + RT_TRACE(COMP_RATR, DBG_LOUD, ("PreState = %d, CurState = %d\n", pRA->PreRATRState, pRA->RATRState)); + pAdapter->HalFunc.UpdateHalRAMaskHandler( + pAdapter, + FALSE, + 0, + NULL, + NULL, + pRA->RATRState); + pRA->PreRATRState = pRA->RATRState; + } + } + + // + // The following part configure AP/VWifi/IBSS rate adaptive mask. + // + if(ACTING_AS_AP(pAdapter) || ACTING_AS_IBSS(pAdapter)) + { + pTargetAdapter = pAdapter; + } + else + { + pTargetAdapter = ADJUST_TO_ADAPTIVE_ADAPTER(pAdapter, FALSE); + if(!ACTING_AS_AP(pTargetAdapter)) + pTargetAdapter = NULL; + } + + // if extension port (softap) is started, updaet RA table for more than one clients associate + if(pTargetAdapter != NULL) + { + int i; + PRT_WLAN_STA pEntry; + PRATE_ADAPTIVE pEntryRA; + + for(i = 0; i < ASSOCIATE_ENTRY_NUM; i++) + { + if( pTargetAdapter->MgntInfo.AsocEntry[i].bUsed && pTargetAdapter->MgntInfo.AsocEntry[i].bAssociated) + { + pEntry = pTargetAdapter->MgntInfo.AsocEntry+i; + pEntryRA = &pEntry->RateAdaptive; + + switch (pEntryRA->PreRATRState) + { + case DM_RATR_STA_HIGH: + { + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 20; + } + break; + + case DM_RATR_STA_MIDDLE: + { + HighRSSIThreshForRA = 55; + LowRSSIThreshForRA = 20; + } + break; + + case DM_RATR_STA_LOW: + { + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 25; + } + break; + + default: + { + HighRSSIThreshForRA = 50; + LowRSSIThreshForRA = 20; + } + } + + if(pEntry->rssi_stat.UndecoratedSmoothedPWDB > (s4Byte)HighRSSIThreshForRA) + pEntryRA->RATRState = DM_RATR_STA_HIGH; + else if(pEntry->rssi_stat.UndecoratedSmoothedPWDB > (s4Byte)LowRSSIThreshForRA) + pEntryRA->RATRState = DM_RATR_STA_MIDDLE; + else + pEntryRA->RATRState = DM_RATR_STA_LOW; + + if(pEntryRA->PreRATRState != pEntryRA->RATRState) + { + RT_PRINT_ADDR(COMP_RATR, DBG_LOUD, ("AsocEntry addr : "), pEntry->MacAddr); + RT_TRACE(COMP_RATR, DBG_LOUD, ("RSSI = %d\n", pEntry->rssi_stat.UndecoratedSmoothedPWDB)); + RT_TRACE(COMP_RATR, DBG_LOUD, ("RSSI_LEVEL = %d\n", pEntryRA->RATRState)); + RT_TRACE(COMP_RATR, DBG_LOUD, ("PreState = %d, CurState = %d\n", pEntryRA->PreRATRState, pEntryRA->RATRState)); + pAdapter->HalFunc.UpdateHalRAMaskHandler( + pTargetAdapter, + FALSE, + pEntry->AID+1, + pEntry->MacAddr, + pEntry, + pEntryRA->RATRState); + pEntryRA->PreRATRState = pEntryRA->RATRState; + } + + } + } + } +#endif +} + +static VOID +dm_CheckProtection( + IN PADAPTER Adapter + ) +{ +#if 0 + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u1Byte CurRate, RateThreshold; + + if(pMgntInfo->pHTInfo->bCurBW40MHz) + RateThreshold = MGN_MCS1; + else + RateThreshold = MGN_MCS3; + + if(Adapter->TxStats.CurrentInitTxRate <= RateThreshold) + { + pMgntInfo->bDmDisableProtect = TRUE; + DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate); + } + else + { + pMgntInfo->bDmDisableProtect = FALSE; + DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate); + } +#endif +} + +static VOID +dm_CheckStatistics( + IN PADAPTER Adapter + ) +{ +#if 0 + if(!Adapter->MgntInfo.bMediaConnect) + return; + + //2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly. + rtw_hal_get_hwreg( Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate) ); + + // Calculate current Tx Rate(Successful transmited!!) + + // Calculate current Rx Rate(Successful received!!) + + //for tx tx retry count + rtw_hal_get_hwreg( Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount) ); +#endif +} + +static void dm_CheckPbcGPIO(_adapter *padapter) +{ + u8 tmp1byte; + u8 bPbcPressed = _FALSE; + int i=0; + + if(!padapter->registrypriv.hw_wps_pbc) + return; + + do + { + i++; +#ifdef CONFIG_USB_HCI + tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); + tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as output mode + + tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IN, tmp1byte); //reset the floating voltage level + + tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); + tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); //enable GPIO[2] as input mode + + tmp1byte =rtw_read8(padapter, GPIO_IN); + + if (tmp1byte == 0xff) + { + bPbcPressed = _FALSE; + break ; + } + + if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT) + { + bPbcPressed = _TRUE; + + if(i<=3) + rtw_msleep_os(50); + } +#else + tmp1byte = rtw_read8(padapter, GPIO_IN); + //RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte)); + + if (tmp1byte == 0xff || padapter->init_adpt_in_progress) + { + bPbcPressed = _FALSE; + break ; + } + + if((tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)==0) + { + bPbcPressed = _TRUE; + + if(i<=3) + rtw_msleep_os(50); + } +#endif + + }while(i<=3 && bPbcPressed == _TRUE); + + if( _TRUE == bPbcPressed) + { + // Here we only set bPbcPressed to true + // After trigger PBC, the variable will be set to false + DBG_8192C("CheckPbcGPIO - PBC is pressed, try_cnt=%d\n", i-1); + +#ifdef RTK_DMP_PLATFORM +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC); +#endif +#else + + if ( padapter->pid[0] == 0 ) + { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. + return; + } + +#ifdef PLATFORM_LINUX + rtw_signal_process(padapter->pid[0], SIGUSR1); +#endif +#endif + } +} + +#ifdef CONFIG_PCI_HCI +// +// Description: +// Perform interrupt migration dynamically to reduce CPU utilization. +// +// Assumption: +// 1. Do not enable migration under WIFI test. +// +// Created by Roger, 2010.03.05. +// +VOID +dm_InterruptMigration( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + BOOLEAN bCurrentIntMt, bCurrentACIntDisable; + BOOLEAN IntMtToSet = _FALSE; + BOOLEAN ACIntToSet = _FALSE; + + + // Retrieve current interrupt migration and Tx four ACs IMR settings first. + bCurrentIntMt = pHalData->bInterruptMigration; + bCurrentACIntDisable = pHalData->bDisableTxInt; + + // + // Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics + // when interrupt migration is set before. 2010.03.05. + // + if(!Adapter->registrypriv.wifi_spec && + (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && + pmlmepriv->LinkDetectInfo.bHigherBusyTraffic) + { + IntMtToSet = _TRUE; + + // To check whether we should disable Tx interrupt or not. + if(pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic ) + ACIntToSet = _TRUE; + } + + //Update current settings. + if( bCurrentIntMt != IntMtToSet ){ + DBG_8192C("%s(): Update interrrupt migration(%d)\n",__FUNCTION__,IntMtToSet); + if(IntMtToSet) + { + // + // Set interrrupt migration timer and corresponging Tx/Rx counter. + // timer 25ns*0xfa0=100us for 0xf packets. + // 2010.03.05. + // + rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);// 0x306:Rx, 0x307:Tx + pHalData->bInterruptMigration = IntMtToSet; + } + else + { + // Reset all interrupt migration settings. + rtw_write32(Adapter, REG_INT_MIG, 0); + pHalData->bInterruptMigration = IntMtToSet; + } + } + + /*if( bCurrentACIntDisable != ACIntToSet ){ + DBG_8192C("%s(): Update AC interrrupt(%d)\n",__FUNCTION__,ACIntToSet); + if(ACIntToSet) // Disable four ACs interrupts. + { + // + // Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization. + // When extremely highly Rx OK occurs, we will disable Tx interrupts. + // 2010.03.05. + // + UpdateInterruptMask8192CE( Adapter, 0, RT_AC_INT_MASKS ); + pHalData->bDisableTxInt = ACIntToSet; + } + else// Enable four ACs interrupts. + { + UpdateInterruptMask8192CE( Adapter, RT_AC_INT_MASKS, 0 ); + pHalData->bDisableTxInt = ACIntToSet; + } + }*/ + +} + +#endif + +// +// Initialize GPIO setting registers +// +static void +dm_InitGPIOSetting( + IN PADAPTER Adapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + u8 tmp1byte; + + tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG); + tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT); + +#ifdef CONFIG_BT_COEXIST + // UMB-B cut bug. We need to support the modification. + if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID) && + pHalData->bt_coexist.BT_Coexist) + { + tmp1byte |= (BIT5); + } +#endif + rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte); + +} + +static void update_EDCA_param(_adapter *padapter) +{ + u32 trafficIndex; + u32 edca_param; + u64 cur_tx_bytes = 0; + u64 cur_rx_bytes = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct recv_priv *precvpriv = &(padapter->recvpriv); + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + u8 bbtchange = _FALSE; +#endif + + + //DBG_871X("%s\n", __FUNCTION__); + + //associated AP + if ((pregpriv->wifi_spec == 1) || (pmlmeinfo->HT_enable == 0)) + { + return; + } + + if (pmlmeinfo->assoc_AP_vendor >= maxAP) + { + return; + } + + cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; + cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; + + //traffic, TX or RX + if((pmlmeinfo->assoc_AP_vendor == ralinkAP)||(pmlmeinfo->assoc_AP_vendor == atherosAP)) + { + 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; + } + } + +#ifdef CONFIG_BT_COEXIST + if(pbtpriv->BT_Coexist) + { + if( (pbtpriv->BT_EDCA[UP_LINK]!=0) || (pbtpriv->BT_EDCA[DOWN_LINK]!=0)) + { + bbtchange = _TRUE; + } + } +#endif + + if (pdmpriv->prv_traffic_idx != trafficIndex) + { +#if 0 +#ifdef CONFIG_BT_COEXIST + if(_TRUE == bbtchange) + rtw_write32(padapter, REG_EDCA_BE_PARAM, pbtpriv->BT_EDCA[trafficIndex]); + else +#endif + //adjust EDCA parameter for BE queue + //fire_write_MAC_cmd(padapter, EDCA_BE_PARAM, EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]); + rtw_write32(padapter, REG_EDCA_BE_PARAM, EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]); + +#else + if((pmlmeinfo->assoc_AP_vendor == ciscoAP) && (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) + { + edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; + } + else if((pmlmeinfo->assoc_AP_vendor == airgocapAP) && + ((pmlmeext->cur_wireless_mode == WIRELESS_11G) ||(pmlmeext->cur_wireless_mode == WIRELESS_11BG))) + { + edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; + } + else + { + edca_param = EDCAParam[unknownAP][trafficIndex]; + } + +#ifdef CONFIG_BT_COEXIST + if(_TRUE == bbtchange) + edca_param = pbtpriv->BT_EDCA[trafficIndex]; +#endif + + rtw_write32(padapter, REG_EDCA_BE_PARAM, edca_param); +#endif + pdmpriv->prv_traffic_idx = trafficIndex; + } + +//exit_update_EDCA_param: + + pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes; + precvpriv->last_rx_bytes = precvpriv->rx_bytes; + + return; +} + +static void dm_InitDynamicBBPowerSaving( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PS_T *pPSTable = &pdmpriv->DM_PSTable; + + pPSTable->PreCCAState = CCA_MAX; + pPSTable->CurCCAState = CCA_MAX; + pPSTable->PreRFState = RF_MAX; + pPSTable->CurRFState = RF_MAX; + pPSTable->Rssi_val_min = 0; +} + +static void dm_1R_CCA( + IN PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PS_T *pPSTable = &pdmpriv->DM_PSTable; + + if(pPSTable->Rssi_val_min != 0) + { + if(pPSTable->PreCCAState == CCA_2R) + { + if(pPSTable->Rssi_val_min >= 35) + pPSTable->CurCCAState = CCA_1R; + else + pPSTable->CurCCAState = CCA_2R; + } + else{ + if(pPSTable->Rssi_val_min <= 30) + pPSTable->CurCCAState = CCA_2R; + else + pPSTable->CurCCAState = CCA_1R; + } + } + else + pPSTable->CurCCAState=CCA_MAX; + + if(pPSTable->PreCCAState != pPSTable->CurCCAState) + { + if(pPSTable->CurCCAState == CCA_1R) + { + if(pHalData->rf_type == RF_2T2R) + { + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable , bMaskByte0, 0x13); + PHY_SetBBReg(pAdapter, 0xe70, bMaskByte3, 0x20); + } + else + { + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable , bMaskByte0, 0x23); + PHY_SetBBReg(pAdapter, 0xe70, 0x7fc00000, 0x10c); // Set RegE70[30:22] = 9b'100001100 + } + } + else + { + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x33); + PHY_SetBBReg(pAdapter,0xe70, bMaskByte3, 0x63); + } + pPSTable->PreCCAState = pPSTable->CurCCAState; + } + //DBG_8192C("dm_1R_CCA(): CCAStage=%x\n", pPSTable->CurCCAState); +} + +void +rtl8192c_dm_RF_Saving( + IN PADAPTER pAdapter, + IN u8 bForceInNormal + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PS_T *pPSTable = &pdmpriv->DM_PSTable; + + if(pdmpriv->initialize == 0){ + pdmpriv->rf_saving_Reg874 = (PHY_QueryBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord)&0x1CC000)>>14; + pdmpriv->rf_saving_RegC70 = (PHY_QueryBBReg(pAdapter, rOFDM0_AGCParameter1, bMaskDWord)&BIT3)>>3; + pdmpriv->rf_saving_Reg85C = (PHY_QueryBBReg(pAdapter, rFPGA0_XCD_SwitchControl, bMaskDWord)&0xFF000000)>>24; + pdmpriv->rf_saving_RegA74 = (PHY_QueryBBReg(pAdapter, 0xa74, bMaskDWord)&0xF000)>>12; + //Reg818 = PHY_QueryBBReg(pAdapter, 0x818, bMaskDWord); + pdmpriv->initialize = 1; + } + + if(!bForceInNormal) + { + if(pPSTable->Rssi_val_min != 0) + { + + if(pPSTable->PreRFState == RF_Normal) + { + #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + if(pPSTable->Rssi_val_min >= 50) + #else + if(pPSTable->Rssi_val_min >= 30) + #endif + pPSTable->CurRFState = RF_Save; + else + pPSTable->CurRFState = RF_Normal; + } + else{ + #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + if(pPSTable->Rssi_val_min <= 45) + #else + if(pPSTable->Rssi_val_min <= 25) + #endif + pPSTable->CurRFState = RF_Normal; + else + pPSTable->CurRFState = RF_Save; + } + } + else + pPSTable->CurRFState=RF_MAX; + } + else + { + pPSTable->CurRFState = RF_Normal; + } + + if(pPSTable->PreRFState != pPSTable->CurRFState) + { + if(pPSTable->CurRFState == RF_Save) + { + PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW , 0x1C0000, 0x2); //Reg874[20:18]=3'b010 + PHY_SetBBReg(pAdapter, rOFDM0_AGCParameter1, BIT3, 0); //RegC70[3]=1'b0 + PHY_SetBBReg(pAdapter, rFPGA0_XCD_SwitchControl, 0xFF000000, 0x63); //Reg85C[31:24]=0x63 + PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, 0xC000, 0x2); //Reg874[15:14]=2'b10 + PHY_SetBBReg(pAdapter, 0xa74, 0xF000, 0x3); //RegA75[7:4]=0x3 + PHY_SetBBReg(pAdapter, 0x818, BIT28, 0x0); //Reg818[28]=1'b0 + PHY_SetBBReg(pAdapter, 0x818, BIT28, 0x1); //Reg818[28]=1'b1 + DBG_8192C("%s(): RF_Save\n", __FUNCTION__); + } + else + { + PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW , 0x1CC000, pdmpriv->rf_saving_Reg874); + PHY_SetBBReg(pAdapter, rOFDM0_AGCParameter1, BIT3, pdmpriv->rf_saving_RegC70); + PHY_SetBBReg(pAdapter, rFPGA0_XCD_SwitchControl, 0xFF000000, pdmpriv->rf_saving_Reg85C); + PHY_SetBBReg(pAdapter, 0xa74, 0xF000, pdmpriv->rf_saving_RegA74); + PHY_SetBBReg(pAdapter, 0x818, BIT28, 0x0); + DBG_8192C("%s(): RF_Normal\n", __FUNCTION__); + } + pPSTable->PreRFState = pPSTable->CurRFState; + } +} + +static void +dm_DynamicBBPowerSaving( +IN PADAPTER pAdapter + ) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PS_T *pPSTable = &pdmpriv->DM_PSTable; + + //1 1.Determine the minimum RSSI + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) && + (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) + { + pPSTable->Rssi_val_min = 0; + //RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any \n")); + } + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) // Default port + { + //if(ACTING_AS_AP(pAdapter) || pMgntInfo->mIbss) + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) //todo: AP Mode + { + pPSTable->Rssi_val_min = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, ("AP Client PWDB = 0x%lx \n", pPSTable->Rssi_val_min)); + } + else + { + pPSTable->Rssi_val_min = pdmpriv->UndecoratedSmoothedPWDB; + //RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, ("STA Default Port PWDB = 0x%lx \n", pPSTable->Rssi_val_min)); + } + } + else // associated entry pwdb + { + pPSTable->Rssi_val_min = pdmpriv->EntryMinUndecoratedSmoothedPWDB; + //RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, ("AP Ext Port PWDB = 0x%lx \n", pPSTable->Rssi_val_min)); + } + + //1 2.Power Saving for 92C + if(IS_92C_SERIAL(pHalData->VersionID)) + { + //dm_1R_CCA(pAdapter); + } + + // 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 to 600ns. + //1 3.Power Saving for 88C + else + { + rtl8192c_dm_RF_Saving(pAdapter, _FALSE); + } +} + + +#ifdef CONFIG_ANTENNA_DIVERSITY +// Add new function to reset the state of antenna diversity before link. +// +void SwAntDivResetBeforeLink8192C(IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + + pDM_SWAT_Table->SWAS_NoLink_State = 0; +} + +// Compare RSSI for deciding antenna +void SwAntDivCompare8192C(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if((0 != pHalData->AntDivCfg) && (!IS_92C_SERIAL(pHalData->VersionID)) ) + { + //DBG_8192C("update_network=> orgRSSI(%d)(%d),newRSSI(%d)(%d)\n",dst->Rssi,query_rx_pwr_percentage(dst->Rssi), + // src->Rssi,query_rx_pwr_percentage(src->Rssi)); + //select optimum_antenna for before linked =>For antenna diversity + if(dst->Rssi >= src->Rssi )//keep org parameter + { + src->Rssi = dst->Rssi; + src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna; + } + } +} + +// Add new function to reset the state of antenna diversity before link. +u8 SwAntDivBeforeLink8192C(IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + // Condition that does not need to use antenna diversity. + if(IS_92C_SERIAL(pHalData->VersionID) ||(pHalData->AntDivCfg==0)) + { + //DBG_8192C("SwAntDivBeforeLink8192C(): No AntDiv Mechanism.\n"); + return _FALSE; + } + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + pDM_SWAT_Table->SWAS_NoLink_State = 0; + return _FALSE; + } + // Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF. +/* + if(pHalData->eRFPowerState!=eRfOn || pMgntInfo->RFChangeInProgress || pMgntInfo->bMediaConnect) + { + + + RT_TRACE(COMP_SWAS, DBG_LOUD, + ("SwAntDivCheckBeforeLink8192C(): RFChangeInProgress(%x), eRFPowerState(%x)\n", + pMgntInfo->RFChangeInProgress, + pHalData->eRFPowerState)); + + pDM_SWAT_Table->SWAS_NoLink_State = 0; + + return FALSE; + } +*/ + + if(pDM_SWAT_Table->SWAS_NoLink_State == 0){ + //switch channel + pDM_SWAT_Table->SWAS_NoLink_State = 1; + pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==Antenna_A)?Antenna_B:Antenna_A; + + //PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, pDM_SWAT_Table->CurAntenna); + rtw_antenna_select_cmd(Adapter, pDM_SWAT_Table->CurAntenna, _FALSE); + //DBG_8192C("%s change antenna to ANT_( %s ).....\n",__FUNCTION__, (pDM_SWAT_Table->CurAntenna==Antenna_A)?"A":"B"); + return _TRUE; + } + else + { + pDM_SWAT_Table->SWAS_NoLink_State = 0; + return _FALSE; + } + + + +} +#endif +#ifdef CONFIG_SW_ANTENNA_DIVERSITY +// +// 20100514 Luke/Joseph: +// Add new function to reset antenna diversity state after link. +// +void +SwAntDivRestAfterLink8192C( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + + if(IS_92C_SERIAL(pHalData->VersionID) ||(pHalData->AntDivCfg==0)) + return; + + //DBG_8192C("======> SwAntDivRestAfterLink <========== \n"); + pHalData->RSSI_cnt_A= 0; + pHalData->RSSI_cnt_B= 0; + pHalData->RSSI_test = _FALSE; + + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->RSSI_Trying = 0; + pDM_SWAT_Table->SelectAntennaMap=0xAA; + pDM_SWAT_Table->CurAntenna = pHalData->CurAntenna; + pDM_SWAT_Table->PreAntenna = pHalData->CurAntenna; + + pdmpriv->lastTxOkCnt=0; + pdmpriv->lastRxOkCnt=0; + + pdmpriv->TXByteCnt_A=0; + pdmpriv->TXByteCnt_B=0; + pdmpriv->RXByteCnt_A=0; + pdmpriv->RXByteCnt_B=0; + pdmpriv->DoubleComfirm=0; + pdmpriv->TrafficLoad = TRAFFIC_LOW; + +} + + +// +// 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 dm_SW_AntennaSwitchCallback(). +// 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, dm_SW_AntennaSwitchCallback() 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. +// +static VOID +dm_SW_AntennaSwitch( + PADAPTER Adapter, + u8 Step +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + s32 curRSSI=100, RSSI_A, RSSI_B; + u64 curTxOkCnt, curRxOkCnt; + u64 CurByteCnt = 0, PreByteCnt = 0; + u8 nextAntenna = 0; + u8 Score_A=0, Score_B=0; + u8 i; + + // Condition that does not need to use antenna diversity. + if(IS_92C_SERIAL(pHalData->VersionID) ||(pHalData->AntDivCfg==0)) + { + //RT_TRACE(COMP_SWAS, DBG_LOUD, ("dm_SW_AntennaSwitch(): No AntDiv Mechanism.\n")); + return; + } + // If dynamic ant_div is disabled. + if(!(pdmpriv->DMFlag & DYNAMIC_FUNC_ANT_DIV) ) + { + return; + } + + if (check_fwstate(&Adapter->mlmepriv, _FW_LINKED) ==_FALSE) + return; +#if 0 //to do + // Radio off: Status reset to default and return. + if(pHalData->eRFPowerState==eRfOff) + { + SwAntDivRestAfterLink(Adapter); + return; + } +#endif + //DBG_8192C("\n............................ %s.........................\n",__FUNCTION__); + // 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 ) + { + SwAntDivRestAfterLink8192C(Adapter); + } + + + if(pDM_SWAT_Table->try_flag == 0xff) + { +#if 0 + // Select RSSI checking target + if(pMgntInfo->mAssoc && !ACTING_AS_AP(Adapter)) + { + // Target: Infrastructure mode AP. + pHalData->RSSI_target = NULL; + RT_TRACE(COMP_SWAS, DBG_LOUD, ("dm_SW_AntennaSwitch(): RSSI_target is DEF AP!\n")); + } + else + { + u8 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(ACTING_AS_AP(ADJUST_TO_ADAPTIVE_ADAPTER(Adapter, FALSE))) + { + // Target: VWIFI peer. + pTargetAdapter = ADJUST_TO_ADAPTIVE_ADAPTER(Adapter, FALSE); + } + + if(pTargetAdapter != NULL) + { + for(index=0; indexbAssociated) + break; + } + } + } + + if(pEntry == NULL) + { + SwAntDivRestAfterLink(Adapter); + RT_TRACE(COMP_SWAS, DBG_LOUD, ("dm_SW_AntennaSwitch(): No Link.\n")); + return; + } + else + { + pHalData->RSSI_target = pEntry; + RT_TRACE(COMP_SWAS, DBG_LOUD, ("dm_SW_AntennaSwitch(): RSSI_target is PEER STA\n")); + } + } + + +#endif + + pHalData->RSSI_cnt_A= 0; + pHalData->RSSI_cnt_B= 0; + pDM_SWAT_Table->try_flag = 0; + // DBG_8192C("dm_SW_AntennaSwitch(): Set try_flag to 0 prepare for peak!\n"); + return; + } + else + { + curTxOkCnt = Adapter->xmitpriv.tx_bytes - pdmpriv->lastTxOkCnt; + curRxOkCnt = Adapter->recvpriv.rx_bytes - pdmpriv->lastRxOkCnt; + + pdmpriv->lastTxOkCnt = Adapter->xmitpriv.tx_bytes ; + pdmpriv->lastRxOkCnt = Adapter->recvpriv.rx_bytes ; + + if(pDM_SWAT_Table->try_flag == 1) + { + if(pDM_SWAT_Table->CurAntenna == Antenna_A) + { + pdmpriv->TXByteCnt_A += curTxOkCnt; + pdmpriv->RXByteCnt_A += curRxOkCnt; + //DBG_8192C("##### TXByteCnt_A(%lld) , RXByteCnt_A(%lld) ####\n",pdmpriv->TXByteCnt_A,pdmpriv->RXByteCnt_A); + } + else + { + pdmpriv->TXByteCnt_B += curTxOkCnt; + pdmpriv->RXByteCnt_B += curRxOkCnt; + //DBG_8192C("##### TXByteCnt_B(%lld) , RXByteCnt_B(%lld) ####\n",pdmpriv->TXByteCnt_B,pdmpriv->RXByteCnt_B); + } + + nextAntenna = (pDM_SWAT_Table->CurAntenna == Antenna_A)? Antenna_B : Antenna_A; + pDM_SWAT_Table->RSSI_Trying--; + //DBG_8192C("RSSI_Trying = %d\n",pDM_SWAT_Table->RSSI_Trying); + + if(pDM_SWAT_Table->RSSI_Trying == 0) + { + CurByteCnt = (pDM_SWAT_Table->CurAntenna == Antenna_A)? (pdmpriv->TXByteCnt_A+pdmpriv->RXByteCnt_A) : (pdmpriv->TXByteCnt_B+pdmpriv->RXByteCnt_B); + PreByteCnt = (pDM_SWAT_Table->CurAntenna == Antenna_A)? (pdmpriv->TXByteCnt_B+pdmpriv->RXByteCnt_B) : (pdmpriv->TXByteCnt_A+pdmpriv->RXByteCnt_A); + + //DBG_8192C("CurByteCnt = %lld\n", CurByteCnt); + //DBG_8192C("PreByteCnt = %lld\n",PreByteCnt); + + if(pdmpriv->TrafficLoad == TRAFFIC_HIGH) + { + PreByteCnt = PreByteCnt*9; //normalize:Cur=90ms:Pre=10ms + } + else if(pdmpriv->TrafficLoad == TRAFFIC_LOW) + { + //CurByteCnt = CurByteCnt/2; + CurByteCnt = CurByteCnt>>1;//normalize:100ms:50ms + } + + + //DBG_8192C("After DIV=>CurByteCnt = %lld\n", CurByteCnt); + //DBG_8192C("PreByteCnt = %lld\n",PreByteCnt); + + 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 == Antenna_A)? RSSI_A : RSSI_B; + pDM_SWAT_Table->PreRSSI = (pDM_SWAT_Table->CurAntenna == Antenna_A)? RSSI_B : RSSI_A; + //DBG_8192C("Luke:PreRSSI = %d, CurRSSI = %d\n",pDM_SWAT_Table->PreRSSI, curRSSI); + //DBG_8192C("SWAS: preAntenna= %s, curAntenna= %s \n", + //(pDM_SWAT_Table->PreAntenna == Antenna_A?"A":"B"), (pDM_SWAT_Table->CurAntenna == Antenna_A?"A":"B")); + //DBG_8192C("Luke: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 + { + + 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 == Antenna_A)? RSSI_A : RSSI_B; + pDM_SWAT_Table->PreRSSI = (pDM_SWAT_Table->PreAntenna == Antenna_A)? RSSI_A : RSSI_B; + //DBG_8192C("Ekul:PreRSSI = %d, CurRSSI = %d\n", pDM_SWAT_Table->PreRSSI, curRSSI); + //DBG_8192C("SWAS: preAntenna= %s, curAntenna= %s \n", + //(pDM_SWAT_Table->PreAntenna == Antenna_A?"A":"B"), (pDM_SWAT_Table->CurAntenna == Antenna_A?"A":"B")); + + //DBG_8192C("Ekul: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_SWAS, DBG_LOUD, ("Ekul:curTxOkCnt = %d\n", curTxOkCnt)); + //RT_TRACE(COMP_SWAS, 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) + { + //DBG_8192C("SWAS: TestMode = TP_MODE\n"); + //DBG_8192C("TRY:CurByteCnt = %lld\n", CurByteCnt); + //DBG_8192C("TRY:PreByteCnt = %lld\n",PreByteCnt); + if(CurByteCnt < PreByteCnt) + { + if(pDM_SWAT_Table->CurAntenna == Antenna_A) + 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 == Antenna_A) + 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++; + } + //DBG_8192C("SelectAntennaMap=%x\n ",pDM_SWAT_Table->SelectAntennaMap); + //DBG_8192C("Score_A=%d, Score_B=%d\n", Score_A, Score_B); + + if(pDM_SWAT_Table->CurAntenna == Antenna_A) + { + nextAntenna = (Score_A > Score_B)?Antenna_A:Antenna_B; + } + else + { + nextAntenna = (Score_B > Score_A)?Antenna_B:Antenna_A; + } + //RT_TRACE(COMP_SWAS, DBG_LOUD, ("nextAntenna=%s\n",(nextAntenna==Antenna_A)?"A":"B")); + //RT_TRACE(COMP_SWAS, DBG_LOUD, ("preAntenna= %s, curAntenna= %s \n", + //(DM_SWAT_Table.PreAntenna == Antenna_A?"A":"B"), (DM_SWAT_Table.CurAntenna == Antenna_A?"A":"B"))); + + if(nextAntenna != pDM_SWAT_Table->CurAntenna) + { + //DBG_8192C("SWAS: Switch back to another antenna\n"); + } + else + { + //DBG_8192C("SWAS: current anntena is good\n"); + } + } + + if(pDM_SWAT_Table->TestMode == RSSI_MODE) + { + //DBG_8192C("SWAS: TestMode = RSSI_MODE\n"); + pDM_SWAT_Table->SelectAntennaMap=0xAA; + if(curRSSI < pDM_SWAT_Table->PreRSSI) //Current antenna is worse than previous antenna + { + //DBG_8192C("SWAS: Switch back to another antenna\n"); + nextAntenna = (pDM_SWAT_Table->CurAntenna == Antenna_A)? Antenna_B : Antenna_A; + } + else // current anntena is good + { + nextAntenna = pDM_SWAT_Table->CurAntenna; + //DBG_8192C("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; + pdmpriv->TXByteCnt_A = 0; + pdmpriv->TXByteCnt_B = 0; + pdmpriv->RXByteCnt_A = 0; + pdmpriv->RXByteCnt_B = 0; + + } + + //1 Normal State + else if(pDM_SWAT_Table->try_flag == 0) + { + if(pdmpriv->TrafficLoad == TRAFFIC_HIGH) + { + if(((curTxOkCnt+curRxOkCnt)>>1) > 1875000) + pdmpriv->TrafficLoad = TRAFFIC_HIGH; + else + pdmpriv->TrafficLoad = TRAFFIC_LOW; + } + else if(pdmpriv->TrafficLoad == TRAFFIC_LOW) + { + if(((curTxOkCnt+curRxOkCnt)>>1) > 1875000) + pdmpriv->TrafficLoad = TRAFFIC_HIGH; + else + pdmpriv->TrafficLoad = TRAFFIC_LOW; + } + if(pdmpriv->TrafficLoad == TRAFFIC_HIGH) + pDM_SWAT_Table->bTriggerAntennaSwitch = 0; + //DBG_8192C("Normal:TrafficLoad = %lld\n", curTxOkCnt+curRxOkCnt); + + //Prepare To Try Antenna + nextAntenna = (pDM_SWAT_Table->CurAntenna == Antenna_A)? Antenna_B : Antenna_A; + pDM_SWAT_Table->try_flag = 1; + pHalData->RSSI_test = _TRUE; + if((curRxOkCnt+curTxOkCnt) > 1000) + { + pDM_SWAT_Table->RSSI_Trying = 4; + pDM_SWAT_Table->TestMode = TP_MODE; + } + else + { + pDM_SWAT_Table->RSSI_Trying = 2; + pDM_SWAT_Table->TestMode = RSSI_MODE; + + } + //DBG_8192C("SWAS: Normal State -> Begin Trying! TestMode=%s\n",(pDM_SWAT_Table->TestMode == TP_MODE)?"TP":"RSSI"); + + + pHalData->RSSI_sum_A = 0; + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_sum_B = 0; + pHalData->RSSI_cnt_B = 0; + } + } + + //1 4.Change TRX antenna + if(nextAntenna != pDM_SWAT_Table->CurAntenna) + { + //DBG_8192C("@@@@@@@@ SWAS: Change TX Antenna!\n "); + rtw_antenna_select_cmd(Adapter, nextAntenna, 1); + } + + //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(pdmpriv->TrafficLoad == TRAFFIC_HIGH) + { + _set_timer(&pdmpriv->SwAntennaSwitchTimer,10 ); //ms + //DBG_8192C("dm_SW_AntennaSwitch(): Test another antenna for 10 ms\n"); + } + else if(pdmpriv->TrafficLoad == TRAFFIC_LOW) + { + _set_timer(&pdmpriv->SwAntennaSwitchTimer, 50 ); //ms + //DBG_8192C("dm_SW_AntennaSwitch(): Test another antenna for 50 ms\n"); + } + } + else + { + _set_timer(&pdmpriv->SwAntennaSwitchTimer, 500 ); //ms + //DBG_8192C("dm_SW_AntennaSwitch(): Test another antenna for 500 ms\n"); + } + } + else + { + if(pDM_SWAT_Table->TestMode == TP_MODE) + { + if(pdmpriv->TrafficLoad == TRAFFIC_HIGH) + _set_timer(&pdmpriv->SwAntennaSwitchTimer,90 ); //ms + else if(pdmpriv->TrafficLoad == TRAFFIC_LOW) + _set_timer(&pdmpriv->SwAntennaSwitchTimer,100 ); //ms + } + else + { + _set_timer(&pdmpriv->SwAntennaSwitchTimer,500 ); //ms + //DBG_8192C("dm_SW_AntennaSwitch(): Test another antenna for 500 ms\n"); + } + } + +// RT_TRACE(COMP_SWAS, DBG_LOUD, ("SWAS: -----The End-----\n ")); + +} + +// +// 20100514 Luke/Joseph: +// Callback function for 500ms antenna test trying. +// +static void dm_SW_AntennaSwitchCallback(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + + if(padapter->net_closed == _TRUE) + return; + // Only + dm_SW_AntennaSwitch(padapter, SWAW_STEP_DETERMINE); +} + + +// +// 20100722 +// 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 SwAntDivRSSICheck8192C(_adapter *padapter ,u32 RxPWDBAll) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + + if(IS_92C_SERIAL(pHalData->VersionID) ||pHalData->AntDivCfg==0) + return; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + if(pDM_SWAT_Table->CurAntenna == Antenna_A) + { + pHalData->RSSI_sum_A += RxPWDBAll; + pHalData->RSSI_cnt_A++; + } + else + { + pHalData->RSSI_sum_B+= RxPWDBAll; + pHalData->RSSI_cnt_B++; + + } + //DBG_8192C("%s Ant_(%s),RSSI_sum(%d),RSSI_cnt(%d)\n",__FUNCTION__,(2==pHalData->CurAntenna)?"A":"B",pHalData->RSSI_sum,pHalData->RSSI_cnt); + } + +} + + + +static VOID +dm_SW_AntennaSwitchInit( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + SWAT_T *pDM_SWAT_Table = &pdmpriv->DM_SWAT_Table; + + pHalData->RSSI_sum_A = 0; + pHalData->RSSI_sum_B = 0; + pHalData->RSSI_cnt_A = 0; + pHalData->RSSI_cnt_B = 0; + + pDM_SWAT_Table->CurAntenna = pHalData->CurAntenna; + pDM_SWAT_Table->PreAntenna = pHalData->CurAntenna; + pDM_SWAT_Table->try_flag = 0xff; + pDM_SWAT_Table->PreRSSI = 0; + pDM_SWAT_Table->bTriggerAntennaSwitch = 0; + pDM_SWAT_Table->SelectAntennaMap=0xAA; + + // Move the timer initialization to InitializeVariables function. + //PlatformInitializeTimer(Adapter, &pMgntInfo->SwAntennaSwitchTimer, (RT_TIMER_CALL_BACK)dm_SW_AntennaSwitchCallback, NULL, "SwAntennaSwitchTimer"); +} + +#endif + +//#define RSSI_CCK 0 +//#define RSSI_OFDM 1 +static void dm_RSSIMonitorInit( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + pdmpriv->OFDM_Pkt_Cnt = 0; + pdmpriv->RSSI_Select = RSSI_DEFAULT; +} + +static void dm_RSSIMonitorCheck( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) + return; + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE |WIFI_ADHOC_STATE) == _TRUE ) + { + if(Adapter->stapriv.asoc_sta_count < 2) + return; + } + + if(pdmpriv->OFDM_Pkt_Cnt == 0) + pdmpriv->RSSI_Select = RSSI_CCK; + else + pdmpriv->RSSI_Select = RSSI_OFDM; + + pdmpriv->OFDM_Pkt_Cnt = 0; + //DBG_8192C("RSSI_Select=%s OFDM_Pkt_Cnt(%d)\n", + //(pdmpriv->RSSI_Select == RSSI_OFDM)?"RSSI_OFDM":"RSSI_CCK", + //pdmpriv->OFDM_Pkt_Cnt); +} + +//============================================================ +// functions +//============================================================ +void rtl8192c_init_dm_priv(IN PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + //_rtw_memset(pdmpriv, 0, sizeof(struct dm_priv)); + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + _init_timer(&(pdmpriv->SwAntennaSwitchTimer), Adapter->pnetdev , dm_SW_AntennaSwitchCallback, Adapter); +#endif +} + +void rtl8192c_deinit_dm_priv(IN PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + _cancel_timer_ex(&pdmpriv->SwAntennaSwitchTimer); +#endif +} +#ifdef CONFIG_HW_ANTENNA_DIVERSITY +void dm_InitHybridAntDiv(IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(IS_92C_SERIAL(pHalData->VersionID) ||pHalData->AntDivCfg==0) + return; + + //Set OFDM HW RX Antenna Diversity + PHY_SetBBReg(Adapter,0xc50, BIT7, 1); //Enable Hardware antenna switch + PHY_SetBBReg(Adapter,0x870, BIT9|BIT8, 0); //Enable hardware control of "ANT_SEL" & "ANT_SELB" + PHY_SetBBReg(Adapter,0xCA4, BIT11, 0); //Switch to another antenna by checking pwdb threshold + PHY_SetBBReg(Adapter,0xCA4, 0x7FF, 0x080); //Pwdb threshold=8dB + PHY_SetBBReg(Adapter,0xC54, BIT23, 1); //Decide final antenna by comparing 2 antennas' pwdb + PHY_SetBBReg(Adapter,0x874, BIT23, 0); //No update ANTSEL during GNT_BT=1 + PHY_SetBBReg(Adapter,0x80C, BIT21, 1); //TX atenna selection from tx_info + //Set CCK HW RX Antenna Diversity + PHY_SetBBReg(Adapter,0xA00, BIT15, 1);//Enable antenna diversity + PHY_SetBBReg(Adapter,0xA0C, BIT4, 0); //Antenna diversity decision period = 32 sample + PHY_SetBBReg(Adapter,0xA0C, 0xf, 0xf); //Threshold for antenna diversity. Check another antenna power if input power < ANT_lim*4 + PHY_SetBBReg(Adapter,0xA10, BIT13, 1); //polarity ana_A=1 and ana_B=0 + PHY_SetBBReg(Adapter,0xA14, 0x1f, 0x8); //default antenna power = inpwr*(0.5 + r_ant_step/16) + + pHalData->CCK_Ant1_Cnt = 0; + pHalData->CCK_Ant2_Cnt = 0; + pHalData->OFDM_Ant1_Cnt = 0; + pHalData->OFDM_Ant2_Cnt = 0; +} + + +#define RxDefaultAnt1 0x65a9 +#define RxDefaultAnt2 0x569a + +void dm_SelectRXDefault(IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(IS_92C_SERIAL(pHalData->VersionID) ||pHalData->AntDivCfg==0) + return; + + //DbgPrint(" Ant1_Cnt=%d, Ant2_Cnt=%d\n", pHalData->Ant1_Cnt, pHalData->Ant2_Cnt); + //DBG_8192C(" CCK_Ant1_Cnt = %d, CCK_Ant2_Cnt = %d\n", pHalData->CCK_Ant1_Cnt, pHalData->CCK_Ant2_Cnt); + //DBG_8192C(" OFDM_Ant1_Cnt = %d, OFDM_Ant2_Cnt = %d\n", pHalData->OFDM_Ant1_Cnt, pHalData->OFDM_Ant2_Cnt); + if((pHalData->OFDM_Ant1_Cnt == 0) && (pHalData->OFDM_Ant2_Cnt == 0)) + { + if((pHalData->CCK_Ant1_Cnt + pHalData->CCK_Ant2_Cnt) >=10 ) + { + if(pHalData->CCK_Ant1_Cnt > (5*pHalData->CCK_Ant2_Cnt)) + { + DBG_8192C(" RX Default = Ant1\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt1); + } + else if(pHalData->CCK_Ant2_Cnt > (5*pHalData->CCK_Ant1_Cnt)) + { + DBG_8192C(" RX Default = Ant2\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt2); + } + else if(pHalData->CCK_Ant1_Cnt > pHalData->CCK_Ant2_Cnt) + { + DBG_8192C(" RX Default = Ant2\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt2); + } + else + { + DBG_8192C(" RX Default = Ant1\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt1); + } + pHalData->CCK_Ant1_Cnt = 0; + pHalData->CCK_Ant2_Cnt = 0; + pHalData->OFDM_Ant1_Cnt = 0; + pHalData->OFDM_Ant2_Cnt = 0; + } + } + else + { + if(pHalData->OFDM_Ant1_Cnt > pHalData->OFDM_Ant2_Cnt) + { + DBG_8192C(" RX Default = Ant1\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt1); + } + else + { + DBG_8192C(" RX Default = Ant2\n"); + PHY_SetBBReg(Adapter, 0x858, 0xFFFF, RxDefaultAnt2); + } + pHalData->CCK_Ant1_Cnt = 0; + pHalData->CCK_Ant2_Cnt = 0; + pHalData->OFDM_Ant1_Cnt = 0; + pHalData->OFDM_Ant2_Cnt = 0; + } + + +} + +#endif + +void +rtl8192c_InitHalDm( + IN PADAPTER Adapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 i; + +#ifdef CONFIG_USB_HCI + dm_InitGPIOSetting(Adapter); +#endif + + pdmpriv->DM_Type = DM_Type_ByDriver; + pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE; + pdmpriv->UndecoratedSmoothedPWDB = (-1); + pdmpriv->UndecoratedSmoothedCCK = (-1); + + + //.1 DIG INIT + pdmpriv->bDMInitialGainEnable = _TRUE; + pdmpriv->DMFlag |= DYNAMIC_FUNC_DIG; + dm_DIGInit(Adapter); + + //.2 DynamicTxPower INIT + pdmpriv->DMFlag |= DYNAMIC_FUNC_HP; + dm_InitDynamicTxPower(Adapter); + + //.3 + DM_InitEdcaTurbo(Adapter); + + //.4 RateAdaptive INIT + dm_InitRateAdaptiveMask(Adapter); + + //.5 Tx Power Tracking Init. + pdmpriv->DMFlag |= DYNAMIC_FUNC_SS; + DM_InitializeTXPowerTracking(Adapter); + +#ifdef CONFIG_BT_COEXIST + pdmpriv->DMFlag |= DYNAMIC_FUNC_BT; + dm_InitBtCoexistDM(Adapter); +#endif + + dm_InitDynamicBBPowerSaving(Adapter); + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + pdmpriv->DMFlag |= DYNAMIC_FUNC_ANT_DIV; + dm_SW_AntennaSwitchInit(Adapter); +#endif + +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + pdmpriv->DMFlag |= DYNAMIC_FUNC_ANT_DIV; + dm_InitHybridAntDiv(Adapter); +#endif + + dm_RSSIMonitorInit(Adapter); + + pdmpriv->DMFlag_tmp = pdmpriv->DMFlag; + + // Save REG_INIDATA_RATE_SEL value for TXDESC. + for(i = 0 ; i<32 ; i++) + { + pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f; + } + +#ifdef CONFIG_DM_ADAPTIVITY + pdmpriv->DMFlag |= DYNAMIC_FUNC_ADAPTIVITY; + dm_adaptivity_init(Adapter); +#endif + +} + +#ifdef CONFIG_CONCURRENT_MODE +static void FindMinimumRSSI(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pbuddy_HalData; + struct dm_priv *pbuddy_dmpriv; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + + if(!rtw_buddy_adapter_up(Adapter)) + return; + + pbuddy_HalData = GET_HAL_DATA(pbuddy_adapter); + pbuddy_dmpriv = &pbuddy_HalData->dmpriv; + + //get min. [PWDB] when both interfaces are connected + if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE + && Adapter->stapriv.asoc_sta_count > 2 + && check_buddy_fwstate(Adapter, _FW_LINKED)) || + (check_buddy_fwstate(Adapter, WIFI_AP_STATE) == _TRUE + && pbuddy_adapter->stapriv.asoc_sta_count > 2 + && check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED) + && check_buddy_fwstate(Adapter,WIFI_STATION_STATE) + && check_buddy_fwstate(Adapter,_FW_LINKED))) + { + if(pdmpriv->UndecoratedSmoothedPWDB > pbuddy_dmpriv->UndecoratedSmoothedPWDB) + pdmpriv->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; + }//primary interface is not connected + else if((check_buddy_fwstate(Adapter, WIFI_AP_STATE) == _TRUE + && pbuddy_adapter->stapriv.asoc_sta_count > 2) || + (check_buddy_fwstate(Adapter,WIFI_STATION_STATE) + && check_buddy_fwstate(Adapter,_FW_LINKED))) + { + pdmpriv->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; + } + //secondary is not connected + else if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE + && Adapter->stapriv.asoc_sta_count > 2) || + (check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED))) + { + pbuddy_dmpriv->UndecoratedSmoothedPWDB = 0; + } + //both interfaces are not connected + else + { + pdmpriv->UndecoratedSmoothedPWDB = 0; + pbuddy_dmpriv->UndecoratedSmoothedPWDB = 0; + } + + //primary interface is ap mode + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && Adapter->stapriv.asoc_sta_count > 2) + { + pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB = 0; + }//secondary interface is ap mode + else if(check_buddy_fwstate(Adapter, WIFI_AP_STATE) == _TRUE && pbuddy_adapter->stapriv.asoc_sta_count > 2) + { + pdmpriv->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB; + } + else //both interfaces are not ap mode + { + pdmpriv->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB = 0; + } + +} + +#endif //CONFIG_CONCURRENT_MODE + +VOID +rtl8192c_HalDmWatchDog( + IN PADAPTER Adapter + ) +{ + BOOLEAN bFwCurrentInPSMode = _FALSE; + BOOLEAN bFwPSAwake = _TRUE; + u8 hw_init_completed = _FALSE; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; +#endif //CONFIG_CONCURRENT_MODE + + #if defined(CONFIG_CONCURRENT_MODE) + if (Adapter->isprimary == _FALSE && pbuddy_adapter) { + hw_init_completed = pbuddy_adapter->hw_init_completed; + } else + #endif + { + hw_init_completed = Adapter->hw_init_completed; + } + + if (hw_init_completed == _FALSE) + goto skip_dm; + +#ifdef CONFIG_LPS + #if defined(CONFIG_CONCURRENT_MODE) + if (Adapter->iface_type != IFACE_PORT0 && pbuddy_adapter) { + bFwCurrentInPSMode = pbuddy_adapter->pwrctrlpriv.bFwCurrentInPSMode; + rtw_hal_get_hwreg(pbuddy_adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); + } else + #endif + { + bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode; + rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); + } +#endif + +#ifdef CONFIG_P2P_PS + // Fw is under p2p powersaving mode, driver should stop dynamic mechanism. + // modifed by thomas. 2011.06.11. + if(Adapter->wdinfo.p2p_ps_mode) + bFwPSAwake = _FALSE; +#endif // CONFIG_P2P_PS + + // Stop dynamic mechanism when: + // 1. RF is OFF. (No need to do DM.) + // 2. Fw is under power saving mode for FwLPS. (Prevent from SW/FW I/O racing.) + // 3. IPS workitem is scheduled. (Prevent from IPS sequence to be swapped with DM. + // Sometimes DM execution time is longer than 100ms such that the assertion + // in MgntActSet_RF_State() called by InactivePsWorkItem will be triggered by + // wating to long for RFChangeInProgress.) + // 4. RFChangeInProgress is TRUE. (Prevent from broken by IPS/HW/SW Rf off.) + // Noted by tynli. 2010.06.01. + //if(rfState == eRfOn) + if( (hw_init_completed == _TRUE) + && ((!bFwCurrentInPSMode) && bFwPSAwake)) + { + // + // Calculate Tx/Rx statistics. + // + dm_CheckStatistics(Adapter); + + // + // For PWDB monitor and record some value for later use. + // + PWDB_Monitor(Adapter); + + dm_RSSIMonitorCheck(Adapter); + +#ifdef CONFIG_CONCURRENT_MODE + if(Adapter->adapter_type > PRIMARY_ADAPTER) + goto _record_initrate; + + FindMinimumRSSI(Adapter); +#endif + + // + // Dynamic Initial Gain mechanism. + // + dm_FalseAlarmCounterStatistics(Adapter); + dm_DIG(Adapter); + dm_adaptivity(Adapter); + + // + //Dynamic BB Power Saving Mechanism + // + dm_DynamicBBPowerSaving(Adapter); + + // + // Dynamic Tx Power mechanism. + // + dm_DynamicTxPower(Adapter); + + // + // Tx Power Tracking. + // +#if MP_DRIVER == 0 +#ifdef CONFIG_BUSY_TRAFFIC_SKIP_PWR_TRACK + if(pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE) +#endif //CONFIG_BUSY_TRAFFIC_SKIP_PWR_TRACK +#endif + rtl8192c_dm_CheckTXPowerTracking(Adapter); + + // + // Rate Adaptive by Rx Signal Strength mechanism. + // + dm_RefreshRateAdaptiveMask(Adapter); + +#ifdef CONFIG_BT_COEXIST + //BT-Coexist + dm_BTCoexist(Adapter); +#endif + + // EDCA turbo + //update the EDCA paramter according to the Tx/RX mode + //update_EDCA_param(Adapter); + dm_CheckEdcaTurbo(Adapter); + + // + // Dynamically switch RTS/CTS protection. + // + //dm_CheckProtection(Adapter); + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + // + // Software Antenna diversity + // + dm_SW_AntennaSwitch(Adapter, SWAW_STEP_PEAK); +#endif + +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + //Hybrid Antenna Diversity + dm_SelectRXDefault(Adapter); +#endif + +#ifdef CONFIG_PCI_HCI + // 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput. + // Tx Migration settings. + //dm_InterruptMigration(Adapter); + + //if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) + // PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem)); +#endif + + +_record_initrate: + + // Read REG_INIDATA_RATE_SEL value for TXDESC. + if(check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) + { + pdmpriv->INIDATA_RATE[0] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f; + +#ifdef CONFIG_TDLS + if(Adapter->tdlsinfo.setup_state == TDLS_LINKED_STATE) + { + u8 i=1; + for(; i < (Adapter->tdlsinfo.macid_index) ; i++) + { + pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f; + } + } +#endif //CONFIG_TDLS + + } + else + { + u8 i; + for(i=1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++) + { + pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f; + } + } + } + +skip_dm: + + // Check GPIO to determine current RF on/off and Pbc status. + // Check Hardware Radio ON/OFF or not + //if(Adapter->MgntInfo.PowerSaveControl.bGpioRfSw) + //{ + //RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO \n")); + // dm_CheckRfCtrlGPIO(Adapter); + //} + +#ifdef CONFIG_PCI_HCI + if(pHalData->bGpioHwWpsPbc) +#endif + { + dm_CheckPbcGPIO(Adapter); // Add by hpfan 2008-03-11 + } + +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c new file mode 100755 index 00000000..b9e91d70 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c @@ -0,0 +1,3628 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + +#define _RTL8192C_HAL_INIT_C_ +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_USB_HCI +#include +#endif + +#ifdef CONFIG_PCI_HCI +#include +#endif + +static BOOLEAN +hal_EfusePgPacketWrite2ByteHeader( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest); +static BOOLEAN +hal_EfusePgPacketWrite1ByteHeader( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest); +static BOOLEAN +hal_EfusePgPacketWriteData( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest); +static BOOLEAN +hal_EfusePgPacketWrite_BT( + IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *pData, + IN BOOLEAN bPseudoTest); + +static VOID +_FWDownloadEnable( + IN PADAPTER Adapter, + IN BOOLEAN enable + ) +{ + u8 tmp; + + if(enable) + { + #ifdef DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE + { + u8 val; + if( (val=rtw_read8(Adapter, REG_MCUFWDL))) + DBG_871X("DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE %s:%d REG_MCUFWDL:0x%02x\n", __FUNCTION__, __LINE__, val); + } + #endif + + // 8051 enable + tmp = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); + rtw_write8(Adapter, REG_SYS_FUNC_EN+1, tmp|0x04); + + // MCU firmware download enable. + tmp = rtw_read8(Adapter, REG_MCUFWDL); + rtw_write8(Adapter, REG_MCUFWDL, tmp|0x01); + + // 8051 reset + tmp = rtw_read8(Adapter, REG_MCUFWDL+2); + rtw_write8(Adapter, REG_MCUFWDL+2, tmp&0xf7); + } + else + { + // MCU firmware download enable. + tmp = rtw_read8(Adapter, REG_MCUFWDL); + rtw_write8(Adapter, REG_MCUFWDL, tmp&0xfe); + + // Reserved for fw extension. + rtw_write8(Adapter, REG_MCUFWDL+1, 0x00); + } +} + + +#define MAX_REG_BOLCK_SIZE 196 +#define MIN_REG_BOLCK_SIZE 8 + +static int +_BlockWrite( + IN PADAPTER Adapter, + IN PVOID buffer, + IN u32 size + ) +{ + int ret = _SUCCESS; + +#ifdef CONFIG_PCI_HCI + u32 blockSize = sizeof(u32); // Use 4-byte write to download FW + u8 *bufferPtr = (u8 *)buffer; + u32 *pu4BytePtr = (u32 *)buffer; + u32 i, offset, blockCount, remainSize; + u8 remainFW[4] = {0, 0, 0, 0}; + u8 *p = NULL; + + blockCount = size / blockSize; + remainSize = size % blockSize; + + for(i = 0 ; i < blockCount ; i++){ + offset = i * blockSize; + rtw_write32(Adapter, (FW_8192C_START_ADDRESS + offset), cpu_to_le32(*(pu4BytePtr + i))); + } + + p = (u8*)((u32*)(bufferPtr + blockCount * blockSize)); + if(remainSize){ + switch (remainSize) { + case 0: + break; + case 3: + remainFW[2]=*(p+2); + case 2: + remainFW[1]=*(p+1); + case 1: + remainFW[0]=*(p); + ret = rtw_write32(Adapter, (FW_8192C_START_ADDRESS + blockCount * blockSize), + le32_to_cpu(*(u32*)remainFW)); + } + return ret; + } +#else + +#ifdef SUPPORTED_BLOCK_IO + u32 blockSize = MAX_REG_BOLCK_SIZE; // Use 196-byte write to download FW + u32 blockSize2 = MIN_REG_BOLCK_SIZE; +#else + u32 blockSize = sizeof(u32); // Use 4-byte write to download FW + u32* pu4BytePtr = (u32*)buffer; + u32 blockSize2 = sizeof(u8); +#endif + u8* bufferPtr = (u8*)buffer; + u32 i, offset = 0, offset2, blockCount, remainSize, remainSize2; + + blockCount = size / blockSize; + remainSize = size % blockSize; + + for(i = 0 ; i < blockCount ; i++){ + offset = i * blockSize; + #ifdef SUPPORTED_BLOCK_IO + ret = rtw_writeN(Adapter, (FW_8192C_START_ADDRESS + offset), blockSize, (bufferPtr + offset)); + #else + ret = rtw_write32(Adapter, (FW_8192C_START_ADDRESS + offset), le32_to_cpu(*(pu4BytePtr + i))); + #endif + + if(ret == _FAIL) + goto exit; + } + + if(remainSize){ + #if defined(SUPPORTED_BLOCK_IO) && defined(DBG_BLOCK_WRITE_ISSUE) //Can this be enabled? + offset = blockCount * blockSize; + ret = rtw_writeN(Adapter, (FW_8192C_START_ADDRESS + offset), remainSize, (bufferPtr + offset)); + goto exit; + #endif + offset2 = blockCount * blockSize; + blockCount = remainSize / blockSize2; + remainSize2 = remainSize % blockSize2; + + for(i = 0 ; i < blockCount ; i++){ + offset = offset2 + i * blockSize2; + #ifdef SUPPORTED_BLOCK_IO + ret = rtw_writeN(Adapter, (FW_8192C_START_ADDRESS + offset), blockSize2, (bufferPtr + offset)); + #else + ret = rtw_write8(Adapter, (FW_8192C_START_ADDRESS + offset ), *(bufferPtr + offset)); + #endif + + if(ret == _FAIL) + goto exit; + } + + if(remainSize2) + { + offset += blockSize2; + bufferPtr += offset; + + for(i = 0 ; i < remainSize2 ; i++){ + ret = rtw_write8(Adapter, (FW_8192C_START_ADDRESS + offset + i), *(bufferPtr + i)); + + if(ret == _FAIL) + goto exit; + } + } + } +#endif + +exit: + return ret; +} + +static int +_PageWrite( + IN PADAPTER Adapter, + IN u32 page, + IN PVOID buffer, + IN u32 size + ) +{ + u8 value8; + u8 u8Page = (u8) (page & 0x07) ; + + value8 = (rtw_read8(Adapter, REG_MCUFWDL+2)& 0xF8 ) | u8Page ; + rtw_write8(Adapter, REG_MCUFWDL+2,value8); + return _BlockWrite(Adapter,buffer,size); +} + +static VOID +_FillDummy( + u8* pFwBuf, + u32* pFwLen + ) +{ + u32 FwLen = *pFwLen; + u8 remain = (u8)(FwLen%4); + remain = (remain==0)?0:(4-remain); + + while(remain>0) + { + pFwBuf[FwLen] = 0; + FwLen++; + remain--; + } + + *pFwLen = FwLen; +} + +static int +_WriteFW( + IN PADAPTER Adapter, + IN PVOID buffer, + IN u32 size + ) +{ + // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. + // We can remove _ReadChipVersion from ReadAdapterInfo8192C later. + + int ret = _SUCCESS; + u32 pageNums,remainSize ; + u32 page,offset; + u8* bufferPtr = (u8*)buffer; + +#ifdef CONFIG_PCI_HCI + // 20100120 Joseph: Add for 88CE normal chip. + // Fill in zero to make firmware image to dword alignment. +// _FillDummy(bufferPtr, &size); +#endif + + pageNums = size / MAX_PAGE_SIZE ; + //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n")); + remainSize = size % MAX_PAGE_SIZE; + + for(page = 0; page < pageNums; page++){ + offset = page *MAX_PAGE_SIZE; + ret = _PageWrite(Adapter,page, (bufferPtr+offset),MAX_PAGE_SIZE); + + if(ret == _FAIL) + goto exit; + } + if(remainSize){ + offset = pageNums *MAX_PAGE_SIZE; + page = pageNums; + ret = _PageWrite(Adapter,page, (bufferPtr+offset),remainSize); + + if(ret == _FAIL) + goto exit; + } + //RT_TRACE(COMP_INIT, DBG_LOUD, ("_WriteFW Done- for Normal chip.\n")); + +exit: + return ret; +} + +static int _FWFreeToGo( + IN PADAPTER Adapter + ) +{ + u32 counter = 0; + u32 value32; + u32 restarted = _FALSE; + + // polling CheckSum report + do{ + value32 = rtw_read32(Adapter, REG_MCUFWDL); + }while((counter ++ < POLLING_READY_TIMEOUT_COUNT) && (!(value32 & FWDL_ChkSum_rpt))); + + if(counter >= POLLING_READY_TIMEOUT_COUNT){ + DBG_8192C("chksum report faill ! REG_MCUFWDL:0x%08x\n",value32); + return _FAIL; + } else { + //DBG_8192C("chksum report success ! REG_MCUFWDL:0x%08x, counter:%u\n",value32, counter); + } + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n",value32)); + + + value32 = rtw_read32(Adapter, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtw_write32(Adapter, REG_MCUFWDL, value32); + + +POLLING_FW_READY: + // polling for FW ready + counter = 0; + do + { + if(rtw_read32(Adapter, REG_MCUFWDL) & WINTINI_RDY){ + //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",PlatformIORead4Byte(Adapter, REG_MCUFWDL)) ); + return _SUCCESS; + } + rtw_udelay_os(5); + }while(counter++ < POLLING_READY_TIMEOUT_COUNT); + + DBG_8192C("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", rtw_read32(Adapter, REG_MCUFWDL)); + + if(restarted == _FALSE) { + u8 tmp = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); + DBG_8192C("Reset 51 write8 REG_SYS_FUNC_EN:0x%04x\n", tmp & ~BIT2); + rtw_write8(Adapter, REG_SYS_FUNC_EN+1, tmp & ~BIT2); + DBG_8192C("Reset 51 write8 REG_SYS_FUNC_EN:0x%04x\n", tmp|BIT2); + rtw_write8(Adapter, REG_SYS_FUNC_EN+1, tmp|BIT2); + restarted = _TRUE; + goto POLLING_FW_READY; + } + + + return _FAIL; + +} + + +VOID +rtl8192c_FirmwareSelfReset( + IN PADAPTER Adapter +) +{ + u8 u1bTmp; + u8 Delay = 100; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if((pHalData->FirmwareVersion > 0x21) || + (pHalData->FirmwareVersion == 0x21 && + pHalData->FirmwareSubVersion >= 0x01)) // after 88C Fw v33.1 + { + //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test + rtw_write8(Adapter, REG_HMETFR+3, 0x20); + + u1bTmp = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); + while(u1bTmp&BIT2) + { + Delay--; + if(Delay == 0) + break; + rtw_udelay_os(50); + u1bTmp = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); + } + + if((u1bTmp&BIT2) && (Delay == 0)) + { + DBG_8192C("FirmwareDownload92C():fw reset by itself Fail!!!!!! 0x03 = %x\n", u1bTmp); + //RT_ASSERT(FALSE, ("PowerOffAdapter8192CE(): 0x03 = %x\n", u1bTmp)); + #ifdef DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE + { + u8 val; + if( (val=rtw_read8(Adapter, REG_MCUFWDL))) + DBG_871X("DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE %s:%d REG_MCUFWDL:0x%02x\n", __FUNCTION__, __LINE__, val); + } + #endif + rtw_write8(Adapter,REG_SYS_FUNC_EN+1,(rtw_read8(Adapter, REG_SYS_FUNC_EN+1)&~BIT2)); + } + + DBG_8192C("%s =====> 8051 reset success (%d) .\n", __FUNCTION__ ,Delay); + } +} + +#ifdef CONFIG_FILE_FWIMG +extern char *rtw_fw_file_path; +u8 FwBuffer8192C[FW_8192C_SIZE]; +#endif //CONFIG_FILE_FWIMG +// +// Description: +// Download 8192C firmware code. +// +// +int FirmwareDownload92C( + IN PADAPTER Adapter, + IN BOOLEAN bUsedWoWLANFw +) +{ + int rtStatus = _SUCCESS; + u8 writeFW_retry = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s8 R92CFwImageFileName_TSMC[] ={RTL8192C_FW_TSMC_IMG}; + s8 R92CFwImageFileName_UMC[] ={RTL8192C_FW_UMC_IMG}; + s8 R92CFwImageFileName_UMC_B[] ={RTL8192C_FW_UMC_B_IMG}; +#ifdef CONFIG_WOWLAN + s8 R92CFwImageFileName_TSMC_WW[] ={RTL8192C_FW_TSMC_WW_IMG}; + s8 R92CFwImageFileName_UMC_WW[] ={RTL8192C_FW_UMC_WW_IMG}; + s8 R92CFwImageFileName_UMC_B_WW[] ={RTL8192C_FW_UMC_B_WW_IMG}; +#endif //CONFIG_WOWLAN + + //s8 R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG}; + u8* FwImage = NULL; + u32 FwImageLen = 0; + char* pFwImageFileName; +#ifdef CONFIG_WOWLAN + u8* FwImageWoWLAN; + u32 FwImageWoWLANLen; + char* pFwImageFileName_WoWLAN; +#endif //CONFIG_WOWLAN + u8* pucMappedFile = NULL; + //vivi, merge 92c and 92s into one driver, 20090817 + //vivi modify this temply, consider it later!!!!!!!! + //PRT_FIRMWARE pFirmware = GET_FIRMWARE_819X(Adapter); + //PRT_FIRMWARE_92C pFirmware = GET_FIRMWARE_8192C(Adapter); + PRT_FIRMWARE_92C pFirmware = NULL; + PRT_8192C_FIRMWARE_HDR pFwHdr = NULL; + u8 *pFirmwareBuf; + u32 FirmwareLen; + + pFirmware = (PRT_FIRMWARE_92C)rtw_zvmalloc(sizeof(RT_FIRMWARE_92C)); + + if(!pFirmware) + { + rtStatus = _FAIL; + goto Exit; + } + + if(IS_VENDOR_UMC_A_CUT(pHalData->VersionID) && !IS_92C_SERIAL(pHalData->VersionID)) + { + pFwImageFileName = R92CFwImageFileName_UMC; + FwImage = Rtl819XFwUMCACutImageArray; + FwImageLen = UMCACutImgArrayLength; +#ifdef CONFIG_WOWLAN + pFwImageFileName_WoWLAN = R92CFwImageFileName_UMC_WW; + FwImageWoWLAN= Rtl8192C_FwUMCWWImageArray; + FwImageWoWLANLen =UMCACutWWImgArrayLength ; +#endif //CONFIG_WOWLAN + DBG_8192C(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_UMC\n"); + } + else if(IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) + { + // The ROM code of UMC B-cut Fw is the same as TSMC. by tynli. 2011.01.14. + pFwImageFileName = R92CFwImageFileName_UMC_B; + FwImage = Rtl819XFwUMCBCutImageArray; + FwImageLen = UMCBCutImgArrayLength; +#ifdef CONFIG_WOWLAN + pFwImageFileName_WoWLAN = R92CFwImageFileName_UMC_B_WW; + FwImageWoWLAN= Rtl8192C_FwUMCBCutWWImageArray; + FwImageWoWLANLen =UMCBCutWWImgArrayLength ; +#endif //CONFIG_WOWLAN + + DBG_8192C(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_UMC_B\n"); + } + else + { + pFwImageFileName = R92CFwImageFileName_TSMC; + FwImage = Rtl819XFwTSMCImageArray; + FwImageLen = TSMCImgArrayLength; +#ifdef CONFIG_WOWLAN + pFwImageFileName_WoWLAN = R92CFwImageFileName_TSMC_WW; + FwImageWoWLAN= Rtl8192C_FwTSMCWWImageArray; + FwImageWoWLANLen =TSMCWWImgArrayLength ; +#endif //CONFIG_WOWLAN + DBG_8192C(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_TSMC\n"); + } + + //RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:%s\n", pFwImageFileName)); + + #ifdef CONFIG_FILE_FWIMG + if(rtw_is_file_readable(rtw_fw_file_path) == _TRUE) + { + DBG_871X("%s accquire FW from file:%s\n", __FUNCTION__, rtw_fw_file_path); + pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg. + } + else + #endif //CONFIG_FILE_FWIMG + { + DBG_871X("%s accquire FW from embedded image\n", __FUNCTION__); + pFirmware->eFWSource = FW_SOURCE_HEADER_FILE; + } + + + switch(pFirmware->eFWSource) + { + case FW_SOURCE_IMG_FILE: + + #ifdef CONFIG_FILE_FWIMG + rtStatus = rtw_retrive_from_file(rtw_fw_file_path, FwBuffer8192C, FW_8192C_SIZE); + pFirmware->ulFwLength = rtStatus>=0?rtStatus:0; + pFirmware->szFwBuffer = FwBuffer8192C; + #endif //CONFIG_FILE_FWIMG + + if(pFirmware->ulFwLength <= 0) + { + rtStatus = _FAIL; + goto Exit; + } + break; + case FW_SOURCE_HEADER_FILE: + if(FwImageLen > FW_8192C_SIZE){ + rtStatus = _FAIL; + //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE) ); + DBG_871X("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE); + goto Exit; + } + + pFirmware->szFwBuffer = FwImage; + pFirmware->ulFwLength = FwImageLen; +#ifdef CONFIG_WOWLAN + { + pFirmware->szWoWLANFwBuffer=FwImageWoWLAN; + pFirmware->ulWoWLANFwLength = FwImageWoWLANLen; + } +#endif //CONFIG_WOWLAN + + break; + } + +#ifdef CONFIG_WOWLAN + if(bUsedWoWLANFw) { + pFirmwareBuf = pFirmware->szWoWLANFwBuffer; + FirmwareLen = pFirmware->ulWoWLANFwLength; + pFwHdr = (PRT_8192C_FIRMWARE_HDR)pFirmware->szWoWLANFwBuffer; + } + else +#endif //CONFIG_WOWLAN + { + #ifdef DBG_FW_STORE_FILE_PATH //used to store firmware to file... + if(pFirmware->ulFwLength > 0) + { + rtw_store_to_file(DBG_FW_STORE_FILE_PATH, pFirmware->szFwBuffer, pFirmware->ulFwLength); + } + #endif + + pFirmwareBuf = pFirmware->szFwBuffer; + FirmwareLen = pFirmware->ulFwLength; + + // To Check Fw header. Added by tynli. 2009.12.04. + pFwHdr = (PRT_8192C_FIRMWARE_HDR)pFirmware->szFwBuffer; + } + pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); + pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion); + + //RT_TRACE(COMP_INIT, DBG_LOUD, (" FirmwareVersion(%#x), Signature(%#x)\n", + // Adapter->MgntInfo.FirmwareVersion, pFwHdr->Signature)); + + DBG_8192C("fw_ver=v%d, fw_subver=%d, sig=0x%x\n", + pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, le16_to_cpu(pFwHdr->Signature)&0xFFF0); + + if(IS_FW_HEADER_EXIST(pFwHdr)) + { + //RT_TRACE(COMP_INIT, DBG_LOUD,("Shift 32 bytes for FW header!!\n")); + pFirmwareBuf = pFirmwareBuf + 32; + FirmwareLen = FirmwareLen -32; + } + + // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, + // or it will cause download Fw fail. 2010.02.01. by tynli. + if(rtw_read8(Adapter, REG_MCUFWDL)&BIT7) //8051 RAM code + { + rtl8192c_FirmwareSelfReset(Adapter); + rtw_write8(Adapter, REG_MCUFWDL, 0x00); + } + + + _FWDownloadEnable(Adapter, _TRUE); + while(1) { + u8 tmp8; + tmp8 = rtw_read8(Adapter, REG_MCUFWDL); + + //reset the FWDL chksum + rtw_write8(Adapter, REG_MCUFWDL, tmp8|FWDL_ChkSum_rpt); + + //tmp8 = rtw_read8(Adapter, REG_MCUFWDL); + //DBG_8192C("Before _WriteFW, REG_MCUFWDL:0x%02x, writeFW_retry:%u\n", tmp8, writeFW_retry); + + rtStatus = _WriteFW(Adapter, pFirmwareBuf, FirmwareLen); + + //tmp8 = rtw_read8(Adapter, REG_MCUFWDL); + //DBG_8192C("After _WriteFW, REG_MCUFWDL:0x%02x, rtStatus:%d\n", tmp8, rtStatus); + + if(rtStatus == _SUCCESS || ++writeFW_retry>3) + break; + } + _FWDownloadEnable(Adapter, _FALSE); + + if(_SUCCESS != rtStatus){ + DBG_8192C("DL Firmware failed!\n"); + goto Exit; + } + + rtStatus = _FWFreeToGo(Adapter); + if(_SUCCESS != rtStatus){ + DBG_8192C("DL Firmware failed!\n"); + goto Exit; + } + //RT_TRACE(COMP_INIT, DBG_LOUD, (" Firmware is ready to run!\n")); + +Exit: + + if(pFirmware) { + rtw_vmfree((u8*)pFirmware, sizeof(RT_FIRMWARE_92C)); + } + + //RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n")); + return rtStatus; + +} + +VOID +InitializeFirmwareVars92C( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + // Init Fw LPS related. + Adapter->pwrctrlpriv.bFwCurrentInPSMode = _FALSE; + + //Init H2C counter. by tynli. 2009.12.09. + pHalData->LastHMEBoxNum = 0; +} + +#ifdef CONFIG_WOWLAN +//=========================================== + +// +// Description: Prepare some information to Fw for WoWLAN. +// (1) Download wowlan Fw. +// (2) Download RSVD page packets. +// (3) Enable AP offload if needed. +// +// 2011.04.12 by tynli. +// +VOID +SetFwRelatedForWoWLAN8192CU( + IN PADAPTER padapter, + IN u8 bHostIsGoingtoSleep +) +{ + int status=_FAIL; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 bRecover = _FALSE; + + if(bHostIsGoingtoSleep) + { + // + // 1. Before WoWLAN we need to re-download WoWLAN Fw. + // + status = FirmwareDownload92C(padapter, bHostIsGoingtoSleep); + if(status != _SUCCESS) + { + DBG_8192C("ConfigFwRelatedForWoWLAN8192CU(): Re-Download Firmware failed!!\n"); + return; + } + else + { + DBG_8192C("ConfigFwRelatedForWoWLAN8192CU(): Re-Download Firmware Success !!\n"); + } + + // + // 2. Re-Init the variables about Fw related setting. + // + InitializeFirmwareVars92C(padapter); + + + } +} +#endif // CONFIG_WOWLAN + +#ifdef CONFIG_BT_COEXIST +static void _update_bt_param(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + struct registry_priv *registry_par = &padapter->registrypriv; + + if(2 != registry_par->bt_iso) + pbtpriv->BT_Ant_isolation = registry_par->bt_iso;// 0:Low, 1:High, 2:From Efuse + + if(registry_par->bt_sco == 1) // 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy + pbtpriv->BT_Service = BT_OtherAction; + else if(registry_par->bt_sco==2) + pbtpriv->BT_Service = BT_SCO; + else if(registry_par->bt_sco==4) + pbtpriv->BT_Service = BT_Busy; + else if(registry_par->bt_sco==5) + pbtpriv->BT_Service = BT_OtherBusy; + else + pbtpriv->BT_Service = BT_Idle; + + pbtpriv->BT_Ampdu = registry_par->bt_ampdu; + pbtpriv->bCOBT = _TRUE; +#if 1 + DBG_8192C("BT Coexistance = %s\n", (pbtpriv->BT_Coexist==_TRUE)?"enable":"disable"); + if(pbtpriv->BT_Coexist) + { + if(pbtpriv->BT_Ant_Num == Ant_x2) + { + DBG_8192C("BlueTooth BT_Ant_Num = Antx2\n"); + } + else if(pbtpriv->BT_Ant_Num == Ant_x1) + { + DBG_8192C("BlueTooth BT_Ant_Num = Antx1\n"); + } + switch(pbtpriv->BT_CoexistType) + { + case BT_2Wire: + DBG_8192C("BlueTooth BT_CoexistType = BT_2Wire\n"); + break; + case BT_ISSC_3Wire: + DBG_8192C("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); + break; + case BT_Accel: + DBG_8192C("BlueTooth BT_CoexistType = BT_Accel\n"); + break; + case BT_CSR_BC4: + DBG_8192C("BlueTooth BT_CoexistType = BT_CSR_BC4\n"); + break; + case BT_RTL8756: + DBG_8192C("BlueTooth BT_CoexistType = BT_RTL8756\n"); + break; + default: + DBG_8192C("BlueTooth BT_CoexistType = Unknown\n"); + break; + } + DBG_8192C("BlueTooth BT_Ant_isolation = %d\n", pbtpriv->BT_Ant_isolation); + + + switch(pbtpriv->BT_Service) + { + case BT_OtherAction: + DBG_8192C("BlueTooth BT_Service = BT_OtherAction\n"); + break; + case BT_SCO: + DBG_8192C("BlueTooth BT_Service = BT_SCO\n"); + break; + case BT_Busy: + DBG_8192C("BlueTooth BT_Service = BT_Busy\n"); + break; + case BT_OtherBusy: + DBG_8192C("BlueTooth BT_Service = BT_OtherBusy\n"); + break; + default: + DBG_8192C("BlueTooth BT_Service = BT_Idle\n"); + break; + } + + DBG_8192C("BT_RadioSharedType = 0x%x\n", pbtpriv->BT_RadioSharedType); + } +#endif + +} + + +#define GET_BT_COEXIST(priv) (&priv->bt_coexist) + +void rtl8192c_ReadBluetoothCoexistInfo( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + u8 rf_opt4; + + if(AutoloadFail){ + pbtpriv->BT_Coexist = _FALSE; + pbtpriv->BT_CoexistType= BT_2Wire; + pbtpriv->BT_Ant_Num = Ant_x2; + pbtpriv->BT_Ant_isolation= 0; + pbtpriv->BT_RadioSharedType = BT_Radio_Shared; + return; + } + + pbtpriv->BT_Coexist = (((PROMContent[EEPROM_RF_OPT1]&BOARD_TYPE_NORMAL_MASK)>>5) == BOARD_USB_COMBO)?_TRUE:_FALSE; // bit [7:5] + rf_opt4 = PROMContent[EEPROM_RF_OPT4]; + pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); // bit [3:1] + pbtpriv->BT_Ant_Num = (rf_opt4&0x1); // bit [0] + pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); // bit [4] + pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); // bit [5] + + _update_bt_param(Adapter); + +} +#endif + +VERSION_8192C +rtl8192c_ReadChipVersion( + IN PADAPTER Adapter + ) +{ + u32 value32; + //VERSION_8192C version; + u32 ChipVersion=0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + value32 = rtw_read32(Adapter, REG_SYS_CFG); + + if (value32 & TRP_VAUX_EN) + { +#if 0 + // Test chip. + if(IS_HARDWARE_TYPE_8723A(Adapter)) { + ChipVersion |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + ChipVersion |= ((value32 & BT_FUNC) ? CHIP_8723: 0); // RTL8723 with BT function. + } + else { + version = (value32 & TYPE_ID) ?VERSION_TEST_CHIP_92C :VERSION_TEST_CHIP_88C; + } +#else + // tynli_test. 2011.01.10. + if(IS_HARDWARE_TYPE_8192C(Adapter)) + { + ChipVersion = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C : VERSION_TEST_CHIP_88C; + } + else + { + ChipVersion |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + ChipVersion |= ((value32 & BT_FUNC) ? CHIP_8723: 0); // RTL8723 with BT function. + } +#endif + } + else + { +#if 0 + // Normal mass production chip. + ChipVersion = NORMAL_CHIP; +#if !RTL8723_FPGA_TRUE_PHY_VERIFICATION + ChipVersion |= ((value32 & TYPE_ID) ? CHIP_92C : 0); +#endif + ChipVersion |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + ChipVersion |= ((value32 & BT_FUNC) ? CHIP_8723: 0); // RTL8723 with BT function. + if(IS_8723_SERIES(ChipVersion)) + { + if(IS_VENDOR_UMC(ChipVersion)) + ChipVersion |= ((value32 & CHIP_VER_RTL_MASK) ? CHIP_VENDOR_UMC_B_CUT : 0); + } + else + { + // Mark out by tynli. UMC B-cut IC will not set the SYS_CFG[19] to UMC + // because we do not want the custmor to know. 2011.01.11. + //if(IS_VENDOR_UMC(ChipVersion)) + { + // To check the value of B-cut. by tynli. 2011.01.11. + u1bTmp = (u1Byte)((value32 & CHIP_VER_RTL_MASK)>>12); + if(u1bTmp == 1) + { // B-cut + ChipVersion |= CHIP_VENDOR_UMC_B_CUT; + } + } + } +#else + // Normal mass production chip. + ChipVersion = NORMAL_CHIP; +//#if !RTL8723_FPGA_TRUE_PHY_VERIFICATION + ChipVersion |= ((value32 & TYPE_ID) ? RF_TYPE_2T2R : 0); //92c +//#endif + ChipVersion |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + ChipVersion |= ((value32 & BT_FUNC) ? CHIP_8723: 0); // RTL8723 with BT function. + if(IS_HARDWARE_TYPE_8192C(Adapter)) + { + // 88/92C UMC B-cut IC will not set the SYS_CFG[19] to UMC + // because we do not want the custmor to know. by tynli. 2011.01.17. + //MSG_8192C("mask result = 0x%x is_UMC %d chipversion 0x%x\n", (value32 & CHIP_VER_RTL_MASK), IS_CHIP_VENDOR_UMC(ChipVersion), ChipVersion); + if((!IS_CHIP_VENDOR_UMC(ChipVersion) )&& (value32 & CHIP_VER_RTL_MASK)) + { + //MSG_8192C("chip mask result = 0x%x\n", ((value32 & CHIP_VER_RTL_MASK) | CHIP_VENDOR_UMC)); + ChipVersion |= ((value32 & CHIP_VER_RTL_MASK) | CHIP_VENDOR_UMC); // IC version (CUT) + //MSG_8192C("chip version = 0x%x\n", ChipVersion); + } + } + else + { + if(IS_CHIP_VENDOR_UMC(ChipVersion)) + ChipVersion |= ((value32 & CHIP_VER_RTL_MASK)); // IC version (CUT) + } + + if(IS_92C_SERIAL(ChipVersion)) + { + value32 = rtw_read32(Adapter, REG_HPON_FSM); + ChipVersion |= ((CHIP_BONDING_IDENTIFIER(value32) == CHIP_BONDING_92C_1T2R) ? RF_TYPE_1T2R : 0); + } + else if(IS_8723_SERIES(ChipVersion)) + { + //RT_ASSERT(IS_HARDWARE_TYPE_8723A(Adapter), ("Incorrect chip version!!\n")); + value32 = rtw_read32(Adapter, REG_GPIO_OUTSTS); + ChipVersion |= ((value32 & RF_RL_ID)>>20); //ROM code version. + } +#endif + + } + + //version = (VERSION_8192C)ChipVersion; + + // For multi-function consideration. Added by Roger, 2010.10.06. + if(IS_8723_SERIES(ChipVersion)) + { + pHalData->MultiFunc = RT_MULTI_FUNC_NONE; + value32 = rtw_read32(Adapter, REG_MULTI_FUNC_CTRL); + pHalData->MultiFunc =(RT_MULTI_FUNC) (pHalData->MultiFunc| ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0) ); + pHalData->MultiFunc =(RT_MULTI_FUNC) (pHalData->MultiFunc| ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0) ); + pHalData->MultiFunc =(RT_MULTI_FUNC) (pHalData->MultiFunc| ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0) ); + pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT); + //MSG_8192C("ReadChipVersion(): MultiFunc(%x), PolarityCtl(%x) \n", pHalData->MultiFunc, pHalData->PolarityCtl); + + //For regulator mode. by tynli. 2011.01.14 + pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR); + //MSG_8192C("ReadChipVersion(): RegulatorMode(%x) \n", pHalData->RegulatorMode); + } + +//#if DBG +#if 1 + switch(ChipVersion) + { + case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: + MSG_8192C("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C_1T2R.\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_92C: + MSG_8192C("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n"); + break; + case VERSION_NORMAL_TSMC_CHIP_88C: + MSG_8192C("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_A_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_A_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_B_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_B_CUT.\n"); + break; + case VERSION_TEST_CHIP_92C: + MSG_8192C("Chip Version ID: VERSION_TEST_CHIP_92C.\n"); + break; + case VERSION_TEST_CHIP_88C: + MSG_8192C("Chip Version ID: VERSION_TEST_CHIP_88C.\n"); + break; + case VERSION_TEST_UMC_CHIP_8723: + MSG_8192C("Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT.\n"); + break; + case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT: + MSG_8192C("Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT.\n"); + break; + default: + MSG_8192C("Chip Version ID: ???????????????.\n"); + break; + } +#endif + + pHalData->VersionID = ChipVersion; + + if(IS_1T2R(ChipVersion)) + pHalData->rf_type = RF_1T2R; + else if(IS_2T2R(ChipVersion)) + pHalData->rf_type = RF_2T2R; + else if(IS_8723_SERIES(ChipVersion)) + pHalData->rf_type = RF_1T1R; + else + pHalData->rf_type = RF_1T1R; + + MSG_8192C("RF_Type is %x!!\n", pHalData->rf_type); + + return ChipVersion; +} + +void +rtl8192c_EfuseParseChnlPlan( + IN PADAPTER padapter, + IN u8* hwinfo, + IN BOOLEAN AutoLoadFail + ) +{ + padapter->mlmepriv.ChannelPlan = hal_com_get_channel_plan( + padapter + , hwinfo?hwinfo[EEPROM_CHANNEL_PLAN]:0xFF + , padapter->registrypriv.channel_plan + , RT_CHANNEL_DOMAIN_WORLD_WIDE_13 + , AutoLoadFail + ); + + DBG_871X("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan); +} + +u8 GetEEPROMSize8192C(PADAPTER Adapter) +{ + u8 size = 0; + u32 curRCR; + + curRCR = rtw_read16(Adapter, REG_9346CR); + size = (curRCR & BOOT_FROM_EEPROM) ? 6 : 4; // 6: EEPROM used is 93C46, 4: boot from E-Fuse. + + MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46"); + + return size; +} + +void rtl8192c_free_hal_data(_adapter * padapter) +{ +_func_enter_; + + DBG_8192C("=====> rtl8192c_free_hal_data =====\n"); + + if(padapter->HalData) + rtw_mfree(padapter->HalData, sizeof(HAL_DATA_TYPE)); + DBG_8192C("<===== rtl8192c_free_hal_data =====\n"); + +_func_exit_; +} + +//=========================================================== +// Efuse related code +//=========================================================== +enum{ + VOLTAGE_V25 = 0x03, + LDOE25_SHIFT = 28 , + }; + +static VOID +hal_EfusePowerSwitch_RTL8192C( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + u8 tempval; + u16 tmpV16; + + if (PwrState == _TRUE) + { + // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_ISO_CTRL); + if( ! (tmpV16 & PWC_EV12V ) ){ + tmpV16 |= PWC_EV12V ; + rtw_write16(pAdapter,REG_SYS_ISO_CTRL,tmpV16); + } + // Reset: 0x0000h[28], default valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_FUNC_EN); + if( !(tmpV16 & FEN_ELDR) ){ + tmpV16 |= FEN_ELDR ; + rtw_write16(pAdapter,REG_SYS_FUNC_EN,tmpV16); + } + + // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_CLKR); + if( (!(tmpV16 & LOADER_CLK_EN) ) ||(!(tmpV16 & ANA8M) ) ){ + tmpV16 |= (LOADER_CLK_EN |ANA8M ) ; + rtw_write16(pAdapter,REG_SYS_CLKR,tmpV16); + } + + if(bWrite == _TRUE) + { + // Enable LDO 2.5V before read/write action + tempval = rtw_read8(pAdapter, EFUSE_TEST+3); + tempval &= 0x0F; + tempval |= (VOLTAGE_V25 << 4); + rtw_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80)); + } + } + else + { + if(bWrite == _TRUE){ + // Disable LDO 2.5V after read/write action + tempval = rtw_read8(pAdapter, EFUSE_TEST+3); + rtw_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F)); + } + } +} + +static VOID +hal_EfusePowerSwitch_RTL8723( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + u8 tempval; + u16 tmpV16; + + if (PwrState == _TRUE) + { + rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_ISO_CTRL); + if( ! (tmpV16 & PWC_EV12V ) ){ + tmpV16 |= PWC_EV12V ; + rtw_write16(pAdapter,REG_SYS_ISO_CTRL,tmpV16); + } + // Reset: 0x0000h[28], default valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_FUNC_EN); + if( !(tmpV16 & FEN_ELDR) ){ + tmpV16 |= FEN_ELDR ; + rtw_write16(pAdapter,REG_SYS_FUNC_EN,tmpV16); + } + + // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid + tmpV16 = rtw_read16(pAdapter,REG_SYS_CLKR); + if( (!(tmpV16 & LOADER_CLK_EN) ) ||(!(tmpV16 & ANA8M) ) ){ + tmpV16 |= (LOADER_CLK_EN |ANA8M ) ; + rtw_write16(pAdapter,REG_SYS_CLKR,tmpV16); + } + + if(bWrite == _TRUE) + { + // Enable LDO 2.5V before read/write action + tempval = rtw_read8(pAdapter, EFUSE_TEST+3); + tempval &= 0x0F; + tempval |= (VOLTAGE_V25 << 4); + rtw_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80)); + } + } + else + { + rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + + if(bWrite == _TRUE){ + // Disable LDO 2.5V after read/write action + tempval = rtw_read8(pAdapter, EFUSE_TEST+3); + rtw_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F)); + } + } +} + +static VOID +rtl8192c_EfusePowerSwitch( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + if(IS_HARDWARE_TYPE_8192C(pAdapter)) + { + hal_EfusePowerSwitch_RTL8192C(pAdapter, bWrite, PwrState); + } + else if(IS_HARDWARE_TYPE_8723A(pAdapter)) + { + hal_EfusePowerSwitch_RTL8723(pAdapter, bWrite, PwrState); + } +} + +static VOID +ReadEFuse_RTL8192C( + PADAPTER Adapter, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ) +{ + u8 efuseTbl[EFUSE_MAP_LEN]; + u8 rtemp8[1]; + u16 eFuse_Addr = 0; + u8 offset, wren; + u16 i, j; + u16 eFuseWord[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; + u16 efuse_utilized = 0; + u8 efuse_usage = 0; + + // + // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. + // + if((_offset + _size_byte)>EFUSE_MAP_LEN) + {// total E-Fuse table is 128bytes + //DBG_8192C("ReadEFuse_RTL8192C(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte); + return; + } + + // 0. Refresh efuse init map as all oxFF. + for (i = 0; i < EFUSE_MAX_SECTION; i++) + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + eFuseWord[i][j] = 0xFFFF; + + + // + // 1. Read the first byte to check if efuse is empty!!! + // + // + ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); + if(*rtemp8 != 0xFF) + { + efuse_utilized++; + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); + eFuse_Addr++; + } + + // + // 2. Read real efuse content. Filter PG header and every section data. + // + while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN)) + { + // Check PG header for section num. + offset = ((*rtemp8 >> 4) & 0x0f); + + if(offset < EFUSE_MAX_SECTION) + { + // Get word enable value from PG header + wren = (*rtemp8 & 0x0f); + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); + + for(i=0; i= EFUSE_REAL_CONTENT_LEN) + break; + + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); + ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); eFuse_Addr++; + efuse_utilized++; + eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00); + + if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN) + break; + } + + wren >>= 1; + + } + } + + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); + // Read next PG header + ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest); + if(*rtemp8 != 0xFF && (eFuse_Addr < 512)) + { + efuse_utilized++; + eFuse_Addr++; + } + } + + // + // 3. Collect 16 sections and 4 word unit into Efuse map. + // + for(i=0; i> 8) & 0xff); + } + } + + // + // 4. Copy from Efuse map to output pointer memory!!! + // + for(i=0; i<_size_byte; i++) + { + pbuf[i] = efuseTbl[_offset+i]; + } + + // + // 5. Calculate Efuse utilization. + // + efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN); + rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized); + //rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_USAGE, (pu1Byte)&efuse_usage); +} + +static VOID +ReadEFuse_RTL8723( + PADAPTER Adapter, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ) +{ + u8 efuseTbl[EFUSE_MAP_LEN_8723]; + u16 eFuse_Addr = 0; + u8 offset = 0, wden = 0; + u16 i, j; + u16 eFuseWord[EFUSE_MAX_SECTION_8723][EFUSE_MAX_WORD_UNIT]; + u16 efuse_utilized = 0; + u8 efuse_usage = 0; + u8 offset_2_0=0; + u8 efuseHeader=0, efuseExtHdr=0, efuseData=0; + // + // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. + // + if((_offset + _size_byte)>EFUSE_MAP_LEN_8723) + { + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("ReadEFuse_RTL8723(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte)); + return; + } + + // 0. Refresh efuse init map as all oxFF. + for (i = 0; i < EFUSE_MAX_SECTION_8723; i++) + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + eFuseWord[i][j] = 0xFFFF; + + // + // 1. Read the first byte to check if efuse is empty!!! + // + // + ReadEFuseByte(Adapter, eFuse_Addr++, &efuseHeader, bPseudoTest); + + if(efuseHeader != 0xFF) + { + efuse_utilized++; + } + else + { + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("EFUSE is empty\n")); + return; + } + + + // + // 2. Read real efuse content. Filter PG header and every section data. + // + while((efuseHeader != 0xFF) && AVAILABLE_EFUSE_ADDR(eFuse_Addr)) + { + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse[%d]=%x\n", eFuse_Addr-1, efuseHeader)); + + // Check PG header for section num. + if(EXT_HEADER(efuseHeader)) //extended header + { + offset_2_0 = GET_HDR_OFFSET_2_0(efuseHeader); + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header offset_2_0=%x\n", offset_2_0)); + + ReadEFuseByte(Adapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); + + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse[%d]=%x\n", eFuse_Addr-1, efuseExtHdr)); + + if(efuseExtHdr != 0xff) + { + efuse_utilized++; + if(ALL_WORDS_DISABLED(efuseExtHdr)) + { + ReadEFuseByte(Adapter, eFuse_Addr++, &efuseHeader, bPseudoTest); + if(efuseHeader != 0xff) + { + efuse_utilized++; + } + continue; + } + else + { + offset = ((efuseExtHdr & 0xF0) >> 1) | offset_2_0; + wden = (efuseExtHdr & 0x0F); + } + } + else + { + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Error condition, extended = 0xff\n")); + // We should handle this condition. + } + } + else + { + offset = ((efuseHeader >> 4) & 0x0f); + wden = (efuseHeader & 0x0f); + } + + if(offset < EFUSE_MAX_SECTION_8723) + { + // Get word enable value from PG header + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wden)); + + for(i=0; i> 8) & 0xff); + } + } + + // + // 4. Copy from Efuse map to output pointer memory!!! + // + for(i=0; i<_size_byte; i++) + { + pbuf[i] = efuseTbl[_offset+i]; + } + + // + // 5. Calculate Efuse utilization. + // + efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN); + rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_utilized); + //rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_USAGE, (pu1Byte)&efuse_usage); +} + +static BOOLEAN +Hal_EfuseSwitchToBank( + IN PADAPTER pAdapter, + IN u8 bank, + IN BOOLEAN bPseudoTest + ) +{ + BOOLEAN bRet = _FALSE; + u32 value32=0; + + //RTPRINT(FEEPROM, EFUSE_PG, ("Efuse switch bank to %d\n", bank)); + if(bPseudoTest) + { + fakeEfuseBank = bank; + bRet = _TRUE; + } + else + { + if(IS_HARDWARE_TYPE_8723A(pAdapter) && + INCLUDE_MULTI_FUNC_BT(pAdapter)) + { + value32 = rtw_read32(pAdapter, EFUSE_TEST); + bRet = _TRUE; + switch(bank) + { + case 0: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + break; + case 1: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0); + break; + case 2: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1); + break; + case 3: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2); + break; + default: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + bRet = _FALSE; + break; + } + rtw_write32(pAdapter, EFUSE_TEST, value32); + } + else + bRet = _TRUE; + } + return bRet; +} + +static VOID +ReadEFuse_BT( + PADAPTER Adapter, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ) +{ + u8 *efuseTbl; + u16 eFuse_Addr = 0; + u8 offset = 0, wden = 0; + u16 i, j; + u16 **eFuseWord; + u16 efuse_utilized = 0; + u8 efuse_usage = 0; + u8 offset_2_0=0; + u8 efuseHeader=0, efuseExtHdr=0, efuseData=0; + u8 bank=0; + BOOLEAN bCheckNextBank=_FALSE; + + efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN); + if(efuseTbl == NULL){ + DBG_8192C("efuseTbl malloc fail !\n"); + return; + } + + eFuseWord = (u16 **)rtw_zmalloc(sizeof(u16 *)*EFUSE_BT_MAX_SECTION); + if(eFuseWord == NULL){ + DBG_8192C("eFuseWord malloc fail !\n"); + return; + } + else{ + for(i=0;iEFUSE_BT_MAP_LEN) + { + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("ReadEFuse_BT(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte)); + return; + } + + // 0. Refresh efuse init map as all oxFF. + for (i = 0; i < EFUSE_BT_MAX_SECTION; i++) + for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + eFuseWord[i][j] = 0xFFFF; + + for(bank=1; bank> 1) | offset_2_0; + wden = (efuseExtHdr & 0x0F); + } + } + else + { + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Error condition, extended = 0xff\n")); + // We should handle this condition. + } + } + else + { + offset = ((efuseHeader >> 4) & 0x0f); + wden = (efuseHeader & 0x0f); + } + + if(offset < EFUSE_BT_MAX_SECTION) + { + // Get word enable value from PG header + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wden)); + + for(i=0; i= EFUSE_REAL_CONTENT_LEN) + bCheckNextBank = _TRUE; + else + bCheckNextBank = _FALSE; + } + } + if(!bCheckNextBank) + { + //RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Stop to check next bank\n")); + break; + } + } + + // switch bank back to bank 0 for later BT and wifi use. + Hal_EfuseSwitchToBank(Adapter, 0, bPseudoTest); + + // + // 3. Collect 16 sections and 4 word unit into Efuse map. + // + for(i=0; i> 8) & 0xff); + } + } + + // + // 4. Copy from Efuse map to output pointer memory!!! + // + for(i=0; i<_size_byte; i++) + { + pbuf[i] = efuseTbl[_offset+i]; + } + + // + // 5. Calculate Efuse utilization. + // + efuse_usage = (u8)((efuse_utilized*100)/EFUSE_BT_REAL_CONTENT_LEN); + if(bPseudoTest) + { + fakeBTEfuseUsedBytes = (EFUSE_REAL_CONTENT_LEN*(bank-1))+eFuse_Addr-1; + } + else + { + BTEfuseUsedBytes = (EFUSE_REAL_CONTENT_LEN*(bank-1))+eFuse_Addr-1; + } + + for(i=0;i>4) & 0x0F; + hworden = efuse_data & 0x0F; + word_cnts = Efuse_CalculateWordCnts(hworden); + //read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + } + else + { + bContinual = _FALSE ; + } + } + + return efuse_addr; +} + +static u16 +Hal_EfuseGetCurrentSize_BT(IN PADAPTER pAdapter, + IN BOOLEAN bPseudoTest) +{ + int bContinual = _TRUE; + u16 efuse_addr = 0; + u8 hoffset=0,hworden=0; + u8 efuse_data,word_cnts=0; + u8 bank=0, startBank=0; + u16 retU2=0; + u32 total_efuse_used=0; + + if(bPseudoTest) + { + efuse_addr = (u16)((fakeBTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN)); + startBank = (u8)(1+(fakeBTEfuseUsedBytes/EFUSE_REAL_CONTENT_LEN)); + } + else + { + efuse_addr = (u16)((BTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN)); + startBank = (u8)(1+(BTEfuseUsedBytes/EFUSE_REAL_CONTENT_LEN)); + } + + if((startBank < 1) || (startBank >= EFUSE_MAX_BANK)) + DBG_8192C("Error, bank error, bank=%d\n", bank); + + //RTPRINT(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT(), start bank=%d, start_efuse_addr = %d\n", startBank, efuse_addr)); + + for(bank=startBank; bank> 5) | ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } + } + else + { + hoffset = (efuse_data>>4) & 0x0F; + hworden = efuse_data & 0x0F; + } + word_cnts = Efuse_CalculateWordCnts(hworden); + //read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + } + else + { + bContinual = _FALSE ; + } + } + + // Check if we need to check next bank efuse + if(efuse_addr < (EFUSE_REAL_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK)) + { + break;// don't need to check next bank. + } + } + + retU2 = ((bank-1)*EFUSE_REAL_CONTENT_LEN)+efuse_addr; + if(bPseudoTest) + { + fakeBTEfuseUsedBytes = retU2; + //RTPRINT(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT(), return %d\n", fakeBTEfuseUsedBytes)); + } + else + { + BTEfuseUsedBytes = retU2; + //RTPRINT(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT(), return %d\n", BTEfuseUsedBytes)); + } + + return retU2; +} + + +static u16 +hal_EfuseGetCurrentSize_8723(IN PADAPTER pAdapter, + IN BOOLEAN bPseudoTest) +{ + int bContinual = _TRUE; + + u16 efuse_addr = 0; + u8 hoffset=0,hworden=0; + u8 efuse_data,word_cnts=0; + + if(bPseudoTest) + { + efuse_addr = (u16)(fakeEfuseUsedBytes); + } + else + { + rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); + } + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723(), start_efuse_addr = %d\n", efuse_addr)); + + while ( bContinual && + efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest) && + AVAILABLE_EFUSE_ADDR(efuse_addr)) + { + if(efuse_data!=0xFF) + { + if((efuse_data&0x1F) == 0x0F) //extended header + { + hoffset = efuse_data; + efuse_addr++; + efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest); + if((efuse_data & 0x0F) == 0x0F) + { + efuse_addr++; + continue; + } + else + { + hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } + } + else + { + hoffset = (efuse_data>>4) & 0x0F; + hworden = efuse_data & 0x0F; + } + word_cnts = Efuse_CalculateWordCnts(hworden); + //read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + } + else + { + bContinual = _FALSE ; + } + } + + if(bPseudoTest) + { + fakeEfuseUsedBytes = efuse_addr; + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723(), return %d\n", fakeEfuseUsedBytes)); + } + else + { + rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723(), return %d\n", efuse_addr)); + } + + return efuse_addr; +} + +static u16 +Hal_EfuseGetCurrentSize_Pseudo(IN PADAPTER pAdapter, + IN BOOLEAN bPseudoTest) +{ + u16 ret=0; + + ret = hal_EfuseGetCurrentSize_8723(pAdapter, bPseudoTest); + + return ret; +} + +static u16 +rtl8192c_EfuseGetCurrentSize( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest) +{ + u16 ret=0; + + if(efuseType == EFUSE_WIFI) + { + if(bPseudoTest) + { + ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest); + } + else + { + if(IS_HARDWARE_TYPE_8192C(pAdapter)) + { + ret = hal_EfuseGetCurrentSize_8192C(pAdapter, bPseudoTest); + } + else if(IS_HARDWARE_TYPE_8723A(pAdapter)) + { + ret = hal_EfuseGetCurrentSize_8723(pAdapter, bPseudoTest); + } + } + } + else + { + ret = Hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest); + } + + return ret; +} + +static int +hal_EfusePgPacketRead_8192C( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 ReadState = PG_STATE_HEADER; + + int bContinual = _TRUE; + int bDataEmpty = _TRUE ; + + u8 efuse_data,word_cnts=0; + u16 efuse_addr = 0; + u8 hoffset=0,hworden=0; + u8 tmpidx=0; + u8 tmpdata[8]; + + if(data==NULL) return _FALSE; + if(offset>15) return _FALSE; + + + _rtw_memset((PVOID)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE); + _rtw_memset((PVOID)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE); + + // + // Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. + // Skip dummy parts to prevent unexpected data read from Efuse. + // By pass right now. 2009.02.19. + // + while(bContinual && (efuse_addr < EFUSE_REAL_CONTENT_LEN) ) + { + //------- Header Read ------------- + if(ReadState & PG_STATE_HEADER) + { + if(efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest)&&(efuse_data!=0xFF)){ + hoffset = (efuse_data>>4) & 0x0F; + hworden = efuse_data & 0x0F; + word_cnts = Efuse_CalculateWordCnts(hworden); + bDataEmpty = _TRUE ; + + if(hoffset==offset){ + for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++){ + if(efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx ,&efuse_data, bPseudoTest) ){ + tmpdata[tmpidx] = efuse_data; + if(efuse_data!=0xff){ + bDataEmpty = _FALSE; + } + } + } + if(bDataEmpty==_FALSE){ + ReadState = PG_STATE_DATA; + }else{//read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + } + else{//read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + + } + else{ + bContinual = _FALSE ; + } + } + //------- Data section Read ------------- + else if(ReadState & PG_STATE_DATA) + { + efuse_WordEnableDataRead(hworden,tmpdata,data); + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + + } + + if( (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff) && (data[3]==0xff) && + (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff) && (data[7]==0xff)) + return _FALSE; + else + return _TRUE; + +} + +static int +hal_EfusePgPacketRead_8723( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 ReadState = PG_STATE_HEADER; + + int bContinual = _TRUE; + int bDataEmpty = _TRUE ; + + u8 efuse_data,word_cnts=0; + u16 efuse_addr = 0; + u8 hoffset=0,hworden=0; + u8 tmpidx=0; + u8 tmpdata[8]; + u8 max_section=0; + u8 tmp_header = 0; + + EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (PVOID)&max_section, bPseudoTest); + + if(data==NULL) + return _FALSE; + if(offset>max_section) + return _FALSE; + + _rtw_memset((PVOID)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE); + _rtw_memset((PVOID)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE); + + + // + // Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. + // Skip dummy parts to prevent unexpected data read from Efuse. + // By pass right now. 2009.02.19. + // + while(bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr) ) + { + //------- Header Read ------------- + if(ReadState & PG_STATE_HEADER) + { + if(efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest)&&(efuse_data!=0xFF)) + { + if(EXT_HEADER(efuse_data)) + { + tmp_header = efuse_data; + efuse_addr++; + efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest); + if(!ALL_WORDS_DISABLED(efuse_data)) + { + hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } + else + { + DBG_8192C("Error, All words disabled\n"); + efuse_addr++; + continue; + } + } + else + { + hoffset = (efuse_data>>4) & 0x0F; + hworden = efuse_data & 0x0F; + } + word_cnts = Efuse_CalculateWordCnts(hworden); + bDataEmpty = _TRUE ; + + if(hoffset==offset) + { + for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++) + { + if(efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx ,&efuse_data, bPseudoTest) ) + { + tmpdata[tmpidx] = efuse_data; + if(efuse_data!=0xff) + { + bDataEmpty = _FALSE; + } + } + } + if(bDataEmpty==_FALSE){ + ReadState = PG_STATE_DATA; + }else{//read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + } + else{//read next header + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + + } + else{ + bContinual = _FALSE ; + } + } + //------- Data section Read ------------- + else if(ReadState & PG_STATE_DATA) + { + efuse_WordEnableDataRead(hworden,tmpdata,data); + efuse_addr = efuse_addr + (word_cnts*2)+1; + ReadState = PG_STATE_HEADER; + } + + } + + if( (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff) && (data[3]==0xff) && + (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff) && (data[7]==0xff)) + return _FALSE; + else + return _TRUE; + +} + +static int +Hal_EfusePgPacketRead( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + if(IS_HARDWARE_TYPE_8192C(pAdapter)) + { + ret = hal_EfusePgPacketRead_8192C(pAdapter, offset, data, bPseudoTest); + } + else if(IS_HARDWARE_TYPE_8723A(pAdapter)) + { + ret = hal_EfusePgPacketRead_8723(pAdapter, offset, data, bPseudoTest); + } + + return ret; +} + +static int +Hal_EfusePgPacketRead_Pseudo( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + ret = hal_EfusePgPacketRead_8723(pAdapter, offset, data, bPseudoTest); + + return ret; +} + +static int +rtl8192c_Efuse_PgPacketRead( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + if(bPseudoTest) + { + ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest); + } + else + { + ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest); + } + + return ret; +} + +static BOOLEAN +hal_EfuseFixHeaderProcess( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN PPGPKT_STRUCT pFixPkt, + IN u16 *pAddr, + IN BOOLEAN bPseudoTest +) +{ + u8 originaldata[8], badworden=0; + u16 efuse_addr=*pAddr; + u32 PgWriteSuccess=0; + + _rtw_memset((PVOID)originaldata, 0xff, 8); + + if(Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) + { //check if data exist + badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest); + + if(badworden != 0xf) // write fail + { + if(efuseType == EFUSE_WIFI) + PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest); + else + PgWriteSuccess = hal_EfusePgPacketWrite_BT(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest); + if(!PgWriteSuccess) + return _FALSE; + else + efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); + } + else + { + efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1; + } + } + else + { + efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1; + } + *pAddr = efuse_addr; + return _TRUE; +} + +static BOOLEAN +hal_EfusePgPacketWrite2ByteHeader( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest) +{ + BOOLEAN bRet=_FALSE, bContinual=_TRUE; + u16 efuse_addr=*pAddr, efuse_max_available_len=0; + u8 pg_header=0, tmp_header=0, pg_header_temp=0; + u8 repeatcnt=0; + + //RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 2byte header\n")); + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (PVOID)&efuse_max_available_len, bPseudoTest); + + while(efuse_addr < efuse_max_available_len) + { + pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; + //RTPRINT(FEEPROM, EFUSE_PG, ("pg_header = 0x%x\n", pg_header)); + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + + while(tmp_header == 0xFF) + { + if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for pg_header!!\n")); + return _FALSE; + } + + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + } + + //to write ext_header + if(tmp_header == pg_header) + { + efuse_addr++; + pg_header_temp = pg_header; + pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; + + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + + while(tmp_header == 0xFF) + { + if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for ext_header!!\n")); + return _FALSE; + } + + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + } + + if((tmp_header & 0x0F) == 0x0F) //word_en PG fail + { + if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("Repeat over limit for word_en!!\n")); + return _FALSE; + } + else + { + efuse_addr++; + continue; + } + } + else if(pg_header != tmp_header) //offset PG fail + { + PGPKT_STRUCT fixPkt; + //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for offset PG fail, need to cover the existed data\n")); + fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1); + fixPkt.word_en = tmp_header & 0x0F; + fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); + if(!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) + return _FALSE; + } + else + { + bRet = _TRUE; + break; + } + } + else if ((tmp_header & 0x1F) == 0x0F) //wrong extended header + { + efuse_addr+=2; + continue; + } + } + + *pAddr = efuse_addr; + return bRet; +} + +static BOOLEAN +hal_EfusePgPacketWrite1ByteHeader( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest) +{ + BOOLEAN bRet=_FALSE; + u8 pg_header=0, tmp_header=0; + u16 efuse_addr=*pAddr; + u8 repeatcnt=0; + + //RTPRINT(FEEPROM, EFUSE_PG, ("Wirte 1byte header\n")); + pg_header = ((pTargetPkt->offset << 4) & 0xf0) |pTargetPkt->word_en; + + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + + while(tmp_header == 0xFF) + { + if(repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) + { + return _FALSE; + } + efuse_OneByteWrite(pAdapter,efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter,efuse_addr, &tmp_header, bPseudoTest); + } + + if(pg_header == tmp_header) + { + bRet = _TRUE; + } + else + { + PGPKT_STRUCT fixPkt; + //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition for fixed PG packet, need to cover the existed data\n")); + fixPkt.offset = (tmp_header>>4) & 0x0F; + fixPkt.word_en = tmp_header & 0x0F; + fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en); + if(!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest)) + return _FALSE; + } + + *pAddr = efuse_addr; + return bRet; +} + +static BOOLEAN +hal_EfusePgPacketWriteData( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest) +{ + BOOLEAN bRet=_FALSE; + u16 efuse_addr=*pAddr; + u8 badworden=0; + u32 PgWriteSuccess=0; + + badworden = 0x0f; + badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest); + if(badworden == 0x0F) + { + // write ok + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData ok!!\n")); + return _TRUE; + } + else + { + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWriteData Fail!!\n")); + //reorganize other pg packet + if(efuseType == EFUSE_WIFI) + PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + else + PgWriteSuccess = hal_EfusePgPacketWrite_BT(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + if(!PgWriteSuccess) + return _FALSE; + else + return _TRUE; + } + + return bRet; +} + +static BOOLEAN +hal_EfusePgPacketWriteHeader( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest) +{ + BOOLEAN bRet=_FALSE; + + if(pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) + { + bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); + } + else + { + bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest); + } + + return bRet; +} + +static BOOLEAN +hal_EfusePgCheckAvailableAddr( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest + ) +{ + u16 efuse_max_available_len=0; + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&efuse_max_available_len, bPseudoTest); + //RTPRINT(FEEPROM, EFUSE_PG, ("efuse_max_available_len = %d\n", efuse_max_available_len)); + + if(Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgCheckAvailableAddr error!!\n")); + return _FALSE; + } + return _TRUE; +} + +static VOID +hal_EfuseConstructPGPkt( + IN u8 offset, + IN u8 word_en, + IN u8 *pData, + IN PPGPKT_STRUCT pTargetPkt + +) +{ + _rtw_memset((PVOID)pTargetPkt->data, 0xFF, sizeof(u8)*8); + pTargetPkt->offset = offset; + pTargetPkt->word_en= word_en; + efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); + pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); + + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseConstructPGPkt(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts)); +} + +static BOOLEAN +hal_EfuseCheckIfDatafollowed( + IN PADAPTER pAdapter, + IN u8 word_cnts, + IN u16 startAddr, + IN BOOLEAN bPseudoTest + ) +{ + BOOLEAN bRet=_FALSE; + u8 i, efuse_data; + + for(i=0; i<(word_cnts*2) ; i++) + { + if(efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest)&&(efuse_data != 0xFF)) + bRet = _TRUE; + } + + return bRet; +} + +static BOOLEAN +wordEnMatched( + IN PPGPKT_STRUCT pTargetPkt, + IN PPGPKT_STRUCT pCurPkt, + IN u8 *pWden +) +{ + u8 match_word_en = 0x0F; // default all words are disabled + u8 i; + + // check if the same words are enabled both target and current PG packet + if( ((pTargetPkt->word_en & BIT0) == 0) && + ((pCurPkt->word_en & BIT0) == 0) ) + { + match_word_en &= ~BIT0; // enable word 0 + } + if( ((pTargetPkt->word_en & BIT1) == 0) && + ((pCurPkt->word_en & BIT1) == 0) ) + { + match_word_en &= ~BIT1; // enable word 1 + } + if( ((pTargetPkt->word_en & BIT2) == 0) && + ((pCurPkt->word_en & BIT2) == 0) ) + { + match_word_en &= ~BIT2; // enable word 2 + } + if( ((pTargetPkt->word_en & BIT3) == 0) && + ((pCurPkt->word_en & BIT3) == 0) ) + { + match_word_en &= ~BIT3; // enable word 3 + } + + *pWden = match_word_en; + + if(match_word_en != 0xf) + return _TRUE; + else + return _FALSE; +} + +static BOOLEAN +hal_EfusePartialWriteCheck( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u16 *pAddr, + IN PPGPKT_STRUCT pTargetPkt, + IN BOOLEAN bPseudoTest + ) +{ + BOOLEAN bRet=_FALSE; + u8 i, efuse_data=0, cur_header=0; + u8 new_wden=0, matched_wden=0, badworden=0; + u16 startAddr=0, efuse_max_available_len=0, efuse_max=0; + PGPKT_STRUCT curPkt; + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (PVOID)&efuse_max_available_len, bPseudoTest); + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&efuse_max, bPseudoTest); + + if(efuseType == EFUSE_WIFI) + { + if(bPseudoTest) + { + startAddr = (u16)(fakeEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN); + } + else + { + rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr); + startAddr%=EFUSE_REAL_CONTENT_LEN; + } + } + else + { + if(bPseudoTest) + { + startAddr = (u16)(fakeBTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN); + } + else + { + startAddr = (u16)(BTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN); + } + } + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePartialWriteCheck(), startAddr=%d\n", startAddr)); + + while(1) + { + if(startAddr >= efuse_max_available_len) + { + bRet = _FALSE; + break; + } + + if(efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF)) + { + if(EXT_HEADER(efuse_data)) + { + cur_header = efuse_data; + startAddr++; + efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest); + if(ALL_WORDS_DISABLED(efuse_data)) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("Error condition, all words disabled")); + bRet = _FALSE; + break; + } + else + { + curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); + curPkt.word_en = efuse_data & 0x0F; + } + } + else + { + cur_header = efuse_data; + curPkt.offset = (cur_header>>4) & 0x0F; + curPkt.word_en = cur_header & 0x0F; + } + + curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en); + // if same header is found but no data followed + // write some part of data followed by the header. + if( (curPkt.offset == pTargetPkt->offset) && + (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1, bPseudoTest)) && + wordEnMatched(pTargetPkt, &curPkt, &matched_wden) ) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("Need to partial write data by the previous wrote header\n")); + // Here to write partial data + badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest); + if(badworden != 0x0F) + { + u32 PgWriteSuccess=0; + // if write fail on some words, write these bad words again + if(efuseType == EFUSE_WIFI) + PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + else + PgWriteSuccess = hal_EfusePgPacketWrite_BT(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + + if(!PgWriteSuccess) + { + bRet = _FALSE; // write fail, return + break; + } + } + // partial write ok, update the target packet for later use + for(i=0; i<4; i++) + { + if((matched_wden & (0x1<word_en |= (0x1<word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); + } + // read from next header + startAddr = startAddr + (curPkt.word_cnts*2) +1; + } + else + { + // not used header, 0xff + *pAddr = startAddr; + //RTPRINT(FEEPROM, EFUSE_PG, ("Started from unused header offset=%d\n", startAddr)); + bRet = _TRUE; + break; + } + } + return bRet; +} + +static BOOLEAN +hal_EfusePgPacketWrite_BT( + IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *pData, + IN BOOLEAN bPseudoTest + ) +{ + PGPKT_STRUCT targetPkt; + u16 startAddr=0; + u8 efuseType=EFUSE_BT; + + if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest)) + return _FALSE; + + hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); + + if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + return _TRUE; +} + +static BOOLEAN +hal_EfusePgPacketWrite_8723( + IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *pData, + IN BOOLEAN bPseudoTest + ) +{ + PGPKT_STRUCT targetPkt; + u16 startAddr=0; + u8 efuseType=EFUSE_WIFI; + + if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest)) + return _FALSE; + + hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); + + if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + return _TRUE; +} + +static int +hal_EfusePgPacketWrite_8192C(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 WriteState = PG_STATE_HEADER; + + int bContinual = _TRUE,bDataEmpty=_TRUE, bResult = _TRUE; + u16 efuse_addr = 0; + u8 efuse_data; + + u8 pg_header = 0; + + u8 tmp_word_cnts=0,target_word_cnts=0; + u8 tmp_header,match_word_en,tmp_word_en; + + PGPKT_STRUCT target_pkt; + PGPKT_STRUCT tmp_pkt; + + u8 originaldata[sizeof(u8)*8]; + u8 tmpindex = 0,badworden = 0x0F; + + static int repeat_times = 0; + u8 efuseType=EFUSE_WIFI; + + // + // Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. + // So we have to prevent unexpected data string connection, which will cause + // incorrect data auto-load from HW. The total size is equal or smaller than 498bytes + // (i.e., offset 0~497, and dummy 1bytes) expected after CP test. + // 2009.02.19. + // + if( Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= (EFUSE_REAL_CONTENT_LEN-EFUSE_OOB_PROTECT_BYTES)) + { + //RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfusePgPacketWrite_8192C(), over size\n")); + return _FALSE; + } + + // Init the 8 bytes content as 0xff + target_pkt.offset = offset; + target_pkt.word_en= word_en; + + _rtw_memset((PVOID)target_pkt.data, 0xFF, sizeof(u8)*8); + + efuse_WordEnableDataRead(word_en,data,target_pkt.data); + target_word_cnts = Efuse_CalculateWordCnts(target_pkt.word_en); + + //efuse_reg_ctrl(pAdapter,_TRUE);//power on + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE Power ON\n")); + + // + // Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. + // So we have to prevent unexpected data string connection, which will cause + // incorrect data auto-load from HW. Dummy 1bytes is additional. + // 2009.02.19. + // + while( bContinual && (efuse_addr < (EFUSE_REAL_CONTENT_LEN-EFUSE_OOB_PROTECT_BYTES)) ) + { + + if(WriteState==PG_STATE_HEADER) + { + bDataEmpty=_TRUE; + badworden = 0x0F; + //************ so ******************* + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE PG_STATE_HEADER\n")); + if ( efuse_OneByteRead(pAdapter, efuse_addr ,&efuse_data, bPseudoTest) && + (efuse_data!=0xFF)) + { + tmp_header = efuse_data; + + tmp_pkt.offset = (tmp_header>>4) & 0x0F; + tmp_pkt.word_en = tmp_header & 0x0F; + tmp_word_cnts = Efuse_CalculateWordCnts(tmp_pkt.word_en); + + //************ so-1 ******************* + if(tmp_pkt.offset != target_pkt.offset) + { + efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet + #if (EFUSE_ERROE_HANDLE == 1) + WriteState = PG_STATE_HEADER; + #endif + } + else + { + //************ so-2 ******************* + for(tmpindex=0 ; tmpindex<(tmp_word_cnts*2) ; tmpindex++) + { + if(efuse_OneByteRead(pAdapter, (efuse_addr+1+tmpindex) ,&efuse_data, bPseudoTest)&&(efuse_data != 0xFF)){ + bDataEmpty = _FALSE; + } + } + //************ so-2-1 ******************* + if(bDataEmpty == _FALSE) + { + efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet + #if (EFUSE_ERROE_HANDLE == 1) + WriteState=PG_STATE_HEADER; + #endif + } + else + {//************ so-2-2 ******************* + match_word_en = 0x0F; + if( !( (target_pkt.word_en&BIT0)|(tmp_pkt.word_en&BIT0) )) + { + match_word_en &= (~BIT0); + } + if( !( (target_pkt.word_en&BIT1)|(tmp_pkt.word_en&BIT1) )) + { + match_word_en &= (~BIT1); + } + if( !( (target_pkt.word_en&BIT2)|(tmp_pkt.word_en&BIT2) )) + { + match_word_en &= (~BIT2); + } + if( !( (target_pkt.word_en&BIT3)|(tmp_pkt.word_en&BIT3) )) + { + match_word_en &= (~BIT3); + } + + //************ so-2-2-A ******************* + if((match_word_en&0x0F)!=0x0F) + { + badworden = Efuse_WordEnableDataWrite(pAdapter,efuse_addr+1, tmp_pkt.word_en ,target_pkt.data, bPseudoTest); + + //************ so-2-2-A-1 ******************* + //############################ + if(0x0F != (badworden&0x0F)) + { + u8 reorg_offset = offset; + u8 reorg_worden=badworden; + Efuse_PgPacketWrite(pAdapter,reorg_offset,reorg_worden,originaldata, bPseudoTest); + } + //############################ + + tmp_word_en = 0x0F; + if( (target_pkt.word_en&BIT0)^(match_word_en&BIT0) ) + { + tmp_word_en &= (~BIT0); + } + if( (target_pkt.word_en&BIT1)^(match_word_en&BIT1) ) + { + tmp_word_en &= (~BIT1); + } + if( (target_pkt.word_en&BIT2)^(match_word_en&BIT2) ) + { + tmp_word_en &= (~BIT2); + } + if( (target_pkt.word_en&BIT3)^(match_word_en&BIT3) ) + { + tmp_word_en &=(~BIT3); + } + + //************ so-2-2-A-2 ******************* + if((tmp_word_en&0x0F)!=0x0F){ + //reorganize other pg packet + //efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr + efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); + //=========================== + target_pkt.offset = offset; + target_pkt.word_en= tmp_word_en; + //=========================== + }else{ + bContinual = _FALSE; + } + #if (EFUSE_ERROE_HANDLE == 1) + WriteState=PG_STATE_HEADER; + repeat_times++; + if(repeat_times>EFUSE_REPEAT_THRESHOLD_){ + bContinual = _FALSE; + bResult = _FALSE; + } + #endif + } + else{//************ so-2-2-B ******************* + //reorganize other pg packet + efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr + //=========================== + target_pkt.offset = offset; + target_pkt.word_en= target_pkt.word_en; + //=========================== + #if (EFUSE_ERROE_HANDLE == 1) + WriteState=PG_STATE_HEADER; + #endif + } + } + } + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE PG_STATE_HEADER-1\n")); + } + else //************ s1: header == oxff ******************* + { + pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en; + + efuse_OneByteWrite(pAdapter,efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter,efuse_addr, &tmp_header, bPseudoTest); + + if(tmp_header == pg_header) + { //************ s1-1******************* + WriteState = PG_STATE_DATA; + } + #if (EFUSE_ERROE_HANDLE == 1) + else if(tmp_header == 0xFF){//************ s1-3: if Write or read func doesn't work ******************* + //efuse_addr doesn't change + WriteState = PG_STATE_HEADER; + repeat_times++; + if(repeat_times>EFUSE_REPEAT_THRESHOLD_){ + bContinual = _FALSE; + bResult = _FALSE; + } + } + #endif + else + {//************ s1-2 : fixed the header procedure ******************* + tmp_pkt.offset = (tmp_header>>4) & 0x0F; + tmp_pkt.word_en= tmp_header & 0x0F; + tmp_word_cnts = Efuse_CalculateWordCnts(tmp_pkt.word_en); + + //************ s1-2-A :cover the exist data ******************* + //memset(originaldata,0xff,sizeof(UINT8)*8); + _rtw_memset((PVOID)originaldata, 0xff, sizeof(u8)*8); + + if(Efuse_PgPacketRead( pAdapter, tmp_pkt.offset,originaldata, bPseudoTest)) + { //check if data exist + //efuse_reg_ctrl(pAdapter,_TRUE);//power on + badworden = Efuse_WordEnableDataWrite(pAdapter,efuse_addr+1,tmp_pkt.word_en,originaldata, bPseudoTest); + //############################ + if(0x0F != (badworden&0x0F)) + { + u8 reorg_offset = tmp_pkt.offset; + u8 reorg_worden=badworden; + Efuse_PgPacketWrite(pAdapter,reorg_offset,reorg_worden,originaldata, bPseudoTest); + efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); + } + //############################ + else{ + efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet + } + } + //************ s1-2-B: wrong address******************* + else + { + efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet + } + + #if (EFUSE_ERROE_HANDLE == 1) + WriteState=PG_STATE_HEADER; + repeat_times++; + if(repeat_times>EFUSE_REPEAT_THRESHOLD_){ + bContinual = _FALSE; + bResult = _FALSE; + } + #endif + + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE PG_STATE_HEADER-2\n")); + } + + } + + } + //write data state + else if(WriteState==PG_STATE_DATA) + { //************ s1-1 ******************* + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE PG_STATE_DATA\n")); + badworden = 0x0f; + badworden = Efuse_WordEnableDataWrite(pAdapter,efuse_addr+1,target_pkt.word_en,target_pkt.data, bPseudoTest); + if((badworden&0x0F)==0x0F) + { //************ s1-1-A ******************* + bContinual = _FALSE; + } + else + {//reorganize other pg packet //************ s1-1-B ******************* + efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr + + //=========================== + target_pkt.offset = offset; + target_pkt.word_en= badworden; + target_word_cnts = Efuse_CalculateWordCnts(target_pkt.word_en); + //=========================== + #if (EFUSE_ERROE_HANDLE == 1) + WriteState=PG_STATE_HEADER; + repeat_times++; + if(repeat_times>EFUSE_REPEAT_THRESHOLD_){ + bContinual = _FALSE; + bResult = _FALSE; + } + #endif + //RTPRINT(FEEPROM, EFUSE_PG, ("EFUSE PG_STATE_HEADER-3\n")); + } + } + } + + if(efuse_addr >= (EFUSE_REAL_CONTENT_LEN-EFUSE_OOB_PROTECT_BYTES)) + { + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("hal_EfusePgPacketWrite_8192C(): efuse_addr(%#x) Out of size!!\n", efuse_addr)); + } + //efuse_reg_ctrl(pAdapter,_FALSE);//power off + + return _TRUE; +} + +static int +Hal_EfusePgPacketWrite_Pseudo(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret; + + ret = hal_EfusePgPacketWrite_8723(pAdapter, offset, word_en, data, bPseudoTest); + + return ret; +} + +static int +Hal_EfusePgPacketWrite(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + if(IS_HARDWARE_TYPE_8192C(pAdapter)) + { + ret = hal_EfusePgPacketWrite_8192C(pAdapter, offset, word_en, data, bPseudoTest); + } + else if(IS_HARDWARE_TYPE_8723A(pAdapter)) + { + ret = hal_EfusePgPacketWrite_8723(pAdapter, offset, word_en, data, bPseudoTest); + } + + return ret; +} + +static int +rtl8192c_Efuse_PgPacketWrite(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret; + + if(bPseudoTest) + { + ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest); + } + else + { + ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest); + } + return ret; +} + +VOID +rtl8192c_EfuseParseIDCode( + IN PADAPTER pAdapter, + IN u8 *hwinfo + ) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u16 i,EEPROMId; + + // Checl 0x8129 again for making sure autoload status!! + EEPROMId = *((u16 *)&hwinfo[0]); + if( le16_to_cpu(EEPROMId) != RTL_EEPROM_ID) + { + DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId); + pEEPROM->bautoload_fail_flag = _TRUE; + } + else + { + pEEPROM->bautoload_fail_flag = _FALSE; + } + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM ID = 0x%4x\n", EEPROMId)); +} + +void rtl8192c_read_chip_version(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + pHalData->VersionID = rtl8192c_ReadChipVersion(pAdapter); +} + +void hal_notch_filter_8192c(_adapter *adapter, bool enable) +{ + if (enable) { + DBG_871X("Enable notch filter\n"); + rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1); + } else { + DBG_871X("Disable notch filter\n"); + rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1); + } +} + +void hal_reset_security_engine_8192c(_adapter * adapter) +{ + rtw_write8(adapter, 0x522, 0xFF); + rtw_write8(adapter, 0x21, 0x35); + rtw_usleep_os(300); + rtw_write8(adapter, 0x101, rtw_read8(adapter,0x101)&~0x02); + rtw_write8(adapter, 0x101, rtw_read8(adapter,0x101)|0x02); + rtw_write8(adapter, 0x21, 0x55); + rtw_write8(adapter, 0x522, 0x00); +} + +s32 c2h_id_filter_ccx_8192c(u8 id) +{ + s32 ret = _FALSE; + if (id == C2H_CCX_TX_RPT) + ret = _TRUE; + + return ret; +} + +static s32 c2h_handler_8192c(_adapter *padapter, struct c2h_evt_hdr *c2h_evt) +{ + s32 ret = _SUCCESS; + u8 i = 0; + + if (c2h_evt == NULL) { + DBG_8192C("%s c2h_evt is NULL\n",__FUNCTION__); + ret = _FAIL; + goto exit; + } + + switch (c2h_evt->id) { + case C2H_CCX_TX_RPT: + handle_txrpt_ccx_8192c(padapter, c2h_evt->payload); + break; + default: + ret = _FAIL; + break; + } + +exit: + return ret; +} + +void rtl8192c_set_hal_ops(struct hal_ops *pHalFunc) +{ + pHalFunc->free_hal_data = &rtl8192c_free_hal_data; + + pHalFunc->dm_init = &rtl8192c_init_dm_priv; + pHalFunc->dm_deinit = &rtl8192c_deinit_dm_priv; + pHalFunc->read_chip_version = &rtl8192c_read_chip_version; + + pHalFunc->set_bwmode_handler = &PHY_SetBWMode8192C; + pHalFunc->set_channel_handler = &PHY_SwChnl8192C; + + pHalFunc->hal_dm_watchdog = &rtl8192c_HalDmWatchDog; + + pHalFunc->Add_RateATid = &rtl8192c_Add_RateATid; + +#ifdef CONFIG_ANTENNA_DIVERSITY + pHalFunc->AntDivBeforeLinkHandler = &SwAntDivBeforeLink8192C; + pHalFunc->AntDivCompareHandler = &SwAntDivCompare8192C; +#endif + + pHalFunc->read_bbreg = &rtl8192c_PHY_QueryBBReg; + pHalFunc->write_bbreg = &rtl8192c_PHY_SetBBReg; + pHalFunc->read_rfreg = &rtl8192c_PHY_QueryRFReg; + pHalFunc->write_rfreg = &rtl8192c_PHY_SetRFReg; + + //Efuse related function + pHalFunc->EfusePowerSwitch = &rtl8192c_EfusePowerSwitch; + pHalFunc->ReadEFuse = &rtl8192c_ReadEFuse; + pHalFunc->EFUSEGetEfuseDefinition = &rtl8192c_EFUSE_GetEfuseDefinition; + pHalFunc->EfuseGetCurrentSize = &rtl8192c_EfuseGetCurrentSize; + pHalFunc->Efuse_PgPacketRead = &rtl8192c_Efuse_PgPacketRead; + pHalFunc->Efuse_PgPacketWrite = &rtl8192c_Efuse_PgPacketWrite; + pHalFunc->Efuse_WordEnableDataWrite = &rtl8192c_Efuse_WordEnableDataWrite; + +#ifdef DBG_CONFIG_ERROR_DETECT + pHalFunc->sreset_init_value = &sreset_init_value; + pHalFunc->sreset_reset_value = &sreset_reset_value; + pHalFunc->silentreset = &sreset_reset; + pHalFunc->sreset_xmit_status_check = &rtl8192c_sreset_xmit_status_check; + pHalFunc->sreset_linked_status_check = &rtl8192c_sreset_linked_status_check; + pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status; + pHalFunc->sreset_inprogress= &sreset_inprogress; +#endif + +#ifdef CONFIG_IOL + pHalFunc->IOL_exec_cmds_sync = &rtl8192c_IOL_exec_cmds_sync; +#endif + pHalFunc->hal_notch_filter = &hal_notch_filter_8192c; + pHalFunc->hal_reset_security_engine = hal_reset_security_engine_8192c; + + pHalFunc->c2h_handler = c2h_handler_8192c; + pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8192c; +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c new file mode 100755 index 00000000..a4194c4c --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c @@ -0,0 +1,1207 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8192C_MP_C_ +#ifdef CONFIG_MP_INCLUDED + +#include +#include + +#ifdef CONFIG_RTL8192C +#include +#endif + + + +s32 Hal_SetPowerTracking(PADAPTER padapter, u8 enable) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + + if (!netif_running(padapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: interface not opened!\n")); + return _FAIL; + } + + if (check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: not in MP mode!\n")); + return _FAIL; + } + + if (enable) + pdmpriv->TxPowerTrackControl = _TRUE; + else + pdmpriv->TxPowerTrackControl = _FALSE; + + return _SUCCESS; +} + +void Hal_GetPowerTracking(PADAPTER padapter, u8 *enable) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + + *enable = pdmpriv->TxPowerTrackControl; +} + +static void Hal_disable_dm(PADAPTER padapter) +{ + u8 v8; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + + //3 1. disable firmware dynamic mechanism + // disable Power Training, Rate Adaptive + v8 = rtw_read8(padapter, REG_BCN_CTRL); + v8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, v8); + + //3 2. disable driver dynamic mechanism + // disable Dynamic Initial Gain + // disable High Power + // disable Power Tracking + Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); + + // enable APK, LCK and IQK but disable power tracking + pdmpriv->TxPowerTrackControl = _FALSE; + Switch_DM_Func(padapter, DYNAMIC_FUNC_SS, _TRUE); +} + +/*----------------------------------------------------------------------------- + * Function: mpt_SwitchRfSetting + * + * Overview: Change RF Setting when we siwthc channel/rate/BW for MP. + * + * Input: IN PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series. + * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3. + * + *---------------------------------------------------------------------------*/ +void Hal_mpt_SwitchRfSetting(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mp_priv *pmp = &pAdapter->mppriv; + u8 ChannelToSw = pmp->channel, eRFPath = RF_PATH_A; + u8 ulRateIdx = pmp->rateidx; + u8 ulbandwidth = pmp->bandwidth; + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + BOOLEAN bInteralPA = _FALSE; + u32 value = 0; + +#ifdef CONFIG_USB_HCI + if (IS_92C_SERIAL(pHalData->VersionID)) + { + //92CE-VAU (92cu mCard) + if( BOARD_MINICARD == pHalData->BoardType) + { + if (ulRateIdx < MPT_RATE_6M) // CCK rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x0F400); + } + else //OFDM~MCS rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F000); + } + } + else //92CU dongle + { + if (ulRateIdx < MPT_RATE_6M) // CCK rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x0F400); + } + else if (ChannelToSw & BIT0) // OFDM rate, odd number channel + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F200); + } + else if (ChannelToSw == 4) // OFDM rate, even number channel + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x28200); + write_rfreg(pAdapter, 0, RF_SYN_G6, 0xe0004); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x709); + rtw_msleep_os(1); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x4B333); + } + else if(ChannelToSw == 10) // OFDM rate, even number channel + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x28000); + write_rfreg(pAdapter, 0, RF_SYN_G6, 0xe000A); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x709); + rtw_msleep_os(1); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x7B333); + } + else if(ChannelToSw == 12) // OFDM rate, even number channel + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x28200); + write_rfreg(pAdapter, 0, RF_SYN_G6, 0xe000C); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x50B); + rtw_msleep_os(1); + write_rfreg(pAdapter, 0, RF_SYN_G7, 0x4B333); + } + else + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F200); + } + } + } + else //88cu + { + + //mcard interface + + if( BOARD_MINICARD == pHalData->BoardType) + { + if (ulRateIdx < MPT_RATE_6M) // CCK rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x0F400); + } + else //OFDM~MCS rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F200); + } + + if(ChannelToSw == 6 || ChannelToSw == 8) + { + write_bbreg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0, 0x22); + write_bbreg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0, 0x22); + write_bbreg(pAdapter, rOFDM0_RxDetector1, bMaskByte0, 0x4F); + } + else + { + write_bbreg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0, 0x20); + write_bbreg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0, 0x20); + write_bbreg(pAdapter, rOFDM0_RxDetector1, bMaskByte0, pMptCtx->backup0xc30); + } + } + else + { + if (ulRateIdx < MPT_RATE_6M) // CCK rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x0F400); + } + else if (ChannelToSw & BIT0) // OFDM rate, odd number channel + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F200); + } + else + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F000); + } + } + } + +#else //PCI_INTERFACE + + if (ulRateIdx < MPT_RATE_6M) // CCK rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x0F400); + } + else //OFDM~MCS rate + { + write_rfreg(pAdapter, 0, RF_SYN_G2, 0x4F000); + } + //88CE + if(!IS_92C_SERIAL(pHalData->VersionID)) + { + if(ChannelToSw == 6 || ChannelToSw == 8) + { + write_bbreg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0, 0x22); + write_bbreg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0, 0x22); + write_bbreg(pAdapter, rOFDM0_RxDetector1, bMaskByte0, 0x4F); + } + else + { + write_bbreg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0, pMptCtx->backup0xc50); + write_bbreg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0, pMptCtx->backup0xc58); + write_bbreg(pAdapter, rOFDM0_RxDetector1, bMaskByte0, pMptCtx->backup0xc30); + } + } + +#endif //CONFIG_USB_HCI + + +} +/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ + +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ +void Hal_MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14) +{ + u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0; + u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12; + u8 i; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + + // get current cck swing value and check 0xa22 & 0xa23 later to match the table. + CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord); + + if (!bInCH14) + { + // Readback the current bb cck swing value and compare with the table to + // get the current swing index + for (i = 0; i < CCK_TABLE_SIZE; i++) + { + if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) && + (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) + { + CCKSwingIndex = i; +// RT_TRACE(COMP_INIT, DBG_LOUD,("Ch1~13, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n", +// (rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex)); + break; + } + } + + //Write 0xa22 0xa23 + TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1]<<8) ; + + + //Write 0xa24 ~ 0xa27 + TempVal2 = 0; + TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3]<<8) + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4]<<16 )+ + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5]<<24); + + //Write 0xa28 0xa29 + TempVal3 = 0; + TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7]<<8) ; + } + else + { + for (i = 0; i < CCK_TABLE_SIZE; i++) + { + if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch14[i][0]) && + (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch14[i][1])) + { + CCKSwingIndex = i; +// RT_TRACE(COMP_INIT, DBG_LOUD,("Ch14, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n", +// (rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex)); + break; + } + } + + //Write 0xa22 0xa23 + TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] + + (CCKSwingTable_Ch14[CCKSwingIndex][1]<<8) ; + + //Write 0xa24 ~ 0xa27 + TempVal2 = 0; + TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] + + (CCKSwingTable_Ch14[CCKSwingIndex][3]<<8) + + (CCKSwingTable_Ch14[CCKSwingIndex][4]<<16 )+ + (CCKSwingTable_Ch14[CCKSwingIndex][5]<<24); + + //Write 0xa28 0xa29 + TempVal3 = 0; + TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] + + (CCKSwingTable_Ch14[CCKSwingIndex][7]<<8) ; + } + + write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal); + write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2); + write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3); +} + +void Hal_MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven) +{ + s32 TempCCk; + u8 CCK_index, CCK_index_old; + u8 Action = 0; //0: no action, 1: even->odd, 2:odd->even + u8 TimeOut = 100; + s32 i = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + + + if (!IS_92C_SERIAL(pHalData->VersionID)) + return; +#if 0 + while(PlatformAtomicExchange(&Adapter->IntrCCKRefCount, TRUE) == TRUE) + { + PlatformSleepUs(100); + TimeOut--; + if(TimeOut <= 0) + { + RTPRINT(FINIT, INIT_TxPower, + ("!!!MPT_CCKTxPowerAdjustbyIndex Wait for check CCK gain index too long!!!\n" )); + break; + } + } +#endif + if (beven && !pMptCtx->bMptIndexEven) //odd->even + { + Action = 2; + pMptCtx->bMptIndexEven = _TRUE; + } + else if (!beven && pMptCtx->bMptIndexEven) //even->odd + { + Action = 1; + pMptCtx->bMptIndexEven = _FALSE; + } + + if (Action != 0) + { + //Query CCK default setting From 0xa24 + TempCCk = read_bbreg(pAdapter, rCCK0_TxFilter2, bMaskDWord) & bMaskCCK; + for (i = 0; i < CCK_TABLE_SIZE; i++) + { + if (pHalData->dmpriv.bCCKinCH14) + { + if (_rtw_memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch14[i][2], 4) == _TRUE) + { + CCK_index_old = (u8) i; +// RTPRINT(FINIT, INIT_TxPower,("MPT_CCKTxPowerAdjustbyIndex: Initial reg0x%x = 0x%lx, CCK_index=0x%x, ch 14 %d\n", +// rCCK0_TxFilter2, TempCCk, CCK_index_old, pHalData->bCCKinCH14)); + break; + } + } + else + { + if (_rtw_memcmp((void*)&TempCCk, (void*)&CCKSwingTable_Ch1_Ch13[i][2], 4) == _TRUE) + { + CCK_index_old = (u8) i; +// RTPRINT(FINIT, INIT_TxPower,("MPT_CCKTxPowerAdjustbyIndex: Initial reg0x%x = 0x%lx, CCK_index=0x%x, ch14 %d\n", +// rCCK0_TxFilter2, TempCCk, CCK_index_old, pHalData->bCCKinCH14)); + break; + } + } + } + + if (Action == 1) + CCK_index = CCK_index_old - 1; + else + CCK_index = CCK_index_old + 1; + +// RTPRINT(FINIT, INIT_TxPower,("MPT_CCKTxPowerAdjustbyIndex: new CCK_index=0x%x\n", +// CCK_index)); + + //Adjust CCK according to gain index + if (!pHalData->dmpriv.bCCKinCH14) { + rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]); + rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]); + rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]); + rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]); + rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]); + rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]); + rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]); + rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]); + } else { + rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch14[CCK_index][0]); + rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch14[CCK_index][1]); + rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch14[CCK_index][2]); + rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch14[CCK_index][3]); + rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch14[CCK_index][4]); + rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch14[CCK_index][5]); + rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch14[CCK_index][6]); + rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch14[CCK_index][7]); + } + } +#if 0 + RTPRINT(FINIT, INIT_TxPower, + ("MPT_CCKTxPowerAdjustbyIndex 0xa20=%x\n", PlatformEFIORead4Byte(Adapter, 0xa20))); + + PlatformAtomicExchange(&Adapter->IntrCCKRefCount, FALSE); +#endif +} +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ + +/* + * SetChannel + * Description + * Use H2C command to change channel, + * not only modify rf register, but also other setting need to be done. + */ +void Hal_SetChannel(PADAPTER pAdapter) +{ +#if 0 + struct mp_priv *pmp = &pAdapter->mppriv; + +// SelectChannel(pAdapter, pmp->channel); + set_channel_bwmode(pAdapter, pmp->channel, pmp->channel_offset, pmp->bandwidth); +#else + u8 eRFPath; + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mp_priv *pmp = &pAdapter->mppriv; + u8 channel = pmp->channel; + u8 bandwidth = pmp->bandwidth; + u8 rate = pmp->rateidx; + + + // set RF channel register + for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) + { + if(IS_HARDWARE_TYPE_8192D(pAdapter)) + _write_rfreg(pAdapter, (RF_RADIO_PATH_E)eRFPath, rRfChannel, 0xFF, channel); + else + _write_rfreg(pAdapter, eRFPath, rRfChannel, 0x3FF, channel); + } + Hal_mpt_SwitchRfSetting(pAdapter); + + SelectChannel(pAdapter, channel); + + if (pHalData->CurrentChannel == 14 && !pHalData->dmpriv.bCCKinCH14) { + pHalData->dmpriv.bCCKinCH14 = _TRUE; + Hal_MPT_CCKTxPowerAdjust(pAdapter, pHalData->dmpriv.bCCKinCH14); + } + else if (pHalData->CurrentChannel != 14 && pHalData->dmpriv.bCCKinCH14) { + pHalData->dmpriv.bCCKinCH14 = _FALSE; + Hal_MPT_CCKTxPowerAdjust(pAdapter, pHalData->dmpriv.bCCKinCH14); + } + +#endif +} + +/* + * Notice + * Switch bandwitdth may change center frequency(channel) + */ +void Hal_SetBandwidth(PADAPTER pAdapter) +{ + struct mp_priv *pmp = &pAdapter->mppriv; + + + SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset); + Hal_mpt_SwitchRfSetting(pAdapter); +} + +void Hal_SetCCKTxPower(PADAPTER pAdapter, u8 *TxPower) +{ + u32 tmpval = 0; + + + // rf-A cck tx power + write_bbreg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, TxPower[RF_PATH_A]); + tmpval = (TxPower[RF_PATH_A]<<16) | (TxPower[RF_PATH_A]<<8) | TxPower[RF_PATH_A]; + write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + + // rf-B cck tx power + write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, TxPower[RF_PATH_B]); + tmpval = (TxPower[RF_PATH_B]<<16) | (TxPower[RF_PATH_B]<<8) | TxPower[RF_PATH_B]; + write_bbreg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-SetCCKTxPower: A[0x%02x] B[0x%02x]\n", + TxPower[RF_PATH_A], TxPower[RF_PATH_B])); +} + +void Hal_SetOFDMTxPower(PADAPTER pAdapter, u8 *TxPower) +{ + u32 TxAGC = 0; + u8 tmpval = 0; + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + + // HT Tx-rf(A) + tmpval = TxPower[RF_PATH_A]; + TxAGC = (tmpval<<24) | (tmpval<<16) | (tmpval<<8) | tmpval; + + write_bbreg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); + + // HT Tx-rf(B) + tmpval = TxPower[RF_PATH_B]; + TxAGC = (tmpval<<24) | (tmpval<<16) | (tmpval<<8) | tmpval; + + write_bbreg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC); + write_bbreg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-SetOFDMTxPower: A[0x%02x] B[0x%02x]\n", + TxPower[RF_PATH_A], TxPower[RF_PATH_B])); +} + +void Hal_SetAntennaPathPower(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 TxPowerLevel[MAX_RF_PATH_NUMS]; + u8 rfPath; + + TxPowerLevel[RF_PATH_A] = pAdapter->mppriv.txpoweridx; + TxPowerLevel[RF_PATH_B] = pAdapter->mppriv.txpoweridx_b; + + switch (pAdapter->mppriv.antenna_tx) + { + case ANTENNA_A: + default: + rfPath = RF_PATH_A; + break; + case ANTENNA_B: + rfPath = RF_PATH_B; + break; + case ANTENNA_C: + rfPath = RF_PATH_C; + break; + } + + switch (pHalData->rf_chip) + { + case RF_8225: + case RF_8256: + case RF_6052: + Hal_SetCCKTxPower(pAdapter, TxPowerLevel); + if (pAdapter->mppriv.rateidx < MPT_RATE_6M) // CCK rate + Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath]%2 == 0); + Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); + break; + + default: + break; + } +} + +void Hal_SetTxPower(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 TxPower = pAdapter->mppriv.txpoweridx; + u8 TxPowerLevel[MAX_RF_PATH_NUMS]; + u8 rf, rfPath; + + for (rf = 0; rf < MAX_RF_PATH_NUMS; rf++) { + TxPowerLevel[rf] = TxPower; + } + + switch (pAdapter->mppriv.antenna_tx) + { + case ANTENNA_A: + default: + rfPath = RF_PATH_A; + break; + case ANTENNA_B: + rfPath = RF_PATH_B; + break; + case ANTENNA_C: + rfPath = RF_PATH_C; + break; + } + + switch (pHalData->rf_chip) + { + // 2008/09/12 MH Test only !! We enable the TX power tracking for MP!!!!! + // We should call normal driver API later!! + case RF_8225: + case RF_8256: + case RF_6052: + Hal_SetCCKTxPower(pAdapter, TxPowerLevel); + if (pAdapter->mppriv.rateidx < MPT_RATE_6M) // CCK rate + Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath]%2 == 0); + Hal_SetOFDMTxPower(pAdapter, TxPowerLevel); + break; + + default: + break; + } + +// SetCCKTxPower(pAdapter, TxPower); +// SetOFDMTxPower(pAdapter, TxPower); +} + +void Hal_SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset) +{ + u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D,tmpAGC; + + TxAGCOffset_B = (ulTxAGCOffset&0x000000ff); + TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8); + TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16); + + tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B); + write_bbreg(pAdapter, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC); +} + +void Hal_SetDataRate(PADAPTER pAdapter) +{ + Hal_mpt_SwitchRfSetting(pAdapter); +} + +#if !defined (CONFIG_RTL8192C) && !defined (CONFIG_RTL8192D) +/*------------------------------Define structure----------------------------*/ +typedef struct _R_ANTENNA_SELECT_OFDM { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; +#endif + +void Hal_SetAntenna(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + R_ANTENNA_SELECT_OFDM *p_ofdm_tx; /* OFDM Tx register */ + R_ANTENNA_SELECT_CCK *p_cck_txrx; + + u8 r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0; + u8 chgTx = 0, chgRx = 0; + u32 r_ant_sel_cck_val = 0, r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0; + + + p_ofdm_tx = (R_ANTENNA_SELECT_OFDM *)&r_ant_select_ofdm_val; + p_cck_txrx = (R_ANTENNA_SELECT_CCK *)&r_ant_select_cck_val; + + p_ofdm_tx->r_ant_ht1 = 0x1; + p_ofdm_tx->r_ant_ht2 = 0x2; // Second TX RF path is A + p_ofdm_tx->r_ant_non_ht = 0x3; // 0x1+0x2=0x3 + + switch (pAdapter->mppriv.antenna_tx) + { + case ANTENNA_A: + p_ofdm_tx->r_tx_antenna = 0x1; + r_ofdm_tx_en_val = 0x1; + p_ofdm_tx->r_ant_l = 0x1; + p_ofdm_tx->r_ant_ht_s1 = 0x1; + p_ofdm_tx->r_ant_non_ht_s1 = 0x1; + p_cck_txrx->r_ccktx_enable = 0x8; + chgTx = 1; + + // From SD3 Willis suggestion !!! Set RF A=TX and B as standby +// if (IS_HARDWARE_TYPE_8192S(pAdapter)) + { + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); + r_ofdm_tx_en_val = 0x3; + + // Power save + //cosa r_ant_select_ofdm_val = 0x11111111; + + // We need to close RFB by SW control + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 0); + } + } + break; + + case ANTENNA_B: + p_ofdm_tx->r_tx_antenna = 0x2; + r_ofdm_tx_en_val = 0x2; + p_ofdm_tx->r_ant_l = 0x2; + p_ofdm_tx->r_ant_ht_s1 = 0x2; + p_ofdm_tx->r_ant_non_ht_s1 = 0x2; + p_cck_txrx->r_ccktx_enable = 0x4; + chgTx = 1; + + // From SD3 Willis suggestion !!! Set RF A as standby + //if (IS_HARDWARE_TYPE_8192S(pAdapter)) + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); +// r_ofdm_tx_en_val = 0x3; + + // Power save + //cosa r_ant_select_ofdm_val = 0x22222222; + + // 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table. + // 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control + if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) + { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0); +// PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1); + } + } + break; + + case ANTENNA_AB: // For 8192S + p_ofdm_tx->r_tx_antenna = 0x3; + r_ofdm_tx_en_val = 0x3; + p_ofdm_tx->r_ant_l = 0x3; + p_ofdm_tx->r_ant_ht_s1 = 0x3; + p_ofdm_tx->r_ant_non_ht_s1 = 0x3; + p_cck_txrx->r_ccktx_enable = 0xC; + chgTx = 1; + + // From SD3 Willis suggestion !!! Set RF B as standby + //if (IS_HARDWARE_TYPE_8192S(pAdapter)) + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); + + // Disable Power save + //cosa r_ant_select_ofdm_val = 0x3321333; +#if 0 + // 2008/10/31 MH From SD3 Willi's suggestion. We must read RFA 2T table. + if ((pHalData->VersionID == VERSION_8192S_ACUT)) // For RTL8192SU A-Cut only, by Roger, 2008.11.07. + { + mpt_RFConfigFromPreParaArrary(pAdapter, 1, RF_PATH_A); + } +#endif + // 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0); +// PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1); + } + } + break; + + default: + break; + } + + // + // r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D + // r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D + // r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D + // + switch (pAdapter->mppriv.antenna_rx) + { + case ANTENNA_A: + r_rx_antenna_ofdm = 0x1; // A + p_cck_txrx->r_cckrx_enable = 0x0; // default: A + p_cck_txrx->r_cckrx_enable_2 = 0x0; // option: A + chgRx = 1; + break; + + case ANTENNA_B: + r_rx_antenna_ofdm = 0x2; // B + p_cck_txrx->r_cckrx_enable = 0x1; // default: B + p_cck_txrx->r_cckrx_enable_2 = 0x1; // option: B + chgRx = 1; + break; + + case ANTENNA_AB: + r_rx_antenna_ofdm = 0x3; // AB + p_cck_txrx->r_cckrx_enable = 0x0; // default:A + p_cck_txrx->r_cckrx_enable_2 = 0x1; // option:B + chgRx = 1; + break; + + default: + break; + } + + if (chgTx && chgRx) + { + switch(pHalData->rf_chip) + { + case RF_8225: + case RF_8256: + case RF_6052: + //r_ant_sel_cck_val = r_ant_select_cck_val; + PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); //OFDM Tx + PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); //OFDM Tx + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); //OFDM Rx + PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); //OFDM Rx + PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val);//r_ant_sel_cck_val); //CCK TxRx + + break; + + default: + break; + } + } + + RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n")); +} + +s32 Hal_SetThermalMeter(PADAPTER pAdapter, u8 target_ther) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + + if (!netif_running(pAdapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter! Fail: interface not opened!\n")); + return _FAIL; + } + + if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter: Fail! not in MP mode!\n")); + return _FAIL; + } + + target_ther &= 0xff; + if (target_ther < 0x07) + target_ther = 0x07; + else if (target_ther > 0x1d) + target_ther = 0x1d; + + pHalData->EEPROMThermalMeter = target_ther; + + return _SUCCESS; +} + +void Hal_TriggerRFThermalMeter(PADAPTER pAdapter) +{ + + write_rfreg(pAdapter, RF_PATH_A, RF_T_METER, 0x60); // 0x24: RF Reg[6:5] + +// RT_TRACE(_module_mp_,_drv_alert_, ("TriggerRFThermalMeter() finished.\n" )); +} + +u8 Hal_ReadRFThermalMeter(PADAPTER pAdapter) +{ + u32 ThermalValue = 0; + + ThermalValue = _read_rfreg(pAdapter, RF_PATH_A, RF_T_METER, 0x1F); // 0x24: RF Reg[4:0] +// RT_TRACE(_module_mp_, _drv_alert_, ("ThermalValue = 0x%x\n", ThermalValue)); + return (u8)ThermalValue; +} + +void Hal_GetThermalMeter(PADAPTER pAdapter, u8 *value) +{ +#if 0 + fw_cmd(pAdapter, IOCMD_GET_THERMAL_METER); + rtw_msleep_os(1000); + fw_cmd_data(pAdapter, value, 1); + *value &= 0xFF; +#else + + Hal_TriggerRFThermalMeter(pAdapter); + rtw_msleep_os(1000); + *value = Hal_ReadRFThermalMeter(pAdapter); +#endif +} + +void Hal_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + pAdapter->mppriv.MptCtx.bSingleCarrier = bStart; + if (bStart)// Start Single Carrier. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetSingleCarrierTx: test start\n")); + // 1. if OFDM block on? + if(!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);//set OFDM block on + + { + // 2. set CCK test mode off, set to CCK normal mode + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); + // 3. turn on scramble setting + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); + } + // 4. Turn On Single Carrier Tx and turn off the other test modes. + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); +#ifdef CONFIG_RTL8192C + // 5. Disable TX power saving at STF & LLTF + write_bbreg(pAdapter, rOFDM1_LSTF, BIT22, 1); +#endif + } + else// Stop Single Carrier. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetSingleCarrierTx: test stop\n")); + + // Turn off all test modes. + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); +#ifdef CONFIG_RTL8192C + // Cancel disable TX power saving at STF&LLTF + write_bbreg(pAdapter, rOFDM1_LSTF, BIT22, 0); +#endif + //Delay 10 ms //delay_ms(10); + rtw_msleep_os(10); + + //BB Reset + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } +} + + +void Hal_SetSingleToneTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN is92C = IS_92C_SERIAL(pHalData->VersionID); + + u8 rfPath; + + switch (pAdapter->mppriv.antenna_tx) + { + case ANTENNA_A: + default: + rfPath = RF_PATH_A; + break; + case ANTENNA_B: + rfPath = RF_PATH_B; + break; + case ANTENNA_C: + rfPath = RF_PATH_C; + break; + } + + pAdapter->mppriv.MptCtx.bSingleTone = bStart; + if (bStart)// Start Single Tone. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetSingleToneTx: test start\n")); + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0); + write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0); + + if (is92C) + { + _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT19, 0x01); + rtw_usleep_os(100); + if (rfPath == RF_PATH_A) + write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x10000); // PAD all on. + else if (rfPath == RF_PATH_B) + write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x10000); // PAD all on. + } else { + write_rfreg(pAdapter, rfPath, 0x21, 0xd4000); + rtw_usleep_os(100); + } + + write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); // PAD all on. + rtw_usleep_os(100); + } + else// Stop Single Tone. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetSingleToneTx: test stop\n")); + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1); + write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1); + + if (is92C) { + _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT19, 0x00); + rtw_usleep_os(100); + write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x32d75); // PAD all on. + write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x32d75); // PAD all on. + rtw_usleep_os(100); + } else { + write_rfreg(pAdapter, rfPath, 0x21, 0x54000); + rtw_usleep_os(100); + + write_rfreg(pAdapter, rfPath, 0x00, 0x30000); // PAD all on. + rtw_usleep_os(100); + } + } + +} + + +void Hal_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) +{ + pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart; + if (bStart) // Start Carrier Suppression. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetCarrierSuppressionTx: test start\n")); + //if(pMgntInfo->dot11CurrentWirelessMode == WIRELESS_MODE_B) + if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) + { + // 1. if CCK block on? + if(!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);//set CCK block on + + //Turn Off All Test Mode + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); + + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); //transmit mode + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); //turn off scramble setting + + //Set CCK Tx Test Rate + //PHY_SetBBReg(pAdapter, rCCK0_System, bCCKTxRate, pMgntInfo->ForcedDataRate); + write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); //Set FTxRate to 1Mbps + } + } + else// Stop Carrier Suppression. + { + RT_TRACE(_module_mp_,_drv_alert_, ("SetCarrierSuppressionTx: test stop\n")); + //if(pMgntInfo->dot11CurrentWirelessMode == WIRELESS_MODE_B) + if (pAdapter->mppriv.rateidx <= MPT_RATE_11M ) { + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); //normal mode + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); //turn on scramble setting + + //BB Reset + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } + } + //DbgPrint("\n MPT_ProSetCarrierSupp() is finished. \n"); +} + +void Hal_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + u32 cckrate; + + if (bStart) + { + RT_TRACE(_module_mp_, _drv_alert_, + ("SetCCKContinuousTx: test start\n")); + + // 1. if CCK block on? + if(!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);//set CCK block on + + //Turn Off All Test Mode + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); + //Set CCK Tx Test Rate + #if 0 + switch(pAdapter->mppriv.rateidx) + { + case 2: + cckrate = 0; + break; + case 4: + cckrate = 1; + break; + case 11: + cckrate = 2; + break; + case 22: + cckrate = 3; + break; + default: + cckrate = 0; + break; + } + #else + cckrate = pAdapter->mppriv.rateidx; + #endif + write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); //transmit mode + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); //turn on scramble setting + +#ifdef CONFIG_RTL8192C + // Patch for CCK 11M waveform + if (cckrate == MPT_RATE_1M) + write_bbreg(pAdapter, 0xA71, BIT(6), bDisable); + else + write_bbreg(pAdapter, 0xA71, BIT(6), bEnable); +#endif + + } + else { + RT_TRACE(_module_mp_, _drv_info_, + ("SetCCKContinuousTx: test stop\n")); + + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); //normal mode + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); //turn on scramble setting + + //BB Reset + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } + + pAdapter->mppriv.MptCtx.bCckContTx = bStart; + pAdapter->mppriv.MptCtx.bOfdmContTx = _FALSE; +}/* mpt_StartCckContTx */ + +void Hal_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + if (bStart) { + RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test start\n")); + // 1. if OFDM block on? + if(!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);//set OFDM block on + { + + // 2. set CCK test mode off, set to CCK normal mode + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); + + // 3. turn on scramble setting + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); + } + // 4. Turn On Continue Tx and turn off the other test modes. + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); + } else { + RT_TRACE(_module_mp_,_drv_info_, ("SetOFDMContinuousTx: test stop\n")); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); + write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); + //Delay 10 ms + rtw_msleep_os(10); + //BB Reset + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } + + pAdapter->mppriv.MptCtx.bCckContTx = _FALSE; + pAdapter->mppriv.MptCtx.bOfdmContTx = bStart; +}/* mpt_StartOfdmContTx */ + +void Hal_SetContinuousTx(PADAPTER pAdapter, u8 bStart) +{ +#if 0 + // ADC turn off [bit24-21] adc port0 ~ port1 + if (bStart) { + write_bbreg(pAdapter, rRx_Wait_CCCA, read_bbreg(pAdapter, rRx_Wait_CCCA) & 0xFE1FFFFF); + rtw_usleep_os(100); + } +#endif + RT_TRACE(_module_mp_, _drv_info_, + ("SetContinuousTx: rate:%d\n", pAdapter->mppriv.rateidx)); + + pAdapter->mppriv.MptCtx.bStartContTx = bStart; + if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) + { + Hal_SetCCKContinuousTx(pAdapter, bStart); + } + else if ((pAdapter->mppriv.rateidx >= MPT_RATE_6M) && + (pAdapter->mppriv.rateidx <= MPT_RATE_MCS15)) + { + Hal_SetOFDMContinuousTx(pAdapter, bStart); + } +#if 0 + // ADC turn on [bit24-21] adc port0 ~ port1 + if (!bStart) { + write_bbreg(pAdapter, rRx_Wait_CCCA, read_bbreg(pAdapter, rRx_Wait_CCCA) | 0x01E00000); + } +#endif +} + +#endif // CONFIG_MP_INCLUDE diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c new file mode 100755 index 00000000..1bae6dad --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c @@ -0,0 +1,4841 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/****************************************************************************** + + Module: rtl8192c_phycfg.c + + Note: Merge 92SE/SU PHY config as below + 1. BB register R/W API + 2. RF register R/W API + 3. Initial BB/RF/MAC config by reading BB/MAC/RF txt. + 3. Power setting API + 4. Channel switch API + 5. Initial gain switch API. + 6. Other BB/MAC/RF API. + + Function: PHY: Extern function, phy: local function + + Export: PHY_FunctionName + + Abbrev: NONE + + History: + Data Who Remark + 08/08/2008 MHC 1. Port from 9x series phycfg.c + 2. Reorganize code arch and ad description. + 3. Collect similar function. + 4. Seperate extern/local API. + 08/12/2008 MHC We must merge or move USB PHY relative function later. + 10/07/2008 MHC Add IQ calibration for PHY.(Only 1T2R mode now!!!) + 11/06/2008 MHC Add TX Power index PG file to config in 0xExx register + area to map with EEPROM/EFUSE tx pwr index. + +******************************************************************************/ +#define _HAL_8192C_PHYCFG_C_ + +#include +#include +#include +#include + +#ifdef CONFIG_IOL +#include +#endif + +#include + + +/*---------------------------Define Local Constant---------------------------*/ +/* Channel switch:The size of command tables for switch channel*/ +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ + +/*------------------------Define local variable------------------------------*/ + + +/*--------------------Define export function prototype-----------------------*/ +// Please refer to header file +/*--------------------Define export function prototype-----------------------*/ + +/*----------------------------Function Body----------------------------------*/ +// +// 1. BB register R/W API +// + +/** +* Function: phy_CalculateBitShift +* +* OverView: Get shifted position of the BitMask +* +* Input: +* u4Byte BitMask, +* +* Output: none +* Return: u4Byte Return the shift bit bit position of the mask +*/ +static u32 +phy_CalculateBitShift( + u32 BitMask + ) +{ + u32 i; + + for(i=0; i<=31; i++) + { + if ( ((BitMask>>i) & 0x1 ) == 1) + break; + } + + return (i); +} + + +/** +* Function: PHY_QueryBBReg +* +* OverView: Read "sepcific bits" from BB register +* +* Input: +* PADAPTER Adapter, +* u4Byte RegAddr, //The target address to be readback +* u4Byte BitMask //The target bit position in the target address +* //to be readback +* Output: None +* Return: u4Byte Data //The readback register value +* Note: This function is equal to "GetRegSetting" in PHY programming guide +*/ +u32 +rtl8192c_PHY_QueryBBReg( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ) +{ + u32 ReturnValue = 0, OriginalValue, BitShift; + u16 BBWaitCounter = 0; + +#if (DISABLE_BB_RF == 1) + return 0; +#endif + + //RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_QueryBBReg(): RegAddr(%#lx), BitMask(%#lx)\n", RegAddr, BitMask)); + + OriginalValue = rtw_read32(Adapter, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + ReturnValue = (OriginalValue & BitMask) >> BitShift; + + //RTPRINT(FPHY, PHY_BBR, ("BBR MASK=0x%lx Addr[0x%lx]=0x%lx\n", BitMask, RegAddr, OriginalValue)); + //RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_QueryBBReg(): RegAddr(%#lx), BitMask(%#lx), OriginalValue(%#lx)\n", RegAddr, BitMask, OriginalValue)); + + return (ReturnValue); + +} + + +/** +* Function: PHY_SetBBReg +* +* OverView: Write "Specific bits" to BB register (page 8~) +* +* Input: +* PADAPTER Adapter, +* u4Byte RegAddr, //The target address to be modified +* u4Byte BitMask //The target bit position in the target address +* //to be modified +* u4Byte Data //The new register value in the target bit position +* //of the target address +* +* Output: None +* Return: None +* Note: This function is equal to "PutRegSetting" in PHY programming guide +*/ + +VOID +rtl8192c_PHY_SetBBReg( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //u16 BBWaitCounter = 0; + u32 OriginalValue, BitShift; + +#if (DISABLE_BB_RF == 1) + return; +#endif + + //RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); + + if(BitMask!= bMaskDWord){//if not "double word" write + OriginalValue = rtw_read32(Adapter, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask)); + } + + rtw_write32(Adapter, RegAddr, Data); + + //RTPRINT(FPHY, PHY_BBW, ("BBW MASK=0x%lx Addr[0x%lx]=0x%lx\n", BitMask, RegAddr, Data)); + //RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); + +} + + +// +// 2. RF register R/W API +// + +/*----------------------------------------------------------------------------- + * Function: phy_FwRFSerialRead() + * + * Overview: We support firmware to execute RF-R/W. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/21/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static u32 +phy_FwRFSerialRead( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset ) +{ + u32 retValue = 0; + //RT_ASSERT(FALSE,("deprecate!\n")); + return (retValue); + +} /* phy_FwRFSerialRead */ + + +/*----------------------------------------------------------------------------- + * Function: phy_FwRFSerialWrite() + * + * Overview: We support firmware to execute RF-R/W. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/21/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static VOID +phy_FwRFSerialWrite( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset, + IN u32 Data ) +{ + //RT_ASSERT(FALSE,("deprecate!\n")); +} + + +/** +* Function: phy_RFSerialRead +* +* OverView: Read regster from RF chips +* +* Input: +* PADAPTER Adapter, +* RF_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D +* u4Byte Offset, //The target address to be read +* +* Output: None +* Return: u4Byte reback value +* Note: Threre are three types of serial operations: +* 1. Software serial write +* 2. Hardware LSSI-Low Speed Serial Interface +* 3. Hardware HSSI-High speed +* serial write. Driver need to implement (1) and (2). +* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() +*/ +static u32 +phy_RFSerialRead( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset + ) +{ + u32 retValue = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath]; + u32 NewOffset; + u32 tmplong,tmplong2; + u8 RfPiEnable=0; +#if 0 + if(pHalData->RFChipID == RF_8225 && Offset > 0x24) //36 valid regs + return retValue; + if(pHalData->RFChipID == RF_8256 && Offset > 0x2D) //45 valid regs + return retValue; +#endif + // + // Make sure RF register offset is correct + // + Offset &= 0x3f; + + // + // Switch page for 8256 RF IC + // + NewOffset = Offset; + + // 2009/06/17 MH We can not execute IO for power save or other accident mode. + //if(RT_CANNOT_IO(Adapter)) + //{ + // RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); + // return 0xFFFFFFFF; + //} + + // For 92S LSSI Read RFLSSIRead + // For RF A/B write 0x824/82c(does not work in the future) + // We must use 0x824 for RF A and B to execute read trigger + tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); + if(eRFPath == RF_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord); + + tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge; //T65 RF + + PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong&(~bLSSIReadEdge)); + rtw_udelay_os(10);// PlatformStallExecution(10); + + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); + rtw_udelay_os(100);//PlatformStallExecution(100); + + PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong|bLSSIReadEdge); + rtw_udelay_os(10);//PlatformStallExecution(10); + + if(eRFPath == RF_PATH_A) + RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT8); + else if(eRFPath == RF_PATH_B) + RfPiEnable = (u8)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1, BIT8); + + if(RfPiEnable) + { // Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF + retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData); + //DBG_8192C("Readback from RF-PI : 0x%x\n", retValue); + } + else + { //Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF + retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); + //DBG_8192C("Readback from RF-SI : 0x%x\n", retValue); + } + //DBG_8192C("RFR-%d Addr[0x%x]=0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); + + return retValue; + +} + + + +/** +* Function: phy_RFSerialWrite +* +* OverView: Write data to RF register (page 8~) +* +* Input: +* PADAPTER Adapter, +* RF_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D +* u4Byte Offset, //The target address to be read +* u4Byte Data //The new register Data in the target bit position +* //of the target to be read +* +* Output: None +* Return: None +* Note: Threre are three types of serial operations: +* 1. Software serial write +* 2. Hardware LSSI-Low Speed Serial Interface +* 3. Hardware HSSI-High speed +* serial write. Driver need to implement (1) and (2). +* This function is equal to the combination of RF_ReadReg() and RFLSSIRead() + * + * Note: For RF8256 only + * The total count of RTL8256(Zebra4) register is around 36 bit it only employs + * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10]) + * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration + * programming guide" for more details. + * Thus, we define a sub-finction for RTL8526 register address conversion + * =========================================================== + * Register Mode RegCTL[1] RegCTL[0] Note + * (Reg00[12]) (Reg00[10]) + * =========================================================== + * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) + * ------------------------------------------------------------------ + * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) + * ------------------------------------------------------------------ + * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) + * ------------------------------------------------------------------ + * + * 2008/09/02 MH Add 92S RF definition + * + * + * +*/ +static VOID +phy_RFSerialWrite( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset, + IN u32 Data + ) +{ + u32 DataAndAddr = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath]; + u32 NewOffset; + +#if 0 + // We should check valid regs for RF_6052 case. + if(pHalData->RFChipID == RF_8225 && Offset > 0x24) //36 valid regs + return; + if(pHalData->RFChipID == RF_8256 && Offset > 0x2D) //45 valid regs + return; +#endif + + // 2009/06/17 MH We can not execute IO for power save or other accident mode. + //if(RT_CANNOT_IO(Adapter)) + //{ + // RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); + // return; + //} + + Offset &= 0x3f; + + // + // Shadow Update + // + //PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); + + // + // Switch page for 8256 RF IC + // + NewOffset = Offset; + + // + // Put write addr in [5:0] and write data in [31:16] + // + //DataAndAddr = (Data<<16) | (NewOffset&0x3f); + DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff; // T65 RF + + // + // Write Operation + // + PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); + //RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]=0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); + +} + + +/** +* Function: PHY_QueryRFReg +* +* OverView: Query "Specific bits" to RF register (page 8~) +* +* Input: +* PADAPTER Adapter, +* RF_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D +* u4Byte RegAddr, //The target address to be read +* u4Byte BitMask //The target bit position in the target address +* //to be read +* +* Output: None +* Return: u4Byte Readback value +* Note: This function is equal to "GetRFRegSetting" in PHY programming guide +*/ +u32 +rtl8192c_PHY_QueryRFReg( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask + ) +{ + u32 Original_Value, Readback_Value, BitShift; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //u8 RFWaitCounter = 0; + //_irqL irqL; + +#if (DISABLE_BB_RF == 1) + return 0; +#endif + + //RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_QueryRFReg(): RegAddr(%#lx), eRFPath(%#x), BitMask(%#lx)\n", RegAddr, eRFPath,BitMask)); + +#ifdef CONFIG_USB_HCI + //PlatformAcquireMutex(&pHalData->mxRFOperate); +#else + //_enter_critical(&pHalData->rf_lock, &irqL); +#endif + + + Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); + + BitShift = phy_CalculateBitShift(BitMask); + Readback_Value = (Original_Value & BitMask) >> BitShift; + +#ifdef CONFIG_USB_HCI + //PlatformReleaseMutex(&pHalData->mxRFOperate); +#else + //_exit_critical(&pHalData->rf_lock, &irqL); +#endif + + + //RTPRINT(FPHY, PHY_RFR, ("RFR-%d MASK=0x%lx Addr[0x%lx]=0x%lx\n", eRFPath, BitMask, RegAddr, Original_Value));//BitMask(%#lx),BitMask, + //RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_QueryRFReg(): RegAddr(%#lx), eRFPath(%#x), Original_Value(%#lx)\n", + // RegAddr, eRFPath, Original_Value)); + + return (Readback_Value); +} + +/** +* Function: PHY_SetRFReg +* +* OverView: Write "Specific bits" to RF register (page 8~) +* +* Input: +* PADAPTER Adapter, +* RF_RADIO_PATH_E eRFPath, //Radio path of A/B/C/D +* u4Byte RegAddr, //The target address to be modified +* u4Byte BitMask //The target bit position in the target address +* //to be modified +* u4Byte Data //The new register Data in the target bit position +* //of the target address +* +* Output: None +* Return: None +* Note: This function is equal to "PutRFRegSetting" in PHY programming guide +*/ +VOID +rtl8192c_PHY_SetRFReg( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ) +{ + + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //u1Byte RFWaitCounter = 0; + u32 Original_Value, BitShift; + //_irqL irqL; + +#if (DISABLE_BB_RF == 1) + return; +#endif + + //RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetRFReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx), eRFPath(%#x)\n", + // RegAddr, BitMask, Data, eRFPath)); + //RTPRINT(FINIT, INIT_RF, ("PHY_SetRFReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx), eRFPath(%#x)\n", + // RegAddr, BitMask, Data, eRFPath)); + + +#ifdef CONFIG_USB_HCI + //PlatformAcquireMutex(&pHalData->mxRFOperate); +#else + //_enter_critical(&pHalData->rf_lock, &irqL); +#endif + + + // RF data is 12 bits only + if (BitMask != bRFRegOffsetMask) + { + Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + Data = ((Original_Value & (~BitMask)) | (Data<< BitShift)); + } + + phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); + + + +#ifdef CONFIG_USB_HCI + //PlatformReleaseMutex(&pHalData->mxRFOperate); +#else + //_exit_critical(&pHalData->rf_lock, &irqL); +#endif + + //PHY_QueryRFReg(Adapter,eRFPath,RegAddr,BitMask); + //RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_SetRFReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx), eRFPath(%#x)\n", + // RegAddr, BitMask, Data, eRFPath)); + +} + + +// +// 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. +// + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigMACWithParaFile() + * + * Overview: This function read BB parameters from general file format, and do register + * Read/Write + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + * Note: The format of MACPHY_REG.txt is different from PHY and RF. + * [Register][Mask][Value] + *---------------------------------------------------------------------------*/ +static int +phy_ConfigMACWithParaFile( + IN PADAPTER Adapter, + IN u8* pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + int rtStatus = _SUCCESS; + + return rtStatus; +} + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigMACWithHeaderFile() + * + * Overview: This function read BB parameters from Header file we gen, and do register + * Read/Write + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + * Note: The format of MACPHY_REG.txt is different from PHY and RF. + * [Register][Mask][Value] + *---------------------------------------------------------------------------*/ +static int +phy_ConfigMACWithHeaderFile( + IN PADAPTER Adapter +) +{ + u32 i = 0; + u32 ArrayLength = 0; + u32* ptrArray; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + //2008.11.06 Modified by tynli. + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Read Rtl819XMACPHY_Array\n")); + ArrayLength = MAC_2T_ArrayLength; + ptrArray = Rtl819XMAC_Array; + +#ifdef CONFIG_IOL_MAC + if(rtw_IOL_applied(Adapter)) + { + struct xmit_frame *xmit_frame; + if((xmit_frame=rtw_IOL_accquire_xmit_frame(Adapter)) == NULL) + return _FAIL; + + for(i = 0 ;i < ArrayLength;i=i+2){ // Add by tynli for 2 column + rtw_IOL_append_WB_cmd(xmit_frame, ptrArray[i], (u8)ptrArray[i+1]); + } + + return rtw_IOL_exec_cmds_sync(Adapter, xmit_frame, 1000); + } + else +#endif + { + for(i = 0 ;i < ArrayLength;i=i+2){ // Add by tynli for 2 column + rtw_write8(Adapter, ptrArray[i], (u8)ptrArray[i+1]); + } + } + + return _SUCCESS; + +} + + +/*----------------------------------------------------------------------------- + * Function: PHY_MACConfig8192C + * + * Overview: Condig MAC by header file or parameter file. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 08/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +int +PHY_MACConfig8192C( + IN PADAPTER Adapter + ) +{ + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s8 *pszMACRegFile; + s8 sz88CMACRegFile[] = RTL8188C_PHY_MACREG; + s8 sz92CMACRegFile[] = RTL8192C_PHY_MACREG; + BOOLEAN is92C = IS_92C_SERIAL(pHalData->VersionID); + + if(is92C) + pszMACRegFile = sz92CMACRegFile; + else + pszMACRegFile = sz88CMACRegFile; + + // + // Config MAC + // +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = phy_ConfigMACWithHeaderFile(Adapter); +#else + + // Not make sure EEPROM, add later + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Read MACREG.txt\n")); + rtStatus = phy_ConfigMACWithParaFile(Adapter, pszMACRegFile); +#endif + +#ifdef CONFIG_PCI_HCI + //this switching setting cause some 8192cu hw have redownload fw fail issue + //improve 2-stream TX EVM by Jenyu + if(is92C) + rtw_write8(Adapter, REG_SPS0_CTRL+3,0x71); +#endif + + + // 2010.07.13 AMPDU aggregation number 9 + //rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); + rtw_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A); //By tynli. 2010.11.18. +#ifdef CONFIG_USB_HCI + if(is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) + rtw_write8(Adapter, 0x40,0x04); +#endif + + return rtStatus; + +} + + +/** +* Function: phy_InitBBRFRegisterDefinition +* +* OverView: Initialize Register definition offset for Radio Path A/B/C/D +* +* Input: +* PADAPTER Adapter, +* +* Output: None +* Return: None +* Note: The initialization value is constant and it should never be changes +*/ +static VOID +phy_InitBBRFRegisterDefinition( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + // RF Interface Sowrtware Control + pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 + pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) + pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874 + pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) + + // RF Interface Readback Value + pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0 + pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) + pHalData->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4 + pHalData->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) + + // RF Interface Output (and Enable) + pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860 + pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864 + + // RF Interface (Output and) Enable + pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) + pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) + + //Addr of LSSI. Wirte RF register by driver + pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter + pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; + + // RF parameter + pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select + pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; + pHalData->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; + pHalData->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; + + // Tx AGC Gain Stage (same for all path. Should we remove this?) + pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + pHalData->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + pHalData->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage + + // Tranceiver A~D HSSI Parameter-1 + pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1 + pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1 + + // Tranceiver A~D HSSI Parameter-2 + pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2 + pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2 + + // RF switch Control + pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control + pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; + pHalData->PHYRegDef[RF_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; + pHalData->PHYRegDef[RF_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; + + // AGC control 1 + pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; + pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; + pHalData->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; + pHalData->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; + + // AGC control 2 + pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; + pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; + pHalData->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; + pHalData->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; + + // RX AFE control 1 + pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; + pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; + pHalData->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; + pHalData->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; + + // RX AFE control 1 + pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; + pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; + pHalData->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; + pHalData->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; + + // Tx AFE control 1 + pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; + pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; + pHalData->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; + pHalData->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; + + // Tx AFE control 2 + pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; + pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; + pHalData->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; + pHalData->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; + + // Tranceiver LSSI Readback SI mode + pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; + pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; + pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; + pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; + + // Tranceiver LSSI Readback PI mode + pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; + pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; + //pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBackPi = rFPGA0_XC_LSSIReadBack; + //pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBackPi = rFPGA0_XD_LSSIReadBack; + +} + + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithParaFile() + * + * Overview: This function read BB parameters from general file format, and do register + * Read/Write + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * 2008/11/06 MH For 92S we do not support silent reset now. Disable + * parameter file compare!!!!!!?? + * + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithParaFile( + IN PADAPTER Adapter, + IN u8* pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + int rtStatus = _SUCCESS; + + return rtStatus; +} + + + +//**************************************** +// The following is for High Power PA +//**************************************** +VOID +phy_ConfigBBExternalPA( + IN PADAPTER Adapter +) +{ +#ifdef CONFIG_USB_HCI + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u16 i=0; + u32 temp=0; + + if(!pHalData->ExternalPA) + { + return; + } + + // 2010/10/19 MH According to Jenyu/EEChou 's opinion, we need not to execute the + // same code as SU. It is already updated in PHY_REG_1T_HP.txt. +#if 0 + PHY_SetBBReg(Adapter, 0xee8, BIT28, 1); + temp = PHY_QueryBBReg(Adapter, 0x860, bMaskDWord); + temp |= (BIT26|BIT21|BIT10|BIT5); + PHY_SetBBReg(Adapter, 0x860, bMaskDWord, temp); + PHY_SetBBReg(Adapter, 0x870, BIT10, 0); + PHY_SetBBReg(Adapter, 0xc80, bMaskDWord, 0x20000080); + PHY_SetBBReg(Adapter, 0xc88, bMaskDWord, 0x40000100); +#endif + +#endif +} + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithHeaderFile() + * + * Overview: This function read BB parameters from general file format, and do register + * Read/Write + * + * Input: PADAPTER Adapter + * u1Byte ConfigType 0 => PHY_CONFIG + * 1 =>AGC_TAB + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithHeaderFile( + IN PADAPTER Adapter, + IN u8 ConfigType +) +{ + int i; + u32* Rtl819XPHY_REGArray_Table; + u32* Rtl819XAGCTAB_Array_Table; + u16 PHY_REGArrayLen, AGCTAB_ArrayLen; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int ret = _SUCCESS; + + // + // 2009.11.24. Modified by tynli. + // + if(IS_92C_SERIAL(pHalData->VersionID)) + { + AGCTAB_ArrayLen = AGCTAB_2TArrayLength; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_2TArray; + PHY_REGArrayLen = PHY_REG_2TArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_2TArray; +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType == BOARD_MINICARD ) + { + PHY_REGArrayLen = PHY_REG_2T_mCardArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_2T_mCardArray; + } +#endif + } + else + { + AGCTAB_ArrayLen = AGCTAB_1TArrayLength; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_1TArray; + PHY_REGArrayLen = PHY_REG_1TArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1TArray; +#ifdef CONFIG_USB_HCI + if(pHalData->BoardType == BOARD_MINICARD ) + { + PHY_REGArrayLen = PHY_REG_1T_mCardArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T_mCardArray; + } + else if(pHalData->BoardType == BOARD_USB_High_PA) + { + AGCTAB_ArrayLen = AGCTAB_1T_HPArrayLength; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_1T_HPArray; + PHY_REGArrayLen = PHY_REG_1T_HPArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T_HPArray; + } +#endif + } + + if(ConfigType == BaseBand_Config_PHY_REG) + { + #ifdef CONFIG_IOL_BB_PHY_REG + if(rtw_IOL_applied(Adapter)) + { + struct xmit_frame *xmit_frame; + u32 tmp_value; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(Adapter)) == NULL) { + ret = _FAIL; + goto exit; + } + + for(i=0;iMCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0])); + } + if(RegAddr == rTxAGC_A_Rate54_24) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1])); + } + if(RegAddr == rTxAGC_A_CCK1_Mcs32) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6])); + } + if(RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7])); + } + if(RegAddr == rTxAGC_A_Mcs03_Mcs00) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2])); + } + if(RegAddr == rTxAGC_A_Mcs07_Mcs04) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3])); + } + if(RegAddr == rTxAGC_A_Mcs11_Mcs08) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4])); + } + if(RegAddr == rTxAGC_A_Mcs15_Mcs12) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5])); + } + if(RegAddr == rTxAGC_B_Rate18_06) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8])); + } + if(RegAddr == rTxAGC_B_Rate54_24) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9])); + } + if(RegAddr == rTxAGC_B_CCK1_55_Mcs32) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14])); + } + if(RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15])); + } + if(RegAddr == rTxAGC_B_Mcs03_Mcs00) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10])); + } + if(RegAddr == rTxAGC_B_Mcs07_Mcs04) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11])); + } + if(RegAddr == rTxAGC_B_Mcs11_Mcs08) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12])); + } + if(RegAddr == rTxAGC_B_Mcs15_Mcs12) + { + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; + //RT_TRACE(COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%lx\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13])); + pHalData->pwrGroupCnt++; + } +} +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithPgParaFile + * + * Overview: + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/06/2008 MHC Create Version 0. + * 2009/07/29 tynli (porting from 92SE branch)2009/03/11 Add copy parameter file to buffer for silent reset + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithPgParaFile( + IN PADAPTER Adapter, + IN u8* pFileName) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + int rtStatus = _SUCCESS; + + + return rtStatus; + +} /* phy_ConfigBBWithPgParaFile */ + + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithPgHeaderFile + * + * Overview: Config PHY_REG_PG array + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!! + * 11/10/2008 tynli Modify to mew files. + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithPgHeaderFile( + IN PADAPTER Adapter, + IN u8 ConfigType) +{ + int i; + u32* Rtl819XPHY_REGArray_Table_PG; + u16 PHY_REGArrayPGLen; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + // Default: pHalData->RF_Type = RF_2T2R. + PHY_REGArrayPGLen = PHY_REG_Array_PGLength; + Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG; + +#ifdef CONFIG_USB_HCI +// 2010/10/19 Chiyoko According to Alex/Willson opinion, VAU/dongle can share the same PHY_REG_PG.txt +/* + if(pHalData->BoardType == BOARD_MINICARD ) + { + PHY_REGArrayPGLen = PHY_REG_Array_PG_mCardLength; + Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG_mCard; + } + else */if(pHalData->BoardType ==BOARD_USB_High_PA ) + { + PHY_REGArrayPGLen = PHY_REG_Array_PG_HPLength; + Rtl819XPHY_REGArray_Table_PG = Rtl819XPHY_REG_Array_PG_HP; + } +#endif + + if(ConfigType == BaseBand_Config_PHY_REG) + { + for(i=0;iBufOfLines), + MAX_LINES_HWCONFIG_TXT, + MAX_BYTES_LINE_HWCONFIG_TXT, + &nLinesRead + ); + if(rtStatus == RT_STATUS_SUCCESS) + { + PlatformMoveMemory(pHalData->BufOfLines6, pHalData->BufOfLines, nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT); + pHalData->nLinesRead6 = nLinesRead; + } + else + { + // Temporarily skip PHY_REG_MP.txt if file does not exist. + pHalData->nLinesRead6 = 0; + RT_TRACE(COMP_INIT, DBG_LOUD, ("No matched file \r\n")); + return RT_STATUS_SUCCESS; + } + } + else + { + PlatformMoveMemory(pHalData->BufOfLines, pHalData->BufOfLines6, MAX_LINES_HWCONFIG_TXT*MAX_BYTES_LINE_HWCONFIG_TXT); + nLinesRead = pHalData->nLinesRead6; + rtStatus = RT_STATUS_SUCCESS; + } + + + if(rtStatus == RT_STATUS_SUCCESS) + { + RT_TRACE(COMP_INIT, DBG_LOUD, ("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName)); + + for(ithLine = 0; ithLine < nLinesRead; ithLine++) + { + szLine = pHalData->BufOfLines[ithLine]; + + if(!IsCommentString(szLine)) + { + // Get 1st hex value as register offset. + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + if(u4bRegOffset == 0xff) + { // Ending. + break; + } + else if (u4bRegOffset == 0xfe) + delay_ms(50); + else if (u4bRegOffset == 0xfd) + delay_ms(5); + else if (u4bRegOffset == 0xfc) + delay_ms(1); + else if (u4bRegOffset == 0xfb) + PlatformStallExecution(50); + else if (u4bRegOffset == 0xfa) + PlatformStallExecution(5); + else if (u4bRegOffset == 0xf9) + PlatformStallExecution(1); + + // Get 2nd hex value as register value. + szLine += u4bMove; + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + RT_TRACE(COMP_FPGA, DBG_TRACE, ("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue)); + PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue); + + // Add 1us delay between BB/RF register setting. + PlatformStallExecution(1); + } + } + } + } + } + else + { + RT_TRACE(COMP_INIT, DBG_LOUD, ("phy_ConfigBBWithMpParaFile(): Failed%s\n", pFileName)); + } +#endif + + return rtStatus; +} + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithMpHeaderFile + * + * Overview: Config PHY_REG_MP array + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 02/04/2010 chiyokolin Modify to new files. + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithMpHeaderFile( + IN PADAPTER Adapter, + IN u1Byte ConfigType) +{ + int i; + u32* Rtl8192CPHY_REGArray_Table_MP; + u16 PHY_REGArrayMPLen; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PHY_REGArrayMPLen = PHY_REG_Array_MPLength; + Rtl8192CPHY_REGArray_Table_MP = Rtl819XPHY_REG_Array_MP; + + if(ConfigType == BaseBand_Config_PHY_REG) + { + for(i=0;iphy_BB8192S_Config_ParaFile\n")); + + if(IS_92C_SERIAL(pHalData->VersionID)){ + pszBBRegFile=(u8*)&sz92CBBRegFile ; + pszAGCTableFile =(u8*)&sz92CAGCTableFile; + } + else{ + pszBBRegFile=(u8*)&sz88CBBRegFile ; + pszAGCTableFile =(u8*)&sz88CAGCTableFile; + } + + // + // 1. Read PHY_REG.TXT BB INIT!! + // We will seperate as 88C / 92C according to chip version + // +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = phy_ConfigBBWithHeaderFile(Adapter, BaseBand_Config_PHY_REG); +#else + // No matter what kind of CHIP we always read PHY_REG.txt. We must copy different + // type of parameter files to phy_reg.txt at first. + rtStatus = phy_ConfigBBWithParaFile(Adapter,pszBBRegFile); +#endif + + if(rtStatus != _SUCCESS){ + //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("phy_BB8192S_Config_ParaFile():Write BB Reg Fail!!")); + goto phy_BB8190_Config_ParaFile_Fail; + } + +#if MP_DRIVER == 1 + // + // 1.1 Read PHY_REG_MP.TXT BB INIT!! + // We will seperate as 88C / 92C according to chip version + // +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = phy_ConfigBBWithMpHeaderFile(Adapter, BaseBand_Config_PHY_REG); +#else + // No matter what kind of CHIP we always read PHY_REG.txt. We must copy different + // type of parameter files to phy_reg.txt at first. + rtStatus = phy_ConfigBBWithMpParaFile(Adapter, pszBBRegMpFile); +#endif + + if(rtStatus != _SUCCESS){ +// RT_TRACE(COMP_INIT, DBG_SERIOUS, ("phy_BB8192S_Config_ParaFile():Write BB Reg MP Fail!!")); + goto phy_BB8190_Config_ParaFile_Fail; + } +#endif // #if (MP_DRIVER == 1) + + // + // 20100318 Joseph: Config 2T2R to 1T2R if necessary. + // + if(pHalData->rf_type == RF_1T2R) + { + phy_BB8192C_Config_1T(Adapter); + DBG_8192C("phy_BB8192C_Config_ParaFile():Config to 1T!!\n"); + } + + // + // 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt + // + if (pEEPROM->bautoload_fail_flag == _FALSE) + { + pHalData->pwrGroupCnt = 0; + +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter, BaseBand_Config_PHY_REG); +#else + rtStatus = phy_ConfigBBWithPgParaFile(Adapter, (u8*)&szBBRegPgFile); +#endif + } + + if(rtStatus != _SUCCESS){ + //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("phy_BB8192S_Config_ParaFile():BB_PG Reg Fail!!")); + goto phy_BB8190_Config_ParaFile_Fail; + } + + // + // 3. BB AGC table Initialization + // +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = phy_ConfigBBWithHeaderFile(Adapter, BaseBand_Config_AGC_TAB); +#else + //RT_TRACE(COMP_INIT, DBG_LOUD, ("phy_BB8192S_Config_ParaFile AGC_TAB.txt\n")); + rtStatus = phy_ConfigBBWithParaFile(Adapter, pszAGCTableFile); +#endif + + if(rtStatus != _SUCCESS){ + //RT_TRACE(COMP_FPGA, DBG_SERIOUS, ("phy_BB8192S_Config_ParaFile():AGC Table Fail\n")); + goto phy_BB8190_Config_ParaFile_Fail; + } + + // Check if the CCK HighPower is turned ON. + // This is used to calculate PWDB. + pHalData->bCckHighPower = (BOOLEAN)(PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, 0x200)); + +phy_BB8190_Config_ParaFile_Fail: + + return rtStatus; +} + + +int +PHY_BBConfig8192C( + IN PADAPTER Adapter + ) +{ + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 RegVal; + u8 TmpU1B=0; + u8 value8; + + phy_InitBBRFRegisterDefinition(Adapter); + + if(IS_HARDWARE_TYPE_8723A(Adapter)) + { + // Suggested by Scott. tynli_test. 2010.12.30. + //1. 0x28[1] = 1 + TmpU1B = rtw_read8(Adapter, REG_AFE_PLL_CTRL); + rtw_udelay_os(2); + rtw_write8(Adapter, REG_AFE_PLL_CTRL, (TmpU1B|BIT1)); + rtw_udelay_os(2); + + //2. 0x29[7:0] = 0xFF + rtw_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff); + rtw_udelay_os(2); + + //3. 0x02[1:0] = 2b'11 + TmpU1B = rtw_read8(Adapter, REG_SYS_FUNC_EN); + rtw_write8(Adapter, REG_SYS_FUNC_EN, (TmpU1B|FEN_BB_GLB_RSTn|FEN_BBRSTB)); + + //undo clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)&(~BIT31)); + + //4. 0x25[6] = 0 + TmpU1B = rtw_read8(Adapter, REG_AFE_XTAL_CTRL+1); + rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, (TmpU1B&(~BIT6))); + + //5. 0x24[20] = 0 //Advised by SD3 Alex Wang. 2011.02.09. + TmpU1B = rtw_read8(Adapter, REG_AFE_XTAL_CTRL+2); + rtw_write8(Adapter, REG_AFE_XTAL_CTRL+2, (TmpU1B&(~BIT4))); + + //6. 0x1f[7:0] = 0x07 + rtw_write8(Adapter, REG_RF_CTRL, 0x07); + } + else + { + // Enable BB and RF + RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN); + rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1)); + + // 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. + rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x83); + rtw_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xdb); + + rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB); + +#ifdef CONFIG_USB_HCI + rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB); +#else + rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB); +#endif + + //undo clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)&(~BIT31)); + + // 2009/10/21 by SD1 Jong. Modified by tynli. Not in Documented in V8.1. +#ifdef CONFIG_USB_HCI + //To Fix MAC loopback mode fail. Suggested by SD4 Johnny. 2010.03.23. + rtw_write8(Adapter, REG_LDOHCI12_CTRL, 0x0f); + rtw_write8(Adapter, 0x15, 0xe9); +#endif + + rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, 0x80); + +#ifdef CONFIG_PCI_HCI + // Force use left antenna by default for 88C. + // if(!IS_92C_SERIAL(pHalData->VersionID) || IS_92C_1T2R(pHalData->VersionID)) + if(Adapter->ledpriv.LedStrategy != SW_LED_MODE10) + { + RegVal = rtw_read32(Adapter, REG_LEDCFG0); + rtw_write32(Adapter, REG_LEDCFG0, RegVal|BIT23); + } +#endif + } + + // + // Config BB and AGC + // + rtStatus = phy_BB8192C_Config_ParaFile(Adapter); +#if 0 + switch(Adapter->MgntInfo.bRegHwParaFile) + { + case 0: + phy_BB8190_Config_HardCode(Adapter); + break; + + case 1: + rtStatus = phy_BB8192C_Config_ParaFile(Adapter); + break; + + case 2: + // Partial Modify. + phy_BB8190_Config_HardCode(Adapter); + phy_BB8192C_Config_ParaFile(Adapter); + break; + + default: + phy_BB8190_Config_HardCode(Adapter); + break; + } +#endif +#ifdef CONFIG_USB_HCI + if(IS_HARDWARE_TYPE_8192CU(Adapter)&&IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID) + &&(pHalData->BoardType == BOARD_USB_High_PA)) + rtw_write8(Adapter, 0xc72, 0x50); +#endif + + return rtStatus; +} + + +int +PHY_RFConfig8192C( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rtStatus = _SUCCESS; + + // + // RF config + // + rtStatus = PHY_RF6052_Config8192C(Adapter); +#if 0 + switch(pHalData->rf_chip) + { + case RF_6052: + rtStatus = PHY_RF6052_Config(Adapter); + break; + case RF_8225: + rtStatus = PHY_RF8225_Config(Adapter); + break; + case RF_8256: + rtStatus = PHY_RF8256_Config(Adapter); + break; + case RF_8258: + break; + case RF_PSEUDO_11N: + rtStatus = PHY_RF8225_Config(Adapter); + break; + default: //for MacOs Warning: "RF_TYPE_MIN" not handled in switch + break; + } +#endif + return rtStatus; +} + + +/*----------------------------------------------------------------------------- + * Function: PHY_ConfigRFWithParaFile() + * + * Overview: This function read RF parameters from general file format, and do RF 3-wire + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * RF_RADIO_PATH_E eRFPath + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + * Note: Delay may be required for RF configuration + *---------------------------------------------------------------------------*/ +int +rtl8192c_PHY_ConfigRFWithParaFile( + IN PADAPTER Adapter, + IN u8* pFileName, + RF_RADIO_PATH_E eRFPath +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + int rtStatus = _SUCCESS; + + + return rtStatus; + +} + +//**************************************** +// The following is for High Power PA +//**************************************** +#define HighPowerRadioAArrayLen 22 +//This is for High power PA +u32 Rtl8192S_HighPower_RadioA_Array[HighPowerRadioAArrayLen] = { +0x013,0x00029ea4, +0x013,0x00025e74, +0x013,0x00020ea4, +0x013,0x0001ced0, +0x013,0x00019f40, +0x013,0x00014e70, +0x013,0x000106a0, +0x013,0x0000c670, +0x013,0x000082a0, +0x013,0x00004270, +0x013,0x00000240, +}; + +int +PHY_ConfigRFExternalPA( + IN PADAPTER Adapter, + RF_RADIO_PATH_E eRFPath +) +{ + int rtStatus = _SUCCESS; +#ifdef CONFIG_USB_HCI + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u16 i=0; + + if(!pHalData->ExternalPA) + { + return rtStatus; + } + + // 2010/10/19 MH According to Jenyu/EEChou 's opinion, we need not to execute the + // same code as SU. It is already updated in radio_a_1T_HP.txt. +#if 0 + //add for SU High Power PA + for(i = 0;iVersionID)) + { + RadioA_ArrayLen = RadioA_2TArrayLength; + Rtl819XRadioA_Array_Table = Rtl819XRadioA_2TArray; + RadioB_ArrayLen = RadioB_2TArrayLength; + Rtl819XRadioB_Array_Table = Rtl819XRadioB_2TArray; + } + else + { + RadioA_ArrayLen = RadioA_1TArrayLength; + Rtl819XRadioA_Array_Table = Rtl819XRadioA_1TArray; + RadioB_ArrayLen = RadioB_1TArrayLength; + Rtl819XRadioB_Array_Table = Rtl819XRadioB_1TArray; +#ifdef CONFIG_USB_HCI + if( BOARD_MINICARD == pHalData->BoardType ) + { + RadioA_ArrayLen = RadioA_1T_mCardArrayLength; + Rtl819XRadioA_Array_Table = Rtl819XRadioA_1T_mCardArray; + RadioB_ArrayLen = RadioB_1T_mCardArrayLength; + Rtl819XRadioB_Array_Table = Rtl819XRadioB_1T_mCardArray; + } + else if( BOARD_USB_High_PA == pHalData->BoardType ) + { + RadioA_ArrayLen = RadioA_1T_HPArrayLength; + Rtl819XRadioA_Array_Table = Rtl819XRadioA_1T_HPArray; + } +#endif + } + + switch(eRFPath){ + case RF_PATH_A: + #ifdef CONFIG_IOL_RF_RF90_PATH_A + if(rtw_IOL_applied(Adapter)) + { + struct xmit_frame *xmit_frame; + if((xmit_frame=rtw_IOL_accquire_xmit_frame(Adapter)) == NULL) { + rtStatus = _FAIL; + goto exit; + } + + for(i = 0;iPHYRegDef[eRFPath]; + u32 NewOffset = 0; + u32 DataAndAddr = 0; + + NewOffset = Rtl819XRadioA_Array_Table[i] & 0x3f; + DataAndAddr = ((NewOffset<<20) | (Rtl819XRadioA_Array_Table[i+1]&0x000fffff)) & 0x0fffffff; // T65 RF + rtw_IOL_append_WD_cmd(xmit_frame, pPhyReg->rf3wireOffset, DataAndAddr); + } + } + rtStatus = rtw_IOL_exec_cmds_sync(Adapter, xmit_frame, 1000); + } + else + #endif + { + for(i = 0;iPHYRegDef[eRFPath]; + u32 NewOffset = 0; + u32 DataAndAddr = 0; + + NewOffset = Rtl819XRadioB_Array_Table[i] & 0x3f; + DataAndAddr = ((NewOffset<<20) | (Rtl819XRadioB_Array_Table[i+1]&0x000fffff)) & 0x0fffffff; // T65 RF + rtw_IOL_append_WD_cmd(xmit_frame, pPhyReg->rf3wireOffset, DataAndAddr); + } + } + rtStatus = rtw_IOL_exec_cmds_sync(Adapter, xmit_frame, 1000); + } + else + #endif + { + for(i = 0;i actually we call PlatformStallExecution()) to do NdisStallExecution() + // [busy wait] instead of NdisMSleep(). So we acquire RT_INITIAL_SPINLOCK + // to run at Dispatch level to achive it. + //cosa PlatformAcquireSpinLock(Adapter, RT_INITIAL_SPINLOCK); + WriteData[i] &= 0xfff; + PHY_SetRFReg(Adapter, eRFPath, WriteAddr[HW90_BLOCK_RF], bRFRegOffsetMask, WriteData[i]); + // TODO: we should not delay for such a long time. Ask SD3 + rtw_mdelay_os(10); + ulRegRead = PHY_QueryRFReg(Adapter, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord); + rtw_mdelay_os(10); + //cosa PlatformReleaseSpinLock(Adapter, RT_INITIAL_SPINLOCK); + break; + + default: + rtStatus = _FAIL; + break; + } + + + // + // Check whether readback data is correct + // + if(ulRegRead != WriteData[i]) + { + //RT_TRACE(COMP_FPGA, DBG_LOUD, ("ulRegRead: %lx, WriteData: %lx \n", ulRegRead, WriteData[i])); + rtStatus = _FAIL; + break; + } + } + + return rtStatus; +} + + +VOID +rtl8192c_PHY_GetHWRegOriginalValue( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + // read rx initial gain + pHalData->DefaultInitialGain[0] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XAAGCCore1, bMaskByte0); + pHalData->DefaultInitialGain[1] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XBAGCCore1, bMaskByte0); + pHalData->DefaultInitialGain[2] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XCAGCCore1, bMaskByte0); + pHalData->DefaultInitialGain[3] = (u8)PHY_QueryBBReg(Adapter, rOFDM0_XDAGCCore1, bMaskByte0); + //RT_TRACE(COMP_INIT, DBG_LOUD, + //("Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n", + //pHalData->DefaultInitialGain[0], pHalData->DefaultInitialGain[1], + //pHalData->DefaultInitialGain[2], pHalData->DefaultInitialGain[3])); + + // read framesync + pHalData->framesync = (u8)PHY_QueryBBReg(Adapter, rOFDM0_RxDetector3, bMaskByte0); + pHalData->framesyncC34 = PHY_QueryBBReg(Adapter, rOFDM0_RxDetector2, bMaskDWord); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Default framesync (0x%x) = 0x%x \n", + // rOFDM0_RxDetector3, pHalData->framesync)); +} + + +// +// Description: +// Map dBm into Tx power index according to +// current HW model, for example, RF and PA, and +// current wireless mode. +// By Bruce, 2008-01-29. +// +static u8 +phy_DbmToTxPwrIdx( + IN PADAPTER Adapter, + IN WIRELESS_MODE WirelessMode, + IN int PowerInDbm + ) +{ + u8 TxPwrIdx = 0; + int Offset = 0; + + + // + // Tested by MP, we found that CCK Index 0 equals to 8dbm, OFDM legacy equals to + // 3dbm, and OFDM HT equals to 0dbm repectively. + // Note: + // The mapping may be different by different NICs. Do not use this formula for what needs accurate result. + // By Bruce, 2008-01-29. + // + switch(WirelessMode) + { + case WIRELESS_MODE_B: + Offset = -7; + break; + + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + Offset = -8; + break; + default: + Offset = -8; + break; + } + + if((PowerInDbm - Offset) > 0) + { + TxPwrIdx = (u8)((PowerInDbm - Offset) * 2); + } + else + { + TxPwrIdx = 0; + } + + // Tx Power Index is too large. + if(TxPwrIdx > MAX_TXPWR_IDX_NMODE_92S) + TxPwrIdx = MAX_TXPWR_IDX_NMODE_92S; + + return TxPwrIdx; +} + +// +// Description: +// Map Tx power index into dBm according to +// current HW model, for example, RF and PA, and +// current wireless mode. +// By Bruce, 2008-01-29. +// +int +phy_TxPwrIdxToDbm( + IN PADAPTER Adapter, + IN WIRELESS_MODE WirelessMode, + IN u8 TxPwrIdx + ) +{ + int Offset = 0; + int PwrOutDbm = 0; + + // + // Tested by MP, we found that CCK Index 0 equals to -7dbm, OFDM legacy equals to -8dbm. + // Note: + // The mapping may be different by different NICs. Do not use this formula for what needs accurate result. + // By Bruce, 2008-01-29. + // + switch(WirelessMode) + { + case WIRELESS_MODE_B: + Offset = -7; + break; + + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + Offset = -8; + default: + Offset = -8; + break; + } + + PwrOutDbm = TxPwrIdx / 2 + Offset; // Discard the decimal part. + + return PwrOutDbm; +} + + +/*----------------------------------------------------------------------------- + * Function: GetTxPowerLevel8190() + * + * Overview: This function is export to "common" moudule + * + * Input: PADAPTER Adapter + * psByte Power Level + * + * Output: NONE + * + * Return: NONE + * + *---------------------------------------------------------------------------*/ +VOID +PHY_GetTxPowerLevel8192C( + IN PADAPTER Adapter, + OUT u32* powerlevel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 TxPwrLevel = 0; + int TxPwrDbm; + + // + // Because the Tx power indexes are different, we report the maximum of them to + // meet the CCX TPC request. By Bruce, 2008-01-31. + // + + // CCK + TxPwrLevel = pHalData->CurrentCckTxPwrIdx; + TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_B, TxPwrLevel); + + // Legacy OFDM + TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx + pHalData->LegacyHTTxPowerDiff; + + // Compare with Legacy OFDM Tx power. + if(phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel) > TxPwrDbm) + TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_G, TxPwrLevel); + + // HT OFDM + TxPwrLevel = pHalData->CurrentOfdm24GTxPwrIdx; + + // Compare with HT OFDM Tx power. + if(phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel) > TxPwrDbm) + TxPwrDbm = phy_TxPwrIdxToDbm(Adapter, WIRELESS_MODE_N_24G, TxPwrLevel); + + *powerlevel = TxPwrDbm; +} + + +static void getTxPowerIndex( + IN PADAPTER Adapter, + IN u8 channel, + IN OUT u8* cckPowerLevel, + IN OUT u8* ofdmPowerLevel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 index = (channel -1); + // 1. CCK + cckPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][index]; //RF-A + cckPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][index]; //RF-B + + // 2. OFDM for 1S or 2S + if (GET_RF_TYPE(Adapter) == RF_1T2R || GET_RF_TYPE(Adapter) == RF_1T1R) + { + // Read HT 40 OFDM TX power + ofdmPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelHT40_1S[RF_PATH_A][index]; + ofdmPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelHT40_1S[RF_PATH_B][index]; + } + else if (GET_RF_TYPE(Adapter) == RF_2T2R) + { + // Read HT 40 OFDM TX power + ofdmPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelHT40_2S[RF_PATH_A][index]; + ofdmPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelHT40_2S[RF_PATH_B][index]; + } + //RTPRINT(FPHY, PHY_TXPWR, ("Channel-%d, set tx power index !!\n", channel)); +} + +static void ccxPowerIndexCheck( + IN PADAPTER Adapter, + IN u8 channel, + IN OUT u8* cckPowerLevel, + IN OUT u8* ofdmPowerLevel + ) +{ +#if 0 + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PRT_CCX_INFO pCcxInfo = GET_CCX_INFO(pMgntInfo); + + // + // CCX 2 S31, AP control of client transmit power: + // 1. We shall not exceed Cell Power Limit as possible as we can. + // 2. Tolerance is +/- 5dB. + // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit. + // + // TODO: + // 1. 802.11h power contraint + // + // 071011, by rcnjko. + // + if( pMgntInfo->OpMode == RT_OP_MODE_INFRASTRUCTURE && + pMgntInfo->mAssoc && + pCcxInfo->bUpdateCcxPwr && + pCcxInfo->bWithCcxCellPwr && + channel == pMgntInfo->dot11CurrentChannelNumber) + { + u1Byte CckCellPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, pCcxInfo->CcxCellPwr); + u1Byte LegacyOfdmCellPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_G, pCcxInfo->CcxCellPwr); + u1Byte OfdmCellPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, pCcxInfo->CcxCellPwr); + + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", + pCcxInfo->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx)); + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", + channel, cckPowerLevel[0], ofdmPowerLevel[0] + pHalData->LegacyHTTxPowerDiff, ofdmPowerLevel[0])); + + // CCK + if(cckPowerLevel[0] > CckCellPwrIdx) + cckPowerLevel[0] = CckCellPwrIdx; + // Legacy OFDM, HT OFDM + if(ofdmPowerLevel[0] + pHalData->LegacyHTTxPowerDiff > LegacyOfdmCellPwrIdx) + { + if((OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff) > 0) + { + ofdmPowerLevel[0] = OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff; + } + else + { + ofdmPowerLevel[0] = 0; + } + } + + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n", + cckPowerLevel[0], ofdmPowerLevel[0] + pHalData->LegacyHTTxPowerDiff, ofdmPowerLevel[0])); + } + + pHalData->CurrentCckTxPwrIdx = cckPowerLevel[0]; + pHalData->CurrentOfdm24GTxPwrIdx = ofdmPowerLevel[0]; + + RT_TRACE(COMP_TXAGC, DBG_LOUD, + ("PHY_SetTxPowerLevel8192S(): CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n", + cckPowerLevel[0], ofdmPowerLevel[0] + pHalData->LegacyHTTxPowerDiff, ofdmPowerLevel[0])); +#endif +} +/*----------------------------------------------------------------------------- + * Function: SetTxPowerLevel8190() + * + * Overview: This function is export to "HalCommon" moudule + * We must consider RF path later!!!!!!! + * + * Input: PADAPTER Adapter + * u1Byte channel + * + * Output: NONE + * + * Return: NONE + * 2008/11/04 MHC We remove EEPROM_93C56. + * We need to move CCX relative code to independet file. + * 2009/01/21 MHC Support new EEPROM format from SD3 requirement. + * + *---------------------------------------------------------------------------*/ +VOID +PHY_SetTxPowerLevel8192C( + IN PADAPTER Adapter, + IN u8 channel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 cckPowerLevel[2], ofdmPowerLevel[2]; // [0]:RF-A, [1]:RF-B + +#if(MP_DRIVER == 1) + return; +#endif + + if(pHalData->bTXPowerDataReadFromEEPORM == _FALSE) + return; + + getTxPowerIndex(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0]); + //RTPRINT(FPHY, PHY_TXPWR, ("Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + // channel, cckPowerLevel[0], cckPowerLevel[1], ofdmPowerLevel[0], ofdmPowerLevel[1])); + + ccxPowerIndexCheck(Adapter, channel, &cckPowerLevel[0], &ofdmPowerLevel[0]); + + rtl8192c_PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]); + rtl8192c_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel); + +#if 0 + switch(pHalData->rf_chip) + { + case RF_8225: + PHY_SetRF8225CckTxPower(Adapter, cckPowerLevel[0]); + PHY_SetRF8225OfdmTxPower(Adapter, ofdmPowerLevel[0]); + break; + + case RF_8256: + PHY_SetRF8256CCKTxPower(Adapter, cckPowerLevel[0]); + PHY_SetRF8256OFDMTxPower(Adapter, ofdmPowerLevel[0]); + break; + + case RF_6052: + PHY_RF6052SetCckTxPower(Adapter, &cckPowerLevel[0]); + PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel); + break; + + case RF_8258: + break; + } +#endif + +} + + +// +// Description: +// Update transmit power level of all channel supported. +// +// TODO: +// A mode. +// By Bruce, 2008-02-04. +// +BOOLEAN +PHY_UpdateTxPowerDbm8192C( + IN PADAPTER Adapter, + IN int powerInDbm + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 idx; + u8 rf_path; + + // TODO: A mode Tx power. + u8 CckTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, powerInDbm); + u8 OfdmTxPwrIdx = phy_DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, powerInDbm); + + if(OfdmTxPwrIdx - pHalData->LegacyHTTxPowerDiff > 0) + OfdmTxPwrIdx -= pHalData->LegacyHTTxPowerDiff; + else + OfdmTxPwrIdx = 0; + + //RT_TRACE(COMP_TXAGC, DBG_LOUD, ("PHY_UpdateTxPowerDbm8192S(): %ld dBm , CckTxPwrIdx = %d, OfdmTxPwrIdx = %d\n", powerInDbm, CckTxPwrIdx, OfdmTxPwrIdx)); + + for(idx = 0; idx < 14; idx++) + { + for (rf_path = 0; rf_path < 2; rf_path++) + { + pHalData->TxPwrLevelCck[rf_path][idx] = CckTxPwrIdx; + pHalData->TxPwrLevelHT40_1S[rf_path][idx] = + pHalData->TxPwrLevelHT40_2S[rf_path][idx] = OfdmTxPwrIdx; + } + } + + //Adapter->HalFunc.SetTxPowerLevelHandler(Adapter, pHalData->CurrentChannel);//gtest:todo + + return _TRUE; +} + + +/* + Description: + When beacon interval is changed, the values of the + hw registers should be modified. + By tynli, 2008.10.24. + +*/ + + +void +rtl8192c_PHY_SetBeaconHwReg( + IN PADAPTER Adapter, + IN u16 BeaconInterval + ) +{ + +} + + +VOID +PHY_ScanOperationBackup8192C( + IN PADAPTER Adapter, + IN u8 Operation + ) +{ +#if 0 + IO_TYPE IoType; + + if(!Adapter->bDriverStopped) + { + switch(Operation) + { + case SCAN_OPT_BACKUP: + IoType = IO_CMD_PAUSE_DM_BY_SCAN; + rtw_hal_set_hwreg(Adapter,HW_VAR_IO_CMD, (pu1Byte)&IoType); + + break; + + case SCAN_OPT_RESTORE: + IoType = IO_CMD_RESUME_DM_BY_SCAN; + rtw_hal_set_hwreg(Adapter,HW_VAR_IO_CMD, (pu1Byte)&IoType); + break; + + default: + RT_TRACE(COMP_SCAN, DBG_LOUD, ("Unknown Scan Backup Operation. \n")); + break; + } + } +#endif +} + +/*----------------------------------------------------------------------------- + * Function: PHY_SetBWModeCallback8192C() + * + * Overview: Timer callback function for SetSetBWMode + * + * Input: PRT_TIMER pTimer + * + * Output: NONE + * + * Return: NONE + * + * Note: (1) We do not take j mode into consideration now + * (2) Will two workitem of "switch channel" and "switch channel bandwidth" run + * concurrently? + *---------------------------------------------------------------------------*/ +static VOID +_PHY_SetBWMode92C( + IN PADAPTER Adapter +) +{ +// PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 regBwOpMode; + u8 regRRSR_RSC; + + //return; + + // Added it for 20/40 mhz switch time evaluation by guangan 070531 + //u4Byte NowL, NowH; + //u8Byte BeginTime, EndTime; + + /*RT_TRACE(COMP_SCAN, DBG_LOUD, ("==>PHY_SetBWModeCallback8192C() Switch to %s bandwidth\n", \ + pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"))*/ + + if(pHalData->rf_chip == RF_PSEUDO_11N) + { + //pHalData->SetBWModeInProgress= _FALSE; + return; + } + + // There is no 40MHz mode in RF_8225. + if(pHalData->rf_chip==RF_8225) + return; + + if(Adapter->bDriverStopped) + return; + + // Added it for 20/40 mhz switch time evaluation by guangan 070531 + //NowL = PlatformEFIORead4Byte(Adapter, TSFR); + //NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); + //BeginTime = ((u8Byte)NowH << 32) + NowL; + + //3// + //3//<1>Set MAC register + //3// + //Adapter->HalFunc.SetBWModeHandler(); + + regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE); + regRRSR_RSC = rtw_read8(Adapter, REG_RRSR+2); + //regBwOpMode = rtw_hal_get_hwreg(Adapter,HW_VAR_BWMODE,(pu1Byte)®BwOpMode); + + switch(pHalData->CurrentChannelBW) + { + case HT_CHANNEL_WIDTH_20: + regBwOpMode |= BW_OPMODE_20MHZ; + // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); + break; + + case HT_CHANNEL_WIDTH_40: + regBwOpMode &= ~BW_OPMODE_20MHZ; + // 2007/02/07 Mark by Emily becasue we have not verify whether this register works + rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); + + regRRSR_RSC = (regRRSR_RSC&0x90) |(pHalData->nCur40MhzPrimeSC<<5); + rtw_write8(Adapter, REG_RRSR+2, regRRSR_RSC); + break; + + default: + /*RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetBWModeCallback8192C(): + unknown Bandwidth: %#X\n",pHalData->CurrentChannelBW));*/ + break; + } + + //3// + //3//<2>Set PHY related register + //3// + switch(pHalData->CurrentChannelBW) + { + /* 20 MHz channel*/ + case HT_CHANNEL_WIDTH_20: + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0); + PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0); + PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 1); + + break; + + + /* 40 MHz channel*/ + case HT_CHANNEL_WIDTH_40: + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1); + PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1); + + // Set Control channel to upper or lower. These settings are required only for 40MHz + PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, (pHalData->nCur40MhzPrimeSC>>1)); + PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, pHalData->nCur40MhzPrimeSC); + PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 0); + + PHY_SetBBReg(Adapter, 0x818, (BIT26|BIT27), (pHalData->nCur40MhzPrimeSC==HAL_PRIME_CHNL_OFFSET_LOWER)?2:1); + + break; + + + + default: + /*RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetBWModeCallback8192C(): unknown Bandwidth: %#X\n"\ + ,pHalData->CurrentChannelBW));*/ + break; + + } + //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 + + // Added it for 20/40 mhz switch time evaluation by guangan 070531 + //NowL = PlatformEFIORead4Byte(Adapter, TSFR); + //NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); + //EndTime = ((u8Byte)NowH << 32) + NowL; + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWModeCallback8190Pci: time of SetBWMode = %I64d us!\n", (EndTime - BeginTime))); + + //3<3>Set RF related register + switch(pHalData->rf_chip) + { + case RF_8225: + //PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW); + break; + + case RF_8256: + // Please implement this function in Hal8190PciPhy8256.c + //PHY_SetRF8256Bandwidth(Adapter, pHalData->CurrentChannelBW); + break; + + case RF_8258: + // Please implement this function in Hal8190PciPhy8258.c + // PHY_SetRF8258Bandwidth(); + break; + + case RF_PSEUDO_11N: + // Do Nothing + break; + + case RF_6052: + rtl8192c_PHY_RF6052SetBandwidth(Adapter, pHalData->CurrentChannelBW); + break; + + default: + //RT_ASSERT(FALSE, ("Unknown RFChipID: %d\n", pHalData->RFChipID)); + break; + } + + //pHalData->SetBWModeInProgress= FALSE; + + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("<==PHY_SetBWModeCallback8192C() \n" )); +} + + + /*----------------------------------------------------------------------------- + * Function: SetBWMode8190Pci() + * + * Overview: This function is export to "HalCommon" moudule + * + * Input: PADAPTER Adapter + * HT_CHANNEL_WIDTH Bandwidth //20M or 40M + * + * Output: NONE + * + * Return: NONE + * + * Note: We do not take j mode into consideration now + *---------------------------------------------------------------------------*/ +VOID +PHY_SetBWMode8192C( + IN PADAPTER Adapter, + IN HT_CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN unsigned char Offset // Upper, Lower, or Don't care +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + HT_CHANNEL_WIDTH tmpBW= pHalData->CurrentChannelBW; + // Modified it for 20/40 mhz switch by guangan 070531 + //PMGNT_INFO pMgntInfo=&Adapter->MgntInfo; + + //return; + + //if(pHalData->SwChnlInProgress) +// if(pMgntInfo->bScanInProgress) +// { +// RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SetBWMode8192C() %s Exit because bScanInProgress!\n", +// Bandwidth == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")); +// return; +// } + +// if(pHalData->SetBWModeInProgress) +// { +// // Modified it for 20/40 mhz switch by guangan 070531 +// RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SetBWMode8192C() %s cancel last timer because SetBWModeInProgress!\n", +// Bandwidth == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")); +// PlatformCancelTimer(Adapter, &pHalData->SetBWModeTimer); +// //return; +// } + + //if(pHalData->SetBWModeInProgress) + // return; + + //pHalData->SetBWModeInProgress= TRUE; + + pHalData->CurrentChannelBW = Bandwidth; + +#if 0 + if(Offset==HT_EXTCHNL_OFFSET_LOWER) + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; + else if(Offset==HT_EXTCHNL_OFFSET_UPPER) + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; + else + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; +#else + pHalData->nCur40MhzPrimeSC = Offset; +#endif + + if((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) + { +#ifdef USE_WORKITEM + //PlatformScheduleWorkItem(&(pHalData->SetBWModeWorkItem)); +#else + #if 0 + //PlatformSetTimer(Adapter, &(pHalData->SetBWModeTimer), 0); + #else + _PHY_SetBWMode92C(Adapter); + #endif +#endif + } + else + { + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SetBWMode8192C() SetBWModeInProgress FALSE driver sleep or unload\n")); + //pHalData->SetBWModeInProgress= FALSE; + pHalData->CurrentChannelBW = tmpBW; + } + +} + + +static void _PHY_SwChnl8192C(PADAPTER Adapter, u8 channel) +{ + u8 eRFPath; + u32 param1, param2; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if ( Adapter->bNotifyChannelChange ) + { + DBG_871X( "[%s] ch = %d\n", __FUNCTION__, channel ); + } + + //s1. pre common command - CmdID_SetTxPowerLevel + PHY_SetTxPowerLevel8192C(Adapter, channel); + + //s2. RF dependent command - CmdID_RF_WriteReg, param1=RF_CHNLBW, param2=channel + param1 = RF_CHNLBW; + param2 = channel; + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + { + pHalData->RfRegChnlVal[eRFPath] = ((pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, param1, bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); + } + + + //s3. post common command - CmdID_End, None + +} + +VOID +PHY_SwChnl8192C( // Call after initialization + IN PADAPTER Adapter, + IN u8 channel + ) +{ + //PADAPTER Adapter = ADJUST_TO_ADAPTIVE_ADAPTER(pAdapter, _TRUE); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 tmpchannel = pHalData->CurrentChannel; + BOOLEAN bResult = _TRUE; + + if(pHalData->rf_chip == RF_PSEUDO_11N) + { + //pHalData->SwChnlInProgress=FALSE; + return; //return immediately if it is peudo-phy + } + + //if(pHalData->SwChnlInProgress) + // return; + + //if(pHalData->SetBWModeInProgress) + // return; + + //-------------------------------------------- + switch(pHalData->CurrentWirelessMode) + { + case WIRELESS_MODE_A: + case WIRELESS_MODE_N_5G: + //RT_ASSERT((channel>14), ("WIRELESS_MODE_A but channel<=14")); + break; + + case WIRELESS_MODE_B: + //RT_ASSERT((channel<=14), ("WIRELESS_MODE_B but channel>14")); + break; + + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + //RT_ASSERT((channel<=14), ("WIRELESS_MODE_G but channel>14")); + break; + + default: + //RT_ASSERT(FALSE, ("Invalid WirelessMode(%#x)!!\n", pHalData->CurrentWirelessMode)); + break; + } + //-------------------------------------------- + + //pHalData->SwChnlInProgress = TRUE; + if(channel == 0) + channel = 1; + + pHalData->CurrentChannel=channel; + + //pHalData->SwChnlStage=0; + //pHalData->SwChnlStep=0; + + if((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) + { +#ifdef USE_WORKITEM + //bResult = PlatformScheduleWorkItem(&(pHalData->SwChnlWorkItem)); +#else + #if 0 + //PlatformSetTimer(Adapter, &(pHalData->SwChnlTimer), 0); + #else + _PHY_SwChnl8192C(Adapter, channel); + #endif +#endif + if(bResult) + { + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SwChnl8192C SwChnlInProgress TRUE schdule workitem done\n")); + } + else + { + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SwChnl8192C SwChnlInProgress FALSE schdule workitem error\n")); + //if(IS_HARDWARE_TYPE_8192SU(Adapter)) + //{ + // pHalData->SwChnlInProgress = FALSE; + pHalData->CurrentChannel = tmpchannel; + //} + } + + } + else + { + //RT_TRACE(COMP_SCAN, DBG_LOUD, ("PHY_SwChnl8192C SwChnlInProgress FALSE driver sleep or unload\n")); + //if(IS_HARDWARE_TYPE_8192SU(Adapter)) + //{ + // pHalData->SwChnlInProgress = FALSE; + pHalData->CurrentChannel = tmpchannel; + //} + } +} + + +static BOOLEAN +phy_SwChnlStepByStep( + IN PADAPTER Adapter, + IN u8 channel, + IN u8 *stage, + IN u8 *step, + OUT u32 *delay + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PCHANNEL_ACCESS_SETTING pChnlAccessSetting; + SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT]; + u4Byte PreCommonCmdCnt; + SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT]; + u4Byte PostCommonCmdCnt; + SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT]; + u4Byte RfDependCmdCnt; + SwChnlCmd *CurrentCmd; + u1Byte eRFPath; + u4Byte RfTXPowerCtrl; + BOOLEAN bAdjRfTXPowerCtrl = _FALSE; + + + RT_ASSERT((Adapter != NULL), ("Adapter should not be NULL\n")); +#if(MP_DRIVER != 1) + RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel)); +#endif + RT_ASSERT((pHalData != NULL), ("pHalData should not be NULL\n")); + + pChnlAccessSetting = &Adapter->MgntInfo.Info8185.ChannelAccessSetting; + RT_ASSERT((pChnlAccessSetting != NULL), ("pChnlAccessSetting should not be NULL\n")); + + //for(eRFPath = RF_PATH_A; eRFPath NumTotalRFPath; eRFPath++) + //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + //{ + // <1> Fill up pre common command. + PreCommonCmdCnt = 0; + phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, + CmdID_SetTxPowerLevel, 0, 0, 0); + phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, + CmdID_End, 0, 0, 0); + + // <2> Fill up post common command. + PostCommonCmdCnt = 0; + + phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT, + CmdID_End, 0, 0, 0); + + // <3> Fill up RF dependent command. + RfDependCmdCnt = 0; + switch( pHalData->RFChipID ) + { + case RF_8225: + RT_ASSERT((channel >= 1 && channel <= 14), ("illegal channel for Zebra: %d\n", channel)); + // 2008/09/04 MH Change channel. + if(channel==14) channel++; + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, (0x10+channel-1), 10); + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_8256: + // TEST!! This is not the table for 8256!! + RT_ASSERT((channel >= 1 && channel <= 14), ("illegal channel for Zebra: %d\n", channel)); + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rRfChannel, channel, 10); + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_6052: + RT_ASSERT((channel >= 1 && channel <= 14), ("illegal channel for Zebra: %d\n", channel)); + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, RF_CHNLBW, channel, 10); + phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + + break; + + case RF_8258: + break; + + // For FPGA two MAC verification + case RF_PSEUDO_11N: + return TRUE; + default: + RT_ASSERT(FALSE, ("Unknown RFChipID: %d\n", pHalData->RFChipID)); + return FALSE; + break; + } + + + do{ + switch(*stage) + { + case 0: + CurrentCmd=&PreCommonCmd[*step]; + break; + case 1: + CurrentCmd=&RfDependCmd[*step]; + break; + case 2: + CurrentCmd=&PostCommonCmd[*step]; + break; + } + + if(CurrentCmd->CmdID==CmdID_End) + { + if((*stage)==2) + { + return TRUE; + } + else + { + (*stage)++; + (*step)=0; + continue; + } + } + + switch(CurrentCmd->CmdID) + { + case CmdID_SetTxPowerLevel: + PHY_SetTxPowerLevel8192C(Adapter,channel); + break; + case CmdID_WritePortUlong: + PlatformEFIOWrite4Byte(Adapter, CurrentCmd->Para1, CurrentCmd->Para2); + break; + case CmdID_WritePortUshort: + PlatformEFIOWrite2Byte(Adapter, CurrentCmd->Para1, (u2Byte)CurrentCmd->Para2); + break; + case CmdID_WritePortUchar: + PlatformEFIOWrite1Byte(Adapter, CurrentCmd->Para1, (u1Byte)CurrentCmd->Para2); + break; + case CmdID_RF_WriteReg: // Only modify channel for the register now !!!!! + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + { +#if 1 + pHalData->RfRegChnlVal[eRFPath] = ((pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | CurrentCmd->Para2); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); +#else + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bRFRegOffsetMask, (CurrentCmd->Para2)); +#endif + } + break; + } + + break; + }while(TRUE); + //cosa }/*for(Number of RF paths)*/ + + (*delay)=CurrentCmd->msDelay; + (*step)++; + return FALSE; +#endif + return _TRUE; +} + + +static BOOLEAN +phy_SetSwChnlCmdArray( + SwChnlCmd* CmdTable, + u32 CmdTableIdx, + u32 CmdTableSz, + SwChnlCmdID CmdID, + u32 Para1, + u32 Para2, + u32 msDelay + ) +{ + SwChnlCmd* pCmd; + + if(CmdTable == NULL) + { + //RT_ASSERT(FALSE, ("phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n")); + return _FALSE; + } + if(CmdTableIdx >= CmdTableSz) + { + //RT_ASSERT(FALSE, + // ("phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%ld, CmdTableSz:%ld\n", + // CmdTableIdx, CmdTableSz)); + return _FALSE; + } + + pCmd = CmdTable + CmdTableIdx; + pCmd->CmdID = CmdID; + pCmd->Para1 = Para1; + pCmd->Para2 = Para2; + pCmd->msDelay = msDelay; + + return _TRUE; +} + + +static void +phy_FinishSwChnlNow( // We should not call this function directly + IN PADAPTER Adapter, + IN u8 channel + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 delay; + + while(!phy_SwChnlStepByStep(Adapter,channel,&pHalData->SwChnlStage,&pHalData->SwChnlStep,&delay)) + { + if(delay>0) + rtw_mdelay_os(delay); + } +#endif +} + + + +// +// Description: +// Switch channel synchronously. Called by SwChnlByDelayHandler. +// +// Implemented by Bruce, 2008-02-14. +// The following procedure is operted according to SwChanlCallback8190Pci(). +// However, this procedure is performed synchronously which should be running under +// passive level. +// +VOID +PHY_SwChnlPhy8192C( // Only called during initialize + IN PADAPTER Adapter, + IN u8 channel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + //RT_TRACE(COMP_SCAN | COMP_RM, DBG_LOUD, ("==>PHY_SwChnlPhy8192S(), switch from channel %d to channel %d.\n", pHalData->CurrentChannel, channel)); + + // Cannot IO. + //if(RT_CANNOT_IO(Adapter)) + // return; + + // Channel Switching is in progress. + //if(pHalData->SwChnlInProgress) + // return; + + //return immediately if it is peudo-phy + if(pHalData->rf_chip == RF_PSEUDO_11N) + { + //pHalData->SwChnlInProgress=FALSE; + return; + } + + //pHalData->SwChnlInProgress = TRUE; + if( channel == 0) + channel = 1; + + pHalData->CurrentChannel=channel; + + //pHalData->SwChnlStage = 0; + //pHalData->SwChnlStep = 0; + + phy_FinishSwChnlNow(Adapter,channel); + + //pHalData->SwChnlInProgress = FALSE; +} + + +// +// Description: +// Configure H/W functionality to enable/disable Monitor mode. +// Note, because we possibly need to configure BB and RF in this function, +// so caller should in PASSIVE_LEVEL. 080118, by rcnjko. +// +VOID +PHY_SetMonitorMode8192C( + IN PADAPTER pAdapter, + IN BOOLEAN bEnableMonitorMode + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN bFilterOutNonAssociatedBSSID = FALSE; + + //2 Note: we may need to stop antenna diversity. + if(bEnableMonitorMode) + { + bFilterOutNonAssociatedBSSID = FALSE; + RT_TRACE(COMP_RM, DBG_LOUD, ("PHY_SetMonitorMode8192S(): enable monitor mode\n")); + + pHalData->bInMonitorMode = TRUE; + pAdapter->HalFunc.AllowAllDestAddrHandler(pAdapter, TRUE, TRUE); + rtw_hal_set_hwreg(pAdapter, HW_VAR_CHECK_BSSID, (pu1Byte)&bFilterOutNonAssociatedBSSID); + } + else + { + bFilterOutNonAssociatedBSSID = TRUE; + RT_TRACE(COMP_RM, DBG_LOUD, ("PHY_SetMonitorMode8192S(): disable monitor mode\n")); + + pAdapter->HalFunc.AllowAllDestAddrHandler(pAdapter, FALSE, TRUE); + pHalData->bInMonitorMode = FALSE; + rtw_hal_set_hwreg(pAdapter, HW_VAR_CHECK_BSSID, (pu1Byte)&bFilterOutNonAssociatedBSSID); + } +#endif +} + + +/*----------------------------------------------------------------------------- + * Function: PHYCheckIsLegalRfPath8190Pci() + * + * Overview: Check different RF type to execute legal judgement. If RF Path is illegal + * We will return false. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/15/2007 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +BOOLEAN +PHY_CheckIsLegalRfPath8192C( + IN PADAPTER pAdapter, + IN u32 eRFPath) +{ +// HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN rtValue = _TRUE; + + // NOt check RF Path now.! +#if 0 + if (pHalData->RF_Type == RF_1T2R && eRFPath != RF_PATH_A) + { + rtValue = FALSE; + } + if (pHalData->RF_Type == RF_1T2R && eRFPath != RF_PATH_A) + { + + } +#endif + return rtValue; + +} /* PHY_CheckIsLegalRfPath8192C */ + +//------------------------------------------------------------------------- +// +// IQK +// +//------------------------------------------------------------------------- +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms + +static u8 //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +_PHY_PathA_IQK( + IN PADAPTER pAdapter, + IN BOOLEAN configPathB + ) +{ + u32 regEAC, regE94, regE9C, regEA4; + u8 result = 0x00; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //RTPRINT(FINIT, INIT_IQK, ("Path A IQK!\n")); + + //path-A IQK setting + //RTPRINT(FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + PHY_SetBBReg(pAdapter, rTx_IQK_PI_A, bMaskDWord, 0x82140102); + + PHY_SetBBReg(pAdapter, rRx_IQK_PI_A, bMaskDWord, configPathB ? 0x28160202 : + IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202:0x28160502); + + //path-B IQK setting + if(configPathB) + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x10008c22); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x10008c22); + PHY_SetBBReg(pAdapter, rTx_IQK_PI_B, bMaskDWord, 0x82140102); + PHY_SetBBReg(pAdapter, rRx_IQK_PI_B, bMaskDWord, 0x28160202); + } + + //LO calibration setting + //RTPRINT(FINIT, INIT_IQK, ("LO calibration setting!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Rsp, bMaskDWord, 0x001028d1); + + //One shot, path A LOK & IQK + //RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms + //RTPRINT(FINIT, INIT_IQK, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME)); + rtw_udelay_os(IQK_DELAY_TIME*1000);//PlatformStallExecution(IQK_DELAY_TIME*1000); + + // Check failed + regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", regEAC)); + regE94 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xe94 = 0x%x\n", regE94)); + regE9C= PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xe9c = 0x%x\n", regE9C)); + regEA4= PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regEA4)); + + if(!(regEAC & BIT28) && + (((regE94 & 0x03FF0000)>>16) != 0x142) && + (((regE9C & 0x03FF0000)>>16) != 0x42) ) + result |= 0x01; + else //if Tx not OK, ignore Rx + return result; + + if(!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK + (((regEA4 & 0x03FF0000)>>16) != 0x132) && + (((regEAC & 0x03FF0000)>>16) != 0x36)) + result |= 0x02; + else + DBG_8192C("Path A Rx IQK fail!!\n"); + + return result; + + +} + +static u8 //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +_PHY_PathB_IQK( + IN PADAPTER pAdapter + ) +{ + u32 regEAC, regEB4, regEBC, regEC4, regECC; + u8 result = 0x00; + //RTPRINT(FINIT, INIT_IQK, ("Path B IQK!\n")); + + //One shot, path B LOK & IQK + //RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000002); + PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000000); + + // delay x ms + //RTPRINT(FINIT, INIT_IQK, ("Delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME)); + rtw_udelay_os(IQK_DELAY_TIME*1000);//PlatformStallExecution(IQK_DELAY_TIME*1000); + + // Check failed + regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", regEAC)); + regEB4 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regEB4)); + regEBC= PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xebc = 0x%x\n", regEBC)); + regEC4= PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regEC4)); + regECC= PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("0xecc = 0x%x\n", regECC)); + + if(!(regEAC & BIT31) && + (((regEB4 & 0x03FF0000)>>16) != 0x142) && + (((regEBC & 0x03FF0000)>>16) != 0x42)) + result |= 0x01; + else + return result; + + if(!(regEAC & BIT30) && + (((regEC4 & 0x03FF0000)>>16) != 0x132) && + (((regECC & 0x03FF0000)>>16) != 0x36)) + result |= 0x02; + else + DBG_8192C("Path B Rx IQK fail!!\n"); + + + return result; + +} + +static VOID +_PHY_PathAFillIQKMatrix( + IN PADAPTER pAdapter, + IN BOOLEAN bIQKOK, + IN int result[][8], + IN u8 final_candidate, + IN BOOLEAN bTxOnly + ) +{ + u32 Oldval_0, X, TX0_A, reg; + s32 Y, TX0_C; + + DBG_8192C("Path A IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed"); + + if(final_candidate == 0xFF) + return; + else if(bIQKOK) + { + Oldval_0 = (PHY_QueryBBReg(pAdapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][0]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX0_A = (X * Oldval_0) >> 8; + //RTPRINT(FINIT, INIT_IQK, ("X = 0x%lx, TX0_A = 0x%lx, Oldval_0 0x%lx\n", X, TX0_A, Oldval_0)); + PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31), ((X* Oldval_0>>7) & 0x1)); + + Y = result[final_candidate][1]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + TX0_C = (Y * Oldval_0) >> 8; + //RTPRINT(FINIT, INIT_IQK, ("Y = 0x%lx, TX = 0x%lx\n", Y, TX0_C)); + PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6)); + PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29), ((Y* Oldval_0>>7) & 0x1)); + + if(bTxOnly) + { + DBG_8192C("_PHY_PathAFillIQKMatrix only Tx OK\n"); + return; + } + + reg = result[final_candidate][2]; + PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0x3FF, reg); + + reg = result[final_candidate][3] & 0x3F; + PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0xFC00, reg); + + reg = (result[final_candidate][3] >> 6) & 0xF; + PHY_SetBBReg(pAdapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg); + } +} + +static VOID +_PHY_PathBFillIQKMatrix( + IN PADAPTER pAdapter, + IN BOOLEAN bIQKOK, + IN int result[][8], + IN u8 final_candidate, + IN BOOLEAN bTxOnly //do Tx only + ) +{ + u32 Oldval_1, X, TX1_A, reg; + s32 Y, TX1_C; + + DBG_8192C("Path B IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed"); + + if(final_candidate == 0xFF) + return; + else if(bIQKOK) + { + Oldval_1 = (PHY_QueryBBReg(pAdapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][4]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX1_A = (X * Oldval_1) >> 8; + //RTPRINT(FINIT, INIT_IQK, ("X = 0x%lx, TX1_A = 0x%lx\n", X, TX1_A)); + PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27), ((X* Oldval_1>>7) & 0x1)); + + Y = result[final_candidate][5]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + TX1_C = (Y * Oldval_1) >> 8; + //RTPRINT(FINIT, INIT_IQK, ("Y = 0x%lx, TX1_C = 0x%lx\n", Y, TX1_C)); + PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6)); + PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25), ((Y* Oldval_1>>7) & 0x1)); + + if(bTxOnly) + return; + + reg = result[final_candidate][6]; + PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg); + + reg = result[final_candidate][7] & 0x3F; + PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg); + + reg = (result[final_candidate][7] >> 6) & 0xF; + PHY_SetBBReg(pAdapter, rOFDM0_AGCRSSITable, 0x0000F000, reg); + } +} + +static VOID +_PHY_SaveADDARegisters( + IN PADAPTER pAdapter, + IN u32* ADDAReg, + IN u32* ADDABackup, + IN u32 RegisterNum + ) +{ + u32 i; + + //RTPRINT(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + for( i = 0 ; i < RegisterNum ; i++){ + ADDABackup[i] = PHY_QueryBBReg(pAdapter, ADDAReg[i], bMaskDWord); + } +} + +static VOID +_PHY_SaveMACRegisters( + IN PADAPTER pAdapter, + IN u32* MACReg, + IN u32* MACBackup + ) +{ + u32 i; + + //RTPRINT(FINIT, INIT_IQK, ("Save MAC parameters.\n")); + for( i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++){ + MACBackup[i] =rtw_read8(pAdapter, MACReg[i]); + } + MACBackup[i] = rtw_read32(pAdapter, MACReg[i]); + +} + +static VOID +_PHY_ReloadADDARegisters( + IN PADAPTER pAdapter, + IN u32* ADDAReg, + IN u32* ADDABackup, + IN u32 RegiesterNum + ) +{ + u32 i; + + //RTPRINT(FINIT, INIT_IQK, ("Reload ADDA power saving parameters !\n")); + for(i = 0 ; i < RegiesterNum ; i++){ + PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, ADDABackup[i]); + } +} + +static VOID +_PHY_ReloadMACRegisters( + IN PADAPTER pAdapter, + IN u32* MACReg, + IN u32* MACBackup + ) +{ + u32 i; + + //RTPRINT(FINIT, INIT_IQK, ("Reload MAC parameters !\n")); + for(i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++){ + rtw_write8(pAdapter, MACReg[i], (u8)MACBackup[i]); + } + rtw_write32(pAdapter, MACReg[i], MACBackup[i]); +} + +static VOID +_PHY_PathADDAOn( + IN PADAPTER pAdapter, + IN u32* ADDAReg, + IN BOOLEAN isPathAOn, + IN BOOLEAN is2T + ) +{ + u32 pathOn; + u32 i; + + //RTPRINT(FINIT, INIT_IQK, ("ADDA ON.\n")); + + pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; + if(_FALSE == is2T){ + pathOn = 0x0bdb25a0; + PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, 0x0b1b25a0); + } + else{ + PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, pathOn); + } + + for( i = 1 ; i < IQK_ADDA_REG_NUM ; i++){ + PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, pathOn); + } + +} + +static VOID +_PHY_MACSettingCalibration( + IN PADAPTER pAdapter, + IN u32* MACReg, + IN u32* MACBackup + ) +{ + u32 i = 0; + + //RTPRINT(FINIT, INIT_IQK, ("MAC settings for Calibration.\n")); + + rtw_write8(pAdapter, MACReg[i], 0x3F); + + for(i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++){ + rtw_write8(pAdapter, MACReg[i], (u8)(MACBackup[i]&(~BIT3))); + } + rtw_write8(pAdapter, MACReg[i], (u8)(MACBackup[i]&(~BIT5))); + +} + +static VOID +_PHY_PathAStandBy( + IN PADAPTER pAdapter + ) +{ + //RTPRINT(FINIT, INIT_IQK, ("Path-A standby mode!\n")); + + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x0); + PHY_SetBBReg(pAdapter, 0x840, bMaskDWord, 0x00010000); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); +} + +static VOID +_PHY_PIModeSwitch( + IN PADAPTER pAdapter, + IN BOOLEAN PIMode + ) +{ + u32 mode; + + //RTPRINT(FINIT, INIT_IQK, ("BB Switch to %s mode!\n", (PIMode ? "PI" : "SI"))); + + mode = PIMode ? 0x01000100 : 0x01000000; + PHY_SetBBReg(pAdapter, 0x820, bMaskDWord, mode); + PHY_SetBBReg(pAdapter, 0x828, bMaskDWord, mode); +} + +/* +return _FALSE => do IQK again +*/ +static BOOLEAN +_PHY_SimularityCompare( + IN PADAPTER pAdapter, + IN int result[][8], + IN u8 c1, + IN u8 c2 + ) +{ + u32 i, j, diff, SimularityBitMap, bound = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 final_candidate[2] = {0xFF, 0xFF}; //for path A and path B + BOOLEAN bResult = _TRUE, is2T = IS_92C_SERIAL( pHalData->VersionID); + + if(is2T) + bound = 8; + else + bound = 4; + + SimularityBitMap = 0; + + for( i = 0; i < bound; i++ ) + { + diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]); + if (diff > MAX_TOLERANCE) + { + if((i == 2 || i == 6) && !SimularityBitMap) + { + if(result[c1][i]+result[c1][i+1] == 0) + final_candidate[(i/4)] = c2; + else if (result[c2][i]+result[c2][i+1] == 0) + final_candidate[(i/4)] = c1; + else + SimularityBitMap = SimularityBitMap|(1<dmpriv; + u32 i; + u8 PathAOK, PathBOK; + u32 ADDA_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 }; + + u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; + + u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, + rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, + rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD + }; + +#if MP_DRIVER + const u32 retryCount = 9; +#else + const u32 retryCount = 2; +#endif + + // Note: IQ calibration must be performed after loading + // PHY_REG.txt , and radio_a, radio_b.txt + + u32 bbvalue; + + if(t==0) + { + bbvalue = PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bMaskDWord); + //RTPRINT(FINIT, INIT_IQK, ("PHY_IQCalibrate()==>0x%08lx\n",bbvalue)); + + //RTPRINT(FINIT, INIT_IQK, ("IQ Calibration for %s\n", (is2T ? "2T2R" : "1T1R"))); + + // Save ADDA parameters, turn Path A ADDA on + _PHY_SaveADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup,IQK_ADDA_REG_NUM); + _PHY_SaveMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); + _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM); + } + _PHY_PathADDAOn(pAdapter, ADDA_REG, _TRUE, is2T); + + if(t==0) + { + pdmpriv->bRfPiEnable = (u8)PHY_QueryBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, BIT(8)); + } + + if(!pdmpriv->bRfPiEnable){ + // Switch BB to PI mode to do IQ Calibration. + _PHY_PIModeSwitch(pAdapter, _TRUE); + } + + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, BIT24, 0x00); + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); + PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); + + if(is2T) + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); + PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); + } + + //MAC settings + _PHY_MACSettingCalibration(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); + + //Page B init + PHY_SetBBReg(pAdapter, rConfig_AntA, bMaskDWord, 0x00080000); + + if(is2T) + { + PHY_SetBBReg(pAdapter, rConfig_AntB, bMaskDWord, 0x00080000); + } + + // IQ calibration setting + //RTPRINT(FINIT, INIT_IQK, ("IQK setting!\n")); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); + PHY_SetBBReg(pAdapter, rTx_IQK, bMaskDWord, 0x01007c00); + PHY_SetBBReg(pAdapter, rRx_IQK, bMaskDWord, 0x01004800); + + for(i = 0 ; i < retryCount ; i++){ + PathAOK = _PHY_PathA_IQK(pAdapter, is2T); + if(PathAOK == 0x03){ + DBG_8192C("Path A IQK Success!!\n"); + result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][2] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; + result[t][3] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; + break; + } + else if (i == (retryCount-1) && PathAOK == 0x01) //Tx IQK OK + { + DBG_8192C("Path A IQK Only Tx Success!!\n"); + + result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + } + } + + if(0x00 == PathAOK){ + DBG_8192C("Path A IQK failed!!\n"); + } + + if(is2T){ + _PHY_PathAStandBy(pAdapter); + + // Turn Path B ADDA on + _PHY_PathADDAOn(pAdapter, ADDA_REG, _FALSE, is2T); + + for(i = 0 ; i < retryCount ; i++){ + PathBOK = _PHY_PathB_IQK(pAdapter); + if(PathBOK == 0x03){ + DBG_8192C("Path B IQK Success!!\n"); + result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][6] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; + result[t][7] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; + break; + } + else if (i == (retryCount - 1) && PathBOK == 0x01) //Tx IQK OK + { + DBG_8192C("Path B Only Tx IQK Success!!\n"); + result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; + } + } + + if(0x00 == PathBOK){ + DBG_8192C("Path B IQK failed!!\n"); + } + } + + //Back to BB mode, load original value + //RTPRINT(FINIT, INIT_IQK, ("IQK:Back to BB mode, load original value!\n")); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0); + + if(t!=0) + { + if(!pdmpriv->bRfPiEnable){ + // Switch back BB to SI mode after finish IQ Calibration. + _PHY_PIModeSwitch(pAdapter, _FALSE); + } + + // Reload ADDA power saving parameters + _PHY_ReloadADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM); + + // Reload MAC parameters + _PHY_ReloadMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); + + // Reload BB parameters + _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM); + + // Restore RX initial gain + PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); + if(is2T){ + PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); + } + + //load 0xe30 IQC default value + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + + } + //RTPRINT(FINIT, INIT_IQK, ("_PHY_IQCalibrate() <==\n")); + +} + + +static VOID +_PHY_LCCalibrate( + IN PADAPTER pAdapter, + IN BOOLEAN is2T + ) +{ + u8 tmpReg; + u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal; + + //Check continuous TX and Packet TX + tmpReg = rtw_read8(pAdapter, 0xd03); + + if((tmpReg&0x70) != 0) //Deal with contisuous TX case + rtw_write8(pAdapter, 0xd03, tmpReg&0x8F); //disable all continuous TX + else // Deal with Packet TX case + rtw_write8(pAdapter, REG_TXPAUSE, 0xFF); // block all queues + + if((tmpReg&0x70) != 0) + { + //1. Read original RF mode + //Path-A + RF_Amode = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits); + + //Path-B + if(is2T) + RF_Bmode = PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits); + + //2. Set RF mode = standby mode + //Path-A + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000); + + //Path-B + if(is2T) + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000); + } + + //3. Read RF reg18 + LC_Cal = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits); + + //4. Set LC calibration begin + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000); + + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(100); + #else + rtw_mdelay_os(100); + #endif + + //Restore original situation + if((tmpReg&0x70) != 0) //Deal with contisuous TX case + { + //Path-A + rtw_write8(pAdapter, 0xd03, tmpReg); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); + + //Path-B + if(is2T) + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); + } + else // Deal with Packet TX case + { + rtw_write8(pAdapter, REG_TXPAUSE, 0x00); + } + +} + + +//Analog Pre-distortion calibration +#define APK_BB_REG_NUM 8 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +static VOID +_PHY_APCalibrate( + IN PADAPTER pAdapter, + IN char delta, + IN BOOLEAN is2T + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + u32 regD[PATH_NUM]; + u32 tmpReg, index, offset, i, apkbound; + u8 path, pathbound = PATH_NUM; + u32 BB_backup[APK_BB_REG_NUM]; + u32 BB_REG[APK_BB_REG_NUM] = { + rFPGA1_TxBlock, rOFDM0_TRxPathEnable, + rFPGA0_RFMOD, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW, + rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE }; + u32 BB_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 }; + u32 BB_normal_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 }; + + u32 AFE_backup[IQK_ADDA_REG_NUM]; + u32 AFE_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 }; + + u32 MAC_backup[IQK_MAC_REG_NUM]; + u32 MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; + + u32 APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u32 APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, //path settings equal to path b settings + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u32 APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u32 APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, //path settings equal to path b settings + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; +#if 0 + u32 APK_RF_value_A[PATH_NUM][APK_BB_REG_NUM] = { + {0x1adb0, 0x1adb0, 0x1ada0, 0x1ad90, 0x1ad80}, + {0x00fb0, 0x00fb0, 0x00fa0, 0x00f90, 0x00f80} + }; +#endif + u32 AFE_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4}; //path A on path B off / path A off path B on + + u32 APK_offset[PATH_NUM] = { + rConfig_AntA, rConfig_AntB}; + + u32 APK_normal_offset[PATH_NUM] = { + rConfig_Pmpd_AntA, rConfig_Pmpd_AntB}; + + u32 APK_value[PATH_NUM] = { + 0x92fc0000, 0x12fc0000}; + + u32 APK_normal_value[PATH_NUM] = { + 0x92680000, 0x12680000}; + + char APK_delta_mapping[APK_BB_REG_NUM][13] = { + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + u32 APK_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + u32 APK_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + u32 APK_result[PATH_NUM][APK_BB_REG_NUM]; //val_1_1a, val_1_2a, val_2a, val_3a, val_4a + //u32 AP_curve[PATH_NUM][APK_CURVE_REG_NUM]; + + int BB_offset, delta_V, delta_offset; + +#if (MP_DRIVER == 1) + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + + pMptCtx->APK_bound[0] = 45; + pMptCtx->APK_bound[1] = 52; +#endif + + //RTPRINT(FINIT, INIT_IQK, ("==>PHY_APCalibrate() delta %d\n", delta)); + + //RTPRINT(FINIT, INIT_IQK, ("AP Calibration for %s %s\n", (is2T ? "2T2R" : "1T1R"), (isNormal ? "Normal chip" : "Test chip"))); + + if(!is2T) + pathbound = 1; + + //2 FOR NORMAL CHIP SETTINGS + +// Temporarily do not allow normal driver to do the following settings because these offset +// and value will cause RF internal PA to be unpredictably disabled by HW, such that RF Tx signal +// will disappear after disable/enable card many times on 88CU. RF SD and DD have not find the +// root cause, so we remove these actions temporarily. Added by tynli and SD3 Allen. 2010.05.31. +#if (MP_DRIVER != 1) + return; +#endif + + //settings adjust for normal chip + for(index = 0; index < PATH_NUM; index ++) + { + APK_offset[index] = APK_normal_offset[index]; + APK_value[index] = APK_normal_value[index]; + AFE_on_off[index] = 0x6fdb25a4; + } + + for(index = 0; index < APK_BB_REG_NUM; index ++) + { + for(path = 0; path < pathbound; path++) + { + APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index]; + APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index]; + } + BB_AP_MODE[index] = BB_normal_AP_MODE[index]; + } + + apkbound = 6; + + //save BB default value + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + if(index == 0) //skip + continue; + BB_backup[index] = PHY_QueryBBReg(pAdapter, BB_REG[index], bMaskDWord); + } + + //save MAC default value + _PHY_SaveMACRegisters(pAdapter, MAC_REG, MAC_backup); + + //save AFE default value + _PHY_SaveADDARegisters(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + for(path = 0; path < pathbound; path++) + { + if(path == RF_PATH_A) + { + //path A APK + //load APK setting + //path-A + offset = rPdp_AntA; + for(index = 0; index < 11; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); + + offset = rConfig_AntA; + for(; index < 13; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x40000000); + + //path A + offset = rPdp_AntA; + for(index = 0; index < 16; index++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_2[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x00000000); + } + else if(path == RF_PATH_B) + { + //path B APK + //load APK setting + //path-B + offset = rPdp_AntB; + for(index = 0; index < 10; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000); + + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); + + offset = rConfig_AntA; + index = 11; + for(; index < 13; index ++) //offset 0xb68, 0xb6c + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x40000000); + + //path B + offset = 0xb60; + for(index = 0; index < 16; index++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_2[index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x00000000); + } + + //save RF default value + regD[path] = PHY_QueryRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_TXBIAS_A, bRFRegOffsetMask); + + //Path A AFE all on, path B AFE All off or vise versa + for(index = 0; index < IQK_ADDA_REG_NUM ; index++) + PHY_SetBBReg(pAdapter, AFE_REG[index], bMaskDWord, AFE_on_off[path]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0xe70 %x\n", PHY_QueryBBReg(pAdapter, 0xe70, bMaskDWord))); + + //BB to AP mode + if(path == 0) + { + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + if(index == 0) //skip + continue; + else if (index < 5) + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_AP_MODE[index]); + else if (BB_REG[index] == 0x870) + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_backup[index]|BIT10|BIT26); + else + PHY_SetBBReg(pAdapter, BB_REG[index], BIT10, 0x0); + } + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + } + else //path B + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00); + } + + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x800 %x\n", PHY_QueryBBReg(pAdapter, 0x800, bMaskDWord))); + + //MAC settings + _PHY_MACSettingCalibration(pAdapter, MAC_REG, MAC_backup); + + if(path == RF_PATH_A) //Path B to standby mode + { + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bRFRegOffsetMask, 0x10000); + } + else //Path A to standby mode + { + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0x10000); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE1, bRFRegOffsetMask, 0x1000f); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE2, bRFRegOffsetMask, 0x20103); + } + + delta_offset = ((delta+14)/2); + if(delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + //AP calibration + for(index = 0; index < APK_BB_REG_NUM; index++) + { + if(index != 1) //only DO PA11+PAD01001, AP RF setting + continue; + + tmpReg = APK_RF_init_value[path][index]; +#if 1 + if(!pdmpriv->bAPKThermalMeterIgnore) + { + BB_offset = (tmpReg & 0xF0000) >> 16; + + if(!(tmpReg & BIT15)) //sign bit 0 + { + BB_offset = -BB_offset; + } + + delta_V = APK_delta_mapping[index][delta_offset]; + + BB_offset += delta_V; + + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() APK num %d delta_V %d delta_offset %d\n", index, delta_V, delta_offset)); + + if(BB_offset < 0) + { + tmpReg = tmpReg & (~BIT15); + BB_offset = -BB_offset; + } + else + { + tmpReg = tmpReg | BIT15; + } + tmpReg = (tmpReg & 0xFFF0FFFF) | (BB_offset << 16); + } +#endif + +#ifdef CONFIG_PCI_HCI + if(IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_IPA_A, bRFRegOffsetMask, 0x894ae); + else +#endif + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_IPA_A, bRFRegOffsetMask, 0x8992e); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0xc %x\n", PHY_QueryRFReg(pAdapter, (RF_RADIO_PATH_E)path, 0xc, bMaskDWord))); + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_AC, bRFRegOffsetMask, APK_RF_value_0[path][index]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x0 %x\n", PHY_QueryRFReg(pAdapter, (RF_RADIO_PATH_E)path, 0x0, bMaskDWord))); + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_TXBIAS_A, bRFRegOffsetMask, tmpReg); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0xd %x\n", PHY_QueryRFReg(pAdapter, (RF_RADIO_PATH_E)path, 0xd, bMaskDWord))); + + // PA11+PAD01111, one shot + i = 0; + do + { + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80000000); + { + PHY_SetBBReg(pAdapter, APK_offset[path], bMaskDWord, APK_value[0]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", APK_offset[path], PHY_QueryBBReg(pAdapter, APK_offset[path], bMaskDWord))); + rtw_mdelay_os(3); + PHY_SetBBReg(pAdapter, APK_offset[path], bMaskDWord, APK_value[1]); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0x%x value 0x%x\n", APK_offset[path], PHY_QueryBBReg(pAdapter, APK_offset[path], bMaskDWord))); + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(20); + #else + rtw_mdelay_os(20); + #endif + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x00000000); + + if(path == RF_PATH_A) + tmpReg = PHY_QueryBBReg(pAdapter, rAPK, 0x03E00000); + else + tmpReg = PHY_QueryBBReg(pAdapter, rAPK, 0xF8000000); + //RTPRINT(FINIT, INIT_IQK, ("PHY_APCalibrate() offset 0xbd8[25:21] %x\n", tmpReg)); + + i++; + } + while(tmpReg > apkbound && i < 4); + + APK_result[path][index] = tmpReg; + } + } + + //reload MAC default value + _PHY_ReloadMACRegisters(pAdapter, MAC_REG, MAC_backup); + + //reload BB default value + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + if(index == 0) //skip + continue; + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_backup[index]); + } + + //reload AFE default value + _PHY_ReloadADDARegisters(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + //reload RF path default value + for(path = 0; path < pathbound; path++) + { + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_TXBIAS_A, bRFRegOffsetMask, regD[path]); + if(path == RF_PATH_B) + { + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE1, bRFRegOffsetMask, 0x1000f); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE2, bRFRegOffsetMask, 0x20101); + } + + //note no index == 0 + if (APK_result[path][1] > 6) + APK_result[path][1] = 6; + //RTPRINT(FINIT, INIT_IQK, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1])); + } + + //RTPRINT(FINIT, INIT_IQK, ("\n")); + + + for(path = 0; path < pathbound; path++) + { + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_BS_PA_APSET_G1_G4, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1])); + if(path == RF_PATH_A) + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_BS_PA_APSET_G5_G8, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05)); + else + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_BS_PA_APSET_G5_G8, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05)); + PHY_SetRFReg(pAdapter, (RF_RADIO_PATH_E)path, RF_BS_PA_APSET_G9_G11, bRFRegOffsetMask, + ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08)); + } + + pdmpriv->bAPKdone = _TRUE; + + //RTPRINT(FINIT, INIT_IQK, ("<==PHY_APCalibrate()\n")); +} + +static VOID _PHY_SetRFPathSwitch( + IN PADAPTER pAdapter, + IN BOOLEAN bMain, + IN BOOLEAN is2T + ) +{ + u8 u1bTmp; + + if(!pAdapter->hw_init_completed) + { + u1bTmp = rtw_read8(pAdapter, REG_LEDCFG2) | BIT7; + rtw_write8(pAdapter, REG_LEDCFG2, u1bTmp); + //PHY_SetBBReg(pAdapter, REG_LEDCFG0, BIT23, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT13, 0x01); + } + + if(is2T) + { + if(bMain) + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x1); //92C_Path_A + else + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6, 0x2); //BT + } + else + { + + if(bMain) + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300, 0x2); //Main + else + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300, 0x1); //Aux + } + +} + +//return value TRUE => Main; FALSE => Aux + +static BOOLEAN _PHY_QueryRFPathSwitch( + IN PADAPTER pAdapter, + IN BOOLEAN is2T + ) +{ +// if(is2T) +// return _TRUE; + + if(!pAdapter->hw_init_completed) + { + PHY_SetBBReg(pAdapter, REG_LEDCFG0, BIT23, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT13, 0x01); + } + + if(is2T) + { + if(PHY_QueryBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5|BIT6) == 0x01) + return _TRUE; + else + return _FALSE; + } + else + { + if(PHY_QueryBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, 0x300) == 0x02) + return _TRUE; + else + return _FALSE; + } +} + +VOID +rtl8192c_PHY_IQCalibrate( + IN PADAPTER pAdapter, + IN BOOLEAN bReCovery + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + s32 result[4][8]; //last is final result + u8 i, final_candidate; + BOOLEAN bPathAOK, bPathBOK; + s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0; + BOOLEAN is12simular, is13simular, is23simular; + BOOLEAN bStartContTx = _FALSE, bSingleTone = _FALSE, bCarrierSuppression = _FALSE; + u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, + rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, + rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, + rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, + rOFDM0_RxIQExtAnta}; + + +#if MP_DRIVER == 1 + bStartContTx = pAdapter->mppriv.MptCtx.bStartContTx; + bSingleTone = pAdapter->mppriv.MptCtx.bSingleTone; + bCarrierSuppression = pAdapter->mppriv.MptCtx.bCarrierSuppression; +#endif + + //ignore IQK when continuous Tx + if(bStartContTx || bSingleTone || bCarrierSuppression) + return; + +#if DISABLE_BB_RF + return; +#endif + + if(bReCovery) + { + _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9); + return; + } + DBG_8192C("IQK:Start!!!\n"); + + for(i = 0; i < 8; i++) + { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + bPathAOK = _FALSE; + bPathBOK = _FALSE; + is12simular = _FALSE; + is23simular = _FALSE; + is13simular = _FALSE; + + for (i=0; i<3; i++) + { + if(IS_92C_SERIAL( pHalData->VersionID)){ + _PHY_IQCalibrate(pAdapter, result, i, _TRUE); + } + else{ + // For 88C 1T1R + _PHY_IQCalibrate(pAdapter, result, i, _FALSE); + } + + if(i == 1) + { + is12simular = _PHY_SimularityCompare(pAdapter, result, 0, 1); + if(is12simular) + { + final_candidate = 0; + break; + } + } + + if(i == 2) + { + is13simular = _PHY_SimularityCompare(pAdapter, result, 0, 2); + if(is13simular) + { + final_candidate = 0; + break; + } + + is23simular = _PHY_SimularityCompare(pAdapter, result, 1, 2); + if(is23simular) + final_candidate = 1; + else + { + for(i = 0; i < 8; i++) + RegTmp += result[3][i]; + + if(RegTmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + + for (i=0; i<4; i++) + { + RegE94 = result[i][0]; + RegE9C = result[i][1]; + RegEA4 = result[i][2]; + RegEAC = result[i][3]; + RegEB4 = result[i][4]; + RegEBC = result[i][5]; + RegEC4 = result[i][6]; + RegECC = result[i][7]; + //RTPRINT(FINIT, INIT_IQK, ("IQK: RegE94=%lx RegE9C=%lx RegEA4=%lx RegEAC=%lx RegEB4=%lx RegEBC=%lx RegEC4=%lx RegECC=%lx\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC)); + } + + if(final_candidate != 0xff) + { + pdmpriv->RegE94 = RegE94 = result[final_candidate][0]; + pdmpriv->RegE9C = RegE9C = result[final_candidate][1]; + RegEA4 = result[final_candidate][2]; + RegEAC = result[final_candidate][3]; + pdmpriv->RegEB4 = RegEB4 = result[final_candidate][4]; + pdmpriv->RegEBC = RegEBC = result[final_candidate][5]; + RegEC4 = result[final_candidate][6]; + RegECC = result[final_candidate][7]; + DBG_8192C("IQK: final_candidate is %x\n", final_candidate); + DBG_8192C("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC); + bPathAOK = bPathBOK = _TRUE; + } + else + { + RegE94 = RegEB4 = pdmpriv->RegE94 = pdmpriv->RegEB4 = 0x100; //X default value + RegE9C = RegEBC = pdmpriv->RegE9C = pdmpriv->RegEBC = 0x0; //Y default value + } + + if((RegE94 != 0)/*&&(RegEA4 != 0)*/) + _PHY_PathAFillIQKMatrix(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); + + if(IS_92C_SERIAL( pHalData->VersionID)){ + if((RegEB4 != 0)/*&&(RegEC4 != 0)*/) + _PHY_PathBFillIQKMatrix(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); + } + + _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9); + +} + + +VOID +rtl8192c_PHY_LCCalibrate( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mlme_ext_priv *pmlmeext = &pAdapter->mlmeextpriv; + BOOLEAN bStartContTx = _FALSE, bSingleTone = _FALSE, bCarrierSuppression = _FALSE; + +#if MP_DRIVER == 1 + bStartContTx = pAdapter->mppriv.MptCtx.bStartContTx; + bSingleTone = pAdapter->mppriv.MptCtx.bSingleTone; + bCarrierSuppression = pAdapter->mppriv.MptCtx.bCarrierSuppression; +#endif + +#if DISABLE_BB_RF + return; +#endif + + //ignore IQK when continuous Tx + if(bStartContTx || bSingleTone || bCarrierSuppression) + return; + + if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS) + return; + + if(IS_92C_SERIAL( pHalData->VersionID)){ + _PHY_LCCalibrate(pAdapter, _TRUE); + } + else{ + // For 88C 1T1R + _PHY_LCCalibrate(pAdapter, _FALSE); + } +} + +VOID +rtl8192c_PHY_APCalibrate( + IN PADAPTER pAdapter, + IN char delta + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + //default disable APK, because Tx NG issue, suggest by Jenyu, 2011.11.25 + return; + +#if DISABLE_BB_RF + return; +#endif + + if(pdmpriv->bAPKdone) + return; + + if(IS_92C_SERIAL( pHalData->VersionID)){ + _PHY_APCalibrate(pAdapter, delta, _TRUE); + } + else{ + // For 88C 1T1R + _PHY_APCalibrate(pAdapter, delta, _FALSE); + } +} + +VOID rtl8192c_PHY_SetRFPathSwitch( + IN PADAPTER pAdapter, + IN BOOLEAN bMain + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + +#if DISABLE_BB_RF + return; +#endif + + if(IS_92C_SERIAL( pHalData->VersionID)){ + _PHY_SetRFPathSwitch(pAdapter, bMain, _TRUE); + } + else{ + // For 88C 1T1R + _PHY_SetRFPathSwitch(pAdapter, bMain, _FALSE); + } +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c new file mode 100755 index 00000000..cf469693 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c @@ -0,0 +1,1031 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/****************************************************************************** + * + * + * Module: rtl8192c_rf6052.c ( Source C File) + * + * Note: Provide RF 6052 series relative API. + * + * Function: + * + * Export: + * + * Abbrev: + * + * History: + * Data Who Remark + * + * 09/25/2008 MHC Create initial version. + * 11/05/2008 MHC Add API for tw power setting. + * + * +******************************************************************************/ + +#define _RTL8192C_RF6052_C_ + +#include +#include +#include +#include + +#include + +/*---------------------------Define Local Constant---------------------------*/ +// Define local structure for debug!!!!! +typedef struct RF_Shadow_Compare_Map { + // Shadow register value + u32 Value; + // Compare or not flag + u8 Compare; + // Record If it had ever modified unpredicted + u8 ErrorOrNot; + // Recorver Flag + u8 Recorver; + // + u8 Driver_Write; +}RF_SHADOW_T; +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ +/*------------------------Define global variable-----------------------------*/ + + +/*------------------------Define local variable------------------------------*/ +// 2008/11/20 MH For Debug only, RF +//static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG] = {0}; +static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG]; +/*------------------------Define local variable------------------------------*/ + + +/*----------------------------------------------------------------------------- + * Function: RF_ChangeTxPath + * + * Overview: For RL6052, we must change some RF settign for 1T or 2T. + * + * Input: u2Byte DataRate // 0x80-8f, 0x90-9f + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/25/2008 MHC Create Version 0. + * Firmwaer support the utility later. + * + *---------------------------------------------------------------------------*/ +void rtl8192c_RF_ChangeTxPath( IN PADAPTER Adapter, + IN u16 DataRate) +{ +// We do not support gain table change inACUT now !!!! Delete later !!! +#if 0//(RTL92SE_FPGA_VERIFY == 0) + static u1Byte RF_Path_Type = 2; // 1 = 1T 2= 2T + static u4Byte tx_gain_tbl1[6] + = {0x17f50, 0x11f40, 0x0cf30, 0x08720, 0x04310, 0x00100}; + static u4Byte tx_gain_tbl2[6] + = {0x15ea0, 0x10e90, 0x0c680, 0x08250, 0x04040, 0x00030}; + u1Byte i; + + if (RF_Path_Type == 2 && (DataRate&0xF) <= 0x7) + { + // Set TX SYNC power G2G3 loop filter + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G2, bRFRegOffsetMask, 0x0f000); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G3, bRFRegOffsetMask, 0xeacf1); + + // Change TX AGC gain table + for (i = 0; i < 6; i++) + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TX_AGC, bRFRegOffsetMask, tx_gain_tbl1[i]); + + // Set PA to high value + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G2, bRFRegOffsetMask, 0x01e39); + } + else if (RF_Path_Type == 1 && (DataRate&0xF) >= 0x8) + { + // Set TX SYNC power G2G3 loop filter + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G2, bRFRegOffsetMask, 0x04440); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G3, bRFRegOffsetMask, 0xea4f1); + + // Change TX AGC gain table + for (i = 0; i < 6; i++) + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TX_AGC, bRFRegOffsetMask, tx_gain_tbl2[i]); + + // Set PA low gain + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)RF_PATH_A, + RF_TXPA_G2, bRFRegOffsetMask, 0x01e19); + } +#endif + +} /* RF_ChangeTxPath */ + + +/*----------------------------------------------------------------------------- + * Function: PHY_RF6052SetBandwidth() + * + * Overview: This function is called by SetBWModeCallback8190Pci() only + * + * Input: PADAPTER Adapter + * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M + * + * Output: NONE + * + * Return: NONE + * + * Note: For RF type 0222D + *---------------------------------------------------------------------------*/ +VOID +rtl8192c_PHY_RF6052SetBandwidth( + IN PADAPTER Adapter, + IN HT_CHANNEL_WIDTH Bandwidth) //20M or 40M +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + switch(Bandwidth) + { + case HT_CHANNEL_WIDTH_20: + pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); + break; + + case HT_CHANNEL_WIDTH_40: + pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff)); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); + break; + + default: + //RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth )); + break; + } + +} + + +/*----------------------------------------------------------------------------- + * Function: PHY_RF6052SetCckTxPower + * + * Overview: + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/05/2008 MHC Simulate 8192series.. + * + *---------------------------------------------------------------------------*/ + +VOID +rtl8192c_PHY_RF6052SetCckTxPower( + IN PADAPTER Adapter, + IN u8* pPowerlevel) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + //PMGNT_INFO pMgntInfo=&Adapter->MgntInfo; + u32 TxAGC[2]={0, 0}, tmpval=0; + BOOLEAN TurboScanOff = _FALSE; + u8 idx1, idx2; + u8* ptr; + + // 2010/10/18 MH Accorsing to SD3 eechou's suggestion, we need to disable turbo scan for RU. + // Otherwise, external PA will be broken if power index > 0x20. +#ifdef CONFIG_USB_HCI + if (pHalData->EEPROMRegulatory != 0 || pHalData->ExternalPA) +#else + if (pHalData->EEPROMRegulatory != 0) +#endif + { + //DbgPrint("TurboScanOff=1 EEPROMRegulatory=%d ExternalPA=%d\n", pHalData->EEPROMRegulatory, pHalData->ExternalPA); + TurboScanOff = _TRUE; + } + + if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS) + { + TxAGC[RF_PATH_A] = 0x3f3f3f3f; + TxAGC[RF_PATH_B] = 0x3f3f3f3f; + + TurboScanOff = _TRUE;//disable turbo scan + + if(TurboScanOff) + { + for(idx1=RF_PATH_A; idx1<=RF_PATH_B; idx1++) + { + TxAGC[idx1] = + pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | + (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); +#ifdef CONFIG_USB_HCI + // 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. + if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA) + TxAGC[idx1] = 0x20; +#endif + } + } + } + else + { +// 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. +// Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. +// In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. + if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) + { + TxAGC[RF_PATH_A] = 0x10101010; + TxAGC[RF_PATH_B] = 0x10101010; + } + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + { + TxAGC[RF_PATH_A] = 0x00000000; + TxAGC[RF_PATH_B] = 0x00000000; + } + else + { + for(idx1=RF_PATH_A; idx1<=RF_PATH_B; idx1++) + { + TxAGC[idx1] = + pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | + (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); + } + + if(pHalData->EEPROMRegulatory==0) + { + tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) + + (pHalData->MCSTxPowerLevelOriginalOffset[0][7]<<8); + TxAGC[RF_PATH_A] += tmpval; + + tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) + + (pHalData->MCSTxPowerLevelOriginalOffset[0][15]<<24); + TxAGC[RF_PATH_B] += tmpval; + } + } + } + + for(idx1=RF_PATH_A; idx1<=RF_PATH_B; idx1++) + { + ptr = (u8*)(&(TxAGC[idx1])); + for(idx2=0; idx2<4; idx2++) + { + if(*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + + // rf-A cck tx power + tmpval = TxAGC[RF_PATH_A]&0xff; + PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval); + //RTPRINT(FPHY, PHY_TXPWR, ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_A_CCK1_Mcs32)); + tmpval = TxAGC[RF_PATH_A]>>8; + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + //RTPRINT(FPHY, PHY_TXPWR, ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_B_CCK11_A_CCK2_11)); + + // rf-B cck tx power + tmpval = TxAGC[RF_PATH_B]>>24; + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval); + //RTPRINT(FPHY, PHY_TXPWR, ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_B_CCK11_A_CCK2_11)); + tmpval = TxAGC[RF_PATH_B]&0x00ffffff; + PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); + //RTPRINT(FPHY, PHY_TXPWR, ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + // tmpval, rTxAGC_B_CCK1_55_Mcs32)); + +} /* PHY_RF6052SetCckTxPower */ + +// +// powerbase0 for OFDM rates +// powerbase1 for HT MCS rates +// +static void getPowerBase( + IN PADAPTER Adapter, + IN u8* pPowerLevel, + IN u8 Channel, + IN OUT u32* OfdmBase, + IN OUT u32* MCSBase + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 powerBase0, powerBase1; + u8 Legacy_pwrdiff=0; + s8 HT20_pwrdiff=0; + u8 i, powerlevel[2]; + + for(i=0; i<2; i++) + { + powerlevel[i] = pPowerLevel[i]; + Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1]; + powerBase0 = powerlevel[i] + Legacy_pwrdiff; + + powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0; + *(OfdmBase+i) = powerBase0; + //RTPRINT(FPHY, PHY_TXPWR, (" [OFDM power base index rf(%c) = 0x%x]\n", ((i==0)?'A':'B'), *(OfdmBase+i))); + } + + for(i=0; i<2; i++) + { + //Check HT20 to HT40 diff + if(pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) + { + HT20_pwrdiff = pHalData->TxPwrHt20Diff[i][Channel-1]; + powerlevel[i] += HT20_pwrdiff; + } + powerBase1 = powerlevel[i]; + powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1; + *(MCSBase+i) = powerBase1; + //RTPRINT(FPHY, PHY_TXPWR, (" [MCS power base index rf(%c) = 0x%x]\n", ((i==0)?'A':'B'), *(MCSBase+i))); + } +} + +static void getTxPowerWriteValByRegulatory( + IN PADAPTER Adapter, + IN u8 Channel, + IN u8 index, + IN u32* powerBase0, + IN u32* powerBase1, + OUT u32* pOutWriteVal + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 i, chnlGroup, pwr_diff_limit[4]; + u32 writeVal, customer_limit, rf; + + // + // Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate + // + for(rf=0; rf<2; rf++) + { + switch(pHalData->EEPROMRegulatory) + { + case 0: // Realtek better performance + // increase power diff defined by Realtek for large power + chnlGroup = 0; + //RTPRINT(FPHY, PHY_TXPWR, ("MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", + // chnlGroup, index, pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)])); + writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + + ((index<2)?powerBase0[rf]:powerBase1[rf]); + //RTPRINT(FPHY, PHY_TXPWR, ("RTK better performance, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal)); + break; + case 1: // Realtek regulatory + // increase power diff defined by Realtek for regulatory + { + if(pHalData->pwrGroupCnt == 1) + chnlGroup = 0; + if(pHalData->pwrGroupCnt >= 3) + { + if(Channel <= 3) + chnlGroup = 0; + else if(Channel >= 4 && Channel <= 9) + chnlGroup = 1; + else if(Channel > 9) + chnlGroup = 2; + + if(pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) + chnlGroup++; + else + chnlGroup+=4; + } + //RTPRINT(FPHY, PHY_TXPWR, ("MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", + //chnlGroup, index, pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)])); + writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + + ((index<2)?powerBase0[rf]:powerBase1[rf]); + //RTPRINT(FPHY, PHY_TXPWR, ("Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal)); + } + break; + case 2: // Better regulatory + // don't increase any power diff + writeVal = ((index<2)?powerBase0[rf]:powerBase1[rf]); + //RTPRINT(FPHY, PHY_TXPWR, ("Better regulatory, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal)); + break; + case 3: // Customer defined power diff. + // increase power diff defined by customer. + chnlGroup = 0; + //RTPRINT(FPHY, PHY_TXPWR, ("MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", + // chnlGroup, index, pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)])); + + if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) + { + //RTPRINT(FPHY, PHY_TXPWR, ("customer's limit, 40MHz rf(%c) = 0x%x\n", + // ((rf==0)?'A':'B'), pHalData->PwrGroupHT40[rf][Channel-1])); + } + else + { + //RTPRINT(FPHY, PHY_TXPWR, ("customer's limit, 20MHz rf(%c) = 0x%x\n", + // ((rf==0)?'A':'B'), pHalData->PwrGroupHT20[rf][Channel-1])); + } + for (i=0; i<4; i++) + { + pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)]&(0x7f<<(i*8)))>>(i*8)); + if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) + { + if(pwr_diff_limit[i] > pHalData->PwrGroupHT40[rf][Channel-1]) + pwr_diff_limit[i] = pHalData->PwrGroupHT40[rf][Channel-1]; + } + else + { + if(pwr_diff_limit[i] > pHalData->PwrGroupHT20[rf][Channel-1]) + pwr_diff_limit[i] = pHalData->PwrGroupHT20[rf][Channel-1]; + } + } + customer_limit = (pwr_diff_limit[3]<<24) | (pwr_diff_limit[2]<<16) | + (pwr_diff_limit[1]<<8) | (pwr_diff_limit[0]); + //RTPRINT(FPHY, PHY_TXPWR, ("Customer's limit rf(%c) = 0x%x\n", ((rf==0)?'A':'B'), customer_limit)); + + writeVal = customer_limit + ((index<2)?powerBase0[rf]:powerBase1[rf]); + //RTPRINT(FPHY, PHY_TXPWR, ("Customer, writeVal rf(%c)= 0x%x\n", ((rf==0)?'A':'B'), writeVal)); + break; + default: + chnlGroup = 0; + writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + + ((index<2)?powerBase0[rf]:powerBase1[rf]); + //RTPRINT(FPHY, PHY_TXPWR, ("RTK better performance, writeVal rf(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal)); + break; + } + +// 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. +// Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. +// In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. + + if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) + writeVal = 0x14141414; + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) + writeVal = 0x00000000; + + + // 20100628 Joseph: High power mode for BT-Coexist mechanism. + // This mechanism is only applied when Driver-Highpower-Mechanism is OFF. + if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1) + { + //RTPRINT(FBT, BT_TRACE, ("Tx Power (-6)\n")); + writeVal = writeVal - 0x06060606; + } + else if(pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2) + { + //RTPRINT(FBT, BT_TRACE, ("Tx Power (-0)\n")); + writeVal = writeVal; + } + *(pOutWriteVal+rf) = writeVal; + } +} + +static void writeOFDMPowerReg( + IN PADAPTER Adapter, + IN u8 index, + IN u32* pValue + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u16 RegOffset_A[6] = { rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, + rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, + rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12}; + u16 RegOffset_B[6] = { rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24, + rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04, + rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12}; + u8 i, rf, pwr_val[4]; + u32 writeVal; + u16 RegOffset; + + for(rf=0; rf<2; rf++) + { + writeVal = pValue[rf]; + for(i=0; i<4; i++) + { + pwr_val[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeVal = (pwr_val[3]<<24) | (pwr_val[2]<<16) |(pwr_val[1]<<8) |pwr_val[0]; + + if(rf == 0) + RegOffset = RegOffset_A[index]; + else + RegOffset = RegOffset_B[index]; + + PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal); + //RTPRINT(FPHY, PHY_TXPWR, ("Set 0x%x = %08x\n", RegOffset, writeVal)); + + // 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. + if(((pHalData->rf_type == RF_2T2R) && + (RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs15_Mcs12))|| + ((pHalData->rf_type != RF_2T2R) && + (RegOffset == rTxAGC_A_Mcs07_Mcs04 || RegOffset == rTxAGC_B_Mcs07_Mcs04)) ) + { + writeVal = pwr_val[3]; + if(RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_A_Mcs07_Mcs04) + RegOffset = 0xc90; + if(RegOffset == rTxAGC_B_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs07_Mcs04) + RegOffset = 0xc98; + for(i=0; i<3; i++) + { + if(i!=2) + writeVal = (writeVal>8)?(writeVal-8):0; + else + writeVal = (writeVal>6)?(writeVal-6):0; + rtw_write8(Adapter, (u32)(RegOffset+i), (u8)writeVal); + } + } + } +} +/*----------------------------------------------------------------------------- + * Function: PHY_RF6052SetOFDMTxPower + * + * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for + * different channel and read original value in TX power register area from + * 0xe00. We increase offset and original value to be correct tx pwr. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/05/2008 MHC Simulate 8192 series method. + * 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to + * A/B pwr difference or legacy/HT pwr diff. + * 2. We concern with path B legacy/HT OFDM difference. + * 01/22/2009 MHC Support new EPRO format from SD3. + * + *---------------------------------------------------------------------------*/ +VOID +rtl8192c_PHY_RF6052SetOFDMTxPower( + IN PADAPTER Adapter, + IN u8* pPowerLevel, + IN u8 Channel) +{ + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 writeVal[2], powerBase0[2], powerBase1[2]; + u8 index = 0; + + getPowerBase(Adapter, pPowerLevel, Channel, &powerBase0[0], &powerBase1[0]); + + for(index=0; index<6; index++) + { + getTxPowerWriteValByRegulatory(Adapter, Channel, index, + &powerBase0[0], &powerBase1[0], &writeVal[0]); + + writeOFDMPowerReg(Adapter, index, &writeVal[0]); + } + +} + + +static VOID +phy_RF6052_Config_HardCode( + IN PADAPTER Adapter + ) +{ + + // Set Default Bandwidth to 20M + //Adapter->HalFunc .SetBWModeHandler(Adapter, HT_CHANNEL_WIDTH_20); + + // TODO: Set Default Channel to channel one for RTL8225 + +} + +static int +phy_RF6052_Config_ParaFile( + IN PADAPTER Adapter + ) +{ + u32 u4RegValue; + u8 eRFPath; + BB_REGISTER_DEFINITION_T *pPhyReg; + + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + static char sz88CRadioAFile[] = RTL8188C_PHY_RADIO_A; + static char sz88CRadioBFile[] = RTL8188C_PHY_RADIO_B; +#ifdef CONFIG_USB_HCI + static char sz88CRadioAFile_mCard[] = RTL8188C_PHY_RADIO_A_mCard; + static char sz88CRadioBFile_mCard[] = RTL8188C_PHY_RADIO_B_mCard; + static char sz88CRadioAFile_HP[] = RTL8188C_PHY_RADIO_A_HP; +#endif + static char sz92CRadioAFile[] = RTL8192C_PHY_RADIO_A; + static char sz92CRadioBFile[] = RTL8192C_PHY_RADIO_B; + static char sz8723RadioAFile[] = RTL8723_PHY_RADIO_A; + static char sz8723RadioBFile[] = RTL8723_PHY_RADIO_B; + char *pszRadioAFile, *pszRadioBFile; + + + if(IS_HARDWARE_TYPE_8192C(Adapter)) + { + if(IS_92C_SERIAL( pHalData->VersionID))// 88c's IPA is different from 92c's + { + pszRadioAFile = sz92CRadioAFile; + pszRadioBFile = sz92CRadioBFile; + } + else + { + pszRadioAFile = sz88CRadioAFile; + pszRadioBFile = sz88CRadioBFile; +#ifdef CONFIG_USB_HCI + if( BOARD_MINICARD == pHalData->BoardType) + { + pszRadioAFile = sz88CRadioAFile_mCard; + pszRadioBFile = sz88CRadioBFile_mCard; + } + else if( BOARD_USB_High_PA == pHalData->BoardType) + { + pszRadioAFile = sz88CRadioAFile_HP; + } +#endif + } + } + else if(IS_HARDWARE_TYPE_8723A(Adapter)) + { + pszRadioAFile = sz8723RadioAFile; + pszRadioBFile = sz8723RadioBFile; + } + + //3//----------------------------------------------------------------- + //3// <2> Initialize RF + //3//----------------------------------------------------------------- + //for(eRFPath = RF_PATH_A; eRFPath NumTotalRFPath; eRFPath++) + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + { + + pPhyReg = &pHalData->PHYRegDef[eRFPath]; + + /*----Store original RFENV control type----*/ + switch(eRFPath) + { + case RF_PATH_A: + case RF_PATH_C: + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); + break; + case RF_PATH_B : + case RF_PATH_D: + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16); + break; + } + + /*----Set RF_ENV enable----*/ + PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + rtw_udelay_os(1);//PlatformStallExecution(1); + + /*----Set RF_ENV output high----*/ + PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); + rtw_udelay_os(1);//PlatformStallExecution(1); + + /* Set bit number of Address and Data for RF register */ + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 1 to 4 bits for 8255 + rtw_udelay_os(1);//PlatformStallExecution(1); + + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for 8255 + rtw_udelay_os(1);//PlatformStallExecution(1); + + /*----Initialize RF fom connfiguration file----*/ + switch(eRFPath) + { + case RF_PATH_A: +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus= rtl8192c_PHY_ConfigRFWithHeaderFile(Adapter,(RF_RADIO_PATH_E)eRFPath); +#else + rtStatus = rtl8192c_PHY_ConfigRFWithParaFile(Adapter, pszRadioAFile, (RF_RADIO_PATH_E)eRFPath); +#endif + break; + case RF_PATH_B: +#ifdef CONFIG_EMBEDDED_FWIMG + rtStatus = rtl8192c_PHY_ConfigRFWithHeaderFile(Adapter,(RF_RADIO_PATH_E)eRFPath); +#else + rtStatus = rtl8192c_PHY_ConfigRFWithParaFile(Adapter, pszRadioBFile, (RF_RADIO_PATH_E)eRFPath); +#endif + break; + case RF_PATH_C: + break; + case RF_PATH_D: + break; + } + + /*----Restore RFENV control type----*/; + switch(eRFPath) + { + case RF_PATH_A: + case RF_PATH_C: + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); + break; + case RF_PATH_B : + case RF_PATH_D: + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); + break; + } + + if(rtStatus != _SUCCESS){ + //RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath)); + goto phy_RF6052_Config_ParaFile_Fail; + } + + } + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("<---phy_RF6052_Config_ParaFile()\n")); + return rtStatus; + +phy_RF6052_Config_ParaFile_Fail: + return rtStatus; +} + + +int +PHY_RF6052_Config8192C( + IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rtStatus = _SUCCESS; + + // + // Initialize general global value + // + // TODO: Extend RF_PATH_C and RF_PATH_D in the future + if(pHalData->rf_type == RF_1T1R) + pHalData->NumTotalRFPath = 1; + else + pHalData->NumTotalRFPath = 2; + + // + // Config BB and RF + // + rtStatus = phy_RF6052_Config_ParaFile(Adapter); +#if 0 + switch( Adapter->MgntInfo.bRegHwParaFile ) + { + case 0: + phy_RF6052_Config_HardCode(Adapter); + break; + + case 1: + rtStatus = phy_RF6052_Config_ParaFile(Adapter); + break; + + case 2: + // Partial Modify. + phy_RF6052_Config_HardCode(Adapter); + phy_RF6052_Config_ParaFile(Adapter); + break; + + default: + phy_RF6052_Config_HardCode(Adapter); + break; + } +#endif + return rtStatus; + +} + + +// +// ==> RF shadow Operation API Code Section!!! +// +/*----------------------------------------------------------------------------- + * Function: PHY_RFShadowRead + * PHY_RFShadowWrite + * PHY_RFShadowCompare + * PHY_RFShadowRecorver + * PHY_RFShadowCompareAll + * PHY_RFShadowRecorverAll + * PHY_RFShadowCompareFlagSet + * PHY_RFShadowRecorverFlagSet + * + * Overview: When we set RF register, we must write shadow at first. + * When we are running, we must compare shadow abd locate error addr. + * Decide to recorver or not. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/20/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u32 +PHY_RFShadowRead( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset) +{ + return RF_Shadow[eRFPath][Offset].Value; + +} /* PHY_RFShadowRead */ + + +VOID +PHY_RFShadowWrite( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset, + IN u32 Data) +{ + RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask); + RF_Shadow[eRFPath][Offset].Driver_Write = _TRUE; + +} /* PHY_RFShadowWrite */ + + +BOOLEAN +PHY_RFShadowCompare( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset) +{ + u32 reg; + // Check if we need to check the register + if (RF_Shadow[eRFPath][Offset].Compare == _TRUE) + { + reg = PHY_QueryRFReg(Adapter, eRFPath, Offset, bRFRegOffsetMask); + // Compare shadow and real rf register for 20bits!! + if (RF_Shadow[eRFPath][Offset].Value != reg) + { + // Locate error position. + RF_Shadow[eRFPath][Offset].ErrorOrNot = _TRUE; + //RT_TRACE(COMP_INIT, DBG_LOUD, + //("PHY_RFShadowCompare RF-%d Addr%02lx Err = %05lx\n", + //eRFPath, Offset, reg)); + } + return RF_Shadow[eRFPath][Offset].ErrorOrNot ; + } + return _FALSE; +} /* PHY_RFShadowCompare */ + + +VOID +PHY_RFShadowRecorver( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset) +{ + // Check if the address is error + if (RF_Shadow[eRFPath][Offset].ErrorOrNot == _TRUE) + { + // Check if we need to recorver the register. + if (RF_Shadow[eRFPath][Offset].Recorver == _TRUE) + { + PHY_SetRFReg(Adapter, eRFPath, Offset, bRFRegOffsetMask, + RF_Shadow[eRFPath][Offset].Value); + //RT_TRACE(COMP_INIT, DBG_LOUD, + //("PHY_RFShadowRecorver RF-%d Addr%02lx=%05lx", + //eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value)); + } + } + +} /* PHY_RFShadowRecorver */ + + +VOID +PHY_RFShadowCompareAll( + IN PADAPTER Adapter) +{ + u32 eRFPath; + u32 Offset; + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++) + { + PHY_RFShadowCompare(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset); + } + } + +} /* PHY_RFShadowCompareAll */ + + +VOID +PHY_RFShadowRecorverAll( + IN PADAPTER Adapter) +{ + u32 eRFPath; + u32 Offset; + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++) + { + PHY_RFShadowRecorver(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset); + } + } + +} /* PHY_RFShadowRecorverAll */ + + +VOID +PHY_RFShadowCompareFlagSet( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset, + IN u8 Type) +{ + // Set True or False!!! + RF_Shadow[eRFPath][Offset].Compare = Type; + +} /* PHY_RFShadowCompareFlagSet */ + + +VOID +PHY_RFShadowRecorverFlagSet( + IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 Offset, + IN u8 Type) +{ + // Set True or False!!! + RF_Shadow[eRFPath][Offset].Recorver= Type; + +} /* PHY_RFShadowRecorverFlagSet */ + + +VOID +PHY_RFShadowCompareFlagSetAll( + IN PADAPTER Adapter) +{ + u32 eRFPath; + u32 Offset; + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++) + { + // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! + if (Offset != 0x26 && Offset != 0x27) + PHY_RFShadowCompareFlagSet(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset, _FALSE); + else + PHY_RFShadowCompareFlagSet(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset, _TRUE); + } + } + +} /* PHY_RFShadowCompareFlagSetAll */ + + +VOID +PHY_RFShadowRecorverFlagSetAll( + IN PADAPTER Adapter) +{ + u32 eRFPath; + u32 Offset; + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++) + { + // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! + if (Offset != 0x26 && Offset != 0x27) + PHY_RFShadowRecorverFlagSet(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset, _FALSE); + else + PHY_RFShadowRecorverFlagSet(Adapter, (RF_RADIO_PATH_E)eRFPath, Offset, _TRUE); + } + } + +} /* PHY_RFShadowCompareFlagSetAll */ + +VOID +PHY_RFShadowRefresh( + IN PADAPTER Adapter) +{ + u32 eRFPath; + u32 Offset; + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset <= RF6052_MAX_REG; Offset++) + { + RF_Shadow[eRFPath][Offset].Value = 0; + RF_Shadow[eRFPath][Offset].Compare = _FALSE; + RF_Shadow[eRFPath][Offset].Recorver = _FALSE; + RF_Shadow[eRFPath][Offset].ErrorOrNot = _FALSE; + RF_Shadow[eRFPath][Offset].Driver_Write = _FALSE; + } + } + +} /* PHY_RFShadowRead */ + +/* End of HalRf6052.c */ + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c new file mode 100755 index 00000000..3e0d795e --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c @@ -0,0 +1,876 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8192C_REDESC_C_ +#include +#include +#include +#include + +static u8 evm_db2percentage(s8 value) +{ + // + // -33dB~0dB to 0%~99% + // + s8 ret_val; + + ret_val = value; + //ret_val /= 2; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("EVMdbToPercentage92S 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 s32 signal_scale_mapping(_adapter *padapter, s32 cur_sig ) +{ + s32 ret_sig; + +#ifdef CONFIG_USB_HCI + if(cur_sig >= 51 && cur_sig <= 100) + { + ret_sig = 100; + } + else if(cur_sig >= 41 && cur_sig <= 50) + { + ret_sig = 80 + ((cur_sig - 40)*2); + } + else if(cur_sig >= 31 && cur_sig <= 40) + { + ret_sig = 66 + (cur_sig - 30); + } + else if(cur_sig >= 21 && cur_sig <= 30) + { + ret_sig = 54 + (cur_sig - 20); + } + else if(cur_sig >= 10 && cur_sig <= 20) + { + ret_sig = 42 + (((cur_sig - 10) * 2) / 3); + } + else if(cur_sig >= 5 && cur_sig <= 9) + { + ret_sig = 22 + (((cur_sig - 5) * 3) / 2); + } + else if(cur_sig >= 1 && cur_sig <= 4) + { + ret_sig = 6 + (((cur_sig - 1) * 3) / 2); + } + else + { + ret_sig = cur_sig; + } +#else + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if(pHalData->CustomerID == RT_CID_819x_Lenovo) + { + // 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(cur_sig >= 54 && cur_sig <= 100) + { + ret_sig = 100; + } + else if(cur_sig>=42 && cur_sig <= 53 ) + { + ret_sig = 95; + } + else if(cur_sig>=36 && cur_sig <= 41 ) + { + ret_sig = 74 + ((cur_sig - 36) *20)/6; + } + else if(cur_sig>=33 && cur_sig <= 35 ) + { + ret_sig = 65 + ((cur_sig - 33) *8)/2; + } + else if(cur_sig>=18 && cur_sig <= 32 ) + { + ret_sig = 62 + ((cur_sig - 18) *2)/15; + } + else if(cur_sig>=15 && cur_sig <= 17 ) + { + ret_sig = 33 + ((cur_sig - 15) *28)/2; + } + else if(cur_sig>=10 && cur_sig <= 14 ) + { + ret_sig = 39; + } + else if(cur_sig>=8 && cur_sig <= 9 ) + { + ret_sig = 33; + } + else if(cur_sig <= 8 ) + { + ret_sig = 19; + } + } + else + { + // Step 1. Scale mapping. + if(cur_sig >= 61 && cur_sig <= 100) + { + ret_sig = 90 + ((cur_sig - 60) / 4); + } + else if(cur_sig >= 41 && cur_sig <= 60) + { + ret_sig = 78 + ((cur_sig - 40) / 2); + } + else if(cur_sig >= 31 && cur_sig <= 40) + { + ret_sig = 66 + (cur_sig - 30); + } + else if(cur_sig >= 21 && cur_sig <= 30) + { + ret_sig = 54 + (cur_sig - 20); + } + else if(cur_sig >= 5 && cur_sig <= 20) + { + ret_sig = 42 + (((cur_sig - 5) * 2) / 3); + } + else if(cur_sig == 4) + { + ret_sig = 36; + } + else if(cur_sig == 3) + { + ret_sig = 27; + } + else if(cur_sig == 2) + { + ret_sig = 18; + } + else if(cur_sig == 1) + { + ret_sig = 9; + } + else + { + ret_sig = cur_sig; + } + } +#endif + + return ret_sig; +} + + +static s32 translate2dbm(u8 signal_strength_idx) +{ + s32 signal_power; // in dBm. + + + // Translate to dBm (x=0.5y-95). + signal_power = (s32)((signal_strength_idx + 1) >> 1); + signal_power -= 95; + + return signal_power; +} + +static void query_rx_phy_status(union recv_frame *prframe, struct phy_stat *pphy_stat) +{ + PHY_STS_OFDM_8192CD_T *pOfdm_buf; + PHY_STS_CCK_8192CD_T *pCck_buf; + u8 i, max_spatial_stream, evm; + s8 rx_pwr[4], rx_pwr_all = 0; + u8 pwdb_all; + u32 rssi,total_rssi=0; + u8 bcck_rate=0, rf_rx_num = 0, cck_highpwr = 0; + _adapter *padapter = prframe->u.hdr.adapter; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 tmp_rxsnr; + s8 rx_snrX; + +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + PHY_RX_DRIVER_INFO_8192CD *pDrvInfo = ((PHY_RX_DRIVER_INFO_8192CD *)pphy_stat); + u8 bant1_sel = (pDrvInfo->ANTSEL == 1)?_TRUE:_FALSE; +#endif + + // Record it for next packet processing + bcck_rate=(pattrib->mcs_rate<=3? 1:0); + + if(bcck_rate) //CCK + { + u8 report; +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + if(bant1_sel == _TRUE) + pHalData->CCK_Ant1_Cnt++; + else + pHalData->CCK_Ant2_Cnt++; +#endif + + // CCK Driver info Structure is not the same as OFDM packet. + pCck_buf = (PHY_STS_CCK_8192CD_T *)pphy_stat; + //Adapter->RxStats.NumQryPhyStatusCCK++; + + // + // (1)Hardware does not provide RSSI for CCK + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) + // + + if(padapter->pwrctrlpriv.rf_pwrstate == rf_on) + cck_highpwr = (u8)pHalData->bCckHighPower; + else + cck_highpwr = _FALSE; + + if(!cck_highpwr) + { + report = pCck_buf->cck_agc_rpt&0xc0; + report = report>>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) - (pCck_buf->cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = (-26) - (pCck_buf->cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = (-12) - (pCck_buf->cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = (16) - (pCck_buf->cck_agc_rpt & 0x3e); + break; + } + } + else + { + report = pCck_buf->cck_agc_rpt & 0x60; + report = report>>5; + switch(report) + { + case 0x3: + rx_pwr_all = (-46) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x2: + rx_pwr_all = (-26)- ((pCck_buf->cck_agc_rpt & 0x1f)<<1); + break; + case 0x1: + rx_pwr_all = (-12) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + case 0x0: + rx_pwr_all = (16) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ; + break; + } + } + + pwdb_all= query_rx_pwr_percentage(rx_pwr_all); + if(pHalData->CustomerID == RT_CID_819x_Lenovo) + { + // CCK gain is smaller than OFDM/MCS gain, + // so we add gain diff by experiences, the val is 6 + pwdb_all+=6; + if(pwdb_all > 100) + pwdb_all = 100; + // modify the offset to make the same gain index with OFDM. + if(pwdb_all > 34 && pwdb_all <= 42) + pwdb_all -= 2; + else if(pwdb_all > 26 && pwdb_all <= 34) + pwdb_all -= 6; + else if(pwdb_all > 14 && pwdb_all <= 26) + pwdb_all -= 8; + else if(pwdb_all > 4 && pwdb_all <= 14) + pwdb_all -= 4; + } + + pattrib->RxPWDBAll = pwdb_all; //for DIG/rate adaptive + pattrib->RecvSignalPower = rx_pwr_all; //dBM + padapter->recvpriv.rxpwdb = rx_pwr_all; + // + // (3) Get Signal Quality (EVM) + // + //if(bPacketMatchBSSID) + { + u8 sq; + + if(pHalData->CustomerID == RT_CID_819x_Lenovo) + { + // mapping to 5 bars for vista signal strength + // signal quality in driver will be displayed to signal strength + // in vista. + 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 = 20; + } + else + { + if(pwdb_all> 40) + { + sq = 100; + } + else + { + sq = pCck_buf->SQ_rpt; + + if(pCck_buf->SQ_rpt > 64) + sq = 0; + else if (pCck_buf->SQ_rpt < 20) + sq= 100; + else + sq = ((64-sq) * 100) / 44; + + } + } + + pattrib->signal_qual=sq; + pattrib->rx_mimo_signal_qual[0]=sq; + pattrib->rx_mimo_signal_qual[1]=(-1); + } + + } + else //OFDM/HT + { +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + if(bant1_sel == _TRUE) + pHalData->OFDM_Ant1_Cnt++; + else + pHalData->OFDM_Ant2_Cnt++; +#endif + pdmpriv->OFDM_Pkt_Cnt++; + + pOfdm_buf = (PHY_STS_OFDM_8192CD_T *)pphy_stat; + + // + // (1)Get RSSI per-path + // + for(i=0; iNumTotalRFPath; i++) + { + // 2008/01/30 MH we will judge RF RX path now. + if (pHalData->bRFPathRxEnable[i]) + rf_rx_num++; + //else + //continue; + + rx_pwr[i] = ((pOfdm_buf->trsw_gain_X[i]&0x3F)*2) - 110; + padapter->recvpriv.RxRssi[i] = rx_pwr[i]; + /* Translate DBM to percentage. */ + pattrib->rx_rssi[i] = rssi = query_rx_pwr_percentage(rx_pwr[i]); + total_rssi += rssi; + + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], rssi)); + + //Get Rx snr value in DB + tmp_rxsnr = pOfdm_buf->rxsnr_X[i]; + rx_snrX = (s8)(tmp_rxsnr); + rx_snrX >>= 1; + padapter->recvpriv.RxSNRdB[i] = (int)rx_snrX; + pattrib->rx_snr[i]=pOfdm_buf->rxsnr_X[i]; + /* Record Signal Strength for next packet */ + //if(bPacketMatchBSSID) + { + //pRfd->Status.RxMIMOSignalStrength[i] =(u1Byte) RSSI; + + //The following is for lenovo signal strength in vista + if(pHalData->CustomerID == RT_CID_819x_Lenovo) + { + u8 sq; + + if(i == 0) + { + // mapping to 5 bars for vista signal strength + // signal quality in driver will be displayed to signal strength + // in vista. + if(rssi >= 50) + sq = 100; + else if(rssi >= 35 && rssi < 50) + sq = 80; + else if(rssi >= 22 && rssi < 35) + sq = 60; + else if(rssi >= 18 && rssi < 22) + sq = 40; + else + sq = 20; + //DbgPrint("ofdm/mcs RSSI=%d\n", RSSI); + //pRfd->Status.SignalQuality = SQ; + //DbgPrint("ofdm/mcs SQ = %d\n", pRfd->Status.SignalQuality); + } + } + } + } + + + // + // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive),average + // + rx_pwr_all = (((pOfdm_buf->pwdb_all ) >> 1 )& 0x7f) -110;//for OFDM Average RSSI + pwdb_all = query_rx_pwr_percentage(rx_pwr_all); + + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("PWDB_ALL=%d\n", pwdb_all)); + + pattrib->RxPWDBAll = pwdb_all; //for DIG/rate adaptive + pattrib->RecvSignalPower = rx_pwr_all;//dBM + padapter->recvpriv.rxpwdb = rx_pwr_all; + // + // (3)EVM of HT rate + // + if(pHalData->CustomerID != RT_CID_819x_Lenovo) + { + if(pattrib->rxht && pattrib->mcs_rate >=20 && pattrib->mcs_rate<=27) + 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 = evm_db2percentage( (pOfdm_buf->rxevm_X[i]/*/ 2*/));//dbm + + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("RXRATE=%x RXEVM=%x EVM=%s%d\n", + pattrib->mcs_rate, pOfdm_buf->rxevm_X[i], "%",evm)); + + //if(bPacketMatchBSSID) + { + if(i==0) // Fill value in RFD, Get the first spatial stream only + { + pattrib->signal_qual = (u8)(evm & 0xff); + } + pattrib->rx_mimo_signal_qual[i] = (u8)(evm & 0xff); + } + } + + } + + // + // 4. Record rx statistics for debug + // + + } + + + //UI BSS List signal strength(in percentage), make it good looking, from 0~100. + //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). + if(bcck_rate) + { + pattrib->signal_strength=(u8)signal_scale_mapping(padapter, pwdb_all); + } + else + { + if (rf_rx_num != 0) + { + pattrib->signal_strength= (u8)(signal_scale_mapping(padapter, total_rssi/=rf_rx_num)); + } + } + //DBG_8192C("%s,rx_pwr_all(%d),RxPWDBAll(%d)\n",__FUNCTION__,rx_pwr_all,pattrib->RxPWDBAll); + +} + + +static void process_rssi(_adapter *padapter,union recv_frame *prframe) +{ + u32 last_rssi, tmp_val; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + struct signal_stat * signal_stat = &padapter->recvpriv.signal_strength_data; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //DBG_8192C("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength); + //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) + { + + #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + if(signal_stat->update_req) { + signal_stat->total_num = 0; + signal_stat->total_val = 0; + signal_stat->update_req = 0; + } + + signal_stat->total_num++; + signal_stat->total_val += pattrib->signal_strength; + signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; + #else //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //Adapter->RxStats.RssiCalculateCnt++; //For antenna Test + if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX) + { + padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index]; + padapter->recvpriv.signal_strength_data.total_val -= last_rssi; + } + padapter->recvpriv.signal_strength_data.total_val +=pattrib->signal_strength; + + padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->signal_strength; + if(padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX) + padapter->recvpriv.signal_strength_data.index = 0; + + + tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num; + + if(padapter->recvpriv.is_signal_dbg) { + padapter->recvpriv.signal_strength= padapter->recvpriv.signal_strength_dbg; + padapter->recvpriv.rssi=(s8)translate2dbm((u8)padapter->recvpriv.signal_strength_dbg); + } else { + padapter->recvpriv.signal_strength= tmp_val; + padapter->recvpriv.rssi=(s8)translate2dbm((u8)tmp_val); + } + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("UI RSSI = %d, ui_rssi.TotalVal = %d, ui_rssi.TotalNum = %d\n", tmp_val, padapter->recvpriv.signal_strength_data.total_val,padapter->recvpriv.signal_strength_data.total_num)); + #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + } + +}// Process_UI_RSSI_8192C + + +static void process_PWDB(_adapter *padapter, union recv_frame *prframe) +{ + int UndecoratedSmoothedPWDB; + int UndecoratedSmoothedCCK; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct rx_pkt_attrib *pattrib= &prframe->u.hdr.attrib; + struct sta_info *psta = prframe->u.hdr.psta; + u8 isCCKrate=(pattrib->mcs_rate<=3? 1:0); + + + if(psta) + { + UndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + UndecoratedSmoothedCCK = psta->rssi_stat.UndecoratedSmoothedCCK; + } + else + { + UndecoratedSmoothedPWDB = pdmpriv->UndecoratedSmoothedPWDB; + UndecoratedSmoothedCCK = pdmpriv->UndecoratedSmoothedCCK; + } + + //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) + + if(!isCCKrate) + { + // Process OFDM RSSI + if(UndecoratedSmoothedPWDB < 0) // initialize + { + UndecoratedSmoothedPWDB = pattrib->RxPWDBAll; + } + + if(pattrib->RxPWDBAll > (u32)UndecoratedSmoothedPWDB) + { + UndecoratedSmoothedPWDB = + ( ((UndecoratedSmoothedPWDB)*(Rx_Smooth_Factor-1)) + + (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor); + + UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB + 1; + } + else + { + UndecoratedSmoothedPWDB = + ( ((UndecoratedSmoothedPWDB)*(Rx_Smooth_Factor-1)) + + (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor); + } + } + else + { + // Process CCK RSSI + if(UndecoratedSmoothedCCK < 0) // initialize + { + UndecoratedSmoothedCCK = pattrib->RxPWDBAll; + } + + if(pattrib->RxPWDBAll > (u32)UndecoratedSmoothedCCK) + { + UndecoratedSmoothedCCK = + ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + + (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor); + + UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1; + } + else + { + UndecoratedSmoothedCCK = + ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + + (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor); + } + } + + + if(psta) + { + //psta->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;//todo: + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + + if(pdmpriv->RSSI_Select == RSSI_OFDM){ + psta->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + } + else if(pdmpriv->RSSI_Select == RSSI_CCK){ + psta->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK; + } + else{ + if(UndecoratedSmoothedPWDB <0 ) + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK; + else + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + } + psta->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; + } + else + { + //pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + + if(pdmpriv->RSSI_Select == RSSI_OFDM){ + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + } + else if(pdmpriv->RSSI_Select == RSSI_CCK){ + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK; + } + else { + if(UndecoratedSmoothedPWDB <0 ) + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK; + else + pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; + + } + pdmpriv->UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; + } + + //UpdateRxSignalStatistics8192C(padapter, prframe); + +} + + +static void process_link_qual(_adapter *padapter,union recv_frame *prframe) +{ + u32 last_evm=0, tmpVal; + struct rx_pkt_attrib *pattrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + struct signal_stat * signal_stat; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + if(prframe == NULL || padapter==NULL){ + return; + } + + pattrib = &prframe->u.hdr.attrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + signal_stat = &padapter->recvpriv.signal_qual_data; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual); + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + if(signal_stat->update_req) { + signal_stat->total_num = 0; + signal_stat->total_val = 0; + signal_stat->update_req = 0; + } + + signal_stat->total_num++; + signal_stat->total_val += pattrib->signal_qual; + signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; + +#else //CONFIG_NEW_SIGNAL_STAT_PROCESS + if(pattrib->signal_qual != 0) + { + // + // 1. Record the general EVM to the sliding window. + // + if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) + { + padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index]; + padapter->recvpriv.signal_qual_data.total_val -= last_evm; + } + padapter->recvpriv.signal_qual_data.total_val += pattrib->signal_qual; + + padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->signal_qual; + if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX) + padapter->recvpriv.signal_qual_data.index = 0; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, pattrib->signal_qual)); + + // <1> Showed on UI for user, in percentage. + tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num; + padapter->recvpriv.signal_qual=(u8)tmpVal; + + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->signal_qual)); + } +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +}// Process_UiLinkQuality8192S + + +static void process_phy_info(_adapter *padapter, union recv_frame *prframe) +{ + union recv_frame *precvframe = (union recv_frame *)prframe; + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + // If we switch to the antenna for testing, the signal strength + // of the packets in this time shall not be counted into total receiving power. + // This prevents error counting Rx signal strength and affecting other dynamic mechanism. + + // Select the packets to do RSSI checking for antenna switching. + SwAntDivRSSICheck8192C(padapter, precvframe->u.hdr.attrib.RxPWDBAll); + + if(GET_HAL_DATA(padapter)->RSSI_test == _TRUE) + return; +#endif + // + // Check RSSI + // + process_rssi(padapter, precvframe); + // + // Check PWDB. + // + process_PWDB(padapter, precvframe); + // + // Check EVM + // + process_link_qual(padapter, precvframe); + +} + + +void rtl8192c_translate_rx_signal_stuff(union recv_frame *precvframe, struct phy_stat *pphy_info) +{ + struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + _adapter *padapter = precvframe->u.hdr.adapter; + u8 bPacketMatchBSSID =_FALSE; + u8 bPacketToSelf = _FALSE; + u8 bPacketBeacon = _FALSE; + + if((pattrib->physt) && (pphy_info != NULL)) + { + bPacketMatchBSSID = ((!IsFrameTypeCtrl(precvframe->u.hdr.rx_data)) && !(pattrib->icv_err) && !(pattrib->crc_err) && + _rtw_memcmp(get_hdr_bssid(precvframe->u.hdr.rx_data), get_my_bssid(&padapter->mlmeextpriv.mlmext_info.network), ETH_ALEN)); + + + bPacketToSelf = bPacketMatchBSSID && (_rtw_memcmp(get_da(precvframe->u.hdr.rx_data), myid(&padapter->eeprompriv), ETH_ALEN)); + + bPacketBeacon =bPacketMatchBSSID && (GetFrameSubType(precvframe->u.hdr.rx_data) == WIFI_BEACON); + + query_rx_phy_status(precvframe, pphy_info); + + precvframe->u.hdr.psta = NULL; + if(bPacketMatchBSSID && check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) + { + u8 *sa; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + sa = get_sa(precvframe->u.hdr.rx_data); + + psta = rtw_get_stainfo(pstapriv, sa); + if(psta) + { + precvframe->u.hdr.psta = psta; + process_phy_info(padapter, precvframe); + } + } + else if(bPacketToSelf || bPacketBeacon) + { + if(check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + u8 *sa; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + sa = get_sa(precvframe->u.hdr.rx_data); + + psta = rtw_get_stainfo(pstapriv, sa); + if(psta) + { + precvframe->u.hdr.psta = psta; + } + } + + process_phy_info(padapter, precvframe); + } + } +} + +void rtl8192c_query_rx_desc_status(union recv_frame *precvframe, struct recv_stat *pdesc) +{ + struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + + //Offset 0 + pattrib->physt = (u8)((le32_to_cpu(pdesc->rxdw0) >> 26) & 0x1); + pattrib->pkt_len = (u16)(le32_to_cpu(pdesc->rxdw0)&0x00003fff); + pattrib->drvinfo_sz = (u8)((le32_to_cpu(pdesc->rxdw0) >> 16) & 0xf) * 8;//uint 2^3 = 8 bytes + + pattrib->shift_sz = (u8)((le32_to_cpu(pdesc->rxdw0) >> 24) & 0x3); + + pattrib->crc_err = (u8)((le32_to_cpu(pdesc->rxdw0) >> 14) & 0x1); + pattrib->icv_err = (u8)((le32_to_cpu(pdesc->rxdw0) >> 15) & 0x1); + pattrib->qos = (u8)(( le32_to_cpu( pdesc->rxdw0 ) >> 23) & 0x1);// Qos data, wireless lan header length is 26 + pattrib->bdecrypted = (le32_to_cpu(pdesc->rxdw0) & BIT(27))? 0:1; + + //Offset 4 + pattrib->mfrag = (u8)((le32_to_cpu(pdesc->rxdw1) >> 27) & 0x1);//more fragment bit + + //Offset 8 + pattrib->frag_num = (u8)((le32_to_cpu(pdesc->rxdw2) >> 12) & 0xf);//fragmentation number + + //Offset 12 +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + if ( le32_to_cpu(pdesc->rxdw3) & BIT(13)){ + pattrib->tcpchk_valid = 1; // valid + if ( le32_to_cpu(pdesc->rxdw3) & BIT(11) ) { + pattrib->tcp_chkrpt = 1; // correct + //DBG_8192C("tcp csum ok\n"); + } + else + pattrib->tcp_chkrpt = 0; // incorrect + + if ( le32_to_cpu(pdesc->rxdw3) & BIT(12) ) + pattrib->ip_chkrpt = 1; // correct + else + pattrib->ip_chkrpt = 0; // incorrect + } + else { + pattrib->tcpchk_valid = 0; // invalid + } +#endif + + pattrib->mcs_rate=(u8)((le32_to_cpu(pdesc->rxdw3))&0x3f); + pattrib->rxht=(u8)((le32_to_cpu(pdesc->rxdw3) >>6)&0x1); + pattrib->sgi=(u8)((le32_to_cpu(pdesc->rxdw3) >>8)&0x1); + //Offset 16 + //Offset 20 + +} + + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c new file mode 100755 index 00000000..1368d66a --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * 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 +#ifdef DBG_CONFIG_ERROR_DETECT +void rtl8192c_sreset_xmit_status_check(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + unsigned long current_time; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + unsigned int diff_time; + u32 txdma_status; + if( (txdma_status=rtw_read32(padapter, REG_TXDMA_STATUS)) !=0x00){ + DBG_871X("%s REG_TXDMA_STATUS:0x%08x\n", __FUNCTION__, txdma_status); + rtw_hal_sreset_reset(padapter); + } + + //total xmit irp = 4 + //DBG_8192C("==>%s free_xmitbuf_cnt(%d),txirp_cnt(%d)\n",__FUNCTION__,pxmitpriv->free_xmitbuf_cnt,pxmitpriv->txirp_cnt); + //if(pxmitpriv->txirp_cnt == NR_XMITBUFF+1) + current_time = rtw_get_current_time(); + + if(0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) { + + diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_time); + + if (diff_time > 2000) { + if (psrtpriv->last_tx_complete_time == 0) { + psrtpriv->last_tx_complete_time = current_time; + } + else{ + diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time); + if (diff_time > 4000) { + //padapter->Wifi_Error_Status = WIFI_TX_HANG; + DBG_871X("%s tx hang\n", __FUNCTION__); + rtw_hal_sreset_reset(padapter); + } + } + } + } + + if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) { + psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; + rtw_hal_sreset_reset(padapter); + return; + } +} +void rtl8192c_sreset_linked_status_check(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + u32 regc50,regc58,reg824,reg800; + regc50 = rtw_read32(padapter,0xc50); + regc58 = rtw_read32(padapter,0xc58); + reg824 = rtw_read32(padapter,0x824); + reg800 = rtw_read32(padapter,0x800); + if( ((regc50&0xFFFFFF00)!= 0x69543400)|| + ((regc58&0xFFFFFF00)!= 0x69543400)|| + (((reg824&0xFFFFFF00)!= 0x00390000)&&(((reg824&0xFFFFFF00)!= 0x80390000)))|| + ( ((reg800&0xFFFFFF00)!= 0x03040000)&&((reg800&0xFFFFFF00)!= 0x83040000))) + { + DBG_8192C("%s regc50:0x%08x, regc58:0x%08x, reg824:0x%08x, reg800:0x%08x,\n", __FUNCTION__, + regc50, regc58, reg824, reg800); + rtw_hal_sreset_reset(padapter); + } + + if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) { + psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; + rtw_hal_sreset_reset(padapter); + return; + } +} +#endif + diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c new file mode 100755 index 00000000..092700c3 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8192C_XMIT_C_ + +#include +#include +#include +#include + +#ifdef CONFIG_XMIT_ACK +void dump_txrpt_ccx_8192c(void *buf) +{ + struct txrpt_ccx_8192c *txrpt_ccx = buf; + + DBG_871X("%s:\n" + "retry_cnt:%u, rsvd_0:%u, rts_retry_cnt:%u, rsvd_1:%u\n" + "ccx_qtime:%u, missed_pkt_num:%u, rsvd_4:%u\n" + "mac_id:%u, des1_fragssn:%u\n" + "rpt_pkt_num:%u, pkt_drop:%u, lifetime_over:%u, retry_over:%u\n" + "edca_tx_queue:%u, rsvd_7:%u, bmc:%u, pkt_ok:%u, init_ccx:%u\n" + , __func__ + , txrpt_ccx->retry_cnt, txrpt_ccx->rsvd_0, txrpt_ccx->rts_retry_cnt, txrpt_ccx->rsvd_1 + , txrpt_ccx_qtime_8192c(txrpt_ccx), txrpt_ccx->missed_pkt_num, txrpt_ccx->rsvd_4 + , txrpt_ccx->mac_id, txrpt_ccx->des1_fragssn + , txrpt_ccx->rpt_pkt_num, txrpt_ccx->pkt_drop, txrpt_ccx->lifetime_over, txrpt_ccx->retry_over + , txrpt_ccx->edca_tx_queue, txrpt_ccx->rsvd_7, txrpt_ccx->bmc, txrpt_ccx->pkt_ok, txrpt_ccx->int_ccx + ); +} + +void handle_txrpt_ccx_8192c(_adapter *adapter, void *buf) +{ + struct txrpt_ccx_8192c *txrpt_ccx = buf; + + #ifdef DBG_CCX + dump_txrpt_ccx_8192c(buf); + #endif + + if (txrpt_ccx->int_ccx) { + if (txrpt_ccx->pkt_ok) + rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS); + else + rtw_ack_tx_done(&adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); + } +} +#endif //CONFIG_XMIT_ACK + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c b/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c new file mode 100755 index 00000000..b49486b4 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c @@ -0,0 +1,8758 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + +/*Created on 2011/ 6/15, 5:45*/ + +#include +#include "Hal8192CUHWImg.h" + +#ifdef CONFIG_BT_COEXISTENCE +// =================== v84 TSMC COMMON 2012-04-13 ======================= +u8 Rtl8192CUFwTSMCImgArray[TSMCImgArrayLength] = { +0xc1,0x88,0x02,0x00,0x54,0x00,0x01,0x00,0x04,0x13,0x11,0x07,0x3a,0x3d,0x00,0x00, +0x58,0x97,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x50,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x57,0x91,0x00,0x00,0x00,0x00,0x00,0xa1,0xe8,0x00,0x00,0x00, +0x05,0x04,0x03,0x02,0x00,0x03,0x06,0x05,0x04,0x03,0x00,0x04,0x06,0x05,0x04,0x02, +0x00,0x04,0x08,0x07,0x06,0x04,0x00,0x06,0x0a,0x09,0x08,0x06,0x00,0x08,0x0a,0x09, +0x08,0x04,0x00,0x08,0x0a,0x09,0x08,0x02,0x00,0x08,0x0a,0x09,0x08,0x00,0x00,0x08, +0x12,0x11,0x10,0x08,0x00,0x10,0x1a,0x19,0x18,0x10,0x00,0x18,0x22,0x21,0x20,0x18, +0x00,0x20,0x22,0x21,0x20,0x10,0x00,0x20,0x22,0x21,0x20,0x08,0x00,0x20,0x22,0x21, +0x1c,0x08,0x00,0x20,0x22,0x21,0x14,0x08,0x00,0x20,0x22,0x20,0x18,0x08,0x00,0x20, +0x31,0x30,0x20,0x10,0x00,0x30,0x31,0x30,0x18,0x00,0x00,0x30,0x31,0x2f,0x10,0x10, +0x00,0x30,0x31,0x2c,0x10,0x10,0x00,0x30,0x31,0x28,0x10,0x00,0x00,0x30,0x31,0x20, +0x10,0x00,0x00,0x30,0x31,0x10,0x10,0x00,0x00,0x30,0x04,0x04,0x04,0x05,0x04,0x04, +0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04, +0x05,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x07,0x0a,0x0b, +0x0d,0x10,0x04,0x05,0x05,0x06,0x06,0x09,0x0c,0x11,0x08,0x08,0x09,0x09,0x0a,0x0c, +0x10,0x11,0x04,0x04,0x04,0x05,0x04,0x04,0x05,0x07,0x07,0x07,0x08,0x0a,0x04,0x04, +0x04,0x04,0x06,0x0a,0x0b,0x0d,0x05,0x05,0x07,0x07,0x08,0x0b,0x0d,0x0f,0x04,0x04, +0x04,0x05,0x07,0x07,0x09,0x09,0x0c,0x0e,0x10,0x12,0x04,0x04,0x05,0x05,0x06,0x0a, +0x11,0x13,0x09,0x09,0x09,0x09,0x0c,0x0e,0x11,0x13,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x24,0x26,0x2a,0x18,0x1a,0x1d,0x1f,0x21,0x27,0x29,0x2a,0x00,0x00, +0x00,0x1f,0x23,0x28,0x2a,0x2c,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x18, +0x00,0x24,0x00,0x30,0x00,0x48,0x00,0x60,0x00,0x90,0x00,0xc0,0x00,0xd8,0x00,0x50, +0x00,0x78,0x00,0xa0,0x00,0xc8,0x01,0x40,0x01,0x90,0x01,0xe0,0x02,0x30,0x01,0x2c, +0x01,0x40,0x01,0xe0,0x02,0xd0,0x03,0xe8,0x04,0xb0,0x06,0x40,0x07,0xd0,0x00,0x02, +0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x0c,0x00,0x12,0x00,0x18,0x00,0x24,0x00,0x30, +0x00,0x48,0x00,0x60,0x00,0x6c,0x00,0x28,0x00,0x3c,0x00,0x50,0x00,0x64,0x00,0xa0, +0x00,0xc8,0x00,0xf0,0x01,0x18,0x00,0x64,0x00,0xa0,0x00,0xf0,0x01,0x68,0x01,0xf4, +0x02,0x58,0x03,0x20,0x03,0xe8,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x04,0x04, +0x05,0x07,0x04,0x04,0x07,0x0a,0x0a,0x0c,0x0c,0x12,0x05,0x07,0x07,0x08,0x0b,0x12, +0x24,0x3c,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02, +0x03,0x04,0x05,0x06,0x07,0x08,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x20,0x1e, +0x1c,0x18,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a,0x83,0xe0,0xf5, +0xf0,0xa3,0xe0,0x22,0x50,0x06,0x87,0xf0,0x09,0xe7,0x19,0x22,0xbb,0xfe,0x07,0xe3, +0xf5,0xf0,0x09,0xe3,0x19,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0xf5,0xf0,0x74,0x01, +0x93,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0, +0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22, +0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a, +0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a, +0x83,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x06,0xf7,0x09,0xa7,0xf0,0x19,0x22,0xbb, +0xfe,0x06,0xf3,0xe5,0xf0,0x09,0xf3,0x19,0x22,0xf8,0xbb,0x01,0x11,0xe5,0x82,0x29, +0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x09, +0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb,0xfe,0x09,0xe9,0x25,0x82,0xc8, +0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee,0x4a,0xfe,0xed,0x49,0xfd,0xec, +0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xa4, +0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83,0x22,0xe0,0xfb,0xa3,0xe0,0xfa, +0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0,0xf9,0x25,0xf0,0xf0,0xe5,0x82, +0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0, +0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93, +0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74, +0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf,0x02,0x43,0xf8,0x02,0x48,0x29, +0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2,0x08,0xdf,0xf4, +0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33,0xc4,0x54,0x0f, +0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf,0xe4,0x80,0x0b, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x3d,0xe4,0x7e,0x01,0x93,0x60, +0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x9e,0x77, +0x00,0x41,0x9e,0xae,0x00,0x41,0x9e,0x54,0x80,0x41,0x9e,0xb0,0x00,0x00,0xf0,0x90, +0x9e,0x5d,0xe0,0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x54,0x7e,0x01,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x85,0xe0,0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5, +0x45,0x12,0x35,0xab,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01, +0x3c,0x74,0x08,0xf0,0xe4,0x90,0x9e,0x85,0xf0,0x90,0x9e,0x5b,0xe0,0x90,0x9e,0x86, +0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x5e,0x90,0x01,0x5f,0x74,0x05,0xf0, +0x90,0x06,0x92,0x74,0x02,0xf0,0x90,0x9e,0x63,0x14,0xf0,0xe5,0x61,0x54,0x0f,0xc3, +0x94,0x0c,0x50,0x03,0x12,0x54,0xe3,0x22,0x8f,0x82,0x8e,0x83,0xa3,0xa3,0xa3,0xe4, +0xf0,0x22,0xe4,0xf5,0x65,0x7f,0x60,0x7e,0x01,0x80,0xed,0x7d,0x01,0xaf,0x62,0x02, +0x54,0xe7,0xb1,0xb0,0xbf,0x01,0x12,0x90,0x9e,0x79,0xe0,0xff,0xe4,0xfd,0xf1,0x79, +0x12,0x5f,0xf7,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0xb1,0xb0,0xbf,0x01,0x0f,0x90, +0x02,0x09,0xe0,0xff,0x7d,0x01,0xf1,0x79,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x22, +0x22,0x22,0x00,0x02,0x45,0x03,0x02,0x45,0x06,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x8b,0x20,0x8a,0x21,0x89,0x22,0x90,0x9e,0x87,0x71,0x8b,0xab,0x23,0xaa,0x24,0xa9, +0x25,0x90,0x9e,0x8a,0x71,0x8b,0xaf,0x26,0x15,0x26,0xef,0x60,0x1b,0x90,0x9e,0x8a, +0xe4,0x75,0xf0,0x01,0x71,0x74,0x12,0x29,0xd9,0xff,0x90,0x9e,0x87,0xe4,0x75,0xf0, +0x01,0x71,0x74,0xef,0x51,0x4d,0x80,0xde,0xab,0x20,0xaa,0x21,0xa9,0x22,0xd0,0xd0, +0x92,0xaf,0x22,0x90,0x9e,0x11,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0x90,0x06,0xa9, +0xe0,0x90,0x9e,0x10,0xf0,0xe0,0x54,0xc0,0x70,0x08,0x53,0x64,0xfe,0x53,0x64,0xfd, +0x91,0xcb,0x90,0x9e,0x10,0xe0,0x30,0xe6,0x13,0x43,0x64,0x01,0x90,0x9e,0x66,0xe0, +0x64,0x02,0x60,0x04,0x91,0xd2,0x80,0x07,0x91,0x79,0x80,0x03,0x53,0x64,0xfe,0x90, +0x9e,0x10,0xe0,0x30,0xe7,0x16,0x43,0x64,0x02,0xe4,0x90,0x9e,0x85,0x91,0x4e,0x90, +0x01,0x57,0x74,0x05,0xf0,0x90,0x9e,0x67,0x74,0x01,0xf0,0x22,0x53,0x64,0xfd,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x01,0xc4,0x74,0xb0,0xf0,0x74,0x45,0xa3, +0xf0,0x90,0x04,0x1d,0xe0,0x60,0x1a,0x90,0x05,0x22,0xe0,0x54,0x90,0x60,0x07,0x90, +0x01,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7,0xe0,0x30,0xe1,0xe4,0x7f,0x00,0x80, +0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,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,0x75,0x13,0x00,0x90,0x01,0xc4,0x74,0xe8,0xf0,0x74,0x45, +0xa3,0xf0,0x53,0x91,0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5,0x34,0xa3,0xe0,0x55, +0x31,0xf5,0x35,0xa3,0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55,0x33,0xf5,0x37,0xe5, +0x34,0x30,0xe0,0x06,0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34,0x30,0xe1,0x09,0x90, +0x01,0x3c,0x74,0x02,0xf0,0x12,0x61,0xc9,0xe5,0x34,0x30,0xe2,0x38,0x90,0x01,0x3c, +0x74,0x04,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe0,0x24,0x90,0x9e,0x85,0xe4,0xf0,0x90, +0x9e,0x5b,0xe0,0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x91,0x5e, +0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80,0x07,0x90,0x9e, +0x64,0xe4,0xf0,0x91,0xcb,0xe5,0x34,0x30,0xe3,0x38,0x90,0x01,0x3c,0x74,0x08,0xf0, +0x90,0x06,0x92,0xe0,0x30,0xe1,0x24,0x90,0x9e,0x85,0xe4,0xf0,0x90,0x9e,0x5b,0xe0, +0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x5e,0x90,0x01,0x5f, +0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x07,0x90,0x9e,0x63,0xe4,0xf0, +0x91,0xcb,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10,0xf0,0x12,0x4b,0xfb, +0xe5,0x34,0x30,0xe5,0x09,0x90,0x01,0x3c,0x74,0x20,0xf0,0x12,0x4c,0x3d,0xe5,0x35, +0x30,0xe0,0x44,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f,0xe0,0x44,0x7f,0xf0, +0x90,0x00,0x83,0xe0,0x54,0x0f,0xf5,0x13,0xb4,0x01,0x02,0x80,0x1c,0xe5,0x13,0xb4, +0x02,0x05,0x90,0x00,0x83,0x80,0x12,0xe5,0x13,0xb4,0x04,0x05,0x90,0x00,0x83,0x80, +0x08,0xe5,0x13,0xb4,0x0c,0x06,0x90,0x00,0x83,0xe0,0xf5,0x62,0x90,0x01,0xbb,0xe5, +0x62,0xf0,0x12,0x60,0xc0,0x91,0xcb,0xe5,0x35,0x30,0xe2,0x06,0x90,0x01,0x3d,0x74, +0x04,0xf0,0xe5,0x35,0x30,0xe4,0x06,0x90,0x01,0x3d,0x74,0x10,0xf0,0xe5,0x36,0x30, +0xe0,0x06,0x90,0x01,0x3e,0x74,0x01,0xf0,0xe5,0x36,0x30,0xe1,0x06,0x90,0x01,0x3e, +0x74,0x02,0xf0,0x74,0xe8,0x04,0x90,0x01,0xc4,0xf0,0x74,0x45,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,0x9e,0x98,0xef,0xf0,0xa3,0xed, +0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5,0x63,0x60,0x05,0xe4,0xff,0x12,0x54,0x97,0x90, +0x9e,0x98,0xe0,0x30,0xe0,0x09,0x90,0x9e,0x9a,0xe4,0xf0,0xa3,0x74,0x80,0xf0,0x90, +0x9e,0x98,0xe0,0xff,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x90,0x04,0x25,0xef,0xf0,0x90, +0x9e,0x99,0xe0,0x60,0x1f,0xa3,0xa3,0xe0,0xff,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xfc, +0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x44,0x80,0xf0,0x90,0x9e,0x9a,0xa3,0xe0,0xff,0xfd,0x24,0x08,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54, +0xf7,0xf0,0x90,0x9e,0x9a,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x75,0x28,0x33,0xe4,0xf5, +0x29,0x75,0x2a,0x07,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3,0xe5,0x29,0xf0, +0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0xe4,0x90,0x9e,0x16,0xf0,0xa3,0xf0, +0x75,0x8e,0x02,0xf1,0xa1,0xf1,0xe9,0x90,0x9e,0x7e,0xef,0xf0,0xf1,0xdd,0x90,0x9e, +0x80,0xef,0xf0,0xf1,0xf6,0x90,0x9e,0x75,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xf5,0x57, +0x12,0x6e,0x77,0xf1,0xd4,0x12,0x60,0x4b,0x12,0x32,0x3d,0xf1,0xc9,0x11,0x0b,0x12, +0x50,0x0e,0xf1,0xcd,0xf1,0xb1,0x12,0x44,0xff,0xf1,0x45,0x90,0x9e,0x18,0xe5,0xd9, +0xf0,0x11,0xd0,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44,0x40,0xf0,0xb1,0x45,0x75,0xe8, +0x03,0x43,0xa8,0x85,0xd2,0xaf,0x90,0x9e,0x16,0xe0,0x64,0x01,0xf0,0x24,0x29,0x90, +0x01,0xc4,0xf0,0x74,0x48,0xa3,0xf0,0xe5,0x57,0x30,0xe4,0x0a,0xc2,0xaf,0x53,0x57, +0xef,0xd2,0xaf,0x12,0x58,0x74,0xe5,0x57,0x30,0xe6,0x17,0xc2,0xaf,0x53,0x57,0xbf, +0xd2,0xaf,0x12,0x67,0xa1,0x90,0x9e,0x43,0xe0,0xff,0x60,0x03,0xb4,0x01,0x03,0x12, +0x7b,0x5c,0x90,0x9e,0x43,0xe0,0x70,0x03,0x12,0x7c,0x5f,0x12,0x73,0x85,0x80,0xb6, +0x90,0x01,0x3c,0x74,0xff,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01,0x34,0xf0,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x54,0x31,0x05,0x7d,0xff,0x7f,0x55,0x31,0x05,0x7d, +0xff,0x7f,0x56,0x31,0x05,0x7d,0xff,0x7f,0x57,0x80,0x0a,0xf0,0x90,0x00,0x45,0xe0, +0x54,0xfe,0xfd,0x7f,0x45,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x8f,0x82,0x75,0x83, +0x00,0xed,0xf0,0xb1,0x45,0xd0,0xd0,0x92,0xaf,0x22,0xef,0x14,0x60,0x30,0x14,0x60, +0x66,0x24,0x02,0x60,0x02,0x21,0xc1,0x90,0x9e,0x3f,0x74,0x02,0xf0,0x90,0x00,0x48, +0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x31,0x05,0x90,0x00,0x47,0xe0,0x44,0x08,0xfd,0x7f, +0x47,0x31,0x05,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x80,0x71,0xe4,0x90, +0x9e,0x3f,0xf0,0x90,0x9e,0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x00,0x45,0xe0,0x44,0xef,0xfd,0x7f,0x45,0x31, +0x05,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x46,0xe0, +0x44,0x10,0xfd,0x7f,0x46,0x80,0x38,0x90,0x9e,0x3f,0x74,0x01,0xf0,0x90,0x9e,0x45, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9, +0x90,0x00,0x45,0xe0,0x44,0x20,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x45,0xe0,0x44, +0x10,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x31, +0x05,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x9e,0x41,0xf0,0x90,0x00,0x01,0x12, +0x42,0x20,0x25,0xe0,0x25,0xe0,0x90,0x9e,0x40,0xf0,0x12,0x29,0xd9,0x25,0xe0,0x25, +0xe0,0x90,0x9e,0x44,0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x4f,0xf0,0x90,0x05,0x61, +0xe0,0x90,0x9e,0x50,0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x51,0xf0,0x90,0x05,0x63, +0xe0,0x90,0x9e,0x52,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x90, +0x9e,0x40,0xe0,0xff,0x91,0xf0,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x90,0x9e, +0x41,0xe0,0x70,0x02,0x41,0xc8,0x90,0x9e,0x40,0xe0,0x70,0x02,0x41,0xc8,0x90,0x9e, +0x44,0xe0,0x70,0x02,0x41,0xc8,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf, +0x90,0x9e,0x53,0x74,0x01,0xf0,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x11,0xfc, +0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x31,0x05,0x90,0x9e,0x39,0xe0,0x60, +0x15,0x90,0x9e,0x45,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e, +0x08,0x12,0x2f,0xd9,0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x00,0x45,0xe0, +0x54,0xef,0xfd,0x7f,0x45,0x31,0x05,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x9e, +0x4f,0xe0,0x90,0x05,0x84,0xf0,0x90,0x9e,0x50,0xe0,0x90,0x05,0x85,0xf0,0x90,0x9e, +0x51,0xe0,0x90,0x05,0x86,0xf0,0x90,0x9e,0x52,0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf, +0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x90,0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d, +0x20,0xe4,0xff,0x12,0x37,0x00,0x80,0x2b,0x90,0x9e,0x41,0xe0,0x70,0x2d,0x90,0x9e, +0x53,0x11,0xfb,0x90,0x00,0x46,0xe0,0x54,0xfe,0xfd,0x7f,0x46,0x31,0x05,0x90,0x05, +0x22,0xe4,0xf0,0xa2,0xaf,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff, +0x12,0x36,0x92,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x22,0x8b,0x14,0x8a,0x15, +0x89,0x16,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x9e,0x42,0xf0,0xe0,0x30,0xe0,0x4b, +0x90,0x9e,0x39,0x74,0x01,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0x3b, +0x12,0x2a,0x7f,0xab,0x14,0xaa,0x15,0xa9,0x16,0x90,0x00,0x01,0x12,0x42,0x20,0xff, +0xe4,0xfc,0xfd,0xfe,0x78,0x1a,0x12,0x2a,0x6c,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab, +0x07,0x90,0x9e,0x3b,0x12,0x43,0x53,0xec,0x54,0x03,0xfc,0x12,0x43,0x46,0x90,0x9e, +0x45,0x12,0x2a,0x7f,0x90,0x05,0x22,0xe4,0xf0,0x80,0x2d,0xe4,0x90,0x9e,0x39,0xf0, +0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0xec,0x54,0x03,0xfc,0xec,0x44,0xc0,0xfc,0x90, +0x9e,0x3b,0x12,0x2a,0x7f,0x90,0x9e,0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x42,0xe0,0x30,0xe1,0x19,0x7d, +0x0c,0x7f,0x47,0x31,0x05,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x31,0x05, +0x90,0x00,0x46,0xe0,0x44,0x10,0x80,0x1c,0x90,0x00,0x47,0xe0,0x54,0xf3,0xfd,0x7f, +0x47,0x31,0x05,0x90,0x00,0x48,0xe0,0x54,0xf3,0xfd,0x7f,0x48,0x31,0x05,0x90,0x00, +0x46,0xe0,0x54,0xef,0xfd,0x7f,0x46,0x31,0x05,0xe4,0x90,0x9e,0x3f,0xf0,0x22,0x90, +0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01,0x38,0xf0,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0x31,0x05,0xe4,0xfd,0x7f,0x51,0x31,0x05,0xe4, +0xfd,0x7f,0x52,0x31,0x05,0xe4,0xfd,0x7f,0x53,0x21,0x05,0xe5,0x65,0x64,0x01,0x70, +0x3b,0xd1,0x85,0xbf,0x01,0x04,0x7f,0x01,0xd1,0x79,0x90,0x00,0x46,0xe0,0x44,0x04, +0xfd,0x7f,0x46,0x31,0x05,0x90,0x00,0x44,0xe0,0x54,0xfb,0xfd,0x7f,0x44,0x31,0x05, +0x90,0x00,0x46,0xe0,0x54,0xfb,0xfd,0x7f,0x46,0x31,0x05,0x7f,0x02,0xd1,0xa1,0x8f, +0x69,0x90,0x01,0xc9,0xe5,0x69,0xf0,0xb4,0x01,0x02,0xd1,0x19,0x22,0x90,0x9e,0x41, +0xe0,0x64,0x01,0x60,0x02,0x81,0xef,0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46, +0x31,0x05,0x90,0x9e,0x53,0xe0,0x70,0x31,0x90,0x9e,0x39,0xe0,0x60,0x15,0x90,0x9e, +0x45,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f, +0xd9,0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x9e,0x40,0xe0,0xff,0x91,0xf0, +0x90,0x9e,0x53,0x74,0x01,0x11,0xfb,0x80,0x3f,0x90,0x9e,0x53,0xe0,0x64,0x01,0x70, +0x37,0x90,0x9e,0x44,0xe0,0xff,0x91,0xf0,0xe4,0x90,0x9e,0x53,0xf0,0x90,0x00,0x45, +0xe0,0x44,0x01,0xfd,0x7f,0x45,0x31,0x05,0x90,0x9e,0x39,0xe0,0x60,0x15,0x90,0x9e, +0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f, +0xd9,0x80,0x05,0x90,0x05,0x22,0xe4,0xf0,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90, +0x9e,0x4f,0xe0,0x90,0x05,0x84,0xf0,0x90,0x9e,0x50,0xe0,0x90,0x05,0x85,0xf0,0x90, +0x9e,0x51,0xe0,0x90,0x05,0x86,0xf0,0x90,0x9e,0x52,0xe0,0x90,0x05,0x87,0xf0,0x22, +0x90,0x05,0x60,0xe0,0x90,0x9e,0x4f,0xf0,0x90,0x05,0x61,0xe0,0x90,0x9e,0x50,0xf0, +0x90,0x05,0x62,0xe0,0x90,0x9e,0x51,0xf0,0x90,0x05,0x63,0xe0,0x90,0x9e,0x52,0xf0, +0xc3,0x74,0xff,0x9f,0xfe,0x90,0x9e,0x50,0xe0,0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0, +0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3,0xe0,0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90, +0x9e,0x52,0x80,0x03,0x90,0x9e,0x51,0xe0,0x04,0xf0,0x22,0x90,0x9e,0x50,0xe0,0x2f, +0xf0,0x22,0xe0,0x5f,0xf0,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x7f,0x10,0xdf,0xfe, +0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x2a,0xed, +0xf0,0x90,0x9e,0x29,0xef,0xf0,0xd3,0x94,0x07,0x50,0x4e,0xa3,0xe0,0x70,0x1a,0x90, +0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4, +0xff,0x90,0x00,0x47,0xe0,0x5f,0xf0,0x80,0x17,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0,0x4f,0xf0, +0xb1,0x45,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0x80,0x59,0x90,0x9e,0x29,0xe0,0x24,0xf8,0xf0, +0xa3,0xe0,0x70,0x1d,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x80, +0x1a,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0xb1,0x45,0x90,0x9e,0x29, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90, +0x00,0x43,0xb1,0x42,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x49,0xe0,0x90,0x9e,0xb1, +0xf0,0xe0,0x54,0x0f,0xf0,0x44,0xf0,0xfd,0x7f,0x49,0x31,0x05,0x90,0x9e,0xb1,0xe0, +0x44,0xb0,0xfd,0x7f,0x49,0x21,0x05,0x90,0x9e,0x27,0xee,0xf0,0xa3,0xef,0xf0,0x75, +0x65,0x01,0x8e,0x66,0xf5,0x67,0xe4,0xfd,0x7f,0x0b,0xb1,0x55,0xe4,0xfd,0x7f,0x02, +0xb1,0x55,0xd1,0x85,0xe4,0xff,0xd1,0x79,0xe4,0xf5,0x69,0x90,0x01,0xc9,0xe5,0x69, +0xf0,0x90,0x9e,0x27,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5,0x45, +0x7d,0x01,0x7f,0x60,0x7e,0x01,0x02,0x35,0xab,0x90,0x01,0xca,0xe5,0x68,0xf0,0xef, +0x60,0x02,0xd1,0x19,0x22,0x7f,0x0b,0xd1,0xa1,0xef,0x65,0x68,0x60,0x10,0xe5,0x68, +0xb4,0x01,0x05,0xe4,0xf5,0x68,0x80,0x03,0x75,0x68,0x01,0x7f,0x01,0x22,0x7f,0x00, +0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0xb2,0xef,0xf0,0xd3,0x94,0x07, +0x50,0x43,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4, +0xff,0x90,0x00,0x46,0xb1,0x42,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8, +0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0, +0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13, +0xd8,0xf8,0xff,0x80,0x4b,0x90,0x9e,0xb2,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f, +0xf0,0xb1,0x45,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80, +0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x42,0xe0,0xfb,0xe4,0xfe, +0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff, +0xd0,0xd0,0x92,0xaf,0x22,0xe4,0xfd,0x7f,0x45,0x31,0x05,0x90,0x04,0xfd,0xe4,0xf0, +0xa3,0xf0,0x90,0x9e,0x43,0xf0,0x90,0x9e,0x49,0xf0,0x90,0x9e,0x4c,0xf0,0x90,0x9e, +0x4a,0xf0,0x90,0x9e,0x4d,0xf0,0x90,0x9e,0x4b,0xf0,0x90,0x9e,0x4e,0xf0,0x90,0x9e, +0x35,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x9e,0x3a,0xf0,0x90,0x9e, +0x3f,0xf0,0x90,0x9e,0x41,0xf0,0x90,0x9e,0x53,0xf0,0x90,0x9e,0x44,0xf0,0x90,0x9e, +0x40,0xf0,0x90,0x9e,0x39,0xf0,0x90,0x00,0x51,0xe0,0x44,0xc0,0xfd,0x7f,0x51,0x21, +0x05,0xe4,0x90,0x9e,0x7d,0xf0,0x90,0x00,0x80,0xe0,0x44,0x80,0xfd,0x7f,0x80,0x21, +0x05,0x75,0x30,0x1f,0x75,0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0, +0xa3,0xe5,0x31,0xf0,0xa3,0xe5,0x32,0xf0,0x22,0xe4,0xf5,0x68,0x22,0x90,0x01,0x64, +0x74,0xa0,0xf0,0x22,0x90,0x9e,0x80,0xe0,0x90,0x9e,0x0f,0xf0,0x22,0x90,0x00,0xf3, +0xe0,0x7f,0x00,0x30,0xe3,0x02,0x7f,0x01,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x7f, +0x01,0x60,0x02,0x7f,0x00,0x22,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x0c,0x90,0x00,0xf2, +0xe0,0x30,0xe7,0x05,0x7e,0xfd,0x7f,0x33,0x22,0x7e,0xfd,0x7f,0x2f,0x22,0x90,0x00, +0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41,0x74,0x10,0xf0,0x90,0x05,0x5a,0xf0,0xa3, +0xe4,0xf0,0x22,0x90,0x01,0x02,0xe0,0x54,0x03,0xff,0xe0,0x54,0x0c,0x13,0x13,0x54, +0x3f,0xfe,0xef,0x64,0x01,0x60,0x04,0xef,0xb4,0x03,0x10,0x90,0x9e,0x10,0x74,0x01, +0xf0,0xa3,0x74,0x37,0xf0,0xa3,0x74,0x01,0xf0,0x80,0x1a,0xee,0x64,0x01,0x60,0x07, +0xaf,0x06,0xee,0x64,0x03,0x70,0x49,0x90,0x9e,0x10,0x74,0x01,0xf0,0xa3,0x74,0x3d, +0xf0,0xa3,0x74,0x40,0xf0,0x90,0x9e,0x10,0xe0,0xfe,0xa3,0xe0,0xff,0xf5,0x82,0x8e, +0x83,0xe0,0xfd,0x90,0x9e,0x12,0xe0,0xfc,0xed,0x5c,0x60,0x0c,0x8f,0x82,0x8e,0x83, +0xec,0xf0,0xe4,0x90,0x9e,0x77,0xf0,0x22,0x90,0x9e,0x77,0xe0,0x04,0xf0,0xe0,0xc3, +0x94,0x0a,0x40,0x0c,0xe4,0xf0,0x90,0x04,0x19,0xe0,0x30,0xe0,0x03,0x12,0x44,0xea, +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,0xa1,0xf0,0x74,0x50,0xa3,0xf0,0x90,0x01,0x34,0xe0,0x55,0x28,0xf5,0x2c, +0xa3,0xe0,0x55,0x29,0xf5,0x2d,0xa3,0xe0,0x55,0x2a,0xf5,0x2e,0xa3,0xe0,0x55,0x2b, +0xf5,0x2f,0xe5,0x2c,0x20,0xe0,0x02,0x41,0x46,0x90,0x01,0x34,0x74,0x01,0xf0,0x85, +0xd1,0x4d,0x85,0xd2,0x4e,0x85,0xd3,0x4f,0x85,0xd4,0x50,0x85,0xd5,0x51,0x85,0xd6, +0x52,0x85,0xd7,0x53,0x85,0xd9,0x54,0xe5,0x54,0x54,0x40,0xc3,0x13,0xff,0xe5,0x53, +0x54,0x20,0x6f,0x70,0x02,0x21,0xf5,0xe5,0x54,0x30,0xe5,0x02,0x21,0xf5,0xe5,0x52, +0x54,0x3f,0xf5,0x08,0xe5,0x4d,0x54,0x3f,0xf5,0x09,0xe5,0x51,0x54,0x1f,0xff,0xe5, +0x08,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12, +0x42,0x81,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4, +0x34,0x93,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x09,0xd3,0x94,0x04,0x40, +0x03,0x75,0x09,0x04,0x75,0xf0,0x0a,0xe5,0x08,0x90,0x90,0x00,0x12,0x43,0x5f,0x75, +0xf0,0x02,0xe5,0x09,0x12,0x43,0x5f,0xe0,0xfe,0xa3,0xe0,0xff,0xe5,0x53,0x54,0x1f, +0x2f,0xff,0xe4,0x3e,0xfe,0x75,0xf0,0x0a,0xe5,0x08,0x90,0x90,0x00,0x12,0x43,0x5f, +0x75,0xf0,0x02,0xe5,0x09,0x12,0x43,0x5f,0xee,0xf0,0xa3,0xef,0xf0,0xe5,0x54,0x20, +0xe6,0x24,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4, +0x34,0x98,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x4f,0x30,0xe7,0x36,0xaf, +0x08,0x12,0x63,0x51,0x80,0x2f,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24, +0x44,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x4f, +0x30,0xe7,0x12,0xe5,0x4f,0x54,0x7f,0xfd,0xe5,0x53,0x54,0x1f,0xf5,0x0d,0xab,0x09, +0xaf,0x08,0x12,0x62,0xee,0xe5,0x63,0x14,0x24,0xfd,0x50,0x02,0x80,0x48,0x90,0x9e, +0x66,0xe0,0x60,0x3a,0x90,0x01,0x5b,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0,0x71, +0xc3,0xef,0x64,0x01,0x70,0x30,0x90,0x9e,0x85,0xf0,0x90,0x9e,0x5b,0xe0,0x90,0x9e, +0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44,0x5e,0x90,0x01,0x5b,0x74, +0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x90,0x9e,0x64,0xf0,0x80,0x08,0x71,0xc3, +0xbf,0x01,0x03,0x12,0x44,0xcb,0xe5,0x2c,0x30,0xe1,0x20,0x90,0x01,0x34,0x74,0x02, +0xf0,0x85,0xd1,0x58,0x85,0xd2,0x59,0x85,0xd3,0x5a,0x85,0xd4,0x5b,0x85,0xd5,0x5c, +0x85,0xd6,0x5d,0x85,0xd7,0x5e,0x85,0xd9,0x5f,0x71,0xd2,0xe5,0x2c,0x30,0xe3,0x06, +0x90,0x01,0x34,0x74,0x08,0xf0,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01,0x34,0x74,0x10, +0xf0,0x43,0x57,0x10,0xe5,0x2c,0x30,0xe5,0x26,0x90,0x01,0xcf,0xe0,0x30,0xe5,0x1f, +0xe0,0x54,0xdf,0xf0,0x90,0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00,0x75,0xe8,0x00, +0x12,0x4b,0xcf,0x90,0x00,0x03,0xe0,0x54,0xfb,0xf0,0x12,0x4d,0x45,0x80,0xfe,0xe5, +0x2c,0x30,0xe6,0x06,0x90,0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe0,0x12,0x90, +0x9e,0x7f,0x74,0x01,0xf0,0x90,0x01,0x36,0xf0,0x12,0x61,0x4e,0x90,0x9e,0x7f,0xe4, +0xf0,0xe5,0x2e,0x30,0xe1,0x0b,0x90,0x01,0x36,0x74,0x02,0xf0,0x43,0x57,0x40,0x11, +0x23,0xe5,0x2e,0x30,0xe2,0x09,0x90,0x01,0x36,0x74,0x04,0xf0,0x12,0x60,0xdf,0xe5, +0x2e,0x30,0xe3,0x28,0x90,0x01,0x36,0x74,0x08,0xf0,0xe5,0x60,0x64,0x01,0x70,0x1c, +0xe5,0x63,0x60,0x18,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90, +0x9e,0x85,0xe4,0x12,0x44,0x4e,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x2e,0x30,0xe4, +0x2b,0x90,0x01,0x36,0x74,0x10,0xf0,0xe5,0x60,0xb4,0x01,0x20,0xe5,0x63,0x60,0x1c, +0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x9e,0x67,0xe4,0xf0, +0x53,0x64,0xfd,0xe5,0x64,0x54,0x07,0x70,0x03,0x12,0x44,0xcb,0xe5,0x2e,0x30,0xe5, +0x1f,0x90,0x01,0x36,0x74,0x20,0xf0,0xe5,0x60,0xb4,0x01,0x14,0xe5,0x63,0x60,0x10, +0x90,0x9e,0x66,0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xd2,0x80,0x03,0x12,0x44,0x79, +0xe5,0x2e,0x30,0xe6,0x1b,0x90,0x01,0x36,0x74,0x40,0xf0,0xe5,0x60,0xb4,0x01,0x10, +0xe5,0x63,0x60,0x0c,0x53,0x64,0xfe,0xe5,0x64,0x54,0x07,0x70,0x03,0x12,0x44,0xcb, +0xe5,0x2f,0x30,0xe1,0x08,0x90,0x01,0x37,0x74,0x02,0xf0,0x91,0x64,0x74,0xa1,0x04, +0x90,0x01,0xc4,0xf0,0x74,0x50,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,0x04,0x1b,0xe0,0x54,0x7f,0x64,0x7f,0x7f,0x01,0x60,0x02,0x7f, +0x00,0x22,0x90,0x9e,0x10,0xe0,0x54,0xf0,0x44,0x03,0xf0,0x54,0x0f,0x44,0x80,0xf0, +0x7b,0x00,0x7a,0x00,0x79,0x58,0x90,0x9e,0x90,0x12,0x43,0x8b,0x0b,0x7a,0x9e,0x79, +0x10,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x8d,0x12,0x43,0x8b,0x90,0x9e, +0xb0,0xe0,0xff,0x04,0xf0,0x90,0x00,0x01,0xef,0x12,0x42,0x5f,0x7f,0xaf,0x7e,0x01, +0x12,0x71,0x7a,0xef,0x60,0x49,0x90,0x9e,0x8d,0x12,0x43,0x6b,0x8b,0x23,0x8a,0x24, +0x89,0x25,0x75,0x26,0x02,0x7b,0x01,0x7a,0x01,0x79,0xa0,0x12,0x45,0x09,0x90,0x9e, +0x90,0x12,0x43,0x6b,0x8b,0x23,0x8a,0x24,0x89,0x25,0x90,0x9e,0x8d,0x12,0x43,0x6b, +0x12,0x29,0xd9,0xff,0xc4,0x54,0x0f,0xf5,0x26,0x7b,0x01,0x7a,0x01,0x79,0xa2,0x12, +0x45,0x09,0x90,0x01,0xaf,0x74,0xff,0xf0,0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0, +0xd0,0x92,0xaf,0x22,0x90,0x9e,0xa0,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x63, +0x14,0x24,0xfd,0x50,0x02,0x80,0x1f,0x90,0x9e,0x66,0xe0,0x60,0x06,0x7d,0x01,0x7f, +0x0c,0x80,0x0d,0xe5,0x61,0x54,0x0f,0xc3,0x94,0x04,0x50,0x06,0x7d,0x01,0x7f,0x04, +0x91,0xe7,0xe4,0xff,0x91,0x97,0x22,0xef,0x60,0x0b,0x90,0x9e,0x80,0xe0,0xb4,0x01, +0x10,0xe4,0xff,0x80,0x09,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x75, +0xa5,0x22,0x90,0x01,0x37,0x74,0x02,0xf0,0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x74, +0x12,0xef,0x70,0x06,0x90,0x01,0xc8,0x74,0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x36, +0xe6,0xe5,0x63,0x60,0x04,0x7f,0x01,0x91,0x97,0x12,0x74,0xd2,0x53,0x61,0xf0,0x43, +0x61,0x02,0x22,0x7d,0x01,0x7f,0x0c,0x8f,0x6a,0x8d,0x6b,0xe5,0x6a,0x54,0x0f,0xff, +0xe5,0x61,0x54,0x0f,0x6f,0x60,0x65,0xe5,0x6a,0x30,0xe2,0x28,0xe5,0x61,0x20,0xe2, +0x04,0x7f,0x01,0xd1,0xc2,0xe5,0x61,0x30,0xe3,0x0c,0xe5,0x6a,0x20,0xe3,0x07,0xb1, +0x5d,0xef,0x60,0x48,0xa1,0xa5,0xe5,0x61,0x20,0xe3,0x41,0xe5,0x6a,0x30,0xe3,0x3c, +0xaf,0x6b,0xc1,0xdc,0xe5,0x61,0x54,0x0f,0xff,0xbf,0x0c,0x0c,0xe5,0x6a,0x20,0xe3, +0x07,0xb1,0x5d,0xef,0x60,0x26,0xb1,0xa5,0xe5,0x61,0x54,0x0f,0xff,0xbf,0x04,0x0c, +0xe5,0x6a,0x20,0xe2,0x07,0xf1,0x21,0xef,0x60,0x12,0x91,0xb2,0xe5,0x61,0x54,0x0f, +0xff,0xbf,0x02,0x08,0x12,0x60,0xbd,0xef,0x60,0x02,0xd1,0xaf,0x22,0x71,0xc3,0xef, +0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x30,0x90,0x9e,0x64,0xe0, +0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x22,0x90,0x9e,0x63,0xe0,0x60,0x08, +0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x14,0xe5,0x62,0x54,0x0f,0xd3,0x94,0x04,0x40, +0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74, +0x08,0xf0,0x7f,0x00,0x22,0x90,0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x60,0xb4,0x01, +0x04,0x7f,0x01,0xd1,0xf6,0x53,0x61,0xf0,0x43,0x61,0x04,0x22,0xef,0x64,0x01,0x70, +0x2e,0x7d,0x78,0x7f,0x02,0x12,0x36,0x75,0x7d,0x02,0x7f,0x03,0x12,0x36,0x75,0x90, +0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x91,0xe3,0xe4,0xff,0x91,0x97, +0x90,0x06,0x04,0xe0,0x54,0x7f,0xf0,0x90,0x06,0x0a,0xe0,0x54,0xf8,0xf0,0x22,0x90, +0x01,0x36,0x74,0x7b,0xf0,0xa3,0x74,0x02,0xf0,0x7d,0x7b,0xff,0x12,0x36,0xe6,0x7d, +0x02,0x7f,0x03,0x12,0x36,0xe6,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a, +0xe0,0x44,0x07,0xf0,0x12,0x62,0x4c,0xe5,0x60,0x20,0xe0,0x05,0xe4,0x90,0x9e,0x58, +0xf0,0x22,0x8b,0x14,0x8a,0x15,0x89,0x16,0x12,0x60,0xb1,0xab,0x14,0xaa,0x15,0xa9, +0x16,0x12,0x29,0xd9,0xf5,0x63,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24, +0x03,0x70,0x40,0x7f,0x01,0x80,0x3a,0xab,0x14,0xaa,0x15,0xa9,0x16,0x90,0x00,0x02, +0x12,0x42,0x20,0xfd,0xe4,0xff,0xd1,0x84,0x80,0x27,0xab,0x14,0xaa,0x15,0xa9,0x16, +0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x01,0xd1,0x84,0x1f,0x80,0x13,0xab,0x14, +0xaa,0x15,0xa9,0x16,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0xd1,0x84,0xe4, +0xff,0xb1,0xbc,0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x9e,0x65,0x74, +0x01,0xf0,0x80,0x16,0xed,0x70,0x0a,0x90,0x9e,0x62,0xe0,0x90,0x9e,0x65,0xf0,0x80, +0x05,0x90,0x9e,0x65,0xed,0xf0,0x90,0x9e,0x65,0xe0,0x90,0x9e,0x56,0xf0,0x22,0x53, +0x61,0xf0,0x43,0x61,0x01,0x12,0x45,0x00,0x12,0x45,0x01,0x53,0x61,0xf0,0x43,0x61, +0x02,0x22,0x90,0x9e,0xaf,0xef,0xf0,0x12,0x74,0x53,0x90,0x9e,0xaf,0xe0,0x60,0x05, +0x90,0x05,0x22,0xe4,0xf0,0x53,0x61,0xf0,0x43,0x61,0x04,0x22,0x90,0x06,0x04,0xe0, +0x54,0xbf,0xf0,0xef,0x60,0x09,0xe5,0x60,0xb4,0x01,0x04,0xe4,0xff,0xd1,0xf6,0x53, +0x61,0xf0,0x43,0x61,0x0c,0x22,0x8f,0x27,0x12,0x45,0xb0,0xbf,0x01,0x22,0x90,0x9e, +0x7a,0xe0,0xff,0x7d,0x01,0x12,0x47,0x79,0xab,0x07,0xaa,0x06,0xad,0x03,0xac,0x02, +0xaf,0x27,0x12,0x60,0x2a,0xaf,0x03,0x12,0x5f,0xf7,0x90,0x04,0x1f,0x74,0x20,0xf0, +0x22,0x71,0xc3,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x58, +0xe5,0x64,0x54,0x03,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4a,0xe5,0x62, +0x54,0x0f,0xd3,0x94,0x02,0x40,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x39,0xe5, +0x64,0x30,0xe2,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x2c,0xe5,0x64,0x30,0xe4, +0x08,0x90,0x01,0xb9,0x74,0x10,0xf0,0x80,0x1f,0x90,0x9e,0x58,0xe0,0x60,0x08,0x90, +0x01,0xb9,0x74,0x20,0xf0,0x80,0x11,0x90,0x9e,0x5e,0xe0,0x60,0x08,0x90,0x01,0xb9, +0x74,0x80,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0,0x7f,0x00, +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,0x91,0xf0,0x74,0x57,0xa3,0xf0,0x53,0x91,0xef,0x90,0x00,0x51,0xe0,0xff, +0x90,0x00,0x55,0xe0,0x5f,0xf5,0x3d,0x90,0x00,0x52,0xe0,0xff,0x90,0x00,0x56,0xe0, +0x5f,0xf5,0x3e,0xe5,0x3d,0x30,0xe4,0x06,0x90,0x00,0x55,0x74,0x10,0xf0,0xe5,0x3d, +0x30,0xe5,0x06,0x90,0x00,0x55,0x74,0x20,0xf0,0xe5,0x3d,0x30,0xe6,0x1b,0x90,0x00, +0x55,0x74,0x40,0xf0,0x90,0x9e,0x42,0xe0,0x54,0x03,0xff,0xbf,0x03,0x0b,0x90,0x9e, +0x3f,0xe0,0x60,0x05,0x7f,0x01,0x12,0x49,0x1a,0xe5,0x3d,0x30,0xe7,0x15,0x90,0x00, +0x55,0x74,0x80,0xf0,0x90,0x9e,0x42,0xe0,0x54,0x03,0xff,0xbf,0x03,0x05,0x7f,0x02, +0x12,0x49,0x1a,0xe5,0x3e,0x30,0xe0,0x06,0x90,0x00,0x56,0x74,0x01,0xf0,0xe5,0x3e, +0x30,0xe1,0x06,0x90,0x00,0x56,0x74,0x02,0xf0,0xe5,0x3e,0x30,0xe2,0x06,0x90,0x00, +0x56,0x74,0x04,0xf0,0xe5,0x3e,0x30,0xe3,0x06,0x90,0x00,0x56,0x74,0x08,0xf0,0x90, +0x01,0xc4,0x74,0x91,0xf0,0x74,0x57,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,0x01,0xcc,0xe0,0x54,0x0f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0x19,0xe0,0xfd,0x70,0x02,0x21,0xb5,0x90,0x9e,0xae,0xe0,0xff,0x74,0x01,0x7e,0x00, +0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70, +0x02,0x21,0xae,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x5f, +0xe0,0x90,0x9e,0x1a,0xf0,0x75,0x23,0x01,0x75,0x24,0x9e,0x75,0x25,0x1a,0x75,0x26, +0x01,0x7b,0x01,0x7a,0x9e,0x79,0x1b,0x12,0x45,0x09,0x90,0x9e,0x1b,0xe0,0xff,0xc4, +0x13,0x13,0x13,0x54,0x01,0x90,0x9e,0xae,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90, +0x00,0x88,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1c,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0, +0x02,0x90,0x00,0x89,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1d,0xf0,0x90,0x9e,0xae,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1e,0xf0,0x90,0x9e, +0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1f,0xf0, +0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x5f,0xe0,0x90,0x9e, +0x20,0xf0,0x80,0x33,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x5f,0xe0,0x90, +0x9e,0x1c,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x5f, +0xe0,0x90,0x9e,0x1d,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12, +0x43,0x5f,0xe0,0x90,0x9e,0x1e,0xf0,0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x9e,0x79, +0x1c,0x31,0xb6,0x90,0x9e,0x19,0xe0,0xff,0x90,0x9e,0xae,0xe0,0xfe,0x74,0x01,0xa8, +0x06,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0x5f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0xae,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01, +0xcc,0xf0,0x90,0x9e,0xae,0xe0,0x04,0xf0,0xe0,0x54,0x03,0xf0,0x01,0x7e,0x90,0x01, +0xc6,0xe0,0x44,0x02,0xf0,0x22,0x90,0x9e,0x21,0x12,0x43,0x8b,0xef,0x12,0x43,0x94, +0x59,0xfc,0x01,0x59,0xf4,0x02,0x5a,0x20,0x03,0x5a,0x29,0x05,0x5a,0x32,0x06,0x5a, +0x7e,0x07,0x5a,0x3a,0x09,0x5a,0x43,0x0b,0x5a,0x4c,0x0c,0x5a,0x55,0x0d,0x5a,0x5e, +0x0e,0x5a,0x67,0x1b,0x5a,0x6f,0x1c,0x5a,0x05,0x2d,0x5a,0x0e,0x2e,0x5a,0x17,0x3b, +0x00,0x00,0x5a,0x77,0x90,0x9e,0x21,0x12,0x43,0x6b,0xe1,0xe9,0x90,0x9e,0x21,0x12, +0x43,0x6b,0x02,0x71,0xd0,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0x0b,0x90,0x9e, +0x21,0x12,0x43,0x6b,0x02,0x72,0x53,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0x8c, +0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0xb6,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02, +0x70,0x4a,0x90,0x9e,0x21,0x12,0x43,0x6b,0x80,0x45,0x90,0x9e,0x21,0x12,0x43,0x6b, +0x02,0x72,0xfe,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x70,0xa2,0x90,0x9e,0x21,0x12, +0x43,0x6b,0x02,0x49,0xc2,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x7b,0x29,0x90,0x9e, +0x21,0x12,0x43,0x6b,0x02,0x4a,0xfc,0x90,0x9e,0x21,0x12,0x43,0x6b,0xe1,0xef,0x90, +0x9e,0x21,0x12,0x43,0x6b,0xe1,0xd1,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22,0x90, +0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x1f,0xfe,0xef,0x54,0x20,0xc4,0x13,0x54,0x07, +0xfd,0xaf,0x06,0x90,0x9e,0x24,0xef,0xf0,0xa3,0xed,0xf0,0xa3,0x12,0x43,0x8b,0x90, +0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0xf0,0xc4,0x54,0x0f, +0x90,0x9e,0x29,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0x54,0x40,0xc4,0x13,0x13,0x54, +0x03,0x90,0x9e,0x2a,0xf0,0x90,0x9e,0x24,0xe0,0xff,0x75,0xf0,0x09,0x90,0x96,0x46, +0x12,0x43,0x5f,0xad,0x82,0xac,0x83,0x90,0x9e,0x2b,0xec,0xf0,0xa3,0xed,0xf0,0xef, +0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74,0x96,0x35,0xf0,0xfa,0x7b,0x01,0xa3,0x12, +0x43,0x8b,0x90,0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0x0f, +0xff,0x90,0x9e,0x2d,0x12,0x43,0x6b,0xef,0x12,0x42,0x4d,0x90,0x9e,0x26,0x12,0x43, +0x6b,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x90,0x9e,0x2d,0x12,0x43,0x6b,0x90,0x00, +0x01,0xef,0x12,0x42,0x5f,0x90,0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42, +0x20,0xff,0x90,0x9e,0x2b,0xe0,0xfc,0xa3,0xe0,0xfd,0xf5,0x82,0x8c,0x83,0xef,0xf0, +0x12,0x29,0xd9,0x8d,0x82,0x8c,0x83,0xa3,0xf0,0x90,0x9e,0x29,0xe0,0xfe,0x90,0x9e, +0x24,0xe0,0xff,0x24,0x82,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0x90,0x9e, +0x25,0xe0,0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4a,0x12,0x43,0x5f,0xee,0xf0,0x75, +0xf0,0x09,0xef,0x90,0x96,0x4b,0x12,0x43,0x5f,0x74,0x01,0xf0,0x90,0x9e,0x2a,0xe0, +0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4c,0x12,0x43,0x5f,0xee,0xf0,0x8f,0x14,0xef, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xaf,0x82,0xf5,0x16,0x8f,0x17,0xe5, +0x14,0x75,0xf0,0x02,0xa4,0x24,0x02,0xf9,0x74,0x95,0x35,0xf0,0x75,0x18,0x01,0xf5, +0x19,0x89,0x1a,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x46,0x12,0x43,0x5f,0xaf,0x82, +0x85,0x83,0x1b,0x8f,0x1c,0xe5,0x14,0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74,0x96, +0x35,0xf0,0x75,0x1d,0x01,0xf5,0x1e,0x89,0x1f,0x74,0x82,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xe0,0x12,0x43,0x94,0x5c,0x0d,0x00,0x5c,0x22,0x01,0x5c,0x37, +0x02,0x5c,0x4c,0x03,0x5c,0x75,0x04,0x5c,0x8a,0x05,0x5c,0x9f,0x06,0x5c,0xc5,0x0c, +0x5c,0xf2,0x0d,0x5d,0x1f,0x0e,0x5d,0x4c,0x0f,0x00,0x00,0x5d,0x80,0xe5,0x14,0x25, +0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74,0x15, +0x80,0x3c,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74, +0xf0,0xf0,0xa3,0x74,0x10,0x80,0x27,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4, +0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74,0x05,0x80,0x12,0xe5,0x14,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0xe4,0xf0,0xe5, +0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0x74,0x0f,0xf0,0xa3, +0x74,0x8f,0xf0,0xa1,0x80,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf5,0x80,0x27,0xe5,0x14,0x25,0xe0,0x24,0xc6, +0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf0,0x80,0x12,0xe5, +0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3,0x74, +0x0d,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe4, +0xf0,0xa3,0xf0,0xa1,0x80,0x90,0x04,0x47,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12, +0x42,0x4d,0x90,0x04,0x46,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12, +0x42,0x5f,0x90,0x04,0x45,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x44, +0xa1,0x77,0x90,0x04,0x4b,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90, +0x04,0x4a,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90, +0x04,0x49,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x48,0x80,0x58,0x90, +0x04,0x4f,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90,0x04,0x4e,0xe0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x4d,0xe0, +0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x4c,0x80,0x2b,0x90,0x04,0x53,0xe0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90,0x04,0x52,0xe0,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x51,0xe0,0x85,0x17,0x82, +0x85,0x16,0x83,0xf0,0x90,0x04,0x50,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xa3,0xf0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0xc0,0x03,0xc0,0x02,0xc0,0x01,0x12,0x29,0xd9,0xff, +0xab,0x1d,0xaa,0x1e,0xa9,0x1f,0x12,0x29,0xd9,0x5f,0xd0,0x01,0xd0,0x02,0xd0,0x03, +0x12,0x42,0x4d,0xab,0x18,0xe5,0x1a,0x24,0x01,0xf9,0xe4,0x35,0x19,0xfa,0xc0,0x03, +0xc0,0x02,0xc0,0x01,0x12,0x29,0xd9,0xff,0xab,0x1d,0xaa,0x1e,0xa9,0x1f,0x90,0x00, +0x01,0x12,0x42,0x20,0x5f,0xd0,0x01,0xd0,0x02,0xd0,0x03,0x12,0x42,0x4d,0x85,0x17, +0x82,0x85,0x16,0x83,0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x1c,0x82,0x85,0x1b,0x83, +0xe0,0xfe,0xef,0x5e,0xd0,0x82,0xd0,0x83,0xf0,0x85,0x17,0x82,0x85,0x16,0x83,0xa3, +0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x1c,0x82,0x85,0x1b,0x83,0xa3,0xe0,0xfe,0xef, +0x5e,0xd0,0x82,0xd0,0x83,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34, +0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b,0x75,0x15,0x0b,0x74,0x01,0x7e, +0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5,0x14, +0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x60,0x06,0xe5,0x15,0x24,0x10,0x80,0x5d,0x15,0x15,0xe5,0x15,0xc3,0x94, +0x00,0x50,0xca,0x80,0x56,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3d,0x75,0x15,0x0f,0x74,0x01,0x7e,0x00, +0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5,0x14,0x25, +0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f, +0x4e,0x60,0x08,0x90,0x9e,0x30,0xe5,0x15,0xf0,0x80,0x10,0x15,0x15,0xe5,0x15,0xc3, +0x94,0x00,0x50,0xc8,0x80,0x05,0xe4,0x90,0x9e,0x30,0xf0,0xe5,0x14,0x25,0xe0,0x24, +0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b,0xe4, +0xf5,0x15,0x74,0x01,0x7e,0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce, +0xd8,0xf9,0xff,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83, +0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x08,0x90,0x9e,0x31,0xe5,0x15,0xf0,0x80, +0x5b,0x05,0x15,0xe5,0x15,0xb4,0x10,0xca,0x80,0x52,0xe5,0x14,0x25,0xe0,0x24,0x02, +0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x39,0xe4,0xf5, +0x15,0x74,0x01,0x7e,0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8, +0xf9,0xff,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0, +0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x06,0xe5,0x15,0x24,0x10,0x80,0x0a,0x05,0x15, +0xe5,0x15,0xb4,0x0c,0xcc,0x80,0x05,0xe4,0x90,0x9e,0x31,0xf0,0x90,0x9e,0x30,0xe0, +0xff,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x48,0x12,0x43,0x5f,0xef,0xf0,0x90,0x9e, +0x31,0xe0,0xfe,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x49,0x12,0x43,0x5f,0xee,0xf0, +0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0xd3,0x9f,0x40,0x06, +0x90,0x9e,0x30,0x12,0x62,0x94,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x04,0xf5, +0x83,0xe0,0xff,0x90,0x9e,0x31,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x03,0x12,0x62,0x94, +0x90,0x9e,0x30,0xe0,0xff,0xd3,0x94,0x13,0x40,0x07,0x90,0x96,0x43,0x74,0x03,0xf0, +0x22,0xef,0xd3,0x94,0x0b,0x40,0x07,0x90,0x96,0x43,0x74,0x02,0xf0,0x22,0xef,0xd3, +0x94,0x03,0x40,0x07,0x90,0x96,0x43,0x74,0x01,0xf0,0x22,0xe4,0x90,0x96,0x43,0xf0, +0x22,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x3f,0xfe,0xef,0x54,0x80,0xc4,0x13, +0x13,0x13,0x54,0x01,0xfd,0xaf,0x06,0x41,0x93,0x12,0x29,0xd9,0xf5,0x60,0x22,0x12, +0x29,0xd9,0x90,0x95,0x01,0xf0,0x22,0xad,0x07,0x74,0x11,0x2d,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xe0,0x44,0x01,0xf0,0x90,0x04,0x80,0xe0,0x54,0x0f,0xfc,0x74,0x14, +0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xc0,0x4c,0xfd,0x74,0x14,0x2f, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0x22,0xef,0x60,0x0f,0x74,0x21,0x2d, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x22,0x74,0x21,0x2d,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x22,0xe4,0xf5,0x60,0xf5,0x64, +0xf5,0x63,0x75,0x62,0x0c,0x75,0x61,0x0c,0x90,0x9e,0x66,0xf0,0x90,0x9e,0x64,0xf0, +0x90,0x9e,0x63,0xf0,0x90,0x9e,0x65,0x04,0xf0,0x90,0x9e,0x56,0xf0,0xe4,0x90,0x9e, +0x67,0xf0,0x90,0x9e,0x58,0xf0,0x90,0x9e,0x61,0x74,0x07,0xf0,0xe4,0x90,0x9e,0x57, +0xf0,0x90,0x9e,0x5f,0xf0,0xa3,0x74,0x03,0xf0,0x90,0x9e,0x5c,0x74,0x0a,0xf0,0xa3, +0x74,0x05,0xf0,0x90,0x9e,0x5b,0x74,0x14,0xf0,0x90,0x9e,0x62,0x74,0x05,0xf0,0xe4, +0x90,0x9e,0x5a,0xf0,0x90,0x9e,0x55,0xf0,0x90,0x9e,0x7f,0xf0,0x90,0x9e,0x5e,0xf0, +0x22,0xe4,0x90,0x9e,0x67,0xf0,0x90,0x9e,0x57,0xf0,0xf5,0x64,0x22,0x7f,0x00,0x22, +0xe5,0x62,0x30,0xe6,0x19,0xe5,0x62,0x54,0x0f,0xff,0x90,0x9e,0x54,0xe0,0xfe,0x4f, +0x90,0x01,0x2f,0xf0,0xee,0x64,0x80,0x90,0x9e,0x54,0xf0,0x53,0x62,0xbf,0x22,0xe5, +0x60,0x64,0x01,0x70,0x68,0xe5,0x63,0x60,0x64,0xe5,0x63,0x64,0x02,0x60,0x06,0xe5, +0x63,0x64,0x05,0x70,0x27,0x90,0x06,0xab,0xe0,0x90,0x9e,0x56,0xf0,0x90,0x06,0xaa, +0xe0,0x90,0x9e,0x65,0xf0,0x90,0x9e,0x56,0xe0,0x70,0x07,0x90,0x9e,0x65,0xe0,0xff, +0x80,0x05,0x90,0x9e,0x56,0xe0,0xff,0x90,0x9e,0x56,0xef,0xf0,0x90,0x9e,0x58,0xe0, +0x60,0x03,0xe0,0x14,0xf0,0xe4,0x90,0x9e,0x57,0xf0,0x90,0x05,0x58,0x74,0x03,0xf0, +0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x53,0x64,0xfd,0x53,0x64, +0xef,0xe5,0x63,0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0x53,0x22,0xe4,0xfb, +0x90,0x9e,0x9c,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x63,0x60,0x6a,0xe5,0x60, +0x64,0x01,0x70,0x64,0xe5,0x63,0x14,0x60,0x2b,0x24,0xfd,0x60,0x27,0x24,0x02,0x24, +0xfb,0x50,0x02,0x80,0x21,0x90,0x9e,0x56,0xe0,0x14,0xf0,0xe0,0x60,0x04,0xa3,0xe0, +0x60,0x14,0x90,0x9e,0x56,0xe0,0x70,0x08,0x90,0x9e,0x65,0xe0,0x90,0x9e,0x56,0xf0, +0x7b,0x01,0x80,0x02,0x7b,0x01,0xeb,0x60,0x2f,0x43,0x64,0x10,0xe4,0x90,0x9e,0x85, +0xf0,0x90,0x9e,0x57,0xe0,0x75,0xf0,0x03,0xa4,0xff,0x90,0x9e,0x61,0xe0,0x2f,0x12, +0x44,0x53,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x61,0x54,0x0f,0xc3,0x94,0x04,0x50, +0x07,0x7d,0x01,0x7f,0x04,0x12,0x54,0xe7,0x22,0xe4,0x90,0x9e,0x15,0xf0,0xe5,0x63, +0x60,0x79,0x90,0x9e,0x67,0xe0,0x60,0x0d,0xe4,0xf0,0x53,0x64,0xfd,0xe5,0x64,0x54, +0x07,0x70,0x68,0x80,0x63,0x90,0x9e,0x57,0xe0,0x04,0xf0,0x53,0x64,0xef,0x90,0x9e, +0x15,0xe0,0xf9,0xff,0x7e,0x00,0x24,0x01,0xfd,0xee,0x33,0xfc,0x90,0x9e,0x57,0xe0, +0xb5,0x05,0x06,0xe4,0xb5,0x04,0x02,0x80,0x12,0xef,0x24,0x02,0xff,0xe4,0x3e,0xfe, +0x90,0x9e,0x57,0xe0,0xb5,0x07,0x0a,0xe4,0xb5,0x06,0x06,0x90,0x05,0x58,0xe0,0x04, +0xf0,0xe9,0xff,0x90,0x9e,0x5c,0xe0,0x2f,0xff,0xe4,0x33,0xfe,0x90,0x9e,0x57,0xe0, +0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x40,0x0d,0xe5,0x60,0xb4,0x01,0x0b, +0xa3,0xe0,0x70,0x07,0xe0,0x04,0xf0,0x22,0x12,0x44,0xcb,0x22,0x90,0x9e,0x5f,0xe0, +0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e, +0x93,0x12,0x43,0x8b,0x90,0x9e,0x96,0xe0,0x54,0xf0,0x44,0x06,0xff,0xf0,0xed,0x54, +0x0f,0xc4,0x54,0xf0,0xfe,0xef,0x54,0x0f,0x4e,0xf0,0x90,0x9e,0x93,0x12,0x43,0x6b, +0x90,0x9e,0x90,0x12,0x43,0x8b,0x7b,0x01,0x7a,0x9e,0x79,0x96,0x12,0x53,0xf1,0xd0, +0xd0,0x92,0xaf,0x22,0xe0,0xfd,0x74,0x26,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9d,0xf5, +0x83,0xed,0xf0,0xaf,0x14,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xef,0xc3,0x94,0x20, +0x50,0x0e,0x74,0x84,0x2f,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xed,0xf0,0x80,0x29, +0x74,0xa6,0x2f,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xed,0xf0,0x90,0x9e,0x68,0xef, +0xf0,0x24,0xa6,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x90,0x9e,0x69,0xf0,0x7b, +0x01,0x7a,0x9e,0x79,0x68,0x7d,0x02,0x51,0x57,0xd0,0xd0,0x92,0xaf,0x22,0x8f,0x0a, +0x8d,0x0b,0xe5,0x0b,0x54,0x1f,0xf5,0x10,0x74,0x01,0x2f,0xf5,0x82,0xe4,0x34,0x94, +0xf5,0x83,0xe0,0xf5,0x0e,0x90,0x04,0xfd,0xe0,0xb4,0x01,0x05,0x75,0x11,0x03,0x80, +0x03,0x75,0x11,0x01,0xeb,0xc3,0x95,0x11,0x40,0x04,0xaf,0x0a,0x80,0x33,0xe5,0x0e, +0x25,0x0d,0xf5,0x0f,0xe5,0x10,0x90,0x41,0xd6,0x93,0xff,0xe5,0x0f,0xd3,0x9f,0x74, +0x01,0x40,0x11,0x25,0x0a,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe4,0xf0,0xad,0x0b, +0xaf,0x0a,0x41,0xa5,0x25,0x0a,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe5,0x0f,0xf0, +0x22,0xad,0x07,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0,0xff,0x74, +0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xe0,0x54,0x1f,0xf5,0x12,0xd3,0x9f, +0x40,0x02,0x8f,0x12,0xe5,0x12,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xe5,0x12,0x25,0xe0,0x24,0x66,0xf5,0x82, +0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe, +0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee, +0xf0,0xa3,0xef,0xf0,0xaf,0x05,0xad,0x12,0x51,0xa5,0xaf,0x12,0x22,0xac,0x07,0xec, +0xc3,0x94,0x20,0x50,0x0d,0x74,0x84,0x2c,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0, +0x80,0x0b,0x74,0xa6,0x2c,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x7f,0xf5, +0x1f,0xe5,0x1f,0x54,0x1f,0xff,0x90,0x9e,0x25,0xf0,0x75,0xf0,0x09,0xec,0x90,0x96, +0x49,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x27,0xf0,0x75,0xf0,0x09,0xec,0x90,0x96,0x48, +0x12,0x43,0x5f,0xe0,0xfe,0x90,0x9e,0x28,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x29,0xcb,0xf0,0xa3,0xeb, +0xf0,0xec,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfb,0xa3, +0xe0,0x90,0x9e,0x2b,0xcb,0xf0,0xa3,0xeb,0xf0,0xef,0xd3,0x9e,0x40,0x0a,0x90,0x9e, +0x28,0xe0,0x90,0x9e,0x25,0xf0,0xf5,0x1f,0xed,0x70,0x02,0xa1,0x13,0x90,0x9e,0x26, +0xed,0xf0,0xe5,0x1f,0x30,0xe6,0x0a,0x90,0x9e,0x25,0xe0,0xf5,0x1f,0xa3,0xe0,0x14, +0xf0,0x90,0x9e,0x26,0xe0,0x70,0x02,0xa1,0x13,0x90,0x9e,0x25,0xe0,0xff,0xd3,0x94, +0x00,0x50,0x02,0xa1,0x13,0xe4,0x90,0x9e,0x24,0xf0,0xef,0x14,0x90,0x9e,0x23,0xf0, +0x90,0x9e,0x27,0xe0,0xfd,0x90,0x9e,0x23,0xe0,0xff,0xd3,0x9d,0x40,0x6b,0xef,0x94, +0x10,0x40,0x21,0xef,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x2b,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x70,0x27,0x90,0x9e,0x23,0xe0,0xff,0xc3,0x94,0x10,0x50,0x33,0x74,0x01, +0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90, +0x9e,0x29,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x16,0x90,0x9e,0x23,0xe0,0xf5, +0x1f,0xa3,0xe0,0x04,0xf0,0x90,0x9e,0x26,0xe0,0xff,0x90,0x9e,0x24,0xe0,0x6f,0x60, +0x08,0x90,0x9e,0x23,0xe0,0x14,0xf0,0x80,0x87,0x90,0x9e,0x26,0xe0,0xff,0x90,0x9e, +0x24,0xe0,0xc3,0x9f,0x50,0x0d,0x90,0x9e,0x23,0xe0,0xb5,0x05,0x06,0x90,0x9e,0x27, +0xe0,0xf5,0x1f,0xe5,0x1f,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83, +0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xe5,0x1f,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4, +0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef, +0x13,0xff,0xec,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0, +0xa3,0xef,0xf0,0xaf,0x04,0xad,0x1f,0x51,0xa5,0xaf,0x1f,0x22,0xad,0x07,0xed,0xc3, +0x94,0x20,0x50,0x0d,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x80, +0x0b,0x74,0xa6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x7f,0xf5,0x1f, +0xe5,0x1f,0x54,0x1f,0xfc,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0, +0xff,0x90,0x9e,0x23,0xf0,0xed,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5, +0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x24,0xcb,0xf0,0xa3,0xeb,0xf0,0xed,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x26, +0xcb,0xf0,0xa3,0xeb,0xf0,0xec,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfa,0x74,0x01,0x93,0xfb,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xea,0xf0,0xa3,0xeb,0xf0,0xec,0xc3,0x9f,0x40,0x02,0xc1,0x7a, +0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xec,0xf0,0x04,0xfb,0x90,0x9e, +0x23,0xe0,0xff,0xeb,0xd3,0x9f,0x40,0x02,0xc1,0xab,0xeb,0xc3,0x94,0x10,0x40,0x21, +0xeb,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce, +0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x24,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x70, +0x23,0xeb,0xc3,0x94,0x10,0x50,0x40,0x74,0x01,0x7e,0x00,0xa8,0x03,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x26,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x60,0x23,0xbb,0x11,0x09,0x90,0x9e,0x25,0xe0,0x30,0xe7,0x02,0x7b,0x17, +0xeb,0x64,0x13,0x60,0x03,0xbb,0x12,0x09,0x90,0x9e,0x24,0xe0,0x30,0xe0,0x02,0x7b, +0x18,0xac,0x03,0x8c,0x1f,0x80,0x34,0x0b,0x80,0x84,0x90,0x9e,0x23,0xe0,0xfb,0x6c, +0x70,0x69,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xec,0xf0,0x75,0xf0, +0x09,0xed,0x90,0x96,0x4a,0x12,0x43,0x5f,0xe0,0xb4,0x01,0x0c,0xe5,0x1f,0x20,0xe6, +0x07,0xec,0x44,0x40,0xf5,0x1f,0x80,0x03,0xaf,0x1f,0x22,0xec,0x25,0xe0,0x24,0x9e, +0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25, +0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4, +0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x80,0x5b,0xec,0xd3,0x9b,0x40,0x56, +0x90,0x9e,0x23,0xe0,0xff,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef, +0xf0,0xac,0x07,0x8f,0x1f,0xec,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4, +0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef, +0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0, +0xa3,0xef,0xf0,0xaf,0x1f,0x22,0x74,0x01,0x2d,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83, +0xe4,0xf0,0xaf,0x05,0xe5,0x1f,0x44,0x80,0xfd,0x51,0xa5,0xe5,0x1f,0x44,0x80,0xff, +0x22,0xef,0xc3,0x94,0x20,0x50,0x39,0xef,0x30,0xe0,0x17,0xed,0xc4,0x54,0xf0,0xfd, +0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x54,0x0f, +0x80,0x10,0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0, +0x54,0xf0,0xf0,0x74,0xa4,0x2e,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x4d,0xf0, +0x22,0xe4,0xf5,0x14,0xe5,0x14,0xb4,0x20,0x14,0x90,0x9a,0xc5,0xe0,0x04,0xf0,0x90, +0x95,0x01,0xe0,0xff,0x90,0x9a,0xc5,0xe0,0xb5,0x07,0x02,0xe4,0xf0,0x75,0xf0,0x09, +0xe5,0x14,0x90,0x96,0x4b,0x12,0x43,0x5f,0xe0,0x64,0x01,0x60,0x03,0x02,0x6e,0x6a, +0xe5,0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xfe,0xa3, +0xe0,0xd3,0x94,0x00,0xee,0x94,0x00,0x50,0x03,0x02,0x6e,0x6a,0xe5,0x14,0x94,0x20, +0x40,0x09,0x90,0x9a,0xc5,0xe0,0x60,0x03,0x02,0x6e,0x76,0xe5,0x14,0x75,0xf0,0x0a, +0xa4,0x24,0x00,0xf9,0x74,0x90,0x35,0xf0,0x75,0x18,0x01,0xf5,0x19,0x89,0x1a,0xe5, +0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xff,0xa3,0xe0, +0x90,0x9e,0x1b,0xcf,0xf0,0xa3,0xef,0xf0,0xe5,0x14,0x25,0xe0,0x24,0xc4,0xf5,0x82, +0xe4,0x34,0x98,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x9e,0x1d,0xcf,0xf0,0xa3,0xef, +0xf0,0xe5,0x14,0xc3,0x94,0x20,0x50,0x14,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34, +0x04,0xf5,0x83,0xe0,0x54,0x3f,0x90,0x9e,0x19,0xf0,0x80,0x12,0x74,0xa6,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x3f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0x19,0xe0,0xfe,0x54,0x1f,0xa3,0xf0,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x48,0x12, +0x43,0x5f,0xe0,0x90,0x9e,0x20,0xf0,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c, +0xf5,0x83,0xe0,0xc3,0x94,0x05,0x40,0x02,0x41,0x9f,0x90,0x9e,0x20,0xe0,0xff,0x90, +0x9e,0x1a,0xe0,0x9f,0x40,0x13,0x90,0x9e,0x20,0xe0,0x90,0x9e,0x1a,0xf0,0xee,0x54, +0x40,0xfe,0x90,0x9e,0x19,0xf0,0xef,0x4e,0xf0,0x90,0x04,0xfd,0xe0,0x54,0x05,0x64, +0x01,0x70,0x29,0x90,0x9e,0x1a,0xe0,0xff,0x90,0x41,0x4a,0x93,0xfe,0x74,0x44,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xc3,0x9e,0x40,0x06,0xef,0x90,0x40, +0xda,0x80,0x30,0x90,0x9e,0x1a,0xe0,0x90,0x40,0xf6,0x80,0x27,0x90,0x9e,0x1a,0xe0, +0xff,0x90,0x41,0x4a,0x93,0xfe,0x74,0x44,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5, +0x83,0xe0,0xc3,0x9e,0x40,0x06,0xef,0x90,0x41,0x12,0x80,0x07,0x90,0x9e,0x1a,0xe0, +0x90,0x41,0x2e,0x93,0x90,0x9e,0x1f,0xf0,0x90,0x9e,0x1f,0xe0,0x75,0xf0,0x06,0xa4, +0x24,0x50,0xf9,0x74,0x40,0x35,0xf0,0xfa,0x7b,0xff,0x8b,0x15,0xf5,0x16,0x89,0x17, +0xe5,0x14,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xf5,0x1b, +0xa3,0xe0,0xf5,0x1c,0x12,0x29,0xd9,0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a, +0x12,0x42,0x97,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35, +0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x01,0x12,0x42,0x20,0xff, +0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x02,0x12,0x42,0xc2,0xfd,0xac, +0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab,0x15, +0xaa,0x16,0xa9,0x17,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x04,0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef, +0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90, +0x00,0x03,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00, +0x06,0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee, +0x35,0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x04,0x12,0x42,0x20, +0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x08,0x12,0x42,0xc2,0xfd, +0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab, +0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x05,0x12,0x42,0x20,0xff,0x7e,0x00,0x90,0x9e, +0x1b,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x29,0xf2,0xd3,0xe5,0x1c,0x9f,0xe5,0x1b,0x9e, +0x40,0x0c,0xe5,0x1c,0x9f,0xf5,0x1c,0xe5,0x1b,0x9e,0xf5,0x1b,0x80,0x05,0xe4,0xf5, +0x1b,0xf5,0x1c,0xe5,0x14,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83, +0xe5,0x1b,0xf0,0xa3,0xe5,0x1c,0xf0,0x90,0x9e,0x19,0xe0,0x25,0xe0,0x24,0x66,0xf5, +0x82,0xe4,0x34,0x41,0xf5,0x83,0xc3,0x74,0x01,0x93,0x95,0x1c,0xe4,0x93,0x95,0x1b, +0x50,0x07,0xaf,0x14,0x12,0x65,0x5c,0xa1,0x31,0x90,0x9e,0x19,0xe0,0x25,0xe0,0x24, +0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xd3,0x74,0x01,0x93,0x95,0x1c,0xe4,0x93, +0x95,0x1b,0x50,0x02,0xa1,0x31,0x7d,0x01,0xaf,0x14,0x12,0x63,0xbd,0xa1,0x31,0x74, +0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xfc,0x64,0x05,0x60,0x02, +0x81,0x3a,0x90,0x96,0x43,0xe0,0xff,0xb4,0x03,0x0b,0x90,0x9e,0x1a,0xe0,0xc3,0x94, +0x19,0x40,0x3d,0x80,0x2e,0xef,0xb4,0x02,0x0b,0x90,0x9e,0x1a,0xe0,0xc3,0x94,0x11, +0x40,0x2e,0x80,0x1f,0x90,0x96,0x43,0xe0,0xff,0xb4,0x01,0x0b,0x90,0x9e,0x1a,0xe0, +0xc3,0x94,0x0a,0x40,0x1b,0x80,0x0c,0xef,0x70,0x11,0x90,0x9e,0x1a,0xe0,0xc3,0x94, +0x03,0x40,0x0d,0x90,0x9a,0x84,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90,0x9a,0x84,0xf0, +0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x1e,0x74,0x44, +0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xc3,0x94,0x30,0x50,0x02, +0x61,0xe7,0x90,0x9a,0x84,0xe0,0x64,0x01,0x60,0x02,0x61,0xe7,0x74,0x85,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0x64,0x0a,0x60,0x51,0xef,0x24,0x05,0xff, +0xe4,0x33,0xfe,0x74,0x41,0x25,0x14,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe0,0xfd, +0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x32,0xed,0x24,0x05,0xff,0xe4, +0x33,0xfe,0x74,0x44,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xd3,0x9f, +0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x14,0x74,0x26,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x9d,0xf5,0x83,0xe0,0xff,0x90,0x9e,0x1a,0xe0,0x6f,0x60,0x3d,0x74,0x44,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xd3,0x94,0x42,0x40,0x05,0x75, +0x1e,0x05,0x80,0x0e,0xef,0xd3,0x94,0x39,0x40,0x05,0x75,0x1e,0x03,0x80,0x03,0x75, +0x1e,0x01,0x74,0x41,0x25,0x14,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xef,0xf0,0x74, +0x85,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0x80,0x29,0x74,0xe6,0x25,0x14,0xf5,0x82, +0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x85,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xe0,0x04,0xf0,0x80,0x10,0xe4,0xf5,0x1e,0x74,0xe6,0x25,0x14,0xf5,0x82, +0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x9e,0x1a,0xe0,0xff,0x74,0x26,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef,0xf0,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x98,0xf5,0x83,0xe5,0x1e,0xf0,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x4c,0x12, +0x43,0x5f,0xe0,0xb4,0x01,0x10,0xe4,0xf5,0x1e,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe4,0xf0,0xad,0x1e,0xa1,0x2c,0xec,0x64,0x06,0x60,0x02,0xa1, +0x31,0xf5,0x1b,0xf5,0x1c,0x90,0x42,0x13,0x93,0xff,0x7e,0x00,0x90,0x9e,0x1b,0xe0, +0xfc,0xa3,0xe0,0xfd,0x12,0x29,0xf2,0x90,0x9e,0x21,0xee,0xf0,0xa3,0xef,0xf0,0x74, +0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x1e,0xe4,0xf5,0x1d, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x75,0xf0,0x02,0xe5,0x1d,0xa4,0xf5,0x82,0x85,0xf0, +0x83,0x12,0x42,0xc2,0xfd,0xac,0xf0,0xe5,0x1d,0x90,0x42,0x0e,0x93,0xff,0x7e,0x00, +0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xc3,0x90,0x9e, +0x22,0xe0,0x95,0x1c,0x90,0x9e,0x21,0xe0,0x95,0x1b,0x40,0x07,0x05,0x1d,0xe5,0x1d, +0xb4,0x05,0xbd,0xe5,0x1d,0xc3,0x13,0xf5,0x1d,0xe5,0x1e,0xb4,0x01,0x06,0xe5,0x1d, +0x70,0x46,0x80,0x13,0xe5,0x1e,0xb4,0x03,0x15,0xe5,0x1d,0x70,0x05,0x75,0x1e,0x03, +0x80,0x39,0xe5,0x1d,0xb4,0x01,0x05,0x75,0x1e,0x01,0x80,0x2f,0x80,0x2a,0xe5,0x1e, +0xb4,0x05,0x28,0xe5,0x1d,0x70,0x05,0x75,0x1e,0x05,0x80,0x0d,0xe5,0x1d,0xb4,0x01, +0x05,0x75,0x1e,0x03,0x80,0x03,0x75,0x1e,0x01,0xd3,0x90,0x9e,0x1e,0xe0,0x94,0x03, +0x90,0x9e,0x1d,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x1e,0xd3,0x90,0x9e,0x1e,0xe0, +0x94,0x03,0x90,0x9e,0x1d,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x1e,0x74,0x84,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe5,0x1e,0xf0,0xfd,0xaf,0x14,0x12,0x67, +0x61,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xd3,0x94,0x05, +0x74,0xe6,0x50,0x0e,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x04,0xf0, +0x80,0x0b,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x9e,0x1d, +0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x74,0xff,0x9f,0xfd,0x74,0xff,0x9e,0xfc,0xe5,0x14, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xd3, +0x9d,0xea,0x9c,0xe5,0x14,0x50,0x13,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xee,0x8f,0xf0,0x12,0x42,0x81,0x80,0x10,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9a,0xf5,0x83,0x74,0xff,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x44, +0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x74,0xff,0x9f, +0xfd,0x74,0xff,0x9e,0xfc,0xe5,0x14,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xd3,0x9d,0xea,0x9c,0xe5,0x14,0x50,0x13,0x25,0xe0, +0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xee,0x8f,0xf0,0x12,0x42,0x81,0x80, +0x10,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xff,0xf0,0xa3, +0xf0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0xe4,0xf5,0xf0,0x12,0x42,0xfa,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x02,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x04,0xe4, +0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x06,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00, +0x08,0xe4,0xf5,0xf0,0x12,0x43,0x19,0xe5,0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4, +0x34,0x93,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0xc4,0xf5,0x82, +0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x44,0xf5, +0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x05,0x14,0xe5,0x14,0xc3,0x94, +0x40,0x50,0x03,0x02,0x67,0xa4,0x22,0x90,0x04,0x44,0x74,0x11,0xf0,0xa3,0x74,0xf0, +0xf0,0xa3,0x74,0x0f,0xf0,0xa3,0xe4,0xf0,0xfd,0x74,0xa4,0x2d,0xf5,0x82,0xe4,0x34, +0x04,0xf5,0x83,0xe4,0xf0,0x0d,0xbd,0x10,0xf0,0xe4,0x90,0x9a,0xc5,0xf0,0x90,0x95, +0x01,0x04,0xf0,0xe4,0xfd,0x75,0xf0,0x0a,0xed,0x90,0x90,0x00,0x12,0x43,0x5f,0xe4, +0xf0,0xa3,0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x02,0x12,0x43,0x5f,0xe4,0xf0,0xa3, +0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x04,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75, +0xf0,0x0a,0xed,0x90,0x90,0x06,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a, +0xed,0x90,0x90,0x08,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x74,0x26,0x2d,0xf5,0x82, +0xe4,0x34,0x9d,0xf5,0x83,0x74,0x13,0xf0,0x74,0x85,0x2d,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xe4,0xf0,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0, +0xed,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0x44,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0x74,0x86,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x46,0x2d,0xf5, +0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0xe6,0x2d,0xf5,0x82,0xe4,0x34,0x9c, +0xf5,0x83,0xe4,0xf0,0x90,0x41,0xc4,0x93,0xfe,0x74,0x01,0x93,0xff,0x90,0x41,0x8c, +0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25, +0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x75, +0xf0,0x09,0xed,0x90,0x96,0x4b,0x12,0x43,0x5f,0x74,0x01,0xf0,0x75,0xf0,0x09,0xed, +0x90,0x96,0x4a,0x12,0x43,0x5f,0x74,0x01,0xf0,0x74,0x82,0x2d,0xf5,0x82,0xe4,0x34, +0x95,0xf5,0x83,0x74,0x0c,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x46,0x12,0x43,0x5f, +0x74,0xff,0xf0,0xa3,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x44,0x12,0x43,0x5f,0xe4, +0xf0,0xa3,0x74,0x0f,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0x74, +0x13,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x49,0x12,0x43,0x5f,0xe4,0xf0,0xed,0xc3, +0x94,0x20,0x50,0x0f,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0x74,0x13, +0xf0,0x80,0x0d,0x74,0xa6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0x74,0x13,0xf0, +0x0d,0xed,0x64,0x40,0x60,0x03,0x02,0x6e,0xa5,0x22,0x12,0x29,0xd9,0xf5,0x14,0xc3, +0x94,0x40,0x50,0x15,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x74,0x44,0x25,0x14,0xf5, +0x82,0xe4,0x34,0x9a,0xf5,0x83,0xef,0xf0,0x22,0xe5,0x14,0xb4,0x40,0x0a,0x90,0x00, +0x02,0x12,0x42,0x20,0x90,0x96,0x42,0xf0,0x22,0x90,0x9e,0x30,0x12,0x43,0x8b,0x90, +0x9e,0x33,0xe0,0x54,0xf0,0x44,0x02,0xf0,0x54,0x0f,0x44,0xc0,0xf0,0x90,0x9e,0x30, +0x12,0x43,0x6b,0x90,0x9e,0x90,0x12,0x43,0x8b,0x7b,0x01,0x7a,0x9e,0x79,0x33,0x02, +0x53,0xf1,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x90,0x00,0x01,0x12,0x42,0x20,0xfc, +0xed,0xc3,0x94,0x40,0x40,0x02,0xe4,0xfd,0xec,0xc3,0x94,0x40,0x40,0x02,0xe4,0xfc, +0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0, +0xfb,0xea,0x90,0x9e,0x24,0xf0,0xeb,0xa3,0xf0,0xed,0x25,0xe0,0x24,0x46,0xf5,0x82, +0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x26,0xf0,0xeb, +0xa3,0xf0,0xa3,0xed,0xf0,0xa3,0x74,0xff,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x2a,0xf0,0xeb, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfa, +0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x2c,0xf0,0xeb,0xa3,0xf0,0xa3,0xec,0xf0,0xa3,0x74, +0xff,0xf0,0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xed,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0x7b,0x01,0x7a,0x9e,0x79,0x24,0x01,0x79,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0x90,0x9e,0xa4,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0x90,0x9e, +0xa4,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90,0x9e,0xa7, +0xe0,0x94,0xe8,0x90,0x9e,0xa6,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6,0xe0,0x44, +0x10,0xf0,0x7f,0x00,0x80,0x15,0x90,0x9e,0xa6,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81, +0x7f,0x0a,0x7e,0x00,0x12,0x37,0x54,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x24,0x12,0x2a,0x8b,0x00,0x00,0x00, +0x00,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x9e,0x66,0xf0,0x90,0x00,0x03,0x12,0x42, +0x20,0x90,0x9e,0x55,0xf0,0x12,0x56,0x22,0x90,0x01,0xe5,0xe5,0x63,0xf0,0x90,0x9e, +0x66,0xe0,0x90,0x01,0xe6,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x02,0x12,0x42, +0x20,0xff,0x30,0xe0,0x25,0x12,0x29,0xd9,0x90,0x9e,0x5c,0xf0,0x90,0x00,0x01,0x12, +0x42,0x20,0x90,0x9e,0x5d,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x5b,0xf0,0x90, +0x00,0x03,0x12,0x42,0x20,0x90,0x9e,0x62,0xf0,0x22,0x90,0x9e,0x5c,0x74,0x0a,0xf0, +0x90,0x9e,0x5d,0x74,0x05,0xf0,0x90,0x9e,0x5b,0x74,0x14,0xf0,0x90,0x9e,0x62,0x74, +0x05,0xf0,0x22,0x12,0x29,0xd9,0x30,0xe0,0x19,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x61, +0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x9e,0x5f,0xe4,0xf0,0xa3,0xef,0xf0, +0x80,0x0f,0x90,0x9e,0x61,0x74,0x07,0xf0,0x90,0x9e,0x5f,0xe4,0xf0,0xa3,0x74,0x03, +0xf0,0x90,0x9e,0x5f,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0x90,0x9e,0x24,0x12, +0x2a,0x8b,0x00,0x00,0x00,0x00,0x12,0x29,0xd9,0x60,0x0d,0x90,0x9e,0x5e,0xf0,0xe4, +0xfd,0x7f,0x04,0x12,0x54,0xe7,0x80,0x05,0xe4,0x90,0x9e,0x5e,0xf0,0x90,0x9e,0x5e, +0xe0,0x90,0x01,0xe7,0xf0,0x22,0x90,0x02,0x09,0xe0,0xfd,0x12,0x29,0xd9,0xfe,0xaf, +0x05,0xed,0x2e,0x90,0x9e,0x78,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f, +0x90,0x9e,0x79,0xf0,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x7a, +0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x7b,0xf0,0x90,0x00, +0x04,0x12,0x42,0x20,0xff,0xae,0x05,0xed,0x2f,0x90,0x9e,0x7c,0xf0,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x24,0x12,0x43,0x8b,0x90,0x9e,0x24,0x12,0x43, +0x6b,0x90,0x00,0x01,0x12,0x42,0xc2,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe, +0x90,0x9e,0x24,0x12,0x43,0x6b,0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x43,0x19,0x12, +0x29,0xd9,0xff,0x60,0x2d,0xb5,0x65,0x16,0x90,0x9e,0x24,0x12,0x43,0x6b,0x90,0x00, +0x01,0x12,0x42,0xc2,0x65,0x67,0x70,0x04,0xe5,0x66,0x65,0xf0,0x60,0x24,0x90,0x9e, +0x24,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42,0xc2,0xff,0xae,0xf0,0x12,0x4e,0x37, +0x80,0x10,0x90,0x9e,0x24,0x12,0x43,0x6b,0x12,0x29,0xd9,0x65,0x65,0x60,0x03,0x12, +0x44,0xc2,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x06,0x34,0x74,0xff,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0x22,0x90,0x06,0x34,0xe0,0x60,0x24,0x14,0x70,0x1a,0x7b,0x01, +0x7a,0x06,0x79,0x35,0x7f,0xf9,0x7e,0x01,0x71,0xb0,0xbf,0x01,0x09,0x90,0x06,0x35, +0xe0,0x54,0x0f,0xf0,0x80,0x04,0x80,0x00,0x80,0xcd,0xe4,0x90,0x06,0x34,0xf0,0x22, +0x8e,0x14,0x8f,0x15,0x8b,0x16,0x8a,0x17,0x89,0x18,0xe4,0x90,0x9e,0x19,0xf0,0xef, +0x90,0x00,0x31,0xf0,0x12,0x4d,0x45,0xe5,0x14,0x54,0x03,0xff,0x90,0x00,0x32,0xe0, +0x54,0xfc,0x4f,0xf0,0x12,0x4d,0x45,0x90,0x00,0x33,0xe0,0x54,0x7f,0xf0,0x12,0x4d, +0x45,0x90,0x00,0x33,0xe0,0x20,0xe7,0x0e,0x90,0x9e,0x19,0xe0,0xc3,0x94,0x64,0x50, +0x05,0xe0,0x04,0xf0,0x80,0xeb,0x90,0x9e,0x19,0xe0,0xc3,0x94,0x64,0x50,0x10,0x90, +0x00,0x30,0xe0,0xab,0x16,0xaa,0x17,0xa9,0x18,0x12,0x42,0x4d,0x7f,0x01,0x22,0x7f, +0x00,0x22,0xe4,0x90,0x9e,0xac,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, +0x9e,0xad,0xe0,0x94,0xe8,0x90,0x9e,0xac,0xe0,0x94,0x03,0x40,0x03,0x7f,0x00,0x22, +0x7f,0x32,0x7e,0x00,0x12,0x37,0x54,0x90,0x9e,0xac,0xe4,0x75,0xf0,0x01,0x12,0x42, +0x81,0x80,0xc6,0x90,0x00,0x11,0xe0,0x44,0x09,0xf0,0x12,0x4d,0x45,0x90,0x9d,0xff, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12,0x2f,0xd9, +0x90,0x9e,0x03,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c, +0x12,0x2f,0xd9,0x90,0x9e,0x07,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x0b,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00, +0x03,0x2d,0x95,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x11, +0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd,0x7f,0x01,0x12,0x34, +0x81,0x22,0x7f,0x78,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xff,0x12,0x2a,0x7f,0x7f, +0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x9e,0x03,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08, +0x12,0x27,0xde,0x90,0x9e,0x07,0x12,0x2a,0x7f,0x90,0x9e,0x80,0xe0,0x90,0x9d,0xff, +0xb4,0x01,0x0d,0x12,0x43,0x53,0xef,0x54,0xc7,0xff,0xed,0x54,0xc7,0xfd,0x80,0x07, +0x12,0x43,0x53,0xef,0x54,0xc7,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78, +0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x03,0x12,0x43,0x53,0xef,0x54,0x0f,0xff,0xec, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x9e,0x07, +0x12,0x43,0x53,0xef,0x44,0x02,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x00, +0x7e,0x08,0x12,0x2f,0xd9,0x7f,0x70,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9e,0x0b,0x12, +0x2a,0x7f,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa0,0x7f,0x70,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4,0xfd,0xff, +0x12,0x34,0x81,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x11,0x90,0x80,0x59,0x12,0x2a,0x8b, +0x00,0x00,0x00,0x00,0xe4,0xfd,0x7f,0x01,0x12,0x34,0x81,0x90,0x00,0x11,0xe0,0x54, +0xf6,0xf0,0x02,0x4d,0x45,0xef,0x70,0x02,0xe1,0x5c,0x90,0x9e,0x0f,0xe0,0x60,0x03, +0x02,0x7b,0x28,0x90,0x9d,0xfb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9d,0xa7,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9d,0xab,0x12,0x43,0x53,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9d,0xaf,0x12, +0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x9d,0xb3,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x9d,0xb7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x74, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xbb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xbf,0x12,0x43,0x53,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xc3,0x12,0x43, +0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d, +0xc7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x9d,0xcb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x88,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xcf,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x8c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xd3,0x12,0x43,0x53,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xd7,0x12,0x43,0x53, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd4,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xdb, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd8,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x9d,0xdf,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x9d,0xe3,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xe7,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xeb,0x12,0x43,0x53,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x9d,0xef,0x12, +0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x90, +0x9d,0xf3,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12, +0x2f,0xd9,0x90,0x9d,0xf7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x0f,0x74,0x01,0xf0,0x22,0x90,0x9e,0x0f,0xe0, +0x64,0x01,0x60,0x03,0x02,0x7b,0x28,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d, +0xfb,0x12,0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xa7,0x12,0x2a, +0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xab,0x12,0x2a,0x7f,0x7f,0x6c, +0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xaf,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12, +0x27,0xde,0x90,0x9d,0xb3,0x12,0x2a,0x7f,0x7f,0x74,0x7e,0x0e,0x12,0x27,0xde,0x90, +0x9d,0xb7,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xbb,0x12, +0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xbf,0x12,0x2a,0x7f,0x7f, +0x80,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xc3,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e, +0x12,0x27,0xde,0x90,0x9d,0xc7,0x12,0x2a,0x7f,0x7f,0x88,0x7e,0x0e,0x12,0x27,0xde, +0x90,0x9d,0xcb,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xcf, +0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xd3,0x12,0x2a,0x7f, +0x7f,0xd4,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xd7,0x12,0x2a,0x7f,0x7f,0xd8,0x7e, +0x0e,0x12,0x27,0xde,0x90,0x9d,0xdb,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e,0x12,0x27, +0xde,0x90,0x9d,0xdf,0x12,0x2a,0x7f,0x7f,0xe0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d, +0xe3,0x12,0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xe7,0x12,0x2a, +0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x9d,0xeb,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x0d,0x12,0x27,0xde,0x90,0x9d,0xef,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12, +0x27,0xde,0x90,0x9d,0xf3,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90, +0x9d,0xf7,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12, +0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xed,0x44,0xc0,0xfd,0xec,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x01,0x00,0x00, +0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0xdb,0x25, +0xa4,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb, +0x25,0xa4,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20, +0xdb,0x25,0xa4,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b, +0x04,0x1b,0x25,0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a, +0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12, +0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85, +0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80, +0x85,0x12,0x2a,0x8b,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x80,0x85,0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd8,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f,0xdc, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f, +0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x24,0xdb,0x25,0xa4, +0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x9e, +0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xe4,0xff,0xec,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x11,0xff,0xec,0x90,0x9e, +0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0d,0x12,0x27,0xde,0x90,0x9e, +0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x54,0xf0,0xff,0xec,0x90, +0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x01,0xff,0xec, +0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xe4,0xff,0xec,0x90, +0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x11,0xff,0xec, +0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xed,0x54,0x0f,0xfd, +0xec,0x54,0xf0,0xfc,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53, +0xed,0x44,0x10,0xfd,0xec,0x44,0x01,0xfc,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e, +0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f, +0xd9,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e, +0xa8,0x12,0x43,0x53,0xef,0x54,0xf0,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90, +0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x01,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f, +0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08, +0x12,0x2f,0xd9,0xe4,0x90,0x9e,0x0f,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90, +0x9e,0x43,0xf0,0xe0,0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5,0x14, +0xc2,0xaf,0x90,0x00,0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x49,0x05,0x7d,0x40, +0x7f,0x01,0x12,0x36,0xaf,0xe5,0x14,0x24,0xff,0x92,0xaf,0x22,0x90,0x9e,0x3a,0xe0, +0xc3,0x94,0x14,0x50,0x05,0xe0,0x04,0xf0,0x81,0x14,0x90,0x9e,0x3a,0xe0,0x64,0x14, +0x60,0x02,0x81,0x14,0x90,0x9e,0x49,0xe0,0x70,0x25,0x90,0x9e,0x4c,0xe0,0x70,0x1f, +0x90,0x9e,0x4a,0xe0,0x70,0x19,0x90,0x9e,0x4d,0xe0,0x70,0x13,0x90,0x9e,0x4b,0xe0, +0x70,0x0d,0x90,0x9e,0x4e,0xe0,0x70,0x07,0x90,0x04,0xfd,0xe0,0x54,0xfe,0xf0,0x90, +0x9e,0x49,0xe0,0x90,0x04,0x44,0xf0,0x90,0x9e,0x4a,0xe0,0x90,0x04,0x45,0xf0,0x90, +0x9e,0x4b,0xe0,0x90,0x04,0x46,0xf0,0xa3,0xe4,0xf0,0x90,0x9e,0x4c,0xe0,0x90,0x04, +0x48,0xf0,0x90,0x9e,0x4d,0xe0,0x90,0x04,0x49,0xf0,0x90,0x9e,0x4e,0xe0,0x90,0x04, +0x4a,0xf0,0xa3,0xe4,0xf0,0x90,0x9e,0x35,0xe0,0x90,0x04,0x4c,0xf0,0x90,0x9e,0x36, +0xe0,0x90,0x04,0x4d,0xf0,0x90,0x9e,0x37,0xe0,0x90,0x04,0x4e,0xf0,0x90,0x9e,0x38, +0xe0,0x90,0x04,0x4f,0xf0,0xe4,0x90,0x9e,0x3a,0xf0,0x90,0x9e,0x35,0x04,0xf0,0xe4, +0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x9e,0x49,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x19,0xf0,0x90,0x05,0x61,0xe0, +0x90,0x9e,0x1a,0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x1b,0xf0,0x90,0x05,0x63,0xe0, +0x90,0x9e,0x1c,0xf0,0x90,0x9e,0x52,0xe0,0xff,0x90,0x9e,0x1c,0xe0,0xfe,0xd3,0x9f, +0x50,0x0b,0x90,0x9e,0x52,0xe0,0xc3,0x9e,0xd3,0x94,0x01,0x40,0x11,0x90,0x9e,0x40, +0xe0,0xb4,0x01,0x02,0x80,0x03,0x90,0x9e,0x44,0xe0,0xff,0x12,0x4c,0xf0,0x22,0x90, +0x9e,0x53,0xe0,0x64,0x01,0x60,0x08,0x90,0x9e,0x41,0xe0,0x60,0x02,0xa1,0x36,0x90, +0x9e,0x35,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x3b,0x90,0x9e,0x36, +0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x28,0x90,0x9e,0x37,0xe0, +0xc3,0x94,0xff,0x50,0x0a,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x36,0xf0,0x80,0x15,0x90, +0x9e,0x38,0xe0,0xc3,0x94,0xff,0x50,0x10,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x37,0xf0, +0x90,0x9e,0x36,0xf0,0x90,0x9e,0x35,0xf0,0x90,0x00,0x44,0xe0,0x54,0x0c,0x60,0x76, +0xe0,0x30,0xe2,0x32,0x90,0x9e,0x49,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0, +0x80,0x24,0x90,0x9e,0x4a,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80, +0x11,0x90,0x9e,0x4b,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x9e, +0x4a,0xf0,0x90,0x9e,0x49,0xf0,0x90,0x00,0x44,0xe0,0x30,0xe3,0x32,0x90,0x9e,0x4c, +0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x9e,0x4d,0xe0,0xc3, +0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x9e,0x4e,0xe0,0xc3,0x94, +0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x4d,0xf0,0x90,0x9e,0x4c,0xf0,0x90, +0x04,0xfd,0xe0,0x44,0x01,0xf0,0x22,0x00,0x37,0xda,}; + +// =================== v79 UMC A Cut COMMON 2011-10-06 ===================== +u8 Rtl8192CUFwUMCACutImgArray[UMCACutImgArrayLength] = { +0xc1,0x88,0x02,0x00,0x4f,0x00,0x00,0x00,0x0a,0x06,0x18,0x09,0x58,0x3f,0x01,0x00, +0x61,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x5a,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x5f,0xfb,0x00,0x00,0x00,0x00,0x00,0xa1,0xdf,0x00,0x00,0x00, +0x05,0x04,0x03,0x02,0x00,0x03,0x06,0x05,0x04,0x03,0x00,0x04,0x06,0x05,0x04,0x02, +0x00,0x04,0x08,0x07,0x06,0x04,0x00,0x06,0x0a,0x09,0x08,0x06,0x00,0x08,0x0a,0x09, +0x08,0x04,0x00,0x08,0x0a,0x09,0x08,0x02,0x00,0x08,0x0a,0x09,0x08,0x00,0x00,0x08, +0x12,0x11,0x10,0x08,0x00,0x10,0x1a,0x19,0x18,0x10,0x00,0x18,0x22,0x21,0x20,0x18, +0x00,0x20,0x22,0x21,0x20,0x10,0x00,0x20,0x22,0x21,0x20,0x08,0x00,0x20,0x22,0x21, +0x1c,0x08,0x00,0x20,0x22,0x21,0x14,0x08,0x00,0x20,0x22,0x20,0x18,0x08,0x00,0x20, +0x31,0x30,0x20,0x10,0x00,0x30,0x31,0x30,0x18,0x00,0x00,0x30,0x31,0x2f,0x10,0x10, +0x00,0x30,0x31,0x2c,0x10,0x10,0x00,0x30,0x31,0x28,0x10,0x00,0x00,0x30,0x31,0x20, +0x10,0x00,0x00,0x30,0x31,0x10,0x10,0x00,0x00,0x30,0x04,0x04,0x04,0x05,0x04,0x04, +0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04, +0x05,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x07,0x0a,0x0b, +0x0d,0x10,0x04,0x05,0x05,0x06,0x06,0x09,0x0c,0x11,0x08,0x08,0x09,0x09,0x0a,0x0c, +0x10,0x11,0x04,0x04,0x04,0x05,0x04,0x04,0x05,0x07,0x07,0x07,0x08,0x0a,0x04,0x04, +0x04,0x04,0x06,0x0a,0x0b,0x0d,0x05,0x05,0x07,0x07,0x08,0x0b,0x0d,0x0f,0x04,0x04, +0x04,0x05,0x07,0x07,0x09,0x09,0x0c,0x0e,0x10,0x12,0x04,0x04,0x05,0x05,0x06,0x0a, +0x11,0x13,0x09,0x09,0x09,0x09,0x0c,0x0e,0x11,0x13,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x24,0x26,0x2a,0x18,0x1a,0x1d,0x1f,0x21,0x27,0x29,0x2a,0x00,0x00, +0x00,0x1f,0x23,0x28,0x2a,0x2c,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x18, +0x00,0x24,0x00,0x30,0x00,0x48,0x00,0x60,0x00,0x90,0x00,0xc0,0x00,0xd8,0x00,0x50, +0x00,0x78,0x00,0xa0,0x00,0xc8,0x01,0x40,0x01,0x90,0x01,0xe0,0x02,0x30,0x01,0x2c, +0x01,0x40,0x01,0xe0,0x02,0xd0,0x03,0xe8,0x04,0xb0,0x06,0x40,0x07,0xd0,0x00,0x02, +0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x0c,0x00,0x12,0x00,0x18,0x00,0x24,0x00,0x30, +0x00,0x48,0x00,0x60,0x00,0x6c,0x00,0x28,0x00,0x3c,0x00,0x50,0x00,0x64,0x00,0xa0, +0x00,0xc8,0x00,0xf0,0x01,0x18,0x00,0x64,0x00,0xa0,0x00,0xf0,0x01,0x68,0x01,0xf4, +0x02,0x58,0x03,0x20,0x03,0xe8,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x04,0x04, +0x05,0x07,0x04,0x04,0x07,0x0a,0x0a,0x0c,0x0c,0x12,0x05,0x07,0x07,0x08,0x0b,0x12, +0x24,0x3c,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02, +0x03,0x04,0x05,0x06,0x07,0x08,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x20,0x1e, +0x1c,0x18,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a,0x83,0xe0,0xf5, +0xf0,0xa3,0xe0,0x22,0x50,0x06,0x87,0xf0,0x09,0xe7,0x19,0x22,0xbb,0xfe,0x07,0xe3, +0xf5,0xf0,0x09,0xe3,0x19,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0xf5,0xf0,0x74,0x01, +0x93,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0, +0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22, +0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a, +0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a, +0x83,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x06,0xf7,0x09,0xa7,0xf0,0x19,0x22,0xbb, +0xfe,0x06,0xf3,0xe5,0xf0,0x09,0xf3,0x19,0x22,0xf8,0xbb,0x01,0x11,0xe5,0x82,0x29, +0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x09, +0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb,0xfe,0x09,0xe9,0x25,0x82,0xc8, +0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee,0x4a,0xfe,0xed,0x49,0xfd,0xec, +0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xa4, +0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83,0x22,0xe0,0xfb,0xa3,0xe0,0xfa, +0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0,0xf9,0x25,0xf0,0xf0,0xe5,0x82, +0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0, +0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93, +0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74, +0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf,0x02,0x43,0xf8,0x02,0x50,0xa9, +0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2,0x08,0xdf,0xf4, +0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33,0xc4,0x54,0x0f, +0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf,0xe4,0x80,0x0b, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x3d,0xe4,0x7e,0x01,0x93,0x60, +0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x9e,0x66, +0x00,0x41,0x9e,0xae,0x00,0x41,0x9e,0x4d,0x80,0x41,0x9e,0x4e,0x80,0x41,0x9e,0xb0, +0x00,0x00,0xf0,0x90,0x9e,0x57,0xe0,0x90,0x9e,0x8a,0xf0,0xe4,0xfb,0xfd,0x7f,0x54, +0x7e,0x01,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x88,0xeb,0xf0,0xa3,0xe0, +0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5,0x45,0x12,0x30,0x62,0xd0,0xd0,0x92,0xaf,0x22, +0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x08,0xf0,0xe4,0x90,0x9e,0x89,0xf0, +0x90,0x9e,0x55,0xe0,0x90,0x9e,0x8a,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91, +0x62,0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x90,0x9e,0x5c, +0x14,0xf0,0x90,0x9e,0x5e,0xe0,0x54,0x0f,0xc3,0x94,0x0c,0x50,0x02,0xf1,0x16,0x22, +0x8f,0x82,0x8e,0x83,0xa3,0xa3,0xa3,0xe4,0xf0,0x22,0xe4,0xf5,0x22,0x7f,0x60,0x7e, +0x01,0x80,0xed,0x90,0x9e,0x60,0xe0,0xff,0x7d,0x01,0xe1,0x1a,0xb1,0xb1,0xbf,0x01, +0x0f,0x90,0x9e,0x68,0xe0,0xff,0xe4,0xfd,0xf1,0xfe,0x90,0x04,0x1f,0x74,0x20,0xf0, +0x22,0x90,0x01,0xca,0xe5,0x25,0xf0,0xef,0x60,0x03,0x12,0x4f,0x2a,0x22,0x22,0x22, +0x22,0x22,0x00,0x02,0x60,0x8d,0x02,0x60,0x94,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x8b,0x1b,0x8a,0x1c,0x89,0x1d,0x90,0x9e,0x8b,0x71,0x8b,0xab,0x1e,0xaa,0x1f,0xa9, +0x20,0x90,0x9e,0x8e,0x71,0x8b,0xaf,0x21,0x15,0x21,0xef,0x60,0x1b,0x90,0x9e,0x8e, +0xe4,0x75,0xf0,0x01,0x71,0x74,0x12,0x24,0x62,0xff,0x90,0x9e,0x8b,0xe4,0x75,0xf0, +0x01,0x71,0x74,0xef,0x51,0x4d,0x80,0xde,0xab,0x1b,0xaa,0x1c,0xa9,0x1d,0xd0,0xd0, +0x92,0xaf,0x22,0x90,0x06,0xa9,0xe0,0xf5,0x50,0x54,0xc0,0x70,0x0d,0x90,0x9e,0x63, +0xe0,0x54,0xfe,0xf0,0xe0,0x54,0xfd,0xf0,0x91,0xd3,0xe5,0x50,0x30,0xe6,0x17,0x90, +0x9e,0x63,0xe0,0x44,0x01,0xf0,0x90,0x9e,0x61,0xe0,0x64,0x02,0x60,0x04,0x91,0xdc, +0x80,0x0b,0x91,0x80,0x80,0x07,0x90,0x9e,0x63,0xe0,0x54,0xfe,0xf0,0xe5,0x50,0x90, +0x9e,0x63,0x30,0xe7,0x17,0xe0,0x44,0x02,0xf0,0xe4,0x90,0x9e,0x89,0x91,0x52,0x90, +0x01,0x57,0x74,0x05,0xf0,0x90,0x9e,0x62,0x74,0x01,0xf0,0x22,0xe0,0x54,0xfd,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,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7, +0xe0,0x30,0xe1,0xe4,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,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, +0xdf,0xf0,0x74,0x45,0xa3,0xf0,0x53,0x91,0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5, +0x34,0xa3,0xe0,0x55,0x31,0xf5,0x35,0xa3,0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55, +0x33,0xf5,0x37,0xe5,0x34,0x30,0xe0,0x06,0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34, +0x30,0xe1,0x08,0x90,0x01,0x3c,0x74,0x02,0xf0,0xf1,0xbc,0xe5,0x34,0x30,0xe2,0x38, +0x90,0x01,0x3c,0x74,0x04,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe0,0x24,0x90,0x9e,0x89, +0xe4,0xf0,0x90,0x9e,0x55,0xe0,0x90,0x9e,0x8a,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e, +0x01,0x91,0x62,0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80, +0x07,0x90,0x9e,0x5d,0xe4,0xf0,0x91,0xd3,0xe5,0x34,0x30,0xe3,0x38,0x90,0x01,0x3c, +0x74,0x08,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe1,0x24,0x90,0x9e,0x89,0xe4,0xf0,0x90, +0x9e,0x55,0xe0,0x90,0x9e,0x8a,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x62, +0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x07,0x90,0x9e, +0x5c,0xe4,0xf0,0x91,0xd3,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10,0xf0, +0x12,0x4d,0xe2,0xe5,0x34,0x30,0xe5,0x09,0x90,0x01,0x3c,0x74,0x20,0xf0,0x12,0x4e, +0x25,0xe5,0x35,0x30,0xe0,0x1a,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f,0xe0, +0x44,0x7f,0xf0,0x90,0x00,0x83,0xe0,0x90,0x9e,0x60,0xf0,0x12,0x64,0xa1,0x91,0xd3, +0x74,0xdf,0x04,0x90,0x01,0xc4,0xf0,0x74,0x45,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,0x7d,0x01,0x7f,0x0c,0x8f,0x71,0x8d,0x72,0xe5,0x71, +0x54,0x0f,0xff,0x90,0x9e,0x5e,0xe0,0x54,0x0f,0x6f,0x60,0x72,0xe5,0x71,0x30,0xe2, +0x2b,0x90,0x9e,0x5e,0xe0,0x20,0xe2,0x05,0x7f,0x01,0x12,0x63,0x92,0x90,0x9e,0x5e, +0xe0,0x30,0xe3,0x07,0xe5,0x71,0x20,0xe3,0x02,0x80,0x54,0x90,0x9e,0x5e,0xe0,0x20, +0xe3,0x4c,0xe5,0x71,0x30,0xe3,0x47,0xaf,0x72,0x02,0x63,0x2e,0x90,0x9e,0x5e,0xe0, +0x54,0x0f,0xff,0xbf,0x0c,0x0d,0xe5,0x71,0x20,0xe3,0x08,0x12,0x5e,0xf1,0xef,0x60, +0x2d,0xf1,0x9f,0x90,0x9e,0x5e,0xe0,0x54,0x0f,0xff,0xbf,0x04,0x0e,0xe5,0x71,0x20, +0xe2,0x09,0x12,0x62,0x50,0xef,0x60,0x16,0x12,0x48,0xaa,0x90,0x9e,0x5e,0xe0,0x54, +0x0f,0xff,0xbf,0x02,0x09,0x12,0x62,0xbb,0xef,0x60,0x03,0x12,0x64,0x87,0x22,0x90, +0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x73,0xb4,0x01,0x05,0x7f,0x01,0x12,0x63,0x4d, +0x90,0x9e,0x5e,0xe0,0x54,0xf0,0xf0,0xe0,0x44,0x04,0xf0,0x22,0x90,0x9e,0x62,0xe0, +0x60,0x0e,0xe4,0xf0,0xa3,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0x07,0x70,0x2b,0x80,0x27, +0x90,0x9e,0x51,0xe0,0x04,0xf0,0x90,0x9e,0x63,0xe0,0x54,0xef,0xf0,0x90,0x9e,0x56, +0xe0,0xff,0x90,0x9e,0x51,0xe0,0xd3,0x9f,0x40,0x0d,0xe5,0x73,0xb4,0x01,0x0a,0xa3, +0xe0,0x70,0x06,0xe0,0x04,0xf0,0x22,0x91,0xd3,0x22,0xe0,0xff,0x7d,0x01,0x90,0x9e, +0x9c,0xef,0xf0,0xa3,0xed,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5,0x74,0x60,0x04,0xe4, +0xff,0x11,0x8f,0x90,0x9e,0x9c,0xe0,0x30,0xe0,0x09,0x90,0x9e,0x9e,0xe4,0xf0,0xa3, +0x74,0x80,0xf0,0x90,0x9e,0x9c,0xe0,0xff,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x90,0x04, +0x25,0xef,0xf0,0x90,0x9e,0x9d,0xe0,0x60,0x1f,0xa3,0xa3,0xe0,0xff,0x24,0x0f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10,0x2f,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x90,0x9e,0x9e,0xa3,0xe0,0xff,0xfd,0x24, +0x08,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09,0x2d,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34,0xfc, +0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x90,0x9e,0x9e,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xef, +0x60,0x0b,0x90,0x9e,0x77,0xe0,0xb4,0x01,0x10,0xe4,0xff,0x80,0x09,0x90,0x9e,0x77, +0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x77,0x66,0x22,0x90,0x01,0x37,0x74,0x02,0xf0, +0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x77,0x1c,0xef,0x70,0x06,0x90,0x01,0xc8,0x74, +0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x31,0x9d,0xe5,0x74,0x60,0x04,0x7f,0x01,0x11, +0x8f,0x11,0xdf,0x90,0x9e,0x5e,0xe0,0x54,0xf0,0xf0,0xe0,0x44,0x02,0xf0,0x22,0x7f, +0x78,0x7e,0x08,0x12,0x22,0x65,0x90,0x9d,0xff,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c, +0x12,0x22,0x65,0x90,0x9e,0x03,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12,0x22,0x65, +0x90,0x9e,0x07,0x12,0x25,0x08,0x90,0x9e,0x77,0xe0,0x90,0x9d,0xff,0xb4,0x01,0x0d, +0x12,0x43,0x53,0xef,0x54,0xc7,0xff,0xed,0x54,0xc7,0xfd,0x80,0x07,0x12,0x43,0x53, +0xef,0x54,0xc7,0xff,0xec,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x78,0x7e,0x08,0x12, +0x2b,0x08,0x90,0x9e,0x03,0x12,0x43,0x53,0xef,0x54,0x0f,0xff,0xec,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x90,0x9e,0x07,0x12,0x43,0x53, +0xef,0x44,0x02,0xff,0xec,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12, +0x2b,0x08,0x7f,0x70,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9e,0x0b,0x12,0x25,0x08,0x90, +0x80,0x96,0x12,0x25,0x14,0x00,0x1b,0x25,0xa0,0x7f,0x70,0x7e,0x0e,0x12,0x2b,0x08, +0x90,0x80,0x68,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe4,0xfd,0xff,0x12,0x30,0x2c, +0x90,0x9e,0x77,0xe0,0xb4,0x01,0x11,0x90,0x80,0x68,0x12,0x25,0x14,0x00,0x00,0x00, +0x00,0xe4,0xfd,0x7f,0x01,0x12,0x30,0x2c,0x90,0x00,0x11,0xe0,0x54,0xf6,0xf0,0x80, +0x08,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x7f,0x10,0xdf,0xfe,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x9e,0xad,0xed,0xf0,0x90,0x9e,0xac,0xef,0xf0,0xd3,0x94,0x07,0x50,0x63,0xe0, +0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00, +0x47,0xe0,0x5f,0xf0,0x31,0xb9,0x90,0x9e,0xac,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08, +0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x46,0xe0,0x4f,0xf0,0x31,0xb9,0x90, +0x9e,0xad,0xe0,0x60,0x16,0x90,0x9e,0xac,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x45,0x80,0x66,0x90,0x9e,0xac,0xe0,0xff, +0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x45, +0x80,0x6b,0x90,0x9e,0xac,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08, +0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0x31,0xb1,0x90,0x9e,0xac,0xe0,0xff, +0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x43,0xe0, +0x4f,0xf0,0x31,0xb9,0x90,0x9e,0xad,0xe0,0x60,0x1b,0x90,0x9e,0xac,0xe0,0xff,0x74, +0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00, +0x42,0xe0,0x4f,0x80,0x1a,0x90,0x9e,0xac,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x42,0xe0,0x5f,0xf0, +0x31,0xb9,0xd0,0xd0,0x92,0xaf,0x22,0xf0,0x90,0x00,0x45,0xe0,0x54,0xfe,0xfd,0x7f, +0x45,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x8f,0x82,0x75,0x83,0x00,0xed,0xf0,0x31, +0xb9,0xd0,0xd0,0x92,0xaf,0x22,0xef,0x14,0x60,0x30,0x14,0x60,0x66,0x24,0x02,0x60, +0x02,0x61,0x7d,0x90,0x9e,0x1a,0x74,0x02,0xf0,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd, +0x7f,0x48,0x51,0xc1,0x90,0x00,0x47,0xe0,0x44,0x08,0xfd,0x7f,0x47,0x51,0xc1,0x90, +0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x80,0x71,0xe4,0x90,0x9e,0x1a,0xf0,0x90, +0x9e,0x16,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12, +0x2b,0x08,0x90,0x00,0x45,0xe0,0x44,0xef,0xfd,0x7f,0x45,0x51,0xc1,0x90,0x00,0x45, +0xe0,0x54,0xef,0xfd,0x7f,0x45,0x51,0xc1,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f, +0x46,0x80,0x38,0x90,0x9e,0x1a,0x74,0x01,0xf0,0x90,0x9e,0x20,0x12,0x43,0x53,0x90, +0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x90,0x00,0x45,0xe0, +0x44,0x20,0xfd,0x7f,0x45,0x51,0xc1,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45, +0x51,0xc1,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x51,0xc1,0x22,0x90,0x00, +0x02,0x12,0x42,0x20,0x90,0x9e,0x1c,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x25,0xe0, +0x25,0xe0,0x90,0x9e,0x1b,0xf0,0x12,0x24,0x62,0x25,0xe0,0x25,0xe0,0x90,0x9e,0x1f, +0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x2a,0xf0,0x90,0x05,0x61,0xe0,0x90,0x9e,0x2b, +0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x2c,0xf0,0x90,0x05,0x63,0xe0,0x90,0x9e,0x2d, +0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x3f,0xf0,0xc2,0xaf,0x90,0x9e,0x1b,0xe0,0xff, +0xd1,0xd8,0x90,0x9e,0x3f,0xe0,0x24,0xff,0x92,0xaf,0x90,0x9e,0x1c,0xe0,0x70,0x02, +0x81,0x84,0x90,0x9e,0x1b,0xe0,0x70,0x02,0x81,0x84,0x90,0x9e,0x1f,0xe0,0x70,0x02, +0x81,0x84,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x3f,0xf0,0xc2,0xaf,0x90,0x9e,0x2e,0x74, +0x01,0xf0,0x90,0x9e,0x3f,0xe0,0x24,0xff,0x92,0xaf,0x51,0xb8,0x90,0x00,0x46,0xe0, +0x44,0x01,0xfd,0x7f,0x46,0x51,0xc1,0x90,0x9e,0x14,0xe0,0x60,0x15,0x90,0x9e,0x20, +0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08, +0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f, +0x45,0x51,0xc1,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x9e,0x2a,0xe0,0x90,0x05, +0x84,0xf0,0x90,0x9e,0x2b,0xe0,0x90,0x05,0x85,0xf0,0x90,0x9e,0x2c,0xe0,0x90,0x05, +0x86,0xf0,0x90,0x9e,0x2d,0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x9e, +0x3f,0xf0,0xc2,0xaf,0x90,0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d,0x20,0xe4,0xff,0x12, +0x31,0xb7,0x80,0x2b,0x90,0x9e,0x1c,0xe0,0x70,0x2d,0x90,0x9e,0x2e,0x51,0xb7,0x90, +0x00,0x46,0xe0,0x54,0xfe,0xfd,0x7f,0x46,0x51,0xc1,0x90,0x05,0x22,0xe4,0xf0,0xa2, +0xaf,0x33,0x90,0x9e,0x3f,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff,0x12,0x31,0x49,0x90, +0x9e,0x3f,0xe0,0x24,0xff,0x92,0xaf,0x22,0x8b,0x59,0x8a,0x5a,0x89,0x5b,0x90,0x00, +0x02,0x12,0x42,0x20,0x90,0x9e,0x1d,0xf0,0xe0,0x30,0xe0,0x4b,0x90,0x9e,0x14,0x74, +0x01,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x22,0x65,0x90,0x9e,0x16,0x12,0x25,0x08,0xab, +0x59,0xaa,0x5a,0xa9,0x5b,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xe4,0xfc,0xfd,0xfe, +0x78,0x1a,0x12,0x24,0xf5,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x9e,0x16, +0x12,0x43,0x53,0xec,0x54,0x03,0xfc,0x12,0x43,0x46,0x90,0x9e,0x20,0x12,0x25,0x08, +0x90,0x05,0x22,0xe4,0xf0,0x80,0x2d,0xe4,0x90,0x9e,0x14,0xf0,0x7f,0x80,0x7e,0x08, +0x12,0x22,0x65,0xec,0x54,0x03,0xfc,0xec,0x44,0xc0,0xfc,0x90,0x9e,0x16,0x12,0x25, +0x08,0x90,0x9e,0x16,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e, +0x08,0x12,0x2b,0x08,0x90,0x9e,0x1d,0xe0,0x30,0xe1,0x19,0x7d,0x0c,0x7f,0x47,0x51, +0xc1,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x51,0xc1,0x90,0x00,0x46,0xe0, +0x44,0x10,0x80,0x1c,0x90,0x00,0x47,0xe0,0x54,0xf3,0xfd,0x7f,0x47,0x51,0xc1,0x90, +0x00,0x48,0xe0,0x54,0xf3,0xfd,0x7f,0x48,0x51,0xc1,0x90,0x00,0x46,0xe0,0x54,0xef, +0xfd,0x7f,0x46,0x51,0xc1,0xe4,0x90,0x9e,0x1a,0xf0,0x22,0x90,0x01,0x3c,0x74,0xff, +0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01,0x34,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd, +0x7f,0x54,0x51,0xc1,0x7d,0xff,0x7f,0x55,0x51,0xc1,0x7d,0xff,0x7f,0x56,0x51,0xc1, +0x7d,0xff,0x7f,0x57,0x41,0xc1,0x90,0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3, +0xf0,0x90,0x01,0x38,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0x51,0xc1, +0xe4,0xfd,0x7f,0x51,0x51,0xc1,0xe4,0xfd,0x7f,0x52,0x51,0xc1,0xe4,0xfd,0x7f,0x53, +0x41,0xc1,0xe5,0x22,0x64,0x01,0x70,0x3c,0xf1,0xbe,0xbf,0x01,0x05,0x7f,0x01,0x12, +0x44,0xf1,0x90,0x00,0x46,0xe0,0x44,0x04,0xfd,0x7f,0x46,0x51,0xc1,0x90,0x00,0x44, +0xe0,0x54,0xfb,0xfd,0x7f,0x44,0x51,0xc1,0x90,0x00,0x46,0xe0,0x54,0xfb,0xfd,0x7f, +0x46,0x51,0xc1,0x7f,0x02,0xf1,0xea,0x8f,0x26,0x90,0x01,0xc9,0xe5,0x26,0xf0,0xb4, +0x01,0x02,0xf1,0x2a,0x22,0x90,0x9e,0x1c,0xe0,0x64,0x01,0x60,0x02,0xc1,0xd7,0x90, +0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x51,0xc1,0x90,0x9e,0x2e,0xe0,0x70,0x31, +0x90,0x9e,0x14,0xe0,0x60,0x15,0x90,0x9e,0x20,0x12,0x43,0x53,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x80,0x06,0x90,0x05,0x22,0x74,0x7f, +0xf0,0x90,0x9e,0x1b,0xe0,0xff,0xd1,0xd8,0x90,0x9e,0x2e,0x74,0x01,0x51,0xb7,0x80, +0x3f,0x90,0x9e,0x2e,0xe0,0x64,0x01,0x70,0x37,0x90,0x9e,0x1f,0xe0,0xff,0xd1,0xd8, +0xe4,0x90,0x9e,0x2e,0xf0,0x90,0x00,0x45,0xe0,0x44,0x01,0xfd,0x7f,0x45,0x51,0xc1, +0x90,0x9e,0x14,0xe0,0x60,0x15,0x90,0x9e,0x16,0x12,0x43,0x53,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x80,0x05,0x90,0x05,0x22,0xe4,0xf0, +0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x9e,0x2a,0xe0,0x90,0x05,0x84,0xf0,0x90, +0x9e,0x2b,0xe0,0x90,0x05,0x85,0xf0,0x90,0x9e,0x2c,0xe0,0x90,0x05,0x86,0xf0,0x90, +0x9e,0x2d,0xe0,0x90,0x05,0x87,0xf0,0x22,0x90,0x05,0x60,0xe0,0x90,0x9e,0x2a,0xf0, +0x90,0x05,0x61,0xe0,0x90,0x9e,0x2b,0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x2c,0xf0, +0x90,0x05,0x63,0xe0,0x90,0x9e,0x2d,0xf0,0xc3,0x74,0xff,0x9f,0xfe,0x90,0x9e,0x2b, +0xe0,0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0,0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3, +0xe0,0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90,0x9e,0x2d,0x80,0x03,0x90,0x9e,0x2c,0xe0, +0x04,0xf0,0x22,0x90,0x9e,0x2b,0xe0,0x2f,0xf0,0x22,0x90,0x00,0x49,0xe0,0x90,0x9e, +0xb1,0xf0,0xe0,0x54,0x0f,0xf0,0x44,0xf0,0xfd,0x7f,0x49,0x51,0xc1,0x90,0x9e,0xb1, +0xe0,0x44,0xb0,0xfd,0x7f,0x49,0x41,0xc1,0x8e,0x59,0x8f,0x5a,0x8b,0x5b,0x8a,0x5c, +0x89,0x5d,0xe4,0x90,0x9e,0x34,0xf0,0xef,0x90,0x00,0x31,0xf0,0x31,0xb9,0xe5,0x59, +0x54,0x03,0xff,0x90,0x00,0x32,0xe0,0x54,0xfc,0x4f,0xf0,0x31,0xb9,0x90,0x00,0x33, +0xe0,0x54,0x7f,0xf0,0x31,0xb9,0x90,0x00,0x33,0xe0,0x20,0xe7,0x0e,0x90,0x9e,0x34, +0xe0,0xc3,0x94,0x64,0x50,0x05,0xe0,0x04,0xf0,0x80,0xeb,0x90,0x9e,0x34,0xe0,0xc3, +0x94,0x64,0x50,0x10,0x90,0x00,0x30,0xe0,0xab,0x5b,0xaa,0x5c,0xa9,0x5d,0x12,0x42, +0x4d,0x7f,0x01,0x22,0x7f,0x00,0x22,0x12,0x45,0xb1,0xbf,0x01,0x10,0x90,0x02,0x09, +0xe0,0xff,0x7d,0x01,0x12,0x47,0xfe,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x7f,0x0b, +0xf1,0xea,0xef,0x65,0x25,0x60,0x10,0xe5,0x25,0xb4,0x01,0x05,0xe4,0xf5,0x25,0x80, +0x03,0x75,0x25,0x01,0x7f,0x01,0x22,0x7f,0x00,0x22,0xe4,0x90,0x9e,0x74,0xf0,0x90, +0x00,0x80,0xe0,0x44,0x80,0xfd,0x7f,0x80,0x41,0xc1,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0x90,0x9e,0xb2,0xef,0xf0,0xd3,0x94,0x07,0x50,0x47,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0xe0,0x5f,0xf0, +0x12,0x49,0xb9,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80, +0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0,0xfb,0xe4,0xfe, +0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff, +0x80,0x44,0x90,0x9e,0xb2,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08, +0x80,0x02,0xc3,0x33,0xd8,0xfc,0x12,0x49,0xb1,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01, +0x7e,0x00,0xa8,0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90, +0x00,0x42,0xe0,0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7, +0x13,0xce,0x13,0xd8,0xf8,0xff,0xd0,0xd0,0x92,0xaf,0x22,0x75,0x28,0x33,0xe4,0xf5, +0x29,0x75,0x2a,0x03,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3,0xe5,0x29,0xf0, +0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0xe4,0x90,0x9e,0x31,0xf0,0xa3,0xf0, +0x75,0x8e,0x02,0x12,0x4f,0xda,0x12,0x5f,0xa9,0x12,0x5f,0xbc,0xe4,0xf5,0x12,0x12, +0x6f,0xa1,0x12,0x77,0x5d,0x12,0x60,0x9b,0x12,0x2e,0x01,0x12,0x77,0x18,0x11,0x8b, +0x90,0x00,0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41,0x74,0x10,0xf0,0x90,0x05,0x5a, +0xf0,0xa3,0xe4,0xf0,0x12,0x5f,0xf4,0x12,0x5f,0x91,0x12,0x44,0xfe,0x12,0x7d,0x1d, +0x90,0x9e,0x33,0xe5,0xd9,0xf0,0x12,0x4d,0x8b,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44, +0x40,0xf0,0x12,0x49,0xb9,0x75,0xe8,0x03,0x43,0xa8,0x85,0xd2,0xaf,0x90,0x01,0xbe, +0xe0,0x04,0xf0,0x90,0x01,0xc0,0xe0,0x04,0xf0,0x90,0x9e,0x31,0xe0,0x64,0x01,0xf0, +0x24,0xa9,0x90,0x01,0xc4,0xf0,0x74,0x50,0xa3,0xf0,0xe5,0x12,0x30,0xe4,0x09,0xc2, +0xaf,0x53,0x12,0xef,0xd2,0xaf,0x31,0x8e,0xe5,0x12,0x30,0xe6,0x17,0xc2,0xaf,0x53, +0x12,0xbf,0xd2,0xaf,0x12,0x69,0x51,0x90,0x9e,0x1e,0xe0,0xff,0x60,0x03,0xb4,0x01, +0x03,0x12,0x7d,0x7b,0x90,0x9e,0x1e,0xe0,0x70,0x03,0x12,0x7e,0x7e,0x31,0x61,0x80, +0xb8,0x90,0x06,0x34,0xe0,0x60,0x26,0x14,0x70,0x1b,0x7b,0x01,0x7a,0x06,0x79,0x35, +0x7f,0xf9,0x7e,0x01,0x12,0x4f,0x48,0xbf,0x01,0x09,0x90,0x06,0x35,0xe0,0x54,0x0f, +0xf0,0x80,0x05,0x80,0x00,0x02,0x77,0x0a,0xe4,0x90,0x06,0x34,0xf0,0x22,0x90,0x01, +0xcc,0xe0,0x54,0x0f,0x90,0x9e,0x34,0xf0,0x90,0x9e,0x34,0xe0,0xfd,0x70,0x02,0x41, +0xcf,0x90,0x9e,0xae,0xe0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3, +0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70,0x02,0x41,0xc8,0x90,0x9e,0xae, +0xe0,0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x35,0xf0,0x75, +0x1e,0x01,0x75,0x1f,0x9e,0x75,0x20,0x35,0x75,0x21,0x01,0x7b,0x01,0x7a,0x9e,0x79, +0x36,0x12,0x45,0x09,0x90,0x9e,0x36,0xe0,0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x90, +0x9e,0xae,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90,0x00,0x88,0x12,0x43,0x5f,0xe0, +0x90,0x9e,0x37,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x02,0x90,0x00,0x89,0x12,0x43, +0x5f,0xe0,0x90,0x9e,0x38,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1, +0x12,0x43,0x5f,0xe0,0x90,0x9e,0x39,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90, +0x01,0xd2,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x3a,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0, +0x04,0x90,0x01,0xd3,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x3b,0xf0,0x80,0x33,0xe0,0x75, +0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x37,0xf0,0x90,0x9e,0xae, +0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x38,0xf0,0x90, +0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x39, +0xf0,0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x9e,0x79,0x37,0x51,0xd0,0x90,0x9e,0x34, +0xe0,0xff,0x90,0x9e,0xae,0xe0,0xfe,0x74,0x01,0xa8,0x06,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0x5f,0x90,0x9e,0x34,0xf0,0x90,0x9e,0xae,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01,0xcc,0xf0,0x90,0x9e,0xae,0xe0, +0x04,0xf0,0xe0,0x54,0x03,0xf0,0x21,0x98,0x90,0x01,0xc6,0xe0,0x44,0x02,0xf0,0x22, +0x90,0x9e,0x3c,0x12,0x43,0x8b,0xef,0x12,0x43,0x94,0x53,0x0b,0x01,0x53,0x14,0x02, +0x53,0x2f,0x03,0x53,0x38,0x05,0x53,0x41,0x06,0x53,0x8f,0x07,0x53,0x49,0x09,0x53, +0x52,0x0c,0x53,0x5b,0x0d,0x53,0x64,0x0e,0x53,0x6d,0x1b,0x53,0x76,0x1c,0x53,0x7f, +0x2c,0x53,0x1d,0x2d,0x53,0x26,0x2e,0x00,0x00,0x53,0x88,0x90,0x9e,0x3c,0x12,0x43, +0x6b,0x02,0x61,0x9d,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x71,0xc4,0x90,0x9e,0x3c, +0x12,0x43,0x6b,0x02,0x71,0xca,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x72,0x12,0x90, +0x9e,0x3c,0x12,0x43,0x6b,0x02,0x72,0x40,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x71, +0x74,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x80,0x47,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02, +0x72,0x88,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x4b,0x7e,0x90,0x9e,0x3c,0x12,0x43, +0x6b,0x02,0x7c,0xea,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x4c,0xb8,0x90,0x9e,0x3c, +0x12,0x43,0x6b,0x02,0x71,0xbc,0x90,0x9e,0x3c,0x12,0x43,0x6b,0x02,0x71,0xa3,0x90, +0x9e,0x3c,0x12,0x43,0x6b,0x02,0x75,0xea,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22, +0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x1f,0xfe,0xef,0x54,0x20,0xc4,0x13,0x54, +0x07,0xfd,0xaf,0x06,0x90,0x9e,0x3f,0xef,0xf0,0xa3,0xed,0xf0,0xa3,0x12,0x43,0x8b, +0x90,0x9e,0x41,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0xf0,0xc4,0x54, +0x0f,0x90,0x9e,0x44,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0x54,0x40,0xc4,0x13,0x13, +0x54,0x03,0x90,0x9e,0x45,0xf0,0x90,0x9e,0x3f,0xe0,0xff,0x75,0xf0,0x09,0x90,0x96, +0x46,0x12,0x43,0x5f,0xad,0x82,0xac,0x83,0x90,0x9e,0x46,0xec,0xf0,0xa3,0xed,0xf0, +0xef,0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74,0x96,0x35,0xf0,0xfa,0x7b,0x01,0xa3, +0x12,0x43,0x8b,0x90,0x9e,0x41,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54, +0x0f,0xff,0x90,0x9e,0x48,0x12,0x43,0x6b,0xef,0x12,0x42,0x4d,0x90,0x9e,0x41,0x12, +0x43,0x6b,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x90,0x9e,0x48,0x12,0x43,0x6b,0x90, +0x00,0x01,0xef,0x12,0x42,0x5f,0x90,0x9e,0x41,0x12,0x43,0x6b,0x90,0x00,0x01,0x12, +0x42,0x20,0xff,0x90,0x9e,0x46,0xe0,0xfc,0xa3,0xe0,0xfd,0xf5,0x82,0x8c,0x83,0xef, +0xf0,0x12,0x24,0x62,0x8d,0x82,0x8c,0x83,0xa3,0xf0,0x90,0x9e,0x44,0xe0,0xfe,0x90, +0x9e,0x3f,0xe0,0xff,0x24,0x82,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0x90, +0x9e,0x40,0xe0,0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4a,0x12,0x43,0x5f,0xee,0xf0, +0x75,0xf0,0x09,0xef,0x90,0x96,0x4b,0x12,0x43,0x5f,0x74,0x01,0xf0,0x90,0x9e,0x45, +0xe0,0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4c,0x12,0x43,0x5f,0xee,0xf0,0x8f,0x59, +0xef,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xaf,0x82,0xf5,0x5b,0x8f,0x5c, +0xe5,0x59,0x75,0xf0,0x02,0xa4,0x24,0x02,0xf9,0x74,0x95,0x35,0xf0,0x75,0x5d,0x01, +0xf5,0x5e,0x89,0x5f,0x75,0xf0,0x09,0xe5,0x59,0x90,0x96,0x46,0x12,0x43,0x5f,0xaf, +0x82,0x85,0x83,0x60,0x8f,0x61,0xe5,0x59,0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74, +0x96,0x35,0xf0,0x75,0x62,0x01,0xf5,0x63,0x89,0x64,0x74,0x82,0x25,0x59,0xf5,0x82, +0xe4,0x34,0x95,0xf5,0x83,0xe0,0x12,0x43,0x94,0x55,0x1e,0x00,0x55,0x33,0x01,0x55, +0x48,0x02,0x55,0x5d,0x03,0x55,0x86,0x04,0x55,0x9b,0x05,0x55,0xb0,0x06,0x55,0xd6, +0x0c,0x56,0x03,0x0d,0x56,0x30,0x0e,0x56,0x5d,0x0f,0x00,0x00,0x56,0x91,0xe5,0x59, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74, +0x15,0x80,0x3c,0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83, +0x74,0xf0,0xf0,0xa3,0x74,0x10,0x80,0x27,0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74,0x05,0x80,0x12,0xe5,0x59,0x25, +0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0xe4,0xf0, +0xe5,0x59,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0x74,0x0f,0xf0, +0xa3,0x74,0x8f,0xf0,0xc1,0x91,0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34, +0x9b,0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf5,0x80,0x27,0xe5,0x59,0x25,0xe0,0x24, +0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf0,0x80,0x12, +0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3, +0x74,0x0d,0xf0,0xe5,0x59,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83, +0xe4,0xf0,0xa3,0xf0,0xc1,0x91,0x90,0x04,0x47,0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f, +0x12,0x42,0x4d,0x90,0x04,0x46,0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x90,0x00,0x01, +0x12,0x42,0x5f,0x90,0x04,0x45,0xe0,0x85,0x5c,0x82,0x85,0x5b,0x83,0xf0,0x90,0x04, +0x44,0xc1,0x88,0x90,0x04,0x4b,0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x12,0x42,0x4d, +0x90,0x04,0x4a,0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x90,0x00,0x01,0x12,0x42,0x5f, +0x90,0x04,0x49,0xe0,0x85,0x5c,0x82,0x85,0x5b,0x83,0xf0,0x90,0x04,0x48,0x80,0x58, +0x90,0x04,0x4f,0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x12,0x42,0x4d,0x90,0x04,0x4e, +0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x4d, +0xe0,0x85,0x5c,0x82,0x85,0x5b,0x83,0xf0,0x90,0x04,0x4c,0x80,0x2b,0x90,0x04,0x53, +0xe0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0x12,0x42,0x4d,0x90,0x04,0x52,0xe0,0xab,0x5d, +0xaa,0x5e,0xa9,0x5f,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x51,0xe0,0x85,0x5c, +0x82,0x85,0x5b,0x83,0xf0,0x90,0x04,0x50,0xe0,0x85,0x5c,0x82,0x85,0x5b,0x83,0xa3, +0xf0,0xab,0x5d,0xaa,0x5e,0xa9,0x5f,0xc0,0x03,0xc0,0x02,0xc0,0x01,0x12,0x24,0x62, +0xff,0xab,0x62,0xaa,0x63,0xa9,0x64,0x12,0x24,0x62,0x5f,0xd0,0x01,0xd0,0x02,0xd0, +0x03,0x12,0x42,0x4d,0xab,0x5d,0xe5,0x5f,0x24,0x01,0xf9,0xe4,0x35,0x5e,0xfa,0xc0, +0x03,0xc0,0x02,0xc0,0x01,0x12,0x24,0x62,0xff,0xab,0x62,0xaa,0x63,0xa9,0x64,0x90, +0x00,0x01,0x12,0x42,0x20,0x5f,0xd0,0x01,0xd0,0x02,0xd0,0x03,0x12,0x42,0x4d,0x85, +0x5c,0x82,0x85,0x5b,0x83,0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x61,0x82,0x85,0x60, +0x83,0xe0,0xfe,0xef,0x5e,0xd0,0x82,0xd0,0x83,0xf0,0x85,0x5c,0x82,0x85,0x5b,0x83, +0xa3,0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x61,0x82,0x85,0x60,0x83,0xa3,0xe0,0xfe, +0xef,0x5e,0xd0,0x82,0xd0,0x83,0xf0,0xe5,0x59,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b,0x75,0x5a,0x0b,0x74,0x01, +0x7e,0x00,0xa8,0x5a,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5, +0x59,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0x5e,0xfe,0xa3, +0xe0,0x5f,0x4e,0x60,0x06,0xe5,0x5a,0x24,0x10,0x80,0x5d,0x15,0x5a,0xe5,0x5a,0xc3, +0x94,0x00,0x50,0xca,0x80,0x56,0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34, +0x9b,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3d,0x75,0x5a,0x0f,0x74,0x01,0x7e, +0x00,0xa8,0x5a,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5,0x59, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x60,0x08,0x90,0x9e,0x4b,0xe5,0x5a,0xf0,0x80,0x10,0x15,0x5a,0xe5,0x5a, +0xc3,0x94,0x00,0x50,0xc8,0x80,0x05,0xe4,0x90,0x9e,0x4b,0xf0,0xe5,0x59,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b, +0xe4,0xf5,0x5a,0x74,0x01,0x7e,0x00,0xa8,0x5a,0x08,0x80,0x05,0xc3,0x33,0xce,0x33, +0xce,0xd8,0xf9,0xff,0xe5,0x59,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5, +0x83,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x08,0x90,0x9e,0x4c,0xe5,0x5a,0xf0, +0x80,0x5b,0x05,0x5a,0xe5,0x5a,0xb4,0x10,0xca,0x80,0x52,0xe5,0x59,0x25,0xe0,0x24, +0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x39,0xe4, +0xf5,0x5a,0x74,0x01,0x7e,0x00,0xa8,0x5a,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce, +0xd8,0xf9,0xff,0xe5,0x59,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83, +0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x06,0xe5,0x5a,0x24,0x10,0x80,0x0a,0x05, +0x5a,0xe5,0x5a,0xb4,0x0c,0xcc,0x80,0x05,0xe4,0x90,0x9e,0x4c,0xf0,0x90,0x9e,0x4b, +0xe0,0xff,0x75,0xf0,0x09,0xe5,0x59,0x90,0x96,0x48,0x12,0x43,0x5f,0xef,0xf0,0x90, +0x9e,0x4c,0xe0,0xfe,0x75,0xf0,0x09,0xe5,0x59,0x90,0x96,0x49,0x12,0x43,0x5f,0xee, +0xf0,0x74,0x84,0x25,0x59,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0xd3,0x9f,0x40, +0x05,0x90,0x9e,0x4b,0x11,0xe0,0x74,0x84,0x25,0x59,0xf5,0x82,0xe4,0x34,0x04,0xf5, +0x83,0xe0,0xff,0x90,0x9e,0x4c,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x02,0x11,0xe0,0x90, +0x9e,0x4b,0xe0,0xff,0xd3,0x94,0x13,0x40,0x07,0x90,0x96,0x43,0x74,0x03,0xf0,0x22, +0xef,0xd3,0x94,0x0b,0x40,0x07,0x90,0x96,0x43,0x74,0x02,0xf0,0x22,0xef,0xd3,0x94, +0x03,0x40,0x07,0x90,0x96,0x43,0x74,0x01,0xf0,0x22,0xe4,0x90,0x96,0x43,0xf0,0x22, +0xe0,0xfd,0x74,0x26,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xed,0xf0,0xaf, +0x59,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xef,0xc3,0x94,0x20,0x50,0x0e,0x74,0x84, +0x2f,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xed,0xf0,0x80,0x29,0x74,0xa6,0x2f,0xf5, +0x82,0xe4,0x34,0x9c,0xf5,0x83,0xed,0xf0,0x90,0x9e,0x78,0xef,0xf0,0x24,0xa6,0xf5, +0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x90,0x9e,0x79,0xf0,0x7b,0x01,0x7a,0x9e,0x79, +0x78,0x7d,0x02,0x31,0x3a,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0x90,0x9e,0x97,0x12,0x43,0x8b,0x90,0x9e,0x9a,0xe0,0x54,0xf0,0x44,0x06,0xff, +0xf0,0xed,0x54,0x0f,0xc4,0x54,0xf0,0xfe,0xef,0x54,0x0f,0x4e,0xf0,0x90,0x9e,0x97, +0x12,0x43,0x6b,0x90,0x9e,0x94,0x12,0x43,0x8b,0x7b,0x01,0x7a,0x9e,0x79,0x9a,0xd1, +0x14,0xd0,0xd0,0x92,0xaf,0x22,0x8f,0x50,0x8d,0x51,0xe5,0x51,0x54,0x1f,0xf5,0x56, +0x74,0x01,0x2f,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe0,0xf5,0x54,0x90,0x04,0xfd, +0xe0,0xb4,0x01,0x05,0x75,0x57,0x03,0x80,0x03,0x75,0x57,0x01,0xeb,0xc3,0x95,0x57, +0x40,0x04,0xaf,0x50,0x80,0x33,0xe5,0x54,0x25,0x53,0xf5,0x55,0xe5,0x56,0x90,0x41, +0xd6,0x93,0xff,0xe5,0x55,0xd3,0x9f,0x74,0x01,0x40,0x11,0x25,0x50,0xf5,0x82,0xe4, +0x34,0x94,0xf5,0x83,0xe4,0xf0,0xad,0x51,0xaf,0x50,0x01,0xf1,0x25,0x50,0xf5,0x82, +0xe4,0x34,0x94,0xf5,0x83,0xe5,0x55,0xf0,0x22,0xad,0x07,0x75,0xf0,0x09,0xed,0x90, +0x96,0x48,0x12,0x43,0x5f,0xe0,0xff,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5, +0x83,0xe0,0x54,0x1f,0xf5,0x58,0xd3,0x9f,0x40,0x02,0x8f,0x58,0xe5,0x58,0x25,0xe0, +0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff, +0xe5,0x58,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93, +0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2, +0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0xaf,0x05,0xad,0x58, +0x11,0xf1,0xaf,0x58,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,0x45,0xf0,0x74,0x5a,0xa3,0xf0,0x90,0x01,0x34,0xe0, +0x55,0x28,0xf5,0x2c,0x90,0x01,0x36,0xe0,0x55,0x2a,0xf5,0x2e,0xa3,0xe0,0x55,0x2b, +0xf5,0x2f,0xe5,0x2c,0x20,0xe0,0x02,0x61,0xe1,0x90,0x01,0x34,0x74,0x01,0xf0,0x85, +0xd1,0x08,0x85,0xd2,0x09,0x85,0xd3,0x0a,0x85,0xd4,0x0b,0x85,0xd5,0x0c,0x85,0xd6, +0x0d,0x85,0xd7,0x0e,0x85,0xd9,0x0f,0xe5,0x0f,0x54,0x40,0xc3,0x13,0xff,0xe5,0x0e, +0x54,0x20,0x6f,0x70,0x02,0x61,0x93,0xe5,0x0f,0x30,0xe5,0x02,0x61,0x93,0xe5,0x0d, +0x54,0x3f,0xf5,0x4d,0xe5,0x08,0x54,0x3f,0xf5,0x4e,0xe5,0x0c,0x54,0x1f,0xff,0xe5, +0x4d,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12, +0x42,0x81,0xe5,0x0e,0x54,0x1f,0xff,0xe5,0x4d,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4, +0x34,0x93,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x4e,0xd3,0x94,0x04,0x40, +0x03,0x75,0x4e,0x04,0x75,0xf0,0x0a,0xe5,0x4d,0x90,0x90,0x00,0x12,0x43,0x5f,0x75, +0xf0,0x02,0xe5,0x4e,0x12,0x43,0x5f,0xe0,0xfe,0xa3,0xe0,0xff,0xe5,0x0e,0x54,0x1f, +0x2f,0xff,0xe4,0x3e,0xfe,0x75,0xf0,0x0a,0xe5,0x4d,0x90,0x90,0x00,0x12,0x43,0x5f, +0x75,0xf0,0x02,0xe5,0x4e,0x12,0x43,0x5f,0xee,0xf0,0xa3,0xef,0xf0,0xe5,0x0f,0x20, +0xe6,0x23,0xe5,0x0e,0x54,0x1f,0xff,0xe5,0x4d,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4, +0x34,0x98,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x0a,0x30,0xe7,0x34,0xaf, +0x4d,0x31,0xd9,0x80,0x2e,0xe5,0x0e,0x54,0x1f,0xff,0xe5,0x4d,0x25,0xe0,0x24,0x44, +0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x0a,0x30, +0xe7,0x11,0xe5,0x0a,0x54,0x7f,0xfd,0xe5,0x0e,0x54,0x1f,0xf5,0x53,0xab,0x4e,0xaf, +0x4d,0x31,0x76,0xe5,0x74,0x14,0x24,0xfd,0x50,0x02,0x80,0x45,0x90,0x9e,0x61,0xe0, +0x60,0x37,0x90,0x01,0x5b,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0,0xd1,0x05,0xef, +0x64,0x01,0x70,0x2d,0x90,0x9e,0x55,0xe0,0xf5,0x44,0x75,0x45,0x00,0xe4,0xfb,0xfd, +0x7f,0x58,0x7e,0x01,0x12,0x30,0x62,0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92, +0x74,0x01,0xf0,0x90,0x9e,0x5d,0xf0,0x80,0x08,0xd1,0x05,0xbf,0x01,0x03,0x12,0x44, +0xd3,0xe5,0x2c,0x30,0xe1,0x20,0x90,0x01,0x34,0x74,0x02,0xf0,0x85,0xd1,0x13,0x85, +0xd2,0x14,0x85,0xd3,0x15,0x85,0xd4,0x16,0x85,0xd5,0x17,0x85,0xd6,0x18,0x85,0xd7, +0x19,0x85,0xd9,0x1a,0xd1,0x9c,0xe5,0x2c,0x30,0xe3,0x06,0x90,0x01,0x34,0x74,0x08, +0xf0,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01,0x34,0x74,0x10,0xf0,0x43,0x12,0x10,0xe5, +0x2c,0x30,0xe5,0x26,0x90,0x01,0xcf,0xe0,0x30,0xe5,0x1f,0xe0,0x54,0xdf,0xf0,0x90, +0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00,0x75,0xe8,0x00,0x12,0x4d,0xb6,0x90,0x00, +0x03,0xe0,0x54,0xfb,0xf0,0x12,0x49,0xb9,0x80,0xfe,0xe5,0x2c,0x30,0xe6,0x06,0x90, +0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe1,0x3c,0x90,0x01,0x36,0x74,0x02,0xf0, +0x43,0x12,0x40,0x90,0x01,0x02,0xe0,0x54,0x03,0x64,0x01,0x70,0x29,0x90,0x01,0x37, +0xe0,0x30,0xe0,0x0a,0x74,0x01,0xf0,0x90,0x9e,0x66,0xe4,0xf0,0x80,0x18,0x90,0x9e, +0x66,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a,0x40,0x0c,0xe4,0xf0,0x90,0x04,0x19,0xe0, +0x30,0xe0,0x03,0x12,0x4f,0xa7,0xe5,0x2e,0x30,0xe0,0x12,0x90,0x9e,0x76,0x74,0x01, +0xf0,0x90,0x01,0x36,0xf0,0x12,0x64,0xfe,0x90,0x9e,0x76,0xe4,0xf0,0xe5,0x2e,0x30, +0xe2,0x78,0x90,0x01,0x36,0x74,0x04,0xf0,0x90,0x01,0xbd,0xe0,0x04,0xf0,0xe5,0x73, +0x64,0x01,0x70,0x66,0xe5,0x74,0x60,0x62,0xe5,0x74,0x64,0x02,0x60,0x06,0xe5,0x74, +0x64,0x05,0x70,0x27,0x90,0x06,0xab,0xe0,0x90,0x9e,0x50,0xf0,0x90,0x06,0xaa,0xe0, +0x90,0x9e,0x5f,0xf0,0x90,0x9e,0x50,0xe0,0x70,0x07,0x90,0x9e,0x5f,0xe0,0xff,0x80, +0x05,0x90,0x9e,0x50,0xe0,0xff,0x90,0x9e,0x50,0xef,0xf0,0x90,0x9e,0x52,0xe0,0x60, +0x03,0xe0,0x14,0xf0,0x90,0x9e,0x51,0xe4,0xf0,0x90,0x01,0x57,0xf0,0x90,0x01,0x3c, +0x74,0x02,0xf0,0x90,0x9e,0x63,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xef,0xf0,0xe5,0x74, +0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0x53,0xe5,0x2e,0x30,0xe3,0x28,0x90, +0x01,0x36,0x74,0x08,0xf0,0xe5,0x73,0x64,0x01,0x70,0x1c,0xe5,0x74,0x60,0x18,0x90, +0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x9e,0x89,0xe4,0x12,0x44, +0x52,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x2e,0x30,0xe4,0x2f,0x90,0x01,0x36,0x74, +0x10,0xf0,0xe5,0x73,0x64,0x01,0x70,0x23,0xe5,0x74,0x60,0x1f,0x90,0x01,0x57,0xe4, +0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x9e,0x62,0xe4,0xf0,0x90,0x9e,0x63,0xe0, +0x54,0xfd,0xf0,0xe0,0x54,0x07,0x70,0x03,0x12,0x44,0xd3,0xe5,0x2e,0x30,0xe5,0x1f, +0x90,0x01,0x36,0x74,0x20,0xf0,0xe5,0x73,0xb4,0x01,0x14,0xe5,0x74,0x60,0x10,0x90, +0x9e,0x61,0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xdc,0x80,0x03,0x12,0x44,0x80,0xe5, +0x2e,0x30,0xe6,0x1e,0x90,0x01,0x36,0x74,0x40,0xf0,0xe5,0x73,0xb4,0x01,0x13,0xe5, +0x74,0x60,0x0f,0x90,0x9e,0x63,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0x07,0x70,0x03,0x12, +0x44,0xd3,0xe5,0x2f,0x30,0xe1,0x08,0x90,0x01,0x37,0x74,0x02,0xf0,0xd1,0xbd,0x74, +0x45,0x04,0x90,0x01,0xc4,0xf0,0x74,0x5a,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,0x04,0x1b,0xe0,0x54,0x7f,0x64,0x7f,0x7f,0x01,0x60, +0x02,0x7f,0x00,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x91,0x12,0x43, +0x8b,0x90,0x9e,0x75,0xe0,0x64,0x02,0x60,0x6e,0x90,0x9e,0x75,0xe0,0x64,0x01,0x70, +0x66,0x90,0x9e,0xb0,0xe0,0xff,0x04,0xf0,0x90,0x9e,0x91,0x12,0x43,0x6b,0x90,0x00, +0x01,0xef,0x12,0x42,0x5f,0x7f,0xaf,0x7e,0x01,0xf1,0x3b,0xef,0x60,0x49,0x90,0x9e, +0x91,0x12,0x43,0x6b,0x8b,0x1e,0x8a,0x1f,0x89,0x20,0x75,0x21,0x02,0x7b,0x01,0x7a, +0x01,0x79,0xa0,0x12,0x45,0x09,0x90,0x9e,0x94,0x12,0x43,0x6b,0x8b,0x1e,0x8a,0x1f, +0x89,0x20,0x90,0x9e,0x91,0x12,0x43,0x6b,0x12,0x24,0x62,0xff,0xc4,0x54,0x0f,0xf5, +0x21,0x7b,0x01,0x7a,0x01,0x79,0xa2,0x12,0x45,0x09,0x90,0x01,0xaf,0x74,0xff,0xf0, +0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x9e,0x2f,0xe0, +0x54,0xf0,0x44,0x03,0xf0,0x54,0x0f,0x44,0x80,0xf0,0x7b,0x00,0x7a,0x00,0x79,0x13, +0x90,0x9e,0x94,0x12,0x43,0x8b,0x0b,0x7a,0x9e,0x79,0x2f,0xc1,0x14,0x7d,0x02,0x7f, +0x03,0x12,0x31,0x2c,0xe5,0x74,0x14,0x24,0xfd,0x50,0x02,0x80,0x23,0x90,0x9e,0x61, +0xe0,0x60,0x06,0x7d,0x01,0x7f,0x0c,0x80,0x0f,0x90,0x9e,0x5e,0xe0,0x54,0x0f,0xc3, +0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x1a,0xe4,0xff,0x12,0x48,0x8f, +0x22,0xd1,0x05,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x32, +0x90,0x9e,0x5d,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x24,0x90,0x9e, +0x5c,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x16,0x90,0x9e,0x60,0xe0, +0x54,0x0f,0xd3,0x94,0x04,0x40,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f, +0x01,0x22,0x90,0x01,0xb8,0x74,0x08,0xf0,0x7f,0x00,0x22,0xd3,0x10,0xaf,0x01,0xc3, +0xc0,0xd0,0x90,0x9e,0xa0,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0x90, +0x9e,0xa0,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90,0x9e, +0xa3,0xe0,0x94,0xe8,0x90,0x9e,0xa2,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6,0xe0, +0x44,0x10,0xf0,0x7f,0x00,0x80,0x15,0x90,0x9e,0xa2,0xe4,0x75,0xf0,0x01,0x12,0x42, +0x81,0x7f,0x0a,0x7e,0x00,0x12,0x32,0x15,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92,0xaf, +0x22,0x75,0x30,0x1f,0x75,0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0, +0xa3,0xe5,0x31,0xf0,0xa3,0xe5,0x32,0xf0,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x90, +0x9e,0x75,0x60,0x04,0x74,0x01,0xf0,0x22,0x74,0x02,0xf0,0x22,0x90,0x00,0xf3,0xe0, +0x30,0xe3,0x08,0x90,0x9e,0x77,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90,0x9e,0x77,0xf0, +0x90,0x9e,0x77,0xe0,0xb4,0x01,0x12,0x90,0x00,0xf2,0xe0,0x30,0xe7,0x0b,0x90,0x9e, +0x64,0x74,0xfd,0xf0,0xa3,0x74,0x33,0xf0,0x22,0x90,0x9e,0x64,0x74,0xfd,0xf0,0xa3, +0x74,0x2f,0xf0,0x22,0x90,0x01,0x64,0x74,0xa0,0xf0,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,0xfb,0xf0,0x74,0x5f, +0xa3,0xf0,0x53,0x91,0xef,0x90,0x00,0x51,0xe0,0xff,0x90,0x00,0x55,0xe0,0x5f,0xf5, +0x3d,0xe5,0x3d,0x30,0xe6,0x18,0x74,0x40,0xf0,0x90,0x9e,0x1d,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x0b,0x90,0x9e,0x1a,0xe0,0x60,0x05,0x7f,0x01,0x12,0x4a,0xd6,0xe5,0x3d, +0x30,0xe7,0x15,0x90,0x00,0x55,0x74,0x80,0xf0,0x90,0x9e,0x1d,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x05,0x7f,0x02,0x12,0x4a,0xd6,0x90,0x01,0xc4,0x74,0xfb,0xf0,0x74,0x5f, +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,0x8f,0x6b,0x8c, +0x6c,0x8d,0x6d,0x22,0x8f,0x6e,0x8c,0x6f,0x8d,0x70,0x22,0xe4,0xf5,0x73,0x90,0x9e, +0x63,0xf0,0xf5,0x74,0x90,0x9e,0x60,0x74,0x0c,0xf0,0x90,0x9e,0x5e,0xf0,0xe4,0x90, +0x9e,0x61,0xf0,0x90,0x9e,0x5d,0xf0,0x90,0x9e,0x5c,0xf0,0x90,0x9e,0x5f,0x04,0xf0, +0x90,0x9e,0x50,0xf0,0xe4,0x90,0x9e,0x62,0xf0,0x90,0x9e,0x52,0xf0,0x90,0x9e,0x5a, +0x74,0x07,0xf0,0xe4,0x90,0x9e,0x51,0xf0,0x90,0x9e,0x58,0xf0,0xa3,0x74,0x02,0xf0, +0x90,0x9e,0x56,0x14,0xf0,0xa3,0x74,0x03,0xf0,0x90,0x9e,0x55,0x74,0x14,0xf0,0x90, +0x9e,0x5b,0x74,0x05,0xf0,0xe4,0x90,0x9e,0x54,0xf0,0x90,0x9e,0x4f,0xf0,0x90,0x9e, +0x76,0xf0,0x22,0xe4,0x90,0x9e,0x62,0xf0,0x90,0x9e,0x51,0xf0,0x90,0x9e,0x63,0xf0, +0x22,0x8b,0x59,0x8a,0x5a,0x89,0x5b,0x31,0x03,0xab,0x59,0xaa,0x5a,0xa9,0x5b,0x12, +0x24,0x62,0xf5,0x74,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24,0x03,0x70, +0x40,0x7f,0x01,0x80,0x3a,0xab,0x59,0xaa,0x5a,0xa9,0x5b,0x90,0x00,0x02,0x12,0x42, +0x20,0xfd,0xe4,0xff,0x31,0x72,0x80,0x27,0xab,0x59,0xaa,0x5a,0xa9,0x5b,0x90,0x00, +0x02,0x12,0x42,0x20,0xfd,0x7f,0x01,0x31,0x72,0x1f,0x80,0x13,0xab,0x59,0xaa,0x5a, +0xa9,0x5b,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0x31,0x72,0xe4,0xff,0x31, +0xc6,0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x9e,0x5f,0x74,0x01,0xf0, +0x80,0x16,0xed,0x70,0x0a,0x90,0x9e,0x5b,0xe0,0x90,0x9e,0x5f,0xf0,0x80,0x05,0x90, +0x9e,0x5f,0xed,0xf0,0x90,0x9e,0x5f,0xe0,0x90,0x9e,0x50,0xf0,0x22,0xd3,0x10,0xaf, +0x01,0xc3,0xc0,0xd0,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x9e,0x61,0xf0,0x90,0x00, +0x03,0x12,0x42,0x20,0x90,0x9e,0x4f,0xf0,0x12,0x24,0x62,0x65,0x74,0x60,0x02,0x31, +0x11,0xd0,0xd0,0x92,0xaf,0x22,0xef,0x64,0x01,0x70,0x30,0x7d,0x7c,0x7f,0x02,0x12, +0x31,0x2c,0x7d,0x02,0x7f,0x03,0x12,0x31,0x2c,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01, +0x3c,0x74,0x02,0xf0,0x12,0x47,0x16,0xe4,0xff,0x12,0x48,0x8f,0x90,0x06,0x04,0xe0, +0x54,0x7f,0xf0,0x90,0x06,0x0a,0xe0,0x54,0xf8,0xf0,0x22,0x90,0x01,0x36,0x74,0x7c, +0xf0,0xa3,0x74,0x02,0xf0,0x7d,0x7c,0xff,0x12,0x31,0x9d,0x7d,0x02,0x7f,0x03,0x12, +0x31,0x9d,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a,0xe0,0x44,0x07,0xf0, +0x90,0x9e,0x58,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0xe5,0x73,0x30,0xe0,0x1b,0x90, +0x9e,0x52,0xe0,0x70,0x1a,0xe0,0x04,0xf0,0x90,0x9e,0x5e,0xe0,0x54,0x0f,0xc3,0x94, +0x04,0x50,0x0c,0x7d,0x01,0x7f,0x04,0x02,0x47,0x1a,0xe4,0x90,0x9e,0x52,0xf0,0x22, +0x12,0x5e,0x05,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x52, +0x90,0x9e,0x63,0xe0,0x54,0x03,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x42, +0x90,0x9e,0x60,0xe0,0x54,0x0f,0xd3,0x94,0x02,0x40,0x08,0x90,0x01,0xb9,0x74,0x04, +0xf0,0x80,0x2f,0x90,0x9e,0x63,0xe0,0x30,0xe2,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0, +0x80,0x20,0x90,0x9e,0x63,0xe0,0x30,0xe4,0x08,0x90,0x01,0xb9,0x74,0x10,0xf0,0x80, +0x11,0x90,0x9e,0x52,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x20,0xf0,0x80,0x03,0x7f, +0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0,0x7f,0x00,0x22,0xe5,0x12,0x60,0x08,0x90, +0x01,0xb9,0x74,0x01,0xf0,0x80,0x5e,0x90,0x9e,0x60,0xe0,0x54,0x0f,0xd3,0x94,0x01, +0x40,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4b,0x90,0x02,0x87,0xe0,0x60,0x08, +0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x3d,0x90,0x9e,0x75,0xe0,0xb4,0x02,0x10,0x90, +0x9e,0x64,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x17,0x80,0x26,0x90, +0x9e,0x75,0xe0,0xb4,0x01,0x0e,0x90,0x01,0xaf,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74, +0x08,0xf0,0x80,0x11,0x90,0x9e,0x54,0xe0,0x70,0x08,0x90,0x01,0xb9,0x74,0x10,0xf0, +0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74,0x02,0xf0,0x7f,0x00,0x22,0x90,0x06, +0x04,0xe0,0x54,0xbf,0xf0,0xef,0x60,0x09,0xe5,0x73,0xb4,0x01,0x04,0xe4,0xff,0x71, +0x4d,0x90,0x9e,0x5e,0xe0,0x54,0xf0,0xf0,0xe0,0x44,0x0c,0xf0,0x22,0x8f,0x76,0x90, +0x9e,0x5e,0xe0,0x90,0x01,0xc1,0xf0,0xa3,0xe5,0x12,0xf0,0x12,0x45,0xb1,0xef,0x64, +0x01,0x70,0x2e,0x90,0x9e,0x69,0x12,0x47,0xfa,0xe5,0x76,0x60,0x10,0x74,0x21,0x2f, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x80,0x0e,0x74,0x21,0x2f, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x90,0x04,0x1f,0x74,0x20, +0xf0,0x22,0x90,0x9e,0xaf,0xef,0xf0,0x71,0xb0,0x90,0x9e,0xaf,0xe0,0x60,0x05,0x90, +0x05,0x22,0xe4,0xf0,0x90,0x9e,0x5e,0xe0,0x54,0xf0,0xf0,0xe0,0x44,0x04,0xf0,0x22, +0x90,0x00,0x11,0xe0,0x44,0x09,0xf0,0x12,0x49,0xb9,0x90,0x9d,0xff,0x12,0x43,0x53, +0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x78,0x7e,0x08,0x12,0x2b,0x08,0x90,0x9e,0x03, +0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08, +0x90,0x9e,0x07,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08, +0x12,0x2b,0x08,0x90,0x9e,0x0b,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f, +0x70,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x68,0x12,0x25,0x14,0x00,0x03,0x2d,0x95, +0xe4,0xfd,0xff,0x12,0x30,0x2c,0x90,0x9e,0x77,0xe0,0xb4,0x01,0x11,0x90,0x80,0x68, +0x12,0x25,0x14,0x00,0x03,0x2d,0x95,0xe4,0xfd,0x7f,0x01,0x12,0x30,0x2c,0x22,0x8f, +0x27,0xe4,0x90,0x9e,0xa8,0xf0,0xa3,0xf0,0x90,0x01,0x09,0xe0,0x7f,0x00,0x30,0xe7, +0x02,0x7f,0x01,0xef,0x65,0x27,0x60,0x3e,0xc3,0x90,0x9e,0xa9,0xe0,0x94,0x88,0x90, +0x9e,0xa8,0xe0,0x94,0x13,0x40,0x08,0x90,0x01,0xc6,0xe0,0x44,0x80,0xf0,0x22,0x90, +0x9e,0xa8,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x7f,0x14,0x7e,0x00,0x12,0x32,0x15, +0xd3,0x90,0x9e,0xa9,0xe0,0x94,0x32,0x90,0x9e,0xa8,0xe0,0x94,0x00,0x40,0xb9,0x90, +0x01,0xc7,0xe0,0x30,0xe0,0xb2,0x22,0x90,0x9e,0x5e,0xe0,0x54,0xf0,0xf0,0xe0,0x44, +0x01,0xf0,0x12,0x44,0xff,0x12,0x45,0x00,0xe0,0x54,0xf0,0xf0,0xe0,0x44,0x02,0xf0, +0x22,0x90,0x9e,0x60,0xe0,0x30,0xe6,0x1c,0xe0,0x54,0x0f,0xff,0x90,0x9e,0x4e,0xe0, +0xfe,0x4f,0x90,0x01,0x2f,0xf0,0xee,0x64,0x80,0x90,0x9e,0x4e,0xf0,0x90,0x9e,0x60, +0xe0,0x54,0xbf,0xf0,0x22,0x8f,0x75,0x12,0x45,0xb1,0xef,0x64,0x01,0x70,0x2e,0x90, +0x9e,0x6a,0x12,0x47,0xfa,0xe5,0x75,0x60,0x10,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x80,0x0e,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0xe4,0x90, +0x9e,0x2f,0xf0,0xe5,0x74,0x60,0x6a,0xe5,0x73,0x64,0x01,0x70,0x64,0xe5,0x74,0x14, +0x60,0x29,0x24,0xfd,0x60,0x25,0x24,0x02,0x24,0xfb,0x50,0x02,0x80,0x23,0x90,0x9e, +0x50,0xe0,0x14,0xf0,0xe0,0x60,0x04,0xa3,0xe0,0x60,0x16,0x90,0x9e,0x50,0xe0,0x70, +0x0a,0x90,0x9e,0x5f,0xe0,0x90,0x9e,0x50,0xf0,0x80,0x00,0x90,0x9e,0x2f,0x74,0x01, +0xf0,0x90,0x9e,0x2f,0xe0,0x60,0x2a,0x90,0x9e,0x63,0xe0,0x44,0x10,0xf0,0xe4,0x90, +0x9e,0x89,0xf0,0x90,0x9e,0x5a,0x12,0x44,0x56,0x90,0x01,0x57,0x74,0x05,0xf0,0x90, +0x9e,0x5e,0xe0,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47, +0x1a,0x22,0xef,0xc3,0x94,0x20,0x50,0x39,0xef,0x30,0xe0,0x17,0xed,0xc4,0x54,0xf0, +0xfd,0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x54, +0x0f,0x80,0x10,0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83, +0xe0,0x54,0xf0,0xf0,0x74,0xa4,0x2e,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x4d, +0xf0,0x22,0xad,0x07,0xed,0xc3,0x94,0x20,0x50,0x0d,0x74,0x84,0x2d,0xf5,0x82,0xe4, +0x34,0x04,0xf5,0x83,0xe0,0x80,0x0b,0x74,0xa6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5, +0x83,0xe0,0x54,0x7f,0xf5,0x64,0xe5,0x64,0x54,0x1f,0xfc,0x75,0xf0,0x09,0xed,0x90, +0x96,0x48,0x12,0x43,0x5f,0xe0,0xff,0x90,0x9e,0x3e,0xf0,0xed,0x25,0xe0,0x24,0x02, +0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x3f,0xcb,0xf0, +0xa3,0xeb,0xf0,0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0, +0xfb,0xa3,0xe0,0x90,0x9e,0x41,0xcb,0xf0,0xa3,0xeb,0xf0,0xec,0x25,0xe0,0x24,0x66, +0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xe4,0x93,0xfa,0x74,0x01,0x93,0xfb,0xed,0x25, +0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xea,0xf0,0xa3,0xeb,0xf0,0xec, +0xc3,0x9f,0x40,0x02,0xc1,0xc9,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83, +0xec,0xf0,0x04,0xfb,0x90,0x9e,0x3e,0xe0,0xff,0xeb,0xd3,0x9f,0x40,0x02,0xc1,0xfa, +0xeb,0xc3,0x94,0x10,0x40,0x21,0xeb,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07, +0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x3f,0xe0,0x5e, +0xfe,0xa3,0xe0,0x5f,0x4e,0x70,0x23,0xeb,0xc3,0x94,0x10,0x50,0x39,0x74,0x01,0x7e, +0x00,0xa8,0x03,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e, +0x41,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x1c,0xeb,0x64,0x13,0x60,0x08,0xeb, +0x64,0x12,0x60,0x03,0xbb,0x11,0x09,0x90,0x9e,0x3f,0xe0,0x30,0xe0,0x02,0x7b,0x18, +0xac,0x03,0x8c,0x64,0x80,0x34,0x0b,0x80,0x8b,0x90,0x9e,0x3e,0xe0,0xfb,0x6c,0x70, +0x69,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xec,0xf0,0x75,0xf0,0x09, +0xed,0x90,0x96,0x4a,0x12,0x43,0x5f,0xe0,0xb4,0x01,0x0c,0xe5,0x64,0x20,0xe6,0x07, +0xec,0x44,0x40,0xf5,0x64,0x80,0x03,0xaf,0x64,0x22,0xec,0x25,0xe0,0x24,0x9e,0xf5, +0x82,0xe4,0x34,0x41,0xf5,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25,0xe0, +0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93, +0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34, +0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x80,0x5b,0xec,0xd3,0x9b,0x40,0x56,0x90, +0x9e,0x3e,0xe0,0xff,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef,0xf0, +0xac,0x07,0x8f,0x64,0xec,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83, +0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34, +0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13, +0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3, +0xef,0xf0,0xaf,0x64,0x22,0x74,0x01,0x2d,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe4, +0xf0,0xaf,0x05,0xe5,0x64,0x44,0x80,0xfd,0x12,0x58,0xf1,0xe5,0x64,0x44,0x80,0xff, +0x22,0xac,0x07,0xec,0xc3,0x94,0x20,0x50,0x0d,0x74,0x84,0x2c,0xf5,0x82,0xe4,0x34, +0x04,0xf5,0x83,0xe0,0x80,0x0b,0x74,0xa6,0x2c,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83, +0xe0,0x54,0x7f,0xf5,0x64,0xe5,0x64,0x54,0x1f,0xff,0x90,0x9e,0x40,0xf0,0x75,0xf0, +0x09,0xec,0x90,0x96,0x49,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x42,0xf0,0x75,0xf0,0x09, +0xec,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0,0xfe,0x90,0x9e,0x43,0xf0,0xec,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x44, +0xcb,0xf0,0xa3,0xeb,0xf0,0xec,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5, +0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x46,0xcb,0xf0,0xa3,0xeb,0xf0,0xef,0xd3,0x9e, +0x40,0x0a,0x90,0x9e,0x43,0xe0,0x90,0x9e,0x40,0xf0,0xf5,0x64,0xed,0x70,0x02,0x21, +0x07,0x90,0x9e,0x41,0xed,0xf0,0xe5,0x64,0x30,0xe6,0x0a,0x90,0x9e,0x40,0xe0,0xf5, +0x64,0xa3,0xe0,0x14,0xf0,0x90,0x9e,0x41,0xe0,0x70,0x02,0x21,0x07,0x90,0x9e,0x40, +0xe0,0xff,0xd3,0x94,0x00,0x50,0x02,0x21,0x07,0xe4,0x90,0x9e,0x3f,0xf0,0xef,0x14, +0x90,0x9e,0x3e,0xf0,0x90,0x9e,0x42,0xe0,0xfd,0x90,0x9e,0x3e,0xe0,0xff,0xd3,0x9d, +0x40,0x6b,0xef,0x94,0x10,0x40,0x21,0xef,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8, +0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x46,0xe0, +0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x70,0x27,0x90,0x9e,0x3e,0xe0,0xff,0xc3,0x94,0x10, +0x50,0x33,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce, +0xd8,0xf9,0xff,0x90,0x9e,0x44,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x16,0x90, +0x9e,0x3e,0xe0,0xf5,0x64,0xa3,0xe0,0x04,0xf0,0x90,0x9e,0x41,0xe0,0xff,0x90,0x9e, +0x3f,0xe0,0x6f,0x60,0x08,0x90,0x9e,0x3e,0xe0,0x14,0xf0,0x80,0x87,0x90,0x9e,0x41, +0xe0,0xff,0x90,0x9e,0x3f,0xe0,0xc3,0x9f,0x50,0x0d,0x90,0x9e,0x3e,0xe0,0xb5,0x05, +0x06,0x90,0x9e,0x42,0xe0,0xf5,0x64,0xe5,0x64,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4, +0x34,0x41,0xf5,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xe5,0x64,0x25,0xe0,0x24, +0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e, +0xc3,0x13,0xfe,0xef,0x13,0xff,0xec,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95, +0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0xaf,0x04,0xad,0x64,0x12,0x58,0xf1,0xaf,0x64, +0x22,0xe4,0xf5,0x59,0xe5,0x59,0xb4,0x20,0x14,0x90,0x9a,0xc5,0xe0,0x04,0xf0,0x90, +0x95,0x01,0xe0,0xff,0x90,0x9a,0xc5,0xe0,0xb5,0x07,0x02,0xe4,0xf0,0x75,0xf0,0x09, +0xe5,0x59,0x90,0x96,0x4b,0x12,0x43,0x5f,0xe0,0x64,0x01,0x60,0x02,0xe1,0x95,0xe5, +0x59,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xfe,0xa3,0xe0, +0xd3,0x94,0x00,0xee,0x94,0x00,0x50,0x02,0xe1,0x95,0xe5,0x59,0x94,0x20,0x40,0x08, +0x90,0x9a,0xc5,0xe0,0x60,0x02,0xe1,0xa0,0xe5,0x59,0x75,0xf0,0x0a,0xa4,0x24,0x00, +0xf9,0x74,0x90,0x35,0xf0,0x75,0x5e,0x01,0xf5,0x5f,0x89,0x60,0xe5,0x59,0x25,0xe0, +0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x9e,0x38, +0xcf,0xf0,0xa3,0xef,0xf0,0xe5,0x59,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x98, +0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x9e,0x3a,0xcf,0xf0,0xa3,0xef,0xf0,0xe5,0x59, +0xc3,0x94,0x20,0x50,0x14,0x74,0x84,0x25,0x59,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83, +0xe0,0x54,0x3f,0x90,0x9e,0x34,0xf0,0x80,0x12,0x74,0xa6,0x25,0x59,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe0,0x54,0x3f,0x90,0x9e,0x34,0xf0,0x90,0x9e,0x34,0xe0,0xfe, +0x54,0x1f,0xa3,0xf0,0x75,0xf0,0x09,0xe5,0x59,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0, +0x90,0x9e,0x3d,0xf0,0x74,0xe6,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0, +0xc3,0x94,0x05,0x40,0x02,0x81,0x6e,0x90,0x9e,0x3d,0xe0,0xff,0x90,0x9e,0x35,0xe0, +0x9f,0x40,0x13,0x90,0x9e,0x3d,0xe0,0x90,0x9e,0x35,0xf0,0xee,0x54,0x40,0xfe,0x90, +0x9e,0x34,0xf0,0xef,0x4e,0xf0,0x90,0x04,0xfd,0xe0,0x64,0x01,0x70,0x29,0x90,0x9e, +0x35,0xe0,0xff,0x90,0x41,0x4a,0x93,0xfe,0x74,0x44,0x25,0x59,0xf5,0x82,0xe4,0x34, +0x9a,0xf5,0x83,0xe0,0xc3,0x9e,0x40,0x06,0xef,0x90,0x40,0xda,0x80,0x30,0x90,0x9e, +0x35,0xe0,0x90,0x40,0xf6,0x80,0x27,0x90,0x9e,0x35,0xe0,0xff,0x90,0x41,0x4a,0x93, +0xfe,0x74,0x44,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xc3,0x9e,0x40, +0x06,0xef,0x90,0x41,0x12,0x80,0x07,0x90,0x9e,0x35,0xe0,0x90,0x41,0x2e,0x93,0x90, +0x9e,0x3c,0xf0,0x90,0x9e,0x3c,0xe0,0x75,0xf0,0x06,0xa4,0x24,0x50,0xf9,0x74,0x40, +0x35,0xf0,0x75,0x5b,0xff,0xf5,0x5c,0x89,0x5d,0x90,0x9e,0x34,0xe0,0x90,0x41,0xf2, +0x93,0xff,0xd3,0x90,0x9e,0x3b,0xe0,0x9f,0x90,0x9e,0x3a,0xe0,0x94,0x00,0x40,0x09, +0xe4,0xfd,0xaf,0x59,0x12,0x67,0xb1,0xe1,0x2c,0xe5,0x59,0x25,0xe0,0x24,0xc2,0xf5, +0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xf5,0x61,0xa3,0xe0,0xf5,0x62,0xab,0x5b,0xaa, +0x5c,0xa9,0x5d,0x12,0x24,0x62,0xff,0x7e,0x00,0xab,0x5e,0xaa,0x5f,0xa9,0x60,0x12, +0x42,0x97,0xfd,0xac,0xf0,0x12,0x24,0x7b,0xef,0x25,0x62,0xf5,0x62,0xee,0x35,0x61, +0xf5,0x61,0xab,0x5b,0xaa,0x5c,0xa9,0x5d,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x7e, +0x00,0xab,0x5e,0xaa,0x5f,0xa9,0x60,0x90,0x00,0x02,0x12,0x42,0xc2,0xfd,0xac,0xf0, +0x12,0x24,0x7b,0xef,0x25,0x62,0xf5,0x62,0xee,0x35,0x61,0xf5,0x61,0xab,0x5b,0xaa, +0x5c,0xa9,0x5d,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x5e,0xaa,0x5f, +0xa9,0x60,0x90,0x00,0x04,0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x24,0x7b,0xef,0x25, +0x62,0xf5,0x62,0xee,0x35,0x61,0xf5,0x61,0xab,0x5b,0xaa,0x5c,0xa9,0x5d,0x90,0x00, +0x03,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x5e,0xaa,0x5f,0xa9,0x60,0x90,0x00,0x06, +0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x24,0x7b,0xef,0x25,0x62,0xf5,0x62,0xee,0x35, +0x61,0xf5,0x61,0xab,0x5b,0xaa,0x5c,0xa9,0x5d,0x90,0x00,0x04,0x12,0x42,0x20,0xff, +0x7e,0x00,0xab,0x5e,0xaa,0x5f,0xa9,0x60,0x90,0x00,0x08,0x12,0x42,0xc2,0xfd,0xac, +0xf0,0x12,0x24,0x7b,0xef,0x25,0x62,0xf5,0x62,0xee,0x35,0x61,0xf5,0x61,0xab,0x5b, +0xaa,0x5c,0xa9,0x5d,0x90,0x00,0x05,0x12,0x42,0x20,0xff,0x7e,0x00,0x90,0x9e,0x38, +0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x24,0x7b,0xd3,0xe5,0x62,0x9f,0xe5,0x61,0x9e,0x40, +0x0c,0xe5,0x62,0x9f,0xf5,0x62,0xe5,0x61,0x9e,0xf5,0x61,0x80,0x05,0xe4,0xf5,0x61, +0xf5,0x62,0xe5,0x59,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe5, +0x61,0xf0,0xa3,0xe5,0x62,0xf0,0x90,0x9e,0x34,0xe0,0x25,0xe0,0x24,0x66,0xf5,0x82, +0xe4,0x34,0x41,0xf5,0x83,0xc3,0x74,0x01,0x93,0x95,0x62,0xe4,0x93,0x95,0x61,0x50, +0x07,0xaf,0x59,0x12,0x65,0xb2,0xe1,0x00,0x90,0x9e,0x34,0xe0,0x25,0xe0,0x24,0x9e, +0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xd3,0x74,0x01,0x93,0x95,0x62,0xe4,0x93,0x95, +0x61,0x50,0x02,0xe1,0x00,0x7d,0x01,0xaf,0x59,0x12,0x67,0xb1,0xe1,0x00,0x74,0xe6, +0x25,0x59,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xfc,0x64,0x05,0x60,0x02,0xc1, +0x09,0x90,0x96,0x43,0xe0,0xff,0xb4,0x03,0x0b,0x90,0x9e,0x35,0xe0,0xc3,0x94,0x19, +0x40,0x3d,0x80,0x2e,0xef,0xb4,0x02,0x0b,0x90,0x9e,0x35,0xe0,0xc3,0x94,0x11,0x40, +0x2e,0x80,0x1f,0x90,0x96,0x43,0xe0,0xff,0xb4,0x01,0x0b,0x90,0x9e,0x35,0xe0,0xc3, +0x94,0x0a,0x40,0x1b,0x80,0x0c,0xef,0x70,0x11,0x90,0x9e,0x35,0xe0,0xc3,0x94,0x03, +0x40,0x0d,0x90,0x9a,0x84,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90,0x9a,0x84,0xf0,0x74, +0x84,0x25,0x59,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x63,0x74,0x44,0x25, +0x59,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xc3,0x94,0x30,0x50,0x02,0xa1, +0xb6,0x90,0x9a,0x84,0xe0,0x64,0x01,0x60,0x02,0xa1,0xb6,0x74,0x85,0x25,0x59,0xf5, +0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0x64,0x0a,0x60,0x51,0xef,0x24,0x05,0xff,0xe4, +0x33,0xfe,0x74,0x41,0x25,0x59,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe0,0xfd,0xd3, +0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x32,0xed,0x24,0x05,0xff,0xe4,0x33, +0xfe,0x74,0x44,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xd3,0x9f,0xee, +0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x14,0x74,0x26,0x25,0x59,0xf5,0x82,0xe4,0x34, +0x9d,0xf5,0x83,0xe0,0xff,0x90,0x9e,0x35,0xe0,0x6f,0x60,0x3d,0x74,0x44,0x25,0x59, +0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xd3,0x94,0x42,0x40,0x05,0x75,0x63, +0x05,0x80,0x0e,0xef,0xd3,0x94,0x39,0x40,0x05,0x75,0x63,0x03,0x80,0x03,0x75,0x63, +0x01,0x74,0x41,0x25,0x59,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xef,0xf0,0x74,0x85, +0x25,0x59,0xf5,0x82,0xe4,0x34,0x9a,0x80,0x29,0x74,0xe6,0x25,0x59,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x85,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9a,0xf5, +0x83,0xe0,0x04,0xf0,0x80,0x10,0xe4,0xf5,0x63,0x74,0xe6,0x25,0x59,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x9e,0x35,0xe0,0xff,0x74,0x26,0x25,0x59,0xf5, +0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef,0xf0,0x74,0x84,0x25,0x59,0xf5,0x82,0xe4,0x34, +0x98,0xf5,0x83,0xe5,0x63,0xf0,0x75,0xf0,0x09,0xe5,0x59,0x90,0x96,0x4c,0x12,0x43, +0x5f,0xe0,0xb4,0x01,0x10,0xe4,0xf5,0x63,0x74,0xe6,0x25,0x59,0xf5,0x82,0xe4,0x34, +0x9c,0xf5,0x83,0xe4,0xf0,0xad,0x63,0xc1,0xfb,0xec,0x64,0x06,0x60,0x02,0xe1,0x00, +0xf5,0x61,0xf5,0x62,0x90,0x42,0x13,0x93,0xff,0x7e,0x00,0x90,0x9e,0x38,0xe0,0xfc, +0xa3,0xe0,0xfd,0x12,0x24,0x7b,0x90,0x9e,0x36,0xee,0xf0,0xa3,0xef,0xf0,0x74,0x84, +0x25,0x59,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x63,0xe4,0xf5,0x5a,0xab, +0x5e,0xaa,0x5f,0xa9,0x60,0x75,0xf0,0x02,0xe5,0x5a,0xa4,0xf5,0x82,0x85,0xf0,0x83, +0x12,0x42,0xc2,0xfd,0xac,0xf0,0xe5,0x5a,0x90,0x42,0x0e,0x93,0xff,0x7e,0x00,0x12, +0x24,0x7b,0xef,0x25,0x62,0xf5,0x62,0xee,0x35,0x61,0xf5,0x61,0xc3,0x90,0x9e,0x37, +0xe0,0x95,0x62,0x90,0x9e,0x36,0xe0,0x95,0x61,0x40,0x07,0x05,0x5a,0xe5,0x5a,0xb4, +0x05,0xbd,0xe5,0x5a,0xc3,0x13,0xf5,0x5a,0xe5,0x63,0xb4,0x01,0x06,0xe5,0x5a,0x70, +0x46,0x80,0x13,0xe5,0x63,0xb4,0x03,0x15,0xe5,0x5a,0x70,0x05,0x75,0x63,0x03,0x80, +0x39,0xe5,0x5a,0xb4,0x01,0x05,0x75,0x63,0x01,0x80,0x2f,0x80,0x2a,0xe5,0x63,0xb4, +0x05,0x28,0xe5,0x5a,0x70,0x05,0x75,0x63,0x05,0x80,0x0d,0xe5,0x5a,0xb4,0x01,0x05, +0x75,0x63,0x03,0x80,0x03,0x75,0x63,0x01,0xd3,0x90,0x9e,0x3b,0xe0,0x94,0x03,0x90, +0x9e,0x3a,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x63,0xd3,0x90,0x9e,0x3b,0xe0,0x94, +0x03,0x90,0x9e,0x3a,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x63,0x74,0x84,0x25,0x59, +0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe5,0x63,0xf0,0xfd,0xaf,0x59,0x12,0x65,0x72, +0x74,0xe6,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xd3,0x94,0x05,0x74, +0xe6,0x50,0x0e,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x04,0xf0,0x80, +0x0b,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0xab,0x5e,0xaa,0x5f, +0xa9,0x60,0xe4,0xf5,0xf0,0x12,0x42,0xfa,0xab,0x5e,0xaa,0x5f,0xa9,0x60,0x90,0x00, +0x02,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x04,0xe4,0xf5,0xf0,0x12,0x43,0x19, +0x90,0x00,0x06,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x08,0xe4,0xf5,0xf0,0x12, +0x43,0x19,0xe5,0x59,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe4, +0xf0,0xa3,0xf0,0xe5,0x59,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83, +0xe4,0xf0,0xa3,0xf0,0xe5,0x59,0x25,0xe0,0x24,0x44,0xf5,0x82,0xe4,0x34,0x99,0xf5, +0x83,0xe4,0xf0,0xa3,0xf0,0x05,0x59,0xe5,0x59,0xc3,0x94,0x40,0x50,0x02,0x21,0x54, +0x22,0x90,0x04,0x44,0x74,0x11,0xf0,0xa3,0x74,0xf0,0xf0,0xa3,0x74,0x0f,0xf0,0xa3, +0xe4,0xf0,0xfd,0x74,0xa4,0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe4,0xf0,0x0d, +0xbd,0x10,0xf0,0xe4,0x90,0x9a,0xc5,0xf0,0x90,0x95,0x01,0x04,0xf0,0xe4,0xfd,0x75, +0xf0,0x0a,0xed,0x90,0x90,0x00,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a, +0xed,0x90,0x90,0x02,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a,0xed,0x90, +0x90,0x04,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x06, +0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x08,0x12,0x43, +0x5f,0xe4,0xf0,0xa3,0xf0,0x74,0x26,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0x74, +0x13,0xf0,0x74,0x85,0x2d,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0,0x74,0x84, +0x2d,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xed,0x25,0xe0,0x24,0x80,0xf5, +0x82,0xe4,0x34,0x93,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xed,0x25,0xe0,0x24,0xc4,0xf5, +0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xed,0x25,0xe0,0x24,0xc4,0xf5, +0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xed,0x25,0xe0,0x24,0x44,0xf5, +0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xed,0x25,0xe0,0x24,0xc6,0xf5, +0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xed,0x25,0xe0,0x24,0x46,0xf5, +0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x74,0x86,0x2d,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x46,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83, +0xe4,0xf0,0x74,0xe6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x41, +0xc4,0x93,0xfe,0x74,0x01,0x93,0xff,0x90,0x41,0x8c,0x74,0x01,0x93,0x2f,0xff,0xe4, +0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x4b, +0x12,0x43,0x5f,0x74,0x01,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x4a,0x12,0x43,0x5f, +0x74,0x01,0xf0,0x74,0x82,0x2d,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0x74,0x0c,0xf0, +0x75,0xf0,0x09,0xed,0x90,0x96,0x46,0x12,0x43,0x5f,0x74,0xff,0xf0,0xa3,0xf0,0x75, +0xf0,0x09,0xed,0x90,0x96,0x44,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0x74,0x0f,0xf0,0x75, +0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0x74,0x13,0xf0,0x75,0xf0,0x09,0xed, +0x90,0x96,0x49,0x12,0x43,0x5f,0xe4,0xf0,0xed,0xc3,0x94,0x20,0x50,0x0f,0x74,0x84, +0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0x74,0x13,0xf0,0x80,0x0d,0x74,0xa6,0x2d, +0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0x74,0x13,0xf0,0x0d,0xed,0x64,0x40,0x60,0x03, +0x02,0x6f,0xcf,0x22,0x12,0x24,0x62,0xf5,0x59,0xc3,0x94,0x40,0x50,0x15,0x90,0x00, +0x02,0x12,0x42,0x20,0xff,0x74,0x44,0x25,0x59,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83, +0xef,0xf0,0x22,0xe5,0x59,0xb4,0x40,0x0a,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x96, +0x42,0xf0,0x22,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x3f,0xfe,0xef,0x54,0x80, +0xc4,0x13,0x13,0x13,0x54,0x01,0xfd,0xaf,0x06,0x02,0x53,0xa4,0x12,0x24,0x62,0x90, +0x95,0x01,0xf0,0x22,0x12,0x24,0x62,0xf5,0x73,0x22,0x90,0x00,0x02,0x12,0x42,0x20, +0xff,0x30,0xe0,0x25,0x12,0x24,0x62,0x90,0x9e,0x56,0xf0,0x90,0x00,0x01,0x12,0x42, +0x20,0x90,0x9e,0x57,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x55,0xf0,0x90,0x00, +0x03,0x12,0x42,0x20,0x90,0x9e,0x5b,0xf0,0x22,0x90,0x9e,0x56,0x74,0x01,0xf0,0x90, +0x9e,0x57,0x74,0x03,0xf0,0x90,0x9e,0x55,0x74,0x14,0xf0,0x90,0x9e,0x5b,0x74,0x05, +0xf0,0x22,0x12,0x24,0x62,0x30,0xe0,0x18,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x5a,0xf0, +0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x9e,0x58,0xe4,0xf0,0xa3,0xef,0xf0,0x22, +0x90,0x9e,0x5a,0x74,0x07,0xf0,0x90,0x9e,0x58,0xe4,0xf0,0xa3,0x74,0x02,0xf0,0x22, +0x90,0x02,0x09,0xe0,0xfd,0x12,0x24,0x62,0xfe,0xaf,0x05,0xed,0x2e,0x90,0x9e,0x67, +0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x68,0xf0,0x90,0x00, +0x02,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x69,0xf0,0x90,0x00,0x03,0x12,0x42, +0x20,0xff,0xed,0x2f,0x90,0x9e,0x6a,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0xae, +0x05,0xed,0x2f,0x90,0x9e,0x6b,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90, +0x9e,0x3f,0x12,0x43,0x8b,0x90,0x9e,0x3f,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42, +0xc2,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe,0x90,0x9e,0x3f,0x12,0x43,0x6b, +0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x43,0x19,0x12,0x24,0x62,0xff,0x60,0x2c,0xb5, +0x22,0x16,0x90,0x9e,0x3f,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42,0xc2,0x65,0x24, +0x70,0x04,0xe5,0x23,0x65,0xf0,0x60,0x23,0x90,0x9e,0x3f,0x12,0x43,0x6b,0x90,0x00, +0x01,0x12,0x42,0xc2,0xff,0xae,0xf0,0x71,0x00,0x80,0x10,0x90,0x9e,0x3f,0x12,0x43, +0x6b,0x12,0x24,0x62,0x65,0x22,0x60,0x03,0x12,0x44,0xca,0xd0,0xd0,0x92,0xaf,0x22, +0x90,0x9e,0x42,0xee,0xf0,0xa3,0xef,0xf0,0x75,0x22,0x01,0x8e,0x23,0xf5,0x24,0xe4, +0xfd,0x7f,0x0b,0x71,0x44,0xe4,0xfd,0x7f,0x02,0x71,0x44,0x12,0x4f,0xbe,0xe4,0xff, +0x12,0x44,0xf1,0xe4,0xf5,0x26,0x90,0x01,0xc9,0xe5,0x26,0xf0,0x90,0x9e,0x42,0xe0, +0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5,0x45,0x7d,0x01,0x7f,0x60,0x7e, +0x01,0x02,0x30,0x62,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x45,0xed,0xf0, +0x90,0x9e,0x44,0xef,0xf0,0xd3,0x94,0x07,0x50,0x4f,0xa3,0xe0,0x70,0x1a,0x90,0x9e, +0x44,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff, +0x90,0x00,0x47,0xe0,0x5f,0xf0,0x80,0x17,0x90,0x9e,0x44,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0,0x4f,0xf0,0x12, +0x49,0xb9,0x90,0x9e,0x44,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0x80,0x5a,0x90,0x9e,0x44,0xe0,0x24,0xf8,0xf0, +0xa3,0xe0,0x70,0x1d,0x90,0x9e,0x44,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x80, +0x1a,0x90,0x9e,0x44,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0x12,0x49,0xb9,0x90,0x9e, +0x44,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff, +0x90,0x00,0x43,0xe0,0x5f,0xf0,0x12,0x49,0xb9,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x6d,0xe0,0x90,0x9e,0x40,0xf0,0x90,0x9e,0x6e, +0xe0,0xf5,0x64,0xa3,0xe0,0xf5,0x65,0xe4,0xf5,0x61,0x74,0x70,0x25,0x61,0xf5,0x82, +0xe4,0x34,0x9e,0xf5,0x83,0xe0,0xff,0x74,0x66,0x25,0x61,0xf8,0xa6,0x07,0x05,0x61, +0xe5,0x61,0xb4,0x04,0xe5,0x90,0x9e,0x40,0xe0,0x12,0x43,0x94,0x74,0x6b,0x00,0x75, +0x93,0x01,0x74,0x71,0x02,0x74,0x71,0x03,0x74,0x71,0x04,0x75,0x93,0x05,0x75,0x63, +0x80,0x75,0x79,0x81,0x75,0x93,0x82,0x00,0x00,0x75,0x8f,0xaf,0x69,0xb1,0x9a,0xa1, +0x93,0x90,0x9e,0x40,0xe0,0xff,0xb4,0x02,0x08,0x90,0x9e,0x3f,0x74,0x01,0xf0,0x80, +0x0f,0xef,0x90,0x9e,0x3f,0xb4,0x03,0x05,0x74,0x02,0xf0,0x80,0x03,0x74,0x04,0xf0, +0xc3,0xe5,0x64,0x94,0x08,0x50,0x49,0xe4,0xf5,0x61,0x90,0x9e,0x3f,0xe0,0xff,0xe5, +0x61,0xc3,0x9f,0x40,0x02,0xa1,0x93,0xc3,0xe5,0x64,0x94,0x01,0x50,0x14,0xe5,0x61, +0x25,0x65,0xff,0xc3,0x74,0x03,0x95,0x61,0x24,0x66,0xf8,0xe6,0xfd,0x12,0x4a,0xc1, +0x80,0x1a,0xc3,0x74,0x03,0x95,0x61,0x24,0x66,0xf8,0xe6,0xff,0xe5,0x61,0x7c,0x00, +0x25,0x65,0xfd,0xec,0x35,0x64,0x8d,0x82,0xf5,0x83,0xef,0xf0,0x05,0x61,0x80,0xba, +0xc3,0xe5,0x64,0x94,0x10,0x40,0x02,0xa1,0x93,0x90,0x9e,0x40,0xe0,0x64,0x04,0x60, +0x02,0xa1,0x93,0xaf,0x67,0xfc,0xfd,0xfe,0x78,0x10,0x12,0x24,0xf5,0xc0,0x04,0xc0, +0x05,0xc0,0x06,0xc0,0x07,0xaf,0x66,0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x24,0xf5, +0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x43,0x46,0xc0,0x04,0xc0,0x05,0xc0, +0x06,0xc0,0x07,0xaf,0x68,0xe4,0xfc,0xfd,0xfe,0x78,0x08,0x12,0x24,0xf5,0xd0,0x03, +0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x43,0x46,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab, +0x07,0xaf,0x69,0xe4,0xfc,0xfd,0xfe,0x12,0x43,0x46,0xa3,0x12,0x25,0x08,0x90,0x9e, +0x41,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0xaf,0x65,0xae,0x64,0x12,0x2b, +0x08,0x80,0x30,0xe5,0x68,0x7f,0x00,0xfe,0xef,0x25,0x69,0xf5,0x63,0xe4,0x3e,0xf5, +0x62,0xaf,0x63,0xfe,0x12,0x32,0x15,0x80,0x1a,0xe5,0x68,0x7f,0x00,0xfe,0xef,0x25, +0x69,0xf5,0x63,0xe4,0x3e,0xf5,0x62,0xaf,0x63,0xfe,0x12,0x31,0x82,0x80,0x04,0x7f, +0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0x8f,0x6a,0xe4,0x90,0x9e,0x45, +0xf0,0xe5,0x6a,0x14,0xfe,0x90,0x9e,0x45,0xe0,0xff,0xc3,0x9e,0x50,0x0e,0xef,0x04, +0xfd,0x12,0x2d,0x4d,0x90,0x9e,0x45,0xe0,0x04,0xf0,0x80,0xe5,0xe5,0x6a,0x14,0xff, +0x7d,0xff,0x12,0x2d,0x4d,0x90,0x9e,0x45,0xe5,0x6a,0xf0,0x90,0x9e,0x45,0xe0,0xc3, +0x94,0xff,0x50,0x0f,0xe0,0xff,0x04,0xfd,0x12,0x2d,0x4d,0x90,0x9e,0x45,0xe0,0x04, +0xf0,0x80,0xe8,0xad,0x6a,0x7f,0xff,0x02,0x2d,0x4d,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0xe4,0xf5,0x5b,0x75,0x5c,0x04,0xf5,0x5d,0xf5,0x5f,0xf5,0x60,0x90,0x02,0x09, +0xe0,0xff,0x12,0x24,0x62,0xfe,0xef,0x2e,0xf5,0x5e,0x30,0xe0,0x08,0x75,0x59,0x00, +0x75,0x5a,0x80,0x80,0x05,0xe4,0xf5,0x59,0xf5,0x5a,0xe5,0x5e,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x74,0x20,0x25,0x5b,0xf5,0x5b,0xad,0x5a,0xe5,0x5b,0x2d,0xff,0x24,0x01, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x90,0x9e,0x6d,0xf0,0x74,0x02,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xfe,0xe5,0x5b,0x2d,0x24,0x03,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x24,0x00,0xff,0xe4,0x3e,0x90,0x9e,0x6e,0xf0,0xa3,0xef, +0xf0,0x7f,0x04,0xe5,0x5b,0x25,0x5a,0x2f,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfc,0xf5, +0x83,0xe0,0xfe,0x74,0x6c,0x2f,0xf5,0x82,0xe4,0x34,0x9e,0xf5,0x83,0xee,0xf0,0x0f, +0xbf,0x08,0xe0,0x91,0x0e,0xef,0x70,0x3f,0x90,0x01,0xc3,0xe0,0x60,0x25,0xc3,0xe5, +0x60,0x94,0xe8,0xe5,0x5f,0x94,0x03,0x40,0x09,0x90,0x01,0xc6,0xe0,0x44,0x10,0xf0, +0x80,0x63,0x05,0x60,0xe5,0x60,0x70,0x02,0x05,0x5f,0x7f,0x0a,0x7e,0x00,0x12,0x32, +0x15,0x80,0xd5,0x90,0x01,0xc6,0xe0,0x90,0x01,0xc3,0x30,0xe2,0x05,0x74,0xfe,0xf0, +0x80,0x43,0x74,0xff,0xf0,0x80,0x3e,0xe5,0x5b,0xb4,0x78,0x23,0xe4,0xf5,0x5b,0x05, +0x5e,0xe5,0x5a,0x64,0x80,0x45,0x59,0x70,0x06,0xf5,0x59,0xf5,0x5a,0x80,0x06,0x75, +0x59,0x00,0x75,0x5a,0x80,0xe5,0x5e,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x80,0x06,0x74, +0x08,0x25,0x5b,0xf5,0x5b,0xe5,0x5d,0x15,0x5d,0x70,0x02,0x15,0x5c,0xe5,0x5d,0x45, +0x5c,0x60,0x02,0xc1,0x28,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x06,0x34,0x74,0xff,0xf0, +0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x22,0xe4,0xf5,0x25,0x22,0xe4,0x90,0x9e,0xaa, +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,0x9e,0xab,0xe0,0x94,0xe8,0x90, +0x9e,0xaa,0xe0,0x94,0x03,0x40,0x03,0x7f,0x00,0x22,0x7f,0x32,0x7e,0x00,0x12,0x32, +0x15,0x90,0x9e,0xaa,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x80,0xc6,0x90,0x9e,0x77, +0xe0,0x90,0x9e,0x0f,0xf0,0x22,0xef,0x70,0x03,0x02,0x79,0x1e,0x90,0x9e,0x0f,0xe0, +0x60,0x03,0x02,0x7c,0xe9,0x90,0x9d,0xfb,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25, +0x08,0x7f,0x8c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x9d,0xa7,0x12,0x43,0x53,0x90,0x80, +0x96,0x12,0x25,0x08,0x7f,0x44,0x7e,0x08,0x12,0x2b,0x08,0x90,0x9d,0xab,0x12,0x43, +0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x5c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x9d, +0xaf,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x6c,0x7e,0x0e,0x12,0x2b, +0x08,0x90,0x9d,0xb3,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x70,0x7e, +0x0e,0x12,0x2b,0x08,0x90,0x9d,0xb7,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x74,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xbb,0x12,0x43,0x53,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x78,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xbf,0x12,0x43,0x53, +0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x7c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xc3, +0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x0e,0x12,0x2b,0x08, +0x90,0x9d,0xc7,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x84,0x7e,0x0e, +0x12,0x2b,0x08,0x90,0x9d,0xcb,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f, +0x88,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xcf,0x12,0x43,0x53,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x8c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xd3,0x12,0x43,0x53,0x90, +0x80,0x96,0x12,0x25,0x08,0x7f,0xd0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xd7,0x12, +0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xd4,0x7e,0x0e,0x12,0x2b,0x08,0x90, +0x9d,0xdb,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xd8,0x7e,0x0e,0x12, +0x2b,0x08,0x90,0x9d,0xdf,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xdc, +0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xe3,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25, +0x08,0x7f,0xe0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xe7,0x12,0x43,0x53,0x90,0x80, +0x96,0x12,0x25,0x08,0x7f,0xec,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x9d,0xeb,0x12,0x43, +0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x90,0x9d, +0xef,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x2b, +0x08,0x90,0x9d,0xf3,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x0c,0x7e, +0x09,0x12,0x2b,0x08,0x90,0x9d,0xf7,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x04,0x7e,0x08,0x12,0x2b,0x08,0x90,0x9e,0x0f,0x74,0x01,0xf0,0x22,0x90,0x9e, +0x0f,0xe0,0x64,0x01,0x60,0x02,0x81,0xe9,0x7f,0x8c,0x7e,0x08,0x12,0x22,0x65,0x90, +0x9d,0xfb,0x12,0x25,0x08,0x7f,0x44,0x7e,0x08,0x12,0x22,0x65,0x90,0x9d,0xa7,0x12, +0x25,0x08,0x7f,0x5c,0x7e,0x08,0x12,0x22,0x65,0x90,0x9d,0xab,0x12,0x25,0x08,0x7f, +0x6c,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xaf,0x12,0x25,0x08,0x7f,0x70,0x7e,0x0e, +0x12,0x22,0x65,0x90,0x9d,0xb3,0x12,0x25,0x08,0x7f,0x74,0x7e,0x0e,0x12,0x22,0x65, +0x90,0x9d,0xb7,0x12,0x25,0x08,0x7f,0x78,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xbb, +0x12,0x25,0x08,0x7f,0x7c,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xbf,0x12,0x25,0x08, +0x7f,0x80,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xc3,0x12,0x25,0x08,0x7f,0x84,0x7e, +0x0e,0x12,0x22,0x65,0x90,0x9d,0xc7,0x12,0x25,0x08,0x7f,0x88,0x7e,0x0e,0x12,0x22, +0x65,0x90,0x9d,0xcb,0x12,0x25,0x08,0x7f,0x8c,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d, +0xcf,0x12,0x25,0x08,0x7f,0xd0,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xd3,0x12,0x25, +0x08,0x7f,0xd4,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xd7,0x12,0x25,0x08,0x7f,0xd8, +0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xdb,0x12,0x25,0x08,0x7f,0xdc,0x7e,0x0e,0x12, +0x22,0x65,0x90,0x9d,0xdf,0x12,0x25,0x08,0x7f,0xe0,0x7e,0x0e,0x12,0x22,0x65,0x90, +0x9d,0xe3,0x12,0x25,0x08,0x7f,0xec,0x7e,0x0e,0x12,0x22,0x65,0x90,0x9d,0xe7,0x12, +0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x22,0x65,0x90,0x9d,0xeb,0x12,0x25,0x08,0x7f, +0x04,0x7e,0x0d,0x12,0x22,0x65,0x90,0x9d,0xef,0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09, +0x12,0x22,0x65,0x90,0x9d,0xf3,0x12,0x25,0x08,0x7f,0x04,0x7e,0x08,0x12,0x22,0x65, +0x90,0x9d,0xf7,0x12,0x25,0x08,0x7f,0x8c,0x7e,0x08,0x12,0x22,0x65,0x90,0x9e,0xa4, +0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xed,0x44,0xc0,0xfd,0xec,0x90,0x9e, +0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x8c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x01,0x00, +0x00,0x7f,0x44,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0xdb, +0x25,0xa4,0x7f,0x5c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20, +0xdb,0x25,0xa4,0x7f,0x6c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14, +0x20,0xdb,0x25,0xa4,0x7f,0x70,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25, +0x14,0x04,0x1b,0x25,0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12, +0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96, +0x12,0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80, +0x96,0x12,0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2b,0x08,0x90, +0x80,0x96,0x12,0x25,0x14,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2b,0x08, +0x90,0x80,0x96,0x12,0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2b, +0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12, +0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e, +0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e, +0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd8, +0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x1b,0x25,0xa4,0x7f, +0xdc,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x1b,0x25,0xa4, +0x7f,0xe0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x24,0xdb,0x25, +0xa4,0x7f,0xec,0x7e,0x0e,0x12,0x2b,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x22,0x65,0x90, +0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xe4,0xff,0xec,0x90,0x9e, +0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xef,0x44,0x11,0xff,0xec,0x90, +0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25, +0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x22,0x65,0x90, +0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xef,0x54,0xf0,0xff,0xec, +0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xef,0x44,0x01,0xff, +0xec,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x2b,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x22, +0x65,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xe4,0xff,0xec, +0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xef,0x44,0x11,0xff, +0xec,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x2b,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x22, +0x65,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0xed,0x54,0x0f, +0xfd,0xec,0x54,0xf0,0xfc,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90,0x9e,0xa4,0x12,0x43, +0x53,0xed,0x44,0x10,0xfd,0xec,0x44,0x01,0xfc,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90, +0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09,0x12, +0x2b,0x08,0x7f,0x04,0x7e,0x08,0x12,0x22,0x65,0x90,0x9e,0xa4,0x12,0x25,0x08,0x90, +0x9e,0xa4,0x12,0x43,0x53,0xef,0x54,0xf0,0xff,0xec,0x90,0x9e,0xa4,0x12,0x25,0x08, +0x90,0x9e,0xa4,0x12,0x43,0x53,0xef,0x44,0x01,0xff,0xec,0x90,0x9e,0xa4,0x12,0x25, +0x08,0x90,0x9e,0xa4,0x12,0x43,0x53,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e, +0x08,0x12,0x2b,0x08,0xe4,0x90,0x9e,0x0f,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20, +0x90,0x9e,0x1e,0xf0,0xe0,0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5, +0x59,0xc2,0xaf,0x90,0x00,0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x4a,0xc1,0x7d, +0x40,0x7f,0x01,0x12,0x31,0x66,0xe5,0x59,0x24,0xff,0x92,0xaf,0x22,0xe4,0xfd,0x7f, +0x45,0x12,0x4a,0xc1,0x90,0x04,0xfd,0xe4,0xf0,0xa3,0xf0,0x90,0x9e,0x1e,0xf0,0x90, +0x9e,0x24,0xf0,0x90,0x9e,0x27,0xf0,0x90,0x9e,0x25,0xf0,0x90,0x9e,0x28,0xf0,0x90, +0x9e,0x26,0xf0,0x90,0x9e,0x29,0xf0,0x90,0x9e,0x10,0x04,0xf0,0xe4,0xa3,0xf0,0xa3, +0xf0,0xa3,0xf0,0x90,0x9e,0x15,0xf0,0x90,0x9e,0x1a,0xf0,0x90,0x9e,0x1c,0xf0,0x90, +0x9e,0x2e,0xf0,0x90,0x9e,0x1f,0xf0,0x90,0x9e,0x1b,0xf0,0x90,0x9e,0x14,0xf0,0x90, +0x00,0x51,0xe0,0x44,0xc0,0xfd,0x7f,0x51,0x02,0x4a,0xc1,0x90,0x9e,0x15,0xe0,0xc3, +0x94,0x14,0x50,0x05,0xe0,0x04,0xf0,0xc1,0x33,0x90,0x9e,0x15,0xe0,0x64,0x14,0x60, +0x02,0xc1,0x33,0x90,0x9e,0x24,0xe0,0x70,0x25,0x90,0x9e,0x27,0xe0,0x70,0x1f,0x90, +0x9e,0x25,0xe0,0x70,0x19,0x90,0x9e,0x28,0xe0,0x70,0x13,0x90,0x9e,0x26,0xe0,0x70, +0x0d,0x90,0x9e,0x29,0xe0,0x70,0x07,0x90,0x04,0xfd,0xe0,0x54,0xfe,0xf0,0x90,0x9e, +0x24,0xe0,0x90,0x04,0x44,0xf0,0x90,0x9e,0x25,0xe0,0x90,0x04,0x45,0xf0,0x90,0x9e, +0x26,0xe0,0x90,0x04,0x46,0xf0,0xa3,0xe4,0xf0,0x90,0x9e,0x27,0xe0,0x90,0x04,0x48, +0xf0,0x90,0x9e,0x28,0xe0,0x90,0x04,0x49,0xf0,0x90,0x9e,0x29,0xe0,0x90,0x04,0x4a, +0xf0,0xa3,0xe4,0xf0,0x90,0x9e,0x10,0xe0,0x90,0x04,0x4c,0xf0,0x90,0x9e,0x11,0xe0, +0x90,0x04,0x4d,0xf0,0x90,0x9e,0x12,0xe0,0x90,0x04,0x4e,0xf0,0x90,0x9e,0x13,0xe0, +0x90,0x04,0x4f,0xf0,0xe4,0x90,0x9e,0x15,0xf0,0x90,0x9e,0x10,0x04,0xf0,0xe4,0xa3, +0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x9e,0x24,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3, +0xf0,0xa3,0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x34,0xf0,0x90,0x05,0x61,0xe0,0x90, +0x9e,0x35,0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x36,0xf0,0x90,0x05,0x63,0xe0,0x90, +0x9e,0x37,0xf0,0x90,0x9e,0x2d,0xe0,0xff,0x90,0x9e,0x37,0xe0,0xfe,0xd3,0x9f,0x50, +0x0b,0x90,0x9e,0x2d,0xe0,0xc3,0x9e,0xd3,0x94,0x01,0x40,0x11,0x90,0x9e,0x1b,0xe0, +0xb4,0x01,0x02,0x80,0x03,0x90,0x9e,0x1f,0xe0,0xff,0x12,0x4e,0xd8,0x22,0x90,0x9e, +0x2e,0xe0,0x64,0x01,0x60,0x08,0x90,0x9e,0x1c,0xe0,0x60,0x02,0xe1,0x55,0x90,0x9e, +0x10,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x3b,0x90,0x9e,0x11,0xe0, +0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x28,0x90,0x9e,0x12,0xe0,0xc3, +0x94,0xff,0x50,0x0a,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x11,0xf0,0x80,0x15,0x90,0x9e, +0x13,0xe0,0xc3,0x94,0xff,0x50,0x10,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x12,0xf0,0x90, +0x9e,0x11,0xf0,0x90,0x9e,0x10,0xf0,0x90,0x00,0x44,0xe0,0x54,0x0c,0x60,0x76,0xe0, +0x30,0xe2,0x32,0x90,0x9e,0x24,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80, +0x24,0x90,0x9e,0x25,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11, +0x90,0x9e,0x26,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x25, +0xf0,0x90,0x9e,0x24,0xf0,0x90,0x00,0x44,0xe0,0x30,0xe3,0x32,0x90,0x9e,0x27,0xe0, +0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x9e,0x28,0xe0,0xc3,0x94, +0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x9e,0x29,0xe0,0xc3,0x94,0xff, +0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x28,0xf0,0x90,0x9e,0x27,0xf0,0x90,0x04, +0xfd,0xe0,0x44,0x01,0xf0,0x22,0xf5,0x67,}; + +// =================== v84 UMC B Cut COMMON 2012-04-13 ===================== +u8 Rtl8192CUFwUMCBCutImgArray[UMCBCutImgArrayLength] = { +0xc2,0x88,0x02,0x00,0x54,0x00,0x01,0x00,0x04,0x13,0x11,0x08,0x26,0x3d,0x01,0x00, +0x58,0x97,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x50,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x57,0x91,0x00,0x00,0x00,0x00,0x00,0xa1,0xe8,0x00,0x00,0x00, +0x05,0x04,0x03,0x02,0x00,0x03,0x06,0x05,0x04,0x03,0x00,0x04,0x06,0x05,0x04,0x02, +0x00,0x04,0x08,0x07,0x06,0x04,0x00,0x06,0x0a,0x09,0x08,0x06,0x00,0x08,0x0a,0x09, +0x08,0x04,0x00,0x08,0x0a,0x09,0x08,0x02,0x00,0x08,0x0a,0x09,0x08,0x00,0x00,0x08, +0x12,0x11,0x10,0x08,0x00,0x10,0x1a,0x19,0x18,0x10,0x00,0x18,0x22,0x21,0x20,0x18, +0x00,0x20,0x22,0x21,0x20,0x10,0x00,0x20,0x22,0x21,0x20,0x08,0x00,0x20,0x22,0x21, +0x1c,0x08,0x00,0x20,0x22,0x21,0x14,0x08,0x00,0x20,0x22,0x20,0x18,0x08,0x00,0x20, +0x31,0x30,0x20,0x10,0x00,0x30,0x31,0x30,0x18,0x00,0x00,0x30,0x31,0x2f,0x10,0x10, +0x00,0x30,0x31,0x2c,0x10,0x10,0x00,0x30,0x31,0x28,0x10,0x00,0x00,0x30,0x31,0x20, +0x10,0x00,0x00,0x30,0x31,0x10,0x10,0x00,0x00,0x30,0x04,0x04,0x04,0x05,0x04,0x04, +0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x04,0x04, +0x05,0x05,0x05,0x05,0x06,0x06,0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x07,0x0a,0x0b, +0x0d,0x10,0x04,0x05,0x05,0x06,0x06,0x09,0x0c,0x11,0x08,0x08,0x09,0x09,0x0a,0x0c, +0x10,0x11,0x04,0x04,0x04,0x05,0x04,0x04,0x05,0x07,0x07,0x07,0x08,0x0a,0x04,0x04, +0x04,0x04,0x06,0x0a,0x0b,0x0d,0x05,0x05,0x07,0x07,0x08,0x0b,0x0d,0x0f,0x04,0x04, +0x04,0x05,0x07,0x07,0x09,0x09,0x0c,0x0e,0x10,0x12,0x04,0x04,0x05,0x05,0x06,0x0a, +0x11,0x13,0x09,0x09,0x09,0x09,0x0c,0x0e,0x11,0x13,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x24,0x26,0x2a,0x18,0x1a,0x1d,0x1f,0x21,0x27,0x29,0x2a,0x00,0x00, +0x00,0x1f,0x23,0x28,0x2a,0x2c,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x18, +0x00,0x24,0x00,0x30,0x00,0x48,0x00,0x60,0x00,0x90,0x00,0xc0,0x00,0xd8,0x00,0x50, +0x00,0x78,0x00,0xa0,0x00,0xc8,0x01,0x40,0x01,0x90,0x01,0xe0,0x02,0x30,0x01,0x2c, +0x01,0x40,0x01,0xe0,0x02,0xd0,0x03,0xe8,0x04,0xb0,0x06,0x40,0x07,0xd0,0x00,0x02, +0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x0c,0x00,0x12,0x00,0x18,0x00,0x24,0x00,0x30, +0x00,0x48,0x00,0x60,0x00,0x6c,0x00,0x28,0x00,0x3c,0x00,0x50,0x00,0x64,0x00,0xa0, +0x00,0xc8,0x00,0xf0,0x01,0x18,0x00,0x64,0x00,0xa0,0x00,0xf0,0x01,0x68,0x01,0xf4, +0x02,0x58,0x03,0x20,0x03,0xe8,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x04,0x04, +0x05,0x07,0x04,0x04,0x07,0x0a,0x0a,0x0c,0x0c,0x12,0x05,0x07,0x07,0x08,0x0b,0x12, +0x24,0x3c,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02, +0x03,0x04,0x05,0x06,0x07,0x08,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x20,0x1e, +0x1c,0x18,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a,0x83,0xe0,0xf5, +0xf0,0xa3,0xe0,0x22,0x50,0x06,0x87,0xf0,0x09,0xe7,0x19,0x22,0xbb,0xfe,0x07,0xe3, +0xf5,0xf0,0x09,0xe3,0x19,0x22,0x89,0x82,0x8a,0x83,0xe4,0x93,0xf5,0xf0,0x74,0x01, +0x93,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0, +0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8,0x86,0xf0,0x08,0xe6,0x22, +0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08,0xe2,0x22,0xe5,0x83,0x2a, +0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xbb,0x01,0x0a,0x89,0x82,0x8a, +0x83,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x06,0xf7,0x09,0xa7,0xf0,0x19,0x22,0xbb, +0xfe,0x06,0xf3,0xe5,0xf0,0x09,0xf3,0x19,0x22,0xf8,0xbb,0x01,0x11,0xe5,0x82,0x29, +0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x09, +0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb,0xfe,0x09,0xe9,0x25,0x82,0xc8, +0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee,0x4a,0xfe,0xed,0x49,0xfd,0xec, +0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xa4, +0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83,0x22,0xe0,0xfb,0xa3,0xe0,0xfa, +0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0,0xf9,0x25,0xf0,0xf0,0xe5,0x82, +0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0,0x22,0xeb,0xf0,0xa3,0xea,0xf0, +0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93, +0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74, +0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf,0x02,0x43,0xf8,0x02,0x48,0x29, +0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2,0x08,0xdf,0xf4, +0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33,0xc4,0x54,0x0f, +0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf,0xe4,0x80,0x0b, +0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x3d,0xe4,0x7e,0x01,0x93,0x60, +0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x9e,0x77, +0x00,0x41,0x9e,0xae,0x00,0x41,0x9e,0x54,0x80,0x41,0x9e,0xb0,0x00,0x00,0xf0,0x90, +0x9e,0x5d,0xe0,0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x54,0x7e,0x01,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x85,0xe0,0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5, +0x45,0x12,0x35,0xab,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01, +0x3c,0x74,0x08,0xf0,0xe4,0x90,0x9e,0x85,0xf0,0x90,0x9e,0x5b,0xe0,0x90,0x9e,0x86, +0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x5e,0x90,0x01,0x5f,0x74,0x05,0xf0, +0x90,0x06,0x92,0x74,0x02,0xf0,0x90,0x9e,0x63,0x14,0xf0,0xe5,0x61,0x54,0x0f,0xc3, +0x94,0x0c,0x50,0x03,0x12,0x54,0xe3,0x22,0x8f,0x82,0x8e,0x83,0xa3,0xa3,0xa3,0xe4, +0xf0,0x22,0xe4,0xf5,0x65,0x7f,0x60,0x7e,0x01,0x80,0xed,0x7d,0x01,0xaf,0x62,0x02, +0x54,0xe7,0xb1,0xb0,0xbf,0x01,0x12,0x90,0x9e,0x79,0xe0,0xff,0xe4,0xfd,0xf1,0x79, +0x12,0x5f,0xf7,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0xb1,0xb0,0xbf,0x01,0x0f,0x90, +0x02,0x09,0xe0,0xff,0x7d,0x01,0xf1,0x79,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x22, +0x22,0x22,0x00,0x02,0x45,0x03,0x02,0x45,0x06,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x8b,0x20,0x8a,0x21,0x89,0x22,0x90,0x9e,0x87,0x71,0x8b,0xab,0x23,0xaa,0x24,0xa9, +0x25,0x90,0x9e,0x8a,0x71,0x8b,0xaf,0x26,0x15,0x26,0xef,0x60,0x1b,0x90,0x9e,0x8a, +0xe4,0x75,0xf0,0x01,0x71,0x74,0x12,0x29,0xd9,0xff,0x90,0x9e,0x87,0xe4,0x75,0xf0, +0x01,0x71,0x74,0xef,0x51,0x4d,0x80,0xde,0xab,0x20,0xaa,0x21,0xa9,0x22,0xd0,0xd0, +0x92,0xaf,0x22,0x90,0x9e,0x11,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0x90,0x06,0xa9, +0xe0,0x90,0x9e,0x10,0xf0,0xe0,0x54,0xc0,0x70,0x08,0x53,0x64,0xfe,0x53,0x64,0xfd, +0x91,0xcb,0x90,0x9e,0x10,0xe0,0x30,0xe6,0x13,0x43,0x64,0x01,0x90,0x9e,0x66,0xe0, +0x64,0x02,0x60,0x04,0x91,0xd2,0x80,0x07,0x91,0x79,0x80,0x03,0x53,0x64,0xfe,0x90, +0x9e,0x10,0xe0,0x30,0xe7,0x16,0x43,0x64,0x02,0xe4,0x90,0x9e,0x85,0x91,0x4e,0x90, +0x01,0x57,0x74,0x05,0xf0,0x90,0x9e,0x67,0x74,0x01,0xf0,0x22,0x53,0x64,0xfd,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x01,0xc4,0x74,0xb0,0xf0,0x74,0x45,0xa3, +0xf0,0x90,0x04,0x1d,0xe0,0x60,0x1a,0x90,0x05,0x22,0xe0,0x54,0x90,0x60,0x07,0x90, +0x01,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7,0xe0,0x30,0xe1,0xe4,0x7f,0x00,0x80, +0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,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,0x75,0x13,0x00,0x90,0x01,0xc4,0x74,0xe8,0xf0,0x74,0x45, +0xa3,0xf0,0x53,0x91,0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5,0x34,0xa3,0xe0,0x55, +0x31,0xf5,0x35,0xa3,0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55,0x33,0xf5,0x37,0xe5, +0x34,0x30,0xe0,0x06,0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34,0x30,0xe1,0x09,0x90, +0x01,0x3c,0x74,0x02,0xf0,0x12,0x61,0xc9,0xe5,0x34,0x30,0xe2,0x38,0x90,0x01,0x3c, +0x74,0x04,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe0,0x24,0x90,0x9e,0x85,0xe4,0xf0,0x90, +0x9e,0x5b,0xe0,0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x91,0x5e, +0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80,0x07,0x90,0x9e, +0x64,0xe4,0xf0,0x91,0xcb,0xe5,0x34,0x30,0xe3,0x38,0x90,0x01,0x3c,0x74,0x08,0xf0, +0x90,0x06,0x92,0xe0,0x30,0xe1,0x24,0x90,0x9e,0x85,0xe4,0xf0,0x90,0x9e,0x5b,0xe0, +0x90,0x9e,0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x5e,0x90,0x01,0x5f, +0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x07,0x90,0x9e,0x63,0xe4,0xf0, +0x91,0xcb,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10,0xf0,0x12,0x4b,0xfb, +0xe5,0x34,0x30,0xe5,0x09,0x90,0x01,0x3c,0x74,0x20,0xf0,0x12,0x4c,0x3d,0xe5,0x35, +0x30,0xe0,0x44,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f,0xe0,0x44,0x7f,0xf0, +0x90,0x00,0x83,0xe0,0x54,0x0f,0xf5,0x13,0xb4,0x01,0x02,0x80,0x1c,0xe5,0x13,0xb4, +0x02,0x05,0x90,0x00,0x83,0x80,0x12,0xe5,0x13,0xb4,0x04,0x05,0x90,0x00,0x83,0x80, +0x08,0xe5,0x13,0xb4,0x0c,0x06,0x90,0x00,0x83,0xe0,0xf5,0x62,0x90,0x01,0xbb,0xe5, +0x62,0xf0,0x12,0x60,0xc0,0x91,0xcb,0xe5,0x35,0x30,0xe2,0x06,0x90,0x01,0x3d,0x74, +0x04,0xf0,0xe5,0x35,0x30,0xe4,0x06,0x90,0x01,0x3d,0x74,0x10,0xf0,0xe5,0x36,0x30, +0xe0,0x06,0x90,0x01,0x3e,0x74,0x01,0xf0,0xe5,0x36,0x30,0xe1,0x06,0x90,0x01,0x3e, +0x74,0x02,0xf0,0x74,0xe8,0x04,0x90,0x01,0xc4,0xf0,0x74,0x45,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,0x9e,0x98,0xef,0xf0,0xa3,0xed, +0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5,0x63,0x60,0x05,0xe4,0xff,0x12,0x54,0x97,0x90, +0x9e,0x98,0xe0,0x30,0xe0,0x09,0x90,0x9e,0x9a,0xe4,0xf0,0xa3,0x74,0x80,0xf0,0x90, +0x9e,0x98,0xe0,0xff,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x90,0x04,0x25,0xef,0xf0,0x90, +0x9e,0x99,0xe0,0x60,0x1f,0xa3,0xa3,0xe0,0xff,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xfc, +0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x44,0x80,0xf0,0x90,0x9e,0x9a,0xa3,0xe0,0xff,0xfd,0x24,0x08,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54, +0xf7,0xf0,0x90,0x9e,0x9a,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x75,0x28,0x33,0xe4,0xf5, +0x29,0x75,0x2a,0x07,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3,0xe5,0x29,0xf0, +0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0xe4,0x90,0x9e,0x16,0xf0,0xa3,0xf0, +0x75,0x8e,0x02,0xf1,0xa1,0xf1,0xe9,0x90,0x9e,0x7e,0xef,0xf0,0xf1,0xdd,0x90,0x9e, +0x80,0xef,0xf0,0xf1,0xf6,0x90,0x9e,0x75,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xf5,0x57, +0x12,0x6e,0x77,0xf1,0xd4,0x12,0x60,0x4b,0x12,0x32,0x3d,0xf1,0xc9,0x11,0x0b,0x12, +0x50,0x0e,0xf1,0xcd,0xf1,0xb1,0x12,0x44,0xff,0xf1,0x45,0x90,0x9e,0x18,0xe5,0xd9, +0xf0,0x11,0xd0,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44,0x40,0xf0,0xb1,0x45,0x75,0xe8, +0x03,0x43,0xa8,0x85,0xd2,0xaf,0x90,0x9e,0x16,0xe0,0x64,0x01,0xf0,0x24,0x29,0x90, +0x01,0xc4,0xf0,0x74,0x48,0xa3,0xf0,0xe5,0x57,0x30,0xe4,0x0a,0xc2,0xaf,0x53,0x57, +0xef,0xd2,0xaf,0x12,0x58,0x74,0xe5,0x57,0x30,0xe6,0x17,0xc2,0xaf,0x53,0x57,0xbf, +0xd2,0xaf,0x12,0x67,0xa1,0x90,0x9e,0x43,0xe0,0xff,0x60,0x03,0xb4,0x01,0x03,0x12, +0x7b,0x49,0x90,0x9e,0x43,0xe0,0x70,0x03,0x12,0x7c,0x4c,0x12,0x73,0x85,0x80,0xb6, +0x90,0x01,0x3c,0x74,0xff,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01,0x34,0xf0,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x54,0x31,0x05,0x7d,0xff,0x7f,0x55,0x31,0x05,0x7d, +0xff,0x7f,0x56,0x31,0x05,0x7d,0xff,0x7f,0x57,0x80,0x0a,0xf0,0x90,0x00,0x45,0xe0, +0x54,0xfe,0xfd,0x7f,0x45,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x8f,0x82,0x75,0x83, +0x00,0xed,0xf0,0xb1,0x45,0xd0,0xd0,0x92,0xaf,0x22,0xef,0x14,0x60,0x30,0x14,0x60, +0x66,0x24,0x02,0x60,0x02,0x21,0xc1,0x90,0x9e,0x3f,0x74,0x02,0xf0,0x90,0x00,0x48, +0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x31,0x05,0x90,0x00,0x47,0xe0,0x44,0x08,0xfd,0x7f, +0x47,0x31,0x05,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x80,0x71,0xe4,0x90, +0x9e,0x3f,0xf0,0x90,0x9e,0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x00,0x45,0xe0,0x44,0xef,0xfd,0x7f,0x45,0x31, +0x05,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x46,0xe0, +0x44,0x10,0xfd,0x7f,0x46,0x80,0x38,0x90,0x9e,0x3f,0x74,0x01,0xf0,0x90,0x9e,0x45, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9, +0x90,0x00,0x45,0xe0,0x44,0x20,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x45,0xe0,0x44, +0x10,0xfd,0x7f,0x45,0x31,0x05,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x31, +0x05,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x9e,0x41,0xf0,0x90,0x00,0x01,0x12, +0x42,0x20,0x25,0xe0,0x25,0xe0,0x90,0x9e,0x40,0xf0,0x12,0x29,0xd9,0x25,0xe0,0x25, +0xe0,0x90,0x9e,0x44,0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x4f,0xf0,0x90,0x05,0x61, +0xe0,0x90,0x9e,0x50,0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x51,0xf0,0x90,0x05,0x63, +0xe0,0x90,0x9e,0x52,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x90, +0x9e,0x40,0xe0,0xff,0x91,0xf0,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x90,0x9e, +0x41,0xe0,0x70,0x02,0x41,0xc8,0x90,0x9e,0x40,0xe0,0x70,0x02,0x41,0xc8,0x90,0x9e, +0x44,0xe0,0x70,0x02,0x41,0xc8,0xa2,0xaf,0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf, +0x90,0x9e,0x53,0x74,0x01,0xf0,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x11,0xfc, +0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x31,0x05,0x90,0x9e,0x39,0xe0,0x60, +0x15,0x90,0x9e,0x45,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e, +0x08,0x12,0x2f,0xd9,0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x00,0x45,0xe0, +0x54,0xef,0xfd,0x7f,0x45,0x31,0x05,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x9e, +0x4f,0xe0,0x90,0x05,0x84,0xf0,0x90,0x9e,0x50,0xe0,0x90,0x05,0x85,0xf0,0x90,0x9e, +0x51,0xe0,0x90,0x05,0x86,0xf0,0x90,0x9e,0x52,0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf, +0xe4,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x90,0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d, +0x20,0xe4,0xff,0x12,0x37,0x00,0x80,0x2b,0x90,0x9e,0x41,0xe0,0x70,0x2d,0x90,0x9e, +0x53,0x11,0xfb,0x90,0x00,0x46,0xe0,0x54,0xfe,0xfd,0x7f,0x46,0x31,0x05,0x90,0x05, +0x22,0xe4,0xf0,0xa2,0xaf,0x33,0x90,0x9e,0x24,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff, +0x12,0x36,0x92,0x90,0x9e,0x24,0xe0,0x24,0xff,0x92,0xaf,0x22,0x8b,0x14,0x8a,0x15, +0x89,0x16,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x9e,0x42,0xf0,0xe0,0x30,0xe0,0x4b, +0x90,0x9e,0x39,0x74,0x01,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0x3b, +0x12,0x2a,0x7f,0xab,0x14,0xaa,0x15,0xa9,0x16,0x90,0x00,0x01,0x12,0x42,0x20,0xff, +0xe4,0xfc,0xfd,0xfe,0x78,0x1a,0x12,0x2a,0x6c,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab, +0x07,0x90,0x9e,0x3b,0x12,0x43,0x53,0xec,0x54,0x03,0xfc,0x12,0x43,0x46,0x90,0x9e, +0x45,0x12,0x2a,0x7f,0x90,0x05,0x22,0xe4,0xf0,0x80,0x2d,0xe4,0x90,0x9e,0x39,0xf0, +0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0xec,0x54,0x03,0xfc,0xec,0x44,0xc0,0xfc,0x90, +0x9e,0x3b,0x12,0x2a,0x7f,0x90,0x9e,0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x42,0xe0,0x30,0xe1,0x19,0x7d, +0x0c,0x7f,0x47,0x31,0x05,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x31,0x05, +0x90,0x00,0x46,0xe0,0x44,0x10,0x80,0x1c,0x90,0x00,0x47,0xe0,0x54,0xf3,0xfd,0x7f, +0x47,0x31,0x05,0x90,0x00,0x48,0xe0,0x54,0xf3,0xfd,0x7f,0x48,0x31,0x05,0x90,0x00, +0x46,0xe0,0x54,0xef,0xfd,0x7f,0x46,0x31,0x05,0xe4,0x90,0x9e,0x3f,0xf0,0x22,0x90, +0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01,0x38,0xf0,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0x31,0x05,0xe4,0xfd,0x7f,0x51,0x31,0x05,0xe4, +0xfd,0x7f,0x52,0x31,0x05,0xe4,0xfd,0x7f,0x53,0x21,0x05,0xe5,0x65,0x64,0x01,0x70, +0x3b,0xd1,0x85,0xbf,0x01,0x04,0x7f,0x01,0xd1,0x79,0x90,0x00,0x46,0xe0,0x44,0x04, +0xfd,0x7f,0x46,0x31,0x05,0x90,0x00,0x44,0xe0,0x54,0xfb,0xfd,0x7f,0x44,0x31,0x05, +0x90,0x00,0x46,0xe0,0x54,0xfb,0xfd,0x7f,0x46,0x31,0x05,0x7f,0x02,0xd1,0xa1,0x8f, +0x69,0x90,0x01,0xc9,0xe5,0x69,0xf0,0xb4,0x01,0x02,0xd1,0x19,0x22,0x90,0x9e,0x41, +0xe0,0x64,0x01,0x60,0x02,0x81,0xef,0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46, +0x31,0x05,0x90,0x9e,0x53,0xe0,0x70,0x31,0x90,0x9e,0x39,0xe0,0x60,0x15,0x90,0x9e, +0x45,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f, +0xd9,0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x9e,0x40,0xe0,0xff,0x91,0xf0, +0x90,0x9e,0x53,0x74,0x01,0x11,0xfb,0x80,0x3f,0x90,0x9e,0x53,0xe0,0x64,0x01,0x70, +0x37,0x90,0x9e,0x44,0xe0,0xff,0x91,0xf0,0xe4,0x90,0x9e,0x53,0xf0,0x90,0x00,0x45, +0xe0,0x44,0x01,0xfd,0x7f,0x45,0x31,0x05,0x90,0x9e,0x39,0xe0,0x60,0x15,0x90,0x9e, +0x3b,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f, +0xd9,0x80,0x05,0x90,0x05,0x22,0xe4,0xf0,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90, +0x9e,0x4f,0xe0,0x90,0x05,0x84,0xf0,0x90,0x9e,0x50,0xe0,0x90,0x05,0x85,0xf0,0x90, +0x9e,0x51,0xe0,0x90,0x05,0x86,0xf0,0x90,0x9e,0x52,0xe0,0x90,0x05,0x87,0xf0,0x22, +0x90,0x05,0x60,0xe0,0x90,0x9e,0x4f,0xf0,0x90,0x05,0x61,0xe0,0x90,0x9e,0x50,0xf0, +0x90,0x05,0x62,0xe0,0x90,0x9e,0x51,0xf0,0x90,0x05,0x63,0xe0,0x90,0x9e,0x52,0xf0, +0xc3,0x74,0xff,0x9f,0xfe,0x90,0x9e,0x50,0xe0,0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0, +0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3,0xe0,0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90, +0x9e,0x52,0x80,0x03,0x90,0x9e,0x51,0xe0,0x04,0xf0,0x22,0x90,0x9e,0x50,0xe0,0x2f, +0xf0,0x22,0xe0,0x5f,0xf0,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x7f,0x10,0xdf,0xfe, +0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x2a,0xed, +0xf0,0x90,0x9e,0x29,0xef,0xf0,0xd3,0x94,0x07,0x50,0x4e,0xa3,0xe0,0x70,0x1a,0x90, +0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4, +0xff,0x90,0x00,0x47,0xe0,0x5f,0xf0,0x80,0x17,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0,0x4f,0xf0, +0xb1,0x45,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0x80,0x59,0x90,0x9e,0x29,0xe0,0x24,0xf8,0xf0, +0xa3,0xe0,0x70,0x1d,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x80, +0x1a,0x90,0x9e,0x29,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0xb1,0x45,0x90,0x9e,0x29, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90, +0x00,0x43,0xb1,0x42,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x49,0xe0,0x90,0x9e,0xb1, +0xf0,0xe0,0x54,0x0f,0xf0,0x44,0xf0,0xfd,0x7f,0x49,0x31,0x05,0x90,0x9e,0xb1,0xe0, +0x44,0xb0,0xfd,0x7f,0x49,0x21,0x05,0x90,0x9e,0x27,0xee,0xf0,0xa3,0xef,0xf0,0x75, +0x65,0x01,0x8e,0x66,0xf5,0x67,0xe4,0xfd,0x7f,0x0b,0xb1,0x55,0xe4,0xfd,0x7f,0x02, +0xb1,0x55,0xd1,0x85,0xe4,0xff,0xd1,0x79,0xe4,0xf5,0x69,0x90,0x01,0xc9,0xe5,0x69, +0xf0,0x90,0x9e,0x27,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5,0x45, +0x7d,0x01,0x7f,0x60,0x7e,0x01,0x02,0x35,0xab,0x90,0x01,0xca,0xe5,0x68,0xf0,0xef, +0x60,0x02,0xd1,0x19,0x22,0x7f,0x0b,0xd1,0xa1,0xef,0x65,0x68,0x60,0x10,0xe5,0x68, +0xb4,0x01,0x05,0xe4,0xf5,0x68,0x80,0x03,0x75,0x68,0x01,0x7f,0x01,0x22,0x7f,0x00, +0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0xb2,0xef,0xf0,0xd3,0x94,0x07, +0x50,0x43,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4, +0xff,0x90,0x00,0x46,0xb1,0x42,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8, +0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0, +0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13, +0xd8,0xf8,0xff,0x80,0x4b,0x90,0x9e,0xb2,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f, +0xf0,0xb1,0x45,0x90,0x9e,0xb2,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80, +0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x42,0xe0,0xfb,0xe4,0xfe, +0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff, +0xd0,0xd0,0x92,0xaf,0x22,0xe4,0xfd,0x7f,0x45,0x31,0x05,0x90,0x04,0xfd,0xe4,0xf0, +0xa3,0xf0,0x90,0x9e,0x43,0xf0,0x90,0x9e,0x49,0xf0,0x90,0x9e,0x4c,0xf0,0x90,0x9e, +0x4a,0xf0,0x90,0x9e,0x4d,0xf0,0x90,0x9e,0x4b,0xf0,0x90,0x9e,0x4e,0xf0,0x90,0x9e, +0x35,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x9e,0x3a,0xf0,0x90,0x9e, +0x3f,0xf0,0x90,0x9e,0x41,0xf0,0x90,0x9e,0x53,0xf0,0x90,0x9e,0x44,0xf0,0x90,0x9e, +0x40,0xf0,0x90,0x9e,0x39,0xf0,0x90,0x00,0x51,0xe0,0x44,0xc0,0xfd,0x7f,0x51,0x21, +0x05,0xe4,0x90,0x9e,0x7d,0xf0,0x90,0x00,0x80,0xe0,0x44,0x80,0xfd,0x7f,0x80,0x21, +0x05,0x75,0x30,0x1f,0x75,0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0, +0xa3,0xe5,0x31,0xf0,0xa3,0xe5,0x32,0xf0,0x22,0xe4,0xf5,0x68,0x22,0x90,0x01,0x64, +0x74,0xa0,0xf0,0x22,0x90,0x9e,0x80,0xe0,0x90,0x9e,0x0f,0xf0,0x22,0x90,0x00,0xf3, +0xe0,0x7f,0x00,0x30,0xe3,0x02,0x7f,0x01,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x7f, +0x01,0x60,0x02,0x7f,0x00,0x22,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x0c,0x90,0x00,0xf2, +0xe0,0x30,0xe7,0x05,0x7e,0xfd,0x7f,0x33,0x22,0x7e,0xfd,0x7f,0x2f,0x22,0x90,0x00, +0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41,0x74,0x10,0xf0,0x90,0x05,0x5a,0xf0,0xa3, +0xe4,0xf0,0x22,0x90,0x01,0x02,0xe0,0x54,0x03,0xff,0xe0,0x54,0x0c,0x13,0x13,0x54, +0x3f,0xfe,0xef,0x64,0x01,0x60,0x04,0xef,0xb4,0x03,0x10,0x90,0x9e,0x10,0x74,0x01, +0xf0,0xa3,0x74,0x37,0xf0,0xa3,0x74,0x01,0xf0,0x80,0x1a,0xee,0x64,0x01,0x60,0x07, +0xaf,0x06,0xee,0x64,0x03,0x70,0x49,0x90,0x9e,0x10,0x74,0x01,0xf0,0xa3,0x74,0x3d, +0xf0,0xa3,0x74,0x40,0xf0,0x90,0x9e,0x10,0xe0,0xfe,0xa3,0xe0,0xff,0xf5,0x82,0x8e, +0x83,0xe0,0xfd,0x90,0x9e,0x12,0xe0,0xfc,0xed,0x5c,0x60,0x0c,0x8f,0x82,0x8e,0x83, +0xec,0xf0,0xe4,0x90,0x9e,0x77,0xf0,0x22,0x90,0x9e,0x77,0xe0,0x04,0xf0,0xe0,0xc3, +0x94,0x0a,0x40,0x0c,0xe4,0xf0,0x90,0x04,0x19,0xe0,0x30,0xe0,0x03,0x12,0x44,0xea, +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,0xa1,0xf0,0x74,0x50,0xa3,0xf0,0x90,0x01,0x34,0xe0,0x55,0x28,0xf5,0x2c, +0xa3,0xe0,0x55,0x29,0xf5,0x2d,0xa3,0xe0,0x55,0x2a,0xf5,0x2e,0xa3,0xe0,0x55,0x2b, +0xf5,0x2f,0xe5,0x2c,0x20,0xe0,0x02,0x41,0x46,0x90,0x01,0x34,0x74,0x01,0xf0,0x85, +0xd1,0x4d,0x85,0xd2,0x4e,0x85,0xd3,0x4f,0x85,0xd4,0x50,0x85,0xd5,0x51,0x85,0xd6, +0x52,0x85,0xd7,0x53,0x85,0xd9,0x54,0xe5,0x54,0x54,0x40,0xc3,0x13,0xff,0xe5,0x53, +0x54,0x20,0x6f,0x70,0x02,0x21,0xf5,0xe5,0x54,0x30,0xe5,0x02,0x21,0xf5,0xe5,0x52, +0x54,0x3f,0xf5,0x08,0xe5,0x4d,0x54,0x3f,0xf5,0x09,0xe5,0x51,0x54,0x1f,0xff,0xe5, +0x08,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12, +0x42,0x81,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4, +0x34,0x93,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x09,0xd3,0x94,0x04,0x40, +0x03,0x75,0x09,0x04,0x75,0xf0,0x0a,0xe5,0x08,0x90,0x90,0x00,0x12,0x43,0x5f,0x75, +0xf0,0x02,0xe5,0x09,0x12,0x43,0x5f,0xe0,0xfe,0xa3,0xe0,0xff,0xe5,0x53,0x54,0x1f, +0x2f,0xff,0xe4,0x3e,0xfe,0x75,0xf0,0x0a,0xe5,0x08,0x90,0x90,0x00,0x12,0x43,0x5f, +0x75,0xf0,0x02,0xe5,0x09,0x12,0x43,0x5f,0xee,0xf0,0xa3,0xef,0xf0,0xe5,0x54,0x20, +0xe6,0x24,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4, +0x34,0x98,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x4f,0x30,0xe7,0x36,0xaf, +0x08,0x12,0x63,0x51,0x80,0x2f,0xe5,0x53,0x54,0x1f,0xff,0xe5,0x08,0x25,0xe0,0x24, +0x44,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0x8f,0xf0,0x12,0x42,0x81,0xe5,0x4f, +0x30,0xe7,0x12,0xe5,0x4f,0x54,0x7f,0xfd,0xe5,0x53,0x54,0x1f,0xf5,0x0d,0xab,0x09, +0xaf,0x08,0x12,0x62,0xee,0xe5,0x63,0x14,0x24,0xfd,0x50,0x02,0x80,0x48,0x90,0x9e, +0x66,0xe0,0x60,0x3a,0x90,0x01,0x5b,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0,0x71, +0xc3,0xef,0x64,0x01,0x70,0x30,0x90,0x9e,0x85,0xf0,0x90,0x9e,0x5b,0xe0,0x90,0x9e, +0x86,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44,0x5e,0x90,0x01,0x5b,0x74, +0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x90,0x9e,0x64,0xf0,0x80,0x08,0x71,0xc3, +0xbf,0x01,0x03,0x12,0x44,0xcb,0xe5,0x2c,0x30,0xe1,0x20,0x90,0x01,0x34,0x74,0x02, +0xf0,0x85,0xd1,0x58,0x85,0xd2,0x59,0x85,0xd3,0x5a,0x85,0xd4,0x5b,0x85,0xd5,0x5c, +0x85,0xd6,0x5d,0x85,0xd7,0x5e,0x85,0xd9,0x5f,0x71,0xd2,0xe5,0x2c,0x30,0xe3,0x06, +0x90,0x01,0x34,0x74,0x08,0xf0,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01,0x34,0x74,0x10, +0xf0,0x43,0x57,0x10,0xe5,0x2c,0x30,0xe5,0x26,0x90,0x01,0xcf,0xe0,0x30,0xe5,0x1f, +0xe0,0x54,0xdf,0xf0,0x90,0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00,0x75,0xe8,0x00, +0x12,0x4b,0xcf,0x90,0x00,0x03,0xe0,0x54,0xfb,0xf0,0x12,0x4d,0x45,0x80,0xfe,0xe5, +0x2c,0x30,0xe6,0x06,0x90,0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe0,0x12,0x90, +0x9e,0x7f,0x74,0x01,0xf0,0x90,0x01,0x36,0xf0,0x12,0x61,0x4e,0x90,0x9e,0x7f,0xe4, +0xf0,0xe5,0x2e,0x30,0xe1,0x0b,0x90,0x01,0x36,0x74,0x02,0xf0,0x43,0x57,0x40,0x11, +0x23,0xe5,0x2e,0x30,0xe2,0x09,0x90,0x01,0x36,0x74,0x04,0xf0,0x12,0x60,0xdf,0xe5, +0x2e,0x30,0xe3,0x28,0x90,0x01,0x36,0x74,0x08,0xf0,0xe5,0x60,0x64,0x01,0x70,0x1c, +0xe5,0x63,0x60,0x18,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90, +0x9e,0x85,0xe4,0x12,0x44,0x4e,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x2e,0x30,0xe4, +0x2b,0x90,0x01,0x36,0x74,0x10,0xf0,0xe5,0x60,0xb4,0x01,0x20,0xe5,0x63,0x60,0x1c, +0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x9e,0x67,0xe4,0xf0, +0x53,0x64,0xfd,0xe5,0x64,0x54,0x07,0x70,0x03,0x12,0x44,0xcb,0xe5,0x2e,0x30,0xe5, +0x1f,0x90,0x01,0x36,0x74,0x20,0xf0,0xe5,0x60,0xb4,0x01,0x14,0xe5,0x63,0x60,0x10, +0x90,0x9e,0x66,0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xd2,0x80,0x03,0x12,0x44,0x79, +0xe5,0x2e,0x30,0xe6,0x1b,0x90,0x01,0x36,0x74,0x40,0xf0,0xe5,0x60,0xb4,0x01,0x10, +0xe5,0x63,0x60,0x0c,0x53,0x64,0xfe,0xe5,0x64,0x54,0x07,0x70,0x03,0x12,0x44,0xcb, +0xe5,0x2f,0x30,0xe1,0x08,0x90,0x01,0x37,0x74,0x02,0xf0,0x91,0x64,0x74,0xa1,0x04, +0x90,0x01,0xc4,0xf0,0x74,0x50,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,0x04,0x1b,0xe0,0x54,0x7f,0x64,0x7f,0x7f,0x01,0x60,0x02,0x7f, +0x00,0x22,0x90,0x9e,0x10,0xe0,0x54,0xf0,0x44,0x03,0xf0,0x54,0x0f,0x44,0x80,0xf0, +0x7b,0x00,0x7a,0x00,0x79,0x58,0x90,0x9e,0x90,0x12,0x43,0x8b,0x0b,0x7a,0x9e,0x79, +0x10,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x8d,0x12,0x43,0x8b,0x90,0x9e, +0xb0,0xe0,0xff,0x04,0xf0,0x90,0x00,0x01,0xef,0x12,0x42,0x5f,0x7f,0xaf,0x7e,0x01, +0x12,0x71,0x7a,0xef,0x60,0x49,0x90,0x9e,0x8d,0x12,0x43,0x6b,0x8b,0x23,0x8a,0x24, +0x89,0x25,0x75,0x26,0x02,0x7b,0x01,0x7a,0x01,0x79,0xa0,0x12,0x45,0x09,0x90,0x9e, +0x90,0x12,0x43,0x6b,0x8b,0x23,0x8a,0x24,0x89,0x25,0x90,0x9e,0x8d,0x12,0x43,0x6b, +0x12,0x29,0xd9,0xff,0xc4,0x54,0x0f,0xf5,0x26,0x7b,0x01,0x7a,0x01,0x79,0xa2,0x12, +0x45,0x09,0x90,0x01,0xaf,0x74,0xff,0xf0,0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0, +0xd0,0x92,0xaf,0x22,0x90,0x9e,0xa0,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x63, +0x14,0x24,0xfd,0x50,0x02,0x80,0x1f,0x90,0x9e,0x66,0xe0,0x60,0x06,0x7d,0x01,0x7f, +0x0c,0x80,0x0d,0xe5,0x61,0x54,0x0f,0xc3,0x94,0x04,0x50,0x06,0x7d,0x01,0x7f,0x04, +0x91,0xe7,0xe4,0xff,0x91,0x97,0x22,0xef,0x60,0x0b,0x90,0x9e,0x80,0xe0,0xb4,0x01, +0x10,0xe4,0xff,0x80,0x09,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x75, +0x92,0x22,0x90,0x01,0x37,0x74,0x02,0xf0,0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x74, +0x12,0xef,0x70,0x06,0x90,0x01,0xc8,0x74,0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x36, +0xe6,0xe5,0x63,0x60,0x04,0x7f,0x01,0x91,0x97,0x12,0x74,0xc8,0x53,0x61,0xf0,0x43, +0x61,0x02,0x22,0x7d,0x01,0x7f,0x0c,0x8f,0x6a,0x8d,0x6b,0xe5,0x6a,0x54,0x0f,0xff, +0xe5,0x61,0x54,0x0f,0x6f,0x60,0x65,0xe5,0x6a,0x30,0xe2,0x28,0xe5,0x61,0x20,0xe2, +0x04,0x7f,0x01,0xd1,0xc2,0xe5,0x61,0x30,0xe3,0x0c,0xe5,0x6a,0x20,0xe3,0x07,0xb1, +0x5d,0xef,0x60,0x48,0xa1,0xa5,0xe5,0x61,0x20,0xe3,0x41,0xe5,0x6a,0x30,0xe3,0x3c, +0xaf,0x6b,0xc1,0xdc,0xe5,0x61,0x54,0x0f,0xff,0xbf,0x0c,0x0c,0xe5,0x6a,0x20,0xe3, +0x07,0xb1,0x5d,0xef,0x60,0x26,0xb1,0xa5,0xe5,0x61,0x54,0x0f,0xff,0xbf,0x04,0x0c, +0xe5,0x6a,0x20,0xe2,0x07,0xf1,0x21,0xef,0x60,0x12,0x91,0xb2,0xe5,0x61,0x54,0x0f, +0xff,0xbf,0x02,0x08,0x12,0x60,0xbd,0xef,0x60,0x02,0xd1,0xaf,0x22,0x71,0xc3,0xef, +0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x30,0x90,0x9e,0x64,0xe0, +0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x22,0x90,0x9e,0x63,0xe0,0x60,0x08, +0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x14,0xe5,0x62,0x54,0x0f,0xd3,0x94,0x04,0x40, +0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74, +0x08,0xf0,0x7f,0x00,0x22,0x90,0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x60,0xb4,0x01, +0x04,0x7f,0x01,0xd1,0xf6,0x53,0x61,0xf0,0x43,0x61,0x04,0x22,0xef,0x64,0x01,0x70, +0x2e,0x7d,0x78,0x7f,0x02,0x12,0x36,0x75,0x7d,0x02,0x7f,0x03,0x12,0x36,0x75,0x90, +0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x91,0xe3,0xe4,0xff,0x91,0x97, +0x90,0x06,0x04,0xe0,0x54,0x7f,0xf0,0x90,0x06,0x0a,0xe0,0x54,0xf8,0xf0,0x22,0x90, +0x01,0x36,0x74,0x7b,0xf0,0xa3,0x74,0x02,0xf0,0x7d,0x7b,0xff,0x12,0x36,0xe6,0x7d, +0x02,0x7f,0x03,0x12,0x36,0xe6,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a, +0xe0,0x44,0x07,0xf0,0x12,0x62,0x4c,0xe5,0x60,0x20,0xe0,0x05,0xe4,0x90,0x9e,0x58, +0xf0,0x22,0x8b,0x14,0x8a,0x15,0x89,0x16,0x12,0x60,0xb1,0xab,0x14,0xaa,0x15,0xa9, +0x16,0x12,0x29,0xd9,0xf5,0x63,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24, +0x03,0x70,0x40,0x7f,0x01,0x80,0x3a,0xab,0x14,0xaa,0x15,0xa9,0x16,0x90,0x00,0x02, +0x12,0x42,0x20,0xfd,0xe4,0xff,0xd1,0x84,0x80,0x27,0xab,0x14,0xaa,0x15,0xa9,0x16, +0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x01,0xd1,0x84,0x1f,0x80,0x13,0xab,0x14, +0xaa,0x15,0xa9,0x16,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0xd1,0x84,0xe4, +0xff,0xb1,0xbc,0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x9e,0x65,0x74, +0x01,0xf0,0x80,0x16,0xed,0x70,0x0a,0x90,0x9e,0x62,0xe0,0x90,0x9e,0x65,0xf0,0x80, +0x05,0x90,0x9e,0x65,0xed,0xf0,0x90,0x9e,0x65,0xe0,0x90,0x9e,0x56,0xf0,0x22,0x53, +0x61,0xf0,0x43,0x61,0x01,0x12,0x45,0x00,0x12,0x45,0x01,0x53,0x61,0xf0,0x43,0x61, +0x02,0x22,0x90,0x9e,0xaf,0xef,0xf0,0x12,0x74,0x53,0x90,0x9e,0xaf,0xe0,0x60,0x05, +0x90,0x05,0x22,0xe4,0xf0,0x53,0x61,0xf0,0x43,0x61,0x04,0x22,0x90,0x06,0x04,0xe0, +0x54,0xbf,0xf0,0xef,0x60,0x09,0xe5,0x60,0xb4,0x01,0x04,0xe4,0xff,0xd1,0xf6,0x53, +0x61,0xf0,0x43,0x61,0x0c,0x22,0x8f,0x27,0x12,0x45,0xb0,0xbf,0x01,0x22,0x90,0x9e, +0x7a,0xe0,0xff,0x7d,0x01,0x12,0x47,0x79,0xab,0x07,0xaa,0x06,0xad,0x03,0xac,0x02, +0xaf,0x27,0x12,0x60,0x2a,0xaf,0x03,0x12,0x5f,0xf7,0x90,0x04,0x1f,0x74,0x20,0xf0, +0x22,0x71,0xc3,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x58, +0xe5,0x64,0x54,0x03,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4a,0xe5,0x62, +0x54,0x0f,0xd3,0x94,0x02,0x40,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x39,0xe5, +0x64,0x30,0xe2,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x2c,0xe5,0x64,0x30,0xe4, +0x08,0x90,0x01,0xb9,0x74,0x10,0xf0,0x80,0x1f,0x90,0x9e,0x58,0xe0,0x60,0x08,0x90, +0x01,0xb9,0x74,0x20,0xf0,0x80,0x11,0x90,0x9e,0x5e,0xe0,0x60,0x08,0x90,0x01,0xb9, +0x74,0x80,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0,0x7f,0x00, +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,0x91,0xf0,0x74,0x57,0xa3,0xf0,0x53,0x91,0xef,0x90,0x00,0x51,0xe0,0xff, +0x90,0x00,0x55,0xe0,0x5f,0xf5,0x3d,0x90,0x00,0x52,0xe0,0xff,0x90,0x00,0x56,0xe0, +0x5f,0xf5,0x3e,0xe5,0x3d,0x30,0xe4,0x06,0x90,0x00,0x55,0x74,0x10,0xf0,0xe5,0x3d, +0x30,0xe5,0x06,0x90,0x00,0x55,0x74,0x20,0xf0,0xe5,0x3d,0x30,0xe6,0x1b,0x90,0x00, +0x55,0x74,0x40,0xf0,0x90,0x9e,0x42,0xe0,0x54,0x03,0xff,0xbf,0x03,0x0b,0x90,0x9e, +0x3f,0xe0,0x60,0x05,0x7f,0x01,0x12,0x49,0x1a,0xe5,0x3d,0x30,0xe7,0x15,0x90,0x00, +0x55,0x74,0x80,0xf0,0x90,0x9e,0x42,0xe0,0x54,0x03,0xff,0xbf,0x03,0x05,0x7f,0x02, +0x12,0x49,0x1a,0xe5,0x3e,0x30,0xe0,0x06,0x90,0x00,0x56,0x74,0x01,0xf0,0xe5,0x3e, +0x30,0xe1,0x06,0x90,0x00,0x56,0x74,0x02,0xf0,0xe5,0x3e,0x30,0xe2,0x06,0x90,0x00, +0x56,0x74,0x04,0xf0,0xe5,0x3e,0x30,0xe3,0x06,0x90,0x00,0x56,0x74,0x08,0xf0,0x90, +0x01,0xc4,0x74,0x91,0xf0,0x74,0x57,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,0x01,0xcc,0xe0,0x54,0x0f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0x19,0xe0,0xfd,0x70,0x02,0x21,0xb5,0x90,0x9e,0xae,0xe0,0xff,0x74,0x01,0x7e,0x00, +0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70, +0x02,0x21,0xae,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x5f, +0xe0,0x90,0x9e,0x1a,0xf0,0x75,0x23,0x01,0x75,0x24,0x9e,0x75,0x25,0x1a,0x75,0x26, +0x01,0x7b,0x01,0x7a,0x9e,0x79,0x1b,0x12,0x45,0x09,0x90,0x9e,0x1b,0xe0,0xff,0xc4, +0x13,0x13,0x13,0x54,0x01,0x90,0x9e,0xae,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90, +0x00,0x88,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1c,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0, +0x02,0x90,0x00,0x89,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1d,0xf0,0x90,0x9e,0xae,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1e,0xf0,0x90,0x9e, +0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x1f,0xf0, +0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x5f,0xe0,0x90,0x9e, +0x20,0xf0,0x80,0x33,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x5f,0xe0,0x90, +0x9e,0x1c,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x5f, +0xe0,0x90,0x9e,0x1d,0xf0,0x90,0x9e,0xae,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12, +0x43,0x5f,0xe0,0x90,0x9e,0x1e,0xf0,0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x9e,0x79, +0x1c,0x31,0xb6,0x90,0x9e,0x19,0xe0,0xff,0x90,0x9e,0xae,0xe0,0xfe,0x74,0x01,0xa8, +0x06,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0x5f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0xae,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01, +0xcc,0xf0,0x90,0x9e,0xae,0xe0,0x04,0xf0,0xe0,0x54,0x03,0xf0,0x01,0x7e,0x90,0x01, +0xc6,0xe0,0x44,0x02,0xf0,0x22,0x90,0x9e,0x21,0x12,0x43,0x8b,0xef,0x12,0x43,0x94, +0x59,0xfc,0x01,0x59,0xf4,0x02,0x5a,0x20,0x03,0x5a,0x29,0x05,0x5a,0x32,0x06,0x5a, +0x7e,0x07,0x5a,0x3a,0x09,0x5a,0x43,0x0b,0x5a,0x4c,0x0c,0x5a,0x55,0x0d,0x5a,0x5e, +0x0e,0x5a,0x67,0x1b,0x5a,0x6f,0x1c,0x5a,0x05,0x2d,0x5a,0x0e,0x2e,0x5a,0x17,0x3b, +0x00,0x00,0x5a,0x77,0x90,0x9e,0x21,0x12,0x43,0x6b,0xe1,0xe9,0x90,0x9e,0x21,0x12, +0x43,0x6b,0x02,0x71,0xd0,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0x0b,0x90,0x9e, +0x21,0x12,0x43,0x6b,0x02,0x72,0x53,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0x8c, +0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x72,0xb6,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02, +0x70,0x4a,0x90,0x9e,0x21,0x12,0x43,0x6b,0x80,0x45,0x90,0x9e,0x21,0x12,0x43,0x6b, +0x02,0x72,0xfe,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x70,0xa2,0x90,0x9e,0x21,0x12, +0x43,0x6b,0x02,0x49,0xc2,0x90,0x9e,0x21,0x12,0x43,0x6b,0x02,0x7b,0x16,0x90,0x9e, +0x21,0x12,0x43,0x6b,0x02,0x4a,0xfc,0x90,0x9e,0x21,0x12,0x43,0x6b,0xe1,0xef,0x90, +0x9e,0x21,0x12,0x43,0x6b,0xe1,0xd1,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22,0x90, +0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x1f,0xfe,0xef,0x54,0x20,0xc4,0x13,0x54,0x07, +0xfd,0xaf,0x06,0x90,0x9e,0x24,0xef,0xf0,0xa3,0xed,0xf0,0xa3,0x12,0x43,0x8b,0x90, +0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0xf0,0xc4,0x54,0x0f, +0x90,0x9e,0x29,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0x54,0x40,0xc4,0x13,0x13,0x54, +0x03,0x90,0x9e,0x2a,0xf0,0x90,0x9e,0x24,0xe0,0xff,0x75,0xf0,0x09,0x90,0x96,0x46, +0x12,0x43,0x5f,0xad,0x82,0xac,0x83,0x90,0x9e,0x2b,0xec,0xf0,0xa3,0xed,0xf0,0xef, +0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74,0x96,0x35,0xf0,0xfa,0x7b,0x01,0xa3,0x12, +0x43,0x8b,0x90,0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0x0f, +0xff,0x90,0x9e,0x2d,0x12,0x43,0x6b,0xef,0x12,0x42,0x4d,0x90,0x9e,0x26,0x12,0x43, +0x6b,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x90,0x9e,0x2d,0x12,0x43,0x6b,0x90,0x00, +0x01,0xef,0x12,0x42,0x5f,0x90,0x9e,0x26,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42, +0x20,0xff,0x90,0x9e,0x2b,0xe0,0xfc,0xa3,0xe0,0xfd,0xf5,0x82,0x8c,0x83,0xef,0xf0, +0x12,0x29,0xd9,0x8d,0x82,0x8c,0x83,0xa3,0xf0,0x90,0x9e,0x29,0xe0,0xfe,0x90,0x9e, +0x24,0xe0,0xff,0x24,0x82,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0x90,0x9e, +0x25,0xe0,0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4a,0x12,0x43,0x5f,0xee,0xf0,0x75, +0xf0,0x09,0xef,0x90,0x96,0x4b,0x12,0x43,0x5f,0x74,0x01,0xf0,0x90,0x9e,0x2a,0xe0, +0xfe,0x75,0xf0,0x09,0xef,0x90,0x96,0x4c,0x12,0x43,0x5f,0xee,0xf0,0x8f,0x14,0xef, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xaf,0x82,0xf5,0x16,0x8f,0x17,0xe5, +0x14,0x75,0xf0,0x02,0xa4,0x24,0x02,0xf9,0x74,0x95,0x35,0xf0,0x75,0x18,0x01,0xf5, +0x19,0x89,0x1a,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x46,0x12,0x43,0x5f,0xaf,0x82, +0x85,0x83,0x1b,0x8f,0x1c,0xe5,0x14,0x75,0xf0,0x09,0xa4,0x24,0x44,0xf9,0x74,0x96, +0x35,0xf0,0x75,0x1d,0x01,0xf5,0x1e,0x89,0x1f,0x74,0x82,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xe0,0x12,0x43,0x94,0x5c,0x0d,0x00,0x5c,0x22,0x01,0x5c,0x37, +0x02,0x5c,0x4c,0x03,0x5c,0x75,0x04,0x5c,0x8a,0x05,0x5c,0x9f,0x06,0x5c,0xc5,0x0c, +0x5c,0xf2,0x0d,0x5d,0x1f,0x0e,0x5d,0x4c,0x0f,0x00,0x00,0x5d,0x80,0xe5,0x14,0x25, +0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74,0x15, +0x80,0x3c,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74, +0xf0,0xf0,0xa3,0x74,0x10,0x80,0x27,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4, +0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0x74,0x05,0x80,0x12,0xe5,0x14,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xf0,0xf0,0xa3,0xe4,0xf0,0xe5, +0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0x74,0x0f,0xf0,0xa3, +0x74,0x8f,0xf0,0xa1,0x80,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf5,0x80,0x27,0xe5,0x14,0x25,0xe0,0x24,0xc6, +0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0x0f,0xf0,0xa3,0x74,0xf0,0x80,0x12,0xe5, +0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3,0x74, +0x0d,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe4, +0xf0,0xa3,0xf0,0xa1,0x80,0x90,0x04,0x47,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12, +0x42,0x4d,0x90,0x04,0x46,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12, +0x42,0x5f,0x90,0x04,0x45,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x44, +0xa1,0x77,0x90,0x04,0x4b,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90, +0x04,0x4a,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90, +0x04,0x49,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x48,0x80,0x58,0x90, +0x04,0x4f,0xe0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90,0x04,0x4e,0xe0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x4d,0xe0, +0x85,0x17,0x82,0x85,0x16,0x83,0xf0,0x90,0x04,0x4c,0x80,0x2b,0x90,0x04,0x53,0xe0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x12,0x42,0x4d,0x90,0x04,0x52,0xe0,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x01,0x12,0x42,0x5f,0x90,0x04,0x51,0xe0,0x85,0x17,0x82, +0x85,0x16,0x83,0xf0,0x90,0x04,0x50,0xe0,0x85,0x17,0x82,0x85,0x16,0x83,0xa3,0xf0, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0xc0,0x03,0xc0,0x02,0xc0,0x01,0x12,0x29,0xd9,0xff, +0xab,0x1d,0xaa,0x1e,0xa9,0x1f,0x12,0x29,0xd9,0x5f,0xd0,0x01,0xd0,0x02,0xd0,0x03, +0x12,0x42,0x4d,0xab,0x18,0xe5,0x1a,0x24,0x01,0xf9,0xe4,0x35,0x19,0xfa,0xc0,0x03, +0xc0,0x02,0xc0,0x01,0x12,0x29,0xd9,0xff,0xab,0x1d,0xaa,0x1e,0xa9,0x1f,0x90,0x00, +0x01,0x12,0x42,0x20,0x5f,0xd0,0x01,0xd0,0x02,0xd0,0x03,0x12,0x42,0x4d,0x85,0x17, +0x82,0x85,0x16,0x83,0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x1c,0x82,0x85,0x1b,0x83, +0xe0,0xfe,0xef,0x5e,0xd0,0x82,0xd0,0x83,0xf0,0x85,0x17,0x82,0x85,0x16,0x83,0xa3, +0xc0,0x83,0xc0,0x82,0xe0,0xff,0x85,0x1c,0x82,0x85,0x1b,0x83,0xa3,0xe0,0xfe,0xef, +0x5e,0xd0,0x82,0xd0,0x83,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34, +0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b,0x75,0x15,0x0b,0x74,0x01,0x7e, +0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5,0x14, +0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x60,0x06,0xe5,0x15,0x24,0x10,0x80,0x5d,0x15,0x15,0xe5,0x15,0xc3,0x94, +0x00,0x50,0xca,0x80,0x56,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3d,0x75,0x15,0x0f,0x74,0x01,0x7e,0x00, +0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xe5,0x14,0x25, +0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f, +0x4e,0x60,0x08,0x90,0x9e,0x30,0xe5,0x15,0xf0,0x80,0x10,0x15,0x15,0xe5,0x15,0xc3, +0x94,0x00,0x50,0xc8,0x80,0x05,0xe4,0x90,0x9e,0x30,0xf0,0xe5,0x14,0x25,0xe0,0x24, +0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x3b,0xe4, +0xf5,0x15,0x74,0x01,0x7e,0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce, +0xd8,0xf9,0xff,0xe5,0x14,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83, +0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x08,0x90,0x9e,0x31,0xe5,0x15,0xf0,0x80, +0x5b,0x05,0x15,0xe5,0x15,0xb4,0x10,0xca,0x80,0x52,0xe5,0x14,0x25,0xe0,0x24,0x02, +0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0x4e,0x60,0x39,0xe4,0xf5, +0x15,0x74,0x01,0x7e,0x00,0xa8,0x15,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8, +0xf9,0xff,0xe5,0x14,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0, +0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x06,0xe5,0x15,0x24,0x10,0x80,0x0a,0x05,0x15, +0xe5,0x15,0xb4,0x0c,0xcc,0x80,0x05,0xe4,0x90,0x9e,0x31,0xf0,0x90,0x9e,0x30,0xe0, +0xff,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x48,0x12,0x43,0x5f,0xef,0xf0,0x90,0x9e, +0x31,0xe0,0xfe,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x49,0x12,0x43,0x5f,0xee,0xf0, +0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0xd3,0x9f,0x40,0x06, +0x90,0x9e,0x30,0x12,0x62,0x94,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x04,0xf5, +0x83,0xe0,0xff,0x90,0x9e,0x31,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x03,0x12,0x62,0x94, +0x90,0x9e,0x30,0xe0,0xff,0xd3,0x94,0x13,0x40,0x07,0x90,0x96,0x43,0x74,0x03,0xf0, +0x22,0xef,0xd3,0x94,0x0b,0x40,0x07,0x90,0x96,0x43,0x74,0x02,0xf0,0x22,0xef,0xd3, +0x94,0x03,0x40,0x07,0x90,0x96,0x43,0x74,0x01,0xf0,0x22,0xe4,0x90,0x96,0x43,0xf0, +0x22,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x3f,0xfe,0xef,0x54,0x80,0xc4,0x13, +0x13,0x13,0x54,0x01,0xfd,0xaf,0x06,0x41,0x93,0x12,0x29,0xd9,0xf5,0x60,0x22,0x12, +0x29,0xd9,0x90,0x95,0x01,0xf0,0x22,0xad,0x07,0x74,0x11,0x2d,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xe0,0x44,0x01,0xf0,0x90,0x04,0x80,0xe0,0x54,0x0f,0xfc,0x74,0x14, +0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xc0,0x4c,0xfd,0x74,0x14,0x2f, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xed,0xf0,0x22,0xef,0x60,0x0f,0x74,0x21,0x2d, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x22,0x74,0x21,0x2d,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x22,0xe4,0xf5,0x60,0xf5,0x64, +0xf5,0x63,0x75,0x62,0x0c,0x75,0x61,0x0c,0x90,0x9e,0x66,0xf0,0x90,0x9e,0x64,0xf0, +0x90,0x9e,0x63,0xf0,0x90,0x9e,0x65,0x04,0xf0,0x90,0x9e,0x56,0xf0,0xe4,0x90,0x9e, +0x67,0xf0,0x90,0x9e,0x58,0xf0,0x90,0x9e,0x61,0x74,0x07,0xf0,0xe4,0x90,0x9e,0x57, +0xf0,0x90,0x9e,0x5f,0xf0,0xa3,0x74,0x03,0xf0,0x90,0x9e,0x5c,0x74,0x0a,0xf0,0xa3, +0x74,0x05,0xf0,0x90,0x9e,0x5b,0x74,0x14,0xf0,0x90,0x9e,0x62,0x74,0x05,0xf0,0xe4, +0x90,0x9e,0x5a,0xf0,0x90,0x9e,0x55,0xf0,0x90,0x9e,0x7f,0xf0,0x90,0x9e,0x5e,0xf0, +0x22,0xe4,0x90,0x9e,0x67,0xf0,0x90,0x9e,0x57,0xf0,0xf5,0x64,0x22,0x7f,0x00,0x22, +0xe5,0x62,0x30,0xe6,0x19,0xe5,0x62,0x54,0x0f,0xff,0x90,0x9e,0x54,0xe0,0xfe,0x4f, +0x90,0x01,0x2f,0xf0,0xee,0x64,0x80,0x90,0x9e,0x54,0xf0,0x53,0x62,0xbf,0x22,0xe5, +0x60,0x64,0x01,0x70,0x68,0xe5,0x63,0x60,0x64,0xe5,0x63,0x64,0x02,0x60,0x06,0xe5, +0x63,0x64,0x05,0x70,0x27,0x90,0x06,0xab,0xe0,0x90,0x9e,0x56,0xf0,0x90,0x06,0xaa, +0xe0,0x90,0x9e,0x65,0xf0,0x90,0x9e,0x56,0xe0,0x70,0x07,0x90,0x9e,0x65,0xe0,0xff, +0x80,0x05,0x90,0x9e,0x56,0xe0,0xff,0x90,0x9e,0x56,0xef,0xf0,0x90,0x9e,0x58,0xe0, +0x60,0x03,0xe0,0x14,0xf0,0xe4,0x90,0x9e,0x57,0xf0,0x90,0x05,0x58,0x74,0x03,0xf0, +0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x53,0x64,0xfd,0x53,0x64, +0xef,0xe5,0x63,0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0x53,0x22,0xe4,0xfb, +0x90,0x9e,0x9c,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x63,0x60,0x6a,0xe5,0x60, +0x64,0x01,0x70,0x64,0xe5,0x63,0x14,0x60,0x2b,0x24,0xfd,0x60,0x27,0x24,0x02,0x24, +0xfb,0x50,0x02,0x80,0x21,0x90,0x9e,0x56,0xe0,0x14,0xf0,0xe0,0x60,0x04,0xa3,0xe0, +0x60,0x14,0x90,0x9e,0x56,0xe0,0x70,0x08,0x90,0x9e,0x65,0xe0,0x90,0x9e,0x56,0xf0, +0x7b,0x01,0x80,0x02,0x7b,0x01,0xeb,0x60,0x2f,0x43,0x64,0x10,0xe4,0x90,0x9e,0x85, +0xf0,0x90,0x9e,0x57,0xe0,0x75,0xf0,0x03,0xa4,0xff,0x90,0x9e,0x61,0xe0,0x2f,0x12, +0x44,0x53,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x61,0x54,0x0f,0xc3,0x94,0x04,0x50, +0x07,0x7d,0x01,0x7f,0x04,0x12,0x54,0xe7,0x22,0xe4,0x90,0x9e,0x15,0xf0,0xe5,0x63, +0x60,0x79,0x90,0x9e,0x67,0xe0,0x60,0x0d,0xe4,0xf0,0x53,0x64,0xfd,0xe5,0x64,0x54, +0x07,0x70,0x68,0x80,0x63,0x90,0x9e,0x57,0xe0,0x04,0xf0,0x53,0x64,0xef,0x90,0x9e, +0x15,0xe0,0xf9,0xff,0x7e,0x00,0x24,0x01,0xfd,0xee,0x33,0xfc,0x90,0x9e,0x57,0xe0, +0xb5,0x05,0x06,0xe4,0xb5,0x04,0x02,0x80,0x12,0xef,0x24,0x02,0xff,0xe4,0x3e,0xfe, +0x90,0x9e,0x57,0xe0,0xb5,0x07,0x0a,0xe4,0xb5,0x06,0x06,0x90,0x05,0x58,0xe0,0x04, +0xf0,0xe9,0xff,0x90,0x9e,0x5c,0xe0,0x2f,0xff,0xe4,0x33,0xfe,0x90,0x9e,0x57,0xe0, +0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x40,0x0d,0xe5,0x60,0xb4,0x01,0x0b, +0xa3,0xe0,0x70,0x07,0xe0,0x04,0xf0,0x22,0x12,0x44,0xcb,0x22,0x90,0x9e,0x5f,0xe0, +0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e, +0x93,0x12,0x43,0x8b,0x90,0x9e,0x96,0xe0,0x54,0xf0,0x44,0x06,0xff,0xf0,0xed,0x54, +0x0f,0xc4,0x54,0xf0,0xfe,0xef,0x54,0x0f,0x4e,0xf0,0x90,0x9e,0x93,0x12,0x43,0x6b, +0x90,0x9e,0x90,0x12,0x43,0x8b,0x7b,0x01,0x7a,0x9e,0x79,0x96,0x12,0x53,0xf1,0xd0, +0xd0,0x92,0xaf,0x22,0xe0,0xfd,0x74,0x26,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9d,0xf5, +0x83,0xed,0xf0,0xaf,0x14,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xef,0xc3,0x94,0x20, +0x50,0x0e,0x74,0x84,0x2f,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xed,0xf0,0x80,0x29, +0x74,0xa6,0x2f,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xed,0xf0,0x90,0x9e,0x68,0xef, +0xf0,0x24,0xa6,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x90,0x9e,0x69,0xf0,0x7b, +0x01,0x7a,0x9e,0x79,0x68,0x7d,0x02,0x51,0x57,0xd0,0xd0,0x92,0xaf,0x22,0x8f,0x0a, +0x8d,0x0b,0xe5,0x0b,0x54,0x1f,0xf5,0x10,0x74,0x01,0x2f,0xf5,0x82,0xe4,0x34,0x94, +0xf5,0x83,0xe0,0xf5,0x0e,0x90,0x04,0xfd,0xe0,0xb4,0x01,0x05,0x75,0x11,0x03,0x80, +0x03,0x75,0x11,0x01,0xeb,0xc3,0x95,0x11,0x40,0x04,0xaf,0x0a,0x80,0x33,0xe5,0x0e, +0x25,0x0d,0xf5,0x0f,0xe5,0x10,0x90,0x41,0xd6,0x93,0xff,0xe5,0x0f,0xd3,0x9f,0x74, +0x01,0x40,0x11,0x25,0x0a,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe4,0xf0,0xad,0x0b, +0xaf,0x0a,0x41,0xa5,0x25,0x0a,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe5,0x0f,0xf0, +0x22,0xad,0x07,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0,0xff,0x74, +0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xe0,0x54,0x1f,0xf5,0x12,0xd3,0x9f, +0x40,0x02,0x8f,0x12,0xe5,0x12,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xe5,0x12,0x25,0xe0,0x24,0x66,0xf5,0x82, +0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe, +0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee, +0xf0,0xa3,0xef,0xf0,0xaf,0x05,0xad,0x12,0x51,0xa5,0xaf,0x12,0x22,0xac,0x07,0xec, +0xc3,0x94,0x20,0x50,0x0d,0x74,0x84,0x2c,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0, +0x80,0x0b,0x74,0xa6,0x2c,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x7f,0xf5, +0x1f,0xe5,0x1f,0x54,0x1f,0xff,0x90,0x9e,0x25,0xf0,0x75,0xf0,0x09,0xec,0x90,0x96, +0x49,0x12,0x43,0x5f,0xe0,0x90,0x9e,0x27,0xf0,0x75,0xf0,0x09,0xec,0x90,0x96,0x48, +0x12,0x43,0x5f,0xe0,0xfe,0x90,0x9e,0x28,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x29,0xcb,0xf0,0xa3,0xeb, +0xf0,0xec,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xfb,0xa3, +0xe0,0x90,0x9e,0x2b,0xcb,0xf0,0xa3,0xeb,0xf0,0xef,0xd3,0x9e,0x40,0x0a,0x90,0x9e, +0x28,0xe0,0x90,0x9e,0x25,0xf0,0xf5,0x1f,0xed,0x70,0x02,0xa1,0x13,0x90,0x9e,0x26, +0xed,0xf0,0xe5,0x1f,0x30,0xe6,0x0a,0x90,0x9e,0x25,0xe0,0xf5,0x1f,0xa3,0xe0,0x14, +0xf0,0x90,0x9e,0x26,0xe0,0x70,0x02,0xa1,0x13,0x90,0x9e,0x25,0xe0,0xff,0xd3,0x94, +0x00,0x50,0x02,0xa1,0x13,0xe4,0x90,0x9e,0x24,0xf0,0xef,0x14,0x90,0x9e,0x23,0xf0, +0x90,0x9e,0x27,0xe0,0xfd,0x90,0x9e,0x23,0xe0,0xff,0xd3,0x9d,0x40,0x6b,0xef,0x94, +0x10,0x40,0x21,0xef,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x2b,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x70,0x27,0x90,0x9e,0x23,0xe0,0xff,0xc3,0x94,0x10,0x50,0x33,0x74,0x01, +0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90, +0x9e,0x29,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x60,0x16,0x90,0x9e,0x23,0xe0,0xf5, +0x1f,0xa3,0xe0,0x04,0xf0,0x90,0x9e,0x26,0xe0,0xff,0x90,0x9e,0x24,0xe0,0x6f,0x60, +0x08,0x90,0x9e,0x23,0xe0,0x14,0xf0,0x80,0x87,0x90,0x9e,0x26,0xe0,0xff,0x90,0x9e, +0x24,0xe0,0xc3,0x9f,0x50,0x0d,0x90,0x9e,0x23,0xe0,0xb5,0x05,0x06,0x90,0x9e,0x27, +0xe0,0xf5,0x1f,0xe5,0x1f,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83, +0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xe5,0x1f,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4, +0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef, +0x13,0xff,0xec,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0, +0xa3,0xef,0xf0,0xaf,0x04,0xad,0x1f,0x51,0xa5,0xaf,0x1f,0x22,0xad,0x07,0xed,0xc3, +0x94,0x20,0x50,0x0d,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x80, +0x0b,0x74,0xa6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x7f,0xf5,0x1f, +0xe5,0x1f,0x54,0x1f,0xfc,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0xe0, +0xff,0x90,0x9e,0x23,0xf0,0xed,0x25,0xe0,0x24,0x02,0xf5,0x82,0xe4,0x34,0x95,0xf5, +0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x24,0xcb,0xf0,0xa3,0xeb,0xf0,0xed,0x25,0xe0, +0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x9e,0x26, +0xcb,0xf0,0xa3,0xeb,0xf0,0xec,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfa,0x74,0x01,0x93,0xfb,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xea,0xf0,0xa3,0xeb,0xf0,0xec,0xc3,0x9f,0x40,0x02,0xc1,0x7a, +0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xec,0xf0,0x04,0xfb,0x90,0x9e, +0x23,0xe0,0xff,0xeb,0xd3,0x9f,0x40,0x02,0xc1,0xab,0xeb,0xc3,0x94,0x10,0x40,0x21, +0xeb,0x24,0xf0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce, +0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x24,0xe0,0x5e,0xfe,0xa3,0xe0,0x5f,0x4e,0x70, +0x23,0xeb,0xc3,0x94,0x10,0x50,0x40,0x74,0x01,0x7e,0x00,0xa8,0x03,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x9e,0x26,0xe0,0x5e,0xfe,0xa3,0xe0, +0x5f,0x4e,0x60,0x23,0xbb,0x11,0x09,0x90,0x9e,0x25,0xe0,0x30,0xe7,0x02,0x7b,0x17, +0xeb,0x64,0x13,0x60,0x03,0xbb,0x12,0x09,0x90,0x9e,0x24,0xe0,0x30,0xe0,0x02,0x7b, +0x18,0xac,0x03,0x8c,0x1f,0x80,0x34,0x0b,0x80,0x84,0x90,0x9e,0x23,0xe0,0xfb,0x6c, +0x70,0x69,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xec,0xf0,0x75,0xf0, +0x09,0xed,0x90,0x96,0x4a,0x12,0x43,0x5f,0xe0,0xb4,0x01,0x0c,0xe5,0x1f,0x20,0xe6, +0x07,0xec,0x44,0x40,0xf5,0x1f,0x80,0x03,0xaf,0x1f,0x22,0xec,0x25,0xe0,0x24,0x9e, +0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25, +0xe0,0x24,0x66,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4, +0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4, +0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x80,0x5b,0xec,0xd3,0x9b,0x40,0x56, +0x90,0x9e,0x23,0xe0,0xff,0x74,0x67,0x2d,0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef, +0xf0,0xac,0x07,0x8f,0x1f,0xec,0x25,0xe0,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5, +0x83,0xe4,0x93,0xfe,0x74,0x01,0x93,0xff,0xec,0x25,0xe0,0x24,0x66,0xf5,0x82,0xe4, +0x34,0x41,0xf5,0x83,0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef, +0x13,0xff,0xed,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0, +0xa3,0xef,0xf0,0xaf,0x1f,0x22,0x74,0x01,0x2d,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83, +0xe4,0xf0,0xaf,0x05,0xe5,0x1f,0x44,0x80,0xfd,0x51,0xa5,0xe5,0x1f,0x44,0x80,0xff, +0x22,0xef,0xc3,0x94,0x20,0x50,0x39,0xef,0x30,0xe0,0x17,0xed,0xc4,0x54,0xf0,0xfd, +0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x54,0x0f, +0x80,0x10,0xef,0xc3,0x13,0xfe,0x24,0xa4,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0, +0x54,0xf0,0xf0,0x74,0xa4,0x2e,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0x4d,0xf0, +0x22,0xe4,0xf5,0x14,0xe5,0x14,0xb4,0x20,0x14,0x90,0x9a,0xc5,0xe0,0x04,0xf0,0x90, +0x95,0x01,0xe0,0xff,0x90,0x9a,0xc5,0xe0,0xb5,0x07,0x02,0xe4,0xf0,0x75,0xf0,0x09, +0xe5,0x14,0x90,0x96,0x4b,0x12,0x43,0x5f,0xe0,0x64,0x01,0x60,0x03,0x02,0x6e,0x6a, +0xe5,0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xfe,0xa3, +0xe0,0xd3,0x94,0x00,0xee,0x94,0x00,0x50,0x03,0x02,0x6e,0x6a,0xe5,0x14,0x94,0x20, +0x40,0x09,0x90,0x9a,0xc5,0xe0,0x60,0x03,0x02,0x6e,0x76,0xe5,0x14,0x75,0xf0,0x0a, +0xa4,0x24,0x00,0xf9,0x74,0x90,0x35,0xf0,0x75,0x18,0x01,0xf5,0x19,0x89,0x1a,0xe5, +0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe0,0xff,0xa3,0xe0, +0x90,0x9e,0x1b,0xcf,0xf0,0xa3,0xef,0xf0,0xe5,0x14,0x25,0xe0,0x24,0xc4,0xf5,0x82, +0xe4,0x34,0x98,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x9e,0x1d,0xcf,0xf0,0xa3,0xef, +0xf0,0xe5,0x14,0xc3,0x94,0x20,0x50,0x14,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34, +0x04,0xf5,0x83,0xe0,0x54,0x3f,0x90,0x9e,0x19,0xf0,0x80,0x12,0x74,0xa6,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x54,0x3f,0x90,0x9e,0x19,0xf0,0x90,0x9e, +0x19,0xe0,0xfe,0x54,0x1f,0xa3,0xf0,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x48,0x12, +0x43,0x5f,0xe0,0x90,0x9e,0x20,0xf0,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c, +0xf5,0x83,0xe0,0xc3,0x94,0x05,0x40,0x02,0x41,0x9f,0x90,0x9e,0x20,0xe0,0xff,0x90, +0x9e,0x1a,0xe0,0x9f,0x40,0x13,0x90,0x9e,0x20,0xe0,0x90,0x9e,0x1a,0xf0,0xee,0x54, +0x40,0xfe,0x90,0x9e,0x19,0xf0,0xef,0x4e,0xf0,0x90,0x04,0xfd,0xe0,0x54,0x05,0x64, +0x01,0x70,0x29,0x90,0x9e,0x1a,0xe0,0xff,0x90,0x41,0x4a,0x93,0xfe,0x74,0x44,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xc3,0x9e,0x40,0x06,0xef,0x90,0x40, +0xda,0x80,0x30,0x90,0x9e,0x1a,0xe0,0x90,0x40,0xf6,0x80,0x27,0x90,0x9e,0x1a,0xe0, +0xff,0x90,0x41,0x4a,0x93,0xfe,0x74,0x44,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5, +0x83,0xe0,0xc3,0x9e,0x40,0x06,0xef,0x90,0x41,0x12,0x80,0x07,0x90,0x9e,0x1a,0xe0, +0x90,0x41,0x2e,0x93,0x90,0x9e,0x1f,0xf0,0x90,0x9e,0x1f,0xe0,0x75,0xf0,0x06,0xa4, +0x24,0x50,0xf9,0x74,0x40,0x35,0xf0,0xfa,0x7b,0xff,0x8b,0x15,0xf5,0x16,0x89,0x17, +0xe5,0x14,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xe0,0xf5,0x1b, +0xa3,0xe0,0xf5,0x1c,0x12,0x29,0xd9,0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a, +0x12,0x42,0x97,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35, +0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x01,0x12,0x42,0x20,0xff, +0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x02,0x12,0x42,0xc2,0xfd,0xac, +0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab,0x15, +0xaa,0x16,0xa9,0x17,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x04,0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef, +0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90, +0x00,0x03,0x12,0x42,0x20,0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00, +0x06,0x12,0x42,0xc2,0xfd,0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee, +0x35,0x1b,0xf5,0x1b,0xab,0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x04,0x12,0x42,0x20, +0xff,0x7e,0x00,0xab,0x18,0xaa,0x19,0xa9,0x1a,0x90,0x00,0x08,0x12,0x42,0xc2,0xfd, +0xac,0xf0,0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xab, +0x15,0xaa,0x16,0xa9,0x17,0x90,0x00,0x05,0x12,0x42,0x20,0xff,0x7e,0x00,0x90,0x9e, +0x1b,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x29,0xf2,0xd3,0xe5,0x1c,0x9f,0xe5,0x1b,0x9e, +0x40,0x0c,0xe5,0x1c,0x9f,0xf5,0x1c,0xe5,0x1b,0x9e,0xf5,0x1b,0x80,0x05,0xe4,0xf5, +0x1b,0xf5,0x1c,0xe5,0x14,0x25,0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83, +0xe5,0x1b,0xf0,0xa3,0xe5,0x1c,0xf0,0x90,0x9e,0x19,0xe0,0x25,0xe0,0x24,0x66,0xf5, +0x82,0xe4,0x34,0x41,0xf5,0x83,0xc3,0x74,0x01,0x93,0x95,0x1c,0xe4,0x93,0x95,0x1b, +0x50,0x07,0xaf,0x14,0x12,0x65,0x5c,0xa1,0x31,0x90,0x9e,0x19,0xe0,0x25,0xe0,0x24, +0x9e,0xf5,0x82,0xe4,0x34,0x41,0xf5,0x83,0xd3,0x74,0x01,0x93,0x95,0x1c,0xe4,0x93, +0x95,0x1b,0x50,0x02,0xa1,0x31,0x7d,0x01,0xaf,0x14,0x12,0x63,0xbd,0xa1,0x31,0x74, +0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xfc,0x64,0x05,0x60,0x02, +0x81,0x3a,0x90,0x96,0x43,0xe0,0xff,0xb4,0x03,0x0b,0x90,0x9e,0x1a,0xe0,0xc3,0x94, +0x19,0x40,0x3d,0x80,0x2e,0xef,0xb4,0x02,0x0b,0x90,0x9e,0x1a,0xe0,0xc3,0x94,0x11, +0x40,0x2e,0x80,0x1f,0x90,0x96,0x43,0xe0,0xff,0xb4,0x01,0x0b,0x90,0x9e,0x1a,0xe0, +0xc3,0x94,0x0a,0x40,0x1b,0x80,0x0c,0xef,0x70,0x11,0x90,0x9e,0x1a,0xe0,0xc3,0x94, +0x03,0x40,0x0d,0x90,0x9a,0x84,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90,0x9a,0x84,0xf0, +0x74,0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x1e,0x74,0x44, +0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xc3,0x94,0x30,0x50,0x02, +0x61,0xe7,0x90,0x9a,0x84,0xe0,0x64,0x01,0x60,0x02,0x61,0xe7,0x74,0x85,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0x64,0x0a,0x60,0x51,0xef,0x24,0x05,0xff, +0xe4,0x33,0xfe,0x74,0x41,0x25,0x14,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xe0,0xfd, +0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x32,0xed,0x24,0x05,0xff,0xe4, +0x33,0xfe,0x74,0x44,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xd3,0x9f, +0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x50,0x14,0x74,0x26,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x9d,0xf5,0x83,0xe0,0xff,0x90,0x9e,0x1a,0xe0,0x6f,0x60,0x3d,0x74,0x44,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xff,0xd3,0x94,0x42,0x40,0x05,0x75, +0x1e,0x05,0x80,0x0e,0xef,0xd3,0x94,0x39,0x40,0x05,0x75,0x1e,0x03,0x80,0x03,0x75, +0x1e,0x01,0x74,0x41,0x25,0x14,0xf5,0x82,0xe4,0x34,0x94,0xf5,0x83,0xef,0xf0,0x74, +0x85,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a,0x80,0x29,0x74,0xe6,0x25,0x14,0xf5,0x82, +0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x85,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xe0,0x04,0xf0,0x80,0x10,0xe4,0xf5,0x1e,0x74,0xe6,0x25,0x14,0xf5,0x82, +0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x9e,0x1a,0xe0,0xff,0x74,0x26,0x25,0x14, +0xf5,0x82,0xe4,0x34,0x9d,0xf5,0x83,0xef,0xf0,0x74,0x84,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x98,0xf5,0x83,0xe5,0x1e,0xf0,0x75,0xf0,0x09,0xe5,0x14,0x90,0x96,0x4c,0x12, +0x43,0x5f,0xe0,0xb4,0x01,0x10,0xe4,0xf5,0x1e,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4, +0x34,0x9c,0xf5,0x83,0xe4,0xf0,0xad,0x1e,0xa1,0x2c,0xec,0x64,0x06,0x60,0x02,0xa1, +0x31,0xf5,0x1b,0xf5,0x1c,0x90,0x42,0x13,0x93,0xff,0x7e,0x00,0x90,0x9e,0x1b,0xe0, +0xfc,0xa3,0xe0,0xfd,0x12,0x29,0xf2,0x90,0x9e,0x21,0xee,0xf0,0xa3,0xef,0xf0,0x74, +0x84,0x25,0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe0,0xf5,0x1e,0xe4,0xf5,0x1d, +0xab,0x18,0xaa,0x19,0xa9,0x1a,0x75,0xf0,0x02,0xe5,0x1d,0xa4,0xf5,0x82,0x85,0xf0, +0x83,0x12,0x42,0xc2,0xfd,0xac,0xf0,0xe5,0x1d,0x90,0x42,0x0e,0x93,0xff,0x7e,0x00, +0x12,0x29,0xf2,0xef,0x25,0x1c,0xf5,0x1c,0xee,0x35,0x1b,0xf5,0x1b,0xc3,0x90,0x9e, +0x22,0xe0,0x95,0x1c,0x90,0x9e,0x21,0xe0,0x95,0x1b,0x40,0x07,0x05,0x1d,0xe5,0x1d, +0xb4,0x05,0xbd,0xe5,0x1d,0xc3,0x13,0xf5,0x1d,0xe5,0x1e,0xb4,0x01,0x06,0xe5,0x1d, +0x70,0x46,0x80,0x13,0xe5,0x1e,0xb4,0x03,0x15,0xe5,0x1d,0x70,0x05,0x75,0x1e,0x03, +0x80,0x39,0xe5,0x1d,0xb4,0x01,0x05,0x75,0x1e,0x01,0x80,0x2f,0x80,0x2a,0xe5,0x1e, +0xb4,0x05,0x28,0xe5,0x1d,0x70,0x05,0x75,0x1e,0x05,0x80,0x0d,0xe5,0x1d,0xb4,0x01, +0x05,0x75,0x1e,0x03,0x80,0x03,0x75,0x1e,0x01,0xd3,0x90,0x9e,0x1e,0xe0,0x94,0x03, +0x90,0x9e,0x1d,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x1e,0xd3,0x90,0x9e,0x1e,0xe0, +0x94,0x03,0x90,0x9e,0x1d,0xe0,0x94,0x00,0x40,0x03,0xe4,0xf5,0x1e,0x74,0x84,0x25, +0x14,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe5,0x1e,0xf0,0xfd,0xaf,0x14,0x12,0x67, +0x61,0x74,0xe6,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0xd3,0x94,0x05, +0x74,0xe6,0x50,0x0e,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe0,0x04,0xf0, +0x80,0x0b,0x25,0x14,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x90,0x9e,0x1d, +0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x74,0xff,0x9f,0xfd,0x74,0xff,0x9e,0xfc,0xe5,0x14, +0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xd3, +0x9d,0xea,0x9c,0xe5,0x14,0x50,0x13,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xee,0x8f,0xf0,0x12,0x42,0x81,0x80,0x10,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9a,0xf5,0x83,0x74,0xff,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x44, +0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x74,0xff,0x9f, +0xfd,0x74,0xff,0x9e,0xfc,0xe5,0x14,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b, +0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xd3,0x9d,0xea,0x9c,0xe5,0x14,0x50,0x13,0x25,0xe0, +0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xee,0x8f,0xf0,0x12,0x42,0x81,0x80, +0x10,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0x74,0xff,0xf0,0xa3, +0xf0,0xab,0x18,0xaa,0x19,0xa9,0x1a,0xe4,0xf5,0xf0,0x12,0x42,0xfa,0xab,0x18,0xaa, +0x19,0xa9,0x1a,0x90,0x00,0x02,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x04,0xe4, +0xf5,0xf0,0x12,0x43,0x19,0x90,0x00,0x06,0xe4,0xf5,0xf0,0x12,0x43,0x19,0x90,0x00, +0x08,0xe4,0xf5,0xf0,0x12,0x43,0x19,0xe5,0x14,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4, +0x34,0x93,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0xc4,0xf5,0x82, +0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xe5,0x14,0x25,0xe0,0x24,0x44,0xf5, +0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x05,0x14,0xe5,0x14,0xc3,0x94, +0x40,0x50,0x03,0x02,0x67,0xa4,0x22,0x90,0x04,0x44,0x74,0x11,0xf0,0xa3,0x74,0xf0, +0xf0,0xa3,0x74,0x0f,0xf0,0xa3,0xe4,0xf0,0xfd,0x74,0xa4,0x2d,0xf5,0x82,0xe4,0x34, +0x04,0xf5,0x83,0xe4,0xf0,0x0d,0xbd,0x10,0xf0,0xe4,0x90,0x9a,0xc5,0xf0,0x90,0x95, +0x01,0x04,0xf0,0xe4,0xfd,0x75,0xf0,0x0a,0xed,0x90,0x90,0x00,0x12,0x43,0x5f,0xe4, +0xf0,0xa3,0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x02,0x12,0x43,0x5f,0xe4,0xf0,0xa3, +0xf0,0x75,0xf0,0x0a,0xed,0x90,0x90,0x04,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75, +0xf0,0x0a,0xed,0x90,0x90,0x06,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x75,0xf0,0x0a, +0xed,0x90,0x90,0x08,0x12,0x43,0x5f,0xe4,0xf0,0xa3,0xf0,0x74,0x26,0x2d,0xf5,0x82, +0xe4,0x34,0x9d,0xf5,0x83,0x74,0x13,0xf0,0x74,0x85,0x2d,0xf5,0x82,0xe4,0x34,0x9a, +0xf5,0x83,0xe4,0xf0,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0, +0xed,0x25,0xe0,0x24,0x80,0xf5,0x82,0xe4,0x34,0x93,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x98,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc4,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0x44,0xf5,0x82,0xe4,0x34,0x99,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0xed,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0,0xa3,0xf0, +0x74,0x86,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0x46,0x2d,0xf5, +0x82,0xe4,0x34,0x9c,0xf5,0x83,0xe4,0xf0,0x74,0xe6,0x2d,0xf5,0x82,0xe4,0x34,0x9c, +0xf5,0x83,0xe4,0xf0,0x90,0x41,0xc4,0x93,0xfe,0x74,0x01,0x93,0xff,0x90,0x41,0x8c, +0x74,0x01,0x93,0x2f,0xff,0xe4,0x93,0x3e,0xc3,0x13,0xfe,0xef,0x13,0xff,0xed,0x25, +0xe0,0x24,0xc2,0xf5,0x82,0xe4,0x34,0x95,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x75, +0xf0,0x09,0xed,0x90,0x96,0x4b,0x12,0x43,0x5f,0x74,0x01,0xf0,0x75,0xf0,0x09,0xed, +0x90,0x96,0x4a,0x12,0x43,0x5f,0x74,0x01,0xf0,0x74,0x82,0x2d,0xf5,0x82,0xe4,0x34, +0x95,0xf5,0x83,0x74,0x0c,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x46,0x12,0x43,0x5f, +0x74,0xff,0xf0,0xa3,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x44,0x12,0x43,0x5f,0xe4, +0xf0,0xa3,0x74,0x0f,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x48,0x12,0x43,0x5f,0x74, +0x13,0xf0,0x75,0xf0,0x09,0xed,0x90,0x96,0x49,0x12,0x43,0x5f,0xe4,0xf0,0xed,0xc3, +0x94,0x20,0x50,0x0f,0x74,0x84,0x2d,0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0x74,0x13, +0xf0,0x80,0x0d,0x74,0xa6,0x2d,0xf5,0x82,0xe4,0x34,0x9c,0xf5,0x83,0x74,0x13,0xf0, +0x0d,0xed,0x64,0x40,0x60,0x03,0x02,0x6e,0xa5,0x22,0x12,0x29,0xd9,0xf5,0x14,0xc3, +0x94,0x40,0x50,0x15,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0x74,0x44,0x25,0x14,0xf5, +0x82,0xe4,0x34,0x9a,0xf5,0x83,0xef,0xf0,0x22,0xe5,0x14,0xb4,0x40,0x0a,0x90,0x00, +0x02,0x12,0x42,0x20,0x90,0x96,0x42,0xf0,0x22,0x90,0x9e,0x30,0x12,0x43,0x8b,0x90, +0x9e,0x33,0xe0,0x54,0xf0,0x44,0x02,0xf0,0x54,0x0f,0x44,0xc0,0xf0,0x90,0x9e,0x30, +0x12,0x43,0x6b,0x90,0x9e,0x90,0x12,0x43,0x8b,0x7b,0x01,0x7a,0x9e,0x79,0x33,0x02, +0x53,0xf1,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x90,0x00,0x01,0x12,0x42,0x20,0xfc, +0xed,0xc3,0x94,0x40,0x40,0x02,0xe4,0xfd,0xec,0xc3,0x94,0x40,0x40,0x02,0xe4,0xfc, +0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0, +0xfb,0xea,0x90,0x9e,0x24,0xf0,0xeb,0xa3,0xf0,0xed,0x25,0xe0,0x24,0x46,0xf5,0x82, +0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x26,0xf0,0xeb, +0xa3,0xf0,0xa3,0xed,0xf0,0xa3,0x74,0xff,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82, +0xe4,0x34,0x9a,0xf5,0x83,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x2a,0xf0,0xeb, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe0,0xfa, +0xa3,0xe0,0xfb,0xea,0x90,0x9e,0x2c,0xf0,0xeb,0xa3,0xf0,0xa3,0xec,0xf0,0xa3,0x74, +0xff,0xf0,0xed,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xed,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x9a,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0xec,0x25,0xe0,0x24,0x46,0xf5,0x82,0xe4,0x34,0x9b,0xf5,0x83,0xe4,0xf0, +0xa3,0xf0,0x7b,0x01,0x7a,0x9e,0x79,0x24,0x01,0x79,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0x90,0x9e,0xa4,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0x90,0x9e, +0xa4,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90,0x9e,0xa7, +0xe0,0x94,0xe8,0x90,0x9e,0xa6,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6,0xe0,0x44, +0x10,0xf0,0x7f,0x00,0x80,0x15,0x90,0x9e,0xa6,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81, +0x7f,0x0a,0x7e,0x00,0x12,0x37,0x54,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x24,0x12,0x2a,0x8b,0x00,0x00,0x00, +0x00,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x9e,0x66,0xf0,0x90,0x00,0x03,0x12,0x42, +0x20,0x90,0x9e,0x55,0xf0,0x12,0x56,0x22,0x90,0x01,0xe5,0xe5,0x63,0xf0,0x90,0x9e, +0x66,0xe0,0x90,0x01,0xe6,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x02,0x12,0x42, +0x20,0xff,0x30,0xe0,0x25,0x12,0x29,0xd9,0x90,0x9e,0x5c,0xf0,0x90,0x00,0x01,0x12, +0x42,0x20,0x90,0x9e,0x5d,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x5b,0xf0,0x90, +0x00,0x03,0x12,0x42,0x20,0x90,0x9e,0x62,0xf0,0x22,0x90,0x9e,0x5c,0x74,0x0a,0xf0, +0x90,0x9e,0x5d,0x74,0x05,0xf0,0x90,0x9e,0x5b,0x74,0x14,0xf0,0x90,0x9e,0x62,0x74, +0x05,0xf0,0x22,0x12,0x29,0xd9,0x30,0xe0,0x19,0xc3,0x13,0x54,0x7f,0x90,0x9e,0x61, +0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x9e,0x5f,0xe4,0xf0,0xa3,0xef,0xf0, +0x80,0x0f,0x90,0x9e,0x61,0x74,0x07,0xf0,0x90,0x9e,0x5f,0xe4,0xf0,0xa3,0x74,0x03, +0xf0,0x90,0x9e,0x5f,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0x90,0x9e,0x24,0x12, +0x2a,0x8b,0x00,0x00,0x00,0x00,0x12,0x29,0xd9,0x60,0x0d,0x90,0x9e,0x5e,0xf0,0xe4, +0xfd,0x7f,0x04,0x12,0x54,0xe7,0x80,0x05,0xe4,0x90,0x9e,0x5e,0xf0,0x90,0x9e,0x5e, +0xe0,0x90,0x01,0xe7,0xf0,0x22,0x90,0x02,0x09,0xe0,0xfd,0x12,0x29,0xd9,0xfe,0xaf, +0x05,0xed,0x2e,0x90,0x9e,0x78,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f, +0x90,0x9e,0x79,0xf0,0x90,0x00,0x02,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x7a, +0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x9e,0x7b,0xf0,0x90,0x00, +0x04,0x12,0x42,0x20,0xff,0xae,0x05,0xed,0x2f,0x90,0x9e,0x7c,0xf0,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x9e,0x24,0x12,0x43,0x8b,0x90,0x9e,0x24,0x12,0x43, +0x6b,0x90,0x00,0x01,0x12,0x42,0xc2,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe, +0x90,0x9e,0x24,0x12,0x43,0x6b,0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x43,0x19,0x12, +0x29,0xd9,0xff,0x60,0x2d,0xb5,0x65,0x16,0x90,0x9e,0x24,0x12,0x43,0x6b,0x90,0x00, +0x01,0x12,0x42,0xc2,0x65,0x67,0x70,0x04,0xe5,0x66,0x65,0xf0,0x60,0x24,0x90,0x9e, +0x24,0x12,0x43,0x6b,0x90,0x00,0x01,0x12,0x42,0xc2,0xff,0xae,0xf0,0x12,0x4e,0x37, +0x80,0x10,0x90,0x9e,0x24,0x12,0x43,0x6b,0x12,0x29,0xd9,0x65,0x65,0x60,0x03,0x12, +0x44,0xc2,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x06,0x34,0x74,0xff,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0x22,0x90,0x06,0x34,0xe0,0x60,0x24,0x14,0x70,0x1a,0x7b,0x01, +0x7a,0x06,0x79,0x35,0x7f,0xf9,0x7e,0x01,0x71,0xb0,0xbf,0x01,0x09,0x90,0x06,0x35, +0xe0,0x54,0x0f,0xf0,0x80,0x04,0x80,0x00,0x80,0xcd,0xe4,0x90,0x06,0x34,0xf0,0x22, +0x8e,0x14,0x8f,0x15,0x8b,0x16,0x8a,0x17,0x89,0x18,0xe4,0x90,0x9e,0x19,0xf0,0xef, +0x90,0x00,0x31,0xf0,0x12,0x4d,0x45,0xe5,0x14,0x54,0x03,0xff,0x90,0x00,0x32,0xe0, +0x54,0xfc,0x4f,0xf0,0x12,0x4d,0x45,0x90,0x00,0x33,0xe0,0x54,0x7f,0xf0,0x12,0x4d, +0x45,0x90,0x00,0x33,0xe0,0x20,0xe7,0x0e,0x90,0x9e,0x19,0xe0,0xc3,0x94,0x64,0x50, +0x05,0xe0,0x04,0xf0,0x80,0xeb,0x90,0x9e,0x19,0xe0,0xc3,0x94,0x64,0x50,0x10,0x90, +0x00,0x30,0xe0,0xab,0x16,0xaa,0x17,0xa9,0x18,0x12,0x42,0x4d,0x7f,0x01,0x22,0x7f, +0x00,0x22,0xe4,0x90,0x9e,0xac,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, +0x9e,0xad,0xe0,0x94,0xe8,0x90,0x9e,0xac,0xe0,0x94,0x03,0x40,0x03,0x7f,0x00,0x22, +0x7f,0x32,0x7e,0x00,0x12,0x37,0x54,0x90,0x9e,0xac,0xe4,0x75,0xf0,0x01,0x12,0x42, +0x81,0x80,0xc6,0x90,0x9d,0xff,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x78,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x03,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x9e,0x07,0x12,0x43,0x53,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x0b,0x12, +0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x80,0x59,0x12,0x2a,0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90, +0x9e,0x80,0xe0,0xb4,0x01,0x11,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x03,0x2d,0x95, +0xe4,0xfd,0x7f,0x01,0x12,0x34,0x81,0x22,0x7f,0x78,0x7e,0x08,0x12,0x27,0xde,0x90, +0x9d,0xff,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x9e,0x03,0x12, +0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0x07,0x12,0x2a,0x7f,0x90, +0x9e,0x80,0xe0,0x90,0x9d,0xff,0xb4,0x01,0x0d,0x12,0x43,0x53,0xef,0x54,0xc7,0xff, +0xed,0x54,0xc7,0xfd,0x80,0x07,0x12,0x43,0x53,0xef,0x54,0xc7,0xff,0xec,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9e,0x03,0x12,0x43, +0x53,0xef,0x54,0x0f,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c, +0x12,0x2f,0xd9,0x90,0x9e,0x07,0x12,0x43,0x53,0xef,0x44,0x02,0xff,0xec,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x7f,0x70,0x7e,0x0e,0x12, +0x27,0xde,0x90,0x9e,0x0b,0x12,0x2a,0x7f,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b, +0x25,0xa0,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00, +0x00,0x00,0x00,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90,0x9e,0x80,0xe0,0xb4,0x01,0x11, +0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4,0xfd,0x7f,0x01,0x12,0x34, +0x81,0x22,0xef,0x70,0x02,0xe1,0x49,0x90,0x9e,0x0f,0xe0,0x60,0x03,0x02,0x7b,0x15, +0x90,0x9d,0xfb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x08, +0x12,0x2f,0xd9,0x90,0x9d,0xa7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9d,0xab,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x9d,0xaf,0x12,0x43,0x53,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xb3,0x12, +0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x9d,0xb7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x74,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x9d,0xbb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xbf,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xc3,0x12,0x43,0x53,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xc7,0x12,0x43, +0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d, +0xcb,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x88,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x9d,0xcf,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x8c,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xd3,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0xd0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xd7,0x12,0x43,0x53,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0xd4,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xdb,0x12,0x43,0x53, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd8,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xdf, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x9d,0xe3,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xe0,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x9d,0xe7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x9d,0xeb,0x12,0x43,0x53,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x9d,0xef,0x12,0x43,0x53,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x90,0x9d,0xf3,0x12, +0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x90, +0x9d,0xf7,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12, +0x2f,0xd9,0x90,0x9e,0x0f,0x74,0x01,0xf0,0x22,0x90,0x9e,0x0f,0xe0,0x64,0x01,0x60, +0x03,0x02,0x7b,0x15,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xfb,0x12,0x2a, +0x7f,0x7f,0x44,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xa7,0x12,0x2a,0x7f,0x7f,0x5c, +0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xab,0x12,0x2a,0x7f,0x7f,0x6c,0x7e,0x0e,0x12, +0x27,0xde,0x90,0x9d,0xaf,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12,0x27,0xde,0x90, +0x9d,0xb3,0x12,0x2a,0x7f,0x7f,0x74,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xb7,0x12, +0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xbb,0x12,0x2a,0x7f,0x7f, +0x7c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xbf,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x0e, +0x12,0x27,0xde,0x90,0x9d,0xc3,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e,0x12,0x27,0xde, +0x90,0x9d,0xc7,0x12,0x2a,0x7f,0x7f,0x88,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xcb, +0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xcf,0x12,0x2a,0x7f, +0x7f,0xd0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xd3,0x12,0x2a,0x7f,0x7f,0xd4,0x7e, +0x0e,0x12,0x27,0xde,0x90,0x9d,0xd7,0x12,0x2a,0x7f,0x7f,0xd8,0x7e,0x0e,0x12,0x27, +0xde,0x90,0x9d,0xdb,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d, +0xdf,0x12,0x2a,0x7f,0x7f,0xe0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xe3,0x12,0x2a, +0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x27,0xde,0x90,0x9d,0xe7,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x0c,0x12,0x27,0xde,0x90,0x9d,0xeb,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12, +0x27,0xde,0x90,0x9d,0xef,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde,0x90, +0x9d,0xf3,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90,0x9d,0xf7,0x12, +0x2a,0x7f,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90, +0x9e,0xa8,0x12,0x43,0x53,0xed,0x44,0xc0,0xfd,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f, +0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x08, +0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x01,0x00,0x00,0x7f,0x44,0x7e, +0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0xdb,0x25,0xa4,0x7f,0x5c, +0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f, +0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4, +0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x04,0x1b,0x25, +0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x04,0x1b, +0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x04, +0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b, +0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a, +0x8b,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12, +0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85, +0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80, +0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd8,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f,0xdc,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f,0xe0,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x24,0xdb,0x25,0xa4,0x7f,0xec,0x7e, +0x0e,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12,0x2a, +0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xe4,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f, +0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x11,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a, +0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e, +0x0c,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0d,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12,0x2a, +0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x54,0xf0,0xff,0xec,0x90,0x9e,0xa8,0x12, +0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x01,0xff,0xec,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xe4,0xff,0xec,0x90,0x9e,0xa8,0x12, +0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xef,0x44,0x11,0xff,0xec,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde,0x90,0x9e,0xa8, +0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xed,0x54,0x0f,0xfd,0xec,0x54,0xf0, +0xfc,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43,0x53,0xed,0x44,0x10, +0xfd,0xec,0x44,0x01,0xfc,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43, +0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x7f,0x04, +0x7e,0x08,0x12,0x27,0xde,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12,0x43, +0x53,0xef,0x54,0xf0,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8,0x12, +0x43,0x53,0xef,0x44,0x01,0xff,0xec,0x90,0x9e,0xa8,0x12,0x2a,0x7f,0x90,0x9e,0xa8, +0x12,0x43,0x53,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12,0x2f,0xd9, +0xe4,0x90,0x9e,0x0f,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x9e,0x43,0xf0, +0xe0,0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5,0x14,0xc2,0xaf,0x90, +0x00,0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x49,0x05,0x7d,0x40,0x7f,0x01,0x12, +0x36,0xaf,0xe5,0x14,0x24,0xff,0x92,0xaf,0x22,0x90,0x9e,0x3a,0xe0,0xc3,0x94,0x14, +0x50,0x05,0xe0,0x04,0xf0,0x81,0x01,0x90,0x9e,0x3a,0xe0,0x64,0x14,0x60,0x02,0x81, +0x01,0x90,0x9e,0x49,0xe0,0x70,0x25,0x90,0x9e,0x4c,0xe0,0x70,0x1f,0x90,0x9e,0x4a, +0xe0,0x70,0x19,0x90,0x9e,0x4d,0xe0,0x70,0x13,0x90,0x9e,0x4b,0xe0,0x70,0x0d,0x90, +0x9e,0x4e,0xe0,0x70,0x07,0x90,0x04,0xfd,0xe0,0x54,0xfe,0xf0,0x90,0x9e,0x49,0xe0, +0x90,0x04,0x44,0xf0,0x90,0x9e,0x4a,0xe0,0x90,0x04,0x45,0xf0,0x90,0x9e,0x4b,0xe0, +0x90,0x04,0x46,0xf0,0xa3,0xe4,0xf0,0x90,0x9e,0x4c,0xe0,0x90,0x04,0x48,0xf0,0x90, +0x9e,0x4d,0xe0,0x90,0x04,0x49,0xf0,0x90,0x9e,0x4e,0xe0,0x90,0x04,0x4a,0xf0,0xa3, +0xe4,0xf0,0x90,0x9e,0x35,0xe0,0x90,0x04,0x4c,0xf0,0x90,0x9e,0x36,0xe0,0x90,0x04, +0x4d,0xf0,0x90,0x9e,0x37,0xe0,0x90,0x04,0x4e,0xf0,0x90,0x9e,0x38,0xe0,0x90,0x04, +0x4f,0xf0,0xe4,0x90,0x9e,0x3a,0xf0,0x90,0x9e,0x35,0x04,0xf0,0xe4,0xa3,0xf0,0xa3, +0xf0,0xa3,0xf0,0x90,0x9e,0x49,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3, +0xf0,0x90,0x05,0x60,0xe0,0x90,0x9e,0x19,0xf0,0x90,0x05,0x61,0xe0,0x90,0x9e,0x1a, +0xf0,0x90,0x05,0x62,0xe0,0x90,0x9e,0x1b,0xf0,0x90,0x05,0x63,0xe0,0x90,0x9e,0x1c, +0xf0,0x90,0x9e,0x52,0xe0,0xff,0x90,0x9e,0x1c,0xe0,0xfe,0xd3,0x9f,0x50,0x0b,0x90, +0x9e,0x52,0xe0,0xc3,0x9e,0xd3,0x94,0x01,0x40,0x11,0x90,0x9e,0x40,0xe0,0xb4,0x01, +0x02,0x80,0x03,0x90,0x9e,0x44,0xe0,0xff,0x12,0x4c,0xf0,0x22,0x90,0x9e,0x53,0xe0, +0x64,0x01,0x60,0x08,0x90,0x9e,0x41,0xe0,0x60,0x02,0xa1,0x23,0x90,0x9e,0x35,0xe0, +0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x3b,0x90,0x9e,0x36,0xe0,0xc3,0x94, +0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x28,0x90,0x9e,0x37,0xe0,0xc3,0x94,0xff, +0x50,0x0a,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x36,0xf0,0x80,0x15,0x90,0x9e,0x38,0xe0, +0xc3,0x94,0xff,0x50,0x10,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x37,0xf0,0x90,0x9e,0x36, +0xf0,0x90,0x9e,0x35,0xf0,0x90,0x00,0x44,0xe0,0x54,0x0c,0x60,0x76,0xe0,0x30,0xe2, +0x32,0x90,0x9e,0x49,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90, +0x9e,0x4a,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x9e, +0x4b,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x4a,0xf0,0x90, +0x9e,0x49,0xf0,0x90,0x00,0x44,0xe0,0x30,0xe3,0x32,0x90,0x9e,0x4c,0xe0,0xc3,0x94, +0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x9e,0x4d,0xe0,0xc3,0x94,0xff,0x50, +0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x9e,0x4e,0xe0,0xc3,0x94,0xff,0x50,0x0c, +0xe0,0x04,0xf0,0xe4,0x90,0x9e,0x4d,0xf0,0x90,0x9e,0x4c,0xf0,0x90,0x04,0xfd,0xe0, +0x44,0x01,0xf0,0x22,0x68,0x4c,}; +#else +// =================== v88 TSMC P2PPS with CCX report C2H 2012-12-05 ======================= +u8 Rtl8192CUFwTSMCImgArray[TSMCImgArrayLength] = { +0xC1, 0x88, 0x02, 0x05, 0x58, 0x00, 0x02, 0x00, 0x12, 0x05, 0x17, 0x12, 0xDE, 0x3E, 0x00, 0x00, +0x94, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x46, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x60, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x68, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4B, 0x87, 0x00, 0x00, +0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x06, 0x05, 0x04, 0x03, 0x00, 0x04, 0x06, 0x05, 0x04, 0x02, +0x00, 0x04, 0x08, 0x07, 0x06, 0x04, 0x00, 0x06, 0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x0A, 0x09, +0x08, 0x04, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x08, +0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x18, 0x22, 0x21, 0x20, 0x18, +0x00, 0x20, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20, 0x22, 0x21, 0x20, 0x08, 0x00, 0x20, 0x22, 0x21, +0x1C, 0x08, 0x00, 0x20, 0x22, 0x21, 0x14, 0x08, 0x00, 0x20, 0x22, 0x20, 0x18, 0x08, 0x00, 0x20, +0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x31, 0x30, 0x18, 0x00, 0x00, 0x30, 0x31, 0x2F, 0x10, 0x10, +0x00, 0x30, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x30, 0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x31, 0x20, +0x10, 0x00, 0x00, 0x30, 0x31, 0x10, 0x10, 0x00, 0x00, 0x30, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, +0x05, 0x07, 0x07, 0x07, 0x08, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x06, 0x0A, 0x0B, 0x0D, 0x05, 0x05, +0x07, 0x07, 0x08, 0x0B, 0x0D, 0x0F, 0x04, 0x04, 0x04, 0x05, 0x07, 0x07, 0x09, 0x09, 0x0C, 0x0E, +0x10, 0x12, 0x06, 0x07, 0x09, 0x0A, 0x0C, 0x0E, 0x11, 0x13, 0x09, 0x09, 0x09, 0x09, 0x0C, 0x0E, +0x11, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x26, 0x2A, 0x18, 0x1A, +0x1D, 0x1F, 0x21, 0x27, 0x29, 0x2A, 0x00, 0x00, 0x00, 0x1F, 0x23, 0x28, 0x2A, 0x2C, 0x00, 0x04, +0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, +0x00, 0x90, 0x00, 0xC0, 0x00, 0xD8, 0x00, 0x50, 0x00, 0x78, 0x00, 0xA0, 0x00, 0xC8, 0x01, 0x40, +0x01, 0x90, 0x01, 0xE0, 0x02, 0x30, 0x01, 0x2C, 0x01, 0x40, 0x01, 0xE0, 0x02, 0xD0, 0x03, 0xE8, +0x04, 0xB0, 0x06, 0x40, 0x07, 0xD0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, +0x00, 0x12, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x28, +0x00, 0x3C, 0x00, 0x50, 0x00, 0x64, 0x00, 0xA0, 0x00, 0xC8, 0x00, 0xF0, 0x01, 0x18, 0x00, 0x64, +0x00, 0xA0, 0x00, 0xF0, 0x01, 0x68, 0x01, 0xF4, 0x02, 0x58, 0x03, 0x20, 0x03, 0xE8, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x07, 0x02, 0x03, 0x04, 0x0A, 0x0C, 0x0E, +0x10, 0x12, 0x05, 0x07, 0x07, 0x08, 0x0B, 0x12, 0x24, 0x3C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, +0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x20, 0x1E, 0x1C, 0x18, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBB, 0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, +0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, +0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, +0x89, 0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, +0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, +0x50, 0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, +0x22, 0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, +0x02, 0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xF5, +0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x06, 0x87, 0xF0, 0x09, 0xE7, 0x19, 0x22, 0xBB, 0xFE, 0x07, 0xE3, +0xF5, 0xF0, 0x09, 0xE3, 0x19, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xF5, 0xF0, 0x74, 0x01, +0x93, 0x22, 0xBB, 0x01, 0x10, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, +0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, +0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, +0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0, 0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, +0x83, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x06, 0xF7, 0x09, 0xA7, 0xF0, 0x19, 0x22, 0xBB, +0xFE, 0x06, 0xF3, 0xE5, 0xF0, 0x09, 0xF3, 0x19, 0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, +0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, +0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0, 0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, +0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, +0x48, 0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xA4, +0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, +0xA3, 0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, +0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, +0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, +0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, +0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, +0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, +0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0xB5, 0xF0, 0x06, 0x74, 0x03, 0x93, 0x68, 0x60, +0xE9, 0xA3, 0xA3, 0xA3, 0xA3, 0x80, 0xD8, 0xE4, 0x90, 0x8A, 0xC5, 0xF0, 0xE5, 0x24, 0x70, 0x03, +0x02, 0x44, 0x9D, 0xE5, 0x21, 0x64, 0x01, 0x60, 0x03, 0x02, 0x44, 0x9D, 0xE5, 0x24, 0x14, 0x60, +0x29, 0x24, 0xFD, 0x60, 0x25, 0x24, 0x02, 0x24, 0xFB, 0x50, 0x02, 0x80, 0x23, 0x90, 0x8B, 0x0B, +0xE0, 0x14, 0xF0, 0xE0, 0x60, 0x04, 0xA3, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x0A, +0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, 0xF0, 0x80, 0x00, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, +0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x16, 0xA3, 0xE0, 0xB4, 0x06, 0x05, 0xE4, 0x90, 0x8A, 0xC5, +0xF0, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x70, 0x04, 0x90, 0x8A, 0xC5, 0xF0, 0x90, 0x8A, 0xC5, +0xE0, 0x60, 0x4A, 0x43, 0x25, 0x10, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0C, 0xE0, 0x75, +0xF0, 0x03, 0xA4, 0xFF, 0x90, 0x8B, 0x15, 0xE0, 0x2F, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0xE5, 0x22, 0x54, +0x0F, 0xC3, 0x94, 0x04, 0x50, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x90, 0x8B, 0x2C, +0xE0, 0x30, 0xE0, 0x09, 0x12, 0x7D, 0xC1, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0xE4, 0xF5, +0x25, 0xF5, 0x24, 0x75, 0x23, 0x0C, 0x75, 0x22, 0x0C, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x8B, 0x18, +0xF0, 0x90, 0x8B, 0x17, 0xF0, 0x90, 0x8B, 0x19, 0x04, 0xF0, 0x90, 0x8B, 0x0B, 0xF0, 0xE4, 0x90, +0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0D, 0xF0, 0x90, 0x8B, 0x15, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x8B, +0x0C, 0xF0, 0x90, 0x8B, 0x13, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x10, 0xF0, 0xA3, 0x74, +0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, 0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0xE4, 0x90, +0x8B, 0x0E, 0xF0, 0x90, 0x8B, 0x0A, 0xF0, 0x90, 0x8B, 0x08, 0xF0, 0x90, 0x8B, 0x12, 0xF0, 0x22, +0x7F, 0x00, 0x22, 0x02, 0x45, 0x03, 0x02, 0x45, 0x06, 0x8E, 0x64, 0x8F, 0x65, 0xAD, 0x65, 0xAC, +0x64, 0xAF, 0x63, 0x12, 0x4A, 0x5B, 0xAF, 0x65, 0xAE, 0x64, 0x90, 0x04, 0x80, 0xE0, 0x54, 0x0F, +0xFD, 0xAC, 0x07, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x01, +0xF0, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xFB, 0xF0, 0xAC, +0x07, 0x74, 0x16, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0xFA, 0xF0, 0x74, +0x15, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, +0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53, +0xE4, 0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74, +0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0x4D, +0xFD, 0x74, 0x14, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xED, 0xF0, 0x22, 0x7D, 0x01, +0x7F, 0x0C, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x67, 0x8D, 0x68, 0xE5, 0x67, 0x54, +0x0F, 0xFF, 0xE5, 0x22, 0x54, 0x0F, 0x6F, 0x60, 0x72, 0xE5, 0x67, 0x30, 0xE2, 0x30, 0xE5, 0x22, +0x20, 0xE2, 0x05, 0x7F, 0x01, 0x12, 0x4A, 0xB2, 0xE5, 0x22, 0x30, 0xE3, 0x10, 0xE5, 0x67, 0x20, +0xE3, 0x0B, 0x12, 0x49, 0xD5, 0xEF, 0x60, 0x53, 0x12, 0x4A, 0xCC, 0x80, 0x4E, 0xE5, 0x22, 0x20, +0xE3, 0x49, 0xE5, 0x67, 0x30, 0xE3, 0x44, 0xAF, 0x68, 0x12, 0x4A, 0x7C, 0x80, 0x3D, 0xE5, 0x22, +0x54, 0x0F, 0xFF, 0xBF, 0x0C, 0x0E, 0xE5, 0x67, 0x20, 0xE3, 0x09, 0x12, 0x49, 0xD5, 0xEF, 0x60, +0x2A, 0x12, 0x4A, 0xCC, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, 0x04, 0x0E, 0xE5, 0x67, 0x20, 0xE2, +0x09, 0x12, 0x49, 0x93, 0xEF, 0x60, 0x14, 0x12, 0x4A, 0x32, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, +0x02, 0x09, 0x12, 0x45, 0x00, 0xEF, 0x60, 0x03, 0x12, 0x4B, 0x10, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x02, 0x46, 0x6E, 0x02, 0x50, 0xC6, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, +0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, +0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, +0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x4B, +0x23, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, 0xE5, 0x21, 0x64, 0x01, 0x70, 0x67, 0xE5, 0x24, 0x60, 0x63, 0xE5, 0x24, 0x64, +0x02, 0x60, 0x06, 0xE5, 0x24, 0x64, 0x05, 0x70, 0x27, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x8B, 0x19, 0xF0, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x07, 0x90, +0x8B, 0x19, 0xE0, 0xFF, 0x80, 0x05, 0x90, 0x8B, 0x0B, 0xE0, 0xFF, 0x90, 0x8B, 0x0B, 0xEF, 0xF0, +0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x02, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x0C, 0xF0, 0x90, 0x05, 0x58, +0x74, 0x03, 0xF0, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x53, 0x25, +0xFD, 0x53, 0x25, 0xEF, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x03, 0x12, 0x47, 0x8E, +0x22, 0xEF, 0x64, 0x01, 0x70, 0x35, 0x7D, 0x78, 0x7F, 0x02, 0x12, 0x36, 0x75, 0x7D, 0x02, 0x7F, +0x03, 0x12, 0x36, 0x75, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x12, +0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x7D, 0xC1, 0x90, 0x06, 0x04, 0xE0, +0x54, 0x7F, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x7B, +0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x7B, 0xFF, 0x12, 0x36, 0xE6, 0x7D, 0x02, 0x7F, 0x03, 0x12, +0x36, 0xE6, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0xF0, +0x12, 0x4B, 0x4F, 0xE5, 0x21, 0x20, 0xE0, 0x05, 0xE4, 0x90, 0x8B, 0x0D, 0xF0, 0x22, 0xE4, 0x90, +0x8A, 0xC5, 0xF0, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x8A, 0xC5, 0xF0, 0xE0, 0x54, 0xC0, 0x70, 0x09, +0x53, 0x25, 0xFE, 0x53, 0x25, 0xFD, 0x12, 0x4A, 0xFC, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE6, 0x15, +0x43, 0x25, 0x01, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, 0x4A, 0x97, 0x80, 0x08, +0x12, 0x49, 0x49, 0x80, 0x03, 0x53, 0x25, 0xFE, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE7, 0x27, 0x43, +0x25, 0x02, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, +0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0x90, +0x8B, 0x1B, 0x74, 0x01, 0xF0, 0x22, 0x53, 0x25, 0xFD, 0x22, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x8B, +0x12, 0x4B, 0x43, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xF5, 0x24, 0x14, 0x60, +0x0E, 0x14, 0x60, 0x1F, 0x14, 0x60, 0x31, 0x24, 0x03, 0x70, 0x44, 0x7F, 0x01, 0x80, 0x3D, 0x90, +0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, 0xE4, 0xFF, 0x12, 0x4A, +0x07, 0x80, 0x29, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, +0x7F, 0x01, 0x12, 0x4A, 0x07, 0x1F, 0x80, 0x14, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, +0x02, 0x12, 0x42, 0x20, 0xFD, 0x7F, 0x02, 0x12, 0x4A, 0x07, 0xE4, 0xFF, 0x12, 0x47, 0x21, 0x22, +0xE4, 0x90, 0x8A, 0xCB, 0xF0, 0xE5, 0x24, 0x60, 0x49, 0x90, 0x8B, 0x1B, 0xE0, 0x60, 0x0D, 0xE4, +0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x38, 0x80, 0x33, 0x90, 0x8B, 0x0C, 0xE0, +0x04, 0xF0, 0x53, 0x25, 0xEF, 0x90, 0x8A, 0xCB, 0xE0, 0xFF, 0x90, 0x8B, 0x10, 0xE0, 0x2F, 0xFF, +0xE4, 0x33, 0xFE, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, +0x40, 0x0D, 0xE5, 0x21, 0xB4, 0x01, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xE0, 0x04, 0xF0, 0x22, 0x12, +0x4A, 0xFC, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x63, 0x90, 0x04, 0x1D, 0xE0, +0x60, 0x24, 0x90, 0x05, 0x22, 0xE0, 0xF5, 0x66, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x9A, 0xBF, 0x01, +0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, 0x12, 0x45, 0x09, 0x90, 0x05, +0x22, 0xE5, 0x66, 0xF0, 0x80, 0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, +0x12, 0x45, 0x09, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE5, 0x24, +0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x41, 0x90, 0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x12, 0x45, 0x9E, +0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x58, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, +0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x22, 0xE5, 0x22, 0x54, 0x0F, 0xC3, 0x94, 0x04, 0x50, +0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x22, 0x90, 0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, +0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, +0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, +0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x17, 0x14, 0xF0, 0xE5, 0x22, 0x54, 0x0F, +0xC3, 0x94, 0x0C, 0x50, 0x0D, 0x12, 0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, +0x7D, 0xC1, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x37, 0xE5, 0x25, 0x54, 0x03, 0x70, +0x31, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x02, 0x50, 0x28, 0xE5, 0x25, 0x20, 0xE2, 0x23, 0xE5, +0x25, 0x20, 0xE4, 0x1E, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x18, 0x90, 0x8B, 0x12, 0xE0, 0x70, 0x12, +0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x7F, +0x01, 0x22, 0x7F, 0x00, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x27, 0x90, 0x8B, 0x18, +0xE0, 0x70, 0x21, 0x90, 0x8B, 0x17, 0xE0, 0x70, 0x1B, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x04, +0x50, 0x12, 0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x08, +0xF0, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x22, 0x90, +0x8B, 0x19, 0x74, 0x01, 0xF0, 0x80, 0x16, 0xED, 0x70, 0x0A, 0x90, 0x8B, 0x16, 0xE0, 0x90, 0x8B, +0x19, 0xF0, 0x80, 0x05, 0x90, 0x8B, 0x19, 0xED, 0xF0, 0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x22, 0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, +0x9A, 0xEF, 0x70, 0x06, 0x90, 0x01, 0xC8, 0x74, 0xFD, 0xF0, 0x7D, 0x02, 0x7F, 0x03, 0x12, 0x36, +0xE6, 0x12, 0x7C, 0x50, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x02, 0x22, 0xEF, 0x60, 0x0F, 0x74, 0x21, +0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, 0x21, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x54, 0xBF, 0xF0, 0xEF, 0x60, 0x0A, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0xE4, 0xFF, 0x12, 0x48, 0xB3, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x0C, 0x22, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x14, 0x90, 0x8A, 0xF8, +0xE0, 0xFF, 0xE4, 0xFD, 0x12, 0x5F, 0xFD, 0x8E, 0x69, 0x8F, 0x6A, 0x90, 0x04, 0x1F, 0x74, 0x20, +0xF0, 0x22, 0x90, 0x8B, 0x52, 0xEF, 0xF0, 0x12, 0x7D, 0x42, 0x90, 0x8B, 0x52, 0xE0, 0x60, 0x05, +0x90, 0x05, 0x22, 0xE4, 0xF0, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x04, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x44, 0x40, 0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0x7F, 0x01, 0x12, 0x48, 0xB3, 0x53, 0x22, 0xF0, +0x43, 0x22, 0x04, 0x22, 0xE5, 0x23, 0x30, 0xE6, 0x12, 0xE5, 0x23, 0x54, 0x0F, 0xFF, 0x90, 0x01, +0x2F, 0xE0, 0x54, 0x80, 0x4F, 0x64, 0x80, 0xF0, 0x53, 0x23, 0xBF, 0x22, 0x90, 0x8B, 0x2C, 0xE0, +0x30, 0xE0, 0x05, 0xAF, 0x23, 0x02, 0x7E, 0x06, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x22, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x01, 0x12, 0x4B, 0x5A, 0x12, 0x4B, 0x5B, 0x53, 0x22, 0xF0, 0x43, +0x22, 0x02, 0x22, 0x41, 0x8A, 0xF6, 0x00, 0x41, 0x8B, 0x05, 0x00, 0x41, 0x8B, 0x51, 0x00, 0x41, +0x8B, 0x53, 0x00, 0x00, 0x90, 0x04, 0x1B, 0xE0, 0x54, 0x7F, 0x64, 0x7F, 0x7F, 0x01, 0x60, 0x02, +0x7F, 0x00, 0x22, 0xE4, 0x90, 0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0C, 0xF0, 0xF5, 0x25, 0x22, 0x90, +0x8B, 0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x22, 0x22, 0xF0, 0x90, 0x8B, 0x0F, +0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x3D, 0xE0, 0xFB, 0xA3, 0xE0, 0xF5, 0x44, 0xE4, 0xF5, 0x45, 0x12, +0x35, 0xAB, 0xD0, 0xD0, 0x92, 0xAF, 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, 0x75, 0x0E, 0x00, 0x90, 0x01, 0xC4, 0x74, 0x87, 0xF0, 0x74, 0x4B, 0xA3, +0xF0, 0x53, 0x91, 0xDF, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x30, 0xF5, 0x34, 0xA3, 0xE0, 0x55, 0x31, +0xF5, 0x35, 0xA3, 0xE0, 0x55, 0x32, 0xF5, 0x36, 0xA3, 0xE0, 0x55, 0x33, 0xF5, 0x37, 0xE5, 0x34, +0x30, 0xE0, 0x51, 0x90, 0x01, 0x3C, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x1F, +0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x34, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x1D, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x16, 0x90, 0x8B, +0x2E, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, +0x70, 0x02, 0xD1, 0x56, 0xE5, 0x34, 0x30, 0xE1, 0x08, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x11, +0x60, 0xE5, 0x34, 0x30, 0xE2, 0x28, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x92, 0xE0, +0x30, 0xE0, 0x14, 0x90, 0x8B, 0x3D, 0xE4, 0x71, 0x5C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, +0x06, 0x92, 0x74, 0x01, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x18, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, +0x30, 0xE3, 0x38, 0x90, 0x01, 0x3C, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x24, +0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x5C, 0x7E, 0x01, 0x71, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, +0x02, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x17, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, 0x30, 0xE4, 0x09, +0x90, 0x01, 0x3C, 0x74, 0x10, 0xF0, 0x12, 0x51, 0xC9, 0xE5, 0x34, 0x30, 0xE5, 0x06, 0x90, 0x01, +0x3C, 0x74, 0x20, 0xF0, 0xE5, 0x35, 0x30, 0xE0, 0x10, 0x90, 0x01, 0x3D, 0x74, 0x01, 0xF0, 0x90, +0x00, 0x83, 0xE0, 0xF5, 0x23, 0x51, 0xE4, 0x51, 0xFC, 0xE5, 0x35, 0x30, 0xE2, 0x06, 0x90, 0x01, +0x3D, 0x74, 0x04, 0xF0, 0xE5, 0x35, 0x30, 0xE4, 0x1B, 0x90, 0x01, 0x3D, 0x74, 0x10, 0xF0, 0x90, +0x8B, 0x05, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x05, +0xFD, 0xE0, 0x04, 0xF0, 0xE5, 0x36, 0x30, 0xE0, 0x75, 0x90, 0x01, 0x3E, 0x74, 0x01, 0xF0, 0x90, +0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x36, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, +0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0xD1, 0x89, 0x90, 0x8B, +0x2C, 0xE0, 0x30, 0xE0, 0x49, 0x90, 0x8B, 0x30, 0xE4, 0xF0, 0xFF, 0xB1, 0xE0, 0xEF, 0x60, 0x3E, +0x12, 0x65, 0x5F, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, 0x32, 0xEF, 0xB4, 0x04, 0x02, +0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, 0x80, 0x14, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x05, 0x7F, +0x01, 0x12, 0x65, 0x82, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x12, 0x7D, 0xC1, 0xE5, 0x36, +0x30, 0xE1, 0x47, 0x90, 0x01, 0x3E, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x19, +0x90, 0x8B, 0x36, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, +0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x1A, +0x90, 0x8B, 0x30, 0x74, 0x01, 0xF0, 0x12, 0x7E, 0x2B, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, +0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, 0x70, 0x02, 0xD1, 0x56, 0x74, 0x87, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0x74, 0x4B, 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, +0xEF, 0x64, 0x01, 0x70, 0x3D, 0x90, 0x8B, 0x35, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, +0x08, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x34, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, +0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x54, +0x07, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x36, 0xE0, 0x7F, 0x01, 0x60, 0x36, 0x7F, +0x00, 0x22, 0x90, 0x8B, 0x2F, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x08, 0xE0, 0x60, +0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2E, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2C, +0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x30, 0xE0, 0x7F, +0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x2D, 0xE0, +0x70, 0x04, 0x7F, 0x05, 0x80, 0x1F, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x01, 0x70, 0x1A, 0x7F, 0x02, +0x80, 0x13, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x03, 0x80, 0x08, 0x90, 0x8B, 0x2D, +0xE0, 0x70, 0x05, 0x7F, 0x04, 0x12, 0x65, 0x82, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8B, 0x33, 0xE0, 0x90, 0x8B, 0x55, 0xF0, 0x6F, 0x70, 0x02, 0xE1, 0x55, 0xEF, 0x14, 0x60, +0x3B, 0x14, 0x60, 0x5F, 0x14, 0x70, 0x02, 0xE1, 0x30, 0x24, 0x03, 0x60, 0x02, 0xE1, 0x55, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x04, 0xF1, 0xC2, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x02, +0x04, 0xF1, 0xAF, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, 0x04, 0xF1, 0xC6, 0xE1, 0x55, +0x90, 0x8B, 0x55, 0xE0, 0x64, 0x01, 0x70, 0x7D, 0xF1, 0xB1, 0x80, 0x79, 0x90, 0x8B, 0x55, 0xE0, +0xFF, 0xB4, 0x03, 0x04, 0xF1, 0xCA, 0x80, 0x6D, 0xEF, 0xB4, 0x02, 0x04, 0xF1, 0xA1, 0x80, 0x65, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0xD5, 0x80, 0x59, 0xEF, 0x70, 0x56, 0xF1, +0x8E, 0x80, 0x52, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x05, 0x12, 0x7C, 0x41, 0x80, 0x46, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x01, 0x04, 0xF1, 0x72, 0x80, 0x3B, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, +0x05, 0x12, 0x7D, 0x23, 0x80, 0x2F, 0x90, 0x8B, 0x55, 0xE0, 0x70, 0x29, 0xF1, 0x70, 0x80, 0x25, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x01, 0x04, 0xF1, 0x5A, 0x80, 0x19, 0xEF, 0xB4, 0x02, 0x04, +0xF1, 0x6B, 0x80, 0x11, 0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0x5A, 0x80, 0x05, +0xEF, 0x70, 0x02, 0xF1, 0x67, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, +0x90, 0x8B, 0x33, 0x74, 0x03, 0xF0, 0x22, 0xF1, 0x8E, 0x80, 0xEF, 0x12, 0x7D, 0x42, 0x80, 0xEA, +0xF1, 0x8E, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x9A, 0xEF, 0x70, 0x06, 0x90, 0x01, +0xC8, 0x74, 0xFD, 0xF0, 0x12, 0x7C, 0x50, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x01, +0x3E, 0x74, 0x03, 0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x37, 0x00, 0x90, 0x8B, 0x33, 0x74, 0x01, 0xF0, +0x22, 0x12, 0x7D, 0x42, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, 0xF1, +0xA1, 0x7D, 0x03, 0x7F, 0x02, 0x12, 0x36, 0x92, 0x90, 0x05, 0x27, 0xE4, 0xF0, 0x90, 0x8B, 0x33, +0xF0, 0x22, 0xF1, 0xCA, 0x80, 0xEB, 0xF1, 0xD5, 0x80, 0xE7, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, +0x8B, 0x33, 0x04, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, +0xF1, 0x8E, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0x90, +0x02, 0x84, 0xEF, 0xF0, 0xA3, 0xEE, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0xEF, 0x8E, 0xF0, 0x12, +0x43, 0xBA, 0x50, 0x1A, 0x00, 0x40, 0x50, 0x42, 0x00, 0x80, 0x50, 0x6D, 0x01, 0x00, 0x50, 0x81, +0x02, 0x00, 0x50, 0x99, 0x04, 0x00, 0x00, 0x00, 0x50, 0xB6, 0xED, 0x54, 0x3F, 0x70, 0x04, 0xFE, +0xFF, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x40, 0xEF, 0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xEF, 0x78, 0x06, +0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x78, 0x06, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +0x80, 0x26, 0xED, 0x54, 0x7F, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x80, 0xEF, +0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xEF, 0x78, 0x07, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x78, +0x07, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFD, 0xAC, 0x06, 0x80, 0x49, 0xED, 0x70, 0x04, +0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x01, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x7D, 0x00, 0xFC, 0x80, +0x35, 0xEC, 0x54, 0x01, 0x4D, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x02, 0x7F, 0x00, 0xEF, +0x2D, 0xEE, 0x3C, 0xC3, 0x13, 0x7D, 0x00, 0x80, 0x1A, 0xEC, 0x54, 0x03, 0x4D, 0x70, 0x04, 0xFE, +0xFF, 0x80, 0x04, 0x7E, 0x04, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x13, 0x13, 0x54, 0x3F, 0x7D, +0x00, 0x25, 0xE0, 0x25, 0xE0, 0xFC, 0xAE, 0x04, 0xAF, 0x05, 0x22, 0x90, 0x01, 0xE4, 0x74, 0x58, +0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x22, 0xE4, 0x90, 0x8A, 0xCC, 0xF0, 0xA3, 0xF0, 0x75, 0x8E, 0x02, +0x91, 0x0E, 0x12, 0x68, 0x44, 0x90, 0x8B, 0x07, 0xEF, 0xF0, 0x12, 0x68, 0x51, 0x90, 0x8B, 0x09, +0xEF, 0xF0, 0x12, 0x68, 0x5D, 0x90, 0x8A, 0xF4, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xF5, 0x55, +0xF5, 0x21, 0x12, 0x72, 0x55, 0x12, 0x44, 0x9E, 0x12, 0x32, 0x3D, 0x7F, 0x03, 0x12, 0x78, 0x42, +0x12, 0x7C, 0x3D, 0x12, 0x68, 0x0A, 0x12, 0x68, 0x75, 0x12, 0x68, 0x8A, 0x12, 0x68, 0x28, 0x12, +0x68, 0x43, 0x90, 0x8A, 0xCE, 0xE5, 0xD9, 0xF0, 0x31, 0x5F, 0xC2, 0xAF, 0x90, 0x00, 0x80, 0xE0, +0x44, 0x40, 0xF0, 0x51, 0x0E, 0x75, 0xE8, 0x03, 0x43, 0xA8, 0x85, 0xD2, 0xAF, 0x11, 0xBB, 0x90, +0x8A, 0xCC, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0xC6, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x50, 0xA3, 0xF0, +0xE5, 0x55, 0x30, 0xE4, 0x09, 0xC2, 0xAF, 0x53, 0x55, 0xEF, 0xD2, 0xAF, 0xB1, 0x59, 0xE5, 0x55, +0x30, 0xE6, 0xDC, 0xC2, 0xAF, 0x53, 0x55, 0xBF, 0xD2, 0xAF, 0x12, 0x6B, 0xBD, 0x80, 0xD0, 0x90, +0x01, 0x3C, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xF0, 0xA3, 0xF0, 0xA3, +0xF0, 0xA3, 0xF0, 0xFD, 0x7F, 0x54, 0x31, 0x88, 0x7D, 0xFF, 0x7F, 0x55, 0x31, 0x88, 0x7D, 0xFF, +0x7F, 0x56, 0x31, 0x88, 0x7D, 0xFF, 0x7F, 0x57, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, +0x82, 0x75, 0x83, 0x00, 0xED, 0xF0, 0x51, 0x0E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0x30, +0xE4, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x38, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xFD, 0x7F, 0x50, 0x31, 0x88, 0xE4, 0xFD, 0x7F, 0x51, 0x31, 0x88, 0xE4, 0xFD, 0x7F, +0x52, 0x31, 0x88, 0xE4, 0xFD, 0x7F, 0x53, 0x80, 0xBF, 0xE5, 0x5E, 0x64, 0x01, 0x70, 0x3B, 0x71, +0x4E, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x71, 0x42, 0x90, 0x00, 0x46, 0xE0, 0x44, 0x04, 0xFD, 0x7F, +0x46, 0x31, 0x88, 0x90, 0x00, 0x44, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x44, 0x31, 0x88, 0x90, 0x00, +0x46, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x46, 0x31, 0x88, 0x7F, 0x02, 0x71, 0x6A, 0x8F, 0x62, 0x90, +0x01, 0xC9, 0xE5, 0x62, 0xF0, 0xB4, 0x01, 0x02, 0x51, 0xE2, 0x22, 0xE0, 0x5F, 0xF0, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x10, 0xDF, 0xFE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xE0, 0xED, 0xF0, 0x90, 0x8A, 0xDF, 0xEF, 0xF0, 0xD3, +0x94, 0x07, 0x50, 0x4E, 0xA3, 0xE0, 0x70, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, +0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x5F, 0xF0, +0x80, 0x17, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, +0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x4F, 0xF0, 0x51, 0x0E, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, +0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x46, +0x80, 0x59, 0x90, 0x8A, 0xDF, 0xE0, 0x24, 0xF8, 0xF0, 0xA3, 0xE0, 0x70, 0x1D, 0x90, 0x8A, 0xDF, +0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xC4, 0x54, 0xF0, +0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x80, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, +0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0x00, +0x43, 0xE0, 0x4F, 0xF0, 0x51, 0x0E, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, +0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0x51, 0x0B, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0x90, 0x00, 0x49, 0xE0, 0x90, 0x8B, 0x54, 0xF0, 0xE0, 0x54, 0x0F, 0xF0, 0x44, 0xF0, +0xFD, 0x7F, 0x49, 0x31, 0x88, 0x90, 0x8B, 0x54, 0xE0, 0x44, 0xB0, 0xFD, 0x7F, 0x49, 0x21, 0x88, +0x90, 0x8A, 0xDD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0x5E, 0x01, 0x8E, 0x5F, 0xF5, 0x60, 0xE4, +0xFD, 0x7F, 0x0B, 0x51, 0x1E, 0xE4, 0xFD, 0x7F, 0x02, 0x51, 0x1E, 0x71, 0x4E, 0xE4, 0xFF, 0x71, +0x42, 0xE4, 0xF5, 0x62, 0x90, 0x01, 0xC9, 0xE5, 0x62, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0xEC, 0xFB, 0x8D, 0x44, 0xE4, 0xF5, 0x45, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01, 0x02, +0x35, 0xAB, 0x90, 0x01, 0xCA, 0xE5, 0x61, 0xF0, 0xEF, 0x60, 0x02, 0x51, 0xE2, 0x22, 0x7F, 0x0B, +0x71, 0x6A, 0xEF, 0x65, 0x61, 0x60, 0x10, 0xE5, 0x61, 0xB4, 0x01, 0x05, 0xE4, 0xF5, 0x61, 0x80, +0x03, 0x75, 0x61, 0x01, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x8B, 0x57, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x43, 0xE0, 0xFF, 0x74, 0x01, 0xA8, +0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x46, 0x51, 0x0B, 0x90, +0x8B, 0x57, 0xE0, 0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x00, 0x44, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x5B, 0xA8, 0x05, +0x08, 0x80, 0x06, 0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0x80, 0x4B, 0x90, 0x8B, +0x57, 0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, +0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x51, 0x0E, 0x90, 0x8B, 0x57, 0xE0, +0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x5B, 0xA8, 0x05, 0x08, 0x80, 0x06, +0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, +0x8B, 0x04, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x21, 0x88, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDA, 0x12, 0x43, +0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFA, 0xE5, 0xF0, 0x24, 0x00, 0xFF, 0xE4, 0x3A, 0xFE, +0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEE, 0x8F, 0xF0, 0x12, 0x43, 0x19, 0x12, +0x29, 0xD9, 0xFF, 0x60, 0x2C, 0xB5, 0x5E, 0x16, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, +0x01, 0x12, 0x42, 0xC2, 0x65, 0x60, 0x70, 0x04, 0xE5, 0x5F, 0x65, 0xF0, 0x60, 0x22, 0x90, 0x8A, +0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFF, 0xAE, 0xF0, 0x71, 0x00, 0x80, +0x0F, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0x65, 0x5E, 0x60, 0x02, 0x91, 0x95, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xF5, 0x5E, 0x7F, 0x60, 0x7E, 0x01, 0x8F, 0x82, 0x8E, 0x83, +0xA3, 0xA3, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x8B, 0xEF, 0x12, 0x43, 0x94, +0x54, 0xE7, 0x01, 0x54, 0xDE, 0x02, 0x55, 0x0B, 0x03, 0x55, 0x14, 0x05, 0x55, 0x1D, 0x06, 0x55, +0x58, 0x07, 0x55, 0x25, 0x08, 0x55, 0x2E, 0x09, 0x55, 0x36, 0x20, 0x55, 0x3F, 0x2C, 0x54, 0xF0, +0x2D, 0x54, 0xF9, 0x2E, 0x55, 0x02, 0x3B, 0x55, 0x48, 0x4B, 0x00, 0x00, 0x55, 0x51, 0x90, 0x8A, +0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x85, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x8B, +0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0xB8, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, +0x75, 0x00, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x75, 0x39, 0x90, 0x8A, 0xD7, 0x12, 0x43, +0x6B, 0x02, 0x75, 0x52, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x0F, 0x90, 0x8A, 0xD7, +0x12, 0x43, 0x6B, 0xC1, 0xA6, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x75, 0x9A, 0x90, 0x8A, +0xD7, 0x12, 0x43, 0x6B, 0x81, 0x1E, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x78, 0x81, 0x90, +0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x7A, 0xC2, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x7C, +0x2B, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFD, 0x70, +0x02, 0xC1, 0xA1, 0x90, 0x8B, 0x51, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xC1, 0x9A, 0x90, +0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD0, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD0, +0xF0, 0x75, 0x1D, 0x01, 0x75, 0x1E, 0x8A, 0x75, 0x1F, 0xD0, 0x75, 0x20, 0x01, 0x7B, 0x01, 0x7A, +0x8A, 0x79, 0xD1, 0x12, 0x5E, 0xE4, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54, +0x01, 0x90, 0x8B, 0x51, 0x30, 0xE0, 0x59, 0xE0, 0x75, 0xF0, 0x02, 0x90, 0x00, 0x88, 0x12, 0x43, +0x5F, 0xE0, 0x90, 0x8A, 0xD2, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x02, 0x90, 0x00, 0x89, +0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD3, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, +0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD4, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, +0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD5, 0xF0, 0x90, 0x8B, 0x51, 0xE0, +0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD6, 0xF0, 0x80, 0x33, +0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD2, 0xF0, 0x90, +0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD3, +0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, 0x5F, 0xE0, 0x90, +0x8A, 0xD4, 0xF0, 0xEF, 0x54, 0x7F, 0xFF, 0x7B, 0x01, 0x7A, 0x8A, 0x79, 0xD2, 0x91, 0xA6, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x90, 0x8B, 0x51, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, +0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0xFF, 0x74, +0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x8B, +0x51, 0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0xA1, 0x6A, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x02, +0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, 0xFF, 0x54, 0x1F, 0xFE, +0xEF, 0x54, 0x20, 0xC4, 0x13, 0x54, 0x07, 0xFD, 0xAF, 0x06, 0x90, 0x8A, 0xDA, 0xEF, 0xF0, 0xA3, +0xED, 0xF0, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x03, 0x12, +0x42, 0x20, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x00, 0x04, 0x12, 0x42, +0x20, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x8A, 0xE0, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, +0xFF, 0x75, 0xF0, 0x09, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0xAD, 0x82, 0xAC, 0x83, 0x90, 0x8A, +0xE1, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0x23, 0xF9, 0x74, 0x87, +0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, +0x00, 0x03, 0x12, 0x42, 0x20, 0x54, 0x0F, 0xFF, 0x90, 0x8A, 0xE3, 0x12, 0x43, 0x6B, 0xEF, 0x12, +0x42, 0x4D, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x90, +0x8A, 0xE3, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x90, 0x8A, 0xDC, 0x12, +0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, 0xFC, 0xA3, 0xE0, +0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xEF, 0xF0, 0x12, 0x29, 0xD9, 0x8D, 0x82, 0x8C, 0x83, 0xA3, 0xF0, +0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x24, 0xC1, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xDB, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, +0x29, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, 0x12, 0x43, 0x5F, +0x74, 0x01, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2B, 0x12, +0x43, 0x5F, 0xEE, 0xF0, 0x8F, 0x0F, 0xEF, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, +0xAF, 0x82, 0xF5, 0x10, 0x8F, 0x11, 0xE5, 0x0F, 0x75, 0xF0, 0x02, 0xA4, 0x24, 0x81, 0xF9, 0x74, +0x86, 0x35, 0xF0, 0x75, 0x12, 0x01, 0xF5, 0x13, 0x89, 0x14, 0x75, 0xF0, 0x09, 0xE5, 0x0F, 0x90, +0x87, 0x25, 0x12, 0x43, 0x5F, 0xAF, 0x82, 0x85, 0x83, 0x15, 0x8F, 0x16, 0xE5, 0x0F, 0x75, 0xF0, +0x09, 0xA4, 0x24, 0x23, 0xF9, 0x74, 0x87, 0x35, 0xF0, 0x75, 0x17, 0x01, 0xF5, 0x18, 0x89, 0x19, +0x74, 0xC1, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x12, 0x43, 0x94, 0x58, +0x34, 0x00, 0x58, 0x49, 0x01, 0x58, 0x5E, 0x02, 0x58, 0x73, 0x03, 0x58, 0x9C, 0x04, 0x58, 0xB1, +0x05, 0x58, 0xC6, 0x06, 0x58, 0xEC, 0x0C, 0x59, 0x19, 0x0D, 0x59, 0x46, 0x0E, 0x59, 0x73, 0x0F, +0x00, 0x00, 0x59, 0xA7, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x15, 0x80, 0x3C, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x10, 0x80, 0x27, 0xE5, 0x0F, +0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, +0x05, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0x74, 0xF0, 0xF0, 0xA3, 0xE4, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0x8F, 0xF0, 0x21, 0xA7, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0xF5, 0x80, +0x27, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0x0F, +0xF0, 0xA3, 0x74, 0xF0, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0x74, 0x0D, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, +0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x21, 0xA7, 0x90, 0x04, 0x47, 0xE0, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x46, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x45, 0xE0, 0x85, 0x11, 0x82, +0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x44, 0x21, 0x9E, 0x90, 0x04, 0x4B, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x4A, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x49, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, +0xF0, 0x90, 0x04, 0x48, 0x80, 0x58, 0x90, 0x04, 0x4F, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x12, 0x42, 0x4D, 0x90, 0x04, 0x4E, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, +0x12, 0x42, 0x5F, 0x90, 0x04, 0x4D, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, +0x4C, 0x80, 0x2B, 0x90, 0x04, 0x53, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, +0x90, 0x04, 0x52, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, +0x90, 0x04, 0x51, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x50, 0xE0, 0x85, +0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0xC0, 0x03, 0xC0, +0x02, 0xC0, 0x01, 0x12, 0x29, 0xD9, 0xFF, 0xAB, 0x17, 0xAA, 0x18, 0xA9, 0x19, 0x12, 0x29, 0xD9, +0x5F, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x42, 0x4D, 0xAB, 0x12, 0xE5, 0x14, 0x24, 0x01, +0xF9, 0xE4, 0x35, 0x13, 0xFA, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x12, 0x29, 0xD9, 0xFF, 0xAB, +0x17, 0xAA, 0x18, 0xA9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x5F, 0xD0, 0x01, 0xD0, 0x02, +0xD0, 0x03, 0x12, 0x42, 0x4D, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, +0xFF, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, +0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x85, 0x16, 0x82, +0x85, 0x15, 0x83, 0xA3, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xE5, 0x0F, 0x25, +0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, +0x4B, 0x90, 0x8A, 0xE6, 0x74, 0x0B, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x00, 0x50, +0x02, 0x41, 0xEC, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, +0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x0A, 0x90, 0x8A, 0xE6, 0xE0, 0x24, 0x10, +0xA3, 0xF0, 0x80, 0x68, 0x90, 0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBB, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x47, +0x90, 0x8A, 0xE6, 0x74, 0x0F, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x00, 0x40, 0x3C, +0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x5E, +0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x08, 0x90, 0x8A, 0xE6, 0xE0, 0xA3, 0xF0, 0x80, 0x0D, 0x90, +0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBF, 0xE4, 0x90, 0x8A, 0xE7, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x46, +0xE4, 0x90, 0x8A, 0xE6, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x40, 0x02, 0x61, +0xA5, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, +0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x06, 0x90, 0x8A, 0xE6, 0xE0, 0x80, 0x63, 0x90, 0x8A, +0xE6, 0xE0, 0x04, 0xF0, 0x80, 0xBF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x46, 0xE4, 0x90, 0x8A, 0xE6, 0xF0, 0x90, +0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x0C, 0x50, 0x3C, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, +0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x08, +0x90, 0x8A, 0xE6, 0xE0, 0x24, 0x10, 0x80, 0x09, 0x90, 0x8A, 0xE6, 0xE0, 0x04, 0xF0, 0x80, 0xBF, +0xE4, 0x90, 0x8A, 0xE8, 0xF0, 0x90, 0x8A, 0xE7, 0xE0, 0xFF, 0x75, 0xF0, 0x09, 0xE5, 0x0F, 0x90, +0x87, 0x27, 0x12, 0x43, 0x5F, 0xEF, 0xF0, 0x90, 0x8A, 0xE8, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xE5, +0x0F, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xE5, 0x0F, 0xC3, 0x94, 0x20, 0x50, 0x32, +0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xD3, 0x9F, 0x40, 0x02, +0x80, 0x18, 0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xC3, 0x9E, +0x50, 0x08, 0x90, 0x8A, 0xE8, 0xE0, 0xA3, 0xF0, 0x80, 0x08, 0x90, 0x8A, 0xE7, 0xE0, 0x90, 0x8A, +0xE9, 0xF0, 0x90, 0x8A, 0xE9, 0xE0, 0xFD, 0xAF, 0x0F, 0x91, 0x4E, 0x90, 0x8A, 0xE9, 0xE0, 0xFF, +0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x8A, 0xE7, +0xE0, 0xFF, 0xD3, 0x94, 0x13, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x03, 0xF0, 0x22, 0xEF, 0xD3, +0x94, 0x0B, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x02, 0xF0, 0x22, 0xEF, 0xD3, 0x94, 0x03, 0x40, +0x07, 0x90, 0x87, 0x22, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0x87, 0x22, 0xF0, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x74, 0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xED, +0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAC, 0x07, 0xED, 0x54, 0x1F, 0x90, 0x8A, 0xC7, 0xF0, 0x74, +0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xC5, 0xF0, 0x90, 0x8A, +0xC8, 0x74, 0x01, 0xF0, 0xEB, 0xC3, 0x94, 0x01, 0x40, 0x02, 0x80, 0x37, 0x90, 0x8A, 0xC5, 0xE0, +0x25, 0x0D, 0xFF, 0xA3, 0xF0, 0xA3, 0xE0, 0x90, 0x41, 0x9E, 0x93, 0xFE, 0xEF, 0xD3, 0x9E, 0x40, +0x10, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xAF, 0x04, 0x80, +0x9D, 0x90, 0x8A, 0xC6, 0xE0, 0xFF, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEF, 0xF0, 0x22, 0xAD, 0x07, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, +0xFF, 0x90, 0x8A, 0xCA, 0xF0, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, +0x54, 0x1F, 0x90, 0x8A, 0xC9, 0xF0, 0xD3, 0x9F, 0x40, 0x06, 0xA3, 0xE0, 0x90, 0x8A, 0xC9, 0xF0, +0x90, 0x8A, 0xC9, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, +0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, +0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xC9, 0xE0, 0xFD, 0x91, 0x4E, 0x90, 0x8A, 0xC9, 0xE0, 0xFF, +0x22, 0xAC, 0x07, 0x74, 0x84, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x7F, +0x90, 0x8A, 0xDE, 0xF0, 0xE0, 0x54, 0x1F, 0xFF, 0x90, 0x8A, 0xE1, 0xF0, 0x75, 0xF0, 0x09, 0xEC, +0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xE3, 0xF0, 0x75, 0xF0, 0x09, 0xEC, 0x90, +0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0x90, 0x8A, 0xE4, 0xF0, 0xEC, 0x25, 0xE0, 0x24, 0xE4, +0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE5, 0xCB, 0xF0, +0xA3, 0xEB, 0xF0, 0xEC, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, +0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE7, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xEF, 0xD3, 0x9E, 0x40, 0x0C, +0x90, 0x8A, 0xE4, 0xE0, 0x90, 0x8A, 0xE1, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0xED, 0x70, 0x02, 0xC1, +0x93, 0x90, 0x8A, 0xE2, 0xED, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0x30, 0xE6, 0x0E, 0x90, 0x8A, 0xE1, +0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0x14, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0x70, +0x02, 0xC1, 0x93, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0xD3, 0x94, 0x00, 0x50, 0x02, 0xC1, 0x93, 0xE4, +0x90, 0x8A, 0xE0, 0xF0, 0xEF, 0x14, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xE3, 0xE0, 0xFD, 0x90, +0x8A, 0xDF, 0xE0, 0xFF, 0xD3, 0x9D, 0x40, 0x6F, 0xEF, 0x94, 0x10, 0x40, 0x21, 0xEF, 0x24, 0xF0, +0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x8A, 0xE7, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x70, 0x27, 0x90, 0x8A, +0xDF, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x37, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE5, 0xE0, 0x5E, 0xFE, 0xA3, +0xE0, 0x5F, 0x4E, 0x60, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0x04, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, 0x6F, 0x60, 0x08, 0x90, +0x8A, 0xDF, 0xE0, 0x14, 0xF0, 0x80, 0x83, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, +0xC3, 0x9F, 0x50, 0x0F, 0x90, 0x8A, 0xDF, 0xE0, 0xB5, 0x05, 0x08, 0x90, 0x8A, 0xE3, 0xE0, 0x90, +0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, +0xFE, 0xEF, 0x13, 0xFF, 0xEC, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x90, 0x8A, 0xDE, 0xE0, 0xFD, 0x91, 0x4E, 0x90, 0x8A, +0xDE, 0xE0, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x1A, 0x8A, 0x1B, 0x89, +0x1C, 0x90, 0x8B, 0x3F, 0x12, 0x43, 0x8B, 0xAB, 0x1D, 0xAA, 0x1E, 0xA9, 0x1F, 0x90, 0x8B, 0x42, +0x12, 0x43, 0x8B, 0xAF, 0x20, 0x15, 0x20, 0xEF, 0x60, 0x1E, 0x90, 0x8B, 0x42, 0xE4, 0x75, 0xF0, +0x01, 0x12, 0x43, 0x74, 0x12, 0x29, 0xD9, 0xFF, 0x90, 0x8B, 0x3F, 0xE4, 0x75, 0xF0, 0x01, 0x12, +0x43, 0x74, 0xEF, 0x12, 0x42, 0x4D, 0x80, 0xDB, 0xAB, 0x1A, 0xAA, 0x1B, 0xA9, 0x1C, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x8B, +0x90, 0x8B, 0x53, 0xE0, 0xFF, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x7F, 0xAF, +0x7E, 0x01, 0x12, 0x74, 0x3B, 0xEF, 0x60, 0x47, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x6B, 0x8B, 0x1D, +0x8A, 0x1E, 0x89, 0x1F, 0x75, 0x20, 0x02, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0xD1, 0xE4, 0x90, +0x8B, 0x48, 0x12, 0x43, 0x6B, 0x8B, 0x1D, 0x8A, 0x1E, 0x89, 0x1F, 0x90, 0x8B, 0x45, 0x12, 0x43, +0x6B, 0x12, 0x29, 0xD9, 0xFF, 0xC4, 0x54, 0x0F, 0xF5, 0x20, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA2, +0xD1, 0xE4, 0x90, 0x01, 0xAF, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8A, 0xC5, 0xE0, 0x54, 0xF0, 0x44, 0x03, 0xF0, 0x54, 0x0F, 0x44, +0x80, 0xF0, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x56, 0x90, 0x8B, 0x48, 0x12, 0x43, 0x8B, 0x0B, 0x7A, +0x8A, 0x79, 0xC5, 0xE1, 0x33, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0xC4, 0x74, +0xC5, 0xF0, 0x74, 0x5F, 0xA3, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A, 0x90, 0x05, 0x22, 0xE0, +0x54, 0x90, 0x60, 0x07, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x01, 0xC7, 0xE0, 0x30, +0xE1, 0xE4, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFB, 0xFA, 0xEF, 0x30, 0xE0, 0x02, 0x7B, 0x80, 0xEF, 0xC3, 0x13, +0x90, 0xFD, 0x10, 0xF0, 0x90, 0x04, 0x25, 0xEF, 0xF0, 0xED, 0x60, 0x1E, 0xAF, 0x03, 0x74, 0x0F, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x10, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x03, 0x74, 0x08, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0x21, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0x54, 0xF7, 0xF0, 0xAE, 0x02, 0xAF, 0x03, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x5F, 0xC5, +0xBF, 0x01, 0x10, 0x90, 0x02, 0x09, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, 0x90, 0x04, 0x1F, +0x74, 0x20, 0xF0, 0x22, 0x90, 0x01, 0x02, 0xE0, 0x54, 0x03, 0xFF, 0xE0, 0x54, 0x0C, 0x13, 0x13, +0x54, 0x3F, 0xFE, 0xEF, 0x64, 0x01, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x0E, 0x90, 0x8A, 0xC5, 0x74, +0x01, 0xF0, 0xA3, 0x74, 0x37, 0xF0, 0x79, 0x01, 0x80, 0x18, 0xEE, 0x64, 0x01, 0x60, 0x07, 0xAF, +0x06, 0xEE, 0x64, 0x03, 0x70, 0x3B, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x3D, 0xF0, +0x79, 0x40, 0x90, 0x8A, 0xC5, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x59, +0x60, 0x08, 0xE9, 0xF0, 0xE4, 0x90, 0x8A, 0xF6, 0xF0, 0x22, 0x90, 0x8A, 0xF6, 0xE0, 0x04, 0xF0, +0xE0, 0xC3, 0x94, 0x0A, 0x40, 0x0B, 0xE4, 0xF0, 0x90, 0x04, 0x19, 0xE0, 0x30, 0xE0, 0x02, 0x11, +0x6D, 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, 0xF2, 0xF0, 0x74, 0x60, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x28, 0xF5, +0x2C, 0xA3, 0xE0, 0x55, 0x29, 0xF5, 0x2D, 0xA3, 0xE0, 0x55, 0x2A, 0xF5, 0x2E, 0xA3, 0xE0, 0x55, +0x2B, 0xF5, 0x2F, 0xE5, 0x2C, 0x20, 0xE0, 0x02, 0x41, 0x89, 0x90, 0x01, 0x34, 0x74, 0x01, 0xF0, +0x85, 0xD1, 0x4D, 0x85, 0xD2, 0x4E, 0x85, 0xD3, 0x4F, 0x85, 0xD4, 0x50, 0x85, 0xD5, 0x51, 0x85, +0xD6, 0x52, 0x85, 0xD7, 0x53, 0x85, 0xD9, 0x54, 0xE5, 0x54, 0x54, 0x40, 0xC3, 0x13, 0xFF, 0xE5, +0x53, 0x54, 0x20, 0x6F, 0x70, 0x02, 0x41, 0x46, 0xE5, 0x54, 0x30, 0xE5, 0x02, 0x41, 0x46, 0xE5, +0x52, 0x54, 0x1F, 0xF5, 0x08, 0xE5, 0x4D, 0x54, 0x3F, 0xF5, 0x09, 0xE5, 0x51, 0x54, 0x1F, 0xFF, +0xE5, 0x08, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, +0x12, 0x42, 0x81, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, +0xE4, 0x34, 0x85, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x09, 0xD3, 0x94, 0x04, +0x40, 0x03, 0x75, 0x09, 0x04, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, 0x43, 0x5F, +0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE5, 0x53, 0x54, +0x1F, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, 0x43, +0x5F, 0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x54, +0x20, 0xE6, 0x24, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, +0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x4F, 0x30, 0xE7, 0x36, +0xAF, 0x08, 0x12, 0x5C, 0xC3, 0x80, 0x2F, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, +0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, +0x4F, 0x30, 0xE7, 0x12, 0xE5, 0x4F, 0x54, 0x7F, 0xFD, 0xE5, 0x53, 0x54, 0x1F, 0xF5, 0x0D, 0xAB, +0x09, 0xAF, 0x08, 0x12, 0x5C, 0x66, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x3A, 0x90, +0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, +0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x21, 0x90, 0x8B, 0x3D, 0x12, 0x4B, 0x5C, 0x90, 0x01, +0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x80, 0x09, +0x12, 0x4B, 0x34, 0xBF, 0x01, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2C, 0x30, 0xE1, 0x21, 0x90, 0x01, +0x34, 0x74, 0x02, 0xF0, 0x85, 0xD1, 0x56, 0x85, 0xD2, 0x57, 0x85, 0xD3, 0x58, 0x85, 0xD4, 0x59, +0x85, 0xD5, 0x5A, 0x85, 0xD6, 0x5B, 0x85, 0xD7, 0x5C, 0x85, 0xD9, 0x5D, 0x12, 0x5F, 0xA4, 0xE5, +0x2C, 0x30, 0xE3, 0x06, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0xE5, 0x2C, 0x30, 0xE4, 0x09, 0x90, +0x01, 0x34, 0x74, 0x10, 0xF0, 0x43, 0x55, 0x10, 0xE5, 0x2C, 0x30, 0xE5, 0x26, 0x90, 0x01, 0xCF, +0xE0, 0x30, 0xE5, 0x1F, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0x75, 0xA8, +0x00, 0x75, 0xE8, 0x00, 0x12, 0x51, 0x9D, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x12, 0x52, +0x0E, 0x80, 0xFE, 0xE5, 0x2C, 0x30, 0xE6, 0x2D, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0x90, 0x8B, +0x32, 0xE0, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, 0x90, 0x8B, 0x34, 0xE4, +0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, +0x90, 0x8B, 0x2E, 0xE4, 0xF0, 0xE5, 0x2E, 0x20, 0xE0, 0x02, 0x61, 0xE6, 0x90, 0x8B, 0x08, 0x74, +0x01, 0xF0, 0x90, 0x01, 0x36, 0xF0, 0x90, 0x8B, 0x06, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, +0x53, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, +0xE0, 0x2F, 0x90, 0x8B, 0x37, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, +0x3F, 0x30, 0xE0, 0x1D, 0x90, 0x8B, 0x34, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0D, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x7F, 0x04, 0x12, 0x4E, +0x89, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x55, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x4E, +0x90, 0x8B, 0x2E, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x3E, +0xB1, 0x5F, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, +0x2D, 0xEF, 0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, +0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x02, 0x04, 0x7F, 0x01, 0xB1, 0x82, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x43, +0xE7, 0x90, 0x8B, 0x08, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE1, 0x2F, 0x90, 0x01, 0x36, 0x74, 0x02, +0xF0, 0x43, 0x55, 0x40, 0x11, 0x84, 0x90, 0x8B, 0x37, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x05, 0x22, +0xE4, 0xF0, 0x90, 0x8B, 0x37, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x0D, 0xE4, 0xFF, 0x12, +0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE2, 0x16, 0x90, +0x01, 0x36, 0x74, 0x04, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x06, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x03, 0x12, 0x46, 0xB3, 0xE5, 0x2E, 0x30, 0xE3, 0x38, 0x90, 0x01, 0x36, 0x74, 0x08, 0xF0, +0xE5, 0x21, 0x64, 0x01, 0x70, 0x2C, 0xE5, 0x24, 0x60, 0x28, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, +0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, 0x8B, +0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, +0x05, 0xF0, 0xE5, 0x2E, 0x30, 0xE4, 0x2B, 0x90, 0x01, 0x36, 0x74, 0x10, 0xF0, 0xE5, 0x21, 0xB4, +0x01, 0x20, 0xE5, 0x24, 0x60, 0x1C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, +0xF0, 0x90, 0x8B, 0x1B, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x03, 0x12, +0x4A, 0xFC, 0xE5, 0x2E, 0x30, 0xE5, 0x1F, 0x90, 0x01, 0x36, 0x74, 0x20, 0xF0, 0xE5, 0x21, 0xB4, +0x01, 0x14, 0xE5, 0x24, 0x60, 0x10, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, 0x4A, +0x97, 0x80, 0x03, 0x12, 0x49, 0x49, 0xE5, 0x2E, 0x30, 0xE6, 0x1B, 0x90, 0x01, 0x36, 0x74, 0x40, +0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x10, 0xE5, 0x24, 0x60, 0x0C, 0x53, 0x25, 0xFE, 0xE5, 0x25, 0x54, +0x07, 0x70, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2F, 0x30, 0xE1, 0x28, 0x90, 0x01, 0x37, 0x74, 0x02, +0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x18, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x08, +0x12, 0x48, 0xFE, 0x12, 0x7D, 0xC1, 0x80, 0x0B, 0x90, 0x8B, 0x31, 0x74, 0x01, 0xF0, 0x80, 0x03, +0x12, 0x48, 0xFE, 0x74, 0xF2, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x60, 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, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x05, +0x58, 0xE0, 0xFF, 0x90, 0x8B, 0x38, 0xE0, 0x2F, 0x24, 0xFE, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, +0xFD, 0x7F, 0x50, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x53, 0x74, 0x05, 0xF0, 0x22, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x0A, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x04, 0x7F, 0x06, 0xB1, 0x82, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x03, 0x12, 0x78, +0x35, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0x6F, 0x70, +0x02, 0xE1, 0x4E, 0xEF, 0x12, 0x43, 0x94, 0x65, 0xB0, 0x00, 0x65, 0xEA, 0x01, 0x66, 0x30, 0x02, +0x66, 0x6A, 0x03, 0x66, 0xA2, 0x04, 0x66, 0xDB, 0x05, 0x67, 0x16, 0x06, 0x00, 0x00, 0x67, 0x4E, +0xEE, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, 0x81, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0xB4, +0x05, 0x04, 0xF1, 0x5D, 0xE1, 0x4E, 0xEF, 0xB4, 0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0x80, 0x16, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xA4, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, +0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, +0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, +0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0xE1, 0x4E, 0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, +0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x02, 0x60, 0x02, 0xE1, 0x4E, 0xF1, 0x67, 0xE1, 0x4E, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0x80, 0x16, +0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0x80, 0x08, 0xEE, 0xB4, +0x03, 0x04, 0x7F, 0x01, 0xF1, 0x53, 0xF1, 0xD0, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, +0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, +0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, +0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x06, 0xEE, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xB9, +0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x13, +0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, +0x02, 0xF1, 0x67, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0xF1, 0xA4, 0x80, 0x09, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0xF1, 0xAF, 0x80, 0x73, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, +0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x13, 0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, +0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0x90, 0x8B, 0x2D, 0xE0, +0xB4, 0x01, 0x04, 0xF1, 0xA4, 0x80, 0x0B, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x04, 0x7F, 0x01, +0xF1, 0x81, 0xF1, 0xC3, 0x80, 0x38, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, +0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0x90, 0x8B, 0x2D, 0xE0, +0x70, 0x04, 0xF1, 0x9A, 0x80, 0x16, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x06, 0xE4, 0xFF, 0xF1, +0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xDD, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x12, 0x4A, 0xB2, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x22, 0x90, 0x05, 0x22, +0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0x04, +0xF0, 0x22, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, +0x22, 0x90, 0x8B, 0x56, 0xEF, 0xF0, 0x12, 0x7D, 0x42, 0x90, 0x8B, 0x56, 0xE0, 0x60, 0x05, 0x90, +0x05, 0x22, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x12, 0x4A, 0xCC, 0x90, 0x8B, 0x2D, +0x74, 0x01, 0xF0, 0x22, 0x7F, 0x01, 0x12, 0x4A, 0x7C, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x12, +0x7C, 0x4A, 0x90, 0x8B, 0x2D, 0x74, 0x04, 0xF0, 0x22, 0x12, 0x4A, 0x32, 0x90, 0x8B, 0x2D, 0x74, +0x03, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x05, 0xF0, 0x22, +0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, +0x74, 0x6F, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x06, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0xE4, 0xFD, 0xFC, 0xEF, 0x30, 0xE0, 0x02, 0x7D, 0x80, 0xEF, 0xC3, 0x13, 0x90, 0xFD, 0x10, +0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0x28, 0x33, 0xE4, 0xF5, 0x29, +0x75, 0x2A, 0x07, 0xF5, 0x2B, 0x90, 0x01, 0x30, 0xE5, 0x28, 0xF0, 0xA3, 0xE5, 0x29, 0xF0, 0xA3, +0xE5, 0x2A, 0xF0, 0xA3, 0xE5, 0x2B, 0xF0, 0x22, 0x75, 0x30, 0x1F, 0x75, 0x31, 0x01, 0x43, 0x31, +0x10, 0xE4, 0xF5, 0x32, 0x90, 0x01, 0x38, 0xE5, 0x30, 0xF0, 0xA3, 0xE5, 0x31, 0xF0, 0xA3, 0xE5, +0x32, 0xF0, 0x22, 0x22, 0x90, 0x00, 0x02, 0xE0, 0x54, 0xE0, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, +0x22, 0x90, 0x00, 0xF3, 0xE0, 0x7F, 0x00, 0x30, 0xE3, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x09, +0xE0, 0xB4, 0x01, 0x0C, 0x90, 0x00, 0xF2, 0xE0, 0x30, 0xE7, 0x05, 0x7E, 0xFD, 0x7F, 0x33, 0x22, +0x7E, 0xFD, 0x7F, 0x2F, 0x22, 0x90, 0x00, 0xF3, 0xE0, 0x30, 0xE2, 0x0D, 0x90, 0x05, 0x41, 0x74, +0x10, 0xF0, 0x90, 0x05, 0x5A, 0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x64, 0x74, 0xA0, 0xF0, +0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x06, +0xC0, 0x07, 0x7D, 0x91, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x68, 0xFF, 0xA3, 0xF0, 0x53, 0x91, +0xEF, 0x90, 0x00, 0x51, 0xE0, 0xFE, 0x90, 0x00, 0x55, 0xE0, 0x5E, 0xF5, 0x3D, 0x90, 0x00, 0x52, +0xE0, 0xFE, 0x90, 0x00, 0x56, 0xE0, 0x5E, 0xF5, 0x3E, 0xE5, 0x3D, 0x30, 0xE4, 0x06, 0x90, 0x00, +0x55, 0x74, 0x10, 0xF0, 0xE5, 0x3D, 0x30, 0xE5, 0x06, 0x90, 0x00, 0x55, 0x74, 0x20, 0xF0, 0xE5, +0x3D, 0x30, 0xE6, 0x06, 0x90, 0x00, 0x55, 0x74, 0x40, 0xF0, 0xE5, 0x3D, 0x30, 0xE7, 0x06, 0x90, +0x00, 0x55, 0x74, 0x80, 0xF0, 0xE5, 0x3E, 0x30, 0xE0, 0x06, 0x90, 0x00, 0x56, 0x74, 0x01, 0xF0, +0xE5, 0x3E, 0x30, 0xE1, 0x06, 0x90, 0x00, 0x56, 0x74, 0x02, 0xF0, 0xE5, 0x3E, 0x30, 0xE2, 0x06, +0x90, 0x00, 0x56, 0x74, 0x04, 0xF0, 0xE5, 0x3E, 0x30, 0xE3, 0x06, 0x90, 0x00, 0x56, 0x74, 0x08, +0xF0, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, +0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xEF, 0xC3, 0x94, 0x20, 0x50, 0x39, 0xEF, 0x30, +0xE0, 0x17, 0xED, 0xC4, 0x54, 0xF0, 0xFD, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x0F, 0x80, 0x10, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, +0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0xA4, 0x2E, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x4D, 0xF0, 0x22, 0xAD, 0x07, 0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0x90, 0x8A, 0xDE, 0xF0, 0xE0, 0xF9, 0x54, 0x1F, 0xA3, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0xFF, 0x90, 0x8A, 0xE1, +0xF0, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, +0xE0, 0x90, 0x8A, 0xE2, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xED, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, +0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE4, 0xCB, 0xF0, 0xA3, 0xEB, +0xF0, 0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, +0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, +0x34, 0x86, 0xF5, 0x83, 0xEA, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0xB9, +0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, +0xF0, 0xEF, 0x04, 0x90, 0x8A, 0xE0, 0xF0, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, +0xFE, 0xD3, 0x9F, 0x40, 0x02, 0x41, 0xF3, 0xEE, 0xC3, 0x94, 0x10, 0x40, 0x21, 0xEE, 0x24, 0xF0, +0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x8A, 0xE2, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x70, 0x27, 0x90, 0x8A, +0xE0, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x59, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE4, 0xE0, 0x5E, 0xFE, 0xA3, +0xE0, 0x5F, 0x4E, 0x60, 0x3C, 0x90, 0x8A, 0xE0, 0xE0, 0xB4, 0x11, 0x0D, 0x90, 0x8A, 0xE3, 0xE0, +0x30, 0xE7, 0x06, 0x90, 0x8A, 0xE0, 0x74, 0x17, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFF, 0x64, 0x13, +0x60, 0x04, 0xEF, 0xB4, 0x12, 0x0D, 0x90, 0x8A, 0xE2, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x8A, 0xE0, +0x74, 0x18, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0x80, +0x42, 0x90, 0x8A, 0xE0, 0xE0, 0x04, 0xF0, 0x41, 0x17, 0x90, 0x8A, 0xE1, 0xE0, 0xFC, 0x90, 0x8A, +0xDF, 0xE0, 0xFF, 0x6C, 0x70, 0x71, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, +0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x29, 0x12, 0x43, 0x5F, 0xE0, 0xB4, 0x01, 0x10, +0xE9, 0x20, 0xE6, 0x0C, 0x90, 0x8A, 0xDF, 0xE0, 0x44, 0x40, 0x90, 0x8A, 0xDE, 0xF0, 0x80, 0x03, +0xAF, 0x01, 0x22, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, +0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x66, 0x90, 0x8A, 0xDF, 0xE0, 0xD3, 0x9C, 0x40, 0x5E, 0x90, +0x8A, 0xE1, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x8A, 0xDF, 0xEF, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0xFC, 0xA3, 0xE0, 0xFF, 0x25, 0xE0, 0x24, +0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, +0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, +0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, +0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x22, 0x74, 0x01, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xDE, 0xE0, 0x44, +0x80, 0xFD, 0x12, 0x5C, 0x4E, 0x90, 0x8A, 0xDE, 0xE0, 0x44, 0x80, 0xFF, 0x22, 0xE4, 0x90, 0x8A, +0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, 0x03, 0x02, 0x72, 0x54, 0x75, +0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, 0x12, 0x43, 0x5F, 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x72, +0x4B, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, +0xE0, 0xFC, 0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEC, 0x94, 0x00, 0x50, 0x03, 0x02, 0x72, 0x4B, 0xEF, +0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x00, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0x75, 0x12, 0x01, 0xF5, 0x13, +0x89, 0x14, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, +0x83, 0xE0, 0xFD, 0xA3, 0xE0, 0x90, 0x8A, 0xD4, 0xCD, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, 0x25, 0xE0, +0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xD6, +0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, +0x04, 0xF5, 0x83, 0xE0, 0x54, 0x3F, 0x90, 0x8A, 0xD0, 0xF0, 0xE0, 0xFD, 0x54, 0x1F, 0xA3, 0xF0, +0x75, 0xF0, 0x09, 0xEE, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD9, 0xF0, 0x90, +0x8A, 0xCF, 0xE0, 0xFB, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xC3, 0x94, +0x05, 0x40, 0x02, 0xC1, 0x9C, 0x90, 0x8A, 0xD9, 0xE0, 0xFE, 0x90, 0x8A, 0xD1, 0xE0, 0x9E, 0x40, +0x13, 0x90, 0x8A, 0xD9, 0xE0, 0x90, 0x8A, 0xD1, 0xF0, 0xED, 0x54, 0x40, 0xFD, 0x90, 0x8A, 0xD0, +0xF0, 0xEE, 0x4D, 0xF0, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0x90, 0x41, 0x12, 0x93, 0xFE, 0x74, 0x23, +0x2B, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xC3, 0x9E, 0x40, 0x06, 0xEF, 0x90, 0x40, +0xDA, 0x80, 0x07, 0x90, 0x8A, 0xD1, 0xE0, 0x90, 0x40, 0xF6, 0x93, 0x90, 0x8A, 0xD8, 0xF0, 0x90, +0x8A, 0xD8, 0xE0, 0x75, 0xF0, 0x06, 0xA4, 0x24, 0x50, 0xF9, 0x74, 0x40, 0x35, 0xF0, 0x75, 0x0F, +0xFF, 0xF5, 0x10, 0x89, 0x11, 0x90, 0x8A, 0xD0, 0xE0, 0x90, 0x41, 0xBA, 0x93, 0xFF, 0xD3, 0x90, +0x8A, 0xD7, 0xE0, 0x9F, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0xE4, 0xFD, 0x12, 0x5D, 0x41, 0x02, 0x71, 0xE1, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, +0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xD2, 0xCF, +0xF0, 0xA3, 0xEF, 0xF0, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x12, 0x29, 0xD9, 0xFF, 0x7E, 0x00, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x97, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, +0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, +0x01, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x02, +0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, +0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x7E, +0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x04, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, +0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, +0xA9, 0x11, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, +0x14, 0x90, 0x00, 0x06, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, +0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x04, 0x12, +0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x08, 0x12, 0x42, +0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, +0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x05, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0x90, +0x8A, 0xD4, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x29, 0xF2, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, 0x9F, +0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x0C, 0xA3, 0xE0, 0x9F, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, +0xF0, 0x80, 0x07, 0xE4, 0x90, 0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, +0xF5, 0x83, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xD3, 0xED, 0x9B, +0xEC, 0x9A, 0x40, 0x05, 0x31, 0x78, 0x02, 0x71, 0xAF, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, +0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0xFF, 0xC3, +0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x71, 0xAF, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5D, 0x41, 0x02, 0x71, 0xAF, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xFC, 0x64, 0x05, 0x60, 0x03, +0x02, 0x70, 0x7D, 0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x03, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, +0x94, 0x19, 0x40, 0x3D, 0x80, 0x2E, 0xEE, 0xB4, 0x02, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, +0x11, 0x40, 0x2E, 0x80, 0x1F, 0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x01, 0x0B, 0x90, 0x8A, 0xD1, +0xE0, 0xC3, 0x94, 0x0A, 0x40, 0x1B, 0x80, 0x0C, 0xEE, 0x70, 0x11, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, +0x94, 0x03, 0x40, 0x0D, 0x90, 0x89, 0x43, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x89, 0x43, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, +0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x23, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, +0xC3, 0x94, 0x30, 0x50, 0x0B, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0x02, 0x70, 0x28, +0x90, 0x89, 0x43, 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x70, 0x1D, 0x90, 0x8A, 0xCF, 0xE0, 0x24, +0x44, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x64, 0x0A, 0x60, 0x5B, 0x90, 0x8A, 0xCF, +0xE0, 0xFF, 0xEE, 0x24, 0x05, 0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xE0, 0xFF, 0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x50, 0x38, +0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0xEF, 0x24, 0x05, 0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x23, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, +0x50, 0x16, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, +0xFF, 0x90, 0x8A, 0xD1, 0xE0, 0x6F, 0x60, 0x56, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x23, 0xF5, 0x82, +0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFF, 0xD3, 0x94, 0x42, 0x40, 0x08, 0x90, 0x8A, 0xDD, 0x74, +0x05, 0xF0, 0x80, 0x11, 0xEF, 0xD3, 0x94, 0x39, 0x90, 0x8A, 0xDD, 0x40, 0x05, 0x74, 0x03, 0xF0, +0x80, 0x03, 0x74, 0x01, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x23, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x44, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0x80, 0x2F, 0x90, 0x8A, +0xCF, 0xE0, 0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x44, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x80, 0x14, 0xE4, 0x90, 0x8A, +0xDD, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0x90, 0x8A, 0xD1, 0xE0, 0xFE, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x84, 0xF5, 0x82, 0xE4, +0x34, 0x8A, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFE, 0x74, 0x43, 0x2F, 0xF5, 0x82, +0xE4, 0x34, 0x88, 0xF5, 0x83, 0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2B, 0x12, 0x43, +0x5F, 0xE0, 0xB4, 0x01, 0x11, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0xF5, 0x82, 0xE4, +0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0x21, 0xAC, 0xEC, 0x64, 0x06, +0x60, 0x02, 0x21, 0xAF, 0x90, 0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x41, 0xDB, 0x93, 0xFF, 0x7E, +0x00, 0x90, 0x8A, 0xD4, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xDB, 0xEE, +0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE0, 0x90, 0x8A, 0xDD, 0xF0, 0xE4, 0x90, 0x8A, 0xDA, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, +0xD3, 0x94, 0x04, 0x50, 0x47, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x75, 0xF0, 0x02, 0xEF, 0xA4, +0xF5, 0x82, 0x85, 0xF0, 0x83, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0xEF, 0x90, 0x41, 0xD6, 0x93, +0xFF, 0x7E, 0x00, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0x90, +0x8A, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, +0xE0, 0x9E, 0x50, 0x08, 0x90, 0x8A, 0xDA, 0xE0, 0x04, 0xF0, 0x80, 0xAF, 0x90, 0x8A, 0xDA, 0xE0, +0xC3, 0x13, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFF, 0xB4, 0x01, 0x0D, 0x90, 0x8A, 0xDA, 0xE0, 0x70, +0x5D, 0x90, 0x8A, 0xDD, 0x04, 0xF0, 0x80, 0x5B, 0xEF, 0xB4, 0x03, 0x1D, 0x90, 0x8A, 0xDA, 0xE0, +0xFF, 0x70, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x03, 0xF0, 0x80, 0x48, 0xEF, 0xB4, 0x01, 0x08, 0x90, +0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x80, 0x3C, 0x80, 0x35, 0x90, 0x8A, 0xDD, 0xE0, 0x64, 0x05, 0x70, +0x32, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x05, 0xF0, 0x80, 0x0F, +0xEF, 0x90, 0x8A, 0xDD, 0xB4, 0x01, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x03, 0x74, 0x01, 0xF0, 0xD3, +0x90, 0x8A, 0xD7, 0xE0, 0x94, 0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x05, 0xE4, 0x90, +0x8A, 0xDD, 0xF0, 0xD3, 0x90, 0x8A, 0xD7, 0xE0, 0x94, 0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, +0x40, 0x05, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xED, 0xF0, 0x12, 0x69, 0x38, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xD3, 0x94, +0x05, 0x50, 0x0F, 0x74, 0x64, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0x04, 0xF0, +0x80, 0x0F, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0xE4, 0xF5, 0xF0, 0x12, 0x42, 0xFA, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x90, 0x00, 0x02, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x04, 0xE4, +0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x06, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, +0x08, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xC0, +0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, +0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, +0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, +0xF0, 0x02, 0x6B, 0xC2, 0x22, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xC3, +0x94, 0x10, 0x50, 0x14, 0x74, 0xA4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE4, 0xF0, +0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x80, 0xE2, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, +0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, 0x02, 0x81, 0x0E, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x00, +0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x02, 0x12, 0x43, +0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x04, 0x12, 0x43, 0x5F, 0xE4, +0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x06, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, +0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x08, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x74, +0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x74, 0x44, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x43, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x88, +0xF5, 0x83, 0xE4, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0x74, 0x44, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, +0x74, 0x24, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x64, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x41, 0x8C, 0x93, 0xFE, 0x74, 0x01, 0x93, +0xFF, 0x90, 0x41, 0x54, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x3E, 0xC3, 0x13, 0xFE, 0xEF, +0x13, 0xFF, 0x90, 0x8A, 0xCF, 0xE0, 0xFD, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, +0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x29, 0x12, 0x43, +0x5F, 0x74, 0x01, 0xF0, 0x74, 0xC1, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0x74, 0x0C, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, +0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x23, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, +0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0x74, 0x13, 0xF0, 0x75, 0xF0, 0x09, +0xED, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, 0x34, +0x04, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x41, 0x7D, 0x22, 0x12, +0x29, 0xD9, 0xFF, 0xC3, 0x94, 0x20, 0x50, 0x14, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFE, 0x74, +0x23, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xEF, 0xB4, 0x20, 0x0A, +0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0x90, 0x87, 0x21, 0xF0, 0x22, 0x90, 0x8B, 0x4B, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x8B, 0x4B, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, +0x82, 0x8E, 0x83, 0xE0, 0x60, 0x2C, 0xC3, 0x90, 0x8B, 0x4E, 0xE0, 0x94, 0xE8, 0x90, 0x8B, 0x4D, +0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x7F, 0x00, 0x22, 0x90, +0x8B, 0x4D, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x37, 0x54, +0x80, 0xC6, 0x7F, 0x01, 0x22, 0x12, 0x29, 0xD9, 0xF5, 0x21, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x2A, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x01, 0x12, +0x42, 0x20, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x0A, 0xF0, +0x12, 0x47, 0xFA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x30, +0xE0, 0x25, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x10, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, +0x8B, 0x11, 0xF0, 0xEF, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x8B, 0x0F, 0xF0, 0x90, 0x00, 0x03, 0x12, +0x42, 0x20, 0x90, 0x8B, 0x16, 0xF0, 0x22, 0x90, 0x8B, 0x10, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x11, +0x74, 0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, 0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0x22, +0x12, 0x29, 0xD9, 0x30, 0xE0, 0x19, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x8B, 0x15, 0xF0, 0x90, 0x00, +0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8B, 0x13, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x0F, 0x90, +0x8B, 0x15, 0x74, 0x05, 0xF0, 0x90, 0x8B, 0x13, 0xE4, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, +0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x12, 0xF0, +0x60, 0x07, 0xE4, 0xFD, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x90, 0x8B, 0x12, 0xE0, 0x90, 0x01, 0xE7, +0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x29, 0xD9, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x90, +0x8A, 0xF7, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xF8, 0xF0, +0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xF9, 0xF0, 0x90, 0x00, 0x03, +0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xFA, 0xF0, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, +0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x8A, 0xFB, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x12, 0x29, 0xD9, 0xC3, +0x13, 0x20, 0xE0, 0x02, 0xC1, 0xED, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, +0x54, 0x02, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0x54, 0xFD, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, +0xEE, 0x54, 0xFE, 0x4F, 0xFF, 0xF0, 0x12, 0x29, 0xD9, 0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, +0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, +0x12, 0x29, 0xD9, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF, 0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, +0xEE, 0x54, 0x40, 0xFE, 0xEF, 0x54, 0xBF, 0x4E, 0xF0, 0x20, 0xE0, 0x02, 0xC1, 0xD9, 0x90, 0x8A, +0xDD, 0x74, 0x21, 0xF0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, 0x13, 0x13, +0x54, 0x01, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, 0x13, 0x54, 0x01, 0x6E, 0x60, 0x2A, 0xEF, +0x54, 0x04, 0xFF, 0xED, 0x54, 0xFB, 0x4F, 0xF0, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0E, +0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x12, 0x36, 0xE6, 0x80, 0x0B, 0xE4, 0x90, +0x8B, 0x34, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x36, 0x75, 0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, 0x13, +0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x12, 0xF0, 0xED, 0xC4, 0x54, +0x0F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x14, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x8B, 0x32, +0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x40, 0xF0, +0x90, 0x8A, 0xDD, 0xE0, 0x90, 0x05, 0x27, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x70, 0x05, 0x7F, 0x01, +0x12, 0x4E, 0x89, 0x90, 0x8B, 0x32, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x04, 0x7F, +0x03, 0x80, 0x0E, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, +0x02, 0x12, 0x4E, 0x89, 0x7F, 0x02, 0x02, 0x78, 0x2E, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, +0x05, 0x27, 0xF0, 0xE4, 0xFF, 0x12, 0x4E, 0x89, 0x7F, 0x03, 0x02, 0x78, 0x2E, 0x90, 0x8A, 0xDA, +0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, 0x54, 0x02, 0xFE, 0x90, 0x8B, 0x2C, 0xE0, 0x54, 0xFD, +0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, 0xEE, 0x54, 0xFE, 0x4F, 0xFF, 0xF0, 0x12, 0x29, 0xD9, +0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, 0x90, 0x8B, 0x2C, 0xF0, 0xEE, 0x54, 0x10, +0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x29, 0xD9, 0xFE, 0x54, 0x40, 0xFD, 0xEF, 0x54, +0xBF, 0x4D, 0xFF, 0x90, 0x8B, 0x2C, 0xF0, 0xEE, 0x54, 0x04, 0xFE, 0xEF, 0x54, 0xFB, 0x4E, 0xF0, +0x20, 0xE0, 0x02, 0xE1, 0xE2, 0x90, 0x8A, 0xDD, 0x74, 0x31, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x20, 0xE0, 0x0B, 0xE4, 0x90, 0x8B, 0x2E, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x36, +0x75, 0x90, 0x8B, 0x2C, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x8A, +0xDD, 0xE0, 0x44, 0x02, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, +0x44, 0x04, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0x54, 0x06, 0x60, 0x0C, 0x90, 0x01, 0x3E, 0x74, 0x03, +0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x37, 0x00, 0x90, 0x8A, 0xDD, 0xE0, 0x90, 0x05, 0x27, 0xF0, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x0D, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x2C, 0x7F, 0x06, 0x12, 0x65, 0x82, 0x80, 0x25, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x06, 0x1B, +0x7F, 0x01, 0x12, 0x65, 0x82, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x09, 0x7D, 0x01, 0xAF, +0x23, 0x12, 0x45, 0xA2, 0x80, 0x05, 0x12, 0x4E, 0x56, 0x80, 0x03, 0x12, 0x7D, 0xC1, 0x7F, 0x01, +0x80, 0x4C, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27, 0xF0, 0x7D, 0x03, 0x7F, 0x02, +0x12, 0x36, 0x92, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x06, 0x02, 0x80, 0x1B, 0x90, 0x8B, 0x2D, 0xE0, +0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, 0x80, 0x14, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, +0x02, 0x05, 0x7F, 0x01, 0x12, 0x65, 0x82, 0x11, 0x35, 0x12, 0x4A, 0xFC, 0x7F, 0x03, 0x11, 0x42, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8B, 0x31, 0xE0, 0xB4, 0x01, 0x05, 0xE4, 0xF0, 0x12, 0x48, +0xFE, 0x22, 0xAD, 0x07, 0xEF, 0x64, 0x01, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x32, +0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xED, 0x64, 0x02, 0x60, 0x04, 0xED, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x2C, 0xE0, 0x54, +0xFE, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0x22, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x38, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8A, 0xFD, 0xE0, 0x90, 0x8A, 0xE8, 0xF0, 0x90, 0x8A, 0xFE, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, +0x8A, 0xE9, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, +0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x8B, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xEB, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, +0x04, 0xDA, 0x90, 0x8A, 0xE8, 0xE0, 0x12, 0x43, 0x94, 0x78, 0xF8, 0x00, 0x7A, 0x6B, 0x01, 0x79, +0x01, 0x02, 0x79, 0x01, 0x03, 0x79, 0x01, 0x04, 0x7A, 0x6B, 0x05, 0x7A, 0x35, 0x80, 0x7A, 0x4E, +0x81, 0x7A, 0x6B, 0x82, 0x00, 0x00, 0x7A, 0x67, 0x90, 0x8A, 0xEE, 0xE0, 0xFF, 0x51, 0x72, 0x41, +0x6B, 0x90, 0x8A, 0xE8, 0xE0, 0xFF, 0xB4, 0x02, 0x08, 0x90, 0x8A, 0xE5, 0x74, 0x01, 0xF0, 0x80, +0x0F, 0xEF, 0x90, 0x8A, 0xE5, 0xB4, 0x03, 0x05, 0x74, 0x02, 0xF0, 0x80, 0x03, 0x74, 0x04, 0xF0, +0xC3, 0x90, 0x8A, 0xE9, 0xE0, 0x94, 0x08, 0x50, 0x78, 0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, +0xE5, 0xE0, 0xFF, 0x90, 0x8A, 0xE4, 0xE0, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xE9, +0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0xEE, 0x94, 0x01, 0x90, 0x8A, 0xE4, 0xE0, 0x50, 0x1F, 0xFE, +0x2F, 0xFF, 0xEE, 0xFD, 0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, +0xF5, 0x82, 0x74, 0x8A, 0x3C, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x51, 0x88, 0x80, 0x2B, 0xFF, 0xFD, +0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, 0xF5, 0x82, 0x74, 0x8A, +0x3C, 0xF5, 0x83, 0xE0, 0xFE, 0xEF, 0xFD, 0x90, 0x8A, 0xEA, 0xE0, 0x2D, 0xFD, 0x90, 0x8A, 0xE9, +0xE0, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0x80, +0x8D, 0xC3, 0x90, 0x8A, 0xE9, 0xE0, 0x94, 0x10, 0x40, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xE8, 0xE0, +0x64, 0x04, 0x60, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xEC, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, +0x10, 0x12, 0x2A, 0x6C, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xEB, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x18, 0x12, 0x2A, 0x6C, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, +0xD0, 0x00, 0x12, 0x43, 0x46, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xED, +0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12, 0x2A, 0x6C, 0xD0, 0x03, 0xD0, 0x02, 0xD0, +0x01, 0xD0, 0x00, 0x12, 0x43, 0x46, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0xA3, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x12, 0x43, 0x46, 0xA3, 0x12, 0x2A, 0x7F, 0x90, 0x8A, 0xEF, 0x12, +0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x90, 0x8A, 0xE9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x12, 0x2F, 0xD9, 0x80, 0x36, 0x90, 0x8A, 0xED, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xE4, +0x3E, 0xFE, 0x90, 0x8A, 0xE6, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x37, 0x54, 0x80, 0x1D, 0x90, 0x8A, +0xED, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x8A, 0xE6, 0xF0, 0xA3, +0xEF, 0xF0, 0x12, 0x36, 0xCB, 0x80, 0x04, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0x8F, 0x0F, 0xE4, 0x90, 0x8A, 0xF3, 0xF0, 0xE5, 0x0F, 0x14, 0xFE, 0x90, 0x8A, 0xF3, +0xE0, 0xFF, 0xC3, 0x9E, 0x50, 0x0E, 0xEF, 0x04, 0xFD, 0x12, 0x34, 0xB7, 0x90, 0x8A, 0xF3, 0xE0, +0x04, 0xF0, 0x80, 0xE5, 0xE5, 0x0F, 0x14, 0xFF, 0x7D, 0xFF, 0x12, 0x34, 0xB7, 0x90, 0x8A, 0xF3, +0xE5, 0x0F, 0xF0, 0x90, 0x8A, 0xF3, 0xE0, 0xC3, 0x94, 0xFF, 0x50, 0x0F, 0xE0, 0xFF, 0x04, 0xFD, +0x12, 0x34, 0xB7, 0x90, 0x8A, 0xF3, 0xE0, 0x04, 0xF0, 0x80, 0xE8, 0xAD, 0x0F, 0x7F, 0xFF, 0x02, +0x34, 0xB7, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0xA3, 0x74, +0x04, 0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0x8A, 0xE2, 0xF0, 0xA3, 0xF0, 0x90, 0x02, 0x09, 0xE0, 0x90, +0x8A, 0xE1, 0xF0, 0x12, 0x29, 0xD9, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, 0x2F, 0x90, 0x8A, 0xE0, 0xF0, +0x30, 0xE0, 0x0B, 0x90, 0x8A, 0xDB, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x80, 0x07, 0xE4, 0x90, +0x8A, 0xDB, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x90, +0x8A, 0xDD, 0xE0, 0x24, 0x20, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFC, 0x2D, +0xFF, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xFD, 0xF0, 0x74, +0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0xEC, 0x2D, 0x24, 0x03, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0x90, 0x8A, 0xFE, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xDA, 0x74, 0x04, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFF, 0xA3, +0xE0, 0x2F, 0xFF, 0x90, 0x8A, 0xDA, 0xE0, 0xFE, 0x2F, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0xFF, 0x74, 0xFC, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x8A, 0xDA, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x08, 0xCF, 0x11, 0x89, 0xEF, 0x70, 0x45, 0x90, +0x01, 0xC3, 0xE0, 0x60, 0x2B, 0xC3, 0x90, 0x8A, 0xE3, 0xE0, 0x94, 0xE8, 0x90, 0x8A, 0xE2, 0xE0, +0x94, 0x03, 0x40, 0x09, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x80, 0x79, 0x90, 0x8A, 0xE2, +0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x37, 0x54, 0x80, 0xCF, +0x90, 0x01, 0xC6, 0xE0, 0x90, 0x01, 0xC3, 0x30, 0xE2, 0x05, 0x74, 0xFE, 0xF0, 0x80, 0x57, 0x74, +0xFF, 0xF0, 0x80, 0x52, 0x90, 0x8A, 0xDD, 0xE0, 0xB4, 0x78, 0x2E, 0xE4, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0x04, 0xF0, 0x90, 0x8A, 0xDB, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x80, 0x90, 0x8A, 0xDB, +0x70, 0x05, 0xF0, 0xA3, 0xF0, 0x80, 0x06, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x80, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x24, 0x08, 0xF0, +0x90, 0x8A, 0xDE, 0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x42, 0x81, 0x90, 0x8A, 0xDE, 0xE0, 0x70, 0x02, +0xA3, 0xE0, 0x60, 0x02, 0x61, 0x16, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x29, 0xD9, 0x90, 0x8B, +0x05, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x06, 0xF0, 0x22, 0xE4, 0xF5, 0x61, +0x22, 0x91, 0x4A, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, +0x7F, 0x78, 0x7E, 0x08, 0x12, 0x27, 0xDE, 0x90, 0x8B, 0x1C, 0x12, 0x2A, 0x7F, 0x7F, 0x04, 0x7E, +0x0C, 0x12, 0x27, 0xDE, 0x90, 0x8B, 0x20, 0x12, 0x2A, 0x7F, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x27, +0xDE, 0x90, 0x8B, 0x24, 0x12, 0x2A, 0x7F, 0x90, 0x8B, 0x09, 0xE0, 0x90, 0x8B, 0x1C, 0xB4, 0x01, +0x0D, 0x12, 0x43, 0x53, 0xEF, 0x54, 0xC7, 0xFF, 0xED, 0x54, 0xC7, 0xFD, 0x80, 0x07, 0x12, 0x43, +0x53, 0xEF, 0x54, 0xC7, 0xFF, 0xEC, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x78, 0x7E, 0x08, +0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x20, 0x12, 0x43, 0x53, 0xEF, 0x54, 0x0F, 0xFF, 0xEC, 0x90, 0x80, +0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x04, 0x7E, 0x0C, 0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x24, 0x12, 0x43, +0x53, 0xEF, 0x44, 0x02, 0xFF, 0xEC, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x00, 0x7E, 0x08, +0x12, 0x2F, 0xD9, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x27, 0xDE, 0x90, 0x8B, 0x28, 0x12, 0x2A, 0x7F, +0x90, 0x80, 0x85, 0x12, 0x2A, 0x8B, 0x00, 0x1B, 0x25, 0xA0, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2F, +0xD9, 0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x34, +0x81, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x11, 0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x00, +0x00, 0x00, 0xE4, 0xFD, 0x7F, 0x01, 0x12, 0x34, 0x81, 0x90, 0x00, 0x11, 0xE0, 0x54, 0xF6, 0xF0, +0x02, 0x52, 0x0E, 0x91, 0x50, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, +0xFF, 0xF0, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0xB1, 0x42, 0x90, 0x8B, 0x33, 0x74, 0x04, +0xF0, 0x22, 0x90, 0x00, 0x11, 0xE0, 0x44, 0x09, 0xF0, 0x12, 0x52, 0x0E, 0x90, 0x8B, 0x1C, 0x12, +0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x78, 0x7E, 0x08, 0x12, 0x2F, 0xD9, 0x90, +0x8B, 0x20, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x04, 0x7E, 0x0C, 0x12, +0x2F, 0xD9, 0x90, 0x8B, 0x24, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x00, +0x7E, 0x08, 0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x28, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, +0x7F, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2F, 0xD9, 0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x03, +0x2D, 0x95, 0xE4, 0xFD, 0xFF, 0x12, 0x34, 0x81, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x11, 0x90, +0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x03, 0x2D, 0x95, 0xE4, 0xFD, 0x7F, 0x01, 0x12, 0x34, 0x81, +0x22, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x3C, 0xE5, 0x22, 0x54, 0x0F, 0x14, 0x60, 0x2E, +0x14, 0x60, 0x1E, 0x24, 0xFE, 0x60, 0x0E, 0x24, 0xF8, 0x70, 0x2A, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, +0x90, 0x05, 0x22, 0xF0, 0x22, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x22, 0xE4, 0xF0, +0x22, 0x90, 0x8B, 0x2D, 0x74, 0x03, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0x90, 0x01, +0xC6, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0xAE, 0x07, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x18, +0x90, 0x8B, 0x2C, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x0C, 0xAF, 0x06, 0x7D, 0x01, +0x12, 0x45, 0xA2, 0xB1, 0xC1, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x01, 0x57, 0xE0, 0x60, +0x3C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x1B, 0xE0, +0x60, 0x07, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0x80, 0x24, 0x90, 0x8B, 0x0C, 0xE0, 0x04, 0xF0, 0x53, +0x25, 0xEF, 0x90, 0x8B, 0x10, 0xE0, 0xFF, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, 0x40, 0x0E, 0xE5, +0x21, 0xB4, 0x01, 0x09, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0x01, 0x5B, +0xE0, 0x60, 0x10, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0x90, +0x8B, 0x18, 0xF0, 0x90, 0x01, 0x5F, 0xE0, 0x60, 0x10, 0x90, 0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, +0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x17, 0xF0, 0x22, 0xE4, 0x90, 0x8B, 0x4F, 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, 0x8B, 0x50, 0xE0, 0x94, 0xE8, 0x90, 0x8B, 0x4F, +0xE0, 0x94, 0x03, 0x40, 0x03, 0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x37, 0x54, 0x90, +0x8B, 0x4F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x80, 0xC6, 0x00, 0x92, 0x00}; + +// =================== v88 UMC A Cut P2PPS with CCX report C2H 2012-12-05 ===================== +u8 Rtl8192CUFwUMCACutImgArray[UMCACutImgArrayLength] = { +0xC1, 0x88, 0x02, 0x05, 0x58, 0x00, 0x02, 0x00, 0x12, 0x05, 0x17, 0x11, 0xDE, 0x3E, 0x01, 0x00, +0x94, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x46, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x60, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x68, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4B, 0x87, 0x00, 0x00, +0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x06, 0x05, 0x04, 0x03, 0x00, 0x04, 0x06, 0x05, 0x04, 0x02, +0x00, 0x04, 0x08, 0x07, 0x06, 0x04, 0x00, 0x06, 0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x0A, 0x09, +0x08, 0x04, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x08, +0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x18, 0x22, 0x21, 0x20, 0x18, +0x00, 0x20, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20, 0x22, 0x21, 0x20, 0x08, 0x00, 0x20, 0x22, 0x21, +0x1C, 0x08, 0x00, 0x20, 0x22, 0x21, 0x14, 0x08, 0x00, 0x20, 0x22, 0x20, 0x18, 0x08, 0x00, 0x20, +0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x31, 0x30, 0x18, 0x00, 0x00, 0x30, 0x31, 0x2F, 0x10, 0x10, +0x00, 0x30, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x30, 0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x31, 0x20, +0x10, 0x00, 0x00, 0x30, 0x31, 0x10, 0x10, 0x00, 0x00, 0x30, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, +0x05, 0x07, 0x07, 0x07, 0x08, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x06, 0x0A, 0x0B, 0x0D, 0x05, 0x05, +0x07, 0x07, 0x08, 0x0B, 0x0D, 0x0F, 0x04, 0x04, 0x04, 0x05, 0x07, 0x07, 0x09, 0x09, 0x0C, 0x0E, +0x10, 0x12, 0x06, 0x07, 0x09, 0x0A, 0x0C, 0x0E, 0x11, 0x13, 0x09, 0x09, 0x09, 0x09, 0x0C, 0x0E, +0x11, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x26, 0x2A, 0x18, 0x1A, +0x1D, 0x1F, 0x21, 0x27, 0x29, 0x2A, 0x00, 0x00, 0x00, 0x1F, 0x23, 0x28, 0x2A, 0x2C, 0x00, 0x04, +0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, +0x00, 0x90, 0x00, 0xC0, 0x00, 0xD8, 0x00, 0x50, 0x00, 0x78, 0x00, 0xA0, 0x00, 0xC8, 0x01, 0x40, +0x01, 0x90, 0x01, 0xE0, 0x02, 0x30, 0x01, 0x2C, 0x01, 0x40, 0x01, 0xE0, 0x02, 0xD0, 0x03, 0xE8, +0x04, 0xB0, 0x06, 0x40, 0x07, 0xD0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, +0x00, 0x12, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x28, +0x00, 0x3C, 0x00, 0x50, 0x00, 0x64, 0x00, 0xA0, 0x00, 0xC8, 0x00, 0xF0, 0x01, 0x18, 0x00, 0x64, +0x00, 0xA0, 0x00, 0xF0, 0x01, 0x68, 0x01, 0xF4, 0x02, 0x58, 0x03, 0x20, 0x03, 0xE8, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x07, 0x02, 0x03, 0x04, 0x0A, 0x0C, 0x0E, +0x10, 0x12, 0x05, 0x07, 0x07, 0x08, 0x0B, 0x12, 0x24, 0x3C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, +0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x20, 0x1E, 0x1C, 0x18, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBB, 0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, +0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, +0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, +0x89, 0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, +0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, +0x50, 0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, +0x22, 0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, +0x02, 0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xF5, +0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x06, 0x87, 0xF0, 0x09, 0xE7, 0x19, 0x22, 0xBB, 0xFE, 0x07, 0xE3, +0xF5, 0xF0, 0x09, 0xE3, 0x19, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xF5, 0xF0, 0x74, 0x01, +0x93, 0x22, 0xBB, 0x01, 0x10, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, +0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, +0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, +0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0, 0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, +0x83, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x06, 0xF7, 0x09, 0xA7, 0xF0, 0x19, 0x22, 0xBB, +0xFE, 0x06, 0xF3, 0xE5, 0xF0, 0x09, 0xF3, 0x19, 0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, +0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, +0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0, 0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, +0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, +0x48, 0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xA4, +0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, +0xA3, 0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, +0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, +0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, +0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, +0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, +0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, +0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0xB5, 0xF0, 0x06, 0x74, 0x03, 0x93, 0x68, 0x60, +0xE9, 0xA3, 0xA3, 0xA3, 0xA3, 0x80, 0xD8, 0xE4, 0x90, 0x8A, 0xC5, 0xF0, 0xE5, 0x24, 0x70, 0x03, +0x02, 0x44, 0x9D, 0xE5, 0x21, 0x64, 0x01, 0x60, 0x03, 0x02, 0x44, 0x9D, 0xE5, 0x24, 0x14, 0x60, +0x29, 0x24, 0xFD, 0x60, 0x25, 0x24, 0x02, 0x24, 0xFB, 0x50, 0x02, 0x80, 0x23, 0x90, 0x8B, 0x0B, +0xE0, 0x14, 0xF0, 0xE0, 0x60, 0x04, 0xA3, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x0A, +0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, 0xF0, 0x80, 0x00, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, +0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x16, 0xA3, 0xE0, 0xB4, 0x06, 0x05, 0xE4, 0x90, 0x8A, 0xC5, +0xF0, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x70, 0x04, 0x90, 0x8A, 0xC5, 0xF0, 0x90, 0x8A, 0xC5, +0xE0, 0x60, 0x4A, 0x43, 0x25, 0x10, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0C, 0xE0, 0x75, +0xF0, 0x03, 0xA4, 0xFF, 0x90, 0x8B, 0x15, 0xE0, 0x2F, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0xE5, 0x22, 0x54, +0x0F, 0xC3, 0x94, 0x04, 0x50, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x90, 0x8B, 0x2C, +0xE0, 0x30, 0xE0, 0x09, 0x12, 0x7D, 0xC1, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0xE4, 0xF5, +0x25, 0xF5, 0x24, 0x75, 0x23, 0x0C, 0x75, 0x22, 0x0C, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x8B, 0x18, +0xF0, 0x90, 0x8B, 0x17, 0xF0, 0x90, 0x8B, 0x19, 0x04, 0xF0, 0x90, 0x8B, 0x0B, 0xF0, 0xE4, 0x90, +0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0D, 0xF0, 0x90, 0x8B, 0x15, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x8B, +0x0C, 0xF0, 0x90, 0x8B, 0x13, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x10, 0xF0, 0xA3, 0x74, +0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, 0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0xE4, 0x90, +0x8B, 0x0E, 0xF0, 0x90, 0x8B, 0x0A, 0xF0, 0x90, 0x8B, 0x08, 0xF0, 0x90, 0x8B, 0x12, 0xF0, 0x22, +0x7F, 0x00, 0x22, 0x02, 0x45, 0x03, 0x02, 0x45, 0x06, 0x8E, 0x64, 0x8F, 0x65, 0xAD, 0x65, 0xAC, +0x64, 0xAF, 0x63, 0x12, 0x4A, 0x5B, 0xAF, 0x65, 0xAE, 0x64, 0x90, 0x04, 0x80, 0xE0, 0x54, 0x0F, +0xFD, 0xAC, 0x07, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x01, +0xF0, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xFB, 0xF0, 0xAC, +0x07, 0x74, 0x16, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0xFA, 0xF0, 0x74, +0x15, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, +0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53, +0xE4, 0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74, +0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0x4D, +0xFD, 0x74, 0x14, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xED, 0xF0, 0x22, 0x7D, 0x01, +0x7F, 0x0C, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x67, 0x8D, 0x68, 0xE5, 0x67, 0x54, +0x0F, 0xFF, 0xE5, 0x22, 0x54, 0x0F, 0x6F, 0x60, 0x72, 0xE5, 0x67, 0x30, 0xE2, 0x30, 0xE5, 0x22, +0x20, 0xE2, 0x05, 0x7F, 0x01, 0x12, 0x4A, 0xB2, 0xE5, 0x22, 0x30, 0xE3, 0x10, 0xE5, 0x67, 0x20, +0xE3, 0x0B, 0x12, 0x49, 0xD5, 0xEF, 0x60, 0x53, 0x12, 0x4A, 0xCC, 0x80, 0x4E, 0xE5, 0x22, 0x20, +0xE3, 0x49, 0xE5, 0x67, 0x30, 0xE3, 0x44, 0xAF, 0x68, 0x12, 0x4A, 0x7C, 0x80, 0x3D, 0xE5, 0x22, +0x54, 0x0F, 0xFF, 0xBF, 0x0C, 0x0E, 0xE5, 0x67, 0x20, 0xE3, 0x09, 0x12, 0x49, 0xD5, 0xEF, 0x60, +0x2A, 0x12, 0x4A, 0xCC, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, 0x04, 0x0E, 0xE5, 0x67, 0x20, 0xE2, +0x09, 0x12, 0x49, 0x93, 0xEF, 0x60, 0x14, 0x12, 0x4A, 0x32, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, +0x02, 0x09, 0x12, 0x45, 0x00, 0xEF, 0x60, 0x03, 0x12, 0x4B, 0x10, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x02, 0x46, 0x6E, 0x02, 0x50, 0xC6, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, +0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, +0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, +0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x4B, +0x23, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, 0xE5, 0x21, 0x64, 0x01, 0x70, 0x67, 0xE5, 0x24, 0x60, 0x63, 0xE5, 0x24, 0x64, +0x02, 0x60, 0x06, 0xE5, 0x24, 0x64, 0x05, 0x70, 0x27, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x8B, 0x19, 0xF0, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x07, 0x90, +0x8B, 0x19, 0xE0, 0xFF, 0x80, 0x05, 0x90, 0x8B, 0x0B, 0xE0, 0xFF, 0x90, 0x8B, 0x0B, 0xEF, 0xF0, +0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x02, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x0C, 0xF0, 0x90, 0x05, 0x58, +0x74, 0x03, 0xF0, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x53, 0x25, +0xFD, 0x53, 0x25, 0xEF, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x03, 0x12, 0x47, 0x8E, +0x22, 0xEF, 0x64, 0x01, 0x70, 0x35, 0x7D, 0x78, 0x7F, 0x02, 0x12, 0x31, 0x2C, 0x7D, 0x02, 0x7F, +0x03, 0x12, 0x31, 0x2C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x12, +0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x7D, 0xC1, 0x90, 0x06, 0x04, 0xE0, +0x54, 0x7F, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x7B, +0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x7B, 0xFF, 0x12, 0x31, 0x9D, 0x7D, 0x02, 0x7F, 0x03, 0x12, +0x31, 0x9D, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0xF0, +0x12, 0x4B, 0x4F, 0xE5, 0x21, 0x20, 0xE0, 0x05, 0xE4, 0x90, 0x8B, 0x0D, 0xF0, 0x22, 0xE4, 0x90, +0x8A, 0xC5, 0xF0, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x8A, 0xC5, 0xF0, 0xE0, 0x54, 0xC0, 0x70, 0x09, +0x53, 0x25, 0xFE, 0x53, 0x25, 0xFD, 0x12, 0x4A, 0xFC, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE6, 0x15, +0x43, 0x25, 0x01, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, 0x4A, 0x97, 0x80, 0x08, +0x12, 0x49, 0x49, 0x80, 0x03, 0x53, 0x25, 0xFE, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE7, 0x27, 0x43, +0x25, 0x02, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, +0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0x90, +0x8B, 0x1B, 0x74, 0x01, 0xF0, 0x22, 0x53, 0x25, 0xFD, 0x22, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x8B, +0x12, 0x4B, 0x43, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x12, 0x24, 0x62, 0xF5, 0x24, 0x14, 0x60, +0x0E, 0x14, 0x60, 0x1F, 0x14, 0x60, 0x31, 0x24, 0x03, 0x70, 0x44, 0x7F, 0x01, 0x80, 0x3D, 0x90, +0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, 0xE4, 0xFF, 0x12, 0x4A, +0x07, 0x80, 0x29, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, +0x7F, 0x01, 0x12, 0x4A, 0x07, 0x1F, 0x80, 0x14, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, +0x02, 0x12, 0x42, 0x20, 0xFD, 0x7F, 0x02, 0x12, 0x4A, 0x07, 0xE4, 0xFF, 0x12, 0x47, 0x21, 0x22, +0xE4, 0x90, 0x8A, 0xCB, 0xF0, 0xE5, 0x24, 0x60, 0x49, 0x90, 0x8B, 0x1B, 0xE0, 0x60, 0x0D, 0xE4, +0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x38, 0x80, 0x33, 0x90, 0x8B, 0x0C, 0xE0, +0x04, 0xF0, 0x53, 0x25, 0xEF, 0x90, 0x8A, 0xCB, 0xE0, 0xFF, 0x90, 0x8B, 0x10, 0xE0, 0x2F, 0xFF, +0xE4, 0x33, 0xFE, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, +0x40, 0x0D, 0xE5, 0x21, 0xB4, 0x01, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xE0, 0x04, 0xF0, 0x22, 0x12, +0x4A, 0xFC, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x63, 0x90, 0x04, 0x1D, 0xE0, +0x60, 0x24, 0x90, 0x05, 0x22, 0xE0, 0xF5, 0x66, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x9A, 0xBF, 0x01, +0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, 0x12, 0x45, 0x09, 0x90, 0x05, +0x22, 0xE5, 0x66, 0xF0, 0x80, 0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, +0x12, 0x45, 0x09, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE5, 0x24, +0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x41, 0x90, 0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x12, 0x45, 0x9E, +0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x58, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, +0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x22, 0xE5, 0x22, 0x54, 0x0F, 0xC3, 0x94, 0x04, 0x50, +0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x22, 0x90, 0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, +0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, +0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, +0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x17, 0x14, 0xF0, 0xE5, 0x22, 0x54, 0x0F, +0xC3, 0x94, 0x0C, 0x50, 0x0D, 0x12, 0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, +0x7D, 0xC1, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x37, 0xE5, 0x25, 0x54, 0x03, 0x70, +0x31, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x02, 0x50, 0x28, 0xE5, 0x25, 0x20, 0xE2, 0x23, 0xE5, +0x25, 0x20, 0xE4, 0x1E, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x18, 0x90, 0x8B, 0x12, 0xE0, 0x70, 0x12, +0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x7F, +0x01, 0x22, 0x7F, 0x00, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x27, 0x90, 0x8B, 0x18, +0xE0, 0x70, 0x21, 0x90, 0x8B, 0x17, 0xE0, 0x70, 0x1B, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x04, +0x50, 0x12, 0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x08, +0xF0, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x22, 0x90, +0x8B, 0x19, 0x74, 0x01, 0xF0, 0x80, 0x16, 0xED, 0x70, 0x0A, 0x90, 0x8B, 0x16, 0xE0, 0x90, 0x8B, +0x19, 0xF0, 0x80, 0x05, 0x90, 0x8B, 0x19, 0xED, 0xF0, 0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x22, 0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, +0x9A, 0xEF, 0x70, 0x06, 0x90, 0x01, 0xC8, 0x74, 0xFD, 0xF0, 0x7D, 0x02, 0x7F, 0x03, 0x12, 0x31, +0x9D, 0x12, 0x7C, 0x50, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x02, 0x22, 0xEF, 0x60, 0x0F, 0x74, 0x21, +0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, 0x21, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x54, 0xBF, 0xF0, 0xEF, 0x60, 0x0A, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0xE4, 0xFF, 0x12, 0x48, 0xB3, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x0C, 0x22, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x14, 0x90, 0x8A, 0xF8, +0xE0, 0xFF, 0xE4, 0xFD, 0x12, 0x5F, 0xFD, 0x8E, 0x69, 0x8F, 0x6A, 0x90, 0x04, 0x1F, 0x74, 0x20, +0xF0, 0x22, 0x90, 0x8B, 0x52, 0xEF, 0xF0, 0x12, 0x7D, 0x42, 0x90, 0x8B, 0x52, 0xE0, 0x60, 0x05, +0x90, 0x05, 0x22, 0xE4, 0xF0, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x04, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x44, 0x40, 0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0x7F, 0x01, 0x12, 0x48, 0xB3, 0x53, 0x22, 0xF0, +0x43, 0x22, 0x04, 0x22, 0xE5, 0x23, 0x30, 0xE6, 0x12, 0xE5, 0x23, 0x54, 0x0F, 0xFF, 0x90, 0x01, +0x2F, 0xE0, 0x54, 0x80, 0x4F, 0x64, 0x80, 0xF0, 0x53, 0x23, 0xBF, 0x22, 0x90, 0x8B, 0x2C, 0xE0, +0x30, 0xE0, 0x05, 0xAF, 0x23, 0x02, 0x7E, 0x06, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x22, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x01, 0x12, 0x4B, 0x5A, 0x12, 0x4B, 0x5B, 0x53, 0x22, 0xF0, 0x43, +0x22, 0x02, 0x22, 0x41, 0x8A, 0xF6, 0x00, 0x41, 0x8B, 0x05, 0x00, 0x41, 0x8B, 0x51, 0x00, 0x41, +0x8B, 0x53, 0x00, 0x00, 0x90, 0x04, 0x1B, 0xE0, 0x54, 0x7F, 0x64, 0x7F, 0x7F, 0x01, 0x60, 0x02, +0x7F, 0x00, 0x22, 0xE4, 0x90, 0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0C, 0xF0, 0xF5, 0x25, 0x22, 0x90, +0x8B, 0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x22, 0x22, 0xF0, 0x90, 0x8B, 0x0F, +0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x3D, 0xE0, 0xFB, 0xA3, 0xE0, 0xF5, 0x44, 0xE4, 0xF5, 0x45, 0x12, +0x30, 0x62, 0xD0, 0xD0, 0x92, 0xAF, 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, 0x75, 0x0E, 0x00, 0x90, 0x01, 0xC4, 0x74, 0x87, 0xF0, 0x74, 0x4B, 0xA3, +0xF0, 0x53, 0x91, 0xDF, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x30, 0xF5, 0x34, 0xA3, 0xE0, 0x55, 0x31, +0xF5, 0x35, 0xA3, 0xE0, 0x55, 0x32, 0xF5, 0x36, 0xA3, 0xE0, 0x55, 0x33, 0xF5, 0x37, 0xE5, 0x34, +0x30, 0xE0, 0x51, 0x90, 0x01, 0x3C, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x1F, +0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x34, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x1D, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x16, 0x90, 0x8B, +0x2E, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, +0x70, 0x02, 0xD1, 0x56, 0xE5, 0x34, 0x30, 0xE1, 0x08, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x11, +0x60, 0xE5, 0x34, 0x30, 0xE2, 0x28, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x92, 0xE0, +0x30, 0xE0, 0x14, 0x90, 0x8B, 0x3D, 0xE4, 0x71, 0x5C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, +0x06, 0x92, 0x74, 0x01, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x18, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, +0x30, 0xE3, 0x38, 0x90, 0x01, 0x3C, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x24, +0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x5C, 0x7E, 0x01, 0x71, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, +0x02, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x17, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, 0x30, 0xE4, 0x09, +0x90, 0x01, 0x3C, 0x74, 0x10, 0xF0, 0x12, 0x51, 0xC9, 0xE5, 0x34, 0x30, 0xE5, 0x06, 0x90, 0x01, +0x3C, 0x74, 0x20, 0xF0, 0xE5, 0x35, 0x30, 0xE0, 0x10, 0x90, 0x01, 0x3D, 0x74, 0x01, 0xF0, 0x90, +0x00, 0x83, 0xE0, 0xF5, 0x23, 0x51, 0xE4, 0x51, 0xFC, 0xE5, 0x35, 0x30, 0xE2, 0x06, 0x90, 0x01, +0x3D, 0x74, 0x04, 0xF0, 0xE5, 0x35, 0x30, 0xE4, 0x1B, 0x90, 0x01, 0x3D, 0x74, 0x10, 0xF0, 0x90, +0x8B, 0x05, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x05, +0xFD, 0xE0, 0x04, 0xF0, 0xE5, 0x36, 0x30, 0xE0, 0x75, 0x90, 0x01, 0x3E, 0x74, 0x01, 0xF0, 0x90, +0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x36, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, +0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0xD1, 0x89, 0x90, 0x8B, +0x2C, 0xE0, 0x30, 0xE0, 0x49, 0x90, 0x8B, 0x30, 0xE4, 0xF0, 0xFF, 0xB1, 0xE0, 0xEF, 0x60, 0x3E, +0x12, 0x65, 0x5F, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, 0x32, 0xEF, 0xB4, 0x04, 0x02, +0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, 0x80, 0x14, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x05, 0x7F, +0x01, 0x12, 0x65, 0x82, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x12, 0x7D, 0xC1, 0xE5, 0x36, +0x30, 0xE1, 0x47, 0x90, 0x01, 0x3E, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x19, +0x90, 0x8B, 0x36, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, +0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x1A, +0x90, 0x8B, 0x30, 0x74, 0x01, 0xF0, 0x12, 0x7E, 0x2B, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, +0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, 0x70, 0x02, 0xD1, 0x56, 0x74, 0x87, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0x74, 0x4B, 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, +0xEF, 0x64, 0x01, 0x70, 0x3D, 0x90, 0x8B, 0x35, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, +0x08, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x34, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, +0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x54, +0x07, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x36, 0xE0, 0x7F, 0x01, 0x60, 0x36, 0x7F, +0x00, 0x22, 0x90, 0x8B, 0x2F, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x08, 0xE0, 0x60, +0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2E, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2C, +0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x30, 0xE0, 0x7F, +0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x2D, 0xE0, +0x70, 0x04, 0x7F, 0x05, 0x80, 0x1F, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x01, 0x70, 0x1A, 0x7F, 0x02, +0x80, 0x13, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x03, 0x80, 0x08, 0x90, 0x8B, 0x2D, +0xE0, 0x70, 0x05, 0x7F, 0x04, 0x12, 0x65, 0x82, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8B, 0x33, 0xE0, 0x90, 0x8B, 0x55, 0xF0, 0x6F, 0x70, 0x02, 0xE1, 0x55, 0xEF, 0x14, 0x60, +0x3B, 0x14, 0x60, 0x5F, 0x14, 0x70, 0x02, 0xE1, 0x30, 0x24, 0x03, 0x60, 0x02, 0xE1, 0x55, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x04, 0xF1, 0xC2, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x02, +0x04, 0xF1, 0xAF, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, 0x04, 0xF1, 0xC6, 0xE1, 0x55, +0x90, 0x8B, 0x55, 0xE0, 0x64, 0x01, 0x70, 0x7D, 0xF1, 0xB1, 0x80, 0x79, 0x90, 0x8B, 0x55, 0xE0, +0xFF, 0xB4, 0x03, 0x04, 0xF1, 0xCA, 0x80, 0x6D, 0xEF, 0xB4, 0x02, 0x04, 0xF1, 0xA1, 0x80, 0x65, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0xD5, 0x80, 0x59, 0xEF, 0x70, 0x56, 0xF1, +0x8E, 0x80, 0x52, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x05, 0x12, 0x7C, 0x41, 0x80, 0x46, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x01, 0x04, 0xF1, 0x72, 0x80, 0x3B, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, +0x05, 0x12, 0x7D, 0x23, 0x80, 0x2F, 0x90, 0x8B, 0x55, 0xE0, 0x70, 0x29, 0xF1, 0x70, 0x80, 0x25, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x01, 0x04, 0xF1, 0x5A, 0x80, 0x19, 0xEF, 0xB4, 0x02, 0x04, +0xF1, 0x6B, 0x80, 0x11, 0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0x5A, 0x80, 0x05, +0xEF, 0x70, 0x02, 0xF1, 0x67, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, +0x90, 0x8B, 0x33, 0x74, 0x03, 0xF0, 0x22, 0xF1, 0x8E, 0x80, 0xEF, 0x12, 0x7D, 0x42, 0x80, 0xEA, +0xF1, 0x8E, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x9A, 0xEF, 0x70, 0x06, 0x90, 0x01, +0xC8, 0x74, 0xFD, 0xF0, 0x12, 0x7C, 0x50, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x01, +0x3E, 0x74, 0x03, 0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x31, 0xB7, 0x90, 0x8B, 0x33, 0x74, 0x01, 0xF0, +0x22, 0x12, 0x7D, 0x42, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, 0xF1, +0xA1, 0x7D, 0x03, 0x7F, 0x02, 0x12, 0x31, 0x49, 0x90, 0x05, 0x27, 0xE4, 0xF0, 0x90, 0x8B, 0x33, +0xF0, 0x22, 0xF1, 0xCA, 0x80, 0xEB, 0xF1, 0xD5, 0x80, 0xE7, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, +0x8B, 0x33, 0x04, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, +0xF1, 0x8E, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0x90, +0x02, 0x84, 0xEF, 0xF0, 0xA3, 0xEE, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0xEF, 0x8E, 0xF0, 0x12, +0x43, 0xBA, 0x50, 0x1A, 0x00, 0x40, 0x50, 0x42, 0x00, 0x80, 0x50, 0x6D, 0x01, 0x00, 0x50, 0x81, +0x02, 0x00, 0x50, 0x99, 0x04, 0x00, 0x00, 0x00, 0x50, 0xB6, 0xED, 0x54, 0x3F, 0x70, 0x04, 0xFE, +0xFF, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x40, 0xEF, 0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xEF, 0x78, 0x06, +0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x78, 0x06, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +0x80, 0x26, 0xED, 0x54, 0x7F, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x80, 0xEF, +0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xEF, 0x78, 0x07, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x78, +0x07, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFD, 0xAC, 0x06, 0x80, 0x49, 0xED, 0x70, 0x04, +0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x01, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x7D, 0x00, 0xFC, 0x80, +0x35, 0xEC, 0x54, 0x01, 0x4D, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x02, 0x7F, 0x00, 0xEF, +0x2D, 0xEE, 0x3C, 0xC3, 0x13, 0x7D, 0x00, 0x80, 0x1A, 0xEC, 0x54, 0x03, 0x4D, 0x70, 0x04, 0xFE, +0xFF, 0x80, 0x04, 0x7E, 0x04, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x13, 0x13, 0x54, 0x3F, 0x7D, +0x00, 0x25, 0xE0, 0x25, 0xE0, 0xFC, 0xAE, 0x04, 0xAF, 0x05, 0x22, 0x90, 0x01, 0xE4, 0x74, 0x58, +0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x22, 0xE4, 0x90, 0x8A, 0xCC, 0xF0, 0xA3, 0xF0, 0x75, 0x8E, 0x02, +0x91, 0x0E, 0x12, 0x68, 0x44, 0x90, 0x8B, 0x07, 0xEF, 0xF0, 0x12, 0x68, 0x51, 0x90, 0x8B, 0x09, +0xEF, 0xF0, 0x12, 0x68, 0x5D, 0x90, 0x8A, 0xF4, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xF5, 0x55, +0xF5, 0x21, 0x12, 0x72, 0x55, 0x12, 0x44, 0x9E, 0x12, 0x2E, 0x01, 0x7F, 0x03, 0x12, 0x78, 0x42, +0x12, 0x7C, 0x3D, 0x12, 0x68, 0x0A, 0x12, 0x68, 0x75, 0x12, 0x68, 0x8A, 0x12, 0x68, 0x28, 0x12, +0x68, 0x43, 0x90, 0x8A, 0xCE, 0xE5, 0xD9, 0xF0, 0x31, 0x5F, 0xC2, 0xAF, 0x90, 0x00, 0x80, 0xE0, +0x44, 0x40, 0xF0, 0x51, 0x0E, 0x75, 0xE8, 0x03, 0x43, 0xA8, 0x85, 0xD2, 0xAF, 0x11, 0xBB, 0x90, +0x8A, 0xCC, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0xC6, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x50, 0xA3, 0xF0, +0xE5, 0x55, 0x30, 0xE4, 0x09, 0xC2, 0xAF, 0x53, 0x55, 0xEF, 0xD2, 0xAF, 0xB1, 0x59, 0xE5, 0x55, +0x30, 0xE6, 0xDC, 0xC2, 0xAF, 0x53, 0x55, 0xBF, 0xD2, 0xAF, 0x12, 0x6B, 0xBD, 0x80, 0xD0, 0x90, +0x01, 0x3C, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xF0, 0xA3, 0xF0, 0xA3, +0xF0, 0xA3, 0xF0, 0xFD, 0x7F, 0x54, 0x31, 0x88, 0x7D, 0xFF, 0x7F, 0x55, 0x31, 0x88, 0x7D, 0xFF, +0x7F, 0x56, 0x31, 0x88, 0x7D, 0xFF, 0x7F, 0x57, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, +0x82, 0x75, 0x83, 0x00, 0xED, 0xF0, 0x51, 0x0E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0x30, +0xE4, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x38, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xFD, 0x7F, 0x50, 0x31, 0x88, 0xE4, 0xFD, 0x7F, 0x51, 0x31, 0x88, 0xE4, 0xFD, 0x7F, +0x52, 0x31, 0x88, 0xE4, 0xFD, 0x7F, 0x53, 0x80, 0xBF, 0xE5, 0x5E, 0x64, 0x01, 0x70, 0x3B, 0x71, +0x4E, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x71, 0x42, 0x90, 0x00, 0x46, 0xE0, 0x44, 0x04, 0xFD, 0x7F, +0x46, 0x31, 0x88, 0x90, 0x00, 0x44, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x44, 0x31, 0x88, 0x90, 0x00, +0x46, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x46, 0x31, 0x88, 0x7F, 0x02, 0x71, 0x6A, 0x8F, 0x62, 0x90, +0x01, 0xC9, 0xE5, 0x62, 0xF0, 0xB4, 0x01, 0x02, 0x51, 0xE2, 0x22, 0xE0, 0x5F, 0xF0, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x10, 0xDF, 0xFE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xE0, 0xED, 0xF0, 0x90, 0x8A, 0xDF, 0xEF, 0xF0, 0xD3, +0x94, 0x07, 0x50, 0x4E, 0xA3, 0xE0, 0x70, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, +0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x5F, 0xF0, +0x80, 0x17, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, +0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x4F, 0xF0, 0x51, 0x0E, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, +0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x46, +0x80, 0x59, 0x90, 0x8A, 0xDF, 0xE0, 0x24, 0xF8, 0xF0, 0xA3, 0xE0, 0x70, 0x1D, 0x90, 0x8A, 0xDF, +0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xC4, 0x54, 0xF0, +0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x80, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, +0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0x00, +0x43, 0xE0, 0x4F, 0xF0, 0x51, 0x0E, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, +0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0x51, 0x0B, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0x90, 0x00, 0x49, 0xE0, 0x90, 0x8B, 0x54, 0xF0, 0xE0, 0x54, 0x0F, 0xF0, 0x44, 0xF0, +0xFD, 0x7F, 0x49, 0x31, 0x88, 0x90, 0x8B, 0x54, 0xE0, 0x44, 0xB0, 0xFD, 0x7F, 0x49, 0x21, 0x88, +0x90, 0x8A, 0xDD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0x5E, 0x01, 0x8E, 0x5F, 0xF5, 0x60, 0xE4, +0xFD, 0x7F, 0x0B, 0x51, 0x1E, 0xE4, 0xFD, 0x7F, 0x02, 0x51, 0x1E, 0x71, 0x4E, 0xE4, 0xFF, 0x71, +0x42, 0xE4, 0xF5, 0x62, 0x90, 0x01, 0xC9, 0xE5, 0x62, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0xEC, 0xFB, 0x8D, 0x44, 0xE4, 0xF5, 0x45, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01, 0x02, +0x30, 0x62, 0x90, 0x01, 0xCA, 0xE5, 0x61, 0xF0, 0xEF, 0x60, 0x02, 0x51, 0xE2, 0x22, 0x7F, 0x0B, +0x71, 0x6A, 0xEF, 0x65, 0x61, 0x60, 0x10, 0xE5, 0x61, 0xB4, 0x01, 0x05, 0xE4, 0xF5, 0x61, 0x80, +0x03, 0x75, 0x61, 0x01, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x8B, 0x57, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x43, 0xE0, 0xFF, 0x74, 0x01, 0xA8, +0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x46, 0x51, 0x0B, 0x90, +0x8B, 0x57, 0xE0, 0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x00, 0x44, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x5B, 0xA8, 0x05, +0x08, 0x80, 0x06, 0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0x80, 0x4B, 0x90, 0x8B, +0x57, 0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, +0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x51, 0x0E, 0x90, 0x8B, 0x57, 0xE0, +0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x5B, 0xA8, 0x05, 0x08, 0x80, 0x06, +0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0x90, +0x8B, 0x04, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x21, 0x88, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDA, 0x12, 0x43, +0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFA, 0xE5, 0xF0, 0x24, 0x00, 0xFF, 0xE4, 0x3A, 0xFE, +0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEE, 0x8F, 0xF0, 0x12, 0x43, 0x19, 0x12, +0x24, 0x62, 0xFF, 0x60, 0x2C, 0xB5, 0x5E, 0x16, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, +0x01, 0x12, 0x42, 0xC2, 0x65, 0x60, 0x70, 0x04, 0xE5, 0x5F, 0x65, 0xF0, 0x60, 0x22, 0x90, 0x8A, +0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFF, 0xAE, 0xF0, 0x71, 0x00, 0x80, +0x0F, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x24, 0x62, 0x65, 0x5E, 0x60, 0x02, 0x91, 0x95, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xF5, 0x5E, 0x7F, 0x60, 0x7E, 0x01, 0x8F, 0x82, 0x8E, 0x83, +0xA3, 0xA3, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x8B, 0xEF, 0x12, 0x43, 0x94, +0x54, 0xE7, 0x01, 0x54, 0xDE, 0x02, 0x55, 0x0B, 0x03, 0x55, 0x14, 0x05, 0x55, 0x1D, 0x06, 0x55, +0x58, 0x07, 0x55, 0x25, 0x08, 0x55, 0x2E, 0x09, 0x55, 0x36, 0x20, 0x55, 0x3F, 0x2C, 0x54, 0xF0, +0x2D, 0x54, 0xF9, 0x2E, 0x55, 0x02, 0x3B, 0x55, 0x48, 0x4B, 0x00, 0x00, 0x55, 0x51, 0x90, 0x8A, +0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x85, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x8B, +0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0xB8, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, +0x75, 0x00, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x75, 0x39, 0x90, 0x8A, 0xD7, 0x12, 0x43, +0x6B, 0x02, 0x75, 0x52, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, 0x0F, 0x90, 0x8A, 0xD7, +0x12, 0x43, 0x6B, 0xC1, 0xA6, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x75, 0x9A, 0x90, 0x8A, +0xD7, 0x12, 0x43, 0x6B, 0x81, 0x1E, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x78, 0x81, 0x90, +0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x7A, 0xC2, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x7C, +0x2B, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFD, 0x70, +0x02, 0xC1, 0xA1, 0x90, 0x8B, 0x51, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xC1, 0x9A, 0x90, +0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD0, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD0, +0xF0, 0x75, 0x1D, 0x01, 0x75, 0x1E, 0x8A, 0x75, 0x1F, 0xD0, 0x75, 0x20, 0x01, 0x7B, 0x01, 0x7A, +0x8A, 0x79, 0xD1, 0x12, 0x5E, 0xE4, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54, +0x01, 0x90, 0x8B, 0x51, 0x30, 0xE0, 0x59, 0xE0, 0x75, 0xF0, 0x02, 0x90, 0x00, 0x88, 0x12, 0x43, +0x5F, 0xE0, 0x90, 0x8A, 0xD2, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x02, 0x90, 0x00, 0x89, +0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD3, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, +0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD4, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, +0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD5, 0xF0, 0x90, 0x8B, 0x51, 0xE0, +0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD6, 0xF0, 0x80, 0x33, +0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD2, 0xF0, 0x90, +0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD3, +0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, 0x5F, 0xE0, 0x90, +0x8A, 0xD4, 0xF0, 0xEF, 0x54, 0x7F, 0xFF, 0x7B, 0x01, 0x7A, 0x8A, 0x79, 0xD2, 0x91, 0xA6, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x90, 0x8B, 0x51, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, +0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0xFF, 0x74, +0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x8B, +0x51, 0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0xA1, 0x6A, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x02, +0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, 0xFF, 0x54, 0x1F, 0xFE, +0xEF, 0x54, 0x20, 0xC4, 0x13, 0x54, 0x07, 0xFD, 0xAF, 0x06, 0x90, 0x8A, 0xDA, 0xEF, 0xF0, 0xA3, +0xED, 0xF0, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x03, 0x12, +0x42, 0x20, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x00, 0x04, 0x12, 0x42, +0x20, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x8A, 0xE0, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, +0xFF, 0x75, 0xF0, 0x09, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0xAD, 0x82, 0xAC, 0x83, 0x90, 0x8A, +0xE1, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0x23, 0xF9, 0x74, 0x87, +0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, +0x00, 0x03, 0x12, 0x42, 0x20, 0x54, 0x0F, 0xFF, 0x90, 0x8A, 0xE3, 0x12, 0x43, 0x6B, 0xEF, 0x12, +0x42, 0x4D, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x90, +0x8A, 0xE3, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x90, 0x8A, 0xDC, 0x12, +0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, 0xFC, 0xA3, 0xE0, +0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xEF, 0xF0, 0x12, 0x24, 0x62, 0x8D, 0x82, 0x8C, 0x83, 0xA3, 0xF0, +0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x24, 0xC1, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xDB, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, +0x29, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, 0x12, 0x43, 0x5F, +0x74, 0x01, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2B, 0x12, +0x43, 0x5F, 0xEE, 0xF0, 0x8F, 0x0F, 0xEF, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, +0xAF, 0x82, 0xF5, 0x10, 0x8F, 0x11, 0xE5, 0x0F, 0x75, 0xF0, 0x02, 0xA4, 0x24, 0x81, 0xF9, 0x74, +0x86, 0x35, 0xF0, 0x75, 0x12, 0x01, 0xF5, 0x13, 0x89, 0x14, 0x75, 0xF0, 0x09, 0xE5, 0x0F, 0x90, +0x87, 0x25, 0x12, 0x43, 0x5F, 0xAF, 0x82, 0x85, 0x83, 0x15, 0x8F, 0x16, 0xE5, 0x0F, 0x75, 0xF0, +0x09, 0xA4, 0x24, 0x23, 0xF9, 0x74, 0x87, 0x35, 0xF0, 0x75, 0x17, 0x01, 0xF5, 0x18, 0x89, 0x19, +0x74, 0xC1, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x12, 0x43, 0x94, 0x58, +0x34, 0x00, 0x58, 0x49, 0x01, 0x58, 0x5E, 0x02, 0x58, 0x73, 0x03, 0x58, 0x9C, 0x04, 0x58, 0xB1, +0x05, 0x58, 0xC6, 0x06, 0x58, 0xEC, 0x0C, 0x59, 0x19, 0x0D, 0x59, 0x46, 0x0E, 0x59, 0x73, 0x0F, +0x00, 0x00, 0x59, 0xA7, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x15, 0x80, 0x3C, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x10, 0x80, 0x27, 0xE5, 0x0F, +0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, +0x05, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0x74, 0xF0, 0xF0, 0xA3, 0xE4, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0x8F, 0xF0, 0x21, 0xA7, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0xF5, 0x80, +0x27, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0x0F, +0xF0, 0xA3, 0x74, 0xF0, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0x74, 0x0D, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, +0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x21, 0xA7, 0x90, 0x04, 0x47, 0xE0, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x46, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x45, 0xE0, 0x85, 0x11, 0x82, +0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x44, 0x21, 0x9E, 0x90, 0x04, 0x4B, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x4A, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x49, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, +0xF0, 0x90, 0x04, 0x48, 0x80, 0x58, 0x90, 0x04, 0x4F, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x12, 0x42, 0x4D, 0x90, 0x04, 0x4E, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, +0x12, 0x42, 0x5F, 0x90, 0x04, 0x4D, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, +0x4C, 0x80, 0x2B, 0x90, 0x04, 0x53, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, +0x90, 0x04, 0x52, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, +0x90, 0x04, 0x51, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x50, 0xE0, 0x85, +0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0xC0, 0x03, 0xC0, +0x02, 0xC0, 0x01, 0x12, 0x24, 0x62, 0xFF, 0xAB, 0x17, 0xAA, 0x18, 0xA9, 0x19, 0x12, 0x24, 0x62, +0x5F, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x42, 0x4D, 0xAB, 0x12, 0xE5, 0x14, 0x24, 0x01, +0xF9, 0xE4, 0x35, 0x13, 0xFA, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x12, 0x24, 0x62, 0xFF, 0xAB, +0x17, 0xAA, 0x18, 0xA9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x5F, 0xD0, 0x01, 0xD0, 0x02, +0xD0, 0x03, 0x12, 0x42, 0x4D, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, +0xFF, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, +0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x85, 0x16, 0x82, +0x85, 0x15, 0x83, 0xA3, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xE5, 0x0F, 0x25, +0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, +0x4B, 0x90, 0x8A, 0xE6, 0x74, 0x0B, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x00, 0x50, +0x02, 0x41, 0xEC, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, +0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x0A, 0x90, 0x8A, 0xE6, 0xE0, 0x24, 0x10, +0xA3, 0xF0, 0x80, 0x68, 0x90, 0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBB, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x47, +0x90, 0x8A, 0xE6, 0x74, 0x0F, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x00, 0x40, 0x3C, +0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x5E, +0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x08, 0x90, 0x8A, 0xE6, 0xE0, 0xA3, 0xF0, 0x80, 0x0D, 0x90, +0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBF, 0xE4, 0x90, 0x8A, 0xE7, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x46, +0xE4, 0x90, 0x8A, 0xE6, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x40, 0x02, 0x61, +0xA5, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, +0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x06, 0x90, 0x8A, 0xE6, 0xE0, 0x80, 0x63, 0x90, 0x8A, +0xE6, 0xE0, 0x04, 0xF0, 0x80, 0xBF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x46, 0xE4, 0x90, 0x8A, 0xE6, 0xF0, 0x90, +0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x0C, 0x50, 0x3C, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, +0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x08, +0x90, 0x8A, 0xE6, 0xE0, 0x24, 0x10, 0x80, 0x09, 0x90, 0x8A, 0xE6, 0xE0, 0x04, 0xF0, 0x80, 0xBF, +0xE4, 0x90, 0x8A, 0xE8, 0xF0, 0x90, 0x8A, 0xE7, 0xE0, 0xFF, 0x75, 0xF0, 0x09, 0xE5, 0x0F, 0x90, +0x87, 0x27, 0x12, 0x43, 0x5F, 0xEF, 0xF0, 0x90, 0x8A, 0xE8, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xE5, +0x0F, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xE5, 0x0F, 0xC3, 0x94, 0x20, 0x50, 0x32, +0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xD3, 0x9F, 0x40, 0x02, +0x80, 0x18, 0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xC3, 0x9E, +0x50, 0x08, 0x90, 0x8A, 0xE8, 0xE0, 0xA3, 0xF0, 0x80, 0x08, 0x90, 0x8A, 0xE7, 0xE0, 0x90, 0x8A, +0xE9, 0xF0, 0x90, 0x8A, 0xE9, 0xE0, 0xFD, 0xAF, 0x0F, 0x91, 0x4E, 0x90, 0x8A, 0xE9, 0xE0, 0xFF, +0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x8A, 0xE7, +0xE0, 0xFF, 0xD3, 0x94, 0x13, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x03, 0xF0, 0x22, 0xEF, 0xD3, +0x94, 0x0B, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x02, 0xF0, 0x22, 0xEF, 0xD3, 0x94, 0x03, 0x40, +0x07, 0x90, 0x87, 0x22, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0x87, 0x22, 0xF0, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x74, 0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xED, +0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAC, 0x07, 0xED, 0x54, 0x1F, 0x90, 0x8A, 0xC7, 0xF0, 0x74, +0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xC5, 0xF0, 0x90, 0x8A, +0xC8, 0x74, 0x01, 0xF0, 0xEB, 0xC3, 0x94, 0x01, 0x40, 0x02, 0x80, 0x37, 0x90, 0x8A, 0xC5, 0xE0, +0x25, 0x0D, 0xFF, 0xA3, 0xF0, 0xA3, 0xE0, 0x90, 0x41, 0x9E, 0x93, 0xFE, 0xEF, 0xD3, 0x9E, 0x40, +0x10, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xAF, 0x04, 0x80, +0x9D, 0x90, 0x8A, 0xC6, 0xE0, 0xFF, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEF, 0xF0, 0x22, 0xAD, 0x07, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, +0xFF, 0x90, 0x8A, 0xCA, 0xF0, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, +0x54, 0x1F, 0x90, 0x8A, 0xC9, 0xF0, 0xD3, 0x9F, 0x40, 0x06, 0xA3, 0xE0, 0x90, 0x8A, 0xC9, 0xF0, +0x90, 0x8A, 0xC9, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, +0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, +0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xC9, 0xE0, 0xFD, 0x91, 0x4E, 0x90, 0x8A, 0xC9, 0xE0, 0xFF, +0x22, 0xAC, 0x07, 0x74, 0x84, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x7F, +0x90, 0x8A, 0xDE, 0xF0, 0xE0, 0x54, 0x1F, 0xFF, 0x90, 0x8A, 0xE1, 0xF0, 0x75, 0xF0, 0x09, 0xEC, +0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xE3, 0xF0, 0x75, 0xF0, 0x09, 0xEC, 0x90, +0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0x90, 0x8A, 0xE4, 0xF0, 0xEC, 0x25, 0xE0, 0x24, 0xE4, +0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE5, 0xCB, 0xF0, +0xA3, 0xEB, 0xF0, 0xEC, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, +0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE7, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xEF, 0xD3, 0x9E, 0x40, 0x0C, +0x90, 0x8A, 0xE4, 0xE0, 0x90, 0x8A, 0xE1, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0xED, 0x70, 0x02, 0xC1, +0x93, 0x90, 0x8A, 0xE2, 0xED, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0x30, 0xE6, 0x0E, 0x90, 0x8A, 0xE1, +0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0x14, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0x70, +0x02, 0xC1, 0x93, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0xD3, 0x94, 0x00, 0x50, 0x02, 0xC1, 0x93, 0xE4, +0x90, 0x8A, 0xE0, 0xF0, 0xEF, 0x14, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xE3, 0xE0, 0xFD, 0x90, +0x8A, 0xDF, 0xE0, 0xFF, 0xD3, 0x9D, 0x40, 0x6F, 0xEF, 0x94, 0x10, 0x40, 0x21, 0xEF, 0x24, 0xF0, +0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x8A, 0xE7, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x70, 0x27, 0x90, 0x8A, +0xDF, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x37, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE5, 0xE0, 0x5E, 0xFE, 0xA3, +0xE0, 0x5F, 0x4E, 0x60, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0x04, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, 0x6F, 0x60, 0x08, 0x90, +0x8A, 0xDF, 0xE0, 0x14, 0xF0, 0x80, 0x83, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, +0xC3, 0x9F, 0x50, 0x0F, 0x90, 0x8A, 0xDF, 0xE0, 0xB5, 0x05, 0x08, 0x90, 0x8A, 0xE3, 0xE0, 0x90, +0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, +0xFE, 0xEF, 0x13, 0xFF, 0xEC, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x90, 0x8A, 0xDE, 0xE0, 0xFD, 0x91, 0x4E, 0x90, 0x8A, +0xDE, 0xE0, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x1A, 0x8A, 0x1B, 0x89, +0x1C, 0x90, 0x8B, 0x3F, 0x12, 0x43, 0x8B, 0xAB, 0x1D, 0xAA, 0x1E, 0xA9, 0x1F, 0x90, 0x8B, 0x42, +0x12, 0x43, 0x8B, 0xAF, 0x20, 0x15, 0x20, 0xEF, 0x60, 0x1E, 0x90, 0x8B, 0x42, 0xE4, 0x75, 0xF0, +0x01, 0x12, 0x43, 0x74, 0x12, 0x24, 0x62, 0xFF, 0x90, 0x8B, 0x3F, 0xE4, 0x75, 0xF0, 0x01, 0x12, +0x43, 0x74, 0xEF, 0x12, 0x42, 0x4D, 0x80, 0xDB, 0xAB, 0x1A, 0xAA, 0x1B, 0xA9, 0x1C, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x8B, +0x90, 0x8B, 0x53, 0xE0, 0xFF, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x7F, 0xAF, +0x7E, 0x01, 0x12, 0x74, 0x3B, 0xEF, 0x60, 0x47, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x6B, 0x8B, 0x1D, +0x8A, 0x1E, 0x89, 0x1F, 0x75, 0x20, 0x02, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0xD1, 0xE4, 0x90, +0x8B, 0x48, 0x12, 0x43, 0x6B, 0x8B, 0x1D, 0x8A, 0x1E, 0x89, 0x1F, 0x90, 0x8B, 0x45, 0x12, 0x43, +0x6B, 0x12, 0x24, 0x62, 0xFF, 0xC4, 0x54, 0x0F, 0xF5, 0x20, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA2, +0xD1, 0xE4, 0x90, 0x01, 0xAF, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8A, 0xC5, 0xE0, 0x54, 0xF0, 0x44, 0x03, 0xF0, 0x54, 0x0F, 0x44, +0x80, 0xF0, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x56, 0x90, 0x8B, 0x48, 0x12, 0x43, 0x8B, 0x0B, 0x7A, +0x8A, 0x79, 0xC5, 0xE1, 0x33, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0xC4, 0x74, +0xC5, 0xF0, 0x74, 0x5F, 0xA3, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A, 0x90, 0x05, 0x22, 0xE0, +0x54, 0x90, 0x60, 0x07, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x01, 0xC7, 0xE0, 0x30, +0xE1, 0xE4, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFB, 0xFA, 0xEF, 0x30, 0xE0, 0x02, 0x7B, 0x80, 0xEF, 0xC3, 0x13, +0x90, 0xFD, 0x10, 0xF0, 0x90, 0x04, 0x25, 0xEF, 0xF0, 0xED, 0x60, 0x1E, 0xAF, 0x03, 0x74, 0x0F, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x10, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x03, 0x74, 0x08, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0x21, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0xE0, 0x54, 0xF7, 0xF0, 0xAE, 0x02, 0xAF, 0x03, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x5F, 0xC5, +0xBF, 0x01, 0x10, 0x90, 0x02, 0x09, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xFD, 0x90, 0x04, 0x1F, +0x74, 0x20, 0xF0, 0x22, 0x90, 0x01, 0x02, 0xE0, 0x54, 0x03, 0xFF, 0xE0, 0x54, 0x0C, 0x13, 0x13, +0x54, 0x3F, 0xFE, 0xEF, 0x64, 0x01, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x0E, 0x90, 0x8A, 0xC5, 0x74, +0x01, 0xF0, 0xA3, 0x74, 0x37, 0xF0, 0x79, 0x01, 0x80, 0x18, 0xEE, 0x64, 0x01, 0x60, 0x07, 0xAF, +0x06, 0xEE, 0x64, 0x03, 0x70, 0x3B, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x3D, 0xF0, +0x79, 0x40, 0x90, 0x8A, 0xC5, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x59, +0x60, 0x08, 0xE9, 0xF0, 0xE4, 0x90, 0x8A, 0xF6, 0xF0, 0x22, 0x90, 0x8A, 0xF6, 0xE0, 0x04, 0xF0, +0xE0, 0xC3, 0x94, 0x0A, 0x40, 0x0B, 0xE4, 0xF0, 0x90, 0x04, 0x19, 0xE0, 0x30, 0xE0, 0x02, 0x11, +0x6D, 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, 0xF2, 0xF0, 0x74, 0x60, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x28, 0xF5, +0x2C, 0xA3, 0xE0, 0x55, 0x29, 0xF5, 0x2D, 0xA3, 0xE0, 0x55, 0x2A, 0xF5, 0x2E, 0xA3, 0xE0, 0x55, +0x2B, 0xF5, 0x2F, 0xE5, 0x2C, 0x20, 0xE0, 0x02, 0x41, 0x89, 0x90, 0x01, 0x34, 0x74, 0x01, 0xF0, +0x85, 0xD1, 0x4D, 0x85, 0xD2, 0x4E, 0x85, 0xD3, 0x4F, 0x85, 0xD4, 0x50, 0x85, 0xD5, 0x51, 0x85, +0xD6, 0x52, 0x85, 0xD7, 0x53, 0x85, 0xD9, 0x54, 0xE5, 0x54, 0x54, 0x40, 0xC3, 0x13, 0xFF, 0xE5, +0x53, 0x54, 0x20, 0x6F, 0x70, 0x02, 0x41, 0x46, 0xE5, 0x54, 0x30, 0xE5, 0x02, 0x41, 0x46, 0xE5, +0x52, 0x54, 0x1F, 0xF5, 0x08, 0xE5, 0x4D, 0x54, 0x3F, 0xF5, 0x09, 0xE5, 0x51, 0x54, 0x1F, 0xFF, +0xE5, 0x08, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, +0x12, 0x42, 0x81, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, +0xE4, 0x34, 0x85, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x09, 0xD3, 0x94, 0x04, +0x40, 0x03, 0x75, 0x09, 0x04, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, 0x43, 0x5F, +0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE5, 0x53, 0x54, +0x1F, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, 0x43, +0x5F, 0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x54, +0x20, 0xE6, 0x24, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, +0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x4F, 0x30, 0xE7, 0x36, +0xAF, 0x08, 0x12, 0x5C, 0xC3, 0x80, 0x2F, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, +0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, +0x4F, 0x30, 0xE7, 0x12, 0xE5, 0x4F, 0x54, 0x7F, 0xFD, 0xE5, 0x53, 0x54, 0x1F, 0xF5, 0x0D, 0xAB, +0x09, 0xAF, 0x08, 0x12, 0x5C, 0x66, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x3A, 0x90, +0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, +0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x21, 0x90, 0x8B, 0x3D, 0x12, 0x4B, 0x5C, 0x90, 0x01, +0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x80, 0x09, +0x12, 0x4B, 0x34, 0xBF, 0x01, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2C, 0x30, 0xE1, 0x21, 0x90, 0x01, +0x34, 0x74, 0x02, 0xF0, 0x85, 0xD1, 0x56, 0x85, 0xD2, 0x57, 0x85, 0xD3, 0x58, 0x85, 0xD4, 0x59, +0x85, 0xD5, 0x5A, 0x85, 0xD6, 0x5B, 0x85, 0xD7, 0x5C, 0x85, 0xD9, 0x5D, 0x12, 0x5F, 0xA4, 0xE5, +0x2C, 0x30, 0xE3, 0x06, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0xE5, 0x2C, 0x30, 0xE4, 0x09, 0x90, +0x01, 0x34, 0x74, 0x10, 0xF0, 0x43, 0x55, 0x10, 0xE5, 0x2C, 0x30, 0xE5, 0x26, 0x90, 0x01, 0xCF, +0xE0, 0x30, 0xE5, 0x1F, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0x75, 0xA8, +0x00, 0x75, 0xE8, 0x00, 0x12, 0x51, 0x9D, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x12, 0x52, +0x0E, 0x80, 0xFE, 0xE5, 0x2C, 0x30, 0xE6, 0x2D, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0x90, 0x8B, +0x32, 0xE0, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, 0x90, 0x8B, 0x34, 0xE4, +0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, +0x90, 0x8B, 0x2E, 0xE4, 0xF0, 0xE5, 0x2E, 0x20, 0xE0, 0x02, 0x61, 0xE6, 0x90, 0x8B, 0x08, 0x74, +0x01, 0xF0, 0x90, 0x01, 0x36, 0xF0, 0x90, 0x8B, 0x06, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, +0x53, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, +0xE0, 0x2F, 0x90, 0x8B, 0x37, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, +0x3F, 0x30, 0xE0, 0x1D, 0x90, 0x8B, 0x34, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0D, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x7F, 0x04, 0x12, 0x4E, +0x89, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x55, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x4E, +0x90, 0x8B, 0x2E, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x3E, +0xB1, 0x5F, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, +0x2D, 0xEF, 0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, +0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x02, 0x04, 0x7F, 0x01, 0xB1, 0x82, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x43, +0xE7, 0x90, 0x8B, 0x08, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE1, 0x2F, 0x90, 0x01, 0x36, 0x74, 0x02, +0xF0, 0x43, 0x55, 0x40, 0x11, 0x84, 0x90, 0x8B, 0x37, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x05, 0x22, +0xE4, 0xF0, 0x90, 0x8B, 0x37, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x0D, 0xE4, 0xFF, 0x12, +0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE2, 0x16, 0x90, +0x01, 0x36, 0x74, 0x04, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x06, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x03, 0x12, 0x46, 0xB3, 0xE5, 0x2E, 0x30, 0xE3, 0x38, 0x90, 0x01, 0x36, 0x74, 0x08, 0xF0, +0xE5, 0x21, 0x64, 0x01, 0x70, 0x2C, 0xE5, 0x24, 0x60, 0x28, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, +0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, 0x8B, +0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, +0x05, 0xF0, 0xE5, 0x2E, 0x30, 0xE4, 0x2B, 0x90, 0x01, 0x36, 0x74, 0x10, 0xF0, 0xE5, 0x21, 0xB4, +0x01, 0x20, 0xE5, 0x24, 0x60, 0x1C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, +0xF0, 0x90, 0x8B, 0x1B, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x03, 0x12, +0x4A, 0xFC, 0xE5, 0x2E, 0x30, 0xE5, 0x1F, 0x90, 0x01, 0x36, 0x74, 0x20, 0xF0, 0xE5, 0x21, 0xB4, +0x01, 0x14, 0xE5, 0x24, 0x60, 0x10, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, 0x4A, +0x97, 0x80, 0x03, 0x12, 0x49, 0x49, 0xE5, 0x2E, 0x30, 0xE6, 0x1B, 0x90, 0x01, 0x36, 0x74, 0x40, +0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x10, 0xE5, 0x24, 0x60, 0x0C, 0x53, 0x25, 0xFE, 0xE5, 0x25, 0x54, +0x07, 0x70, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2F, 0x30, 0xE1, 0x28, 0x90, 0x01, 0x37, 0x74, 0x02, +0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x18, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x08, +0x12, 0x48, 0xFE, 0x12, 0x7D, 0xC1, 0x80, 0x0B, 0x90, 0x8B, 0x31, 0x74, 0x01, 0xF0, 0x80, 0x03, +0x12, 0x48, 0xFE, 0x74, 0xF2, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x60, 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, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x05, +0x58, 0xE0, 0xFF, 0x90, 0x8B, 0x38, 0xE0, 0x2F, 0x24, 0xFE, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, +0xFD, 0x7F, 0x50, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x53, 0x74, 0x05, 0xF0, 0x22, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x0A, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x04, 0x7F, 0x06, 0xB1, 0x82, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x03, 0x12, 0x78, +0x35, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0x6F, 0x70, +0x02, 0xE1, 0x4E, 0xEF, 0x12, 0x43, 0x94, 0x65, 0xB0, 0x00, 0x65, 0xEA, 0x01, 0x66, 0x30, 0x02, +0x66, 0x6A, 0x03, 0x66, 0xA2, 0x04, 0x66, 0xDB, 0x05, 0x67, 0x16, 0x06, 0x00, 0x00, 0x67, 0x4E, +0xEE, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, 0x81, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0xB4, +0x05, 0x04, 0xF1, 0x5D, 0xE1, 0x4E, 0xEF, 0xB4, 0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0x80, 0x16, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xA4, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, +0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, +0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, +0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0xE1, 0x4E, 0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, +0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x02, 0x60, 0x02, 0xE1, 0x4E, 0xF1, 0x67, 0xE1, 0x4E, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0x80, 0x16, +0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0x7F, 0x01, 0xF1, 0x72, 0x80, 0x08, 0xEE, 0xB4, +0x03, 0x04, 0x7F, 0x01, 0xF1, 0x53, 0xF1, 0xD0, 0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, +0x06, 0x7F, 0x01, 0xF1, 0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, +0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xF1, 0x9A, 0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, +0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x06, 0xEE, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xB9, +0xE1, 0x4E, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x13, +0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, 0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, +0x02, 0xF1, 0x67, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0xF1, 0xA4, 0x80, 0x09, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0xF1, 0xAF, 0x80, 0x73, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, +0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xF1, 0x72, 0x80, 0x13, 0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xF1, +0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0x90, 0x8B, 0x2D, 0xE0, +0xB4, 0x01, 0x04, 0xF1, 0xA4, 0x80, 0x0B, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x04, 0x7F, 0x01, +0xF1, 0x81, 0xF1, 0xC3, 0x80, 0x38, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xF1, +0x81, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xF1, 0x5D, 0x90, 0x8B, 0x2D, 0xE0, +0x70, 0x04, 0xF1, 0x9A, 0x80, 0x16, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x06, 0xE4, 0xFF, 0xF1, +0x53, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xF1, 0x67, 0xF1, 0xDD, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x12, 0x4A, 0xB2, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x22, 0x90, 0x05, 0x22, +0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0x04, +0xF0, 0x22, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, +0x22, 0x90, 0x8B, 0x56, 0xEF, 0xF0, 0x12, 0x7D, 0x42, 0x90, 0x8B, 0x56, 0xE0, 0x60, 0x05, 0x90, +0x05, 0x22, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x12, 0x4A, 0xCC, 0x90, 0x8B, 0x2D, +0x74, 0x01, 0xF0, 0x22, 0x7F, 0x01, 0x12, 0x4A, 0x7C, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x12, +0x7C, 0x4A, 0x90, 0x8B, 0x2D, 0x74, 0x04, 0xF0, 0x22, 0x12, 0x4A, 0x32, 0x90, 0x8B, 0x2D, 0x74, +0x03, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x05, 0xF0, 0x22, +0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, +0x74, 0x6F, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x06, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0xE4, 0xFD, 0xFC, 0xEF, 0x30, 0xE0, 0x02, 0x7D, 0x80, 0xEF, 0xC3, 0x13, 0x90, 0xFD, 0x10, +0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0x28, 0x33, 0xE4, 0xF5, 0x29, +0x75, 0x2A, 0x07, 0xF5, 0x2B, 0x90, 0x01, 0x30, 0xE5, 0x28, 0xF0, 0xA3, 0xE5, 0x29, 0xF0, 0xA3, +0xE5, 0x2A, 0xF0, 0xA3, 0xE5, 0x2B, 0xF0, 0x22, 0x75, 0x30, 0x1F, 0x75, 0x31, 0x01, 0x43, 0x31, +0x10, 0xE4, 0xF5, 0x32, 0x90, 0x01, 0x38, 0xE5, 0x30, 0xF0, 0xA3, 0xE5, 0x31, 0xF0, 0xA3, 0xE5, +0x32, 0xF0, 0x22, 0x22, 0x90, 0x00, 0x02, 0xE0, 0x54, 0xE0, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, +0x22, 0x90, 0x00, 0xF3, 0xE0, 0x7F, 0x00, 0x30, 0xE3, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x09, +0xE0, 0xB4, 0x01, 0x0C, 0x90, 0x00, 0xF2, 0xE0, 0x30, 0xE7, 0x05, 0x7E, 0xFD, 0x7F, 0x33, 0x22, +0x7E, 0xFD, 0x7F, 0x2F, 0x22, 0x90, 0x00, 0xF3, 0xE0, 0x30, 0xE2, 0x0D, 0x90, 0x05, 0x41, 0x74, +0x10, 0xF0, 0x90, 0x05, 0x5A, 0xF0, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x64, 0x74, 0xA0, 0xF0, +0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x06, +0xC0, 0x07, 0x7D, 0x91, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0x68, 0xFF, 0xA3, 0xF0, 0x53, 0x91, +0xEF, 0x90, 0x00, 0x51, 0xE0, 0xFE, 0x90, 0x00, 0x55, 0xE0, 0x5E, 0xF5, 0x3D, 0x90, 0x00, 0x52, +0xE0, 0xFE, 0x90, 0x00, 0x56, 0xE0, 0x5E, 0xF5, 0x3E, 0xE5, 0x3D, 0x30, 0xE4, 0x06, 0x90, 0x00, +0x55, 0x74, 0x10, 0xF0, 0xE5, 0x3D, 0x30, 0xE5, 0x06, 0x90, 0x00, 0x55, 0x74, 0x20, 0xF0, 0xE5, +0x3D, 0x30, 0xE6, 0x06, 0x90, 0x00, 0x55, 0x74, 0x40, 0xF0, 0xE5, 0x3D, 0x30, 0xE7, 0x06, 0x90, +0x00, 0x55, 0x74, 0x80, 0xF0, 0xE5, 0x3E, 0x30, 0xE0, 0x06, 0x90, 0x00, 0x56, 0x74, 0x01, 0xF0, +0xE5, 0x3E, 0x30, 0xE1, 0x06, 0x90, 0x00, 0x56, 0x74, 0x02, 0xF0, 0xE5, 0x3E, 0x30, 0xE2, 0x06, +0x90, 0x00, 0x56, 0x74, 0x04, 0xF0, 0xE5, 0x3E, 0x30, 0xE3, 0x06, 0x90, 0x00, 0x56, 0x74, 0x08, +0xF0, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, +0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xEF, 0xC3, 0x94, 0x20, 0x50, 0x39, 0xEF, 0x30, +0xE0, 0x17, 0xED, 0xC4, 0x54, 0xF0, 0xFD, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x0F, 0x80, 0x10, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, +0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0xA4, 0x2E, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x4D, 0xF0, 0x22, 0xAD, 0x07, 0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0x90, 0x8A, 0xDE, 0xF0, 0xE0, 0xF9, 0x54, 0x1F, 0xA3, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0xFF, 0x90, 0x8A, 0xE1, +0xF0, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, +0xE0, 0x90, 0x8A, 0xE2, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xED, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, +0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE4, 0xCB, 0xF0, 0xA3, 0xEB, +0xF0, 0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, +0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, +0x34, 0x86, 0xF5, 0x83, 0xEA, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0xB9, +0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, +0xF0, 0xEF, 0x04, 0x90, 0x8A, 0xE0, 0xF0, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, +0xFE, 0xD3, 0x9F, 0x40, 0x02, 0x41, 0xF3, 0xEE, 0xC3, 0x94, 0x10, 0x40, 0x21, 0xEE, 0x24, 0xF0, +0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0x90, 0x8A, 0xE2, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x70, 0x27, 0x90, 0x8A, +0xE0, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x59, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, +0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE4, 0xE0, 0x5E, 0xFE, 0xA3, +0xE0, 0x5F, 0x4E, 0x60, 0x3C, 0x90, 0x8A, 0xE0, 0xE0, 0xB4, 0x11, 0x0D, 0x90, 0x8A, 0xE3, 0xE0, +0x30, 0xE7, 0x06, 0x90, 0x8A, 0xE0, 0x74, 0x17, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFF, 0x64, 0x13, +0x60, 0x04, 0xEF, 0xB4, 0x12, 0x0D, 0x90, 0x8A, 0xE2, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x8A, 0xE0, +0x74, 0x18, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0x80, +0x42, 0x90, 0x8A, 0xE0, 0xE0, 0x04, 0xF0, 0x41, 0x17, 0x90, 0x8A, 0xE1, 0xE0, 0xFC, 0x90, 0x8A, +0xDF, 0xE0, 0xFF, 0x6C, 0x70, 0x71, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, +0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x29, 0x12, 0x43, 0x5F, 0xE0, 0xB4, 0x01, 0x10, +0xE9, 0x20, 0xE6, 0x0C, 0x90, 0x8A, 0xDF, 0xE0, 0x44, 0x40, 0x90, 0x8A, 0xDE, 0xF0, 0x80, 0x03, +0xAF, 0x01, 0x22, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, +0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x66, 0x90, 0x8A, 0xDF, 0xE0, 0xD3, 0x9C, 0x40, 0x5E, 0x90, +0x8A, 0xE1, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x8A, 0xDF, 0xEF, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0xFC, 0xA3, 0xE0, 0xFF, 0x25, 0xE0, 0x24, +0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, +0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, +0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, +0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x22, 0x74, 0x01, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xDE, 0xE0, 0x44, +0x80, 0xFD, 0x12, 0x5C, 0x4E, 0x90, 0x8A, 0xDE, 0xE0, 0x44, 0x80, 0xFF, 0x22, 0xE4, 0x90, 0x8A, +0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, 0x03, 0x02, 0x72, 0x54, 0x75, +0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, 0x12, 0x43, 0x5F, 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x72, +0x4B, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, +0xE0, 0xFC, 0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEC, 0x94, 0x00, 0x50, 0x03, 0x02, 0x72, 0x4B, 0xEF, +0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x00, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0x75, 0x12, 0x01, 0xF5, 0x13, +0x89, 0x14, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, +0x83, 0xE0, 0xFD, 0xA3, 0xE0, 0x90, 0x8A, 0xD4, 0xCD, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, 0x25, 0xE0, +0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xD6, +0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, +0x04, 0xF5, 0x83, 0xE0, 0x54, 0x3F, 0x90, 0x8A, 0xD0, 0xF0, 0xE0, 0xFD, 0x54, 0x1F, 0xA3, 0xF0, +0x75, 0xF0, 0x09, 0xEE, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD9, 0xF0, 0x90, +0x8A, 0xCF, 0xE0, 0xFB, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xC3, 0x94, +0x05, 0x40, 0x02, 0xC1, 0x9C, 0x90, 0x8A, 0xD9, 0xE0, 0xFE, 0x90, 0x8A, 0xD1, 0xE0, 0x9E, 0x40, +0x13, 0x90, 0x8A, 0xD9, 0xE0, 0x90, 0x8A, 0xD1, 0xF0, 0xED, 0x54, 0x40, 0xFD, 0x90, 0x8A, 0xD0, +0xF0, 0xEE, 0x4D, 0xF0, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0x90, 0x41, 0x12, 0x93, 0xFE, 0x74, 0x23, +0x2B, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xC3, 0x9E, 0x40, 0x06, 0xEF, 0x90, 0x40, +0xDA, 0x80, 0x07, 0x90, 0x8A, 0xD1, 0xE0, 0x90, 0x40, 0xF6, 0x93, 0x90, 0x8A, 0xD8, 0xF0, 0x90, +0x8A, 0xD8, 0xE0, 0x75, 0xF0, 0x06, 0xA4, 0x24, 0x50, 0xF9, 0x74, 0x40, 0x35, 0xF0, 0x75, 0x0F, +0xFF, 0xF5, 0x10, 0x89, 0x11, 0x90, 0x8A, 0xD0, 0xE0, 0x90, 0x41, 0xBA, 0x93, 0xFF, 0xD3, 0x90, +0x8A, 0xD7, 0xE0, 0x9F, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0xE4, 0xFD, 0x12, 0x5D, 0x41, 0x02, 0x71, 0xE1, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, +0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xD2, 0xCF, +0xF0, 0xA3, 0xEF, 0xF0, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x12, 0x24, 0x62, 0xFF, 0x7E, 0x00, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x97, 0xFD, 0xAC, 0xF0, 0x12, 0x24, 0x7B, 0x90, +0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, +0x01, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x02, +0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x24, 0x7B, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, +0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x7E, +0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x04, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, +0x12, 0x24, 0x7B, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, +0xA9, 0x11, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, +0x14, 0x90, 0x00, 0x06, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x24, 0x7B, 0x90, 0x8A, 0xD2, +0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x04, 0x12, +0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x08, 0x12, 0x42, +0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x24, 0x7B, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, +0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x05, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0x90, +0x8A, 0xD4, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x24, 0x7B, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, 0x9F, +0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x0C, 0xA3, 0xE0, 0x9F, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, +0xF0, 0x80, 0x07, 0xE4, 0x90, 0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, +0xF5, 0x83, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xD3, 0xED, 0x9B, +0xEC, 0x9A, 0x40, 0x05, 0x31, 0x78, 0x02, 0x71, 0xAF, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, +0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0xFF, 0xC3, +0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x71, 0xAF, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5D, 0x41, 0x02, 0x71, 0xAF, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xFC, 0x64, 0x05, 0x60, 0x03, +0x02, 0x70, 0x7D, 0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x03, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, +0x94, 0x19, 0x40, 0x3D, 0x80, 0x2E, 0xEE, 0xB4, 0x02, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, +0x11, 0x40, 0x2E, 0x80, 0x1F, 0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x01, 0x0B, 0x90, 0x8A, 0xD1, +0xE0, 0xC3, 0x94, 0x0A, 0x40, 0x1B, 0x80, 0x0C, 0xEE, 0x70, 0x11, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, +0x94, 0x03, 0x40, 0x0D, 0x90, 0x89, 0x43, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x89, 0x43, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, +0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x23, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, +0xC3, 0x94, 0x30, 0x50, 0x0B, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0x02, 0x70, 0x28, +0x90, 0x89, 0x43, 0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x70, 0x1D, 0x90, 0x8A, 0xCF, 0xE0, 0x24, +0x44, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x64, 0x0A, 0x60, 0x5B, 0x90, 0x8A, 0xCF, +0xE0, 0xFF, 0xEE, 0x24, 0x05, 0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xE0, 0xFF, 0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x50, 0x38, +0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0xEF, 0x24, 0x05, 0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x23, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, +0x50, 0x16, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, +0xFF, 0x90, 0x8A, 0xD1, 0xE0, 0x6F, 0x60, 0x56, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x23, 0xF5, 0x82, +0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFF, 0xD3, 0x94, 0x42, 0x40, 0x08, 0x90, 0x8A, 0xDD, 0x74, +0x05, 0xF0, 0x80, 0x11, 0xEF, 0xD3, 0x94, 0x39, 0x90, 0x8A, 0xDD, 0x40, 0x05, 0x74, 0x03, 0xF0, +0x80, 0x03, 0x74, 0x01, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x23, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x44, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0x80, 0x2F, 0x90, 0x8A, +0xCF, 0xE0, 0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x44, +0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x80, 0x14, 0xE4, 0x90, 0x8A, +0xDD, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0x90, 0x8A, 0xD1, 0xE0, 0xFE, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x84, 0xF5, 0x82, 0xE4, +0x34, 0x8A, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFE, 0x74, 0x43, 0x2F, 0xF5, 0x82, +0xE4, 0x34, 0x88, 0xF5, 0x83, 0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2B, 0x12, 0x43, +0x5F, 0xE0, 0xB4, 0x01, 0x11, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0xF5, 0x82, 0xE4, +0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0x21, 0xAC, 0xEC, 0x64, 0x06, +0x60, 0x02, 0x21, 0xAF, 0x90, 0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x41, 0xDB, 0x93, 0xFF, 0x7E, +0x00, 0x90, 0x8A, 0xD4, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x24, 0x7B, 0x90, 0x8A, 0xDB, 0xEE, +0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE0, 0x90, 0x8A, 0xDD, 0xF0, 0xE4, 0x90, 0x8A, 0xDA, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, +0xD3, 0x94, 0x04, 0x50, 0x47, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x75, 0xF0, 0x02, 0xEF, 0xA4, +0xF5, 0x82, 0x85, 0xF0, 0x83, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0xEF, 0x90, 0x41, 0xD6, 0x93, +0xFF, 0x7E, 0x00, 0x12, 0x24, 0x7B, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0x90, +0x8A, 0xDB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, +0xE0, 0x9E, 0x50, 0x08, 0x90, 0x8A, 0xDA, 0xE0, 0x04, 0xF0, 0x80, 0xAF, 0x90, 0x8A, 0xDA, 0xE0, +0xC3, 0x13, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFF, 0xB4, 0x01, 0x0D, 0x90, 0x8A, 0xDA, 0xE0, 0x70, +0x5D, 0x90, 0x8A, 0xDD, 0x04, 0xF0, 0x80, 0x5B, 0xEF, 0xB4, 0x03, 0x1D, 0x90, 0x8A, 0xDA, 0xE0, +0xFF, 0x70, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x03, 0xF0, 0x80, 0x48, 0xEF, 0xB4, 0x01, 0x08, 0x90, +0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x80, 0x3C, 0x80, 0x35, 0x90, 0x8A, 0xDD, 0xE0, 0x64, 0x05, 0x70, +0x32, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x05, 0xF0, 0x80, 0x0F, +0xEF, 0x90, 0x8A, 0xDD, 0xB4, 0x01, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x03, 0x74, 0x01, 0xF0, 0xD3, +0x90, 0x8A, 0xD7, 0xE0, 0x94, 0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x05, 0xE4, 0x90, +0x8A, 0xDD, 0xF0, 0xD3, 0x90, 0x8A, 0xD7, 0xE0, 0x94, 0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, +0x40, 0x05, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, +0xFF, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xED, 0xF0, 0x12, 0x69, 0x38, 0x90, +0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xD3, 0x94, +0x05, 0x50, 0x0F, 0x74, 0x64, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0x04, 0xF0, +0x80, 0x0F, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0xE4, 0xF5, 0xF0, 0x12, 0x42, 0xFA, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x90, 0x00, 0x02, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x04, 0xE4, +0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x06, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, +0x08, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xC0, +0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, +0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, +0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, +0xF0, 0x02, 0x6B, 0xC2, 0x22, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xC3, +0x94, 0x10, 0x50, 0x14, 0x74, 0xA4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE4, 0xF0, +0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x80, 0xE2, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, +0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, 0x02, 0x81, 0x0E, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x00, +0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x02, 0x12, 0x43, +0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x04, 0x12, 0x43, 0x5F, 0xE4, +0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x06, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, +0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x08, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x74, +0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x74, 0x44, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x43, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x88, +0xF5, 0x83, 0xE4, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0xE4, 0xF0, 0xA3, 0xF0, 0x74, 0x44, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, +0x74, 0x24, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x64, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x41, 0x8C, 0x93, 0xFE, 0x74, 0x01, 0x93, +0xFF, 0x90, 0x41, 0x54, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x3E, 0xC3, 0x13, 0xFE, 0xEF, +0x13, 0xFF, 0x90, 0x8A, 0xCF, 0xE0, 0xFD, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, +0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x29, 0x12, 0x43, +0x5F, 0x74, 0x01, 0xF0, 0x74, 0xC1, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0x74, 0x0C, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, +0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x23, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, +0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0x74, 0x13, 0xF0, 0x75, 0xF0, 0x09, +0xED, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, 0x34, +0x04, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x41, 0x7D, 0x22, 0x12, +0x24, 0x62, 0xFF, 0xC3, 0x94, 0x20, 0x50, 0x14, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFE, 0x74, +0x23, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xEF, 0xB4, 0x20, 0x0A, +0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0x90, 0x87, 0x21, 0xF0, 0x22, 0x90, 0x8B, 0x4B, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x8B, 0x4B, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, +0x82, 0x8E, 0x83, 0xE0, 0x60, 0x2C, 0xC3, 0x90, 0x8B, 0x4E, 0xE0, 0x94, 0xE8, 0x90, 0x8B, 0x4D, +0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x7F, 0x00, 0x22, 0x90, +0x8B, 0x4D, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x32, 0x15, +0x80, 0xC6, 0x7F, 0x01, 0x22, 0x12, 0x24, 0x62, 0xF5, 0x21, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x25, 0x14, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x01, 0x12, +0x42, 0x20, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x0A, 0xF0, +0x12, 0x47, 0xFA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x30, +0xE0, 0x25, 0x12, 0x24, 0x62, 0x90, 0x8B, 0x10, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, +0x8B, 0x11, 0xF0, 0xEF, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x8B, 0x0F, 0xF0, 0x90, 0x00, 0x03, 0x12, +0x42, 0x20, 0x90, 0x8B, 0x16, 0xF0, 0x22, 0x90, 0x8B, 0x10, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x11, +0x74, 0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, 0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0x22, +0x12, 0x24, 0x62, 0x30, 0xE0, 0x19, 0xC3, 0x13, 0x54, 0x7F, 0x90, 0x8B, 0x15, 0xF0, 0x90, 0x00, +0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8B, 0x13, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x0F, 0x90, +0x8B, 0x15, 0x74, 0x05, 0xF0, 0x90, 0x8B, 0x13, 0xE4, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, +0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x12, 0x24, 0x62, 0x90, 0x8B, 0x12, 0xF0, +0x60, 0x07, 0xE4, 0xFD, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x90, 0x8B, 0x12, 0xE0, 0x90, 0x01, 0xE7, +0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x24, 0x62, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x90, +0x8A, 0xF7, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xF8, 0xF0, +0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xF9, 0xF0, 0x90, 0x00, 0x03, +0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xFA, 0xF0, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, +0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x8A, 0xFB, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x12, 0x24, 0x62, 0xC3, +0x13, 0x20, 0xE0, 0x02, 0xC1, 0xED, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x24, 0x62, 0xFF, +0x54, 0x02, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0x54, 0xFD, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, +0xEE, 0x54, 0xFE, 0x4F, 0xFF, 0xF0, 0x12, 0x24, 0x62, 0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, +0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, +0x12, 0x24, 0x62, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF, 0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, +0xEE, 0x54, 0x40, 0xFE, 0xEF, 0x54, 0xBF, 0x4E, 0xF0, 0x20, 0xE0, 0x02, 0xC1, 0xD9, 0x90, 0x8A, +0xDD, 0x74, 0x21, 0xF0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x24, 0x62, 0xFF, 0x13, 0x13, +0x54, 0x01, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, 0x13, 0x54, 0x01, 0x6E, 0x60, 0x2A, 0xEF, +0x54, 0x04, 0xFF, 0xED, 0x54, 0xFB, 0x4F, 0xF0, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0E, +0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x12, 0x31, 0x9D, 0x80, 0x0B, 0xE4, 0x90, +0x8B, 0x34, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x31, 0x2C, 0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, 0x13, +0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x12, 0xF0, 0xED, 0xC4, 0x54, +0x0F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x14, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x8B, 0x32, +0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x40, 0xF0, +0x90, 0x8A, 0xDD, 0xE0, 0x90, 0x05, 0x27, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x70, 0x05, 0x7F, 0x01, +0x12, 0x4E, 0x89, 0x90, 0x8B, 0x32, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x04, 0x7F, +0x03, 0x80, 0x0E, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, +0x02, 0x12, 0x4E, 0x89, 0x7F, 0x02, 0x02, 0x78, 0x2E, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, +0x05, 0x27, 0xF0, 0xE4, 0xFF, 0x12, 0x4E, 0x89, 0x7F, 0x03, 0x02, 0x78, 0x2E, 0x90, 0x8A, 0xDA, +0x12, 0x43, 0x6B, 0x12, 0x24, 0x62, 0xFF, 0x54, 0x02, 0xFE, 0x90, 0x8B, 0x2C, 0xE0, 0x54, 0xFD, +0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, 0xEE, 0x54, 0xFE, 0x4F, 0xFF, 0xF0, 0x12, 0x24, 0x62, +0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, 0x90, 0x8B, 0x2C, 0xF0, 0xEE, 0x54, 0x10, +0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x24, 0x62, 0xFE, 0x54, 0x40, 0xFD, 0xEF, 0x54, +0xBF, 0x4D, 0xFF, 0x90, 0x8B, 0x2C, 0xF0, 0xEE, 0x54, 0x04, 0xFE, 0xEF, 0x54, 0xFB, 0x4E, 0xF0, +0x20, 0xE0, 0x02, 0xE1, 0xE2, 0x90, 0x8A, 0xDD, 0x74, 0x31, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x20, 0xE0, 0x0B, 0xE4, 0x90, 0x8B, 0x2E, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x31, +0x2C, 0x90, 0x8B, 0x2C, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x8A, +0xDD, 0xE0, 0x44, 0x02, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, +0x44, 0x04, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0x54, 0x06, 0x60, 0x0C, 0x90, 0x01, 0x3E, 0x74, 0x03, +0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x31, 0xB7, 0x90, 0x8A, 0xDD, 0xE0, 0x90, 0x05, 0x27, 0xF0, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x0D, 0xA3, 0xE0, 0x64, 0x06, +0x60, 0x2C, 0x7F, 0x06, 0x12, 0x65, 0x82, 0x80, 0x25, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x06, 0x1B, +0x7F, 0x01, 0x12, 0x65, 0x82, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x09, 0x7D, 0x01, 0xAF, +0x23, 0x12, 0x45, 0xA2, 0x80, 0x05, 0x12, 0x4E, 0x56, 0x80, 0x03, 0x12, 0x7D, 0xC1, 0x7F, 0x01, +0x80, 0x4C, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27, 0xF0, 0x7D, 0x03, 0x7F, 0x02, +0x12, 0x31, 0x49, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x06, 0x02, 0x80, 0x1B, 0x90, 0x8B, 0x2D, 0xE0, +0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, 0x80, 0x14, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, +0x02, 0x05, 0x7F, 0x01, 0x12, 0x65, 0x82, 0x11, 0x35, 0x12, 0x4A, 0xFC, 0x7F, 0x03, 0x11, 0x42, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x8B, 0x31, 0xE0, 0xB4, 0x01, 0x05, 0xE4, 0xF0, 0x12, 0x48, +0xFE, 0x22, 0xAD, 0x07, 0xEF, 0x64, 0x01, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x32, +0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xED, 0x64, 0x02, 0x60, 0x04, 0xED, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x2C, 0xE0, 0x54, +0xFE, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0x22, 0x12, 0x24, 0x62, 0x90, 0x8B, 0x38, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8A, 0xFD, 0xE0, 0x90, 0x8A, 0xE8, 0xF0, 0x90, 0x8A, 0xFE, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, +0x8A, 0xE9, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, +0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x8B, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xEB, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, +0x04, 0xDA, 0x90, 0x8A, 0xE8, 0xE0, 0x12, 0x43, 0x94, 0x78, 0xF8, 0x00, 0x7A, 0x6B, 0x01, 0x79, +0x01, 0x02, 0x79, 0x01, 0x03, 0x79, 0x01, 0x04, 0x7A, 0x6B, 0x05, 0x7A, 0x35, 0x80, 0x7A, 0x4E, +0x81, 0x7A, 0x6B, 0x82, 0x00, 0x00, 0x7A, 0x67, 0x90, 0x8A, 0xEE, 0xE0, 0xFF, 0x51, 0x72, 0x41, +0x6B, 0x90, 0x8A, 0xE8, 0xE0, 0xFF, 0xB4, 0x02, 0x08, 0x90, 0x8A, 0xE5, 0x74, 0x01, 0xF0, 0x80, +0x0F, 0xEF, 0x90, 0x8A, 0xE5, 0xB4, 0x03, 0x05, 0x74, 0x02, 0xF0, 0x80, 0x03, 0x74, 0x04, 0xF0, +0xC3, 0x90, 0x8A, 0xE9, 0xE0, 0x94, 0x08, 0x50, 0x78, 0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, +0xE5, 0xE0, 0xFF, 0x90, 0x8A, 0xE4, 0xE0, 0xC3, 0x9F, 0x40, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xE9, +0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0xEE, 0x94, 0x01, 0x90, 0x8A, 0xE4, 0xE0, 0x50, 0x1F, 0xFE, +0x2F, 0xFF, 0xEE, 0xFD, 0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, +0xF5, 0x82, 0x74, 0x8A, 0x3C, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x51, 0x88, 0x80, 0x2B, 0xFF, 0xFD, +0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, 0xF5, 0x82, 0x74, 0x8A, +0x3C, 0xF5, 0x83, 0xE0, 0xFE, 0xEF, 0xFD, 0x90, 0x8A, 0xEA, 0xE0, 0x2D, 0xFD, 0x90, 0x8A, 0xE9, +0xE0, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0x80, +0x8D, 0xC3, 0x90, 0x8A, 0xE9, 0xE0, 0x94, 0x10, 0x40, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xE8, 0xE0, +0x64, 0x04, 0x60, 0x02, 0x41, 0x6B, 0x90, 0x8A, 0xEC, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, +0x10, 0x12, 0x24, 0xF5, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xEB, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x18, 0x12, 0x24, 0xF5, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, +0xD0, 0x00, 0x12, 0x43, 0x46, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xED, +0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12, 0x24, 0xF5, 0xD0, 0x03, 0xD0, 0x02, 0xD0, +0x01, 0xD0, 0x00, 0x12, 0x43, 0x46, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0xA3, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x12, 0x43, 0x46, 0xA3, 0x12, 0x25, 0x08, 0x90, 0x8A, 0xEF, 0x12, +0x43, 0x53, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x90, 0x8A, 0xE9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x12, 0x2B, 0x08, 0x80, 0x36, 0x90, 0x8A, 0xED, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xE4, +0x3E, 0xFE, 0x90, 0x8A, 0xE6, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x32, 0x15, 0x80, 0x1D, 0x90, 0x8A, +0xED, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x8A, 0xE6, 0xF0, 0xA3, +0xEF, 0xF0, 0x12, 0x31, 0x82, 0x80, 0x04, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0x8F, 0x0F, 0xE4, 0x90, 0x8A, 0xF3, 0xF0, 0xE5, 0x0F, 0x14, 0xFE, 0x90, 0x8A, 0xF3, +0xE0, 0xFF, 0xC3, 0x9E, 0x50, 0x0E, 0xEF, 0x04, 0xFD, 0x12, 0x2D, 0x4D, 0x90, 0x8A, 0xF3, 0xE0, +0x04, 0xF0, 0x80, 0xE5, 0xE5, 0x0F, 0x14, 0xFF, 0x7D, 0xFF, 0x12, 0x2D, 0x4D, 0x90, 0x8A, 0xF3, +0xE5, 0x0F, 0xF0, 0x90, 0x8A, 0xF3, 0xE0, 0xC3, 0x94, 0xFF, 0x50, 0x0F, 0xE0, 0xFF, 0x04, 0xFD, +0x12, 0x2D, 0x4D, 0x90, 0x8A, 0xF3, 0xE0, 0x04, 0xF0, 0x80, 0xE8, 0xAD, 0x0F, 0x7F, 0xFF, 0x02, +0x2D, 0x4D, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0xA3, 0x74, +0x04, 0xF0, 0xA3, 0xE4, 0xF0, 0x90, 0x8A, 0xE2, 0xF0, 0xA3, 0xF0, 0x90, 0x02, 0x09, 0xE0, 0x90, +0x8A, 0xE1, 0xF0, 0x12, 0x24, 0x62, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, 0x2F, 0x90, 0x8A, 0xE0, 0xF0, +0x30, 0xE0, 0x0B, 0x90, 0x8A, 0xDB, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x80, 0x07, 0xE4, 0x90, +0x8A, 0xDB, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x90, +0x8A, 0xDD, 0xE0, 0x24, 0x20, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFC, 0x2D, +0xFF, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xFD, 0xF0, 0x74, +0x02, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0xEC, 0x2D, 0x24, 0x03, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0x90, 0x8A, 0xFE, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xDA, 0x74, 0x04, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFF, 0xA3, +0xE0, 0x2F, 0xFF, 0x90, 0x8A, 0xDA, 0xE0, 0xFE, 0x2F, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0xFF, 0x74, 0xFC, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x8A, 0xDA, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x08, 0xCF, 0x11, 0x89, 0xEF, 0x70, 0x45, 0x90, +0x01, 0xC3, 0xE0, 0x60, 0x2B, 0xC3, 0x90, 0x8A, 0xE3, 0xE0, 0x94, 0xE8, 0x90, 0x8A, 0xE2, 0xE0, +0x94, 0x03, 0x40, 0x09, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x80, 0x79, 0x90, 0x8A, 0xE2, +0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x32, 0x15, 0x80, 0xCF, +0x90, 0x01, 0xC6, 0xE0, 0x90, 0x01, 0xC3, 0x30, 0xE2, 0x05, 0x74, 0xFE, 0xF0, 0x80, 0x57, 0x74, +0xFF, 0xF0, 0x80, 0x52, 0x90, 0x8A, 0xDD, 0xE0, 0xB4, 0x78, 0x2E, 0xE4, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0x04, 0xF0, 0x90, 0x8A, 0xDB, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x80, 0x90, 0x8A, 0xDB, +0x70, 0x05, 0xF0, 0xA3, 0xF0, 0x80, 0x06, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x90, 0x8A, 0xE0, +0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x80, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x24, 0x08, 0xF0, +0x90, 0x8A, 0xDE, 0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x42, 0x81, 0x90, 0x8A, 0xDE, 0xE0, 0x70, 0x02, +0xA3, 0xE0, 0x60, 0x02, 0x61, 0x16, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x24, 0x62, 0x90, 0x8B, +0x05, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x06, 0xF0, 0x22, 0xE4, 0xF5, 0x61, +0x22, 0x91, 0x4A, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, +0x7F, 0x78, 0x7E, 0x08, 0x12, 0x22, 0x65, 0x90, 0x8B, 0x1C, 0x12, 0x25, 0x08, 0x7F, 0x04, 0x7E, +0x0C, 0x12, 0x22, 0x65, 0x90, 0x8B, 0x20, 0x12, 0x25, 0x08, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x22, +0x65, 0x90, 0x8B, 0x24, 0x12, 0x25, 0x08, 0x90, 0x8B, 0x09, 0xE0, 0x90, 0x8B, 0x1C, 0xB4, 0x01, +0x0D, 0x12, 0x43, 0x53, 0xEF, 0x54, 0xC7, 0xFF, 0xED, 0x54, 0xC7, 0xFD, 0x80, 0x07, 0x12, 0x43, +0x53, 0xEF, 0x54, 0xC7, 0xFF, 0xEC, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x7F, 0x78, 0x7E, 0x08, +0x12, 0x2B, 0x08, 0x90, 0x8B, 0x20, 0x12, 0x43, 0x53, 0xEF, 0x54, 0x0F, 0xFF, 0xEC, 0x90, 0x80, +0x96, 0x12, 0x25, 0x08, 0x7F, 0x04, 0x7E, 0x0C, 0x12, 0x2B, 0x08, 0x90, 0x8B, 0x24, 0x12, 0x43, +0x53, 0xEF, 0x44, 0x02, 0xFF, 0xEC, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x7F, 0x00, 0x7E, 0x08, +0x12, 0x2B, 0x08, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x22, 0x65, 0x90, 0x8B, 0x28, 0x12, 0x25, 0x08, +0x90, 0x80, 0x96, 0x12, 0x25, 0x14, 0x00, 0x1B, 0x25, 0xA0, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2B, +0x08, 0x90, 0x80, 0x68, 0x12, 0x25, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x30, +0x2C, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x11, 0x90, 0x80, 0x68, 0x12, 0x25, 0x14, 0x00, 0x00, +0x00, 0x00, 0xE4, 0xFD, 0x7F, 0x01, 0x12, 0x30, 0x2C, 0x90, 0x00, 0x11, 0xE0, 0x54, 0xF6, 0xF0, +0x02, 0x52, 0x0E, 0x91, 0x50, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, +0xFF, 0xF0, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0xB1, 0x42, 0x90, 0x8B, 0x33, 0x74, 0x04, +0xF0, 0x22, 0x90, 0x00, 0x11, 0xE0, 0x44, 0x09, 0xF0, 0x12, 0x52, 0x0E, 0x90, 0x8B, 0x1C, 0x12, +0x43, 0x53, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x7F, 0x78, 0x7E, 0x08, 0x12, 0x2B, 0x08, 0x90, +0x8B, 0x20, 0x12, 0x43, 0x53, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x7F, 0x04, 0x7E, 0x0C, 0x12, +0x2B, 0x08, 0x90, 0x8B, 0x24, 0x12, 0x43, 0x53, 0x90, 0x80, 0x96, 0x12, 0x25, 0x08, 0x7F, 0x00, +0x7E, 0x08, 0x12, 0x2B, 0x08, 0x90, 0x8B, 0x28, 0x12, 0x43, 0x53, 0x90, 0x80, 0x96, 0x12, 0x25, +0x08, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2B, 0x08, 0x90, 0x80, 0x68, 0x12, 0x25, 0x14, 0x00, 0x03, +0x2D, 0x95, 0xE4, 0xFD, 0xFF, 0x12, 0x30, 0x2C, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x11, 0x90, +0x80, 0x68, 0x12, 0x25, 0x14, 0x00, 0x03, 0x2D, 0x95, 0xE4, 0xFD, 0x7F, 0x01, 0x12, 0x30, 0x2C, +0x22, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x3C, 0xE5, 0x22, 0x54, 0x0F, 0x14, 0x60, 0x2E, +0x14, 0x60, 0x1E, 0x24, 0xFE, 0x60, 0x0E, 0x24, 0xF8, 0x70, 0x2A, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, +0x90, 0x05, 0x22, 0xF0, 0x22, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x22, 0xE4, 0xF0, +0x22, 0x90, 0x8B, 0x2D, 0x74, 0x03, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0x90, 0x01, +0xC6, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0xAE, 0x07, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x18, +0x90, 0x8B, 0x2C, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x0C, 0xAF, 0x06, 0x7D, 0x01, +0x12, 0x45, 0xA2, 0xB1, 0xC1, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x01, 0x57, 0xE0, 0x60, +0x3C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x1B, 0xE0, +0x60, 0x07, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0x80, 0x24, 0x90, 0x8B, 0x0C, 0xE0, 0x04, 0xF0, 0x53, +0x25, 0xEF, 0x90, 0x8B, 0x10, 0xE0, 0xFF, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, 0x40, 0x0E, 0xE5, +0x21, 0xB4, 0x01, 0x09, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x03, 0xE0, 0x04, 0xF0, 0x90, 0x01, 0x5B, +0xE0, 0x60, 0x10, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0xE4, 0x90, +0x8B, 0x18, 0xF0, 0x90, 0x01, 0x5F, 0xE0, 0x60, 0x10, 0x90, 0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, +0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x17, 0xF0, 0x22, 0xE4, 0x90, 0x8B, 0x4F, 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, 0x8B, 0x50, 0xE0, 0x94, 0xE8, 0x90, 0x8B, 0x4F, +0xE0, 0x94, 0x03, 0x40, 0x03, 0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x32, 0x15, 0x90, +0x8B, 0x4F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x80, 0xC6, 0x00, 0xFB, 0x98}; + +// =================== v88 UMC B Cut P2PPS with CCX report C2H 2012-12-05 ===================== +u8 Rtl8192CUFwUMCBCutImgArray[UMCBCutImgArrayLength] = { +0xC2, 0x88, 0x02, 0x05, 0x58, 0x00, 0x02, 0x00, 0x12, 0x05, 0x17, 0x10, 0xC0, 0x3E, 0x01, 0x00, +0x94, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x46, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x60, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x67, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x4B, 0x87, 0x00, 0x00, +0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x06, 0x05, 0x04, 0x03, 0x00, 0x04, 0x06, 0x05, 0x04, 0x02, +0x00, 0x04, 0x08, 0x07, 0x06, 0x04, 0x00, 0x06, 0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x0A, 0x09, +0x08, 0x04, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x08, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x08, +0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x18, 0x22, 0x21, 0x20, 0x18, +0x00, 0x20, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20, 0x22, 0x21, 0x20, 0x08, 0x00, 0x20, 0x22, 0x21, +0x1C, 0x08, 0x00, 0x20, 0x22, 0x21, 0x14, 0x08, 0x00, 0x20, 0x22, 0x20, 0x18, 0x08, 0x00, 0x20, +0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x31, 0x30, 0x18, 0x00, 0x00, 0x30, 0x31, 0x2F, 0x10, 0x10, +0x00, 0x30, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x30, 0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x31, 0x20, +0x10, 0x00, 0x00, 0x30, 0x31, 0x10, 0x10, 0x00, 0x00, 0x30, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, +0x05, 0x07, 0x07, 0x07, 0x08, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x06, 0x0A, 0x0B, 0x0D, 0x05, 0x05, +0x07, 0x07, 0x08, 0x0B, 0x0D, 0x0F, 0x04, 0x04, 0x04, 0x05, 0x07, 0x07, 0x09, 0x09, 0x0C, 0x0E, +0x10, 0x12, 0x06, 0x07, 0x09, 0x0A, 0x0C, 0x0E, 0x11, 0x13, 0x09, 0x09, 0x09, 0x09, 0x0C, 0x0E, +0x11, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x26, 0x2A, 0x18, 0x1A, +0x1D, 0x1F, 0x21, 0x27, 0x29, 0x2A, 0x00, 0x00, 0x00, 0x1F, 0x23, 0x28, 0x2A, 0x2C, 0x00, 0x04, +0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, +0x00, 0x90, 0x00, 0xC0, 0x00, 0xD8, 0x00, 0x50, 0x00, 0x78, 0x00, 0xA0, 0x00, 0xC8, 0x01, 0x40, +0x01, 0x90, 0x01, 0xE0, 0x02, 0x30, 0x01, 0x2C, 0x01, 0x40, 0x01, 0xE0, 0x02, 0xD0, 0x03, 0xE8, +0x04, 0xB0, 0x06, 0x40, 0x07, 0xD0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, +0x00, 0x12, 0x00, 0x18, 0x00, 0x24, 0x00, 0x30, 0x00, 0x48, 0x00, 0x60, 0x00, 0x6C, 0x00, 0x28, +0x00, 0x3C, 0x00, 0x50, 0x00, 0x64, 0x00, 0xA0, 0x00, 0xC8, 0x00, 0xF0, 0x01, 0x18, 0x00, 0x64, +0x00, 0xA0, 0x00, 0xF0, 0x01, 0x68, 0x01, 0xF4, 0x02, 0x58, 0x03, 0x20, 0x03, 0xE8, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x07, 0x02, 0x03, 0x04, 0x0A, 0x0C, 0x0E, +0x10, 0x12, 0x05, 0x07, 0x07, 0x08, 0x0B, 0x12, 0x24, 0x3C, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, +0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x20, 0x1E, 0x1C, 0x18, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBB, 0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, +0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, +0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, +0x89, 0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, +0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, +0x50, 0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, +0x22, 0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, +0x02, 0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0xF5, +0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x06, 0x87, 0xF0, 0x09, 0xE7, 0x19, 0x22, 0xBB, 0xFE, 0x07, 0xE3, +0xF5, 0xF0, 0x09, 0xE3, 0x19, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0xF5, 0xF0, 0x74, 0x01, +0x93, 0x22, 0xBB, 0x01, 0x10, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, +0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, +0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, +0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0, 0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0A, 0x89, 0x82, 0x8A, +0x83, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x06, 0xF7, 0x09, 0xA7, 0xF0, 0x19, 0x22, 0xBB, +0xFE, 0x06, 0xF3, 0xE5, 0xF0, 0x09, 0xF3, 0x19, 0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, +0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, +0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0, 0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, +0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, +0x48, 0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xA4, +0x25, 0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, +0xA3, 0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, +0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, +0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, +0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, +0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, +0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, +0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0xB5, 0xF0, 0x06, 0x74, 0x03, 0x93, 0x68, 0x60, +0xE9, 0xA3, 0xA3, 0xA3, 0xA3, 0x80, 0xD8, 0xE4, 0x90, 0x8A, 0xC5, 0xF0, 0xE5, 0x24, 0x70, 0x03, +0x02, 0x44, 0x9D, 0xE5, 0x21, 0x64, 0x01, 0x60, 0x03, 0x02, 0x44, 0x9D, 0xE5, 0x24, 0x14, 0x60, +0x29, 0x24, 0xFD, 0x60, 0x25, 0x24, 0x02, 0x24, 0xFB, 0x50, 0x02, 0x80, 0x23, 0x90, 0x8B, 0x0B, +0xE0, 0x14, 0xF0, 0xE0, 0x60, 0x04, 0xA3, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x0A, +0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, 0xF0, 0x80, 0x00, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, +0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x16, 0xA3, 0xE0, 0xB4, 0x06, 0x05, 0xE4, 0x90, 0x8A, 0xC5, +0xF0, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x70, 0x04, 0x90, 0x8A, 0xC5, 0xF0, 0x90, 0x8A, 0xC5, +0xE0, 0x60, 0x4A, 0x43, 0x25, 0x10, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0C, 0xE0, 0x75, +0xF0, 0x03, 0xA4, 0xFF, 0x90, 0x8B, 0x15, 0xE0, 0x2F, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0xE5, 0x22, 0x54, +0x0F, 0xC3, 0x94, 0x04, 0x50, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x90, 0x8B, 0x2C, +0xE0, 0x30, 0xE0, 0x09, 0x12, 0x66, 0x20, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0xE4, 0xF5, +0x25, 0xF5, 0x24, 0x75, 0x23, 0x0C, 0x75, 0x22, 0x0C, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x8B, 0x18, +0xF0, 0x90, 0x8B, 0x17, 0xF0, 0x90, 0x8B, 0x19, 0x04, 0xF0, 0x90, 0x8B, 0x0B, 0xF0, 0xE4, 0x90, +0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0D, 0xF0, 0x90, 0x8B, 0x15, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x8B, +0x0C, 0xF0, 0x90, 0x8B, 0x13, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x10, 0xF0, 0xA3, 0x74, +0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, 0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0xE4, 0x90, +0x8B, 0x0E, 0xF0, 0x90, 0x8B, 0x0A, 0xF0, 0x90, 0x8B, 0x08, 0xF0, 0x90, 0x8B, 0x12, 0xF0, 0x22, +0x7F, 0x00, 0x22, 0x02, 0x45, 0x03, 0x02, 0x45, 0x06, 0x8E, 0x64, 0x8F, 0x65, 0xAD, 0x65, 0xAC, +0x64, 0xAF, 0x63, 0x12, 0x4A, 0x5B, 0xAF, 0x65, 0xAE, 0x64, 0x90, 0x04, 0x80, 0xE0, 0x54, 0x0F, +0xFD, 0xAC, 0x07, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x01, +0xF0, 0x74, 0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xFB, 0xF0, 0xAC, +0x07, 0x74, 0x16, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0xFA, 0xF0, 0x74, +0x15, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F, 0xF0, 0xAC, 0x07, 0x74, +0x06, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F, 0xF0, 0x90, 0x04, 0x53, +0xE4, 0xF0, 0x90, 0x04, 0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0, 0x90, 0x04, 0x50, 0x74, +0xFD, 0xF0, 0x74, 0x14, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0x4D, +0xFD, 0x74, 0x14, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xED, 0xF0, 0x22, 0x7D, 0x01, +0x7F, 0x0C, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x67, 0x8D, 0x68, 0xE5, 0x67, 0x54, +0x0F, 0xFF, 0xE5, 0x22, 0x54, 0x0F, 0x6F, 0x60, 0x72, 0xE5, 0x67, 0x30, 0xE2, 0x30, 0xE5, 0x22, +0x20, 0xE2, 0x05, 0x7F, 0x01, 0x12, 0x4A, 0xB2, 0xE5, 0x22, 0x30, 0xE3, 0x10, 0xE5, 0x67, 0x20, +0xE3, 0x0B, 0x12, 0x49, 0xD5, 0xEF, 0x60, 0x53, 0x12, 0x4A, 0xCC, 0x80, 0x4E, 0xE5, 0x22, 0x20, +0xE3, 0x49, 0xE5, 0x67, 0x30, 0xE3, 0x44, 0xAF, 0x68, 0x12, 0x4A, 0x7C, 0x80, 0x3D, 0xE5, 0x22, +0x54, 0x0F, 0xFF, 0xBF, 0x0C, 0x0E, 0xE5, 0x67, 0x20, 0xE3, 0x09, 0x12, 0x49, 0xD5, 0xEF, 0x60, +0x2A, 0x12, 0x4A, 0xCC, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, 0x04, 0x0E, 0xE5, 0x67, 0x20, 0xE2, +0x09, 0x12, 0x49, 0x93, 0xEF, 0x60, 0x14, 0x12, 0x4A, 0x32, 0xE5, 0x22, 0x54, 0x0F, 0xFF, 0xBF, +0x02, 0x09, 0x12, 0x45, 0x00, 0xEF, 0x60, 0x03, 0x12, 0x4B, 0x10, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x02, 0x46, 0x6E, 0x02, 0x51, 0x39, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, +0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, +0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, +0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x4B, +0x23, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, 0xE5, 0x21, 0x64, 0x01, 0x70, 0x67, 0xE5, 0x24, 0x60, 0x63, 0xE5, 0x24, 0x64, +0x02, 0x60, 0x06, 0xE5, 0x24, 0x64, 0x05, 0x70, 0x27, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x8B, 0x19, 0xF0, 0x90, 0x8B, 0x0B, 0xE0, 0x70, 0x07, 0x90, +0x8B, 0x19, 0xE0, 0xFF, 0x80, 0x05, 0x90, 0x8B, 0x0B, 0xE0, 0xFF, 0x90, 0x8B, 0x0B, 0xEF, 0xF0, +0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x02, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x0C, 0xF0, 0x90, 0x05, 0x58, +0x74, 0x03, 0xF0, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x53, 0x25, +0xFD, 0x53, 0x25, 0xEF, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x03, 0x12, 0x47, 0x8E, +0x22, 0xEF, 0x64, 0x01, 0x70, 0x35, 0x7D, 0x78, 0x7F, 0x02, 0x12, 0x36, 0x75, 0x7D, 0x02, 0x7F, +0x03, 0x12, 0x36, 0x75, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x12, +0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0x66, 0x20, 0x90, 0x06, 0x04, 0xE0, +0x54, 0x7F, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22, 0x90, 0x01, 0x36, 0x74, 0x7B, +0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x7D, 0x7B, 0xFF, 0x12, 0x36, 0xE6, 0x7D, 0x02, 0x7F, 0x03, 0x12, +0x36, 0xE6, 0x90, 0x06, 0x04, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x44, 0x07, 0xF0, +0x12, 0x4B, 0x4F, 0xE5, 0x21, 0x20, 0xE0, 0x05, 0xE4, 0x90, 0x8B, 0x0D, 0xF0, 0x22, 0xE4, 0x90, +0x8A, 0xC5, 0xF0, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x8A, 0xC5, 0xF0, 0xE0, 0x54, 0xC0, 0x70, 0x09, +0x53, 0x25, 0xFE, 0x53, 0x25, 0xFD, 0x12, 0x4A, 0xFC, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE6, 0x15, +0x43, 0x25, 0x01, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, 0x4A, 0x97, 0x80, 0x08, +0x12, 0x49, 0x49, 0x80, 0x03, 0x53, 0x25, 0xFE, 0x90, 0x8A, 0xC5, 0xE0, 0x30, 0xE7, 0x27, 0x43, +0x25, 0x02, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, +0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, 0x74, 0x05, 0xF0, 0x90, +0x8B, 0x1B, 0x74, 0x01, 0xF0, 0x22, 0x53, 0x25, 0xFD, 0x22, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x8B, +0x12, 0x4B, 0x43, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xF5, 0x24, 0x14, 0x60, +0x0E, 0x14, 0x60, 0x1F, 0x14, 0x60, 0x31, 0x24, 0x03, 0x70, 0x44, 0x7F, 0x01, 0x80, 0x3D, 0x90, +0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, 0xE4, 0xFF, 0x12, 0x4A, +0x07, 0x80, 0x29, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFD, +0x7F, 0x01, 0x12, 0x4A, 0x07, 0x1F, 0x80, 0x14, 0x90, 0x8A, 0xDE, 0x12, 0x43, 0x6B, 0x90, 0x00, +0x02, 0x12, 0x42, 0x20, 0xFD, 0x7F, 0x02, 0x12, 0x4A, 0x07, 0xE4, 0xFF, 0x12, 0x47, 0x21, 0x22, +0xE4, 0x90, 0x8A, 0xCB, 0xF0, 0xE5, 0x24, 0x60, 0x49, 0x90, 0x8B, 0x1B, 0xE0, 0x60, 0x0D, 0xE4, +0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x38, 0x80, 0x33, 0x90, 0x8B, 0x0C, 0xE0, +0x04, 0xF0, 0x53, 0x25, 0xEF, 0x90, 0x8A, 0xCB, 0xE0, 0xFF, 0x90, 0x8B, 0x10, 0xE0, 0x2F, 0xFF, +0xE4, 0x33, 0xFE, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, 0xEE, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, +0x40, 0x0D, 0xE5, 0x21, 0xB4, 0x01, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xE0, 0x04, 0xF0, 0x22, 0x12, +0x4A, 0xFC, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8F, 0x63, 0x90, 0x04, 0x1D, 0xE0, +0x60, 0x24, 0x90, 0x05, 0x22, 0xE0, 0xF5, 0x66, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x2D, 0xBF, 0x01, +0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xDE, 0x12, 0x45, 0x09, 0x90, 0x05, +0x22, 0xE5, 0x66, 0xF0, 0x80, 0x0D, 0x90, 0x8A, 0xF9, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xDE, +0x12, 0x45, 0x09, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE5, 0x24, +0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x41, 0x90, 0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x12, 0x45, 0x9E, +0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x58, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, +0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x22, 0xE5, 0x22, 0x54, 0x0F, 0xC3, 0x94, 0x04, 0x50, +0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x45, 0xA2, 0x22, 0x90, 0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, +0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, +0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, +0xF0, 0x90, 0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x17, 0x14, 0xF0, 0xE5, 0x22, 0x54, 0x0F, +0xC3, 0x94, 0x0C, 0x50, 0x0D, 0x12, 0x45, 0x9E, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x03, 0x12, +0x66, 0x20, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x37, 0xE5, 0x25, 0x54, 0x03, 0x70, +0x31, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x02, 0x50, 0x28, 0xE5, 0x25, 0x20, 0xE2, 0x23, 0xE5, +0x25, 0x20, 0xE4, 0x1E, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x18, 0x90, 0x8B, 0x12, 0xE0, 0x70, 0x12, +0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x7F, +0x01, 0x22, 0x7F, 0x00, 0x22, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x27, 0x90, 0x8B, 0x18, +0xE0, 0x70, 0x21, 0x90, 0x8B, 0x17, 0xE0, 0x70, 0x1B, 0xE5, 0x23, 0x54, 0x0F, 0xD3, 0x94, 0x04, +0x50, 0x12, 0xE5, 0x26, 0x70, 0x0E, 0x90, 0x01, 0xB9, 0xE4, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x08, +0xF0, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xEF, 0x24, 0xFE, 0x60, 0x0B, 0x04, 0x70, 0x22, 0x90, +0x8B, 0x19, 0x74, 0x01, 0xF0, 0x80, 0x16, 0xED, 0x70, 0x0A, 0x90, 0x8B, 0x16, 0xE0, 0x90, 0x8B, +0x19, 0xF0, 0x80, 0x05, 0x90, 0x8B, 0x19, 0xED, 0xF0, 0x90, 0x8B, 0x19, 0xE0, 0x90, 0x8B, 0x0B, +0xF0, 0x22, 0x90, 0x01, 0x37, 0x74, 0x02, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, +0x2D, 0xEF, 0x70, 0x06, 0x90, 0x01, 0xC8, 0x74, 0xFD, 0xF0, 0x7D, 0x02, 0x7F, 0x03, 0x12, 0x36, +0xE6, 0x12, 0x7A, 0x6D, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x02, 0x22, 0xEF, 0x60, 0x0F, 0x74, 0x21, +0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x74, 0x21, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x54, 0xBF, 0xF0, 0xEF, 0x60, 0x0A, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0xE4, 0xFF, 0x12, 0x48, 0xB3, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x0C, 0x22, 0x90, 0x04, 0x1D, 0xE0, 0x70, 0x14, 0x90, 0x8A, 0xF8, +0xE0, 0xFF, 0xE4, 0xFD, 0x12, 0x5F, 0xDE, 0x8E, 0x69, 0x8F, 0x6A, 0x90, 0x04, 0x1F, 0x74, 0x20, +0xF0, 0x22, 0x90, 0x8B, 0x52, 0xEF, 0xF0, 0x12, 0x4F, 0xED, 0x90, 0x8B, 0x52, 0xE0, 0x60, 0x05, +0x90, 0x05, 0x22, 0xE4, 0xF0, 0x53, 0x22, 0xF0, 0x43, 0x22, 0x04, 0x22, 0x90, 0x06, 0x04, 0xE0, +0x44, 0x40, 0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x05, 0x7F, 0x01, 0x12, 0x48, 0xB3, 0x53, 0x22, 0xF0, +0x43, 0x22, 0x04, 0x22, 0xE5, 0x23, 0x30, 0xE6, 0x12, 0xE5, 0x23, 0x54, 0x0F, 0xFF, 0x90, 0x01, +0x2F, 0xE0, 0x54, 0x80, 0x4F, 0x64, 0x80, 0xF0, 0x53, 0x23, 0xBF, 0x22, 0x90, 0x8B, 0x2C, 0xE0, +0x30, 0xE0, 0x05, 0xAF, 0x23, 0x02, 0x66, 0x65, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x22, +0x53, 0x22, 0xF0, 0x43, 0x22, 0x01, 0x12, 0x4B, 0x5A, 0x12, 0x4B, 0x5B, 0x53, 0x22, 0xF0, 0x43, +0x22, 0x02, 0x22, 0x41, 0x8A, 0xF6, 0x00, 0x41, 0x8B, 0x05, 0x00, 0x41, 0x8B, 0x51, 0x00, 0x41, +0x8B, 0x53, 0x00, 0x00, 0x90, 0x04, 0x1B, 0xE0, 0x54, 0x7F, 0x64, 0x7F, 0x7F, 0x01, 0x60, 0x02, +0x7F, 0x00, 0x22, 0xE4, 0x90, 0x8B, 0x1B, 0xF0, 0x90, 0x8B, 0x0C, 0xF0, 0xF5, 0x25, 0x22, 0x90, +0x8B, 0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x22, 0x22, 0xF0, 0x90, 0x8B, 0x0F, +0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x3D, 0xE0, 0xFB, 0xA3, 0xE0, 0xF5, 0x44, 0xE4, 0xF5, 0x45, 0x12, +0x35, 0xAB, 0xD0, 0xD0, 0x92, 0xAF, 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, 0x75, 0x0E, 0x00, 0x90, 0x01, 0xC4, 0x74, 0x87, 0xF0, 0x74, 0x4B, 0xA3, +0xF0, 0x53, 0x91, 0xDF, 0x90, 0x01, 0x3C, 0xE0, 0x55, 0x30, 0xF5, 0x34, 0xA3, 0xE0, 0x55, 0x31, +0xF5, 0x35, 0xA3, 0xE0, 0x55, 0x32, 0xF5, 0x36, 0xA3, 0xE0, 0x55, 0x33, 0xF5, 0x37, 0xE5, 0x34, +0x30, 0xE0, 0x51, 0x90, 0x01, 0x3C, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x1F, +0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x34, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, +0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x1D, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x16, 0x90, 0x8B, +0x2E, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, +0x70, 0x02, 0xD1, 0x56, 0xE5, 0x34, 0x30, 0xE1, 0x08, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x11, +0x60, 0xE5, 0x34, 0x30, 0xE2, 0x28, 0x90, 0x01, 0x3C, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x92, 0xE0, +0x30, 0xE0, 0x14, 0x90, 0x8B, 0x3D, 0xE4, 0x71, 0x5C, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, +0x06, 0x92, 0x74, 0x01, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x18, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, +0x30, 0xE3, 0x38, 0x90, 0x01, 0x3C, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x24, +0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x0F, 0xE0, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, +0x7F, 0x5C, 0x7E, 0x01, 0x71, 0x6C, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, +0x02, 0xF0, 0x80, 0x07, 0x90, 0x8B, 0x17, 0xE4, 0xF0, 0x51, 0xFC, 0xE5, 0x34, 0x30, 0xE4, 0x09, +0x90, 0x01, 0x3C, 0x74, 0x10, 0xF0, 0x12, 0x52, 0x3C, 0xE5, 0x34, 0x30, 0xE5, 0x06, 0x90, 0x01, +0x3C, 0x74, 0x20, 0xF0, 0xE5, 0x35, 0x30, 0xE0, 0x10, 0x90, 0x01, 0x3D, 0x74, 0x01, 0xF0, 0x90, +0x00, 0x83, 0xE0, 0xF5, 0x23, 0x51, 0xE4, 0x51, 0xFC, 0xE5, 0x35, 0x30, 0xE2, 0x06, 0x90, 0x01, +0x3D, 0x74, 0x04, 0xF0, 0xE5, 0x35, 0x30, 0xE4, 0x1B, 0x90, 0x01, 0x3D, 0x74, 0x10, 0xF0, 0x90, +0x8B, 0x05, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x05, +0xFD, 0xE0, 0x04, 0xF0, 0xE5, 0x36, 0x30, 0xE0, 0x75, 0x90, 0x01, 0x3E, 0x74, 0x01, 0xF0, 0x90, +0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x8B, 0x36, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, +0x03, 0x60, 0x0B, 0x7F, 0x01, 0xB1, 0xE0, 0xEF, 0x60, 0x04, 0x7F, 0x01, 0xD1, 0x89, 0x90, 0x8B, +0x2C, 0xE0, 0x30, 0xE0, 0x49, 0x90, 0x8B, 0x30, 0xE4, 0xF0, 0xFF, 0xB1, 0xE0, 0xEF, 0x60, 0x3E, +0x12, 0x65, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, 0x32, 0xEF, 0xB4, 0x04, 0x02, +0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, 0x80, 0x14, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x05, 0x7F, +0x01, 0x12, 0x7B, 0x49, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x12, 0x66, 0x20, 0xE5, 0x36, +0x30, 0xE1, 0x47, 0x90, 0x01, 0x3E, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, 0xE0, 0x19, +0x90, 0x8B, 0x36, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x33, 0xE0, 0x64, 0x03, 0x60, 0x0B, 0x7F, 0x01, +0xB1, 0xE0, 0xEF, 0x70, 0x04, 0x7F, 0x02, 0xD1, 0x89, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x1A, +0x90, 0x8B, 0x30, 0x74, 0x01, 0xF0, 0x12, 0x7D, 0xBE, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, +0x09, 0xE4, 0xFF, 0xB1, 0xE0, 0xEF, 0x70, 0x02, 0xD1, 0x56, 0x74, 0x87, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0x74, 0x4B, 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, +0xEF, 0x64, 0x01, 0x70, 0x3D, 0x90, 0x8B, 0x35, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, +0x08, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x34, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, +0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x54, +0x07, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x36, 0xE0, 0x7F, 0x01, 0x60, 0x36, 0x7F, +0x00, 0x22, 0x90, 0x8B, 0x2F, 0xE0, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x08, 0xE0, 0x60, +0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2E, 0xE0, 0x60, 0x03, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x2C, +0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x30, 0xE0, 0x7F, +0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x0D, 0xE0, 0x60, 0x16, 0x90, 0x8B, 0x2D, 0xE0, +0x70, 0x04, 0x7F, 0x05, 0x80, 0x1F, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x01, 0x70, 0x1A, 0x7F, 0x02, +0x80, 0x13, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x03, 0x80, 0x08, 0x90, 0x8B, 0x2D, +0xE0, 0x70, 0x05, 0x7F, 0x04, 0x12, 0x7B, 0x49, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8B, 0x33, 0xE0, 0x90, 0x8B, 0x55, 0xF0, 0x6F, 0x70, 0x02, 0xE1, 0x55, 0xEF, 0x14, 0x60, +0x3B, 0x14, 0x60, 0x5F, 0x14, 0x70, 0x02, 0xE1, 0x30, 0x24, 0x03, 0x60, 0x02, 0xE1, 0x55, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x04, 0xF1, 0xC0, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x02, +0x04, 0xF1, 0xAD, 0xE1, 0x55, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, 0x04, 0xF1, 0xC4, 0xE1, 0x55, +0x90, 0x8B, 0x55, 0xE0, 0x64, 0x01, 0x70, 0x7D, 0xF1, 0xAF, 0x80, 0x79, 0x90, 0x8B, 0x55, 0xE0, +0xFF, 0xB4, 0x03, 0x04, 0xF1, 0xC8, 0x80, 0x6D, 0xEF, 0xB4, 0x02, 0x04, 0xF1, 0xA0, 0x80, 0x65, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0xD3, 0x80, 0x59, 0xEF, 0x70, 0x56, 0xF1, +0x8D, 0x80, 0x52, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x03, 0x05, 0x12, 0x7A, 0x5E, 0x80, 0x46, 0x90, +0x8B, 0x55, 0xE0, 0xB4, 0x01, 0x04, 0xF1, 0x71, 0x80, 0x3B, 0x90, 0x8B, 0x55, 0xE0, 0xB4, 0x04, +0x05, 0x12, 0x7B, 0x37, 0x80, 0x2F, 0x90, 0x8B, 0x55, 0xE0, 0x70, 0x29, 0xF1, 0x6F, 0x80, 0x25, +0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x01, 0x04, 0xF1, 0x5A, 0x80, 0x19, 0xEF, 0xB4, 0x02, 0x04, +0xF1, 0x6B, 0x80, 0x11, 0x90, 0x8B, 0x55, 0xE0, 0xFF, 0xB4, 0x04, 0x04, 0xF1, 0x5A, 0x80, 0x05, +0xEF, 0x70, 0x02, 0xF1, 0x67, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, +0x90, 0x8B, 0x33, 0x74, 0x03, 0xF0, 0x22, 0xF1, 0x8D, 0x80, 0xEF, 0xF1, 0xED, 0x80, 0xEB, 0xF1, +0x8D, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, 0x7E, 0x2D, 0xEF, 0x70, 0x06, 0x90, 0x01, 0xC8, +0x74, 0xFD, 0xF0, 0x12, 0x7A, 0x6D, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x01, 0x3E, +0x74, 0x03, 0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x37, 0x00, 0x90, 0x8B, 0x33, 0x74, 0x01, 0xF0, 0x22, +0xF1, 0xED, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, 0xF1, 0xA0, 0x7D, +0x03, 0x7F, 0x02, 0x12, 0x36, 0x92, 0x90, 0x05, 0x27, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0xF0, 0x22, +0xF1, 0xC8, 0x80, 0xEB, 0xF1, 0xD3, 0x80, 0xE7, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, +0x04, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x33, 0x04, 0xF0, 0x22, 0xF1, 0x8D, +0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0x90, 0x8B, 0x1C, +0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x78, 0x7E, 0x08, 0x12, 0x2F, 0xD9, +0x90, 0x8B, 0x20, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x04, 0x7E, 0x0C, +0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x24, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, +0x00, 0x7E, 0x08, 0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x28, 0x12, 0x43, 0x53, 0x90, 0x80, 0x85, 0x12, +0x2A, 0x7F, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2F, 0xD9, 0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, +0x03, 0x2D, 0x95, 0xE4, 0xFD, 0xFF, 0x12, 0x34, 0x81, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x11, +0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x03, 0x2D, 0x95, 0xE4, 0xFD, 0x7F, 0x01, 0x12, 0x34, +0x81, 0x22, 0x90, 0x02, 0x84, 0xEF, 0xF0, 0xA3, 0xEE, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0xEF, +0x8E, 0xF0, 0x12, 0x43, 0xBA, 0x50, 0x8D, 0x00, 0x40, 0x50, 0xB5, 0x00, 0x80, 0x50, 0xE0, 0x01, +0x00, 0x50, 0xF4, 0x02, 0x00, 0x51, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x51, 0x29, 0xED, 0x54, 0x3F, +0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x40, 0xEF, 0x2D, 0xFF, 0xEE, 0x3C, 0xFE, +0xEF, 0x78, 0x06, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x78, 0x06, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0x80, 0x26, 0xED, 0x54, 0x7F, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x00, +0x7F, 0x80, 0xEF, 0x2D, 0xFF, 0xEE, 0x3C, 0xFE, 0xEF, 0x78, 0x07, 0xCE, 0xC3, 0x13, 0xCE, 0x13, +0xD8, 0xF9, 0x78, 0x07, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFD, 0xAC, 0x06, 0x80, 0x49, +0xED, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x01, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x7D, +0x00, 0xFC, 0x80, 0x35, 0xEC, 0x54, 0x01, 0x4D, 0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x02, +0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0xC3, 0x13, 0x7D, 0x00, 0x80, 0x1A, 0xEC, 0x54, 0x03, 0x4D, +0x70, 0x04, 0xFE, 0xFF, 0x80, 0x04, 0x7E, 0x04, 0x7F, 0x00, 0xEF, 0x2D, 0xEE, 0x3C, 0x13, 0x13, +0x54, 0x3F, 0x7D, 0x00, 0x25, 0xE0, 0x25, 0xE0, 0xFC, 0xAE, 0x04, 0xAF, 0x05, 0x22, 0x90, 0x01, +0xE4, 0x74, 0x58, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x22, 0xE4, 0x90, 0x8A, 0xCC, 0xF0, 0xA3, 0xF0, +0x75, 0x8E, 0x02, 0x91, 0x81, 0x12, 0x67, 0x0E, 0x90, 0x8B, 0x07, 0xEF, 0xF0, 0x12, 0x67, 0x1B, +0x90, 0x8B, 0x09, 0xEF, 0xF0, 0x12, 0x67, 0x27, 0x90, 0x8A, 0xF4, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, +0xE4, 0xF5, 0x55, 0xF5, 0x21, 0x12, 0x71, 0x16, 0x12, 0x44, 0x9E, 0x12, 0x32, 0x3D, 0x7F, 0x03, +0x12, 0x76, 0xAB, 0x12, 0x7A, 0x5A, 0x12, 0x66, 0xD4, 0x12, 0x67, 0x3F, 0x12, 0x67, 0x54, 0x12, +0x66, 0xF2, 0x12, 0x67, 0x0D, 0x90, 0x8A, 0xCE, 0xE5, 0xD9, 0xF0, 0x31, 0xD2, 0xC2, 0xAF, 0x90, +0x00, 0x80, 0xE0, 0x44, 0x40, 0xF0, 0x51, 0x81, 0x75, 0xE8, 0x03, 0x43, 0xA8, 0x85, 0xD2, 0xAF, +0x31, 0x2E, 0x90, 0x8A, 0xCC, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0x39, 0x90, 0x01, 0xC4, 0xF0, 0x74, +0x51, 0xA3, 0xF0, 0xE5, 0x55, 0x30, 0xE4, 0x09, 0xC2, 0xAF, 0x53, 0x55, 0xEF, 0xD2, 0xAF, 0xB1, +0xCC, 0xE5, 0x55, 0x30, 0xE6, 0xDC, 0xC2, 0xAF, 0x53, 0x55, 0xBF, 0xD2, 0xAF, 0x12, 0x68, 0x42, +0x80, 0xD0, 0x90, 0x01, 0x3C, 0x74, 0xFF, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xF0, +0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD, 0x7F, 0x54, 0x31, 0xFB, 0x7D, 0xFF, 0x7F, 0x55, 0x31, +0xFB, 0x7D, 0xFF, 0x7F, 0x56, 0x31, 0xFB, 0x7D, 0xFF, 0x7F, 0x57, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x8F, 0x82, 0x75, 0x83, 0x00, 0xED, 0xF0, 0x51, 0x81, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x90, 0x01, 0x30, 0xE4, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x38, 0xF0, 0xA3, +0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD, 0x7F, 0x50, 0x31, 0xFB, 0xE4, 0xFD, 0x7F, 0x51, 0x31, 0xFB, +0xE4, 0xFD, 0x7F, 0x52, 0x31, 0xFB, 0xE4, 0xFD, 0x7F, 0x53, 0x80, 0xBF, 0xE5, 0x5E, 0x64, 0x01, +0x70, 0x3B, 0x71, 0xC1, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x71, 0xB5, 0x90, 0x00, 0x46, 0xE0, 0x44, +0x04, 0xFD, 0x7F, 0x46, 0x31, 0xFB, 0x90, 0x00, 0x44, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x44, 0x31, +0xFB, 0x90, 0x00, 0x46, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x46, 0x31, 0xFB, 0x7F, 0x02, 0x71, 0xDD, +0x8F, 0x62, 0x90, 0x01, 0xC9, 0xE5, 0x62, 0xF0, 0xB4, 0x01, 0x02, 0x71, 0x55, 0x22, 0xE0, 0x5F, +0xF0, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x10, 0xDF, 0xFE, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xE0, 0xED, 0xF0, 0x90, 0x8A, 0xDF, +0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x4E, 0xA3, 0xE0, 0x70, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, +0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, +0xE0, 0x5F, 0xF0, 0x80, 0x17, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, +0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x47, 0xE0, 0x4F, 0xF0, 0x51, 0x81, 0x90, 0x8A, +0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, +0x90, 0x00, 0x46, 0x80, 0x59, 0x90, 0x8A, 0xDF, 0xE0, 0x24, 0xF8, 0xF0, 0xA3, 0xE0, 0x70, 0x1D, +0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, +0xC4, 0x54, 0xF0, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x80, 0x1A, 0x90, 0x8A, 0xDF, +0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xC4, 0x54, 0xF0, +0xFF, 0x90, 0x00, 0x43, 0xE0, 0x4F, 0xF0, 0x51, 0x81, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0x01, +0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0x51, 0x7E, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x49, 0xE0, 0x90, 0x8B, 0x54, 0xF0, 0xE0, 0x54, 0x0F, +0xF0, 0x44, 0xF0, 0xFD, 0x7F, 0x49, 0x31, 0xFB, 0x90, 0x8B, 0x54, 0xE0, 0x44, 0xB0, 0xFD, 0x7F, +0x49, 0x21, 0xFB, 0x90, 0x8A, 0xDD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0x5E, 0x01, 0x8E, 0x5F, +0xF5, 0x60, 0xE4, 0xFD, 0x7F, 0x0B, 0x51, 0x91, 0xE4, 0xFD, 0x7F, 0x02, 0x51, 0x91, 0x71, 0xC1, +0xE4, 0xFF, 0x71, 0xB5, 0xE4, 0xF5, 0x62, 0x90, 0x01, 0xC9, 0xE5, 0x62, 0xF0, 0x90, 0x8A, 0xDD, +0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFB, 0x8D, 0x44, 0xE4, 0xF5, 0x45, 0x7D, 0x01, 0x7F, 0x60, +0x7E, 0x01, 0x02, 0x35, 0xAB, 0x90, 0x01, 0xCA, 0xE5, 0x61, 0xF0, 0xEF, 0x60, 0x02, 0x71, 0x55, +0x22, 0x7F, 0x0B, 0x71, 0xDD, 0xEF, 0x65, 0x61, 0x60, 0x10, 0xE5, 0x61, 0xB4, 0x01, 0x05, 0xE4, +0xF5, 0x61, 0x80, 0x03, 0x75, 0x61, 0x01, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x57, 0xEF, 0xF0, 0xD3, 0x94, 0x07, 0x50, 0x43, 0xE0, 0xFF, +0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x46, +0x51, 0x7E, 0x90, 0x8B, 0x57, 0xE0, 0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, +0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x00, 0x44, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, +0x5B, 0xA8, 0x05, 0x08, 0x80, 0x06, 0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0x80, +0x4B, 0x90, 0x8B, 0x57, 0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, +0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43, 0xE0, 0x5F, 0xF0, 0x51, 0x81, 0x90, +0x8B, 0x57, 0xE0, 0xFD, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x05, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0xFB, 0xE4, 0xFE, 0xEF, 0x5B, 0xA8, 0x05, +0x08, 0x80, 0x06, 0xCE, 0xA2, 0xE7, 0x13, 0xCE, 0x13, 0xD8, 0xF8, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xE4, 0x90, 0x8B, 0x04, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x21, +0xFB, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0x90, 0x8A, +0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFA, 0xE5, 0xF0, 0x24, 0x00, 0xFF, +0xE4, 0x3A, 0xFE, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEE, 0x8F, 0xF0, 0x12, +0x43, 0x19, 0x12, 0x29, 0xD9, 0xFF, 0x60, 0x2C, 0xB5, 0x5E, 0x16, 0x90, 0x8A, 0xDA, 0x12, 0x43, +0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0x65, 0x60, 0x70, 0x04, 0xE5, 0x5F, 0x65, 0xF0, 0x60, +0x22, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0xC2, 0xFF, 0xAE, 0xF0, +0x71, 0x73, 0x80, 0x0F, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0x65, 0x5E, 0x60, +0x02, 0xB1, 0x08, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xF5, 0x5E, 0x7F, 0x60, 0x7E, 0x01, 0x8F, +0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x8B, 0xEF, +0x12, 0x43, 0x94, 0x55, 0x5A, 0x01, 0x55, 0x51, 0x02, 0x55, 0x7E, 0x03, 0x55, 0x87, 0x05, 0x55, +0x90, 0x06, 0x55, 0xCB, 0x07, 0x55, 0x98, 0x08, 0x55, 0xA1, 0x09, 0x55, 0xA9, 0x20, 0x55, 0xB2, +0x2C, 0x55, 0x63, 0x2D, 0x55, 0x6C, 0x2E, 0x55, 0x75, 0x3B, 0x55, 0xBB, 0x4B, 0x00, 0x00, 0x55, +0xC4, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x72, 0xFC, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, +0x02, 0x73, 0x02, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x73, 0x2F, 0x90, 0x8A, 0xD7, 0x12, +0x43, 0x6B, 0x02, 0x73, 0x77, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x73, 0xB0, 0x90, 0x8A, +0xD7, 0x12, 0x43, 0x6B, 0x02, 0x73, 0xC9, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x72, 0xD0, +0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0xE1, 0x19, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x74, +0x11, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x81, 0x91, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, +0x76, 0xEA, 0x90, 0x8A, 0xD7, 0x12, 0x43, 0x6B, 0x02, 0x78, 0xDE, 0x90, 0x8A, 0xD7, 0x12, 0x43, +0x6B, 0x02, 0x7A, 0x48, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, +0xE0, 0xFD, 0x70, 0x02, 0xE1, 0x14, 0x90, 0x8B, 0x51, 0xE0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, +0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, +0xE1, 0x0D, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD0, 0x12, 0x43, 0x5F, 0xE0, +0x90, 0x8A, 0xD0, 0xF0, 0x75, 0x1D, 0x01, 0x75, 0x1E, 0x8A, 0x75, 0x1F, 0xD0, 0x75, 0x20, 0x01, +0x7B, 0x01, 0x7A, 0x8A, 0x79, 0xD1, 0x12, 0x5F, 0x57, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0xC4, 0x13, +0x13, 0x13, 0x54, 0x01, 0x90, 0x8B, 0x51, 0x30, 0xE0, 0x59, 0xE0, 0x75, 0xF0, 0x02, 0x90, 0x00, +0x88, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD2, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x02, +0x90, 0x00, 0x89, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD3, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, +0xF0, 0x04, 0x90, 0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD4, 0xF0, 0x90, 0x8B, 0x51, +0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD5, 0xF0, 0x90, +0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD6, +0xF0, 0x80, 0x33, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD1, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, +0xD2, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD2, 0x12, 0x43, 0x5F, 0xE0, +0x90, 0x8A, 0xD3, 0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD3, 0x12, 0x43, +0x5F, 0xE0, 0x90, 0x8A, 0xD4, 0xF0, 0xEF, 0x54, 0x7F, 0xFF, 0x7B, 0x01, 0x7A, 0x8A, 0x79, 0xD2, +0xB1, 0x19, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x90, 0x8B, 0x51, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, +0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8B, 0x51, +0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, +0xF0, 0x90, 0x8B, 0x51, 0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0xA1, 0xDD, 0x90, 0x01, 0xC6, +0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, 0xFF, +0x54, 0x1F, 0xFE, 0xEF, 0x54, 0x20, 0xC4, 0x13, 0x54, 0x07, 0xFD, 0xAF, 0x06, 0x90, 0x8A, 0xDA, +0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, +0x00, 0x03, 0x12, 0x42, 0x20, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x00, +0x04, 0x12, 0x42, 0x20, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x8A, 0xE0, 0xF0, 0x90, +0x8A, 0xDA, 0xE0, 0xFF, 0x75, 0xF0, 0x09, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0xAD, 0x82, 0xAC, +0x83, 0x90, 0x8A, 0xE1, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0x23, +0xF9, 0x74, 0x87, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xA3, 0x12, 0x43, 0x8B, 0x90, 0x8A, 0xDC, 0x12, +0x43, 0x6B, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0x54, 0x0F, 0xFF, 0x90, 0x8A, 0xE3, 0x12, 0x43, +0x6B, 0xEF, 0x12, 0x42, 0x4D, 0x90, 0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x02, 0x12, 0x42, +0x20, 0xFF, 0x90, 0x8A, 0xE3, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x90, +0x8A, 0xDC, 0x12, 0x43, 0x6B, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, +0xFC, 0xA3, 0xE0, 0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xEF, 0xF0, 0x12, 0x29, 0xD9, 0x8D, 0x82, 0x8C, +0x83, 0xA3, 0xF0, 0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x24, 0xC1, 0xF5, +0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xDB, 0xE0, 0xFE, 0x75, 0xF0, 0x09, +0xEF, 0x90, 0x87, 0x29, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, +0x12, 0x43, 0x5F, 0x74, 0x01, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFE, 0x75, 0xF0, 0x09, 0xEF, 0x90, +0x87, 0x2B, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0x8F, 0x0F, 0xEF, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, +0xE4, 0x34, 0x89, 0xAF, 0x82, 0xF5, 0x10, 0x8F, 0x11, 0xE5, 0x0F, 0x75, 0xF0, 0x02, 0xA4, 0x24, +0x81, 0xF9, 0x74, 0x86, 0x35, 0xF0, 0x75, 0x12, 0x01, 0xF5, 0x13, 0x89, 0x14, 0x75, 0xF0, 0x09, +0xE5, 0x0F, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0xAF, 0x82, 0x85, 0x83, 0x15, 0x8F, 0x16, 0xE5, +0x0F, 0x75, 0xF0, 0x09, 0xA4, 0x24, 0x23, 0xF9, 0x74, 0x87, 0x35, 0xF0, 0x75, 0x17, 0x01, 0xF5, +0x18, 0x89, 0x19, 0x74, 0xC1, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x12, +0x43, 0x94, 0x58, 0xA7, 0x00, 0x58, 0xBC, 0x01, 0x58, 0xD1, 0x02, 0x58, 0xE6, 0x03, 0x59, 0x0F, +0x04, 0x59, 0x24, 0x05, 0x59, 0x39, 0x06, 0x59, 0x5F, 0x0C, 0x59, 0x8C, 0x0D, 0x59, 0xB9, 0x0E, +0x59, 0xE6, 0x0F, 0x00, 0x00, 0x5A, 0x1A, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, +0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x15, 0x80, 0x3C, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0x74, 0x10, 0x80, +0x27, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0xF0, +0xF0, 0xA3, 0x74, 0x05, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0x74, 0xF0, 0xF0, 0xA3, 0xE4, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, +0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0x8F, 0xF0, 0x41, 0x1A, 0xE5, +0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0x74, 0x0F, 0xF0, 0xA3, +0x74, 0xF5, 0x80, 0x27, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0x74, 0x0F, 0xF0, 0xA3, 0x74, 0xF0, 0x80, 0x12, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, +0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0x74, 0x0D, 0xF0, 0xE5, 0x0F, 0x25, 0xE0, +0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x41, 0x1A, 0x90, +0x04, 0x47, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x46, 0xE0, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x45, 0xE0, +0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x44, 0x41, 0x11, 0x90, 0x04, 0x4B, 0xE0, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x4A, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x49, 0xE0, 0x85, 0x11, 0x82, +0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, 0x48, 0x80, 0x58, 0x90, 0x04, 0x4F, 0xE0, 0xAB, 0x12, 0xAA, +0x13, 0xA9, 0x14, 0x12, 0x42, 0x4D, 0x90, 0x04, 0x4E, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x90, 0x00, 0x01, 0x12, 0x42, 0x5F, 0x90, 0x04, 0x4D, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, +0xF0, 0x90, 0x04, 0x4C, 0x80, 0x2B, 0x90, 0x04, 0x53, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0x12, 0x42, 0x4D, 0x90, 0x04, 0x52, 0xE0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x01, +0x12, 0x42, 0x5F, 0x90, 0x04, 0x51, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xF0, 0x90, 0x04, +0x50, 0xE0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, +0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x12, 0x29, 0xD9, 0xFF, 0xAB, 0x17, 0xAA, 0x18, 0xA9, 0x19, +0x12, 0x29, 0xD9, 0x5F, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x42, 0x4D, 0xAB, 0x12, 0xE5, +0x14, 0x24, 0x01, 0xF9, 0xE4, 0x35, 0x13, 0xFA, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x12, 0x29, +0xD9, 0xFF, 0xAB, 0x17, 0xAA, 0x18, 0xA9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x5F, 0xD0, +0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x42, 0x4D, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xC0, 0x83, +0xC0, 0x82, 0xE0, 0xFF, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, +0xD0, 0x83, 0xF0, 0x85, 0x11, 0x82, 0x85, 0x10, 0x83, 0xA3, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, +0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xA3, 0xE0, 0xFE, 0xEF, 0x5E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, +0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, +0xE0, 0x4E, 0x60, 0x4B, 0x90, 0x8A, 0xE6, 0x74, 0x0B, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, +0x94, 0x00, 0x50, 0x02, 0x61, 0x5F, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, +0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, +0x34, 0x86, 0xF5, 0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x0A, 0x90, 0x8A, 0xE6, +0xE0, 0x24, 0x10, 0xA3, 0xF0, 0x80, 0x68, 0x90, 0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBB, 0xE5, +0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, +0x4E, 0x60, 0x47, 0x90, 0x8A, 0xE6, 0x74, 0x0F, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, +0x00, 0x40, 0x3C, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x08, 0x90, 0x8A, 0xE6, 0xE0, 0xA3, 0xF0, +0x80, 0x0D, 0x90, 0x8A, 0xE6, 0xE0, 0x14, 0xF0, 0x80, 0xBF, 0xE4, 0x90, 0x8A, 0xE7, 0xF0, 0xE5, +0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, +0x4E, 0x60, 0x46, 0xE4, 0x90, 0x8A, 0xE6, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x10, +0x40, 0x02, 0x81, 0x18, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, +0xF5, 0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x06, 0x90, 0x8A, 0xE6, 0xE0, 0x80, +0x63, 0x90, 0x8A, 0xE6, 0xE0, 0x04, 0xF0, 0x80, 0xBF, 0xE5, 0x0F, 0x25, 0xE0, 0x24, 0x81, 0xF5, +0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x60, 0x46, 0xE4, 0x90, 0x8A, +0xE6, 0xF0, 0x90, 0x8A, 0xE6, 0xE0, 0xFF, 0xC3, 0x94, 0x0C, 0x50, 0x3C, 0x74, 0x01, 0x7E, 0x00, +0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xE5, 0x0F, 0x25, +0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, +0x4E, 0x60, 0x08, 0x90, 0x8A, 0xE6, 0xE0, 0x24, 0x10, 0x80, 0x09, 0x90, 0x8A, 0xE6, 0xE0, 0x04, +0xF0, 0x80, 0xBF, 0xE4, 0x90, 0x8A, 0xE8, 0xF0, 0x90, 0x8A, 0xE7, 0xE0, 0xFF, 0x75, 0xF0, 0x09, +0xE5, 0x0F, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xEF, 0xF0, 0x90, 0x8A, 0xE8, 0xE0, 0xFE, 0x75, +0xF0, 0x09, 0xE5, 0x0F, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xE5, 0x0F, 0xC3, 0x94, +0x20, 0x50, 0x32, 0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xD3, +0x9F, 0x40, 0x02, 0x80, 0x18, 0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, +0xE0, 0xC3, 0x9E, 0x50, 0x08, 0x90, 0x8A, 0xE8, 0xE0, 0xA3, 0xF0, 0x80, 0x08, 0x90, 0x8A, 0xE7, +0xE0, 0x90, 0x8A, 0xE9, 0xF0, 0x90, 0x8A, 0xE9, 0xE0, 0xFD, 0xAF, 0x0F, 0x91, 0xC1, 0x90, 0x8A, +0xE9, 0xE0, 0xFF, 0x74, 0x84, 0x25, 0x0F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, +0x90, 0x8A, 0xE7, 0xE0, 0xFF, 0xD3, 0x94, 0x13, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x03, 0xF0, +0x22, 0xEF, 0xD3, 0x94, 0x0B, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x02, 0xF0, 0x22, 0xEF, 0xD3, +0x94, 0x03, 0x40, 0x07, 0x90, 0x87, 0x22, 0x74, 0x01, 0xF0, 0x22, 0xE4, 0x90, 0x87, 0x22, 0xF0, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x74, 0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, +0xF5, 0x83, 0xED, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAC, 0x07, 0xED, 0x54, 0x1F, 0x90, 0x8A, +0xC7, 0xF0, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xC5, +0xF0, 0x90, 0x8A, 0xC8, 0x74, 0x01, 0xF0, 0xEB, 0xC3, 0x94, 0x01, 0x40, 0x02, 0x80, 0x37, 0x90, +0x8A, 0xC5, 0xE0, 0x25, 0x0D, 0xFF, 0xA3, 0xF0, 0xA3, 0xE0, 0x90, 0x41, 0x9E, 0x93, 0xFE, 0xEF, +0xD3, 0x9E, 0x40, 0x10, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE4, 0xF0, +0xAF, 0x04, 0x80, 0x9D, 0x90, 0x8A, 0xC6, 0xE0, 0xFF, 0x74, 0x01, 0x2C, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEF, 0xF0, 0x22, 0xAD, 0x07, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, +0x43, 0x5F, 0xE0, 0xFF, 0x90, 0x8A, 0xCA, 0xF0, 0x74, 0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, +0xF5, 0x83, 0xE0, 0x54, 0x1F, 0x90, 0x8A, 0xC9, 0xF0, 0xD3, 0x9F, 0x40, 0x06, 0xA3, 0xE0, 0x90, +0x8A, 0xC9, 0xF0, 0x90, 0x8A, 0xC9, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, +0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, +0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xC9, 0xE0, 0xFD, 0x91, 0xC1, 0x90, 0x8A, +0xC9, 0xE0, 0xFF, 0x22, 0xAC, 0x07, 0x74, 0x84, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, +0xE0, 0x54, 0x7F, 0x90, 0x8A, 0xDE, 0xF0, 0xE0, 0x54, 0x1F, 0xFF, 0x90, 0x8A, 0xE1, 0xF0, 0x75, +0xF0, 0x09, 0xEC, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xE3, 0xF0, 0x75, 0xF0, +0x09, 0xEC, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0x90, 0x8A, 0xE4, 0xF0, 0xEC, 0x25, +0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, +0xE5, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xEC, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, 0x86, +0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE7, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xEF, 0xD3, +0x9E, 0x40, 0x0C, 0x90, 0x8A, 0xE4, 0xE0, 0x90, 0x8A, 0xE1, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0xED, +0x70, 0x02, 0xE1, 0x06, 0x90, 0x8A, 0xE2, 0xED, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0x30, 0xE6, 0x0E, +0x90, 0x8A, 0xE1, 0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0x14, 0xF0, 0x90, 0x8A, +0xE2, 0xE0, 0x70, 0x02, 0xE1, 0x06, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0xD3, 0x94, 0x00, 0x50, 0x02, +0xE1, 0x06, 0xE4, 0x90, 0x8A, 0xE0, 0xF0, 0xEF, 0x14, 0x90, 0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xE3, +0xE0, 0xFD, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0xD3, 0x9D, 0x40, 0x6F, 0xEF, 0x94, 0x10, 0x40, 0x21, +0xEF, 0x24, 0xF0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, +0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE7, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x70, +0x27, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x37, 0x74, 0x01, 0x7E, 0x00, 0xA8, +0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE5, 0xE0, +0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x1A, 0x90, 0x8A, 0xDF, 0xE0, 0x90, 0x8A, 0xDE, 0xF0, +0x90, 0x8A, 0xE0, 0xE0, 0x04, 0xF0, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, 0x6F, +0x60, 0x08, 0x90, 0x8A, 0xDF, 0xE0, 0x14, 0xF0, 0x80, 0x83, 0x90, 0x8A, 0xE2, 0xE0, 0xFF, 0x90, +0x8A, 0xE0, 0xE0, 0xC3, 0x9F, 0x50, 0x0F, 0x90, 0x8A, 0xDF, 0xE0, 0xB5, 0x05, 0x08, 0x90, 0x8A, +0xE3, 0xE0, 0x90, 0x8A, 0xDE, 0xF0, 0x90, 0x8A, 0xDE, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, +0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, +0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, +0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xEC, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x90, 0x8A, 0xDE, 0xE0, 0xFD, 0x91, +0xC1, 0x90, 0x8A, 0xDE, 0xE0, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x1A, +0x8A, 0x1B, 0x89, 0x1C, 0x90, 0x8B, 0x3F, 0x12, 0x43, 0x8B, 0xAB, 0x1D, 0xAA, 0x1E, 0xA9, 0x1F, +0x90, 0x8B, 0x42, 0x12, 0x43, 0x8B, 0xAF, 0x20, 0x15, 0x20, 0xEF, 0x60, 0x1E, 0x90, 0x8B, 0x42, +0xE4, 0x75, 0xF0, 0x01, 0x12, 0x43, 0x74, 0x12, 0x29, 0xD9, 0xFF, 0x90, 0x8B, 0x3F, 0xE4, 0x75, +0xF0, 0x01, 0x12, 0x43, 0x74, 0xEF, 0x12, 0x42, 0x4D, 0x80, 0xDB, 0xAB, 0x1A, 0xAA, 0x1B, 0xA9, +0x1C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0xC4, +0x74, 0xA6, 0xF0, 0x74, 0x5F, 0xA3, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A, 0x90, 0x05, 0x22, +0xE0, 0x54, 0x90, 0x60, 0x07, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x01, 0xC7, 0xE0, +0x30, 0xE1, 0xE4, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFB, 0xFA, 0xEF, 0x30, 0xE0, 0x02, 0x7B, 0x80, 0xEF, 0xC3, +0x13, 0x90, 0xFD, 0x10, 0xF0, 0x90, 0x04, 0x25, 0xEF, 0xF0, 0xED, 0x60, 0x1E, 0xAF, 0x03, 0x74, +0x0F, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x74, 0x10, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF, 0x03, 0x74, 0x08, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F, 0xF5, 0x82, 0xE4, 0x34, +0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF0, 0xF0, 0x74, 0x21, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0xE0, 0x54, 0xF7, 0xF0, 0xAE, 0x02, 0xAF, 0x03, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFD, 0xFC, 0xEF, 0x30, 0xE0, 0x02, 0x7D, 0x80, 0xEF, 0xC3, +0x13, 0x90, 0xFD, 0x10, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x5F, +0xA6, 0xBF, 0x01, 0x10, 0x90, 0x02, 0x09, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5F, 0xDE, 0x90, 0x04, +0x1F, 0x74, 0x20, 0xF0, 0x22, 0x90, 0x01, 0x02, 0xE0, 0x54, 0x03, 0xFF, 0xE0, 0x54, 0x0C, 0x13, +0x13, 0x54, 0x3F, 0xFE, 0xEF, 0x64, 0x01, 0x60, 0x04, 0xEF, 0xB4, 0x03, 0x0E, 0x90, 0x8A, 0xC5, +0x74, 0x01, 0xF0, 0xA3, 0x74, 0x37, 0xF0, 0x79, 0x01, 0x80, 0x18, 0xEE, 0x64, 0x01, 0x60, 0x07, +0xAF, 0x06, 0xEE, 0x64, 0x03, 0x70, 0x3B, 0x90, 0x8A, 0xC5, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x3D, +0xF0, 0x79, 0x40, 0x90, 0x8A, 0xC5, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, +0x59, 0x60, 0x08, 0xE9, 0xF0, 0xE4, 0x90, 0x8A, 0xF6, 0xF0, 0x22, 0x90, 0x8A, 0xF6, 0xE0, 0x04, +0xF0, 0xE0, 0xC3, 0x94, 0x0A, 0x40, 0x0B, 0xE4, 0xF0, 0x90, 0x04, 0x19, 0xE0, 0x30, 0xE0, 0x02, +0x11, 0x6E, 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, 0xF3, 0xF0, 0x74, 0x60, 0xA3, 0xF0, 0x90, 0x01, 0x34, 0xE0, 0x55, 0x28, +0xF5, 0x2C, 0xA3, 0xE0, 0x55, 0x29, 0xF5, 0x2D, 0xA3, 0xE0, 0x55, 0x2A, 0xF5, 0x2E, 0xA3, 0xE0, +0x55, 0x2B, 0xF5, 0x2F, 0xE5, 0x2C, 0x20, 0xE0, 0x02, 0x41, 0x8A, 0x90, 0x01, 0x34, 0x74, 0x01, +0xF0, 0x85, 0xD1, 0x4D, 0x85, 0xD2, 0x4E, 0x85, 0xD3, 0x4F, 0x85, 0xD4, 0x50, 0x85, 0xD5, 0x51, +0x85, 0xD6, 0x52, 0x85, 0xD7, 0x53, 0x85, 0xD9, 0x54, 0xE5, 0x54, 0x54, 0x40, 0xC3, 0x13, 0xFF, +0xE5, 0x53, 0x54, 0x20, 0x6F, 0x70, 0x02, 0x41, 0x47, 0xE5, 0x54, 0x30, 0xE5, 0x02, 0x41, 0x47, +0xE5, 0x52, 0x54, 0x1F, 0xF5, 0x08, 0xE5, 0x4D, 0x54, 0x3F, 0xF5, 0x09, 0xE5, 0x51, 0x54, 0x1F, +0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, +0xF0, 0x12, 0x42, 0x81, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0xC0, 0xF5, +0x82, 0xE4, 0x34, 0x85, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x09, 0xD3, 0x94, +0x04, 0x40, 0x03, 0x75, 0x09, 0x04, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, 0x43, +0x5F, 0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xE5, 0x53, +0x54, 0x1F, 0x2F, 0xFF, 0xE4, 0x3E, 0xFE, 0x75, 0xF0, 0x0A, 0xE5, 0x08, 0x90, 0x84, 0x00, 0x12, +0x43, 0x5F, 0x75, 0xF0, 0x02, 0xE5, 0x09, 0x12, 0x43, 0x5F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, +0x54, 0x20, 0xE6, 0x24, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, 0xE0, 0x24, 0x63, 0xF5, +0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xE5, 0x4F, 0x30, 0xE7, +0x36, 0xAF, 0x08, 0x12, 0x5D, 0x36, 0x80, 0x2F, 0xE5, 0x53, 0x54, 0x1F, 0xFF, 0xE5, 0x08, 0x25, +0xE0, 0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE4, 0x8F, 0xF0, 0x12, 0x42, 0x81, +0xE5, 0x4F, 0x30, 0xE7, 0x12, 0xE5, 0x4F, 0x54, 0x7F, 0xFD, 0xE5, 0x53, 0x54, 0x1F, 0xF5, 0x0D, +0xAB, 0x09, 0xAF, 0x08, 0x12, 0x5C, 0xD9, 0xE5, 0x24, 0x14, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x3A, +0x90, 0x8B, 0x1A, 0xE0, 0x60, 0x2B, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, +0xF0, 0x12, 0x4B, 0x34, 0xEF, 0x64, 0x01, 0x70, 0x21, 0x90, 0x8B, 0x3D, 0x12, 0x4B, 0x5C, 0x90, +0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x92, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x18, 0xF0, 0x80, +0x09, 0x12, 0x4B, 0x34, 0xBF, 0x01, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2C, 0x30, 0xE1, 0x20, 0x90, +0x01, 0x34, 0x74, 0x02, 0xF0, 0x85, 0xD1, 0x56, 0x85, 0xD2, 0x57, 0x85, 0xD3, 0x58, 0x85, 0xD4, +0x59, 0x85, 0xD5, 0x5A, 0x85, 0xD6, 0x5B, 0x85, 0xD7, 0x5C, 0x85, 0xD9, 0x5D, 0xB1, 0x5F, 0xE5, +0x2C, 0x30, 0xE3, 0x06, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0xE5, 0x2C, 0x30, 0xE4, 0x09, 0x90, +0x01, 0x34, 0x74, 0x10, 0xF0, 0x43, 0x55, 0x10, 0xE5, 0x2C, 0x30, 0xE5, 0x26, 0x90, 0x01, 0xCF, +0xE0, 0x30, 0xE5, 0x1F, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x20, 0xF0, 0x75, 0xA8, +0x00, 0x75, 0xE8, 0x00, 0x12, 0x52, 0x10, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xF0, 0x12, 0x52, +0x81, 0x80, 0xFE, 0xE5, 0x2C, 0x30, 0xE6, 0x2D, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0x90, 0x8B, +0x32, 0xE0, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, 0x90, 0x8B, 0x34, 0xE4, +0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, +0x90, 0x8B, 0x2E, 0xE4, 0xF0, 0xE5, 0x2E, 0x20, 0xE0, 0x02, 0x61, 0xE7, 0x90, 0x8B, 0x08, 0x74, +0x01, 0xF0, 0x90, 0x01, 0x36, 0xF0, 0x90, 0x8B, 0x06, 0xE0, 0x60, 0x0F, 0xE4, 0xF0, 0x90, 0x05, +0x53, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0x30, +0xE0, 0x2F, 0x90, 0x8B, 0x37, 0x74, 0x01, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xFF, 0x13, 0x13, 0x54, +0x3F, 0x30, 0xE0, 0x1D, 0x90, 0x8B, 0x34, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0x90, 0x8B, 0x33, 0xE0, +0x64, 0x03, 0x60, 0x0D, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x7F, 0x04, 0x12, 0x4E, +0x89, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0x30, 0xE0, 0x56, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x4F, +0x90, 0x8B, 0x2E, 0x74, 0x01, 0xF0, 0xB1, 0x39, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x3F, +0xB1, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0x64, 0x06, 0x60, +0x2E, 0xEF, 0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x04, 0xE4, 0xFF, +0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x02, 0x05, 0x7F, 0x01, 0x12, 0x7B, 0x49, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x12, +0x43, 0xE7, 0x90, 0x8B, 0x08, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE1, 0x2F, 0x90, 0x01, 0x36, 0x74, +0x02, 0xF0, 0x43, 0x55, 0x40, 0x11, 0x85, 0x90, 0x8B, 0x37, 0xE0, 0xB4, 0x01, 0x09, 0x90, 0x05, +0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x37, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x0D, 0xE4, 0xFF, +0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0xE5, 0x2E, 0x30, 0xE2, 0x16, +0x90, 0x01, 0x36, 0x74, 0x04, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x06, 0xA3, 0xE0, 0x64, +0x06, 0x60, 0x03, 0x12, 0x46, 0xB3, 0xE5, 0x2E, 0x30, 0xE3, 0x38, 0x90, 0x01, 0x36, 0x74, 0x08, +0xF0, 0xE5, 0x21, 0x64, 0x01, 0x70, 0x2C, 0xE5, 0x24, 0x60, 0x28, 0x90, 0x01, 0x57, 0xE4, 0xF0, +0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x8B, 0x3D, 0xE4, 0xF0, 0x90, 0x8B, 0x11, 0xE0, 0x90, +0x8B, 0x3E, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x57, +0x74, 0x05, 0xF0, 0xE5, 0x2E, 0x30, 0xE4, 0x2B, 0x90, 0x01, 0x36, 0x74, 0x10, 0xF0, 0xE5, 0x21, +0xB4, 0x01, 0x20, 0xE5, 0x24, 0x60, 0x1C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, +0x02, 0xF0, 0x90, 0x8B, 0x1B, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0xE5, 0x25, 0x54, 0x07, 0x70, 0x03, +0x12, 0x4A, 0xFC, 0xE5, 0x2E, 0x30, 0xE5, 0x1F, 0x90, 0x01, 0x36, 0x74, 0x20, 0xF0, 0xE5, 0x21, +0xB4, 0x01, 0x14, 0xE5, 0x24, 0x60, 0x10, 0x90, 0x8B, 0x1A, 0xE0, 0x64, 0x02, 0x60, 0x05, 0x12, +0x4A, 0x97, 0x80, 0x03, 0x12, 0x49, 0x49, 0xE5, 0x2E, 0x30, 0xE6, 0x1B, 0x90, 0x01, 0x36, 0x74, +0x40, 0xF0, 0xE5, 0x21, 0xB4, 0x01, 0x10, 0xE5, 0x24, 0x60, 0x0C, 0x53, 0x25, 0xFE, 0xE5, 0x25, +0x54, 0x07, 0x70, 0x03, 0x12, 0x4A, 0xFC, 0xE5, 0x2F, 0x30, 0xE1, 0x27, 0x90, 0x01, 0x37, 0x74, +0x02, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0x30, 0xE0, 0x17, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, +0x07, 0x12, 0x48, 0xFE, 0xD1, 0x20, 0x80, 0x0B, 0x90, 0x8B, 0x31, 0x74, 0x01, 0xF0, 0x80, 0x03, +0x12, 0x48, 0xFE, 0x74, 0xF3, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x60, 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, 0x90, 0x8B, 0x3D, 0xF0, 0x90, 0x05, +0x58, 0xE0, 0xFF, 0x90, 0x8B, 0x38, 0xE0, 0x2F, 0x24, 0xFE, 0x90, 0x8B, 0x3E, 0xF0, 0xE4, 0xFB, +0xFD, 0x7F, 0x50, 0x7E, 0x01, 0x12, 0x4B, 0x6C, 0x90, 0x01, 0x53, 0x74, 0x05, 0xF0, 0x22, 0x90, +0x8A, 0xC5, 0xE0, 0x54, 0xF0, 0x44, 0x03, 0xF0, 0x54, 0x0F, 0x44, 0x80, 0xF0, 0x7B, 0x00, 0x7A, +0x00, 0x79, 0x56, 0x90, 0x8B, 0x48, 0x12, 0x43, 0x8B, 0x0B, 0x7A, 0x8A, 0x79, 0xC5, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x8B, 0x90, 0x8B, 0x53, 0xE0, 0xFF, +0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x42, 0x5F, 0x7F, 0xAF, 0x7E, 0x01, 0xD1, 0x8A, 0xEF, +0x60, 0x49, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x6B, 0x8B, 0x1D, 0x8A, 0x1E, 0x89, 0x1F, 0x75, 0x20, +0x02, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12, 0x5F, 0x57, 0x90, 0x8B, 0x48, 0x12, 0x43, 0x6B, +0x8B, 0x1D, 0x8A, 0x1E, 0x89, 0x1F, 0x90, 0x8B, 0x45, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, +0xC4, 0x54, 0x0F, 0xF5, 0x20, 0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA2, 0x12, 0x5F, 0x57, 0x90, 0x01, +0xAF, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB, 0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x0B, 0xA3, 0xE0, 0x64, +0x06, 0x60, 0x05, 0x7F, 0x06, 0x12, 0x7B, 0x49, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x02, +0xD1, 0x13, 0x22, 0x90, 0x8B, 0x31, 0xE0, 0xB4, 0x01, 0x05, 0xE4, 0xF0, 0x12, 0x48, 0xFE, 0x22, +0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x06, 0x60, 0x3C, 0xE5, 0x22, 0x54, 0x0F, 0x14, 0x60, 0x2E, 0x14, +0x60, 0x1E, 0x24, 0xFE, 0x60, 0x0E, 0x24, 0xF8, 0x70, 0x2A, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x90, +0x05, 0x22, 0xF0, 0x22, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x22, +0x90, 0x8B, 0x2D, 0x74, 0x03, 0xF0, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x22, 0x90, 0x01, 0xC6, +0xE0, 0x44, 0x08, 0xF0, 0x22, 0xAE, 0x07, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, 0x60, 0x18, 0x90, +0x8B, 0x2C, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x0C, 0xAF, 0x06, 0x7D, 0x01, 0x12, +0x45, 0xA2, 0xD1, 0x20, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x8B, 0x4B, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x8B, 0x4B, 0xE0, 0xFE, 0xA3, 0xE0, 0xF5, 0x82, +0x8E, 0x83, 0xE0, 0x60, 0x2C, 0xC3, 0x90, 0x8B, 0x4E, 0xE0, 0x94, 0xE8, 0x90, 0x8B, 0x4D, 0xE0, +0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x7F, 0x00, 0x22, 0x90, 0x8B, +0x4D, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x37, 0x54, 0x80, +0xC6, 0x7F, 0x01, 0x22, 0x75, 0x28, 0x33, 0xE4, 0xF5, 0x29, 0x75, 0x2A, 0x07, 0xF5, 0x2B, 0x90, +0x01, 0x30, 0xE5, 0x28, 0xF0, 0xA3, 0xE5, 0x29, 0xF0, 0xA3, 0xE5, 0x2A, 0xF0, 0xA3, 0xE5, 0x2B, +0xF0, 0x22, 0x75, 0x30, 0x1F, 0x75, 0x31, 0x01, 0x43, 0x31, 0x10, 0xE4, 0xF5, 0x32, 0x90, 0x01, +0x38, 0xE5, 0x30, 0xF0, 0xA3, 0xE5, 0x31, 0xF0, 0xA3, 0xE5, 0x32, 0xF0, 0x22, 0x22, 0x90, 0x00, +0x02, 0xE0, 0x54, 0xE0, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22, 0x90, 0x00, 0xF3, 0xE0, 0x7F, +0x00, 0x30, 0xE3, 0x02, 0x7F, 0x01, 0x22, 0x90, 0x8B, 0x09, 0xE0, 0xB4, 0x01, 0x0C, 0x90, 0x00, +0xF2, 0xE0, 0x30, 0xE7, 0x05, 0x7E, 0xFD, 0x7F, 0x33, 0x22, 0x7E, 0xFD, 0x7F, 0x2F, 0x22, 0x90, +0x00, 0xF3, 0xE0, 0x30, 0xE2, 0x0D, 0x90, 0x05, 0x41, 0x74, 0x10, 0xF0, 0x90, 0x05, 0x5A, 0xF0, +0xA3, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0x64, 0x74, 0xA0, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, +0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x7D, 0x5B, 0x90, 0x01, +0xC4, 0xED, 0xF0, 0x74, 0x67, 0xFF, 0xA3, 0xF0, 0x53, 0x91, 0xEF, 0x90, 0x00, 0x51, 0xE0, 0xFE, +0x90, 0x00, 0x55, 0xE0, 0x5E, 0xF5, 0x3D, 0x90, 0x00, 0x52, 0xE0, 0xFE, 0x90, 0x00, 0x56, 0xE0, +0x5E, 0xF5, 0x3E, 0xE5, 0x3D, 0x30, 0xE4, 0x06, 0x90, 0x00, 0x55, 0x74, 0x10, 0xF0, 0xE5, 0x3D, +0x30, 0xE5, 0x06, 0x90, 0x00, 0x55, 0x74, 0x20, 0xF0, 0xE5, 0x3D, 0x30, 0xE6, 0x06, 0x90, 0x00, +0x55, 0x74, 0x40, 0xF0, 0xE5, 0x3D, 0x30, 0xE7, 0x06, 0x90, 0x00, 0x55, 0x74, 0x80, 0xF0, 0xE5, +0x3E, 0x30, 0xE0, 0x06, 0x90, 0x00, 0x56, 0x74, 0x01, 0xF0, 0xE5, 0x3E, 0x30, 0xE1, 0x06, 0x90, +0x00, 0x56, 0x74, 0x02, 0xF0, 0xE5, 0x3E, 0x30, 0xE2, 0x06, 0x90, 0x00, 0x56, 0x74, 0x04, 0xF0, +0xE5, 0x3E, 0x30, 0xE3, 0x06, 0x90, 0x00, 0x56, 0x74, 0x08, 0xF0, 0x90, 0x01, 0xC4, 0xED, 0xF0, +0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, +0xE0, 0x32, 0xEF, 0xC3, 0x94, 0x20, 0x50, 0x39, 0xEF, 0x30, 0xE0, 0x17, 0xED, 0xC4, 0x54, 0xF0, +0xFD, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, +0x0F, 0x80, 0x10, 0xEF, 0xC3, 0x13, 0xFE, 0x24, 0xA4, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, +0xE0, 0x54, 0xF0, 0xF0, 0x74, 0xA4, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x4D, +0xF0, 0x22, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, +0x02, 0xC1, 0xCD, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2A, 0x12, 0x43, 0x5F, 0xE0, 0x64, 0x01, +0x60, 0x02, 0xC1, 0xC5, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, +0x85, 0xF5, 0x83, 0xE0, 0xFC, 0xA3, 0xE0, 0xD3, 0x94, 0x00, 0xEC, 0x94, 0x00, 0x50, 0x02, 0xC1, +0xC5, 0xEF, 0x75, 0xF0, 0x0A, 0xA4, 0x24, 0x00, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0x75, 0x12, 0x01, +0xF5, 0x13, 0x89, 0x14, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, +0x85, 0xF5, 0x83, 0xE0, 0xFD, 0xA3, 0xE0, 0x90, 0x8A, 0xD4, 0xCD, 0xF0, 0xA3, 0xED, 0xF0, 0xEF, +0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, +0x8A, 0xD6, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, 0x24, 0x84, 0xF5, 0x82, +0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x3F, 0x90, 0x8A, 0xD0, 0xF0, 0xE0, 0xFD, 0x54, 0x1F, +0xA3, 0xF0, 0x75, 0xF0, 0x09, 0xEE, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0xE0, 0x90, 0x8A, 0xD9, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFB, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, +0xC3, 0x94, 0x05, 0x40, 0x02, 0x61, 0x1A, 0x90, 0x8A, 0xD9, 0xE0, 0xFE, 0x90, 0x8A, 0xD1, 0xE0, +0x9E, 0x40, 0x13, 0x90, 0x8A, 0xD9, 0xE0, 0x90, 0x8A, 0xD1, 0xF0, 0xED, 0x54, 0x40, 0xFD, 0x90, +0x8A, 0xD0, 0xF0, 0xEE, 0x4D, 0xF0, 0x90, 0x8A, 0xD1, 0xE0, 0xFF, 0x90, 0x41, 0x12, 0x93, 0xFE, +0x74, 0x23, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xC3, 0x9E, 0x40, 0x06, 0xEF, +0x90, 0x40, 0xDA, 0x80, 0x07, 0x90, 0x8A, 0xD1, 0xE0, 0x90, 0x40, 0xF6, 0x93, 0x90, 0x8A, 0xD8, +0xF0, 0x90, 0x8A, 0xD8, 0xE0, 0x75, 0xF0, 0x06, 0xA4, 0x24, 0x50, 0xF9, 0x74, 0x40, 0x35, 0xF0, +0x75, 0x0F, 0xFF, 0xF5, 0x10, 0x89, 0x11, 0x90, 0x8A, 0xD0, 0xE0, 0x90, 0x41, 0xBA, 0x93, 0xFF, +0xD3, 0x90, 0x8A, 0xD7, 0xE0, 0x9F, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x0C, 0x90, 0x8A, +0xCF, 0xE0, 0xFF, 0xE4, 0xFD, 0x12, 0x5D, 0xB4, 0xC1, 0x5B, 0x90, 0x8A, 0xCF, 0xE0, 0x25, 0xE0, +0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xD2, +0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x12, 0x29, 0xD9, 0xFF, 0x7E, +0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x12, 0x42, 0x97, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, +0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, +0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, +0x02, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, +0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, +0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x04, 0x12, 0x42, 0xC2, 0xFD, 0xAC, +0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, +0x10, 0xA9, 0x11, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, +0xA9, 0x14, 0x90, 0x00, 0x06, 0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, +0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x04, +0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x08, 0x12, +0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, +0x81, 0xAB, 0x0F, 0xAA, 0x10, 0xA9, 0x11, 0x90, 0x00, 0x05, 0x12, 0x42, 0x20, 0xFF, 0x7E, 0x00, +0x90, 0x8A, 0xD4, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x29, 0xF2, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, +0x9F, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x0C, 0xA3, 0xE0, 0x9F, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, +0x9E, 0xF0, 0x80, 0x07, 0xE4, 0x90, 0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xD2, 0xE0, 0xFC, +0xA3, 0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEC, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, 0x2E, +0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xD3, 0xED, +0x9B, 0xEC, 0x9A, 0x40, 0x04, 0xD1, 0xCE, 0xC1, 0x29, 0x90, 0x8A, 0xD0, 0xE0, 0x25, 0xE0, 0x24, +0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0xFF, 0xC3, +0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x40, 0x02, 0xC1, 0x29, 0x90, 0x8A, +0xCF, 0xE0, 0xFF, 0x7D, 0x01, 0x12, 0x5D, 0xB4, 0xC1, 0x29, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, +0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xFC, 0x64, 0x05, 0x60, 0x02, 0x81, 0xF8, +0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x03, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, 0x19, 0x40, +0x3D, 0x80, 0x2E, 0xEE, 0xB4, 0x02, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, 0x11, 0x40, 0x2E, +0x80, 0x1F, 0x90, 0x87, 0x22, 0xE0, 0xFE, 0xB4, 0x01, 0x0B, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, +0x0A, 0x40, 0x1B, 0x80, 0x0C, 0xEE, 0x70, 0x11, 0x90, 0x8A, 0xD1, 0xE0, 0xC3, 0x94, 0x03, 0x40, +0x0D, 0x90, 0x89, 0x43, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x89, 0x43, 0xF0, 0x90, 0x8A, +0xCF, 0xE0, 0xFE, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xDD, +0xF0, 0x74, 0x23, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, 0xC3, 0x94, 0x30, +0x50, 0x0A, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0x81, 0xA3, 0x90, 0x89, 0x43, 0xE0, +0x64, 0x01, 0x60, 0x02, 0x81, 0x98, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x44, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE0, 0x64, 0x0A, 0x60, 0x5B, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0xEE, 0x24, 0x05, +0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xE0, 0xFF, +0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x50, 0x38, 0x90, 0x8A, 0xCF, 0xE0, 0xFE, +0xEF, 0x24, 0x05, 0xFB, 0xE4, 0x33, 0xFA, 0x74, 0x23, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0xE0, 0xD3, 0x9B, 0xEA, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x98, 0x50, 0x16, 0x90, 0x8A, 0xCF, +0xE0, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x8A, 0xD1, 0xE0, +0x6F, 0x60, 0x56, 0x90, 0x8A, 0xCF, 0xE0, 0x24, 0x23, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, +0xE0, 0xFF, 0xD3, 0x94, 0x42, 0x40, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x05, 0xF0, 0x80, 0x11, 0xEF, +0xD3, 0x94, 0x39, 0x90, 0x8A, 0xDD, 0x40, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x03, 0x74, 0x01, 0xF0, +0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x23, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFE, +0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, +0x24, 0x44, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0x80, 0x2F, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x64, +0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x44, 0x2F, 0xF5, 0x82, 0xE4, 0x34, +0x89, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x80, 0x14, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x90, 0x8A, 0xCF, +0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x8A, 0xD1, 0xE0, +0xFE, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x84, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEE, +0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFE, 0x74, 0x43, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, +0xEE, 0xF0, 0x75, 0xF0, 0x09, 0xEF, 0x90, 0x87, 0x2B, 0x12, 0x43, 0x5F, 0xE0, 0xB4, 0x01, 0x11, +0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0x74, 0x64, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0xC1, 0x27, 0xEC, 0x64, 0x06, 0x60, 0x02, 0xC1, 0x29, 0x90, +0x8A, 0xD2, 0xF0, 0xA3, 0xF0, 0x90, 0x41, 0xDB, 0x93, 0xFF, 0x7E, 0x00, 0x90, 0x8A, 0xD4, 0xE0, +0xFC, 0xA3, 0xE0, 0xFD, 0x12, 0x29, 0xF2, 0x90, 0x8A, 0xDB, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x8A, 0xCF, 0xE0, 0x24, 0x43, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xDD, +0xF0, 0xE4, 0x90, 0x8A, 0xDA, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0xD3, 0x94, 0x04, 0x50, 0x47, +0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x75, 0xF0, 0x02, 0xEF, 0xA4, 0xF5, 0x82, 0x85, 0xF0, 0x83, +0x12, 0x42, 0xC2, 0xFD, 0xAC, 0xF0, 0xEF, 0x90, 0x41, 0xD6, 0x93, 0xFF, 0x7E, 0x00, 0x12, 0x29, +0xF2, 0x90, 0x8A, 0xD2, 0xEE, 0x8F, 0xF0, 0x12, 0x42, 0x81, 0x90, 0x8A, 0xDB, 0xE0, 0xFE, 0xA3, +0xE0, 0xFF, 0xD3, 0x90, 0x8A, 0xD3, 0xE0, 0x9F, 0x90, 0x8A, 0xD2, 0xE0, 0x9E, 0x50, 0x08, 0x90, +0x8A, 0xDA, 0xE0, 0x04, 0xF0, 0x80, 0xAF, 0x90, 0x8A, 0xDA, 0xE0, 0xC3, 0x13, 0xF0, 0x90, 0x8A, +0xDD, 0xE0, 0xFF, 0xB4, 0x01, 0x0D, 0x90, 0x8A, 0xDA, 0xE0, 0x70, 0x5D, 0x90, 0x8A, 0xDD, 0x04, +0xF0, 0x80, 0x5B, 0xEF, 0xB4, 0x03, 0x1D, 0x90, 0x8A, 0xDA, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x8A, +0xDD, 0x74, 0x03, 0xF0, 0x80, 0x48, 0xEF, 0xB4, 0x01, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, +0x80, 0x3C, 0x80, 0x35, 0x90, 0x8A, 0xDD, 0xE0, 0x64, 0x05, 0x70, 0x32, 0x90, 0x8A, 0xDA, 0xE0, +0xFF, 0x70, 0x08, 0x90, 0x8A, 0xDD, 0x74, 0x05, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x8A, 0xDD, 0xB4, +0x01, 0x05, 0x74, 0x03, 0xF0, 0x80, 0x03, 0x74, 0x01, 0xF0, 0xD3, 0x90, 0x8A, 0xD7, 0xE0, 0x94, +0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x05, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0xD3, 0x90, +0x8A, 0xD7, 0xE0, 0x94, 0x03, 0x90, 0x8A, 0xD6, 0xE0, 0x94, 0x00, 0x40, 0x05, 0xE4, 0x90, 0x8A, +0xDD, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0xFD, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x43, 0xF5, 0x82, +0xE4, 0x34, 0x88, 0xF5, 0x83, 0xED, 0xF0, 0x11, 0x02, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x24, 0x64, +0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0xD3, 0x94, 0x05, 0x50, 0x0F, 0x74, 0x64, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x80, 0x0F, 0x90, 0x8A, 0xCF, 0xE0, +0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0xAB, 0x12, 0xAA, 0x13, 0xA9, +0x14, 0xE4, 0xF5, 0xF0, 0x12, 0x42, 0xFA, 0xAB, 0x12, 0xAA, 0x13, 0xA9, 0x14, 0x90, 0x00, 0x02, +0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x04, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, +0x00, 0x06, 0xE4, 0xF5, 0xF0, 0x12, 0x43, 0x19, 0x90, 0x00, 0x08, 0xE4, 0xF5, 0xF0, 0x12, 0x43, +0x19, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x01, 0x47, 0x22, 0xAD, 0x07, +0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0x90, 0x8A, 0xDE, +0xF0, 0xE0, 0xF9, 0x54, 0x1F, 0xA3, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, +0x5F, 0xE0, 0xFF, 0x90, 0x8A, 0xE1, 0xF0, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x8A, 0xE2, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0xED, +0x25, 0xE0, 0x24, 0xE4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, +0x8A, 0xE4, 0xCB, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x8A, 0xDF, 0xE0, 0xFE, 0x25, 0xE0, 0x24, 0x2E, +0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xED, 0x25, +0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEA, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, +0xC3, 0x9F, 0x40, 0x03, 0x02, 0x70, 0x12, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, 0xF5, +0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0xEF, 0x04, 0x90, 0x8A, 0xE0, 0xF0, 0x90, 0x8A, +0xE1, 0xE0, 0xFF, 0x90, 0x8A, 0xE0, 0xE0, 0xFE, 0xD3, 0x9F, 0x40, 0x03, 0x02, 0x70, 0x4C, 0xEE, +0xC3, 0x94, 0x10, 0x40, 0x21, 0xEE, 0x24, 0xF0, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x8A, 0xE2, 0xE0, 0x5E, 0xFE, +0xA3, 0xE0, 0x5F, 0x4E, 0x70, 0x27, 0x90, 0x8A, 0xE0, 0xE0, 0xFF, 0xC3, 0x94, 0x10, 0x50, 0x59, +0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +0xFF, 0x90, 0x8A, 0xE4, 0xE0, 0x5E, 0xFE, 0xA3, 0xE0, 0x5F, 0x4E, 0x60, 0x3C, 0x90, 0x8A, 0xE0, +0xE0, 0xB4, 0x11, 0x0D, 0x90, 0x8A, 0xE3, 0xE0, 0x30, 0xE7, 0x06, 0x90, 0x8A, 0xE0, 0x74, 0x17, +0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xFF, 0x64, 0x13, 0x60, 0x04, 0xEF, 0xB4, 0x12, 0x0D, 0x90, 0x8A, +0xE2, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x8A, 0xE0, 0x74, 0x18, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0x90, +0x8A, 0xDF, 0xF0, 0x90, 0x8A, 0xDE, 0xF0, 0x80, 0x43, 0x90, 0x8A, 0xE0, 0xE0, 0x04, 0xF0, 0x02, +0x6F, 0x6E, 0x90, 0x8A, 0xE1, 0xE0, 0xFC, 0x90, 0x8A, 0xDF, 0xE0, 0xFF, 0x6C, 0x70, 0x71, 0x74, +0xA5, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, +0x87, 0x29, 0x12, 0x43, 0x5F, 0xE0, 0xB4, 0x01, 0x10, 0xE9, 0x20, 0xE6, 0x0C, 0x90, 0x8A, 0xDF, +0xE0, 0x44, 0x40, 0x90, 0x8A, 0xDE, 0xF0, 0x80, 0x03, 0xAF, 0x01, 0x22, 0x90, 0x8A, 0xDF, 0xE0, +0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE4, 0x93, 0xFA, 0x74, +0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0x74, +0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xED, 0x25, 0xE0, +0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x66, +0x90, 0x8A, 0xDF, 0xE0, 0xD3, 0x9C, 0x40, 0x5E, 0x90, 0x8A, 0xE1, 0xE0, 0xFF, 0x74, 0xA5, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x8A, 0xDF, 0xEF, 0xF0, 0x90, 0x8A, +0xDE, 0xF0, 0xFC, 0xA3, 0xE0, 0xFF, 0x25, 0xE0, 0x24, 0x66, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, +0x83, 0xE4, 0x93, 0xFA, 0x74, 0x01, 0x93, 0xFB, 0xEF, 0x25, 0xE0, 0x24, 0x2E, 0xF5, 0x82, 0xE4, +0x34, 0x41, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x2B, 0xFF, 0xE4, 0x93, 0x3A, 0xC3, 0x13, 0xFE, 0xEF, +0x13, 0xFF, 0xED, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0xEE, 0xF0, +0xA3, 0xEF, 0xF0, 0xAF, 0x04, 0x22, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, +0xE4, 0xF0, 0xAF, 0x05, 0x90, 0x8A, 0xDE, 0xE0, 0x44, 0x80, 0xFD, 0x12, 0x5C, 0xC1, 0x90, 0x8A, +0xDE, 0xE0, 0x44, 0x80, 0xFF, 0x22, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0xFF, +0xC3, 0x94, 0x10, 0x50, 0x14, 0x74, 0xA4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE4, +0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x80, 0xE2, 0xE4, 0x90, 0x8A, 0xCF, 0xF0, 0x90, 0x8A, +0xCF, 0xE0, 0xFF, 0xC3, 0x94, 0x20, 0x40, 0x02, 0x41, 0xCF, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, +0x00, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x02, 0x12, +0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x04, 0x12, 0x43, 0x5F, +0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x06, 0x12, 0x43, 0x5F, 0xE4, 0xF0, +0xA3, 0xF0, 0x75, 0xF0, 0x0A, 0xEF, 0x90, 0x84, 0x08, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0xF0, +0x74, 0x84, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x74, 0x44, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x43, 0x2F, 0xF5, 0x82, 0xE4, 0x34, +0x88, 0xF5, 0x83, 0xE4, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xC0, 0xF5, 0x82, 0xE4, 0x34, 0x85, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x63, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xE3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA3, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0xEF, 0x25, 0xE0, 0x24, 0xA4, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, +0x83, 0xE4, 0xF0, 0xA3, 0xF0, 0x74, 0x44, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, +0xF0, 0x74, 0x24, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x64, 0x2F, +0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x41, 0x8C, 0x93, 0xFE, 0x74, 0x01, +0x93, 0xFF, 0x90, 0x41, 0x54, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x3E, 0xC3, 0x13, 0xFE, +0xEF, 0x13, 0xFF, 0x90, 0x8A, 0xCF, 0xE0, 0xFD, 0x25, 0xE0, 0x24, 0xE1, 0xF5, 0x82, 0xE4, 0x34, +0x86, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x29, 0x12, +0x43, 0x5F, 0x74, 0x01, 0xF0, 0x74, 0xC1, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x86, 0xF5, 0x83, 0x74, +0x0C, 0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x25, 0x12, 0x43, 0x5F, 0x74, 0xFF, 0xF0, 0xA3, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x23, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, +0xF0, 0x75, 0xF0, 0x09, 0xED, 0x90, 0x87, 0x27, 0x12, 0x43, 0x5F, 0x74, 0x13, 0xF0, 0x75, 0xF0, +0x09, 0xED, 0x90, 0x87, 0x28, 0x12, 0x43, 0x5F, 0xE4, 0xF0, 0x74, 0x84, 0x2D, 0xF5, 0x82, 0xE4, +0x34, 0x04, 0xF5, 0x83, 0x74, 0x13, 0xF0, 0x90, 0x8A, 0xCF, 0xE0, 0x04, 0xF0, 0x21, 0x3E, 0x22, +0x12, 0x29, 0xD9, 0xFF, 0xC3, 0x94, 0x20, 0x50, 0x14, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFE, +0x74, 0x23, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x89, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xEF, 0xB4, 0x20, +0x0A, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0x90, 0x87, 0x21, 0xF0, 0x22, 0x12, 0x29, 0xD9, 0xF5, +0x21, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x2A, 0x8B, 0x00, +0x00, 0x00, 0x00, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x1A, 0xF0, 0x90, 0x00, 0x03, +0x12, 0x42, 0x20, 0x90, 0x8B, 0x0A, 0xF0, 0x12, 0x47, 0xFA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, +0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0x30, 0xE0, 0x25, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x10, 0xF0, +0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x11, 0xF0, 0xEF, 0xC3, 0x13, 0x54, 0x7F, 0x90, +0x8B, 0x0F, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x16, 0xF0, 0x22, 0x90, 0x8B, +0x10, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x11, 0x74, 0x05, 0xF0, 0x90, 0x8B, 0x0F, 0x74, 0x14, 0xF0, +0x90, 0x8B, 0x16, 0x74, 0x05, 0xF0, 0x22, 0x12, 0x29, 0xD9, 0x30, 0xE0, 0x19, 0xC3, 0x13, 0x54, +0x7F, 0x90, 0x8B, 0x15, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, 0xFF, 0x90, 0x8B, 0x13, 0xE4, +0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x0F, 0x90, 0x8B, 0x15, 0x74, 0x05, 0xF0, 0x90, 0x8B, 0x13, 0xE4, +0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x90, 0x8B, 0x13, 0xE0, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, +0x12, 0x29, 0xD9, 0x90, 0x8B, 0x12, 0xF0, 0x60, 0x07, 0xE4, 0xFD, 0x7F, 0x04, 0x12, 0x45, 0xA2, +0x90, 0x8B, 0x12, 0xE0, 0x90, 0x01, 0xE7, 0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x29, +0xD9, 0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x90, 0x8A, 0xF7, 0xF0, 0x90, 0x00, 0x01, 0x12, 0x42, 0x20, +0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xF8, 0xF0, 0x90, 0x00, 0x02, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, +0x90, 0x8A, 0xF9, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x42, 0x20, 0xFF, 0xED, 0x2F, 0x90, 0x8A, 0xFA, +0xF0, 0x90, 0x00, 0x04, 0x12, 0x42, 0x20, 0xFF, 0xAE, 0x05, 0xED, 0x2F, 0x90, 0x8A, 0xFB, 0xF0, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x8B, 0xE4, 0x90, +0x8A, 0xDD, 0xF0, 0x12, 0x29, 0xD9, 0xC3, 0x13, 0x20, 0xE0, 0x02, 0xA1, 0x62, 0x90, 0x8A, 0xDA, +0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, 0x54, 0x02, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0x54, 0xFD, +0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, 0xEE, 0x54, 0xFE, 0x4F, 0xFF, 0xF0, 0x12, 0x29, 0xD9, +0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, 0xEE, 0x54, 0x10, +0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x29, 0xD9, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, +0xDF, 0x4D, 0xFF, 0x90, 0x8B, 0x32, 0xF0, 0xEE, 0x54, 0x40, 0xFE, 0xEF, 0x54, 0xBF, 0x4E, 0xF0, +0x20, 0xE0, 0x02, 0xA1, 0x4F, 0x90, 0x8A, 0xDD, 0x74, 0x21, 0xF0, 0x90, 0x8A, 0xDA, 0x12, 0x43, +0x6B, 0x12, 0x29, 0xD9, 0xFF, 0x13, 0x13, 0x54, 0x01, 0xFE, 0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, +0x13, 0x54, 0x01, 0x6E, 0x60, 0x2A, 0xEF, 0x54, 0x04, 0xFF, 0xED, 0x54, 0xFB, 0x4F, 0xF0, 0xE0, +0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0E, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, +0x12, 0x36, 0xE6, 0x80, 0x0B, 0xE4, 0x90, 0x8B, 0x34, 0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x36, 0x75, +0x90, 0x8B, 0x32, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, +0xE0, 0x44, 0x12, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, +0x14, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, +0xE0, 0x44, 0x80, 0xF0, 0x90, 0x8B, 0x32, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x07, +0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0x90, 0x05, 0x27, 0xF0, 0x90, +0x8B, 0x33, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x4E, 0x89, 0x90, 0x8B, 0x32, 0xE0, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x30, 0xE0, 0x04, 0x7F, 0x03, 0x80, 0x0E, 0x7F, 0x01, 0x12, 0x4D, 0xE0, 0xEF, +0x60, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0x4E, 0x89, 0x7F, 0x02, 0xC1, 0xA4, 0x90, +0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27, 0xF0, 0xE4, 0xFF, 0x12, 0x4E, 0x89, 0x7F, 0x03, +0xC1, 0xA4, 0x90, 0x8A, 0xDA, 0x12, 0x43, 0x6B, 0x12, 0x29, 0xD9, 0xFF, 0x54, 0x02, 0xFE, 0x90, +0x8B, 0x2C, 0xE0, 0x54, 0xFD, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x01, 0xFF, 0xEE, 0x54, 0xFE, 0x4F, +0xFF, 0xF0, 0x12, 0x29, 0xD9, 0xFE, 0x54, 0x08, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, 0x90, 0x8B, +0x2C, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x29, 0xD9, 0xFE, +0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0x4D, 0xFF, 0x90, 0x8B, 0x2C, 0xF0, 0xEE, 0x54, 0x04, 0xFE, +0xEF, 0x54, 0xFB, 0x4E, 0xF0, 0x20, 0xE0, 0x02, 0xC1, 0x57, 0x90, 0x8A, 0xDD, 0x74, 0x31, 0xF0, +0x90, 0x8B, 0x2C, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x20, 0xE0, 0x0B, 0xE4, 0x90, 0x8B, 0x2E, 0xF0, +0x7D, 0x40, 0xFF, 0x12, 0x36, 0x75, 0x90, 0x8B, 0x2C, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, +0x30, 0xE0, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x02, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, +0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0x54, 0x06, 0x60, 0x0C, +0x90, 0x01, 0x3E, 0x74, 0x03, 0xF0, 0xFD, 0x7F, 0x02, 0x12, 0x37, 0x00, 0x90, 0x8A, 0xDD, 0xE0, +0x90, 0x05, 0x27, 0xF0, 0x90, 0x8B, 0x2C, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, +0x0D, 0xA3, 0xE0, 0x64, 0x06, 0x60, 0x2C, 0x7F, 0x06, 0x12, 0x7B, 0x49, 0x80, 0x25, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x06, 0x1B, 0x7F, 0x01, 0x12, 0x7B, 0x49, 0xE4, 0xFF, 0x12, 0x4D, 0xE0, 0xEF, +0x60, 0x09, 0x7D, 0x01, 0xAF, 0x23, 0x12, 0x45, 0xA2, 0x80, 0x05, 0x12, 0x4E, 0x56, 0x80, 0x03, +0x12, 0x66, 0x20, 0x7F, 0x01, 0x80, 0x4D, 0x90, 0x8A, 0xDD, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27, +0xF0, 0x7D, 0x03, 0x7F, 0x02, 0x12, 0x36, 0x92, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x06, 0x02, 0x80, +0x1B, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x02, 0x80, 0x07, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, +0x04, 0xE4, 0xFF, 0x80, 0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0x80, 0x09, +0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x05, 0x7F, 0x01, 0x12, 0x7B, 0x49, 0x12, 0x66, 0x13, 0x12, +0x4A, 0xFC, 0x7F, 0x03, 0xD1, 0xAB, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAD, 0x07, 0xEF, 0x64, 0x01, +0x60, 0x04, 0xEF, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x32, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFB, 0xF0, +0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xED, 0x64, 0x02, 0x60, 0x04, +0xED, 0xB4, 0x03, 0x15, 0x90, 0x8B, 0x2C, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFB, 0xF0, 0xE4, 0xA3, +0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x38, +0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x8A, 0xFD, 0xE0, 0x90, 0x8A, 0xE8, +0xF0, 0x90, 0x8A, 0xFE, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x8A, 0xE9, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, +0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, +0x8B, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xEB, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEE, +0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x04, 0xDA, 0x90, 0x8A, 0xE8, 0xE0, 0x12, +0x43, 0x94, 0x77, 0x61, 0x00, 0x78, 0xD7, 0x01, 0x77, 0x6C, 0x02, 0x77, 0x6C, 0x03, 0x77, 0x6C, +0x04, 0x78, 0xD7, 0x05, 0x78, 0xA1, 0x80, 0x78, 0xBA, 0x81, 0x78, 0xD7, 0x82, 0x00, 0x00, 0x78, +0xD3, 0x90, 0x8A, 0xEE, 0xE0, 0xFF, 0x12, 0x7E, 0x6E, 0x02, 0x78, 0xD7, 0x90, 0x8A, 0xE8, 0xE0, +0xFF, 0xB4, 0x02, 0x08, 0x90, 0x8A, 0xE5, 0x74, 0x01, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x8A, 0xE5, +0xB4, 0x03, 0x05, 0x74, 0x02, 0xF0, 0x80, 0x03, 0x74, 0x04, 0xF0, 0xC3, 0x90, 0x8A, 0xE9, 0xE0, +0x94, 0x08, 0x50, 0x79, 0xE4, 0x90, 0x8A, 0xE4, 0xF0, 0x90, 0x8A, 0xE5, 0xE0, 0xFF, 0x90, 0x8A, +0xE4, 0xE0, 0xC3, 0x9F, 0x40, 0x03, 0x02, 0x78, 0xD7, 0x90, 0x8A, 0xE9, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0xC3, 0xEE, 0x94, 0x01, 0x90, 0x8A, 0xE4, 0xE0, 0x50, 0x1F, 0xFE, 0x2F, 0xFF, 0xEE, 0xFD, +0xC3, 0x74, 0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, 0xF5, 0x82, 0x74, 0x8A, +0x3C, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x51, 0xFB, 0x80, 0x2B, 0xFF, 0xFD, 0xC3, 0x74, 0x03, 0x9D, +0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x74, 0xEB, 0x2D, 0xF5, 0x82, 0x74, 0x8A, 0x3C, 0xF5, 0x83, 0xE0, +0xFE, 0xEF, 0xFD, 0x90, 0x8A, 0xEA, 0xE0, 0x2D, 0xFD, 0x90, 0x8A, 0xE9, 0xE0, 0x34, 0x00, 0x8D, +0x82, 0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x8A, 0xE4, 0xE0, 0x04, 0xF0, 0x80, 0x8C, 0xC3, 0x90, 0x8A, +0xE9, 0xE0, 0x94, 0x10, 0x40, 0x02, 0x01, 0xD7, 0x90, 0x8A, 0xE8, 0xE0, 0x64, 0x04, 0x60, 0x02, +0x01, 0xD7, 0x90, 0x8A, 0xEC, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x10, 0x12, 0x2A, 0x6C, +0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xEB, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, +0xFE, 0x78, 0x18, 0x12, 0x2A, 0x6C, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x43, +0x46, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x8A, 0xED, 0xE0, 0xFF, 0xE4, 0xFC, +0xFD, 0xFE, 0x78, 0x08, 0x12, 0x2A, 0x6C, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, +0x43, 0x46, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0xA3, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, +0xFE, 0x12, 0x43, 0x46, 0xA3, 0x12, 0x2A, 0x7F, 0x90, 0x8A, 0xEF, 0x12, 0x43, 0x53, 0x90, 0x80, +0x85, 0x12, 0x2A, 0x7F, 0x90, 0x8A, 0xE9, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x2F, 0xD9, 0x80, +0x36, 0x90, 0x8A, 0xED, 0xE0, 0xFE, 0xA3, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x8A, +0xE6, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x37, 0x54, 0x80, 0x1D, 0x90, 0x8A, 0xED, 0xE0, 0xFE, 0xA3, +0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x8A, 0xE6, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x36, +0xCB, 0x80, 0x04, 0x7F, 0x00, 0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x8A, 0xDD, 0xF0, 0xA3, 0x74, 0x04, 0xF0, 0xA3, 0xE4, +0xF0, 0x90, 0x8A, 0xE2, 0xF0, 0xA3, 0xF0, 0x90, 0x02, 0x09, 0xE0, 0x90, 0x8A, 0xE1, 0xF0, 0x12, +0x29, 0xD9, 0xFF, 0x90, 0x8A, 0xE1, 0xE0, 0x2F, 0x90, 0x8A, 0xE0, 0xF0, 0x30, 0xE0, 0x0B, 0x90, +0x8A, 0xDB, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x80, 0x07, 0xE4, 0x90, 0x8A, 0xDB, 0xF0, 0xA3, +0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0x90, 0x8A, 0xDD, 0xE0, 0x24, +0x20, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFC, 0x2D, 0xFF, 0x24, 0x01, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x90, 0x8A, 0xFD, 0xF0, 0x74, 0x02, 0x2F, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0xEC, 0x2D, 0x24, 0x03, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0x24, 0x00, 0xFF, 0xE4, 0x3E, 0x90, 0x8A, 0xFE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x8A, 0xDA, 0x74, 0x04, 0xF0, 0x90, 0x8A, 0xDB, 0xA3, 0xE0, 0xFF, 0xA3, 0xE0, 0x2F, 0xFF, 0x90, +0x8A, 0xDA, 0xE0, 0xFE, 0x2F, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, +0x74, 0xFC, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x8A, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x8A, 0xDA, 0xE0, +0x04, 0xF0, 0xE0, 0xB4, 0x08, 0xCF, 0x12, 0x76, 0xF2, 0xEF, 0x70, 0x45, 0x90, 0x01, 0xC3, 0xE0, +0x60, 0x2B, 0xC3, 0x90, 0x8A, 0xE3, 0xE0, 0x94, 0xE8, 0x90, 0x8A, 0xE2, 0xE0, 0x94, 0x03, 0x40, +0x09, 0x90, 0x01, 0xC6, 0xE0, 0x44, 0x10, 0xF0, 0x80, 0x79, 0x90, 0x8A, 0xE2, 0xE4, 0x75, 0xF0, +0x01, 0x12, 0x42, 0x81, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x37, 0x54, 0x80, 0xCF, 0x90, 0x01, 0xC6, +0xE0, 0x90, 0x01, 0xC3, 0x30, 0xE2, 0x05, 0x74, 0xFE, 0xF0, 0x80, 0x57, 0x74, 0xFF, 0xF0, 0x80, +0x52, 0x90, 0x8A, 0xDD, 0xE0, 0xB4, 0x78, 0x2E, 0xE4, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0x04, 0xF0, +0x90, 0x8A, 0xDB, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x80, 0x90, 0x8A, 0xDB, 0x70, 0x05, 0xF0, +0xA3, 0xF0, 0x80, 0x06, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0x90, 0x8A, 0xE0, 0xE0, 0xC3, 0x13, +0x90, 0xFD, 0x10, 0xF0, 0x80, 0x07, 0x90, 0x8A, 0xDD, 0xE0, 0x24, 0x08, 0xF0, 0x90, 0x8A, 0xDE, +0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x42, 0x81, 0x90, 0x8A, 0xDE, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x60, +0x02, 0x21, 0x32, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x29, 0xD9, 0x90, 0x8B, 0x05, 0xF0, 0x90, +0x00, 0x01, 0x12, 0x42, 0x20, 0x90, 0x8B, 0x06, 0xF0, 0x22, 0xE4, 0xF5, 0x61, 0x22, 0x51, 0x67, +0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x7F, 0x78, 0x7E, +0x08, 0x12, 0x27, 0xDE, 0x90, 0x8B, 0x1C, 0x12, 0x2A, 0x7F, 0x7F, 0x04, 0x7E, 0x0C, 0x12, 0x27, +0xDE, 0x90, 0x8B, 0x20, 0x12, 0x2A, 0x7F, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x27, 0xDE, 0x90, 0x8B, +0x24, 0x12, 0x2A, 0x7F, 0x90, 0x8B, 0x09, 0xE0, 0x90, 0x8B, 0x1C, 0xB4, 0x01, 0x0D, 0x12, 0x43, +0x53, 0xEF, 0x54, 0xC7, 0xFF, 0xED, 0x54, 0xC7, 0xFD, 0x80, 0x07, 0x12, 0x43, 0x53, 0xEF, 0x54, +0xC7, 0xFF, 0xEC, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x78, 0x7E, 0x08, 0x12, 0x2F, 0xD9, +0x90, 0x8B, 0x20, 0x12, 0x43, 0x53, 0xEF, 0x54, 0x0F, 0xFF, 0xEC, 0x90, 0x80, 0x85, 0x12, 0x2A, +0x7F, 0x7F, 0x04, 0x7E, 0x0C, 0x12, 0x2F, 0xD9, 0x90, 0x8B, 0x24, 0x12, 0x43, 0x53, 0xEF, 0x44, +0x02, 0xFF, 0xEC, 0x90, 0x80, 0x85, 0x12, 0x2A, 0x7F, 0x7F, 0x00, 0x7E, 0x08, 0x12, 0x2F, 0xD9, +0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x27, 0xDE, 0x90, 0x8B, 0x28, 0x12, 0x2A, 0x7F, 0x90, 0x80, 0x85, +0x12, 0x2A, 0x8B, 0x00, 0x1B, 0x25, 0xA0, 0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2F, 0xD9, 0x90, 0x80, +0x59, 0x12, 0x2A, 0x8B, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x34, 0x81, 0x90, 0x8B, +0x09, 0xE0, 0xB4, 0x01, 0x11, 0x90, 0x80, 0x59, 0x12, 0x2A, 0x8B, 0x00, 0x00, 0x00, 0x00, 0xE4, +0xFD, 0x7F, 0x01, 0x12, 0x34, 0x81, 0x22, 0x51, 0x6D, 0x90, 0x8B, 0x33, 0x74, 0x02, 0xF0, 0x22, +0x51, 0x67, 0x90, 0x8B, 0x2D, 0x74, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0xA1, 0x15, 0xEF, 0x12, 0x43, 0x94, 0x7B, 0x77, +0x00, 0x7B, 0xB1, 0x01, 0x7B, 0xF7, 0x02, 0x7C, 0x31, 0x03, 0x7C, 0x69, 0x04, 0x7C, 0xA2, 0x05, +0x7C, 0xDD, 0x06, 0x00, 0x00, 0x7D, 0x15, 0xEE, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xB1, 0x48, 0xA1, +0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xFF, 0xB4, 0x05, 0x04, 0xB1, 0x24, 0xA1, 0x15, 0xEF, 0xB4, 0x06, +0x06, 0x7F, 0x01, 0xB1, 0x39, 0x80, 0x16, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x03, 0x06, 0x7F, 0x01, +0xB1, 0x1A, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xB1, 0x2E, 0xB1, 0x6B, 0xA1, +0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xB1, 0x48, 0x80, 0x09, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xB1, 0x24, 0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xB1, 0x61, 0xA1, +0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0x7F, 0x01, 0xB1, 0x39, 0xA1, 0x15, 0xEE, +0xB4, 0x03, 0x06, 0x7F, 0x01, 0xB1, 0x1A, 0xA1, 0x15, 0x90, 0x8B, 0x2D, 0xE0, 0x64, 0x02, 0x60, +0x02, 0xA1, 0x15, 0xB1, 0x2E, 0xA1, 0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, +0xB1, 0x48, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xB1, 0x24, 0x90, 0x8B, 0x2D, +0xE0, 0x70, 0x04, 0xB1, 0x61, 0x80, 0x16, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0x7F, +0x01, 0xB1, 0x39, 0x80, 0x08, 0xEE, 0xB4, 0x03, 0x04, 0x7F, 0x01, 0xB1, 0x1A, 0xB1, 0x8D, 0xA1, +0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xB1, 0x48, 0x80, 0x09, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xB1, 0x24, 0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xB1, 0x61, 0x80, +0x14, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xB1, 0x39, 0x80, 0x06, 0xEE, +0xB4, 0x02, 0x02, 0xB1, 0x2E, 0xB1, 0x76, 0xA1, 0x15, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, +0x06, 0xE4, 0xFF, 0xB1, 0x39, 0x80, 0x13, 0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xB1, 0x1A, 0x80, +0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, 0x02, 0xB1, 0x2E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, +0x04, 0xB1, 0x6B, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, 0x02, 0xB1, 0x24, 0x71, 0x40, +0x80, 0x73, 0x90, 0x8B, 0x2D, 0xE0, 0xFE, 0xB4, 0x06, 0x06, 0xE4, 0xFF, 0xB1, 0x39, 0x80, 0x13, +0xEE, 0xB4, 0x03, 0x06, 0x7F, 0x01, 0xB1, 0x1A, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, +0x02, 0xB1, 0x2E, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x01, 0x04, 0xB1, 0x6B, 0x80, 0x0B, 0x90, 0x8B, +0x2D, 0xE0, 0xB4, 0x04, 0x04, 0x7F, 0x01, 0xB1, 0x48, 0xB1, 0x80, 0x80, 0x38, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x04, 0x06, 0x7F, 0x01, 0xB1, 0x48, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x05, +0x02, 0xB1, 0x24, 0x90, 0x8B, 0x2D, 0xE0, 0x70, 0x04, 0xB1, 0x61, 0x80, 0x16, 0x90, 0x8B, 0x2D, +0xE0, 0xB4, 0x03, 0x06, 0xE4, 0xFF, 0xB1, 0x1A, 0x80, 0x09, 0x90, 0x8B, 0x2D, 0xE0, 0xB4, 0x02, +0x02, 0xB1, 0x2E, 0xB1, 0x9A, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x4A, 0xB2, 0x90, 0x8B, 0x2D, +0x74, 0x01, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x90, 0x05, +0x22, 0xE4, 0xF0, 0x90, 0x8B, 0x2D, 0x04, 0xF0, 0x22, 0xEF, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, +0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x22, 0x90, 0x8B, 0x56, 0xEF, 0xF0, 0x12, 0x4F, 0xED, +0x90, 0x8B, 0x56, 0xE0, 0x60, 0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0xE4, 0x90, 0x8B, 0x2D, 0xF0, +0x22, 0x12, 0x4A, 0xCC, 0x90, 0x8B, 0x2D, 0x74, 0x01, 0xF0, 0x22, 0x7F, 0x01, 0x12, 0x4A, 0x7C, +0xE4, 0x90, 0x8B, 0x2D, 0xF0, 0x22, 0x12, 0x4A, 0x32, 0x90, 0x8B, 0x2D, 0x74, 0x03, 0xF0, 0x22, +0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x05, 0xF0, 0x22, 0x90, 0x05, 0x22, +0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x2D, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, +0x90, 0x8B, 0x2D, 0x74, 0x06, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0xFF, 0xF0, 0x90, 0x8B, 0x33, +0x74, 0x04, 0xF0, 0x22, 0x12, 0x4F, 0xED, 0x90, 0x8B, 0x33, 0x74, 0x04, 0xF0, 0x22, 0x90, 0x01, +0x57, 0xE0, 0x60, 0x3C, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, +0x8B, 0x1B, 0xE0, 0x60, 0x07, 0xE4, 0xF0, 0x53, 0x25, 0xFD, 0x80, 0x24, 0x90, 0x8B, 0x0C, 0xE0, +0x04, 0xF0, 0x53, 0x25, 0xEF, 0x90, 0x8B, 0x10, 0xE0, 0xFF, 0x90, 0x8B, 0x0C, 0xE0, 0xD3, 0x9F, +0x40, 0x0E, 0xE5, 0x21, 0xB4, 0x01, 0x09, 0x90, 0x8B, 0x0D, 0xE0, 0x70, 0x03, 0xE0, 0x04, 0xF0, +0x90, 0x01, 0x5B, 0xE0, 0x60, 0x10, 0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x04, +0xF0, 0xE4, 0x90, 0x8B, 0x18, 0xF0, 0x90, 0x01, 0x5F, 0xE0, 0x60, 0x10, 0x90, 0x01, 0x5F, 0xE4, +0xF0, 0x90, 0x01, 0x3C, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x8B, 0x17, 0xF0, 0x22, 0xE4, 0x90, 0x8B, +0x4F, 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, 0x8B, 0x50, 0xE0, 0x94, 0xE8, +0x90, 0x8B, 0x4F, 0xE0, 0x94, 0x03, 0x40, 0x03, 0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, +0x37, 0x54, 0x90, 0x8B, 0x4F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x42, 0x81, 0x80, 0xC6, 0x8F, 0x0F, +0xE4, 0x90, 0x8A, 0xF3, 0xF0, 0xE5, 0x0F, 0x14, 0xFE, 0x90, 0x8A, 0xF3, 0xE0, 0xFF, 0xC3, 0x9E, +0x50, 0x0E, 0xEF, 0x04, 0xFD, 0x12, 0x34, 0xB7, 0x90, 0x8A, 0xF3, 0xE0, 0x04, 0xF0, 0x80, 0xE5, +0xE5, 0x0F, 0x14, 0xFF, 0x7D, 0xFF, 0x12, 0x34, 0xB7, 0x90, 0x8A, 0xF3, 0xE5, 0x0F, 0xF0, 0x90, +0x8A, 0xF3, 0xE0, 0xC3, 0x94, 0xFF, 0x50, 0x0F, 0xE0, 0xFF, 0x04, 0xFD, 0x12, 0x34, 0xB7, 0x90, +0x8A, 0xF3, 0xE0, 0x04, 0xF0, 0x80, 0xE8, 0xAD, 0x0F, 0x7F, 0xFF, 0x02, 0x34, 0xB7, 0xDC, 0xD3, +}; +#endif + +//8188C_Formal_All_PHYforMP_111117 2011-11-23 +//8192C_Formal_92CU_PHYforMP_110817 2011-11-23 + +u32 Rtl8192CUPHY_REG_2TArray[PHY_REG_2TArrayLength] = { +0x024,0x0011800f, +0x028,0x00ffdb83, +0x800,0x80040002, +0x804,0x00000003, +0x808,0x0000fc00, +0x80c,0x0000000a, +0x810,0x10000330, //for Broadcom AP IOT +0x814,0x020c3d10, +0x818,0x02200385, +0x81c,0x00000000, +0x820,0x01000100, +0x824,0x00390004, +0x828,0x01000100, +0x82c,0x00390004, +0x830,0x27272727, +0x834,0x27272727, +0x838,0x27272727, +0x83c,0x27272727, +0x840,0x00010000, +0x844,0x00010000, +0x848,0x27272727, +0x84c,0x27272727, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x569a569a, +0x85c,0x0c1b25a4, +0x860,0x66e60230, +0x864,0x061f0130, +0x868,0x27272727, +0x86c,0x2b2b2b27, +0x870,0x07000700, +0x874,0x22184000, +0x878,0x08080808, +0x87c,0x00000000, +0x880,0xc0083070, +0x884,0x000004d5, +0x888,0x00000000, +0x88c,0xcc0000c0, +0x890,0x00000800, +0x894,0xfffffffe, +0x898,0x40302010, +0x89c,0x00706050, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x81121313, +0xa00,0x00d047c8, +0xa04,0x80ff000c, +0xa08,0x8c838300, +0xa0c,0x2e68120f, +0xa10,0x9500bb78, +0xa14,0x11144028, +0xa18,0x00881117, +0xa1c,0x89140f00, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00d30000, +0xa70,0x101fbf00, +0xa74,0x00000007, +0xc00,0x48071d40, +0xc04,0x03a05633, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08800000, +0xc1c,0x40000100, +0xc20,0x00000000, +0xc24,0x00000000, +0xc28,0x00000000, +0xc2c,0x00000000, +0xc30,0x69e9ac44, +0xc34,0x469652cf, +0xc38,0x49795994, +0xc3c,0x0a97971c, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020107, +0xc4c,0x007f037f, +0xc50,0x69543420, +0xc54,0x43bc0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x00000000, +0xc64,0x5116848b, +0xc68,0x47c00bff, +0xc6c,0x00000036, +0xc70,0x2c7f000d, +0xc74,0x2186115b, +0xc78,0x0000001f, +0xc7c,0x00b99612, +0xc80,0x40000100, +0xc84,0x20f60000, +0xc88,0x40000100, +0xc8c,0xa0e40000, +0xc90,0x00121820, +0xc94,0x00000000, +0xc98,0x00121820, +0xc9c,0x00007f7f, +0xca0,0x00000000, +0xca4,0x00000080, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x28000000, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xce4,0x00000000, +0xce8,0x37644302, +0xcec,0x2f97d40c, +0xd00,0x00080740, +0xd04,0x00020403, +0xd08,0x0000907f, +0xd0c,0x20010201, +0xd10,0xa0633333, +0xd14,0x3333bc43, +0xd18,0x7a8f5b6b, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x80608000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x00000000, +0xd58,0x00000000, +0xd5c,0x30032064, +0xd60,0x4653de68, +0xd64,0x04518a3c, +0xd68,0x00002101, +0xd6c,0x2a201c16, +0xd70,0x1812362e, +0xd74,0x322c2220, +0xd78,0x000e3c24, +0xe00,0x2a2a2a2a, +0xe04,0x2a2a2a2a, +0xe08,0x03902a2a, +0xe10,0x2a2a2a2a, +0xe14,0x2a2a2a2a, +0xe18,0x2a2a2a2a, +0xe1c,0x2a2a2a2a, +0xe28,0x00000000, +0xe30,0x1000dc1f, +0xe34,0x10008c1f, +0xe38,0x02140102, +0xe3c,0x681604c2, +0xe40,0x01007c00, +0xe44,0x01004800, +0xe48,0xfb000000, +0xe4c,0x000028d1, +0xe50,0x1000dc1f, +0xe54,0x10008c1f, +0xe58,0x02140102, +0xe5c,0x28160d05, +0xe60,0x00000010, +0xe68,0x001b25a4, +0xe6c,0x63db25a4, +0xe70,0x63db25a4, +0xe74,0x0c1b25a4, +0xe78,0x0c1b25a4, +0xe7c,0x0c1b25a4, +0xe80,0x0c1b25a4, +0xe84,0x63db25a4, +0xe88,0x0c1b25a4, +0xe8c,0x63db25a4, +0xed0,0x63db25a4, +0xed4,0x63db25a4, +0xed8,0x63db25a4, +0xedc,0x001b25a4, +0xee0,0x001b25a4, +0xeec,0x6fdb25a4, +0xf14,0x00000003, +0xf4c,0x00000000, +0xf00,0x00000300, +}; + +u32 Rtl8192CUPHY_REG_1TArray[PHY_REG_1TArrayLength] = { +0x024,0x0011800f, +0x028,0x00ffdb83, +0x800,0x80040000, +0x804,0x00000001, +0x808,0x0000fc00, +0x80c,0x0000000a, +0x810,0x10000330, //for Broadcom AP IOT +0x814,0x020c3d10, +0x818,0x02200385, +0x81c,0x00000000, +0x820,0x01000100, +0x824,0x00390004, +0x828,0x00000000, +0x82c,0x00000000, +0x830,0x00000000, +0x834,0x00000000, +0x838,0x00000000, +0x83c,0x00000000, +0x840,0x00010000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x569a569a, +0x85c,0x001b25a4, +0x860,0x66e60230, +0x864,0x061f0130, +0x868,0x00000000, +0x86c,0x32323200, +0x870,0x07000700, +0x874,0x22004000, +0x878,0x00000808, +0x87c,0x00000000, +0x880,0xc0083070, +0x884,0x000004d5, +0x888,0x00000000, +0x88c,0xccc000c0, +0x890,0x00000800, +0x894,0xfffffffe, +0x898,0x40302010, +0x89c,0x00706050, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x81121111, +0xa00,0x00d047c8, +0xa04,0x80ff000c, +0xa08,0x8c838300, +0xa0c,0x2e68120f, +0xa10,0x9500bb78, +0xa14,0x11144028, +0xa18,0x00881117, +0xa1c,0x89140f00, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00d30000, +0xa70,0x101fbf00, +0xa74,0x00000007, +0xc00,0x48071d40, +0xc04,0x03a05611, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08800000, +0xc1c,0x40000100, +0xc20,0x00000000, +0xc24,0x00000000, +0xc28,0x00000000, +0xc2c,0x00000000, +0xc30,0x69e9ac44, +0xc34,0x469652cf, +0xc38,0x49795994, +0xc3c,0x0a97971c, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020107, +0xc4c,0x007f037f, +0xc50,0x69543420, +0xc54,0x43bc0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x00000000, +0xc64,0x5116848b, +0xc68,0x47c00bff, +0xc6c,0x00000036, +0xc70,0x2c7f000d, +0xc74,0x018610db, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x20f60000, +0xc88,0x40000100, +0xc8c,0x20200000, +0xc90,0x00121820, +0xc94,0x00000000, +0xc98,0x00121820, +0xc9c,0x00007f7f, +0xca0,0x00000000, +0xca4,0x00000080, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x28000000, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xce4,0x00000000, +0xce8,0x37644302, +0xcec,0x2f97d40c, +0xd00,0x00000740, +0xd04,0x00020401, +0xd08,0x0000907f, +0xd0c,0x20010201, +0xd10,0xa0633333, +0xd14,0x3333bc43, +0xd18,0x7a8f5b6b, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x80608000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x00000000, +0xd58,0x00000000, +0xd5c,0x30032064, +0xd60,0x4653de68, +0xd64,0x04518a3c, +0xd68,0x00002101, +0xd6c,0x2a201c16, +0xd70,0x1812362e, +0xd74,0x322c2220, +0xd78,0x000e3c24, +0xe00,0x2a2a2a2a, +0xe04,0x2a2a2a2a, +0xe08,0x03902a2a, +0xe10,0x2a2a2a2a, +0xe14,0x2a2a2a2a, +0xe18,0x2a2a2a2a, +0xe1c,0x2a2a2a2a, +0xe28,0x00000000, +0xe30,0x1000dc1f, +0xe34,0x10008c1f, +0xe38,0x02140102, +0xe3c,0x681604c2, +0xe40,0x01007c00, +0xe44,0x01004800, +0xe48,0xfb000000, +0xe4c,0x000028d1, +0xe50,0x1000dc1f, +0xe54,0x10008c1f, +0xe58,0x02140102, +0xe5c,0x28160d05, +0xe60,0x00000008, +0xe68,0x001b25a4, +0xe6c,0x631b25a0, +0xe70,0x631b25a0, +0xe74,0x081b25a0, +0xe78,0x081b25a0, +0xe7c,0x081b25a0, +0xe80,0x081b25a0, +0xe84,0x631b25a0, +0xe88,0x081b25a0, +0xe8c,0x631b25a0, +0xed0,0x631b25a0, +0xed4,0x631b25a0, +0xed8,0x631b25a0, +0xedc,0x001b25a0, +0xee0,0x001b25a0, +0xeec,0x6b1b25a0, +0xf14,0x00000003, +0xf4c,0x00000000, +0xf00,0x00000300, +}; + +u32 Rtl8192CUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength] = { +0x0, }; + +u32 Rtl8192CUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength] = { +0x0, }; + +u32 Rtl8192CUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength] = { +0x0, }; + +u32 Rtl8192CUPHY_REG_Array_PG[PHY_REG_Array_PGLength] = { +0xe00,0xffffffff,0x07090c0c, +0xe04,0xffffffff,0x01020405, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x0b0c0c0e, +0xe14,0xffffffff,0x01030506, +0xe18,0xffffffff,0x0b0c0d0e, +0xe1c,0xffffffff,0x01030509, +0x830,0xffffffff,0x07090c0c, +0x834,0xffffffff,0x01020405, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x0b0c0d0e, +0x848,0xffffffff,0x01030509, +0x84c,0xffffffff,0x0b0c0d0e, +0x868,0xffffffff,0x01030509, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x04040404, +0xe04,0xffffffff,0x00020204, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x06060606, +0xe14,0xffffffff,0x00020406, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x04040404, +0x834,0xffffffff,0x00020204, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x06060606, +0x848,0xffffffff,0x00020406, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x04040404, +0xe04,0xffffffff,0x00020204, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x04040404, +0x834,0xffffffff,0x00020204, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +}; + +u32 Rtl8192CUPHY_REG_Array_PG_mCard[PHY_REG_Array_PG_mCardLength] = { +0xe00,0xffffffff,0x0a0c0c0c, +0xe04,0xffffffff,0x02040608, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x0a0c0d0e, +0xe14,0xffffffff,0x02040608, +0xe18,0xffffffff,0x0a0c0d0e, +0xe1c,0xffffffff,0x02040608, +0x830,0xffffffff,0x0a0c0c0c, +0x834,0xffffffff,0x02040608, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x0a0c0d0e, +0x848,0xffffffff,0x02040608, +0x84c,0xffffffff,0x0a0c0d0e, +0x868,0xffffffff,0x02040608, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x04040404, +0xe04,0xffffffff,0x00020204, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x06060606, +0xe14,0xffffffff,0x00020406, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x04040404, +0x834,0xffffffff,0x00020204, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x06060606, +0x848,0xffffffff,0x00020406, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x04040404, +0xe04,0xffffffff,0x00020204, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x04040404, +0x834,0xffffffff,0x00020204, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +}; + +u32 Rtl8192CUPHY_REG_Array_MP[PHY_REG_Array_MPLength] = { +0xc30,0x69e9ac4a, +0xc3c,0x0a979718, +}; + +u32 Rtl8192CUPHY_REG_1T_HPArray[PHY_REG_1T_HPArrayLength] = { +0x024,0x0011800f, +0x028,0x00ffdb83, +0x040,0x000c0004, +0x800,0x80040000, +0x804,0x00000001, +0x808,0x0000fc00, +0x80c,0x0000000a, +0x810,0x10000330, //for Broadcom AP IOT +0x814,0x020c3d10, +0x818,0x02200385, +0x81c,0x00000000, +0x820,0x01000100, +0x824,0x00390204, +0x828,0x00000000, +0x82c,0x00000000, +0x830,0x00000000, +0x834,0x00000000, +0x838,0x00000000, +0x83c,0x00000000, +0x840,0x00010000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x569a569a, +0x85c,0x001b25a4, +0x860,0x66e60230, +0x864,0x061f0130, +0x868,0x00000000, +0x86c,0x20202000, +0x870,0x03000300, +0x874,0x22004000, +0x878,0x00000808, +0x87c,0x00ffc3f1, +0x880,0xc0083070, +0x884,0x000004d5, +0x888,0x00000000, +0x88c,0xccc000c0, +0x890,0x00000800, +0x894,0xfffffffe, +0x898,0x40302010, +0x89c,0x00706050, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x81121111, +0xa00,0x00d047c8, +0xa04,0x80ff000c, +0xa08,0x8c838300, +0xa0c,0x2e68120f, +0xa10,0x9500bb78, +0xa14,0x11144028, +0xa18,0x00881117, +0xa1c,0x89140f00, +0xa20,0x15160000, +0xa24,0x070b0f12, +0xa28,0x00000104, +0xa2c,0x00d30000, +0xa70,0x101fbf00, +0xa74,0x00000007, +0xc00,0x48071d40, +0xc04,0x03a05611, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08800000, +0xc1c,0x40000100, +0xc20,0x00000000, +0xc24,0x00000000, +0xc28,0x00000000, +0xc2c,0x00000000, +0xc30,0x69e9ac44, +0xc34,0x469652cf, +0xc38,0x49795994, +0xc3c,0x0a97971c, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020107, +0xc4c,0x007f037f, +0xc50,0x6954342e, +0xc54,0x43bc0094, +0xc58,0x6954342f, +0xc5c,0x433c0094, +0xc60,0x00000000, +0xc64,0x5116848b, +0xc68,0x47c00bff, +0xc6c,0x00000036, +0xc70,0x2c46000d, +0xc74,0x018610db, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x24000090, +0xc84,0x20f60000, +0xc88,0x24000090, +0xc8c,0x20200000, +0xc90,0x00121820, +0xc94,0x00000000, +0xc98,0x00121820, +0xc9c,0x00007f7f, +0xca0,0x00000000, +0xca4,0x00000080, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x28000000, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xce4,0x00000000, +0xce8,0x37644302, +0xcec,0x2f97d40c, +0xd00,0x00000740, +0xd04,0x00020401, +0xd08,0x0000907f, +0xd0c,0x20010201, +0xd10,0xa0633333, +0xd14,0x3333bc43, +0xd18,0x7a8f5b6b, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x80608000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x00000000, +0xd58,0x00000000, +0xd5c,0x30032064, +0xd60,0x4653de68, +0xd64,0x04518a3c, +0xd68,0x00002101, +0xd6c,0x2a201c16, +0xd70,0x1812362e, +0xd74,0x322c2220, +0xd78,0x000e3c24, +0xe00,0x24242424, +0xe04,0x24242424, +0xe08,0x03902024, +0xe10,0x24242424, +0xe14,0x24242424, +0xe18,0x24242424, +0xe1c,0x24242424, +0xe28,0x00000000, +0xe30,0x1000dc1f, +0xe34,0x10008c1f, +0xe38,0x02140102, +0xe3c,0x681604c2, +0xe40,0x01007c00, +0xe44,0x01004800, +0xe48,0xfb000000, +0xe4c,0x000028d1, +0xe50,0x1000dc1f, +0xe54,0x10008c1f, +0xe58,0x02140102, +0xe5c,0x28160d05, +0xe60,0x00000008, +0xe68,0x001b25a4, +0xe6c,0x631b25a0, +0xe70,0x631b25a0, +0xe74,0x081b25a0, +0xe78,0x081b25a0, +0xe7c,0x081b25a0, +0xe80,0x081b25a0, +0xe84,0x631b25a0, +0xe88,0x081b25a0, +0xe8c,0x631b25a0, +0xed0,0x631b25a0, +0xed4,0x631b25a0, +0xed8,0x631b25a0, +0xedc,0x001b25a0, +0xee0,0x001b25a0, +0xeec,0x6b1b25a0, +0xee8,0x31555448, +0xf14,0x00000003, +0xf4c,0x00000000, +0xf00,0x00000300, +}; + +u32 Rtl8192CUPHY_REG_1T_mCardArray[PHY_REG_1T_mCardArrayLength] = { +0x024,0x0011800d, +0x028,0x00ffdb83, +0x800,0x80040000, +0x804,0x00000001, +0x808,0x0000fc00, +0x80c,0x0000000a, +0x810,0x10000330, //for Broadcom AP IOT +0x814,0x020c3d10, +0x818,0x02200385, +0x81c,0x00000000, +0x820,0x01000100, +0x824,0x00390004, +0x828,0x00000000, +0x82c,0x00000000, +0x830,0x00000000, +0x834,0x00000000, +0x838,0x00000000, +0x83c,0x00000000, +0x840,0x00010000, +0x844,0x00000000, +0x848,0x00000000, +0x84c,0x00000000, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x569a569a, +0x85c,0x001b25a4, +0x860,0x66e60230, +0x864,0x061f0130, +0x868,0x00000000, +0x86c,0x32323200, +0x870,0x07000700, +0x874,0x22004000, +0x878,0x00000808, +0x87c,0x00000000, +0x880,0xc0083070, +0x884,0x000004d5, +0x888,0x00000000, +0x88c,0xccc000c0, +0x890,0x00000800, +0x894,0xfffffffe, +0x898,0x40302010, +0x89c,0x00706050, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x81121111, +0xa00,0x00d047c8, +0xa04,0x80ff000c, +0xa08,0x8c838300, +0xa0c,0x2e68120f, +0xa10,0x9500bb78, +0xa14,0x11144028, +0xa18,0x00881117, +0xa1c,0x89140f00, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00d30000, +0xa70,0x101fbf00, +0xa74,0x00000007, +0xc00,0x48071d40, +0xc04,0x03a05611, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08800000, +0xc1c,0x40000100, +0xc20,0x00000000, +0xc24,0x00000000, +0xc28,0x00000000, +0xc2c,0x00000000, +0xc30,0x69e9ac44, +0xc34,0x469652cf, +0xc38,0x49795994, +0xc3c,0x0a97971c, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020107, +0xc4c,0x007f037f, +0xc50,0x69543420, +0xc54,0x43bc0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x00000000, +0xc64,0x5116848b, +0xc68,0x47c00bff, +0xc6c,0x00000036, +0xc70,0x2c7f000d, +0xc74,0x018610db, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x20f60000, +0xc88,0x40000100, +0xc8c,0x20200000, +0xc90,0x00121820, +0xc94,0x00000000, +0xc98,0x00121820, +0xc9c,0x00007f7f, +0xca0,0x00000000, +0xca4,0x00000080, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x28000000, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xce4,0x00000000, +0xce8,0x37644302, +0xcec,0x2f97d40c, +0xd00,0x00000740, +0xd04,0x00020401, +0xd08,0x0000907f, +0xd0c,0x20010201, +0xd10,0xa0633333, +0xd14,0x3333bc43, +0xd18,0x7a8f5b6b, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x80608000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x00000000, +0xd58,0x00000000, +0xd5c,0x30032064, +0xd60,0x4653de68, +0xd64,0x04518a3c, +0xd68,0x00002101, +0xd6c,0x2a201c16, +0xd70,0x1812362e, +0xd74,0x322c2220, +0xd78,0x000e3c24, +0xe00,0x2a2a2a2a, +0xe04,0x2a2a2a2a, +0xe08,0x03902a2a, +0xe10,0x2a2a2a2a, +0xe14,0x2a2a2a2a, +0xe18,0x2a2a2a2a, +0xe1c,0x2a2a2a2a, +0xe28,0x00000000, +0xe30,0x1000dc1f, +0xe34,0x10008c1f, +0xe38,0x02140102, +0xe3c,0x681604c2, +0xe40,0x01007c00, +0xe44,0x01004800, +0xe48,0xfb000000, +0xe4c,0x000028d1, +0xe50,0x1000dc1f, +0xe54,0x10008c1f, +0xe58,0x02140102, +0xe5c,0x28160d05, +0xe60,0x00000008, +0xe68,0x001b25a4, +0xe6c,0x631b25a0, +0xe70,0x631b25a0, +0xe74,0x081b25a0, +0xe78,0x081b25a0, +0xe7c,0x081b25a0, +0xe80,0x081b25a0, +0xe84,0x631b25a0, +0xe88,0x081b25a0, +0xe8c,0x631b25a0, +0xed0,0x631b25a0, +0xed4,0x631b25a0, +0xed8,0x631b25a0, +0xedc,0x001b25a0, +0xee0,0x001b25a0, +0xeec,0x6b1b25a0, +0xf14,0x00000003, +0xf4c,0x00000000, +0xf00,0x00000300, +}; + +u32 Rtl8192CUPHY_REG_2T_mCardArray[PHY_REG_2T_mCardArrayLength] = { +0x024,0x0011800d, +0x028,0x00ffdb83, +0x800,0x80040002, +0x804,0x00000003, +0x808,0x0000fc00, +0x80c,0x0000000a, +0x810,0x10000330, //for Broadcom AP IOT +0x814,0x020c3d10, +0x818,0x02200385, +0x81c,0x00000000, +0x820,0x01000100, +0x824,0x00390004, +0x828,0x01000100, +0x82c,0x00390004, +0x830,0x27272727, +0x834,0x27272727, +0x838,0x27272727, +0x83c,0x27272727, +0x840,0x00010000, +0x844,0x00010000, +0x848,0x27272727, +0x84c,0x27272727, +0x850,0x00000000, +0x854,0x00000000, +0x858,0x569a569a, +0x85c,0x0c1b25a4, +0x860,0x66e60230, +0x864,0x061f0130, +0x868,0x27272727, +0x86c,0x2b2b2b27, +0x870,0x07000700, +0x874,0x22184000, +0x878,0x08080808, +0x87c,0x00000000, +0x880,0xc0083070, +0x884,0x000004d5, +0x888,0x00000000, +0x88c,0xcc0000c0, +0x890,0x00000800, +0x894,0xfffffffe, +0x898,0x40302010, +0x89c,0x00706050, +0x900,0x00000000, +0x904,0x00000023, +0x908,0x00000000, +0x90c,0x81121313, +0xa00,0x00d047c8, +0xa04,0x80ff000c, +0xa08,0x8c838300, +0xa0c,0x2e68120f, +0xa10,0x9500bb78, +0xa14,0x11144028, +0xa18,0x00881117, +0xa1c,0x89140f00, +0xa20,0x1a1b0000, +0xa24,0x090e1317, +0xa28,0x00000204, +0xa2c,0x00d30000, +0xa70,0x101fbf00, +0xa74,0x00000007, +0xc00,0x48071d40, +0xc04,0x03a05633, +0xc08,0x000000e4, +0xc0c,0x6c6c6c6c, +0xc10,0x08800000, +0xc14,0x40000100, +0xc18,0x08800000, +0xc1c,0x40000100, +0xc20,0x00000000, +0xc24,0x00000000, +0xc28,0x00000000, +0xc2c,0x00000000, +0xc30,0x69e9ac44, +0xc34,0x469652cf, +0xc38,0x49795994, +0xc3c,0x0a97971c, +0xc40,0x1f7c403f, +0xc44,0x000100b7, +0xc48,0xec020107, +0xc4c,0x007f037f, +0xc50,0x69543420, +0xc54,0x43bc0094, +0xc58,0x69543420, +0xc5c,0x433c0094, +0xc60,0x00000000, +0xc64,0x5116848b, +0xc68,0x47c00bff, +0xc6c,0x00000036, +0xc70,0x2c7f000d, +0xc74,0x218610db, +0xc78,0x0000001f, +0xc7c,0x00b91612, +0xc80,0x40000100, +0xc84,0x20f60000, +0xc88,0x40000100, +0xc8c,0xa0e40000, +0xc90,0x00121820, +0xc94,0x00000000, +0xc98,0x00121820, +0xc9c,0x00007f7f, +0xca0,0x00000000, +0xca4,0x00000080, +0xca8,0x00000000, +0xcac,0x00000000, +0xcb0,0x00000000, +0xcb4,0x00000000, +0xcb8,0x00000000, +0xcbc,0x28000000, +0xcc0,0x00000000, +0xcc4,0x00000000, +0xcc8,0x00000000, +0xccc,0x00000000, +0xcd0,0x00000000, +0xcd4,0x00000000, +0xcd8,0x64b22427, +0xcdc,0x00766932, +0xce0,0x00222222, +0xce4,0x00000000, +0xce8,0x37644302, +0xcec,0x2f97d40c, +0xd00,0x00080740, +0xd04,0x00020403, +0xd08,0x0000907f, +0xd0c,0x20010201, +0xd10,0xa0633333, +0xd14,0x3333bc43, +0xd18,0x7a8f5b6b, +0xd2c,0xcc979975, +0xd30,0x00000000, +0xd34,0x80608000, +0xd38,0x00000000, +0xd3c,0x00027293, +0xd40,0x00000000, +0xd44,0x00000000, +0xd48,0x00000000, +0xd4c,0x00000000, +0xd50,0x6437140a, +0xd54,0x00000000, +0xd58,0x00000000, +0xd5c,0x30032064, +0xd60,0x4653de68, +0xd64,0x04518a3c, +0xd68,0x00002101, +0xd6c,0x2a201c16, +0xd70,0x1812362e, +0xd74,0x322c2220, +0xd78,0x000e3c24, +0xe00,0x2a2a2a2a, +0xe04,0x2a2a2a2a, +0xe08,0x03902a2a, +0xe10,0x2a2a2a2a, +0xe14,0x2a2a2a2a, +0xe18,0x2a2a2a2a, +0xe1c,0x2a2a2a2a, +0xe28,0x00000000, +0xe30,0x1000dc1f, +0xe34,0x10008c1f, +0xe38,0x02140102, +0xe3c,0x681604c2, +0xe40,0x01007c00, +0xe44,0x01004800, +0xe48,0xfb000000, +0xe4c,0x000028d1, +0xe50,0x1000dc1f, +0xe54,0x10008c1f, +0xe58,0x02140102, +0xe5c,0x28160d05, +0xe60,0x00000010, +0xe68,0x001b25a4, +0xe6c,0x63db25a4, +0xe70,0x63db25a4, +0xe74,0x0c1b25a4, +0xe78,0x0c1b25a4, +0xe7c,0x0c1b25a4, +0xe80,0x0c1b25a4, +0xe84,0x63db25a4, +0xe88,0x0c1b25a4, +0xe8c,0x63db25a4, +0xed0,0x63db25a4, +0xed4,0x63db25a4, +0xed8,0x63db25a4, +0xedc,0x001b25a4, +0xee0,0x001b25a4, +0xeec,0x6fdb25a4, +0xf14,0x00000003, +0xf4c,0x00000000, +0xf00,0x00000300, +}; + +u32 Rtl8192CUPHY_REG_Array_PG_HP[PHY_REG_Array_PG_HPLength] = { +0xe00,0xffffffff,0x06080808, +0xe04,0xffffffff,0x00040406, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x04060608, +0xe14,0xffffffff,0x00020204, +0xe18,0xffffffff,0x04060608, +0xe1c,0xffffffff,0x00020204, +0x830,0xffffffff,0x06080808, +0x834,0xffffffff,0x00040406, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x04060608, +0x848,0xffffffff,0x00020204, +0x84c,0xffffffff,0x04060608, +0x868,0xffffffff,0x00020204, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +0xe00,0xffffffff,0x00000000, +0xe04,0xffffffff,0x00000000, +0xe08,0x0000ff00,0x00000000, +0x86c,0xffffff00,0x00000000, +0xe10,0xffffffff,0x00000000, +0xe14,0xffffffff,0x00000000, +0xe18,0xffffffff,0x00000000, +0xe1c,0xffffffff,0x00000000, +0x830,0xffffffff,0x00000000, +0x834,0xffffffff,0x00000000, +0x838,0xffffff00,0x00000000, +0x86c,0x000000ff,0x00000000, +0x83c,0xffffffff,0x00000000, +0x848,0xffffffff,0x00000000, +0x84c,0xffffffff,0x00000000, +0x868,0xffffffff,0x00000000, +}; + +u32 Rtl8192CURadioA_2TArray[RadioA_2TArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x019,0x00000000, +0x01a,0x00010255, +0x01b,0x00060a00, +0x01c,0x000fc378, +0x01d,0x000a1250, +0x01e,0x0004445f, +0x01f,0x00080001, +0x020,0x0000b614, +0x021,0x0006c000, +0x022,0x00000000, +0x023,0x00001558, +0x024,0x00000060, +0x025,0x00000483, +0x026,0x0004f000, +0x027,0x000ec7d9, +0x028,0x000577c0, +0x029,0x00004783, +0x02a,0x00000001, +0x02b,0x00021334, +0x02a,0x00000000, +0x02b,0x00000054, +0x02a,0x00000001, +0x02b,0x00000808, +0x02b,0x00053333, +0x02c,0x0000000c, +0x02a,0x00000002, +0x02b,0x00000808, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000003, +0x02b,0x00000808, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000004, +0x02b,0x00000808, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x00000005, +0x02b,0x00000808, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x00000006, +0x02b,0x00000709, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000007, +0x02b,0x00000709, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000008, +0x02b,0x0000060a, +0x02b,0x0004b333, +0x02c,0x0000000d, +0x02a,0x00000009, +0x02b,0x0000060a, +0x02b,0x00053333, +0x02c,0x0000000d, +0x02a,0x0000000a, +0x02b,0x0000060a, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x0000000b, +0x02b,0x0000060a, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x0000000c, +0x02b,0x0000060a, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x0000000d, +0x02b,0x0000060a, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x0000000e, +0x02b,0x0000050b, +0x02b,0x00066666, +0x02c,0x0000001a, +0x02a,0x000e0000, +0x010,0x0004000f, +0x011,0x000e31fc, +0x010,0x0006000f, +0x011,0x000ff9f8, +0x010,0x0002000f, +0x011,0x000203f9, +0x010,0x0003000f, +0x011,0x000ff500, +0x010,0x00000000, +0x011,0x00000000, +0x010,0x0008000f, +0x011,0x0003f100, +0x010,0x0009000f, +0x011,0x00023100, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287b3, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x0001429b, +0x013,0x00010299, +0x013,0x0000c29c, +0x013,0x000081a0, +0x013,0x000040ac, +0x013,0x00000020, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f424, +0x015,0x0004f424, +0x015,0x0008f424, +0x015,0x000cf424, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +0x000,0x00010159, +0x018,0x0000f401, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01f,0x00080003, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01e,0x00044457, +0x01f,0x00080000, +0x000,0x00030159, +}; + +u32 Rtl8192CURadioB_2TArray[RadioB_2TArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287af, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x00014297, +0x013,0x00010295, +0x013,0x0000c298, +0x013,0x0000819c, +0x013,0x000040a8, +0x013,0x0000001c, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f424, +0x015,0x0004f424, +0x015,0x0008f424, +0x015,0x000cf424, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +}; + +u32 Rtl8192CURadioA_1TArray[RadioA_1TArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x019,0x00000000, +0x01a,0x00010255, +0x01b,0x00060a00, +0x01c,0x000fc378, +0x01d,0x000a1250, +0x01e,0x0004445f, +0x01f,0x00080001, +0x020,0x0000b614, +0x021,0x0006c000, +0x022,0x00000000, +0x023,0x00001558, +0x024,0x00000060, +0x025,0x00000483, +0x026,0x0004f000, +0x027,0x000ec7d9, +0x028,0x000577c0, +0x029,0x00004783, +0x02a,0x00000001, +0x02b,0x00021334, +0x02a,0x00000000, +0x02b,0x00000054, +0x02a,0x00000001, +0x02b,0x00000808, +0x02b,0x00053333, +0x02c,0x0000000c, +0x02a,0x00000002, +0x02b,0x00000808, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000003, +0x02b,0x00000808, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000004, +0x02b,0x00000808, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x00000005, +0x02b,0x00000808, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x00000006, +0x02b,0x00000709, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000007, +0x02b,0x00000709, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000008, +0x02b,0x0000060a, +0x02b,0x0004b333, +0x02c,0x0000000d, +0x02a,0x00000009, +0x02b,0x0000060a, +0x02b,0x00053333, +0x02c,0x0000000d, +0x02a,0x0000000a, +0x02b,0x0000060a, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x0000000b, +0x02b,0x0000060a, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x0000000c, +0x02b,0x0000060a, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x0000000d, +0x02b,0x0000060a, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x0000000e, +0x02b,0x0000050b, +0x02b,0x00066666, +0x02c,0x0000001a, +0x02a,0x000e0000, +0x010,0x0004000f, +0x011,0x000e31fc, +0x010,0x0006000f, +0x011,0x000ff9f8, +0x010,0x0002000f, +0x011,0x000203f9, +0x010,0x0003000f, +0x011,0x000ff500, +0x010,0x00000000, +0x011,0x00000000, +0x010,0x0008000f, +0x011,0x0003f100, +0x010,0x0009000f, +0x011,0x00023100, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287b3, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x0001429b, +0x013,0x00010299, +0x013,0x0000c29c, +0x013,0x000081a0, +0x013,0x000040ac, +0x013,0x00000020, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f405, +0x015,0x0004f405, +0x015,0x0008f405, +0x015,0x000cf405, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +0x000,0x00010159, +0x018,0x0000f401, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01f,0x00080003, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01e,0x00044457, +0x01f,0x00080000, +0x000,0x00030159, +}; + +u32 Rtl8192CURadioB_1TArray[RadioB_1TArrayLength] = { +0x0, }; + + +u32 Rtl8192CURadioA_2T_mCardArray[RadioA_2T_mCardArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x019,0x00000000, +0x01a,0x00010255, +0x01b,0x00060a00, +0x01c,0x000fc378, +0x01d,0x000a1250, +0x01e,0x0004445f, +0x01f,0x00080001, +0x020,0x0000b614, +0x021,0x0006c000, +0x022,0x00000000, +0x023,0x00001558, +0x024,0x00000060, +0x025,0x00000483, +0x026,0x0004f000, +0x027,0x000ec7d9, +0x028,0x000577c0, +0x029,0x00004783, +0x02a,0x00000001, +0x02b,0x00021334, +0x02a,0x00000000, +0x02b,0x00000054, +0x02a,0x00000001, +0x02b,0x00000808, +0x02b,0x00053333, +0x02c,0x0000000c, +0x02a,0x00000002, +0x02b,0x00000808, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000003, +0x02b,0x00000808, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000004, +0x02b,0x00000808, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x00000005, +0x02b,0x00000808, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x00000006, +0x02b,0x00000709, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000007, +0x02b,0x00000709, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000008, +0x02b,0x0000060a, +0x02b,0x0004b333, +0x02c,0x0000000d, +0x02a,0x00000009, +0x02b,0x0000060a, +0x02b,0x00053333, +0x02c,0x0000000d, +0x02a,0x0000000a, +0x02b,0x0000060a, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x0000000b, +0x02b,0x0000060a, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x0000000c, +0x02b,0x0000060a, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x0000000d, +0x02b,0x0000060a, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x0000000e, +0x02b,0x0000050b, +0x02b,0x00066666, +0x02c,0x0000001a, +0x02a,0x000e0000, +0x010,0x0004000f, +0x011,0x000e31fc, +0x010,0x0006000f, +0x011,0x000ff9f8, +0x010,0x0002000f, +0x011,0x000203f9, +0x010,0x0003000f, +0x011,0x000ff500, +0x010,0x00000000, +0x011,0x00000000, +0x010,0x0008000f, +0x011,0x0003f100, +0x010,0x0009000f, +0x011,0x00023100, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287b3, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x0001429b, +0x013,0x00010299, +0x013,0x0000c29c, +0x013,0x000081a0, +0x013,0x000040ac, +0x013,0x00000020, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f424, +0x015,0x0004f424, +0x015,0x0008f424, +0x015,0x000cf424, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +0x000,0x00010159, +0x018,0x0000f401, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01f,0x00080003, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01e,0x00044457, +0x01f,0x00080000, +0x000,0x00030159, +}; + +u32 Rtl8192CURadioB_2T_mCardArray[RadioB_2T_mCardArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287af, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x00014297, +0x013,0x00010295, +0x013,0x0000c298, +0x013,0x0000819c, +0x013,0x000040a8, +0x013,0x0000001c, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f424, +0x015,0x0004f424, +0x015,0x0008f424, +0x015,0x000cf424, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +}; + +u32 Rtl8192CURadioA_1T_mCardArray[RadioA_1T_mCardArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb1, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e52c, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x019,0x00000000, +0x01a,0x00010255, +0x01b,0x00060a00, +0x01c,0x000fc378, +0x01d,0x000a1250, +0x01e,0x0004445f, +0x01f,0x00080001, +0x020,0x0000b614, +0x021,0x0006c000, +0x022,0x00000000, +0x023,0x00001558, +0x024,0x00000060, +0x025,0x00000483, +0x026,0x0004f200, +0x027,0x000ec7d9, +0x028,0x000577c0, +0x029,0x00004783, +0x02a,0x00000001, +0x02b,0x00021334, +0x02a,0x00000000, +0x02b,0x00000054, +0x02a,0x00000001, +0x02b,0x00000808, +0x02b,0x00053333, +0x02c,0x0000000c, +0x02a,0x00000002, +0x02b,0x00000808, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000003, +0x02b,0x00000808, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000004, +0x02b,0x00000808, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x00000005, +0x02b,0x00000808, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x00000006, +0x02b,0x00000709, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000007, +0x02b,0x00000709, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000008, +0x02b,0x0000060a, +0x02b,0x0004b333, +0x02c,0x0000000d, +0x02a,0x00000009, +0x02b,0x0000060a, +0x02b,0x00053333, +0x02c,0x0000000d, +0x02a,0x0000000a, +0x02b,0x0000060a, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x0000000b, +0x02b,0x0000060a, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x0000000c, +0x02b,0x0000060a, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x0000000d, +0x02b,0x0000060a, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x0000000e, +0x02b,0x0000050b, +0x02b,0x00066666, +0x02c,0x0000001a, +0x02a,0x000e0000, +0x010,0x0004000f, +0x011,0x000e31fc, +0x010,0x0006000f, +0x011,0x000ff9f8, +0x010,0x0002000f, +0x011,0x000203f9, +0x010,0x0003000f, +0x011,0x000ff500, +0x010,0x00000000, +0x011,0x00000000, +0x010,0x0008000f, +0x011,0x0003f100, +0x010,0x0009000f, +0x011,0x00023100, +0x012,0x00032000, +0x012,0x00071000, +0x012,0x000b0000, +0x012,0x000fc000, +0x013,0x000287b3, +0x013,0x000244b7, +0x013,0x000204ab, +0x013,0x0001c49f, +0x013,0x00018493, +0x013,0x0001429b, +0x013,0x00010299, +0x013,0x0000c29c, +0x013,0x000081a0, +0x013,0x000040ac, +0x013,0x00000020, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f424, +0x015,0x0004f424, +0x015,0x0008f424, +0x015,0x000cf424, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +0x000,0x00010159, +0x018,0x0000f401, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01f,0x00080003, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01e,0x00044457, +0x01f,0x00080000, +0x000,0x00030159, +}; + +u32 Rtl8192CURadioB_1T_mCardArray[RadioB_1T_mCardArrayLength] = { +0x0, }; + +u32 Rtl8192CURadioA_1T_HPArray[RadioA_1T_HPArrayLength] = { +0x000,0x00030159, +0x001,0x00031284, +0x002,0x00098000, +0x003,0x00018c63, +0x004,0x000210e7, +0x009,0x0002044f, +0x00a,0x0001adb0, +0x00b,0x00054867, +0x00c,0x0008992e, +0x00d,0x0000e529, +0x00e,0x00039ce7, +0x00f,0x00000451, +0x019,0x00000000, +0x01a,0x00000255, +0x01b,0x00060a00, +0x01c,0x000fc378, +0x01d,0x000a1250, +0x01e,0x0004445f, +0x01f,0x00080001, +0x020,0x0000b614, +0x021,0x0006c000, +0x022,0x0000083c, +0x023,0x00001558, +0x024,0x00000060, +0x025,0x00000483, +0x026,0x0004f000, +0x027,0x000ec7d9, +0x028,0x000977c0, +0x029,0x00004783, +0x02a,0x00000001, +0x02b,0x00021334, +0x02a,0x00000000, +0x02b,0x00000054, +0x02a,0x00000001, +0x02b,0x00000808, +0x02b,0x00053333, +0x02c,0x0000000c, +0x02a,0x00000002, +0x02b,0x00000808, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000003, +0x02b,0x00000808, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000004, +0x02b,0x00000808, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x00000005, +0x02b,0x00000808, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x00000006, +0x02b,0x00000709, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x00000007, +0x02b,0x00000709, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x00000008, +0x02b,0x0000060a, +0x02b,0x0004b333, +0x02c,0x0000000d, +0x02a,0x00000009, +0x02b,0x0000060a, +0x02b,0x00053333, +0x02c,0x0000000d, +0x02a,0x0000000a, +0x02b,0x0000060a, +0x02b,0x0005b333, +0x02c,0x0000000d, +0x02a,0x0000000b, +0x02b,0x0000060a, +0x02b,0x00063333, +0x02c,0x0000000d, +0x02a,0x0000000c, +0x02b,0x0000060a, +0x02b,0x0006b333, +0x02c,0x0000000d, +0x02a,0x0000000d, +0x02b,0x0000060a, +0x02b,0x00073333, +0x02c,0x0000000d, +0x02a,0x0000000e, +0x02b,0x0000050b, +0x02b,0x00066666, +0x02c,0x0000001a, +0x02a,0x000e0000, +0x010,0x0004000f, +0x011,0x000e31fc, +0x010,0x0006000f, +0x011,0x000ff9f8, +0x010,0x0002000f, +0x011,0x000203f9, +0x010,0x0003000f, +0x011,0x000ff500, +0x010,0x00000000, +0x011,0x00000000, +0x010,0x0008000f, +0x011,0x0003f100, +0x010,0x0009000f, +0x011,0x00023100, +0x012,0x000d8000, +0x012,0x00090000, +0x012,0x00051000, +0x012,0x00012000, +0x013,0x00028fb4, +0x013,0x00024fa8, +0x013,0x000207a4, +0x013,0x0001c3b0, +0x013,0x000183a4, +0x013,0x00014398, +0x013,0x000101a4, +0x013,0x0000c198, +0x013,0x000080a4, +0x013,0x00004098, +0x013,0x00000000, +0x014,0x0001944c, +0x014,0x00059444, +0x014,0x0009944c, +0x014,0x000d9444, +0x015,0x0000f405, +0x015,0x0004f405, +0x015,0x0008f405, +0x015,0x000cf405, +0x016,0x000e0330, +0x016,0x000a0330, +0x016,0x00060330, +0x016,0x00020330, +0x000,0x00010159, +0x018,0x0000f401, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01f,0x00080003, +0x0fe,0x00000000, +0x0fe,0x00000000, +0x01e,0x00044457, +0x01f,0x00080000, +0x000,0x00030159, +}; + +u32 Rtl8192CURadioB_GM_Array[RadioB_GM_ArrayLength] = { +0x0, }; + +// MAC reg V14 - 2011-11-23 +u32 Rtl8192CUMAC_2T_Array[MAC_2T_ArrayLength] = { +0x420,0x00000080, +0x423,0x00000000, +0x430,0x00000000, +0x431,0x00000000, +0x432,0x00000000, +0x433,0x00000001, +0x434,0x00000004, +0x435,0x00000005, +0x436,0x00000006, +0x437,0x00000007, +0x438,0x00000000, +0x439,0x00000000, +0x43a,0x00000000, +0x43b,0x00000001, +0x43c,0x00000004, +0x43d,0x00000005, +0x43e,0x00000006, +0x43f,0x00000007, +0x440,0x0000005d, +0x441,0x00000001, +0x442,0x00000000, +0x444,0x00000015, +0x445,0x000000f0, +0x446,0x0000000f, +0x447,0x00000000, +0x458,0x00000041, +0x459,0x000000a8, +0x45a,0x00000072, +0x45b,0x000000b9, +0x460,0x00000066, +0x461,0x00000066, +0x462,0x00000008, +0x463,0x00000003, +0x4c8,0x000000ff, +0x4c9,0x00000008, +0x4cc,0x000000ff, +0x4cd,0x000000ff, +0x4ce,0x00000001, +0x500,0x00000026, +0x501,0x000000a2, +0x502,0x0000002f, +0x503,0x00000000, +0x504,0x00000028, +0x505,0x000000a3, +0x506,0x0000005e, +0x507,0x00000000, +0x508,0x0000002b, +0x509,0x000000a4, +0x50a,0x0000005e, +0x50b,0x00000000, +0x50c,0x0000004f, +0x50d,0x000000a4, +0x50e,0x00000000, +0x50f,0x00000000, +0x512,0x0000001c, +0x514,0x0000000a, +0x515,0x00000010, +0x516,0x0000000a, +0x517,0x00000010, +0x51a,0x00000016, +0x524,0x0000000f, +0x525,0x0000004f, +0x546,0x00000040, +0x547,0x00000000, +0x550,0x00000010, +0x551,0x00000010, +0x559,0x00000002, +0x55a,0x00000002, +0x55d,0x000000ff, +0x605,0x00000030, +0x608,0x0000000e, +0x609,0x0000002a, +0x652,0x00000020, +0x652,0x00000020, +0x63c,0x00000008, +0x63d,0x00000008, +0x63e,0x0000000c, +0x63f,0x0000000c, +0x66e,0x00000005, +0x700,0x00000021, +0x701,0x00000043, +0x702,0x00000065, +0x703,0x00000087, +0x708,0x00000021, +0x709,0x00000043, +0x70a,0x00000065, +0x70b,0x00000087, +}; + +u32 Rtl8192CUMACPHY_Array_PG[MACPHY_Array_PGLength] = { +0x0, }; + +u32 Rtl8192CUAGCTAB_2TArray[AGCTAB_2TArrayLength] = { +0xc78,0x7b000001, +0xc78,0x7b010001, +0xc78,0x7b020001, +0xc78,0x7b030001, +0xc78,0x7b040001, +0xc78,0x7b050001, +0xc78,0x7a060001, +0xc78,0x79070001, +0xc78,0x78080001, +0xc78,0x77090001, +0xc78,0x760a0001, +0xc78,0x750b0001, +0xc78,0x740c0001, +0xc78,0x730d0001, +0xc78,0x720e0001, +0xc78,0x710f0001, +0xc78,0x70100001, +0xc78,0x6f110001, +0xc78,0x6e120001, +0xc78,0x6d130001, +0xc78,0x6c140001, +0xc78,0x6b150001, +0xc78,0x6a160001, +0xc78,0x69170001, +0xc78,0x68180001, +0xc78,0x67190001, +0xc78,0x661a0001, +0xc78,0x651b0001, +0xc78,0x641c0001, +0xc78,0x631d0001, +0xc78,0x621e0001, +0xc78,0x611f0001, +0xc78,0x60200001, +0xc78,0x49210001, +0xc78,0x48220001, +0xc78,0x47230001, +0xc78,0x46240001, +0xc78,0x45250001, +0xc78,0x44260001, +0xc78,0x43270001, +0xc78,0x42280001, +0xc78,0x41290001, +0xc78,0x402a0001, +0xc78,0x262b0001, +0xc78,0x252c0001, +0xc78,0x242d0001, +0xc78,0x232e0001, +0xc78,0x222f0001, +0xc78,0x21300001, +0xc78,0x20310001, +0xc78,0x06320001, +0xc78,0x05330001, +0xc78,0x04340001, +0xc78,0x03350001, +0xc78,0x02360001, +0xc78,0x01370001, +0xc78,0x00380001, +0xc78,0x00390001, +0xc78,0x003a0001, +0xc78,0x003b0001, +0xc78,0x003c0001, +0xc78,0x003d0001, +0xc78,0x003e0001, +0xc78,0x003f0001, +0xc78,0x7b400001, +0xc78,0x7b410001, +0xc78,0x7b420001, +0xc78,0x7b430001, +0xc78,0x7b440001, +0xc78,0x7b450001, +0xc78,0x7a460001, +0xc78,0x79470001, +0xc78,0x78480001, +0xc78,0x77490001, +0xc78,0x764a0001, +0xc78,0x754b0001, +0xc78,0x744c0001, +0xc78,0x734d0001, +0xc78,0x724e0001, +0xc78,0x714f0001, +0xc78,0x70500001, +0xc78,0x6f510001, +0xc78,0x6e520001, +0xc78,0x6d530001, +0xc78,0x6c540001, +0xc78,0x6b550001, +0xc78,0x6a560001, +0xc78,0x69570001, +0xc78,0x68580001, +0xc78,0x67590001, +0xc78,0x665a0001, +0xc78,0x655b0001, +0xc78,0x645c0001, +0xc78,0x635d0001, +0xc78,0x625e0001, +0xc78,0x615f0001, +0xc78,0x60600001, +0xc78,0x49610001, +0xc78,0x48620001, +0xc78,0x47630001, +0xc78,0x46640001, +0xc78,0x45650001, +0xc78,0x44660001, +0xc78,0x43670001, +0xc78,0x42680001, +0xc78,0x41690001, +0xc78,0x406a0001, +0xc78,0x266b0001, +0xc78,0x256c0001, +0xc78,0x246d0001, +0xc78,0x236e0001, +0xc78,0x226f0001, +0xc78,0x21700001, +0xc78,0x20710001, +0xc78,0x06720001, +0xc78,0x05730001, +0xc78,0x04740001, +0xc78,0x03750001, +0xc78,0x02760001, +0xc78,0x01770001, +0xc78,0x00780001, +0xc78,0x00790001, +0xc78,0x007a0001, +0xc78,0x007b0001, +0xc78,0x007c0001, +0xc78,0x007d0001, +0xc78,0x007e0001, +0xc78,0x007f0001, +0xc78,0x3800001e, +0xc78,0x3801001e, +0xc78,0x3802001e, +0xc78,0x3803001e, +0xc78,0x3804001e, +0xc78,0x3805001e, +0xc78,0x3806001e, +0xc78,0x3807001e, +0xc78,0x3808001e, +0xc78,0x3c09001e, +0xc78,0x3e0a001e, +0xc78,0x400b001e, +0xc78,0x440c001e, +0xc78,0x480d001e, +0xc78,0x4c0e001e, +0xc78,0x500f001e, +0xc78,0x5210001e, +0xc78,0x5611001e, +0xc78,0x5a12001e, +0xc78,0x5e13001e, +0xc78,0x6014001e, +0xc78,0x6015001e, +0xc78,0x6016001e, +0xc78,0x6217001e, +0xc78,0x6218001e, +0xc78,0x6219001e, +0xc78,0x621a001e, +0xc78,0x621b001e, +0xc78,0x621c001e, +0xc78,0x621d001e, +0xc78,0x621e001e, +0xc78,0x621f001e, +}; + +u32 Rtl8192CUAGCTAB_1TArray[AGCTAB_1TArrayLength] = { +0xc78,0x7b000001, +0xc78,0x7b010001, +0xc78,0x7b020001, +0xc78,0x7b030001, +0xc78,0x7b040001, +0xc78,0x7b050001, +0xc78,0x7a060001, +0xc78,0x79070001, +0xc78,0x78080001, +0xc78,0x77090001, +0xc78,0x760a0001, +0xc78,0x750b0001, +0xc78,0x740c0001, +0xc78,0x730d0001, +0xc78,0x720e0001, +0xc78,0x710f0001, +0xc78,0x70100001, +0xc78,0x6f110001, +0xc78,0x6e120001, +0xc78,0x6d130001, +0xc78,0x6c140001, +0xc78,0x6b150001, +0xc78,0x6a160001, +0xc78,0x69170001, +0xc78,0x68180001, +0xc78,0x67190001, +0xc78,0x661a0001, +0xc78,0x651b0001, +0xc78,0x641c0001, +0xc78,0x631d0001, +0xc78,0x621e0001, +0xc78,0x611f0001, +0xc78,0x60200001, +0xc78,0x49210001, +0xc78,0x48220001, +0xc78,0x47230001, +0xc78,0x46240001, +0xc78,0x45250001, +0xc78,0x44260001, +0xc78,0x43270001, +0xc78,0x42280001, +0xc78,0x41290001, +0xc78,0x402a0001, +0xc78,0x262b0001, +0xc78,0x252c0001, +0xc78,0x242d0001, +0xc78,0x232e0001, +0xc78,0x222f0001, +0xc78,0x21300001, +0xc78,0x20310001, +0xc78,0x06320001, +0xc78,0x05330001, +0xc78,0x04340001, +0xc78,0x03350001, +0xc78,0x02360001, +0xc78,0x01370001, +0xc78,0x00380001, +0xc78,0x00390001, +0xc78,0x003a0001, +0xc78,0x003b0001, +0xc78,0x003c0001, +0xc78,0x003d0001, +0xc78,0x003e0001, +0xc78,0x003f0001, +0xc78,0x7b400001, +0xc78,0x7b410001, +0xc78,0x7b420001, +0xc78,0x7b430001, +0xc78,0x7b440001, +0xc78,0x7b450001, +0xc78,0x7a460001, +0xc78,0x79470001, +0xc78,0x78480001, +0xc78,0x77490001, +0xc78,0x764a0001, +0xc78,0x754b0001, +0xc78,0x744c0001, +0xc78,0x734d0001, +0xc78,0x724e0001, +0xc78,0x714f0001, +0xc78,0x70500001, +0xc78,0x6f510001, +0xc78,0x6e520001, +0xc78,0x6d530001, +0xc78,0x6c540001, +0xc78,0x6b550001, +0xc78,0x6a560001, +0xc78,0x69570001, +0xc78,0x68580001, +0xc78,0x67590001, +0xc78,0x665a0001, +0xc78,0x655b0001, +0xc78,0x645c0001, +0xc78,0x635d0001, +0xc78,0x625e0001, +0xc78,0x615f0001, +0xc78,0x60600001, +0xc78,0x49610001, +0xc78,0x48620001, +0xc78,0x47630001, +0xc78,0x46640001, +0xc78,0x45650001, +0xc78,0x44660001, +0xc78,0x43670001, +0xc78,0x42680001, +0xc78,0x41690001, +0xc78,0x406a0001, +0xc78,0x266b0001, +0xc78,0x256c0001, +0xc78,0x246d0001, +0xc78,0x236e0001, +0xc78,0x226f0001, +0xc78,0x21700001, +0xc78,0x20710001, +0xc78,0x06720001, +0xc78,0x05730001, +0xc78,0x04740001, +0xc78,0x03750001, +0xc78,0x02760001, +0xc78,0x01770001, +0xc78,0x00780001, +0xc78,0x00790001, +0xc78,0x007a0001, +0xc78,0x007b0001, +0xc78,0x007c0001, +0xc78,0x007d0001, +0xc78,0x007e0001, +0xc78,0x007f0001, +0xc78,0x3800001e, +0xc78,0x3801001e, +0xc78,0x3802001e, +0xc78,0x3803001e, +0xc78,0x3804001e, +0xc78,0x3805001e, +0xc78,0x3806001e, +0xc78,0x3807001e, +0xc78,0x3808001e, +0xc78,0x3c09001e, +0xc78,0x3e0a001e, +0xc78,0x400b001e, +0xc78,0x440c001e, +0xc78,0x480d001e, +0xc78,0x4c0e001e, +0xc78,0x500f001e, +0xc78,0x5210001e, +0xc78,0x5611001e, +0xc78,0x5a12001e, +0xc78,0x5e13001e, +0xc78,0x6014001e, +0xc78,0x6015001e, +0xc78,0x6016001e, +0xc78,0x6217001e, +0xc78,0x6218001e, +0xc78,0x6219001e, +0xc78,0x621a001e, +0xc78,0x621b001e, +0xc78,0x621c001e, +0xc78,0x621d001e, +0xc78,0x621e001e, +0xc78,0x621f001e, +}; + +u32 Rtl8192CUAGCTAB_1T_HPArray[AGCTAB_1T_HPArrayLength] = { +0xc78,0x7b000001, +0xc78,0x7b010001, +0xc78,0x7b020001, +0xc78,0x7b030001, +0xc78,0x7b040001, +0xc78,0x7b050001, +0xc78,0x7b060001, +0xc78,0x7b070001, +0xc78,0x7b080001, +0xc78,0x7a090001, +0xc78,0x790a0001, +0xc78,0x780b0001, +0xc78,0x770c0001, +0xc78,0x760d0001, +0xc78,0x750e0001, +0xc78,0x740f0001, +0xc78,0x73100001, +0xc78,0x72110001, +0xc78,0x71120001, +0xc78,0x70130001, +0xc78,0x6f140001, +0xc78,0x6e150001, +0xc78,0x6d160001, +0xc78,0x6c170001, +0xc78,0x6b180001, +0xc78,0x6a190001, +0xc78,0x691a0001, +0xc78,0x681b0001, +0xc78,0x671c0001, +0xc78,0x661d0001, +0xc78,0x651e0001, +0xc78,0x641f0001, +0xc78,0x63200001, +0xc78,0x62210001, +0xc78,0x61220001, +0xc78,0x60230001, +0xc78,0x46240001, +0xc78,0x45250001, +0xc78,0x44260001, +0xc78,0x43270001, +0xc78,0x42280001, +0xc78,0x41290001, +0xc78,0x402a0001, +0xc78,0x262b0001, +0xc78,0x252c0001, +0xc78,0x242d0001, +0xc78,0x232e0001, +0xc78,0x222f0001, +0xc78,0x21300001, +0xc78,0x20310001, +0xc78,0x06320001, +0xc78,0x05330001, +0xc78,0x04340001, +0xc78,0x03350001, +0xc78,0x02360001, +0xc78,0x01370001, +0xc78,0x00380001, +0xc78,0x00390001, +0xc78,0x003a0001, +0xc78,0x003b0001, +0xc78,0x003c0001, +0xc78,0x003d0001, +0xc78,0x003e0001, +0xc78,0x003f0001, +0xc78,0x7b400001, +0xc78,0x7b410001, +0xc78,0x7b420001, +0xc78,0x7b430001, +0xc78,0x7b440001, +0xc78,0x7b450001, +0xc78,0x7b460001, +0xc78,0x7b470001, +0xc78,0x7b480001, +0xc78,0x7a490001, +0xc78,0x794a0001, +0xc78,0x784b0001, +0xc78,0x774c0001, +0xc78,0x764d0001, +0xc78,0x754e0001, +0xc78,0x744f0001, +0xc78,0x73500001, +0xc78,0x72510001, +0xc78,0x71520001, +0xc78,0x70530001, +0xc78,0x6f540001, +0xc78,0x6e550001, +0xc78,0x6d560001, +0xc78,0x6c570001, +0xc78,0x6b580001, +0xc78,0x6a590001, +0xc78,0x695a0001, +0xc78,0x685b0001, +0xc78,0x675c0001, +0xc78,0x665d0001, +0xc78,0x655e0001, +0xc78,0x645f0001, +0xc78,0x63600001, +0xc78,0x62610001, +0xc78,0x61620001, +0xc78,0x60630001, +0xc78,0x46640001, +0xc78,0x45650001, +0xc78,0x44660001, +0xc78,0x43670001, +0xc78,0x42680001, +0xc78,0x41690001, +0xc78,0x406a0001, +0xc78,0x266b0001, +0xc78,0x256c0001, +0xc78,0x246d0001, +0xc78,0x236e0001, +0xc78,0x226f0001, +0xc78,0x21700001, +0xc78,0x20710001, +0xc78,0x06720001, +0xc78,0x05730001, +0xc78,0x04740001, +0xc78,0x03750001, +0xc78,0x02760001, +0xc78,0x01770001, +0xc78,0x00780001, +0xc78,0x00790001, +0xc78,0x007a0001, +0xc78,0x007b0001, +0xc78,0x007c0001, +0xc78,0x007d0001, +0xc78,0x007e0001, +0xc78,0x007f0001, +0xc78,0x3800001e, +0xc78,0x3801001e, +0xc78,0x3802001e, +0xc78,0x3803001e, +0xc78,0x3804001e, +0xc78,0x3805001e, +0xc78,0x3806001e, +0xc78,0x3807001e, +0xc78,0x3808001e, +0xc78,0x3c09001e, +0xc78,0x3e0a001e, +0xc78,0x400b001e, +0xc78,0x440c001e, +0xc78,0x480d001e, +0xc78,0x4c0e001e, +0xc78,0x500f001e, +0xc78,0x5210001e, +0xc78,0x5611001e, +0xc78,0x5a12001e, +0xc78,0x5e13001e, +0xc78,0x6014001e, +0xc78,0x6015001e, +0xc78,0x6016001e, +0xc78,0x6217001e, +0xc78,0x6218001e, +0xc78,0x6219001e, +0xc78,0x621a001e, +0xc78,0x621b001e, +0xc78,0x621c001e, +0xc78,0x621d001e, +0xc78,0x621e001e, +0xc78,0x621f001e, +}; + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c b/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c new file mode 100755 index 00000000..66970f1c --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c @@ -0,0 +1,2564 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/*Created on 2011/11/ 8, 14:15*/ + +#include +#include "Hal8192CUHWImg_wowlan.h" + + +u8 Rtl8192CUFwTSMCWWImgArray[TSMCWWImgArrayLength] = { +0xc1,0x88,0x02,0x00,0x51,0x00,0x00,0x00,0x03,0x23,0x16,0x43,0x72,0x34,0x00,0x00, +0x58,0x92,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x57,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x5c,0xb6,0x00,0x00,0x00,0x00,0x00,0x02,0x5d,0x99,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5, +0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8, +0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08, +0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xf8, +0xbb,0x01,0x11,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5, +0xf0,0xa3,0xf0,0x22,0x50,0x09,0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb, +0xfe,0x09,0xe9,0x25,0x82,0xc8,0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee, +0x4a,0xfe,0xed,0x49,0xfd,0xec,0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0, +0xfe,0xa3,0xe0,0xff,0x22,0xa4,0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83, +0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0, +0xf9,0x25,0xf0,0xf0,0xe5,0x82,0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0, +0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4, +0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5, +0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf, +0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3, +0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0xb5,0xf0, +0x06,0x74,0x03,0x93,0x68,0x60,0xe9,0xa3,0xa3,0xa3,0xa3,0x80,0xd8,0x02,0x43,0xdb, +0x02,0x50,0x2a,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2, +0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33, +0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf, +0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x20,0xe4,0x7e, +0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x91,0x40,0x00,0x41,0x91,0x9c,0x00,0x41,0x91,0x23,0x80,0x41,0x91,0x24,0x80, +0x41,0x91,0x9e,0x00,0x41,0x91,0x52,0x00,0x41,0x91,0x93,0x00,0x41,0x91,0x91,0x00, +0x41,0x91,0x90,0x00,0x41,0x91,0x92,0x00,0x00,0xf0,0x90,0x91,0x30,0xe0,0x90,0x91, +0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x54,0x7e,0x01,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0x65,0xeb,0xf0,0xa3,0xe0,0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5,0x45,0x12, +0x35,0xab,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01,0x3c,0x74, +0x08,0xf0,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4, +0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x59,0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06, +0x92,0x74,0x02,0xf0,0x90,0x91,0x36,0x14,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x0c, +0x50,0x02,0xf1,0x23,0x22,0x90,0x02,0x84,0xef,0xf0,0xa3,0xee,0xf0,0xa3,0x74,0x05, +0xf0,0x22,0x7d,0x01,0xaf,0x6f,0xe1,0x27,0xf1,0xe6,0xbf,0x01,0x10,0x90,0x91,0x42, +0xe0,0xff,0xe4,0xfd,0x12,0x48,0x22,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x8f,0x82, +0x8e,0x83,0xa3,0xa3,0xa3,0xe4,0xf0,0x22,0xe4,0xf5,0x72,0x7f,0x60,0x7e,0x01,0x80, +0xed,0x7f,0x00,0x22,0x90,0x91,0x53,0xe0,0x54,0xfe,0xf0,0x02,0x50,0xd6,0x22,0xe4, +0xf5,0x75,0x22,0x02,0x5f,0xe2,0x02,0x5f,0xe9,0xef,0x8e,0xf0,0x71,0x70,0x45,0x26, +0x00,0x40,0x45,0x4e,0x00,0x80,0x45,0x79,0x01,0x00,0x45,0x8d,0x02,0x00,0x45,0xa5, +0x04,0x00,0x00,0x00,0x45,0xc2,0xed,0x54,0x3f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x00,0x7f,0x40,0xef,0x2d,0xff,0xee,0x3c,0xfe,0xef,0x78,0x06,0xce,0xc3,0x13,0xce, +0x13,0xd8,0xf9,0x78,0x06,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x80,0x26,0xed,0x54, +0x7f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x00,0x7f,0x80,0xef,0x2d,0xff,0xee,0x3c, +0xfe,0xef,0x78,0x07,0xce,0xc3,0x13,0xce,0x13,0xd8,0xf9,0x78,0x07,0xc3,0x33,0xce, +0x33,0xce,0xd8,0xf9,0xfd,0xac,0x06,0x80,0x49,0xed,0x70,0x04,0xfe,0xff,0x80,0x04, +0x7e,0x01,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x7d,0x00,0xfc,0x80,0x35,0xec,0x54,0x01, +0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x02,0x7f,0x00,0xef,0x2d,0xee,0x3c,0xc3, +0x13,0x7d,0x00,0x80,0x1a,0xec,0x54,0x03,0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x04,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x13,0x13,0x54,0x3f,0x7d,0x00,0x25,0xe0,0x25, +0xe0,0xfc,0xae,0x04,0xaf,0x05,0x22,0x90,0x91,0x09,0x12,0x2a,0x8b,0x00,0x00,0x00, +0x00,0x90,0x06,0xa9,0xe0,0x90,0x91,0x08,0xf0,0xe0,0x54,0xc0,0x70,0x0a,0x53,0x71, +0xfe,0x53,0x71,0xfd,0x91,0xc2,0x80,0x47,0x90,0x91,0x26,0xe0,0x60,0x41,0x90,0x91, +0x38,0xe0,0x70,0x3b,0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x27, +0xde,0x90,0x91,0x09,0x12,0x2a,0x7f,0x90,0x91,0x09,0x71,0x09,0xec,0x44,0x02,0xfc, +0x90,0x91,0x09,0x12,0x2a,0x7f,0x90,0x91,0x09,0x71,0x09,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x90, +0x91,0x08,0xe0,0x30,0xe6,0x13,0x43,0x71,0x01,0x90,0x91,0x3b,0xe0,0x64,0x02,0x60, +0x04,0x91,0xc8,0x80,0x07,0x91,0x77,0x80,0x03,0x53,0x71,0xfe,0x90,0x91,0x08,0xe0, +0x30,0xe7,0x16,0x43,0x71,0x02,0xe4,0x90,0x91,0x66,0x91,0x49,0x90,0x01,0x57,0x74, +0x05,0xf0,0x90,0x91,0x3c,0x74,0x01,0xf0,0x22,0x53,0x71,0xfd,0x22,0xd3,0x10,0xaf, +0x01,0xc3,0xc0,0xd0,0x8b,0x60,0x8a,0x61,0x89,0x62,0x90,0x91,0x68,0x71,0x41,0xab, +0x63,0xaa,0x64,0xa9,0x65,0x90,0x91,0x6b,0x71,0x41,0xaf,0x66,0x15,0x66,0xef,0x60, +0x1b,0x90,0x91,0x6b,0xe4,0x75,0xf0,0x01,0x71,0x2a,0x12,0x29,0xd9,0xff,0x90,0x91, +0x68,0xe4,0x75,0xf0,0x01,0x71,0x2a,0xef,0x51,0x4d,0x80,0xde,0xab,0x60,0xaa,0x61, +0xa9,0x62,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91, +0x6e,0x71,0x41,0x90,0x91,0x9e,0xe0,0xff,0x04,0xf0,0x90,0x00,0x01,0xef,0x51,0x5f, +0x7f,0xaf,0x7e,0x01,0x12,0x64,0x1c,0xef,0x60,0x44,0x90,0x91,0x6e,0x71,0x21,0x8b, +0x63,0x8a,0x64,0x89,0x65,0x75,0x66,0x02,0x7b,0x01,0x7a,0x01,0x79,0xa0,0xd1,0x6d, +0x90,0x91,0x71,0x71,0x21,0x8b,0x63,0x8a,0x64,0x89,0x65,0x90,0x91,0x6e,0x71,0x21, +0x12,0x29,0xd9,0xff,0xc4,0x54,0x0f,0xf5,0x66,0x7b,0x01,0x7a,0x01,0x79,0xa2,0xd1, +0x6d,0x90,0x01,0xaf,0x74,0xff,0xf0,0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0,0xd0, +0x92,0xaf,0x22,0x7d,0x01,0x7f,0x0c,0x90,0x91,0x95,0xed,0xf0,0x90,0x91,0x94,0xef, +0xf0,0x54,0x0f,0xff,0xe5,0x6e,0x54,0x0f,0x6f,0x60,0x76,0x90,0x91,0x94,0xe0,0x30, +0xe2,0x30,0xe5,0x6e,0x20,0xe2,0x05,0x7f,0x01,0x12,0x62,0x65,0xe5,0x6e,0x30,0xe3, +0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3,0x08,0x12,0x5a,0x3f,0xef,0x60,0x53,0x80,0x52, +0xe5,0x6e,0x20,0xe3,0x4c,0x90,0x91,0x94,0xe0,0x30,0xe3,0x45,0xa3,0xe0,0xff,0x02, +0x62,0x4a,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x0c,0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3, +0x08,0x12,0x5a,0x3f,0xef,0x60,0x2a,0xf1,0xb2,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x04, +0x10,0x90,0x91,0x94,0xe0,0x20,0xe2,0x09,0x12,0x5b,0xb3,0xef,0x60,0x13,0x12,0x48, +0xce,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x02,0x08,0x91,0xf1,0xef,0x60,0x03,0x12,0x63, +0x56,0x22,0x90,0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x6d,0xb4,0x01,0x04,0x7f,0x01, +0xf1,0xc9,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x8f,0x67,0xf1,0xe6,0xbf,0x01,0x15, +0x90,0x91,0x43,0x12,0x48,0x1e,0xad,0x07,0xac,0x06,0xaf,0x67,0x12,0x61,0xa3,0x90, +0x04,0x1f,0x74,0x20,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x01,0xc4, +0x74,0xe6,0xf0,0x74,0x47,0xa3,0xf0,0x90,0x04,0x1d,0xe0,0x60,0x1a,0x90,0x05,0x22, +0xe0,0x54,0x90,0x60,0x07,0x90,0x01,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7,0xe0, +0x30,0xe1,0xe4,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0xe0,0xff, +0x7d,0x01,0x90,0x91,0x74,0xef,0xf0,0xa3,0xed,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5, +0x70,0x60,0x04,0xe4,0xff,0x11,0xb3,0x90,0x91,0x74,0xe0,0x30,0xe0,0x09,0x90,0x91, +0x76,0xe4,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x91,0x74,0xe0,0xff,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x90,0x04,0x25,0xef,0xf0,0x90,0x91,0x75,0xe0,0x60,0x1f,0xa3,0xa3,0xe0, +0xff,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10, +0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x90,0x91,0x76,0xa3, +0xe0,0xff,0xfd,0x24,0x08,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09, +0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x90,0x91,0x76,0xe0,0xfe,0xa3, +0xe0,0xff,0x22,0xef,0x60,0x0b,0x90,0x91,0x51,0xe0,0xb4,0x01,0x10,0xe4,0xff,0x80, +0x09,0x90,0x91,0x51,0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x68,0x87,0x22,0x90,0x01, +0x37,0x74,0x02,0xf0,0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x68,0x46,0xef,0x70,0x06, +0x90,0x01,0xc8,0x74,0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x36,0xe6,0xe5,0x70,0x60, +0x04,0x7f,0x01,0x11,0xb3,0x51,0x0c,0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0xef,0x64, +0x01,0x70,0x42,0x7d,0x78,0x7f,0x02,0x12,0x36,0x75,0x7d,0x02,0x7f,0x03,0x12,0x36, +0x75,0x90,0x01,0x36,0x74,0x03,0xf0,0xfd,0x7f,0x02,0x12,0x36,0xe6,0x7d,0x10,0x7f, +0x03,0x12,0x36,0x92,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x12, +0x47,0x23,0xe4,0xff,0x11,0xb3,0x90,0x06,0x04,0xe0,0x54,0x7f,0xf0,0x90,0x06,0x0a, +0xe0,0x54,0xf8,0xf0,0x22,0x90,0x01,0x36,0x74,0x7b,0xf0,0xa3,0x74,0x02,0xf0,0x7d, +0x7b,0xff,0x12,0x36,0xe6,0x7d,0x02,0x7f,0x03,0x12,0x36,0xe6,0x7d,0x10,0x7f,0x03, +0x12,0x36,0x92,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a,0xe0,0x44,0x07, +0xf0,0x12,0x64,0x11,0xe5,0x6d,0x20,0xe0,0x05,0xe4,0x90,0x91,0x29,0xf0,0x22,0x8b, +0x0e,0x8a,0x0f,0x89,0x10,0x12,0x62,0x3e,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x12,0x29, +0xd9,0xf5,0x70,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24,0x03,0x70,0x40, +0x7f,0x01,0x80,0x3a,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02,0x12,0x42,0x20, +0xfd,0xe4,0xff,0x31,0xe1,0x80,0x27,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02, +0x12,0x42,0x20,0xfd,0x7f,0x01,0x31,0xe1,0x1f,0x80,0x13,0xab,0x0e,0xaa,0x0f,0xa9, +0x10,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0x31,0xe1,0xe4,0xff,0x11,0xfe, +0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x91,0x39,0x74,0x01,0xf0,0x80, +0x16,0xed,0x70,0x0a,0x90,0x91,0x35,0xe0,0x90,0x91,0x39,0xf0,0x80,0x05,0x90,0x91, +0x39,0xed,0xf0,0x90,0x91,0x39,0xe0,0x90,0x91,0x27,0xf0,0x22,0x7f,0x78,0x7e,0x08, +0x12,0x27,0xde,0x90,0x90,0xd8,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde, +0x90,0x90,0xdc,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0xe0, +0x12,0x2a,0x7f,0x90,0x91,0x51,0xe0,0x90,0x90,0xd8,0xb4,0x01,0x0d,0x12,0x43,0x09, +0xef,0x54,0xc7,0xff,0xed,0x54,0xc7,0xfd,0x80,0x07,0x12,0x43,0x09,0xef,0x54,0xc7, +0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12,0x2f,0xd9,0x90, +0x90,0xdc,0x12,0x43,0x09,0xef,0x54,0x0f,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90,0xe0,0x12,0x43,0x09,0xef,0x44,0x02, +0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x7f, +0x70,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xe4,0x12,0x2a,0x7f,0x90,0x80,0x85,0x12, +0x2a,0x8b,0x00,0x1b,0x25,0xa0,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x59, +0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90,0x91,0x51, +0xe0,0xb4,0x01,0x11,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4,0xfd, +0x7f,0x01,0x12,0x34,0x81,0x90,0x00,0x11,0xe0,0x54,0xf6,0xf0,0x80,0x08,0xf4,0xff, +0x90,0x00,0x43,0xe0,0x5f,0xf0,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x7f,0x10,0xdf, +0xfe,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x9b, +0xed,0xf0,0x90,0x91,0x9a,0xef,0xf0,0xd3,0x94,0x07,0x50,0x63,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0,0x5f, +0xf0,0x51,0xe6,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3, +0x33,0xd8,0xfc,0xff,0x90,0x00,0x46,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x9b,0xe0, +0x60,0x16,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xff,0x90,0x00,0x45,0x80,0x66,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x45,0x80,0x6b,0x90, +0x91,0x9a,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3, +0x33,0xd8,0xfc,0xc4,0x54,0xf0,0x51,0xde,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0x51, +0xe6,0x90,0x91,0x9b,0xe0,0x60,0x1b,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x42,0xe0,0x4f, +0x80,0x1a,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x42,0xe0,0x5f,0xf0,0x51,0xe6,0xd0, +0xd0,0x92,0xaf,0x22,0xf0,0x90,0x00,0x45,0xe0,0x54,0xfe,0xfd,0x7f,0x45,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x8f,0x82,0x75,0x83,0x00,0xed,0xf0,0x51,0xe6,0xd0,0xd0, +0x92,0xaf,0x22,0xef,0x14,0x60,0x30,0x14,0x60,0x66,0x24,0x02,0x60,0x02,0x81,0xaa, +0x90,0x90,0xf3,0x74,0x02,0xf0,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x71, +0xee,0x90,0x00,0x47,0xe0,0x44,0x08,0xfd,0x7f,0x47,0x71,0xee,0x90,0x00,0x45,0xe0, +0x44,0x10,0xfd,0x7f,0x45,0x80,0x71,0xe4,0x90,0x90,0xf3,0xf0,0x90,0x90,0xef,0x12, +0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90, +0x00,0x45,0xe0,0x44,0xef,0xfd,0x7f,0x45,0x71,0xee,0x90,0x00,0x45,0xe0,0x54,0xef, +0xfd,0x7f,0x45,0x71,0xee,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x80,0x38, +0x90,0x90,0xf3,0x74,0x01,0xf0,0x90,0x90,0xf9,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x00,0x45,0xe0,0x44,0x20,0xfd, +0x7f,0x45,0x71,0xee,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x71,0xee,0x90, +0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x71,0xee,0x22,0x90,0x00,0x02,0x12,0x42, +0x20,0x90,0x90,0xf5,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x25,0xe0,0x25,0xe0,0x90, +0x90,0xf4,0xf0,0x12,0x29,0xd9,0x25,0xe0,0x25,0xe0,0x90,0x90,0xf8,0xf0,0x90,0x05, +0x60,0xe0,0x90,0x91,0x03,0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05, +0x62,0xe0,0x90,0x91,0x05,0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xa2,0xaf, +0xe4,0x33,0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x90,0x90,0xf4,0xe0,0xff,0x12,0x6e,0x67, +0x90,0x91,0x1c,0xe0,0x24,0xff,0x92,0xaf,0x90,0x90,0xf5,0xe0,0x70,0x02,0xa1,0xb2, +0x90,0x90,0xf4,0xe0,0x70,0x02,0xa1,0xb2,0x90,0x90,0xf8,0xe0,0x70,0x02,0xa1,0xb2, +0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x90,0x91,0x07,0x74,0x01,0xf0, +0x90,0x91,0x1c,0xe0,0x24,0xff,0x92,0xaf,0x71,0xe5,0x90,0x00,0x46,0xe0,0x44,0x01, +0xfd,0x7f,0x46,0x71,0xee,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x80,0x06, +0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0x71, +0xee,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x91,0x03,0xe0,0x90,0x05,0x84,0xf0, +0x90,0x91,0x04,0xe0,0x90,0x05,0x85,0xf0,0x90,0x91,0x05,0xe0,0x90,0x05,0x86,0xf0, +0x90,0x91,0x06,0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c,0xf0, +0xc2,0xaf,0x90,0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d,0x20,0xe4,0xff,0x12,0x37,0x00, +0x80,0x2b,0x90,0x90,0xf5,0xe0,0x70,0x2d,0x90,0x91,0x07,0x71,0xe4,0x90,0x00,0x46, +0xe0,0x54,0xfe,0xfd,0x7f,0x46,0x71,0xee,0x90,0x05,0x22,0xe4,0xf0,0xa2,0xaf,0x33, +0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff,0x12,0x36,0x92,0x90,0x91,0x1c, +0xe0,0x24,0xff,0x92,0xaf,0x22,0x8b,0x0e,0x8a,0x0f,0x89,0x10,0x90,0x00,0x02,0x12, +0x42,0x20,0x90,0x90,0xf6,0xf0,0xe0,0x30,0xe0,0x4b,0x90,0x90,0xed,0x74,0x01,0xf0, +0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0xef,0x12,0x2a,0x7f,0xab,0x0e,0xaa, +0x0f,0xa9,0x10,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x1a, +0x12,0x2a,0x6c,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x90,0xef,0x12,0x43, +0x09,0xec,0x54,0x03,0xfc,0x12,0x42,0xfc,0x90,0x90,0xf9,0x12,0x2a,0x7f,0x90,0x05, +0x22,0xe4,0xf0,0x80,0x2d,0xe4,0x90,0x90,0xed,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x27, +0xde,0xec,0x54,0x03,0xfc,0xec,0x44,0xc0,0xfc,0x90,0x90,0xef,0x12,0x2a,0x7f,0x90, +0x90,0xef,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12, +0x2f,0xd9,0x90,0x90,0xf6,0xe0,0x30,0xe1,0x19,0x7d,0x0c,0x7f,0x47,0x71,0xee,0x90, +0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x71,0xee,0x90,0x00,0x46,0xe0,0x44,0x10, +0x80,0x1c,0x90,0x00,0x47,0xe0,0x54,0xf3,0xfd,0x7f,0x47,0x71,0xee,0x90,0x00,0x48, +0xe0,0x54,0xf3,0xfd,0x7f,0x48,0x71,0xee,0x90,0x00,0x46,0xe0,0x54,0xef,0xfd,0x7f, +0x46,0x71,0xee,0xe4,0x90,0x90,0xf3,0xf0,0x22,0x90,0x01,0x3c,0x74,0xff,0xf0,0xa3, +0xf0,0xa3,0xf0,0x90,0x01,0x34,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x54, +0x71,0xee,0x7d,0xff,0x7f,0x55,0x71,0xee,0x7d,0xff,0x7f,0x56,0x71,0xee,0x7d,0xff, +0x7f,0x57,0x61,0xee,0x90,0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90, +0x01,0x38,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0x71,0xee,0xe4,0xfd, +0x7f,0x51,0x71,0xee,0xe4,0xfd,0x7f,0x52,0x71,0xee,0xe4,0xfd,0x7f,0x53,0x61,0xee, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x22,0xed,0xf0,0x90,0x91,0x21,0xef, +0xf0,0xd3,0x94,0x07,0x50,0x4e,0xa3,0xe0,0x70,0x1a,0x90,0x91,0x21,0xe0,0xff,0x74, +0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0, +0x5f,0xf0,0x80,0x17,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x21, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90, +0x00,0x46,0x80,0x59,0x90,0x91,0x21,0xe0,0x24,0xf8,0xf0,0xa3,0xe0,0x70,0x1d,0x90, +0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4, +0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x80,0x1a,0x90,0x91,0x21,0xe0, +0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff, +0x90,0x00,0x43,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0, +0x51,0xe6,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x49,0xe0,0x90,0x91,0x9f,0xf0,0xe0, +0x54,0x0f,0xf0,0x44,0xf0,0xfd,0x7f,0x49,0x71,0xee,0x90,0x91,0x9f,0xe0,0x44,0xb0, +0xfd,0x7f,0x49,0x61,0xee,0x12,0x47,0xe6,0xbf,0x01,0x10,0x90,0x02,0x09,0xe0,0xff, +0x7d,0x01,0x12,0x48,0x22,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x75,0x28,0x33,0xe4, +0xf5,0x29,0x75,0x2a,0x07,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3,0xe5,0x29, +0xf0,0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0xe4,0x90,0x91,0x0e,0xf0,0xa3, +0xf0,0x75,0x8e,0x02,0xf1,0x25,0xd1,0xe8,0x90,0x91,0x4f,0xef,0xf0,0xf1,0x0b,0x90, +0x91,0x51,0xef,0xf0,0xf1,0x60,0x90,0x91,0x3d,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xf5, +0x57,0xf1,0x02,0x12,0x61,0xc4,0x12,0x32,0x3d,0x12,0x44,0xff,0x11,0x0c,0xf1,0x36, +0xd1,0xfb,0xd1,0xd0,0x12,0x44,0xfe,0x31,0x13,0x12,0x44,0xf4,0x12,0x6e,0x09,0x90, +0x91,0x10,0xe5,0xd9,0xf0,0x12,0x4e,0xb9,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44,0x40, +0xf0,0x12,0x4a,0xe6,0x75,0xe8,0x03,0x43,0xa8,0x85,0xd2,0xaf,0x90,0x91,0x0e,0xe0, +0x64,0x01,0xf0,0x24,0x2a,0x90,0x01,0xc4,0xf0,0x74,0x50,0xa3,0xf0,0xe5,0x57,0x30, +0xe2,0x10,0x12,0x5f,0xf0,0xbf,0x01,0x0a,0xc2,0xaf,0x53,0x57,0xfb,0xd2,0xaf,0x12, +0x71,0x97,0xe5,0x57,0x30,0xe4,0x0a,0xc2,0xaf,0x53,0x57,0xef,0xd2,0xaf,0x12,0x60, +0x2d,0x90,0x90,0xf7,0xe0,0x70,0x03,0x12,0x70,0x74,0x11,0xe7,0x90,0x91,0x3f,0xe0, +0x90,0x01,0xba,0xf0,0x80,0xb6,0xe4,0x90,0x91,0x55,0xf0,0x90,0x91,0x53,0xe0,0x54, +0x7f,0xf0,0xa3,0x74,0x0a,0xf0,0x22,0x90,0x06,0x34,0xe0,0x60,0x25,0x14,0x70,0x1b, +0x7b,0x01,0x7a,0x06,0x79,0x35,0x7f,0xf9,0x7e,0x01,0x12,0x67,0xe4,0xbf,0x01,0x09, +0x90,0x06,0x35,0xe0,0x54,0x0f,0xf0,0x80,0x04,0x80,0x00,0xe1,0x17,0xe4,0x90,0x06, +0x34,0xf0,0x22,0x90,0x91,0x56,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0x7f,0xf0,0x90,0x01, +0x17,0xe0,0xfe,0x90,0x01,0x16,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x91, +0x5c,0xf0,0xa3,0xef,0xf0,0x90,0x01,0x04,0xe0,0x54,0x0f,0x90,0x91,0x1c,0xf0,0xe0, +0xff,0x74,0x40,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8, +0xf9,0x90,0x91,0x5b,0xf0,0xee,0x90,0x91,0x5a,0xf0,0x90,0x91,0x5e,0xe0,0x54,0xfe, +0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xfb,0xf0,0xe0,0x54,0xf7,0xf0,0xe0,0x54,0xef, +0xf0,0xe0,0x54,0xdf,0xf0,0xe0,0x54,0xbf,0xf0,0xe0,0x54,0x7f,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xf7,0xf0,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x12,0x29,0xd9,0x54,0x01,0xff,0x90,0x91,0x56, +0xe0,0x54,0xfe,0x4f,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x57,0xf0,0x90, +0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x58,0xf0,0x90,0x91,0x56,0xe0,0x30,0xe0,0x1a, +0x90,0x06,0x09,0xe0,0x54,0xfe,0xf0,0x90,0x02,0x86,0xe0,0x44,0x04,0xf0,0x43,0x57, +0x04,0x7d,0x08,0xe4,0xff,0x12,0x36,0xe6,0x80,0x12,0x7d,0x08,0xe4,0xff,0x12,0x36, +0x75,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x31,0xf1,0x31,0x13,0xd0,0xd0,0x92,0xaf, +0x22,0x90,0x06,0x90,0xe4,0xf0,0x21,0x5a,0x90,0x91,0x19,0x12,0x43,0x41,0xef,0x12, +0x43,0x4a,0x52,0x30,0x01,0x52,0x39,0x02,0x52,0x5b,0x03,0x52,0x64,0x09,0x52,0x6c, +0x0c,0x52,0x75,0x0d,0x52,0x7d,0x0e,0x52,0x8e,0x1a,0x52,0x96,0x2c,0x52,0x41,0x2d, +0x52,0x4a,0x2e,0x52,0x9e,0x30,0x52,0x53,0x3b,0x52,0x86,0x3c,0x00,0x00,0x52,0xa6, +0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x64,0x72,0x90,0x91,0x19,0x12,0x43,0x21,0xc1, +0xf5,0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x65,0x8d,0x90,0x91,0x19,0x12,0x43,0x21, +0x02,0x65,0xd5,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x4b,0x90,0x91,0x19,0x12,0x43, +0x21,0x02,0x66,0x0e,0x90,0x91,0x19,0x12,0x43,0x21,0x80,0x42,0x90,0x91,0x19,0x12, +0x43,0x21,0x02,0x4c,0xab,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x98,0x90,0x91,0x19, +0x12,0x43,0x21,0x02,0x4d,0xe6,0x90,0x91,0x19,0x12,0x43,0x21,0x21,0x90,0x90,0x91, +0x19,0x12,0x43,0x21,0xa1,0x9b,0x90,0x91,0x19,0x12,0x43,0x21,0x81,0x7a,0x90,0x91, +0x19,0x12,0x43,0x21,0xe1,0x78,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90,0x91,0x1c,0x12,0x43, +0x21,0x90,0x00,0x01,0x12,0x42,0x97,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe, +0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x42,0xcf,0x12, +0x29,0xd9,0xff,0x60,0x2c,0xb5,0x72,0x16,0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00, +0x01,0x12,0x42,0x97,0x65,0x74,0x70,0x04,0xe5,0x73,0x65,0xf0,0x60,0x23,0x90,0x91, +0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0x12,0x42,0x97,0xff,0xae,0xf0,0x71,0x26,0x80, +0x10,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x29,0xd9,0x65,0x72,0x60,0x03,0x12,0x44, +0xe8,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x1f,0xee,0xf0,0xa3,0xef,0xf0,0x75,0x72, +0x01,0x8e,0x73,0xf5,0x74,0xe4,0xfd,0x7f,0x0b,0x12,0x4f,0x10,0xe4,0xfd,0x7f,0x02, +0x12,0x4f,0x10,0x71,0x6a,0xe4,0xff,0x71,0xcc,0xe4,0xf5,0x76,0x90,0x01,0xc9,0xe5, +0x76,0xf0,0x90,0x91,0x1f,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5, +0x45,0x7d,0x01,0x7f,0x60,0x7e,0x01,0x02,0x35,0xab,0x7f,0x0b,0x71,0xd9,0xef,0x65, +0x75,0x60,0x10,0xe5,0x75,0xb4,0x01,0x05,0xe4,0xf5,0x75,0x80,0x03,0x75,0x75,0x01, +0x7f,0x01,0x22,0x7f,0x00,0x22,0xe5,0x72,0x64,0x01,0x70,0x3f,0x71,0x6a,0xbf,0x01, +0x04,0x7f,0x01,0x71,0xcc,0x90,0x00,0x46,0xe0,0x44,0x04,0xfd,0x7f,0x46,0x12,0x4b, +0xee,0x90,0x00,0x44,0xe0,0x54,0xfb,0xfd,0x7f,0x44,0x12,0x4b,0xee,0x90,0x00,0x46, +0xe0,0x54,0xfb,0xfd,0x7f,0x46,0x12,0x4b,0xee,0x7f,0x02,0x71,0xd9,0x8f,0x76,0x90, +0x01,0xc9,0xe5,0x76,0xf0,0xb4,0x01,0x03,0x12,0x4f,0xd7,0x22,0x90,0x01,0xca,0xe5, +0x75,0xf0,0xef,0x60,0x03,0x12,0x4f,0xd7,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0xa0,0xef,0xf0,0xd3,0x94,0x07,0x50,0x47,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0xe0,0x5f,0xf0,0x12, +0x4a,0xe6,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0,0xfb,0xe4,0xfe,0xef, +0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x80, +0x44,0x90,0x91,0xa0,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0x12,0x4a,0xde,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e, +0x00,0xa8,0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00, +0x42,0xe0,0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13, +0xce,0x13,0xd8,0xf8,0xff,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0xe4,0xf5,0x10,0x75,0x11,0x04,0xf5,0x12,0xf5,0x14,0xf5,0x15,0x90,0x02,0x09, +0xe0,0xff,0x12,0x29,0xd9,0xfe,0xef,0x2e,0xf5,0x13,0x30,0xe0,0x08,0x75,0x0e,0x00, +0x75,0x0f,0x80,0x80,0x05,0xe4,0xf5,0x0e,0xf5,0x0f,0xe5,0x13,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x74,0x20,0x25,0x10,0xf5,0x10,0xad,0x0f,0xe5,0x10,0x2d,0xff,0x24,0x01, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x90,0x91,0x47,0xf0,0x74,0x02,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xfe,0xe5,0x10,0x2d,0x24,0x03,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x24,0x00,0xff,0xe4,0x3e,0x90,0x91,0x48,0xf0,0xa3,0xef, +0xf0,0x7f,0x04,0xe5,0x10,0x25,0x0f,0x2f,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfc,0xf5, +0x83,0xe0,0xfe,0x74,0x46,0x2f,0xf5,0x82,0xe4,0x34,0x91,0xf5,0x83,0xee,0xf0,0x0f, +0xbf,0x08,0xe0,0x12,0x66,0x56,0xef,0x70,0x3f,0x90,0x01,0xc3,0xe0,0x60,0x25,0xc3, +0xe5,0x15,0x94,0xe8,0xe5,0x14,0x94,0x03,0x40,0x09,0x90,0x01,0xc6,0xe0,0x44,0x10, +0xf0,0x80,0x63,0x05,0x15,0xe5,0x15,0x70,0x02,0x05,0x14,0x7f,0x0a,0x7e,0x00,0x12, +0x37,0x54,0x80,0xd5,0x90,0x01,0xc6,0xe0,0x90,0x01,0xc3,0x30,0xe2,0x05,0x74,0xfe, +0xf0,0x80,0x43,0x74,0xff,0xf0,0x80,0x3e,0xe5,0x10,0xb4,0x78,0x23,0xe4,0xf5,0x10, +0x05,0x13,0xe5,0x0f,0x64,0x80,0x45,0x0e,0x70,0x06,0xf5,0x0e,0xf5,0x0f,0x80,0x06, +0x75,0x0e,0x00,0x75,0x0f,0x80,0xe5,0x13,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x80,0x06, +0x74,0x08,0x25,0x10,0xf5,0x10,0xe5,0x12,0x15,0x12,0x70,0x02,0x15,0x11,0xe5,0x12, +0x45,0x11,0x60,0x02,0x81,0xb8,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x1c,0x12,0x43, +0x41,0x12,0x29,0xd9,0xff,0x54,0x01,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xfe,0x4e,0xf0, +0xef,0x54,0x04,0xff,0xe0,0x54,0xfb,0x4f,0xf0,0x12,0x29,0xd9,0xff,0x54,0x02,0xfe, +0x90,0x91,0x5e,0xe0,0x54,0xfd,0x4e,0xf0,0xef,0x54,0x08,0xff,0xe0,0x54,0xf7,0x4f, +0xf0,0x12,0x29,0xd9,0xff,0x54,0x10,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xef,0x4e,0xf0, +0xef,0x54,0x20,0xff,0xe0,0x54,0xdf,0x4f,0xf0,0x12,0x29,0xd9,0xff,0x54,0x40,0xfe, +0x90,0x91,0x5e,0xe0,0x54,0xbf,0x4e,0xf0,0xef,0x54,0x80,0xff,0xe0,0x54,0x7f,0x4f, +0xf0,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x60,0xf0,0x90,0x00,0x01,0x12,0x42, +0x20,0x90,0x91,0x5f,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff,0x54,0x01,0xfe,0x90, +0x91,0x61,0xe0,0x54,0xfe,0x4e,0xf0,0xef,0x54,0x02,0xff,0xe0,0x54,0xfd,0x4f,0xf0, +0x90,0x00,0x03,0x12,0x42,0x20,0x54,0x04,0xff,0x90,0x91,0x61,0xe0,0x54,0xfb,0x4f, +0xf0,0x90,0x91,0x5e,0xe0,0x54,0x01,0x90,0x01,0xb8,0xf0,0x90,0x91,0x5e,0xe0,0xff, +0xc4,0x13,0x54,0x01,0x90,0x01,0xb9,0xf0,0x90,0x91,0x61,0xe0,0x54,0x01,0x90,0x01, +0xba,0xf0,0xa3,0x74,0xff,0xf0,0x12,0x29,0xd9,0x20,0xe0,0x02,0x21,0xf1,0xe4,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x29,0xd9,0xff,0xc3, +0x13,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x02,0xf0,0xef,0x13,0x13,0x54,0x3f, +0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x04,0xf0,0x12,0x29,0xd9,0x13,0x13,0x13, +0x54,0x1f,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x08,0xf0,0x90,0x91,0x61,0xe0, +0x30,0xe0,0x1c,0x90,0x91,0x5e,0xe0,0xc4,0x13,0x54,0x07,0x30,0xe0,0x07,0xa3,0xe0, +0xff,0xe4,0xfd,0x80,0x07,0x90,0x91,0x5f,0xe0,0xff,0x7d,0x01,0x12,0x4a,0xf6,0x22, +0x75,0x30,0x1f,0x75,0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0,0xa3, +0xe5,0x31,0xf0,0xa3,0xe5,0x32,0xf0,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x7f,0x01, +0x60,0x02,0x7f,0x00,0x22,0x12,0x29,0xd9,0xf5,0x6d,0x22,0x90,0x01,0x64,0x74,0xa0, +0xf0,0x22,0x90,0x91,0x51,0xe0,0x90,0x90,0xe8,0xf0,0x22,0x90,0x00,0xf3,0xe0,0x7f, +0x00,0x30,0xe3,0x02,0x7f,0x01,0x22,0x90,0x06,0x34,0x74,0xff,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0x22,0xe4,0x90,0x91,0x4e,0xf0,0x90,0x00,0x80,0xe0,0x44,0x80, +0xfd,0x7f,0x80,0x02,0x4b,0xee,0x90,0x00,0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41, +0x74,0x10,0xf0,0x90,0x05,0x5a,0xf0,0xa3,0xe4,0xf0,0x22,0x12,0x29,0xd9,0x60,0x02, +0x80,0x01,0xe4,0x90,0x91,0x31,0xf0,0x90,0x91,0x31,0xe0,0x90,0x01,0xe7,0xf0,0x22, +0x90,0x91,0x51,0xe0,0xb4,0x01,0x0c,0x90,0x00,0xf2,0xe0,0x30,0xe7,0x05,0x7e,0xfd, +0x7f,0x33,0x22,0x7e,0xfd,0x7f,0x2f,0x22,0x12,0x29,0xd9,0xff,0x54,0x01,0xfe,0x90, +0x91,0x53,0xe0,0x54,0xfe,0x4e,0xf0,0xef,0xc3,0x13,0x30,0xe0,0x0a,0x90,0x00,0x01, +0x12,0x42,0x20,0x90,0x91,0x54,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x90, +0xf7,0xf0,0xe0,0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5,0x0e,0xc2, +0xaf,0x90,0x00,0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x4b,0xee,0x7d,0x40,0x7f, +0x01,0x12,0x36,0xaf,0xe5,0x0e,0x24,0xff,0x92,0xaf,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,0xcb,0xf0,0x74,0x57, +0xa3,0xf0,0x90,0x01,0x34,0xe0,0x55,0x28,0xf5,0x2c,0x90,0x01,0x36,0xe0,0x55,0x2a, +0xf5,0x2e,0xa3,0xe0,0x55,0x2b,0xf5,0x2f,0xe5,0x2c,0x30,0xe0,0x5a,0x90,0x01,0x34, +0x74,0x01,0xf0,0x85,0xd9,0x54,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80,0x48,0x90, +0x91,0x3b,0xe0,0x60,0x3a,0x90,0x01,0x5b,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0, +0x51,0x30,0xef,0x64,0x01,0x70,0x30,0x90,0x91,0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90, +0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44,0x59,0x90,0x01,0x5b, +0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x90,0x91,0x37,0xf0,0x80,0x08,0x51, +0x30,0xbf,0x01,0x03,0x12,0x44,0xc2,0xe5,0x2c,0x30,0xe1,0x20,0x90,0x01,0x34,0x74, +0x02,0xf0,0x85,0xd1,0x58,0x85,0xd2,0x59,0x85,0xd3,0x5a,0x85,0xd4,0x5b,0x85,0xd5, +0x5c,0x85,0xd6,0x5d,0x85,0xd7,0x5e,0x85,0xd9,0x5f,0x71,0x5c,0xe5,0x2c,0x30,0xe3, +0x10,0x90,0x01,0x34,0x74,0x08,0xf0,0x90,0x91,0x56,0xe0,0x30,0xe0,0x03,0x43,0x57, +0x04,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01,0x34,0x74,0x10,0xf0,0x43,0x57,0x10,0xe5, +0x2c,0x30,0xe5,0x26,0x90,0x01,0xcf,0xe0,0x30,0xe5,0x1f,0xe0,0x54,0xdf,0xf0,0x90, +0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00,0x75,0xe8,0x00,0x12,0x4e,0xe4,0x90,0x00, +0x03,0xe0,0x54,0xfb,0xf0,0x12,0x4a,0xe6,0x80,0xfe,0xe5,0x2c,0x30,0xe6,0x06,0x90, +0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe0,0x13,0x90,0x91,0x50,0x74,0x01,0xf0, +0x90,0x01,0x36,0xf0,0x91,0x23,0x51,0x87,0x90,0x91,0x50,0xe4,0xf0,0xe5,0x2e,0x30, +0xe1,0x3c,0x90,0x01,0x36,0x74,0x02,0xf0,0x43,0x57,0x40,0x90,0x01,0x02,0xe0,0x54, +0x03,0x64,0x01,0x70,0x29,0x90,0x01,0x37,0xe0,0x30,0xe0,0x0a,0x74,0x01,0xf0,0x90, +0x91,0x40,0xe4,0xf0,0x80,0x18,0x90,0x91,0x40,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a, +0x40,0x0c,0xe4,0xf0,0x90,0x04,0x19,0xe0,0x30,0xe0,0x03,0x12,0x4f,0xf5,0xe5,0x2e, +0x30,0xe2,0x19,0x90,0x01,0x36,0x74,0x04,0xf0,0x90,0x91,0x3a,0xe4,0xf0,0x90,0x05, +0x58,0x74,0x03,0xf0,0x51,0xd8,0x90,0x91,0x3f,0xe0,0x04,0xf0,0xe5,0x2e,0x30,0xe3, +0x28,0x90,0x01,0x36,0x74,0x08,0xf0,0xe5,0x6d,0x64,0x01,0x70,0x1c,0xe5,0x70,0x60, +0x18,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x91,0x66,0xe4, +0x12,0x44,0x49,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x2e,0x30,0xe4,0x2b,0x90,0x01, +0x36,0x74,0x10,0xf0,0xe5,0x6d,0xb4,0x01,0x20,0xe5,0x70,0x60,0x1c,0x90,0x01,0x57, +0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x91,0x3c,0xe4,0xf0,0x53,0x71,0xfd, +0xe5,0x71,0x54,0x07,0x70,0x03,0x12,0x44,0xc2,0xe5,0x2e,0x30,0xe5,0x1f,0x90,0x01, +0x36,0x74,0x20,0xf0,0xe5,0x6d,0xb4,0x01,0x14,0xe5,0x70,0x60,0x10,0x90,0x91,0x3b, +0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xc8,0x80,0x03,0x12,0x44,0x77,0xe5,0x2e,0x30, +0xe6,0x1b,0x90,0x01,0x36,0x74,0x40,0xf0,0xe5,0x6d,0xb4,0x01,0x10,0xe5,0x70,0x60, +0x0c,0x53,0x71,0xfe,0xe5,0x71,0x54,0x07,0x70,0x03,0x12,0x44,0xc2,0xe5,0x2f,0x30, +0xe1,0x08,0x90,0x01,0x37,0x74,0x02,0xf0,0x71,0x7e,0x74,0xcb,0x04,0x90,0x01,0xc4, +0xf0,0x74,0x57,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,0x04,0x1b,0xe0,0x54,0x7f,0x64,0x7f,0x7f,0x01,0x60,0x02,0x7f,0x00,0x22,0x51, +0x30,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x30,0x90,0x91, +0x37,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x22,0x90,0x91,0x36,0xe0, +0x60,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x14,0xe5,0x6f,0x54,0x0f,0xd3,0x94, +0x04,0x40,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01, +0xb8,0x74,0x08,0xf0,0x7f,0x00,0x22,0x90,0x91,0x53,0xe0,0x30,0xe0,0x49,0xe5,0x6d, +0x64,0x01,0x70,0x43,0x90,0x91,0x52,0xe0,0x04,0xf0,0xe5,0x70,0x64,0x03,0x60,0x05, +0xe5,0x70,0xb4,0x06,0x0d,0x90,0x91,0x52,0xe0,0xff,0x74,0x01,0xd3,0x9f,0x50,0x14, +0x80,0x07,0x90,0x91,0x52,0xe0,0xb4,0x0a,0x0b,0x90,0x91,0x55,0xe0,0x04,0xf0,0xe4, +0x90,0x91,0x52,0xf0,0x90,0x91,0x55,0xe0,0xff,0x90,0x91,0x54,0xe0,0xb5,0x07,0x07, +0x71,0x4e,0xe4,0x90,0x91,0x55,0xf0,0x22,0xe5,0x6d,0x64,0x01,0x70,0x63,0xe5,0x70, +0x60,0x5f,0xe5,0x70,0x64,0x02,0x60,0x06,0xe5,0x70,0x64,0x05,0x70,0x27,0x90,0x06, +0xab,0xe0,0x90,0x91,0x27,0xf0,0x90,0x06,0xaa,0xe0,0x90,0x91,0x39,0xf0,0x90,0x91, +0x27,0xe0,0x70,0x07,0x90,0x91,0x39,0xe0,0xff,0x80,0x05,0x90,0x91,0x27,0xe0,0xff, +0x90,0x91,0x27,0xef,0xf0,0x90,0x91,0x29,0xe0,0x60,0x03,0xe0,0x14,0xf0,0xe4,0x90, +0x91,0x28,0xf0,0x90,0x01,0x57,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x53,0x71,0xfd, +0x53,0x71,0xef,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0xc7,0x71, +0x42,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xd0,0xd0,0x92,0xaf,0x22,0xe5,0x6e, +0x30,0xe3,0x04,0xe4,0xff,0x80,0x02,0x7f,0x01,0x02,0x47,0xc9,0x90,0x91,0x08,0xe0, +0x54,0xf0,0x44,0x03,0xf0,0x54,0x0f,0x44,0x80,0xf0,0x7b,0x00,0x7a,0x00,0x79,0x58, +0x90,0x91,0x71,0x12,0x43,0x41,0x0b,0x7a,0x91,0x79,0x08,0x02,0x46,0xb7,0x90,0x91, +0x80,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80, +0x21,0x90,0x91,0x3b,0xe0,0x60,0x06,0x7d,0x01,0x7f,0x0c,0x80,0x0d,0xe5,0x6e,0x54, +0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27,0xe4,0xff,0x12, +0x48,0xb3,0x22,0x51,0x30,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0, +0x80,0x58,0xe5,0x71,0x54,0x03,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4a, +0xe5,0x6f,0x54,0x0f,0xd3,0x94,0x02,0x40,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80, +0x39,0xe5,0x71,0x30,0xe2,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x2c,0xe5,0x71, +0x30,0xe4,0x08,0x90,0x01,0xb9,0x74,0x10,0xf0,0x80,0x1f,0x90,0x91,0x29,0xe0,0x60, +0x08,0x90,0x01,0xb9,0x74,0x20,0xf0,0x80,0x11,0x90,0x91,0x31,0xe0,0x60,0x08,0x90, +0x01,0xb9,0x74,0x80,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0, +0x7f,0x00,0x22,0xe4,0xfb,0x90,0x91,0x78,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5, +0x70,0x70,0x02,0x81,0xb5,0xe5,0x6d,0x64,0x01,0x70,0x7a,0xe5,0x70,0x14,0x60,0x2b, +0x24,0xfd,0x60,0x27,0x24,0x02,0x24,0xfb,0x50,0x02,0x80,0x21,0x90,0x91,0x27,0xe0, +0x14,0xf0,0xe0,0x60,0x04,0xa3,0xe0,0x60,0x14,0x90,0x91,0x27,0xe0,0x70,0x08,0x90, +0x91,0x39,0xe0,0x90,0x91,0x27,0xf0,0x7b,0x01,0x80,0x02,0x7b,0x01,0xeb,0x60,0x45, +0x43,0x71,0x10,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4, +0xff,0x90,0x91,0x34,0xe0,0x2f,0x12,0x44,0x4e,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5, +0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27,0x90, +0x91,0x2e,0xe0,0x60,0x10,0x90,0x91,0x2c,0xe0,0x90,0x07,0x78,0x60,0x04,0x74,0x0d, +0xf0,0x22,0x74,0x09,0xf0,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,0xb6,0xf0,0x74,0x5c,0xa3,0xf0,0x53,0x91,0xef, +0x90,0x00,0x51,0xe0,0xff,0x90,0x00,0x55,0xe0,0x5f,0xf5,0x3d,0x90,0x00,0x52,0xe0, +0xff,0x90,0x00,0x56,0xe0,0x5f,0xf5,0x3e,0xe5,0x3d,0x30,0xe4,0x06,0x90,0x00,0x55, +0x74,0x10,0xf0,0xe5,0x3d,0x30,0xe5,0x06,0x90,0x00,0x55,0x74,0x20,0xf0,0xe5,0x3d, +0x30,0xe6,0x1b,0x90,0x00,0x55,0x74,0x40,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x0b,0x90,0x90,0xf3,0xe0,0x60,0x05,0x7f,0x01,0x12,0x4c,0x03,0xe5,0x3d, +0x30,0xe7,0x15,0x90,0x00,0x55,0x74,0x80,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x05,0x7f,0x02,0x12,0x4c,0x03,0xe5,0x3e,0x30,0xe0,0x06,0x90,0x00,0x56, +0x74,0x01,0xf0,0xe5,0x3e,0x30,0xe1,0x06,0x90,0x00,0x56,0x74,0x02,0xf0,0xe5,0x3e, +0x30,0xe2,0x06,0x90,0x00,0x56,0x74,0x04,0xf0,0xe5,0x3e,0x30,0xe3,0x06,0x90,0x00, +0x56,0x74,0x08,0xf0,0x90,0x01,0xc4,0x74,0xb6,0xf0,0x74,0x5c,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,0x75,0x0d,0x00,0x90,0x01,0xc4,0x74,0x99,0xf0,0x74, +0x5d,0xa3,0xf0,0x53,0x91,0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5,0x34,0xa3,0xe0, +0x55,0x31,0xf5,0x35,0xa3,0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55,0x33,0xf5,0x37, +0xe5,0x34,0x30,0xe0,0x06,0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34,0x30,0xe1,0x08, +0x90,0x01,0x3c,0x74,0x02,0xf0,0xf1,0x57,0xe5,0x34,0x30,0xe2,0x3a,0x90,0x01,0x3c, +0x74,0x04,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe0,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90, +0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44, +0x59,0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80,0x08,0x90, +0x91,0x37,0xe4,0xf0,0x12,0x44,0xc2,0xe5,0x34,0x30,0xe3,0x3a,0x90,0x01,0x3c,0x74, +0x08,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe1,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90,0x91, +0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x12,0x44,0x59, +0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x08,0x90,0x91, +0x36,0xe4,0xf0,0x12,0x44,0xc2,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10, +0xf0,0x12,0x53,0x86,0xe5,0x34,0x30,0xe5,0x09,0x90,0x01,0x3c,0x74,0x20,0xf0,0x12, +0x6e,0xb9,0xe5,0x35,0x30,0xe0,0x5a,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f, +0xe0,0x44,0x7f,0xf0,0x90,0x00,0x83,0xe0,0x54,0x0f,0xf5,0x0d,0xb4,0x01,0x02,0x80, +0x1c,0xe5,0x0d,0xb4,0x02,0x05,0x90,0x00,0x83,0x80,0x12,0xe5,0x0d,0xb4,0x04,0x05, +0x90,0x00,0x83,0x80,0x08,0xe5,0x0d,0xb4,0x0c,0x08,0x90,0x00,0x83,0xe0,0xf5,0x6f, +0x80,0x06,0x90,0x01,0xbe,0xe0,0x04,0xf0,0x90,0x01,0xbb,0xe5,0x6f,0xf0,0xe5,0x6f, +0x30,0xe0,0x03,0xa3,0x80,0x03,0x90,0x01,0xbd,0xe0,0x04,0xf0,0xf1,0x38,0x12,0x44, +0xc2,0xe5,0x35,0x30,0xe2,0x06,0x90,0x01,0x3d,0x74,0x04,0xf0,0xe5,0x36,0x30,0xe0, +0x06,0x90,0x01,0x3e,0x74,0x01,0xf0,0xe5,0x36,0x30,0xe1,0x06,0x90,0x01,0x3e,0x74, +0x02,0xf0,0x74,0x99,0x04,0x90,0x01,0xc4,0xf0,0x74,0x5d,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,0xe5,0x6f,0x30,0xe6,0x19,0xe5,0x6f,0x54, +0x0f,0xff,0x90,0x91,0x24,0xe0,0xfe,0x4f,0x90,0x01,0x2f,0xf0,0xee,0x64,0x80,0x90, +0x91,0x24,0xf0,0x53,0x6f,0xbf,0x22,0xe4,0x90,0x91,0x0d,0xf0,0xe5,0x70,0x70,0x02, +0xe1,0xe1,0x90,0x91,0x3c,0xe0,0x60,0x0d,0xe4,0xf0,0x53,0x71,0xfd,0xe5,0x71,0x54, +0x07,0x70,0x6e,0x80,0x69,0x90,0x91,0x28,0xe0,0x04,0xf0,0x53,0x71,0xef,0x90,0x91, +0x3a,0xe0,0x04,0xf0,0x90,0x91,0x0d,0xe0,0xf9,0xff,0x7e,0x00,0x24,0x01,0xfd,0xee, +0x33,0xfc,0x90,0x91,0x3a,0xe0,0xb5,0x05,0x06,0xe4,0xb5,0x04,0x02,0x80,0x12,0xef, +0x24,0x02,0xff,0xe4,0x3e,0xfe,0x90,0x91,0x3a,0xe0,0xb5,0x07,0x0a,0xe4,0xb5,0x06, +0x06,0x90,0x05,0x58,0xe0,0x04,0xf0,0xe9,0xff,0x90,0x91,0x2f,0xe0,0x2f,0xff,0xe4, +0x33,0xfe,0x90,0x91,0x28,0xe0,0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x40, +0x0d,0xe5,0x6d,0xb4,0x01,0x0b,0xa3,0xe0,0x70,0x07,0xe0,0x04,0xf0,0x22,0x12,0x44, +0xc2,0x22,0x8f,0x20,0x8c,0x21,0x8d,0x22,0x22,0x8f,0x23,0x8c,0x24,0x8d,0x25,0x22, +0xe4,0x90,0x91,0x11,0xf0,0xa3,0xf0,0x90,0x02,0x86,0xe0,0x20,0xe1,0x2c,0xc3,0x90, +0x91,0x12,0xe0,0x94,0x20,0x90,0x91,0x11,0xe0,0x94,0x03,0x40,0x0a,0x90,0x01,0xc6, +0xe0,0x44,0x20,0xf0,0x7f,0x00,0x22,0x90,0x91,0x11,0xe4,0x75,0xf0,0x01,0x12,0x42, +0x81,0x7f,0x01,0x7e,0x00,0x12,0x37,0x54,0x80,0xcd,0x7f,0x01,0x22,0x90,0x01,0xcc, +0xe0,0x54,0x0f,0x90,0x91,0x11,0xf0,0x90,0x91,0x11,0xe0,0xfd,0x70,0x02,0x21,0x6f, +0x90,0x91,0x9c,0xe0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33, +0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70,0x02,0x21,0x68,0x90,0x91,0x9c,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x15,0xe0,0x90,0x91,0x12,0xf0,0x75,0x63, +0x01,0x75,0x64,0x91,0x75,0x65,0x12,0x75,0x66,0x01,0x7b,0x01,0x7a,0x91,0x79,0x13, +0x12,0x46,0x6d,0x90,0x91,0x13,0xe0,0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x90,0x91, +0x9c,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90,0x00,0x88,0x12,0x43,0x15,0xe0,0x90, +0x91,0x14,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x02,0x90,0x00,0x89,0x12,0x43,0x15, +0xe0,0x90,0x91,0x15,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1,0x12, +0x43,0x15,0xe0,0x90,0x91,0x16,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01, +0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x17,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04, +0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90,0x91,0x18,0xf0,0x80,0x33,0xe0,0x75,0xf0, +0x04,0x90,0x01,0xd1,0x12,0x43,0x15,0xe0,0x90,0x91,0x14,0xf0,0x90,0x91,0x9c,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x15,0xf0,0x90,0x91, +0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90,0x91,0x16,0xf0, +0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x91,0x79,0x14,0x12,0x51,0xf8,0x90,0x91,0x11, +0xe0,0xff,0x90,0x91,0x9c,0xe0,0xfe,0x74,0x01,0xa8,0x06,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0x5f,0x90,0x91,0x11,0xf0,0x90,0x91,0x9c,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01,0xcc,0xf0,0x90,0x91,0x9c,0xe0, +0x04,0xf0,0xe0,0x54,0x03,0xf0,0x01,0x37,0x90,0x01,0xc6,0xe0,0x44,0x02,0xf0,0x22, +0xad,0x07,0x74,0x11,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x01,0xf0, +0x90,0x04,0x80,0xe0,0x54,0x0f,0xfc,0x74,0x14,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5, +0x83,0xe0,0x54,0xc0,0x4c,0xfd,0x74,0x14,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xed,0xf0,0x22,0xef,0x60,0x0f,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x44,0x10,0xf0,0x22,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0, +0x54,0xef,0xf0,0x22,0xe4,0xf5,0x6d,0xf5,0x71,0xf5,0x70,0x75,0x6f,0x0c,0x75,0x6e, +0x0c,0x90,0x91,0x3b,0xf0,0x90,0x91,0x37,0xf0,0x90,0x91,0x36,0xf0,0x90,0x91,0x39, +0x04,0xf0,0x90,0x91,0x27,0xf0,0xe4,0x90,0x91,0x3c,0xf0,0x90,0x91,0x29,0xf0,0x90, +0x91,0x34,0x74,0x07,0xf0,0xe4,0x90,0x91,0x28,0xf0,0x90,0x91,0x32,0xf0,0xa3,0x74, +0x03,0xf0,0x90,0x91,0x2f,0x74,0x0a,0xf0,0xa3,0x74,0x05,0xf0,0x90,0x91,0x2d,0x74, +0x14,0xf0,0x90,0x91,0x35,0x74,0x05,0xf0,0xe4,0x90,0x91,0x2b,0xf0,0x90,0x91,0x25, +0xf0,0x90,0x91,0x50,0xf0,0x90,0x91,0x31,0xf0,0x90,0x91,0x3a,0xf0,0x90,0x91,0x26, +0xf0,0x90,0x91,0x38,0xf0,0x90,0x91,0x2e,0xf0,0x90,0x91,0x2c,0xf0,0x22,0xe4,0x90, +0x91,0x3c,0xf0,0x90,0x91,0x28,0xf0,0xf5,0x71,0x22,0x90,0x06,0x04,0xe0,0x54,0xbf, +0xf0,0xef,0x60,0x0a,0xe5,0x6d,0xb4,0x01,0x05,0xe4,0xff,0x12,0x47,0xc9,0x53,0x6e, +0xf0,0x43,0x6e,0x0c,0x22,0x90,0x91,0x9d,0xef,0xf0,0x51,0x7e,0x90,0x91,0x9d,0xe0, +0x60,0x05,0x90,0x05,0x22,0xe4,0xf0,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x90,0x00, +0x11,0xe0,0x44,0x09,0xf0,0x12,0x4a,0xe6,0x90,0x90,0xd8,0x12,0x43,0x09,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0xdc,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90, +0xe0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f, +0xd9,0x90,0x90,0xe4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd, +0xff,0x12,0x34,0x81,0x90,0x91,0x51,0xe0,0xb4,0x01,0x11,0x90,0x80,0x59,0x12,0x2a, +0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd,0x7f,0x01,0x12,0x34,0x81,0x22,0x8f,0x77,0xe4, +0x90,0x91,0x96,0xf0,0xa3,0xf0,0x90,0x01,0x09,0xe0,0x7f,0x00,0x30,0xe7,0x02,0x7f, +0x01,0xef,0x65,0x77,0x60,0x3e,0xc3,0x90,0x91,0x97,0xe0,0x94,0x88,0x90,0x91,0x96, +0xe0,0x94,0x13,0x40,0x08,0x90,0x01,0xc6,0xe0,0x44,0x80,0xf0,0x22,0x90,0x91,0x96, +0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x7f,0x14,0x7e,0x00,0x12,0x37,0x54,0xd3,0x90, +0x91,0x97,0xe0,0x94,0x32,0x90,0x91,0x96,0xe0,0x94,0x00,0x40,0xb9,0x90,0x01,0xc7, +0xe0,0x30,0xe0,0xb2,0x22,0x22,0x53,0x6e,0xf0,0x43,0x6e,0x01,0x71,0x55,0x71,0x67, +0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0x22,0x8f,0x78,0x12,0x47,0xe6,0xef,0x64,0x01, +0x70,0x2e,0x90,0x91,0x44,0x12,0x48,0x1e,0xe5,0x78,0x60,0x10,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x80,0x0e,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x90,0x04,0x1f,0x74,0x20,0xf0, +0x22,0xe4,0xfb,0x90,0x91,0x7c,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x70,0x60, +0x5f,0xe5,0x6d,0x64,0x01,0x70,0x59,0x0b,0x90,0x91,0x27,0xf0,0x04,0x60,0x51,0x43, +0x71,0x10,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4,0xff, +0x90,0x91,0x34,0xe0,0x2f,0x90,0x91,0x67,0xf0,0xe4,0x1b,0x12,0x44,0x54,0x90,0x01, +0x57,0x74,0x05,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f, +0x04,0x12,0x47,0x27,0x90,0x91,0x2e,0xe0,0x60,0x11,0x90,0x91,0x2c,0xe0,0x90,0x07, +0x78,0x60,0x05,0x74,0x0d,0xf0,0x80,0x03,0x74,0x09,0xf0,0x90,0x05,0x22,0xe4,0xf0, +0x22,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0xd3,0x10,0xaf,0x01, +0xc3,0xc0,0xd0,0x90,0x91,0x84,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0, +0x90,0x91,0x84,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90, +0x91,0x87,0xe0,0x94,0xe8,0x90,0x91,0x86,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6, +0xe0,0x44,0x10,0xf0,0x7f,0x00,0x80,0x15,0x90,0x91,0x86,0xe4,0x75,0xf0,0x01,0x12, +0x42,0x81,0x7f,0x0a,0x7e,0x00,0x12,0x37,0x54,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92, +0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90, +0x91,0x1f,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0x90,0x91,0x1c,0x12,0x43,0x21,0x90, +0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x3b,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x90, +0x91,0x25,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x01,0x90,0x91,0x26,0xf0, +0xef,0xc3,0x13,0x54,0x01,0x90,0x91,0x2e,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff, +0x13,0x13,0x54,0x01,0x90,0x91,0x2c,0xf0,0x90,0x91,0x2e,0xe0,0x90,0x91,0x1f,0x70, +0x26,0x12,0x2a,0x8b,0x00,0x00,0x02,0x10,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x60,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x91,0x1f,0x12,0x2a, +0x8b,0x00,0x00,0x03,0x10,0x80,0x24,0x12,0x2a,0x8b,0x00,0x00,0x01,0x10,0x90,0x91, +0x1f,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x60,0x7e,0x08,0x12,0x2f, +0xd9,0x90,0x91,0x1f,0x12,0x2a,0x8b,0x00,0x00,0x03,0x00,0x90,0x91,0x1f,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x91, +0x26,0xe0,0x70,0x3d,0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x27, +0xde,0x90,0x91,0x1f,0x12,0x2a,0x7f,0x90,0x91,0x1f,0x12,0x43,0x09,0xec,0x44,0x02, +0xfc,0x90,0x91,0x1f,0x12,0x2a,0x7f,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x02,0x86,0xe0,0x54,0xfb, +0xf0,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x49,0x7f,0x90,0x01,0xe5,0xe5,0x70,0xf0, +0x90,0x91,0x3b,0xe0,0x90,0x01,0xe6,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x02, +0x12,0x42,0x20,0xff,0x30,0xe0,0x25,0x12,0x29,0xd9,0x90,0x91,0x2f,0xf0,0x90,0x00, +0x01,0x12,0x42,0x20,0x90,0x91,0x30,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x91,0x2d, +0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x90,0x91,0x35,0xf0,0x22,0x90,0x91,0x2f,0x74, +0x0a,0xf0,0x90,0x91,0x30,0x74,0x05,0xf0,0x90,0x91,0x2d,0x74,0x14,0xf0,0x90,0x91, +0x35,0x74,0x05,0xf0,0x22,0x12,0x29,0xd9,0x30,0xe0,0x19,0xc3,0x13,0x54,0x7f,0x90, +0x91,0x34,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x91,0x32,0xe4,0xf0,0xa3, +0xef,0xf0,0x80,0x0f,0x90,0x91,0x34,0x74,0x07,0xf0,0x90,0x91,0x32,0xe4,0xf0,0xa3, +0x74,0x03,0xf0,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0x90,0x02, +0x09,0xe0,0xfd,0x12,0x29,0xd9,0xfe,0xaf,0x05,0xed,0x2e,0x90,0x91,0x41,0xf0,0x90, +0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x42,0xf0,0x90,0x00,0x02,0x12, +0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x43,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff, +0xed,0x2f,0x90,0x91,0x44,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0xae,0x05,0xed, +0x2f,0x90,0x91,0x45,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x47, +0xe0,0x90,0x91,0x1d,0xf0,0x90,0x91,0x48,0xe0,0xf5,0x19,0xa3,0xe0,0xf5,0x1a,0xe4, +0xf5,0x16,0x74,0x4a,0x25,0x16,0xf5,0x82,0xe4,0x34,0x91,0xf5,0x83,0xe0,0xff,0x74, +0x1b,0x25,0x16,0xf8,0xa6,0x07,0x05,0x16,0xe5,0x16,0xb4,0x04,0xe5,0x90,0x91,0x1d, +0xe0,0x12,0x43,0x4a,0x66,0xb3,0x00,0x67,0xdc,0x01,0x66,0xba,0x02,0x66,0xba,0x03, +0x66,0xba,0x04,0x67,0xdc,0x05,0x67,0xac,0x80,0x67,0xc2,0x81,0x67,0xdc,0x82,0x00, +0x00,0x67,0xd8,0xaf,0x1e,0x12,0x73,0xea,0xe1,0xdc,0x90,0x91,0x1d,0xe0,0xff,0xb4, +0x02,0x08,0x90,0x91,0x1c,0x74,0x01,0xf0,0x80,0x0f,0xef,0x90,0x91,0x1c,0xb4,0x03, +0x05,0x74,0x02,0xf0,0x80,0x03,0x74,0x04,0xf0,0xc3,0xe5,0x19,0x94,0x08,0x50,0x49, +0xe4,0xf5,0x16,0x90,0x91,0x1c,0xe0,0xff,0xe5,0x16,0xc3,0x9f,0x40,0x02,0xe1,0xdc, +0xc3,0xe5,0x19,0x94,0x01,0x50,0x14,0xe5,0x16,0x25,0x1a,0xff,0xc3,0x74,0x03,0x95, +0x16,0x24,0x1b,0xf8,0xe6,0xfd,0x12,0x4b,0xee,0x80,0x1a,0xc3,0x74,0x03,0x95,0x16, +0x24,0x1b,0xf8,0xe6,0xff,0xe5,0x16,0x7c,0x00,0x25,0x1a,0xfd,0xec,0x35,0x19,0x8d, +0x82,0xf5,0x83,0xef,0xf0,0x05,0x16,0x80,0xba,0xc3,0xe5,0x19,0x94,0x10,0x40,0x02, +0xe1,0xdc,0x90,0x91,0x1d,0xe0,0x64,0x04,0x60,0x02,0xe1,0xdc,0xaf,0x1c,0xfc,0xfd, +0xfe,0x78,0x10,0x12,0x2a,0x6c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0xaf,0x1b, +0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x2a,0x6c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0, +0x00,0x12,0x42,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0xaf,0x1d,0xe4,0xfc, +0xfd,0xfe,0x78,0x08,0x12,0x2a,0x6c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12, +0x42,0xfc,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xaf,0x1e,0xe4,0xfc,0xfd,0xfe, +0x12,0x42,0xfc,0xa3,0x12,0x2a,0x7f,0x90,0x91,0x1e,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0xaf,0x1a,0xae,0x19,0x12,0x2f,0xd9,0x80,0x30,0xe5,0x1d,0x7f,0x00, +0xfe,0xef,0x25,0x1e,0xf5,0x18,0xe4,0x3e,0xf5,0x17,0xaf,0x18,0xfe,0x12,0x37,0x54, +0x80,0x1a,0xe5,0x1d,0x7f,0x00,0xfe,0xef,0x25,0x1e,0xf5,0x18,0xe4,0x3e,0xf5,0x17, +0xaf,0x18,0xfe,0x12,0x36,0xcb,0x80,0x04,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0, +0x92,0xaf,0x22,0x22,0x8e,0x0e,0x8f,0x0f,0x8b,0x10,0x8a,0x11,0x89,0x12,0xe4,0x90, +0x91,0x11,0xf0,0xef,0x90,0x00,0x31,0xf0,0x12,0x4a,0xe6,0xe5,0x0e,0x54,0x03,0xff, +0x90,0x00,0x32,0xe0,0x54,0xfc,0x4f,0xf0,0x12,0x4a,0xe6,0x90,0x00,0x33,0xe0,0x54, +0x7f,0xf0,0x12,0x4a,0xe6,0x90,0x00,0x33,0xe0,0x20,0xe7,0x0e,0x90,0x91,0x11,0xe0, +0xc3,0x94,0x64,0x50,0x05,0xe0,0x04,0xf0,0x80,0xeb,0x90,0x91,0x11,0xe0,0xc3,0x94, +0x64,0x50,0x10,0x90,0x00,0x30,0xe0,0xab,0x10,0xaa,0x11,0xa9,0x12,0x12,0x42,0x4d, +0x7f,0x01,0x22,0x7f,0x00,0x22,0xe4,0x90,0x91,0x98,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,0x91,0x99,0xe0,0x94,0xe8,0x90,0x91,0x98,0xe0,0x94,0x03,0x40, +0x03,0x7f,0x00,0x22,0x7f,0x32,0x7e,0x00,0x12,0x37,0x54,0x90,0x91,0x98,0xe4,0x75, +0xf0,0x01,0x12,0x42,0x81,0x80,0xc6,0xef,0x70,0x02,0x41,0x3d,0x90,0x90,0xe8,0xe0, +0x60,0x02,0xc1,0x08,0x90,0x90,0xd4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x80,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x84,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x88, +0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x90,0x8c,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x90,0x90,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x94,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x98,0x12,0x43,0x09,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x9c,0x12, +0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x90,0xa0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x90,0xa4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x88, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xa8,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xac,0x12,0x43,0x09,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xb0,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd4,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90, +0xb4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd8,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x90,0xb8,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xdc,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x90,0xbc,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xc0,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xc4,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90,0xc8, +0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9, +0x90,0x90,0xcc,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09, +0x12,0x2f,0xd9,0x90,0x90,0xd0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x04,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0xe8,0x74,0x01,0xf0,0x22,0x90,0x90,0xe8, +0xe0,0x64,0x01,0x60,0x02,0xc1,0x08,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x90, +0xd4,0x12,0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0x80,0x12,0x2a, +0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0x84,0x12,0x2a,0x7f,0x7f,0x6c, +0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x88,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12, +0x27,0xde,0x90,0x90,0x8c,0x12,0x2a,0x7f,0x7f,0x74,0x7e,0x0e,0x12,0x27,0xde,0x90, +0x90,0x90,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x94,0x12, +0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x98,0x12,0x2a,0x7f,0x7f, +0x80,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x9c,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e, +0x12,0x27,0xde,0x90,0x90,0xa0,0x12,0x2a,0x7f,0x7f,0x88,0x7e,0x0e,0x12,0x27,0xde, +0x90,0x90,0xa4,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xa8, +0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xac,0x12,0x2a,0x7f, +0x7f,0xd4,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xb0,0x12,0x2a,0x7f,0x7f,0xd8,0x7e, +0x0e,0x12,0x27,0xde,0x90,0x90,0xb4,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e,0x12,0x27, +0xde,0x90,0x90,0xb8,0x12,0x2a,0x7f,0x7f,0xe0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90, +0xbc,0x12,0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xc0,0x12,0x2a, +0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x90,0xc4,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x0d,0x12,0x27,0xde,0x90,0x90,0xc8,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12, +0x27,0xde,0x90,0x90,0xcc,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90, +0x90,0xd0,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x91,0x88,0x12, +0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x44,0xc0,0xfd,0xec,0x90,0x91,0x88, +0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x01,0x00,0x00, +0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0xdb,0x25, +0xa4,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb, +0x25,0xa4,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20, +0xdb,0x25,0xa4,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b, +0x04,0x1b,0x25,0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a, +0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12, +0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85, +0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80, +0x85,0x12,0x2a,0x8b,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x80,0x85,0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd8,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f,0xdc, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f, +0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x24,0xdb,0x25,0xa4, +0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90,0x91,0x88, +0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0d,0x12,0x27,0xde,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90, +0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90, +0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x54,0x0f,0xfd, +0xec,0x54,0xf0,0xfc,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09, +0xed,0x44,0x10,0xfd,0xec,0x44,0x01,0xfc,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91, +0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f, +0xd9,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91, +0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90, +0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec,0x90,0x91,0x88,0x12,0x2a,0x7f, +0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08, +0x12,0x2f,0xd9,0xe4,0x90,0x90,0xe8,0xf0,0x22,0xe4,0xfd,0x7f,0x45,0x12,0x4b,0xee, +0x90,0x04,0xfd,0xe4,0xf0,0xa3,0xf0,0x90,0x90,0xf7,0xf0,0x90,0x90,0xfd,0xf0,0x90, +0x91,0x00,0xf0,0x90,0x90,0xfe,0xf0,0x90,0x91,0x01,0xf0,0x90,0x90,0xff,0xf0,0x90, +0x91,0x02,0xf0,0x90,0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90, +0x90,0xee,0xf0,0x90,0x90,0xf3,0xf0,0x90,0x90,0xf5,0xf0,0x90,0x91,0x07,0xf0,0x90, +0x90,0xf8,0xf0,0x90,0x90,0xf4,0xf0,0x90,0x90,0xed,0xf0,0x90,0x00,0x51,0xe0,0x44, +0xc0,0xfd,0x7f,0x51,0x02,0x4b,0xee,0x90,0x05,0x60,0xe0,0x90,0x91,0x03,0xf0,0x90, +0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x05,0xf0,0x90, +0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xc3,0x74,0xff,0x9f,0xfe,0x90,0x91,0x04,0xe0, +0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0,0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3,0xe0, +0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90,0x91,0x06,0x80,0x03,0x90,0x91,0x05,0xe0,0x04, +0xf0,0x22,0x90,0x91,0x04,0xe0,0x2f,0xf0,0x22,0x90,0x90,0xf5,0xe0,0x64,0x01,0x60, +0x02,0xe1,0x6e,0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x12,0x4b,0xee,0x90, +0x91,0x07,0xe0,0x70,0x32,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x80,0x06, +0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x90,0xf4,0xe0,0xff,0xd1,0x67,0x90,0x91,0x07, +0x74,0x01,0x12,0x4b,0xe4,0x80,0x40,0x90,0x91,0x07,0xe0,0x64,0x01,0x70,0x38,0x90, +0x90,0xf8,0xe0,0xff,0xd1,0x67,0xe4,0x90,0x91,0x07,0xf0,0x90,0x00,0x45,0xe0,0x44, +0x01,0xfd,0x7f,0x45,0x12,0x4b,0xee,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xef, +0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9, +0x80,0x05,0x90,0x05,0x22,0xe4,0xf0,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x91, +0x03,0xe0,0x90,0x05,0x84,0xf0,0x90,0x91,0x04,0xe0,0x90,0x05,0x85,0xf0,0x90,0x91, +0x05,0xe0,0x90,0x05,0x86,0xf0,0x90,0x91,0x06,0xe0,0x90,0x05,0x87,0xf0,0x22,0x90, +0x90,0xee,0xe0,0xc3,0x94,0x14,0x50,0x06,0xe0,0x04,0xf0,0x02,0x70,0x29,0x90,0x90, +0xee,0xe0,0x64,0x14,0x60,0x03,0x02,0x70,0x29,0x90,0x90,0xfd,0xe0,0x70,0x25,0x90, +0x91,0x00,0xe0,0x70,0x1f,0x90,0x90,0xfe,0xe0,0x70,0x19,0x90,0x91,0x01,0xe0,0x70, +0x13,0x90,0x90,0xff,0xe0,0x70,0x0d,0x90,0x91,0x02,0xe0,0x70,0x07,0x90,0x04,0xfd, +0xe0,0x54,0xfe,0xf0,0x90,0x90,0xfd,0xe0,0x90,0x04,0x44,0xf0,0x90,0x90,0xfe,0xe0, +0x90,0x04,0x45,0xf0,0x90,0x90,0xff,0xe0,0x90,0x04,0x46,0xf0,0xa3,0xe4,0xf0,0x90, +0x91,0x00,0xe0,0x90,0x04,0x48,0xf0,0x90,0x91,0x01,0xe0,0x90,0x04,0x49,0xf0,0x90, +0x91,0x02,0xe0,0x90,0x04,0x4a,0xf0,0xa3,0xe4,0xf0,0x90,0x90,0xe9,0xe0,0x90,0x04, +0x4c,0xf0,0x90,0x90,0xea,0xe0,0x90,0x04,0x4d,0xf0,0x90,0x90,0xeb,0xe0,0x90,0x04, +0x4e,0xf0,0x90,0x90,0xec,0xe0,0x90,0x04,0x4f,0xf0,0xe4,0x90,0x90,0xee,0xf0,0x90, +0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x90,0xfd,0xf0,0xa3, +0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x05,0x60,0xe0,0x90,0x91,0x8c, +0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x8d,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x8e, +0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x8f,0xf0,0x90,0x91,0x06,0xe0,0xff,0x90,0x91, +0x8f,0xe0,0xfe,0xd3,0x9f,0x50,0x0b,0x90,0x91,0x06,0xe0,0xc3,0x9e,0xd3,0x94,0x01, +0x40,0x11,0x90,0x90,0xf4,0xe0,0xb4,0x01,0x02,0x80,0x03,0x90,0x90,0xf8,0xe0,0xff, +0x12,0x6e,0x67,0x22,0x90,0x91,0x07,0xe0,0x64,0x01,0x60,0x08,0x90,0x90,0xf5,0xe0, +0x60,0x02,0x21,0x4b,0x90,0x90,0xe9,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0, +0x80,0x3b,0x90,0x90,0xea,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80, +0x28,0x90,0x90,0xeb,0xe0,0xc3,0x94,0xff,0x50,0x0a,0xe0,0x04,0xf0,0xe4,0x90,0x90, +0xea,0xf0,0x80,0x15,0x90,0x90,0xec,0xe0,0xc3,0x94,0xff,0x50,0x10,0xe0,0x04,0xf0, +0xe4,0x90,0x90,0xeb,0xf0,0x90,0x90,0xea,0xf0,0x90,0x90,0xe9,0xf0,0x90,0x00,0x44, +0xe0,0x54,0x0c,0x60,0x76,0xe0,0x30,0xe2,0x32,0x90,0x90,0xfd,0xe0,0xc3,0x94,0xff, +0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x90,0xfe,0xe0,0xc3,0x94,0xff,0x50,0x06, +0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x90,0xff,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0, +0x04,0xf0,0xe4,0x90,0x90,0xfe,0xf0,0x90,0x90,0xfd,0xf0,0x90,0x00,0x44,0xe0,0x30, +0xe3,0x32,0x90,0x91,0x00,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24, +0x90,0x91,0x01,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90, +0x91,0x02,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x91,0x01,0xf0, +0x90,0x91,0x00,0xf0,0x90,0x04,0xfd,0xe0,0x44,0x01,0xf0,0x22,0x90,0x06,0x90,0xe0, +0x44,0x01,0xf0,0x90,0x91,0x61,0xe0,0x30,0xe0,0x3c,0x90,0x91,0x5f,0xe0,0xff,0x90, +0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x54,0x01,0xfd,0x12,0x4a,0xf6,0x90,0x91,0x60,0xe0, +0x75,0xf0,0x20,0xa4,0xff,0xae,0xf0,0x12,0x37,0x54,0x90,0x91,0x5e,0xe0,0xc4,0x13, +0x54,0x07,0x30,0xe0,0x07,0xa3,0xe0,0xff,0xe4,0xfd,0x80,0x07,0x90,0x91,0x5f,0xe0, +0xff,0x7d,0x01,0x12,0x4a,0xf6,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xe4,0x90, +0x91,0x19,0xf0,0xa3,0x74,0x08,0xf0,0xa3,0xf0,0xe4,0xa3,0xf0,0x90,0x01,0x1f,0xe0, +0xfe,0x90,0x01,0x1e,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x91,0x11,0xf0, +0xa3,0xef,0xf0,0x90,0x02,0x87,0xe0,0x90,0x91,0x18,0xf0,0x90,0x91,0x56,0xe0,0x20, +0xe0,0x02,0x61,0xc4,0xe4,0x90,0x91,0x17,0xf0,0x90,0x91,0x18,0xe0,0xff,0x90,0x91, +0x17,0xe0,0xc3,0x9f,0x40,0x02,0x61,0xc4,0x90,0x91,0x11,0xe0,0xfc,0xa3,0xe0,0xfd, +0xec,0xff,0x90,0xfd,0x11,0xf0,0x90,0x91,0x1c,0xef,0xf0,0x74,0x02,0x2d,0xf5,0x82, +0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x54,0x0f,0xfc,0x33,0x33,0x33,0x54,0xf8,0xff,0xed, +0x24,0x18,0x2f,0x90,0x91,0x15,0xf0,0xe0,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x54,0xfc,0x90,0x91,0x16,0xf0,0x74,0x01,0x2d,0xf5,0x82,0xe4,0x34,0xfb, +0xf5,0x83,0xe0,0xfe,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7a, +0x00,0x24,0x00,0xff,0xea,0x3e,0x54,0x3f,0xab,0x07,0xfa,0x90,0x91,0x13,0xf0,0xa3, +0xeb,0xf0,0xaf,0x04,0xef,0x75,0xf0,0x08,0xa4,0x24,0x18,0xff,0xe4,0x35,0xf0,0xfe, +0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x91,0x5a,0xe0,0xfe,0xa3,0xe0,0xff,0xad,0x03, +0xac,0x02,0x12,0x45,0x09,0xaa,0x06,0xab,0x07,0x90,0x91,0x15,0xe0,0x24,0x00,0xf5, +0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x30,0xe7,0x08,0x90,0x91,0x19,0x74,0x02,0xf0, +0x80,0x05,0xe4,0x90,0x91,0x19,0xf0,0xaf,0x03,0x90,0x91,0x11,0xea,0x8f,0xf0,0x12, +0x42,0x81,0x90,0x91,0x5c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x91,0x11,0xe0,0xfc,0xa3, +0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x1b,0x90,0x91,0x5d,0xe0,0x24,0x01,0xff,0x90, +0x91,0x5c,0xe0,0x34,0x00,0xfe,0xc3,0xed,0x9f,0xff,0xec,0x9e,0x90,0x91,0x11,0xf0, +0xa3,0xef,0xf0,0x90,0x91,0x16,0xe0,0xff,0x24,0x40,0x60,0x04,0x24,0x20,0x70,0x27, +0x90,0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x13,0x13,0x54,0x01,0x20,0xe0,0x02,0x61,0x9c, +0xef,0x90,0x00,0x81,0xb4,0xa0,0x05,0xe0,0x44,0x04,0x80,0x03,0xe0,0x44,0x08,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x61,0x95,0x90,0x91,0x5e,0xe0,0xc4,0x13,0x13,0x54,0x03, +0x20,0xe0,0x02,0x61,0x9c,0x90,0x91,0x15,0xe0,0xff,0x24,0x00,0xf5,0x82,0xe4,0x34, +0xfb,0xf5,0x83,0xe0,0x54,0x0c,0x64,0x08,0x70,0x72,0x90,0x91,0x19,0xe0,0xfe,0xef, +0x2e,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x1e,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0, +0x64,0x88,0x70,0x58,0x74,0x1f,0x2f,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x64, +0x8e,0x70,0x49,0x90,0x91,0x19,0xe0,0xff,0x90,0x91,0x15,0xe0,0x2f,0xff,0x90,0x91, +0x1a,0xe0,0x2f,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x19,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x64,0x03,0x70,0x26,0x74,0x1e,0x2f,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83, +0xe0,0x90,0x00,0x81,0x30,0xe3,0x05,0xe0,0x44,0x01,0x80,0x03,0xe0,0x44,0x02,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x90,0x91,0x56,0xe0,0x44,0x80,0xf0,0x90,0x91,0x56,0xe0, +0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x30,0xe0,0x02,0x31,0x4c,0x71,0xc9,0xbf,0x01, +0x13,0x90,0x91,0x11,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x44,0xb5,0x90,0x91,0x17,0xe0, +0x04,0xf0,0x21,0xd9,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x56,0xe0,0xc4,0x13,0x13, +0x13,0x54,0x01,0x30,0xe0,0x11,0xe0,0x44,0x80,0xf0,0x90,0x91,0x5e,0xe0,0xc4,0x54, +0x0f,0x20,0xe0,0x03,0x7f,0x00,0x22,0x7f,0x01,0x22,0x8f,0x1f,0xe4,0x90,0x91,0x22, +0xf0,0xe5,0x1f,0x14,0xfe,0x90,0x91,0x22,0xe0,0xff,0xc3,0x9e,0x50,0x0e,0xef,0x04, +0xfd,0x12,0x34,0xb7,0x90,0x91,0x22,0xe0,0x04,0xf0,0x80,0xe5,0xe5,0x1f,0x14,0xff, +0x7d,0xff,0x12,0x34,0xb7,0x90,0x91,0x22,0xe5,0x1f,0xf0,0x90,0x91,0x22,0xe0,0xc3, +0x94,0xff,0x50,0x0f,0xe0,0xff,0x04,0xfd,0x12,0x34,0xb7,0x90,0x91,0x22,0xe0,0x04, +0xf0,0x80,0xe8,0xad,0x1f,0x7f,0xff,0x02,0x34,0xb7,0xc3,0xee,0x94,0x01,0x40,0x0a, +0x0d,0xed,0x13,0x90,0xfd,0x10,0xf0,0xe4,0x2f,0xff,0x22,0xc3,0xee,0x94,0x01,0x40, +0x1e,0x90,0xfd,0x11,0xe0,0xb5,0x05,0x14,0x90,0x01,0x17,0xe0,0xb5,0x05,0x07,0x90, +0xfd,0x11,0xe4,0xf0,0x80,0x06,0xed,0x04,0x90,0xfd,0x11,0xf0,0xe4,0x2f,0xff,0x22, +0x0f,0x75,}; + +u8 Rtl8192CUFwUMCACutWWImgArray[UMCACutWWImgArrayLength] = { +0xc1,0x88,0x02,0x00,0x51,0x00,0x00,0x00,0x03,0x23,0x16,0x44,0x72,0x34,0x01,0x00, +0x58,0x92,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x57,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x5c,0xb6,0x00,0x00,0x00,0x00,0x00,0x02,0x5d,0x99,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5, +0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8, +0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08, +0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xf8, +0xbb,0x01,0x11,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5, +0xf0,0xa3,0xf0,0x22,0x50,0x09,0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb, +0xfe,0x09,0xe9,0x25,0x82,0xc8,0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee, +0x4a,0xfe,0xed,0x49,0xfd,0xec,0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0, +0xfe,0xa3,0xe0,0xff,0x22,0xa4,0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83, +0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0, +0xf9,0x25,0xf0,0xf0,0xe5,0x82,0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0, +0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4, +0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5, +0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf, +0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3, +0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0xb5,0xf0, +0x06,0x74,0x03,0x93,0x68,0x60,0xe9,0xa3,0xa3,0xa3,0xa3,0x80,0xd8,0x02,0x43,0xdb, +0x02,0x50,0x2a,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2, +0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33, +0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf, +0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x20,0xe4,0x7e, +0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x91,0x40,0x00,0x41,0x91,0x9c,0x00,0x41,0x91,0x23,0x80,0x41,0x91,0x24,0x80, +0x41,0x91,0x9e,0x00,0x41,0x91,0x52,0x00,0x41,0x91,0x93,0x00,0x41,0x91,0x91,0x00, +0x41,0x91,0x90,0x00,0x41,0x91,0x92,0x00,0x00,0xf0,0x90,0x91,0x30,0xe0,0x90,0x91, +0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x54,0x7e,0x01,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0x65,0xeb,0xf0,0xa3,0xe0,0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5,0x45,0x12, +0x30,0x62,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01,0x3c,0x74, +0x08,0xf0,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4, +0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x59,0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06, +0x92,0x74,0x02,0xf0,0x90,0x91,0x36,0x14,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x0c, +0x50,0x02,0xf1,0x23,0x22,0x90,0x02,0x84,0xef,0xf0,0xa3,0xee,0xf0,0xa3,0x74,0x05, +0xf0,0x22,0x7d,0x01,0xaf,0x6f,0xe1,0x27,0xf1,0xe6,0xbf,0x01,0x10,0x90,0x91,0x42, +0xe0,0xff,0xe4,0xfd,0x12,0x48,0x22,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x8f,0x82, +0x8e,0x83,0xa3,0xa3,0xa3,0xe4,0xf0,0x22,0xe4,0xf5,0x72,0x7f,0x60,0x7e,0x01,0x80, +0xed,0x7f,0x00,0x22,0x90,0x91,0x53,0xe0,0x54,0xfe,0xf0,0x02,0x50,0xd6,0x22,0xe4, +0xf5,0x75,0x22,0x02,0x5f,0xe2,0x02,0x5f,0xe9,0xef,0x8e,0xf0,0x71,0x70,0x45,0x26, +0x00,0x40,0x45,0x4e,0x00,0x80,0x45,0x79,0x01,0x00,0x45,0x8d,0x02,0x00,0x45,0xa5, +0x04,0x00,0x00,0x00,0x45,0xc2,0xed,0x54,0x3f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x00,0x7f,0x40,0xef,0x2d,0xff,0xee,0x3c,0xfe,0xef,0x78,0x06,0xce,0xc3,0x13,0xce, +0x13,0xd8,0xf9,0x78,0x06,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x80,0x26,0xed,0x54, +0x7f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x00,0x7f,0x80,0xef,0x2d,0xff,0xee,0x3c, +0xfe,0xef,0x78,0x07,0xce,0xc3,0x13,0xce,0x13,0xd8,0xf9,0x78,0x07,0xc3,0x33,0xce, +0x33,0xce,0xd8,0xf9,0xfd,0xac,0x06,0x80,0x49,0xed,0x70,0x04,0xfe,0xff,0x80,0x04, +0x7e,0x01,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x7d,0x00,0xfc,0x80,0x35,0xec,0x54,0x01, +0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x02,0x7f,0x00,0xef,0x2d,0xee,0x3c,0xc3, +0x13,0x7d,0x00,0x80,0x1a,0xec,0x54,0x03,0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x04,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x13,0x13,0x54,0x3f,0x7d,0x00,0x25,0xe0,0x25, +0xe0,0xfc,0xae,0x04,0xaf,0x05,0x22,0x90,0x91,0x09,0x12,0x25,0x14,0x00,0x00,0x00, +0x00,0x90,0x06,0xa9,0xe0,0x90,0x91,0x08,0xf0,0xe0,0x54,0xc0,0x70,0x0a,0x53,0x71, +0xfe,0x53,0x71,0xfd,0x91,0xc2,0x80,0x47,0x90,0x91,0x26,0xe0,0x60,0x41,0x90,0x91, +0x38,0xe0,0x70,0x3b,0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x22, +0x65,0x90,0x91,0x09,0x12,0x25,0x08,0x90,0x91,0x09,0x71,0x09,0xec,0x44,0x02,0xfc, +0x90,0x91,0x09,0x12,0x25,0x08,0x90,0x91,0x09,0x71,0x09,0x90,0x80,0x96,0x12,0x25, +0x08,0x7f,0x00,0x7e,0x08,0x12,0x2b,0x08,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x90, +0x91,0x08,0xe0,0x30,0xe6,0x13,0x43,0x71,0x01,0x90,0x91,0x3b,0xe0,0x64,0x02,0x60, +0x04,0x91,0xc8,0x80,0x07,0x91,0x77,0x80,0x03,0x53,0x71,0xfe,0x90,0x91,0x08,0xe0, +0x30,0xe7,0x16,0x43,0x71,0x02,0xe4,0x90,0x91,0x66,0x91,0x49,0x90,0x01,0x57,0x74, +0x05,0xf0,0x90,0x91,0x3c,0x74,0x01,0xf0,0x22,0x53,0x71,0xfd,0x22,0xd3,0x10,0xaf, +0x01,0xc3,0xc0,0xd0,0x8b,0x60,0x8a,0x61,0x89,0x62,0x90,0x91,0x68,0x71,0x41,0xab, +0x63,0xaa,0x64,0xa9,0x65,0x90,0x91,0x6b,0x71,0x41,0xaf,0x66,0x15,0x66,0xef,0x60, +0x1b,0x90,0x91,0x6b,0xe4,0x75,0xf0,0x01,0x71,0x2a,0x12,0x24,0x62,0xff,0x90,0x91, +0x68,0xe4,0x75,0xf0,0x01,0x71,0x2a,0xef,0x51,0x4d,0x80,0xde,0xab,0x60,0xaa,0x61, +0xa9,0x62,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91, +0x6e,0x71,0x41,0x90,0x91,0x9e,0xe0,0xff,0x04,0xf0,0x90,0x00,0x01,0xef,0x51,0x5f, +0x7f,0xaf,0x7e,0x01,0x12,0x64,0x1c,0xef,0x60,0x44,0x90,0x91,0x6e,0x71,0x21,0x8b, +0x63,0x8a,0x64,0x89,0x65,0x75,0x66,0x02,0x7b,0x01,0x7a,0x01,0x79,0xa0,0xd1,0x6d, +0x90,0x91,0x71,0x71,0x21,0x8b,0x63,0x8a,0x64,0x89,0x65,0x90,0x91,0x6e,0x71,0x21, +0x12,0x24,0x62,0xff,0xc4,0x54,0x0f,0xf5,0x66,0x7b,0x01,0x7a,0x01,0x79,0xa2,0xd1, +0x6d,0x90,0x01,0xaf,0x74,0xff,0xf0,0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0,0xd0, +0x92,0xaf,0x22,0x7d,0x01,0x7f,0x0c,0x90,0x91,0x95,0xed,0xf0,0x90,0x91,0x94,0xef, +0xf0,0x54,0x0f,0xff,0xe5,0x6e,0x54,0x0f,0x6f,0x60,0x76,0x90,0x91,0x94,0xe0,0x30, +0xe2,0x30,0xe5,0x6e,0x20,0xe2,0x05,0x7f,0x01,0x12,0x62,0x65,0xe5,0x6e,0x30,0xe3, +0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3,0x08,0x12,0x5a,0x3f,0xef,0x60,0x53,0x80,0x52, +0xe5,0x6e,0x20,0xe3,0x4c,0x90,0x91,0x94,0xe0,0x30,0xe3,0x45,0xa3,0xe0,0xff,0x02, +0x62,0x4a,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x0c,0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3, +0x08,0x12,0x5a,0x3f,0xef,0x60,0x2a,0xf1,0xb2,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x04, +0x10,0x90,0x91,0x94,0xe0,0x20,0xe2,0x09,0x12,0x5b,0xb3,0xef,0x60,0x13,0x12,0x48, +0xce,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x02,0x08,0x91,0xf1,0xef,0x60,0x03,0x12,0x63, +0x56,0x22,0x90,0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x6d,0xb4,0x01,0x04,0x7f,0x01, +0xf1,0xc9,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x8f,0x67,0xf1,0xe6,0xbf,0x01,0x15, +0x90,0x91,0x43,0x12,0x48,0x1e,0xad,0x07,0xac,0x06,0xaf,0x67,0x12,0x61,0xa3,0x90, +0x04,0x1f,0x74,0x20,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x01,0xc4, +0x74,0xe6,0xf0,0x74,0x47,0xa3,0xf0,0x90,0x04,0x1d,0xe0,0x60,0x1a,0x90,0x05,0x22, +0xe0,0x54,0x90,0x60,0x07,0x90,0x01,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7,0xe0, +0x30,0xe1,0xe4,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0xe0,0xff, +0x7d,0x01,0x90,0x91,0x74,0xef,0xf0,0xa3,0xed,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5, +0x70,0x60,0x04,0xe4,0xff,0x11,0xb3,0x90,0x91,0x74,0xe0,0x30,0xe0,0x09,0x90,0x91, +0x76,0xe4,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x91,0x74,0xe0,0xff,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x90,0x04,0x25,0xef,0xf0,0x90,0x91,0x75,0xe0,0x60,0x1f,0xa3,0xa3,0xe0, +0xff,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10, +0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x90,0x91,0x76,0xa3, +0xe0,0xff,0xfd,0x24,0x08,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09, +0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x90,0x91,0x76,0xe0,0xfe,0xa3, +0xe0,0xff,0x22,0xef,0x60,0x0b,0x90,0x91,0x51,0xe0,0xb4,0x01,0x10,0xe4,0xff,0x80, +0x09,0x90,0x91,0x51,0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x68,0x87,0x22,0x90,0x01, +0x37,0x74,0x02,0xf0,0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x68,0x46,0xef,0x70,0x06, +0x90,0x01,0xc8,0x74,0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x31,0x9d,0xe5,0x70,0x60, +0x04,0x7f,0x01,0x11,0xb3,0x51,0x0c,0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0xef,0x64, +0x01,0x70,0x42,0x7d,0x78,0x7f,0x02,0x12,0x31,0x2c,0x7d,0x02,0x7f,0x03,0x12,0x31, +0x2c,0x90,0x01,0x36,0x74,0x03,0xf0,0xfd,0x7f,0x02,0x12,0x31,0x9d,0x7d,0x10,0x7f, +0x03,0x12,0x31,0x49,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x12, +0x47,0x23,0xe4,0xff,0x11,0xb3,0x90,0x06,0x04,0xe0,0x54,0x7f,0xf0,0x90,0x06,0x0a, +0xe0,0x54,0xf8,0xf0,0x22,0x90,0x01,0x36,0x74,0x7b,0xf0,0xa3,0x74,0x02,0xf0,0x7d, +0x7b,0xff,0x12,0x31,0x9d,0x7d,0x02,0x7f,0x03,0x12,0x31,0x9d,0x7d,0x10,0x7f,0x03, +0x12,0x31,0x49,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a,0xe0,0x44,0x07, +0xf0,0x12,0x64,0x11,0xe5,0x6d,0x20,0xe0,0x05,0xe4,0x90,0x91,0x29,0xf0,0x22,0x8b, +0x0e,0x8a,0x0f,0x89,0x10,0x12,0x62,0x3e,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x12,0x24, +0x62,0xf5,0x70,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24,0x03,0x70,0x40, +0x7f,0x01,0x80,0x3a,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02,0x12,0x42,0x20, +0xfd,0xe4,0xff,0x31,0xe1,0x80,0x27,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02, +0x12,0x42,0x20,0xfd,0x7f,0x01,0x31,0xe1,0x1f,0x80,0x13,0xab,0x0e,0xaa,0x0f,0xa9, +0x10,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0x31,0xe1,0xe4,0xff,0x11,0xfe, +0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x91,0x39,0x74,0x01,0xf0,0x80, +0x16,0xed,0x70,0x0a,0x90,0x91,0x35,0xe0,0x90,0x91,0x39,0xf0,0x80,0x05,0x90,0x91, +0x39,0xed,0xf0,0x90,0x91,0x39,0xe0,0x90,0x91,0x27,0xf0,0x22,0x7f,0x78,0x7e,0x08, +0x12,0x22,0x65,0x90,0x90,0xd8,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x22,0x65, +0x90,0x90,0xdc,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12,0x22,0x65,0x90,0x90,0xe0, +0x12,0x25,0x08,0x90,0x91,0x51,0xe0,0x90,0x90,0xd8,0xb4,0x01,0x0d,0x12,0x43,0x09, +0xef,0x54,0xc7,0xff,0xed,0x54,0xc7,0xfd,0x80,0x07,0x12,0x43,0x09,0xef,0x54,0xc7, +0xff,0xec,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x78,0x7e,0x08,0x12,0x2b,0x08,0x90, +0x90,0xdc,0x12,0x43,0x09,0xef,0x54,0x0f,0xff,0xec,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x90,0x90,0xe0,0x12,0x43,0x09,0xef,0x44,0x02, +0xff,0xec,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12,0x2b,0x08,0x7f, +0x70,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0xe4,0x12,0x25,0x08,0x90,0x80,0x96,0x12, +0x25,0x14,0x00,0x1b,0x25,0xa0,0x7f,0x70,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x68, +0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe4,0xfd,0xff,0x12,0x30,0x2c,0x90,0x91,0x51, +0xe0,0xb4,0x01,0x11,0x90,0x80,0x68,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe4,0xfd, +0x7f,0x01,0x12,0x30,0x2c,0x90,0x00,0x11,0xe0,0x54,0xf6,0xf0,0x80,0x08,0xf4,0xff, +0x90,0x00,0x43,0xe0,0x5f,0xf0,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x7f,0x10,0xdf, +0xfe,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x9b, +0xed,0xf0,0x90,0x91,0x9a,0xef,0xf0,0xd3,0x94,0x07,0x50,0x63,0xe0,0xff,0x74,0x01, +0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0,0x5f, +0xf0,0x51,0xe6,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3, +0x33,0xd8,0xfc,0xff,0x90,0x00,0x46,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x9b,0xe0, +0x60,0x16,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xff,0x90,0x00,0x45,0x80,0x66,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x45,0x80,0x6b,0x90, +0x91,0x9a,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3, +0x33,0xd8,0xfc,0xc4,0x54,0xf0,0x51,0xde,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0x51, +0xe6,0x90,0x91,0x9b,0xe0,0x60,0x1b,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x42,0xe0,0x4f, +0x80,0x1a,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x42,0xe0,0x5f,0xf0,0x51,0xe6,0xd0, +0xd0,0x92,0xaf,0x22,0xf0,0x90,0x00,0x45,0xe0,0x54,0xfe,0xfd,0x7f,0x45,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x8f,0x82,0x75,0x83,0x00,0xed,0xf0,0x51,0xe6,0xd0,0xd0, +0x92,0xaf,0x22,0xef,0x14,0x60,0x30,0x14,0x60,0x66,0x24,0x02,0x60,0x02,0x81,0xaa, +0x90,0x90,0xf3,0x74,0x02,0xf0,0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x71, +0xee,0x90,0x00,0x47,0xe0,0x44,0x08,0xfd,0x7f,0x47,0x71,0xee,0x90,0x00,0x45,0xe0, +0x44,0x10,0xfd,0x7f,0x45,0x80,0x71,0xe4,0x90,0x90,0xf3,0xf0,0x90,0x90,0xef,0x12, +0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x90, +0x00,0x45,0xe0,0x44,0xef,0xfd,0x7f,0x45,0x71,0xee,0x90,0x00,0x45,0xe0,0x54,0xef, +0xfd,0x7f,0x45,0x71,0xee,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x80,0x38, +0x90,0x90,0xf3,0x74,0x01,0xf0,0x90,0x90,0xf9,0x12,0x43,0x09,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x90,0x00,0x45,0xe0,0x44,0x20,0xfd, +0x7f,0x45,0x71,0xee,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x71,0xee,0x90, +0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x71,0xee,0x22,0x90,0x00,0x02,0x12,0x42, +0x20,0x90,0x90,0xf5,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x25,0xe0,0x25,0xe0,0x90, +0x90,0xf4,0xf0,0x12,0x24,0x62,0x25,0xe0,0x25,0xe0,0x90,0x90,0xf8,0xf0,0x90,0x05, +0x60,0xe0,0x90,0x91,0x03,0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05, +0x62,0xe0,0x90,0x91,0x05,0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xa2,0xaf, +0xe4,0x33,0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x90,0x90,0xf4,0xe0,0xff,0x12,0x6e,0x67, +0x90,0x91,0x1c,0xe0,0x24,0xff,0x92,0xaf,0x90,0x90,0xf5,0xe0,0x70,0x02,0xa1,0xb2, +0x90,0x90,0xf4,0xe0,0x70,0x02,0xa1,0xb2,0x90,0x90,0xf8,0xe0,0x70,0x02,0xa1,0xb2, +0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x90,0x91,0x07,0x74,0x01,0xf0, +0x90,0x91,0x1c,0xe0,0x24,0xff,0x92,0xaf,0x71,0xe5,0x90,0x00,0x46,0xe0,0x44,0x01, +0xfd,0x7f,0x46,0x71,0xee,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43, +0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x80,0x06, +0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0x71, +0xee,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x91,0x03,0xe0,0x90,0x05,0x84,0xf0, +0x90,0x91,0x04,0xe0,0x90,0x05,0x85,0xf0,0x90,0x91,0x05,0xe0,0x90,0x05,0x86,0xf0, +0x90,0x91,0x06,0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c,0xf0, +0xc2,0xaf,0x90,0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d,0x20,0xe4,0xff,0x12,0x31,0xb7, +0x80,0x2b,0x90,0x90,0xf5,0xe0,0x70,0x2d,0x90,0x91,0x07,0x71,0xe4,0x90,0x00,0x46, +0xe0,0x54,0xfe,0xfd,0x7f,0x46,0x71,0xee,0x90,0x05,0x22,0xe4,0xf0,0xa2,0xaf,0x33, +0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff,0x12,0x31,0x49,0x90,0x91,0x1c, +0xe0,0x24,0xff,0x92,0xaf,0x22,0x8b,0x0e,0x8a,0x0f,0x89,0x10,0x90,0x00,0x02,0x12, +0x42,0x20,0x90,0x90,0xf6,0xf0,0xe0,0x30,0xe0,0x4b,0x90,0x90,0xed,0x74,0x01,0xf0, +0x7f,0x80,0x7e,0x08,0x12,0x22,0x65,0x90,0x90,0xef,0x12,0x25,0x08,0xab,0x0e,0xaa, +0x0f,0xa9,0x10,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x1a, +0x12,0x24,0xf5,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x90,0xef,0x12,0x43, +0x09,0xec,0x54,0x03,0xfc,0x12,0x42,0xfc,0x90,0x90,0xf9,0x12,0x25,0x08,0x90,0x05, +0x22,0xe4,0xf0,0x80,0x2d,0xe4,0x90,0x90,0xed,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x22, +0x65,0xec,0x54,0x03,0xfc,0xec,0x44,0xc0,0xfc,0x90,0x90,0xef,0x12,0x25,0x08,0x90, +0x90,0xef,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12, +0x2b,0x08,0x90,0x90,0xf6,0xe0,0x30,0xe1,0x19,0x7d,0x0c,0x7f,0x47,0x71,0xee,0x90, +0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0x71,0xee,0x90,0x00,0x46,0xe0,0x44,0x10, +0x80,0x1c,0x90,0x00,0x47,0xe0,0x54,0xf3,0xfd,0x7f,0x47,0x71,0xee,0x90,0x00,0x48, +0xe0,0x54,0xf3,0xfd,0x7f,0x48,0x71,0xee,0x90,0x00,0x46,0xe0,0x54,0xef,0xfd,0x7f, +0x46,0x71,0xee,0xe4,0x90,0x90,0xf3,0xf0,0x22,0x90,0x01,0x3c,0x74,0xff,0xf0,0xa3, +0xf0,0xa3,0xf0,0x90,0x01,0x34,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x54, +0x71,0xee,0x7d,0xff,0x7f,0x55,0x71,0xee,0x7d,0xff,0x7f,0x56,0x71,0xee,0x7d,0xff, +0x7f,0x57,0x61,0xee,0x90,0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90, +0x01,0x38,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0x71,0xee,0xe4,0xfd, +0x7f,0x51,0x71,0xee,0xe4,0xfd,0x7f,0x52,0x71,0xee,0xe4,0xfd,0x7f,0x53,0x61,0xee, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x22,0xed,0xf0,0x90,0x91,0x21,0xef, +0xf0,0xd3,0x94,0x07,0x50,0x4e,0xa3,0xe0,0x70,0x1a,0x90,0x91,0x21,0xe0,0xff,0x74, +0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0, +0x5f,0xf0,0x80,0x17,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x21, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90, +0x00,0x46,0x80,0x59,0x90,0x91,0x21,0xe0,0x24,0xf8,0xf0,0xa3,0xe0,0x70,0x1d,0x90, +0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4, +0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x80,0x1a,0x90,0x91,0x21,0xe0, +0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff, +0x90,0x00,0x43,0xe0,0x4f,0xf0,0x51,0xe6,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0, +0x51,0xe6,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x49,0xe0,0x90,0x91,0x9f,0xf0,0xe0, +0x54,0x0f,0xf0,0x44,0xf0,0xfd,0x7f,0x49,0x71,0xee,0x90,0x91,0x9f,0xe0,0x44,0xb0, +0xfd,0x7f,0x49,0x61,0xee,0x12,0x47,0xe6,0xbf,0x01,0x10,0x90,0x02,0x09,0xe0,0xff, +0x7d,0x01,0x12,0x48,0x22,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x75,0x28,0x33,0xe4, +0xf5,0x29,0x75,0x2a,0x07,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3,0xe5,0x29, +0xf0,0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0xe4,0x90,0x91,0x0e,0xf0,0xa3, +0xf0,0x75,0x8e,0x02,0xf1,0x25,0xd1,0xe8,0x90,0x91,0x4f,0xef,0xf0,0xf1,0x0b,0x90, +0x91,0x51,0xef,0xf0,0xf1,0x60,0x90,0x91,0x3d,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xf5, +0x57,0xf1,0x02,0x12,0x61,0xc4,0x12,0x2e,0x01,0x12,0x44,0xff,0x11,0x0c,0xf1,0x36, +0xd1,0xfb,0xd1,0xd0,0x12,0x44,0xfe,0x31,0x13,0x12,0x44,0xf4,0x12,0x6e,0x09,0x90, +0x91,0x10,0xe5,0xd9,0xf0,0x12,0x4e,0xb9,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44,0x40, +0xf0,0x12,0x4a,0xe6,0x75,0xe8,0x03,0x43,0xa8,0x85,0xd2,0xaf,0x90,0x91,0x0e,0xe0, +0x64,0x01,0xf0,0x24,0x2a,0x90,0x01,0xc4,0xf0,0x74,0x50,0xa3,0xf0,0xe5,0x57,0x30, +0xe2,0x10,0x12,0x5f,0xf0,0xbf,0x01,0x0a,0xc2,0xaf,0x53,0x57,0xfb,0xd2,0xaf,0x12, +0x71,0x97,0xe5,0x57,0x30,0xe4,0x0a,0xc2,0xaf,0x53,0x57,0xef,0xd2,0xaf,0x12,0x60, +0x2d,0x90,0x90,0xf7,0xe0,0x70,0x03,0x12,0x70,0x74,0x11,0xe7,0x90,0x91,0x3f,0xe0, +0x90,0x01,0xba,0xf0,0x80,0xb6,0xe4,0x90,0x91,0x55,0xf0,0x90,0x91,0x53,0xe0,0x54, +0x7f,0xf0,0xa3,0x74,0x0a,0xf0,0x22,0x90,0x06,0x34,0xe0,0x60,0x25,0x14,0x70,0x1b, +0x7b,0x01,0x7a,0x06,0x79,0x35,0x7f,0xf9,0x7e,0x01,0x12,0x67,0xe4,0xbf,0x01,0x09, +0x90,0x06,0x35,0xe0,0x54,0x0f,0xf0,0x80,0x04,0x80,0x00,0xe1,0x17,0xe4,0x90,0x06, +0x34,0xf0,0x22,0x90,0x91,0x56,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0x7f,0xf0,0x90,0x01, +0x17,0xe0,0xfe,0x90,0x01,0x16,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x91, +0x5c,0xf0,0xa3,0xef,0xf0,0x90,0x01,0x04,0xe0,0x54,0x0f,0x90,0x91,0x1c,0xf0,0xe0, +0xff,0x74,0x40,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8, +0xf9,0x90,0x91,0x5b,0xf0,0xee,0x90,0x91,0x5a,0xf0,0x90,0x91,0x5e,0xe0,0x54,0xfe, +0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xfb,0xf0,0xe0,0x54,0xf7,0xf0,0xe0,0x54,0xef, +0xf0,0xe0,0x54,0xdf,0xf0,0xe0,0x54,0xbf,0xf0,0xe0,0x54,0x7f,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xf7,0xf0,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x12,0x24,0x62,0x54,0x01,0xff,0x90,0x91,0x56, +0xe0,0x54,0xfe,0x4f,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x57,0xf0,0x90, +0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x58,0xf0,0x90,0x91,0x56,0xe0,0x30,0xe0,0x1a, +0x90,0x06,0x09,0xe0,0x54,0xfe,0xf0,0x90,0x02,0x86,0xe0,0x44,0x04,0xf0,0x43,0x57, +0x04,0x7d,0x08,0xe4,0xff,0x12,0x31,0x9d,0x80,0x12,0x7d,0x08,0xe4,0xff,0x12,0x31, +0x2c,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x31,0xf1,0x31,0x13,0xd0,0xd0,0x92,0xaf, +0x22,0x90,0x06,0x90,0xe4,0xf0,0x21,0x5a,0x90,0x91,0x19,0x12,0x43,0x41,0xef,0x12, +0x43,0x4a,0x52,0x30,0x01,0x52,0x39,0x02,0x52,0x5b,0x03,0x52,0x64,0x09,0x52,0x6c, +0x0c,0x52,0x75,0x0d,0x52,0x7d,0x0e,0x52,0x8e,0x1a,0x52,0x96,0x2c,0x52,0x41,0x2d, +0x52,0x4a,0x2e,0x52,0x9e,0x30,0x52,0x53,0x3b,0x52,0x86,0x3c,0x00,0x00,0x52,0xa6, +0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x64,0x72,0x90,0x91,0x19,0x12,0x43,0x21,0xc1, +0xf5,0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x65,0x8d,0x90,0x91,0x19,0x12,0x43,0x21, +0x02,0x65,0xd5,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x4b,0x90,0x91,0x19,0x12,0x43, +0x21,0x02,0x66,0x0e,0x90,0x91,0x19,0x12,0x43,0x21,0x80,0x42,0x90,0x91,0x19,0x12, +0x43,0x21,0x02,0x4c,0xab,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x98,0x90,0x91,0x19, +0x12,0x43,0x21,0x02,0x4d,0xe6,0x90,0x91,0x19,0x12,0x43,0x21,0x21,0x90,0x90,0x91, +0x19,0x12,0x43,0x21,0xa1,0x9b,0x90,0x91,0x19,0x12,0x43,0x21,0x81,0x7a,0x90,0x91, +0x19,0x12,0x43,0x21,0xe1,0x78,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90,0x91,0x1c,0x12,0x43, +0x21,0x90,0x00,0x01,0x12,0x42,0x97,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe, +0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x42,0xcf,0x12, +0x24,0x62,0xff,0x60,0x2c,0xb5,0x72,0x16,0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00, +0x01,0x12,0x42,0x97,0x65,0x74,0x70,0x04,0xe5,0x73,0x65,0xf0,0x60,0x23,0x90,0x91, +0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0x12,0x42,0x97,0xff,0xae,0xf0,0x71,0x26,0x80, +0x10,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x24,0x62,0x65,0x72,0x60,0x03,0x12,0x44, +0xe8,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x1f,0xee,0xf0,0xa3,0xef,0xf0,0x75,0x72, +0x01,0x8e,0x73,0xf5,0x74,0xe4,0xfd,0x7f,0x0b,0x12,0x4f,0x10,0xe4,0xfd,0x7f,0x02, +0x12,0x4f,0x10,0x71,0x6a,0xe4,0xff,0x71,0xcc,0xe4,0xf5,0x76,0x90,0x01,0xc9,0xe5, +0x76,0xf0,0x90,0x91,0x1f,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5, +0x45,0x7d,0x01,0x7f,0x60,0x7e,0x01,0x02,0x30,0x62,0x7f,0x0b,0x71,0xd9,0xef,0x65, +0x75,0x60,0x10,0xe5,0x75,0xb4,0x01,0x05,0xe4,0xf5,0x75,0x80,0x03,0x75,0x75,0x01, +0x7f,0x01,0x22,0x7f,0x00,0x22,0xe5,0x72,0x64,0x01,0x70,0x3f,0x71,0x6a,0xbf,0x01, +0x04,0x7f,0x01,0x71,0xcc,0x90,0x00,0x46,0xe0,0x44,0x04,0xfd,0x7f,0x46,0x12,0x4b, +0xee,0x90,0x00,0x44,0xe0,0x54,0xfb,0xfd,0x7f,0x44,0x12,0x4b,0xee,0x90,0x00,0x46, +0xe0,0x54,0xfb,0xfd,0x7f,0x46,0x12,0x4b,0xee,0x7f,0x02,0x71,0xd9,0x8f,0x76,0x90, +0x01,0xc9,0xe5,0x76,0xf0,0xb4,0x01,0x03,0x12,0x4f,0xd7,0x22,0x90,0x01,0xca,0xe5, +0x75,0xf0,0xef,0x60,0x03,0x12,0x4f,0xd7,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0xa0,0xef,0xf0,0xd3,0x94,0x07,0x50,0x47,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0xe0,0x5f,0xf0,0x12, +0x4a,0xe6,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0,0xfb,0xe4,0xfe,0xef, +0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x80, +0x44,0x90,0x91,0xa0,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0x12,0x4a,0xde,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e, +0x00,0xa8,0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00, +0x42,0xe0,0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13, +0xce,0x13,0xd8,0xf8,0xff,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0xe4,0xf5,0x10,0x75,0x11,0x04,0xf5,0x12,0xf5,0x14,0xf5,0x15,0x90,0x02,0x09, +0xe0,0xff,0x12,0x24,0x62,0xfe,0xef,0x2e,0xf5,0x13,0x30,0xe0,0x08,0x75,0x0e,0x00, +0x75,0x0f,0x80,0x80,0x05,0xe4,0xf5,0x0e,0xf5,0x0f,0xe5,0x13,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x74,0x20,0x25,0x10,0xf5,0x10,0xad,0x0f,0xe5,0x10,0x2d,0xff,0x24,0x01, +0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x90,0x91,0x47,0xf0,0x74,0x02,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xfe,0xe5,0x10,0x2d,0x24,0x03,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x24,0x00,0xff,0xe4,0x3e,0x90,0x91,0x48,0xf0,0xa3,0xef, +0xf0,0x7f,0x04,0xe5,0x10,0x25,0x0f,0x2f,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfc,0xf5, +0x83,0xe0,0xfe,0x74,0x46,0x2f,0xf5,0x82,0xe4,0x34,0x91,0xf5,0x83,0xee,0xf0,0x0f, +0xbf,0x08,0xe0,0x12,0x66,0x56,0xef,0x70,0x3f,0x90,0x01,0xc3,0xe0,0x60,0x25,0xc3, +0xe5,0x15,0x94,0xe8,0xe5,0x14,0x94,0x03,0x40,0x09,0x90,0x01,0xc6,0xe0,0x44,0x10, +0xf0,0x80,0x63,0x05,0x15,0xe5,0x15,0x70,0x02,0x05,0x14,0x7f,0x0a,0x7e,0x00,0x12, +0x32,0x15,0x80,0xd5,0x90,0x01,0xc6,0xe0,0x90,0x01,0xc3,0x30,0xe2,0x05,0x74,0xfe, +0xf0,0x80,0x43,0x74,0xff,0xf0,0x80,0x3e,0xe5,0x10,0xb4,0x78,0x23,0xe4,0xf5,0x10, +0x05,0x13,0xe5,0x0f,0x64,0x80,0x45,0x0e,0x70,0x06,0xf5,0x0e,0xf5,0x0f,0x80,0x06, +0x75,0x0e,0x00,0x75,0x0f,0x80,0xe5,0x13,0xc3,0x13,0x90,0xfd,0x10,0xf0,0x80,0x06, +0x74,0x08,0x25,0x10,0xf5,0x10,0xe5,0x12,0x15,0x12,0x70,0x02,0x15,0x11,0xe5,0x12, +0x45,0x11,0x60,0x02,0x81,0xb8,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x1c,0x12,0x43, +0x41,0x12,0x24,0x62,0xff,0x54,0x01,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xfe,0x4e,0xf0, +0xef,0x54,0x04,0xff,0xe0,0x54,0xfb,0x4f,0xf0,0x12,0x24,0x62,0xff,0x54,0x02,0xfe, +0x90,0x91,0x5e,0xe0,0x54,0xfd,0x4e,0xf0,0xef,0x54,0x08,0xff,0xe0,0x54,0xf7,0x4f, +0xf0,0x12,0x24,0x62,0xff,0x54,0x10,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xef,0x4e,0xf0, +0xef,0x54,0x20,0xff,0xe0,0x54,0xdf,0x4f,0xf0,0x12,0x24,0x62,0xff,0x54,0x40,0xfe, +0x90,0x91,0x5e,0xe0,0x54,0xbf,0x4e,0xf0,0xef,0x54,0x80,0xff,0xe0,0x54,0x7f,0x4f, +0xf0,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x60,0xf0,0x90,0x00,0x01,0x12,0x42, +0x20,0x90,0x91,0x5f,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff,0x54,0x01,0xfe,0x90, +0x91,0x61,0xe0,0x54,0xfe,0x4e,0xf0,0xef,0x54,0x02,0xff,0xe0,0x54,0xfd,0x4f,0xf0, +0x90,0x00,0x03,0x12,0x42,0x20,0x54,0x04,0xff,0x90,0x91,0x61,0xe0,0x54,0xfb,0x4f, +0xf0,0x90,0x91,0x5e,0xe0,0x54,0x01,0x90,0x01,0xb8,0xf0,0x90,0x91,0x5e,0xe0,0xff, +0xc4,0x13,0x54,0x01,0x90,0x01,0xb9,0xf0,0x90,0x91,0x61,0xe0,0x54,0x01,0x90,0x01, +0xba,0xf0,0xa3,0x74,0xff,0xf0,0x12,0x24,0x62,0x20,0xe0,0x02,0x21,0xf1,0xe4,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x24,0x62,0xff,0xc3, +0x13,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x02,0xf0,0xef,0x13,0x13,0x54,0x3f, +0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x04,0xf0,0x12,0x24,0x62,0x13,0x13,0x13, +0x54,0x1f,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x08,0xf0,0x90,0x91,0x61,0xe0, +0x30,0xe0,0x1c,0x90,0x91,0x5e,0xe0,0xc4,0x13,0x54,0x07,0x30,0xe0,0x07,0xa3,0xe0, +0xff,0xe4,0xfd,0x80,0x07,0x90,0x91,0x5f,0xe0,0xff,0x7d,0x01,0x12,0x4a,0xf6,0x22, +0x75,0x30,0x1f,0x75,0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0,0xa3, +0xe5,0x31,0xf0,0xa3,0xe5,0x32,0xf0,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x7f,0x01, +0x60,0x02,0x7f,0x00,0x22,0x12,0x24,0x62,0xf5,0x6d,0x22,0x90,0x01,0x64,0x74,0xa0, +0xf0,0x22,0x90,0x91,0x51,0xe0,0x90,0x90,0xe8,0xf0,0x22,0x90,0x00,0xf3,0xe0,0x7f, +0x00,0x30,0xe3,0x02,0x7f,0x01,0x22,0x90,0x06,0x34,0x74,0xff,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xf0,0x22,0xe4,0x90,0x91,0x4e,0xf0,0x90,0x00,0x80,0xe0,0x44,0x80, +0xfd,0x7f,0x80,0x02,0x4b,0xee,0x90,0x00,0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41, +0x74,0x10,0xf0,0x90,0x05,0x5a,0xf0,0xa3,0xe4,0xf0,0x22,0x12,0x24,0x62,0x60,0x02, +0x80,0x01,0xe4,0x90,0x91,0x31,0xf0,0x90,0x91,0x31,0xe0,0x90,0x01,0xe7,0xf0,0x22, +0x90,0x91,0x51,0xe0,0xb4,0x01,0x0c,0x90,0x00,0xf2,0xe0,0x30,0xe7,0x05,0x7e,0xfd, +0x7f,0x33,0x22,0x7e,0xfd,0x7f,0x2f,0x22,0x12,0x24,0x62,0xff,0x54,0x01,0xfe,0x90, +0x91,0x53,0xe0,0x54,0xfe,0x4e,0xf0,0xef,0xc3,0x13,0x30,0xe0,0x0a,0x90,0x00,0x01, +0x12,0x42,0x20,0x90,0x91,0x54,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x90, +0xf7,0xf0,0xe0,0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5,0x0e,0xc2, +0xaf,0x90,0x00,0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x4b,0xee,0x7d,0x40,0x7f, +0x01,0x12,0x31,0x66,0xe5,0x0e,0x24,0xff,0x92,0xaf,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,0xcb,0xf0,0x74,0x57, +0xa3,0xf0,0x90,0x01,0x34,0xe0,0x55,0x28,0xf5,0x2c,0x90,0x01,0x36,0xe0,0x55,0x2a, +0xf5,0x2e,0xa3,0xe0,0x55,0x2b,0xf5,0x2f,0xe5,0x2c,0x30,0xe0,0x5a,0x90,0x01,0x34, +0x74,0x01,0xf0,0x85,0xd9,0x54,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80,0x48,0x90, +0x91,0x3b,0xe0,0x60,0x3a,0x90,0x01,0x5b,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0, +0x51,0x30,0xef,0x64,0x01,0x70,0x30,0x90,0x91,0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90, +0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44,0x59,0x90,0x01,0x5b, +0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x90,0x91,0x37,0xf0,0x80,0x08,0x51, +0x30,0xbf,0x01,0x03,0x12,0x44,0xc2,0xe5,0x2c,0x30,0xe1,0x20,0x90,0x01,0x34,0x74, +0x02,0xf0,0x85,0xd1,0x58,0x85,0xd2,0x59,0x85,0xd3,0x5a,0x85,0xd4,0x5b,0x85,0xd5, +0x5c,0x85,0xd6,0x5d,0x85,0xd7,0x5e,0x85,0xd9,0x5f,0x71,0x5c,0xe5,0x2c,0x30,0xe3, +0x10,0x90,0x01,0x34,0x74,0x08,0xf0,0x90,0x91,0x56,0xe0,0x30,0xe0,0x03,0x43,0x57, +0x04,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01,0x34,0x74,0x10,0xf0,0x43,0x57,0x10,0xe5, +0x2c,0x30,0xe5,0x26,0x90,0x01,0xcf,0xe0,0x30,0xe5,0x1f,0xe0,0x54,0xdf,0xf0,0x90, +0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00,0x75,0xe8,0x00,0x12,0x4e,0xe4,0x90,0x00, +0x03,0xe0,0x54,0xfb,0xf0,0x12,0x4a,0xe6,0x80,0xfe,0xe5,0x2c,0x30,0xe6,0x06,0x90, +0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe0,0x13,0x90,0x91,0x50,0x74,0x01,0xf0, +0x90,0x01,0x36,0xf0,0x91,0x23,0x51,0x87,0x90,0x91,0x50,0xe4,0xf0,0xe5,0x2e,0x30, +0xe1,0x3c,0x90,0x01,0x36,0x74,0x02,0xf0,0x43,0x57,0x40,0x90,0x01,0x02,0xe0,0x54, +0x03,0x64,0x01,0x70,0x29,0x90,0x01,0x37,0xe0,0x30,0xe0,0x0a,0x74,0x01,0xf0,0x90, +0x91,0x40,0xe4,0xf0,0x80,0x18,0x90,0x91,0x40,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a, +0x40,0x0c,0xe4,0xf0,0x90,0x04,0x19,0xe0,0x30,0xe0,0x03,0x12,0x4f,0xf5,0xe5,0x2e, +0x30,0xe2,0x19,0x90,0x01,0x36,0x74,0x04,0xf0,0x90,0x91,0x3a,0xe4,0xf0,0x90,0x05, +0x58,0x74,0x03,0xf0,0x51,0xd8,0x90,0x91,0x3f,0xe0,0x04,0xf0,0xe5,0x2e,0x30,0xe3, +0x28,0x90,0x01,0x36,0x74,0x08,0xf0,0xe5,0x6d,0x64,0x01,0x70,0x1c,0xe5,0x70,0x60, +0x18,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x91,0x66,0xe4, +0x12,0x44,0x49,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x2e,0x30,0xe4,0x2b,0x90,0x01, +0x36,0x74,0x10,0xf0,0xe5,0x6d,0xb4,0x01,0x20,0xe5,0x70,0x60,0x1c,0x90,0x01,0x57, +0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x90,0x91,0x3c,0xe4,0xf0,0x53,0x71,0xfd, +0xe5,0x71,0x54,0x07,0x70,0x03,0x12,0x44,0xc2,0xe5,0x2e,0x30,0xe5,0x1f,0x90,0x01, +0x36,0x74,0x20,0xf0,0xe5,0x6d,0xb4,0x01,0x14,0xe5,0x70,0x60,0x10,0x90,0x91,0x3b, +0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xc8,0x80,0x03,0x12,0x44,0x77,0xe5,0x2e,0x30, +0xe6,0x1b,0x90,0x01,0x36,0x74,0x40,0xf0,0xe5,0x6d,0xb4,0x01,0x10,0xe5,0x70,0x60, +0x0c,0x53,0x71,0xfe,0xe5,0x71,0x54,0x07,0x70,0x03,0x12,0x44,0xc2,0xe5,0x2f,0x30, +0xe1,0x08,0x90,0x01,0x37,0x74,0x02,0xf0,0x71,0x7e,0x74,0xcb,0x04,0x90,0x01,0xc4, +0xf0,0x74,0x57,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,0x04,0x1b,0xe0,0x54,0x7f,0x64,0x7f,0x7f,0x01,0x60,0x02,0x7f,0x00,0x22,0x51, +0x30,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x30,0x90,0x91, +0x37,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x22,0x90,0x91,0x36,0xe0, +0x60,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x14,0xe5,0x6f,0x54,0x0f,0xd3,0x94, +0x04,0x40,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01, +0xb8,0x74,0x08,0xf0,0x7f,0x00,0x22,0x90,0x91,0x53,0xe0,0x30,0xe0,0x49,0xe5,0x6d, +0x64,0x01,0x70,0x43,0x90,0x91,0x52,0xe0,0x04,0xf0,0xe5,0x70,0x64,0x03,0x60,0x05, +0xe5,0x70,0xb4,0x06,0x0d,0x90,0x91,0x52,0xe0,0xff,0x74,0x01,0xd3,0x9f,0x50,0x14, +0x80,0x07,0x90,0x91,0x52,0xe0,0xb4,0x0a,0x0b,0x90,0x91,0x55,0xe0,0x04,0xf0,0xe4, +0x90,0x91,0x52,0xf0,0x90,0x91,0x55,0xe0,0xff,0x90,0x91,0x54,0xe0,0xb5,0x07,0x07, +0x71,0x4e,0xe4,0x90,0x91,0x55,0xf0,0x22,0xe5,0x6d,0x64,0x01,0x70,0x63,0xe5,0x70, +0x60,0x5f,0xe5,0x70,0x64,0x02,0x60,0x06,0xe5,0x70,0x64,0x05,0x70,0x27,0x90,0x06, +0xab,0xe0,0x90,0x91,0x27,0xf0,0x90,0x06,0xaa,0xe0,0x90,0x91,0x39,0xf0,0x90,0x91, +0x27,0xe0,0x70,0x07,0x90,0x91,0x39,0xe0,0xff,0x80,0x05,0x90,0x91,0x27,0xe0,0xff, +0x90,0x91,0x27,0xef,0xf0,0x90,0x91,0x29,0xe0,0x60,0x03,0xe0,0x14,0xf0,0xe4,0x90, +0x91,0x28,0xf0,0x90,0x01,0x57,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x53,0x71,0xfd, +0x53,0x71,0xef,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0xc7,0x71, +0x42,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xd0,0xd0,0x92,0xaf,0x22,0xe5,0x6e, +0x30,0xe3,0x04,0xe4,0xff,0x80,0x02,0x7f,0x01,0x02,0x47,0xc9,0x90,0x91,0x08,0xe0, +0x54,0xf0,0x44,0x03,0xf0,0x54,0x0f,0x44,0x80,0xf0,0x7b,0x00,0x7a,0x00,0x79,0x58, +0x90,0x91,0x71,0x12,0x43,0x41,0x0b,0x7a,0x91,0x79,0x08,0x02,0x46,0xb7,0x90,0x91, +0x80,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80, +0x21,0x90,0x91,0x3b,0xe0,0x60,0x06,0x7d,0x01,0x7f,0x0c,0x80,0x0d,0xe5,0x6e,0x54, +0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27,0xe4,0xff,0x12, +0x48,0xb3,0x22,0x51,0x30,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0, +0x80,0x58,0xe5,0x71,0x54,0x03,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4a, +0xe5,0x6f,0x54,0x0f,0xd3,0x94,0x02,0x40,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80, +0x39,0xe5,0x71,0x30,0xe2,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x2c,0xe5,0x71, +0x30,0xe4,0x08,0x90,0x01,0xb9,0x74,0x10,0xf0,0x80,0x1f,0x90,0x91,0x29,0xe0,0x60, +0x08,0x90,0x01,0xb9,0x74,0x20,0xf0,0x80,0x11,0x90,0x91,0x31,0xe0,0x60,0x08,0x90, +0x01,0xb9,0x74,0x80,0xf0,0x80,0x03,0x7f,0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0, +0x7f,0x00,0x22,0xe4,0xfb,0x90,0x91,0x78,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe5, +0x70,0x70,0x02,0x81,0xb5,0xe5,0x6d,0x64,0x01,0x70,0x7a,0xe5,0x70,0x14,0x60,0x2b, +0x24,0xfd,0x60,0x27,0x24,0x02,0x24,0xfb,0x50,0x02,0x80,0x21,0x90,0x91,0x27,0xe0, +0x14,0xf0,0xe0,0x60,0x04,0xa3,0xe0,0x60,0x14,0x90,0x91,0x27,0xe0,0x70,0x08,0x90, +0x91,0x39,0xe0,0x90,0x91,0x27,0xf0,0x7b,0x01,0x80,0x02,0x7b,0x01,0xeb,0x60,0x45, +0x43,0x71,0x10,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4, +0xff,0x90,0x91,0x34,0xe0,0x2f,0x12,0x44,0x4e,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5, +0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27,0x90, +0x91,0x2e,0xe0,0x60,0x10,0x90,0x91,0x2c,0xe0,0x90,0x07,0x78,0x60,0x04,0x74,0x0d, +0xf0,0x22,0x74,0x09,0xf0,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,0xb6,0xf0,0x74,0x5c,0xa3,0xf0,0x53,0x91,0xef, +0x90,0x00,0x51,0xe0,0xff,0x90,0x00,0x55,0xe0,0x5f,0xf5,0x3d,0x90,0x00,0x52,0xe0, +0xff,0x90,0x00,0x56,0xe0,0x5f,0xf5,0x3e,0xe5,0x3d,0x30,0xe4,0x06,0x90,0x00,0x55, +0x74,0x10,0xf0,0xe5,0x3d,0x30,0xe5,0x06,0x90,0x00,0x55,0x74,0x20,0xf0,0xe5,0x3d, +0x30,0xe6,0x1b,0x90,0x00,0x55,0x74,0x40,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x0b,0x90,0x90,0xf3,0xe0,0x60,0x05,0x7f,0x01,0x12,0x4c,0x03,0xe5,0x3d, +0x30,0xe7,0x15,0x90,0x00,0x55,0x74,0x80,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff, +0xbf,0x03,0x05,0x7f,0x02,0x12,0x4c,0x03,0xe5,0x3e,0x30,0xe0,0x06,0x90,0x00,0x56, +0x74,0x01,0xf0,0xe5,0x3e,0x30,0xe1,0x06,0x90,0x00,0x56,0x74,0x02,0xf0,0xe5,0x3e, +0x30,0xe2,0x06,0x90,0x00,0x56,0x74,0x04,0xf0,0xe5,0x3e,0x30,0xe3,0x06,0x90,0x00, +0x56,0x74,0x08,0xf0,0x90,0x01,0xc4,0x74,0xb6,0xf0,0x74,0x5c,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,0x75,0x0d,0x00,0x90,0x01,0xc4,0x74,0x99,0xf0,0x74, +0x5d,0xa3,0xf0,0x53,0x91,0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5,0x34,0xa3,0xe0, +0x55,0x31,0xf5,0x35,0xa3,0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55,0x33,0xf5,0x37, +0xe5,0x34,0x30,0xe0,0x06,0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34,0x30,0xe1,0x08, +0x90,0x01,0x3c,0x74,0x02,0xf0,0xf1,0x57,0xe5,0x34,0x30,0xe2,0x3a,0x90,0x01,0x3c, +0x74,0x04,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe0,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90, +0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44, +0x59,0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80,0x08,0x90, +0x91,0x37,0xe4,0xf0,0x12,0x44,0xc2,0xe5,0x34,0x30,0xe3,0x3a,0x90,0x01,0x3c,0x74, +0x08,0xf0,0x90,0x06,0x92,0xe0,0x30,0xe1,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90,0x91, +0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x12,0x44,0x59, +0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x08,0x90,0x91, +0x36,0xe4,0xf0,0x12,0x44,0xc2,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10, +0xf0,0x12,0x53,0x86,0xe5,0x34,0x30,0xe5,0x09,0x90,0x01,0x3c,0x74,0x20,0xf0,0x12, +0x6e,0xb9,0xe5,0x35,0x30,0xe0,0x5a,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f, +0xe0,0x44,0x7f,0xf0,0x90,0x00,0x83,0xe0,0x54,0x0f,0xf5,0x0d,0xb4,0x01,0x02,0x80, +0x1c,0xe5,0x0d,0xb4,0x02,0x05,0x90,0x00,0x83,0x80,0x12,0xe5,0x0d,0xb4,0x04,0x05, +0x90,0x00,0x83,0x80,0x08,0xe5,0x0d,0xb4,0x0c,0x08,0x90,0x00,0x83,0xe0,0xf5,0x6f, +0x80,0x06,0x90,0x01,0xbe,0xe0,0x04,0xf0,0x90,0x01,0xbb,0xe5,0x6f,0xf0,0xe5,0x6f, +0x30,0xe0,0x03,0xa3,0x80,0x03,0x90,0x01,0xbd,0xe0,0x04,0xf0,0xf1,0x38,0x12,0x44, +0xc2,0xe5,0x35,0x30,0xe2,0x06,0x90,0x01,0x3d,0x74,0x04,0xf0,0xe5,0x36,0x30,0xe0, +0x06,0x90,0x01,0x3e,0x74,0x01,0xf0,0xe5,0x36,0x30,0xe1,0x06,0x90,0x01,0x3e,0x74, +0x02,0xf0,0x74,0x99,0x04,0x90,0x01,0xc4,0xf0,0x74,0x5d,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,0xe5,0x6f,0x30,0xe6,0x19,0xe5,0x6f,0x54, +0x0f,0xff,0x90,0x91,0x24,0xe0,0xfe,0x4f,0x90,0x01,0x2f,0xf0,0xee,0x64,0x80,0x90, +0x91,0x24,0xf0,0x53,0x6f,0xbf,0x22,0xe4,0x90,0x91,0x0d,0xf0,0xe5,0x70,0x70,0x02, +0xe1,0xe1,0x90,0x91,0x3c,0xe0,0x60,0x0d,0xe4,0xf0,0x53,0x71,0xfd,0xe5,0x71,0x54, +0x07,0x70,0x6e,0x80,0x69,0x90,0x91,0x28,0xe0,0x04,0xf0,0x53,0x71,0xef,0x90,0x91, +0x3a,0xe0,0x04,0xf0,0x90,0x91,0x0d,0xe0,0xf9,0xff,0x7e,0x00,0x24,0x01,0xfd,0xee, +0x33,0xfc,0x90,0x91,0x3a,0xe0,0xb5,0x05,0x06,0xe4,0xb5,0x04,0x02,0x80,0x12,0xef, +0x24,0x02,0xff,0xe4,0x3e,0xfe,0x90,0x91,0x3a,0xe0,0xb5,0x07,0x0a,0xe4,0xb5,0x06, +0x06,0x90,0x05,0x58,0xe0,0x04,0xf0,0xe9,0xff,0x90,0x91,0x2f,0xe0,0x2f,0xff,0xe4, +0x33,0xfe,0x90,0x91,0x28,0xe0,0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80,0x98,0x40, +0x0d,0xe5,0x6d,0xb4,0x01,0x0b,0xa3,0xe0,0x70,0x07,0xe0,0x04,0xf0,0x22,0x12,0x44, +0xc2,0x22,0x8f,0x20,0x8c,0x21,0x8d,0x22,0x22,0x8f,0x23,0x8c,0x24,0x8d,0x25,0x22, +0xe4,0x90,0x91,0x11,0xf0,0xa3,0xf0,0x90,0x02,0x86,0xe0,0x20,0xe1,0x2c,0xc3,0x90, +0x91,0x12,0xe0,0x94,0x20,0x90,0x91,0x11,0xe0,0x94,0x03,0x40,0x0a,0x90,0x01,0xc6, +0xe0,0x44,0x20,0xf0,0x7f,0x00,0x22,0x90,0x91,0x11,0xe4,0x75,0xf0,0x01,0x12,0x42, +0x81,0x7f,0x01,0x7e,0x00,0x12,0x32,0x15,0x80,0xcd,0x7f,0x01,0x22,0x90,0x01,0xcc, +0xe0,0x54,0x0f,0x90,0x91,0x11,0xf0,0x90,0x91,0x11,0xe0,0xfd,0x70,0x02,0x21,0x6f, +0x90,0x91,0x9c,0xe0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33, +0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70,0x02,0x21,0x68,0x90,0x91,0x9c,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x15,0xe0,0x90,0x91,0x12,0xf0,0x75,0x63, +0x01,0x75,0x64,0x91,0x75,0x65,0x12,0x75,0x66,0x01,0x7b,0x01,0x7a,0x91,0x79,0x13, +0x12,0x46,0x6d,0x90,0x91,0x13,0xe0,0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x90,0x91, +0x9c,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90,0x00,0x88,0x12,0x43,0x15,0xe0,0x90, +0x91,0x14,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x02,0x90,0x00,0x89,0x12,0x43,0x15, +0xe0,0x90,0x91,0x15,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1,0x12, +0x43,0x15,0xe0,0x90,0x91,0x16,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01, +0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x17,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04, +0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90,0x91,0x18,0xf0,0x80,0x33,0xe0,0x75,0xf0, +0x04,0x90,0x01,0xd1,0x12,0x43,0x15,0xe0,0x90,0x91,0x14,0xf0,0x90,0x91,0x9c,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x15,0xf0,0x90,0x91, +0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90,0x91,0x16,0xf0, +0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x91,0x79,0x14,0x12,0x51,0xf8,0x90,0x91,0x11, +0xe0,0xff,0x90,0x91,0x9c,0xe0,0xfe,0x74,0x01,0xa8,0x06,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0x5f,0x90,0x91,0x11,0xf0,0x90,0x91,0x9c,0xe0,0xff,0x74,0x01,0xa8, +0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01,0xcc,0xf0,0x90,0x91,0x9c,0xe0, +0x04,0xf0,0xe0,0x54,0x03,0xf0,0x01,0x37,0x90,0x01,0xc6,0xe0,0x44,0x02,0xf0,0x22, +0xad,0x07,0x74,0x11,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x01,0xf0, +0x90,0x04,0x80,0xe0,0x54,0x0f,0xfc,0x74,0x14,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5, +0x83,0xe0,0x54,0xc0,0x4c,0xfd,0x74,0x14,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xed,0xf0,0x22,0xef,0x60,0x0f,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83, +0xe0,0x44,0x10,0xf0,0x22,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0, +0x54,0xef,0xf0,0x22,0xe4,0xf5,0x6d,0xf5,0x71,0xf5,0x70,0x75,0x6f,0x0c,0x75,0x6e, +0x0c,0x90,0x91,0x3b,0xf0,0x90,0x91,0x37,0xf0,0x90,0x91,0x36,0xf0,0x90,0x91,0x39, +0x04,0xf0,0x90,0x91,0x27,0xf0,0xe4,0x90,0x91,0x3c,0xf0,0x90,0x91,0x29,0xf0,0x90, +0x91,0x34,0x74,0x07,0xf0,0xe4,0x90,0x91,0x28,0xf0,0x90,0x91,0x32,0xf0,0xa3,0x74, +0x03,0xf0,0x90,0x91,0x2f,0x74,0x0a,0xf0,0xa3,0x74,0x05,0xf0,0x90,0x91,0x2d,0x74, +0x14,0xf0,0x90,0x91,0x35,0x74,0x05,0xf0,0xe4,0x90,0x91,0x2b,0xf0,0x90,0x91,0x25, +0xf0,0x90,0x91,0x50,0xf0,0x90,0x91,0x31,0xf0,0x90,0x91,0x3a,0xf0,0x90,0x91,0x26, +0xf0,0x90,0x91,0x38,0xf0,0x90,0x91,0x2e,0xf0,0x90,0x91,0x2c,0xf0,0x22,0xe4,0x90, +0x91,0x3c,0xf0,0x90,0x91,0x28,0xf0,0xf5,0x71,0x22,0x90,0x06,0x04,0xe0,0x54,0xbf, +0xf0,0xef,0x60,0x0a,0xe5,0x6d,0xb4,0x01,0x05,0xe4,0xff,0x12,0x47,0xc9,0x53,0x6e, +0xf0,0x43,0x6e,0x0c,0x22,0x90,0x91,0x9d,0xef,0xf0,0x51,0x7e,0x90,0x91,0x9d,0xe0, +0x60,0x05,0x90,0x05,0x22,0xe4,0xf0,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x90,0x00, +0x11,0xe0,0x44,0x09,0xf0,0x12,0x4a,0xe6,0x90,0x90,0xd8,0x12,0x43,0x09,0x90,0x80, +0x96,0x12,0x25,0x08,0x7f,0x78,0x7e,0x08,0x12,0x2b,0x08,0x90,0x90,0xdc,0x12,0x43, +0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x90,0x90, +0xe0,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12,0x2b, +0x08,0x90,0x90,0xe4,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x70,0x7e, +0x0e,0x12,0x2b,0x08,0x90,0x80,0x68,0x12,0x25,0x14,0x00,0x03,0x2d,0x95,0xe4,0xfd, +0xff,0x12,0x30,0x2c,0x90,0x91,0x51,0xe0,0xb4,0x01,0x11,0x90,0x80,0x68,0x12,0x25, +0x14,0x00,0x03,0x2d,0x95,0xe4,0xfd,0x7f,0x01,0x12,0x30,0x2c,0x22,0x8f,0x77,0xe4, +0x90,0x91,0x96,0xf0,0xa3,0xf0,0x90,0x01,0x09,0xe0,0x7f,0x00,0x30,0xe7,0x02,0x7f, +0x01,0xef,0x65,0x77,0x60,0x3e,0xc3,0x90,0x91,0x97,0xe0,0x94,0x88,0x90,0x91,0x96, +0xe0,0x94,0x13,0x40,0x08,0x90,0x01,0xc6,0xe0,0x44,0x80,0xf0,0x22,0x90,0x91,0x96, +0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x7f,0x14,0x7e,0x00,0x12,0x32,0x15,0xd3,0x90, +0x91,0x97,0xe0,0x94,0x32,0x90,0x91,0x96,0xe0,0x94,0x00,0x40,0xb9,0x90,0x01,0xc7, +0xe0,0x30,0xe0,0xb2,0x22,0x22,0x53,0x6e,0xf0,0x43,0x6e,0x01,0x71,0x55,0x71,0x67, +0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0x22,0x8f,0x78,0x12,0x47,0xe6,0xef,0x64,0x01, +0x70,0x2e,0x90,0x91,0x44,0x12,0x48,0x1e,0xe5,0x78,0x60,0x10,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x80,0x0e,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef,0xf0,0x90,0x04,0x1f,0x74,0x20,0xf0, +0x22,0xe4,0xfb,0x90,0x91,0x7c,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0xe5,0x70,0x60, +0x5f,0xe5,0x6d,0x64,0x01,0x70,0x59,0x0b,0x90,0x91,0x27,0xf0,0x04,0x60,0x51,0x43, +0x71,0x10,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4,0xff, +0x90,0x91,0x34,0xe0,0x2f,0x90,0x91,0x67,0xf0,0xe4,0x1b,0x12,0x44,0x54,0x90,0x01, +0x57,0x74,0x05,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f, +0x04,0x12,0x47,0x27,0x90,0x91,0x2e,0xe0,0x60,0x11,0x90,0x91,0x2c,0xe0,0x90,0x07, +0x78,0x60,0x05,0x74,0x0d,0xf0,0x80,0x03,0x74,0x09,0xf0,0x90,0x05,0x22,0xe4,0xf0, +0x22,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0xd3,0x10,0xaf,0x01, +0xc3,0xc0,0xd0,0x90,0x91,0x84,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0, +0x90,0x91,0x84,0xe0,0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90, +0x91,0x87,0xe0,0x94,0xe8,0x90,0x91,0x86,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6, +0xe0,0x44,0x10,0xf0,0x7f,0x00,0x80,0x15,0x90,0x91,0x86,0xe4,0x75,0xf0,0x01,0x12, +0x42,0x81,0x7f,0x0a,0x7e,0x00,0x12,0x32,0x15,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92, +0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90, +0x91,0x1f,0x12,0x25,0x14,0x00,0x00,0x00,0x00,0x90,0x91,0x1c,0x12,0x43,0x21,0x90, +0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x3b,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x90, +0x91,0x25,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x01,0x90,0x91,0x26,0xf0, +0xef,0xc3,0x13,0x54,0x01,0x90,0x91,0x2e,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff, +0x13,0x13,0x54,0x01,0x90,0x91,0x2c,0xf0,0x90,0x91,0x2e,0xe0,0x90,0x91,0x1f,0x70, +0x26,0x12,0x25,0x14,0x00,0x00,0x02,0x10,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80, +0x96,0x12,0x25,0x08,0x7f,0x60,0x7e,0x08,0x12,0x2b,0x08,0x90,0x91,0x1f,0x12,0x25, +0x14,0x00,0x00,0x03,0x10,0x80,0x24,0x12,0x25,0x14,0x00,0x00,0x01,0x10,0x90,0x91, +0x1f,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x60,0x7e,0x08,0x12,0x2b, +0x08,0x90,0x91,0x1f,0x12,0x25,0x14,0x00,0x00,0x03,0x00,0x90,0x91,0x1f,0x12,0x43, +0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x70,0x7e,0x08,0x12,0x2b,0x08,0x90,0x91, +0x26,0xe0,0x70,0x3d,0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x22, +0x65,0x90,0x91,0x1f,0x12,0x25,0x08,0x90,0x91,0x1f,0x12,0x43,0x09,0xec,0x44,0x02, +0xfc,0x90,0x91,0x1f,0x12,0x25,0x08,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x00,0x7e,0x08,0x12,0x2b,0x08,0x90,0x02,0x86,0xe0,0x54,0xfb, +0xf0,0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x49,0x7f,0x90,0x01,0xe5,0xe5,0x70,0xf0, +0x90,0x91,0x3b,0xe0,0x90,0x01,0xe6,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x02, +0x12,0x42,0x20,0xff,0x30,0xe0,0x25,0x12,0x24,0x62,0x90,0x91,0x2f,0xf0,0x90,0x00, +0x01,0x12,0x42,0x20,0x90,0x91,0x30,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x91,0x2d, +0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x90,0x91,0x35,0xf0,0x22,0x90,0x91,0x2f,0x74, +0x0a,0xf0,0x90,0x91,0x30,0x74,0x05,0xf0,0x90,0x91,0x2d,0x74,0x14,0xf0,0x90,0x91, +0x35,0x74,0x05,0xf0,0x22,0x12,0x24,0x62,0x30,0xe0,0x19,0xc3,0x13,0x54,0x7f,0x90, +0x91,0x34,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x91,0x32,0xe4,0xf0,0xa3, +0xef,0xf0,0x80,0x0f,0x90,0x91,0x34,0x74,0x07,0xf0,0x90,0x91,0x32,0xe4,0xf0,0xa3, +0x74,0x03,0xf0,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0x90,0x02, +0x09,0xe0,0xfd,0x12,0x24,0x62,0xfe,0xaf,0x05,0xed,0x2e,0x90,0x91,0x41,0xf0,0x90, +0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x42,0xf0,0x90,0x00,0x02,0x12, +0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x43,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff, +0xed,0x2f,0x90,0x91,0x44,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0xae,0x05,0xed, +0x2f,0x90,0x91,0x45,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x47, +0xe0,0x90,0x91,0x1d,0xf0,0x90,0x91,0x48,0xe0,0xf5,0x19,0xa3,0xe0,0xf5,0x1a,0xe4, +0xf5,0x16,0x74,0x4a,0x25,0x16,0xf5,0x82,0xe4,0x34,0x91,0xf5,0x83,0xe0,0xff,0x74, +0x1b,0x25,0x16,0xf8,0xa6,0x07,0x05,0x16,0xe5,0x16,0xb4,0x04,0xe5,0x90,0x91,0x1d, +0xe0,0x12,0x43,0x4a,0x66,0xb3,0x00,0x67,0xdc,0x01,0x66,0xba,0x02,0x66,0xba,0x03, +0x66,0xba,0x04,0x67,0xdc,0x05,0x67,0xac,0x80,0x67,0xc2,0x81,0x67,0xdc,0x82,0x00, +0x00,0x67,0xd8,0xaf,0x1e,0x12,0x73,0xea,0xe1,0xdc,0x90,0x91,0x1d,0xe0,0xff,0xb4, +0x02,0x08,0x90,0x91,0x1c,0x74,0x01,0xf0,0x80,0x0f,0xef,0x90,0x91,0x1c,0xb4,0x03, +0x05,0x74,0x02,0xf0,0x80,0x03,0x74,0x04,0xf0,0xc3,0xe5,0x19,0x94,0x08,0x50,0x49, +0xe4,0xf5,0x16,0x90,0x91,0x1c,0xe0,0xff,0xe5,0x16,0xc3,0x9f,0x40,0x02,0xe1,0xdc, +0xc3,0xe5,0x19,0x94,0x01,0x50,0x14,0xe5,0x16,0x25,0x1a,0xff,0xc3,0x74,0x03,0x95, +0x16,0x24,0x1b,0xf8,0xe6,0xfd,0x12,0x4b,0xee,0x80,0x1a,0xc3,0x74,0x03,0x95,0x16, +0x24,0x1b,0xf8,0xe6,0xff,0xe5,0x16,0x7c,0x00,0x25,0x1a,0xfd,0xec,0x35,0x19,0x8d, +0x82,0xf5,0x83,0xef,0xf0,0x05,0x16,0x80,0xba,0xc3,0xe5,0x19,0x94,0x10,0x40,0x02, +0xe1,0xdc,0x90,0x91,0x1d,0xe0,0x64,0x04,0x60,0x02,0xe1,0xdc,0xaf,0x1c,0xfc,0xfd, +0xfe,0x78,0x10,0x12,0x24,0xf5,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0xaf,0x1b, +0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x24,0xf5,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0, +0x00,0x12,0x42,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0xaf,0x1d,0xe4,0xfc, +0xfd,0xfe,0x78,0x08,0x12,0x24,0xf5,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12, +0x42,0xfc,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xaf,0x1e,0xe4,0xfc,0xfd,0xfe, +0x12,0x42,0xfc,0xa3,0x12,0x25,0x08,0x90,0x91,0x1e,0x12,0x43,0x09,0x90,0x80,0x96, +0x12,0x25,0x08,0xaf,0x1a,0xae,0x19,0x12,0x2b,0x08,0x80,0x30,0xe5,0x1d,0x7f,0x00, +0xfe,0xef,0x25,0x1e,0xf5,0x18,0xe4,0x3e,0xf5,0x17,0xaf,0x18,0xfe,0x12,0x32,0x15, +0x80,0x1a,0xe5,0x1d,0x7f,0x00,0xfe,0xef,0x25,0x1e,0xf5,0x18,0xe4,0x3e,0xf5,0x17, +0xaf,0x18,0xfe,0x12,0x31,0x82,0x80,0x04,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0, +0x92,0xaf,0x22,0x22,0x8e,0x0e,0x8f,0x0f,0x8b,0x10,0x8a,0x11,0x89,0x12,0xe4,0x90, +0x91,0x11,0xf0,0xef,0x90,0x00,0x31,0xf0,0x12,0x4a,0xe6,0xe5,0x0e,0x54,0x03,0xff, +0x90,0x00,0x32,0xe0,0x54,0xfc,0x4f,0xf0,0x12,0x4a,0xe6,0x90,0x00,0x33,0xe0,0x54, +0x7f,0xf0,0x12,0x4a,0xe6,0x90,0x00,0x33,0xe0,0x20,0xe7,0x0e,0x90,0x91,0x11,0xe0, +0xc3,0x94,0x64,0x50,0x05,0xe0,0x04,0xf0,0x80,0xeb,0x90,0x91,0x11,0xe0,0xc3,0x94, +0x64,0x50,0x10,0x90,0x00,0x30,0xe0,0xab,0x10,0xaa,0x11,0xa9,0x12,0x12,0x42,0x4d, +0x7f,0x01,0x22,0x7f,0x00,0x22,0xe4,0x90,0x91,0x98,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,0x91,0x99,0xe0,0x94,0xe8,0x90,0x91,0x98,0xe0,0x94,0x03,0x40, +0x03,0x7f,0x00,0x22,0x7f,0x32,0x7e,0x00,0x12,0x32,0x15,0x90,0x91,0x98,0xe4,0x75, +0xf0,0x01,0x12,0x42,0x81,0x80,0xc6,0xef,0x70,0x02,0x41,0x3d,0x90,0x90,0xe8,0xe0, +0x60,0x02,0xc1,0x08,0x90,0x90,0xd4,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x8c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x90,0x80,0x12,0x43,0x09,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0x44,0x7e,0x08,0x12,0x2b,0x08,0x90,0x90,0x84,0x12,0x43,0x09, +0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x5c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x90,0x88, +0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x6c,0x7e,0x0e,0x12,0x2b,0x08, +0x90,0x90,0x8c,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x70,0x7e,0x0e, +0x12,0x2b,0x08,0x90,0x90,0x90,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f, +0x74,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0x94,0x12,0x43,0x09,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x78,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0x98,0x12,0x43,0x09,0x90, +0x80,0x96,0x12,0x25,0x08,0x7f,0x7c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0x9c,0x12, +0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x0e,0x12,0x2b,0x08,0x90, +0x90,0xa0,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x84,0x7e,0x0e,0x12, +0x2b,0x08,0x90,0x90,0xa4,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x88, +0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0xa8,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25, +0x08,0x7f,0x8c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0xac,0x12,0x43,0x09,0x90,0x80, +0x96,0x12,0x25,0x08,0x7f,0xd0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0xb0,0x12,0x43, +0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xd4,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90, +0xb4,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xd8,0x7e,0x0e,0x12,0x2b, +0x08,0x90,0x90,0xb8,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0xdc,0x7e, +0x0e,0x12,0x2b,0x08,0x90,0x90,0xbc,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0xe0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0xc0,0x12,0x43,0x09,0x90,0x80,0x96, +0x12,0x25,0x08,0x7f,0xec,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x90,0xc4,0x12,0x43,0x09, +0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x90,0x90,0xc8, +0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x2b,0x08, +0x90,0x90,0xcc,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09, +0x12,0x2b,0x08,0x90,0x90,0xd0,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f, +0x04,0x7e,0x08,0x12,0x2b,0x08,0x90,0x90,0xe8,0x74,0x01,0xf0,0x22,0x90,0x90,0xe8, +0xe0,0x64,0x01,0x60,0x02,0xc1,0x08,0x7f,0x8c,0x7e,0x08,0x12,0x22,0x65,0x90,0x90, +0xd4,0x12,0x25,0x08,0x7f,0x44,0x7e,0x08,0x12,0x22,0x65,0x90,0x90,0x80,0x12,0x25, +0x08,0x7f,0x5c,0x7e,0x08,0x12,0x22,0x65,0x90,0x90,0x84,0x12,0x25,0x08,0x7f,0x6c, +0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0x88,0x12,0x25,0x08,0x7f,0x70,0x7e,0x0e,0x12, +0x22,0x65,0x90,0x90,0x8c,0x12,0x25,0x08,0x7f,0x74,0x7e,0x0e,0x12,0x22,0x65,0x90, +0x90,0x90,0x12,0x25,0x08,0x7f,0x78,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0x94,0x12, +0x25,0x08,0x7f,0x7c,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0x98,0x12,0x25,0x08,0x7f, +0x80,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0x9c,0x12,0x25,0x08,0x7f,0x84,0x7e,0x0e, +0x12,0x22,0x65,0x90,0x90,0xa0,0x12,0x25,0x08,0x7f,0x88,0x7e,0x0e,0x12,0x22,0x65, +0x90,0x90,0xa4,0x12,0x25,0x08,0x7f,0x8c,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0xa8, +0x12,0x25,0x08,0x7f,0xd0,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0xac,0x12,0x25,0x08, +0x7f,0xd4,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0xb0,0x12,0x25,0x08,0x7f,0xd8,0x7e, +0x0e,0x12,0x22,0x65,0x90,0x90,0xb4,0x12,0x25,0x08,0x7f,0xdc,0x7e,0x0e,0x12,0x22, +0x65,0x90,0x90,0xb8,0x12,0x25,0x08,0x7f,0xe0,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90, +0xbc,0x12,0x25,0x08,0x7f,0xec,0x7e,0x0e,0x12,0x22,0x65,0x90,0x90,0xc0,0x12,0x25, +0x08,0x7f,0x04,0x7e,0x0c,0x12,0x22,0x65,0x90,0x90,0xc4,0x12,0x25,0x08,0x7f,0x04, +0x7e,0x0d,0x12,0x22,0x65,0x90,0x90,0xc8,0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09,0x12, +0x22,0x65,0x90,0x90,0xcc,0x12,0x25,0x08,0x7f,0x04,0x7e,0x08,0x12,0x22,0x65,0x90, +0x90,0xd0,0x12,0x25,0x08,0x7f,0x8c,0x7e,0x08,0x12,0x22,0x65,0x90,0x91,0x88,0x12, +0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x44,0xc0,0xfd,0xec,0x90,0x91,0x88, +0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f, +0x8c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x01,0x00,0x00, +0x7f,0x44,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0xdb,0x25, +0xa4,0x7f,0x5c,0x7e,0x08,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb, +0x25,0xa4,0x7f,0x6c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20, +0xdb,0x25,0xa4,0x7f,0x70,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14, +0x04,0x1b,0x25,0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25, +0x14,0x04,0x1b,0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12, +0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96, +0x12,0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80, +0x96,0x12,0x25,0x14,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2b,0x08,0x90, +0x80,0x96,0x12,0x25,0x14,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2b,0x08, +0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12,0x2b, +0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e,0x12, +0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e,0x0e, +0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x20,0xdb,0x25,0xa4,0x7f,0xd8,0x7e, +0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x1b,0x25,0xa4,0x7f,0xdc, +0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x00,0x1b,0x25,0xa4,0x7f, +0xe0,0x7e,0x0e,0x12,0x2b,0x08,0x90,0x80,0x96,0x12,0x25,0x14,0x24,0xdb,0x25,0xa4, +0x7f,0xec,0x7e,0x0e,0x12,0x2b,0x08,0x7f,0x04,0x7e,0x0c,0x12,0x22,0x65,0x90,0x91, +0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90,0x91,0x88, +0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec,0x90,0x91, +0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08, +0x7f,0x04,0x7e,0x0c,0x12,0x2b,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x22,0x65,0x90,0x91, +0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90, +0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec, +0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x04,0x7e,0x0d,0x12,0x2b,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x22,0x65, +0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90, +0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec, +0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12, +0x25,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x2b,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x22,0x65, +0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x54,0x0f,0xfd, +0xec,0x54,0xf0,0xfc,0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91,0x88,0x12,0x43,0x09, +0xed,0x44,0x10,0xfd,0xec,0x44,0x01,0xfc,0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91, +0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x0c,0x7e,0x09,0x12,0x2b, +0x08,0x7f,0x04,0x7e,0x08,0x12,0x22,0x65,0x90,0x91,0x88,0x12,0x25,0x08,0x90,0x91, +0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90,0x91,0x88,0x12,0x25,0x08,0x90, +0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec,0x90,0x91,0x88,0x12,0x25,0x08, +0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x04,0x7e,0x08, +0x12,0x2b,0x08,0xe4,0x90,0x90,0xe8,0xf0,0x22,0xe4,0xfd,0x7f,0x45,0x12,0x4b,0xee, +0x90,0x04,0xfd,0xe4,0xf0,0xa3,0xf0,0x90,0x90,0xf7,0xf0,0x90,0x90,0xfd,0xf0,0x90, +0x91,0x00,0xf0,0x90,0x90,0xfe,0xf0,0x90,0x91,0x01,0xf0,0x90,0x90,0xff,0xf0,0x90, +0x91,0x02,0xf0,0x90,0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90, +0x90,0xee,0xf0,0x90,0x90,0xf3,0xf0,0x90,0x90,0xf5,0xf0,0x90,0x91,0x07,0xf0,0x90, +0x90,0xf8,0xf0,0x90,0x90,0xf4,0xf0,0x90,0x90,0xed,0xf0,0x90,0x00,0x51,0xe0,0x44, +0xc0,0xfd,0x7f,0x51,0x02,0x4b,0xee,0x90,0x05,0x60,0xe0,0x90,0x91,0x03,0xf0,0x90, +0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x05,0xf0,0x90, +0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xc3,0x74,0xff,0x9f,0xfe,0x90,0x91,0x04,0xe0, +0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0,0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3,0xe0, +0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90,0x91,0x06,0x80,0x03,0x90,0x91,0x05,0xe0,0x04, +0xf0,0x22,0x90,0x91,0x04,0xe0,0x2f,0xf0,0x22,0x90,0x90,0xf5,0xe0,0x64,0x01,0x60, +0x02,0xe1,0x6e,0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x12,0x4b,0xee,0x90, +0x91,0x07,0xe0,0x70,0x32,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43, +0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08,0x80,0x06, +0x90,0x05,0x22,0x74,0x7f,0xf0,0x90,0x90,0xf4,0xe0,0xff,0xd1,0x67,0x90,0x91,0x07, +0x74,0x01,0x12,0x4b,0xe4,0x80,0x40,0x90,0x91,0x07,0xe0,0x64,0x01,0x70,0x38,0x90, +0x90,0xf8,0xe0,0xff,0xd1,0x67,0xe4,0x90,0x91,0x07,0xf0,0x90,0x00,0x45,0xe0,0x44, +0x01,0xfd,0x7f,0x45,0x12,0x4b,0xee,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xef, +0x12,0x43,0x09,0x90,0x80,0x96,0x12,0x25,0x08,0x7f,0x80,0x7e,0x08,0x12,0x2b,0x08, +0x80,0x05,0x90,0x05,0x22,0xe4,0xf0,0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x91, +0x03,0xe0,0x90,0x05,0x84,0xf0,0x90,0x91,0x04,0xe0,0x90,0x05,0x85,0xf0,0x90,0x91, +0x05,0xe0,0x90,0x05,0x86,0xf0,0x90,0x91,0x06,0xe0,0x90,0x05,0x87,0xf0,0x22,0x90, +0x90,0xee,0xe0,0xc3,0x94,0x14,0x50,0x06,0xe0,0x04,0xf0,0x02,0x70,0x29,0x90,0x90, +0xee,0xe0,0x64,0x14,0x60,0x03,0x02,0x70,0x29,0x90,0x90,0xfd,0xe0,0x70,0x25,0x90, +0x91,0x00,0xe0,0x70,0x1f,0x90,0x90,0xfe,0xe0,0x70,0x19,0x90,0x91,0x01,0xe0,0x70, +0x13,0x90,0x90,0xff,0xe0,0x70,0x0d,0x90,0x91,0x02,0xe0,0x70,0x07,0x90,0x04,0xfd, +0xe0,0x54,0xfe,0xf0,0x90,0x90,0xfd,0xe0,0x90,0x04,0x44,0xf0,0x90,0x90,0xfe,0xe0, +0x90,0x04,0x45,0xf0,0x90,0x90,0xff,0xe0,0x90,0x04,0x46,0xf0,0xa3,0xe4,0xf0,0x90, +0x91,0x00,0xe0,0x90,0x04,0x48,0xf0,0x90,0x91,0x01,0xe0,0x90,0x04,0x49,0xf0,0x90, +0x91,0x02,0xe0,0x90,0x04,0x4a,0xf0,0xa3,0xe4,0xf0,0x90,0x90,0xe9,0xe0,0x90,0x04, +0x4c,0xf0,0x90,0x90,0xea,0xe0,0x90,0x04,0x4d,0xf0,0x90,0x90,0xeb,0xe0,0x90,0x04, +0x4e,0xf0,0x90,0x90,0xec,0xe0,0x90,0x04,0x4f,0xf0,0xe4,0x90,0x90,0xee,0xf0,0x90, +0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x90,0xfd,0xf0,0xa3, +0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x05,0x60,0xe0,0x90,0x91,0x8c, +0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x8d,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x8e, +0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x8f,0xf0,0x90,0x91,0x06,0xe0,0xff,0x90,0x91, +0x8f,0xe0,0xfe,0xd3,0x9f,0x50,0x0b,0x90,0x91,0x06,0xe0,0xc3,0x9e,0xd3,0x94,0x01, +0x40,0x11,0x90,0x90,0xf4,0xe0,0xb4,0x01,0x02,0x80,0x03,0x90,0x90,0xf8,0xe0,0xff, +0x12,0x6e,0x67,0x22,0x90,0x91,0x07,0xe0,0x64,0x01,0x60,0x08,0x90,0x90,0xf5,0xe0, +0x60,0x02,0x21,0x4b,0x90,0x90,0xe9,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0, +0x80,0x3b,0x90,0x90,0xea,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80, +0x28,0x90,0x90,0xeb,0xe0,0xc3,0x94,0xff,0x50,0x0a,0xe0,0x04,0xf0,0xe4,0x90,0x90, +0xea,0xf0,0x80,0x15,0x90,0x90,0xec,0xe0,0xc3,0x94,0xff,0x50,0x10,0xe0,0x04,0xf0, +0xe4,0x90,0x90,0xeb,0xf0,0x90,0x90,0xea,0xf0,0x90,0x90,0xe9,0xf0,0x90,0x00,0x44, +0xe0,0x54,0x0c,0x60,0x76,0xe0,0x30,0xe2,0x32,0x90,0x90,0xfd,0xe0,0xc3,0x94,0xff, +0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x90,0xfe,0xe0,0xc3,0x94,0xff,0x50,0x06, +0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x90,0xff,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0, +0x04,0xf0,0xe4,0x90,0x90,0xfe,0xf0,0x90,0x90,0xfd,0xf0,0x90,0x00,0x44,0xe0,0x30, +0xe3,0x32,0x90,0x91,0x00,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24, +0x90,0x91,0x01,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90, +0x91,0x02,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x91,0x01,0xf0, +0x90,0x91,0x00,0xf0,0x90,0x04,0xfd,0xe0,0x44,0x01,0xf0,0x22,0x90,0x06,0x90,0xe0, +0x44,0x01,0xf0,0x90,0x91,0x61,0xe0,0x30,0xe0,0x3c,0x90,0x91,0x5f,0xe0,0xff,0x90, +0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x54,0x01,0xfd,0x12,0x4a,0xf6,0x90,0x91,0x60,0xe0, +0x75,0xf0,0x20,0xa4,0xff,0xae,0xf0,0x12,0x32,0x15,0x90,0x91,0x5e,0xe0,0xc4,0x13, +0x54,0x07,0x30,0xe0,0x07,0xa3,0xe0,0xff,0xe4,0xfd,0x80,0x07,0x90,0x91,0x5f,0xe0, +0xff,0x7d,0x01,0x12,0x4a,0xf6,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xe4,0x90, +0x91,0x19,0xf0,0xa3,0x74,0x08,0xf0,0xa3,0xf0,0xe4,0xa3,0xf0,0x90,0x01,0x1f,0xe0, +0xfe,0x90,0x01,0x1e,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x91,0x11,0xf0, +0xa3,0xef,0xf0,0x90,0x02,0x87,0xe0,0x90,0x91,0x18,0xf0,0x90,0x91,0x56,0xe0,0x20, +0xe0,0x02,0x61,0xc4,0xe4,0x90,0x91,0x17,0xf0,0x90,0x91,0x18,0xe0,0xff,0x90,0x91, +0x17,0xe0,0xc3,0x9f,0x40,0x02,0x61,0xc4,0x90,0x91,0x11,0xe0,0xfc,0xa3,0xe0,0xfd, +0xec,0xff,0x90,0xfd,0x11,0xf0,0x90,0x91,0x1c,0xef,0xf0,0x74,0x02,0x2d,0xf5,0x82, +0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x54,0x0f,0xfc,0x33,0x33,0x33,0x54,0xf8,0xff,0xed, +0x24,0x18,0x2f,0x90,0x91,0x15,0xf0,0xe0,0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x54,0xfc,0x90,0x91,0x16,0xf0,0x74,0x01,0x2d,0xf5,0x82,0xe4,0x34,0xfb, +0xf5,0x83,0xe0,0xfe,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x7a, +0x00,0x24,0x00,0xff,0xea,0x3e,0x54,0x3f,0xab,0x07,0xfa,0x90,0x91,0x13,0xf0,0xa3, +0xeb,0xf0,0xaf,0x04,0xef,0x75,0xf0,0x08,0xa4,0x24,0x18,0xff,0xe4,0x35,0xf0,0xfe, +0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x91,0x5a,0xe0,0xfe,0xa3,0xe0,0xff,0xad,0x03, +0xac,0x02,0x12,0x45,0x09,0xaa,0x06,0xab,0x07,0x90,0x91,0x15,0xe0,0x24,0x00,0xf5, +0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x30,0xe7,0x08,0x90,0x91,0x19,0x74,0x02,0xf0, +0x80,0x05,0xe4,0x90,0x91,0x19,0xf0,0xaf,0x03,0x90,0x91,0x11,0xea,0x8f,0xf0,0x12, +0x42,0x81,0x90,0x91,0x5c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x91,0x11,0xe0,0xfc,0xa3, +0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x1b,0x90,0x91,0x5d,0xe0,0x24,0x01,0xff,0x90, +0x91,0x5c,0xe0,0x34,0x00,0xfe,0xc3,0xed,0x9f,0xff,0xec,0x9e,0x90,0x91,0x11,0xf0, +0xa3,0xef,0xf0,0x90,0x91,0x16,0xe0,0xff,0x24,0x40,0x60,0x04,0x24,0x20,0x70,0x27, +0x90,0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x13,0x13,0x54,0x01,0x20,0xe0,0x02,0x61,0x9c, +0xef,0x90,0x00,0x81,0xb4,0xa0,0x05,0xe0,0x44,0x04,0x80,0x03,0xe0,0x44,0x08,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x61,0x95,0x90,0x91,0x5e,0xe0,0xc4,0x13,0x13,0x54,0x03, +0x20,0xe0,0x02,0x61,0x9c,0x90,0x91,0x15,0xe0,0xff,0x24,0x00,0xf5,0x82,0xe4,0x34, +0xfb,0xf5,0x83,0xe0,0x54,0x0c,0x64,0x08,0x70,0x72,0x90,0x91,0x19,0xe0,0xfe,0xef, +0x2e,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x1e,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0, +0x64,0x88,0x70,0x58,0x74,0x1f,0x2f,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x64, +0x8e,0x70,0x49,0x90,0x91,0x19,0xe0,0xff,0x90,0x91,0x15,0xe0,0x2f,0xff,0x90,0x91, +0x1a,0xe0,0x2f,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x19,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x64,0x03,0x70,0x26,0x74,0x1e,0x2f,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83, +0xe0,0x90,0x00,0x81,0x30,0xe3,0x05,0xe0,0x44,0x01,0x80,0x03,0xe0,0x44,0x02,0xfd, +0x7f,0x81,0x12,0x4b,0xee,0x90,0x91,0x56,0xe0,0x44,0x80,0xf0,0x90,0x91,0x56,0xe0, +0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x30,0xe0,0x02,0x31,0x4c,0x71,0xc9,0xbf,0x01, +0x13,0x90,0x91,0x11,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x44,0xb5,0x90,0x91,0x17,0xe0, +0x04,0xf0,0x21,0xd9,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x56,0xe0,0xc4,0x13,0x13, +0x13,0x54,0x01,0x30,0xe0,0x11,0xe0,0x44,0x80,0xf0,0x90,0x91,0x5e,0xe0,0xc4,0x54, +0x0f,0x20,0xe0,0x03,0x7f,0x00,0x22,0x7f,0x01,0x22,0x8f,0x1f,0xe4,0x90,0x91,0x22, +0xf0,0xe5,0x1f,0x14,0xfe,0x90,0x91,0x22,0xe0,0xff,0xc3,0x9e,0x50,0x0e,0xef,0x04, +0xfd,0x12,0x2d,0x4d,0x90,0x91,0x22,0xe0,0x04,0xf0,0x80,0xe5,0xe5,0x1f,0x14,0xff, +0x7d,0xff,0x12,0x2d,0x4d,0x90,0x91,0x22,0xe5,0x1f,0xf0,0x90,0x91,0x22,0xe0,0xc3, +0x94,0xff,0x50,0x0f,0xe0,0xff,0x04,0xfd,0x12,0x2d,0x4d,0x90,0x91,0x22,0xe0,0x04, +0xf0,0x80,0xe8,0xad,0x1f,0x7f,0xff,0x02,0x2d,0x4d,0xc3,0xee,0x94,0x01,0x40,0x0a, +0x0d,0xed,0x13,0x90,0xfd,0x10,0xf0,0xe4,0x2f,0xff,0x22,0xc3,0xee,0x94,0x01,0x40, +0x1e,0x90,0xfd,0x11,0xe0,0xb5,0x05,0x14,0x90,0x01,0x17,0xe0,0xb5,0x05,0x07,0x90, +0xfd,0x11,0xe4,0xf0,0x80,0x06,0xed,0x04,0x90,0xfd,0x11,0xf0,0xe4,0x2f,0xff,0x22, +0x14,0x25,}; + + + +u8 Rtl8192CUFwUMCBCutWWImgArray[UMCBCutWWImgArrayLength] = { +0xc2,0x88,0x02,0x00,0x51,0x00,0x00,0x00,0x03,0x23,0x16,0x45,0x66,0x34,0x01,0x00, +0x58,0x92,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x43,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x4a,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x57,0xe1,0x00,0x00,0x00,0x00,0x00,0x02,0x58,0xc4,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,0x50, +0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,0x22, +0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,0x06, +0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,0xf8, +0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0x22, +0x50,0x06,0xe9,0x25,0x82,0xc8,0xf6,0x22,0xbb,0xfe,0x05,0xe9,0x25,0x82,0xc8,0xf2, +0x22,0xc5,0xf0,0xf8,0xa3,0xe0,0x28,0xf0,0xc5,0xf0,0xf8,0xe5,0x82,0x15,0x82,0x70, +0x02,0x15,0x83,0xe0,0x38,0xf0,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,0xe5, +0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,0xf8, +0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,0x08, +0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,0xf8, +0xbb,0x01,0x11,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5, +0xf0,0xa3,0xf0,0x22,0x50,0x09,0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb, +0xfe,0x09,0xe9,0x25,0x82,0xc8,0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xef,0x4b,0xff,0xee, +0x4a,0xfe,0xed,0x49,0xfd,0xec,0x48,0xfc,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0, +0xfe,0xa3,0xe0,0xff,0x22,0xa4,0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83, +0x22,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x22,0xf8,0xe0,0xfb,0xa3,0xa3,0xe0, +0xf9,0x25,0xf0,0xf0,0xe5,0x82,0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xfa,0x38,0xf0, +0x22,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x22,0xd0,0x83,0xd0,0x82,0xf8,0xe4, +0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5, +0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60,0xef,0xa3,0xa3,0xa3,0x80,0xdf, +0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3, +0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0xb5,0xf0, +0x06,0x74,0x03,0x93,0x68,0x60,0xe9,0xa3,0xa3,0xa3,0xa3,0x80,0xd8,0x02,0x43,0xdb, +0x02,0x50,0x34,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2, +0x08,0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33, +0xc4,0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf, +0xe4,0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x44,0x20,0xe4,0x7e, +0x01,0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,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,0x91,0x40,0x00,0x41,0x91,0x9c,0x00,0x41,0x91,0x23,0x80,0x41,0x91,0x24,0x80, +0x41,0x91,0x9e,0x00,0x41,0x91,0x52,0x00,0x41,0x91,0x93,0x00,0x41,0x91,0x91,0x00, +0x41,0x91,0x90,0x00,0x41,0x91,0x92,0x00,0x00,0xf0,0x90,0x91,0x30,0xe0,0x90,0x91, +0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x54,0x7e,0x01,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0x65,0xeb,0xf0,0xa3,0xe0,0xfb,0xa3,0xe0,0xf5,0x44,0xe4,0xf5,0x45,0x12, +0x35,0xab,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x01,0x5f,0xe4,0xf0,0x90,0x01,0x3c,0x74, +0x08,0xf0,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4, +0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x91,0x59,0x90,0x01,0x5f,0x74,0x05,0xf0,0x90,0x06, +0x92,0x74,0x02,0xf0,0x90,0x91,0x36,0x14,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x0c, +0x50,0x02,0xf1,0x23,0x22,0x90,0x02,0x84,0xef,0xf0,0xa3,0xee,0xf0,0xa3,0x74,0x05, +0xf0,0x22,0x7d,0x01,0xaf,0x6f,0xe1,0x27,0xf1,0xe6,0xbf,0x01,0x10,0x90,0x91,0x42, +0xe0,0xff,0xe4,0xfd,0x12,0x48,0x22,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0x8f,0x82, +0x8e,0x83,0xa3,0xa3,0xa3,0xe4,0xf0,0x22,0xe4,0xf5,0x72,0x7f,0x60,0x7e,0x01,0x80, +0xed,0x7f,0x00,0x22,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0,0x22,0x22, +0x22,0x22,0x22,0x02,0x5e,0x55,0x02,0x5e,0x5c,0xef,0x8e,0xf0,0x71,0x70,0x45,0x26, +0x00,0x40,0x45,0x4e,0x00,0x80,0x45,0x79,0x01,0x00,0x45,0x8d,0x02,0x00,0x45,0xa5, +0x04,0x00,0x00,0x00,0x45,0xc2,0xed,0x54,0x3f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x00,0x7f,0x40,0xef,0x2d,0xff,0xee,0x3c,0xfe,0xef,0x78,0x06,0xce,0xc3,0x13,0xce, +0x13,0xd8,0xf9,0x78,0x06,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x80,0x26,0xed,0x54, +0x7f,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x00,0x7f,0x80,0xef,0x2d,0xff,0xee,0x3c, +0xfe,0xef,0x78,0x07,0xce,0xc3,0x13,0xce,0x13,0xd8,0xf9,0x78,0x07,0xc3,0x33,0xce, +0x33,0xce,0xd8,0xf9,0xfd,0xac,0x06,0x80,0x49,0xed,0x70,0x04,0xfe,0xff,0x80,0x04, +0x7e,0x01,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x7d,0x00,0xfc,0x80,0x35,0xec,0x54,0x01, +0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e,0x02,0x7f,0x00,0xef,0x2d,0xee,0x3c,0xc3, +0x13,0x7d,0x00,0x80,0x1a,0xec,0x54,0x03,0x4d,0x70,0x04,0xfe,0xff,0x80,0x04,0x7e, +0x04,0x7f,0x00,0xef,0x2d,0xee,0x3c,0x13,0x13,0x54,0x3f,0x7d,0x00,0x25,0xe0,0x25, +0xe0,0xfc,0xae,0x04,0xaf,0x05,0x22,0x90,0x91,0x09,0x12,0x2a,0x8b,0x00,0x00,0x00, +0x00,0x90,0x06,0xa9,0xe0,0x90,0x91,0x08,0xf0,0xe0,0x54,0xc0,0x70,0x0a,0x53,0x71, +0xfe,0x53,0x71,0xfd,0x91,0xc2,0x80,0x47,0x90,0x91,0x26,0xe0,0x60,0x41,0x90,0x91, +0x38,0xe0,0x70,0x3b,0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x27, +0xde,0x90,0x91,0x09,0x12,0x2a,0x7f,0x90,0x91,0x09,0x71,0x09,0xec,0x44,0x02,0xfc, +0x90,0x91,0x09,0x12,0x2a,0x7f,0x90,0x91,0x09,0x71,0x09,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x90, +0x91,0x08,0xe0,0x30,0xe6,0x13,0x43,0x71,0x01,0x90,0x91,0x3b,0xe0,0x64,0x02,0x60, +0x04,0x91,0xc8,0x80,0x07,0x91,0x77,0x80,0x03,0x53,0x71,0xfe,0x90,0x91,0x08,0xe0, +0x30,0xe7,0x16,0x43,0x71,0x02,0xe4,0x90,0x91,0x66,0x91,0x49,0x90,0x01,0x57,0x74, +0x05,0xf0,0x90,0x91,0x3c,0x74,0x01,0xf0,0x22,0x53,0x71,0xfd,0x22,0xd3,0x10,0xaf, +0x01,0xc3,0xc0,0xd0,0x8b,0x60,0x8a,0x61,0x89,0x62,0x90,0x91,0x68,0x71,0x41,0xab, +0x63,0xaa,0x64,0xa9,0x65,0x90,0x91,0x6b,0x71,0x41,0xaf,0x66,0x15,0x66,0xef,0x60, +0x1b,0x90,0x91,0x6b,0xe4,0x75,0xf0,0x01,0x71,0x2a,0x12,0x29,0xd9,0xff,0x90,0x91, +0x68,0xe4,0x75,0xf0,0x01,0x71,0x2a,0xef,0x51,0x4d,0x80,0xde,0xab,0x60,0xaa,0x61, +0xa9,0x62,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91, +0x6e,0x71,0x41,0x90,0x91,0x9e,0xe0,0xff,0x04,0xf0,0x90,0x00,0x01,0xef,0x51,0x5f, +0x7f,0xaf,0x7e,0x01,0x12,0x64,0x88,0xef,0x60,0x44,0x90,0x91,0x6e,0x71,0x21,0x8b, +0x63,0x8a,0x64,0x89,0x65,0x75,0x66,0x02,0x7b,0x01,0x7a,0x01,0x79,0xa0,0xd1,0x6d, +0x90,0x91,0x71,0x71,0x21,0x8b,0x63,0x8a,0x64,0x89,0x65,0x90,0x91,0x6e,0x71,0x21, +0x12,0x29,0xd9,0xff,0xc4,0x54,0x0f,0xf5,0x66,0x7b,0x01,0x7a,0x01,0x79,0xa2,0xd1, +0x6d,0x90,0x01,0xaf,0x74,0xff,0xf0,0x90,0x01,0xcb,0xe0,0x64,0x80,0xf0,0xd0,0xd0, +0x92,0xaf,0x22,0x7d,0x01,0x7f,0x0c,0x90,0x91,0x95,0xed,0xf0,0x90,0x91,0x94,0xef, +0xf0,0x54,0x0f,0xff,0xe5,0x6e,0x54,0x0f,0x6f,0x60,0x76,0x90,0x91,0x94,0xe0,0x30, +0xe2,0x30,0xe5,0x6e,0x20,0xe2,0x05,0x7f,0x01,0x12,0x61,0x86,0xe5,0x6e,0x30,0xe3, +0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3,0x08,0x12,0x60,0xb1,0xef,0x60,0x53,0x80,0x52, +0xe5,0x6e,0x20,0xe3,0x4c,0x90,0x91,0x94,0xe0,0x30,0xe3,0x45,0xa3,0xe0,0xff,0x02, +0x61,0x6b,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x0c,0x0f,0x90,0x91,0x94,0xe0,0x20,0xe3, +0x08,0x12,0x60,0xb1,0xef,0x60,0x2a,0xf1,0xb2,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x04, +0x10,0x90,0x91,0x94,0xe0,0x20,0xe2,0x09,0x12,0x60,0xfa,0xef,0x60,0x13,0x12,0x48, +0xce,0xe5,0x6e,0x54,0x0f,0xff,0xbf,0x02,0x08,0x91,0xf1,0xef,0x60,0x03,0x12,0x62, +0x6c,0x22,0x90,0x06,0x04,0xe0,0x44,0x40,0xf0,0xe5,0x6d,0xb4,0x01,0x04,0x7f,0x01, +0xf1,0xc9,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x8f,0x67,0xf1,0xe6,0xbf,0x01,0x15, +0x90,0x91,0x43,0x12,0x48,0x1e,0xad,0x07,0xac,0x06,0xaf,0x67,0x12,0x60,0x16,0x90, +0x04,0x1f,0x74,0x20,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x01,0xc4, +0x74,0xe6,0xf0,0x74,0x47,0xa3,0xf0,0x90,0x04,0x1d,0xe0,0x60,0x1a,0x90,0x05,0x22, +0xe0,0x54,0x90,0x60,0x07,0x90,0x01,0xc6,0xe0,0x44,0x40,0xf0,0x90,0x01,0xc7,0xe0, +0x30,0xe1,0xe4,0x7f,0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0xe0,0xff, +0x7d,0x01,0x90,0x91,0x74,0xef,0xf0,0xa3,0xed,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xe5, +0x70,0x60,0x04,0xe4,0xff,0x11,0xb3,0x90,0x91,0x74,0xe0,0x30,0xe0,0x09,0x90,0x91, +0x76,0xe4,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x91,0x74,0xe0,0xff,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x90,0x04,0x25,0xef,0xf0,0x90,0x91,0x75,0xe0,0x60,0x1f,0xa3,0xa3,0xe0, +0xff,0x24,0x0f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x74,0x10, +0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x80,0xf0,0x90,0x91,0x76,0xa3, +0xe0,0xff,0xfd,0x24,0x08,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe4,0xf0,0x74,0x09, +0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf0,0xf0,0x74,0x21,0x2f,0xf5, +0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xf7,0xf0,0x90,0x91,0x76,0xe0,0xfe,0xa3, +0xe0,0xff,0x22,0xef,0x60,0x0b,0x90,0x91,0x51,0xe0,0xb4,0x01,0x10,0xe4,0xff,0x80, +0x09,0x90,0x91,0x51,0xe0,0xb4,0x01,0x05,0x7f,0x01,0x12,0x69,0x87,0x22,0x90,0x01, +0x37,0x74,0x02,0xf0,0x90,0x05,0x22,0x74,0xff,0xf0,0x12,0x68,0x7c,0xef,0x70,0x06, +0x90,0x01,0xc8,0x74,0xfd,0xf0,0x7d,0x02,0x7f,0x03,0x12,0x36,0xe6,0xe5,0x70,0x60, +0x04,0x7f,0x01,0x11,0xb3,0x12,0x68,0xbd,0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0xef, +0x64,0x01,0x70,0x42,0x7d,0x78,0x7f,0x02,0x12,0x36,0x75,0x7d,0x02,0x7f,0x03,0x12, +0x36,0x75,0x90,0x01,0x36,0x74,0x03,0xf0,0xfd,0x7f,0x02,0x12,0x36,0xe6,0x7d,0x10, +0x7f,0x03,0x12,0x36,0x92,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0, +0x12,0x47,0x23,0xe4,0xff,0x11,0xb3,0x90,0x06,0x04,0xe0,0x54,0x7f,0xf0,0x90,0x06, +0x0a,0xe0,0x54,0xf8,0xf0,0x22,0x90,0x01,0x36,0x74,0x7b,0xf0,0xa3,0x74,0x02,0xf0, +0x7d,0x7b,0xff,0x12,0x36,0xe6,0x7d,0x02,0x7f,0x03,0x12,0x36,0xe6,0x7d,0x10,0x7f, +0x03,0x12,0x36,0x92,0x90,0x06,0x04,0xe0,0x44,0x80,0xf0,0x90,0x06,0x0a,0xe0,0x44, +0x07,0xf0,0x12,0x44,0xf4,0xe5,0x6d,0x20,0xe0,0x05,0xe4,0x90,0x91,0x29,0xf0,0x22, +0x8b,0x0e,0x8a,0x0f,0x89,0x10,0xf1,0xf2,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x12,0x29, +0xd9,0xf5,0x70,0x14,0x60,0x0e,0x14,0x60,0x1e,0x14,0x60,0x2f,0x24,0x03,0x70,0x40, +0x7f,0x01,0x80,0x3a,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02,0x12,0x42,0x20, +0xfd,0xe4,0xff,0x31,0xe1,0x80,0x27,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00,0x02, +0x12,0x42,0x20,0xfd,0x7f,0x01,0x31,0xe1,0x1f,0x80,0x13,0xab,0x0e,0xaa,0x0f,0xa9, +0x10,0x90,0x00,0x02,0x12,0x42,0x20,0xfd,0x7f,0x02,0x31,0xe1,0xe4,0xff,0x11,0xff, +0x22,0xef,0x24,0xfe,0x60,0x0b,0x04,0x70,0x22,0x90,0x91,0x39,0x74,0x01,0xf0,0x80, +0x16,0xed,0x70,0x0a,0x90,0x91,0x35,0xe0,0x90,0x91,0x39,0xf0,0x80,0x05,0x90,0x91, +0x39,0xed,0xf0,0x90,0x91,0x39,0xe0,0x90,0x91,0x27,0xf0,0x22,0x12,0x47,0xe6,0xbf, +0x01,0x0f,0x90,0x02,0x09,0xe0,0xff,0x7d,0x01,0x11,0x22,0x90,0x04,0x1f,0x74,0x20, +0xf0,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,0x22,0xf0,0x74,0x4a,0xa3,0xf0,0x90,0x01,0x34,0xe0,0x55,0x28,0xf5, +0x2c,0x90,0x01,0x36,0xe0,0x55,0x2a,0xf5,0x2e,0xa3,0xe0,0x55,0x2b,0xf5,0x2f,0xe5, +0x2c,0x30,0xe0,0x5a,0x90,0x01,0x34,0x74,0x01,0xf0,0x85,0xd9,0x54,0xe5,0x70,0x14, +0x24,0xfd,0x50,0x02,0x80,0x48,0x90,0x91,0x3b,0xe0,0x60,0x3a,0x90,0x01,0x5b,0xe4, +0xf0,0x90,0x01,0x3c,0x74,0x04,0xf0,0x91,0x89,0xef,0x64,0x01,0x70,0x30,0x90,0x91, +0x66,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91,0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e, +0x01,0x12,0x44,0x59,0x90,0x01,0x5b,0x74,0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0, +0x90,0x91,0x37,0xf0,0x80,0x08,0x91,0x89,0xbf,0x01,0x03,0x12,0x44,0xc2,0xe5,0x2c, +0x30,0xe1,0x21,0x90,0x01,0x34,0x74,0x02,0xf0,0x85,0xd1,0x58,0x85,0xd2,0x59,0x85, +0xd3,0x5a,0x85,0xd4,0x5b,0x85,0xd5,0x5c,0x85,0xd6,0x5d,0x85,0xd7,0x5e,0x85,0xd9, +0x5f,0x12,0x64,0x66,0xe5,0x2c,0x30,0xe3,0x10,0x90,0x01,0x34,0x74,0x08,0xf0,0x90, +0x91,0x56,0xe0,0x30,0xe0,0x03,0x43,0x57,0x04,0xe5,0x2c,0x30,0xe4,0x09,0x90,0x01, +0x34,0x74,0x10,0xf0,0x43,0x57,0x10,0xe5,0x2c,0x30,0xe5,0x24,0x90,0x01,0xcf,0xe0, +0x30,0xe5,0x1d,0xe0,0x54,0xdf,0xf0,0x90,0x01,0x34,0x74,0x20,0xf0,0x75,0xa8,0x00, +0x75,0xe8,0x00,0xd1,0x65,0x90,0x00,0x03,0xe0,0x54,0xfb,0xf0,0x91,0xa0,0x80,0xfe, +0xe5,0x2c,0x30,0xe6,0x06,0x90,0x01,0x34,0x74,0x40,0xf0,0xe5,0x2e,0x30,0xe0,0x15, +0x90,0x91,0x50,0x74,0x01,0xf0,0x90,0x01,0x36,0xf0,0x12,0x63,0x2e,0x12,0x70,0xee, +0x90,0x91,0x50,0xe4,0xf0,0xe5,0x2e,0x30,0xe1,0x3b,0x90,0x01,0x36,0x74,0x02,0xf0, +0x43,0x57,0x40,0x90,0x01,0x02,0xe0,0x54,0x03,0x64,0x01,0x70,0x28,0x90,0x01,0x37, +0xe0,0x30,0xe0,0x0a,0x74,0x01,0xf0,0x90,0x91,0x40,0xe4,0xf0,0x80,0x17,0x90,0x91, +0x40,0xe0,0x04,0xf0,0xe0,0xc3,0x94,0x0a,0x40,0x0b,0xe4,0xf0,0x90,0x04,0x19,0xe0, +0x30,0xe0,0x02,0x51,0x0c,0xe5,0x2e,0x30,0xe2,0x1a,0x90,0x01,0x36,0x74,0x04,0xf0, +0x90,0x91,0x3a,0xe4,0xf0,0x90,0x05,0x58,0x74,0x03,0xf0,0x12,0x62,0xb8,0x90,0x91, +0x3f,0xe0,0x04,0xf0,0xe5,0x2e,0x30,0xe3,0x28,0x90,0x01,0x36,0x74,0x08,0xf0,0xe5, +0x6d,0x64,0x01,0x70,0x1c,0xe5,0x70,0x60,0x18,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01, +0x3c,0x74,0x02,0xf0,0x90,0x91,0x66,0xe4,0x12,0x44,0x49,0x90,0x01,0x57,0x74,0x05, +0xf0,0xe5,0x2e,0x30,0xe4,0x2b,0x90,0x01,0x36,0x74,0x10,0xf0,0xe5,0x6d,0xb4,0x01, +0x20,0xe5,0x70,0x60,0x1c,0x90,0x01,0x57,0xe4,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0, +0x90,0x91,0x3c,0xe4,0xf0,0x53,0x71,0xfd,0xe5,0x71,0x54,0x07,0x70,0x03,0x12,0x44, +0xc2,0xe5,0x2e,0x30,0xe5,0x1f,0x90,0x01,0x36,0x74,0x20,0xf0,0xe5,0x6d,0xb4,0x01, +0x14,0xe5,0x70,0x60,0x10,0x90,0x91,0x3b,0xe0,0x64,0x02,0x60,0x05,0x12,0x44,0xc8, +0x80,0x03,0x12,0x44,0x77,0xe5,0x2e,0x30,0xe6,0x1b,0x90,0x01,0x36,0x74,0x40,0xf0, +0xe5,0x6d,0xb4,0x01,0x10,0xe5,0x70,0x60,0x0c,0x53,0x71,0xfe,0xe5,0x71,0x54,0x07, +0x70,0x03,0x12,0x44,0xc2,0xe5,0x2f,0x30,0xe1,0x09,0x90,0x01,0x37,0x74,0x02,0xf0, +0x12,0x64,0x31,0x74,0x22,0x04,0x90,0x01,0xc4,0xf0,0x74,0x4a,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,0x04,0x1b,0xe0,0x54,0x7f,0x64, +0x7f,0x7f,0x01,0x60,0x02,0x7f,0x00,0x22,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x7f,0x10,0xdf,0xfe,0xd0,0xd0,0x92,0xaf,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x9b,0xed,0xf0,0x90,0x91,0x9a,0xef, +0xf0,0xd3,0x94,0x07,0x50,0x63,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3, +0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0,0x5f,0xf0,0x91,0xa0,0x90,0x91,0x9a, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00, +0x46,0xe0,0x4f,0xf0,0x91,0xa0,0x90,0x91,0x9b,0xe0,0x60,0x16,0x90,0x91,0x9a,0xe0, +0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x45, +0x80,0x66,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xf4,0xff,0x90,0x00,0x45,0x80,0x6b,0x90,0x91,0x9a,0xe0,0x24,0xf8,0xf0, +0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0, +0x91,0x98,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33, +0xd8,0xfc,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0x91,0xa0,0x90,0x91,0x9b,0xe0,0x60, +0x1b,0x90,0x91,0x9a,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x42,0xe0,0x4f,0x80,0x1a,0x90,0x91,0x9a,0xe0, +0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4, +0xff,0x90,0x00,0x42,0xe0,0x5f,0xf0,0x91,0xa0,0xd0,0xd0,0x92,0xaf,0x22,0xf0,0x90, +0x00,0x45,0xe0,0x54,0xfe,0xfd,0x7f,0x45,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x8f, +0x82,0x75,0x83,0x00,0xed,0xf0,0x91,0xa0,0xd0,0xd0,0x92,0xaf,0x22,0xef,0x14,0x60, +0x30,0x14,0x60,0x66,0x24,0x02,0x60,0x02,0xc1,0x64,0x90,0x90,0xf3,0x74,0x02,0xf0, +0x90,0x00,0x48,0xe0,0x44,0x0c,0xfd,0x7f,0x48,0xb1,0xa8,0x90,0x00,0x47,0xe0,0x44, +0x08,0xfd,0x7f,0x47,0xb1,0xa8,0x90,0x00,0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0x80, +0x71,0xe4,0x90,0x90,0xf3,0xf0,0x90,0x90,0xef,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x00,0x45,0xe0,0x44,0xef,0xfd, +0x7f,0x45,0xb1,0xa8,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0xb1,0xa8,0x90, +0x00,0x46,0xe0,0x44,0x10,0xfd,0x7f,0x46,0x80,0x38,0x90,0x90,0xf3,0x74,0x01,0xf0, +0x90,0x90,0xf9,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08, +0x12,0x2f,0xd9,0x90,0x00,0x45,0xe0,0x44,0x20,0xfd,0x7f,0x45,0xb1,0xa8,0x90,0x00, +0x45,0xe0,0x44,0x10,0xfd,0x7f,0x45,0xb1,0xa8,0x90,0x00,0x46,0xe0,0x44,0x10,0xfd, +0x7f,0x46,0xb1,0xa8,0x22,0x90,0x01,0x30,0xe4,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0, +0x90,0x01,0x38,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x50,0xb1,0xa8,0xe4, +0xfd,0x7f,0x51,0xb1,0xa8,0xe4,0xfd,0x7f,0x52,0xb1,0xa8,0xe4,0xfd,0x7f,0x53,0xa1, +0xa8,0x8b,0x0e,0x8a,0x0f,0x89,0x10,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x90,0xf6, +0xf0,0xe0,0x30,0xe0,0x4b,0x90,0x90,0xed,0x74,0x01,0xf0,0x7f,0x80,0x7e,0x08,0x12, +0x27,0xde,0x90,0x90,0xef,0x12,0x2a,0x7f,0xab,0x0e,0xaa,0x0f,0xa9,0x10,0x90,0x00, +0x01,0x12,0x42,0x20,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x1a,0x12,0x2a,0x6c,0xa8,0x04, +0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x90,0xef,0x12,0x43,0x09,0xec,0x54,0x03,0xfc, +0x12,0x42,0xfc,0x90,0x90,0xf9,0x12,0x2a,0x7f,0x90,0x05,0x22,0xe4,0xf0,0x80,0x2d, +0xe4,0x90,0x90,0xed,0xf0,0x7f,0x80,0x7e,0x08,0x12,0x27,0xde,0xec,0x54,0x03,0xfc, +0xec,0x44,0xc0,0xfc,0x90,0x90,0xef,0x12,0x2a,0x7f,0x90,0x90,0xef,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0xf6, +0xe0,0x30,0xe1,0x19,0x7d,0x0c,0x7f,0x47,0xb1,0xa8,0x90,0x00,0x48,0xe0,0x44,0x0c, +0xfd,0x7f,0x48,0xb1,0xa8,0x90,0x00,0x46,0xe0,0x44,0x10,0x80,0x1c,0x90,0x00,0x47, +0xe0,0x54,0xf3,0xfd,0x7f,0x47,0xb1,0xa8,0x90,0x00,0x48,0xe0,0x54,0xf3,0xfd,0x7f, +0x48,0xb1,0xa8,0x90,0x00,0x46,0xe0,0x54,0xef,0xfd,0x7f,0x46,0xb1,0xa8,0xe4,0x90, +0x90,0xf3,0xf0,0x22,0x90,0x01,0x3c,0x74,0xff,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x01, +0x34,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xfd,0x7f,0x54,0xb1,0xa8,0x7d,0xff,0x7f, +0x55,0xb1,0xa8,0x7d,0xff,0x7f,0x56,0xb1,0xa8,0x7d,0xff,0x7f,0x57,0xa1,0xa8,0xe5, +0x72,0x64,0x01,0x70,0x3e,0x12,0x54,0x41,0xbf,0x01,0x05,0x7f,0x01,0x12,0x56,0xe7, +0x90,0x00,0x46,0xe0,0x44,0x04,0xfd,0x7f,0x46,0xb1,0xa8,0x90,0x00,0x44,0xe0,0x54, +0xfb,0xfd,0x7f,0x44,0xb1,0xa8,0x90,0x00,0x46,0xe0,0x54,0xfb,0xfd,0x7f,0x46,0xb1, +0xa8,0x7f,0x02,0x12,0x6f,0x09,0x8f,0x76,0x90,0x01,0xc9,0xe5,0x76,0xf0,0xb4,0x01, +0x02,0xf1,0xd4,0x22,0x90,0x00,0x49,0xe0,0x90,0x91,0x9f,0xf0,0xe0,0x54,0x0f,0xf0, +0x44,0xf0,0xfd,0x7f,0x49,0xb1,0xa8,0x90,0x91,0x9f,0xe0,0x44,0xb0,0xfd,0x7f,0x49, +0xa1,0xa8,0xe4,0x90,0x91,0x3c,0xf0,0x90,0x91,0x28,0xf0,0xf5,0x71,0x22,0x75,0x28, +0x33,0xe4,0xf5,0x29,0x75,0x2a,0x07,0xf5,0x2b,0x90,0x01,0x30,0xe5,0x28,0xf0,0xa3, +0xe5,0x29,0xf0,0xa3,0xe5,0x2a,0xf0,0xa3,0xe5,0x2b,0xf0,0x22,0x75,0x30,0x1f,0x75, +0x31,0x01,0xe4,0xf5,0x32,0x90,0x01,0x38,0xe5,0x30,0xf0,0xa3,0xe5,0x31,0xf0,0xa3, +0xe5,0x32,0xf0,0x22,0xe4,0x90,0x91,0x0e,0xf0,0xa3,0xf0,0x75,0x8e,0x02,0xf1,0x02, +0xd1,0xb4,0x90,0x91,0x4f,0xef,0xf0,0xd1,0xdb,0x90,0x91,0x51,0xef,0xf0,0xf1,0x3d, +0x90,0x91,0x3d,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xf5,0x57,0xd1,0xd2,0x12,0x60,0x37, +0x12,0x32,0x3d,0xd1,0xc1,0x12,0x4f,0xfe,0xf1,0x13,0xd1,0xcb,0x11,0x1c,0x12,0x44, +0xff,0x31,0x23,0x11,0xdf,0x12,0x6f,0xaa,0x90,0x91,0x10,0xe5,0xd9,0xf0,0x12,0x4f, +0x64,0xc2,0xaf,0x90,0x00,0x80,0xe0,0x44,0x40,0xf0,0x12,0x4c,0xa0,0x75,0xe8,0x03, +0x43,0xa8,0x85,0xd2,0xaf,0x90,0x91,0x0e,0xe0,0x64,0x01,0xf0,0x24,0x34,0x90,0x01, +0xc4,0xf0,0x74,0x50,0xa3,0xf0,0xe5,0x57,0x30,0xe2,0x10,0x12,0x5e,0x63,0xbf,0x01, +0x0a,0xc2,0xaf,0x53,0x57,0xfb,0xd2,0xaf,0x12,0x71,0x8a,0xe5,0x57,0x30,0xe4,0x0a, +0xc2,0xaf,0x53,0x57,0xef,0xd2,0xaf,0x12,0x5e,0xa0,0x90,0x90,0xf7,0xe0,0x70,0x03, +0x12,0x70,0x08,0x11,0xf7,0x90,0x91,0x3f,0xe0,0x90,0x01,0xba,0xf0,0x80,0xb6,0x90, +0x91,0x53,0xe0,0x54,0xfe,0xf0,0xe4,0x90,0x91,0x55,0xf0,0x90,0x91,0x53,0xe0,0x54, +0x7f,0xf0,0xa3,0x74,0x0a,0xf0,0x22,0x90,0x06,0x34,0xe0,0x60,0x25,0x14,0x70,0x1b, +0x7b,0x01,0x7a,0x06,0x79,0x35,0x7f,0xf9,0x7e,0x01,0x12,0x68,0x1a,0xbf,0x01,0x09, +0x90,0x06,0x35,0xe0,0x54,0x0f,0xf0,0x80,0x04,0x80,0x00,0xc1,0xf4,0xe4,0x90,0x06, +0x34,0xf0,0x22,0x90,0x91,0x56,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0x7f,0xf0,0x90,0x01, +0x17,0xe0,0xfe,0x90,0x01,0x16,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x91, +0x5c,0xf0,0xa3,0xef,0xf0,0x90,0x01,0x04,0xe0,0x54,0x0f,0x90,0x91,0x1c,0xf0,0xe0, +0xff,0x74,0x40,0x7e,0x00,0xa8,0x07,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8, +0xf9,0x90,0x91,0x5b,0xf0,0xee,0x90,0x91,0x5a,0xf0,0x90,0x91,0x5e,0xe0,0x54,0xfe, +0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xfb,0xf0,0xe0,0x54,0xf7,0xf0,0xe0,0x54,0xef, +0xf0,0xe0,0x54,0xdf,0xf0,0xe0,0x54,0xbf,0xf0,0xe0,0x54,0x7f,0xf0,0xe4,0xa3,0xf0, +0xa3,0xf0,0xa3,0xe0,0x54,0xfe,0xf0,0xe0,0x54,0xfd,0xf0,0xe0,0x54,0xf7,0xf0,0x22, +0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x12,0x29,0xd9,0x54,0x01,0xff,0x90,0x91,0x56, +0xe0,0x54,0xfe,0x4f,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x57,0xf0,0x90, +0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x58,0xf0,0x90,0x91,0x56,0xe0,0x30,0xe0,0x1a, +0x90,0x06,0x09,0xe0,0x54,0xfe,0xf0,0x90,0x02,0x86,0xe0,0x44,0x04,0xf0,0x43,0x57, +0x04,0x7d,0x08,0xe4,0xff,0x12,0x36,0xe6,0x80,0x12,0x7d,0x08,0xe4,0xff,0x12,0x36, +0x75,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x51,0x01,0x31,0x23,0xd0,0xd0,0x92,0xaf, +0x22,0x90,0x06,0x90,0xe4,0xf0,0x21,0x6a,0x90,0x91,0x19,0x12,0x43,0x41,0xef,0x12, +0x43,0x4a,0x52,0x40,0x01,0x52,0x49,0x02,0x52,0x6a,0x03,0x52,0x73,0x09,0x52,0x7b, +0x0c,0x52,0x84,0x0d,0x52,0x8c,0x0e,0x52,0x9d,0x1a,0x52,0xa5,0x2c,0x52,0x51,0x2d, +0x52,0x5a,0x2e,0x52,0xad,0x30,0x52,0x62,0x3b,0x52,0x95,0x3c,0x00,0x00,0x52,0xb5, +0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x64,0xde,0x90,0x91,0x19,0x12,0x43,0x21,0xc1, +0xc5,0x90,0x91,0x19,0x12,0x43,0x21,0x02,0x65,0xf9,0x90,0x91,0x19,0x12,0x43,0x21, +0xe1,0xa8,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x28,0x90,0x91,0x19,0x12,0x43,0x21, +0x02,0x66,0x41,0x90,0x91,0x19,0x12,0x43,0x21,0x80,0x42,0x90,0x91,0x19,0x12,0x43, +0x21,0x02,0x5d,0x16,0x90,0x91,0x19,0x12,0x43,0x21,0xe1,0x75,0x90,0x91,0x19,0x12, +0x43,0x21,0x02,0x4e,0x91,0x90,0x91,0x19,0x12,0x43,0x21,0x21,0xa0,0x90,0x91,0x19, +0x12,0x43,0x21,0xa1,0x7f,0x90,0x91,0x19,0x12,0x43,0x21,0x81,0x5e,0x90,0x91,0x19, +0x12,0x43,0x21,0xe1,0x55,0x90,0x01,0xc6,0xe0,0x44,0x01,0xf0,0x22,0xd3,0x10,0xaf, +0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90,0x91,0x1c,0x12,0x43,0x21, +0x90,0x00,0x01,0x12,0x42,0x97,0xfa,0xe5,0xf0,0x24,0x00,0xff,0xe4,0x3a,0xfe,0x90, +0x91,0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0xee,0x8f,0xf0,0x12,0x42,0xcf,0x12,0x29, +0xd9,0xff,0x60,0x2c,0xb5,0x72,0x16,0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00,0x01, +0x12,0x42,0x97,0x65,0x74,0x70,0x04,0xe5,0x73,0x65,0xf0,0x60,0x23,0x90,0x91,0x1c, +0x12,0x43,0x21,0x90,0x00,0x01,0x12,0x42,0x97,0xff,0xae,0xf0,0x71,0x35,0x80,0x10, +0x90,0x91,0x1c,0x12,0x43,0x21,0x12,0x29,0xd9,0x65,0x72,0x60,0x03,0x12,0x44,0xe8, +0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x1f,0xee,0xf0,0xa3,0xef,0xf0,0x75,0x72,0x01, +0x8e,0x73,0xf5,0x74,0xe4,0xfd,0x7f,0x0b,0x71,0x77,0xe4,0xfd,0x7f,0x02,0x71,0x77, +0x91,0x41,0xe4,0xff,0xd1,0xe7,0xe4,0xf5,0x76,0x90,0x01,0xc9,0xe5,0x76,0xf0,0x90, +0x91,0x1f,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0xfb,0x8d,0x44,0xe4,0xf5,0x45,0x7d,0x01, +0x7f,0x60,0x7e,0x01,0x02,0x35,0xab,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91, +0x22,0xed,0xf0,0x90,0x91,0x21,0xef,0xf0,0xd3,0x94,0x07,0x50,0x4f,0xa3,0xe0,0x70, +0x1a,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xf4,0xff,0x90,0x00,0x47,0xe0,0x5f,0xf0,0x80,0x17,0x90,0x91,0x21,0xe0,0xff, +0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x00,0x47,0xe0, +0x4f,0xf0,0x12,0x4c,0xa0,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0x80,0x5a,0x90,0x91,0x21,0xe0, +0x24,0xf8,0xf0,0xa3,0xe0,0x70,0x1d,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xf4,0xff,0x90,0x00,0x43,0xe0, +0x5f,0xf0,0x80,0x1a,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02, +0xc3,0x33,0xd8,0xfc,0xc4,0x54,0xf0,0xff,0x90,0x00,0x43,0xe0,0x4f,0xf0,0x12,0x4c, +0xa0,0x90,0x91,0x21,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8, +0xfc,0xf4,0xff,0x90,0x00,0x43,0xe0,0x5f,0xf0,0x12,0x4c,0xa0,0xd0,0xd0,0x92,0xaf, +0x22,0x7f,0x0b,0x12,0x6f,0x09,0xef,0x65,0x75,0x60,0x10,0xe5,0x75,0xb4,0x01,0x05, +0xe4,0xf5,0x75,0x80,0x03,0x75,0x75,0x01,0x7f,0x01,0x22,0x7f,0x00,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0xe4,0xf5,0x10,0x75,0x11,0x04,0xf5,0x12,0xf5,0x14,0xf5, +0x15,0x90,0x02,0x09,0xe0,0xff,0x12,0x29,0xd9,0xfe,0xef,0x2e,0xf5,0x13,0x30,0xe0, +0x08,0x75,0x0e,0x00,0x75,0x0f,0x80,0x80,0x05,0xe4,0xf5,0x0e,0xf5,0x0f,0xe5,0x13, +0xc3,0x13,0x90,0xfd,0x10,0xf0,0x74,0x20,0x25,0x10,0xf5,0x10,0xad,0x0f,0xe5,0x10, +0x2d,0xff,0x24,0x01,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x90,0x91,0x47,0xf0, +0x74,0x02,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xfe,0xe5,0x10,0x2d,0x24, +0x03,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x24,0x00,0xff,0xe4,0x3e,0x90,0x91, +0x48,0xf0,0xa3,0xef,0xf0,0x7f,0x04,0xe5,0x10,0x25,0x0f,0x2f,0x24,0x00,0xf5,0x82, +0xe4,0x34,0xfc,0xf5,0x83,0xe0,0xfe,0x74,0x46,0x2f,0xf5,0x82,0xe4,0x34,0x91,0xf5, +0x83,0xee,0xf0,0x0f,0xbf,0x08,0xe0,0x12,0x66,0x89,0xef,0x70,0x3f,0x90,0x01,0xc3, +0xe0,0x60,0x25,0xc3,0xe5,0x15,0x94,0xe8,0xe5,0x14,0x94,0x03,0x40,0x09,0x90,0x01, +0xc6,0xe0,0x44,0x10,0xf0,0x80,0x63,0x05,0x15,0xe5,0x15,0x70,0x02,0x05,0x14,0x7f, +0x0a,0x7e,0x00,0x12,0x37,0x54,0x80,0xd5,0x90,0x01,0xc6,0xe0,0x90,0x01,0xc3,0x30, +0xe2,0x05,0x74,0xfe,0xf0,0x80,0x43,0x74,0xff,0xf0,0x80,0x3e,0xe5,0x10,0xb4,0x78, +0x23,0xe4,0xf5,0x10,0x05,0x13,0xe5,0x0f,0x64,0x80,0x45,0x0e,0x70,0x06,0xf5,0x0e, +0xf5,0x0f,0x80,0x06,0x75,0x0e,0x00,0x75,0x0f,0x80,0xe5,0x13,0xc3,0x13,0x90,0xfd, +0x10,0xf0,0x80,0x06,0x74,0x08,0x25,0x10,0xf5,0x10,0xe5,0x12,0x15,0x12,0x70,0x02, +0x15,0x11,0xe5,0x12,0x45,0x11,0x60,0x02,0x81,0x9c,0xd0,0xd0,0x92,0xaf,0x22,0x90, +0x91,0x1c,0x12,0x43,0x41,0x12,0x29,0xd9,0xff,0x54,0x01,0xfe,0x90,0x91,0x5e,0xe0, +0x54,0xfe,0x4e,0xf0,0xef,0x54,0x04,0xff,0xe0,0x54,0xfb,0x4f,0xf0,0x12,0x29,0xd9, +0xff,0x54,0x02,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xfd,0x4e,0xf0,0xef,0x54,0x08,0xff, +0xe0,0x54,0xf7,0x4f,0xf0,0x12,0x29,0xd9,0xff,0x54,0x10,0xfe,0x90,0x91,0x5e,0xe0, +0x54,0xef,0x4e,0xf0,0xef,0x54,0x20,0xff,0xe0,0x54,0xdf,0x4f,0xf0,0x12,0x29,0xd9, +0xff,0x54,0x40,0xfe,0x90,0x91,0x5e,0xe0,0x54,0xbf,0x4e,0xf0,0xef,0x54,0x80,0xff, +0xe0,0x54,0x7f,0x4f,0xf0,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x91,0x60,0xf0,0x90, +0x00,0x01,0x12,0x42,0x20,0x90,0x91,0x5f,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0xff, +0x54,0x01,0xfe,0x90,0x91,0x61,0xe0,0x54,0xfe,0x4e,0xf0,0xef,0x54,0x02,0xff,0xe0, +0x54,0xfd,0x4f,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x54,0x04,0xff,0x90,0x91,0x61, +0xe0,0x54,0xfb,0x4f,0xf0,0x90,0x91,0x5e,0xe0,0x54,0x01,0x90,0x01,0xb8,0xf0,0x90, +0x91,0x5e,0xe0,0xff,0xc4,0x13,0x54,0x01,0x90,0x01,0xb9,0xf0,0x90,0x91,0x61,0xe0, +0x54,0x01,0x90,0x01,0xba,0xf0,0xa3,0x74,0xff,0xf0,0x12,0x29,0xd9,0x20,0xe0,0x02, +0x41,0x01,0xe4,0xfd,0x7f,0x81,0x12,0x4d,0xa8,0x90,0x91,0x1c,0x12,0x43,0x21,0x12, +0x29,0xd9,0xff,0xc3,0x13,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x02,0xf0,0xef, +0x13,0x13,0x54,0x3f,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x04,0xf0,0x12,0x29, +0xd9,0x13,0x13,0x13,0x54,0x1f,0x30,0xe0,0x07,0x90,0x06,0x90,0xe0,0x44,0x08,0xf0, +0x90,0x91,0x61,0xe0,0x30,0xe0,0x1c,0x90,0x91,0x5e,0xe0,0xc4,0x13,0x54,0x07,0x30, +0xe0,0x07,0xa3,0xe0,0xff,0xe4,0xfd,0x80,0x07,0x90,0x91,0x5f,0xe0,0xff,0x7d,0x01, +0x12,0x4c,0xb0,0x22,0x90,0x00,0x02,0xe0,0x54,0xe0,0x7f,0x01,0x60,0x02,0x7f,0x00, +0x22,0xe4,0xf5,0x75,0x22,0x12,0x29,0xd9,0xf5,0x6d,0x22,0x90,0x01,0x64,0x74,0xa0, +0xf0,0x22,0x90,0x91,0x51,0xe0,0x90,0x90,0xe8,0xf0,0x22,0x90,0x00,0xf3,0xe0,0x7f, +0x00,0x30,0xe3,0x02,0x7f,0x01,0x22,0x90,0x01,0xca,0xe5,0x75,0xf0,0xef,0x60,0x03, +0x12,0x4f,0xd4,0x22,0x90,0x06,0x34,0x74,0xff,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3, +0xf0,0x22,0xe4,0x90,0x91,0x4e,0xf0,0x90,0x00,0x80,0xe0,0x44,0x80,0xfd,0x7f,0x80, +0x02,0x4d,0xa8,0x90,0x00,0xf3,0xe0,0x30,0xe2,0x0d,0x90,0x05,0x41,0x74,0x10,0xf0, +0x90,0x05,0x5a,0xf0,0xa3,0xe4,0xf0,0x22,0x12,0x29,0xd9,0x60,0x02,0x80,0x01,0xe4, +0x90,0x91,0x31,0xf0,0x90,0x91,0x31,0xe0,0x90,0x01,0xe7,0xf0,0x22,0x90,0x91,0x51, +0xe0,0xb4,0x01,0x0c,0x90,0x00,0xf2,0xe0,0x30,0xe7,0x05,0x7e,0xfd,0x7f,0x33,0x22, +0x7e,0xfd,0x7f,0x2f,0x22,0x12,0x29,0xd9,0xff,0x54,0x01,0xfe,0x90,0x91,0x53,0xe0, +0x54,0xfe,0x4e,0xf0,0xef,0xc3,0x13,0x30,0xe0,0x0a,0x90,0x00,0x01,0x12,0x42,0x20, +0x90,0x91,0x54,0xf0,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x90,0xf7,0xf0,0xe0, +0x60,0x04,0xe0,0xf4,0x70,0x21,0xa2,0xaf,0xe4,0x33,0xf5,0x0e,0xc2,0xaf,0x90,0x00, +0x47,0xe0,0x54,0xfb,0xfd,0x7f,0x47,0x12,0x4d,0xa8,0x7d,0x40,0x7f,0x01,0x12,0x36, +0xaf,0xe5,0x0e,0x24,0xff,0x92,0xaf,0x22,0x12,0x29,0xd9,0x30,0xe0,0x19,0xc3,0x13, +0x54,0x7f,0x90,0x91,0x34,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0x90,0x91,0x32, +0xe4,0xf0,0xa3,0xef,0xf0,0x80,0x0f,0x90,0x91,0x34,0x74,0x07,0xf0,0x90,0x91,0x32, +0xe4,0xf0,0xa3,0x74,0x03,0xf0,0x90,0x91,0x32,0xe0,0xa3,0xe0,0x90,0x05,0x58,0xf0, +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,0xe1,0xf0,0x74,0x57,0xa3,0xf0,0x53,0x91,0xef,0x90,0x00,0x51,0xe0,0xff, +0x90,0x00,0x55,0xe0,0x5f,0xf5,0x3d,0x90,0x00,0x52,0xe0,0xff,0x90,0x00,0x56,0xe0, +0x5f,0xf5,0x3e,0xe5,0x3d,0x30,0xe4,0x06,0x90,0x00,0x55,0x74,0x10,0xf0,0xe5,0x3d, +0x30,0xe5,0x06,0x90,0x00,0x55,0x74,0x20,0xf0,0xe5,0x3d,0x30,0xe6,0x1b,0x90,0x00, +0x55,0x74,0x40,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff,0xbf,0x03,0x0b,0x90,0x90, +0xf3,0xe0,0x60,0x05,0x7f,0x01,0x12,0x4d,0xbd,0xe5,0x3d,0x30,0xe7,0x15,0x90,0x00, +0x55,0x74,0x80,0xf0,0x90,0x90,0xf6,0xe0,0x54,0x03,0xff,0xbf,0x03,0x05,0x7f,0x02, +0x12,0x4d,0xbd,0xe5,0x3e,0x30,0xe0,0x06,0x90,0x00,0x56,0x74,0x01,0xf0,0xe5,0x3e, +0x30,0xe1,0x06,0x90,0x00,0x56,0x74,0x02,0xf0,0xe5,0x3e,0x30,0xe2,0x06,0x90,0x00, +0x56,0x74,0x04,0xf0,0xe5,0x3e,0x30,0xe3,0x06,0x90,0x00,0x56,0x74,0x08,0xf0,0x90, +0x01,0xc4,0x74,0xe1,0xf0,0x74,0x57,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,0x75,0x0d,0x00,0x90,0x01,0xc4,0x74,0xc4,0xf0,0x74,0x58,0xa3,0xf0,0x53,0x91, +0xdf,0x90,0x01,0x3c,0xe0,0x55,0x30,0xf5,0x34,0xa3,0xe0,0x55,0x31,0xf5,0x35,0xa3, +0xe0,0x55,0x32,0xf5,0x36,0xa3,0xe0,0x55,0x33,0xf5,0x37,0xe5,0x34,0x30,0xe0,0x06, +0x90,0x01,0x3c,0x74,0x01,0xf0,0xe5,0x34,0x30,0xe1,0x08,0x90,0x01,0x3c,0x74,0x02, +0xf0,0x71,0x89,0xe5,0x34,0x30,0xe2,0x3a,0x90,0x01,0x3c,0x74,0x04,0xf0,0x90,0x06, +0x92,0xe0,0x30,0xe0,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91, +0x67,0xf0,0xe4,0xfb,0xfd,0x7f,0x58,0x7e,0x01,0x12,0x44,0x59,0x90,0x01,0x5b,0x74, +0x05,0xf0,0x90,0x06,0x92,0x74,0x01,0xf0,0x80,0x08,0x90,0x91,0x37,0xe4,0xf0,0x12, +0x44,0xc2,0xe5,0x34,0x30,0xe3,0x3a,0x90,0x01,0x3c,0x74,0x08,0xf0,0x90,0x06,0x92, +0xe0,0x30,0xe1,0x25,0x90,0x91,0x66,0xe4,0xf0,0x90,0x91,0x2d,0xe0,0x90,0x91,0x67, +0xf0,0xe4,0xfb,0xfd,0x7f,0x5c,0x7e,0x01,0x12,0x44,0x59,0x90,0x01,0x5f,0x74,0x05, +0xf0,0x90,0x06,0x92,0x74,0x02,0xf0,0x80,0x08,0x90,0x91,0x36,0xe4,0xf0,0x12,0x44, +0xc2,0xe5,0x34,0x30,0xe4,0x09,0x90,0x01,0x3c,0x74,0x10,0xf0,0x12,0x4f,0x8f,0xe5, +0x34,0x30,0xe5,0x08,0x90,0x01,0x3c,0x74,0x20,0xf0,0x51,0x62,0xe5,0x35,0x30,0xe0, +0x5a,0x90,0x01,0x3d,0x74,0x01,0xf0,0x90,0x01,0x2f,0xe0,0x44,0x7f,0xf0,0x90,0x00, +0x83,0xe0,0x54,0x0f,0xf5,0x0d,0xb4,0x01,0x02,0x80,0x1c,0xe5,0x0d,0xb4,0x02,0x05, +0x90,0x00,0x83,0x80,0x12,0xe5,0x0d,0xb4,0x04,0x05,0x90,0x00,0x83,0x80,0x08,0xe5, +0x0d,0xb4,0x0c,0x08,0x90,0x00,0x83,0xe0,0xf5,0x6f,0x80,0x06,0x90,0x01,0xbe,0xe0, +0x04,0xf0,0x90,0x01,0xbb,0xe5,0x6f,0xf0,0xe5,0x6f,0x30,0xe0,0x03,0xa3,0x80,0x03, +0x90,0x01,0xbd,0xe0,0x04,0xf0,0x71,0x6a,0x12,0x44,0xc2,0xe5,0x35,0x30,0xe2,0x06, +0x90,0x01,0x3d,0x74,0x04,0xf0,0xe5,0x36,0x30,0xe0,0x06,0x90,0x01,0x3e,0x74,0x01, +0xf0,0xe5,0x36,0x30,0xe1,0x06,0x90,0x01,0x3e,0x74,0x02,0xf0,0x74,0xc4,0x04,0x90, +0x01,0xc4,0xf0,0x74,0x58,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,0x90,0xf5,0xe0,0x64,0x01,0x60,0x02,0x61,0x17,0x90,0x00,0x46,0xe0, +0x44,0x01,0xfd,0x7f,0x46,0x12,0x4d,0xa8,0x90,0x91,0x07,0xe0,0x70,0x32,0x90,0x90, +0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x80,0x06,0x90,0x05,0x22,0x74,0x7f,0xf0,0x90, +0x90,0xf4,0xe0,0xff,0x71,0x18,0x90,0x91,0x07,0x74,0x01,0x12,0x4d,0x9e,0x80,0x40, +0x90,0x91,0x07,0xe0,0x64,0x01,0x70,0x38,0x90,0x90,0xf8,0xe0,0xff,0x71,0x18,0xe4, +0x90,0x91,0x07,0xf0,0x90,0x00,0x45,0xe0,0x44,0x01,0xfd,0x7f,0x45,0x12,0x4d,0xa8, +0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xef,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x80,0x05,0x90,0x05,0x22,0xe4,0xf0, +0x90,0x05,0x87,0xe0,0x64,0x80,0xf0,0x90,0x91,0x03,0xe0,0x90,0x05,0x84,0xf0,0x90, +0x91,0x04,0xe0,0x90,0x05,0x85,0xf0,0x90,0x91,0x05,0xe0,0x90,0x05,0x86,0xf0,0x90, +0x91,0x06,0xe0,0x90,0x05,0x87,0xf0,0x22,0x90,0x05,0x60,0xe0,0x90,0x91,0x03,0xf0, +0x90,0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x05,0xf0, +0x90,0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xc3,0x74,0xff,0x9f,0xfe,0x90,0x91,0x04, +0xe0,0xd3,0x9e,0x40,0x1e,0xe0,0x2f,0xf0,0xa3,0xe0,0xb4,0xff,0x0f,0xe4,0xf0,0xa3, +0xe0,0xb4,0xff,0x03,0xe4,0xf0,0x22,0x90,0x91,0x06,0x80,0x03,0x90,0x91,0x05,0xe0, +0x04,0xf0,0x22,0x90,0x91,0x04,0xe0,0x2f,0xf0,0x22,0xe5,0x6f,0x30,0xe6,0x19,0xe5, +0x6f,0x54,0x0f,0xff,0x90,0x91,0x24,0xe0,0xfe,0x4f,0x90,0x01,0x2f,0xf0,0xee,0x64, +0x80,0x90,0x91,0x24,0xf0,0x53,0x6f,0xbf,0x22,0xe4,0x90,0x91,0x0d,0xf0,0xe5,0x70, +0x70,0x02,0x81,0x13,0x90,0x91,0x3c,0xe0,0x60,0x0d,0xe4,0xf0,0x53,0x71,0xfd,0xe5, +0x71,0x54,0x07,0x70,0x6e,0x80,0x69,0x90,0x91,0x28,0xe0,0x04,0xf0,0x53,0x71,0xef, +0x90,0x91,0x3a,0xe0,0x04,0xf0,0x90,0x91,0x0d,0xe0,0xf9,0xff,0x7e,0x00,0x24,0x01, +0xfd,0xee,0x33,0xfc,0x90,0x91,0x3a,0xe0,0xb5,0x05,0x06,0xe4,0xb5,0x04,0x02,0x80, +0x12,0xef,0x24,0x02,0xff,0xe4,0x3e,0xfe,0x90,0x91,0x3a,0xe0,0xb5,0x07,0x0a,0xe4, +0xb5,0x06,0x06,0x90,0x05,0x58,0xe0,0x04,0xf0,0xe9,0xff,0x90,0x91,0x2f,0xe0,0x2f, +0xff,0xe4,0x33,0xfe,0x90,0x91,0x28,0xe0,0xd3,0x9f,0xee,0x64,0x80,0xf8,0x74,0x80, +0x98,0x40,0x0d,0xe5,0x6d,0xb4,0x01,0x0b,0xa3,0xe0,0x70,0x07,0xe0,0x04,0xf0,0x22, +0x12,0x44,0xc2,0x22,0x90,0x90,0xee,0xe0,0xc3,0x94,0x14,0x50,0x05,0xe0,0x04,0xf0, +0x81,0xcc,0x90,0x90,0xee,0xe0,0x64,0x14,0x60,0x02,0x81,0xcc,0x90,0x90,0xfd,0xe0, +0x70,0x25,0x90,0x91,0x00,0xe0,0x70,0x1f,0x90,0x90,0xfe,0xe0,0x70,0x19,0x90,0x91, +0x01,0xe0,0x70,0x13,0x90,0x90,0xff,0xe0,0x70,0x0d,0x90,0x91,0x02,0xe0,0x70,0x07, +0x90,0x04,0xfd,0xe0,0x54,0xfe,0xf0,0x90,0x90,0xfd,0xe0,0x90,0x04,0x44,0xf0,0x90, +0x90,0xfe,0xe0,0x90,0x04,0x45,0xf0,0x90,0x90,0xff,0xe0,0x90,0x04,0x46,0xf0,0xa3, +0xe4,0xf0,0x90,0x91,0x00,0xe0,0x90,0x04,0x48,0xf0,0x90,0x91,0x01,0xe0,0x90,0x04, +0x49,0xf0,0x90,0x91,0x02,0xe0,0x90,0x04,0x4a,0xf0,0xa3,0xe4,0xf0,0x90,0x90,0xe9, +0xe0,0x90,0x04,0x4c,0xf0,0x90,0x90,0xea,0xe0,0x90,0x04,0x4d,0xf0,0x90,0x90,0xeb, +0xe0,0x90,0x04,0x4e,0xf0,0x90,0x90,0xec,0xe0,0x90,0x04,0x4f,0xf0,0xe4,0x90,0x90, +0xee,0xf0,0x90,0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x90, +0xfd,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x05,0x60,0xe0, +0x90,0x91,0x8c,0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x8d,0xf0,0x90,0x05,0x62,0xe0, +0x90,0x91,0x8e,0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x8f,0xf0,0x90,0x91,0x06,0xe0, +0xff,0x90,0x91,0x8f,0xe0,0xfe,0xd3,0x9f,0x50,0x0b,0x90,0x91,0x06,0xe0,0xc3,0x9e, +0xd3,0x94,0x01,0x40,0x10,0x90,0x90,0xf4,0xe0,0xb4,0x01,0x02,0x80,0x03,0x90,0x90, +0xf8,0xe0,0xff,0x71,0x18,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0x90,0x90,0xf5,0xf0, +0x90,0x00,0x01,0x12,0x42,0x20,0x25,0xe0,0x25,0xe0,0x90,0x90,0xf4,0xf0,0x12,0x29, +0xd9,0x25,0xe0,0x25,0xe0,0x90,0x90,0xf8,0xf0,0x90,0x05,0x60,0xe0,0x90,0x91,0x03, +0xf0,0x90,0x05,0x61,0xe0,0x90,0x91,0x04,0xf0,0x90,0x05,0x62,0xe0,0x90,0x91,0x05, +0xf0,0x90,0x05,0x63,0xe0,0x90,0x91,0x06,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c, +0xf0,0xc2,0xaf,0x90,0x90,0xf4,0xe0,0xff,0x71,0x18,0x90,0x91,0x1c,0xe0,0x24,0xff, +0x92,0xaf,0x90,0x90,0xf5,0xe0,0x70,0x02,0xc1,0x1f,0x90,0x90,0xf4,0xe0,0x70,0x02, +0xc1,0x1f,0x90,0x90,0xf8,0xe0,0x70,0x02,0xc1,0x1f,0xa2,0xaf,0xe4,0x33,0x90,0x91, +0x1c,0xf0,0xc2,0xaf,0x90,0x91,0x07,0x74,0x01,0xf0,0x90,0x91,0x1c,0xe0,0x24,0xff, +0x92,0xaf,0x12,0x4d,0x9f,0x90,0x00,0x46,0xe0,0x44,0x01,0xfd,0x7f,0x46,0x12,0x4d, +0xa8,0x90,0x90,0xed,0xe0,0x60,0x15,0x90,0x90,0xf9,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x08,0x12,0x2f,0xd9,0x80,0x06,0x90,0x05,0x22,0x74, +0x7f,0xf0,0x90,0x00,0x45,0xe0,0x54,0xef,0xfd,0x7f,0x45,0x12,0x4d,0xa8,0x90,0x05, +0x87,0xe0,0x64,0x80,0xf0,0x90,0x91,0x03,0xe0,0x90,0x05,0x84,0xf0,0x90,0x91,0x04, +0xe0,0x90,0x05,0x85,0xf0,0x90,0x91,0x05,0xe0,0x90,0x05,0x86,0xf0,0x90,0x91,0x06, +0xe0,0x90,0x05,0x87,0xf0,0xa2,0xaf,0xe4,0x33,0x90,0x91,0x1c,0xf0,0xc2,0xaf,0x90, +0x01,0x3c,0xe0,0x44,0x20,0xf0,0x7d,0x20,0xe4,0xff,0x12,0x37,0x00,0x80,0x2d,0x90, +0x90,0xf5,0xe0,0x70,0x2f,0x90,0x91,0x07,0x12,0x4d,0x9e,0x90,0x00,0x46,0xe0,0x54, +0xfe,0xfd,0x7f,0x46,0x12,0x4d,0xa8,0x90,0x05,0x22,0xe4,0xf0,0xa2,0xaf,0x33,0x90, +0x91,0x1c,0xf0,0xc2,0xaf,0x7d,0x20,0xe4,0xff,0x12,0x36,0x92,0x90,0x91,0x1c,0xe0, +0x24,0xff,0x92,0xaf,0x22,0x8f,0x20,0x8c,0x21,0x8d,0x22,0x22,0x8f,0x23,0x8c,0x24, +0x8d,0x25,0x22,0xe4,0x90,0x91,0x11,0xf0,0xa3,0xf0,0x90,0x02,0x86,0xe0,0x20,0xe1, +0x2c,0xc3,0x90,0x91,0x12,0xe0,0x94,0x20,0x90,0x91,0x11,0xe0,0x94,0x03,0x40,0x0a, +0x90,0x01,0xc6,0xe0,0x44,0x20,0xf0,0x7f,0x00,0x22,0x90,0x91,0x11,0xe4,0x75,0xf0, +0x01,0x12,0x42,0x81,0x7f,0x01,0x7e,0x00,0x12,0x37,0x54,0x80,0xcd,0x7f,0x01,0x22, +0x90,0x01,0xcc,0xe0,0x54,0x0f,0x90,0x91,0x11,0xf0,0x90,0x91,0x11,0xe0,0xfd,0x70, +0x02,0xe1,0xe2,0x90,0x91,0x9c,0xe0,0xff,0x74,0x01,0x7e,0x00,0xa8,0x07,0x08,0x80, +0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xef,0x5d,0x70,0x02,0xe1,0xdb,0x90, +0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd0,0x12,0x43,0x15,0xe0,0x90,0x91,0x12, +0xf0,0x75,0x63,0x01,0x75,0x64,0x91,0x75,0x65,0x12,0x75,0x66,0x01,0x7b,0x01,0x7a, +0x91,0x79,0x13,0x12,0x46,0x6d,0x90,0x91,0x13,0xe0,0xff,0xc4,0x13,0x13,0x13,0x54, +0x01,0x90,0x91,0x9c,0x30,0xe0,0x59,0xe0,0x75,0xf0,0x02,0x90,0x00,0x88,0x12,0x43, +0x15,0xe0,0x90,0x91,0x14,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x02,0x90,0x00,0x89, +0x12,0x43,0x15,0xe0,0x90,0x91,0x15,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90, +0x01,0xd1,0x12,0x43,0x15,0xe0,0x90,0x91,0x16,0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0, +0x04,0x90,0x01,0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x17,0xf0,0x90,0x91,0x9c,0xe0, +0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90,0x91,0x18,0xf0,0x80,0x33, +0xe0,0x75,0xf0,0x04,0x90,0x01,0xd1,0x12,0x43,0x15,0xe0,0x90,0x91,0x14,0xf0,0x90, +0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd2,0x12,0x43,0x15,0xe0,0x90,0x91,0x15, +0xf0,0x90,0x91,0x9c,0xe0,0x75,0xf0,0x04,0x90,0x01,0xd3,0x12,0x43,0x15,0xe0,0x90, +0x91,0x16,0xf0,0xef,0x54,0x7f,0xff,0x7b,0x01,0x7a,0x91,0x79,0x14,0x12,0x52,0x08, +0x90,0x91,0x11,0xe0,0xff,0x90,0x91,0x9c,0xe0,0xfe,0x74,0x01,0xa8,0x06,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0xf4,0x5f,0x90,0x91,0x11,0xf0,0x90,0x91,0x9c,0xe0,0xff, +0x74,0x01,0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x90,0x01,0xcc,0xf0,0x90, +0x91,0x9c,0xe0,0x04,0xf0,0xe0,0x54,0x03,0xf0,0xc1,0xaa,0x90,0x01,0xc6,0xe0,0x44, +0x02,0xf0,0x22,0xad,0x07,0x74,0x11,0x2d,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0, +0x44,0x01,0xf0,0x90,0x04,0x80,0xe0,0x54,0x0f,0xfc,0x74,0x14,0x2d,0xf5,0x82,0xe4, +0x34,0xfc,0xf5,0x83,0xe0,0x54,0xc0,0x4c,0xfd,0x74,0x14,0x2f,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xed,0xf0,0x22,0xef,0x60,0x0f,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34, +0xfc,0xf5,0x83,0xe0,0x44,0x10,0xf0,0x22,0x74,0x21,0x2d,0xf5,0x82,0xe4,0x34,0xfc, +0xf5,0x83,0xe0,0x54,0xef,0xf0,0x22,0xe4,0xf5,0x6d,0xf5,0x71,0xf5,0x70,0x75,0x6f, +0x0c,0x75,0x6e,0x0c,0x90,0x91,0x3b,0xf0,0x90,0x91,0x37,0xf0,0x90,0x91,0x36,0xf0, +0x90,0x91,0x39,0x04,0xf0,0x90,0x91,0x27,0xf0,0xe4,0x90,0x91,0x3c,0xf0,0x90,0x91, +0x29,0xf0,0x90,0x91,0x34,0x74,0x07,0xf0,0xe4,0x90,0x91,0x28,0xf0,0x90,0x91,0x32, +0xf0,0xa3,0x74,0x03,0xf0,0x90,0x91,0x2f,0x74,0x0a,0xf0,0xa3,0x74,0x05,0xf0,0x90, +0x91,0x2d,0x74,0x14,0xf0,0x90,0x91,0x35,0x74,0x05,0xf0,0xe4,0x90,0x91,0x2b,0xf0, +0x90,0x91,0x25,0xf0,0x90,0x91,0x50,0xf0,0x90,0x91,0x31,0xf0,0x90,0x91,0x3a,0xf0, +0x90,0x91,0x26,0xf0,0x90,0x91,0x38,0xf0,0x90,0x91,0x2e,0xf0,0x90,0x91,0x2c,0xf0, +0x22,0x12,0x4c,0x89,0xef,0x64,0x01,0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80, +0x30,0x90,0x91,0x37,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x22,0x90, +0x91,0x36,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x14,0xe5,0x6f,0x54, +0x0f,0xd3,0x94,0x04,0x40,0x08,0x90,0x01,0xb9,0x74,0x08,0xf0,0x80,0x03,0x7f,0x01, +0x22,0x90,0x01,0xb8,0x74,0x08,0xf0,0x7f,0x00,0x22,0x12,0x4c,0x89,0xef,0x64,0x01, +0x60,0x08,0x90,0x01,0xb9,0x74,0x01,0xf0,0x80,0x58,0xe5,0x71,0x54,0x03,0x60,0x08, +0x90,0x01,0xb9,0x74,0x02,0xf0,0x80,0x4a,0xe5,0x6f,0x54,0x0f,0xd3,0x94,0x02,0x40, +0x08,0x90,0x01,0xb9,0x74,0x04,0xf0,0x80,0x39,0xe5,0x71,0x30,0xe2,0x08,0x90,0x01, +0xb9,0x74,0x08,0xf0,0x80,0x2c,0xe5,0x71,0x30,0xe4,0x08,0x90,0x01,0xb9,0x74,0x10, +0xf0,0x80,0x1f,0x90,0x91,0x29,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x20,0xf0,0x80, +0x11,0x90,0x91,0x31,0xe0,0x60,0x08,0x90,0x01,0xb9,0x74,0x80,0xf0,0x80,0x03,0x7f, +0x01,0x22,0x90,0x01,0xb8,0x74,0x04,0xf0,0x7f,0x00,0x22,0x90,0x06,0x04,0xe0,0x54, +0xbf,0xf0,0xef,0x60,0x0a,0xe5,0x6d,0xb4,0x01,0x05,0xe4,0xff,0x12,0x47,0xc9,0x53, +0x6e,0xf0,0x43,0x6e,0x0c,0x22,0x90,0x91,0x9d,0xef,0xf0,0x31,0x9f,0x90,0x91,0x9d, +0xe0,0x60,0x05,0x90,0x05,0x22,0xe4,0xf0,0x53,0x6e,0xf0,0x43,0x6e,0x04,0x22,0x90, +0x90,0xd8,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12, +0x2f,0xd9,0x90,0x90,0xdc,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90,0xe0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0xe4,0x12,0x43,0x09,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x59,0x12,0x2a, +0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90,0x91,0x51,0xe0,0xb4, +0x01,0x11,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x03,0x2d,0x95,0xe4,0xfd,0x7f,0x01, +0x12,0x34,0x81,0x22,0x8f,0x77,0xe4,0x90,0x91,0x96,0xf0,0xa3,0xf0,0x90,0x01,0x09, +0xe0,0x7f,0x00,0x30,0xe7,0x02,0x7f,0x01,0xef,0x65,0x77,0x60,0x3e,0xc3,0x90,0x91, +0x97,0xe0,0x94,0x88,0x90,0x91,0x96,0xe0,0x94,0x13,0x40,0x08,0x90,0x01,0xc6,0xe0, +0x44,0x80,0xf0,0x22,0x90,0x91,0x96,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x7f,0x14, +0x7e,0x00,0x12,0x37,0x54,0xd3,0x90,0x91,0x97,0xe0,0x94,0x32,0x90,0x91,0x96,0xe0, +0x94,0x00,0x40,0xb9,0x90,0x01,0xc7,0xe0,0x30,0xe0,0xb2,0x22,0x53,0x6e,0xf0,0x43, +0x6e,0x01,0x12,0x45,0x00,0x12,0x45,0x01,0x53,0x6e,0xf0,0x43,0x6e,0x02,0x22,0x8f, +0x78,0x12,0x47,0xe6,0xef,0x64,0x01,0x70,0x2e,0x90,0x91,0x44,0x12,0x48,0x1e,0xe5, +0x78,0x60,0x10,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x44,0x10, +0xf0,0x80,0x0e,0x74,0x21,0x2f,0xf5,0x82,0xe4,0x34,0xfc,0xf5,0x83,0xe0,0x54,0xef, +0xf0,0x90,0x04,0x1f,0x74,0x20,0xf0,0x22,0xe5,0x6d,0x64,0x01,0x70,0x63,0xe5,0x70, +0x60,0x5f,0xe5,0x70,0x64,0x02,0x60,0x06,0xe5,0x70,0x64,0x05,0x70,0x27,0x90,0x06, +0xab,0xe0,0x90,0x91,0x27,0xf0,0x90,0x06,0xaa,0xe0,0x90,0x91,0x39,0xf0,0x90,0x91, +0x27,0xe0,0x70,0x07,0x90,0x91,0x39,0xe0,0xff,0x80,0x05,0x90,0x91,0x27,0xe0,0xff, +0x90,0x91,0x27,0xef,0xf0,0x90,0x91,0x29,0xe0,0x60,0x03,0xe0,0x14,0xf0,0xe4,0x90, +0x91,0x28,0xf0,0x90,0x01,0x57,0xf0,0x90,0x01,0x3c,0x74,0x02,0xf0,0x53,0x71,0xfd, +0x53,0x71,0xef,0xe5,0x70,0x14,0x24,0xfd,0x50,0x02,0x80,0x03,0x12,0x45,0xc7,0x71, +0x22,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0xd0,0xd0,0x92,0xaf,0x22,0xe4,0xfb, +0x90,0x91,0x78,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x70,0x70,0x02,0x61,0xc0, +0xe5,0x6d,0x64,0x01,0x70,0x7a,0xe5,0x70,0x14,0x60,0x2b,0x24,0xfd,0x60,0x27,0x24, +0x02,0x24,0xfb,0x50,0x02,0x80,0x21,0x90,0x91,0x27,0xe0,0x14,0xf0,0xe0,0x60,0x04, +0xa3,0xe0,0x60,0x14,0x90,0x91,0x27,0xe0,0x70,0x08,0x90,0x91,0x39,0xe0,0x90,0x91, +0x27,0xf0,0x7b,0x01,0x80,0x02,0x7b,0x01,0xeb,0x60,0x45,0x43,0x71,0x10,0xe4,0x90, +0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4,0xff,0x90,0x91,0x34,0xe0, +0x2f,0x12,0x44,0x4e,0x90,0x01,0x57,0x74,0x05,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94, +0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27,0x90,0x91,0x2e,0xe0,0x60,0x10, +0x90,0x91,0x2c,0xe0,0x90,0x07,0x78,0x60,0x04,0x74,0x0d,0xf0,0x22,0x74,0x09,0xf0, +0x22,0xe4,0xfb,0x90,0x91,0x7c,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x70,0x60, +0x5f,0xe5,0x6d,0x64,0x01,0x70,0x59,0x0b,0x90,0x91,0x27,0xf0,0x04,0x60,0x51,0x43, +0x71,0x10,0xe4,0x90,0x91,0x66,0xf0,0x90,0x91,0x3a,0xe0,0x75,0xf0,0x05,0xa4,0xff, +0x90,0x91,0x34,0xe0,0x2f,0x90,0x91,0x67,0xf0,0xe4,0x1b,0x12,0x44,0x54,0x90,0x01, +0x57,0x74,0x05,0xf0,0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f, +0x04,0x12,0x47,0x27,0x90,0x91,0x2e,0xe0,0x60,0x11,0x90,0x91,0x2c,0xe0,0x90,0x07, +0x78,0x60,0x05,0x74,0x0d,0xf0,0x80,0x03,0x74,0x09,0xf0,0x90,0x05,0x22,0xe4,0xf0, +0x22,0x90,0x91,0x80,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe5,0x70,0x14,0x24,0xfd, +0x50,0x02,0x80,0x21,0x90,0x91,0x3b,0xe0,0x60,0x06,0x7d,0x01,0x7f,0x0c,0x80,0x0d, +0xe5,0x6e,0x54,0x0f,0xc3,0x94,0x04,0x50,0x07,0x7d,0x01,0x7f,0x04,0x12,0x47,0x27, +0xe4,0xff,0x12,0x48,0xb3,0x22,0x90,0x91,0x08,0xe0,0x54,0xf0,0x44,0x03,0xf0,0x54, +0x0f,0x44,0x80,0xf0,0x7b,0x00,0x7a,0x00,0x79,0x58,0x90,0x91,0x71,0x12,0x43,0x41, +0x0b,0x7a,0x91,0x79,0x08,0x02,0x46,0xb7,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0,0x90, +0x91,0x84,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0x90,0x91,0x84,0xe0, +0xfe,0xa3,0xe0,0xf5,0x82,0x8e,0x83,0xe0,0x60,0x2d,0xc3,0x90,0x91,0x87,0xe0,0x94, +0xe8,0x90,0x91,0x86,0xe0,0x94,0x03,0x40,0x0b,0x90,0x01,0xc6,0xe0,0x44,0x10,0xf0, +0x7f,0x00,0x80,0x15,0x90,0x91,0x86,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x7f,0x0a, +0x7e,0x00,0x12,0x37,0x54,0x80,0xc5,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0xd3,0x10, +0xaf,0x01,0xc3,0xc0,0xd0,0x90,0x91,0x1c,0x12,0x43,0x41,0x90,0x91,0x1f,0x12,0x2a, +0x8b,0x00,0x00,0x00,0x00,0x90,0x91,0x1c,0x12,0x43,0x21,0x90,0x00,0x01,0x12,0x42, +0x20,0x90,0x91,0x3b,0xf0,0x90,0x00,0x03,0x12,0x42,0x20,0x90,0x91,0x25,0xf0,0x90, +0x00,0x04,0x12,0x42,0x20,0xff,0x54,0x01,0x90,0x91,0x26,0xf0,0xef,0xc3,0x13,0x54, +0x01,0x90,0x91,0x2e,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff,0x13,0x13,0x54,0x01, +0x90,0x91,0x2c,0xf0,0x90,0x91,0x2e,0xe0,0x90,0x91,0x1f,0x70,0x26,0x12,0x2a,0x8b, +0x00,0x00,0x02,0x10,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x60,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x91,0x1f,0x12,0x2a,0x8b,0x00,0x00,0x03, +0x10,0x80,0x24,0x12,0x2a,0x8b,0x00,0x00,0x01,0x10,0x90,0x91,0x1f,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x60,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x91,0x1f, +0x12,0x2a,0x8b,0x00,0x00,0x03,0x00,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x91,0x26,0xe0,0x70,0x3d, +0x90,0x91,0x38,0x74,0x01,0xf0,0x7f,0x00,0x7e,0x08,0x12,0x27,0xde,0x90,0x91,0x1f, +0x12,0x2a,0x7f,0x90,0x91,0x1f,0x12,0x43,0x09,0xec,0x44,0x02,0xfc,0x90,0x91,0x1f, +0x12,0x2a,0x7f,0x90,0x91,0x1f,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x00,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x02,0x86,0xe0,0x54,0xfb,0xf0,0x90,0x91,0x1c, +0x12,0x43,0x21,0x12,0x49,0x80,0x90,0x01,0xe5,0xe5,0x70,0xf0,0x90,0x91,0x3b,0xe0, +0x90,0x01,0xe6,0xf0,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x00,0x02,0x12,0x42,0x20,0xff, +0x30,0xe0,0x25,0x12,0x29,0xd9,0x90,0x91,0x2f,0xf0,0x90,0x00,0x01,0x12,0x42,0x20, +0x90,0x91,0x30,0xf0,0xef,0xc3,0x13,0x54,0x7f,0x90,0x91,0x2d,0xf0,0x90,0x00,0x03, +0x12,0x42,0x20,0x90,0x91,0x35,0xf0,0x22,0x90,0x91,0x2f,0x74,0x0a,0xf0,0x90,0x91, +0x30,0x74,0x05,0xf0,0x90,0x91,0x2d,0x74,0x14,0xf0,0x90,0x91,0x35,0x74,0x05,0xf0, +0x22,0x90,0x02,0x09,0xe0,0xfd,0x12,0x29,0xd9,0xfe,0xaf,0x05,0xed,0x2e,0x90,0x91, +0x41,0xf0,0x90,0x00,0x01,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x42,0xf0,0x90, +0x00,0x02,0x12,0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x43,0xf0,0x90,0x00,0x03,0x12, +0x42,0x20,0xff,0xed,0x2f,0x90,0x91,0x44,0xf0,0x90,0x00,0x04,0x12,0x42,0x20,0xff, +0xae,0x05,0xed,0x2f,0x90,0x91,0x45,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0x47,0xe0,0x90,0x91,0x1d,0xf0,0x90,0x91,0x48,0xe0,0xf5,0x19,0xa3,0xe0, +0xf5,0x1a,0xe4,0xf5,0x16,0x74,0x4a,0x25,0x16,0xf5,0x82,0xe4,0x34,0x91,0xf5,0x83, +0xe0,0xff,0x74,0x1b,0x25,0x16,0xf8,0xa6,0x07,0x05,0x16,0xe5,0x16,0xb4,0x04,0xe5, +0x90,0x91,0x1d,0xe0,0x12,0x43,0x4a,0x66,0xe6,0x00,0x68,0x13,0x01,0x66,0xee,0x02, +0x66,0xee,0x03,0x66,0xee,0x04,0x68,0x13,0x05,0x67,0xe3,0x80,0x67,0xf9,0x81,0x68, +0x13,0x82,0x00,0x00,0x68,0x0f,0xaf,0x1e,0x12,0x73,0xdd,0x02,0x68,0x13,0x90,0x91, +0x1d,0xe0,0xff,0xb4,0x02,0x08,0x90,0x91,0x1c,0x74,0x01,0xf0,0x80,0x0f,0xef,0x90, +0x91,0x1c,0xb4,0x03,0x05,0x74,0x02,0xf0,0x80,0x03,0x74,0x04,0xf0,0xc3,0xe5,0x19, +0x94,0x08,0x50,0x4a,0xe4,0xf5,0x16,0x90,0x91,0x1c,0xe0,0xff,0xe5,0x16,0xc3,0x9f, +0x40,0x03,0x02,0x68,0x13,0xc3,0xe5,0x19,0x94,0x01,0x50,0x14,0xe5,0x16,0x25,0x1a, +0xff,0xc3,0x74,0x03,0x95,0x16,0x24,0x1b,0xf8,0xe6,0xfd,0x12,0x4d,0xa8,0x80,0x1a, +0xc3,0x74,0x03,0x95,0x16,0x24,0x1b,0xf8,0xe6,0xff,0xe5,0x16,0x7c,0x00,0x25,0x1a, +0xfd,0xec,0x35,0x19,0x8d,0x82,0xf5,0x83,0xef,0xf0,0x05,0x16,0x80,0xb9,0xc3,0xe5, +0x19,0x94,0x10,0x40,0x03,0x02,0x68,0x13,0x90,0x91,0x1d,0xe0,0x64,0x04,0x60,0x03, +0x02,0x68,0x13,0xaf,0x1c,0xfc,0xfd,0xfe,0x78,0x10,0x12,0x2a,0x6c,0xc0,0x04,0xc0, +0x05,0xc0,0x06,0xc0,0x07,0xaf,0x1b,0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x2a,0x6c, +0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x42,0xfc,0xc0,0x04,0xc0,0x05,0xc0, +0x06,0xc0,0x07,0xaf,0x1d,0xe4,0xfc,0xfd,0xfe,0x78,0x08,0x12,0x2a,0x6c,0xd0,0x03, +0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x42,0xfc,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab, +0x07,0xaf,0x1e,0xe4,0xfc,0xfd,0xfe,0x12,0x42,0xfc,0xa3,0x12,0x2a,0x7f,0x90,0x91, +0x1e,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0xaf,0x1a,0xae,0x19,0x12,0x2f, +0xd9,0x80,0x30,0xe5,0x1d,0x7f,0x00,0xfe,0xef,0x25,0x1e,0xf5,0x18,0xe4,0x3e,0xf5, +0x17,0xaf,0x18,0xfe,0x12,0x37,0x54,0x80,0x1a,0xe5,0x1d,0x7f,0x00,0xfe,0xef,0x25, +0x1e,0xf5,0x18,0xe4,0x3e,0xf5,0x17,0xaf,0x18,0xfe,0x12,0x36,0xcb,0x80,0x04,0x7f, +0x00,0x80,0x02,0x7f,0x01,0xd0,0xd0,0x92,0xaf,0x22,0x8e,0x0e,0x8f,0x0f,0x8b,0x10, +0x8a,0x11,0x89,0x12,0xe4,0x90,0x91,0x11,0xf0,0xef,0x90,0x00,0x31,0xf0,0x12,0x4c, +0xa0,0xe5,0x0e,0x54,0x03,0xff,0x90,0x00,0x32,0xe0,0x54,0xfc,0x4f,0xf0,0x12,0x4c, +0xa0,0x90,0x00,0x33,0xe0,0x54,0x7f,0xf0,0x12,0x4c,0xa0,0x90,0x00,0x33,0xe0,0x20, +0xe7,0x0e,0x90,0x91,0x11,0xe0,0xc3,0x94,0x64,0x50,0x05,0xe0,0x04,0xf0,0x80,0xeb, +0x90,0x91,0x11,0xe0,0xc3,0x94,0x64,0x50,0x10,0x90,0x00,0x30,0xe0,0xab,0x10,0xaa, +0x11,0xa9,0x12,0x12,0x42,0x4d,0x7f,0x01,0x22,0x7f,0x00,0x22,0xe4,0x90,0x91,0x98, +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,0x91,0x99,0xe0,0x94,0xe8,0x90, +0x91,0x98,0xe0,0x94,0x03,0x40,0x03,0x7f,0x00,0x22,0x7f,0x32,0x7e,0x00,0x12,0x37, +0x54,0x90,0x91,0x98,0xe4,0x75,0xf0,0x01,0x12,0x42,0x81,0x80,0xc6,0x7f,0x78,0x7e, +0x08,0x12,0x27,0xde,0x90,0x90,0xd8,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27, +0xde,0x90,0x90,0xdc,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x27,0xde,0x90,0x90, +0xe0,0x12,0x2a,0x7f,0x90,0x91,0x51,0xe0,0x90,0x90,0xd8,0xb4,0x01,0x0d,0x12,0x43, +0x09,0xef,0x54,0xc7,0xff,0xed,0x54,0xc7,0xfd,0x80,0x07,0x12,0x43,0x09,0xef,0x54, +0xc7,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x08,0x12,0x2f,0xd9, +0x90,0x90,0xdc,0x12,0x43,0x09,0xef,0x54,0x0f,0xff,0xec,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90,0xe0,0x12,0x43,0x09,0xef,0x44, +0x02,0xff,0xec,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x00,0x7e,0x08,0x12,0x2f,0xd9, +0x7f,0x70,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xe4,0x12,0x2a,0x7f,0x90,0x80,0x85, +0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa0,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80, +0x59,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4,0xfd,0xff,0x12,0x34,0x81,0x90,0x91, +0x51,0xe0,0xb4,0x01,0x11,0x90,0x80,0x59,0x12,0x2a,0x8b,0x00,0x00,0x00,0x00,0xe4, +0xfd,0x7f,0x01,0x12,0x34,0x81,0x22,0xef,0x70,0x02,0x61,0x3d,0x90,0x90,0xe8,0xe0, +0x60,0x02,0xe1,0x08,0x90,0x90,0xd4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x80,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x84,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0x88, +0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x90,0x8c,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x90,0x90,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x94,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x98,0x12,0x43,0x09,0x90, +0x80,0x85,0x12,0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0x9c,0x12, +0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x90,0xa0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x90,0xa4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x88, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xa8,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a, +0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xac,0x12,0x43,0x09,0x90,0x80, +0x85,0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xb0,0x12,0x43, +0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd4,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90, +0xb4,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xd8,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x90,0xb8,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0xdc,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x90,0xbc,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xc0,0x12,0x43,0x09,0x90,0x80,0x85, +0x12,0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x90,0xc4,0x12,0x43,0x09, +0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x90,0x90,0xc8, +0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9, +0x90,0x90,0xcc,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09, +0x12,0x2f,0xd9,0x90,0x90,0xd0,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x04,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x90,0xe8,0x74,0x01,0xf0,0x22,0x90,0x90,0xe8, +0xe0,0x64,0x01,0x60,0x02,0xe1,0x08,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x90, +0xd4,0x12,0x2a,0x7f,0x7f,0x44,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0x80,0x12,0x2a, +0x7f,0x7f,0x5c,0x7e,0x08,0x12,0x27,0xde,0x90,0x90,0x84,0x12,0x2a,0x7f,0x7f,0x6c, +0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x88,0x12,0x2a,0x7f,0x7f,0x70,0x7e,0x0e,0x12, +0x27,0xde,0x90,0x90,0x8c,0x12,0x2a,0x7f,0x7f,0x74,0x7e,0x0e,0x12,0x27,0xde,0x90, +0x90,0x90,0x12,0x2a,0x7f,0x7f,0x78,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x94,0x12, +0x2a,0x7f,0x7f,0x7c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x98,0x12,0x2a,0x7f,0x7f, +0x80,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0x9c,0x12,0x2a,0x7f,0x7f,0x84,0x7e,0x0e, +0x12,0x27,0xde,0x90,0x90,0xa0,0x12,0x2a,0x7f,0x7f,0x88,0x7e,0x0e,0x12,0x27,0xde, +0x90,0x90,0xa4,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xa8, +0x12,0x2a,0x7f,0x7f,0xd0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xac,0x12,0x2a,0x7f, +0x7f,0xd4,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xb0,0x12,0x2a,0x7f,0x7f,0xd8,0x7e, +0x0e,0x12,0x27,0xde,0x90,0x90,0xb4,0x12,0x2a,0x7f,0x7f,0xdc,0x7e,0x0e,0x12,0x27, +0xde,0x90,0x90,0xb8,0x12,0x2a,0x7f,0x7f,0xe0,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90, +0xbc,0x12,0x2a,0x7f,0x7f,0xec,0x7e,0x0e,0x12,0x27,0xde,0x90,0x90,0xc0,0x12,0x2a, +0x7f,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x90,0xc4,0x12,0x2a,0x7f,0x7f,0x04, +0x7e,0x0d,0x12,0x27,0xde,0x90,0x90,0xc8,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12, +0x27,0xde,0x90,0x90,0xcc,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90, +0x90,0xd0,0x12,0x2a,0x7f,0x7f,0x8c,0x7e,0x08,0x12,0x27,0xde,0x90,0x91,0x88,0x12, +0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x44,0xc0,0xfd,0xec,0x90,0x91,0x88, +0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f, +0x8c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x01,0x00,0x00, +0x7f,0x44,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0xdb,0x25, +0xa4,0x7f,0x5c,0x7e,0x08,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb, +0x25,0xa4,0x7f,0x6c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20, +0xdb,0x25,0xa4,0x7f,0x70,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b, +0x04,0x1b,0x25,0xa4,0x7f,0x74,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a, +0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x78,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12, +0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x7c,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85, +0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x80,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80, +0x85,0x12,0x2a,0x8b,0x63,0xdb,0x25,0xa4,0x7f,0x84,0x7e,0x0e,0x12,0x2f,0xd9,0x90, +0x80,0x85,0x12,0x2a,0x8b,0x04,0x1b,0x25,0xa4,0x7f,0x88,0x7e,0x0e,0x12,0x2f,0xd9, +0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0x8c,0x7e,0x0e,0x12,0x2f, +0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd0,0x7e,0x0e,0x12, +0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd4,0x7e,0x0e, +0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x20,0xdb,0x25,0xa4,0x7f,0xd8,0x7e, +0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f,0xdc, +0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x00,0x1b,0x25,0xa4,0x7f, +0xe0,0x7e,0x0e,0x12,0x2f,0xd9,0x90,0x80,0x85,0x12,0x2a,0x8b,0x24,0xdb,0x25,0xa4, +0x7f,0xec,0x7e,0x0e,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0c,0x12,0x27,0xde,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90,0x91,0x88, +0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f, +0x7f,0x04,0x7e,0x0c,0x12,0x2f,0xd9,0x7f,0x04,0x7e,0x0d,0x12,0x27,0xde,0x90,0x91, +0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90, +0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x04,0x7e,0x0d,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xe4,0xff,0xec,0x90, +0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x11,0xff,0xec, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12, +0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f,0xd9,0x7f,0x0c,0x7e,0x09,0x12,0x27,0xde, +0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09,0xed,0x54,0x0f,0xfd, +0xec,0x54,0xf0,0xfc,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91,0x88,0x12,0x43,0x09, +0xed,0x44,0x10,0xfd,0xec,0x44,0x01,0xfc,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91, +0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x0c,0x7e,0x09,0x12,0x2f, +0xd9,0x7f,0x04,0x7e,0x08,0x12,0x27,0xde,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90,0x91, +0x88,0x12,0x43,0x09,0xef,0x54,0xf0,0xff,0xec,0x90,0x91,0x88,0x12,0x2a,0x7f,0x90, +0x91,0x88,0x12,0x43,0x09,0xef,0x44,0x01,0xff,0xec,0x90,0x91,0x88,0x12,0x2a,0x7f, +0x90,0x91,0x88,0x12,0x43,0x09,0x90,0x80,0x85,0x12,0x2a,0x7f,0x7f,0x04,0x7e,0x08, +0x12,0x2f,0xd9,0xe4,0x90,0x90,0xe8,0xf0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0,0xd0, +0x90,0x91,0xa0,0xef,0xf0,0xd3,0x94,0x07,0x50,0x47,0xe0,0xff,0x74,0x01,0xa8,0x07, +0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0xf4,0xff,0x90,0x00,0x46,0xe0,0x5f,0xf0,0x12, +0x4c,0xa0,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e,0x00,0xa8,0x05,0x08,0x80,0x05, +0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00,0x44,0xe0,0xfb,0xe4,0xfe,0xef, +0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xff,0x80, +0x44,0x90,0x91,0xa0,0xe0,0x24,0xf8,0xf0,0xe0,0xff,0x74,0x01,0xa8,0x07,0x08,0x80, +0x02,0xc3,0x33,0xd8,0xfc,0x12,0x4c,0x98,0x90,0x91,0xa0,0xe0,0xfd,0x74,0x01,0x7e, +0x00,0xa8,0x05,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x00, +0x42,0xe0,0xfb,0xe4,0xfe,0xef,0x5b,0xa8,0x05,0x08,0x80,0x06,0xce,0xa2,0xe7,0x13, +0xce,0x13,0xd8,0xf8,0xff,0xd0,0xd0,0x92,0xaf,0x22,0xe4,0xfd,0x7f,0x45,0x12,0x4d, +0xa8,0x90,0x04,0xfd,0xe4,0xf0,0xa3,0xf0,0x90,0x90,0xf7,0xf0,0x90,0x90,0xfd,0xf0, +0x90,0x91,0x00,0xf0,0x90,0x90,0xfe,0xf0,0x90,0x91,0x01,0xf0,0x90,0x90,0xff,0xf0, +0x90,0x91,0x02,0xf0,0x90,0x90,0xe9,0x04,0xf0,0xe4,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0, +0x90,0x90,0xee,0xf0,0x90,0x90,0xf3,0xf0,0x90,0x90,0xf5,0xf0,0x90,0x91,0x07,0xf0, +0x90,0x90,0xf8,0xf0,0x90,0x90,0xf4,0xf0,0x90,0x90,0xed,0xf0,0x90,0x00,0x51,0xe0, +0x44,0xc0,0xfd,0x7f,0x51,0x02,0x4d,0xa8,0x90,0x91,0x07,0xe0,0x64,0x01,0x60,0x08, +0x90,0x90,0xf5,0xe0,0x60,0x02,0x01,0xdf,0x90,0x90,0xe9,0xe0,0xc3,0x94,0xff,0x50, +0x05,0xe0,0x04,0xf0,0x80,0x3b,0x90,0x90,0xea,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0, +0x04,0xf0,0xe4,0x80,0x28,0x90,0x90,0xeb,0xe0,0xc3,0x94,0xff,0x50,0x0a,0xe0,0x04, +0xf0,0xe4,0x90,0x90,0xea,0xf0,0x80,0x15,0x90,0x90,0xec,0xe0,0xc3,0x94,0xff,0x50, +0x10,0xe0,0x04,0xf0,0xe4,0x90,0x90,0xeb,0xf0,0x90,0x90,0xea,0xf0,0x90,0x90,0xe9, +0xf0,0x90,0x00,0x44,0xe0,0x54,0x0c,0x60,0x76,0xe0,0x30,0xe2,0x32,0x90,0x90,0xfd, +0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0,0x04,0xf0,0x80,0x24,0x90,0x90,0xfe,0xe0,0xc3, +0x94,0xff,0x50,0x06,0xe0,0x04,0xf0,0xe4,0x80,0x11,0x90,0x90,0xff,0xe0,0xc3,0x94, +0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4,0x90,0x90,0xfe,0xf0,0x90,0x90,0xfd,0xf0,0x90, +0x00,0x44,0xe0,0x30,0xe3,0x32,0x90,0x91,0x00,0xe0,0xc3,0x94,0xff,0x50,0x05,0xe0, +0x04,0xf0,0x80,0x24,0x90,0x91,0x01,0xe0,0xc3,0x94,0xff,0x50,0x06,0xe0,0x04,0xf0, +0xe4,0x80,0x11,0x90,0x91,0x02,0xe0,0xc3,0x94,0xff,0x50,0x0c,0xe0,0x04,0xf0,0xe4, +0x90,0x91,0x01,0xf0,0x90,0x91,0x00,0xf0,0x90,0x04,0xfd,0xe0,0x44,0x01,0xf0,0x22, +0xe5,0x6e,0x30,0xe3,0x04,0xe4,0xff,0x80,0x02,0x7f,0x01,0x02,0x47,0xc9,0x90,0x91, +0x53,0xe0,0x30,0xe0,0x49,0xe5,0x6d,0x64,0x01,0x70,0x43,0x90,0x91,0x52,0xe0,0x04, +0xf0,0xe5,0x70,0x64,0x03,0x60,0x05,0xe5,0x70,0xb4,0x06,0x0d,0x90,0x91,0x52,0xe0, +0xff,0x74,0x01,0xd3,0x9f,0x50,0x14,0x80,0x07,0x90,0x91,0x52,0xe0,0xb4,0x0a,0x0b, +0x90,0x91,0x55,0xe0,0x04,0xf0,0xe4,0x90,0x91,0x52,0xf0,0x90,0x91,0x55,0xe0,0xff, +0x90,0x91,0x54,0xe0,0xb5,0x07,0x07,0x11,0xe0,0xe4,0x90,0x91,0x55,0xf0,0x22,0x90, +0x06,0x90,0xe0,0x44,0x01,0xf0,0x90,0x91,0x61,0xe0,0x30,0xe0,0x3c,0x90,0x91,0x5f, +0xe0,0xff,0x90,0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x54,0x01,0xfd,0x12,0x4c,0xb0,0x90, +0x91,0x60,0xe0,0x75,0xf0,0x20,0xa4,0xff,0xae,0xf0,0x12,0x37,0x54,0x90,0x91,0x5e, +0xe0,0xc4,0x13,0x54,0x07,0x30,0xe0,0x07,0xa3,0xe0,0xff,0xe4,0xfd,0x80,0x07,0x90, +0x91,0x5f,0xe0,0xff,0x7d,0x01,0x12,0x4c,0xb0,0x22,0xd3,0x10,0xaf,0x01,0xc3,0xc0, +0xd0,0xe4,0x90,0x91,0x19,0xf0,0xa3,0x74,0x08,0xf0,0xa3,0xf0,0xe4,0xa3,0xf0,0x90, +0x01,0x1f,0xe0,0xfe,0x90,0x01,0x1e,0xe0,0x7c,0x00,0x24,0x00,0xff,0xec,0x3e,0x90, +0x91,0x11,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x87,0xe0,0x90,0x91,0x18,0xf0,0x90,0x91, +0x56,0xe0,0x20,0xe0,0x02,0x61,0xb7,0xe4,0x90,0x91,0x17,0xf0,0x90,0x91,0x18,0xe0, +0xff,0x90,0x91,0x17,0xe0,0xc3,0x9f,0x40,0x02,0x61,0xb7,0x90,0x91,0x11,0xe0,0xfc, +0xa3,0xe0,0xfd,0xec,0xff,0x90,0xfd,0x11,0xf0,0x90,0x91,0x1c,0xef,0xf0,0x74,0x02, +0x2d,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x54,0x0f,0xfc,0x33,0x33,0x33,0x54, +0xf8,0xff,0xed,0x24,0x18,0x2f,0x90,0x91,0x15,0xf0,0xe0,0x24,0x00,0xf5,0x82,0xe4, +0x34,0xfb,0xf5,0x83,0xe0,0x54,0xfc,0x90,0x91,0x16,0xf0,0x74,0x01,0x2d,0xf5,0x82, +0xe4,0x34,0xfb,0xf5,0x83,0xe0,0xfe,0x74,0x00,0x2d,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x7a,0x00,0x24,0x00,0xff,0xea,0x3e,0x54,0x3f,0xab,0x07,0xfa,0x90,0x91, +0x13,0xf0,0xa3,0xeb,0xf0,0xaf,0x04,0xef,0x75,0xf0,0x08,0xa4,0x24,0x18,0xff,0xe4, +0x35,0xf0,0xfe,0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x91,0x5a,0xe0,0xfe,0xa3,0xe0, +0xff,0xad,0x03,0xac,0x02,0x12,0x45,0x09,0xaa,0x06,0xab,0x07,0x90,0x91,0x15,0xe0, +0x24,0x00,0xf5,0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x30,0xe7,0x08,0x90,0x91,0x19, +0x74,0x02,0xf0,0x80,0x05,0xe4,0x90,0x91,0x19,0xf0,0xaf,0x03,0x90,0x91,0x11,0xea, +0x8f,0xf0,0x12,0x42,0x81,0x90,0x91,0x5c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x91,0x11, +0xe0,0xfc,0xa3,0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x1b,0x90,0x91,0x5d,0xe0,0x24, +0x01,0xff,0x90,0x91,0x5c,0xe0,0x34,0x00,0xfe,0xc3,0xed,0x9f,0xff,0xec,0x9e,0x90, +0x91,0x11,0xf0,0xa3,0xef,0xf0,0x90,0x91,0x16,0xe0,0xff,0x24,0x40,0x60,0x04,0x24, +0x20,0x70,0x27,0x90,0x91,0x5e,0xe0,0xfe,0xc4,0x13,0x13,0x13,0x54,0x01,0x20,0xe0, +0x02,0x61,0x8f,0xef,0x90,0x00,0x81,0xb4,0xa0,0x05,0xe0,0x44,0x04,0x80,0x03,0xe0, +0x44,0x08,0xfd,0x7f,0x81,0x12,0x4d,0xa8,0x61,0x88,0x90,0x91,0x5e,0xe0,0xc4,0x13, +0x13,0x54,0x03,0x20,0xe0,0x02,0x61,0x8f,0x90,0x91,0x15,0xe0,0xff,0x24,0x00,0xf5, +0x82,0xe4,0x34,0xfb,0xf5,0x83,0xe0,0x54,0x0c,0x64,0x08,0x70,0x72,0x90,0x91,0x19, +0xe0,0xfe,0xef,0x2e,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x1e,0xf5,0x82,0xe4,0x34,0xfb, +0xf5,0x83,0xe0,0x64,0x88,0x70,0x58,0x74,0x1f,0x2f,0xf5,0x82,0xe4,0x34,0xfb,0xf5, +0x83,0xe0,0x64,0x8e,0x70,0x49,0x90,0x91,0x19,0xe0,0xff,0x90,0x91,0x15,0xe0,0x2f, +0xff,0x90,0x91,0x1a,0xe0,0x2f,0xff,0xa3,0xe0,0x2f,0xff,0x24,0x19,0xf5,0x82,0xe4, +0x34,0xfb,0xf5,0x83,0xe0,0x64,0x03,0x70,0x26,0x74,0x1e,0x2f,0xf5,0x82,0xe4,0x34, +0xfb,0xf5,0x83,0xe0,0x90,0x00,0x81,0x30,0xe3,0x05,0xe0,0x44,0x01,0x80,0x03,0xe0, +0x44,0x02,0xfd,0x7f,0x81,0x12,0x4d,0xa8,0x90,0x91,0x56,0xe0,0x44,0x80,0xf0,0x90, +0x91,0x56,0xe0,0xff,0xc4,0x13,0x13,0x13,0x54,0x01,0x30,0xe0,0x02,0x31,0x3f,0x71, +0xbc,0xbf,0x01,0x13,0x90,0x91,0x11,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x44,0xb5,0x90, +0x91,0x17,0xe0,0x04,0xf0,0x21,0xcc,0xd0,0xd0,0x92,0xaf,0x22,0x90,0x91,0x56,0xe0, +0xc4,0x13,0x13,0x13,0x54,0x01,0x30,0xe0,0x11,0xe0,0x44,0x80,0xf0,0x90,0x91,0x5e, +0xe0,0xc4,0x54,0x0f,0x20,0xe0,0x03,0x7f,0x00,0x22,0x7f,0x01,0x22,0x8f,0x1f,0xe4, +0x90,0x91,0x22,0xf0,0xe5,0x1f,0x14,0xfe,0x90,0x91,0x22,0xe0,0xff,0xc3,0x9e,0x50, +0x0e,0xef,0x04,0xfd,0x12,0x34,0xb7,0x90,0x91,0x22,0xe0,0x04,0xf0,0x80,0xe5,0xe5, +0x1f,0x14,0xff,0x7d,0xff,0x12,0x34,0xb7,0x90,0x91,0x22,0xe5,0x1f,0xf0,0x90,0x91, +0x22,0xe0,0xc3,0x94,0xff,0x50,0x0f,0xe0,0xff,0x04,0xfd,0x12,0x34,0xb7,0x90,0x91, +0x22,0xe0,0x04,0xf0,0x80,0xe8,0xad,0x1f,0x7f,0xff,0x02,0x34,0xb7,0xc3,0xee,0x94, +0x01,0x40,0x0a,0x0d,0xed,0x13,0x90,0xfd,0x10,0xf0,0xe4,0x2f,0xff,0x22,0xc3,0xee, +0x94,0x01,0x40,0x1e,0x90,0xfd,0x11,0xe0,0xb5,0x05,0x14,0x90,0x01,0x17,0xe0,0xb5, +0x05,0x07,0x90,0xfd,0x11,0xe4,0xf0,0x80,0x06,0xed,0x04,0x90,0xfd,0x11,0xf0,0xe4, +0x2f,0xff,0x22,0x00,0x18,0x58,}; + + + + + + + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c new file mode 100755 index 00000000..0d7af4aa --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c @@ -0,0 +1,2675 @@ +/****************************************************************************** + * + * 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 "drv_types.h" +#include "rtl8192c_hal.h" + +//================================================================================ +// Constant. +//================================================================================ + +// +// Default LED behavior. +// +#define LED_BLINK_NORMAL_INTERVAL 100 +#define LED_BLINK_SLOWLY_INTERVAL 200 +#define LED_BLINK_LONG_INTERVAL 400 + +#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 +#define LED_BLINK_LINK_INTERVAL_ALPHA 500 //500 +#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 //150 +#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 +#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 + +//================================================================================ +// LED object. +//================================================================================ + + +//================================================================================ +// Prototype of protected function. +//================================================================================ + + +static void +BlinkTimerCallback( + unsigned long data + ); + +static void +BlinkWorkItemCallback( + struct work_struct *work + ); + +// +// Description: +// Reset blinking status of LED_871x object. +// +static void +ResetLedStatus(PLED_871x pLed) { + pLed->CurrLedState = RTW_LED_OFF; // Current LED state. + pLed->bLedOn = _FALSE; // true if LED is ON, false if LED is OFF. + + pLed->bLedBlinkInProgress = _FALSE; // true if it is blinking, false o.w.. + pLed->bLedNoLinkBlinkInProgress = _FALSE; + pLed->bLedLinkBlinkInProgress = _FALSE; + pLed->bLedStartToLinkBlinkInProgress = _FALSE; + pLed->bLedScanBlinkInProgress = _FALSE; + pLed->bLedWPSBlinkInProgress = _FALSE; + pLed->BlinkTimes = 0; // Number of times to toggle led state for blinking. + pLed->BlinkingLedState = LED_UNKNOWN; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. +} + +//================================================================================ +// LED_819xUsb routines. +//================================================================================ + +// +// Description: +// Initialize an LED_871x object. +// +static void +InitLed871x( + _adapter *padapter, + PLED_871x pLed, + LED_PIN_871x LedPin + ) +{ + pLed->padapter = padapter; + pLed->LedPin = LedPin; + + ResetLedStatus(pLed); + + _init_timer(&(pLed->BlinkTimer), padapter->pnetdev, BlinkTimerCallback, pLed); + _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed); +} + + +// +// Description: +// DeInitialize an LED_871x object. +// +static void +DeInitLed871x( + PLED_871x pLed + ) +{ + //call _cancel_workitem_sync(&(pLed->BlinkWorkItem)) + //before _cancel_timer_ex(&(pLed->BlinkTimer)) to + //avoid led timer restarting when driver is removed + + _cancel_workitem_sync(&(pLed->BlinkWorkItem)); + + _cancel_timer_ex(&(pLed->BlinkTimer)); + + // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko. + ResetLedStatus(pLed); +} + +// +// Description: +// Turn on LED according to LedPin specified. +// +static void +SwLedOn( + _adapter *padapter, + PLED_871x pLed +) +{ + u8 LedCfg; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)) + { + return; + } + + if( (BOARD_MINICARD == pHalData->BoardType )|| + (BOARD_USB_SOLO == pHalData->BoardType)|| + (BOARD_USB_COMBO == pHalData->BoardType)) + { + LedCfg = rtw_read8(padapter, REG_LEDCFG2); + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + break; + + case LED_PIN_LED0: + rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0xf0)|BIT5|BIT6); // SW control led0 on. + break; + + case LED_PIN_LED1: + rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0x0f)|BIT5); // SW control led1 on. + break; + + default: + break; + + } + } + else + { + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + break; + + case LED_PIN_LED0: +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + if(pHalData->AntDivCfg) + { + LedCfg = rtw_read8(padapter, REG_LEDCFG2); + rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0xe0)|BIT7|BIT6|BIT5); // SW control led0 on. + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOn LED0 0x%x\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG2))); + } + else +#endif + { + LedCfg = rtw_read8(padapter, REG_LEDCFG0); + rtw_write8(padapter,REG_LEDCFG0, LedCfg&0x70); // SW control led0 on. + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOn LED0 0x%lx\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG0))); + } + break; + + case LED_PIN_LED1: + LedCfg = rtw_read8(padapter,(REG_LEDCFG1)); + rtw_write8(padapter,(REG_LEDCFG1), LedCfg&0x70); // SW control led1 on. + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOn LED1 0x%lx\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG0))); + + break; + + default: + break; + } + } + pLed->bLedOn = _TRUE; + +} + + +// +// Description: +// Turn off LED according to LedPin specified. +// +static void +SwLedOff( + _adapter *padapter, + PLED_871x pLed +) +{ + u8 LedCfg; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if((padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)) + { + goto exit; + } + + if( (BOARD_MINICARD == pHalData->BoardType )|| + (BOARD_USB_SOLO == pHalData->BoardType)|| + (BOARD_USB_COMBO == pHalData->BoardType)) + { + LedCfg = rtw_read8(padapter, REG_LEDCFG2);//0x4E + + switch(pLed->LedPin) + { + + case LED_PIN_GPIO0: + break; + + case LED_PIN_LED0: + if(BOARD_USB_COMBO == pHalData->BoardType) + { + LedCfg &= 0x90; // Set to software control. + rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3)); + LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG); + LedCfg &= 0xFE; + rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg); + } + else + { + LedCfg &= 0xf0; // Set to software control. + if(pHalData->bLedOpenDrain == _TRUE) // Open-drain arrangement for controlling the LED + rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT1|BIT5|BIT6)); + else + rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT5|BIT6)); + } + break; + + case LED_PIN_LED1: + LedCfg &= 0x0f; // Set to software control. + rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3)); + break; + + default: + break; + } + } + else + { + switch(pLed->LedPin) + { + case LED_PIN_GPIO0: + break; + + case LED_PIN_LED0: +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + if(pHalData->AntDivCfg) + { + LedCfg = rtw_read8(padapter, REG_LEDCFG2); + LedCfg &= 0xe0; // Set to software control. + rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT7|BIT6|BIT5)); + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOff LED0 0x%x\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG2))); + } + else +#endif + { + LedCfg = rtw_read8(padapter, REG_LEDCFG0); + LedCfg &= 0x70; // Set to software control. + rtw_write8(padapter, REG_LEDCFG0, (LedCfg|BIT3)); + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOff LED0 0x%lx\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG0))); + } + break; + + case LED_PIN_LED1: + LedCfg = rtw_read8(padapter, (REG_LEDCFG1)); + LedCfg &= 0x70; // Set to software control. + rtw_write8(padapter, (REG_LEDCFG1), (LedCfg|BIT3)); + //RT_TRACE(COMP_LED, DBG_LOUD, ("SwLedOff LED1 0x%lx\n", PlatformEFIORead4Byte(Adapter, REG_LEDCFG0))); + break; + + default: + break; + } + } + +exit: + pLed->bLedOn = _FALSE; + +} + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ + + +// +// Description: +// Implementation of LED blinking behavior. +// It toggle off LED and schedule corresponding timer if necessary. +// +static void +SwLedBlink( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + // Determine if we shall change LED state again. + pLed->BlinkTimes--; + switch(pLed->CurrLedState) + { + + case LED_BLINK_NORMAL: + if(pLed->BlinkTimes == 0) + { + bStopBlinking = _TRUE; + } + break; + + case LED_BLINK_StartToBlink: + if( check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) ) + { + bStopBlinking = _TRUE; + } + if( check_fwstate(pmlmepriv, _FW_LINKED) && + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ) + { + bStopBlinking = _TRUE; + } + else if(pLed->BlinkTimes == 0) + { + bStopBlinking = _TRUE; + } + break; + + case LED_BLINK_WPS: + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + break; + + + default: + bStopBlinking = _TRUE; + break; + + } + + if(bStopBlinking) + { + //if( padapter->pwrctrlpriv.cpwm >= PS_STATE_S2) + if(0) + { + SwLedOff(padapter, pLed); + } + else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (pLed->bLedOn == _FALSE)) + { + SwLedOn(padapter, pLed); + } + else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && pLed->bLedOn == _TRUE) + { + SwLedOff(padapter, pLed); + } + + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + // Assign LED state to toggle. + if( pLed->BlinkingLedState == RTW_LED_ON ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + // Schedule a timer to toggle LED state. + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_SLOWLY: + case LED_BLINK_StartToBlink: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + + case LED_BLINK_WPS: + { + if( pLed->BlinkingLedState == RTW_LED_ON ) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + else + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + break; + + default: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + } + } +} + + +static void +SwLedBlink1( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PLED_871x pLed1 = &(ledpriv->SwLed1); + u8 bStopBlinking = _FALSE; + + if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + + if(pHalData->EEPROMCustomerID == RT_CID_DEFAULT) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + if(!pLed1->bSWLedCtrl) + { + SwLedOn(padapter, pLed1); + pLed1->bSWLedCtrl = _TRUE; + } + else if(!pLed1->bLedOn) + SwLedOn(padapter, pLed1); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn on pLed1\n")); + } + else + { + if(!pLed1->bSWLedCtrl) + { + SwLedOff(padapter, pLed1); + pLed1->bSWLedCtrl = _TRUE; + } + else if(pLed1->bLedOn) + SwLedOff(padapter, pLed1); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn off pLed1\n")); + } + } + + + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + ResetLedStatus(pLed); + return; + } + + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_BLINK_NORMAL: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + break; + + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + break; + + case LED_BLINK_WPS_STOP: //WPS success + if(pLed->BlinkingLedState == RTW_LED_ON) + bStopBlinking = _FALSE; + else + bStopBlinking = _TRUE; + + if(bStopBlinking) + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + + pLed->bLedWPSBlinkInProgress = _FALSE; + } + else + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + } + break; + + default: + break; + } + +} + +static void +SwLedBlink2( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + default: + break; + } + +} + +static void +SwLedBlink3( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + if(pLed->CurrLedState != LED_BLINK_WPS_STOP) + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( !pLed->bLedOn ) + SwLedOn(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedOn ) + SwLedOff(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + + if( !pLed->bLedOn ) + SwLedOn(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedOn ) + SwLedOff(padapter, pLed); + + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + break; + + case LED_BLINK_WPS_STOP: //WPS success + if(pLed->BlinkingLedState == RTW_LED_ON) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + bStopBlinking = _FALSE; + } + else + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedWPSBlinkInProgress = _FALSE; + } + break; + + + default: + break; + } + +} + + +static void +SwLedBlink4( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PLED_871x pLed1 = &(ledpriv->SwLed1); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) + { + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed1); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_BLINK_StartToBlink: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _FALSE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = _FALSE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_BLINK_WPS_STOP: //WPS authentication fail + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_WPS_STOP_OVERLAP: //WPS session overlap + pLed->BlinkTimes--; + if(pLed->BlinkTimes == 0) + { + if(pLed->bLedOn) + { + pLed->BlinkTimes = 1; + } + else + { + bStopBlinking = _TRUE; + } + } + + if(bStopBlinking) + { + pLed->BlinkTimes = 10; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState)); + + +} + +static void +SwLedBlink5( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if(pLed->bLedOn) + SwLedOff(padapter, pLed); + } + else + { pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if(!pLed->bLedOn) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if(pLed->bLedOn) + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if(!pLed->bLedOn) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState)); + + +} + +static void +SwLedBlink6( + PLED_871x pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("<==== blink6\n")); +} + + +// +// Description: +// Callback function of LED BlinkTimer, +// it just schedules to corresponding BlinkWorkItem. +// +static void +BlinkTimerCallback( + unsigned long data + ) +{ + PLED_871x pLed = (PLED_871x)data; + _adapter *padapter = pLed->padapter; + + //DBG_871X("%s\n", __FUNCTION__); + + if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)) + { + //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped); + return; + } + +#ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD + rtw_led_blink_cmd(padapter, pLed); +#else + _set_workitem(&(pLed->BlinkWorkItem)); +#endif +} + +// +// Description: +// Handler function of LED Blinking. +// We dispatch acture LED blink action according to LedStrategy. +// +void BlinkHandler(PLED_871x pLed) +{ + struct led_priv *ledpriv = &(pLed->padapter->ledpriv); + _adapter *padapter = pLed->padapter; + + //DBG_871X("%s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)) + { + //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped); + return; + } + + switch(ledpriv->LedStrategy) + { + case SW_LED_MODE0: + SwLedBlink(pLed); + break; + + case SW_LED_MODE1: + SwLedBlink1(pLed); + break; + + case SW_LED_MODE2: + SwLedBlink2(pLed); + break; + + case SW_LED_MODE3: + SwLedBlink3(pLed); + break; + + case SW_LED_MODE4: + SwLedBlink4(pLed); + break; + + case SW_LED_MODE5: + SwLedBlink5(pLed); + break; + + case SW_LED_MODE6: + SwLedBlink6(pLed); + break; + + default: + //RT_TRACE(COMP_LED, DBG_LOUD, ("BlinkWorkItemCallback 0x%x \n", pHalData->LedStrategy)); + //SwLedBlink(pLed); + break; + } +} + +// +// Description: +// Callback function of LED BlinkWorkItem. +// We dispatch acture LED blink action according to LedStrategy. +// +static void BlinkWorkItemCallback(struct work_struct *work) +{ + PLED_871x pLed = container_of(work, LED_871x, BlinkWorkItem); + BlinkHandler(pLed); +} + + + +//================================================================================ +// Default LED behavior. +//================================================================================ + +// +// Description: +// Implement each led action for SW_LED_MODE0. +// This is default strategy. +// +static void +SwLedControlMode0( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + PLED_871x pLed = &(ledpriv->SwLed1); + + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_CTL_START_TO_LINK: + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_StartToBlink; + pLed->BlinkTimes = 24; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->CurrLedState = LED_BLINK_StartToBlink; + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress == _FALSE ) + { + SwLedOn(padapter, pLed); + } + break; + + case LED_CTL_NO_LINK: + pLed->CurrLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress == _FALSE ) + { + SwLedOff(padapter, pLed); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + if(pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + SwLedOff(padapter, pLed); + break; + + case LED_CTL_START_WPS: + if( pLed->bLedBlinkInProgress == _FALSE || pLed->CurrLedState == RTW_LED_ON) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_WPS; + pLed->BlinkTimes = 20; + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedBlinkInProgress) + { + pLed->CurrLedState = RTW_LED_OFF; + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + break; + + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); + +} + + //ALPHA, added by chiyoko, 20090106 +static void +SwLedControlMode1( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct led_priv *ledpriv = &(padapter->ledpriv); + PLED_871x pLed = &(ledpriv->SwLed0); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if( pLed->bLedNoLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + if( pLed->bLedLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + + case LED_CTL_STOP_WPS: + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + } + else + { + pLed->bLedWPSBlinkInProgress = _TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedNoLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + //Arcadyan/Sitecom , added by chiyoko, 20090216 +static void +SwLedControlMode2( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_871x pLed = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(pmlmepriv->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS: + pLed->bLedWPSBlinkInProgress = _FALSE; + if(padapter->pwrctrlpriv.rf_pwrstate != rf_on) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + pLed->bLedWPSBlinkInProgress = _FALSE; + if(padapter->pwrctrlpriv.rf_pwrstate != rf_on) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); +} + + //COREGA, added by chiyoko, 20090316 + static void + SwLedControlMode3( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_871x pLed = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(pmlmepriv->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + if(IS_LED_WPS_BLINKING(pLed)) + return; + + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + else + { + pLed->bLedWPSBlinkInProgress = _TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); +} + + + //Edimax-Belkin, added by chiyoko, 20090413 +static void +SwLedControlMode4( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_871x pLed = &(ledpriv->SwLed0); + PLED_871x pLed1 = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_START_TO_LINK: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + + if( pLed->bLedStartToLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedNoLinkBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + + pLed->bLedStartToLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_StartToBlink; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + } + break; + + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + //LED1 settings + if(LedAction == LED_CTL_LINK) + { + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + } + + if( pLed->bLedNoLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + } + break; + + case LED_CTL_STOP_WPS: //WPS connect success + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + break; + + case LED_CTL_STOP_WPS_FAIL: //WPS authentication fail + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + //LED1 settings + if(pLed1->bLedWPSBlinkInProgress) + _cancel_timer_ex(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = _TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = RTW_LED_OFF; + else + pLed1->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + + break; + + case LED_CTL_STOP_WPS_FAIL_OVERLAP: //WPS session overlap + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + //LED1 settings + if(pLed1->bLedWPSBlinkInProgress) + _cancel_timer_ex(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = _TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; + pLed1->BlinkTimes = 10; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = RTW_LED_OFF; + else + pLed1->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedNoLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedStartToLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedStartToLinkBlinkInProgress = _FALSE; + } + + if( pLed1->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed1->BlinkTimer)); + pLed1->bLedWPSBlinkInProgress = _FALSE; + } + + pLed1->BlinkingLedState = LED_UNKNOWN; + SwLedOff(padapter, pLed); + SwLedOff(padapter, pLed1); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + + + //Sercomm-Belkin, added by chiyoko, 20090415 +static void +SwLedControlMode5( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_871x pLed = &(ledpriv->SwLed0); + + if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_NO_LINK: + case LED_CTL_LINK: //solid blue + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK) + { + return; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + //WNC-Corega, added by chiyoko, 20090902 +static void +SwLedControlMode6( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_871x pLed0 = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + _cancel_timer_ex(&(pLed0->BlinkTimer)); + pLed0->CurrLedState = RTW_LED_ON; + pLed0->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed0->BlinkTimer), 0); + break; + + case LED_CTL_POWER_OFF: + SwLedOff(padapter, pLed0); + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("ledcontrol 6 Led %d\n", pLed0->CurrLedState)); +} + + +// +// Description: +// Dispatch LED action according to pHalData->LedStrategy. +// +static void +LedControl871x( + _adapter *padapter, + LED_CTL_MODE LedAction + ) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + + if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE) + ||(padapter->hw_init_completed == _FALSE) ) + { + return; + } + + + if( ledpriv->bRegUseLed == _FALSE) + return; + + //if (!priv->up) + // return; + + //if(priv->bInHctTest) + // return; + + if( (padapter->pwrctrlpriv.rf_pwrstate != rf_on && + padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) && + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || + LedAction == LED_CTL_SITE_SURVEY || + LedAction == LED_CTL_LINK || + LedAction == LED_CTL_NO_LINK || + LedAction == LED_CTL_POWER_ON) ) + { + return; + } + + switch(ledpriv->LedStrategy) + { + case SW_LED_MODE0: + //SwLedControlMode0(padapter, LedAction); + break; + + case SW_LED_MODE1: + SwLedControlMode1(padapter, LedAction); + break; + case SW_LED_MODE2: + SwLedControlMode2(padapter, LedAction); + break; + + case SW_LED_MODE3: + SwLedControlMode3(padapter, LedAction); + break; + + case SW_LED_MODE4: + SwLedControlMode4(padapter, LedAction); + break; + + case SW_LED_MODE5: + SwLedControlMode5(padapter, LedAction); + break; + + case SW_LED_MODE6: + SwLedControlMode6(padapter, LedAction); + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy,LedAction)); +} + +// +// Description: +// Initialize all LED_871x objects. +// +void +rtl8192cu_InitSwLeds( + _adapter *padapter + ) +{ + struct led_priv *pledpriv = &(padapter->ledpriv); + + pledpriv->LedControlHandler = LedControl871x; + + InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0); + + InitLed871x(padapter,&(pledpriv->SwLed1), LED_PIN_LED1); +} + + +// +// Description: +// DeInitialize all LED_819xUsb objects. +// +void +rtl8192cu_DeInitSwLeds( + _adapter *padapter + ) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + + DeInitLed871x( &(ledpriv->SwLed0) ); + DeInitLed871x( &(ledpriv->SwLed1) ); +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c new file mode 100755 index 00000000..1119cf81 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c @@ -0,0 +1,229 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8192CU_RECV_C_ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#include +#include + +#include + + +void rtl8192cu_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 rtl8192cu_init_recv_priv(_adapter *padapter) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + int i, res = _SUCCESS; + struct recv_buf *precvbuf; + +#ifdef CONFIG_RECV_THREAD_MODE + _rtw_init_sema(&precvpriv->recv_sema, 0);//will be removed + _rtw_init_sema(&precvpriv->terminate_recvthread_sema, 0);//will be removed +#endif + +#ifdef PLATFORM_LINUX + tasklet_init(&precvpriv->recv_tasklet, + (void(*)(unsigned long))rtl8192cu_recv_tasklet, + (unsigned long)padapter); +#endif + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE +#ifdef PLATFORM_LINUX + precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); + if(precvpriv->int_in_urb == NULL){ + DBG_8192C("alloc_urb for interrupt in endpoint fail !!!!\n"); + } +#endif + precvpriv->int_in_buf = rtw_zmalloc(sizeof(INTERRUPT_MSG_FORMAT_EX)); + if(precvpriv->int_in_buf == NULL){ + DBG_8192C("alloc_mem for interrupt in endpoint fail !!!!\n"); + } +#endif + + //init recv_buf + _rtw_init_queue(&precvpriv->free_recv_buf_queue); + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + _rtw_init_queue(&precvpriv->recv_buf_pending_queue); +#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX + + precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4); + if(precvpriv->pallocated_recv_buf==NULL){ + res= _FAIL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("alloc recv_buf fail!\n")); + goto exit; + } + _rtw_memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF *sizeof(struct recv_buf) + 4); + + precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4); + //precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 - + // ((uint) (precvpriv->pallocated_recv_buf) &(4-1)); + + + precvbuf = (struct recv_buf*)precvpriv->precv_buf; + + for(i=0; i < NR_RECVBUFF ; i++) + { + _rtw_init_listhead(&precvbuf->list); + + _rtw_spinlock_init(&precvbuf->recvbuf_lock); + + precvbuf->alloc_sz = MAX_RECVBUF_SZ; + + res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); + if(res==_FAIL) + break; + + precvbuf->ref_cnt = 0; + precvbuf->adapter =padapter; + + + //rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue)); + + precvbuf++; + + } + + precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; + +#ifdef PLATFORM_LINUX + + skb_queue_head_init(&precvpriv->rx_skb_queue); + +#ifdef CONFIG_PREALLOC_RECV_SKB + { + int i; + SIZE_PTR tmpaddr=0; + SIZE_PTR alignment=0; + struct sk_buff *pskb=NULL; + + skb_queue_head_init(&precvpriv->free_recv_skb_queue); + + for(i=0; idev = padapter->pnetdev; + + tmpaddr = (SIZE_PTR)pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); + skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); + + skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); + } + + pskb=NULL; + + } + } +#endif + +#endif + +exit: + + return res; + +} + +void rtl8192cu_free_recv_priv (_adapter *padapter) +{ + int i; + struct recv_buf *precvbuf; + struct recv_priv *precvpriv = &padapter->recvpriv; + + precvbuf = (struct recv_buf *)precvpriv->precv_buf; + + for(i=0; i < NR_RECVBUFF ; i++) + { + rtw_os_recvbuf_resource_free(padapter, precvbuf); + precvbuf++; + } + + if(precvpriv->pallocated_recv_buf) + rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF *sizeof(struct recv_buf) + 4); + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE +#ifdef PLATFORM_LINUX + if(precvpriv->int_in_urb) + { + usb_free_urb(precvpriv->int_in_urb); + } +#endif + if(precvpriv->int_in_buf) + rtw_mfree(precvpriv->int_in_buf, sizeof(INTERRUPT_MSG_FORMAT_EX)); +#endif + +#ifdef PLATFORM_LINUX + + if (skb_queue_len(&precvpriv->rx_skb_queue)) { + DBG_8192C(KERN_WARNING "rx_skb_queue not empty\n"); + } + + rtw_skb_queue_purge(&precvpriv->rx_skb_queue); + +#ifdef CONFIG_PREALLOC_RECV_SKB + + if (skb_queue_len(&precvpriv->free_recv_skb_queue)) { + DBG_8192C(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue)); + } + + rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue); + +#endif + +#endif + +} + + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c new file mode 100755 index 00000000..3a4137b9 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c @@ -0,0 +1,1150 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8192C_XMIT_C_ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) +#error "Shall be Linux or Windows, but not both!\n" +#endif + + +s32 rtl8192cu_init_xmit_priv(_adapter *padapter) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + +#ifdef PLATFORM_LINUX + tasklet_init(&pxmitpriv->xmit_tasklet, + (void(*)(unsigned long))rtl8192cu_xmit_tasklet, + (unsigned long)padapter); +#endif + return _SUCCESS; +} + +void rtl8192cu_free_xmit_priv(_adapter *padapter) +{ +} + +u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe) +{ + u32 addr; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + switch(pattrib->qsel) + { + case 0: + case 3: + addr = BE_QUEUE_INX; + break; + case 1: + case 2: + addr = BK_QUEUE_INX; + break; + case 4: + case 5: + addr = VI_QUEUE_INX; + break; + case 6: + case 7: + addr = VO_QUEUE_INX; + break; + case 0x10: + addr = BCN_QUEUE_INX; + break; + case 0x11://BC/MC in PS (HIQ) + addr = HIGH_QUEUE_INX; + break; + case 0x12: + addr = MGT_QUEUE_INX; + break; + default: + addr = BE_QUEUE_INX; + break; + + } + + return addr; + +} + +int urb_zero_packet_chk(_adapter *padapter, int sz) +{ + int blnSetTxDescOffset; + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + + if ( pdvobj->ishighspeed ) + { + if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) { + blnSetTxDescOffset = 1; + } else { + blnSetTxDescOffset = 0; + } + } + else + { + if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 ) { + blnSetTxDescOffset = 1; + } else { + blnSetTxDescOffset = 0; + } + } + + return blnSetTxDescOffset; + +} + +void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc) +{ + u16 *usPtr = (u16*)ptxdesc; + u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times + u32 index; + u16 checksum = 0; + + //Clear first + ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); + + for(index = 0 ; index < count ; index++){ + checksum = checksum ^ le16_to_cpu(*(usPtr + index)); + } + + ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum); + +} + +void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc) +{ + if ((pattrib->encrypt > 0) && !pattrib->bswenc) + { + switch (pattrib->encrypt) + { + //SEC_TYPE + case _WEP40_: + case _WEP104_: + ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000); + break; + case _TKIP_: + case _TKIP_WTMIC_: + //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000); + ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000); + break; + case _AES_: + ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000); + break; + case _NO_PRIVACY_: + default: + break; + + } + + } + +} + +static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw) +{ + //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode); + + switch(pattrib->vcs_mode) + { + case RTS_CTS: + *pdw |= cpu_to_le32(BIT(12)); + break; + case CTS_TO_SELF: + *pdw |= cpu_to_le32(BIT(11)); + break; + case NONE_VCS: + default: + break; + } + + if(pattrib->vcs_mode) { + *pdw |= cpu_to_le32(BIT(13)); + + // Set RTS BW + if(pattrib->ht_en) + { + *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(27)):0; + + if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + *pdw |= cpu_to_le32((0x01<<28)&0x30000000); + else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + *pdw |= cpu_to_le32((0x02<<28)&0x30000000); + else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) + *pdw |= 0; + else + *pdw |= cpu_to_le32((0x03<<28)&0x30000000); + } + } +} + +static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw) +{ + //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); + + if(pattrib->ht_en) + { + *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(25)):0; + + if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + *pdw |= cpu_to_le32((0x01<<20)&0x00300000); + else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + *pdw |= cpu_to_le32((0x02<<20)&0x00300000); + else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) + *pdw |= 0; + else + *pdw |= cpu_to_le32((0x03<<20)&0x00300000); + } +} + +static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) +{ + int pull=0; + uint qsel; + _adapter *padapter = pxmitframe->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct tx_desc *ptxdesc = (struct tx_desc *)pmem; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + sint bmcst = IS_MCAST(pattrib->ra); +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + +#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX + if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0)) + { + ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); + pull = 1; + pxmitframe->pkt_offset --; + } +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + + _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc)); + + if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) + { + //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n"); + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); + + qsel = (uint)(pattrib->qsel & 0x0000001f); + ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); + + ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); + + fill_txdesc_sectype(pattrib, ptxdesc); + + if(pattrib->ampdu_en==_TRUE) + ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN + else + ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK + + //offset 8 + + + //offset 12 + ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); + + + //offset 16 , offset 20 + if (pattrib->qos_en) + ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS + + if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1)) + { + //Non EAP & ARP & DHCP type data packet + + fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); + fill_txdesc_phy(pattrib, &ptxdesc->txdw4); + + ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M + ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);// + //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M + + //use REG_INIDATA_RATE_SEL value + ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]); + + if(0)//for driver dbg + { + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + + if(pattrib->ht_en) + ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI + + ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7 + } + + } + else + { + // EAP data packet and ARP packet. + // Use the 1M data rate to send the EAP/ARP packet. + // This will maybe make the handshake smooth. + + ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK + + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + + if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) + ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT + + ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); + } + + //offset 24 +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + if ( pattrib->hw_tcp_csum == 1 ) { + // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!! + u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8; + ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16); + DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7); + } +#endif + } + else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG) + { + //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n"); + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); + + qsel = (uint)(pattrib->qsel&0x0000001f); + ptxdesc->txdw1 |= cpu_to_le32((qsel<txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000); + + //fill_txdesc_sectype(pattrib, ptxdesc); + + //offset 8 +#ifdef CONFIG_XMIT_ACK + //CCX-TXRPT ack for xmit mgmt frames. + if (pxmitframe->ack_report) { + ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); + #ifdef DBG_CCX + DBG_871X("%s set ccx\n", __func__); + #endif + } +#endif //CONFIG_XMIT_ACK + + //offset 12 + ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); + + //offset 16 + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + + //offset 20 + ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable + if(pattrib->retry_ctrl == _TRUE) + { +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { +#ifdef CONFIG_INTEL_WIDI + if(padapter->mlmepriv.widi_enable == _TRUE) + ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6 + else +#endif //CONFIG_INTEL_WIDI + ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2 + } + else +#endif //CONFIG_P2P + ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6 + } + else + ptxdesc->txdw5 |= cpu_to_le32(0x00300000);//retry limit = 12 + +#ifdef CONFIG_INTEL_PROXIM + if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){ + printk("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate); + ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate); + } + else +#endif + { + ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); + } + } + else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) + { + DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); + } +#ifdef CONFIG_MP_INCLUDED + else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) + { + fill_txdesc_for_mp(padapter, ptxdesc); + } +#endif + else + { + DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID) + + ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid + + //offset 8 + + //offset 12 + ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); + + //offset 16 + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + + //offset 20 + ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate)); + } + + // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. + // (1) The sequence number of each non-Qos frame / broadcast / multicast / + // mgnt frame should be controled by Hw because Fw will also send null data + // which we cannot control when Fw LPS enable. + // --> default enable non-Qos data sequense number. 2010.06.23. by tynli. + // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. + // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. + // 2010.06.23. Added by tynli. + if(!pattrib->qos_en) + { + ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number + ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. + } + + //offset 0 + ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff); + ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); + ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<txdw0 |= cpu_to_le32(BIT(24)); + } + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0)); + + //offset 4 + // pkt_offset, unit:8 bytes padding + if (pxmitframe->pkt_offset > 0) + ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); + +#ifdef CONFIG_USB_TX_AGGREGATION + if (pxmitframe->agg_num > 1) + ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000); +#endif + + rtl8192cu_cal_txdesc_chksum(ptxdesc); + + return pull; + +} + +static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + s32 ret = _SUCCESS; + s32 inner_ret = _SUCCESS; + int t, sz, w_sz, pull=0; + u8 *mem_addr; + u32 ff_hwaddr; + struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + + if ((pxmitframe->frame_tag == DATA_FRAMETAG) && + (pxmitframe->attrib.ether_type != 0x0806) && + (pxmitframe->attrib.ether_type != 0x888e) && + (pxmitframe->attrib.dhcp_pkt != 1)) + { + rtw_issue_addbareq_cmd(padapter, pxmitframe); + } + + mem_addr = pxmitframe->buf_addr; + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n")); + + for (t = 0; t < pattrib->nr_frags; t++) + { + if (inner_ret != _SUCCESS && ret == _SUCCESS) + ret = _FAIL; + + if (t != (pattrib->nr_frags - 1)) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags)); + + sz = pxmitpriv->frag_len; + sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len); + } + else //no frag + { + sz = pattrib->last_txcmdsz; + } + + pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE); + + if(pull) + { + mem_addr += PACKET_OFFSET_SZ; //pull txdesc head + + //pxmitbuf ->pbuf = mem_addr; + pxmitframe->buf_addr = mem_addr; + + w_sz = sz + TXDESC_SIZE; + } + else + { + w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ; + } + + ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); + + inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf); + + rtw_count_tx_stats(padapter, pxmitframe, sz); + + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz)); + //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority); + + mem_addr += w_sz; + + mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr))); + + } + + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + if (ret != _SUCCESS) + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); + + return ret; +} + +#ifdef CONFIG_USB_TX_AGGREGATION +static u32 xmitframe_need_length(struct xmit_frame *pxmitframe) +{ + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + u32 len = 0; + + // no consider fragement + len = pattrib->hdrlen + pattrib->iv_len + + SNAP_SIZE + sizeof(u16) + + pattrib->pktlen + + ((pattrib->bswenc) ? pattrib->icv_len : 0); + + if(pattrib->encrypt ==_TKIP_) + len += 8; + + return len; +} + +#define IDEA_CONDITION 1 // check all packets before enqueue +s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct xmit_frame *pxmitframe = NULL; + struct xmit_frame *pfirstframe = NULL; + + // aggregate variable + struct hw_xmit *phwxmit; + struct sta_info *psta = NULL; + struct tx_servq *ptxservq = NULL; + + _irqL irqL; + _list *xmitframe_plist = NULL, *xmitframe_phead = NULL; + + u32 pbuf; // next pkt address + u32 pbuf_tail; // last pkt tail + u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET + + u32 bulkSize = pHalData->UsbBulkOutSize; + u8 descCount; + u32 bulkPtr; + + // dump frame variable + u32 ff_hwaddr; + +#ifndef IDEA_CONDITION + int res = _SUCCESS; +#endif + + RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n")); + + + // check xmitbuffer is ok + if (pxmitbuf == NULL) { + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + if (pxmitbuf == NULL) return _FALSE; + } + + + //3 1. pick up first frame + do { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); + if (pxmitframe == NULL) { + // no more xmit frame, release xmit buffer + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + return _FALSE; + } + + +#ifndef IDEA_CONDITION + if (pxmitframe->frame_tag != DATA_FRAMETAG) { + RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_, + ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n", + pxmitframe->frame_tag, DATA_FRAMETAG)); +// rtw_free_xmitframe(pxmitpriv, pxmitframe); + continue; + } + + // TID 0~15 + if ((pxmitframe->attrib.priority < 0) || + (pxmitframe->attrib.priority > 15)) { + RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_, + ("xmitframe_complete: TID(%d) should be 0~15!\n", + pxmitframe->attrib.priority)); +// rtw_free_xmitframe(pxmitpriv, pxmitframe); + continue; + } +#endif + + pxmitframe->pxmitbuf = pxmitbuf; + pxmitframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pxmitframe; + + //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1. + pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset + + + if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) { + DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__); + continue; + } + + + // always return ndis_packet after rtw_xmitframe_coalesce + rtw_os_xmit_complete(padapter, pxmitframe); + + break; + } while (1); + + //3 2. aggregate same priority and same DA(AP or STA) frames + pfirstframe = pxmitframe; + len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET; + pbuf_tail = len; + pbuf = _RND8(pbuf_tail); + + // check pkt amount in one bluk + descCount = 0; + bulkPtr = bulkSize; + if (pbuf < bulkPtr) + descCount++; + else { + descCount = 0; + bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize + } + + // dequeue same priority packet from station tx queue + psta = pfirstframe->attrib.psta; + switch (pfirstframe->attrib.priority) { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + phwxmit = pxmitpriv->hwxmits + 3; + break; + + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + phwxmit = pxmitpriv->hwxmits + 1; + break; + + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + phwxmit = pxmitpriv->hwxmits; + break; + + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + phwxmit = pxmitpriv->hwxmits + 2; + break; + } + + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&ptxservq->sta_pending); + xmitframe_plist = get_next(xmitframe_phead); + while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + xmitframe_plist = get_next(xmitframe_plist); + + len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset + if (pbuf + len > MAX_XMITBUF_SZ) break; + + rtw_list_delete(&pxmitframe->list); + ptxservq->qcnt--; + phwxmit->accnt--; + +#ifndef IDEA_CONDITION + // suppose only data frames would be in queue + if (pxmitframe->frame_tag != DATA_FRAMETAG) { + RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_, + ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n", + pxmitframe->frame_tag, DATA_FRAMETAG)); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + continue; + } + + // TID 0~15 + if ((pxmitframe->attrib.priority < 0) || + (pxmitframe->attrib.priority > 15)) { + RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_, + ("xmitframe_complete: TID(%d) should be 0~15!\n", + pxmitframe->attrib.priority)); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + continue; + } +#endif + +// pxmitframe->pxmitbuf = pxmitbuf; + pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf; + + pxmitframe->agg_num = 0; // not first frame of aggregation + pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset + + if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) { + DBG_871X("%s coalesce failed \n",__FUNCTION__); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + continue; + } + + // always return ndis_packet after rtw_xmitframe_coalesce + rtw_os_xmit_complete(padapter, pxmitframe); + + // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz + update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE); + + // don't need xmitframe any more + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + // handle pointer and stop condition + pbuf_tail = pbuf + len; + pbuf = _RND8(pbuf_tail); + + pfirstframe->agg_num++; + if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num) + break; + + if (pbuf < bulkPtr) { + descCount++; + if (descCount == pHalData->UsbTxAggDescNum) + break; + } else { + descCount = 0; + bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; + } + } + if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE) + rtw_list_delete(&ptxservq->tx_pending); + + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + if ((pfirstframe->attrib.ether_type != 0x0806) && + (pfirstframe->attrib.ether_type != 0x888e) && + (pfirstframe->attrib.dhcp_pkt != 1)) + { + rtw_issue_addbareq_cmd(padapter, pfirstframe); + } + +#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX + //3 3. update first frame txdesc + if ((pbuf_tail % bulkSize) == 0) { + // remove pkt_offset + pbuf_tail -= PACKET_OFFSET_SZ; + pfirstframe->buf_addr += PACKET_OFFSET_SZ; + pfirstframe->pkt_offset = 0; + } +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE); + + //3 4. write xmit buffer to USB FIFO + ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe); + + // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr + rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf); + + + //3 5. update statisitc + pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE); + if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ; + + rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail); + + rtw_free_xmitframe(pxmitpriv, pfirstframe); + + return _TRUE; +} + +#else + +s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + + struct hw_xmit *phwxmits; + sint hwentry; + struct xmit_frame *pxmitframe=NULL; + int res=_SUCCESS, xcnt = 0; + + phwxmits = pxmitpriv->hwxmits; + hwentry = pxmitpriv->hwxmit_entry; + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n")); + + if(pxmitbuf==NULL) + { + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + if(!pxmitbuf) + { + return _FALSE; + } + } + + + do + { + pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry); + + if(pxmitframe) + { + pxmitframe->pxmitbuf = pxmitbuf; + + pxmitframe->buf_addr = pxmitbuf->pbuf; + + pxmitbuf->priv_data = pxmitframe; + + if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) + { + if(pxmitframe->attrib.priority<=15)//TID0~15 + { + res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); + } + + rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce + } + + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n")); + + + if(res == _SUCCESS) + { + rtw_dump_xframe(padapter, pxmitframe); + } + else + { + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + } + + xcnt++; + + } + else + { + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + return _FALSE; + } + + break; + + }while(0/*xcnt < (NR_XMITFRAME >> 3)*/); + + return _TRUE; + +} +#endif + + + +static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + s32 res = _SUCCESS; + + + res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); + if (res == _SUCCESS) { + rtw_dump_xframe(padapter, pxmitframe); + } + + return res; +} + +/* + * Return + * _TRUE dump packet directly + * _FALSE enqueue packet + */ +static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + s32 res; + struct xmit_buf *pxmitbuf = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + + if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) + goto enqueue; + + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + goto enqueue; + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + goto enqueue; +#endif + + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + if (pxmitbuf == NULL) + goto enqueue; + + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + pxmitframe->pxmitbuf = pxmitbuf; + pxmitframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pxmitframe; + + if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + } + + return _TRUE; + +enqueue: + res = rtw_xmitframe_enqueue(padapter, pxmitframe); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + if (res != _SUCCESS) { + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n")); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + // Trick, make the statistics correct + pxmitpriv->tx_pkts--; + pxmitpriv->tx_drop++; + return _TRUE; + } + + return _FALSE; +} + +s32 rtl8192cu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + return rtw_dump_xframe(padapter, pmgntframe); +} + +/* + * Return + * _TRUE dump packet directly ok + * _FALSE temporary can't transmit packets to hardware + */ +s32 rtl8192cu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + return pre_xmitframe(padapter, pxmitframe); +} + +s32 rtl8192cu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + s32 err; + + if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) + { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + // Trick, make the statistics correct + pxmitpriv->tx_pkts--; + pxmitpriv->tx_drop++; + } + else + { +#ifdef PLATFORM_LINUX + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#endif + } + + return err; + +} + +#ifdef CONFIG_HOSTAPD_MLME + +static void rtl8192cu_hostap_mgnt_xmit_cb(struct urb *urb) +{ +#ifdef PLATFORM_LINUX + struct sk_buff *skb = (struct sk_buff *)urb->context; + + //DBG_8192C("%s\n", __FUNCTION__); + + rtw_skb_free(skb); +#endif +} + +s32 rtl8192cu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt) +{ +#ifdef PLATFORM_LINUX + u16 fc; + int rc, len, pipe; + unsigned int bmcst, tid, qsel; + struct sk_buff *skb, *pxmit_skb; + struct urb *urb; + unsigned char *pxmitbuf; + struct tx_desc *ptxdesc; + struct rtw_ieee80211_hdr *tx_hdr; + struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; + struct net_device *pnetdev = padapter->pnetdev; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + + + //DBG_8192C("%s\n", __FUNCTION__); + + skb = pkt; + + len = skb->len; + tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data); + fc = le16_to_cpu(tx_hdr->frame_ctl); + bmcst = IS_MCAST(tx_hdr->addr1); + + if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT) + goto _exit; + + pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE); + + if(!pxmit_skb) + goto _exit; + + pxmitbuf = pxmit_skb->data; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + goto _exit; + } + + // ----- fill tx desc ----- + ptxdesc = (struct tx_desc *)pxmitbuf; + _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc)); + + //offset 0 + ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); + ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<txdw0 |= cpu_to_le32(OWN | FSG | LSG); + + if(bmcst) + { + ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); + } + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID + + ptxdesc->txdw1 |= cpu_to_le32((0x12<txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode + + //offset 8 + + //offset 12 + ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000); + + //offset 16 + ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate + + //offset 20 + + + //HW append seq + ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number + ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. + + + rtl8192cu_cal_txdesc_chksum(ptxdesc); + // ----- end of fill tx desc ----- + + // + skb_put(pxmit_skb, len + TXDESC_SIZE); + pxmitbuf = pxmitbuf + TXDESC_SIZE; + _rtw_memcpy(pxmitbuf, skb->data, len); + + //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len); + + + // ----- prepare urb for submit ----- + + //translate DMA FIFO addr to pipehandle + //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); + pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f); + + usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe, + pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb); + + urb->transfer_flags |= URB_ZERO_PACKET; + usb_anchor_urb(urb, &phostapdpriv->anchored); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + usb_unanchor_urb(urb); + kfree_skb(skb); + } + usb_free_urb(urb); + + +_exit: + + rtw_skb_free(skb); + +#endif + + return 0; + +} +#endif + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c new file mode 100755 index 00000000..ff894732 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c @@ -0,0 +1,6261 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_HAL_INIT_C_ + +#include +#include +#include +#include + +#include +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8192c_sreset.h" +#endif + +#ifdef CONFIG_IOL +#include +#endif + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#ifndef CONFIG_USB_HCI + +#error "CONFIG_USB_HCI shall be on!\n" + +#endif + +#include +#include +#include + +#if DISABLE_BB_RF + #define HAL_MAC_ENABLE 0 + #define HAL_BB_ENABLE 0 + #define HAL_RF_ENABLE 0 +#else + #define HAL_MAC_ENABLE 1 + #define HAL_BB_ENABLE 1 + #define HAL_RF_ENABLE 1 +#endif + +//endpoint number 1,2,3,4,5 +// bult in : 1 +// bult out: 2 (High) +// bult out: 3 (Normal) for 3 out_ep, (Low) for 2 out_ep +// interrupt in: 4 +// bult out: 5 (Low) for 3 out_ep + + +static VOID +_OneOutEpMapping( + IN HAL_DATA_TYPE *pHalData + ) +{ + //only endpoint number 0x02 + + pHalData->Queue2EPNum[0] = pHalData->RtBulkOutPipe[0];//VO + pHalData->Queue2EPNum[1] = pHalData->RtBulkOutPipe[0];//VI + pHalData->Queue2EPNum[2] = pHalData->RtBulkOutPipe[0];//BE + pHalData->Queue2EPNum[3] = pHalData->RtBulkOutPipe[0];//BK + + pHalData->Queue2EPNum[4] = pHalData->RtBulkOutPipe[0];//BCN + pHalData->Queue2EPNum[5] = pHalData->RtBulkOutPipe[0];//MGT + pHalData->Queue2EPNum[6] = pHalData->RtBulkOutPipe[0];//HIGH + pHalData->Queue2EPNum[7] = pHalData->RtBulkOutPipe[0];//TXCMD +} + + +static VOID +_TwoOutEpMapping( + IN HAL_DATA_TYPE *pHalData, + IN BOOLEAN bWIFICfg + ) +{ + +/* +#define VO_QUEUE_INX 0 +#define VI_QUEUE_INX 1 +#define BE_QUEUE_INX 2 +#define BK_QUEUE_INX 3 +#define BCN_QUEUE_INX 4 +#define MGT_QUEUE_INX 5 +#define HIGH_QUEUE_INX 6 +#define TXCMD_QUEUE_INX 7 +*/ + if(bWIFICfg){ // Normal chip && wmm + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 0, 1, 0, 1, 0, 0, 0, 0, 0 }; + //0:H(end_number=0x02), 1:L (end_number=0x03) + + pHalData->Queue2EPNum[0] = pHalData->RtBulkOutPipe[1];//VO + pHalData->Queue2EPNum[1] = pHalData->RtBulkOutPipe[0];//VI + pHalData->Queue2EPNum[2] = pHalData->RtBulkOutPipe[1];//BE + pHalData->Queue2EPNum[3] = pHalData->RtBulkOutPipe[0];//BK + + pHalData->Queue2EPNum[4] = pHalData->RtBulkOutPipe[0];//BCN + pHalData->Queue2EPNum[5] = pHalData->RtBulkOutPipe[0];//MGT + pHalData->Queue2EPNum[6] = pHalData->RtBulkOutPipe[0];//HIGH + pHalData->Queue2EPNum[7] = pHalData->RtBulkOutPipe[0];//TXCMD + } + else{//typical setting + + //BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + //0:H(end_number=0x02), 1:L (end_number=0x03) + + pHalData->Queue2EPNum[0] = pHalData->RtBulkOutPipe[0];//VO + pHalData->Queue2EPNum[1] = pHalData->RtBulkOutPipe[0];//VI + pHalData->Queue2EPNum[2] = pHalData->RtBulkOutPipe[1];//BE + pHalData->Queue2EPNum[3] = pHalData->RtBulkOutPipe[1];//BK + + pHalData->Queue2EPNum[4] = pHalData->RtBulkOutPipe[0];//BCN + pHalData->Queue2EPNum[5] = pHalData->RtBulkOutPipe[0];//MGT + pHalData->Queue2EPNum[6] = pHalData->RtBulkOutPipe[0];//HIGH + pHalData->Queue2EPNum[7] = pHalData->RtBulkOutPipe[0];//TXCMD + } + +} + + +static VOID _ThreeOutEpMapping( + IN HAL_DATA_TYPE *pHalData, + IN BOOLEAN bWIFICfg + ) +{ + if(bWIFICfg){//for WMM + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 1, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H(end_number=0x02), 1:N(end_number=0x03), 2:L (end_number=0x05) + + pHalData->Queue2EPNum[0] = pHalData->RtBulkOutPipe[0];//VO + pHalData->Queue2EPNum[1] = pHalData->RtBulkOutPipe[1];//VI + pHalData->Queue2EPNum[2] = pHalData->RtBulkOutPipe[2];//BE + pHalData->Queue2EPNum[3] = pHalData->RtBulkOutPipe[1];//BK + + pHalData->Queue2EPNum[4] = pHalData->RtBulkOutPipe[0];//BCN + pHalData->Queue2EPNum[5] = pHalData->RtBulkOutPipe[0];//MGT + pHalData->Queue2EPNum[6] = pHalData->RtBulkOutPipe[0];//HIGH + pHalData->Queue2EPNum[7] = pHalData->RtBulkOutPipe[0];//TXCMD + } + else{//typical setting + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 2, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H(end_number=0x02), 1:N(end_number=0x03), 2:L (end_number=0x05) + pHalData->Queue2EPNum[0] = pHalData->RtBulkOutPipe[0];//VO + pHalData->Queue2EPNum[1] = pHalData->RtBulkOutPipe[1];//VI + pHalData->Queue2EPNum[2] = pHalData->RtBulkOutPipe[2];//BE + pHalData->Queue2EPNum[3] = pHalData->RtBulkOutPipe[2];//BK + + pHalData->Queue2EPNum[4] = pHalData->RtBulkOutPipe[0];//BCN + pHalData->Queue2EPNum[5] = pHalData->RtBulkOutPipe[0];//MGT + pHalData->Queue2EPNum[6] = pHalData->RtBulkOutPipe[0];//HIGH + pHalData->Queue2EPNum[7] = pHalData->RtBulkOutPipe[0];//TXCMD + } + +} + +static BOOLEAN +_MappingOutEP( + IN PADAPTER pAdapter, + IN u8 NumOutPipe + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct registry_priv *pregistrypriv = &pAdapter->registrypriv; + + BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ?_TRUE:_FALSE; + + BOOLEAN result = _TRUE; + + switch(NumOutPipe) + { + case 2: + _TwoOutEpMapping(pHalData, bWIFICfg); + break; + case 3: + _ThreeOutEpMapping(pHalData, bWIFICfg); + break; + case 1: + _OneOutEpMapping(pHalData); + break; + default: + result = _FALSE; + break; + } + + return result; + +} + +static VOID +_ConfigChipOutEP( + IN PADAPTER pAdapter, + IN u8 NumOutPipe + ) +{ + u8 value8; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + pHalData->OutEpQueueSel = 0; + pHalData->OutEpNumber = 0; + + // Normal and High queue + value8 = rtw_read8(pAdapter, (REG_NORMAL_SIE_EP + 1)); + + if(value8 & USB_NORMAL_SIE_EP_MASK){ + pHalData->OutEpQueueSel |= TX_SELE_HQ; + pHalData->OutEpNumber++; + } + +#ifdef CONFIG_USB_ONE_OUT_EP + return; +#endif + + if((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK){ + pHalData->OutEpQueueSel |= TX_SELE_NQ; + pHalData->OutEpNumber++; + } + + // Low queue + value8 = rtw_read8(pAdapter, (REG_NORMAL_SIE_EP + 2)); + if(value8 & USB_NORMAL_SIE_EP_MASK){ + pHalData->OutEpQueueSel |= TX_SELE_LQ; + pHalData->OutEpNumber++; + } + + // TODO: Error recovery for this case + //RT_ASSERT((NumOutPipe == pHalData->OutEpNumber), ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n", (u4Byte)NumOutPipe, (u4Byte)pHalData->OutEpNumber)); + +} + +static BOOLEAN HalUsbSetQueuePipeMapping8192CUsb( + IN PADAPTER pAdapter, + IN u8 NumInPipe, + IN u8 NumOutPipe + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN result = _FALSE; + + _ConfigChipOutEP(pAdapter, NumOutPipe); + + #ifndef CONFIG_USB_ONE_OUT_EP + // Normal chip with one IN and one OUT doesn't have interrupt IN EP. + if(1 == pHalData->OutEpNumber){ + if(1 != NumInPipe){ + return result; + } + } + #endif + result = _MappingOutEP(pAdapter, NumOutPipe); + + return result; + +} + +void rtl8192cu_interface_configure(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + + if (pdvobjpriv->ishighspeed == _TRUE) + { + pHalData->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE;//512 bytes + } + else + { + pHalData->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE;//64 bytes + } + + pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber; + pHalData->RtBulkInPipe = pdvobjpriv->ep_num[0]; + pHalData->RtBulkOutPipe[0] = pdvobjpriv->ep_num[1]; + pHalData->RtBulkOutPipe[1] = pdvobjpriv->ep_num[2]; + pHalData->RtIntInPipe = pdvobjpriv->ep_num[3]; + pHalData->RtBulkOutPipe[2] = pdvobjpriv->ep_num[4]; + +#ifdef CONFIG_USB_TX_AGGREGATION + pHalData->UsbTxAggMode = 1; + pHalData->UsbTxAggDescNum = 0x6; // only 4 bits +#endif + +#ifdef CONFIG_USB_RX_AGGREGATION + pHalData->UsbRxAggMode = USB_RX_AGG_DMA;// USB_RX_AGG_DMA; + pHalData->UsbRxAggBlockCount = 8; //unit : 512b + pHalData->UsbRxAggBlockTimeout = 0x6; + pHalData->UsbRxAggPageCount = 48; //uint :128 b //0x0A; // 10 = MAX_RX_DMA_BUFFER_SIZE/2/pHalData->UsbBulkOutSize + pHalData->UsbRxAggPageTimeout = 0x4; //6, absolute time = 34ms/(2^6) +#endif + + HalUsbSetQueuePipeMapping8192CUsb(padapter, pdvobjpriv->RtNumInPipes, + #ifdef CONFIG_USB_ONE_OUT_EP + 1 + #else + pdvobjpriv->RtNumOutPipes + #endif + ); + +} + +static u8 _InitPowerOn(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 ret = _SUCCESS; + u16 value16=0; + u8 value8 = 0; + u32 value32 = 0; + + // polling autoload done. + u32 pollingCount = 0; + + do + { + if(rtw_read8(padapter, REG_APS_FSMCO) & PFM_ALDN){ + //RT_TRACE(COMP_INIT,DBG_LOUD,("Autoload Done!\n")); + break; + } + + if(pollingCount++ > POLLING_READY_TIMEOUT_COUNT){ + //RT_TRACE(COMP_INIT,DBG_SERIOUS,("Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n")); + return _FAIL; + } + + }while(_TRUE); + + +// For hardware power on sequence. + + //0. RSV_CTRL 0x1C[7:0] = 0x00 // unlock ISO/CLK/Power control register + rtw_write8(padapter, REG_RSV_CTRL, 0x0); + // Power on when re-enter from IPS/Radio off/card disable + rtw_write8(padapter, REG_SPS0_CTRL, 0x2b);//enable SPS into PWM mode +/* + value16 = PlatformIORead2Byte(Adapter, REG_AFE_XTAL_CTRL);//enable AFE clock + value16 &= (~XTAL_GATE_AFE); + PlatformIOWrite2Byte(Adapter,REG_AFE_XTAL_CTRL, value16 ); +*/ + + rtw_udelay_os(100);//PlatformSleepUs(150);//this is not necessary when initially power on + + value8 = rtw_read8(padapter, REG_LDOV12D_CTRL); + if(0== (value8 & LDV12_EN) ){ + value8 |= LDV12_EN; + rtw_write8(padapter, REG_LDOV12D_CTRL, value8); + //RT_TRACE(COMP_INIT, DBG_LOUD, (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8)); + rtw_udelay_os(100);//PlatformSleepUs(100);//this is not necessary when initially power on + value8 = rtw_read8(padapter, REG_SYS_ISO_CTRL); + value8 &= ~ISO_MD2PP; + rtw_write8(padapter, REG_SYS_ISO_CTRL, value8); + } + + // auto enable WLAN + pollingCount = 0; + value16 = rtw_read16(padapter, REG_APS_FSMCO); + value16 |= APFM_ONMAC; + rtw_write16(padapter, REG_APS_FSMCO, value16); + + do + { + if(0 == (rtw_read16(padapter, REG_APS_FSMCO) & APFM_ONMAC)){ + //RT_TRACE(COMP_INIT,DBG_LOUD,("MAC auto ON okay!\n")); + break; + } + + if(pollingCount++ > POLLING_READY_TIMEOUT_COUNT){ + //RT_TRACE(COMP_INIT,DBG_SERIOUS,("Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n")); + return _FAIL; + } + + }while(_TRUE); + + //Enable Radio ,GPIO ,and LED function + rtw_write16(padapter,REG_APS_FSMCO,0x0812); + +#ifdef CONFIG_AUTOSUSPEND + //for usb Combo card ,BT + if((BOARD_USB_COMBO == pHalData->BoardType)&&(padapter->registrypriv.usbss_enable)) + { + value32 = rtw_read32(padapter, REG_APS_FSMCO); + value32 |= (SOP_ABG|SOP_AMB|XOP_BTCK); + rtw_write32(padapter, REG_APS_FSMCO, value32); + } +#endif + + // release RF digital isolation + value16 = rtw_read16(padapter, REG_SYS_ISO_CTRL); + value16 &= ~ISO_DIOR; + rtw_write16(padapter, REG_SYS_ISO_CTRL, value16); + + // Enable MAC DMA/WMAC/SCHEDULE/SEC block + value16 = rtw_read16(padapter, REG_CR); + value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN + | PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); + rtw_write16(padapter, REG_CR, value16); + + //tynli_test for suspend mode. + { + rtw_write8(padapter, 0xfe10, 0x19); + } + + // 2010/11/22 MH For slim combo debug mode check. + if (pHalData->BoardType == BOARD_USB_COMBO) + { + if (pHalData->SlimComboDbg == _TRUE) + { + DBG_8192C("SlimComboDbg == TRUE\n"); + + // 1. SIC?Test Mode ¤¤, Debug Ports ·|¦Û°Ê Enable, ©Ò¥H Driver ¤W¨Ó«á, + // ­nÃö±¼½Ð³]©w 0x 00[7] -> "1", ±N¥¦ Disable. effect if not: power consumption increase + rtw_write8(padapter, REG_SYS_ISO_CTRL, rtw_read8(padapter, REG_SYS_ISO_CTRL)|BIT7); + + // 2. SIC?Test Mode ¤¤, GPIO-8?·| report Power State ©Ò¥H Driver ¤W¨Ó«á, ½Ð³]©w? 0x04[6] -> "1" ±N¥¦ Disable + // effect if not: GPIO-8 could not be GPIO or LED function + rtw_write8(padapter, REG_APS_FSMCO, rtw_read8(padapter, REG_APS_FSMCO)|BIT6); + + // 3. SIC Test Mode ¤¤, EESK, EECS ·| report?Host Clock status, ©Ò¥H Driver ¤W¨Ó«á, ½Ð³]©w? 0x40[4] -> "1" ±N¥¦¤Á¦¨ EEPROM ¨Ï¥Î Pin (autoload still from Efuse) + // effect if not:power consumption increase + value8 = rtw_read8(padapter, REG_GPIO_MUXCFG)|BIT4 ; + #ifdef CONFIG_BT_COEXIST + // 2011/01/26 MH UMB-B cut bug. We need to support the modification. + if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID) && + pHalData->bt_coexist.BT_Coexist) + { + value8 |= (BIT5); + } + #endif + rtw_write8(padapter, REG_GPIO_MUXCFG,value8 ); + + + // 4. SIC Test Mode ¤¤,?SIC Debug ports ·|¦Û°Ê Enable , ©Ò¥H Driver ¤W¨Ó«á°¨¤W, ½Ð³]©w? 0x40[15:11] -> ¡§0x00¡¨, ±N¥¦Disable + // 4.1Two Steps setting for safety: 0x40[15,13,12, 11] -> "0", then ?0x40[14] -> "0" + // effect if not: Host could not transfer packets, and GPIO-3,2 will occupied by SIC then Co-exist could not work. + rtw_write16(padapter, REG_GPIO_MUXCFG, (rtw_read16(padapter, REG_GPIO_MUXCFG)&0x07FF)|BIT14); + rtw_write16(padapter, REG_GPIO_MUXCFG, rtw_read16(padapter, REG_GPIO_MUXCFG)&0x07FF); + } + } + + + // 2011/02/18 To Fix RU LNA power leakage problem. We need to execute below below in + // Adapter init and halt sequence. Accordingto EEchou's opinion, we can enable the ability for all + // IC. According to Johnny's opinion, only RU will meet the condition. + if (IS_HARDWARE_TYPE_8192C(padapter) && (pHalData->BoardType == BOARD_USB_High_PA)) + rtw_write32(padapter, rFPGA0_XCD_RFParameter, rtw_read32(padapter, rFPGA0_XCD_RFParameter)&(~BIT1)); + return ret; + +} + + +static void _dbg_dump_macreg(_adapter *padapter) +{ + u32 offset = 0; + u32 val32 = 0; + u32 index =0 ; + for(index=0;index<64;index++) + { + offset = index*4; + val32 = rtw_read32(padapter,offset); + DBG_8192C("offset : 0x%02x ,val:0x%08x\n",offset,val32); + } +} + + +static void _InitPABias(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 pa_setting; + BOOLEAN is92C = IS_92C_SERIAL(pHalData->VersionID); + + //FIXED PA current issue + //efuse_one_byte_read(padapter, 0x1FA, &pa_setting); + pa_setting = EFUSE_Read1Byte(padapter, 0x1FA); + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("_InitPABias 0x1FA 0x%x \n",pa_setting)); + + if(!(pa_setting & BIT0)) + { + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x0F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x4F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x8F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0xCF406); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path A\n")); + } + + if(!(pa_setting & BIT1) && is92C) + { + PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x0F406); + PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x4F406); + PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0x8F406); + PHY_SetRFReg(padapter,RF_PATH_B, 0x15, 0x0FFFFF, 0xCF406); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path B\n")); + } + + if(!(pa_setting & BIT4)) + { + pa_setting = rtw_read8(padapter, 0x16); + pa_setting &= 0x0F; + rtw_write8(padapter, 0x16, pa_setting | 0x90); + } +} +#ifdef CONFIG_BT_COEXIST +static void _InitBTCoexist(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); + u8 u1Tmp; + + if(pbtpriv->BT_Coexist && pbtpriv->BT_CoexistType == BT_CSR_BC4) + { + +#if MP_DRIVER != 1 + if(pbtpriv->BT_Ant_isolation) + { + rtw_write8( padapter,REG_GPIO_MUXCFG, 0xa0); + DBG_8192C("BT write 0x%x = 0x%x\n", REG_GPIO_MUXCFG, 0xa0); + } +#endif + + u1Tmp = rtw_read8(padapter, 0x4fd) & BIT0; + u1Tmp = u1Tmp | + ((pbtpriv->BT_Ant_isolation==1)?0:BIT1) | + ((pbtpriv->BT_Service==BT_SCO)?0:BIT2); + rtw_write8( padapter, 0x4fd, u1Tmp); + DBG_8192C("BT write 0x%x = 0x%x for non-isolation\n", 0x4fd, u1Tmp); + + + rtw_write32(padapter, REG_BT_COEX_TABLE+4, 0xaaaa9aaa); + DBG_8192C("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE+4, 0xaaaa9aaa); + + rtw_write32(padapter, REG_BT_COEX_TABLE+8, 0xffbd0040); + DBG_8192C("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE+8, 0xffbd0040); + + rtw_write32(padapter, REG_BT_COEX_TABLE+0xc, 0x40000010); + DBG_8192C("BT write 0x%x = 0x%x\n", REG_BT_COEX_TABLE+0xc, 0x40000010); + + //Config to 1T1R + u1Tmp = rtw_read8(padapter,rOFDM0_TRxPathEnable); + u1Tmp &= ~(BIT1); + rtw_write8( padapter, rOFDM0_TRxPathEnable, u1Tmp); + DBG_8192C("BT write 0xC04 = 0x%x\n", u1Tmp); + + u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable); + u1Tmp &= ~(BIT1); + rtw_write8( padapter, rOFDM1_TRxPathEnable, u1Tmp); + DBG_8192C("BT write 0xD04 = 0x%x\n", u1Tmp); + + } +} +#endif + +//------------------------------------------------------------------------- +// +// LLT R/W/Init function +// +//------------------------------------------------------------------------- +static u8 _LLTWrite( + IN PADAPTER Adapter, + IN u32 address, + IN u32 data + ) +{ + u8 status = _SUCCESS; + int count = 0; + u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtw_write32(Adapter, REG_LLT_INIT, value); + + //polling + do{ + + value = rtw_read32(Adapter, REG_LLT_INIT); + if(_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)){ + break; + } + + if(count > POLLING_LLT_THRESHOLD){ + //RT_TRACE(COMP_INIT,DBG_SERIOUS,("Failed to polling write LLT done at address %d!\n", address)); + status = _FAIL; + break; + } + }while(count++); + + return status; + +} + + +static u8 _LLTRead( + IN PADAPTER Adapter, + IN u32 address + ) +{ + int count = 0; + u32 value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS); + + rtw_write32(Adapter, REG_LLT_INIT, value); + + //polling and get value + do{ + + value = rtw_read32(Adapter, REG_LLT_INIT); + if(_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)){ + return (u8)value; + } + + if(count > POLLING_LLT_THRESHOLD){ + //RT_TRACE(COMP_INIT,DBG_SERIOUS,("Failed to polling read LLT done at address %d!\n", address)); + break; + } + }while(count++); + + return 0xFF; + +} + + +static u8 InitLLTTable( + IN PADAPTER Adapter, + IN u32 boundary + ) +{ + u8 status = _SUCCESS; + u32 i; + +#ifdef CONFIG_IOL_LLT + if(rtw_IOL_applied(Adapter)) + { + struct xmit_frame *xmit_frame; + if((xmit_frame=rtw_IOL_accquire_xmit_frame(Adapter)) == NULL) + return _FAIL; + + rtw_IOL_append_LLT_cmd(xmit_frame, boundary); + status = rtw_IOL_exec_cmds_sync(Adapter, xmit_frame, 1000); + } + else +#endif + { + for(i = 0 ; i < (boundary - 1) ; i++){ + status = _LLTWrite(Adapter, i , i + 1); + if(_SUCCESS != status){ + return status; + } + } + + // end of list + status = _LLTWrite(Adapter, (boundary - 1), 0xFF); + if(_SUCCESS != status){ + return status; + } + + // Make the other pages as ring buffer + // This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. + // Otherwise used as local loopback buffer. + for(i = boundary ; i < LAST_ENTRY_OF_TX_PKT_BUFFER ; i++){ + status = _LLTWrite(Adapter, i, (i + 1)); + if(_SUCCESS != status){ + return status; + } + } + + // Let last entry point to the start entry of ring buffer + status = _LLTWrite(Adapter, LAST_ENTRY_OF_TX_PKT_BUFFER, boundary); + if(_SUCCESS != status){ + return status; + } + } + + return status; + +} + + +//--------------------------------------------------------------- +// +// 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 +_InitInterrupt( + IN PADAPTER Adapter + ) +{ + u32 value32; + + // HISR - turn all on + value32 = 0xFFFFFFFF; + rtw_write32(Adapter, REG_HISR, value32); + + // HIMR - turn all on + rtw_write32(Adapter, REG_HIMR, value32); +} + + +static VOID +_InitQueueReservedPage( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + + u32 outEPNum = (u32)pHalData->OutEpNumber; + u32 numHQ = 0; + u32 numLQ = 0; + u32 numNQ = 0; + u32 numPubQ; + u32 value32; + u8 value8; + BOOLEAN bWiFiConfig = pregistrypriv->wifi_spec; + //u32 txQPageNum, txQPageUnit,txQRemainPage; + + { //for WMM + //RT_ASSERT((outEPNum>=2), ("for WMM ,number of out-ep must more than or equal to 2!\n")); + + if(pHalData->OutEpQueueSel & TX_SELE_HQ){ + numHQ = (bWiFiConfig)?WMM_NORMAL_PAGE_NUM_HPQ:NORMAL_PAGE_NUM_HPQ; + } + + if(pHalData->OutEpQueueSel & TX_SELE_LQ){ + numLQ = (bWiFiConfig)?WMM_NORMAL_PAGE_NUM_LPQ:NORMAL_PAGE_NUM_LPQ; + } + // NOTE: This step shall be proceed before writting REG_RQPN. + if(pHalData->OutEpQueueSel & TX_SELE_NQ){ + numNQ = (bWiFiConfig)?WMM_NORMAL_PAGE_NUM_NPQ:NORMAL_PAGE_NUM_NPQ; + } + value8 = (u8)_NPQ(numNQ); + rtw_write8(Adapter, REG_RQPN_NPQ, value8); + + if (bWiFiConfig) + numPubQ = WMM_NORMAL_TX_TOTAL_PAGE_NUMBER - numHQ - numLQ - numNQ; + else + numPubQ = TX_TOTAL_PAGE_NUMBER - numHQ - numLQ - numNQ; + } + + // TX DMA + value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; + rtw_write32(Adapter, REG_RQPN, value32); +} + +static VOID +_InitTxBufferBoundary( + IN PADAPTER Adapter + ) +{ + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + u8 txpktbuf_bndy; + + if(!pregistrypriv->wifi_spec){ + txpktbuf_bndy = TX_PAGE_BOUNDARY; + } + else{//for WMM + txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY; + } + + rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); + rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy); +#if 1 + rtw_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy); +#else + txdmactrl = PlatformIORead2Byte(Adapter, REG_TDECTRL); + txdmactrl &= ~BCN_HEAD_MASK; + txdmactrl |= BCN_HEAD(txpktbuf_bndy); + PlatformIOWrite2Byte(Adapter, REG_TDECTRL, txdmactrl); +#endif +} + +static VOID +_InitPageBoundary( + IN PADAPTER Adapter + ) +{ + // RX Page Boundary + //srand(static_cast(time(NULL)) ); + u16 rxff_bndy = 0x27FF;//(rand() % 1) ? 0x27FF : 0x23FF; + + rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); + + // TODO: ?? shall we set tx boundary? +} + + +static VOID +_InitNormalChipRegPriority( + IN PADAPTER Adapter, + IN u16 beQ, + IN u16 bkQ, + IN u16 viQ, + IN u16 voQ, + IN u16 mgtQ, + IN u16 hiQ + ) +{ + u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7); + + value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | + _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | + _TXDMA_MGQ_MAP(mgtQ)| _TXDMA_HIQ_MAP(hiQ); + + rtw_write16(Adapter, REG_TRXDMA_CTRL, value16); +} + +static VOID +_InitNormalChipOneOutEpPriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + u16 value = 0; + switch(pHalData->OutEpQueueSel) + { + case TX_SELE_HQ: + value = QUEUE_HIGH; + break; + case TX_SELE_LQ: + value = QUEUE_LOW; + break; + case TX_SELE_NQ: + value = QUEUE_NORMAL; + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + _InitNormalChipRegPriority(Adapter, + value, + value, + value, + value, + value, + value + ); + +} + +static VOID +_InitNormalChipTwoOutEpPriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + u16 beQ,bkQ,viQ,voQ,mgtQ,hiQ; + + + u16 valueHi = 0; + u16 valueLow = 0; + + switch(pHalData->OutEpQueueSel) + { + case (TX_SELE_HQ | TX_SELE_LQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_NQ | TX_SELE_LQ): + valueHi = QUEUE_NORMAL; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_HQ | TX_SELE_NQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_NORMAL; + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + if(!pregistrypriv->wifi_spec ){ + beQ = valueLow; + bkQ = valueLow; + viQ = valueHi; + voQ = valueHi; + mgtQ = valueHi; + hiQ = valueHi; + } + else{//for WMM ,CONFIG_OUT_EP_WIFI_MODE + beQ = valueLow; + bkQ = valueHi; + viQ = valueHi; + voQ = valueLow; + mgtQ = valueHi; + hiQ = valueHi; + } + + _InitNormalChipRegPriority(Adapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ); + +} + +static VOID +_InitNormalChipThreeOutEpPriority( + IN PADAPTER Adapter + ) +{ + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + u16 beQ,bkQ,viQ,voQ,mgtQ,hiQ; + + if(!pregistrypriv->wifi_spec ){// typical setting + beQ = QUEUE_LOW; + bkQ = QUEUE_LOW; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } + else{// for WMM + beQ = QUEUE_LOW; + bkQ = QUEUE_NORMAL; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } + _InitNormalChipRegPriority(Adapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ); +} + +static VOID +_InitNormalChipQueuePriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + switch(pHalData->OutEpNumber) + { + case 1: + _InitNormalChipOneOutEpPriority(Adapter); + break; + case 2: + _InitNormalChipTwoOutEpPriority(Adapter); + break; + case 3: + _InitNormalChipThreeOutEpPriority(Adapter); + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + +} + +static VOID +_InitQueuePriority( + IN PADAPTER Adapter + ) +{ + _InitNormalChipQueuePriority(Adapter); +} + +static VOID +_InitHardwareDropIncorrectBulkOut( + IN PADAPTER Adapter + ) +{ + u32 value32 = rtw_read32(Adapter, REG_TXDMA_OFFSET_CHK); + value32 |= DROP_DATA_EN; + rtw_write32(Adapter, REG_TXDMA_OFFSET_CHK, value32); +} + +static VOID +_InitNetworkType( + IN PADAPTER Adapter + ) +{ + u32 value32; + + value32 = rtw_read32(Adapter, REG_CR); + + // TODO: use the other function to set network type +#if RTL8191C_FPGA_NETWORKTYPE_ADHOC + value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AD_HOC); +#else + value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP); +#endif + rtw_write32(Adapter, REG_CR, value32); +// RASSERT(pIoBase->rtw_read8(REG_CR + 2) == 0x2); +} + +static VOID +_InitTransferPageSize( + IN PADAPTER Adapter + ) +{ + // Tx page size is always 128. + + u8 value8; + value8 = _PSRX(PBP_128) | _PSTX(PBP_128); + rtw_write8(Adapter, REG_PBP, value8); +} + +static VOID +_InitDriverInfoSize( + IN PADAPTER Adapter, + IN u8 drvInfoSize + ) +{ + rtw_write8(Adapter,REG_RX_DRVINFO_SZ, drvInfoSize); +} + +static VOID +_InitWMACSetting( + IN PADAPTER Adapter + ) +{ + //u4Byte value32; + //u16 value16; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + //pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | APP_FCS | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS; + //pHalData->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB |RCR_CBSSID_DATA| RCR_CBSSID_BCN| RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYSTS; + // don't turn on AAP, it will allow all packets to driver + pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB |RCR_CBSSID_DATA| RCR_CBSSID_BCN| RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYSTS; + +#if (0 == RTL8192C_RX_PACKET_NO_INCLUDE_CRC) + pHalData->ReceiveConfig |= ACRC32; +#endif + + // some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() + rtw_write32(Adapter, REG_RCR, pHalData->ReceiveConfig); + + // Accept all multicast address + rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF); + rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF); + + + // Accept all data frames + //value16 = 0xFFFF; + //rtw_write16(Adapter, REG_RXFLTMAP2, value16); + + // 2010.09.08 hpfan + // Since ADF is removed from RCR, ps-poll will not be indicate to driver, + // RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll. + //value16 = 0x400; + //rtw_write16(Adapter, REG_RXFLTMAP1, value16); + + // Accept all management frames + //value16 = 0xFFFF; + //rtw_write16(Adapter, REG_RXFLTMAP0, value16); + + //enable RX_SHIFT bits + //rtw_write8(Adapter, REG_TRXDMA_CTRL, rtw_read8(Adapter, REG_TRXDMA_CTRL)|BIT(1)); + +} + +static VOID +_InitAdaptiveCtrl( + IN PADAPTER Adapter + ) +{ + u16 value16; + u32 value32; + + // Response Rate Set + value32 = rtw_read32(Adapter, REG_RRSR); + value32 &= ~RATE_BITMAP_ALL; + value32 |= RATE_RRSR_CCK_ONLY_1M; + rtw_write32(Adapter, REG_RRSR, value32); + + // CF-END Threshold + //m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1); + + // SIFS (used in NAV) + value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); + rtw_write16(Adapter, REG_SPEC_SIFS, value16); + + // Retry Limit + value16 = _LRL(0x30) | _SRL(0x30); + rtw_write16(Adapter, REG_RL, value16); + +} + +static VOID +_InitRateFallback( + IN PADAPTER Adapter + ) +{ + // Set Data Auto Rate Fallback Retry Count register. + rtw_write32(Adapter, REG_DARFRC, 0x00000000); + rtw_write32(Adapter, REG_DARFRC+4, 0x10080404); + rtw_write32(Adapter, REG_RARFRC, 0x04030201); + rtw_write32(Adapter, REG_RARFRC+4, 0x08070605); + +} + + +static VOID +_InitEDCA( + IN PADAPTER Adapter + ) +{ + // Set Spec SIFS (used in NAV) + rtw_write16(Adapter,REG_SPEC_SIFS, 0x100a); + rtw_write16(Adapter,REG_MAC_SPEC_SIFS, 0x100a); + + //REG514:SIFS_CCK_CTX + //REG515:SIFS_OFDM_CTX + //REG516:SIFS_CCK_TRX + //REG517:SIFS_OFDM_TRX + + // Set SIFS for CCK_CTS and OFDM_CTX + rtw_write16(Adapter,REG_SIFS_CTX, 0x100a); + + // Set SIFS for CCK_TRX and OFDM_TRX + rtw_write16(Adapter,REG_SIFS_TRX, 0x100a); + + // TXOP + rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226); +} + + +static VOID +_InitBeaconMaxError( + IN PADAPTER Adapter, + IN BOOLEAN InfraMode + ) +{ +#ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING + rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); +#else + //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10)); +#endif +} + + +#ifdef CONFIG_LED +static void _InitHWLed(PADAPTER Adapter) +{ + struct led_priv *pledpriv = &(Adapter->ledpriv); + + if( pledpriv->LedStrategy != HW_LED) + return; + +// HW led control +// to do .... +//must consider cases of antenna diversity/ commbo card/solo card/mini card + +} +#endif //CONFIG_LED + +static VOID +_InitRDGSetting( + IN PADAPTER Adapter + ) +{ + rtw_write8(Adapter,REG_RD_CTRL,0xFF); + rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200); + rtw_write8(Adapter,REG_RD_RESP_PKT_TH,0x05); +} + +static VOID +_InitRxSetting( + IN PADAPTER Adapter + ) +{ + rtw_write32(Adapter, REG_MACID, 0x87654321); + rtw_write32(Adapter, 0x0700, 0x87654321); +} + +static VOID +_InitRetryFunction( + IN PADAPTER Adapter + ) +{ + u8 value8; + + value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL); + value8 |= EN_AMPDU_RTY_NEW; + rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8); + + // Set ACK timeout + rtw_write8(Adapter, REG_ACKTO, 0x40); +} + +/*----------------------------------------------------------------------------- + * Function: usb_AggSettingTxUpdate() + * + * Overview: Seperate TX/RX parameters update independent for TP detection and + * dynamic TX/RX aggreagtion parameters update. + * + * Input: PADAPTER + * + * Output/Return: NONE + * + * Revised History: + * When Who Remark + * 12/10/2010 MHC Seperate to smaller function. + * + *---------------------------------------------------------------------------*/ +static VOID +usb_AggSettingTxUpdate( + IN PADAPTER Adapter + ) +{ +#ifdef CONFIG_USB_TX_AGGREGATION + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u32 value32; + + if(Adapter->registrypriv.wifi_spec) + pHalData->UsbTxAggMode = _FALSE; + + if(pHalData->UsbTxAggMode){ + value32 = rtw_read32(Adapter, REG_TDECTRL); + value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT); + value32 |= ((pHalData->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT); + + rtw_write32(Adapter, REG_TDECTRL, value32); + } + +#endif +} // usb_AggSettingTxUpdate + + +/*----------------------------------------------------------------------------- + * Function: usb_AggSettingRxUpdate() + * + * Overview: Seperate TX/RX parameters update independent for TP detection and + * dynamic TX/RX aggreagtion parameters update. + * + * Input: PADAPTER + * + * Output/Return: NONE + * + * Revised History: + * When Who Remark + * 12/10/2010 MHC Seperate to smaller function. + * + *---------------------------------------------------------------------------*/ +static VOID +usb_AggSettingRxUpdate( + IN PADAPTER Adapter + ) +{ +#ifdef CONFIG_USB_RX_AGGREGATION + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u8 valueDMA; + u8 valueUSB; + + valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL); + valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION); + + switch(pHalData->UsbRxAggMode) + { + case USB_RX_AGG_DMA: + valueDMA |= RXDMA_AGG_EN; + valueUSB &= ~USB_AGG_EN; + break; + case USB_RX_AGG_USB: + valueDMA &= ~RXDMA_AGG_EN; + valueUSB |= USB_AGG_EN; + break; + case USB_RX_AGG_MIX: + valueDMA |= RXDMA_AGG_EN; + valueUSB |= USB_AGG_EN; + break; + case USB_RX_AGG_DISABLE: + default: + valueDMA &= ~RXDMA_AGG_EN; + valueUSB &= ~USB_AGG_EN; + break; + } + + rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA); + rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB); + + switch(pHalData->UsbRxAggMode) + { + case USB_RX_AGG_DMA: + rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, pHalData->UsbRxAggPageCount); + rtw_write8(Adapter, REG_USB_DMA_AGG_TO, pHalData->UsbRxAggPageTimeout); + break; + case USB_RX_AGG_USB: + rtw_write8(Adapter, REG_USB_AGG_TH, pHalData->UsbRxAggBlockCount); + rtw_write8(Adapter, REG_USB_AGG_TO, pHalData->UsbRxAggBlockTimeout); + break; + case USB_RX_AGG_MIX: + rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, pHalData->UsbRxAggPageCount); + rtw_write8(Adapter, REG_USB_DMA_AGG_TO, pHalData->UsbRxAggPageTimeout); + rtw_write8(Adapter, REG_USB_AGG_TH, pHalData->UsbRxAggBlockCount); + rtw_write8(Adapter, REG_USB_AGG_TO, pHalData->UsbRxAggBlockTimeout); + break; + case USB_RX_AGG_DISABLE: + default: + // TODO: + break; + } + + switch(PBP_128) + { + case PBP_128: + pHalData->HwRxPageSize = 128; + break; + case PBP_64: + pHalData->HwRxPageSize = 64; + break; + case PBP_256: + pHalData->HwRxPageSize = 256; + break; + case PBP_512: + pHalData->HwRxPageSize = 512; + break; + case PBP_1024: + pHalData->HwRxPageSize = 1024; + break; + default: + //RT_ASSERT(FALSE, ("RX_PAGE_SIZE_REG_VALUE definition is incorrect!\n")); + break; + } +#endif +} // usb_AggSettingRxUpdate + +static VOID +InitUsbAggregationSetting( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + // Tx aggregation setting + usb_AggSettingTxUpdate(Adapter); + + // Rx aggregation setting + usb_AggSettingRxUpdate(Adapter); + + // 201/12/10 MH Add for USB agg mode dynamic switch. + pHalData->UsbRxHighSpeedMode = _FALSE; +} + +/*----------------------------------------------------------------------------- + * Function: USB_AggModeSwitch() + * + * Overview: When RX traffic is more than 40M, we need to adjust some parameters to increase + * RX speed by increasing batch indication size. This will decrease TCP ACK speed, we + * need to monitor the influence of FTP/network share. + * For TX mode, we are still ubder investigation. + * + * Input: PADAPTER + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 12/10/2010 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +USB_AggModeSwitch( + IN PADAPTER Adapter + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + //pHalData->UsbRxHighSpeedMode = FALSE; + // How to measure the RX speed? We assume that when traffic is more than + if (pMgntInfo->bRegAggDMEnable == _FALSE) + { + return; // Inf not support. + } + + + if (pmlmepriv->LinkDetectInfo.bHigherBusyTraffic == _TRUE && + pHalData->UsbRxHighSpeedMode == _FALSE) + { + pHalData->UsbRxHighSpeedMode = _TRUE; + DBG_8192C("UsbAggModeSwitchCheck to HIGH\n"); + } + else if (pmlmepriv->LinkDetectInfo.bHigherBusyTraffic == _FALSE && + pHalData->UsbRxHighSpeedMode == _TRUE) + { + pHalData->UsbRxHighSpeedMode = _FALSE; + DBG_8192C("UsbAggModeSwitchCheck to LOW\n"); + } + else + { + return; + } + + // 2010/12/10 MH Add for USB Aggregation judgement we need to + //if( pMgntInfo->LinkDetectInfo.NumRxOkInPeriod > 4000 || + // pMgntInfo->LinkDetectInfo.NumTxOkInPeriod > 4000 ) + +#ifdef CONFIG_USB_TX_AGGREGATION + //usb_AggSettingTxUpdate(Adapter); +#endif + +#ifdef CONFIG_USB_RX_AGGREGATION + if (pHalData->UsbRxHighSpeedMode == _TRUE) + { + // 2010/12/10 MH The parameter is tested by SD1 engineer and SD3 channel emulator. + // USB mode + pHalData->UsbRxAggBlockCount = 40; + pHalData->UsbRxAggBlockTimeout = 5; + // Mix mode + pHalData->UsbRxAggPageCount = 72; + pHalData->UsbRxAggPageTimeout = 6; + } + else + { + // USB mode + pHalData->UsbRxAggBlockCount = pMgntInfo->RegUsbRxAggBlockCount; + pHalData->UsbRxAggBlockTimeout = pMgntInfo->RegUsbRxAggBlockTimeout; + // Mix mode + pHalData->UsbRxAggPageCount = pMgntInfo->RegUsbRxAggPageCount; + pHalData->UsbRxAggPageTimeout = pMgntInfo->RegUsbRxAggPageTimeout; + } +#endif +#endif +} // USB_AggModeSwitch + +static VOID +_InitOperationMode( + IN PADAPTER Adapter + ) +{ +#if 0//gtest + PHAL_DATA_8192CUSB pHalData = GetHalData8192CUsb(Adapter); + u1Byte regBwOpMode = 0; + u4Byte regRATR = 0, regRRSR = 0; + + + //1 This part need to modified according to the rate set we filtered!! + // + // Set RRSR, RATR, and REG_BWOPMODE registers + // + switch(Adapter->RegWirelessMode) + { + case WIRELESS_MODE_B: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK; + regRRSR = RATE_ALL_CCK; + break; + case WIRELESS_MODE_A: + ASSERT(FALSE); +#if 0 + regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ; + regRATR = RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_OFDM_AG; +#endif + break; + case WIRELESS_MODE_G: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_AUTO: + if (Adapter->bInHctTest) + { + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + } + else + { + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + } + break; + case WIRELESS_MODE_N_24G: + // It support CCK rate by default. + // CCK rate will be filtered out only when associated AP does not support it. + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_N_5G: + ASSERT(FALSE); +#if 0 + regBwOpMode = BW_OPMODE_5G; + regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_OFDM_AG; +#endif + break; + } + + // Ziv ???????? + //PlatformEFIOWrite4Byte(Adapter, REG_INIRTS_RATE_SEL, regRRSR); + PlatformEFIOWrite1Byte(Adapter, REG_BWOPMODE, regBwOpMode); + + // For Min Spacing configuration. + switch(pHalData->RF_Type) + { + case RF_1T2R: + case RF_1T1R: + RT_TRACE(COMP_INIT, DBG_LOUD, ("Initializeadapter: RF_Type%s\n", (pHalData->RF_Type==RF_1T1R? "(1T1R)":"(1T2R)"))); + Adapter->MgntInfo.MinSpaceCfg = (MAX_MSS_DENSITY_1T<<3); + break; + case RF_2T2R: + case RF_2T2R_GREEN: + RT_TRACE(COMP_INIT, DBG_LOUD, ("Initializeadapter:RF_Type(2T2R)\n")); + Adapter->MgntInfo.MinSpaceCfg = (MAX_MSS_DENSITY_2T<<3); + break; + } + + PlatformEFIOWrite1Byte(Adapter, REG_AMPDU_MIN_SPACE, Adapter->MgntInfo.MinSpaceCfg); +#endif +} + + + static VOID +_InitBeaconParameters( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + rtw_write16(Adapter, REG_BCN_CTRL, 0x1010); + + // TODO: Remove these magic number + rtw_write16(Adapter, REG_TBTT_PROHIBIT,0x6404);// ms + + rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);// 5ms + rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); // 2ms + + // Suggested by designer timchen. Change beacon AIFS to the largest number + // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 + rtw_write16(Adapter, REG_BCNTCFG, 0x660F); +} + +static VOID +_InitRFType( + IN PADAPTER Adapter + ) +{ + struct registry_priv *pregpriv = &Adapter->registrypriv; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BOOLEAN is92CU = IS_92C_SERIAL(pHalData->VersionID); + +#if DISABLE_BB_RF + pHalData->rf_chip = RF_PSEUDO_11N; + return; +#endif + + pHalData->rf_chip = RF_6052; + + if(_FALSE == is92CU){ + pHalData->rf_type = RF_1T1R; + DBG_8192C("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n"); + return; + } + + // TODO: Consider that EEPROM set 92CU to 1T1R later. + // Force to overwrite setting according to chip version. Ignore EEPROM setting. + //pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; + MSG_8192C("Set RF Chip ID to RF_6052 and RF type to %d.\n", pHalData->rf_type); + +} + +static VOID _InitAdhocWorkaroundParams(IN PADAPTER Adapter) +{ +#if RTL8192CU_ADHOC_WORKAROUND_SETTING + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + pHalData->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL); + pHalData->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE); + pHalData->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL+2); + pHalData->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT+2); +#endif +} + +static VOID +_BeaconFunctionEnable( + IN PADAPTER Adapter, + IN BOOLEAN Enable, + IN BOOLEAN Linked + ) +{ + rtw_write8(Adapter, REG_BCN_CTRL, (BIT4 | BIT3 | BIT1)); + //SetBcnCtrlReg(Adapter, (BIT4 | BIT3 | BIT1), 0x00); + //RT_TRACE(COMP_BEACON, DBG_LOUD, ("_BeaconFunctionEnable 0x550 0x%x\n", PlatformEFIORead1Byte(Adapter, 0x550))); + + rtw_write8(Adapter, REG_RD_CTRL+1, 0x6F); +} + + +// Set CCK and OFDM Block "ON" +static VOID _BBTurnOnBlock( + IN PADAPTER Adapter + ) +{ +#if (DISABLE_BB_RF) + return; +#endif + + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1); +} + +static VOID _RfPowerSave( + IN PADAPTER Adapter + ) +{ +#if 0 + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u1Byte eRFPath; + +#if (DISABLE_BB_RF) + return; +#endif + + if(pMgntInfo->RegRfOff == TRUE){ // User disable RF via registry. + RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter8192CUsb(): Turn off RF for RegRfOff.\n")); + MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW); + // Those action will be discard in MgntActSet_RF_State because off the same state + for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); + } + else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS){ // H/W or S/W RF OFF before sleep. + RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter8192CUsb(): Turn off RF for RfOffReason(%ld).\n", pMgntInfo->RfOffReason)); + MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason); + } + else{ + pHalData->eRFPowerState = eRfOn; + pMgntInfo->RfOffReason = 0; + if(Adapter->bInSetPower || Adapter->bResetInProgress) + PlatformUsbEnableInPipes(Adapter); + RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter8192CUsb(): RF is on.\n")); + } +#endif +} + +enum { + Antenna_Lfet = 1, + Antenna_Right = 2, +}; + +static VOID +_InitAntenna_Selection(IN PADAPTER Adapter) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(pHalData->AntDivCfg==0) + return; + DBG_8192C("==> %s ....\n",__FUNCTION__); + + if((RF_1T1R == pHalData->rf_type)) + { + rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0)|BIT23); + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT13, 0x01); + + if(PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A) + pHalData->CurAntenna = Antenna_A; + else + pHalData->CurAntenna = Antenna_B; + DBG_8192C("%s,Cur_ant:(%x)%s\n",__FUNCTION__,pHalData->CurAntenna,(pHalData->CurAntenna == Antenna_A)?"Antenna_A":"Antenna_B"); + +} + + +} +// +// 2010/08/09 MH Add for power down check. +// +static BOOLEAN +HalDetectPwrDownMode( + IN PADAPTER Adapter + ) +{ + u8 tmpvalue; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; + + EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_OPT3, (u32 *)&tmpvalue); + + // 2010/08/25 MH INF priority > PDN Efuse value. + if(tmpvalue & BIT4 && pwrctrlpriv->reg_pdnmode) + { + pHalData->pwrdown = _TRUE; + } + else + { + pHalData->pwrdown = _FALSE; + } + + DBG_8192C("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown); + return pHalData->pwrdown; + +} // HalDetectPwrDownMode + + +// +// 2010/08/26 MH Add for selective suspend mode check. +// If Efuse 0x0e bit1 is not enabled, we can not support selective suspend for Minicard and +// slim card. +// +static VOID +HalDetectSelectiveSuspendMode( + IN PADAPTER Adapter + ) +{ + u8 tmpvalue; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); + + // If support HW radio detect, we need to enable WOL ability, otherwise, we + // can not use FW to notify host the power state switch. + + EFUSE_ShadowRead(Adapter, 1, EEPROM_USB_OPTIONAL1, (u32 *)&tmpvalue); + + DBG_8192C("HalDetectSelectiveSuspendMode(): SS "); + if(tmpvalue & BIT1) + { + DBG_8192C("Enable\n"); + } + else + { + DBG_8192C("Disable\n"); + pdvobjpriv->RegUsbSS = _FALSE; + } + + // 2010/09/01 MH According to Dongle Selective Suspend INF. We can switch SS mode. + if (pdvobjpriv->RegUsbSS && !SUPPORT_HW_RADIO_DETECT(pHalData)) + { + //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + + //if (!pMgntInfo->bRegDongleSS) + //{ + // RT_TRACE(COMP_INIT, DBG_LOUD, ("Dongle disable SS\n")); + pdvobjpriv->RegUsbSS = _FALSE; + //} + } +} // HalDetectSelectiveSuspendMode +/*----------------------------------------------------------------------------- + * Function: HwSuspendModeEnable92Cu() + * + * Overview: HW suspend mode switch. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 08/23/2010 MHC HW suspend mode switch test.. + *---------------------------------------------------------------------------*/ +static VOID +HwSuspendModeEnable92Cu( + IN PADAPTER pAdapter, + IN u8 Type + ) +{ + //PRT_USB_DEVICE pDevice = GET_RT_USB_DEVICE(pAdapter); + u16 reg = rtw_read16(pAdapter, REG_GPIO_MUXCFG); + + //if (!pDevice->RegUsbSS) + { + return; + } + + // + // 2010/08/23 MH According to Alfred's suggestion, we need to to prevent HW + // to enter suspend mode automatically. Otherwise, it will shut down major power + // domain and 8051 will stop. When we try to enter selective suspend mode, we + // need to prevent HW to enter D2 mode aumotmatically. Another way, Host will + // issue a S10 signal to power domain. Then it will cleat SIC setting(from Yngli). + // We need to enable HW suspend mode when enter S3/S4 or disable. We need + // to disable HW suspend mode for IPS/radio_off. + // + //RT_TRACE(COMP_RF, DBG_LOUD, ("HwSuspendModeEnable92Cu = %d\n", Type)); + if (Type == _FALSE) + { + reg |= BIT14; + //RT_TRACE(COMP_RF, DBG_LOUD, ("REG_GPIO_MUXCFG = %x\n", reg)); + rtw_write16(pAdapter, REG_GPIO_MUXCFG, reg); + reg |= BIT12; + //RT_TRACE(COMP_RF, DBG_LOUD, ("REG_GPIO_MUXCFG = %x\n", reg)); + rtw_write16(pAdapter, REG_GPIO_MUXCFG, reg); + } + else + { + reg &= (~BIT12); + rtw_write16(pAdapter, REG_GPIO_MUXCFG, reg); + reg &= (~BIT14); + rtw_write16(pAdapter, REG_GPIO_MUXCFG, reg); + } + +} // HwSuspendModeEnable92Cu +rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 val8; + rt_rf_power_state rfpowerstate = rf_off; + + if(pAdapter->pwrctrlpriv.bHWPowerdown) + { + val8 = rtw_read8(pAdapter, REG_HSISR); + DBG_8192C("pwrdown, 0x5c(BIT7)=%02x\n", val8); + rfpowerstate = (val8 & BIT7) ? rf_off: rf_on; + } + else // rf on/off + { + rtw_write8( pAdapter, REG_MAC_PINMUX_CFG,rtw_read8(pAdapter, REG_MAC_PINMUX_CFG)&~(BIT3)); + val8 = rtw_read8(pAdapter, REG_GPIO_IO_SEL); + DBG_8192C("GPIO_IN=%02x\n", val8); + rfpowerstate = (val8 & BIT3) ? rf_on : rf_off; + } + return rfpowerstate; +} // HalDetectPwrDownMode + +void _ps_open_RF(_adapter *padapter); + + +u32 rtl8192cu_hal_init(PADAPTER Adapter) +{ + u8 val8 = 0; + u32 boundary, status = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + u8 is92C = IS_92C_SERIAL(pHalData->VersionID); + rt_rf_power_state eRfPowerStateToSet; +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); +#endif + + u32 init_start_time = rtw_get_current_time(); + + +#ifdef DBG_HAL_INIT_PROFILING + + enum HAL_INIT_STAGES { + HAL_INIT_STAGES_BEGIN = 0, + HAL_INIT_STAGES_INIT_PW_ON, + HAL_INIT_STAGES_MISC01, + HAL_INIT_STAGES_DOWNLOAD_FW, + HAL_INIT_STAGES_INIT_LLTT, + HAL_INIT_STAGES_MAC, + HAL_INIT_STAGES_MISC02, + HAL_INIT_STAGES_BB, + HAL_INIT_STAGES_RF, + HAL_INIT_STAGES_TURN_ON_BLOCK, + HAL_INIT_STAGES_INIT_SECURITY, + HAL_INIT_STAGES_MISC11, + //HAL_INIT_STAGES_RF_PS, + HAL_INIT_STAGES_IQK, + HAL_INIT_STAGES_PW_TRACK, + HAL_INIT_STAGES_LCK, + HAL_INIT_STAGES_MISC21, + HAL_INIT_STAGES_INIT_PABIAS, + HAL_INIT_STAGES_BT_COEXIST, + //HAL_INIT_STAGES_ANTENNA_SEL, + HAL_INIT_STAGES_INIT_HAL_DM, + HAL_INIT_STAGES_MISC31, + HAL_INIT_STAGES_END, + HAL_INIT_STAGES_NUM + }; + + char * hal_init_stages_str[] = { + "HAL_INIT_STAGES_BEGIN", + "HAL_INIT_STAGES_INIT_PW_ON", + "HAL_INIT_STAGES_MISC01", + "HAL_INIT_STAGES_DOWNLOAD_FW", + "HAL_INIT_STAGES_INIT_LLTT", + "HAL_INIT_STAGES_MAC", + "HAL_INIT_STAGES_MISC02", + "HAL_INIT_STAGES_BB", + "HAL_INIT_STAGES_RF", + "HAL_INIT_STAGES_TURN_ON_BLOCK", + "HAL_INIT_STAGES_INIT_SECURITY", + "HAL_INIT_STAGES_MISC11", + //"HAL_INIT_STAGES_RF_PS", + "HAL_INIT_STAGES_IQK", + "HAL_INIT_STAGES_PW_TRACK", + "HAL_INIT_STAGES_LCK", + "HAL_INIT_STAGES_MISC21", + "HAL_INIT_STAGES_INIT_PABIAS", + "HAL_INIT_STAGES_BT_COEXIST", + //"HAL_INIT_STAGES_ANTENNA_SEL", + "HAL_INIT_STAGES_INIT_HAL_DM", + "HAL_INIT_STAGES_MISC31", + "HAL_INIT_STAGES_END", + }; + + int hal_init_profiling_i; + u32 hal_init_stages_timestamp[HAL_INIT_STAGES_NUM]; //used to record the time of each stage's starting point + + for(hal_init_profiling_i=0;hal_init_profiling_ipwrctrlpriv.bkeepfwalive) + { + _ps_open_RF(Adapter); + + if(pHalData->bIQKInitialized ){ + rtl8192c_PHY_IQCalibrate(Adapter,_TRUE); + } + else{ + rtl8192c_PHY_IQCalibrate(Adapter,_FALSE); + pHalData->bIQKInitialized = _TRUE; + } + rtl8192c_dm_CheckTXPowerTracking(Adapter); + rtl8192c_PHY_LCCalibrate(Adapter); + + goto exit; + } + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON); + status = _InitPowerOn(Adapter); + if(status == _FAIL){ + RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init power on!\n")); + goto exit; + } + + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01); + _InitQueueReservedPage(Adapter); + _InitTxBufferBoundary(Adapter); + _InitQueuePriority(Adapter); + _InitPageBoundary(Adapter); + _InitTransferPageSize(Adapter); + + +#if ENABLE_USB_DROP_INCORRECT_OUT + _InitHardwareDropIncorrectBulkOut(Adapter); +#endif + + if(pHalData->bRDGEnable){ + _InitRDGSetting(Adapter); + } + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW); +#if (1 == MP_DRIVER) + _InitRxSetting(Adapter); + // Don't Download Firmware + Adapter->bFWReady = _FALSE; +#elif RTL8192CU_FW_DOWNLOAD_ENABLE + status = FirmwareDownload92C(Adapter,_FALSE); + if(status != _SUCCESS) + { + Adapter->bFWReady = _FALSE; + pHalData->fw_ractrl = _FALSE; + DBG_8192C("fw download fail!\n"); + goto exit; + } + else + { + Adapter->bFWReady = _TRUE; + pHalData->fw_ractrl = _TRUE; + DBG_8192C("fw download ok!\n"); + } +#endif + + InitializeFirmwareVars92C(Adapter); + + if(pwrctrlpriv->reg_rfoff == _TRUE){ + pwrctrlpriv->rf_pwrstate = rf_off; + } + + // 2010/08/09 MH We need to check if we need to turnon or off RF after detecting + // HW GPIO pin. Before PHY_RFConfig8192C. + //HalDetectPwrDownMode(Adapter); + // 2010/08/26 MH If Efuse does not support sective suspend then disable the function. + //HalDetectSelectiveSuspendMode(Adapter); + + // Set RF type for BB/RF configuration + _InitRFType(Adapter);//->_ReadRFType() + + // Save target channel + // Current Channel will be updated again later. + pHalData->CurrentChannel = 6;//default set to 6 + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT); + if(!pregistrypriv->wifi_spec){ + boundary = TX_PAGE_BOUNDARY; + } + else{// for WMM + boundary = WMM_NORMAL_TX_PAGE_BOUNDARY; + } + status = InitLLTTable(Adapter, boundary); + if(status == _FAIL){ + RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init LLT table\n")); + goto exit; + } + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC); +#if (HAL_MAC_ENABLE == 1) + status = PHY_MACConfig8192C(Adapter); + if(status == _FAIL) + { + goto exit; + } +#endif + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02); + // Get Rx PHY status in order to report RSSI and others. + _InitDriverInfoSize(Adapter, DRVINFO_SZ); + + _InitInterrupt(Adapter); + hal_init_macaddr(Adapter);//set mac_address + _InitNetworkType(Adapter);//set msr + _InitWMACSetting(Adapter); + _InitAdaptiveCtrl(Adapter); + _InitEDCA(Adapter); + _InitRateFallback(Adapter); + _InitRetryFunction(Adapter); + InitUsbAggregationSetting(Adapter); + _InitOperationMode(Adapter);//todo + _InitBeaconParameters(Adapter); + _InitBeaconMaxError(Adapter, _TRUE); + +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_TX_MCAST2UNI) + +#ifdef CONFIG_CHECK_AC_LIFETIME + // Enable lifetime check for the four ACs + rtw_write8(Adapter, REG_LIFETIME_EN, 0x0F); +#endif // CONFIG_CHECK_AC_LIFETIME + +#ifdef CONFIG_TX_MCAST2UNI + rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); // unit: 256us. 256ms + rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); // unit: 256us. 256ms +#else // CONFIG_TX_MCAST2UNI + rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x3000); // unit: 256us. 3s + rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x3000); // unit: 256us. 3s +#endif // CONFIG_TX_MCAST2UNI +#endif // CONFIG_CONCURRENT_MODE || CONFIG_TX_MCAST2UNI + + +#ifdef CONFIG_LED + _InitHWLed(Adapter); +#endif //CONFIG_LED + + // + //d. Initialize BB related configurations. + // + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); +#if (HAL_BB_ENABLE == 1) + status = PHY_BBConfig8192C(Adapter); + if(status == _FAIL) + { + goto exit; + } +#endif + + // 92CU use 3-wire to r/w RF + //pHalData->Rf_Mode = RF_OP_By_SW_3wire; + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF); +#if (HAL_RF_ENABLE == 1) + status = PHY_RFConfig8192C(Adapter); + if(status == _FAIL) + { + goto exit; + } + + if(IS_VENDOR_UMC_A_CUT(pHalData->VersionID) && !IS_92C_SERIAL(pHalData->VersionID)) + { + PHY_SetRFReg(Adapter, RF_PATH_A, RF_RX_G1, bMaskDWord, 0x30255); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_RX_G2, bMaskDWord, 0x50a00); + } +#endif + + // + // Joseph Note: Keep RfRegChnlVal for later use. + // + pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (RF_RADIO_PATH_E)0, RF_CHNLBW, bRFRegOffsetMask); + pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (RF_RADIO_PATH_E)1, RF_CHNLBW, bRFRegOffsetMask); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK); + _BBTurnOnBlock(Adapter); + //NicIFSetMacAddress(padapter, padapter->PermanentAddress); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY); + invalidate_cam_all(Adapter); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11); + // 2010/12/17 MH We need to set TX power according to EFUSE content at first. + PHY_SetTxPowerLevel8192C(Adapter, pHalData->CurrentChannel); + +// Move by Neo for USB SS to below setp +//_RfPowerSave(Adapter); + + if (!IS_92C_SERIAL( pHalData->VersionID) && (pHalData->AntDivCfg!=0)) + { //for 88CU ,1T1R + _InitAntenna_Selection(Adapter); + } + + + // + // Disable BAR, suggested by Scott + // 2010.04.09 add by hpfan + // + rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff); + + // HW SEQ CTRL + //set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. + rtw_write8(Adapter,REG_HWSEQ_CTRL, 0xFF); + + if(pregistrypriv->wifi_spec) + rtw_write16(Adapter,REG_FAST_EDCA_CTRL ,0); + + //Nav limit , suggest by scott + rtw_write8(Adapter, 0x652, 0x0); + +#if (MP_DRIVER == 1) + Adapter->mppriv.channel = pHalData->CurrentChannel; + MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel); +#else + // + // 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status + // and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not + // call init_adapter. May cause some problem?? + // + // Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed + // in MgntActSet_RF_State() after wake up, because the value of pHalData->eRFPowerState + // is the same as eRfOff, we should change it to eRfOn after we config RF parameters. + // Added by tynli. 2010.03.30. + pwrctrlpriv->rf_pwrstate = rf_on; + +#if 0 //to do + RT_CLEAR_PS_LEVEL(pwrctrlpriv, RT_RF_OFF_LEVL_HALT_NIC); +#if 1 //Todo + // 20100326 Joseph: Copy from GPIOChangeRFWorkItemCallBack() function to check HW radio on/off. + // 20100329 Joseph: Revise and integrate the HW/SW radio off code in initialization. + + eRfPowerStateToSet = (rt_rf_power_state) RfOnOffDetect(Adapter); + pwrctrlpriv->rfoff_reason |= eRfPowerStateToSet==rf_on ? RF_CHANGE_BY_INIT : RF_CHANGE_BY_HW; + pwrctrlpriv->rfoff_reason |= (pwrctrlpriv->reg_rfoff) ? RF_CHANGE_BY_SW : 0; + + if(pwrctrlpriv->rfoff_reason&RF_CHANGE_BY_HW) + pwrctrlpriv->b_hw_radio_off = _TRUE; + + DBG_8192C("eRfPowerStateToSet=%d\n", eRfPowerStateToSet); + + if(pwrctrlpriv->reg_rfoff == _TRUE) + { // User disable RF via registry. + DBG_8192C("InitializeAdapter8192CU(): Turn off RF for RegRfOff.\n"); + //MgntActSet_RF_State(Adapter, rf_off, RF_CHANGE_BY_SW, _TRUE); + + // Those action will be discard in MgntActSet_RF_State because off the same state + //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) + //PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); + } + else if(pwrctrlpriv->rfoff_reason > RF_CHANGE_BY_PS) + { // H/W or S/W RF OFF before sleep. + DBG_8192C(" Turn off RF for RfOffReason(%x) ----------\n", pwrctrlpriv->rfoff_reason); + //pwrctrlpriv->rfoff_reason = RF_CHANGE_BY_INIT; + pwrctrlpriv->rf_pwrstate = rf_on; + //MgntActSet_RF_State(Adapter, rf_off, pwrctrlpriv->rfoff_reason, _TRUE); + } + else + { + // Perform GPIO polling to find out current RF state. added by Roger, 2010.04.09. + if(pHalData->BoardType == BOARD_MINICARD /*&& (Adapter->MgntInfo.PowerSaveControl.bGpioRfSw)*/) + { + DBG_8192C("InitializeAdapter8192CU(): RF=%d \n", eRfPowerStateToSet); + if (eRfPowerStateToSet == rf_off) + { + //MgntActSet_RF_State(Adapter, rf_off, RF_CHANGE_BY_HW, _TRUE); + pwrctrlpriv->b_hw_radio_off = _TRUE; + } + else + { + pwrctrlpriv->rf_pwrstate = rf_off; + pwrctrlpriv->rfoff_reason = RF_CHANGE_BY_INIT; + pwrctrlpriv->b_hw_radio_off = _FALSE; + //MgntActSet_RF_State(Adapter, rf_on, pwrctrlpriv->rfoff_reason, _TRUE); + } + } + else + { + pwrctrlpriv->rf_pwrstate = rf_off; + pwrctrlpriv->rfoff_reason = RF_CHANGE_BY_INIT; + //MgntActSet_RF_State(Adapter, rf_on, pwrctrlpriv->rfoff_reason, _TRUE); + } + + pwrctrlpriv->rfoff_reason = 0; + pwrctrlpriv->b_hw_radio_off = _FALSE; + pwrctrlpriv->rf_pwrstate = rf_on; + rtw_led_control(Adapter, LED_CTL_POWER_ON); + + } + + // 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. + // Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1. + if(pHalData->pwrdown && eRfPowerStateToSet == rf_off) + { + // Enable register area 0x0-0xc. + rtw_write8(Adapter, REG_RSV_CTRL, 0x0); + + // + // We should configure HW PDn source for WiFi ONLY, and then + // our HW will be set in power-down mode if PDn source from all functions are configured. + // 2010.10.06. + // + //if(IS_HARDWARE_TYPE_8723AU(Adapter)) + //{ + // u1bTmp = rtw_read8(Adapter, REG_MULTI_FUNC_CTRL); + // rtw_write8(Adapter, REG_MULTI_FUNC_CTRL, (u1bTmp|WL_HWPDN_EN)); + //} + //else + //{ + rtw_write16(Adapter, REG_APS_FSMCO, 0x8812); + //} + } + //DrvIFIndicateCurrentPhyStatus(Adapter); // 2010/08/17 MH Disable to prevent BSOD. +#endif +#endif + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK); + // 2010/08/26 MH Merge from 8192CE. + if(pwrctrlpriv->rf_pwrstate == rf_on) + { + if(pHalData->bIQKInitialized ){ + rtl8192c_PHY_IQCalibrate(Adapter,_TRUE); + } + else + { + rtl8192c_PHY_IQCalibrate(Adapter,_FALSE); + pHalData->bIQKInitialized = _TRUE; + } + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK); + rtl8192c_dm_CheckTXPowerTracking(Adapter); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK); + rtl8192c_PHY_LCCalibrate(Adapter); + } +#endif /* #if (MP_DRIVER == 1) */ + + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC21); +#if RTL8192CU_ADHOC_WORKAROUND_SETTING + _InitAdhocWorkaroundParams(Adapter); +#endif + + +#ifdef USB_INTERFERENCE_ISSUE + //fixed USB interface interference issue + rtw_write8(Adapter, 0xfe40, 0xe0); + rtw_write8(Adapter, 0xfe41, 0x8d); + rtw_write8(Adapter, 0xfe42, 0x80); + rtw_write32(Adapter,0x20c,0xfd0320); +#if 1 + //2011/01/07 ,suggest by Johnny,for solved the problem that too many protocol error on USB bus + if(!IS_VENDOR_UMC_A_CUT(pHalData->VersionID) )//&& !IS_92C_SERIAL(pHalData->VersionID))// TSMC , 8188 + { + // 0xE6=0x94 + rtw_write8(Adapter, 0xFE40, 0xE6); + rtw_write8(Adapter, 0xFE41, 0x94); + rtw_write8(Adapter, 0xFE42, 0x80); + + // 0xE0=0x19 + rtw_write8(Adapter, 0xFE40, 0xE0); + rtw_write8(Adapter, 0xFE41, 0x19); + rtw_write8(Adapter, 0xFE42, 0x80); + + // 0xE5=0x91 + rtw_write8(Adapter, 0xFE40, 0xE5); + rtw_write8(Adapter, 0xFE41, 0x91); + rtw_write8(Adapter, 0xFE42, 0x80); + + // 0xE2=0x81 + rtw_write8(Adapter, 0xFE40, 0xE2); + rtw_write8(Adapter, 0xFE41, 0x81); + rtw_write8(Adapter, 0xFE42, 0x80); + + } + +#endif +#endif //USB_INTERFERENCE_ISSUE + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); + _InitPABias(Adapter); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BT_COEXIST); +#ifdef CONFIG_BT_COEXIST + _InitBTCoexist(Adapter); +#endif + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM); + rtl8192c_InitHalDm(Adapter); + + // 2010/08/23 MH According to Alfred's suggestion, we need to to prevent HW enter + // suspend mode automatically. + //HwSuspendModeEnable92Cu(Adapter, _FALSE); + +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC31); + rtw_write8(Adapter, 0x15, 0xe9);//suggest by Johnny for lower temperature + + rtw_write8(Adapter, 0xc87, 0x50);//suggest by Jackson for CCA + + //_dbg_dump_macreg(padapter); + + rtw_write16(Adapter, REG_BCN_CTRL, 0x1818); // For 2 PORT TSF SYNC + + + +#ifdef CONFIG_XMIT_ACK + //ack for xmit mgmt frames. + rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12)); +#endif //CONFIG_XMIT_ACK + +exit: +HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); + + DBG_871X("%s in %dms\n", __FUNCTION__, rtw_get_passing_time_ms(init_start_time)); + + #ifdef DBG_HAL_INIT_PROFILING + hal_init_stages_timestamp[HAL_INIT_STAGES_END]=rtw_get_current_time(); + + for(hal_init_profiling_i=0;hal_init_profiling_irf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x380038, 1); + else + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 1); + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 0); + + //AFE + //DbgPrint("0x0e70 = %x\n", Adapter->PS_BBRegBackup[PSBBREG_AFE0]); + //PHY_SetBBReg(Adapter, 0x0e70, bMaskDWord ,Adapter->PS_BBRegBackup[PSBBREG_AFE0] ); + //PHY_SetBBReg(Adapter, 0x0e70, bMaskDWord ,0x631B25A0 ); + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x63DB25A0 ); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x631B25A0 ); + + // 4. issue 3-wire command that RF set to Rx idle mode. This is used to re-write the RX idle mode. + // We can only prvide a usual value instead and then HW will modify the value by itself. + PHY_SetRFReg(Adapter,RF_PATH_A, 0, bRFRegOffsetMask,0x32D95); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetRFReg(Adapter,RF_PATH_B, 0, bRFRegOffsetMask,0x32D95); + } + } + else // Level 2 or others. + { + //h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL + rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x81); + + // i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK + rtw_write16(Adapter, REG_AFE_XTAL_CTRL, 0x800F); + rtw_mdelay_os(1); + + // 1. Enable MAC Clock. Can not be enabled now. + //WriteXBYTE(REG_SYS_CLKR+1, ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); + + // 2. Force PWM, Enable SPS18_LDO_Marco_Block + rtw_write8(Adapter, REG_SPS0_CTRL, + rtw_read8(Adapter, REG_SPS0_CTRL) | (BIT0|BIT3)); + + // 3. restore BB, AFE control register. + //RF + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x380038, 1); + else + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 1); + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 0); + + //AFE + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x63DB25A0 ); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x631B25A0 ); + + // 4. issue 3-wire command that RF set to Rx idle mode. This is used to re-write the RX idle mode. + // We can only prvide a usual value instead and then HW will modify the value by itself. + PHY_SetRFReg(Adapter,RF_PATH_A, 0, bRFRegOffsetMask,0x32D95); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetRFReg(Adapter,RF_PATH_B, 0, bRFRegOffsetMask,0x32D95); + } + + // 5. gated MAC Clock + //WriteXBYTE(REG_SYS_CLKR+1, ReadXBYTE(REG_SYS_CLKR+1) & ~(BIT(3))); + //PlatformEFIOWrite1Byte(Adapter, REG_SYS_CLKR+1, PlatformEFIORead1Byte(Adapter, REG_SYS_CLKR+1)|(BIT3)); + + { + //u8 eRFPath = RF_PATH_A,value8 = 0, retry = 0; + u8 bytetmp; + //PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, 0x0, bMaskByte0, 0x0); + // 2010/08/12 MH Add for B path under SS test. + //if (pHalData->RF_Type == RF_2T2R) + //PHY_SetRFReg(Adapter, RF_PATH_B, 0x0, bMaskByte0, 0x0); + + bytetmp = rtw_read8(Adapter, REG_APSD_CTRL); + rtw_write8(Adapter, REG_APSD_CTRL, bytetmp & ~BIT6); + + rtw_mdelay_os(10); + + // Set BB reset at first + rtw_write8(Adapter, REG_SYS_FUNC_EN, 0x17 );//0x16 + //undo clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)&(~BIT31)); + // Enable TX + rtw_write8(Adapter, REG_TXPAUSE, 0x0); + } + //Adapter->HalFunc.InitializeAdapterHandler(Adapter, Adapter->MgntInfo.dot11CurrentChannelNumber); + //CardSelectiveSuspendLeave(Adapter); + } + + break; + + case rf_sleep: + case rf_off: + value8 = rtw_read8(Adapter, REG_SPS0_CTRL) ; + if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) + value8 &= ~(BIT0); + else + value8 &= ~(BIT0|BIT3); + if (bRegSSPwrLvl == 1) + { + //RT_TRACE(COMP_POWER, DBG_LOUD, ("SS LVL1\n")); + // Disable RF and BB only for SelectSuspend. + + // 1. Set BB/RF to shutdown. + // (1) Reg878[5:3]= 0 // RF rx_code for preamble power saving + // (2)Reg878[21:19]= 0 //Turn off RF-B + // (3) RegC04[7:4]= 0 // turn off all paths for packet detection + // (4) Reg800[1] = 1 // enable preamble power saving + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x380038, 0); + } + else if (pHalData->rf_type == RF_1T1R) + { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0); + } + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1,1); + + // 2 .AFE control register to power down. bit[30:22] + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = PHY_QueryBBReg(Adapter, rRx_Wait_CCA, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x00DB25A0); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x001B25A0); + + // 3. issue 3-wire command that RF set to power down. + PHY_SetRFReg(Adapter,RF_PATH_A, 0, bRFRegOffsetMask,0); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetRFReg(Adapter,RF_PATH_B, 0, bRFRegOffsetMask,0); + } + + // 4. Force PFM , disable SPS18_LDO_Marco_Block + rtw_write8(Adapter, REG_SPS0_CTRL, value8); + + // 5. gated MAC Clock + //WriteXBYTE(REG_SYS_CLKR+1, ReadXBYTE(REG_SYS_CLKR+1) & ~(BIT(3))); + } + else // Level 2 or others. + { + //RT_TRACE(COMP_POWER, DBG_LOUD, ("SS LVL2\n")); + { + u8 eRFPath = RF_PATH_A,value8 = 0; + rtw_write8(Adapter, REG_TXPAUSE, 0xFF); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, 0x0, bMaskByte0, 0x0); + // 2010/08/12 MH Add for B path under SS test. + //if (pHalData->RF_Type == RF_2T2R) + //PHY_SetRFReg(Adapter, RF_PATH_B, 0x0, bMaskByte0, 0x0); + + value8 |= APSDOFF; + rtw_write8(Adapter, REG_APSD_CTRL, value8);//0x40 + + // After switch APSD, we need to delay for stability + rtw_mdelay_os(10); + //before BB reset should do clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)|(BIT31)); + // Set BB reset at first + value8 = 0 ; + value8 |=( FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); + rtw_write8(Adapter, REG_SYS_FUNC_EN,value8 );//0x16 + } + + // Disable RF and BB only for SelectSuspend. + + // 1. Set BB/RF to shutdown. + // (1) Reg878[5:3]= 0 // RF rx_code for preamble power saving + // (2)Reg878[21:19]= 0 //Turn off RF-B + // (3) RegC04[7:4]= 0 // turn off all paths for packet detection + // (4) Reg800[1] = 1 // enable preamble power saving + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskDWord); + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x380038, 0); + } + else if (pHalData->rf_type == RF_1T1R) + { + PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0); + } + PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1,1); + + // 2 .AFE control register to power down. bit[30:22] + Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = PHY_QueryBBReg(Adapter, rRx_Wait_CCA, bMaskDWord); + if (pHalData->rf_type == RF_2T2R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x00DB25A0); + else if (pHalData->rf_type == RF_1T1R) + PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord ,0x001B25A0); + + // 3. issue 3-wire command that RF set to power down. + PHY_SetRFReg(Adapter,RF_PATH_A, 0, bRFRegOffsetMask,0); + if (pHalData->rf_type == RF_2T2R) + { + PHY_SetRFReg(Adapter,RF_PATH_B, 0, bRFRegOffsetMask,0); + } + + // 4. Force PFM , disable SPS18_LDO_Marco_Block + rtw_write8(Adapter, REG_SPS0_CTRL, value8); + + // 2010/10/13 MH/Isaachsu exchange sequence. + //h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL + rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x80); + rtw_mdelay_os(1); + + // i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK + rtw_write16(Adapter, REG_AFE_XTAL_CTRL, 0xA80F); + + // 5. gated MAC Clock + //WriteXBYTE(REG_SYS_CLKR+1, ReadXBYTE(REG_SYS_CLKR+1) & ~(BIT(3))); + //PlatformEFIOWrite1Byte(Adapter, REG_SYS_CLKR+1, PlatformEFIORead1Byte(Adapter, REG_SYS_CLKR+1)& ~(BIT3)) + + //CardSelectiveSuspendEnter(Adapter); + } + + break; + + default: + break; + } + +} // phy_PowerSwitch92CU + +void _ps_open_RF(_adapter *padapter) { + //here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified + phy_SsPwrSwitch92CU(padapter, rf_on, 1); +} + +void _ps_close_RF(_adapter *padapter){ + //here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified + phy_SsPwrSwitch92CU(padapter, rf_off, 1); +} +#endif //SYNC_SD7_20110802_phy_SsPwrSwitch92CU + + + +static VOID +_DisableGPIO( + IN PADAPTER Adapter + ) +{ +/*************************************** +j. GPIO_PIN_CTRL 0x44[31:0]=0x000 // +k. Value = GPIO_PIN_CTRL[7:0] +l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level +m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 +n. LEDCFG 0x4C[15:0] = 0x8080 +***************************************/ + u8 value8; + u16 value16; + u32 value32; + + //1. Disable GPIO[7:0] + rtw_write16(Adapter, REG_GPIO_PIN_CTRL+2, 0x0000); + value32 = rtw_read32(Adapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; + value8 = (u8) (value32&0x000000FF); + value32 |= ((value8<<8) | 0x00FF0000); + rtw_write32(Adapter, REG_GPIO_PIN_CTRL, value32); + + //2. Disable GPIO[10:8] + rtw_write8(Adapter, REG_GPIO_MUXCFG+3, 0x00); + value16 = rtw_read16(Adapter, REG_GPIO_MUXCFG+2) & 0xFF0F; + value8 = (u8) (value16&0x000F); + value16 |= ((value8<<4) | 0x0780); + rtw_write16(Adapter, REG_GPIO_MUXCFG+2, value16); + + //3. Disable LED0 & 1 + rtw_write16(Adapter, REG_LEDCFG0, 0x8080); + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n")); + +} //end of _DisableGPIO() + +static VOID +_ResetFWDownloadRegister( + IN PADAPTER Adapter + ) +{ + u32 value32; + + value32 = rtw_read32(Adapter, REG_MCUFWDL); + value32 &= ~(MCUFWDL_EN | MCUFWDL_RDY); + rtw_write32(Adapter, REG_MCUFWDL, value32); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Reset FW download register.\n")); +} + + +static int +_DisableRF_AFE( + IN PADAPTER Adapter + ) +{ + int rtStatus = _SUCCESS; + u32 pollingCount = 0; + u8 value8; + + //disable RF/ AFE AD/DA + value8 = APSDOFF; + rtw_write8(Adapter, REG_APSD_CTRL, value8); + + +#if (RTL8192CU_ASIC_VERIFICATION) + + do + { + if(rtw_read8(Adapter, REG_APSD_CTRL) & APSDOFF_STATUS){ + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Disable RF, AFE, AD, DA Done!\n")); + break; + } + + if(pollingCount++ > POLLING_READY_TIMEOUT_COUNT){ + //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Failed to polling APSDOFF_STATUS done!\n")); + return _FAIL; + } + + }while(_TRUE); + +#endif + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Disable RF, AFE,AD, DA.\n")); + return rtStatus; + +} + +static VOID +_ResetBB( + IN PADAPTER Adapter + ) +{ + u16 value16; + + //before BB reset should do clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)|(BIT31)); + //reset BB + value16 = rtw_read16(Adapter, REG_SYS_FUNC_EN); + value16 &= ~(FEN_BBRSTB | FEN_BB_GLB_RSTn); + rtw_write16(Adapter, REG_SYS_FUNC_EN, value16); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Reset BB.\n")); +} + +static VOID +_ResetMCU( + IN PADAPTER Adapter + ) +{ + u16 value16; + + // reset MCU + value16 = rtw_read16(Adapter, REG_SYS_FUNC_EN); + value16 &= ~FEN_CPUEN; + rtw_write16(Adapter, REG_SYS_FUNC_EN, value16); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Reset MCU.\n")); +} + +static VOID +_DisableMAC_AFE_PLL( + IN PADAPTER Adapter + ) +{ + u32 value32; + + //disable MAC/ AFE PLL + value32 = rtw_read32(Adapter, REG_APS_FSMCO); + value32 |= APDM_MAC; + rtw_write32(Adapter, REG_APS_FSMCO, value32); + + value32 |= APFM_OFF; + rtw_write32(Adapter, REG_APS_FSMCO, value32); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Disable MAC, AFE PLL.\n")); +} + +static VOID +_AutoPowerDownToHostOff( + IN PADAPTER Adapter + ) +{ + u32 value32; + rtw_write8(Adapter, REG_SPS0_CTRL, 0x22); + + value32 = rtw_read32(Adapter, REG_APS_FSMCO); + + value32 |= APDM_HOST;//card disable + rtw_write32(Adapter, REG_APS_FSMCO, value32); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Auto Power Down to Host-off state.\n")); + + // set USB suspend + value32 = rtw_read32(Adapter, REG_APS_FSMCO); + value32 &= ~AFSM_PCIE; + rtw_write32(Adapter, REG_APS_FSMCO, value32); + +} + +static VOID +_SetUsbSuspend( + IN PADAPTER Adapter + ) +{ + u32 value32; + + value32 = rtw_read32(Adapter, REG_APS_FSMCO); + + // set USB suspend + value32 |= AFSM_HSUS; + rtw_write32(Adapter, REG_APS_FSMCO, value32); + + //RT_ASSERT(0 == (rtw_read32(Adapter, REG_APS_FSMCO) & BIT(12)),("")); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("Set USB suspend.\n")); + +} + +static VOID +_DisableRFAFEAndResetBB( + IN PADAPTER Adapter + ) +{ +/************************************** +a. TXPAUSE 0x522[7:0] = 0xFF //Pause MAC TX queue +b. RF path 0 offset 0x00 = 0x00 // disable RF +c. APSD_CTRL 0x600[7:0] = 0x40 +d. SYS_FUNC_EN 0x02[7:0] = 0x16 //reset BB state machine +e. SYS_FUNC_EN 0x02[7:0] = 0x14 //reset BB state machine +***************************************/ + u8 eRFPath = 0,value8 = 0; + rtw_write8(Adapter, REG_TXPAUSE, 0xFF); + PHY_SetRFReg(Adapter, (RF_RADIO_PATH_E)eRFPath, 0x0, bMaskByte0, 0x0); + + value8 |= APSDOFF; + rtw_write8(Adapter, REG_APSD_CTRL, value8);//0x40 + //before BB reset should do clock gated + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)|(BIT31)); + value8 = 0 ; + value8 |=( FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); + rtw_write8(Adapter, REG_SYS_FUNC_EN,value8 );//0x16 + + value8 &=( ~FEN_BB_GLB_RSTn ); + rtw_write8(Adapter, REG_SYS_FUNC_EN, value8); //0x14 + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); +} + +static VOID +_ResetDigitalProcedure1( + IN PADAPTER Adapter, + IN BOOLEAN bWithoutHWSM + ) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(pHalData->FirmwareVersion <= 0x20){ + #if 0 + /***************************** + f. SYS_FUNC_EN 0x03[7:0]=0x54 // reset MAC register, DCORE + g. MCUFWDL 0x80[7:0]=0 // reset MCU ready status + ******************************/ + u4Byte value32 = 0; + PlatformIOWrite1Byte(Adapter, REG_SYS_FUNC_EN+1, 0x54); + PlatformIOWrite1Byte(Adapter, REG_MCUFWDL, 0); + #else + /***************************** + f. MCUFWDL 0x80[7:0]=0 // reset MCU ready status + g. SYS_FUNC_EN 0x02[10]= 0 // reset MCU register, (8051 reset) + h. SYS_FUNC_EN 0x02[15-12]= 5 // reset MAC register, DCORE + i. SYS_FUNC_EN 0x02[10]= 1 // enable MCU register, (8051 enable) + ******************************/ + u16 valu16 = 0; + rtw_write8(Adapter, REG_MCUFWDL, 0); + + valu16 = rtw_read16(Adapter, REG_SYS_FUNC_EN); + rtw_write16(Adapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051 + + valu16 = rtw_read16(Adapter, REG_SYS_FUNC_EN)&0x0FFF; + rtw_write16(Adapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC + + #ifdef DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE + { + u8 val; + if( (val=rtw_read8(Adapter, REG_MCUFWDL))) + DBG_871X("DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE %s:%d REG_MCUFWDL:0x%02x\n", __FUNCTION__, __LINE__, val); + } + #endif + + + valu16 = rtw_read16(Adapter, REG_SYS_FUNC_EN); + rtw_write16(Adapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051 + + + #endif + } + else{ + u8 retry_cnts = 0; + + if(rtw_read8(Adapter, REG_MCUFWDL) & BIT1) + { //IF fw in RAM code, do reset + + rtw_write8(Adapter, REG_MCUFWDL, 0); + if(Adapter->bFWReady){ + // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other + // HRCV INT to influence 8051 reset. + rtw_write8(Adapter, REG_FWIMR, 0x20); + + rtw_write8(Adapter, REG_HMETFR+3, 0x20);//8051 reset by self + + while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(Adapter, REG_SYS_FUNC_EN))) + { + rtw_udelay_os(50);//PlatformStallExecution(50);//us + } + + if(retry_cnts >= 100){ + DBG_8192C("%s #####=> 8051 reset failed!.........................\n", __FUNCTION__); + // if 8051 reset fail we trigger GPIO 0 for LA + //PlatformEFIOWrite4Byte( Adapter, + // REG_GPIO_PIN_CTRL, + // 0x00010100); + // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly. + rtw_write8(Adapter, REG_SYS_FUNC_EN+1, 0x50); //Reset MAC and Enable 8051 + rtw_mdelay_os(10); + } + else { + //DBG_871X("%s =====> 8051 reset success (%d) .\n", __FUNCTION__, retry_cnts); + } + } + else { + DBG_871X("%s =====> 8051 in RAM but !Adapter->bFWReady\n", __FUNCTION__); + } + } + else{ + //DBG_871X("%s =====> 8051 in ROM.\n", __FUNCTION__); + } + + #ifdef DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE + { + u8 val; + if( (val=rtw_read8(Adapter, REG_MCUFWDL))) + DBG_871X("DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE %s:%d REG_MCUFWDL:0x%02x\n", __FUNCTION__, __LINE__, val); + } + #endif + + rtw_write8(Adapter, REG_SYS_FUNC_EN+1, 0x54); //Reset MAC and Enable 8051 + } + + // Clear rpwm value for initial toggle bit trigger. + rtw_write8(Adapter, REG_USB_HRPWM, 0x00); + + if(bWithoutHWSM){ + /***************************** + Without HW auto state machine + g. SYS_CLKR 0x08[15:0] = 0x30A3 //disable MAC clock + h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL + i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK + j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 // isolated digital to PON + ******************************/ + //rtw_write16(Adapter, REG_SYS_CLKR, 0x30A3); + rtw_write16(Adapter, REG_SYS_CLKR, 0x70A3);//modify to 0x70A3 by Scott. + rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x80); + rtw_write16(Adapter, REG_AFE_XTAL_CTRL, 0x880F); + rtw_write8(Adapter, REG_SYS_ISO_CTRL, 0xF9); + } + else + { + // Disable all RF/BB power + rtw_write8(Adapter, REG_RF_CTRL, 0x00); + } + //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n")); + +} + +static VOID +_ResetDigitalProcedure2( + IN PADAPTER Adapter +) +{ +/***************************** +k. SYS_FUNC_EN 0x03[7:0] = 0x44 // disable ELDR runction +l. SYS_CLKR 0x08[15:0] = 0x3083 // disable ELDR clock +m. SYS_ISO_CTRL 0x01[7:0] = 0x83 // isolated ELDR to PON +******************************/ + //rtw_write8(Adapter, REG_SYS_FUNC_EN+1, 0x44);//marked by Scott. + //rtw_write16(Adapter, REG_SYS_CLKR, 0x3083); + //rtw_write8(Adapter, REG_SYS_ISO_CTRL+1, 0x83); + + rtw_write16(Adapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott. + rtw_write8(Adapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott. +} + +static VOID +_DisableAnalog( + IN PADAPTER Adapter, + IN BOOLEAN bWithoutHWSM + ) +{ + u16 value16 = 0; + u8 value8=0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(bWithoutHWSM){ + /***************************** + n. LDOA15_CTRL 0x20[7:0] = 0x04 // disable A15 power + o. LDOV12D_CTRL 0x21[7:0] = 0x54 // disable digital core power + r. When driver call disable, the ASIC will turn off remaining clock automatically + ******************************/ + + rtw_write8(Adapter, REG_LDOA15_CTRL, 0x04); + //PlatformIOWrite1Byte(Adapter, REG_LDOV12D_CTRL, 0x54); + + value8 = rtw_read8(Adapter, REG_LDOV12D_CTRL); + value8 &= (~LDV12_EN); + rtw_write8(Adapter, REG_LDOV12D_CTRL, value8); + //RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8)); + } + +/***************************** +h. SPS0_CTRL 0x11[7:0] = 0x23 //enter PFM mode +i. APS_FSMCO 0x04[15:0] = 0x4802 // set USB suspend +******************************/ + + + value8 = 0x23; + if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) + value8 |= BIT3; + + rtw_write8(Adapter, REG_SPS0_CTRL, value8); + + + if(bWithoutHWSM) + { + //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN); + // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically. + // Becasue suspend operatione need the asistance of 8051 to wait for 3ms. + value16 |= (APDM_HOST | AFSM_HSUS |PFM_ALDN); + } + else + { + value16 |= (APDM_HOST | AFSM_HSUS |PFM_ALDN); + } + + rtw_write16(Adapter, REG_APS_FSMCO,value16 );//0x4802 + + rtw_write8(Adapter, REG_RSV_CTRL, 0x0e); + + #if 0 + //tynli_test for suspend mode. + if(!bWithoutHWSM){ + rtw_write8(Adapter, 0xfe10, 0x19); + } +#endif + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16)); +} + +static int +CardDisableHWSM( // HW Auto state machine + IN PADAPTER Adapter, + IN BOOLEAN resetMCU + ) +{ + int rtStatus = _SUCCESS; + if(Adapter->bSurpriseRemoved){ + return rtStatus; + } +#if 1 + //==== RF Off Sequence ==== + _DisableRFAFEAndResetBB(Adapter); + + // ==== Reset digital sequence ====== + _ResetDigitalProcedure1(Adapter, _FALSE); + + // ==== Pull GPIO PIN to balance level and LED control ====== + _DisableGPIO(Adapter); + + // ==== Disable analog sequence === + _DisableAnalog(Adapter, _FALSE); + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n")); +#else + _DisableGPIO(Adapter); + + //reset FW download register + _ResetFWDownloadRegister(Adapter); + + + //disable RF/ AFE AD/DA + rtStatus = _DisableRF_AFE(Adapter); + if(RT_STATUS_SUCCESS != rtStatus){ + RT_TRACE(COMP_INIT, DBG_SERIOUS, ("_DisableRF_AFE failed!\n")); + goto Exit; + } + _ResetBB(Adapter); + + if(resetMCU){ + _ResetMCU(Adapter); + } + + _AutoPowerDownToHostOff(Adapter); + //_DisableMAC_AFE_PLL(Adapter); + + _SetUsbSuspend(Adapter); +Exit: +#endif + return rtStatus; + +} + +static int +CardDisableWithoutHWSM( // without HW Auto state machine + IN PADAPTER Adapter + ) +{ + int rtStatus = _SUCCESS; + + if(Adapter->bSurpriseRemoved){ + return rtStatus; + } + //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n")); + //==== RF Off Sequence ==== + _DisableRFAFEAndResetBB(Adapter); + + // ==== Reset digital sequence ====== + _ResetDigitalProcedure1(Adapter, _TRUE); + + // ==== Pull GPIO PIN to balance level and LED control ====== + _DisableGPIO(Adapter); + + // ==== Reset digital sequence ====== + _ResetDigitalProcedure2(Adapter); + + // ==== Disable analog sequence === + _DisableAnalog(Adapter, _TRUE); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n")); + return rtStatus; +} + +static void rtl8192cu_hw_power_down(_adapter *padapter) +{ + // 2010/-8/09 MH For power down module, we need to enable register block contrl reg at 0x1c. + // Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1. + + // Enable register area 0x0-0xc. + rtw_write8(padapter,REG_RSV_CTRL, 0x0); + rtw_write16(padapter, REG_APS_FSMCO, 0x8812); +} + +u32 rtl8192cu_hal_deinit(PADAPTER Adapter) + { + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + DBG_8192C("==> %s \n",__FUNCTION__); + // 2011/02/18 To Fix RU LNA power leakage problem. We need to execute below below in + // Adapter init and halt sequence. Accordingto EEchou's opinion, we can enable the ability for all + // IC. Accord to johnny's opinion, only RU need the support. + if (IS_HARDWARE_TYPE_8192C(Adapter) && (pHalData->BoardType == BOARD_USB_High_PA)) + rtw_write32(Adapter, rFPGA0_XCD_RFParameter, rtw_read32(Adapter, rFPGA0_XCD_RFParameter)|BIT1); + + #ifdef SUPPORT_HW_RFOFF_DETECTED + DBG_8192C("bkeepfwalive(%x)\n",Adapter->pwrctrlpriv.bkeepfwalive); + if(Adapter->pwrctrlpriv.bkeepfwalive) + { + _ps_close_RF(Adapter); + if((Adapter->pwrctrlpriv.bHWPwrPindetect) && (Adapter->pwrctrlpriv.bHWPowerdown)) + rtl8192cu_hw_power_down(Adapter); + } + else +#endif + { + if( Adapter->bCardDisableWOHSM == _FALSE) + { + DBG_8192C("card disble HWSM...........\n"); + CardDisableHWSM(Adapter, _FALSE); + } + else + { + DBG_8192C("card disble without HWSM...........\n"); + CardDisableWithoutHWSM(Adapter); // without HW Auto state machine + + if((Adapter->pwrctrlpriv.bHWPwrPindetect ) && (Adapter->pwrctrlpriv.bHWPowerdown)) + rtl8192cu_hw_power_down(Adapter); + } + } + + return _SUCCESS; + } + + +unsigned int rtl8192cu_inirp_init(PADAPTER Adapter) +{ + u8 i; + struct recv_buf *precvbuf; + uint status; + struct dvobj_priv *pdev = adapter_to_dvobj(Adapter); + struct intf_hdl * pintfhdl=&Adapter->iopriv.intf; + struct recv_priv *precvpriv = &(Adapter->recvpriv); + u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE + u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr); +#endif + +_func_enter_; + + _read_port = pintfhdl->io_ops._read_port; + + status = _SUCCESS; + + RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("===> usb_inirp_init \n")); + + precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR; + + //issue Rx irp to receive data + precvbuf = (struct recv_buf *)precvpriv->precv_buf; + for(i=0; iff_hwaddr, 0, (unsigned char *)precvbuf) == _FALSE ) + { + RT_TRACE(_module_hci_hal_init_c_,_drv_err_,("usb_rx_init: usb_read_port error \n")); + status = _FAIL; + goto exit; + } + + precvbuf++; + precvpriv->free_recv_buf_queue_cnt--; + } + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE + _read_interrupt = pintfhdl->io_ops._read_interrupt; + if(_read_interrupt(pintfhdl, RECV_INT_IN_ADDR) == _FALSE ) + { + RT_TRACE(_module_hci_hal_init_c_,_drv_err_,("usb_rx_init: usb_read_interrupt error \n")); + status = _FAIL; + } +#endif + +exit: + + RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("<=== usb_inirp_init \n")); + +_func_exit_; + + return status; + +} + +unsigned int rtl8192cu_inirp_deinit(PADAPTER Adapter) +{ + RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("\n ===> usb_rx_deinit \n")); + + rtw_read_port_cancel(Adapter); + + RT_TRACE(_module_hci_hal_init_c_,_drv_info_,("\n <=== usb_rx_deinit \n")); + + return _SUCCESS; +} + + +//------------------------------------------------------------------------- +// +// EEPROM Power index mapping +// +//------------------------------------------------------------------------- + + static VOID +_ReadPowerValueFromPROM( + IN PTxPowerInfo pwrInfo, + IN u8* PROMContent, + IN BOOLEAN AutoLoadFail + ) +{ + u32 rfPath, eeAddr, group; + + _rtw_memset(pwrInfo, 0, sizeof(TxPowerInfo)); + + if(AutoLoadFail){ + for(group = 0 ; group < CHANNEL_GROUP_MAX ; group++){ + for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++){ + pwrInfo->CCKIndex[rfPath][group] = EEPROM_Default_TxPowerLevel; + pwrInfo->HT40_1SIndex[rfPath][group] = EEPROM_Default_TxPowerLevel; + pwrInfo->HT40_2SIndexDiff[rfPath][group]= EEPROM_Default_HT40_2SDiff; + pwrInfo->HT20IndexDiff[rfPath][group] = EEPROM_Default_HT20_Diff; + pwrInfo->OFDMIndexDiff[rfPath][group] = EEPROM_Default_LegacyHTTxPowerDiff; + pwrInfo->HT40MaxOffset[rfPath][group] = EEPROM_Default_HT40_PwrMaxOffset; + pwrInfo->HT20MaxOffset[rfPath][group] = EEPROM_Default_HT20_PwrMaxOffset; + } + } + + pwrInfo->TSSI_A = EEPROM_Default_TSSI; + pwrInfo->TSSI_B = EEPROM_Default_TSSI; + + return; + } + + for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++){ + for(group = 0 ; group < CHANNEL_GROUP_MAX ; group++){ + eeAddr = EEPROM_CCK_TX_PWR_INX + (rfPath * 3) + group; + pwrInfo->CCKIndex[rfPath][group] = PROMContent[eeAddr]; + + eeAddr = EEPROM_HT40_1S_TX_PWR_INX + (rfPath * 3) + group; + pwrInfo->HT40_1SIndex[rfPath][group] = PROMContent[eeAddr]; + } + } + + for(group = 0 ; group < CHANNEL_GROUP_MAX ; group++){ + for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++){ + pwrInfo->HT40_2SIndexDiff[rfPath][group] = + (PROMContent[EEPROM_HT40_2S_TX_PWR_INX_DIFF + group] >> (rfPath * 4)) & 0xF; + +#if 1 + pwrInfo->HT20IndexDiff[rfPath][group] = + (PROMContent[EEPROM_HT20_TX_PWR_INX_DIFF + group] >> (rfPath * 4)) & 0xF; + if(pwrInfo->HT20IndexDiff[rfPath][group] & BIT3) //4bit sign number to 8 bit sign number + pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0; +#else + pwrInfo->HT20IndexDiff[rfPath][group] = + (PROMContent[EEPROM_HT20_TX_PWR_INX_DIFF + group] >> (rfPath * 4)) & 0xF; +#endif + + pwrInfo->OFDMIndexDiff[rfPath][group] = + (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF+ group] >> (rfPath * 4)) & 0xF; + + pwrInfo->HT40MaxOffset[rfPath][group] = + (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET+ group] >> (rfPath * 4)) & 0xF; + + pwrInfo->HT20MaxOffset[rfPath][group] = + (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET+ group] >> (rfPath * 4)) & 0xF; + } + } + + pwrInfo->TSSI_A = PROMContent[EEPROM_TSSI_A]; + pwrInfo->TSSI_B = PROMContent[EEPROM_TSSI_B]; + +} + + +static u32 +_GetChannelGroup( + IN u32 channel + ) +{ + //RT_ASSERT((channel < 14), ("Channel %d no is supported!\n")); + + if(channel < 3){ // Channel 1~3 + return 0; + } + else if(channel < 9){ // Channel 4~9 + return 1; + } + + return 2; // Channel 10~14 +} + + +static VOID +ReadTxPowerInfo( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoLoadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + TxPowerInfo pwrInfo; + u32 rfPath, ch, group; + u8 pwr, diff; + + _ReadPowerValueFromPROM(&pwrInfo, PROMContent, AutoLoadFail); + + if(!AutoLoadFail) + pHalData->bTXPowerDataReadFromEEPORM = _TRUE; + + for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++){ + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + group = _GetChannelGroup(ch); + + pHalData->TxPwrLevelCck[rfPath][ch] = pwrInfo.CCKIndex[rfPath][group]; + pHalData->TxPwrLevelHT40_1S[rfPath][ch] = pwrInfo.HT40_1SIndex[rfPath][group]; + + pHalData->TxPwrHt20Diff[rfPath][ch] = pwrInfo.HT20IndexDiff[rfPath][group]; + pHalData->TxPwrLegacyHtDiff[rfPath][ch] = pwrInfo.OFDMIndexDiff[rfPath][group]; + pHalData->PwrGroupHT20[rfPath][ch] = pwrInfo.HT20MaxOffset[rfPath][group]; + pHalData->PwrGroupHT40[rfPath][ch] = pwrInfo.HT40MaxOffset[rfPath][group]; + + pwr = pwrInfo.HT40_1SIndex[rfPath][group]; + diff = pwrInfo.HT40_2SIndexDiff[rfPath][group]; + + pHalData->TxPwrLevelHT40_2S[rfPath][ch] = (pwr > diff) ? (pwr - diff) : 0; + } + } + +#if DBG + + for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++){ + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + RTPRINT(FINIT, INIT_TxPower, + ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rfPath, ch, pHalData->TxPwrLevelCck[rfPath][ch], + pHalData->TxPwrLevelHT40_1S[rfPath][ch], + pHalData->TxPwrLevelHT40_2S[rfPath][ch])); + + } + } + + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + RTPRINT(FINIT, INIT_TxPower, ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", ch, pHalData->TxPwrHt20Diff[RF_PATH_A][ch])); + } + + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + RTPRINT(FINIT, INIT_TxPower, ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch])); + } + + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + RTPRINT(FINIT, INIT_TxPower, ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", ch, pHalData->TxPwrHt20Diff[RF_PATH_B][ch])); + } + + for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++){ + RTPRINT(FINIT, INIT_TxPower, ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch])); + } + +#endif + // 2010/10/19 MH Add Regulator recognize for CU. + if(!AutoLoadFail) + { + pHalData->EEPROMRegulatory = (PROMContent[RF_OPTION1]&0x7); //bit0~2 + } + else + { + pHalData->EEPROMRegulatory = 0; + } + DBG_8192C("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory); + +} + + +//------------------------------------------------------------------- +// +// EEPROM/EFUSE Content Parsing +// +//------------------------------------------------------------------- +static void +_ReadIDs( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(_FALSE == AutoloadFail){ + // VID, PID + pHalData->EEPROMVID = le16_to_cpu( *(u16 *)&PROMContent[EEPROM_VID]); + pHalData->EEPROMPID = le16_to_cpu( *(u16 *)&PROMContent[EEPROM_PID]); + + // Customer ID, 0x00 and 0xff are reserved for Realtek. + pHalData->EEPROMCustomerID = *(u8 *)&PROMContent[EEPROM_CUSTOMER_ID]; + pHalData->EEPROMSubCustomerID = *(u8 *)&PROMContent[EEPROM_SUBCUSTOMER_ID]; + + } + else{ + pHalData->EEPROMVID = EEPROM_Default_VID; + pHalData->EEPROMPID = EEPROM_Default_PID; + + // Customer ID, 0x00 and 0xff are reserved for Realtek. + pHalData->EEPROMCustomerID = EEPROM_Default_CustomerID; + pHalData->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; + + } + + // For customized behavior. + if((pHalData->EEPROMVID == 0x103C) && (pHalData->EEPROMVID == 0x1629))// HP Lite-On for RTL8188CUS Slim Combo. + pHalData->CustomerID = RT_CID_819x_HP; + + // Decide CustomerID according to VID/DID or EEPROM + switch(pHalData->EEPROMCustomerID) + { + case EEPROM_CID_DEFAULT: + if((pHalData->EEPROMVID == 0x2001) && (pHalData->EEPROMPID == 0x3308)) + pHalData->CustomerID = RT_CID_DLINK; + else if((pHalData->EEPROMVID == 0x2001) && (pHalData->EEPROMPID == 0x3309)) + pHalData->CustomerID = RT_CID_DLINK; + else if((pHalData->EEPROMVID == 0x2001) && (pHalData->EEPROMPID == 0x330a)) + pHalData->CustomerID = RT_CID_DLINK; + break; + case EEPROM_CID_WHQL: +/* + Adapter->bInHctTest = TRUE; + + pMgntInfo->bSupportTurboMode = FALSE; + pMgntInfo->bAutoTurboBy8186 = FALSE; + + pMgntInfo->PowerSaveControl.bInactivePs = FALSE; + pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE; + pMgntInfo->PowerSaveControl.bLeisurePs = FALSE; + + pMgntInfo->keepAliveLevel = 0; + + Adapter->bUnloadDriverwhenS3S4 = FALSE; +*/ + break; + default: + pHalData->CustomerID = RT_CID_DEFAULT; + break; + + } + + MSG_8192C("EEPROMVID = 0x%04x\n", pHalData->EEPROMVID); + MSG_8192C("EEPROMPID = 0x%04x\n", pHalData->EEPROMPID); + MSG_8192C("EEPROMCustomerID : 0x%02x\n", pHalData->EEPROMCustomerID); + MSG_8192C("EEPROMSubCustomerID: 0x%02x\n", pHalData->EEPROMSubCustomerID); + + MSG_8192C("RT_CustomerID: 0x%02x\n", pHalData->CustomerID); + +} + + +static VOID +_ReadMACAddress( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); + + if(_FALSE == AutoloadFail){ + //Read Permanent MAC address and set value to hardware + _rtw_memcpy(pEEPROM->mac_addr, &PROMContent[EEPROM_MAC_ADDR], ETH_ALEN); + } + else{ + //Random assigh MAC address + u8 sMacAddr[MAC_ADDR_LEN] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00}; + //sMacAddr[5] = (u8)GetRandomNumber(1, 254); + _rtw_memcpy(pEEPROM->mac_addr, sMacAddr, ETH_ALEN); + } + DBG_8192C("%s MAC Address from EFUSE = "MAC_FMT"\n",__FUNCTION__, MAC_ARG(pEEPROM->mac_addr)); + //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress); + //RT_PRINT_ADDR(COMP_INIT|COMP_EFUSE, DBG_LOUD, "MAC Addr: %s", Adapter->PermanentAddress); + +} + +static VOID +_ReadBoardType( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 value32; + u8 boardType = BOARD_USB_DONGLE; + + if(AutoloadFail){ + if(IS_8723_SERIES(pHalData->VersionID)) + pHalData->rf_type = RF_1T1R; + else + pHalData->rf_type = RF_2T2R; + + pHalData->BluetoothCoexist = _FALSE; + pHalData->BoardType = boardType; + return; + } + + boardType = PROMContent[EEPROM_NORMAL_BoardType]; + boardType &= BOARD_TYPE_NORMAL_MASK;//bit[7:5] + boardType >>= 5; + + pHalData->BoardType = boardType; + MSG_8192C("_ReadBoardType(%x)\n",pHalData->BoardType); + + if (boardType == BOARD_USB_High_PA) + pHalData->ExternalPA = 1; +} + + +static VOID +_ReadLEDSetting( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + struct led_priv *pledpriv = &(Adapter->ledpriv); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +#ifdef CONFIG_SW_LED + pledpriv->bRegUseLed = _TRUE; + + // + // Led mode + // + switch(pHalData->CustomerID) + { + case RT_CID_DEFAULT: + pledpriv->LedStrategy = SW_LED_MODE1; + pledpriv->bRegUseLed = _TRUE; + break; + + case RT_CID_819x_HP: + pledpriv->LedStrategy = SW_LED_MODE6; + break; + + default: + pledpriv->LedStrategy = SW_LED_MODE1; + break; + } + + if( BOARD_MINICARD == pHalData->BoardType ) + { + pledpriv->LedStrategy = SW_LED_MODE6; + } + pHalData->bLedOpenDrain = _TRUE;// Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. +#else // HW LED + pledpriv->LedStrategy = HW_LED; +#endif //CONFIG_SW_LED +} + +static VOID +_ReadThermalMeter( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 tempval; + + // + // ThermalMeter from EEPROM + // + if(!AutoloadFail) + tempval = PROMContent[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_Default_ThermalMeter; + + pHalData->EEPROMThermalMeter = (tempval&0x1f); //[4:0] + + if(pHalData->EEPROMThermalMeter == 0x1f || AutoloadFail) + pdmpriv->bAPKThermalMeterIgnore = _TRUE; + +#if 0 + if(pHalData->EEPROMThermalMeter < 0x06 || pHalData->EEPROMThermalMeter > 0x1c) + pHalData->EEPROMThermalMeter = 0x12; +#endif + + pdmpriv->ThermalMeter[0] = pHalData->EEPROMThermalMeter; + + //RTPRINT(FINIT, INIT_TxPower, ("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter)); + +} + +static VOID +_ReadRFSetting( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ +} + +static void +_ReadPROMVersion( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if(AutoloadFail){ + pHalData->EEPROMVersion = EEPROM_Default_Version; + } + else{ + pHalData->EEPROMVersion = *(u8 *)&PROMContent[EEPROM_VERSION]; + } +} + +static VOID +readAntennaDiversity( + IN PADAPTER pAdapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail + ) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct registry_priv *registry_par = &pAdapter->registrypriv; + + if(!AutoLoadFail) + { + // Antenna Diversity setting. + if(registry_par->antdiv_cfg == 2) // 2: From Efuse + pHalData->AntDivCfg = (hwinfo[EEPROM_RF_OPT1]&0x18)>>3; + else + pHalData->AntDivCfg = registry_par->antdiv_cfg ; // 0:OFF , 1:ON, + + DBG_8192C("### AntDivCfg(%x)\n",pHalData->AntDivCfg); + + //if(pHalData->EEPROMBluetoothCoexist!=0 && pHalData->EEPROMBluetoothAntNum==Ant_x1) + // pHalData->AntDivCfg = 0; + } + else + { + pHalData->AntDivCfg = 0; + } + +} + +static VOID +hal_InitPGData( + IN PADAPTER pAdapter, + IN OUT u8 *PROMContent + ) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u32 i; + u16 value16; + + if(_FALSE == pEEPROM->bautoload_fail_flag) + { // autoload OK. + if (_TRUE == pEEPROM->EepromOrEfuse) + { + // Read all Content from EEPROM or EFUSE. + for(i = 0; i < HWSET_MAX_SIZE; i += 2) + { + //value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1))); + //*((u16 *)(&PROMContent[i])) = value16; + } + } + else + { + // Read EFUSE real map to shadow. + EFUSE_ShadowMapUpdate(pAdapter, EFUSE_WIFI, _FALSE); + _rtw_memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE); + } + } + else + {//autoload fail + //RT_TRACE(COMP_INIT, DBG_LOUD, ("AutoLoad Fail reported from CR9346!!\n")); + pEEPROM->bautoload_fail_flag = _TRUE; + //update to default value 0xFF + if (_FALSE == pEEPROM->EepromOrEfuse) + EFUSE_ShadowMapUpdate(pAdapter, EFUSE_WIFI, _FALSE); + } +} +// Read HW power down mode selection +static void _ReadPSSetting(IN PADAPTER Adapter,IN u8*PROMContent,IN u8 AutoloadFail) +{ + if(AutoloadFail){ + Adapter->pwrctrlpriv.bHWPowerdown = _FALSE; + Adapter->pwrctrlpriv.bSupportRemoteWakeup = _FALSE; + } + else { + //if(SUPPORT_HW_RADIO_DETECT(Adapter)) + Adapter->pwrctrlpriv.bHWPwrPindetect = Adapter->registrypriv.hwpwrp_detect; + //else + //Adapter->pwrctrlpriv.bHWPwrPindetect = _FALSE;//dongle not support new + + + //hw power down mode selection , 0:rf-off / 1:power down + + if(Adapter->registrypriv.hwpdn_mode==2) + Adapter->pwrctrlpriv.bHWPowerdown = (PROMContent[EEPROM_RF_OPT3] & BIT4); + else + Adapter->pwrctrlpriv.bHWPowerdown = Adapter->registrypriv.hwpdn_mode; +#ifdef CONFIG_WOWLAN + // decide hw if support remote wakeup function + // if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume + Adapter->pwrctrlpriv.bSupportRemoteWakeup = (PROMContent[EEPROM_TEST_USB_OPT] & BIT1)?_TRUE :_FALSE; +#endif //CONFIG_WOWLAN + + //if(SUPPORT_HW_RADIO_DETECT(Adapter)) + //Adapter->registrypriv.usbss_enable = Adapter->pwrctrlpriv.bSupportRemoteWakeup ; + + DBG_8192C("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) ,bSupportRemoteWakeup(%x)\n",__FUNCTION__, + Adapter->pwrctrlpriv.bHWPwrPindetect,Adapter->pwrctrlpriv.bHWPowerdown ,Adapter->pwrctrlpriv.bSupportRemoteWakeup); + + DBG_8192C("### PS params=> power_mgnt(%x),usbss_enable(%x) ###\n",Adapter->registrypriv.power_mgnt,Adapter->registrypriv.usbss_enable); + + } + +} + +static VOID +readAdapterInfo_8192CU( + IN PADAPTER Adapter + ) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + u8 PROMContent[HWSET_MAX_SIZE]={0}; + + hal_InitPGData(Adapter, PROMContent); + rtl8192c_EfuseParseIDCode(Adapter, PROMContent); + + _ReadPROMVersion(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadIDs(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadMACAddress(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + ReadTxPowerInfo(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadBoardType(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + +#ifdef CONFIG_BT_COEXIST + // + // Read Bluetooth co-exist and initialize + // + rtl8192c_ReadBluetoothCoexistInfo(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); +#endif + + rtl8192c_EfuseParseChnlPlan(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadThermalMeter(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadLEDSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + readAntennaDiversity(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); + + //hal_CustomizedBehavior_8723U(Adapter); + + Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; + DBG_8192C("%s(): REPLACEMENT = %x\n",__FUNCTION__,Adapter->bDongle); +#ifdef CONFIG_INTEL_PROXIM + /* for intel proximity */ + if (pHalData->rf_type== RF_1T1R) { + Adapter->proximity.proxim_support = _TRUE; + } else if (pHalData->rf_type== RF_2T2R) { + if ((pHalData->EEPROMPID == 0x8186) && + (pHalData->EEPROMVID== 0x0bda)) + Adapter->proximity.proxim_support = _TRUE; + } else { + Adapter->proximity.proxim_support = _FALSE; + } +#endif //CONFIG_INTEL_PROXIM +} + +static void _ReadPROMContent( + IN PADAPTER Adapter + ) +{ + EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 PROMContent[HWSET_MAX_SIZE]={0}; + u8 eeValue; + u32 i; + u16 value16; + + eeValue = rtw_read8(Adapter, REG_9346CR); + // To check system boot selection. + pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? _TRUE : _FALSE; + pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? _FALSE : _TRUE; + + + DBG_8192C("Boot from %s, Autoload %s !\n", (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"), + (pEEPROM->bautoload_fail_flag ? "Fail" : "OK") ); + + //pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; + + //if(IS_HARDWARE_TYPE_8723A(Adapter)) + // readAdapterInfo_8723U(Adapter); + //else + readAdapterInfo_8192CU(Adapter); +} + + +static VOID +_InitOtherVariable( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + + //if(Adapter->bInHctTest){ + // pMgntInfo->PowerSaveControl.bInactivePs = FALSE; + // pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE; + // pMgntInfo->PowerSaveControl.bLeisurePs = FALSE; + // pMgntInfo->keepAliveLevel = 0; + //} + + // 2009/06/10 MH For 92S 1*1=1R/ 1*2&2*2 use 2R. We default set 1*1 use radio A + // So if you want to use radio B. Please modify RF path enable bit for correct signal + // strength calculate. + if (pHalData->rf_type == RF_1T1R){ + pHalData->bRFPathRxEnable[0] = _TRUE; + } + else{ + pHalData->bRFPathRxEnable[0] = pHalData->bRFPathRxEnable[1] = _TRUE; + } + +} + +static VOID +_ReadRFType( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + +#if DISABLE_BB_RF + pHalData->rf_chip = RF_PSEUDO_11N; +#else + pHalData->rf_chip = RF_6052; +#endif +} + +void _ReadSilmComboMode(PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + pHalData->SlimComboDbg = _FALSE; // Default is not debug mode. + + // 2010/11/22 MH We need to enter debug mode for TSMA and UMC A cut + if ((Adapter->chip_type == RTL8188C_8192C) && + (pHalData->BoardType == BOARD_USB_COMBO)) + { + switch (pHalData->VersionID) + { + case VERSION_NORMAL_TSMC_CHIP_88C: + case VERSION_NORMAL_TSMC_CHIP_92C: + case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: + if ((rtw_read8(Adapter, REG_SYS_CFG+3) &0xF0) == 0x20) + pHalData->SlimComboDbg = _TRUE; + + break; + + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: + // 2011/02/15 MH UNC-B cut ECO fail, we need to support slim combo debug mode. + if ((rtw_read8(Adapter, REG_SYS_CFG+3) &0xF0) == 0x20) + pHalData->SlimComboDbg = _TRUE; + break; + + default: + break; + } + + } + +} +static int _ReadAdapterInfo8192CU(PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 start=rtw_get_current_time(); + + MSG_8192C("====> ReadAdapterInfo8192C\n"); + + //Efuse_InitSomeVar(Adapter); + + //if(IS_HARDWARE_TYPE_8723A(Adapter)) + // _EfuseCellSel(Adapter); + + _ReadRFType(Adapter);//rf_chip -> _InitRFType() + _ReadPROMContent(Adapter); + + // 2010/10/25 MH THe function must be called after borad_type & IC-Version recognize. + _ReadSilmComboMode(Adapter); + + _InitOtherVariable(Adapter); + + //MSG_8192C("%s()(done), rf_chip=0x%x, rf_type=0x%x\n", __FUNCTION__, pHalData->rf_chip, pHalData->rf_type); + + MSG_8192C("<==== ReadAdapterInfo8192C in %d ms\n", rtw_get_passing_time_ms(start)); + + return _SUCCESS; +} + + +static void ReadAdapterInfo8192CU(PADAPTER Adapter) +{ + // Read EEPROM size before call any EEPROM function + //Adapter->EepromAddressSize=Adapter->HalFunc.GetEEPROMSizeHandler(Adapter); + Adapter->EepromAddressSize = GetEEPROMSize8192C(Adapter); + + _ReadAdapterInfo8192CU(Adapter); +} + + +#define GPIO_DEBUG_PORT_NUM 0 +static void rtl8192cu_trigger_gpio_0(_adapter *padapter) +{ + + u32 gpioctrl; + DBG_8192C("==> trigger_gpio_0...\n"); + rtw_write16_async(padapter,REG_GPIO_PIN_CTRL,0); + rtw_write8_async(padapter,REG_GPIO_PIN_CTRL+2,0xFF); + gpioctrl = (BIT(GPIO_DEBUG_PORT_NUM)<<24 )|(BIT(GPIO_DEBUG_PORT_NUM)<<16); + rtw_write32_async(padapter,REG_GPIO_PIN_CTRL,gpioctrl); + gpioctrl |= (BIT(GPIO_DEBUG_PORT_NUM)<<8); + rtw_write32_async(padapter,REG_GPIO_PIN_CTRL,gpioctrl); + DBG_8192C("<=== trigger_gpio_0...\n"); + +} + +static void ResumeTxBeacon(_adapter *padapter) +{ + HAL_DATA_TYPE* pHalData = GET_HAL_DATA(padapter); + + // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value + // which should be read from register to a global variable. + + rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) | BIT6); + pHalData->RegFwHwTxQCtrl |= BIT6; +} + +static void StopTxBeacon(_adapter *padapter) +{ + HAL_DATA_TYPE* pHalData = GET_HAL_DATA(padapter); + + // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value + // which should be read from register to a global variable. + + rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) & (~BIT6)); + pHalData->RegFwHwTxQCtrl &= (~BIT6); + + //todo: CheckFwRsvdPageContent(Adapter); // 2010.06.23. Added by tynli. + +} + +u16 CRC16(u8 data,u16 CRC) +{ + unsigned char shift_in,CRC_BIT15,DataBit,CRC_BIT11,CRC_BIT4 ; + int index; + unsigned short CRC_Result; + + for(index=0;index<8;index++) + { + CRC_BIT15=((CRC&BIT15) ? 1:0); + DataBit =(data&(BIT0<iface_type == IFACE_PORT1) + { + // disable Port1 TSF update + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4)); + + // set net_type + val8 = rtw_read8(Adapter, MSR)&0x03; + val8 |= (mode<<2); + rtw_write8(Adapter, MSR, val8); + + //reset TSF1 + rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)); + + DBG_871X("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode); + + if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) + { + if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE)) + { + StopTxBeacon(Adapter); + } + + rtw_write8(Adapter,REG_BCN_CTRL_1, 0x19);//disable atim wnd + //rtw_write8(Adapter,REG_BCN_CTRL_1, 0x18); + } + else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) + { + ResumeTxBeacon(Adapter); + rtw_write8(Adapter,REG_BCN_CTRL_1, 0x1a); + } + else if(mode == _HW_STATE_AP_) + { + ResumeTxBeacon(Adapter); + + rtw_write8(Adapter, REG_BCN_CTRL_1, 0x12); + + //Set RCR + //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0 + rtw_write32(Adapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0 + //enable to rx data frame + rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); + //enable to rx ps-poll + rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400); + + //Beacon Control related register for first time + rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms + rtw_write8(Adapter, REG_DRVERLYINT, 0x05);// 5ms + //rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); + rtw_write8(Adapter, REG_ATIMWND_1, 0x0a); // 10ms for port1 + rtw_write16(Adapter, REG_BCNTCFG, 0x00); + rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04); + rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms) + + + //enable BCN1 Function for if2 + //don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) + rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1))); + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE)) + rtw_write8(Adapter, REG_BCN_CTRL, + rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION); +#endif + + DBG_871X("%s()-%d: REG_BCN_CTRL_1 = %02x\n", __FUNCTION__, __LINE__, rtw_read8(Adapter, REG_BCN_CTRL_1)); + + //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked + //rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5)); + //rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3)); + + //dis BCN0 ATIM WND if if1 is station + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(0)); +#ifdef CONFIG_TSF_RESET_OFFLOAD + // Reset TSF for STA+AP concurrent mode + if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) { + if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n", + __FUNCTION__, __LINE__); + } +#endif // CONFIG_TSF_RESET_OFFLOAD + } + + } + else // (Adapter->iface_type == IFACE_PORT1) +#endif //CONFIG_CONCURRENT_MODE + { + // disable Port0 TSF update + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4)); + + // set net_type + val8 = rtw_read8(Adapter, MSR)&0x0c; + val8 |= mode; + rtw_write8(Adapter, MSR, val8); + + //reset TSF0 + rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0)); + + DBG_871X("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode); + + if((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) + { +#ifdef CONFIG_CONCURRENT_MODE + if(!check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE)) +#endif //CONFIG_CONCURRENT_MODE + { + StopTxBeacon(Adapter); + } + + rtw_write8(Adapter,REG_BCN_CTRL, 0x19);//disable atim wnd + //rtw_write8(Adapter,REG_BCN_CTRL, 0x18); + } + else if((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) + { + ResumeTxBeacon(Adapter); + rtw_write8(Adapter,REG_BCN_CTRL, 0x1a); + } + else if(mode == _HW_STATE_AP_) + { + ResumeTxBeacon(Adapter); + + rtw_write8(Adapter, REG_BCN_CTRL, 0x12); + + //Set RCR + //write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0 + rtw_write32(Adapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0 + //enable to rx data frame + rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF); + //enable to rx ps-poll + rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400); + + //Beacon Control related register for first time + + rtw_write8(Adapter, REG_BCNDMATIM, 0x02); // 2ms + rtw_write8(Adapter, REG_DRVERLYINT, 0x05);// 5ms + + //write8(Adapter, REG_BCN_MAX_ERR, 0xFF); + rtw_write8(Adapter, REG_ATIMWND, 0x0a); // 10ms for port0 + rtw_write16(Adapter, REG_BCNTCFG, 0x00); + rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04); + rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms) + + //enable BCN0 Function for if1 + //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) + rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | EN_TXBCN_RPT|BIT(1))); + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(Adapter, WIFI_FW_NULL_STATE)) + rtw_write8(Adapter, REG_BCN_CTRL_1, + rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION); +#endif + //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked + //only interface 2 as AP MODE need to sync + //rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5)); + + + //dis BCN1 ATIM WND if if2 is station + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(0)); +#ifdef CONFIG_TSF_RESET_OFFLOAD + // Reset TSF for STA+AP concurrent mode + if ( check_buddy_fwstate(Adapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) { + if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n", + __FUNCTION__, __LINE__); + } +#endif // CONFIG_TSF_RESET_OFFLOAD + + } + + + } + +} + +static void hw_var_set_macaddr(PADAPTER Adapter, u8 variable, u8* val) +{ + u8 idx = 0; + u32 reg_macid; + +#ifdef CONFIG_CONCURRENT_MODE + if(Adapter->iface_type == IFACE_PORT1) + { + reg_macid = REG_MACID1; + } + else +#endif + { + reg_macid = REG_MACID; + } + + for(idx = 0 ; idx < 6; idx++) + { + rtw_write8(Adapter, (reg_macid+idx), val[idx]); + } + +} + +static void hw_var_set_bssid(PADAPTER Adapter, u8 variable, u8* val) +{ + u8 idx = 0; + u32 reg_bssid; + +#ifdef CONFIG_CONCURRENT_MODE + if(Adapter->iface_type == IFACE_PORT1) + { + reg_bssid = REG_BSSID1; + } + else +#endif + { + reg_bssid = REG_BSSID; + } + + for(idx = 0 ; idx < 6; idx++) + { + rtw_write8(Adapter, (reg_bssid+idx), val[idx]); + } + +} + +static void hw_var_set_bcn_func(PADAPTER Adapter, u8 variable, u8* val) +{ + u32 bcn_ctrl_reg; + +#ifdef CONFIG_CONCURRENT_MODE + if(Adapter->iface_type == IFACE_PORT1) + { + bcn_ctrl_reg = REG_BCN_CTRL_1; + + if(*((u8 *)val)) + { + rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); + } + else + { + rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); + } + } + else +#endif + { + bcn_ctrl_reg = REG_BCN_CTRL; + if(*((u8 *)val)) + { + rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); + } + else + { + //rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); + rtw_write8(Adapter, bcn_ctrl_reg, (rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_TXBCN_RPT))) | DIS_TSF_UDT0_NORMAL_CHIP); + } + } + + +} + +#ifdef CONFIG_WOWLAN +static int rtw_wowlan_set_pattern(_adapter *padapter ,u8* pbuf){ + struct pwrctrl_priv *pwrpriv=&padapter->pwrctrlpriv; + int res=0,crc_idx; + u32 content=0,cmd=0; + u32 *pdata; + u8 config,crc,mc,bc,uc,idx,pattern_len,packet[200],packet_len,valid; + u16 crc_val=0,i; + + config=pbuf[0]; + bc=config & BIT(3)?1:0; + mc=config & BIT(4)?1:0; + uc=config & BIT(5)?1:0; + idx=config & 0x7; + crc=config & BIT(6)?1:0; + valid=config & BIT(7)?1:0; + pattern_len=pbuf[1]; + packet_len=pattern_len*8; + pdata=(u32 *)pbuf; + + // Write to the Wakeup CAM + //offset 0 + if(pattern_len>=4){ + content=pdata[1]; + } + else{ + content=0; + } + DBG_8192C("\nrtw_wowlan_set_pattern offset[0] content 0x%x [cpu_to_le32 0x%x]\n", content,__cpu_to_le32(content)); + //rtw_write32(padapter, REG_WKFMCAM_RWD, __cpu_to_le32(content)); + pwrpriv->wowlan_pattern_context[idx][0]= __cpu_to_le32(content); + //cmd=BIT(31)|BIT(16)|(idx+0); + //rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + //offset 4 + if(pattern_len>=8){ + content=pdata[2]; + } + else{ + content=0; + } + DBG_8192C("rtw_wowlan_set_pattern offset[4] content 0x%x [cpu_to_le32 0x%x]\n", content,__cpu_to_le32(content)); + //rtw_write32(padapter, REG_WKFMCAM_RWD, __cpu_to_le32(content)); + pwrpriv->wowlan_pattern_context[idx][1]= __cpu_to_le32(content); + + //cmd=BIT(31)|BIT(16)|(idx+1); + //rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + //offset 8 + if(pattern_len>=12){ + content=pdata[3]; + } + else{ + content=0; + } + DBG_8192C("rtw_wowlan_set_pattern offset[8] content 0x%x [cpu_to_le32 0x%x]\n", content,__cpu_to_le32(content)); + //rtw_write32(padapter, REG_WKFMCAM_RWD, __cpu_to_le32(content)); + pwrpriv->wowlan_pattern_context[idx][2]= __cpu_to_le32(content); + //cmd=BIT(31)|BIT(16)|(idx+2); + //rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + //offset 12 + if(pattern_len>=16){ + content=pdata[4]; + } + else{ + content=0; + } + DBG_8192C("rtw_wowlan_set_pattern offset[12] content 0x%x [cpu_to_le32 0x%x]\n", content,__cpu_to_le32(content)); + //rtw_write32(padapter, REG_WKFMCAM_RWD, __cpu_to_le32(content)); + pwrpriv->wowlan_pattern_context[idx][3]= __cpu_to_le32(content); + //cmd=BIT(31)|BIT(16)|(idx+3); + //rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + if(crc){ + // Have the CRC value + crc_val=*(u16 *)(&pbuf[2]); + DBG_8192C("rtw_wowlan_set_pattern crc_val 0x%x \n", crc_val); + crc_val=__cpu_to_le16(crc_val); + DBG_8192C("rtw_wowlan_set_pattern crc_val after 0x%x \n", crc_val); + } + else{ + DBG_8192C("+rtw_wowlan_set_pattern crc=0[%x] Should calculate the CRC\n", crc); + // calculate the CRC the write to the Wakeup CAM + crc_idx=0; + for(i=0;iwowlan_pattern_context[idx][4]= content; + //cmd=BIT(31)|BIT(16)|(idx+4); + //rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + pwrpriv->wowlan_pattern_idx|=BIT(idx); + +_rtw_wowlan_set_pattern_exit: + return res; +} + + + +void rtw_wowlan_reload_pattern(_adapter *padapter){ + struct pwrctrl_priv *pwrpriv=&padapter->pwrctrlpriv; + u32 content=0,cmd=0; + u8 idx; + + for (idx=0;idx<8;idx ++){ + if(pwrpriv->wowlan_pattern_idx & BIT(idx)){ + //offset 0 + rtw_write32(padapter, REG_WKFMCAM_RWD, pwrpriv->wowlan_pattern_context[idx][0]); + cmd=BIT(31)|BIT(16)|(idx+0); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + //offset 4 + rtw_write32(padapter, REG_WKFMCAM_RWD, pwrpriv->wowlan_pattern_context[idx][1]); + cmd=BIT(31)|BIT(16)|(idx+1); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + //offset 8 + rtw_write32(padapter, REG_WKFMCAM_RWD, pwrpriv->wowlan_pattern_context[idx][2]); + cmd=BIT(31)|BIT(16)|(idx+2); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + //offset 12 + rtw_write32(padapter, REG_WKFMCAM_RWD, pwrpriv->wowlan_pattern_context[idx][3]); + cmd=BIT(31)|BIT(16)|(idx+3); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + //offset 16 + rtw_write32(padapter, REG_WKFMCAM_RWD, pwrpriv->wowlan_pattern_context[idx][4]); + cmd=BIT(31)|BIT(16)|(idx+4); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + + } + printk("print WOWCAM idx =%d\n",idx); + cmd=BIT(31)|(idx+0); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + printk("print WOWCAM offset[0] =%x\n",rtw_read32(padapter, REG_WKFMCAM_RWD)); + cmd=BIT(31)|(idx+1); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + printk("print WOWCAM offset[1] =%x\n",rtw_read32(padapter, REG_WKFMCAM_RWD)); + cmd=BIT(31)|(idx+2); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + printk("print WOWCAM offset[2] =%x\n",rtw_read32(padapter, REG_WKFMCAM_RWD)); + cmd=BIT(31)|(idx+3); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + printk("print WOWCAM offset[3] =%x\n",rtw_read32(padapter, REG_WKFMCAM_RWD)); + cmd=BIT(31)|(idx+4); + rtw_write32(padapter, REG_WKFMCAM_CMD, cmd); + printk("print WOWCAM offset[4] =%x\n",rtw_read32(padapter, REG_WKFMCAM_RWD)); + + + } +} +#endif //CONFIG_WOWLAN + +static void hw_var_set_correct_tsf(PADAPTER Adapter, u8 variable, u8* val) +{ +#ifdef CONFIG_CONCURRENT_MODE + u64 tsf; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us + tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pHalData->RegTxPause |= STOP_BCNQ;BIT(6) + //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6))); + StopTxBeacon(Adapter); + } + + if(Adapter->iface_type == IFACE_PORT1) + { + //disable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3))); + + rtw_write32(Adapter, REG_TSFTR1, tsf); + rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32); + + //enable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3)); + + +#ifdef CONFIG_TSF_RESET_OFFLOAD + // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue! + if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE + && check_buddy_fwstate(Adapter, WIFI_AP_STATE) ) { + if (reset_tsf(Adapter, IFACE_PORT0) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n", + __FUNCTION__, __LINE__); + } +#endif // CONFIG_TSF_RESET_OFFLOAD + + } + else // Adapter->iface_type == IFACE_PORT1 + { + //disable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3))); + // disable TSF update instead! May induce burst beacon TX + //rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4)); + + rtw_write32(Adapter, REG_TSFTR, tsf); + rtw_write32(Adapter, REG_TSFTR+4, tsf>>32); + + //enable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3)); + //rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); + + // Update buddy port's TSF if it is SoftAP for beacon TX issue! + if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE + && check_buddy_fwstate(Adapter, WIFI_AP_STATE) + ) { + //disable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3))); + // disable TSF update instead! + //rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4)); + + rtw_write32(Adapter, REG_TSFTR1, tsf); + rtw_write32(Adapter, REG_TSFTR1+4, tsf>>32); + + //enable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(3)); + //rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(4))); + } +#ifdef CONFIG_TSF_RESET_OFFLOAD + // Update buddy port's TSF if it is SoftAP for beacon TX issue! + if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE + && check_buddy_fwstate(Adapter, WIFI_AP_STATE) ) { + if (reset_tsf(Adapter, IFACE_PORT1) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n", + __FUNCTION__, __LINE__); + } +#endif // CONFIG_TSF_RESET_OFFLOAD + } + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pHalData->RegTxPause &= (~STOP_BCNQ); + //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6)))); + ResumeTxBeacon(Adapter); + } +#endif // CONFIG_CONCURRENT_MODE +} + +static void hw_var_set_mlme_disconnect(PADAPTER Adapter, u8 variable, u8* val) +{ +#ifdef CONFIG_CONCURRENT_MODE + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; + + + if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_)) + rtw_write16(Adapter, REG_RXFLTMAP2, 0x00); + + + if(Adapter->iface_type == IFACE_PORT1) + { + int i; + u8 reg_bcn_ctrl_1; + + // a.Driver set 0x422 bit 6 =0 + rtw_write8(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) & (~BIT6)); + pHalData->RegFwHwTxQCtrl &= (~BIT6); + + +#ifdef CONFIG_BEACON_DISABLE_OFFLOAD + u8 reg_bcn_disable_cnt = rtw_read8(Adapter, REG_FW_BCN_DIS_CNT); + DBG_871X("%s()-%d: reg_bcn_disable_cnt=%02x\n", __FUNCTION__, __LINE__, reg_bcn_disable_cnt); + + reg_bcn_ctrl_1 = rtw_read8(Adapter, REG_BCN_CTRL_1); + DBG_871X("%s()-%d: reg_bcn_ctrl_1=%02x\n", __FUNCTION__, __LINE__, reg_bcn_ctrl_1); + + // b. driver set h2c cmd + rtl8192c_dis_beacon_fun_cmd(Adapter); + + /* + // FW Job for port 0 + + c. 8051 set nettype to ap + d. 8051 check dma_int + e. 8051 set nettype to no_link + f.8051 dis_tsf_update 0x550 bit 4 + g.8051 reset beacon function test count 0x553 bit0. + h.8051 disable beacon function 0x550 bit3 + i. 8051 sent ready to driver + + */ + + // The worst case is 100 + 15 ms + rtw_msleep_os(120); + + for (i=0; i< 10; i++) { + reg_bcn_ctrl_1 = rtw_read8(Adapter, REG_BCN_CTRL_1); + if ( (reg_bcn_ctrl_1 & BIT(3)) == 0 ) { + //DBG_871X("%s()-%d: BEACON_DISABLE_OFFLOAD finished! reg=%02x\n", __FUNCTION__, __LINE__, reg); + break; + } + DBG_871X("%s()-%d: BEACON_DISABLE_OFFLOAD not finished! REG_BCN_CTRL_1=%02x\n", __FUNCTION__, __LINE__, reg_bcn_ctrl_1); + DBG_871X("%s()-%d: reg_bcn_disable_cnt=%02x\n", __FUNCTION__, __LINE__, rtw_read8(Adapter, REG_FW_BCN_DIS_CNT)); + DBG_871X("%s()-%d: REG_BCN_CTRL=%02x\n", __FUNCTION__, __LINE__, rtw_read8(Adapter, REG_BCN_CTRL)); + DBG_871X("%s()-%d: FWISR=%08x\n", __FUNCTION__, __LINE__, rtw_read32(Adapter, REG_FWISR)); + rtw_msleep_os(100); + } + DBG_871X("%s()-%d: reg_bcn_disable_cnt=%02x\n", __FUNCTION__, __LINE__, rtw_read8(Adapter, REG_FW_BCN_DIS_CNT)); + DBG_871X("%s()-%d: reg_bcn_ctrl_1=%02x\n", __FUNCTION__, __LINE__, reg_bcn_ctrl_1); + +#else // CONFIG_BEACON_DISABLE_OFFLOAD + + //disable update TSF1 + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(4)); + + //reset TSF1 + rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)); + + // disable Port1's beacon function + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(3))); + +#endif // CONFIG_BEACON_DISABLE_OFFLOAD + + // j, Driver set 0x422 bit 6 =1 + rtw_write8(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl) | BIT6); + pHalData->RegFwHwTxQCtrl |= BIT6; + + // k. re_download beacon pkt + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE)) + set_tx_beacon_cmd(pbuddy_adapter); + + + } + else // (Adapter->iface_type == IFACE_PORT1) + { + //disable update TSF + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4)); + + //reset TSF + rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0)); + + // Can't disable Port0's beacon function due to it is used by RA + } +#endif +} + +static void hw_var_set_mlme_sitesurvey(PADAPTER Adapter, u8 variable, u8* val) +{ + u32 value_rcr, rcr_clear_bit, reg_bcn_ctl; + u16 value_rxfltmap2; + struct mlme_priv *pmlmepriv=&(Adapter->mlmepriv); + + +#ifdef CONFIG_CONCURRENT_MODE + if(Adapter->iface_type == IFACE_PORT1) + reg_bcn_ctl = REG_BCN_CTRL_1; + else +#endif + reg_bcn_ctl = REG_BCN_CTRL; + +#ifdef CONFIG_FIND_BEST_CHANNEL + + if( (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) +#ifdef CONFIG_CONCURRENT_MODE + || (check_buddy_fwstate(Adapter, WIFI_AP_STATE) == _TRUE) +#endif +#ifdef CONFIG_TDLS + // TDLS will clear RCR_CBSSID_DATA bit for connection. + || ( Adapter->tdlsinfo.setup_state & TDLS_LINKED_STATE ) +#endif // CONFIG_TDLS + ) + { + rcr_clear_bit = RCR_CBSSID_BCN; + } + else + { + rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA); + } + + // Recieve all data frames + value_rxfltmap2 = 0xFFFF; + +#else /* CONFIG_FIND_BEST_CHANNEL */ + + rcr_clear_bit = RCR_CBSSID_BCN; + + //config RCR to receive different BSSID & not to receive data frame + value_rxfltmap2 = 0; + +#endif /* CONFIG_FIND_BEST_CHANNEL */ + + value_rcr = rtw_read32(Adapter, REG_RCR); + + if(*((u8 *)val))//under sitesurvey + { + value_rcr &= ~(rcr_clear_bit); + rtw_write32(Adapter, REG_RCR, value_rcr); + + rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2); + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE |WIFI_ADHOC_MASTER_STATE)) { + //disable update TSF + rtw_write8(Adapter, reg_bcn_ctl, rtw_read8(Adapter, reg_bcn_ctl)|BIT(4)); + } + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(Adapter, _FW_LINKED)) + { + StopTxBeacon(Adapter); + } +#endif + } + else//sitesurvey done + { + if(check_fwstate(pmlmepriv, _FW_LINKED) || check_fwstate(pmlmepriv, WIFI_AP_STATE) +#ifdef CONFIG_CONCURRENT_MODE + || check_buddy_fwstate(Adapter, _FW_LINKED) || check_buddy_fwstate(Adapter, WIFI_AP_STATE) +#endif + ) + { + //enable to rx data frame + rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF); + } + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE |WIFI_ADHOC_MASTER_STATE)) { + //enable update TSF + rtw_write8(Adapter, reg_bcn_ctl, rtw_read8(Adapter, reg_bcn_ctl)&(~BIT(4))); + } + + value_rcr |= rcr_clear_bit; + rtw_write32(Adapter, REG_RCR, value_rcr); + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(Adapter, _FW_LINKED)) + { + ResumeTxBeacon(Adapter); + } +#endif + } +} + +static void hw_var_set_mlme_join(PADAPTER Adapter, u8 variable, u8* val) +{ +#ifdef CONFIG_CONCURRENT_MODE + u8 RetryLimit = 0x30; + u8 type = *((u8 *)val); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + + if(type == 0) // prepare to join + { + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(Adapter, _FW_LINKED)) + { + StopTxBeacon(Adapter); + } + + //enable to rx data frame.Accept all data frame + //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); + rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF); + + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE)) + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN); + else + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48; + } + else // Ad-hoc Mode + { + RetryLimit = 0x7; + } + } + else if(type == 1) //joinbss_event call back when join res < 0 + { + if(check_buddy_mlmeinfo_state(Adapter, _HW_STATE_NOLINK_)) + rtw_write16(Adapter, REG_RXFLTMAP2,0x00); + + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(Adapter, _FW_LINKED)) + { + ResumeTxBeacon(Adapter); + + //reset TSF 1/2 after ResumeTxBeacon + //rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0)); + + } + } + else if(type == 2) //sta add event call back + { + + //enable update TSF + if(Adapter->iface_type == IFACE_PORT1) + rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)&(~BIT(4))); + else + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); + + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) + { + //fixed beacon issue for 8191su........... + rtw_write8(Adapter,0x542 ,0x02); + RetryLimit = 0x7; + } + + + if(check_buddy_mlmeinfo_state(Adapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(Adapter, _FW_LINKED)) + { + ResumeTxBeacon(Adapter); + + //reset TSF 1/2 after ResumeTxBeacon + //rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0)); + } + + } + + rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); + +#endif +} + +void SetHwReg8192CU(PADAPTER Adapter, u8 variable, u8* val) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + +_func_enter_; + + switch(variable) + { + case HW_VAR_MEDIA_STATUS: + { + u8 val8; + + val8 = rtw_read8(Adapter, MSR)&0x0c; + val8 |= *((u8 *)val); + rtw_write8(Adapter, MSR, val8); + } + break; + case HW_VAR_MEDIA_STATUS1: + { + u8 val8; + + val8 = rtw_read8(Adapter, MSR)&0x03; + val8 |= *((u8 *)val) <<2; + rtw_write8(Adapter, MSR, val8); + } + break; + case HW_VAR_SET_OPMODE: + hw_var_set_opmode(Adapter, variable, val); + break; + case HW_VAR_MAC_ADDR: + hw_var_set_macaddr(Adapter, variable, val); + break; + case HW_VAR_BSSID: + hw_var_set_bssid(Adapter, variable, val); + break; + case HW_VAR_BASIC_RATE: + { + u16 BrateCfg = 0; + u8 RateIndex = 0; + + // 2007.01.16, by Emily + // Select RRSR (in Legacy-OFDM and CCK) + // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. + // We do not use other rates. + HalSetBrateCfg( Adapter, val, &BrateCfg ); + + //2011.03.30 add by Luke Lee + //CCK 2M ACK should be disabled for some BCM and Atheros AP IOT + //because CCK 2M has poor TXEVM + //CCK 5.5M & 11M ACK should be enabled for better performance + + pHalData->BasicRateSet = BrateCfg = (BrateCfg |0xd) & 0x15d; + + BrateCfg |= 0x01; // default enable 1M ACK rate + + DBG_8192C("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg); + + // Set RRSR rate table. + rtw_write8(Adapter, REG_RRSR, BrateCfg&0xff); + rtw_write8(Adapter, REG_RRSR+1, (BrateCfg>>8)&0xff); + rtw_write8(Adapter, REG_RRSR+2, rtw_read8(Adapter, REG_RRSR+2)&0xf0); + + // Set RTS initial rate + while(BrateCfg > 0x1) + { + BrateCfg = (BrateCfg>> 1); + RateIndex++; + } + // Ziv - Check + rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex); + } + break; + case HW_VAR_TXPAUSE: + rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val)); + break; + case HW_VAR_BCN_FUNC: + hw_var_set_bcn_func(Adapter, variable, val); + break; + case HW_VAR_CORRECT_TSF: +#ifdef CONFIG_CONCURRENT_MODE + hw_var_set_correct_tsf(Adapter, variable, val); +#else + { + u64 tsf; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) -1024; //us + tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pHalData->RegTxPause |= STOP_BCNQ;BIT(6) + //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6))); + StopTxBeacon(Adapter); + } + + //disable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3))); + + rtw_write32(Adapter, REG_TSFTR, tsf); + rtw_write32(Adapter, REG_TSFTR+4, tsf>>32); + + //enable related TSF function + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3)); + + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pHalData->RegTxPause &= (~STOP_BCNQ); + //rtw_write8(Adapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)&(~BIT(6)))); + ResumeTxBeacon(Adapter); + } + } +#endif + break; + case HW_VAR_CHECK_BSSID: + if(*((u8 *)val)) + { + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN); + } + else + { + u32 val32; + + val32 = rtw_read32(Adapter, REG_RCR); + val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtw_write32(Adapter, REG_RCR, val32); + } + break; + case HW_VAR_MLME_DISCONNECT: +#ifdef CONFIG_CONCURRENT_MODE + hw_var_set_mlme_disconnect(Adapter, variable, val); +#else + { + //Set RCR to not to receive data frame when NO LINK state + //rtw_write32(Adapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF); + //reject all data frames + rtw_write16(Adapter, REG_RXFLTMAP2,0x00); + + //reset TSF + rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1))); + + //disable update TSF + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4)); + } +#endif + break; + case HW_VAR_MLME_SITESURVEY: + hw_var_set_mlme_sitesurvey(Adapter, variable, val); + break; + case HW_VAR_MLME_JOIN: +#ifdef CONFIG_CONCURRENT_MODE + hw_var_set_mlme_join(Adapter, variable, val); +#else + { + u8 RetryLimit = 0x30; + u8 type = *((u8 *)val); + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + + if(type == 0) // prepare to join + { + //enable to rx data frame.Accept all data frame + //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); + rtw_write16(Adapter, REG_RXFLTMAP2,0xFFFF); + + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48; + } + else // Ad-hoc Mode + { + RetryLimit = 0x7; + } + } + else if(type == 1) //joinbss_event call back when join res < 0 + { + rtw_write16(Adapter, REG_RXFLTMAP2,0x00); + } + else if(type == 2) //sta add event call back + { + //enable update TSF + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4))); + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) + { + //fixed beacon issue for 8191su........... + rtw_write8(Adapter,0x542 ,0x02); + RetryLimit = 0x7; + } + } + + rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); + } +#endif + break; + + case HW_VAR_ON_RCR_AM: + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_AM); + DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(Adapter, REG_RCR)); + break; + case HW_VAR_OFF_RCR_AM: + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)& (~RCR_AM)); + DBG_871X("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(Adapter, REG_RCR)); + break; + + case HW_VAR_BEACON_INTERVAL: + rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME: + { + u8 u1bAIFS, aSifsTime; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + rtw_write8(Adapter, REG_SLOT, val[0]); + + if(pmlmeinfo->WMM_enable == 0) + { + if( pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime); + + // Temporary removed, 2008.06.20. + rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS); + rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS); + rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS); + rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS); + } + } + break; + case HW_VAR_RESP_SIFS: + { +#if 0 + // SIFS for OFDM Data ACK + rtw_write8(Adapter, REG_SIFS_CTX+1, val[0]); + // SIFS for OFDM consecutive tx like CTS data! + rtw_write8(Adapter, REG_SIFS_TRX+1, val[1]); + + rtw_write8(Adapter,REG_SPEC_SIFS+1, val[0]); + rtw_write8(Adapter,REG_MAC_SPEC_SIFS+1, val[0]); + + // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change. + rtw_write8(Adapter, REG_R2T_SIFS+1, val[0]); //0x08 - CCK + rtw_write8(Adapter, REG_T2T_SIFS+1, val[0]); //0x0e - OFDM +#else + //SIFS_Timer = 0x0a0a0808; + //RESP_SIFS for CCK + rtw_write8(Adapter, REG_R2T_SIFS, val[0]); // SIFS_T2T_CCK (0x08) + rtw_write8(Adapter, REG_R2T_SIFS+1, val[1]); //SIFS_R2T_CCK(0x08) + //RESP_SIFS for OFDM + rtw_write8(Adapter, REG_T2T_SIFS, val[2]); //SIFS_T2T_OFDM (0x0a) + rtw_write8(Adapter, REG_T2T_SIFS+1, val[3]); //SIFS_R2T_OFDM(0x0a) +#endif + } + break; + case HW_VAR_ACK_PREAMBLE: + { + u8 regTmp; + u8 bShortPreamble = *( (PBOOLEAN)val ); + // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) + regTmp = (pHalData->nCur40MhzPrimeSC)<<5; + //regTmp = 0; + if(bShortPreamble) + regTmp |= 0x80; + + rtw_write8(Adapter, REG_RRSR+2, regTmp); + } + break; + case HW_VAR_SEC_CFG: +#ifdef CONFIG_CONCURRENT_MODE + rtw_write8(Adapter, REG_SECCFG, 0x0c|BIT(5));// enable tx enc and rx dec engine, and no key search for MC/BC +#else + rtw_write8(Adapter, REG_SECCFG, *((u8 *)val)); +#endif + break; + case HW_VAR_DM_FLAG: + pdmpriv->DMFlag = *((u8 *)val); + break; + case HW_VAR_DM_FUNC_OP: + if(val[0]) + {// save dm flag + pdmpriv->DMFlag_tmp = pdmpriv->DMFlag; + } + else + {// restore dm flag + pdmpriv->DMFlag = pdmpriv->DMFlag_tmp; + } + break; + case HW_VAR_DM_FUNC_SET: + pdmpriv->DMFlag |= *((u8 *)val); + break; + case HW_VAR_DM_FUNC_CLR: + pdmpriv->DMFlag &= *((u8 *)val); + break; + case HW_VAR_CAM_EMPTY_ENTRY: + { + u8 ucIndex = *((u8 *)val); + u8 i; + u32 ulCommand=0; + u32 ulContent=0; + u32 ulEncAlgo=CAM_AES; + + for(i=0;iAcParam_BE = ((u32 *)(val))[0]; + rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]); + break; + case HW_VAR_AC_PARAM_BK: + rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]); + break; + case HW_VAR_ACM_CTRL: + { + u8 acm_ctrl = *((u8 *)val); + u8 AcmCtrl = rtw_read8( Adapter, REG_ACMHWCTRL); + + if(acm_ctrl > 1) + AcmCtrl = AcmCtrl | 0x1; + + if(acm_ctrl & BIT(3)) + AcmCtrl |= AcmHw_VoqEn; + else + AcmCtrl &= (~AcmHw_VoqEn); + + if(acm_ctrl & BIT(2)) + AcmCtrl |= AcmHw_ViqEn; + else + AcmCtrl &= (~AcmHw_ViqEn); + + if(acm_ctrl & BIT(1)) + AcmCtrl |= AcmHw_BeqEn; + else + AcmCtrl &= (~AcmHw_BeqEn); + + DBG_871X("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ); + rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl ); + } + break; + case HW_VAR_AMPDU_MIN_SPACE: + { + u8 MinSpacingToSet; + u8 SecMinSpace; + + MinSpacingToSet = *((u8 *)val); + if(MinSpacingToSet <= 7) + { + switch(Adapter->securitypriv.dot11PrivacyAlgrthm) + { + case _NO_PRIVACY_: + case _AES_: + SecMinSpace = 0; + break; + + case _WEP40_: + case _WEP104_: + case _TKIP_: + case _TKIP_WTMIC_: + SecMinSpace = 6; + break; + default: + SecMinSpace = 7; + break; + } + + if(MinSpacingToSet < SecMinSpace){ + MinSpacingToSet = SecMinSpace; + } + + //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", Adapter->MgntInfo.MinSpaceCfg)); + rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet); + } + } + break; + case HW_VAR_AMPDU_FACTOR: + { + u8 RegToSet_Normal[4]={0x41,0xa8,0x72, 0xb9}; + u8 RegToSet_BT[4]={0x31,0x74,0x42, 0x97}; + u8 FactorToSet; + u8 *pRegToSet; + u8 index = 0; + +#ifdef CONFIG_BT_COEXIST + if( (pHalData->bt_coexist.BT_Coexist) && + (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC4) ) + pRegToSet = RegToSet_BT; // 0x97427431; + else +#endif + pRegToSet = RegToSet_Normal; // 0xb972a841; + + FactorToSet = *((u8 *)val); + if(FactorToSet <= 3) + { + FactorToSet = (1<<(FactorToSet + 2)); + if(FactorToSet>0xf) + FactorToSet = 0xf; + + for(index=0; index<4; index++) + { + if((pRegToSet[index] & 0xf0) > (FactorToSet<<4)) + pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet<<4); + + if((pRegToSet[index] & 0x0f) > FactorToSet) + pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet); + + rtw_write8(Adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]); + } + + //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet)); + } + } + break; + case HW_VAR_RXDMA_AGG_PG_TH: + #ifdef CONFIG_USB_RX_AGGREGATION + { + u8 threshold = *((u8 *)val); + if( threshold == 0) + { + threshold = pHalData->UsbRxAggPageCount; + } + rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold); + } + #endif + break; + case HW_VAR_SET_RPWM: + rtw_write8(Adapter, REG_USB_HRPWM, *((u8 *)val)); + break; + case HW_VAR_H2C_FW_PWRMODE: + { + u8 psmode = (*(u8 *)val); + + // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power + // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. + if( (psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID))) + { + rtl8192c_dm_RF_Saving(Adapter, _TRUE); + } + rtl8192c_set_FwPwrMode_cmd(Adapter, psmode); + } + break; + case HW_VAR_H2C_FW_JOINBSSRPT: + { + u8 mstatus = (*(u8 *)val); + rtl8192c_set_FwJoinBssReport_cmd(Adapter, mstatus); + } + break; +#ifdef CONFIG_P2P_PS + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + { + u8 p2p_ps_state = (*(u8 *)val); + rtl8192c_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state); + } + break; +#endif // CONFIG_P2P_PS +#ifdef CONFIG_TDLS + case HW_VAR_TDLS_WRCR: + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)&(~ BIT(6) )); + break; + case HW_VAR_TDLS_INIT_CH_SEN: + { + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)&(~ BIT(6) )&(~ BIT(7) )); + rtw_write16(Adapter, REG_RXFLTMAP2,0xffff); + + //disable update TSF + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4)); + } + break; + case HW_VAR_TDLS_DONE_CH_SEN: + { + //enable update TSF + rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~ BIT(4))); + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|(BIT(7) )); + } + break; + case HW_VAR_TDLS_RS_RCR: + rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|(BIT(6))); + break; +#endif //CONFIG_TDLS + case HW_VAR_INITIAL_GAIN: + { + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + u32 rx_gain = ((u32 *)(val))[0]; + + if(rx_gain == 0xff){//restore rx gain + pDigTable->CurIGValue = pDigTable->BackupIGValue; + PHY_SetBBReg(Adapter, rOFDM0_XAAGCCore1, 0x7f,pDigTable->CurIGValue ); + PHY_SetBBReg(Adapter, rOFDM0_XBAGCCore1, 0x7f,pDigTable->CurIGValue); + } + else{ + pDigTable->BackupIGValue = pDigTable->CurIGValue; + PHY_SetBBReg(Adapter, rOFDM0_XAAGCCore1, 0x7f,rx_gain ); + PHY_SetBBReg(Adapter, rOFDM0_XBAGCCore1, 0x7f,rx_gain); + pDigTable->CurIGValue = (u8)rx_gain; + } + + + } + break; + case HW_VAR_TRIGGER_GPIO_0: + rtl8192cu_trigger_gpio_0(Adapter); + break; +#ifdef CONFIG_BT_COEXIST + case HW_VAR_BT_SET_COEXIST: + { + u8 bStart = (*(u8 *)val); + rtl8192c_set_dm_bt_coexist(Adapter, bStart); + } + break; + case HW_VAR_BT_ISSUE_DELBA: + { + u8 dir = (*(u8 *)val); + rtl8192c_issue_delete_ba(Adapter, dir); + } + break; +#endif +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + + case HW_VAR_ANTENNA_DIVERSITY_LINK: + SwAntDivRestAfterLink8192C(Adapter); + break; + case HW_VAR_ANTENNA_DIVERSITY_SELECT: + { + u8 Optimum_antenna = (*(u8 *)val); + //switch antenna to Optimum_antenna + // DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B"); + if(pHalData->CurAntenna != Optimum_antenna) + { + PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna); + pHalData->CurAntenna = Optimum_antenna ; + //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B"); + } + } + break; +#endif + case HW_VAR_EFUSE_BYTES: // To set EFUE total used bytes, added by Roger, 2008.12.22. + pHalData->EfuseUsedBytes = *((u16 *)val); + break; + case HW_VAR_FIFO_CLEARN_UP: + { + #define RW_RELEASE_EN BIT18 + #define RXDMA_IDLE BIT17 + + struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv; + u8 trycnt = 100; + + //pause tx + rtw_write8(Adapter,REG_TXPAUSE,0xff); + + //keep sn + Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter,REG_NQOS_SEQ); + + if(pwrpriv->bkeepfwalive != _TRUE) + { + //RX DMA stop + 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)) + break; + }while(trycnt--); + if(trycnt ==0) + DBG_8192C("Stop RX DMA failed...... \n"); + + //RQPN Load 0 + rtw_write16(Adapter,REG_RQPN_NPQ,0x0); + rtw_write32(Adapter,REG_RQPN,0x80000000); + rtw_mdelay_os(10); + } + } + break; + case HW_VAR_WOWLAN: +#ifdef CONFIG_WOWLAN + { + struct wowlan_ioctl_param *poidparam; + + int res; + + poidparam = (struct wowlan_ioctl_param *)val; + switch (poidparam->subcode){ + case WOWLAN_PATTERN_MATCH: + //Turn on the Pattern Match feature + DBG_8192C("\n PATTERN_MATCH poidparam->subcode_value=%d\n",poidparam->subcode_value); + if(poidparam->subcode_value==1){ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)|BIT(1))); + Adapter->pwrctrlpriv.wowlan_pattern=_TRUE; + DBG_8192C("%s Adapter->pwrctrlpriv.wowlan_pattern=%x\n",__FUNCTION__,Adapter->pwrctrlpriv.wowlan_pattern); + } + else{ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)&~BIT(1))); + Adapter->pwrctrlpriv.wowlan_pattern=_FALSE; + } + break; + case WOWLAN_MAGIC_PACKET: + //Turn on the Magic Packet feature + DBG_8192C("\n MAGIC_PACKET poidparam->subcode_value=%d\n",poidparam->subcode_value); + if(poidparam->subcode_value==1){ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)|BIT(2))); + Adapter->pwrctrlpriv.wowlan_magic=_TRUE; + DBG_8192C("%s Adapter->pwrctrlpriv.wowlan_magic=%x\n",__FUNCTION__,Adapter->pwrctrlpriv.wowlan_magic); + } + else{ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)&~BIT(2))); + Adapter->pwrctrlpriv.wowlan_magic=_FALSE; + } + break; + case WOWLAN_UNICAST: + //Turn on the Unicast wakeup feature + if(poidparam->subcode_value==1){ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)|BIT(3))); + Adapter->pwrctrlpriv.wowlan_unicast=_TRUE; + } + else{ + //rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)&~BIT(3))); + Adapter->pwrctrlpriv.wowlan_unicast=_FALSE; + DBG_8192C("%s Adapter->pwrctrlpriv.wowlan_unicast=%x\n",__FUNCTION__,Adapter->pwrctrlpriv.wowlan_unicast); + } + break; + case WOWLAN_SET_PATTERN: + //Setting the Pattern for wowlan + res=rtw_wowlan_set_pattern(Adapter,poidparam->pattern); + if(res) + DBG_8192C("rtw_wowlan_set_pattern retern value=0x%x",res); + break; + case WOWLAN_DUMP_REG: + //dump the WKFMCAM and WOW_CTRL register + /*DBG_8192C("\n\n\n\n rtw_wowlan_ctrl: WOW_CTRL=0x%x \n",rtw_read8(Adapter, REG_WOW_CTRL)); + DBG_8192C("print WKFMCAM index =%d ",poidparam->data[0]); + { int cmd=0,offset=0; + for(offset=0;offset<5;offset++){ + cmd=BIT(31)|(poidparam->data[0]+offset); + rtw_write32(Adapter, REG_WKFMCAM_CMD, cmd); + DBG_8192C("offset[%d]=0x%.8x ",offset,rtw_read32(Adapter, REG_WKFMCAM_RWD)); + DBG_8192C("offset[%d]=MSB 0x%x:0x%x:0x%x:0x%x ",offset,rtw_read8(Adapter, REG_WKFMCAM_RWD+3),rtw_read8(Adapter, REG_WKFMCAM_RWD+2),rtw_read8(Adapter, REG_WKFMCAM_RWD+1),rtw_read8(Adapter, REG_WKFMCAM_RWD)); + } + }*/ + + break; + case WOWLAN_ENABLE: + SetFwRelatedForWoWLAN8192CU(Adapter, _TRUE); + //Set Pattern + if(Adapter->pwrctrlpriv.wowlan_pattern==_TRUE) + rtw_wowlan_reload_pattern(Adapter); + rtl8192c_set_wowlan_cmd(Adapter); + rtw_write8(Adapter, 0x6, rtw_read8(Adapter, 0x6)|BIT(3)); + rtw_msleep_os(10); + //DBG_8192C(" \n REG_WOW_CTRL=0x%x \n",rtw_read8(Adapter, REG_WOW_CTRL)); +// if(rtw_read8(Adapter, REG_WOW_CTRL)==0) +// rtw_write8(Adapter, REG_WOW_CTRL, (rtw_read8(Adapter, REG_WOW_CTRL)|BIT(1)|BIT(2)|BIT(3))); + //DBG_8192C(" \n REG_WOW_CTRL=0x%x \n",rtw_read8(Adapter, REG_WOW_CTRL)); + break; + + case WOWLAN_DISABLE: + Adapter->pwrctrlpriv.wowlan_mode=_FALSE; + rtl8192c_set_wowlan_cmd(Adapter); + rtw_msleep_os(10); + break; + + case WOWLAN_STATUS: + poidparam->wakeup_reason = rtw_read8(Adapter, REG_WOWLAN_REASON); + DBG_8192C("wake on wlan reason 0x%02x\n", poidparam->wakeup_reason); + break; + + default: + break; + } + if (Adapter->pwrctrlpriv.wowlan_unicast||Adapter->pwrctrlpriv.wowlan_magic || Adapter->pwrctrlpriv.wowlan_pattern) + Adapter->pwrctrlpriv.wowlan_mode =_TRUE; + else + Adapter->pwrctrlpriv.wowlan_mode =_FALSE; + } + + break; +#endif //CONFIG_WOWLAN + case HW_VAR_CHECK_TXBUF: +#ifdef CONFIG_CONCURRENT_MODE + { + int i; + u8 RetryLimit = 0x01; + + //rtw_write16(Adapter, REG_RL,0x0101); + rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); + + for(i=0;i<1000;i++) + { + if(rtw_read32(Adapter, 0x200) != rtw_read32(Adapter, 0x204)) + { + //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(Adapter, 0x204), rtw_read32(Adapter, 0x200), i); + rtw_msleep_os(10); + } + else + { + DBG_871X("no packet in tx packet buffer (%d)\n", i); + break; + } + } + + RetryLimit = 0x30; + rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT); + + } +#endif + break; + case HW_VAR_BCN_VALID: + //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw + rtw_write8(Adapter, REG_TDECTRL+2, rtw_read8(Adapter, REG_TDECTRL+2) | BIT0); + break; + case HW_VAR_USB_RXAGG_PAGE_TO: + rtw_write8(Adapter, REG_USB_DMA_AGG_TO, *((u8 *)val)); + break; + default: + break; + } + +_func_exit_; +} + +void GetHwReg8192CU(PADAPTER Adapter, u8 variable, u8* val) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + +_func_enter_; + + switch(variable) + { + case HW_VAR_BASIC_RATE: + *((u16 *)(val)) = pHalData->BasicRateSet; + case HW_VAR_TXPAUSE: + val[0] = rtw_read8(Adapter, REG_TXPAUSE); + break; + case HW_VAR_BCN_VALID: + //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 + val[0] = (BIT0 & rtw_read8(Adapter, REG_TDECTRL+2))?_TRUE:_FALSE; + break; + case HW_VAR_DM_FLAG: + val[0] = pHalData->dmpriv.DMFlag; + break; + case HW_VAR_RF_TYPE: + val[0] = pHalData->rf_type; + break; + case HW_VAR_FWLPS_RF_ON: + { + //When we halt NIC, we should check if FW LPS is leave. + u32 valRCR; + + if(Adapter->pwrctrlpriv.rf_pwrstate == rf_off) + { + // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, + // because Fw is unload. + val[0] = _TRUE; + } + else + { + valRCR = rtw_read32(Adapter, REG_RCR); + valRCR &= 0x00070000; + if(valRCR) + val[0] = _FALSE; + else + val[0] = _TRUE; + } + } + break; +#ifdef CONFIG_ANTENNA_DIVERSITY + case HW_VAR_CURRENT_ANTENNA: + val[0] = pHalData->CurAntenna; + break; +#endif + case HW_VAR_EFUSE_BYTES: // To get EFUE total used bytes, added by Roger, 2008.12.22. + *((u16 *)(val)) = pHalData->EfuseUsedBytes; + break; + case HW_VAR_VID: + *((u16 *)(val)) = pHalData->EEPROMVID; + break; + case HW_VAR_PID: + *((u16 *)(val)) = pHalData->EEPROMPID; + break; + default: + break; + } + +_func_exit_; +} + +// +// Description: +// Query setting of specified variable. +// +u8 +GetHalDefVar8192CUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 bResult = _TRUE; + + switch(eVariable) + { + case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: +#if 0 //trunk + { + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + struct sta_priv * pstapriv = &Adapter->stapriv; + struct sta_info * psta; + psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress); + if(psta) + { + *((int *)pValue) = psta->rssi_stat.UndecoratedSmoothedPWDB; + } + } +#else //v4 branch + //if(check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ + *((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB; + //} + //else{ + + //} +#endif + break; + case HAL_DEF_IS_SUPPORT_ANT_DIV: + #ifdef CONFIG_ANTENNA_DIVERSITY + *((u8 *)pValue) = (IS_92C_SERIAL(pHalData->VersionID) ||(pHalData->AntDivCfg==0))?_FALSE:_TRUE; + #endif + break; + case HAL_DEF_CURRENT_ANTENNA: + #ifdef CONFIG_ANTENNA_DIVERSITY + *(( u8*)pValue) = pHalData->CurAntenna; + #endif + break; + case HAL_DEF_DRVINFO_SZ: + *(( u32*)pValue) = DRVINFO_SZ; + break; + case HAL_DEF_MAX_RECVBUF_SZ: + *(( u32*)pValue) = MAX_RECVBUF_SZ; + break; + case HAL_DEF_RX_PACKET_OFFSET: + *(( u32*)pValue) = RXDESC_SIZE + DRVINFO_SZ; + break; + case HAL_DEF_DBG_DUMP_RXPKT: + *(( u8*)pValue) = pHalData->bDumpRxPkt; + break; + case HAL_DEF_DBG_DM_FUNC: + *(( u8*)pValue) = pHalData->dmpriv.DMFlag; + break; + default: + //RT_TRACE(COMP_INIT, DBG_WARNING, ("GetHalDefVar8192CUsb(): Unkown variable: %d!\n", eVariable)); + bResult = _FALSE; + break; + } + + return bResult; +} + + + + +// +// Description: +// Change default setting of specified variable. +// +u8 +SetHalDefVar8192CUsb( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 bResult = _TRUE; + + switch(eVariable) + { + case HAL_DEF_DBG_DUMP_RXPKT: + pHalData->bDumpRxPkt = *(( u8*)pValue); + break; + case HAL_DEF_DBG_DM_FUNC: + { + u8 dm_func = *(( u8*)pValue); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + if(dm_func == 0){ //disable all dynamic func + pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE; + DBG_8192C("==> Disable all dynamic function...\n"); + } + else if(dm_func == 1){//disable DIG + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_DIG); + DBG_8192C("==> Disable DIG...\n"); + } + else if(dm_func == 2){//disable High power + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_HP); + } + else if(dm_func == 3){//disable tx power tracking + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_SS); + DBG_8192C("==> Disable tx power tracking...\n"); + } + else if(dm_func == 4){//disable BT coexistence + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_BT); + } + else if(dm_func == 5){//disable antenna diversity + pdmpriv->DMFlag &= (~DYNAMIC_FUNC_ANT_DIV); + } + else if(dm_func == 6){//turn on all dynamic func + if(!(pdmpriv->DMFlag & DYNAMIC_FUNC_DIG)) + { + struct dm_priv *pdmpriv = &pHalData->dmpriv; + DIG_T *pDigTable = &pdmpriv->DM_DigTable; + pDigTable->PreIGValue = rtw_read8(Adapter,0xc50); + } + + pdmpriv->DMFlag |= (DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS| + DYNAMIC_FUNC_BT|DYNAMIC_FUNC_ANT_DIV) ; + DBG_8192C("==> Turn on all dynamic function...\n"); + } + } + break; + default: + //RT_TRACE(COMP_INIT, DBG_TRACE, ("SetHalDefVar819xUsb(): Unkown variable: %d!\n", eVariable)); + bResult = _FALSE; + break; + } + + return bResult; +} + +u32 _update_92cu_basic_rate(_adapter *padapter, unsigned int mask) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); +#endif + unsigned int BrateCfg = 0; + +#ifdef CONFIG_BT_COEXIST + if( (pbtpriv->BT_Coexist) && (pbtpriv->BT_CoexistType == BT_CSR_BC4) ) + { + BrateCfg = mask & 0x151; + //DBG_8192C("BT temp disable cck 2/5.5/11M, (0x%x = 0x%x)\n", REG_RRSR, BrateCfg & 0x151); + } + else +#endif + { + if(pHalData->VersionID != VERSION_TEST_CHIP_88C) + BrateCfg = mask & 0x15F; + else //for 88CU 46PING setting, Disable CCK 2M, 5.5M, Others must tuning + BrateCfg = mask & 0x159; + } + + BrateCfg |= 0x01; // default enable 1M ACK rate + + return BrateCfg; +} + +void _update_response_rate(_adapter *padapter,unsigned int mask) +{ + u8 RateIndex = 0; + // Set RRSR rate table. + rtw_write8(padapter, REG_RRSR, mask&0xff); + rtw_write8(padapter,REG_RRSR+1, (mask>>8)&0xff); + + + // Set RTS initial rate + while(mask > 0x1) + { + mask = (mask>> 1); + RateIndex++; + } + rtw_write8(padapter, REG_INIRTS_RATE_SEL, RateIndex); +} + +void UpdateHalRAMask8192CUsb(PADAPTER padapter, u32 mac_id) +{ + //volatile unsigned int result; + u8 init_rate=0; + u8 networkType, raid; + u32 mask; + u8 shortGIrate = _FALSE; + int supportRateNum = 0; + struct sta_info *psta; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv *pbtpriv = &(pHalData->bt_coexist); +#endif + + if (mac_id >= NUM_STA) //CAM_SIZE + { + return; + } + + psta = pmlmeinfo->FW_sta_info[mac_id].psta; + if(psta == NULL) + { + return; + } + + switch (mac_id) + { + case 0:// for infra mode +#ifdef CONFIG_CONCURRENT_MODE + case 2:// first station uses macid=0, second station uses macid=2 +#endif + supportRateNum = rtw_get_rateset_len(cur_network->SupportedRates); + networkType = judge_network_type(padapter, cur_network->SupportedRates, supportRateNum) & 0xf; + //pmlmeext->cur_wireless_mode = networkType; + raid = networktype_to_raid(networkType); + + mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); + mask |= (pmlmeinfo->HT_enable)? update_MSC_rate(&(pmlmeinfo->HT_caps)): 0; + mask |= ((raid<<28)&0xf0000000); + + if (support_short_GI(padapter, &(pmlmeinfo->HT_caps))) + { + shortGIrate = _TRUE; + } + + break; + + case 1://for broadcast/multicast + supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); + if(pmlmeext->cur_wireless_mode & WIRELESS_11B) + networkType = WIRELESS_11B; + else + networkType = WIRELESS_11G; + raid = networktype_to_raid(networkType); + + mask = update_basic_rate(cur_network->SupportedRates, supportRateNum); + mask |= ((raid<<28)&0xf0000000); + + break; + + default: //for each sta in IBSS +#ifdef CONFIG_TDLS + if(psta->tdls_sta_state & TDLS_LINKED_STATE) + { + shortGIrate = update_sgi_tdls(padapter, psta); + mask = update_mask_tdls(padapter, psta); + raid = mask>>28; + break; + } + else +#endif //CONFIG_TDLS + { + supportRateNum = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); + networkType = judge_network_type(padapter, pmlmeinfo->FW_sta_info[mac_id].SupportedRates, supportRateNum) & 0xf; + //pmlmeext->cur_wireless_mode = networkType; + raid = networktype_to_raid(networkType); + + mask = update_supported_rate(cur_network->SupportedRates, supportRateNum); + mask |= ((raid<<28)&0xf0000000); + + //todo: support HT in IBSS + + break; + } + } + +#ifdef CONFIG_BT_COEXIST + if( (pbtpriv->BT_Coexist) && + (pbtpriv->BT_CoexistType == BT_CSR_BC4) && + (pbtpriv->BT_CUR_State) && + (pbtpriv->BT_Ant_isolation) && + ((pbtpriv->BT_Service==BT_SCO)|| + (pbtpriv->BT_Service==BT_Busy)) ) + mask &= 0xffffcfc0; + else +#endif + mask &=0xffffffff; + + + init_rate = get_highest_rate_idx(mask)&0x3f; + + if(pHalData->fw_ractrl == _TRUE) + { + u8 arg = 0; + + //arg = (cam_idx-4)&0x1f;//MACID + arg = mac_id&0x1f;//MACID + + arg |= BIT(7); + + if (shortGIrate==_TRUE) + arg |= BIT(5); + + DBG_871X("update raid entry, mask=0x%x, arg=0x%x\n", mask, arg); + psta->ra_mask=mask; +#ifdef CONFIG_INTEL_PROXIM + if(padapter->proximity.proxim_on ==_TRUE){ + arg &= ~BIT(6); + } + else { + arg |= BIT(6); + } +#endif //CONFIG_INTEL_PROXIM + rtl8192c_set_raid_cmd(padapter, mask, arg); + + } + else + { + if (shortGIrate==_TRUE) + init_rate |= BIT(6); + + rtw_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id), init_rate); + } + + + //set ra_id + psta->raid = raid; + psta->init_rate = init_rate; + + //set correct initial date rate for each mac_id + pdmpriv->INIDATA_RATE[mac_id] = init_rate; +} + +void SetBeaconRelatedRegisters8192CUsb(PADAPTER padapter) +{ + u32 value32; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //reset TSF, enable update TSF, correcting TSF On Beacon + + //REG_BCN_INTERVAL + //REG_BCNDMATIM + //REG_ATIMWND + //REG_TBTT_PROHIBIT + //REG_DRVERLYINT + //REG_BCN_MAX_ERR + //REG_BCNTCFG //(0x510) + //REG_DUAL_TSF_RST + //REG_BCN_CTRL //(0x550) + + //BCN interval + rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); + rtw_write8(padapter, REG_ATIMWND, 0x02);// 2ms + + _InitBeaconParameters(padapter); + + rtw_write8(padapter, REG_SLOT, 0x09); + + value32 =rtw_read32(padapter, REG_TCR); + value32 &= ~TSFRST; + rtw_write32(padapter, REG_TCR, value32); + + value32 |= TSFRST; + rtw_write32(padapter, REG_TCR, value32); + + // NOTE: Fix test chip's bug (about contention windows's randomness) + rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50); + rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50); + + _BeaconFunctionEnable(padapter, _TRUE, _TRUE); + + ResumeTxBeacon(padapter); + + //rtw_write8(padapter, 0x422, rtw_read8(padapter, 0x422)|BIT(6)); + + //rtw_write8(padapter, 0x541, 0xff); + + //rtw_write8(padapter, 0x542, rtw_read8(padapter, 0x541)|BIT(0)); + + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(1)); + +} + +static void rtl8192cu_init_default_value(_adapter * padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + struct dm_priv *pdmpriv = &pHalData->dmpriv; + u8 i; + + //init default value + pHalData->fw_ractrl = _FALSE; + pHalData->bIQKInitialized = _FALSE; + if(!pwrctrlpriv->bkeepfwalive) + pHalData->LastHMEBoxNum = 0; + + pHalData->bIQKInitialized = _FALSE; + //init dm default value + pdmpriv->TM_Trigger = 0; + pdmpriv->binitialized = _FALSE; + pdmpriv->prv_traffic_idx = 3; + pdmpriv->initialize = 0; + + pdmpriv->ThermalValue_HP_index = 0; + for(i = 0; i < HP_THERMAL_NUM; i++) + pdmpriv->ThermalValue_HP[i] = 0; +} + +static u8 rtl8192cu_ps_func(PADAPTER Adapter,HAL_INTF_PS_FUNC efunc_id, u8 *val) +{ + u8 bResult = _TRUE; + switch(efunc_id){ + + #if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED) + case HAL_USB_SELECT_SUSPEND: + { + u8 bfwpoll = *(( u8*)val); + rtl8192c_set_FwSelectSuspend_cmd(Adapter,bfwpoll ,500);//note fw to support hw power down ping detect + } + break; + #endif //CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED + + default: + break; + } + return bResult; +} + +void rtl8192cu_set_hal_ops(_adapter * padapter) +{ + struct hal_ops *pHalFunc = &padapter->HalFunc; + +_func_enter_; + + padapter->HalData = rtw_zmalloc(sizeof(HAL_DATA_TYPE)); + if(padapter->HalData == NULL){ + DBG_8192C("cant not alloc memory for HAL DATA \n"); + } + //_rtw_memset(padapter->HalData, 0, sizeof(HAL_DATA_TYPE)); + padapter->hal_data_sz = sizeof(HAL_DATA_TYPE); + + pHalFunc->hal_init = &rtl8192cu_hal_init; + pHalFunc->hal_deinit = &rtl8192cu_hal_deinit; + + //pHalFunc->free_hal_data = &rtl8192c_free_hal_data; + + pHalFunc->inirp_init = &rtl8192cu_inirp_init; + pHalFunc->inirp_deinit = &rtl8192cu_inirp_deinit; + + pHalFunc->init_xmit_priv = &rtl8192cu_init_xmit_priv; + pHalFunc->free_xmit_priv = &rtl8192cu_free_xmit_priv; + + pHalFunc->init_recv_priv = &rtl8192cu_init_recv_priv; + pHalFunc->free_recv_priv = &rtl8192cu_free_recv_priv; +#ifdef CONFIG_SW_LED + pHalFunc->InitSwLeds = &rtl8192cu_InitSwLeds; + pHalFunc->DeInitSwLeds = &rtl8192cu_DeInitSwLeds; +#else //case of hw led or no led + pHalFunc->InitSwLeds = NULL; + pHalFunc->DeInitSwLeds = NULL; +#endif//CONFIG_SW_LED + + //pHalFunc->dm_init = &rtl8192c_init_dm_priv; + //pHalFunc->dm_deinit = &rtl8192c_deinit_dm_priv; + + pHalFunc->init_default_value = &rtl8192cu_init_default_value; + pHalFunc->intf_chip_configure = &rtl8192cu_interface_configure; + pHalFunc->read_adapter_info = &ReadAdapterInfo8192CU; + + //pHalFunc->set_bwmode_handler = &PHY_SetBWMode8192C; + //pHalFunc->set_channel_handler = &PHY_SwChnl8192C; + + //pHalFunc->hal_dm_watchdog = &rtl8192c_HalDmWatchDog; + + pHalFunc->SetHwRegHandler = &SetHwReg8192CU; + pHalFunc->GetHwRegHandler = &GetHwReg8192CU; + pHalFunc->GetHalDefVarHandler = &GetHalDefVar8192CUsb; + pHalFunc->SetHalDefVarHandler = &SetHalDefVar8192CUsb; + + pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8192CUsb; + pHalFunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8192CUsb; + + //pHalFunc->Add_RateATid = &rtl8192c_Add_RateATid; + +//#ifdef CONFIG_SW_ANTENNA_DIVERSITY + //pHalFunc->AntDivBeforeLinkHandler = &SwAntDivBeforeLink8192C; + //pHalFunc->AntDivCompareHandler = &SwAntDivCompare8192C; +//#endif + + pHalFunc->hal_xmit = &rtl8192cu_hal_xmit; + pHalFunc->mgnt_xmit = &rtl8192cu_mgnt_xmit; + pHalFunc->hal_xmitframe_enqueue = &rtl8192cu_hal_xmitframe_enqueue; + + //pHalFunc->read_bbreg = &rtl8192c_PHY_QueryBBReg; + //pHalFunc->write_bbreg = &rtl8192c_PHY_SetBBReg; + //pHalFunc->read_rfreg = &rtl8192c_PHY_QueryRFReg; + //pHalFunc->write_rfreg = &rtl8192c_PHY_SetRFReg; + +#ifdef CONFIG_HOSTAPD_MLME + pHalFunc->hostap_mgnt_xmit_entry = &rtl8192cu_hostap_mgnt_xmit_entry; +#endif + pHalFunc->interface_ps_func = &rtl8192cu_ps_func; + + rtl8192c_set_hal_ops(pHalFunc); +_func_exit_; + +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c new file mode 100755 index 00000000..95233376 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c @@ -0,0 +1,1207 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_OPS_OS_C_ + +#include +#include +#include +#include + +#ifndef PLATFORM_OS_CE + #error "PLATFORM_OS_CE shall be set \n" +#endif + +#ifndef CONFIG_USB_HCI + #error "CONFIG_USB_HCI shall be on!\n" +#endif + +#include +#include + +#include + + +struct zero_bulkout_context +{ + void *pbuf; + void *purb; + void *pirp; + void *padapter; +}; + + + +#define PUSB_ERROR LPDWORD +#define USBD_HALTED(Status) ((ULONG)(Status) >> 30 == 3) + + +USB_PIPE ffaddr2pipehdl(struct dvobj_priv *pNdisCEDvice, u32 addr); + + +static NTSTATUS usb_async_interrupt_in_complete( LPVOID Context ); +static NTSTATUS usb_async_interrupt_out_complete( LPVOID Context ); + +DWORD usb_write_port_complete( LPVOID Context ); +DWORD usb_read_port_complete( LPVOID Context ); + +void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); +_func_exit_; +} + + + +BOOL +CloseTransferHandle( + LPCUSB_FUNCS pUsbFuncs, + USB_TRANSFER hTransfer + ) +{ + BOOL bRc = TRUE; + + // This assert may fail on suprise remove, + // but should pass during normal I/O. + // ASSERT( pUsbFuncs->lpIsTransferComplete(hTransfer) ); + + // CloseTransfer aborts any pending transfers + if ( !pUsbFuncs->lpCloseTransfer(hTransfer) ) { + + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("*** CloseTransfer ERROR:%d ***\n", GetLastError())); + bRc = FALSE; + } + + return bRc; +} + + +BOOL +GetTransferStatus( + LPCUSB_FUNCS pUsbFuncs, + USB_TRANSFER hTransfer, + LPDWORD pBytesTransferred , // OPTIONAL returns number of bytes transferred + PUSB_ERROR pUsbError // returns USB error code + ) +{ + + BOOL bRc = TRUE; + + if ( pUsbFuncs->lpGetTransferStatus(hTransfer, pBytesTransferred, pUsbError) ) { + if ( USB_NO_ERROR != *pUsbError ) { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("*** CloseTransfer ERROR:%d ***\n", GetLastError())); + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("GetTransferStatus (BytesTransferred:%d, UsbError:0x%x)\n", pBytesTransferred?*pBytesTransferred:-1, pUsbError?*pUsbError:-1 )); + } + } else { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_,("*** GetTransferStatus ERROR:%d ***\n", GetLastError())); + *pUsbError = USB_CANCELED_ERROR; + bRc = FALSE; + } + + return bRc; +} + + +// The driver should never read RxCmd register. We have to set +// RCR CMDHAT0 (bit6) to append Rx status before the Rx frame. +// +// |<-------- pBulkUrb->TransferBufferLength ------------>| +// +------------------+-------------------+------------+ +// | Rx status (16 bytes) | Rx frame ..... | CRC(4 bytes) | +// +------------------+-------------------+------------+ +// ^ +// ^pRfd->Buffer.VirtualAddress +// +/*! \brief USB RX IRP Complete Routine. + @param Context pointer of RT_RFD +*/ +u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + struct intf_priv *pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv *pdvobj_priv = (struct dvobj_priv*)pintfpriv->intf_dev; + _adapter *adapter = (_adapter *)pdvobj_priv->padapter; + + struct recv_priv *precvpriv = &adapter->recvpriv; + + struct recv_buf *precvbuf = (struct recv_buf *)rmem; + DWORD dwErr = ERROR_SUCCESS ; + DWORD dwBytesTransferred = 0 ; + USB_TRANSFER hTransfer = NULL; + USB_PIPE hPipe; + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_read_port(%u)\n", __LINE__)); + +#if (CONFIG_PWRCTRL == 1) + if (adapter->pwrctrlpriv.pnp_bstop_trx) + { + return _FALSE; + } +#endif + + if(adapter->bDriverStopped || adapter->bSurpriseRemoved) + { + RT_TRACE(_module_hci_ops_os_c_, _drv_info_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved)!!!\n")); + return _FALSE; + } + + if(precvbuf !=NULL) + { + + // get a recv buffer + rtl8192cu_init_recvbuf(adapter, precvbuf); + + + + _rtw_spinlock(&precvpriv->lock); + precvpriv->rx_pending_cnt++; + precvbuf->irp_pending = _TRUE; + _rtw_spinunlock(&precvpriv->lock); + + + //translate DMA FIFO addr to pipehandle + hPipe = ffaddr2pipehdl(pdvobj_priv, addr); + + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_read_port(%u)\n", __LINE__)); + + precvbuf->usb_transfer_read_port = (*usb_funcs_vp->lpIssueBulkTransfer)( + hPipe, + usb_read_port_complete, + precvbuf, + USB_IN_TRANSFER|USB_SHORT_TRANSFER_OK, + MAX_RECVBUF_SZ, + precvbuf->pbuf, + 0); + + + if(precvbuf->usb_transfer_read_port) + { + + // GetTransferStatus(usb_funcs_vp, hTransfer, &dwBytesTransferred,&UsbRc); + + // CloseTransferHandle(usb_funcs_vp, hTransfer); + + } + else + { + + dwErr = GetLastError(); + //RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_read_port ERROR : %d\n", dwErr)); + + } + +// if ( USB_NO_ERROR != UsbRc && ERROR_SUCCESS == dwErr) { +// dwErr = ERROR_GEN_FAILURE; +// } + + + if ( ERROR_SUCCESS != dwErr ) { + + SetLastError(dwErr); + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_read_port ERROR : %d\n", dwErr)); + } + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("-usb_read_port(%u)\n", __LINE__)); + + } + else // if(precvbuf !=NULL) + { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precv_frame ==NULL\n")); + } + + return _TRUE; + +} + +DWORD usb_read_port_complete( PVOID context ) +{ + struct recv_buf *precvbuf = (struct recv_buf *)context; + _adapter *adapter = (_adapter *)precvbuf->adapter; + struct recv_priv *precvpriv = &adapter->recvpriv; + + + struct intf_hdl *pintfhdl = &adapter->pio_queue->intf; + struct intf_priv *pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv *pdvobj_priv = (struct dvobj_priv*)pintfpriv->intf_dev; + + + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + + DWORD dwBytesTransferred = 0; + DWORD dwErr = USB_CANCELED_ERROR; + + uint isevt, *pbuf; + int fComplete =_FALSE; + + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_read_port_complete(%u)\n", __LINE__)); + +_func_enter_; + + + _rtw_spinlock_ex(&precvpriv->lock); + precvbuf->irp_pending=_FALSE; + precvpriv->rx_pending_cnt --; + _rtw_spinunlock_ex(&precvpriv->lock); + + +#if 1 + + (*usb_funcs_vp->lpGetTransferStatus)(precvbuf->usb_transfer_read_port, &dwBytesTransferred, &dwErr); + fComplete = (*usb_funcs_vp->lpIsTransferComplete)(precvbuf->usb_transfer_read_port); + if(fComplete!=_TRUE) + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete CloseTransfer before complete\n")); + } + (*usb_funcs_vp->lpCloseTransfer)(precvbuf->usb_transfer_read_port); + + +#endif + + + if(USB_NO_ERROR != dwErr) + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete Fail :%d\n",dwErr)); + + { + + if ( dwBytesTransferred > MAX_RECVBUF_SZ || dwBytesTransferred < RXDESC_SIZE ) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_, + ("\n usb_read_port_complete: (pbulkurb->TransferBufferLength > MAX_RECVBUF_SZ) || (pbulkurb->TransferBufferLength < RXDESC_SIZE): %d\n",dwBytesTransferred)); + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + + //usb_read_port(pintfhdl, 0, 0, (unsigned char *)precvframe); + } + else + { + precvbuf->transfer_len = dwBytesTransferred; + + pbuf = (uint*)precvbuf->pbuf; + + if((isevt = *(pbuf+1)&0x1ff) == 0x1ff) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_info_, + ("\n usb_read_port_complete: get a event\n")); + rxcmd_event_hdl(adapter, pbuf);//rx c2h events + + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + else + { + if(recvbuf2recvframe(adapter, precvbuf)==_FAIL)//rx packets + { + //precvbuf->reuse = _TRUE; + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + } + } + } + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("-usb_read_port_complete(%u)\n", __LINE__)); + +_func_exit_; + return ERROR_SUCCESS; +// return STATUS_MORE_PROCESSING_REQUIRED; +} + +void usb_read_port_cancel(_adapter *padapter){ + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_read_port_cancel(%u)\n",__FUNCTION__, __LINE__)); +} + +DWORD usb_write_mem_complete( LPVOID Context ) +{ + int fComplete =_FALSE; + DWORD dwBytes = 0; + DWORD dwErr = USB_CANCELED_ERROR; + + _irqL irqL; + _list *head; + _list *plist; + struct io_req *pio_req; + struct io_queue *pio_q = (struct io_queue *) Context; + struct intf_hdl *pintf = &(pio_q->intf); + struct intf_priv *pintfpriv = pintf->pintfpriv; + _adapter *padapter = (_adapter *)pintf->adapter; + NTSTATUS status = STATUS_SUCCESS; + struct xmit_priv * pxmitpriv = &padapter->xmitpriv; + + struct dvobj_priv * pdvobj_priv = (struct dvobj_priv*)pintfpriv->intf_dev; + + USB_HANDLE usbHandle = pdvobj_priv->usb_extension._hDevice; + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + + // get the head from the processing io_queue + head = &(pio_q->processing); + +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("+usb_write_mem_complete %p\n", Context)); + +#if 1 + _enter_critical_bh(&(pio_q->lock), &irqL); + + + //free irp in processing list... + while(rtw_is_list_empty(head) != _TRUE) + { + plist = get_next(head); + rtw_list_delete(plist); + pio_req = LIST_CONTAINOR(plist, struct io_req, list); + _rtw_up_sema(&pio_req->sema); + } + + _exit_critical_bh(&(pio_q->lock), &irqL); +#endif + + +#if 1 + + (*usb_funcs_vp->lpGetTransferStatus)(pio_req->usb_transfer_write_mem , &dwBytes, &dwErr); + fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pio_req->usb_transfer_write_mem); + if(fComplete!=_TRUE) + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_mem_complete CloseTransfer before complete\n")); + } + (*usb_funcs_vp->lpCloseTransfer)(pio_req->usb_transfer_write_mem ); + +#endif + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("-usb_write_mem_complete\n")); + +_func_exit_; + + + return STATUS_MORE_PROCESSING_REQUIRED; + +} + + +void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + + NTSTATUS NtStatus = STATUS_SUCCESS; + USB_PIPE hPipe; + _irqL irqL; + + int fComplete = _FALSE; + DWORD dwBytes = 0; + DWORD dwErr = USB_CANCELED_ERROR; + + + struct io_req *pio_req; + + _adapter *adapter = (_adapter *)pintfhdl->adapter; + struct intf_priv *pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv * pdvobj_priv = (struct dvobj_priv*)pintfpriv->intf_dev; + + + struct xmit_priv *pxmitpriv = &adapter->xmitpriv; + struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + + +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_write_mem(%u) pintfhdl %p wmem %p\n", __LINE__, pintfhdl, wmem)); + + // fetch a io_request from the io_queue + pio_req = alloc_ioreq(pio_queue); + + if ((pio_req == NULL)||(adapter->bSurpriseRemoved)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("async_irp_write32 : pio_req =0x%x adapter->bSurpriseRemoved=0x%x",pio_req,adapter->bSurpriseRemoved )); + goto exit; + } + + _enter_critical_bh(&(pio_queue->lock), &irqL); + + + // insert the io_request into processing io_queue + rtw_list_insert_tail(&(pio_req->list),&(pio_queue->processing)); + + + if((adapter->bDriverStopped) || (adapter->bSurpriseRemoved) ||(adapter->pwrctrlpriv.pnp_bstop_trx)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\npadapter->pwrctrlpriv.pnp_bstop_trx==_TRUE\n")); + goto exit; + } + + //translate DMA FIFO addr to pipehandle + hPipe = ffaddr2pipehdl(pdvobj_priv, addr); + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_,("usb_write_mem(%u)\n",__LINE__)); + + pio_req->usb_transfer_write_mem = (*usb_funcs_vp->lpIssueBulkTransfer)( + hPipe, + usb_write_mem_complete, + pio_queue, + USB_OUT_TRANSFER, + cnt, + wmem, + 0); + +#if 0 + + (*usb_funcs_vp->lpGetTransferStatus)(pio_req->usb_transfer_write_mem , &dwBytes, &dwErr); + + while( fComplete != _TRUE) + { + fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pio_req->usb_transfer_write_mem); + if(fComplete==_TRUE) + { + (*usb_funcs_vp->lpCloseTransfer)(pio_req->usb_transfer_write_mem ); + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_mem finished\n")); + break; + } + else + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, + ("usb_write_mem not yet finished %X\n", + pio_req->usb_transfer_write_mem)); + rtw_msleep_os(10); + } + + } + +#endif + + +// _rtw_down_sema(&pio_req->sema); + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("-usb_write_mem(%X)\n",pio_req->usb_transfer_write_mem)); + + _exit_critical_bh(&(pio_queue->lock), &irqL); + + _rtw_down_sema(&pio_req->sema); + free_ioreq(pio_req, pio_queue); + +exit: +_func_exit_; + return; +} + +u32 usb_write_cnt=0; +u32 usb_complete_cnt=0; + +USB_PIPE ffaddr2pipehdl(struct dvobj_priv *pNdisCEDvice, u32 addr) +{ + USB_PIPE PipeHandle = NULL; + _adapter *padapter = pNdisCEDvice->padapter; + + + if(pNdisCEDvice->nr_endpoint == 11) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3] ; + break; + case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[4]; + break; + case RTL8712_DMA_VIQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_BCNQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[6]; + break; + case RTL8712_DMA_BMCQ: //HI Queue + PipeHandle= padapter->halpriv.pipehdls_r8712[7]; + break; + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[8]; + break; + case RTL8712_DMA_RX0FF: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[5]; + break; + case RTL8712_DMA_H2CCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[9]; + break; + + } + + } + else if(pNdisCEDvice->nr_endpoint == 6) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3]; + break; + case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[4]; + break; + case RTL8712_DMA_VIQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_RX0FF: + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_H2CCMD: + case RTL8712_DMA_BCNQ: + case RTL8712_DMA_BMCQ: + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[5]; + break; + + } + + } + else if(pNdisCEDvice->nr_endpoint == 4) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + case RTL8712_DMA_VIQ: + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_RX0FF: + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_H2CCMD: + case RTL8712_DMA_BCNQ: + case RTL8712_DMA_BMCQ: + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3]; + break; + } + + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("ffaddr2pipehdl():nr_endpoint=%d error!\n", pNdisCEDvice->nr_endpoint)); + } + + return PipeHandle; + +} + +DWORD usb_bulkout_zero_complete( LPVOID pZeroContext ) +{ + struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)pZeroContext; + _adapter * padapter = pcontext->padapter; + struct dvobj_priv * pdvobj_priv = (struct dvobj_priv *)&padapter->dvobjpriv; + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + struct xmit_priv * pxmitpriv = &padapter->xmitpriv; + + int fComplete =_FALSE; + DWORD dwBytesTransferred = 0; + DWORD dwErr = USB_CANCELED_ERROR; + +_func_enter_; + +#if 1 + + (*usb_funcs_vp->lpGetTransferStatus)(pxmitpriv->usb_transfer_write_port, &dwBytesTransferred, &dwErr); + fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pxmitpriv->usb_transfer_write_port); + if(fComplete!=_TRUE) + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_bulkout_zero_complete CloseTransfer before complete\n")); + } + (*usb_funcs_vp->lpCloseTransfer)(pxmitpriv->usb_transfer_write_port); + +#endif + + if(pcontext) + { + if(pcontext->pbuf) + { + rtw_mfree(pcontext->pbuf, sizeof(int)); + } + + rtw_mfree((u8*)pcontext, sizeof(struct zero_bulkout_context)); + } + +_func_exit_; + + return ERROR_SUCCESS; + + +} + +u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) +{ + struct zero_bulkout_context *pcontext; + unsigned char *pbuf; + u8 len = 0 ; + _adapter *padapter = (_adapter *)pintfhdl->adapter; + struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv; + struct xmit_priv * pxmitpriv = &padapter->xmitpriv; + + + LPCUSB_FUNCS usb_funcs_vp = pdvobj->usb_extension._lpUsbFuncs; + + USB_PIPE hPipe; + +_func_enter_; + + if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) + { + return _FAIL; + } + + + pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context)); + + pbuf = (unsigned char *)rtw_zmalloc(sizeof(int)); + + len = 0; + + pcontext->pbuf = pbuf; + pcontext->purb = NULL; + pcontext->pirp = NULL; + pcontext->padapter = padapter; + + +//translate DMA FIFO addr to pipehandle + hPipe = ffaddr2pipehdl(pdvobj, addr); + + + + + pxmitpriv->usb_transfer_write_port = (*usb_funcs_vp->lpIssueBulkTransfer)( + hPipe, usb_bulkout_zero_complete, + pcontext, USB_OUT_TRANSFER, + len, pbuf, 0); + + +_func_exit_; + + return _SUCCESS; + +} + +u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + + u32 i, bwritezero = _FALSE; + u32 ac_tag = addr; + + u8* ptr; + + struct intf_priv * pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv * pdvobj_priv = (struct dvobj_priv*)pintfpriv->intf_dev; + _adapter * padapter = pdvobj_priv->padapter; + + struct xmit_priv * pxmitpriv = &padapter->xmitpriv; + struct xmit_frame * pxmitframe = (struct xmit_frame *)wmem; + + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + + USB_PIPE hPipe; + + u32 bResult = _FALSE; + +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("+usb_write_port\n")); + +#if (CONFIG_PWRCTRL == 1) + if(padapter->pwrctrlpriv.pnp_bstop_trx==_TRUE){ + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("\npadapter->pwrctrlpriv.pnp_bstop_trx==_TRUE\n")); + + } +#endif + + if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + bResult = _FALSE; + goto exit; + } + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_write_port(%u)\n", __LINE__)); + + for(i=0; i<8; i++) + { + if(pxmitframe->bpending[i] == _FALSE) + { + _rtw_spinlock(&pxmitpriv->lock); + pxmitpriv->txirp_cnt++; + pxmitframe->bpending[i] = _TRUE; + _rtw_spinunlock(&pxmitpriv->lock); + + pxmitframe->sz[i] = cnt; + pxmitframe->ac_tag[i] = ac_tag; + + break; + } + } + + + //TODO: + if (pdvobj_priv->ishighspeed) + { + if(cnt> 0 && cnt%512 == 0) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("ishighspeed, cnt=%d\n", cnt)); + // cnt=cnt+1; + bwritezero = _TRUE; + + } + } + else + { + if(cnt > 0 && cnt%64 == 0) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("cnt=%d\n", cnt)); + // cnt=cnt+1; + bwritezero = _TRUE; + + } + } + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_write_port: pipe handle convert\n")); + + //translate DMA FIFO addr to pipehandle + hPipe = ffaddr2pipehdl(pdvobj_priv, addr); + + +#if 0 + // for tx fifo, the maximum payload number is 8, + // we workaround this issue here by separate whole fifo into 8 segments. + if (cnt <= 500) + cnt = 500; +#endif + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, + ("usb_write_port(%u): pxmitframe %X pxmitframe->padapter %X\n",__LINE__, pxmitframe, pxmitframe->padapter)); + + pxmitpriv->usb_transfer_write_port = (*usb_funcs_vp->lpIssueBulkTransfer)( + hPipe, usb_write_port_complete, + pxmitframe, USB_OUT_TRANSFER, + cnt, pxmitframe->mem_addr, 0); + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + + ptr=(u8 *)&pxmitframe->mem; + +#if 0 + if (pdvobj_priv->ishighspeed) + { + ptr=ptr+512; + } + else + { + ptr=ptr+64; + + } +#endif + if(bwritezero == _TRUE) + { + usb_bulkout_zero(pintfhdl, addr); + } + +// if (!pxmitframe->usb_transfer_xmit) +// padapter->bSurpriseRemoved=_TRUE; + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + bResult = _SUCCESS; + +exit: +_func_exit_; + return bResult; +} + +DWORD usb_write_port_complete( LPVOID Context ) +{ + +// u8 *ptr; + + struct xmit_frame * pxmitframe = (struct xmit_frame *) Context; + _adapter * padapter = pxmitframe->padapter; + struct dvobj_priv * pdvobj_priv = (struct dvobj_priv *)&padapter->dvobjpriv; + struct xmit_priv * pxmitpriv = &padapter->xmitpriv; + struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; + LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs; + + int fComplete =_FALSE; + DWORD dwBytesTransferred = 0; + DWORD dwErr = USB_CANCELED_ERROR; + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u), pxmitframe %X\n",__FUNCTION__, __LINE__, Context)); + +_func_enter_; + + RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("+usb_write_port_complete\n")); + + _rtw_spinlock_ex(&pxmitpriv->lock); + pxmitpriv->txirp_cnt--; + _rtw_spinunlock_ex(&pxmitpriv->lock); + + if(pxmitpriv->txirp_cnt==0){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n")); + _rtw_up_sema(&(pxmitpriv->tx_retevt)); + } + + + //not to consider tx fragment + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + +#if 1 + + (*usb_funcs_vp->lpGetTransferStatus)(pxmitpriv->usb_transfer_write_port, &dwBytesTransferred, &dwErr); + fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pxmitpriv->usb_transfer_write_port); + if(fComplete!=_TRUE) + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete CloseTransfer before complete\n")); + } + (*usb_funcs_vp->lpCloseTransfer)(pxmitpriv->usb_transfer_write_port); + +#else + + if((*usb_funcs_vp->lpIsTransferComplete)(pxmitpriv->usb_transfer_write_port)) + { + (*usb_funcs_vp->lpCloseTransfer)(pxmitpriv->usb_transfer_write_port); + } + +#endif + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, + ("%s(%u): pxmitpriv %X pxmitpriv->free_xmitframe_cnt %X pxmitframe->padapter %X pxmitframe->padapter %X\n", + __LINE__, pxmitpriv, pxmitpriv->free_xmitframe_cnt, pxmitframe->padapter)); + + rtl8192cu_xmitframe_complete(padapter, pxmitpriv, pxmitbuf); + +_func_exit_; + + return STATUS_SUCCESS; +} + +DWORD usb_write_scsi_complete(LPVOID pTxContext) +{ +#ifndef PLATFORM_OS_CE + struct SCSI_BUFFER_ENTRY *psb_entry = (struct SCSI_BUFFER_ENTRY *)pTxContext; + _adapter *padapter = psb_entry->padapter; + struct SCSI_BUFFER *psb = padapter->pscsi_buf; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct dvobj_priv *pdvobj_priv = (struct dvobj_priv *)&padapter->dvobjpriv; + LPCUSB_FUNCS lpUsbFuncs = pdvobj_priv->pUsbExtension->_lpUsbFuncs; + + int fComplete =_FALSE; + DWORD dwBytesTransferred = 0; + DWORD dwErr = USB_CANCELED_ERROR; + +_func_enter_; + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u): circ_space = %d\n",__FUNCTION__, __LINE__, CIRC_SPACE( psb->head,psb->tail, SCSI_BUFFER_NUMBER))); + +#if 1 + + (*lpUsbFuncs->lpGetTransferStatus)(psb_entry->usb_transfer_scsi_txcmd, &dwBytesTransferred, &dwErr); + fComplete = (*lpUsbFuncs->lpIsTransferComplete)(psb_entry->usb_transfer_scsi_txcmd); + if(fComplete!=_TRUE) + { + RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_scsi_complete CloseTransfer before complete\n")); + } + (*lpUsbFuncs->lpCloseTransfer)(psb_entry->usb_transfer_scsi_txcmd); + +#else + + if((*lpUsbFuncs->lpIsTransferComplete)(psb_entry->usb_transfer_scsi_txcmd)) + (*lpUsbFuncs->lpCloseTransfer)(psb_entry->usb_transfer_scsi_txcmd); +#endif + + memset(psb_entry->entry_memory, 0, 8); + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + if((psb->tail+1)==SCSI_BUFFER_NUMBER) + psb->tail=0; + else + psb->tail++; + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + if(CIRC_CNT(psb->head,psb->tail,SCSI_BUFFER_NUMBER)==0){ + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("write_txcmd_scsififo_callback: up_sema\n")); + _rtw_up_sema(&pxmitpriv->xmit_sema); + } + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + if(padapter->bSurpriseRemoved) { + return STATUS_MORE_PROCESSING_REQUIRED; + } + +_func_exit_; +#endif + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +uint usb_write_scsi(struct intf_hdl *pintfhdl, u32 cnt, u8 *wmem) +{ + +#ifndef PLATFORM_OS_CE + + _adapter *padapter = (_adapter *)pintfhdl->adapter; + struct dvobj_priv *pdev = (struct dvobj_priv*)&padapter->dvobjpriv; + + struct SCSI_BUFFER *psb =padapter->pscsi_buf; + struct SCSI_BUFFER_ENTRY *psb_entry=LIST_CONTAINOR(wmem,struct SCSI_BUFFER_ENTRY,entry_memory); + +_func_enter_; + if(padapter->bSurpriseRemoved||padapter->bDriverStopped) + return 0; + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + psb_entry->usb_transfer_scsi_txcmd=pdev->pUsbExtension->_lpUsbFuncs->lpIssueBulkTransfer( + pdev->scsi_out_pipehandle, + usb_write_scsi_complete, + psb_entry, + USB_OUT_TRANSFER, + cnt, + wmem, + 0); + +_func_exit_; +#endif + + return _SUCCESS; +} + + +/* + */ +uint usb_init_intf_priv(struct intf_priv *pintfpriv) +{ + // get the dvobj_priv object + struct dvobj_priv * pNdisCEDvice = (struct dvobj_priv *) pintfpriv->intf_dev; + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); + // set init intf_priv init status as _IOREADY + pintfpriv->intf_status = _IOREADY; + + // determine the max io size by dvobj_priv.ishighspeed + if(pNdisCEDvice->ishighspeed) + pintfpriv->max_iosz = 128; + else + pintfpriv->max_iosz = 64; + + // read/write size set as 0 + pintfpriv->io_wsz = 0; + pintfpriv->io_rsz = 0; + + // init io_rwmem buffer + pintfpriv->allocated_io_rwmem = rtw_zmalloc(pintfpriv->max_iosz +4); + if (pintfpriv->allocated_io_rwmem == NULL) + { + rtw_mfree((u8 *)(pintfpriv->allocated_io_rwmem), pintfpriv->max_iosz +4); + return _FAIL; + } + else + { + // word align the io_rwmem + pintfpriv->io_rwmem = pintfpriv->allocated_io_rwmem + 4 - ( (u32)(pintfpriv->allocated_io_rwmem) & 3); + } + +#ifndef PLATFORM_OS_CE + + // init io_r_mem buffer + pintfpriv->allocated_io_r_mem = rtw_zmalloc(pintfpriv->max_iosz +4); + if (pintfpriv->allocated_io_r_mem == NULL) + { + rtw_mfree((u8 *)(pintfpriv->allocated_io_r_mem), pintfpriv->max_iosz +4); + return _FAIL; + } + else + { + // word align the io_rwmem + pintfpriv->io_r_mem = pintfpriv->allocated_io_r_mem + 4 - ( (u32)(pintfpriv->allocated_io_r_mem) & 3); + } +#endif + + return _SUCCESS; +} + +void usb_unload_intf_priv(struct intf_priv *pintfpriv) +{ +#ifndef PLATFORM_OS_CE + + rtw_mfree((u8 *)(pintfpriv->allocated_io_rwmem), pintfpriv->max_iosz+4); + rtw_mfree((u8 *)(pintfpriv->allocated_io_r_mem), pintfpriv->max_iosz+4); +#endif + + RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("%s(%u)\n",__FUNCTION__, __LINE__)); +} + + + +void usb_write_port_cancel(_adapter *padapter) +{ + + sint i,j; + struct dvobj_priv *pdev = &padapter->dvobjpriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + struct xmit_frame *pxmitframe; + + _rtw_spinlock(&pxmitpriv->lock); + pxmitpriv->txirp_cnt--; //decrease 1 for Initialize ++ + _rtw_spinunlock(&pxmitpriv->lock); + + if (pxmitpriv->txirp_cnt) + { + // Canceling Pending Recv Irp + pxmitframe= (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; + + for( i = 0; i < NR_XMITFRAME; i++ ) + { + for(j=0;j<8;j++) + { + if (pxmitframe->bpending[j]==_TRUE) + { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,(" usb_write_port_cancel() :IoCancelIrp\n")); + + } + } + + pxmitframe++; + } + + _rtw_down_sema(&(pxmitpriv->tx_retevt)); + + } + +} + +DWORD usbctrl_vendorreq_complete(LPVOID lpvNotifyParameter) +{ + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv*)lpvNotifyParameter; + + RT_TRACE(_module_hci_ops_os_c_,_drv_debug_,("+usbctrl_vendorreq_complete\n")); + + return STATUS_SUCCESS; +} + + +int usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) +{ + u8 ret=_TRUE; +// NTSTATUS ntstatus; +// int fComplete; +// LPCUSB_DEVICE lpDeviceInfo; + + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfpriv->intf_dev; + + USB_TRANSFER usbTrans; + USB_DEVICE_REQUEST usb_device_req; + USB_HANDLE usbHandle = pdvobjpriv->usb_extension._hDevice; + LPCUSB_FUNCS usbFuncs = pdvobjpriv->usb_extension._lpUsbFuncs; + + u32 transfer_flags = 0; + + _func_enter_; + + memset( &usb_device_req, 0, sizeof( USB_DEVICE_REQUEST ) ); + + if( 0x01 == requesttype ) + { + usb_device_req.bmRequestType = USB_REQUEST_DEVICE_TO_HOST | USB_REQUEST_VENDOR | USB_REQUEST_FOR_DEVICE; + } + else + { + usb_device_req.bmRequestType = USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_VENDOR | USB_REQUEST_FOR_DEVICE; + } + + usb_device_req.bRequest = request; + usb_device_req.wValue = value; + usb_device_req.wIndex = index; + usb_device_req.wLength = len; + + if (requesttype == 0x01) + { + transfer_flags = USB_IN_TRANSFER;//read_in + } + else + { + transfer_flags= USB_OUT_TRANSFER;//write_out + } + + RT_TRACE(_module_hci_ops_os_c_,_drv_debug_,("+usbctrl_vendorreq\n",__FUNCTION__,__LINE__)); + +#if 0 + // Remember to add callback for sync + usbTrans = (*usbFuncs->lpIssueVendorTransfer)(usbHandle, + usbctrl_vendorreq_complete, pdvobjpriv, + transfer_flags, &usb_device_req, pdata, 0); +#else + // Remember to add callback for sync + usbTrans = (*usbFuncs->lpIssueVendorTransfer)(usbHandle, + NULL, 0, + transfer_flags, &usb_device_req, pdata, 0); +#endif + +// rtw_usleep_os(10); + + if ( usbTrans ) + { + DWORD dwBytes = 0; + DWORD dwErr = USB_CANCELED_ERROR; + int fComplete; + + (*usbFuncs->lpGetTransferStatus)(usbTrans, &dwBytes, &dwErr); + + fComplete = (*usbFuncs->lpIsTransferComplete)(usbTrans); + + if (fComplete== _TRUE) + { + (*usbFuncs->lpCloseTransfer)(usbTrans); + RT_TRACE(_module_hci_ops_os_c_,_drv_debug_,("usbctrl_vendorreq lpCloseTransfer\n")); + } + + if ( dwErr != USB_NO_ERROR || fComplete != _TRUE) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq lpCloseTransfer without complete\n")); + ret = _FALSE; + goto exit; + } + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq without usbTrans\n")); + ret = _FALSE; + goto exit; + + } + +exit: + RT_TRACE(_module_hci_ops_os_c_,_drv_debug_,("-usbctrl_vendorreq\n")); +_func_exit_; + + return ret; + +} + + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c new file mode 100755 index 00000000..2d627d30 --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c @@ -0,0 +1,1536 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_OPS_OS_C_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) +{ + _adapter *padapter = pintfhdl->padapter; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *udev = pdvobjpriv->pusbdev; + + unsigned int pipe; + int status = 0; + u32 tmp_buflen=0; + u8 reqtype; + u8 *pIo_buf; + int vendorreq_times = 0; + + #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE + u8 *tmp_buf; + #else // use stack memory + u8 tmp_buf[MAX_USB_IO_CTL_SIZE]; + #endif + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type > PRIMARY_ADAPTER) + { + padapter = padapter->pbuddy_adapter; + pdvobjpriv = adapter_to_dvobj(padapter); + udev = pdvobjpriv->pusbdev; + } +#endif + + + //DBG_871X("%s %s:%d\n",__FUNCTION__, current->comm, current->pid); + + if((padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq:(padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + status = -EPERM; + goto exit; + } + + if(len>MAX_VENDOR_REQ_CMD_SIZE){ + DBG_8192C( "[%s] Buffer len error ,vendor request failed\n", __FUNCTION__ ); + status = -EINVAL; + goto exit; + } + + #ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); + #endif + + + // Acquire IO memory for vendorreq +#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + pIo_buf = pdvobjpriv->usb_vendor_req_buf; +#else + #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE + tmp_buf = rtw_malloc( (u32) len + ALIGNMENT_UNIT); + tmp_buflen = (u32)len + ALIGNMENT_UNIT; + #else // use stack memory + tmp_buflen = MAX_USB_IO_CTL_SIZE; + #endif + + // Added by Albert 2010/02/09 + // For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment. + // Trying to fix it here. + pIo_buf = (tmp_buf==NULL)?NULL:tmp_buf + ALIGNMENT_UNIT -((SIZE_PTR)(tmp_buf) & 0x0f ); +#endif + + if ( pIo_buf== NULL) { + DBG_8192C( "[%s] pIo_buf == NULL \n", __FUNCTION__ ); + status = -ENOMEM; + goto release_mutex; + } + + while(++vendorreq_times<= MAX_USBCTRL_VENDORREQ_TIMES) + { + _rtw_memset(pIo_buf, 0, len); + + if (requesttype == 0x01) + { + pipe = usb_rcvctrlpipe(udev, 0);//read_in + reqtype = REALTEK_USB_VENQT_READ; + } + else + { + pipe = usb_sndctrlpipe(udev, 0);//write_out + reqtype = REALTEK_USB_VENQT_WRITE; + _rtw_memcpy( pIo_buf, pdata, len); + } + + #if 0 + //timeout test for firmware downloading + status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len + , ((value >= FW_8192C_START_ADDRESS && value <= FW_8192C_END_ADDRESS) ||value!=0x1000) ?RTW_USB_CONTROL_MSG_TIMEOUT : RTW_USB_CONTROL_MSG_TIMEOUT_TEST + ); + #else + status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); + #endif + + if ( status == len) // Success this control transfer. + { + rtw_reset_continual_urb_error(pdvobjpriv); + if ( requesttype == 0x01 ) + { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. + _rtw_memcpy( pdata, pIo_buf, len ); + } + } + else { // error cases + DBG_8192C("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n" + , value,(requesttype == 0x01)?"read":"write" , len, status, *(u32*)pdata, vendorreq_times); + + if (status < 0) { + if(status == (-ESHUTDOWN) || status == -ENODEV ) + { + padapter->bSurpriseRemoved = _TRUE; + } else { + #ifdef DBG_CONFIG_ERROR_DETECT + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL; + } + #endif + } + } + else // status != len && status >= 0 + { + if(status > 0) { + if ( requesttype == 0x01 ) + { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. + _rtw_memcpy( pdata, pIo_buf, len ); + } + } + } + + if(rtw_inc_and_chk_continual_urb_error(pdvobjpriv) == _TRUE ){ + padapter->bSurpriseRemoved = _TRUE; + break; + } + + } + + // firmware download is checksumed, don't retry + if( (value >= FW_8192C_START_ADDRESS && value <= FW_8192C_END_ADDRESS) || status == len ) + break; + + } + + // release IO memory used by vendorreq + #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE + rtw_mfree(tmp_buf, tmp_buflen); + #endif + +release_mutex: + #ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); + #endif +exit: + return status; + +} + +static u8 usb_read8(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 = 1; + + usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); + + _func_exit_; + + return (u8)(le32_to_cpu(data)&0x0ff); + +} + +static u16 usb_read16(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 = 2; + + usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); + + _func_exit_; + + return (u16)(le32_to_cpu(data)&0xffff); + +} + +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 le32_to_cpu(data); + +} + +static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 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 = 1; + + data = val; + data = cpu_to_le32(data&0x000000ff); + + 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; + u32 data; + int ret; + + _func_enter_; + + request = 0x05; + requesttype = 0x00;//write_out + index = 0;//n/a + + wvalue = (u16)(addr&0x0000ffff); + len = 2; + + data = val; + data = cpu_to_le32(data&0x0000ffff); + + 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 = cpu_to_le32(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_USB_INTERRUPT_IN_PIPE +static void usb_read_interrupt_complete(struct urb *purb, struct pt_regs *regs) +{ + int err; + _adapter *padapter = (_adapter *)purb->context; + + if(purb->status==0)//SUCCESS + { + if (purb->actual_length > sizeof(INTERRUPT_MSG_FORMAT_EX)) + { + DBG_8192C("usb_read_interrupt_complete: purb->actual_length > sizeof(INTERRUPT_MSG_FORMAT_EX) \n"); + } + + err = usb_submit_urb(purb, GFP_ATOMIC); + if((err) && (err != (-EPERM))) + { + DBG_8192C("cannot submit interrupt in-token(err = 0x%08x),urb_status = %d\n",err, purb->status); + } + } + else + { + DBG_8192C("###=> usb_read_interrupt_complete => urb status(%d)\n", purb->status); + + 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: + break; + case -EINPROGRESS: + DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); + break; + default: + break; + } + } + +} + +static u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr) +{ + int err; + unsigned int pipe; + u32 ret = _SUCCESS; + _adapter *adapter = pintfhdl->padapter; + struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); + struct recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; + +_func_enter_; + + //translate DMA FIFO addr to pipehandle + pipe = ffaddr2pipehdl(pdvobj, addr); + + usb_fill_int_urb(precvpriv->int_in_urb, pusbd, pipe, + precvpriv->int_in_buf, + sizeof(INTERRUPT_MSG_FORMAT_EX), + usb_read_interrupt_complete, + adapter, + 1); + + err = usb_submit_urb(precvpriv->int_in_urb, GFP_ATOMIC); + if((err) && (err != (-EPERM))) + { + DBG_8192C("cannot submit interrupt in-token(err = 0x%08x),urb_status = %d\n",err, precvpriv->int_in_urb->status); + ret = _FAIL; + } + +_func_exit_; + + return ret; +} +#endif + +static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_stat *prxstat, struct phy_stat *pphy_info) +{ + s32 ret=_SUCCESS; +#ifdef CONFIG_CONCURRENT_MODE + u8 *primary_myid, *secondary_myid, *paddr1; + union recv_frame *precvframe_if2 = NULL; + _adapter *primary_padapter = precvframe->u.hdr.adapter; + _adapter *secondary_padapter = primary_padapter->pbuddy_adapter; + struct recv_priv *precvpriv = &primary_padapter->recvpriv; + _queue *pfree_recv_queue = &precvpriv->free_recv_queue; + u8 *pbuf = precvframe->u.hdr.rx_data; + + if(!secondary_padapter) + return ret; + + paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data); + + if(IS_MCAST(paddr1) == _FALSE)//unicast packets + { + //primary_myid = myid(&primary_padapter->eeprompriv); + secondary_myid = myid(&secondary_padapter->eeprompriv); + + if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN)) + { + //change to secondary interface + precvframe->u.hdr.adapter = secondary_padapter; + } + + //ret = recv_entry(precvframe); + + } + else // Handle BC/MC Packets + { + + u8 clone = _TRUE; +#if 0 + u8 type, subtype, *paddr2, *paddr3; + + type = GetFrameType(pbuf); + subtype = GetFrameSubType(pbuf); //bit(7)~bit(2) + + switch (type) + { + case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets + if(subtype == WIFI_BEACON) + { + paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data); + + if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) && + _rtw_memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) + { + //change to secondary interface + precvframe->u.hdr.adapter = secondary_padapter; + clone = _FALSE; + } + + if(check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) && + _rtw_memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN)) + { + if(clone==_FALSE) + { + clone = _TRUE; + } + else + { + clone = _FALSE; + } + + precvframe->u.hdr.adapter = primary_padapter; + } + + if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) || + check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) + { + clone = _TRUE; + precvframe->u.hdr.adapter = primary_padapter; + } + + } + else if(subtype == WIFI_PROBEREQ) + { + //probe req frame is only for interface2 + //change to secondary interface + precvframe->u.hdr.adapter = secondary_padapter; + clone = _FALSE; + } + break; + case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets + + break; + case WIFI_DATA_TYPE: //Handle BC/MC data Packets + //Notes: AP MODE never rx BC/MC data packets + + paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data); + + if(_rtw_memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) + { + //change to secondary interface + precvframe->u.hdr.adapter = secondary_padapter; + clone = _FALSE; + } + + break; + default: + + break; + } +#endif + + if(_TRUE == clone) + { + //clone/copy to if2 + u8 shift_sz = 0; + u32 alloc_sz, skb_len; + _pkt *pkt_copy = NULL; + struct rx_pkt_attrib *pattrib = NULL; + + precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue); + if(precvframe_if2) + { + precvframe_if2->u.hdr.adapter = secondary_padapter; + + _rtw_init_listhead(&precvframe_if2->u.hdr.list); + precvframe_if2->u.hdr.precvbuf = NULL; //can't access the precvbuf for new arch. + precvframe_if2->u.hdr.len=0; + + _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)); + + pattrib = &precvframe_if2->u.hdr.attrib; + + // Modified by Albert 20101213 + // For 8 bytes IP header alignment. + if (pattrib->qos) // Qos data, wireless lan header length is 26 + { + shift_sz = 6; + } + else + { + shift_sz = 0; + } + + skb_len = pattrib->pkt_len; + + // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. + // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){ + //alloc_sz = 1664; //1664 is 128 alignment. + if(skb_len <= 1650) + alloc_sz = 1664; + else + alloc_sz = skb_len + 14; + } + else { + alloc_sz = skb_len; + // 6 is for IP header 8 bytes alignment in QoS packet case. + // 8 is for skb->data 4 bytes alignment. + alloc_sz += 14; + } + + pkt_copy = rtw_skb_alloc(alloc_sz); + + if(pkt_copy) + { + pkt_copy->dev = secondary_padapter->pnetdev; + precvframe_if2->u.hdr.pkt = pkt_copy; + precvframe_if2->u.hdr.rx_head = pkt_copy->data; + precvframe_if2->u.hdr.rx_end = pkt_copy->data + alloc_sz; + skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address + skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz. + _rtw_memcpy(pkt_copy->data, pbuf, skb_len); + precvframe_if2->u.hdr.rx_data = precvframe_if2->u.hdr.rx_tail = pkt_copy->data; + + + recvframe_put(precvframe_if2, skb_len); + //recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE); + + rtl8192c_translate_rx_signal_stuff(precvframe_if2, pphy_info); + + ret = rtw_recv_entry(precvframe_if2); + + } else { + rtw_free_recvframe(precvframe_if2, pfree_recv_queue); + DBG_8192C("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__); + } + + } + + } + + } + + rtl8192c_translate_rx_signal_stuff(precvframe, pphy_info); + + ret = rtw_recv_entry(precvframe); + +#endif + + return ret; + +} + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX +static int recvbuf2recvframe(_adapter *padapter, struct recv_buf *precvbuf) +{ + u8 *pbuf; + u8 shift_sz = 0; + u16 pkt_cnt, drvinfo_sz; + u32 pkt_offset, skb_len, alloc_sz; + s32 transfer_len; + struct recv_stat *prxstat; + struct phy_stat *pphy_info = NULL; + _pkt *pkt_copy = 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; + + + transfer_len = (s32)precvbuf->transfer_len; + pbuf = precvbuf->pbuf; + + prxstat = (struct recv_stat *)pbuf; + pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff; + +#if 0 //temp remove when disable usb rx aggregation + if((pkt_cnt > 10) || (pkt_cnt < 1) || (transfer_lenrxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4)); + + prxstat = (struct recv_stat *)pbuf; + + 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__); + goto _exit_recvbuf2recvframe; + } + + _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; + + rtl8192c_query_rx_desc_status(precvframe, prxstat); + + pattrib = &precvframe->u.hdr.attrib; + if(pattrib->physt) + { + pphy_info = (struct phy_stat *)(pbuf + RXDESC_OFFSET); + } + + pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len; + + if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len)) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n")); + DBG_8192C("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__); + rtw_free_recvframe(precvframe, pfree_recv_queue); + goto _exit_recvbuf2recvframe; + } + + // Modified by Albert 20101213 + // For 8 bytes IP header alignment. + if (pattrib->qos) // Qos data, wireless lan header length is 26 + { + shift_sz = 6; + } + else + { + shift_sz = 0; + } + + skb_len = pattrib->pkt_len; + + // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. + // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){ + //alloc_sz = 1664; //1664 is 128 alignment. + if(skb_len <= 1650) + alloc_sz = 1664; + else + alloc_sz = skb_len + 14; + } + else { + alloc_sz = skb_len; + // 6 is for IP header 8 bytes alignment in QoS packet case. + // 8 is for skb->data 4 bytes alignment. + alloc_sz += 14; + } + + pkt_copy = rtw_skb_alloc(alloc_sz); + + if(pkt_copy) + { + pkt_copy->dev = padapter->pnetdev; + precvframe->u.hdr.pkt = pkt_copy; + precvframe->u.hdr.rx_head = pkt_copy->data; + precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; + skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address + skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz. + _rtw_memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); + precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; + } + else + { + DBG_8192C("recvbuf2recvframe:can not allocate memory for skb copy\n"); + //precvframe->u.hdr.pkt = rtw_skb_clone(pskb); + //precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pbuf; + //precvframe->u.hdr.rx_end = pbuf + (pkt_offset>1612?pkt_offset:1612); + + precvframe->u.hdr.pkt = NULL; + rtw_free_recvframe(precvframe, pfree_recv_queue); + + goto _exit_recvbuf2recvframe; + } + + recvframe_put(precvframe, skb_len); + //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); + +#ifdef CONFIG_USB_RX_AGGREGATION + switch(pHalData->UsbRxAggMode) + { + case USB_RX_AGG_DMA: + case USB_RX_AGG_MIX: + pkt_offset = (u16)_RND128(pkt_offset); + break; + case USB_RX_AGG_USB: + pkt_offset = (u16)_RND4(pkt_offset); + break; + case USB_RX_AGG_DISABLE: + default: + break; + } +#endif + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + { + if(pre_recv_entry(precvframe, prxstat, pphy_info) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); + } + } + else + { + rtl8192c_translate_rx_signal_stuff(precvframe, pphy_info); + if(rtw_recv_entry(precvframe) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } + } + +#else + rtl8192c_translate_rx_signal_stuff(precvframe, pphy_info); + if(rtw_recv_entry(precvframe) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } +#endif + + pkt_cnt--; + transfer_len -= pkt_offset; + pbuf += pkt_offset; + precvframe = NULL; + pkt_copy = NULL; + + if(transfer_len>0 && pkt_cnt==0) + pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff; + + }while((transfer_len>0) && (pkt_cnt>0)); + +_exit_recvbuf2recvframe: + + return _SUCCESS; +} + +void rtl8192cu_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(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel) + { + 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_urb_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_urb_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 recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; + +_func_enter_; + + if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + return _FAIL; + } + + if(precvbuf !=NULL) + { + rtl8192cu_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; + } + + } + + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n")); + ret = _FAIL; + } + +_func_exit_; + + return ret; +} +#else // CONFIG_USE_USB_BUFFER_ALLOC_RX +static int recvbuf2recvframe(_adapter *padapter, _pkt *pskb) +{ + u8 *pbuf; + u8 shift_sz = 0; + u16 pkt_cnt; + u32 pkt_offset, skb_len, alloc_sz; + s32 transfer_len; + struct recv_stat *prxstat; + struct phy_stat *pphy_info = NULL; + _pkt *pkt_copy = 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; + + + transfer_len = (s32)pskb->len; + pbuf = pskb->data; + + prxstat = (struct recv_stat *)pbuf; + pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff; + +#if 0 //temp remove when disable usb rx aggregation + if((pkt_cnt > 10) || (pkt_cnt < 1) || (transfer_lenrxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4)); + + prxstat = (struct recv_stat *)pbuf; + + 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__); + goto _exit_recvbuf2recvframe; + } + + _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; + + rtl8192c_query_rx_desc_status(precvframe, prxstat); + + pattrib = &precvframe->u.hdr.attrib; + if(pattrib->physt) + { + pphy_info = (struct phy_stat *)(pbuf + RXDESC_OFFSET); + } + + pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len; + + if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len)) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n")); + DBG_8192C("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__); + rtw_free_recvframe(precvframe, pfree_recv_queue); + goto _exit_recvbuf2recvframe; + } + + // Modified by Albert 20101213 + // For 8 bytes IP header alignment. + if (pattrib->qos) // Qos data, wireless lan header length is 26 + { + shift_sz = 6; + } + else + { + shift_sz = 0; + } + + skb_len = pattrib->pkt_len; + + // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. + // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){ + //alloc_sz = 1664; //1664 is 128 alignment. + if(skb_len <= 1650) + alloc_sz = 1664; + else + alloc_sz = skb_len + 14; + } + else { + alloc_sz = skb_len; + // 6 is for IP header 8 bytes alignment in QoS packet case. + // 8 is for skb->data 4 bytes alignment. + alloc_sz += 14; + } + + pkt_copy = rtw_skb_alloc(alloc_sz); + + if(pkt_copy) + { + pkt_copy->dev = padapter->pnetdev; + precvframe->u.hdr.pkt = pkt_copy; + precvframe->u.hdr.rx_head = pkt_copy->data; + precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; + skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address + skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz. + _rtw_memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); + precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; + + } + else + { + precvframe->u.hdr.pkt = rtw_skb_clone(pskb); + if(pkt_copy) + { + precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pbuf; + precvframe->u.hdr.rx_end = pbuf + alloc_sz; + } + else + { + DBG_8192C("recvbuf2recvframe: rtw_skb_clone fail\n"); + rtw_free_recvframe(precvframe, pfree_recv_queue); + goto _exit_recvbuf2recvframe; + } + } + + recvframe_put(precvframe, skb_len); + //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); + +#ifdef CONFIG_USB_RX_AGGREGATION + switch(pHalData->UsbRxAggMode) + { + case USB_RX_AGG_DMA: + case USB_RX_AGG_MIX: + pkt_offset = (u16)_RND128(pkt_offset); + break; + case USB_RX_AGG_USB: + pkt_offset = (u16)_RND4(pkt_offset); + break; + case USB_RX_AGG_DISABLE: + default: + break; + } +#endif + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + { + if(pre_recv_entry(precvframe, prxstat, pphy_info) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); + } + } + else + { + rtl8192c_translate_rx_signal_stuff(precvframe, pphy_info); + if(rtw_recv_entry(precvframe) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } + } + +#else + rtl8192c_translate_rx_signal_stuff(precvframe, pphy_info); + if(rtw_recv_entry(precvframe) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } +#endif + + pkt_cnt--; + transfer_len -= pkt_offset; + pbuf += pkt_offset; + precvframe = NULL; + pkt_copy = NULL; + + if(transfer_len>0 && pkt_cnt==0) + pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff; + + }while((transfer_len>0) && (pkt_cnt>0)); + +_exit_recvbuf2recvframe: + + return _SUCCESS; +} + +void rtl8192cu_recv_tasklet(void *priv) +{ + _pkt *pskb; + _adapter *padapter = (_adapter*)priv; + struct recv_priv *precvpriv = &padapter->recvpriv; + + while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) + { + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE)) + { + DBG_8192C("recv_tasklet => bDriverStopped or bSurpriseRemoved \n"); + 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 + + } + +} + + +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(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel) + { + 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()-%d: RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n", + __FUNCTION__, __LINE__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel); + 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_urb_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_urb_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: + precvpriv->read_port_complete_EINPROGRESS_cnt++; + DBG_8192C("ERROR: URB IS IN PROGRESS!/n"); + break; + default: + precvpriv->read_port_complete_other_urb_err_cnt++; + 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 recv_priv *precvpriv = &adapter->recvpriv; + struct usb_device *pusbd = pdvobj->pusbdev; + +_func_enter_; + + if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\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 + + + if(precvbuf !=NULL) + { + rtl8192cu_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")); + precvpriv->recvbuf_skb_alloc_fail_cnt++; + 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; + } + } + else + { + precvpriv->recvbuf_null_cnt++; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n")); + ret = _FAIL; + } + +_func_exit_; + + return ret; +} +#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX + +void rtl8192cu_xmit_tasklet(void *priv) +{ + int ret = _FALSE; + _adapter *padapter = (_adapter*)priv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if(check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE) + return; + + while(1) + { + if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE) || (padapter->bWritePortCancel == _TRUE)) + { + DBG_8192C("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n"); + break; + } + + ret = rtl8192cu_xmitframe_complete(padapter, pxmitpriv, NULL); + + if(ret==_FALSE) + break; + + } + +} + +void rtl8192cu_set_intf_ops(struct _io_ops *pops) +{ + _func_enter_; + + _rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops)); + + pops->_read8 = &usb_read8; + pops->_read16 = &usb_read16; + pops->_read32 = &usb_read32; + pops->_read_mem = &usb_read_mem; + pops->_read_port = &usb_read_port; + + pops->_write8 = &usb_write8; + pops->_write16 = &usb_write16; + pops->_write32 = &usb_write32; + pops->_writeN = &usb_writeN; + +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ + pops->_write8_async= &usb_async_write8; + pops->_write16_async = &usb_async_write16; + pops->_write32_async = &usb_async_write32; +#endif + pops->_write_mem = &usb_write_mem; + pops->_write_port = &usb_write_port; + + pops->_read_port_cancel = &usb_read_port_cancel; + pops->_write_port_cancel = &usb_write_port_cancel; + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE + pops->_read_interrupt = &usb_read_interrupt; +#endif + + _func_exit_; + +} + diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c new file mode 100755 index 00000000..32ff645a --- /dev/null +++ b/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c @@ -0,0 +1,1265 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_OPS_OS_C_ + +#include +#include +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + #error "Shall be Linux or Windows, but not both!\n" +#endif + +#ifndef CONFIG_USB_HCI + #error "CONFIG_USB_HCI shall be on!\n" +#endif + + +#include +#include +#include + +#include +#include + +#include + + +struct zero_bulkout_context +{ + void *pbuf; + void *purb; + void *pirp; + void *padapter; +}; + +#define usb_write_cmd usb_write_mem +#define usb_read_cmd usb_read_mem +#define usb_write_cmd_complete usb_write_mem_complete +//#define usb_read_cmd_complete usb_read_mem_complete + + + +uint usb_init_intf_priv(struct intf_priv *pintfpriv) +{ + + PURB piorw_urb; + u8 NextDeviceStackSize; + struct dvobj_priv *pdev = (struct dvobj_priv *)pintfpriv->intf_dev; + _adapter * padapter=pdev->padapter; + +_func_enter_; + + RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("\n +usb_init_intf_priv\n")); + + pintfpriv->intf_status = _IOREADY; + + if(pdev->ishighspeed) pintfpriv->max_iosz = 128; + else pintfpriv->max_iosz = 64; + + + _init_timer(&pintfpriv->io_timer, padapter->hndis_adapter, io_irp_timeout_handler, pintfpriv); + + + RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("usb_init_intf_priv:pintfpriv->max_iosz:%d\n",pintfpriv->max_iosz)); + + pintfpriv->io_wsz = 0; + pintfpriv->io_rsz = 0; + + pintfpriv->allocated_io_rwmem = rtw_zmalloc(pintfpriv->max_iosz +4); + + if (pintfpriv->allocated_io_rwmem == NULL){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_init_intf_priv:pintfpriv->allocated_io_rwmem == NULL\n")); + goto usb_init_intf_priv_fail; + } + + pintfpriv->io_rwmem = pintfpriv->allocated_io_rwmem + 4 \ + -( (u32)(pintfpriv->allocated_io_rwmem) & 3); + + + + NextDeviceStackSize = (u8)pdev->nextdevstacksz;//pintfpriv->pUsbDevObj->StackSize + 1; + + piorw_urb = (PURB)ExAllocatePool(NonPagedPool, sizeof(URB) ); + if(piorw_urb == NULL) + goto usb_init_intf_priv_fail; + + pintfpriv->piorw_urb = piorw_urb; + + pintfpriv->piorw_irp = IoAllocateIrp(NextDeviceStackSize , FALSE); + + + pintfpriv->io_irp_cnt=1; + pintfpriv->bio_irp_pending=_FALSE; + + _rtw_init_sema(&(pintfpriv->io_retevt), 0);//NdisInitializeEvent(&pintfpriv->io_irp_return_evt); + +_func_exit_; + return _SUCCESS; + +usb_init_intf_priv_fail: + + if (pintfpriv->allocated_io_rwmem) + rtw_mfree((u8 *)(pintfpriv->allocated_io_rwmem), pintfpriv->max_iosz +4); + + if(piorw_urb) + ExFreePool(piorw_urb); + + RT_TRACE(_module_hci_ops_os_c_,_drv_info_,("\n -usb_init_intf_priv(usb_init_intf_priv_fail)\n")); + +_func_exit_; + return _FAIL; + +} + +void usb_unload_intf_priv(struct intf_priv *pintfpriv) +{ + +_func_enter_; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n+usb_unload_intf_priv\n")); + + rtw_mfree((u8 *)(pintfpriv->allocated_io_rwmem), pintfpriv->max_iosz+4); + +#ifdef PLATFORM_WINDOWS + if(pintfpriv->piorw_urb) + ExFreePool(pintfpriv->piorw_urb); + + if(pintfpriv->piorw_irp) + IoFreeIrp(pintfpriv->piorw_irp); +#endif + + +#ifdef PLATFORM_LINUX + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\npintfpriv->io_irp_cnt=%d\n",pintfpriv->io_irp_cnt)); + pintfpriv->io_irp_cnt--; + if(pintfpriv->io_irp_cnt){ + if(pintfpriv->bio_irp_pending==_TRUE){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\nkill iorw_urb\n")); + usb_kill_urb(pintfpriv->piorw_urb); + } + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n wait io_retevt\n")); + _rtw_down_sema(&(pintfpriv->io_retevt)); + } + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n cancel io_urb ok\n")); +#endif + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n-usb_unload_intf_priv\n")); + +_func_exit_; + +} + +void *ffaddr2pipehdl(struct dvobj_priv *pNdisCEDvice, u32 addr) +{ + HANDLE PipeHandle = NULL; + _adapter *padapter = pNdisCEDvice->padapter; + + + if(pNdisCEDvice->nr_endpoint == 11) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3] ; + break; + case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[4]; + break; + case RTL8712_DMA_VIQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_BCNQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[6]; + break; + case RTL8712_DMA_BMCQ: //HI Queue + PipeHandle= padapter->halpriv.pipehdls_r8712[7]; + break; + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[8]; + break; + case RTL8712_DMA_RX0FF: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[5]; + break; + case RTL8712_DMA_H2CCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[9]; + break; + + } + + } + else if(pNdisCEDvice->nr_endpoint == 6) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3]; + break; + case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[4]; + break; + case RTL8712_DMA_VIQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_RX0FF: + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_H2CCMD: + case RTL8712_DMA_BCNQ: + case RTL8712_DMA_BMCQ: + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[5]; + break; + + } + + } + else if(pNdisCEDvice->nr_endpoint == 4) + { + switch(addr) + { + case RTL8712_DMA_BEQ: + //case RTL8712_DMA_BKQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[2]; + break; + //case RTL8712_DMA_VIQ: + case RTL8712_DMA_VOQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[1]; + break; + case RTL8712_DMA_RX0FF: + case RTL8712_DMA_C2HCMD: + PipeHandle= padapter->halpriv.pipehdls_r8712[0]; + break; + case RTL8712_DMA_H2CCMD: + case RTL8712_DMA_BCNQ: + case RTL8712_DMA_BMCQ: + case RTL8712_DMA_MGTQ: + PipeHandle= padapter->halpriv.pipehdls_r8712[3]; + break; + } + + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("ffaddr2pipehdl():nr_endpoint=%d error!\n", pNdisCEDvice->nr_endpoint)); + } + + return PipeHandle; + +} + + +NTSTATUS usb_bulkout_zero_complete( + PDEVICE_OBJECT pUsbDevObj, + PIRP pIrp, void* pZeroContext) +{ + struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)pZeroContext; + +_func_enter_; + + if(pcontext) + { + if(pcontext->pbuf) + { + ExFreePool(pcontext->pbuf); + } + + if(pcontext->purb) + { + ExFreePool(pcontext->purb); + } + + if(pcontext->pirp && (pIrp ==pcontext->pirp)) + { + IoFreeIrp(pIrp); + } + + ExFreePool(pcontext); + } + +_func_exit_; + + return STATUS_MORE_PROCESSING_REQUIRED; + + +} + +u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) +{ + struct zero_bulkout_context *pcontext; + unsigned char *pbuf; + char NextDeviceStackSize, len; + PIO_STACK_LOCATION nextStack; + USBD_STATUS usbdstatus; + HANDLE PipeHandle; + PIRP pirp = NULL; + PURB purb = NULL; + NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; + _adapter *padapter = (_adapter *)pintfhdl->adapter; + struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv; + + +_func_enter_; + + if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) + { + return _FAIL; + } + + len = 0; + NextDeviceStackSize = (char)pdvobj->nextdevstacksz; + + pcontext = (struct zero_bulkout_context *)ExAllocatePool(NonPagedPool, sizeof(struct zero_bulkout_context)); + pbuf = (unsigned char *)ExAllocatePool(NonPagedPool, sizeof(int)); + purb = (PURB)ExAllocatePool(NonPagedPool, sizeof(URB)); + pirp = IoAllocateIrp(NextDeviceStackSize, FALSE); + + pcontext->pbuf = pbuf; + pcontext->purb = purb; + pcontext->pirp = pirp; + pcontext->padapter = padapter; + + //translate DMA FIFO addr to pipehandle + PipeHandle = ffaddr2pipehdl(pdvobj, addr); + + + // Build our URB for USBD + UsbBuildInterruptOrBulkTransferRequest( + purb, + sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), + PipeHandle, + pbuf, + NULL, + len, + 0, + NULL); + + // + // call the calss driver to perform the operation + // pass the URB to the USB driver stack + // + nextStack = IoGetNextIrpStackLocation(pirp); + nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + nextStack->Parameters.Others.Argument1 = purb; + nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + + //Set Completion Routine + IoSetCompletionRoutine(pirp, // irp to use + usb_bulkout_zero_complete, // callback routine + pcontext, // context + TRUE, // call on success + TRUE, // call on error + TRUE); // call on cancel + + + // Call IoCallDriver to send the irp to the usb bus driver + // + ndisStatus = IoCallDriver(pdvobj->pnextdevobj, pirp); + usbdstatus = URB_STATUS(purb); + + if( USBD_HALTED(usbdstatus) ) + { + padapter->bDriverStopped=_TRUE; + padapter->bSurpriseRemoved=_TRUE; + } + + // + // The usb bus driver should always return STATUS_PENDING when bulk out irp async + // + if ( ndisStatus != STATUS_PENDING ) + { + return _FAIL; + } + +_func_exit_; + + return _SUCCESS; + +} + +void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + _func_enter_; + + + + _func_exit_; +} + +NTSTATUS usb_write_mem_complete(PDEVICE_OBJECT pUsbDevObj, PIRP piowrite_irp, PVOID pusb_cnxt) +{ + + _irqL irqL; + _list *head, *plist; + struct io_req *pio_req; + struct io_queue *pio_q = (struct io_queue *) pusb_cnxt; + struct intf_hdl *pintf = &(pio_q->intf); + struct intf_priv *pintfpriv = pintf->pintfpriv; + _adapter *padapter = (_adapter *)pintf->adapter; + NTSTATUS status = STATUS_SUCCESS; + + head = &(pio_q->processing); + + _func_enter_; + + _enter_critical_bh(&(pio_q->lock), &irqL); + + pintfpriv->io_irp_cnt--; + if(pintfpriv->io_irp_cnt ==0){ + _rtw_up_sema(&(pintfpriv->io_retevt)); + } + + pintfpriv->bio_irp_pending=_FALSE; + + switch(piowrite_irp->IoStatus.Status) + { + case STATUS_SUCCESS: + break; + + default: + padapter->bSurpriseRemoved=_TRUE; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usbAsynIntOutComplete:pioread_irp->IoStatus.Status !=STATUS_SUCCESS\n")); + break; + } + + //free irp in processing list... + while(rtw_is_list_empty(head) != _TRUE) + { + plist = get_next(head); + rtw_list_delete(plist); + pio_req = LIST_CONTAINOR(plist, struct io_req, list); + _rtw_up_sema(&pio_req->sema); + } + + _exit_critical_bh(&(pio_q->lock), &irqL); + + _func_exit_; + + return STATUS_MORE_PROCESSING_REQUIRED; + +} + +void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + u32 bwritezero; + _irqL irqL; + USBD_STATUS usbdstatus; + PIO_STACK_LOCATION nextStack; + HANDLE PipeHandle; + struct io_req *pio_req; + + _adapter *adapter = (_adapter *)pintfhdl->adapter; + struct intf_priv *pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv *pdev = (struct dvobj_priv *)pintfpriv->intf_dev; + PURB piorw_urb = pintfpriv->piorw_urb; + PIRP piorw_irp = pintfpriv->piorw_irp; + struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + NTSTATUS NtStatus = STATUS_SUCCESS; + + _func_enter_; + + pio_req = alloc_ioreq(pio_queue); + + if ((pio_req == NULL)||(adapter->bSurpriseRemoved)){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("async_irp_write32 : pio_req =0x%x adapter->bSurpriseRemoved=0x%x",pio_req,adapter->bSurpriseRemoved )); + goto exit; + } + + _enter_critical_bh(&(pio_queue->lock), &irqL); + + rtw_list_insert_tail(&(pio_req->list),&(pio_queue->processing)); + + +#ifdef NDIS51_MINIPORT + IoReuseIrp(piorw_irp, STATUS_SUCCESS); +#else + piorw_irp->Cancel = _FALSE; +#endif + + if((adapter->bDriverStopped) || (adapter->bSurpriseRemoved) ||(adapter->pwrctrlpriv.pnp_bstop_trx)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\npadapter->pwrctrlpriv.pnp_bstop_trx==_TRUE\n")); + _func_exit_; + return; + } + + //translate DMA FIFO addr to pipehandle + PipeHandle = ffaddr2pipehdl(pdev, addr); + + + pintfpriv->io_irp_cnt++; + pintfpriv->bio_irp_pending=_TRUE; + // Build our URB for USBD + UsbBuildInterruptOrBulkTransferRequest( + piorw_urb, + sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), + PipeHandle, + (PVOID)wmem, + NULL, + cnt, + 0, + NULL); + + // + // call the calss driver to perform the operation + // pass the URB to the USB driver stack + // + nextStack = IoGetNextIrpStackLocation(piorw_irp); + nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + nextStack->Parameters.Others.Argument1 = (PURB)piorw_urb; + nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + + IoSetCompletionRoutine( + piorw_irp, // irp to use + usb_write_mem_complete, // routine to call when irp is done + pio_queue, // context to pass routine + TRUE, // call on success + TRUE, // call on error + TRUE); // call on cancel + + // + // Call IoCallDriver to send the irp to the usb port + // + NtStatus = IoCallDriver(pdev->pnextdevobj, piorw_irp); + usbdstatus = URB_STATUS(piorw_urb); + + // + // The USB driver should always return STATUS_PENDING when + // it receives a write irp + // + if ((NtStatus != STATUS_PENDING) || USBD_HALTED(usbdstatus) ) { + + if( USBD_HALTED(usbdstatus) ) { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_mem():USBD_HALTED(usbdstatus)=%X!\n",USBD_HALTED(usbdstatus)) ); + } + _func_exit_; + return;//STATUS_UNSUCCESSFUL; + } + + _exit_critical_bh(&(pio_queue->lock), &irqL); + + _rtw_down_sema(&pio_req->sema); + free_ioreq(pio_req, pio_queue); + + + bwritezero = _FALSE; + if (pdev->ishighspeed) + { + if(cnt> 0 && cnt%512 == 0) + bwritezero = _TRUE; + + } + else + { + if(cnt > 0 && cnt%64 == 0) + bwritezero = _TRUE; + } + + + if(bwritezero == _TRUE) + { + usb_bulkout_zero(pintfhdl, addr); + } + +exit: + + _func_exit_; + +} + +NTSTATUS usb_read_port_complete(PDEVICE_OBJECT pUsbDevObj, PIRP pIrp, PVOID context) +{ + uint isevt, *pbuf; + struct _URB_BULK_OR_INTERRUPT_TRANSFER *pbulkurb; + USBD_STATUS usbdstatus; + struct recv_buf *precvbuf = (struct recv_buf *)context; + _adapter *adapter =(_adapter *)precvbuf->adapter; + struct recv_priv *precvpriv = &adapter->recvpriv; + struct dvobj_priv *dev = (struct dvobj_priv *)&adapter->dvobjpriv; + PURB purb = precvbuf->purb; + struct intf_hdl *pintfhdl = &adapter->pio_queue->intf; + + //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n")); + + usbdstatus = URB_STATUS(purb); + + _rtw_spinlock_ex(&precvpriv->lock); + precvbuf->irp_pending=_FALSE; + precvpriv->rx_pending_cnt --; + _rtw_spinunlock_ex(&precvpriv->lock); + + 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( pIrp->Cancel == _TRUE ) { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: One IRP has been cancelled succesfully\n")); + return STATUS_MORE_PROCESSING_REQUIRED; + } + if(adapter->bSurpriseRemoved) { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); + return STATUS_MORE_PROCESSING_REQUIRED; + } + + switch(pIrp->IoStatus.Status) + { + case STATUS_SUCCESS: + + pbulkurb = &(precvbuf->purb)->UrbBulkOrInterruptTransfer; + if((pbulkurb->TransferBufferLength >(MAX_RECVBUF_SZ)) || (pbulkurb->TransferBufferLength < RXDESC_SIZE) ) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_read_port_complete: (pbulkurb->TransferBufferLength > MAX_RECVBUF_SZ) || (pbulkurb->TransferBufferLength < RXDESC_SIZE)\n")); + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + else + { + precvbuf->transfer_len = pbulkurb->TransferBufferLength; + + pbuf = (uint*)precvbuf->pbuf; + + if((isevt = *(pbuf+1)&0x1ff) == 0x1ff) + { + rxcmd_event_hdl(adapter, pbuf);//rx c2h events + + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + else + { + if(recvbuf2recvframe(adapter, precvbuf)==_FAIL)//rx packets + { + //precvbuf->reuse = _TRUE; + rtw_read_port(adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + } + + } + + break; + + default: + + if( !USBD_HALTED(usbdstatus) ) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_read_port_complete():USBD_HALTED(usbdstatus)=%x (need to handle ) \n",USBD_HALTED(usbdstatus))); + + } + else + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_read_port_complete(): USBD_HALTED(usbdstatus)=%x \n\n", USBD_HALTED(usbdstatus)) ); + adapter->bDriverStopped = _TRUE; + adapter->bSurpriseRemoved = _TRUE; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete(): USBD_HALTED(usbdstatus)=%x \n\n", USBD_HALTED(usbdstatus))) ; + } + + break; + + } + + return STATUS_MORE_PROCESSING_REQUIRED; + +} + +u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + u8 *pdata; + u16 size; + PURB purb; + PIRP pirp; + PIO_STACK_LOCATION nextStack; + NTSTATUS ntstatus; + USBD_STATUS usbdstatus; + HANDLE PipeHandle; + struct recv_buf *precvbuf = (struct recv_buf *)rmem; + struct intf_priv *pintfpriv = pintfhdl->pintfpriv; + struct dvobj_priv *pdev = (struct dvobj_priv *)pintfpriv->intf_dev; + _adapter *adapter = (_adapter *)pdev->padapter; + struct recv_priv *precvpriv = &adapter->recvpriv; + u32 bResult = _FALSE; + +_func_enter_; + + if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx) { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + return bResult; + } + + if(precvbuf !=NULL) + { + + rtl8192cu_init_recvbuf(adapter, precvbuf); + + _rtw_spinlock(&precvpriv->lock); + precvpriv->rx_pending_cnt++; + precvbuf->irp_pending = _TRUE; + _rtw_spinunlock(&precvpriv->lock); + + pdata = (u8*)precvbuf->pbuf; + + size = sizeof( struct _URB_BULK_OR_INTERRUPT_TRANSFER ); + purb = precvbuf->purb; + + //translate DMA FIFO addr to pipehandle + PipeHandle = ffaddr2pipehdl(pdev, addr); + + UsbBuildInterruptOrBulkTransferRequest( + purb, + (USHORT)size, + PipeHandle, + pdata, + NULL, + MAX_RECVBUF_SZ, + USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, + NULL + ); + + pirp = precvbuf->pirp; + +#if NDIS51_MINIPORT + IoReuseIrp(pirp, STATUS_SUCCESS); +#else + pirp->Cancel = _FALSE; +#endif + + // call the class driver to perform the operation + // and pass the URB to the USB driver stack + nextStack = IoGetNextIrpStackLocation(pirp); + nextStack->Parameters.Others.Argument1 = purb; + nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + + IoSetCompletionRoutine( + pirp, // irp to use + usb_read_port_complete, // routine to call when irp is done + precvbuf, // context to pass routine + TRUE, // call on success + TRUE, // call on error + TRUE); // call on cancel + + // + // The IoCallDriver routine + // sends an IRP to the driver associated with a specified device object. + // + ntstatus = IoCallDriver(pdev->pnextdevobj, pirp); + usbdstatus = URB_STATUS(purb); + + if( USBD_HALTED(usbdstatus) ) { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_read_port(): USBD_HALTED(usbdstatus=0x%.8x)=%.8x \n\n", usbdstatus, USBD_HALTED(usbdstatus))); + pdev->padapter->bDriverStopped=_TRUE; + pdev->padapter->bSurpriseRemoved=_TRUE; + } + + if( ntstatus == STATUS_PENDING ) + { + bResult = _TRUE;// The IRP is pended in USBD as we expected. + } + else { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port(): IoCallDriver failed!!! IRP STATUS: %X\n", ntstatus)); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port(): IoCallDriver failed!!! USB STATUS: %X\n", usbdstatus)); + } + + } + else{ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precv_frame ==NULL\n")); + } + +_func_exit_; + + return bResult; + +} + +void usb_read_port_cancel(_adapter *padapter) +{ + struct recv_buf *precvbuf; + sint i; + struct dvobj_priv *pdev = &padapter->dvobjpriv; + struct recv_priv *precvpriv=&padapter->recvpriv; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n ==>usb_read_port_cancel\n")); + + _rtw_spinlock(&precvpriv->lock); + precvpriv->rx_pending_cnt--; //decrease 1 for Initialize ++ + _rtw_spinunlock(&precvpriv->lock); + + if (precvpriv->rx_pending_cnt) + { + // Canceling Pending Recv Irp + precvbuf = (struct recv_buf *)precvpriv->precv_buf; + + for( i = 0; i < NR_RECVBUFF; i++ ) + { + if (precvbuf->irp_pending == _TRUE) + { + IoCancelIrp(precvbuf->pirp); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_cancel() :IoCancelIrp\n")); + } + + precvbuf++; + } + + _rtw_down_sema(&precvpriv->allrxreturnevt); + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_cancel:down sema\n")); + + } + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("<==usb_read_port_cancel\n")); + +} + +NTSTATUS usb_write_port_complete( + PDEVICE_OBJECT pUsbDevObj, + PIRP pIrp, + PVOID pTxContext +) +{ + u32 i, bIrpSuccess, sz; + NTSTATUS status = STATUS_SUCCESS; + u8 *ptr; + struct xmit_frame *pxmitframe = (struct xmit_frame *) pTxContext; + struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; + _adapter *padapter = pxmitframe->padapter; + struct dvobj_priv *pdev = (struct dvobj_priv *)&padapter->dvobjpriv; + struct io_queue *pio_queue = (struct io_queue *)padapter->pio_queue; + struct intf_hdl *pintfhdl = &(pio_queue->intf); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + +_func_enter_; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port_complete\n")); + + _rtw_spinlock_ex(&pxmitpriv->lock); + pxmitpriv->txirp_cnt--; + _rtw_spinunlock_ex(&pxmitpriv->lock); + + if(pxmitpriv->txirp_cnt==0){ + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n")); + _rtw_up_sema(&(pxmitpriv->tx_retevt)); + } + + status = pIrp->IoStatus.Status; + + if( status == STATUS_SUCCESS ) + bIrpSuccess = _TRUE; + else + bIrpSuccess = _FALSE; + + if( pIrp->Cancel == _TRUE ) + { + if(pxmitframe !=NULL) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_write_port_complete:pIrp->Cancel == _TRUE,(pxmitframe !=NULL\n")); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + } + + return STATUS_MORE_PROCESSING_REQUIRED; + } + + if(padapter->bSurpriseRemoved) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + return STATUS_MORE_PROCESSING_REQUIRED; + } + + + // + // Send 0-byte here if necessary. + // + // + // 1. We MUST keep at most one IRP pending in each endpoint, otherwise USB host controler driver will hang. + // Besides, even 0-byte IRP shall be count into #IRP sent down, so, we send 0-byte here instead of TxFillDescriptor8187(). + // 2. If we don't count 0-byte IRP into an #IRP sent down, Tx will stuck when we download files via BT and + // play online video on XP SP1 EHCU. + // 2005.12.26, by rcnjko. + // + + + for(i=0; i< 8; i++) + { + if(pIrp == pxmitframe->pxmit_irp[i]) + { + pxmitframe->bpending[i] = _FALSE;// + //ac_tag = pxmitframe->ac_tag[i]; + sz = pxmitframe->sz[i]; + break; + } + } + +#if 0 + pxmitframe->fragcnt--; + if(pxmitframe->fragcnt == 0)// if((pxmitframe->fragcnt == 0) && (pxmitframe->irpcnt == 8)){ + { + //RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_write_port_complete:pxmitframe->fragcnt == 0\n")); + rtw_free_xmitframe(pxmitpriv,pxmitframe); + } +#else + + //not to consider tx fragment + rtw_free_xmitframe(pxmitpriv, pxmitframe); + +#endif + + rtl8192cu_xmitframe_complete(padapter, pxmitpriv, pxmitbuf); + +_func_exit_; + + return STATUS_MORE_PROCESSING_REQUIRED; + +} + +u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + u32 i, bwritezero; + u8 *ptr; + PIO_STACK_LOCATION nextStack; + USBD_STATUS usbdstatus; + HANDLE PipeHandle; + PIRP pirp = NULL; + PURB purb = NULL; + NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; + _adapter *padapter = (_adapter *)pintfhdl->adapter; + struct dvobj_priv *pNdisCEDvice = (struct dvobj_priv *)&padapter->dvobjpriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem; + +_func_enter_; + + if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + return _FAIL; + } + + + for(i=0; i<8; i++) + { + if(pxmitframe->bpending[i] == _FALSE) + { + _rtw_spinlock(&pxmitpriv->lock); + pxmitpriv->txirp_cnt++; + pxmitframe->bpending[i] = _TRUE; + _rtw_spinunlock(&pxmitpriv->lock); + + pxmitframe->sz[i] = cnt; + purb = pxmitframe->pxmit_urb[i]; + pirp = pxmitframe->pxmit_irp[i]; + + //pxmitframe->ac_tag[i] = ac_tag; + + break; + } + } + + bwritezero = _FALSE; + if (pNdisCEDvice->ishighspeed) + { + if(cnt> 0 && cnt%512 == 0) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("ishighspeed, cnt=%d\n", cnt)); + //cnt=cnt+1; + bwritezero = _TRUE; + } + } + else + { + if(cnt > 0 && cnt%64 == 0) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cnt=%d\n", cnt)); + //cnt=cnt+1; + bwritezero = _TRUE; + } + } + + +#ifdef NDIS51_MINIPORT + IoReuseIrp(pirp, STATUS_SUCCESS); +#else + pirp->Cancel = _FALSE; +#endif + + + //translate DMA FIFO addr to pipehandle + PipeHandle = ffaddr2pipehdl(pNdisCEDvice, addr); + + + // Build our URB for USBD + UsbBuildInterruptOrBulkTransferRequest( + purb, + sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), + PipeHandle, + pxmitframe->mem_addr, + NULL, + cnt, + 0, + NULL); + + // + // call the calss driver to perform the operation + // pass the URB to the USB driver stack + // + nextStack = IoGetNextIrpStackLocation(pirp); + nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + nextStack->Parameters.Others.Argument1 = purb; + nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + + //Set Completion Routine + IoSetCompletionRoutine(pirp, // irp to use + usb_write_port_complete, // callback routine + pxmitframe, // context + TRUE, // call on success + TRUE, // call on error + TRUE); // call on cancel + + + // Call IoCallDriver to send the irp to the usb bus driver + // + ndisStatus = IoCallDriver(pNdisCEDvice->pnextdevobj, pirp); + usbdstatus = URB_STATUS(purb); + + if( USBD_HALTED(usbdstatus) ) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_write_port(): USBD_HALTED(usbdstatus)=%x set bDriverStopped TRUE!\n\n",USBD_HALTED(usbdstatus)) ); + padapter->bDriverStopped=_TRUE; + padapter->bSurpriseRemoved=_TRUE; + } + + // + // The usb bus driver should always return STATUS_PENDING when bulk out irp async + // + if ( ndisStatus != STATUS_PENDING ) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\n usb_write_port(): ndisStatus(%x) != STATUS_PENDING!\n\n", ndisStatus)); + + _func_exit_; + + return _FAIL; + } + + if(bwritezero == _TRUE) + { + usb_bulkout_zero(pintfhdl, addr); + } + + +_func_exit_; + + return _SUCCESS; + +} + + +void usb_write_port_cancel(_adapter *padapter) +{ + + sint i,j; + struct dvobj_priv *pdev = &padapter->dvobjpriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + struct xmit_frame *pxmitframe; + + _rtw_spinlock(&pxmitpriv->lock); + pxmitpriv->txirp_cnt--; //decrease 1 for Initialize ++ + _rtw_spinunlock(&pxmitpriv->lock); + + if (pxmitpriv->txirp_cnt) + { + // Canceling Pending Recv Irp + pxmitframe= (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; + + for( i = 0; i < NR_XMITFRAME; i++ ) + { + for(j=0;j<8;j++) + { + if (pxmitframe->bpending[j]==_TRUE) + { + IoCancelIrp(pxmitframe->pxmit_irp[j]); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,(" usb_write_port_cancel() :IoCancelIrp\n")); + + } + } + + pxmitframe++; + } + + _rtw_down_sema(&(pxmitpriv->tx_retevt)); + + } + +} + + +/*! \brief Wrap the pUrb to an IRP and send this IRP to Bus Driver. Then wait for this IRP completion. + The Caller shall be at Passive Level. +*/ +NTSTATUS sync_callusbd(struct dvobj_priv *pdvobjpriv, PURB purb) +{ + + KEVENT kevent; + PIRP irp; + IO_STATUS_BLOCK iostatusblock; + PIO_STACK_LOCATION nextstack; + USBD_STATUS usbdstatus; + LARGE_INTEGER waittime; + NTSTATUS ntstatus = STATUS_SUCCESS; + _adapter *padapter = pdvobjpriv->padapter; + + + _func_enter_; + +// if(padapter->bDriverStopped) { +// goto exit; +// } + + KeInitializeEvent(&kevent, NotificationEvent, _FALSE); + irp = IoBuildDeviceIoControlRequest( + IOCTL_INTERNAL_USB_SUBMIT_URB, + pdvobjpriv->pphysdevobj,//CEdevice->pUsbDevObj, + NULL, + 0, + NULL, + 0, + _TRUE, + &kevent, + &iostatusblock); + + if(irp == NULL) { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("SyncCallUSBD: memory alloc for irp failed\n")); + ntstatus=STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + nextstack = IoGetNextIrpStackLocation(irp); + if(nextstack == NULL) + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("IoGetNextIrpStackLocation fail\n")); + + nextstack->Parameters.Others.Argument1 = purb; + + // Issue an IRP for Sync IO. + ntstatus = IoCallDriver(pdvobjpriv->pphysdevobj, irp); + usbdstatus = URB_STATUS(purb); + + if(ntstatus == STATUS_PENDING) + { + // Method 1 + waittime.QuadPart = -10000 * 50000; + ntstatus = KeWaitForSingleObject(&kevent, Executive, KernelMode, _FALSE, &waittime); //8150 code + + // Method 2 + //ntStatus = KeWaitForSingleObject(&Kevent, Executive, KernelMode, FALSE, NULL); //DDK sample + + usbdstatus = URB_STATUS(purb); + + if(ntstatus == STATUS_TIMEOUT) + { + //usbdevice->nIoStuckCnt++; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("SyncCallUSBD: TIMEOUT....5000ms\n")); + + // Method 2 + IoCancelIrp(irp); + ntstatus = KeWaitForSingleObject(&kevent, Executive, KernelMode, _FALSE, NULL); //DDK sample + usbdstatus = URB_STATUS(purb); + + usbdstatus = USBD_STATUS_SUCCESS; + } + + } + +exit: + + _func_exit_; + + return ntstatus; + +} +int usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) +{ + PURB purb; + u8 ret; + unsigned long transferflags; + NTSTATUS ntstatus; + + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfpriv->intf_dev; + + _func_enter_; + + ret=_TRUE; + purb = (PURB)ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST) ); + if(purb == NULL) { + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq(): Failed to allocate urb !!!\n")); + ret =_FALSE; + goto exit; + } + + if (requesttype == 0x01) { + transferflags = USBD_TRANSFER_DIRECTION_IN;//read_in + } else { + transferflags= 0;//write_out + } + + UsbBuildVendorRequest( + purb, //Pointer to an URB that is to be formatted as a vendor or class request. + URB_FUNCTION_VENDOR_DEVICE, //Indicates the URB is a vendor-defined request for a USB device. + sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), //Specifies the length, in bytes, of the URB. + transferflags, //TransferFlags + 0, //ReservedBits + request, //Request + value, //Value + index, //Index + pdata, //TransferBuffer + NULL, //TransferBufferMDL + len, //TransferBufferLength + NULL //Link + ); + + ntstatus = sync_callusbd(pdvobjpriv, purb); + if(!NT_SUCCESS(ntstatus)) + { + ExFreePool(purb); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,(" usbctrl_vendorreq() : SOMETHING WRONG\n") ); + ret = _FALSE; + goto exit; + } + + ExFreePool(purb); + +exit: + _func_exit_; + + return ret; + +} + diff --git a/rtl8192cu-fixes/include/Hal8192CEHWImg.h b/rtl8192cu-fixes/include/Hal8192CEHWImg.h new file mode 100755 index 00000000..4ae36300 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192CEHWImg.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * 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_HAL8192CE_FW_IMG_H +#define __INC_HAL8192CE_FW_IMG_H + +#include + +/*Created on 2011/ 6/15, 5:45*/ + +#ifdef CONFIG_BT_COEXISTENCE +#define TSMCImgArrayLength 15706 //v84 TSMC COMMON 2012-04-13 +#else //#ifdef CONFIG_P2P +#define TSMCImgArrayLength 16126 //v88 TSMC P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CEFwTSMCImgArray[TSMCImgArrayLength]; + +#ifdef CONFIG_BT_COEXISTENCE +#define UMCACutImgArrayLength 16248 //v79 UMC A Cut COMMON 2011-10-06 +#else //#ifdef CONFIG_P2P +#define UMCACutImgArrayLength 16126 //v88 UMC A Cut P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CEFwUMCACutImgArray[UMCACutImgArrayLength]; + +#ifdef CONFIG_BT_COEXISTENCE +#define UMCBCutImgArrayLength 15686 //v84 UMC B Cut COMMON 2012-04-13 +#else //#ifdef CONFIG_P2P +#define UMCBCutImgArrayLength 16096 //v88 UMC B Cut P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CEFwUMCBCutImgArray[UMCBCutImgArrayLength]; + +//8192C_Formal_92CE_PHYforMP_110804 2011-11-23 +//8188C_Formal_88CE_PHYforMP_111117 2011-11-23 + +#define PHY_REG_2TArrayLength 374 +extern u32 Rtl8192CEPHY_REG_2TArray[PHY_REG_2TArrayLength]; +#define PHY_REG_1TArrayLength 374 +extern u32 Rtl8192CEPHY_REG_1TArray[PHY_REG_1TArrayLength]; +#define PHY_ChangeTo_1T1RArrayLength 1 +extern u32 Rtl8192CEPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength]; +#define PHY_ChangeTo_1T2RArrayLength 1 +extern u32 Rtl8192CEPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength]; +#define PHY_ChangeTo_2T2RArrayLength 1 +extern u32 Rtl8192CEPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength]; +#define PHY_REG_Array_PGLength 336 +extern u32 Rtl8192CEPHY_REG_Array_PG[PHY_REG_Array_PGLength]; +#define PHY_REG_Array_MPLength 4 +extern u32 Rtl8192CEPHY_REG_Array_MP[PHY_REG_Array_MPLength]; +#define RadioA_2TArrayLength 282 +extern u32 Rtl8192CERadioA_2TArray[RadioA_2TArrayLength]; +#define RadioB_2TArrayLength 78 +extern u32 Rtl8192CERadioB_2TArray[RadioB_2TArrayLength]; +#define RadioA_1TArrayLength 282 +extern u32 Rtl8192CERadioA_1TArray[RadioA_1TArrayLength]; +#define RadioB_1TArrayLength 1 +extern u32 Rtl8192CERadioB_1TArray[RadioB_1TArrayLength]; +#define RadioB_GM_ArrayLength 1 +extern u32 Rtl8192CERadioB_GM_Array[RadioB_GM_ArrayLength]; +// MAC reg V14 - 2011-11-23 +#define MAC_2T_ArrayLength 174 +extern u32 Rtl8192CEMAC_2T_Array[MAC_2T_ArrayLength]; +#define MACPHY_Array_PGLength 1 +extern u32 Rtl8192CEMACPHY_Array_PG[MACPHY_Array_PGLength]; +#define AGCTAB_2TArrayLength 320 +extern u32 Rtl8192CEAGCTAB_2TArray[AGCTAB_2TArrayLength]; +#define AGCTAB_1TArrayLength 320 +extern u32 Rtl8192CEAGCTAB_1TArray[AGCTAB_1TArrayLength]; + +#endif //__INC_HAL8192CE_FW_IMG_H diff --git a/rtl8192cu-fixes/include/Hal8192CPhyCfg.h b/rtl8192cu-fixes/include/Hal8192CPhyCfg.h new file mode 100755 index 00000000..3afb292c --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192CPhyCfg.h @@ -0,0 +1,428 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * Module: __INC_HAL8192CPHYCFG_H + * + * + * Note: + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * + *****************************************************************************/ + /* Check to see if the file has been included already. */ +#ifndef __INC_HAL8192CPHYCFG_H +#define __INC_HAL8192CPHYCFG_H + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define HP_THERMAL_NUM 8 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0A0A +#else +#define MAX_AGGR_NUM 0x0909 +#endif + +#ifdef CONFIG_PCI_HCI +#define SET_RTL8192SE_RF_SLEEP(_pAdapter) \ +{ \ + u1Byte u1bTmp; \ + u1bTmp = PlatformEFIORead1Byte(_pAdapter, REG_LDOV12D_CTRL); \ + u1bTmp |= BIT0; \ + PlatformEFIOWrite1Byte(_pAdapter, REG_LDOV12D_CTRL, u1bTmp); \ + PlatformEFIOWrite1Byte(_pAdapter, REG_SPS_OCP_CFG, 0x0); \ + PlatformEFIOWrite1Byte(_pAdapter, TXPAUSE, 0xFF); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x57FC); \ + delay_us(100); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x77FC); \ + PlatformEFIOWrite1Byte(_pAdapter, PHY_CCA, 0x0); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x37FC); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x77FC); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x57FC); \ +} +#endif + + +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ +typedef enum _SwChnlCmdID{ + CmdID_End, + CmdID_SetTxPowerLevel, + CmdID_BBRegWrite10, + CmdID_WritePortUlong, + CmdID_WritePortUshort, + CmdID_WritePortUchar, + CmdID_RF_WriteReg, +}SwChnlCmdID; + + +/* 1. Switch channel related */ +typedef struct _SwChnlCmd{ + SwChnlCmdID CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +}SwChnlCmd; + +typedef enum _HW90_BLOCK{ + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, // Never use this +}HW90_BLOCK_E, *PHW90_BLOCK_E; + +#define RF_PATH_MAX 2 + +#define CHANNEL_MAX_NUMBER 14 // 14 is the max channel number +#define CHANNEL_GROUP_MAX 3 // ch1~3, ch4~9, ch10~14 total three groups + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20 +} WIRELESS_MODE; + +typedef enum _BaseBand_Config_Type{ + BaseBand_Config_PHY_REG = 0, //Radio Path A + BaseBand_Config_AGC_TAB = 1, //Radio Path B +}BaseBand_Config_Type, *PBaseBand_Config_Type; + + +typedef enum _PHY_Rate_Tx_Power_Offset_Area{ + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}RA_OFFSET_AREA,*PRA_OFFSET_AREA; + + +/* BB/RF related */ +typedef enum _RF_TYPE_8190P{ + RF_TYPE_MIN, // 0 + RF_8225=1, // 1 11b/g RF for verification only + RF_8256=2, // 2 11b/g/n + RF_8258=3, // 3 11a/b/g/n RF + RF_6052=4, // 4 11b/g/n RF + //RF_6052=5, // 4 11b/g/n RF + // TODO: We sholud remove this psudo PHY RF after we get new RF. + RF_PSEUDO_11N=5, // 5, It is a temporality RF. +}RF_TYPE_8190P_E,*PRF_TYPE_8190P_E; + +typedef struct _BB_REGISTER_DEFINITION{ + u32 rfintfs; // set software control: + // 0x870~0x877[8 bytes] + + u32 rfintfi; // readback data: + // 0x8e0~0x8e7[8 bytes] + + u32 rfintfo; // output data: + // 0x860~0x86f [16 bytes] + + u32 rfintfe; // output enable: + // 0x860~0x86f [16 bytes] + + u32 rf3wireOffset; // LSSI data: + // 0x840~0x84f [16 bytes] + + u32 rfLSSI_Select; // BB Band Select: + // 0x878~0x87f [8 bytes] + + u32 rfTxGainStage; // Tx gain stage: + // 0x80c~0x80f [4 bytes] + + u32 rfHSSIPara1; // wire parameter control1 : + // 0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes] + + u32 rfHSSIPara2; // wire parameter control2 : + // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] + + u32 rfSwitchControl; //Tx Rx antenna control : + // 0x858~0x85f [16 bytes] + + u32 rfAGCControl1; //AGC parameter control1 : + // 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] + + u32 rfAGCControl2; //AGC parameter control2 : + // 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] + + u32 rfRxIQImbalance; //OFDM Rx IQ imbalance matrix : + // 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] + + u32 rfRxAFE; //Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : + // 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes] + + u32 rfTxIQImbalance; //OFDM Tx IQ imbalance matrix + // 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes] + + u32 rfTxAFE; //Tx IQ DC Offset and Tx DFIR type + // 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] + + u32 rfLSSIReadBack; //LSSI RF readback data SI mode + // 0x8a0~0x8af [16 bytes] + + u32 rfLSSIReadBackPi; //LSSI RF readback data PI mode 0x8b8-8bc for Path A and B + +}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; + +#ifdef CONFIG_MP_INCLUDED +typedef enum _ANTENNA_PATH{ + ANTENNA_NONE = 0x00, + ANTENNA_D , + ANTENNA_C , + ANTENNA_CD , + ANTENNA_B , + ANTENNA_BD , + ANTENNA_BC , + ANTENNA_BCD , + ANTENNA_A , + ANTENNA_AD , + ANTENNA_AC , + ANTENNA_ACD , + ANTENNA_AB , + ANTENNA_ABD , + ANTENNA_ABC , + ANTENNA_ABCD +} ANTENNA_PATH; +#endif + +typedef struct _R_ANTENNA_SELECT_OFDM{ + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK{ + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +// +// BB and RF register read/write +// +u32 rtl8192c_PHY_QueryBBReg( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); +void rtl8192c_PHY_SetBBReg( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 rtl8192c_PHY_QueryRFReg( IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); +void rtl8192c_PHY_SetRFReg( IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +int PHY_MACConfig8192C( IN PADAPTER Adapter ); +int PHY_BBConfig8192C( IN PADAPTER Adapter ); +int PHY_RFConfig8192C( IN PADAPTER Adapter ); +/* RF config */ +int rtl8192c_PHY_ConfigRFWithParaFile( IN PADAPTER Adapter, + IN u8* pFileName, + IN RF_RADIO_PATH_E eRFPath); +int rtl8192c_PHY_ConfigRFWithHeaderFile( IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath); + +/* BB/RF readback check for making sure init OK */ +int rtl8192c_PHY_CheckBBAndRFOK( IN PADAPTER Adapter, + IN HW90_BLOCK_E CheckBlock, + IN RF_RADIO_PATH_E eRFPath ); +/* Read initi reg value for tx power setting. */ +void rtl8192c_PHY_GetHWRegOriginalValue( IN PADAPTER Adapter ); + +// +// RF Power setting +// +//extern BOOLEAN PHY_SetRFPowerState(IN PADAPTER Adapter, +// IN RT_RF_POWER_STATE eRFPowerState); + +// +// BB TX Power R/W +// +void PHY_GetTxPowerLevel8192C( IN PADAPTER Adapter, + OUT u32* powerlevel ); +void PHY_SetTxPowerLevel8192C( IN PADAPTER Adapter, + IN u8 channel ); +BOOLEAN PHY_UpdateTxPowerDbm8192C( IN PADAPTER Adapter, + IN int powerInDbm ); + +// +VOID +PHY_ScanOperationBackup8192C(IN PADAPTER Adapter, + IN u8 Operation ); + +// +// Switch bandwidth for 8192S +// +//extern void PHY_SetBWModeCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SetBWMode8192C( IN PADAPTER pAdapter, + IN HT_CHANNEL_WIDTH ChnlWidth, + IN unsigned char Offset ); + +// +// Set FW CMD IO for 8192S. +// +//extern BOOLEAN HalSetIO8192C( IN PADAPTER Adapter, +// IN IO_TYPE IOType); + +// +// Set A2 entry to fw for 8192S +// +extern void FillA2Entry8192C( IN PADAPTER Adapter, + IN u8 index, + IN u8* val); + + +// +// channel switch related funciton +// +//extern void PHY_SwChnlCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SwChnl8192C( IN PADAPTER pAdapter, + IN u8 channel ); + // Call after initialization +void PHY_SwChnlPhy8192C( IN PADAPTER pAdapter, + IN u8 channel ); + +void ChkFwCmdIoDone( IN PADAPTER Adapter); + +#ifdef USE_WORKITEM +//extern void SetIOWorkItemCallback( IN PVOID pContext ); +#else +//extern void SetIOTimerCallback( IN PRT_TIMER pTimer); +#endif + +// +// BB/MAC/RF other monitor API +// +void PHY_SetMonitorMode8192C(IN PADAPTER pAdapter, + IN BOOLEAN bEnableMonitorMode ); + +BOOLEAN PHY_CheckIsLegalRfPath8192C(IN PADAPTER pAdapter, + IN u32 eRFPath ); + +// +// IQ calibrate +// +VOID rtl8192c_PHY_IQCalibrate( IN PADAPTER pAdapter , IN BOOLEAN bReCovery); + +// +// LC calibrate +// +VOID rtl8192c_PHY_LCCalibrate(IN PADAPTER pAdapter); + +// +// AP calibrate +// +VOID rtl8192c_PHY_APCalibrate(IN PADAPTER pAdapter, IN char delta); + +VOID rtl8192c_PHY_SetRFPathSwitch(IN PADAPTER pAdapter, IN BOOLEAN bMain); + +// +// Modify the value of the hw register when beacon interval be changed. +// +void +rtl8192c_PHY_SetBeaconHwReg( IN PADAPTER Adapter, + IN u16 BeaconInterval ); + + +extern VOID +PHY_SwitchEphyParameter( + IN PADAPTER Adapter + ); + +extern VOID +PHY_EnableHostClkReq( + IN PADAPTER Adapter + ); + +BOOLEAN +SetAntennaConfig92C( + IN PADAPTER Adapter, + IN u8 DefaultAnt + ); + + +/*--------------------------Exported Function prototype---------------------*/ + +#define PHY_QueryBBReg(Adapter, RegAddr, BitMask) rtl8192c_PHY_QueryBBReg((Adapter), (RegAddr), (BitMask)) +#define PHY_SetBBReg(Adapter, RegAddr, BitMask, Data) rtl8192c_PHY_SetBBReg((Adapter), (RegAddr), (BitMask), (Data)) +#define PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask) rtl8192c_PHY_QueryRFReg((Adapter), (eRFPath), (RegAddr), (BitMask)) +#define PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data) rtl8192c_PHY_SetRFReg((Adapter), (eRFPath), (RegAddr), (BitMask), (Data)) + +#define PHY_SetMacReg PHY_SetBBReg + +#endif // __INC_HAL8192CPHYCFG_H + diff --git a/rtl8192cu-fixes/include/Hal8192CPhyReg.h b/rtl8192cu-fixes/include/Hal8192CPhyReg.h new file mode 100755 index 00000000..6364166d --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192CPhyReg.h @@ -0,0 +1,1123 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __INC_HAL8192CPHYREG_H + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __INC_HAL8192CPHYREG_H +#define __INC_HAL8192CPHYREG_H + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c + +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8192SPHYREG_H + diff --git a/rtl8192cu-fixes/include/Hal8192CUHWImg.h b/rtl8192cu-fixes/include/Hal8192CUHWImg.h new file mode 100755 index 00000000..ba3c282f --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192CUHWImg.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 __INC_HAL8192CU_FW_IMG_H +#define __INC_HAL8192CU_FW_IMG_H + +/*Created on 2011/ 6/15, 5:45*/ + +#ifdef CONFIG_BT_COEXISTENCE +#define TSMCImgArrayLength 15706 //v84 TSMC COMMON 2012-04-13 +#else //#ifdef CONFIG_P2P +#define TSMCImgArrayLength 16126 //v88 TSMC P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CUFwTSMCImgArray[TSMCImgArrayLength]; + +#ifdef CONFIG_BT_COEXISTENCE +#define UMCACutImgArrayLength 16248 //v79 UMC A Cut COMMON 2011-10-06 +#else //#ifdef CONFIG_P2P +#define UMCACutImgArrayLength 16126 //v88 UMC A Cut P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CUFwUMCACutImgArray[UMCACutImgArrayLength]; + +#ifdef CONFIG_BT_COEXISTENCE +#define UMCBCutImgArrayLength 15686 //v84 UMC B Cut COMMON 2012-04-13 +#else //#ifdef CONFIG_P2P +#define UMCBCutImgArrayLength 16096 //v88 UMC B Cut P2PPS with CCX report C2H 2012-12-05 +#endif +extern u8 Rtl8192CUFwUMCBCutImgArray[UMCBCutImgArrayLength]; + +//8188C_Formal_All_PHYforMP_111117 2011-11-23 +//8192C_Formal_92CU_PHYforMP_110817 2011-11-23 +#define PHY_REG_2TArrayLength 374 +extern u32 Rtl8192CUPHY_REG_2TArray[PHY_REG_2TArrayLength]; +#define PHY_REG_1TArrayLength 374 +extern u32 Rtl8192CUPHY_REG_1TArray[PHY_REG_1TArrayLength]; +#define PHY_ChangeTo_1T1RArrayLength 1 +extern u32 Rtl8192CUPHY_ChangeTo_1T1RArray[PHY_ChangeTo_1T1RArrayLength]; +#define PHY_ChangeTo_1T2RArrayLength 1 +extern u32 Rtl8192CUPHY_ChangeTo_1T2RArray[PHY_ChangeTo_1T2RArrayLength]; +#define PHY_ChangeTo_2T2RArrayLength 1 +extern u32 Rtl8192CUPHY_ChangeTo_2T2RArray[PHY_ChangeTo_2T2RArrayLength]; +#define PHY_REG_Array_PGLength 336 +extern u32 Rtl8192CUPHY_REG_Array_PG[PHY_REG_Array_PGLength]; +#define PHY_REG_Array_PG_mCardLength 336 +extern u32 Rtl8192CUPHY_REG_Array_PG_mCard[PHY_REG_Array_PG_mCardLength]; +#define PHY_REG_Array_MPLength 4 +extern u32 Rtl8192CUPHY_REG_Array_MP[PHY_REG_Array_MPLength]; +#define PHY_REG_1T_HPArrayLength 378 +extern u32 Rtl8192CUPHY_REG_1T_HPArray[PHY_REG_1T_HPArrayLength]; +#define PHY_REG_1T_mCardArrayLength 374 +extern u32 Rtl8192CUPHY_REG_1T_mCardArray[PHY_REG_1T_mCardArrayLength]; +#define PHY_REG_2T_mCardArrayLength 374 +extern u32 Rtl8192CUPHY_REG_2T_mCardArray[PHY_REG_2T_mCardArrayLength]; +#define PHY_REG_Array_PG_HPLength 336 +extern u32 Rtl8192CUPHY_REG_Array_PG_HP[PHY_REG_Array_PG_HPLength]; +#define RadioA_2TArrayLength 282 +extern u32 Rtl8192CURadioA_2TArray[RadioA_2TArrayLength]; +#define RadioB_2TArrayLength 78 +extern u32 Rtl8192CURadioB_2TArray[RadioB_2TArrayLength]; +#define RadioA_1TArrayLength 282 +extern u32 Rtl8192CURadioA_1TArray[RadioA_1TArrayLength]; +#define RadioB_1TArrayLength 1 +extern u32 Rtl8192CURadioB_1TArray[RadioB_1TArrayLength]; +#define RadioA_2T_mCardArrayLength 282 +extern u32 Rtl8192CURadioA_2T_mCardArray[RadioA_2T_mCardArrayLength]; +#define RadioB_2T_mCardArrayLength 78 +extern u32 Rtl8192CURadioB_2T_mCardArray[RadioB_2T_mCardArrayLength]; +#define RadioA_1T_mCardArrayLength 282 +extern u32 Rtl8192CURadioA_1T_mCardArray[RadioA_1T_mCardArrayLength]; +#define RadioB_1T_mCardArrayLength 1 +extern u32 Rtl8192CURadioB_1T_mCardArray[RadioB_1T_mCardArrayLength]; +#define RadioA_1T_HPArrayLength 282 +extern u32 Rtl8192CURadioA_1T_HPArray[RadioA_1T_HPArrayLength]; +#define RadioB_GM_ArrayLength 1 +extern u32 Rtl8192CURadioB_GM_Array[RadioB_GM_ArrayLength]; + +// MAC reg V14 - 2011-11-23 +#define MAC_2T_ArrayLength 174 +extern u32 Rtl8192CUMAC_2T_Array[MAC_2T_ArrayLength]; +#define MACPHY_Array_PGLength 1 +extern u32 Rtl8192CUMACPHY_Array_PG[MACPHY_Array_PGLength]; +#define AGCTAB_2TArrayLength 320 +extern u32 Rtl8192CUAGCTAB_2TArray[AGCTAB_2TArrayLength]; +#define AGCTAB_1TArrayLength 320 +extern u32 Rtl8192CUAGCTAB_1TArray[AGCTAB_1TArrayLength]; +#define AGCTAB_1T_HPArrayLength 320 +extern u32 Rtl8192CUAGCTAB_1T_HPArray[AGCTAB_1T_HPArrayLength]; + +#endif //__INC_HAL8192CU_FW_IMG_H diff --git a/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h b/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h new file mode 100755 index 00000000..47d4d2fc --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * 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_HAL8192CU_FW_IMG_WOWLAN_H +#define __INC_HAL8192CU_FW_IMG_WOWLAN_H + +/*Created on 2011/11/ 8, 14:15*/ + + +#define TSMCWWImgArrayLength 13458 +extern u8 Rtl8192CUFwTSMCWWImgArray[TSMCWWImgArrayLength]; +#define UMCACutWWImgArrayLength 13458 +extern u8 Rtl8192CUFwUMCACutWWImgArray[UMCACutWWImgArrayLength]; +#define UMCBCutWWImgArrayLength 13446 +extern u8 Rtl8192CUFwUMCBCutWWImgArray[UMCBCutWWImgArrayLength]; + +#endif //__INC_HAL8192CU_FW_IMG_WOWLAN_H + diff --git a/rtl8192cu-fixes/include/Hal8192DEHWImg.h b/rtl8192cu-fixes/include/Hal8192DEHWImg.h new file mode 100755 index 00000000..06397752 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192DEHWImg.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * 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_HAL8192DE_FW_IMG_H +#define __INC_HAL8192DE_FW_IMG_H + +#include + +/*Created on 2011/11/11, 8: 8*/ + +#define Rtl8192DEImgArrayLength 32296 +extern const u8 Rtl8192DEFwImgArray[Rtl8192DEImgArrayLength]; +#define Rtl8192DEMainArrayLength 1 +extern const u8 Rtl8192DEFwMainArray[Rtl8192DEMainArrayLength]; +#define Rtl8192DEDataArrayLength 1 +extern const u8 Rtl8192DEFwDataArray[Rtl8192DEDataArrayLength]; +#define Rtl8192DEPHY_REG_2TArrayLength 372 +extern const u32 Rtl8192DEPHY_REG_2TArray[Rtl8192DEPHY_REG_2TArrayLength]; +#define Rtl8192DEPHY_REG_1TArrayLength 1 +extern const u32 Rtl8192DEPHY_REG_1TArray[Rtl8192DEPHY_REG_1TArrayLength]; +#define Rtl8192DEPHY_REG_Array_PGLength 624 +extern const u32 Rtl8192DEPHY_REG_Array_PG[Rtl8192DEPHY_REG_Array_PGLength]; +#define Rtl8192DEPHY_REG_Array_MPLength 12 +extern const u32 Rtl8192DEPHY_REG_Array_MP[Rtl8192DEPHY_REG_Array_MPLength]; +#define Rtl8192DERadioA_2TArrayLength 378 +extern const u32 Rtl8192DERadioA_2TArray[Rtl8192DERadioA_2TArrayLength]; +#define Rtl8192DERadioB_2TArrayLength 384 +extern const u32 Rtl8192DERadioB_2TArray[Rtl8192DERadioB_2TArrayLength]; +#define Rtl8192DERadioA_1TArrayLength 1 +extern const u32 Rtl8192DERadioA_1TArray[Rtl8192DERadioA_1TArrayLength]; +#define Rtl8192DERadioB_1TArrayLength 1 +extern const u32 Rtl8192DERadioB_1TArray[Rtl8192DERadioB_1TArrayLength]; +#define Rtl8192DERadioA_2T_intPAArrayLength 378 +extern const u32 Rtl8192DERadioA_2T_intPAArray[Rtl8192DERadioA_2T_intPAArrayLength]; +#define Rtl8192DERadioB_2T_intPAArrayLength 384 +extern const u32 Rtl8192DERadioB_2T_intPAArray[Rtl8192DERadioB_2T_intPAArrayLength]; +#define Rtl8192DEMAC_2T_ArrayLength 192 +extern const u32 Rtl8192DEMAC_2T_Array[Rtl8192DEMAC_2T_ArrayLength]; +#define Rtl8192DEAGCTAB_ArrayLength 386 +extern const u32 Rtl8192DEAGCTAB_Array[Rtl8192DEAGCTAB_ArrayLength]; +#define Rtl8192DEAGCTAB_5GArrayLength 194 +extern const u32 Rtl8192DEAGCTAB_5GArray[Rtl8192DEAGCTAB_5GArrayLength]; +#define Rtl8192DEAGCTAB_2GArrayLength 194 +extern const u32 Rtl8192DEAGCTAB_2GArray[Rtl8192DEAGCTAB_2GArrayLength]; +#define Rtl8192DEAGCTAB_2TArrayLength 1 +extern const u32 Rtl8192DEAGCTAB_2TArray[Rtl8192DEAGCTAB_2TArrayLength]; +#define Rtl8192DEAGCTAB_1TArrayLength 1 +extern const u32 Rtl8192DEAGCTAB_1TArray[Rtl8192DEAGCTAB_1TArrayLength]; + +#endif //__INC_HAL8192CU_FW_IMG_H diff --git a/rtl8192cu-fixes/include/Hal8192DPhyCfg.h b/rtl8192cu-fixes/include/Hal8192DPhyCfg.h new file mode 100755 index 00000000..624fbda6 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192DPhyCfg.h @@ -0,0 +1,528 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __INC_HAL8192DPHYCFG_H + * + * + * Note: + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * + *****************************************************************************/ + /* Check to see if the file has been included already. */ +#ifndef __INC_HAL8192DPHYCFG_H +#define __INC_HAL8192DPHYCFG_H + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + + +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 10 +#define IQK_BB_REG_NUM_92C 9 +#define IQK_BB_REG_NUM_92D 10 +#define IQK_BB_REG_NUM_test 6 +#define index_mapping_NUM 13 +#define Rx_index_mapping_NUM 15 +#define AVG_THERMAL_NUM 8 +#define IQK_Matrix_REG_NUM 8 +#define IQK_Matrix_Settings_NUM 1+24+21 + +#ifdef CONFIG_PCI_HCI +#define SET_RTL8192SE_RF_SLEEP(_pAdapter) \ +{ \ + u1Byte u1bTmp; \ + u1bTmp = PlatformEFIORead1Byte(_pAdapter, REG_LDOV12D_CTRL); \ + u1bTmp |= BIT0; \ + PlatformEFIOWrite1Byte(_pAdapter, REG_LDOV12D_CTRL, u1bTmp); \ + PlatformEFIOWrite1Byte(_pAdapter, REG_SPS_OCP_CFG, 0x0); \ + PlatformEFIOWrite1Byte(_pAdapter, TXPAUSE, 0xFF); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x57FC); \ + delay_us(100); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x77FC); \ + PlatformEFIOWrite1Byte(_pAdapter, PHY_CCA, 0x0); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x37FC); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x77FC); \ + delay_us(10); \ + PlatformEFIOWrite2Byte(_pAdapter, CMDR, 0x57FC); \ +} +#endif + + +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ +typedef enum _SwChnlCmdID{ + CmdID_End, + CmdID_SetTxPowerLevel, + CmdID_BBRegWrite10, + CmdID_WritePortUlong, + CmdID_WritePortUshort, + CmdID_WritePortUchar, + CmdID_RF_WriteReg, +}SwChnlCmdID; + + +/* 1. Switch channel related */ +typedef struct _SwChnlCmd{ + SwChnlCmdID CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +}SwChnlCmd; + +typedef enum _HW90_BLOCK{ + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, // Never use this +}HW90_BLOCK_E, *PHW90_BLOCK_E; + +//vivi added this for read parameter from header, 20100908 +typedef enum _RF_CONTENT{ + radioa_txt = 0x1000, + radiob_txt = 0x1001, + radioc_txt = 0x1002, + radiod_txt = 0x1003 +} RF_CONTENT; + +#define RF_PATH_MAX 2 + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20 +} WIRELESS_MODE; + + +#define CHANNEL_MAX_NUMBER 14+24+21 // 14 is the max channel number +#define CHANNEL_GROUP_MAX 3+9 // ch1~3, ch4~9, ch10~14 total three groups +#define MAX_PG_GROUP 13 + +#define CHANNEL_GROUP_MAX_2G 3 +#define CHANNEL_GROUP_IDX_5GL 3 +#define CHANNEL_GROUP_IDX_5GM 6 +#define CHANNEL_GROUP_IDX_5GH 9 +#define CHANNEL_GROUP_MAX_5G 9 +#define CHANNEL_MAX_NUMBER_2G 14 + +typedef enum _BaseBand_Config_Type{ + BaseBand_Config_PHY_REG = 0, //Radio Path A + BaseBand_Config_AGC_TAB = 1, //Radio Path B +}BaseBand_Config_Type, *PBaseBand_Config_Type; + +typedef enum _MACPHY_MODE_8192D{ + SINGLEMAC_SINGLEPHY, + DUALMAC_DUALPHY, + DUALMAC_SINGLEPHY, +}MACPHY_MODE_8192D,*PMACPHY_MODE_8192D; + +typedef enum _MACPHY_MODE_CHANGE_ACTION{ + DMDP2DMSP = 0, + DMSP2DMDP = 1, + DMDP2SMSP = 2, + SMSP2DMDP = 3, + DMSP2SMSP = 4, + SMSP2DMSP = 5, + MAXACTION +}MACPHY_MODE_CHANGE_ACTION,*PMACPHY_MODE_CHANGE_ACTION; + +typedef enum _BAND_TYPE{ + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}BAND_TYPE,*PBAND_TYPE; + +typedef enum _PHY_Rate_Tx_Power_Offset_Area{ + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}RA_OFFSET_AREA,*PRA_OFFSET_AREA; + + +/* BB/RF related */ +typedef enum _RF_TYPE_8190P{ + RF_TYPE_MIN, // 0 + RF_8225=1, // 1 11b/g RF for verification only + RF_8256=2, // 2 11b/g/n + RF_8258=3, // 3 11a/b/g/n RF + RF_6052=4, // 4 11b/g/n RF + //RF_6052=5, // 4 11b/g/n RF + // TODO: We sholud remove this psudo PHY RF after we get new RF. + RF_PSEUDO_11N=5, // 5, It is a temporality RF. +}RF_TYPE_8190P_E,*PRF_TYPE_8190P_E; + +typedef struct _BB_REGISTER_DEFINITION{ + u32 rfintfs; // set software control: + // 0x870~0x877[8 bytes] + + u32 rfintfi; // readback data: + // 0x8e0~0x8e7[8 bytes] + + u32 rfintfo; // output data: + // 0x860~0x86f [16 bytes] + + u32 rfintfe; // output enable: + // 0x860~0x86f [16 bytes] + + u32 rf3wireOffset; // LSSI data: + // 0x840~0x84f [16 bytes] + + u32 rfLSSI_Select; // BB Band Select: + // 0x878~0x87f [8 bytes] + + u32 rfTxGainStage; // Tx gain stage: + // 0x80c~0x80f [4 bytes] + + u32 rfHSSIPara1; // wire parameter control1 : + // 0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes] + + u32 rfHSSIPara2; // wire parameter control2 : + // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] + + u32 rfSwitchControl; //Tx Rx antenna control : + // 0x858~0x85f [16 bytes] + + u32 rfAGCControl1; //AGC parameter control1 : + // 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] + + u32 rfAGCControl2; //AGC parameter control2 : + // 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] + + u32 rfRxIQImbalance; //OFDM Rx IQ imbalance matrix : + // 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] + + u32 rfRxAFE; //Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : + // 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes] + + u32 rfTxIQImbalance; //OFDM Tx IQ imbalance matrix + // 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes] + + u32 rfTxAFE; //Tx IQ DC Offset and Tx DFIR type + // 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] + + u32 rfLSSIReadBack; //LSSI RF readback data SI mode + // 0x8a0~0x8af [16 bytes] + + u32 rfLSSIReadBackPi; //LSSI RF readback data PI mode 0x8b8-8bc for Path A and B + +}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; + +#ifdef CONFIG_MP_INCLUDED +typedef enum _ANTENNA_PATH{ + ANTENNA_NONE = 0x00, + ANTENNA_D , + ANTENNA_C , + ANTENNA_CD , + ANTENNA_B , + ANTENNA_BD , + ANTENNA_BC , + ANTENNA_BCD , + ANTENNA_A , + ANTENNA_AD , + ANTENNA_AC , + ANTENNA_ACD , + ANTENNA_AB , + ANTENNA_ABD , + ANTENNA_ABC , + ANTENNA_ABCD +} ANTENNA_PATH; +#endif + +typedef struct _R_ANTENNA_SELECT_OFDM{ + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK{ + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + +//Added for TX Power +//u8 GetRightChnlPlace(u8 chnl); +u8 rtl8192d_GetRightChnlPlaceforIQK(u8 chnl); +u8 rtl8192d_getChnlGroupfromArray(u8 chnl); +/*--------------------------Exported Function prototype---------------------*/ +// +// BB and RF register read/write +// +void rtl8192d_PHY_SetBBReg1Byte( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 rtl8192d_PHY_QueryBBReg( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); +void rtl8192d_PHY_SetBBReg( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 rtl8192d_PHY_QueryRFReg( IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); +void rtl8192d_PHY_SetRFReg( IN PADAPTER Adapter, + IN RF_RADIO_PATH_E eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +extern int PHY_MACConfig8192D( IN PADAPTER Adapter ); +extern int PHY_BBConfig8192D( IN PADAPTER Adapter ); +extern int PHY_RFConfig8192D( IN PADAPTER Adapter ); +/* RF config */ +int rtl8192d_PHY_ConfigRFWithParaFile( IN PADAPTER Adapter, + IN u8* pFileName, + IN RF_RADIO_PATH_E eRFPath); +int rtl8192d_PHY_ConfigRFWithHeaderFile( IN PADAPTER Adapter, + IN RF_CONTENT Content, + IN RF_RADIO_PATH_E eRFPath); +/* BB/RF readback check for making sure init OK */ +int rtl8192d_PHY_CheckBBAndRFOK( IN PADAPTER Adapter, + IN HW90_BLOCK_E CheckBlock, + IN RF_RADIO_PATH_E eRFPath ); +/* Read initi reg value for tx power setting. */ +void rtl8192d_PHY_GetHWRegOriginalValue( IN PADAPTER Adapter ); + +// +// RF Power setting +// +//extern BOOLEAN PHY_SetRFPowerState(IN PADAPTER Adapter, +// IN RT_RF_POWER_STATE eRFPowerState); + +// +// BB TX Power R/W +// +void PHY_GetTxPowerLevel8192D( IN PADAPTER Adapter, + OUT u32* powerlevel ); +void PHY_SetTxPowerLevel8192D( IN PADAPTER Adapter, + IN u8 channel ); +BOOLEAN PHY_UpdateTxPowerDbm8192D( IN PADAPTER Adapter, + IN int powerInDbm ); + +// +VOID +PHY_ScanOperationBackup8192D(IN PADAPTER Adapter, + IN u8 Operation ); + +// +// Switch bandwidth for 8192S +// +//void PHY_SetBWModeCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SetBWMode8192D( IN PADAPTER pAdapter, + IN HT_CHANNEL_WIDTH ChnlWidth, + IN unsigned char Offset ); + +// +// Set FW CMD IO for 8192S. +// +//extern BOOLEAN HalSetIO8192C( IN PADAPTER Adapter, +// IN IO_TYPE IOType); + +// +// Set A2 entry to fw for 8192S +// +extern void FillA2Entry8192C( IN PADAPTER Adapter, + IN u8 index, + IN u8* val); + + +// +// channel switch related funciton +// +//extern void PHY_SwChnlCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SwChnl8192D( IN PADAPTER pAdapter, + IN u8 channel ); + // Call after initialization +void PHY_SwChnlPhy8192D( IN PADAPTER pAdapter, + IN u8 channel ); + +extern void ChkFwCmdIoDone( IN PADAPTER Adapter); + +#ifdef USE_WORKITEM +//extern void SetIOWorkItemCallback( IN PVOID pContext ); +#else +//extern void SetIOTimerCallback( IN PRT_TIMER pTimer); +#endif + +// +// BB/MAC/RF other monitor API +// +void PHY_SetMonitorMode8192D(IN PADAPTER pAdapter, + IN BOOLEAN bEnableMonitorMode ); + +BOOLEAN PHY_CheckIsLegalRfPath8192D(IN PADAPTER pAdapter, + IN u32 eRFPath ); + +// +// IQ calibrate +// +void rtl8192d_PHY_IQCalibrate( IN PADAPTER pAdapter); + + +// +// LC calibrate +// +void rtl8192d_PHY_LCCalibrate(IN PADAPTER pAdapter); + +// +// AP calibrate +// +void rtl8192d_PHY_APCalibrate(IN PADAPTER pAdapter, IN char delta); + + +// +// Modify the value of the hw register when beacon interval be changed. +// +void +rtl8192d_PHY_SetBeaconHwReg( IN PADAPTER Adapter, + IN u16 BeaconInterval ); + + +extern VOID +PHY_SwitchEphyParameter( + IN PADAPTER Adapter + ); + +extern VOID +PHY_EnableHostClkReq( + IN PADAPTER Adapter + ); + +BOOLEAN +SetAntennaConfig92C( + IN PADAPTER Adapter, + IN u8 DefaultAnt + ); + +VOID +PHY_StopTRXBeforeChangeBand8192D( + PADAPTER Adapter +); + +VOID +PHY_UpdateBBRFConfiguration8192D( + IN PADAPTER Adapter, + IN BOOLEAN bisBandSwitch +); + +VOID PHY_ReadMacPhyMode92D( + IN PADAPTER Adapter, + IN BOOLEAN AutoloadFail +); + +VOID PHY_ConfigMacPhyMode92D( + IN PADAPTER Adapter +); + +VOID PHY_ConfigMacPhyModeInfo92D( + IN PADAPTER Adapter +); + +VOID PHY_ConfigMacCoexist_RFPage92D( + IN PADAPTER Adapter +); + +VOID +rtl8192d_PHY_InitRxSetting( + IN PADAPTER Adapter +); + +VOID +rtl8192d_PHY_ResetIQKResult( + IN PADAPTER Adapter +); + + +VOID +rtl8192d_PHY_SetRFPathSwitch(IN PADAPTER pAdapter, IN BOOLEAN bMain); + +VOID +HalChangeCCKStatus8192D( + IN PADAPTER Adapter, + IN BOOLEAN bCCKDisable +); + +VOID +PHY_InitPABias92D(IN PADAPTER Adapter); + +/*--------------------------Exported Function prototype---------------------*/ + +#define PHY_SetBBReg1Byte(Adapter, RegAddr, BitMask, Data) rtl8192d_PHY_SetBBReg1Byte((Adapter), (RegAddr), (BitMask), (Data)) +#define PHY_QueryBBReg(Adapter, RegAddr, BitMask) rtl8192d_PHY_QueryBBReg((Adapter), (RegAddr), (BitMask)) +#define PHY_SetBBReg(Adapter, RegAddr, BitMask, Data) rtl8192d_PHY_SetBBReg((Adapter), (RegAddr), (BitMask), (Data)) +#define PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask) rtl8192d_PHY_QueryRFReg((Adapter), (eRFPath), (RegAddr), (BitMask)) +#define PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data) rtl8192d_PHY_SetRFReg((Adapter), (eRFPath), (RegAddr), (BitMask), (Data)) + +#define PHY_SetMacReg PHY_SetBBReg + +#endif // __INC_HAL8192SPHYCFG_H + diff --git a/rtl8192cu-fixes/include/Hal8192DPhyReg.h b/rtl8192cu-fixes/include/Hal8192DPhyReg.h new file mode 100755 index 00000000..f28aa033 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192DPhyReg.h @@ -0,0 +1,1171 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __INC_HAL8192DPHYREG_H + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __INC_HAL8192DPHYREG_H +#define __INC_HAL8192DPHYREG_H + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rPdp_AntA_8 0xb08 +#define rPdp_AntA_C 0xb0c +#define rPdp_AntA_10 0xb10 +#define rPdp_AntA_14 0xb14 +#define rPdp_AntA_18 0xb18 +#define rPdp_AntA_1C 0xb1c +#define rPdp_AntA_20 0xb20 +#define rPdp_AntA_24 0xb24 + +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rBndA 0xb30 +#define rHssiPar 0xb34 + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c + +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rPdp_AntB_8 0xb78 +#define rPdp_AntB_C 0xb7c +#define rPdp_AntB_10 0xb80 +#define rPdp_AntB_14 0xb84 +#define rPdp_AntB_18 0xb88 +#define rPdp_AntB_1C 0xb8c +#define rPdp_AntB_20 0xb90 +#define rPdp_AntB_24 0xb94 + +#define rConfig_Pmpd_AntB 0xb98 + +#define rBndB 0xba0 + +#define rAPK 0xbd8 +#define rPm_Rx0_AntA 0xbdc +#define rPm_Rx1_AntA 0xbe0 +#define rPm_Rx2_AntA 0xbe4 +#define rPm_Rx3_AntA 0xbe8 +#define rPm_Rx0_AntB 0xbec +#define rPm_Rx1_AntB 0xbf0 +#define rPm_Rx2_AntB 0xbf4 +#define rPm_Rx3_AntB 0xbf8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x42 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff +//#define bRFRegOffsetMask 0xfff + +//MAC0 will wirte PHY1 +#define MAC0_ACCESS_PHY1 0x4000 +//MAC1 will wirte PHY0 +#define MAC1_ACCESS_PHY0 0x2000 + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8192SPHYREG_H + diff --git a/rtl8192cu-fixes/include/Hal8192DUHWImg.h b/rtl8192cu-fixes/include/Hal8192DUHWImg.h new file mode 100755 index 00000000..d6c66d99 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192DUHWImg.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * 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_HAL8192DU_FW_IMG_H +#define __INC_HAL8192DU_FW_IMG_H + +#include + +/*Created on 2011/11/11, 8: 8*/ + +#define Rtl8192DUImgArrayLength 31452 +extern const u8 Rtl8192DUFwImgArray[Rtl8192DUImgArrayLength]; +#define Rtl8192DUMainArrayLength 1 +extern const u8 Rtl8192DUFwMainArray[Rtl8192DUMainArrayLength]; +#define Rtl8192DUDataArrayLength 1 +extern const u8 Rtl8192DUFwDataArray[Rtl8192DUDataArrayLength]; +#define Rtl8192DUPHY_REG_2TArrayLength 372 +extern const u32 Rtl8192DUPHY_REG_2TArray[Rtl8192DUPHY_REG_2TArrayLength]; +#define Rtl8192DUPHY_REG_1TArrayLength 1 +extern const u32 Rtl8192DUPHY_REG_1TArray[Rtl8192DUPHY_REG_1TArrayLength]; +#define Rtl8192DUPHY_REG_Array_PGLength 624 +extern const u32 Rtl8192DUPHY_REG_Array_PG[Rtl8192DUPHY_REG_Array_PGLength]; +#define Rtl8192DUPHY_REG_Array_MPLength 14 +extern const u32 Rtl8192DUPHY_REG_Array_MP[Rtl8192DUPHY_REG_Array_MPLength]; +#define Rtl8192DURadioA_2TArrayLength 378 +extern const u32 Rtl8192DURadioA_2TArray[Rtl8192DURadioA_2TArrayLength]; +#define Rtl8192DURadioB_2TArrayLength 384 +extern const u32 Rtl8192DURadioB_2TArray[Rtl8192DURadioB_2TArrayLength]; +#define Rtl8192DURadioA_1TArrayLength 1 +extern const u32 Rtl8192DURadioA_1TArray[Rtl8192DURadioA_1TArrayLength]; +#define Rtl8192DURadioB_1TArrayLength 1 +extern const u32 Rtl8192DURadioB_1TArray[Rtl8192DURadioB_1TArrayLength]; +#define Rtl8192DURadioA_2T_intPAArrayLength 378 +extern const u32 Rtl8192DURadioA_2T_intPAArray[Rtl8192DURadioA_2T_intPAArrayLength]; +#define Rtl8192DURadioB_2T_intPAArrayLength 384 +extern const u32 Rtl8192DURadioB_2T_intPAArray[Rtl8192DURadioB_2T_intPAArrayLength]; +#define Rtl8192DUMAC_2T_ArrayLength 192 +extern const u32 Rtl8192DUMAC_2T_Array[Rtl8192DUMAC_2T_ArrayLength]; +#define Rtl8192DUAGCTAB_ArrayLength 386 +extern const u32 Rtl8192DUAGCTAB_Array[Rtl8192DUAGCTAB_ArrayLength]; +#define Rtl8192DUAGCTAB_5GArrayLength 194 +extern const u32 Rtl8192DUAGCTAB_5GArray[Rtl8192DUAGCTAB_5GArrayLength]; +#define Rtl8192DUAGCTAB_2GArrayLength 194 +extern const u32 Rtl8192DUAGCTAB_2GArray[Rtl8192DUAGCTAB_2GArrayLength]; +#define Rtl8192DUAGCTAB_2TArrayLength 1 +extern const u32 Rtl8192DUAGCTAB_2TArray[Rtl8192DUAGCTAB_2TArrayLength]; +#define Rtl8192DUAGCTAB_1TArrayLength 1 +extern const u32 Rtl8192DUAGCTAB_1TArray[Rtl8192DUAGCTAB_1TArrayLength]; + +#endif //__INC_HAL8192CU_FW_IMG_H diff --git a/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h b/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h new file mode 100755 index 00000000..cc27a776 --- /dev/null +++ b/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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_HAL8192DU_FW_IMG_WOWLAN_H +#define __INC_HAL8192DU_FW_IMG_WOWLAN_H + +/*Created on 2011/11/ 8, 14:15*/ + + +#define DUWWImgArrayLength 24818 +extern u8 Rtl8192DUFwWWImgArray[DUWWImgArrayLength]; + +#endif //__INC_HAL8192DU_FW_IMG_WOWLAN_H + diff --git a/rtl8192cu-fixes/include/HalPwrSeqCmd.h b/rtl8192cu-fixes/include/HalPwrSeqCmd.h new file mode 100755 index 00000000..e5d151cf --- /dev/null +++ b/rtl8192cu-fixes/include/HalPwrSeqCmd.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * 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 __HALPWRSEQCMD_H__ +#define __HALPWRSEQCMD_H__ + +#include + +/*---------------------------------------------*/ +//3 The value of cmd: 4 bits +/*---------------------------------------------*/ +#define PWR_CMD_READ 0x00 + // offset: the read register offset + // msk: the mask of the read value + // value: N/A, left by 0 + // note: dirver shall implement this function by read & msk + +#define PWR_CMD_WRITE 0x01 + // offset: the read register offset + // msk: the mask of the write bits + // value: write value + // note: driver shall implement this cmd by read & msk after write + +#define PWR_CMD_POLLING 0x02 + // offset: the read register offset + // msk: the mask of the polled value + // value: the value to be polled, masked by the msd field. + // note: driver shall implement this cmd by + // do{ + // if( (Read(offset) & msk) == (value & msk) ) + // break; + // } while(not timeout); + +#define PWR_CMD_DELAY 0x03 + // offset: the value to delay + // msk: N/A + // value: the unit of delay, 0: us, 1: ms + +#define PWR_CMD_END 0x04 + // offset: N/A + // msk: N/A + // value: N/A + +/*---------------------------------------------*/ +//3 The value of base: 4 bits +/*---------------------------------------------*/ + // define the base address of each block +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +/*---------------------------------------------*/ +//3 The value of interface_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of fab_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of cut_msk: 8 bits +/*---------------------------------------------*/ +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + + +typedef enum _PWRSEQ_CMD_DELAY_UNIT_ +{ + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +} PWRSEQ_DELAY_UNIT; + +typedef struct _WL_PWR_CFG_ +{ + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +} WLAN_PWR_CFG, *PWLAN_PWR_CFG; + + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk +#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base +#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd +#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk +#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value + + +//================================================================================ +// Prototype of protected function. +//================================================================================ +u8 HalPwrSeqCmdParsing( + PADAPTER padapter, + u8 CutVersion, + u8 FabVersion, + u8 InterfaceType, + WLAN_PWR_CFG PwrCfgCmd[]); + +#endif diff --git a/rtl8192cu-fixes/include/autoconf.h b/rtl8192cu-fixes/include/autoconf.h new file mode 100755 index 00000000..f62231bd --- /dev/null +++ b/rtl8192cu-fixes/include/autoconf.h @@ -0,0 +1,336 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + +/* + * Public General Config + */ +#define AUTOCONF_INCLUDED +#define RTL871X_MODULE_NAME "92CU" +#define DRV_NAME "rtl8192cu" + +#define CONFIG_USB_HCI 1 + +#define CONFIG_RTL8192C 1 + +#define PLATFORM_LINUX 1 + +//#define CONFIG_IOCTL_CFG80211 1 +#ifdef CONFIG_IOCTL_CFG80211 + //#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 1 + //#define CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 + #define CONFIG_SET_SCAN_DENY_TIMER +#endif + +/* + * Internal General Config + */ +//#define CONFIG_PWRCTRL +//#define CONFIG_H2CLBK + +#define CONFIG_EMBEDDED_FWIMG 1 +//#define CONFIG_FILE_FWIMG + +#ifdef CONFIG_WAKE_ON_WLAN +#define CONFIG_WOWLAN 1 +#endif //CONFIG_WAKE_ON_WLAN + +#define CONFIG_R871X_TEST 1 + +#define CONFIG_XMIT_ACK +#ifdef CONFIG_XMIT_ACK + #define CONFIG_XMIT_ACK_POLLING + #define CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#endif + +#define CONFIG_80211N_HT 1 + +#define CONFIG_RECV_REORDERING_CTRL 1 + +//#define CONFIG_TCP_CSUM_OFFLOAD_RX 1 + +//#define CONFIG_BEFORE_LINKED_DIG +//#define CONFIG_DRVEXT_MODULE 1 + +#ifndef CONFIG_MP_INCLUDED + #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 + #define CONFIG_BT_COEXIST 1 + + //befor link + #define CONFIG_ANTENNA_DIVERSITY + + //after link + #ifdef CONFIG_ANTENNA_DIVERSITY + #define CONFIG_SW_ANTENNA_DIVERSITY + //#define CONFIG_HW_ANTENNA_DIVERSITY + #endif + + #define CONFIG_IOL +#else //#ifndef CONFIG_MP_INCLUDED + #define CONFIG_MP_IWPRIV_SUPPORT 1 +#endif //#ifndef CONFIG_MP_INCLUDED + +#define CONFIG_AP_MODE 1 +#ifdef CONFIG_AP_MODE + #define CONFIG_NATIVEAP_MLME 1 + #ifndef CONFIG_NATIVEAP_MLME + #define CONFIG_HOSTAPD_MLME 1 + #endif + #define CONFIG_FIND_BEST_CHANNEL 1 + //#define CONFIG_NO_WIRELESS_HANDLERS 1 +#endif + +// Added by Albert 20110314 +#define CONFIG_P2P 1 +#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 P2P_OP_CHECK_SOCIAL_CH + // Added comment by Borg 2013/06/21 + // Issue: Nexus 4 is hard to do miracast. + // Root Cause: After group formation, + // Nexus 4 is possible to be not at OP channel of Invitation Resp/Nego Confirm but at social channel. + // Patch: While scan OP channel, + // not only scan OP channel of Invitation Resp/Nego Confirm, + // but also scan social channel(1, 6, 11) +#endif + +// Added by Kurt 20110511 +//#define CONFIG_TDLS 1 +#ifdef CONFIG_TDLS +// #ifndef CONFIG_WFD +// #define CONFIG_WFD 1 +// #endif +// #define CONFIG_TDLS_AUTOSETUP 1 +// #define CONFIG_TDLS_AUTOCHECKALIVE 1 +#endif + +#define CONFIG_SKB_COPY 1//for amsdu + +#define CONFIG_LED +#ifdef CONFIG_LED + #define CONFIG_SW_LED + #ifdef CONFIG_SW_LED + //#define CONFIG_LED_HANDLED_BY_CMD_THREAD + #endif +#endif // CONFIG_LED + + + +#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 +#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable */ +#define CONFIG_DEAUTH_BEFORE_CONNECT + +#ifdef CONFIG_IOL + #define CONFIG_IOL_LLT + #define CONFIG_IOL_MAC + #define CONFIG_IOL_BB_PHY_REG + #define CONFIG_IOL_BB_AGC_TAB + #define CONFIG_IOL_RF_RF90_PATH_A + #define CONFIG_IOL_RF_RF90_PATH_B +#endif + +#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 + +#define CONFIG_TX_MCAST2UNI 1 // Support IP multicast->unicast +//#define CONFIG_DM_ADAPTIVITY +//#define CONFIG_CHECK_AC_LIFETIME 1 // Check packet lifetime of 4 ACs. + +//#define CONFIG_CONCURRENT_MODE 1 +#ifdef CONFIG_CONCURRENT_MODE + #define CONFIG_TSF_RESET_OFFLOAD 1 // For 2 PORT TSF SYNC. + //#define CONFIG_HWPORT_SWAP //Port0->Sec , Port1 -> Pri + //#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_80211D + +/* + * Interface Related Config + */ + +//#define CONFIG_USB_ONE_OUT_EP +//#define CONFIG_USB_INTERRUPT_IN_PIPE 1 + +#ifndef CONFIG_MINIMAL_MEMORY_USAGE + #define CONFIG_USB_TX_AGGREGATION 1 + #define CONFIG_USB_RX_AGGREGATION 1 +#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 + +/* + * 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 +#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 + + +/* + * HAL Related Config + */ + +#define RTL8192C_RX_PACKET_NO_INCLUDE_CRC 1 + +#define SUPPORTED_BLOCK_IO + + + +#define RTL8192CU_FW_DOWNLOAD_ENABLE 1 + +#define CONFIG_ONLY_ONE_OUT_EP_TO_LOW 0 + +#define CONFIG_OUT_EP_WIFI_MODE 0 + +#define ENABLE_USB_DROP_INCORRECT_OUT 0 + +#define RTL8192CU_ASIC_VERIFICATION 0 // For ASIC verification. + +#define RTL8192CU_ADHOC_WORKAROUND_SETTING 1 + +#define DISABLE_BB_RF 0 + +#define RTL8191C_FPGA_NETWORKTYPE_ADHOC 0 + +#ifdef CONFIG_MP_INCLUDED + #define MP_DRIVER 1 + #undef CONFIG_USB_TX_AGGREGATION + #undef CONFIG_USB_RX_AGGREGATION +#else + #define MP_DRIVER 0 +#endif + + +/* + * Platform Related Config + */ +#ifdef CONFIG_PLATFORM_MN10300 +#define CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + +#if defined (CONFIG_SW_ANTENNA_DIVERSITY) + #undef CONFIG_SW_ANTENNA_DIVERSITY + #define CONFIG_HW_ANTENNA_DIVERSITY +#endif + +#endif + +#ifdef CONFIG_WISTRON_PLATFORM + +#endif + +#ifdef CONFIG_PLATFORM_TI_DM365 +#define CONFIG_USE_USB_BUFFER_ALLOC_RX 1 +#endif + +#define CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR + +/* + * Debug Related Config + */ +//#define CONFIG_DEBUG_RTL871X + +#define DBG 0 +//#define CONFIG_DEBUG_RTL819X + +//#define CONFIG_PROC_DEBUG 1 + +//#define DBG_IO +//#define DBG_DELAY_OS +//#define DBG_MEM_ALLOC +//#define DBG_IOCTL + +//#define DBG_TX +//#define DBG_XMIT_BUF +//#define DBG_TX_DROP_FRAME + +//#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_EXPIRATION_CHK + + +//#define DBG_SHOW_MCUFWDL_BEFORE_51_ENABLE +//#define DBG_ROAMING_TEST + +//#define DBG_HAL_INIT_PROFILING + +//#define DBG_MEMORY_LEAK 1 + +#define DBG_CONFIG_ERROR_DETECT +//#define DBG_CONFIG_ERROR_RESET + +//TX use 1 urb +//#define CONFIG_SINGLE_XMIT_BUF +//RX use 1 urb +//#define CONFIG_SINGLE_RECV_BUF + +//turn off power tracking when traffic is busy +//#define CONFIG_BUSY_TRAFFIC_SKIP_PWR_TRACK diff --git a/rtl8192cu-fixes/include/basic_types.h b/rtl8192cu-fixes/include/basic_types.h new file mode 100755 index 00000000..f76e68ff --- /dev/null +++ b/rtl8192cu-fixes/include/basic_types.h @@ -0,0 +1,321 @@ +/****************************************************************************** + * + * 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 __BASIC_TYPES_H__ +#define __BASIC_TYPES_H__ + +#include + + +#define SUCCESS 0 +#define FAIL (-1) + +#ifndef TRUE + #define _TRUE 1 +#else + #define _TRUE TRUE +#endif + +#ifndef FALSE + #define _FALSE 0 +#else + #define _FALSE FALSE +#endif + +#ifdef PLATFORM_WINDOWS + + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed long s32; + typedef unsigned long u32; + + typedef unsigned int uint; + typedef signed int sint; + + + typedef signed long long s64; + typedef unsigned long long u64; + + #ifdef NDIS50_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 0 + + #endif + + #ifdef NDIS51_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 1 + + #endif + + typedef NDIS_PROC proc_t; + + typedef LONG atomic_t; + +#endif + + +#ifdef PLATFORM_LINUX + + #include + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + typedef signed int sint; + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + + #define UCHAR u8 + #define USHORT u16 + #define UINT u32 + #define ULONG u32 + + typedef void (*proc_t)(void*); + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + + +#ifdef PLATFORM_FREEBSD + + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed int s32; + typedef unsigned int u32; + + typedef unsigned int uint; + typedef signed int sint; + typedef long atomic_t; + + typedef signed long long s64; + typedef unsigned long long u64; + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + typedef u32 dma_addr_t; + #define UCHAR u8 + #define USHORT u16 + #define UINT u32 + #define ULONG u32 + + typedef void (*proc_t)(void*); + + typedef unsigned int __kernel_size_t; + typedef int __kernel_ssize_t; + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + +#define MEM_ALIGNMENT_OFFSET (sizeof (SIZE_T)) +#define MEM_ALIGNMENT_PADDING (sizeof(SIZE_T) - 1) + +#define SIZE_PTR SIZE_T +#define SSIZE_PTR SSIZE_T + +//port from fw by thomas +// TODO: Belows are Sync from SD7-Driver. It is necessary to check correctness + +/* + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. +*/ + +// +// Byte Swapping routine. +// +#define EF1Byte +#define EF2Byte le16_to_cpu +#define EF4Byte le32_to_cpu + +// +// Read LE format data from memory +// +#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr))) +#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr))) +#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr))) + +// +// Write LE data to memory +// +#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr)))=EF1Byte(_val) +#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr)))=EF2Byte(_val) +#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr)))=EF4Byte(_val) + +// +// Example: +// BIT_LEN_MASK_32(0) => 0x00000000 +// BIT_LEN_MASK_32(1) => 0x00000001 +// BIT_LEN_MASK_32(2) => 0x00000003 +// BIT_LEN_MASK_32(32) => 0xFFFFFFFF +// +#define BIT_LEN_MASK_32(__BitLen) \ + (0xFFFFFFFF >> (32 - (__BitLen))) +// +// Example: +// BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +// BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 +// +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) + +// +// Description: +// Return 4-byte value in host byte ordering from +// 4-byte pointer in litten-endian system. +// +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + (EF4Byte(*((u32 *)(__pStart)))) + +// +// Description: +// Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to +// 4-byte value in host byte ordering. +// +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_32(__BitLen) \ + ) + +// +// Description: +// Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering +// and return the result in 4-byte value in host byte ordering. +// +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \ + ) + +// +// Description: +// Set subfield of little-endian 4-byte value to specified value. +// +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u32 *)(__pStart)) = \ + EF4Byte( \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \ + ); + + +#define BIT_LEN_MASK_16(__BitLen) \ + (0xFFFF >> (16 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_16(__BitLen) << (__BitOffset)) + +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + (EF2Byte(*((u16 *)(__pStart)))) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_16(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u16 *)(__pStart)) = \ + EF2Byte( \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \ + ); + +#define BIT_LEN_MASK_8(__BitLen) \ + (0xFF >> (8 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_8(__BitLen) << (__BitOffset)) + +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + (EF1Byte(*((u8 *)(__pStart)))) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_8(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u8 *)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \ + ); + +// Get the N-bytes aligment offset from the current length +#define N_BYTE_ALIGMENT(__Value, __Aligment) ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / __Aligment) * __Aligment)) + +typedef unsigned char BOOLEAN,*PBOOLEAN; + +#endif //__BASIC_TYPES_H__ + diff --git a/rtl8192cu-fixes/include/byteorder/big_endian.h b/rtl8192cu-fixes/include/byteorder/big_endian.h new file mode 100755 index 00000000..eca68a65 --- /dev/null +++ b/rtl8192cu-fixes/include/byteorder/big_endian.h @@ -0,0 +1,87 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_BIG_ENDIAN_H +#define _LINUX_BYTEORDER_BIG_ENDIAN_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#include + +#define __constant_htonl(x) ((__u32)(x)) +#define __constant_ntohl(x) ((__u32)(x)) +#define __constant_htons(x) ((__u16)(x)) +#define __constant_ntohs(x) ((__u16)(x)) +#define __constant_cpu_to_le64(x) ___constant_swab64((x)) +#define __constant_le64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_le32(x) ___constant_swab32((x)) +#define __constant_le32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_le16(x) ___constant_swab16((x)) +#define __constant_le16_to_cpu(x) ___constant_swab16((x)) +#define __constant_cpu_to_be64(x) ((__u64)(x)) +#define __constant_be64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_be32(x) ((__u32)(x)) +#define __constant_be32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_be16(x) ((__u16)(x)) +#define __constant_be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64(x) __swab64((x)) +#define __le64_to_cpu(x) __swab64((x)) +#define __cpu_to_le32(x) __swab32((x)) +#define __le32_to_cpu(x) __swab32((x)) +#define __cpu_to_le16(x) __swab16((x)) +#define __le16_to_cpu(x) __swab16((x)) +#define __cpu_to_be64(x) ((__u64)(x)) +#define __be64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_be32(x) ((__u32)(x)) +#define __be32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_be16(x) ((__u16)(x)) +#define __be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64p(x) __swab64p((x)) +#define __le64_to_cpup(x) __swab64p((x)) +#define __cpu_to_le32p(x) __swab32p((x)) +#define __le32_to_cpup(x) __swab32p((x)) +#define __cpu_to_le16p(x) __swab16p((x)) +#define __le16_to_cpup(x) __swab16p((x)) +#define __cpu_to_be64p(x) (*(__u64*)(x)) +#define __be64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_be32p(x) (*(__u32*)(x)) +#define __be32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_be16p(x) (*(__u16*)(x)) +#define __be16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_le64s(x) __swab64s((x)) +#define __le64_to_cpus(x) __swab64s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) +#define __le32_to_cpus(x) __swab32s((x)) +#define __cpu_to_le16s(x) __swab16s((x)) +#define __le16_to_cpus(x) __swab16s((x)) +#define __cpu_to_be64s(x) do {} while (0) +#define __be64_to_cpus(x) do {} while (0) +#define __cpu_to_be32s(x) do {} while (0) +#define __be32_to_cpus(x) do {} while (0) +#define __cpu_to_be16s(x) do {} while (0) +#define __be16_to_cpus(x) do {} while (0) + +#include + +#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */ diff --git a/rtl8192cu-fixes/include/byteorder/generic.h b/rtl8192cu-fixes/include/byteorder/generic.h new file mode 100755 index 00000000..7c8d4d70 --- /dev/null +++ b/rtl8192cu-fixes/include/byteorder/generic.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_GENERIC_H +#define _LINUX_BYTEORDER_GENERIC_H + +/* + * linux/byteorder_generic.h + * Generic Byte-reordering support + * + * Francois-Rene Rideau 19970707 + * gathered all the good ideas from all asm-foo/byteorder.h into one file, + * cleaned them up. + * I hope it is compliant with non-GCC compilers. + * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, + * because I wasn't sure it would be ok to put it in types.h + * Upgraded it to 2.1.43 + * Francois-Rene Rideau 19971012 + * Upgraded it to 2.1.57 + * to please Linus T., replaced huge #ifdef's between little/big endian + * by nestedly #include'd files. + * Francois-Rene Rideau 19971205 + * Made it to 2.1.71; now a facelift: + * Put files under include/linux/byteorder/ + * Split swab from generic support. + * + * TODO: + * = Regular kernel maintainers could also replace all these manual + * byteswap macros that remain, disseminated among drivers, + * after some grep or the sources... + * = Linus might want to rename all these macros and files to fit his taste, + * to fit his personal naming scheme. + * = it seems that a few drivers would also appreciate + * nybble swapping support... + * = every architecture could add their byteswap macro in asm/byteorder.h + * see how some architectures already do (i386, alpha, ppc, etc) + * = cpu_to_beXX and beXX_to_cpu might some day need to be well + * distinguished throughout the kernel. This is not the case currently, + * since little endian, big endian, and pdp endian machines needn't it. + * But this might be the case for, say, a port of Linux to 20/21 bit + * architectures (and F21 Linux addict around?). + */ + +/* + * The following macros are to be defined by : + * + * Conversion of long and short int between network and host format + * ntohl(__u32 x) + * ntohs(__u16 x) + * htonl(__u32 x) + * htons(__u16 x) + * It seems that some programs (which? where? or perhaps a standard? POSIX?) + * might like the above to be functions, not macros (why?). + * if that's true, then detect them, and take measures. + * Anyway, the measure is: define only ___ntohl as a macro instead, + * and in a separate file, have + * unsigned long inline ntohl(x){return ___ntohl(x);} + * + * The same for constant arguments + * __constant_ntohl(__u32 x) + * __constant_ntohs(__u16 x) + * __constant_htonl(__u32 x) + * __constant_htons(__u16 x) + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + * + */ + + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) || defined(PLATFORM_MPIXEL) || defined(PLATFORM_FREEBSD) +/* + * inside the kernel, we can use nicknames; + * outside of it, we must avoid POSIX namespace pollution... + */ +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus +#endif + + +/* + * Handle ntohl and suches. These have various compatibility + * issues - like we want to give the prototype even though we + * also have a macro for them in case some strange program + * wants to take the address of the thing or something.. + * + * Note that these used to return a "long" in libc5, even though + * long is often 64-bit these days.. Thus the casts. + * + * They have to be macros in order to do the constant folding + * correctly - if the argument passed into a inline function + * it is no longer constant according to gcc.. + */ + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +/* + * Do the prototypes. Somebody might want to take the + * address or some such sick thing.. + */ +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +extern __u32 ntohl(__u32); +extern __u32 htonl(__u32); +#else //defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#ifndef PLATFORM_FREEBSD +extern unsigned long int ntohl(unsigned long int); +extern unsigned long int htonl(unsigned long int); +#endif +#endif +#ifndef PLATFORM_FREEBSD +extern unsigned short int ntohs(unsigned short int); +extern unsigned short int htons(unsigned short int); +#endif + +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) || defined(PLATFORM_MPIXEL) + +#define ___htonl(x) __cpu_to_be32(x) +#define ___htons(x) __cpu_to_be16(x) +#define ___ntohl(x) __be32_to_cpu(x) +#define ___ntohs(x) __be16_to_cpu(x) + +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#else +#define htonl(x) ((unsigned long)___htonl(x)) +#define ntohl(x) ((unsigned long)___ntohl(x)) +#endif +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#endif /* OPTIMIZE */ + + +#if defined (PLATFORM_WINDOWS) + +#define htonl(x) __cpu_to_be32(x) +#define ntohl(x) __be32_to_cpu(x) +#define htons(x) __cpu_to_be16(x) +#define ntohs(x) __be16_to_cpu(x) + + +#endif + +#endif /* _LINUX_BYTEORDER_GENERIC_H */ diff --git a/rtl8192cu-fixes/include/byteorder/little_endian.h b/rtl8192cu-fixes/include/byteorder/little_endian.h new file mode 100755 index 00000000..433045e4 --- /dev/null +++ b/rtl8192cu-fixes/include/byteorder/little_endian.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 _LINUX_BYTEORDER_LITTLE_ENDIAN_H +#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +#include + +#ifndef __constant_htonl +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) +#define __constant_cpu_to_le64(x) ((__u64)(x)) +#define __constant_le64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_le32(x) ((__u32)(x)) +#define __constant_le32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le16(x) ((__u16)(x)) +#define __constant_le16_to_cpu(x) ((__u16)(x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) +#define __cpu_to_le64(x) ((__u64)(x)) +#define __le64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_le32(x) ((__u32)(x)) +#define __le32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le16(x) ((__u16)(x)) +#define __le16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_be64(x) __swab64((x)) +#define __be64_to_cpu(x) __swab64((x)) +#define __cpu_to_be32(x) __swab32((x)) +#define __be32_to_cpu(x) __swab32((x)) +#define __cpu_to_be16(x) __swab16((x)) +#define __be16_to_cpu(x) __swab16((x)) +#define __cpu_to_le64p(x) (*(__u64*)(x)) +#define __le64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_le32p(x) (*(__u32*)(x)) +#define __le32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le16p(x) (*(__u16*)(x)) +#define __le16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_be64p(x) __swab64p((x)) +#define __be64_to_cpup(x) __swab64p((x)) +#define __cpu_to_be32p(x) __swab32p((x)) +#define __be32_to_cpup(x) __swab32p((x)) +#define __cpu_to_be16p(x) __swab16p((x)) +#define __be16_to_cpup(x) __swab16p((x)) +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) +#endif // __constant_htonl + +#include + +#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ diff --git a/rtl8192cu-fixes/include/byteorder/swab.h b/rtl8192cu-fixes/include/byteorder/swab.h new file mode 100755 index 00000000..a3ca9eae --- /dev/null +++ b/rtl8192cu-fixes/include/byteorder/swab.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_SWAB_H +#define _LINUX_BYTEORDER_SWAB_H + +#if !defined(CONFIG_PLATFORM_MSTAR) +#ifndef __u16 +typedef unsigned short __u16; +#endif + +#ifndef __u32 +typedef unsigned int __u32; +#endif + +#ifndef __u8 +typedef unsigned char __u8; +#endif + +#ifndef __u64 +typedef unsigned long long __u64; +#endif + + +__inline static __u16 ___swab16(__u16 x) +{ + __u16 __x = x; + return + ((__u16)( + (((__u16)(__x) & (__u16)0x00ffU) << 8) | + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); + +} + +__inline static __u32 ___swab32(__u32 x) +{ + __u32 __x = (x); + return ((__u32)( + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); +} + +__inline static __u64 ___swab64(__u64 x) +{ + __u64 __x = (x); + + return + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +} +#endif // CONFIG_PLATFORM_MSTAR + +#ifndef __arch__swab16 +__inline static __u16 __arch__swab16(__u16 x) +{ + return ___swab16(x); +} + +#endif + +#ifndef __arch__swab32 +__inline static __u32 __arch__swab32(__u32 x) +{ + __u32 __tmp = (x) ; + return ___swab32(__tmp); +} +#endif + +#ifndef __arch__swab64 + +__inline static __u64 __arch__swab64(__u64 x) +{ + __u64 __tmp = (x) ; + return ___swab64(__tmp); +} + + +#endif + +#ifndef __swab16 +#define __swab16(x) __fswab16(x) +#define __swab32(x) __fswab32(x) +#define __swab64(x) __fswab64(x) +#endif // __swab16 + +#ifdef PLATFORM_FREEBSD +__inline static __u16 __fswab16(__u16 x) +#else +__inline static const __u16 __fswab16(__u16 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab16(x); +} +#ifdef PLATFORM_FREEBSD +__inline static __u32 __fswab32(__u32 x) +#else +__inline static const __u32 __fswab32(__u32 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab32(x); +} + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) +#define swab16 __swab16 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab32s __swab32s +#define swab64s __swab64s +#endif + +#endif /* _LINUX_BYTEORDER_SWAB_H */ diff --git a/rtl8192cu-fixes/include/byteorder/swabb.h b/rtl8192cu-fixes/include/byteorder/swabb.h new file mode 100755 index 00000000..7e2a118c --- /dev/null +++ b/rtl8192cu-fixes/include/byteorder/swabb.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_SWABB_H +#define _LINUX_BYTEORDER_SWABB_H + +/* + * linux/byteorder/swabb.h + * SWAp Bytes Bizarrely + * swaHHXX[ps]?(foo) + * + * Support for obNUXIous pdp-endian and other bizarre architectures. + * Will Linux ever run on such ancient beasts? if not, this file + * will be but a programming pearl. Still, it's a reminder that we + * shouldn't be making too many assumptions when trying to be portable. + * + */ + +/* + * Meaning of the names I chose (vaxlinux people feel free to correct them): + * swahw32 swap 16-bit half-words in a 32-bit word + * swahb32 swap 8-bit halves of each 16-bit half-word in a 32-bit word + * + * No 64-bit support yet. I don't know NUXI conventions for long longs. + * I guarantee it will be a mess when it's there, though :-> + * It will be even worse if there are conflicting 64-bit conventions. + * Hopefully, no one ever used 64-bit objects on NUXI machines. + * + */ + +#define ___swahw32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x0000ffffUL) << 16) | \ + (((__u32)(__x) & (__u32)0xffff0000UL) >> 16) )); \ +}) +#define ___swahb32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x00ff00ffUL) << 8) | \ + (((__u32)(__x) & (__u32)0xff00ff00UL) >> 8) )); \ +}) + +#define ___constant_swahw32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \ + (((__u32)(x) & (__u32)0xffff0000UL) >> 16) )) +#define ___constant_swahb32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \ + (((__u32)(x) & (__u32)0xff00ff00UL) >> 8) )) + +/* + * provide defaults when no architecture-specific optimization is detected + */ +#ifndef __arch__swahw32 +# define __arch__swahw32(x) ___swahw32(x) +#endif +#ifndef __arch__swahb32 +# define __arch__swahb32(x) ___swahb32(x) +#endif + +#ifndef __arch__swahw32p +# define __arch__swahw32p(x) __swahw32(*(x)) +#endif +#ifndef __arch__swahb32p +# define __arch__swahb32p(x) __swahb32(*(x)) +#endif + +#ifndef __arch__swahw32s +# define __arch__swahw32s(x) do { *(x) = __swahw32p((x)); } while (0) +#endif +#ifndef __arch__swahb32s +# define __arch__swahb32s(x) do { *(x) = __swahb32p((x)); } while (0) +#endif + + +/* + * Allow constant folding + */ +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) +# define __swahw32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swahw32((x)) : \ + __fswahw32((x))) +# define __swahb32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swahb32((x)) : \ + __fswahb32((x))) +#else +# define __swahw32(x) __fswahw32(x) +# define __swahb32(x) __fswahb32(x) +#endif /* OPTIMIZE */ + + +__inline static__ __const__ __u32 __fswahw32(__u32 x) +{ + return __arch__swahw32(x); +} +__inline static__ __u32 __swahw32p(__u32 *x) +{ + return __arch__swahw32p(x); +} +__inline static__ void __swahw32s(__u32 *addr) +{ + __arch__swahw32s(addr); +} + + +__inline static__ __const__ __u32 __fswahb32(__u32 x) +{ + return __arch__swahb32(x); +} +__inline static__ __u32 __swahb32p(__u32 *x) +{ + return __arch__swahb32p(x); +} +__inline static__ void __swahb32s(__u32 *addr) +{ + __arch__swahb32s(addr); +} + +#ifdef __BYTEORDER_HAS_U64__ +/* + * Not supported yet + */ +#endif /* __BYTEORDER_HAS_U64__ */ + +#if defined(PLATFORM_LINUX) +#define swahw32 __swahw32 +#define swahb32 __swahb32 +#define swahw32p __swahw32p +#define swahb32p __swahb32p +#define swahw32s __swahw32s +#define swahb32s __swahb32s +#endif + +#endif /* _LINUX_BYTEORDER_SWABB_H */ diff --git a/rtl8192cu-fixes/include/circ_buf.h b/rtl8192cu-fixes/include/circ_buf.h new file mode 100755 index 00000000..1bd4704a --- /dev/null +++ b/rtl8192cu-fixes/include/circ_buf.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * + * 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 __CIRC_BUF_H_ +#define __CIRC_BUF_H_ 1 + +#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1)) + +#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size)) + +#endif //_CIRC_BUF_H_ diff --git a/rtl8192cu-fixes/include/cmd_osdep.h b/rtl8192cu-fixes/include/cmd_osdep.h new file mode 100755 index 00000000..077efa73 --- /dev/null +++ b/rtl8192cu-fixes/include/cmd_osdep.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * 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 __CMD_OSDEP_H_ +#define __CMD_OSDEP_H_ + + +#include +#include +#include + +extern sint _rtw_init_cmd_priv (struct cmd_priv *pcmdpriv); +extern sint _rtw_init_evt_priv(struct evt_priv *pevtpriv); +extern void _rtw_free_evt_priv (struct evt_priv *pevtpriv); +extern void _rtw_free_cmd_priv (struct cmd_priv *pcmdpriv); +extern sint _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj); +extern struct cmd_obj *_rtw_dequeue_cmd(_queue *queue); + +#endif + diff --git a/rtl8192cu-fixes/include/drv_conf.h b/rtl8192cu-fixes/include/drv_conf.h new file mode 100755 index 00000000..13176879 --- /dev/null +++ b/rtl8192cu-fixes/include/drv_conf.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * + * 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 __DRV_CONF_H__ +#define __DRV_CONF_H__ +#include "autoconf.h" + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +//Older Android kernel doesn't has CONFIG_ANDROID defined, +//add this to force CONFIG_ANDROID defined +#ifdef CONFIG_PLATFORM_ANDROID +#define CONFIG_ANDROID +#endif + +#ifdef CONFIG_ANDROID +//Some Android build will restart the UI while non-printable ascii is passed +//between java and c/c++ layer (JNI). We force CONFIG_VALIDATE_SSID +//for Android here. If you are sure there is no risk on your system about this, +//mask this macro define to support non-printable ascii ssid. +//#define CONFIG_VALIDATE_SSID + +//Android expect dbm as the rx signal strength unit +#define CONFIG_SIGNAL_DISPLAY_DBM +#endif + +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_HAS_EARLYSUSPEND enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif + +#if defined(CONFIG_ANDROID_POWER) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_ANDROID_POWER enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif + +#ifdef CONFIG_RESUME_IN_WORKQUEUE //this can be removed, because there is no case for this... + #if !defined( CONFIG_WAKELOCK) && !defined(CONFIG_ANDROID_POWER) + #error "enable CONFIG_RESUME_IN_WORKQUEUE without CONFIG_WAKELOCK or CONFIG_ANDROID_POWER will suffer from the danger of wifi's unfunctionality..." + #error "If you still want to enable CONFIG_RESUME_IN_WORKQUEUE in this case, mask this preprossor checking and GOOD LUCK..." + #endif +#endif + +//About USB VENDOR REQ +#if defined(CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif +#if defined(CONFIG_VENDOR_REQ_RETRY) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_VENDOR_REQ_RETRY automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif + + +//#include + +#endif // __DRV_CONF_H__ + diff --git a/rtl8192cu-fixes/include/drv_types.h b/rtl8192cu-fixes/include/drv_types.h new file mode 100755 index 00000000..0ac34f21 --- /dev/null +++ b/rtl8192cu-fixes/include/drv_types.h @@ -0,0 +1,662 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/*------------------------------------------------------------------------------- + + For type defines and data structure defines + +--------------------------------------------------------------------------------*/ + + +#ifndef __DRV_TYPES_H__ +#define __DRV_TYPES_H__ + +#include +#include +#include + + +#ifdef PLATFORM_OS_XP +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#ifdef PLATFORM_LINUX +#include +#endif + +enum _NIC_VERSION { + + RTL8711_NIC, + RTL8712_NIC, + RTL8713_NIC, + RTL8716_NIC + +}; + +enum{ + UP_LINK, + DOWN_LINK, +}; +typedef struct _ADAPTER _adapter, ADAPTER,*PADAPTER; + +#ifdef CONFIG_80211N_HT +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_DRVEXT_MODULE +#include +#endif + +#ifdef CONFIG_MP_INCLUDED +#include +#endif + +#ifdef CONFIG_BR_EXT +#include +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_IOCTL_CFG80211 + #include "ioctl_cfg80211.h" +#endif //CONFIG_IOCTL_CFG80211 + +#define SPEC_DEV_ID_NONE BIT(0) +#define SPEC_DEV_ID_DISABLE_HT BIT(1) +#define SPEC_DEV_ID_ENABLE_PS BIT(2) +#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3) +#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4) +#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5) + +struct specific_device_id{ + + u32 flags; + + u16 idVendor; + u16 idProduct; + +}; + +struct registry_priv +{ + u8 chip_version; + u8 rfintfs; + u8 lbkmode; + u8 hci; + NDIS_802_11_SSID ssid; + u8 network_mode; //infra, ad-hoc, auto + u8 channel;//ad-hoc support requirement + u8 wireless_mode;//A, B, G, auto + u8 scan_mode;//active, passive + u8 radio_enable; + u8 preamble;//long, short, auto + u8 vrtl_carrier_sense;//Enable, Disable, Auto + u8 vcs_type;//RTS/CTS, CTS-to-self + u16 rts_thresh; + u16 frag_thresh; + u8 adhoc_tx_pwr; + u8 soft_ap; + u8 power_mgnt; + u8 ips_mode; + u8 smart_ps; + u8 long_retry_lmt; + u8 short_retry_lmt; + u16 busy_thresh; + u8 ack_policy; + u8 mp_mode; + u8 software_encrypt; + u8 software_decrypt; + + u8 acm_method; + //UAPSD + u8 wmm_enable; + u8 uapsd_enable; + u8 uapsd_max_sp; + u8 uapsd_acbk_en; + u8 uapsd_acbe_en; + u8 uapsd_acvi_en; + u8 uapsd_acvo_en; + + WLAN_BSSID_EX dev_network; + +#ifdef CONFIG_80211N_HT + u8 ht_enable; + u8 cbw40_enable; + u8 ampdu_enable;//for tx + u8 rx_stbc; + u8 ampdu_amsdu;//A-MPDU Supports A-MSDU is permitted +#endif + u8 lowrate_two_xmit; + + u8 rf_config ; + u8 low_power ; + + u8 wifi_spec;// !turbo_mode + + u8 channel_plan; +#ifdef CONFIG_BT_COEXIST + u8 bt_iso; + u8 bt_sco; + u8 bt_ampdu; +#endif + BOOLEAN bAcceptAddbaReq; + + u8 antdiv_cfg; + + u8 usbss_enable;//0:disable,1:enable + u8 hwpdn_mode;//0:disable,1:enable,2:decide by EFUSE config + u8 hwpwrp_detect;//0:disable,1:enable + + u8 hw_wps_pbc;//0:disable,1:enable + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + char adaptor_info_caching_file_path[PATH_LENGTH_MAX]; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + u8 max_roaming_times; // the max number driver will try to roaming +#endif + +#ifdef CONFIG_IOL + bool force_iol; //enable iol without other concern +#endif + u8 special_rf_path; //0: 2T2R ,1: only turn on path A 1T1R, 2: only turn on path B 1T1R + u8 mac_phy_mode; //0:by efuse, 1:smsp, 2:dmdp, 3:dmsp. + +#ifdef CONFIG_80211D + u8 enable80211d; +#endif + + u8 ifname[16]; + u8 if2name[16]; + + u8 notch_filter; + +#ifdef CONFIG_MULTI_VIR_IFACES + u8 ext_iface_num;//primary/secondary iface is excluded +#endif +}; + + +//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 BSSID_OFT(field) ((ULONG)FIELD_OFFSET(WLAN_BSSID_EX,field)) +#define BSSID_SZ(field) sizeof(((PWLAN_BSSID_EX) 0)->field) + +#define MAX_CONTINUAL_URB_ERR 4 + +#ifdef CONFIG_SDIO_HCI +#include +#define INTF_DATA SDIO_DATA +#endif + +#define GET_PRIMARY_ADAPTER(padapter) (((_adapter *)padapter)->dvobj->if1) + +#define GET_IFACE_NUMS(padapter) (((_adapter *)padapter)->dvobj->iface_nums) +#define GET_ADAPTER(padapter, iface_id) (((_adapter *)padapter)->dvobj->padapters[iface_id]) + +enum _IFACE_ID { + IFACE_ID0, //maping to PRIMARY_ADAPTER + IFACE_ID1, //maping to SECONDARY_ADAPTER + IFACE_ID2, + IFACE_ID3, + IFACE_ID_MAX, +}; + +struct dvobj_priv +{ + _adapter *if1; //PRIMARY_ADAPTER + _adapter *if2; //SECONDARY_ADAPTER + + s32 processing_dev_remove; + + //for local/global synchronization + _mutex hw_init_mutex; + _mutex h2c_fwcmd_mutex; + _mutex setch_mutex; + _mutex setbw_mutex; + + unsigned char oper_channel; //saved channel info when call set_channel_bw + unsigned char oper_bwmode; + unsigned char oper_ch_offset;//PRIME_CHNL_OFFSET + u32 on_oper_ch_time; + + //extend to support mulitu interface + //padapters[IFACE_ID0] == if1 + //padapters[IFACE_ID1] == if2 + _adapter *padapters[IFACE_ID_MAX]; + u8 iface_nums; // total number of ifaces used runtime + + //For 92D, DMDP have 2 interface. + u8 InterfaceNumber; + u8 NumInterfaces; + u8 DualMacMode; + u8 irq_alloc; + +/*-------- below is for SDIO INTERFACE --------*/ + +#ifdef INTF_DATA + INTF_DATA intf_data; +#endif + +/*-------- below is for USB INTERFACE --------*/ + +#ifdef CONFIG_USB_HCI + + u8 nr_endpoint; + u8 ishighspeed; + u8 RtNumInPipes; + u8 RtNumOutPipes; + int ep_num[5]; //endpoint number + + int RegUsbSS; + + _sema usb_suspend_sema; + +#ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _mutex usb_vendor_req_mutex; +#endif + +#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + u8 * usb_alloc_vendor_req_buf; + u8 * usb_vendor_req_buf; +#endif + +#ifdef PLATFORM_WINDOWS + //related device objects + PDEVICE_OBJECT pphysdevobj;//pPhysDevObj; + PDEVICE_OBJECT pfuncdevobj;//pFuncDevObj; + PDEVICE_OBJECT pnextdevobj;//pNextDevObj; + + u8 nextdevstacksz;//unsigned char NextDeviceStackSize; //= (CHAR)CEdevice->pUsbDevObj->StackSize + 1; + + //urb for control diescriptor request + +#ifdef PLATFORM_OS_XP + struct _URB_CONTROL_DESCRIPTOR_REQUEST descriptor_urb; + PUSB_CONFIGURATION_DESCRIPTOR pconfig_descriptor;//UsbConfigurationDescriptor; +#endif + +#ifdef PLATFORM_OS_CE + WCHAR active_path[MAX_ACTIVE_REG_PATH]; // adapter regpath + USB_EXTENSION usb_extension; + + _nic_hdl pipehdls_r8192c[0x10]; +#endif + + u32 config_descriptor_len;//ULONG UsbConfigurationDescriptorLength; +#endif//PLATFORM_WINDOWS + +#ifdef PLATFORM_LINUX + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_FREEBSD + ATOMIC_T continual_urb_error; +#endif//CONFIG_USB_HCI + +/*-------- below is for PCIE INTERFACE --------*/ + +#ifdef CONFIG_PCI_HCI + +#ifdef PLATFORM_LINUX + struct pci_dev *ppcidev; + + //PCI MEM map + unsigned long pci_mem_end; /* shared mem end */ + unsigned long pci_mem_start; /* shared mem start */ + + //PCI IO map + unsigned long pci_base_addr; /* device I/O address */ + + //PciBridge + struct pci_priv pcipriv; + + u16 irqline; + u8 irq_enabled; + RT_ISR_CONTENT isr_content; + _lock irq_th_lock; + + //ASPM + u8 const_pci_aspm; + u8 const_amdpci_aspm; + u8 const_hwsw_rfoff_d3; + u8 const_support_pciaspm; + // pci-e bridge */ + u8 const_hostpci_aspm_setting; + // pci-e device */ + u8 const_devicepci_aspm_setting; + u8 b_support_aspm; // If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. + u8 b_support_backdoor; + u8 bdma64; +#endif//PLATFORM_LINUX + +#endif//CONFIG_PCI_HCI +}; + +#ifdef PLATFORM_LINUX +static struct device *dvobj_to_dev(struct dvobj_priv *dvobj) +{ + /* todo: get interface type from dvobj and the return the dev accordingly */ +#ifdef RTW_DVOBJ_CHIP_HW_TYPE +#endif + +#ifdef CONFIG_USB_HCI + return &dvobj->pusbintf->dev; +#endif +#ifdef CONFIG_SDIO_HCI + return &dvobj->intf_data.func->dev; +#endif +#ifdef CONFIG_PCI_HCI + return &dvobj->ppcidev->dev; +#endif +} +#endif + + +enum _IFACE_TYPE { + IFACE_PORT0, //mapping to port0 for C/D series chips + IFACE_PORT1, //mapping to port1 for C/D series chip + MAX_IFACE_PORT, +}; + +enum _ADAPTER_TYPE { + PRIMARY_ADAPTER, + SECONDARY_ADAPTER, + MAX_ADAPTER = 0xFF, +}; + +typedef enum _DRIVER_STATE{ + DRIVER_NORMAL = 0, + DRIVER_DISAPPEAR = 1, + DRIVER_REPLACE_DONGLE = 2, +}DRIVER_STATE; + +#ifdef CONFIG_INTEL_PROXIM +struct proxim { + bool proxim_support; + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(_adapter *padapter, + union recv_frame *precv_frame); + u8 (*proxim_get_var)(_adapter* padapter, u8 type); +}; +#endif //CONFIG_INTEL_PROXIM + +#ifdef RTL8723A_SDIO_LOOPBACK +typedef struct loopbackdata +{ + _sema sema; + _thread_hdl_ lbkthread; + u8 bstop; + u32 cnt; + u16 size; + u16 txsize; + u8 txbuf[0x8000]; + u16 rxsize; + u8 rxbuf[0x8000]; + u8 msg[100]; + +}LOOPBACKDATA, *PLOOPBACKDATA; +#endif + +struct _ADAPTER{ + int DriverState;// for disable driver using module, use dongle to replace module. + int pid[3];//process id from UI, 0:wps, 1:hostapd, 2:dhcpcd + int bDongle;//build-in module or external dongle + u16 chip_type; + u16 HardwareType; + u16 interface_type;//USB,SDIO,PCI + + struct dvobj_priv *dvobj; + struct mlme_priv mlmepriv; + struct mlme_ext_priv mlmeextpriv; + struct cmd_priv cmdpriv; + struct evt_priv evtpriv; + //struct io_queue *pio_queue; + struct io_priv iopriv; + struct xmit_priv xmitpriv; + struct recv_priv recvpriv; + struct sta_priv stapriv; + struct security_priv securitypriv; + _lock security_key_mutex; // add for CONFIG_IEEE80211W, none 11w also can use + struct registry_priv registrypriv; + struct pwrctrl_priv pwrctrlpriv; + struct eeprom_priv eeprompriv; + struct led_priv ledpriv; + +#ifdef CONFIG_MP_INCLUDED + struct mp_priv mppriv; +#endif + +#ifdef CONFIG_DRVEXT_MODULE + struct drvext_priv drvextpriv; +#endif + +#ifdef CONFIG_AP_MODE + struct hostapd_priv *phostapdpriv; +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P + struct cfg80211_wifidirect_info cfg80211_wdinfo; +#endif //CONFIG_P2P +#endif //CONFIG_IOCTL_CFG80211 + u32 setband; +#ifdef CONFIG_P2P + struct wifidirect_info wdinfo; +#endif //CONFIG_P2P + +#ifdef CONFIG_TDLS + struct tdls_info tdlsinfo; +#endif //CONFIG_TDLS + +#ifdef CONFIG_WFD + struct wifi_display_info wfd_info; +#endif //CONFIG_WFD + + PVOID HalData; + u32 hal_data_sz; + struct hal_ops HalFunc; + +#ifdef CONFIG_BT_COEXIST + //struct btcoexist_priv bt_coexist; +#endif + s32 bDriverStopped; + s32 bSurpriseRemoved; + s32 bCardDisableWOHSM; + + u32 IsrContent; + u32 ImrContent; + + u8 EepromAddressSize; + u8 hw_init_completed; + u8 bDriverIsGoingToUnload; + u8 init_adpt_in_progress; + u8 bHaltInProgress; + + _thread_hdl_ cmdThread; + _thread_hdl_ evtThread; + _thread_hdl_ xmitThread; + _thread_hdl_ recvThread; + +#ifndef PLATFORM_LINUX + NDIS_STATUS (*dvobj_init)(struct dvobj_priv *dvobj); + void (*dvobj_deinit)(struct dvobj_priv *dvobj); +#endif + + void (*intf_start)(_adapter * adapter); + void (*intf_stop)(_adapter * adapter); + +#ifdef PLATFORM_WINDOWS + _nic_hdl hndis_adapter;//hNdisAdapter(NDISMiniportAdapterHandle); + _nic_hdl hndis_config;//hNdisConfiguration; + NDIS_STRING fw_img; + + u32 NdisPacketFilter; + u8 MCList[MAX_MCAST_LIST_NUM][6]; + u32 MCAddrCount; +#endif //end of PLATFORM_WINDOWS + + +#ifdef PLATFORM_LINUX + _nic_hdl pnetdev; + + // used by rtw_rereg_nd_name related function + struct rereg_nd_name_data { + _nic_hdl old_pnetdev; + char old_ifname[IFNAMSIZ]; + u8 old_ips_mode; + u8 old_bRegUseLed; + } rereg_nd_name_priv; + + int bup; + struct net_device_stats stats; + struct iw_statistics iwstats; + struct proc_dir_entry *dir_dev;// for proc directory + +#ifdef CONFIG_IOCTL_CFG80211 + struct wireless_dev *rtw_wdev; +#endif //CONFIG_IOCTL_CFG80211 + +#endif //end of PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + _nic_hdl pifp; + int bup; + _lock glock; +#endif //PLATFORM_FREEBSD + int net_closed; + + u8 bFWReady; + u8 bReadPortCancel; + u8 bWritePortCancel; + u8 bRxRSSIDisplay; + // Added by Albert 2012/07/26 + // The driver will write the initial gain everytime when running in the DM_Write_DIG function. + u8 bForceWriteInitGain; + // Added by Albert 2012/10/26 + // The driver will show up the desired channel number when this flag is 1. + u8 bNotifyChannelChange; +#ifdef CONFIG_P2P + // Added by Albert 2012/12/06 + // The driver will show the current P2P status when the upper application reads it. + u8 bShowGetP2PState; +#endif +#ifdef CONFIG_AUTOSUSPEND + u8 bDisableAutosuspend; +#endif + + //pbuddy_adapter is used only in two inteface case, (iface_nums=2 in struct dvobj_priv) + //PRIMARY_ADAPTER's buddy is SECONDARY_ADAPTER + //SECONDARY_ADAPTER's buddy is PRIMARY_ADAPTER + //for iface_id > SECONDARY_ADAPTER(IFACE_ID1), refer to padapters[iface_id] in struct dvobj_priv + //and their pbuddy_adapter is PRIMARY_ADAPTER. + //for PRIMARY_ADAPTER(IFACE_ID0) can directly refer to if1 in struct dvobj_priv + _adapter *pbuddy_adapter; + +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_DUALMAC_CONCURRENT) + u8 isprimary; //is primary adapter or not + //notes: + // if isprimary is true, the adapter_type value is 0, iface_id is IFACE_ID0 for PRIMARY_ADAPTER + // if isprimary is false, the adapter_type value is 1, iface_id is IFACE_ID1 for SECONDARY_ADAPTER + // refer to iface_id if iface_nums>2 and isprimary is false and the adapter_type value is 0xff. + u8 adapter_type;//used only in two inteface case(PRIMARY_ADAPTER and SECONDARY_ADAPTER) . + u8 iface_type; //interface port type, it depends on HW port +#endif + + //extend to support multi interface + //IFACE_ID0 is equals to PRIMARY_ADAPTER + //IFACE_ID1 is equals to SECONDARY_ADAPTER + u8 iface_id; + +#ifdef CONFIG_DUALMAC_CONCURRENT + u8 DualMacConcurrent; // 1: DMSP 0:DMDP +#endif + +#ifdef CONFIG_BR_EXT + _lock br_ext_lock; + //unsigned int macclone_completed; + struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; + int pppoe_connection_in_progress; + unsigned char pppoe_addr[MACADDRLEN]; + unsigned char scdb_mac[MACADDRLEN]; + unsigned char scdb_ip[4]; + struct nat25_network_db_entry *scdb_entry; + unsigned char br_mac[MACADDRLEN]; + unsigned char br_ip[4]; + + struct br_ext_info ethBrExtInfo; +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_INTEL_PROXIM + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode */ + struct proxim proximity; +#endif //CONFIG_INTEL_PROXIM + +#ifdef RTL8723A_SDIO_LOOPBACK + PLOOPBACKDATA ploopback; +#endif + +}; + +#define adapter_to_dvobj(adapter) (adapter->dvobj) + +int rtw_handle_dualmac(_adapter *adapter, bool init); + +__inline static u8 *myid(struct eeprom_priv *peepriv) +{ + return (peepriv->mac_addr); +} + + +#endif //__DRV_TYPES_H__ + diff --git a/rtl8192cu-fixes/include/drv_types_ce.h b/rtl8192cu-fixes/include/drv_types_ce.h new file mode 100755 index 00000000..be0459dc --- /dev/null +++ b/rtl8192cu-fixes/include/drv_types_ce.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_CE_H__ +#define __DRV_TYPES_CE_H__ + +#include +#include + +#include + +#define MAX_ACTIVE_REG_PATH 256 + +#define MAX_MCAST_LIST_NUM 32 + + + +//for ioctl +#define MAKE_DRIVER_VERSION(_MainVer,_MinorVer) ((((u32)(_MainVer))<<16)+_MinorVer) + +#define NIC_HEADER_SIZE 14 //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h +#define NIC_MAX_SEND_PACKETS 10 // max number of send packets the MiniportSendPackets function can accept, can be moved to typedef.h +#define NIC_VENDOR_DRIVER_VERSION MAKE_DRIVER_VERSION(0,001) //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h + +typedef struct _MP_REG_ENTRY +{ + + NDIS_STRING RegName; // variable name text + BOOLEAN bRequired; // 1 -> required, 0 -> optional + + u8 Type; // NdisParameterInteger/NdisParameterHexInteger/NdisParameterStringle/NdisParameterMultiString + uint FieldOffset; // offset to MP_ADAPTER field + uint FieldSize; // size (in bytes) of the field + +#ifdef UNDER_AMD64 + u64 Default; +#else + u32 Default; // default value to use +#endif + + u32 Min; // minimum value allowed + u32 Max; // maximum value allowed +} MP_REG_ENTRY, *PMP_REG_ENTRY; + +#ifdef CONFIG_USB_HCI +typedef struct _USB_EXTENSION { + LPCUSB_FUNCS _lpUsbFuncs; + USB_HANDLE _hDevice; + PVOID pAdapter; + +#if 0 + USB_ENDPOINT_DESCRIPTOR _endpACLIn; + USB_ENDPOINT_DESCRIPTOR _endpACLOutHigh; + USB_ENDPOINT_DESCRIPTOR _endpACLOutNormal; + + USB_PIPE pPipeIn; + USB_PIPE pPipeOutNormal; + USB_PIPE pPipeOutHigh; +#endif + +} USB_EXTENSION, *PUSB_EXTENSION; +#endif + + +typedef struct _OCTET_STRING{ + u8 *Octet; + u16 Length; +} OCTET_STRING, *POCTET_STRING; + + + + + +#endif diff --git a/rtl8192cu-fixes/include/drv_types_linux.h b/rtl8192cu-fixes/include/drv_types_linux.h new file mode 100755 index 00000000..db1c5856 --- /dev/null +++ b/rtl8192cu-fixes/include/drv_types_linux.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_LINUX_H__ +#define __DRV_TYPES_LINUX_H__ + + +#endif + diff --git a/rtl8192cu-fixes/include/drv_types_sdio.h b/rtl8192cu-fixes/include/drv_types_sdio.h new file mode 100755 index 00000000..fd467ca6 --- /dev/null +++ b/rtl8192cu-fixes/include/drv_types_sdio.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_SDIO_H__ +#define __DRV_TYPES_SDIO_H__ + +#include +#include + +// SDIO Header Files +#ifdef PLATFORM_LINUX +#include +#endif +#ifdef PLATFORM_OS_XP +#include +#include +#endif +#ifdef PLATFORM_OS_CE +#include +#endif + + +typedef struct sdio_data +{ + u8 func_number; + + u8 tx_block_mode; + u8 rx_block_mode; + u32 block_transfer_len; + +#ifdef PLATFORM_LINUX + struct sdio_func *func; +#endif + +#ifdef PLATFORM_OS_XP + PDEVICE_OBJECT pphysdevobj; + PDEVICE_OBJECT pfuncdevobj; + PDEVICE_OBJECT pnextdevobj; + SDBUS_INTERFACE_STANDARD sdbusinft; + u8 nextdevstacksz; +#endif + +#ifdef PLATFORM_OS_CE + SD_DEVICE_HANDLE hDevice; + SD_CARD_RCA sd_rca; + SD_CARD_INTERFACE card_intf; + BOOLEAN enableIsarWithStatus; + WCHAR active_path[MAX_ACTIVE_REG_PATH]; + SD_HOST_BLOCK_CAPABILITY sd_host_blk_cap; +#endif +} SDIO_DATA, *PSDIO_DATA; + +#endif + diff --git a/rtl8192cu-fixes/include/drv_types_xp.h b/rtl8192cu-fixes/include/drv_types_xp.h new file mode 100755 index 00000000..2d51b1db --- /dev/null +++ b/rtl8192cu-fixes/include/drv_types_xp.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_XP_H__ +#define __DRV_TYPES_XP_H__ + +#include +#include + + + +#define MAX_MCAST_LIST_NUM 32 + + + +//for ioctl +#define MAKE_DRIVER_VERSION(_MainVer,_MinorVer) ((((u32)(_MainVer))<<16)+_MinorVer) + +#define NIC_HEADER_SIZE 14 //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h +#define NIC_MAX_SEND_PACKETS 10 // max number of send packets the MiniportSendPackets function can accept, can be moved to typedef.h +#define NIC_VENDOR_DRIVER_VERSION MAKE_DRIVER_VERSION(0,001) //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h + + +#undef ON_VISTA +//added by Jackson +#ifndef ON_VISTA +// +// Bus driver versions +// + +#define SDBUS_DRIVER_VERSION_1 0x100 +#define SDBUS_DRIVER_VERSION_2 0x200 + +#define SDP_FUNCTION_TYPE 4 +#define SDP_BUS_DRIVER_VERSION 5 +#define SDP_BUS_WIDTH 6 +#define SDP_BUS_CLOCK 7 +#define SDP_BUS_INTERFACE_CONTROL 8 +#define SDP_HOST_BLOCK_LENGTH 9 +#define SDP_FUNCTION_BLOCK_LENGTH 10 +#define SDP_FN0_BLOCK_LENGTH 11 +#define SDP_FUNCTION_INT_ENABLE 12 +#endif + + +typedef struct _MP_REG_ENTRY +{ + + NDIS_STRING RegName; // variable name text + BOOLEAN bRequired; // 1 -> required, 0 -> optional + + u8 Type; // NdisParameterInteger/NdisParameterHexInteger/NdisParameterStringle/NdisParameterMultiString + uint FieldOffset; // offset to MP_ADAPTER field + uint FieldSize; // size (in bytes) of the field + +#ifdef UNDER_AMD64 + u64 Default; +#else + u32 Default; // default value to use +#endif + + u32 Min; // minimum value allowed + u32 Max; // maximum value allowed +} MP_REG_ENTRY, *PMP_REG_ENTRY; + + +typedef struct _OCTET_STRING{ + u8 *Octet; + u16 Length; +} OCTET_STRING, *POCTET_STRING; + + + + + +#endif + diff --git a/rtl8192cu-fixes/include/ethernet.h b/rtl8192cu-fixes/include/ethernet.h new file mode 100755 index 00000000..36e29c06 --- /dev/null +++ b/rtl8192cu-fixes/include/ethernet.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * 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 */ +#ifndef __INC_ETHERNET_H +#define __INC_ETHERNET_H + +#define ETHERNET_ADDRESS_LENGTH 6 //!< Ethernet Address Length +#define ETHERNET_HEADER_SIZE 14 //!< Ethernet Header Length +#define LLC_HEADER_SIZE 6 //!< LLC Header Length +#define TYPE_LENGTH_FIELD_SIZE 2 //!< Type/Length Size +#define MINIMUM_ETHERNET_PACKET_SIZE 60 //!< Minimum Ethernet Packet Size +#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 //!< Maximum Ethernet Packet Size + +#define RT_ETH_IS_MULTICAST(_pAddr) ((((UCHAR *)(_pAddr))[0]&0x01)!=0) //!< Is Multicast Address? +#define RT_ETH_IS_BROADCAST(_pAddr) ( \ + ((UCHAR *)(_pAddr))[0]==0xff && \ + ((UCHAR *)(_pAddr))[1]==0xff && \ + ((UCHAR *)(_pAddr))[2]==0xff && \ + ((UCHAR *)(_pAddr))[3]==0xff && \ + ((UCHAR *)(_pAddr))[4]==0xff && \ + ((UCHAR *)(_pAddr))[5]==0xff ) //!< Is Broadcast Address? + + +#endif // #ifndef __INC_ETHERNET_H diff --git a/rtl8192cu-fixes/include/h2clbk.h b/rtl8192cu-fixes/include/h2clbk.h new file mode 100755 index 00000000..359c9e7a --- /dev/null +++ b/rtl8192cu-fixes/include/h2clbk.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + + +#define _H2CLBK_H_ + + +#include +#include + + +void _lbk_cmd(PADAPTER Adapter); + +void _lbk_rsp(PADAPTER Adapter); + +void _lbk_evt(IN PADAPTER Adapter); + +void h2c_event_callback(unsigned char *dev, unsigned char *pbuf); diff --git a/rtl8192cu-fixes/include/hal_com.h b/rtl8192cu-fixes/include/hal_com.h new file mode 100755 index 00000000..42aae0e0 --- /dev/null +++ b/rtl8192cu-fixes/include/hal_com.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 __HAL_COMMON_H__ +#define __HAL_COMMON_H__ + +//CCK +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +//OFDM +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +//MCS 1 Spatial Stream +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +//MCS 2 Spatial Stream +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\ + RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + +/*------------------------------ Tx Desc definition Macro ------------------------*/ +//#pragma mark -- Tx Desc related definition. -- +//---------------------------------------------------------------------------- +//----------------------------------------------------------- +// Rate +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC_RATE1M 0x00 +#define DESC_RATE2M 0x01 +#define DESC_RATE5_5M 0x02 +#define DESC_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC_RATE6M 0x04 +#define DESC_RATE9M 0x05 +#define DESC_RATE12M 0x06 +#define DESC_RATE18M 0x07 +#define DESC_RATE24M 0x08 +#define DESC_RATE36M 0x09 +#define DESC_RATE48M 0x0a +#define DESC_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC_RATEMCS0 0x0c +#define DESC_RATEMCS1 0x0d +#define DESC_RATEMCS2 0x0e +#define DESC_RATEMCS3 0x0f +#define DESC_RATEMCS4 0x10 +#define DESC_RATEMCS5 0x11 +#define DESC_RATEMCS6 0x12 +#define DESC_RATEMCS7 0x13 +#define DESC_RATEMCS8 0x14 +#define DESC_RATEMCS9 0x15 +#define DESC_RATEMCS10 0x16 +#define DESC_RATEMCS11 0x17 +#define DESC_RATEMCS12 0x18 +#define DESC_RATEMCS13 0x19 +#define DESC_RATEMCS14 0x1a +#define DESC_RATEMCS15 0x1b +#define DESC_RATEMCS15_SG 0x1c +#define DESC_RATEMCS32 0x20 + +//============================================================ +// Global var +//============================================================ +#define OFDM_TABLE_SIZE_92C 37 +#define OFDM_TABLE_SIZE_92D 43 +#define CCK_TABLE_SIZE 33 + +extern u32 OFDMSwingTable[OFDM_TABLE_SIZE_92D] ; + +extern u8 CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; + +extern u8 CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; + +#ifdef CONFIG_CHIP_VER_INTEGRATION +void dump_chip_info(HAL_VERSION ChipVersion); +#endif + +u8 //return the final channel plan decision +hal_com_get_channel_plan( + IN PADAPTER padapter, + IN u8 hw_channel_plan, //channel plan from HW (efuse/eeprom) + IN u8 sw_channel_plan, //channel plan from SW (registry/module param) + IN u8 def_channel_plan, //channel plan used when the former two is invalid + IN BOOLEAN AutoLoadFail + ); + +void HalSetBrateCfg( + IN PADAPTER Adapter, + IN u8 *mBratesOS, + OUT u16 *pBrateCfg); + +u8 MRateToHwRate(u8 rate); + +void hal_init_macaddr(_adapter *adapter); + +void c2h_evt_clear(_adapter *adapter); +s32 c2h_evt_read(_adapter *adapter, u8 *buf); + +#endif //__HAL_COMMON_H__ + diff --git a/rtl8192cu-fixes/include/hal_intf.h b/rtl8192cu-fixes/include/hal_intf.h new file mode 100755 index 00000000..dd826622 --- /dev/null +++ b/rtl8192cu-fixes/include/hal_intf.h @@ -0,0 +1,432 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __HAL_INTF_H__ +#define __HAL_INTF_H__ + +#include +#include +#include + +#ifdef CONFIG_PCI_HCI +#include +#endif + + +enum RTL871X_HCI_TYPE { + + RTW_SDIO, + RTW_USB, + RTW_PCIE +}; + +enum _CHIP_TYPE { + + NULL_CHIP_TYPE, + RTL8712_8188S_8191S_8192S, + RTL8188C_8192C, + RTL8192D, + RTL8723A, + RTL8188E, + MAX_CHIP_TYPE +}; + + +typedef enum _HW_VARIABLES{ + HW_VAR_MEDIA_STATUS, + HW_VAR_MEDIA_STATUS1, + HW_VAR_SET_OPMODE, + HW_VAR_MAC_ADDR, + HW_VAR_BSSID, + HW_VAR_INIT_RTS_RATE, + HW_VAR_INIT_DATA_RATE, + HW_VAR_BASIC_RATE, + HW_VAR_TXPAUSE, + HW_VAR_BCN_FUNC, + HW_VAR_CORRECT_TSF, + HW_VAR_CHECK_BSSID, + HW_VAR_MLME_DISCONNECT, + HW_VAR_MLME_SITESURVEY, + HW_VAR_MLME_JOIN, + HW_VAR_ON_RCR_AM, + HW_VAR_OFF_RCR_AM, + HW_VAR_BEACON_INTERVAL, + HW_VAR_SLOT_TIME, + HW_VAR_RESP_SIFS, + HW_VAR_ACK_PREAMBLE, + HW_VAR_SEC_CFG, + HW_VAR_BCN_VALID, + HW_VAR_RF_TYPE, + HW_VAR_DM_FLAG, + HW_VAR_DM_FUNC_OP, + HW_VAR_DM_FUNC_SET, + HW_VAR_DM_FUNC_CLR, + HW_VAR_DM_INIT_PWDB, + HW_VAR_CAM_EMPTY_ENTRY, + HW_VAR_CAM_INVALID_ALL, + HW_VAR_CAM_WRITE, + HW_VAR_CAM_READ, + HW_VAR_AC_PARAM_VO, + HW_VAR_AC_PARAM_VI, + HW_VAR_AC_PARAM_BE, + HW_VAR_AC_PARAM_BK, + HW_VAR_ACM_CTRL, + HW_VAR_AMPDU_MIN_SPACE, + HW_VAR_AMPDU_FACTOR, + HW_VAR_RXDMA_AGG_PG_TH, + HW_VAR_SET_RPWM, + HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_FW_JOINBSSRPT, + HW_VAR_FWLPS_RF_ON, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + HW_VAR_TDLS_WRCR, + HW_VAR_TDLS_INIT_CH_SEN, + HW_VAR_TDLS_RS_RCR, + HW_VAR_TDLS_DONE_CH_SEN, + HW_VAR_INITIAL_GAIN, + HW_VAR_TRIGGER_GPIO_0, + HW_VAR_BT_SET_COEXIST, + HW_VAR_BT_ISSUE_DELBA, + HW_VAR_CURRENT_ANTENNA, + HW_VAR_ANTENNA_DIVERSITY_LINK, + HW_VAR_ANTENNA_DIVERSITY_SELECT, + HW_VAR_SWITCH_EPHY_WoWLAN, + HW_VAR_EFUSE_BYTES, + HW_VAR_FIFO_CLEARN_UP, + HW_VAR_CHECK_TXBUF, + HW_VAR_APFM_ON_MAC, //Auto FSM to Turn On, include clock, isolation, power control for MAC only + HW_VAR_WOWLAN, + HW_VAR_VID, + HW_VAR_PID, + HW_VAR_MBSSID_CAM_WRITE, + HW_VAR_MBSSID_CAM_CLEAR, + HW_VAR_RCR_MBSSID_EN, + HW_VAR_USB_RXAGG_PAGE_TO, +}HW_VARIABLES; + +typedef enum _HAL_DEF_VARIABLE{ + HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, + HAL_DEF_IS_SUPPORT_ANT_DIV, + HAL_DEF_CURRENT_ANTENNA, + HAL_DEF_DRVINFO_SZ, + HAL_DEF_MAX_RECVBUF_SZ, + HAL_DEF_RX_PACKET_OFFSET, + HAL_DEF_DBG_DUMP_RXPKT,//for dbg + HAL_DEF_DBG_DM_FUNC,//for dbg + HAL_DEF_DUAL_MAC_MODE, +}HAL_DEF_VARIABLE; + +typedef enum _HAL_INTF_PS_FUNC{ + HAL_USB_SELECT_SUSPEND, + HAL_MAX_ID, +}HAL_INTF_PS_FUNC; + +typedef s32 (*c2h_id_filter)(u8 id); + +struct hal_ops { + u32 (*hal_init)(PADAPTER Adapter); + u32 (*hal_deinit)(PADAPTER Adapter); + + void (*free_hal_data)(PADAPTER Adapter); + + u32 (*inirp_init)(PADAPTER Adapter); + u32 (*inirp_deinit)(PADAPTER Adapter); + + s32 (*init_xmit_priv)(PADAPTER Adapter); + void (*free_xmit_priv)(PADAPTER Adapter); + + s32 (*init_recv_priv)(PADAPTER Adapter); + void (*free_recv_priv)(PADAPTER Adapter); + + void (*InitSwLeds)(PADAPTER Adapter); + void (*DeInitSwLeds)(PADAPTER Adapter); + + void (*dm_init)(PADAPTER Adapter); + void (*dm_deinit)(PADAPTER Adapter); + void (*read_chip_version)(PADAPTER Adapter); + + void (*init_default_value)(PADAPTER Adapter); + + void (*intf_chip_configure)(PADAPTER Adapter); + + void (*read_adapter_info)(PADAPTER Adapter); + + void (*enable_interrupt)(PADAPTER Adapter); + void (*disable_interrupt)(PADAPTER Adapter); + s32 (*interrupt_handler)(PADAPTER Adapter); + + void (*set_bwmode_handler)(PADAPTER Adapter, HT_CHANNEL_WIDTH Bandwidth, u8 Offset); + void (*set_channel_handler)(PADAPTER Adapter, u8 channel); + + void (*hal_dm_watchdog)(PADAPTER Adapter); + + void (*SetHwRegHandler)(PADAPTER Adapter, u8 variable,u8* val); + void (*GetHwRegHandler)(PADAPTER Adapter, u8 variable,u8* val); + + u8 (*GetHalDefVarHandler)(PADAPTER Adapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + u8 (*SetHalDefVarHandler)(PADAPTER Adapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + + void (*UpdateRAMaskHandler)(PADAPTER Adapter, u32 mac_id); + void (*SetBeaconRelatedRegistersHandler)(PADAPTER Adapter); + + void (*Add_RateATid)(PADAPTER Adapter, u32 bitmap, u8 arg); + +#ifdef CONFIG_ANTENNA_DIVERSITY + u8 (*AntDivBeforeLinkHandler)(PADAPTER Adapter); + void (*AntDivCompareHandler)(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +#endif + u8 (*interface_ps_func)(PADAPTER Adapter,HAL_INTF_PS_FUNC efunc_id, u8* val); + + s32 (*hal_xmit)(PADAPTER Adapter, struct xmit_frame *pxmitframe); + s32 (*mgnt_xmit)(PADAPTER Adapter, struct xmit_frame *pmgntframe); + s32 (*hal_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); + + u32 (*read_bbreg)(PADAPTER Adapter, u32 RegAddr, u32 BitMask); + void (*write_bbreg)(PADAPTER Adapter, u32 RegAddr, u32 BitMask, u32 Data); + u32 (*read_rfreg)(PADAPTER Adapter, u32 eRFPath, u32 RegAddr, u32 BitMask); + void (*write_rfreg)(PADAPTER Adapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); + +#ifdef CONFIG_HOSTAPD_MLME + s32 (*hostap_mgnt_xmit_entry)(PADAPTER Adapter, _pkt *pkt); +#endif + void (*EfusePowerSwitch)(PADAPTER pAdapter, u8 bWrite, u8 PwrState); + void (*ReadEFuse)(PADAPTER Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, BOOLEAN bPseudoTest); + void (*EFUSEGetEfuseDefinition)(PADAPTER pAdapter, u8 efuseType, u8 type, PVOID *pOut, BOOLEAN bPseudoTest); + u16 (*EfuseGetCurrentSize)(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); + int (*Efuse_PgPacketRead)(PADAPTER pAdapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); + int (*Efuse_PgPacketWrite)(PADAPTER pAdapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + u8 (*Efuse_WordEnableDataWrite)(PADAPTER pAdapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + +#ifdef DBG_CONFIG_ERROR_DETECT + void (*sreset_init_value)(_adapter *padapter); + void (*sreset_reset_value)(_adapter *padapter); + void (*silentreset)(_adapter *padapter); + void (*sreset_xmit_status_check)(_adapter *padapter); + void (*sreset_linked_status_check) (_adapter *padapter); + u8 (*sreset_get_wifi_status)(_adapter *padapter); + bool (*sreset_inprogress)(_adapter *padapter); +#endif + +#ifdef CONFIG_IOL + int (*IOL_exec_cmds_sync)(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms); +#endif + void (*hal_notch_filter)(_adapter * adapter, bool enable); + void (*hal_reset_security_engine)(_adapter * adapter); + + s32 (*c2h_handler)(_adapter *padapter, struct c2h_evt_hdr *c2h_evt); + c2h_id_filter c2h_id_filter_ccx; +}; + +typedef enum _RT_EEPROM_TYPE{ + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}RT_EEPROM_TYPE,*PRT_EEPROM_TYPE; + +#define USB_HIGH_SPEED_BULK_SIZE 512 +#define USB_FULL_SPEED_BULK_SIZE 64 + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_SW BIT31 + +typedef enum _HARDWARE_TYPE{ + HARDWARE_TYPE_RTL8180, + HARDWARE_TYPE_RTL8185, + HARDWARE_TYPE_RTL8187, + HARDWARE_TYPE_RTL8188, + HARDWARE_TYPE_RTL8190P, + HARDWARE_TYPE_RTL8192E, + HARDWARE_TYPE_RTL819xU, + HARDWARE_TYPE_RTL8192SE, + HARDWARE_TYPE_RTL8192SU, + HARDWARE_TYPE_RTL8192CE, + HARDWARE_TYPE_RTL8192CU, + HARDWARE_TYPE_RTL8192DE, + HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723AE, + HARDWARE_TYPE_RTL8723AU, + HARDWARE_TYPE_RTL8723AS, + HARDWARE_TYPE_RTL8188EE, + HARDWARE_TYPE_RTL8188EU, + HARDWARE_TYPE_RTL8188ES, + HARDWARE_TYPE_MAX, +}HARDWARE_TYPE; + +// +// RTL8192C Series +// +#define IS_HARDWARE_TYPE_8192CE(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8192CU(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192CU) +#define IS_HARDWARE_TYPE_8192C(_Adapter) \ +(IS_HARDWARE_TYPE_8192CE(_Adapter) || IS_HARDWARE_TYPE_8192CU(_Adapter)) + +// +// RTL8192D Series +// +#define IS_HARDWARE_TYPE_8192DE(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192DE) +#define IS_HARDWARE_TYPE_8192DU(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192DU) +#define IS_HARDWARE_TYPE_8192D(_Adapter) \ +(IS_HARDWARE_TYPE_8192DE(_Adapter) || IS_HARDWARE_TYPE_8192DU(_Adapter)) + +// +// RTL8723A Series +// +#define IS_HARDWARE_TYPE_8723AE(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AE) +#define IS_HARDWARE_TYPE_8723AU(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AU) +#define IS_HARDWARE_TYPE_8723AS(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AS) +#define IS_HARDWARE_TYPE_8723A(_Adapter) \ +(IS_HARDWARE_TYPE_8723AE(_Adapter) || IS_HARDWARE_TYPE_8723AU(_Adapter) || IS_HARDWARE_TYPE_8723AS(_Adapter)) + +// +// RTL8188E Series +// +#define IS_HARDWARE_TYPE_8188EE(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188EE) +#define IS_HARDWARE_TYPE_8188EU(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188EU) +#define IS_HARDWARE_TYPE_8188ES(_Adapter) (((PADAPTER)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188ES) +#define IS_HARDWARE_TYPE_8188E(_Adapter) \ +(IS_HARDWARE_TYPE_8188EE(_Adapter) || IS_HARDWARE_TYPE_8188EU(_Adapter) || IS_HARDWARE_TYPE_8188ES(_Adapter)) + + +typedef struct eeprom_priv EEPROM_EFUSE_PRIV, *PEEPROM_EFUSE_PRIV; +#define GET_EEPROM_EFUSE_PRIV(priv) (&priv->eeprompriv) + +#ifdef CONFIG_WOWLAN +typedef enum _wowlan_subcode{ + WOWLAN_PATTERN_MATCH = 1, + WOWLAN_MAGIC_PACKET = 2, + WOWLAN_UNICAST = 3, + WOWLAN_SET_PATTERN = 4, + WOWLAN_DUMP_REG = 5, + WOWLAN_ENABLE = 6, + WOWLAN_DISABLE = 7, + WOWLAN_STATUS = 8, + WOWLAN_DEBUG_RELOAD_FW = 9, + WOWLAN_DEBUG_1 =10, + WOWLAN_DEBUG_2 =11 +}wowlan_subcode; + +struct wowlan_ioctl_param{ + unsigned int subcode; + unsigned int subcode_value; + unsigned int wakeup_reason; + unsigned int len; + unsigned char pattern[0]; +}; + +#define Rx_Pairwisekey BIT(0) +#define Rx_GTK BIT(1) +#define Rx_DisAssoc BIT(2) +#define Rx_DeAuth BIT(3) +#define FWDecisionDisconnect BIT(4) +#define Rx_MagicPkt BIT(5) +#define FinishBtFwPatch BIT(7) + +#endif // CONFIG_WOWLAN + +void rtw_hal_def_value_init(_adapter *padapter); +void rtw_hal_free_data(_adapter *padapter); + +void rtw_hal_dm_init(_adapter *padapter); +void rtw_hal_dm_deinit(_adapter *padapter); +void rtw_hal_sw_led_init(_adapter *padapter); +void rtw_hal_sw_led_deinit(_adapter *padapter); + +uint rtw_hal_init(_adapter *padapter); +uint rtw_hal_deinit(_adapter *padapter); +void rtw_hal_stop(_adapter *padapter); + +void rtw_hal_set_hwreg(PADAPTER padapter, u8 variable, u8 *val); +void rtw_hal_get_hwreg(PADAPTER padapter, u8 variable, u8 *val); + +void rtw_hal_chip_configure(_adapter *padapter); +void rtw_hal_read_chip_info(_adapter *padapter); +void rtw_hal_read_chip_version(_adapter *padapter); + +u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); +u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + +void rtw_hal_enable_interrupt(_adapter *padapter); +void rtw_hal_disable_interrupt(_adapter *padapter); + +u32 rtw_hal_inirp_init(_adapter *padapter); +u32 rtw_hal_inirp_deinit(_adapter *padapter); + +u8 rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val); + +s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtw_hal_init_xmit_priv(_adapter *padapter); +void rtw_hal_free_xmit_priv(_adapter *padapter); + +s32 rtw_hal_init_recv_priv(_adapter *padapter); +void rtw_hal_free_recv_priv(_adapter *padapter); + +void rtw_hal_update_ra_mask(_adapter *padapter, u32 mac_id); +void rtw_hal_add_ra_tid(_adapter *padapter, u32 bitmap, u8 arg); + +void rtw_hal_bcn_related_reg_setting(_adapter *padapter); + +u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask); +void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); +u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask); +void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); + +s32 rtw_hal_interrupt_handler(_adapter *padapter); + +void rtw_hal_set_bwmode(_adapter *padapter, HT_CHANNEL_WIDTH Bandwidth, u8 Offset); +void rtw_hal_set_chan(_adapter *padapter, u8 channel); + +void rtw_hal_dm_watchdog(_adapter *padapter); + +#ifdef CONFIG_ANTENNA_DIVERSITY +u8 rtw_hal_antdiv_before_linked(_adapter *padapter); +void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +#endif + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtw_hal_sreset_init(_adapter *padapter); +void rtw_hal_sreset_reset(_adapter *padapter); +void rtw_hal_sreset_reset_value(_adapter *padapter); +void rtw_hal_sreset_xmit_status_check(_adapter *padapter); +void rtw_hal_sreset_linked_status_check(_adapter *padapter); +u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter); +bool rtw_hal_sreset_inprogress(_adapter *padapter); +#endif + +#ifdef CONFIG_IOL +int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms); +#endif + +void rtw_hal_notch_filter(_adapter * adapter, bool enable); +void rtw_hal_reset_security_engine(_adapter * adapter); + +s32 rtw_hal_c2h_handler(_adapter *adapter, struct c2h_evt_hdr *c2h_evt); +c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *adapter); + +#endif //__HAL_INTF_H__ + diff --git a/rtl8192cu-fixes/include/ieee80211.h b/rtl8192cu-fixes/include/ieee80211.h new file mode 100755 index 00000000..e283a5f2 --- /dev/null +++ b/rtl8192cu-fixes/include/ieee80211.h @@ -0,0 +1,1580 @@ +/****************************************************************************** + * + * 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 __IEEE80211_H +#define __IEEE80211_H + + +#ifndef CONFIG_RTL8711FW + + #include + #include + #include + #include "wifi.h" + + #if defined PLATFORM_OS_XP + #include + #endif + #if defined PLATFORM_LINUX + #include + #endif +#else + + #include + +#endif + +#define MGMT_QUEUE_NUM 5 + +#define ETH_ALEN 6 +#define ETH_TYPE_LEN 2 +#define PAYLOAD_TYPE_LEN 1 + +#ifdef CONFIG_AP_MODE + +#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) + +/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ +enum { + RTL871X_HOSTAPD_FLUSH = 1, + RTL871X_HOSTAPD_ADD_STA = 2, + RTL871X_HOSTAPD_REMOVE_STA = 3, + RTL871X_HOSTAPD_GET_INFO_STA = 4, + /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ + RTL871X_HOSTAPD_GET_WPAIE_STA = 5, + RTL871X_SET_ENCRYPTION = 6, + RTL871X_GET_ENCRYPTION = 7, + RTL871X_HOSTAPD_SET_FLAGS_STA = 8, + RTL871X_HOSTAPD_GET_RID = 9, + RTL871X_HOSTAPD_SET_RID = 10, + RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, + RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, + RTL871X_HOSTAPD_MLME = 13, + RTL871X_HOSTAPD_SCAN_REQ = 14, + RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, + RTL871X_HOSTAPD_SET_BEACON=16, + RTL871X_HOSTAPD_SET_WPS_BEACON = 17, + RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, + RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, + RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, + RTL871X_HOSTAPD_SET_MACADDR_ACL = 21, + RTL871X_HOSTAPD_ACL_ADD_STA = 22, + RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, +}; + +/* STA flags */ +#define WLAN_STA_AUTH BIT(0) +#define WLAN_STA_ASSOC BIT(1) +#define WLAN_STA_PS BIT(2) +#define WLAN_STA_TIM BIT(3) +#define WLAN_STA_PERM BIT(4) +#define WLAN_STA_AUTHORIZED BIT(5) +#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ +#define WLAN_STA_SHORT_PREAMBLE BIT(7) +#define WLAN_STA_PREAUTH BIT(8) +#define WLAN_STA_WME BIT(9) +#define WLAN_STA_MFP BIT(10) +#define WLAN_STA_HT BIT(11) +#define WLAN_STA_WPS BIT(12) +#define WLAN_STA_MAYBE_WPS BIT(13) +#define WLAN_STA_NONERP BIT(31) + +#endif + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +#define IEEE_PARAM_WPAX_SELECT 7 + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 +#define AUTH_ALG_LEAP 0x00000004 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define WPA_CIPHER_NONE BIT(0) +#define WPA_CIPHER_WEP40 BIT(1) +#define WPA_CIPHER_WEP104 BIT(2) +#define WPA_CIPHER_TKIP BIT(3) +#define WPA_CIPHER_CCMP BIT(4) + + + +#define WPA_SELECTOR_LEN 4 +extern u8 RTW_WPA_OUI_TYPE[] ; +extern u16 RTW_WPA_VERSION ; +extern u8 WPA_AUTH_KEY_MGMT_NONE[]; +extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +extern u8 WPA_CIPHER_SUITE_NONE[]; +extern u8 WPA_CIPHER_SUITE_WEP40[]; +extern u8 WPA_CIPHER_SUITE_TKIP[]; +extern u8 WPA_CIPHER_SUITE_WRAP[]; +extern u8 WPA_CIPHER_SUITE_CCMP[]; +extern u8 WPA_CIPHER_SUITE_WEP104[]; + + +#define RSN_HEADER_LEN 4 +#define RSN_SELECTOR_LEN 4 + +extern u16 RSN_VERSION_BSD; +extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +extern u8 RSN_CIPHER_SUITE_NONE[]; +extern u8 RSN_CIPHER_SUITE_WEP40[]; +extern u8 RSN_CIPHER_SUITE_TKIP[]; +extern u8 RSN_CIPHER_SUITE_WRAP[]; +extern u8 RSN_CIPHER_SUITE_CCMP[]; +extern u8 RSN_CIPHER_SUITE_WEP104[]; + +typedef enum _RATR_TABLE_MODE{ + RATR_INX_WIRELESS_NGB = 0, // BGN 40 Mhz 2SS 1SS + RATR_INX_WIRELESS_NG = 1, // GN or N + RATR_INX_WIRELESS_NB = 2, // BGN 20 Mhz 2SS 1SS or BN + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_AC_N = 8, +}RATR_TABLE_MODE, *PRATR_TABLE_MODE; + +enum NETWORK_TYPE +{ + WIRELESS_INVALID = 0, + //Sub-Element + WIRELESS_11B = BIT(0), // tx: cck only , rx: cck only, hw: cck + WIRELESS_11G = BIT(1), // tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm + WIRELESS_11A = BIT(2), // tx: ofdm only, rx: ofdm only, hw: ofdm only + WIRELESS_11_24N = BIT(3), // tx: MCS only, rx: MCS & cck, hw: MCS & cck + WIRELESS_11_5N = BIT(4), // tx: MCS only, rx: MCS & ofdm, hw: ofdm only + //WIRELESS_AUTO = BIT(5), + WIRELESS_AC = BIT(6), + + //Combination + WIRELESS_11BG = (WIRELESS_11B|WIRELESS_11G), // tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm + WIRELESS_11G_24N = (WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm + WIRELESS_11A_5N = (WIRELESS_11A|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11BG_24N = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck + WIRELESS_11AGN = (WIRELESS_11A|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11ABGN = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), +}; + +#define SUPPORTED_24G_NETTYPE_MSK (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N) +#define SUPPORTED_5G_NETTYPE_MSK (WIRELESS_11A | WIRELESS_11_5N) + +#define IsSupported24G(NetType) ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? _TRUE : _FALSE) +#define IsSupported5G(NetType) ((NetType) & SUPPORTED_5G_NETTYPE_MSK ? _TRUE : _FALSE) + +#define IsEnableHWCCK(NetType) IsSupported24G(NetType) +#define IsEnableHWOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11_24N|SUPPORTED_5G_NETTYPE_MSK) ? _TRUE : _FALSE) + +#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType) +#define IsSupportedRxOFDM(NetType) IsEnableHWOFDM(NetType) +#define IsSupportedRxMCS(NetType) IsEnableHWOFDM(NetType) + +#define IsSupportedTxCCK(NetType) ((NetType) & (WIRELESS_11B) ? _TRUE : _FALSE) +#define IsSupportedTxOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11A) ? _TRUE : _FALSE) +#define IsSupportedTxMCS(NetType) ((NetType) & (WIRELESS_11_24N|WIRELESS_11_5N) ? _TRUE : _FALSE) + + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; +#ifdef CONFIG_AP_MODE + struct { + u16 aid; + u16 capability; + int flags; + u8 tx_supp_rates[16]; + struct rtw_ieee80211_ht_cap ht_cap; + } add_sta; + struct { + u8 reserved[2];//for set max_num_sta + u8 buf[0]; + } bcn_ie; +#endif + + } u; +}ieee_param; + +#ifdef CONFIG_AP_MODE +typedef struct ieee_param_ex { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + u8 data[0]; +}ieee_param_ex; + +struct sta_data{ + u16 aid; + u16 capability; + int flags; + u32 sta_set; + u8 tx_supp_rates[16]; + u32 tx_supp_rates_len; + struct rtw_ieee80211_ht_cap ht_cap; + u64 rx_pkts; + u64 rx_bytes; + u64 rx_drops; + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; +}; +#endif + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + + +#define IEEE80211_HLEN 30 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 + +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + _list list; +}; + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW)||defined(PLATFORM_FREEBSD) + +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +} __attribute__ ((packed)); + +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +} __attribute__ ((packed)); + + +struct rtw_ieee80211_hdr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 qc; +} __attribute__ ((packed)); + +struct rtw_ieee80211_hdr_3addr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u16 qc; +} __attribute__ ((packed)); + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__ ((packed)); + +#endif + + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +}; + +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +}; + + +struct rtw_ieee80211_hdr_qos { + struct rtw_ieee80211_hdr wlan_hdr; + u16 qc; +}; + +struct rtw_ieee80211_hdr_3addr_qos { + struct rtw_ieee80211_hdr_3addr wlan_hdr; + u16 qc; +}; + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +}; +#pragma pack() + +#endif + + + +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + +/* Frame control field constants */ +#define RTW_IEEE80211_FCTL_VERS 0x0003 +#define RTW_IEEE80211_FCTL_FTYPE 0x000c +#define RTW_IEEE80211_FCTL_STYPE 0x00f0 +#define RTW_IEEE80211_FCTL_TODS 0x0100 +#define RTW_IEEE80211_FCTL_FROMDS 0x0200 +#define RTW_IEEE80211_FCTL_MOREFRAGS 0x0400 +#define RTW_IEEE80211_FCTL_RETRY 0x0800 +#define RTW_IEEE80211_FCTL_PM 0x1000 +#define RTW_IEEE80211_FCTL_MOREDATA 0x2000 +#define RTW_IEEE80211_FCTL_PROTECTED 0x4000 +#define RTW_IEEE80211_FCTL_ORDER 0x8000 +#define RTW_IEEE80211_FCTL_CTL_EXT 0x0f00 + +#define RTW_IEEE80211_FTYPE_MGMT 0x0000 +#define RTW_IEEE80211_FTYPE_CTL 0x0004 +#define RTW_IEEE80211_FTYPE_DATA 0x0008 +#define RTW_IEEE80211_FTYPE_EXT 0x000c + +/* management */ +#define RTW_IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define RTW_IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define RTW_IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define RTW_IEEE80211_STYPE_PROBE_REQ 0x0040 +#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050 +#define RTW_IEEE80211_STYPE_BEACON 0x0080 +#define RTW_IEEE80211_STYPE_ATIM 0x0090 +#define RTW_IEEE80211_STYPE_DISASSOC 0x00A0 +#define RTW_IEEE80211_STYPE_AUTH 0x00B0 +#define RTW_IEEE80211_STYPE_DEAUTH 0x00C0 +#define RTW_IEEE80211_STYPE_ACTION 0x00D0 + +/* control */ +#define RTW_IEEE80211_STYPE_CTL_EXT 0x0060 +#define RTW_IEEE80211_STYPE_BACK_REQ 0x0080 +#define RTW_IEEE80211_STYPE_BACK 0x0090 +#define RTW_IEEE80211_STYPE_PSPOLL 0x00A0 +#define RTW_IEEE80211_STYPE_RTS 0x00B0 +#define RTW_IEEE80211_STYPE_CTS 0x00C0 +#define RTW_IEEE80211_STYPE_ACK 0x00D0 +#define RTW_IEEE80211_STYPE_CFEND 0x00E0 +#define RTW_IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define RTW_IEEE80211_STYPE_DATA 0x0000 +#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010 +#define RTW_IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define RTW_IEEE80211_STYPE_NULLFUNC 0x0040 +#define RTW_IEEE80211_STYPE_CFACK 0x0050 +#define RTW_IEEE80211_STYPE_CFPOLL 0x0060 +#define RTW_IEEE80211_STYPE_CFACKPOLL 0x0070 +#define RTW_IEEE80211_STYPE_QOS_DATA 0x0080 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 +#define RTW_IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 +#define RTW_IEEE80211_STYPE_QOS_CFACK 0x00D0 +#define RTW_IEEE80211_STYPE_QOS_CFPOLL 0x00E0 +#define RTW_IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 + +/* sequence control field */ +#define RTW_IEEE80211_SCTL_FRAG 0x000F +#define RTW_IEEE80211_SCTL_SEQ 0xFFF0 + + +#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0) +#define RTW_ERP_INFO_USE_PROTECTION BIT(1) +#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + +/* QoS,QOS */ +#define NORMAL_ACK 0 +#define NO_ACK 1 +#define NON_EXPLICIT_ACK 2 +#define BLOCK_ACK 3 + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#define ETH_P_ECONET 0x0018 + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) || defined(PLATFORM_FREEBSD) + +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +}; +#pragma pack() + +#endif + + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE) + +#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f) + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & RTW_IEEE80211_SCTL_SEQ) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) + +/* Status codes */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +/* 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/* Reason codes */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 +#define WLAN_REASON_EXPIRATION_CHK 65535 + +/* Information Element IDs */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARAMS 2 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_CHALLENGE 16 +/* EIDs defined by IEEE 802.11h - START */ +#define WLAN_EID_PWR_CONSTRAINT 32 +#define WLAN_EID_PWR_CAPABILITY 33 +#define WLAN_EID_TPC_REQUEST 34 +#define WLAN_EID_TPC_REPORT 35 +#define WLAN_EID_SUPPORTED_CHANNELS 36 +#define WLAN_EID_CHANNEL_SWITCH 37 +#define WLAN_EID_MEASURE_REQUEST 38 +#define WLAN_EID_MEASURE_REPORT 39 +#define WLAN_EID_QUITE 40 +#define WLAN_EID_IBSS_DFS 41 +/* EIDs defined by IEEE 802.11h - END */ +#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_SUPP_RATES 50 +#define WLAN_EID_MOBILITY_DOMAIN 54 +#define WLAN_EID_FAST_BSS_TRANSITION 55 +#define WLAN_EID_TIMEOUT_INTERVAL 56 +#define WLAN_EID_RIC_DATA 57 +#define WLAN_EID_HT_OPERATION 61 +#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 +#define WLAN_EID_20_40_BSS_COEXISTENCE 72 +#define WLAN_EID_20_40_BSS_INTOLERANT 73 +#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 +#define WLAN_EID_MMIE 76 +#define WLAN_EID_VENDOR_SPECIFIC 221 +#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) + +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_NUM_OFDM_RATESLEN 8 + + +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + + + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { + //u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 received_channel; + u16 rate; /* in 100 kbps */ + //u8 control; + u8 mask; + u8 freq; + u16 len; +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + u32 first_frag_time; + uint seq; + uint last_frag; + uint qos; //jackson + uint tid; //jackson + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined +struct ieee80211_stats { + uint tx_unicast_frames; + uint tx_multicast_frames; + uint tx_fragments; + uint tx_unicast_octets; + uint tx_multicast_octets; + uint tx_deferred_transmissions; + uint tx_single_retry_frames; + uint tx_multiple_retry_frames; + uint tx_retry_limit_exceeded; + uint tx_discards; + uint rx_unicast_frames; + uint rx_multicast_frames; + uint rx_fragments; + uint rx_unicast_octets; + uint rx_multicast_octets; + uint rx_fcs_errors; + uint rx_discards_no_buffer; + uint tx_discards_wrong_sa; + uint rx_discards_undecryptable; + uint rx_message_in_msg_fragments; + uint rx_message_in_bad_msg_fragments; +}; +#endif //PLATFORM_FREEBSD +struct ieee80211_softmac_stats{ + uint rx_ass_ok; + uint rx_ass_err; + uint rx_probe_rq; + uint tx_probe_rs; + uint tx_beacons; + uint rx_auth_rq; + uint rx_auth_rs_ok; + uint rx_auth_rs_err; + uint tx_auth_rq; + uint no_auth_rs; + uint no_ass_rs; + uint tx_ass_rq; + uint rx_ass_rq; + uint tx_probe_rq; + uint reassoc; + uint swtxstop; + uint swtxawake; +}; + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 + +#ifdef CONFIG_IEEE80211W +#define BIP_MAX_KEYID 5 +#define BIP_AAD_SIZE 20 +#endif //CONFIG_IEEE80211W + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} ; +#pragma pack() + +#endif + +/* + + 802.11 data frame from AP + + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' + +Total: 28-2340 bytes + +*/ + +struct ieee80211_header_data { + u16 frame_ctl; + u16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + u16 seq_ctrl; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +/* Management Frame Information Element Types */ +#define MFIE_TYPE_SSID 0 +#define MFIE_TYPE_RATES 1 +#define MFIE_TYPE_FH_SET 2 +#define MFIE_TYPE_DS_SET 3 +#define MFIE_TYPE_CF_SET 4 +#define MFIE_TYPE_TIM 5 +#define MFIE_TYPE_IBSS_SET 6 +#define MFIE_TYPE_CHALLENGE 16 +#define MFIE_TYPE_ERP 42 +#define MFIE_TYPE_RSN 48 +#define MFIE_TYPE_RATES_EX 50 +#define MFIE_TYPE_GENERIC 221 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} ; + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} ; +#pragma pack() + +#endif + + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 10 + + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} __attribute__ ((packed)); + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +} __attribute__ ((packed)); +#endif + + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} ; + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} ; + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} ; + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} ; + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +}; + +#pragma pack() + +#endif + + + + +struct ieee80211_txb { + u8 nr_frags; + u8 encrypted; + u16 reserved; + u16 frag_size; + u16 payload_size; + struct sk_buff *fragments[0]; +}; + + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 +#define MAX_CHANNEL_NUMBER 161 +#define IEEE80211_SOFTMAC_SCAN_TIME 400 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN (256) +#define MAX_WPS_IE_LEN (512) +#define MAX_P2P_IE_LEN (256) +#define MAX_WFD_IE_LEN (128) + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST +#define IW_ESSID_MAX_SIZE 32 +#if 0 +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + u8 rssi; //relative signal strength + u8 sq; //signal quality + + /* These are network statistics */ + //struct ieee80211_rx_stats stats; + u16 capability; + u16 aid; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + + u8 edca_parmsets[18]; + + u8 mode; + u8 flags; + u8 time_stamp[8]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + u8 country[6]; + u8 dtim_period; + u8 dtim_data; + u8 power_constraint; + u8 qosinfo; + u8 qbssload[5]; + u8 network_type; + int join_res; + unsigned long last_scanned; +}; +#endif +/* +join_res: +-1: authentication fail +-2: association fail +> 0: TID +*/ + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined + +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, + +}; +#endif //PLATFORM_FREEBSD + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] + +#ifdef PLATFORM_FREEBSD //Baron change func to macro +#define is_multicast_mac_addr(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff)) +#define is_broadcast_mac_addr(Addr) ((((Addr[0]) & 0xff) == 0xff) && (((Addr[1]) & 0xff) == 0xff) && \ +(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ +(((Addr[5]) & 0xff) == 0xff)) +#else +extern __inline int is_multicast_mac_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} + +extern __inline int is_broadcast_mac_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} + +extern __inline int is_zero_mac_addr(const u8 *addr) +{ + return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ + (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); +} +#endif //PLATFORM_FREEBSD + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) + +typedef struct tx_pending_t{ + int frag; + struct ieee80211_txb *txb; +}tx_pending_t; + + + +#define MAXTID 16 + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +//Baron move to ieee80211.c +int ieee80211_is_empty_essid(const char *essid, int essid_len); +int ieee80211_get_hdrlen(u16 fc); + +#if 0 +/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_WMM 17 +#endif + + +/* Action category code */ +enum rtw_ieee80211_category { + RTW_WLAN_CATEGORY_SPECTRUM_MGMT = 0, + RTW_WLAN_CATEGORY_QOS = 1, + RTW_WLAN_CATEGORY_DLS = 2, + RTW_WLAN_CATEGORY_BACK = 3, + RTW_WLAN_CATEGORY_PUBLIC = 4, //IEEE 802.11 public action frames + RTW_WLAN_CATEGORY_RADIO_MEASUREMENT = 5, + RTW_WLAN_CATEGORY_FT = 6, + RTW_WLAN_CATEGORY_HT = 7, + RTW_WLAN_CATEGORY_SA_QUERY = 8, + RTW_WLAN_CATEGORY_UNPROTECTED_WNM = 11, // add for CONFIG_IEEE80211W, none 11w also can use + RTW_WLAN_CATEGORY_TDLS = 12, + RTW_WLAN_CATEGORY_SELF_PROTECTED = 15, // add for CONFIG_IEEE80211W, none 11w also can use + RTW_WLAN_CATEGORY_WMM = 17, + RTW_WLAN_CATEGORY_P2P = 0x7f,//P2P action frames +}; + +/* SPECTRUM_MGMT action code */ +enum rtw_ieee80211_spectrum_mgmt_actioncode { + RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, + RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, + RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, + RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, + RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, + RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, +}; + +enum _PUBLIC_ACTION{ + ACT_PUBLIC_BSSCOEXIST = 0, // 20/40 BSS Coexistence + ACT_PUBLIC_DSE_ENABLE = 1, + ACT_PUBLIC_DSE_DEENABLE = 2, + ACT_PUBLIC_DSE_REG_LOCATION = 3, + ACT_PUBLIC_EXT_CHL_SWITCH = 4, + ACT_PUBLIC_DSE_MSR_REQ = 5, + ACT_PUBLIC_DSE_MSR_RPRT = 6, + ACT_PUBLIC_MP = 7, // Measurement Pilot + ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, + ACT_PUBLIC_VENDOR = 9, // for WIFI_DIRECT + ACT_PUBLIC_GAS_INITIAL_REQ = 10, + ACT_PUBLIC_GAS_INITIAL_RSP = 11, + ACT_PUBLIC_GAS_COMEBACK_REQ = 12, + ACT_PUBLIC_GAS_COMEBACK_RSP = 13, + ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, + ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_MAX +}; + +#ifdef CONFIG_TDLS +enum TDLS_ACTION_FIELD{ + TDLS_SETUP_REQUEST = 0, + TDLS_SETUP_RESPONSE = 1, + TDLS_SETUP_CONFIRM = 2, + TDLS_TEARDOWN = 3, + TDLS_PEER_TRAFFIC_INDICATION = 4, + TDLS_CHANNEL_SWITCH_REQUEST = 5, + TDLS_CHANNEL_SWITCH_RESPONSE = 6, + TDLS_PEER_PSM_REQUEST = 7, + TDLS_PEER_PSM_RESPONSE = 8, + TDLS_PEER_TRAFFIC_RESPONSE = 9, + TDLS_DISCOVERY_REQUEST = 10, + TDLS_DISCOVERY_RESPONSE = 14, //it's used in public action frame +}; + +#define TUNNELED_PROBE_REQ 15 +#define TUNNELED_PROBE_RSP 16 +#endif //CONFIG_TDLS + +/* BACK action code */ +enum rtw_ieee80211_back_actioncode { + RTW_WLAN_ACTION_ADDBA_REQ = 0, + RTW_WLAN_ACTION_ADDBA_RESP = 1, + RTW_WLAN_ACTION_DELBA = 2, +}; + +/* HT features action code */ +enum rtw_ieee80211_ht_actioncode { + RTW_WLAN_ACTION_NOTIFY_CH_WIDTH = 0, + RTW_WLAN_ACTION_SM_PS = 1, + RTW_WLAN_ACTION_PSPM = 2, + RTW_WLAN_ACTION_PCO_PHASE = 3, + RTW_WLAN_ACTION_MIMO_CSI_MX = 4, + RTW_WLAN_ACTION_MIMO_NONCP_BF = 5, + RTW_WLAN_ACTION_MIMP_CP_BF = 6, + RTW_WLAN_ACTION_ASEL_INDICATES_FB = 7, + RTW_WLAN_ACTION_HI_INFO_EXCHG = 8, +}; + +/* BACK (block-ack) parties */ +enum rtw_ieee80211_back_parties { + RTW_WLAN_BACK_RECIPIENT = 0, + RTW_WLAN_BACK_INITIATOR = 1, + RTW_WLAN_BACK_TIMER = 2, +}; + + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ +#ifndef PLATFORM_FREEBSD //Baron BSD has defined +#define WME_OUI_TYPE 2 +#endif //PLATFORM_FREEBSD +#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WME_VERSION 1 + +#define WME_ACTION_CODE_SETUP_REQUEST 0 +#define WME_ACTION_CODE_SETUP_RESPONSE 1 +#define WME_ACTION_CODE_TEARDOWN 2 + +#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 +#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 +#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 + +#define WME_TSPEC_DIRECTION_UPLINK 0 +#define WME_TSPEC_DIRECTION_DOWNLINK 1 +#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + + +#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ + +#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ + +/** + * enum rtw_ieee80211_channel_flags - channel flags + * + * Channel flags set by the regulatory control code. + * + * @RTW_IEEE80211_CHAN_DISABLED: This channel is disabled. + * @RTW_IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted + * on this channel. + * @RTW_IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. + * @RTW_IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @RTW_IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel + * is not permitted. + * @RTW_IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel + * is not permitted. + */ + enum rtw_ieee80211_channel_flags { + RTW_IEEE80211_CHAN_DISABLED = 1<<0, + RTW_IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, + RTW_IEEE80211_CHAN_NO_IBSS = 1<<2, + RTW_IEEE80211_CHAN_RADAR = 1<<3, + RTW_IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + RTW_IEEE80211_CHAN_NO_HT40MINUS = 1<<5, + }; + + #define RTW_IEEE80211_CHAN_NO_HT40 \ + (RTW_IEEE80211_CHAN_NO_HT40PLUS | RTW_IEEE80211_CHAN_NO_HT40MINUS) + +/* Represent channel details, subset of ieee80211_channel */ +struct rtw_ieee80211_channel { + //enum ieee80211_band band; + //u16 center_freq; + u16 hw_value; + u32 flags; + //int max_antenna_gain; + //int max_power; + //int max_reg_power; + //bool beacon_found; + //u32 orig_flags; + //int orig_mag; + //int orig_mpwr; +}; + +#define CHAN_FMT \ + /*"band:%d, "*/ \ + /*"center_freq:%u, "*/ \ + "hw_value:%u, " \ + "flags:0x%08x" \ + /*"max_antenna_gain:%d\n"*/ \ + /*"max_power:%d\n"*/ \ + /*"max_reg_power:%d\n"*/ \ + /*"beacon_found:%u\n"*/ \ + /*"orig_flags:0x%08x\n"*/ \ + /*"orig_mag:%d\n"*/ \ + /*"orig_mpwr:%d\n"*/ + +#define CHAN_ARG(channel) \ + /*(channel)->band*/ \ + /*, (channel)->center_freq*/ \ + (channel)->hw_value \ + , (channel)->flags \ + /*, (channel)->max_antenna_gain*/ \ + /*, (channel)->max_power*/ \ + /*, (channel)->max_reg_power*/ \ + /*, (channel)->beacon_found*/ \ + /*, (channel)->orig_flags*/ \ + /*, (channel)->orig_mag*/ \ + /*, (channel)->orig_mpwr*/ \ + +/* Parsed Information Elements */ +struct rtw_ieee802_11_elems { + u8 *ssid; + u8 ssid_len; + u8 *supp_rates; + u8 supp_rates_len; + u8 *fh_params; + u8 fh_params_len; + u8 *ds_params; + u8 ds_params_len; + u8 *cf_params; + u8 cf_params_len; + u8 *tim; + u8 tim_len; + u8 *ibss_params; + u8 ibss_params_len; + u8 *challenge; + u8 challenge_len; + u8 *erp_info; + u8 erp_info_len; + u8 *ext_supp_rates; + u8 ext_supp_rates_len; + u8 *wpa_ie; + u8 wpa_ie_len; + u8 *rsn_ie; + u8 rsn_ie_len; + u8 *wme; + u8 wme_len; + u8 *wme_tspec; + u8 wme_tspec_len; + u8 *wps_ie; + u8 wps_ie_len; + u8 *power_cap; + u8 power_cap_len; + u8 *supp_channels; + u8 supp_channels_len; + u8 *mdie; + u8 mdie_len; + u8 *ftie; + u8 ftie_len; + u8 *timeout_int; + u8 timeout_int_len; + u8 *ht_capabilities; + u8 ht_capabilities_len; + u8 *ht_operation; + u8 ht_operation_len; + u8 *vendor_ht_cap; + u8 vendor_ht_cap_len; +}; + +typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; + +ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, + struct rtw_ieee802_11_elems *elems, + int show_errors); + +u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen); +u8 *rtw_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen); + +enum secondary_ch_offset { + SCN = 0, /* no secondary channel */ + SCA = 1, /* secondary channel above */ + SCB = 3, /* secondary channel below */ +}; +u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset); +u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset); +u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt); +u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset); +u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, u8 flags, u16 reason, u16 precedence); + +u8 *rtw_get_ie(u8*pbuf, sint index, sint *len, sint limit); +u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen); +int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len); + +void rtw_set_supported_rate(u8* SupportedRates, uint mode) ; + +unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit); +unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); +int rtw_get_wpa_cipher_suite(u8 *s); +int rtw_get_wpa2_cipher_suite(u8 *s); +int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher); +int rtw_parse_wpa2_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher); + +int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len); + +u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); +u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); +u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content); + +/** + * for_each_ie - iterate over continuous IEs + * @ie: + * @buf: + * @buf_len: + */ +#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); + +#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); +u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen); +u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content); +u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr); +void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif + +#ifdef CONFIG_WFD +int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); +int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen); +#endif // CONFIG_WFD + +uint rtw_get_rateset_len(u8 *rateset); + +struct registry_priv; +int rtw_generate_ie(struct registry_priv *pregistrypriv); + + +int rtw_get_bit_value_from_ieee_value(u8 val); + +uint rtw_is_cckrates_included(u8 *rate); + +uint rtw_is_cckratesonly_included(u8 *rate); + +int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); + +void rtw_macaddr_cfg(u8 *mac_addr); + +u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char * MCS_rate); + +int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8* category, u8 *action); +const char *action_public_str(u8 action); + +#endif /* IEEE80211_H */ + diff --git a/rtl8192cu-fixes/include/ieee80211_ext.h b/rtl8192cu-fixes/include/ieee80211_ext.h new file mode 100755 index 00000000..3e55305e --- /dev/null +++ b/rtl8192cu-fixes/include/ieee80211_ext.h @@ -0,0 +1,477 @@ +/****************************************************************************** + * + * 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 __IEEE80211_EXT_H +#define __IEEE80211_EXT_H + +#include +#include +#include + +#define WMM_OUI_TYPE 2 +#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WMM_VERSION 1 + +#define WPA_PROTO_WPA BIT(0) +#define WPA_PROTO_RSN BIT(1) + +#define WPA_KEY_MGMT_IEEE8021X BIT(0) +#define WPA_KEY_MGMT_PSK BIT(1) +#define WPA_KEY_MGMT_NONE BIT(2) +#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3) +#define WPA_KEY_MGMT_WPA_NONE BIT(4) + + +#define WPA_CAPABILITY_PREAUTH BIT(0) +#define WPA_CAPABILITY_MGMT_FRAME_PROTECTION BIT(6) +#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) + + +#define PMKID_LEN 16 + + +#ifdef PLATFORM_LINUX +struct wpa_ie_hdr { + u8 elem_id; + u8 len; + u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ + u8 version[2]; /* little endian */ +}__attribute__ ((packed)); + +struct rsn_ie_hdr { + u8 elem_id; /* WLAN_EID_RSN */ + u8 len; + u8 version[2]; /* little endian */ +}__attribute__ ((packed)); + +struct wme_ac_parameter { +#if defined(CONFIG_LITTLE_ENDIAN) + /* byte 1 */ + u8 aifsn:4, + acm:1, + aci:2, + reserved:1; + + /* byte 2 */ + u8 eCWmin:4, + eCWmax:4; +#elif defined(CONFIG_BIG_ENDIAN) + /* byte 1 */ + u8 reserved:1, + aci:2, + acm:1, + aifsn:4; + + /* byte 2 */ + u8 eCWmax:4, + eCWmin:4; +#else +#error "Please fix " +#endif + + /* bytes 3 & 4 */ + u16 txopLimit; +} __attribute__ ((packed)); + +struct wme_parameter_element { + /* required fields for WME version 1 */ + u8 oui[3]; + u8 oui_type; + u8 oui_subtype; + u8 version; + u8 acInfo; + u8 reserved; + struct wme_ac_parameter ac[4]; + +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct wpa_ie_hdr { + u8 elem_id; + u8 len; + u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ + u8 version[2]; /* little endian */ +}; + +struct rsn_ie_hdr { + u8 elem_id; /* WLAN_EID_RSN */ + u8 len; + u8 version[2]; /* little endian */ +}; + +#pragma pack() + +#endif + +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val)) +//#define RSN_SELECTOR_PUT(a, val) WPA_PUT_LE32((u8 *) (a), (val)) + + + +/* Action category code */ +enum ieee80211_category { + WLAN_CATEGORY_SPECTRUM_MGMT = 0, + WLAN_CATEGORY_QOS = 1, + WLAN_CATEGORY_DLS = 2, + WLAN_CATEGORY_BACK = 3, + WLAN_CATEGORY_HT = 7, + WLAN_CATEGORY_WMM = 17, +}; + +/* SPECTRUM_MGMT action code */ +enum ieee80211_spectrum_mgmt_actioncode { + WLAN_ACTION_SPCT_MSR_REQ = 0, + WLAN_ACTION_SPCT_MSR_RPRT = 1, + WLAN_ACTION_SPCT_TPC_REQ = 2, + WLAN_ACTION_SPCT_TPC_RPRT = 3, + WLAN_ACTION_SPCT_CHL_SWITCH = 4, + WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, +}; + +/* BACK action code */ +enum ieee80211_back_actioncode { + WLAN_ACTION_ADDBA_REQ = 0, + WLAN_ACTION_ADDBA_RESP = 1, + WLAN_ACTION_DELBA = 2, +}; + +/* HT features action code */ +enum ieee80211_ht_actioncode { + WLAN_ACTION_NOTIFY_CH_WIDTH = 0, + WLAN_ACTION_SM_PS = 1, + WLAN_ACTION_PSPM = 2, + WLAN_ACTION_PCO_PHASE = 3, + WLAN_ACTION_MIMO_CSI_MX = 4, + WLAN_ACTION_MIMO_NONCP_BF = 5, + WLAN_ACTION_MIMP_CP_BF = 6, + WLAN_ACTION_ASEL_INDICATES_FB = 7, + WLAN_ACTION_HI_INFO_EXCHG = 8, +}; + +/* BACK (block-ack) parties */ +enum ieee80211_back_parties { + WLAN_BACK_RECIPIENT = 0, + WLAN_BACK_INITIATOR = 1, + WLAN_BACK_TIMER = 2, +}; + +#ifdef PLATFORM_LINUX + +struct ieee80211_mgmt { + u16 frame_control; + u16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + u16 seq_ctrl; + union { + struct { + u16 auth_alg; + u16 auth_transaction; + u16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } __attribute__ ((packed)) auth; + struct { + u16 reason_code; + } __attribute__ ((packed)) deauth; + struct { + u16 capab_info; + u16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) assoc_req; + struct { + u16 capab_info; + u16 status_code; + u16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) assoc_resp, reassoc_resp; + struct { + u16 capab_info; + u16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) reassoc_req; + struct { + u16 reason_code; + } __attribute__ ((packed)) disassoc; + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } __attribute__ ((packed)) beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) probe_req; + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } __attribute__ ((packed)) probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } __attribute__ ((packed)) wme_action; +#if 0 + struct{ + u8 action_code; + u8 element_id; + u8 length; + struct ieee80211_channel_sw_ie sw_elem; + } __attribute__ ((packed)) chan_switch; + struct{ + u8 action_code; + u8 dialog_token; + u8 element_id; + u8 length; + struct ieee80211_msrment_ie msr_elem; + } __attribute__ ((packed)) measurement; +#endif + struct{ + u8 action_code; + u8 dialog_token; + u16 capab; + u16 timeout; + u16 start_seq_num; + } __attribute__ ((packed)) addba_req; + struct{ + u8 action_code; + u8 dialog_token; + u16 status; + u16 capab; + u16 timeout; + } __attribute__ ((packed)) addba_resp; + struct{ + u8 action_code; + u16 params; + u16 reason_code; + } __attribute__ ((packed)) delba; + struct{ + u8 action_code; + /* capab_info for open and confirm, + * reason for close + */ + u16 aux; + /* Followed in plink_confirm by status + * code, AID and supported rates, + * and directly by supported rates in + * plink_open and plink_close + */ + u8 variable[0]; + } __attribute__ ((packed)) plink_action; + struct{ + u8 action_code; + u8 variable[0]; + } __attribute__ ((packed)) mesh_action; + } __attribute__ ((packed)) u; + } __attribute__ ((packed)) action; + } __attribute__ ((packed)) u; +}__attribute__ ((packed)); + +#endif + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct ieee80211_mgmt { + u16 frame_control; + u16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + u16 seq_ctrl; + union { + struct { + u16 auth_alg; + u16 auth_transaction; + u16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } auth; + struct { + u16 reason_code; + } deauth; + struct { + u16 capab_info; + u16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } assoc_req; + struct { + u16 capab_info; + u16 status_code; + u16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } assoc_resp, reassoc_resp; + struct { + u16 capab_info; + u16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } reassoc_req; + struct { + u16 reason_code; + } disassoc; +#if 0 + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } probe_req; + + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } probe_resp; +#endif + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } wme_action; +/* + struct{ + u8 action_code; + u8 element_id; + u8 length; + struct ieee80211_channel_sw_ie sw_elem; + } chan_switch; + struct{ + u8 action_code; + u8 dialog_token; + u8 element_id; + u8 length; + struct ieee80211_msrment_ie msr_elem; + } measurement; +*/ + struct{ + u8 action_code; + u8 dialog_token; + u16 capab; + u16 timeout; + u16 start_seq_num; + } addba_req; + struct{ + u8 action_code; + u8 dialog_token; + u16 status; + u16 capab; + u16 timeout; + } addba_resp; + struct{ + u8 action_code; + u16 params; + u16 reason_code; + } delba; + struct{ + u8 action_code; + /* capab_info for open and confirm, + * reason for close + */ + u16 aux; + /* Followed in plink_confirm by status + * code, AID and supported rates, + * and directly by supported rates in + * plink_open and plink_close + */ + u8 variable[0]; + } plink_action; + struct{ + u8 action_code; + u8 variable[0]; + } mesh_action; + } u; + } action; + } u; +} ; + +#pragma pack() + +#endif + +/* mgmt header + 1 byte category code */ +#define IEEE80211_MIN_ACTION_SIZE FIELD_OFFSET(struct ieee80211_mgmt, u.action.u) + + + +#endif + diff --git a/rtl8192cu-fixes/include/if_ether.h b/rtl8192cu-fixes/include/if_ether.h new file mode 100755 index 00000000..9e36d7fa --- /dev/null +++ b/rtl8192cu-fixes/include/if_ether.h @@ -0,0 +1,112 @@ +/****************************************************************************** + * + * 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 _LINUX_IF_ETHER_H +#define _LINUX_IF_ETHER_H + +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ + +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ +#define ETH_DATA_LEN 1500 /* Max. octets in payload */ +#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + +/* + * These are the defined Ethernet Protocol ID's. + */ + +#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ +#define ETH_P_PUP 0x0200 /* Xerox PUP packet */ +#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_X25 0x0805 /* CCITT X.25 */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ +#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ +#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ +#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ +#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ +#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ +#define ETH_P_LAT 0x6004 /* DEC LAT */ +#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ +#define ETH_P_CUST 0x6006 /* DEC Customer use */ +#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ +#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ +#define ETH_P_ATALK 0x809B /* Appletalk DDP */ +#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ +#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define ETH_P_IPX 0x8137 /* IPX over DIX */ +#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ +#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ +#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport + * over Ethernet + */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + +#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ +#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ +#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ +#define ETH_P_802_2 0x0004 /* 802.2 frames */ +#define ETH_P_SNAP 0x0005 /* Internal only */ +#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ +#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ +#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ +#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ +#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ +#define ETH_P_CONTROL 0x0016 /* Card specific control frames */ +#define ETH_P_IRDA 0x0017 /* Linux-IrDA */ +#define ETH_P_ECONET 0x0018 /* Acorn Econet */ + +/* + * This is an Ethernet frame header. + */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; + +struct _vlan { + unsigned short h_vlan_TCI; // Encapsulates priority and VLAN ID + unsigned short h_vlan_encapsulated_proto; +}; + + + +#define get_vlan_id(pvlan) ((ntohs((unsigned short )pvlan->h_vlan_TCI)) & 0xfff) +#define get_vlan_priority(pvlan) ((ntohs((unsigned short )pvlan->h_vlan_TCI))>>13) +#define get_vlan_encap_proto(pvlan) (ntohs((unsigned short )pvlan->h_vlan_encapsulated_proto)) + + +#endif /* _LINUX_IF_ETHER_H */ diff --git a/rtl8192cu-fixes/include/ioctl_cfg80211.h b/rtl8192cu-fixes/include/ioctl_cfg80211.h new file mode 100755 index 00000000..48d06c74 --- /dev/null +++ b/rtl8192cu-fixes/include/ioctl_cfg80211.h @@ -0,0 +1,180 @@ +/****************************************************************************** + * + * 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(CONFIG_IOCTL_CFG80211) && !defined(CONFIG_CFG80211) && !defined(CONFIG_CFG80211_MODULE) + #error "Can't define CONFIG_IOCTL_CFG80211 because neither CONFIG_CFG80211 nor CONFIG_CFG80211_MODULE is defined in kernel" +#endif +#if defined(CONFIG_IOCTL_CFG80211) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) + #error "We haven't verify our cfg80211 solution below kernel version 2.6.35" +#endif + +#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, 3: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 wdev_to_priv(w) ((struct rtw_wdev_priv *)(wdev_priv(w))) + +#define wiphy_to_adapter(x) (_adapter *)(((struct rtw_wdev_priv*)wiphy_priv(x))->padapter) + +#define wiphy_to_wdev(x) (struct wireless_dev *)(((struct rtw_wdev_priv*)wiphy_priv(x))->rtw_wdev) + +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_surveydone_event_callback(_adapter *padapter); +int rtw_cfg80211_check_bss(_adapter *padapter); +void rtw_cfg80211_indicate_connect(_adapter *padapter); +void rtw_cfg80211_indicate_disconnect(_adapter *padapter); +void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, 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) +#else +#define rtw_cfg80211_rx_mgmt(adapter, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt((adapter)->rtw_wdev, freq, sig_dbm, buf, len, 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 + +#endif //__IOCTL_CFG80211_H__ + diff --git a/rtl8192cu-fixes/include/ip.h b/rtl8192cu-fixes/include/ip.h new file mode 100755 index 00000000..d7f723d2 --- /dev/null +++ b/rtl8192cu-fixes/include/ip.h @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * 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 _LINUX_IP_H +#define _LINUX_IP_H +#include + +/* SOL_IP socket options */ + +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_MINCOST 0x02 + +#define IPTOS_PREC_MASK 0xE0 +#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* IP options */ +#define IPOPT_COPY 0x80 +#define IPOPT_CLASS_MASK 0x60 +#define IPOPT_NUMBER_MASK 0x1f + +#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) +#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) +#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_MEASUREMENT 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_END (0 |IPOPT_CONTROL) +#define IPOPT_NOOP (1 |IPOPT_CONTROL) +#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) +#define IPOPT_RR (7 |IPOPT_CONTROL) +#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY) + +#define IPVERSION 4 +#define MAXTTL 255 +#define IPDEFTTL 64 + +/* struct timestamp, struct route and MAX_ROUTES are removed. + + REASONS: it is clear that nobody used them because: + - MAX_ROUTES value was wrong. + - "struct route" was wrong. + - "struct timestamp" had fatally misaligned bitfields and was completely unusable. + */ + +#define IPOPT_OPTVAL 0 +#define IPOPT_OLEN 1 +#define IPOPT_OFFSET 2 +#define IPOPT_MINOFF 4 +#define MAX_IPOPTLEN 40 +#define IPOPT_NOP IPOPT_NOOP +#define IPOPT_EOL IPOPT_END +#define IPOPT_TS IPOPT_TIMESTAMP + +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +#ifdef PLATFORM_LINUX + +struct ip_options { + __u32 faddr; /* Saved first hop address */ + unsigned char optlen; + unsigned char srr; + unsigned char rr; + unsigned char ts; + unsigned char is_setbyuser:1, /* Set by setsockopt? */ + is_data:1, /* Options in __data, rather than skb */ + is_strictroute:1, /* Strict source route */ + srr_is_hit:1, /* Packet destination addr was our one */ + is_changed:1, /* IP checksum more not valid */ + rr_needaddr:1, /* Need to record addr of outgoing dev */ + ts_needtime:1, /* Need to record timestamp */ + ts_needaddr:1; /* Need to record addr of outgoing dev */ + unsigned char router_alert; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __data[0]; +}; + +#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) +#endif + +struct iphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +#error "Please fix " +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; + /*The options start here. */ +}; + +#endif /* _LINUX_IP_H */ diff --git a/rtl8192cu-fixes/include/linux/wireless.h b/rtl8192cu-fixes/include/linux/wireless.h new file mode 100755 index 00000000..24a22d63 --- /dev/null +++ b/rtl8192cu-fixes/include/linux/wireless.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * + * 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 _LINUX_WIRELESS_H +#define _LINUX_WIRELESS_H + +/***************************** INCLUDES *****************************/ + +#if 0 +#include /* for __u* and __s* typedefs */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#else +#define __user +//typedef uint16_t __u16; +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#endif + +/****************************** TYPES ******************************/ + +/* --------------------------- SUBTYPES --------------------------- */ +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + + +/* ------------------------ IOCTL REQUEST ------------------------ */ +/* + * This structure defines the payload of an ioctl, and is used + * below. + * + * Note that this structure should fit on the memory footprint + * of iwreq (which is the same as ifreq), which mean a max size of + * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... + * You should check this when increasing the structures defined + * above in this file... + */ +union iwreq_data +{ + /* Config - generic */ + char name[IFNAMSIZ]; + /* Name : used to verify the presence of wireless extensions. + * Name of the protocol/provider... */ + + struct iw_point data; /* Other large parameters */ +}; + +/* + * The structure to exchange data for ioctl. + * This structure is the same as 'struct ifreq', but (re)defined for + * convenience... + * Do I need to remind you about structure size (32 octets) ? + */ +struct iwreq +{ + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + } ifr_ifrn; + + /* Data part (defined just above) */ + union iwreq_data u; +}; + +#endif /* _LINUX_WIRELESS_H */ diff --git a/rtl8192cu-fixes/include/mlme_osdep.h b/rtl8192cu-fixes/include/mlme_osdep.h new file mode 100755 index 00000000..75754db1 --- /dev/null +++ b/rtl8192cu-fixes/include/mlme_osdep.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * 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 __MLME_OSDEP_H_ +#define __MLME_OSDEP_H_ + +#include +#include +#include + +#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_MPIXEL) +extern int time_after(u32 now, u32 old); +#endif + +extern void rtw_init_mlme_timer(_adapter *padapter); +extern void rtw_os_indicate_disconnect( _adapter *adapter ); +extern void rtw_os_indicate_connect( _adapter *adapter ); +void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted); +extern void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie); + +void rtw_reset_securitypriv( _adapter *adapter ); + +#endif //_MLME_OSDEP_H_ + diff --git a/rtl8192cu-fixes/include/mp_custom_oid.h b/rtl8192cu-fixes/include/mp_custom_oid.h new file mode 100755 index 00000000..5f867381 --- /dev/null +++ b/rtl8192cu-fixes/include/mp_custom_oid.h @@ -0,0 +1,353 @@ +/****************************************************************************** + * + * 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 __CUSTOM_OID_H +#define __CUSTOM_OID_H + +// by Owen +// 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit +// 0xFF818500 - 0xFF81850F RTL8185 Setup Utility +// 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility + +// + +// by Owen for Production Kit +// For Production Kit with Agilent Equipments +// in order to make our custom oids hopefully somewhat unique +// we will use 0xFF (indicating implementation specific OID) +// 81(first byte of non zero Realtek unique identifier) +// 80 (second byte of non zero Realtek unique identifier) +// XX (the custom OID number - providing 255 possible custom oids) + +#define OID_RT_PRO_RESET_DUT 0xFF818000 +#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 +#define OID_RT_PRO_START_TEST 0xFF818002 +#define OID_RT_PRO_STOP_TEST 0xFF818003 +#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 +#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 +#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 +#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 +#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 +#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 +#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A + +#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D +#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E +#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F +#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 +#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 +#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 +#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 +#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 +#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 +#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 +#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 +#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 +#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 +#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A +#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B +#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C +#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D +#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E +#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F +#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 +#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 +#define OID_RT_PRO_READ_EEPROM 0xFF818022 +#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 +#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 +#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 +#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 +#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 +#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 +#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 +#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A +#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C +// added by Owen on 04/08/03 for Cameo's request +#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D +#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E +#define OID_RT_PRO_SET_MODULATION 0xFF81802F +// + +//Sean +#define OID_RT_DRIVER_OPTION 0xFF818080 +#define OID_RT_RF_OFF 0xFF818081 +#define OID_RT_AUTH_STATUS 0xFF818082 + +//======================================================================== +#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B +#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C +#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B +#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 +//======================================================================== + + +// by Owen for RTL8185 Phy Status Report Utility +#define OID_RT_UTILITY_FALSE_ALARM_COUNTERS 0xFF818580 +#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 +#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 +#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 +#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 +#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS 0xFF818585 +#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 +// + +// by Owen on 03/09/19-03/09/22 for RTL8185 +#define OID_RT_WIRELESS_MODE 0xFF818500 +#define OID_RT_SUPPORTED_RATES 0xFF818501 +#define OID_RT_DESIRED_RATES 0xFF818502 +#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 +// + +#define OID_RT_GET_CONNECT_STATE 0xFF030001 +#define OID_RT_RESCAN 0xFF030002 +#define OID_RT_SET_KEY_LENGTH 0xFF030003 +#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 + +#define OID_RT_SET_CHANNEL 0xFF010182 +#define OID_RT_SET_SNIFFER_MODE 0xFF010183 +#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 +#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 +#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 +#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 +#define OID_RT_GET_TX_RETRY 0xFF010188 +#define OID_RT_GET_RX_RETRY 0xFF010189 +#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A//S +#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B//S + +#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 +#define OID_RT_GET_TX_BEACON_OK 0xFF010191 +#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 +#define OID_RT_GET_RX_ICV_ERR 0xFF010193 +#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 +#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 +#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 +#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 +#define OID_RT_GET_AP_IP 0xFF010198 +#define OID_RT_GET_CHANNELPLAN 0xFF010199 +#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A +#define OID_RT_SET_BCN_INTVL 0xFF01019B +#define OID_RT_GET_RF_VENDER 0xFF01019C +#define OID_RT_DEDICATE_PROBE 0xFF01019D +#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E + +#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F + +#define OID_RT_GET_CCA_ERR 0xFF0101A0 +#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 +#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 + +#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 +#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 + +// by Owen on 03/31/03 for Cameo's request +#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 +// +#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 +#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 +#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 +#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 +#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 +#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA +#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB +#define OID_RT_GET_CHANNEL 0xFF0101AC + +#define OID_RT_SET_CHANNELPLAN 0xFF0101AD +#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE +#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF +#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 +#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 +#define OID_RT_GET_IS_ROAMING 0xFF0101B2 +#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 +#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 +#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 +#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 +#define OID_RT_RESET_LOG 0xFF0101B7 +#define OID_RT_GET_LOG 0xFF0101B8 +#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 +#define OID_RT_GET_HEADER_FAIL 0xFF0101BA +#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB +#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC +#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD +#define OID_RT_GET_TX_INFO 0xFF0101BE +#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF +#define OID_RT_RF_READ_WRITE 0xFF0101C0 + +// For Netgear request. 2005.01.13, by rcnjko. +#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 +#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 +// For Netgear request. 2005.02.17, by rcnjko. +#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 +// For AZ project. 2005.06.27, by rcnjko. +#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 + +// Vincent 8185MP +#define OID_RT_PRO_RX_FILTER 0xFF0111C0 + +//Andy TEST +//#define OID_RT_PRO_WRITE_REGISTRY 0xFF0111C1 +//#define OID_RT_PRO_READ_REGISTRY 0xFF0111C2 +#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 +#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 + + +#define OID_RT_PRO_SET_INITIAL_GAIN 0xFF0111C3 +#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 +#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 +#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 +#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 +#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 +#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 +#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA + +// AP OID +#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 +#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 +#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 +#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 +#define OID_RT_AP_SUPPORTED 0xFF010304 // Determine if driver supports AP mode. 2004.08.27, by rcnjko. +#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 // Set WPA-PSK passphrase into authenticator. 2005.07.08, byrcnjko. + +// 8187MP. 2004.09.06, by rcnjko. +#define OID_RT_PRO8187_WI_POLL 0xFF818780 +#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 +#define OID_RT_PRO_READ_BB_REG 0xFF818782 +#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 +#define OID_RT_PRO_READ_RF_REG 0xFF818784 + +// Meeting House. added by Annie, 2005-07-20. +#define OID_RT_MH_VENDER_ID 0xFFEDC100 + +//8711 MP OID added 20051230. +#define OID_RT_PRO8711_JOIN_BSS 0xFF871100//S + +#define OID_RT_PRO_READ_REGISTER 0xFF871101 //Q +#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 //S + +#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 //Q +#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 //S + +#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 //S + +#define OID_RT_PRO_READ16_EEPROM 0xFF871106 //Q +#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 //S + +#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 //S +#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 //Q + +#define OID_RT_PRO8711_WI_POLL 0xFF87110A //Q +#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B //Q +#define OID_RT_RD_ATTRIB_MEM 0xFF87110C//Q +#define OID_RT_WR_ATTRIB_MEM 0xFF87110D//S + + +//Method 2 for H2C/C2H +#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 //S +#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 //Q +#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 //S +#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 //Q +#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114//Q + +#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 //Q, S + +#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 //S +#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 //Q,S +#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 //Q +#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 //Q + +#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A //S +#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B //Q +#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C //S +#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D //Q +#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E //S +#define OID_RT_POLL_RX_STATUS 0xFF87111F //Q + +#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 //Q,S +#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121//S +#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122//S +#define OID_RT_PRO_READ_TSSI 0xFF871123//S +#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124//S + + +#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 //Q +#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 //S + +//Method 2 , using workitem +#define OID_RT_SET_READ_REG 0xFF871181 //S +#define OID_RT_SET_WRITE_REG 0xFF871182 //S +#define OID_RT_SET_BURST_READ_REG 0xFF871183 //S +#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 //S +#define OID_RT_SET_WRITE_TXCMD 0xFF871185 //S +#define OID_RT_SET_READ16_EEPROM 0xFF871186 //S +#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 //S +#define OID_RT_QRY_POLL_WKITEM 0xFF871188 //Q + +//For SDIO INTERFACE only +#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 //Q, S +#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 + +//For USB INTERFACE only +#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 //Q, S +#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 //S +#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 //S +#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 //Q +#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 //Q + +#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB //S +#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC //S +#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE + +#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 //Q, S +#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 //S +#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 //S +#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 //Q + +#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 //Q, S + +#define OID_RT_PRO_READ_EFUSE 0xFF871205 //Q +#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 //S +#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 //Q, S +#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 //Q + +#define OID_RT_SET_BANDWIDTH 0xFF871209 //S +#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A //S + +#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B //S + +#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C //Q + +#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D //S + +#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E //S + +#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F //S + +#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 //Q + +#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 //S +#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 //Q +#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 //Q + +#define OID_RT_SET_POWER_DOWN 0xFF871214 //S + +#define OID_RT_GET_POWER_MODE 0xFF871215 //Q + +#define OID_RT_PRO_EFUSE 0xFF871216 //Q, S +#define OID_RT_PRO_EFUSE_MAP 0xFF871217 //Q, S + +#endif //#ifndef __CUSTOM_OID_H diff --git a/rtl8192cu-fixes/include/nic_spec.h b/rtl8192cu-fixes/include/nic_spec.h new file mode 100755 index 00000000..18e7b2c0 --- /dev/null +++ b/rtl8192cu-fixes/include/nic_spec.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * + * 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 __NIC_SPEC_H__ +#define __NIC_SPEC_H__ + +#include + +#define RTL8711_MCTRL_ (0x20000) +#define RTL8711_UART_ (0x30000) +#define RTL8711_TIMER_ (0x40000) +#define RTL8711_FINT_ (0x50000) +#define RTL8711_HINT_ (0x50000) +#define RTL8711_GPIO_ (0x60000) +#define RTL8711_WLANCTRL_ (0x200000) +#define RTL8711_WLANFF_ (0xe00000) +#define RTL8711_HCICTRL_ (0x600000) +#define RTL8711_SYSCFG_ (0x620000) +#define RTL8711_SYSCTRL_ (0x620000) +#define RTL8711_MCCTRL_ (0x020000) + + +#include + +#include + + +#endif // __RTL8711_SPEC_H__ + diff --git a/rtl8192cu-fixes/include/osdep_ce_service.h b/rtl8192cu-fixes/include/osdep_ce_service.h new file mode 100755 index 00000000..e374077f --- /dev/null +++ b/rtl8192cu-fixes/include/osdep_ce_service.h @@ -0,0 +1,171 @@ +/****************************************************************************** + * + * 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 __OSDEP_CE_SERVICE_H_ +#define __OSDEP_CE_SERVICE_H_ + + +#include +#include + +#ifdef CONFIG_SDIO_HCI +#include "SDCardDDK.h" +#endif + +#ifdef CONFIG_USB_HCI +#include +#endif + +typedef HANDLE _sema; +typedef LIST_ENTRY _list; +typedef NDIS_STATUS _OS_STATUS; + +typedef NDIS_SPIN_LOCK _lock; + +typedef HANDLE _rwlock; //Mutex + +typedef u32 _irqL; + +typedef NDIS_HANDLE _nic_hdl; + + +typedef NDIS_MINIPORT_TIMER _timer; + +struct __queue { + LIST_ENTRY queue; + _lock lock; +}; + +typedef NDIS_PACKET _pkt; +typedef NDIS_BUFFER _buffer; +typedef struct __queue _queue; + +typedef HANDLE _thread_hdl_; +typedef DWORD thread_return; +typedef void* thread_context; +typedef NDIS_WORK_ITEM _workitem; + +#define thread_exit() ExitThread(STATUS_SUCCESS); return 0; + + +#define SEMA_UPBND (0x7FFFFFFF) //8192 + +__inline static _list *get_prev(_list *list) +{ + return list->Blink; +} + +__inline static _list *get_next(_list *list) +{ + return list->Flink; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + +#define LIST_CONTAINOR(ptr, type, member) CONTAINING_RECORD(ptr, type, member) + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + NdisAcquireSpinLock(plock); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + NdisReleaseSpinLock(plock); +} + +__inline static _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + + +__inline static void _enter_hwio_critical(_rwlock *prwlock, _irqL *pirqL) +{ + WaitForSingleObject(*prwlock, INFINITE ); + +} + +__inline static void _exit_hwio_critical(_rwlock *prwlock, _irqL *pirqL) +{ + ReleaseMutex(*prwlock); +} + +__inline static void rtw_list_delete(_list *plist) +{ + RemoveEntryList(plist); + InitializeListHead(plist); +} + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,PVOID cntx) +{ + NdisMInitializeTimer(ptimer, nic_hdl, pfunc, cntx); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + NdisMSetTimer(ptimer,delay_time); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + NdisMCancelTimer(ptimer,bcancelled); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + + NdisInitializeWorkItem(pwork, pfunc, cntx); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + NdisScheduleWorkItem(pwork); +} + +#define ATOMIC_INIT(i) { (i) } + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (NdisInterlockedIncrement((PULONG)&(_MutexCounter)) != 1)\ + { \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ + NdisMSleep(10000); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ +} +#endif + diff --git a/rtl8192cu-fixes/include/osdep_intf.h b/rtl8192cu-fixes/include/osdep_intf.h new file mode 100755 index 00000000..3cd16596 --- /dev/null +++ b/rtl8192cu-fixes/include/osdep_intf.h @@ -0,0 +1,155 @@ +/****************************************************************************** + * + * 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 __OSDEP_INTF_H_ +#define __OSDEP_INTF_H_ + +#include +#include +#include + +struct intf_priv { + + u8 *intf_dev; + u32 max_iosz; //USB2.0: 128, USB1.1: 64, SDIO:64 + u32 max_xmitsz; //USB2.0: unlimited, SDIO:512 + u32 max_recvsz; //USB2.0: unlimited, SDIO:512 + + volatile u8 *io_rwmem; + volatile u8 *allocated_io_rwmem; + u32 io_wsz; //unit: 4bytes + u32 io_rsz;//unit: 4bytes + u8 intf_status; + + void (*_bus_io)(u8 *priv); + +/* +Under Sync. IRP (SDIO/USB) +A protection mechanism is necessary for the io_rwmem(read/write protocol) + +Under Async. IRP (SDIO/USB) +The protection mechanism is through the pending queue. +*/ + + _mutex ioctl_mutex; + + +#ifdef PLATFORM_LINUX + #ifdef CONFIG_USB_HCI + // when in USB, IO is through interrupt in/out endpoints + struct usb_device *udev; + PURB piorw_urb; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + _timer io_timer; + u8 bio_irp_timeout; + u8 bio_timer_cancel; + #endif +#endif + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + // below is for io_rwmem... + PMDL pmdl; + PSDBUS_REQUEST_PACKET sdrp; + PSDBUS_REQUEST_PACKET recv_sdrp; + PSDBUS_REQUEST_PACKET xmit_sdrp; + + PIRP piorw_irp; + + #endif + #ifdef CONFIG_USB_HCI + PURB piorw_urb; + PIRP piorw_irp; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + #endif +#endif + +}; + + +#ifdef CONFIG_R871X_TEST +int rtw_start_pseudo_adhoc(_adapter *padapter); +int rtw_stop_pseudo_adhoc(_adapter *padapter); +#endif + +struct dvobj_priv *devobj_init(void); +void devobj_deinit(struct dvobj_priv *pdvobj); + +u8 rtw_init_drv_sw(_adapter *padapter); +u8 rtw_free_drv_sw(_adapter *padapter); +u8 rtw_reset_drv_sw(_adapter *padapter); + +u32 rtw_start_drv_threads(_adapter *padapter); +void rtw_stop_drv_threads (_adapter *padapter); +void rtw_cancel_all_timer(_adapter *padapter); + +#ifdef PLATFORM_LINUX +int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + +int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); +struct net_device *rtw_init_netdev(_adapter *padapter); +void rtw_unregister_netdevs(struct dvobj_priv *dvobj); + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) +u16 rtw_recv_select_queue(struct sk_buff *skb); +#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) + +#ifdef CONFIG_PROC_DEBUG +void rtw_proc_init_one(struct net_device *dev); +void rtw_proc_remove_one(struct net_device *dev); +#else //!CONFIG_PROC_DEBUG +static void rtw_proc_init_one(struct net_device *dev){} +static void rtw_proc_remove_one(struct net_device *dev){} +#endif //!CONFIG_PROC_DEBUG +#endif //PLATFORM_LINUX + + +#ifdef PLATFORM_FREEBSD +extern int rtw_ioctl(struct ifnet * ifp, u_long cmd, caddr_t data); +#endif + +void rtw_ips_dev_unload(_adapter *padapter); +#ifdef CONFIG_IPS +int rtw_ips_pwr_up(_adapter *padapter); +void rtw_ips_pwr_down(_adapter *padapter); +#endif + +#ifdef CONFIG_CONCURRENT_MODE +struct _io_ops; +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, void (*set_intf_ops)(struct _io_ops *pops)); +void rtw_drv_if2_free(_adapter *if2); +void rtw_drv_if2_stop(_adapter *if2); +#ifdef CONFIG_MULTI_VIR_IFACES +struct dvobj_priv; +_adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, void (*set_intf_ops)(struct _io_ops *pops)); +void rtw_drv_stop_vir_ifaces(struct dvobj_priv *dvobj); +void rtw_drv_free_vir_ifaces(struct dvobj_priv *dvobj); +#endif //CONFIG_MULTI_VIR_IFACES +#endif + +int rtw_drv_register_netdev(_adapter *padapter); +void rtw_ndev_destructor(_nic_hdl ndev); + +#endif //_OSDEP_INTF_H_ + diff --git a/rtl8192cu-fixes/include/osdep_service.h b/rtl8192cu-fixes/include/osdep_service.h new file mode 100755 index 00000000..c5c465e7 --- /dev/null +++ b/rtl8192cu-fixes/include/osdep_service.h @@ -0,0 +1,1815 @@ +/****************************************************************************** + * + * 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 __OSDEP_SERVICE_H_ +#define __OSDEP_SERVICE_H_ + +#include +#include +//#include + +#define _FAIL 0 +#define _SUCCESS 1 +#define RTW_RX_HANDLED 2 +//#define RTW_STATUS_TIMEDOUT -110 + +#undef _TRUE +#define _TRUE 1 + +#undef _FALSE +#define _FALSE 0 + + +#ifdef PLATFORM_FREEBSD +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include "usbdevs.h" + +#define USB_DEBUG_VAR rum_debug +#include + +#if 1 //Baron porting from linux, it's all temp solution, needs to check again +#include +#include /* XXX for PCPU_GET */ +// typedef struct semaphore _sema; + typedef struct sema _sema; +// typedef spinlock_t _lock; + typedef struct mtx _lock; + typedef struct mtx _mutex; + typedef struct timer_list _timer; + struct list_head { + struct list_head *next, *prev; + }; + struct __queue { + struct list_head queue; + _lock lock; + }; + + //typedef struct sk_buff _pkt; + typedef struct mbuf _pkt; + typedef struct mbuf _buffer; + + typedef struct __queue _queue; + typedef struct list_head _list; + typedef int _OS_STATUS; + //typedef u32 _irqL; + typedef unsigned long _irqL; + typedef struct ifnet * _nic_hdl; + + typedef pid_t _thread_hdl_; +// typedef struct thread _thread_hdl_; + typedef void thread_return; + typedef void* thread_context; + + //#define thread_exit() complete_and_exit(NULL, 0) + + typedef void timer_hdl_return; + typedef void* timer_hdl_context; + typedef struct work_struct _workitem; + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +/* emulate a modern version */ +#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 35) + +#define WIRELESS_EXT -1 +#define HZ hz +#define spin_lock_irqsave mtx_lock_irqsave +#define spin_lock_bh mtx_lock_irqsave +#define mtx_lock_irqsave(lock, x) mtx_lock(lock)//{local_irq_save((x)); mtx_lock_spin((lock));} +//#define IFT_RTW 0xf9 //ifnet allocate type for RTW +#define free_netdev if_free +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n)) +/* + * Linux timers are emulated using FreeBSD callout functions + * (and taskqueue functionality). + * + * Currently no timer stats functionality. + * + * See (linux_compat) processes.c + * + */ +struct timer_list { + + /* FreeBSD callout related fields */ + struct callout callout; + + //timeout function + void (*function)(void*); + //argument + void *arg; + +}; +struct workqueue_struct; +struct work_struct; +typedef void (*work_func_t)(struct work_struct *work); +/* Values for the state of an item of work (work_struct) */ +typedef enum work_state { + WORK_STATE_UNSET = 0, + WORK_STATE_CALLOUT_PENDING = 1, + WORK_STATE_TASK_PENDING = 2, + WORK_STATE_WORK_CANCELLED = 3 +} work_state_t; + +struct work_struct { + struct task task; /* FreeBSD task */ + work_state_t state; /* the pending or otherwise state of work. */ + work_func_t func; +}; +#define spin_unlock_irqrestore mtx_unlock_irqrestore +#define spin_unlock_bh mtx_unlock_irqrestore +#define mtx_unlock_irqrestore(lock,x) mtx_unlock(lock); +extern void _rtw_spinlock_init(_lock *plock); + +//modify private structure to match freebsd +#define BITS_PER_LONG 32 +union ktime { + s64 tv64; +#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR) + struct { +#ifdef __BIG_ENDIAN + s32 sec, nsec; +#else + s32 nsec, sec; +#endif + } tv; +#endif +}; +#define kmemcheck_bitfield_begin(name) +#define kmemcheck_bitfield_end(name) +#define CHECKSUM_NONE 0 +typedef unsigned char *sk_buff_data_t; +typedef union ktime ktime_t; /* Kill this */ + +void rtw_mtx_lock(_lock *plock); + +void rtw_mtx_unlock(_lock *plock); + +/** + * struct sk_buff - socket buffer + * @next: Next buffer in list + * @prev: Previous buffer in list + * @sk: Socket we are owned by + * @tstamp: Time we arrived + * @dev: Device we arrived on/are leaving by + * @transport_header: Transport layer header + * @network_header: Network layer header + * @mac_header: Link layer header + * @_skb_refdst: destination entry (with norefcount bit) + * @sp: the security path, used for xfrm + * @cb: Control buffer. Free for use by every layer. Put private vars here + * @len: Length of actual data + * @data_len: Data length + * @mac_len: Length of link layer header + * @hdr_len: writable header length of cloned skb + * @csum: Checksum (must include start/offset pair) + * @csum_start: Offset from skb->head where checksumming should start + * @csum_offset: Offset from csum_start where checksum should be stored + * @local_df: allow local fragmentation + * @cloned: Head may be cloned (check refcnt to be sure) + * @nohdr: Payload reference only, must not modify header + * @pkt_type: Packet class + * @fclone: skbuff clone status + * @ip_summed: Driver fed us an IP checksum + * @priority: Packet queueing priority + * @users: User count - see {datagram,tcp}.c + * @protocol: Packet protocol from driver + * @truesize: Buffer size + * @head: Head of buffer + * @data: Data head pointer + * @tail: Tail pointer + * @end: End pointer + * @destructor: Destruct function + * @mark: Generic packet mark + * @nfct: Associated connection, if any + * @ipvs_property: skbuff is owned by ipvs + * @peeked: this packet has been seen already, so stats have been + * done for it, don't do them again + * @nf_trace: netfilter packet trace flag + * @nfctinfo: Relationship of this skb to the connection + * @nfct_reasm: netfilter conntrack re-assembly pointer + * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c + * @skb_iif: ifindex of device we arrived on + * @rxhash: the packet hash computed on receive + * @queue_mapping: Queue mapping for multiqueue devices + * @tc_index: Traffic control index + * @tc_verd: traffic control verdict + * @ndisc_nodetype: router type (from link layer) + * @dma_cookie: a cookie to one of several possible DMA operations + * done by skb DMA functions + * @secmark: security marking + * @vlan_tci: vlan tag control information + */ + +struct sk_buff { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + ktime_t tstamp; + + struct sock *sk; + //struct net_device *dev; + struct ifnet *dev; + + /* + * This is the control buffer. It is free to use for every + * layer. Please put your private variables there. If you + * want to keep them across layers you have to do a skb_clone() + * first. This is owned by whoever has the skb queued ATM. + */ + char cb[48] __aligned(8); + + unsigned long _skb_refdst; +#ifdef CONFIG_XFRM + struct sec_path *sp; +#endif + unsigned int len, + data_len; + u16 mac_len, + hdr_len; + union { + u32 csum; + struct { + u16 csum_start; + u16 csum_offset; + }smbol2; + }smbol1; + u32 priority; + kmemcheck_bitfield_begin(flags1); + u8 local_df:1, + cloned:1, + ip_summed:2, + nohdr:1, + nfctinfo:3; + u8 pkt_type:3, + fclone:2, + ipvs_property:1, + peeked:1, + nf_trace:1; + kmemcheck_bitfield_end(flags1); + u16 protocol; + + void (*destructor)(struct sk_buff *skb); +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + struct nf_conntrack *nfct; + struct sk_buff *nfct_reasm; +#endif +#ifdef CONFIG_BRIDGE_NETFILTER + struct nf_bridge_info *nf_bridge; +#endif + + int skb_iif; +#ifdef CONFIG_NET_SCHED + u16 tc_index; /* traffic control index */ +#ifdef CONFIG_NET_CLS_ACT + u16 tc_verd; /* traffic control verdict */ +#endif +#endif + + u32 rxhash; + + kmemcheck_bitfield_begin(flags2); + u16 queue_mapping:16; +#ifdef CONFIG_IPV6_NDISC_NODETYPE + u8 ndisc_nodetype:2, + deliver_no_wcard:1; +#else + u8 deliver_no_wcard:1; +#endif + kmemcheck_bitfield_end(flags2); + + /* 0/14 bit hole */ + +#ifdef CONFIG_NET_DMA + dma_cookie_t dma_cookie; +#endif +#ifdef CONFIG_NETWORK_SECMARK + u32 secmark; +#endif + union { + u32 mark; + u32 dropcount; + }symbol3; + + u16 vlan_tci; + + sk_buff_data_t transport_header; + sk_buff_data_t network_header; + sk_buff_data_t mac_header; + /* These elements must be at the end, see alloc_skb() for details. */ + sk_buff_data_t tail; + sk_buff_data_t end; + unsigned char *head, + *data; + unsigned int truesize; + atomic_t users; +}; +struct sk_buff_head { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + u32 qlen; + _lock lock; +}; +#define skb_tail_pointer(skb) skb->tail +static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len) +{ + unsigned char *tmp = skb_tail_pointer(skb); + //SKB_LINEAR_ASSERT(skb); + skb->tail += len; + skb->len += len; + return tmp; +} + +static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) +{ + skb->len -= len; + if(skb->len < skb->data_len) + printf("%s(),%d,error!\n",__FUNCTION__,__LINE__); + return skb->data += len; +} +static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) +{ + #ifdef PLATFORM_FREEBSD + return __skb_pull(skb, len); + #else + return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); + #endif //PLATFORM_FREEBSD +} +static inline u32 skb_queue_len(const struct sk_buff_head *list_) +{ + return list_->qlen; +} +static inline void __skb_insert(struct sk_buff *newsk, + struct sk_buff *prev, struct sk_buff *next, + struct sk_buff_head *list) +{ + newsk->next = next; + newsk->prev = prev; + next->prev = prev->next = newsk; + list->qlen++; +} +static inline void __skb_queue_before(struct sk_buff_head *list, + struct sk_buff *next, + struct sk_buff *newsk) +{ + __skb_insert(newsk, next->prev, next, list); +} +static inline void skb_queue_tail(struct sk_buff_head *list, + struct sk_buff *newsk) +{ + mtx_lock(&list->lock); + __skb_queue_before(list, (struct sk_buff *)list, newsk); + mtx_unlock(&list->lock); +} +static inline struct sk_buff *skb_peek(struct sk_buff_head *list_) +{ + struct sk_buff *list = ((struct sk_buff *)list_)->next; + if (list == (struct sk_buff *)list_) + list = NULL; + return list; +} +static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) +{ + struct sk_buff *next, *prev; + + list->qlen--; + next = skb->next; + prev = skb->prev; + skb->next = skb->prev = NULL; + next->prev = prev; + prev->next = next; +} + +static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list) +{ + mtx_lock(&list->lock); + + struct sk_buff *skb = skb_peek(list); + if (skb) + __skb_unlink(skb, list); + + mtx_unlock(&list->lock); + + return skb; +} +static inline void skb_reserve(struct sk_buff *skb, int len) +{ + skb->data += len; + skb->tail += len; +} +static inline void __skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = list->next = (struct sk_buff *)list; + list->qlen = 0; +} +/* + * This function creates a split out lock class for each invocation; + * this is needed for now since a whole lot of users of the skb-queue + * infrastructure in drivers have different locking usage (in hardirq) + * than the networking core (in softirq only). In the long run either the + * network layer or drivers should need annotation to consolidate the + * main types of usage into 3 classes. + */ +static inline void skb_queue_head_init(struct sk_buff_head *list) +{ + _rtw_spinlock_init(&list->lock); + __skb_queue_head_init(list); +} +unsigned long copy_from_user(void *to, const void *from, unsigned long n); +unsigned long copy_to_user(void *to, const void *from, unsigned long n); +struct sk_buff * dev_alloc_skb(unsigned int size); +struct sk_buff *skb_clone(const struct sk_buff *skb); +void dev_kfree_skb_any(struct sk_buff *skb); +#endif //Baron porting from linux, it's all temp solution, needs to check again + + +#if 1 // kenny add Linux compatibility code for Linux USB driver +#include + +#define __init // __attribute ((constructor)) +#define __exit // __attribute ((destructor)) + +/* + * Definitions for module_init and module_exit macros. + * + * These macros will use the SYSINIT framework to call a specified + * function (with no arguments) on module loading or unloading. + * + */ + +void module_init_exit_wrapper(void *arg); + +#define module_init(initfn) \ + SYSINIT(mod_init_ ## initfn, \ + SI_SUB_KLD, SI_ORDER_FIRST, \ + module_init_exit_wrapper, initfn) + +#define module_exit(exitfn) \ + SYSUNINIT(mod_exit_ ## exitfn, \ + SI_SUB_KLD, SI_ORDER_ANY, \ + module_init_exit_wrapper, exitfn) + +/* + * The usb_register and usb_deregister functions are used to register + * usb drivers with the usb subsystem. + */ +int usb_register(struct usb_driver *driver); +int usb_deregister(struct usb_driver *driver); + +/* + * usb_get_dev and usb_put_dev - increment/decrement the reference count + * of the usb device structure. + * + * Original body of usb_get_dev: + * + * if (dev) + * get_device(&dev->dev); + * return dev; + * + * Reference counts are not currently used in this compatibility + * layer. So these functions will do nothing. + */ +static inline struct usb_device * +usb_get_dev(struct usb_device *dev) +{ + return dev; +} + +static inline void +usb_put_dev(struct usb_device *dev) +{ + return; +} + + +// rtw_usb_compat_linux +int rtw_usb_submit_urb(struct urb *urb, uint16_t mem_flags); +int rtw_usb_unlink_urb(struct urb *urb); +int rtw_usb_clear_halt(struct usb_device *dev, struct usb_host_endpoint *uhe); +int rtw_usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *uhe, + uint8_t request, uint8_t requesttype, + uint16_t value, uint16_t index, void *data, + uint16_t size, usb_timeout_t timeout); +int rtw_usb_set_interface(struct usb_device *dev, uint8_t iface_no, uint8_t alt_index); +int rtw_usb_setup_endpoint(struct usb_device *dev, + struct usb_host_endpoint *uhe, usb_size_t bufsize); +struct urb *rtw_usb_alloc_urb(uint16_t iso_packets, uint16_t mem_flags); +struct usb_host_endpoint *rtw_usb_find_host_endpoint(struct usb_device *dev, uint8_t type, uint8_t ep); +struct usb_host_interface *rtw_usb_altnum_to_altsetting(const struct usb_interface *intf, uint8_t alt_index); +struct usb_interface *rtw_usb_ifnum_to_if(struct usb_device *dev, uint8_t iface_no); +void *rtw_usb_buffer_alloc(struct usb_device *dev, usb_size_t size, uint8_t *dma_addr); +void *rtw_usbd_get_intfdata(struct usb_interface *intf); +void rtw_usb_linux_register(void *arg); +void rtw_usb_linux_deregister(void *arg); +void rtw_usb_linux_free_device(struct usb_device *dev); +void rtw_usb_buffer_free(struct usb_device *dev, usb_size_t size, + void *addr, uint8_t dma_addr); +void rtw_usb_free_urb(struct urb *urb); +void rtw_usb_init_urb(struct urb *urb); +void rtw_usb_kill_urb(struct urb *urb); +void rtw_usb_set_intfdata(struct usb_interface *intf, void *data); +void rtw_usb_fill_bulk_urb(struct urb *urb, struct usb_device *udev, + struct usb_host_endpoint *uhe, void *buf, + int length, usb_complete_t callback, void *arg); +int rtw_usb_bulk_msg(struct usb_device *udev, struct usb_host_endpoint *uhe, + void *data, int len, uint16_t *pactlen, usb_timeout_t timeout); +void *usb_get_intfdata(struct usb_interface *intf); +int usb_linux_init_endpoints(struct usb_device *udev); + + + +typedef struct urb * PURB; + +typedef unsigned gfp_t; +#define __GFP_WAIT ((gfp_t)0x10u) /* Can wait and reschedule? */ +#define __GFP_HIGH ((gfp_t)0x20u) /* Should access emergency pools? */ +#define __GFP_IO ((gfp_t)0x40u) /* Can start physical IO? */ +#define __GFP_FS ((gfp_t)0x80u) /* Can call down to low-level FS? */ +#define __GFP_COLD ((gfp_t)0x100u) /* Cache-cold page required */ +#define __GFP_NOWARN ((gfp_t)0x200u) /* Suppress page allocation failure warning */ +#define __GFP_REPEAT ((gfp_t)0x400u) /* Retry the allocation. Might fail */ +#define __GFP_NOFAIL ((gfp_t)0x800u) /* Retry for ever. Cannot fail */ +#define __GFP_NORETRY ((gfp_t)0x1000u)/* Do not retry. Might fail */ +#define __GFP_NO_GROW ((gfp_t)0x2000u)/* Slab internal usage */ +#define __GFP_COMP ((gfp_t)0x4000u)/* Add compound page metadata */ +#define __GFP_ZERO ((gfp_t)0x8000u)/* Return zeroed page on success */ +#define __GFP_NOMEMALLOC ((gfp_t)0x10000u) /* Don't use emergency reserves */ +#define __GFP_HARDWALL ((gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ + +/* This equals 0, but use constants in case they ever change */ +#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) +/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */ +#define GFP_ATOMIC (__GFP_HIGH) +#define GFP_NOIO (__GFP_WAIT) +#define GFP_NOFS (__GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL) +#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ + __GFP_HIGHMEM) + + +#endif // kenny add Linux compatibility code for Linux USB + + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#endif + +__inline static _list *get_next(_list *list) +{ + return list->next; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) + + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_lock_bh(plock, *pirqL); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_unlock_bh(plock, *pirqL); +} + +__inline static void _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + + mtx_lock(pmutex); + +} + + +__inline static void _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + + mtx_unlock(pmutex); + +} +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} +__inline static void rtw_list_delete(_list *plist) +{ + __list_del(plist->prev, plist->next); + INIT_LIST_HEAD(plist); +} + +__inline static void _init_timer(_timer *ptimer,_nic_hdl padapter,void *pfunc,void* cntx) +{ + ptimer->function = pfunc; + ptimer->arg = cntx; + callout_init(&ptimer->callout, CALLOUT_MPSAFE); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + // mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); + if(ptimer->function && ptimer->arg){ + rtw_mtx_lock(NULL); + callout_reset(&ptimer->callout, delay_time,ptimer->function, ptimer->arg); + rtw_mtx_unlock(NULL); + } +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + // del_timer_sync(ptimer); + // *bcancelled= _TRUE;//TRUE ==1; FALSE==0 + rtw_mtx_lock(NULL); + callout_drain(&ptimer->callout); + rtw_mtx_unlock(NULL); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + printf("%s Not implement yet! \n",__FUNCTION__); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + printf("%s Not implement yet! \n",__FUNCTION__); +// schedule_work(pwork); +} + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ +} + +#define ATOMIC_INIT(i) { (i) } + +#endif //PLATFORM_FREEBSD + + +#ifdef PLATFORM_LINUX + #include + #include + #include + #include + #include + #include + #include + #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5)) + #include +#endif + //#include + #include + #include + #include + #include + #include + #include + #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + #include +#else + #include +#endif + #include + #include + #include + #include + #include + #include + #include + #include + #include // Necessary because we use the proc fs + #include // for struct tasklet_struct + #include + #include + +#ifdef CONFIG_IOCTL_CFG80211 +// #include + #include + #include +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + #include + #include +#endif + +#ifdef CONFIG_USB_HCI + #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + #include +#else + #include +#endif +#endif + +#ifdef CONFIG_PCI_HCI + #include +#endif + + +#ifdef CONFIG_USB_HCI + typedef struct urb * PURB; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22)) +#ifdef CONFIG_USB_SUSPEND +#define CONFIG_AUTOSUSPEND 1 +#endif +#endif +#endif + + typedef struct semaphore _sema; + typedef spinlock_t _lock; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + typedef struct mutex _mutex; +#else + typedef struct semaphore _mutex; +#endif + typedef struct timer_list _timer; + + struct __queue { + struct list_head queue; + _lock lock; + }; + + typedef struct sk_buff _pkt; + typedef unsigned char _buffer; + + typedef struct __queue _queue; + typedef struct list_head _list; + typedef int _OS_STATUS; + //typedef u32 _irqL; + typedef unsigned long _irqL; + typedef struct net_device * _nic_hdl; + + typedef void* _thread_hdl_; + typedef int thread_return; + typedef void* thread_context; + + #define thread_exit() complete_and_exit(NULL, 0) + + typedef void timer_hdl_return; + typedef void* timer_hdl_context; + typedef struct work_struct _workitem; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) +// Porting from linux kernel, for compatible with old kernel. +static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->tail; +} + +static inline void skb_reset_tail_pointer(struct sk_buff *skb) +{ + skb->tail = skb->data; +} + +static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) +{ + skb->tail = skb->data + offset; +} + +static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) +{ + return skb->end; +} +#endif + +__inline static _list *get_next(_list *list) +{ + return list->next; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) + + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_lock_bh(plock); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_unlock_bh(plock); +} + +__inline static void _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_lock(pmutex); +#else + down(pmutex); +#endif +} + + +__inline static void _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_unlock(pmutex); +#else + up(pmutex); +#endif +} + +__inline static void rtw_list_delete(_list *plist) +{ + list_del_init(plist); +} + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,void* cntx) +{ + //setup_timer(ptimer, pfunc,(u32)cntx); + ptimer->function = pfunc; + ptimer->data = (unsigned long)cntx; + init_timer(ptimer); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + del_timer_sync(ptimer); + *bcancelled= _TRUE;//TRUE ==1; FALSE==0 +} + +#ifdef PLATFORM_LINUX +#define RTW_TIMER_HDL_ARGS void *FunctionContext +#elif defined(PLATFORM_OS_CE) || defined(PLATFORM_WINDOWS) +#define RTW_TIMER_HDL_ARGS IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3 +#endif + +#define RTW_TIMER_HDL_NAME(name) rtw_##name##_timer_hdl +#define RTW_DECLARE_TIMER_HDL(name) void RTW_TIMER_HDL_NAME(name)(RTW_TIMER_HDL_ARGS) + + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + INIT_WORK(pwork, pfunc); +#else + INIT_WORK(pwork, pfunc,pwork); +#endif +} + +__inline static void _set_workitem(_workitem *pwork) +{ + schedule_work(pwork); +} + +__inline static void _cancel_workitem_sync(_workitem *pwork) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22)) + cancel_work_sync(pwork); +#else + flush_scheduled_work(); +#endif +} + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (atomic_inc_return((atomic_t *)&(_MutexCounter)) != 1)\ + { \ + atomic_dec((atomic_t *)&(_MutexCounter)); \ + msleep(10); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + atomic_dec((atomic_t *)&(_MutexCounter)); \ +} + +static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + return (netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)) ); +#else + return netif_queue_stopped(pnetdev); +#endif +} + +static inline void rtw_netif_wake_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_wake_all_queues(pnetdev); +#else + netif_wake_queue(pnetdev); +#endif +} + +static inline void rtw_netif_start_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_start_all_queues(pnetdev); +#else + netif_start_queue(pnetdev); +#endif +} + +static inline void rtw_netif_stop_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_stop_all_queues(pnetdev); +#else + netif_stop_queue(pnetdev); +#endif +} + +#endif // PLATFORM_LINUX + + +#ifdef PLATFORM_OS_XP + + #include + #include + #include + #include + +#ifdef CONFIG_USB_HCI + #include + #include + #include +#endif + + typedef KSEMAPHORE _sema; + typedef LIST_ENTRY _list; + typedef NDIS_STATUS _OS_STATUS; + + + typedef NDIS_SPIN_LOCK _lock; + + typedef KMUTEX _mutex; + + typedef KIRQL _irqL; + + // USB_PIPE for WINCE , but handle can be use just integer under windows + typedef NDIS_HANDLE _nic_hdl; + + + typedef NDIS_MINIPORT_TIMER _timer; + + struct __queue { + LIST_ENTRY queue; + _lock lock; + }; + + typedef NDIS_PACKET _pkt; + typedef NDIS_BUFFER _buffer; + typedef struct __queue _queue; + + typedef PKTHREAD _thread_hdl_; + typedef void thread_return; + typedef void* thread_context; + + typedef NDIS_WORK_ITEM _workitem; + + #define thread_exit() PsTerminateSystemThread(STATUS_SUCCESS); + + #define HZ 10000000 + #define SEMA_UPBND (0x7FFFFFFF) //8192 + +__inline static _list *get_next(_list *list) +{ + return list->Flink; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) CONTAINING_RECORD(ptr, type, member) + + +__inline static _enter_critical(_lock *plock, _irqL *pirqL) +{ + NdisAcquireSpinLock(plock); +} + +__inline static _exit_critical(_lock *plock, _irqL *pirqL) +{ + NdisReleaseSpinLock(plock); +} + + +__inline static _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + +__inline static _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + KeWaitForSingleObject(pmutex, Executive, KernelMode, FALSE, NULL); +} + + +__inline static _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + KeReleaseMutex(pmutex, FALSE); +} + + +__inline static void rtw_list_delete(_list *plist) +{ + RemoveEntryList(plist); + InitializeListHead(plist); +} + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,PVOID cntx) +{ + NdisMInitializeTimer(ptimer, nic_hdl, pfunc, cntx); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + NdisMSetTimer(ptimer,delay_time); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + NdisMCancelTimer(ptimer,bcancelled); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + + NdisInitializeWorkItem(pwork, pfunc, cntx); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + NdisScheduleWorkItem(pwork); +} + + +#define ATOMIC_INIT(i) { (i) } + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (NdisInterlockedIncrement((PULONG)&(_MutexCounter)) != 1)\ + { \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ + NdisMSleep(10000); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ +} + +#endif // PLATFORM_OS_XP + + +#ifdef PLATFORM_OS_CE +#include +#endif + +#include + +#ifndef BIT + #define BIT(x) ( 1 << (x)) +#endif + +extern int RTW_STATUS_CODE(int error_code); + +#define CONFIG_USE_VMALLOC + +/* flags used for rtw_mstat_update() */ +enum mstat_f { + /* type: 0x00ff */ + MSTAT_TYPE_VIR = 0x00, + MSTAT_TYPE_PHY= 0x01, + MSTAT_TYPE_SKB = 0x02, + MSTAT_TYPE_USB = 0x03, + MSTAT_TYPE_MAX = 0x04, + + /* func: 0xff00 */ + MSTAT_FUNC_UNSPECIFIED = 0x00<<8, + MSTAT_FUNC_IO = 0x01<<8, + MSTAT_FUNC_TX_IO = 0x02<<8, + MSTAT_FUNC_RX_IO = 0x03<<8, + MSTAT_FUNC_TX = 0x04<<8, + MSTAT_FUNC_RX = 0x05<<8, + MSTAT_FUNC_MAX = 0x06<<8, +}; + +#define mstat_tf_idx(flags) ((flags)&0xff) +#define mstat_ff_idx(flags) (((flags)&0xff00) >> 8) + +typedef enum mstat_status{ + MSTAT_ALLOC_SUCCESS = 0, + MSTAT_ALLOC_FAIL, + MSTAT_FREE +} MSTAT_STATUS; + +#ifdef DBG_MEM_ALLOC +void rtw_mstat_update(const enum mstat_f flags, const MSTAT_STATUS status, u32 sz); +int _rtw_mstat_dump(char *buf, int len); +void rtw_mstat_dump (void); +u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_vmfree(u8 *pbuf, const enum mstat_f flags, u32 sz, const char *func, const int line); +u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_mfree(u8 *pbuf, const enum mstat_f flags, u32 sz, const char *func, const int line); + +struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line); +void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line); + +#ifdef CONFIG_USB_HCI +void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, const int line); +#endif /* CONFIG_USB_HCI */ + +#ifdef CONFIG_USE_VMALLOC +#define rtw_vmalloc(sz) dbg_rtw_vmalloc((sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_zvmalloc(sz) dbg_rtw_zvmalloc((sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmfree(pbuf, sz) dbg_rtw_vmfree((pbuf), (sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmalloc_f(sz, mstat_f) dbg_rtw_vmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_zvmalloc_f(sz, mstat_f) dbg_rtw_zvmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmfree_f(pbuf, sz, mstat_f) dbg_rtw_vmfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#else /* CONFIG_USE_VMALLOC */ +#define rtw_vmalloc(sz) dbg_rtw_malloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zvmalloc(sz) dbg_rtw_zmalloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmfree(pbuf, sz) dbg_rtw_mfree((pbuf), (sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmalloc_f(sz, mstat_f) dbg_rtw_malloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zvmalloc_f(sz, mstat_f) dbg_rtw_zmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmfree_f(pbuf, sz, mstat_f) dbg_rtw_mfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#endif /* CONFIG_USE_VMALLOC */ +#define rtw_malloc(sz) dbg_rtw_malloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zmalloc(sz) dbg_rtw_zmalloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_mfree(pbuf, sz) dbg_rtw_mfree((pbuf), (sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_malloc_f(sz, mstat_f) dbg_rtw_malloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zmalloc_f(sz, mstat_f) dbg_rtw_zmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_mfree_f(pbuf, sz, mstat_f) dbg_rtw_mfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) + +#define rtw_skb_alloc(size) dbg_rtw_skb_alloc((size), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_free(skb) dbg_rtw_skb_free((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_alloc_f(size, mstat_f) dbg_rtw_skb_alloc((size), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_free_f(skb, mstat_f) dbg_rtw_skb_free((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_copy(skb) dbg_rtw_skb_copy((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_clone(skb) dbg_rtw_skb_clone((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_copy_f(skb, mstat_f) dbg_rtw_skb_copy((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_clone_f(skb, mstat_f) dbg_rtw_skb_clone((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_netif_rx(ndev, skb) dbg_rtw_netif_rx(ndev, skb, MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_queue_purge(sk_buff_head) dbg_rtw_skb_queue_purge(sk_buff_head, MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#ifdef CONFIG_USB_HCI +#define rtw_usb_buffer_alloc(dev, size, dma) dbg_rtw_usb_buffer_alloc((dev), (size), (dma), MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_free(dev, size, addr, dma) dbg_rtw_usb_buffer_free((dev), (size), (addr), (dma), MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_alloc_f(dev, size, dma, mstat_f) dbg_rtw_usb_buffer_alloc((dev), (size), (dma), ((mstat_f)&0xff00)|MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_free_f(dev, size, addr, dma, mstat_f) dbg_rtw_usb_buffer_free((dev), (size), (addr), (dma), ((mstat_f)&0xff00)|MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#endif /* CONFIG_USB_HCI */ + +#else /* DBG_MEM_ALLOC */ +#define rtw_mstat_update(flag, status, sz) do {} while(0) +#define rtw_mstat_dump() do {} while(0) +u8* _rtw_vmalloc(u32 sz); +u8* _rtw_zvmalloc(u32 sz); +void _rtw_vmfree(u8 *pbuf, u32 sz); +u8* _rtw_zmalloc(u32 sz); +u8* _rtw_malloc(u32 sz); +void _rtw_mfree(u8 *pbuf, u32 sz); + +struct sk_buff *_rtw_skb_alloc(u32 sz); +void _rtw_skb_free(struct sk_buff *skb); +struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb); +struct sk_buff *_rtw_skb_clone(struct sk_buff *skb); +int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb); +void _rtw_skb_queue_purge(struct sk_buff_head *list); + +#ifdef CONFIG_USB_HCI +void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma); +void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma); +#endif /* CONFIG_USB_HCI */ + +#ifdef CONFIG_USE_VMALLOC +#define rtw_vmalloc(sz) _rtw_vmalloc((sz)) +#define rtw_zvmalloc(sz) _rtw_zvmalloc((sz)) +#define rtw_vmfree(pbuf, sz) _rtw_vmfree((pbuf), (sz)) +#define rtw_vmalloc_f(sz, mstat_f) _rtw_vmalloc((sz)) +#define rtw_zvmalloc_f(sz, mstat_f) _rtw_zvmalloc((sz)) +#define rtw_vmfree_f(pbuf, sz, mstat_f) _rtw_vmfree((pbuf), (sz)) +#else /* CONFIG_USE_VMALLOC */ +#define rtw_vmalloc(sz) _rtw_malloc((sz)) +#define rtw_zvmalloc(sz) _rtw_zmalloc((sz)) +#define rtw_vmfree(pbuf, sz) _rtw_mfree((pbuf), (sz)) +#define rtw_vmalloc_f(sz, mstat_f) _rtw_malloc((sz)) +#define rtw_zvmalloc_f(sz, mstat_f) _rtw_zmalloc((sz)) +#define rtw_vmfree_f(pbuf, sz, mstat_f) _rtw_mfree((pbuf), (sz)) +#endif /* CONFIG_USE_VMALLOC */ +#define rtw_malloc(sz) _rtw_malloc((sz)) +#define rtw_zmalloc(sz) _rtw_zmalloc((sz)) +#define rtw_mfree(pbuf, sz) _rtw_mfree((pbuf), (sz)) +#define rtw_malloc_f(sz, mstat_f) _rtw_malloc((sz)) +#define rtw_zmalloc_f(sz, mstat_f) _rtw_zmalloc((sz)) +#define rtw_mfree_f(pbuf, sz, mstat_f) _rtw_mfree((pbuf), (sz)) + +#define rtw_skb_alloc(size) _rtw_skb_alloc((size)) +#define rtw_skb_free(skb) _rtw_skb_free((skb)) +#define rtw_skb_alloc_f(size, mstat_f) _rtw_skb_alloc((size)) +#define rtw_skb_free_f(skb, mstat_f) _rtw_skb_free((skb)) +#define rtw_skb_copy(skb) _rtw_skb_copy((skb)) +#define rtw_skb_clone(skb) _rtw_skb_clone((skb)) +#define rtw_skb_copy_f(skb, mstat_f) _rtw_skb_copy((skb)) +#define rtw_skb_clone_f(skb, mstat_f) _rtw_skb_clone((skb)) +#define rtw_netif_rx(ndev, skb) _rtw_netif_rx(ndev, skb) +#define rtw_skb_queue_purge(sk_buff_head) _rtw_skb_queue_purge(sk_buff_head) +#ifdef CONFIG_USB_HCI +#define rtw_usb_buffer_alloc(dev, size, dma) _rtw_usb_buffer_alloc((dev), (size), (dma)) +#define rtw_usb_buffer_free(dev, size, addr, dma) _rtw_usb_buffer_free((dev), (size), (addr), (dma)) +#define rtw_usb_buffer_alloc_f(dev, size, dma, mstat_f) _rtw_usb_buffer_alloc((dev), (size), (dma)) +#define rtw_usb_buffer_free_f(dev, size, addr, dma, mstat_f) _rtw_usb_buffer_free((dev), (size), (addr), (dma)) +#endif /* CONFIG_USB_HCI */ +#endif /* DBG_MEM_ALLOC */ + +extern void* rtw_malloc2d(int h, int w, int size); +extern void rtw_mfree2d(void *pbuf, int h, int w, int size); + +extern void _rtw_memcpy(void* dec, void* sour, u32 sz); +extern int _rtw_memcmp(void *dst, void *src, u32 sz); +extern void _rtw_memset(void *pbuf, int c, u32 sz); + +extern void _rtw_init_listhead(_list *list); +extern u32 rtw_is_list_empty(_list *phead); +extern void rtw_list_insert_head(_list *plist, _list *phead); +extern void rtw_list_insert_tail(_list *plist, _list *phead); +#ifndef PLATFORM_FREEBSD +extern void rtw_list_delete(_list *plist); +#endif //PLATFORM_FREEBSD + +extern void _rtw_init_sema(_sema *sema, int init_val); +extern void _rtw_free_sema(_sema *sema); +extern void _rtw_up_sema(_sema *sema); +extern u32 _rtw_down_sema(_sema *sema); +extern void _rtw_mutex_init(_mutex *pmutex); +extern void _rtw_mutex_free(_mutex *pmutex); +#ifndef PLATFORM_FREEBSD +extern void _rtw_spinlock_init(_lock *plock); +#endif //PLATFORM_FREEBSD +extern void _rtw_spinlock_free(_lock *plock); +extern void _rtw_spinlock(_lock *plock); +extern void _rtw_spinunlock(_lock *plock); +extern void _rtw_spinlock_ex(_lock *plock); +extern void _rtw_spinunlock_ex(_lock *plock); + +extern void _rtw_init_queue(_queue *pqueue); +extern u32 _rtw_queue_empty(_queue *pqueue); +extern u32 rtw_end_of_queue_search(_list *queue, _list *pelement); + +extern u32 rtw_get_current_time(void); +extern u32 rtw_systime_to_ms(u32 systime); +extern u32 rtw_ms_to_systime(u32 ms); +extern s32 rtw_get_passing_time_ms(u32 start); +extern s32 rtw_get_time_interval_ms(u32 start, u32 end); + +extern void rtw_sleep_schedulable(int ms); + +extern void rtw_msleep_os(int ms); +extern void rtw_usleep_os(int us); + +extern u32 rtw_atoi(u8* s); + +#ifdef DBG_DELAY_OS +#define rtw_mdelay_os(ms) _rtw_mdelay_os((ms), __FUNCTION__, __LINE__) +#define rtw_udelay_os(ms) _rtw_udelay_os((ms), __FUNCTION__, __LINE__) +extern void _rtw_mdelay_os(int ms, const char *func, const int line); +extern void _rtw_udelay_os(int us, const char *func, const int line); +#else +extern void rtw_mdelay_os(int ms); +extern void rtw_udelay_os(int us); +#endif + +extern void rtw_yield_os(void); + + +__inline static unsigned char _cancel_timer_ex(_timer *ptimer) +{ +#ifdef PLATFORM_LINUX + return del_timer_sync(ptimer); +#endif +#ifdef PLATFORM_FREEBSD + _cancel_timer(ptimer,0); + return 0; +#endif +#ifdef PLATFORM_WINDOWS + u8 bcancelled; + + _cancel_timer(ptimer, &bcancelled); + + return bcancelled; +#endif +} + +#ifdef PLATFORM_FREEBSD +static __inline void thread_enter(void *context); +#endif //PLATFORM_FREEBSD +static __inline void thread_enter(char *name) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) + daemonize("%s", name); + #endif + allow_signal(SIGTERM); +#endif +#ifdef PLATFORM_FREEBSD + printf("%s", "RTKTHREAD_enter"); +#endif +} + +#ifdef PLATFORM_FREEBSD +#define thread_exit() do{printf("%s", "RTKTHREAD_exit");}while(0) +#endif //PLATFORM_FREEBSD +__inline static void flush_signals_thread(void) +{ +#ifdef PLATFORM_LINUX + if (signal_pending (current)) + { + flush_signals(current); + } +#endif +} + +__inline static _OS_STATUS res_to_status(sint res) +{ + + +#if defined (PLATFORM_LINUX) || defined (PLATFORM_MPIXEL) || defined (PLATFORM_FREEBSD) + return res; +#endif + +#ifdef PLATFORM_WINDOWS + + if (res == _SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; + +#endif + +} + +__inline static void rtw_dump_stack(void) +{ +#ifdef PLATFORM_LINUX + dump_stack(); +#endif +} + +#ifdef PLATFORM_LINUX +#define rtw_warn_on(condition) WARN_ON(condition) +#else +#define rtw_warn_on(condition) do {} while (0) +#endif + +#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) +#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) + +__inline static u32 _RND4(u32 sz) +{ + + u32 val; + + val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; + + return val; + +} + +__inline static u32 _RND8(u32 sz) +{ + + u32 val; + + val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; + + return val; + +} + +__inline static u32 _RND128(u32 sz) +{ + + u32 val; + + val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; + + return val; + +} + +__inline static u32 _RND256(u32 sz) +{ + + u32 val; + + val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; + + return val; + +} + +__inline static u32 _RND512(u32 sz) +{ + + u32 val; + + val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; + + return val; + +} + +__inline static u32 bitshift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) + if (((bitmask>>i) & 0x1) == 1) break; + + return i; +} + +#ifndef MAC_FMT +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#endif +#ifndef MAC_ARG +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] +#endif + +//#ifdef __GNUC__ +#ifdef PLATFORM_LINUX +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define STRUCT_PACKED +#endif + + +// limitation of path length +#ifdef PLATFORM_LINUX + #define PATH_LENGTH_MAX PATH_MAX +#elif defined(PLATFORM_WINDOWS) + #define PATH_LENGTH_MAX MAX_PATH +#endif + + +// Suspend lock prevent system from going suspend +#ifdef CONFIG_WAKELOCK +#include +#elif defined(CONFIG_ANDROID_POWER) +#include +#endif + +extern void rtw_suspend_lock_init(void); +extern void rtw_suspend_lock_uninit(void); +extern void rtw_lock_suspend(void); +extern void rtw_unlock_suspend(void); +extern void rtw_lock_suspend_timeout(u32 timeout_ms); + + +//Atomic integer operations +#ifdef PLATFORM_LINUX + #define ATOMIC_T atomic_t +#elif defined(PLATFORM_WINDOWS) + #define ATOMIC_T LONG +#elif defined(PLATFORM_FREEBSD) + typedef uint32_t ATOMIC_T ; +#endif + +extern void ATOMIC_SET(ATOMIC_T *v, int i); +extern int ATOMIC_READ(ATOMIC_T *v); +extern void ATOMIC_ADD(ATOMIC_T *v, int i); +extern void ATOMIC_SUB(ATOMIC_T *v, int i); +extern void ATOMIC_INC(ATOMIC_T *v); +extern void ATOMIC_DEC(ATOMIC_T *v); +extern int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i); +extern int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i); +extern int ATOMIC_INC_RETURN(ATOMIC_T *v); +extern int ATOMIC_DEC_RETURN(ATOMIC_T *v); + +//File operation APIs, just for linux now +extern int rtw_is_file_readable(char *path); +extern int rtw_retrive_from_file(char *path, u8* buf, u32 sz); +extern int rtw_store_to_file(char *path, u8* buf, u32 sz); + + +#if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR +struct rtw_netdev_priv_indicator { + void *priv; + u32 sizeof_priv; +}; +struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); +extern struct net_device * rtw_alloc_etherdev(int sizeof_priv); + +#ifndef PLATFORM_FREEBSD +#define rtw_netdev_priv(netdev) ( ((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv ) +#else //PLATFORM_FREEBSD +#define rtw_netdev_priv(netdev) (((struct ifnet *)netdev)->if_softc) +#endif //PLATFORM_FREEBSD + +#ifndef PLATFORM_FREEBSD +extern void rtw_free_netdev(struct net_device * netdev); +#else //PLATFORM_FREEBSD +#define rtw_free_netdev(netdev) if_free((netdev)) +#endif //PLATFORM_FREEBSD + +#else //MEM_ALLOC_REFINE_ADAPTOR + +#define rtw_alloc_etherdev(sizeof_priv) alloc_etherdev((sizeof_priv)) + +#ifndef PLATFORM_FREEBSD +#define rtw_netdev_priv(netdev) netdev_priv((netdev)) +#define rtw_free_netdev(netdev) free_netdev((netdev)) +#else //PLATFORM_FREEBSD +#define rtw_netdev_priv(netdev) (((struct ifnet *)netdev)->if_softc) +#define rtw_free_netdev(netdev) if_free((netdev)) +#endif //PLATFORM_FREEBSD +#endif + +#ifdef PLATFORM_LINUX +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) ndev->name +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) adapter->pnetdev->name +#define FUNC_NDEV_FMT "%s(%s)" +#define FUNC_NDEV_ARG(ndev) __func__, ndev->name +#define FUNC_ADPT_FMT "%s(%s)" +#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name +#else +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) "" +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) "" +#define FUNC_NDEV_FMT "%s" +#define FUNC_NDEV_ARG(ndev) __func__ +#define FUNC_ADPT_FMT "%s" +#define FUNC_ADPT_ARG(adapter) __func__ +#endif + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1) +#else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define rtw_signal_process(pid, sig) kill_proc((pid), (sig), 1) +#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#endif //PLATFORM_LINUX + +extern u64 rtw_modular64(u64 x, u64 y); +extern u64 rtw_division64(u64 x, u64 y); + + +/* Macros for handling unaligned memory accesses */ + +#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) +#define RTW_PUT_BE16(a, val) \ + do { \ + (a)[0] = ((u16) (val)) >> 8; \ + (a)[1] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define RTW_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32) (a)[2])) +#define RTW_PUT_BE24(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[2] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) +#define RTW_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ + (((u32) (a)[1]) << 8) | ((u32) (a)[0])) +#define RTW_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ + (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ + (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ + (((u64) (a)[6]) << 8) | ((u64) (a)[7])) +#define RTW_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ + (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ + (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ + (((u64) (a)[1]) << 8) | ((u64) (a)[0])) + +void rtw_buf_free(u8 **buf, u32 *buf_len); +void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); + +struct rtw_cbuf { + u32 write; + u32 read; + u32 size; + void *bufs[0]; +}; + +bool rtw_cbuf_full(struct rtw_cbuf *cbuf); +bool rtw_cbuf_empty(struct rtw_cbuf *cbuf); +bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf); +void *rtw_cbuf_pop(struct rtw_cbuf *cbuf); +struct rtw_cbuf *rtw_cbuf_alloc(u32 size); +void rtw_cbuf_free(struct rtw_cbuf *cbuf); + +#endif + + diff --git a/rtl8192cu-fixes/include/pci_hal.h b/rtl8192cu-fixes/include/pci_hal.h new file mode 100755 index 00000000..1ee0ee2c --- /dev/null +++ b/rtl8192cu-fixes/include/pci_hal.h @@ -0,0 +1,168 @@ +/****************************************************************************** + * + * 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 __PCI_HAL_H__ +#define __PCI_HAL_H__ + + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define PCI_MAX_BRIDGE_NUMBER 255 +#define PCI_MAX_DEVICES 32 +#define PCI_MAX_FUNCTION 8 + +#define PCI_CONF_ADDRESS 0x0CF8 // PCI Configuration Space Address +#define PCI_CONF_DATA 0x0CFC // PCI Configuration Space Data + +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 + +#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define PCI_VENDER_ID_REALTEK 0x10ec + +#define HAL_HW_PCI_8180_DEVICE_ID 0x8180 +#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 //8185 or 8185b +#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 //8185b +#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 //8185b +#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 //8190 +#define HAL_HW_PCI_8723E_DEVICE_ID 0x8723 //8723E +#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 //8192 PCI-E +#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 //8192 SE +#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 //8192 SE +#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 //8191 SE Crab +#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 //8191 SE RE +#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 //8191 SE Unicron +#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 //8190 PCI for Ceraga +#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 //8190 Cardbus for Ceraga +#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 //8192e PCIE for Ceraga +#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 //8192e Express Card for Ceraga +#define HAL_HW_PCI_700F_DEVICE_ID 0x700F +#define HAL_HW_PCI_701F_DEVICE_ID 0x701F +#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304 +#define HAL_HW_PCI_8192CET_DEVICE_ID 0x8191 //8192ce +#define HAL_HW_PCI_8192CE_DEVICE_ID 0x8178 //8192ce +#define HAL_HW_PCI_8191CE_DEVICE_ID 0x8177 //8192ce +#define HAL_HW_PCI_8188CE_DEVICE_ID 0x8176 //8192ce +#define HAL_HW_PCI_8192CU_DEVICE_ID 0x8191 //8192ce +#define HAL_HW_PCI_8192DE_DEVICE_ID 0x8193 //8192de +#define HAL_HW_PCI_002B_DEVICE_ID 0x002B //8192de, provided by HW SD + +#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 //8190 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192SE 0x10 +#define HAL_HW_PCI_REVISION_ID_8192CE 0x1 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192DE 0x0 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 //8192 support 16 pages of IO registers + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0,//0b'0000,0001 + PCI_BRIDGE_VENDOR_ATI, //= 0x02,//0b'0000,0010 + PCI_BRIDGE_VENDOR_AMD, //= 0x04,//0b'0000,0100 + PCI_BRIDGE_VENDOR_SIS ,//= 0x08,//0b'0000,1000 + PCI_BRIDGE_VENDOR_UNKNOWN, //= 0x40,//0b'0100,0000 + PCI_BRIDGE_VENDOR_MAX ,//= 0x80 +} ; + +struct rt_pci_capabilities_header { + u8 capability_id; + u8 next; +}; + +struct pci_priv{ + u8 linkctrl_reg; + + u8 busnumber; + u8 devnumber; + u8 funcnumber; + + u8 pcibridge_busnum; + u8 pcibridge_devnum; + u8 pcibridge_funcnum; + u8 pcibridge_vendor; + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + u8 pcibridge_pciehdr_offset; + u8 pcibridge_linkctrlreg; + + u8 amd_l1_patch; +}; + +typedef struct _RT_ISR_CONTENT +{ + union{ + u32 IntArray[2]; + u32 IntReg4Byte; + u16 IntReg2Byte; + }; +}RT_ISR_CONTENT, *PRT_ISR_CONTENT; + +//#define RegAddr(addr) (addr + 0xB2000000UL) +//some platform macros will def here +static inline void NdisRawWritePortUlong(u32 port, u32 val) +{ + outl(val, port); + //writel(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawWritePortUchar(u32 port, u8 val) +{ + outb(val, port); + //writeb(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUchar(u32 port, u8 *pval) +{ + *pval = inb(port); + //*pval = readb((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUshort(u32 port, u16 *pval) +{ + *pval = inw(port); + //*pval = readw((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUlong(u32 port, u32 *pval) +{ + *pval = inl(port); + //*pval = readl((u8 *)RegAddr(port)); +} + +#ifdef CONFIG_RTL8192C +void rtl8192ce_set_hal_ops(_adapter * padapter); +#endif +#ifdef CONFIG_RTL8192D +void rtl8192de_set_hal_ops(_adapter * padapter); +#endif + +#endif //__PCIE_HAL_H__ + diff --git a/rtl8192cu-fixes/include/pci_ops.h b/rtl8192cu-fixes/include/pci_ops.h new file mode 100755 index 00000000..9404ff44 --- /dev/null +++ b/rtl8192cu-fixes/include/pci_ops.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * 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 __PCI_OPS_H_ +#define __PCI_OPS_H_ + +#include +#include +#include +#include + +#ifdef CONFIG_RTL8192C +u32 rtl8192ce_init_desc_ring(_adapter * padapter); +u32 rtl8192ce_free_desc_ring(_adapter * padapter); +void rtl8192ce_reset_desc_ring(_adapter * padapter); +#ifdef CONFIG_64BIT_DMA +u8 PlatformEnable92CEDMA64(PADAPTER Adapter); +#endif +int rtl8192ce_interrupt(PADAPTER Adapter); +void rtl8192ce_xmit_tasklet(void *priv); +void rtl8192ce_recv_tasklet(void *priv); +void rtl8192ce_prepare_bcn_tasklet(void *priv); +void rtl8192ce_set_intf_ops(struct _io_ops *pops); +#define pci_set_intf_ops rtl8192ce_set_intf_ops +#endif + +#ifdef CONFIG_RTL8192D +u32 rtl8192de_init_desc_ring(_adapter * padapter); +u32 rtl8192de_free_desc_ring(_adapter * padapter); +void rtl8192de_reset_desc_ring(_adapter * padapter); +#ifdef CONFIG_64BIT_DMA +u8 PlatformEnable92DEDMA64(PADAPTER Adapter); +#endif +int rtl8192de_interrupt(PADAPTER Adapter); +void rtl8192de_xmit_tasklet(void *priv); +void rtl8192de_recv_tasklet(void *priv); +void rtl8192de_prepare_bcn_tasklet(void *priv); +void rtl8192de_set_intf_ops(struct _io_ops *pops); +#define pci_set_intf_ops rtl8192de_set_intf_ops +u32 MpReadPCIDwordDBI8192D(IN PADAPTER Adapter, IN u16 Offset, IN u8 Direct); +void MpWritePCIDwordDBI8192D(IN PADAPTER Adapter, IN u16 Offset, IN u32 Value, IN u8 Direct); +#endif + +#endif diff --git a/rtl8192cu-fixes/include/pci_osintf.h b/rtl8192cu-fixes/include/pci_osintf.h new file mode 100755 index 00000000..09715af4 --- /dev/null +++ b/rtl8192cu-fixes/include/pci_osintf.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * 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 __PCI_OSINTF_H +#define __PCI_OSINTF_H + +#include +#include +#include + + +void rtw_pci_disable_aspm(_adapter *padapter); +void rtw_pci_enable_aspm(_adapter *padapter); + + +#endif + diff --git a/rtl8192cu-fixes/include/recv_osdep.h b/rtl8192cu-fixes/include/recv_osdep.h new file mode 100755 index 00000000..536ed310 --- /dev/null +++ b/rtl8192cu-fixes/include/recv_osdep.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * 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 __RECV_OSDEP_H_ +#define __RECV_OSDEP_H_ + +#include +#include +#include + + +extern sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +extern void _rtw_free_recv_priv (struct recv_priv *precvpriv); + + +extern s32 rtw_recv_entry(union recv_frame *precv_frame); +extern int rtw_recv_indicatepkt(_adapter *adapter, union recv_frame *precv_frame); +extern void rtw_recv_returnpacket(IN _nic_hdl cnxt, IN _pkt *preturnedpkt); + +extern void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame); +extern void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup); + + +int rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +void rtw_free_recv_priv (struct recv_priv *precvpriv); + + +int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter); +int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe); +void rtw_os_recv_resource_free(struct recv_priv *precvpriv); + + +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); + +void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf); + +void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); + + +#endif // + diff --git a/rtl8192cu-fixes/include/rtl8192c_cmd.h b/rtl8192cu-fixes/include/rtl8192c_cmd.h new file mode 100755 index 00000000..c54cc313 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_cmd.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * 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 __RTL8192C_CMD_H_ +#define __RTL8192C_CMD_H_ + + +enum cmd_msg_element_id +{ + NONE_CMDMSG_EID, + AP_OFFLOAD_EID=0, + SET_PWRMODE_EID=1, + JOINBSS_RPT_EID=2, + RSVD_PAGE_EID=3, + RSSI_4_EID = 4, + RSSI_SETTING_EID=5, + MACID_CONFIG_EID=6, + MACID_PS_MODE_EID=7, + P2P_PS_OFFLOAD_EID=8, + SELECTIVE_SUSPEND_ROF_CMD=9, +#ifdef CONFIG_WOWLAN + H2C_WO_WLAN_CMD = 26, // Wake on Wlan. + EXT_MACID_PERIOD_EID = 27, // support macid to 64 + MACID64_CONFIG_EID = 28, // support macid to 64 +#endif // CONFIG_WOWLAN + P2P_PS_CTW_CMD_EID=32, + H2C_92C_IO_OFFLOAD=44, +#ifdef CONFIG_WOWLAN + KEEP_ALIVE_CONTROL_CMD=48, + DISCONNECT_DECISION_CTRL_CMD=49, + REMOTE_WAKE_CTRL_CMD=60, +#endif // CONFIG_WOWLAN + H2C_92C_TSF_SYNC=67, + H2C_92C_DISABLE_BCN_FUNC=68, + H2C_92C_RESET_TSF = 75, + H2C_92C_CMD_MAX +}; + +struct cmd_msg_parm { + u8 eid; //element id + u8 sz; // sz + u8 buf[6]; +}; + +typedef struct _SETPWRMODE_PARM{ + u8 Mode; + u8 SmartPS; + u8 BcnPassTime; // unit: 100ms +}SETPWRMODE_PARM, *PSETPWRMODE_PARM; + +#ifdef CONFIG_WOWLAN +typedef struct _SETWOWLAN_PARM{ + u8 mode; + u8 gpio_index; + u8 gpio_duration; + u8 second_mode; + u8 reserve; +}SETWOWLAN_PARM, *PSETWOWLAN_PARM; + +#define FW_WOWLAN_FUN_EN BIT(0) +#define FW_WOWLAN_PATTERN_MATCH BIT(1) +#define FW_WOWLAN_MAGIC_PKT BIT(2) +#define FW_WOWLAN_UNICAST BIT(3) +#define FW_WOWLAN_ALL_PKT_DROP BIT(4) +#define FW_WOWLAN_GPIO_ACTIVE BIT(5) +#define FW_WOWLAN_REKEY_WAKEUP BIT(6) +#define FW_WOWLAN_DEAUTH_WAKEUP BIT(7) + +#define FW_WOWLAN_GPIO_WAKEUP_EN BIT(0) +#define FW_FW_PARSE_MAGIC_PKT BIT(1) +#endif // CONFIG_WOWLAN + +struct H2C_SS_RFOFF_PARAM{ + u8 ROFOn; // 1: on, 0:off + u16 gpio_period; // unit: 1024 us +}__attribute__ ((packed)); + + +typedef struct JOINBSSRPT_PARM{ + u8 OpMode; // RT_MEDIA_STATUS +}JOINBSSRPT_PARM, *PJOINBSSRPT_PARM; + +typedef struct _RSVDPAGE_LOC{ + u8 LocProbeRsp; + u8 LocPsPoll; + u8 LocNullData; +}RSVDPAGE_LOC, *PRSVDPAGE_LOC; + +struct P2P_PS_Offload_t { + unsigned char Offload_En:1; + unsigned char role:1; // 1: Owner, 0: Client + unsigned char CTWindow_En:1; + unsigned char NoA0_En:1; + unsigned char NoA1_En:1; + unsigned char AllStaSleep:1; // Only valid in Owner + unsigned char discovery:1; + unsigned char rsvd:1; +}; + +struct P2P_PS_CTWPeriod_t { + unsigned char CTWPeriod; //TU +}; + +// host message to firmware cmd +void rtl8192c_set_FwPwrMode_cmd(_adapter*padapter, u8 Mode); +void rtl8192c_set_FwJoinBssReport_cmd(_adapter* padapter, u8 mstatus); +u8 rtl8192c_set_rssi_cmd(_adapter*padapter, u8 *param); +u8 rtl8192c_set_raid_cmd(_adapter*padapter, u32 mask, u8 arg); +void rtl8192c_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8 arg); +u8 rtl8192c_set_FwSelectSuspend_cmd(_adapter*padapter,u8 bfwpoll, u16 period); +#ifdef CONFIG_P2P +void rtl8192c_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +#ifdef CONFIG_IOL +typedef struct _IO_OFFLOAD_LOC{ + u8 LocCmd; +}IO_OFFLOAD_LOC, *PIO_OFFLOAD_LOC; +int rtl8192c_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms); +#endif //CONFIG_IOL + +#ifdef CONFIG_BEACON_DISABLE_OFFLOAD +u8 rtl8192c_dis_beacon_fun_cmd(_adapter* padapter); +#endif // CONFIG_BEACON_DISABLE_OFFLOAD + + +#ifdef CONFIG_TSF_RESET_OFFLOAD +int reset_tsf(PADAPTER Adapter, u8 reset_port ); +#endif // CONFIG_TSF_RESET_OFFLOAD + +#ifdef CONFIG_WOWLAN +void rtl8192c_set_wowlan_cmd(_adapter* padapter); +void SetFwRelatedForWoWLAN8192CU(_adapter* padapter,u8 bHostIsGoingtoSleep); +#endif // CONFIG_WOWLAN + +#endif // __RTL8192C_CMD_H_ + diff --git a/rtl8192cu-fixes/include/rtl8192c_dm.h b/rtl8192cu-fixes/include/rtl8192c_dm.h new file mode 100755 index 00000000..9d065405 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_dm.h @@ -0,0 +1,516 @@ +/****************************************************************************** + * + * 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 __RTL8192C_DM_H__ +#define __RTL8192C_DM_H__ +//============================================================ +// Description: +// +// This file is for 92CE/92CU dynamic mechanism only +// +// +//============================================================ + +#define RSSI_CCK 0 +#define RSSI_OFDM 1 +#define RSSI_DEFAULT 2 + +//============================================================ +// structure and define +//============================================================ + +typedef struct _FALSE_ALARM_STATISTICS{ + u32 Cnt_Parity_Fail; + u32 Cnt_Rate_Illegal; + u32 Cnt_Crc8_fail; + u32 Cnt_Mcs_fail; + u32 Cnt_Ofdm_fail; + u32 Cnt_Cck_fail; + u32 Cnt_all; + u32 Cnt_Fast_Fsync; + u32 Cnt_SB_Search_fail; +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; + +typedef struct _Dynamic_Power_Saving_ +{ + u8 PreCCAState; + u8 CurCCAState; + + u8 PreRFState; + u8 CurRFState; + + s32 Rssi_val_min; + +}PS_T; + +typedef struct _Dynamic_Initial_Gain_Threshold_ +{ + u8 Dig_Enable_Flag; + u8 Dig_Ext_Port_Stage; + + int RssiLowThresh; + int RssiHighThresh; + + u32 FALowThresh; + u32 FAHighThresh; + + u8 CurSTAConnectState; + u8 PreSTAConnectState; + u8 CurMultiSTAConnectState; + + u8 PreIGValue; + u8 CurIGValue; + u8 BackupIGValue; + + char BackoffVal; + char BackoffVal_range_max; + char BackoffVal_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 Rssi_val_min; + + u8 PreCCKPDState; + u8 CurCCKPDState; + u8 PreCCKFAState; + u8 CurCCKFAState; + u8 PreCCAState; + u8 CurCCAState; + + u8 LargeFAHit; + u8 ForbiddenIGI; + u32 Recover_cnt; + u8 rx_gain_range_min_nolink; + +}DIG_T; + +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_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_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; + +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; + + + +typedef enum _BT_Ant_NUM{ + Ant_x2 = 0, + Ant_x1 = 1 +} BT_Ant_NUM, *PBT_Ant_NUM; + +typedef enum _BT_CoType{ + BT_2Wire = 0, + BT_ISSC_3Wire = 1, + BT_Accel = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, +} BT_CoType, *PBT_CoType; + +typedef enum _BT_CurState{ + BT_OFF = 0, + BT_ON = 1, +} BT_CurState, *PBT_CurState; + +typedef enum _BT_ServiceType{ + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_Idle = 3, + BT_Scan = 4, + BT_Idle = 5, + BT_OtherAction = 6, + BT_Busy = 7, + BT_OtherBusy = 8, + BT_PAN = 9, +} BT_ServiceType, *PBT_ServiceType; + +typedef enum _BT_RadioShared{ + BT_Radio_Shared = 0, + BT_Radio_Individual = 1, +} BT_RadioShared, *PBT_RadioShared; + +struct btcoexist_priv { + u8 BT_Coexist; + u8 BT_Ant_Num; + u8 BT_CoexistType; + u8 BT_State; + u8 BT_CUR_State; //0:on, 1:off + u8 BT_Ant_isolation; //0:good, 1:bad + u8 BT_PapeCtrl; //0:SW, 1:SW/HW dynamic + u8 BT_Service; + u8 BT_Ampdu; // 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. + u8 BT_RadioSharedType; + u32 Ratio_Tx; + u32 Ratio_PRI; + u8 BtRfRegOrigin1E; + u8 BtRfRegOrigin1F; + u8 BtRssiState; + u32 BtEdcaUL; + u32 BtEdcaDL; + u32 BT_EDCA[2]; + u8 bCOBT; + + u8 bInitSet; + u8 bBTBusyTraffic; + u8 bBTTrafficModeSet; + u8 bBTNonTrafficModeSet; + //BTTraffic BT21TrafficStatistics; + u32 CurrentState; + u32 PreviousState; + u8 BtPreRssiState; + u8 bFWCoexistAllOff; + u8 bSWCoexistAllOff; +}; + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#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 0x3e +#define DM_DIG_MIN 0x1e //0x22//0x1c + +#define DM_DIG_FA_UPPER 0x3e +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN (-4) +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RxPathSelection_SS_TH_low 30 +#define RxPathSelection_diff_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTSToSelfTHVal 30 +#define RegC38_TH 20 + +#define WAIotTHVal 25 + +//Dynamic Tx Power Control Threshold +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +#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 + +#define DM_Type_ByFW 0 +#define DM_Type_ByDriver 1 + + +typedef struct _RATE_ADAPTIVE +{ + u8 RateAdaptiveDisabled; + u8 RATRState; + u16 reserve; + + u32 HighRSSIThreshForRA; + u32 High2LowRSSIThreshForRA; + u8 Low2HighRSSIThreshForRA40M; + u32 LowRSSIThreshForRA40M; + u8 Low2HighRSSIThreshForRA20M; + u32 LowRSSIThreshForRA20M; + u32 UpperRSSIThresholdRATR; + u32 MiddleRSSIThresholdRATR; + u32 LowRSSIThresholdRATR; + u32 LowRSSIThresholdRATR40M; + u32 LowRSSIThresholdRATR20M; + u8 PingRSSIEnable; //cosa add for Netcore long range ping issue + u32 PingRSSIRATR; //cosa add for Netcore long range ping issue + u32 PingRSSIThreshForRA;//cosa add for Netcore long range ping issue + u32 LastRATR; + u8 PreRATRState; + +} RATE_ADAPTIVE, *PRATE_ADAPTIVE; + +typedef enum tag_SW_Antenna_Switch_Definition +{ + Antenna_B = 1, + Antenna_A = 2, + Antenna_MAX = 3, +}DM_SWAS_E; + +#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 + +typedef struct _SW_Antenna_Switch_ +{ + u8 try_flag; + s32 PreRSSI; + u8 CurAntenna; + u8 PreAntenna; + u8 RSSI_Trying; + u8 TestMode; + u8 bTriggerAntennaSwitch; + u8 SelectAntennaMap; + // Before link Antenna Switch check + u8 SWAS_NoLink_State; + +}SWAT_T; + + +#endif + + +struct dm_priv +{ + u8 DM_Type; + u8 DMFlag, DMFlag_tmp; + + + //for DIG + u8 bDMInitialGainEnable; + u8 binitialized; // for dm_initial_gain_Multi_STA use. + DIG_T DM_DigTable; + + PS_T DM_PSTable; + + FALSE_ALARM_STATISTICS FalseAlmCnt; + + //for rate adaptive, in fact, 88c/92c fw will handle this + u8 bUseRAMask; + RATE_ADAPTIVE RateAdaptive; + + //* Upper and Lower Signal threshold for Rate Adaptive*/ + int UndecoratedSmoothedPWDB; + int UndecoratedSmoothedCCK; + int EntryMinUndecoratedSmoothedPWDB; + int EntryMaxUndecoratedSmoothedPWDB; + + + //for High Power + u8 bDynamicTxPowerEnable; + u8 LastDTPLvl; + u8 DynamicTxHighPowerLvl;//Add by Jacken Tx Power Control for Near/Far Range 2008/03/06 + + //for tx power tracking + //u8 bTXPowerTracking; + u8 TXPowercount; + u8 bTXPowerTrackingInit; + u8 TxPowerTrackControl; //for mp mode, turn off txpwrtracking as default + u8 TM_Trigger; + + u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 + u8 ThermalValue; + u8 ThermalValue_LCK; + u8 ThermalValue_IQK; + u8 ThermalValue_DPK; + + u8 bRfPiEnable; + + //for APK + u32 APKoutput[2][2]; //path A/B; output1_1a/output1_2a + u8 bAPKdone; + u8 bAPKThermalMeterIgnore; + u8 bDPdone; + u8 bDPPathAOK; + u8 bDPPathBOK; + + //for IQK + u32 RegC04; + u32 Reg874; + u32 RegC08; + u32 RegB68; + u32 RegB6C; + u32 Reg870; + u32 Reg860; + u32 Reg864; + u32 ADDA_backup[IQK_ADDA_REG_NUM]; + u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; + u32 IQK_BB_backup_recover[9]; + u32 IQK_BB_backup[IQK_BB_REG_NUM]; + u8 PowerIndex_backup[6]; + + u8 bCCKinCH14; + + char CCK_index; + char OFDM_index[2]; + + BOOLEAN bDoneTxpower; + char CCK_index_HP; + char OFDM_index_HP[2]; + u8 ThermalValue_HP[HP_THERMAL_NUM]; + u8 ThermalValue_HP_index; + + //for TxPwrTracking + int RegE94; + int RegE9C; + int RegEB4; + int RegEBC; + + u32 TXPowerTrackingCallbackCnt; //cosa add for debug + + u32 prv_traffic_idx; // edca turbo + + // for dm_RF_Saving + u8 initialize; + u32 rf_saving_Reg874; + u32 rf_saving_RegC70; + u32 rf_saving_Reg85C; + u32 rf_saving_RegA74; + + //for Antenna diversity +#ifdef CONFIG_ANTENNA_DIVERSITY + SWAT_T DM_SWAT_Table; +#endif +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + _timer SwAntennaSwitchTimer; + + u64 lastTxOkCnt; + u64 lastRxOkCnt; + u64 TXByteCnt_A; + u64 TXByteCnt_B; + u64 RXByteCnt_A; + u64 RXByteCnt_B; + u8 DoubleComfirm; + u8 TrafficLoad; +#endif + + s32 OFDM_Pkt_Cnt; + u8 RSSI_Select; + u8 DIG_Dynamic_MIN ; + + // 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]; + +#ifdef CONFIG_DM_ADAPTIVITY + /* Ported from ODM, for ESTI Adaptivity test */ + s8 TH_L2H_ini; + s8 TH_EDCCA_HL_diff; + s8 IGI_Base; + u8 IGI_target; + bool ForceEDCCA; + u8 AdapEn_RSSI; + s8 Force_TH_H; + s8 Force_TH_L; + u8 IGI_LowerBound; + + bool bPreEdccaEnable; +#endif +}; + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ +//#define DM_MultiSTA_InitGainChangeNotify(Event) {DM_DigTable.CurMultiSTAConnectState = Event;} + + +//============================================================ +// function prototype +//============================================================ +void rtl8192c_init_dm_priv(IN PADAPTER Adapter); +void rtl8192c_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8192c_InitHalDm(IN PADAPTER Adapter); +void rtl8192c_HalDmWatchDog(IN PADAPTER Adapter); + +VOID rtl8192c_dm_CheckTXPowerTracking(IN PADAPTER Adapter); + +void rtl8192c_dm_RF_Saving(IN PADAPTER pAdapter, IN u8 bForceInNormal); + +#ifdef CONFIG_BT_COEXIST +void rtl8192c_set_dm_bt_coexist(_adapter *padapter, u8 bStart); +void rtl8192c_issue_delete_ba(_adapter *padapter, u8 dir); +#endif + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY +void SwAntDivRSSICheck8192C(_adapter *padapter ,u32 RxPWDBAll); +void SwAntDivRestAfterLink8192C(IN PADAPTER Adapter); +#endif +#ifdef CONFIG_ANTENNA_DIVERSITY +void SwAntDivCompare8192C(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +u8 SwAntDivBeforeLink8192C(IN PADAPTER Adapter); +#endif + +#endif //__HAL8190PCIDM_H__ + diff --git a/rtl8192cu-fixes/include/rtl8192c_event.h b/rtl8192cu-fixes/include/rtl8192c_event.h new file mode 100755 index 00000000..1013f74a --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_event.h @@ -0,0 +1,28 @@ +/****************************************************************************** + * + * 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 _RTL8192C_EVENT_H_ +#define _RTL8192C_EVENT_H_ + + + + +#endif + + diff --git a/rtl8192cu-fixes/include/rtl8192c_hal.h b/rtl8192cu-fixes/include/rtl8192c_hal.h new file mode 100755 index 00000000..3348971c --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_hal.h @@ -0,0 +1,937 @@ +/****************************************************************************** + * + * 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 __RTL8192C_HAL_H__ +#define __RTL8192C_HAL_H__ + +#include "hal_com.h" +#include "rtl8192c_spec.h" +#include "Hal8192CPhyReg.h" +#include "Hal8192CPhyCfg.h" +#include "rtl8192c_rf.h" +#include "rtl8192c_dm.h" +#include "rtl8192c_recv.h" +#include "rtl8192c_xmit.h" +#include "rtl8192c_cmd.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8192c_sreset.h" +#endif + +#ifdef CONFIG_PCI_HCI + + #include "Hal8192CEHWImg.h" + + #define RTL819X_DEFAULT_RF_TYPE RF_2T2R + //#define RTL819X_DEFAULT_RF_TYPE RF_1T2R + #define RTL819X_TOTAL_RF_PATH 2 + + //2TODO: The following need to check!! + #define RTL8192C_FW_TSMC_IMG "rtl8192CE\\rtl8192cfwT.bin" + #define RTL8192C_FW_UMC_IMG "rtl8192CE\\rtl8192cfwU.bin" + #define RTL8192C_FW_UMC_B_IMG "rtl8192CE\\rtl8192cfwU_B.bin" + + #define RTL8188C_PHY_REG "rtl8192CE\\PHY_REG_1T.txt" + #define RTL8188C_PHY_RADIO_A "rtl8192CE\\radio_a_1T.txt" + #define RTL8188C_PHY_RADIO_B "rtl8192CE\\radio_b_1T.txt" + #define RTL8188C_AGC_TAB "rtl8192CE\\AGC_TAB_1T.txt" + #define RTL8188C_PHY_MACREG "rtl8192CE\\MACREG_1T.txt" + + #define RTL8192C_PHY_REG "rtl8192CE\\PHY_REG_2T.txt" + #define RTL8192C_PHY_RADIO_A "rtl8192CE\\radio_a_2T.txt" + #define RTL8192C_PHY_RADIO_B "rtl8192CE\\radio_b_2T.txt" + #define RTL8192C_AGC_TAB "rtl8192CE\\AGC_TAB_2T.txt" + #define RTL8192C_PHY_MACREG "rtl8192CE\\MACREG_2T.txt" + + #define RTL819X_PHY_MACPHY_REG "rtl8192CE\\MACPHY_reg.txt" + #define RTL819X_PHY_MACPHY_REG_PG "rtl8192CE\\MACPHY_reg_PG.txt" + #define RTL819X_PHY_MACREG "rtl8192CE\\MAC_REG.txt" + #define RTL819X_PHY_REG "rtl8192CE\\PHY_REG.txt" + #define RTL819X_PHY_REG_1T2R "rtl8192CE\\PHY_REG_1T2R.txt" + #define RTL819X_PHY_REG_to1T1R "rtl8192CE\\phy_to1T1R_a.txt" + #define RTL819X_PHY_REG_to1T2R "rtl8192CE\\phy_to1T2R.txt" + #define RTL819X_PHY_REG_to2T2R "rtl8192CE\\phy_to2T2R.txt" + #define RTL819X_PHY_REG_PG "rtl8192CE\\PHY_REG_PG.txt" + #define RTL819X_AGC_TAB "rtl8192CE\\AGC_TAB.txt" + #define RTL819X_PHY_RADIO_A "rtl8192CE\\radio_a.txt" + #define RTL819X_PHY_RADIO_A_1T "rtl8192CE\\radio_a_1t.txt" + #define RTL819X_PHY_RADIO_A_2T "rtl8192CE\\radio_a_2t.txt" + #define RTL819X_PHY_RADIO_B "rtl8192CE\\radio_b.txt" + #define RTL819X_PHY_RADIO_B_GM "rtl8192CE\\radio_b_gm.txt" + #define RTL819X_PHY_RADIO_C "rtl8192CE\\radio_c.txt" + #define RTL819X_PHY_RADIO_D "rtl8192CE\\radio_d.txt" + #define RTL819X_EEPROM_MAP "rtl8192CE\\8192ce.map" + #define RTL819X_EFUSE_MAP "rtl8192CE\\8192ce.map" + +//--------------------------------------------------------------------- +// RTL8723E From file +//--------------------------------------------------------------------- + #define RTL8723_FW_UMC_IMG "rtl8723E\\rtl8723fw.bin" + #define RTL8723_PHY_REG "rtl8723E\\PHY_REG_1T.txt" + #define RTL8723_PHY_RADIO_A "rtl8723E\\radio_a_1T.txt" + #define RTL8723_PHY_RADIO_B "rtl8723E\\radio_b_1T.txt" + #define RTL8723_AGC_TAB "rtl8723E\\AGC_TAB_1T.txt" + #define RTL8723_PHY_MACREG "rtl8723E\\MAC_REG.txt" + #define RTL8723_PHY_MACREG "rtl8723E\\MAC_REG.txt" + #define RTL8723_PHY_REG_PG "rtl8723E\\PHY_REG_PG.txt" + #define RTL8723_PHY_REG_MP "rtl8723E\\PHY_REG_MP.txt" + + // The file name "_2T" is for 92CE, "_1T" is for 88CE. Modified by tynli. 2009.11.24. + #define Rtl819XFwTSMCImageArray Rtl8192CEFwTSMCImgArray + #define Rtl819XFwUMCACutImageArray Rtl8192CEFwUMCACutImgArray + #define Rtl819XFwUMCBCutImageArray Rtl8192CEFwUMCBCutImgArray + + #define Rtl8723FwUMCImageArray Rtl8192CEFwUMC8723ImgArray + #define Rtl819XMAC_Array Rtl8192CEMAC_2T_Array + #define Rtl819XAGCTAB_2TArray Rtl8192CEAGCTAB_2TArray + #define Rtl819XAGCTAB_1TArray Rtl8192CEAGCTAB_1TArray + #define Rtl819XPHY_REG_2TArray Rtl8192CEPHY_REG_2TArray + #define Rtl819XPHY_REG_1TArray Rtl8192CEPHY_REG_1TArray + #define Rtl819XRadioA_2TArray Rtl8192CERadioA_2TArray + #define Rtl819XRadioA_1TArray Rtl8192CERadioA_1TArray + #define Rtl819XRadioB_2TArray Rtl8192CERadioB_2TArray + #define Rtl819XRadioB_1TArray Rtl8192CERadioB_1TArray + #define Rtl819XPHY_REG_Array_PG Rtl8192CEPHY_REG_Array_PG + #define Rtl819XPHY_REG_Array_MP Rtl8192CEPHY_REG_Array_MP + +#elif defined(CONFIG_USB_HCI) + + #include "Hal8192CUHWImg.h" +#ifdef CONFIG_WOWLAN + #include "Hal8192CUHWImg_wowlan.h" +#endif //CONFIG_WOWLAN + //2TODO: We should define 8192S firmware related macro settings here!! + #define RTL819X_DEFAULT_RF_TYPE RF_1T2R + #define RTL819X_TOTAL_RF_PATH 2 + + //TODO: The following need to check!! + #define RTL8192C_FW_TSMC_IMG "rtl8192CU\\rtl8192cfwT.bin" + #define RTL8192C_FW_UMC_IMG "rtl8192CU\\rtl8192cfwU.bin" + #define RTL8192C_FW_UMC_B_IMG "rtl8192CU\\rtl8192cfwU_B.bin" +#ifdef CONFIG_WOWLAN + #define RTL8192C_FW_TSMC_WW_IMG "rtl8192CU\\rtl8192cfwTww.bin" + #define RTL8192C_FW_UMC_WW_IMG "rtl8192CU\\rtl8192cfwUww.bin" + #define RTL8192C_FW_UMC_B_WW_IMG "rtl8192CU\\rtl8192cfwU_Bww.bin" +#endif // CONFIG_WOWLAN + //#define RTL819X_FW_BOOT_IMG "rtl8192CU\\boot.img" + //#define RTL819X_FW_MAIN_IMG "rtl8192CU\\main.img" + //#define RTL819X_FW_DATA_IMG "rtl8192CU\\data.img" + + #define RTL8188C_PHY_REG "rtl8188CU\\PHY_REG.txt" + #define RTL8188C_PHY_RADIO_A "rtl8188CU\\radio_a.txt" + #define RTL8188C_PHY_RADIO_B "rtl8188CU\\radio_b.txt" + #define RTL8188C_PHY_RADIO_A_mCard "rtl8192CU\\radio_a_1T_mCard.txt" + #define RTL8188C_PHY_RADIO_B_mCard "rtl8192CU\\radio_b_1T_mCard.txt" + #define RTL8188C_PHY_RADIO_A_HP "rtl8192CU\\radio_a_1T_HP.txt" + #define RTL8188C_AGC_TAB "rtl8188CU\\AGC_TAB.txt" + #define RTL8188C_PHY_MACREG "rtl8188CU\\MACREG.txt" + + #define RTL8192C_PHY_REG "rtl8192CU\\PHY_REG.txt" + #define RTL8192C_PHY_RADIO_A "rtl8192CU\\radio_a.txt" + #define RTL8192C_PHY_RADIO_B "rtl8192CU\\radio_b.txt" + #define RTL8192C_AGC_TAB "rtl8192CU\\AGC_TAB.txt" + #define RTL8192C_PHY_MACREG "rtl8192CU\\MACREG.txt" + + #define RTL819X_PHY_REG_PG "rtl8192CU\\PHY_REG_PG.txt" + +//--------------------------------------------------------------------- +// RTL8723U From file +//--------------------------------------------------------------------- + #define RTL8723_FW_UMC_IMG "rtl8723U\\rtl8723fw.bin" + #define RTL8723_PHY_REG "rtl8723U\\PHY_REG_1T.txt" + #define RTL8723_PHY_RADIO_A "rtl8723U\\radio_a_1T.txt" + #define RTL8723_PHY_RADIO_B "rtl8723U\\radio_b_1T.txt" + #define RTL8723_AGC_TAB "rtl8723U\\AGC_TAB_1T.txt" + #define RTL8723_PHY_MACREG "rtl8723U\\MAC_REG.txt" + #define RTL8723_PHY_MACREG "rtl8723U\\MAC_REG.txt" + #define RTL8723_PHY_REG_PG "rtl8723U\\PHY_REG_PG.txt" + #define RTL8723_PHY_REG_MP "rtl8723U\\PHY_REG_MP.txt" + + // The file name "_2T" is for 92CU, "_1T" is for 88CU. Modified by tynli. 2009.11.24. + #define Rtl819XFwImageArray Rtl8192CUFwTSMCImgArray + #define Rtl819XFwTSMCImageArray Rtl8192CUFwTSMCImgArray + #define Rtl819XFwUMCACutImageArray Rtl8192CUFwUMCACutImgArray + #define Rtl819XFwUMCBCutImageArray Rtl8192CUFwUMCBCutImgArray +#ifdef CONFIG_WOWLAN + #define Rtl8192C_FwTSMCWWImageArray Rtl8192CUFwTSMCWWImgArray + #define Rtl8192C_FwUMCWWImageArray Rtl8192CUFwUMCACutWWImgArray + #define Rtl8192C_FwUMCBCutWWImageArray Rtl8192CUFwUMCBCutWWImgArray +#endif //CONFIG_WOWLAN + #define Rtl819XMAC_Array Rtl8192CUMAC_2T_Array + #define Rtl819XAGCTAB_2TArray Rtl8192CUAGCTAB_2TArray + #define Rtl819XAGCTAB_1TArray Rtl8192CUAGCTAB_1TArray + #define Rtl819XAGCTAB_1T_HPArray Rtl8192CUAGCTAB_1T_HPArray + #define Rtl819XPHY_REG_2TArray Rtl8192CUPHY_REG_2TArray + #define Rtl819XPHY_REG_1TArray Rtl8192CUPHY_REG_1TArray + #define Rtl819XPHY_REG_1T_mCardArray Rtl8192CUPHY_REG_1T_mCardArray + #define Rtl819XPHY_REG_2T_mCardArray Rtl8192CUPHY_REG_2T_mCardArray + #define Rtl819XPHY_REG_1T_HPArray Rtl8192CUPHY_REG_1T_HPArray + #define Rtl819XRadioA_2TArray Rtl8192CURadioA_2TArray + #define Rtl819XRadioA_1TArray Rtl8192CURadioA_1TArray + #define Rtl819XRadioA_1T_mCardArray Rtl8192CURadioA_1T_mCardArray + #define Rtl819XRadioB_2TArray Rtl8192CURadioB_2TArray + #define Rtl819XRadioB_1TArray Rtl8192CURadioB_1TArray + #define Rtl819XRadioB_1T_mCardArray Rtl8192CURadioB_1T_mCardArray + #define Rtl819XRadioA_1T_HPArray Rtl8192CURadioA_1T_HPArray + #define Rtl819XPHY_REG_Array_PG Rtl8192CUPHY_REG_Array_PG + #define Rtl819XPHY_REG_Array_PG_mCard Rtl8192CUPHY_REG_Array_PG_mCard + #define Rtl819XPHY_REG_Array_PG_HP Rtl8192CUPHY_REG_Array_PG_HP + #define Rtl819XPHY_REG_Array_MP Rtl8192CUPHY_REG_Array_MP +#endif + +#define DRVINFO_SZ 4 // unit is 8bytes +#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len)&0x7F ? 1:0)) + +#define FW_8192C_SIZE 16384+32//16k +#define FW_8192C_START_ADDRESS 0x1000 +//#define FW_8192C_END_ADDRESS 0x3FFF //Filen said this is for test chip +#define FW_8192C_END_ADDRESS 0x1FFF + +#define MAX_PAGE_SIZE 4096 // @ page : 4k bytes + +#define IS_FW_HEADER_EXIST(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300) + +typedef enum _FIRMWARE_SOURCE{ + FW_SOURCE_IMG_FILE = 0, + FW_SOURCE_HEADER_FILE = 1, //from header file +}FIRMWARE_SOURCE, *PFIRMWARE_SOURCE; + +typedef struct _RT_FIRMWARE{ + FIRMWARE_SOURCE eFWSource; + u8* szFwBuffer; + u32 ulFwLength; +#ifdef CONFIG_WOWLAN + u8* szWoWLANFwBuffer; + u32 ulWoWLANFwLength; +#endif //CONFIG_WOWLAN +}RT_FIRMWARE, *PRT_FIRMWARE, RT_FIRMWARE_92C, *PRT_FIRMWARE_92C; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8192C_FIRMWARE_HDR {//8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u8 Subversion; // FW Subversion, default 0x00 + u16 Rsvd1; + + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; + +}RT_8192C_FIRMWARE_HDR, *PRT_8192C_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME 0x05 +#define BCN_DMA_ATIME_INT_TIME 0x02 + +#ifdef CONFIG_USB_RX_AGGREGATION + +typedef enum _USB_RX_AGG_MODE{ + USB_RX_AGG_DISABLE, + USB_RX_AGG_DMA, + USB_RX_AGG_USB, + USB_RX_AGG_MIX +}USB_RX_AGG_MODE; + +#define MAX_RX_DMA_BUFFER_SIZE 10240 // 10K for 8192C RX DMA buffer + +#endif + + +#define TX_SELE_HQ BIT(0) // High Queue +#define TX_SELE_LQ BIT(1) // Low Queue +#define TX_SELE_NQ BIT(2) // Normal Queue + + +// Note: We will divide number of page equally for each queue other than public queue! + +#define TX_TOTAL_PAGE_NUMBER 0xF8 +#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER +#define NORMAL_PAGE_NUM_PUBQ 0xE7 +#define NORMAL_PAGE_NUM_HPQ 0x0C +#define NORMAL_PAGE_NUM_LPQ 0x02 +#define NORMAL_PAGE_NUM_NPQ 0x02 + + +// For Test Chip Setting +// (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER +#define TEST_PAGE_NUM_PUBQ 0x7E + + +// For Test Chip Setting +#define WMM_TEST_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_TEST_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6 + +#define WMM_TEST_PAGE_NUM_PUBQ 0xA3 +#define WMM_TEST_PAGE_NUM_HPQ 0x29 +#define WMM_TEST_PAGE_NUM_LPQ 0x29 + + +//Note: For Normal Chip Setting ,modify later +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6 + +#define WMM_NORMAL_PAGE_NUM_PUBQ 0x65 +#define WMM_NORMAL_PAGE_NUM_HPQ 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ 0x30 +#define WMM_NORMAL_PAGE_NUM_NPQ 0x30 + +//------------------------------------------------------------------------- +// Chip specific +//------------------------------------------------------------------------- +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_88C_USB_MCARD 0x2 +#define CHIP_BONDING_88C_USB_HP 0x1 + +// +// 2011.01.06. Define new structure of chip version for RTL8723 and so on. Added by tynli. +// +/* + | BIT15:12 | BIT11:8 | BIT 7 | BIT6:4 | BIT3 | BIT2:0 | + |-------------+-----------+-----------+-------+-----------+-------| + | IC version(CUT) | ROM version | Manufacturer | RF type | Chip type | IC Type | + | | | TSMC/UMC | | TEST/NORMAL| | +*/ +// [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 +// [7] Manufacturer: TSMC=0, UMC=1 +// [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 +// [3] Chip type: TEST=0, NORMAL=1 +// [2:0] IC type: 81xxC=0, 8723=1, 92D=2 + +#define CHIP_8723 BIT(0) +#define CHIP_92D BIT(1) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(13)|BIT(14))) + + +// MASK +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + +// Get element +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0)? _TRUE : _FALSE) +#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723)? _TRUE : _FALSE) +#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == CHIP_92D)? _TRUE : _FALSE) +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version))? _FALSE : _TRUE) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)? _TRUE : _FALSE) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)? _TRUE : _FALSE) +#define IS_NORMAL_CHIP(version) ((GET_CVID_CHIP_TYPE(version))? _TRUE: _FALSE) +#define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version))? _TRUE: _FALSE) + +#define IS_81XXC_TEST_CHIP(version) ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version)))? _TRUE: _FALSE) +#define IS_92D_TEST_CHIP(version) ((IS_92D(version) && (!IS_NORMAL_CHIP(version)))? _TRUE: _FALSE) +#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ? _TRUE : _FALSE) +#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? ((GET_CVID_CUT_VERSION(version)) ? _FALSE : _TRUE) : _FALSE) +#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? ((GET_CVID_CUT_VERSION(version)) ? _FALSE : _TRUE) : _FALSE) +// 88/92C UMC B-cut vendor is set to TSMC so we need to check CHIP_VENDOR_UMC bit is not 1. +#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? _TRUE : _FALSE):_FALSE) +#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? (IS_2T2R(version) ? _TRUE: _FALSE) : _FALSE) +#define IS_92D_C_CUT(version) ((IS_92D(version)) ? ((GET_CVID_CUT_VERSION(version) == 0x2) ? _TRUE : _FALSE) : _FALSE) +#define IS_92D_D_CUT(version) ((IS_92D(version)) ? ((GET_CVID_CUT_VERSION(version) == 0x3) ? _TRUE : _FALSE) : _FALSE) + +typedef enum _VERSION_8192C{ + VERSION_TEST_CHIP_88C = 0x0000, + VERSION_TEST_CHIP_92C = 0x0020, + VERSION_TEST_UMC_CHIP_8723 = 0x0081, + VERSION_NORMAL_TSMC_CHIP_88C = 0x0008, + VERSION_NORMAL_TSMC_CHIP_92C = 0x0028, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x0018, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x0088, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x00a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x0098, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x1088, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x10a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x1090, + VERSION_TEST_CHIP_92D_SINGLEPHY= 0x0022, + VERSION_TEST_CHIP_92D_DUALPHY = 0x0002, + VERSION_NORMAL_CHIP_92D_SINGLEPHY= 0x002a, + VERSION_NORMAL_CHIP_92D_DUALPHY = 0x000a, + VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x202a, + VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x200a, + VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0x302a, + VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x300a, +}VERSION_8192C,*PVERSION_8192C; + + + +//------------------------------------------------------------------------- +// Channel Plan +//------------------------------------------------------------------------- +enum ChannelPlan{ + CHPL_FCC = 0, + CHPL_IC = 1, + CHPL_ETSI = 2, + CHPL_SPAIN = 3, + CHPL_FRANCE = 4, + CHPL_MKK = 5, + CHPL_MKK1 = 6, + CHPL_ISRAEL = 7, + CHPL_TELEC = 8, + CHPL_GLOBAL = 9, + CHPL_WORLD = 10, +}; + +typedef struct _TxPowerInfo{ + u8 CCKIndex[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40_1SIndex[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40_2SIndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + s8 HT20IndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 OFDMIndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40MaxOffset[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT20MaxOffset[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 TSSI_A; + u8 TSSI_B; +}TxPowerInfo, *PTxPowerInfo; + +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_MAP_LEN 128 +#define EFUSE_MAX_SECTION 16 +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN) +// +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 1byte|----8bytes----|1byte|--5bytes--| +// | | Reserved(14bytes) | +// +#define EFUSE_OOB_PROTECT_BYTES 15 // PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. + + +#define EFUSE_MAP_LEN_8723 256 +#define EFUSE_MAX_SECTION_8723 32 + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +// +// For RTL8723 WiFi/BT/GPS multi-function configuration. 2010.10.06. +// +typedef enum _RT_MULTI_FUNC{ + RT_MULTI_FUNC_NONE = 0x00, + RT_MULTI_FUNC_WIFI = 0x01, + RT_MULTI_FUNC_BT = 0x02, + RT_MULTI_FUNC_GPS = 0x04, +}RT_MULTI_FUNC,*PRT_MULTI_FUNC; + +// +// For RTL8723 WiFi PDn/GPIO polarity control configuration. 2010.10.08. +// +typedef enum _RT_POLARITY_CTL{ + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +}RT_POLARITY_CTL,*PRT_POLARITY_CTL; + +// For RTL8723 regulator mode. by tynli. 2011.01.14. +typedef enum _RT_REGULATOR_MODE{ + RT_SWITCHING_REGULATOR = 0, + RT_LDO_REGULATOR = 1, +}RT_REGULATOR_MODE,*PRT_REGULATOR_MODE; + +enum c2h_id_8192c { + C2H_DBG = 0, + C2H_TSF = 1, + C2H_AP_RPT_RSP = 2, + C2H_CCX_TX_RPT = 3, + C2H_BT_RSSI = 4, + C2H_BT_OP_MODE = 5, + C2H_EXT_RA_RPT = 6, + C2H_HW_INFO_EXCH = 10, + C2H_C2H_H2C_TEST = 11, + C2H_BT_INFO = 12, + C2H_BT_MP_INFO = 15, + MAX_C2HEVENT +}; + +#ifdef CONFIG_PCI_HCI +struct hal_data_8192ce +{ + VERSION_8192C VersionID; + RT_MULTI_FUNC MultiFunc; // For multi-function consideration. + RT_POLARITY_CTL PolarityCtl; // For Wifi PDn Polarity control. + RT_REGULATOR_MODE RegulatorMode; // switching regulator or LDO + u16 CustomerID; + + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + + u32 IntrMask[2]; + u32 IntrMaskToSet[2]; + + u32 DisabledFunctions; + + //current WIFI_PHY values + u32 ReceiveConfig; + u32 TransmitConfig; + WIRELESS_MODE CurrentWirelessMode; + HT_CHANNEL_WIDTH CurrentChannelBW; + u8 CurrentChannel; + u8 nCur40MhzPrimeSC;// Control channel sub-carrier + + u16 BasicRateSet; + + //rf_ctrl + _lock rf_lock; + u8 rf_chip; + u8 rf_type; + u8 NumTotalRFPath; + + INTERFACE_SELECT_8192CPCIe InterfaceSel; + + // + // EEPROM setting. + // + u16 EEPROMVID; + u16 EEPROMDID; + u16 EEPROMSVID; + u16 EEPROMSMID; + u16 EEPROMChannelPlan; + u16 EEPROMVersion; + + u8 EEPROMChnlAreaTxPwrCCK[2][3]; + u8 EEPROMChnlAreaTxPwrHT40_1S[2][3]; + u8 EEPROMChnlAreaTxPwrHT40_2SDiff[2][3]; + u8 EEPROMPwrLimitHT20[3]; + u8 EEPROMPwrLimitHT40[3]; + + u8 bTXPowerDataReadFromEEPORM; + u8 EEPROMThermalMeter; + u8 EEPROMTSSI[2]; + + u8 EEPROMCustomerID; + u8 EEPROMBoardType; + u8 EEPROMRegulatory; + + u8 bDefaultAntenna; + u8 bIQKInitialized; + + u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + s8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff + // For power group + u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + + u8 LegacyHTTxPowerDiff;// Legacy to HT rate power diff + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv bt_coexist; +#endif + + // Read/write are allow for following hardware information variables + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + u8 DefaultInitialGain[4]; + u8 pwrGroupCnt; + u32 MCSTxPowerLevelOriginalOffset[7][16]; + u32 CCKTxPowerLevelOriginalOffset; + + u32 AntennaTxPath; // Antenna path Tx + u32 AntennaRxPath; // Antenna path Rx + u8 BluetoothCoexist; + u8 ExternalPA; + + //u32 LedControlNum; + //u32 LedControlMode; + u8 bLedOpenDrain; // Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. + //u32 TxPowerTrackControl; + u8 b1x1RecvCombine; // for 1T1R receive combining + + u8 bCurrentTurboEDCA; + u32 AcParam_BE; //Original parameter for BE, use for EDCA turbo. + + //vivi, for tx power tracking, 20080407 + //u16 TSSI_13dBm; + //u32 Pwr_Track; + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + + BOOLEAN bRFPathRxEnable[4]; // We support 4 RF path now. + + u32 RfRegChnlVal[2]; + + u8 bCckHighPower; + + //RDG enable + BOOLEAN bRDGEnable; + + //for host message to fw + u8 LastHMEBoxNum; + + u8 fw_ractrl; + u8 RegTxPause; + // Beacon function related global variable. + u32 RegBcnCtrlVal; + u8 RegFwHwTxQCtrl; + u8 RegReg542; + u8 CurAntenna; + u8 AntDivCfg; + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + //SW Antenna Switch + s32 RSSI_sum_A; + s32 RSSI_sum_B; + s32 RSSI_cnt_A; + s32 RSSI_cnt_B; + BOOLEAN RSSI_test; +#endif +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + //Hybrid Antenna Diversity + u32 CCK_Ant1_Cnt; + u32 CCK_Ant2_Cnt; + u32 OFDM_Ant1_Cnt; + u32 OFDM_Ant2_Cnt; +#endif + + struct dm_priv dmpriv; + u8 bDumpRxPkt;//for debug +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv srestpriv; +#endif + u8 bInterruptMigration; + u8 bDisableTxInt; + u8 bGpioHwWpsPbc; + + u8 FwRsvdPageStartOffset; //2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. + + u16 EfuseUsedBytes; + +#ifdef CONFIG_P2P + struct P2P_PS_Offload_t p2p_ps_offload; +#endif //CONFIG_P2P +}; + +typedef struct hal_data_8192ce HAL_DATA_TYPE, *PHAL_DATA_TYPE; + +// +// Function disabled. +// +#define DF_TX_BIT BIT0 +#define DF_RX_BIT BIT1 +#define DF_IO_BIT BIT2 +#define DF_IO_D3_BIT BIT3 + +#define RT_DF_TYPE u32 +#define RT_DISABLE_FUNC(__pAdapter, __FuncBits) ((__pAdapter)->DisabledFunctions |= ((RT_DF_TYPE)(__FuncBits))) +#define RT_ENABLE_FUNC(__pAdapter, __FuncBits) ((__pAdapter)->DisabledFunctions &= (~((RT_DF_TYPE)(__FuncBits)))) +#define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) +#define IS_MULTI_FUNC_CHIP(_Adapter) (((((PHAL_DATA_TYPE)(_Adapter->HalData))->MultiFunc) & (RT_MULTI_FUNC_BT|RT_MULTI_FUNC_GPS)) ? _TRUE : _FALSE) + +void InterruptRecognized8192CE(PADAPTER Adapter, PRT_ISR_CONTENT pIsrContent); +VOID UpdateInterruptMask8192CE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif + +#ifdef CONFIG_USB_HCI +struct hal_data_8192cu +{ + VERSION_8192C VersionID; + RT_MULTI_FUNC MultiFunc; // For multi-function consideration. + RT_POLARITY_CTL PolarityCtl; // For Wifi PDn Polarity control. + RT_REGULATOR_MODE RegulatorMode; // switching regulator or LDO + u16 CustomerID; + + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + + //current WIFI_PHY values + u32 ReceiveConfig; + WIRELESS_MODE CurrentWirelessMode; + HT_CHANNEL_WIDTH CurrentChannelBW; + u8 CurrentChannel; + u8 nCur40MhzPrimeSC;// Control channel sub-carrier + + u16 BasicRateSet; + + //rf_ctrl + u8 rf_chip; + u8 rf_type; + u8 NumTotalRFPath; + + u8 BoardType; + //INTERFACE_SELECT_8192CUSB InterfaceSel; + + // + // EEPROM setting. + // + u16 EEPROMVID; + u16 EEPROMPID; + u16 EEPROMSVID; + u16 EEPROMSDID; + u8 EEPROMCustomerID; + u8 EEPROMSubCustomerID; + u8 EEPROMVersion; + u8 EEPROMRegulatory; + + u8 bTXPowerDataReadFromEEPORM; + u8 EEPROMThermalMeter; + + u8 bIQKInitialized; + + u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + s8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff + // For power group + u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + + u8 LegacyHTTxPowerDiff;// Legacy to HT rate power diff + + // Read/write are allow for following hardware information variables + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + u8 DefaultInitialGain[4]; + u8 pwrGroupCnt; + u32 MCSTxPowerLevelOriginalOffset[7][16]; + u32 CCKTxPowerLevelOriginalOffset; + + u32 AntennaTxPath; // Antenna path Tx + u32 AntennaRxPath; // Antenna path Rx + u8 BluetoothCoexist; + u8 ExternalPA; + + u8 bLedOpenDrain; // Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. + + //u32 LedControlNum; + //u32 LedControlMode; + //u32 TxPowerTrackControl; + u8 b1x1RecvCombine; // for 1T1R receive combining + + u8 bCurrentTurboEDCA; + u32 AcParam_BE; //Original parameter for BE, use for EDCA turbo. + + //vivi, for tx power tracking, 20080407 + //u16 TSSI_13dBm; + //u32 Pwr_Track; + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + + BOOLEAN bRFPathRxEnable[4]; // We support 4 RF path now. + + u32 RfRegChnlVal[2]; + + u8 bCckHighPower; + + //RDG enable + BOOLEAN bRDGEnable; + + //for host message to fw + u8 LastHMEBoxNum; + + u8 fw_ractrl; + u8 RegTxPause; + // Beacon function related global variable. + u32 RegBcnCtrlVal; + u8 RegFwHwTxQCtrl; + u8 RegReg542; + + struct dm_priv dmpriv; +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv srestpriv; +#endif + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv bt_coexist; +#endif + u8 CurAntenna; + u8 AntDivCfg; + +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + //SW Antenna Switch + s32 RSSI_sum_A; + s32 RSSI_sum_B; + s32 RSSI_cnt_A; + s32 RSSI_cnt_B; + BOOLEAN RSSI_test; +#endif +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + //Hybrid Antenna Diversity + u32 CCK_Ant1_Cnt; + u32 CCK_Ant2_Cnt; + u32 OFDM_Ant1_Cnt; + u32 OFDM_Ant2_Cnt; +#endif + + u8 bDumpRxPkt;//for debug + u8 FwRsvdPageStartOffset; //2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. + + // 2010/08/09 MH Add CU power down mode. + BOOLEAN pwrdown; + + // For 92C USB endpoint setting + // + + u32 UsbBulkOutSize; + + int RtBulkOutPipe[3]; + int RtBulkInPipe; + int RtIntInPipe; + // Add for dual MAC 0--Mac0 1--Mac1 + u32 interfaceIndex; + + u8 OutEpQueueSel; + u8 OutEpNumber; + + u8 Queue2EPNum[8];//for out endpoint number mapping + +#ifdef CONFIG_USB_TX_AGGREGATION + u8 UsbTxAggMode; + u8 UsbTxAggDescNum; +#endif +#ifdef CONFIG_USB_RX_AGGREGATION + u16 HwRxPageSize; // Hardware setting + u32 MaxUsbRxAggBlock; + + USB_RX_AGG_MODE UsbRxAggMode; + u8 UsbRxAggBlockCount; // USB Block count. Block size is 512-byte in hight speed and 64-byte in full speed + u8 UsbRxAggBlockTimeout; + u8 UsbRxAggPageCount; // 8192C DMA page count + u8 UsbRxAggPageTimeout; +#endif + + // 2010/12/10 MH Add for USB aggreation mode dynamic shceme. + BOOLEAN UsbRxHighSpeedMode; + + // 2010/11/22 MH Add for slim combo debug mode selective. + // This is used for fix the drawback of CU TSMC-A/UMC-A cut. HW auto suspend ability. Close BT clock. + BOOLEAN SlimComboDbg; + + u16 EfuseUsedBytes; + +#ifdef CONFIG_P2P + struct P2P_PS_Offload_t p2p_ps_offload; +#endif //CONFIG_P2P +}; + +typedef struct hal_data_8192cu HAL_DATA_TYPE, *PHAL_DATA_TYPE; +#endif + +#define GET_HAL_DATA(__pAdapter) ((HAL_DATA_TYPE *)((__pAdapter)->HalData)) +#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +VOID rtl8192c_FirmwareSelfReset(IN PADAPTER Adapter); +int FirmwareDownload92C(IN PADAPTER Adapter,IN BOOLEAN bUsedWoWLANFw); +VOID InitializeFirmwareVars92C(PADAPTER Adapter); +u8 GetEEPROMSize8192C(PADAPTER Adapter); +void rtl8192c_EfuseParseChnlPlan(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +VERSION_8192C rtl8192c_ReadChipVersion(IN PADAPTER Adapter); +void rtl8192c_ReadBluetoothCoexistInfo(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +//void rtl8192c_free_hal_data(_adapter * padapter); +VOID rtl8192c_EfuseParseIDCode(PADAPTER pAdapter, u8 *hwinfo); +void rtl8192c_set_hal_ops(struct hal_ops *pHalFunc); + +s32 c2h_id_filter_ccx_8192c(u8 id); +#endif + +#ifdef CONFIG_MP_INCLUDED + +extern void Hal_SetAntenna(PADAPTER pAdapter); +extern void Hal_SetBandwidth(PADAPTER pAdapter); + +extern void Hal_SetTxPower(PADAPTER pAdapter); +extern void Hal_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetSingleToneTx ( PADAPTER pAdapter , u8 bStart ); +extern void Hal_SetSingleCarrierTx (PADAPTER pAdapter, u8 bStart); +extern void Hal_SetContinuousTx (PADAPTER pAdapter, u8 bStart); + +extern void Hal_SetDataRate(PADAPTER pAdapter); +extern void Hal_SetChannel(PADAPTER pAdapter); +extern void Hal_SetAntennaPathPower(PADAPTER pAdapter); +extern s32 Hal_SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +extern s32 Hal_SetPowerTracking(PADAPTER padapter, u8 enable); +extern void Hal_GetPowerTracking(PADAPTER padapter, u8 * enable); +extern void Hal_GetThermalMeter(PADAPTER pAdapter, u8 *value); +extern void Hal_mpt_SwitchRfSetting(PADAPTER pAdapter); +extern void Hal_MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14); +extern void Hal_MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven); +extern void Hal_SetCCKTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_SetOFDMTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_TriggerRFThermalMeter(PADAPTER pAdapter); +extern u8 Hal_ReadRFThermalMeter(PADAPTER pAdapter); +extern void Hal_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart); + +#endif + + + diff --git a/rtl8192cu-fixes/include/rtl8192c_led.h b/rtl8192cu-fixes/include/rtl8192c_led.h new file mode 100755 index 00000000..1ccf9359 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_led.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * 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 __RTL8192C_LED_H_ +#define __RTL8192C_LED_H_ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8192cu_InitSwLeds(_adapter *padapter); +void rtl8192cu_DeInitSwLeds(_adapter *padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8192ce_gen_RefreshLedState(PADAPTER Adapter); +void rtl8192ce_InitSwLeds(_adapter *padapter); +void rtl8192ce_DeInitSwLeds(_adapter *padapter); +#endif + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192c_recv.h b/rtl8192cu-fixes/include/rtl8192c_recv.h new file mode 100755 index 00000000..d5656f5e --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_recv.h @@ -0,0 +1,184 @@ +/****************************************************************************** + * + * 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 _RTL8192C_RECV_H_ +#define _RTL8192C_RECV_H_ + +#include +#include +#include + + +#ifdef PLATFORM_OS_XP + #define NR_RECVBUFF (16) +#elif defined(PLATFORM_OS_CE) + #define NR_RECVBUFF (4) +#else +#ifdef CONFIG_SINGLE_RECV_BUF + #define NR_RECVBUFF (1) +#else + #define NR_RECVBUFF (4) +#endif //CONFIG_SINGLE_RECV_BUF + + #define NR_PREALLOC_RECV_SKB (8) +#endif + + +#define RECV_BLK_SZ 512 +#define RECV_BLK_CNT 16 +#define RECV_BLK_TH RECV_BLK_CNT + +#if defined(CONFIG_USB_HCI) + +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + //#define MAX_RECVBUF_SZ (32768) // 32k + //#define MAX_RECVBUF_SZ (16384) //16K + //#define MAX_RECVBUF_SZ (10240) //10K + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 +#endif + + +#define RECV_BULK_IN_ADDR 0x80 +#define RECV_INT_IN_ADDR 0x81 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 + + +struct phy_stat +{ + unsigned int phydw0; + + unsigned int phydw1; + + unsigned int phydw2; + + unsigned int phydw3; + + unsigned int phydw4; + + unsigned int phydw5; + + unsigned int phydw6; + + unsigned int phydw7; +}; + +typedef struct _Phy_OFDM_Rx_Status_Report_8192cd +{ + unsigned char trsw_gain_X[4]; + unsigned char pwdb_all; + unsigned char cfosho_X[4]; + unsigned char cfotail_X[4]; + unsigned char rxevm_X[2]; + unsigned char rxsnr_X[4]; + unsigned char pdsnr_X[2]; + unsigned char csi_current_X[2]; + unsigned char csi_target_X[2]; + unsigned char sigevm; + unsigned char max_ex_pwr; +//#ifdef RTL8192SE +#ifdef CONFIG_LITTLE_ENDIAN + unsigned char ex_intf_flg:1; + unsigned char sgi_en:1; + unsigned char rxsc:2; + //unsigned char rsvd:4; + unsigned char idle_long:1; + unsigned char r_ant_train_en:1; + unsigned char ANTSELB:1; + unsigned char ANTSEL:1; +#else // _BIG_ENDIAN_ + //unsigned char rsvd:4; + unsigned char ANTSEL:1; + unsigned char ANTSELB:1; + unsigned char r_ant_train_en:1; + unsigned char idle_long:1; + unsigned char rxsc:2; + unsigned char sgi_en:1; + unsigned char ex_intf_flg:1; +#endif +//#else // RTL8190, RTL8192E +// unsigned char sgi_en; +// unsigned char rxsc_sgien_exflg; +//#endif +} __attribute__ ((packed))PHY_STS_OFDM_8192CD_T,PHY_RX_DRIVER_INFO_8192CD; + +typedef struct _Phy_CCK_Rx_Status_Report_8192cd +{ + /* For CCK rate descriptor. This is a signed 8:1 variable. LSB bit presend + 0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */ + u8 adc_pwdb_X[4]; + u8 SQ_rpt; + u8 cck_agc_rpt; +} PHY_STS_CCK_8192CD_T; + + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + + +#ifdef CONFIG_USB_HCI +typedef struct _INTERRUPT_MSG_FORMAT_EX{ + unsigned int C2H_MSG0; + unsigned int C2H_MSG1; + unsigned int C2H_MSG2; + unsigned int C2H_MSG3; + unsigned int HISR; // from HISR Reg0x124, read to clear + unsigned int HISRE;// from HISRE Reg0x12c, read to clear + unsigned int MSG_EX; +}INTERRUPT_MSG_FORMAT_EX,*PINTERRUPT_MSG_FORMAT_EX; + +void rtl8192cu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +int rtl8192cu_init_recv_priv(_adapter * padapter); +void rtl8192cu_free_recv_priv(_adapter * padapter); +#endif + +#ifdef CONFIG_PCI_HCI +int rtl8192ce_init_recv_priv(_adapter * padapter); +void rtl8192ce_free_recv_priv(_adapter * padapter); +#endif + +void rtl8192c_translate_rx_signal_stuff(union recv_frame *precvframe, struct phy_stat *pphy_info); +void rtl8192c_query_rx_desc_status(union recv_frame *precvframe, struct recv_stat *pdesc); + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192c_rf.h b/rtl8192cu-fixes/include/rtl8192c_rf.h new file mode 100755 index 00000000..26c678a8 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_rf.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/****************************************************************************** + * + * + * Module: rtl8192c_rf.h ( Header File) + * + * Note: Collect every HAL RF type exter API or constant. + * + * Function: + * + * Export: + * + * Abbrev: + * + * History: + * Data Who Remark + * + * 09/25/2008 MHC Create initial version. + * + * +******************************************************************************/ +#ifndef _RTL8192C_RF_H_ +#define _RTL8192C_RF_H_ +/* Check to see if the file has been included already. */ + + +/*--------------------------Define Parameters-------------------------------*/ + +// +// For RF 6052 Series +// +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + +/*------------------------Export Marco Definition---------------------------*/ + +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ + +// +// RF RL6052 Series API +// +void rtl8192c_RF_ChangeTxPath( IN PADAPTER Adapter, + IN u16 DataRate); +void rtl8192c_PHY_RF6052SetBandwidth( + IN PADAPTER Adapter, + IN HT_CHANNEL_WIDTH Bandwidth); +VOID rtl8192c_PHY_RF6052SetCckTxPower( + IN PADAPTER Adapter, + IN u8* pPowerlevel); +VOID rtl8192c_PHY_RF6052SetOFDMTxPower( + IN PADAPTER Adapter, + IN u8* pPowerLevel, + IN u8 Channel); +int PHY_RF6052_Config8192C( IN PADAPTER Adapter ); + +/*--------------------------Exported Function prototype---------------------*/ + + +#endif/* End of HalRf.h */ + diff --git a/rtl8192cu-fixes/include/rtl8192c_spec.h b/rtl8192cu-fixes/include/rtl8192c_spec.h new file mode 100755 index 00000000..8ff13a7e --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_spec.h @@ -0,0 +1,1865 @@ +/****************************************************************************** + * + * 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 __RTL8192C_SPEC_H__ +#define __RTL8192C_SPEC_H__ + +#include + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + + +//============================================================ +// 8192C Regsiter offset definition +//============================================================ + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_LEDCFG REG_LEDCFG2 +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. +#define REG_GPIO_IO_SEL_2 0x0062 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. +#define REG_MULTI_FUNC_CTRL 0x0068 // RTL8723 WIFI/BT/GPS Multi-Function control source. +#define REG_MCUFWDL 0x0080 +#ifdef CONFIG_WOWLAN +#define REG_WOWLAN_REASON 0x0081 +#endif //CONFIG_WOWLAN +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E +#define REG_HOST_SUSP_CNT 0x00BC // Host suspend counter on FPGA platform +#define REG_EFUSE_ACCESS 0x00CF // Efuse access protection for RTL8723 +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 // For RTL8723 only. + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA 0x0340 // RX Queue Descriptor Address +#define REG_DBI 0x0348 // Backdoor REG for Access Configuration +#define REG_MDIO 0x0354 // MDIO for Access PCIE PHY +#define REG_DBG_SEL 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM 0x0363 //PCIe CPWM +#define REG_UART_CTRL 0x0364 // UART Control +#define REG_UART_TX_DESA 0x0370 // UART TX Descriptor Address +#define REG_UART_RX_DESA 0x0378 // UART Rx Descriptor Address + + +// spec version 11 +//----------------------------------------------------- +// +// 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 + + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_LIFETIME_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 + +//#define REG_FW_TSF_SYNC_CNT 0x04A0 +#define REG_FW_RESET_TSF_CNT_1 0x05FC +#define REG_FW_RESET_TSF_CNT_0 0x05FD +#define REG_FW_BCN_DIS_CNT 0x05FE + +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + + + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CCK 0x0514 +#define REG_SIFS_OFDM 0x0516 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_TSFTR_SYN_OFFSET 0x0518 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 // The same as REG_MBSSID_BCN_SPACE +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_TSFTR1 0x0568 +#define REG_INIT_TSFTR 0x0564 +#define REG_ATIMWND_1 0x0570 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A + +// 20100719 Joseph: Hardware register definition change. (HW datasheet v54) +#define REG_R2T_SIFS 0x063C // [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK +#define REG_T2T_SIFS 0x063E // [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +//WMA, BA, CCX +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + + +// Security +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +// Power +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +// For test chip +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_TEST_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 // 0xFE66~0xFE6B +#define REG_TEST_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_TEST_SIE_STRING 0xFE80 // 0xFE80~0xFEB9 + + +// For normal chip +#define REG_NORMAL_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_NORMAL_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 // 0xFE65~0xFE67 +#define REG_NORMAL_SIE_PHY 0xFE68 // 0xFE68~0xFE6B +#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C +#define REG_NORMAL_SIE_GPS_EP 0xFE6D // 0xFE6D, for RTL8723 only. +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_NORMAL_SIE_STRING 0xFE80 // 0xFE80~0xFEDF + + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. + +#define SYS_ISO_CTRL REG_SYS_ISO_CTRL // System Isolation Interface Control. +#define SYS_FUNC_EN REG_SYS_FUNC_EN // System Function Enable. +#define SYS_CLK REG_SYS_CLKR +#define CR9346 REG_9346CR // 93C46/93C56 Command Register. +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +#define EFUSE_TEST REG_EFUSE_TEST // E-Fuse Test. +#define MSR (REG_CR + 2) // Media Status register +#define ISR REG_HISR +#define TSFR REG_TSFTR // Timing Sync Function Timer Register. + +#define MACIDR0 REG_MACID // MAC ID Register, Offset 0x0050-0x0053 +#define MACIDR4 (REG_MACID + 4) // MAC ID Register, Offset 0x0054-0x0055 + +#define PBP REG_PBP + +// Redifine MACID register, to compatible prior ICs. +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM REG_CAMCMD //IN 8190 Data Sheet is called CAMcmd +#define WCAMI REG_CAMWRITE // Software write CAM input content +#define RCAMO REG_CAMREAD // Software read/write CAM config +#define CAMDBG REG_CAMDBG +#define SECR REG_SECCFG //Security Configuration Register + +// Unused register +#define UnusedRegister 0x1BF +#define DCAM UnusedRegister +#define PSR UnusedRegister +#define BBAddr UnusedRegister +#define PhyDataR UnusedRegister + +#define InvalidBBRFValue 0x12345678 + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +//---------------------------------------------------------------------------- +// 8192C Cmd9346CR bits (Offset 0xA, 16bit) +//---------------------------------------------------------------------------- +#define CmdEEPROM_En BIT5 // EEPROM enable when set 1 +#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 +#define Cmd9346CR_9356SEL BIT4 +#define AutoLoadEEPROM (CmdEEPROM_En|CmdEERPOMSEL) +#define AutoLoadEFUSE CmdEEPROM_En + +//---------------------------------------------------------------------------- +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +//---------------------------------------------------------------------------- +// 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +/* +Network Type +00: No link +01: Link in ad hoc network +10: Link in infrastructure network +11: AP mode +Default: 00b. +*/ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +// +// 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) +// +//---------------------------------------------------------------------------- +// 8192C Response Rate Set Register (offset 0x181, 24bits) +//---------------------------------------------------------------------------- +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 +#define BRSR_AckShortPmb BIT23 +// CCK ACK: use Short Preamble or not + + +//---------------------------------------------------------------------------- +// 8192C Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +//---------------------------------------------------------------------------- +// 8192C BW_OPMODE bits (Offset 0x203, 8bit) +//---------------------------------------------------------------------------- +#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_5G BIT1 +#define BW_OPMODE_11J BIT0 + + +//---------------------------------------------------------------------------- +// 8192C CAM Config Setting (offset 0x250, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID BIT15 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT5 + +#define CAM_CONTENT_COUNT 8 + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_CONFIG_USEDK _TRUE +#define CAM_CONFIG_NO_USEDK _FALSE + +#define CAM_WRITE BIT16 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT31 + +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 + + +// +// 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) +// +//---------------------------------------------------------------------------- +// 8190 IMR/ISR bits (offset 0xfd, 8bits) +//---------------------------------------------------------------------------- +#define IMR8190_DISABLED 0x0 +// IMR DW0 Bit 0-31 +#define IMR_BCNDMAINT6 BIT31 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5 BIT30 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4 BIT29 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3 BIT28 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2 BIT27 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1 BIT26 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK8 BIT25 // Beacon Queue DMA OK Interrup 8 +#define IMR_BCNDOK7 BIT24 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6 BIT23 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5 BIT22 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4 BIT21 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3 BIT20 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2 BIT19 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1 BIT18 // Beacon Queue DMA OK Interrup 1 +#define IMR_TIMEOUT2 BIT17 // Timeout interrupt 2 +#define IMR_TIMEOUT1 BIT16 // Timeout interrupt 1 +#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow +#define IMR_PSTIMEOUT BIT14 // Power save time out interrupt +#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 +#define IMR_RXFOVW BIT12 // Receive FIFO Overflow +#define IMR_RDU BIT11 // Receive Descriptor Unavailable +#define IMR_ATIMEND BIT10 // For 92C,ATIM Window End Interrupt +#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup +#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt +#define IMR_TBDOK BIT7 // Transmit Beacon OK interrup +#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define IMR_TBDER BIT5 // For 92C,Transmit Beacon Error Interrupt +#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt +#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt +#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt +#define IMR_VODOK BIT1 // AC_VO DMA Interrupt +#define IMR_ROK BIT0 // Receive DMA OK Interrupt + +#define IMR_RX_MASK (IMR_ROK|IMR_RDU|IMR_RXFOVW) +#define IMR_TX_MASK (IMR_VODOK|IMR_VIDOK|IMR_BEDOK|IMR_BKDOK|IMR_MGNTDOK|IMR_HIGHDOK|IMR_BDOK) + +// 13. Host Interrupt Status Extension Register (Offset: 0x012C-012Eh) +#define IMR_BcnInt_E BIT12 +#define IMR_TXERR BIT11 +#define IMR_RXERR BIT10 +#define IMR_C2HCMD BIT9 +#define IMR_CPWM BIT8 +//RSVD [2-7] +#define IMR_OCPINT BIT1 +#define IMR_WLANOFF BIT0 + + + +//---------------------------------------------------------------------------- +// 8192C EFUSE +//---------------------------------------------------------------------------- +#define HWSET_MAX_SIZE 128 + + +//---------------------------------------------------------------------------- +// 8192C EEPROM/EFUSE share register definition. +//---------------------------------------------------------------------------- + +// +// Default Value for EEPROM or EFUSE!!! +// +#define EEPROM_Default_TSSI 0x0 +#define EEPROM_Default_TxPowerDiff 0x0 +#define EEPROM_Default_CrystalCap 0x5 +#define EEPROM_Default_BoardType 0x02 // Default: 2X2, RTL8192CE(QFPN68) +#define EEPROM_Default_TxPower 0x1010 +#define EEPROM_Default_HT2T_TxPwr 0x10 + +#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 +#define EEPROM_Default_ThermalMeter 0x12 + +#define EEPROM_Default_AntTxPowerDiff 0x0 +#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 +#define EEPROM_Default_TxPowerLevel 0x22 +#define EEPROM_Default_HT40_2SDiff 0x0 +#define EEPROM_Default_HT20_Diff 2 // HT20<->40 default Tx Power Index Difference +#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 +#define EEPROM_Default_HT40_PwrMaxOffset 0 +#define EEPROM_Default_HT20_PwrMaxOffset 0 + +// For debug +#define EEPROM_Default_PID 0x1234 +#define EEPROM_Default_VID 0x5678 +#define EEPROM_Default_CustomerID 0xAB +#define EEPROM_Default_SubCustomerID 0xCD +#define EEPROM_Default_Version 0 + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_USB_OPTIONAL1 0xE +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 // CCX test. By Bruce, 2009-02-25. +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + + +#define RTL_EEPROM_ID 0x8129 + + +#ifdef CONFIG_PCI_HCI +#define RT_IBSS_INT_MASKS (IMR_BcnInt | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) +#define RT_BSS_INT_MASKS (RT_IBSS_INT_MASKS) + +// +// Interface type. +// +typedef enum _INTERFACE_SELECT_8192CPCIe{ + INTF_SEL0_SOLO_MINICARD = 0, // WiFi solo-mCard + INTF_SEL1_BT_COMBO_MINICARD = 1, // WiFi+BT combo-mCard + INTF_SEL2_PCIe = 2, // PCIe Card +} INTERFACE_SELECT_8192CPCIe, *PINTERFACE_SELECT_8192CPCIe; + +#define RTL8190_EEPROM_ID 0x8129 // 0-1 +#define EEPROM_HPON 0x02 // LDO settings.2-5 +#define EEPROM_CLK 0x06 // Clock settings.6-7 +#define EEPROM_TESTR 0x08 // SE Test mode.8 + +#define EEPROM_VID 0x0A // SE Vendor ID.A-B +#define EEPROM_DID 0x0C // SE Device ID. C-D +#define EEPROM_SVID 0x0E // SE Vendor ID.E-F +#define EEPROM_SMID 0x10 // SE PCI Subsystem ID. 10-11 + +#define EEPROM_MAC_ADDR 0x16 // SEMAC Address. 12-17 + +//---------------------------------------------------------------- +// Ziv - Let PCIe and USB use the same define. Modify address mapping later. +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F +#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 + +#define EEPROM_CHANNEL_PLAN 0x75 +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_VERSION 0x7E +#define EEPROM_CUSTOMER_ID 0x7F + +#define EEPROM_NORMAL_BoardType EEPROM_RF_OPT1 //[7:5] + +#endif + +#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_8192CUSB, *PBOARD_TYPE_8192CUSB; + +#define SUPPORT_HW_RADIO_DETECT(pHalData) (pHalData->BoardType == BOARD_MINICARD||\ + pHalData->BoardType == BOARD_USB_SOLO||\ + pHalData->BoardType == BOARD_USB_COMBO) + +//--------------------------------------------------------------- +// EEPROM address for Test chip +//--------------------------------------------------------------- +#define EEPROM_TEST_USB_OPT 0x0E +#define EEPROM_TEST_CHIRP_K 0x0F +#define EEPROM_TEST_EP_SETTING 0x0E +#define EEPROM_TEST_USB_PHY 0x10 + + +//--------------------------------------------------------------- +// EEPROM address for Normal chip +//--------------------------------------------------------------- +#define EEPROM_NORMAL_USB_OPT 0x0E +#define EEPROM_NORMAL_CHIRP_K 0x0E // Changed +#define EEPROM_NORMAL_EP_SETTING 0x0F // Changed +#define EEPROM_NORMAL_USB_PHY 0x12 // Changed + + +// Test chip and normal chip common define +//--------------------------------------------------------------- +// EEPROM address for both +//--------------------------------------------------------------- +#define EEPROM_ID0 0x00 +#define EEPROM_ID1 0x01 +#define EEPROM_RTK_RSV1 0x02 +#define EEPROM_RTK_RSV2 0x03 +#define EEPROM_RTK_RSV3 0x04 +#define EEPROM_RTK_RSV4 0x05 +#define EEPROM_RTK_RSV5 0x06 +#define EEPROM_DBG_SEL 0x07 +#define EEPROM_RTK_RSV6 0x08 +#define EEPROM_VID 0x0A +#define EEPROM_PID 0x0C + +#define EEPROM_MAC_ADDR 0x16 +#define EEPROM_STRING 0x1C +#define EEPROM_SUBCUSTOMER_ID 0x59 +#define EEPROM_CCK_TX_PWR_INX 0x5A +#define EEPROM_HT40_1S_TX_PWR_INX 0x60 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 +#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 +#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C +#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F +#define EEPROM_HT20_MAX_PWR_OFFSET 0x72 + +#define EEPROM_CHANNEL_PLAN 0x75 +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 +#define EEPROM_RF_OPT1 0x79 +#define EEPROM_RF_OPT2 0x7A +#define EEPROM_RF_OPT3 0x7B +#define EEPROM_RF_OPT4 0x7C +#define EEPROM_VERSION 0x7E +#define EEPROM_CUSTOMER_ID 0x7F + +#define EEPROM_BoardType 0x54 //0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU +#define EEPROM_TxPwIndex 0x5C //0x5C-0x76, Tx Power index. +#define EEPROM_PwDiff 0x67 // Difference of gain index between legacy and high throughput OFDM. + +#define EEPROM_TxPowerCCK 0x5A // CCK Tx Power + +// 2009/02/09 Cosa Add for SD3 requirement +#define EEPROM_TX_PWR_HT20_DIFF 0x6e// HT20 Tx Power Index Difference +#define DEFAULT_HT20_TXPWR_DIFF 2 // HT20<->40 default Tx Power Index Difference +#define EEPROM_TX_PWR_OFDM_DIFF 0x71// OFDM Tx Power Index Difference + +#define EEPROM_TxPWRGroup 0x73// Power diff for channel group +#define EEPROM_Regulatory 0x79// Check if power safety is need + +#define EEPROM_BLUETOOTH_COEXIST 0x7E // 92cu, 0x7E[4] +#define EEPROM_NORMAL_BoardType EEPROM_RF_OPT1 //[7:5] +#define BOARD_TYPE_NORMAL_MASK 0xE0 +#define BOARD_TYPE_TEST_MASK 0x0F +#define EEPROM_EASY_REPLACEMENT 0x50//BIT0 1 for build-in module, 0 for external dongle +//------------------------------------------------------------- +// EEPROM content definitions +//------------------------------------------------------------- +#define OS_LINK_SPEED BIT(5) + +#define BOARD_TYPE_MASK 0xF + +#define BT_COEXISTENCE BIT(4) +#define BT_CO_SHIFT 4 + +#define EP_NUMBER_MASK 0x30 //bit 4:5 0Eh +#define EP_NUMBER_SHIFT 4 + + +#define USB_PHY_PARA_SIZE 5 + + +//------------------------------------------------------------- +// EEPROM default value definitions +//------------------------------------------------------------- +// Use 0xABCD instead of 0x8192 for debug +#define EEPROM_DEF_ID_0 0xCD // Byte 0x00 +#define EEPROM_DEF_ID_1 0xAB // Byte 0x01 + +#define EEPROM_DEF_RTK_RSV_A3 0x74 // Byte 0x03 +#define EEPROM_DEF_RTK_RSV_A4 0x6D // Byte 0x04 +#define EEPROM_DEF_RTK_RSV_A8 0xFF // Byte 0x08 + +#define EEPROM_DEF_VID_0 0x0A // Byte 0x0A +#define EEPROM_DEF_VID_1 0x0B + +#define EEPROM_DEF_PID_0 0x92 // Byte 0x0C +#define EEPROM_DEF_PID_1 0x81 + + +#define EEPROM_TEST_DEF_USB_OPT 0x80 // Byte 0x0E +#define EEPROM_NORMAL_DEF_USB_OPT 0x00 // Byte 0x0E + +#define EEPROM_DEF_CHIRPK 0x15 // Byte 0x0F + +#define EEPROM_DEF_USB_PHY_0 0x85 // Byte 0x10 +#define EEPROM_DEF_USB_PHY_1 0x62 // Byte 0x11 +#define EEPROM_DEF_USB_PHY_2 0x9E // Byte 0x12 +#define EEPROM_DEF_USB_PHY_3 0x06 // Byte 0x13 + +#define EEPROM_DEF_TSSI_A 0x09 // Byte 0x78 +#define EEPROM_DEF_TSSI_B 0x09 // Byte 0x79 + + +#define EEPROM_DEF_THERMAL_METER 0x12 // Byte 0x7A + +#define RF_OPTION1 0x79// Check if power safety spec is need +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + + +#define EEPROM_USB_SN BIT(0) +#define EEPROM_USB_REMOTE_WAKEUP BIT(1) +#define EEPROM_USB_DEVICE_PWR BIT(2) +#define EEPROM_EP_NUMBER (BIT(3)|BIT(4)) + +#if 0 +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 + +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + + +#define EEPROM_CID_CCX 0x10 // CCX test. By Bruce, 2009-02-25. +#endif + +#endif + + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ + +//---------------------------------------------------------------------------- +// 8192C (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +#define RCR_APPFCS BIT31 //WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // +#define RCR_APP_PHYSTS BIT28// +#define RCR_APP_ICV BIT29 // +#define RCR_APP_PHYST_RXFF BIT28 // +#define RCR_APP_BA_SSN BIT27 //Accept BA SSN +#define RCR_ENMBID BIT24 //Enable Multiple BssId. +#define RCR_LSIGEN BIT23 +#define RCR_MFBEN BIT22 +#define RCR_HTC_LOC_CTRL BIT14 //MFC<--HTC=1 MFC-->HTC=0 +#define RCR_AMF BIT13 //Accept management type frame +#define RCR_ACF BIT12 //Accept control type frame +#define RCR_ADF BIT11 //Accept data type frame +#define RCR_AICV BIT9 //Accept ICV error packet +#define RCR_ACRC32 BIT8 //Accept CRC32 error packet +#define RCR_CBSSID_BCN BIT7 //Accept BSSID match packet (Rx beacon, probe rsp) +#define RCR_CBSSID_DATA BIT6 //Accept BSSID match packet (Data) +#define RCR_CBSSID RCR_CBSSID_DATA //Accept BSSID match packet +#define RCR_APWRMGT BIT5 //Accept power management packet +#define RCR_ADD3 BIT4 //Accept address 3 match packet +#define RCR_AB BIT3 //Accept broadcast packet +#define RCR_AM BIT2 //Accept multicast packet +#define RCR_APM BIT1 //Accept physical match packet +#define RCR_AAP BIT0 //Accept all unicast packet +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + + + +//============================================================================ +// 8192c USB specific Regsiter Offset and Content definition, +// 2009.08.18, added by vivi. for merge 92c and 92C into one driver +//============================================================================ +//#define APS_FSMCO 0x0004 same with 92Ce +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 + +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define InvalidBBRFValue 0x12345678 + +//============================================================================ +// 8192C Regsiter Bit and Content definition +//============================================================================ +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- + +//2 SPS0_CTRL +#define SW18_FPWM BIT(3) + + +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + + +//2 9346CR + + +#define EEDO BIT(0) +#define EEDI BIT(1) +#define EESK BIT(2) +#define EECS BIT(3) +//#define EERPROMSEL BIT(4) +//#define EEPROM_EN BIT(5) +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) +#define EEM0 BIT(6) +#define EEM1 BIT(7) + + +//2 AFE_MISC +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + + +//2 SPS0_CTRL + + +//2 SPS_OCP_CFG + + +//2 RSV_CTRL +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + + +//2 LDOA15_CTRL +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + + + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +//2 AFE_XTAL_CTRL +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + + +//2 AFE_PLL_CTRL +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + + +//2 EFUSE_CTRL +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +//2 EFUSE_TEST (For RTL8723 partially) +#define EF_TRPT BIT(7) +#define EF_CELL_SEL (BIT(8)|BIT(9)) // 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 +#define LDOE25_EN BIT(31) +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +#define EFUSE_BT_SEL_0 0x1 +#define EFUSE_BT_SEL_1 0x2 +#define EFUSE_BT_SEL_2 0x3 + +#define EFUSE_ACCESS_ON 0x69 // For RTL8723 only. +#define EFUSE_ACCESS_OFF 0x00 // For RTL8723 only. + +//2 PWR_DATA + +//2 CAL_TIMER + +//2 ACLK_MON +#define RSM_EN BIT(0) +#define Timer_EN BIT(4) + + +//2 GPIO_MUXCFG +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EnBT BIT(5) +#define EnUart BIT(8) +#define Uart_910 BIT(9) +#define EnPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EnSIC BIT(12) +#define SIC_23 BIT(13) +#define EnHDP BIT(14) +#define SIC_LBK BIT(15) + +//2 GPIO_PIN_CTRL + +// GPIO BIT +#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) + +//2 GPIO_INTM + +//2 LEDCFG +#define LED0PL BIT(4) +#define LED0DIS BIT(7) +#define LED1DIS BIT(15) +#define LED1PL BIT(12) + +#define SECCAM_CLR BIT(30) + + +//2 FSIMR + +//2 FSISR + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +//2REG_HPON_FSM +#define BOND92CE_1T2R_CFG BIT(22) + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 + +//2REG_GPIO_OUTSTS (For RTL8723 only) +#define EFS_HCI_SEL (BIT(0)|BIT(1)) +#define PAD_HCI_SEL (BIT(2)|BIT(3)) +#define HCI_SEL (BIT(4)|BIT(5)) +#define PKG_SEL_HCI BIT(6) +#define FEN_GPS BIT(7) +#define FEN_BT BIT(8) +#define FEN_WL BIT(9) +#define FEN_PCI BIT(10) +#define FEN_USB BIT(11) +#define BTRF_HWPDN_N BIT(12) +#define WLRF_HWPDN_N BIT(13) +#define PDN_BT_N BIT(14) +#define PDN_GPS_N BIT(15) +#define BT_CTL_HWPDN BIT(16) +#define GPS_CTL_HWPDN BIT(17) +#define PPHY_SUSB BIT(20) +#define UPHY_SUSB BIT(21) +#define PCI_SUSEN BIT(22) +#define USB_SUSEN BIT(23) +#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + + +//2 Function Enable Registers +//2 CR + +#define REG_LBMODE (REG_CR + 3) + + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + + +//2 PBP - Page Size Register +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + + +//2 TRXFF_BNDY + + +//2 LLT_INIT +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +//2 BB_ACCESS_CTRL +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) +//#define BB_ADDR_MASK 0xFFF +//#define _BB_ADDR(x) ((x) & BB_ADDR_MASK) + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +//2 RQPN +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) // NOTE: in RQPN_NPQ register + + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + + +//2 TDECTRL +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +//2 TDECTL +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK +#define DROP_DATA_EN BIT(9) + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +//2 FWHW_TXQ_CTRL +#define EN_AMPDU_RTY_NEW BIT(7) + +//2 INIRTSMCS_SEL +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + + +//2 SPEC SIFS +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + + +//2 RRSR + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + + +//2 ARFR +#define USE_SHORT_G1 BIT(20) + +//2 AGGLEN_LMT_L +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + + +//2 RL +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + + +//2 DARFRC +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +// NOTE: shift starting from address (DARFRC + 4) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + + +//2 RARFRC +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +// NOTE: shift starting from address (RARFRC + 4) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + + + + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + + + +//2 EDCA setting +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +//2 EDCA_VO_PARAM +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) (((x) & 0xF))<< 8) + + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + + +//2 SIFS_CCK +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); + + +//2 SIFS_OFDM +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); + + +//2 TBTT PROHIBIT +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + + +//2 REG_RD_CTRL +#define DIS_EDCA_CNT_DWN BIT(11) + + +//2 BCN_CTRL +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) +// The same function but different bit field. +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +//2 ACMHWCTRL +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +//2 APSD_CTRL +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + + +//2 BWOPMODE +#define BW_20MHZ BIT(2) +//#define BW_OPMODE_20MHZ BIT(2) // For compability + + +#define RATE_BITMAP_ALL 0xFFFFF + +// Only use CCK 1M rate for ACK +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +//2 TCR +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + + + +//2 RCR +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +//2 RX_PKT_LIMIT + +//2 RX_DLK_TIME + +//2 MBIDCAMCFG + + + +//2 AMPDU_MIN_SPACE +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + + +//2 RXERR_RPT +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + + +//2 SECCFG +#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key +#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key +#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption +#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption +#define SCR_SKByA2 BIT(4) //Search kEY BY A2 +#define SCR_NoSKMC BIT(5) //No Key Search Multicast + + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- + +//2 USB Information (0xFE17) +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +//2 Special Option +#define USB_AGG_EN BIT(3) + + +//2REG_C2HEVT_CLEAR +#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message +#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver. + + +//2REG_MULTI_FUNC_CTRL(For RTL8723 Only) +#define WL_HWPDN_EN BIT0 // Enable GPIO[9] as WiFi HW PDn source +#define WL_HWPDN_SL BIT1 // WiFi HW PDn polarity control +#define WL_FUNC_EN BIT2 // WiFi function enable +#define WL_HWROF_EN BIT3 // Enable GPIO[9] as WiFi RF HW PDn source +#define BT_HWPDN_EN BIT16 // Enable GPIO[11] as BT HW PDn source +#define BT_HWPDN_SL BIT17 // BT HW PDn polarity control +#define BT_FUNC_EN BIT18 // BT function enable +#define BT_HWROF_EN BIT19 // Enable GPIO[11] as BT/GPS RF HW PDn source +#define GPS_HWPDN_EN BIT20 // Enable GPIO[10] as GPS HW PDn source +#define GPS_HWPDN_SL BIT21 // GPS HW PDn polarity control +#define GPS_FUNC_EN BIT22 // GPS function enable + +//3 REG_LIFECTRL_CTRL +#define HAL92C_EN_PKT_LIFE_TIME_BK BIT3 +#define HAL92C_EN_PKT_LIFE_TIME_BE BIT2 +#define HAL92C_EN_PKT_LIFE_TIME_VI BIT1 +#define HAL92C_EN_PKT_LIFE_TIME_VO BIT0 + +#define HAL92C_MSDU_LIFE_TIME_UNIT 128 // in us, said by Tim. + +//======================================================== +// General definitions +//======================================================== + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +//---------------------------------------------------------------------------- +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + + + +#include "basic_types.h" + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192c_sreset.h b/rtl8192cu-fixes/include/rtl8192c_sreset.h new file mode 100755 index 00000000..20e88b50 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_sreset.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 _RTL8192C_SRESET_C_ +#define _RTL8192C_SRESET_C_ + +#include +#include +#include +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8192c_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8192c_sreset_linked_status_check(_adapter *padapter); +#endif +#endif diff --git a/rtl8192cu-fixes/include/rtl8192c_xmit.h b/rtl8192cu-fixes/include/rtl8192c_xmit.h new file mode 100755 index 00000000..7d2059df --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192c_xmit.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * 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 _RTL8192C_XMIT_H_ +#define _RTL8192C_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 + +struct txrpt_ccx_8192c { + /* offset 0 */ + u8 retry_cnt:6; + u8 rsvd_0:2; + + /* offset 1 */ + u8 rts_retry_cnt:6; + u8 rsvd_1:2; + + /* offset 2 */ + u8 ccx_qtime0; + u8 ccx_qtime1; + + /* offset 4 */ + u8 missed_pkt_num:5; + u8 rsvd_4:3; + + /* offset 5 */ + u8 mac_id:5; + u8 des1_fragssn:3; + + /* offset 6 */ + u8 rpt_pkt_num:5; + u8 pkt_drop:1; + u8 lifetime_over:1; + u8 retry_over:1; + + /* offset 7*/ + u8 edca_tx_queue:4; + u8 rsvd_7:1; + u8 bmc:1; + u8 pkt_ok:1; + u8 int_ccx:1; +}; + +#define txrpt_ccx_qtime_8192c(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8)) + +#ifdef CONFIG_XMIT_ACK +void dump_txrpt_ccx_8192c(void *buf); +void handle_txrpt_ccx_8192c(_adapter *adapter, void *buf); +#else +#define dump_txrpt_ccx_8192c(buf) do {} while(0) +#define handle_txrpt_ccx_8192c(adapter, buf) do {} while(0) +#endif + +#ifdef CONFIG_USB_HCI + +#ifdef CONFIG_USB_TX_AGGREGATION +#define MAX_TX_AGG_PACKET_NUMBER 0xFF +#endif + +s32 rtl8192cu_init_xmit_priv(_adapter * padapter); + +void rtl8192cu_free_xmit_priv(_adapter * padapter); + +void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc); + +s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +s32 rtl8192cu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtl8192cu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); + +s32 rtl8192cu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtl8192cu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8192ce_init_xmit_priv(_adapter * padapter); +void rtl8192ce_free_xmit_priv(_adapter * padapter); + +s32 rtl8192ce_enqueue_xmitbuf(struct rtw_tx_ring *ring, struct xmit_buf *pxmitbuf); +struct xmit_buf *rtl8192ce_dequeue_xmitbuf(struct rtw_tx_ring *ring); + +void rtl8192ce_xmitframe_resume(_adapter *padapter); + +s32 rtl8192ce_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtl8192ce_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); + +s32 rtl8192ce_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtl8192ce_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#endif + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192d_cmd.h b/rtl8192cu-fixes/include/rtl8192d_cmd.h new file mode 100755 index 00000000..ad7e7838 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_cmd.h @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * 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 __RTL8192D_CMD_H_ +#define __RTL8192D_CMD_H_ + + +//-------------------------------------------- +//3 Host Message Box +//-------------------------------------------- + +// User Define Message [31:8] + +//_SETPWRMODE_PARM +#define SET_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) + +//JOINBSSRPT_PARM +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) + +//_RSVDPAGE_LOC +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) + +//P2P_PS_OFFLOAD + +struct P2P_PS_Offload_t { + unsigned char Offload_En:1; + unsigned char role:1; // 1: Owner, 0: Client + unsigned char CTWindow_En:1; + unsigned char NoA0_En:1; + unsigned char NoA1_En:1; + unsigned char AllStaSleep:1; // Only valid in Owner + unsigned char discovery:1; + unsigned char rsvd:1; +}; + +#define SET_H2CCMD_P2P_PS_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_ROLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_CTW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_NOA0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_NOA1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) + +// Description: Determine the types of H2C commands that are the same in driver and Fw. +// Fisrt constructed by tynli. 2009.10.09. +typedef enum _RTL8192D_H2C_CMD +{ + H2C_AP_OFFLOAD = 0, /*0*/ + H2C_SETPWRMODE = 1, /*1*/ + H2C_JOINBSSRPT = 2, /*2*/ + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + H2C_P2P_PS_OFFLOAD = 8, + H2C_MAC_MODE_SEL = 9, + H2C_PWRM=15, +#ifdef CONFIG_WOWLAN + H2C_WO_WLAN_CMD = 20, // Wake on Wlan. +#endif // CONFIG_WOWLAN + H2C_P2P_PS_CTW_CMD = 24, + H2C_PathDiv = 26, //PathDiv--NeilChen--2011.07.15 +#ifdef CONFIG_WOWLAN + KEEP_ALIVE_CONTROL_CMD=31, //keep alive for wake on wlan + DISCONNECT_DECISION_CTRL_CMD=32, + REMOTE_WAKE_CTRL_CMD=34, +#endif // CONFIG_WOWLAN + H2C_92D_TSF_SYNC=36, + H2C_92D_RESET_TSF = 43, + H2C_CMD_MAX +}RTL8192D_H2C_CMD; + +struct cmd_msg_parm { + u8 eid; //element id + u8 sz; // sz + u8 buf[6]; +}; + + +void FillH2CCmd92D(_adapter* padapter, u8 ElementID, u32 CmdLen, u8* pCmdBuffer); + +// host message to firmware cmd +void rtl8192d_set_FwPwrMode_cmd(_adapter*padapter, u8 Mode); +void rtl8192d_set_FwJoinBssReport_cmd(_adapter* padapter, u8 mstatus); +u8 rtl8192d_set_rssi_cmd(_adapter*padapter, u8 *param); +u8 rtl8192d_set_raid_cmd(_adapter*padapter, u32 mask, u8 arg); +void rtl8192d_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8 arg); +#ifdef CONFIG_P2P +void rtl8192d_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +#ifdef CONFIG_TSF_RESET_OFFLOAD +int reset_tsf(PADAPTER Adapter, u8 reset_port ); +#endif // CONFIG_TSF_RESET_OFFLOAD + +#ifdef CONFIG_WOWLAN +typedef struct _SETWOWLAN_PARM{ + u8 mode; + u8 gpio_index; + u8 gpio_duration; + u8 second_mode; + u8 reserve; +}SETWOWLAN_PARM, *PSETWOWLAN_PARM; + +#define FW_WOWLAN_FUN_EN BIT(0) +#define FW_WOWLAN_PATTERN_MATCH BIT(1) +#define FW_WOWLAN_MAGIC_PKT BIT(2) +#define FW_WOWLAN_UNICAST BIT(3) +#define FW_WOWLAN_ALL_PKT_DROP BIT(4) +#define FW_WOWLAN_GPIO_ACTIVE BIT(5) +#define FW_WOWLAN_REKEY_WAKEUP BIT(6) +#define FW_WOWLAN_DEAUTH_WAKEUP BIT(7) + +#define FW_WOWLAN_GPIO_WAKEUP_EN BIT(0) +#define FW_FW_PARSE_MAGIC_PKT BIT(1) + +void rtl8192d_set_wowlan_cmd(_adapter* padapter); +void SetFwRelatedForWoWLAN8192DU(_adapter* padapter,u8 bHostIsGoingtoSleep); +#endif // CONFIG_WOWLAN + +#endif // __RTL8192D_CMD_H_ + + diff --git a/rtl8192cu-fixes/include/rtl8192d_dm.h b/rtl8192cu-fixes/include/rtl8192d_dm.h new file mode 100755 index 00000000..ab5e5f79 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_dm.h @@ -0,0 +1,420 @@ +/****************************************************************************** + * + * 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 __RTL8192D_DM_H__ +#define __RTL8192D_DM_H__ +//============================================================ +// Description: +// +// This file is for 92CE/92CU dynamic mechanism only +// +// +//============================================================ +//============================================================ +// Global var +//============================================================ + +extern u32 EDCAParam[maxAP][3] ; + +//============================================================ +// structure and define +//============================================================ + +typedef struct _FALSE_ALARM_STATISTICS{ + u32 Cnt_Parity_Fail; + u32 Cnt_Rate_Illegal; + u32 Cnt_Crc8_fail; + u32 Cnt_Mcs_fail; + u32 Cnt_Ofdm_fail; + u32 Cnt_Cck_fail; + u32 Cnt_all; + u32 Cnt_Fast_Fsync; + u32 Cnt_SB_Search_fail; +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; + +typedef struct _Dynamic_Power_Saving_ +{ + u8 PreCCAState; + u8 CurCCAState; + + u8 PreRFState; + u8 CurRFState; + + //int Rssi_val_min; + +}PS_T,*pPS_T; + +typedef struct _Dynamic_Initial_Gain_Threshold_ +{ + u8 Dig_Enable_Flag; + u8 Dig_Ext_Port_Stage; + + int RssiLowThresh; + int RssiHighThresh; + + u32 FALowThresh; + u32 FAHighThresh; + + u8 CurSTAConnectState; + u8 PreSTAConnectState; + u8 CurMultiSTAConnectState; + + u8 PreIGValue; + u8 CurIGValue; + u8 BackupIGValue; + + char BackoffVal; + char BackoffVal_range_max; + char BackoffVal_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 Rssi_val_min; + + u8 PreCCKPDState; + u8 CurCCKPDState; + + u8 LargeFAHit; + u8 ForbiddenIGI; + u32 Recover_cnt; + u8 rx_gain_range_min_nolink; +}DIG_T,*pDIG_T; + +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_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_1R_CCA_Type_Definition +{ + CCA_MIN = 0, + CCA_1R =1, + CCA_2R = 2, + CCA_MAX = 3, +}DM_1R_CCA_E; + +typedef enum tag_RF_Type_Definition +{ + RF_Save =0, + RF_Normal = 1, + RF_MAX = 2, +}DM_RF_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_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 0x3e +#define DM_DIG_MIN 0x1e //0x22//0x1c + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 + +//vivi 92c&92d has different definition, 20110504 +//this is for 92c +#define DM_DIG_FA_TH0 0x200//0x20 +#define DM_DIG_FA_TH1 0x300//0x100 +#define DM_DIG_FA_TH2 0x400//0x200 +//this is for 92d +#define DM_DIG_FA_TH0_92D 0x100 +#define DM_DIG_FA_TH1_92D 0x150 +#define DM_DIG_FA_TH2_92D 0x250 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN (-4) +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RxPathSelection_SS_TH_low 30 +#define RxPathSelection_diff_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTSToSelfTHVal 30 +#define RegC38_TH 20 + +#define WAIotTHVal 25 + +//Dynamic Tx Power Control Threshold +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +#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 + +#define DM_Type_ByFW 0 +#define DM_Type_ByDriver 1 + +typedef struct _RATE_ADAPTIVE +{ + u8 RateAdaptiveDisabled; + u8 RATRState; + u16 reserve; + + u32 HighRSSIThreshForRA; + u32 High2LowRSSIThreshForRA; + u8 Low2HighRSSIThreshForRA40M; + u32 LowRSSIThreshForRA40M; + u8 Low2HighRSSIThreshForRA20M; + u32 LowRSSIThreshForRA20M; + u32 UpperRSSIThresholdRATR; + u32 MiddleRSSIThresholdRATR; + u32 LowRSSIThresholdRATR; + u32 LowRSSIThresholdRATR40M; + u32 LowRSSIThresholdRATR20M; + u8 PingRSSIEnable; //cosa add for Netcore long range ping issue + u32 PingRSSIRATR; //cosa add for Netcore long range ping issue + u32 PingRSSIThreshForRA;//cosa add for Netcore long range ping issue + u32 LastRATR; + u8 PreRATRState; + +} RATE_ADAPTIVE, *PRATE_ADAPTIVE; + +typedef enum tag_SW_Antenna_Switch_Definition +{ + Antenna_B = 1, + Antenna_A = 2, + Antenna_MAX = 3, +}DM_SWAS_E; + +// 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 + +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 + +//============================= +//Neil Chen---2011--06--15-- +//============================== +//3 PathDiv +typedef struct _SW_Antenna_Switch_ +{ + u8 try_flag; + s32 PreRSSI; + u8 CurAntenna; + u8 PreAntenna; + u8 RSSI_Trying; + u8 TestMode; + u8 bTriggerAntennaSwitch; + u8 SelectAntennaMap; + + // Before link Antenna Switch check + u8 SWAS_NoLink_State; + u32 SWAS_NoLink_BK_Reg860; +}SWAT_T, *pSWAT_T; +//======================================== + +struct dm_priv +{ + u8 DM_Type; + u8 DMFlag, DMFlag_tmp; + + //for DIG + u8 bDMInitialGainEnable; + //u8 binitialized; // for dm_initial_gain_Multi_STA use. + DIG_T DM_DigTable; + + PS_T DM_PSTable; + + FALSE_ALARM_STATISTICS FalseAlmCnt; + + //for rate adaptive, in fact, 88c/92c fw will handle this + u8 bUseRAMask; + RATE_ADAPTIVE RateAdaptive; + + //* Upper and Lower Signal threshold for Rate Adaptive*/ + int UndecoratedSmoothedPWDB; + int EntryMinUndecoratedSmoothedPWDB; + int EntryMaxUndecoratedSmoothedPWDB; + int MinUndecoratedPWDBForDM; + int LastMinUndecoratedPWDBForDM; +#ifdef CONFIG_DUALMAC_CONCURRENT + int RssiValMinForAnotherMacOfDMSP; + u32 CurDigValueForAnotherMacOfDMSP; + BOOLEAN bWriteDigForAnotherMacOfDMSP; + BOOLEAN bChangeCCKPDStateForAnotherMacOfDMSP; + u8 CurCCKPDStateForAnotherMacOfDMSP; + BOOLEAN bChangeTxHighPowerLvlForAnotherMacOfDMSP; + u8 CurTxHighLvlForAnotherMacOfDMSP; +#endif + + //for High Power + u8 bDynamicTxPowerEnable; + u8 LastDTPLvl; + u8 DynamicTxHighPowerLvl;//Add by Jacken Tx Power Control for Near/Far Range 2008/03/06 + + //for tx power tracking + u8 bTXPowerTracking; + u8 TXPowercount; + u8 bTXPowerTrackingInit; + u8 TxPowerTrackControl; //for mp mode, turn off txpwrtracking as default + u8 TM_Trigger; + + u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 + u8 ThermalValue; + u8 ThermalValue_LCK; + u8 ThermalValue_IQK; + u8 ThermalValue_AVG[AVG_THERMAL_NUM]; + u8 ThermalValue_AVG_index; + u8 ThermalValue_RxGain; + u8 ThermalValue_Crystal; + u8 Delta_IQK; + u8 Delta_LCK; + u8 bRfPiEnable; + u8 bReloadtxpowerindex; + u8 bDoneTxpower; + + //for APK + u32 APKoutput[2][2]; //path A/B; output1_1a/output1_2a + u8 bAPKdone; + u8 bAPKThermalMeterIgnore; + BOOLEAN bDPKdone[2]; + BOOLEAN bDPKstore; + BOOLEAN bDPKworking; + u8 OFDM_min_index_internalPA_DPK[2]; + u8 TxPowerLevelDPK[2]; + + u32 RegA24; + + //for IQK + u32 Reg874; + u32 RegC08; + u32 Reg88C; + u8 Reg522; + u8 Reg550; + u8 Reg551; + u32 Reg870; + u32 ADDA_backup[IQK_ADDA_REG_NUM]; + u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; + u32 IQK_BB_backup[IQK_BB_REG_NUM]; + + u8 bCCKinCH14; + + char CCK_index; + //u8 Record_CCK_20Mindex; + //u8 Record_CCK_40Mindex; + char OFDM_index[2]; + + SWAT_T DM_SWAT_Table; + + //for TxPwrTracking + int RegE94; + int RegE9C; + int RegEB4; + int RegEBC; +#if MP_DRIVER == 1 + u8 RegC04_MP; + u32 RegD04_MP; +#endif + u32 TXPowerTrackingCallbackCnt; //cosa add for debug + + u32 prv_traffic_idx; // edca turbo + + u32 RegRF3C[2]; //pathA / pathB + + // 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]; + +#ifdef CONFIG_DM_ADAPTIVITY + /* Ported from ODM, for ESTI Adaptivity test */ + s8 TH_L2H_ini; + s8 TH_EDCCA_HL_diff; + s8 IGI_Base; + u8 IGI_target; + bool ForceEDCCA; + u8 AdapEn_RSSI; + s8 Force_TH_H; + s8 Force_TH_L; + u8 IGI_LowerBound; + + bool bPreEdccaEnable; +#endif +}; + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ +//#define DM_MultiSTA_InitGainChangeNotify(Event) {DM_DigTable.CurMultiSTAConnectState = Event;} + + +//============================================================ +// function prototype +//============================================================ +void rtl8192d_init_dm_priv(IN PADAPTER Adapter); +void rtl8192d_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8192d_InitHalDm(IN PADAPTER Adapter); +void rtl8192d_HalDmWatchDog(IN PADAPTER Adapter); + +VOID rtl8192d_dm_CheckTXPowerTracking(IN PADAPTER Adapter); + +#endif //__HAL8190PCIDM_H__ diff --git a/rtl8192cu-fixes/include/rtl8192d_hal.h b/rtl8192cu-fixes/include/rtl8192d_hal.h new file mode 100755 index 00000000..1ab5f982 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_hal.h @@ -0,0 +1,1126 @@ +/****************************************************************************** + * + * 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 __RTL8192D_HAL_H__ +#define __RTL8192D_HAL_H__ + +#include "hal_com.h" +#include "rtl8192d_spec.h" +#include "Hal8192DPhyReg.h" +#include "Hal8192DPhyCfg.h" +#include "rtl8192d_rf.h" +#include "rtl8192d_dm.h" +#include "rtl8192d_recv.h" +#include "rtl8192d_xmit.h" +#include "rtl8192d_cmd.h" + +/*---------------------------Define Local Constant---------------------------*/ +/* Channel switch:The size of command tables for switch channel*/ +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define MAX_RF_IMR_INDEX 12 +#define MAX_RF_IMR_INDEX_NORMAL 13 +#define RF_REG_NUM_for_C_CUT_5G 6 +#define RF_REG_NUM_for_C_CUT_5G_internalPA 7 +#define RF_REG_NUM_for_C_CUT_2G 5 +#define RF_CHNL_NUM_5G 19 +#define RF_CHNL_NUM_5G_40M 17 +#define TARGET_CHNL_NUM_5G 221 +#define TARGET_CHNL_NUM_2G 14 +#define TARGET_CHNL_NUM_2G_5G 59 +#define CV_CURVE_CNT 64 + +//static u32 RF_REG_FOR_5G_SWCHNL[MAX_RF_IMR_INDEX]={0,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x38,0x39,0x0}; +static u32 RF_REG_FOR_5G_SWCHNL_NORMAL[MAX_RF_IMR_INDEX_NORMAL]={0,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x0}; + +static u8 RF_REG_for_C_CUT_5G[RF_REG_NUM_for_C_CUT_5G] = + {RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6}; + +static u8 RF_REG_for_C_CUT_5G_internalPA[RF_REG_NUM_for_C_CUT_5G_internalPA] = + {0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E}; +static u8 RF_REG_for_C_CUT_2G[RF_REG_NUM_for_C_CUT_2G] = + {RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8}; + +#if DBG +static u32 RF_REG_MASK_for_C_CUT_2G[RF_REG_NUM_for_C_CUT_2G] = + {BIT19|BIT18|BIT17|BIT14|BIT1, BIT10|BIT9, + BIT18|BIT17|BIT16|BIT1, BIT2|BIT1, + BIT15|BIT14|BIT13|BIT12|BIT11}; +#endif //amy, temp remove +static u8 RF_CHNL_5G[RF_CHNL_NUM_5G] = + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}; +static u8 RF_CHNL_5G_40M[RF_CHNL_NUM_5G_40M] = + {38,42,46,50,54,58,62,102,106,110,114,118,122,126,130,134,138}; + +static u32 RF_REG_Param_for_C_CUT_5G[5][RF_REG_NUM_for_C_CUT_5G] = { + {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04}, + {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04}, + {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04}}; + +static u32 RF_REG_Param_for_C_CUT_2G[3][RF_REG_NUM_for_C_CUT_2G] = { + {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840}, + {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840}, + {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41}}; + +#if SWLCK == 1 +static u32 RF_REG_SYN_G4_for_C_CUT_2G = 0xD1C31&0x7FF; +#endif + +static u32 RF_REG_Param_for_C_CUT_5G_internalPA[3][RF_REG_NUM_for_C_CUT_5G_internalPA] = { + {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52}, + {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12}}; + + + +//[mode][patha+b][reg] +static u32 RF_IMR_Param_Normal[1][3][MAX_RF_IMR_INDEX_NORMAL]={{ + {0x70000,0x00ff0,0x4400f,0x00ff0,0x0,0x0,0x0,0x0,0x0,0x64888,0xe266c,0x00090,0x22fff},// channel 1-14. + {0x70000,0x22880,0x4470f,0x55880,0x00070, 0x88000, 0x0,0x88080,0x70000,0x64a82,0xe466c,0x00090,0x32c9a}, //path 36-64 + {0x70000,0x44880,0x4477f,0x77880,0x00070, 0x88000, 0x0,0x880b0,0x0,0x64b82,0xe466c,0x00090,0x32c9a} //100 -165 +} +}; + +//static u32 CurveIndex_5G[TARGET_CHNL_NUM_5G]={0}; +//static u32 CurveIndex_2G[TARGET_CHNL_NUM_2G]={0}; +static u32 CurveIndex[TARGET_CHNL_NUM_2G_5G]={0}; + +static u32 TargetChnl_5G[TARGET_CHNL_NUM_5G] = { +25141, 25116, 25091, 25066, 25041, +25016, 24991, 24966, 24941, 24917, +24892, 24867, 24843, 24818, 24794, +24770, 24765, 24721, 24697, 24672, +24648, 24624, 24600, 24576, 24552, +24528, 24504, 24480, 24457, 24433, +24409, 24385, 24362, 24338, 24315, +24291, 24268, 24245, 24221, 24198, +24175, 24151, 24128, 24105, 24082, +24059, 24036, 24013, 23990, 23967, +23945, 23922, 23899, 23876, 23854, +23831, 23809, 23786, 23764, 23741, +23719, 23697, 23674, 23652, 23630, +23608, 23586, 23564, 23541, 23519, +23498, 23476, 23454, 23432, 23410, +23388, 23367, 23345, 23323, 23302, +23280, 23259, 23237, 23216, 23194, +23173, 23152, 23130, 23109, 23088, +23067, 23046, 23025, 23003, 22982, +22962, 22941, 22920, 22899, 22878, +22857, 22837, 22816, 22795, 22775, +22754, 22733, 22713, 22692, 22672, +22652, 22631, 22611, 22591, 22570, +22550, 22530, 22510, 22490, 22469, +22449, 22429, 22409, 22390, 22370, +22350, 22336, 22310, 22290, 22271, +22251, 22231, 22212, 22192, 22173, +22153, 22134, 22114, 22095, 22075, +22056, 22037, 22017, 21998, 21979, +21960, 21941, 21921, 21902, 21883, +21864, 21845, 21826, 21807, 21789, +21770, 21751, 21732, 21713, 21695, +21676, 21657, 21639, 21620, 21602, +21583, 21565, 21546, 21528, 21509, +21491, 21473, 21454, 21436, 21418, +21400, 21381, 21363, 21345, 21327, +21309, 21291, 21273, 21255, 21237, +21219, 21201, 21183, 21166, 21148, +21130, 21112, 21095, 21077, 21059, +21042, 21024, 21007, 20989, 20972, +25679, 25653, 25627, 25601, 25575, +25549, 25523, 25497, 25471, 25446, +25420, 25394, 25369, 25343, 25318, +25292, 25267, 25242, 25216, 25191, +25166 }; + +static u32 TargetChnl_2G[TARGET_CHNL_NUM_2G] = { // channel 1~14 +26084, 26030, 25976, 25923, 25869, 25816, 25764, +25711, 25658, 25606, 25554, 25502, 25451, 25328 +}; + + +#ifdef CONFIG_PCI_HCI + #include + #include "Hal8192DEHWImg.h" + + #define RTL819X_DEFAULT_RF_TYPE RF_2T2R + +//--------------------------------------------------------------------- +// RTL8192DE From file +//--------------------------------------------------------------------- + #define RTL8192D_FW_IMG "rtl8192DE\\rtl8192dfw.bin" + + #define RTL8192D_PHY_REG "rtl8192DE\\PHY_REG.txt" + #define RTL8192D_PHY_REG_PG "rtl8192DE\\PHY_REG_PG.txt" + #define RTL8192D_PHY_REG_MP "rtl8192DE\\PHY_REG_MP.txt" + + #define RTL8192D_AGC_TAB "rtl8192DE\\AGC_TAB.txt" + #define RTL8192D_AGC_TAB_2G "rtl8192DE\\AGC_TAB_2G.txt" + #define RTL8192D_AGC_TAB_5G "rtl8192DE\\AGC_TAB_5G.txt" + #define RTL8192D_PHY_RADIO_A "rtl8192DE\\radio_a.txt" + #define RTL8192D_PHY_RADIO_B "rtl8192DE\\radio_b.txt" + #define RTL8192D_PHY_RADIO_A_intPA "rtl8192DE\\radio_a_intPA.txt" + #define RTL8192D_PHY_RADIO_B_intPA "rtl8192DE\\radio_b_intPA.txt" + #define RTL8192D_PHY_MACREG "rtl8192DE\\MAC_REG.txt" + +//--------------------------------------------------------------------- +// RTL8192DE From header +//--------------------------------------------------------------------- + + // Fw Array + #define Rtl8192D_FwImageArray Rtl8192DEFwImgArray + + // MAC/BB/PHY Array + #define Rtl8192D_MAC_Array Rtl8192DEMAC_2T_Array + #define Rtl8192D_AGCTAB_Array Rtl8192DEAGCTAB_Array + #define Rtl8192D_AGCTAB_5GArray Rtl8192DEAGCTAB_5GArray + #define Rtl8192D_AGCTAB_2GArray Rtl8192DEAGCTAB_2GArray + #define Rtl8192D_AGCTAB_2TArray Rtl8192DEAGCTAB_2TArray + #define Rtl8192D_AGCTAB_1TArray Rtl8192DEAGCTAB_1TArray + #define Rtl8192D_PHY_REG_2TArray Rtl8192DEPHY_REG_2TArray + #define Rtl8192D_PHY_REG_1TArray Rtl8192DEPHY_REG_1TArray + #define Rtl8192D_PHY_REG_Array_PG Rtl8192DEPHY_REG_Array_PG + #define Rtl8192D_PHY_REG_Array_MP Rtl8192DEPHY_REG_Array_MP + #define Rtl8192D_RadioA_2TArray Rtl8192DERadioA_2TArray + #define Rtl8192D_RadioA_1TArray Rtl8192DERadioA_1TArray + #define Rtl8192D_RadioB_2TArray Rtl8192DERadioB_2TArray + #define Rtl8192D_RadioB_1TArray Rtl8192DERadioB_1TArray + #define Rtl8192D_RadioA_2T_intPAArray Rtl8192DERadioA_2T_intPAArray + #define Rtl8192D_RadioB_2T_intPAArray Rtl8192DERadioB_2T_intPAArray + + // Array length + #define Rtl8192D_FwImageArrayLength Rtl8192DEImgArrayLength + #define Rtl8192D_MAC_ArrayLength Rtl8192DEMAC_2T_ArrayLength + #define Rtl8192D_AGCTAB_5GArrayLength Rtl8192DEAGCTAB_5GArrayLength + #define Rtl8192D_AGCTAB_2GArrayLength Rtl8192DEAGCTAB_2GArrayLength + #define Rtl8192D_AGCTAB_2TArrayLength Rtl8192DEAGCTAB_2TArrayLength + #define Rtl8192D_AGCTAB_1TArrayLength Rtl8192DEAGCTAB_1TArrayLength + #define Rtl8192D_AGCTAB_ArrayLength Rtl8192DEAGCTAB_ArrayLength + #define Rtl8192D_PHY_REG_2TArrayLength Rtl8192DEPHY_REG_2TArrayLength + #define Rtl8192D_PHY_REG_1TArrayLength Rtl8192DEPHY_REG_1TArrayLength + #define Rtl8192D_PHY_REG_Array_PGLength Rtl8192DEPHY_REG_Array_PGLength + #define Rtl8192D_PHY_REG_Array_MPLength Rtl8192DEPHY_REG_Array_MPLength + #define Rtl8192D_RadioA_2TArrayLength Rtl8192DERadioA_2TArrayLength + #define Rtl8192D_RadioB_2TArrayLength Rtl8192DERadioB_2TArrayLength + #define Rtl8192D_RadioA_2T_intPAArrayLength Rtl8192DERadioA_2T_intPAArrayLength + #define Rtl8192D_RadioB_2T_intPAArrayLength Rtl8192DERadioB_2T_intPAArrayLength + +#elif defined(CONFIG_USB_HCI) + + #include "Hal8192DUHWImg.h" +#ifdef CONFIG_WOWLAN + #include "Hal8192DUHWImg_wowlan.h" +#endif //CONFIG_WOWLAN + #define RTL819X_DEFAULT_RF_TYPE RF_1T2R + +//--------------------------------------------------------------------- +// RTL8192DU From file +//--------------------------------------------------------------------- + #define RTL8192D_FW_IMG "rtl8192DU\\rtl8192dfw.bin" + + #define RTL8192D_PHY_REG "rtl8192DU\\PHY_REG.txt" + #define RTL8192D_PHY_REG_PG "rtl8192DU\\PHY_REG_PG.txt" + #define RTL8192D_PHY_REG_MP "rtl8192DU\\PHY_REG_MP.txt" + + #define RTL8192D_AGC_TAB "rtl8192DU\\AGC_TAB.txt" + #define RTL8192D_AGC_TAB_2G "rtl8192DU\\AGC_TAB_2G.txt" + #define RTL8192D_AGC_TAB_5G "rtl8192DU\\AGC_TAB_5G.txt" + #define RTL8192D_PHY_RADIO_A "rtl8192DU\\radio_a.txt" + #define RTL8192D_PHY_RADIO_B "rtl8192DU\\radio_b.txt" + #define RTL8192D_PHY_RADIO_A_intPA "rtl8192DU\\radio_a_intPA.txt" + #define RTL8192D_PHY_RADIO_B_intPA "rtl8192DU\\radio_b_intPA.txt" + #define RTL8192D_PHY_MACREG "rtl8192DU\\MAC_REG.txt" + +//--------------------------------------------------------------------- +// RTL8192DU From header +//--------------------------------------------------------------------- + + // Fw Array + #define Rtl8192D_FwImageArray Rtl8192DUFwImgArray +#ifdef CONFIG_WOWLAN + #define Rtl8192D_FwWWImageArray Rtl8192DUFwWWImgArray +#endif //CONFIG_WOWLAN + // MAC/BB/PHY Array + #define Rtl8192D_MAC_Array Rtl8192DUMAC_2T_Array + #define Rtl8192D_AGCTAB_Array Rtl8192DUAGCTAB_Array + #define Rtl8192D_AGCTAB_5GArray Rtl8192DUAGCTAB_5GArray + #define Rtl8192D_AGCTAB_2GArray Rtl8192DUAGCTAB_2GArray + #define Rtl8192D_AGCTAB_2TArray Rtl8192DUAGCTAB_2TArray + #define Rtl8192D_AGCTAB_1TArray Rtl8192DUAGCTAB_1TArray + #define Rtl8192D_PHY_REG_2TArray Rtl8192DUPHY_REG_2TArray + #define Rtl8192D_PHY_REG_1TArray Rtl8192DUPHY_REG_1TArray + #define Rtl8192D_PHY_REG_Array_PG Rtl8192DUPHY_REG_Array_PG + #define Rtl8192D_PHY_REG_Array_MP Rtl8192DUPHY_REG_Array_MP + #define Rtl8192D_RadioA_2TArray Rtl8192DURadioA_2TArray + #define Rtl8192D_RadioA_1TArray Rtl8192DURadioA_1TArray + #define Rtl8192D_RadioB_2TArray Rtl8192DURadioB_2TArray + #define Rtl8192D_RadioB_1TArray Rtl8192DURadioB_1TArray + #define Rtl8192D_RadioA_2T_intPAArray Rtl8192DURadioA_2T_intPAArray + #define Rtl8192D_RadioB_2T_intPAArray Rtl8192DURadioB_2T_intPAArray + + // Array length + #define Rtl8192D_FwImageArrayLength Rtl8192DUImgArrayLength + #define Rtl8192D_MAC_ArrayLength Rtl8192DUMAC_2T_ArrayLength + #define Rtl8192D_AGCTAB_5GArrayLength Rtl8192DUAGCTAB_5GArrayLength + #define Rtl8192D_AGCTAB_2GArrayLength Rtl8192DUAGCTAB_2GArrayLength + #define Rtl8192D_AGCTAB_2TArrayLength Rtl8192DUAGCTAB_2TArrayLength + #define Rtl8192D_AGCTAB_1TArrayLength Rtl8192DUAGCTAB_1TArrayLength + #define Rtl8192D_AGCTAB_ArrayLength Rtl8192DUAGCTAB_ArrayLength + #define Rtl8192D_PHY_REG_2TArrayLength Rtl8192DUPHY_REG_2TArrayLength + #define Rtl8192D_PHY_REG_1TArrayLength Rtl8192DUPHY_REG_1TArrayLength + #define Rtl8192D_PHY_REG_Array_PGLength Rtl8192DUPHY_REG_Array_PGLength + #define Rtl8192D_PHY_REG_Array_MPLength Rtl8192DUPHY_REG_Array_MPLength + #define Rtl8192D_RadioA_2TArrayLength Rtl8192DURadioA_2TArrayLength + #define Rtl8192D_RadioB_2TArrayLength Rtl8192DURadioB_2TArrayLength + #define Rtl8192D_RadioA_2T_intPAArrayLength Rtl8192DURadioA_2T_intPAArrayLength + #define Rtl8192D_RadioB_2T_intPAArrayLength Rtl8192DURadioB_2T_intPAArrayLength + + // The file name "_2T" is for 92CU, "_1T" is for 88CU. Modified by tynli. 2009.11.24. +/* #define Rtl819XFwImageArray Rtl8192DUFwImgArray + #define Rtl819XMAC_Array Rtl8192DUMAC_2TArray + #define Rtl819XAGCTAB_Array Rtl8192DUAGCTAB_Array + #define Rtl819XAGCTAB_5GArray Rtl8192DUAGCTAB_5GArray + #define Rtl819XAGCTAB_2GArray Rtl8192DUAGCTAB_2GArray + #define Rtl819XPHY_REG_2TArray Rtl8192DUPHY_REG_2TArray + #define Rtl819XPHY_REG_1TArray Rtl8192DUPHY_REG_1TArray + #define Rtl819XRadioA_2TArray Rtl8192DURadioA_2TArray + #define Rtl819XRadioA_1TArray Rtl8192DURadioA_1TArray + #define Rtl819XRadioA_2T_intPAArray Rtl8192DURadioA_2T_intPAArray + #define Rtl819XRadioB_2TArray Rtl8192DURadioB_2TArray + #define Rtl819XRadioB_1TArray Rtl8192DURadioB_1TArray + #define Rtl819XRadioB_2T_intPAArray Rtl8192DURadioB_2T_intPAArray + #define Rtl819XPHY_REG_Array_PG Rtl8192DUPHY_REG_Array_PG + #define Rtl819XPHY_REG_Array_MP Rtl8192DUPHY_REG_Array_MP + + #define Rtl819XAGCTAB_2TArray Rtl8192DUAGCTAB_2TArray + #define Rtl819XAGCTAB_1TArray Rtl8192DUAGCTAB_1TArray*/ + +#endif + +#define DRVINFO_SZ 4 // unit is 8bytes +#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len)&0x7F ? 1:0)) + +// +// Check if FW header exists. We do not consider the lower 4 bits in this case. +// By tynli. 2009.12.04. +// +#define IS_FW_HEADER_EXIST(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFFF) == 0x92D0 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFFF) == 0x92D1 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFFF) == 0x92D2 ||\ + (le16_to_cpu(_pFwHdr->Signature)&0xFFFF) == 0x92D3 ) + +#define FW_8192D_SIZE 0x8020 // Max FW len = 32k + 32(FW header length). +#define FW_8192D_START_ADDRESS 0x1000 +#define FW_8192D_END_ADDRESS 0x1FFF + +#define MAX_PAGE_SIZE 4096 // @ page : 4k bytes + +typedef enum _FIRMWARE_SOURCE{ + FW_SOURCE_IMG_FILE = 0, + FW_SOURCE_HEADER_FILE = 1, //from header file +}FIRMWARE_SOURCE, *PFIRMWARE_SOURCE; + +typedef struct _RT_FIRMWARE{ + FIRMWARE_SOURCE eFWSource; + u8* szFwBuffer; + u32 ulFwLength; +#ifdef CONFIG_WOWLAN + u8* szWoWLANFwBuffer; + u32 ulWoWLANFwLength; +#endif //CONFIG_WOWLAN +}RT_FIRMWARE, *PRT_FIRMWARE, RT_FIRMWARE_92D, *PRT_FIRMWARE_92D; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8192D_FIRMWARE_HDR {//8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u8 Subversion; // FW Subversion, default 0x00 + u8 Rsvd1; + + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; + +}RT_8192D_FIRMWARE_HDR, *PRT_8192D_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME 0x05 +#define BCN_DMA_ATIME_INT_TIME 0x02 + +typedef enum _BT_CoType{ + BT_2Wire = 0, + BT_ISSC_3Wire = 1, + BT_Accel = 2, + BT_CSR = 3, + BT_CSR_ENHAN = 4, + BT_RTL8756 = 5, +} BT_CoType, *PBT_CoType; + +typedef enum _BT_CurState{ + BT_OFF = 0, + BT_ON = 1, +} BT_CurState, *PBT_CurState; + +typedef enum _BT_ServiceType{ + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_Idle = 3, + BT_Scan = 4, + BT_Idle = 5, + BT_OtherAction = 6, + BT_Busy = 7, + BT_OtherBusy = 8, +} BT_ServiceType, *PBT_ServiceType; + +typedef enum _BT_RadioShared{ + BT_Radio_Shared = 0, + BT_Radio_Individual = 1, +} BT_RadioShared, *PBT_RadioShared; + +typedef struct _BT_COEXIST_STR{ + u8 BluetoothCoexist; + u8 BT_Ant_Num; + u8 BT_CoexistType; + u8 BT_State; + u8 BT_CUR_State; //0:on, 1:off + u8 BT_Ant_isolation; //0:good, 1:bad + u8 BT_PapeCtrl; //0:SW, 1:SW/HW dynamic + u8 BT_Service; + u8 BT_RadioSharedType; + u8 Ratio_Tx; + u8 Ratio_PRI; +}BT_COEXIST_STR, *PBT_COEXIST_STR; + +//Added for 92D IQK setting. +typedef struct _IQK_MATRIX_REGS_SETTING{ + BOOLEAN bIQKDone; +#if 1 + int Value[1][IQK_Matrix_REG_NUM]; +#else + u32 Mark[IQK_Matrix_REG_NUM]; + u32 Value[IQK_Matrix_REG_NUM]; +#endif +}IQK_MATRIX_REGS_SETTING,*PIQK_MATRIX_REGS_SETTING; + +#ifdef CONFIG_USB_RX_AGGREGATION + +typedef enum _USB_RX_AGG_MODE{ + USB_RX_AGG_DISABLE, + USB_RX_AGG_DMA, + USB_RX_AGG_USB, + USB_RX_AGG_DMA_USB +}USB_RX_AGG_MODE; + +#define MAX_RX_DMA_BUFFER_SIZE 10240 // 10K for 8192C RX DMA buffer + +#endif + + +#define TX_SELE_HQ BIT(0) // High Queue +#define TX_SELE_LQ BIT(1) // Low Queue +#define TX_SELE_NQ BIT(2) // Normal Queue + + +// Note: We will divide number of page equally for each queue other than public queue! + +#define TX_TOTAL_PAGE_NUMBER 0xF8 +#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER +#define NORMAL_PAGE_NUM_PUBQ 0x56 + + +// For Test Chip Setting +// (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER +#define TEST_PAGE_NUM_PUBQ_92DU 0x89 +#define TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC 0x7A +#define NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC 0x5A +#define NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC 0x10 +#define NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC 0x10 +#define NORMAL_PAGE_NUM_NORMALQ_92D_DUAL_MAC 0 + +#define TX_PAGE_BOUNDARY_DUAL_MAC (TX_TOTAL_PAGE_NUMBER_92D_DUAL_MAC + 1) + +// For Test Chip Setting +#define WMM_TEST_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_TEST_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6 + +#define WMM_TEST_PAGE_NUM_PUBQ 0xA3 +#define WMM_TEST_PAGE_NUM_HPQ 0x29 +#define WMM_TEST_PAGE_NUM_LPQ 0x29 + + +//Note: For Normal Chip Setting ,modify later +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6 + +#define WMM_NORMAL_PAGE_NUM_PUBQ_92D 0X65//0x82 +#define WMM_NORMAL_PAGE_NUM_HPQ_92D 0X30//0x29 +#define WMM_NORMAL_PAGE_NUM_LPQ_92D 0X30 +#define WMM_NORMAL_PAGE_NUM_NPQ_92D 0X30 + +#define WMM_NORMAL_PAGE_NUM_PUBQ_92D_DUAL_MAC 0X32 +#define WMM_NORMAL_PAGE_NUM_HPQ_92D_DUAL_MAC 0X18 +#define WMM_NORMAL_PAGE_NUM_LPQ_92D_DUAL_MAC 0X18 +#define WMM_NORMAL_PAGE_NUM_NPQ_92D_DUAL_MAC 0X18 + +//------------------------------------------------------------------------- +// Chip specific +//------------------------------------------------------------------------- + +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_88C_USB_MCARD 0x2 +#define CHIP_BONDING_88C_USB_HP 0x1 + +// +// 2011.01.06. Define new structure of chip version for RTL8723 and so on. Added by tynli. +// +/* + | BIT15:12 | BIT11:8 | BIT 7 | BIT6:4 | BIT3 | BIT2:0 | + |-------------+-----------+-----------+-------+-----------+-------| + | IC version(CUT) | ROM version | Manufacturer | RF type | Chip type | IC Type | + | | | TSMC/UMC | | TEST/NORMAL| | +*/ +// [15:12] IC version(CUT): A-cut=0, B-cut=1, C-cut=2, D-cut=3 +// [7] Manufacturer: TSMC=0, UMC=1 +// [6:4] RF type: 1T1R=0, 1T2R=1, 2T2R=2 +// [3] Chip type: TEST=0, NORMAL=1 +// [2:0] IC type: 81xxC=0, 8723=1, 92D=2 + +#define CHIP_8723 BIT(0) +#define CHIP_92D BIT(1) +#define NORMAL_CHIP BIT(3) +#define RF_TYPE_1T1R (~(BIT(4)|BIT(5)|BIT(6))) +#define RF_TYPE_1T2R BIT(4) +#define RF_TYPE_2T2R BIT(5) +#define CHIP_VENDOR_UMC BIT(7) +#define B_CUT_VERSION BIT(12) +#define C_CUT_VERSION BIT(13) +#define D_CUT_VERSION ((BIT(12)|BIT(13))) +#define E_CUT_VERSION BIT(14) + + +// MASK +#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) +#define CHIP_TYPE_MASK BIT(3) +#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) +#define MANUFACTUER_MASK BIT(7) +#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) +#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) + +// Get element +#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) + +#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0)? _TRUE : _FALSE) +#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723)? _TRUE : _FALSE) +#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == CHIP_92D)? _TRUE : _FALSE) +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version))? _FALSE : _TRUE) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)? _TRUE : _FALSE) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)? _TRUE : _FALSE) +#define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version))? _TRUE: _FALSE) + +#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ? _TRUE : _FALSE) +#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? ((GET_CVID_CUT_VERSION(version)) ? _FALSE : _TRUE) : _FALSE) +#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? ((GET_CVID_CUT_VERSION(version)) ? _FALSE : _TRUE) : _FALSE) +// 88/92C UMC B-cut vendor is set to TSMC so we need to check CHIP_VENDOR_UMC bit is not 1. +#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? _TRUE : _FALSE):_FALSE) +#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? (IS_2T2R(version) ? _TRUE: _FALSE) : _FALSE) + +#define IS_92D_C_CUT(version) ((IS_92D(version)) ? ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? _TRUE : _FALSE) : _FALSE) +#define IS_92D_D_CUT(version) ((IS_92D(version)) ? ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? _TRUE : _FALSE) : _FALSE) +#define IS_92D_E_CUT(version) ((IS_92D(version)) ? ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? _TRUE : _FALSE) : _FALSE) +#define IS_NORMAL_CHIP92D(version) ((GET_CVID_CHIP_TYPE(version))? _TRUE: _FALSE) + +typedef enum _VERSION_8192D{ + VERSION_TEST_CHIP_88C = 0x0000, + VERSION_TEST_CHIP_92C = 0x0020, + VERSION_TEST_UMC_CHIP_8723 = 0x0081, + VERSION_NORMAL_TSMC_CHIP_88C = 0x0008, + VERSION_NORMAL_TSMC_CHIP_92C = 0x0028, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x0018, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x0088, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x00a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x0098, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, + VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x1088, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x10a8, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x1090, + VERSION_TEST_CHIP_92D_SINGLEPHY= 0x0022, + VERSION_TEST_CHIP_92D_DUALPHY = 0x0002, + VERSION_NORMAL_CHIP_92D_SINGLEPHY= 0x002a, + VERSION_NORMAL_CHIP_92D_DUALPHY = 0x000a, + VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x202a, + VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x200a, + VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0x302a, + VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x300a, + VERSION_NORMAL_CHIP_92D_E_CUT_SINGLEPHY = 0x402a, + VERSION_NORMAL_CHIP_92D_E_CUT_DUALPHY = 0x400a, +}VERSION_8192D,*PVERSION_8192D; + + +//------------------------------------------------------------------------- +// Channel Plan +//------------------------------------------------------------------------- +enum ChannelPlan{ + CHPL_FCC = 0, + CHPL_IC = 1, + CHPL_ETSI = 2, + CHPL_SPAIN = 3, + CHPL_FRANCE = 4, + CHPL_MKK = 5, + CHPL_MKK1 = 6, + CHPL_ISRAEL = 7, + CHPL_TELEC = 8, + CHPL_GLOBAL = 9, + CHPL_WORLD = 10, +}; + +typedef struct _TxPowerInfo{ + u8 CCKIndex[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40_1SIndex[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40_2SIndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + s8 HT20IndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 OFDMIndexDiff[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT40MaxOffset[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 HT20MaxOffset[RF_PATH_MAX][CHANNEL_GROUP_MAX]; + u8 TSSI_A[3]; + u8 TSSI_B[3]; + u8 TSSI_A_5G[3]; //5GL/5GM/5GH + u8 TSSI_B_5G[3]; +}TxPowerInfo, *PTxPowerInfo; + +#define EFUSE_REAL_CONTENT_LEN 1024 +#define EFUSE_MAP_LEN 256 +#define EFUSE_MAX_SECTION 32 +#define EFUSE_MAX_SECTION_BASE 16 +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 2byte|----8bytes----|1byte|--7bytes--| //92D +#define EFUSE_OOB_PROTECT_BYTES 18 // PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. + +typedef enum _PA_MODE { + PA_MODE_EXTERNAL = 0x00, + PA_MODE_INTERNAL_SP3T = 0x01, + PA_MODE_INTERNAL_SPDT = 0x02 +} PA_MODE; + +/* Copy from rtl8192c */ +enum c2h_id_8192d { + C2H_DBG = 0, + C2H_TSF = 1, + C2H_AP_RPT_RSP = 2, + C2H_CCX_TX_RPT = 3, + C2H_BT_RSSI = 4, + C2H_BT_OP_MODE = 5, + C2H_EXT_RA_RPT = 6, + C2H_HW_INFO_EXCH = 10, + C2H_C2H_H2C_TEST = 11, + C2H_BT_INFO = 12, + C2H_BT_MP_INFO = 15, + MAX_C2HEVENT +}; + +#ifdef CONFIG_PCI_HCI +struct hal_data_8192de +{ + VERSION_8192D VersionID; + + // add for 92D Phy mode/mac/Band mode + MACPHY_MODE_8192D MacPhyMode92D; + BAND_TYPE CurrentBandType92D; //0:2.4G, 1:5G + BAND_TYPE BandSet92D; + BOOLEAN bIsVS; + BOOLEAN bSupportRemoteWakeUp; + u8 AutoLoadStatusFor8192D; + + BOOLEAN bNOPG; + + BOOLEAN bMasterOfDMSP; + BOOLEAN bSlaveOfDMSP; + + u16 CustomerID; + + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + + u32 IntrMask[2]; + u32 IntrMaskToSet[2]; + + u32 DisabledFunctions; + + //current WIFI_PHY values + u32 ReceiveConfig; + u32 TransmitConfig; + WIRELESS_MODE CurrentWirelessMode; + HT_CHANNEL_WIDTH CurrentChannelBW; + u8 CurrentChannel; + u8 nCur40MhzPrimeSC;// Control channel sub-carrier + u16 BasicRateSet; + + //rf_ctrl + u8 rf_chip; + u8 rf_type; + u8 NumTotalRFPath; + + // + // EEPROM setting. + // + u16 EEPROMVID; + u16 EEPROMDID; + u16 EEPROMSVID; + u16 EEPROMSMID; + u16 EEPROMChannelPlan; + u16 EEPROMVersion; + + u8 EEPROMCustomerID; + u8 EEPROMBoardType; + u8 EEPROMRegulatory; + + u8 EEPROMThermalMeter; + + u8 EEPROMC9; + u8 EEPROMCC; + u8 PAMode; + + u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER_2G]; + u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + s8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff + // For power group + u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + + u8 LegacyHTTxPowerDiff;// Legacy to HT rate power diff + + u8 CrystalCap; // CrystalCap. + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv bt_coexist; +#endif + + // Read/write are allow for following hardware information variables + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + u8 DefaultInitialGain[4]; + u8 pwrGroupCnt; + u32 MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16]; + u32 CCKTxPowerLevelOriginalOffset; + + u32 AntennaTxPath; // Antenna path Tx + u32 AntennaRxPath; // Antenna path Rx + u8 BluetoothCoexist; + u8 ExternalPA; + u8 InternalPA5G[2]; //pathA / pathB + + //u32 LedControlNum; + //u32 LedControlMode; + //u32 TxPowerTrackControl; + u8 b1x1RecvCombine; // for 1T1R receive combining + + u8 bCurrentTurboEDCA; + u32 AcParam_BE; //Original parameter for BE, use for EDCA turbo. + + //vivi, for tx power tracking, 20080407 + //u16 TSSI_13dBm; + //u32 Pwr_Track; + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + + BOOLEAN bRFPathRxEnable[4]; // We support 4 RF path now. + + u32 RfRegChnlVal[2]; + + u8 bCckHighPower; + + BOOLEAN bPhyValueInitReady; + + BOOLEAN bTXPowerDataReadFromEEPORM; + + BOOLEAN bInSetPower; + + //RDG enable + BOOLEAN bRDGEnable; + + BOOLEAN bLoadIMRandIQKSettingFor2G;// True if IMR or IQK have done for 2.4G in scan progress + BOOLEAN bNeedIQK; + + BOOLEAN bLCKInProgress; + + BOOLEAN bEarlyModeEnable; + +#if 1 + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; +#else + //regc80¡¢regc94¡¢regc4c¡¢regc88¡¢regc9c¡¢regc14¡¢regca0¡¢regc1c¡¢regc78 + u4Byte IQKMatrixReg[IQK_Matrix_REG_NUM]; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; // 1->2G,24->5G 20M channel,21->5G 40M channel. +#endif + + //for host message to fw + u8 LastHMEBoxNum; + + u8 fw_ractrl; + // Beacon function related global variable. + u32 RegBcnCtrlVal; + u8 RegTxPause; + u8 RegFwHwTxQCtrl; + u8 RegReg542; + u8 RegCR_1; + + struct dm_priv dmpriv; + + u8 bInterruptMigration; + + u8 FwRsvdPageStartOffset; //2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. + + // Add for dual MAC 0--Mac0 1--Mac1 + u32 interfaceIndex; + + u16 RegRRSR; + + u16 EfuseUsedBytes; + u8 RTSInitRate; // 2010.11.24.by tynli. +#ifdef CONFIG_P2P + struct P2P_PS_Offload_t p2p_ps_offload; +#endif //CONFIG_P2P +}; + +typedef struct hal_data_8192de HAL_DATA_TYPE, *PHAL_DATA_TYPE; + +// +// Function disabled. +// +#define DF_TX_BIT BIT0 +#define DF_RX_BIT BIT1 +#define DF_IO_BIT BIT2 +#define DF_IO_D3_BIT BIT3 + +#define RT_DF_TYPE u32 +#define RT_DISABLE_FUNC(__pAdapter, __FuncBits) ((__pAdapter)->DisabledFunctions |= ((RT_DF_TYPE)(__FuncBits))) +#define RT_ENABLE_FUNC(__pAdapter, __FuncBits) ((__pAdapter)->DisabledFunctions &= (~((RT_DF_TYPE)(__FuncBits)))) +#define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) + +void InterruptRecognized8192DE(PADAPTER Adapter, PRT_ISR_CONTENT pIsrContent); +VOID UpdateInterruptMask8192DE(PADAPTER Adapter, u32 AddMSR, u32 RemoveMSR); +#endif + +#ifdef CONFIG_USB_HCI + +//should be renamed and moved to another file +typedef enum _INTERFACE_SELECT_8192DUSB{ + INTF_SEL0_USB = 0, // USB + INTF_SEL1_MINICARD = 1, // Minicard + INTF_SEL2_EKB_PRO = 2, // Eee keyboard proprietary + INTF_SEL3_PRO = 3, // Customized proprietary +} INTERFACE_SELECT_8192DUSB, *PINTERFACE_SELECT_8192DUSB; + +typedef INTERFACE_SELECT_8192DUSB INTERFACE_SELECT_USB; + +struct hal_data_8192du +{ + VERSION_8192D VersionID; + + // add for 92D Phy mode/mac/Band mode + MACPHY_MODE_8192D MacPhyMode92D; + BAND_TYPE CurrentBandType92D; //0:2.4G, 1:5G + BAND_TYPE BandSet92D; + BOOLEAN bIsVS; + + BOOLEAN bNOPG; + + BOOLEAN bSupportRemoteWakeUp; + BOOLEAN bMasterOfDMSP; + BOOLEAN bSlaveOfDMSP; +#ifdef CONFIG_DUALMAC_CONCURRENT + BOOLEAN bInModeSwitchProcess; +#endif + + u16 CustomerID; + + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + + //current WIFI_PHY values + u32 ReceiveConfig; + WIRELESS_MODE CurrentWirelessMode; + HT_CHANNEL_WIDTH CurrentChannelBW; + u8 CurrentChannel; + u8 nCur40MhzPrimeSC;// Control channel sub-carrier + u16 BasicRateSet; + + INTERFACE_SELECT_8192DUSB InterfaceSel; + + //rf_ctrl + u8 rf_chip; + u8 rf_type; + u8 NumTotalRFPath; + + // + // EEPROM setting. + // + u8 EEPROMVersion; + u16 EEPROMVID; + u16 EEPROMPID; + u16 EEPROMSVID; + u16 EEPROMSDID; + u8 EEPROMCustomerID; + u8 EEPROMSubCustomerID; + u8 EEPROMRegulatory; + + u8 EEPROMThermalMeter; + + u8 EEPROMC9; + u8 EEPROMCC; + u8 PAMode; + + u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER_2G]; + u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + s8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff + // For power group + u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; + + u8 LegacyHTTxPowerDiff;// Legacy to HT rate power diff + + u8 CrystalCap; // CrystalCap. + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv bt_coexist; +#endif + + // Read/write are allow for following hardware information variables + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + u8 DefaultInitialGain[4]; + u8 pwrGroupCnt; + u32 MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16]; + u32 CCKTxPowerLevelOriginalOffset; + + u32 AntennaTxPath; // Antenna path Tx + u32 AntennaRxPath; // Antenna path Rx + u8 BluetoothCoexist; + u8 ExternalPA; + u8 InternalPA5G[2]; //pathA / pathB + + //u32 LedControlNum; + //u32 LedControlMode; + //u32 TxPowerTrackControl; + u8 b1x1RecvCombine; // for 1T1R receive combining + + u8 bCurrentTurboEDCA; + u32 AcParam_BE; //Original parameter for BE, use for EDCA turbo. + + //vivi, for tx power tracking, 20080407 + //u16 TSSI_13dBm; + //u32 Pwr_Track; + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + + BOOLEAN bRFPathRxEnable[4]; // We support 4 RF path now. + + u32 RfRegChnlVal[2]; + + u8 bCckHighPower; + + BOOLEAN bPhyValueInitReady; + + BOOLEAN bTXPowerDataReadFromEEPORM; + + BOOLEAN bInSetPower; + + //RDG enable + BOOLEAN bRDGEnable; + + BOOLEAN bLoadIMRandIQKSettingFor2G;// True if IMR or IQK have done for 2.4G in scan progress + BOOLEAN bNeedIQK; + + BOOLEAN bLCKInProgress; + + BOOLEAN bEarlyModeEnable; + +#if 1 + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; +#else + //regc80¡¢regc94¡¢regc4c¡¢regc88¡¢regc9c¡¢regc14¡¢regca0¡¢regc1c¡¢regc78 + u4Byte IQKMatrixReg[IQK_Matrix_REG_NUM]; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; // 1->2G,24->5G 20M channel,21->5G 40M channel. +#endif + + //for host message to fw + u8 LastHMEBoxNum; + + u8 fw_ractrl; + // Beacon function related global variable. + u32 RegBcnCtrlVal; + u8 RegTxPause; + u8 RegFwHwTxQCtrl; + u8 RegReg542; + u8 RegCR_1; + + struct dm_priv dmpriv; + + u8 FwRsvdPageStartOffset; //2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. + + //Query RF by FW + BOOLEAN bReadRFbyFW; + + // For 92C USB endpoint setting + // + + u32 UsbBulkOutSize; + + int RtBulkOutPipe[3]; + int RtBulkInPipe; + int RtIntInPipe; + + // Add for dual MAC 0--Mac0 1--Mac1 + u32 interfaceIndex; + + u8 OutEpQueueSel; + u8 OutEpNumber; + + u8 Queue2EPNum[8];//for out endpoint number mapping + +#ifdef CONFIG_USB_TX_AGGREGATION + u8 UsbTxAggMode; + u8 UsbTxAggDescNum; +#endif +#ifdef CONFIG_USB_RX_AGGREGATION + u16 HwRxPageSize; // Hardware setting + u32 MaxUsbRxAggBlock; + + USB_RX_AGG_MODE UsbRxAggMode; + u8 UsbRxAggBlockCount; // USB Block count. Block size is 512-byte in hight speed and 64-byte in full speed + u8 UsbRxAggBlockTimeout; + u8 UsbRxAggPageCount; // 8192C DMA page count + u8 UsbRxAggPageTimeout; +#endif + + u16 RegRRSR; + + u16 EfuseUsedBytes; + u8 RTSInitRate; // 2010.11.24.by tynli. +#ifdef CONFIG_P2P + struct P2P_PS_Offload_t p2p_ps_offload; +#endif //CONFIG_P2P +}; + +typedef struct hal_data_8192du HAL_DATA_TYPE, *PHAL_DATA_TYPE; +#endif + +#define GET_HAL_DATA(__pAdapter) ((HAL_DATA_TYPE *)((__pAdapter)->HalData)) +#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) + +int FirmwareDownload92D(IN PADAPTER Adapter,IN BOOLEAN bUsedWoWLANFw); +VOID rtl8192d_FirmwareSelfReset(IN PADAPTER Adapter); +void rtl8192d_ReadChipVersion(IN PADAPTER Adapter); +VOID rtl8192d_EfuseParseChnlPlan(PADAPTER Adapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +VOID rtl8192d_ReadTxPowerInfo(PADAPTER Adapter, u8* PROMContent, BOOLEAN AutoLoadFail); +VOID rtl8192d_ResetDualMacSwitchVariables(IN PADAPTER Adapter); +u8 GetEEPROMSize8192D(PADAPTER Adapter); +BOOLEAN PHY_CheckPowerOffFor8192D(PADAPTER Adapter); +VOID PHY_SetPowerOnFor8192D(PADAPTER Adapter); +//void PHY_ConfigMacPhyMode92D(PADAPTER Adapter); +void rtl8192d_free_hal_data(_adapter * padapter); +void rtl8192d_set_hal_ops(struct hal_ops *pHalFunc); + +#endif + +#ifdef CONFIG_MP_INCLUDED + + +extern void Hal_SetAntenna(PADAPTER pAdapter); +extern void Hal_SetBandwidth(PADAPTER pAdapter); + +extern void Hal_SetTxPower(PADAPTER pAdapter); +extern void Hal_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetSingleToneTx ( PADAPTER pAdapter , u8 bStart ); +extern void Hal_SetSingleCarrierTx (PADAPTER pAdapter, u8 bStart); +extern void Hal_SetContinuousTx (PADAPTER pAdapter, u8 bStart); +extern void Hal_SetBandwidth(PADAPTER pAdapter); + +extern void Hal_SetDataRate(PADAPTER pAdapter); +extern void Hal_SetChannel(PADAPTER pAdapter); +extern void Hal_SetAntennaPathPower(PADAPTER pAdapter); +extern s32 Hal_SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +extern s32 Hal_SetPowerTracking(PADAPTER padapter, u8 enable); +extern void Hal_GetPowerTracking(PADAPTER padapter, u8 * enable); +extern void Hal_GetThermalMeter(PADAPTER pAdapter, u8 *value); +extern void Hal_mpt_SwitchRfSetting(PADAPTER pAdapter); +extern void Hal_MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14); +extern void Hal_MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven); +extern void Hal_SetCCKTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_SetOFDMTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_TriggerRFThermalMeter(PADAPTER pAdapter); +extern u8 Hal_ReadRFThermalMeter(PADAPTER pAdapter); +extern void Hal_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart); + + +#endif //end CONFIG_MP_INCLUDED + diff --git a/rtl8192cu-fixes/include/rtl8192d_led.h b/rtl8192cu-fixes/include/rtl8192d_led.h new file mode 100755 index 00000000..d736bda4 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_led.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * 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 __RTL8192D_LED_H_ +#define __RTL8192D_LED_H_ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8192du_InitSwLeds(_adapter *padapter); +void rtl8192du_DeInitSwLeds(_adapter *padapter); +#endif + +#ifdef CONFIG_PCI_HCI +void rtl8192de_gen_RefreshLedState(PADAPTER Adapter); +void rtl8192de_InitSwLeds(_adapter *padapter); +void rtl8192de_DeInitSwLeds(_adapter *padapter); +#endif + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192d_recv.h b/rtl8192cu-fixes/include/rtl8192d_recv.h new file mode 100755 index 00000000..36cc2322 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_recv.h @@ -0,0 +1,187 @@ +/****************************************************************************** + * + * 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 _RTL8192D_RECV_H_ +#define _RTL8192D_RECV_H_ + +#include +#include +#include + + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + #define NR_RECVBUFF 1024//512//128 + #else + #define NR_RECVBUFF (16) + #endif +#elif defined(PLATFORM_OS_CE) + #ifdef CONFIG_SDIO_HCI + #define NR_RECVBUFF (128) + #else + #define NR_RECVBUFF (4) + #endif +#else +#ifdef CONFIG_SINGLE_RECV_BUF + #define NR_RECVBUFF (1) +#else + #define NR_RECVBUFF (4) +#endif //CONFIG_SINGLE_RECV_BUF + #define NR_PREALLOC_RECV_SKB (8) +#endif + + + +#define RECV_BLK_SZ 512 +#define RECV_BLK_CNT 16 +#define RECV_BLK_TH RECV_BLK_CNT + +#if defined(CONFIG_USB_HCI) + +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + //#define MAX_RECVBUF_SZ (32768) // 32k + //#define MAX_RECVBUF_SZ (16384) //16K + //#define MAX_RECVBUF_SZ (10240) //10K + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 +#define RX_MAX_QUEUE 2 +#endif + +#define RECV_BULK_IN_ADDR 0x80 +#define RECV_INT_IN_ADDR 0x81 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 + +struct phy_stat +{ + unsigned int phydw0; + + unsigned int phydw1; + + unsigned int phydw2; + + unsigned int phydw3; + + unsigned int phydw4; + + unsigned int phydw5; + + unsigned int phydw6; + + unsigned int phydw7; +}; + +typedef struct _Phy_OFDM_Rx_Status_Report_8192cd +{ + unsigned char trsw_gain_X[4]; + unsigned char pwdb_all; + unsigned char cfosho_X[4]; + unsigned char cfotail_X[4]; + unsigned char rxevm_X[2]; + unsigned char rxsnr_X[4]; + unsigned char pdsnr_X[2]; + unsigned char csi_current_X[2]; + unsigned char csi_target_X[2]; + unsigned char sigevm; + unsigned char max_ex_pwr; +//#ifdef RTL8192SE +#ifdef CONFIG_LITTLE_ENDIAN + unsigned char ex_intf_flg:1; + unsigned char sgi_en:1; + unsigned char rxsc:2; + //unsigned char rsvd:4; + unsigned char idle_long:1; + unsigned char r_ant_train_en:1; + unsigned char ANTSELB:1; + unsigned char ANTSEL:1; +#else // _BIG_ENDIAN_ + //unsigned char rsvd:4; + unsigned char ANTSEL:1; + unsigned char ANTSELB:1; + unsigned char r_ant_train_en:1; + unsigned char idle_long:1; + unsigned char rxsc:2; + unsigned char sgi_en:1; + unsigned char ex_intf_flg:1; +#endif +//#else // RTL8190, RTL8192E +// unsigned char sgi_en; +// unsigned char rxsc_sgien_exflg; +//#endif +}__attribute__ ((packed)) PHY_STS_OFDM_8192CD_T,PHY_RX_DRIVER_INFO_8192CD; + +typedef struct _Phy_CCK_Rx_Status_Report_8192cd +{ + /* For CCK rate descriptor. This is a signed 8:1 variable. LSB bit presend + 0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */ + u8 adc_pwdb_X[4]; + u8 SQ_rpt; + u8 cck_agc_rpt; +} PHY_STS_CCK_8192CD_T; + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#ifdef CONFIG_USB_HCI +typedef struct _INTERRUPT_MSG_FORMAT_EX{ + unsigned int C2H_MSG0; + unsigned int C2H_MSG1; + unsigned int C2H_MSG2; + unsigned int C2H_MSG3; + unsigned int HISR; // from HISR Reg0x124, read to clear + unsigned int HISRE;// from HISRE Reg0x12c, read to clear + unsigned int MSG_EX; +}INTERRUPT_MSG_FORMAT_EX,*PINTERRUPT_MSG_FORMAT_EX; + +void rtl8192du_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +int rtl8192du_init_recv_priv(_adapter * padapter); +void rtl8192du_free_recv_priv(_adapter * padapter); +#endif + +#ifdef CONFIG_PCI_HCI +int rtl8192de_init_recv_priv(_adapter * padapter); +void rtl8192de_free_recv_priv(_adapter * padapter); +#endif + +void rtl8192d_translate_rx_signal_stuff(union recv_frame *precvframe, struct phy_stat *pphy_info); +void rtl8192d_query_rx_desc_status(union recv_frame *precvframe, struct recv_stat *pdesc); + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192d_rf.h b/rtl8192cu-fixes/include/rtl8192d_rf.h new file mode 100755 index 00000000..0b439a3f --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_rf.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/****************************************************************************** + * + * + * Module: rtl8192d_rf.h ( Header File) + * + * Note: Collect every HAL RF type exter API or constant. + * + * Function: + * + * Export: + * + * Abbrev: + * + * History: + * Data Who Remark + * + * 09/25/2008 MHC Create initial version. + * + * +******************************************************************************/ +#ifndef _RTL8192D_RF_H_ +#define _RTL8192D_RF_H_ +/* Check to see if the file has been included already. */ + + +/*--------------------------Define Parameters-------------------------------*/ + +// +// For RF 6052 Series +// +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + +/*------------------------Export Marco Definition---------------------------*/ + +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ + +// +// RF RL6052 Series API +// +void rtl8192d_RF_ChangeTxPath( IN PADAPTER Adapter, + IN u16 DataRate); +void rtl8192d_PHY_RF6052SetBandwidth( + IN PADAPTER Adapter, + IN HT_CHANNEL_WIDTH Bandwidth); +VOID rtl8192d_PHY_RF6052SetCckTxPower( + IN PADAPTER Adapter, + IN u8* pPowerlevel); +VOID rtl8192d_PHY_RF6052SetOFDMTxPower( + IN PADAPTER Adapter, + IN u8* pPowerLevel, + IN u8 Channel); +int PHY_RF6052_Config8192D( IN PADAPTER Adapter ); + +BOOLEAN rtl8192d_PHY_EnableAnotherPHY(IN PADAPTER Adapter, IN BOOLEAN bMac0); + +void rtl8192d_PHY_PowerDownAnotherPHY(IN PADAPTER Adapter, IN BOOLEAN bMac0); + + +/*--------------------------Exported Function prototype---------------------*/ + + +#endif/* End of HalRf.h */ + diff --git a/rtl8192cu-fixes/include/rtl8192d_spec.h b/rtl8192cu-fixes/include/rtl8192d_spec.h new file mode 100755 index 00000000..bef7184e --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_spec.h @@ -0,0 +1,1841 @@ +/****************************************************************************** + * + * 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 __RTL8192D_SPEC_H__ +#define __RTL8192D_SPEC_H__ + +#include + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + + +//============================================================ +// 8192D Regsiter offset definition +//============================================================ + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_POWER_OFF_IN_PROCESS 0x0017 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002c //for 92d, DMDP,SMSP,DMSP contrl +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +//#define REG_GPIO_MUXCFG 0x0041 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 + +#define REG_MCUFWDL 0x0080 +#ifdef CONFIG_WOWLAN +#define REG_WOWLAN_REASON 0x00FC +#endif // CONFIG_WOWLAN +#define REG_HMEBOX_EXT_0 0x0088 +#define REG_HMEBOX_EXT_1 0x008A +#define REG_HMEBOX_EXT_2 0x008C +#define REG_HMEBOX_EXT_3 0x008E + +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 + +#define REG_MAC0 0x0081 +#define REG_MAC1 0x0053 +#define FW_MAC0_ready 0x18 +#define FW_MAC1_ready 0x1A +#define MAC0_ON BIT7 +#define MAC1_ON BIT0 +#define mac0_ready BIT0 +#define mac1_ready BIT0 + + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTIMR 0x0138 +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_C2HEVT_MSG_TEST 0x01B8 +#define REG_MCUTST_1 0x01c0 +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC + +#define REG_LLT_INIT 0x01E0 +#define REG_BB_ACCEESS_CTRL 0x01E8 +#define REG_BB_ACCESS_DATA 0x01EC + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA 0x0340 // RX Queue Descriptor Address +#define REG_DBI 0x0348 // Backdoor REG for Access Configuration +//sherry added for DBI Read/Write 20091126 +#define REG_DBI_WDATA 0x0348 // Backdoor REG for Access Configuration +#define REG_DBI_RDATA 0x034C //Backdoor REG for Access Configuration +#define REG_DBI_CTRL 0x0350 //Backdoor REG for Access Configuration +#define REG_DBI_FLAG 0x0352 //Backdoor REG for Access Configuration#define REG_MDIO 0x0354 // MDIO for Access PCIE PHY +#define REG_MDIO 0x0354 // MDIO for Access PCIE PHY +#define REG_DBG_SEL 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM 0x0363 //PCIe CPWM +#define REG_UART_CTRL 0x0364 // UART Control +#define REG_UART_TX_DESA 0x0370 // UART TX Descriptor Address +#define REG_UART_RX_DESA 0x0378 // UART Rx Descriptor Address + + +// spec version 11 +//----------------------------------------------------- +// +// 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 + + +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY 0x0425 +#define REG_LIFETIME_EN 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 +#define REG_INIRTS_RATE_SEL 0x0480 +#define REG_INIDATA_RATE_SEL 0x0484 + +//#define REG_FW_TSF_SYNC_CNT 0x04A0 +#define REG_FW_RESET_TSF_CNT_1 0x05FC +#define REG_FW_RESET_TSF_CNT_0 0x05FD +#define REG_FW_BCN_DIS_CNT 0x05FE + +#define REG_POWER_STATUS 0x04A4 +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#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_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_DUMMY 0x04FC + + + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_TSFTR_SYN_OFFSET 0x0518 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 // The same as REG_MBSSID_BCN_SPACE +#define REG_MBSSID_BCN_SPACE 0x0554 +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_TSFTR1 0x0568 +#define REG_INIT_TSFTR 0x0564 +#define REG_ATIMWND_1 0x0570 +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_ACMRSTCTRL 0x05C1 +#define REG_ACMAVG 0x05C2 +#define REG_VO_ADMTIME 0x05C4 +#define REG_VI_ADMTIME 0x05C6 +#define REG_BE_ADMTIME 0x05C8 +#define REG_EDCA_RANDOM_GEN 0x05CC +#define REG_SCH_TXCMD 0x05D0 + +#define REG_DMC 0x05F0 //Dual MAC Co-Existence Register + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +#define REG_RESP_SIFS_CCK 0x063C +#define REG_RESP_SIFS_OFDM 0x063E +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + + +//WMA, BA, CCX +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + + +// Security +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +// Power +#define REG_WOW_CTRL 0x0690 +#define REG_PSSTATUS 0x0691 +#define REG_PS_RX_INFO 0x0692 +#define REG_LPNAV_CTRL 0x0694 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_CALB32K_CTRL 0x06AC +#define REG_PKT_MON_CTRL 0x06B4 +#define REG_BT_COEX_TABLE 0x06C0 +#define REG_WMAC_RESP_TXINFO 0x06D8 + +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +// for 92DU high_Queue low_Queue Normal_Queue select +#define REG_USB_High_NORMAL_Queue_Select_MAC0 0xFE44 +//#define REG_USB_LOW_Queue_Select_MAC0 0xFE45 +#define REG_USB_High_NORMAL_Queue_Select_MAC1 0xFE47 +//#define REG_USB_LOW_Queue_Select_MAC1 0xFE48 + +// For test chip +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_TEST_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 // 0xFE66~0xFE6B +#define REG_TEST_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_TEST_SIE_STRING 0xFE80 // 0xFE80~0xFEB9 + + +// For normal chip +#define REG_NORMAL_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_NORMAL_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 // 0xFE65~0xFE67 +#define REG_NORMAL_SIE_PHY 0xFE68 // 0xFE68~0xFE6B +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_NORMAL_SIE_STRING 0xFE80 // 0xFE80~0xFEDF + + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. + +#define SYS_ISO_CTRL REG_SYS_ISO_CTRL // System Isolation Interface Control. +#define SYS_FUNC_EN REG_SYS_FUNC_EN // System Function Enable. +#define SYS_CLK REG_SYS_CLKR +#define CR9346 REG_9346CR // 93C46/93C56 Command Register. +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +#define EFUSE_TEST REG_EFUSE_TEST // E-Fuse Test. +#define MSR (REG_CR + 2) // Media Status register +#define ISR REG_HISR +#define TSFR REG_TSFTR // Timing Sync Function Timer Register. + +#define MACIDR0 REG_MACID // MAC ID Register, Offset 0x0050-0x0053 +#define MACIDR4 (REG_MACID + 4) // MAC ID Register, Offset 0x0054-0x0055 + +#define PBP REG_PBP + +// Redifine MACID register, to compatible prior ICs. +#define IDR0 MACIDR0 +#define IDR4 MACIDR4 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM REG_CAMCMD //IN 8190 Data Sheet is called CAMcmd +#define WCAMI REG_CAMWRITE // Software write CAM input content +#define RCAMO REG_CAMREAD // Software read/write CAM config +#define CAMDBG REG_CAMDBG +#define SECR REG_SECCFG //Security Configuration Register + +// Unused register +#define UnusedRegister 0x1BF +#define DCAM UnusedRegister +#define PSR UnusedRegister +#define BBAddr UnusedRegister +#define PhyDataR UnusedRegister + +#define InvalidBBRFValue 0x12345678 + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +//---------------------------------------------------------------------------- +// 8192C Cmd9346CR bits (Offset 0xA, 16bit) +//---------------------------------------------------------------------------- +#define CmdEEPROM_En BIT5 // EEPROM enable when set 1 +#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 +#define Cmd9346CR_9356SEL BIT4 +#define AutoLoadEEPROM (CmdEEPROM_En|CmdEERPOMSEL) +#define AutoLoadEFUSE CmdEEPROM_En + +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + + +//---------------------------------------------------------------------------- +// 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +/* +Network Type +00: No link +01: Link in ad hoc network +10: Link in infrastructure network +11: AP mode +Default: 00b. +*/ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +// +// 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) +// +//---------------------------------------------------------------------------- +// 8192C Response Rate Set Register (offset 0x181, 24bits) +//---------------------------------------------------------------------------- +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 +#define BRSR_AckShortPmb BIT23 +// CCK ACK: use Short Preamble or not + + +//---------------------------------------------------------------------------- +// 8192C Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +//---------------------------------------------------------------------------- +// 8192C BW_OPMODE bits (Offset 0x203, 8bit) +//---------------------------------------------------------------------------- +#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_5G BIT1 +#define BW_OPMODE_11J BIT0 + + +//---------------------------------------------------------------------------- +// 8192C CAM Config Setting (offset 0x250, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID BIT15 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT5 + +#define CAM_CONTENT_COUNT 8 + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_CONFIG_USEDK _TRUE +#define CAM_CONFIG_NO_USEDK _FALSE + +#define CAM_WRITE BIT16 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT31 + +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 + + +// +// 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) +// +//---------------------------------------------------------------------------- +// 8190 IMR/ISR bits (offset 0xfd, 8bits) +//---------------------------------------------------------------------------- +#define IMR8190_DISABLED 0x0 +// IMR DW0 Bit 0-31 +#define IMR_BCNDMAINT6 BIT31 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5 BIT30 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4 BIT29 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3 BIT28 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2 BIT27 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1 BIT26 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK8 BIT25 // Beacon Queue DMA OK Interrup 8 +#define IMR_BCNDOK7 BIT24 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6 BIT23 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5 BIT22 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4 BIT21 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3 BIT20 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2 BIT19 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1 BIT18 // Beacon Queue DMA OK Interrup 1 +#define IMR_TIMEOUT2 BIT17 // Timeout interrupt 2 +#define IMR_TIMEOUT1 BIT16 // Timeout interrupt 1 +#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow +#define IMR_PSTIMEOUT BIT14 // Power save time out interrupt +#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 +#define IMR_RXFOVW BIT12 // Receive FIFO Overflow +#define IMR_RDU BIT11 // Receive Descriptor Unavailable +#define IMR_ATIMEND BIT10 // For 92C,ATIM Window End Interrupt +#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup +#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt +#define IMR_TBDOK BIT7 // Transmit Beacon OK interrup +#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define IMR_TBDER BIT5 // For 92C,Transmit Beacon Error Interrupt +#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt +#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt +#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt +#define IMR_VODOK BIT1 // AC_VO DMA Interrupt +#define IMR_ROK BIT0 // Receive DMA OK Interrupt + +// 13. Host Interrupt Status Extension Register (Offset: 0x012C-012Eh) +#define IMR_TXERR BIT11 +#define IMR_RXERR BIT10 +#define IMR_C2HCMD BIT9 +#define IMR_CPWM BIT8 +//RSVD [2-7] +#define IMR_OCPINT BIT1 +#define IMR_WLANOFF BIT0 + + + +//---------------------------------------------------------------------------- +// 8192D EFUSE +//---------------------------------------------------------------------------- +#define HWSET_MAX_SIZE 256 + +//---------------------------------------------------------------------------- +// 8192C EEPROM/EFUSE share register definition. +//---------------------------------------------------------------------------- + +// +// Default Value for EEPROM or EFUSE!!! +// +#define EEPROM_Default_TSSI 0x0 +#define EEPROM_Default_TxPowerDiff 0x0 +#define EEPROM_Default_CrystalCap 0x0 //92D default 0x0 +#define EEPROM_Default_BoardType 0x02 // Default: 2X2, RTL8192CE(QFPN68) +#define EEPROM_Default_TxPower 0x1010 +#define EEPROM_Default_HT2T_TxPwr 0x10 + +#define EEPROM_Default_LegacyHTTxPowerDiff 0x4 +#define EEPROM_Default_ThermalMeter 0x12 + +#define EEPROM_Default_AntTxPowerDiff 0x0 +//#define EEPROM_Default_TxPwDiff_CrystalCap 0x5 +#define EEPROM_Default_TxPowerLevel_2G 0x2C +#define EEPROM_Default_TxPowerLevel_5G 0x22 + +#define EEPROM_Default_HT40_2SDiff 0x0 +#define EEPROM_Default_HT20_Diff 2 // HT20<->40 default Tx Power Index Difference +#define EEPROM_Default_LegacyHTTxPowerDiff 0x4 //OFDM Tx Power index diff +#define EEPROM_Default_HT40_PwrMaxOffset 0 +#define EEPROM_Default_HT20_PwrMaxOffset 0 + +// For debug +#define EEPROM_Default_PID 0x1234 +#define EEPROM_Default_VID 0x5678 +#define EEPROM_Default_CustomerID 0xAB +#define EEPROM_Default_SubCustomerID 0xCD +#define EEPROM_Default_Version 0 + +#define EEPROM_Default_externalPA_C9 0x00 +#define EEPROM_Default_externalPA_CC 0xFF +#define EEPROM_Default_internalPA_SP3T_C9 0xAA +#define EEPROM_Default_internalPA_SP3T_CC 0xAF +#define EEPROM_Default_internalPA_SPDT_C9 0xAA +#ifdef CONFIG_PCI_HCI +#define EEPROM_Default_internalPA_SPDT_CC 0xA0 +#else +#define EEPROM_Default_internalPA_SPDT_CC 0xFA +#endif + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC 0xB +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 // CCX test. By Bruce, 2009-02-25. +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + + +#define RTL8192_EEPROM_ID 0x8129 +#define EEPROM_WAPI_SUPPORT 0x78 + + +#ifdef CONFIG_PCI_HCI +#define RT_IBSS_INT_MASKS (IMR_BcnInt | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) +#define RT_BSS_INT_MASKS (RT_IBSS_INT_MASKS) + +#define RTL8190_EEPROM_ID 0x8129 // 0-1 +#define EEPROM_HPON 0x02 // LDO settings.2-5 +#define EEPROM_CLK 0x06 // Clock settings.6-7 +#define EEPROM_MAC_FUNCTION 0x08 // SE Test mode.8 + +#define EEPROM_VID 0x28 // SE Vendor ID.A-B +#define EEPROM_DID 0x2A // SE Device ID. C-D +#define EEPROM_SVID 0x2C // SE Vendor ID.E-F +#define EEPROM_SMID 0x2E // SE PCI Subsystem ID. 10-11 + +#define EEPROM_MAC_ADDR 0x16 // SEMAC Address. 12-17 +#define EEPROM_MAC_ADDR_MAC0_92D 0x55 +#define EEPROM_MAC_ADDR_MAC1_92D 0x5B +//---------------------------------------------------------------- +// 2.4G band Tx power index setting +#define EEPROM_CCK_TX_PWR_INX_2G 0x61 +#define EEPROM_HT40_1S_TX_PWR_INX_2G 0x67 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G 0x6D +#define EEPROM_HT20_TX_PWR_INX_DIFF_2G 0x70 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_2G 0x73 +#define EEPROM_HT40_MAX_PWR_OFFSET_2G 0x76 +#define EEPROM_HT20_MAX_PWR_OFFSET_2G 0x79 + +//5GL channel 32-64 +#define EEPROM_HT40_1S_TX_PWR_INX_5GL 0x7C +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GL 0x82 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GL 0x85 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GL 0x88 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GL 0x8B +#define EEPROM_HT20_MAX_PWR_OFFSET_5GL 0x8E + +//5GM channel 100-140 +#define EEPROM_HT40_1S_TX_PWR_INX_5GM 0x91 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GM 0x97 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GM 0x9A +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GM 0x9D +#define EEPROM_HT40_MAX_PWR_OFFSET_5GM 0xA0 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GM 0xA3 + +//5GH channel 149-165 +#define EEPROM_HT40_1S_TX_PWR_INX_5GH 0xA6 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GH 0xAC +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GH 0xAF +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GH 0xB2 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GH 0xB5 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GH 0xB8 + +#define EEPROM_CHANNEL_PLAN 0xBB // Map of supported channels. +#define EEPROM_IQK_DELTA 0xBC +#define EEPROM_LCK_DELTA 0xBC +#define EEPROM_XTAL_K 0xBD //[7:5] +#define EEPROM_TSSI_A_5G 0xBE +#define EEPROM_TSSI_B_5G 0xBF +#define EEPROM_TSSI_AB_5G 0xC0 +#define EEPROM_THERMAL_METER 0xC3 //[4:0] +#define EEPROM_PATHDIV 0xC4 +#define EEPROM_RF_OPT1 0xC4 +#define EEPROM_RF_OPT2 0xC5 +#define EEPROM_RF_OPT3 0xC6 +#define EEPROM_RF_OPT4 0xC7 +#define EEPROM_RF_OPT5 0xC8 +#define EEPROM_RF_OPT6 0xC9 +#define EEPROM_VERSION 0xCA +#define EEPROM_CUSTOMER_ID 0xCB +#define EEPROM_RF_OPT7 0xCC + +#define EEPROM_WIDIPAIRING_ADDR 0xF0 +#define EEPROM_WIDIPAIRING_KEY 0xF6 + +#define EEPROM_DEF_PART_NO 0x3FD //Byte +#define EEPROME_CHIP_VERSION_L 0x3FF +#define EEPROME_CHIP_VERSION_H 0x3FE +#endif + +#ifdef CONFIG_USB_HCI +#define RTL8190_EEPROM_ID 0x8129 // 0-1 +#define EEPROM_HPON 0x02 // LDO settings.2-5 +#define EEPROM_CLK 0x06 // Clock settings.6-7 +#define EEPROM_MAC_FUNCTION 0x08 // SE Test mode.8 + +#define EEPROM_VID 0xC // SE Vendor ID.A-B +#define EEPROM_PID 0xE // SE Device ID. C-D +#define EEPROM_ENDPOINT_SETTING 0x10 +#ifdef CONFIG_WOWLAN +#define EEPROM_Option_Setting 0x11 +#endif // CONFIG_WOWLAN +#define EEPROM_CHIRP_K 0x12 // Changed +#define EEPROM_USB_PHY 0x13 // Changed +#define EEPROM_NORMAL_BoardType EEPROM_RF_OPT1 //[7:5] +#define EEPROM_MAC_ADDR 0x16 // SEMAC Address. 12-17 +#define EEPROM_STRING 0x1F +#define EEPROM_SUBCUSTOMER_ID 0x59 + +#define EEPROM_MAC_ADDR_MAC0_92D 0x19 +#define EEPROM_MAC_ADDR_MAC1_92D 0x5B +//---------------------------------------------------------------- +// 2.4G band Tx power index setting +#define EEPROM_CCK_TX_PWR_INX_2G 0x61 +#define EEPROM_HT40_1S_TX_PWR_INX_2G 0x67 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G 0x6D +#define EEPROM_HT20_TX_PWR_INX_DIFF_2G 0x70 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_2G 0x73 +#define EEPROM_HT40_MAX_PWR_OFFSET_2G 0x76 +#define EEPROM_HT20_MAX_PWR_OFFSET_2G 0x79 + +//5GL channel 32-64 +#define EEPROM_HT40_1S_TX_PWR_INX_5GL 0x7C +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GL 0x82 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GL 0x85 +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GL 0x88 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GL 0x8B +#define EEPROM_HT20_MAX_PWR_OFFSET_5GL 0x8E + +//5GM channel 100-140 +#define EEPROM_HT40_1S_TX_PWR_INX_5GM 0x91 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GM 0x97 +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GM 0x9A +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GM 0x9D +#define EEPROM_HT40_MAX_PWR_OFFSET_5GM 0xA0 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GM 0xA3 + +//5GH channel 149-165 +#define EEPROM_HT40_1S_TX_PWR_INX_5GH 0xA6 +#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GH 0xAC +#define EEPROM_HT20_TX_PWR_INX_DIFF_5GH 0xAF +#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GH 0xB2 +#define EEPROM_HT40_MAX_PWR_OFFSET_5GH 0xB5 +#define EEPROM_HT20_MAX_PWR_OFFSET_5GH 0xB8 + +#define EEPROM_CHANNEL_PLAN 0xBB // Map of supported channels. +#define EEPROM_TEST_CHANNEL_PLAN 0xBB +#define EEPROM_IQK_DELTA 0xBC +#define EEPROM_LCK_DELTA 0xBC +#define EEPROM_XTAL_K 0xBD //[7:5] +#define EEPROM_TSSI_A_5G 0xBE +#define EEPROM_TSSI_B_5G 0xBF +#define EEPROM_TSSI_AB_5G 0xC0 +#define EEPROM_THERMAL_METER 0xC3 //[4:0] +#define EEPROM_RF_OPT1 0xC4 +#define EEPROM_RF_OPT2 0xC5 +#define EEPROM_RF_OPT3 0xC6 +#define EEPROM_RF_OPT4 0xC7 +#define EEPROM_RF_OPT5 0xC8 +#define EEPROM_RF_OPT6 0xC9 +#define EEPROM_VERSION 0xCA +#define EEPROM_CUSTOMER_ID 0xCB +#define EEPROM_RF_OPT7 0xCC + +#define EEPROM_DEF_PART_NO 0x3FD //Byte +#define EEPROME_CHIP_VERSION_L 0x3FF +#define EEPROME_CHIP_VERSION_H 0x3FE + +//------------------------------------------------------------- +// EEPROM content definitions +//------------------------------------------------------------- +#define OS_LINK_SPEED_NORMAL_MASK BIT3 | BIT2 +#define OS_LINK_SPEED_TEST_MASK BIT3 | BIT4 + +#define BOARD_TYPE_NORMAL_MASK 0xE0 +#define BOARD_TYPE_TEST_MASK 0xF + +#define BT_COEXISTENCE_TEST BIT4 +#define BT_COEXISTENCE_NORMAL BIT5 + +#define BT_CO_SHIFT_TEST 4 +#define BT_CO_SHIFT_NORMAL 5 + +#define EP_NUMBER_MASK_TEST 0x30 //bit 4:5 0Eh +#define EP_NUMBER_SHIFT_TEST 4 + +#define USB_PHY_PARA_SIZE_TEST 6 +#define USB_PHY_PARA_SIZE_NORMAL 4 + +//------------------------------------------------------------- +// EEPROM default value definitions +//------------------------------------------------------------- +// Use 0xABCD instead of 0x8192 for debug +#define EEPROM_DEF_ID_0 0xCD // Byte 0x00 +#define EEPROM_DEF_ID_1 0xAB // Byte 0x01 + +#define EEPROM_DEF_RTK_RSV_A3 0x74 // Byte 0x03 +#define EEPROM_DEF_RTK_RSV_A4 0x6D // Byte 0x04 +#define EEPROM_DEF_RTK_RSV_A8 0xFF // Byte 0x08 + +#define EEPROM_DEF_VID_0 0x0A // Byte 0x0A +#define EEPROM_DEF_VID_1 0x0B + +#define EEPROM_DEF_PID_0 0x92 // Byte 0x0C +#define EEPROM_DEF_PID_1 0x81 + + +#define EEPROM_TEST_DEF_USB_OPT 0x80 // Byte 0x0E +#define EEPROM_NORMAL_DEF_USB_OPT 0x00 // Byte 0x0E + +#define EEPROM_DEF_CHIRPK 0x15 // Byte 0x0F + +#define EEPROM_DEF_USB_PHY_0 0x85 // Byte 0x10 +#define EEPROM_DEF_USB_PHY_1 0x62 // Byte 0x11 +#define EEPROM_DEF_USB_PHY_2 0x9E // Byte 0x12 +#define EEPROM_DEF_USB_PHY_3 0x06 // Byte 0x13 + +#define EEPROM_DEF_TSSI_A 0x09 // Byte 0x78 +#define EEPROM_DEF_TSSI_B 0x09 // Byte 0x79 + + +#define EEPROM_DEF_THERMAL_METER 0x12 // Byte 0x7A + + +#define EEPROM_USB_SN BIT(0) +#define EEPROM_USB_REMOTE_WAKEUP BIT(1) +#define EEPROM_USB_DEVICE_PWR BIT(2) +#define EEPROM_EP_NUMBER (BIT(3)|BIT(4)) + +#if 0 +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define EEPROM_CID_DEFAULT 0x0 + +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + + +#define EEPROM_CID_CCX 0x10 // CCX test. By Bruce, 2009-02-25. + +#endif +#endif + + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ + +//---------------------------------------------------------------------------- +// 8192C (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +#define RCR_APPFCS BIT31 //WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // +#define RCR_APP_ICV BIT29 // +#define RCR_APP_PHYST_RXFF BIT28 // +#define RCR_APP_BA_SSN BIT27 //Accept BA SSN +#define RCR_ENMBID BIT24 //Enable Multiple BssId. +#define RCR_LSIGEN BIT23 +#define RCR_MFBEN BIT22 +#define RCR_HTC_LOC_CTRL BIT14 //MFC<--HTC=1 MFC-->HTC=0 +#define RCR_AMF BIT13 //Accept management type frame +#define RCR_ACF BIT12 //Accept control type frame +#define RCR_ADF BIT11 //Accept data type frame +#define RCR_AICV BIT9 //Accept ICV error packet +#define RCR_ACRC32 BIT8 //Accept CRC32 error packet +#define RCR_CBSSID_BCN BIT7 //Accept BSSID match packet (Rx beacon, probe rsp) +#define RCR_CBSSID_DATA BIT6 //Accept BSSID match packet (Data) +#define RCR_CBSSID RCR_CBSSID_DATA //Accept BSSID match packet +#define RCR_APWRMGT BIT5 //Accept power management packet +#define RCR_ADD3 BIT4 //Accept address 3 match packet +#define RCR_AB BIT3 //Accept broadcast packet +#define RCR_AM BIT2 //Accept multicast packet +#define RCR_APM BIT1 //Accept physical match packet +#define RCR_AAP BIT0 //Accept all unicast packet +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + + + +//============================================================================ +// 8192c USB specific Regsiter Offset and Content definition, +// 2009.08.18, added by vivi. for merge 92c and 92C into one driver +//============================================================================ +//#define APS_FSMCO 0x0004 same with 92Ce +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_VID 0xFE60 +#define REG_USB_PID 0xFE62 +#define REG_USB_OPTIONAL 0xFE64 +#define REG_USB_CHIRP_K 0xFE65 +#define REG_USB_PHY 0xFE66 +#define REG_USB_MAC_ADDR 0xFE70 + +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +#define InvalidBBRFValue 0x12345678 + +//============================================================================ +// 8192C Regsiter Bit and Content definition +//============================================================================ +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- + +//2 SPS0_CTRL +#define SW18_FPWM BIT(3) + + +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + + +//2 9346CR + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + + +//2 AFE_MISC +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + + +//2 SPS0_CTRL + + +//2 SPS_OCP_CFG + + +//2 RSV_CTRL +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + + +//2 LDOA15_CTRL +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + + + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +//2 AFE_XTAL_CTRL +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + + +//2 AFE_PLL_CTRL +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + + +//2 EFUSE_CTRL +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +//2 EFUSE_TEST +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +//2 PWR_DATA + +//2 CAL_TIMER + +//2 ACLK_MON +#define RSM_EN BIT(0) +#define Timer_EN BIT(4) + + +//2 GPIO_MUXCFG +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EnBT BIT(5) +#define EnUart BIT(8) +#define Uart_910 BIT(9) +#define EnPMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EnSIC BIT(12) +#define SIC_23 BIT(13) +#define EnHDP BIT(14) +#define SIC_LBK BIT(15) + +//2 GPIO_PIN_CTRL + + + +//2 GPIO_INTM + +//2 LEDCFG +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define SECCAM_CLR BIT(30) + +//2 FSIMR + +//2 FSISR + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define MAC1_WINTINI_RDY BIT(11)// 0X81 BIT3 +#define CPRST BIT(23) + + + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + + +//2 Function Enable Registers +//2 CR + +#define REG_LBMODE (REG_CR + 3) + + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + + +//2 PBP - Page Size Register +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + + +//2 TRXFF_BNDY + + +//2 LLT_INIT +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +//2 BB_ACCESS_CTRL +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) +//#define BB_ADDR_MASK 0xFFF +//#define _BB_ADDR(x) ((x) & BB_ADDR_MASK) + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +//2 RQPN +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) // NOTE: in RQPN_NPQ register + + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + + +//2 TDECTRL +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +//2 TDECTL +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK +#define DROP_DATA_EN BIT(9) + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +//2 FWHW_TXQ_CTRL +#define EN_AMPDU_RTY_NEW BIT(7) + +//2 INIRTSMCS_SEL +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + + +//2 SPEC SIFS +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + + +//2 RRSR + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + + +//2 ARFR +#define USE_SHORT_G1 BIT(20) + +//2 AGGLEN_LMT_L +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + + +//2 RL +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + + +//2 DARFRC +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +// NOTE: shift starting from address (DARFRC + 4) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + + +//2 RARFRC +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +// NOTE: shift starting from address (RARFRC + 4) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + + + + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + + + +//2 EDCA setting +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +//2 EDCA_VO_PARAM +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) (((x) & 0xF))<< 8) + + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + + +//2 SIFS_CCK +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); + + +//2 SIFS_OFDM +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); + + +//2 TBTT PROHIBIT +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + + +//2 REG_RD_CTRL +#define DIS_EDCA_CNT_DWN BIT(11) + + +//2 BCN_CTRL +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) +// The same function but different bit field. +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +//2 ACMHWCTRL +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +//2 APSD_CTRL +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + + +//2 BWOPMODE +#define BW_20MHZ BIT(2) +//#define BW_OPMODE_20MHZ BIT(2) // For compability + + +#define RATE_BITMAP_ALL 0xFFFFF + +// Only use CCK 1M rate for ACK +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 +#define RATE_RRSR_WITHOUT_CCK 0xFFFF0 + +//2 TCR +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + + + +//2 RCR +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +//2 RX_PKT_LIMIT + +//2 RX_DLK_TIME + +//2 MBIDCAMCFG + + + +//2 AMPDU_MIN_SPACE +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + + +//2 RXERR_RPT +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + + +//2 SECCFG +#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key +#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key +#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption +#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption +#define SCR_SKByA2 BIT(4) //Search kEY BY A2 +#define SCR_NoSKMC BIT(5) //No Key Search Multicast +#define SCR_TXBCUSEDK BIT(6) // Force Tx Broadcast packets Use Default Key +#define SCR_RXBCUSEDK BIT(7) // Force Rx Broadcast packets Use Default Key + +//vivi added for new cam search flow, 20091028 +#ifdef HW_EN_DE_CRYPTION_FOR_NEW_CAM_SEARCH_FLOW +#define SCR_TxUseBroadcastDK BIT6 //Force Tx Use Broadcast Default Key +#define SCR_RxUseBroadcastDK BIT7 //Force Rx Use Broadcast Default Key +#endif + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- + +//2 USB Information (0xFE17) +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +//2 Special Option +#define USB_AGG_EN BIT(3) + + +//2REG_C2HEVT_CLEAR +#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message +#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver. + +//2 8192D PartNo. +#define PARTNO_92D_NIC (BIT7|BIT6) +#define PARTNO_92D_NIC_REMARK (BIT5|BIT4) +#define PARTNO_SINGLE_BAND_VS BIT3 +#define PARTNO_SINGLE_BAND_VS_REMARK BIT1 +#define PARTNO_CONCURRENT_BAND_VC (BIT3|BIT2) +#define PARTNO_CONCURRENT_BAND_VC_REMARK (BIT1|BIT0) +//======================================================== +// General definitions +//======================================================== + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC 127 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 1000 + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A +// GPIO BIT +#define HAL_8192C_HW_GPIO_WPS_BIT BIT2 + + +#include "basic_types.h" + +#endif + diff --git a/rtl8192cu-fixes/include/rtl8192d_xmit.h b/rtl8192cu-fixes/include/rtl8192d_xmit.h new file mode 100755 index 00000000..d01fb4a7 --- /dev/null +++ b/rtl8192cu-fixes/include/rtl8192d_xmit.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * 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 _RTL8192D_XMIT_H_ +#define _RTL8192D_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 + +//Because we open EM for normal case, we just always insert 2*8 bytes.by wl +#define USB_92D_DUMMY_OFFSET 2 +#define USB_92D_DUMMY_LENGTH (USB_92D_DUMMY_OFFSET * PACKET_OFFSET_SZ) +#define USB_HWDESC_HEADER_LEN (TXDESC_SIZE + USB_92D_DUMMY_LENGTH) + +//For 92D early mode +#define SET_EARLYMODE_PKTNUM(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 3, __Value) +#define SET_EARLYMODE_LEN0(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 12, __Value) +#define SET_EARLYMODE_LEN1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 16, 12, __Value) +#define SET_EARLYMODE_LEN2_1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 28, 4, __Value) +#define SET_EARLYMODE_LEN2_2(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 8, __Value) +#define SET_EARLYMODE_LEN3(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 8, 12, __Value) +#define SET_EARLYMODE_LEN4(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 20, 12, __Value) + +/* Copy from rtl8192c */ +struct txrpt_ccx_8192d { + /* offset 0 */ + u8 retry_cnt:6; + u8 rsvd_0:2; + + /* offset 1 */ + u8 rts_retry_cnt:6; + u8 rsvd_1:2; + + /* offset 2 */ + u8 ccx_qtime0; + u8 ccx_qtime1; + + /* offset 4 */ + u8 missed_pkt_num:5; + u8 rsvd_4:3; + + /* offset 5 */ + u8 mac_id:5; + u8 des1_fragssn:3; + + /* offset 6 */ + u8 rpt_pkt_num:5; + u8 pkt_drop:1; + u8 lifetime_over:1; + u8 retry_over:1; + + /* offset 7*/ + u8 edca_tx_queue:4; + u8 rsvd_7:1; + u8 bmc:1; + u8 pkt_ok:1; + u8 int_ccx:1; +}; + +#define txrpt_ccx_qtime_8192d(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8)) + +#ifdef CONFIG_XMIT_ACK +void dump_txrpt_ccx_8192d(void *buf); +void handle_txrpt_ccx_8192d(_adapter *adapter, void *buf); +#else +#define dump_txrpt_ccx_8192d(buf) do {} while(0) +#define handle_txrpt_ccx_8192d(adapter, buf) do {} while(0) +#endif + +#ifdef CONFIG_USB_HCI + +#ifdef CONFIG_USB_TX_AGGREGATION +#define MAX_TX_AGG_PACKET_NUMBER 0xFF +#endif + +s32 rtl8192du_init_xmit_priv(_adapter * padapter); + +void rtl8192du_free_xmit_priv(_adapter * padapter); + +void rtl8192du_cal_txdesc_chksum(struct tx_desc *ptxdesc); + +s32 rtl8192du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +s32 rtl8192du_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtl8192du_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); + +s32 rtl8192du_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtl8192du_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8192de_init_xmit_priv(_adapter * padapter); +void rtl8192de_free_xmit_priv(_adapter * padapter); + +s32 rtl8192de_enqueue_xmitbuf(struct rtw_tx_ring *ring, struct xmit_buf *pxmitbuf); +struct xmit_buf *rtl8192de_dequeue_xmitbuf(struct rtw_tx_ring *ring); + +void rtl8192de_xmitframe_resume(_adapter *padapter); + +s32 rtl8192de_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtl8192de_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); + +s32 rtl8192de_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtl8192de_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#endif + + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_android.h b/rtl8192cu-fixes/include/rtw_android.h new file mode 100755 index 00000000..f9214c2d --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_android.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * + * 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 __RTW_ANDROID_H__ +#define __RTW_ANDROID_H__ + +#include +#include + +enum ANDROID_WIFI_CMD { + ANDROID_WIFI_CMD_START, + ANDROID_WIFI_CMD_STOP, + ANDROID_WIFI_CMD_SCAN_ACTIVE, + ANDROID_WIFI_CMD_SCAN_PASSIVE, + ANDROID_WIFI_CMD_RSSI, + ANDROID_WIFI_CMD_LINKSPEED, + ANDROID_WIFI_CMD_RXFILTER_START, + ANDROID_WIFI_CMD_RXFILTER_STOP, + ANDROID_WIFI_CMD_RXFILTER_ADD, + ANDROID_WIFI_CMD_RXFILTER_REMOVE, + ANDROID_WIFI_CMD_BTCOEXSCAN_START, + ANDROID_WIFI_CMD_BTCOEXSCAN_STOP, + ANDROID_WIFI_CMD_BTCOEXMODE, + ANDROID_WIFI_CMD_SETSUSPENDOPT, + ANDROID_WIFI_CMD_P2P_DEV_ADDR, + ANDROID_WIFI_CMD_SETFWPATH, + ANDROID_WIFI_CMD_SETBAND, + ANDROID_WIFI_CMD_GETBAND, + ANDROID_WIFI_CMD_COUNTRY, + ANDROID_WIFI_CMD_P2P_SET_NOA, + ANDROID_WIFI_CMD_P2P_GET_NOA, + ANDROID_WIFI_CMD_P2P_SET_PS, + ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE, +#ifdef PNO_SUPPORT + ANDROID_WIFI_CMD_PNOSSIDCLR_SET, + ANDROID_WIFI_CMD_PNOSETUP_SET, + ANDROID_WIFI_CMD_PNOENABLE_SET, + ANDROID_WIFI_CMD_PNODEBUG_SET, +#endif + + ANDROID_WIFI_CMD_MACADDR, + + ANDROID_WIFI_CMD_BLOCK, + + ANDROID_WIFI_CMD_WFD_ENABLE, + ANDROID_WIFI_CMD_WFD_DISABLE, + + ANDROID_WIFI_CMD_WFD_SET_TCPPORT, + ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT, + ANDROID_WIFI_CMD_WFD_SET_DEVTYPE, + + ANDROID_WIFI_CMD_MAX +}; + +int rtw_android_cmdstr_to_num(char *cmdstr); +int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); + +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) +int rtw_android_wifictrl_func_add(void); +void rtw_android_wifictrl_func_del(void); +void* wl_android_prealloc(int section, unsigned long size); + +int wifi_get_irq_number(unsigned long *irq_flags_ptr); +int wifi_set_power(int on, unsigned long msec); +int wifi_get_mac_addr(unsigned char *buf); +void *wifi_get_country_code(char *ccode); +#else +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) */ + +#endif //__RTW_ANDROID_H__ + diff --git a/rtl8192cu-fixes/include/rtw_ap.h b/rtl8192cu-fixes/include/rtw_ap.h new file mode 100755 index 00000000..66085c37 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ap.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_AP_H_ +#define __RTW_AP_H_ + +#include +#include +#include + + +#ifdef CONFIG_AP_MODE + +//external function +extern void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta); +extern void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta); + + +void init_mlme_ap_info(_adapter *padapter); +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 expire_timeout_chk(_adapter *padapter); +void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta); +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len); +void rtw_ap_restore_network(_adapter *padapter); +void rtw_set_macaddr_acl(_adapter *padapter, int mode); +int rtw_acl_add_sta(_adapter *padapter, u8 *addr); +int rtw_acl_remove_sta(_adapter *padapter, u8 *addr); + +#ifdef CONFIG_NATIVEAP_MLME +void associated_clients_update(_adapter *padapter, u8 updated); +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); +void sta_info_update(_adapter *padapter, struct sta_info *psta); +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason); +int rtw_sta_flush(_adapter *padapter); +int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset); +void start_ap_mode(_adapter *padapter); +void stop_ap_mode(_adapter *padapter); +#endif +#endif //end of CONFIG_AP_MODE + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_br_ext.h b/rtl8192cu-fixes/include/rtw_br_ext.h new file mode 100755 index 00000000..9da3fddc --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_br_ext.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 _RTW_BR_EXT_H_ +#define _RTW_BR_EXT_H_ + +#if 1 // rtw_wifi_driver +#define CL_IPV6_PASS 1 +#define MACADDRLEN 6 +#define _DEBUG_ERR printk +#define _DEBUG_INFO //printk +#define DEBUG_WARN printk +#define DEBUG_INFO //printk +#define DEBUG_ERR printk +//#define GET_MY_HWADDR ((GET_MIB(priv))->dot11OperationEntry.hwaddr) +#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr) +#endif // rtw_wifi_driver + +#define NAT25_HASH_BITS 4 +#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS) +#define NAT25_AGEING_TIME 300 + +#ifdef CL_IPV6_PASS +#define MAX_NETWORK_ADDR_LEN 17 +#else +#define MAX_NETWORK_ADDR_LEN 11 +#endif + +struct nat25_network_db_entry +{ + struct nat25_network_db_entry *next_hash; + struct nat25_network_db_entry **pprev_hash; + atomic_t use_count; + unsigned char macAddr[6]; + unsigned long ageing_timer; + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; +}; + +enum NAT25_METHOD { + NAT25_MIN, + NAT25_CHECK, + NAT25_INSERT, + NAT25_LOOKUP, + NAT25_PARSE, + NAT25_MAX +}; + +struct br_ext_info { + unsigned int nat25_disable; + unsigned int macclone_enable; + unsigned int dhcp_bcst_disable; + int addPPPoETag; // 1: Add PPPoE relay-SID, 0: disable + unsigned char nat25_dmzMac[MACADDRLEN]; + unsigned int nat25sc_disable; +}; + +void nat25_db_cleanup(_adapter *priv); + +#endif // _RTW_BR_EXT_H_ + diff --git a/rtl8192cu-fixes/include/rtw_byteorder.h b/rtl8192cu-fixes/include/rtw_byteorder.h new file mode 100755 index 00000000..0f06b7ac --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_byteorder.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * 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 _RTL871X_BYTEORDER_H_ +#define _RTL871X_BYTEORDER_H_ + +#include + +#if defined (CONFIG_LITTLE_ENDIAN) && defined (CONFIG_BIG_ENDIAN) +#error "Shall be CONFIG_LITTLE_ENDIAN or CONFIG_BIG_ENDIAN, but not both!\n" +#endif + +#if defined (CONFIG_LITTLE_ENDIAN) +#ifndef CONFIG_PLATFORM_MSTAR389 +# include +#endif +#elif defined (CONFIG_BIG_ENDIAN) +# include +#else +# error "Must be LITTLE/BIG Endian Host" +#endif + +#endif /* _RTL871X_BYTEORDER_H_ */ + diff --git a/rtl8192cu-fixes/include/rtw_cmd.h b/rtl8192cu-fixes/include/rtw_cmd.h new file mode 100755 index 00000000..ab115c5f --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_cmd.h @@ -0,0 +1,1167 @@ +/****************************************************************************** + * + * 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 __RTW_CMD_H_ +#define __RTW_CMD_H_ + +#include +#include +#include +#include + +#define C2H_MEM_SZ (16*1024) + +#ifndef CONFIG_RTL8711FW + + #include + #include // + + + #define FREE_CMDOBJ_SZ 128 + + #define MAX_CMDSZ 1024 + #define MAX_RSPSZ 512 + #define MAX_EVTSZ 1024 + +#ifdef PLATFORM_OS_CE + #define CMDBUFF_ALIGN_SZ 4 +#else + #define CMDBUFF_ALIGN_SZ 512 +#endif + + struct cmd_obj { + _adapter *padapter; + u16 cmdcode; + u8 res; + u8 *parmbuf; + u32 cmdsz; + u8 *rsp; + u32 rspsz; + //_sema cmd_sem; + _list list; + }; + + struct cmd_priv { + _sema cmd_queue_sema; + //_sema cmd_done_sema; + _sema terminate_cmdthread_sema; + _queue cmd_queue; + u8 cmd_seq; + u8 *cmd_buf; //shall be non-paged, and 4 bytes aligned + u8 *cmd_allocated_buf; + u8 *rsp_buf; //shall be non-paged, and 4 bytes aligned + u8 *rsp_allocated_buf; + u32 cmd_issued_cnt; + u32 cmd_done_cnt; + u32 rsp_cnt; + u8 cmdthd_running; + u8 stop_req; + _adapter *padapter; + }; + +#ifdef CONFIG_EVENT_THREAD_MODE + struct evt_obj { + u16 evtcode; + u8 res; + u8 *parmbuf; + u32 evtsz; + _list list; + }; +#endif + + struct evt_priv { +#ifdef CONFIG_EVENT_THREAD_MODE + _sema evt_notify; + _sema terminate_evtthread_sema; + _queue evt_queue; +#endif + +//#define CONFIG_C2H_WK +#ifdef CONFIG_C2H_WK + _workitem c2h_wk; + bool c2h_wk_alive; + struct rtw_cbuf *c2h_queue; + #define C2H_QUEUE_MAX_LEN 10 +#endif + +#ifdef CONFIG_H2CLBK + _sema lbkevt_done; + u8 lbkevt_limit; + u8 lbkevt_num; + u8 *cmdevt_parm; +#endif + ATOMIC_T event_seq; + u8 *evt_buf; //shall be non-paged, and 4 bytes aligned + u8 *evt_allocated_buf; + u32 evt_done_cnt; +#ifdef CONFIG_SDIO_HCI + u8 *c2h_mem; + u8 *allocated_c2h_mem; +#ifdef PLATFORM_OS_XP + PMDL pc2h_mdl; +#endif +#endif + + }; + +#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ +do {\ + _rtw_init_listhead(&pcmd->list);\ + pcmd->cmdcode = code;\ + pcmd->parmbuf = (u8 *)(pparm);\ + pcmd->cmdsz = sizeof (*pparm);\ + pcmd->rsp = NULL;\ + pcmd->rspsz = 0;\ +} while(0) + +struct c2h_evt_hdr { + u8 id:4; + u8 plen:4; + u8 seq; + u8 payload[0]; +}; + +#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen) + +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); + +#ifdef CONFIG_EVENT_THREAD_MODE +extern u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj); +extern struct evt_obj *rtw_dequeue_evt(_queue *queue); +extern void rtw_free_evt_obj(struct evt_obj *pcmd); +#endif + +void rtw_stop_cmd_thread(_adapter *adapter); +thread_return rtw_cmd_thread(thread_context context); + +extern u32 rtw_init_cmd_priv (struct cmd_priv *pcmdpriv); +extern void rtw_free_cmd_priv (struct cmd_priv *pcmdpriv); + +extern u32 rtw_init_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_free_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); +extern void rtw_evt_notify_isr(struct evt_priv *pevtpriv); +#ifdef CONFIG_P2P +u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType ); +#endif //CONFIG_P2P + +#else + #include +#endif /* CONFIG_RTL8711FW */ + +enum rtw_drvextra_cmd_id +{ + NONE_WK_CID, + DYNAMIC_CHK_WK_CID, + DM_CTRL_WK_CID, + PBC_POLLING_WK_CID, + POWER_SAVING_CTRL_WK_CID,//IPS,AUTOSuspend + LPS_CTRL_WK_CID, + ANT_SELECT_WK_CID, + P2P_PS_WK_CID, + P2P_PROTO_WK_CID, + CHECK_HIQ_WK_CID,//for softap mode, check hi queue if empty + INTEl_WIDI_WK_CID, + C2H_WK_CID, + RESET_SECURITYPRIV, // add for CONFIG_IEEE80211W, none 11w also can use + FREE_ASSOC_RESOURCES, // add for CONFIG_IEEE80211W, none 11w also can use + MAX_WK_CID +}; + +enum LPS_CTRL_TYPE +{ + LPS_CTRL_SCAN=0, + LPS_CTRL_JOINBSS=1, + LPS_CTRL_CONNECT=2, + LPS_CTRL_DISCONNECT=3, + LPS_CTRL_SPECIAL_PACKET=4, +}; + +enum RFINTFS { + SWSI, + HWSI, + HWPI, +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To enter USB suspend mode + +Command Mode + +*/ +struct usb_suspend_parm { + u32 action;// 1: sleep, 0:resume +}; + +/* +Caller Mode: Infra, Ad-HoC + +Notes: To join a known BSS. + +Command-Event Mode + +*/ + +/* +Caller Mode: Infra, Ad-Hoc + +Notes: To join the specified bss + +Command Event Mode + +*/ +struct joinbss_parm { + WLAN_BSSID_EX network; +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To disconnect the current associated BSS + +Command Mode + +*/ +struct disconnect_parm { + u32 deauth_timeout_ms; +}; + +/* +Caller Mode: AP, Ad-HoC(M) + +Notes: To create a BSS + +Command Mode +*/ +struct createbss_parm { + WLAN_BSSID_EX network; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To set the NIC mode of RTL8711 + +Command Mode + +The definition of mode: + +#define IW_MODE_AUTO 0 // Let the driver decides which AP to join +#define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients) +#define IW_MODE_INFRA 2 // Multi cell network, roaming, .. +#define IW_MODE_MASTER 3 // Synchronisation master or Access Point +#define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder) +#define IW_MODE_SECOND 5 // Secondary master/repeater (backup) +#define IW_MODE_MONITOR 6 // Passive monitor (listen only) + +*/ +struct setopmode_parm { + u8 mode; + u8 rsvd[3]; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To ask RTL8711 performing site-survey + +Command-Event Mode + +*/ + +#define RTW_SSID_SCAN_AMOUNT 9 // for WEXT_CSCAN_AMOUNT 9 +#define RTW_CHANNEL_SCAN_AMOUNT (14+37) +struct sitesurvey_parm { + sint scan_mode; //active: 1, passive: 0 + /* sint bsslimit; // 1 ~ 48 */ + u8 ssid_num; + u8 ch_num; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; +}; + +/* +Caller Mode: Any + +Notes: To set the auth type of RTL8711. open/shared/802.1x + +Command Mode + +*/ +struct setauth_parm { + u8 mode; //0: legacy open, 1: legacy shared 2: 802.1x + u8 _1x; //0: PSK, 1: TLS + u8 rsvd[2]; +}; + +/* +Caller Mode: Infra + +a. algorithm: wep40, wep104, tkip & aes +b. keytype: grp key/unicast key +c. key contents + +when shared key ==> keyid is the camid +when 802.1x ==> keyid [0:1] ==> grp key +when 802.1x ==> keyid > 2 ==> unicast key + +*/ +struct setkey_parm { + u8 algorithm; // encryption algorithm, could be none, wep40, TKIP, CCMP, wep104 + u8 keyid; + u8 grpkey; // 1: this is the grpkey for 802.1x. 0: this is the unicast key for 802.1x + u8 set_tx; // 1: main tx key for wep. 0: other key. + u8 key[16]; // this could be 40 or 104 +}; + +/* +When in AP or Ad-Hoc mode, this is used to +allocate an sw/hw entry for a newly associated sta. + +Command + +when shared key ==> algorithm/keyid + +*/ +struct set_stakey_parm { + u8 addr[ETH_ALEN]; + u8 algorithm; + u8 id;// currently for erasing cam entry if algorithm == _NO_PRIVACY_ + u8 key[16]; +}; + +struct set_stakey_rsp { + u8 addr[ETH_ALEN]; + u8 keyid; + u8 rsvd; +}; + +/* +Caller Ad-Hoc/AP + +Command -Rsp(AID == CAMID) mode + +This is to force fw to add an sta_data entry per driver's request. + +FW will write an cam entry associated with it. + +*/ +struct set_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +struct set_assocsta_rsp { + u8 cam_id; + u8 rsvd[3]; +}; + +/* + Caller Ad-Hoc/AP + + Command mode + + This is to force fw to del an sta_data entry per driver's request + + FW will invalidate the cam entry associated with it. + +*/ +struct del_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +/* +Caller Mode: AP/Ad-HoC(M) + +Notes: To notify fw that given staid has changed its power state + +Command Mode + +*/ +struct setstapwrstate_parm { + u8 staid; + u8 status; + u8 hwaddr[6]; +}; + +/* +Caller Mode: Any + +Notes: To setup the basic rate of RTL8711 + +Command Mode + +*/ +struct setbasicrate_parm { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To read the current basic rate + +Command-Rsp Mode + +*/ +struct getbasicrate_parm { + u32 rsvd; +}; + +struct getbasicrate_rsp { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To setup the data rate of RTL8711 + +Command Mode + +*/ +struct setdatarate_parm { +#ifdef MP_FIRMWARE_OFFLOAD + u32 curr_rateidx; +#else + u8 mac_id; + u8 datarates[NumRates]; +#endif +}; + +/* +Caller Mode: Any + +Notes: To read the current data rate + +Command-Rsp Mode + +*/ +struct getdatarate_parm { + u32 rsvd; + +}; +struct getdatarate_rsp { + u8 datarates[NumRates]; +}; + + +/* +Caller Mode: Any +AP: AP can use the info for the contents of beacon frame +Infra: STA can use the info when sitesurveying +Ad-HoC(M): Like AP +Ad-HoC(C): Like STA + + +Notes: To set the phy capability of the NIC + +Command Mode + +*/ + +struct setphyinfo_parm { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +struct getphyinfo_parm { + u32 rsvd; +}; + +struct getphyinfo_rsp { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +/* +Caller Mode: Any + +Notes: To set the channel/modem/band +This command will be used when channel/modem/band is changed. + +Command Mode + +*/ +struct setphy_parm { + u8 rfchannel; + u8 modem; +}; + +/* +Caller Mode: Any + +Notes: To get the current setting of channel/modem/band + +Command-Rsp Mode + +*/ +struct getphy_parm { + u32 rsvd; + +}; +struct getphy_rsp { + u8 rfchannel; + u8 modem; +}; + +struct readBB_parm { + u8 offset; +}; +struct readBB_rsp { + u8 value; +}; + +struct readTSSI_parm { + u8 offset; +}; +struct readTSSI_rsp { + u8 value; +}; + +struct writeBB_parm { + u8 offset; + u8 value; +}; + +struct readRF_parm { + u8 offset; +}; +struct readRF_rsp { + u32 value; +}; + +struct writeRF_parm { + u32 offset; + u32 value; +}; + +struct getrfintfs_parm { + u8 rfintfs; +}; + + +struct Tx_Beacon_param +{ + WLAN_BSSID_EX network; +}; + +/* + Notes: This command is used for H2C/C2H loopback testing + + mac[0] == 0 + ==> CMD mode, return H2C_SUCCESS. + The following condition must be ture under CMD mode + mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; + s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; + s2 == (b1 << 8 | b0); + + mac[0] == 1 + ==> CMD_RSP mode, return H2C_SUCCESS_RSP + + The rsp layout shall be: + rsp: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = mac[3]; + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = s1; + s1 = swap16(s0); + w0 = swap32(w1); + b0 = b1 + s2 = s0 + s1 + b1 = b0 + w1 = w0 + + mac[0] == 2 + ==> CMD_EVENT mode, return H2C_SUCCESS + The event layout shall be: + event: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = event's sequence number, starting from 1 to parm's marc[3] + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = swap16(s0) - event.mac[2]; + s1 = s1 + event.mac[2]; + w0 = swap32(w0); + b0 = b1 + s2 = s0 + event.mac[2] + b1 = b0 + w1 = swap32(w1) - event.mac[2]; + + parm->mac[3] is the total event counts that host requested. + + + event will be the same with the cmd's param. + +*/ + +#ifdef CONFIG_H2CLBK + +struct seth2clbk_parm { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +struct geth2clbk_parm { + u32 rsv; +}; + +struct geth2clbk_rsp { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +#endif /* CONFIG_H2CLBK */ + +// CMD param Formart for driver extra cmd handler +struct drvextra_cmd_parm { + int ec_id; //extra cmd id + int type_size; // Can use this field as the type id or command size + unsigned char *pbuf; +}; + +/*------------------- Below are used for RF/BB tunning ---------------------*/ + +struct setantenna_parm { + u8 tx_antset; + u8 rx_antset; + u8 tx_antenna; + u8 rx_antenna; +}; + +struct enrateadaptive_parm { + u32 en; +}; + +struct settxagctbl_parm { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct gettxagctbl_parm { + u32 rsvd; +}; +struct gettxagctbl_rsp { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct setagcctrl_parm { + u32 agcctrl; // 0: pure hw, 1: fw +}; + + +struct setssup_parm { + u32 ss_ForceUp[MAX_RATES_LENGTH]; +}; + +struct getssup_parm { + u32 rsvd; +}; +struct getssup_rsp { + u8 ss_ForceUp[MAX_RATES_LENGTH]; +}; + + +struct setssdlevel_parm { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct getssdlevel_parm { + u32 rsvd; +}; +struct getssdlevel_rsp { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct setssulevel_parm { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + +struct getssulevel_parm { + u32 rsvd; +}; +struct getssulevel_rsp { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + + +struct setcountjudge_parm { + u8 count_judge[MAX_RATES_LENGTH]; +}; + +struct getcountjudge_parm { + u32 rsvd; +}; +struct getcountjudge_rsp { + u8 count_judge[MAX_RATES_LENGTH]; +}; + + +struct setratable_parm { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + +struct getratable_parm { + uint rsvd; +}; +struct getratable_rsp { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + + +//to get TX,RX retry count +struct gettxretrycnt_parm{ + unsigned int rsvd; +}; +struct gettxretrycnt_rsp{ + unsigned long tx_retrycnt; +}; + +struct getrxretrycnt_parm{ + unsigned int rsvd; +}; +struct getrxretrycnt_rsp{ + unsigned long rx_retrycnt; +}; + +//to get BCNOK,BCNERR count +struct getbcnokcnt_parm{ + unsigned int rsvd; +}; +struct getbcnokcnt_rsp{ + unsigned long bcnokcnt; +}; + +struct getbcnerrcnt_parm{ + unsigned int rsvd; +}; +struct getbcnerrcnt_rsp{ + unsigned long bcnerrcnt; +}; + +// to get current TX power level +struct getcurtxpwrlevel_parm{ + unsigned int rsvd; +}; +struct getcurtxpwrlevel_rsp{ + unsigned short tx_power; +}; + +struct setprobereqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocreqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setproberspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocrspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + + +struct addBaReq_parm +{ + unsigned int tid; + u8 addr[ETH_ALEN]; +}; + +/*H2C Handler index: 46 */ +struct set_ch_parm { + u8 ch; + u8 bw; + u8 ch_offset; +}; + +#ifdef MP_FIRMWARE_OFFLOAD +/*H2C Handler index: 47 */ +struct SetTxPower_parm +{ + u8 TxPower; +}; + +/*H2C Handler index: 48 */ +struct SwitchAntenna_parm +{ + u16 antenna_tx; + u16 antenna_rx; +// R_ANTENNA_SELECT_CCK cck_txrx; + u8 cck_txrx; +}; + +/*H2C Handler index: 49 */ +struct SetCrystalCap_parm +{ + u32 curr_crystalcap; +}; + +/*H2C Handler index: 50 */ +struct SetSingleCarrierTx_parm +{ + u8 bStart; +}; + +/*H2C Handler index: 51 */ +struct SetSingleToneTx_parm +{ + u8 bStart; + u8 curr_rfpath; +}; + +/*H2C Handler index: 52 */ +struct SetCarrierSuppressionTx_parm +{ + u8 bStart; + u32 curr_rateidx; +}; + +/*H2C Handler index: 53 */ +struct SetContinuousTx_parm +{ + u8 bStart; + u8 CCK_flag; /*1:CCK 2:OFDM*/ + u32 curr_rateidx; +}; + +/*H2C Handler index: 54 */ +struct SwitchBandwidth_parm +{ + u8 curr_bandwidth; +}; + +#endif /* MP_FIRMWARE_OFFLOAD */ + +/*H2C Handler index: 59 */ +struct SetChannelPlan_param +{ + u8 channel_plan; +}; + +/*H2C Handler index: 60 */ +struct LedBlink_param +{ + PLED_871x pLed; +}; + +/*H2C Handler index: 61 */ +struct SetChannelSwitch_param +{ + u8 new_ch_no; +}; + +/*H2C Handler index: 62 */ +struct TDLSoption_param +{ + u8 addr[ETH_ALEN]; + u8 option; +}; + +#define GEN_CMD_CODE(cmd) cmd ## _CMD_ + + +/* + +Result: +0x00: success +0x01: sucess, and check Response. +0x02: cmd ignored due to duplicated sequcne number +0x03: cmd dropped due to invalid cmd code +0x04: reserved. + +*/ + +#define H2C_RSP_OFFSET 512 + +#define H2C_SUCCESS 0x00 +#define H2C_SUCCESS_RSP 0x01 +#define H2C_DUPLICATED 0x02 +#define H2C_DROPPED 0x03 +#define H2C_PARAMETERS_ERROR 0x04 +#define H2C_REJECTED 0x05 +#define H2C_CMD_OVERFLOW 0x06 +#define H2C_RESERVED 0x07 + +extern u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr); +extern u8 rtw_setstandby_cmd(_adapter *padapter, uint action); +u8 rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *ssid, int ssid_num, struct rtw_ieee80211_channel *ch, int ch_num); +extern u8 rtw_createbss_cmd(_adapter *padapter); +extern u8 rtw_createbss_cmd_ex(_adapter *padapter, unsigned char *pbss, unsigned int sz); +extern u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch); +extern u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key); +extern u8 rtw_clearstakey_cmd(_adapter *padapter, u8 *psta, u8 entry, u8 enqueue); +extern u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork); +u8 rtw_disassoc_cmd(_adapter *padapter, u32 deauth_timeout_ms, bool enqueue); +extern u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +extern u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_setbbreg_cmd(_adapter * padapter, u8 offset, u8 val); +extern u8 rtw_setrfreg_cmd(_adapter * padapter, u8 offset, u32 val); +extern u8 rtw_getbbreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_getrfreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_setrfintfs_cmd(_adapter *padapter, u8 mode); +extern u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table); +extern u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval); + +extern u8 rtw_gettssi_cmd(_adapter *padapter, u8 offset,u8 *pval); +extern u8 rtw_setfwdig_cmd(_adapter*padapter, u8 type); +extern u8 rtw_setfwra_cmd(_adapter*padapter, u8 type); + +extern u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr); +// add for CONFIG_IEEE80211W, none 11w also can use +extern u8 rtw_reset_securitypriv_cmd(_adapter*padapter); +extern u8 rtw_free_assoc_resources_cmd(_adapter *padapter); +extern u8 rtw_dynamic_chk_wk_cmd(_adapter *adapter); + +u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue); + +#ifdef CONFIG_ANTENNA_DIVERSITY +extern u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue); +#endif + +extern u8 rtw_ps_cmd(_adapter*padapter); + + +#ifdef CONFIG_AP_MODE +u8 rtw_chk_hi_queue_cmd(_adapter*padapter); +#endif + +u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue); +extern u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue); +extern u8 rtw_led_blink_cmd(_adapter*padapter, PLED_871x pLed); +extern u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no); +extern u8 rtw_tdls_cmd(_adapter*padapter, u8 *addr, u8 option); + +extern u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt); + +u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf); + +extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_createbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getbbrfreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); + +extern void rtw_setstaKey_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_setassocsta_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getrttbl_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); + + +struct _cmd_callback { + u32 cmd_code; + void (*callback)(_adapter *padapter, struct cmd_obj *cmd); +}; + +enum rtw_h2c_cmd +{ + GEN_CMD_CODE(_Read_MACREG) , /*0*/ + GEN_CMD_CODE(_Write_MACREG) , + GEN_CMD_CODE(_Read_BBREG) , + GEN_CMD_CODE(_Write_BBREG) , + GEN_CMD_CODE(_Read_RFREG) , + GEN_CMD_CODE(_Write_RFREG) , /*5*/ + GEN_CMD_CODE(_Read_EEPROM) , + GEN_CMD_CODE(_Write_EEPROM) , + GEN_CMD_CODE(_Read_EFUSE) , + GEN_CMD_CODE(_Write_EFUSE) , + + GEN_CMD_CODE(_Read_CAM) , /*10*/ + GEN_CMD_CODE(_Write_CAM) , + GEN_CMD_CODE(_setBCNITV), + GEN_CMD_CODE(_setMBIDCFG), + GEN_CMD_CODE(_JoinBss), /*14*/ + GEN_CMD_CODE(_DisConnect) , /*15*/ + GEN_CMD_CODE(_CreateBss) , + GEN_CMD_CODE(_SetOpMode) , + GEN_CMD_CODE(_SiteSurvey), /*18*/ + GEN_CMD_CODE(_SetAuth) , + + GEN_CMD_CODE(_SetKey) , /*20*/ + GEN_CMD_CODE(_SetStaKey) , + GEN_CMD_CODE(_SetAssocSta) , + GEN_CMD_CODE(_DelAssocSta) , + GEN_CMD_CODE(_SetStaPwrState) , + GEN_CMD_CODE(_SetBasicRate) , /*25*/ + GEN_CMD_CODE(_GetBasicRate) , + GEN_CMD_CODE(_SetDataRate) , + GEN_CMD_CODE(_GetDataRate) , + GEN_CMD_CODE(_SetPhyInfo) , + + GEN_CMD_CODE(_GetPhyInfo) , /*30*/ + GEN_CMD_CODE(_SetPhy) , + GEN_CMD_CODE(_GetPhy) , + GEN_CMD_CODE(_readRssi) , + GEN_CMD_CODE(_readGain) , + GEN_CMD_CODE(_SetAtim) , /*35*/ + GEN_CMD_CODE(_SetPwrMode) , + GEN_CMD_CODE(_JoinbssRpt), + GEN_CMD_CODE(_SetRaTable) , + GEN_CMD_CODE(_GetRaTable) , + + GEN_CMD_CODE(_GetCCXReport), /*40*/ + GEN_CMD_CODE(_GetDTMReport), + GEN_CMD_CODE(_GetTXRateStatistics), + GEN_CMD_CODE(_SetUsbSuspend), + GEN_CMD_CODE(_SetH2cLbk), + GEN_CMD_CODE(_AddBAReq) , /*45*/ + GEN_CMD_CODE(_SetChannel), /*46*/ + GEN_CMD_CODE(_SetTxPower), + GEN_CMD_CODE(_SwitchAntenna), + GEN_CMD_CODE(_SetCrystalCap), + GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ + + GEN_CMD_CODE(_SetSingleToneTx),/*51*/ + GEN_CMD_CODE(_SetCarrierSuppressionTx), + GEN_CMD_CODE(_SetContinuousTx), + GEN_CMD_CODE(_SwitchBandwidth), /*54*/ + GEN_CMD_CODE(_TX_Beacon), /*55*/ + + GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ + GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ + GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ + + GEN_CMD_CODE(_SetChannelPlan), /*59*/ + GEN_CMD_CODE(_LedBlink), /*60*/ + + GEN_CMD_CODE(_SetChannelSwitch), /*61*/ + GEN_CMD_CODE(_TDLS), /*62*/ + + MAX_H2CCMD +}; + +#define _GetBBReg_CMD_ _Read_BBREG_CMD_ +#define _SetBBReg_CMD_ _Write_BBREG_CMD_ +#define _GetRFReg_CMD_ _Read_RFREG_CMD_ +#define _SetRFReg_CMD_ _Write_RFREG_CMD_ + +#ifdef _RTW_CMD_C_ +struct _cmd_callback rtw_cmd_callback[] = +{ + {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ + {GEN_CMD_CODE(_Write_MACREG), NULL}, + {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Write_BBREG), NULL}, + {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ + {GEN_CMD_CODE(_Read_EEPROM), NULL}, + {GEN_CMD_CODE(_Write_EEPROM), NULL}, + {GEN_CMD_CODE(_Read_EFUSE), NULL}, + {GEN_CMD_CODE(_Write_EFUSE), NULL}, + + {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ + {GEN_CMD_CODE(_Write_CAM), NULL}, + {GEN_CMD_CODE(_setBCNITV), NULL}, + {GEN_CMD_CODE(_setMBIDCFG), NULL}, + {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ + {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ + {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, + {GEN_CMD_CODE(_SetOpMode), NULL}, + {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ + {GEN_CMD_CODE(_SetAuth), NULL}, + + {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ + {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, + {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, + {GEN_CMD_CODE(_DelAssocSta), NULL}, + {GEN_CMD_CODE(_SetStaPwrState), NULL}, + {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ + {GEN_CMD_CODE(_GetBasicRate), NULL}, + {GEN_CMD_CODE(_SetDataRate), NULL}, + {GEN_CMD_CODE(_GetDataRate), NULL}, + {GEN_CMD_CODE(_SetPhyInfo), NULL}, + + {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ + {GEN_CMD_CODE(_SetPhy), NULL}, + {GEN_CMD_CODE(_GetPhy), NULL}, + {GEN_CMD_CODE(_readRssi), NULL}, + {GEN_CMD_CODE(_readGain), NULL}, + {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ + {GEN_CMD_CODE(_SetPwrMode), NULL}, + {GEN_CMD_CODE(_JoinbssRpt), NULL}, + {GEN_CMD_CODE(_SetRaTable), NULL}, + {GEN_CMD_CODE(_GetRaTable) , NULL}, + + {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ + {GEN_CMD_CODE(_GetDTMReport), NULL}, + {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, + {GEN_CMD_CODE(_SetUsbSuspend), NULL}, + {GEN_CMD_CODE(_SetH2cLbk), NULL}, + {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ + {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ + {GEN_CMD_CODE(_SetTxPower), NULL}, + {GEN_CMD_CODE(_SwitchAntenna), NULL}, + {GEN_CMD_CODE(_SetCrystalCap), NULL}, + {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ + + {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ + {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, + {GEN_CMD_CODE(_SetContinuousTx), NULL}, + {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ + {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ + + {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ + {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ + {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ + {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ + {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ + + {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ + {GEN_CMD_CODE(_TDLS), NULL},/*62*/ +}; +#endif + +#endif // _CMD_H_ + diff --git a/rtl8192cu-fixes/include/rtw_debug.h b/rtl8192cu-fixes/include/rtw_debug.h new file mode 100755 index 00000000..44537363 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_debug.h @@ -0,0 +1,538 @@ +/****************************************************************************** + * + * 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 __RTW_DEBUG_H__ +#define __RTW_DEBUG_H__ + +#include +#include +#include + + +#define _no_debug_ 0 +#define _drv_emerg_ 1 +#define _drv_alert_ 2 +#define _drv_crit_ 3 +#define _drv_err_ 4 +#define _drv_warning_ 5 +#define _drv_notice_ 6 +#define _drv_info_ 7 +#define _drv_dump_ 8 +#define _drv_debug_ 9 +#define _drv_always_ _drv_emerg_ + +#define _module_rtl871x_xmit_c_ BIT(0) +#define _module_xmit_osdep_c_ BIT(1) +#define _module_rtl871x_recv_c_ BIT(2) +#define _module_recv_osdep_c_ BIT(3) +#define _module_rtl871x_mlme_c_ BIT(4) +#define _module_mlme_osdep_c_ BIT(5) +#define _module_rtl871x_sta_mgt_c_ BIT(6) +#define _module_rtl871x_cmd_c_ BIT(7) +#define _module_cmd_osdep_c_ BIT(8) +#define _module_rtl871x_io_c_ BIT(9) +#define _module_io_osdep_c_ BIT(10) +#define _module_os_intfs_c_ BIT(11) +#define _module_rtl871x_security_c_ BIT(12) +#define _module_rtl871x_eeprom_c_ BIT(13) +#define _module_hal_init_c_ BIT(14) +#define _module_hci_hal_init_c_ BIT(15) +#define _module_rtl871x_ioctl_c_ BIT(16) +#define _module_rtl871x_ioctl_set_c_ BIT(17) +#define _module_rtl871x_ioctl_query_c_ BIT(18) +#define _module_rtl871x_pwrctrl_c_ BIT(19) +#define _module_hci_intfs_c_ BIT(20) +#define _module_hci_ops_c_ BIT(21) +#define _module_osdep_service_c_ BIT(22) +#define _module_mp_ BIT(23) +#define _module_hci_ops_os_c_ BIT(24) +#define _module_rtl871x_ioctl_os_c BIT(25) +#define _module_rtl8712_cmd_c_ BIT(26) +//#define _module_efuse_ BIT(27) +#define _module_rtl8192c_xmit_c_ BIT(28) +#define _module_hal_xmit_c_ BIT(28) +#define _module_efuse_ BIT(29) +#define _module_rtl8712_recv_c_ BIT(30) +#define _module_rtl8712_led_c_ BIT(31) + +#undef _MODULE_DEFINE_ + +#if defined _RTW_XMIT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_ +#elif defined _XMIT_OSDEP_C_ + #define _MODULE_DEFINE_ _module_xmit_osdep_c_ +#elif defined _RTW_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl871x_recv_c_ +#elif defined _RECV_OSDEP_C_ + #define _MODULE_DEFINE_ _module_recv_osdep_c_ +#elif defined _RTW_MLME_C_ + #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_ +#elif defined _MLME_OSDEP_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MLME_EXT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTW_STA_MGT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_ +#elif defined _RTW_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_ +#elif defined _CMD_OSDEP_C_ + #define _MODULE_DEFINE_ _module_cmd_osdep_c_ +#elif defined _RTW_IO_C_ + #define _MODULE_DEFINE_ _module_rtl871x_io_c_ +#elif defined _IO_OSDEP_C_ + #define _MODULE_DEFINE_ _module_io_osdep_c_ +#elif defined _OS_INTFS_C_ + #define _MODULE_DEFINE_ _module_os_intfs_c_ +#elif defined _RTW_SECURITY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_security_c_ +#elif defined _RTW_EEPROM_C_ + #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_ +#elif defined _HAL_INTF_C_ + #define _MODULE_DEFINE_ _module_hal_init_c_ +#elif defined _HCI_HAL_INIT_C_ + #define _MODULE_DEFINE_ _module_hci_hal_init_c_ +#elif defined _RTL871X_IOCTL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_ +#elif defined _RTL871X_IOCTL_SET_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_ +#elif defined _RTL871X_IOCTL_QUERY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_query_c_ +#elif defined _RTL871X_PWRCTRL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_ +#elif defined _RTW_PWRCTRL_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _HCI_OPS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_c_ +#elif defined _SDIO_OPS_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _OSDEP_HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _OSDEP_SERVICE_C_ + #define _MODULE_DEFINE_ _module_osdep_service_c_ +#elif defined _HCI_OPS_OS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_os_c_ +#elif defined _RTL871X_IOCTL_LINUX_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c +#elif defined _RTL8712_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_ +#elif defined _RTL8192C_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8723AS_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8712_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL8192CU_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL871X_MLME_EXT_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MP_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_MP_IOCTL_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_EFUSE_C_ + #define _MODULE_DEFINE_ _module_efuse_ +#endif + +#ifdef PLATFORM_OS_CE +extern void rtl871x_cedbg(const char *fmt, ...); +#endif + +#define RT_TRACE(_Comp, _Level, Fmt) do{}while(0) +#define _func_enter_ do{}while(0) +#define _func_exit_ do{}while(0) +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) do{}while(0) + +#undef _dbgdump + +#ifdef CONFIG_DEBUG_RTL871X + +#ifndef _RTL871X_DEBUG_C_ + extern u32 GlobalDebugLevel; + extern u64 GlobalDebugComponents; +#endif + +#ifdef PLATFORM_WINDOWS + + #ifdef PLATFORM_OS_XP + + #define _dbgdump DbgPrint + + #elif defined PLATFORM_OS_CE + + #define _dbgdump rtl871x_cedbg + + #endif + +#elif defined PLATFORM_LINUX + + #define _dbgdump printk + +#elif defined PLATFORM_FREEBSD + + #define _dbgdump printf + +#endif + +#endif /* CONFIG_DEBUG_RTL871X */ + + +#if defined (_dbgdump) && defined (_MODULE_DEFINE_) + + #undef RT_TRACE + #define RT_TRACE(_Comp, _Level, Fmt)\ + do {\ + if((_Comp & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) {\ + _dbgdump("%s [0x%08x,%d]", RTL871X_MODULE_NAME, (unsigned int)_Comp, _Level);\ + _dbgdump Fmt;\ + }\ + }while(0) + +#endif + + +#if defined (_dbgdump) + + #undef _func_enter_ + #define _func_enter_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s enters at %d\n", RTL871X_MODULE_NAME, __FUNCTION__, __LINE__);\ + } \ + } while(0) + + #undef _func_exit_ + #define _func_exit_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s exits at %d\n", RTL871X_MODULE_NAME, __FUNCTION__, __LINE__); \ + } \ + } while(0) + + #undef RT_PRINT_DATA + #define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \ + if(((_Comp) & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) \ + { \ + int __i; \ + u8 *ptr = (u8 *)_HexData; \ + _dbgdump("Rtl871x: "); \ + _dbgdump(_TitleString); \ + for( __i=0; __i<(int)_HexDataLen; __i++ ) \ + { \ + _dbgdump("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \ + if (((__i + 1) % 16) == 0) _dbgdump("\n"); \ + } \ + _dbgdump("\n"); \ + } +#endif + + +#ifdef CONFIG_DEBUG_RTL819X + +#undef _dbgdump + +#ifdef PLATFORM_WINDOWS + + #ifdef PLATFORM_OS_XP + + #define _dbgdump DbgPrint + + #elif defined PLATFORM_OS_CE + + #define _dbgdump rtl871x_cedbg + + #endif + +#elif defined PLATFORM_LINUX + + #define _dbgdump printk + +#elif defined PLATFORM_FREEBSD + + #define _dbgdump printf + +#endif + +#endif /* CONFIG_DEBUG_RTL819X */ + + +#ifdef PLATFORM_WINDOWS + #define DBG_871X do {} while(0) + #define MSG_8192C do {} while(0) + #define DBG_8192C do {} while(0) + #define WRN_8192C do {} while(0) + #define ERR_8192C do {} while(0) +#endif + +#ifdef PLATFORM_LINUX + #define DBG_871X(x, ...) do {} while(0) + #define MSG_8192C(x, ...) do {} while(0) + #define DBG_8192C(x,...) do {} while(0) + #define WRN_8192C(x,...) do {} while(0) + #define ERR_8192C(x,...) do {} while(0) +#endif + +#ifdef PLATFORM_FREEBSD + #define _dbgdump printf + #define DBG_871X(x, ...) do {} while(0) + #define MSG_8192C(x, ...) do {} while(0) + #define DBG_8192C(x,...) do {} while(0) + #define WRN_8192C(x,...) do {} while(0) + #define ERR_8192C(x,...) do {} while(0) +#endif + +extern u32 GlobalDebugLevel; +#define LOG_LEVEL(level, ...)\ + do {\ + if(level <= GlobalDebugLevel) {\ + printk(__VA_ARGS__);\ + }\ + }while(0) + +#define DBG_871X_LEVEL LOG_LEVEL + +#if defined (_dbgdump) + #undef DBG_871X +// #define DBG_871X _dbgdump + #define DBG_871X(...) LOG_LEVEL(_drv_debug_ , __VA_ARGS__) + + #undef MSG_8192C +// #define MSG_8192C _dbgdump + #define MSG_8192C(...) LOG_LEVEL(_drv_info_ , __VA_ARGS__) + + #undef DBG_8192C +// #define DBG_8192C _dbgdump + #define DBG_8192C(...) LOG_LEVEL(_drv_debug_ , __VA_ARGS__) + + + #undef WRN_8192C + #define WRN_8192C _dbgdump + + #undef ERR_8192C + #define ERR_8192C _dbgdump +#endif + + +#ifdef CONFIG_PROC_DEBUG + + int proc_get_drv_version(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_log_level(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_log_level(struct file *file, const char *buffer, + unsigned long count, void *data); + +#ifdef DBG_MEM_ALLOC + int proc_get_mstat(char *page, char **start, + off_t offset, int count, + int *eof, void *data); +#endif /* DBG_MEM_ALLOC */ + + int proc_get_write_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_write_reg(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_read_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_read_reg(struct file *file, const char *buffer, + unsigned long count, void *data); + + + int proc_get_fwstate(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_sec_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mlmext_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_qos_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_ht_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_ap_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_adapter_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_trx_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump4(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + +#ifdef CONFIG_AP_MODE + + int proc_get_all_sta_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + +#endif + +#ifdef DBG_MEMORY_LEAK + int proc_get_malloc_cnt(char *page, char **start, + off_t offset, int count, + int *eof, void *data); +#endif + +#ifdef CONFIG_FIND_BEST_CHANNEL + int proc_get_best_channel(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + int proc_set_best_channel(struct file *file, const char *buffer, + unsigned long count, void *data); +#endif + + int proc_get_rx_signal(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rx_signal(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_ht_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_ht_enable(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_cbw40_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_cbw40_enable(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_ampdu_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_ampdu_enable(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_two_path_rssi(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rx_stbc(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rx_stbc(struct file *file, const char *buffer, + unsigned long count, void *data); + + + int proc_get_vid(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_pid(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rssi_disp(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rssi_disp(struct file *file, const char *buffer, + unsigned long count, void *data); + +#if defined(DBG_CONFIG_ERROR_DETECT) +int proc_get_sreset(char *page, char **start, off_t offset, int count, int *eof, void *data); +int proc_set_sreset(struct file *file, const char *buffer, unsigned long count, void *data); +#endif /* DBG_CONFIG_ERROR_DETECT */ + +#ifdef CONFIG_DM_ADAPTIVITY +int proc_get_dm_adaptivity(char *page, char **start, + off_t offset, int count, + int *eof, void *data); +int proc_set_dm_adaptivity(struct file *file, const char *buffer, + unsigned long count, void *data); +#endif /* CONFIG_DM_ADAPTIVITY */ + +#endif //CONFIG_PROC_DEBUG + +#endif //__RTW_DEBUG_H__ + diff --git a/rtl8192cu-fixes/include/rtw_eeprom.h b/rtl8192cu-fixes/include/rtw_eeprom.h new file mode 100755 index 00000000..ce834dd1 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_eeprom.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 __RTW_EEPROM_H__ +#define __RTW_EEPROM_H__ + +#include +#include +#include + +#define RTL8712_EEPROM_ID 0x8712 +#define EEPROM_MAX_SIZE 256 +#define CLOCK_RATE 50 //100us + +//- EEPROM opcodes +#define EEPROM_READ_OPCODE 06 +#define EEPROM_WRITE_OPCODE 05 +#define EEPROM_ERASE_OPCODE 07 +#define EEPROM_EWEN_OPCODE 19 // Erase/write enable +#define EEPROM_EWDS_OPCODE 16 // Erase/write disable + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +#ifdef CONFIG_SDIO_HCI +#define eeprom_cis0_sz 17 +#define eeprom_cis1_sz 50 +#endif + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_ALPHA 0x1 +#define EEPROM_CID_Senao 0x3 +#define EEPROM_CID_NetCore 0x5 +#define EEPROM_CID_CAMEO 0X8 +#define EEPROM_CID_SITECOM 0x9 +#define EEPROM_CID_COREGA 0xB +#define EEPROM_CID_EDIMAX_BELKIN 0xC +#define EEPROM_CID_SERCOMM_BELKIN 0xE +#define EEPROM_CID_CAMEO1 0xF +#define EEPROM_CID_WNC_COREGA 0x12 +#define EEPROM_CID_CLEVO 0x13 +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + +// +// Customer ID, note that: +// This variable is initiailzed through EEPROM or registry, +// however, its definition may be different with that in EEPROM for +// EEPROM size consideration. So, we have to perform proper translation between them. +// Besides, CustomerID of registry has precedence of that of EEPROM. +// defined below. 060703, by rcnjko. +// +typedef enum _RT_CUSTOMER_ID +{ + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31. + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_CHINA_MOBILE = 15, + RT_CID_819x_ALPHA = 16, + RT_CID_819x_Sitecom = 17, + RT_CID_CCX = 18, // It's set under CCX logo test and isn't demanded for CCX functions, but for test behavior like retry limit and tx report. By Bruce, 2009-02-17. + RT_CID_819x_Lenovo = 19, + RT_CID_819x_QMI = 20, + RT_CID_819x_Edimax_Belkin = 21, + RT_CID_819x_Sercomm_Belkin = 22, + RT_CID_819x_CAMEO1 = 23, + RT_CID_819x_MSI = 24, + RT_CID_819x_Acer = 25, + RT_CID_819x_AzWave_ASUS = 26, + RT_CID_819x_AzWave = 27, // For AzWave in PCIe, The ID is AzWave use and not only Asus + RT_CID_819x_HP = 28, + RT_CID_819x_WNC_COREGA = 29, + RT_CID_819x_Arcadyan_Belkin = 30, + RT_CID_819x_SAMSUNG = 31, + RT_CID_819x_CLEVO = 32, + RT_CID_819x_DELL = 33, + RT_CID_819x_PRONETS = 34, + RT_CID_819x_Edimax_ASUS = 35, + RT_CID_819x_CAMEO_NETGEAR = 36, +}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; + +struct eeprom_priv +{ + u8 bautoload_fail_flag; + //u8 bempty; + //u8 sys_config; + u8 mac_addr[6]; //PermanentAddress + //u8 config0; + u16 channel_plan; + //u8 country_string[3]; + //u8 tx_power_b[15]; + //u8 tx_power_g[15]; + //u8 tx_power_a[201]; + + u8 EepromOrEfuse; + + u8 efuse_eeprom_data[EEPROM_MAX_SIZE]; + +#ifdef CONFIG_SDIO_HCI + u8 sdio_setting; + u32 ocr; + u8 cis0[eeprom_cis0_sz]; + u8 cis1[eeprom_cis1_sz]; +#endif +}; + + +extern void eeprom_write16(_adapter *padapter, u16 reg, u16 data); +extern u16 eeprom_read16(_adapter *padapter, u16 reg); +extern void read_eeprom_content(_adapter *padapter); +extern void eeprom_read_sz(_adapter * padapter, u16 reg,u8* data, u32 sz); + +extern void read_eeprom_content_by_attrib(_adapter * padapter ); + +#ifdef PLATFORM_LINUX +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE +extern int isAdaptorInfoFileValid(void); +extern int storeAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv); +extern int retriveAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv); +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE +#endif //PLATFORM_LINUX + +#endif //__RTL871X_EEPROM_H__ diff --git a/rtl8192cu-fixes/include/rtw_efuse.h b/rtl8192cu-fixes/include/rtw_efuse.h new file mode 100755 index 00000000..224aa4f9 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_efuse.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * 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 __RTW_EFUSE_H__ +#define __RTW_EFUSE_H__ + +#include +#include + +#define EFUSE_ERROE_HANDLE 1 + +#define PG_STATE_HEADER 0x01 +#define PG_STATE_WORD_0 0x02 +#define PG_STATE_WORD_1 0x04 +#define PG_STATE_WORD_2 0x08 +#define PG_STATE_WORD_3 0x10 +#define PG_STATE_DATA 0x20 + +#define PG_SWBYTE_H 0x01 +#define PG_SWBYTE_L 0x02 + +#define PGPKT_DATA_SIZE 8 + +#define EFUSE_WIFI 0 +#define EFUSE_BT 1 + +enum _EFUSE_DEF_TYPE { + TYPE_EFUSE_MAX_SECTION = 0, + TYPE_EFUSE_REAL_CONTENT_LEN = 1, + TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, + TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, + TYPE_EFUSE_MAP_LEN = 4, + TYPE_EFUSE_PROTECT_BYTES_BANK = 5, +}; + +#define EFUSE_MAX_MAP_LEN 256 +#define EFUSE_MAX_HW_SIZE 512 +#define EFUSE_MAX_SECTION_BASE 16 + +#define EXT_HEADER(header) ((header & 0x1F ) == 0x0F) +#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) +#define GET_HDR_OFFSET_2_0(header) ( (header & 0xE0) >> 5) + +#define EFUSE_REPEAT_THRESHOLD_ 3 + +//============================================= +// The following is for BT Efuse definition +//============================================= +#define EFUSE_BT_MAX_MAP_LEN 1024 +#define EFUSE_MAX_BANK 4 +#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) +//============================================= +/*--------------------------Define Parameters-------------------------------*/ +#define EFUSE_MAX_WORD_UNIT 4 + +/*------------------------------Define structure----------------------------*/ +typedef struct PG_PKT_STRUCT_A{ + u8 offset; + u8 word_en; + u8 data[8]; + u8 word_cnts; +}PGPKT_STRUCT,*PPGPKT_STRUCT; +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +extern u8 fakeEfuseBank; +extern u32 fakeEfuseUsedBytes; +extern u8 fakeEfuseContent[]; +extern u8 fakeEfuseInitMap[]; +extern u8 fakeEfuseModifiedMap[]; + +extern u32 BTEfuseUsedBytes; +extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 BTEfuseInitMap[]; +extern u8 BTEfuseModifiedMap[]; + +extern u32 fakeBTEfuseUsedBytes; +extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 fakeBTEfuseInitMap[]; +extern u8 fakeBTEfuseModifiedMap[]; +/*------------------------Export global variable----------------------------*/ + +u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size); +u16 efuse_GetMaxSize(PADAPTER padapter); +u8 rtw_efuse_access(PADAPTER padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); + +u16 Efuse_GetCurrentSize(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +u8 Efuse_CalculateWordCnts(u8 word_en); +void ReadEFuseByte(PADAPTER Adapter, u16 _offset, u8 *pbuf, BOOLEAN bPseudoTest) ; +void EFUSE_GetEfuseDefinition(PADAPTER pAdapter, u8 efuseType, u8 type, void *pOut, BOOLEAN bPseudoTest); +u8 efuse_OneByteRead(PADAPTER pAdapter, u16 addr, u8 *data, BOOLEAN bPseudoTest); +u8 efuse_OneByteWrite(PADAPTER pAdapter, u16 addr, u8 data, BOOLEAN bPseudoTest); + +void Efuse_PowerSwitch(PADAPTER pAdapter,u8 bWrite,u8 PwrState); +int Efuse_PgPacketRead(PADAPTER pAdapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); +int Efuse_PgPacketWrite(PADAPTER pAdapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); +void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); +u8 Efuse_WordEnableDataWrite(PADAPTER pAdapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + +u8 EFUSE_Read1Byte(PADAPTER pAdapter, u16 Address); +void EFUSE_ShadowMapUpdate(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +void EFUSE_ShadowRead(PADAPTER pAdapter, u8 Type, u16 Offset, u32 *Value); + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_event.h b/rtl8192cu-fixes/include/rtw_event.h new file mode 100755 index 00000000..4299ddcf --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_event.h @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * 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 _RTW_EVENT_H_ +#define _RTW_EVENT_H_ +#include +#include + +#ifndef CONFIG_RTL8711FW +#ifdef PLATFORM_LINUX +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) +#include +#else +#include +#endif +#include +#endif +#else +#include +#endif//CONFIG_RTL8711FW + + + +#ifdef CONFIG_H2CLBK +#include +#endif + +/* +Used to report a bss has been scanned + +*/ +struct survey_event { + WLAN_BSSID_EX bss; +}; + +/* +Used to report that the requested site survey has been done. + +bss_cnt indicates the number of bss that has been reported. + + +*/ +struct surveydone_event { + unsigned int bss_cnt; + +}; + +/* +Used to report the link result of joinning the given bss + + +join_res: +-1: authentication fail +-2: association fail +> 0: TID + +*/ +struct joinbss_event { + struct wlan_network network; +}; + +/* +Used to report a given STA has joinned the created BSS. +It is used in AP/Ad-HoC(M) mode. + + +*/ +struct stassoc_event { + unsigned char macaddr[6]; + unsigned char rsvd[2]; + int cam_id; + +}; + +struct stadel_event { + unsigned char macaddr[6]; + unsigned char rsvd[2]; //for reason + int mac_id; +}; + +struct addba_event +{ + unsigned int tid; +}; + + +#ifdef CONFIG_H2CLBK +struct c2hlbk_event{ + unsigned char mac[6]; + unsigned short s0; + unsigned short s1; + unsigned int w0; + unsigned char b0; + unsigned short s2; + unsigned char b1; + unsigned int w1; +}; +#endif//CONFIG_H2CLBK + +#define GEN_EVT_CODE(event) event ## _EVT_ + + + +struct fwevent { + u32 parmsize; + void (*event_callback)(_adapter *dev, u8 *pbuf); +}; + + +#define C2HEVENT_SZ 32 + +struct event_node{ + unsigned char *node; + unsigned char evt_code; + unsigned short evt_sz; + volatile int *caller_ff_tail; + int caller_ff_sz; +}; + +struct c2hevent_queue { + volatile int head; + volatile int tail; + struct event_node nodes[C2HEVENT_SZ]; + unsigned char seq; +}; + +#define NETWORK_QUEUE_SZ 4 + +struct network_queue { + volatile int head; + volatile int tail; + WLAN_BSSID_EX networks[NETWORK_QUEUE_SZ]; +}; + + +#endif // _WLANEVENT_H_ + diff --git a/rtl8192cu-fixes/include/rtw_ht.h b/rtl8192cu-fixes/include/rtw_ht.h new file mode 100755 index 00000000..3cd904df --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ht.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * 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 _RTW_HT_H_ +#define _RTW_HT_H_ + +#include +#include +#include "wifi.h" + +struct ht_priv +{ + u32 ht_option; + u32 ampdu_enable;//for enable Tx A-MPDU + //u8 baddbareq_issued[16]; + u32 tx_amsdu_enable;//for enable Tx A-MSDU + u32 tx_amdsu_maxlen; // 1: 8k, 0:4k ; default:8k, for tx + u32 rx_ampdu_maxlen; //for rx reordering ctrl win_sz, updated when join_callback. + + u8 bwmode;// + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + + //for processing Tx A-MPDU + u8 agg_enable_bitmap; + //u8 ADDBA_retry_count; + u8 candidate_tid_bitmap; + + struct rtw_ieee80211_ht_cap ht_cap; + +}; + +#endif //_RTL871X_HT_H_ + diff --git a/rtl8192cu-fixes/include/rtw_io.h b/rtl8192cu-fixes/include/rtw_io.h new file mode 100755 index 00000000..c66845c8 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_io.h @@ -0,0 +1,504 @@ +/****************************************************************************** + * + * 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 _RTW_IO_H_ +#define _RTW_IO_H_ + +#include +#include +#include + +#ifdef PLATFORM_LINUX +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) +#include +#else +#include +#endif +#include +//#include +#include +#include + +#ifdef CONFIG_USB_HCI +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) +#include +#else +#include +#endif +#endif //CONFIG_USB_HCI + +#endif //PLATFORM_LINUX + + +#define NUM_IOREQ 8 + +#ifdef PLATFORM_WINDOWS +#define MAX_PROT_SZ 64 +#endif +#ifdef PLATFORM_LINUX +#define MAX_PROT_SZ (64-16) +#endif + +#define _IOREADY 0 +#define _IO_WAIT_COMPLETE 1 +#define _IO_WAIT_RSP 2 + +// IO COMMAND TYPE +#define _IOSZ_MASK_ (0x7F) +#define _IO_WRITE_ BIT(7) +#define _IO_FIXED_ BIT(8) +#define _IO_BURST_ BIT(9) +#define _IO_BYTE_ BIT(10) +#define _IO_HW_ BIT(11) +#define _IO_WORD_ BIT(12) +#define _IO_SYNC_ BIT(13) +#define _IO_CMDMASK_ (0x1F80) + + +/* + For prompt mode accessing, caller shall free io_req + Otherwise, io_handler will free io_req +*/ + + + +// IO STATUS TYPE +#define _IO_ERR_ BIT(2) +#define _IO_SUCCESS_ BIT(1) +#define _IO_DONE_ BIT(0) + + +#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) +#define IO_RD16 (_IO_SYNC_ | _IO_HW_) +#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) + +#define IO_RD32_ASYNC (_IO_WORD_) +#define IO_RD16_ASYNC (_IO_HW_) +#define IO_RD8_ASYNC (_IO_BYTE_) + +#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) +#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) +#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) + +#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) +#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) +#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) + +/* + + Only Sync. burst accessing is provided. + +*/ + +#define IO_WR_BURST(x) (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_)) +#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_)) + + + +//below is for the intf_option bit defition... + +#define _INTF_ASYNC_ BIT(0) //support async io + +struct intf_priv; +struct intf_hdl; +struct io_queue; + +struct _io_ops +{ + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); + + int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata); + + int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + + void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + + void (*_sync_irp_protocol_rw)(struct io_queue *pio_q); + + u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr); + + u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + + u32 (*_write_scsi)(struct intf_hdl *pintfhdl,u32 cnt, u8 *pmem); + + void (*_read_port_cancel)(struct intf_hdl *pintfhdl); + void (*_write_port_cancel)(struct intf_hdl *pintfhdl); + +}; + +struct io_req { + _list list; + u32 addr; + volatile u32 val; + u32 command; + u32 status; + u8 *pbuf; + _sema sema; + +#ifdef PLATFORM_OS_CE +#ifdef CONFIG_USB_HCI + // URB handler for rtw_write_mem + USB_TRANSFER usb_transfer_write_mem; +#endif +#endif + + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt); + u8 *cnxt; + +#ifdef PLATFORM_OS_XP + PMDL pmdl; + PIRP pirp; + +#ifdef CONFIG_SDIO_HCI + PSDBUS_REQUEST_PACKET sdrp; +#endif + +#endif + + +}; + +struct intf_hdl { + +/* + u32 intf_option; + u32 bus_status; + u32 do_flush; + u8 *adapter; + u8 *intf_dev; + struct intf_priv *pintfpriv; + u8 cnt; + void (*intf_hdl_init)(u8 *priv); + void (*intf_hdl_unload)(u8 *priv); + void (*intf_hdl_open)(u8 *priv); + void (*intf_hdl_close)(u8 *priv); + struct _io_ops io_ops; + //u8 intf_status;//moved to struct intf_priv + u16 len; + u16 done_len; +*/ + _adapter *padapter; + struct dvobj_priv *pintf_dev;// pointer to &(padapter->dvobjpriv); + + struct _io_ops io_ops; + +}; + +struct reg_protocol_rd { + +#ifdef CONFIG_LITTLE_ENDIAN + + //DW1 + u32 NumOfTrans:4; + u32 Reserved1:4; + u32 Reserved2:24; + //DW2 + u32 ByteCount:7; + u32 WriteEnable:1; //0:read, 1:write + u32 FixOrContinuous:1; //0:continuous, 1: Fix + u32 BurstMode:1; + u32 Byte1Access:1; + u32 Byte2Access:1; + u32 Byte4Access:1; + u32 Reserved3:3; + u32 Reserved4:16; + //DW3 + u32 BusAddress; + //DW4 + //u32 Value; +#else + + +//DW1 + u32 Reserved1 :4; + u32 NumOfTrans :4; + + u32 Reserved2 :24; + + //DW2 + u32 WriteEnable : 1; + u32 ByteCount :7; + + + u32 Reserved3 : 3; + u32 Byte4Access : 1; + + u32 Byte2Access : 1; + u32 Byte1Access : 1; + u32 BurstMode :1 ; + u32 FixOrContinuous : 1; + + u32 Reserved4 : 16; + + //DW3 + u32 BusAddress; + + //DW4 + //u32 Value; + +#endif + +}; + + +struct reg_protocol_wt { + + +#ifdef CONFIG_LITTLE_ENDIAN + + //DW1 + u32 NumOfTrans:4; + u32 Reserved1:4; + u32 Reserved2:24; + //DW2 + u32 ByteCount:7; + u32 WriteEnable:1; //0:read, 1:write + u32 FixOrContinuous:1; //0:continuous, 1: Fix + u32 BurstMode:1; + u32 Byte1Access:1; + u32 Byte2Access:1; + u32 Byte4Access:1; + u32 Reserved3:3; + u32 Reserved4:16; + //DW3 + u32 BusAddress; + //DW4 + u32 Value; + +#else + //DW1 + u32 Reserved1 :4; + u32 NumOfTrans :4; + + u32 Reserved2 :24; + + //DW2 + u32 WriteEnable : 1; + u32 ByteCount :7; + + u32 Reserved3 : 3; + u32 Byte4Access : 1; + + u32 Byte2Access : 1; + u32 Byte1Access : 1; + u32 BurstMode :1 ; + u32 FixOrContinuous : 1; + + u32 Reserved4 : 16; + + //DW3 + u32 BusAddress; + + //DW4 + u32 Value; + +#endif + +}; + + + +/* +Below is the data structure used by _io_handler + +*/ + +struct io_queue { + _lock lock; + _list free_ioreqs; + _list pending; //The io_req list that will be served in the single protocol read/write. + _list processing; + u8 *free_ioreqs_buf; // 4-byte aligned + u8 *pallocated_free_ioreqs_buf; + struct intf_hdl intf; +}; + +struct io_priv{ + + _adapter *padapter; + + struct intf_hdl intf; + +}; + +extern uint ioreq_flush(_adapter *adapter, struct io_queue *ioqueue); +extern void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue); +extern uint sync_ioreq_flush(_adapter *adapter, struct io_queue *ioqueue); + + +extern uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue); +extern struct io_req *alloc_ioreq(struct io_queue *pio_q); + +extern uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl); +extern void unregister_intf_hdl(struct intf_hdl *pintfhdl); + +extern void _rtw_attrib_read(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_attrib_write(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + +extern u8 _rtw_read8(_adapter *adapter, u32 addr); +extern u16 _rtw_read16(_adapter *adapter, u32 addr); +extern u32 _rtw_read32(_adapter *adapter, u32 addr); +extern void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_read_port_cancel(_adapter *adapter); + + +extern int _rtw_write8(_adapter *adapter, u32 addr, u8 val); +extern int _rtw_write16(_adapter *adapter, u32 addr, u16 val); +extern int _rtw_write32(_adapter *adapter, u32 addr, u32 val); +extern int _rtw_writeN(_adapter *adapter, u32 addr, u32 length, u8 *pdata); + +extern int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val); +extern int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val); +extern int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val); + +extern void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms); +extern void _rtw_write_port_cancel(_adapter *adapter); + +#ifdef DBG_IO +bool match_read_sniff_ranges(u16 addr, u16 len); +bool match_write_sniff_ranges(u16 addr, u16 len); + +extern u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line); +extern u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line); +extern u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line); + +extern int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line); +extern int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line); +extern int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line); +extern int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line); + +#define rtw_read8(adapter, addr) dbg_rtw_read8((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read16(adapter, addr) dbg_rtw_read16((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read32(adapter, addr) dbg_rtw_read32((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read_mem(adapter, addr, cnt, mem) _rtw_read_mem((adapter), (addr), (cnt), (mem)) +#define rtw_read_port(adapter, addr, cnt, mem) _rtw_read_port((adapter), (addr), (cnt), (mem)) +#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) + +#define rtw_write8(adapter, addr, val) dbg_rtw_write8((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_write16(adapter, addr, val) dbg_rtw_write16((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_write32(adapter, addr, val) dbg_rtw_write32((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_writeN(adapter, addr, length, data) dbg_rtw_writeN((adapter), (addr), (length), (data), __FUNCTION__, __LINE__) + +#define rtw_write8_async(adapter, addr, val) _rtw_write8_async((adapter), (addr), (val)) +#define rtw_write16_async(adapter, addr, val) _rtw_write16_async((adapter), (addr), (val)) +#define rtw_write32_async(adapter, addr, val) _rtw_write32_async((adapter), (addr), (val)) + +#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem((adapter), addr, cnt, mem) +#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port(adapter, addr, cnt, mem) +#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) +#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel(adapter) +#else //DBG_IO +#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr)) +#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr)) +#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr)) +#define rtw_read_mem(adapter, addr, cnt, mem) _rtw_read_mem((adapter), (addr), (cnt), (mem)) +#define rtw_read_port(adapter, addr, cnt, mem) _rtw_read_port((adapter), (addr), (cnt), (mem)) +#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) + +#define rtw_write8(adapter, addr, val) _rtw_write8((adapter), (addr), (val)) +#define rtw_write16(adapter, addr, val) _rtw_write16((adapter), (addr), (val)) +#define rtw_write32(adapter, addr, val) _rtw_write32((adapter), (addr), (val)) +#define rtw_writeN(adapter, addr, length, data) _rtw_writeN((adapter), (addr), (length), (data)) + +#define rtw_write8_async(adapter, addr, val) _rtw_write8_async((adapter), (addr), (val)) +#define rtw_write16_async(adapter, addr, val) _rtw_write16_async((adapter), (addr), (val)) +#define rtw_write32_async(adapter, addr, val) _rtw_write32_async((adapter), (addr), (val)) + +#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem((adapter), (addr), (cnt), (mem)) +#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port((adapter), (addr), (cnt), (mem)) +#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) +#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel((adapter)) +#endif //DBG_IO + +extern void rtw_write_scsi(_adapter *adapter, u32 cnt, u8 *pmem); + +//ioreq +extern void ioreq_read8(_adapter *adapter, u32 addr, u8 *pval); +extern void ioreq_read16(_adapter *adapter, u32 addr, u16 *pval); +extern void ioreq_read32(_adapter *adapter, u32 addr, u32 *pval); +extern void ioreq_write8(_adapter *adapter, u32 addr, u8 val); +extern void ioreq_write16(_adapter *adapter, u32 addr, u16 val); +extern void ioreq_write32(_adapter *adapter, u32 addr, u32 val); + + +extern uint async_read8(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern uint async_read16(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern uint async_read32(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); + +extern void async_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void async_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + +extern void async_write8(_adapter *adapter, u32 addr, u8 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern void async_write16(_adapter *adapter, u32 addr, u16 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern void async_write32(_adapter *adapter, u32 addr, u32 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); + +extern void async_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void async_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + + +int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops)); + + +extern uint alloc_io_queue(_adapter *adapter); +extern void free_io_queue(_adapter *adapter); +extern void async_bus_io(struct io_queue *pio_q); +extern void bus_sync_io(struct io_queue *pio_q); +extern u32 _ioreq2rwmem(struct io_queue *pio_q); +extern void dev_power_down(_adapter * Adapter, u8 bpwrup); + +/* +#define RTL_R8(reg) rtw_read8(padapter, reg) +#define RTL_R16(reg) rtw_read16(padapter, reg) +#define RTL_R32(reg) rtw_read32(padapter, reg) +#define RTL_W8(reg, val8) rtw_write8(padapter, reg, val8) +#define RTL_W16(reg, val16) rtw_write16(padapter, reg, val16) +#define RTL_W32(reg, val32) rtw_write32(padapter, reg, val32) +*/ + +/* +#define RTL_W8_ASYNC(reg, val8) rtw_write32_async(padapter, reg, val8) +#define RTL_W16_ASYNC(reg, val16) rtw_write32_async(padapter, reg, val16) +#define RTL_W32_ASYNC(reg, val32) rtw_write32_async(padapter, reg, val32) + +#define RTL_WRITE_BB(reg, val32) phy_SetUsbBBReg(padapter, reg, val32) +#define RTL_READ_BB(reg) phy_QueryUsbBBReg(padapter, reg) +*/ + +#endif //_RTL8711_IO_H_ diff --git a/rtl8192cu-fixes/include/rtw_ioctl.h b/rtl8192cu-fixes/include/rtw_ioctl.h new file mode 100755 index 00000000..c4da3019 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ioctl.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_H_ +#define _RTW_IOCTL_H_ + +#include +#include +#include + +#ifndef OID_802_11_CAPABILITY + #define OID_802_11_CAPABILITY 0x0d010122 +#endif + +#ifndef OID_802_11_PMKID + #define OID_802_11_PMKID 0x0d010123 +#endif + + +// For DDK-defined OIDs +#define OID_NDIS_SEG1 0x00010100 +#define OID_NDIS_SEG2 0x00010200 +#define OID_NDIS_SEG3 0x00020100 +#define OID_NDIS_SEG4 0x01010100 +#define OID_NDIS_SEG5 0x01020100 +#define OID_NDIS_SEG6 0x01020200 +#define OID_NDIS_SEG7 0xFD010100 +#define OID_NDIS_SEG8 0x0D010100 +#define OID_NDIS_SEG9 0x0D010200 +#define OID_NDIS_SEG10 0x0D020200 + +#define SZ_OID_NDIS_SEG1 23 +#define SZ_OID_NDIS_SEG2 3 +#define SZ_OID_NDIS_SEG3 6 +#define SZ_OID_NDIS_SEG4 6 +#define SZ_OID_NDIS_SEG5 4 +#define SZ_OID_NDIS_SEG6 8 +#define SZ_OID_NDIS_SEG7 7 +#define SZ_OID_NDIS_SEG8 36 +#define SZ_OID_NDIS_SEG9 24 +#define SZ_OID_NDIS_SEG10 19 + +// For Realtek-defined OIDs +#define OID_MP_SEG1 0xFF871100 +#define OID_MP_SEG2 0xFF818000 + +#define OID_MP_SEG3 0xFF818700 +#define OID_MP_SEG4 0xFF011100 + +#define DEBUG_OID(dbg, str) \ + if((!dbg)) \ + { \ + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_info_,("%s(%d): %s", __FUNCTION__, __LINE__, str)); \ + } + + +enum oid_type +{ + QUERY_OID, + SET_OID +}; + +struct oid_funs_node { + unsigned int oid_start; //the starting number for OID + unsigned int oid_end; //the ending number for OID + struct oid_obj_priv *node_array; + unsigned int array_sz; //the size of node_array + int query_counter; //count the number of query hits for this segment + int set_counter; //count the number of set hits for this segment +}; + +struct oid_par_priv +{ + void *adapter_context; + NDIS_OID oid; + void *information_buf; + u32 information_buf_len; + u32 *bytes_rw; + u32 *bytes_needed; + enum oid_type type_of_oid; + u32 dbg; +}; + +struct oid_obj_priv { + unsigned char dbg; // 0: without OID debug message 1: with OID debug message + NDIS_STATUS (*oidfuns)(struct oid_par_priv *poid_par_priv); +}; + +#if (defined(CONFIG_MP_INCLUDED) && defined(_RTW_MP_IOCTL_C_)) || \ + (defined(PLATFORM_WINDOWS) && defined(_RTW_IOCTL_RTL_C_)) +static NDIS_STATUS oid_null_function(struct oid_par_priv* poid_par_priv) +{ + _func_enter_; + _func_exit_; + return NDIS_STATUS_SUCCESS; +} +#endif + +#ifdef PLATFORM_WINDOWS + +int TranslateNdisPsToRtPs(IN NDIS_802_11_POWER_MODE ndisPsMode); + +//OID Handler for Segment 1 +NDIS_STATUS oid_gen_supported_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_hardware_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_in_use_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_lookahead_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_frame_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_link_speed_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_transmit_buffer_space_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_receive_buffer_space_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_transmit_block_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_receive_block_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_id_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_description_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_current_packet_filter_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_current_lookahead_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_driver_version_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_total_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_protocol_options_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_mac_options_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_connect_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_send_packets_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_driver_version_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 2 +NDIS_STATUS oid_gen_physical_medium_hdl(struct oid_par_priv* poid_par_priv); + +//OID Handler for Segment 3 +NDIS_STATUS oid_gen_xmit_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_xmit_error_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_error_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_no_buffer_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 4 +NDIS_STATUS oid_802_3_permanent_address_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_current_address_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_multicast_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_maximum_list_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_mac_options_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 5 +NDIS_STATUS oid_802_3_rcv_error_alignment_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_one_collision_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_more_collisions_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 6 +NDIS_STATUS oid_802_3_xmit_deferred_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_max_collisions_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_rcv_overrun_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_underrun_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_heartbeat_failure_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_times_crs_lost_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_late_collisions_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 7 +NDIS_STATUS oid_pnp_capabilities_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_set_power_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_query_power_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_add_wake_up_pattern_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_remove_wake_up_pattern_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_wake_up_pattern_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_enable_wake_up_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 8 +NDIS_STATUS oid_802_11_bssid_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_ssid_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_infrastructure_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_add_wep_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_remove_wep_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_disassociate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_authentication_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_privacy_filter_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_bssid_list_scan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_encryption_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_reload_defaults_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_add_key_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_remove_key_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_association_information_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_media_stream_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_capability_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_pmkid_hdl(struct oid_par_priv* poid_par_priv); + + + + + +//OID Handler for Segment 9 +NDIS_STATUS oid_802_11_network_types_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_network_type_in_use_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_tx_power_level_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rssi_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rssi_trigger_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_fragmentation_threshold_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rts_threshold_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_number_of_antennas_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rx_antenna_selected_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_tx_antenna_selected_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_supported_rates_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_desired_rates_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_configuration_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_power_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_bssid_list_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 10 +NDIS_STATUS oid_802_11_statistics_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment ED +NDIS_STATUS oid_rt_mh_vender_id_hdl(struct oid_par_priv* poid_par_priv); + +void Set_802_3_MULTICAST_LIST(ADAPTER *pAdapter, UCHAR *MCListbuf, ULONG MCListlen, BOOLEAN bAcceptAllMulticast); + +#endif// end of PLATFORM_WINDOWS + + +#if defined(PLATFORM_LINUX) && defined(CONFIG_WIRELESS_EXT) +extern struct iw_handler_def rtw_handlers_def; +#endif + +extern NDIS_STATUS drv_query_info( + IN _nic_hdl MiniportAdapterContext, + IN NDIS_OID Oid, + IN void * InformationBuffer, + IN u32 InformationBufferLength, + OUT u32* BytesWritten, + OUT u32* BytesNeeded + ); + +extern NDIS_STATUS drv_set_info( + IN _nic_hdl MiniportAdapterContext, + IN NDIS_OID Oid, + IN void * InformationBuffer, + IN u32 InformationBufferLength, + OUT u32* BytesRead, + OUT u32* BytesNeeded + ); + +#endif // #ifndef __INC_CEINFO_ + diff --git a/rtl8192cu-fixes/include/rtw_ioctl_query.h b/rtl8192cu-fixes/include/rtw_ioctl_query.h new file mode 100755 index 00000000..5b6018af --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ioctl_query.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_QUERY_H_ +#define _RTW_IOCTL_QUERY_H_ + +#include +#include + + +#ifdef PLATFORM_WINDOWS + +u8 query_802_11_capability(_adapter* padapter,u8* pucBuf,u32 * pulOutLen); +u8 query_802_11_association_information (_adapter * padapter, PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo); + +#endif + + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_ioctl_rtl.h b/rtl8192cu-fixes/include/rtw_ioctl_rtl.h new file mode 100755 index 00000000..3bff7665 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ioctl_rtl.h @@ -0,0 +1,83 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_RTL_H_ +#define _RTW_IOCTL_RTL_H_ + +#include +#include +#include + +//************** oid_rtl_seg_01_01 ************** +NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv* poid_par_priv);//84 +NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv* poid_par_priv); //8a +NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv* poid_par_priv); //8b + +NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv* poid_par_priv);//93 +NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv* poid_par_priv); + +//************** oid_rtl_seg_01_03 section start ************** +NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv* poid_par_priv); + +// oid_rtl_seg_01_11 +NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv* poid_par_priv); + +//************** oid_rtl_seg_03_00 section start ************** +NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv* poid_par_priv); + + + + +#endif diff --git a/rtl8192cu-fixes/include/rtw_ioctl_set.h b/rtl8192cu-fixes/include/rtw_ioctl_set.h new file mode 100755 index 00000000..82f98103 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_ioctl_set.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * + * 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 __RTW_IOCTL_SET_H_ +#define __RTW_IOCTL_SET_H_ + +#include +#include + + +typedef u8 NDIS_802_11_PMKID_VALUE[16]; + +typedef struct _BSSIDInfo { + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_PMKID_VALUE PMKID; +} BSSIDInfo, *PBSSIDInfo; + + +#ifdef PLATFORM_OS_XP +typedef struct _NDIS_802_11_PMKID { + u32 Length; + u32 BSSIDInfoCount; + BSSIDInfo BSSIDInfo[1]; +} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID; +#endif + + +#ifdef PLATFORM_WINDOWS +u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults); +u8 rtw_set_802_11_test(_adapter * padapter, NDIS_802_11_TEST * test); +u8 rtw_set_802_11_pmkid(_adapter *pdapter, NDIS_802_11_PMKID *pmkid); + +u8 rtw_pnp_set_power_sleep(_adapter* padapter); +u8 rtw_pnp_set_power_wakeup(_adapter* padapter); + +void rtw_pnp_resume_wk(void *context); +void rtw_pnp_sleep_wk(void * context); + +#endif + +u8 rtw_set_802_11_add_key(_adapter * padapter, NDIS_802_11_KEY * key); +u8 rtw_set_802_11_authentication_mode(_adapter *pdapter, NDIS_802_11_AUTHENTICATION_MODE authmode); +u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid); +u8 rtw_set_802_11_add_wep(_adapter * padapter, NDIS_802_11_WEP * wep); +u8 rtw_set_802_11_disassociate(_adapter * padapter); +u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +u8 rtw_set_802_11_infrastructure_mode(_adapter * padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +u8 rtw_set_802_11_remove_wep(_adapter * padapter, u32 keyindex); +u8 rtw_set_802_11_ssid(_adapter * padapter, NDIS_802_11_SSID * ssid); +u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid); +u8 rtw_set_802_11_remove_key(_adapter * padapter, NDIS_802_11_REMOVE_KEY * key); + +u8 rtw_validate_bssid(u8 *bssid); +u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid); + +u16 rtw_get_cur_max_rate(_adapter *adapter); +int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode); +int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan); +int rtw_set_country(_adapter *adapter, const char *country_code); +int rtw_set_band(_adapter *adapter, enum _BAND band); + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_iol.h b/rtl8192cu-fixes/include/rtw_iol.h new file mode 100755 index 00000000..45fa5a22 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_iol.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 __RTW_IOL_H_ +#define __RTW_IOL_H_ + +#include +#include +#include + +typedef struct _io_offload_cmd { + u8 rsvd0; + u8 cmd; + u16 address; + u32 value; +} IO_OFFLOAD_CMD, IOL_CMD; + +#define IOL_CMD_LLT 0x00 +//#define IOL_CMD_R_EFUSE 0x01 +#define IOL_CMD_WB_REG 0x02 +#define IOL_CMD_WW_REG 0x03 +#define IOL_CMD_WD_REG 0x04 +//#define IOL_CMD_W_RF 0x05 +#define IOL_CMD_DELAY_US 0x80 +#define IOL_CMD_DELAY_MS 0x81 +//#define IOL_CMD_DELAY_S 0x82 +#define IOL_CMD_END 0x83 + +/***************************************************** +CMD Address Value +(B1) (B2/B3:H/L addr) (B4:B7 : MSB:LSB) +****************************************************** +IOL_CMD_LLT - B7: PGBNDY +//IOL_CMD_R_EFUSE - - +IOL_CMD_WB_REG 0x0~0xFFFF B7 +IOL_CMD_WW_REG 0x0~0xFFFF B6~B7 +IOL_CMD_WD_REG 0x0~0xFFFF B4~B7 +//IOL_CMD_W_RF RF Reg B5~B7 +IOL_CMD_DELAY_US - B6~B7 +IOL_CMD_DELAY_MS - B6~B7 +//IOL_CMD_DELAY_S - B6~B7 +IOL_CMD_END - - +******************************************************/ + +struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter); +int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len); +int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value); +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value); +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value); +int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); +int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); +int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); +int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms); +int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms); +int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms); + +#ifdef DBG_IO +int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line); +int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line); +int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line); +#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#else +#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value) _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value)) +#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value) _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value)) +#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value) _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value)) +#endif + +bool rtw_IOL_applied(ADAPTER *adapter); + +#endif //__RTW_IOL_H_ diff --git a/rtl8192cu-fixes/include/rtw_led.h b/rtl8192cu-fixes/include/rtw_led.h new file mode 100755 index 00000000..b5365ba3 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_led.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 __RTW_LED_H_ +#define __RTW_LED_H_ + +#include +#include +#include + +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) + +typedef enum _LED_CTL_MODE{ + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, + LED_CTL_START_WPS_BOTTON = 11, //added for runtop + LED_CTL_STOP_WPS_FAIL = 12, //added for ALPHA + LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, //added for BELKIN +}LED_CTL_MODE; + + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) +//================================================================================ +// LED object. +//================================================================================ + +typedef enum _LED_STATE_871x{ + LED_UNKNOWN = 0, + RTW_LED_ON = 1, + RTW_LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_POWER_ON_BLINK = 5, + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning. + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state. + LED_BLINK_StartToBlink = 8,// Customzied for Sercomm Printer Server case + LED_BLINK_WPS = 9, // LED is blinkg during WPS communication + LED_TXRX_BLINK = 10, + LED_BLINK_WPS_STOP = 11, //for ALPHA + LED_BLINK_WPS_STOP_OVERLAP = 12, //for BELKIN +}LED_STATE_871x; + +#define IS_LED_WPS_BLINKING(_LED_871x) (((PLED_871x)_LED_871x)->CurrLedState==LED_BLINK_WPS \ + || ((PLED_871x)_LED_871x)->CurrLedState==LED_BLINK_WPS_STOP \ + || ((PLED_871x)_LED_871x)->bLedWPSBlinkInProgress) + +#define IS_LED_BLINKING(_LED_871x) (((PLED_871x)_LED_871x)->bLedWPSBlinkInProgress \ + ||((PLED_871x)_LED_871x)->bLedScanBlinkInProgress) + +typedef enum _LED_PIN_871x{ + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1 +}LED_PIN_871x; + +typedef struct _LED_871x{ + _adapter *padapter; + LED_PIN_871x LedPin; // Identify how to implement this SW led. + LED_STATE_871x CurrLedState; // Current LED state. + u8 bLedOn; // true if LED is ON, false if LED is OFF. + + u8 bSWLedCtrl; + + u8 bLedBlinkInProgress; // true if it is blinking, false o.w.. + // ALPHA, added by chiyoko, 20090106 + u8 bLedNoLinkBlinkInProgress; + u8 bLedLinkBlinkInProgress; + u8 bLedStartToLinkBlinkInProgress; + u8 bLedScanBlinkInProgress; + u8 bLedWPSBlinkInProgress; + + u32 BlinkTimes; // Number of times to toggle led state for blinking. + LED_STATE_871x BlinkingLedState; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. + + _timer BlinkTimer; // Timer object for led blinking. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)|| defined PLATFORM_FREEBSD + _workitem BlinkWorkItem; // Workitem used by BlinkTimer to manipulate H/W to blink LED. +#endif +} LED_871x, *PLED_871x; + + +//================================================================================ +// LED customization. +//================================================================================ + +typedef enum _LED_STRATEGY_871x{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. + SW_LED_MODE4, //for Edimax / Belkin + SW_LED_MODE5, //for Sercomm / Belkin + SW_LED_MODE6, //for 88CU minicard, porting from ce SW_LED_MODE7 + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) +}LED_STRATEGY_871x, *PLED_STRATEGY_871x; +#endif //CONFIG_USB_HCI + +#ifdef CONFIG_PCI_HCI +//================================================================================ +// LED object. +//================================================================================ + +typedef enum _LED_STATE_871x{ + LED_UNKNOWN = 0, + RTW_LED_ON = 1, + RTW_LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_POWER_ON_BLINK = 5, + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning. + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state. + LED_BLINK_StartToBlink = 8, + LED_BLINK_TXRX = 9, + LED_BLINK_RUNTOP = 10, // Customized for RunTop + LED_BLINK_CAMEO = 11, +}LED_STATE_871x; + +typedef enum _LED_PIN_871x{ + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}LED_PIN_871x; + +typedef struct _LED_871x{ + _adapter *padapter; + + LED_PIN_871x LedPin; // Identify how to implement this SW led. + + LED_STATE_871x CurrLedState; // Current LED state. + u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF. + + u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + u8 bLedWPSBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + + u8 bLedSlowBlinkInProgress;//added by vivi, for led new mode + u32 BlinkTimes; // Number of times to toggle led state for blinking. + LED_STATE_871x BlinkingLedState; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. + + _timer BlinkTimer; // Timer object for led blinking. + + u8 bLedLinkBlinkInProgress; + u8 bLedNoLinkBlinkInProgress; + u8 bLedScanBlinkInProgress; +} LED_871x, *PLED_871x; + + +//================================================================================ +// LED customization. +//================================================================================ + +typedef enum _LED_STRATEGY_871x{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // SW control for PCI Express + SW_LED_MODE2, // SW control for Cameo. + SW_LED_MODE3, // SW contorl for RunTop. + SW_LED_MODE4, // SW control for Netcore + SW_LED_MODE5, //added by vivi, for led new mode, DLINK + SW_LED_MODE6, //added by vivi, for led new mode, PRONET + SW_LED_MODE7, //added by chiyokolin, for Lenovo, PCI Express Minicard Spec Rev.1.2 spec + SW_LED_MODE8, //added by chiyokolin, for QMI + SW_LED_MODE9, //added by chiyokolin, for BITLAND, PCI Express Minicard Spec Rev.1.1 + SW_LED_MODE10, //added by chiyokolin, for Edimax-ASUS + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) +}LED_STRATEGY_871x, *PLED_STRATEGY_871x; + +#define LED_CM8_BLINK_INTERVAL 500 //for QMI +#endif //CONFIG_PCI_HCI + +struct led_priv{ + /* add for led controll */ + LED_871x SwLed0; + LED_871x SwLed1; + LED_STRATEGY_871x LedStrategy; + u8 bRegUseLed; + void (*LedControlHandler)(_adapter *padapter, LED_CTL_MODE LedAction); + /* add for led controll */ +}; + +#ifdef CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) \ + do { \ + if((adapter)->ledpriv.LedControlHandler) \ + (adapter)->ledpriv.LedControlHandler((adapter), (LedAction)); \ + } while(0) +#else //CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) +#endif //CONFIG_SW_LED + +extern void BlinkHandler(PLED_871x pLed); + +#endif //__RTW_LED_H_ + diff --git a/rtl8192cu-fixes/include/rtw_mlme.h b/rtl8192cu-fixes/include/rtw_mlme.h new file mode 100755 index 00000000..d9d64566 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_mlme.h @@ -0,0 +1,844 @@ +/****************************************************************************** + * + * 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 __RTW_MLME_H_ +#define __RTW_MLME_H_ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_INTEL_WIDI +#include +#endif + +#define MAX_BSS_CNT 128 +//#define MAX_JOIN_TIMEOUT 2000 +//#define MAX_JOIN_TIMEOUT 2500 +#define MAX_JOIN_TIMEOUT 6500 + +// Commented by Albert 20101105 +// Increase the scanning timeout because of increasing the SURVEY_TO value. + +#define SCANNING_TIMEOUT 8000 + +#define SCAN_INTERVAL (30) // unit:2sec, 30*2=60sec + +#ifdef PALTFORM_OS_WINCE +#define SCANQUEUE_LIFETIME 12000000 // unit:us +#else +#define SCANQUEUE_LIFETIME 20 // unit:sec +#endif + +#define WIFI_NULL_STATE 0x00000000 + +#define WIFI_ASOC_STATE 0x00000001 // Under Linked state... +#define WIFI_REASOC_STATE 0x00000002 +#define WIFI_SLEEP_STATE 0x00000004 +#define WIFI_STATION_STATE 0x00000008 + +#define WIFI_AP_STATE 0x00000010 +#define WIFI_ADHOC_STATE 0x00000020 +#define WIFI_ADHOC_MASTER_STATE 0x00000040 +#define WIFI_UNDER_LINKING 0x00000080 + +#define WIFI_UNDER_WPS 0x00000100 +//#define WIFI_UNDER_CMD 0x00000200 +//#define WIFI_UNDER_P2P 0x00000400 +#define WIFI_STA_ALIVE_CHK_STATE 0x00000400 +#define WIFI_SITE_MONITOR 0x00000800 //to indicate the station is under site surveying + +#ifdef WDS +#define WIFI_WDS 0x00001000 +#define WIFI_WDS_RX_BEACON 0x00002000 // already rx WDS AP beacon +#endif +#ifdef AUTO_CONFIG +#define WIFI_AUTOCONF 0x00004000 +#define WIFI_AUTOCONF_IND 0x00008000 +#endif + +/* +// ========== P2P Section Start =============== +#define WIFI_P2P_LISTEN_STATE 0x00010000 +#define WIFI_P2P_GROUP_FORMATION_STATE 0x00020000 +// ========== P2P Section End =============== +*/ + +//#ifdef UNDER_MPTEST +#define WIFI_MP_STATE 0x00010000 +#define WIFI_MP_CTX_BACKGROUND 0x00020000 // in continous tx background +#define WIFI_MP_CTX_ST 0x00040000 // in continous tx with single-tone +#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 // pending in continous tx background due to out of skb +#define WIFI_MP_CTX_CCK_HW 0x00100000 // in continous tx +#define WIFI_MP_CTX_CCK_CS 0x00200000 // in continous tx with carrier suppression +#define WIFI_MP_LPBK_STATE 0x00400000 +//#endif + +//#define _FW_UNDER_CMD WIFI_UNDER_CMD +#define _FW_UNDER_LINKING WIFI_UNDER_LINKING +#define _FW_LINKED WIFI_ASOC_STATE +#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR + + +enum dot11AuthAlgrthmNum { + dot11AuthAlgrthm_Open = 0, + dot11AuthAlgrthm_Shared, + dot11AuthAlgrthm_8021X, + dot11AuthAlgrthm_Auto, + dot11AuthAlgrthm_MaxNum +}; + +// Scan type including active and passive scan. +typedef enum _RT_SCAN_TYPE +{ + SCAN_PASSIVE, + SCAN_ACTIVE, + SCAN_MIX, +}RT_SCAN_TYPE, *PRT_SCAN_TYPE; + +enum DriverInterface { + DRIVER_WEXT = 1, + DRIVER_CFG80211 = 2 +}; + +enum _BAND +{ + GHZ24_50 = 0, + GHZ_50, + GHZ_24, + GHZ_MAX, +}; + +#define rtw_band_valid(band) ((band) >= GHZ24_50 && (band) < GHZ_MAX) + +enum SCAN_RESULT_TYPE +{ + SCAN_RESULT_P2P_ONLY = 0, // Will return all the P2P devices. + SCAN_RESULT_ALL = 1, // Will return all the scanned device, include AP. + SCAN_RESULT_WFD_TYPE = 2 // Will just return the correct WFD device. + // If this device is Miracast sink device, it will just return all the Miracast source devices. +}; + +/* + +there are several "locks" in mlme_priv, +since mlme_priv is a shared resource between many threads, +like ISR/Call-Back functions, the OID handlers, and even timer functions. + + +Each _queue has its own locks, already. +Other items are protected by mlme_priv.lock. + +To avoid possible dead lock, any thread trying to modifiying mlme_priv +SHALL not lock up more than one locks at a time! + +*/ + + +#define traffic_threshold 10 +#define traffic_scan_period 500 + +struct sitesurvey_ctrl { + u64 last_tx_pkts; + uint last_rx_pkts; + sint traffic_busy; + _timer sitesurvey_ctrl_timer; +}; + +typedef struct _RT_LINK_DETECT_T{ + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + u32 NumRxUnicastOkInPeriod; + BOOLEAN bBusyTraffic; + BOOLEAN bTxBusyTraffic; + BOOLEAN bRxBusyTraffic; + BOOLEAN bHigherBusyTraffic; // For interrupt migration purpose. + BOOLEAN bHigherBusyRxTraffic; // We may disable Tx interrupt according as Rx traffic. + BOOLEAN bHigherBusyTxTraffic; // We may disable Tx interrupt according as Tx traffic. +}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; + +struct profile_info { + u8 ssidlen; + u8 ssid[ WLAN_SSID_MAXLEN ]; + u8 peermac[ ETH_ALEN ]; +}; + +struct tx_invite_req_info{ + u8 token; + u8 benable; + u8 go_ssid[ WLAN_SSID_MAXLEN ]; + u8 ssidlen; + u8 go_bssid[ ETH_ALEN ]; + u8 peer_macaddr[ ETH_ALEN ]; + u8 operating_ch; // This information will be set by using the p2p_set op_ch=x + u8 peer_ch; // The listen channel for peer P2P device + +}; + +struct tx_invite_resp_info{ + u8 token; // Used to record the dialog token of p2p invitation request frame. +}; + +#ifdef CONFIG_WFD + +struct wifi_display_info{ + u16 wfd_enable; // Eanble/Disable the WFD function. + u16 rtsp_ctrlport; // TCP port number at which the this WFD device listens for RTSP messages + u16 peer_rtsp_ctrlport; // TCP port number at which the peer WFD device listens for RTSP messages + // This filed should be filled when receiving the gropu negotiation request + + u8 peer_session_avail; // WFD session is available or not for the peer wfd device. + // This variable will be set when sending the provisioning discovery request to peer WFD device. + // And this variable will be reset when it is read by using the iwpriv p2p_get wfd_sa command. + + u8 ip_address[4]; + u8 peer_ip_address[4]; + u8 wfd_pc; // WFD preferred connection + // 0 -> Prefer to use the P2P for WFD connection on peer side. + // 1 -> Prefer to use the TDLS for WFD connection on peer side. + + u8 wfd_device_type; // WFD Device Type + // 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. +}; +#endif //CONFIG_WFD + +struct tx_provdisc_req_info{ + u16 wps_config_method_request; // Used when sending the provisioning request frame + u16 peer_channel_num[2]; // The channel number which the receiver stands. + NDIS_802_11_SSID ssid; + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 peerIFAddr[ ETH_ALEN ]; // Peer interface address + u8 benable; // This provision discovery request frame is trigger to send or not +}; + +struct rx_provdisc_req_info{ //When peer device issue prov_disc_req first, we should store the following informations + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 strconfig_method_desc_of_prov_disc_req[4]; // description for the config method located in the provisioning discovery request frame. + // The UI must know this information to know which config method the remote p2p device is requiring. +}; + +struct tx_nego_req_info{ + u16 peer_channel_num[2]; // The channel number which the receiver stands. + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 benable; // This negoitation request frame is trigger to send or not +}; + +struct group_id_info{ + u8 go_device_addr[ ETH_ALEN ]; // The GO's device address of this P2P group + u8 ssid[ WLAN_SSID_MAXLEN ]; // The SSID of this P2P group +}; + +struct scan_limit_info{ + u8 scan_op_ch_only; // When this flag is set, the driver should just scan the operation channel +#ifndef P2P_OP_CHECK_SOCIAL_CH + u8 operation_ch[2]; // Store the operation channel of invitation request frame +#else + u8 operation_ch[5]; // Store additional channel 1,6,11 for Android 4.2 IOT & Nexus 4 +#endif //P2P_OP_CHECK_SOCIAL_CH +}; + +#ifdef CONFIG_IOCTL_CFG80211 +struct cfg80211_wifidirect_info{ + _timer remain_on_ch_timer; + u8 restore_channel; + struct ieee80211_channel remain_on_ch_channel; + enum nl80211_channel_type remain_on_ch_type; + u64 remain_on_ch_cookie; + bool is_ro_ch; +}; +#endif //CONFIG_IOCTL_CFG80211 + +struct wifidirect_info{ + _adapter* padapter; + _timer find_phase_timer; + _timer restore_p2p_state_timer; + + // Used to do the scanning. After confirming the peer is availalble, the driver transmits the P2P frame to peer. + _timer pre_tx_scan_timer; + _timer reset_ch_sitesurvey; + _timer reset_ch_sitesurvey2; // Just for resetting the scan limit function by using p2p nego +#ifdef CONFIG_CONCURRENT_MODE + // Used to switch the channel between legacy AP and listen state. + _timer ap_p2p_switch_timer; +#endif + struct tx_provdisc_req_info tx_prov_disc_info; + struct rx_provdisc_req_info rx_prov_disc_info; + struct tx_invite_req_info invitereq_info; + struct profile_info profileinfo[ P2P_MAX_PERSISTENT_GROUP_NUM ]; // Store the profile information of persistent group + struct tx_invite_resp_info inviteresp_info; + struct tx_nego_req_info nego_req_info; + struct group_id_info groupid_info; // Store the group id information when doing the group negotiation handshake. + struct scan_limit_info rx_invitereq_info; // Used for get the limit scan channel from the Invitation procedure + struct scan_limit_info p2p_info; // Used for get the limit scan channel from the P2P negotiation handshake +#ifdef CONFIG_WFD + struct wifi_display_info *wfd_info; +#endif + enum P2P_ROLE role; + enum P2P_STATE pre_p2p_state; + enum P2P_STATE p2p_state; + u8 device_addr[ETH_ALEN]; // The device address should be the mac address of this device. + u8 interface_addr[ETH_ALEN]; + u8 social_chan[4]; + u8 listen_channel; + u8 operating_channel; + u8 listen_dwell; // This value should be between 1 and 3 + u8 support_rate[8]; + u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; + u8 intent; // should only include the intent value. + u8 p2p_peer_interface_addr[ ETH_ALEN ]; + u8 p2p_peer_device_addr[ ETH_ALEN ]; + u8 peer_intent; // Included the intent value and tie breaker value. + u8 device_name[ WPS_MAX_DEVICE_NAME_LEN ]; // Device name for displaying on searching device screen + u8 device_name_len; + u8 profileindex; // Used to point to the index of profileinfo array + u8 peer_operating_ch; + u8 find_phase_state_exchange_cnt; + u16 device_password_id_for_nego; // The device password ID for group negotation + u8 negotiation_dialog_token; + u8 nego_ssid[ WLAN_SSID_MAXLEN ]; // SSID information for group negotitation + u8 nego_ssidlen; + u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; + u8 p2p_group_ssid_len; + u8 persistent_supported; // Flag to know the persistent function should be supported or not. + // In the Sigma test, the Sigma will provide this enable from the sta_set_p2p CAPI. + // 0: disable + // 1: enable + u8 session_available; // Flag to set the WFD session available to enable or disable "by Sigma" + // In the Sigma test, the Sigma will disable the session available by using the sta_preset CAPI. + // 0: disable + // 1: enable + u8 wfd_tdls_enable; // Flag to enable or disable the TDLS by WFD Sigma + // 0: disable + // 1: enable + u8 wfd_tdls_weaksec; // Flag to enable or disable the weak security function for TDLS by WFD Sigma + // 0: disable + // In this case, the driver can't issue the tdsl setup request frame. + // 1: enable + // In this case, the driver can issue the tdls setup request frame + // even the current security is weak security. + + enum P2P_WPSINFO ui_got_wps_info; // This field will store the WPS value (PIN value or PBC) that UI had got from the user. + u16 supported_wps_cm; // This field describes the WPS config method which this driver supported. + // The value should be the combination of config method defined in page104 of WPS v2.0 spec. + u8 external_uuid; // UUID flag + u8 uuid[16]; // UUID + uint channel_list_attr_len; // This field will contain the length of body of P2P Channel List attribute of group negotitation response frame. + u8 channel_list_attr[100]; // This field will contain the body of P2P Channel List attribute of group negotitation response frame. + // We will use the channel_cnt and channel_list fields when constructing the group negotitation confirm frame. + u8 driver_interface; // Indicate DRIVER_WEXT or DRIVER_CFG80211 + +#ifdef CONFIG_CONCURRENT_MODE + u16 ext_listen_interval; // The interval to be available with legacy AP (ms) + u16 ext_listen_period; // The time period to be available for P2P listen state (ms) +#endif +#ifdef CONFIG_P2P_PS + enum P2P_PS_MODE p2p_ps_mode; // indicate p2p ps mode + enum P2P_PS_STATE p2p_ps_state; // indicate p2p ps state + u8 noa_index; // Identifies and instance of Notice of Absence timing. + u8 ctwindow; // Client traffic window. A period of time in TU after TBTT. + u8 opp_ps; // opportunistic power save. + u8 noa_num; // number of NoA descriptor in P2P IE. + u8 noa_count[P2P_MAX_NOA_NUM]; // Count for owner, Type of client. + u32 noa_duration[P2P_MAX_NOA_NUM]; // Max duration for owner, preferred or min acceptable duration for client. + u32 noa_interval[P2P_MAX_NOA_NUM]; // Length of interval for owner, preferred or max acceptable interval of client. + u32 noa_start_time[P2P_MAX_NOA_NUM]; // schedule expressed in terms of the lower 4 bytes of the TSF timer. +#endif // CONFIG_P2P_PS +}; + +struct tdls_ss_record{ //signal strength record; recording the tdls sta with lowerest ss + u8 macaddr[ETH_ALEN]; + u8 RxPWDBAll; + u8 is_tdls_sta; // _TRUE: direct link sta, _FALSE: else +}; + +struct tdls_info{ + u8 ap_prohibited; + uint setup_state; + u8 sta_cnt; + u8 sta_maximum; // 1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; + struct tdls_ss_record ss_record; + u8 macid_index; //macid entry that is ready to write + u8 clear_cam; //cam entry that is trying to clear, using it in direct link teardown + u8 ch_sensing; + u8 cur_channel; + u8 candidate_ch; + u8 collect_pkt_num[MAX_CHANNEL_NUM]; + _lock cmd_lock; + _lock hdl_lock; + u8 watchdog_count; + u8 dev_discovered; //WFD_TDLS: for sigma test + u8 enable; +#ifdef CONFIG_WFD + struct wifi_display_info *wfd_info; +#endif +}; + +struct mlme_priv { + + _lock lock; + sint fw_state; //shall we protect this variable? maybe not necessarily... + + u8 to_join; //flag + #ifdef CONFIG_LAYER2_ROAMING + u8 to_roaming; // roaming trying times + #endif + + u8 *nic_hdl; + + u8 not_indic_disco; + _list *pscanned; + _queue free_bss_pool; + _queue scanned_queue; + u8 *free_bss_buf; + u32 num_of_scanned; + + NDIS_802_11_SSID assoc_ssid; + u8 assoc_bssid[6]; + + struct wlan_network cur_network; + + //uint wireless_mode; no used, remove it + + u32 scan_interval; + + _timer assoc_timer; + + uint assoc_by_bssid; + uint assoc_by_rssi; + + _timer scan_to_timer; // driver itself handles scan_timeout status. + u32 scan_start_time; // used to evaluate the time spent in scanning + + #ifdef CONFIG_SET_SCAN_DENY_TIMER + _timer set_scan_deny_timer; + ATOMIC_T set_scan_deny; //0: allowed, 1: deny + #endif + + struct qos_priv qospriv; + +#ifdef CONFIG_80211N_HT + + /* Number of non-HT AP/stations */ + int num_sta_no_ht; + + /* Number of HT AP/stations 20 MHz */ + //int num_sta_ht_20mhz; + + + int num_FortyMHzIntolerant; + + struct ht_priv htpriv; + +#endif + + RT_LINK_DETECT_T LinkDetectInfo; + _timer dynamic_chk_timer; //dynamic/periodic check timer + + u8 acm_mask; // for wmm acm mask + u8 ChannelPlan; + RT_SCAN_TYPE scan_mode; // active: 1, passive: 0 + + //u8 probereq_wpsie[MAX_WPS_IE_LEN];//added in probe req + //int probereq_wpsie_len; + u8 *wps_probe_req_ie; + u32 wps_probe_req_ie_len; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + /* Number of associated Non-ERP stations (i.e., stations using 802.11b + * in 802.11g BSS) */ + int num_sta_non_erp; + + /* Number of associated stations that do not support Short Slot Time */ + int num_sta_no_short_slot_time; + + /* Number of associated stations that do not support Short Preamble */ + int num_sta_no_short_preamble; + + int olbc; /* Overlapping Legacy BSS Condition */ + + /* Number of HT associated stations that do not support greenfield */ + int num_sta_ht_no_gf; + + /* Number of associated non-HT stations */ + //int num_sta_no_ht; + + /* Number of HT associated stations 20 MHz */ + int num_sta_ht_20mhz; + + /* Overlapping BSS information */ + int olbc_ht; + +#ifdef CONFIG_80211N_HT + u16 ht_op_mode; +#endif /* CONFIG_80211N_HT */ + + u8 *assoc_req; + u32 assoc_req_len; + u8 *assoc_rsp; + u32 assoc_rsp_len; + + u8 *wps_beacon_ie; + //u8 *wps_probe_req_ie; + u8 *wps_probe_resp_ie; + u8 *wps_assoc_resp_ie; // for CONFIG_IOCTL_CFG80211, this IE could include p2p ie / wfd ie + + u32 wps_beacon_ie_len; + //u32 wps_probe_req_ie_len; + u32 wps_probe_resp_ie_len; + u32 wps_assoc_resp_ie_len; // for CONFIG_IOCTL_CFG80211, this IE len could include p2p ie / wfd ie + + u8 *p2p_beacon_ie; + u8 *p2p_probe_req_ie; + u8 *p2p_probe_resp_ie; + u8 *p2p_go_probe_resp_ie; //for GO + u8 *p2p_assoc_req_ie; + + u32 p2p_beacon_ie_len; + u32 p2p_probe_req_ie_len; + u32 p2p_probe_resp_ie_len; + u32 p2p_go_probe_resp_ie_len; //for GO + u32 p2p_assoc_req_ie_len; +/* +#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + //u8 *wps_p2p_beacon_ie; + u8 *p2p_beacon_ie; + u8 *wps_p2p_probe_resp_ie; + u8 *wps_p2p_assoc_resp_ie; + //u32 wps_p2p_beacon_ie_len; + u32 p2p_beacon_ie_len; + u32 wps_p2p_probe_resp_ie_len; + u32 wps_p2p_assoc_resp_ie_len; +#endif +*/ + + _lock bcn_update_lock; + u8 update_bcn; + + +#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) + + u8 *wfd_beacon_ie; + u8 *wfd_probe_req_ie; + u8 *wfd_probe_resp_ie; + u8 *wfd_go_probe_resp_ie; //for GO + u8 *wfd_assoc_req_ie; + + u32 wfd_beacon_ie_len; + u32 wfd_probe_req_ie_len; + u32 wfd_probe_resp_ie_len; + u32 wfd_go_probe_resp_ie_len; //for GO + u32 wfd_assoc_req_ie_len; + +#endif + +#ifdef RTK_DMP_PLATFORM + // DMP kobject_hotplug function signal need in passive level + _workitem Linkup_workitem; + _workitem Linkdown_workitem; +#endif + +#ifdef CONFIG_INTEL_WIDI + int widi_state; + int listen_state; + _timer listen_timer; + ATOMIC_T rx_probe_rsp; // 1:receive probe respone from RDS source. + u8 *l2sdTaBuffer; + u8 channel_idx; + s8 group_cnt; //For WiDi 3.5, they specified another scan algo. for WFD/RDS co-existed + u8 sa_ext[L2SDTA_SERVICE_VE_LEN]; + + u8 widi_enable; + /** + * For WiDi 4; upper layer would set + * p2p_primary_device_type_category_id + * p2p_primary_device_type_sub_category_id + * p2p_secondary_device_type_category_id + * p2p_secondary_device_type_sub_category_id + */ + u16 p2p_pdt_cid; + u16 p2p_pdt_scid; + u8 num_p2p_sdt; + u16 p2p_sdt_cid[MAX_NUM_P2P_SDT]; + u16 p2p_sdt_scid[MAX_NUM_P2P_SDT]; + u8 p2p_reject_disable; //When starting NL80211 wpa_supplicant/hostapd, it will call netdev_close + //such that it will cause p2p disabled. Use this flag to reject. +#endif // CONFIG_INTEL_WIDI + +#ifdef CONFIG_CONCURRENT_MODE + u8 scanning_via_buddy_intf; +#endif +}; + +#ifdef CONFIG_AP_MODE + +struct hostapd_priv +{ + _adapter *padapter; + +#ifdef CONFIG_HOSTAPD_MLME + struct net_device *pmgnt_netdev; + struct usb_anchor anchored; +#endif + +}; + +extern int hostapd_mode_init(_adapter *padapter); +extern void hostapd_mode_unload(_adapter *padapter); +#endif + + +extern void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf); +extern void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_atimdone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_cpwm_event_callback(_adapter *adapter, u8 *pbuf); + +#ifdef PLATFORM_WINDOWS +extern thread_return event_thread(void *context); + +extern void rtw_join_timeout_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); + +extern void _rtw_scan_timeout_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); + +#endif + +#if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD) +extern int event_thread(void *context); +extern void rtw_join_timeout_handler(void* FunctionContext); +extern void _rtw_scan_timeout_handler(void* FunctionContext); +#endif + +extern void rtw_free_network_queue(_adapter *adapter,u8 isfreeall); +extern int rtw_init_mlme_priv(_adapter *adapter);// (struct mlme_priv *pmlmepriv); + +extern void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv); + + +extern sint rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); +extern sint rtw_set_key(_adapter *adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx); +extern sint rtw_set_auth(_adapter *adapter,struct security_priv *psecuritypriv); + +__inline static u8 *get_bssid(struct mlme_priv *pmlmepriv) +{ //if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid + // if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address + return pmlmepriv->cur_network.network.MacAddress; +} + +__inline static sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + if (pmlmepriv->fw_state & state) + return _TRUE; + + return _FALSE; +} + +__inline static sint get_fwstate(struct mlme_priv *pmlmepriv) +{ + return pmlmepriv->fw_state; +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + * + * ### NOTE:#### (!!!!) + * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock + */ +__inline static void set_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state |= state; +} + +__inline static void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state &= ~state; +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + */ +__inline static void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if (check_fwstate(pmlmepriv, state) == _TRUE) + pmlmepriv->fw_state ^= state; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void clr_fwstate_ex(struct mlme_priv *pmlmepriv, sint state) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _clr_fwstate_(pmlmepriv, state); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void up_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned++; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +#ifdef CONFIG_CONCURRENT_MODE +sint rtw_buddy_adapter_up(_adapter *padapter); +sint check_buddy_fwstate(_adapter *padapter, sint state); +#endif //CONFIG_CONCURRENT_MODE + +__inline static void down_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned--; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void set_scanned_network_val(struct mlme_priv *pmlmepriv, sint val) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned = val; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +extern u16 rtw_get_capability(WLAN_BSSID_EX *bss); +extern void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target); +extern void rtw_disconnect_hdl_under_linked(_adapter* adapter, struct sta_info *psta, u8 free_assoc); +extern void rtw_generate_random_ibss(u8 *pibss); +extern struct wlan_network* rtw_find_network(_queue *scanned_queue, u8 *addr); +extern struct wlan_network* rtw_get_oldest_wlan_network(_queue *scanned_queue); + +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); +void rtw_scan_abort(_adapter *adapter); + +extern int rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie,u8 *out_ie,uint in_len); +extern int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len); +extern void rtw_init_registrypriv_dev_network(_adapter *adapter); + +extern void rtw_update_registrypriv_dev_network(_adapter *adapter); + +extern void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter); + +extern void _rtw_join_timeout_handler(_adapter *adapter); +extern void rtw_scan_timeout_handler(_adapter *adapter); + +extern void rtw_dynamic_check_timer_handlder(_adapter *adapter); +#ifdef CONFIG_SET_SCAN_DENY_TIMER +bool rtw_is_scan_deny(_adapter *adapter); +void rtw_clear_scan_deny(_adapter *adapter); +void rtw_set_scan_deny_timer_hdl(_adapter *adapter); +void rtw_set_scan_deny(_adapter *adapter, u32 ms); +#else +#define rtw_is_scan_deny(adapter) _FALSE +#define rtw_clear_scan_deny(adapter) do {} while (0) +#define rtw_set_scan_deny_timer_hdl(adapter) do {} while (0) +#define rtw_set_scan_deny(adapter, ms) do {} while (0) +#endif + + +extern int _rtw_init_mlme_priv(_adapter *padapter); + +void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); + +extern void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); + +extern int _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); + +extern struct wlan_network* _rtw_dequeue_network(_queue *queue); + +extern struct wlan_network* _rtw_alloc_network(struct mlme_priv *pmlmepriv); + + +extern void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall); +extern void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork); + + +extern struct wlan_network* _rtw_find_network(_queue *scanned_queue, u8 *addr); + +extern void _rtw_free_network_queue(_adapter* padapter, u8 isfreeall); + +extern sint rtw_if_up(_adapter *padapter); + + +u8 *rtw_get_capability_from_ie(u8 *ie); +u8 *rtw_get_timestampe_from_ie(u8 *ie); +u8 *rtw_get_beacon_interval_from_ie(u8 *ie); + + +void rtw_joinbss_reset(_adapter *padapter); + +#ifdef CONFIG_80211N_HT +unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel); +void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel); +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif + +int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork); +int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst); + +#ifdef CONFIG_LAYER2_ROAMING +void _rtw_roaming(_adapter *adapter, struct wlan_network *tgt_network); +void rtw_roaming(_adapter *adapter, struct wlan_network *tgt_network); +void rtw_set_roaming(_adapter *adapter, u8 to_roaming); +u8 rtw_to_roaming(_adapter *adapter); +#else +#define _rtw_roaming(adapter, tgt_network) do {} while(0) +#define rtw_roaming(adapter, tgt_network) do {} while(0) +#define rtw_set_roaming(adapter, to_roaming) do {} while(0) +#define rtw_to_roaming(adapter) 0 +#endif + + +#ifdef CONFIG_INTEL_PROXIM +void rtw_proxim_enable(_adapter *padapter); +void rtw_proxim_disable(_adapter *padapter); +void rtw_proxim_send_packet(_adapter *padapter,u8 *pbuf,u16 len,u8 hw_rate); +#endif //CONFIG_INTEL_PROXIM +#endif //__RTL871X_MLME_H_ + diff --git a/rtl8192cu-fixes/include/rtw_mlme_ext.h b/rtl8192cu-fixes/include/rtw_mlme_ext.h new file mode 100755 index 00000000..5cddca4d --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_mlme_ext.h @@ -0,0 +1,963 @@ +/****************************************************************************** + * + * 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 __RTW_MLME_EXT_H_ +#define __RTW_MLME_EXT_H_ + +#include +#include +#include +#include + + +// Commented by Albert 20101105 +// Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) +// The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. +// So, this driver tried to extend the dwell time for each scanning channel. +// This will increase the chance to receive the probe response from SoftAP. + +#define SURVEY_TO (100) +#define REAUTH_TO (300) //(50) +#define REASSOC_TO (300) //(50) +//#define DISCONNECT_TO (3000) +#define ADDBA_TO (2000) + +#define LINKED_TO (1) //unit:2 sec, 1x2=2 sec + +#define REAUTH_LIMIT (4) +#define REASSOC_LIMIT (4) +#define READDBA_LIMIT (2) + +//#define IOCMD_REG0 0x10250370 +//#define IOCMD_REG1 0x10250374 +//#define IOCMD_REG2 0x10250378 + +//#define FW_DYNAMIC_FUN_SWITCH 0x10250364 + +//#define WRITE_BB_CMD 0xF0000001 +//#define SET_CHANNEL_CMD 0xF3000000 +//#define UPDATE_RA_CMD 0xFD0000A2 + +#define DYNAMIC_FUNC_DISABLE (0x0) +#define DYNAMIC_FUNC_DIG BIT(0) +#define DYNAMIC_FUNC_HP BIT(1) +#define DYNAMIC_FUNC_SS BIT(2) //Tx Power Tracking +#define DYNAMIC_FUNC_BT BIT(3) +#define DYNAMIC_FUNC_ANT_DIV BIT(4) +#define DYNAMIC_FUNC_ADAPTIVITY BIT(5) + +#define _HW_STATE_NOLINK_ 0x00 +#define _HW_STATE_ADHOC_ 0x01 +#define _HW_STATE_STATION_ 0x02 +#define _HW_STATE_AP_ 0x03 + + +#define _1M_RATE_ 0 +#define _2M_RATE_ 1 +#define _5M_RATE_ 2 +#define _11M_RATE_ 3 +#define _6M_RATE_ 4 +#define _9M_RATE_ 5 +#define _12M_RATE_ 6 +#define _18M_RATE_ 7 +#define _24M_RATE_ 8 +#define _36M_RATE_ 9 +#define _48M_RATE_ 10 +#define _54M_RATE_ 11 + + +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WMM_OUI[]; +extern unsigned char WPS_OUI[]; +extern unsigned char WFD_OUI[]; +extern unsigned char P2P_OUI[]; + +extern unsigned char WMM_INFO_OUI[]; +extern unsigned char WMM_PARA_OUI[]; + + +// +// Channel Plan Type. +// Note: +// We just add new channel plan when the new channel plan is different from any of the following +// channel plan. +// If you just wnat to customize the acitions(scan period or join actions) about one of the channel plan, +// customize them in RT_CHANNEL_INFO in the RT_CHANNEL_LIST. +// +typedef enum _RT_CHANNEL_DOMAIN +{ + //===== old channel plan mapping =====// + RT_CHANNEL_DOMAIN_FCC = 0x00, + RT_CHANNEL_DOMAIN_IC = 0x01, + RT_CHANNEL_DOMAIN_ETSI = 0x02, + RT_CHANNEL_DOMAIN_SPAIN = 0x03, + RT_CHANNEL_DOMAIN_FRANCE = 0x04, + RT_CHANNEL_DOMAIN_MKK = 0x05, + RT_CHANNEL_DOMAIN_MKK1 = 0x06, + RT_CHANNEL_DOMAIN_ISRAEL = 0x07, + RT_CHANNEL_DOMAIN_TELEC = 0x08, + RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09, + RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A, + RT_CHANNEL_DOMAIN_TAIWAN = 0x0B, + RT_CHANNEL_DOMAIN_CHINA = 0x0C, + RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D, + RT_CHANNEL_DOMAIN_KOREA = 0x0E, + RT_CHANNEL_DOMAIN_TURKEY = 0x0F, + RT_CHANNEL_DOMAIN_JAPAN = 0x10, + RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11, + RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12, + RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = 0x13, + RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14, + + //===== new channel plan mapping, (2GDOMAIN_5GDOMAIN) =====// + RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, + RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21, + RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22, + RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23, + RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24, + RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25, + RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26, + RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27, + RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28, + RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29, + RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30, + RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31, + RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32, + RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33, + RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34, + RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35, + RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36, + RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37, + RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38, + RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39, + RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40, + + //===== Add new channel plan above this line===============// + RT_CHANNEL_DOMAIN_MAX, + RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, +}RT_CHANNEL_DOMAIN, *PRT_CHANNEL_DOMAIN; + +typedef enum _RT_CHANNEL_DOMAIN_2G +{ + RT_CHANNEL_DOMAIN_2G_WORLD = 0x00, //Worldwird 13 + RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01, //Europe + RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02, //US + RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03, //Japan + RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04, //France + RT_CHANNEL_DOMAIN_2G_NULL = 0x05, + //===== Add new channel plan above this line===============// + RT_CHANNEL_DOMAIN_2G_MAX, +}RT_CHANNEL_DOMAIN_2G, *PRT_CHANNEL_DOMAIN_2G; + +typedef enum _RT_CHANNEL_DOMAIN_5G +{ + RT_CHANNEL_DOMAIN_5G_NULL = 0x00, + RT_CHANNEL_DOMAIN_5G_ETSI1 = 0x01, //Europe + RT_CHANNEL_DOMAIN_5G_ETSI2 = 0x02, //Australia, New Zealand + RT_CHANNEL_DOMAIN_5G_ETSI3 = 0x03, //Russia + RT_CHANNEL_DOMAIN_5G_FCC1 = 0x04, //US + RT_CHANNEL_DOMAIN_5G_FCC2 = 0x05, //FCC o/w DFS Channels + RT_CHANNEL_DOMAIN_5G_FCC3 = 0x06, //India, Mexico + RT_CHANNEL_DOMAIN_5G_FCC4 = 0x07, //Venezuela + RT_CHANNEL_DOMAIN_5G_FCC5 = 0x08, //China + RT_CHANNEL_DOMAIN_5G_FCC6 = 0x09, //Israel + RT_CHANNEL_DOMAIN_5G_FCC7_IC1 = 0x0A, //US, Canada + RT_CHANNEL_DOMAIN_5G_KCC1 = 0x0B, //Korea + RT_CHANNEL_DOMAIN_5G_MKK1 = 0x0C, //Japan + RT_CHANNEL_DOMAIN_5G_MKK2 = 0x0D, //Japan (W52, W53) + RT_CHANNEL_DOMAIN_5G_MKK3 = 0x0E, //Japan (W56) + RT_CHANNEL_DOMAIN_5G_NCC1 = 0x0F, //Taiwan + RT_CHANNEL_DOMAIN_5G_NCC2 = 0x10, //Taiwan o/w DFS + //===== Add new channel plan above this line===============// + //===== Driver Self Defined =====// + RT_CHANNEL_DOMAIN_5G_FCC = 0x11, + RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS = 0x12, + RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS = 0x13, + RT_CHANNEL_DOMAIN_5G_MAX, +}RT_CHANNEL_DOMAIN_5G, *PRT_CHANNEL_DOMAIN_5G; + +#define rtw_is_channel_plan_valid(chplan) (chplansurvey_timer, (ms)); \ + } while(0) + +#define set_link_timer(mlmeext, ms) \ + do { \ + /*DBG_871X("%s set_link_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms));*/ \ + _set_timer(&(mlmeext)->link_timer, (ms)); \ + } while(0) +#ifdef CONFIG_IEEE80211W +#define set_sa_query_timer(mlmeext, ms) \ + do { \ + DBG_871X("%s set_sa_query_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms)); \ + _set_timer(&(mlmeext)->sa_query_timer, (ms)); \ + } while(0) +#endif //CONFIG_IEEE80211W +extern int cckrates_included(unsigned char *rate, int ratelen); +extern int cckratesonly_included(unsigned char *rate, int ratelen); + +extern void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr); + +extern void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); +extern void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext); + + +#ifdef CONFIG_CONCURRENT_MODE + sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state); +void concurrent_chk_joinbss_done(_adapter *padapter, int join_res); +#endif //CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_DUALMAC_CONCURRENT +void dc_SelectChannel(_adapter *padapter, unsigned char channel); +void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset); +void dc_set_channel_bwmode_disconnect(_adapter *padapter); +u8 dc_handle_join_request(_adapter *padapter); +void dc_handle_join_done(_adapter *padapter, u8 join_res); +sint dc_check_fwstate(_adapter *padapter, sint fw_state); +u8 dc_handle_site_survey(_adapter *padapter); +void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame); +void dc_set_channel_bwmode_survey_done(_adapter *padapter); +void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode); +void dc_resume_xmit(_adapter *padapter); +u8 dc_check_xmit(_adapter *padapter); +#endif + +int rtw_chk_start_clnt_join(_adapter *padapter); +int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset); + +struct cmd_hdl { + uint parmsize; + u8 (*h2cfuns)(struct _ADAPTER *padapter, u8 *pbuf); +}; + + +u8 read_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_rfreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_rfreg_hdl(_adapter *padapter, u8 *pbuf); + + +u8 NULL_hdl(_adapter *padapter, u8 *pbuf); +u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 disconnect_hdl(_adapter *padapter, u8 *pbuf); +u8 createbss_hdl(_adapter *padapter, u8 *pbuf); +u8 setopmode_hdl(_adapter *padapter, u8 *pbuf); +u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 setauth_hdl(_adapter *padapter, u8 *pbuf); +u8 setkey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 del_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf); + +u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf); +u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf); +u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf); +u8 set_ch_hdl(_adapter *padapter, u8 *pbuf); +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); + + +#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, +#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, + +#ifdef _RTW_CMD_C_ + +struct cmd_hdl wlancmds[] = +{ + GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/ + GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/ + GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ + + GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ + GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ + + GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ + GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ + GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/ + GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*61*/ + GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/ +}; + +#endif + +struct C2HEvent_Header +{ + +#ifdef CONFIG_LITTLE_ENDIAN + + unsigned int len:16; + unsigned int ID:8; + unsigned int seq:8; + +#elif defined(CONFIG_BIG_ENDIAN) + + unsigned int seq:8; + unsigned int ID:8; + unsigned int len:16; + +#else + +# error "Must be LITTLE or BIG Endian" + +#endif + + unsigned int rsvd; + +}; + +void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf); +void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf); + +enum rtw_c2h_event +{ + GEN_EVT_CODE(_Read_MACREG)=0, /*0*/ + GEN_EVT_CODE(_Read_BBREG), + GEN_EVT_CODE(_Read_RFREG), + GEN_EVT_CODE(_Read_EEPROM), + GEN_EVT_CODE(_Read_EFUSE), + GEN_EVT_CODE(_Read_CAM), /*5*/ + GEN_EVT_CODE(_Get_BasicRate), + GEN_EVT_CODE(_Get_DataRate), + GEN_EVT_CODE(_Survey), /*8*/ + GEN_EVT_CODE(_SurveyDone), /*9*/ + + GEN_EVT_CODE(_JoinBss) , /*10*/ + GEN_EVT_CODE(_AddSTA), + GEN_EVT_CODE(_DelSTA), + GEN_EVT_CODE(_AtimDone) , + GEN_EVT_CODE(_TX_Report), + GEN_EVT_CODE(_CCX_Report), /*15*/ + GEN_EVT_CODE(_DTM_Report), + GEN_EVT_CODE(_TX_Rate_Statistics), + GEN_EVT_CODE(_C2HLBK), + GEN_EVT_CODE(_FWDBG), + GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ + GEN_EVT_CODE(_ADDBA), + GEN_EVT_CODE(_C2HBCN), + GEN_EVT_CODE(_ReportPwrState), //filen: only for PCIE, USB + GEN_EVT_CODE(_CloseRF), //filen: only for PCIE, work around ASPM + MAX_C2HEVT +}; + + +#ifdef _RTW_MLME_EXT_C_ + +static struct fwevent wlanevents[] = +{ + {0, rtw_dummy_event_callback}, /*0*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, &rtw_survey_event_callback}, /*8*/ + {sizeof (struct surveydone_event), &rtw_surveydone_event_callback}, /*9*/ + + {0, &rtw_joinbss_event_callback}, /*10*/ + {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, + {sizeof(struct stadel_event), &rtw_stadel_event_callback}, + {0, &rtw_atimdone_event_callback}, + {0, rtw_dummy_event_callback}, + {0, NULL}, /*15*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, rtw_fwdbg_event_callback}, + {0, NULL}, /*20*/ + {0, NULL}, + {0, NULL}, + {0, &rtw_cpwm_event_callback}, +}; + +#endif//_RTL8192C_CMD_C_ + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_mp.h b/rtl8192cu-fixes/include/rtw_mp.h new file mode 100755 index 00000000..0ebb1ba6 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_mp.h @@ -0,0 +1,712 @@ +/****************************************************************************** + * + * 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 _RTW_MP_H_ +#define _RTW_MP_H_ + +#ifndef PLATFORM_WINDOWS +// 00 - Success +// 11 - Error +#define STATUS_SUCCESS (0x00000000L) +#define STATUS_PENDING (0x00000103L) + +#define STATUS_UNSUCCESSFUL (0xC0000001L) +#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) +#define STATUS_NOT_SUPPORTED (0xC00000BBL) + +#define NDIS_STATUS_SUCCESS ((NDIS_STATUS)STATUS_SUCCESS) +#define NDIS_STATUS_PENDING ((NDIS_STATUS)STATUS_PENDING) +#define NDIS_STATUS_NOT_RECOGNIZED ((NDIS_STATUS)0x00010001L) +#define NDIS_STATUS_NOT_COPIED ((NDIS_STATUS)0x00010002L) +#define NDIS_STATUS_NOT_ACCEPTED ((NDIS_STATUS)0x00010003L) +#define NDIS_STATUS_CALL_ACTIVE ((NDIS_STATUS)0x00010007L) + +#define NDIS_STATUS_FAILURE ((NDIS_STATUS)STATUS_UNSUCCESSFUL) +#define NDIS_STATUS_RESOURCES ((NDIS_STATUS)STATUS_INSUFFICIENT_RESOURCES) +#define NDIS_STATUS_CLOSING ((NDIS_STATUS)0xC0010002L) +#define NDIS_STATUS_BAD_VERSION ((NDIS_STATUS)0xC0010004L) +#define NDIS_STATUS_BAD_CHARACTERISTICS ((NDIS_STATUS)0xC0010005L) +#define NDIS_STATUS_ADAPTER_NOT_FOUND ((NDIS_STATUS)0xC0010006L) +#define NDIS_STATUS_OPEN_FAILED ((NDIS_STATUS)0xC0010007L) +#define NDIS_STATUS_DEVICE_FAILED ((NDIS_STATUS)0xC0010008L) +#define NDIS_STATUS_MULTICAST_FULL ((NDIS_STATUS)0xC0010009L) +#define NDIS_STATUS_MULTICAST_EXISTS ((NDIS_STATUS)0xC001000AL) +#define NDIS_STATUS_MULTICAST_NOT_FOUND ((NDIS_STATUS)0xC001000BL) +#define NDIS_STATUS_REQUEST_ABORTED ((NDIS_STATUS)0xC001000CL) +#define NDIS_STATUS_RESET_IN_PROGRESS ((NDIS_STATUS)0xC001000DL) +#define NDIS_STATUS_CLOSING_INDICATING ((NDIS_STATUS)0xC001000EL) +#define NDIS_STATUS_NOT_SUPPORTED ((NDIS_STATUS)STATUS_NOT_SUPPORTED) +#define NDIS_STATUS_INVALID_PACKET ((NDIS_STATUS)0xC001000FL) +#define NDIS_STATUS_OPEN_LIST_FULL ((NDIS_STATUS)0xC0010010L) +#define NDIS_STATUS_ADAPTER_NOT_READY ((NDIS_STATUS)0xC0010011L) +#define NDIS_STATUS_ADAPTER_NOT_OPEN ((NDIS_STATUS)0xC0010012L) +#define NDIS_STATUS_NOT_INDICATING ((NDIS_STATUS)0xC0010013L) +#define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) +#define NDIS_STATUS_INVALID_DATA ((NDIS_STATUS)0xC0010015L) +#define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) +#define NDIS_STATUS_INVALID_OID ((NDIS_STATUS)0xC0010017L) +#define NDIS_STATUS_ADAPTER_REMOVED ((NDIS_STATUS)0xC0010018L) +#define NDIS_STATUS_UNSUPPORTED_MEDIA ((NDIS_STATUS)0xC0010019L) +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((NDIS_STATUS)0xC001001AL) +#define NDIS_STATUS_FILE_NOT_FOUND ((NDIS_STATUS)0xC001001BL) +#define NDIS_STATUS_ERROR_READING_FILE ((NDIS_STATUS)0xC001001CL) +#define NDIS_STATUS_ALREADY_MAPPED ((NDIS_STATUS)0xC001001DL) +#define NDIS_STATUS_RESOURCE_CONFLICT ((NDIS_STATUS)0xC001001EL) +#define NDIS_STATUS_NO_CABLE ((NDIS_STATUS)0xC001001FL) + +#define NDIS_STATUS_INVALID_SAP ((NDIS_STATUS)0xC0010020L) +#define NDIS_STATUS_SAP_IN_USE ((NDIS_STATUS)0xC0010021L) +#define NDIS_STATUS_INVALID_ADDRESS ((NDIS_STATUS)0xC0010022L) +#define NDIS_STATUS_VC_NOT_ACTIVATED ((NDIS_STATUS)0xC0010023L) +#define NDIS_STATUS_DEST_OUT_OF_ORDER ((NDIS_STATUS)0xC0010024L) // cause 27 +#define NDIS_STATUS_VC_NOT_AVAILABLE ((NDIS_STATUS)0xC0010025L) // cause 35,45 +#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((NDIS_STATUS)0xC0010026L) // cause 37 +#define NDIS_STATUS_INCOMPATABLE_QOS ((NDIS_STATUS)0xC0010027L) // cause 49 +#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((NDIS_STATUS)0xC0010028L) // cause 93 +#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((NDIS_STATUS)0xC0010029L) // cause 3 +#endif /* #ifndef PLATFORM_WINDOWS */ + +#if 0 +#define MPT_NOOP 0 +#define MPT_READ_MAC_1BYTE 1 +#define MPT_READ_MAC_2BYTE 2 +#define MPT_READ_MAC_4BYTE 3 +#define MPT_WRITE_MAC_1BYTE 4 +#define MPT_WRITE_MAC_2BYTE 5 +#define MPT_WRITE_MAC_4BYTE 6 +#define MPT_READ_BB_CCK 7 +#define MPT_WRITE_BB_CCK 8 +#define MPT_READ_BB_OFDM 9 +#define MPT_WRITE_BB_OFDM 10 +#define MPT_READ_RF 11 +#define MPT_WRITE_RF 12 +#define MPT_READ_EEPROM_1BYTE 13 +#define MPT_WRITE_EEPROM_1BYTE 14 +#define MPT_READ_EEPROM_2BYTE 15 +#define MPT_WRITE_EEPROM_2BYTE 16 +#define MPT_SET_CSTHRESHOLD 21 +#define MPT_SET_INITGAIN 22 +#define MPT_SWITCH_BAND 23 +#define MPT_SWITCH_CHANNEL 24 +#define MPT_SET_DATARATE 25 +#define MPT_SWITCH_ANTENNA 26 +#define MPT_SET_TX_POWER 27 +#define MPT_SET_CONT_TX 28 +#define MPT_SET_SINGLE_CARRIER 29 +#define MPT_SET_CARRIER_SUPPRESSION 30 +#define MPT_GET_RATE_TABLE 31 +#define MPT_READ_TSSI 32 +#define MPT_GET_THERMAL_METER 33 +#endif + +#define MAX_MP_XMITBUF_SZ 2048 +#define NR_MP_XMITFRAME 8 + +struct mp_xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + +#ifdef CONFIG_USB_HCI + + //insert urb, irp, and irpcnt info below... + //max frag_cnt = 8 + + u8 *mem_addr; + u32 sz[8]; + +#if defined(PLATFORM_OS_XP) || defined(PLATFORM_LINUX) + PURB pxmit_urb[8]; +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + + u8 bpending[8]; + sint ac_tag[8]; + sint last[8]; + uint irpcnt; + uint fragcnt; +#endif /* CONFIG_USB_HCI */ + + uint mem[(MAX_MP_XMITBUF_SZ >> 2)]; +}; + +struct mp_wiparam +{ + u32 bcompleted; + u32 act_type; + u32 io_offset; + u32 io_value; +}; + +typedef void(*wi_act_func)(void* padapter); + +#ifdef PLATFORM_WINDOWS +struct mp_wi_cntx +{ + u8 bmpdrv_unload; + + // Work Item + NDIS_WORK_ITEM mp_wi; + NDIS_EVENT mp_wi_evt; + _lock mp_wi_lock; + u8 bmp_wi_progress; + wi_act_func curractfunc; + // Variable needed in each implementation of CurrActFunc. + struct mp_wiparam param; +}; +#endif + +struct mp_tx +{ + u8 stop; + u32 count, sended; + u8 payload; + struct pkt_attrib attrib; + struct tx_desc desc; + u8 *pallocated_buf; + u8 *buf; + u32 buf_size, write_size; + _thread_hdl_ PktTxThread; +}; + +//#if (MP_DRIVER == 1) +#if defined(CONFIG_RTL8192C) || defined(CONFIG_RTL8192D) || defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8188E) +#ifdef CONFIG_RTL8192C +#include +#endif +#ifdef CONFIG_RTL8192D +#include +#endif +#ifdef CONFIG_RTL8723A +#include +#endif +#ifdef CONFIG_RTL8188E +#include +#endif +#define MP_MAX_LINES 1000 +#define MP_MAX_LINES_BYTES 256 +#define u1Byte u8 +#define s1Byte s8 +#define u4Byte u32 +#define s4Byte s32 +typedef VOID (*MPT_WORK_ITEM_HANDLER)(IN PVOID Adapter); +typedef struct _MPT_CONTEXT +{ + // Indicate if we have started Mass Production Test. + BOOLEAN bMassProdTest; + + // Indicate if the driver is unloading or unloaded. + BOOLEAN bMptDrvUnload; + + /* 8190 PCI does not support NDIS_WORK_ITEM. */ + // Work Item for Mass Production Test. + //NDIS_WORK_ITEM MptWorkItem; +// RT_WORK_ITEM MptWorkItem; + // Event used to sync the case unloading driver and MptWorkItem is still in progress. +// NDIS_EVENT MptWorkItemEvent; + // To protect the following variables. +// NDIS_SPIN_LOCK MptWorkItemSpinLock; + // Indicate a MptWorkItem is scheduled and not yet finished. + BOOLEAN bMptWorkItemInProgress; + // An instance which implements function and context of MptWorkItem. + MPT_WORK_ITEM_HANDLER CurrMptAct; + + // 1=Start, 0=Stop from UI. + ULONG MptTestStart; + // _TEST_MODE, defined in MPT_Req2.h + ULONG MptTestItem; + // Variable needed in each implementation of CurrMptAct. + ULONG MptActType; // Type of action performed in CurrMptAct. + // The Offset of IO operation is depend of MptActType. + ULONG MptIoOffset; + // The Value of IO operation is depend of MptActType. + ULONG MptIoValue; + // The RfPath of IO operation is depend of MptActType. + ULONG MptRfPath; + + WIRELESS_MODE MptWirelessModeToSw; // Wireless mode to switch. + u8 MptChannelToSw; // Channel to switch. + u8 MptInitGainToSet; // Initial gain to set. + //ULONG bMptAntennaA; // TRUE if we want to use antenna A. + ULONG MptBandWidth; // bandwidth to switch. + ULONG MptRateIndex; // rate index. + // Register value kept for Single Carrier Tx test. + u8 btMpCckTxPower; + // Register value kept for Single Carrier Tx test. + u8 btMpOfdmTxPower; + // For MP Tx Power index + u8 TxPwrLevel[2]; // rf-A, rf-B + + // Content of RCR Regsiter for Mass Production Test. + ULONG MptRCR; + // TRUE if we only receive packets with specific pattern. + BOOLEAN bMptFilterPattern; + // Rx OK count, statistics used in Mass Production Test. + ULONG MptRxOkCnt; + // Rx CRC32 error count, statistics used in Mass Production Test. + ULONG MptRxCrcErrCnt; + + BOOLEAN bCckContTx; // TRUE if we are in CCK Continuous Tx test. + BOOLEAN bOfdmContTx; // TRUE if we are in OFDM Continuous Tx test. + BOOLEAN bStartContTx; // TRUE if we have start Continuous Tx test. + // TRUE if we are in Single Carrier Tx test. + BOOLEAN bSingleCarrier; + // TRUE if we are in Carrier Suppression Tx Test. + BOOLEAN bCarrierSuppression; + //TRUE if we are in Single Tone Tx test. + BOOLEAN bSingleTone; + + // ACK counter asked by K.Y.. + BOOLEAN bMptEnableAckCounter; + ULONG MptAckCounter; + + // SD3 Willis For 8192S to save 1T/2T RF table for ACUT Only fro ACUT delete later ~~~! + //s1Byte BufOfLines[2][MAX_LINES_HWCONFIG_TXT][MAX_BYTES_LINE_HWCONFIG_TXT]; + //s1Byte BufOfLines[2][MP_MAX_LINES][MP_MAX_LINES_BYTES]; + //s4Byte RfReadLine[2]; + + u8 APK_bound[2]; //for APK path A/path B + BOOLEAN bMptIndexEven; + + u8 backup0xc50; + u8 backup0xc58; + u8 backup0xc30; +}MPT_CONTEXT, *PMPT_CONTEXT; +#endif +//#endif + +/* E-Fuse */ +#ifdef CONFIG_RTL8192D +#define EFUSE_MAP_SIZE 255 +#endif +#ifdef CONFIG_RTL8192C +#define EFUSE_MAP_SIZE 128 +#endif +#ifdef CONFIG_RTL8723A +#define EFUSE_MAP_SIZE 256 +#endif +#ifdef CONFIG_RTL8188E +#define EFUSE_MAP_SIZE 256 +#endif +#define EFUSE_MAX_SIZE 512 + +/* end of E-Fuse */ + +//#define RTPRIV_IOCTL_MP ( SIOCIWFIRSTPRIV + 0x17) +enum { + WRITE_REG = 1, + READ_REG, + WRITE_RF, + READ_RF, + MP_START, + MP_STOP, + MP_RATE, + MP_CHANNEL, + MP_BANDWIDTH, + MP_TXPOWER, + MP_ANT_TX, + MP_ANT_RX, + MP_CTX, + MP_QUERY, + MP_ARX, + MP_PSD, + MP_PWRTRK, + MP_THER, + MP_IOCTL, + EFUSE_GET, + EFUSE_SET, + MP_RESET_STATS, + MP_DUMP, + MP_PHYPARA, + MP_NULL, +}; + +struct mp_priv +{ + _adapter *papdater; + + //Testing Flag + u32 mode;//0 for normal type packet, 1 for loopback packet (16bytes TXCMD) + + u32 prev_fw_state; + + //OID cmd handler + struct mp_wiparam workparam; +// u8 act_in_progress; + + //Tx Section + u8 TID; + u32 tx_pktcount; + struct mp_tx tx; + + //Rx Section + u32 rx_pktcount; + u32 rx_crcerrpktcount; + u32 rx_pktloss; + + struct recv_stat rxstat; + + //RF/BB relative + u8 channel; + u8 bandwidth; + u8 prime_channel_offset; + u8 txpoweridx; + u8 txpoweridx_b; + u8 rateidx; + u32 preamble; +// u8 modem; + u32 CrystalCap; +// u32 curr_crystalcap; + + u16 antenna_tx; + u16 antenna_rx; +// u8 curr_rfpath; + + u8 check_mp_pkt; + +// uint ForcedDataRate; + + struct wlan_network mp_network; + NDIS_802_11_MAC_ADDRESS network_macaddr; + +#ifdef PLATFORM_WINDOWS + u32 rx_testcnt; + u32 rx_testcnt1; + u32 rx_testcnt2; + u32 tx_testcnt; + u32 tx_testcnt1; + + struct mp_wi_cntx wi_cntx; + + u8 h2c_result; + u8 h2c_seqnum; + u16 h2c_cmdcode; + u8 h2c_resp_parambuf[512]; + _lock h2c_lock; + _lock wkitm_lock; + u32 h2c_cmdcnt; + NDIS_EVENT h2c_cmd_evt; + NDIS_EVENT c2h_set; + NDIS_EVENT h2c_clr; + NDIS_EVENT cpwm_int; + + NDIS_EVENT scsir_full_evt; + NDIS_EVENT scsiw_empty_evt; +#endif + + u8 *pallocated_mp_xmitframe_buf; + u8 *pmp_xmtframe_buf; + _queue free_mp_xmitqueue; + u32 free_mp_xmitframe_cnt; + + MPT_CONTEXT MptCtx; +}; + +typedef struct _IOCMD_STRUCT_ { + u8 cmdclass; + u16 value; + u8 index; +}IOCMD_STRUCT; + +struct rf_reg_param { + u32 path; + u32 offset; + u32 value; +}; + +struct bb_reg_param { + u32 offset; + u32 value; +}; +//======================================================================= + +#define LOWER _TRUE +#define RAISE _FALSE + +/* Hardware Registers */ +#if 0 +#if 0 +#define IOCMD_CTRL_REG 0x102502C0 +#define IOCMD_DATA_REG 0x102502C4 +#else +#define IOCMD_CTRL_REG 0x10250370 +#define IOCMD_DATA_REG 0x10250374 +#endif + +#define IOCMD_GET_THERMAL_METER 0xFD000028 + +#define IOCMD_CLASS_BB_RF 0xF0 +#define IOCMD_BB_READ_IDX 0x00 +#define IOCMD_BB_WRITE_IDX 0x01 +#define IOCMD_RF_READ_IDX 0x02 +#define IOCMD_RF_WRIT_IDX 0x03 +#endif +#define BB_REG_BASE_ADDR 0x800 + +/* MP variables */ +#if 0 +#define _2MAC_MODE_ 0 +#define _LOOPBOOK_MODE_ 1 +#endif +typedef enum _MP_MODE_ { + MP_OFF, + MP_ON, + MP_ERR, + MP_CONTINUOUS_TX, + MP_SINGLE_CARRIER_TX, + MP_CARRIER_SUPPRISSION_TX, + MP_SINGLE_TONE_TX, + MP_PACKET_TX, + MP_PACKET_RX +} MP_MODE; + +#ifdef CONFIG_RTL8192C +#define RF_PATH_A RF_PATH_A +#define RF_PATH_B RF_PATH_B +#define RF_PATH_C RF_PATH_C +#define RF_PATH_D RF_PATH_D + +#define MAX_RF_PATH_NUMS RF_PATH_MAX +#else +#define RF_PATH_A 0 +#define RF_PATH_B 1 +#define RF_PATH_C 2 +#define RF_PATH_D 3 + +#define MAX_RF_PATH_NUMS 2 +#endif + +extern u8 mpdatarate[NumRates]; + +/* MP set force data rate base on the definition. */ +typedef enum _MPT_RATE_INDEX +{ + /* CCK rate. */ + MPT_RATE_1M, /* 0 */ + MPT_RATE_2M, + MPT_RATE_55M, + MPT_RATE_11M, /* 3 */ + + /* OFDM rate. */ + MPT_RATE_6M, /* 4 */ + MPT_RATE_9M, + MPT_RATE_12M, + MPT_RATE_18M, + MPT_RATE_24M, + MPT_RATE_36M, + MPT_RATE_48M, + MPT_RATE_54M, /* 11 */ + + /* HT rate. */ + MPT_RATE_MCS0, /* 12 */ + MPT_RATE_MCS1, + MPT_RATE_MCS2, + MPT_RATE_MCS3, + MPT_RATE_MCS4, + MPT_RATE_MCS5, + MPT_RATE_MCS6, + MPT_RATE_MCS7, /* 19 */ + MPT_RATE_MCS8, + MPT_RATE_MCS9, + MPT_RATE_MCS10, + MPT_RATE_MCS11, + MPT_RATE_MCS12, + MPT_RATE_MCS13, + MPT_RATE_MCS14, + MPT_RATE_MCS15, /* 27 */ + MPT_RATE_LAST +}MPT_RATE_E, *PMPT_RATE_E; + +#if 0 +// Represent Channel Width in HT Capabilities +typedef enum _HT_CHANNEL_WIDTH { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_40 = 1, +}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; +#endif + +#define MAX_TX_PWR_INDEX_N_MODE 64 // 0x3F + +typedef enum _POWER_MODE_ { + POWER_LOW = 0, + POWER_NORMAL +}POWER_MODE; + + +#define RX_PKT_BROADCAST 1 +#define RX_PKT_DEST_ADDR 2 +#define RX_PKT_PHY_MATCH 3 + +#if 0 +#define RPTMaxCount 0x000FFFFF; + +// parameter 1 : BitMask +// bit 0 : OFDM PPDU +// bit 1 : OFDM False Alarm +// bit 2 : OFDM MPDU OK +// bit 3 : OFDM MPDU Fail +// bit 4 : CCK PPDU +// bit 5 : CCK False Alarm +// bit 6 : CCK MPDU ok +// bit 7 : CCK MPDU fail +// bit 8 : HT PPDU counter +// bit 9 : HT false alarm +// bit 10 : HT MPDU total +// bit 11 : HT MPDU OK +// bit 12 : HT MPDU fail +// bit 15 : RX full drop +typedef enum _RXPHY_BITMASK_ +{ + OFDM_PPDU_BIT = 0, + OFDM_FALSE_BIT, + OFDM_MPDU_OK_BIT, + OFDM_MPDU_FAIL_BIT, + CCK_PPDU_BIT, + CCK_FALSE_BIT, + CCK_MPDU_OK_BIT, + CCK_MPDU_FAIL_BIT, + HT_PPDU_BIT, + HT_FALSE_BIT, + HT_MPDU_BIT, + HT_MPDU_OK_BIT, + HT_MPDU_FAIL_BIT, +} RXPHY_BITMASK; +#endif + +typedef enum _ENCRY_CTRL_STATE_ { + HW_CONTROL, //hw encryption& decryption + SW_CONTROL, //sw encryption& decryption + HW_ENCRY_SW_DECRY, //hw encryption & sw decryption + SW_ENCRY_HW_DECRY //sw encryption & hw decryption +}ENCRY_CTRL_STATE; + +typedef enum _OFDM_TX_MODE { + OFDM_ALL_OFF = 0, + OFDM_ContinuousTx = 1, + OFDM_SingleCarrier = 2, + OFDM_SingleTone = 4, +} OFDM_TX_MODE; + +//======================================================================= +//extern struct mp_xmit_frame *alloc_mp_xmitframe(struct mp_priv *pmp_priv); +//extern int free_mp_xmitframe(struct xmit_priv *pxmitpriv, struct mp_xmit_frame *pmp_xmitframe); + +extern s32 init_mp_priv(PADAPTER padapter); +extern void free_mp_priv(struct mp_priv *pmp_priv); +extern s32 MPT_InitializeAdapter(PADAPTER padapter, u8 Channel); +extern void MPT_DeInitAdapter(PADAPTER padapter); +extern s32 mp_start_test(PADAPTER padapter); +extern void mp_stop_test(PADAPTER padapter); + +//======================================================================= +//extern void IQCalibrateBcut(PADAPTER pAdapter); + +//extern u32 bb_reg_read(PADAPTER Adapter, u16 offset); +//extern u8 bb_reg_write(PADAPTER Adapter, u16 offset, u32 value); +//extern u32 rf_reg_read(PADAPTER Adapter, u8 path, u8 offset); +//extern u8 rf_reg_write(PADAPTER Adapter, u8 path, u8 offset, u32 value); + +//extern u32 get_bb_reg(PADAPTER Adapter, u16 offset, u32 bitmask); +//extern u8 set_bb_reg(PADAPTER Adapter, u16 offset, u32 bitmask, u32 value); +//extern u32 get_rf_reg(PADAPTER Adapter, u8 path, u8 offset, u32 bitmask); +//extern u8 set_rf_reg(PADAPTER Adapter, u8 path, u8 offset, u32 bitmask, u32 value); + +extern u32 _read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask); +extern void _write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val); + +extern u32 read_macreg(_adapter *padapter, u32 addr, u32 sz); +extern void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz); +extern u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask); +extern void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val); +extern u32 read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr); +extern void write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 val); + +extern void SetChannel(PADAPTER pAdapter); +extern void SetBandwidth(PADAPTER pAdapter); +extern void SetTxPower(PADAPTER pAdapter); +extern void SetAntennaPathPower(PADAPTER pAdapter); +//extern void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset); +extern void SetDataRate(PADAPTER pAdapter); + +extern void SetAntenna(PADAPTER pAdapter); + +//extern void SetCrystalCap(PADAPTER pAdapter); + +extern s32 SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +extern void GetThermalMeter(PADAPTER pAdapter, u8 *value); + +extern void SetContinuousTx(PADAPTER pAdapter, u8 bStart); +extern void SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart); +extern void SetSingleToneTx(PADAPTER pAdapter, u8 bStart); +extern void SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); + +extern void fill_txdesc_for_mp(PADAPTER padapter, struct tx_desc *ptxdesc); +extern void SetPacketTx(PADAPTER padapter); +extern void SetPacketRx(PADAPTER pAdapter, u8 bStartRx); + +extern void ResetPhyRxPktCount(PADAPTER pAdapter); +extern u32 GetPhyRxPktReceived(PADAPTER pAdapter); +extern u32 GetPhyRxPktCRC32Error(PADAPTER pAdapter); + +extern s32 SetPowerTracking(PADAPTER padapter, u8 enable); +extern void GetPowerTracking(PADAPTER padapter, u8 *enable); + +extern u32 mp_query_psd(PADAPTER pAdapter, u8 *data); + + +extern void Hal_SetAntenna(PADAPTER pAdapter); +extern void Hal_SetBandwidth(PADAPTER pAdapter); + +extern void Hal_SetTxPower(PADAPTER pAdapter); +extern void Hal_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetSingleToneTx ( PADAPTER pAdapter , u8 bStart ); +extern void Hal_SetSingleCarrierTx (PADAPTER pAdapter, u8 bStart); +extern void Hal_SetContinuousTx (PADAPTER pAdapter, u8 bStart); +extern void Hal_SetBandwidth(PADAPTER pAdapter); + +extern void Hal_SetDataRate(PADAPTER pAdapter); +extern void Hal_SetChannel(PADAPTER pAdapter); +extern void Hal_SetAntennaPathPower(PADAPTER pAdapter); +extern s32 Hal_SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +extern s32 Hal_SetPowerTracking(PADAPTER padapter, u8 enable); +extern void Hal_GetPowerTracking(PADAPTER padapter, u8 * enable); +extern void Hal_GetThermalMeter(PADAPTER pAdapter, u8 *value); +extern void Hal_mpt_SwitchRfSetting(PADAPTER pAdapter); +extern void Hal_MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14); +extern void Hal_MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven); +extern void Hal_SetCCKTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_SetOFDMTxPower(PADAPTER pAdapter, u8 * TxPower); +extern void Hal_TriggerRFThermalMeter(PADAPTER pAdapter); +extern u8 Hal_ReadRFThermalMeter(PADAPTER pAdapter); +extern void Hal_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart); +extern void Hal_ProSetCrystalCap (PADAPTER pAdapter , u32 CrystalCapVal); + +#endif //_RTW_MP_H_ + diff --git a/rtl8192cu-fixes/include/rtw_mp_ioctl.h b/rtl8192cu-fixes/include/rtw_mp_ioctl.h new file mode 100755 index 00000000..962bc38e --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_mp_ioctl.h @@ -0,0 +1,596 @@ +/****************************************************************************** + * + * 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 _RTW_MP_IOCTL_H_ +#define _RTW_MP_IOCTL_H_ + +//#include +//#include +#include +#include +#include +#include +#include +#include + +#if 0 +#define TESTFWCMDNUMBER 1000000 +#define TEST_H2CINT_WAIT_TIME 500 +#define TEST_C2HINT_WAIT_TIME 500 +#define HCI_TEST_SYSCFG_HWMASK 1 +#define _BUSCLK_40M (4 << 2) +#endif +//------------------------------------------------------------------------------ +typedef struct CFG_DBG_MSG_STRUCT { + u32 DebugLevel; + u32 DebugComponent_H32; + u32 DebugComponent_L32; +}CFG_DBG_MSG_STRUCT,*PCFG_DBG_MSG_STRUCT; + +typedef struct _RW_REG { + u32 offset; + u32 width; + u32 value; +}mp_rw_reg,RW_Reg, *pRW_Reg; + +//for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM +typedef struct _EEPROM_RW_PARAM { + u32 offset; + u16 value; +}eeprom_rw_param,EEPROM_RWParam, *pEEPROM_RWParam; + +typedef struct _EFUSE_ACCESS_STRUCT_ { + u16 start_addr; + u16 cnts; + u8 data[0]; +}EFUSE_ACCESS_STRUCT, *PEFUSE_ACCESS_STRUCT; + +typedef struct _BURST_RW_REG { + u32 offset; + u32 len; + u8 Data[256]; +}burst_rw_reg,Burst_RW_Reg, *pBurst_RW_Reg; + +typedef struct _USB_VendorReq{ + u8 bRequest; + u16 wValue; + u16 wIndex; + u16 wLength; + u8 u8Dir;//0:OUT, 1:IN + u8 u8InData; +}usb_vendor_req, USB_VendorReq, *pUSB_VendorReq; + +typedef struct _DR_VARIABLE_STRUCT_ { + u8 offset; + u32 variable; +}DR_VARIABLE_STRUCT; + +//int mp_start_joinbss(_adapter *padapter, NDIS_802_11_SSID *pssid); + +//void _irqlevel_changed_(_irqL *irqlevel, /*BOOLEAN*/unsigned char bLower); +#ifdef PLATFORM_OS_XP +static void _irqlevel_changed_(_irqL *irqlevel, u8 bLower) +{ + + if (bLower == LOWER) { + *irqlevel = KeGetCurrentIrql(); + + if (*irqlevel > PASSIVE_LEVEL) { + KeLowerIrql(PASSIVE_LEVEL); + } + } else { + if (KeGetCurrentIrql() == PASSIVE_LEVEL) { + KeRaiseIrql(DISPATCH_LEVEL, irqlevel); + } + } + +} +#else +#define _irqlevel_changed_(a,b) +#endif + +//oid_rtl_seg_81_80_00 +NDIS_STATUS oid_rt_pro_set_data_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_start_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_stop_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_81_80_20 +NDIS_STATUS oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_modulation_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_81_87 +NDIS_STATUS oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_81_85 +NDIS_STATUS oid_rt_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); + + +// oid_rtl_seg_87_11_00 +NDIS_STATUS oid_rt_pro8711_join_bss_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_burst_read_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_burst_write_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write_txcmd_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write16_eeprom_hdl (struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_rd_attrib_mem_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_wr_attrib_mem_hdl (struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_poll_rx_status_hdl(struct oid_par_priv* poid_par_priv); +// oid_rtl_seg_87_11_20 +NDIS_STATUS oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_tssi_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_87_11_50 +NDIS_STATUS oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_87_11_F0 +NDIS_STATUS oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_87_12_00 +NDIS_STATUS oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_add_sta_info_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); + +NDIS_STATUS oid_rt_set_bandwidth_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_crystal_cap_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_rx_packet_type_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_efuse_max_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_get_thermal_meter_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_set_power_down_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_get_power_mode_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv); + +#ifdef _RTW_MP_IOCTL_C_ + +const struct oid_obj_priv oid_rtl_seg_81_80_00[] = +{ + {1, &oid_null_function}, //0x00 OID_RT_PRO_RESET_DUT + {1, &oid_rt_pro_set_data_rate_hdl}, //0x01 + {1, &oid_rt_pro_start_test_hdl}, //0x02 + {1, &oid_rt_pro_stop_test_hdl}, //0x03 + {1, &oid_null_function}, //0x04 OID_RT_PRO_SET_PREAMBLE + {1, &oid_null_function}, //0x05 OID_RT_PRO_SET_SCRAMBLER + {1, &oid_null_function}, //0x06 OID_RT_PRO_SET_FILTER_BB + {1, &oid_null_function}, //0x07 OID_RT_PRO_SET_MANUAL_DIVERSITY_BB + {1, &oid_rt_pro_set_channel_direct_call_hdl}, //0x08 + {1, &oid_null_function}, //0x09 OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL + {1, &oid_null_function}, //0x0A OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL + {1, &oid_rt_pro_set_continuous_tx_hdl}, //0x0B OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL + {1, &oid_rt_pro_set_single_carrier_tx_hdl}, //0x0C OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS + {1, &oid_null_function}, //0x0D OID_RT_PRO_SET_TX_ANTENNA_BB + {1, &oid_rt_pro_set_antenna_bb_hdl}, //0x0E + {1, &oid_null_function}, //0x0F OID_RT_PRO_SET_CR_SCRAMBLER + {1, &oid_null_function}, //0x10 OID_RT_PRO_SET_CR_NEW_FILTER + {1, &oid_rt_pro_set_tx_power_control_hdl}, //0x11 OID_RT_PRO_SET_TX_POWER_CONTROL + {1, &oid_null_function}, //0x12 OID_RT_PRO_SET_CR_TX_CONFIG + {1, &oid_null_function}, //0x13 OID_RT_PRO_GET_TX_POWER_CONTROL + {1, &oid_null_function}, //0x14 OID_RT_PRO_GET_CR_SIGNAL_QUALITY + {1, &oid_null_function}, //0x15 OID_RT_PRO_SET_CR_SETPOINT + {1, &oid_null_function}, //0x16 OID_RT_PRO_SET_INTEGRATOR + {1, &oid_null_function}, //0x17 OID_RT_PRO_SET_SIGNAL_QUALITY + {1, &oid_null_function}, //0x18 OID_RT_PRO_GET_INTEGRATOR + {1, &oid_null_function}, //0x19 OID_RT_PRO_GET_SIGNAL_QUALITY + {1, &oid_null_function}, //0x1A OID_RT_PRO_QUERY_EEPROM_TYPE + {1, &oid_null_function}, //0x1B OID_RT_PRO_WRITE_MAC_ADDRESS + {1, &oid_null_function}, //0x1C OID_RT_PRO_READ_MAC_ADDRESS + {1, &oid_null_function}, //0x1D OID_RT_PRO_WRITE_CIS_DATA + {1, &oid_null_function}, //0x1E OID_RT_PRO_READ_CIS_DATA + {1, &oid_null_function} //0x1F OID_RT_PRO_WRITE_POWER_CONTROL + +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_20[] = +{ + {1, &oid_null_function}, //0x20 OID_RT_PRO_READ_POWER_CONTROL + {1, &oid_null_function}, //0x21 OID_RT_PRO_WRITE_EEPROM + {1, &oid_null_function}, //0x22 OID_RT_PRO_READ_EEPROM + {1, &oid_rt_pro_reset_tx_packet_sent_hdl}, //0x23 + {1, &oid_rt_pro_query_tx_packet_sent_hdl}, //0x24 + {1, &oid_rt_pro_reset_rx_packet_received_hdl}, //0x25 + {1, &oid_rt_pro_query_rx_packet_received_hdl}, //0x26 + {1, &oid_rt_pro_query_rx_packet_crc32_error_hdl}, //0x27 + {1, &oid_null_function}, //0x28 OID_RT_PRO_QUERY_CURRENT_ADDRESS + {1, &oid_null_function}, //0x29 OID_RT_PRO_QUERY_PERMANENT_ADDRESS + {1, &oid_null_function}, //0x2A OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS + {1, &oid_rt_pro_set_carrier_suppression_tx_hdl},//0x2B OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX + {1, &oid_null_function}, //0x2C OID_RT_PRO_RECEIVE_PACKET + {1, &oid_null_function}, //0x2D OID_RT_PRO_WRITE_EEPROM_BYTE + {1, &oid_null_function}, //0x2E OID_RT_PRO_READ_EEPROM_BYTE + {1, &oid_rt_pro_set_modulation_hdl} //0x2F + +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_40[] = +{ + {1, &oid_null_function}, //0x40 + {1, &oid_null_function}, //0x41 + {1, &oid_null_function}, //0x42 + {1, &oid_rt_pro_set_single_tone_tx_hdl}, //0x43 + {1, &oid_null_function}, //0x44 + {1, &oid_null_function} //0x45 +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_80[] = +{ + {1, &oid_null_function}, //0x80 OID_RT_DRIVER_OPTION + {1, &oid_null_function}, //0x81 OID_RT_RF_OFF + {1, &oid_null_function} //0x82 OID_RT_AUTH_STATUS + +}; + +const struct oid_obj_priv oid_rtl_seg_81_85[] = +{ + {1, &oid_rt_wireless_mode_hdl} //0x00 OID_RT_WIRELESS_MODE +}; + +struct oid_obj_priv oid_rtl_seg_81_87[] = +{ + {1, &oid_null_function}, //0x80 OID_RT_PRO8187_WI_POLL + {1, &oid_rt_pro_write_bb_reg_hdl}, //0x81 + {1, &oid_rt_pro_read_bb_reg_hdl}, //0x82 + {1, &oid_rt_pro_write_rf_reg_hdl}, //0x82 + {1, &oid_rt_pro_read_rf_reg_hdl} //0x83 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_00[] = +{ + {1, &oid_rt_pro8711_join_bss_hdl}, //0x00 //S + {1, &oid_rt_pro_read_register_hdl}, //0x01 + {1, &oid_rt_pro_write_register_hdl}, //0x02 + {1, &oid_rt_pro_burst_read_register_hdl}, //0x03 + {1, &oid_rt_pro_burst_write_register_hdl}, //0x04 + {1, &oid_rt_pro_write_txcmd_hdl}, //0x05 + {1, &oid_rt_pro_read16_eeprom_hdl}, //0x06 + {1, &oid_rt_pro_write16_eeprom_hdl}, //0x07 + {1, &oid_null_function}, //0x08 OID_RT_PRO_H2C_SET_COMMAND + {1, &oid_null_function}, //0x09 OID_RT_PRO_H2C_QUERY_RESULT + {1, &oid_rt_pro8711_wi_poll_hdl}, //0x0A + {1, &oid_rt_pro8711_pkt_loss_hdl}, //0x0B + {1, &oid_rt_rd_attrib_mem_hdl}, //0x0C + {1, &oid_rt_wr_attrib_mem_hdl}, //0x0D + {1, &oid_null_function}, //0x0E + {1, &oid_null_function}, //0x0F + {1, &oid_null_function}, //0x10 OID_RT_PRO_H2C_CMD_MODE + {1, &oid_null_function}, //0x11 OID_RT_PRO_H2C_CMD_RSP_MODE + {1, &oid_null_function}, //0X12 OID_RT_PRO_WAIT_C2H_EVENT + {1, &oid_null_function}, //0X13 OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST + {1, &oid_null_function}, //0X14 OID_RT_PRO_SCSI_ACCESS_TEST + {1, &oid_null_function}, //0X15 OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT + {1, &oid_null_function}, //0X16 OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN + {1, &oid_null_function}, //0X17 OID_RT_RRO_RX_PKT_VIA_IOCTRL + {1, &oid_null_function}, //0X18 OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL + {1, &oid_null_function}, //0X19 OID_RT_RPO_SET_PWRMGT_TEST + {1, &oid_null_function}, //0X1A + {1, &oid_null_function}, //0X1B OID_RT_PRO_QRY_PWRMGT_TEST + {1, &oid_null_function}, //0X1C OID_RT_RPO_ASYNC_RWIO_TEST + {1, &oid_null_function}, //0X1D OID_RT_RPO_ASYNC_RWIO_POLL + {1, &oid_rt_pro_set_rf_intfs_hdl}, //0X1E + {1, &oid_rt_poll_rx_status_hdl} //0X1F +}; + +struct oid_obj_priv oid_rtl_seg_87_11_20[] = +{ + {1, &oid_rt_pro_cfg_debug_message_hdl}, //0x20 + {1, &oid_rt_pro_set_data_rate_ex_hdl}, //0x21 + {1, &oid_rt_pro_set_basic_rate_hdl}, //0x22 + {1, &oid_rt_pro_read_tssi_hdl}, //0x23 + {1, &oid_rt_pro_set_power_tracking_hdl} //0x24 +}; + + +struct oid_obj_priv oid_rtl_seg_87_11_50[] = +{ + {1, &oid_rt_pro_qry_pwrstate_hdl}, //0x50 + {1, &oid_rt_pro_set_pwrstate_hdl} //0x51 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_80[] = +{ + {1, &oid_null_function} //0x80 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_B0[] = +{ + {1, &oid_null_function} //0xB0 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_F0[] = +{ + {1, &oid_null_function}, //0xF0 + {1, &oid_null_function}, //0xF1 + {1, &oid_null_function}, //0xF2 + {1, &oid_null_function}, //0xF3 + {1, &oid_null_function}, //0xF4 + {1, &oid_null_function}, //0xF5 + {1, &oid_null_function}, //0xF6 + {1, &oid_null_function}, //0xF7 + {1, &oid_null_function}, //0xF8 + {1, &oid_null_function}, //0xF9 + {1, &oid_null_function}, //0xFA + {1, &oid_rt_pro_h2c_set_rate_table_hdl}, //0xFB + {1, &oid_rt_pro_h2c_get_rate_table_hdl}, //0xFC + {1, &oid_null_function}, //0xFD + {1, &oid_null_function}, //0xFE OID_RT_PRO_H2C_C2H_LBK_TEST + {1, &oid_null_function} //0xFF + +}; + +struct oid_obj_priv oid_rtl_seg_87_12_00[]= +{ + {1, &oid_rt_pro_encryption_ctrl_hdl}, //0x00 Q&S + {1, &oid_rt_pro_add_sta_info_hdl}, //0x01 S + {1, &oid_rt_pro_dele_sta_info_hdl}, //0x02 S + {1, &oid_rt_pro_query_dr_variable_hdl}, //0x03 Q + {1, &oid_rt_pro_rx_packet_type_hdl}, //0x04 Q,S + {1, &oid_rt_pro_read_efuse_hdl}, //0x05 Q OID_RT_PRO_READ_EFUSE + {1, &oid_rt_pro_write_efuse_hdl}, //0x06 S OID_RT_PRO_WRITE_EFUSE + {1, &oid_rt_pro_rw_efuse_pgpkt_hdl}, //0x07 Q,S + {1, &oid_rt_get_efuse_current_size_hdl}, //0x08 Q + {1, &oid_rt_set_bandwidth_hdl}, //0x09 + {1, &oid_rt_set_crystal_cap_hdl}, //0x0a + {1, &oid_rt_set_rx_packet_type_hdl}, //0x0b S + {1, &oid_rt_get_efuse_max_size_hdl}, //0x0c + {1, &oid_rt_pro_set_tx_agc_offset_hdl}, //0x0d + {1, &oid_rt_pro_set_pkt_test_mode_hdl}, //0x0e + {1, &oid_null_function}, //0x0f OID_RT_PRO_FOR_EVM_TEST_SETTING + {1, &oid_rt_get_thermal_meter_hdl}, //0x10 Q OID_RT_PRO_GET_THERMAL_METER + {1, &oid_rt_reset_phy_rx_packet_count_hdl}, //0x11 S OID_RT_RESET_PHY_RX_PACKET_COUNT + {1, &oid_rt_get_phy_rx_packet_received_hdl}, //0x12 Q OID_RT_GET_PHY_RX_PACKET_RECEIVED + {1, &oid_rt_get_phy_rx_packet_crc32_error_hdl}, //0x13 Q OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR + {1, &oid_rt_set_power_down_hdl}, //0x14 Q OID_RT_SET_POWER_DOWN + {1, &oid_rt_get_power_mode_hdl} //0x15 Q OID_RT_GET_POWER_MODE +}; + +#else /* _RTL871X_MP_IOCTL_C_ */ + +extern struct oid_obj_priv oid_rtl_seg_81_80_00[32]; +extern struct oid_obj_priv oid_rtl_seg_81_80_20[16]; +extern struct oid_obj_priv oid_rtl_seg_81_80_40[6]; +extern struct oid_obj_priv oid_rtl_seg_81_80_80[3]; + +extern struct oid_obj_priv oid_rtl_seg_81_85[1]; +extern struct oid_obj_priv oid_rtl_seg_81_87[5]; + +extern struct oid_obj_priv oid_rtl_seg_87_11_00[32]; +extern struct oid_obj_priv oid_rtl_seg_87_11_20[5]; +extern struct oid_obj_priv oid_rtl_seg_87_11_50[2]; +extern struct oid_obj_priv oid_rtl_seg_87_11_80[1]; +extern struct oid_obj_priv oid_rtl_seg_87_11_B0[1]; +extern struct oid_obj_priv oid_rtl_seg_87_11_F0[16]; + +extern struct oid_obj_priv oid_rtl_seg_87_12_00[32]; + +#endif /* _RTL871X_MP_IOCTL_C_ */ + +struct rwreg_param{ + u32 offset; + u32 width; + u32 value; +}; + +struct bbreg_param{ + u32 offset; + u32 phymask; + u32 value; +}; +/* +struct rfchannel_param{ + u32 ch; + u32 modem; +}; +*/ +struct txpower_param{ + u32 pwr_index; +}; + + +struct datarate_param{ + u32 rate_index; +}; + + +struct rfintfs_parm { + u32 rfintfs; +}; + +typedef struct _mp_xmit_parm_ { + u8 enable; + u32 count; + u16 length; + u8 payload_type; + u8 da[ETH_ALEN]; +}MP_XMIT_PARM, *PMP_XMIT_PARM; + +struct mp_xmit_packet { + u32 len; + u32 mem[MAX_MP_XMITBUF_SZ >> 2]; +}; + +struct psmode_param { + u32 ps_mode; + u32 smart_ps; +}; + +//for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM +struct eeprom_rw_param { + u32 offset; + u16 value; +}; + +struct mp_ioctl_handler { + u32 paramsize; + u32 (*handler)(struct oid_par_priv* poid_par_priv); + u32 oid; +}; + +struct mp_ioctl_param{ + u32 subcode; + u32 len; + u8 data[0]; +}; + +#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ + +enum RTL871X_MP_IOCTL_SUBCODE { + GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ + GEN_MP_IOCTL_SUBCODE(MP_STOP), + GEN_MP_IOCTL_SUBCODE(READ_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_REG), + GEN_MP_IOCTL_SUBCODE(READ_BB_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), /*5*/ + GEN_MP_IOCTL_SUBCODE(READ_RF_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), + GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), + GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), + GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*10*/ + GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), + GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), + GEN_MP_IOCTL_SUBCODE(CNTU_TX), + GEN_MP_IOCTL_SUBCODE(SC_TX), + GEN_MP_IOCTL_SUBCODE(CS_TX), /*15*/ + GEN_MP_IOCTL_SUBCODE(ST_TX), + GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), + GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), + GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), + GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*20*/ + GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), + GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), + GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), + GEN_MP_IOCTL_SUBCODE(EFUSE), + GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*25*/ + GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), + GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), + GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), + GEN_MP_IOCTL_SUBCODE(SET_PTM), + GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*30*/ + GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO), + GEN_MP_IOCTL_SUBCODE(SET_DM_BT), /*35*/ + GEN_MP_IOCTL_SUBCODE(DEL_BA), /*36*/ + GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS), /*37*/ + MAX_MP_IOCTL_SUBCODE, +}; + +u32 mp_ioctl_xmit_packet_hdl(struct oid_par_priv* poid_par_priv); + +#ifdef _RTW_MP_IOCTL_C_ + +#define GEN_MP_IOCTL_HANDLER(sz, hdl, oid) {sz, hdl, oid}, + +#define EXT_MP_IOCTL_HANDLER(sz, subcode, oid) {sz, mp_ioctl_ ## subcode ## _hdl, oid}, + + +struct mp_ioctl_handler mp_ioctl_hdl[] = { + +/*0*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST) + + GEN_MP_IOCTL_HANDLER(sizeof(struct rwreg_param), oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER) + GEN_MP_IOCTL_HANDLER(sizeof(struct rwreg_param), oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER) + GEN_MP_IOCTL_HANDLER(sizeof(struct bb_reg_param), oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG) +/*5*/ GEN_MP_IOCTL_HANDLER(sizeof(struct bb_reg_param), oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG) + GEN_MP_IOCTL_HANDLER(sizeof(struct rf_reg_param), oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY) + GEN_MP_IOCTL_HANDLER(sizeof(struct rf_reg_param), oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL) + GEN_MP_IOCTL_HANDLER(sizeof(struct txpower_param), oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL) +/*10*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX) +/*15*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX) + + EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE) + GEN_MP_IOCTL_HANDLER(0, oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT) +/*20*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR) + + GEN_MP_IOCTL_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) + GEN_MP_IOCTL_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) + GEN_MP_IOCTL_HANDLER(sizeof(EFUSE_ACCESS_STRUCT), oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE) +/*25*/ GEN_MP_IOCTL_HANDLER(0, oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER) + GEN_MP_IOCTL_HANDLER(sizeof(u8), oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING) +/*30*/ GEN_MP_IOCTL_HANDLER(sizeof(u8), oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN) +/*31*/ GEN_MP_IOCTL_HANDLER(0, oid_rt_pro_trigger_gpio_hdl, 0) + + +}; + +#else /* _RTW_MP_IOCTL_C_ */ + +extern struct mp_ioctl_handler mp_ioctl_hdl[]; + +#endif /* _RTW_MP_IOCTL_C_ */ + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h b/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h new file mode 100755 index 00000000..0b47cb5c --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h @@ -0,0 +1,1097 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __RTW_MP_PHY_REGDEF_H_ + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __RTW_MP_PHY_REGDEF_H_ +#define __RTW_MP_PHY_REGDEF_H_ + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +//#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +//#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 +//#define rFPGA0_XC_RFTiming 0x818 +//#define rFPGA0_XD_RFTiming 0x81c + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rFPGA0_XC_HSSIParameter1 0x830 +#define rFPGA0_XC_HSSIParameter2 0x834 +#define rFPGA0_XD_HSSIParameter1 0x838 +#define rFPGA0_XD_HSSIParameter2 0x83c +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 +#define rFPGA0_XC_LSSIParameter 0x848 +#define rFPGA0_XD_LSSIParameter 0x84c + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rFPGA0_XC_RFInterfaceOE 0x868 +#define rFPGA0_XD_RFInterfaceOE 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_RxIQExtAnta 0xca0 + +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 + + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_Rate18_06 0xe00 +#define rTxAGC_Rate54_24 0xe04 +#define rTxAGC_CCK_Mcs32 0xe08 +#define rTxAGC_Mcs03_Mcs00 0xe10 +#define rTxAGC_Mcs07_Mcs04 0xe14 +#define rTxAGC_Mcs11_Mcs08 0xe18 +#define rTxAGC_Mcs15_Mcs12 0xe1c + +// Analog- control in RX_WAIT_CCA : REG: EE0 [Analog- Power & Control Register] +#define rRx_Wait_CCCA 0xe70 +#define rAnapar_Ctrl_BB 0xee0 + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define RTL92SE_FPGA_VERIFY 0 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +//#if (RTL92SE_FPGA_VERIFY == 1) +#define rZebra1_Channel 0x7 // RF channel switch +//#else + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 +#if (RTL92SE_FPGA_VERIFY == 1) +#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address // Reg 0x824 rFPGA0_XA_HSSIParameter2 +#else +#define bLSSIReadAddress 0x7f800000 // T65 RF +#endif +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal +#if (RTL92SE_FPGA_VERIFY == 1) +#define bLSSIReadBackData 0xfff // Reg 0x8a0 rFPGA0_XA_LSSIReadBack +#else +#define bLSSIReadBackData 0xfffff // T65 RF +#endif +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +#define bTxAGCRate18_06 0x7f7f7f7f // Useless +#define bTxAGCRate54_24 0x7f7f7f7f +#define bTxAGCRateMCS32 0x7f +#define bTxAGCRateCCK 0x7f00 +#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f +#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f +#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f +#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f +#define bMask12Bits 0xfff + +//for PutRFRegsetting & GetRFRegSetting BitMask +#if (RTL92SE_FPGA_VERIFY == 1) +//#define bMask12Bits 0xfff // RF Reg mask bits +//#define bMask20Bits 0xfff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfff +#else +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff +#endif +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#if 0 +#define ANTENNA_A 0x1 // Useless +#define ANTENNA_B 0x2 +#define ANTENNA_AB 0x3 // ANTENNA_A|ANTENNA_B + +#define ANTENNA_C 0x4 +#define ANTENNA_D 0x8 +#endif + +#define RCR_AAP BIT(0) // accept all physical address +#define RCR_APM BIT(1) // accept physical match +#define RCR_AM BIT(2) // accept multicast +#define RCR_AB BIT(3) // accept broadcast +#define RCR_ACRC32 BIT(5) // accept error packet +#define RCR_9356SEL BIT(6) +#define RCR_AICV BIT(12) // Accept ICV error packet +#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) // Rx FIFO threshold +#define RCR_ADF BIT(18) // Accept Data(frame type) frame +#define RCR_ACF BIT(19) // Accept control frame +#define RCR_AMF BIT(20) // Accept management frame +#define RCR_ADD3 BIT(21) +#define RCR_APWRMGT BIT(22) // Accept power management packet +#define RCR_CBSSID BIT(23) // Accept BSSID match packet +#define RCR_ENMARP BIT(28) // enable mac auto reset phy +#define RCR_EnCS1 BIT(29) // enable carrier sense method 1 +#define RCR_EnCS2 BIT(30) // enable carrier sense method 2 +#define RCR_OnlyErlPkt BIT(31) // Rx Early mode is performed for packet size greater than 1536 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8192SPHYREG_H + diff --git a/rtl8192cu-fixes/include/rtw_p2p.h b/rtl8192cu-fixes/include/rtw_p2p.h new file mode 100755 index 00000000..4249bc96 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_p2p.h @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * 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 __RTW_P2P_H_ +#define __RTW_P2P_H_ + +#include + +u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr ); +u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code); +u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +#ifdef CONFIG_WFD +u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled); +u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +#endif //CONFIG_WFD + +u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta); +u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe); +u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); + +void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType); + +#ifdef CONFIG_P2P_PS +void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength); +void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state); +u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue); +#endif // CONFIG_P2P_PS + +#ifdef CONFIG_IOCTL_CFG80211 +void rtw_init_cfg80211_wifidirect_info( _adapter* padapter); +int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx); +void rtw_append_wfd_ie(_adapter *padapter, u8 *buf, u32 *len); +#endif //CONFIG_IOCTL_CFG80211 + +void reset_global_wifidirect_info( _adapter* padapter ); +int rtw_init_wifi_display_info(_adapter* padapter); +void rtw_init_wifidirect_timers(_adapter* padapter); +void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr); +void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role); +int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role); + +static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + if(wdinfo->p2p_state != state) { + //wdinfo->pre_p2p_state = wdinfo->p2p_state; + wdinfo->p2p_state = state; + } +} +static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + if(wdinfo->pre_p2p_state != state) { + wdinfo->pre_p2p_state = state; + } +} +#if 0 +static inline void _rtw_p2p_restore_state(struct wifidirect_info *wdinfo) +{ + if(wdinfo->pre_p2p_state != -1) { + wdinfo->p2p_state = wdinfo->pre_p2p_state; + wdinfo->pre_p2p_state = -1; + } +} +#endif +static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role) +{ + if(wdinfo->role != role) { + wdinfo->role = role; + } +} +static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo) +{ + return wdinfo->p2p_state; +} +static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo) +{ + return wdinfo->pre_p2p_state; +} +static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo) +{ + return wdinfo->role; +} +static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + return wdinfo->p2p_state == state; +} +static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role) +{ + return wdinfo->role == role; +} + +#ifdef CONFIG_DBG_P2P +void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line); +void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line); +//void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line); +void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line); +#define rtw_p2p_set_state(wdinfo, state) dbg_rtw_p2p_set_state(wdinfo, state, __FUNCTION__, __LINE__) +#define rtw_p2p_set_pre_state(wdinfo, state) dbg_rtw_p2p_set_pre_state(wdinfo, state, __FUNCTION__, __LINE__) +#define rtw_p2p_set_role(wdinfo, role) dbg_rtw_p2p_set_role(wdinfo, role, __FUNCTION__, __LINE__) +//#define rtw_p2p_restore_state(wdinfo) dbg_rtw_p2p_restore_state(wdinfo, __FUNCTION__, __LINE__) +#else //CONFIG_DBG_P2P +#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state) +#define rtw_p2p_set_pre_state(wdinfo, state) _rtw_p2p_set_pre_state(wdinfo, state) +#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role) +//#define rtw_p2p_restore_state(wdinfo) _rtw_p2p_restore_state(wdinfo) +#endif //CONFIG_DBG_P2P + +#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo) +#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo) +#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo) +#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state) +#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role) + +#define rtw_p2p_findphase_ex_set(wdinfo, value) \ + (wdinfo)->find_phase_state_exchange_cnt = (value) + +//is this find phase exchange for social channel scan? +#define rtw_p2p_findphase_ex_is_social(wdinfo) \ + (wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST + +//should we need find phase exchange anymore? +#define rtw_p2p_findphase_ex_is_needed(wdinfo) \ + ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \ + (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE) + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_pwrctrl.h b/rtl8192cu-fixes/include/rtw_pwrctrl.h new file mode 100755 index 00000000..a4cb292e --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_pwrctrl.h @@ -0,0 +1,362 @@ +/****************************************************************************** + * + * 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 __RTW_PWRCTRL_H_ +#define __RTW_PWRCTRL_H_ + +#include +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif //CONFIG_HAS_EARLYSUSPEND + + +#define FW_PWR0 0 +#define FW_PWR1 1 +#define FW_PWR2 2 +#define FW_PWR3 3 + + +#define HW_PWR0 7 +#define HW_PWR1 6 +#define HW_PWR2 2 +#define HW_PWR3 0 +#define HW_PWR4 8 + +#define FW_PWRMSK 0x7 + + +#define XMIT_ALIVE BIT(0) +#define RECV_ALIVE BIT(1) +#define CMD_ALIVE BIT(2) +#define EVT_ALIVE BIT(3) + + +enum Power_Mgnt +{ + PS_MODE_ACTIVE = 0 , + PS_MODE_MIN , + PS_MODE_MAX , + PS_MODE_DTIM , + PS_MODE_VOIP , + PS_MODE_UAPSD_WMM , + PS_MODE_UAPSD , + PS_MODE_IBSS , + PS_MODE_WWLAN , + PM_Radio_Off , + PM_Card_Disable , + PS_MODE_NUM +}; + + +/* + BIT[2:0] = HW state + BIT[3] = Protocol PS state, 0: register active state , 1: register sleep state + BIT[4] = sub-state +*/ + +#define PS_DPS BIT(0) +#define PS_LCLK (PS_DPS) +#define PS_RF_OFF BIT(1) +#define PS_ALL_ON BIT(2) +#define PS_ST_ACTIVE BIT(3) + +#define PS_ISR_ENABLE BIT(4) +#define PS_IMR_ENABLE BIT(5) +#define PS_ACK BIT(6) +#define PS_TOGGLE BIT(7) + +#define PS_STATE_MASK (0x0F) +#define PS_STATE_HW_MASK (0x07) +#define PS_SEQ_MASK (0xc0) + +#define PS_STATE(x) (PS_STATE_MASK & (x)) +#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) +#define PS_SEQ(x) (PS_SEQ_MASK & (x)) + +#define PS_STATE_S0 (PS_DPS) +#define PS_STATE_S1 (PS_LCLK) +#define PS_STATE_S2 (PS_RF_OFF) +#define PS_STATE_S3 (PS_ALL_ON) +#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) + + +#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) +#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) +#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) + + +struct reportpwrstate_parm { + unsigned char mode; + unsigned char state; //the CPWM value + unsigned short rsvd; +}; + + +typedef _sema _pwrlock; + + +__inline static void _init_pwrlock(_pwrlock *plock) +{ + _rtw_init_sema(plock, 1); +} + +__inline static void _free_pwrlock(_pwrlock *plock) +{ + _rtw_free_sema(plock); +} + + +__inline static void _enter_pwrlock(_pwrlock *plock) +{ + _rtw_down_sema(plock); +} + + +__inline static void _exit_pwrlock(_pwrlock *plock) +{ + _rtw_up_sema(plock); +} + +#define LPS_DELAY_TIME 1*HZ // 1 sec + +#define EXE_PWR_NONE 0x01 +#define EXE_PWR_IPS 0x02 +#define EXE_PWR_LPS 0x04 + +// RF state. +typedef enum _rt_rf_power_state +{ + rf_on, // RF is on after RFSleep or RFOff + rf_sleep, // 802.11 Power Save mode + rf_off, // HW/SW Radio OFF or Inactive Power Save + //=====Add the new RF state above this line=====// + rf_max +}rt_rf_power_state; + +// RF Off Level for IPS or HW/SW radio off +#define RT_RF_OFF_LEVL_ASPM BIT(0) // PCI ASPM +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) // PCI clock request +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) // PCI D3 mode +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) // NIC halt, re-initialize hw parameters +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) // FW free, re-download the FW +#define RT_RF_OFF_LEVL_FW_32K BIT(5) // FW in 32k +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) // Always enable ASPM and Clock Req in initialization. +#define RT_RF_LPS_DISALBE_2R BIT(30) // When LPS is on, disable 2R if no packet is received or transmittd. +#define RT_RF_LPS_LEVEL_ASPM BIT(31) // LPS with ASPM + +#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) ((ppsc->cur_ps_level & _PS_FLAG) ? _TRUE : _FALSE) +#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level |= _PS_FLAG) + + +enum _PS_BBRegBackup_ { + PSBBREG_RF0 = 0, + PSBBREG_RF1, + PSBBREG_RF2, + PSBBREG_AFE0, + PSBBREG_TOTALCNT +}; + +enum { // for ips_mode + IPS_NONE=0, + IPS_NORMAL, + IPS_LEVEL_2, +}; + +struct pwrctrl_priv +{ + _pwrlock lock; + volatile u8 rpwm; // requested power state for fw + volatile u8 cpwm; // fw current power state. updated when 1. read from HCPWM 2. driver lowers power level + volatile u8 tog; // toggling + volatile u8 cpwm_tog; // toggling + u8 pwr_mode; + u8 smart_ps; + u32 alives; + + u8 b_hw_radio_off; + u8 reg_rfoff; + u8 reg_pdnmode; //powerdown mode + u32 rfoff_reason; + + //RF OFF Level + u32 cur_ps_level; + u32 reg_rfps_level; + + + +#ifdef CONFIG_PCI_HCI + //just for PCIE ASPM + u8 b_support_aspm; // If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. + u8 b_support_backdoor; + + //just for PCIE ASPM + u8 const_amdpci_aspm; +#endif + + uint ips_enter_cnts; + uint ips_leave_cnts; + + u8 ips_mode; + u8 ips_mode_req; // used to accept the mode setting request, will update to ipsmode later + uint bips_processing; + u32 ips_deny_time; /* will deny IPS when system time is smaller than this */ + u8 ps_processing; /* temporarily used to mark whether in rtw_ps_processor */ + + u8 bLeisurePs; + u8 LpsIdleCount; + u8 power_mgnt; + u8 bFwCurrentInPSMode; + u32 DelayLPSLastTimeStamp; + + s32 pnp_current_pwr_state; + u8 pnp_bstop_trx; + + + u8 bInternalAutoSuspend; + u8 bInSuspend; + u8 bSupportRemoteWakeup; +#ifdef CONFIG_WOWLAN + u8 wowlan_mode; + u8 wowlan_pattern; + u8 wowlan_magic; + u8 wowlan_unicast; + u8 wowlan_pattern_idx; + u32 wowlan_pattern_context[8][5]; +#endif // CONFIG_WOWLAN + _timer pwr_state_check_timer; + int pwr_state_check_interval; + u8 pwr_state_check_cnts; + + int ps_flag; + + rt_rf_power_state rf_pwrstate;//cur power state + //rt_rf_power_state current_rfpwrstate; + rt_rf_power_state change_rfpwrstate; + + u8 bHWPowerdown;//if support hw power down + u8 bHWPwrPindetect; + u8 bkeepfwalive; + u8 brfoffbyhw; + unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + struct workqueue_struct *rtw_workqueue; + _workitem resume_work; + #endif + + #ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; + u8 do_late_resume; + #endif //CONFIG_HAS_EARLYSUSPEND + + #ifdef CONFIG_ANDROID_POWER + android_early_suspend_t early_suspend; + u8 do_late_resume; + #endif + +}; + +#define rtw_get_ips_mode_req(pwrctrlpriv) \ + (pwrctrlpriv)->ips_mode_req + +#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \ + (pwrctrlpriv)->ips_mode_req = (ips_mode) + +#define RTW_PWR_STATE_CHK_INTERVAL 2000 + +#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \ + do { \ + /*DBG_871X("%s _rtw_set_pwr_state_check_timer(%p, %d)\n", __FUNCTION__, (pwrctrlpriv), (ms));*/ \ + _set_timer(&(pwrctrlpriv)->pwr_state_check_timer, (ms)); \ + } while(0) + +#define rtw_set_pwr_state_check_timer(pwrctrlpriv) \ + _rtw_set_pwr_state_check_timer((pwrctrlpriv), (pwrctrlpriv)->pwr_state_check_interval) + +extern void rtw_init_pwrctrl_priv(_adapter *adapter); +extern void rtw_free_pwrctrl_priv(_adapter * adapter); + +#ifdef CONFIG_LPS_LCLK +extern s32 rtw_register_tx_alive(PADAPTER padapter); +extern void rtw_unregister_tx_alive(PADAPTER padapter); +extern s32 rtw_register_rx_alive(PADAPTER padapter); +extern void rtw_unregister_rx_alive(PADAPTER padapter); +extern s32 rtw_register_cmd_alive(PADAPTER padapter); +extern void rtw_unregister_cmd_alive(PADAPTER padapter); +extern s32 rtw_register_evt_alive(PADAPTER padapter); +extern void rtw_unregister_evt_alive(PADAPTER padapter); +extern void cpwm_int_hdl(PADAPTER padapter, struct reportpwrstate_parm *preportpwrstate); +#endif + +extern void rtw_set_ps_mode(_adapter * padapter, u8 ps_mode, u8 smart_ps); +extern void rtw_set_rpwm(_adapter * padapter, u8 val8); +extern void LeaveAllPowerSaveMode(PADAPTER Adapter); +#ifdef CONFIG_IPS +void _ips_enter(_adapter * padapter); +void ips_enter(_adapter * padapter); +int _ips_leave(_adapter * padapter); +int ips_leave(_adapter * padapter); +#endif + +void rtw_ps_processor(_adapter*padapter); + +#ifdef CONFIG_AUTOSUSPEND +int autoresume_enter(_adapter* padapter); +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED +rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter ); +#endif + + +#ifdef CONFIG_LPS +void LPS_Enter(PADAPTER padapter); +void LPS_Leave(PADAPTER padapter); +#endif + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv); +#endif //CONFIG_RESUME_IN_WORKQUEUE + +#if defined(CONFIG_HAS_EARLYSUSPEND ) || defined(CONFIG_ANDROID_POWER) +bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv); +bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv); +void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable); +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv); +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv); +#else +#define rtw_is_earlysuspend_registered(pwrpriv) _FALSE +#define rtw_is_do_late_resume(pwrpriv) _FALSE +#define rtw_set_do_late_resume(pwrpriv, enable) do {} while (0) +#define rtw_register_early_suspend(pwrpriv) do {} while (0) +#define rtw_unregister_early_suspend(pwrpriv) do {} while (0) +#endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */ + +u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val); +void rtw_set_ips_deny(_adapter *padapter, u32 ms); +int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller); +#define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __FUNCTION__) +#define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) _rtw_pwr_wakeup(adapter, ips_deffer_ms, __FUNCTION__) +int rtw_pm_set_ips(_adapter *padapter, u8 mode); +int rtw_pm_set_lps(_adapter *padapter, u8 mode); + +#endif //__RTL871X_PWRCTRL_H_ diff --git a/rtl8192cu-fixes/include/rtw_qos.h b/rtl8192cu-fixes/include/rtw_qos.h new file mode 100755 index 00000000..a359c5fe --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_qos.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * 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 _RTW_QOS_H_ +#define _RTW_QOS_H_ +#include +#include + + + + + + +struct qos_priv { + + unsigned int qos_option; //bit mask option: u-apsd, s-apsd, ts, block ack... + +}; + + +#endif //_RTL871X_QOS_H_ + diff --git a/rtl8192cu-fixes/include/rtw_recv.h b/rtl8192cu-fixes/include/rtw_recv.h new file mode 100755 index 00000000..3a4b14bb --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_recv.h @@ -0,0 +1,731 @@ +/****************************************************************************** + * + * 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 _RTW_RECV_H_ +#define _RTW_RECV_H_ + +#include +#include +#include + + +#define NR_RECVFRAME 256 + +#define RXFRAME_ALIGN 8 +#define RXFRAME_ALIGN_SZ (1<signal_stat_timer, (recvpriv)->signal_stat_sampling_interval) +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +struct sta_recv_priv { + + _lock lock; + sint option; + + //_queue blk_strms[MAX_RX_NUMBLKS]; + _queue defrag_q; //keeping the fragment frame until defrag + + struct stainfo_rxcache rxcache; + + //uint sta_rx_bytes; + //uint sta_rx_pkts; + //uint sta_rx_fail; + +}; + + +struct recv_buf +{ + _list list; + + _lock recvbuf_lock; + + u32 ref_cnt; + + PADAPTER adapter; + + u8 *pbuf; + u8 *pallocated_buf; + + u32 len; + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + +#ifdef CONFIG_USB_HCI + + #if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX)||defined(PLATFORM_FREEBSD) + PURB purb; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ + u32 alloc_sz; + #endif + + #ifdef PLATFORM_OS_XP + PIRP pirp; + #endif + + #ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_read_port; + #endif + + u8 irp_pending; + int transfer_len; + +#endif + +#ifdef PLATFORM_LINUX + _pkt *pskb; + u8 reuse; +#endif +#ifdef PLATFORM_FREEBSD //skb solution + struct sk_buff *pskb; + u8 reuse; +#endif //PLATFORM_FREEBSD //skb solution +}; + + +/* + head -----> + + data -----> + + payload + + tail -----> + + + end -----> + + len = (unsigned int )(tail - data); + +*/ +struct recv_frame_hdr +{ + _list list; +#ifndef CONFIG_BSD_RX_USE_MBUF + struct sk_buff *pkt; + struct sk_buff *pkt_newalloc; +#else // CONFIG_BSD_RX_USE_MBUF + _pkt *pkt; + _pkt *pkt_newalloc; +#endif // CONFIG_BSD_RX_USE_MBUF + + _adapter *adapter; + + u8 fragcnt; + + int frame_tag; + + struct rx_pkt_attrib attrib; + + uint len; + u8 *rx_head; + u8 *rx_data; + u8 *rx_tail; + u8 *rx_end; + + void *precvbuf; + + + // + struct sta_info *psta; + + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl *preorder_ctrl; + +}; + + +union recv_frame{ + + union{ + _list list; + struct recv_frame_hdr hdr; + uint mem[RECVFRAME_HDR_ALIGN>>2]; + }u; + + //uint mem[MAX_RXSZ>>2]; + +}; + + +extern union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +extern union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +extern void rtw_init_recvframe(union recv_frame *precvframe ,struct recv_priv *precvpriv); +extern int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue); + +#define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue) +extern int _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); +extern int rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); + +extern void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue); +u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter); + +sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); +sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); +struct recv_buf *rtw_dequeue_recvbuf (_queue *queue); + +void rtw_reordering_ctrl_timeout_handler(void *pcontext); + +__inline static u8 *get_rxmem(union recv_frame *precvframe) +{ + //always return rx_head... + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_head; +} + +__inline static u8 *get_rx_status(union recv_frame *precvframe) +{ + + return get_rxmem(precvframe); + +} + +__inline static u8 *get_recvframe_data(union recv_frame *precvframe) +{ + + //alwasy return rx_data + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_data; + +} + +__inline static u8 *recvframe_push(union recv_frame *precvframe, sint sz) +{ + // append data before rx_data + + /* add data to the start of recv_frame + * + * This function extends the used data area of the recv_frame at the buffer + * start. rx_data must be still larger than rx_head, after pushing. + */ + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data -= sz ; + if( precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head ) + { + precvframe->u.hdr.rx_data += sz ; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_data; + +} + + +__inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz) +{ + // rx_data += sz; move rx_data sz bytes hereafter + + //used for extract sz bytes from rx_data, update rx_data and return the updated rx_data to the caller + + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data += sz; + + if(precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) + { + precvframe->u.hdr.rx_data -= sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_data; + +} + +__inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz) +{ + // rx_tai += sz; move rx_tail sz bytes hereafter + + //used for append sz bytes from ptr to rx_tail, update rx_tail and return the updated rx_tail to the caller + //after putting, rx_tail must be still larger than rx_end. + unsigned char * prev_rx_tail; + + if(precvframe==NULL) + return NULL; + + prev_rx_tail = precvframe->u.hdr.rx_tail; + + precvframe->u.hdr.rx_tail += sz; + + if(precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) + { + precvframe->u.hdr.rx_tail -= sz; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_tail; + +} + + + +__inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) +{ + // rmv data from rx_tail (by yitsen) + + //used for extract sz bytes from rx_end, update rx_end and return the updated rx_end to the caller + //after pulling, rx_end must be still larger than rx_data. + + if(precvframe==NULL) + return NULL; + + precvframe->u.hdr.rx_tail -= sz; + + if(precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) + { + precvframe->u.hdr.rx_tail += sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_tail; + +} + + + +__inline static _buffer * get_rxbuf_desc(union recv_frame *precvframe) +{ + _buffer * buf_desc; + + if(precvframe==NULL) + return NULL; +#ifdef PLATFORM_WINDOWS + NdisQueryPacket(precvframe->u.hdr.pkt, NULL, NULL, &buf_desc, NULL); +#endif + + return buf_desc; +} + + +__inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) +{ + //due to the design of 2048 bytes alignment of recv_frame, we can reference the union recv_frame + //from any given member of recv_frame. + // rxmem indicates the any member/address in recv_frame + + return (union recv_frame*)(((SIZE_PTR)rxmem >> RXFRAME_ALIGN) << RXFRAME_ALIGN); + +} + +__inline static union recv_frame *pkt_to_recvframe(_pkt *pkt) +{ + + u8 * buf_star; + union recv_frame * precv_frame; +#ifdef PLATFORM_WINDOWS + _buffer * buf_desc; + uint len; + + NdisQueryPacket(pkt, NULL, NULL, &buf_desc, &len); + NdisQueryBufferSafe(buf_desc, &buf_star, &len, HighPagePriority); +#endif + precv_frame = rxmem_to_recvframe((unsigned char*)buf_star); + + return precv_frame; +} + +__inline static u8 *pkt_to_recvmem(_pkt *pkt) +{ + // return the rx_head + + union recv_frame * precv_frame = pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_head; + +} + +__inline static u8 *pkt_to_recvdata(_pkt *pkt) +{ + // return the rx_data + + union recv_frame * precv_frame =pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_data; + +} + + +__inline static sint get_recvframe_len(union recv_frame *precvframe) +{ + return precvframe->u.hdr.len; +} + +__inline static u8 query_rx_pwr_percentage(s8 antpower ) +{ + if ((antpower <= -100) || (antpower >= 20)) + { + return 0; + } + else if (antpower >= 0) + { + return 100; + } + else + { + return (100+antpower); + } +} + +__inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex) +{ + s32 SignalPower; // in dBm. + + // Translate to dBm (x=0.5y-95). + SignalPower = (s32)((SignalStrengthIndex + 1) >> 1); + SignalPower -= 95; + + return SignalPower; +} + + +struct sta_info; + +extern void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); + +extern void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame); + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_rf.h b/rtl8192cu-fixes/include/rtw_rf.h new file mode 100755 index 00000000..697dd4e5 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_rf.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 __RTW_RF_H_ +#define __RTW_RF_H_ + +#include +#include + +#define OFDM_PHY 1 +#define MIXED_PHY 2 +#define CCK_PHY 3 + +#define NumRates (13) + +// slot time for 11g +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + +#define RTL8711_RF_MAX_SENS 6 +#define RTL8711_RF_DEF_SENS 4 + +// +// We now define the following channels as the max channels in each channel plan. +// 2G, total 14 chnls +// {1,2,3,4,5,6,7,8,9,10,11,12,13,14} +// 5G, total 24 chnls +// {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165} +#define MAX_CHANNEL_NUM_2G 14 +#define MAX_CHANNEL_NUM_5G 24 +#define MAX_CHANNEL_NUM 38//14+24 + +//#define NUM_REGULATORYS 21 +#define NUM_REGULATORYS 1 + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +struct regulatory_class { + u32 starting_freq; //MHz, + u8 channel_set[MAX_CHANNEL_NUM]; + u8 channel_cck_power[MAX_CHANNEL_NUM];//dbm + u8 channel_ofdm_power[MAX_CHANNEL_NUM];//dbm + u8 txpower_limit; //dbm + u8 channel_spacing; //MHz + u8 modem; +}; + +typedef enum _CAPABILITY{ + cESS = 0x0001, + cIBSS = 0x0002, + cPollable = 0x0004, + cPollReq = 0x0008, + cPrivacy = 0x0010, + cShortPreamble = 0x0020, + cPBCC = 0x0040, + cChannelAgility = 0x0080, + cSpectrumMgnt = 0x0100, + cQos = 0x0200, // For HCCA, use with CF-Pollable and CF-PollReq + cShortSlotTime = 0x0400, + cAPSD = 0x0800, + cRM = 0x1000, // RRM (Radio Request Measurement) + cDSSS_OFDM = 0x2000, + cDelayedBA = 0x4000, + cImmediateBA = 0x8000, +}CAPABILITY, *PCAPABILITY; + +enum _REG_PREAMBLE_MODE{ + PREAMBLE_LONG = 1, + PREAMBLE_AUTO = 2, + PREAMBLE_SHORT = 3, +}; + + +enum _RTL8712_RF_MIMO_CONFIG_{ + RTL8712_RFCONFIG_1T=0x10, + RTL8712_RFCONFIG_2T=0x20, + RTL8712_RFCONFIG_1R=0x01, + RTL8712_RFCONFIG_2R=0x02, + RTL8712_RFCONFIG_1T1R=0x11, + RTL8712_RFCONFIG_1T2R=0x12, + RTL8712_RFCONFIG_TURBO=0x92, + RTL8712_RFCONFIG_2T2R=0x22 +}; + + +// Bandwidth Offset +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +// Represent Channel Width in HT Capabilities +// +typedef enum _HT_CHANNEL_WIDTH { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_40 = 1, +}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; + +// +// Represent Extention Channel Offset in HT Capabilities +// This is available only in 40Mhz mode. +// +typedef enum _HT_EXTCHNL_OFFSET{ + HT_EXTCHNL_OFFSET_NO_EXT = 0, + HT_EXTCHNL_OFFSET_UPPER = 1, + HT_EXTCHNL_OFFSET_NO_DEF = 2, + HT_EXTCHNL_OFFSET_LOWER = 3, +}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET; + +/* 2007/11/15 MH Define different RF type. */ +typedef enum _RT_RF_TYPE_DEFINITION +{ + RF_1T2R = 0, + RF_2T4R = 1, + RF_2T2R = 2, + RF_1T1R = 3, + RF_2T2R_GREEN = 4, + RF_819X_MAX_TYPE = 5, +}RT_RF_TYPE_DEF_E; + +typedef enum _RF_RADIO_PATH{ + RF_PATH_A = 0, //Radio Path A + RF_PATH_B = 1, //Radio Path B + RF_PATH_C = 2, //Radio Path C + RF_PATH_D = 3, //Radio Path D + //RF_PATH_MAX //Max RF number 90 support +}RF_RADIO_PATH_E, *PRF_RADIO_PATH_E; + +u32 rtw_ch2freq(u32 ch); +u32 rtw_freq2ch(u32 freq); + + +#endif //_RTL8711_RF_H_ + diff --git a/rtl8192cu-fixes/include/rtw_security.h b/rtl8192cu-fixes/include/rtw_security.h new file mode 100755 index 00000000..835677c3 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_security.h @@ -0,0 +1,447 @@ +/****************************************************************************** + * + * 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 __RTW_SECURITY_H_ +#define __RTW_SECURITY_H_ + + +#include +#include +#include + + +#define _NO_PRIVACY_ 0x0 +#define _WEP40_ 0x1 +#define _TKIP_ 0x2 +#define _TKIP_WTMIC_ 0x3 +#define _AES_ 0x4 +#define _WEP104_ 0x5 +#ifdef CONFIG_IEEE80211W +#define _BIP_ 0x8 +#endif //CONFIG_IEEE80211W +#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) + +#define _WPA_IE_ID_ 0xdd +#define _WPA2_IE_ID_ 0x30 + +#define SHA256_MAC_LEN 32 +#define AES_BLOCK_SIZE 16 +#define AES_PRIV_SIZE (4 * 44) + +#ifndef Ndis802_11AuthModeWPA2 +#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) +#endif + +#ifndef Ndis802_11AuthModeWPA2PSK +#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) +#endif + +union pn48 { + + u64 val; + +#ifdef CONFIG_LITTLE_ENDIAN + +struct { + u8 TSC0; + u8 TSC1; + u8 TSC2; + u8 TSC3; + u8 TSC4; + u8 TSC5; + u8 TSC6; + u8 TSC7; +} _byte_; + +#elif defined(CONFIG_BIG_ENDIAN) + +struct { + u8 TSC7; + u8 TSC6; + u8 TSC5; + u8 TSC4; + u8 TSC3; + u8 TSC2; + u8 TSC1; + u8 TSC0; +} _byte_; + +#endif + +}; + +union Keytype { + u8 skey[16]; + u32 lkey[4]; +}; + + +typedef struct _RT_PMKID_LIST +{ + u8 bUsed; + u8 Bssid[6]; + u8 PMKID[16]; + u8 SsidBuf[33]; + u8* ssid_octet; + u16 ssid_length; +} RT_PMKID_LIST, *PRT_PMKID_LIST; + + +struct security_priv +{ + u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, 8021x and authswitch + u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm. + + /* WEP */ + u32 dot11PrivacyKeyIndex; // this is only valid for legendary wep, 0~3 for key id. (tx key index) + union Keytype dot11DefKey[4]; // this is only valid for def. key + u32 dot11DefKeylen[4]; + u8 key_mask; /* use to restore wep key after hal_init */ + + u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key + u32 dot118021XGrpKeyid; // key id used for Grp Key ( tx key index) + union Keytype dot118021XGrpKey[4]; // 802.1x Group Key, for inx0 and inx1 + union Keytype dot118021XGrptxmickey[4]; + union Keytype dot118021XGrprxmickey[4]; + union pn48 dot11Grptxpn; // PN48 used for Grp Key xmit. + union pn48 dot11Grprxpn; // PN48 used for Grp Key recv. +#ifdef CONFIG_IEEE80211W + u32 dot11wBIPKeyid; // key id used for BIP Key ( tx key index) + union Keytype dot11wBIPKey[6]; // BIP Key, for index4 and index5 + union pn48 dot11wBIPtxpn; // PN48 used for Grp Key xmit. + union pn48 dot11wBIPrxpn; // PN48 used for Grp Key recv. +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_AP_MODE + //extend security capabilities for AP_MODE + unsigned int dot8021xalg;//0:disable, 1:psk, 2:802.1x + unsigned int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + unsigned int wpa_group_cipher; + unsigned int wpa2_group_cipher; + unsigned int wpa_pairwise_cipher; + unsigned int wpa2_pairwise_cipher; +#endif + + u8 wps_ie[MAX_WPS_IE_LEN];//added in assoc req + int wps_ie_len; + + + u8 binstallGrpkey; +#ifdef CONFIG_IEEE80211W + u8 binstallBIPkey; +#endif //CONFIG_IEEE80211W + u8 busetkipkey; + //_timer tkip_timer; + u8 bcheck_grpkey; + u8 bgrpkey_handshake; + + //u8 packet_cnt;//unused, removed + + s32 sw_encrypt;//from registry_priv + s32 sw_decrypt;//from registry_priv + + s32 hw_decrypted;//if the rx packets is hw_decrypted==_FALSE, it means the hw has not been ready. + + + //keeps the auth_type & enc_status from upper layer ioctl(wpa_supplicant or wzc) + u32 ndisauthtype; // NDIS_802_11_AUTHENTICATION_MODE + u32 ndisencryptstatus; // NDIS_802_11_ENCRYPTION_STATUS + + WLAN_BSSID_EX sec_bss; //for joinbss (h2c buffer) usage + + NDIS_802_11_WEP ndiswep; +#ifdef PLATFORM_WINDOWS + u8 KeyMaterial[16];// variable length depending on above field. +#endif + + u8 assoc_info[600]; + u8 szofcapability[256]; //for wpa2 usage + u8 oidassociation[512]; //for wpa/wpa2 usage + u8 authenticator_ie[256]; //store ap security information element + u8 supplicant_ie[256]; //store sta security information element + + + //for tkip countermeasure + u32 last_mic_err_time; + u8 btkip_countermeasure; + u8 btkip_wait_report; + u32 btkip_countermeasure_time; + + //--------------------------------------------------------------------------- + // For WPA2 Pre-Authentication. + //--------------------------------------------------------------------------- + //u8 RegEnablePreAuth; // Default value: Pre-Authentication enabled or not, from registry "EnablePreAuth". Added by Annie, 2005-11-01. + //u8 EnablePreAuthentication; // Current Value: Pre-Authentication enabled or not. + RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; // Renamed from PreAuthKey[NUM_PRE_AUTH_KEY]. Annie, 2006-10-13. + u8 PMKIDIndex; + //u32 PMKIDCount; // Added by Annie, 2006-10-13. + //u8 szCapability[256]; // For WPA2-PSK using zero-config, by Annie, 2005-09-20. + + u8 bWepDefaultKeyIdxSet; +}; + +struct sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +}; + +#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\ +do{\ + switch(psecuritypriv->dot11AuthAlgrthm)\ + {\ + case dot11AuthAlgrthm_Open:\ + case dot11AuthAlgrthm_Shared:\ + case dot11AuthAlgrthm_Auto:\ + encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;\ + break;\ + case dot11AuthAlgrthm_8021X:\ + if(bmcst)\ + encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\ + else\ + encry_algo =(u8) psta->dot118021XPrivacy;\ + break;\ + }\ +}while(0) + + +#define SET_ICE_IV_LEN( iv_len, icv_len, encrypt)\ +do{\ + switch(encrypt)\ + {\ + case _WEP40_:\ + case _WEP104_:\ + iv_len = 4;\ + icv_len = 4;\ + break;\ + case _TKIP_:\ + iv_len = 8;\ + icv_len = 4;\ + break;\ + case _AES_:\ + iv_len = 8;\ + icv_len = 8;\ + break;\ + default:\ + iv_len = 0;\ + icv_len = 0;\ + break;\ + }\ +}while(0) + + +#define GET_TKIP_PN(iv,dot11txpn)\ +do{\ + dot11txpn._byte_.TSC0=iv[2];\ + dot11txpn._byte_.TSC1=iv[0];\ + dot11txpn._byte_.TSC2=iv[4];\ + dot11txpn._byte_.TSC3=iv[5];\ + dot11txpn._byte_.TSC4=iv[6];\ + dot11txpn._byte_.TSC5=iv[7];\ +}while(0) + + +#define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + +struct mic_data +{ + u32 K0, K1; // Key + u32 L, R; // Current state + u32 M; // Message accumulator (single word) + u32 nBytesInM; // # bytes in M +}; + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ + ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) + +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } + +#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) + +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif +#ifdef CONFIG_IEEE80211W +int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac); +#endif //CONFIG_IEEE80211W +void rtw_secmicsetkey(struct mic_data *pmicdata, u8 * key ); +void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b ); +void rtw_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nBytes ); +void rtw_secgetmic(struct mic_data *pmicdata, u8 * dst ); + +void rtw_seccalctkipmic( + u8 * key, + u8 *header, + u8 *data, + u32 data_len, + u8 *Miccode, + u8 priority); + +u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe); +u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe); +void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe); + +u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe); +u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe); +void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe); +#ifdef CONFIG_IEEE80211W +u32 rtw_BIP_verify(_adapter *padapter, u8 *precvframe); +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_TDLS +void wpa_tdls_generate_tpk(_adapter *padapter, struct sta_info *psta); +int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie, + u8 *mic); +int tdls_verify_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie); +#endif //CONFIG_TDLS + +#ifdef PLATFORM_WINDOWS +void rtw_use_tkipkey_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); +#endif +#ifdef PLATFORM_LINUX +void rtw_use_tkipkey_handler(void* FunctionContext); +#endif + +#ifdef PLATFORM_FREEBSD +void rtw_use_tkipkey_handler(void* FunctionContext); +#endif //PLATFORM_FREEBSD + +void rtw_sec_restore_wep_key(_adapter *adapter); +u8 rtw_handle_tkip_countermeasure(_adapter* adapter, const char *caller); + +#endif //__RTL871X_SECURITY_H_ + diff --git a/rtl8192cu-fixes/include/rtw_sreset.h b/rtl8192cu-fixes/include/rtw_sreset.h new file mode 100755 index 00000000..45dd2bfb --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_sreset.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_SRESET_C_ +#define _RTW_SRESET_C_ + +#include +#include +#include + +enum { + SRESET_TGP_NULL = 0, + SRESET_TGP_XMIT_STATUS = 1, + SRESET_TGP_LINK_STATUS = 2, +}; + +struct sreset_priv { + _mutex silentreset_mutex; + u8 silent_reset_inprogress; + u8 Wifi_Error_Status; + unsigned long last_tx_time; + unsigned long last_tx_complete_time; + + s32 dbg_trigger_point; +}; + +#ifdef CONFIG_RTL8192C +#include +#endif +#ifdef CONFIG_RTL8192D +#include +#endif +#ifdef CONFIG_RTL8723A +#include +#endif +#ifdef CONFIG_RTL8188E +#include +#endif + +#define WIFI_STATUS_SUCCESS 0 +#define USB_VEN_REQ_CMD_FAIL BIT0 +#define USB_READ_PORT_FAIL BIT1 +#define USB_WRITE_PORT_FAIL BIT2 +#define WIFI_MAC_TXDMA_ERROR BIT3 +#define WIFI_TX_HANG BIT4 +#define WIFI_RX_HANG BIT5 +#define WIFI_IF_NOT_EXIST BIT6 + +void sreset_init_value(_adapter *padapter); +void sreset_reset_value(_adapter *padapter); +u8 sreset_get_wifi_status(_adapter *padapter); +void sreset_set_wifi_error_status(_adapter *padapter, u32 status); +void sreset_set_trigger_point(_adapter *padapter, s32 tgp); +bool sreset_inprogress(_adapter *padapter); +void sreset_reset(_adapter *padapter); + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_tdls.h b/rtl8192cu-fixes/include/rtw_tdls.h new file mode 100755 index 00000000..1005331c --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_tdls.h @@ -0,0 +1,143 @@ +/****************************************************************************** + * + * 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 __RTW_TDLS_H_ +#define __RTW_TDLS_H_ + +#include + +#ifdef CONFIG_TDLS +/* TDLS STA state */ +#define TDLS_STATE_NONE 0x00000000 //default state +#define TDLS_INITIATOR_STATE 0x10000000 +#define TDLS_RESPONDER_STATE 0x20000000 +#define TDLS_LINKED_STATE 0x40000000 +#define TDLS_CH_SWITCH_ON_STATE 0x01000000 +#define TDLS_PEER_AT_OFF_STATE 0x02000000 //could send pkt on target ch +#define TDLS_AT_OFF_CH_STATE 0x04000000 +#define TDLS_CH_SW_INITIATOR_STATE 0x08000000 //avoiding duplicated or unconditional ch. switch rsp. +#define TDLS_APSD_CHSW_STATE 0x00100000 //in APSD and want to setup channel switch +#define TDLS_PEER_SLEEP_STATE 0x00200000 //peer sta is sleeping +#define TDLS_SW_OFF_STATE 0x00400000 //terminate channel swithcing +#define TDLS_ALIVE_STATE 0x00010000 //Check if peer sta is alived. + +#define TPK_RESEND_COUNT 301 +#define CH_SWITCH_TIME 10 +#define CH_SWITCH_TIMEOUT 30 +#define TDLS_STAY_TIME 500 +#define TDLS_SIGNAL_THRESH 0x20 +#define TDLS_WATCHDOG_PERIOD 10 //Periodically sending tdls discovery request in TDLS_WATCHDOG_PERIOD * 2 sec +#define TDLS_ALIVE_TIMER_PH1 5000 +#define TDLS_ALIVE_TIMER_PH2 2000 +#define TDLS_STAY_TIME 500 +#define TDLS_HANDSHAKE_TIME 2000 +#define TDLS_ALIVE_COUNT 3 +#define TDLS_INI_MACID_ENTRY 6 + +/* TDLS */ +#define TDLS_MIC_LEN 16 +#define WPA_NONCE_LEN 32 +#define TDLS_TIMEOUT_LEN 4 + +struct wpa_tdls_ftie { + u8 ie_type; /* FTIE */ + u8 ie_len; + u8 mic_ctrl[2]; + u8 mic[TDLS_MIC_LEN]; + u8 Anonce[WPA_NONCE_LEN]; /* Responder Nonce in TDLS */ + u8 Snonce[WPA_NONCE_LEN]; /* Initiator Nonce in TDLS */ + /* followed by optional elements */ +} ; + +struct wpa_tdls_lnkid { + u8 ie_type; /* Link Identifier IE */ + u8 ie_len; + u8 bssid[ETH_ALEN]; + u8 init_sta[ETH_ALEN]; + u8 resp_sta[ETH_ALEN]; +} ; + +static u8 TDLS_RSNIE[]={ 0x01, 0x00, //version shall be set to 1 + 0x00, 0x0f, 0xac, 0x07, //group sipher suite + 0x01, 0x00, //pairwise cipher suite count + 0x00, 0x0f, 0xac, 0x04, //pairwise cipher suite list; CCMP only + 0x01, 0x00, //AKM suite count + 0x00, 0x0f, 0xac, 0x07, //TPK Handshake + 0x00, 0x02, + //PMKID shall not be present + }; + +static u8 TDLS_WMMIE[]={0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; //Qos info all set zero + +static u8 TDLS_EXT_CAPIE[] = {0x00, 0x00, 0x00, 0x50, 0x20}; //bit(28), bit(30), bit(37) + +// SRC: Supported Regulatory Classes +static u8 TDLS_SRC[] = { 0x01, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21 }; + +void rtw_reset_tdls_info(_adapter* padapter); +int rtw_init_tdls_info(_adapter* padapter); +void rtw_free_tdls_info(struct tdls_info *ptdlsinfo); +void issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, struct sta_info *ptdls_sta, unsigned int power_mode); +void init_TPK_timer(_adapter *padapter, struct sta_info *psta); +void init_ch_switch_timer(_adapter *padapter, struct sta_info *psta); +void init_base_ch_timer(_adapter *padapter, struct sta_info *psta); +void init_off_ch_timer(_adapter *padapter, struct sta_info *psta); +void init_tdls_alive_timer(_adapter *padapter, struct sta_info *psta); +void init_handshake_timer(_adapter *padapter, struct sta_info *psta); +void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta); +#ifdef CONFIG_WFD +void issue_tunneled_probe_req(_adapter *padapter); +void issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame); +#endif //CONFIG_WFD +void issue_tdls_dis_req(_adapter *padapter, u8 *mac_addr); +void issue_tdls_setup_req(_adapter *padapter, u8 *mac_addr); +void issue_tdls_setup_rsp(_adapter *padapter, union recv_frame *precv_frame); +void issue_tdls_setup_cfm(_adapter *padapter, union recv_frame *precv_frame); +void issue_tdls_dis_rsp(_adapter * padapter, union recv_frame * precv_frame, u8 dialog); +void issue_tdls_teardown(_adapter *padapter, u8 *mac_addr); +void issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *psta); +void issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr); +void issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr); +sint On_TDLS_Dis_Rsp(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Setup_Req(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Setup_Rsp(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Setup_Cfm(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Dis_Req(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Teardown(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Peer_Traffic_Rsp(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Ch_Switch_Req(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Ch_Switch_Rsp(_adapter *adapter, union recv_frame *precv_frame); +void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog); +void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); + +int update_sgi_tdls(_adapter *padapter, struct sta_info *psta); +u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta); +#endif //CONFIG_TDLS + +#endif + diff --git a/rtl8192cu-fixes/include/rtw_version.h b/rtl8192cu-fixes/include/rtw_version.h new file mode 100644 index 00000000..4fb9dd43 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_version.h @@ -0,0 +1 @@ +#define DRIVERVERSION "v4.0.2_9000.20130911" diff --git a/rtl8192cu-fixes/include/rtw_xmit.h b/rtl8192cu-fixes/include/rtw_xmit.h new file mode 100755 index 00000000..f7eaf4a6 --- /dev/null +++ b/rtl8192cu-fixes/include/rtw_xmit.h @@ -0,0 +1,754 @@ +/****************************************************************************** + * + * 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 _RTW_XMIT_H_ +#define _RTW_XMIT_H_ + +#include +#include +#include +#ifdef PLATFORM_FREEBSD +#include +#endif //PLATFORM_FREEBSD + +#ifdef CONFIG_SDIO_HCI +//#define MAX_XMITBUF_SZ (30720)// (2048) +#define MAX_XMITBUF_SZ (12288) +#define NR_XMITBUFF (16) + +#elif defined (CONFIG_USB_HCI) +#ifdef CONFIG_USB_TX_AGGREGATION + #if defined(CONFIG_PLATFORM_ARM_SUNxI) || defined(CONFIG_PLATFORM_ARM_SUN6I) + #define MAX_XMITBUF_SZ (12288) //12k 1536*8 + #elif defined (CONFIG_PLATFORM_MSTAR) + #define MAX_XMITBUF_SZ 7680 // 7.5k + #else + #define MAX_XMITBUF_SZ (20480) // 20k + #endif +#else +#define MAX_XMITBUF_SZ (2048) +#endif //CONFIG_USB_TX_AGGREGATION +#ifdef CONFIG_SINGLE_XMIT_BUF +#define NR_XMITBUFF (1) +#else +#define NR_XMITBUFF (4) +#endif //CONFIG_SINGLE_XMIT_BUF + +#elif defined (CONFIG_PCI_HCI) +#define MAX_XMITBUF_SZ (1664) +#define NR_XMITBUFF (128) +#endif + +#ifdef PLATFORM_OS_CE +#define XMITBUF_ALIGN_SZ 4 +#else +#ifdef CONFIG_PCI_HCI +#define XMITBUF_ALIGN_SZ 4 +#else +#define XMITBUF_ALIGN_SZ 512 +#endif +#endif + +// 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 //CONFIG_SINGLE_XMIT_BUF + +#define MAX_NUMBLKS (1) + +#define XMIT_VO_QUEUE (0) +#define XMIT_VI_QUEUE (1) +#define XMIT_BE_QUEUE (2) +#define XMIT_BK_QUEUE (3) + +#define VO_QUEUE_INX 0 +#define VI_QUEUE_INX 1 +#define BE_QUEUE_INX 2 +#define BK_QUEUE_INX 3 +#define BCN_QUEUE_INX 4 +#define MGT_QUEUE_INX 5 +#define HIGH_QUEUE_INX 6 +#define TXCMD_QUEUE_INX 7 + +#define HW_QUEUE_ENTRY 8 + +#ifdef CONFIG_PCI_HCI +//#define TXDESC_NUM 64 +#define TXDESC_NUM 128 +#define TXDESC_NUM_BE_QUEUE 128 +#endif + +#define WEP_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC0;\ + pattrib_iv[1] = dot11txpn._byte_.TSC1;\ + pattrib_iv[2] = dot11txpn._byte_.TSC2;\ + pattrib_iv[3] = ((keyidx & 0x3)<<6);\ + dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0: (dot11txpn.val+1);\ +}while(0) + + +#define TKIP_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC1;\ + pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f;\ + pattrib_iv[2] = dot11txpn._byte_.TSC0;\ + pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ + pattrib_iv[4] = dot11txpn._byte_.TSC2;\ + pattrib_iv[5] = dot11txpn._byte_.TSC3;\ + pattrib_iv[6] = dot11txpn._byte_.TSC4;\ + pattrib_iv[7] = dot11txpn._byte_.TSC5;\ + dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0: (dot11txpn.val+1);\ +}while(0) + +#define AES_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC0;\ + pattrib_iv[1] = dot11txpn._byte_.TSC1;\ + pattrib_iv[2] = 0;\ + pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ + pattrib_iv[4] = dot11txpn._byte_.TSC2;\ + pattrib_iv[5] = dot11txpn._byte_.TSC3;\ + pattrib_iv[6] = dot11txpn._byte_.TSC4;\ + pattrib_iv[7] = dot11txpn._byte_.TSC5;\ + dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0: (dot11txpn.val+1);\ +}while(0) + + +#define HWXMIT_ENTRY 4 + +#define TXDESC_SIZE 32 + +#ifdef CONFIG_SDIO_HCI +#define TXDESC_OFFSET TXDESC_SIZE +#endif + +#ifdef CONFIG_USB_HCI +#define PACKET_OFFSET_SZ (8) +#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) +#endif + +#ifdef CONFIG_PCI_HCI +#define TXDESC_OFFSET 0 +#define TX_DESC_NEXT_DESC_OFFSET 40 +#endif + +// +//defined for TX DESC Operation +// + +#define MAX_TID (15) + +//OFFSET 0 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define BMC BIT(24) +#define LSG BIT(26) +#define FSG BIT(27) +#define OWN BIT(31) + +//OFFSET 4 +#define PKT_OFFSET_SZ 0 +#define BK BIT(6) +#define QSEL_SHT 8 +#define Rate_ID_SHT 16 +#define NAVUSEHDR BIT(20) +#define PKT_OFFSET_SHT 26 +#define HWPC BIT(31) + +//OFFSET 8 +#define AGG_EN BIT(29) + +//OFFSET 12 +#define SEQ_SHT 16 + +//OFFSET 16 +#define QoS BIT(6) +#define HW_SEQ_EN BIT(7) +#define USERATE BIT(8) +#define DISDATAFB BIT(10) +#define DATA_SHORT BIT(24) +#define DATA_BW BIT(25) + +//OFFSET 20 +#define SGI BIT(6) + +struct tx_desc{ + + //DWORD 0 + unsigned int txdw0; + + unsigned int txdw1; + + unsigned int txdw2; + + unsigned int txdw3; + + unsigned int txdw4; + + unsigned int txdw5; + + unsigned int txdw6; + + unsigned int txdw7; +#ifdef CONFIG_PCI_HCI + unsigned int txdw8; + + unsigned int txdw9; + + unsigned int txdw10; + + unsigned int txdw11; + + // 2008/05/15 MH Because PCIE HW memory R/W 4K limit. And now, our descriptor + // size is 40 bytes. If you use more than 102 descriptor( 103*40>4096), HW will execute + // memoryR/W CRC error. And then all DMA fetch will fail. We must decrease descriptor + // number or enlarge descriptor size as 64 bytes. + unsigned int txdw12; + + unsigned int txdw13; + + unsigned int txdw14; + + unsigned int txdw15; +#endif +}; + + +union txdesc { + struct tx_desc txdesc; + unsigned int value[TXDESC_SIZE>>2]; +}; + +#ifdef CONFIG_PCI_HCI +#define PCI_MAX_TX_QUEUE_COUNT 8 + +struct rtw_tx_ring { + struct tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + _queue queue; + u32 qlen; +}; +#endif + +struct hw_xmit { + //_lock xmit_lock; + //_list pending; + _queue *sta_queue; + //struct hw_txqueue *phwtxqueue; + //sint txcmdcnt; + int accnt; +}; + +#if 0 +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + int pktlen; //the original 802.3 pkt raw_data len (not include ether_hdr data) + int pkt_hdrlen; //the original 802.3 pkt header len + int hdrlen; //the WLAN Header Len + int nr_frags; + int last_txcmdsz; + int encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv[8]; + int iv_len; + u8 icv[8]; + int icv_len; + int priority; + int ack_policy; + int mac_id; + int vcs_mode; //virtual carrier sense method + + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + + u8 key_idx; + + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 mdata;//more data bit + u8 eosp; + + u8 pctrl;//per packet txdesc control enable + u8 triggered;//for ap mode handling Power Saving sta + + u32 qsel; + u16 seqnum; + + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif +}; +#else +//reduce size +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + u16 seqnum; + 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) + u32 last_txcmdsz; + u8 nr_frags; + u8 encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv_len; + u8 icv_len; + u8 iv[8]; + u8 icv[8]; + u8 priority; + u8 ack_policy; + u8 mac_id; + u8 vcs_mode; //virtual carrier sense method + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + u8 key_idx; + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 mdata;//more data bit + u8 pctrl;//per packet txdesc control enable + u8 triggered;//for ap mode handling Power Saving sta + u8 qsel; + u8 eosp; + u8 rate; + u8 intel_proxim; + u8 retry_ctrl; + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif + union Keytype dot11tkiptxmickey; + //union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; +}; +#endif + +#ifdef PLATFORM_FREEBSD +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ + +/*struct rtw_ieee80211_hdr { + uint16_t frame_control; + uint16_t duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + uint16_t seq_ctrl; + u8 addr4[6]; +} ;*/ +#endif //PLATFORM_FREEBSD + +#define WLANHDR_OFFSET 64 + +#define NULL_FRAMETAG (0x0) +#define DATA_FRAMETAG 0x01 +#define L2_FRAMETAG 0x02 +#define MGNT_FRAMETAG 0x03 +#define AMSDU_FRAMETAG 0x04 + +#define EII_FRAMETAG 0x05 +#define IEEE8023_FRAMETAG 0x06 + +#define MP_FRAMETAG 0x07 + +#define TXAGG_FRAMETAG 0x08 + +struct submit_ctx{ + u32 submit_time; /* */ + u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */ + int status; /* status for operation */ +#ifdef PLATFORM_LINUX + struct completion done; +#endif +}; + +enum { + RTW_SCTX_SUBMITTED = -1, + RTW_SCTX_DONE_SUCCESS = 0, + RTW_SCTX_DONE_UNKNOWN, + RTW_SCTX_DONE_TIMEOUT, + RTW_SCTX_DONE_BUF_ALLOC, + RTW_SCTX_DONE_BUF_FREE, + RTW_SCTX_DONE_WRITE_PORT_ERR, + RTW_SCTX_DONE_TX_DESC_NA, + RTW_SCTX_DONE_TX_DENY, + RTW_SCTX_DONE_CCX_PKT_FAIL, + RTW_SCTX_DONE_DRV_STOP, + RTW_SCTX_DONE_DEV_REMOVE, +}; + + +void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); +int rtw_sctx_wait(struct submit_ctx *sctx); +void rtw_sctx_done_err(struct submit_ctx **sctx, int status); +void rtw_sctx_done(struct submit_ctx **sctx); + +struct xmit_buf +{ + _list list; + + _adapter *padapter; + + u8 *pallocated_buf; + + u8 *pbuf; + + void *priv_data; + + u16 ext_tag; // 0: Normal xmitbuf, 1: extension xmitbuf. + u16 flags; + u32 alloc_sz; + + struct submit_ctx *sctx; + +#ifdef CONFIG_USB_HCI + + u32 sz[8]; + +#if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) + PURB pxmit_urb[8]; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +#endif + + u8 bpending[8]; + + sint last[8]; + +#endif + +#ifdef CONFIG_SDIO_HCI + u32 len; + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + u32 ff_hwaddr; +#ifdef PLATFORM_OS_XP + PMDL pxmitbuf_mdl; + PIRP pxmitbuf_irp; + PSDBUS_REQUEST_PACKET pxmitbuf_sdrp; +#endif +#endif + +#ifdef CONFIG_PCI_HCI + u32 len; +#endif + +#ifdef DBG_XMIT_BUF + u8 no; +#endif + +}; + +struct xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + + u8 *buf_addr; + + struct xmit_buf *pxmitbuf; + +#ifdef CONFIG_SDIO_HCI + u8 pg_num; + u8 agg_num; +#endif + +#ifdef CONFIG_USB_HCI +#ifdef CONFIG_USB_TX_AGGREGATION + u8 agg_num; +#endif + u8 pkt_offset; +#ifdef CONFIG_RTL8192D + u8 EMPktNum; + u16 EMPktLen[5];//The max value by HW +#endif +#endif +#ifdef CONFIG_XMIT_ACK + u8 ack_report; +#endif + + u8 *alloc_addr; /* the actual address this xmitframe allocated */ + u8 ext_tag; /* 0:data, 1:mgmt */ + +}; + +struct tx_servq { + _list tx_pending; + _queue sta_pending; + int qcnt; +}; + + + +struct sta_xmit_priv +{ + _lock lock; + sint option; + sint apsd_setting; //When bit mask is on, the associated edca queue supports APSD. + + + //struct tx_servq blk_q[MAX_NUMBLKS]; + struct tx_servq be_q; //priority == 0,3 + struct tx_servq bk_q; //priority == 1,2 + struct tx_servq vi_q; //priority == 4,5 + struct tx_servq vo_q; //priority == 6,7 + _list legacy_dz; + _list apsd; + + u16 txseq_tid[16]; + + //uint sta_tx_bytes; + //u64 sta_tx_pkts; + //uint sta_tx_fail; + +}; + + +struct hw_txqueue { + volatile sint head; + volatile sint tail; + volatile sint free_sz; //in units of 64 bytes + volatile sint free_cmdsz; + volatile sint txsz[8]; + uint ff_hwaddr; + uint cmd_hwaddr; + sint ac_tag; +}; + + +struct xmit_priv { + + _lock lock; + + _sema xmit_sema; + _sema terminate_xmitthread_sema; + + //_queue blk_strms[MAX_NUMBLKS]; + _queue be_pending; + _queue bk_pending; + _queue vi_pending; + _queue vo_pending; + _queue bm_pending; + + //_queue legacy_dz_queue; + //_queue apsd_queue; + + u8 *pallocated_frame_buf; + u8 *pxmit_frame_buf; + uint free_xmitframe_cnt; + _queue free_xmit_queue; + + //uint mapping_addr; + //uint pkt_sz; + + u8 *xframe_ext_alloc_addr; + u8 *xframe_ext; + uint free_xframe_ext_cnt; + _queue free_xframe_ext_queue; + + //struct hw_txqueue be_txqueue; + //struct hw_txqueue bk_txqueue; + //struct hw_txqueue vi_txqueue; + //struct hw_txqueue vo_txqueue; + //struct hw_txqueue bmc_txqueue; + + uint frag_len; + + _adapter *adapter; + + u8 vcs_setting; + u8 vcs; + u8 vcs_type; + //u16 rts_thresh; + + u64 tx_bytes; + u64 tx_pkts; + u64 tx_drop; + u64 last_tx_bytes; + u64 last_tx_pkts; + + struct hw_xmit *hwxmits; + u8 hwxmit_entry; + +#ifdef CONFIG_USB_HCI + _sema tx_retevt;//all tx return event; + u8 txirp_cnt;// + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +// USB_TRANSFER usb_transfer_write_mem; +#endif +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#ifdef PLATFORM_FREEBSD + struct task xmit_tasklet; +#endif + //per AC pending irp + int beq_cnt; + int bkq_cnt; + int viq_cnt; + int voq_cnt; + +#endif + +#ifdef CONFIG_PCI_HCI + // Tx + struct rtw_tx_ring tx_ring[PCI_MAX_TX_QUEUE_COUNT]; + int txringcount[PCI_MAX_TX_QUEUE_COUNT]; +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#endif + + _queue free_xmitbuf_queue; + _queue pending_xmitbuf_queue; + u8 *pallocated_xmitbuf; + u8 *pxmitbuf; + uint free_xmitbuf_cnt; + + _queue free_xmit_extbuf_queue; + u8 *pallocated_xmit_extbuf; + u8 *pxmit_extbuf; + uint free_xmit_extbuf_cnt; + + u16 nqos_ssn; + +#ifdef CONFIG_XMIT_ACK + int ack_tx; + _mutex ack_tx_mutex; + struct submit_ctx ack_tx_ops; +#endif + _lock lock_sctx; +}; + +extern struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +extern struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +void rtw_count_tx_stats(_adapter *padapter, struct xmit_frame *pxmitframe, int sz); +extern void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len); +extern s32 rtw_make_wlanhdr(_adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib); +extern s32 rtw_put_snap(u8 *data, u16 h_proto); + +extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv); +struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); +extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); +struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac); +extern s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +extern struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); + +extern s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); +extern thread_return rtw_xmit_thread(thread_context context); +extern u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); +#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue(&f->attrib) +extern s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +#ifdef CONFIG_IEEE80211W +extern s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_TDLS +s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, u8 action); +#endif //CONFIG_TDLS +s32 _rtw_init_hw_txqueue(struct hw_txqueue* phw_txqueue, u8 ac_tag); +void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); + + +s32 rtw_txframes_pending(_adapter *padapter); +s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib); +void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry); + + +s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter); +void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv); + + +void rtw_alloc_hwxmits(_adapter *padapter); +void rtw_free_hwxmits(_adapter *padapter); + + +s32 rtw_xmit(_adapter *padapter, _pkt **pkt); + +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); +void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); +void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta); +#endif + +u8 qos_acm(u8 acm_mask, u8 priority); + +#ifdef CONFIG_XMIT_ACK +int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms); +void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status); +#endif //CONFIG_XMIT_ACK + + +//include after declaring struct xmit_buf, in order to avoid warning +#include + +#endif //_RTL871X_XMIT_H_ + diff --git a/rtl8192cu-fixes/include/sta_info.h b/rtl8192cu-fixes/include/sta_info.h new file mode 100755 index 00000000..75763db2 --- /dev/null +++ b/rtl8192cu-fixes/include/sta_info.h @@ -0,0 +1,432 @@ +/****************************************************************************** + * + * 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 __STA_INFO_H_ +#define __STA_INFO_H_ + +#include +#include +#include +#include + +#define IBSS_START_MAC_ID 2 +#define NUM_STA 32 +#define NUM_ACL 16 + + +//if mode ==0, then the sta is allowed once the addr is hit. +//if mode ==1, then the sta is rejected once the addr is non-hit. +struct rtw_wlan_acl_node { + _list list; + u8 addr[ETH_ALEN]; + u8 valid; +}; + +//mode=0, disable +//mode=1, accept unless in deny list +//mode=2, deny unless in accept list +struct wlan_acl_pool { + int mode; + int num; + struct rtw_wlan_acl_node aclnode[NUM_ACL]; + _queue acl_node_q; +}; + +typedef struct _RSSI_STA{ + s32 UndecoratedSmoothedPWDB; + s32 UndecoratedSmoothedCCK; + s32 UndecoratedSmoothedOFDM; + u64 PacketMap; + u8 ValidBit; +}RSSI_STA, *PRSSI_STA; + +struct stainfo_stats { + + u64 rx_mgnt_pkts; + u64 rx_beacon_pkts; + u64 rx_probereq_pkts; + u64 rx_probersp_pkts; + u64 rx_probersp_bm_pkts; + u64 rx_probersp_uo_pkts; + u64 rx_ctrl_pkts; + u64 rx_data_pkts; + + u64 last_rx_mgnt_pkts; + u64 last_rx_beacon_pkts; + u64 last_rx_probereq_pkts; + u64 last_rx_probersp_pkts; + u64 last_rx_probersp_bm_pkts; + u64 last_rx_probersp_uo_pkts; + u64 last_rx_ctrl_pkts; + u64 last_rx_data_pkts; + + u64 rx_bytes; + u64 rx_drops; + + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; + +}; + +#ifdef CONFIG_TDLS +struct TDLS_PeerKey { + u8 kck[16]; /* TPK-KCK */ + u8 tk[16]; /* TPK-TK; only CCMP will be used */ +} ; +#endif //CONFIG_TDLS + +struct sta_info { + + _lock lock; + _list list; //free_sta_queue + _list hash_list; //sta_hash + //_list asoc_list; //20061114 + //_list sleep_list;//sleep_q + //_list wakeup_list;//wakeup_q + + struct sta_xmit_priv sta_xmitpriv; + struct sta_recv_priv sta_recvpriv; + + _queue sleep_q; + unsigned int sleepq_len; + + uint state; + uint aid; + uint mac_id; + uint qos_option; + u8 hwaddr[ETH_ALEN]; + + uint ieee8021x_blocked; //0: allowed, 1:blocked + uint dot118021XPrivacy; //aes, tkip... + union Keytype dot11tkiptxmickey; + union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; + union pn48 dot11txpn; // PN48 used for Unicast xmit. +#ifdef CONFIG_IEEE80211W + union pn48 dot11wtxpn; // PN48 used for Unicast mgmt xmit. +#endif //CONFIG_IEEE80211W + union pn48 dot11rxpn; // PN48 used for Unicast recv. + + + u8 bssrateset[16]; + u32 bssratelen; + s32 rssi; + s32 signal_quality; + + u8 cts2self; + u8 rtsen; + + u8 raid; + u8 init_rate; + u32 ra_mask; + struct stainfo_stats sta_stats; + +#ifdef CONFIG_TDLS + u32 tdls_sta_state; + u8 dialog; + u8 SNonce[32]; + u8 ANonce[32]; + u32 TDLS_PeerKey_Lifetime; + u16 TPK_count; + _timer TPK_timer; + struct TDLS_PeerKey tpk; + _adapter *padapter; + u16 stat_code; + u8 off_ch; + u16 ch_switch_time; + u16 ch_switch_timeout; + u8 option; + _timer option_timer; + _timer base_ch_timer; + _timer off_ch_timer; + + _timer handshake_timer; + _timer alive_timer1; + _timer alive_timer2; + u8 timer_flag; + u8 alive_count; +#endif //CONFIG_TDLS + + //for A-MPDU TX, ADDBA timeout check + _timer addba_retry_timer; + + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl recvreorder_ctrl[16]; + + //for A-MPDU Tx + //unsigned char ampdu_txen_bitmap; + u16 BA_starting_seqctrl[16]; + + +#ifdef CONFIG_80211N_HT + struct ht_priv htpriv; +#endif + + //Notes: + //STA_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) + sta_info: (STA & AP) CAP/INFO + //scan_q: AP CAP/INFO + + //AP_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO + //sta_info: (AP & STA) CAP/INFO + +#ifdef CONFIG_AP_MODE + + _list asoc_list; + _list auth_list; + + unsigned int expire_to; + unsigned int auth_seq; + unsigned int authalg; + unsigned char chg_txt[128]; + + u16 capability; + int flags; + + int dot8021xalg;//0:disable, 1:psk, 2:802.1x + int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + int wpa_group_cipher; + int wpa2_group_cipher; + int wpa_pairwise_cipher; + int wpa2_pairwise_cipher; + + u8 bpairwise_key_installed; + +#ifdef CONFIG_NATIVEAP_MLME + u8 wpa_ie[32]; + + u8 nonerp_set; + u8 no_short_slot_time_set; + u8 no_short_preamble_set; + u8 no_ht_gf_set; + u8 no_ht_set; + u8 ht_20mhz_set; +#endif // CONFIG_NATIVEAP_MLME + + unsigned int tx_ra_bitmap; + u8 qos_info; + + u8 max_sp_len; + u8 uapsd_bk;//BIT(0): Delivery enabled, BIT(1): Trigger enabled + u8 uapsd_be; + u8 uapsd_vi; + u8 uapsd_vo; + + u8 has_legacy_ac; + unsigned int sleepq_ac_len; + +#ifdef CONFIG_P2P + //p2p priv data + u8 is_p2p_device; + u8 p2p_status_code; + + //p2p client info + u8 dev_addr[ETH_ALEN]; + //u8 iface_addr[ETH_ALEN];//= hwaddr[ETH_ALEN] + u8 dev_cap; + u16 config_methods; + u8 primary_dev_type[8]; + u8 num_of_secdev_type; + u8 secdev_types_list[32];// 32/8 == 4; + u16 dev_name_len; + u8 dev_name[32]; +#endif //CONFIG_P2P + +#ifdef CONFIG_TX_MCAST2UNI + u8 under_exist_checking; +#endif // CONFIG_TX_MCAST2UNI + + u8 keep_alive_trycnt; + +#endif // CONFIG_AP_MODE + +#ifdef CONFIG_IOCTL_CFG80211 + u8 *passoc_req; + u32 assoc_req_len; +#endif + + //for DM + RSSI_STA rssi_stat; + + /* To store the sequence number of received management frame */ + u16 RxMgmtFrameSeqNum; +}; + +#define sta_rx_pkts(sta) \ + (sta->sta_stats.rx_mgnt_pkts \ + + sta->sta_stats.rx_ctrl_pkts \ + + sta->sta_stats.rx_data_pkts) + +#define sta_last_rx_pkts(sta) \ + (sta->sta_stats.last_rx_mgnt_pkts \ + + sta->sta_stats.last_rx_ctrl_pkts \ + + sta->sta_stats.last_rx_data_pkts) + +#define sta_rx_data_pkts(sta) \ + (sta->sta_stats.rx_data_pkts) + +#define sta_last_rx_data_pkts(sta) \ + (sta->sta_stats.last_rx_data_pkts) + +#define sta_rx_mgnt_pkts(sta) \ + (sta->sta_stats.rx_mgnt_pkts) + +#define sta_last_rx_mgnt_pkts(sta) \ + (sta->sta_stats.last_rx_mgnt_pkts) + +#define sta_rx_beacon_pkts(sta) \ + (sta->sta_stats.rx_beacon_pkts) + +#define sta_last_rx_beacon_pkts(sta) \ + (sta->sta_stats.last_rx_beacon_pkts) + +#define sta_rx_probereq_pkts(sta) \ + (sta->sta_stats.rx_probereq_pkts) + +#define sta_last_rx_probereq_pkts(sta) \ + (sta->sta_stats.last_rx_probereq_pkts) + +#define sta_rx_probersp_pkts(sta) \ + (sta->sta_stats.rx_probersp_pkts) + +#define sta_last_rx_probersp_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_pkts) + +#define sta_rx_probersp_bm_pkts(sta) \ + (sta->sta_stats.rx_probersp_bm_pkts) + +#define sta_last_rx_probersp_bm_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_bm_pkts) + +#define sta_rx_probersp_uo_pkts(sta) \ + (sta->sta_stats.rx_probersp_uo_pkts) + +#define sta_last_rx_probersp_uo_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_uo_pkts) + +#define sta_update_last_rx_pkts(sta) \ + do { \ + sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \ + sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \ + sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \ + sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \ + sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \ + sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \ + sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \ + sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \ + } while(0) + +#define STA_RX_PKTS_ARG(sta) \ + sta->sta_stats.rx_mgnt_pkts \ + , sta->sta_stats.rx_ctrl_pkts \ + , sta->sta_stats.rx_data_pkts + +#define STA_LAST_RX_PKTS_ARG(sta) \ + sta->sta_stats.last_rx_mgnt_pkts \ + , sta->sta_stats.last_rx_ctrl_pkts \ + , sta->sta_stats.last_rx_data_pkts + +#define STA_RX_PKTS_DIFF_ARG(sta) \ + sta->sta_stats.rx_mgnt_pkts - sta->sta_stats.last_rx_mgnt_pkts \ + , sta->sta_stats.rx_ctrl_pkts - sta->sta_stats.last_rx_ctrl_pkts \ + , sta->sta_stats.rx_data_pkts -sta->sta_stats.last_rx_data_pkts + +#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)" + +struct sta_priv { + + u8 *pallocated_stainfo_buf; + u8 *pstainfo_buf; + _queue free_sta_queue; + + _lock sta_hash_lock; + _list sta_hash[NUM_STA]; + int asoc_sta_count; + _queue sleep_q; + _queue wakeup_q; + + _adapter *padapter; + + +#ifdef CONFIG_AP_MODE + _list asoc_list; + _list auth_list; + _lock asoc_list_lock; + _lock auth_list_lock; + u8 asoc_list_cnt; + u8 auth_list_cnt; + + unsigned int auth_to; //sec, time to expire in authenticating. + unsigned int assoc_to; //sec, time to expire before associating. + unsigned int expire_to; //sec , time to expire after associated. + + /* pointers to STA info; based on allocated AID or NULL if AID free + * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 + * and so on + */ + struct sta_info *sta_aid[NUM_STA]; + + u16 sta_dz_bitmap;//only support 15 stations, staion aid bitmap for sleeping sta. + u16 tim_bitmap;//only support 15 stations, aid=0~15 mapping bit0~bit15 + + u16 max_num_sta; + + struct wlan_acl_pool acl_list; +#endif + +}; + + +__inline static u32 wifi_mac_hash(u8 *mac) +{ + u32 x; + + x = mac[0]; + x = (x << 2) ^ mac[1]; + x = (x << 2) ^ mac[2]; + x = (x << 2) ^ mac[3]; + x = (x << 2) ^ mac[4]; + x = (x << 2) ^ mac[5]; + + x ^= x >> 8; + x = x & (NUM_STA - 1); + + return x; +} + + +extern u32 _rtw_init_sta_priv(struct sta_priv *pstapriv); +extern u32 _rtw_free_sta_priv(struct sta_priv *pstapriv); + +#define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) +int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); +struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset); + +extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta); +extern void rtw_free_all_stainfo(_adapter *padapter); +extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_init_bcmc_stainfo(_adapter* padapter); +extern struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter); +extern u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr); + +#endif //_STA_INFO_H_ + diff --git a/rtl8192cu-fixes/include/usb_hal.h b/rtl8192cu-fixes/include/usb_hal.h new file mode 100755 index 00000000..d765b820 --- /dev/null +++ b/rtl8192cu-fixes/include/usb_hal.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * 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 __USB_HAL_H__ +#define __USB_HAL_H__ + + +void rtl8192cu_set_hal_ops(_adapter * padapter); + +void rtl8192du_set_hal_ops(_adapter * padapter); +#ifdef CONFIG_INTEL_PROXIM +extern _adapter *rtw_usb_get_sw_pointer(void); +#endif //CONFIG_INTEL_PROXIM +#ifdef CONFIG_WOWLAN +#ifdef CONFIG_WOWLAN_MANUAL +extern int rtw_suspend_toshiba(PADAPTER Adapter); +extern int rtw_resume_toshiba(PADAPTER Adapter); +#endif // CONFIG_WOWLAN_MANUAL +#endif //CONFIG_WOWLAN +#endif //__USB_HAL_H__ + diff --git a/rtl8192cu-fixes/include/usb_ops.h b/rtl8192cu-fixes/include/usb_ops.h new file mode 100755 index 00000000..8bbec2d8 --- /dev/null +++ b/rtl8192cu-fixes/include/usb_ops.h @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * 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 __USB_OPS_H_ +#define __USB_OPS_H_ + +#include +#include +#include +#include + +#define REALTEK_USB_VENQT_READ 0xC0 +#define REALTEK_USB_VENQT_WRITE 0x40 +#define REALTEK_USB_VENQT_CMD_REQ 0x05 +#define REALTEK_USB_VENQT_CMD_IDX 0x00 + +enum{ + VENDOR_WRITE = 0x00, + VENDOR_READ = 0x01, +}; +#define ALIGNMENT_UNIT 16 +#define MAX_VENDOR_REQ_CMD_SIZE 254 //8188cu SIE Support +#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE +ALIGNMENT_UNIT) + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) +#define rtw_usb_control_msg(dev, pipe, request, requesttype, value, index, data, size, timeout_ms) \ + usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), (data), (size), (timeout_ms)) +#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout_ms) \ + usb_bulk_msg((usb_dev), (pipe), (data), (len), (actual_length), (timeout_ms)) +#else +#define rtw_usb_control_msg(dev, pipe, request, requesttype, value, index, data, size,timeout_ms) \ + usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), (data), (size), \ + ((timeout_ms) == 0) ||((timeout_ms)*HZ/1000>0)?((timeout_ms)*HZ/1000):1) +#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout_ms) \ + usb_bulk_msg((usb_dev), (pipe), (data), (len), (actual_length), \ + ((timeout_ms) == 0) ||((timeout_ms)*HZ/1000>0)?((timeout_ms)*HZ/1000):1) +#endif +#include +#endif //PLATFORM_LINUX + +#ifdef CONFIG_RTL8192C +void rtl8192cu_set_intf_ops(struct _io_ops *pops); +#define usb_set_intf_ops rtl8192cu_set_intf_ops + +void rtl8192cu_recv_tasklet(void *priv); + +void rtl8192cu_xmit_tasklet(void *priv); +#endif + +#ifdef CONFIG_RTL8192D +void rtl8192du_set_intf_ops(struct _io_ops *pops); +#define usb_set_intf_ops rtl8192du_set_intf_ops + +#ifndef PLATFORM_FREEBSD +void rtl8192du_recv_tasklet(void *priv); +#else // PLATFORM_FREEBSD +void rtl8192du_recv_tasklet(void *priv, int npending); +#ifdef CONFIG_RX_INDICATE_QUEUE +void rtw_rx_indicate_tasklet(void *priv, int npending); +#endif // CONFIG_RX_INDICATE_QUEUE +#endif // PLATFORM_FREEBSD + +void rtl8192du_xmit_tasklet(void *priv); +#endif + +/* +* Increase and check if the continual_urb_error of this @param dvobjprive is larger than MAX_CONTINUAL_URB_ERR +* @return _TRUE: +* @return _FALSE: +*/ +static inline int rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj) +{ + int ret = _FALSE; + int value; + if( (value=ATOMIC_INC_RETURN(&dvobj->continual_urb_error)) > MAX_CONTINUAL_URB_ERR) { + DBG_871X("[dvobj:%p][ERROR] continual_urb_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_URB_ERR); + ret = _TRUE; + } else { + //DBG_871X("[dvobj:%p] continual_urb_error:%d\n", dvobj, value); + } + return ret; +} + +/* +* Set the continual_urb_error of this @param dvobjprive to 0 +*/ +static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj) +{ + ATOMIC_SET(&dvobj->continual_urb_error, 0); +} + +#endif //__USB_OPS_H_ + diff --git a/rtl8192cu-fixes/include/usb_ops_linux.h b/rtl8192cu-fixes/include/usb_ops_linux.h new file mode 100755 index 00000000..d418ba26 --- /dev/null +++ b/rtl8192cu-fixes/include/usb_ops_linux.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 __USB_OPS_LINUX_H__ +#define __USB_OPS_LINUX_H__ + +#define VENDOR_CMD_MAX_DATA_LEN 254 + +#define RTW_USB_CONTROL_MSG_TIMEOUT_TEST 10//ms +#define RTW_USB_CONTROL_MSG_TIMEOUT 500//ms + +#if defined(CONFIG_VENDOR_REQ_RETRY) && defined(CONFIG_USB_VENDOR_REQ_MUTEX) +/* vendor req retry should be in the situation when each vendor req is atomically submitted from others */ +#define MAX_USBCTRL_VENDORREQ_TIMES 10 +#else +#define MAX_USBCTRL_VENDORREQ_TIMES 1 +#endif + +#define RTW_USB_BULKOUT_TIMEOUT 5000//ms + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) +#define _usbctrl_vendorreq_async_callback(urb, regs) _usbctrl_vendorreq_async_callback(urb) +#define usb_bulkout_zero_complete(purb, regs) usb_bulkout_zero_complete(purb) +#define usb_write_mem_complete(purb, regs) usb_write_mem_complete(purb) +#define usb_write_port_complete(purb, regs) usb_write_port_complete(purb) +#define usb_read_port_complete(purb, regs) usb_read_port_complete(purb) +#define usb_read_interrupt_complete(purb, regs) usb_read_interrupt_complete(purb) +#endif + +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ +int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val); +int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val); +int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val); +#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */ + +unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr); + +void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); +void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); + +void usb_read_port_cancel(struct intf_hdl *pintfhdl); + +u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); +void usb_write_port_cancel(struct intf_hdl *pintfhdl); + +#endif + diff --git a/rtl8192cu-fixes/include/usb_osintf.h b/rtl8192cu-fixes/include/usb_osintf.h new file mode 100755 index 00000000..753013dd --- /dev/null +++ b/rtl8192cu-fixes/include/usb_osintf.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * 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 __USB_OSINTF_H +#define __USB_OSINTF_H + +#include +#include +#include +#include + +#define USBD_HALTED(Status) ((ULONG)(Status) >> 30 == 3) + + +//uint usb_dvobj_init(_adapter * adapter); +//void usb_dvobj_deinit(_adapter * adapter); + +u8 usbvendorrequest(struct dvobj_priv *pdvobjpriv, RT_USB_BREQUEST brequest, RT_USB_WVALUE wvalue, u8 windex, void* data, u8 datalen, u8 isdirectionin); + + +#endif + diff --git a/rtl8192cu-fixes/include/usb_vendor_req.h b/rtl8192cu-fixes/include/usb_vendor_req.h new file mode 100755 index 00000000..f33e9825 --- /dev/null +++ b/rtl8192cu-fixes/include/usb_vendor_req.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * 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 _USB_VENDOR_REQUEST_H_ +#define _USB_VENDOR_REQUEST_H_ + +//4 Set/Get Register related wIndex/Data +#define RT_USB_RESET_MASK_OFF 0 +#define RT_USB_RESET_MASK_ON 1 +#define RT_USB_SLEEP_MASK_OFF 0 +#define RT_USB_SLEEP_MASK_ON 1 +#define RT_USB_LDO_ON 1 +#define RT_USB_LDO_OFF 0 + +//4 Set/Get SYSCLK related wValue or Data +#define RT_USB_SYSCLK_32KHZ 0 +#define RT_USB_SYSCLK_40MHZ 1 +#define RT_USB_SYSCLK_60MHZ 2 + + +typedef enum _RT_USB_BREQUEST { + RT_USB_SET_REGISTER = 1, + RT_USB_SET_SYSCLK = 2, + RT_USB_GET_SYSCLK = 3, + RT_USB_GET_REGISTER = 4 +} RT_USB_BREQUEST; + + +typedef enum _RT_USB_WVALUE { + RT_USB_RESET_MASK = 1, + RT_USB_SLEEP_MASK = 2, + RT_USB_USB_HRCPWM = 3, + RT_USB_LDO = 4, + RT_USB_BOOT_TYPE = 5 +} RT_USB_WVALUE; + + +//BOOLEAN usbvendorrequest(PCE_USB_DEVICE CEdevice, RT_USB_BREQUEST bRequest, RT_USB_WVALUE wValue, UCHAR wIndex, PVOID Data, UCHAR DataLength, BOOLEAN isDirectionIn); +//BOOLEAN CEusbGetStatusRequest(PCE_USB_DEVICE CEdevice, IN USHORT Op, IN USHORT Index, PVOID Data); +//BOOLEAN CEusbFeatureRequest(PCE_USB_DEVICE CEdevice, IN USHORT Op, IN USHORT FeatureSelector, IN USHORT Index); +//BOOLEAN CEusbGetDescriptorRequest(PCE_USB_DEVICE CEdevice, IN short urbLength, IN UCHAR DescriptorType, IN UCHAR Index, IN USHORT LanguageId, IN PVOID TransferBuffer, IN ULONG TransferBufferLength); + +#endif diff --git a/rtl8192cu-fixes/include/wifi.h b/rtl8192cu-fixes/include/wifi.h new file mode 100755 index 00000000..0bb55bb2 --- /dev/null +++ b/rtl8192cu-fixes/include/wifi.h @@ -0,0 +1,1246 @@ +/****************************************************************************** + * + * 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 _WIFI_H_ +#define _WIFI_H_ + +#include + +#ifdef BIT +//#error "BIT define occurred earlier elsewhere!\n" +#undef BIT +#endif +#define BIT(x) (1 << (x)) + + +#define WLAN_ETHHDR_LEN 14 +#define WLAN_ETHADDR_LEN 6 +#define WLAN_IEEE_OUI_LEN 3 +#define WLAN_ADDR_LEN 6 +#define WLAN_CRC_LEN 4 +#define WLAN_BSSID_LEN 6 +#define WLAN_BSS_TS_LEN 8 +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +#define WLAN_HDR_A3_QOS_LEN 26 +#define WLAN_HDR_A4_QOS_LEN 32 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_DATA_MAXLEN 2312 + +#define WLAN_A3_PN_OFFSET 24 +#define WLAN_A4_PN_OFFSET 30 + +#define WLAN_MIN_ETHFRM_LEN 60 +#define WLAN_MAX_ETHFRM_LEN 1514 +#define WLAN_ETHHDR_LEN 14 + +#define P80211CAPTURE_VERSION 0x80211001 + +#ifdef GREEN_HILL +#pragma pack(1) +#endif + +enum WIFI_FRAME_TYPE { + WIFI_MGT_TYPE = (0), + WIFI_CTRL_TYPE = (BIT(2)), + WIFI_DATA_TYPE = (BIT(3)), + WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), //!< QoS Data +}; + +enum WIFI_FRAME_SUBTYPE { + + // below is for mgt frame + WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), + WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE), + WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE), + WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), + WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE), + WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE), + WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE), + WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE), + WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE), + + // below is for control frame + WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE), + WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + + // below is for data frame + WIFI_DATA = (0 | WIFI_DATA_TYPE), + WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE), + WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE), + WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE), + WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE), + WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), +}; + +enum WIFI_REASON_CODE { + _RSON_RESERVED_ = 0, + _RSON_UNSPECIFIED_ = 1, + _RSON_AUTH_NO_LONGER_VALID_ = 2, + _RSON_DEAUTH_STA_LEAVING_ = 3, + _RSON_INACTIVITY_ = 4, + _RSON_UNABLE_HANDLE_ = 5, + _RSON_CLS2_ = 6, + _RSON_CLS3_ = 7, + _RSON_DISAOC_STA_LEAVING_ = 8, + _RSON_ASOC_NOT_AUTH_ = 9, + + // WPA reason + _RSON_INVALID_IE_ = 13, + _RSON_MIC_FAILURE_ = 14, + _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, + _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, + _RSON_DIFF_IE_ = 17, + _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, + _RSON_UNICST_CIPHER_NOT_VALID_ = 19, + _RSON_AKMP_NOT_VALID_ = 20, + _RSON_UNSUPPORT_RSNE_VER_ = 21, + _RSON_INVALID_RSNE_CAP_ = 22, + _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, + + //belowing are Realtek definition + _RSON_PMK_NOT_AVAILABLE_ = 24, + _RSON_TDLS_TEAR_TOOFAR_ = 25, + _RSON_TDLS_TEAR_UN_RSN_ = 26, +}; + +/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */ +#if 0 +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#endif +/* IEEE 802.11h */ +#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 +#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 +#if 0 +/* IEEE 802.11i */ +#define WLAN_REASON_INVALID_IE 13 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 +#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 +#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 +#define WLAN_REASON_AKMP_NOT_VALID 20 +#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 +#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 +#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#endif + +enum WIFI_STATUS_CODE { + _STATS_SUCCESSFUL_ = 0, + _STATS_FAILURE_ = 1, + _STATS_CAP_FAIL_ = 10, + _STATS_NO_ASOC_ = 11, + _STATS_OTHER_ = 12, + _STATS_NO_SUPP_ALG_ = 13, + _STATS_OUT_OF_AUTH_SEQ_ = 14, + _STATS_CHALLENGE_FAIL_ = 15, + _STATS_AUTH_TIMEOUT_ = 16, + _STATS_UNABLE_HANDLE_STA_ = 17, + _STATS_RATE_FAIL_ = 18, +}; + +/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) */ +#if 0 +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +#endif +//entended +/* IEEE 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 +/* IEEE 802.11h */ +#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 +#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 +#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 +/* IEEE 802.11g */ +#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 +#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 +/* IEEE 802.11w */ +#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 +#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +/* IEEE 802.11i */ +#define WLAN_STATUS_INVALID_IE 40 +#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 +#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 +#define WLAN_STATUS_AKMP_NOT_VALID 43 +#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 +#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 +#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 +/* IEEE 802.11r */ +#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 +#define WLAN_STATUS_INVALID_PMKID 53 +#define WLAN_STATUS_INVALID_MDIE 54 +#define WLAN_STATUS_INVALID_FTIE 55 + + +enum WIFI_REG_DOMAIN { + DOMAIN_FCC = 1, + DOMAIN_IC = 2, + DOMAIN_ETSI = 3, + DOMAIN_SPAIN = 4, + DOMAIN_FRANCE = 5, + DOMAIN_MKK = 6, + DOMAIN_ISRAEL = 7, + DOMAIN_MKK1 = 8, + DOMAIN_MKK2 = 9, + DOMAIN_MKK3 = 10, + DOMAIN_MAX +}; + +#define _TO_DS_ BIT(8) +#define _FROM_DS_ BIT(9) +#define _MORE_FRAG_ BIT(10) +#define _RETRY_ BIT(11) +#define _PWRMGT_ BIT(12) +#define _MORE_DATA_ BIT(13) +#define _PRIVACY_ BIT(14) +#define _ORDER_ BIT(15) + +#define SetToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_TO_DS_); \ + } while(0) + +#define GetToDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_TO_DS_)) != 0) + +#define ClearToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \ + } while(0) + +#define SetFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_FROM_DS_); \ + } while(0) + +#define GetFrDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_FROM_DS_)) != 0) + +#define ClearFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ + } while(0) + +#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) + + +#define SetMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \ + } while(0) + +#define GetMFrag(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_FRAG_)) != 0) + +#define ClearMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \ + } while(0) + +#define SetRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_RETRY_); \ + } while(0) + +#define GetRetry(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_RETRY_)) != 0) + +#define ClearRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \ + } while(0) + +#define SetPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PWRMGT_); \ + } while(0) + +#define GetPwrMgt(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PWRMGT_)) != 0) + +#define ClearPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \ + } while(0) + +#define SetMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \ + } while(0) + +#define GetMData(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_DATA_)) != 0) + +#define ClearMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \ + } while(0) + +#define SetPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PRIVACY_); \ + } while(0) + +#define GetPrivacy(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PRIVACY_)) != 0) + +#define ClearPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)); \ + } while(0) + + +#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + +#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & (BIT(3) | BIT(2))) + +#define SetFrameType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \ + } while(0) + +#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))) + +#define SetFrameSubType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + } while(0) + +#define GetSequence(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) >> 4) + +#define GetFragNum(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & 0x0f) + +#define GetTupleCache(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22))) + +#define SetFragNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu(~(0x000f))) | \ + cpu_to_le16(0x0f & (num)); \ + } while(0) + +#define SetSeqNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu((unsigned short)~0xfff0)) | \ + le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \ + } while(0) + +#define SetDuration(pbuf, dur) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 2) = cpu_to_le16(0xffff & (dur)); \ + } while(0) + + +#define SetPriority(pbuf, tid) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf); \ + } while(0) + +#define GetPriority(pbuf) ((le16_to_cpu(*(unsigned short *)(pbuf))) & 0xf) + +#define SetEOSP(pbuf, eosp) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (eosp & 1) << 4); \ + } while(0) + +#define SetAckpolicy(pbuf, ack) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (ack & 3) << 5); \ + } while(0) + +#define GetAckpolicy(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 5) & 0x3) + +#define GetAMsdu(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 7) & 0x1) + +#define SetAMsdu(pbuf, amsdu) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (amsdu & 1) << 7); \ + } while(0) + +#define GetAid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 2)) & 0x3fff) + +#define GetTid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + (((GetToDs(pbuf)<<1)|GetFrDs(pbuf))==3?30:24))) & 0x000f) + +#define GetAddr1Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 4)) + +#define GetAddr2Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 10)) + +#define GetAddr3Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 16)) + +#define GetAddr4Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 24)) + +#define MacAddr_isBcst(addr) \ +( \ + ( (addr[0] == 0xff) && (addr[1] == 0xff) && \ + (addr[2] == 0xff) && (addr[3] == 0xff) && \ + (addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \ +) + +__inline static int IS_MCAST(unsigned char *da) +{ + if ((*da) & 0x01) + return _TRUE; + else + return _FALSE; +} + + +__inline static unsigned char * get_da(unsigned char *pframe) +{ + unsigned char *da; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + da = GetAddr1Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + da = GetAddr1Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + da = GetAddr3Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + da = GetAddr3Ptr(pframe); + break; + } + + return da; +} + + +__inline static unsigned char * get_sa(unsigned char *pframe) +{ + unsigned char *sa; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr3Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + sa = GetAddr4Ptr(pframe); + break; + } + + return sa; +} + +__inline static unsigned char * get_hdr_bssid(unsigned char *pframe) +{ + unsigned char *sa; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr3Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr2Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr1Ptr(pframe); + break; + case 0x03: // ToDs=1, FromDs=1 + sa = GetAddr1Ptr(pframe); + break; + default: + sa =NULL; //??????? + break; + } + + return sa; +} + + +__inline static int IsFrameTypeCtrl(unsigned char *pframe) +{ + if(WIFI_CTRL_TYPE == GetFrameType(pframe)) + return _TRUE; + else + return _FALSE; +} +/*----------------------------------------------------------------------------- + Below is for the security related definition +------------------------------------------------------------------------------*/ +#define _RESERVED_FRAME_TYPE_ 0 +#define _SKB_FRAME_TYPE_ 2 +#define _PRE_ALLOCMEM_ 1 +#define _PRE_ALLOCHDR_ 3 +#define _PRE_ALLOCLLCHDR_ 4 +#define _PRE_ALLOCICVHDR_ 5 +#define _PRE_ALLOCMICHDR_ 6 + +#define _SIFSTIME_ ((priv->pmib->dot11BssType.net_work_type&WIRELESS_11A)?16:10) +#define _ACKCTSLNG_ 14 //14 bytes long, including crclng +#define _CRCLNG_ 4 + +#define _ASOCREQ_IE_OFFSET_ 4 // excluding wlan_hdr +#define _ASOCRSP_IE_OFFSET_ 6 +#define _REASOCREQ_IE_OFFSET_ 10 +#define _REASOCRSP_IE_OFFSET_ 6 +#define _PROBEREQ_IE_OFFSET_ 0 +#define _PROBERSP_IE_OFFSET_ 12 +#define _AUTH_IE_OFFSET_ 6 +#define _DEAUTH_IE_OFFSET_ 0 +#define _BEACON_IE_OFFSET_ 12 +#define _PUBLIC_ACTION_IE_OFFSET_ 8 + +#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_ + +#define _SSID_IE_ 0 +#define _SUPPORTEDRATES_IE_ 1 +#define _DSSET_IE_ 3 +#define _TIM_IE_ 5 +#define _IBSS_PARA_IE_ 6 +#define _COUNTRY_IE_ 7 +#define _CHLGETXT_IE_ 16 +#define _POW_CAP_IE_ 33 +#define _SUPPORTED_CH_IE_ 36 +#define _CH_SWTICH_ANNOUNCE_ 37 //Secondary Channel Offset +#define _RSN_IE_2_ 48 +#define _SSN_IE_1_ 221 +#define _ERPINFO_IE_ 42 +#define _EXT_SUPPORTEDRATES_IE_ 50 + +#define _HT_CAPABILITY_IE_ 45 +#define _FTIE_ 55 +#define _TIMEOUT_ITVL_IE_ 56 +#define _SRC_IE_ 59 +#define _HT_EXTRA_INFO_IE_ 61 +#define _HT_ADD_INFO_IE_ 61 //_HT_EXTRA_INFO_IE_ + +#define EID_BSSCoexistence 72 // 20/40 BSS Coexistence +#define EID_BSSIntolerantChlReport 73 +#define _RIC_Descriptor_IE_ 75 + +#ifdef CONFIG_IEEE80211W +#define _MME_IE_ 76 //802.11w Management MIC element +#endif //CONFIG_IEEE80211W +#define _LINK_ID_IE_ 101 +#define _CH_SWITCH_TIMING_ 104 +#define _PTI_BUFFER_STATUS_ 106 +#define _EXT_CAP_IE_ 127 +#define _VENDOR_SPECIFIC_IE_ 221 + +#define _RESERVED47_ 47 + +/* --------------------------------------------------------------------------- + Below is the fixed elements... +-----------------------------------------------------------------------------*/ +#define _AUTH_ALGM_NUM_ 2 +#define _AUTH_SEQ_NUM_ 2 +#define _BEACON_ITERVAL_ 2 +#define _CAPABILITY_ 2 +#define _CURRENT_APADDR_ 6 +#define _LISTEN_INTERVAL_ 2 +#define _RSON_CODE_ 2 +#define _ASOC_ID_ 2 +#define _STATUS_CODE_ 2 +#define _TIMESTAMP_ 8 + +#define AUTH_ODD_TO 0 +#define AUTH_EVEN_TO 1 + +#define WLAN_ETHCONV_ENCAP 1 +#define WLAN_ETHCONV_RFC1042 2 +#define WLAN_ETHCONV_8021h 3 + +#define cap_ESS BIT(0) +#define cap_IBSS BIT(1) +#define cap_CFPollable BIT(2) +#define cap_CFRequest BIT(3) +#define cap_Privacy BIT(4) +#define cap_ShortPremble BIT(5) +#define cap_PBCC BIT(6) +#define cap_ChAgility BIT(7) +#define cap_SpecMgmt BIT(8) +#define cap_QoS BIT(9) +#define cap_ShortSlot BIT(10) + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11i / 802.1x +------------------------------------------------------------------------------*/ +#define _IEEE8021X_MGT_ 1 // WPA +#define _IEEE8021X_PSK_ 2 // WPA with pre-shared key + +/* +#define _NO_PRIVACY_ 0 +#define _WEP_40_PRIVACY_ 1 +#define _TKIP_PRIVACY_ 2 +#define _WRAP_PRIVACY_ 3 +#define _CCMP_PRIVACY_ 4 +#define _WEP_104_PRIVACY_ 5 +#define _WEP_WPA_MIXED_PRIVACY_ 6 // WEP + WPA +*/ + +#ifdef CONFIG_IEEE80211W +#define _MME_IE_LENGTH_ 18 +#endif //CONFIG_IEEE80211W +/*----------------------------------------------------------------------------- + Below is the definition for WMM +------------------------------------------------------------------------------*/ +#define _WMM_IE_Length_ 7 // for WMM STA +#define _WMM_Para_Element_Length_ 24 + + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11n +------------------------------------------------------------------------------*/ + +/* block-ack parameters */ +#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C +#define RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 +#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 +#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 + +//#ifdef CONFIG_80211N_HT + +#define SetOrderBit(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ + } while(0) + +#define GetOrderBit(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + + +/** + * struct rtw_ieee80211_bar - HT Block Ack Request + * + * This structure refers to "HT BlockAckReq" as + * described in 802.11n draft section 7.2.1.7.1 + */ + #if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) +struct rtw_ieee80211_bar { + unsigned short frame_control; + unsigned short duration; + unsigned char ra[6]; + unsigned char ta[6]; + unsigned short control; + unsigned short start_seq_num; +} __attribute__((packed)); + #endif + +/* 802.11 BAR control masks */ +#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 +#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 + + + #if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) || defined(PLATFORM_FREEBSD) + + + + /** + * struct rtw_ieee80211_ht_cap - HT capabilities + * + * This structure refers to "HT capabilities element" as + * described in 802.11n draft section 7.3.2.52 + */ + +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +} __attribute__ ((packed)); + +/** + * struct rtw_ieee80211_ht_cap - HT additional information + * + * This structure refers to "HT information element" as + * described in 802.11n draft section 7.3.2.53 + */ +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +} __attribute__ ((packed)); + + +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } HT_cap_element; + unsigned char HT_cap[26]; + }u; +} __attribute__ ((packed)); + +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +} __attribute__ ((packed)); + +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +} __attribute__ ((packed)); + +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +} __attribute__ ((packed)); + +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +} __attribute__ ((packed)); + + + +#endif + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +}; + + +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +}; + +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } HT_cap_element; + unsigned char HT_cap[26]; + }; +}; + +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +}; + +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +}; + +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +}; + +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +}; + + +#pragma pack() + +#endif + + +/* 802.11n HT capabilities masks */ +#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 +#define IEEE80211_HT_CAP_SM_PS 0x000C +#define IEEE80211_HT_CAP_GRN_FLD 0x0010 +#define IEEE80211_HT_CAP_SGI_20 0x0020 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_TX_STBC 0x0080 +#define IEEE80211_HT_CAP_RX_STBC 0x0300 +#define IEEE80211_HT_CAP_DELAY_BA 0x0400 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 +/* 802.11n HT capability AMPDU settings */ +#define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03 +#define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C +/* 802.11n HT capability MSC set */ +#define IEEE80211_SUPP_MCS_SET_UEQM 4 +#define IEEE80211_HT_CAP_MAX_STREAMS 4 +#define IEEE80211_SUPP_MCS_SET_LEN 10 +/* maximum streams the spec allows */ +#define IEEE80211_HT_CAP_MCS_TX_DEFINED 0x01 +#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF 0x02 +#define IEEE80211_HT_CAP_MCS_TX_STREAMS 0x0C +#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 +/* 802.11n HT IE masks */ +#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 +#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 +#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 +#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 +#define IEEE80211_HT_IE_CHA_WIDTH 0x04 +#define IEEE80211_HT_IE_HT_PROTECTION 0x0003 +#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 +#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 + +/* block-ack parameters */ +#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C +#define RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 +#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 +#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 + +/* + * A-PMDU buffer sizes + * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) + */ +#define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_MAX_AMPDU_BUF 0x40 + + +/* Spatial Multiplexing Power Save Modes */ +#define WLAN_HT_CAP_SM_PS_STATIC 0 +#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 +#define WLAN_HT_CAP_SM_PS_INVALID 2 +#define WLAN_HT_CAP_SM_PS_DISABLED 3 + + +#define OP_MODE_PURE 0 +#define OP_MODE_MAY_BE_LEGACY_STAS 1 +#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 +#define OP_MODE_MIXED 3 + +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) + +#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ + ((u16) (0x0001 | 0x0002)) +#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BCN ((u16) BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) + + + +//#endif + +// ===============WPS Section=============== +// For WPSv1.0 +#define WPSOUI 0x0050f204 +// WPS attribute ID +#define WPS_ATTR_VER1 0x104A +#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044 +#define WPS_ATTR_RESP_TYPE 0x103B +#define WPS_ATTR_UUID_E 0x1047 +#define WPS_ATTR_MANUFACTURER 0x1021 +#define WPS_ATTR_MODEL_NAME 0x1023 +#define WPS_ATTR_MODEL_NUMBER 0x1024 +#define WPS_ATTR_SERIAL_NUMBER 0x1042 +#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054 +#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055 +#define WPS_ATTR_DEVICE_NAME 0x1011 +#define WPS_ATTR_CONF_METHOD 0x1008 +#define WPS_ATTR_RF_BANDS 0x103C +#define WPS_ATTR_DEVICE_PWID 0x1012 +#define WPS_ATTR_REQUEST_TYPE 0x103A +#define WPS_ATTR_ASSOCIATION_STATE 0x1002 +#define WPS_ATTR_CONFIG_ERROR 0x1009 +#define WPS_ATTR_VENDOR_EXT 0x1049 +#define WPS_ATTR_SELECTED_REGISTRAR 0x1041 + +// Value of WPS attribute "WPS_ATTR_DEVICE_NAME +#define WPS_MAX_DEVICE_NAME_LEN 32 + +// Value of WPS Request Type Attribute +#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 +#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 +#define WPS_REQ_TYPE_REGISTRAR 0x02 +#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR 0x03 + +// Value of WPS Response Type Attribute +#define WPS_RESPONSE_TYPE_INFO_ONLY 0x00 +#define WPS_RESPONSE_TYPE_8021X 0x01 +#define WPS_RESPONSE_TYPE_REGISTRAR 0x02 +#define WPS_RESPONSE_TYPE_AP 0x03 + +// Value of WPS WiFi Simple Configuration State Attribute +#define WPS_WSC_STATE_NOT_CONFIG 0x01 +#define WPS_WSC_STATE_CONFIG 0x02 + +// Value of WPS Version Attribute +#define WPS_VERSION_1 0x10 + +// Value of WPS Configuration Method Attribute +#define WPS_CONFIG_METHOD_FLASH 0x0001 +#define WPS_CONFIG_METHOD_ETHERNET 0x0002 +#define WPS_CONFIG_METHOD_LABEL 0x0004 +#define WPS_CONFIG_METHOD_DISPLAY 0x0008 +#define WPS_CONFIG_METHOD_E_NFC 0x0010 +#define WPS_CONFIG_METHOD_I_NFC 0x0020 +#define WPS_CONFIG_METHOD_NFC 0x0040 +#define WPS_CONFIG_METHOD_PBC 0x0080 +#define WPS_CONFIG_METHOD_KEYPAD 0x0100 +#define WPS_CONFIG_METHOD_VPBC 0x0280 +#define WPS_CONFIG_METHOD_PPBC 0x0480 +#define WPS_CONFIG_METHOD_VDISPLAY 0x2008 +#define WPS_CONFIG_METHOD_PDISPLAY 0x4008 + +// Value of Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_CID_DISPLAYS 0x0007 +#define WPS_PDT_CID_MULIT_MEDIA 0x0008 +#define WPS_PDT_CID_RTK_WIDI WPS_PDT_CID_MULIT_MEDIA + +// Value of Sub Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_SCID_MEDIA_SERVER 0x0005 +#define WPS_PDT_SCID_RTK_DMP WPS_PDT_SCID_MEDIA_SERVER + +// Value of Device Password ID +#define WPS_DPID_PIN 0x0000 +#define WPS_DPID_USER_SPEC 0x0001 +#define WPS_DPID_MACHINE_SPEC 0x0002 +#define WPS_DPID_REKEY 0x0003 +#define WPS_DPID_PBC 0x0004 +#define WPS_DPID_REGISTRAR_SPEC 0x0005 + +// Value of WPS RF Bands Attribute +#define WPS_RF_BANDS_2_4_GHZ 0x01 +#define WPS_RF_BANDS_5_GHZ 0x02 + +// Value of WPS Association State Attribute +#define WPS_ASSOC_STATE_NOT_ASSOCIATED 0x00 +#define WPS_ASSOC_STATE_CONNECTION_SUCCESS 0x01 +#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE 0x02 +#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03 +#define WPS_ASSOC_STATE_IP_FAILURE 0x04 + +// =====================P2P Section===================== +// For P2P +#define P2POUI 0x506F9A09 + +// P2P Attribute ID +#define P2P_ATTR_STATUS 0x00 +#define P2P_ATTR_MINOR_REASON_CODE 0x01 +#define P2P_ATTR_CAPABILITY 0x02 +#define P2P_ATTR_DEVICE_ID 0x03 +#define P2P_ATTR_GO_INTENT 0x04 +#define P2P_ATTR_CONF_TIMEOUT 0x05 +#define P2P_ATTR_LISTEN_CH 0x06 +#define P2P_ATTR_GROUP_BSSID 0x07 +#define P2P_ATTR_EX_LISTEN_TIMING 0x08 +#define P2P_ATTR_INTENTED_IF_ADDR 0x09 +#define P2P_ATTR_MANAGEABILITY 0x0A +#define P2P_ATTR_CH_LIST 0x0B +#define P2P_ATTR_NOA 0x0C +#define P2P_ATTR_DEVICE_INFO 0x0D +#define P2P_ATTR_GROUP_INFO 0x0E +#define P2P_ATTR_GROUP_ID 0x0F +#define P2P_ATTR_INTERFACE 0x10 +#define P2P_ATTR_OPERATING_CH 0x11 +#define P2P_ATTR_INVITATION_FLAGS 0x12 + +// Value of Status Attribute +#define P2P_STATUS_SUCCESS 0x00 +#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02 +#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03 +#define P2P_STATUS_FAIL_INVALID_PARAM 0x04 +#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05 +#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06 +#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07 +#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08 +#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A +#define P2P_STATUS_FAIL_USER_REJECT 0x0B + +// Value of Inviation Flags Attribute +#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) + +#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ + P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ + P2P_DEVCAP_CONCURRENT_OPERATION | \ + P2P_DEVCAP_INVITATION_PROC) + +#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) + +// Value of Device Capability Bitmap +#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) +#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1) +#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2) +#define P2P_DEVCAP_INFRA_MANAGED BIT(3) +#define P2P_DEVCAP_DEVICE_LIMIT BIT(4) +#define P2P_DEVCAP_INVITATION_PROC BIT(5) + +// Value of Group Capability Bitmap +#define P2P_GRPCAP_GO BIT(0) +#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1) +#define P2P_GRPCAP_GROUP_LIMIT BIT(2) +#define P2P_GRPCAP_INTRABSS BIT(3) +#define P2P_GRPCAP_CROSS_CONN BIT(4) +#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5) +#define P2P_GRPCAP_GROUP_FORMATION BIT(6) + +// P2P Public Action Frame ( Management Frame ) +#define P2P_PUB_ACTION_ACTION 0x09 + +// P2P Public Action Frame Type +#define P2P_GO_NEGO_REQ 0 +#define P2P_GO_NEGO_RESP 1 +#define P2P_GO_NEGO_CONF 2 +#define P2P_INVIT_REQ 3 +#define P2P_INVIT_RESP 4 +#define P2P_DEVDISC_REQ 5 +#define P2P_DEVDISC_RESP 6 +#define P2P_PROVISION_DISC_REQ 7 +#define P2P_PROVISION_DISC_RESP 8 + +// P2P Action Frame Type +#define P2P_NOTICE_OF_ABSENCE 0 +#define P2P_PRESENCE_REQUEST 1 +#define P2P_PRESENCE_RESPONSE 2 +#define P2P_GO_DISC_REQUEST 3 + + +#define P2P_MAX_PERSISTENT_GROUP_NUM 10 + +#define P2P_PROVISIONING_SCAN_CNT 3 + +#define P2P_WILDCARD_SSID_LEN 7 + +#define P2P_FINDPHASE_EX_NONE 0 // default value, used when: (1)p2p disabed or (2)p2p enabled but only do 1 scan phase +#define P2P_FINDPHASE_EX_FULL 1 // used when p2p enabled and want to do 1 scan phase and P2P_FINDPHASE_EX_MAX-1 find phase +#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1) +#define P2P_FINDPHASE_EX_MAX 4 +#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX + +#define P2P_PROVISION_TIMEOUT 5000 // 5 seconds timeout for sending the provision discovery request +#define P2P_CONCURRENT_PROVISION_TIMEOUT 3000 // 3 seconds timeout for sending the provision discovery request under concurrent mode +#define P2P_GO_NEGO_TIMEOUT 5000 // 5 seconds timeout for receiving the group negotation response +#define P2P_CONCURRENT_GO_NEGO_TIMEOUT 3000 // 3 seconds timeout for sending the negotiation request under concurrent mode +#define P2P_TX_PRESCAN_TIMEOUT 100 // 100ms +#define P2P_INVITE_TIMEOUT 5000 // 5 seconds timeout for sending the invitation request +#define P2P_CONCURRENT_INVITE_TIMEOUT 3000 // 3 seconds timeout for sending the invitation request under concurrent mode +#define P2P_RESET_SCAN_CH 15000 // 15 seconds timeout to reset the scan channel ( based on channel plan ) +#define P2P_MAX_INTENT 15 + +#define P2P_MAX_NOA_NUM 2 + +// WPS Configuration Method +#define WPS_CM_NONE 0x0000 +#define WPS_CM_LABEL 0x0004 +#define WPS_CM_DISPLYA 0x0008 +#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010 +#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020 +#define WPS_CM_NFC_INTERFACE 0x0040 +#define WPS_CM_PUSH_BUTTON 0x0080 +#define WPS_CM_KEYPAD 0x0100 +#define WPS_CM_SW_PUHS_BUTTON 0x0280 +#define WPS_CM_HW_PUHS_BUTTON 0x0480 +#define WPS_CM_SW_DISPLAY_PIN 0x2008 +#define WPS_CM_LCD_DISPLAY_PIN 0x4008 + +enum P2P_ROLE { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum P2P_STATE { + P2P_STATE_NONE = 0, // P2P disable + P2P_STATE_IDLE = 1, // P2P had enabled and do nothing + P2P_STATE_LISTEN = 2, // In pure listen state + P2P_STATE_SCAN = 3, // In scan phase + P2P_STATE_FIND_PHASE_LISTEN = 4, // In the listen state of find phase + P2P_STATE_FIND_PHASE_SEARCH = 5, // In the search state of find phase + P2P_STATE_TX_PROVISION_DIS_REQ = 6, // In P2P provisioning discovery + P2P_STATE_RX_PROVISION_DIS_RSP = 7, + P2P_STATE_RX_PROVISION_DIS_REQ = 8, + P2P_STATE_GONEGO_ING = 9, // Doing the group owner negoitation handshake + P2P_STATE_GONEGO_OK = 10, // finish the group negoitation handshake with success + P2P_STATE_GONEGO_FAIL = 11, // finish the group negoitation handshake with failure + P2P_STATE_RECV_INVITE_REQ_MATCH = 12, // receiving the P2P Inviation request and match with the profile. + P2P_STATE_PROVISIONING_ING = 13, // Doing the P2P WPS + P2P_STATE_PROVISIONING_DONE = 14, // Finish the P2P WPS + P2P_STATE_TX_INVITE_REQ = 15, // Transmit the P2P Invitation request + P2P_STATE_RX_INVITE_RESP_OK = 16, // Receiving the P2P Invitation response with sucess + P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, // receiving the P2P Inviation request and dismatch with the profile. + P2P_STATE_RECV_INVITE_REQ_GO = 18, // receiving the P2P Inviation request and this wifi is GO. + P2P_STATE_RECV_INVITE_REQ_JOIN = 19, // receiving the P2P Inviation request to join an existing P2P Group. + P2P_STATE_RX_INVITE_RESP_FAIL = 20, // recveing the P2P Inviation response with failure + P2P_STATE_RX_INFOR_NOREADY = 21, // receiving p2p negoitation response with information is not available + P2P_STATE_TX_INFOR_NOREADY = 22, // sending p2p negoitation response with information is not available +}; + +enum P2P_WPSINFO { + P2P_NO_WPSINFO = 0, + P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, + P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, + P2P_GOT_WPSINFO_PBC = 3, +}; + +#define P2P_PRIVATE_IOCTL_SET_LEN 64 + +enum P2P_PROTO_WK_ID +{ + P2P_FIND_PHASE_WK = 0, + P2P_RESTORE_STATE_WK = 1, + P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, + P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, + P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, + P2P_AP_P2P_CH_SWITCH_PROCESS_WK =5, + P2P_RO_CH_WK = 6, +}; + +#ifdef CONFIG_P2P_PS +enum P2P_PS_STATE +{ + P2P_PS_DISABLE = 0, + P2P_PS_ENABLE = 1, + P2P_PS_SCAN = 2, + P2P_PS_SCAN_DONE = 3, + P2P_PS_ALLSTASLEEP = 4, // for P2P GO +}; + +enum P2P_PS_MODE +{ + P2P_PS_NONE = 0, + P2P_PS_CTWINDOW = 1, + P2P_PS_NOA = 2, + P2P_PS_MIX = 3, // CTWindow and NoA +}; +#endif // CONFIG_P2P_PS + +// =====================WFD Section===================== +// For Wi-Fi Display +#define WFD_ATTR_DEVICE_INFO 0x00 +#define WFD_ATTR_ASSOC_BSSID 0x01 +#define WFD_ATTR_COUPLED_SINK_INFO 0x06 +#define WFD_ATTR_LOCAL_IP_ADDR 0x08 +#define WFD_ATTR_SESSION_INFO 0x09 +#define WFD_ATTR_ALTER_MAC 0x0a + +// For WFD Device Information Attribute +#define WFD_DEVINFO_SOURCE 0x0000 +#define WFD_DEVINFO_PSINK 0x0001 +#define WFD_DEVINFO_SSINK 0x0002 +#define WFD_DEVINFO_DUAL 0x0003 + +#define WFD_DEVINFO_SESSION_AVAIL 0x0010 +#define WFD_DEVINFO_WSD 0x0040 +#define WFD_DEVINFO_PC_TDLS 0x0080 +#define WFD_DEVINFO_HDCP_SUPPORT 0x0100 + + +#ifdef CONFIG_TX_MCAST2UNI +#define IP_MCAST_MAC(mac) ((mac[0]==0x01)&&(mac[1]==0x00)&&(mac[2]==0x5e)) +#define ICMPV6_MCAST_MAC(mac) ((mac[0]==0x33)&&(mac[1]==0x33)&&(mac[2]!=0xff)) +#endif // CONFIG_TX_MCAST2UNI + + + +#endif // _WIFI_H_ + diff --git a/rtl8192cu-fixes/include/wlan_bssdef.h b/rtl8192cu-fixes/include/wlan_bssdef.h new file mode 100755 index 00000000..1cf93dca --- /dev/null +++ b/rtl8192cu-fixes/include/wlan_bssdef.h @@ -0,0 +1,703 @@ +/****************************************************************************** + * + * 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 __WLAN_BSSDEF_H__ +#define __WLAN_BSSDEF_H__ + + +#define MAX_IE_SZ 768 + + +#ifdef PLATFORM_LINUX + +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef ULONG NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + ULONG SsidLength; + UCHAR Ssid[32]; +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + ULONG Length; // Length of structure + ULONG HopPattern; // As defined by 802.11, MSB set + ULONG HopSet; // to one if non-802.11 + ULONG DwellTime; // units are Kusec +} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + ULONG Length; // Length of structure + ULONG BeaconPeriod; // units are Kusec + ULONG ATIMWindow; // units are Kusec + ULONG DSConfig; // Frequency, units are kHz + NDIS_802_11_CONFIGURATION_FH FHConfig; +} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + UCHAR Timestamp[8]; + USHORT BeaconInterval; + USHORT Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + UCHAR ElementID; + UCHAR Length; + UCHAR data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + ULONG NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + USHORT Capabilities; + USHORT ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + USHORT Capabilities; + USHORT StatusCode; + USHORT AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + ULONG Length; + USHORT AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + ULONG RequestIELength; + ULONG OffsetRequestIEs; + USHORT AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + ULONG ResponseIELength; + ULONG OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + ULONG KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + UCHAR KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; // 0 is the per-client key, 1-N are the global keys + ULONG KeyLength; // length of key in bytes + UCHAR KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + ULONG Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + ULONG Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + ULONG Length; + ULONG Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //end of #ifdef PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef ULONG NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + ULONG SsidLength; + UCHAR Ssid[32]; +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + ULONG Length; // Length of structure + ULONG HopPattern; // As defined by 802.11, MSB set + ULONG HopSet; // to one if non-802.11 + ULONG DwellTime; // units are Kusec +} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + ULONG Length; // Length of structure + ULONG BeaconPeriod; // units are Kusec + ULONG ATIMWindow; // units are Kusec + ULONG DSConfig; // Frequency, units are kHz + NDIS_802_11_CONFIGURATION_FH FHConfig; +} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + UCHAR Timestamp[8]; + USHORT BeaconInterval; + USHORT Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + UCHAR ElementID; + UCHAR Length; + UCHAR data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + ULONG NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + USHORT Capabilities; + USHORT ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + USHORT Capabilities; + USHORT StatusCode; + USHORT AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + ULONG Length; + USHORT AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + ULONG RequestIELength; + ULONG OffsetRequestIEs; + USHORT AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + ULONG ResponseIELength; + ULONG OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + ULONG KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + UCHAR KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; // 0 is the per-client key, 1-N are the global keys + ULONG KeyLength; // length of key in bytes + UCHAR KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + ULONG Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + ULONG Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + ULONG Length; + ULONG Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //PLATFORM_FREEBSD +#ifndef Ndis802_11APMode +#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1) +#endif + +typedef struct _WLAN_PHY_INFO +{ + u8 SignalStrength;//(in percentage) + u8 SignalQuality;//(in percentage) + u8 Optimum_antenna; //for Antenna diversity + u8 Reserved_0; +}WLAN_PHY_INFO,*PWLAN_PHY_INFO; + +/* temporally add #pragma pack for structure alignment issue of +* WLAN_BSSID_EX and get_WLAN_BSSID_EX_sz() +*/ +#ifdef PLATFORM_WINDOWS +#pragma pack(push) +#pragma pack(1) +#endif +typedef struct _WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi;//(in dBM,raw data ,get from PHY) + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + WLAN_PHY_INFO PhyInfo; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} +#ifndef PLATFORM_WINDOWS +__attribute__((packed)) +#endif +WLAN_BSSID_EX, *PWLAN_BSSID_EX; +#ifdef PLATFORM_WINDOWS +#pragma pack(pop) +#endif + +__inline static uint get_WLAN_BSSID_EX_sz(WLAN_BSSID_EX *bss) +{ + return (sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + bss->IELength); +} + +struct wlan_network { + _list list; + int network_type; //refer to ieee80211.h for WIRELESS_11A/B/G + int fixed; // set to fixed when not to be removed as site-surveying + unsigned long last_scanned; //timestamp for the network + int aid; //will only be valid when a BSS is joinned. + int join_res; + WLAN_BSSID_EX network; //must be the last item +#ifdef PLATFORM_WINDOWS + unsigned char iebuf[MAX_IE_SZ]; +#endif + +}; + +enum VRTL_CARRIER_SENSE +{ + DISABLE_VCS, + ENABLE_VCS, + AUTO_VCS +}; + +enum VCS_TYPE +{ + NONE_VCS, + RTS_CTS, + CTS_TO_SELF +}; + + + + +#define PWR_CAM 0 +#define PWR_MINPS 1 +#define PWR_MAXPS 2 +#define PWR_UAPSD 3 +#define PWR_VOIP 4 + + +enum UAPSD_MAX_SP +{ + NO_LIMIT, + TWO_MSDU, + FOUR_MSDU, + SIX_MSDU +}; + + +//john +#define NUM_PRE_AUTH_KEY 16 +#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY + +/* +* WPA2 +*/ + +#ifndef PLATFORM_OS_CE +typedef struct _PMKID_CANDIDATE { + NDIS_802_11_MAC_ADDRESS BSSID; + ULONG Flags; +} PMKID_CANDIDATE, *PPMKID_CANDIDATE; + +typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST +{ + ULONG Version; // Version of the structure + ULONG NumCandidates; // No. of pmkid candidates + PMKID_CANDIDATE CandidateList[1]; +} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST; + + +typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION +{ + NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; + NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; + +} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION; + +typedef struct _NDIS_802_11_CAPABILITY +{ + ULONG Length; + ULONG Version; + ULONG NoOfPMKIDs; + ULONG NoOfAuthEncryptPairsSupported; + NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1]; + +} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY; +#endif + + +#endif //#ifndef WLAN_BSSDEF_H_ + diff --git a/rtl8192cu-fixes/include/xmit_osdep.h b/rtl8192cu-fixes/include/xmit_osdep.h new file mode 100755 index 00000000..e5848ece --- /dev/null +++ b/rtl8192cu-fixes/include/xmit_osdep.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * 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 __XMIT_OSDEP_H_ +#define __XMIT_OSDEP_H_ + +#include +#include +#include + +struct pkt_file { + _pkt *pkt; + SIZE_T pkt_len; //the remainder length of the open_file + _buffer *cur_buffer; + u8 *buf_start; + u8 *cur_addr; + SIZE_T buf_len; +}; + +#ifdef PLATFORM_WINDOWS + +#ifdef PLATFORM_OS_XP +#ifdef CONFIG_USB_HCI +#include +#include +#include +#endif +#endif + +#define NR_XMITFRAME 128 + +#define ETH_ALEN 6 + +extern NDIS_STATUS rtw_xmit_entry( +IN _nic_hdl cnxt, +IN NDIS_PACKET *pkt, +IN UINT flags +); + +#endif + +#ifdef PLATFORM_FREEBSD +#define NR_XMITFRAME 256 +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); +extern void rtw_xmit_entry_wrap (struct ifnet * pifp); +#endif //PLATFORM_FREEBSD + +#ifdef PLATFORM_LINUX + +#define NR_XMITFRAME 256 + +struct xmit_priv; +struct pkt_attrib; +struct sta_xmit_priv; +struct xmit_frame; +struct xmit_buf; + +extern int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); + +#endif + +void rtw_os_xmit_schedule(_adapter *padapter); + +int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz); +void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz); + +extern void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib); + +extern uint rtw_remainder_len(struct pkt_file *pfile); +extern void _rtw_open_pktfile(_pkt *pkt, struct pkt_file *pfile); +extern uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen); +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); + +#endif //__XMIT_OSDEP_H_ + diff --git a/rtl8192cu-fixes/installer.sh b/rtl8192cu-fixes/installer.sh new file mode 100644 index 00000000..410baa95 --- /dev/null +++ b/rtl8192cu-fixes/installer.sh @@ -0,0 +1,2 @@ +install -p -m 644 8192cu.ko /lib/modules/$(uname -r)/kernel/drivers/net/wireless/ +depmod -a $(uname -r) diff --git a/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c b/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c new file mode 100755 index 00000000..5013d9dd --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c @@ -0,0 +1,5489 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _IOCTL_CFG80211_C_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_IOCTL_CFG80211 + +#include "ioctl_cfg80211.h" + +#define RTW_MAX_MGMT_TX_CNT (8) + +#define RTW_SCAN_IE_LEN_MAX 2304 +#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms +#define RTW_MAX_NUM_PMKIDS 4 + +#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ + +static const u32 rtw_cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +#ifdef CONFIG_IEEE80211W + WLAN_CIPHER_SUITE_AES_CMAC, +#endif //CONFIG_IEEE80211W +}; + +#define RATETAB_ENT(_rate, _rateid, _flags) \ + { \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ + } + +#define CHAN2G(_channel, _freq, _flags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +#define CHAN5G(_channel, _flags) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = 5000 + (5 * (_channel)), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +static struct ieee80211_rate rtw_rates[] = { + RATETAB_ENT(10, 0x1, 0), + RATETAB_ENT(20, 0x2, 0), + RATETAB_ENT(55, 0x4, 0), + RATETAB_ENT(110, 0x8, 0), + RATETAB_ENT(60, 0x10, 0), + RATETAB_ENT(90, 0x20, 0), + RATETAB_ENT(120, 0x40, 0), + RATETAB_ENT(180, 0x80, 0), + RATETAB_ENT(240, 0x100, 0), + RATETAB_ENT(360, 0x200, 0), + RATETAB_ENT(480, 0x400, 0), + RATETAB_ENT(540, 0x800, 0), +}; + +#define rtw_a_rates (rtw_rates + 4) +#define RTW_A_RATES_NUM 8 +#define rtw_g_rates (rtw_rates + 0) +#define RTW_G_RATES_NUM 12 + +#define RTW_2G_CHANNELS_NUM 14 +#define RTW_5G_CHANNELS_NUM 37 + +static struct ieee80211_channel rtw_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0), + CHAN2G(7, 2442, 0), + CHAN2G(8, 2447, 0), + CHAN2G(9, 2452, 0), + CHAN2G(10, 2457, 0), + CHAN2G(11, 2462, 0), + CHAN2G(12, 2467, 0), + CHAN2G(13, 2472, 0), + CHAN2G(14, 2484, 0), +}; + +static struct ieee80211_channel rtw_5ghz_a_channels[] = { + CHAN5G(34, 0), CHAN5G(36, 0), + CHAN5G(38, 0), CHAN5G(40, 0), + CHAN5G(42, 0), CHAN5G(44, 0), + CHAN5G(46, 0), CHAN5G(48, 0), + CHAN5G(52, 0), CHAN5G(56, 0), + CHAN5G(60, 0), CHAN5G(64, 0), + CHAN5G(100, 0), CHAN5G(104, 0), + CHAN5G(108, 0), CHAN5G(112, 0), + CHAN5G(116, 0), CHAN5G(120, 0), + CHAN5G(124, 0), CHAN5G(128, 0), + CHAN5G(132, 0), CHAN5G(136, 0), + CHAN5G(140, 0), CHAN5G(149, 0), + CHAN5G(153, 0), CHAN5G(157, 0), + CHAN5G(161, 0), CHAN5G(165, 0), + CHAN5G(184, 0), CHAN5G(188, 0), + CHAN5G(192, 0), CHAN5G(196, 0), + CHAN5G(200, 0), CHAN5G(204, 0), + CHAN5G(208, 0), CHAN5G(212, 0), + CHAN5G(216, 0), +}; + + +void rtw_2g_channels_init(struct ieee80211_channel *channels) +{ + _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels, + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM + ); +} + +void rtw_5g_channels_init(struct ieee80211_channel *channels) +{ + _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels, + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM + ); +} + +void rtw_2g_rates_init(struct ieee80211_rate *rates) +{ + _rtw_memcpy(rates, rtw_g_rates, + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM + ); +} + +void rtw_5g_rates_init(struct ieee80211_rate *rates) +{ + _rtw_memcpy(rates, rtw_a_rates, + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM + ); +} + +struct ieee80211_supported_band *rtw_spt_band_alloc( + enum ieee80211_band band + ) +{ + struct ieee80211_supported_band *spt_band = NULL; + int n_channels, n_bitrates; + + if(band == IEEE80211_BAND_2GHZ) + { + n_channels = RTW_2G_CHANNELS_NUM; + n_bitrates = RTW_G_RATES_NUM; + } + else if(band == IEEE80211_BAND_5GHZ) + { + n_channels = RTW_5G_CHANNELS_NUM; + n_bitrates = RTW_A_RATES_NUM; + } + else + { + goto exit; + } + + spt_band = (struct ieee80211_supported_band *)rtw_zmalloc( + sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*n_channels + + sizeof(struct ieee80211_rate)*n_bitrates + ); + if(!spt_band) + goto exit; + + spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band)); + spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels); + spt_band->band = band; + spt_band->n_channels = n_channels; + spt_band->n_bitrates = n_bitrates; + + if(band == IEEE80211_BAND_2GHZ) + { + rtw_2g_channels_init(spt_band->channels); + rtw_2g_rates_init(spt_band->bitrates); + } + else if(band == IEEE80211_BAND_5GHZ) + { + rtw_5g_channels_init(spt_band->channels); + rtw_5g_rates_init(spt_band->bitrates); + } + + //spt_band.ht_cap + +exit: + + return spt_band; +} + +void rtw_spt_band_free(struct ieee80211_supported_band *spt_band) +{ + u32 size; + + if(!spt_band) + return; + + if(spt_band->band == IEEE80211_BAND_2GHZ) + { + size = sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM + + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM; + } + else if(spt_band->band == IEEE80211_BAND_5GHZ) + { + size = sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM + + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM; + } + else + { + + } + rtw_mfree((u8*)spt_band, size); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) +static const struct ieee80211_txrx_stypes +rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, +}; +#endif + +static int rtw_ieee80211_channel_to_frequency(int chan, int band) +{ + /* see 802.11 17.3.8.3.2 and Annex J + * there are overlapping channel numbers in 5GHz and 2GHz bands */ + + if (band == IEEE80211_BAND_5GHZ) { + if (chan >= 182 && chan <= 196) + return 4000 + chan * 5; + else + return 5000 + chan * 5; + } else { /* IEEE80211_BAND_2GHZ */ + if (chan == 14) + return 2484; + else if (chan < 14) + return 2407 + chan * 5; + else + return 0; /* not supported */ + } +} + +#define MAX_BSSINFO_LEN 1000 +static int rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork) +{ + int ret=0; + struct ieee80211_channel *notify_channel; + struct cfg80211_bss *bss; + //struct ieee80211_supported_band *band; + u16 channel; + u32 freq; + u64 notify_timestamp; + u16 notify_capability; + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; + s32 notify_signal; + u8 buf[MAX_BSSINFO_LEN], *pbuf; + size_t len,bssinf_len=0; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + struct wireless_dev *wdev = padapter->rtw_wdev; + struct wiphy *wiphy = wdev->wiphy; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + + //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); + goto exit; + } + + //To reduce PBC Overlap rate + //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + if(wdev_to_priv(wdev)->scan_request != NULL) + { + u8 *psr=NULL, sr = 0; + NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid; + struct cfg80211_scan_request *request = wdev_to_priv(wdev)->scan_request; + struct cfg80211_ssid *ssids = request->ssids; + u32 wpsielen=0; + u8 *wpsie=NULL; + + wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen); + + if(wpsie && wpsielen>0) + psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + + if (sr != 0) + { + if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS + { + DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength); + + if(pssid->SsidLength == ssids[0].ssid_len && + _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len)) + { + DBG_871X("%s, got sr and ssid match!\n", __func__); + } + else + { + if(psr !=NULL) + *psr = 0; //clear sr + +#if 0 + WLAN_BSSID_EX *pselect_network = &pnetwork->network; + struct cfg80211_bss *pselect_bss = NULL; + struct ieee80211_channel *notify_channel = NULL; + u32 freq; + + DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__); + + if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ); + + notify_channel = ieee80211_get_channel(wiphy, freq); + pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/, + pselect_network->MacAddress, pselect_network->Ssid.Ssid, + pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/, + 0/*WLAN_CAPABILITY_ESS*/); + + if(pselect_bss) + { + DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__); + + cfg80211_unlink_bss(wiphy, pselect_bss); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(wiphy, pselect_bss); +#else + cfg80211_put_bss(pselect_bss); +#endif + + } + + goto exit; +#endif + } + } + } + } + //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + + channel = pnetwork->network.Configuration.DSConfig; + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + + notify_channel = ieee80211_get_channel(wiphy, freq); + + //rtw_get_timestampe_from_ie() + notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ + + notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs)); + notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs)); + + + notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_; + notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_; + + //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) + if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE && + is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) { + notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm + } else { + notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm + } + +/* + DBG_8192C("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2], + pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]); + DBG_8192C("Channel: %d(%d)\n", channel, freq); + DBG_8192C("Capability: %X\n", notify_capability); + DBG_8192C("Beacon interval: %d\n", notify_interval); + DBG_8192C("Signal: %d\n", notify_signal); + DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp); +*/ + + pbuf = buf; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf; + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); + //pmlmeext->mgnt_seq++; + + if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + SetFrameSubType(pbuf, WIFI_BEACON); + } else { + _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN); + SetFrameSubType(pbuf, WIFI_PROBERSP); + } + + _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN); + + + 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; + + //#ifdef CONFIG_P2P + //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL)) + //{ + // DBG_8192C("%s, got p2p_ie\n", __func__); + //} + //#endif + + +#if 1 + bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf, + len, notify_signal, GFP_ATOMIC); +#else + + bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress, + notify_timestamp, notify_capability, notify_interval, notify_ie, + notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/); +#endif + + if (unlikely(!bss)) { + DBG_8192C("rtw_cfg80211_inform_bss error\n"); + return -EINVAL; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) +#ifndef COMPAT_KERNEL_RELEASE + //patch for cfg80211, update beacon ies to information_elements + if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON + + if(bss->len_information_elements != bss->len_beacon_ies) + { + bss->information_elements = bss->beacon_ies; + bss->len_information_elements = bss->len_beacon_ies; + } + } +#endif //COMPAT_KERNEL_RELEASE +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) + +/* + { + if( bss->information_elements == bss->proberesp_ies) + { + if( bss->len_information_elements != bss->len_proberesp_ies) + { + DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n"); + } + + } + else if(bss->len_information_elements < bss->len_beacon_ies) + { + bss->information_elements = bss->beacon_ies; + bss->len_information_elements = bss->len_beacon_ies; + } + } +*/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(wiphy, bss); +#else + cfg80211_put_bss(bss); +#endif + +exit: + return ret; + +} + +/* + Check the given bss is valid by kernel API cfg80211_get_bss() + @padapter : the given adapter + + return _TRUE if bss is valid, _FALSE for not found. +*/ +int rtw_cfg80211_check_bss(_adapter *padapter) +{ + WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network); + struct cfg80211_bss *bss = NULL; + struct ieee80211_channel *notify_channel = NULL; + u32 freq; + + if (!(pnetwork) || !(padapter->rtw_wdev)) + return _FALSE; + + if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ); + + notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq); + bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel, + pnetwork->MacAddress, pnetwork->Ssid.Ssid, + pnetwork->Ssid.SsidLength, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + + return (bss!=NULL); +} + +void rtw_cfg80211_indicate_connect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wireless_dev *pwdev = padapter->rtw_wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + struct cfg80211_bss *bss = NULL; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + if (pwdev->iftype != NL80211_IFTYPE_STATION + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT + #endif + ) { + return; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return; + +#ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + } +#endif //CONFIG_P2P + + #ifdef CONFIG_LAYER2_ROAMING + if (rtw_to_roaming(padapter) > 0) { + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) + struct wiphy *wiphy = pwdev->wiphy; + struct ieee80211_channel *notify_channel; + u32 freq; + u16 channel = cur_network->network.Configuration.DSConfig; + + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + + notify_channel = ieee80211_get_channel(wiphy, freq); + #endif + + DBG_871X("%s call cfg80211_roamed\n", __FUNCTION__); + cfg80211_roamed(padapter->pnetdev + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) + , notify_channel + #endif + , 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 + , GFP_ATOMIC); + } + else + #endif + { + DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state); + 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); + DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); + } +} + +void rtw_cfg80211_indicate_disconnect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wireless_dev *pwdev = padapter->rtw_wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + if (pwdev->iftype != NL80211_IFTYPE_STATION + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT + #endif + ) { + return; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return; + +#ifdef CONFIG_P2P + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + } +#endif //CONFIG_P2P + + if (!padapter->mlmepriv.not_indic_disco) { + DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state); + + if(pwdev->sme_state==CFG80211_SME_CONNECTING) + cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/); + else if(pwdev->sme_state==CFG80211_SME_CONNECTED) + cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC); + //else + //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state); + + DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); + } +} + + +#ifdef CONFIG_AP_MODE +static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + + + psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy; + + _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN); + + _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); + + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid) +{ + u8 keylen; + struct cmd_obj* pcmd; + struct setkey_parm *psetkeyparm; + struct cmd_priv *pcmdpriv=&(padapter->cmdpriv); + int res=_SUCCESS; + + DBG_8192C("%s\n", __FUNCTION__); + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; + goto exit; + } + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm)); + + psetkeyparm->keyid=(u8)keyid; + if (is_wep_enc(alg)) + padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); + + psetkeyparm->algorithm = alg; + + psetkeyparm->set_tx = 1; + + switch(alg) + { + case _WEP40_: + keylen = 5; + break; + case _WEP104_: + keylen = 13; + break; + case _TKIP_: + case _TKIP_WTMIC_: + case _AES_: + keylen = 16; + default: + keylen = 16; + } + + _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen); + + pcmd->cmdcode = _SetKey_CMD_; + pcmd->parmbuf = (u8 *)psetkeyparm; + pcmd->cmdsz = (sizeof(struct setkey_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + + return res; + + +} + +static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid) +{ + u8 alg; + + switch(keylen) + { + case 5: + alg =_WEP40_; + break; + case 13: + alg =_WEP104_; + break; + default: + alg =_NO_PRIVACY_; + } + + return set_group_key(padapter, key, alg, keyid); + +} + +static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + struct sta_info *psta = NULL, *pbcmc_sta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_8192C("%s\n", __FUNCTION__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + //sizeof(struct ieee_param) = 64 bytes; + //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS) + { + ret = -EINVAL; + goto exit; + } + } + else + { + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(!psta) + { + //ret = -EINVAL; + DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n"); + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL)) + { + //todo:clear default encryption keys + + DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx); + + goto exit; + } + + + if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL)) + { + DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len); + + if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0)) + { + ret = -EINVAL; + goto exit; + } + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + } + + if (psecuritypriv->bWepDefaultKeyIdxSet == 0) + { + //wep default key has not been set, so use this key index as default key. + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + psecuritypriv->dot118021XGrpPrivacy=_WEP40_; + + if(wep_key_len == 13) + { + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + psecuritypriv->dot118021XGrpPrivacy=_WEP104_; + } + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len; + + set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx); + + goto exit; + + } + + + if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key + { + if(param->u.crypt.set_tx == 0) //group key + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__); + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + DBG_8192C("%s, set group_key, none\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + goto exit; + + } + + if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x + { + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + if(param->u.crypt.set_tx ==1) //pairwise key + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psta->dot118021XPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _TKIP_; + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + + DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _AES_; + } + else + { + DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__); + + psta->dot118021XPrivacy = _NO_PRIVACY_; + } + + set_pairwise_key(padapter, psta); + + psta->ieee8021x_blocked = _FALSE; + + psta->bpairwise_key_installed = _TRUE; + + } + else//group key??? + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + } + + } + +exit: + + return ret; + +} +#endif + +static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + +_func_enter_; + + DBG_8192C("%s\n", __func__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif //CONFIG_IEEE80211W + ) + { + ret = -EINVAL; + goto exit; + } + } else { + ret = -EINVAL; + goto exit; + } + + if (strcmp(param->u.crypt.alg, "WEP") == 0) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n")); + DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) + { + ret = -EINVAL; + goto exit; + } + + if (psecuritypriv->bWepDefaultKeyIdxSet == 0) + { + //wep default key has not been set, so use this key index as default key. + + wep_key_len = wep_key_len <= 5 ? 5 : 13; + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + + if(wep_key_len==13) + { + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len; + + rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); + + goto exit; + } + + if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x + { + struct sta_info * psta,*pbcmc_sta; + struct sta_priv * pstapriv = &padapter->stapriv; + + //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__); + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode + { + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + DBG_8192C("%s, : Obtain Sta_info fail \n", __func__); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + psta->ieee8021x_blocked = _FALSE; + + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + + if(param->u.crypt.set_tx ==1)//pairwise key + { + + DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__); + + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key + { + //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + padapter->securitypriv.busetkipkey=_FALSE; + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + } + + //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:unicastkey\n"); + + rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); + } + else//group key + { + if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); + _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); + padapter->securitypriv.binstallGrpkey = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:groupkey\n"); + + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + + rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1); + } +#ifdef CONFIG_IEEE80211W + else if(strcmp(param->u.crypt.alg, "BIP") == 0) + { + int no; + //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); + //save the IGTK key, length 16 bytes + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + /*DBG_871X("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + DBG_871X("\n");*/ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + } +#endif //CONFIG_IEEE80211W + +#ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); + } + } +#endif //CONFIG_P2P + + } + } + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta==NULL) + { + //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + pbcmc_sta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + } + } + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode + { + } + } + +exit: + + DBG_8192C("%s, ret=%d\n", __func__, ret); + + _func_exit_; + + return ret; +} + +static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr, +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr, +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + struct key_params *params) +{ + char *alg_name; + u32 param_len; + struct ieee_param *param = NULL; + int ret=0; + struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr); + DBG_871X("cipher=0x%x\n", params->cipher); + DBG_871X("key_len=0x%x\n", params->key_len); + DBG_871X("seq_len=0x%x\n", params->seq_len); + DBG_871X("key_index=%d\n", key_index); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + DBG_871X("pairwise=%d\n", pairwise); +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + + param_len = sizeof(struct ieee_param) + params->key_len; + param = (struct ieee_param *)rtw_malloc(param_len); + if (param == NULL) + return -1; + + _rtw_memset(param, 0, param_len); + + param->cmd = IEEE_CMD_SET_ENCRYPTION; + _rtw_memset(param->sta_addr, 0xff, ETH_ALEN); + + switch (params->cipher) { + case IW_AUTH_CIPHER_NONE: + //todo: remove key + //remove = 1; + alg_name = "none"; + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + alg_name = "WEP"; + break; + case WLAN_CIPHER_SUITE_TKIP: + alg_name = "TKIP"; + break; + case WLAN_CIPHER_SUITE_CCMP: + alg_name = "CCMP"; + break; +#ifdef CONFIG_IEEE80211W + case WLAN_CIPHER_SUITE_AES_CMAC: + alg_name = "BIP"; + break; +#endif //CONFIG_IEEE80211W + default: + return -ENOTSUPP; + } + + strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); + + + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) + { + param->u.crypt.set_tx = 0; //for wpa/wpa2 group key + } else { + param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key + } + + + //param->u.crypt.idx = key_index - 1; + param->u.crypt.idx = key_index; + + if (params->seq_len && params->seq) + { + _rtw_memcpy(param->u.crypt.seq, 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); + } + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + ret = rtw_cfg80211_set_encryption(ndev, param, param_len); + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_AP_MODE + if(mac_addr) + _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN); + + ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len); +#endif + } + else + { + DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); + + } + + if(param) + { + rtw_mfree((u8*)param, param_len); + } + + return ret; + +} + +static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr, +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr, +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + void *cookie, + void (*callback)(void *cookie, + struct key_params*)) +{ +#if 0 + struct iwm_priv *iwm = ndev_to_iwm(ndev); + struct iwm_key *key = &iwm->keys[key_index]; + struct key_params params; + + IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index); + + memset(¶ms, 0, sizeof(params)); + + params.cipher = key->cipher; + params.key_len = key->key_len; + params.seq_len = key->seq_len; + params.seq = key->seq; + params.key = key->key; + + callback(cookie, ¶ms); + + return key->key_len ? 0 : -ENOENT; +#endif + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr) +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr) +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index); + + if (key_index == psecuritypriv->dot11PrivacyKeyIndex) + { + //clear the flag of wep default key set. + psecuritypriv->bWepDefaultKeyIdxSet = 0; + } + + return 0; +} + +static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + , bool unicast, bool multicast + #endif + ) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT" key_index=%d" + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + ", unicast=%d, multicast=%d" + #endif + ".\n", FUNC_NDEV_ARG(ndev), key_index + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + , unicast, multicast + #endif + ); + + if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key + { + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + + psecuritypriv->dot11PrivacyKeyIndex = key_index; + + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if (psecuritypriv->dot11DefKeylen[key_index] == 13) + { + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set + } + + return 0; + +} + +static int cfg80211_rtw_get_station(struct wiphy *wiphy, + struct net_device *ndev, + u8 *mac, struct station_info *sinfo) +{ + int ret = 0; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + sinfo->filled = 0; + + if (!mac) { + DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac); + ret = -ENOENT; + goto exit; + } + + psta = rtw_get_stainfo(pstapriv, mac); + if (psta == NULL) { + DBG_8192C("%s, sta_info is null\n", __func__); + ret = -ENOENT; + goto exit; + } + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac)); +#endif + + //for infra./P2PClient mode + if( check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED) + ) + { + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + + if (_rtw_memcmp(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; + } + + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); + + sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); + + sinfo->filled |= STATION_INFO_RX_PACKETS; + sinfo->rx_packets = sta_rx_data_pkts(psta); + + sinfo->filled |= STATION_INFO_TX_PACKETS; + sinfo->tx_packets = psta->sta_stats.tx_pkts; + + } + + //for Ad-Hoc/AP mode + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) + ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) + ||check_fwstate(pmlmepriv, WIFI_AP_STATE)) + && check_fwstate(pmlmepriv, _FW_LINKED) + ) + { + //TODO: should acquire station info... + } + +exit: + return ret; +} + +extern int netdev_open(struct net_device *pnetdev); +#ifdef CONFIG_CONCURRENT_MODE +extern int netdev_if2_open(struct net_device *pnetdev); +#endif + +/* +enum nl80211_iftype { + NL80211_IFTYPE_UNSPECIFIED, + NL80211_IFTYPE_ADHOC, //1 + NL80211_IFTYPE_STATION, //2 + NL80211_IFTYPE_AP, //3 + NL80211_IFTYPE_AP_VLAN, + NL80211_IFTYPE_WDS, + NL80211_IFTYPE_MONITOR, //6 + NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, //8 + NL80211_IFTYPE_P2P_GO, //9 + //keep last + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; +*/ +static int cfg80211_rtw_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + enum nl80211_iftype old_type; + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _queue *queue = &pmlmepriv->scanned_queue; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + int ret = 0; + u8 change = _FALSE; + + if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) { + ret= -EPERM; + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type == SECONDARY_ADAPTER) + { + DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev)); + if(netdev_if2_open(ndev) != 0) { + ret= -EPERM; + goto exit; + } + } + else if(padapter->adapter_type == PRIMARY_ADAPTER) +#endif //CONFIG_CONCURRENT_MODE + { + DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev)); + if(netdev_open(ndev) != 0) { + ret= -EPERM; + goto exit; + } + } + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + old_type = rtw_wdev->iftype; + DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n", + FUNC_NDEV_ARG(ndev), old_type, type); + + if(old_type != type) + { + change = _TRUE; + pmlmeext->action_public_rxseq = 0xffff; + pmlmeext->action_public_dialog_token = 0xff; + } + + switch (type) { + case NL80211_IFTYPE_ADHOC: + networkType = Ndis802_11IBSS; + break; +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_CLIENT: +#endif + case NL80211_IFTYPE_STATION: + networkType = Ndis802_11Infrastructure; + #ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + + //it means remove GO and change mode from AP(GO) to station(P2P DEVICE) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + } + #endif //CONFIG_P2P + break; +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_AP: + networkType = Ndis802_11APMode; + #ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + #endif //CONFIG_P2P + break; + default: + return -EOPNOTSUPP; + } + + rtw_wdev->iftype = type; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _enter_critical_bh(&queue->lock, &irqL); + + if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE) + { + rtw_wdev->iftype = old_type; + ret = -EPERM; + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + goto exit; + } + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + rtw_setopmode_cmd(padapter, networkType); + +exit: + + return ret; +} + +void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool aborted) +{ + _irqL irqL; + + _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + if(pwdev_priv->scan_request != NULL) + { + //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s with scan req\n", __FUNCTION__); + #endif + + //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); + //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req) + if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy) + { + DBG_8192C("error wiphy compare\n"); + } + else + { + cfg80211_scan_done(pwdev_priv->scan_request, aborted); + } + + pwdev_priv->scan_request = NULL; + + } else { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s without scan req\n", __FUNCTION__); + #endif + } + _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); +} + +void rtw_cfg80211_surveydone_event_callback(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u32 cnt=0; + u32 wait_for_surveydone; + sint wait_status; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s\n", __func__); +#endif + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //report network only if the current channel set contains the channel to which this network belongs + if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 + && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE + && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) + ) + { + //ev=translate_scan(padapter, a, pnetwork, ev, stop); + rtw_cfg80211_inform_bss(padapter, pnetwork); + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + //call this after other things have been done + rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), _FALSE); +} + +static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen); + #endif + + if(pmlmepriv->wps_probe_req_ie) + { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_probe_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_req_ie_len = wps_ielen; + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + struct wifidirect_info *wdinfo = &padapter->wdinfo; + u32 attr_contentlen = 0; + u8 listen_ch_attr[5]; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen); + #endif + + if(pmlmepriv->p2p_probe_req_ie) + { + u32 free_len = pmlmepriv->p2p_probe_req_ie_len; + pmlmepriv->p2p_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len); + pmlmepriv->p2p_probe_req_ie = NULL; + } + + pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_probe_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_req_ie_len = p2p_ielen; + + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen) + && attr_contentlen == 5) + { + if (wdinfo->listen_channel != listen_ch_attr[4]) { + DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n", + FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2], + listen_ch_attr[3], listen_ch_attr[4]); + wdinfo->listen_channel = listen_ch_attr[4]; + } + } + } + #endif //CONFIG_P2P + + //buf += p2p_ielen; + //len -= p2p_ielen; + + #ifdef CONFIG_WFD + if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen); + #endif + + if(pmlmepriv->wfd_probe_req_ie) + { + u32 free_len = pmlmepriv->wfd_probe_req_ie_len; + pmlmepriv->wfd_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len); + pmlmepriv->wfd_probe_req_ie = NULL; + } + + pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen); + if ( pmlmepriv->wfd_probe_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); + } + #endif //CONFIG_WFD + + } + + return ret; + +} + +static int cfg80211_rtw_scan(struct wiphy *wiphy + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) + , struct net_device *ndev + #endif + , struct cfg80211_scan_request *request) +{ + int i; + u8 _status = _FALSE; + int ret = 0; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; + _irqL irqL; + u8 *wps_ie=NULL; + uint wps_ielen=0; + u8 *p2p_ie=NULL; + uint p2p_ielen=0; + u8 survey_times=3; + u8 survey_times_for_one_ch=6; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + struct cfg80211_ssid *ssids = request->ssids; + int social_channel = 0, j = 0; + bool need_indicate_scan_done = _FALSE; +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = NULL; + struct mlme_priv *pbuddy_mlmepriv = NULL; +#endif //CONFIG_CONCURRENT_MODE + +//#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); +//#endif + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) { + pbuddy_adapter = padapter->pbuddy_adapter; + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + } +#endif //CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_MP_INCLUDED + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + ret = -EPERM; + goto exit; + } +#endif + + _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + pwdev_priv->scan_request = request; + _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__); +#endif + + if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + DBG_8192C("AP mode process WPS \n"); + } + + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + } + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + + #ifdef CONFIG_P2P + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(ssids->ssid != NULL + && _rtw_memcmp(ssids->ssid, "DIRECT-", 7) + && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL) + ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + u32 initialgain = 0x30; + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE; + padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain)); + padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain)); + } + else + { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); + #endif + } + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + if(request->n_channels == 3 && + request->channels[0]->hw_value == 1 && + request->channels[1]->hw_value == 6 && + request->channels[2]->hw_value == 11 + ) + { + social_channel = 1; + } + } + } + #endif //CONFIG_P2P + + if(request->ie && request->ie_len>0) + { + rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len ); + } + + if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) + { + DBG_8192C("%s, bBusyTraffic == _TRUE\n", __func__); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + if (rtw_is_scan_deny(padapter)){ + DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter)); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) + { + DBG_8192C("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } +#endif //CONFIG_CONCURRENT_MODE + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, + _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) + { + if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) + { + DBG_8192C("scanning_via_buddy_intf\n"); + pmlmepriv->scanning_via_buddy_intf = _TRUE; + } + + DBG_8192C("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state); + + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } +#endif + + +#ifdef CONFIG_P2P + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_free_network_queue(padapter, _TRUE); + + if(social_channel == 0) + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + else + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST); + } + } +#endif //CONFIG_P2P + + + _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT); + //parsing request ssids, n_ssids + for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len); + #endif + _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len); + ssid[i].SsidLength = ssids[i].ssid_len; + } + + + /* parsing channels, n_channels */ + _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT); + for (i=0;in_channels && ichannels[i])); + #endif + ch[i].hw_value = request->channels[i]->hw_value; + ch[i].flags = request->channels[i]->flags; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if (request->n_channels == 1) { + for(i=1;in_channels == 2) { + _rtw_memcpy(&ch[3], &ch[1], sizeof(struct rtw_ieee80211_channel)); + for(i=1;ilock, &irqL); + + + if(_status == _FALSE) + { + ret = -1; + } + +check_need_indicate_scan_done: + if(need_indicate_scan_done) + rtw_cfg80211_surveydone_event_callback(padapter); + +exit: + + return ret; + +} + +static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + + if (changed & WIPHY_PARAM_RTS_THRESHOLD && + (iwm->conf.rts_threshold != wiphy->rts_threshold)) { + int ret; + + iwm->conf.rts_threshold = wiphy->rts_threshold; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, + CFG_RTS_THRESHOLD, + iwm->conf.rts_threshold); + if (ret < 0) + return ret; + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD && + (iwm->conf.frag_threshold != wiphy->frag_threshold)) { + int ret; + + iwm->conf.frag_threshold = wiphy->frag_threshold; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX, + CFG_FRAG_THRESHOLD, + iwm->conf.frag_threshold); + if (ret < 0) + return ret; + } +#endif + DBG_8192C("%s\n", __func__); + return 0; +} + +static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ibss_params *params) +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + struct ieee80211_channel *chan = params->channel; + + if (!test_bit(IWM_STATUS_READY, &iwm->status)) + return -EIO; + + /* UMAC doesn't support creating or joining an IBSS network + * with specified bssid. */ + if (params->bssid) + return -EOPNOTSUPP; + + iwm->channel = ieee80211_frequency_to_channel(chan->center_freq); + iwm->umac_profile->ibss.band = chan->band; + iwm->umac_profile->ibss.channel = iwm->channel; + iwm->umac_profile->ssid.ssid_len = params->ssid_len; + memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len); + + return iwm_send_mlme_profile(iwm); +#endif + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + + if (iwm->umac_profile_active) + return iwm_invalidate_mlme_profile(iwm); +#endif + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version) +{ + DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version); + + if (!wpa_version) { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + return 0; + } + + + if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) + { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK; + } + +/* + if (wpa_version & NL80211_WPA_VERSION_2) + { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; + } +*/ + + return 0; + +} + +static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, + enum nl80211_auth_type sme_auth_type) +{ + DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type); + + + switch (sme_auth_type) { + case NL80211_AUTHTYPE_AUTOMATIC: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + + break; + case NL80211_AUTHTYPE_OPEN_SYSTEM: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; + + if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA) + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + + break; + case NL80211_AUTHTYPE_SHARED_KEY: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + + + break; + default: + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; + //return -ENOTSUPP; + } + + return 0; + +} + +static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast) +{ + u32 ndisencryptstatus = Ndis802_11EncryptionDisabled; + + u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm : + &psecuritypriv->dot118021XGrpPrivacy; + + DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher); + + + if (!cipher) { + *profile_cipher = _NO_PRIVACY_; + psecuritypriv->ndisencryptstatus = ndisencryptstatus; + return 0; + } + + switch (cipher) { + case IW_AUTH_CIPHER_NONE: + *profile_cipher = _NO_PRIVACY_; + ndisencryptstatus = Ndis802_11EncryptionDisabled; + break; + case WLAN_CIPHER_SUITE_WEP40: + *profile_cipher = _WEP40_; + ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WLAN_CIPHER_SUITE_WEP104: + *profile_cipher = _WEP104_; + ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WLAN_CIPHER_SUITE_TKIP: + *profile_cipher = _TKIP_; + ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WLAN_CIPHER_SUITE_CCMP: + *profile_cipher = _AES_; + ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + default: + DBG_8192C("Unsupported cipher: 0x%x\n", cipher); + return -ENOTSUPP; + } + + if(ucast) + { + psecuritypriv->ndisencryptstatus = ndisencryptstatus; + + //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_) + // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; + } + + return 0; +} + +static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt) +{ + DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt); + + if (key_mgt == WLAN_AKM_SUITE_8021X) + //*auth_type = UMAC_AUTH_TYPE_8021X; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + else if (key_mgt == WLAN_AKM_SUITE_PSK) { + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + } else { + DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt); + //return -EINVAL; + } + + return 0; +} + +static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) +{ + u8 *buf=NULL, *pos=NULL; + u32 left; + int group_cipher = 0, pairwise_cipher = 0; + int ret = 0; + int wpa_ielen=0; + int wpa2_ielen=0; + u8 *pwpa, *pwpa2; + u8 null_addr[]= {0,0,0,0,0,0}; + + if (pie == NULL || !ielen) { + /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */ + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + goto exit; + } + + if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) { + ret = -EINVAL; + goto exit; + } + + buf = rtw_zmalloc(ielen); + if (buf == NULL){ + ret = -ENOMEM; + goto exit; + } + + _rtw_memcpy(buf, pie , ielen); + + //dump + { + int i; + DBG_8192C("set wpa_ie(length:%zu):\n", ielen); + for(i=0;i0) + { + if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2); + + DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen); + } + } + + pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen); + if(pwpa2 && wpa2_ielen>0) + { + if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2); + + DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen); + } + } + + if (group_cipher == 0) + { + group_cipher = WPA_CIPHER_NONE; + } + if (pairwise_cipher == 0) + { + pairwise_cipher = WPA_CIPHER_NONE; + } + + switch(group_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot118021XGrpPrivacy=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot11PrivacyAlgrthm=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + {/* handle wps_ie */ + uint wps_ielen; + u8 *wps_ie; + + wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen); + if (wps_ie && wps_ielen > 0) { + DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen); + padapter->securitypriv.wps_ie_len = wps_ielensecuritypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len); + set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); + } else { + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + } + } + + #ifdef CONFIG_P2P + {//check p2p_ie for assoc req; + uint p2p_ielen=0; + u8 *p2p_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen); + #endif + + if(pmlmepriv->p2p_assoc_req_ie) + { + u32 free_len = pmlmepriv->p2p_assoc_req_ie_len; + pmlmepriv->p2p_assoc_req_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len); + pmlmepriv->p2p_assoc_req_ie = NULL; + } + + pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_assoc_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + goto exit; + } + _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen; + } + } + #endif //CONFIG_P2P + + #ifdef CONFIG_WFD + {//check wfd_ie for assoc req; + uint wfd_ielen=0; + u8 *wfd_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen)) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen); + #endif + + if(pmlmepriv->wfd_assoc_req_ie) + { + u32 free_len = pmlmepriv->wfd_assoc_req_ie_len; + pmlmepriv->wfd_assoc_req_ie_len = 0; + rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len); + pmlmepriv->wfd_assoc_req_ie = NULL; + } + + pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen); + if ( pmlmepriv->wfd_assoc_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + goto exit; + } + rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); + } + } + #endif //CONFIG_WFD + + //TKIP and AES disallow multicast packets until installing group key + if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) + //WPS open need to enable multicast + //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) + rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n", + pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + +exit: + if (buf) + rtw_mfree(buf, ielen); + if (ret) + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + return ret; +} + +static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + int ret=0; + _irqL irqL; + _list *phead; + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + NDIS_802_11_SSID ndis_ssid; + u8 *dst_ssid, *src_ssid; + u8 *dst_bssid, *src_bssid; + //u8 matched_by_bssid=_FALSE; + //u8 matched_by_ssid=_FALSE; + u8 matched=_FALSE; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + _queue *queue = &pmlmepriv->scanned_queue; + + DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n", + sme->privacy, sme->key, sme->key_len, sme->key_idx); + + + if(wdev_to_priv(padapter->rtw_wdev)->block == _TRUE) + { + ret = -EBUSY; + DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__); + goto exit; + } + +#ifdef CONFIG_PLATFORM_MSTAR + printk("MStar Android!\n"); + if((wdev_to_priv(padapter->rtw_wdev))->bandroid_scan == _FALSE) + { +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) +#endif //CONFIG_P2P + { + ret = -EBUSY; + printk("Android hasn't attached yet!\n"); + goto exit; + } + } +#endif + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + ret = -EPERM; + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) { + DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__); + ret = -EINVAL; + goto exit; + } + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) { + rtw_scan_abort(padapter->pbuddy_adapter); + } +#endif + + if (!sme->ssid || !sme->ssid_len) + { + ret = -EINVAL; + goto exit; + } + + if (sme->ssid_len > IW_ESSID_MAX_SIZE){ + + ret= -E2BIG; + goto exit; + } + + _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); + + DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len); + + + if (sme->bssid) + DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid)); + + + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + ret = -EBUSY; + DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state); + goto exit; + } + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + rtw_scan_abort(padapter); + } + + psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + + + ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions); + if (ret < 0) + goto exit; + + ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type); + if (ret < 0) + goto exit; + + DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len); + + ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len); + if (ret < 0) + goto exit; + + if (sme->crypto.n_ciphers_pairwise) { + ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE); + if (ret < 0) + goto exit; + } + + //For WEP Shared auth + if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared + || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key + ) + { + u32 wep_key_idx, wep_key_len,wep_total_len; + NDIS_802_11_WEP *pwep = NULL; + DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__); + + wep_key_idx = sme->key_idx; + wep_key_len = sme->key_len; + + if (sme->key_idx > WEP_KEYS) { + ret = -EINVAL; + goto exit; + } + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len); + if(pwep == NULL){ + DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n"); + ret = -ENOMEM; + goto exit; + } + + _rtw_memset(pwep, 0, wep_total_len); + + pwep->KeyLength = wep_key_len; + pwep->Length = wep_total_len; + + if(wep_key_len==13) + { + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + } + } + else { + ret = -EINVAL; + goto exit; + } + + pwep->KeyIndex = wep_key_idx; + pwep->KeyIndex |= 0x80000000; + + _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength); + + if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) + { + ret = -EOPNOTSUPP ; + } + + if (pwep) { + rtw_mfree((u8 *)pwep,wep_total_len); + } + + if(ret < 0) + goto exit; + } + + ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE); + if (ret < 0) + return ret; + + if (sme->crypto.n_akm_suites) { + ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]); + if (ret < 0) + goto exit; + } + + authmode = psecuritypriv->ndisauthtype; + rtw_set_802_11_authentication_mode(padapter, authmode); + + //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + + if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) { + ret = -1; + goto exit; + } + + DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy); + +exit: + + DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret); + + return ret; +} + +static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, + u16 reason_code) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + rtw_set_roaming(padapter, 0); + + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + rtw_scan_abort(padapter); + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + + DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__); + + padapter->mlmepriv.not_indic_disco = _TRUE; + rtw_indicate_disconnect(padapter); + padapter->mlmepriv.not_indic_disco = _FALSE; + + rtw_free_assoc_resources(padapter, 1); + } + + return 0; +} + +static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + struct wireless_dev *wdev, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE) + enum nl80211_tx_power_setting type, int mbm) +#else + enum tx_power_setting type, int dbm) +#endif +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + int ret; + + switch (type) { + case NL80211_TX_POWER_AUTOMATIC: + return 0; + case NL80211_TX_POWER_FIXED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + + if (!test_bit(IWM_STATUS_READY, &iwm->status)) + return 0; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, + CFG_TX_PWR_LIMIT_USR, + MBM_TO_DBM(mbm) * 2); + if (ret < 0) + return ret; + + return iwm_tx_power_trigger(iwm); + default: + IWM_ERR(iwm, "Unsupported power type: %d\n", type); + return -EOPNOTSUPP; + } +#endif + DBG_8192C("%s\n", __func__); + return 0; +} + +static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + struct wireless_dev *wdev, +#endif + int *dbm) +{ + //_adapter *padapter = wiphy_to_adapter(wiphy); + + DBG_8192C("%s\n", __func__); + + *dbm = (12); + + return 0; +} + +inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter) +{ + struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev); + return rtw_wdev_priv->power_mgmt; +} + +static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + bool enabled, int timeout) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev); + + DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev), + enabled, timeout); + + rtw_wdev_priv->power_mgmt = enabled; + + #ifdef CONFIG_LPS + if (!enabled) + LPS_Leave(padapter); + #endif + + return 0; +} + +static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, + struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + u8 index,blInserted = _FALSE; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 }; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev)); + + if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE ) + { + return -EINVAL; + } + + blInserted = _FALSE; + + //overwrite PMKID + for(index=0 ; indexPMKIDList[index].Bssid, 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(netdev)); + + _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); + psecuritypriv->PMKIDList[index].bUsed = _TRUE; + psecuritypriv->PMKIDIndex = index+1; + blInserted = _TRUE; + break; + } + } + + if(!blInserted) + { + // Find a new entry + DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n", + FUNC_NDEV_ARG(netdev), 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); + + psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE; + psecuritypriv->PMKIDIndex++ ; + if(psecuritypriv->PMKIDIndex==16) + { + psecuritypriv->PMKIDIndex =0; + } + } + + return 0; +} + +static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy, + struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + u8 index, bMatched = _FALSE; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev)); + + for(index=0 ; indexPMKIDList[index].Bssid, 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 ); + psecuritypriv->PMKIDList[index].bUsed = _FALSE; + bMatched = _TRUE; + break; + } + } + + if(_FALSE == bMatched) + { + DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n" + , FUNC_NDEV_ARG(netdev)); + return -EINVAL; + } + + return 0; +} + +static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, + struct net_device *netdev) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev)); + + _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + psecuritypriv->PMKIDIndex = 0; + + return 0; +} + +#ifdef CONFIG_AP_MODE +void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + s32 freq; + int channel; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct net_device *ndev = padapter->pnetdev; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + { + struct station_info sinfo; + u8 ie_offset; + if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ) + ie_offset = _ASOCREQ_IE_OFFSET_; + else // WIFI_REASSOCREQ + ie_offset = _REASOCREQ_IE_OFFSET_; + + sinfo.filled = 0; + sinfo.filled = STATION_INFO_ASSOC_REQ_IES; + sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; + sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; + cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); + } +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #else //COMPAT_KERNEL_RELEASE + { + //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() + #ifndef CONFIG_PLATFORM_MSTAR + pwdev->iftype = NL80211_IFTYPE_STATION; + #endif //CONFIG_PLATFORM_MSTAR + DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); + rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); + DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); + pwdev->iftype = NL80211_IFTYPE_AP; + //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); + } + #endif //COMPAT_KERNEL_RELEASE +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ + +} + +void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason) +{ + s32 freq; + int channel; + u8 *pmgmt_frame; + uint frame_len; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + u8 mgmt_buf[128] = {0}; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct net_device *ndev = padapter->pnetdev; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + cfg80211_del_sta(ndev, da, GFP_ATOMIC); +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + + pmgmt_frame = mgmt_buf; + pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pmgmt_frame, WIFI_DEAUTH); + + pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); + frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #else //COMPAT_KERNEL_RELEASE + cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); + //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); + #endif //COMPAT_KERNEL_RELEASE +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ +} + +static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +static int rtw_cfg80211_monitor_if_close(struct net_device *ndev) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev) +{ + int ret = 0; + int rtap_len; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + u16 frame_ctl; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + struct ieee80211_hdr *dot11_hdr; + struct ieee80211_radiotap_header *rtap_hdr; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + if (skb) + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize); + + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) + goto fail; + + rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; + if (unlikely(rtap_hdr->it_version)) + goto fail; + + rtap_len = ieee80211_get_radiotap_len(skb->data); + if (unlikely(skb->len < rtap_len)) + goto fail; + + if(rtap_len != 14) + { + DBG_8192C("radiotap len (should be 14): %d\n", rtap_len); + goto fail; + } + + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + + dot11_hdr = (struct ieee80211_hdr *)skb->data; + frame_ctl = le16_to_cpu(dot11_hdr->frame_control); + /* Check if the QoS bit is set */ + if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) { + /* Check if this ia a Wireless Distribution System (WDS) frame + * which has 4 MAC addresses + */ + if (dot11_hdr->frame_control & 0x0080) + qos_len = 2; + if ((dot11_hdr->frame_control & 0x0300) == 0x0300) + dot11_hdr_len += 6; + + memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); + memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); + + /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for + * for two MAC addresses + */ + skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2); + pdata = (unsigned char*)skb->data; + memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr)); + memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr)); + + DBG_8192C("should be eapol packet\n"); + + /* Use the real net device to transmit the packet */ + ret = _rtw_xmit_entry(skb, padapter->pnetdev); + + return ret; + + } + else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)) + == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION) + ) + { + //only for action frames + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + //u8 category, action, OUI_Subtype, dialogToken=0; + //unsigned char *frame_body; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 *buf = skb->data; + u32 len = skb->len; + u8 category, action; + int type = -1; + + if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { + DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev), + le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl)); + goto fail; + } + + DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n", + MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev)); + #ifdef CONFIG_P2P + if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) + goto dump; + #endif + if (category == RTW_WLAN_CATEGORY_PUBLIC) + DBG_871X("RTW_Tx:%s\n", action_public_str(action)); + else + DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action); + +dump: + //starting alloc mgmt frame to dump it + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto fail; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void*)buf, len); + #ifdef CONFIG_WFD + if (type >= 0) + { + struct wifi_display_info *pwfd_info; + + pwfd_info = padapter->wdinfo.wfd_info; + + if ( _TRUE == pwfd_info->wfd_enable ) + { + rtw_append_wfd_ie( padapter, pframe, &len ); + } + } + #endif // CONFIG_WFD + pattrib->pktlen = len; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //update seq number + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + } + else + { + DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)); + } + + +fail: + + dev_kfree_skb(skb); + + return 0; + +} + +static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev) +{ + DBG_8192C("%s\n", __func__); +} + +static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_cfg80211_monitor_if_ops = { + .ndo_open = rtw_cfg80211_monitor_if_open, + .ndo_stop = rtw_cfg80211_monitor_if_close, + .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) + .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list, + #endif + .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address, +}; +#endif + +static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev) +{ + int ret = 0; + struct net_device* mon_ndev = NULL; + struct wireless_dev* mon_wdev = NULL; + struct rtw_netdev_priv_indicator *pnpi; + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + + if (!name ) { + DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter)); + ret = -EINVAL; + goto out; + } + + if (pwdev_priv->pmon_ndev) { + DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n", + FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev)); + ret = -EBUSY; + goto out; + } + + mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); + if (!mon_ndev) { + DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter)); + ret = -ENOMEM; + goto out; + } + + mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(mon_ndev->name, name, IFNAMSIZ); + mon_ndev->name[IFNAMSIZ - 1] = 0; + mon_ndev->destructor = rtw_ndev_destructor; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; +#else + mon_ndev->open = rtw_cfg80211_monitor_if_open; + mon_ndev->stop = rtw_cfg80211_monitor_if_close; + mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry; + mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address; +#endif + + pnpi = netdev_priv(mon_ndev); + pnpi->priv = padapter; + pnpi->sizeof_priv = sizeof(_adapter); + + /* wdev */ + mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev)); + if (!mon_wdev) { + DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter)); + ret = -ENOMEM; + goto out; + } + + mon_wdev->wiphy = padapter->rtw_wdev->wiphy; + mon_wdev->netdev = mon_ndev; + mon_wdev->iftype = NL80211_IFTYPE_MONITOR; + mon_ndev->ieee80211_ptr = mon_wdev; + + ret = register_netdevice(mon_ndev); + if (ret) { + goto out; + } + + *ndev = pwdev_priv->pmon_ndev = mon_ndev; + _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1); + +out: + if (ret && mon_wdev) { + rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev)); + mon_wdev = NULL; + } + + if (ret && mon_ndev) { + free_netdev(mon_ndev); + *ndev = mon_ndev = NULL; + } + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +static struct wireless_dev * +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) +static struct net_device * +#else +static int +#endif + cfg80211_rtw_add_virtual_intf( + struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) + const char *name, + #else + char *name, + #endif + enum nl80211_iftype type, u32 *flags, struct vif_params *params) +{ + int ret = 0; + struct net_device* ndev = NULL; + _adapter *padapter = wiphy_to_adapter(wiphy); + + DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n", + FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type); + + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + case NL80211_IFTYPE_MESH_POINT: + ret = -ENODEV; + break; + case NL80211_IFTYPE_MONITOR: + ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); + break; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + case NL80211_IFTYPE_P2P_CLIENT: +#endif + case NL80211_IFTYPE_STATION: + ret = -ENODEV; + break; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_AP: + ret = -ENODEV; + break; + default: + ret = -ENODEV; + DBG_871X("Unsupported interface type\n"); + break; + } + + DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + return ndev ? ndev : ERR_PTR(ret); +#else + return ret; +#endif +} + +static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev +#else + struct net_device *ndev +#endif +) +{ + struct rtw_wdev_priv *pwdev_priv = (struct rtw_wdev_priv *)wiphy_priv(wiphy); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev; + ndev = wdev ? wdev->netdev : NULL; +#endif + + if (!ndev) + goto exit; + + unregister_netdevice(ndev); + + if (ndev == pwdev_priv->pmon_ndev) { + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev)); + } + +exit: + return 0; +} + +static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len) +{ + int ret=0; + u8 *pbuf = NULL; + uint len, wps_ielen=0; + uint p2p_ielen=0; + u8 *p2p_ie; + u8 got_p2p_ie = _FALSE; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + //struct sta_priv *pstapriv = &padapter->stapriv; + + + DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if(head_len<24) + return -EINVAL; + + + pbuf = rtw_zmalloc(head_len+tail_len); + if(!pbuf) + return -ENOMEM; + + + //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); + + //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) + // pstapriv->max_num_sta = NUM_STA; + + + _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len. + _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len); + + len = head_len+tail_len-24; + + //check wps ie if inclued + if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen)) + DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen); + +#ifdef CONFIG_P2P + //check p2p ie if inclued + if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + //check p2p if enable + if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen)) + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct wifidirect_info *pwdinfo= &(adapter->wdinfo); + + DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen); + got_p2p_ie = _TRUE; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_8192C("Enable P2P function for the first time\n"); + rtw_p2p_enable(adapter, P2P_ROLE_GO); + wdev_to_priv(adapter->rtw_wdev)->p2p_enabled = _TRUE; + } + else + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + + DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen); + + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 15; + } + } + } +#endif // CONFIG_P2P + + /* pbss_network->IEs will not include p2p_ie, wfd ie */ + rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4); + rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4); + + if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) + { +#ifdef CONFIG_P2P + //check p2p if enable + if(got_p2p_ie == _TRUE) + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct wifidirect_info *pwdinfo= &(adapter->wdinfo); + pwdinfo->operating_channel = pmlmeext->cur_channel; + } +#endif //CONFIG_P2P + ret = 0; + } + else + { + ret = -EINVAL; + } + + + rtw_mfree(pbuf, head_len+tail_len); + + return ret; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE) +static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct beacon_parameters *info) +{ + int ret=0; + _adapter *adapter = wiphy_to_adapter(wiphy); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); + + return ret; +} + +static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct beacon_parameters *info) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + pmlmeext->bstart_bss = _TRUE; + + cfg80211_rtw_add_beacon(wiphy, ndev, info); + + return 0; +} + +static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} +#else +static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ap_settings *settings) +{ + int ret = 0; + _adapter *adapter = wiphy_to_adapter(wiphy); + + DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev), + settings->hidden_ssid, settings->auth_type); + + ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len, + settings->beacon.tail, settings->beacon.tail_len); + + adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid; + + if (settings->ssid && settings->ssid_len) { + WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network; + WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network; + + if(0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter), + settings->ssid, settings->ssid_len, + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength); + + _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len); + pbss_network->Ssid.SsidLength = settings->ssid_len; + _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len); + pbss_network_ext->Ssid.SsidLength = settings->ssid_len; + + if(0) + DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + } + + return ret; +} + +static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_beacon_data *info) +{ + int ret = 0; + _adapter *adapter = wiphy_to_adapter(wiphy); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); + + return ret; +} + +static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +#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) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} + +static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev, + u8 *mac) +{ + int ret=0; + _irqL irqL; + _list *phead, *plist; + u8 updated; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__); + return -EINVAL; + } + + + if(!mac) + { + DBG_8192C("flush all sta, and cam_entry\n"); + + flush_all_cam_entry(padapter); //clear CAM + + ret = rtw_sta_flush(padapter); + + return ret; + } + + + DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac)); + + if (mac[0] == 0xff && mac[1] == 0xff && + mac[2] == 0xff && mac[3] == 0xff && + mac[4] == 0xff && mac[5] == 0xff) + { + return -EINVAL; + } + + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN)) + { + if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) + { + DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__); + } + else + { + DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid); + + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + + //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING); + //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + psta = NULL; + + break; + } + + } + + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated); + + DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return ret; + +} + +static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev, + u8 *mac, struct station_parameters *params) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} + +static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev, + int idx, u8 *mac, struct station_info *sinfo) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + //TODO: dump scanned queue + + return -ENOENT; +} + +static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev, + struct bss_parameters *params) +{ + u8 i; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); +/* + DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot); + DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble); + DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time); + DBG_8192C("ap_isolate=%d\n", params->ap_isolate); + + DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len); + for(i=0; ibasic_rates_len; i++) + { + DBG_8192C("basic_rates=%d\n", params->basic_rates[i]); + + } +*/ + return 0; + +} + +static int cfg80211_rtw_set_channel(struct wiphy *wiphy + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + , struct net_device *ndev + #endif + , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) +{ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + #endif + + return 0; +} + +static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_auth_request *req) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} + +static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_assoc_request *req) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} +#endif //CONFIG_AP_MODE + +void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + int type; + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 category, action; + + channel = rtw_get_oper_ch(padapter); + + DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); + #ifdef CONFIG_P2P + type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE); + if (type >= 0) + goto indicate; + #endif + rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action); + DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); + +indicate: + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); +#else + cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); +#endif +} + +void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + int type; + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 category, action; + + channel = rtw_get_oper_ch(padapter); + + DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); + #ifdef CONFIG_P2P + type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE); + if (type >= 0) { + switch (type) { + case P2P_GO_NEGO_CONF: + case P2P_PROVISION_DISC_RESP: + case P2P_INVIT_RESP: + rtw_set_scan_deny(padapter, 2000); + rtw_clear_scan_deny(padapter); + } + goto indicate; + } + #endif + rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action); + DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); + +indicate: + if (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); +#else + cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); +#endif +} + +void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg) +{ + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev); + u8 category, action; + + channel = rtw_get_oper_ch(adapter); + + 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 (channel <= RTW_CH_MAX_2G_CHANNEL) + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); + else + freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC); +#else + cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC); +#endif + +} + +#ifdef CONFIG_P2P +void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len) +{ + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; + u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 }; + uint p2p_ielen = 0; + uint wpsielen = 0; + u32 devinfo_contentlen = 0; + u8 devinfo_content[64] = { 0x00 }; + u16 capability = 0; + uint capability_len = 0; + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = 1; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_REQ; + u32 p2pielen = 0; +#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); + u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); + size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr); + + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + + //prepare for building provision_request frame + _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN); + _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN); + + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + + rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); + rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + switch(wps_devicepassword_id) + { + case WPS_DPID_PIN: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; + break; + case WPS_DPID_USER_SPEC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; + break; + case WPS_DPID_MACHINE_SPEC: + break; + case WPS_DPID_REKEY: + break; + case WPS_DPID_PBC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + break; + case WPS_DPID_REGISTRAR_SPEC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; + break; + default: + break; + } + + + if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) ) + { + + rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen); + rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len); + + } + + + //start to build provision_request frame + _rtw_memset(wpsie, 0, sizeof(wpsie)); + _rtw_memset(p2p_ie, 0, sizeof(p2p_ie)); + p2p_ielen = 0; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + + //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, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //build_prov_disc_request_p2p_ie + // P2P OUI + p2pielen = 0; + p2p_ie[ p2pielen++ ] = 0x50; + p2p_ie[ p2pielen++ ] = 0x6F; + p2p_ie[ p2pielen++ ] = 0x9A; + p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110301 + // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Device Info + // 3. Group ID ( When joining an operating P2P Group ) + + // P2P Capability ATTR + // Type: + p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + // Group Capability Bitmap, 1 byte + _rtw_memcpy(p2p_ie + p2pielen, &capability, 2); + p2pielen += 2; + + + // Device Info ATTR + // Type: + p2p_ie[ 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 ); + RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen); + p2pielen += 2; + + // Value: + _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen); + p2pielen += devinfo_contentlen; + + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen); + //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr); + //pframe += p2pielen; + pattrib->pktlen += p2p_ielen; + + 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 + + // 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->tx_prov_disc_info.wps_config_method_request ); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif //CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + //dump_mgntframe(padapter, pmgntframe); + if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) + DBG_8192C("%s, ack to\n", __func__); + + //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) + //{ + // DBG_8192C("waiting for p2p peer key-in PIN CODE\n"); + // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req. + //} + +} + +static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + struct ieee80211_channel * channel, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie) +{ + s32 err = 0; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq); + u8 ready_on_channel = _FALSE; + + DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration); + + 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 + + p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK); + } + + pcfg80211_wdinfo->is_ro_ch = _TRUE; + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + err = -EFAULT; + goto exit; + } + + _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pcfg80211_wdinfo->remain_on_ch_type= channel_type; + #endif + pcfg80211_wdinfo->remain_on_ch_cookie= *cookie; + + rtw_scan_abort(padapter); +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + rtw_scan_abort(padapter->pbuddy_adapter); +#endif //CONFIG_CONCURRENT_MODE + + //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE; + } + else + { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + } + + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + + if(duration < 400) + duration = duration*3;//extend from exper. + + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) && + (durationext_listen_interval)) + { + duration = duration + pwdinfo->ext_listen_interval; + } +#endif + + pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter); + + if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + if(remain_ch != pbuddy_mlmeext->cur_channel) + { + if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 || + (remain_ch != pmlmeext->cur_channel)) + { + DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__); + issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); + + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + + 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); + } + } + + ready_on_channel = _TRUE; + //pmlmeext->cur_channel = remain_ch; + //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + }else +#endif //CONFIG_CONCURRENT_MODE + if(remain_ch != pmlmeext->cur_channel ) + { + ready_on_channel = _TRUE; + //pmlmeext->cur_channel = remain_ch; + //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + } else { + DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch); + } + + + //call this after other things have been done +#ifdef CONFIG_CONCURRENT_MODE + if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 || + (remain_ch != pmlmeext->cur_channel)) + { + u8 co_channel = 0xff; + ATOMIC_SET(&pwdev_priv->ro_ch_to, 0); +#endif + + if(ready_on_channel == _TRUE) + { + if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) ) + pmlmeext->cur_channel = remain_ch; + +#ifdef CONFIG_CONCURRENT_MODE + co_channel = rtw_get_oper_ch(padapter); + + if(co_channel !=remain_ch) +#endif + { + if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) + set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + } + DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration); + _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration); + +#ifdef CONFIG_CONCURRENT_MODE + } +#endif + + rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL); + +exit: + if (err) + pcfg80211_wdinfo->is_ro_ch = _FALSE; + + return err; +} + +static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + u64 cookie) +{ + s32 err = 0; + _adapter *padapter = wiphy_to_adapter(wiphy); + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + 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 + p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK); + } + + #if 0 + // Disable P2P Listen State + if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info)); + } + } + else + #endif + { + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + } + pcfg80211_wdinfo->is_ro_ch = _FALSE; + + return err; +} + +#endif //CONFIG_P2P + +static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + int ret = _FAIL; + bool ack = _TRUE; + struct rtw_ieee80211_hdr *pwlanhdr; + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret = -EFAULT; + goto exit; + } + + rtw_set_scan_deny(padapter, 1000); + + rtw_scan_abort(padapter); + #ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + rtw_scan_abort(padapter->pbuddy_adapter); + #endif /* CONFIG_CONCURRENT_MODE */ + + if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) { + //DBG_8192C("%s, cancel ro ch timer\n", __func__); + //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); + //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE; + #ifdef CONFIG_CONCURRENT_MODE + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + { + DBG_8192C("%s, extend ro ch time\n", __func__); + _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); + } + #endif //CONFIG_CONCURRENT_MODE + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_LINKED )) { + u8 co_channel=0xff; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + co_channel = rtw_get_oper_ch(padapter); + + if (tx_ch != pbuddy_mlmeext->cur_channel) { + + u16 ext_listen_period; + + if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) { + DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__); + issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); + + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + + //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period); + //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period); + } + + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + { + ext_listen_period = 500;// 500ms + } + else + { + ext_listen_period = pwdinfo->ext_listen_period; + } + + DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period); + _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period); + + } + + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + pmlmeext->cur_channel = tx_ch; + + if (tx_ch != co_channel) + set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + }else +#endif //CONFIG_CONCURRENT_MODE + //if (tx_ch != pmlmeext->cur_channel) { + if(tx_ch != rtw_get_oper_ch(padapter)) { + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + pmlmeext->cur_channel = tx_ch; + set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + + //starting alloc mgmt frame to dump it + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + //ret = -ENOMEM; + ret = _FAIL; + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void*)buf, len); + pattrib->pktlen = len; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //update seq number + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + +#ifdef CONFIG_WFD + { + struct wifi_display_info *pwfd_info; + + pwfd_info = padapter->wdinfo.wfd_info; + + if ( _TRUE == pwfd_info->wfd_enable ) + { + rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen ); + } + } +#endif // CONFIG_WFD + + pattrib->last_txcmdsz = pattrib->pktlen; + + if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) + { + ack = _FALSE; + ret = _FAIL; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ack == _FAIL\n", __func__); + #endif + } + else + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ack=%d, ok!\n", __func__, ack); + #endif + ret = _SUCCESS; + } + +exit: + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ret=%d\n", __func__, ret); + #endif + + return ret; + +} + +static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + bool offchan, +#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) + bool channel_type_valid, + #endif +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + unsigned int wait, +#endif + const u8 *buf, size_t len, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + bool no_cck, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + bool dont_wait_for_ack, +#endif + u64 *cookie) +{ + _adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy); + struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev); + int ret = 0; + int tx_ret; + u32 dump_limit = RTW_MAX_MGMT_TX_CNT; + u32 dump_cnt = 0; + bool ack = _TRUE; + u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq); + u8 category, action; + int type = (-1); + u32 start = rtw_get_current_time(); + + /* cookie generation */ + *cookie = (unsigned long) buf; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d" + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + ", ch_type=%d" + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + ", channel_type_valid=%d" + #endif + #endif + "\n", FUNC_ADPT_ARG(padapter), + len, tx_ch + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + , channel_type + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + , channel_type_valid + #endif + #endif + ); +#endif /* CONFIG_DEBUG_CFG80211 */ + + /* indicate ack before issue frame to avoid racing with rsp frame */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL); +#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) + cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL); +#endif + + if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { + DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter), + le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl)); + goto exit; + } + + DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf))); + #ifdef CONFIG_P2P + if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) { + goto dump; + } + #endif + if (category == RTW_WLAN_CATEGORY_PUBLIC) + DBG_871X("RTW_Tx:%s\n", action_public_str(action)); + else + DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action); + +dump: + do { + dump_cnt++; + tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len); + } while (dump_cnt < dump_limit && tx_ret != _SUCCESS); + + if (tx_ret != _SUCCESS || dump_cnt > 1) { + DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter), + tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start)); + } + + switch (type) { + case P2P_GO_NEGO_CONF: + rtw_clear_scan_deny(padapter); + break; + case P2P_INVIT_RESP: + if (pwdev_priv->invit_info.flags & BIT(0) + && pwdev_priv->invit_info.status == 0) + { + DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n", + FUNC_ADPT_ARG(padapter)); + rtw_set_scan_deny(padapter, 5000); + rtw_pwr_wakeup_ex(padapter, 5000); + rtw_clear_scan_deny(padapter); + } + break; + } + +exit: + return ret; +} + +static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + u16 frame_type, bool reg) +{ + _adapter *adapter = wiphy_to_adapter(wiphy); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter), + frame_type, reg); +#endif + + if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) + return; + + return; +} + +static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 wps_oui[8]={0x0,0x50,0xf2,0x04}; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen); + #endif + + if(pmlmepriv->wps_beacon_ie) + { + u32 free_len = pmlmepriv->wps_beacon_ie_len; + pmlmepriv->wps_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_beacon_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); + pmlmepriv->wps_beacon_ie_len = wps_ielen; + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE); + + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen); + #endif + + if(pmlmepriv->p2p_beacon_ie) + { + u32 free_len = pmlmepriv->p2p_beacon_ie_len; + pmlmepriv->p2p_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); + pmlmepriv->p2p_beacon_ie = NULL; + } + + pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_beacon_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_beacon_ie_len = p2p_ielen; + + } + #endif //CONFIG_P2P + + //buf += p2p_ielen; + //len -= p2p_ielen; + + #ifdef CONFIG_WFD + if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen); + #endif + + if(pmlmepriv->wfd_beacon_ie) + { + u32 free_len = pmlmepriv->wfd_beacon_ie_len; + pmlmepriv->wfd_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len); + pmlmepriv->wfd_beacon_ie = NULL; + } + + pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen); + if ( pmlmepriv->wfd_beacon_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); + } + #endif //CONFIG_WFD + + pmlmeext->bstart_bss = _TRUE; + + } + + return ret; + +} + +static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + uint attr_contentlen = 0; + u16 uconfig_method, *puconfig_method = NULL; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen); + #endif + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + u8 sr = 0; + rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + + if (sr != 0) + { + DBG_871X("%s, got sr\n", __func__); + } + else + { + DBG_8192C("GO mode process WPS under site-survey, sr no set\n"); + return ret; + } + } + + if(pmlmepriv->wps_probe_resp_ie) + { + u32 free_len = pmlmepriv->wps_probe_resp_ie_len; + pmlmepriv->wps_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode + if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL ) + { + #ifdef CONFIG_DEBUG_CFG80211 + //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); + #endif + + uconfig_method = WPS_CM_PUSH_BUTTON; + uconfig_method = cpu_to_be16( uconfig_method ); + + *puconfig_method |= uconfig_method; + } + + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_resp_ie_len = wps_ielen; + + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + u8 is_GO = _FALSE; + u32 attr_contentlen = 0; + u16 cap_attr=0; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen); + #endif + + //Check P2P Capability ATTR + if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) ) + { + u8 grp_cap=0; + //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); + cap_attr = le16_to_cpu(cap_attr); + grp_cap = (u8)((cap_attr >> 8)&0xff); + + is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE; + + if(is_GO) + DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); + } + + + if(is_GO == _FALSE) + { + if(pmlmepriv->p2p_probe_resp_ie) + { + u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; + pmlmepriv->p2p_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); + pmlmepriv->p2p_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; + } + else + { + if(pmlmepriv->p2p_go_probe_resp_ie) + { + u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; + pmlmepriv->p2p_go_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); + pmlmepriv->p2p_go_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; + } + + } + #endif //CONFIG_P2P + + //buf += p2p_ielen; + //len -= p2p_ielen; + + #ifdef CONFIG_WFD + if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen); + #endif + + if(pmlmepriv->wfd_probe_resp_ie) + { + u32 free_len = pmlmepriv->wfd_probe_resp_ie_len; + pmlmepriv->wfd_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len); + pmlmepriv->wfd_probe_resp_ie = NULL; + } + + pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen); + if ( pmlmepriv->wfd_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); + } + #endif //CONFIG_WFD + + } + + return ret; + +} + +static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + DBG_8192C("%s, ielen=%d\n", __func__, len); + + if(len>0) + { + if(pmlmepriv->wps_assoc_resp_ie) + { + u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; + pmlmepriv->wps_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len); + if ( pmlmepriv->wps_assoc_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len); + pmlmepriv->wps_assoc_resp_ie_len = len; + } + + return ret; + +} + +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, + int type) +{ + int ret = 0; + uint wps_ielen = 0; + u32 p2p_ielen = 0; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0)) + #ifdef CONFIG_P2P + || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0)) + #endif + ) + { + if (net != NULL) + { + switch (type) + { + case 0x1: //BEACON + ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); + break; + case 0x2: //PROBE_RESP + ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); + break; + case 0x4: //ASSOC_RESP + ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); + break; + } + } + } + + return ret; + +} + +static struct cfg80211_ops rtw_cfg80211_ops = { + .change_virtual_intf = cfg80211_rtw_change_iface, + .add_key = cfg80211_rtw_add_key, + .get_key = cfg80211_rtw_get_key, + .del_key = cfg80211_rtw_del_key, + .set_default_key = cfg80211_rtw_set_default_key, + .get_station = cfg80211_rtw_get_station, + .scan = cfg80211_rtw_scan, + .set_wiphy_params = cfg80211_rtw_set_wiphy_params, + .connect = cfg80211_rtw_connect, + .disconnect = cfg80211_rtw_disconnect, + .join_ibss = cfg80211_rtw_join_ibss, + .leave_ibss = cfg80211_rtw_leave_ibss, + .set_tx_power = cfg80211_rtw_set_txpower, + .get_tx_power = cfg80211_rtw_get_txpower, + .set_power_mgmt = cfg80211_rtw_set_power_mgmt, + .set_pmksa = cfg80211_rtw_set_pmksa, + .del_pmksa = cfg80211_rtw_del_pmksa, + .flush_pmksa = cfg80211_rtw_flush_pmksa, + +#ifdef CONFIG_AP_MODE + .add_virtual_intf = cfg80211_rtw_add_virtual_intf, + .del_virtual_intf = cfg80211_rtw_del_virtual_intf, + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE) + .add_beacon = cfg80211_rtw_add_beacon, + .set_beacon = cfg80211_rtw_set_beacon, + .del_beacon = cfg80211_rtw_del_beacon, + #else + .start_ap = cfg80211_rtw_start_ap, + .change_beacon = cfg80211_rtw_change_beacon, + .stop_ap = cfg80211_rtw_stop_ap, + #endif + + .add_station = cfg80211_rtw_add_station, + .del_station = cfg80211_rtw_del_station, + .change_station = cfg80211_rtw_change_station, + .dump_station = cfg80211_rtw_dump_station, + .change_bss = cfg80211_rtw_change_bss, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) + .set_channel = cfg80211_rtw_set_channel, + #endif + //.auth = cfg80211_rtw_auth, + //.assoc = cfg80211_rtw_assoc, +#endif //CONFIG_AP_MODE + +#ifdef CONFIG_P2P + .remain_on_channel = cfg80211_rtw_remain_on_channel, + .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel, +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, +#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) + .action = cfg80211_rtw_mgmt_tx, +#endif +}; + +static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type) +{ + +#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ +#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ + + ht_cap->ht_supported = _TRUE; + + ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + + /* + *Maximum length of AMPDU that the STA can receive. + *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + */ + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + + /*Minimum MPDU start spacing , */ + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + /* + *hw->wiphy->bands[IEEE80211_BAND_2GHZ] + *base on ant_num + *rx_mask: RX mask + *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7 + *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15 + *if rx_ant >=3 rx_mask[2]=0xff; + *if BW_40 rx_mask[4]=0x01; + *highest supported RX rate + */ + if(rf_type == RF_1T1R) + { + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0x00; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; + } + else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R)) + { + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; + } + else + { + DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type); + } + +} + +void rtw_cfg80211_init_wiphy(_adapter *padapter) +{ + u8 rf_type; + struct ieee80211_supported_band *bands; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct wiphy *wiphy = pwdev->wiphy; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + DBG_8192C("%s:rf_type=%d\n", __func__, rf_type); + + /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ + { + bands = wiphy->bands[IEEE80211_BAND_2GHZ]; + if(bands) + rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type); + } + + /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ + { + bands = wiphy->bands[IEEE80211_BAND_5GHZ]; + if(bands) + rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type); + } +} + +/* +struct ieee80211_iface_limit rtw_limits[] = { + { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) +#ifdef CONFIG_AP_MODE + | BIT(NL80211_IFTYPE_AP) +#endif +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) +#endif + }, + {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)}, +}; + +struct ieee80211_iface_combination rtw_combinations = { + .limits = rtw_limits, + .n_limits = ARRAY_SIZE(rtw_limits), + .max_interfaces = 2, + .num_different_channels = 1, +}; +*/ + +static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy) +{ + + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT; + wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION; +#endif + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) +#ifdef CONFIG_AP_MODE + | BIT(NL80211_IFTYPE_AP) + | BIT(NL80211_IFTYPE_MONITOR) +#endif +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) +#endif + ; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) +#ifdef CONFIG_AP_MODE + wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; +#endif //CONFIG_AP_MODE +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) + wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); +#endif + + /* + wiphy->iface_combinations = &rtw_combinations; + wiphy->n_iface_combinations = 1; + */ + + wiphy->cipher_suites = rtw_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); + + /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */ + wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ); + /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */ + wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; +#endif + + if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; + else + wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; +} + +int rtw_wdev_alloc(_adapter *padapter, struct device *dev) +{ + int ret = 0; + struct wiphy *wiphy; + struct wireless_dev *wdev; + struct rtw_wdev_priv *pwdev_priv; + struct net_device *pnetdev = padapter->pnetdev; + + DBG_8192C("%s(padapter=%p)\n", __func__, padapter); + + /* wiphy */ + wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv)); + if (!wiphy) { + DBG_8192C("Couldn't allocate wiphy device\n"); + ret = -ENOMEM; + goto exit; + } + set_wiphy_dev(wiphy, dev); + rtw_cfg80211_preinit_wiphy(padapter, wiphy); + + ret = wiphy_register(wiphy); + if (ret < 0) { + DBG_8192C("Couldn't register wiphy device\n"); + goto free_wiphy; + } + + /* wdev */ + wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev)); + if (!wdev) { + DBG_8192C("Couldn't allocate wireless device\n"); + ret = -ENOMEM; + goto unregister_wiphy; + } + wdev->wiphy = wiphy; + wdev->netdev = pnetdev; + //wdev->iftype = NL80211_IFTYPE_STATION; + wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface() + padapter->rtw_wdev = wdev; + pnetdev->ieee80211_ptr = wdev; + + //init pwdev_priv + pwdev_priv = wdev_to_priv(wdev); + pwdev_priv->rtw_wdev = wdev; + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + pwdev_priv->padapter = padapter; + pwdev_priv->scan_request = NULL; + _rtw_spinlock_init(&pwdev_priv->scan_req_lock); + + pwdev_priv->p2p_enabled = _FALSE; + pwdev_priv->provdisc_req_issued = _FALSE; + rtw_wdev_invit_info_init(&pwdev_priv->invit_info); + rtw_wdev_nego_info_init(&pwdev_priv->nego_info); + + pwdev_priv->bandroid_scan = _FALSE; + + if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) + pwdev_priv->power_mgmt = _TRUE; + else + pwdev_priv->power_mgmt = _FALSE; + +#ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); +#endif + + return ret; + + rtw_mfree((u8*)wdev, sizeof(struct wireless_dev)); +unregister_wiphy: + wiphy_unregister(wiphy); + free_wiphy: + wiphy_free(wiphy); +exit: + return ret; + +} + +void rtw_wdev_free(struct wireless_dev *wdev) +{ + struct rtw_wdev_priv *pwdev_priv; + + DBG_8192C("%s(wdev=%p)\n", __func__, wdev); + + if (!wdev) + return; + + pwdev_priv = wdev_to_priv(wdev); + + rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]); + rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]); + + wiphy_free(wdev->wiphy); + + rtw_mfree((u8*)wdev, sizeof(struct wireless_dev)); +} + +void rtw_wdev_unregister(struct wireless_dev *wdev) +{ + struct rtw_wdev_priv *pwdev_priv; + + DBG_8192C("%s(wdev=%p)\n", __func__, wdev); + + if (!wdev) + return; + + pwdev_priv = wdev_to_priv(wdev); + + rtw_cfg80211_indicate_scan_done(pwdev_priv, _TRUE); + + if (pwdev_priv->pmon_ndev) { + DBG_8192C("%s, unregister monitor interface\n", __func__); + unregister_netdev(pwdev_priv->pmon_ndev); + } + + wiphy_unregister(wdev->wiphy); +} + +#endif //CONFIG_IOCTL_CFG80211 + diff --git a/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c b/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c new file mode 100755 index 00000000..9adbeaf1 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c @@ -0,0 +1,11909 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _IOCTL_LINUX_C_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#ifdef CONFIG_MP_INCLUDED +#include +//#endif + +#ifdef CONFIG_USB_HCI +#include +#endif //CONFIG_USB_HCI +#include + +#ifdef CONFIG_MP_INCLUDED +#include +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) +#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e) +#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e) +#endif + + +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 + +#define SCAN_ITEM_SIZE 768 +#define MAX_CUSTOM_LEN 64 +#define RATE_COUNT 4 + +#ifdef CONFIG_GLOBAL_UI_PID +extern int ui_pid[3]; +#endif + +// combo scan +#define WEXT_CSCAN_AMOUNT 9 +#define WEXT_CSCAN_BUF_LEN 360 +#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" +#define WEXT_CSCAN_HEADER_SIZE 12 +#define WEXT_CSCAN_SSID_SECTION 'S' +#define WEXT_CSCAN_CHANNEL_SECTION 'C' +#define WEXT_CSCAN_NPROBE_SECTION 'N' +#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' +#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' +#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' +#define WEXT_CSCAN_TYPE_SECTION 'T' + + +extern u8 key_2char2num(u8 hch, u8 lch); +extern u8 str_2char2num(u8 hch, u8 lch); +extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); + +u32 rtw_rates[] = {1000000,2000000,5500000,11000000, + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; + +static const char * const iw_operation_mode[] = +{ + "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor" +}; + +static int hex2num_i(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex2byte_i(const char *hex) +{ + int a, b; + a = hex2num_i(*hex++); + if (a < 0) + return -1; + b = hex2num_i(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +/** + * hwaddr_aton - Convert ASCII string to MAC address + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +static int hwaddr_aton_i(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num_i(*txt++); + if (a < 0) + return -1; + b = hex2num_i(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + +static void indicate_wx_custom_event(_adapter *padapter, char *msg) +{ +#ifndef CONFIG_IOCTL_CFG80211 + u8 *buff, *p; + union iwreq_data wrqu; + + if ((u32)strlen(msg) > IW_CUSTOM_MAX) { + DBG_871X("%s strlen(msg):%u > IW_CUSTOM_MAX:%u\n", __FUNCTION__ ,(u32)strlen(msg), IW_CUSTOM_MAX); + return; + } + + buff = rtw_zmalloc(IW_CUSTOM_MAX+1); + if(!buff) + return; + + _rtw_memcpy(buff, msg, strlen(msg)); + + _rtw_memset(&wrqu,0,sizeof(wrqu)); + wrqu.data.length = strlen(msg); + + DBG_871X("%s %s\n", __FUNCTION__, buff); + wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff); + + rtw_mfree(buff, IW_CUSTOM_MAX+1); +#endif +} + + +static void request_wps_pbc_event(_adapter *padapter) +{ +#ifndef CONFIG_IOCTL_CFG80211 + u8 *buff, *p; + union iwreq_data wrqu; + + buff = rtw_malloc(IW_CUSTOM_MAX); + if(!buff) + return; + + _rtw_memset(buff, 0, IW_CUSTOM_MAX); + + p=buff; + + p+=sprintf(p, "WPS_PBC_START.request=TRUE"); + + _rtw_memset(&wrqu,0,sizeof(wrqu)); + + wrqu.data.length = p-buff; + + wrqu.data.length = (wrqu.data.lengthpnetdev, IWEVCUSTOM, &wrqu, buff); + + if(buff) + { + rtw_mfree(buff, IW_CUSTOM_MAX); + } +#endif +} + + +void indicate_wx_scan_complete_event(_adapter *padapter) +{ +#ifndef CONFIG_IOCTL_CFG80211 + union iwreq_data wrqu; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + //DBG_871X("+rtw_indicate_wx_scan_complete_event\n"); + wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL); +#endif +} + + +void rtw_indicate_wx_assoc_event(_adapter *padapter) +{ +#ifndef CONFIG_IOCTL_CFG80211 + union iwreq_data wrqu; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); + + //DBG_871X("+rtw_indicate_wx_assoc_event\n"); + wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); +#endif +} + +void rtw_indicate_wx_disassoc_event(_adapter *padapter) +{ +#ifndef CONFIG_IOCTL_CFG80211 + union iwreq_data wrqu; + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + + //DBG_871X("+rtw_indicate_wx_disassoc_event\n"); + wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); +#endif +} + +/* +uint rtw_is_cckrates_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + i++; + } + + return _FALSE; +} + +uint rtw_is_cckratesonly_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + return _FALSE; + i++; + } + + return _TRUE; +} +*/ + +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; + char custom[MAX_CUSTOM_LEN]; + char *p; + u16 max_rate=0, rate, ht_cap=_FALSE; + u32 i = 0; + char *current_val; + long rssi; + u8 bw_40MHz=0, short_GI=0; + u16 mcs_rate=0; + 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 ) + { + + } + else if ( ( SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type ) || + ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) ) +#endif // CONFIG_WFD + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + u32 blnGotP2PIE = _FALSE; + + // User is doing the P2P device discovery + // The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. + // If not, the driver should ignore this AP and go to the next AP. + + // Verifying the SSID + if ( _rtw_memcmp( pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ) ) + { + u32 p2pielen = 0; + + // Verifying the P2P IE + if ( rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen) ) + { + blnGotP2PIE = _TRUE; + } + } + + if ( blnGotP2PIE == _FALSE ) + { + return start; + } + + } + } + +#ifdef CONFIG_WFD + if ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) + { + u32 blnGotWFD = _FALSE; + u8 wfd_ie[ 128 ] = { 0x00 }; + uint wfd_ielen = 0; + + if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + { + u8 wfd_devinfo[ 6 ] = { 0x00 }; + uint wfd_devlen = 6; + + if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen) ) + { + if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK ) + { + // the first two bits will indicate the WFD device type + if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_SOURCE ) + { + // If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. + blnGotWFD = _TRUE; + } + } + else if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE ) + { + // the first two bits will indicate the WFD device type + if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_PSINK ) + { + // If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. + // Todo: How about the SSink?! + blnGotWFD = _TRUE; + } + } + } + } + + if ( blnGotWFD == _FALSE ) + { + return start; + } + } +#endif // CONFIG_WFD + +#endif //CONFIG_P2P + /* 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); + + /* 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); + + //parsing HT_CAP_IE + p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12); + + 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; + } + + /* 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) + { + 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); + + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); + + + cap = le16_to_cpu(cap); + + if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){ + 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); + } + + 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); + + /* 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); + + /*Add basic and extended rates */ + max_rate = 0; + 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++; + } + + 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); + + //parsing WPA/WPA2 IE + { + u8 buf[MAX_WPA_IE_LEN]; + u8 wpa_ie[255],rsn_ie[255]; + u16 wpa_len=0,rsn_len=0; + u8 *p; + sint out_len=0; + 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) + { + p=buf; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN); + p += sprintf(p, "wpa_ie="); + for (i = 0; i < wpa_len; i++) { + p += sprintf(p, "%02x", wpa_ie[i]); + } + + _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); + + _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) + { + p = buf; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN); + 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(buf); + start = iwe_stream_add_point(info, start, stop, &iwe,buf); + + _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); + } + } + + { //parsing WPS IE + uint cnt = 0,total_ielen; + u8 *wpsie_ptr=NULL; + uint wps_ielen = 0; + + u8 *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 + } + } + + +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 ss, sq; + + /* Add quality statistics */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID + #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)) { + 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 + iwe.u.qual.level = (u8)ss;//% + #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 + iwe.u.qual.noise = 0; // noise level + #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 int wpa_set_auth_algs(struct net_device *dev, u32 value) +{ + _adapter *padapter = (_adapter *) rtw_netdev_priv(dev); + int ret = 0; + + if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM)) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + } + else if (value & AUTH_ALG_SHARED_KEY) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n",value); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; +#endif + } + else if(value & AUTH_ALG_OPEN_SYSTEM) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); + //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) + { +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; +#endif + } + + } + else if(value & AUTH_ALG_LEAP) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); + } + else + { + DBG_871X("wpa_set_auth_algs, error!\n"); + ret = -EINVAL; + } + + return ret; + +} + +static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + NDIS_802_11_WEP *pwep = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + +_func_enter_; + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif //CONFIG_IEEE80211W + ) + { + ret = -EINVAL; + goto exit; + } + } + else + { + + { + ret = -EINVAL; + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "WEP") == 0) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n")); + DBG_871X("wpa_set_encryption, crypt.alg = WEP\n"); + + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(1)wep_key_idx=%d\n", wep_key_idx)); + DBG_871X("(1)wep_key_idx=%d\n", wep_key_idx); + + if (wep_key_idx > WEP_KEYS) + return -EINVAL; + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("(2)wep_key_idx=%d\n", wep_key_idx)); + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len); + if(pwep == NULL){ + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,(" wpa_set_encryption: pwep allocate fail !!!\n")); + goto exit; + } + + _rtw_memset(pwep, 0, wep_total_len); + + pwep->KeyLength = wep_key_len; + pwep->Length = wep_total_len; + + if(wep_key_len==13) + { + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + } + } + else { + ret = -EINVAL; + goto exit; + } + + pwep->KeyIndex = wep_key_idx; + pwep->KeyIndex |= 0x80000000; + + _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); + + if(param->u.crypt.set_tx) + { + DBG_871X("wep, set_tx=1\n"); + + if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) + { + ret = -EOPNOTSUPP ; + } + } + else + { + DBG_871X("wep, set_tx=0\n"); + + //don't update "psecuritypriv->dot11PrivacyAlgrthm" and + //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to fw/cam + + if (wep_key_idx >= WEP_KEYS) { + ret = -EOPNOTSUPP ; + goto exit; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); + psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength; + rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0); + } + + goto exit; + } + + if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x + { + struct sta_info * psta,*pbcmc_sta; + struct sta_priv * pstapriv = &padapter->stapriv; + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode + { + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + psta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + + if(param->u.crypt.set_tx ==1)//pairwise key + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key + { + //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + padapter->securitypriv.busetkipkey=_FALSE; + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + } + + //DEBUG_ERR(("\n param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); + //DEBUG_ERR(("\n ~~~~stastakey:unicastkey\n")); + DBG_871X("\n ~~~~stastakey:unicastkey\n"); + + rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE); + } + else//group key + { + if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + //only TKIP group key need to install this + if(param->u.crypt.key_len > 16) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); + _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); + } + padapter->securitypriv.binstallGrpkey = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:groupkey\n"); + + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + + rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1); + } +#ifdef CONFIG_IEEE80211W + else if(strcmp(param->u.crypt.alg, "BIP") == 0) + { + int no; + //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); + //save the IGTK key, length 16 bytes + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + /*printk("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + printk("\n");*/ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + } +#endif //CONFIG_IEEE80211W + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); + } +#endif //CONFIG_P2P + + } + } + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta==NULL) + { + //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + pbcmc_sta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + } + } + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode + { + } + } + +exit: + + if (pwep) { + rtw_mfree((u8 *)pwep, wep_total_len); + } + + _func_exit_; + + return ret; +} + +static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen) +{ + u8 *buf=NULL, *pos=NULL; + u32 left; + int group_cipher = 0, pairwise_cipher = 0; + int ret = 0; + u8 null_addr[]= {0,0,0,0,0,0}; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + + if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){ + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + if(pie == NULL) + return ret; + else + return -EINVAL; + } + + if(ielen) + { + buf = rtw_zmalloc(ielen); + if (buf == NULL){ + ret = -ENOMEM; + goto exit; + } + + _rtw_memcpy(buf, pie , ielen); + + //dump + { + int i; + DBG_871X("\n wpa_ie(length:%d):\n", ielen); + for(i=0;i= RSN_SELECTOR_LEN){ + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + } + else if (left > 0){ + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie length mismatch, %u too much \n", left)); + ret =-1; + goto exit; + } +#endif + + if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); + } + + if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); + } + + if (group_cipher == 0) + { + group_cipher = WPA_CIPHER_NONE; + } + if (pairwise_cipher == 0) + { + pairwise_cipher = WPA_CIPHER_NONE; + } + + switch(group_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot118021XGrpPrivacy=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot11PrivacyAlgrthm=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + {//set wps_ie + u16 cnt = 0; + u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04}; + + while( cnt < ielen ) + { + eid = buf[cnt]; + + if((eid==_VENDOR_SPECIFIC_IE_)&&(_rtw_memcmp(&buf[cnt+2], wps_oui, 4)==_TRUE)) + { + DBG_871X("SET WPS_IE\n"); + + padapter->securitypriv.wps_ie_len = ( (buf[cnt+1]+2) < (MAX_WPA_IE_LEN<<2)) ? (buf[cnt+1]+2):(MAX_WPA_IE_LEN<<2); + + _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); + + set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING); + } +#endif //CONFIG_P2P + cnt += buf[cnt+1]+2; + + break; + } else { + cnt += buf[cnt+1]+2; //goto next + } + } + } + } + + //TKIP and AES disallow multicast packets until installing group key + if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) + //WPS open need to enable multicast + //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) + rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n", + pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + +exit: + + if (buf) rtw_mfree(buf, ielen); + + return ret; +} + +static int rtw_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u16 cap; + u32 ht_ielen = 0; + char *p; + u8 ht_cap=_FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + NDIS_802_11_RATES_EX* prates = NULL; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd)); + + _func_enter_; + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + //parsing HT_CAP_IE + p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12); + if(p && ht_ielen>0) + { + ht_cap = _TRUE; + } + + prates = &pcur_bss->SupportedRates; + + if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); + } + else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); + } + else + { + if(pcur_bss->Configuration.DSConfig > 14) + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); + } + else + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); + } + } + } + else + { + //prates = &padapter->registrypriv.dev_network.SupportedRates; + //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); + snprintf(wrqu->name, IFNAMSIZ, "unassociated"); + } + + _func_exit_; + + return 0; +} + +static int rtw_wx_set_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n")); + + _func_exit_; + + return 0; +} + +static int rtw_wx_get_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + //wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; + wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; + wrqu->freq.e = 1; + wrqu->freq.i = pcur_bss->Configuration.DSConfig; + + } + else{ + wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; + wrqu->freq.e = 1; + wrqu->freq.i = padapter->mlmeextpriv.cur_channel; + } + + return 0; +} + +static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ; + int ret = 0; + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _queue *queue = &pmlmepriv->scanned_queue; + _func_enter_; + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + if (padapter->hw_init_completed==_FALSE){ + ret = -EPERM; + goto exit; + } + + switch(wrqu->mode) + { + case IW_MODE_AUTO: + networkType = Ndis802_11AutoUnknown; + DBG_871X("set_mode = IW_MODE_AUTO\n"); + break; + case IW_MODE_ADHOC: + networkType = Ndis802_11IBSS; + DBG_871X("set_mode = IW_MODE_ADHOC\n"); + break; + case IW_MODE_MASTER: + networkType = Ndis802_11APMode; + DBG_871X("set_mode = IW_MODE_MASTER\n"); + //rtw_setopmode_cmd(padapter, networkType); + break; + case IW_MODE_INFRA: + networkType = Ndis802_11Infrastructure; + DBG_871X("set_mode = IW_MODE_INFRA\n"); + break; + + default : + ret = -EINVAL;; + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode])); + goto exit; + } + +/* + if(Ndis802_11APMode == networkType) + { + rtw_setopmode_cmd(padapter, networkType); + } + else + { + rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown); + } +*/ + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _enter_critical_bh(&queue->lock, &irqL); + if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){ + + ret = -EPERM; + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + goto exit; + + } + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + rtw_setopmode_cmd(padapter, networkType); + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n")); + + _func_enter_; + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + wrqu->mode = IW_MODE_INFRA; + } + else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + + { + wrqu->mode = IW_MODE_ADHOC; + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + wrqu->mode = IW_MODE_MASTER; + } + else + { + wrqu->mode = IW_MODE_AUTO; + } + + _func_exit_; + + return 0; + +} + + +static int rtw_wx_set_pmkid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 j,blInserted = _FALSE; + int intReturn = _FALSE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct iw_pmksa* pPMK = ( struct iw_pmksa* ) extra; + u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 }; + u8 strIssueBssid[ ETH_ALEN ] = { 0x00 }; + +/* + struct iw_pmksa + { + __u32 cmd; + struct sockaddr bssid; + __u8 pmkid[IW_PMKID_LEN]; //IW_PMKID_LEN=16 + } + There are the BSSID information in the bssid.sa_data array. + If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information. + If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver. + If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver. + */ + + _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); + if ( pPMK->cmd == IW_PMKSA_ADD ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" ); + if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE ) + { + return( intReturn ); + } + else + { + intReturn = _TRUE; + } + blInserted = _FALSE; + + //overwrite PMKID + for(j=0 ; jPMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE ) + { // BSSID is matched, the same AP => rewrite with new PMKID. + + DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" ); + + _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); + psecuritypriv->PMKIDList[ j ].bUsed = _TRUE; + psecuritypriv->PMKIDIndex = j+1; + blInserted = _TRUE; + break; + } + } + + if(!blInserted) + { + // Find a new entry + DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", + psecuritypriv->PMKIDIndex ); + + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); + + psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE; + psecuritypriv->PMKIDIndex++ ; + if(psecuritypriv->PMKIDIndex==16) + { + psecuritypriv->PMKIDIndex =0; + } + } + } + else if ( pPMK->cmd == IW_PMKSA_REMOVE ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" ); + intReturn = _TRUE; + for(j=0 ; jPMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE ) + { // BSSID is matched, the same AP => Remove this PMKID information and reset it. + _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN ); + psecuritypriv->PMKIDList[ j ].bUsed = _FALSE; + break; + } + } + } + else if ( pPMK->cmd == IW_PMKSA_FLUSH ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" ); + _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + psecuritypriv->PMKIDIndex = 0; + intReturn = _TRUE; + } + return( intReturn ); +} + +static int rtw_wx_get_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + #ifdef CONFIG_PLATFORM_ROCKCHIPS + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + /* + * 20110311 Commented by Jeff + * For rockchip platform's wpa_driver_wext_get_rssi + */ + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + //wrqu->sens.value=-padapter->recvpriv.signal_strength; + wrqu->sens.value=-padapter->recvpriv.rssi; + //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value); + wrqu->sens.fixed = 0; /* no auto select */ + } else + #endif + { + wrqu->sens.value = 0; + wrqu->sens.fixed = 0; /* no auto select */ + wrqu->sens.disabled = 1; + } + return 0; +} + +static int rtw_wx_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + u16 val; + int i; + + _func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd)); + + wrqu->data.length = sizeof(*range); + _rtw_memset(range, 0, sizeof(*range)); + + /* Let's try to keep this struct in the same order as in + * linux/include/wireless.h + */ + + /* TODO: See what values we can set, and remove the ones we can't + * set, or fill them with some default data. + */ + + /* ~5 Mb/s real (802.11b) */ + range->throughput = 5 * 1000 * 1000; + + // TODO: Not used in 802.11b? +// range->min_nwid; /* Minimal NWID we are able to set */ + // TODO: Not used in 802.11b? +// range->max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ +// range->old_num_channels; +// range->old_num_frequency; +// range->old_freq[6]; /* Filler to keep "version" at the same offset */ + + /* signal level threshold range */ + + //percent values between 0 and 100. + range->max_qual.qual = 100; + range->max_qual.level = 100; + range->max_qual.noise = 100; + range->max_qual.updated = 7; /* Updated all three */ + + + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + range->avg_qual.level = 20 + -98; + range->avg_qual.noise = 0; + range->avg_qual.updated = 7; /* Updated all three */ + + range->num_bitrates = RATE_COUNT; + + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { + range->bitrate[i] = rtw_rates[i]; + } + + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + range->pm_capa = 0; + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 16; + +// range->retry_capa; /* What retry options are supported */ +// range->retry_flags; /* How to decode max/min retry limit */ +// range->r_time_flags; /* How to decode max/min retry life */ +// range->min_retry; /* Minimal number of retries */ +// range->max_retry; /* Maximal number of retries */ +// range->min_r_time; /* Minimal retry lifetime */ +// range->max_r_time; /* Maximal retry lifetime */ + + for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { + + // Include only legal frequencies for some countries + if(pmlmeext->channel_set[i].ChannelNum != 0) + { + range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; + range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; + range->freq[val].e = 1; + val++; + } + + if (val == IW_MAX_FREQUENCIES) + break; + } + + range->num_channels = val; + range->num_frequency = val; + +// Commented by Albert 2009/10/13 +// The following code will proivde the security capability to network manager. +// If the driver doesn't provide this capability to network manager, +// the WPA/WPA2 routers can't be choosen in the network manager. + +/* +#define IW_SCAN_CAPA_NONE 0x00 +#define IW_SCAN_CAPA_ESSID 0x01 +#define IW_SCAN_CAPA_BSSID 0x02 +#define IW_SCAN_CAPA_CHANNEL 0x04 +#define IW_SCAN_CAPA_MODE 0x08 +#define IW_SCAN_CAPA_RATE 0x10 +#define IW_SCAN_CAPA_TYPE 0x20 +#define IW_SCAN_CAPA_TIME 0x40 +*/ + +#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| + IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; +#endif + +#ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21 + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID| + IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE; +#endif + + + _func_exit_; + + return 0; + +} + +//set bssid flow +//s1. rtw_set_802_11_infrastructure_mode() +//s2. rtw_set_802_11_authentication_mode() +//s3. set_802_11_encryption_mode() +//s4. rtw_set_802_11_bssid() +static int rtw_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + _irqL irqL; + uint ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sockaddr *temp = (struct sockaddr *)awrq; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _list *phead; + u8 *dst_bssid, *src_bssid; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + + _func_enter_; +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + printk("set bssid, but buddy_intf is under scanning or linking\n"); + + ret = -EINVAL; + + goto exit; + } +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE) + { + printk("set bssid, but buddy_intf is under scanning or linking\n"); + ret = -EINVAL; + goto exit; + } +#endif + + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret= -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + + + if (temp->sa_family != ARPHRD_ETHER){ + ret = -EINVAL; + goto exit; + } + + authmode = padapter->securitypriv.ndisauthtype; + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + pmlmepriv->pscanned = get_next(phead); + + while (1) + { + + if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) + { +#if 0 + ret = -EINVAL; + goto exit; + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + rtw_set_802_11_bssid(padapter, temp->sa_data); + goto exit; + } + else + { + ret = -EINVAL; + goto exit; + } +#endif + + break; + } + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + dst_bssid = pnetwork->network.MacAddress; + + src_bssid = temp->sa_data; + + if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) + { + if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) + { + ret = -1; + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + goto exit; + } + + break; + } + + } + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + rtw_set_802_11_authentication_mode(padapter, authmode); + //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) { + ret = -1; + goto exit; + } + +exit: + + _func_exit_; + + return ret; +} + +static int rtw_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + + _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n")); + + _func_enter_; + + if ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) || + ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) || + ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) ) + { + + _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); + } + else + { + _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + } + + _func_exit_; + + return 0; + +} + +static int rtw_wx_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#if 0 +/* SIOCSIWMLME data */ +struct iw_mlme +{ + __u16 cmd; /* IW_MLME_* */ + __u16 reason_code; + struct sockaddr addr; +}; +#endif + + int ret=0; + u16 reason; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_mlme *mlme = (struct iw_mlme *) extra; + + + if(mlme==NULL) + return -1; + + printk("%s\n", __FUNCTION__); + + reason = cpu_to_le16(mlme->reason_code); + + + printk("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason); + + switch (mlme->cmd) + { + case IW_MLME_DEAUTH: + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + break; + + case IW_MLME_DISASSOC: + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + default: + return -EOPNOTSUPP; + } + + return ret; + +} + +static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + u8 _status = _FALSE; + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + _irqL irqL; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n")); + +_func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -1; + goto exit; + } +#endif +*/ + +#ifdef CONFIG_MP_INCLUDED + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + ret = -1; + goto exit; + } +#endif + + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret= -1; + goto exit; + } + + if(padapter->bDriverStopped){ + DBG_871X("bDriverStopped=%d\n", padapter->bDriverStopped); + ret= -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + + if (padapter->hw_init_completed==_FALSE){ + ret = -1; + goto exit; + } + + // When Busy Traffic, driver do not site survey. So driver return success. + // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. + // modify by thomas 2011-02-22. + if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, + _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) + { + if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) + { + printk("scanning_via_buddy_intf\n"); + pmlmepriv->scanning_via_buddy_intf = _TRUE; + } + + indicate_wx_scan_complete_event(padapter); + + goto exit; + } +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } +#endif + +// Mareded by Albert 20101103 +// For the DMP WiFi Display project, the driver won't to scan because +// the pmlmepriv->scan_interval is always equal to 3. +// So, the wpa_supplicant won't find out the WPS SoftAP. + +/* + if(pmlmepriv->scan_interval>10) + pmlmepriv->scan_interval = 0; + + if(pmlmepriv->scan_interval > 0) + { + DBG_871X("scan done\n"); + ret = 0; + goto exit; + } + +*/ +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL); + rtw_free_network_queue(padapter, _TRUE); + } +#endif //CONFIG_P2P + + _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT); + +#if WIRELESS_EXT >= 17 + if (wrqu->data.length == sizeof(struct iw_scan_req)) + { + struct iw_scan_req *req = (struct iw_scan_req *)extra; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) + { + int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); + + _rtw_memcpy(ssid[0].Ssid, req->essid, len); + ssid[0].SsidLength = len; + + DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + } + else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) + { + DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); + } + + } + else +#endif + + if( wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE + && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE + ) + { + int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE; + char *pos = extra+WEXT_CSCAN_HEADER_SIZE; + char section; + char sec_len; + int ssid_index = 0; + + //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__); + + while(len >= 1) { + section = *(pos++); len-=1; + + switch(section) { + case WEXT_CSCAN_SSID_SECTION: + //DBG_871X("WEXT_CSCAN_SSID_SECTION\n"); + if(len < 1) { + len = 0; + break; + } + + sec_len = *(pos++); len-=1; + + if(sec_len>0 && sec_len<=len) { + ssid[ssid_index].SsidLength = sec_len; + _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); + //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__ + // , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength); + ssid_index++; + } + + pos+=sec_len; len-=sec_len; + break; + + + case WEXT_CSCAN_CHANNEL_SECTION: + //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n"); + pos+=1; len-=1; + break; + case WEXT_CSCAN_ACTV_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_PASV_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_HOME_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_TYPE_SECTION: + //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n"); + pos+=1; len-=1; + break; + #if 0 + case WEXT_CSCAN_NPROBE_SECTION: + DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n"); + break; + #endif + + default: + //DBG_871X("Unknown CSCAN section %c\n", section); + len = 0; // stop parsing + } + //DBG_871X("len:%d\n", len); + + } + + //jeff: it has still some scan paramater to parse, we only do this now... + _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); + + } else + + { + _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); + } + + if(_status == _FALSE) + ret = -1; + +exit: + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + +_func_exit_; + + return ret; +} + +static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _irqL irqL; + _list *plist, *phead; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + char *ev = extra; + char *stop = ev + wrqu->data.length; + u32 ret = 0; + u32 cnt=0; + u32 wait_for_surveydone; + sint wait_status; +#ifdef CONFIG_CONCURRENT_MODE + //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); +#endif +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n")); + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n")); + + _func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif + +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + if(padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) + { + ret = -EINVAL; + goto exit; + } + +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + // P2P is enabled + if ( padapter->chip_type == RTL8192D ) + wait_for_surveydone = 300; // Because the 8192du supports more channels. + else + wait_for_surveydone = 200; + } + else + { + // P2P is disabled + wait_for_surveydone = 100; + } +#else + { + wait_for_surveydone = 100; + } +#endif //CONFIG_P2P + +/* +#ifdef CONFIG_CONCURRENT_MODE + if(pmlmepriv->scanning_via_buddy_intf == _TRUE) + { + pmlmepriv->scanning_via_buddy_intf = _FALSE;//reset + + // change pointers to buddy interface + padapter = pbuddy_adapter; + pmlmepriv = pbuddy_mlmepriv; + queue = &(pbuddy_mlmepriv->scanned_queue); + + } +#endif // CONFIG_CONCURRENT_MODE +*/ + + wait_status = _FW_UNDER_SURVEY + #ifndef CONFIG_ANDROID + |_FW_UNDER_LINKING + #endif + ; + +#ifdef CONFIG_DUALMAC_CONCURRENT + while(dc_check_fwstate(padapter, wait_status)== _TRUE) + { + rtw_msleep_os(30); + cnt++; + if(cnt > wait_for_surveydone ) + break; + } +#endif // CONFIG_DUALMAC_CONCURRENT + + while(check_fwstate(pmlmepriv, wait_status) == _TRUE) + { + rtw_msleep_os(30); + cnt++; + if(cnt > wait_for_surveydone ) + break; + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + if((stop - ev) < SCAN_ITEM_SIZE) { + ret = -E2BIG; + break; + } + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //report network only if the current channel set contains the channel to which this network belongs + if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 + && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE + && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) + ) + { + ev=translate_scan(padapter, a, pnetwork, ev, stop); + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + wrqu->data.length = ev-extra; + wrqu->data.flags = 0; + +exit: + + _func_exit_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + + return ret ; + +} + +//set ssid flow +//s1. rtw_set_802_11_infrastructure_mode() +//s2. set_802_11_authenticaion_mode() +//s3. set_802_11_encryption_mode() +//s4. rtw_set_802_11_ssid() +static int rtw_wx_set_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _irqL irqL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _queue *queue = &pmlmepriv->scanned_queue; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + _list *phead; + s8 status = _TRUE; + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + NDIS_802_11_SSID ndis_ssid; + u8 *dst_ssid, *src_ssid; + + uint ret = 0, len; + + _func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif + +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + printk("set ssid, but buddy_intf is under scanning or linking\n"); + + ret = -EINVAL; + + goto exit; + } +#endif + +#ifdef CONFIG_DUALMAC_CONCURRENT + if (dc_check_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)== _TRUE) + { + printk("set bssid, but buddy_intf is under scanning or linking\n"); + ret = -EINVAL; + goto exit; + } +#endif + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv))); + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret = -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + +#if WIRELESS_EXT <= 20 + if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){ +#else + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ +#endif + ret= -E2BIG; + goto exit; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + ret = -1; + goto exit; + } + + authmode = padapter->securitypriv.ndisauthtype; + DBG_871X("=>%s\n",__FUNCTION__); + if (wrqu->essid.flags && wrqu->essid.length) + { + // Commented by Albert 20100519 + // We got the codes in "set_info" function of iwconfig source code. + // ========================================= + // wrq.u.essid.length = strlen(essid) + 1; + // if(we_kernel_version > 20) + // wrq.u.essid.length--; + // ========================================= + // That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. +#if WIRELESS_EXT <= 20 + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; +#else + len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; +#endif + + if( wrqu->essid.length != 33 ) + DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length); + + _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); + ndis_ssid.SsidLength = len; + _rtw_memcpy(ndis_ssid.Ssid, extra, len); + src_ssid = ndis_ssid.Ssid; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid)); + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + pmlmepriv->pscanned = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) + { +#if 0 + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + rtw_set_802_11_ssid(padapter, &ndis_ssid); + + goto exit; + } + else + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n")); + ret = -EINVAL; + goto exit; + } +#endif + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_, + ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n")); + + break; + } + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + dst_ssid = pnetwork->network.Ssid.Ssid; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_wx_set_essid: dst_ssid=%s\n", + pnetwork->network.Ssid.Ssid)); + + if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) && + (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength)) + { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_wx_set_essid: find match, set infra mode\n")); + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) + continue; + } + + if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE) + { + ret = -1; + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + goto exit; + } + + break; + } + } + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("set ssid: set_802_11_auth. mode=%d\n", authmode)); + rtw_set_802_11_authentication_mode(padapter, authmode); + //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) { + ret = -1; + goto exit; + } + } + +exit: + + DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret); + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + + _func_exit_; + + return ret; +} + +static int rtw_wx_get_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + u32 len,ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n")); + + _func_enter_; + + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + len = pcur_bss->Ssid.SsidLength; + + wrqu->essid.length = len; + + _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len); + + wrqu->essid.flags = 1; + } + else + { + ret = -1; + goto exit; + } + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_set_rate(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + int i, ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 datarates[NumRates]; + u32 target_rate = wrqu->bitrate.value; + u32 fixed = wrqu->bitrate.fixed; + u32 ratevalue = 0; + u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n")); + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed)); + + if(target_rate == -1){ + ratevalue = 11; + goto set_rate; + } + target_rate = target_rate/100000; + + switch(target_rate){ + case 10: + ratevalue = 0; + break; + case 20: + ratevalue = 1; + break; + case 55: + ratevalue = 2; + break; + case 60: + ratevalue = 3; + break; + case 90: + ratevalue = 4; + break; + case 110: + ratevalue = 5; + break; + case 120: + ratevalue = 6; + break; + case 180: + ratevalue = 7; + break; + case 240: + ratevalue = 8; + break; + case 360: + ratevalue = 9; + break; + case 480: + ratevalue = 10; + break; + case 540: + ratevalue = 11; + break; + default: + ratevalue = 11; + break; + } + +set_rate: + + for(i=0; ibitrate.fixed = 0; /* no auto select */ + wrqu->bitrate.value = max_rate * 100000; + + return 0; +} + +static int rtw_wx_set_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + if (wrqu->rts.disabled) + padapter->registrypriv.rts_thresh = 2347; + else { + if (wrqu->rts.value < 0 || + wrqu->rts.value > 2347) + return -EINVAL; + + padapter->registrypriv.rts_thresh = wrqu->rts.value; + } + + DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh); + + _func_exit_; + + return 0; + +} + +static int rtw_wx_get_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh); + + wrqu->rts.value = padapter->registrypriv.rts_thresh; + wrqu->rts.fixed = 0; /* no auto select */ + //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); + + _func_exit_; + + return 0; +} + +static int rtw_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + if (wrqu->frag.disabled) + padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; + else { + if (wrqu->frag.value < MIN_FRAG_THRESHOLD || + wrqu->frag.value > MAX_FRAG_THRESHOLD) + return -EINVAL; + + padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; + } + + DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len); + + _func_exit_; + + return 0; + +} + +static int rtw_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len); + + wrqu->frag.value = padapter->xmitpriv.frag_len; + wrqu->frag.fixed = 0; /* no auto select */ + //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); + + _func_exit_; + + return 0; +} + +static int rtw_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + + wrqu->retry.value = 7; + wrqu->retry.fixed = 0; /* no auto select */ + wrqu->retry.disabled = 1; + + return 0; + +} + +#if 0 +#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ +#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ +#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ +#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ +#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ +#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ +#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ +/* +iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto +iwconfig wlan0 key off -> flags = 0x8800 +iwconfig wlan0 key open -> flags = 0x2800 +iwconfig wlan0 key open 1234567890 -> flags = 0x2000 +iwconfig wlan0 key restricted -> flags = 0x4800 +iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003 +iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002 +iwconfig wlan0 key open [3] -> flags = 0x2803 +iwconfig wlan0 key restricted [2] -> flags = 0x4802 +*/ +#endif + +static int rtw_wx_set_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + u32 key, ret = 0; + u32 keyindex_provided; + NDIS_802_11_WEP wep; + NDIS_802_11_AUTHENTICATION_MODE authmode; + + struct iw_point *erq = &(wrqu->encoding); + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags); + + _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP)); + + key = erq->flags & IW_ENCODE_INDEX; + + _func_enter_; + + if (erq->flags & IW_ENCODE_DISABLED) + { + DBG_871X("EncryptionDisabled\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + + goto exit; + } + + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + keyindex_provided = 1; + } + else + { + keyindex_provided = 0; + key = padapter->securitypriv.dot11PrivacyKeyIndex; + DBG_871X("rtw_wx_set_enc, key=%d\n", key); + } + + //set authentication mode + if(erq->flags & IW_ENCODE_OPEN) + { + DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; +#endif + + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + } + else if(erq->flags & IW_ENCODE_RESTRICTED) + { + DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared; +#endif + + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + authmode = Ndis802_11AuthModeShared; + padapter->securitypriv.ndisauthtype=authmode; + } + else + { + DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags); + + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + } + + wep.KeyIndex = key; + if (erq->length > 0) + { + wep.KeyLength = erq->length <= 5 ? 5 : 13; + + wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + } + else + { + wep.KeyLength = 0 ; + + if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0). + { + padapter->securitypriv.dot11PrivacyKeyIndex = key; + + DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]); + + switch(padapter->securitypriv.dot11DefKeylen[key]) + { + case 5: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + break; + case 13: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + break; + default: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + break; + } + + goto exit; + + } + + } + + wep.KeyIndex |= 0x80000000; + + _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); + + if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) { + if(rf_on == pwrpriv->rf_pwrstate ) + ret = -EOPNOTSUPP; + goto exit; + } + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + uint key, ret =0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *erq = &(wrqu->encoding); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + _func_enter_; + + if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + { + if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) + { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + return 0; + } + } + + + key = erq->flags & IW_ENCODE_INDEX; + + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + } else + { + key = padapter->securitypriv.dot11PrivacyKeyIndex; + } + + erq->flags = key + 1; + + //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) + //{ + // erq->flags |= IW_ENCODE_OPEN; + //} + + switch(padapter->securitypriv.ndisencryptstatus) + { + case Ndis802_11EncryptionNotSupported: + case Ndis802_11EncryptionDisabled: + + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + + break; + + case Ndis802_11Encryption1Enabled: + + erq->length = padapter->securitypriv.dot11DefKeylen[key]; + + if(erq->length) + { + _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); + + erq->flags |= IW_ENCODE_ENABLED; + + if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) + { + erq->flags |= IW_ENCODE_OPEN; + } + else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) + { + erq->flags |= IW_ENCODE_RESTRICTED; + } + } + else + { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + } + + break; + + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + + erq->length = 16; + erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); + + break; + + default: + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + + break; + + } + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + wrqu->power.value = 0; + wrqu->power.fixed = 0; /* no auto select */ + wrqu->power.disabled = 1; + + return 0; + +} + +static int rtw_wx_set_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length); + + return ret; +} + +static int rtw_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_param *param = (struct iw_param*)&(wrqu->param); + int ret = 0; + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + break; + case IW_AUTH_CIPHER_PAIRWISE: + + break; + case IW_AUTH_CIPHER_GROUP: + + break; + case IW_AUTH_KEY_MGMT: + /* + * ??? does not use these parameters + */ + break; + + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if ( param->value ) + { // wpa_supplicant is enabling the tkip countermeasure. + padapter->securitypriv.btkip_countermeasure = _TRUE; + } + else + { // wpa_supplicant is disabling the tkip countermeasure. + padapter->securitypriv.btkip_countermeasure = _FALSE; + } + break; + } + case IW_AUTH_DROP_UNENCRYPTED: + { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + + if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) + { + break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, + // then it needn't reset it; + } + + if(param->value){ + padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen; + } + + break; + } + + case IW_AUTH_80211_AUTH_ALG: + + #if defined(CONFIG_ANDROID) || 1 + /* + * It's the starting point of a link layer connection using wpa_supplicant + */ + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + } + #endif + + + ret = wpa_set_auth_algs(dev, (u32)param->value); + + break; + + case IW_AUTH_WPA_ENABLED: + + //if(param->value) + // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x + //else + // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system + + //_disassociate(priv); + + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + //ieee->ieee802_1x = param->value; + break; + + case IW_AUTH_PRIVACY_INVOKED: + //ieee->privacy_invoked = param->value; + break; + + default: + return -EOPNOTSUPP; + + } + + return ret; + +} + +static int rtw_wx_set_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + char *alg_name; + u32 param_len; + struct ieee_param *param = NULL; + struct iw_point *pencoding = &wrqu->encoding; + struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; + int ret=0; + + param_len = sizeof(struct ieee_param) + pext->key_len; + param = (struct ieee_param *)rtw_malloc(param_len); + if (param == NULL) + return -1; + + _rtw_memset(param, 0, param_len); + + param->cmd = IEEE_CMD_SET_ENCRYPTION; + _rtw_memset(param->sta_addr, 0xff, ETH_ALEN); + + + switch (pext->alg) { + case IW_ENCODE_ALG_NONE: + //todo: remove key + //remove = 1; + alg_name = "none"; + break; + case IW_ENCODE_ALG_WEP: + alg_name = "WEP"; + break; + case IW_ENCODE_ALG_TKIP: + alg_name = "TKIP"; + break; + case IW_ENCODE_ALG_CCMP: + alg_name = "CCMP"; + break; +#ifdef CONFIG_IEEE80211W + case IW_ENCODE_ALG_AES_CMAC: + alg_name = "BIP"; + break; +#endif //CONFIG_IEEE80211W + default: + return -1; + } + + strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); + + + if((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)//? +#ifdef CONFIG_IEEE80211W + || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC) +#endif //CONFIG_IEEE80211W + ) + { + param->u.crypt.set_tx = 0; + } + + if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)//? + { + param->u.crypt.set_tx = 1; + } + + param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ; + + if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) + { + _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8); + } + + if(pext->key_len) + { + param->u.crypt.key_len = pext->key_len; + //_rtw_memcpy(param + 1, pext + 1, pext->key_len); + _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len); + } + + + if (pencoding->flags & IW_ENCODE_DISABLED) + { + //todo: remove key + //remove = 1; + } + + ret = wpa_set_encryption(dev, param, param_len); + + + if(param) + { + rtw_mfree((u8*)param, param_len); + } + + + return ret; + +} + + +static int rtw_wx_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + //struct security_priv *psecuritypriv = &padapter->securitypriv; + + if(extra) + { + wrqu->data.length = 14; + wrqu->data.flags = 1; + _rtw_memcpy(extra, "", 14); + } + + //rtw_signal_process(pid, SIGUSR1); //for test + + //dump debug info here +/* + u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, and 8021x + u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm. + u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key + u32 ndisauthtype; + u32 ndisencryptstatus; +*/ + + //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + // psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, + // psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); + + //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); + //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype); + //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); + +#if 0 + DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210)); + DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608)); + DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280)); + DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284)); + DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288)); + + DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664)); + + + DBG_871X("\n"); + + DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430)); + DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438)); + + DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440)); + + DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458)); + + DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484)); + DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488)); + + DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444)); + DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448)); + DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c)); + DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450)); +#endif + + return 0; + +} + +static int rtw_wx_read32(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter; + struct iw_point *p; + u16 len; + u32 addr; + u32 data32; + u32 bytes; + u8 *ptmp; + + + padapter = (PADAPTER)rtw_netdev_priv(dev); + p = &wrqu->data; + len = p->length; + ptmp = (u8*)rtw_malloc(len); + if (NULL == ptmp) + return -ENOMEM; + + if (copy_from_user(ptmp, p->pointer, len)) { + rtw_mfree(ptmp, len); + return -EFAULT; + } + + bytes = 0; + addr = 0; + sscanf(ptmp, "%d,%x", &bytes, &addr); + + switch (bytes) { + case 1: + data32 = rtw_read8(padapter, addr); + sprintf(extra, "0x%02X", data32); + break; + case 2: + data32 = rtw_read16(padapter, addr); + sprintf(extra, "0x%04X", data32); + break; + case 4: + data32 = rtw_read32(padapter, addr); + sprintf(extra, "0x%08X", data32); + break; + default: + printk(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__); + return -EINVAL; + } + printk(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra); + + rtw_mfree(ptmp, len); + + return 0; +} + +static int rtw_wx_write32(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + + u32 addr; + u32 data32; + u32 bytes; + + + bytes = 0; + addr = 0; + data32 = 0; + sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); + + switch (bytes) { + case 1: + rtw_write8(padapter, addr, (u8)data32); + printk(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32); + break; + case 2: + rtw_write16(padapter, addr, (u16)data32); + printk(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32); + break; + case 4: + rtw_write32(padapter, addr, data32); + printk(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32); + break; + default: + printk(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int rtw_wx_read_rf(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u32 path, addr, data32; + + + path = *(u32*)extra; + addr = *((u32*)extra + 1); + data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF); +// DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); + /* + * IMPORTANT!! + * Only when wireless private ioctl is at odd order, + * "extra" would be copied to user space. + */ + sprintf(extra, "0x%05x", data32); + + return 0; +} + +static int rtw_wx_write_rf(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u32 path, addr, data32; + + + path = *(u32*)extra; + addr = *((u32*)extra + 1); + data32 = *((u32*)extra + 2); +// DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); + rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32); + + return 0; +} + +static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + return -1; +} + +static int dummy(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); + + return -1; + +} + +static int rtw_wx_set_channel_plan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + extern int rtw_channel_plan; + u8 channel_plan_req = (u8) (*((int *)wrqu)); + + #if 0 + rtw_channel_plan = (int)wrqu->data.pointer; + pregistrypriv->channel_plan = rtw_channel_plan; + pmlmepriv->ChannelPlan = pregistrypriv->channel_plan; + #endif + + if( _SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1) ) { + DBG_871X("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan); + } else + return -EPERM; + + return 0; +} + +static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, + ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n", + a->cmd, get_fwstate(pmlmepriv))); +#endif + return 0; +} + +static int rtw_wx_get_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *buf) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + // Modified by Albert 20110914 + // This is in dbm format for MTK platform. + wrqu->qual.level = padapter->recvpriv.rssi; + DBG_871X(" level = %u\n", wrqu->qual.level ); +#endif + return 0; +} + +static int rtw_wx_set_mtk_wps_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length); +#else + return 0; +#endif +} + +/* +typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +*/ +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + #if 0 +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + #endif + +#ifdef CONFIG_DRVEXT_MODULE + u8 res; + struct drvext_handler *phandler; + struct drvext_oidparam *poidparam; + int ret; + u16 len; + u8 *pparmbuf, bset; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *p = &wrqu->data; + + if( (!p->length) || (!p->pointer)){ + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + bset = (u8)(p->flags&0xFFFF); + len = p->length; + pparmbuf = (u8*)rtw_malloc(len); + if (pparmbuf == NULL){ + ret = -ENOMEM; + goto _rtw_drvext_hdl_exit; + } + + if(bset)//set info + { + if (copy_from_user(pparmbuf, p->pointer,len)) { + rtw_mfree(pparmbuf, len); + ret = -EFAULT; + goto _rtw_drvext_hdl_exit; + } + } + else//query info + { + + } + + + // + poidparam = (struct drvext_oidparam *)pparmbuf; + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n", + poidparam->subcode, poidparam->len, len)); + + + //check subcode + if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n")); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n")); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + phandler = drvextoidhandlers + poidparam->subcode; + + if (poidparam->len != phandler->parmsize) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n", + poidparam->len , phandler->parmsize)); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data); + + if(res==0) + { + ret = 0; + + if (bset == 0x00) {//query info + //_rtw_memcpy(p->pointer, pparmbuf, len); + if (copy_to_user(p->pointer, pparmbuf, len)) + ret = -EFAULT; + } + } + else + ret = -EFAULT; + + +_rtw_drvext_hdl_exit: + + return ret; + +#endif + + return 0; + +} + +static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len) +{ + pRW_Reg RegRWStruct; + struct rf_reg_param *prfreg; + u8 path; + u8 offset; + u32 value; + + DBG_871X("%s\n", __FUNCTION__); + + switch(id) + { + case GEN_MP_IOCTL_SUBCODE(MP_START): + DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n"); + break; + case GEN_MP_IOCTL_SUBCODE(READ_REG): + RegRWStruct = (pRW_Reg)pdata; + switch (RegRWStruct->width) + { + case 1: + RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset); + break; + case 2: + RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset); + break; + case 4: + RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset); + break; + default: + break; + } + + break; + case GEN_MP_IOCTL_SUBCODE(WRITE_REG): + RegRWStruct = (pRW_Reg)pdata; + switch (RegRWStruct->width) + { + case 1: + rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value); + break; + case 2: + rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value); + break; + case 4: + rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value); + break; + default: + break; + } + + break; + case GEN_MP_IOCTL_SUBCODE(READ_RF_REG): + + prfreg = (struct rf_reg_param *)pdata; + + path = (u8)prfreg->path; + offset = (u8)prfreg->offset; + + value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff); + + prfreg->value = value; + + break; + case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG): + + prfreg = (struct rf_reg_param *)pdata; + + path = (u8)prfreg->path; + offset = (u8)prfreg->offset; + value = prfreg->value; + + rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value); + + break; + case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO): + DBG_871X("==> trigger gpio 0\n"); + rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0); + break; +#ifdef CONFIG_BT_COEXIST + case GEN_MP_IOCTL_SUBCODE(SET_DM_BT): + DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata); + rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata); + break; + case GEN_MP_IOCTL_SUBCODE(DEL_BA): + DBG_871X("==> delete ba:%x\n",*(u8 *)pdata); + rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata); + break; +#endif +#ifdef DBG_CONFIG_ERROR_DETECT + case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS): + *pdata = rtw_hal_sreset_get_wifi_status(padapter); + break; +#endif + + default: + break; + } + +} + +static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + u32 BytesRead, BytesWritten, BytesNeeded; + struct oid_par_priv oid_par; + struct mp_ioctl_handler *phandler; + struct mp_ioctl_param *poidparam; + uint status=0; + u16 len; + u8 *pparmbuf = NULL, bset; + PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + struct iw_point *p = &wrqu->data; + + //DBG_871X("+rtw_mp_ioctl_hdl\n"); + + //mutex_lock(&ioctl_mutex); + + if ((!p->length) || (!p->pointer)) { + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + pparmbuf = NULL; + bset = (u8)(p->flags & 0xFFFF); + len = p->length; + pparmbuf = (u8*)rtw_malloc(len); + if (pparmbuf == NULL){ + ret = -ENOMEM; + goto _rtw_mp_ioctl_hdl_exit; + } + + if (copy_from_user(pparmbuf, p->pointer, len)) { + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } + + poidparam = (struct mp_ioctl_param *)pparmbuf; + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n", + poidparam->subcode, poidparam->len, len)); + + if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n")); + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + //DBG_871X("%s: %d\n", __func__, poidparam->subcode); + +#ifdef CONFIG_MP_INCLUDED + phandler = mp_ioctl_hdl + poidparam->subcode; + + if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) + { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, + ("no matching drvext param size %d vs %d\r\n", + poidparam->len, phandler->paramsize)); + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + if (phandler->handler) + { + oid_par.adapter_context = padapter; + oid_par.oid = phandler->oid; + oid_par.information_buf = poidparam->data; + oid_par.information_buf_len = poidparam->len; + oid_par.dbg = 0; + + BytesWritten = 0; + BytesNeeded = 0; + + if (bset) { + oid_par.bytes_rw = &BytesRead; + oid_par.bytes_needed = &BytesNeeded; + oid_par.type_of_oid = SET_OID; + } else { + oid_par.bytes_rw = &BytesWritten; + oid_par.bytes_needed = &BytesNeeded; + oid_par.type_of_oid = QUERY_OID; + } + + status = phandler->handler(&oid_par); + + //todo:check status, BytesNeeded, etc. + } + else { + DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n", + poidparam->subcode, phandler->oid, phandler->handler); + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } +#else + + rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len); + +#endif + + if (bset == 0x00) {//query info + if (copy_to_user(p->pointer, pparmbuf, len)) + ret = -EFAULT; + } + + if (status) { + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } + +_rtw_mp_ioctl_hdl_exit: + + if (pparmbuf) + rtw_mfree(pparmbuf, len); + + //mutex_unlock(&ioctl_mutex); + + return ret; +} + +static int rtw_get_ap_info(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int bssid_match, ret = 0; + u32 cnt=0, wpa_ielen; + _irqL irqL; + _list *plist, *phead; + unsigned char *pbuf; + u8 bssid[ETH_ALEN]; + char data[32]; + struct wlan_network *pnetwork = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct iw_point *pdata = &wrqu->data; + + DBG_871X("+rtw_get_aplist_info\n"); + + if((padapter->bDriverStopped) || (pdata==NULL)) + { + ret= -EINVAL; + goto exit; + } + + while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE) + { + rtw_msleep_os(30); + cnt++; + if(cnt > 100) + break; + } + + + //pdata->length = 0;//? + pdata->flags = 0; + if(pdata->length>=32) + { + if(copy_from_user(data, pdata->pointer, 32)) + { + ret= -EINVAL; + goto exit; + } + } + else + { + ret= -EINVAL; + goto exit; + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //if(hwaddr_aton_i(pdata->pointer, bssid)) + if(hwaddr_aton_i(data, bssid)) + { + DBG_871X("Invalid BSSID '%s'.\n", (u8*)data); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return -EINVAL; + } + + + if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2 + { + DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid)); + + pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + if(pbuf && (wpa_ielen>0)) + { + pdata->flags = 1; + break; + } + + pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + if(pbuf && (wpa_ielen>0)) + { + pdata->flags = 2; + break; + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if(pdata->length>=34) + { + if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1)) + { + ret= -EINVAL; + goto exit; + } + } + +exit: + + return ret; + +} + +static int rtw_set_pid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = rtw_netdev_priv(dev); + int *pdata = (int *)wrqu; + int selector; + + if((padapter->bDriverStopped) || (pdata==NULL)) + { + ret= -EINVAL; + goto exit; + } + + selector = *pdata; + if(selector < 3 && selector >=0) { + padapter->pid[selector] = *(pdata+1); + #ifdef CONFIG_GLOBAL_UI_PID + ui_pid[selector] = *(pdata+1); + #endif + DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]); + } + else + DBG_871X("%s selector %d error\n", __FUNCTION__, selector); + +exit: + + return ret; + +} + +static int rtw_wps_start(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + u32 u32wps_start = 0; + unsigned int uintRet = 0; + + uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 ); + + if((padapter->bDriverStopped) || (pdata==NULL)) + { + ret= -EINVAL; + goto exit; + } + + if ( u32wps_start == 0 ) + { + u32wps_start = *extra; + } + + DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start ); + + if ( u32wps_start == 1 ) // WPS Start + { + rtw_led_control(padapter, LED_CTL_START_WPS); + } + else if ( u32wps_start == 2 ) // WPS Stop because of wps success + { + rtw_led_control(padapter, LED_CTL_STOP_WPS); + } + else if ( u32wps_start == 3 ) // WPS Stop because of wps fail + { + rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL); + } + +#ifdef CONFIG_INTEL_WIDI + process_intel_widi_wps_status(padapter, u32wps_start); +#endif //CONFIG_INTEL_WIDI + +exit: + + return ret; + +} + +#ifdef CONFIG_P2P +static int rtw_wext_p2p_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + enum P2P_ROLE init_role = P2P_ROLE_DISABLE; + + if(*extra == '0' ) + init_role = P2P_ROLE_DISABLE; + else if(*extra == '1') + init_role = P2P_ROLE_DEVICE; + else if(*extra == '2') + init_role = P2P_ROLE_CLIENT; + else if(*extra == '3') + init_role = P2P_ROLE_GO; + + if(_FAIL == rtw_p2p_enable(padapter, init_role)) + { + ret = -EFAULT; + goto exit; + } + + //set channel/bandwidth + if(init_role != P2P_ROLE_DISABLE) + { + u8 channel, ch_offset; + u16 bwmode; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) + { + // Stay at the listen state and wait for discovery. + channel = pwdinfo->listen_channel; + pwdinfo->operating_channel = pwdinfo->listen_channel; + ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + bwmode = HT_CHANNEL_WIDTH_20; + } +#ifdef CONFIG_CONCURRENT_MODE + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + _adapter *pbuddy_adapter = padapter->pbuddy_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; + + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel; + // How about the ch_offset and bwmode ?? + } + else + { + pwdinfo->operating_channel = pwdinfo->listen_channel; + } + + channel = pbuddy_mlmeext->cur_channel; + ch_offset = pbuddy_mlmeext->cur_ch_offset; + bwmode = pbuddy_mlmeext->cur_bwmode; + } +#endif + else + { + pwdinfo->operating_channel = pmlmeext->cur_channel; + + channel = pwdinfo->operating_channel; + ch_offset = pmlmeext->cur_ch_offset; + bwmode = pmlmeext->cur_bwmode; + } + + set_channel_bwmode(padapter, channel, ch_offset, bwmode); + } + +exit: + return ret; + +} + +static int rtw_p2p_set_go_nego_ssid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + DBG_871X( "[%s] ssid = %s, len = %d\n", __FUNCTION__, extra, (u32)strlen( extra ) ); + _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) ); + pwdinfo->nego_ssidlen = strlen( extra ); + + return ret; + +} + + +static int rtw_p2p_set_intent(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 intent = pwdinfo->intent; + + extra[ wrqu->data.length ] = 0x00; + + intent = rtw_atoi( extra ); + + if ( intent <= 15 ) + { + pwdinfo->intent= intent; + } + else + { + ret = -1; + } + + DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent); + + return ret; + +} + +static int rtw_p2p_set_listen_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 listen_ch = pwdinfo->listen_channel; // Listen channel number + + extra[ wrqu->data.length ] = 0x00; + listen_ch = rtw_atoi( extra ); + + if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) ) + { + pwdinfo->listen_channel = listen_ch; + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } + else + { + ret = -1; + } + + DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel ); + + return ret; + +} + +static int rtw_p2p_set_op_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Albert 20110524 +// This function is used to set the operating channel if the driver will become the group owner + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 op_ch = pwdinfo->operating_channel; // Operating channel number + + extra[ wrqu->data.length ] = 0x00; + + op_ch = ( u8 ) rtw_atoi( extra ); + if ( op_ch > 0 ) + { + pwdinfo->operating_channel = op_ch; + } + else + { + ret = -1; + } + + DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel ); + + return ret; + +} + + +static int rtw_p2p_profilefound(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + // Comment by Albert 2010/10/13 + // Input data format: + // Ex: 0 + // Ex: 1XX:XX:XX:XX:XX:XXYYSSID + // 0 => Reflush the profile record list. + // 1 => Add the profile list + // XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) + // YY => SSID Length + // SSID => SSID for persistence group + + DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1); + + + // The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + if ( extra[ 0 ] == '0' ) + { + // Remove all the profile information of wifidirect_info structure. + _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM ); + pwdinfo->profileindex = 0; + } + else + { + if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM ) + { + ret = -1; + } + else + { + int jj, kk; + + // Add this profile information into pwdinfo->profileinfo + // Ex: 1XX:XX:XX:XX:XX:XXYYSSID + for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 ) + { + pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]); + } + + //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' ); + //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen ); + pwdinfo->profileindex++; + } + } + } + + return ret; + +} + +static int rtw_p2p_setDN(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN ); + _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 ); + pwdinfo->device_name_len = wrqu->data.length - 1; + return ret; + +} + + +static int rtw_p2p_get_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + if ( padapter->bShowGetP2PState ) + { + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + } + + // Commented by Albert 2010/10/12 + // Because of the output size limitation, I had removed the "Role" information. + // About the "Role" information, we will use the new private IOCTL to get the "Role" information. + sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) ); + wrqu->data.length = strlen( extra ); + + return ret; + +} + +// Commented by Albert 20110520 +// This function will return the config method description +// This config method description will show us which config method the remote P2P device is intented to use +// by sending the provisioning discovery request frame. + +static int rtw_p2p_get_req_cm(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req ); + wrqu->data.length = strlen( extra ); + return ret; + +} + + +static int rtw_p2p_get_role(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + + sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) ); + wrqu->data.length = strlen( extra ); + return ret; + +} + + +static int rtw_p2p_get_peer_ifaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + + sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_devaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]); + sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X", + pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], + pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ], + pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]); + sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], + pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ], + pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_groupid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s", + pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ], + pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ], + pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ], + pwdinfo->groupid_info.ssid); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_op_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel); + + sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel ); + wrqu->data.length = strlen( extra ); + return ret; + +} + +inline static void macstr2num(u8 *dst, u8 *src) +{ + int jj, kk; + for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) + { + dst[jj] = key_2char2num(src[kk], src[kk + 1]); + } +} + +static int rtw_p2p_get_wps_configmethod(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list * plist,*phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u16 attr_content = 0; + uint attr_contentlen = 0; + u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20110727 + // The input data is the MAC address which the application wants to know its WPS config method. + // After knowing its WPS config method, the application can decide the config method for provisioning discovery. + // Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen); + if (attr_contentlen) + { + attr_content = be16_to_cpu(attr_content); + sprintf(attr_content_str, "\n\nM=%.4d", attr_content); + blnMatch = 1; + } + } + + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(attr_content_str, "\n\nM=0000"); + } + + wrqu->data.length = strlen(attr_content_str); + _rtw_memcpy(extra, attr_content_str, wrqu->data.length); + + return ret; + +} + +#ifdef CONFIG_WFD +static int rtw_p2p_get_peer_wfd_port(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + + sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport ); + DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc ); + DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc ); + + wrqu->data.length = strlen( extra ); + pwdinfo->wfd_info->wfd_pc = _FALSE; // Reset the WFD preferred connection to P2P + return ret; + +} + +static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail ); + DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail ); + + wrqu->data.length = strlen( extra ); + pwdinfo->wfd_info->peer_session_avail = _TRUE; // Reset the WFD session available + return ret; + +} + +#endif // CONFIG_WFD + +static int rtw_p2p_get_go_device_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + u8 attr_content[100] = { 0x00 }; + u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20121209 + // The input data is the GO's interface address which the application wants to know its device address. + // Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))) + { + while (p2pie) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + _rtw_memset(attr_content, 0x00, 100); + if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) + { + // Handle the P2P Device ID attribute of Beacon first + blnMatch = 1; + break; + + } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) + { + // Handle the P2P Device Info attribute of probe response + blnMatch = 1; + break; + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); + } + } + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(go_devadd_str, "\n\ndev_add=NULL"); + } else + { + sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); + } + + wrqu->data.length = strlen(go_devadd_str); + _rtw_memcpy(extra, go_devadd_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_device_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 dev_type[8] = { 0x00 }; + uint dev_type_len = 0; + u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; // +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer + + // Commented by Albert 20121209 + // The input data is the MAC address which the application wants to know its device type. + // Such user interface could know the device type. + // Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len); + if (dev_type_len) + { + u16 type = 0; + + _rtw_memcpy(&type, dev_type, 2); + type = be16_to_cpu(type); + sprintf(dev_type_str, "\n\nN=%.2d", type); + blnMatch = 1; + } + } + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(dev_type_str, "\n\nN=00"); + } + + wrqu->data.length = strlen(dev_type_str); + _rtw_memcpy(extra, dev_type_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_device_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 }; + uint dev_len = 0; + u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20121225 + // The input data is the MAC address which the application wants to know its device name. + // Such user interface could show peer device's device name instead of ssid. + // Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ((wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len))) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); + if (dev_len) + { + sprintf(dev_name_str, "\n\nN=%s", dev_name); + blnMatch = 1; + } + } + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(dev_name_str, "\n\nN=0000"); + } + + wrqu->data.length = strlen(dev_name_str); + _rtw_memcpy(extra, dev_name_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_invitation_procedure(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + u8 attr_content[2] = { 0x00 }; + u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Ouden 20121226 + // The application wants to know P2P initation procedure is support or not. + // Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + // Commented by Albert 20121226 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + if ((p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))) + { + while (p2pie) + { + //_rtw_memset( attr_content, 0x00, 2); + if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) + { + // Handle the P2P capability attribute + blnMatch = 1; + break; + + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen); + } + } + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(inv_proc_str, "\nIP=-1"); + } else + { + if (attr_content[0] && 0x20) + { + sprintf(inv_proc_str, "\nIP=1"); + } else + { + sprintf(inv_proc_str, "\nIP=0"); + } + } + + wrqu->data.length = strlen(inv_proc_str); + _rtw_memcpy(extra, inv_proc_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_connect(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + + // Commented by Albert 20110304 + // The input data contains two informations. + // 1. First information is the MAC address which wants to formate with + // 2. Second information is the WPS PINCode or "pbc" string for push button method + // Format: 00:E0:4C:00:00:05 + // Format: 00:E0:4C:00:00:05 + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + + if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO ) + { + return -1; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if ( uintPeerChannel ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) ); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); + + pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel; + _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN ); + pwdinfo->nego_req_info.benable = _TRUE; + + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK ) + { + // Restore to the listen state if the current p2p state is not nego OK + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN ); + } + + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } +#endif // CONFIG_CONCURRENT_MODE + + DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ ); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + } + else + { + DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ ); + ret = -1; + } +exit: + return ret; +} + +static int rtw_p2p_invite_req(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_WFD + struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; +#endif // CONFIG_WFD + + // Commented by Albert 20120321 + // The input data contains two informations. + // 1. First information is the P2P device address which you want to send to. + // 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. + // Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" + // Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( wrqu->data.length <= 37 ) + { + DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ ); + return ret; + } + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + // Reset the content of struct tx_invite_req_info + pinvite_req_info->benable = _FALSE; + _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN ); + _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN ); + pinvite_req_info->ssidlen = 0x00; + pinvite_req_info->operating_ch = pwdinfo->operating_channel; + _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN ); + pinvite_req_info->token = 3; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +#ifdef CONFIG_WFD + if ( uintPeerChannel ) + { + u8 wfd_ie[ 128 ] = { 0x00 }; + uint wfd_ielen = 0; + + if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + { + u8 wfd_devinfo[ 6 ] = { 0x00 }; + uint wfd_devlen = 6; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) ) + { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) + { + pwfd_info->peer_session_avail = _TRUE; + } + else + { + pwfd_info->peer_session_avail = _FALSE; + } + } + } + + if ( _FALSE == pwfd_info->peer_session_avail ) + { + DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); + goto exit; + } + } +#endif // CONFIG_WFD + + if ( uintPeerChannel ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + // Store the GO's bssid + for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 ) + { + pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + // Store the GO's ssid + pinvite_req_info->ssidlen = wrqu->data.length - 36; + _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen ); + pinvite_req_info->benable = _TRUE; + pinvite_req_info->peer_ch = uintPeerChannel; + + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } + else + { + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } +#else + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); +#endif + + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); + } +exit: + + return ret; + +} + +static int rtw_p2p_set_persistent(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_WFD + struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; +#endif // CONFIG_WFD + + // Commented by Albert 20120328 + // The input data is 0 or 1 + // 0: disable persistent group functionality + // 1: enable persistent group founctionality + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + if ( extra[ 0 ] == '0' ) // Disable the persistent group function. + { + pwdinfo->persistent_supported = _FALSE; + } + else if ( extra[ 0 ] == '1' ) // Enable the persistent group function. + { + pwdinfo->persistent_supported = _TRUE; + } + else + { + pwdinfo->persistent_supported = _FALSE; + } + } + printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported ); + +exit: + + return ret; + +} + +static int hexstr2bin(const char *hex, u8 *buf, size_t len) +{ + size_t i; + int a; + const char *ipos = hex; + u8 *opos = buf; + + for (i = 0; i < len; i++) { + a = hex2byte_i(ipos); + if (a < 0) + return -1; + *opos++ = a; + ipos += 2; + } + return 0; +} + +static int uuid_str2bin(const char *str, u8 *bin) +{ + const char *pos; + u8 *opos; + + pos = str; + opos = bin; + + if (hexstr2bin(pos, opos, 4)) + return -1; + pos += 8; + opos += 4; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 6)) + return -1; + + return 0; +} + +static int rtw_p2p_set_wps_uuid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + + DBG_871X("[%s] data = %s\n", __FUNCTION__, extra); + + if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0)) + { + pwdinfo->external_uuid = 1; + } else { + pwdinfo->external_uuid = 0; + ret = -EINVAL; + } + + return ret; + +} +#ifdef CONFIG_WFD +static int rtw_p2p_set_pc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; + + // Commented by Albert 20120512 + // 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) + // Format: 00:E0:4C:00:00:05 + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen)) ) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + printk( "[%s] Got P2P IE\n", __FUNCTION__ ); + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ ); + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ ); + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel ); + + if ( uintPeerChannel ) + { + u8 wfd_ie[ 128 ] = { 0x00 }; + uint wfd_ielen = 0; + + if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + { + u8 wfd_devinfo[ 6 ] = { 0x00 }; + uint wfd_devlen = 6; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) ) + { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS ) + { + pwfd_info->wfd_pc = _TRUE; + } + else + { + pwfd_info->wfd_pc = _FALSE; + } + } + } + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); + } + +exit: + + return ret; + +} + +static int rtw_p2p_set_wfd_device_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + + // Commented by Albert 20120328 + // The input data is 0 or 1 + // 0: specify to Miracast source device + // 1 or others: specify to Miracast sink device (display device) + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( extra[ 0 ] == '0' ) // Set to Miracast source device. + { + pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE; + } + else // Set to Miracast sink device. + { + pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK; + } + +exit: + + return ret; + +} + +static int rtw_p2p_set_scan_result_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + + // Commented by Albert 20120328 + // The input data is 0 , 1 , 2 + // 0: when the P2P is enabled, the scan result will return all the found P2P device. + // 1: when the P2P is enabled, the scan result will return all the found P2P device and AP. + // 2: when the P2P is enabled, the scan result will show up the found Miracast devices base on... + // It will show up all the Miracast source device if this device is sink. + // It will show up all the Miracast sink device if this device is source. + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( extra[ 0 ] == '0' ) + { + pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY; + } + else if ( extra[ 0 ] == '1' ) + { + pwfd_info->scan_result_type = SCAN_RESULT_ALL; + } + else if ( extra[ 0 ] == '2' ) + { + pwfd_info->scan_result_type = SCAN_RESULT_WFD_TYPE; + } + else + { + pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY; + } + +exit: + + return ret; + +} + +static int rtw_p2p_set_wfd_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set wfd enabled + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if(*extra == '0' ) + pwdinfo->wfd_info->wfd_enable = _FALSE; + else if(*extra == '1') + pwdinfo->wfd_info->wfd_enable = _TRUE; + + DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable ); + + return ret; + +} + +static int rtw_p2p_set_driver_iface(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set driver iface is WEXT or CFG80211 + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if(*extra == '1' ) + { + pwdinfo->driver_interface = DRIVER_WEXT; + DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__); + } + else if(*extra == '2') + { + pwdinfo->driver_interface = DRIVER_CFG80211; + DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__); + } + + return ret; + +} + +// To set the WFD session available to enable or disable +static int rtw_p2p_set_sa(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if( 0 ) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + if ( extra[ 0 ] == '0' ) // Disable the session available. + { + pwdinfo->session_available = _FALSE; + } + else if ( extra[ 0 ] == '1' ) // Enable the session available. + { + pwdinfo->session_available = _TRUE; + } + else + { + pwdinfo->session_available = _FALSE; + } + } + printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available ); + +exit: + + return ret; + +} +#endif //CONFIG_WFD + +static int rtw_p2p_prov_disc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[100] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + u8 ie_offset; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_WFD + struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; +#endif // CONFIG_WFD + + // Commented by Albert 20110301 + // The input data contains two informations. + // 1. First information is the MAC address which wants to issue the provisioning discovery request frame. + // 2. Second information is the WPS configuration method which wants to discovery + // Format: 00:E0:4C:00:00:05_display + // Format: 00:E0:4C:00:00:05_keypad + // Format: 00:E0:4C:00:00:05_pbc + // Format: 00:E0:4C:00:00:05_label + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { +#ifdef CONFIG_INTEL_WIDI + if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE){ + DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ ); + return ret; + } +#endif //CONFIG_INTEL_WIDI + + // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. + _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN ); + _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN ); + _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) ); + pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0; + pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0; + pwdinfo->tx_prov_disc_info.benable = _FALSE; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; + } + else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; + } + else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + } + else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; + } + else + { + DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ ); + return( ret ); + } + + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + if( uintPeerChannel != 0 ) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + if (pnetwork->network.Reserved[0] == 2) { // Probe Request + ie_offset = 0; + } else { // Beacon or Probe Respones + ie_offset = 12; + } + if ( (p2pie=rtw_get_p2p_ie( &pnetwork->network.IEs[ie_offset], pnetwork->network.IELength - ie_offset, NULL, &p2pielen)) ) + { + while ( p2pie ) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - ie_offset -(p2pie -&pnetwork->network.IEs[ie_offset] + p2pielen), NULL, &p2pielen); + } + } + +#ifdef CONFIG_INTEL_WIDI + // Some Intel WiDi source may not provide P2P IE, + // so we could only compare mac addr by 802.11 Source Address + if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION + && uintPeerChannel == 0 ) + { + if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } +#endif //CONFIG_INTEL_WIDI + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if ( uintPeerChannel ) + { +#ifdef CONFIG_WFD + { + u8 wfd_ie[ 128 ] = { 0x00 }; + uint wfd_ielen = 0; + + if ( rtw_get_wfd_ie( &pnetwork->network.IEs[12], pnetwork->network.IELength - 12, wfd_ie, &wfd_ielen ) ) + { + u8 wfd_devinfo[ 6 ] = { 0x00 }; + uint wfd_devlen = 6; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + if ( rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, wfd_devinfo, &wfd_devlen ) ) + { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) + { + pwfd_info->peer_session_avail = _TRUE; + } + else + { + pwfd_info->peer_session_avail = _FALSE; + } + } + } + + if ( _FALSE == pwfd_info->peer_session_avail ) + { + DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); + goto exit; + } + } +#endif // CONFIG_WFD + + DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel ); +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN ); + _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN ); + pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel; + pwdinfo->tx_prov_disc_info.benable = _TRUE; + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ); + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) + { + _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) ); + } + else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ); + pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN; + } + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } + else + { + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); + } +#else + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); +#endif + + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); +#ifdef CONFIG_INTEL_WIDI + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + rtw_free_network_queue(padapter, _TRUE); + _enter_critical_bh(&pmlmepriv->lock, &irqL); + rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +#endif //CONFIG_INTEL_WIDI + } +exit: + + return ret; + +} + +// Added by Albert 20110328 +// This function is used to inform the driver the user had specified the pin code value or pbc +// to application. + +static int rtw_p2p_got_wpsinfo(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + // Added by Albert 20110328 + // if the input data is P2P_NO_WPSINFO -> reset the wpsinfo + // if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. + // if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. + // if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC + + if ( *extra == '0' ) + { + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; + } + else if ( *extra == '1' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN; + } + else if ( *extra == '2' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN; + } + else if ( *extra == '3' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC; + } + else + { + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; + } + + return ret; + +} + +#endif //CONFIG_P2P + +static int rtw_p2p_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; +#ifdef CONFIG_P2P + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra ); + + if ( _rtw_memcmp( extra, "enable=", 7 ) ) + { + rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "setDN=", 6 ) ) + { + wrqu->data.length -= 6; + rtw_p2p_setDN( dev, info, wrqu, &extra[6] ); + } + else if ( _rtw_memcmp( extra, "profilefound=", 13 ) ) + { + wrqu->data.length -= 13; + rtw_p2p_profilefound( dev, info, wrqu, &extra[13] ); + } + else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) ) + { + wrqu->data.length -= 10; + rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] ); + } + else if ( _rtw_memcmp( extra, "nego=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_p2p_connect( dev, info, wrqu, &extra[5] ); + } + else if ( _rtw_memcmp( extra, "intent=", 7 ) ) + { + // Commented by Albert 2011/03/23 + // The wrqu->data.length will include the null character + // So, we will decrease 7 + 1 + wrqu->data.length -= 8; + rtw_p2p_set_intent( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "ssid=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] ); + } + else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) ) + { + wrqu->data.length -= 12; + rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] ); + } + else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) ) + { + // Commented by Albert 2011/05/24 + // The wrqu->data.length will include the null character + // So, we will decrease (10 + 1) + wrqu->data.length -= 11; + rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] ); + } + else if ( _rtw_memcmp( extra, "op_ch=", 6 ) ) + { + // Commented by Albert 2011/05/24 + // The wrqu->data.length will include the null character + // So, we will decrease (6 + 1) + wrqu->data.length -= 7; + rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] ); + } + else if ( _rtw_memcmp( extra, "invite=", 7 ) ) + { + wrqu->data.length -= 8; + rtw_p2p_invite_req( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "persistent=", 11 ) ) + { + wrqu->data.length -= 11; + rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] ); + } + else if ( _rtw_memcmp ( extra, "uuid=", 5) ) + { + wrqu->data.length -= 5; + ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] ); + } +#ifdef CONFIG_WFD + else if ( _rtw_memcmp( extra, "sa=", 3 ) ) + { + // sa: WFD Session Available information + wrqu->data.length -= 3; + rtw_p2p_set_sa( dev, info, wrqu, &extra[3] ); + } + else if ( _rtw_memcmp( extra, "pc=", 3 ) ) + { + // pc: WFD Preferred Connection + wrqu->data.length -= 3; + rtw_p2p_set_pc( dev, info, wrqu, &extra[3] ); + } + else if ( _rtw_memcmp( extra, "wfd_type=", 9 ) ) + { + // Specify this device is Mircast source or sink + wrqu->data.length -= 9; + rtw_p2p_set_wfd_device_type( dev, info, wrqu, &extra[9] ); + } + else if ( _rtw_memcmp( extra, "scan_type=", 10 ) ) + { + wrqu->data.length -= 10; + rtw_p2p_set_scan_result_type( dev, info, wrqu, &extra[10] ); + } + else if ( _rtw_memcmp( extra, "wfd_enable=", 11 ) ) + { + wrqu->data.length -= 11; + rtw_p2p_set_wfd_enable( dev, info, wrqu, &extra[11] ); + } + else if ( _rtw_memcmp( extra, "driver_iface=", 13 ) ) + { + wrqu->data.length -= 13; + rtw_p2p_set_driver_iface( dev, info, wrqu, &extra[13] ); + } +#endif //CONFIG_WFD +#endif //CONFIG_P2P + + return ret; + +} + +static int rtw_p2p_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_P2P + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if ( padapter->bShowGetP2PState ) + { + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer ); + } + + if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) ) + { + rtw_p2p_get_status( dev, info, wrqu, extra ); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) ) + { + rtw_p2p_get_role( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) ) + { + rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) ) + { + rtw_p2p_get_req_cm( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) ) + { + // Get the P2P device address when receiving the provision discovery request frame. + rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) ) + { + rtw_p2p_get_groupid( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) ) + { + // Get the P2P device address when receiving the P2P Invitation request frame. + rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) ) + { + rtw_p2p_get_op_ch( dev, info, wrqu, extra); + } +#ifdef CONFIG_WFD + else if ( _rtw_memcmp( wrqu->data.pointer, "peer_port", 9 ) ) + { + rtw_p2p_get_peer_wfd_port( dev, info, wrqu, extra ); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_sa", 6 ) ) + { + rtw_p2p_get_peer_wfd_session_available( dev, info, wrqu, extra ); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "wfd_pc", 6 ) ) + { + rtw_p2p_get_peer_wfd_preferred_connection( dev, info, wrqu, extra ); + } +#endif // CONFIG_WFD + +#endif //CONFIG_P2P + + return ret; + +} + +static int rtw_p2p_get2(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_P2P + + int length = wrqu->data.length; + char *buffer = (u8 *)rtw_malloc(length); + + if (buffer == NULL) + { + ret = -ENOMEM; + goto bad; + } + + if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) + { + ret - EFAULT; + goto bad; + } + + DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer); + + if (_rtw_memcmp(buffer, "wpsCM=", 6)) + { + ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]); + } else if (_rtw_memcmp(buffer, "devN=", 5)) + { + ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]); + } else if (_rtw_memcmp(buffer, "dev_type=", 9)) + { + ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]); + } else if (_rtw_memcmp(buffer, "go_devadd=", 10)) + { + ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]); + } else if (_rtw_memcmp(buffer, "InvProc=", 8)) + { + ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]); + } else + { + snprintf(extra, sizeof("Command not found."), "Command not found."); + wrqu->data.length = strlen(extra); + } + +bad: + if (buffer) + { + rtw_mfree(buffer, length); + } + +#endif //CONFIG_P2P + + return ret; + +} + +extern int rtw_change_ifname(_adapter *padapter, const char *ifname); +static int rtw_rereg_nd_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = rtw_netdev_priv(dev); + struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; + char new_ifname[IFNAMSIZ]; + + if(rereg_priv->old_ifname[0] == 0) { + char *reg_ifname; +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->isprimary) + reg_ifname = padapter->registrypriv.ifname; + else +#endif + reg_ifname = padapter->registrypriv.if2name; + + strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); + rereg_priv->old_ifname[IFNAMSIZ-1] = 0; + } + + //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); + if(wrqu->data.length > IFNAMSIZ) + return -EFAULT; + + if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) { + return -EFAULT; + } + + if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) { + return ret; + } + + DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname); + if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) { + goto exit; + } + + if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) { + padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed; + rtw_hal_sw_led_init(padapter); + rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); + } + + strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); + rereg_priv->old_ifname[IFNAMSIZ-1] = 0; + + if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) { + + DBG_871X("%s disable\n", __FUNCTION__); + // free network queue for Android's timming issue + rtw_free_network_queue(padapter, _TRUE); + + // close led + rtw_led_control(padapter, LED_CTL_POWER_OFF); + rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed; + padapter->ledpriv.bRegUseLed= _FALSE; + rtw_hal_sw_led_deinit(padapter); + + // the interface is being "disabled", we can do deeper IPS + rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); + rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); + } +exit: + return ret; + +} + +#if 0 +void mac_reg_dump(_adapter *padapter) +{ + int i,j=1; + DBG_871X("\n======= MAC REG =======\n"); + for(i=0x0;i<0x300;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } + for(i=0x400;i<0x800;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } +} +void bb_reg_dump(_adapter *padapter) +{ + int i,j=1; + DBG_871X("\n======= BB REG =======\n"); + for(i=0x800;i<0x1000;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } +} +void rf_reg_dump(_adapter *padapter) +{ + int i,j=1,path; + u32 value; + DBG_871X("\n======= RF REG =======\n"); + for(path=0;path<2;path++) + { + DBG_871X("\nRF_Path(%x)\n",path); + for(i=0;i<0x100;i++) + { + value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord); + if(j%4==1) DBG_871X("0x%02x ",i); + DBG_871X(" 0x%08x ",value); + if((j++)%4==0) DBG_871X("\n"); + } + } +} + +#endif + +void mac_reg_dump(_adapter *padapter) +{ + int i,j=1; + DBG_871X("\n======= MAC REG =======\n"); + for(i=0x0;i<0x300;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } + for(i=0x400;i<0x800;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } +} +void bb_reg_dump(_adapter *padapter) +{ + int i,j=1; + DBG_871X("\n======= BB REG =======\n"); + for(i=0x800;i<0x1000;i+=4) + { + if(j%4==1) DBG_871X("0x%02x",i); + + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } +} +void rf_reg_dump(_adapter *padapter) +{ + int i,j=1,path; + u32 value; + u8 rf_type,path_nums = 0; + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + DBG_871X("\n======= RF REG =======\n"); + if((RF_1T2R == rf_type) ||(RF_1T1R ==rf_type )) + path_nums = 1; + else + path_nums = 2; + + for(path=0;path +#endif +#ifdef DBG_CONFIG_ERROR_DETECT +#include +#endif +static int rtw_dbg_port(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _irqL irqL; + int ret = 0; + u8 major_cmd, minor_cmd; + u16 arg; + u32 extra_arg, *pdata, val32; + struct sta_info *psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct sta_priv *pstapriv = &padapter->stapriv; + + + pdata = (u32*)&wrqu->data; + + val32 = *pdata; + arg = (u16)(val32&0x0000ffff); + major_cmd = (u8)(val32>>24); + minor_cmd = (u8)((val32>>16)&0x00ff); + + extra_arg = *(pdata+1); + + switch(major_cmd) + { + case 0x70://read_reg + switch(minor_cmd) + { + case 1: + DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg)); + break; + case 2: + DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg)); + break; + case 4: + DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg)); + break; + } + break; + case 0x71://write_reg + switch(minor_cmd) + { + case 1: + rtw_write8(padapter, arg, extra_arg); + DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg)); + break; + case 2: + rtw_write16(padapter, arg, extra_arg); + DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg)); + break; + case 4: + rtw_write32(padapter, arg, extra_arg); + DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg)); + break; + } + break; + case 0x72://read_bb + DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); + break; + case 0x73://write_bb + rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); + DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); + break; + case 0x74://read_rf + DBG_871X("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg,rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); + break; + case 0x75://write_rf + rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); + DBG_871X("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); + break; + + case 0x76: + switch(minor_cmd) + { + case 0x00: //normal mode, + padapter->recvpriv.is_signal_dbg = 0; + break; + case 0x01: //dbg mode + padapter->recvpriv.is_signal_dbg = 1; + extra_arg = extra_arg>100?100:extra_arg; + extra_arg = extra_arg<0?0:extra_arg; + padapter->recvpriv.signal_strength_dbg=extra_arg; + break; + } + break; + case 0x78: //IOL test + switch(minor_cmd) + { + #ifdef CONFIG_IOL + case 0x04: //LLT table initialization test + { + u8 page_boundary = 0xf9; + { + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) { + ret = -ENOMEM; + break; + } + + rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary); + + + if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500) ) + ret = -EPERM; + } + } + break; + case 0x05: //blink LED test + { + u16 reg = 0x4c; + u32 blink_num = 50; + u32 blink_delay_ms = 200; + int i; + + { + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) { + ret = -ENOMEM; + break; + } + + for(i=0;inetwork.MacAddress + , WLAN_REASON_EXPIRATION_CHK); + break; + + case 0x7F: + switch(minor_cmd) + { + case 0x0: + DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv)); + break; + case 0x01: + DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, + psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); + break; + case 0x02: + DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state); + break; + case 0x03: + DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option); + DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option); + break; + case 0x04: + DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel); + DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode); + DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset); + break; + case 0x05: + psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(psta) + { + int i; + struct recv_reorder_ctrl *preorder_ctrl; + + DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid); + DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); + DBG_871X("bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); + DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); + + for(i=0;i<16;i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + if(preorder_ctrl->enable) + { + DBG_871X("tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq); + } + } + + } + else + { + DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); + } + break; + case 0x06: + { + u8 DMFlag; + rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&DMFlag)); + DBG_871X("(B)DMFlag=0x%x, arg=0x%x\n", DMFlag, arg); + DMFlag = (u8)(0x0f&arg); + DBG_871X("(A)DMFlag=0x%x\n", DMFlag); + rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&DMFlag)); + } + break; + case 0x07: + DBG_871X("bSurpriseRemoved=%d, bDriverStopped=%d\n", + padapter->bSurpriseRemoved, padapter->bDriverStopped); + break; + case 0x08: + { + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; + + DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d" + ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d" + ", free_recvframe_cnt=%d\n", + pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, + 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); + #endif + } + break; + case 0x09: + { + int i, j; + _list *plist, *phead; + struct recv_reorder_ctrl *preorder_ctrl; + +#ifdef CONFIG_AP_MODE + DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); +#endif + _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(extra_arg == psta->aid) + { + DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); + DBG_871X("bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); + DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); +#ifdef CONFIG_AP_MODE + DBG_871X("capability=0x%x\n", psta->capability); + DBG_871X("flags=0x%x\n", psta->flags); + DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk); + DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); + DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); + DBG_871X("qos_info=0x%x\n", psta->qos_info); +#endif + DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); + + + + for(j=0;j<16;j++) + { + preorder_ctrl = &psta->recvreorder_ctrl[j]; + if(preorder_ctrl->enable) + { + DBG_871X("tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq); + } + } + + } + + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + } + break; + + case 0x0c://dump rx packet + { + DBG_871X("dump rx packet (%d)\n",extra_arg); + //pHalData->bDumpRxPkt =extra_arg; + rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); + } + break; +#if 0 + case 0x0d://dump cam + { + //u8 entry = (u8) extra_arg; + u8 entry=0; + //dump cam + for(entry=0;entry<32;entry++) + read_cam(padapter,entry); + } + break; +#endif + #ifdef DBG_CONFIG_ERROR_DETECT + case 0x0f: + { + if(extra_arg == 0){ + DBG_871X("###### silent reset test.......#####\n"); + rtw_hal_sreset_reset(padapter); + } else { + sreset_set_trigger_point(padapter, extra_arg); + } + + } + break; + case 0x15: + { + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts); + } + break; + + #endif + + case 0x10:// driver version display + DBG_871X("rtw driver version=%s\n", DRIVERVERSION); + break; + case 0x11: + { + DBG_871X("turn %s Rx RSSI display function\n",(extra_arg==1)?"on":"off"); + padapter->bRxRSSIDisplay = extra_arg ; + } + break; + case 0x12: //set rx_stbc + { + struct registry_priv *pregpriv = &padapter->registrypriv; + // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g + //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ + if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3)) + { + pregpriv->rx_stbc= extra_arg; + DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc); + } + else + DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc); + + } + break; + case 0x13: //set ampdu_enable + { + struct registry_priv *pregpriv = &padapter->registrypriv; + // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) + if( pregpriv && extra_arg >= 0 && extra_arg < 3 ) + { + pregpriv->ampdu_enable= extra_arg; + DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable); + } + else + DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable); + + } + break; + case 0x14: //get wifi_spec + { + struct registry_priv *pregpriv = &padapter->registrypriv; + DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec); + + } + break; + case 0x22: + { + DBG_871X("turn %s the ForceWriteInitGain Variable\n",(extra_arg==1)?"on":"off"); + padapter->bForceWriteInitGain = extra_arg; + break; + } + case 0x23: + { + DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off"); + padapter->bNotifyChannelChange = extra_arg; + break; + } + case 0x24: + { +#ifdef CONFIG_P2P + DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off"); + padapter->bShowGetP2PState = extra_arg; +#endif // CONFIG_P2P + break; + } +#if 1 + case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg + { + if(extra_arg==0){ + mac_reg_dump(padapter); + } + else if(extra_arg==1){ + bb_reg_dump(padapter); + } + else if(extra_arg==2){ + rf_reg_dump(padapter); + } + + } + break; +#endif + case 0xee://turn on/off dynamic funcs + { + u8 dm_flag; + + if(0xf==extra_arg){ + rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&dm_flag); + DBG_871X(" === DMFlag(0x%02x) === \n",dm_flag); + DBG_871X("extra_arg = 0 - disable all dynamic func \n"); + DBG_871X("extra_arg = 1 - disable DIG- BIT(0)\n"); + DBG_871X("extra_arg = 2 - disable High power - BIT(1)\n"); + DBG_871X("extra_arg = 3 - disable tx power tracking - BIT(2)\n"); + DBG_871X("extra_arg = 4 - disable BT coexistence - BIT(3)\n"); + DBG_871X("extra_arg = 5 - disable antenna diversity - BIT(4)\n"); + DBG_871X("extra_arg = 6 - enable all dynamic func \n"); + } + else{ + /* extra_arg = 0 - disable all dynamic func + extra_arg = 1 - disable DIG + extra_arg = 2 - disable tx power tracking + extra_arg = 3 - turn on all dynamic func + */ + rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg)); + rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&dm_flag); + DBG_871X(" === DMFlag(0x%02x) === \n",dm_flag); + } + } + break; + + case 0xfd: + rtw_write8(padapter, 0xc50, arg); + DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50)); + rtw_write8(padapter, 0xc58, arg); + DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58)); + break; + case 0xfe: + DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50)); + DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58)); + break; + case 0xff: + { + DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210)); + DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608)); + DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280)); + DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284)); + DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288)); + + DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664)); + + + DBG_871X("\n"); + + DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430)); + DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438)); + + DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440)); + + DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458)); + + DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484)); + DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488)); + + DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444)); + DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448)); + DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c)); + DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450)); + } + break; + } + break; + default: + DBG_871X("error dbg cmd!\n"); + break; + } + + + return ret; + +} + +static int wpa_set_param(struct net_device *dev, u8 name, u32 value) +{ + uint ret=0; + u32 flags; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + switch (name){ + case IEEE_PARAM_WPA_ENABLED: + + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x + + //ret = ieee80211_wpa_enable(ieee, value); + + switch((value)&0xff) + { + case 1 : //WPA + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case 2: //WPA2 + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + } + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype)); + + break; + + case IEEE_PARAM_TKIP_COUNTERMEASURES: + //ieee->tkip_countermeasures=value; + break; + + case IEEE_PARAM_DROP_UNENCRYPTED: + { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + +#if 0 + struct ieee80211_security sec = { + .flags = SEC_ENABLED, + .enabled = value, + }; + ieee->drop_unencrypted = value; + /* We only change SEC_LEVEL for open mode. Others + * are set by ipw_wpa_set_encryption. + */ + if (!value) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_0; + } + else { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); +#endif + break; + + } + case IEEE_PARAM_PRIVACY_INVOKED: + + //ieee->privacy_invoked=value; + + break; + + case IEEE_PARAM_AUTH_ALGS: + + ret = wpa_set_auth_algs(dev, value); + + break; + + case IEEE_PARAM_IEEE_802_1X: + + //ieee->ieee802_1x=value; + + break; + + case IEEE_PARAM_WPAX_SELECT: + + // added for WPA2 mixed mode + //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value); + /* + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); + ieee->wpax_type_set = 1; + ieee->wpax_type_notify = value; + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); + */ + + break; + + default: + + + + ret = -EOPNOTSUPP; + + + break; + + } + + return ret; + +} + +static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + switch (command) + { + case IEEE_MLME_STA_DEAUTH: + + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + case IEEE_MLME_STA_DISASSOC: + + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; + +} + +static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) +{ + struct ieee_param *param; + uint ret=0; + + //down(&ieee->wx_sem); + + if (p->length < sizeof(struct ieee_param) || !p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)rtw_malloc(p->length); + if (param == NULL) + { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(param, p->pointer, p->length)) + { + rtw_mfree((u8*)param, p->length); + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + + case IEEE_CMD_SET_WPA_PARAM: + ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); + break; + + case IEEE_CMD_SET_WPA_IE: + //ret = wpa_set_wpa_ie(dev, param, p->length); + ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); + break; + + case IEEE_CMD_SET_ENCRYPTION: + ret = wpa_set_encryption(dev, param, p->length); + break; + + case IEEE_CMD_MLME: + ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); + break; + + default: + DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd); + ret = -EOPNOTSUPP; + break; + + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + rtw_mfree((u8 *)param, p->length); + +out: + + //up(&ieee->wx_sem); + + return ret; + +} + +#ifdef CONFIG_AP_MODE +static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + + + psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy; + + _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN); + + _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); + + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid) +{ + u8 keylen; + struct cmd_obj* pcmd; + struct setkey_parm *psetkeyparm; + struct cmd_priv *pcmdpriv=&(padapter->cmdpriv); + int res=_SUCCESS; + + DBG_871X("%s\n", __FUNCTION__); + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; + goto exit; + } + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm)); + + psetkeyparm->keyid=(u8)keyid; + if (is_wep_enc(alg)) + padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); + + psetkeyparm->algorithm = alg; + + psetkeyparm->set_tx = 1; + + switch(alg) + { + case _WEP40_: + keylen = 5; + break; + case _WEP104_: + keylen = 13; + break; + case _TKIP_: + case _TKIP_WTMIC_: + case _AES_: + keylen = 16; + default: + keylen = 16; + } + + _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen); + + pcmd->cmdcode = _SetKey_CMD_; + pcmd->parmbuf = (u8 *)psetkeyparm; + pcmd->cmdsz = (sizeof(struct setkey_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + + return res; + + +} + +static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid) +{ + u8 alg; + + switch(keylen) + { + case 5: + alg =_WEP40_; + break; + case 13: + alg =_WEP104_; + break; + default: + alg =_NO_PRIVACY_; + } + + return set_group_key(padapter, key, alg, keyid); + +} + + +static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + NDIS_802_11_WEP *pwep = NULL; + struct sta_info *psta = NULL, *pbcmc_sta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + //sizeof(struct ieee_param) = 64 bytes; + //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS) + { + ret = -EINVAL; + goto exit; + } + } + else + { + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(!psta) + { + //ret = -EINVAL; + DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n"); + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL)) + { + //todo:clear default encryption keys + + DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx); + + goto exit; + } + + + if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL)) + { + DBG_871X("r871x_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len); + + if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0)) + { + ret = -EINVAL; + goto exit; + } + + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len); + if(pwep == NULL){ + DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n"); + goto exit; + } + + _rtw_memset(pwep, 0, wep_total_len); + + pwep->KeyLength = wep_key_len; + pwep->Length = wep_total_len; + + } + + pwep->KeyIndex = wep_key_idx; + + _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); + + if(param->u.crypt.set_tx) + { + DBG_871X("wep, set_tx=1\n"); + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + psecuritypriv->dot118021XGrpPrivacy=_WEP40_; + + if(pwep->KeyLength==13) + { + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + psecuritypriv->dot118021XGrpPrivacy=_WEP104_; + } + + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); + + psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength; + + set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx); + + + } + else + { + DBG_871X("wep, set_tx=0\n"); + + //don't update "psecuritypriv->dot11PrivacyAlgrthm" and + //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; + + set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx); + + } + + goto exit; + + } + + + if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key + { + if(param->u.crypt.set_tx ==1) + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_871X("%s, set group_key, WEP\n", __FUNCTION__); + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + DBG_871X("%s, set group_key, none\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + goto exit; + + } + + if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x + { + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + if(param->u.crypt.set_tx ==1) + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psta->dot118021XPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _TKIP_; + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + + DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _AES_; + } + else + { + DBG_871X("%s, set pairwise key, none\n", __FUNCTION__); + + psta->dot118021XPrivacy = _NO_PRIVACY_; + } + + set_pairwise_key(padapter, psta); + + psta->ieee8021x_blocked = _FALSE; + + } + else//group key??? + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + } + + } + +exit: + + if(pwep) + { + rtw_mfree((u8 *)pwep,wep_total_len); + } + + return ret; + +} + +static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + unsigned char *pbuf = param->u.bcn_ie.buf; + + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); + + if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) + pstapriv->max_num_sta = NUM_STA; + + + if(rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed + ret = 0; + else + ret = -EINVAL; + + + return ret; + +} + +static int rtw_hostapd_sta_flush(struct net_device *dev) +{ + //_irqL irqL; + //_list *phead, *plist; + int ret=0; + //struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + flush_all_cam_entry(padapter); //clear CAM + + ret = rtw_sta_flush(padapter); + + return ret; + +} + +static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) +{ + _irqL irqL; + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + +/* + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + psta = NULL; + } +*/ + //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + int flags = param->u.add_sta.flags; + + //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta); + + psta->aid = param->u.add_sta.aid;//aid=1~2007 + + _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + + + //check wmm cap. + if(WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if(pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + +#ifdef CONFIG_80211N_HT + //chec 802.11n ht cap. + if(WLAN_STA_HT&flags) + { + psta->htpriv.ht_option = _TRUE; + psta->qos_option = 1; + _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); + } + else + { + psta->htpriv.ht_option = _FALSE; + } + + if(pmlmepriv->htpriv.ht_option == _FALSE) + psta->htpriv.ht_option = _FALSE; +#endif + + + update_sta_info_apmode(padapter, psta); + + + } + else + { + ret = -ENOMEM; + } + + return ret; + +} + +static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) +{ + _irqL irqL; + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + u8 updated=_FALSE; + + //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated); + + psta = NULL; + + } + else + { + DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n"); + + //ret = -1; + } + + + return ret; + +} + +static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; + struct sta_data *psta_data = (struct sta_data *)param_ex->data; + + DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && + param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff && + param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr); + if(psta) + { +#if 0 + struct { + u16 aid; + u16 capability; + int flags; + u32 sta_set; + u8 tx_supp_rates[16]; + u32 tx_supp_rates_len; + struct rtw_ieee80211_ht_cap ht_cap; + u64 rx_pkts; + u64 rx_bytes; + u64 rx_drops; + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; + } get_sta; +#endif + psta_data->aid = (u16)psta->aid; + psta_data->capability = psta->capability; + psta_data->flags = psta->flags; + +/* + nonerp_set : BIT(0) + no_short_slot_time_set : BIT(1) + no_short_preamble_set : BIT(2) + no_ht_gf_set : BIT(3) + no_ht_set : BIT(4) + ht_20mhz_set : BIT(5) +*/ + + psta_data->sta_set =((psta->nonerp_set) | + (psta->no_short_slot_time_set <<1) | + (psta->no_short_preamble_set <<2) | + (psta->no_ht_gf_set <<3) | + (psta->no_ht_set <<4) | + (psta->ht_20mhz_set <<5)); + + psta_data->tx_supp_rates_len = psta->bssratelen; + _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen); + + _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); + + psta_data->rx_pkts = psta->sta_stats.rx_data_pkts; + psta_data->rx_bytes = psta->sta_stats.rx_bytes; + psta_data->rx_drops = psta->sta_stats.rx_drops; + + psta_data->tx_pkts = psta->sta_stats.tx_pkts; + psta_data->tx_bytes = psta->sta_stats.tx_bytes; + psta_data->tx_drops = psta->sta_stats.tx_drops; + + + } + else + { + ret = -1; + } + + return ret; + +} + +static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) +{ + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) + { + int wpa_ie_len; + int copy_len; + + wpa_ie_len = psta->wpa_ie[1]; + + copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2); + + param->u.wpa_ie.len = copy_len; + + _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len); + } + else + { + //ret = -1; + DBG_871X("sta's wpa_ie is NONE\n"); + } + } + else + { + ret = -1; + } + + return ret; + +} + +static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04}; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_beacon_ie) + { + rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); + pmlmepriv->wps_beacon_ie_len = ie_len; + if ( pmlmepriv->wps_beacon_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len); + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE); + + pmlmeext->bstart_bss = _TRUE; + + } + + + return ret; + +} + +static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_probe_resp_ie) + { + rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); + pmlmepriv->wps_probe_resp_ie_len = ie_len; + if ( pmlmepriv->wps_probe_resp_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len); + } + + + return ret; + +} + +static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_assoc_resp_ie) + { + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); + pmlmepriv->wps_assoc_resp_ie_len = ie_len; + if ( pmlmepriv->wps_assoc_resp_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len); + } + + + return ret; + +} + +static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info); + int ie_len; + u8 *ssid_ie; + char ssid[NDIS_802_11_LENGTH_SSID + 1]; + sint ssid_len; + u8 ignore_broadcast_ssid; + + if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE) + return -EPERM; + + if (param->u.bcn_ie.reserved[0] != 0xea) + return -EINVAL; + + mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1]; + + ie_len = len-12-2;// 12 = param header, 2:no packed + ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len); + + if (ssid_ie && ssid_len) { + WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network; + WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network; + + _rtw_memcpy(ssid, ssid_ie+2, ssid_len); + ssid[ssid_len>NDIS_802_11_LENGTH_SSID?NDIS_802_11_LENGTH_SSID:ssid_len] = 0x0; + + if(0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + ssid, ssid_len, + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + + _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len); + pbss_network->Ssid.SsidLength = ssid_len; + _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len); + pbss_network_ext->Ssid.SsidLength = ssid_len; + + if(0) + DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + } + + DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter), + ignore_broadcast_ssid, ssid, ssid_len); + + return ret; +} + +static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + ret = rtw_acl_remove_sta(padapter, param->sta_addr); + + return ret; + +} + +static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + ret = rtw_acl_add_sta(padapter, param->sta_addr); + + return ret; + +} + +static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + rtw_set_macaddr_acl(padapter, param->u.mlme.command); + + return ret; +} + +static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) +{ + struct ieee_param *param; + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + //DBG_871X("%s\n", __FUNCTION__); + + /* + * this function is expect to call in master mode, which allows no power saving + * so, we just check hw_init_completed instead of call rfpwrstate_check() + */ + + if (padapter->hw_init_completed==_FALSE){ + ret = -EPERM; + goto out; + } + + + //if (p->length < sizeof(struct ieee_param) || !p->pointer){ + if(!p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)rtw_malloc(p->length); + if (param == NULL) + { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(param, p->pointer, p->length)) + { + rtw_mfree((u8*)param, p->length); + ret = -EFAULT; + goto out; + } + + //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd); + + switch (param->cmd) + { + case RTL871X_HOSTAPD_FLUSH: + + ret = rtw_hostapd_sta_flush(dev); + + break; + + case RTL871X_HOSTAPD_ADD_STA: + + ret = rtw_add_sta(dev, param); + + break; + + case RTL871X_HOSTAPD_REMOVE_STA: + + ret = rtw_del_sta(dev, param); + + break; + + case RTL871X_HOSTAPD_SET_BEACON: + + ret = rtw_set_beacon(dev, param, p->length); + + break; + + case RTL871X_SET_ENCRYPTION: + + ret = rtw_set_encryption(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_GET_WPAIE_STA: + + ret = rtw_get_sta_wpaie(dev, param); + + break; + + case RTL871X_HOSTAPD_SET_WPS_BEACON: + + ret = rtw_set_wps_beacon(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP: + + ret = rtw_set_wps_probe_resp(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP: + + ret = rtw_set_wps_assoc_resp(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_HIDDEN_SSID: + + ret = rtw_set_hidden_ssid(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_GET_INFO_STA: + + ret = rtw_ioctl_get_sta_data(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_MACADDR_ACL: + + ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_ACL_ADD_STA: + + ret = rtw_ioctl_acl_add_sta(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_ACL_REMOVE_STA: + + ret = rtw_ioctl_acl_remove_sta(dev, param, p->length); + + break; + + default: + DBG_871X("Unknown hostapd request: %d\n", param->cmd); + ret = -EOPNOTSUPP; + break; + + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + + rtw_mfree((u8 *)param, p->length); + +out: + + return ret; + +} +#endif + +#include +static int rtw_wx_set_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + +#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + char *ext_dbg; +#endif + + int ret = 0; + int len = 0; + char *ext; + int i; + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *dwrq = (struct iw_point*)awrq; + + //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n")); + if(dwrq->length == 0) + return -EFAULT; + len = dwrq->length; + if (!(ext = rtw_vmalloc(len))) + return -ENOMEM; + + if (copy_from_user(ext, dwrq->pointer, len)) { + rtw_vmfree(ext, len); + return -EFAULT; + } + + + //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, + // ("rtw_wx_set_priv: %s req=%s\n", + // dev->name, ext)); + + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + if (!(ext_dbg = rtw_vmalloc(len))) + { + rtw_vmfree(ext, len); + return -ENOMEM; + } + + _rtw_memcpy(ext_dbg, ext, len); + #endif + + //added for wps2.0 @20110524 + if(dwrq->flags == 0x8766 && len > 8) + { + u32 cp_sz; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *probereq_wpsie = ext; + int probereq_wpsie_len = len; + u8 wps_oui[4]={0x0,0x50,0xf2,0x04}; + + if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && + (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE)) + { + cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len; + + //_rtw_memcpy(pmlmepriv->probereq_wpsie, probereq_wpsie, cp_sz); + //pmlmepriv->probereq_wpsie_len = cp_sz; + + printk("probe_req_wps_ielen=%d\n", cp_sz); + + if(pmlmepriv->wps_probe_req_ie) + { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz); + if ( pmlmepriv->wps_probe_req_ie == NULL) { + printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + goto FREE_EXT; + + } + + _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); + pmlmepriv->wps_probe_req_ie_len = cp_sz; + + } + + goto FREE_EXT; + + } + + if( len >= WEXT_CSCAN_HEADER_SIZE + && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE + ){ + ret = rtw_wx_set_scan(dev, info, awrq, ext); + goto FREE_EXT; + } + +#ifdef CONFIG_ANDROID + //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); + + i = rtw_android_cmdstr_to_num(ext); + + switch(i) { + case ANDROID_WIFI_CMD_START : + indicate_wx_custom_event(padapter, "START"); + break; + case ANDROID_WIFI_CMD_STOP : + indicate_wx_custom_event(padapter, "STOP"); + break; + case ANDROID_WIFI_CMD_RSSI : + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); + } else { + sprintf(ext, "OK"); + } + } + break; + case ANDROID_WIFI_CMD_LINKSPEED : + { + u16 mbps = rtw_get_cur_max_rate(padapter)/10; + sprintf(ext, "LINKSPEED %d", mbps); + } + break; + case ANDROID_WIFI_CMD_MACADDR : + sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr)); + break; + case ANDROID_WIFI_CMD_SCAN_ACTIVE : + { + //rtw_set_scan_mode(padapter, SCAN_ACTIVE); + sprintf(ext, "OK"); + } + break; + case ANDROID_WIFI_CMD_SCAN_PASSIVE : + { + //rtw_set_scan_mode(padapter, SCAN_PASSIVE); + sprintf(ext, "OK"); + } + break; + + case ANDROID_WIFI_CMD_COUNTRY : + { + char country_code[10]; + sscanf(ext, "%*s %s", country_code); + rtw_set_country(padapter, country_code); + sprintf(ext, "OK"); + } + break; + default : + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__, + dev->name, ext_dbg); + #endif + + sprintf(ext, "OK"); + + } + + if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) ) + ret = -EFAULT; + + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__, + dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1)); + #endif +#endif //end of CONFIG_ANDROID + + +FREE_EXT: + + rtw_vmfree(ext, len); + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + rtw_vmfree(ext_dbg, len); + #endif + + //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", + // dev->name, ret); + + return ret; + +} + +static int rtw_mp_efuse_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + PADAPTER padapter = rtw_netdev_priv(dev); + struct mp_priv *pmp_priv; + + int i,j =0; + u8 data[EFUSE_MAP_SIZE]; + u8 rawdata[EFUSE_MAX_SIZE]; + u16 mapLen=0; + char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00}; + u16 addr = 0, cnts = 0, max_available_size = 0,raw_cursize = 0 ,raw_maxsize = 0; + + _rtw_memset(data, '\0', sizeof(data)); + _rtw_memset(rawdata, '\0', sizeof(rawdata)); + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + pch = extra; + DBG_871X("%s: in=%s\n", __func__, extra); + + i=0; + //mac 16 "00e04c871200" rmap,00,2 + while ( (token = strsep (&pch,",") )!=NULL ) + { + if(i>2) break; + tmp[i] = token; + i++; + } + + if ( strcmp(tmp[0],"realmap") == 0 ) { + + DBG_871X("strcmp OK = %s \n" ,tmp[0]); + + mapLen = EFUSE_MAP_SIZE; + + if (rtw_efuse_map_read(padapter, 0, mapLen, data) == _SUCCESS){ + DBG_871X("\t rtw_efuse_map_read \n"); + }else { + DBG_871X("\t rtw_efuse_map_read : Fail \n"); + return -EFAULT; + } + _rtw_memset(extra, '\0', sizeof(extra)); + DBG_871X("\tOFFSET\tVALUE(hex)\n"); + sprintf(extra, "%s \n", extra); + for ( i = 0; i < EFUSE_MAP_SIZE; i += 16 ) + { + DBG_871X("\t0x%02x\t", i); + sprintf(extra, "%s \t0x%02x\t", extra,i); + for (j = 0; j < 8; j++) + { + DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s %02X", extra, data[i+j]); + } + DBG_871X("\t"); + sprintf(extra,"%s\t",extra); + for (; j < 16; j++){ + DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s %02X", extra, data[i+j]); + } + DBG_871X("\n"); + sprintf(extra,"%s\n",extra); + } + DBG_871X("\n"); + wrqu->length = strlen(extra); + + return 0; + } + else if ( strcmp(tmp[0],"rmap") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + // rmap addr cnts + addr = simple_strtoul(tmp[1], &ptmp, 16); + + DBG_871X("addr = %x \n" ,addr); + + cnts=simple_strtoul(tmp[2], &ptmp,10); + if(cnts==0) return -EINVAL; + + DBG_871X("cnts = %d \n" ,cnts); + //_rtw_memset(extra, '\0', wrqu->data.length); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if ((addr + cnts) > max_available_size) { + DBG_871X("(addr + cnts parameter error \n"); + return -EFAULT; + } + + if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("rtw_efuse_access error \n"); + } + else{ + DBG_871X("rtw_efuse_access ok \n"); + } + + _rtw_memset(extra, '\0', sizeof(extra)); + for ( i = 0; i < cnts; i ++) { + DBG_871X("0x%02x", data[i]); + sprintf(extra, "%s 0x%02X", extra, data[i]); + DBG_871X(" "); + sprintf(extra,"%s ",extra); + } + + wrqu->length = strlen(extra)+1; + + DBG_871X("extra = %s ", extra); + + return 0; + } + else if ( strcmp(tmp[0],"realraw") == 0 ) { + addr=0; + mapLen = EFUSE_MAX_SIZE; + + if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) + { + DBG_871X("\t rtw_efuse_map_read : Fail \n"); + return -EFAULT; + } else + { + DBG_871X("\t rtw_efuse_access raw ok \n"); + } + + _rtw_memset(extra, '\0', sizeof(extra)); + for ( i=0; ilength = strlen(extra); + return 0; + } + else if ( strcmp(tmp[0],"mac") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + #ifdef CONFIG_RTL8192C + addr = 0x16; + cnts = 6; + #endif + #ifdef CONFIG_RTL8192D + addr = 0x19; + cnts = 6; + #endif + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if ((addr + mapLen) > max_available_size) { + DBG_871X("(addr + cnts parameter error \n"); + return -EFAULT; + } + if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("rtw_efuse_access error \n"); + } + else{ + DBG_871X("rtw_efuse_access ok \n"); + } + _rtw_memset(extra, '\0', sizeof(extra)); + for ( i = 0; i < cnts; i ++) { + DBG_871X("0x%02x", data[i]); + sprintf(extra, "%s 0x%02X", extra, data[i+j]); + DBG_871X(" "); + sprintf(extra,"%s ",extra); + } + wrqu->length = strlen(extra); + return 0; + } + else if ( strcmp(tmp[0],"vidpid") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + #ifdef CONFIG_RTL8192C + addr=0x0a; + #endif + #ifdef CONFIG_RTL8192D + addr = 0x0c; + #endif + cnts = 4; + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if ((addr + mapLen) > max_available_size) { + DBG_871X("(addr + cnts parameter error \n"); + return -EFAULT; + } + if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("rtw_efuse_access error \n"); + } + else{ + DBG_871X("rtw_efuse_access ok \n"); + } + _rtw_memset(extra, '\0', sizeof(extra)); + for ( i = 0; i < cnts; i ++) { + DBG_871X("0x%02x", data[i]); + sprintf(extra, "%s 0x%02X", extra, data[i+j]); + DBG_871X(" "); + sprintf(extra,"%s ",extra); + } + wrqu->length = strlen(extra); + return 0; + } + else if ( strcmp(tmp[0],"ableraw") == 0 ) { + efuse_GetCurrentSize(padapter,&raw_cursize); + raw_maxsize = efuse_GetMaxSize(padapter); + sprintf(extra, "%s : [ available raw size] = %d",extra,raw_maxsize-raw_cursize); + wrqu->length = strlen(extra); + + return 0; + }else + { + sprintf(extra, "%s : Command not found\n",extra); + wrqu->length = strlen(extra); + return 0; + } + + return 0; +} + +static int rtw_mp_efuse_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + PADAPTER padapter = rtw_netdev_priv(dev); + + u8 buffer[40]; + u32 i,jj,kk; + u8 setdata[EFUSE_MAP_SIZE]; + u8 setrawdata[EFUSE_MAX_SIZE]; + char *pch, *ptmp, *token, *edata,*tmp[3]={0x00,0x00,0x00}; + + u16 addr = 0, max_available_size = 0; + u32 cnts = 0; + + pch = extra; + DBG_871X("%s: in=%s\n", __func__, extra); + + i=0; + while ( (token = strsep (&pch,",") )!=NULL ) + { + if(i>2) break; + tmp[i] = token; + i++; + } + + // tmp[0],[1],[2] + // wmap,addr,00e04c871200 + if ( strcmp(tmp[0],"wmap") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + if ( ! strlen( tmp[2] )/2 > 1 ) return -EFAULT; + + addr = simple_strtoul( tmp[1], &ptmp, 16 ); + addr = addr & 0xFF; + DBG_871X("addr = %x \n" ,addr); + + cnts = strlen( tmp[2] )/2; + if ( cnts == 0) return -EFAULT; + + DBG_871X("cnts = %d \n" ,cnts); + DBG_871X("target data = %s \n" ,tmp[2]); + + for( jj = 0, kk = 0; jj < cnts; jj++, kk += 2 ) + { + setdata[jj] = key_2char2num( tmp[2][kk], tmp[2][kk+ 1] ); + } + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + DBG_871X("parameter error \n"); + return -EFAULT; + } + if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) { + DBG_871X("rtw_efuse_map_write error \n"); + return -EFAULT; + } else + DBG_871X("rtw_efuse_map_write ok \n"); + + return 0; + } + else if ( strcmp(tmp[0],"wraw") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + if ( ! strlen( tmp[2] )/2 > 1 ) return -EFAULT; + addr = simple_strtoul( tmp[1], &ptmp, 16 ); + addr = addr & 0xFF; + DBG_871X("addr = %x \n" ,addr); + + cnts=strlen( tmp[2] )/2; + if ( cnts == 0) return -EFAULT; + + DBG_871X(" cnts = %d \n" ,cnts ); + DBG_871X("target data = %s \n" ,tmp[2] ); + + for( jj = 0, kk = 0; jj < cnts; jj++, kk += 2 ) + { + setrawdata[jj] = key_2char2num( tmp[2][kk], tmp[2][kk+ 1] ); + } + + if ( rtw_efuse_access( padapter, _TRUE, addr, cnts, setrawdata ) == _FAIL ){ + DBG_871X("\t rtw_efuse_map_read : Fail \n"); + return -EFAULT; + } else + DBG_871X("\t rtw_efuse_access raw ok \n"); + + return 0; + } + else if ( strcmp(tmp[0],"mac") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + //mac,00e04c871200 + #ifdef CONFIG_RTL8192C + addr = 0x16; + #endif + #ifdef CONFIG_RTL8192D + addr = 0x19; + #endif + cnts = strlen( tmp[1] )/2; + if ( cnts == 0) return -EFAULT; + if ( cnts > 6 ){ + DBG_871X("error data for mac addr = %s \n" ,tmp[1]); + return -EFAULT; + } + + DBG_871X("target data = %s \n" ,tmp[1]); + + for( jj = 0, kk = 0; jj < cnts; jj++, kk += 2 ) + { + setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+ 1]); + } + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + DBG_871X("parameter error \n"); + return -EFAULT; + } + if ( rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL ) { + DBG_871X("rtw_efuse_map_write error \n"); + return -EFAULT; + } else + DBG_871X("rtw_efuse_map_write ok \n"); + + return 0; + } + else if ( strcmp(tmp[0],"vidpid") == 0 ) { + if ( tmp[1]==NULL || tmp[2]==NULL ) return -EINVAL; + // pidvid,da0b7881 + #ifdef CONFIG_RTL8192C + addr=0x0a; + #endif + #ifdef CONFIG_RTL8192D + addr = 0x0c; + #endif + + cnts=strlen( tmp[1] )/2; + if ( cnts == 0) return -EFAULT; + DBG_871X("target data = %s \n" ,tmp[1]); + + for( jj = 0, kk = 0; jj < cnts; jj++, kk += 2 ) + { + setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+ 1]); + } + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + DBG_871X("parameter error \n"); + return -EFAULT; + } + + if ( rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL ) { + DBG_871X("rtw_efuse_map_write error \n"); + return -EFAULT; + } else + DBG_871X("rtw_efuse_map_write ok \n"); + + return 0; + } + else{ + DBG_871X("Command not found\n"); + return 0; + } + + return 0; +} + + + +#if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT) + +/* + * Input Format: %s,%d,%d + * %s is width, could be + * "b" for 1 byte + * "w" for WORD (2 bytes) + * "dw" for DWORD (4 bytes) + * 1st %d is address(offset) + * 2st %d is data to write + */ +static int rtw_mp_write_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char *pch, *pnext, *ptmp; + char *width_str; + char width; + u32 addr, data; + int ret; + PADAPTER padapter = rtw_netdev_priv(dev); + + + pch = extra; + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) return -EINVAL; + *pnext = 0; + width_str = pch; + + pch = pnext + 1; + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) return -EINVAL; + *pnext = 0; + addr = simple_strtoul(pch, &ptmp, 16); + if (addr > 0x3FFF) return -EINVAL; + + pch = pnext + 1; + if ((pch - extra) >= wrqu->length) return -EINVAL; + data = simple_strtoul(pch, &ptmp, 16); + + ret = 0; + width = width_str[0]; + switch (width) { + case 'b': + // 1 byte + if (data > 0xFF) { + ret = -EINVAL; + break; + } + rtw_write8(padapter, addr, data); + break; + case 'w': + // 2 bytes + if (data > 0xFFFF) { + ret = -EINVAL; + break; + } + rtw_write16(padapter, addr, data); + break; + case 'd': + // 4 bytes + rtw_write32(padapter, addr, data); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* + * Input Format: %s,%d + * %s is width, could be + * "b" for 1 byte + * "w" for WORD (2 bytes) + * "dw" for DWORD (4 bytes) + * %d is address(offset) + * + * Return: + * %d for data readed + */ +static int rtw_mp_read_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char input[wrqu->length]; + char *pch, *pnext, *ptmp; + char *width_str; + char width; + char data[20],tmp[20]; + u32 addr; + //u32 *data = (u32*)extra; + u32 ret, i=0, j=0, strtout=0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (wrqu->length > 128) return -EFAULT; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(data, 0, 20); + _rtw_memset(tmp, 0, 20); + _rtw_memset(extra, 0, wrqu->length); + + pch = input; + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) return -EINVAL; + *pnext = 0; + width_str = pch; + + pch = pnext + 1; + if ((pch - input) >= wrqu->length) return -EINVAL; + + addr = simple_strtoul(pch, &ptmp, 16); + if (addr > 0x3FFF) return -EINVAL; + + ret = 0; + width = width_str[0]; + switch (width) { + case 'b': + // 1 byte + // *(u8*)data = rtw_read8(padapter, addr); + sprintf(extra, "%d\n", rtw_read8(padapter, addr)); + wrqu->length = strlen(extra); + break; + case 'w': + // 2 bytes + //*(u16*)data = rtw_read16(padapter, addr); + sprintf(data, "%04d\n", rtw_read16(padapter, addr)); + for( i=0 ; i <= strlen(data) ; i++) + { + if( i%2==0 ) + { + tmp[j]=' '; + j++; + } + if ( data[i] != '\0' ) + tmp[j] = data[i]; + + j++; + } + pch = tmp; + DBG_871X("pch=%s",pch); + + while( *pch != '\0' ) + { + pnext = strpbrk(pch, " "); + pnext++; + if ( *pnext != '\0' ) + { + strtout = simple_strtoul (pnext , &ptmp, 16); + sprintf( extra, "%s %d" ,extra ,strtout ); + } + else{ + break; + } + pch = pnext; + } + wrqu->length = 6; + break; + case 'd': + // 4 bytes + //*data = rtw_read32(padapter, addr); + sprintf(data, "%08x", rtw_read32(padapter, addr)); + //add read data format blank + for( i=0 ; i <= strlen(data) ; i++) + { + if( i%2==0 ) + { + tmp[j]=' '; + j++; + } + tmp[j] = data[i]; + j++; + } + pch = tmp; + DBG_871X("pch=%s",pch); + + while( *pch != '\0' ) + { + pnext = strpbrk(pch, " "); + pnext++; + if ( *pnext != '\0' ) + { + strtout = simple_strtoul (pnext , &ptmp, 16); + sprintf( extra, "%s %d" ,extra ,strtout ); + } + else{ + break; + } + pch = pnext; + } + wrqu->length = strlen(extra); + break; + + default: + wrqu->length = 0; + ret = -EINVAL; + break; + + } + + return ret; +} + +/* + * Input Format: %d,%x,%x + * %d is RF path, should be smaller than MAX_RF_PATH_NUMS + * 1st %x is address(offset) + * 2st %x is data to write + */ + static int rtw_mp_write_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ +/*static int rtw_mp_write_rf(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +*/ + u32 path, addr, data; + int ret; + PADAPTER padapter = rtw_netdev_priv(dev); + + + ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data); + if (ret < 3) return -EINVAL; + + if (path >= MAX_RF_PATH_NUMS) return -EINVAL; + if (addr > 0xFF) return -EINVAL; + if (data > 0xFFFFF) return -EINVAL; + _rtw_memset(extra, 0, wrqu->length); + + write_rfreg(padapter, path, addr, data); + + sprintf(extra, "write_rf completed \n"); + + return 0; +} + +/* + * Input Format: %d,%x + * %d is RF path, should be smaller than MAX_RF_PATH_NUMS + * %x is address(offset) + * + * Return: + * %d for data readed + */ +static int rtw_mp_read_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char input[wrqu->length]; + char *pch, *pnext, *ptmp; + char data[20],tmp[20]; + //u32 *data = (u32*)extra; + u32 path, addr; + u32 ret,i=0 ,j=0,strtou=0; + PADAPTER padapter = rtw_netdev_priv(dev); + + + if (wrqu->length > 128) return -EFAULT; + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + ret = sscanf(input, "%d,%x", &path, &addr); + if (ret < 2) return -EINVAL; + + if (path >= MAX_RF_PATH_NUMS) return -EINVAL; + if (addr > 0xFF) return -EINVAL; + + _rtw_memset(extra, 0, wrqu->length); + + //*data = read_rfreg(padapter, path, addr); + sprintf(data, "%08x", read_rfreg(padapter, path, addr)); + //add read data format blank + for( i=0 ; i <= strlen(data) ; i++) + { + if( i%2==0 ) + { + tmp[j]=' '; + j++; + } + tmp[j] = data[i]; + j++; + } + pch = tmp; + DBG_871X("pch=%s",pch); + + while( *pch != '\0' ) + { + pnext = strpbrk(pch, " "); + pnext++; + if ( *pnext != '\0' ) + { + strtou = simple_strtoul (pnext , &ptmp, 16); + sprintf( extra, "%s %d" ,extra ,strtou ); + } + else{ + break; + } + pch = pnext; + } + wrqu->length = strlen(extra); + + return 0; +} + +static int rtw_mp_start(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 val8; + PADAPTER padapter = rtw_netdev_priv(dev); + + + if (padapter->registrypriv.mp_mode == 0) + return -EPERM; + + if (padapter->mppriv.mode == MP_OFF) { + if (mp_start_test(padapter) == _FAIL) + return -EPERM; + padapter->mppriv.mode = MP_ON; + } + + return 0; +} + +static int rtw_mp_stop(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + + + if (padapter->mppriv.mode != MP_OFF) { + mp_stop_test(padapter); + padapter->mppriv.mode = MP_OFF; + } + + return 0; +} + +extern int wifirate2_ratetbl_inx(unsigned char rate); + +static int rtw_mp_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 rate = MPT_RATE_1M; + u8 input[wrqu->length]; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + rate = rtw_atoi(input); + sprintf( extra, "Set data rate to %d" , rate ); + + if(rate <= 0x7f) + rate = wifirate2_ratetbl_inx( (u8)rate); + else + rate =(rate-0x80+MPT_RATE_MCS0); + + //DBG_871X("%s: rate=%d\n", __func__, rate); + + if (rate >= MPT_RATE_LAST ) + return -EINVAL; + + padapter->mppriv.rateidx = rate; + Hal_SetDataRate(padapter); + + wrqu->length = strlen(extra) + 1; + return 0; +} + +static int rtw_mp_channel(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + u32 channel = 1; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + channel = rtw_atoi(input); + //DBG_871X("%s: channel=%d\n", __func__, channel); + sprintf( extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel ); + + padapter->mppriv.channel = channel; + Hal_SetChannel(padapter); + + wrqu->length = strlen(extra) + 1; + return 0; +} + +static int rtw_mp_bandwidth(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 bandwidth=0, sg=0; + //u8 buffer[40]; + PADAPTER padapter = rtw_netdev_priv(dev); + //if (copy_from_user(buffer, (void*)wrqu->data.pointer, wrqu->data.length)) + // return -EFAULT; + + //DBG_871X("%s:iwpriv in=%s\n", __func__, extra); + + sscanf(extra, "40M=%d,shortGI=%d", &bandwidth, &sg); + + if (bandwidth != HT_CHANNEL_WIDTH_40) + bandwidth = HT_CHANNEL_WIDTH_20; + + //DBG_871X("%s: bw=%d sg=%d \n", __func__, bandwidth , sg); + + padapter->mppriv.bandwidth = (u8)bandwidth; + padapter->mppriv.preamble = sg; + + SetBandwidth(padapter); + + return 0; +} + +static int rtw_mp_txpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 idx_a=0,idx_b=0; + u8 input[wrqu->length]; + + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + sscanf(input,"patha=%d,pathb=%d",&idx_a,&idx_b); + //DBG_871X("%s: tx_pwr_idx_a=%x b=%x\n", __func__, idx_a, idx_b); + + sprintf( extra, "Set power level path_A:%d path_B:%d", idx_a , idx_b ); + padapter->mppriv.txpoweridx = (u8)idx_a; + padapter->mppriv.txpoweridx_b = (u8)idx_b; + + Hal_SetAntennaPathPower(padapter); + + wrqu->length = strlen(extra) + 1; + return 0; +} + +static int rtw_mp_ant_tx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 i; + u8 input[wrqu->length]; + u16 antenna = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + //DBG_871X("%s: input=%s\n", __func__, input); + + sprintf( extra, "switch Tx antenna to %s", input ); + + for (i=0; i < strlen(input); i++) + { + switch(input[i]) + { + case 'a' : + antenna|=ANTENNA_A; + break; + case 'b': + antenna|=ANTENNA_B; + break; + } + } + //antenna |= BIT(extra[i]-'a'); + //DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_tx = antenna; + //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx); + + Hal_SetAntenna(padapter); + + wrqu->length = strlen(extra) + 1; + return 0; +} + +static int rtw_mp_ant_rx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 i; + u16 antenna = 0; + u8 input[wrqu->length]; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + //DBG_871X("%s: input=%s\n", __func__, input); + _rtw_memset(extra, 0, wrqu->length); + + sprintf( extra, "switch Rx antenna to %s", input ); + + for (i=0; i < strlen(input); i++) { + + switch( input[i] ) + { + case 'a' : + antenna|=ANTENNA_A; + break; + case 'b': + antenna|=ANTENNA_B; + break; + } + } + + //DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_rx = antenna; + //DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx); + Hal_SetAntenna(padapter); + wrqu->length = strlen(extra); + + return 0; +} + +static int rtw_mp_ctx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1; + u32 bStartTest = 1; + u32 count = 0; + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + + PADAPTER padapter = rtw_netdev_priv(dev); + + + pmp_priv = &padapter->mppriv; + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s: in=%s\n", __func__, extra); + + countPkTx = strncmp(extra, "count=", 5); // strncmp TRUE is 0 + cotuTx = strncmp(extra, "background", 20); + CarrSprTx = strncmp(extra, "background,cs", 20); + scTx = strncmp(extra, "background,sc", 20); + sgleTx = strncmp(extra, "background,stone", 20); + pkTx = strncmp(extra, "background,pkt", 20); + stop = strncmp(extra, "stop", 5); + sscanf(extra, "count=%d,pkt", &count); + + //DBG_871X("%s: count=%d countPkTx=%d cotuTx=%d CarrSprTx=%d scTx=%d sgleTx=%d pkTx=%d stop=%d\n", __func__, count, countPkTx, cotuTx, CarrSprTx, pkTx, sgleTx, scTx, stop); + _rtw_memset(extra, '\0', sizeof(extra)); + + if (stop == 0) { + bStartTest = 0; // To set Stop + pmp_priv->tx.stop = 1; + sprintf( extra, "Stop continuous Tx"); + } else { + bStartTest = 1; + if (pmp_priv->mode != MP_ON) { + if (pmp_priv->tx.stop != 1) { + DBG_871X("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode); + return -EFAULT; + } + } + } + + if (pkTx == 0 || countPkTx == 0) + pmp_priv->mode = MP_PACKET_TX; + if (sgleTx == 0) + pmp_priv->mode = MP_SINGLE_TONE_TX; + if (cotuTx == 0) + pmp_priv->mode = MP_CONTINUOUS_TX; + if (CarrSprTx == 0) + pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX; + if (scTx == 0) + pmp_priv->mode = MP_SINGLE_CARRIER_TX; + + switch (pmp_priv->mode) + { + case MP_PACKET_TX: + + //DBG_871X("%s:pkTx %d\n", __func__,bStartTest); + if (bStartTest == 0) + { + pmp_priv->tx.stop = 1; + pmp_priv->mode = MP_ON; + sprintf( extra, "Stop continuous Tx"); + } + else if (pmp_priv->tx.stop == 1) + { + sprintf( extra, "Start continuous DA=ffffffffffff len=1500 count=%u,\n",count); + //DBG_871X("%s:countPkTx %d\n", __func__,count); + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = count; + pmp_priv->tx.payload = 2; + pattrib = &pmp_priv->tx.attrib; + pattrib->pktlen = 1460; + _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN); + SetPacketTx(padapter); + } + else { + //DBG_871X("%s: pkTx not stop\n", __func__); + return -EFAULT; + } + wrqu->length = strlen(extra); + return 0; + + case MP_SINGLE_TONE_TX: + //DBG_871X("%s: sgleTx %d \n", __func__, bStartTest); + if (bStartTest != 0){ + sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes."); + + } + Hal_SetSingleToneTx(padapter, (u8)bStartTest); + break; + + case MP_CONTINUOUS_TX: + DBG_871X("%s: cotuTx %d\n", __func__, bStartTest); + if (bStartTest != 0){ + sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes."); + } + Hal_SetContinuousTx(padapter, (u8)bStartTest); + break; + + case MP_CARRIER_SUPPRISSION_TX: + //DBG_871X("%s: CarrSprTx %d\n", __func__, bStartTest); + if (bStartTest != 0){ + if( pmp_priv->rateidx <= MPT_RATE_11M ) + { + sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes."); + }else + sprintf( extra, "Specify carrier suppression but not CCK rate"); + } + Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest); + break; + + case MP_SINGLE_CARRIER_TX: + //DBG_871X("%s: scTx %d\n", __func__, bStartTest); + if (bStartTest != 0){ + sprintf( extra, "Start continuous DA=ffffffffffff len=1500 \n infinite=yes."); + } + Hal_SetSingleCarrierTx(padapter, (u8)bStartTest); + break; + + default: + //DBG_871X("%s:No Match MP_MODE\n", __func__); + sprintf( extra, "Error! Continuous-Tx is not on-going."); + return -EFAULT; + } + + if (bStartTest) { + struct mp_priv *pmp_priv = &padapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + //DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(padapter); + } else { + pmp_priv->mode = MP_ON; + } + + wrqu->length = strlen(extra); + return 0; +} + +static int rtw_mp_arx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 bStartRx=0,bStopRx=0; + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s: %s\n", __func__, input); + + bStartRx = (strncmp(input, "start", 5)==0)?1:0; // strncmp TRUE is 0 + bStopRx = (strncmp(input, "stop", 5)==0)?1:0; // strncmp TRUE is 0 + SetPacketRx(padapter, bStartRx); + + if(bStartRx) + { + sprintf( extra, "start"); + wrqu->length = strlen(extra) + 1; + } + else if(bStopRx) + { + sprintf( extra, "Received packet OK:%d CRC error:%d",padapter->mppriv.rx_pktcount, + padapter->mppriv.rx_crcerrpktcount); + wrqu->length = strlen(extra) + 1; + } + + + return 0; +} + +static int rtw_mp_trx_query(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 txok,txfail,rxok,rxfail; + PADAPTER padapter = rtw_netdev_priv(dev); + //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + // return -EFAULT; + + txok=padapter->mppriv.tx.sended; + txfail=0; + rxok = padapter->mppriv.rx_pktcount; + rxfail = padapter->mppriv.rx_crcerrpktcount; + + _rtw_memset(extra, '\0', 128); + + sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ", txok, txfail,rxok,rxfail); + + wrqu->length=strlen(extra)+1; + + return 0; +} + +static int rtw_mp_pwrtrk(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 enable; + u32 thermal; + s32 ret; + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(extra, 0, wrqu->length); + + enable = 1; + if (wrqu->length > 1) { // not empty string + if (strncmp(input, "stop", 4) == 0) + { + enable = 0; + sprintf(extra, "mp tx power tracking stop"); + } + else if (sscanf(input, "ther=%d", &thermal)) { + ret = Hal_SetThermalMeter(padapter, (u8)thermal); + if (ret == _FAIL) return -EPERM; + sprintf(extra, "mp tx power tracking start,target value=%d ok ",thermal); + }else { + return -EINVAL; + } + } + + ret = Hal_SetPowerTracking(padapter, enable); + if (ret == _FAIL) return -EPERM; + + wrqu->length = strlen(extra); + + return 0; +} + +static int rtw_mp_psd(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + strcpy(extra,input); + + wrqu->length = mp_query_psd(padapter, extra); + + return 0; +} + +static int rtw_mp_thermal(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 val; + u16 bwrite=1; + #ifdef CONFIG_RTL8192C + u16 addr=0x78; + #endif + #ifdef CONFIG_RTL8192D + u16 addr=0xc3; + #endif + u16 cnt=1; + u16 max_available_size=0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + //DBG_871X("print extra %s \n",extra); + + bwrite = strncmp(extra, "write", 6); // strncmp TRUE is 0 + + Hal_GetThermalMeter(padapter, &val); + + if( bwrite == 0 ) + { + //DBG_871X("to write val:%d",val); + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if( 2 > max_available_size ) + { + DBG_871X("no available efuse!\n"); + return -EFAULT; + } + if ( rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL ) + { + DBG_871X("rtw_efuse_map_write error \n"); + return -EFAULT; + } + else + { + sprintf(extra, " efuse write ok :%d", val); + } + } + else + { + sprintf(extra, "%d", val); + } + wrqu->length = strlen(extra); + + return 0; +} + +static int rtw_mp_reset_stats(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + PADAPTER padapter = rtw_netdev_priv(dev); + + pmp_priv = &padapter->mppriv; + + pmp_priv->tx.sended = 0; + padapter->mppriv.rx_pktcount = 0; + padapter->mppriv.rx_crcerrpktcount = 0; + + return 0; +} + +static int rtw_mp_dump(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + u32 value; + u8 rf_type,path_nums = 0; + u32 i,j=1,path; + PADAPTER padapter = rtw_netdev_priv(dev); + + pmp_priv = &padapter->mppriv; + + + //if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + // return -EFAULT; + + if ( strncmp(extra, "all", 4)==0 ) + { + DBG_871X("\n======= MAC REG =======\n"); + for ( i=0x0;i<0x300;i+=4 ) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } + for( i=0x400;i<0x800;i+=4 ) + { + if(j%4==1) DBG_871X("0x%02x",i); + DBG_871X(" 0x%08x ",rtw_read32(padapter,i)); + if((j++)%4 == 0) DBG_871X("\n"); + } + + i,j=1; + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + DBG_871X("\n======= RF REG =======\n"); + if(( RF_1T2R == rf_type ) ||( RF_1T1R ==rf_type )) + path_nums = 1; + else + path_nums = 2; + + for(path=0;pathlength]; + u32 valxcap; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s:iwpriv in=%s\n", __func__, input); + + sscanf(input, "xcap=%d", &valxcap); + + if (!IS_HARDWARE_TYPE_8192D(padapter)) + return 0; +#ifdef CONFIG_RTL8192D + Hal_ProSetCrystalCap( padapter , valxcap ); +#endif + + sprintf( extra, "Set xcap=%d",valxcap ); + wrqu->length = strlen(extra) + 1; + +return 0; + +} + + +/* update Tx AGC offset */ +static int rtw_mp_antBdiff(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + + + // MPT_ProSetTxAGCOffset + return 0; +} + + +static int rtw_mp_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + u32 subcmd = wrqu->flags; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (padapter == NULL) + { + return -ENETDOWN; + } + + //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK); + + if (extra == NULL) + { + wrqu->length = 0; + return -EIO; + } + + switch(subcmd) + { + case WRITE_REG : + rtw_mp_write_reg (dev,info,wrqu,extra); + break; + + case WRITE_RF: + rtw_mp_write_rf (dev,info,wrqu,extra); + break; + + case MP_START: + DBG_871X("set case mp_start \n"); + rtw_mp_start (dev,info,wrqu,extra); + break; + + case MP_STOP: + DBG_871X("set case mp_stop \n"); + rtw_mp_stop (dev,info,wrqu,extra); + break; + + case MP_BANDWIDTH: + DBG_871X("set case mp_bandwidth \n"); + rtw_mp_bandwidth (dev,info,wrqu,extra); + break; + + case MP_RESET_STATS: + DBG_871X("set case MP_RESET_STATS \n"); + rtw_mp_reset_stats (dev,info,wrqu,extra); + break; + + case EFUSE_SET: + DBG_871X("efuse set \n"); + rtw_mp_efuse_set (dev,info,wdata,extra); + break; + + } + + + return 0; +} + + +static int rtw_mp_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + u32 subcmd = wrqu->flags; + PADAPTER padapter = rtw_netdev_priv(dev); + + //DBG_871X("in mp_get extra= %s \n",extra); + + if (padapter == NULL) + { + return -ENETDOWN; + } + if (extra == NULL) + { + wrqu->length = 0; + return -EIO; + } + + switch(subcmd) + { + case MP_PHYPARA: + DBG_871X("mp_get MP_PHYPARA \n"); + rtw_mp_phypara(dev,info,wrqu,extra); + break; + + case MP_CHANNEL: + DBG_871X("set case mp_channel \n"); + rtw_mp_channel (dev,info,wrqu,extra); + break; + + case READ_REG: + DBG_871X("mp_get READ_REG \n"); + rtw_mp_read_reg (dev,info,wrqu,extra); + break; + case READ_RF: + DBG_871X("mp_get READ_RF \n"); + rtw_mp_read_rf (dev,info,wrqu,extra); + break; + + case MP_RATE: + DBG_871X("set case mp_rate \n"); + rtw_mp_rate (dev,info,wrqu,extra); + break; + + case MP_TXPOWER: + DBG_871X("set case MP_TXPOWER \n"); + rtw_mp_txpower (dev,info,wrqu,extra); + break; + + case MP_ANT_TX: + DBG_871X("set case MP_ANT_TX \n"); + rtw_mp_ant_tx (dev,info,wrqu,extra); + break; + + case MP_ANT_RX: + DBG_871X("set case MP_ANT_RX \n"); + rtw_mp_ant_rx (dev,info,wrqu,extra); + break; + + case MP_QUERY: + DBG_871X("mp_get mp_query MP_QUERY \n"); + rtw_mp_trx_query(dev,info,wrqu,extra); + break; + + case MP_CTX: + DBG_871X("set case MP_CTX \n"); + rtw_mp_ctx (dev,info,wrqu,extra); + break; + + case MP_ARX: + DBG_871X("set case MP_ARX \n"); + rtw_mp_arx (dev,info,wrqu,extra); + break; + + case EFUSE_GET: + DBG_871X("efuse get EFUSE_GET \n"); + rtw_mp_efuse_get(dev,info,wdata,extra); + break; + + case MP_DUMP: + DBG_871X("set case MP_DUMP \n"); + rtw_mp_dump (dev,info,wrqu,extra); + break; + case MP_PSD: + DBG_871X("set case MP_PSD \n"); + rtw_mp_psd (dev,info,wrqu,extra); + break; + + case MP_THER: + DBG_871X("set case MP_THER \n"); + rtw_mp_thermal (dev,info,wrqu,extra); + break; + + case MP_PWRTRK: + DBG_871X("set case MP_PWRTRK \n"); + rtw_mp_pwrtrk (dev,info,wrqu,extra); + break; + } + +return 0; +} + +#endif //#if defined(CONFIG_MP_INCLUDED) && defined(CONFIG_MP_IWPRIV_SUPPORT) + +static int rtw_wfd_tdls_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if ( extra[ 0 ] == '0' ) + { + padapter->wdinfo.wfd_tdls_enable = 0; + } + else + { + padapter->wdinfo.wfd_tdls_enable = 1; + } + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_weaksec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + u8 i, j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if ( extra[ 0 ] == '0' ) + { + padapter->wdinfo.wfd_tdls_weaksec = 0; + } + else + { + padapter->wdinfo.wfd_tdls_weaksec = 1; + } +#endif + + return ret; +} + + +static int rtw_tdls_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + _irqL irqL; + _list *plist, *phead; + s32 index; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 tdls_sta[NUM_STA][ETH_ALEN]; + u8 empty_hwaddr[ETH_ALEN] = { 0x00 }; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta)); + + if ( extra[ 0 ] == '0' ) + { + ptdlsinfo->enable = 0; + + if(pstapriv->asoc_sta_count==1) + return ret; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for(index=0; index< NUM_STA; index++) + { + phead = &(pstapriv->sta_hash[index]); + 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(psta->tdls_sta_state != TDLS_STATE_NONE) + { + _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN); + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for(index=0; index< NUM_STA; index++) + { + if( !_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN) ) + { + printk("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index])); + issue_tdls_teardown(padapter, tdls_sta[index]); + } + } + rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR); + rtw_reset_tdls_info(padapter); + } + else if ( extra[ 0 ] == '1' ) + { + ptdlsinfo->enable = 1; + } +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_setup(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + u8 i, j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 mac_addr[ETH_ALEN]; + +#ifdef CONFIG_WFD + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif // CONFIG_WFD + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + +#ifdef CONFIG_WFD + if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm ) + { + // Weak Security situation with AP. + if ( 0 == pwdinfo->wfd_tdls_weaksec ) + { + // Can't send the tdls setup request out!! + DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ ); + } + else + { + issue_tdls_setup_req(padapter, mac_addr); + } + } + else +#endif // CONFIG_WFD + { + issue_tdls_setup_req(padapter, mac_addr); + } +#endif + + return ret; +} + +static int rtw_tdls_teardown(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + u8 i,j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sta_info *ptdls_sta = NULL; + u8 mac_addr[ETH_ALEN]; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), mac_addr); + + if(ptdls_sta != NULL) + { + ptdls_sta->stat_code = _RSON_TDLS_TEAR_UN_RSN_; + issue_tdls_teardown(padapter, mac_addr); + } + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_discovery(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + issue_tdls_dis_req(padapter, NULL); + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_ch_switch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + if( ptdls_sta == NULL ) + return ret; + ptdlsinfo->ch_sensing=1; + + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_INIT_CH_SEN); + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_pson(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 1); + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_psoff(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0); + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_setip(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + u8 i=0, j=0, k=0, tag=0, ip[3] = { 0xff }, *ptr = extra; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1 ); + + + while( i < 4 ) + { + for( j=0; j < 4; j++) + { + if( *( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0' ) + { + if( j == 1 ) + pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag)); + if( j == 2 ) + pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag)); + if( j == 3 ) + pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag)); + + tag += j + 1; + break; + } + } + i++; + } + + printk( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__, + ptdlsinfo->wfd_info->ip_address[0], ptdlsinfo->wfd_info->ip_address[1], + ptdlsinfo->wfd_info->ip_address[2], ptdlsinfo->wfd_info->ip_address[3] + ); + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_getip(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + printk( "[%s]\n", __FUNCTION__); + + sprintf( extra, "\n\n%u.%u.%u.%u\n", + pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], + pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3] + ); + + printk( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__, + pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], + pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3] + ); + + wrqu->data.length = strlen( extra ); + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls_getport(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + printk( "[%s]\n", __FUNCTION__); + + sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport ); + printk( "[%s] remote port = %d\n", __FUNCTION__, pwfd_info->peer_rtsp_ctrlport ); + + wrqu->data.length = strlen( extra ); + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; + +} + +//WFDTDLS, for sigma test +static int rtw_tdls_dis_result(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + printk( "[%s]\n", __FUNCTION__); + + if(ptdlsinfo->dev_discovered == 1 ) + { + sprintf( extra, "\n\nDis=1\n" ); + ptdlsinfo->dev_discovered = 0; + } + + wrqu->data.length = strlen( extra ); + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; + +} + +//WFDTDLS, for sigma test +static int rtw_wfd_tdls_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + printk( "[%s]\n", __FUNCTION__); + + if(ptdlsinfo->setup_state == TDLS_LINKED_STATE ) + { + sprintf( extra, "\n\nStatus=1\n" ); + } + else + { + sprintf( extra, "\n\nStatus=0\n" ); + } + + wrqu->data.length = strlen( extra ); + +#endif //CONFIG_WFD +#endif //CONFIG_TDLS + + return ret; + +} + +static int rtw_tdls_ch_switch_off(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + printk( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + + ptdls_sta->tdls_sta_state |= TDLS_SW_OFF_STATE; +/* + if((ptdls_sta->tdls_sta_state & TDLS_AT_OFF_CH_STATE) && (ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE)){ + pmlmeinfo->tdls_candidate_ch= pmlmeext->cur_channel; + issue_tdls_ch_switch_req(padapter, mac_addr); + DBG_871X("issue tdls ch switch req back to base channel\n"); + } +*/ + +#endif //CONFIG_TDLS + + return ret; +} + +static int rtw_tdls(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + printk( "[%s] extra = %s\n", __FUNCTION__, extra ); + // WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! + if ( _rtw_memcmp( extra, "wfdenable=", 10 ) ) + { + wrqu->data.length -=10; + rtw_wfd_tdls_enable( dev, info, wrqu, &extra[10] ); + return ret; + } + else if ( _rtw_memcmp( extra, "weaksec=", 8 ) ) + { + wrqu->data.length -=8; + rtw_tdls_weaksec( dev, info, wrqu, &extra[8] ); + return ret; + } + else if ( _rtw_memcmp( extra, "tdlsenable=", 11 ) ) + { + wrqu->data.length -=11; + rtw_tdls_enable( dev, info, wrqu, &extra[11] ); + return ret; + } + + if( padapter->tdlsinfo.enable == 0 ) + { + printk("tdls haven't enabled\n"); + return 0; + } + + if ( _rtw_memcmp( extra, "setup=", 6 ) ) + { + wrqu->data.length -=6; + rtw_tdls_setup( dev, info, wrqu, &extra[6] ); + } + else if (_rtw_memcmp( extra, "tear=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_tdls_teardown( dev, info, wrqu, &extra[5] ); + } + else if (_rtw_memcmp( extra, "dis=", 4 ) ) + { + wrqu->data.length -= 4; + rtw_tdls_discovery( dev, info, wrqu, &extra[4] ); + } + else if (_rtw_memcmp( extra, "sw=", 3 ) ) + { + wrqu->data.length -= 3; + rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] ); + } + else if (_rtw_memcmp( extra, "swoff=", 6 ) ) + { + wrqu->data.length -= 6; + rtw_tdls_ch_switch_off( dev, info, wrqu, &extra[6] ); + } + else if (_rtw_memcmp( extra, "pson=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_tdls_pson( dev, info, wrqu, &extra[5] ); + } + else if (_rtw_memcmp( extra, "psoff=", 6 ) ) + { + wrqu->data.length -= 6; + rtw_tdls_psoff( dev, info, wrqu, &extra[6] ); + } +#ifdef CONFIG_WFD + else if (_rtw_memcmp( extra, "setip=", 6 ) ) + { + wrqu->data.length -= 6; + rtw_tdls_setip( dev, info, wrqu, &extra[6] ); + } + else if (_rtw_memcmp( extra, "tprobe=", 6 ) ) + { + issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev)); + } +#endif //CONFIG_WFD + +#endif //CONFIG_TDLS + + return ret; +} + + +static int rtw_tdls_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_WFD + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer ); + + if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) ) + { + rtw_tdls_getip( dev, info, wrqu, extra ); + } + if ( _rtw_memcmp( wrqu->data.pointer, "port", 4 ) ) + { + rtw_tdls_getport( dev, info, wrqu, extra ); + } + + //WFDTDLS, for sigma test + if ( _rtw_memcmp( wrqu->data.pointer, "dis", 3 ) ) + { + rtw_tdls_dis_result( dev, info, wrqu, extra ); + } + if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) ) + { + rtw_wfd_tdls_status( dev, info, wrqu, extra ); + } + +#endif //CONFIG_WFD + + return ret; +} + +static int rtw_pm_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + unsigned mode = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra ); + + if ( _rtw_memcmp( extra, "lps=", 4 ) ) + { + sscanf(extra+4, "%u", &mode); + ret = rtw_pm_set_lps(padapter,mode); + } + else if ( _rtw_memcmp( extra, "ips=", 4 ) ) + { + sscanf(extra+4, "%u", &mode); + ret = rtw_pm_set_ips(padapter,mode); + } + else{ + ret = -EINVAL; + } + + return ret; +} + +#ifdef CONFIG_WOWLAN +static int rtw_wowlan_ctrl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + struct oid_par_priv oid_par; + struct wowlan_ioctl_param *poidparam; + uint status=0; + u16 len; + u8 *pparmbuf = NULL, bset; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + struct iw_point *p = &wrqu->data; + + //DBG_871X("+rtw_wowlan_ctrl\n"); + + //mutex_lock(&ioctl_mutex); + + if ((!p->length) || (!p->pointer)) { + ret = -EINVAL; + goto _rtw_wowlan_ctrl_exit; + } + + pparmbuf = NULL; + bset = (u8)(p->flags & 0xFFFF); + len = p->length; + pparmbuf = (u8*)rtw_malloc(len); + if (pparmbuf == NULL){ + ret = -ENOMEM; + goto _rtw_wowlan_ctrl_exit; + } + + if (copy_from_user(pparmbuf, p->pointer, len)) { + ret = -EFAULT; + goto _rtw_wowlan_ctrl_exit_free; + } + poidparam = (struct wowlan_ioctl_param *)pparmbuf; + + if(padapter->pwrctrlpriv.bSupportRemoteWakeup==_FALSE){ + ret = -EPERM; + DBG_871X("+rtw_wowlan_ctrl: Device didn't support the remote wakeup!!\n"); + goto _rtw_wowlan_ctrl_exit_free; + } + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)poidparam); + + DBG_871X("rtw_wowlan_ctrl: subcode [%d], len[%d], buffer_len[%d]\r\n", + poidparam->subcode, poidparam->len, len); + + if (copy_to_user(p->pointer, pparmbuf, len)) { + ret = -EFAULT; + } + + +_rtw_wowlan_ctrl_exit_free: + //DBG_871X("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam->subcode); + rtw_mfree(pparmbuf, len); +_rtw_wowlan_ctrl_exit: + + + return ret; +} +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_INTEL_WIDI +static int rtw_widi_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + process_intel_widi_cmd(padapter, extra); + + return ret; +} + +static int rtw_widi_set_probe_request(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + u8 *pbuf = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + pbuf = rtw_malloc(sizeof(l2_msg_t)); + if(pbuf) + { + copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length); + //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); + + if( wrqu->data.flags == 0 ) + intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf); + else if( wrqu->data.flags == 1 ) + rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf ); + } + return ret; +} + +#endif // CONFIG_INTEL_WIDI + +#ifdef RTL8723A_SDIO_LOOPBACK +#include + +static s32 initLoopback(PADAPTER padapter) +{ + PLOOPBACKDATA ploopback; + + + if (padapter->ploopback == NULL) { + ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA)); + if (ploopback == NULL) return -ENOMEM; + + _rtw_init_sema(&ploopback->sema, 0); + + ploopback->bstop = _TRUE; + ploopback->cnt = 0; + ploopback->size = 300; + _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg)); + + padapter->ploopback = ploopback; + } + + return 0; +} + +static void freeLoopback(PADAPTER padapter) +{ + PLOOPBACKDATA ploopback; + + + ploopback = padapter->ploopback; + if (ploopback) { + rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA)); + padapter->ploopback = NULL; + } +} + +static s32 initpseudoadhoc(PADAPTER padapter) +{ + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; + s32 err; + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _queue *queue = &pmlmepriv->scanned_queue; + + networkType = Ndis802_11IBSS; + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _enter_critical_bh(&queue->lock, &irqL); + err = rtw_set_802_11_infrastructure_mode(padapter, networkType); + _exit_critical_bh(&queue->lock, &irqL); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + if (err == _FALSE) return _FAIL; + + err = rtw_setopmode_cmd(padapter, networkType); + if (err == _FAIL) return _FAIL; + + return _SUCCESS; +} + +static s32 createpseudoadhoc(PADAPTER padapter) +{ + NDIS_802_11_AUTHENTICATION_MODE authmode; + struct mlme_priv *pmlmepriv; + NDIS_802_11_SSID *passoc_ssid; + WLAN_BSSID_EX *pdev_network; + u8 *pibss; + u8 ssid[] = "pseduo_ad-hoc"; + s32 err; + _irqL irqL; + + + pmlmepriv = &padapter->mlmepriv; + + authmode = Ndis802_11AuthModeOpen; + err = rtw_set_802_11_authentication_mode(padapter, authmode); + if (err == _FALSE) return _FAIL; + + passoc_ssid = &pmlmepriv->assoc_ssid; + _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID)); + passoc_ssid->SsidLength = sizeof(ssid) - 1; + _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength); + + pdev_network = &padapter->registrypriv.dev_network; + pibss = padapter->registrypriv.dev_network.MacAddress; + _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(padapter); + rtw_generate_random_ibss(pibss); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +#if 0 + err = rtw_createbss_cmd(padapter); + if (err == _FAIL) return _FAIL; +#else +{ + struct wlan_network *pcur_network; + struct sta_info *psta; + + //3 create a new psta + pcur_network = &pmlmepriv->cur_network; + + //clear psta in the cur_network, if any + psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + psta = rtw_alloc_stainfo(&padapter->stapriv, pibss); + if (psta == NULL) return _FAIL; + + //3 join psudo AdHoc + pcur_network->join_res = 1; + pcur_network->aid = psta->aid = 1; + _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network)); + + // set msr to WIFI_FW_ADHOC_STATE +#if 0 + Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE); +#else + { + u8 val8; + + val8 = rtw_read8(padapter, MSR); + val8 &= 0xFC; // clear NETYPE0 + val8 |= WIFI_FW_ADHOC_STATE & 0x3; + rtw_write8(padapter, MSR, val8); + } +#endif +} +#endif + + return _SUCCESS; +} + +extern void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc); +extern void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); + +static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size) +{ + struct xmit_priv *pxmitpriv; + struct xmit_frame *pframe; + struct xmit_buf *pxmitbuf; + struct pkt_attrib *pattrib; + struct tx_desc *desc; + u8 *pkt_start, *pkt_end, *ptr; + struct rtw_ieee80211_hdr *hdr; + s32 bmcast; + _irqL irqL; + + + if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL; + + pxmitpriv = &padapter->xmitpriv; + pframe = NULL; + + //2 1. allocate xmit frame + pframe = rtw_alloc_xmitframe(pxmitpriv); + if (pframe == NULL) return NULL; + pframe->padapter = padapter; + + //2 2. allocate xmit buffer + _enter_critical_bh(&pxmitpriv->lock, &irqL); + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + if (pxmitbuf == NULL) { + rtw_free_xmitframe(pxmitpriv, pframe); + return NULL; + } + + pframe->pxmitbuf = pxmitbuf; + pframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pframe; + + //2 3. update_attrib() + pattrib = &pframe->attrib; + + // init xmitframe attribute + _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib)); + + pattrib->ether_type = 0x8723; + _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN); + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); +// pattrib->pctrl = 0; +// pattrib->dhcp_pkt = 0; +// pattrib->pktlen = 0; + pattrib->ack_policy = 0; +// pattrib->pkt_hdrlen = ETH_HLEN; + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA; + pattrib->priority = 0; + pattrib->qsel = pattrib->priority; +// do_queue_select(padapter, pattrib); + pattrib->nr_frags = 1; + pattrib->encrypt = 0; + pattrib->bswenc = _FALSE; + pattrib->qos_en = _FALSE; + + bmcast = IS_MCAST(pattrib->ra); + if (bmcast) { + pattrib->mac_id = 1; + pattrib->psta = rtw_get_bcmc_stainfo(padapter); + } else { + pattrib->mac_id = 0; + pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + } + + pattrib->pktlen = size; + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; + + //2 4. fill TX descriptor + desc = (struct tx_desc*)pframe->buf_addr; + _rtw_memset(desc, 0, TXDESC_SIZE); + + rtl8723a_fill_default_txdesc(pframe, (u8*)desc); + + // Hw set sequence number + ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable +// ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL + + ((PTXDESC)desc)->disdatafb = 1; + + // convert to little endian + desc->txdw0 = cpu_to_le32(desc->txdw0); + desc->txdw1 = cpu_to_le32(desc->txdw1); + desc->txdw2 = cpu_to_le32(desc->txdw2); + desc->txdw3 = cpu_to_le32(desc->txdw3); + desc->txdw4 = cpu_to_le32(desc->txdw4); + desc->txdw5 = cpu_to_le32(desc->txdw5); + desc->txdw6 = cpu_to_le32(desc->txdw6); + desc->txdw7 = cpu_to_le32(desc->txdw7); +#ifdef CONFIG_PCI_HCI + desc->txdw8 = cpu_to_le32(desc->txdw8); + desc->txdw9 = cpu_to_le32(desc->txdw9); + desc->txdw10 = cpu_to_le32(desc->txdw10); + desc->txdw11 = cpu_to_le32(desc->txdw11); + desc->txdw12 = cpu_to_le32(desc->txdw12); + desc->txdw13 = cpu_to_le32(desc->txdw13); + desc->txdw14 = cpu_to_le32(desc->txdw14); + desc->txdw15 = cpu_to_le32(desc->txdw15); +#endif + + rtl8723a_cal_txdesc_chksum(desc); + + //2 5. coalesce + pkt_start = pframe->buf_addr + TXDESC_SIZE; + pkt_end = pkt_start + pattrib->last_txcmdsz; + + //3 5.1. make wlan header, make_wlanhdr() + hdr = (struct rtw_ieee80211_hdr *)pkt_start; + SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); + _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA + _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA + _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID + + //3 5.2. make payload + ptr = pkt_start + pattrib->hdrlen; + get_random_bytes(ptr, pkt_end - ptr); + + pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; + pxmitbuf->ptail += pxmitbuf->len; + + return pframe; +} + +static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe) +{ + struct xmit_priv *pxmitpriv; + struct xmit_buf *pxmitbuf; + + + pxmitpriv = &padapter->xmitpriv; + pxmitbuf = pframe->pxmitbuf; + + rtw_free_xmitframe(pxmitpriv, pframe); + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); +} + +extern u32 get_txfifo_hwaddr(struct xmit_frame *pxmitframe); + +thread_return lbk_thread(thread_context context) +{ + s32 err; + PADAPTER padapter; + PLOOPBACKDATA ploopback; + struct xmit_frame *pxmitframe; + u32 cnt, ok, fail, i, headerlen; + u32 pktsize; + u32 ff_hwaddr; + + + padapter = (PADAPTER)context; + ploopback = padapter->ploopback; + if (ploopback == NULL) return -1; + cnt = 0; + ok = 0; + fail = 0; + + daemonize("%s", "RTW_LBK_THREAD"); + allow_signal(SIGTERM); + + do { + if (ploopback->size == 0) { + get_random_bytes(&pktsize, 4); + pktsize = (pktsize % 1535) + 1; // 1~1535 + } else + pktsize = ploopback->size; + + pxmitframe = createloopbackpkt(padapter, pktsize); + if (pxmitframe == NULL) { + sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!"); + break; + } + + ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz; + _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize); + + ff_hwaddr = get_txfifo_hwaddr(pxmitframe); + rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, ploopback->txbuf); + cnt++; + + _rtw_down_sema(&ploopback->sema); + +{ + PHAL_DATA_TYPE phal; + struct recv_stat *prxstat; + struct recv_stat report; + PRXREPORT prxreport; + u32 drvinfosize; + u32 rxpktsize; + u8 fcssize; + + prxstat = (struct recv_stat*)ploopback->rxbuf; + report.rxdw0 = le32_to_cpu(prxstat->rxdw0); + report.rxdw1 = le32_to_cpu(prxstat->rxdw1); + report.rxdw2 = le32_to_cpu(prxstat->rxdw2); + report.rxdw3 = le32_to_cpu(prxstat->rxdw3); + report.rxdw4 = le32_to_cpu(prxstat->rxdw4); + report.rxdw5 = le32_to_cpu(prxstat->rxdw5); + + prxreport = (PRXREPORT)&report; + drvinfosize = prxreport->drvinfosize << 3; + rxpktsize = prxreport->pktlen; + + phal = GET_HAL_DATA(padapter); + if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN; + else fcssize = 0; + + if ((ploopback->txsize - TXDESC_SIZE) != (rxpktsize - fcssize)) { + printk("%s: cnt=%d, size not match! tx=%d rx=%d\n", + __func__, i, ploopback->txsize - TXDESC_SIZE, + rxpktsize - fcssize); + err = _FALSE; + } else { + err = _rtw_memcmp(ploopback->txbuf + TXDESC_SIZE,\ + ploopback->rxbuf + RXDESC_SIZE + drvinfosize,\ + ploopback->txsize - TXDESC_SIZE); + } +} + + if (err == _TRUE) + ok++; + else + fail++; + + ploopback->txsize = 0; + _rtw_memset(ploopback->txbuf, 0, 0x8000); + ploopback->rxsize = 0; + _rtw_memset(ploopback->rxbuf, 0, 0x8000); + + freeloopbackpkt(padapter, pxmitframe); + pxmitframe = NULL; + + if (signal_pending(current)) { + flush_signals(current); + } + + if ((ploopback->bstop == _TRUE) || + ((ploopback->cnt != 0) && (ploopback->cnt == cnt))) + { + u32 ok_rate, fail_rate; + ok_rate = (ok*100)/cnt; + fail_rate = (fail*100)/cnt; + sprintf(ploopback->msg, "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", ok_rate, ok, cnt, fail_rate, fail, cnt); + break; + } + } while (1); + + ploopback->bstop = _TRUE; + + thread_exit(); +} + +static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg) +{ + PLOOPBACKDATA ploopback; + u32 len; + s32 err; + + + ploopback = padapter->ploopback; + + if (ploopback) + { + ploopback->bstop = _TRUE; + len = 0; + do { + len = strlen(ploopback->msg); + if (len) break; + rtw_msleep_os(1); + } while (1); + _rtw_memcpy(pmsg, ploopback->msg, len+1); + freeLoopback(padapter); + return; + } + + // create pseudo ad-hoc connection + err = initpseudoadhoc(padapter); + if (err == _FAIL) { + sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!"); + return; + } + + err = createpseudoadhoc(padapter); + if (err == _FAIL) { + sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!"); + return; + } + + err = initLoopback(padapter); + if (err) { + sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err); + return; + } + + ploopback = padapter->ploopback; + + ploopback->bstop = _FALSE; + ploopback->cnt = cnt; + ploopback->size = size; + ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD"); + if (IS_ERR(padapter->lbkthread)) + { + freeLoopback(padapter); + sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt); + return; + } + + sprintf(pmsg, "loopback start! cnt=%d", cnt); +} + +extern u8 _InitPowerOn(PADAPTER padapter); +extern s32 rtl8723a_FirmwareDownload(PADAPTER padapter); + +static int rtw_test( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + u32 len; + u8 *pbuf, *pch; + char *ptmp; + u8 *delim = ","; + PADAPTER padapter = rtw_netdev_priv(dev); + + + printk("+%s\n", __func__); + len = wrqu->data.length; + + pbuf = (u8*)rtw_zmalloc(len); + if (pbuf == NULL) { + printk("%s: no memory!\n", __func__); + return -ENOMEM; + } + + if (copy_from_user(pbuf, wrqu->data.pointer, len)) { + rtw_mfree(pbuf, len); + printk("%s: copy from user fail!\n", __func__); + return -EFAULT; + } + printk("%s: string=\"%s\"\n", __func__, pbuf); + + ptmp = (char*)pbuf; + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + printk("%s: parameter error(level 1)!\n", __func__); + return -EFAULT; + } + +#ifdef RTL8723A_SDIO_LOOPBACK + if (strcmp(pch, "loopback") == 0) + { + s32 cnt = 0; + u32 size = 64; + + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + printk("%s: parameter error(level 2)!\n", __func__); + return -EFAULT; + } + + sscanf(pch, "%d", &cnt); + printk("%s: loopback cnt=%d\n", __func__, cnt); + + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + printk("%s: parameter error(level 2)!\n", __func__); + return -EFAULT; + } + + sscanf(pch, "%d", &size); + printk("%s: loopback size=%d\n", __func__, size); + + loopbackTest(padapter, cnt, size, extra); + wrqu->data.length = strlen(extra) + 1; + + rtw_mfree(pbuf, len); + return 0; + } +#endif + + if (strcmp(pch, "poweron") == 0) + { + s32 ret; + + ret = _InitPowerOn(padapter); + if (_FAIL == ret) + printk("%s: power on FAIL!\n", __func__); + else + printk("%s: power on OK.\n", __func__); + + rtw_mfree(pbuf, len); + return 0; + } + + if (strcmp(pch, "dlfw") == 0) + { + s32 ret; + + ret = rtl8723a_FirmwareDownload(padapter); + if (_FAIL == ret) + printk("%s: download FW FAIL!\n", __func__); + else + printk("%s: download FW OK.\n", __func__); + + rtw_mfree(pbuf, len); + return 0; + } + + rtw_mfree(pbuf, len); + return 0; +} +#else +static int rtw_test( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + printk("%s\n", __func__); + return 0; +} +#endif //RTL8723A_SDIO_LOOPBACK + +#include +int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct iwreq *wrq = (struct iwreq *)rq; + int ret=0; + + switch (cmd) + { + case RTL_IOCTL_WPA_SUPPLICANT: + ret = wpa_supplicant_ioctl(dev, &wrq->u.data); + break; +#ifdef CONFIG_AP_MODE + case RTL_IOCTL_HOSTAPD: + ret = rtw_hostapd_ioctl(dev, &wrq->u.data); + break; +#ifdef CONFIG_NO_WIRELESS_HANDLERS + case SIOCSIWMODE: + ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL); + break; +#endif +#endif + case (SIOCDEVPRIVATE+1): + ret = rtw_android_priv_cmd(dev, rq, cmd); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static iw_handler rtw_handlers[] = +{ + NULL, /* SIOCSIWCOMMIT */ + rtw_wx_get_name, /* SIOCGIWNAME */ + dummy, /* SIOCSIWNWID */ + dummy, /* SIOCGIWNWID */ + rtw_wx_set_freq, /* SIOCSIWFREQ */ + rtw_wx_get_freq, /* SIOCGIWFREQ */ + rtw_wx_set_mode, /* SIOCSIWMODE */ + rtw_wx_get_mode, /* SIOCGIWMODE */ + dummy, /* SIOCSIWSENS */ + rtw_wx_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + rtw_wx_get_range, /* SIOCGIWRANGE */ + rtw_wx_set_priv, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ + dummy, /* SIOCSIWSPY */ + dummy, /* SIOCGIWSPY */ + NULL, /* SIOCGIWTHRSPY */ + NULL, /* SIOCWIWTHRSPY */ + rtw_wx_set_wap, /* SIOCSIWAP */ + rtw_wx_get_wap, /* SIOCGIWAP */ + rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */ + dummy, /* SIOCGIWAPLIST -- depricated */ + rtw_wx_set_scan, /* SIOCSIWSCAN */ + rtw_wx_get_scan, /* SIOCGIWSCAN */ + rtw_wx_set_essid, /* SIOCSIWESSID */ + rtw_wx_get_essid, /* SIOCGIWESSID */ + dummy, /* SIOCSIWNICKN */ + rtw_wx_get_nick, /* SIOCGIWNICKN */ + NULL, /* -- hole -- */ + NULL, /* -- hole -- */ + rtw_wx_set_rate, /* SIOCSIWRATE */ + rtw_wx_get_rate, /* SIOCGIWRATE */ + rtw_wx_set_rts, /* SIOCSIWRTS */ + rtw_wx_get_rts, /* SIOCGIWRTS */ + rtw_wx_set_frag, /* SIOCSIWFRAG */ + rtw_wx_get_frag, /* SIOCGIWFRAG */ + dummy, /* SIOCSIWTXPOW */ + dummy, /* SIOCGIWTXPOW */ + dummy, /* SIOCSIWRETRY */ + rtw_wx_get_retry, /* SIOCGIWRETRY */ + rtw_wx_set_enc, /* SIOCSIWENCODE */ + rtw_wx_get_enc, /* SIOCGIWENCODE */ + dummy, /* SIOCSIWPOWER */ + rtw_wx_get_power, /* SIOCGIWPOWER */ + NULL, /*---hole---*/ + NULL, /*---hole---*/ + rtw_wx_set_gen_ie, /* SIOCSIWGENIE */ + NULL, /* SIOCGWGENIE */ + rtw_wx_set_auth, /* SIOCSIWAUTH */ + NULL, /* SIOCGIWAUTH */ + rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ + NULL, /* SIOCGIWENCODEEXT */ + rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ + NULL, /*---hole---*/ +}; + +#if 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"}, + { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set + { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" }, + { MP_NULL, IW_PRIV_TYPE_CHAR | 128, 0,"NULL"},//set + { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" }, + { 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_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ant_rx"}, + { 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_NULL , IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"}, + { MP_PWRTRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk" }, + { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl + + + { 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[] = { + { + SIOCIWFIRSTPRIV + 0x0, + IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" + }, + { + SIOCIWFIRSTPRIV + 0x1, + IW_PRIV_TYPE_CHAR | 0x7FF, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" + }, + { + SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" + }, + { + SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" + }, + { + SIOCIWFIRSTPRIV + 0x4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" + }, + { + SIOCIWFIRSTPRIV + 0x5, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" + }, + { + SIOCIWFIRSTPRIV + 0x6, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" + }, +//for PLATFORM_MT53XX + { + SIOCIWFIRSTPRIV + 0x7, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" + }, + { + SIOCIWFIRSTPRIV + 0x8, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" + }, + { + SIOCIWFIRSTPRIV + 0x9, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" + }, + +//for RTK_DMP_PLATFORM + { + SIOCIWFIRSTPRIV + 0xA, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" + }, + + { + SIOCIWFIRSTPRIV + 0xB, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" + }, + { + SIOCIWFIRSTPRIV + 0xC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" + }, + { + SIOCIWFIRSTPRIV + 0xD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" + }, +#ifdef CONFIG_WOWLAN + { + SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl" + }, +#endif // CONFIG_WOWLAN + { + SIOCIWFIRSTPRIV + 0x10, + IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set" + }, + { + SIOCIWFIRSTPRIV + 0x11, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get" + }, + { + SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL" + }, + { + SIOCIWFIRSTPRIV + 0x13, + IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2" + }, + { + SIOCIWFIRSTPRIV + 0x14, + IW_PRIV_TYPE_CHAR | 64, 0, "tdls" + }, + { + SIOCIWFIRSTPRIV + 0x15, + IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN , "tdls_get" + }, + { + SIOCIWFIRSTPRIV + 0x16, + IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" + }, + + {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"}, + + {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 128, 0, "efuse_set"}, + {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED |0x700 ,"efuse_get"}, + { + SIOCIWFIRSTPRIV + 0x1D, + IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" + }, +#ifdef CONFIG_INTEL_WIDI + { + SIOCIWFIRSTPRIV + 0x1E, + IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set" + }, + { + SIOCIWFIRSTPRIV + 0x1F, + IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req" + }, +#endif // CONFIG_INTEL_WIDI +}; + +static iw_handler rtw_private_handler[] = +{ + rtw_wx_write32, //0x00 + rtw_wx_read32, //0x01 + rtw_drvext_hdl, //0x02 + rtw_mp_ioctl_hdl, //0x03 + +// for MM DTV platform + rtw_get_ap_info, //0x04 + + rtw_set_pid, //0x05 + rtw_wps_start, //0x06 + +// for PLATFORM_MT53XX + rtw_wx_get_sensitivity, //0x07 + rtw_wx_set_mtk_wps_probe_ie, //0x08 + rtw_wx_set_mtk_wps_ie, //0x09 + +// for RTK_DMP_PLATFORM +// Set Channel depend on the country code + rtw_wx_set_channel_plan, //0x0A + + rtw_dbg_port, //0x0B + rtw_wx_write_rf, //0x0C + rtw_wx_read_rf, //0x0D + +#ifdef CONFIG_WOWLAN + rtw_wowlan_ctrl, //0x0E +#else + rtw_wx_priv_null, //0x0E +#endif //CONFIG_WOWLAN + rtw_wx_priv_null, //0x0F + + rtw_p2p_set, //0x10 + rtw_p2p_get, //0x11 + NULL, //0x12 + rtw_p2p_get2, //0x13 + + rtw_tdls, //0x14 + rtw_tdls_get, //0x15 + + rtw_pm_set, //0x16 + rtw_wx_priv_null, //0x17 + rtw_rereg_nd_name, //0x18 + rtw_wx_priv_null, //0x19 + + rtw_mp_efuse_set, //0x1A + rtw_mp_efuse_get, //0x1B + NULL, // 0x1C is reserved for hostapd + rtw_test , // 0x1D +#ifdef CONFIG_INTEL_WIDI + rtw_widi_set, //0x1E + rtw_widi_set_probe_request, //0x1F +#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) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_statistics *piwstats=&padapter->iwstats; + int tmp_level = 0; + int tmp_qual = 0; + int tmp_noise = 0; + + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) + { + piwstats->qual.qual = 0; + piwstats->qual.level = 0; + piwstats->qual.noise = 0; + //DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); + } + else{ + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); + #else + tmp_level = padapter->recvpriv.signal_strength; + #endif + + tmp_qual = padapter->recvpriv.signal_qual; + tmp_noise =padapter->recvpriv.noise; + //DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); + + piwstats->qual.level = tmp_level; + piwstats->qual.qual = tmp_qual; + piwstats->qual.noise = tmp_noise; + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM; +#else +#ifdef RTK_DMP_PLATFORM + //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. + //remove this flag for show percentage 0~100 + piwstats->qual.updated = 0x07; +#else + piwstats->qual.updated = 0x0f; +#endif +#endif + + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM; + #endif + + return &padapter->iwstats; +} +#endif + +#ifdef CONFIG_WIRELESS_EXT +struct iw_handler_def rtw_handlers_def = +{ + .standard = rtw_handlers, + .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV) + .private = rtw_private_handler, + .private_args = (struct iw_priv_args *)rtw_private_args, + .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args), +#endif +#if WIRELESS_EXT >= 17 + .get_wireless_stats = rtw_get_wireless_stats, +#endif +}; +#endif + diff --git a/rtl8192cu-fixes/os_dep/linux/mlme_linux.c b/rtl8192cu-fixes/os_dep/linux/mlme_linux.c new file mode 100755 index 00000000..6fc9f034 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/mlme_linux.c @@ -0,0 +1,586 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + + +#define _MLME_OSDEP_C_ + +#include +#include +#include +#include + + +#ifdef RTK_DMP_PLATFORM +void Linkup_workitem_callback(struct work_struct *work) +{ + struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem); + _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv); + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkup_workitem_callback\n")); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP); +#endif + +_func_exit_; +} + +void Linkdown_workitem_callback(struct work_struct *work) +{ + struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem); + _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv); + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkdown_workitem_callback\n")); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN); +#endif + +_func_exit_; +} +#endif + + +/* +void sitesurvey_ctrl_handler(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + _sitesurvey_ctrl_handler(adapter); + + _set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000); +} +*/ + +void rtw_join_timeout_handler (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + _rtw_join_timeout_handler(adapter); +} + + +void _rtw_scan_timeout_handler (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + rtw_scan_timeout_handler(adapter); +} + + +void _dynamic_check_timer_handlder (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + rtw_dynamic_check_timer_handlder(adapter); + + _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); +} + +#ifdef CONFIG_SET_SCAN_DENY_TIMER +void _rtw_set_scan_deny_timer_hdl(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + rtw_set_scan_deny_timer_hdl(adapter); +} +#endif + + +void rtw_init_mlme_timer(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter); + //_init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter); + _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter); + + _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter); + + #ifdef CONFIG_SET_SCAN_DENY_TIMER + _init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter); + #endif + +#ifdef RTK_DMP_PLATFORM + _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter); + _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter); +#endif + +} + +extern void rtw_indicate_wx_assoc_event(_adapter *padapter); +extern void rtw_indicate_wx_disassoc_event(_adapter *padapter); + +void rtw_os_indicate_connect(_adapter *adapter) +{ + +_func_enter_; + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_indicate_connect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_wx_assoc_event(adapter); + netif_carrier_on(adapter->pnetdev); + + if(adapter->pid[2] !=0) + rtw_signal_process(adapter->pid[2], SIGALRM); + +#ifdef RTK_DMP_PLATFORM + _set_workitem(&adapter->mlmepriv.Linkup_workitem); +#endif + +_func_exit_; + +} + +extern void indicate_wx_scan_complete_event(_adapter *padapter); +void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted) +{ +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), aborted); +#endif + indicate_wx_scan_complete_event(padapter); +} + +static RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ]; +void rtw_reset_securitypriv( _adapter *adapter ) +{ + u8 backupPMKIDIndex = 0; + u8 backupTKIPCountermeasure = 0x00; + u32 backupTKIPcountermeasure_time = 0; + // add for CONFIG_IEEE80211W, none 11w also can use + _irqL irqL; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + + _enter_critical_bh(&adapter->security_key_mutex, &irqL); + + if(adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)//802.1x + { + // Added by Albert 2009/02/18 + // We have to backup the PMK information for WiFi PMK Caching test item. + // + // Backup the btkip_countermeasure information. + // When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. + + _rtw_memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + + _rtw_memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + backupPMKIDIndex = adapter->securitypriv.PMKIDIndex; + backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure; + backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time; +#ifdef CONFIG_IEEE80211W + //reset RX BIP packet number + pmlmeext->mgnt_80211w_IPN_rx = 0; +#endif //CONFIG_IEEE80211W + _rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv)); + //_init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter); + + // Added by Albert 2009/02/18 + // Restore the PMK information to securitypriv structure for the following connection. + _rtw_memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; + adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure; + adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time; + + adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + + } + else //reset values in securitypriv + { + //if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE) + //{ + struct security_priv *psec_priv=&adapter->securitypriv; + + psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open; //open system + psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psec_priv->dot11PrivacyKeyIndex = 0; + + psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psec_priv->dot118021XGrpKeyid = 1; + + psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; + psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; + //} + } + // add for CONFIG_IEEE80211W, none 11w also can use + _exit_critical_bh(&adapter->security_key_mutex, &irqL); +} + +void rtw_os_indicate_disconnect( _adapter *adapter ) +{ + //RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ]; + +_func_enter_; + + netif_carrier_off(adapter->pnetdev); // Do it first for tx broadcast pkt after disconnection issue! + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_indicate_disconnect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_wx_disassoc_event(adapter); + +#ifdef RTK_DMP_PLATFORM + _set_workitem(&adapter->mlmepriv.Linkdown_workitem); +#endif + //modify for CONFIG_IEEE80211W, none 11w also can use the same command + rtw_reset_securitypriv_cmd(adapter); + +_func_exit_; + +} + +void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie) +{ + uint len; + u8 *buff,*p,i; + union iwreq_data wrqu; + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode)); + + buff = NULL; + if(authmode==_WPA_IE_ID_) + { + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode)); + + buff = rtw_malloc(IW_CUSTOM_MAX); + + _rtw_memset(buff,0,IW_CUSTOM_MAX); + + p=buff; + + p+=sprintf(p,"ASSOCINFO(ReqIEs="); + + len = sec_ie[1]+2; + len = (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX; + + for(i=0;ipnetdev,IWEVCUSTOM,&wrqu,buff); + + if(buff) + rtw_mfree(buff, IW_CUSTOM_MAX); + + } + +_func_exit_; + +} + +void _survey_timer_hdl (void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + + survey_timer_hdl(padapter); +} + +void _link_timer_hdl (void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + link_timer_hdl(padapter); +} + +void _addba_timer_hdl(void *FunctionContext) +{ + struct sta_info *psta = (struct sta_info *)FunctionContext; + addba_timer_hdl(psta); +} + +#ifdef CONFIG_IEEE80211W +void _sa_query_timer_hdl (void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + sa_query_timer_hdl(padapter); +} +#endif //CONFIG_IEEE80211W + +void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta) +{ + + _init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta); +} + +/* +void _reauth_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + reauth_timer_hdl(padapter); +} + +void _reassoc_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + reassoc_timer_hdl(padapter); +} +*/ + +void init_mlme_ext_timer(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter); + _init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter); +#ifdef CONFIG_IEEE80211W + _init_timer(&pmlmeext->sa_query_timer, padapter->pnetdev, _sa_query_timer_hdl, padapter); +#endif //CONFIG_IEEE80211W + //_init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter); + + //_init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter); + //_init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter); +} + +#ifdef CONFIG_AP_MODE + +void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta) +{ + union iwreq_data wrqu; + struct sta_priv *pstapriv = &padapter->stapriv; + + if(psta==NULL) + return; + + if(psta->aid > NUM_STA) + return; + + if(pstapriv->sta_aid[psta->aid - 1] != psta) + return; + + + wrqu.addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); + + DBG_871X("+rtw_indicate_sta_assoc_event\n"); + + wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL); + +} + +void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta) +{ + union iwreq_data wrqu; + struct sta_priv *pstapriv = &padapter->stapriv; + + if(psta==NULL) + return; + + if(psta->aid > NUM_STA) + return; + + if(pstapriv->sta_aid[psta->aid - 1] != psta) + return; + + + wrqu.addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); + + DBG_871X("+rtw_indicate_sta_disassoc_event\n"); + + wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL); + +} + + +#ifdef CONFIG_HOSTAPD_MLME + +static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + _adapter *padapter = (_adapter *)phostapdpriv->padapter; + + //DBG_871X("%s\n", __FUNCTION__); + + return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb); +} + +static int mgnt_netdev_open(struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + + DBG_871X("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr)); + + + init_usb_anchor(&phostapdpriv->anchored); + + if(!rtw_netif_queue_stopped(pnetdev)) + rtw_netif_start_queue(pnetdev); + else + rtw_netif_wake_queue(pnetdev); + + + netif_carrier_on(pnetdev); + + //rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100);//only excluding beacon + + return 0; +} +static int mgnt_netdev_close(struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + + DBG_871X("%s\n", __FUNCTION__); + + usb_kill_anchored_urbs(&phostapdpriv->anchored); + + netif_carrier_off(pnetdev); + + if (!rtw_netif_queue_stopped(pnetdev)) + rtw_netif_stop_queue(pnetdev); + + //rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f); + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtl871x_mgnt_netdev_ops = { + .ndo_open = mgnt_netdev_open, + .ndo_stop = mgnt_netdev_close, + .ndo_start_xmit = mgnt_xmit_entry, + //.ndo_set_mac_address = r871x_net_set_mac_address, + //.ndo_get_stats = r871x_net_get_stats, + //.ndo_do_ioctl = r871x_mp_ioctl, +}; +#endif + +int hostapd_mode_init(_adapter *padapter) +{ + unsigned char mac[ETH_ALEN]; + struct hostapd_priv *phostapdpriv; + struct net_device *pnetdev; + + pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv)); + if (!pnetdev) + return -ENOMEM; + + //SET_MODULE_OWNER(pnetdev); + ether_setup(pnetdev); + + //pnetdev->type = ARPHRD_IEEE80211; + + phostapdpriv = rtw_netdev_priv(pnetdev); + phostapdpriv->pmgnt_netdev = pnetdev; + phostapdpriv->padapter= padapter; + padapter->phostapdpriv = phostapdpriv; + + //pnetdev->init = NULL; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + + DBG_871X("register rtl871x_mgnt_netdev_ops to netdev_ops\n"); + + pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops; + +#else + + pnetdev->open = mgnt_netdev_open; + + pnetdev->stop = mgnt_netdev_close; + + pnetdev->hard_start_xmit = mgnt_xmit_entry; + + //pnetdev->set_mac_address = r871x_net_set_mac_address; + + //pnetdev->get_stats = r871x_net_get_stats; + + //pnetdev->do_ioctl = r871x_mp_ioctl; + +#endif + + pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ + + //pnetdev->wireless_handlers = NULL; + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + pnetdev->features |= NETIF_F_IP_CSUM; +#endif + + + + if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0) + { + DBG_871X("hostapd_mode_init(): dev_alloc_name, fail! \n"); + } + + + //SET_NETDEV_DEV(pnetdev, pintfpriv->udev); + + + mac[0]=0x00; + mac[1]=0xe0; + mac[2]=0x4c; + mac[3]=0x87; + mac[4]=0x11; + mac[5]=0x12; + + _rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN); + + + netif_carrier_off(pnetdev); + + + /* Tell the network stack we exist */ + if (register_netdev(pnetdev) != 0) + { + DBG_871X("hostapd_mode_init(): register_netdev fail!\n"); + + if(pnetdev) + { + rtw_free_netdev(pnetdev); + } + } + + return 0; + +} + +void hostapd_mode_unload(_adapter *padapter) +{ + struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; + struct net_device *pnetdev = phostapdpriv->pmgnt_netdev; + + unregister_netdev(pnetdev); + rtw_free_netdev(pnetdev); + +} + +#endif +#endif + diff --git a/rtl8192cu-fixes/os_dep/linux/os_intfs.c b/rtl8192cu-fixes/os_dep/linux/os_intfs.c new file mode 100755 index 00000000..3a3cf913 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/os_intfs.c @@ -0,0 +1,2758 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _OS_INTFS_C_ + +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_HCI +#include +#endif + +#ifdef CONFIG_PCI_HCI +#include +#endif + +#ifdef CONFIG_BR_EXT +#include +#endif //CONFIG_BR_EXT + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); +MODULE_AUTHOR("Realtek Semiconductor Corp."); +MODULE_VERSION(DRIVERVERSION); + +/* module param defaults */ +int rtw_chip_version = 0x00; +int rtw_rfintfs = HWPI; +int rtw_lbkmode = 0;//RTL8712_AIR_TRX; + + +int rtw_network_mode = Ndis802_11IBSS;//Ndis802_11Infrastructure;//infra, ad-hoc, auto +//NDIS_802_11_SSID ssid; +int rtw_channel = 1;//ad-hoc support requirement +int rtw_wireless_mode = WIRELESS_11BG_24N; +int rtw_vrtl_carrier_sense = AUTO_VCS; +int rtw_vcs_type = RTS_CTS;//* +int rtw_rts_thresh = 2347;//* +int rtw_frag_thresh = 2346;//* +int rtw_preamble = PREAMBLE_LONG;//long, short, auto +int rtw_scan_mode = 1;//active, passive +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_IPS_LEVEL_2 +int rtw_ips_mode = IPS_LEVEL_2; +#else +int rtw_ips_mode = IPS_NORMAL; +#endif +#else +int rtw_power_mgnt = PS_MODE_ACTIVE; +int rtw_ips_mode = IPS_NONE; +#endif +module_param(rtw_ips_mode, int, 0644); +MODULE_PARM_DESC(rtw_ips_mode,"The default IPS mode"); + +int rtw_radio_enable = 1; +int rtw_long_retry_lmt = 7; +int rtw_short_retry_lmt = 7; +int rtw_busy_thresh = 40; +//int qos_enable = 0; //* +int rtw_ack_policy = NORMAL_ACK; +#ifdef CONFIG_MP_INCLUDED +int rtw_mp_mode = 1; +#else +int rtw_mp_mode = 0; +#endif +int rtw_software_encrypt = 0; +int rtw_software_decrypt = 0; + +int rtw_acm_method = 0;// 0:By SW 1:By HW. + +int rtw_wmm_enable = 1;// default is set to enable the wmm. +int rtw_uapsd_enable = 0; +int rtw_uapsd_max_sp = NO_LIMIT; +int rtw_uapsd_acbk_en = 0; +int rtw_uapsd_acbe_en = 0; +int rtw_uapsd_acvi_en = 0; +int rtw_uapsd_acvo_en = 0; + +#ifdef CONFIG_80211N_HT +int rtw_ht_enable = 1; +int rtw_cbw40_enable = 3; // 0 :diable, bit(0): enable 2.4g, bit(1): enable 5g +int rtw_ampdu_enable = 1;//for enable tx_ampdu +int rtw_rx_stbc = 1;// 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ +int rtw_ampdu_amsdu = 0;// 0: disabled, 1:enabled, 2:auto +#endif + +int rtw_lowrate_two_xmit = 1;//Use 2 path Tx to transmit MCS0~7 and legacy mode + +//int rf_config = RF_1T2R; // 1T2R +int rtw_rf_config = RF_819X_MAX_TYPE; //auto +int rtw_low_power = 0; +#ifdef CONFIG_WIFI_TEST +int rtw_wifi_spec = 1;//for wifi test +#else +int rtw_wifi_spec = 0; +#endif + +int rtw_special_rf_path = 0; //0: 2T2R ,1: only turn on path A 1T1R, 2: only turn on path B 1T1R + +int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX; + +#ifdef CONFIG_BT_COEXIST +int rtw_bt_iso = 2;// 0:Low, 1:High, 2:From Efuse +int rtw_bt_sco = 3;// 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy +int rtw_bt_ampdu =1 ;// 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. +#endif +int rtw_AcceptAddbaReq = _TRUE;// 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. + +int rtw_antdiv_cfg = 2; // 0:OFF , 1:ON, 2:decide by Efuse config + +#ifdef CONFIG_USB_AUTOSUSPEND +int rtw_enusbss = 1;//0:disable,1:enable +#else +int rtw_enusbss = 0;//0:disable,1:enable +#endif + +int rtw_hwpdn_mode=2;//0:disable,1:enable,2: by EFUSE config + +#ifdef CONFIG_HW_PWRP_DETECTION +int rtw_hwpwrp_detect = 1; +#else +int rtw_hwpwrp_detect = 0; //HW power ping detect 0:disable , 1:enable +#endif + +#ifdef CONFIG_USB_HCI +int rtw_hw_wps_pbc = 1; +#else +int rtw_hw_wps_pbc = 0; +#endif + +#ifdef CONFIG_TX_MCAST2UNI +int rtw_mc2u_disable = 0; +#endif // CONFIG_TX_MCAST2UNI + +int rtw_mac_phy_mode = 0; //0:by efuse, 1:smsp, 2:dmdp, 3:dmsp. + +#ifdef CONFIG_80211D +int rtw_80211d = 0; +#endif + +char* ifname = "wlan%d"; +module_param(ifname, charp, 0644); +MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); + +char* if2name = "wlan%d"; +module_param(if2name, charp, 0644); +MODULE_PARM_DESC(if2name, "The default name to allocate for second interface"); + +char* rtw_initmac = 0; // temp mac address if users want to use instead of the mac address in Efuse + +#ifdef CONFIG_MULTI_VIR_IFACES +int rtw_ext_iface_num = 1;//primary/secondary iface is excluded +module_param(rtw_ext_iface_num, int, 0644); +#endif //CONFIG_MULTI_VIR_IFACES + +module_param(rtw_initmac, charp, 0644); +module_param(rtw_channel_plan, int, 0644); +module_param(rtw_chip_version, int, 0644); +module_param(rtw_rfintfs, int, 0644); +module_param(rtw_lbkmode, int, 0644); +module_param(rtw_network_mode, int, 0644); +module_param(rtw_channel, int, 0644); +module_param(rtw_mp_mode, int, 0644); +module_param(rtw_wmm_enable, int, 0644); +module_param(rtw_vrtl_carrier_sense, int, 0644); +module_param(rtw_vcs_type, int, 0644); +module_param(rtw_busy_thresh, int, 0644); +#ifdef CONFIG_80211N_HT +module_param(rtw_ht_enable, int, 0644); +module_param(rtw_cbw40_enable, int, 0644); +module_param(rtw_ampdu_enable, int, 0644); +module_param(rtw_rx_stbc, int, 0644); +module_param(rtw_ampdu_amsdu, int, 0644); +#endif + +module_param(rtw_lowrate_two_xmit, int, 0644); + +module_param(rtw_rf_config, int, 0644); +module_param(rtw_power_mgnt, int, 0644); +module_param(rtw_low_power, int, 0644); +module_param(rtw_wifi_spec, int, 0644); + +module_param(rtw_special_rf_path, int, 0644); + +module_param(rtw_antdiv_cfg, int, 0644); + + +module_param(rtw_enusbss, int, 0644); +module_param(rtw_hwpdn_mode, int, 0644); +module_param(rtw_hwpwrp_detect, int, 0644); + +module_param(rtw_hw_wps_pbc, int, 0644); + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE +char *rtw_adaptor_info_caching_file_path= "/data/misc/wifi/rtw_cache"; +module_param(rtw_adaptor_info_caching_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_adaptor_info_caching_file_path, "The path of adapter info cache file"); +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE + +#ifdef CONFIG_LAYER2_ROAMING +uint rtw_max_roaming_times=2; +module_param(rtw_max_roaming_times, uint, 0644); +MODULE_PARM_DESC(rtw_max_roaming_times,"The max roaming times to try"); +#endif //CONFIG_LAYER2_ROAMING + +#ifdef CONFIG_IOL +bool rtw_force_iol=_FALSE; +module_param(rtw_force_iol, bool, 0644); +MODULE_PARM_DESC(rtw_force_iol,"Force to enable IOL"); +#endif //CONFIG_IOL + +#ifdef CONFIG_FILE_FWIMG +char *rtw_fw_file_path= ""; +module_param(rtw_fw_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_fw_file_path, "The path of fw image"); +#endif //CONFIG_FILE_FWIMG + +#ifdef CONFIG_TX_MCAST2UNI +module_param(rtw_mc2u_disable, int, 0644); +#endif // CONFIG_TX_MCAST2UNI + +module_param(rtw_mac_phy_mode, int, 0644); + +#ifdef CONFIG_80211D +module_param(rtw_80211d, int, 0644); +#endif + +uint rtw_notch_filter = RTW_NOTCH_FILTER; +module_param(rtw_notch_filter, uint, 0644); +MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); + +static uint loadparam( _adapter *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 RTK_DMP_PLATFORM +#ifdef CONFIG_PROC_DEBUG +#define RTL8192C_PROC_NAME "rtl819xC" +#define RTL8192D_PROC_NAME "rtl819xD" +static char rtw_proc_name[IFNAMSIZ]; +static struct proc_dir_entry *rtw_proc = NULL; +static int rtw_proc_cnt = 0; + +#define RTW_PROC_NAME DRV_NAME + +void rtw_proc_init_one(struct net_device *dev) +{ +#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) + struct proc_dir_entry *dir_dev = NULL; + struct proc_dir_entry *entry=NULL; + _adapter *padapter = rtw_netdev_priv(dev); + u8 rf_type; + + if(rtw_proc == NULL) + { + if(padapter->chip_type == RTL8188C_8192C) + { + _rtw_memcpy(rtw_proc_name, RTL8192C_PROC_NAME, sizeof(RTL8192C_PROC_NAME)); + } + else if(padapter->chip_type == RTL8192D) + { + _rtw_memcpy(rtw_proc_name, RTL8192D_PROC_NAME, sizeof(RTL8192D_PROC_NAME)); + } + else if(padapter->chip_type == RTL8723A) + { + _rtw_memcpy(rtw_proc_name, RTW_PROC_NAME, sizeof(RTW_PROC_NAME)); + } + else if(padapter->chip_type == RTL8188E) + { + _rtw_memcpy(rtw_proc_name, RTW_PROC_NAME, sizeof(RTW_PROC_NAME)); + } + else + { + _rtw_memcpy(rtw_proc_name, RTW_PROC_NAME, sizeof(RTW_PROC_NAME)); + } + +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + rtw_proc=create_proc_entry(rtw_proc_name, S_IFDIR, proc_net); +#else + rtw_proc=create_proc_entry(rtw_proc_name, S_IFDIR, init_net.proc_net); +#endif + if (rtw_proc == NULL) { + DBG_871X(KERN_ERR "Unable to create rtw_proc directory\n"); + return; + } + + entry = create_proc_read_entry("ver_info", S_IFREG | S_IRUGO, rtw_proc, proc_get_drv_version, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("log_level", S_IFREG | S_IRUGO, + rtw_proc, proc_get_log_level, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_log_level; + +#ifdef DBG_MEM_ALLOC + entry = create_proc_read_entry("mstat", S_IFREG | S_IRUGO, + rtw_proc, proc_get_mstat, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } +#endif /* DBG_MEM_ALLOC */ + } + + + + if(padapter->dir_dev == NULL) + { + padapter->dir_dev = create_proc_entry(dev->name, + S_IFDIR | S_IRUGO | S_IXUGO, + rtw_proc); + + dir_dev = padapter->dir_dev; + + if(dir_dev==NULL) + { + if(rtw_proc_cnt == 0) + { + if(rtw_proc){ +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(rtw_proc_name, proc_net); +#else + remove_proc_entry(rtw_proc_name, init_net.proc_net); +#endif + rtw_proc = NULL; + } + } + + DBG_871X("Unable to create dir_dev directory\n"); + return; + } + } + else + { + return; + } + + rtw_proc_cnt++; + + entry = create_proc_read_entry("write_reg", S_IFREG | S_IRUGO, + dir_dev, proc_get_write_reg, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_write_reg; + + entry = create_proc_read_entry("read_reg", S_IFREG | S_IRUGO, + dir_dev, proc_get_read_reg, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_read_reg; + + + entry = create_proc_read_entry("fwstate", S_IFREG | S_IRUGO, + dir_dev, proc_get_fwstate, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + + entry = create_proc_read_entry("sec_info", S_IFREG | S_IRUGO, + dir_dev, proc_get_sec_info, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + + entry = create_proc_read_entry("mlmext_state", S_IFREG | S_IRUGO, + dir_dev, proc_get_mlmext_state, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + + entry = create_proc_read_entry("qos_option", S_IFREG | S_IRUGO, + dir_dev, proc_get_qos_option, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("ht_option", S_IFREG | S_IRUGO, + dir_dev, proc_get_ht_option, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("rf_info", S_IFREG | S_IRUGO, + dir_dev, proc_get_rf_info, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("ap_info", S_IFREG | S_IRUGO, + dir_dev, proc_get_ap_info, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("adapter_state", S_IFREG | S_IRUGO, + dir_dev, proc_get_adapter_state, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("trx_info", S_IFREG | S_IRUGO, + dir_dev, proc_get_trx_info, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("mac_reg_dump1", S_IFREG | S_IRUGO, + dir_dev, proc_get_mac_reg_dump1, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("mac_reg_dump2", S_IFREG | S_IRUGO, + dir_dev, proc_get_mac_reg_dump2, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("mac_reg_dump3", S_IFREG | S_IRUGO, + dir_dev, proc_get_mac_reg_dump3, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("bb_reg_dump1", S_IFREG | S_IRUGO, + dir_dev, proc_get_bb_reg_dump1, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("bb_reg_dump2", S_IFREG | S_IRUGO, + dir_dev, proc_get_bb_reg_dump2, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("bb_reg_dump3", S_IFREG | S_IRUGO, + dir_dev, proc_get_bb_reg_dump3, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("rf_reg_dump1", S_IFREG | S_IRUGO, + dir_dev, proc_get_rf_reg_dump1, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("rf_reg_dump2", S_IFREG | S_IRUGO, + dir_dev, proc_get_rf_reg_dump2, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if((RF_1T2R == rf_type) ||(RF_1T1R ==rf_type )) { + entry = create_proc_read_entry("rf_reg_dump3", S_IFREG | S_IRUGO, + dir_dev, proc_get_rf_reg_dump3, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("rf_reg_dump4", S_IFREG | S_IRUGO, + dir_dev, proc_get_rf_reg_dump4, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + } + +#ifdef CONFIG_AP_MODE + + entry = create_proc_read_entry("all_sta_info", S_IFREG | S_IRUGO, + dir_dev, proc_get_all_sta_info, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } +#endif + +#ifdef DBG_MEMORY_LEAK + entry = create_proc_read_entry("_malloc_cnt", S_IFREG | S_IRUGO, + dir_dev, proc_get_malloc_cnt, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } +#endif + +#ifdef CONFIG_FIND_BEST_CHANNEL + entry = create_proc_read_entry("best_channel", S_IFREG | S_IRUGO, + dir_dev, proc_get_best_channel, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_best_channel; +#endif + + entry = create_proc_read_entry("rx_signal", S_IFREG | S_IRUGO, + dir_dev, proc_get_rx_signal, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_rx_signal; + + entry = create_proc_read_entry("ht_enable", S_IFREG | S_IRUGO, + dir_dev, proc_get_ht_enable, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_ht_enable; + + entry = create_proc_read_entry("cbw40_enable", S_IFREG | S_IRUGO, + dir_dev, proc_get_cbw40_enable, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_cbw40_enable; + + entry = create_proc_read_entry("ampdu_enable", S_IFREG | S_IRUGO, + dir_dev, proc_get_ampdu_enable, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_ampdu_enable; + + entry = create_proc_read_entry("rx_stbc", S_IFREG | S_IRUGO, + dir_dev, proc_get_rx_stbc, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_rx_stbc; + + + entry = create_proc_read_entry("path_rssi", S_IFREG | S_IRUGO, + dir_dev, proc_get_two_path_rssi, dev); + + entry = create_proc_read_entry("vid", S_IFREG | S_IRUGO, + dir_dev, proc_get_vid, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("pid", S_IFREG | S_IRUGO, + dir_dev, proc_get_pid, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + + entry = create_proc_read_entry("rssi_disp", S_IFREG | S_IRUGO, + dir_dev, proc_get_rssi_disp, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_rssi_disp; + +#if defined(DBG_CONFIG_ERROR_DETECT) + entry = create_proc_read_entry("sreset", S_IFREG | S_IRUGO, + dir_dev, proc_get_sreset, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_sreset; +#endif /* DBG_CONFIG_ERROR_DETECT */ + +#ifdef CONFIG_DM_ADAPTIVITY + entry = create_proc_read_entry("dm_adaptivity", S_IFREG | S_IRUGO, + dir_dev, proc_get_dm_adaptivity, dev); + if (!entry) { + DBG_871X("Unable to create_proc_read_entry!\n"); + return; + } + entry->write_proc = proc_set_dm_adaptivity; +#endif /* CONFIG_DM_ADAPTIVITY */ + +#else /* kernel version < 3.10 */ + DBG_871X(KERN_ERR "Unable to create /proc entry in this kernel version\n"); +#endif +} + +void rtw_proc_remove_one(struct net_device *dev) +{ + struct proc_dir_entry *dir_dev = NULL; + _adapter *padapter = rtw_netdev_priv(dev); + u8 rf_type; + + dir_dev = padapter->dir_dev; + padapter->dir_dev = NULL; + + if (dir_dev) { + + remove_proc_entry("write_reg", dir_dev); + remove_proc_entry("read_reg", dir_dev); + remove_proc_entry("fwstate", dir_dev); + remove_proc_entry("sec_info", dir_dev); + remove_proc_entry("mlmext_state", dir_dev); + remove_proc_entry("qos_option", dir_dev); + remove_proc_entry("ht_option", dir_dev); + remove_proc_entry("rf_info", dir_dev); + remove_proc_entry("ap_info", dir_dev); + remove_proc_entry("adapter_state", dir_dev); + remove_proc_entry("trx_info", dir_dev); + + remove_proc_entry("mac_reg_dump1", dir_dev); + remove_proc_entry("mac_reg_dump2", dir_dev); + remove_proc_entry("mac_reg_dump3", dir_dev); + remove_proc_entry("bb_reg_dump1", dir_dev); + remove_proc_entry("bb_reg_dump2", dir_dev); + remove_proc_entry("bb_reg_dump3", dir_dev); + remove_proc_entry("rf_reg_dump1", dir_dev); + remove_proc_entry("rf_reg_dump2", dir_dev); + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if((RF_1T2R == rf_type) ||(RF_1T1R ==rf_type )) { + remove_proc_entry("rf_reg_dump3", dir_dev); + remove_proc_entry("rf_reg_dump4", dir_dev); + } +#ifdef CONFIG_AP_MODE + remove_proc_entry("all_sta_info", dir_dev); +#endif + +#ifdef DBG_MEMORY_LEAK + remove_proc_entry("_malloc_cnt", dir_dev); +#endif + +#ifdef CONFIG_FIND_BEST_CHANNEL + remove_proc_entry("best_channel", dir_dev); +#endif + remove_proc_entry("rx_signal", dir_dev); + + remove_proc_entry("cbw40_enable", dir_dev); + + remove_proc_entry("ht_enable", dir_dev); + + remove_proc_entry("ampdu_enable", dir_dev); + + remove_proc_entry("rx_stbc", dir_dev); + + remove_proc_entry("path_rssi", dir_dev); + + remove_proc_entry("vid", dir_dev); + + remove_proc_entry("pid", dir_dev); + + remove_proc_entry("rssi_disp", dir_dev); + +#if defined(DBG_CONFIG_ERROR_DETECT) + remove_proc_entry("sreset", dir_dev); +#endif /* DBG_CONFIG_ERROR_DETECT */ + +#ifdef CONFIG_DM_ADAPTIVITY + remove_proc_entry("dm_adaptivity", dir_dev); +#endif + + remove_proc_entry(dev->name, rtw_proc); + dir_dev = NULL; + + } + else + { + return; + } + + rtw_proc_cnt--; + + if(rtw_proc_cnt == 0) + { + if(rtw_proc){ + remove_proc_entry("ver_info", rtw_proc); + + remove_proc_entry("log_level", rtw_proc); + #ifdef DBG_MEM_ALLOC + remove_proc_entry("mstat", rtw_proc); + #endif /* DBG_MEM_ALLOC */ +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + remove_proc_entry(rtw_proc_name, proc_net); +#else + remove_proc_entry(rtw_proc_name, init_net.proc_net); +#endif + rtw_proc = NULL; + } + } +} +#endif + +uint loadparam( _adapter *padapter, _nic_hdl pnetdev); +uint loadparam( _adapter *padapter, _nic_hdl pnetdev) +{ + + uint status = _SUCCESS; + struct registry_priv *registry_par = &padapter->registrypriv; + +_func_enter_; + + registry_par->chip_version = (u8)rtw_chip_version; + registry_par->rfintfs = (u8)rtw_rfintfs; + registry_par->lbkmode = (u8)rtw_lbkmode; + //registry_par->hci = (u8)hci; + registry_par->network_mode = (u8)rtw_network_mode; + + _rtw_memcpy(registry_par->ssid.Ssid, "ANY", 3); + registry_par->ssid.SsidLength = 3; + + registry_par->channel = (u8)rtw_channel; + registry_par->wireless_mode = (u8)rtw_wireless_mode; + registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; + registry_par->vcs_type = (u8)rtw_vcs_type; + registry_par->rts_thresh=(u16)rtw_rts_thresh; + registry_par->frag_thresh=(u16)rtw_frag_thresh; + registry_par->preamble = (u8)rtw_preamble; + registry_par->scan_mode = (u8)rtw_scan_mode; + registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; + registry_par->soft_ap= (u8)rtw_soft_ap; + //registry_par->smart_ps = (u8)rtw_smart_ps; + registry_par->power_mgnt = (u8)rtw_power_mgnt; + registry_par->ips_mode = (u8)rtw_ips_mode; + registry_par->radio_enable = (u8)rtw_radio_enable; + registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; + registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; + registry_par->busy_thresh = (u16)rtw_busy_thresh; + //registry_par->qos_enable = (u8)rtw_qos_enable; + registry_par->ack_policy = (u8)rtw_ack_policy; + registry_par->mp_mode = (u8)rtw_mp_mode; + registry_par->software_encrypt = (u8)rtw_software_encrypt; + registry_par->software_decrypt = (u8)rtw_software_decrypt; + + registry_par->acm_method = (u8)rtw_acm_method; + + //UAPSD + registry_par->wmm_enable = (u8)rtw_wmm_enable; + registry_par->uapsd_enable = (u8)rtw_uapsd_enable; + registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; + registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; + registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; + registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; + registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; + +#ifdef CONFIG_80211N_HT + registry_par->ht_enable = (u8)rtw_ht_enable; + registry_par->cbw40_enable = (u8)rtw_cbw40_enable; + registry_par->ampdu_enable = (u8)rtw_ampdu_enable; + registry_par->rx_stbc = (u8)rtw_rx_stbc; + registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; +#endif + + registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; + registry_par->rf_config = (u8)rtw_rf_config; + registry_par->low_power = (u8)rtw_low_power; + + + registry_par->wifi_spec = (u8)rtw_wifi_spec; + registry_par->special_rf_path = (u8)rtw_special_rf_path; + registry_par->channel_plan = (u8)rtw_channel_plan; + +#ifdef CONFIG_BT_COEXIST + registry_par->bt_iso = (u8)rtw_bt_iso; + registry_par->bt_sco = (u8)rtw_bt_sco; + registry_par->bt_ampdu = (u8)rtw_bt_ampdu; +#endif + registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq; + + registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; + +#ifdef CONFIG_AUTOSUSPEND + registry_par->usbss_enable = (u8)rtw_enusbss;//0:disable,1:enable +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED + registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;//0:disable,1:enable,2:by EFUSE config + registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;//0:disable,1:enable +#endif + + registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + snprintf(registry_par->adaptor_info_caching_file_path, PATH_LENGTH_MAX, "%s", rtw_adaptor_info_caching_file_path); + registry_par->adaptor_info_caching_file_path[PATH_LENGTH_MAX-1]=0; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + registry_par->max_roaming_times = (u8)rtw_max_roaming_times; +#ifdef CONFIG_INTEL_WIDI + registry_par->max_roaming_times = (u8)rtw_max_roaming_times + 2; +#endif // CONFIG_INTEL_WIDI +#endif + +#ifdef CONFIG_IOL + registry_par->force_iol = rtw_force_iol; +#endif + + registry_par->mac_phy_mode = rtw_mac_phy_mode; + +#ifdef CONFIG_80211D + registry_par->enable80211d = (u8)rtw_80211d; +#endif + + snprintf(registry_par->ifname, 16, "%s", ifname); + snprintf(registry_par->if2name, 16, "%s", if2name); + + registry_par->notch_filter = (u8)rtw_notch_filter; + +#ifdef CONFIG_MULTI_VIR_IFACES + registry_par->ext_iface_num = (u8)rtw_ext_iface_num; +#endif //CONFIG_MULTI_VIR_IFACES + +_func_exit_; + + return status; +} + +static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct sockaddr *addr = p; + + if(padapter->bup == _FALSE) + { + //DBG_871X("r8711_net_set_mac_address(), MAC=%x:%x:%x:%x:%x:%x\n", addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], + //addr->sa_data[4], addr->sa_data[5]); + _rtw_memcpy(padapter->eeprompriv.mac_addr, addr->sa_data, ETH_ALEN); + //_rtw_memcpy(pnetdev->dev_addr, addr->sa_data, ETH_ALEN); + //padapter->bset_hwaddr = _TRUE; + } + + return 0; +} + +static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct recv_priv *precvpriv = &(padapter->recvpriv); + + padapter->stats.tx_packets = pxmitpriv->tx_pkts;//pxmitpriv->tx_pkts++; + padapter->stats.rx_packets = precvpriv->rx_pkts;//precvpriv->rx_pkts++; + padapter->stats.tx_dropped = pxmitpriv->tx_drop; + padapter->stats.rx_dropped = precvpriv->rx_drop; + padapter->stats.tx_bytes = pxmitpriv->tx_bytes; + padapter->stats.rx_bytes = precvpriv->rx_bytes; + + return &padapter->stats; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) +/* + * AC to queue mapping + * + * AC_VO -> queue 0 + * AC_VI -> queue 1 + * AC_BE -> queue 2 + * AC_BK -> queue 3 + */ +static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; + +/* Given a data frame determine the 802.1p/1d tag to use. */ +unsigned int rtw_classify8021d(struct sk_buff *skb) +{ + unsigned int dscp; + + /* skb->priority values from 256->263 are magic values to + * directly indicate a specific 802.1d priority. This is used + * to allow 802.1d priority to be passed directly in from VLAN + * tags, etc. + */ + if (skb->priority >= 256 && skb->priority <= 263) + return skb->priority - 256; + + switch (skb->protocol) { + case htons(ETH_P_IP): + dscp = ip_hdr(skb)->tos & 0xfc; + break; + default: + return 0; + } + + return dscp >> 5; +} + +static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + _adapter *padapter = rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + skb->priority = rtw_classify8021d(skb); + + if(pmlmepriv->acm_mask != 0) + { + skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); + } + + return rtw_1d_to_queue[skb->priority]; +} + +u16 rtw_recv_select_queue(struct sk_buff *skb) +{ + struct iphdr *piphdr; + unsigned int dscp; + u16 eth_type; + u32 priority; + u8 *pdata = skb->data; + + _rtw_memcpy(ð_type, pdata+(ETH_ALEN<<1), 2); + + switch (eth_type) { + case htons(ETH_P_IP): + + piphdr = (struct iphdr *)(pdata+ETH_HLEN); + + dscp = piphdr->tos & 0xfc; + + priority = dscp >> 5; + + break; + default: + priority = 0; + } + + return rtw_1d_to_queue[priority]; + +} + +#endif + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = rtw_xmit_entry, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +}; +#endif + +int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) +{ + _adapter *padapter = rtw_netdev_priv(pnetdev); + +#ifdef CONFIG_EASY_REPLACEMENT + struct net_device *TargetNetdev = NULL; + _adapter *TargetAdapter = NULL; + struct net *devnet = NULL; + + if(padapter->bDongle == 1) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + TargetNetdev = dev_get_by_name("wlan0"); +#else + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = pnetdev->nd_net; + #else + devnet = dev_net(pnetdev); + #endif + TargetNetdev = dev_get_by_name(devnet, "wlan0"); +#endif + if(TargetNetdev) { + DBG_871X("Force onboard module driver disappear !!!\n"); + TargetAdapter = rtw_netdev_priv(TargetNetdev); + TargetAdapter->DriverState = DRIVER_DISAPPEAR; + + padapter->pid[0] = TargetAdapter->pid[0]; + padapter->pid[1] = TargetAdapter->pid[1]; + padapter->pid[2] = TargetAdapter->pid[2]; + + dev_put(TargetNetdev); + unregister_netdev(TargetNetdev); + + if(TargetAdapter->chip_type == padapter->chip_type) + rtw_proc_remove_one(TargetNetdev); + + padapter->DriverState = DRIVER_REPLACE_DONGLE; + } + } +#endif //CONFIG_EASY_REPLACEMENT + + if(dev_alloc_name(pnetdev, ifname) < 0) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("dev_alloc_name, fail! \n")); + } + + netif_carrier_off(pnetdev); + //rtw_netif_stop_queue(pnetdev); + + return 0; +} + +static const struct device_type wlan_type = { + .name = "wlan", +}; + +struct net_device *rtw_init_netdev(_adapter *old_padapter) +{ + _adapter *padapter; + struct net_device *pnetdev; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+init_net_dev\n")); + + if(old_padapter != NULL) + pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(_adapter), (void *)old_padapter); + else + pnetdev = rtw_alloc_etherdev(sizeof(_adapter)); + + if (!pnetdev) + return NULL; + + pnetdev->dev.type = &wlan_type; + padapter = rtw_netdev_priv(pnetdev); + padapter->pnetdev = pnetdev; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(pnetdev); +#endif + + //pnetdev->init = NULL; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + DBG_871X("register rtw_netdev_ops to netdev_ops\n"); + pnetdev->netdev_ops = &rtw_netdev_ops; +#else + pnetdev->open = netdev_open; + pnetdev->stop = netdev_close; + pnetdev->hard_start_xmit = rtw_xmit_entry; + pnetdev->set_mac_address = rtw_net_set_mac_address; + pnetdev->get_stats = rtw_net_get_stats; + pnetdev->do_ioctl = rtw_ioctl; +#endif + + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + pnetdev->features |= NETIF_F_IP_CSUM; +#endif + //pnetdev->tx_timeout = NULL; + pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ +#ifdef CONFIG_WIRELESS_EXT + pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; +#endif + +#ifdef WIRELESS_SPY + //priv->wireless_data.spy_data = &priv->spy_data; + //pnetdev->wireless_data = &priv->wireless_data; +#endif + + //step 2. + loadparam(padapter, pnetdev); + + return pnetdev; + +} + +void rtw_unregister_netdevs(struct dvobj_priv *dvobj) +{ + int i; + _adapter *padapter = NULL; + + for (i=0;iiface_nums;i++) { + struct net_device *pnetdev = NULL; + + padapter = dvobj->padapters[i]; + + if (padapter == NULL) + continue; + + pnetdev = padapter->pnetdev; + + if((padapter->DriverState != DRIVER_DISAPPEAR) && pnetdev) { + unregister_netdev(pnetdev); //will call netdev_close() + rtw_proc_remove_one(pnetdev); + } + + #ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_unregister(padapter->rtw_wdev); + #endif + } + +} + +u32 rtw_start_drv_threads(_adapter *padapter) +{ + + u32 _status = _SUCCESS; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_start_drv_threads\n")); +#ifdef CONFIG_XMIT_THREAD_MODE + padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD"); + if(IS_ERR(padapter->xmitThread)) + _status = _FAIL; +#endif + +#ifdef CONFIG_RECV_THREAD_MODE + padapter->recvThread = kthread_run(rtw_recv_thread, padapter, "RTW_RECV_THREAD"); + if(IS_ERR(padapter->recvThread)) + _status = _FAIL; +#endif + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->isprimary == _TRUE) +#endif //CONFIG_CONCURRENT_MODE + { + padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); + if(IS_ERR(padapter->cmdThread)) + _status = _FAIL; + else + _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); //wait for cmd_thread to run + } + + +#ifdef CONFIG_EVENT_THREAD_MODE + padapter->evtThread = kthread_run(event_thread, padapter, "RTW_EVENT_THREAD"); + if(IS_ERR(padapter->evtThread)) + _status = _FAIL; +#endif + + return _status; + +} + +void rtw_stop_drv_threads (_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_stop_drv_threads\n")); + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->isprimary == _TRUE) +#endif //CONFIG_CONCURRENT_MODE + { + rtw_stop_cmd_thread(padapter); + } + +#ifdef CONFIG_EVENT_THREAD_MODE + _rtw_up_sema(&padapter->evtpriv.evt_notify); + if(padapter->evtThread){ + _rtw_down_sema(&padapter->evtpriv.terminate_evtthread_sema); + } +#endif + +#ifdef CONFIG_XMIT_THREAD_MODE + // Below is to termindate tx_thread... + _rtw_up_sema(&padapter->xmitpriv.xmit_sema); + _rtw_down_sema(&padapter->xmitpriv.terminate_xmitthread_sema); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt: rtw_xmit_thread can be terminated ! \n")); +#endif + +#ifdef CONFIG_RECV_THREAD_MODE + // Below is to termindate rx_thread... + _rtw_up_sema(&padapter->recvpriv.recv_sema); + _rtw_down_sema(&padapter->recvpriv.terminate_recvthread_sema); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt:recv_thread can be terminated! \n")); +#endif + + +} + +u8 rtw_init_default_value(_adapter *padapter); +u8 rtw_init_default_value(_adapter *padapter) +{ + u8 ret = _SUCCESS; + struct registry_priv* pregistrypriv = &padapter->registrypriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + + //xmit_priv + pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; + pxmitpriv->vcs = pregistrypriv->vcs_type; + pxmitpriv->vcs_type = pregistrypriv->vcs_type; + //pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; + pxmitpriv->frag_len = pregistrypriv->frag_thresh; + + + + //recv_priv + + + //mlme_priv + pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec + pmlmepriv->scan_mode = SCAN_ACTIVE; + + //qos_priv + //pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable; + + //ht_priv +#ifdef CONFIG_80211N_HT + pmlmepriv->htpriv.ampdu_enable = _FALSE;//set to disabled +#endif + + //security_priv + //rtw_get_encrypt_decrypt_from_registrypriv(padapter); + psecuritypriv->binstallGrpkey = _FAIL; + psecuritypriv->sw_encrypt=pregistrypriv->software_encrypt; + psecuritypriv->sw_decrypt=pregistrypriv->software_decrypt; + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + + psecuritypriv->dot11PrivacyKeyIndex = 0; + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpKeyid = 1; + + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; + + + //pwrctrl_priv + + + //registry_priv + rtw_init_registrypriv_dev_network(padapter); + rtw_update_registrypriv_dev_network(padapter); + + + //hal_priv + rtw_hal_def_value_init(padapter); + + //misc. + padapter->bReadPortCancel = _FALSE; + padapter->bWritePortCancel = _FALSE; + padapter->bRxRSSIDisplay = 0; + padapter->bForceWriteInitGain = 1; + padapter->bNotifyChannelChange = 0; +#ifdef CONFIG_P2P + padapter->bShowGetP2PState = 1; +#endif + return ret; +} + +struct dvobj_priv *devobj_init(void) +{ + struct dvobj_priv *pdvobj = NULL; + + if ((pdvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*pdvobj))) == NULL) + return NULL; + + _rtw_mutex_init(&pdvobj->hw_init_mutex); + _rtw_mutex_init(&pdvobj->h2c_fwcmd_mutex); + _rtw_mutex_init(&pdvobj->setch_mutex); + _rtw_mutex_init(&pdvobj->setbw_mutex); + + pdvobj->processing_dev_remove = _FALSE; + + return pdvobj; +} + +void devobj_deinit(struct dvobj_priv *pdvobj) +{ + if(!pdvobj) + return; + + _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_mfree((u8*)pdvobj, sizeof(*pdvobj)); +} + +u8 rtw_reset_drv_sw(_adapter *padapter) +{ + u8 ret8=_SUCCESS; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + + //hal_priv + rtw_hal_def_value_init(padapter); + padapter->bReadPortCancel = _FALSE; + padapter->bWritePortCancel = _FALSE; + padapter->bRxRSSIDisplay = 0; + pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec + + pwrctrlpriv->bips_processing = _FALSE; + pwrctrlpriv->rf_pwrstate = rf_on; + + padapter->xmitpriv.tx_pkts = 0; + padapter->recvpriv.rx_pkts = 0; + + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY |_FW_UNDER_LINKING); + +#ifdef CONFIG_AUTOSUSPEND + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + adapter_to_dvobj(padapter)->pusbdev->autosuspend_disabled = 1;//autosuspend disabled by the user + #endif +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_reset_value(padapter); +#endif + pwrctrlpriv->pwr_state_check_cnts = 0; + + //mlmeextpriv + padapter->mlmeextpriv.sitesurvey_res.state= SCAN_DISABLE; + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + + return ret8; +} + + +u8 rtw_init_drv_sw(_adapter *padapter) +{ + + u8 ret8=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_init_drv_sw\n")); + + if ((rtw_init_cmd_priv(&padapter->cmdpriv)) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init cmd_priv\n")); + ret8=_FAIL; + goto exit; + } + + padapter->cmdpriv.padapter=padapter; + + if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init evt_priv\n")); + ret8=_FAIL; + goto exit; + } + + + if (rtw_init_mlme_priv(padapter) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init mlme_priv\n")); + ret8=_FAIL; + goto exit; + } + +#ifdef CONFIG_P2P + rtw_init_wifidirect_timers(padapter); + init_wifidirect_info(padapter, P2P_ROLE_DISABLE); + reset_global_wifidirect_info(padapter); + #ifdef CONFIG_IOCTL_CFG80211 + rtw_init_cfg80211_wifidirect_info(padapter); + #endif +#ifdef CONFIG_WFD + if(rtw_init_wifi_display_info(padapter) == _FAIL) + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init init_wifi_display_info\n")); +#endif +#endif /* CONFIG_P2P */ + + if(init_mlme_ext_priv(padapter) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init mlme_ext_priv\n")); + ret8=_FAIL; + goto exit; + } + +#ifdef CONFIG_TDLS + if(rtw_init_tdls_info(padapter) == _FAIL) + { + DBG_871X("Can't rtw_init_tdls_info\n"); + ret8=_FAIL; + goto exit; + } +#endif //CONFIG_TDLS + + if(_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) + { + DBG_871X("Can't _rtw_init_xmit_priv\n"); + ret8=_FAIL; + goto exit; + } + + if(_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) + { + DBG_871X("Can't _rtw_init_recv_priv\n"); + ret8=_FAIL; + goto exit; + } + // add for CONFIG_IEEE80211W, none 11w also can use + _rtw_spinlock_init(&padapter->security_key_mutex); + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); + + //_init_timer(&(padapter->securitypriv.tkip_timer), padapter->pifp, rtw_use_tkipkey_handler, padapter); + + if(_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) + { + DBG_871X("Can't _rtw_init_sta_priv\n"); + ret8=_FAIL; + goto exit; + } + + padapter->stapriv.padapter = padapter; + padapter->setband = GHZ24_50; + rtw_init_bcmc_stainfo(padapter); + + rtw_init_pwrctrl_priv(padapter); + + //_rtw_memset((u8 *)&padapter->qospriv, 0, sizeof (struct qos_priv));//move to mlme_priv + +#ifdef CONFIG_MP_INCLUDED + if (init_mp_priv(padapter) == _FAIL) { + DBG_871X("%s: initialize MP private data Fail!\n", __func__); + } +#endif + + ret8 = rtw_init_default_value(padapter); + + rtw_hal_dm_init(padapter); + rtw_hal_sw_led_init(padapter); + +#ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_init(padapter); +#endif + +#ifdef CONFIG_INTEL_WIDI + if(rtw_init_intel_widi(padapter) == _FAIL) + { + DBG_871X("Can't rtw_init_intel_widi\n"); + ret8=_FAIL; + goto exit; + } +#endif //CONFIG_INTEL_WIDI + +#ifdef CONFIG_BR_EXT + _rtw_spinlock_init(&padapter->br_ext_lock); +#endif // CONFIG_BR_EXT + +exit: + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-rtw_init_drv_sw\n")); + + _func_exit_; + + return ret8; + +} + +void rtw_cancel_all_timer(_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_cancel_all_timer\n")); + + _cancel_timer_ex(&padapter->mlmepriv.assoc_timer); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel association timer complete! \n")); + + //_cancel_timer_ex(&padapter->securitypriv.tkip_timer); + //RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel tkip_timer! \n")); + + _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel scan_to_timer! \n")); + + _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel dynamic_chk_timer! \n")); + + // cancel sw led timer + rtw_hal_sw_led_deinit(padapter); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel DeInitSwLeds! \n")); + + _cancel_timer_ex(&padapter->pwrctrlpriv.pwr_state_check_timer); + +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P + _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); +#endif //CONFIG_P2P +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_SET_SCAN_DENY_TIMER + _cancel_timer_ex(&padapter->mlmepriv.set_scan_deny_timer); + rtw_clear_scan_deny(padapter); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel set_scan_deny_timer! \n")); +#endif + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer); +#endif + + // cancel dm timer + rtw_hal_dm_deinit(padapter); + +#ifdef CONFIG_PLATFORM_FS_MX61 + msleep(50); +#endif +} + +u8 rtw_free_drv_sw(_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("==>rtw_free_drv_sw")); + + + //we can call rtw_p2p_enable here, but: + // 1. rtw_p2p_enable may have IO operation + // 2. rtw_p2p_enable is bundled with wext interface + #ifdef CONFIG_P2P + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); +#ifdef CONFIG_CONCURRENT_MODE + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); +#endif // CONFIG_CONCURRENT_MODE + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + } + } + #endif + // add for CONFIG_IEEE80211W, none 11w also can use + _rtw_spinlock_free(&padapter->security_key_mutex); + +#ifdef CONFIG_BR_EXT + _rtw_spinlock_free(&padapter->br_ext_lock); +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_INTEL_WIDI + rtw_free_intel_widi(padapter); +#endif //CONFIG_INTEL_WIDI + + free_mlme_ext_priv(&padapter->mlmeextpriv); + +#ifdef CONFIG_TDLS + //rtw_free_tdls_info(&padapter->tdlsinfo); +#endif //CONFIG_TDLS + + rtw_free_cmd_priv(&padapter->cmdpriv); + + rtw_free_evt_priv(&padapter->evtpriv); + + rtw_free_mlme_priv(&padapter->mlmepriv); + + //free_io_queue(padapter); + + _rtw_free_xmit_priv(&padapter->xmitpriv); + + _rtw_free_sta_priv(&padapter->stapriv); //will free bcmc_stainfo here + + _rtw_free_recv_priv(&padapter->recvpriv); + + rtw_free_pwrctrl_priv(padapter); + + //rtw_mfree((void *)padapter, sizeof (padapter)); + +#ifdef CONFIG_DRVEXT_MODULE + free_drvext(&padapter->drvextpriv); +#endif + + rtw_hal_free_data(padapter); + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("<==rtw_free_drv_sw\n")); + + //free the old_pnetdev + if(padapter->rereg_nd_name_priv.old_pnetdev) { + free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); + padapter->rereg_nd_name_priv.old_pnetdev = NULL; + } + + // clear pbuddy_adapter to avoid access wrong pointer. + if(padapter->pbuddy_adapter != NULL) + { + padapter->pbuddy_adapter->pbuddy_adapter = NULL; + } + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-rtw_free_drv_sw\n")); + + return _SUCCESS; + +} + +#ifdef CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_USB_HCI + #include +#endif + +#ifdef CONFIG_MULTI_VIR_IFACES +int _netdev_vir_if_open(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + _adapter *primary_padapter = GET_PRIMARY_ADAPTER(padapter); + + DBG_871X(FUNC_NDEV_FMT" enter\n", FUNC_NDEV_ARG(pnetdev)); + + if(!primary_padapter) + goto _netdev_virtual_iface_open_error; + + if(primary_padapter->bup == _FALSE || primary_padapter->hw_init_completed == _FALSE) + { + _netdev_open(primary_padapter->pnetdev); + } + + if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE && + primary_padapter->hw_init_completed == _TRUE) + { + int i; + + padapter->bDriverStopped = _FALSE; + padapter->bSurpriseRemoved = _FALSE; + padapter->bCardDisableWOHSM = _FALSE; + + _rtw_memcpy(padapter->HalData, primary_padapter->HalData, padapter->hal_data_sz); + + padapter->bFWReady = primary_padapter->bFWReady; + + if(rtw_start_drv_threads(padapter) == _FAIL) + { + goto _netdev_virtual_iface_open_error; + } + + padapter->dir_dev = NULL; + rtw_proc_init_one(pnetdev); + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + padapter->bup = _TRUE; + padapter->hw_init_completed = _TRUE; + + rtw_start_mbssid_cam(padapter);//start mbssid_cam after bup = _TRUE & hw_init_completed = _TRUE + + } + + padapter->net_closed = _FALSE; + + _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); + + + DBG_871X(FUNC_NDEV_FMT" exit\n", FUNC_NDEV_ARG(pnetdev)); + return 0; + +_netdev_virtual_iface_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + return (-1); + +} + +int netdev_vir_if_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_vir_if_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + return ret; +} + +static int netdev_vir_if_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + padapter->net_closed = _TRUE; + + if(pnetdev) + { + if (!rtw_netif_queue_stopped(pnetdev)) + rtw_netif_stop_queue(pnetdev); + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + wdev_to_priv(padapter->rtw_wdev)->bandroid_scan = _FALSE; +#endif + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_vir_if_ops = { + .ndo_open = netdev_vir_if_open, + .ndo_stop = netdev_vir_if_close, + .ndo_start_xmit = rtw_xmit_entry, + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif +}; +#endif + +_adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, void (*set_intf_ops)(struct _io_ops *pops)) +{ + + int res = _FAIL; + struct net_device *pnetdev=NULL; + _adapter *padapter = NULL; + struct dvobj_priv *pdvobjpriv; + u8 mac[ETH_ALEN]; + +/* + if((primary_padapter->bup == _FALSE) || + (rtw_buddy_adapter_up(primary_padapter) == _FALSE)) + { + goto error_rtw_drv_add_iface; + } + +*/ + /****** init netdev ******/ + pnetdev = rtw_init_netdev(NULL); + if (!pnetdev) + goto error_rtw_drv_add_iface; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + DBG_871X("register rtw_netdev_virtual_iface_ops to netdev_ops\n"); + pnetdev->netdev_ops = &rtw_netdev_vir_if_ops; +#else + pnetdev->open = netdev_vir_if_open; + pnetdev->stop = netdev_vir_if_close; +#endif + +#ifdef CONFIG_NO_WIRELESS_HANDLERS + pnetdev->wireless_handlers = NULL; +#endif + + /****** init adapter ******/ + padapter = rtw_netdev_priv(pnetdev); + _rtw_memcpy(padapter, primary_padapter, sizeof(_adapter)); + + // + padapter->bup = _FALSE; + padapter->net_closed = _TRUE; + padapter->hw_init_completed = _FALSE; + + + //set adapter_type/iface type + padapter->isprimary = _FALSE; + padapter->adapter_type = MAX_ADAPTER; + padapter->pbuddy_adapter = primary_padapter; +#if 0 +#ifndef CONFIG_HWPORT_SWAP //Port0 -> Pri , Port1 -> Sec + padapter->iface_type = IFACE_PORT1; +#else + padapter->iface_type = IFACE_PORT0; +#endif //CONFIG_HWPORT_SWAP +#else + //extended virtual interfaces always are set to port0 + padapter->iface_type = IFACE_PORT0; +#endif + // + padapter->pnetdev = pnetdev; + + /****** setup dvobj ******/ + pdvobjpriv = adapter_to_dvobj(padapter); + padapter->iface_id = pdvobjpriv->iface_nums; + pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter; + + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(pdvobjpriv)); +#ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_alloc(padapter, dvobj_to_dev(pdvobjpriv)); +#endif //CONFIG_IOCTL_CFG80211 + + //set interface_type/chip_type/HardwareType + padapter->interface_type = primary_padapter->interface_type; + padapter->chip_type = primary_padapter->chip_type; + padapter->HardwareType = primary_padapter->HardwareType; + + //set hal data & hal ops +#if defined(CONFIG_RTL8192C) + #if defined(CONFIG_PCI_HCI) + rtl8192ce_set_hal_ops(padapter); + #elif defined(CONFIG_USB_HCI) + rtl8192cu_set_hal_ops(padapter); + #endif +#elif defined(CONFIG_RTL8192D) + #if defined(CONFIG_PCI_HCI) + rtl8192de_set_hal_ops(padapter); + #elif defined(CONFIG_USB_HCI) + rtl8192du_set_hal_ops(padapter); + #endif +#endif + + padapter->HalFunc.inirp_init = NULL; + padapter->HalFunc.inirp_deinit = NULL; + padapter->intf_start = NULL; + padapter->intf_stop = NULL; + + //step init_io_priv + if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n")); + } + + //step read_chip_version + rtw_hal_read_chip_version(padapter); + + //step usb endpoint mapping + rtw_hal_chip_configure(padapter); + + + //init drv data + if(rtw_init_drv_sw(padapter)!= _SUCCESS) + goto error_rtw_drv_add_iface; + + + //get mac address from primary_padapter + _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 +#if 1 //needs enable MBSSID CAM + mac[0] |= BIT(1); // locally administered + mac[0] |= (padapter->iface_id-1)<<4; +#endif + } + + _rtw_memcpy(padapter->eeprompriv.mac_addr, mac, ETH_ALEN); + + padapter->dir_dev = NULL; + + res = _SUCCESS; + + return padapter; + + +error_rtw_drv_add_iface: + + if(padapter) + rtw_free_drv_sw(padapter); + + if (pnetdev) + rtw_free_netdev(pnetdev); + + return NULL; + +} + +void rtw_drv_stop_vir_if(_adapter *padapter) +{ + struct net_device *pnetdev=NULL; + + if (padapter == NULL) + return; + + pnetdev = padapter->pnetdev; + + rtw_cancel_all_timer(padapter); + + if(padapter->bup == _TRUE) + { + padapter->bDriverStopped = _TRUE; + + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + if(padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + rtw_stop_drv_threads(padapter); + + padapter->bup = _FALSE; + } +} + +void rtw_drv_free_vir_if(_adapter *padapter) +{ + struct net_device *pnetdev=NULL; + + if (padapter == NULL) + return; + + padapter->pbuddy_adapter = NULL; + + pnetdev = padapter->pnetdev; + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_free(padapter->rtw_wdev); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_free_drv_sw(padapter); + + rtw_free_netdev(pnetdev); +} + +void rtw_drv_stop_vir_ifaces(struct dvobj_priv *dvobj) +{ + int i; + //struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_stop_vir_if(dvobj->padapters[i]); + } +} + +void rtw_drv_free_vir_ifaces(struct dvobj_priv *dvobj) +{ + int i; + //struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_free_vir_if(dvobj->padapters[i]); + } +} + +void rtw_drv_del_vir_if(_adapter *padapter) +{ + rtw_drv_stop_vir_if(padapter); + rtw_drv_free_vir_if(padapter); +} + +void rtw_drv_del_vir_ifaces(_adapter *primary_padapter) +{ + int i; + struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_del_vir_if(dvobj->padapters[i]); + } +} +#endif //CONFIG_MULTI_VIR_IFACES + +int _netdev_if2_open(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + _adapter *primary_padapter = padapter->pbuddy_adapter; + + DBG_871X("+871x_drv - if2_open, bup=%d\n", padapter->bup); + + if(primary_padapter->bup == _FALSE || primary_padapter->hw_init_completed == _FALSE) + { + _netdev_open(primary_padapter->pnetdev); + } + + if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE && + primary_padapter->hw_init_completed == _TRUE) + { + int i; + + padapter->bDriverStopped = _FALSE; + padapter->bSurpriseRemoved = _FALSE; + padapter->bCardDisableWOHSM = _FALSE; + + _rtw_memcpy(padapter->HalData, primary_padapter->HalData, padapter->hal_data_sz); + + padapter->bFWReady = primary_padapter->bFWReady; + + rtw_hal_set_hwreg(padapter, HW_VAR_DM_INIT_PWDB, NULL); + + //if (init_mlme_ext_priv(padapter) == _FAIL) + // goto netdev_if2_open_error; + + + if(rtw_start_drv_threads(padapter) == _FAIL) + { + goto netdev_if2_open_error; + } + + + if(padapter->intf_start) + { + padapter->intf_start(padapter); + } + + + padapter->hw_init_completed = _TRUE; + + padapter->dir_dev = NULL; + rtw_proc_init_one(pnetdev); + + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + padapter->bup = _TRUE; + + } + + padapter->net_closed = _FALSE; + + _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); + + DBG_871X("-871x_drv - if2_open, bup=%d\n", padapter->bup); + return 0; + +netdev_if2_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + return (-1); + +} + +int netdev_if2_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_if2_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + return ret; +} + +static int netdev_if2_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + padapter->net_closed = _TRUE; + + if(pnetdev) + { + if (!rtw_netif_queue_stopped(pnetdev)) + rtw_netif_stop_queue(pnetdev); + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + wdev_to_priv(padapter->rtw_wdev)->bandroid_scan = _FALSE; +#endif + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_if2_ops = { + .ndo_open = netdev_if2_open, + .ndo_stop = netdev_if2_close, + .ndo_start_xmit = rtw_xmit_entry, + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif +}; +#endif + +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, void (*set_intf_ops)(struct _io_ops *pops)) +{ + int res = _FAIL; + struct net_device *pnetdev = NULL; + _adapter *padapter = NULL; + struct dvobj_priv *pdvobjpriv; + u8 mac[ETH_ALEN]; + + /****** init netdev ******/ + pnetdev = rtw_init_netdev(NULL); + if (!pnetdev) + goto error_rtw_drv_if2_init; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + DBG_871X("register rtw_netdev_if2_ops to netdev_ops\n"); + pnetdev->netdev_ops = &rtw_netdev_if2_ops; +#else + pnetdev->open = netdev_if2_open; + pnetdev->stop = netdev_if2_close; +#endif + +#ifdef CONFIG_NO_WIRELESS_HANDLERS + pnetdev->wireless_handlers = NULL; +#endif + + /****** init adapter ******/ + padapter = rtw_netdev_priv(pnetdev); + _rtw_memcpy(padapter, primary_padapter, sizeof(_adapter)); + + // + padapter->bup = _FALSE; + padapter->net_closed = _TRUE; + padapter->hw_init_completed = _FALSE; + + //set adapter_type/iface type + padapter->isprimary = _FALSE; + padapter->adapter_type = SECONDARY_ADAPTER; + padapter->pbuddy_adapter = primary_padapter; + padapter->iface_id = IFACE_ID1; +#ifndef CONFIG_HWPORT_SWAP //Port0 -> Pri , Port1 -> Sec + padapter->iface_type = IFACE_PORT1; +#else + padapter->iface_type = IFACE_PORT0; +#endif //CONFIG_HWPORT_SWAP + // + padapter->pnetdev = pnetdev; + + /****** setup dvobj ******/ + pdvobjpriv = adapter_to_dvobj(padapter); + pdvobjpriv->if2 = padapter; + pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter; + + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(pdvobjpriv)); + #ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_alloc(padapter, dvobj_to_dev(pdvobjpriv)); + #endif //CONFIG_IOCTL_CFG80211 + + //set interface_type/chip_type/HardwareType + padapter->interface_type = primary_padapter->interface_type; + padapter->chip_type = primary_padapter->chip_type; + padapter->HardwareType = primary_padapter->HardwareType; + + //set hal data & hal ops +#if defined(CONFIG_RTL8192C) + #if defined(CONFIG_PCI_HCI) + rtl8192ce_set_hal_ops(padapter); + #elif defined(CONFIG_USB_HCI) + rtl8192cu_set_hal_ops(padapter); + #endif +#elif defined(CONFIG_RTL8192D) + #if defined(CONFIG_PCI_HCI) + rtl8192de_set_hal_ops(padapter); + #elif defined(CONFIG_USB_HCI) + rtl8192du_set_hal_ops(padapter); + #endif +#endif + + padapter->HalFunc.inirp_init = NULL; + padapter->HalFunc.inirp_deinit = NULL; + + // + padapter->intf_start = primary_padapter->intf_start; + padapter->intf_stop = primary_padapter->intf_stop; + + //step init_io_priv + if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n")); + } + + //step read_chip_version + rtw_hal_read_chip_version(padapter); + + //step usb endpoint mapping + rtw_hal_chip_configure(padapter); + + + //init drv data + if(rtw_init_drv_sw(padapter)!= _SUCCESS) + goto error_rtw_drv_if2_init; + + //get mac address from primary_padapter + _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); + + primary_padapter->pbuddy_adapter = padapter; + + padapter->dir_dev = NULL; + + res = _SUCCESS; + + return padapter; + + +error_rtw_drv_if2_init: + + if(padapter) + rtw_free_drv_sw(padapter); + + if (pnetdev) + rtw_free_netdev(pnetdev); + + return NULL; + +} + +void rtw_drv_if2_free(_adapter *if2) +{ + _adapter *padapter = if2; + struct net_device *pnetdev = NULL; + + if (padapter == NULL) + return; + + pnetdev = padapter->pnetdev; + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_free(padapter->rtw_wdev); +#endif /* CONFIG_IOCTL_CFG80211 */ + + + rtw_free_drv_sw(padapter); + + rtw_free_netdev(pnetdev); + +} + +void rtw_drv_if2_stop(_adapter *if2) +{ + _adapter *padapter = if2; + + if (padapter == NULL) + return; + + rtw_cancel_all_timer(padapter); + + if (padapter->bup == _TRUE) { + padapter->bDriverStopped = _TRUE; + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + if(padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + rtw_stop_drv_threads(padapter); + + padapter->bup = _FALSE; + } +} +#endif //end of CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_BR_EXT +void netdev_br_init(struct net_device *netdev) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + + //if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + //struct net_bridge *br = netdev->br_port->br;//->dev->dev_addr; +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if (netdev->br_port) +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if (rcu_dereference(adapter->pnetdev->rx_handler_data)) +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + { + struct net_device *br_netdev; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + br_netdev = dev_get_by_name(CONFIG_BR_EXT_BRNAME); +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + struct net *devnet = NULL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = netdev->nd_net; +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = dev_net(netdev); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + + br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + + if (br_netdev) { + memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN); + dev_put(br_netdev); + } else + printk("%s()-%d: dev_get_by_name(%s) failed!", __FUNCTION__, __LINE__, CONFIG_BR_EXT_BRNAME); + } + + adapter->ethBrExtInfo.addPPPoETag = 1; + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) +} +#endif //CONFIG_BR_EXT + +static int _rtw_drv_register_netdev(_adapter *padapter, char *name) +{ + int ret = _SUCCESS; + struct net_device *pnetdev = padapter->pnetdev; + + /* alloc netdev name */ + rtw_init_netdev_name(pnetdev, name); + + _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); + + /* Tell the network stack we exist */ + if (register_netdev(pnetdev) != 0) { + DBG_871X(FUNC_NDEV_FMT "Failed!\n", FUNC_NDEV_ARG(pnetdev)); + ret = _FAIL; + goto error_register_netdev; + } + + DBG_871X("%s, MAC Address (if%d) = " MAC_FMT "\n", __FUNCTION__, (padapter->iface_id+1), MAC_ARG(pnetdev->dev_addr)); + + return ret; + +error_register_netdev: + + if(padapter->iface_id > IFACE_ID0) + { + rtw_free_drv_sw(padapter); + + rtw_free_netdev(pnetdev); + } + + return ret; +} + +int rtw_drv_register_netdev(_adapter *if1) +{ + int i, status = _SUCCESS; + struct dvobj_priv *dvobj = if1->dvobj; + + if(dvobj->iface_nums < IFACE_ID_MAX) + { + for(i=0; iiface_nums; i++) + { + _adapter *padapter = dvobj->padapters[i]; + + if(padapter) + { + char *name; + + if(padapter->iface_id == IFACE_ID0) + name = if1->registrypriv.ifname; + else if(padapter->iface_id == IFACE_ID1) + name = if1->registrypriv.if2name; + else + name = "wlan%d"; + + if((status = _rtw_drv_register_netdev(padapter, name)) != _SUCCESS) { + break; + } + } + } + } + + return status; +} + +int _netdev_open(struct net_device *pnetdev) +{ + uint status; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - dev_open\n")); + DBG_871X("+871x_drv - drv_open, bup=%d\n", padapter->bup); + + if(pwrctrlpriv->ps_flag == _TRUE){ + padapter->net_closed = _FALSE; + goto netdev_open_normal_process; + } + + if(padapter->bup == _FALSE) + { + padapter->bDriverStopped = _FALSE; + padapter->bSurpriseRemoved = _FALSE; + padapter->bCardDisableWOHSM = _FALSE; + + status = rtw_hal_init(padapter); + if (status ==_FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("rtl871x_hal_init(): Can't init h/w!\n")); + goto netdev_open_error; + } + + DBG_871X("MAC Address = "MAC_FMT"\n", MAC_ARG(pnetdev->dev_addr)); + + + status=rtw_start_drv_threads(padapter); + if(status ==_FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("Initialize driver software resource Failed!\n")); + goto netdev_open_error; + } + +#ifdef CONFIG_DRVEXT_MODULE + init_drvext(padapter); +#endif + + if(padapter->intf_start) + { + padapter->intf_start(padapter); + } + +#ifndef RTK_DMP_PLATFORM + rtw_proc_init_one(pnetdev); +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + padapter->bup = _TRUE; + } + padapter->net_closed = _FALSE; + + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + + padapter->pwrctrlpriv.bips_processing = _FALSE; + rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); + + //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); + +#ifdef CONFIG_BR_EXT + netdev_br_init(pnetdev); +#endif // CONFIG_BR_EXT + +netdev_open_normal_process: + + #ifdef CONFIG_CONCURRENT_MODE + { + _adapter *sec_adapter = padapter->pbuddy_adapter; + if(sec_adapter && (sec_adapter->bup == _FALSE || sec_adapter->hw_init_completed == _FALSE)) + _netdev_if2_open(sec_adapter->pnetdev); + } + #endif + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - dev_open\n")); + DBG_871X("-871x_drv - drv_open, bup=%d\n", padapter->bup); + + return 0; + +netdev_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + RT_TRACE(_module_os_intfs_c_,_drv_err_,("-871x_drv - dev_open, fail!\n")); + DBG_871X("-871x_drv - drv_open fail, bup=%d\n", padapter->bup); + + return (-1); + +} + +int netdev_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + + return ret; +} + +#ifdef CONFIG_IPS +int ips_netdrv_open(_adapter *padapter) +{ + int status = _SUCCESS; + padapter->net_closed = _FALSE; + DBG_871X("===> %s.........\n",__FUNCTION__); + + + padapter->bDriverStopped = _FALSE; + padapter->bCardDisableWOHSM = _FALSE; + //padapter->bup = _TRUE; + + status = rtw_hal_init(padapter); + if (status ==_FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("ips_netdrv_open(): Can't init h/w!\n")); + goto netdev_open_error; + } + + if(padapter->intf_start) + { + padapter->intf_start(padapter); + } + + rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); + _set_timer(&padapter->mlmepriv.dynamic_chk_timer,5000); + + return _SUCCESS; + +netdev_open_error: + //padapter->bup = _FALSE; + DBG_871X("-ips_netdrv_open - drv_open failure, bup=%d\n", padapter->bup); + + return _FAIL; +} + + +int rtw_ips_pwr_up(_adapter *padapter) +{ + int result; + u32 start_time = rtw_get_current_time(); + DBG_871X("===> rtw_ips_pwr_up..............\n"); + rtw_reset_drv_sw(padapter); + + result = ips_netdrv_open(padapter); + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + DBG_871X("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); + return result; + +} + +void rtw_ips_pwr_down(_adapter *padapter) +{ + u32 start_time = rtw_get_current_time(); + DBG_871X("===> rtw_ips_pwr_down...................\n"); + + padapter->bCardDisableWOHSM = _TRUE; + padapter->net_closed = _TRUE; + + rtw_led_control(padapter, LED_CTL_POWER_OFF); + + rtw_ips_dev_unload(padapter); + padapter->bCardDisableWOHSM = _FALSE; + DBG_871X("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); +} +#endif +void rtw_ips_dev_unload(_adapter *padapter) +{ + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + DBG_871X("====> %s...\n",__FUNCTION__); + + rtw_hal_set_hwreg(padapter, HW_VAR_FIFO_CLEARN_UP, 0); + + if(padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + //s5. + if(padapter->bSurpriseRemoved == _FALSE) + { + rtw_hal_deinit(padapter); + } + +} + +int pm_netdev_open(struct net_device *pnetdev,u8 bnormal) +{ + int status; + if(bnormal) + status = netdev_open(pnetdev); +#ifdef CONFIG_IPS + else + status = (_SUCCESS == ips_netdrv_open((_adapter *)rtw_netdev_priv(pnetdev)))?(0):(-1); +#endif + + return status; +} + +static int netdev_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - drv_close\n")); + + if(padapter->pwrctrlpriv.bInternalAutoSuspend == _TRUE) + { + //rtw_pwr_wakeup(padapter); + if(padapter->pwrctrlpriv.rf_pwrstate == rf_off) + padapter->pwrctrlpriv.ps_flag = _TRUE; + } + padapter->net_closed = _TRUE; + +/* if(!padapter->hw_init_completed) + { + DBG_871X("(1)871x_drv - drv_close, bup=%d, hw_init_completed=%d\n", padapter->bup, padapter->hw_init_completed); + + padapter->bDriverStopped = _TRUE; + + rtw_dev_unload(padapter); + } + else*/ + if(padapter->pwrctrlpriv.rf_pwrstate == rf_on){ + DBG_871X("(2)871x_drv - drv_close, bup=%d, hw_init_completed=%d\n", padapter->bup, padapter->hw_init_completed); + + //s1. + if(pnetdev) + { + if (!rtw_netif_queue_stopped(pnetdev)) + rtw_netif_stop_queue(pnetdev); + } + +#ifndef CONFIG_ANDROID + //s2. + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + //s2-2. indicate disconnect to os + rtw_indicate_disconnect(padapter); + //s2-3. + rtw_free_assoc_resources(padapter, 1); + //s2-4. + rtw_free_network_queue(padapter,_TRUE); +#endif + // Close LED + rtw_led_control(padapter, LED_CTL_POWER_OFF); + } + +#ifdef CONFIG_BR_EXT + //if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE)) + { + //void nat25_db_cleanup(_adapter *priv); + nat25_db_cleanup(padapter); + } +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_P2P +#ifdef CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _TRUE) + wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _FALSE; + } +#endif //CONFIG_IOCTL_CFG80211 + rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); +#endif //CONFIG_P2P + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + wdev_to_priv(padapter->rtw_wdev)->bandroid_scan = _FALSE; + padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR; //set this at the end +#endif //CONFIG_IOCTL_CFG80211 + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - drv_close\n")); + DBG_871X("-871x_drv - drv_close, bup=%d\n", padapter->bup); + + return 0; +} + +void rtw_ndev_destructor(struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + +#ifdef CONFIG_IOCTL_CFG80211 + if (ndev->ieee80211_ptr) + rtw_mfree((u8 *)ndev->ieee80211_ptr, sizeof(struct wireless_dev)); +#endif + free_netdev(ndev); +} + diff --git a/rtl8192cu-fixes/os_dep/linux/pci_intf.c b/rtl8192cu-fixes/os_dep/linux/pci_intf.c new file mode 100755 index 00000000..5bf576f1 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/pci_intf.c @@ -0,0 +1,1997 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_INTF_C_ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_PCI_HCI + +#error "CONFIG_PCI_HCI shall be on!\n" + +#endif + +#include +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#ifdef CONFIG_80211N_HT +extern int rtw_ht_enable; +extern int rtw_cbw40_enable; +extern int rtw_ampdu_enable;//for enable tx_ampdu +#endif + +#ifdef CONFIG_PM +extern int pm_netdev_open(struct net_device *pnetdev); +static int rtw_suspend(struct pci_dev *pdev, pm_message_t state); +static int rtw_resume(struct pci_dev *pdev); +#endif + + +static int rtw_drv_init(struct pci_dev *pdev, const struct pci_device_id *pdid); +static void rtw_dev_remove(struct pci_dev *pdev); + +static struct specific_device_id specific_device_id_tbl[] = { + {.idVendor=0x0b05, .idProduct=0x1791, .flags=SPEC_DEV_ID_DISABLE_HT}, + {.idVendor=0x13D3, .idProduct=0x3311, .flags=SPEC_DEV_ID_DISABLE_HT}, + {} +}; + +struct pci_device_id rtw_pci_id_tbl[] = { +#ifdef CONFIG_RTL8192C + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x8191)}, + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x8178)}, + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x8177)}, + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x8176)}, +#endif +#ifdef CONFIG_RTL8192D + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x8193)}, + {PCI_DEVICE(PCI_VENDER_ID_REALTEK, 0x002B)}, +#endif + {}, +}; + +struct pci_drv_priv { + struct pci_driver rtw_pci_drv; + int drv_registered; +}; + + +static struct pci_drv_priv pci_drvpriv = { + .rtw_pci_drv.name = (char*)DRV_NAME, + .rtw_pci_drv.probe = rtw_drv_init, + .rtw_pci_drv.remove = rtw_dev_remove, + .rtw_pci_drv.id_table = rtw_pci_id_tbl, +#ifdef CONFIG_PM + .rtw_pci_drv.suspend = rtw_suspend, + .rtw_pci_drv.resume = rtw_resume, +#else + .rtw_pci_drv.suspend = NULL, + .rtw_pci_drv.resume = NULL, +#endif +}; + + +MODULE_DEVICE_TABLE(pci, rtw_pci_id_tbl); + + +static u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { + INTEL_VENDOR_ID, + ATI_VENDOR_ID, + AMD_VENDOR_ID, + SIS_VENDOR_ID +}; + +static u8 rtw_pci_platform_switch_device_pci_aspm(_adapter *padapter, u8 value) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 bresult = _SUCCESS; + int error; + + value |= 0x40; + + error = pci_write_config_byte(pdvobjpriv->ppcidev, 0x80, value); + + if(error != 0) + { + bresult = _FALSE; + DBG_871X("rtw_pci_platform_switch_device_pci_aspm error (%d)\n",error); + } + + return bresult; +} + +// +// When we set 0x01 to enable clk request. Set 0x0 to disable clk req. +// +static u8 rtw_pci_switch_clk_req(_adapter *padapter, u8 value) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 buffer, bresult = _SUCCESS; + int error; + + buffer = value; + + if(!padapter->hw_init_completed) + return bresult; + + error = pci_write_config_byte(pdvobjpriv->ppcidev, 0x81, value); + + if(error != 0) + { + bresult = _FALSE; + DBG_871X("rtw_pci_switch_clk_req error (%d)\n",error); + } + + return bresult; +} + +#if 0 +//Description: +//Disable RTL8192SE ASPM & Disable Pci Bridge ASPM +void rtw_pci_disable_aspm(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + u32 pcicfg_addrport = 0; + u8 num4bytes; + u8 linkctrl_reg; + u16 pcibridge_linkctrlreg, aspmlevel = 0; + + // When there exists anyone's busnum, devnum, and funcnum that are set to 0xff, + // we do not execute any action and return. + // if it is not intel bus then don't enable ASPM. + if ((pcipriv->busnumber == 0xff + && pcipriv->devnumber == 0xff + && pcipriv->funcnumber == 0xff) + || (pcipriv->pcibridge_busnum == 0xff + && pcipriv->pcibridge_devnum == 0xff + && pcipriv->pcibridge_funcnum == 0xff)) + { + DBG_871X("PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return; + } + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + DBG_871X("%s(): Disable ASPM. Recognize the Bus of PCI(Bridge) as UNKNOWN.\n", __func__); + } + + if (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + RT_CLEAR_PS_LEVEL(pwrpriv, RT_RF_OFF_LEVL_CLK_REQ); + rtw_pci_switch_clk_req(padapter, 0x0); + } + + { + // Suggested by SD1 for promising device will in L0 state after an I/O. + u8 tmp_u1b; + + pci_read_config_byte(pdvobjpriv->ppcidev, 0x80, &tmp_u1b); + } + + // Retrieve original configuration settings. + linkctrl_reg = pcipriv->linkctrl_reg; + pcibridge_linkctrlreg = pcipriv->pcibridge_linkctrlreg; + + // Set corresponding value. + aspmlevel |= BIT(0) | BIT(1); + linkctrl_reg &= ~aspmlevel; + pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); + + rtw_pci_platform_switch_device_pci_aspm(padapter, linkctrl_reg); + rtw_udelay_os(50); + + //When there exists anyone's busnum, devnum, and funcnum that are set to 0xff, + // we do not execute any action and return. + if ((pcipriv->busnumber == 0xff && + pcipriv->devnumber == 0xff && + pcipriv->funcnumber == 0xff) || + (pcipriv->pcibridge_busnum == 0xff && + pcipriv->pcibridge_devnum == 0xff + && pcipriv->pcibridge_funcnum == 0xff)) + { + //Do Nothing!! + } + else + { + //4 //Disable Pci Bridge ASPM + pcicfg_addrport = (pcipriv->pcibridge_busnum << 16) | + (pcipriv->pcibridge_devnum << 11) | + (pcipriv->pcibridge_funcnum << 8) | (1 << 31); + num4bytes = (pcipriv->pcibridge_pciehdr_offset + 0x10) / 4; + + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + + // now grab data port with device|vendor 4 byte dword + NdisRawWritePortUchar(PCI_CONF_DATA, pcibridge_linkctrlreg); + + DBG_871X("rtw_pci_disable_aspm():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcipriv->pcibridge_busnum, pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum, + (pcipriv->pcibridge_pciehdr_offset+0x10), pcibridge_linkctrlreg); + + rtw_udelay_os(50); + } +} + +//[ASPM] +//Description: +// Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for power saving +// We should follow the sequence to enable RTL8192SE first then enable Pci Bridge ASPM +// or the system will show bluescreen. +void rtw_pci_enable_aspm(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + u16 aspmlevel = 0; + u32 pcicfg_addrport = 0; + u8 num4bytes; + u8 u_pcibridge_aspmsetting = 0; + u8 u_device_aspmsetting = 0; + + // When there exists anyone's busnum, devnum, and funcnum that are set to 0xff, + // we do not execute any action and return. + // if it is not intel bus then don't enable ASPM. + + if ((pcipriv->busnumber == 0xff + && pcipriv->devnumber == 0xff + && pcipriv->funcnumber == 0xff) + || (pcipriv->pcibridge_busnum == 0xff + && pcipriv->pcibridge_devnum == 0xff + && pcipriv->pcibridge_funcnum == 0xff)) + { + DBG_871X("PlatformEnableASPM(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return; + } + + //4 Enable Pci Bridge ASPM + pcicfg_addrport = (pcipriv->pcibridge_busnum << 16) + | (pcipriv->pcibridge_devnum << 11) + | (pcipriv->pcibridge_funcnum << 8) | (1 << 31); + num4bytes = (pcipriv->pcibridge_pciehdr_offset + 0x10) / 4; + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + // now grab data port with device|vendor 4 byte dword + + u_pcibridge_aspmsetting = pcipriv->pcibridge_linkctrlreg | pdvobjpriv->const_hostpci_aspm_setting; + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL || + pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_SIS) + u_pcibridge_aspmsetting &= ~BIT(0); + + NdisRawWritePortUchar(PCI_CONF_DATA, u_pcibridge_aspmsetting); + + DBG_871X("PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcipriv->pcibridge_busnum, + pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum, + (pcipriv->pcibridge_pciehdr_offset+0x10), + u_pcibridge_aspmsetting); + + rtw_udelay_os(50); + + // Get ASPM level (with/without Clock Req) + aspmlevel |= pdvobjpriv->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->linkctrl_reg; + u_device_aspmsetting |= aspmlevel; + + rtw_pci_platform_switch_device_pci_aspm(padapter, u_device_aspmsetting); //(priv->linkctrl_reg | ASPMLevel)); + + if (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + rtw_pci_switch_clk_req(padapter, (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_SET_PS_LEVEL(pwrpriv, RT_RF_OFF_LEVL_CLK_REQ); + } + + rtw_udelay_os(50); +} + +// +//Description: +//To get link control field by searching from PCIe capability lists. +// +static u8 +rtw_get_link_control_field(_adapter *padapter, u8 busnum, u8 devnum, + u8 funcnum) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + struct rt_pci_capabilities_header capability_hdr; + u8 capability_offset, num4bytes; + u32 pcicfg_addrport = 0; + u8 linkctrl_reg; + u8 status = _FALSE; + + //If busnum, devnum, funcnum are set to 0xff. + if (busnum == 0xff && devnum == 0xff && funcnum == 0xff) { + DBG_871X("GetLinkControlField(): Fail to find PCIe Capability\n"); + return _FALSE; + } + + pcicfg_addrport = (busnum << 16) | (devnum << 11) | (funcnum << 8) | (1 << 31); + + //2PCIeCap + + // The device supports capability lists. Find the capabilities. + num4bytes = 0x34 / 4; + //get capability_offset + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + // now grab data port with device|vendor 4 byte dword + NdisRawReadPortUchar(PCI_CONF_DATA, &capability_offset); + + // Loop through the capabilities in search of the power management capability. + // The list is NULL-terminated, so the last offset will always be zero. + + while (capability_offset != 0) { + // First find the number of 4 Byte. + num4bytes = capability_offset / 4; + + // Read the header of the capability at this offset. If the retrieved capability is not + // the power management capability that we are looking for, follow the link to the + // next capability and continue looping. + + //4 get capability_hdr + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + // now grab data port with device|vendor 4 byte dword + NdisRawReadPortUshort(PCI_CONF_DATA, (u16 *) & capability_hdr); + + // Found the PCI express capability + if (capability_hdr.capability_id == PCI_CAPABILITY_ID_PCI_EXPRESS) + { + break; + } + else + { + // This is some other capability. Keep looking for the PCI express capability. + capability_offset = capability_hdr.next; + } + } + + if (capability_hdr.capability_id == PCI_CAPABILITY_ID_PCI_EXPRESS) // + { + num4bytes = (capability_offset + 0x10) / 4; + + //4 Read Link Control Register + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + // now grab data port with device|vendor 4 byte dword + NdisRawReadPortUchar(PCI_CONF_DATA, &linkctrl_reg); + + pcipriv->pcibridge_pciehdr_offset = capability_offset; + pcipriv->pcibridge_linkctrlreg = linkctrl_reg; + + status = _TRUE; + } + else + { + // We didn't find a PCIe capability. + DBG_871X("GetLinkControlField(): Cannot Find PCIe Capability\n"); + } + + return status; +} + +// +//Description: +//To get PCI bus infomation and return busnum, devnum, and funcnum about +//the bus(bridge) which the device binds. +// +static u8 +rtw_get_pci_bus_info(_adapter *padapter, + u16 vendorid, + u16 deviceid, + u8 irql, u8 basecode, u8 subclass, u8 filed19val, + u8 * busnum, u8 * devnum, u8 * funcnum) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pci_dev *pdev = pdvobjpriv->ppcidev; + u8 busnum_idx, devicenum_idx, functionnum_idx; + u32 pcicfg_addrport = 0; + u32 dev_venid = 0, classcode, field19, headertype; + u16 venId, devId; + u8 basec, subc, irqline; + u16 regoffset; + u8 b_singlefunc = _FALSE; + u8 b_bridgechk = _FALSE; + + *busnum = 0xFF; + *devnum = 0xFF; + *funcnum = 0xFF; + + //DBG_871X("==============>vendorid:%x,deviceid:%x,irql:%x\n", vendorid,deviceid,irql); + if ((basecode == PCI_CLASS_BRIDGE_DEV) && + (subclass == PCI_SUBCLASS_BR_PCI_TO_PCI) + && (filed19val == U1DONTCARE)) + b_bridgechk = _TRUE; + + // perform a complete pci bus scan operation + for (busnum_idx = 0; busnum_idx < PCI_MAX_BRIDGE_NUMBER; busnum_idx++) //255 + { + for (devicenum_idx = 0; devicenum_idx < PCI_MAX_DEVICES; devicenum_idx++) //32 + { + b_singlefunc = _FALSE; + for (functionnum_idx = 0; functionnum_idx < PCI_MAX_FUNCTION; functionnum_idx++) //8 + { + // + // We have to skip redundant Bus scan to prevent unexpected system hang + // if single function is present in this device. + // 2009.02.26. + // + if (functionnum_idx == 0) { + //4 get header type (DWORD #3) + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (3 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &headertype); + headertype = ((headertype >> 16) & 0x0080) >> 7; // address 0x0e[7]. + if (headertype == 0) //Single function + b_singlefunc = _TRUE; + } + else + {//By pass the following scan process. + if (b_singlefunc == _TRUE) + break; + } + + // Set access enable control. + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + + //4 // Get vendorid/ deviceid + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport); + // now grab data port with device|vendor 4 byte dword + NdisRawReadPortUlong(PCI_CONF_DATA, &dev_venid); + + // if data port is full of 1s, no device is present + // some broken boards return 0 if a slot is empty: + if (dev_venid == 0xFFFFFFFF || dev_venid == 0) + continue; //PCI_INVALID_VENDORID + + // 4 // Get irql + regoffset = 0x3C; + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31) | (regoffset & 0xFFFFFFFC); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport); + NdisRawReadPortUchar((PCI_CONF_DATA +(regoffset & 0x3)), &irqline); + + venId = (u16) (dev_venid >> 0) & 0xFFFF; + devId = (u16) (dev_venid >> 16) & 0xFFFF; + + // Check Vendor ID + if (!b_bridgechk && (venId != vendorid) && (vendorid != U2DONTCARE)) + continue; + + // Check Device ID + if (!b_bridgechk && (devId != deviceid) && (deviceid != U2DONTCARE)) + continue; + + // Check irql + if (!b_bridgechk && (irqline != irql) && (irql != U1DONTCARE)) + continue; + + //4 get Class Code + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (2 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &classcode); + classcode = classcode >> 8; + + basec = (u8) (classcode >> 16) & 0xFF; + subc = (u8) (classcode >> 8) & 0xFF; + if (b_bridgechk && (venId != vendorid) && (basec == basecode) && (subc == subclass)) + return _TRUE; + + // Check Vendor ID + if (b_bridgechk && (venId != vendorid) && (vendorid != U2DONTCARE)) + continue; + + // Check Device ID + if (b_bridgechk && (devId != deviceid) && (deviceid != U2DONTCARE)) + continue; + + // Check irql + if (b_bridgechk && (irqline != irql) && (irql != U1DONTCARE)) + continue; + + //4 get field 0x19 value (DWORD #6) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (6 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &field19); + field19 = (field19 >> 8) & 0xFF; + + //4 Matching Class Code and filed19. + if ((basec == basecode) && (subc == subclass) && ((field19 == filed19val) || (filed19val == U1DONTCARE))) { + *busnum = busnum_idx; + *devnum = devicenum_idx; + *funcnum = functionnum_idx; + + DBG_871X("GetPciBusInfo(): Find Device(%X:%X) bus=%d dev=%d, func=%d\n", + vendorid, deviceid, busnum_idx, devicenum_idx, functionnum_idx); + return _TRUE; + } + } + } + } + + DBG_871X("GetPciBusInfo(): Cannot Find Device(%X:%X:%X)\n", vendorid, deviceid, dev_venid); + + return _FALSE; +} + +static u8 +rtw_get_pci_brideg_info(_adapter *padapter, + u8 basecode, + u8 subclass, + u8 filed19val, u8 * busnum, u8 * devnum, + u8 * funcnum, u16 * vendorid, u16 * deviceid) +{ + u8 busnum_idx, devicenum_idx, functionnum_idx; + u32 pcicfg_addrport = 0; + u32 dev_venid, classcode, field19, headertype; + u16 venId, devId; + u8 basec, subc, irqline; + u16 regoffset; + u8 b_singlefunc = _FALSE; + + *busnum = 0xFF; + *devnum = 0xFF; + *funcnum = 0xFF; + + // perform a complete pci bus scan operation + for (busnum_idx = 0; busnum_idx < PCI_MAX_BRIDGE_NUMBER; busnum_idx++) //255 + { + for (devicenum_idx = 0; devicenum_idx < PCI_MAX_DEVICES; devicenum_idx++) //32 + { + b_singlefunc = _FALSE; + for (functionnum_idx = 0; functionnum_idx < PCI_MAX_FUNCTION; functionnum_idx++) //8 + { + // + // We have to skip redundant Bus scan to prevent unexpected system hang + // if single function is present in this device. + // 2009.02.26. + // + if (functionnum_idx == 0) + { + //4 get header type (DWORD #3) + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + //NdisRawWritePortUlong((ULONG_PTR)PCI_CONF_ADDRESS , pcicfg_addrport + (3 << 2)); + //NdisRawReadPortUlong((ULONG_PTR)PCI_CONF_DATA, &headertype); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (3 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &headertype); + headertype = ((headertype >> 16) & 0x0080) >> 7; // address 0x0e[7]. + if (headertype == 0) //Single function + b_singlefunc = _TRUE; + } + else + {//By pass the following scan process. + if (b_singlefunc == _TRUE) + break; + } + + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + + //4 // Get vendorid/ deviceid + // set up address port at 0xCF8 offset field= 0 (dev|vend) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport); + // now grab data port with device|vendor 4 byte dword + NdisRawReadPortUlong(PCI_CONF_DATA, &dev_venid); + + //4 Get irql + regoffset = 0x3C; + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31) | (regoffset & 0xFFFFFFFC); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport); + NdisRawReadPortUchar((PCI_CONF_DATA + (regoffset & 0x3)), &irqline); + + venId = (u16) (dev_venid >> 0) & 0xFFFF; + devId = (u16) (dev_venid >> 16) & 0xFFFF; + + //4 get Class Code + pcicfg_addrport = (busnum_idx << 16) | (devicenum_idx << 11) | (functionnum_idx << 8) | (1 << 31); + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (2 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &classcode); + classcode = classcode >> 8; + + basec = (u8) (classcode >> 16) & 0xFF; + subc = (u8) (classcode >> 8) & 0xFF; + + //4 get field 0x19 value (DWORD #6) + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (6 << 2)); + NdisRawReadPortUlong(PCI_CONF_DATA, &field19); + field19 = (field19 >> 8) & 0xFF; + + //4 Matching Class Code and filed19. + if ((basec == basecode) && (subc == subclass) && ((field19 == filed19val) || (filed19val == U1DONTCARE))) { + *busnum = busnum_idx; + *devnum = devicenum_idx; + *funcnum = functionnum_idx; + *vendorid = venId; + *deviceid = devId; + + DBG_871X("GetPciBridegInfo : Find Device(%X:%X) bus=%d dev=%d, func=%d\n", + venId, devId, busnum_idx, devicenum_idx, functionnum_idx); + + return _TRUE; + } + } + } + } + + DBG_871X("GetPciBridegInfo(): Cannot Find PciBridge for Device\n"); + + return _FALSE; +} // end of GetPciBridegInfo + +// +//Description: +//To find specific bridge information. +// +static void rtw_find_bridge_info(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + u8 pcibridge_busnum = 0xff; + u8 pcibridge_devnum = 0xff; + u8 pcibridge_funcnum = 0xff; + u16 pcibridge_vendorid = 0xff; + u16 pcibridge_deviceid = 0xff; + u8 tmp = 0; + + rtw_get_pci_brideg_info(padapter, + PCI_CLASS_BRIDGE_DEV, + PCI_SUBCLASS_BR_PCI_TO_PCI, + pcipriv->busnumber, + &pcibridge_busnum, + &pcibridge_devnum, &pcibridge_funcnum, + &pcibridge_vendorid, &pcibridge_deviceid); + + // match the array of vendor id and regonize which chipset is used. + pcipriv->pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN; + + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (pcibridge_vendorid == pcibridge_vendors[tmp]) { + pcipriv->pcibridge_vendor = tmp; + DBG_871X("Pci Bridge Vendor is found index: %d\n", tmp); + break; + } + } + DBG_871X("Pci Bridge Vendor is %x\n", pcibridge_vendors[tmp]); + + // Update corresponding PCI bus info. + pcipriv->pcibridge_busnum = pcibridge_busnum; + pcipriv->pcibridge_devnum = pcibridge_devnum; + pcipriv->pcibridge_funcnum = pcibridge_funcnum; + pcipriv->pcibridge_vendorid = pcibridge_vendorid; + pcipriv->pcibridge_deviceid = pcibridge_deviceid; + +} + +static u8 +rtw_get_amd_l1_patch(_adapter *padapter, u8 busnum, u8 devnum, + u8 funcnum) +{ + u8 status = _FALSE; + u8 offset_e0; + unsigned offset_e4; + u32 pcicfg_addrport = 0; + + pcicfg_addrport = (busnum << 16) | (devnum << 11) | (funcnum << 8) | (1 << 31); + + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + 0xE0); + NdisRawWritePortUchar(PCI_CONF_DATA, 0xA0); + + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + 0xE0); + NdisRawReadPortUchar(PCI_CONF_DATA, &offset_e0); + + if (offset_e0 == 0xA0) + { + NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + 0xE4); + NdisRawReadPortUlong(PCI_CONF_DATA, &offset_e4); + //DbgPrint("Offset E4 %x\n", offset_e4); + if (offset_e4 & BIT(23)) + status = _TRUE; + } + + return status; +} +#else +/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ +void rtw_pci_disable_aspm(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pci_dev *pdev = pdvobjpriv->ppcidev; + struct pci_dev *bridge_pdev = pdev->bus->self; + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + u8 linkctrl_reg; + u16 pcibridge_linkctrlreg; + u16 aspmlevel = 0; + + // We do not diable/enable ASPM by driver, in the future, the BIOS will enable host and NIC ASPM. + // Advertised by SD1 victorh. Added by tynli. 2009.11.23. + if(pdvobjpriv->const_pci_aspm == 0) + return; + + if(!padapter->hw_init_completed) + return; + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s(): PCI(Bridge) UNKNOWN.\n", __FUNCTION__)); + return; + } + + linkctrl_reg = pcipriv->linkctrl_reg; + pcibridge_linkctrlreg = pcipriv->pcibridge_linkctrlreg; + + // Set corresponding value. + aspmlevel |= BIT(0) | BIT(1); + linkctrl_reg &=~aspmlevel; + pcibridge_linkctrlreg &=~aspmlevel; + + if (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + RT_CLEAR_PS_LEVEL(pwrpriv, RT_RF_OFF_LEVL_CLK_REQ); + rtw_pci_switch_clk_req(padapter, 0x0); + } + + { + /*for promising device will in L0 state after an I/O.*/ + u8 tmp_u1b; + pci_read_config_byte(pdev, 0x80, &tmp_u1b); + } + + rtw_pci_platform_switch_device_pci_aspm(padapter, linkctrl_reg); + rtw_udelay_os(50); + + //When there exists anyone's BusNum, DevNum, and FuncNum that are set to 0xff, + // we do not execute any action and return. Added by tynli. + if( (pcipriv->busnumber == 0xff && pcipriv->devnumber == 0xff && pcipriv->funcnumber == 0xff) || + (pcipriv->pcibridge_busnum == 0xff && pcipriv->pcibridge_devnum == 0xff && pcipriv->pcibridge_funcnum == 0xff) ) + { + // Do Nothing!! + } + else + { + /*Disable Pci Bridge ASPM*/ + //NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + (num4bytes << 2)); + //NdisRawWritePortUchar(PCI_CONF_DATA, pcibridge_linkctrlreg); + pci_write_config_byte(bridge_pdev, pcipriv->pcibridge_pciehdr_offset + 0x10, pcibridge_linkctrlreg); + + DBG_871X("rtw_pci_disable_aspm():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcipriv->pcibridge_busnum, pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum, + (pcipriv->pcibridge_pciehdr_offset+0x10), pcibridge_linkctrlreg); + + rtw_udelay_os(50); + } + +} + +/*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for +power saving We should follow the sequence to enable +RTL8192SE first then enable Pci Bridge ASPM +or the system will show bluescreen.*/ +void rtw_pci_enable_aspm(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct pci_dev *pdev = pdvobjpriv->ppcidev; + struct pci_dev *bridge_pdev = pdev->bus->self; + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + u16 aspmlevel = 0; + u8 u_pcibridge_aspmsetting = 0; + u8 u_device_aspmsetting = 0; + u32 u_device_aspmsupportsetting = 0; + + // We do not diable/enable ASPM by driver, in the future, the BIOS will enable host and NIC ASPM. + // Advertised by SD1 victorh. Added by tynli. 2009.11.23. + if(pdvobjpriv->const_pci_aspm == 0) + return; + + //When there exists anyone's BusNum, DevNum, and FuncNum that are set to 0xff, + // we do not execute any action and return. Added by tynli. + if( (pcipriv->busnumber == 0xff && pcipriv->devnumber == 0xff && pcipriv->funcnumber == 0xff) || + (pcipriv->pcibridge_busnum == 0xff && pcipriv->pcibridge_devnum == 0xff && pcipriv->pcibridge_funcnum == 0xff) ) + { + DBG_871X("rtw_pci_enable_aspm(): Fail to enable ASPM. Cannot find the Bus of PCI(Bridge).\n"); + return; + } + +//Get Bridge ASPM Support +//not to enable bridge aspm if bridge does not support +//Added by sherry 20100803 + if (IS_HARDWARE_TYPE_8192DE(padapter)) + { + //PciCfgAddrPort = (pcipriv->pcibridge_busnum << 16)|(pcipriv->pcibridge_devnum<< 11)|(pcipriv->pcibridge_funcnum << 8)|(1 << 31); + //Num4Bytes = (pcipriv->pcibridge_pciehdr_offset+0x0C)/4; + //NdisRawWritePortUlong((ULONG_PTR)PCI_CONF_ADDRESS , PciCfgAddrPort+(Num4Bytes << 2)); + //NdisRawReadPortUlong((ULONG_PTR)PCI_CONF_DATA,&uDeviceASPMSupportSetting); + pci_read_config_dword(bridge_pdev, (pcipriv->pcibridge_pciehdr_offset+0x0C), &u_device_aspmsupportsetting); + DBG_871X("rtw_pci_enable_aspm(): Bridge ASPM support %x \n",u_device_aspmsupportsetting); + if(((u_device_aspmsupportsetting & BIT(11)) != BIT(11)) || ((u_device_aspmsupportsetting & BIT(10)) != BIT(10))) + { + if(pdvobjpriv->const_devicepci_aspm_setting == 3) + { + DBG_871X("rtw_pci_enable_aspm(): Bridge not support L0S or L1\n"); + return; + } + else if(pdvobjpriv->const_devicepci_aspm_setting == 2) + { + if((u_device_aspmsupportsetting & BIT(11)) != BIT(11)) + { + DBG_871X("rtw_pci_enable_aspm(): Bridge not support L1 \n"); + return; + } + } + else if(pdvobjpriv->const_devicepci_aspm_setting == 1) + { + if((u_device_aspmsupportsetting & BIT(10)) != BIT(10)) + { + DBG_871X("rtw_pci_enable_aspm(): Bridge not support L0s \n"); + return; + } + + } + } + else + { + DBG_871X("rtw_pci_enable_aspm(): Bridge support L0s and L1 \n"); + } + } + + + /*Enable Pci Bridge ASPM*/ + //PciCfgAddrPort = (pcipriv->pcibridge_busnum << 16)|(pcipriv->pcibridge_devnum<< 11) |(pcipriv->pcibridge_funcnum << 8)|(1 << 31); + //Num4Bytes = (pcipriv->pcibridge_pciehdr_offset+0x10)/4; + // set up address port at 0xCF8 offset field= 0 (dev|vend) + //NdisRawWritePortUlong(PCI_CONF_ADDRESS, PciCfgAddrPort + (Num4Bytes << 2)); + // now grab data port with device|vendor 4 byte dword + + u_pcibridge_aspmsetting = pcipriv->pcibridge_linkctrlreg; + u_pcibridge_aspmsetting |= pdvobjpriv->const_hostpci_aspm_setting; + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL || + pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_SIS ) + u_pcibridge_aspmsetting &= ~BIT(0); // for intel host 42 device 43 + + //NdisRawWritePortUchar(PCI_CONF_DATA, u_pcibridge_aspmsetting); + pci_write_config_byte(bridge_pdev, (pcipriv->pcibridge_pciehdr_offset+0x10), u_pcibridge_aspmsetting); + + DBG_871X("PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcipriv->pcibridge_busnum, pcipriv->pcibridge_devnum, pcipriv->pcibridge_funcnum, + (pcipriv->pcibridge_pciehdr_offset+0x10), + u_pcibridge_aspmsetting); + + rtw_udelay_os(50); + + /*Get ASPM level (with/without Clock Req)*/ + aspmlevel |= pdvobjpriv->const_devicepci_aspm_setting; + u_device_aspmsetting = pcipriv->linkctrl_reg; + u_device_aspmsetting |= aspmlevel; // device 43 + + rtw_pci_platform_switch_device_pci_aspm(padapter, u_device_aspmsetting); + + if (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { + rtw_pci_switch_clk_req(padapter, (pwrpriv->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_SET_PS_LEVEL(pwrpriv, RT_RF_OFF_LEVL_CLK_REQ); + } + + rtw_udelay_os(50); +} + +static u8 rtw_pci_get_amd_l1_patch(struct dvobj_priv *dvobj) +{ + struct pci_dev *pdev = dvobj->ppcidev; + struct pci_dev *bridge_pdev = pdev->bus->self; + u8 status = _FALSE; + u8 offset_e0; + u32 offset_e4; + + //NdisRawWritePortUlong(PCI_CONF_ADDRESS,pcicfg_addrport + 0xE0); + //NdisRawWritePortUchar(PCI_CONF_DATA, 0xA0); + pci_write_config_byte(bridge_pdev, 0xE0, 0xA0); + + //NdisRawWritePortUlong(PCI_CONF_ADDRESS,pcicfg_addrport + 0xE0); + //NdisRawReadPortUchar(PCI_CONF_DATA, &offset_e0); + pci_read_config_byte(bridge_pdev, 0xE0, &offset_e0); + + if (offset_e0 == 0xA0) { + //NdisRawWritePortUlong(PCI_CONF_ADDRESS, pcicfg_addrport + 0xE4); + //NdisRawReadPortUlong(PCI_CONF_DATA, &offset_e4); + pci_read_config_dword(bridge_pdev, 0xE4, &offset_e4); + if (offset_e4 & BIT(23)) + status = _TRUE; + } + + return status; +} + +static void rtw_pci_get_linkcontrol_field(struct dvobj_priv *dvobj) +{ + struct pci_priv *pcipriv = &(dvobj->pcipriv); + struct pci_dev *pdev = dvobj->ppcidev; + struct pci_dev *bridge_pdev = pdev->bus->self; + u8 capabilityoffset = pcipriv->pcibridge_pciehdr_offset; + u8 linkctrl_reg; + + /*Read Link Control Register*/ + pci_read_config_byte(bridge_pdev, capabilityoffset + PCI_EXP_LNKCTL, &linkctrl_reg); + + pcipriv->pcibridge_linkctrlreg = linkctrl_reg; +} +#endif + +static void rtw_pci_parse_configuration(struct dvobj_priv *dvobj) +{ + struct pci_dev *pdev = dvobj->ppcidev; + struct pci_priv *pcipriv = &(dvobj->pcipriv); + u8 tmp; + int pos; + u8 linkctrl_reg; + + //Link Control Register + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); + pcipriv->linkctrl_reg = linkctrl_reg; + + //DBG_871X("Link Control Register = %x\n", pcipriv->linkctrl_reg); + + pci_read_config_byte(pdev, 0x98, &tmp); + tmp |= BIT(4); + pci_write_config_byte(pdev, 0x98, tmp); + + //tmp = 0x17; + //pci_write_config_byte(pdev, 0x70f, tmp); +} + +// +// Update PCI dependent default settings. +// +static void rtw_pci_update_default_setting(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct pci_priv *pcipriv = &(pdvobjpriv->pcipriv); + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + + //reset pPSC->reg_rfps_level & priv->b_support_aspm + pwrpriv->reg_rfps_level = 0; + pwrpriv->b_support_aspm = 0; + + // Dynamic Mechanism, + //rtw_hal_set_def_var(pAdapter, HAL_DEF_INIT_GAIN, &(pDevice->InitGainState)); + + // Update PCI ASPM setting + pwrpriv->const_amdpci_aspm = pdvobjpriv->const_amdpci_aspm; + switch (pdvobjpriv->const_pci_aspm) { + case 0: // No ASPM + break; + + case 1: // ASPM dynamically enabled/disable. + pwrpriv->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM; + break; + + case 2: // ASPM with Clock Req dynamically enabled/disable. + pwrpriv->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM | RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 3: // Always enable ASPM and Clock Req from initialization to halt. + pwrpriv->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM); + pwrpriv->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM | RT_RF_OFF_LEVL_CLK_REQ); + break; + + case 4: // Always enable ASPM without Clock Req from initialization to halt. + pwrpriv->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM | RT_RF_OFF_LEVL_CLK_REQ); + pwrpriv->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM; + break; + } + + pwrpriv->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + + // Update Radio OFF setting + switch (pdvobjpriv->const_hwsw_rfoff_d3) { + case 1: + if (pwrpriv->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + pwrpriv->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + break; + + case 2: + if (pwrpriv->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM) + pwrpriv->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM; + pwrpriv->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC; + break; + + case 3: + pwrpriv->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3; + break; + } + + // Update Rx 2R setting + //pPSC->reg_rfps_level |= ((pDevice->RegLPS2RDisable) ? RT_RF_LPS_DISALBE_2R : 0); + + // + // Set HW definition to determine if it supports ASPM. + // + switch (pdvobjpriv->const_support_pciaspm) { + case 0: // Not support ASPM. + { + u8 b_support_aspm = _FALSE; + pwrpriv->b_support_aspm = b_support_aspm; + } + break; + + case 1: // Support ASPM. + { + u8 b_support_aspm = _TRUE; + u8 b_support_backdoor = _TRUE; + + pwrpriv->b_support_aspm = b_support_aspm; + + /*if(pAdapter->MgntInfo.CustomerID == RT_CID_TOSHIBA && + pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD && + !pcipriv->amd_l1_patch) + b_support_backdoor = _FALSE;*/ + + pwrpriv->b_support_backdoor = b_support_backdoor; + } + break; + + case 2: // Set by Chipset. + // ASPM value set by chipset. + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { + u8 b_support_aspm = _TRUE; + pwrpriv->b_support_aspm = b_support_aspm; + } + break; + + default: + // Do nothing. Set when finding the chipset. + break; + } +} + +static void rtw_pci_initialize_adapter_common(_adapter *padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + + rtw_pci_update_default_setting(padapter); + + if (pwrpriv->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) { + // Always enable ASPM & Clock Req. + rtw_pci_enable_aspm(padapter); + RT_SET_PS_LEVEL(pwrpriv, RT_RF_PS_LEVEL_ALWAYS_ASPM); + } + +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) +#define rtw_pci_interrupt(x,y,z) rtw_pci_interrupt(x,y) +#endif + +static irqreturn_t rtw_pci_interrupt(int irq, void *priv, struct pt_regs *regs) +{ + struct dvobj_priv *dvobj = (struct dvobj_priv *)priv; + _adapter *adapter = dvobj->if1; + + if (dvobj->irq_enabled == 0) { + return IRQ_HANDLED; + } + + if(rtw_hal_interrupt_handler(adapter) == _FAIL) + return IRQ_HANDLED; + //return IRQ_NONE; + + return IRQ_HANDLED; +} + +#ifdef RTK_DMP_PLATFORM +#define pci_iounmap(x,y) iounmap(y) +#endif + +int pci_alloc_irq(struct dvobj_priv *dvobj) +{ + int err; + struct pci_dev *pdev = dvobj->ppcidev; + +#if defined(IRQF_SHARED) + err = request_irq(pdev->irq, &rtw_pci_interrupt, IRQF_SHARED, DRV_NAME, dvobj); +#else + err = request_irq(pdev->irq, &rtw_pci_interrupt, SA_SHIRQ, DRV_NAME, dvobj); +#endif + if (err) { + DBG_871X("Error allocating IRQ %d",pdev->irq); + } else { + dvobj->irq_alloc = 1; + DBG_871X("Request_irq OK, IRQ %d\n",pdev->irq); + } + + return err?_FAIL:_SUCCESS; +} + +static struct dvobj_priv *pci_dvobj_init(struct pci_dev *pdev) +{ + int err; + u32 status = _FAIL; + struct dvobj_priv *dvobj = NULL; + struct pci_priv *pcipriv = NULL; + struct pci_dev *bridge_pdev = pdev->bus->self; + unsigned long pmem_start, pmem_len, pmem_flags; + u8 tmp; + +_func_enter_; + + if ((dvobj = devobj_init()) == NULL) { + goto exit; + } + dvobj->ppcidev = pdev; + pcipriv = &(dvobj->pcipriv); + pci_set_drvdata(pdev, dvobj); + + if ( (err = pci_enable_device(pdev)) != 0) { + DBG_871X(KERN_ERR "%s : Cannot enable new PCI device\n", pci_name(pdev)); + goto free_dvobj; + } + +#ifdef CONFIG_64BIT_DMA + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + DBG_871X("RTL819xCE: Using 64bit DMA\n"); + if ((err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) != 0) { + DBG_871X(KERN_ERR "Unable to obtain 64bit DMA for consistent allocations\n"); + goto disable_picdev; + } + dvobj->bdma64 = _TRUE; + } else +#endif + { + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + if ((err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { + DBG_871X(KERN_ERR "Unable to obtain 32bit DMA for consistent allocations\n"); + goto disable_picdev; + } + } + } + + pci_set_master(pdev); + + if ((err = pci_request_regions(pdev, DRV_NAME)) != 0) { + DBG_871X(KERN_ERR "Can't obtain PCI resources\n"); + goto disable_picdev; + } + //MEM map + pmem_start = pci_resource_start(pdev, 2); + pmem_len = pci_resource_len(pdev, 2); + pmem_flags = pci_resource_flags(pdev, 2); + +#ifdef RTK_DMP_PLATFORM + dvobj->pci_mem_start = (unsigned long)ioremap_nocache(pmem_start, pmem_len); +#else + dvobj->pci_mem_start = (unsigned long)pci_iomap(pdev, 2, pmem_len); /* shared mem start */ +#endif + if (dvobj->pci_mem_start == 0) { + DBG_871X(KERN_ERR "Can't map PCI mem\n"); + goto release_regions; + } + + DBG_871X("Memory mapped space start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, dvobj->pci_mem_start); + + // Disable Clk Request */ + pci_write_config_byte(pdev, 0x81, 0); + // leave D3 mode */ + pci_write_config_byte(pdev, 0x44, 0); + pci_write_config_byte(pdev, 0x04, 0x06); + pci_write_config_byte(pdev, 0x04, 0x07); + + +#if 1 + /*find bus info*/ + pcipriv->busnumber = pdev->bus->number; + pcipriv->devnumber = PCI_SLOT(pdev->devfn); + pcipriv->funcnumber = PCI_FUNC(pdev->devfn); + + /*find bridge info*/ + pcipriv->pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN; + if(bridge_pdev){ + pcipriv->pcibridge_vendorid = bridge_pdev->vendor; + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { + pcipriv->pcibridge_vendor = tmp; + DBG_871X("Pci Bridge Vendor is found index: %d, %x\n", tmp, pcibridge_vendors[tmp]); + break; + } + } + } + + //if (pcipriv->pcibridge_vendor != PCI_BRIDGE_VENDOR_UNKNOWN) { + if(bridge_pdev){ + pcipriv->pcibridge_busnum = bridge_pdev->bus->number; + pcipriv->pcibridge_devnum = PCI_SLOT(bridge_pdev->devfn); + pcipriv->pcibridge_funcnum = PCI_FUNC(bridge_pdev->devfn); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) + pcipriv->pcibridge_pciehdr_offset = pci_find_capability(bridge_pdev, PCI_CAP_ID_EXP); +#else + pcipriv->pcibridge_pciehdr_offset = bridge_pdev->pcie_cap; +#endif + + rtw_pci_get_linkcontrol_field(dvobj); + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD) { + pcipriv->amd_l1_patch = rtw_pci_get_amd_l1_patch(dvobj); + } + } +#else + // + // Find bridge related info. + // + rtw_get_pci_bus_info(padapter, + pdev->vendor, + pdev->device, + (u8) pdvobjpriv->irqline, + 0x02, 0x80, U1DONTCARE, + &pcipriv->busnumber, + &pcipriv->devnumber, + &pcipriv->funcnumber); + + rtw_find_bridge_info(padapter); + + if (pcipriv->pcibridge_vendor != PCI_BRIDGE_VENDOR_UNKNOWN) { + rtw_get_link_control_field(padapter, + pcipriv->pcibridge_busnum, + pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum); + + if (pcipriv->pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD) { + pcipriv->amd_l1_patch = + rtw_get_amd_l1_patch(padapter, + pcipriv->pcibridge_busnum, + pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum); + } + } +#endif + + // + // Allow the hardware to look at PCI config information. + // + rtw_pci_parse_configuration(dvobj); + + DBG_871X("pcidev busnumber:devnumber:funcnumber:" + "vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->busnumber, + pcipriv->devnumber, + pcipriv->funcnumber, + pdev->vendor, + pcipriv->linkctrl_reg); + + DBG_871X("pci_bridge busnumber:devnumber:funcnumber:vendor:" + "pcie_cap:link_ctl_reg: %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->pcibridge_busnum, + pcipriv->pcibridge_devnum, + pcipriv->pcibridge_funcnum, + pcibridge_vendors[pcipriv->pcibridge_vendor], + pcipriv->pcibridge_pciehdr_offset, + pcipriv->pcibridge_linkctrlreg, + pcipriv->amd_l1_patch); + + status = _SUCCESS; + +iounmap: + if (status != _SUCCESS && dvobj->pci_mem_start != 0) { + pci_iounmap(pdev, (void *)dvobj->pci_mem_start); + dvobj->pci_mem_start = 0; + } +release_regions: + if (status != _SUCCESS) + pci_release_regions(pdev); +disable_picdev: + if (status != _SUCCESS) + pci_disable_device(pdev); +free_dvobj: + if (status != _SUCCESS && dvobj) { + pci_set_drvdata(pdev, NULL); + devobj_deinit(dvobj); + dvobj = NULL; + } +exit: +_func_exit_; + return dvobj; +} + +static void pci_dvobj_deinit(struct pci_dev *pdev) +{ + struct dvobj_priv *dvobj = pci_get_drvdata(pdev); +_func_enter_; + + pci_set_drvdata(pdev, NULL); + if (dvobj) { + if (dvobj->irq_alloc) { + free_irq(pdev->irq, dvobj); + dvobj->irq_alloc = 0; + } + + if (dvobj->pci_mem_start != 0) { + pci_iounmap(pdev, (void *)dvobj->pci_mem_start); + dvobj->pci_mem_start = 0; + } + + devobj_deinit(dvobj); + } + + pci_release_regions(pdev); + pci_disable_device(pdev); + +_func_exit_; +} + +static void decide_chip_type_by_pci_device_id(_adapter *padapter, struct pci_dev *pdev) +{ + u16 venderid, deviceid, irqline; + u8 revisionid; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + + + venderid = pdev->vendor; + deviceid = pdev->device; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + pci_read_config_byte(pdev, PCI_REVISION_ID, &revisionid); // PCI_REVISION_ID 0x08 +#else + revisionid = pdev->revision; +#endif + pci_read_config_word(pdev, PCI_INTERRUPT_LINE, &irqline); // PCI_INTERRUPT_LINE 0x3c + pdvobjpriv->irqline = irqline; + + + // + // Decide hardware type here. + // + if( deviceid == HAL_HW_PCI_8185_DEVICE_ID || + deviceid == HAL_HW_PCI_8188_DEVICE_ID || + deviceid == HAL_HW_PCI_8198_DEVICE_ID) + { + DBG_871X("Adapter (8185/8185B) is found- VendorID/DeviceID=%x/%x\n", venderid, deviceid); + padapter->HardwareType=HARDWARE_TYPE_RTL8185; + } + else if (deviceid == HAL_HW_PCI_8190_DEVICE_ID || + deviceid == HAL_HW_PCI_0045_DEVICE_ID || + deviceid == HAL_HW_PCI_0046_DEVICE_ID || + deviceid == HAL_HW_PCI_DLINK_DEVICE_ID) + { + DBG_871X("Adapter(8190 PCI) is found - vendorid/deviceid=%x/%x\n", venderid, deviceid); + padapter->HardwareType = HARDWARE_TYPE_RTL8190P; + } + else if (deviceid == HAL_HW_PCI_8192_DEVICE_ID || + deviceid == HAL_HW_PCI_0044_DEVICE_ID || + deviceid == HAL_HW_PCI_0047_DEVICE_ID || + deviceid == HAL_HW_PCI_8192SE_DEVICE_ID || + deviceid == HAL_HW_PCI_8174_DEVICE_ID || + deviceid == HAL_HW_PCI_8173_DEVICE_ID || + deviceid == HAL_HW_PCI_8172_DEVICE_ID || + deviceid == HAL_HW_PCI_8171_DEVICE_ID) + { + // 8192e and and 8192se may have the same device ID 8192. However, their Revision + // ID is different + // Added for 92DE. We deferentiate it from SVID,SDID. + if( pdev->subsystem_vendor == 0x10EC && pdev->subsystem_device == 0xE020){ + padapter->HardwareType = HARDWARE_TYPE_RTL8192DE; + DBG_871X("Adapter(8192DE) is found - VendorID/DeviceID/RID=%X/%X/%X\n", venderid, deviceid, revisionid); + }else{ + switch (revisionid) { + case HAL_HW_PCI_REVISION_ID_8192PCIE: + DBG_871X("Adapter(8192 PCI-E) is found - vendorid/deviceid=%x/%x\n", venderid, deviceid); + padapter->HardwareType = HARDWARE_TYPE_RTL8192E; + break; + case HAL_HW_PCI_REVISION_ID_8192SE: + DBG_871X("Adapter(8192SE) is found - vendorid/deviceid=%x/%x\n", venderid, deviceid); + padapter->HardwareType = HARDWARE_TYPE_RTL8192SE; + break; + default: + DBG_871X("Err: Unknown device - vendorid/deviceid=%x/%x\n", venderid, deviceid); + padapter->HardwareType = HARDWARE_TYPE_RTL8192SE; + break; + } + } + } + else if(deviceid==HAL_HW_PCI_8723E_DEVICE_ID ) + {//RTL8723E may have the same device ID with RTL8192CET + padapter->HardwareType = HARDWARE_TYPE_RTL8723AE; + DBG_871X("Adapter(8723 PCI-E) is found - VendorID/DeviceID=%x/%x\n", venderid, deviceid); + } + else if (deviceid == HAL_HW_PCI_8192CET_DEVICE_ID || + deviceid == HAL_HW_PCI_8192CE_DEVICE_ID || + deviceid == HAL_HW_PCI_8191CE_DEVICE_ID || + deviceid == HAL_HW_PCI_8188CE_DEVICE_ID) + { + DBG_871X("Adapter(8192C PCI-E) is found - vendorid/deviceid=%x/%x\n", venderid, deviceid); + padapter->HardwareType = HARDWARE_TYPE_RTL8192CE; + } + else if (deviceid == HAL_HW_PCI_8192DE_DEVICE_ID || + deviceid == HAL_HW_PCI_002B_DEVICE_ID ){ + padapter->HardwareType = HARDWARE_TYPE_RTL8192DE; + DBG_871X("Adapter(8192DE) is found - VendorID/DeviceID/RID=%X/%X/%X\n", venderid, deviceid, revisionid); + } + else + { + DBG_871X("Err: Unknown device - vendorid/deviceid=%x/%x\n", venderid, deviceid); + //padapter->HardwareType = HAL_DEFAULT_HARDWARE_TYPE; + } + + + padapter->chip_type = NULL_CHIP_TYPE; + + //TODO: +#ifdef CONFIG_RTL8192C + padapter->chip_type = RTL8188C_8192C; + padapter->HardwareType = HARDWARE_TYPE_RTL8192CE; +#endif +#ifdef CONFIG_RTL8192D + pdvobjpriv->InterfaceNumber = revisionid; + + padapter->chip_type = RTL8192D; + padapter->HardwareType = HARDWARE_TYPE_RTL8192DE; +#endif + +} + +static void pci_intf_start(_adapter *padapter) +{ + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+pci_intf_start\n")); + DBG_871X("+pci_intf_start\n"); + +#ifdef CONFIG_PCILED_BLINK + rtw_led_control(padapter, LED_CTL_NO_LINK); +#endif + //Enable hw interrupt + rtw_hal_enable_interrupt(padapter); + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-pci_intf_start\n")); + DBG_871X("-pci_intf_start\n"); +} + +static void pci_intf_stop(_adapter *padapter) +{ + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+pci_intf_stop\n")); + + //Disable hw interrupt + if(padapter->bSurpriseRemoved == _FALSE) + { + //device still exists, so driver can do i/o operation + rtw_hal_disable_interrupt(padapter); + tasklet_disable(&(padapter->recvpriv.recv_tasklet)); + tasklet_disable(&(padapter->recvpriv.irq_prepare_beacon_tasklet)); + tasklet_disable(&(padapter->xmitpriv.xmit_tasklet)); + +#ifdef CONFIG_CONCURRENT_MODE + /* This function only be called at driver removing. disable buddy_adapter too + don't disable interrupt of buddy_adapter because it is same as primary. + */ + if (padapter->pbuddy_adapter){ + tasklet_disable(&(padapter->pbuddy_adapter->recvpriv.recv_tasklet)); + tasklet_disable(&(padapter->pbuddy_adapter->recvpriv.irq_prepare_beacon_tasklet)); + tasklet_disable(&(padapter->pbuddy_adapter->xmitpriv.xmit_tasklet)); + } +#endif + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("pci_intf_stop: SurpriseRemoved==_FALSE\n")); + } + else + { + // Clear irq_enabled to prevent handle interrupt function. + adapter_to_dvobj(padapter)->irq_enabled = 0; + } + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-pci_intf_stop\n")); + +} + + +static void rtw_dev_unload(_adapter *padapter) +{ + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_dev_unload\n")); + + if(padapter->bup == _TRUE) + { + DBG_871X("+rtw_dev_unload\n"); + + padapter->bDriverStopped = _TRUE; + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + //s3. + if(padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + //s4. + rtw_stop_drv_threads(padapter); + + + //s5. + if(padapter->bSurpriseRemoved == _FALSE) + { + DBG_871X("r871x_dev_unload()->rtl871x_hal_deinit()\n"); + rtw_hal_deinit(padapter); + + padapter->bSurpriseRemoved = _TRUE; + } + + padapter->bup = _FALSE; + + } + else + { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("r871x_dev_unload():padapter->bup == _FALSE\n" )); + } + + DBG_871X("-rtw_dev_unload\n"); + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-rtw_dev_unload\n")); + +} + +static void disable_ht_for_spec_devid(const struct pci_device_id *pdid) +{ +#ifdef CONFIG_80211N_HT + u16 vid, pid; + u32 flags; + int i; + int num = sizeof(specific_device_id_tbl)/sizeof(struct specific_device_id); + + for(i=0; ivendor==vid) && (pdid->device==pid) && (flags&SPEC_DEV_ID_DISABLE_HT)) + { + rtw_ht_enable = 0; + rtw_cbw40_enable = 0; + rtw_ampdu_enable = 0; + } + + } +#endif +} + +#ifdef CONFIG_PM +static int rtw_suspend(struct pci_dev *pdev, pm_message_t state) +{ + _func_enter_; + + + _func_exit_; + return 0; +} + +static int rtw_resume(struct pci_dev *pdev) +{ + _func_enter_; + + + _func_exit_; + + return 0; +} +#endif + +_adapter *rtw_pci_if1_init(struct dvobj_priv * dvobj, struct pci_dev *pdev, + const struct pci_device_id *pdid) +{ + _adapter *padapter = NULL; + struct net_device *pnetdev = NULL; + int status = _FAIL; + + if ((padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter))) == NULL) { + goto exit; + } + padapter->dvobj = dvobj; + dvobj->if1 = padapter; + + padapter->bDriverStopped=_TRUE; + + dvobj->padapters[dvobj->iface_nums++] = padapter; + padapter->iface_id = IFACE_ID0; + +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_DUALMAC_CONCURRENT) + //set adapter_type/iface type for primary padapter + padapter->isprimary = _TRUE; + padapter->adapter_type = PRIMARY_ADAPTER; + #ifndef CONFIG_HWPORT_SWAP + padapter->iface_type = IFACE_PORT0; + #else + padapter->iface_type = IFACE_PORT1; + #endif +#endif + + //step 1-1., decide the chip_type via vid/pid + padapter->interface_type = RTW_PCIE; + decide_chip_type_by_pci_device_id(padapter, pdev); + + if((pnetdev = rtw_init_netdev(padapter)) == NULL) { + goto free_adapter; + } + if (dvobj->bdma64) + pnetdev->features |= NETIF_F_HIGHDMA; + pnetdev->irq = pdev->irq; + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); + padapter = rtw_netdev_priv(pnetdev); + + //step 2. hook HalFunc, allocate HalData + if (padapter->chip_type == RTL8188C_8192C) { + #ifdef CONFIG_RTL8192C + rtl8192ce_set_hal_ops(padapter); + #endif + } else if (padapter->chip_type == RTL8192D) { + #ifdef CONFIG_RTL8192D + rtl8192de_set_hal_ops(padapter); + #endif + } else { + DBG_871X("Detect NULL_CHIP_TYPE\n"); + goto free_hal_data; + } + + //step 3. initialize the dvobj_priv + padapter->intf_start=&pci_intf_start; + padapter->intf_stop=&pci_intf_stop; + + + //.2 + if ((rtw_init_io_priv(padapter, pci_set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n")); + goto free_hal_data; + } + + //.3 + rtw_hal_read_chip_version(padapter); + + //.4 + rtw_hal_chip_configure(padapter); + + //step 4. read efuse/eeprom data and get mac_addr + rtw_hal_read_chip_info(padapter); + + if (rtw_handle_dualmac(padapter, 1) != _SUCCESS) + goto free_hal_data; + +#ifdef CONFIG_IOCTL_CFG80211 + if(rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)) != 0) { + goto handle_dualmac; + } +#endif + + //step 5. + if (rtw_init_drv_sw(padapter) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("Initialize driver software resource Failed!\n")); + goto free_wdev; + } + + status = rtw_hal_inirp_init(padapter); + if(status ==_FAIL){ + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("Initialize PCI desc ring Failed!\n")); + goto free_drv_sw; + } + + rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); + rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr); + + + rtw_hal_disable_interrupt(padapter); + + //step 6. Init pci related configuration + rtw_pci_initialize_adapter_common(padapter); + + DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" + ,padapter->bDriverStopped + ,padapter->bSurpriseRemoved + ,padapter->bup + ,padapter->hw_init_completed + ); + + status = _SUCCESS; + +inirp_deinit: + if (status != _SUCCESS) + rtw_hal_inirp_deinit(padapter); +free_drv_sw: + if (status != _SUCCESS) + rtw_free_drv_sw(padapter); +free_wdev: + if (status != _SUCCESS) { + #ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_unregister(padapter->rtw_wdev); + rtw_wdev_free(padapter->rtw_wdev); + #endif + } +handle_dualmac: + if (status != _SUCCESS) + rtw_handle_dualmac(padapter, 0); +free_hal_data: + if (status != _SUCCESS && padapter->HalData) + rtw_mfree(padapter->HalData, sizeof(*(padapter->HalData))); +free_adapter: + if (status != _SUCCESS) { + if (pnetdev) + rtw_free_netdev(pnetdev); + else if (padapter) + rtw_vmfree((u8*)padapter, sizeof(*padapter)); + padapter = NULL; + } +exit: + return padapter; +} + +static void rtw_pci_if1_deinit(_adapter *if1) +{ + struct net_device *pnetdev = if1->pnetdev; + struct mlme_priv *pmlmepriv= &if1->mlmepriv; + + // padapter->intf_stop(padapter); + + if(check_fwstate(pmlmepriv, _FW_LINKED)) + rtw_disassoc_cmd(if1, 0, _FALSE); + +#ifdef CONFIG_AP_MODE + free_mlme_ap_info(if1); + #ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_unload(if1); + #endif +#endif + + rtw_cancel_all_timer(if1); +#ifdef CONFIG_WOWLAN + if1->pwrctrlpriv.wowlan_mode=_FALSE; +#endif //CONFIG_WOWLAN + rtw_dev_unload(if1); + + DBG_871X("%s, hw_init_completed=%d\n", __func__, if1->hw_init_completed); + + //s6. + rtw_handle_dualmac(if1, 0); + +#ifdef CONFIG_IOCTL_CFG80211 + if (if1->rtw_wdev) + rtw_wdev_free(if1->rtw_wdev); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_hal_inirp_deinit(if1); + rtw_free_drv_sw(if1); + + if(pnetdev) + rtw_free_netdev(pnetdev); + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link down\n"); + rtd2885_wlan_netlink_sendMsg("linkdown", "8712"); +#endif +} + +/* + * drv_init() - a device potentially for us + * + * notes: drv_init() is called when the bus driver has located a card for us to support. + * We accept the new device by returning 0. +*/ +static int rtw_drv_init(struct pci_dev *pdev, const struct pci_device_id *did) +{ + int i, err = -ENODEV; + + int status; + _adapter *if1 = NULL, *if2 = NULL; + struct dvobj_priv *dvobj; + + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n")); + + //step 0. + disable_ht_for_spec_devid(did); + + /* Initialize dvobj_priv */ + if ((dvobj = pci_dvobj_init(pdev)) == NULL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n")); + goto exit; + } + + /* Initialize if1 */ + if ((if1 = rtw_pci_if1_init(dvobj, pdev, did)) == NULL) { + DBG_871X("rtw_pci_if1_init Failed!\n"); + goto free_dvobj; + } + + /* Initialize if2 */ +#ifdef CONFIG_CONCURRENT_MODE + if((if2 = rtw_drv_if2_init(if1, pci_set_intf_ops)) == NULL) { + goto free_if1; + } +#endif + +#ifdef CONFIG_GLOBAL_UI_PID + if (ui_pid[1]!=0) { + DBG_871X("ui_pid[1]:%d\n",ui_pid[1]); + rtw_signal_process(ui_pid[1], SIGUSR2); + } +#endif + + //dev_alloc_name && register_netdev + if((status = rtw_drv_register_netdev(if1)) != _SUCCESS) { + goto free_if1; + } + +#ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_init(if1); +#endif + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link up\n"); + rtd2885_wlan_netlink_sendMsg("linkup", "8712"); +#endif + +#ifdef RTK_DMP_PLATFORM + rtw_proc_init_one(if1->pnetdev); +#endif + + + /* alloc irq */ + if (pci_alloc_irq(dvobj) != _SUCCESS) + goto free_if2; + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n")); + //DBG_871X("-871x_drv - drv_init, success!\n"); + + status = _SUCCESS; + +free_if2: + if(status != _SUCCESS && if2) { + #ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_stop(if2); + rtw_drv_if2_free(if2); + #endif + } +free_if1: + if (status != _SUCCESS && if1) { + rtw_pci_if1_deinit(if1); + } +free_dvobj: + if (status != _SUCCESS) + pci_dvobj_deinit(pdev); +exit: + return status == _SUCCESS?0:-ENODEV; +} + +/* + * dev_remove() - our device is being removed +*/ +//rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both +static void rtw_dev_remove(struct pci_dev *pdev) +{ + struct dvobj_priv *pdvobjpriv = pci_get_drvdata(pdev); + _adapter *padapter = pdvobjpriv->if1; + struct net_device *pnetdev = padapter->pnetdev; + +_func_exit_; + + DBG_871X("+rtw_dev_remove\n"); + + pdvobjpriv->processing_dev_remove = _TRUE; + + if (unlikely(!padapter)) { + return; + } + + rtw_unregister_netdevs(pdvobjpriv); + + #if 0 +#ifdef RTK_DMP_PLATFORM + padapter->bSurpriseRemoved = _FALSE; // always trate as device exists + // this will let the driver to disable it's interrupt +#else + if(pci_drvpriv.drv_registered == _TRUE) + { + //DBG_871X("r871xu_dev_remove():padapter->bSurpriseRemoved == _TRUE\n"); + padapter->bSurpriseRemoved = _TRUE; + } + /*else + { + //DBG_871X("r871xu_dev_remove():module removed\n"); + padapter->hw_init_completed = _FALSE; + }*/ +#endif + #endif + +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + rtw_unregister_early_suspend(&padapter->pwrctrlpriv); +#endif + + rtw_pm_set_ips(padapter, IPS_NONE); + rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); + + LeaveAllPowerSaveMode(padapter); + + rtw_hal_disable_interrupt(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_stop(pdvobjpriv->if2); +#endif //CONFIG_CONCURRENT_MODE + + rtw_pci_if1_deinit(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_free(pdvobjpriv->if2); +#endif + + pci_dvobj_deinit(pdev); + + DBG_871X("-r871xu_dev_remove, done\n"); + +_func_exit_; + return; +} + + +static int __init rtw_drv_entry(void) +{ + int ret = 0; + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_drv_entry\n")); + DBG_871X("rtw driver version=%s\n", DRIVERVERSION); + DBG_871X("Build at: %s %s\n", __DATE__, __TIME__); + pci_drvpriv.drv_registered = _TRUE; + + rtw_suspend_lock_init(); + + ret = pci_register_driver(&pci_drvpriv.rtw_pci_drv); + if (ret) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, (": No device found\n")); + } + + return ret; +} + +static void __exit rtw_drv_halt(void) +{ + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_drv_halt\n")); + DBG_871X("+rtw_drv_halt\n"); + + pci_drvpriv.drv_registered = _FALSE; + + pci_unregister_driver(&pci_drvpriv.rtw_pci_drv); + + rtw_suspend_lock_uninit(); + DBG_871X("-rtw_drv_halt\n"); + + rtw_mstat_dump(); +} + + +module_init(rtw_drv_entry); +module_exit(rtw_drv_halt); + diff --git a/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c b/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c new file mode 100755 index 00000000..7d671df3 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + *******************************************************************************/ +#define _PCI_OPS_LINUX_C_ + +#include + + + diff --git a/rtl8192cu-fixes/os_dep/linux/recv_linux.c b/rtl8192cu-fixes/os_dep/linux/recv_linux.c new file mode 100755 index 00000000..9c92019a --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/recv_linux.c @@ -0,0 +1,448 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RECV_OSDEP_C_ + +#include +#include +#include + +#include +#include + +#include +#include + +#ifdef CONFIG_USB_HCI +#include +#endif + +//init os related resource in struct recv_priv +int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter) +{ + int res=_SUCCESS; + + return res; +} + +//alloc os related resource in union recv_frame +int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe) +{ + int res=_SUCCESS; + + precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL; + + return res; + +} + +//free os related resource in union recv_frame +void rtw_os_recv_resource_free(struct recv_priv *precvpriv) +{ + +} + + +//alloc os related resource in struct recv_buf +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) +{ + int res=_SUCCESS; + +#ifdef CONFIG_USB_HCI + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + precvbuf->irp_pending = _FALSE; + precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); + if(precvbuf->purb == NULL){ + res = _FAIL; + } + + precvbuf->pskb = NULL; + + precvbuf->reuse = _FALSE; + + precvbuf->pallocated_buf = precvbuf->pbuf = NULL; + + precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL; + + precvbuf->transfer_len = 0; + + precvbuf->len = 0; + + #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr); + precvbuf->pbuf = precvbuf->pallocated_buf; + if(precvbuf->pallocated_buf == NULL) + return _FAIL; + #endif //CONFIG_USE_USB_BUFFER_ALLOC_RX + +#endif //CONFIG_USB_HCI + + return res; +} + +//free os related resource in struct recv_buf +int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf) +{ + int ret = _SUCCESS; + +#ifdef CONFIG_USB_HCI + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + rtw_usb_buffer_free(pusbd, (size_t)precvbuf->alloc_sz, precvbuf->pallocated_buf, precvbuf->dma_transfer_addr); + precvbuf->pallocated_buf = NULL; + precvbuf->dma_transfer_addr = 0; + +#endif //CONFIG_USE_USB_BUFFER_ALLOC_RX + + if(precvbuf->purb) + { + //usb_kill_urb(precvbuf->purb); + usb_free_urb(precvbuf->purb); + } + +#endif //CONFIG_USB_HCI + + + if(precvbuf->pskb) + rtw_skb_free(precvbuf->pskb); + + + return ret; + +} + +void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup) +{ +#ifdef CONFIG_IOCTL_CFG80211 + enum nl80211_key_type key_type; +#endif + union iwreq_data wrqu; + struct iw_michaelmicfailure ev; + struct mlme_priv* pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u32 cur_time = 0; + + if( psecuritypriv->last_mic_err_time == 0 ) + { + psecuritypriv->last_mic_err_time = rtw_get_current_time(); + } + else + { + cur_time = rtw_get_current_time(); + + if( cur_time - psecuritypriv->last_mic_err_time < 60*HZ ) + { + psecuritypriv->btkip_countermeasure = _TRUE; + psecuritypriv->last_mic_err_time = 0; + psecuritypriv->btkip_countermeasure_time = cur_time; + } + else + { + psecuritypriv->last_mic_err_time = rtw_get_current_time(); + } + } + +#ifdef CONFIG_IOCTL_CFG80211 + if ( bgroup ) + { + key_type |= NL80211_KEYTYPE_GROUP; + } + else + { + key_type |= NL80211_KEYTYPE_PAIRWISE; + } + + cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[ 0 ], key_type, -1, + NULL, GFP_ATOMIC); +#endif + + _rtw_memset( &ev, 0x00, sizeof( ev ) ); + if ( bgroup ) + { + ev.flags |= IW_MICFAILURE_GROUP; + } + else + { + ev.flags |= IW_MICFAILURE_PAIRWISE; + } + + ev.src_addr.sa_family = ARPHRD_ETHER; + _rtw_memcpy( ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + + _rtw_memset( &wrqu, 0x00, sizeof( wrqu ) ); + wrqu.data.length = sizeof( ev ); + + wireless_send_event( padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, (char*) &ev ); +} + +void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_HOSTAPD_MLME + _pkt *skb; + struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; + struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev; + + RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("+rtw_hostapd_mlme_rx\n")); + + skb = precv_frame->u.hdr.pkt; + + if (skb == NULL) + return; + + skb->data = precv_frame->u.hdr.rx_data; + skb->tail = precv_frame->u.hdr.rx_tail; + skb->len = precv_frame->u.hdr.len; + + //pskb_copy = rtw_skb_copy(skb); +// if(skb == NULL) goto _exit; + + skb->dev = pmgnt_netdev; + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + //skb->protocol = __constant_htons(0x0019); /*ETH_P_80211_RAW*/ + skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/ + + //DBG_871X("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len); + + //skb->mac.raw = skb->data; + skb_reset_mac_header(skb); + + //skb_pull(skb, 24); + _rtw_memset(skb->cb, 0, sizeof(skb->cb)); + + rtw_netif_rx(pmgnt_netdev, skb); + + precv_frame->u.hdr.pkt = NULL; // set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx() +#endif +} + +int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame) +{ + struct recv_priv *precvpriv; + _queue *pfree_recv_queue; + _pkt *skb; + struct mlme_priv*pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; +#endif + +#ifdef CONFIG_BR_EXT + void *br_port = NULL; +#endif + +_func_enter_; + + precvpriv = &(padapter->recvpriv); + pfree_recv_queue = &(precvpriv->free_recv_queue); + +#ifdef CONFIG_DRVEXT_MODULE + if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS) + { + goto _recv_indicatepkt_drop; + } +#endif + + skb = precv_frame->u.hdr.pkt; + if(skb == NULL) + { + RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n")); + goto _recv_indicatepkt_drop; + } + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n")); + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data)); + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len)); + + skb->data = precv_frame->u.hdr.rx_data; + + skb_set_tail_pointer(skb, precv_frame->u.hdr.len); + + skb->len = precv_frame->u.hdr.len; + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len)); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _pkt *pskb2=NULL; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + int bmcast = IS_MCAST(pattrib->dst); + + //DBG_871X("bmcast=%d\n", bmcast); + + if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE) + { + //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); + + if(bmcast) + { + psta = rtw_get_bcmc_stainfo(padapter); + pskb2 = rtw_skb_clone(skb); + } else { + psta = rtw_get_stainfo(pstapriv, pattrib->dst); + } + + if(psta) + { + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + + //DBG_871X("directly forwarding to the rtw_xmit_entry\n"); + + //skb->ip_summed = CHECKSUM_NONE; + skb->dev = pnetdev; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + skb_set_queue_mapping(skb, rtw_recv_select_queue(skb)); +#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) + + _rtw_xmit_entry(skb, pnetdev); + + if(bmcast) + skb = pskb2; + else + goto _recv_indicatepkt_end; + } + + + } + else// to APself + { + //DBG_871X("to APSelf\n"); + } + } + + +#ifdef CONFIG_BR_EXT + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + + if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) + { + int nat25_handle_frame(_adapter *priv, struct sk_buff *skb); + if (nat25_handle_frame(padapter, skb) == -1) { + //priv->ext_stats.rx_data_drops++; + //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); + //return FAIL; +#if 1 + // bypass this frame to upper layer!! +#else + goto _recv_indicatepkt_drop; +#endif + } + } + +#endif // CONFIG_BR_EXT + + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + //DBG_871X("CHECKSUM_UNNECESSARY \n"); + } else { + skb->ip_summed = CHECKSUM_NONE; + //DBG_871X("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt); + } +#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ + + skb->ip_summed = CHECKSUM_NONE; + +#endif + + skb->dev = padapter->pnetdev; + skb->protocol = eth_type_trans(skb, padapter->pnetdev); + + rtw_netif_rx(padapter->pnetdev, skb); + +_recv_indicatepkt_end: + + precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe() + + rtw_free_recvframe(precv_frame, pfree_recv_queue); + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n")); + +_func_exit_; + + return _SUCCESS; + +_recv_indicatepkt_drop: + + //enqueue back to free_recv_queue + if(precv_frame) + rtw_free_recvframe(precv_frame, pfree_recv_queue); + + return _FAIL; + +_func_exit_; + +} + +void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + +#ifdef CONFIG_USB_HCI + + precvbuf->ref_cnt--; + + //free skb in recv_buf + rtw_skb_free(precvbuf->pskb); + + precvbuf->pskb = NULL; + precvbuf->reuse = _FALSE; + + if(precvbuf->irp_pending == _FALSE) + { + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + + +#endif +#ifdef CONFIG_SDIO_HCI + precvbuf->pskb = NULL; +#endif + +} +void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext); +void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext) +{ + struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)FunctionContext; + rtw_reordering_ctrl_timeout_handler(preorder_ctrl); +} + +void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) +{ + _adapter *padapter = preorder_ctrl->padapter; + + _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl); + +} + diff --git a/rtl8192cu-fixes/os_dep/linux/rtw_android.c b/rtl8192cu-fixes/os_dep/linux/rtw_android.c new file mode 100755 index 00000000..d6ac16c5 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/rtw_android.c @@ -0,0 +1,839 @@ +/****************************************************************************** + * + * 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 + +#include +#include +#include +#include +#include + +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) +#include +#else +#include +#endif +#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */ + +const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = { + "START", + "STOP", + "SCAN-ACTIVE", + "SCAN-PASSIVE", + "RSSI", + "LINKSPEED", + "RXFILTER-START", + "RXFILTER-STOP", + "RXFILTER-ADD", + "RXFILTER-REMOVE", + "BTCOEXSCAN-START", + "BTCOEXSCAN-STOP", + "BTCOEXMODE", + "SETSUSPENDOPT", + "P2P_DEV_ADDR", + "SETFWPATH", + "SETBAND", + "GETBAND", + "COUNTRY", + "P2P_SET_NOA", + "P2P_GET_NOA", + "P2P_SET_PS", + "SET_AP_WPS_P2P_IE", +#ifdef PNO_SUPPORT + "PNOSSIDCLR", + "PNOSETUP ", + "PNOFORCE", + "PNODEBUG", +#endif + + "MACADDR", + + "BLOCK", + "WFD-ENABLE", + "WFD-DISABLE", + "WFD-SET-TCPPORT", + "WFD-SET-MAXTPUT", + "WFD-SET-DEVTYPE", +}; + +#ifdef PNO_SUPPORT +#define PNO_TLV_PREFIX 'S' +#define PNO_TLV_VERSION '1' +#define PNO_TLV_SUBVERSION '2' +#define PNO_TLV_RESERVED '0' +#define PNO_TLV_TYPE_SSID_IE 'S' +#define PNO_TLV_TYPE_TIME 'T' +#define PNO_TLV_FREQ_REPEAT 'R' +#define PNO_TLV_FREQ_EXPO_MAX 'M' + +typedef struct cmd_tlv { + char prefix; + char version; + char subver; + char reserved; +} cmd_tlv_t; +#endif /* PNO_SUPPORT */ + +typedef struct android_wifi_priv_cmd { + +#ifdef CONFIG_COMPAT + compat_uptr_t buf; +#else + char *buf; +#endif + + int used_len; + int total_len; +} android_wifi_priv_cmd; + +/** + * Local (static) functions and variables + */ + +/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first + * time (only) in dhd_open, subsequential wifi on will be handled by + * wl_android_wifi_on + */ +static int g_wifi_on = _TRUE; + + +#ifdef PNO_SUPPORT +static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) +{ + wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; + int res = -1; + int nssid = 0; + cmd_tlv_t *cmd_tlv_temp; + char *str_ptr; + int tlv_size_left; + int pno_time = 0; + int pno_repeat = 0; + int pno_freq_expo_max = 0; + +#ifdef PNO_SET_DEBUG + int i; + char pno_in_example[] = { + 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', + 'S', '1', '2', '0', + 'S', + 0x05, + 'd', 'l', 'i', 'n', 'k', + 'S', + 0x04, + 'G', 'O', 'O', 'G', + 'T', + '0', 'B', + 'R', + '2', + 'M', + '2', + 0x00 + }; +#endif /* PNO_SET_DEBUG */ + + DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + + if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { + DBG_871X("%s argument=%d less min size\n", __FUNCTION__, total_len); + goto exit_proc; + } + +#ifdef PNO_SET_DEBUG + memcpy(command, pno_in_example, sizeof(pno_in_example)); + for (i = 0; i < sizeof(pno_in_example); i++) + printf("%02X ", command[i]); + printf("\n"); + total_len = sizeof(pno_in_example); +#endif + + str_ptr = command + strlen(CMD_PNOSETUP_SET); + tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); + + cmd_tlv_temp = (cmd_tlv_t *)str_ptr; + memset(ssids_local, 0, sizeof(ssids_local)); + + if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && + (cmd_tlv_temp->version == PNO_TLV_VERSION) && + (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { + + str_ptr += sizeof(cmd_tlv_t); + tlv_size_left -= sizeof(cmd_tlv_t); + + if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, + MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { + DBG_871X("SSID is not presented or corrupted ret=%d\n", nssid); + goto exit_proc; + } else { + if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { + DBG_871X("%s scan duration corrupted field size %d\n", + __FUNCTION__, tlv_size_left); + goto exit_proc; + } + str_ptr++; + pno_time = simple_strtoul(str_ptr, &str_ptr, 16); + DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); + + if (str_ptr[0] != 0) { + if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { + DBG_871X("%s pno repeat : corrupted field\n", + __FUNCTION__); + goto exit_proc; + } + str_ptr++; + pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); + DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); + if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { + DBG_871X("%s FREQ_EXPO_MAX corrupted field size\n", + __FUNCTION__); + goto exit_proc; + } + str_ptr++; + pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); + DHD_INFO(("%s: pno_freq_expo_max=%d\n", + __FUNCTION__, pno_freq_expo_max)); + } + } + } else { + DBG_871X("%s get wrong TLV command\n", __FUNCTION__); + goto exit_proc; + } + + res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); + +exit_proc: + return res; +} +#endif /* PNO_SUPPORT */ + +int rtw_android_cmdstr_to_num(char *cmdstr) +{ + int cmd_num; + for(cmd_num=0 ; cmd_nummlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + int bytes_written = 0; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d", + pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); + } + + return bytes_written; +} + +int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + int bytes_written = 0; + u16 link_speed = 0; + + link_speed = rtw_get_cur_max_rate(padapter)/10; + bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); + + return bytes_written; +} + +int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + int bytes_written = 0; + + bytes_written = snprintf(command, total_len, "Macaddr = "MAC_FMT, MAC_ARG(net->dev_addr)); + return bytes_written; +} + +int rtw_android_set_country(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1; + int ret = _FAIL; + + ret = rtw_set_country(adapter, country_code); + + return (ret==_SUCCESS)?0:-1; +} + +int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len) +{ + int bytes_written = 0; + + //We use the same address as our HW MAC address + _rtw_memcpy(command, net->dev_addr, ETH_ALEN); + + bytes_written = ETH_ALEN; + return bytes_written; +} + +int rtw_android_set_block(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK]) + 1; + + #ifdef CONFIG_IOCTL_CFG80211 + wdev_to_priv(adapter->rtw_wdev)->block = (*block_value=='0')?_FALSE:_TRUE; + #endif + + return 0; +} + +int rtw_android_setband(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *arg = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SETBAND]) + 1; + u32 band = GHZ_MAX; + int ret = _FAIL; + + sscanf(arg, "%u", &band); + ret = rtw_set_band(adapter, band); + + return (ret==_SUCCESS)?0:-1; +} + +int rtw_android_getband(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + int bytes_written = 0; + + bytes_written = snprintf(command, total_len, "%u", adapter->setband); + + return bytes_written; +} + +int get_int_from_command( char* pcmd ) +{ + int i = 0; + + for( i = 0; i < strlen( pcmd ); i++ ) + { + if ( pcmd[ i ] == '=' ) + { + // Skip the '=' and space characters. + i += 2; + break; + } + } + return ( rtw_atoi( pcmd + i ) ); +} + +int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) +{ + int ret = 0; + char *command = NULL; + int cmd_num; + int bytes_written = 0; + android_wifi_priv_cmd priv_cmd; + + rtw_lock_suspend(); + + if (!ifr->ifr_data) { + ret = -EINVAL; + goto exit; + } + if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { + ret = -EFAULT; + goto exit; + } + + command = rtw_zmalloc(priv_cmd.total_len); + if (!command) + { + DBG_871X("%s: failed to allocate memory\n", __FUNCTION__); + ret = -ENOMEM; + goto exit; + } + + if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ + DBG_871X("%s: failed to access memory\n", __FUNCTION__); + ret = -EFAULT; + goto exit; + } + if (copy_from_user(command, (void *)priv_cmd.buf, priv_cmd.total_len)) { + ret = -EFAULT; + goto exit; + } + + DBG_871X("%s: Android private cmd \"%s\" on %s\n" + , __FUNCTION__, command, ifr->ifr_name); + + cmd_num = rtw_android_cmdstr_to_num(command); + + switch(cmd_num) { + case ANDROID_WIFI_CMD_START: + //bytes_written = wl_android_wifi_on(net); + goto response; + case ANDROID_WIFI_CMD_SETFWPATH: + goto response; + } + + if (!g_wifi_on) { + DBG_871X("%s: Ignore private cmd \"%s\" - iface %s is down\n" + ,__FUNCTION__, command, ifr->ifr_name); + ret = 0; + goto exit; + } + + switch(cmd_num) { + + case ANDROID_WIFI_CMD_STOP: + //bytes_written = wl_android_wifi_off(net); + break; + + case ANDROID_WIFI_CMD_SCAN_ACTIVE: + //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE); +#ifdef CONFIG_PLATFORM_MSTAR +#ifdef CONFIG_IOCTL_CFG80211 + (wdev_to_priv(net->ieee80211_ptr))->bandroid_scan = _TRUE; +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_PLATFORM_MSTAR + break; + case ANDROID_WIFI_CMD_SCAN_PASSIVE: + //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE); + break; + + case ANDROID_WIFI_CMD_RSSI: + bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_LINKSPEED: + bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_MACADDR: + bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_BLOCK: + bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_RXFILTER_START: + //bytes_written = net_os_set_packet_filter(net, 1); + break; + case ANDROID_WIFI_CMD_RXFILTER_STOP: + //bytes_written = net_os_set_packet_filter(net, 0); + break; + case ANDROID_WIFI_CMD_RXFILTER_ADD: + //int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; + //bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); + break; + case ANDROID_WIFI_CMD_RXFILTER_REMOVE: + //int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; + //bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); + break; + + case ANDROID_WIFI_CMD_BTCOEXSCAN_START: + /* TBD: BTCOEXSCAN-START */ + break; + case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP: + /* TBD: BTCOEXSCAN-STOP */ + break; + case ANDROID_WIFI_CMD_BTCOEXMODE: + #if 0 + uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; + if (mode == 1) + net_os_set_packet_filter(net, 0); /* DHCP starts */ + else + net_os_set_packet_filter(net, 1); /* DHCP ends */ +#ifdef WL_CFG80211 + bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); +#endif + #endif + break; + + case ANDROID_WIFI_CMD_SETSUSPENDOPT: + //bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_SETBAND: + bytes_written = rtw_android_setband(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_GETBAND: + bytes_written = rtw_android_getband(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; + +#ifdef PNO_SUPPORT + case ANDROID_WIFI_CMD_PNOSSIDCLR_SET: + //bytes_written = dhd_dev_pno_reset(net); + break; + case ANDROID_WIFI_CMD_PNOSETUP_SET: + //bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_PNOENABLE_SET: + //uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; + //bytes_written = dhd_dev_pno_enable(net, pfn_enabled); + break; +#endif + + case ANDROID_WIFI_CMD_P2P_DEV_ADDR: + bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_P2P_SET_NOA: + //int skip = strlen(CMD_P2P_SET_NOA) + 1; + //bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); + break; + case ANDROID_WIFI_CMD_P2P_GET_NOA: + //bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_P2P_SET_PS: + //int skip = strlen(CMD_P2P_SET_PS) + 1; + //bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip); + break; + +#ifdef CONFIG_IOCTL_CFG80211 + case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: + { + int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3; + bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); + break; + } +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_WFD + case ANDROID_WIFI_CMD_WFD_ENABLE: + { + // Commented by Albert 2012/07/24 + // We can enable the WFD function by using the following command: + // wpa_cli driver wfd-enable + + struct wifi_display_info *pwfd_info; + _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); + + pwfd_info = &padapter->wfd_info; + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + pwfd_info->wfd_enable = _TRUE; + break; + } + + case ANDROID_WIFI_CMD_WFD_DISABLE: + { + // Commented by Albert 2012/07/24 + // We can disable the WFD function by using the following command: + // wpa_cli driver wfd-disable + + struct wifi_display_info *pwfd_info; + _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); + + pwfd_info = &padapter->wfd_info; + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + pwfd_info->wfd_enable = _FALSE; + break; + } + case ANDROID_WIFI_CMD_WFD_SET_TCPPORT: + { + // Commented by Albert 2012/07/24 + // We can set the tcp port number by using the following command: + // wpa_cli driver wfd-set-tcpport = 554 + + struct wifi_display_info *pwfd_info; + _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); + + pwfd_info = &padapter->wfd_info; + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + pwfd_info->rtsp_ctrlport = ( u16 ) get_int_from_command( priv_cmd.buf ); + break; + } + case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT: + { + + + break; + } + case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE: + { + // Commented by Albert 2012/08/28 + // Specify the WFD device type ( WFD source/primary sink ) + + struct wifi_display_info *pwfd_info; + _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); + + pwfd_info = &padapter->wfd_info; + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + pwfd_info->wfd_device_type = ( u8 ) get_int_from_command( priv_cmd.buf ); + + pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL; + } + break; + } +#endif + default: + DBG_871X("Unknown PRIVATE command %s - ignored\n", command); + snprintf(command, 3, "OK"); + bytes_written = strlen("OK"); + } + +response: + if (bytes_written >= 0) { + if ((bytes_written == 0) && (priv_cmd.total_len > 0)) + command[0] = '\0'; + if (bytes_written >= priv_cmd.total_len) { + DBG_871X("%s: bytes_written = %d\n", __FUNCTION__, bytes_written); + bytes_written = priv_cmd.total_len; + } else { + bytes_written++; + } + priv_cmd.used_len = bytes_written; + if (copy_to_user((void *)priv_cmd.buf, command, bytes_written)) { + DBG_871X("%s: failed to copy data to user buffer\n", __FUNCTION__); + ret = -EFAULT; + } + } + else { + ret = bytes_written; + } + +exit: + rtw_unlock_suspend(); + if (command) { + rtw_mfree(command, priv_cmd.total_len); + } + + return ret; +} + + +/** + * Functions for Android WiFi card detection + */ +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) + +static int g_wifidev_registered = 0; +static struct semaphore wifi_control_sem; +static struct wifi_platform_data *wifi_control_data = NULL; +static struct resource *wifi_irqres = NULL; + +static int wifi_add_dev(void); +static void wifi_del_dev(void); + +int rtw_android_wifictrl_func_add(void) +{ + int ret = 0; + sema_init(&wifi_control_sem, 0); + + ret = wifi_add_dev(); + if (ret) { + DBG_871X("%s: platform_driver_register failed\n", __FUNCTION__); + return ret; + } + g_wifidev_registered = 1; + + /* Waiting callback after platform_driver_register is done or exit with error */ + if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { + ret = -EINVAL; + DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__); + } + + return ret; +} + +void rtw_android_wifictrl_func_del(void) +{ + if (g_wifidev_registered) + { + wifi_del_dev(); + g_wifidev_registered = 0; + } +} + +void *wl_android_prealloc(int section, unsigned long size) +{ + void *alloc_ptr = NULL; + if (wifi_control_data && wifi_control_data->mem_prealloc) { + alloc_ptr = wifi_control_data->mem_prealloc(section, size); + if (alloc_ptr) { + DBG_871X("success alloc section %d\n", section); + if (size != 0L) + memset(alloc_ptr, 0, size); + return alloc_ptr; + } + } + + DBG_871X("can't alloc section %d\n", section); + return NULL; +} + +int wifi_get_irq_number(unsigned long *irq_flags_ptr) +{ + if (wifi_irqres) { + *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; + return (int)wifi_irqres->start; + } +#ifdef CUSTOM_OOB_GPIO_NUM + return CUSTOM_OOB_GPIO_NUM; +#else + return -1; +#endif +} + +int wifi_set_power(int on, unsigned long msec) +{ + DBG_871X("%s = %d\n", __FUNCTION__, on); + if (wifi_control_data && wifi_control_data->set_power) { + wifi_control_data->set_power(on); + } + if (msec) + msleep(msec); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) +int wifi_get_mac_addr(unsigned char *buf) +{ + DBG_871X("%s\n", __FUNCTION__); + if (!buf) + return -EINVAL; + if (wifi_control_data && wifi_control_data->get_mac_addr) { + return wifi_control_data->get_mac_addr(buf); + } + return -EOPNOTSUPP; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE) +void *wifi_get_country_code(char *ccode) +{ + DBG_871X("%s\n", __FUNCTION__); + if (!ccode) + return NULL; + if (wifi_control_data && wifi_control_data->get_country_code) { + return wifi_control_data->get_country_code(ccode); + } + return NULL; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ + +static int wifi_set_carddetect(int on) +{ + DBG_871X("%s = %d\n", __FUNCTION__, on); + if (wifi_control_data && wifi_control_data->set_carddetect) { + wifi_control_data->set_carddetect(on); + } + return 0; +} + +static int wifi_probe(struct platform_device *pdev) +{ + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + + DBG_871X("## %s\n", __FUNCTION__); + wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); + if (wifi_irqres == NULL) + wifi_irqres = platform_get_resource_byname(pdev, + IORESOURCE_IRQ, "bcm4329_wlan_irq"); + wifi_control_data = wifi_ctrl; + + wifi_set_power(1, 0); /* Power On */ + wifi_set_carddetect(1); /* CardDetect (0->1) */ + + up(&wifi_control_sem); + return 0; +} + +static int wifi_remove(struct platform_device *pdev) +{ + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + + DBG_871X("## %s\n", __FUNCTION__); + wifi_control_data = wifi_ctrl; + + wifi_set_power(0, 0); /* Power Off */ + wifi_set_carddetect(0); /* CardDetect (1->0) */ + + up(&wifi_control_sem); + return 0; +} + +static int wifi_suspend(struct platform_device *pdev, pm_message_t state) +{ + DBG_871X("##> %s\n", __FUNCTION__); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) + bcmsdh_oob_intr_set(0); +#endif + return 0; +} + +static int wifi_resume(struct platform_device *pdev) +{ + DBG_871X("##> %s\n", __FUNCTION__); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) + if (dhd_os_check_if_up(bcmsdh_get_drvdata())) + bcmsdh_oob_intr_set(1); +#endif + return 0; +} + +/* temporarily use these two */ +static struct platform_driver wifi_device = { + .probe = wifi_probe, + .remove = wifi_remove, + .suspend = wifi_suspend, + .resume = wifi_resume, + .driver = { + .name = "bcmdhd_wlan", + } +}; + +static struct platform_driver wifi_device_legacy = { + .probe = wifi_probe, + .remove = wifi_remove, + .suspend = wifi_suspend, + .resume = wifi_resume, + .driver = { + .name = "bcm4329_wlan", + } +}; + +static int wifi_add_dev(void) +{ + DBG_871X("## Calling platform_driver_register\n"); + platform_driver_register(&wifi_device); + platform_driver_register(&wifi_device_legacy); + return 0; +} + +static void wifi_del_dev(void) +{ + DBG_871X("## Unregister platform_driver_register\n"); + platform_driver_unregister(&wifi_device); + platform_driver_unregister(&wifi_device_legacy); +} +#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */ + diff --git a/rtl8192cu-fixes/os_dep/linux/usb_intf.c b/rtl8192cu-fixes/os_dep/linux/usb_intf.c new file mode 100755 index 00000000..47e095c1 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/usb_intf.c @@ -0,0 +1,1660 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HCI_INTF_C_ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_USB_HCI + +#error "CONFIG_USB_HCI shall be on!\n" + +#endif + +#include +#include +#include +#include +#ifdef CONFIG_PLATFORM_RTK_DMP +#include +#endif + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +#ifdef CONFIG_80211N_HT +extern int rtw_ht_enable; +extern int rtw_cbw40_enable; +extern int rtw_ampdu_enable;//for enable tx_ampdu +#endif + +#ifdef CONFIG_GLOBAL_UI_PID +int ui_pid[3] = {0, 0, 0}; +#endif + + +extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal); +static int rtw_suspend(struct usb_interface *intf, pm_message_t message); +static int rtw_resume(struct usb_interface *intf); +int rtw_resume_process(_adapter *padapter); + + +static int rtw_drv_init(struct usb_interface *pusb_intf,const struct usb_device_id *pdid); +static void rtw_dev_remove(struct usb_interface *pusb_intf); + +#define USB_VENDER_ID_REALTEK 0x0BDA + +/* DID_USB_v915_20121224 */ +#define RTL8192C_USB_IDS \ + /*=== Realtek demoboard ===*/ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191)},/* Default ID */ \ + /****** 8188CUS ********/ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176)},/* 8188cu 1*1 dongole */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170)},/* 8188CE-VAU USB minCard */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817E)},/* 8188CE-VAU USB minCard */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817A)},/* 8188cu Slim Solo */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817B)},/* 8188cu Slim Combo */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817D)},/* 8188RU High-power USB Dongle */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754)},/* 8188 Combo for BC4 */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817F)},/* 8188RU */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818A)},/* RTL8188CUS-VL */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x018A)},/* RTL8188CTV */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x17C0)}, /* RTK demoboard - USB-N10E */ \ + /****** 8192CUS ********/ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177)},/* 8191cu 1*2 */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8178)},/* 8192cu 2*2 */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817C)},/* 8192CE-VAU USB minCard */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191)},/* 8192CU 2*2 */ \ + {USB_DEVICE(0x1058, 0x0631)},/* Alpha, 8192CU */ \ + /*=== Customer ID ===*/ \ + /****** 8188CUS Dongle ********/ \ + {USB_DEVICE(0x2019, 0xED17)},/* PCI - Edimax */ \ + {USB_DEVICE(0x0DF6, 0x0052)},/* Sitecom - Edimax */ \ + {USB_DEVICE(0x7392, 0x7811)},/* Edimax - Edimax */ \ + {USB_DEVICE(0x07B8, 0x8189)},/* Abocom - Abocom */ \ + {USB_DEVICE(0x0EB0, 0x9071)},/* NO Brand - Etop */ \ + {USB_DEVICE(0x06F8, 0xE033)},/* Hercules - Edimax */ \ + {USB_DEVICE(0x103C, 0x1629)},/* HP - Lite-On ,8188CUS Slim Combo */ \ + {USB_DEVICE(0x2001, 0x3308)},/* D-Link - Alpha */ \ + {USB_DEVICE(0x050D, 0x1102)},/* Belkin - Edimax */ \ + {USB_DEVICE(0x050D, 0x11F2)},/* ISY - Edimax */ \ + {USB_DEVICE(0x2019, 0xAB2A)},/* Planex - Abocom */ \ + {USB_DEVICE(0x20F4, 0x648B)},/* TRENDnet - Cameo */ \ + {USB_DEVICE(0x4855, 0x0090)},/* - Feixun */ \ + {USB_DEVICE(0x13D3, 0x3357)},/* - AzureWave */ \ + {USB_DEVICE(0x0DF6, 0x005C)},/* Sitecom - Edimax */ \ + {USB_DEVICE(0x0BDA, 0x5088)},/* Thinkware - CC&C */ \ + {USB_DEVICE(0x4856, 0x0091)},/* NetweeN - Feixun */ \ + {USB_DEVICE(0x0846, 0x9041)}, /* Netgear - Cameo */ \ + {USB_DEVICE(0x0846, 0x9042)}, /* On Networks - N150MA */ \ + {USB_DEVICE(0x0846, 0x9043)}, /* Netgear N150 -WNA1000M */ \ + {USB_DEVICE(0x2019, 0x4902)},/* Planex - Etop */ \ + {USB_DEVICE(0x2019, 0xAB2E)},/* SW-WF02-AD15 -Abocom */ \ + {USB_DEVICE(0x2001, 0x330B)}, /* D-LINK - T&W */ \ + {USB_DEVICE(0xCDAB, 0x8010)}, /* - - compare */ \ + {USB_DEVICE(0x0B05, 0x17BA)}, /* ASUS - Edimax */ \ + {USB_DEVICE(0x0BDA, 0x1E1E)}, /* Intel - - */ \ + {USB_DEVICE(0x04BB, 0x094c)}, /* I-O DATA - Edimax */ \ + {USB_DEVICE(0X0BDA, 0x8176)}, /* TP-Link - TL-WN723N */ \ + /****** 8188CTV ********/ \ + {USB_DEVICE(0xCDAB, 0x8011)}, /* - - compare */ \ + {USB_DEVICE(0x0BDA, 0x0A8A)}, /* Sony - Foxconn */ \ + /****** 8188 RU ********/ \ + {USB_DEVICE(0x0BDA, 0x317F)},/* Netcore,Netcore */ \ + /****** 8188CE-VAU ********/ \ + {USB_DEVICE(0x13D3, 0x3359)},/* - Azwave */ \ + {USB_DEVICE(0x13D3, 0x3358)},/* - Azwave */ \ + /****** 8188CUS Slim Solo********/ \ + {USB_DEVICE(0x04F2, 0xAFF7)},/* XAVI - XAVI */ \ + {USB_DEVICE(0x04F2, 0xAFF9)},/* XAVI - XAVI */ \ + {USB_DEVICE(0x04F2, 0xAFFA)},/* XAVI - XAVI */ \ + /****** 8188CUS Slim Combo ********/ \ + {USB_DEVICE(0x04F2, 0xAFF8)},/* XAVI - XAVI */ \ + {USB_DEVICE(0x04F2, 0xAFFB)},/* XAVI - XAVI */ \ + {USB_DEVICE(0x04F2, 0xAFFC)},/* XAVI - XAVI */ \ + {USB_DEVICE(0x2019, 0x1201)},/* Planex - Vencer */ \ + /****** 8192CUS Dongle ********/ \ + {USB_DEVICE(0x2001, 0x3307)},/* D-Link - Cameo */ \ + {USB_DEVICE(0x2001, 0x330A)},/* D-Link - Alpha */ \ + {USB_DEVICE(0x2001, 0x3309)},/* D-Link - Alpha */ \ + {USB_DEVICE(0x2001, 0x330D)},/* D-Link DWA-131 (H/W Ver. B1) */ \ + {USB_DEVICE(0x0586, 0x341F)},/* Zyxel - Abocom */ \ + {USB_DEVICE(0x7392, 0x7822)},/* Edimax - Edimax */ \ + {USB_DEVICE(0x2019, 0xAB2B)},/* Planex - Abocom */ \ + {USB_DEVICE(0x07B8, 0x8178)},/* Abocom - Abocom */ \ + {USB_DEVICE(0x07AA, 0x0056)},/* ATKK - Gemtek */ \ + {USB_DEVICE(0x4855, 0x0091)},/* - Feixun */ \ + {USB_DEVICE(0x050D, 0x2102)},/* Belkin - Sercomm */ \ + {USB_DEVICE(0x050D, 0x2103)},/* Belkin - Edimax */ \ + {USB_DEVICE(0x20F4, 0x624D)},/* TRENDnet */ \ + {USB_DEVICE(0x0DF6, 0x0061)},/* Sitecom - Edimax */ \ + {USB_DEVICE(0x0B05, 0x17AB)},/* ASUS - Edimax */ \ + {USB_DEVICE(0x0846, 0x9021)},/* Netgear - Sercomm */ \ + {USB_DEVICE(0x0846, 0xF001)}, /* Netgear - Sercomm */ \ + {USB_DEVICE(0x0E66, 0x0019)},/* Hawking,Edimax */ \ + {USB_DEVICE(0x0E66, 0x0020)}, /* Hawking - Edimax */ \ + {USB_DEVICE(0x050D, 0x1004)}, /* Belkin - Edimax */ \ + {USB_DEVICE(0x0BDA, 0x2E2E)}, /* Intel - - */ \ + {USB_DEVICE(0x2357, 0x0100)}, /* TP-Link - TP-Link */ \ + {USB_DEVICE(0x06F8, 0xE035)}, /* Hercules - Edimax */ \ + {USB_DEVICE(0x04BB, 0x0950)}, /* IO-DATA - Edimax */ \ + {USB_DEVICE(0x0DF6, 0x0070)}, /* Sitecom - Edimax */ \ + {USB_DEVICE(0x0789, 0x016D)}, /* LOGITEC - Edimax */ \ + /****** 8192CE-VAU ********/ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8186)},/* Intel-Xavi( Azwave) */ + +#define RTL8192D_USB_IDS \ + /*=== Realtek demoboard ===*/ \ + /****** 8192DU ********/ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8193)},/* 8192DU-VC */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8194)},/* 8192DU-VS */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8111)},/* Realtek 5G dongle for WiFi Display */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0193)},/* 8192DE-VAU */ \ + {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8171)},/* 8192DU-VC */ \ + /*=== Customer ID ===*/ \ + /****** 8192DU-VC ********/ \ + {USB_DEVICE(0x2019, 0xAB2C)},/* PCI - Abocm */ \ + {USB_DEVICE(0x2019, 0x4903)},/* PCI - ETOP */ \ + {USB_DEVICE(0x2019, 0x4904)},/* PCI - ETOP */ \ + {USB_DEVICE(0x07B8, 0x8193)},/* Abocom - Abocom */ \ + /****** 8192DU-VS ********/ \ + {USB_DEVICE(0x20F4, 0x664B)}, /* TRENDnet - Cameo */ \ + {USB_DEVICE(0x04DD, 0x954F)}, /* Sharp */ \ + {USB_DEVICE(0x04DD, 0x96A6)}, /* Sharp */ \ + {USB_DEVICE(0x050D, 0x110A)}, /* Belkin - Edimax */ \ + {USB_DEVICE(0x050D, 0x1105)}, /* Belkin - Edimax */ \ + {USB_DEVICE(0x050D, 0x120A)}, /* Belkin - Edimax */ \ + {USB_DEVICE(0x1668, 0x8102)}, /* - */ \ + {USB_DEVICE(0x0BDA, 0xE194)}, /* - Edimax */ \ + /****** 8192DU-WiFi Display Dongle ********/ \ + {USB_DEVICE(0x2019, 0xAB2D)},/* Planex - Abocom ,5G dongle for WiFi Display */ + +#ifndef CONFIG_RTL8192C + #undef RTL8192C_USB_IDS + #define RTL8192C_USB_IDS +#endif +#ifndef CONFIG_RTL8192D + #undef RTL8192D_USB_IDS + #define RTL8192D_USB_IDS +#endif + + +static struct usb_device_id rtw_usb_id_tbl[] ={ + RTL8192C_USB_IDS + RTL8192D_USB_IDS + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl); + +int const rtw_usb_id_len = sizeof(rtw_usb_id_tbl) / sizeof(struct usb_device_id); + +static struct specific_device_id specific_device_id_tbl[] = { + {.idVendor=USB_VENDER_ID_REALTEK, .idProduct=0x8177, .flags=SPEC_DEV_ID_DISABLE_HT},//8188cu 1*1 dongole, (b/g mode only) + {.idVendor=USB_VENDER_ID_REALTEK, .idProduct=0x817E, .flags=SPEC_DEV_ID_DISABLE_HT},//8188CE-VAU USB minCard (b/g mode only) + {.idVendor=0x0b05, .idProduct=0x1791, .flags=SPEC_DEV_ID_DISABLE_HT}, + {.idVendor=0x13D3, .idProduct=0x3311, .flags=SPEC_DEV_ID_DISABLE_HT}, + {.idVendor=0x13D3, .idProduct=0x3359, .flags=SPEC_DEV_ID_DISABLE_HT},//Russian customer -Azwave (8188CE-VAU g mode) +#ifdef RTK_DMP_PLATFORM + {.idVendor=USB_VENDER_ID_REALTEK, .idProduct=0x8111, .flags=SPEC_DEV_ID_ASSIGN_IFNAME}, // Realtek 5G dongle for WiFi Display + {.idVendor=0x2019, .idProduct=0xAB2D, .flags=SPEC_DEV_ID_ASSIGN_IFNAME}, // PCI-Abocom 5G dongle for WiFi Display +#endif /* RTK_DMP_PLATFORM */ + {} +}; + +struct rtw_usb_drv { + struct usb_driver usbdrv; + int drv_registered; +}; + +static void rtw_dev_shutdown(struct device *dev) +{ + struct usb_interface *usb_intf = container_of(dev, struct usb_interface, dev); + struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); + _adapter *adapter = dvobj->if1; + int i; + + DBG_871X("%s\n", __func__); + + for (i = 0; iiface_nums; i++) { + adapter = dvobj->padapters[i]; + adapter->bSurpriseRemoved = _TRUE; + } + + ATOMIC_SET(&dvobj->continual_urb_error, MAX_CONTINUAL_URB_ERR+1); +} + +#ifdef CONFIG_RTL8192C +static struct usb_device_id rtl8192c_usb_id_tbl[] ={ + RTL8192C_USB_IDS + {} /* Terminating entry */ +}; + +struct rtw_usb_drv rtl8192c_usb_drv = { + .usbdrv.name = (char*)"rtl8192cu", + .usbdrv.probe = rtw_drv_init, + .usbdrv.disconnect = rtw_dev_remove, + .usbdrv.id_table = rtl8192c_usb_id_tbl, + .usbdrv.suspend = rtw_suspend, + .usbdrv.resume = rtw_resume, + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) + .usbdrv.reset_resume = rtw_resume, + #endif + #ifdef CONFIG_AUTOSUSPEND + .usbdrv.supports_autosuspend = 1, + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) + .usbdrv.drvwrap.driver.shutdown = rtw_dev_shutdown, + #else + .usbdrv.driver.shutdown = rtw_dev_shutdown, + #endif +}; + +static struct rtw_usb_drv *usb_drv = &rtl8192c_usb_drv; +#endif /* CONFIG_RTL8192C */ + +#ifdef CONFIG_RTL8192D +static struct usb_device_id rtl8192d_usb_id_tbl[] ={ + RTL8192D_USB_IDS + {} /* Terminating entry */ +}; + +struct rtw_usb_drv rtl8192d_usb_drv = { + .usbdrv.name = (char*)"rtl8192du", + .usbdrv.probe = rtw_drv_init, + .usbdrv.disconnect = rtw_dev_remove, + .usbdrv.id_table = rtl8192d_usb_id_tbl, + .usbdrv.suspend = rtw_suspend, + .usbdrv.resume = rtw_resume, + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) + .usbdrv.reset_resume = rtw_resume, + #endif + #ifdef CONFIG_AUTOSUSPEND + .usbdrv.supports_autosuspend = 1, + #endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) + .usbdrv.drvwrap.driver.shutdown = rtw_dev_shutdown, + #else + .usbdrv.driver.shutdown = rtw_dev_shutdown, + #endif +}; +static struct rtw_usb_drv *usb_drv = &rtl8192d_usb_drv; +#endif /* CONFIG_RTL8192D */ + +static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); +} + +static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); +} + +static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT); +} + +static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK); +} + +static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) +{ + return (RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd)); +} + +static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) +{ + return (RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd)); +} + +static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) +{ + return (RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd)); +} + +static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) +{ + return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +} + +static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj) +{ + u8 rst = _SUCCESS; + + #ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _rtw_mutex_init(&dvobj->usb_vendor_req_mutex); + #endif + + + #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + dvobj->usb_alloc_vendor_req_buf = rtw_zmalloc(MAX_USB_IO_CTL_SIZE); + if (dvobj->usb_alloc_vendor_req_buf == NULL) { + DBG_871X("alloc usb_vendor_req_buf failed... /n"); + rst = _FAIL; + goto exit; + } + dvobj->usb_vendor_req_buf = + (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(dvobj->usb_alloc_vendor_req_buf ), ALIGNMENT_UNIT); +exit: + #endif + + return rst; + +} + +static u8 rtw_deinit_intf_priv(struct dvobj_priv *dvobj) +{ + u8 rst = _SUCCESS; + + #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + if(dvobj->usb_vendor_req_buf) + rtw_mfree(dvobj->usb_alloc_vendor_req_buf, MAX_USB_IO_CTL_SIZE); + #endif + + #ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _rtw_mutex_free(&dvobj->usb_vendor_req_mutex); + #endif + + return rst; +} + +static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) +{ + int i; + u8 val8; + int status = _FAIL; + struct dvobj_priv *pdvobjpriv = NULL; + struct usb_device *pusbd; + struct usb_device_descriptor *pdev_desc; + struct usb_host_config *phost_conf; + struct usb_config_descriptor *pconf_desc; + struct usb_host_interface *phost_iface; + struct usb_interface_descriptor *piface_desc; + struct usb_host_endpoint *phost_endp; + struct usb_endpoint_descriptor *pendp_desc; + +_func_enter_; + + if((pdvobjpriv = devobj_init()) == NULL) { + goto exit; + } + + pdvobjpriv->pusbintf = usb_intf ; + pusbd = pdvobjpriv->pusbdev = interface_to_usbdev(usb_intf); + usb_set_intfdata(usb_intf, pdvobjpriv); + + pdvobjpriv->RtNumInPipes = 0; + pdvobjpriv->RtNumOutPipes = 0; + + + pdev_desc = &pusbd->descriptor; +#if 0 + DBG_871X("\n8712_usb_device_descriptor:\n"); + DBG_871X("bLength=%x\n", pdev_desc->bLength); + DBG_871X("bDescriptorType=%x\n", pdev_desc->bDescriptorType); + DBG_871X("bcdUSB=%x\n", pdev_desc->bcdUSB); + DBG_871X("bDeviceClass=%x\n", pdev_desc->bDeviceClass); + DBG_871X("bDeviceSubClass=%x\n", pdev_desc->bDeviceSubClass); + DBG_871X("bDeviceProtocol=%x\n", pdev_desc->bDeviceProtocol); + DBG_871X("bMaxPacketSize0=%x\n", pdev_desc->bMaxPacketSize0); + DBG_871X("idVendor=%x\n", pdev_desc->idVendor); + DBG_871X("idProduct=%x\n", pdev_desc->idProduct); + DBG_871X("bcdDevice=%x\n", pdev_desc->bcdDevice); + DBG_871X("iManufacturer=%x\n", pdev_desc->iManufacturer); + DBG_871X("iProduct=%x\n", pdev_desc->iProduct); + DBG_871X("iSerialNumber=%x\n", pdev_desc->iSerialNumber); + DBG_871X("bNumConfigurations=%x\n", pdev_desc->bNumConfigurations); +#endif + + phost_conf = pusbd->actconfig; + pconf_desc = &phost_conf->desc; + +#if 0 + DBG_871X("\n8712_usb_configuration_descriptor:\n"); + DBG_871X("bLength=%x\n", pconf_desc->bLength); + DBG_871X("bDescriptorType=%x\n", pconf_desc->bDescriptorType); + DBG_871X("wTotalLength=%x\n", pconf_desc->wTotalLength); + DBG_871X("bNumInterfaces=%x\n", pconf_desc->bNumInterfaces); + DBG_871X("bConfigurationValue=%x\n", pconf_desc->bConfigurationValue); + DBG_871X("iConfiguration=%x\n", pconf_desc->iConfiguration); + DBG_871X("bmAttributes=%x\n", pconf_desc->bmAttributes); + DBG_871X("bMaxPower=%x\n", pconf_desc->bMaxPower); +#endif + + //DBG_871X("\n/****** num of altsetting = (%d) ******/\n", usb_intf->num_altsetting); + + phost_iface = &usb_intf->altsetting[0]; + piface_desc = &phost_iface->desc; + +#if 0 + DBG_871X("\n8712_usb_interface_descriptor:\n"); + DBG_871X("bLength=%x\n", piface_desc->bLength); + DBG_871X("bDescriptorType=%x\n", piface_desc->bDescriptorType); + DBG_871X("bInterfaceNumber=%x\n", piface_desc->bInterfaceNumber); + DBG_871X("bAlternateSetting=%x\n", piface_desc->bAlternateSetting); + DBG_871X("bNumEndpoints=%x\n", piface_desc->bNumEndpoints); + DBG_871X("bInterfaceClass=%x\n", piface_desc->bInterfaceClass); + DBG_871X("bInterfaceSubClass=%x\n", piface_desc->bInterfaceSubClass); + DBG_871X("bInterfaceProtocol=%x\n", piface_desc->bInterfaceProtocol); + DBG_871X("iInterface=%x\n", piface_desc->iInterface); +#endif + + pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; + pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber; + pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; + + //DBG_871X("\ndump usb_endpoint_descriptor:\n"); + + for (i = 0; i < pdvobjpriv->nr_endpoint; i++) + { + phost_endp = phost_iface->endpoint + i; + if (phost_endp) + { + pendp_desc = &phost_endp->desc; + + DBG_871X("\nusb_endpoint_descriptor(%d):\n", i); + DBG_871X("bLength=%x\n",pendp_desc->bLength); + DBG_871X("bDescriptorType=%x\n",pendp_desc->bDescriptorType); + DBG_871X("bEndpointAddress=%x\n",pendp_desc->bEndpointAddress); + //DBG_871X("bmAttributes=%x\n",pendp_desc->bmAttributes); + //DBG_871X("wMaxPacketSize=%x\n",pendp_desc->wMaxPacketSize); + DBG_871X("wMaxPacketSize=%x\n",le16_to_cpu(pendp_desc->wMaxPacketSize)); + DBG_871X("bInterval=%x\n",pendp_desc->bInterval); + //DBG_871X("bRefresh=%x\n",pendp_desc->bRefresh); + //DBG_871X("bSynchAddress=%x\n",pendp_desc->bSynchAddress); + + if (RT_usb_endpoint_is_bulk_in(pendp_desc)) + { + DBG_871X("RT_usb_endpoint_is_bulk_in = %x\n", RT_usb_endpoint_num(pendp_desc)); + pdvobjpriv->RtNumInPipes++; + } + else if (RT_usb_endpoint_is_int_in(pendp_desc)) + { + DBG_871X("RT_usb_endpoint_is_int_in = %x, Interval = %x\n", RT_usb_endpoint_num(pendp_desc),pendp_desc->bInterval); + pdvobjpriv->RtNumInPipes++; + } + else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) + { + DBG_871X("RT_usb_endpoint_is_bulk_out = %x\n", RT_usb_endpoint_num(pendp_desc)); + pdvobjpriv->RtNumOutPipes++; + } + pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc); + } + } + + DBG_871X("nr_endpoint=%d, in_num=%d, out_num=%d\n\n", pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes); + + if (pusbd->speed == USB_SPEED_HIGH) { + pdvobjpriv->ishighspeed = _TRUE; + DBG_871X("USB_SPEED_HIGH\n"); + } else { + pdvobjpriv->ishighspeed = _FALSE; + DBG_871X("NON USB_SPEED_HIGH\n"); + } + + if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't INIT rtw_init_intf_priv\n")); + goto free_dvobj; + } + + //.3 misc + _rtw_init_sema(&(pdvobjpriv->usb_suspend_sema), 0); + + rtw_reset_continual_urb_error(pdvobjpriv); + + usb_get_dev(pusbd); + + //DBG_871X("%s %d\n", __func__, ATOMIC_READ(&usb_intf->dev.kobj.kref.refcount)); + + status = _SUCCESS; + +free_dvobj: + if (status != _SUCCESS && pdvobjpriv) { + usb_set_intfdata(usb_intf, NULL); + devobj_deinit(pdvobjpriv); + pdvobjpriv = NULL; + } +exit: +_func_exit_; + return pdvobjpriv; +} + +static void usb_dvobj_deinit(struct usb_interface *usb_intf) +{ + struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf); + +_func_enter_; + + usb_set_intfdata(usb_intf, NULL); + if (dvobj) { + //Modify condition for 92DU DMDP 2010.11.18, by Thomas + /*if ((dvobj->NumInterfaces == 1) + || ((dvobj->InterfaceNumber == 1) && (dvobj->DualMacMode == _TRUE))) { + if (interface_to_usbdev(usb_intf)->state != USB_STATE_NOTATTACHED) { + //If we didn't unplug usb dongle and remove/insert modlue, driver fails on sitesurvey for the first time when device is up . + //Reset usb port for sitesurvey fail issue. 2009.8.13, by Thomas + DBG_871X("usb attached..., try to reset usb device\n"); + usb_reset_device(interface_to_usbdev(usb_intf)); + } + }*/ + rtw_deinit_intf_priv(dvobj); + devobj_deinit(dvobj); + } + + //DBG_871X("%s %d\n", __func__, ATOMIC_READ(&usb_intf->dev.kobj.kref.refcount)); + usb_put_dev(interface_to_usbdev(usb_intf)); + +_func_exit_; +} + +static void decide_chip_type_by_usb_device_id(_adapter *padapter, const struct usb_device_id *pdid) +{ + padapter->chip_type = NULL_CHIP_TYPE; +#ifdef CONFIG_RTL8192C + padapter->chip_type = RTL8188C_8192C; + padapter->HardwareType = HARDWARE_TYPE_RTL8192CU; + DBG_871X("CHIP TYPE: RTL8188C_8192C\n"); +#endif + +#ifdef CONFIG_RTL8192D + padapter->chip_type = RTL8192D; + padapter->HardwareType = HARDWARE_TYPE_RTL8192DU; + DBG_871X("CHIP TYPE: RTL8192D\n"); +#endif +} + +static void usb_intf_start(_adapter *padapter) +{ + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+usb_intf_start\n")); + rtw_hal_inirp_init(padapter); + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-usb_intf_start\n")); +} + +static void usb_intf_stop(_adapter *padapter) +{ + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+usb_intf_stop\n")); + + //disabel_hw_interrupt + if(padapter->bSurpriseRemoved == _FALSE) + { + //device still exists, so driver can do i/o operation + //TODO: + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("SurpriseRemoved==_FALSE\n")); + } + + //cancel in irp + rtw_hal_inirp_deinit(padapter); + + //cancel out irp + rtw_write_port_cancel(padapter); + + //todo:cancel other irps + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-usb_intf_stop\n")); + +} + +static void rtw_dev_unload(_adapter *padapter) +{ + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + u8 val8; + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_dev_unload\n")); + + if(padapter->bup == _TRUE) + { + DBG_871X("===> rtw_dev_unload\n"); + + padapter->bDriverStopped = _TRUE; + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + //s3. + if(padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + //s4. + if(!padapter->pwrctrlpriv.bInternalAutoSuspend ) + rtw_stop_drv_threads(padapter); + + + //s5. + if(padapter->bSurpriseRemoved == _FALSE) + { + //DBG_871X("r871x_dev_unload()->rtl871x_hal_deinit()\n"); +#ifdef CONFIG_WOWLAN + if((padapter->pwrctrlpriv.bSupportRemoteWakeup==_TRUE)&&(padapter->pwrctrlpriv.wowlan_mode==_TRUE)){ + DBG_871X("%s bSupportWakeOnWlan==_TRUE do not run rtw_hal_deinit()\n",__FUNCTION__); + } + else +#endif //CONFIG_WOWLAN + { + rtw_hal_deinit(padapter); + } + padapter->bSurpriseRemoved = _TRUE; + } + + padapter->bup = _FALSE; +#ifdef CONFIG_WOWLAN + padapter->hw_init_completed=_FALSE; +#endif //CONFIG_WOWLAN + } + else + { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("r871x_dev_unload():padapter->bup == _FALSE\n" )); + } + + DBG_871X("<=== rtw_dev_unload\n"); + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-rtw_dev_unload\n")); + +} + +static void process_spec_devid(const struct usb_device_id *pdid) +{ + u16 vid, pid; + u32 flags; + int i; + int num = sizeof(specific_device_id_tbl)/sizeof(struct specific_device_id); + + for(i=0; iidVendor==vid) && (pdid->idProduct==pid) && (flags&SPEC_DEV_ID_DISABLE_HT)) + { + rtw_ht_enable = 0; + rtw_cbw40_enable = 0; + rtw_ampdu_enable = 0; + } +#endif + +#ifdef RTK_DMP_PLATFORM + // Change the ifname to wlan10 when PC side WFD dongle plugin on DMP platform. + // It is used to distinguish between normal and PC-side wifi dongle/module. + if((pdid->idVendor==vid) && (pdid->idProduct==pid) && (flags&SPEC_DEV_ID_ASSIGN_IFNAME)) + { + extern char* ifname; + strncpy(ifname, "wlan10", 6); + //DBG_871X("%s()-%d: ifname=%s, vid=%04X, pid=%04X\n", __FUNCTION__, __LINE__, ifname, vid, pid); + } +#endif /* RTK_DMP_PLATFORM */ + + } +} + +#ifdef SUPPORT_HW_RFOFF_DETECTED +int rtw_hw_suspend(_adapter *padapter ) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct usb_interface *pusb_intf = adapter_to_dvobj(padapter)->pusbintf; + struct net_device *pnetdev = padapter->pnetdev; + + _func_enter_; + + if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved)) + { + DBG_871X("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", + padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved); + goto error_exit; + } + + if(padapter)//system suspend + { + LeaveAllPowerSaveMode(padapter); + + DBG_871X("==> rtw_hw_suspend\n"); + _enter_pwrlock(&pwrpriv->lock); + pwrpriv->bips_processing = _TRUE; + //padapter->net_closed = _TRUE; + //s1. + if(pnetdev) + { + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + } + + //s2. + rtw_disassoc_cmd(padapter, 500, _FALSE); + + //s2-2. indicate disconnect to os + //rtw_indicate_disconnect(padapter); + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if(check_fwstate(pmlmepriv, _FW_LINKED)) + { + _clr_fwstate_(pmlmepriv, _FW_LINKED); + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + rtw_os_indicate_disconnect(padapter); + + #ifdef CONFIG_LPS + //donnot enqueue cmd + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0); + #endif + } + + } + //s2-3. + rtw_free_assoc_resources(padapter, 1); + + //s2-4. + rtw_free_network_queue(padapter,_TRUE); + #ifdef CONFIG_IPS + rtw_ips_dev_unload(padapter); + #endif + pwrpriv->rf_pwrstate = rf_off; + pwrpriv->bips_processing = _FALSE; + + _exit_pwrlock(&pwrpriv->lock); + } + else + goto error_exit; + + _func_exit_; + return 0; + +error_exit: + DBG_871X("%s, failed \n",__FUNCTION__); + return (-1); + +} + +int rtw_hw_resume(_adapter *padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct usb_interface *pusb_intf = adapter_to_dvobj(padapter)->pusbintf; + struct net_device *pnetdev = padapter->pnetdev; + + _func_enter_; + + if(padapter)//system resume + { + DBG_871X("==> rtw_hw_resume\n"); + _enter_pwrlock(&pwrpriv->lock); + pwrpriv->bips_processing = _TRUE; + rtw_reset_drv_sw(padapter); + + if(pm_netdev_open(pnetdev,_FALSE) != 0) + { + _exit_pwrlock(&pwrpriv->lock); + goto error_exit; + } + + 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); + + pwrpriv->bkeepfwalive = _FALSE; + pwrpriv->brfoffbyhw = _FALSE; + + pwrpriv->rf_pwrstate = rf_on; + pwrpriv->bips_processing = _FALSE; + + _exit_pwrlock(&pwrpriv->lock); + } + else + { + goto error_exit; + } + + _func_exit_; + + return 0; +error_exit: + DBG_871X("%s, Open net dev failed \n",__FUNCTION__); + return (-1); +} +#endif + +static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message) +{ + struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); + _adapter *padapter = dvobj->if1; + struct net_device *pnetdev = padapter->pnetdev; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct usb_device *usb_dev = interface_to_usbdev(pusb_intf); +#ifdef CONFIG_WOWLAN + struct wowlan_ioctl_param poidparam; +#endif // CONFIG_WOWLAN + int ret = 0; + u32 start_time = rtw_get_current_time(); + _func_enter_; + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved)) + { + DBG_871X("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", + padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved); + goto exit; + } + + if(pwrpriv->bInternalAutoSuspend ) + { + #ifdef CONFIG_AUTOSUSPEND + #ifdef SUPPORT_HW_RFOFF_DETECTED + // The FW command register update must after MAC and FW init ready. + if((padapter->bFWReady) && ( padapter->pwrctrlpriv.bHWPwrPindetect ) && (padapter->registrypriv.usbss_enable )) + { + u8 bOpen = _TRUE; + rtw_interface_ps_func(padapter,HAL_USB_SELECT_SUSPEND,&bOpen); + //rtl8192c_set_FwSelectSuspend_cmd(padapter,_TRUE ,500);//note fw to support hw power down ping detect + } + #endif + #endif + } + pwrpriv->bInSuspend = _TRUE; + rtw_cancel_all_timer(padapter); + LeaveAllPowerSaveMode(padapter); + + rtw_stop_cmd_thread(padapter); + + _enter_pwrlock(&pwrpriv->lock); + //padapter->net_closed = _TRUE; + //s1. + if(pnetdev) + { + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + } +#ifdef CONFIG_WOWLAN + if(padapter->pwrctrlpriv.bSupportRemoteWakeup==_TRUE&&padapter->pwrctrlpriv.wowlan_mode==_TRUE){ + u8 ps_mode=PS_MODE_MIN; + //set H2C command + poidparam.subcode=WOWLAN_ENABLE; + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam); + //rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, &ps_mode); + //rtw_set_rpwm(padapter, PS_STATE_S2); + } + else +#endif //CONFIG_WOWLAN + { + //s2. + rtw_disassoc_cmd(padapter, 0, _FALSE); + } + +#ifdef CONFIG_LAYER2_ROAMING_RESUME + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) ) + { + //printk("%s:%d assoc_ssid:%s\n", __FUNCTION__, __LINE__, pmlmepriv->assoc_ssid.Ssid); + DBG_871X("%s:%d %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, __LINE__, + pmlmepriv->cur_network.network.Ssid.Ssid, + MAC_ARG(pmlmepriv->cur_network.network.MacAddress), + pmlmepriv->cur_network.network.Ssid.SsidLength, + pmlmepriv->assoc_ssid.SsidLength); + rtw_set_roaming(padapter, 1); + } +#endif + //s2-2. indicate disconnect to os + rtw_indicate_disconnect(padapter); + //s2-3. + rtw_free_assoc_resources(padapter, 1); +#ifdef CONFIG_AUTOSUSPEND + if(!pwrpriv->bInternalAutoSuspend ) +#endif + //s2-4. + rtw_free_network_queue(padapter, _TRUE); + + rtw_dev_unload(padapter); +#ifdef CONFIG_AUTOSUSPEND + pwrpriv->rf_pwrstate = rf_off; + pwrpriv->bips_processing = _FALSE; +#endif + _exit_pwrlock(&pwrpriv->lock); + + if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + rtw_indicate_scan_done(padapter, 1); + + if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) + rtw_indicate_disconnect(padapter); + +exit: + DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ + , ret, rtw_get_passing_time_ms(start_time)); + + _func_exit_; + return ret; +} + +static int rtw_resume(struct usb_interface *pusb_intf) +{ + struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); + _adapter *padapter = dvobj->if1; + struct net_device *pnetdev = padapter->pnetdev; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + int ret = 0; + + if(pwrpriv->bInternalAutoSuspend ){ + ret = rtw_resume_process(padapter); + } else { +#ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_resume_in_workqueue(pwrpriv); +#else + if (rtw_is_earlysuspend_registered(pwrpriv) + #ifdef CONFIG_WOWLAN + && !padapter->pwrctrlpriv.wowlan_mode + #endif /* CONFIG_WOWLAN */ + ) { + /* jeff: bypass resume here, do in late_resume */ + rtw_set_do_late_resume(pwrpriv, _TRUE); + } else { + ret = rtw_resume_process(padapter); + } +#endif /* CONFIG_RESUME_IN_WORKQUEUE */ + } + + return ret; + +} + +int rtw_resume_process(_adapter *padapter) +{ + struct net_device *pnetdev; + struct pwrctrl_priv *pwrpriv; + int ret = -1; + u32 start_time = rtw_get_current_time(); + _func_enter_; + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + if(padapter) { + pnetdev= padapter->pnetdev; + pwrpriv = &padapter->pwrctrlpriv; + } else { + goto exit; + } + + _enter_pwrlock(&pwrpriv->lock); + rtw_reset_drv_sw(padapter); + pwrpriv->bkeepfwalive = _FALSE; + + DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive); + if(pm_netdev_open(pnetdev,_TRUE) != 0) { + _exit_pwrlock(&pwrpriv->lock); + goto exit; + } + + netif_device_attach(pnetdev); + netif_carrier_on(pnetdev); + +#ifdef CONFIG_AUTOSUSPEND + if(pwrpriv->bInternalAutoSuspend ) + { + #ifdef CONFIG_AUTOSUSPEND + #ifdef SUPPORT_HW_RFOFF_DETECTED + // The FW command register update must after MAC and FW init ready. + if((padapter->bFWReady) && ( padapter->pwrctrlpriv.bHWPwrPindetect ) && (padapter->registrypriv.usbss_enable )) + { + //rtl8192c_set_FwSelectSuspend_cmd(padapter,_FALSE ,500);//note fw to support hw power down ping detect + u8 bOpen = _FALSE; + rtw_interface_ps_func(padapter,HAL_USB_SELECT_SUSPEND,&bOpen); + } + #endif + #endif + + pwrpriv->bInternalAutoSuspend = _FALSE; + pwrpriv->brfoffbyhw = _FALSE; + } +#endif + _exit_pwrlock(&pwrpriv->lock); + + if( padapter->pid[1]!=0) { + DBG_871X("pid[1]:%d\n",padapter->pid[1]); + rtw_signal_process(padapter->pid[1], SIGUSR2); + } + + #ifdef CONFIG_LAYER2_ROAMING_RESUME + rtw_roaming(padapter, NULL); + #endif + + ret = 0; +exit: + #ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_unlock_suspend(); + #endif //CONFIG_RESUME_IN_WORKQUEUE + + pwrpriv->bInSuspend = _FALSE; + DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ + , ret, rtw_get_passing_time_ms(start_time)); + + _func_exit_; + + return ret; +} + +#ifdef CONFIG_AUTOSUSPEND +void autosuspend_enter(_adapter* padapter) +{ + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + + pwrpriv->bInternalAutoSuspend = _TRUE; + pwrpriv->bips_processing = _TRUE; + + DBG_871X("==>autosuspend_enter...........\n"); + + if(rf_off == pwrpriv->change_rfpwrstate ) + { + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + usb_enable_autosuspend(dvobj->pusbdev); + #else + dvobj->pusbdev->autosuspend_disabled = 0;//autosuspend disabled by the user + #endif + + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,33)) + usb_autopm_put_interface(dvobj->pusbintf); + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,20)) + usb_autopm_enable(dvobj->pusbintf); + #else + usb_autosuspend_device(dvobj->pusbdev, 1); + #endif + } + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,32)) + DBG_871X("...pm_usage_cnt(%d).....\n", atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); + #else + DBG_871X("...pm_usage_cnt(%d).....\n", dvobj->pusbintf->pm_usage_cnt); + #endif + +} +int autoresume_enter(_adapter* padapter) +{ + int result = _SUCCESS; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + + + DBG_871X("====> autoresume_enter \n"); + + if(rf_off == pwrpriv->rf_pwrstate ) + { + pwrpriv->ps_flag = _FALSE; + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,33)) + if (usb_autopm_get_interface(dvobj->pusbintf) < 0) + { + DBG_871X( "can't get autopm: %d\n", result); + result = _FAIL; + goto error_exit; + } + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,20)) + usb_autopm_disable(dvobj->pusbintf); + #else + usb_autoresume_device(dvobj->pusbdev, 1); + #endif + + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,32)) + DBG_871X("...pm_usage_cnt(%d).....\n", atomic_read(&(dvobj->pusbintf->pm_usage_cnt))); + #else + DBG_871X("...pm_usage_cnt(%d).....\n", dvobj->pusbintf->pm_usage_cnt); + #endif + } + DBG_871X("<==== autoresume_enter \n"); +error_exit: + + return result; +} +#endif + +#ifdef CONFIG_PLATFORM_RTD2880B +extern void rtd2885_wlan_netlink_sendMsg(char *action_string, char *name); +#endif + +#ifdef CONFIG_PLATFORM_ARM_SUNxI +#include +extern int sw_usb_disable_hcd(__u32 usbc_no); +extern int sw_usb_enable_hcd(__u32 usbc_no); +static int usb_wifi_host = 2; +#endif + +#ifdef CONFIG_PLATFORM_ARM_SUN6I +#include +extern int sw_usb_disable_hcd(__u32 usbc_no); +extern int sw_usb_enable_hcd(__u32 usbc_no); +extern void wifi_pm_power(int on); +static script_item_u item; +#endif + +_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, + struct usb_interface *pusb_intf, const struct usb_device_id *pdid) +{ + _adapter *padapter = NULL; + struct net_device *pnetdev = NULL; + int status = _FAIL; + + if ((padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter))) == NULL) { + goto exit; + } + padapter->dvobj = dvobj; + dvobj->if1 = padapter; + + padapter->bDriverStopped=_TRUE; + + dvobj->padapters[dvobj->iface_nums++] = padapter; + padapter->iface_id = IFACE_ID0; + +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_DUALMAC_CONCURRENT) + //set adapter_type/iface type for primary padapter + padapter->isprimary = _TRUE; + padapter->adapter_type = PRIMARY_ADAPTER; + #ifndef CONFIG_HWPORT_SWAP + padapter->iface_type = IFACE_PORT0; + #else + padapter->iface_type = IFACE_PORT1; + #endif +#endif + + #ifndef RTW_DVOBJ_CHIP_HW_TYPE + //step 1-1., decide the chip_type via vid/pid + padapter->interface_type = RTW_USB; + decide_chip_type_by_usb_device_id(padapter, pdid); + #endif + + if((pnetdev = rtw_init_netdev(padapter)) == NULL) { + goto free_adapter; + } + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj)); + padapter = rtw_netdev_priv(pnetdev); + + //step 2. hook HalFunc, allocate HalData + if(padapter->chip_type == RTL8188C_8192C) { + #ifdef CONFIG_RTL8192C + rtl8192cu_set_hal_ops(padapter); + #endif + } else if(padapter->chip_type == RTL8192D) { + #ifdef CONFIG_RTL8192D + rtl8192du_set_hal_ops(padapter); + #endif + } else { + DBG_871X("Detect NULL_CHIP_TYPE\n"); + goto free_hal_data; + } + + //step 3. + padapter->intf_start=&usb_intf_start; + padapter->intf_stop=&usb_intf_stop; + + //.2 + if ((rtw_init_io_priv(padapter, usb_set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,(" \n Can't init io_reqs\n")); + goto free_hal_data; + } + + rtw_hal_read_chip_version(padapter); + + //.4 usb endpoint mapping + rtw_hal_chip_configure(padapter); + + //step 4. read efuse/eeprom data and get mac_addr + rtw_hal_read_chip_info(padapter); + + if (rtw_handle_dualmac(padapter, 1) != _SUCCESS) + goto free_hal_data; + +#ifdef CONFIG_IOCTL_CFG80211 + if(rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)) != 0) { + goto handle_dualmac; + } +#endif + + //step 5. + if (rtw_init_drv_sw(padapter) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("Initialize driver software resource Failed!\n")); + goto free_wdev; + } + +#ifdef CONFIG_PM +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) + if(padapter->pwrctrlpriv.bSupportRemoteWakeup) + { + dvobj->pusbdev->do_remote_wakeup=1; + pusb_intf->needs_remote_wakeup = 1; + device_init_wakeup(&pusb_intf->dev, 1); + DBG_871X("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n"); + DBG_871X("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n",device_may_wakeup(&pusb_intf->dev)); + } +#endif +#endif + +#ifdef CONFIG_AUTOSUSPEND + if( padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE ) + { + if(padapter->registrypriv.usbss_enable ){ /* autosuspend (2s delay) */ + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,38)) + dvobj->pusbdev->dev.power.autosuspend_delay = 0 * HZ;//15 * HZ; idle-delay time + #else + dvobj->pusbdev->autosuspend_delay = 0 * HZ;//15 * HZ; idle-delay time + #endif + + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + usb_enable_autosuspend(dvobj->pusbdev); + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + padapter->bDisableAutosuspend = dvobj->pusbdev->autosuspend_disabled ; + dvobj->pusbdev->autosuspend_disabled = 0;//autosuspend disabled by the user + #endif + + usb_autopm_get_interface(dvobj->pusbintf );//init pm_usage_cnt ,let it start from 1 + + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,32)) + DBG_871X("%s...pm_usage_cnt(%d).....\n",__FUNCTION__, atomic_read(&(dvobj->pusbintf ->pm_usage_cnt))); + #else + DBG_871X("%s...pm_usage_cnt(%d).....\n",__FUNCTION__, dvobj->pusbintf ->pm_usage_cnt); + #endif + } + } +#endif + + // set mac addr + rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); + rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr, padapter->eeprompriv.mac_addr); + + DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" + ,padapter->bDriverStopped + ,padapter->bSurpriseRemoved + ,padapter->bup + ,padapter->hw_init_completed + ); + + status = _SUCCESS; + +free_wdev: + if(status != _SUCCESS) { + #ifdef CONFIG_IOCTL_CFG80211 + rtw_wdev_unregister(padapter->rtw_wdev); + rtw_wdev_free(padapter->rtw_wdev); + #endif + } +handle_dualmac: + if (status != _SUCCESS) + rtw_handle_dualmac(padapter, 0); +free_hal_data: + if(status != _SUCCESS && padapter->HalData) + rtw_mfree(padapter->HalData, sizeof(*(padapter->HalData))); +free_adapter: + if (status != _SUCCESS) { + if (pnetdev) + rtw_free_netdev(pnetdev); + else if (padapter) + rtw_vmfree((u8*)padapter, sizeof(*padapter)); + padapter = NULL; + } +exit: + return padapter; +} + +static void rtw_usb_if1_deinit(_adapter *if1) +{ + struct net_device *pnetdev = if1->pnetdev; + struct mlme_priv *pmlmepriv= &if1->mlmepriv; + + if(check_fwstate(pmlmepriv, _FW_LINKED)) + rtw_disassoc_cmd(if1, 0, _FALSE); + +#ifdef CONFIG_AP_MODE + free_mlme_ap_info(if1); + #ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_unload(if1); + #endif +#endif + + rtw_cancel_all_timer(if1); +#ifdef CONFIG_WOWLAN + if1->pwrctrlpriv.wowlan_mode=_FALSE; +#endif //CONFIG_WOWLAN + rtw_dev_unload(if1); + + DBG_871X("%s, hw_init_completed=%d\n", __func__, if1->hw_init_completed); + + //s6. + rtw_handle_dualmac(if1, 0); + +#ifdef CONFIG_IOCTL_CFG80211 + if (if1->rtw_wdev) + rtw_wdev_free(if1->rtw_wdev); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_free_drv_sw(if1); + + if(pnetdev) + rtw_free_netdev(pnetdev); + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link down\n"); + rtd2885_wlan_netlink_sendMsg("linkdown", "8712"); +#endif + +} + +/* + * drv_init() - a device potentially for us + * + * notes: drv_init() is called when the bus driver has located a card for us to support. + * We accept the new device by returning 0. +*/ + +_adapter *rtw_sw_export = NULL; + +static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *did) +{ + int i; + uint status = _FAIL; + _adapter *if1 = NULL, *if2 = NULL; + struct dvobj_priv *dvobj = NULL; + + + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_init\n")); + + + //step 0. + process_spec_devid(did); + + /* Initialize dvobj_priv */ + if ((dvobj = usb_dvobj_init(pusb_intf)) == NULL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n")); + goto exit; + } + + /* Initialize if1 */ + if ((if1 = rtw_usb_if1_init(dvobj, pusb_intf, did)) == NULL) { + DBG_871X("rtw_usb_if1_init Failed!\n"); + goto free_dvobj; + } + + /* Initialize if2 */ +#ifdef CONFIG_CONCURRENT_MODE + if((if2 = rtw_drv_if2_init(if1, usb_set_intf_ops)) == NULL) { + goto free_if1; + } +#ifdef CONFIG_MULTI_VIR_IFACES + for(i=0; iregistrypriv.ext_iface_num;i++) + { + if(rtw_drv_add_vir_if(if1, usb_set_intf_ops) == NULL) + { + DBG_871X("rtw_drv_add_iface failed! (%d)\n", i); + goto free_if1; + } + } +#endif //CONFIG_MULTI_VIR_IFACES +#endif + +#ifdef CONFIG_INTEL_PROXIM + rtw_sw_export=if1; +#endif + +#ifdef CONFIG_GLOBAL_UI_PID + if (ui_pid[1]!=0) { + DBG_871X("ui_pid[1]:%d\n",ui_pid[1]); + rtw_signal_process(ui_pid[1], SIGUSR2); + } +#endif + + //dev_alloc_name && register_netdev + if((status = rtw_drv_register_netdev(if1)) != _SUCCESS) { + goto free_if1; + } + +#ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_init(if1); +#endif + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link up\n"); + rtd2885_wlan_netlink_sendMsg("linkup", "8712"); +#endif + +#ifdef RTK_DMP_PLATFORM + rtw_proc_init_one(if1->pnetdev); +#endif + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n")); + + status = _SUCCESS; + +free_if1: + if (status != _SUCCESS && if1) { + rtw_usb_if1_deinit(if1); + } +free_dvobj: + if (status != _SUCCESS) + usb_dvobj_deinit(pusb_intf); +exit: + return status == _SUCCESS?0:-ENODEV; +} + +/* + * dev_remove() - our device is being removed +*/ +//rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() => how to recognize both +static void rtw_dev_remove(struct usb_interface *pusb_intf) +{ + struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf); + _adapter *padapter = dvobj->if1; + +_func_exit_; + + DBG_871X("+rtw_dev_remove\n"); + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+dev_remove()\n")); + + dvobj->processing_dev_remove = _TRUE; + + rtw_unregister_netdevs(dvobj); + + if(usb_drv->drv_registered == _TRUE) + { + //DBG_871X("r871xu_dev_remove():padapter->bSurpriseRemoved == _TRUE\n"); + padapter->bSurpriseRemoved = _TRUE; + } + /*else + { + //DBG_871X("r871xu_dev_remove():module removed\n"); + padapter->hw_init_completed = _FALSE; + }*/ + +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + rtw_unregister_early_suspend(&padapter->pwrctrlpriv); +#endif + + rtw_pm_set_ips(padapter, IPS_NONE); + rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); + + LeaveAllPowerSaveMode(padapter); + +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_MULTI_VIR_IFACES + rtw_drv_stop_vir_ifaces(dvobj); +#endif //CONFIG_MULTI_VIR_IFACES + rtw_drv_if2_stop(dvobj->if2); +#endif //CONFIG_CONCURRENT_MODE + + rtw_usb_if1_deinit(padapter); + +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_MULTI_VIR_IFACES + rtw_drv_free_vir_ifaces(dvobj); +#endif //CONFIG_MULTI_VIR_IFACES + rtw_drv_if2_free(dvobj->if2); +#endif //CONFIG_CONCURRENT_MODE + + usb_dvobj_deinit(pusb_intf); + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-dev_remove()\n")); + DBG_871X("-r871xu_dev_remove, done\n"); + + +#ifdef CONFIG_INTEL_PROXIM + rtw_sw_export=NULL; +#endif + +_func_exit_; + + return; + +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) +extern int console_suspend_enabled; +#endif + +static int __init rtw_drv_entry(void) +{ +#ifdef CONFIG_PLATFORM_RTK_DMP + u32 tmp; + tmp=readl((volatile unsigned int*)0xb801a608); + tmp &= 0xffffff00; + tmp |= 0x55; + writel(tmp,(volatile unsigned int*)0xb801a608);//write dummy register for 1055 +#endif +#ifdef CONFIG_PLATFORM_ARM_SUNxI +#ifndef CONFIG_RTL8723A + int ret = 0; + /* ----------get usb_wifi_usbc_num------------- */ + ret = script_parser_fetch("usb_wifi_para", "usb_wifi_usbc_num", (int *)&usb_wifi_host, 64); + if(ret != 0){ + printk("ERR: script_parser_fetch usb_wifi_usbc_num failed\n"); + ret = -ENOMEM; + return ret; + } + printk("sw_usb_enable_hcd: usbc_num = %d\n", usb_wifi_host); + sw_usb_enable_hcd(usb_wifi_host); +#endif //CONFIG_RTL8723A +#endif //CONFIG_PLATFORM_ARM_SUNxI + +#ifdef CONFIG_PLATFORM_ARM_SUN6I + script_item_value_type_e type; + + type = script_get_item("wifi_para", "wifi_usbc_id", &item); + if(SCIRPT_ITEM_VALUE_TYPE_INT != type){ + printk("ERR: script_get_item wifi_usbc_id failed\n"); + return -ENOMEM; + } + + printk("sw_usb_enable_hcd: usbc_num = %d\n", item.val); + wifi_pm_power(1); + mdelay(10); + sw_usb_enable_hcd(item.val); +#endif //CONFIG_PLATFORM_ARM_SUN6I + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_drv_entry\n")); + + DBG_871X(DRV_NAME " driver version=%s\n", DRIVERVERSION); + DBG_871X("build time: %s %s\n", __DATE__, __TIME__); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + //console_suspend_enabled=0; +#endif + + rtw_suspend_lock_init(); + + usb_drv->drv_registered = _TRUE; + return usb_register(&usb_drv->usbdrv); +} + +static void __exit rtw_drv_halt(void) +{ + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("+rtw_drv_halt\n")); + DBG_871X("+rtw_drv_halt\n"); + + usb_drv->drv_registered = _FALSE; + usb_deregister(&usb_drv->usbdrv); + +#ifdef CONFIG_PLATFORM_ARM_SUNxI +#ifndef CONFIG_RTL8723A + printk("sw_usb_disable_hcd: usbc_num = %d\n", usb_wifi_host); + sw_usb_disable_hcd(usb_wifi_host); +#endif //ifndef CONFIG_RTL8723A +#endif //CONFIG_PLATFORM_ARM_SUNxI +#ifdef CONFIG_PLATFORM_ARM_SUN6I + sw_usb_disable_hcd(item.val); + wifi_pm_power(0); +#endif + + rtw_suspend_lock_uninit(); + DBG_871X("-rtw_drv_halt\n"); + + rtw_mstat_dump(); +} + + +module_init(rtw_drv_entry); +module_exit(rtw_drv_halt); + +#ifdef CONFIG_WOWLAN +#ifdef CONFIG_WOWLAN_MANUAL + +int rtw_resume_toshiba(PADAPTER Adapter) +{ + struct dvobj_priv *pdvobjpriv; + pdvobjpriv = adapter_to_dvobj(Adapter); + + rtw_resume(pdvobjpriv->pusbintf); + return 0; +} + +int rtw_suspend_toshiba(PADAPTER Adapter) +{ + pm_message_t msg; + struct dvobj_priv *pdvobjpriv; + pdvobjpriv = adapter_to_dvobj(Adapter); + msg.event=0; + //for Toshiba only, they should call rtw_suspend before suspend + rtw_suspend(pdvobjpriv->pusbintf, msg); + return 0; +} +EXPORT_SYMBOL(rtw_suspend_toshiba); +EXPORT_SYMBOL(rtw_resume_toshiba); +#endif //CONFIG_WOWLAN_MANUAL +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_INTEL_PROXIM +_adapter *rtw_usb_get_sw_pointer(void) +{ + return rtw_sw_export; +} +EXPORT_SYMBOL(rtw_usb_get_sw_pointer); +#endif //CONFIG_INTEL_PROXIM + diff --git a/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c b/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c new file mode 100755 index 00000000..906cc1ab --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c @@ -0,0 +1,649 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + *******************************************************************************/ +#define _USB_OPS_LINUX_C_ + +#include +#include +#include + +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ +static void _usbctrl_vendorreq_async_callback(struct urb *urb, struct pt_regs *regs) +{ + if (urb) { + if (urb->context) { + rtw_mfree(urb->context); + } + usb_free_urb(urb); + } +} + +static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, + u16 value, u16 index, void *pdata, u16 len, u8 requesttype) +{ + int rc; + unsigned int pipe; + 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; + + + if (requesttype == VENDOR_READ) { + pipe = usb_rcvctrlpipe(udev, 0);//read_in + reqtype = REALTEK_USB_VENQT_READ; + } + else { + pipe = usb_sndctrlpipe(udev, 0);//write_out + reqtype = REALTEK_USB_VENQT_WRITE; + } + + buf = (struct rtl819x_async_write_data *)rtw_zmalloc(sizeof(*buf)); + if (!buf) { + rc = -ENOMEM; + goto exit; + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + rtw_mfree((u8*)buf, sizeof(*buf)); + rc = -ENOMEM; + goto exit; + } + + dr = &buf->dr; + + dr->bRequestType = reqtype; + dr->bRequest = request; + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(len); + + _rtw_memcpy(buf, pdata, len); + + usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, buf, len, + _usbctrl_vendorreq_async_callback, buf); + + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) { + rtw_mfree((u8*)buf, sizeof(*buf)); + usb_free_urb(urb); + } + +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) +{ + unsigned int pipe=0; + int ep_num=0; + _adapter *padapter = pdvobj->if1; + struct usb_device *pusbd = pdvobj->pusbdev; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (addr == RECV_BULK_IN_ADDR) { + pipe=usb_rcvbulkpipe(pusbd, pHalData->RtBulkInPipe); + + } else if (addr == RECV_INT_IN_ADDR) { + pipe=usb_rcvbulkpipe(pusbd, pHalData->RtIntInPipe); + + } else if (addr < HW_QUEUE_ENTRY) { + ep_num = pHalData->Queue2EPNum[addr]; + pipe = usb_sndbulkpipe(pusbd, ep_num); + } + + return pipe; +} + +struct zero_bulkout_context{ + void *pbuf; + void *purb; + void *pirp; + void *padapter; +}; + +static void usb_bulkout_zero_complete(struct urb *purb, struct pt_regs *regs) +{ + struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)purb->context; + + //DBG_8192C("+usb_bulkout_zero_complete\n"); + + if(pcontext) + { + if(pcontext->pbuf) + { + rtw_mfree(pcontext->pbuf, sizeof(int)); + } + + if(pcontext->purb && (pcontext->purb==purb)) + { + usb_free_urb(pcontext->purb); + } + + + rtw_mfree((u8*)pcontext, sizeof(struct zero_bulkout_context)); + } + + +} + +static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr) +{ + int pipe, status, len; + u32 ret; + unsigned char *pbuf; + struct zero_bulkout_context *pcontext; + PURB purb = NULL; + _adapter *padapter = (_adapter *)pintfhdl->padapter; + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobj->pusbdev; + + //DBG_871X("%s\n", __func__); + + + if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) + { + return _FAIL; + } + + + pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context)); + + pbuf = (unsigned char *)rtw_zmalloc(sizeof(int)); + purb = usb_alloc_urb(0, GFP_ATOMIC); + + len = 0; + pcontext->pbuf = pbuf; + pcontext->purb = purb; + pcontext->pirp = NULL; + pcontext->padapter = padapter; + + + //translate DMA FIFO addr to pipehandle + //pipe = ffaddr2pipehdl(pdvobj, addr); + + usb_fill_bulk_urb(purb, pusbd, pipe, + pbuf, + len, + usb_bulkout_zero_complete, + pcontext);//context is pcontext + + status = usb_submit_urb(purb, GFP_ATOMIC); + + if (!status) + { + ret= _SUCCESS; + } + else + { + ret= _FAIL; + } + + + return _SUCCESS; + +} + +void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + +} + +void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + +} + + +void usb_read_port_cancel(struct intf_hdl *pintfhdl) +{ + int i; + struct recv_buf *precvbuf; + _adapter *padapter = pintfhdl->padapter; + precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; + + DBG_871X("%s\n", __func__); + + padapter->bReadPortCancel = _TRUE; + + for (i=0; i < NR_RECVBUFF ; i++) { + + precvbuf->reuse = _TRUE; + if (precvbuf->purb) { + //DBG_8192C("usb_read_port_cancel : usb_kill_urb \n"); + usb_kill_urb(precvbuf->purb); + } + precvbuf++; + } + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE + usb_kill_urb(padapter->recvpriv.int_in_urb); +#endif +} + +static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs) +{ + _irqL irqL; + int i; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context; + //struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; + //_adapter *padapter = pxmitframe->padapter; + _adapter *padapter = pxmitbuf->padapter; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + //struct pkt_attrib *pattrib = &pxmitframe->attrib; + +_func_enter_; + + switch(pxmitbuf->flags) + { + case VO_QUEUE_INX: + pxmitpriv->voq_cnt--; + break; + case VI_QUEUE_INX: + pxmitpriv->viq_cnt--; + break; + case BE_QUEUE_INX: + pxmitpriv->beq_cnt--; + break; + case BK_QUEUE_INX: + pxmitpriv->bkq_cnt--; + break; + case HIGH_QUEUE_INX: +#ifdef CONFIG_AP_MODE + rtw_chk_hi_queue_cmd(padapter); +#endif + break; + default: + break; + } + + +/* + _enter_critical(&pxmitpriv->lock, &irqL); + + pxmitpriv->txirp_cnt--; + + switch(pattrib->priority) + { + case 1: + case 2: + pxmitpriv->bkq_cnt--; + //DBG_8192C("pxmitpriv->bkq_cnt=%d\n", pxmitpriv->bkq_cnt); + break; + case 4: + case 5: + pxmitpriv->viq_cnt--; + //DBG_8192C("pxmitpriv->viq_cnt=%d\n", pxmitpriv->viq_cnt); + break; + case 6: + case 7: + pxmitpriv->voq_cnt--; + //DBG_8192C("pxmitpriv->voq_cnt=%d\n", pxmitpriv->voq_cnt); + break; + case 0: + case 3: + default: + pxmitpriv->beq_cnt--; + //DBG_8192C("pxmitpriv->beq_cnt=%d\n", pxmitpriv->beq_cnt); + break; + + } + + _exit_critical(&pxmitpriv->lock, &irqL); + + + if(pxmitpriv->txirp_cnt==0) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n")); + _rtw_up_sema(&(pxmitpriv->tx_retevt)); + } +*/ + //rtw_free_xmitframe(pxmitpriv, pxmitframe); + + if(padapter->bSurpriseRemoved || padapter->bDriverStopped ||padapter->bWritePortCancel) + { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); + DBG_8192C("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x) \n", + __FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel,pxmitbuf->ext_tag); + + goto check_completion; + } + + + if (purb->status==0) { + + } else { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete : purb->status(%d) != 0 \n", purb->status)); + DBG_871X("###=> urb_write_port_complete status(%d)\n",purb->status); + if((purb->status==-EPIPE)||(purb->status==-EPROTO)) + { + //usb_clear_halt(pusbdev, purb->pipe); + //msleep(10); + sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL); + } else if (purb->status == -EINPROGRESS) { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: EINPROGESS\n")); + goto check_completion; + + } else if (purb->status == -ENOENT) { + DBG_871X("%s: -ENOENT\n", __func__); + goto check_completion; + + } else if (purb->status == -ECONNRESET) { + DBG_871X("%s: -ECONNRESET\n", __func__); + goto check_completion; + + } else if (purb->status == -ESHUTDOWN) { + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: ESHUTDOWN\n")); + padapter->bDriverStopped=_TRUE; + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped=TRUE\n")); + + goto check_completion; + } + else + { + padapter->bSurpriseRemoved=_TRUE; + DBG_8192C("bSurpriseRemoved=TRUE\n"); + //rtl8192cu_trigger_gpio_0(padapter); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bSurpriseRemoved=TRUE\n")); + + goto check_completion; + } + } + + #ifdef DBG_CONFIG_ERROR_DETECT + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.last_tx_complete_time = rtw_get_current_time(); + } + #endif + +check_completion: + _enter_critical(&pxmitpriv->lock_sctx, &irqL); + rtw_sctx_done_err(&pxmitbuf->sctx, + purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS); + _exit_critical(&pxmitpriv->lock_sctx, &irqL); + + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + + //if(rtw_txframes_pending(padapter)) + { + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); + } + +_func_exit_; + +} + +u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ + _irqL irqL; + unsigned int pipe; + int status; + u32 ret = _FAIL, bwritezero = _FALSE; + PURB purb = NULL; + _adapter *padapter = (_adapter *)pintfhdl->padapter; + struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem; + struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; + struct usb_device *pusbd = pdvobj->pusbdev; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + +_func_enter_; + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n")); + + if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)) { + #ifdef DBG_TX + DBG_871X(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d, pnp_bstop_trx:%d\n",__FUNCTION__, __LINE__ + ,padapter->bDriverStopped, padapter->bSurpriseRemoved, padapter->pwrctrlpriv.pnp_bstop_trx ); + #endif + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY); + goto exit; + } + + _enter_critical(&pxmitpriv->lock, &irqL); + + switch(addr) + { + case VO_QUEUE_INX: + pxmitpriv->voq_cnt++; + pxmitbuf->flags = VO_QUEUE_INX; + break; + case VI_QUEUE_INX: + pxmitpriv->viq_cnt++; + pxmitbuf->flags = VI_QUEUE_INX; + break; + case BE_QUEUE_INX: + pxmitpriv->beq_cnt++; + pxmitbuf->flags = BE_QUEUE_INX; + break; + case BK_QUEUE_INX: + pxmitpriv->bkq_cnt++; + pxmitbuf->flags = BK_QUEUE_INX; + break; + case HIGH_QUEUE_INX: + pxmitbuf->flags = HIGH_QUEUE_INX; + break; + default: + pxmitbuf->flags = MGT_QUEUE_INX; + break; + } + + _exit_critical(&pxmitpriv->lock, &irqL); + + purb = pxmitbuf->pxmit_urb[0]; + +#if 0 + if(pdvobj->ishighspeed) + { + if(cnt> 0 && cnt%512 == 0) + { + //DBG_8192C("ishighspeed, cnt=%d\n", cnt); + bwritezero = _TRUE; + } + } + else + { + if(cnt > 0 && cnt%64 == 0) + { + //DBG_8192C("cnt=%d\n", cnt); + bwritezero = _TRUE; + } + } +#endif + + //translate DMA FIFO addr to pipehandle + pipe = ffaddr2pipehdl(pdvobj, addr); + +#ifdef CONFIG_REDUCE_USB_TX_INT + if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0) + || (pxmitbuf->ext_tag == _TRUE) ) + { + purb->transfer_flags &= (~URB_NO_INTERRUPT); + } else { + purb->transfer_flags |= URB_NO_INTERRUPT; + //DBG_8192C("URB_NO_INTERRUPT "); + } +#endif + + + usb_fill_bulk_urb(purb, pusbd, pipe, + pxmitframe->buf_addr, //= pxmitbuf->pbuf + cnt, + usb_write_port_complete, + pxmitbuf);//context is pxmitbuf + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + purb->transfer_dma = pxmitbuf->dma_transfer_addr; + purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + purb->transfer_flags |= URB_ZERO_PACKET; +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + +#if 0 + if (bwritezero) + { + purb->transfer_flags |= URB_ZERO_PACKET; + } +#endif + + status = usb_submit_urb(purb, GFP_ATOMIC); + if (!status) { + #ifdef DBG_CONFIG_ERROR_DETECT + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.last_tx_time = rtw_get_current_time(); + } + #endif + } else { + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); + DBG_871X("usb_write_port, status=%d\n", status); + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status)); + + switch (status) { + case -ENODEV: + padapter->bDriverStopped=_TRUE; + break; + default: + break; + } + goto exit; + } + + ret= _SUCCESS; + +// Commented by Albert 2009/10/13 +// We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. +/* + if(bwritezero == _TRUE) + { + usb_bulkout_zero(pintfhdl, addr); + } +*/ + + RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n")); + +exit: + if (ret != _SUCCESS) + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); +_func_exit_; + return ret; + +} + +void usb_write_port_cancel(struct intf_hdl *pintfhdl) +{ + int i, j; + _adapter *padapter = pintfhdl->padapter; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf; + + DBG_871X("%s \n", __func__); + + padapter->bWritePortCancel = _TRUE; + + for (i=0; ipxmit_urb[j]) { + usb_kill_urb(pxmitbuf->pxmit_urb[j]); + } + } + pxmitbuf++; + } + + pxmitbuf = (struct xmit_buf*)padapter->xmitpriv.pxmit_extbuf; + for (i = 0; i < NR_XMIT_EXTBUFF; i++) { + for (j=0; j<8; j++) { + if(pxmitbuf->pxmit_urb[j]) { + usb_kill_urb(pxmitbuf->pxmit_urb[j]); + } + } + pxmitbuf++; + } +} + diff --git a/rtl8192cu-fixes/os_dep/linux/xmit_linux.c b/rtl8192cu-fixes/os_dep/linux/xmit_linux.c new file mode 100755 index 00000000..9105e293 --- /dev/null +++ b/rtl8192cu-fixes/os_dep/linux/xmit_linux.c @@ -0,0 +1,421 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _XMIT_OSDEP_C_ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +uint rtw_remainder_len(struct pkt_file *pfile) +{ + return (pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start))); +} + +void _rtw_open_pktfile (_pkt *pktptr, struct pkt_file *pfile) +{ +_func_enter_; + + pfile->pkt = pktptr; + pfile->cur_addr = pfile->buf_start = pktptr->data; + pfile->pkt_len = pfile->buf_len = pktptr->len; + + pfile->cur_buffer = pfile->buf_start ; + +_func_exit_; +} + +uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) +{ + uint len = 0; + +_func_enter_; + + len = rtw_remainder_len(pfile); + len = (rlen > len)? len: rlen; + + if(rmem) + skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len); + + pfile->cur_addr += len; + pfile->pkt_len -= len; + +_func_exit_; + + return len; +} + +sint rtw_endofpktfile(struct pkt_file *pfile) +{ +_func_enter_; + + if (pfile->pkt_len == 0) { +_func_exit_; + return _TRUE; + } + +_func_exit_; + + return _FALSE; +} + +void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib) +{ + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + struct sk_buff *skb = (struct sk_buff *)pkt; + pattrib->hw_tcp_csum = 0; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (skb_shinfo(skb)->nr_frags == 0) + { + const struct iphdr *ip = ip_hdr(skb); + if (ip->protocol == IPPROTO_TCP) { + // TCP checksum offload by HW + DBG_871X("CHECKSUM_PARTIAL TCP\n"); + pattrib->hw_tcp_csum = 1; + //skb_checksum_help(skb); + } else if (ip->protocol == IPPROTO_UDP) { + //DBG_871X("CHECKSUM_PARTIAL UDP\n"); +#if 1 + skb_checksum_help(skb); +#else + // Set UDP checksum = 0 to skip checksum check + struct udphdr *udp = skb_transport_header(skb); + udp->check = 0; +#endif + } else { + DBG_871X("%s-%d TCP CSUM offload Error!!\n", __FUNCTION__, __LINE__); + WARN_ON(1); /* we need a WARN() */ + } + } + else { // IP fragmentation case + DBG_871X("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __FUNCTION__, __LINE__); + skb_checksum_help(skb); + } + } +#endif + +} + +int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz) +{ +#ifdef CONFIG_USB_HCI + int i; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + pxmitbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)alloc_sz, &pxmitbuf->dma_transfer_addr); + pxmitbuf->pbuf = pxmitbuf->pallocated_buf; + if(pxmitbuf->pallocated_buf == NULL) + return _FAIL; +#else // CONFIG_USE_USB_BUFFER_ALLOC_TX + + pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); + if (pxmitbuf->pallocated_buf == NULL) + { + return _FAIL; + } + + pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); + pxmitbuf->dma_transfer_addr = 0; + +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + + for(i=0; i<8; i++) + { + pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); + if(pxmitbuf->pxmit_urb[i] == NULL) + { + DBG_871X("pxmitbuf->pxmit_urb[i]==NULL"); + return _FAIL; + } + + } +#endif +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) + pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); + if (pxmitbuf->pallocated_buf == NULL) + { + return _FAIL; + } + + pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); +#endif + + return _SUCCESS; +} + +void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz) +{ +#ifdef CONFIG_USB_HCI + int i; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + + for(i=0; i<8; i++) + { + if(pxmitbuf->pxmit_urb[i]) + { + //usb_kill_urb(pxmitbuf->pxmit_urb[i]); + usb_free_urb(pxmitbuf->pxmit_urb[i]); + } + } + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + rtw_usb_buffer_free(pusbd, (size_t)free_sz, pxmitbuf->pallocated_buf, pxmitbuf->dma_transfer_addr); + pxmitbuf->pallocated_buf = NULL; + pxmitbuf->dma_transfer_addr = 0; +#else // CONFIG_USE_USB_BUFFER_ALLOC_TX + if(pxmitbuf->pallocated_buf) + rtw_mfree(pxmitbuf->pallocated_buf, free_sz); +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + +#endif +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) + if(pxmitbuf->pallocated_buf) + rtw_mfree(pxmitbuf->pallocated_buf, free_sz); +#endif +} + +void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + u16 queue; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + queue = skb_get_queue_mapping(pkt); + if(__netif_subqueue_stopped(padapter->pnetdev, queue) && + (pxmitpriv->hwxmits[queue].accnt < NR_XMITFRAME/2)) + { + netif_wake_subqueue(padapter->pnetdev, queue); + } +#else + if (netif_queue_stopped(padapter->pnetdev)) + netif_wake_queue(padapter->pnetdev); +#endif + + rtw_skb_free(pkt); +} + +void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe) +{ + if(pxframe->pkt) + rtw_os_pkt_complete(padapter, pxframe->pkt); + + pxframe->pkt = NULL; +} + +void rtw_os_xmit_schedule(_adapter *padapter) +{ +#ifdef CONFIG_SDIO_HCI + if(!padapter) + return; + + if (rtw_txframes_pending(padapter)) + _rtw_up_sema(&padapter->xmitpriv.xmit_sema); +#else + _irqL irqL; + struct xmit_priv *pxmitpriv; + + if(!padapter) + return; + + pxmitpriv = &padapter->xmitpriv; + + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + if(rtw_txframes_pending(padapter)) + { + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); + } + + _exit_critical_bh(&pxmitpriv->lock, &irqL); +#endif +} + + + +#ifdef CONFIG_TX_MCAST2UNI +int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + _list *phead, *plist; + struct sk_buff *newskb; + struct sta_info *psta = NULL; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + u8 bc_addr[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 null_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + int i; + s32 res; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //free sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + + /* avoid come from STA1 and send back STA1 */ + if (_rtw_memcmp(psta->hwaddr, &skb->data[6], 6) == _TRUE + || _rtw_memcmp(psta->hwaddr, null_addr, 6) == _TRUE + || _rtw_memcmp(psta->hwaddr, bc_addr, 6) == _TRUE + ) + continue; + + newskb = rtw_skb_copy(skb); + + if (newskb) { + _rtw_memcpy(newskb->data, psta->hwaddr, 6); + res = rtw_xmit(padapter, &newskb); + if (res < 0) { + DBG_871X("%s()-%d: rtw_xmit() return error!\n", __FUNCTION__, __LINE__); + pxmitpriv->tx_drop++; + rtw_skb_free(newskb); + } else + pxmitpriv->tx_pkts++; + } else { + DBG_871X("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__); + pxmitpriv->tx_drop++; + //rtw_skb_free(skb); + return _FALSE; // Caller shall tx this multicast frame via normal way. + } + } + + rtw_skb_free(skb); + return _TRUE; +} +#endif // CONFIG_TX_MCAST2UNI + + +int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; +#ifdef CONFIG_TX_MCAST2UNI + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + extern int rtw_mc2u_disable; +#endif // CONFIG_TX_MCAST2UNI + s32 res = 0; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + u16 queue; +#endif + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n")); + + if (rtw_if_up(padapter) == _FALSE) { + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n")); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__); + #endif + goto drop_packet; + } + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + queue = skb_get_queue_mapping(pkt); + /* No free space for Tx, tx_worker is too slow */ + if (pxmitpriv->hwxmits[queue].accnt > NR_XMITFRAME/2) { + //DBG_871X("%s(): stop netif_subqueue[%d]\n", __FUNCTION__, queue); + netif_stop_subqueue(padapter->pnetdev, queue); + return NETDEV_TX_BUSY; + } +#endif + +#ifdef CONFIG_TX_MCAST2UNI + if ( !rtw_mc2u_disable + && check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE + && ( IP_MCAST_MAC(pkt->data) + || ICMPV6_MCAST_MAC(pkt->data) ) + && (padapter->registrypriv.wifi_spec == 0) + ) + { + if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) { + res = rtw_mlcst2unicst(padapter, pkt); + if (res == _TRUE) { + goto exit; + } + } else { + //DBG_871X("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); + //DBG_871X("!m2u ); + } + } +#endif // CONFIG_TX_MCAST2UNI + + res = rtw_xmit(padapter, &pkt); + if (res < 0) { + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); + #endif + goto drop_packet; + } + + pxmitpriv->tx_pkts++; + RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts)); + goto exit; + +drop_packet: + pxmitpriv->tx_drop++; + rtw_skb_free(pkt); + RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop)); + +exit: + +_func_exit_; + + return 0; +} + +int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) +{ + if (pkt) + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize); + return _rtw_xmit_entry(pkt, pnetdev); +} + diff --git a/rtl8192cu-fixes/os_dep/osdep_service.c b/rtl8192cu-fixes/os_dep/osdep_service.c new file mode 100755 index 00000000..e73a068e --- /dev/null +++ b/rtl8192cu-fixes/os_dep/osdep_service.c @@ -0,0 +1,2300 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + + +#define _OSDEP_SERVICE_C_ + +#include +#include +#include +#include +#ifdef PLATFORM_LINUX +#include +#endif +#ifdef PLATFORM_FREEBSD +#include +#include +#endif /* PLATFORM_FREEBSD */ +#ifdef RTK_DMP_PLATFORM +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) +#include +#endif +#endif + +#define RT_TAG '1178' + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX +#include +atomic_t _malloc_cnt = ATOMIC_INIT(0); +atomic_t _malloc_size = ATOMIC_INIT(0); +#endif +#endif /* DBG_MEMORY_LEAK */ + + +#if defined(PLATFORM_LINUX) +/* +* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE +* @return: one of RTW_STATUS_CODE +*/ +inline int RTW_STATUS_CODE(int error_code){ + if(error_code >=0) + return _SUCCESS; + + switch(error_code) { + //case -ETIMEDOUT: + // return RTW_STATUS_TIMEDOUT; + default: + return _FAIL; + } +} +#else +inline int RTW_STATUS_CODE(int error_code){ + return error_code; +} +#endif + +u32 rtw_atoi(u8* s) +{ + + int num=0,flag=0; + int i; + for(i=0;i<=strlen(s);i++) + { + if(s[i] >= '0' && s[i] <= '9') + num = num * 10 + s[i] -'0'; + else if(s[0] == '-' && i==0) + flag =1; + else + break; + } + + if(flag == 1) + num = num * -1; + + return(num); + +} + +inline u8* _rtw_vmalloc(u32 sz) +{ + u8 *pbuf; +#ifdef PLATFORM_LINUX + pbuf = vmalloc(sz); +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_NOWAIT); +#endif + +#ifdef PLATFORM_WINDOWS + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + if ( pbuf != NULL) { + atomic_inc(&_malloc_cnt); + atomic_add(sz, &_malloc_size); + } +#endif +#endif /* DBG_MEMORY_LEAK */ + + return pbuf; +} + +inline u8* _rtw_zvmalloc(u32 sz) +{ + u8 *pbuf; +#ifdef PLATFORM_LINUX + pbuf = _rtw_vmalloc(sz); + if (pbuf != NULL) + memset(pbuf, 0, sz); +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT); +#endif +#ifdef PLATFORM_WINDOWS + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); + if (pbuf != NULL) + NdisFillMemory(pbuf, sz, 0); +#endif + + return pbuf; +} + +inline void _rtw_vmfree(u8 *pbuf, u32 sz) +{ +#ifdef PLATFORM_LINUX + vfree(pbuf); +#endif +#ifdef PLATFORM_FREEBSD + free(pbuf,M_DEVBUF); +#endif +#ifdef PLATFORM_WINDOWS + NdisFreeMemory(pbuf,sz, 0); +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + atomic_dec(&_malloc_cnt); + atomic_sub(sz, &_malloc_size); +#endif +#endif /* DBG_MEMORY_LEAK */ +} + +u8* _rtw_malloc(u32 sz) +{ + + u8 *pbuf=NULL; + +#ifdef PLATFORM_LINUX +#ifdef RTK_DMP_PLATFORM + if(sz > 0x4000) + pbuf = (u8 *)dvr_malloc(sz); + else +#endif + pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_NOWAIT); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); + +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + if ( pbuf != NULL) { + atomic_inc(&_malloc_cnt); + atomic_add(sz, &_malloc_size); + } +#endif +#endif /* DBG_MEMORY_LEAK */ + + return pbuf; + +} + + +u8* _rtw_zmalloc(u32 sz) +{ +#ifdef PLATFORM_FREEBSD + return malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT); +#else // PLATFORM_FREEBSD + u8 *pbuf = _rtw_malloc(sz); + + if (pbuf != NULL) { + +#ifdef PLATFORM_LINUX + memset(pbuf, 0, sz); +#endif + +#ifdef PLATFORM_WINDOWS + NdisFillMemory(pbuf, sz, 0); +#endif + + } + + return pbuf; +#endif // PLATFORM_FREEBSD +} + +void _rtw_mfree(u8 *pbuf, u32 sz) +{ + +#ifdef PLATFORM_LINUX +#ifdef RTK_DMP_PLATFORM + if(sz > 0x4000) + dvr_free(pbuf); + else +#endif + kfree(pbuf); + +#endif +#ifdef PLATFORM_FREEBSD + free(pbuf,M_DEVBUF); +#endif +#ifdef PLATFORM_WINDOWS + + NdisFreeMemory(pbuf,sz, 0); + +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + atomic_dec(&_malloc_cnt); + atomic_sub(sz, &_malloc_size); +#endif +#endif /* DBG_MEMORY_LEAK */ + +} + +#ifdef PLATFORM_FREEBSD +//review again +struct sk_buff * dev_alloc_skb(unsigned int size) +{ + struct sk_buff *skb=NULL; + u8 *data=NULL; + + //skb = (struct sk_buff *)_rtw_zmalloc(sizeof(struct sk_buff)); // for skb->len, etc. + skb = (struct sk_buff *)_rtw_malloc(sizeof(struct sk_buff)); + if(!skb) + goto out; + data = _rtw_malloc(size); + if(!data) + goto nodata; + + skb->head = (unsigned char*)data; + skb->data = (unsigned char*)data; + skb->tail = (unsigned char*)data; + skb->end = (unsigned char*)data + size; + skb->len = 0; + //printf("%s()-%d: skb=%p, skb->head = %p\n", __FUNCTION__, __LINE__, skb, skb->head); + +out: + return skb; +nodata: + _rtw_mfree((u8 *)skb, sizeof(struct sk_buff)); + skb = NULL; +goto out; + +} + +void dev_kfree_skb_any(struct sk_buff *skb) +{ + //printf("%s()-%d: skb->head = %p\n", __FUNCTION__, __LINE__, skb->head); + if(skb->head) + _rtw_mfree(skb->head, 0); + //printf("%s()-%d: skb = %p\n", __FUNCTION__, __LINE__, skb); + if(skb) + _rtw_mfree((u8 *)skb, 0); +} +struct sk_buff *skb_clone(const struct sk_buff *skb) +{ + return NULL; +} + +#endif /* PLATFORM_FREEBSD */ + +inline struct sk_buff *_rtw_skb_alloc(u32 sz) +{ +#ifdef PLATFORM_LINUX + return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return dev_alloc_skb(sz); +#endif /* PLATFORM_FREEBSD */ +} + +inline void _rtw_skb_free(struct sk_buff *skb) +{ + dev_kfree_skb_any(skb); +} + +inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return NULL; +#endif /* PLATFORM_FREEBSD */ +} + +inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return skb_clone(skb); +#endif /* PLATFORM_FREEBSD */ +} + +inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + skb->dev = ndev; + return netif_rx(skb); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return (*ndev->if_input)(ndev, skb); +#endif /* PLATFORM_FREEBSD */ +} + +void _rtw_skb_queue_purge(struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(list)) != NULL) + _rtw_skb_free(skb); +} + +#ifdef CONFIG_USB_HCI +inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma) +{ +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + return usb_alloc_coherent(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); +#else + return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); +#endif +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return (malloc(size, M_USBDEV, M_NOWAIT | M_ZERO)); +#endif /* PLATFORM_FREEBSD */ +} +inline void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma) +{ +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + usb_free_coherent(dev, size, addr, dma); +#else + usb_buffer_free(dev, size, addr, dma); +#endif +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + free(addr, M_USBDEV); +#endif /* PLATFORM_FREEBSD */ +} +#endif /* CONFIG_USB_HCI */ + +#ifdef DBG_MEM_ALLOC + +struct rtw_mem_stat { + ATOMIC_T alloc; // the memory bytes we allocate currently + ATOMIC_T peak; // the peak memory bytes we allocate + ATOMIC_T alloc_cnt; // the alloc count for alloc currently + ATOMIC_T alloc_err_cnt; // the error times we fail to allocate memory +}; + +struct rtw_mem_stat rtw_mem_type_stat[mstat_tf_idx(MSTAT_TYPE_MAX)]; +struct rtw_mem_stat rtw_mem_func_stat[mstat_ff_idx(MSTAT_FUNC_MAX)]; + +char *MSTAT_TYPE_str[] = { + "VIR", + "PHY", + "SKB", + "USB", +}; + +char *MSTAT_FUNC_str[] = { + "UNSP", + "IO", + "TXIO", + "RXIO", + "TX", + "RX", +}; + +int _rtw_mstat_dump(char *buf, int len) +{ + int cnt = 0; + int i; + int value_t[4][mstat_tf_idx(MSTAT_TYPE_MAX)]; + int value_f[4][mstat_ff_idx(MSTAT_FUNC_MAX)]; + + int vir_alloc, vir_peak, vir_alloc_err, phy_alloc, phy_peak, phy_alloc_err; + int tx_alloc, tx_peak, tx_alloc_err, rx_alloc, rx_peak, rx_alloc_err; + + for(i=0;i 5000) { + // rtw_mstat_dump(); + update_time=rtw_get_current_time(); + //} +} + + + +inline u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + //DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_vmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + //DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_zvmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline void dbg_rtw_vmfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + //DBG_871X("DBG_MEM_ALLOC %s:%d %s(%p,%d)\n", func, line, __FUNCTION__, (pbuf), (sz)); + + _rtw_vmfree((pbuf), (sz)); + + rtw_mstat_update( + flags + , MSTAT_FREE + , sz + ); +} + +inline u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + //if(sz>=153 && sz<=306) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + //if((sz)>4096) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_malloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + //if(sz>=153 && sz<=306) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + //if((sz)>4096) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p = _rtw_zmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline void dbg_rtw_mfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + //if(sz>=153 && sz<=306) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + //if((sz)>4096) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s(%p,%d)\n", func, line, __FUNCTION__, (pbuf), (sz)); + + _rtw_mfree((pbuf), (sz)); + + rtw_mstat_update( + flags + , MSTAT_FREE + , sz + ); +} + +inline struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, int line) +{ + struct sk_buff *skb; + unsigned int truesize = 0; + + skb = _rtw_skb_alloc(size); + + if(skb) + truesize = skb->truesize; + + if(!skb || truesize < size /*|| size > 4096*/) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, size, skb, truesize); + + rtw_mstat_update( + flags + , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb; +} + +inline void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, int line) +{ + unsigned int truesize = skb->truesize; + + //if(truesize > 4096) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize); + + _rtw_skb_free(skb); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); +} + +inline struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb_cp; + unsigned int truesize = skb->truesize; + unsigned int cp_truesize = 0; + + skb_cp = _rtw_skb_copy(skb); + if(skb_cp) + cp_truesize = skb_cp->truesize; + + if(!skb_cp || cp_truesize != truesize /*||cp_truesize > 4096*/) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cp:%p, cp_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cp, cp_truesize); + + rtw_mstat_update( + flags + , skb_cp ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb_cp; +} + +inline struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb_cl; + unsigned int truesize = skb->truesize; + unsigned int cl_truesize = 0; + + skb_cl = _rtw_skb_clone(skb); + if(skb_cl) + cl_truesize = skb_cl->truesize; + + if(!skb_cl || cl_truesize != truesize /*|| cl_truesize > 4096*/) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cl:%p, cl_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cl, cl_truesize); + + rtw_mstat_update( + flags + , skb_cl ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb_cl; +} + +inline int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line) +{ + int ret; + unsigned int truesize = skb->truesize; + + //if(truesize > 4096) + // DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize); + + ret = _rtw_netif_rx(ndev, skb); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); + + return ret; +} + +inline void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(list)) != NULL) + dbg_rtw_skb_free(skb, flags, func, line); +} + +#ifdef CONFIG_USB_HCI +inline void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, int line) +{ + void *p; + //DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size); + + p = _rtw_usb_buffer_alloc(dev, size, dma); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , size + ); + + return p; +} + +inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, int line) +{ + //DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size); + + _rtw_usb_buffer_free(dev, size, addr, dma); + + rtw_mstat_update( + flags + , MSTAT_FREE + , size + ); +} +#endif /* CONFIG_USB_HCI */ +#endif /* DBG_MEM_ALLOC */ + +void* rtw_malloc2d(int h, int w, int size) +{ + int j; + + void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size ); + if(a == NULL) + { + DBG_871X("%s: alloc memory fail!\n", __FUNCTION__); + return NULL; + } + + for( j=0; jprev = pnew; + pnew->next = pnext; + pnew->prev = pprev; + pprev->next = pnew; +} +#endif /* PLATFORM_FREEBSD */ + +void _rtw_init_listhead(_list *list) +{ + +#ifdef PLATFORM_LINUX + + INIT_LIST_HEAD(list); + +#endif + +#ifdef PLATFORM_FREEBSD + list->next = list; + list->prev = list; +#endif +#ifdef PLATFORM_WINDOWS + + NdisInitializeListHead(list); + +#endif + +} + + +/* +For the following list_xxx operations, +caller must guarantee the atomic context. +Otherwise, there will be racing condition. +*/ +u32 rtw_is_list_empty(_list *phead) +{ + +#ifdef PLATFORM_LINUX + + if (list_empty(phead)) + return _TRUE; + else + return _FALSE; + +#endif +#ifdef PLATFORM_FREEBSD + + if (phead->next == phead) + return _TRUE; + else + return _FALSE; + +#endif + + +#ifdef PLATFORM_WINDOWS + + if (IsListEmpty(phead)) + return _TRUE; + else + return _FALSE; + +#endif + + +} + +void rtw_list_insert_head(_list *plist, _list *phead) +{ + +#ifdef PLATFORM_LINUX + list_add(plist, phead); +#endif + +#ifdef PLATFORM_FREEBSD + __list_add(plist, phead, phead->next); +#endif + +#ifdef PLATFORM_WINDOWS + InsertHeadList(phead, plist); +#endif +} + +void rtw_list_insert_tail(_list *plist, _list *phead) +{ + +#ifdef PLATFORM_LINUX + + list_add_tail(plist, phead); + +#endif +#ifdef PLATFORM_FREEBSD + + __list_add(plist, phead->prev, phead); + +#endif +#ifdef PLATFORM_WINDOWS + + InsertTailList(phead, plist); + +#endif + +} + + +/* + +Caller must check if the list is empty before calling rtw_list_delete + +*/ + + +void _rtw_init_sema(_sema *sema, int init_val) +{ + +#ifdef PLATFORM_LINUX + + sema_init(sema, init_val); + +#endif +#ifdef PLATFORM_FREEBSD + sema_init(sema, init_val, "rtw_drv"); +#endif +#ifdef PLATFORM_OS_XP + + KeInitializeSemaphore(sema, init_val, SEMA_UPBND); // count=0; + +#endif + +#ifdef PLATFORM_OS_CE + if(*sema == NULL) + *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL); +#endif + +} + +void _rtw_free_sema(_sema *sema) +{ +#ifdef PLATFORM_FREEBSD + sema_destroy(sema); +#endif +#ifdef PLATFORM_OS_CE + CloseHandle(*sema); +#endif + +} + +void _rtw_up_sema(_sema *sema) +{ + +#ifdef PLATFORM_LINUX + + up(sema); + +#endif +#ifdef PLATFORM_FREEBSD + sema_post(sema); +#endif +#ifdef PLATFORM_OS_XP + + KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1, FALSE ); + +#endif + +#ifdef PLATFORM_OS_CE + ReleaseSemaphore(*sema, 1, NULL ); +#endif +} + +u32 _rtw_down_sema(_sema *sema) +{ + +#ifdef PLATFORM_LINUX + + if (down_interruptible(sema)) + return _FAIL; + else + return _SUCCESS; + +#endif +#ifdef PLATFORM_FREEBSD + sema_wait(sema); + return _SUCCESS; +#endif +#ifdef PLATFORM_OS_XP + + if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL)) + return _SUCCESS; + else + return _FAIL; +#endif + +#ifdef PLATFORM_OS_CE + if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE )) + return _SUCCESS; + else + return _FAIL; +#endif +} + + + +void _rtw_mutex_init(_mutex *pmutex) +{ +#ifdef PLATFORM_LINUX + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_init(pmutex); +#else + init_MUTEX(pmutex); +#endif + +#endif +#ifdef PLATFORM_FREEBSD + mtx_init(pmutex, "", NULL, MTX_DEF|MTX_RECURSE); +#endif +#ifdef PLATFORM_OS_XP + + KeInitializeMutex(pmutex, 0); + +#endif + +#ifdef PLATFORM_OS_CE + *pmutex = CreateMutex( NULL, _FALSE, NULL); +#endif +} + +void _rtw_mutex_free(_mutex *pmutex); +void _rtw_mutex_free(_mutex *pmutex) +{ +#ifdef PLATFORM_LINUX + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_destroy(pmutex); +#else +#endif + +#ifdef PLATFORM_FREEBSD + sema_destroy(pmutex); +#endif + +#endif + +#ifdef PLATFORM_OS_XP + +#endif + +#ifdef PLATFORM_OS_CE + +#endif +} + +void _rtw_spinlock_init(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock_init(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_init(plock, "", NULL, MTX_DEF|MTX_RECURSE); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAllocateSpinLock(plock); + +#endif + +} + +void _rtw_spinlock_free(_lock *plock) +{ +#ifdef PLATFORM_FREEBSD + mtx_destroy(plock); +#endif + +#ifdef PLATFORM_WINDOWS + + NdisFreeSpinLock(plock); + +#endif + +} +#ifdef PLATFORM_FREEBSD +extern PADAPTER prtw_lock; + +void rtw_mtx_lock(_lock *plock){ + if(prtw_lock){ + mtx_lock(&prtw_lock->glock); + } + else{ + printf("%s prtw_lock==NULL",__FUNCTION__); + } +} +void rtw_mtx_unlock(_lock *plock){ + if(prtw_lock){ + mtx_unlock(&prtw_lock->glock); + } + else{ + printf("%s prtw_lock==NULL",__FUNCTION__); + } + +} +#endif //PLATFORM_FREEBSD + + +void _rtw_spinlock(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_lock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAcquireSpinLock(plock); + +#endif + +} + +void _rtw_spinunlock(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_unlock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_unlock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisReleaseSpinLock(plock); + +#endif +} + + +void _rtw_spinlock_ex(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_lock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisDprAcquireSpinLock(plock); + +#endif + +} + +void _rtw_spinunlock_ex(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_unlock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_unlock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisDprReleaseSpinLock(plock); + +#endif +} + + + +void _rtw_init_queue(_queue *pqueue) +{ + + _rtw_init_listhead(&(pqueue->queue)); + + _rtw_spinlock_init(&(pqueue->lock)); + +} + +u32 _rtw_queue_empty(_queue *pqueue) +{ + return (rtw_is_list_empty(&(pqueue->queue))); +} + + +u32 rtw_end_of_queue_search(_list *head, _list *plist) +{ + if (head == plist) + return _TRUE; + else + return _FALSE; +} + + +u32 rtw_get_current_time(void) +{ + +#ifdef PLATFORM_LINUX + return jiffies; +#endif +#ifdef PLATFORM_FREEBSD + struct timeval tvp; + getmicrotime(&tvp); + return tvp.tv_sec; +#endif +#ifdef PLATFORM_WINDOWS + LARGE_INTEGER SystemTime; + NdisGetCurrentSystemTime(&SystemTime); + return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals +#endif +} + +inline u32 rtw_systime_to_ms(u32 systime) +{ +#ifdef PLATFORM_LINUX + return systime * 1000 / HZ; +#endif +#ifdef PLATFORM_FREEBSD + return systime * 1000; +#endif +#ifdef PLATFORM_WINDOWS + return systime / 10000 ; +#endif +} + +inline u32 rtw_ms_to_systime(u32 ms) +{ +#ifdef PLATFORM_LINUX + return ms * HZ / 1000; +#endif +#ifdef PLATFORM_FREEBSD + return ms /1000; +#endif +#ifdef PLATFORM_WINDOWS + return ms * 10000 ; +#endif +} + +// the input parameter start use the same unit as returned by rtw_get_current_time +inline s32 rtw_get_passing_time_ms(u32 start) +{ +#ifdef PLATFORM_LINUX + return rtw_systime_to_ms(jiffies-start); +#endif +#ifdef PLATFORM_FREEBSD + return rtw_systime_to_ms(rtw_get_current_time()); +#endif +#ifdef PLATFORM_WINDOWS + LARGE_INTEGER SystemTime; + NdisGetCurrentSystemTime(&SystemTime); + return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ; +#endif +} + +inline s32 rtw_get_time_interval_ms(u32 start, u32 end) +{ +#ifdef PLATFORM_LINUX + return rtw_systime_to_ms(end-start); +#endif +#ifdef PLATFORM_FREEBSD + return rtw_systime_to_ms(rtw_get_current_time()); +#endif +#ifdef PLATFORM_WINDOWS + return rtw_systime_to_ms(end-start); +#endif +} + + +void rtw_sleep_schedulable(int ms) +{ + +#ifdef PLATFORM_LINUX + + u32 delta; + + delta = (ms * HZ)/1000;//(ms) + if (delta == 0) { + delta = 1;// 1 ms + } + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(delta) != 0) { + return ; + } + return; + +#endif +#ifdef PLATFORM_FREEBSD + DELAY(ms*1000); + return ; +#endif + +#ifdef PLATFORM_WINDOWS + + NdisMSleep(ms*1000); //(us)*1000=(ms) + +#endif + +} + + +void rtw_msleep_os(int ms) +{ + +#ifdef PLATFORM_LINUX + + msleep((unsigned int)ms); + +#endif +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(ms*1000); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisMSleep(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void rtw_usleep_os(int us) +{ + +#ifdef PLATFORM_LINUX + + // msleep((unsigned int)us); + if ( 1 < (us/1000) ) + msleep(1); + else + msleep( (us/1000) + 1); + +#endif +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(us); + + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisMSleep(us); //(us) + +#endif + + +} + + +#ifdef DBG_DELAY_OS +void _rtw_mdelay_os(int ms, const char *func, const int line) +{ + #if 0 + if(ms>10) + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms); + rtw_msleep_os(ms); + return; + #endif + + + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms); + +#if defined(PLATFORM_LINUX) + + mdelay((unsigned long)ms); + +#elif defined(PLATFORM_WINDOWS) + + NdisStallExecution(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void _rtw_udelay_os(int us, const char *func, const int line) +{ + + #if 0 + if(us > 1000) { + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us); + rtw_usleep_os(us); + return; + } + #endif + + + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us); + + +#if defined(PLATFORM_LINUX) + + udelay((unsigned long)us); + +#elif defined(PLATFORM_WINDOWS) + + NdisStallExecution(us); //(us) + +#endif + +} +#else +void rtw_mdelay_os(int ms) +{ + +#ifdef PLATFORM_LINUX + + mdelay((unsigned long)ms); + +#endif +#ifdef PLATFORM_FREEBSD + DELAY(ms*1000); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisStallExecution(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void rtw_udelay_os(int us) +{ + +#ifdef PLATFORM_LINUX + + udelay((unsigned long)us); + +#endif +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(us); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisStallExecution(us); //(us) + +#endif + +} +#endif + +void rtw_yield_os() +{ +#ifdef PLATFORM_LINUX + yield(); +#endif +#ifdef PLATFORM_FREEBSD + yield(); +#endif +#ifdef PLATFORM_WINDOWS + SwitchToThread(); +#endif +} + +#define RTW_SUSPEND_LOCK_NAME "rtw_wifi" + +#ifdef CONFIG_WAKELOCK +static struct wake_lock rtw_suspend_lock; +#elif defined(CONFIG_ANDROID_POWER) +static android_suspend_lock_t rtw_suspend_lock ={ + .name = RTW_SUSPEND_LOCK_NAME +}; +#endif + +inline void rtw_suspend_lock_init() +{ + #ifdef CONFIG_WAKELOCK + wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME); + #elif defined(CONFIG_ANDROID_POWER) + android_init_suspend_lock(&rtw_suspend_lock); + #endif +} + +inline void rtw_suspend_lock_uninit() +{ + #ifdef CONFIG_WAKELOCK + wake_lock_destroy(&rtw_suspend_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_uninit_suspend_lock(&rtw_suspend_lock); + #endif +} + +inline void rtw_lock_suspend() +{ + #ifdef CONFIG_WAKELOCK + wake_lock(&rtw_suspend_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend(&rtw_suspend_lock); + #endif +} + +inline void rtw_unlock_suspend() +{ + #ifdef CONFIG_WAKELOCK + wake_unlock(&rtw_suspend_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_unlock_suspend(&rtw_suspend_lock); + #endif +} + +inline void rtw_lock_suspend_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms)); + #endif +} + +inline void ATOMIC_SET(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_set(v,i); + #elif defined(PLATFORM_WINDOWS) + *v=i;// other choice???? + #elif defined(PLATFORM_FREEBSD) + atomic_set_int(v,i); + #endif +} + +inline int ATOMIC_READ(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_read(v); + #elif defined(PLATFORM_WINDOWS) + return *v; // other choice???? + #elif defined(PLATFORM_FREEBSD) + return atomic_load_acq_32(v); + #endif +} + +inline void ATOMIC_ADD(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_add(i,v); + #elif defined(PLATFORM_WINDOWS) + InterlockedAdd(v,i); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,i); + #endif +} +inline void ATOMIC_SUB(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_sub(i,v); + #elif defined(PLATFORM_WINDOWS) + InterlockedAdd(v,-i); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,i); + #endif +} + +inline void ATOMIC_INC(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + atomic_inc(v); + #elif defined(PLATFORM_WINDOWS) + InterlockedIncrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,1); + #endif +} + +inline void ATOMIC_DEC(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + atomic_dec(v); + #elif defined(PLATFORM_WINDOWS) + InterlockedDecrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,1); + #endif +} + +inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + return atomic_add_return(i,v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedAdd(v,i); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,i); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + return atomic_sub_return(i,v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedAdd(v,-i); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,i); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_INC_RETURN(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_inc_return(v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedIncrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,1); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_DEC_RETURN(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_dec_return(v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedDecrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,1); + return atomic_load_acq_32(v); + #endif +} + + +#ifdef PLATFORM_LINUX +/* +* Open a file with the specific @param path, @param flag, @param mode +* @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success +* @param path the path of the file to open +* @param flag file operation flags, please refer to linux document +* @param mode please refer to linux document +* @return Linux specific error code +*/ +static int openFile(struct file **fpp, char *path, int flag, int mode) +{ + struct file *fp; + + fp=filp_open(path, flag, mode); + if(IS_ERR(fp)) { + *fpp=NULL; + return PTR_ERR(fp); + } + else { + *fpp=fp; + return 0; + } +} + +/* +* Close the file with the specific @param fp +* @param fp the pointer of struct file to close +* @return always 0 +*/ +static int closeFile(struct file *fp) +{ + filp_close(fp,NULL); + return 0; +} + +static int readFile(struct file *fp,char *buf,int len) +{ + int rlen=0, sum=0; + + if (!fp->f_op || !fp->f_op->read) + return -EPERM; + + while(sumf_op->read(fp,buf+sum,len-sum, &fp->f_pos); + if(rlen>0) + sum+=rlen; + else if(0 != rlen) + return rlen; + else + break; + } + + return sum; + +} + +static int writeFile(struct file *fp,char *buf,int len) +{ + int wlen=0, sum=0; + + if (!fp->f_op || !fp->f_op->write) + return -EPERM; + + while(sumf_op->write(fp,buf+sum,len-sum, &fp->f_pos); + if(wlen>0) + sum+=wlen; + else if(0 != wlen) + return wlen; + else + break; + } + + return sum; + +} + +/* +* Test if the specifi @param path is a file and readable +* @param path the path of the file to test +* @return Linux specific error code +*/ +static int isFileReadable(char *path) +{ + struct file *fp; + int ret = 0; + mm_segment_t oldfs; + char buf; + + fp=filp_open(path, O_RDONLY, 0); + if(IS_ERR(fp)) { + ret = PTR_ERR(fp); + } + else { + oldfs = get_fs(); set_fs(get_ds()); + + if(1!=readFile(fp, &buf, 1)) + ret = PTR_ERR(fp); + + set_fs(oldfs); + filp_close(fp,NULL); + } + return ret; +} + +/* +* Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most +* @param path the path of the file to open and read +* @param buf the starting address of the buffer to store file content +* @param sz how many bytes to read at most +* @return the byte we've read, or Linux specific error code +*/ +static int retriveFromFile(char *path, u8* buf, u32 sz) +{ + int ret =-1; + mm_segment_t oldfs; + struct file *fp; + + if(path && buf) { + if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){ + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + + oldfs = get_fs(); set_fs(get_ds()); + ret=readFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); + + DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret); + + } else { + DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret); + } + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = -EINVAL; + } + return ret; +} + +/* +* Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file +* @param path the path of the file to open and write +* @param buf the starting address of the data to write into file +* @param sz how many bytes to write at most +* @return the byte we've written, or Linux specific error code +*/ +static int storeToFile(char *path, u8* buf, u32 sz) +{ + int ret =0; + mm_segment_t oldfs; + struct file *fp; + + if(path && buf) { + if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) { + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + + oldfs = get_fs(); set_fs(get_ds()); + ret=writeFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); + + DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret); + + } else { + DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret); + } + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = -EINVAL; + } + return ret; +} +#endif //PLATFORM_LINUX + +/* +* Test if the specifi @param path is a file and readable +* @param path the path of the file to test +* @return _TRUE or _FALSE +*/ +int rtw_is_file_readable(char *path) +{ +#ifdef PLATFORM_LINUX + if(isFileReadable(path) == 0) + return _TRUE; + else + return _FALSE; +#else + //Todo... + return _FALSE; +#endif +} + +/* +* Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most +* @param path the path of the file to open and read +* @param buf the starting address of the buffer to store file content +* @param sz how many bytes to read at most +* @return the byte we've read +*/ +int rtw_retrive_from_file(char *path, u8* buf, u32 sz) +{ +#ifdef PLATFORM_LINUX + int ret =retriveFromFile(path, buf, sz); + return ret>=0?ret:0; +#else + //Todo... + return 0; +#endif +} + +/* +* Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file +* @param path the path of the file to open and write +* @param buf the starting address of the data to write into file +* @param sz how many bytes to write at most +* @return the byte we've written +*/ +int rtw_store_to_file(char *path, u8* buf, u32 sz) +{ +#ifdef PLATFORM_LINUX + int ret =storeToFile(path, buf, sz); + return ret>=0?ret:0; +#else + //Todo... + return 0; +#endif +} + +#if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR +#ifdef PLATFORM_LINUX +struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv) +{ + struct net_device *pnetdev; + struct rtw_netdev_priv_indicator *pnpi; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); +#else + pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); +#endif + if (!pnetdev) + goto RETURN; + + pnpi = netdev_priv(pnetdev); + pnpi->priv=old_priv; + pnpi->sizeof_priv=sizeof_priv; + +RETURN: + return pnetdev; +} + +struct net_device *rtw_alloc_etherdev(int sizeof_priv) +{ + struct net_device *pnetdev; + struct rtw_netdev_priv_indicator *pnpi; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); +#else + pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); +#endif + if (!pnetdev) + goto RETURN; + + pnpi = netdev_priv(pnetdev); + + pnpi->priv = rtw_zvmalloc(sizeof_priv); + if (!pnpi->priv) { + free_netdev(pnetdev); + pnetdev = NULL; + goto RETURN; + } + + pnpi->sizeof_priv=sizeof_priv; +RETURN: + return pnetdev; +} + +void rtw_free_netdev(struct net_device * netdev) +{ + struct rtw_netdev_priv_indicator *pnpi; + + if(!netdev) + goto RETURN; + + pnpi = netdev_priv(netdev); + + if(!pnpi->priv) + goto RETURN; + + rtw_vmfree(pnpi->priv, pnpi->sizeof_priv); + free_netdev(netdev); + +RETURN: + return; +} + +/* +* Jeff: this function should be called under ioctl (rtnl_lock is accquired) while +* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +*/ +int rtw_change_ifname(_adapter *padapter, const char *ifname) +{ + struct net_device *pnetdev; + struct net_device *cur_pnetdev = padapter->pnetdev; + struct rereg_nd_name_data *rereg_priv; + int ret; + + if(!padapter) + goto error; + + rereg_priv = &padapter->rereg_nd_name_priv; + + //free the old_pnetdev + if(rereg_priv->old_pnetdev) { + free_netdev(rereg_priv->old_pnetdev); + rereg_priv->old_pnetdev = NULL; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + if(!rtnl_is_locked()) + unregister_netdev(cur_pnetdev); + else +#endif + unregister_netdevice(cur_pnetdev); + + rtw_proc_remove_one(cur_pnetdev); + + rereg_priv->old_pnetdev=cur_pnetdev; + + pnetdev = rtw_init_netdev(padapter); + if (!pnetdev) { + ret = -1; + goto error; + } + + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); + + rtw_init_netdev_name(pnetdev, ifname); + + _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + if(!rtnl_is_locked()) + ret = register_netdev(pnetdev); + else +#endif + ret = register_netdevice(pnetdev); + + if ( ret != 0) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n")); + goto error; + } + + rtw_proc_init_one(pnetdev); + + return 0; + +error: + + return -1; + +} +#endif +#endif //MEM_ALLOC_REFINE_ADAPTOR + +#ifdef PLATFORM_FREEBSD +/* + * Copy a buffer from userspace and write into kernel address + * space. + * + * This emulation just calls the FreeBSD copyin function (to + * copy data from user space buffer into a kernel space buffer) + * and is designed to be used with the above io_write_wrapper. + * + * This function should return the number of bytes not copied. + * I.e. success results in a zero value. + * Negative error values are not returned. + */ +unsigned long +copy_from_user(void *to, const void *from, unsigned long n) +{ + if ( copyin(from, to, n) != 0 ) { + /* Any errors will be treated as a failure + to copy any of the requested bytes */ + return n; + } + + return 0; +} + +unsigned long +copy_to_user(void *to, const void *from, unsigned long n) +{ + if ( copyout(from, to, n) != 0 ) { + /* Any errors will be treated as a failure + to copy any of the requested bytes */ + return n; + } + + return 0; +} + + +/* + * The usb_register and usb_deregister functions are used to register + * usb drivers with the usb subsystem. In this compatibility layer + * emulation a list of drivers (struct usb_driver) is maintained + * and is used for probing/attaching etc. + * + * usb_register and usb_deregister simply call these functions. + */ +int +usb_register(struct usb_driver *driver) +{ + rtw_usb_linux_register(driver); + return 0; +} + + +int +usb_deregister(struct usb_driver *driver) +{ + rtw_usb_linux_deregister(driver); + return 0; +} + +void module_init_exit_wrapper(void *arg) +{ + int (*func)(void) = arg; + func(); + return; +} + +#endif //PLATFORM_FREEBSD +u64 rtw_modular64(u64 x, u64 y) +{ +#ifdef PLATFORM_LINUX + return do_div(x, y); +#elif defined(PLATFORM_WINDOWS) + return (x % y); +#elif defined(PLATFORM_FREEBSD) + return (x %y); +#endif +} + +u64 rtw_division64(u64 x, u64 y) +{ +#ifdef PLATFORM_LINUX + do_div(x, y); + return x; +#elif defined(PLATFORM_WINDOWS) + return (x / y); +#elif defined(PLATFORM_FREEBSD) + return (x / y); +#endif +} + +void rtw_buf_free(u8 **buf, u32 *buf_len) +{ + u32 ori_len; + + if (!buf || !buf_len) + return; + + ori_len = *buf_len; + + if (*buf) { + u32 tmp_buf_len = *buf_len; + *buf_len = 0; + rtw_mfree(*buf, tmp_buf_len); + *buf = NULL; + } +} + +void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) +{ + u32 ori_len = 0, dup_len = 0; + u8 *ori = NULL; + u8 *dup = NULL; + + if (!buf || !buf_len) + return; + + if (!src || !src_len) + goto keep_ori; + + /* duplicate src */ + dup = rtw_malloc(src_len); + if (dup) { + dup_len = src_len; + _rtw_memcpy(dup, src, dup_len); + } + +keep_ori: + ori = *buf; + ori_len = *buf_len; + + /* replace buf with dup */ + *buf_len = 0; + *buf = dup; + *buf_len = dup_len; + + /* free ori */ + if (ori && ori_len > 0) + rtw_mfree(ori, ori_len); +} + + +/** + * rtw_cbuf_full - test if cbuf is full + * @cbuf: pointer of struct rtw_cbuf + * + * Returns: _TRUE if cbuf is full + */ +inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) +{ + return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE; +} + +/** + * rtw_cbuf_empty - test if cbuf is empty + * @cbuf: pointer of struct rtw_cbuf + * + * Returns: _TRUE if cbuf is empty + */ +inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) +{ + return (cbuf->write == cbuf->read)? _TRUE : _FALSE; +} + +/** + * rtw_cbuf_push - push a pointer into cbuf + * @cbuf: pointer of struct rtw_cbuf + * @buf: pointer to push in + * + * Lock free operation, be careful of the use scheme + * Returns: _TRUE push success + */ +bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) +{ + if (rtw_cbuf_full(cbuf)) + return _FAIL; + + if (0) + DBG_871X("%s on %u\n", __func__, cbuf->write); + cbuf->bufs[cbuf->write] = buf; + cbuf->write = (cbuf->write+1)%cbuf->size; + + return _SUCCESS; +} + +/** + * rtw_cbuf_pop - pop a pointer from cbuf + * @cbuf: pointer of struct rtw_cbuf + * + * Lock free operation, be careful of the use scheme + * Returns: pointer popped out + */ +void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) +{ + void *buf; + if (rtw_cbuf_empty(cbuf)) + return NULL; + + if (0) + DBG_871X("%s on %u\n", __func__, cbuf->read); + buf = cbuf->bufs[cbuf->read]; + cbuf->read = (cbuf->read+1)%cbuf->size; + + return buf; +} + +/** + * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization + * @size: size of pointer + * + * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure + */ +struct rtw_cbuf *rtw_cbuf_alloc(u32 size) +{ + struct rtw_cbuf *cbuf; + + cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size); + + if (cbuf) { + cbuf->write = cbuf->read = 0; + cbuf->size = size; + } + + return cbuf; +} + +/** + * rtw_cbuf_free - free the given rtw_cbuf + * @cbuf: pointer of struct rtw_cbuf to free + */ +void rtw_cbuf_free(struct rtw_cbuf *cbuf) +{ + rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size); +} + diff --git a/rtl8192cu-fixes/runwpa b/rtl8192cu-fixes/runwpa new file mode 100755 index 00000000..f825e8bd --- /dev/null +++ b/rtl8192cu-fixes/runwpa @@ -0,0 +1,20 @@ +#!/bin/bash + +if [ "`which iwconfig`" = "" ] ; then + echo "WARNING:Wireless tool not exist!" + echo " Please install it!" + exit +else + if [ `uname -r | cut -d. -f2` -eq 4 ]; then + wpa_supplicant -D ipw -c wpa1.conf -i wlan0 + else + if [ `iwconfig -v |awk '{print $4}' | head -n 1` -lt 18 ] ; then + wpa_supplicant -D ipw -c wpa1.conf -i wlan0 + else + wpa_supplicant -D wext -c wpa1.conf -i wlan0 + fi + + fi +fi + + diff --git a/v4l2loopback b/v4l2loopback new file mode 160000 index 00000000..2fdda920 --- /dev/null +++ b/v4l2loopback @@ -0,0 +1 @@ +Subproject commit 2fdda92084b8dff39f041b44d76d3fc6942f7a5c From 2d77b3e74f2a89383ee4e3023b09b1c60ae344ba Mon Sep 17 00:00:00 2001 From: Leonardo Lontra Date: Fri, 10 Jun 2016 13:28:06 -0300 Subject: [PATCH 04/26] bugs fixes --- build/sun8iw7p1smp_lobo_defconfig | 24 +- build/sun8iw7p1smp_lobo_defconfig.old | 26 +- build/sun8iw7p1smp_lobo_defconfig.old- | 3263 ----------------- .../rtl8192cu-fixes}/.gitignore | 0 .../8192cu-disable-power-management.conf | 0 .../rtl8192cu-fixes}/Makefile | 0 .../rtl8192cu-fixes}/README.md | 0 .../blacklist-native-rtl8192.conf | 0 .../rtl8192cu-fixes}/clean | 0 .../rtl8192cu-fixes}/core/efuse/rtw_efuse.c | 0 .../rtl8192cu-fixes}/core/rtw_ap.c | 0 .../rtl8192cu-fixes}/core/rtw_br_ext.c | 0 .../rtl8192cu-fixes}/core/rtw_cmd.c | 0 .../rtl8192cu-fixes}/core/rtw_debug.c | 0 .../rtl8192cu-fixes}/core/rtw_eeprom.c | 0 .../rtl8192cu-fixes}/core/rtw_ieee80211.c | 0 .../rtl8192cu-fixes}/core/rtw_io.c | 0 .../rtl8192cu-fixes}/core/rtw_ioctl_query.c | 0 .../rtl8192cu-fixes}/core/rtw_ioctl_rtl.c | 0 .../rtl8192cu-fixes}/core/rtw_ioctl_set.c | 0 .../rtl8192cu-fixes}/core/rtw_iol.c | 0 .../rtl8192cu-fixes}/core/rtw_mlme.c | 0 .../rtl8192cu-fixes}/core/rtw_mlme_ext.c | 0 .../rtl8192cu-fixes}/core/rtw_mp.c | 0 .../rtl8192cu-fixes}/core/rtw_mp_ioctl.c | 0 .../rtl8192cu-fixes}/core/rtw_p2p.c | 0 .../rtl8192cu-fixes}/core/rtw_pwrctrl.c | 0 .../rtl8192cu-fixes}/core/rtw_recv.c | 0 .../rtl8192cu-fixes}/core/rtw_rf.c | 0 .../rtl8192cu-fixes}/core/rtw_security.c | 0 .../rtl8192cu-fixes}/core/rtw_sreset.c | 0 .../rtl8192cu-fixes}/core/rtw_sta_mgt.c | 0 .../rtl8192cu-fixes}/core/rtw_tdls.c | 0 .../rtl8192cu-fixes}/core/rtw_wlan_util.c | 0 .../rtl8192cu-fixes}/core/rtw_xmit.c | 0 .../rtl8192cu-fixes}/dkms.conf | 0 .../rtl8192cu-fixes}/hal/HalPwrSeqCmd.c | 0 .../rtl8192cu-fixes}/hal/dm.c | 0 .../rtl8192cu-fixes}/hal/dm.h | 0 .../rtl8192cu-fixes}/hal/hal_com.c | 0 .../rtl8192cu-fixes}/hal/hal_intf.c | 0 .../hal/rtl8192c/rtl8192c_cmd.c | 0 .../hal/rtl8192c/rtl8192c_dm.c | 0 .../hal/rtl8192c/rtl8192c_hal_init.c | 0 .../hal/rtl8192c/rtl8192c_mp.c | 0 .../hal/rtl8192c/rtl8192c_phycfg.c | 0 .../hal/rtl8192c/rtl8192c_rf6052.c | 0 .../hal/rtl8192c/rtl8192c_rxdesc.c | 0 .../hal/rtl8192c/rtl8192c_sreset.c | 0 .../hal/rtl8192c/rtl8192c_xmit.c | 0 .../hal/rtl8192c/usb/Hal8192CUHWImg.c | 0 .../hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c | 0 .../hal/rtl8192c/usb/rtl8192cu_led.c | 0 .../hal/rtl8192c/usb/rtl8192cu_recv.c | 0 .../hal/rtl8192c/usb/rtl8192cu_xmit.c | 0 .../hal/rtl8192c/usb/usb_halinit.c | 0 .../hal/rtl8192c/usb/usb_ops_ce.c | 0 .../hal/rtl8192c/usb/usb_ops_linux.c | 0 .../hal/rtl8192c/usb/usb_ops_xp.c | 0 .../rtl8192cu-fixes}/include/Hal8192CEHWImg.h | 0 .../rtl8192cu-fixes}/include/Hal8192CPhyCfg.h | 0 .../rtl8192cu-fixes}/include/Hal8192CPhyReg.h | 0 .../rtl8192cu-fixes}/include/Hal8192CUHWImg.h | 0 .../include/Hal8192CUHWImg_wowlan.h | 0 .../rtl8192cu-fixes}/include/Hal8192DEHWImg.h | 0 .../rtl8192cu-fixes}/include/Hal8192DPhyCfg.h | 0 .../rtl8192cu-fixes}/include/Hal8192DPhyReg.h | 0 .../rtl8192cu-fixes}/include/Hal8192DUHWImg.h | 0 .../include/Hal8192DUHWImg_wowlan.h | 0 .../rtl8192cu-fixes}/include/HalPwrSeqCmd.h | 0 .../rtl8192cu-fixes}/include/autoconf.h | 0 .../rtl8192cu-fixes}/include/basic_types.h | 0 .../include/byteorder/big_endian.h | 0 .../include/byteorder/generic.h | 0 .../include/byteorder/little_endian.h | 0 .../rtl8192cu-fixes}/include/byteorder/swab.h | 0 .../include/byteorder/swabb.h | 0 .../rtl8192cu-fixes}/include/circ_buf.h | 0 .../rtl8192cu-fixes}/include/cmd_osdep.h | 0 .../rtl8192cu-fixes}/include/drv_conf.h | 0 .../rtl8192cu-fixes}/include/drv_types.h | 0 .../rtl8192cu-fixes}/include/drv_types_ce.h | 0 .../include/drv_types_linux.h | 0 .../rtl8192cu-fixes}/include/drv_types_sdio.h | 0 .../rtl8192cu-fixes}/include/drv_types_xp.h | 0 .../rtl8192cu-fixes}/include/ethernet.h | 0 .../rtl8192cu-fixes}/include/h2clbk.h | 0 .../rtl8192cu-fixes}/include/hal_com.h | 0 .../rtl8192cu-fixes}/include/hal_intf.h | 0 .../rtl8192cu-fixes}/include/ieee80211.h | 0 .../rtl8192cu-fixes}/include/ieee80211_ext.h | 0 .../rtl8192cu-fixes}/include/if_ether.h | 0 .../rtl8192cu-fixes}/include/ioctl_cfg80211.h | 0 .../rtl8192cu-fixes}/include/ip.h | 0 .../rtl8192cu-fixes}/include/linux/wireless.h | 0 .../rtl8192cu-fixes}/include/mlme_osdep.h | 0 .../rtl8192cu-fixes}/include/mp_custom_oid.h | 0 .../rtl8192cu-fixes}/include/nic_spec.h | 0 .../include/osdep_ce_service.h | 0 .../rtl8192cu-fixes}/include/osdep_intf.h | 0 .../rtl8192cu-fixes}/include/osdep_service.h | 0 .../rtl8192cu-fixes}/include/pci_hal.h | 0 .../rtl8192cu-fixes}/include/pci_ops.h | 0 .../rtl8192cu-fixes}/include/pci_osintf.h | 0 .../rtl8192cu-fixes}/include/recv_osdep.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_cmd.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_dm.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_event.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_hal.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_led.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_recv.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_rf.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_spec.h | 0 .../include/rtl8192c_sreset.h | 0 .../rtl8192cu-fixes}/include/rtl8192c_xmit.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_cmd.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_dm.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_hal.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_led.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_recv.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_rf.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_spec.h | 0 .../rtl8192cu-fixes}/include/rtl8192d_xmit.h | 0 .../rtl8192cu-fixes}/include/rtw_android.h | 0 .../rtl8192cu-fixes}/include/rtw_ap.h | 0 .../rtl8192cu-fixes}/include/rtw_br_ext.h | 0 .../rtl8192cu-fixes}/include/rtw_byteorder.h | 0 .../rtl8192cu-fixes}/include/rtw_cmd.h | 0 .../rtl8192cu-fixes}/include/rtw_debug.h | 0 .../rtl8192cu-fixes}/include/rtw_eeprom.h | 0 .../rtl8192cu-fixes}/include/rtw_efuse.h | 0 .../rtl8192cu-fixes}/include/rtw_event.h | 0 .../rtl8192cu-fixes}/include/rtw_ht.h | 0 .../rtl8192cu-fixes}/include/rtw_io.h | 0 .../rtl8192cu-fixes}/include/rtw_ioctl.h | 0 .../include/rtw_ioctl_query.h | 0 .../rtl8192cu-fixes}/include/rtw_ioctl_rtl.h | 0 .../rtl8192cu-fixes}/include/rtw_ioctl_set.h | 0 .../rtl8192cu-fixes}/include/rtw_iol.h | 0 .../rtl8192cu-fixes}/include/rtw_led.h | 0 .../rtl8192cu-fixes}/include/rtw_mlme.h | 0 .../rtl8192cu-fixes}/include/rtw_mlme_ext.h | 0 .../rtl8192cu-fixes}/include/rtw_mp.h | 0 .../rtl8192cu-fixes}/include/rtw_mp_ioctl.h | 0 .../include/rtw_mp_phy_regdef.h | 0 .../rtl8192cu-fixes}/include/rtw_p2p.h | 0 .../rtl8192cu-fixes}/include/rtw_pwrctrl.h | 0 .../rtl8192cu-fixes}/include/rtw_qos.h | 0 .../rtl8192cu-fixes}/include/rtw_recv.h | 0 .../rtl8192cu-fixes}/include/rtw_rf.h | 0 .../rtl8192cu-fixes}/include/rtw_security.h | 0 .../rtl8192cu-fixes}/include/rtw_sreset.h | 0 .../rtl8192cu-fixes}/include/rtw_tdls.h | 0 .../rtl8192cu-fixes}/include/rtw_version.h | 0 .../rtl8192cu-fixes}/include/rtw_xmit.h | 0 .../rtl8192cu-fixes}/include/sta_info.h | 0 .../rtl8192cu-fixes}/include/usb_hal.h | 0 .../rtl8192cu-fixes}/include/usb_ops.h | 0 .../rtl8192cu-fixes}/include/usb_ops_linux.h | 0 .../rtl8192cu-fixes}/include/usb_osintf.h | 0 .../rtl8192cu-fixes}/include/usb_vendor_req.h | 0 .../rtl8192cu-fixes}/include/wifi.h | 0 .../rtl8192cu-fixes}/include/wlan_bssdef.h | 0 .../rtl8192cu-fixes}/include/xmit_osdep.h | 0 .../rtl8192cu-fixes}/installer.sh | 0 .../os_dep/linux/ioctl_cfg80211.c | 0 .../os_dep/linux/ioctl_linux.c | 0 .../os_dep/linux/mlme_linux.c | 0 .../rtl8192cu-fixes}/os_dep/linux/os_intfs.c | 0 .../rtl8192cu-fixes}/os_dep/linux/pci_intf.c | 0 .../os_dep/linux/pci_ops_linux.c | 0 .../os_dep/linux/recv_linux.c | 0 .../os_dep/linux/rtw_android.c | 0 .../rtl8192cu-fixes}/os_dep/linux/usb_intf.c | 0 .../os_dep/linux/usb_ops_linux.c | 0 .../os_dep/linux/xmit_linux.c | 0 .../rtl8192cu-fixes}/os_dep/osdep_service.c | 0 .../rtl8192cu-fixes}/runwpa | 0 extra_modules/v4l2loopback/.gitignore | 8 + extra_modules/v4l2loopback/AUTHORS | 15 + extra_modules/v4l2loopback/COPYING | 339 ++ extra_modules/v4l2loopback/ChangeLog | 414 +++ extra_modules/v4l2loopback/Makefile | 78 + extra_modules/v4l2loopback/Makefile.manual | 16 + extra_modules/v4l2loopback/NEWS | 154 + extra_modules/v4l2loopback/README.md | 200 + extra_modules/v4l2loopback/TODO | 31 + extra_modules/v4l2loopback/currentversion.sh | 6 + extra_modules/v4l2loopback/dkms.conf | 12 + extra_modules/v4l2loopback/doc/docs.txt | 8 + .../v4l2loopback/doc/kernel_debugging.txt | 22 + extra_modules/v4l2loopback/doc/makeformats.sh | 24 + .../v4l2loopback/doc/missingformats.h | 291 ++ .../v4l2loopback/doc/v4l2_formats.txt | 116 + .../v4l2loopback/examples/.gitignore | 2 + extra_modules/v4l2loopback/examples/Makefile | 11 + extra_modules/v4l2loopback/examples/README | 46 + .../v4l2loopback/examples/ondemandcam.c | 130 + .../examples/restarting-writer.sh | 32 + extra_modules/v4l2loopback/examples/test.c | 188 + .../v4l2loopback/examples/yuv4mpeg_to_v4l2.c | 184 + extra_modules/v4l2loopback/man/touch | 0 extra_modules/v4l2loopback/release.sh | 100 + extra_modules/v4l2loopback/tests/Makefile | 1 + extra_modules/v4l2loopback/tests/interlaced_w | 43 + extra_modules/v4l2loopback/tests/test_dqbuf.c | 131 + .../v4l2loopback/utils/v4l2loopback-ctl | 156 + extra_modules/v4l2loopback/v4l2loopback.c | 2443 ++++++++++++ .../v4l2loopback/v4l2loopback_formats.h | 363 ++ .../arm/configs/sun8iw7p1smp_lobo_defconfig | 24 +- .../arch/arm/mach-sunxi/power/brom/Makefile | 2 +- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35129 -> 35129 bytes .../arch/arm/mach-sunxi/power/brom/resumes.h | 12 +- .../arm/mach-sunxi/power/brom/resumes.lst | 6 +- .../arm/mach-sunxi/power/brom/resumes.map | 6 +- linux-3.4/arch/arm/mach-sunxi/sunxi-debug.c | 22 +- linux-3.4/drivers/gpu/ion/ion_cma_heap.c | 2 +- v4l2loopback | 1 - 218 files changed, 5647 insertions(+), 3305 deletions(-) delete mode 100644 build/sun8iw7p1smp_lobo_defconfig.old- rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/.gitignore (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/8192cu-disable-power-management.conf (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/Makefile (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/README.md (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/blacklist-native-rtl8192.conf (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/clean (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/efuse/rtw_efuse.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_ap.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_br_ext.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_cmd.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_debug.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_eeprom.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_ieee80211.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_io.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_ioctl_query.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_ioctl_rtl.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_ioctl_set.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_iol.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_mlme.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_mlme_ext.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_mp.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_mp_ioctl.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_p2p.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_pwrctrl.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_recv.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_rf.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_security.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_sreset.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_sta_mgt.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_tdls.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_wlan_util.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/core/rtw_xmit.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/dkms.conf (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/HalPwrSeqCmd.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/dm.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/dm.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/hal_com.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/hal_intf.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_cmd.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_dm.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_hal_init.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_mp.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_phycfg.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_rf6052.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_rxdesc.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_sreset.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/rtl8192c_xmit.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/Hal8192CUHWImg.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/rtl8192cu_led.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/rtl8192cu_recv.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/rtl8192cu_xmit.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/usb_halinit.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/usb_ops_ce.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/usb_ops_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/hal/rtl8192c/usb/usb_ops_xp.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192CEHWImg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192CPhyCfg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192CPhyReg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192CUHWImg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192CUHWImg_wowlan.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192DEHWImg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192DPhyCfg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192DPhyReg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192DUHWImg.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/Hal8192DUHWImg_wowlan.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/HalPwrSeqCmd.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/autoconf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/basic_types.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/byteorder/big_endian.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/byteorder/generic.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/byteorder/little_endian.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/byteorder/swab.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/byteorder/swabb.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/circ_buf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/cmd_osdep.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_conf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_types.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_types_ce.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_types_linux.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_types_sdio.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/drv_types_xp.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/ethernet.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/h2clbk.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/hal_com.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/hal_intf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/ieee80211.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/ieee80211_ext.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/if_ether.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/ioctl_cfg80211.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/ip.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/linux/wireless.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/mlme_osdep.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/mp_custom_oid.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/nic_spec.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/osdep_ce_service.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/osdep_intf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/osdep_service.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/pci_hal.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/pci_ops.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/pci_osintf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/recv_osdep.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_cmd.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_dm.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_event.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_hal.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_led.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_recv.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_rf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_spec.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_sreset.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192c_xmit.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_cmd.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_dm.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_hal.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_led.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_recv.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_rf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_spec.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtl8192d_xmit.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_android.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ap.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_br_ext.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_byteorder.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_cmd.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_debug.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_eeprom.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_efuse.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_event.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ht.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_io.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ioctl.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ioctl_query.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ioctl_rtl.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_ioctl_set.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_iol.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_led.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_mlme.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_mlme_ext.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_mp.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_mp_ioctl.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_mp_phy_regdef.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_p2p.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_pwrctrl.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_qos.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_recv.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_rf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_security.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_sreset.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_tdls.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_version.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/rtw_xmit.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/sta_info.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/usb_hal.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/usb_ops.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/usb_ops_linux.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/usb_osintf.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/usb_vendor_req.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/wifi.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/wlan_bssdef.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/include/xmit_osdep.h (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/installer.sh (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/ioctl_cfg80211.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/ioctl_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/mlme_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/os_intfs.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/pci_intf.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/pci_ops_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/recv_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/rtw_android.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/usb_intf.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/usb_ops_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/linux/xmit_linux.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/os_dep/osdep_service.c (100%) rename {rtl8192cu-fixes => extra_modules/rtl8192cu-fixes}/runwpa (100%) create mode 100644 extra_modules/v4l2loopback/.gitignore create mode 100644 extra_modules/v4l2loopback/AUTHORS create mode 100644 extra_modules/v4l2loopback/COPYING create mode 100644 extra_modules/v4l2loopback/ChangeLog create mode 100644 extra_modules/v4l2loopback/Makefile create mode 100644 extra_modules/v4l2loopback/Makefile.manual create mode 100644 extra_modules/v4l2loopback/NEWS create mode 100644 extra_modules/v4l2loopback/README.md create mode 100644 extra_modules/v4l2loopback/TODO create mode 100755 extra_modules/v4l2loopback/currentversion.sh create mode 100644 extra_modules/v4l2loopback/dkms.conf create mode 100644 extra_modules/v4l2loopback/doc/docs.txt create mode 100644 extra_modules/v4l2loopback/doc/kernel_debugging.txt create mode 100755 extra_modules/v4l2loopback/doc/makeformats.sh create mode 100644 extra_modules/v4l2loopback/doc/missingformats.h create mode 100644 extra_modules/v4l2loopback/doc/v4l2_formats.txt create mode 100644 extra_modules/v4l2loopback/examples/.gitignore create mode 100644 extra_modules/v4l2loopback/examples/Makefile create mode 100644 extra_modules/v4l2loopback/examples/README create mode 100755 extra_modules/v4l2loopback/examples/ondemandcam.c create mode 100755 extra_modules/v4l2loopback/examples/restarting-writer.sh create mode 100644 extra_modules/v4l2loopback/examples/test.c create mode 100644 extra_modules/v4l2loopback/examples/yuv4mpeg_to_v4l2.c create mode 100644 extra_modules/v4l2loopback/man/touch create mode 100755 extra_modules/v4l2loopback/release.sh create mode 100644 extra_modules/v4l2loopback/tests/Makefile create mode 100755 extra_modules/v4l2loopback/tests/interlaced_w create mode 100644 extra_modules/v4l2loopback/tests/test_dqbuf.c create mode 100755 extra_modules/v4l2loopback/utils/v4l2loopback-ctl create mode 100644 extra_modules/v4l2loopback/v4l2loopback.c create mode 100644 extra_modules/v4l2loopback/v4l2loopback_formats.h delete mode 160000 v4l2loopback diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index d0e65c24..6b7385ff 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -236,10 +236,10 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set -# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -1010,7 +1010,7 @@ CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" # CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set +CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set # CONFIG_WIMAX is not set @@ -1282,9 +1282,23 @@ CONFIG_WLAN=y CONFIG_USB_ZD1201=m # CONFIG_USB_NET_RNDIS_WLAN is not set CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y # CONFIG_MAC80211_HWSIM is not set # CONFIG_WIFI_CONTROL_FUNC is not set -# CONFIG_ATH_COMMON is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set # CONFIG_B43 is not set # CONFIG_B43LEGACY is not set CONFIG_BCMDHD=m diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 3f15ff9e..6b7385ff 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -236,10 +236,10 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set -# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -1010,7 +1010,7 @@ CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" # CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set +CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set # CONFIG_WIMAX is not set @@ -1282,9 +1282,23 @@ CONFIG_WLAN=y CONFIG_USB_ZD1201=m # CONFIG_USB_NET_RNDIS_WLAN is not set CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y # CONFIG_MAC80211_HWSIM is not set # CONFIG_WIFI_CONTROL_FUNC is not set -# CONFIG_ATH_COMMON is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set # CONFIG_B43 is not set # CONFIG_B43LEGACY is not set CONFIG_BCMDHD=m @@ -2666,7 +2680,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=y +CONFIG_RTC_DRV_SUNXI=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set diff --git a/build/sun8iw7p1smp_lobo_defconfig.old- b/build/sun8iw7p1smp_lobo_defconfig.old- deleted file mode 100644 index 3049fa80..00000000 --- a/build/sun8iw7p1smp_lobo_defconfig.old- +++ /dev/null @@ -1,3263 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/arm 3.4.39-02-lobo Kernel Configuration -# -CONFIG_ARM=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_USES_GETTIMEOFFSET is not set -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_KTIME_SCALAR=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_ARCH_HAS_CPUFREQ=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_NEED_MACH_IO_H=y -CONFIG_NEED_MACH_MEMORY_H=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_XZ is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_DEFAULT_HOSTNAME="sun8i" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_FHANDLE=y -# CONFIG_TASKSTATS is not set -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=y -# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_IRQ_DOMAIN=y -# CONFIG_IRQ_DOMAIN_DEBUG is not set - -# -# RCU Subsystem -# -CONFIG_TREE_PREEMPT_RCU=y -CONFIG_PREEMPT_RCU=y -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_RCU_BOOST is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y -CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_CFS_BANDWIDTH is not set -CONFIG_RT_GROUP_SCHED=y -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -# CONFIG_CHECKPOINT_RESTORE is not set -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="output/rootfs.cpio.gz" -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_ROOT_GID=0 -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y -# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=0 -CONFIG_EXPERT=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_COMPAT_BRK=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_JUMP_LABEL=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_DEV_THROTTLING is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -CONFIG_ACORN_PARTITION=y -# CONFIG_ACORN_PARTITION_CUMANA is not set -# CONFIG_ACORN_PARTITION_EESOX is not set -CONFIG_ACORN_PARTITION_ICS=y -# CONFIG_ACORN_PARTITION_ADFS is not set -# CONFIG_ACORN_PARTITION_POWERTEC is not set -CONFIG_ACORN_PARTITION_RISCIX=y -CONFIG_OSF_PARTITION=y -CONFIG_AMIGA_PARTITION=y -CONFIG_ATARI_PARTITION=y -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -CONFIG_LDM_PARTITION=y -# CONFIG_LDM_DEBUG is not set -CONFIG_SGI_PARTITION=y -CONFIG_ULTRIX_PARTITION=y -CONFIG_SUN_PARTITION=y -CONFIG_KARMA_PARTITION=y -CONFIG_EFI_PARTITION=y -CONFIG_SYSV68_PARTITION=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_CFQ_GROUP_IOSCHED is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_UNINLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_UNLOCK is not set -# CONFIG_INLINE_READ_UNLOCK_BH is not set -# CONFIG_INLINE_READ_UNLOCK_IRQ is not set -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_UNLOCK is not set -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -CONFIG_ARCH_SUNXI=y -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_HIGHBANK is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_PRIMA2 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_PICOXCELL is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P64X0 is not set -# CONFIG_ARCH_S5PC100 is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_ARCH_ZYNQ is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set - -# -# System MMU -# -CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 -CONFIG_ARCH_SUN8I=y -# CONFIG_ARCH_SUN9I is not set -# CONFIG_ARCH_SUN8IW1 is not set -# CONFIG_ARCH_SUN8IW3 is not set -# CONFIG_ARCH_SUN8IW5 is not set -# CONFIG_ARCH_SUN8IW6 is not set -CONFIG_ARCH_SUN8IW7=y -# CONFIG_ARCH_SUN8IW8 is not set -# CONFIG_ARCH_SUN8IW9 is not set -CONFIG_ARCH_SUN8IW7P1=y -# CONFIG_FPGA_V4_PLATFORM is not set -# CONFIG_FPGA_V7_PLATFORM is not set -CONFIG_EVB_PLATFORM=y - -# -# Power management -# - -# -# Common Features Selection -# - -# -# Boot Options -# -# CONFIG_SUNXI_TRUSTZONE is not set -CONFIG_HOMLET_PLATFORM=y -# CONFIG_SUNXI_BOOTUP_EXTEND is not set -CONFIG_SUNXI_OOPS_HOOK=y - -# -# Processor Type -# -CONFIG_CPU_V7=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_SWP_EMULATE=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARM_NR_BANKS=8 -CONFIG_CPU_HAS_PMU=y -CONFIG_MULTI_IRQ_HANDLER=y -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_742230 is not set -# CONFIG_ARM_ERRATA_742231 is not set -# CONFIG_ARM_ERRATA_720789 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_751472 is not set -# CONFIG_ARM_ERRATA_754322 is not set -# CONFIG_ARM_ERRATA_754327 is not set -# CONFIG_ARM_ERRATA_764369 is not set -# CONFIG_ARM_ERRATA_775420 is not set -CONFIG_ARM_GIC=y -# CONFIG_FIQ_DEBUGGER is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_HAVE_SMP=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_ARM_CPU_TOPOLOGY=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y -# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set -CONFIG_HAVE_ARM_SCU=y -CONFIG_ARM_ARCH_TIMER=y -# CONFIG_MCPM is not set -# CONFIG_BIG_LITTLE is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_NR_CPUS=4 -CONFIG_HOTPLUG_CPU=y -CONFIG_ARCH_NR_GPIO=2048 -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -CONFIG_HZ=100 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HW_PERF_EVENTS=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 -# CONFIG_CLEANCACHE is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_SECCOMP is not set -# CONFIG_CC_STACKPROTECTOR is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set -CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y - -# -# Boot options -# -# CONFIG_USE_OF is not set -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init" -# CONFIG_CMDLINE_FROM_BOOTLOADER is not set -# CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE_FORCE=y -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_AUTO_ZRELADDR is not set - -# -# CPU Power Management -# - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_STAT_DETAILS=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_INTERACTIVE=y -# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y - -# -# ARM CPU frequency scaling drivers -# -CONFIG_ARM_SUNXI_CPUFREQ=y -# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set -# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set -# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set - -# -# CPU Idle -# -# CONFIG_CPU_IDLE is not set -# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -# CONFIG_WAKELOCK is not set -CONFIG_SCENELOCK=y -CONFIG_USER_SCENELOCK=y -# CONFIG_HIBERNATION is not set -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_WAKELOCKS is not set -CONFIG_PM_RUNTIME=y -CONFIG_PM=y -CONFIG_PM_DEBUG=y -CONFIG_PM_ADVANCED_DEBUG=y -# CONFIG_PM_TEST_SUSPEND is not set -CONFIG_CAN_PM_TRACE=y -CONFIG_APM_EMULATION=y -CONFIG_PM_CLK=y -CONFIG_CPU_PM=y -CONFIG_SUSPEND_TIME=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -# CONFIG_UNIX_DIAG is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set -CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPGRE=y -# CONFIG_NET_IPGRE_BROADCAST is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_ANDROID_PARANOID_NETWORK is not set -CONFIG_NET_ACTIVITY_STATS=y -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=y -# CONFIG_NETFILTER_NETLINK_ACCT is not set -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_PROCFS=y -CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_BROADCAST=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -# CONFIG_NF_CONNTRACK_SNMP is not set -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -CONFIG_NETFILTER_TPROXY=y -CONFIG_NETFILTER_XTABLES=y - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=y -CONFIG_NETFILTER_XT_CONNMARK=y - -# -# Xtables targets -# -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set - -# -# Xtables matches -# -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ECN=y -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_HL=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -CONFIG_NETFILTER_XT_MATCH_POLICY=y -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QTAGUID=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -# CONFIG_IP_SET is not set -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_REJECT_SKERR=y -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=y -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_GRE=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_FTP=y -CONFIG_NF_NAT_IRC=y -CONFIG_NF_NAT_TFTP=y -CONFIG_NF_NAT_AMANDA=y -CONFIG_NF_NAT_PPTP=y -CONFIG_NF_NAT_H323=y -# CONFIG_NF_NAT_SIP is not set -CONFIG_IP_NF_MANGLE=y -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=y -CONFIG_NF_CONNTRACK_IPV6=y -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=y -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y -CONFIG_IP6_NF_TARGET_REJECT_SKERR=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -# CONFIG_BRIDGE_NF_EBTABLES is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_L2TP=y -# CONFIG_L2TP_DEBUGFS is not set -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=y -CONFIG_L2TP_ETH=y -CONFIG_STP=m -CONFIG_GARP=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=m -CONFIG_VLAN_8021Q_GVRP=y -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -# CONFIG_NET_SCH_CBQ is not set -CONFIG_NET_SCH_HTB=y -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_PLUG is not set - -# -# Classification -# -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_CGROUP is not set -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_NBYTE is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_TEXT is not set -CONFIG_NET_CLS_ACT=y -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set -# CONFIG_OPENVSWITCH is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -# CONFIG_NETPRIO_CGROUP is not set -CONFIG_BQL=y -CONFIG_HAVE_BPF_JIT=y -# CONFIG_BPF_JIT is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIBTUSB=m -# CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set -CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m -CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=y -# CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_REG_DEBUG is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set -CONFIG_MAC80211=m -CONFIG_MAC80211_HAS_RC=y -# CONFIG_MAC80211_RC_PID is not set -CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_MINSTREL_HT=y -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_NFC is not set - -# -# Device Drivers -# -CONFIG_SUNXI_ARISC=y - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=16 -CONFIG_CMA_RESERVE_BASE=0x43400000 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=0 -CONFIG_CMA_AREAS=7 -CONFIG_SYNC=y -CONFIG_SW_SYNC=y -# CONFIG_SW_SYNC_USER is not set - -# -# Bus devices -# -CONFIG_SUNXI_MBUS=y -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -CONFIG_BLK_DEV_CRYPTOLOOP=y - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -# CONFIG_BLK_DEV_RBD is not set - -# -# Misc devices -# -# CONFIG_SUNXI_VIBRATOR is not set -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_AD525X_DPOT is not set -# CONFIG_ATMEL_PWM is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_SENSORS_AK8975 is not set -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -CONFIG_UID_STAT=y -# CONFIG_BMP085 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_SUNXI_BROM_READ is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=m -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_IWMC3200TOP is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -# CONFIG_SW_3G_MODULE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -# CONFIG_MULTICORE_RAID456 is not set -CONFIG_MD_MULTIPATH=m -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=y -CONFIG_DM_SNAPSHOT=m -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_MIRROR is not set -CONFIG_DM_RAID=m -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_DM_VERITY is not set -CONFIG_NETDEVICES=y -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -# CONFIG_DUMMY is not set -# CONFIG_EQUALIZER is not set -CONFIG_MII=y -# CONFIG_IFB is not set -# CONFIG_NET_TEAM is not set -CONFIG_MACVLAN=m -# CONFIG_MACVTAP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_TUN=y -CONFIG_VETH=m - -# -# CAIF transport drivers -# -CONFIG_ETHERNET=y -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_CALXEDA_XGMAC is not set -CONFIG_NET_VENDOR_CHELSIO=y -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_DM9000 is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_INTEL is not set -CONFIG_NET_VENDOR_MARVELL=y -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_ETHOC is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -CONFIG_NET_VENDOR_SUNXI=y -CONFIG_SUNXI_GETH=y -CONFIG_GETH_SCRIPT_SYS=y -CONFIG_GETH_CLK_SYS=y -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_AMD_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MICREL_KS8995MA is not set -CONFIG_PPP=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=y -CONFIG_PPTP=y -CONFIG_PPPOL2TP=y -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=y -# CONFIG_SLIP is not set -CONFIG_SLHC=y - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_QF9700=m -CONFIG_USB_NET_CDCETHER=m -# CONFIG_USB_NET_CDC_EEM is not set -# CONFIG_USB_NET_CDC_NCM is not set -# CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_SMSC75XX is not set -# CONFIG_USB_NET_SMSC95XX is not set -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -CONFIG_USB_NET_MCS7830=m -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_USB_NET_CX82310_ETH is not set -# CONFIG_USB_NET_KALMIA is not set -# CONFIG_USB_NET_QMI_WWAN is not set -# CONFIG_USB_NET_INT51X1 is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_USB_SIERRA_NET is not set -# CONFIG_USB_VL600 is not set -CONFIG_WLAN=y -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_AT76C50X_USB is not set -CONFIG_USB_ZD1201=m -# CONFIG_USB_NET_RNDIS_WLAN is not set -CONFIG_RTL8187=m -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_WIFI_CONTROL_FUNC is not set -# CONFIG_ATH_COMMON is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -CONFIG_BCMDHD=m -CONFIG_BCMDHD_FW_PATH=y -CONFIG_BCMDHD_NVRAM_PATH=y -CONFIG_BCMDHD_CONFIG_PATH=y -CONFIG_BCMDHD_OOB=y -# CONFIG_BCMDHD_SDIO_IRQ is not set -# CONFIG_AP6210 is not set -# CONFIG_BRCMFMAC is not set -# CONFIG_HOSTAP is not set -# CONFIG_IWM is not set -# CONFIG_LIBERTAS is not set -# CONFIG_P54_COMMON is not set -CONFIG_RT2X00=m -# CONFIG_RT2500USB is not set -# CONFIG_RT73USB is not set -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT33XX=y -CONFIG_RT2800USB_RT35XX=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_UNKNOWN=y -CONFIG_RT2800_LIB=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTLWIFI_DEBUG=y -CONFIG_RTL8192C_COMMON=m -# CONFIG_WL1251 is not set -# CONFIG_WL12XX_MENU is not set -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_MWIFIEX is not set -CONFIG_RTL8188EU=m -CONFIG_RTL8189ES=m -CONFIG_RTL8723BS=m - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_POLLDEV=y -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_APMPOWER is not set -# CONFIG_INPUT_KEYRESET is not set -CONFIG_INPUT_SW_DEVICE=m - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_XTKBD is not set -CONFIG_KEYBOARD_SUNXI=y -CONFIG_IR_RX_SUNXI=m -# CONFIG_SUNXI_ANYIR_SUPPORT is not set -# CONFIG_IR_TX_SUNXI is not set -# CONFIG_SUNXI_GPIO_KEY is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_JOYSTICK=y -# CONFIG_JOYSTICK_ANALOG is not set -# CONFIG_JOYSTICK_A3D is not set -# CONFIG_JOYSTICK_ADI is not set -# CONFIG_JOYSTICK_COBRA is not set -# CONFIG_JOYSTICK_GF2K is not set -# CONFIG_JOYSTICK_GRIP is not set -# CONFIG_JOYSTICK_GRIP_MP is not set -# CONFIG_JOYSTICK_GUILLEMOT is not set -# CONFIG_JOYSTICK_INTERACT is not set -# CONFIG_JOYSTICK_SIDEWINDER is not set -# CONFIG_JOYSTICK_TMDC is not set -# CONFIG_JOYSTICK_IFORCE is not set -# CONFIG_JOYSTICK_WARRIOR is not set -# CONFIG_JOYSTICK_MAGELLAN is not set -# CONFIG_JOYSTICK_SPACEORB is not set -# CONFIG_JOYSTICK_SPACEBALL is not set -# CONFIG_JOYSTICK_STINGER is not set -# CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set -# CONFIG_JOYSTICK_AS5011 is not set -# CONFIG_JOYSTICK_JOYDUMP is not set -# CONFIG_JOYSTICK_XPAD is not set -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_ADS7846 is not set -# CONFIG_TOUCHSCREEN_AD7877 is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_ILI210X is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -CONFIG_TOUCHSCREEN_USB_EGALAX=y -CONFIG_TOUCHSCREEN_USB_PANJIT=y -CONFIG_TOUCHSCREEN_USB_3M=y -CONFIG_TOUCHSCREEN_USB_ITM=y -CONFIG_TOUCHSCREEN_USB_ETURBO=y -CONFIG_TOUCHSCREEN_USB_GUNZE=y -CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y -CONFIG_TOUCHSCREEN_USB_IRTOUCH=y -CONFIG_TOUCHSCREEN_USB_IDEALTEK=y -CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y -CONFIG_TOUCHSCREEN_USB_GOTOP=y -CONFIG_TOUCHSCREEN_USB_JASTEC=y -CONFIG_TOUCHSCREEN_USB_ELO=y -CONFIG_TOUCHSCREEN_USB_E2I=y -CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y -CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y -CONFIG_TOUCHSCREEN_USB_NEXIO=y -CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_TPS6507X is not set -CONFIG_TOUCHSCREEN_GT82X=m -# CONFIG_TOUCHSCREEN_SUN6I_TS is not set -CONFIG_TOUCHSCREEN_FT5X_TS=m -CONFIG_TOUCHSCREEN_GT9XX_TS=m -CONFIG_TOUCHSCREEN_GT9XXF_TS=m -CONFIG_TOUCHSCREEN_GSLX680=m -CONFIG_TOUCHSCREEN_GSLX680NEW=m -CONFIG_TOUCHSCREEN_AW5X06_TS=m -CONFIG_TOUCHSCREEN_GT818_TS=m -CONFIG_TOUCHSCREEN_TU_TS=m -CONFIG_TOUCHSCREEN_ICN83XX_TS=m -CONFIG_INPUT_MISC=y -# CONFIG_E_COMPASS_L3M303D is not set -# CONFIG_E_COMPASS_FXOS8700 is not set -# CONFIG_E_COMPASS_AKM8963 is not set -# CONFIG_GYR_L3GD20 is not set -# CONFIG_GYR_BMG160 is not set -CONFIG_INPUT_LTR501ALS=y -# CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_MPU3050 is not set -# CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_TILT_POLLED is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYCHORD is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_UINPUT=y -# CONFIG_INPUT_GPIO is not set -# CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -# CONFIG_INPUT_ADXL34X is not set -# CONFIG_INPUT_CMA3000 is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=m -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_UNIX98_PTYS=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=0 -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_CONSOLE_POLL=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -CONFIG_SERIAL_SUNXI=y -CONFIG_SERIAL_SUNXI_CONSOLE=y -# CONFIG_SERIAL_DEBUG is not set -# CONFIG_TTY_PRINTK is not set -# CONFIG_HVC_DCC is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_DCC_TTY is not set -# CONFIG_RAMOOPS is not set -# CONFIG_SUNXI_D7S is not set -CONFIG_SUNXI_CMATESET=y -# CONFIG_SUNXI_ARISC_TEST is not set -# CONFIG_SUNXI_MODULE is not set -# CONFIG_SUNXI_TIMER_TEST is not set -# CONFIG_SUNXI_DMA_TEST is not set -CONFIG_SUNXI_SCR=m -CONFIG_SUNXI_DI=m -CONFIG_SUNXI_SOC_INFO=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_MUX is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -CONFIG_I2C_SUNXI=y -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_PXA2XX_PCI is not set -CONFIG_SPI_SUNXI=y -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=y -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_HSI is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# - -# -# PTP clock support -# - -# -# Enable Device Drivers -> PPS to see the PTP clock options. -# -CONFIG_PINCTRL=y - -# -# Pin controllers -# -CONFIG_PINMUX=y -CONFIG_PINCONF=y -CONFIG_GENERIC_PINCONF=y -# CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_SUNXI=y -# CONFIG_PINCTRL_SUNXI_DEBUG is not set -# CONFIG_SUNXI_PINCTRL_TEST is not set -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO drivers: -# -# CONFIG_GPIO_GENERIC_PLATFORM is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -CONFIG_GPIO_SUNXI=m -CONFIG_W1=m -CONFIG_W1_SUNXI=m - -# -# 1-wire Bus Masters -# -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS1WM is not set -CONFIG_W1_MASTER_GPIO=m - -# -# 1-wire Slaves -# -CONFIG_W1_SLAVE_THERM=m -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2408 is not set -# CONFIG_W1_SLAVE_DS2423 is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_BQ27000 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# CONFIG_SENSORS_KIONIX is not set -# CONFIG_SENSORS_MMA7660 is not set -# CONFIG_SENSORS_MMA865x is not set -# CONFIG_SENSORS_MMA8452 is not set -# CONFIG_SENSORS_AFA750 is not set -# CONFIG_SENSORS_BMA250 is not set -# CONFIG_SENSORS_LIS3DH_ACC is not set -# CONFIG_SENSORS_LIS3DE_ACC is not set -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_GPIO_FAN is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4151 is not set -# CONFIG_SENSORS_LTC4215 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LTC4261 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_MCP3021 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_PMBUS is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_SCH5636 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set - -# -# INA219 drivers -# -# CONFIG_SENSORS_INA219 is not set -# CONFIG_SENSORS_DUMMY_ACC is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_FAIR_SHARE is not set -CONFIG_STEP_WISE=y -# CONFIG_USER_SPACE is not set -# CONFIG_SUNXI_THERMAL_DYNAMIC is not set -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_BUDGET_THERMAL=y -CONFIG_SUNXI_THERMAL=y -CONFIG_SUNXI_BUDGET_COOLING=y -# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_CORE is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=y - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -CONFIG_BCMA_POSSIBLE=y - -# -# Broadcom specific AMBA -# -# CONFIG_BCMA is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL6040_CORE is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_S5M_CORE is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_AC100 is not set -# CONFIG_MFD_AC200 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_REGULATOR is not set -CONFIG_PWM=y -CONFIG_PWM_SUNXI=m -CONFIG_MEDIA_SUPPORT=y - -# -# Multimedia core support -# -# CONFIG_MEDIA_CONTROLLER is not set -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=y - -# -# Multimedia drivers -# -CONFIG_RC_CORE=y -CONFIG_LIRC=y -CONFIG_RC_MAP=y -# CONFIG_IR_NEC_DECODER is not set -# CONFIG_IR_RC5_DECODER is not set -# CONFIG_IR_RC6_DECODER is not set -# CONFIG_IR_JVC_DECODER is not set -# CONFIG_IR_SONY_DECODER is not set -# CONFIG_IR_RC5_SZ_DECODER is not set -# CONFIG_IR_SANYO_DECODER is not set -# CONFIG_IR_MCE_KBD_DECODER is not set -# CONFIG_IR_LIRC_CODEC is not set -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_STREAMZAP is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_IR_GPIO_CIR is not set -# CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=y -CONFIG_MEDIA_TUNER_CUSTOMISE=y - -# -# Customize TV tuners -# -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set -# CONFIG_VIDEO_IR_I2C is not set - -# -# Encoders, decoders, sensors and other helper chips -# - -# -# Audio decoders, processors and mixers -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set - -# -# RDS decoders -# -# CONFIG_VIDEO_SAA6588 is not set - -# -# Video decoders -# -# CONFIG_VIDEO_ADV7180 is not set -# CONFIG_VIDEO_ADV7183 is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7191 is not set -# CONFIG_VIDEO_TVP514X is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_TVP7002 is not set -# CONFIG_VIDEO_VPX3220 is not set - -# -# Video and audio decoders -# -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_CX25840 is not set - -# -# MPEG video encoders -# -# CONFIG_VIDEO_CX2341X is not set - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_AK881X is not set - -# -# Camera sensor devices -# -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_VS6624 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_SR030PC30 is not set - -# -# Flash devices -# - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set - -# -# Miscelaneous helper chips -# -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_VIVI is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_GSPCA is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_HDPVR is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_CX231XX is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_PWC is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set -CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_VIDEO_TIMBERDALE is not set -# CONFIG_SOC_CAMERA is not set -CONFIG_VIDEO_SUNXI_VFE=m -CONFIG_CSI_VFE=m -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -CONFIG_AW_TSC=y -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_KEENE is not set -# CONFIG_RADIO_TEA5764 is not set -# CONFIG_RADIO_SAA7706H is not set -# CONFIG_RADIO_TEF6862 is not set -# CONFIG_RADIO_WL1273 is not set - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y - -# -# Graphics support -# -CONFIG_DRM=m -# CONFIG_DRM_UDL is not set -CONFIG_ION=y -CONFIG_ION_SUNXI=y -CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_WMT_GE_ROPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# - -# -# Video support for sunxi -# -CONFIG_FB_CONSOLE_SUNXI=y -CONFIG_DISP2_SUNXI=y -CONFIG_HDMI_DISP2_SUNXI=y -CONFIG_TV_DISP2_SUNXI=m -# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set -CONFIG_DISP2_SUNXI_DEBUG=y -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_EXYNOS_VIDEO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set -# CONFIG_LOGO is not set -CONFIG_SOUND=y -# CONFIG_SOUND_OSS_CORE is not set -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=y -CONFIG_SND_JACK=y -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_RAWMIDI_SEQ is not set -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_ALOOP is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -CONFIG_SND_ARM=y -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=m -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_6FIRE is not set -CONFIG_SND_SOC=y -CONFIG_SND_SOC_DMAENGINE_PCM=y -CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y -CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y -CONFIG_SND_SUN8IW7_SNDCODEC=y -# CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE is not set -# CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE is not set -# CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE is not set -CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y -CONFIG_SND_SUN8IW7_HDMIPCM=y -CONFIG_SND_SUNXI_SOC_SPDIF=m -# CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE is not set -# CONFIG_SND_SUN8IW7_AUDIOHUB is not set -# CONFIG_SND_SUNXI_SOC_SUPPORT_AUDIO_RAW is not set -CONFIG_SND_SOC_I2C_AND_SPI=y -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -CONFIG_HIDRAW=y -CONFIG_UHID=y - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_REMOTE_WAKEUP is not set -# CONFIG_HID_PID is not set -CONFIG_USB_HIDDEV=y - -# -# Special HID drivers -# -CONFIG_HID_A4TECH=y -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -CONFIG_HID_PRODIKEYS=y -# CONFIG_HID_CYPRESS is not set -CONFIG_HID_DRAGONRISE=y -# CONFIG_DRAGONRISE_FF is not set -CONFIG_HID_EMS_FF=y -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_EZKEY is not set -CONFIG_HID_HOLTEK=y -# CONFIG_HOLTEK_FF is not set -CONFIG_HID_KEYTOUCH=y -# CONFIG_HID_KYE is not set -CONFIG_HID_UCLOGIC=y -CONFIG_HID_WALTOP=y -CONFIG_HID_GYRATION=y -CONFIG_HID_TWINHAN=y -# CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LCPOWER=y -CONFIG_HID_LOGITECH=y -# CONFIG_HID_LOGITECH_DJ is not set -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIWHEELS_FF is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -CONFIG_HID_MULTITOUCH=y -CONFIG_HID_NTRIG=y -CONFIG_HID_ORTEK=y -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -# CONFIG_HID_PICOLCD is not set -CONFIG_HID_PRIMAX=y -CONFIG_HID_ROCCAT=y -# CONFIG_HID_SAITEK is not set -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SPEEDLINK=y -CONFIG_HID_SUNPLUS=y -CONFIG_HID_GREENASIA=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_SMARTJOYPLUS=y -# CONFIG_SMARTJOYPLUS_FF is not set -# CONFIG_HID_TIVO is not set -CONFIG_HID_TOPSEED=y -CONFIG_HID_THRUSTMASTER=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WIIMOTE is not set -CONFIG_HID_ZEROPLUS=y -# CONFIG_ZEROPLUS_FF is not set -CONFIG_HID_ZYDACRON=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB_ARCH_HAS_XHCI=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_SUSPEND=y -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_SUNXI is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_XHCI_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PLATFORM is not set -CONFIG_USB_EHCI_HCD_PLATFORM=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_SUNXI_HCD=y -CONFIG_USB_SUNXI_HCD0=y -CONFIG_USB_SUNXI_HCI=y -CONFIG_USB_SUNXI_EHCI0=y -CONFIG_USB_SUNXI_EHCI1=y -CONFIG_USB_SUNXI_OHCI0=y -CONFIG_USB_SUNXI_OHCI1=y -CONFIG_USB_SUNXI_EHCI2=y -CONFIG_USB_SUNXI_OHCI2=y -CONFIG_USB_SUNXI_EHCI3=y -CONFIG_USB_SUNXI_OHCI3=y -CONFIG_USB_SUNXI_HSIC=y -# CONFIG_SW_USB_3G is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_RENESAS_USBHS is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=y -# CONFIG_USB_SERIAL_CONSOLE is not set -# CONFIG_USB_EZUSB is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -CONFIG_USB_SERIAL_CH341=m -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -CONFIG_USB_SERIAL_CP210X=m -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -CONFIG_USB_SERIAL_FTDI_SIO=m -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_F81232 is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_METRO is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MOTOROLA is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIEMENS_MPI is not set -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -CONFIG_USB_SERIAL_WWAN=y -CONFIG_USB_SERIAL_OPTION=y -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set -# CONFIG_USB_SERIAL_ZIO is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_DEBUG is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -# CONFIG_USB_FUSB300 is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_M66592 is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_DUMMY_HCD is not set -CONFIG_USB_SUNXI_UDC0=y -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_G_NCM is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -CONFIG_USB_G_ANDROID=y -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_G_MULTI is not set -# CONFIG_USB_G_HID is not set -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_WEBCAM is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ULPI is not set -# CONFIG_NOP_USB_XCEIV is not set -CONFIG_USB_SUNXI_USB=y -CONFIG_USB_SUNXI_USB_MANAGER=y -# CONFIG_USB_SUNXI_USB0_NULL is not set -# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set -# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set -CONFIG_USB_SUNXI_USB0_OTG=y -CONFIG_USB_SUNXI_USB_DEBUG=y -CONFIG_USB_SUNXI_HOST=y -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_CLKGATE is not set -# CONFIG_MMC_EMBEDDED_SDIO is not set -CONFIG_MMC_PARANOID_SD_INIT=y - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=16 -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_SDHCI_PXAV3 is not set -# CONFIG_MMC_SDHCI_PXAV2 is not set -# CONFIG_MMC_DW is not set -CONFIG_MMC_SUNXI=y -# CONFIG_MMC_DEBUG_SUNXI is not set -CONFIG_MMC_PRE_DBGLVL_SUNXI=0 -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -CONFIG_SUNXI_LEDS=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA9633 is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_RENESAS_TPU is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_OT200 is not set -CONFIG_LEDS_TRIGGERS=y - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set - -# -# iptables trigger is under Netfilter config (LED target) -# -# CONFIG_SWITCH is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_SUNXI=y -CONFIG_DMADEVICES=y -# CONFIG_DMADEVICES_DEBUG is not set - -# -# DMA Devices -# -# CONFIG_DW_DMAC is not set -# CONFIG_TIMB_DMA is not set -CONFIG_DMA_ENGINE=y -CONFIG_DMA_VIRTUAL_CHANNELS=y - -# -# DMA Clients -# -# CONFIG_NET_DMA is not set -# CONFIG_ASYNC_TX_DMA is not set -CONFIG_SUNXI_DMA=y -# CONFIG_DMATEST is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# Virtio drivers -# -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_MMIO is not set - -# -# Microsoft Hyper-V guest support -# -# CONFIG_STAGING is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_COMMON_CLK=y - -# -# Common Clock Framework -# -# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set -CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y -CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y -CONFIG_COMMON_CLK_DEBUG=y - -# -# SUNXI Clock Configuration -# -CONFIG_SUNXI_CLK_DEFAULT_INIT=y -CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y -CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 -CONFIG_AHB1_CLK_DFT_VALUE=200000000 -CONFIG_APB1_CLK_DFT_VALUE=100000000 - -# -# Hardware Spinlock drivers -# -CONFIG_CLKSRC_MMIO=y -CONFIG_SUNXI_TIMER=y -# CONFIG_IOMMU_SUPPORT is not set - -# -# Remoteproc drivers (EXPERIMENTAL) -# - -# -# Rpmsg drivers (EXPERIMENTAL) -# -# CONFIG_VIRT_DRIVERS is not set -CONFIG_PM_DEVFREQ=y - -# -# DEVFREQ Governors -# -# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -CONFIG_DEVFREQ_GOV_USERSPACE=y - -# -# DEVFREQ Drivers -# -CONFIG_DEVFREQ_DRAM_FREQ=y -# CONFIG_DRAM_FREQ_BSP_TEST is not set -# CONFIG_GATOR_PERF is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_FANOTIFY=y -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y -CONFIG_CUSE=y -CONFIG_GENERIC_ACL=y - -# -# Caches -# -CONFIG_FSCACHE=y -CONFIG_FSCACHE_STATS=y -# CONFIG_FSCACHE_HISTOGRAM is not set -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_OBJECT_LIST is not set -CONFIG_CACHEFILES=y -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_XATTR=y -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -CONFIG_CRAMFS=y -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y -CONFIG_SQUASHFS_EMBEDDED=y -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_V4_1 is not set -# CONFIG_NFS_FSCACHE is not set -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFSD=y -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_FAULT_INJECTION=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_DEBUG is not set -# CONFIG_CEPH_FS is not set -CONFIG_CIFS=y -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_UPCALL is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_DFS_UPCALL is not set -# CONFIG_CIFS_FSCACHE is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -CONFIG_NLS_CODEPAGE_936=y -CONFIG_NLS_CODEPAGE_950=y -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y - -# -# Kernel hacking -# -CONFIG_PRINTK_TIME=y -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOCKUP_DETECTOR=y -# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set -CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y -CONFIG_HARDLOCKUP_DETECTOR=y -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -CONFIG_FRAME_POINTER=y -CONFIG_BOOT_PRINTK_DELAY=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=20 -CONFIG_RCU_CPU_STALL_VERBOSE=y -CONFIG_RCU_CPU_STALL_INFO=y -# CONFIG_RCU_TRACE is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_LKDTM is not set -# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_TRACER_MAX_TRACE=y -CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_EVENT_POWER_TRACING_DEPRECATED=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y -CONFIG_GENERIC_TRACER=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -CONFIG_FUNCTION_TRACER=y -CONFIG_FUNCTION_GRAPH_TRACER=y -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -CONFIG_SCHED_TRACER=y -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -CONFIG_STACK_TRACER=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_DYNAMIC_FTRACE=y -CONFIG_FUNCTION_PROFILER=y -CONFIG_FTRACE_MCOUNT_RECORD=y -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_KGDB=y -CONFIG_KGDB_SERIAL_CONSOLE=y -# CONFIG_KGDB_TESTS is not set -CONFIG_KGDB_KDB=y -CONFIG_KDB_KEYBOARD=y -# CONFIG_TEST_KSTRTOX is not set -CONFIG_STRICT_DEVMEM=y -CONFIG_ARM_UNWIND=y -CONFIG_OLD_MCOUNT=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_RODATA is not set -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_SUNXI_UART0=y -# CONFIG_DEBUG_SUNXI_UART1 is not set -# CONFIG_DEBUG_SUNXI_UART2 is not set -# CONFIG_DEBUG_LL_UART_NONE is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -CONFIG_EARLY_PRINTK=y - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_TRUSTED_LITTLE_KERNEL is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_GHASH is not set -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_SUNXI=m -# CONFIG_ASYMMETRIC_KEY_TYPE is not set -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_RAID6_PQ=m -CONFIG_BITREVERSE=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_IO=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -# CONFIG_CRC32_SELFTEST is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC32_SLICEBY4 is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_BIT is not set -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -# CONFIG_CRC8 is not set -CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_XZ_DEC=y -CONFIG_XZ_DEC_X86=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_NLATTR=y -CONFIG_AVERAGE=y -# CONFIG_CORDIC is not set diff --git a/rtl8192cu-fixes/.gitignore b/extra_modules/rtl8192cu-fixes/.gitignore similarity index 100% rename from rtl8192cu-fixes/.gitignore rename to extra_modules/rtl8192cu-fixes/.gitignore diff --git a/rtl8192cu-fixes/8192cu-disable-power-management.conf b/extra_modules/rtl8192cu-fixes/8192cu-disable-power-management.conf similarity index 100% rename from rtl8192cu-fixes/8192cu-disable-power-management.conf rename to extra_modules/rtl8192cu-fixes/8192cu-disable-power-management.conf diff --git a/rtl8192cu-fixes/Makefile b/extra_modules/rtl8192cu-fixes/Makefile similarity index 100% rename from rtl8192cu-fixes/Makefile rename to extra_modules/rtl8192cu-fixes/Makefile diff --git a/rtl8192cu-fixes/README.md b/extra_modules/rtl8192cu-fixes/README.md similarity index 100% rename from rtl8192cu-fixes/README.md rename to extra_modules/rtl8192cu-fixes/README.md diff --git a/rtl8192cu-fixes/blacklist-native-rtl8192.conf b/extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf similarity index 100% rename from rtl8192cu-fixes/blacklist-native-rtl8192.conf rename to extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf diff --git a/rtl8192cu-fixes/clean b/extra_modules/rtl8192cu-fixes/clean similarity index 100% rename from rtl8192cu-fixes/clean rename to extra_modules/rtl8192cu-fixes/clean diff --git a/rtl8192cu-fixes/core/efuse/rtw_efuse.c b/extra_modules/rtl8192cu-fixes/core/efuse/rtw_efuse.c similarity index 100% rename from rtl8192cu-fixes/core/efuse/rtw_efuse.c rename to extra_modules/rtl8192cu-fixes/core/efuse/rtw_efuse.c diff --git a/rtl8192cu-fixes/core/rtw_ap.c b/extra_modules/rtl8192cu-fixes/core/rtw_ap.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_ap.c rename to extra_modules/rtl8192cu-fixes/core/rtw_ap.c diff --git a/rtl8192cu-fixes/core/rtw_br_ext.c b/extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_br_ext.c rename to extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c diff --git a/rtl8192cu-fixes/core/rtw_cmd.c b/extra_modules/rtl8192cu-fixes/core/rtw_cmd.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_cmd.c rename to extra_modules/rtl8192cu-fixes/core/rtw_cmd.c diff --git a/rtl8192cu-fixes/core/rtw_debug.c b/extra_modules/rtl8192cu-fixes/core/rtw_debug.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_debug.c rename to extra_modules/rtl8192cu-fixes/core/rtw_debug.c diff --git a/rtl8192cu-fixes/core/rtw_eeprom.c b/extra_modules/rtl8192cu-fixes/core/rtw_eeprom.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_eeprom.c rename to extra_modules/rtl8192cu-fixes/core/rtw_eeprom.c diff --git a/rtl8192cu-fixes/core/rtw_ieee80211.c b/extra_modules/rtl8192cu-fixes/core/rtw_ieee80211.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_ieee80211.c rename to extra_modules/rtl8192cu-fixes/core/rtw_ieee80211.c diff --git a/rtl8192cu-fixes/core/rtw_io.c b/extra_modules/rtl8192cu-fixes/core/rtw_io.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_io.c rename to extra_modules/rtl8192cu-fixes/core/rtw_io.c diff --git a/rtl8192cu-fixes/core/rtw_ioctl_query.c b/extra_modules/rtl8192cu-fixes/core/rtw_ioctl_query.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_ioctl_query.c rename to extra_modules/rtl8192cu-fixes/core/rtw_ioctl_query.c diff --git a/rtl8192cu-fixes/core/rtw_ioctl_rtl.c b/extra_modules/rtl8192cu-fixes/core/rtw_ioctl_rtl.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_ioctl_rtl.c rename to extra_modules/rtl8192cu-fixes/core/rtw_ioctl_rtl.c diff --git a/rtl8192cu-fixes/core/rtw_ioctl_set.c b/extra_modules/rtl8192cu-fixes/core/rtw_ioctl_set.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_ioctl_set.c rename to extra_modules/rtl8192cu-fixes/core/rtw_ioctl_set.c diff --git a/rtl8192cu-fixes/core/rtw_iol.c b/extra_modules/rtl8192cu-fixes/core/rtw_iol.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_iol.c rename to extra_modules/rtl8192cu-fixes/core/rtw_iol.c diff --git a/rtl8192cu-fixes/core/rtw_mlme.c b/extra_modules/rtl8192cu-fixes/core/rtw_mlme.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_mlme.c rename to extra_modules/rtl8192cu-fixes/core/rtw_mlme.c diff --git a/rtl8192cu-fixes/core/rtw_mlme_ext.c b/extra_modules/rtl8192cu-fixes/core/rtw_mlme_ext.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_mlme_ext.c rename to extra_modules/rtl8192cu-fixes/core/rtw_mlme_ext.c diff --git a/rtl8192cu-fixes/core/rtw_mp.c b/extra_modules/rtl8192cu-fixes/core/rtw_mp.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_mp.c rename to extra_modules/rtl8192cu-fixes/core/rtw_mp.c diff --git a/rtl8192cu-fixes/core/rtw_mp_ioctl.c b/extra_modules/rtl8192cu-fixes/core/rtw_mp_ioctl.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_mp_ioctl.c rename to extra_modules/rtl8192cu-fixes/core/rtw_mp_ioctl.c diff --git a/rtl8192cu-fixes/core/rtw_p2p.c b/extra_modules/rtl8192cu-fixes/core/rtw_p2p.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_p2p.c rename to extra_modules/rtl8192cu-fixes/core/rtw_p2p.c diff --git a/rtl8192cu-fixes/core/rtw_pwrctrl.c b/extra_modules/rtl8192cu-fixes/core/rtw_pwrctrl.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_pwrctrl.c rename to extra_modules/rtl8192cu-fixes/core/rtw_pwrctrl.c diff --git a/rtl8192cu-fixes/core/rtw_recv.c b/extra_modules/rtl8192cu-fixes/core/rtw_recv.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_recv.c rename to extra_modules/rtl8192cu-fixes/core/rtw_recv.c diff --git a/rtl8192cu-fixes/core/rtw_rf.c b/extra_modules/rtl8192cu-fixes/core/rtw_rf.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_rf.c rename to extra_modules/rtl8192cu-fixes/core/rtw_rf.c diff --git a/rtl8192cu-fixes/core/rtw_security.c b/extra_modules/rtl8192cu-fixes/core/rtw_security.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_security.c rename to extra_modules/rtl8192cu-fixes/core/rtw_security.c diff --git a/rtl8192cu-fixes/core/rtw_sreset.c b/extra_modules/rtl8192cu-fixes/core/rtw_sreset.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_sreset.c rename to extra_modules/rtl8192cu-fixes/core/rtw_sreset.c diff --git a/rtl8192cu-fixes/core/rtw_sta_mgt.c b/extra_modules/rtl8192cu-fixes/core/rtw_sta_mgt.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_sta_mgt.c rename to extra_modules/rtl8192cu-fixes/core/rtw_sta_mgt.c diff --git a/rtl8192cu-fixes/core/rtw_tdls.c b/extra_modules/rtl8192cu-fixes/core/rtw_tdls.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_tdls.c rename to extra_modules/rtl8192cu-fixes/core/rtw_tdls.c diff --git a/rtl8192cu-fixes/core/rtw_wlan_util.c b/extra_modules/rtl8192cu-fixes/core/rtw_wlan_util.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_wlan_util.c rename to extra_modules/rtl8192cu-fixes/core/rtw_wlan_util.c diff --git a/rtl8192cu-fixes/core/rtw_xmit.c b/extra_modules/rtl8192cu-fixes/core/rtw_xmit.c similarity index 100% rename from rtl8192cu-fixes/core/rtw_xmit.c rename to extra_modules/rtl8192cu-fixes/core/rtw_xmit.c diff --git a/rtl8192cu-fixes/dkms.conf b/extra_modules/rtl8192cu-fixes/dkms.conf similarity index 100% rename from rtl8192cu-fixes/dkms.conf rename to extra_modules/rtl8192cu-fixes/dkms.conf diff --git a/rtl8192cu-fixes/hal/HalPwrSeqCmd.c b/extra_modules/rtl8192cu-fixes/hal/HalPwrSeqCmd.c similarity index 100% rename from rtl8192cu-fixes/hal/HalPwrSeqCmd.c rename to extra_modules/rtl8192cu-fixes/hal/HalPwrSeqCmd.c diff --git a/rtl8192cu-fixes/hal/dm.c b/extra_modules/rtl8192cu-fixes/hal/dm.c similarity index 100% rename from rtl8192cu-fixes/hal/dm.c rename to extra_modules/rtl8192cu-fixes/hal/dm.c diff --git a/rtl8192cu-fixes/hal/dm.h b/extra_modules/rtl8192cu-fixes/hal/dm.h similarity index 100% rename from rtl8192cu-fixes/hal/dm.h rename to extra_modules/rtl8192cu-fixes/hal/dm.h diff --git a/rtl8192cu-fixes/hal/hal_com.c b/extra_modules/rtl8192cu-fixes/hal/hal_com.c similarity index 100% rename from rtl8192cu-fixes/hal/hal_com.c rename to extra_modules/rtl8192cu-fixes/hal/hal_com.c diff --git a/rtl8192cu-fixes/hal/hal_intf.c b/extra_modules/rtl8192cu-fixes/hal/hal_intf.c similarity index 100% rename from rtl8192cu-fixes/hal/hal_intf.c rename to extra_modules/rtl8192cu-fixes/hal/hal_intf.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_cmd.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_dm.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_hal_init.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_mp.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_phycfg.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rf6052.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_rxdesc.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_sreset.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/rtl8192c_xmit.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_led.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_recv.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/rtl8192cu_xmit.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_halinit.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_ce.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_linux.c diff --git a/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c b/extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c similarity index 100% rename from rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c rename to extra_modules/rtl8192cu-fixes/hal/rtl8192c/usb/usb_ops_xp.c diff --git a/rtl8192cu-fixes/include/Hal8192CEHWImg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192CEHWImg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192CEHWImg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192CEHWImg.h diff --git a/rtl8192cu-fixes/include/Hal8192CPhyCfg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192CPhyCfg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192CPhyCfg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192CPhyCfg.h diff --git a/rtl8192cu-fixes/include/Hal8192CPhyReg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192CPhyReg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192CPhyReg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192CPhyReg.h diff --git a/rtl8192cu-fixes/include/Hal8192CUHWImg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192CUHWImg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192CUHWImg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192CUHWImg.h diff --git a/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h b/extra_modules/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192CUHWImg_wowlan.h diff --git a/rtl8192cu-fixes/include/Hal8192DEHWImg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192DEHWImg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192DEHWImg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192DEHWImg.h diff --git a/rtl8192cu-fixes/include/Hal8192DPhyCfg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192DPhyCfg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192DPhyCfg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192DPhyCfg.h diff --git a/rtl8192cu-fixes/include/Hal8192DPhyReg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192DPhyReg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192DPhyReg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192DPhyReg.h diff --git a/rtl8192cu-fixes/include/Hal8192DUHWImg.h b/extra_modules/rtl8192cu-fixes/include/Hal8192DUHWImg.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192DUHWImg.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192DUHWImg.h diff --git a/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h b/extra_modules/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h similarity index 100% rename from rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h rename to extra_modules/rtl8192cu-fixes/include/Hal8192DUHWImg_wowlan.h diff --git a/rtl8192cu-fixes/include/HalPwrSeqCmd.h b/extra_modules/rtl8192cu-fixes/include/HalPwrSeqCmd.h similarity index 100% rename from rtl8192cu-fixes/include/HalPwrSeqCmd.h rename to extra_modules/rtl8192cu-fixes/include/HalPwrSeqCmd.h diff --git a/rtl8192cu-fixes/include/autoconf.h b/extra_modules/rtl8192cu-fixes/include/autoconf.h similarity index 100% rename from rtl8192cu-fixes/include/autoconf.h rename to extra_modules/rtl8192cu-fixes/include/autoconf.h diff --git a/rtl8192cu-fixes/include/basic_types.h b/extra_modules/rtl8192cu-fixes/include/basic_types.h similarity index 100% rename from rtl8192cu-fixes/include/basic_types.h rename to extra_modules/rtl8192cu-fixes/include/basic_types.h diff --git a/rtl8192cu-fixes/include/byteorder/big_endian.h b/extra_modules/rtl8192cu-fixes/include/byteorder/big_endian.h similarity index 100% rename from rtl8192cu-fixes/include/byteorder/big_endian.h rename to extra_modules/rtl8192cu-fixes/include/byteorder/big_endian.h diff --git a/rtl8192cu-fixes/include/byteorder/generic.h b/extra_modules/rtl8192cu-fixes/include/byteorder/generic.h similarity index 100% rename from rtl8192cu-fixes/include/byteorder/generic.h rename to extra_modules/rtl8192cu-fixes/include/byteorder/generic.h diff --git a/rtl8192cu-fixes/include/byteorder/little_endian.h b/extra_modules/rtl8192cu-fixes/include/byteorder/little_endian.h similarity index 100% rename from rtl8192cu-fixes/include/byteorder/little_endian.h rename to extra_modules/rtl8192cu-fixes/include/byteorder/little_endian.h diff --git a/rtl8192cu-fixes/include/byteorder/swab.h b/extra_modules/rtl8192cu-fixes/include/byteorder/swab.h similarity index 100% rename from rtl8192cu-fixes/include/byteorder/swab.h rename to extra_modules/rtl8192cu-fixes/include/byteorder/swab.h diff --git a/rtl8192cu-fixes/include/byteorder/swabb.h b/extra_modules/rtl8192cu-fixes/include/byteorder/swabb.h similarity index 100% rename from rtl8192cu-fixes/include/byteorder/swabb.h rename to extra_modules/rtl8192cu-fixes/include/byteorder/swabb.h diff --git a/rtl8192cu-fixes/include/circ_buf.h b/extra_modules/rtl8192cu-fixes/include/circ_buf.h similarity index 100% rename from rtl8192cu-fixes/include/circ_buf.h rename to extra_modules/rtl8192cu-fixes/include/circ_buf.h diff --git a/rtl8192cu-fixes/include/cmd_osdep.h b/extra_modules/rtl8192cu-fixes/include/cmd_osdep.h similarity index 100% rename from rtl8192cu-fixes/include/cmd_osdep.h rename to extra_modules/rtl8192cu-fixes/include/cmd_osdep.h diff --git a/rtl8192cu-fixes/include/drv_conf.h b/extra_modules/rtl8192cu-fixes/include/drv_conf.h similarity index 100% rename from rtl8192cu-fixes/include/drv_conf.h rename to extra_modules/rtl8192cu-fixes/include/drv_conf.h diff --git a/rtl8192cu-fixes/include/drv_types.h b/extra_modules/rtl8192cu-fixes/include/drv_types.h similarity index 100% rename from rtl8192cu-fixes/include/drv_types.h rename to extra_modules/rtl8192cu-fixes/include/drv_types.h diff --git a/rtl8192cu-fixes/include/drv_types_ce.h b/extra_modules/rtl8192cu-fixes/include/drv_types_ce.h similarity index 100% rename from rtl8192cu-fixes/include/drv_types_ce.h rename to extra_modules/rtl8192cu-fixes/include/drv_types_ce.h diff --git a/rtl8192cu-fixes/include/drv_types_linux.h b/extra_modules/rtl8192cu-fixes/include/drv_types_linux.h similarity index 100% rename from rtl8192cu-fixes/include/drv_types_linux.h rename to extra_modules/rtl8192cu-fixes/include/drv_types_linux.h diff --git a/rtl8192cu-fixes/include/drv_types_sdio.h b/extra_modules/rtl8192cu-fixes/include/drv_types_sdio.h similarity index 100% rename from rtl8192cu-fixes/include/drv_types_sdio.h rename to extra_modules/rtl8192cu-fixes/include/drv_types_sdio.h diff --git a/rtl8192cu-fixes/include/drv_types_xp.h b/extra_modules/rtl8192cu-fixes/include/drv_types_xp.h similarity index 100% rename from rtl8192cu-fixes/include/drv_types_xp.h rename to extra_modules/rtl8192cu-fixes/include/drv_types_xp.h diff --git a/rtl8192cu-fixes/include/ethernet.h b/extra_modules/rtl8192cu-fixes/include/ethernet.h similarity index 100% rename from rtl8192cu-fixes/include/ethernet.h rename to extra_modules/rtl8192cu-fixes/include/ethernet.h diff --git a/rtl8192cu-fixes/include/h2clbk.h b/extra_modules/rtl8192cu-fixes/include/h2clbk.h similarity index 100% rename from rtl8192cu-fixes/include/h2clbk.h rename to extra_modules/rtl8192cu-fixes/include/h2clbk.h diff --git a/rtl8192cu-fixes/include/hal_com.h b/extra_modules/rtl8192cu-fixes/include/hal_com.h similarity index 100% rename from rtl8192cu-fixes/include/hal_com.h rename to extra_modules/rtl8192cu-fixes/include/hal_com.h diff --git a/rtl8192cu-fixes/include/hal_intf.h b/extra_modules/rtl8192cu-fixes/include/hal_intf.h similarity index 100% rename from rtl8192cu-fixes/include/hal_intf.h rename to extra_modules/rtl8192cu-fixes/include/hal_intf.h diff --git a/rtl8192cu-fixes/include/ieee80211.h b/extra_modules/rtl8192cu-fixes/include/ieee80211.h similarity index 100% rename from rtl8192cu-fixes/include/ieee80211.h rename to extra_modules/rtl8192cu-fixes/include/ieee80211.h diff --git a/rtl8192cu-fixes/include/ieee80211_ext.h b/extra_modules/rtl8192cu-fixes/include/ieee80211_ext.h similarity index 100% rename from rtl8192cu-fixes/include/ieee80211_ext.h rename to extra_modules/rtl8192cu-fixes/include/ieee80211_ext.h diff --git a/rtl8192cu-fixes/include/if_ether.h b/extra_modules/rtl8192cu-fixes/include/if_ether.h similarity index 100% rename from rtl8192cu-fixes/include/if_ether.h rename to extra_modules/rtl8192cu-fixes/include/if_ether.h diff --git a/rtl8192cu-fixes/include/ioctl_cfg80211.h b/extra_modules/rtl8192cu-fixes/include/ioctl_cfg80211.h similarity index 100% rename from rtl8192cu-fixes/include/ioctl_cfg80211.h rename to extra_modules/rtl8192cu-fixes/include/ioctl_cfg80211.h diff --git a/rtl8192cu-fixes/include/ip.h b/extra_modules/rtl8192cu-fixes/include/ip.h similarity index 100% rename from rtl8192cu-fixes/include/ip.h rename to extra_modules/rtl8192cu-fixes/include/ip.h diff --git a/rtl8192cu-fixes/include/linux/wireless.h b/extra_modules/rtl8192cu-fixes/include/linux/wireless.h similarity index 100% rename from rtl8192cu-fixes/include/linux/wireless.h rename to extra_modules/rtl8192cu-fixes/include/linux/wireless.h diff --git a/rtl8192cu-fixes/include/mlme_osdep.h b/extra_modules/rtl8192cu-fixes/include/mlme_osdep.h similarity index 100% rename from rtl8192cu-fixes/include/mlme_osdep.h rename to extra_modules/rtl8192cu-fixes/include/mlme_osdep.h diff --git a/rtl8192cu-fixes/include/mp_custom_oid.h b/extra_modules/rtl8192cu-fixes/include/mp_custom_oid.h similarity index 100% rename from rtl8192cu-fixes/include/mp_custom_oid.h rename to extra_modules/rtl8192cu-fixes/include/mp_custom_oid.h diff --git a/rtl8192cu-fixes/include/nic_spec.h b/extra_modules/rtl8192cu-fixes/include/nic_spec.h similarity index 100% rename from rtl8192cu-fixes/include/nic_spec.h rename to extra_modules/rtl8192cu-fixes/include/nic_spec.h diff --git a/rtl8192cu-fixes/include/osdep_ce_service.h b/extra_modules/rtl8192cu-fixes/include/osdep_ce_service.h similarity index 100% rename from rtl8192cu-fixes/include/osdep_ce_service.h rename to extra_modules/rtl8192cu-fixes/include/osdep_ce_service.h diff --git a/rtl8192cu-fixes/include/osdep_intf.h b/extra_modules/rtl8192cu-fixes/include/osdep_intf.h similarity index 100% rename from rtl8192cu-fixes/include/osdep_intf.h rename to extra_modules/rtl8192cu-fixes/include/osdep_intf.h diff --git a/rtl8192cu-fixes/include/osdep_service.h b/extra_modules/rtl8192cu-fixes/include/osdep_service.h similarity index 100% rename from rtl8192cu-fixes/include/osdep_service.h rename to extra_modules/rtl8192cu-fixes/include/osdep_service.h diff --git a/rtl8192cu-fixes/include/pci_hal.h b/extra_modules/rtl8192cu-fixes/include/pci_hal.h similarity index 100% rename from rtl8192cu-fixes/include/pci_hal.h rename to extra_modules/rtl8192cu-fixes/include/pci_hal.h diff --git a/rtl8192cu-fixes/include/pci_ops.h b/extra_modules/rtl8192cu-fixes/include/pci_ops.h similarity index 100% rename from rtl8192cu-fixes/include/pci_ops.h rename to extra_modules/rtl8192cu-fixes/include/pci_ops.h diff --git a/rtl8192cu-fixes/include/pci_osintf.h b/extra_modules/rtl8192cu-fixes/include/pci_osintf.h similarity index 100% rename from rtl8192cu-fixes/include/pci_osintf.h rename to extra_modules/rtl8192cu-fixes/include/pci_osintf.h diff --git a/rtl8192cu-fixes/include/recv_osdep.h b/extra_modules/rtl8192cu-fixes/include/recv_osdep.h similarity index 100% rename from rtl8192cu-fixes/include/recv_osdep.h rename to extra_modules/rtl8192cu-fixes/include/recv_osdep.h diff --git a/rtl8192cu-fixes/include/rtl8192c_cmd.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_cmd.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_cmd.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_cmd.h diff --git a/rtl8192cu-fixes/include/rtl8192c_dm.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_dm.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_dm.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_dm.h diff --git a/rtl8192cu-fixes/include/rtl8192c_event.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_event.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_event.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_event.h diff --git a/rtl8192cu-fixes/include/rtl8192c_hal.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_hal.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_hal.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_hal.h diff --git a/rtl8192cu-fixes/include/rtl8192c_led.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_led.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_led.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_led.h diff --git a/rtl8192cu-fixes/include/rtl8192c_recv.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_recv.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_recv.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_recv.h diff --git a/rtl8192cu-fixes/include/rtl8192c_rf.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_rf.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_rf.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_rf.h diff --git a/rtl8192cu-fixes/include/rtl8192c_spec.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_spec.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_spec.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_spec.h diff --git a/rtl8192cu-fixes/include/rtl8192c_sreset.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_sreset.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_sreset.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_sreset.h diff --git a/rtl8192cu-fixes/include/rtl8192c_xmit.h b/extra_modules/rtl8192cu-fixes/include/rtl8192c_xmit.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192c_xmit.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192c_xmit.h diff --git a/rtl8192cu-fixes/include/rtl8192d_cmd.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_cmd.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_cmd.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_cmd.h diff --git a/rtl8192cu-fixes/include/rtl8192d_dm.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_dm.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_dm.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_dm.h diff --git a/rtl8192cu-fixes/include/rtl8192d_hal.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_hal.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_hal.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_hal.h diff --git a/rtl8192cu-fixes/include/rtl8192d_led.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_led.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_led.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_led.h diff --git a/rtl8192cu-fixes/include/rtl8192d_recv.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_recv.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_recv.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_recv.h diff --git a/rtl8192cu-fixes/include/rtl8192d_rf.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_rf.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_rf.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_rf.h diff --git a/rtl8192cu-fixes/include/rtl8192d_spec.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_spec.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_spec.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_spec.h diff --git a/rtl8192cu-fixes/include/rtl8192d_xmit.h b/extra_modules/rtl8192cu-fixes/include/rtl8192d_xmit.h similarity index 100% rename from rtl8192cu-fixes/include/rtl8192d_xmit.h rename to extra_modules/rtl8192cu-fixes/include/rtl8192d_xmit.h diff --git a/rtl8192cu-fixes/include/rtw_android.h b/extra_modules/rtl8192cu-fixes/include/rtw_android.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_android.h rename to extra_modules/rtl8192cu-fixes/include/rtw_android.h diff --git a/rtl8192cu-fixes/include/rtw_ap.h b/extra_modules/rtl8192cu-fixes/include/rtw_ap.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ap.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ap.h diff --git a/rtl8192cu-fixes/include/rtw_br_ext.h b/extra_modules/rtl8192cu-fixes/include/rtw_br_ext.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_br_ext.h rename to extra_modules/rtl8192cu-fixes/include/rtw_br_ext.h diff --git a/rtl8192cu-fixes/include/rtw_byteorder.h b/extra_modules/rtl8192cu-fixes/include/rtw_byteorder.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_byteorder.h rename to extra_modules/rtl8192cu-fixes/include/rtw_byteorder.h diff --git a/rtl8192cu-fixes/include/rtw_cmd.h b/extra_modules/rtl8192cu-fixes/include/rtw_cmd.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_cmd.h rename to extra_modules/rtl8192cu-fixes/include/rtw_cmd.h diff --git a/rtl8192cu-fixes/include/rtw_debug.h b/extra_modules/rtl8192cu-fixes/include/rtw_debug.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_debug.h rename to extra_modules/rtl8192cu-fixes/include/rtw_debug.h diff --git a/rtl8192cu-fixes/include/rtw_eeprom.h b/extra_modules/rtl8192cu-fixes/include/rtw_eeprom.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_eeprom.h rename to extra_modules/rtl8192cu-fixes/include/rtw_eeprom.h diff --git a/rtl8192cu-fixes/include/rtw_efuse.h b/extra_modules/rtl8192cu-fixes/include/rtw_efuse.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_efuse.h rename to extra_modules/rtl8192cu-fixes/include/rtw_efuse.h diff --git a/rtl8192cu-fixes/include/rtw_event.h b/extra_modules/rtl8192cu-fixes/include/rtw_event.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_event.h rename to extra_modules/rtl8192cu-fixes/include/rtw_event.h diff --git a/rtl8192cu-fixes/include/rtw_ht.h b/extra_modules/rtl8192cu-fixes/include/rtw_ht.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ht.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ht.h diff --git a/rtl8192cu-fixes/include/rtw_io.h b/extra_modules/rtl8192cu-fixes/include/rtw_io.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_io.h rename to extra_modules/rtl8192cu-fixes/include/rtw_io.h diff --git a/rtl8192cu-fixes/include/rtw_ioctl.h b/extra_modules/rtl8192cu-fixes/include/rtw_ioctl.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ioctl.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ioctl.h diff --git a/rtl8192cu-fixes/include/rtw_ioctl_query.h b/extra_modules/rtl8192cu-fixes/include/rtw_ioctl_query.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ioctl_query.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ioctl_query.h diff --git a/rtl8192cu-fixes/include/rtw_ioctl_rtl.h b/extra_modules/rtl8192cu-fixes/include/rtw_ioctl_rtl.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ioctl_rtl.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ioctl_rtl.h diff --git a/rtl8192cu-fixes/include/rtw_ioctl_set.h b/extra_modules/rtl8192cu-fixes/include/rtw_ioctl_set.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_ioctl_set.h rename to extra_modules/rtl8192cu-fixes/include/rtw_ioctl_set.h diff --git a/rtl8192cu-fixes/include/rtw_iol.h b/extra_modules/rtl8192cu-fixes/include/rtw_iol.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_iol.h rename to extra_modules/rtl8192cu-fixes/include/rtw_iol.h diff --git a/rtl8192cu-fixes/include/rtw_led.h b/extra_modules/rtl8192cu-fixes/include/rtw_led.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_led.h rename to extra_modules/rtl8192cu-fixes/include/rtw_led.h diff --git a/rtl8192cu-fixes/include/rtw_mlme.h b/extra_modules/rtl8192cu-fixes/include/rtw_mlme.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_mlme.h rename to extra_modules/rtl8192cu-fixes/include/rtw_mlme.h diff --git a/rtl8192cu-fixes/include/rtw_mlme_ext.h b/extra_modules/rtl8192cu-fixes/include/rtw_mlme_ext.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_mlme_ext.h rename to extra_modules/rtl8192cu-fixes/include/rtw_mlme_ext.h diff --git a/rtl8192cu-fixes/include/rtw_mp.h b/extra_modules/rtl8192cu-fixes/include/rtw_mp.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_mp.h rename to extra_modules/rtl8192cu-fixes/include/rtw_mp.h diff --git a/rtl8192cu-fixes/include/rtw_mp_ioctl.h b/extra_modules/rtl8192cu-fixes/include/rtw_mp_ioctl.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_mp_ioctl.h rename to extra_modules/rtl8192cu-fixes/include/rtw_mp_ioctl.h diff --git a/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h b/extra_modules/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_mp_phy_regdef.h rename to extra_modules/rtl8192cu-fixes/include/rtw_mp_phy_regdef.h diff --git a/rtl8192cu-fixes/include/rtw_p2p.h b/extra_modules/rtl8192cu-fixes/include/rtw_p2p.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_p2p.h rename to extra_modules/rtl8192cu-fixes/include/rtw_p2p.h diff --git a/rtl8192cu-fixes/include/rtw_pwrctrl.h b/extra_modules/rtl8192cu-fixes/include/rtw_pwrctrl.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_pwrctrl.h rename to extra_modules/rtl8192cu-fixes/include/rtw_pwrctrl.h diff --git a/rtl8192cu-fixes/include/rtw_qos.h b/extra_modules/rtl8192cu-fixes/include/rtw_qos.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_qos.h rename to extra_modules/rtl8192cu-fixes/include/rtw_qos.h diff --git a/rtl8192cu-fixes/include/rtw_recv.h b/extra_modules/rtl8192cu-fixes/include/rtw_recv.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_recv.h rename to extra_modules/rtl8192cu-fixes/include/rtw_recv.h diff --git a/rtl8192cu-fixes/include/rtw_rf.h b/extra_modules/rtl8192cu-fixes/include/rtw_rf.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_rf.h rename to extra_modules/rtl8192cu-fixes/include/rtw_rf.h diff --git a/rtl8192cu-fixes/include/rtw_security.h b/extra_modules/rtl8192cu-fixes/include/rtw_security.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_security.h rename to extra_modules/rtl8192cu-fixes/include/rtw_security.h diff --git a/rtl8192cu-fixes/include/rtw_sreset.h b/extra_modules/rtl8192cu-fixes/include/rtw_sreset.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_sreset.h rename to extra_modules/rtl8192cu-fixes/include/rtw_sreset.h diff --git a/rtl8192cu-fixes/include/rtw_tdls.h b/extra_modules/rtl8192cu-fixes/include/rtw_tdls.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_tdls.h rename to extra_modules/rtl8192cu-fixes/include/rtw_tdls.h diff --git a/rtl8192cu-fixes/include/rtw_version.h b/extra_modules/rtl8192cu-fixes/include/rtw_version.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_version.h rename to extra_modules/rtl8192cu-fixes/include/rtw_version.h diff --git a/rtl8192cu-fixes/include/rtw_xmit.h b/extra_modules/rtl8192cu-fixes/include/rtw_xmit.h similarity index 100% rename from rtl8192cu-fixes/include/rtw_xmit.h rename to extra_modules/rtl8192cu-fixes/include/rtw_xmit.h diff --git a/rtl8192cu-fixes/include/sta_info.h b/extra_modules/rtl8192cu-fixes/include/sta_info.h similarity index 100% rename from rtl8192cu-fixes/include/sta_info.h rename to extra_modules/rtl8192cu-fixes/include/sta_info.h diff --git a/rtl8192cu-fixes/include/usb_hal.h b/extra_modules/rtl8192cu-fixes/include/usb_hal.h similarity index 100% rename from rtl8192cu-fixes/include/usb_hal.h rename to extra_modules/rtl8192cu-fixes/include/usb_hal.h diff --git a/rtl8192cu-fixes/include/usb_ops.h b/extra_modules/rtl8192cu-fixes/include/usb_ops.h similarity index 100% rename from rtl8192cu-fixes/include/usb_ops.h rename to extra_modules/rtl8192cu-fixes/include/usb_ops.h diff --git a/rtl8192cu-fixes/include/usb_ops_linux.h b/extra_modules/rtl8192cu-fixes/include/usb_ops_linux.h similarity index 100% rename from rtl8192cu-fixes/include/usb_ops_linux.h rename to extra_modules/rtl8192cu-fixes/include/usb_ops_linux.h diff --git a/rtl8192cu-fixes/include/usb_osintf.h b/extra_modules/rtl8192cu-fixes/include/usb_osintf.h similarity index 100% rename from rtl8192cu-fixes/include/usb_osintf.h rename to extra_modules/rtl8192cu-fixes/include/usb_osintf.h diff --git a/rtl8192cu-fixes/include/usb_vendor_req.h b/extra_modules/rtl8192cu-fixes/include/usb_vendor_req.h similarity index 100% rename from rtl8192cu-fixes/include/usb_vendor_req.h rename to extra_modules/rtl8192cu-fixes/include/usb_vendor_req.h diff --git a/rtl8192cu-fixes/include/wifi.h b/extra_modules/rtl8192cu-fixes/include/wifi.h similarity index 100% rename from rtl8192cu-fixes/include/wifi.h rename to extra_modules/rtl8192cu-fixes/include/wifi.h diff --git a/rtl8192cu-fixes/include/wlan_bssdef.h b/extra_modules/rtl8192cu-fixes/include/wlan_bssdef.h similarity index 100% rename from rtl8192cu-fixes/include/wlan_bssdef.h rename to extra_modules/rtl8192cu-fixes/include/wlan_bssdef.h diff --git a/rtl8192cu-fixes/include/xmit_osdep.h b/extra_modules/rtl8192cu-fixes/include/xmit_osdep.h similarity index 100% rename from rtl8192cu-fixes/include/xmit_osdep.h rename to extra_modules/rtl8192cu-fixes/include/xmit_osdep.h diff --git a/rtl8192cu-fixes/installer.sh b/extra_modules/rtl8192cu-fixes/installer.sh similarity index 100% rename from rtl8192cu-fixes/installer.sh rename to extra_modules/rtl8192cu-fixes/installer.sh diff --git a/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c diff --git a/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/ioctl_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_linux.c diff --git a/rtl8192cu-fixes/os_dep/linux/mlme_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/mlme_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/mlme_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/mlme_linux.c diff --git a/rtl8192cu-fixes/os_dep/linux/os_intfs.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/os_intfs.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c diff --git a/rtl8192cu-fixes/os_dep/linux/pci_intf.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/pci_intf.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/pci_intf.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/pci_intf.c diff --git a/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/pci_ops_linux.c diff --git a/rtl8192cu-fixes/os_dep/linux/recv_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/recv_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/recv_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/recv_linux.c diff --git a/rtl8192cu-fixes/os_dep/linux/rtw_android.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/rtw_android.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/rtw_android.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/rtw_android.c diff --git a/rtl8192cu-fixes/os_dep/linux/usb_intf.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/usb_intf.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c diff --git a/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/usb_ops_linux.c diff --git a/rtl8192cu-fixes/os_dep/linux/xmit_linux.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/xmit_linux.c similarity index 100% rename from rtl8192cu-fixes/os_dep/linux/xmit_linux.c rename to extra_modules/rtl8192cu-fixes/os_dep/linux/xmit_linux.c diff --git a/rtl8192cu-fixes/os_dep/osdep_service.c b/extra_modules/rtl8192cu-fixes/os_dep/osdep_service.c similarity index 100% rename from rtl8192cu-fixes/os_dep/osdep_service.c rename to extra_modules/rtl8192cu-fixes/os_dep/osdep_service.c diff --git a/rtl8192cu-fixes/runwpa b/extra_modules/rtl8192cu-fixes/runwpa similarity index 100% rename from rtl8192cu-fixes/runwpa rename to extra_modules/rtl8192cu-fixes/runwpa diff --git a/extra_modules/v4l2loopback/.gitignore b/extra_modules/v4l2loopback/.gitignore new file mode 100644 index 00000000..690b0ac2 --- /dev/null +++ b/extra_modules/v4l2loopback/.gitignore @@ -0,0 +1,8 @@ +.tmp_versions/ +*.cmd +Module.symvers +modules.order +v4l2loopback.ko +v4l2loopback.mod.c +v4l2loopback.mod.o +v4l2loopback.o diff --git a/extra_modules/v4l2loopback/AUTHORS b/extra_modules/v4l2loopback/AUTHORS new file mode 100644 index 00000000..cc4030f4 --- /dev/null +++ b/extra_modules/v4l2loopback/AUTHORS @@ -0,0 +1,15 @@ +Angus McInnes +Aidan Thornton +Anatolij Gutschin +Anton Novikov +Dmitry Eremin +Gorinich Zmey +IOhannes m zmoelnig +Javier Infante +Scott Maines +Stefan Diewald +Tasos Sahanidis +tz +Ted Mielczarek +Vasily Levin +Yusuke Ohshima diff --git a/extra_modules/v4l2loopback/COPYING b/extra_modules/v4l2loopback/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/extra_modules/v4l2loopback/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/extra_modules/v4l2loopback/ChangeLog b/extra_modules/v4l2loopback/ChangeLog new file mode 100644 index 00000000..9a4cf686 --- /dev/null +++ b/extra_modules/v4l2loopback/ChangeLog @@ -0,0 +1,414 @@ +v4l2loopback (0.9.1) unstable; urgency=medium + + * Fixed module version + + -- IOhannes m zmölnig (Debian/GNU) Wed, 03 Jun 2015 19:47:23 +0200 + +v4l2loopback (0.9.0) unstable; urgency=medium + + [ IOhannes m zmölnig ] + * formats + * support more formats + * support compressed formats + * move formats-enumeration to separate file + * tools to implement missing formats + * controls + * disable deprecated vidioc_*ctrl callbacks + * register custom-controls + * use ctrl_config information in (deprecated) queryctrl + * fixed bugs + * used static code analysis to find more bugs + * more error checking + * check timeperframe before setting it (Closes: #61) + * make MAX_DEVICES/TIMEOUT/BUFFERS settable during build-process (Closes: #55) + * check for errors returned by get_capture_buffer() + * check whether there is at least 1 requestbuffer + * unsigned comparision against <0 + * avoid setting b->count to negative/null + * ... + * fixed typos + * code formatting + * standards compliancy + * standard-conformant bus_info + * pretend to not support {G,S,ENUM}_{IN,OUT}PUT depending on state + * only pretend to not support IN/OUTPUT enumeration in exclusive-caps mode + * test programs + * for (de)queuing buffers + * for writing interlaced video + * compatibility with newer kernels + * compatibility with older kernels + * Updated documentation + * Removed GFDL document + * note where to get API documentation + + [ tatokis ] + * Updated v4l2loopback.c to compile on >= 3.18 kernel + + [ tz ] + * add ondemandcam + + [ Yusuke Ohshima ] + * Fix issue #79 + + [ Tasos Sahanidis ] + * Fix for kernel 4.0 + + -- IOhannes m zmölnig Tue, 02 Jun 2015 19:58:39 +0200 + +v4l2loopback (0.8.0) unstable; urgency=medium + + [ Dmitry Eremin ] + * Add DKMS support. + + [ Angus McInnes ] + * Make vidioc_g_fmt_out not change the format + * Set correct output buffer type in vidioc_dqbuf + + [ Javier Infante ] + * Added card_labels option when loading module. + + [ IOhannes m zmölnig ] + * renamed 'card_labels' to 'card_label' + * removed '-e' flag from call to 'depmod' (needs '-E' or '-F') + * auto-detect new version + * auto-update dkms.conf to new version + + -- IOhannes m zmölnig Tue, 10 Dec 2013 18:12:15 +0100 + +v4l2loopback (0.7.1) unstable; urgency=low + + [ Aidan Thornton ] + * Linux 3.11 compatibility fix + + [ IOhannes m zmölnig ] + * trying to keep pre-2.6.29 compatibility + + -- IOhannes m zmoelnig (gpg-key at iem) Mon, 16 Sep 2013 09:55:51 +0200 + +v4l2loopback (0.7.0) unstable; urgency=low + + [ IOhannes m zmölnig ] + * don't implement STD-ioctls + * Revert "dummy audio ioctl's that return EINVAL" + * disable more STD-stuff based on V4L2LOOPBACK_WITH_STD + * don't announce all caps capabilities + * only announce capture/output capabilities if possible + * 'exclusive_caps' parameter to control caps announcment + * avoid duplicate setting of cardname + * break lines + * remove commented out code + * updated AUTHORS information + * fixed ChangeLog for 0.6.1 + * updated NEWS for last releases + + [ Anatolij Gustschin ] + * fix missing spin lock init + * add newlines to debug statements + + [ Hans Verkuil ] + * reformatting to kernel-standards + + -- IOhannes m zmoelnig (gpg-key at iem) Fri, 07 Jun 2013 11:24:34 +0200 + +v4l2loopback (0.6.3) unstable; urgency=low + + [ Ted Mielczarek ] + * Fill in the "v4l2_capability::bus_info" field (Closes: #30) + + [ IOhannes m zmölnig ] + * make "v4l2_capability::card" unique per device (Closes: #37) + * fill in "video_device::vfl_dir" field on newer kernels (Closes: #35) + * always provide format-string when using printf() + * fixing update-changelog script + + -- IOhannes m zmoelnig (gpg-key at iem) Tue, 05 Feb 2013 10:03:28 +0100 + +v4l2loopback (0.6.2) unstable; urgency=low + + [ IOhannes m zmölnig ] + * provide our own v4l2l_vzalloc + * added missing includes + * create unique names for the various devices + * more verbose debugging output when capture DQBUF fails + + [ Anton Novikov ] + * make v4l2loopback.ko a PHONY target + * restarting-writer.sh runs on Ubuntu 11.10 + * warning about disabled timeout when setting image + * readpos2index -> bufpos2index + * test different queue-sizes in restarting-writer.sh + * fix buffer indices before dev->used_buffers update + * fix ctl script (was hardcoded /dev/video0) + + [ yukkeorg ] + * Fix error on compile in Linux kernel 3.6.1. + + -- IOhannes m zmoelnig Tue, 23 Oct 2012 14:38:02 +0200 + +v4l2loopback (0.6.1) UNRELEASED; urgency=low + + [ IOhannes m zmoelnig ] + * Makefile fixes for debian + + -- IOhannes m zmoelnig (gpg-key at iem) Fri, 27 Apr 2012 17:22:25 +0200 + +v4l2loopback (0.6.0) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * added direct link to wiki + * fixed typos + * check for (devices<0) rather than (devices==-1) + + [ Anton Novikov ] + * add .gitignore files + * add 'format' sysfs attr + * remove 'fourcc' sysfs attr + * 'keep_format' ctrl + * set_timeperframe(), dev->frame_jiffies + * 'sustain_framerate' ctrl + * add examples/restarting-writer.sh + * reset write_position only when !ready_for_capture + * handle arbitrary output QBUF index order + * 'timeout' ctrl + * add ability to do i/o on placeholder picture buf + * add v4l2loopback-ctl script + * installing v4l2loopback-ctl + * fix dequeuing unused buffers + * timeout_image_io cleaner memory handling + * some documentation on controls + * some v4l2loopback-ctl syntax&doc tweaks + + [ IOhannes m zmölnig ] + * moved utility into utils/ + * Updated copyright notice + * use max image size to prevent insane allocations + * in-code documentation of the format string + * fixed description of 'debug' option + * fixed closing comment + * allow to set the max.framesize via module parameters + * renamed 'v4l2loopback' target to 'v4l2loopback.ko' + * added install-utils target + + [ Anton Novikov ] + * script bugfix + * v4l2loopback-ctl set-fps + * more README + + [ IOhannes m zmölnig ] + * initialize list in all cases + * notes on how to do kernel-debugging + * when dying, write to stderr + * check for applications before using them + * fix usage/version to make it fit for help2man + * manpage for v4l2loopback-ctl + * placeholder + * simplified description + * build and install manpages + * deleted manage (it's generated automatically) + * updated in-module AUTHORs + * debugging printout + * don't try to force a given format + * clarify README about default device in ./test + + -- IOhannes m zmoelnig (gpg-key at iem) Fri, 27 Apr 2012 09:29:52 +0200 + +v4l2loopback (0.5.0) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * more (and better) debugging output + * stefan diewald's ENUM_FRAMESIZES fix + * simplifified framesize enumeration + * stefan diewald's ENUM_FRAMEINTERVAL implementations + * stefan diewald's buffer request logic + * added Stefan Diewald to the authors + * use sudo to rmmod/insmod kernel modules in Makefile + * use unlocked_ioctl as suggested by salsaman + * provide macros to simplify sysfs attrfile creation + * added deviceattributes + * implemented "video_nr" parameter to manually force device IDs + * dummy audio ioctl's that return EINVAL + * better output enumeration/format handling + * trying to improve handling of std's + * improve readability of vidioc_g_output + * added note about video_nr param + * fixed memleaks + * allow per-device "max_openers" settings + * warn if illegal number of max_openers is requested + * prefix posts with "v4l2loopback" + + [ IOhannes m zmoelnig ] + * simplistic ChangeLog generator + + -- zmoelnig Tue, 27 Dec 2011 19:01:25 +0100 + +v4l2loopback (0.4.1) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * yuv4mpeg producer to be used in conjunction with mplayer + * added yuv4mpeg_to_v4l2 to the build targets + * simplified Makefile; added clean target + * protect newer pixel formats + * fixed preprocessor expansion on linux<2.6.32 + * made it compile on 2.6.28 and 2.6.27 + * <=2.6.27 definitely won't work + * allow S_PARM for fps + * renamed opener->position to opener->read_position + * added dummy VIDIOC_QUERYCTRL implementation (fix for linux-3.1) + + -- IOhannes m zmoelnig (gpg-key at iem) Thu, 24 Nov 2011 18:11:01 +0100 + +v4l2loopback (0.4.0) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * default debug-level should be 0 + * cleanup version confusion + * changed version to 0.3.0 + * updated README to mention Debian packages + * better internal format representation (as found in bttv-drivers) - still unused + * trying to support I420 --- might be very unstable right now + * dummy Makefile to allow "make" + * allow to set device from cmdline + * en/disable the readback test using defines + * use FRAME_SIZE throughout + * more experiments + * more debugging messages + * added rule to autoload the new v4l2loopback device + * rewrote most of the mmap part in order to support I420 + * cleanup to make it C90 compliant again + * reordered formats a bit to make better default choices... + * replace vloopback by v4l2loopback to avoid confusion + * cleaned up code + * properly initialize the timestampe in order to guarantee a monotic series + * updated copyright + * bumped to version 0.4.0 + + -- IOhannes m zmoelnig (gpg-key at iem) Tue, 29 Mar 2011 12:54:23 +0200 + +v4l2loopback (0.3) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * note on why gstreamer v4l2sink fails to write to such a device + * enum_framesizes and enum_fmt_caps + * hmm, this makes it more crashy than better + * enable additional ioctls (eg. enum_output) + * fixed typo: USAGE instead of USEAGE + * remove stray #error + * gcode reorganization; uniform comments + * experiments with returning 0-size + * offline documentation for v4l2 + * allow all kinds of formats during negotiation + * comment on which fields to set + * better support for setting formats + * add note about using application's bytesperline + * set type to WRITER when caller calls enum_fmt_out + * removed TODO as it has been done already + * indentation + * hopefully a bit more intelligent buffer-reallocation strategy + * extra safety checks + * print fourcc in fmt-enum + * fallback formats for try_fmt_out + * nicer format descriptions + * use defines for size-limits + * return EBUSY when trying to set fmt in CAPTURE mode when not ready + * properly implement querycap + * bytes_used in the mmap may be smaller than the page-size + * some dummy functions for video-std settings + * debug-level: 1 + * terminate function call with ";" + * getting rid of MEMLEAK warning (should be fixed now) + * calculate bytesperline + * only return dummy-format with G_FMT[out] when none has been set + * nicer debugging + * disable OVERLAY dummy + * return 0-sized image by default + * default max_buffers_number is 8 + * getting rid of my prefix + * pushed to version 0.0.2 + * pumped to version 0.3 + + -- IOhannes m zmoelnig (gpg-key at iem) Sun, 10 Oct 2010 21:12:38 +0200 + +v4l2loopback (0.2) UNRELEASED; urgency=low + + [ IOhannes m zmölnig ] + * acces /dev/video0 + * variable number of pipes + * nicer printout + * proper cleanup + * renamed "pipes" to "devices" + * bumped version; added meself as co-author + * removed files removed by "debian/rules clean" + * removed examples + * fixed debian/control debian/rules + * postinst stuff + * moved example into separate folder + * MakefileS need not be executable + * README, COPYING, AUTHORS + * re-version to 0.2 + * updated README + * added Vasily Levin to the authors + * removed debian stuff + * added a README for the test + * added vasily.levin to the authors + * included linux/slab.h + * license issues: this module is GPLv2 + * added meself into the copyright header + + -- IOhannes m zmoelnig (gpg-key at iem) Sun, 10 Oct 2010 21:09:43 +0200 + +v4l2loopback (0.1) UNRELEASED; urgency=low + + [ gorinich.zmey ] + * initial + * first approach + * removed autogenerated file + * temproraly removed fps control and input from stdin handling + * removed irrelevant changelog, changed readme + * forgotten changes applued + * modules.order delete + * cleaned the mess with git-svn + * added test file + * added VIDIOC_G_PARM call + * format handling improvment, current solution is a stub + * temporarly removed mmap to keep code simple + * compile fix + * poll added, streaming started + * small test refine + * enum_input added + * basic streaming, polish needed + * first streaming working, mplayer gots a picture, yet crappy + * readme add + * readme rewrite + * readme additions + * mutex add + * skype working + * queue introduction, next step queue remove + * first run is OK already + * queues debugged + * halfway of massive inner structure changes + * compiles + * pre multireader + * style for linux kernel + * indent + * 80 width + * module name changed and debianize start + * debian + * 2.6.28 support + * almost works, just one bug left + * debian + * bug with two and more openers fixed + * redebianized + * removed files + * license header add + * freeing of unitialized pointer fixed, added nonblocking IO + * sync with v4l-dvb tree + * review responce + * hans review + * test improvments by Antonio Ospite + * removed header + * more small fixes + + [ Scott Maines ] + * missing header for Fedora + + -- IOhannes m zmoelnig (gpg-key at iem) Sun, 10 Oct 2010 21:01:50 +0200 diff --git a/extra_modules/v4l2loopback/Makefile b/extra_modules/v4l2loopback/Makefile new file mode 100644 index 00000000..1cf1ea8c --- /dev/null +++ b/extra_modules/v4l2loopback/Makefile @@ -0,0 +1,78 @@ +KERNELRELEASE ?= `uname -r` +KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build +PWD := $(shell pwd) +obj-m := v4l2loopback.o +ARCH := arm +CROSS_COMPILE := ../brandy/gcc-linaro/bin/arm-linux-gnueabi- +KVER := 3.4 +KSRC:= ../linux-3.4/ + +PREFIX ?= /usr/local +BINDIR = $(PREFIX)/bin +MANDIR = $(PREFIX)/share/man +MAN1DIR = $(MANDIR)/man1 +INSTALL = install +INSTALL_PROGRAM = $(INSTALL) -p -m 755 +INSTALL_DIR = $(INSTALL) -p -m 755 -d +INSTALL_DATA = $(INSTALL) -m 644 + +MODULE_OPTIONS = devices=2 + +########################################## +# note on build targets +# +# module-assistant makes some assumptions about targets, namely +# : must be present and build the module +# .ko is not enough +# install: must be present (and should only install the module) +# +# we therefore make a .PHONY alias to .ko +# and remove utils-installation from 'install' +# call 'make install-all' if you want to install everything +########################################## + + +.PHONY: all install clean distclean +.PHONY: install-all install-utils install-man +.PHONY: modprobe v4l2loopback + +# we don't control the .ko file dependencies, as it is done by kernel +# makefiles. therefore v4l2loopback.ko is a phony target actually +.PHONY: v4l2loopback.ko + +all: v4l2loopback.ko +v4l2loopback: v4l2loopback.ko +v4l2loopback.ko: + @echo "Building v4l2-loopback driver..." +# $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules + $(MAKE) -j $(shell nproc) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules + +install-all: install install-utils install-man +install: + $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install + depmod -a $(KERNELRELEASE) + +install-utils: utils/v4l2loopback-ctl + $(INSTALL_DIR) "$(DESTDIR)$(BINDIR)" + $(INSTALL_PROGRAM) $< "$(DESTDIR)$(BINDIR)" + +install-man: man/v4l2loopback-ctl.1 + $(INSTALL_DIR) "$(DESTDIR)$(MAN1DIR)" + $(INSTALL_DATA) $< "$(DESTDIR)$(MAN1DIR)" + +clean: + rm -f *~ + rm -f Module.symvers Module.markers modules.order + $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean + +distclean: clean + rm -f man/v4l2loopback-ctl.1 + +modprobe: v4l2loopback.ko + chmod a+r v4l2loopback.ko + sudo modprobe videodev + -sudo rmmod v4l2loopback + sudo insmod ./v4l2loopback.ko $(MODULE_OPTIONS) + +man/v4l2loopback-ctl.1: utils/v4l2loopback-ctl + help2man -N --name "control v4l2 loopback devices" $^ > $@ diff --git a/extra_modules/v4l2loopback/Makefile.manual b/extra_modules/v4l2loopback/Makefile.manual new file mode 100644 index 00000000..75cb8fb6 --- /dev/null +++ b/extra_modules/v4l2loopback/Makefile.manual @@ -0,0 +1,16 @@ +## DO NOT USE THIS MAKEFILE! +### this is created based on `make V=1 > make.log` and is used solely +### for creating build for static code analysis +.PHONY: default + +KERNELRELEASE ?= `uname -r` +KERNEL_SOURCE ?= /lib/modules/$(KERNELRELEASE)/build +KERNEL_SOURCE_COMMON ?= /lib/modules/$(KERNELRELEASE)/source + +CFLAGS=-nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/include -I$(KERNEL_SOURCE_COMMON)/arch/x86/include -I$(KERNEL_SOURCE)/arch/x86/include/generated -I$(KERNEL_SOURCE_COMMON)/include -I$(KERNEL_SOURCE)/include -I$(KERNEL_SOURCE_COMMON)/arch/x86/include/uapi -I$(KERNEL_SOURCE)/arch/x86/include/generated/uapi -I$(KERNEL_SOURCE_COMMON)/include/uapi -I$(KERNEL_SOURCE)/include/generated/uapi -include $(KERNEL_SOURCE_COMMON)/include/linux/kconfig.h -I. -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mno-mmx -mno-sse -mpreferred-stack-boundary=3 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -Wframe-larger-than=2048 -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -DCC_HAVE_ASM_GOTO + + +default: + $(CC) -Wp,-MD,./.v4l2loopback.o.d $(CFLAGS) -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(v4l2loopback)" -D"KBUILD_MODNAME=KBUILD_STR(v4l2loopback)" -c -o ./.tmp_v4l2loopback.o ./v4l2loopback.c + $(CC) -Wp,-MD,./.v4l2loopback.mod.o.d $(CFLAGS) -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(v4l2loopback.mod)" -D"KBUILD_MODNAME=KBUILD_STR(v4l2loopback)" -DMODULE -c -o ./v4l2loopback.mod.o ./v4l2loopback.mod.c + $(LD) -r -m elf_x86_64 -T $(KERNEL_SOURCE_COMMON)/scripts/module-common.lds --build-id -o ./v4l2loopback.ko ./v4l2loopback.o ./v4l2loopback.mod.o diff --git a/extra_modules/v4l2loopback/NEWS b/extra_modules/v4l2loopback/NEWS new file mode 100644 index 00000000..d88e9c38 --- /dev/null +++ b/extra_modules/v4l2loopback/NEWS @@ -0,0 +1,154 @@ +v4l2loopback-0.9.1 + + - Fixed module version + + -- IOhannes m zmölnig (Debian/GNU) Wed, 03 Jun 2015 19:47:23 +0200 + +v4l2loopback-0.9.0 + + - more formats + - kernel compatibility + fixed issues with kernel up to 4.0 + + -- IOhannes m zmölnig Tue, 02 Jun 2015 19:58:39 +0200 + +v4l2loopback-0.8.0 + + - DKMS config + - 'card_label' option to manually set device names + - fixes in format handling + + -- IOhannes m zmölnig Tue, 10 Dec 2013 18:12:15 +0100 + +v4l2loopback-0.7.1 + + - kernel compatibility + fixed issues with kernel-3.11 + fixed regression with kernel<2.6.29 + + -- IOhannes m zmoelnig (gpg-key at iem) Mon, 16 Sep 2013 09:55:51 +0200 + +v4l2loopback-0.7.0 + + - experimental'exclusive_caps' mode that only reports CAPTURE/OUTPUT + capabilities exclusively (support for Chromium/WebRTC) + - disabled fake STDs (e.g. ffmpeg support) + + -- IOhannes m zmoelnig (gpg-key at iem) Fri, 07 Jun 2013 11:08:10 +0200 + +v4l2loopback-0.6.3 + + - kernel compatibility + fixed issues with kernel-3.7 + - unique "Card Type" Names (fixes broken clients like flash) + - create unique ID in "bus_info" field (fixes Firefox/WebRTC support) + + -- IOhannes m zmoelnig (gpg-key at iem) 2013-02-05 + +v4l2loopback-0.6.2 + + - kernel compatibility + fixed issues with older kernels (<2.6.37) + fixed issues with kernel-3.6.1 + - distinct device names (fixes broken clients like google+) + + -- IOhannes m zmoelnig (gpg-key at iem) 2012-10-23 + +v4l2loopback-0.6.1 + + - Debian specific build-fixes + + -- IOhannes m zmoelnig (gpg-key at iem) 2012-04-27 + +v4l2loopback-0.6.0 + + - support fallback images (in case there is no live-stream) + - utilities to interact with v4l2loopback devices + + -- IOhannes m zmoelnig (gpg-key at iem) 2012-04-27 + +v4l2loopback-0.5.0 + + - module parameters + 'video_nr' manually sets device id(s) + - device attributes + via sysfs: /sys/devices/virtual/video4linux/video*/ + 'max_openers' per device + 'fourcc' queries currently selected format + - ioctl fixes + avoid the BIG KERNEL LOCK + ENUM_FRAMEINTERVAL implementation + fixed ENUM_FRAMESIZES (fixes skype compatibilitiy) + fixes to buffer queue with multiple consumers + minor fixes to handling of standards, output enumeration and output formats + - more (and better) debugging output + - fixed memleaks in the examples + + -- IOhannes m zmoelnig (gpg-key at iem) Tue, 27 Dec 2011 19:01:25 +0100 + +v4l2loopback-0.4.1 + + - yuv4mpeg producer example + - kernel compatibility + fixed issues with kernels<2.6.32 + fixed issues with kernel-3.1 + + -- IOhannes m zmoelnig (gpg-key at iem) Thu, 24 Nov 2011 18:11:01 +0100 + +v4l2loopback-0.4 + + - fixed issues with non-trivial colorspaces (e.g. I420) + this should allow for more clients to work out-of-the-box + (e.g. no more caps-tweak with gstreamer) + - fixed timestamps + this allows playback with players that need monotonous + timestamps (e.g. ffmpeg) + - cleaned up code + + -- IOhannes m zmoelnig Tue, 29 Mar 2011 14:26:10 +0200 + +v4l2loopback-0.3 + + - tested writers: + GStreamer's normal "v4l2sink" element (from plugins-good) + GStreamer's "v4l2loopback" (deprecated by v4l2sink) + pd/Gem(0.93svn) + - tested readers: + GStreamer's "v4l2src" + pd/Gem(0.92) + vlc + xawtv (depending on image format) + mplayer (with correct image format, e.g. rgb32) + - code documentation + - added v4l2-documentation for easier offline programming + - added a lot of ioctls to meet the v4l2 standard + + -- IOhannes m zmoelnig Sun, 10 Oct 2010 21:18:22 +0200 + +v4l2loopback-0.2 + + - Linux 2.6.32 & 2.6.35 + - tested with pd/Gem(0.93svn) and GStreamer's "v4l2loopback" + - add support for multiple video devices + - README, COPYING, AUTHORS + - re-organized file layout + + -- IOhannes m zmoelnig Tue Sep 28 09:46:47 CEST 2010 + +v4l2loopback-0.1 + + - Linux 2.6.28 + - Skype support + - support for GStreamer's "v4l2loopback" element + - test application + - README + - dev: nonblocking I/O + - dev: VIDIOC_G_PARM + + -- Gorinich Zmey Wed Jun 16 12:19:59 CEST 2010 + +v4l2loopback-0.0 + + - initial + + -- Vasily Levin Tue Feb 3 10:56:28 CET 2009 diff --git a/extra_modules/v4l2loopback/README.md b/extra_modules/v4l2loopback/README.md new file mode 100644 index 00000000..651c15e1 --- /dev/null +++ b/extra_modules/v4l2loopback/README.md @@ -0,0 +1,200 @@ +v4l2loopback - a kernel module to create V4L2 loopback devices +============================================================== + +this module allows you to create "virtual video devices" +normal (v4l2) applications will read these devices as if they were ordinary +video devices, but the video will not be read from e.g. a capture card but +instead it is generated by another application. +this allows you for instance to apply apply some nifty video effects on your +Skype video... +it also allows some more serious things (e.g. I've been using it to add +streaming capabilities to an application by the means of hooking GStreamer into +the loopback devices). + +# NEWS +to get the main features of each new release, see the NEWS file. +you could also have a look at the ChangeLog (which gets automatically generated and might +only be of limited use... + + +# ISSUES +for current issues, checkout https://github.com/umlaeute/v4l2loopback/issues +please use the issue-tracker for reporting any problems + +# DEPENDENCIES +The v4l2loopback module is a *kernel module*. +In order to build it, you *must have* the kernel headers installed that match +the linux kernel with which you want to use the module (in most this will be +the kernel that you are currently running). +Please note, that kernel headers and kernel image must have *exactly the same* version. +For example, `3.18.0-trunk-rpi` is a different version that `3.18.7-v7+`, even though +the first few number are the same. +(Modules will be incompatible if the versions don't match. If you are lucky, the module will +simply refuse to load. If you are unlucky, your computer will spit in your eye or do worse.) + +# BUILD +to build the kernel module run: + + $ make + +this should give you a file named "v4l2loopback.ko", which is the kernel module + +# INSTALL +to install the module run "make install" (you might have to be 'root' to have +all necessary permissions to install the module). + +if your system has "sudo", do: + + $ make && sudo make install + +if your system lacks "sudo", do: + + $ make + $ su + (enter root password) + # make install + # exit + +# RUN +Load the v4l2loopback module as root : + + # modprobe v4l2loopback + +using sudo use: + + $ sudo modprobe v4l2loopback + +this will create an additional video-device, e.g. /dev/video0 (the number +depends on whether you already had video devices on your system), which can be +fed by various programs. +tested feeders: +- GStreamer-0.10: using the "v4l2sink" element +- Gem(>=0.93) using the "recordV4L2" plugin +in theory most programs capable of _writing to_ a v4l2 device should work. + +the data sent to the v4l2loopback device can then be read by any v4l2-capable +application. + +you can find a number of scenarios on the wiki at + http://github.com/umlaeute/v4l2loopback/wiki + +# OPTIONS +if you need several independent loopback devices, you can pass the "devices" +option, when loading the module; e.g. + + # modprobe v4l2loopback devices=4 + +will give you 4 loopback devices (e.g. `/dev/video1` ... `/dev/video5`) +you can also specify the device IDs manually; e.g. + + # modprobe v4l2loopback video_nr=3,4,7 + +will create 3 devices (`/dev/video3`, `/dev/video4` & `/dev/video7`) + + # modprobe v4l2loopback video_nr=3,4,7 card_label="device number 3","the number four","the last one" + +will create 3 devices with the card names passed as the second parameter: +- `/dev/video3` -> *device number 3* +- `/dev/video4` -> *the number four* +- `/dev/video7` -> *the last one* + +# ATTRIBUTES +you can set and/or query some per-device attributes via sysfs, in a human +readable format. see `/sys/devices/virtual/video4linux/video*/` + +also there are some V4L2 controls that you can list with + + $ v4l2-ctl -d /dev/video1 -l + +- `keep_format(0/1)`: while set to 1, once negotiated format will be fixed forever, + until the setting is set back to 0 +- `sustain_framerate(0/1)`: if set to 1, nominal device fps will be ensured by means + of frame duplication when needed +- `timeout(integer)`: if >0, will cause a timeout picture (a null frame, by default) + to be displayed after (value) msecs of missing input +- `timeout_image_io(0/1)`: if set to 1, the next opener will write to timeout frame + buffer + +# FORCING FPS + + $ v4l2loopback-ctl set-fps 25 /dev/video0 + +or + + $ echo '@100' | sudo tee /sys/devices/virtual/video4linux/video0/format + +# FORCING A GSTREAMER (0.10) CAPS + + $ v4l2loopback-ctl set-caps "video/x-raw-yuv, width=640, height=480" /dev/video0 + +# SETTING STREAM TIMEOUT +~~~ +$ v4l2-ctl -d /dev/video0 -c timeout=3000 +(will output null frames by default) +$ v4l2loopback-ctl set-timeout-image service-unavailable.png /dev/video0 +this currently requires GStreamer 0.10 installed +~~~ +# KERNELs +the original module has been developed for linux-2.6.28; +i don't have a system with such an old kernel anymore, so i don't know whether +it still works. +further development has been done mainly on linux-2.6.32 and linux-2.6.35, with +newer kernels being continually tested as they enter debian. + +support: +- <= 2.6.27 definitely will NOT work +- 2.6.28 - 2.6.31 may work (seems to compile but i cannot test) +- >= 2.6.32 should work +- >= 3.0.0 should work as well + +# DISTRIBUTIONS +v4l2loopack is now (since 2010-10-13) available as a Debian-package. +https://packages.debian.org/source/stable/v4l2loopback + +This means, that it is also part of Debian-derived distributions, including +Ubuntu (starting with natty). +The most convenient way is to install the package "v4l2loopback-dkms": + + # aptitude install v4l2loopback-dkms + +This should automatically build and install the module for your current kernel +(provided you have the matching kernel-headers installed). +Another option is to install the "v4l2loopback-source" package. +In this case you should be able to simply do (as root): + + # aptitude install v4l2loopback-source module-assistant + # module-assistant auto-install v4l2loopback-source + +# DOWNLOAD +the most up-to-date version of this module can be found at +http://github.com/umlaeute/v4l2loopback/. + +# LICENSE/COPYING + +- Copyright (c) 2010-2015 IOhannes m zmoelnig +- Copyright (c) 2014-2015 Tasos Sahanidis +- Copyright (c) 2012-2015 Yusuke Ohshima +- Copyright (c) 2015 Tom Zerucha +- Copyright (c) 2013 Aidan Thornton +- Copyright (c) 2013 Anatolij Gustschin +- Copyright (c) 2012 Ted Mielczarek +- Copyright (c) 2012 Anton Novikov +- Copyright (c) 2011 Stefan Diewald +- Copyright (c) 2010 Scott Maines +- Copyright (c) 2009 Gorinich Zmey +- Copyright (c) 2005-2009 Vasily Levin + + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This package 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, see . + + diff --git a/extra_modules/v4l2loopback/TODO b/extra_modules/v4l2loopback/TODO new file mode 100644 index 00000000..e4b4c166 --- /dev/null +++ b/extra_modules/v4l2loopback/TODO @@ -0,0 +1,31 @@ +TODO for v4l2loopback in no specific order + +- fix all bugs :-) + +- improve buffering (salsaman) + +- allow USERPTR buffers + +- allow to use the device without streaming i/o + +- pass 'v4l2-compliance' tests + currently failing are: + VIDIOC_G/S_PRIORITY + VIDIOC_LOG_STATUS + VIDIOC_ENUMAUDIO + VIDIOC_G/S_AUDIO + VIDIOC_ENUMAUDOUT + VIDIOC_G/S/ENUMOUTPUT + VIDIOC_G/S_CTRL + VIDIOC_G/S/TRY_EXT_CTRLS + VIDIOC_ENUM/G/S/QUERY_STD + VIDIOC_ENUM/G/S/QUERY_DV_PRESETS + VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS + VIDIOC_G_FBUF + VIDIOC_G_FMT + VIDIOC_G_SLICED_VBI_CAP + +- it would be nice to have a way to communicate format requests from the + consumer to the producer (though i see no way how to do that) + +- provide more producers for more colorspaces in the examples diff --git a/extra_modules/v4l2loopback/currentversion.sh b/extra_modules/v4l2loopback/currentversion.sh new file mode 100755 index 00000000..9230ab8a --- /dev/null +++ b/extra_modules/v4l2loopback/currentversion.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +grep "^#define V4L2LOOPBACK_VERSION_CODE KERNEL_VERSION" v4l2loopback.c \ +| sed -e 's|^#define V4L2LOOPBACK_VERSION_CODE KERNEL_VERSION||' \ + -e 's|^[^0-9]*||' -e 's|[^0-9]*$||' \ + -e 's|[^0-9][^0-9]*|.|g' diff --git a/extra_modules/v4l2loopback/dkms.conf b/extra_modules/v4l2loopback/dkms.conf new file mode 100644 index 00000000..f01d9469 --- /dev/null +++ b/extra_modules/v4l2loopback/dkms.conf @@ -0,0 +1,12 @@ +PACKAGE_NAME="v4l2loopback" +PACKAGE_VERSION="0.9.1" + +# Items below here should not have to change with each driver version +MAKE[0]="make KERNEL_DIR=${kernel_source_dir} all" +CLEAN="make clean" + +BUILT_MODULE_NAME[0]="$PACKAGE_NAME" +DEST_MODULE_LOCATION[0]="/extra" + +REMAKE_INITRD="no" +AUTOINSTALL="yes" diff --git a/extra_modules/v4l2loopback/doc/docs.txt b/extra_modules/v4l2loopback/doc/docs.txt new file mode 100644 index 00000000..5192a358 --- /dev/null +++ b/extra_modules/v4l2loopback/doc/docs.txt @@ -0,0 +1,8 @@ +obsolete V4L2-API: + http://linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html + (an even more obsolete version 0.24 of this document used to be included + here, but is no longer) + +current V4L2-API: + http://linuxtv.org/downloads/v4l-dvb-apis/ + (unfortunately this is multi-page) diff --git a/extra_modules/v4l2loopback/doc/kernel_debugging.txt b/extra_modules/v4l2loopback/doc/kernel_debugging.txt new file mode 100644 index 00000000..56c8cba7 --- /dev/null +++ b/extra_modules/v4l2loopback/doc/kernel_debugging.txt @@ -0,0 +1,22 @@ +some hints how to debug kernel panics + + +https://wiki.ubuntu.com/Kernel/KernelDebuggingTricks + + +basically it is: +- run tests in a virtual machine (i use VirtualBox) +- configure the vm to have a serial output + VirtualBox-Settings/Serial Ports + enable serial port COM1 + port mode: Raw File + file path: /tmp/vbox_serial.log +- configure the vm's kernel to log to the kernel: + add "console=tty console=ttyS0,9600" to the kernel-parms + (i put that into grub) +- reboot +- raise the vm's kernel console verbosity: + echo 7 > /proc/sys/kernel/printk + +- run +- examine /tmp/vbox_serial.log on the host diff --git a/extra_modules/v4l2loopback/doc/makeformats.sh b/extra_modules/v4l2loopback/doc/makeformats.sh new file mode 100755 index 00000000..2f47a574 --- /dev/null +++ b/extra_modules/v4l2loopback/doc/makeformats.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +## usage: +# echo "V4L2_PIX_FMT_MPEG4 MPEG-4 part 2 ES" | $0 +## normally it's more like: +# cat /usr/include/linux/videodev2.h \ +# | grep "define V4L2_PIX_FMT" \ +# | sed -e "s|^#define ||" -e "s|v4l2_fourcc('.', '.', '.', '.')||" -e 's|/\*||' -e 's|\*/||' \ +# | $0 + +DEPTH=0 +FLAGS=0 + +while read FOURCC NAME +do + echo "#ifdef ${FOURCC}" + echo "{" + echo " .name = \"${NAME}\"," + echo " .fourcc = ${FOURCC}," + echo " .depth = ${DEPTH}," + echo " .flags = ${FLAGS}," + echo " }," + echo "#endif /* ${FOURCC} */" +done diff --git a/extra_modules/v4l2loopback/doc/missingformats.h b/extra_modules/v4l2loopback/doc/missingformats.h new file mode 100644 index 00000000..89de33cb --- /dev/null +++ b/extra_modules/v4l2loopback/doc/missingformats.h @@ -0,0 +1,291 @@ +#ifdef V4L2_PIX_FMT_Y10BPACK + }, { + .name = "10 bpp Greyscale bit-packed", + .fourcc = V4L2_PIX_FMT_Y10BPACK, + .depth = 10, + .flags = 0, +#endif /* V4L2_PIX_FMT_Y10BPACK */ +#ifdef V4L2_PIX_FMT_PAL8 + }, { + .name = "8 bpp 8-bit palette", + .fourcc = V4L2_PIX_FMT_PAL8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_PAL8 */ +#ifdef V4L2_PIX_FMT_UV8 + }, { + .name = "8 bpp UV 4:4", + .fourcc = V4L2_PIX_FMT_UV8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_UV8 */ + +#ifdef V4L2_PIX_FMT_HI240 + }, { + .name = "8 bpp 8-bit color ", + .fourcc = V4L2_PIX_FMT_HI240, + .depth = 8, + .flags = FORMAT_FLAGS_PLANAR, +#endif /* V4L2_PIX_FMT_HI240 */ +#ifdef V4L2_PIX_FMT_HM12 + }, { + .name = "8 bpp YUV 4:2:0 16x16 macroblocks", + .fourcc = V4L2_PIX_FMT_HM12, + .depth = 8, + .flags = FORMAT_FLAGS_PLANAR, +#endif /* V4L2_PIX_FMT_HM12 */ +#ifdef V4L2_PIX_FMT_M420 + }, { + .name = "12 bpp YUV 4:2:0 2 lines y, 1 line uv interleaved", + .fourcc = V4L2_PIX_FMT_M420, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, +#endif /* V4L2_PIX_FMT_M420 */ + + + +#ifdef V4L2_PIX_FMT_NV12 + }, { + .name = "12 bpp Y/CbCr 4:2:0 ", + .fourcc = V4L2_PIX_FMT_NV12, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV12 */ +#ifdef V4L2_PIX_FMT_NV21 + }, { + .name = "12 bpp Y/CrCb 4:2:0 ", + .fourcc = V4L2_PIX_FMT_NV21, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV21 */ +#ifdef V4L2_PIX_FMT_NV16 + }, { + .name = "16 bpp Y/CbCr 4:2:2 ", + .fourcc = V4L2_PIX_FMT_NV16, + .depth = 16, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV16 */ +#ifdef V4L2_PIX_FMT_NV61 + }, { + .name = "16 bpp Y/CrCb 4:2:2 ", + .fourcc = V4L2_PIX_FMT_NV61, + .depth = 16, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV61 */ +#ifdef V4L2_PIX_FMT_NV24 + }, { + .name = "24 bpp Y/CbCr 4:4:4 ", + .fourcc = V4L2_PIX_FMT_NV24, + .depth = 24, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV24 */ +#ifdef V4L2_PIX_FMT_NV42 + }, { + .name = "24 bpp Y/CrCb 4:4:4 ", + .fourcc = V4L2_PIX_FMT_NV42, + .depth = 24, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV42 */ +#ifdef V4L2_PIX_FMT_NV12M + }, { + .name = "12 bpp Y/CbCr 4:2:0 ", + .fourcc = V4L2_PIX_FMT_NV12M, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV12M */ +#ifdef V4L2_PIX_FMT_NV21M + }, { + .name = "21 bpp Y/CrCb 4:2:0 ", + .fourcc = V4L2_PIX_FMT_NV21M, + .depth = 21, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV21M */ +#ifdef V4L2_PIX_FMT_NV16M + }, { + .name = "16 bpp Y/CbCr 4:2:2 ", + .fourcc = V4L2_PIX_FMT_NV16M, + .depth = 16, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV16M */ +#ifdef V4L2_PIX_FMT_NV61M + }, { + .name = "16 bpp Y/CrCb 4:2:2 ", + .fourcc = V4L2_PIX_FMT_NV61M, + .depth = 16, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV61M */ +#ifdef V4L2_PIX_FMT_NV12MT + }, { + .name = "12 bpp Y/CbCr 4:2:0 64x32 macroblocks", + .fourcc = V4L2_PIX_FMT_NV12MT, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV12MT */ +#ifdef V4L2_PIX_FMT_NV12MT_16X16 + }, { + .name = "12 bpp Y/CbCr 4:2:0 16x16 macroblocks", + .fourcc = V4L2_PIX_FMT_NV12MT_16X16, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_NV12MT_16X16 */ +#ifdef V4L2_PIX_FMT_YUV420M + }, { + .name = "12 bpp YUV420 planar", + .fourcc = V4L2_PIX_FMT_YUV420M, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_YUV420M */ +#ifdef V4L2_PIX_FMT_YVU420M + }, { + .name = "12 bpp YVU420 planar", + .fourcc = V4L2_PIX_FMT_YVU420M, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_YVU420M */ +#ifdef V4L2_PIX_FMT_SBGGR8 + }, { + .name = "8 bpp BGBG.. GRGR..", + .fourcc = V4L2_PIX_FMT_SBGGR8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR8 */ +#ifdef V4L2_PIX_FMT_SGBRG8 + }, { + .name = "8 bpp GBGB.. RGRG..", + .fourcc = V4L2_PIX_FMT_SGBRG8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGBRG8 */ +#ifdef V4L2_PIX_FMT_SGRBG8 + }, { + .name = "8 bpp GRGR.. BGBG..", + .fourcc = V4L2_PIX_FMT_SGRBG8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGRBG8 */ +#ifdef V4L2_PIX_FMT_SRGGB8 + }, { + .name = "8 bpp RGRG.. GBGB..", + .fourcc = V4L2_PIX_FMT_SRGGB8, + .depth = 8, + .flags = 0, +#endif /* V4L2_PIX_FMT_SRGGB8 */ +#ifdef V4L2_PIX_FMT_SBGGR10 + }, { + .name = "10 bpp BGBG.. GRGR..", + .fourcc = V4L2_PIX_FMT_SBGGR10, + .depth = 10, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR10 */ +#ifdef V4L2_PIX_FMT_SGBRG10 + }, { + .name = "10 bpp GBGB.. RGRG..", + .fourcc = V4L2_PIX_FMT_SGBRG10, + .depth = 10, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGBRG10 */ +#ifdef V4L2_PIX_FMT_SGRBG10 + }, { + .name = "10 bpp GRGR.. BGBG..", + .fourcc = V4L2_PIX_FMT_SGRBG10, + .depth = 10, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGRBG10 */ +#ifdef V4L2_PIX_FMT_SRGGB10 + }, { + .name = "10 bpp RGRG.. GBGB..", + .fourcc = V4L2_PIX_FMT_SRGGB10, + .depth = 10, + .flags = 0, +#endif /* V4L2_PIX_FMT_SRGGB10 */ +#ifdef V4L2_PIX_FMT_SBGGR12 + }, { + .name = "12 bpp BGBG.. GRGR..", + .fourcc = V4L2_PIX_FMT_SBGGR12, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR12 */ +#ifdef V4L2_PIX_FMT_SGBRG12 + }, { + .name = "12 bpp GBGB.. RGRG..", + .fourcc = V4L2_PIX_FMT_SGBRG12, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGBRG12 */ +#ifdef V4L2_PIX_FMT_SGRBG12 + }, { + .name = "12 bpp GRGR.. BGBG..", + .fourcc = V4L2_PIX_FMT_SGRBG12, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGRBG12 */ +#ifdef V4L2_PIX_FMT_SRGGB12 + }, { + .name = "12 bpp RGRG.. GBGB..", + .fourcc = V4L2_PIX_FMT_SRGGB12, + .depth = 12, + .flags = 0, +#endif /* V4L2_PIX_FMT_SRGGB12 */ +#ifdef V4L2_PIX_FMT_SBGGR10ALAW8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SBGGR10ALAW8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR10ALAW8 */ +#ifdef V4L2_PIX_FMT_SGBRG10ALAW8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SGBRG10ALAW8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGBRG10ALAW8 */ +#ifdef V4L2_PIX_FMT_SGRBG10ALAW8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SGRBG10ALAW8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGRBG10ALAW8 */ +#ifdef V4L2_PIX_FMT_SRGGB10ALAW8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SRGGB10ALAW8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SRGGB10ALAW8 */ +#ifdef V4L2_PIX_FMT_SBGGR10DPCM8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SBGGR10DPCM8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR10DPCM8 */ +#ifdef V4L2_PIX_FMT_SGBRG10DPCM8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SGBRG10DPCM8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGBRG10DPCM8 */ +#ifdef V4L2_PIX_FMT_SGRBG10DPCM8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SGRBG10DPCM8 */ +#ifdef V4L2_PIX_FMT_SRGGB10DPCM8 + }, { + .name = "", + .fourcc = V4L2_PIX_FMT_SRGGB10DPCM8, + .depth = 0, + .flags = 0, +#endif /* V4L2_PIX_FMT_SRGGB10DPCM8 */ +#ifdef V4L2_PIX_FMT_SBGGR16 + }, { + .name = "16 bpp BGBG.. GRGR..", + .fourcc = V4L2_PIX_FMT_SBGGR16, + .depth = 16, + .flags = 0, +#endif /* V4L2_PIX_FMT_SBGGR16 */ diff --git a/extra_modules/v4l2loopback/doc/v4l2_formats.txt b/extra_modules/v4l2loopback/doc/v4l2_formats.txt new file mode 100644 index 00000000..a47f6f8f --- /dev/null +++ b/extra_modules/v4l2loopback/doc/v4l2_formats.txt @@ -0,0 +1,116 @@ +/* RGB formats */ +V4L2_PIX_FMT_RGB332 /* 8 RGB-3-3-2 */ +V4L2_PIX_FMT_RGB444 /* 16 xxxxrrrr ggggbbbb */ +V4L2_PIX_FMT_RGB555 /* 16 RGB-5-5-5 */ +V4L2_PIX_FMT_RGB565 /* 16 RGB-5-6-5 */ +V4L2_PIX_FMT_RGB555X /* 16 RGB-5-5-5 BE */ +V4L2_PIX_FMT_RGB565X /* 16 RGB-5-6-5 BE */ +V4L2_PIX_FMT_BGR666 /* 18 BGR-6-6-6 */ +V4L2_PIX_FMT_BGR24 /* 24 BGR-8-8-8 */ +V4L2_PIX_FMT_RGB24 /* 24 RGB-8-8-8 */ +V4L2_PIX_FMT_BGR32 /* 32 BGR-8-8-8-8 */ +V4L2_PIX_FMT_RGB32 /* 32 RGB-8-8-8-8 */ + +/* Grey formats */ +V4L2_PIX_FMT_GREY /* 8 Greyscale */ +V4L2_PIX_FMT_Y4 /* 4 Greyscale */ +V4L2_PIX_FMT_Y6 /* 6 Greyscale */ +V4L2_PIX_FMT_Y10 /* 10 Greyscale */ +V4L2_PIX_FMT_Y12 /* 12 Greyscale */ +V4L2_PIX_FMT_Y16 /* 16 Greyscale */ + +/* Grey bit-packed formats */ +V4L2_PIX_FMT_Y10BPACK /* 10 Greyscale bit-packed */ + +/* Palette formats */ +V4L2_PIX_FMT_PAL8 /* 8 8-bit palette */ + +/* Chrominance formats */ +V4L2_PIX_FMT_UV8 /* 8 UV 4:4 */ + +/* Luminance+Chrominance formats */ +V4L2_PIX_FMT_YVU410 /* 9 YVU 4:1:0 */ +V4L2_PIX_FMT_YVU420 /* 12 YVU 4:2:0 */ +V4L2_PIX_FMT_YUYV /* 16 YUV 4:2:2 */ +V4L2_PIX_FMT_YYUV /* 16 YUV 4:2:2 */ +V4L2_PIX_FMT_YVYU /* 16 YVU 4:2:2 */ +V4L2_PIX_FMT_UYVY /* 16 YUV 4:2:2 */ +V4L2_PIX_FMT_VYUY /* 16 YUV 4:2:2 */ +V4L2_PIX_FMT_YUV422P /* 16 YVU422 planar */ +V4L2_PIX_FMT_YUV411P /* 16 YVU411 planar */ +V4L2_PIX_FMT_Y41P /* 12 YUV 4:1:1 */ +V4L2_PIX_FMT_YUV444 /* 16 xxxxyyyy uuuuvvvv */ +V4L2_PIX_FMT_YUV555 /* 16 YUV-5-5-5 */ +V4L2_PIX_FMT_YUV565 /* 16 YUV-5-6-5 */ +V4L2_PIX_FMT_YUV32 /* 32 YUV-8-8-8-8 */ +V4L2_PIX_FMT_YUV410 /* 9 YUV 4:1:0 */ +V4L2_PIX_FMT_YUV420 /* 12 YUV 4:2:0 */ +V4L2_PIX_FMT_HI240 /* 8 8-bit color */ +V4L2_PIX_FMT_HM12 /* 8 YUV 4:2:0 16x16 macroblocks */ +V4L2_PIX_FMT_M420 /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +V4L2_PIX_FMT_NV12 /* 12 Y/CbCr 4:2:0 */ +V4L2_PIX_FMT_NV21 /* 12 Y/CrCb 4:2:0 */ +V4L2_PIX_FMT_NV16 /* 16 Y/CbCr 4:2:2 */ +V4L2_PIX_FMT_NV61 /* 16 Y/CrCb 4:2:2 */ +V4L2_PIX_FMT_NV24 /* 24 Y/CbCr 4:4:4 */ +V4L2_PIX_FMT_NV42 /* 24 Y/CrCb 4:4:4 */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +V4L2_PIX_FMT_NV12M /* 12 Y/CbCr 4:2:0 */ +V4L2_PIX_FMT_NV21M /* 21 Y/CrCb 4:2:0 */ +V4L2_PIX_FMT_NV16M /* 16 Y/CbCr 4:2:2 */ +V4L2_PIX_FMT_NV61M /* 16 Y/CrCb 4:2:2 */ +V4L2_PIX_FMT_NV12MT /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +V4L2_PIX_FMT_NV12MT_16X16 /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +V4L2_PIX_FMT_YUV420M /* 12 YUV420 planar */ +V4L2_PIX_FMT_YVU420M /* 12 YVU420 planar */ + +/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ +V4L2_PIX_FMT_SBGGR8 /* 8 BGBG.. GRGR.. */ +V4L2_PIX_FMT_SGBRG8 /* 8 GBGB.. RGRG.. */ +V4L2_PIX_FMT_SGRBG8 /* 8 GRGR.. BGBG.. */ +V4L2_PIX_FMT_SRGGB8 /* 8 RGRG.. GBGB.. */ +V4L2_PIX_FMT_SBGGR10 /* 10 BGBG.. GRGR.. */ +V4L2_PIX_FMT_SGBRG10 /* 10 GBGB.. RGRG.. */ +V4L2_PIX_FMT_SGRBG10 /* 10 GRGR.. BGBG.. */ +V4L2_PIX_FMT_SRGGB10 /* 10 RGRG.. GBGB.. */ +V4L2_PIX_FMT_SBGGR12 /* 12 BGBG.. GRGR.. */ +V4L2_PIX_FMT_SGBRG12 /* 12 GBGB.. RGRG.. */ +V4L2_PIX_FMT_SGRBG12 /* 12 GRGR.. BGBG.. */ +V4L2_PIX_FMT_SRGGB12 /* 12 RGRG.. GBGB.. */ + /* 10bit raw bayer a-law compressed to 8 bits */ +V4L2_PIX_FMT_SBGGR10ALAW8 +V4L2_PIX_FMT_SGBRG10ALAW8 +V4L2_PIX_FMT_SGRBG10ALAW8 +V4L2_PIX_FMT_SRGGB10ALAW8 + /* 10bit raw bayer DPCM compressed to 8 bits */ +V4L2_PIX_FMT_SBGGR10DPCM8 +V4L2_PIX_FMT_SGBRG10DPCM8 +V4L2_PIX_FMT_SGRBG10DPCM8 +V4L2_PIX_FMT_SRGGB10DPCM8 + /* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +V4L2_PIX_FMT_SBGGR16 /* 16 BGBG.. GRGR.. */ + +/* compressed formats */ +V4L2_PIX_FMT_MJPEG /* Motion-JPEG */ +V4L2_PIX_FMT_JPEG /* JFIF JPEG */ +V4L2_PIX_FMT_DV /* 1394 */ +V4L2_PIX_FMT_MPEG /* MPEG-1/2/4 Multiplexed */ +V4L2_PIX_FMT_H264 /* H264 with start codes */ +V4L2_PIX_FMT_H264_NO_SC /* H264 without start codes */ +V4L2_PIX_FMT_H264_MVC /* H264 MVC */ +V4L2_PIX_FMT_H263 /* H263 */ +V4L2_PIX_FMT_MPEG1 /* MPEG-1 ES */ +V4L2_PIX_FMT_MPEG2 /* MPEG-2 ES */ +V4L2_PIX_FMT_MPEG4 /* MPEG-4 part 2 ES */ +V4L2_PIX_FMT_XVID /* Xvid */ +V4L2_PIX_FMT_VC1_ANNEX_G /* SMPTE 421M Annex G compliant stream */ +V4L2_PIX_FMT_VC1_ANNEX_L /* SMPTE 421M Annex L compliant stream */ +V4L2_PIX_FMT_VP8 /* VP8 */ diff --git a/extra_modules/v4l2loopback/examples/.gitignore b/extra_modules/v4l2loopback/examples/.gitignore new file mode 100644 index 00000000..7773c094 --- /dev/null +++ b/extra_modules/v4l2loopback/examples/.gitignore @@ -0,0 +1,2 @@ +test +yuv4mpeg_to_v4l2 diff --git a/extra_modules/v4l2loopback/examples/Makefile b/extra_modules/v4l2loopback/examples/Makefile new file mode 100644 index 00000000..f58c7436 --- /dev/null +++ b/extra_modules/v4l2loopback/examples/Makefile @@ -0,0 +1,11 @@ +TARGETS=test yuv4mpeg_to_v4l2 ondemandcam + +.PHONY: all clean + +all: $(TARGETS) + +ondemandcam: ondemandcam.c + gcc -o ondemandcam ondemandcam.c -lrt -lpthread + +clean: + -rm $(TARGETS) diff --git a/extra_modules/v4l2loopback/examples/README b/extra_modules/v4l2loopback/examples/README new file mode 100644 index 00000000..636fc767 --- /dev/null +++ b/extra_modules/v4l2loopback/examples/README @@ -0,0 +1,46 @@ +v4l2loopback tests +================== + +test +---- + +this small sample application will write an image into a v4l2loopback device. +the image will be 640x480 pixels in UYVY colorspace (and since all pixels are +set to "0" it will be green). +the video-device defaults to /dev/video1 but you can specify another device on +the commandline + +USAGE: +$ make test +$ ./test /dev/video2 & +$ xawtv -c /dev/video2 + +if you want to use another device you need to modify the VIDEO_DEVICE define at +the beginning of the code and recompile. + + +yuv4mpeg_to_v4l2 +---------------- +Copyright (C) 2011 Eric C. Cooper + +Example using mplayer as a producer for the v4l2loopback driver: + +$ mkfifo /tmp/pipe +$ ./yuv4mpeg_to_v4l2 < /tmp/pipe & +$ mplayer movie.mp4 -vo yuv4mpeg:file=/tmp/pipe + +ondemandcam +----------- +Copyright 2015, tz@execpc.com, GPLv3. +This will wait until something connects to pull frames then sends them. +It uses two threads and semaphores to do the testing. +It can setup and teardown the frame source. +The example just sends a different color each second. +It is 80x60 (it is a skeleton for hardware with this resolution) + +$ make ondemandcam +$ ondemandcam /dev/videoX & # where X is the v4l2loopback device + +It can be viewed with: + +$ vlc v4l2:///dev/videoX # X is same device as above diff --git a/extra_modules/v4l2loopback/examples/ondemandcam.c b/extra_modules/v4l2loopback/examples/ondemandcam.c new file mode 100755 index 00000000..eae56bb7 --- /dev/null +++ b/extra_modules/v4l2loopback/examples/ondemandcam.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include /* low-level i/o */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *v4l2dev = "/dev/video1"; +static int v4l2sink = -1; +static int width = 80; //640; // Default for Flash +static int height = 60; //480; // Default for Flash +static char *vidsendbuf = NULL; +static int vidsendsiz = 0; + +static void init_device() { + +} + +static void grab_frame() { + + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + memset( vidsendbuf, 0, 3); + switch( ts.tv_sec & 3 ) { + case 0: + vidsendbuf[0] = 255; + break; + case 1: + vidsendbuf[0] = 255; + vidsendbuf[1] = 255; + break; + case 2: + vidsendbuf[1] = 255; + break; + case 3: + vidsendbuf[2] = 255; + break; + } + memcpy( vidsendbuf+3, vidsendbuf, vidsendsiz-3 ); +} + +static void stop_device() { + +} + +static void open_vpipe() +{ + v4l2sink = open(v4l2dev, O_WRONLY); + if (v4l2sink < 0) { + fprintf(stderr, "Failed to open v4l2sink device. (%s)\n", strerror(errno)); + exit(-2); + } + // setup video for proper format + struct v4l2_format v; + int t; + v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + t = ioctl(v4l2sink, VIDIOC_G_FMT, &v); + if( t < 0 ) + exit(t); + v.fmt.pix.width = width; + v.fmt.pix.height = height; + v.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; + vidsendsiz = width * height * 3; + v.fmt.pix.sizeimage = vidsendsiz; + t = ioctl(v4l2sink, VIDIOC_S_FMT, &v); + if( t < 0 ) + exit(t); + vidsendbuf = malloc( vidsendsiz ); +} + +static pthread_t sender; +static sem_t lock1,lock2; +static void *sendvid(void *v) +{ + for (;;) { + sem_wait(&lock1); + if (vidsendsiz != write(v4l2sink, vidsendbuf, vidsendsiz)) + exit(-1); + sem_post(&lock2); + } +} + +int main(int argc, char **argv) +{ + struct timespec ts; + + if( argc == 2 ) + v4l2dev = argv[1]; + + open_vpipe(); + + // open and lock response + if (sem_init(&lock2, 0, 1) == -1) + exit(-1); + sem_wait(&lock2); + + if (sem_init(&lock1, 0, 1) == -1) + exit(-1); + pthread_create(&sender, NULL, sendvid, NULL); + + for (;;) { + // wait until a frame can be written + fprintf( stderr, "Waiting for sink\n" ); + sem_wait(&lock2); + // setup source + init_device(); // open and setup SPI + for (;;) { + grab_frame(); + // push it out + sem_post(&lock1); + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 2; + // wait for it to get written (or is blocking) + if (sem_timedwait(&lock2, &ts)) + break; + } + stop_device(); // close SPI + } + close(v4l2sink); + return 0; +} diff --git a/extra_modules/v4l2loopback/examples/restarting-writer.sh b/extra_modules/v4l2loopback/examples/restarting-writer.sh new file mode 100755 index 00000000..012c394d --- /dev/null +++ b/extra_modules/v4l2loopback/examples/restarting-writer.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +device=${1:-/dev/video0} +echo Using $device + +run_writers() { + declare -a nbufs + nbufs=(10 9 4 5 6) + #nbufs=(12 12 12 12 12) + for i in `seq 0 4`; do + sleep 1 + gst-launch-0.10 videotestsrc horizontal-speed=1 num-buffers=90 ! v4l2sink queue-size=${nbufs[$i]} device=$device + done +} + +#v4l2-ctl -d $device -c keep_format=1 || exit 1 +./utils/v4l2loopback-ctl set-caps "video/x-raw-yuv, width=640, height=480, framerate=(fraction)25/1" $device || exit 1 +v4l2-ctl -d $device -c sustain_framerate=0 || exit 1 +v4l2-ctl -d $device -c timeout=2000 || exit 1 +gst-launch-0.10 videotestsrc num-buffers=1 ! v4l2sink device=$device || exit 1 +{ + run_writers + sleep 10 + # can see a flash of green here + v4l2-ctl -d $device -c sustain_framerate=1 || exit 1 + run_writers + sleep 10 + run_writers +} >/dev/null & +gst-launch-0.10 v4l2src queue-size=3 device=$device ! timeoverlay ! ffmpegcolorspace ! autovideosink +kill $! 2>/dev/null +wait diff --git a/extra_modules/v4l2loopback/examples/test.c b/extra_modules/v4l2loopback/examples/test.c new file mode 100644 index 00000000..4d9c1cb6 --- /dev/null +++ b/extra_modules/v4l2loopback/examples/test.c @@ -0,0 +1,188 @@ +/* + * How to test v4l2loopback: + * 1. launch this test program (even in background), it will initialize the + * loopback device and keep it open so it won't loose the settings. + * 2. Feed the video device with data according to the settings specified + * below: size, pixelformat, etc. + * For instance, you can try the default settings with this command: + * mencoder video.avi -ovc raw -nosound -vf scale=640:480,format=yuy2 -o /dev/video1 + * TODO: a command that limits the fps would be better :) + * + * Test the video in your favourite viewer, for instance: + * luvcview -d /dev/video1 -f yuyv + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define ROUND_UP_2(num) (((num)+1)&~1) +#define ROUND_UP_4(num) (((num)+3)&~3) +#define ROUND_UP_8(num) (((num)+7)&~7) +#define ROUND_UP_16(num) (((num)+15)&~15) +#define ROUND_UP_32(num) (((num)+31)&~31) +#define ROUND_UP_64(num) (((num)+63)&~63) + + + + +#if 0 +# define CHECK_REREAD +#endif + +#define VIDEO_DEVICE "/dev/video0" +#if 1 +# define FRAME_WIDTH 640 +# define FRAME_HEIGHT 480 +#else +# define FRAME_WIDTH 512 +# define FRAME_HEIGHT 512 +#endif + +#if 0 +# define FRAME_FORMAT V4L2_PIX_FMT_YUYV +#else +# define FRAME_FORMAT V4L2_PIX_FMT_YVU420 +#endif + +static int debug=0; + + +int format_properties(const unsigned int format, + const unsigned int width, + const unsigned int height, + size_t*linewidth, + size_t*framewidth) { +size_t lw, fw; + switch(format) { + case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: + lw = width; /* ??? */ + fw = ROUND_UP_4 (width) * ROUND_UP_2 (height); + fw += 2 * ((ROUND_UP_8 (width) / 2) * (ROUND_UP_2 (height) / 2)); + break; + case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_Y41P: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: + lw = (ROUND_UP_2 (width) * 2); + fw = lw * height; + break; + default: + return 0; + } + + if(linewidth)*linewidth=lw; + if(framewidth)*framewidth=fw; + + return 1; +} + + +void print_format(struct v4l2_format*vid_format) { + printf(" vid_format->type =%d\n", vid_format->type ); + printf(" vid_format->fmt.pix.width =%d\n", vid_format->fmt.pix.width ); + printf(" vid_format->fmt.pix.height =%d\n", vid_format->fmt.pix.height ); + printf(" vid_format->fmt.pix.pixelformat =%d\n", vid_format->fmt.pix.pixelformat); + printf(" vid_format->fmt.pix.sizeimage =%d\n", vid_format->fmt.pix.sizeimage ); + printf(" vid_format->fmt.pix.field =%d\n", vid_format->fmt.pix.field ); + printf(" vid_format->fmt.pix.bytesperline=%d\n", vid_format->fmt.pix.bytesperline ); + printf(" vid_format->fmt.pix.colorspace =%d\n", vid_format->fmt.pix.colorspace ); +} + +int main(int argc, char**argv) +{ + struct v4l2_capability vid_caps; + struct v4l2_format vid_format; + + size_t framesize; + size_t linewidth; + + __u8*buffer; + __u8*check_buffer; + + const char*video_device=VIDEO_DEVICE; + int fdwr = 0; + int ret_code = 0; + + int i; + + if(argc>1) { + video_device=argv[1]; + printf("using output device: %s\n", video_device); + } + + fdwr = open(video_device, O_RDWR); + assert(fdwr >= 0); + + ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps); + assert(ret_code != -1); + + memset(&vid_format, 0, sizeof(vid_format)); + + ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format); + if(debug)print_format(&vid_format); + + vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + vid_format.fmt.pix.width = FRAME_WIDTH; + vid_format.fmt.pix.height = FRAME_HEIGHT; + vid_format.fmt.pix.pixelformat = FRAME_FORMAT; + vid_format.fmt.pix.sizeimage = framesize; + vid_format.fmt.pix.field = V4L2_FIELD_NONE; + vid_format.fmt.pix.bytesperline = linewidth; + vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + + if(debug)print_format(&vid_format); + ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format); + + assert(ret_code != -1); + + if(debug)printf("frame: format=%d\tsize=%d\n", FRAME_FORMAT, framesize); + print_format(&vid_format); + + if(!format_properties(vid_format.fmt.pix.pixelformat, + vid_format.fmt.pix.width, vid_format.fmt.pix.height, + &linewidth, + &framesize)) { + printf("unable to guess correct settings for format '%d'\n", FRAME_FORMAT); + } + buffer=(__u8*)malloc(sizeof(__u8)*framesize); + check_buffer=(__u8*)malloc(sizeof(__u8)*framesize); + + memset(buffer, 0, framesize); + memset(check_buffer, 0, framesize); + for (i = 0; i < framesize; ++i) { + //buffer[i] = i % 2; + check_buffer[i] = 0; + } + + + + + + write(fdwr, buffer, framesize); + +#ifdef CHECK_REREAD + do { + /* check if we get the same data on output */ + int fdr = open(video_device, O_RDONLY); + read(fdr, check_buffer, framesize); + for (i = 0; i < framesize; ++i) { + if (buffer[i] != check_buffer[i]) + assert(0); + } + close(fdr); + } while(0); +#endif + + pause(); + + close(fdwr); + + free(buffer); + free(check_buffer); + + return 0; +} diff --git a/extra_modules/v4l2loopback/examples/yuv4mpeg_to_v4l2.c b/extra_modules/v4l2loopback/examples/yuv4mpeg_to_v4l2.c new file mode 100644 index 00000000..47c87e2a --- /dev/null +++ b/extra_modules/v4l2loopback/examples/yuv4mpeg_to_v4l2.c @@ -0,0 +1,184 @@ +/* + * Copy a YUV4MPEG stream to a v4l2 output device. + * The stream is read from standard input. + * The device can be specified as argument; it defaults to /dev/video0. + * + * Example using mplayer as a producer for the v4l2loopback driver: + * + * $ mkfifo /tmp/pipe + * $ ./yuv4mpeg_to_v4l2 < /tmp/pipe & + * $ mplayer movie.mp4 -vo yuv4mpeg:file=/tmp/pipe + * + * Copyright (C) 2011 Eric C. Cooper + * Released under the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include + +char *prog; + +char *device; +int dev_fd; + +int frame_width; +int frame_height; +int frame_bytes; + +void +usage(void) +{ + fprintf(stderr, "Usage: %s [/dev/videoN]\n", prog); + exit(1); +} + +void +process_args(int argc, char **argv) +{ + prog = argv[0]; + switch (argc) { + case 1: + device = "/dev/video0"; + break; + case 2: + device = argv[1]; + break; + default: + usage(); + break; + } +} + +void +sysfail(char *msg) +{ + perror(msg); + exit(1); +} + +void +fail(char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +void +bad_header(char *kind) +{ + char msg[64]; + + sprintf(msg, "malformed %s header", kind); + fail(msg); +} + +void +do_tag(char tag, char *value) +{ + switch (tag) { + case 'W': + frame_width = strtoul(value, NULL, 10); + break; + case 'H': + frame_height = strtoul(value, NULL, 10); + break; + } +} + +int +read_header(char *magic) +{ + char *p, *q, *p0; + size_t n; + int first, done; + + p0 = NULL; + if (getline(&p0, &n, stdin) == -1) { + free(p0); + return 0; + } + + q = p = p0; + first = 1; + done = 0; + while (!done) { + while (*q != ' ' && *q != '\n') + if (*q++ == '\0') bad_header(magic); + done = (*q == '\n'); + *q = '\0'; + if (first) + if (strcmp(p, magic) == 0) first = 0; + else bad_header(magic); + else + do_tag(*p, p + 1); + p = ++q; + } + + free(p0); + return 1; +} + +void +process_header(void) +{ + if (!read_header("YUV4MPEG2")) fail("missing YUV4MPEG2 header"); + frame_bytes = 3 * frame_width * frame_height / 2; + if (frame_bytes == 0) fail("frame width or height is missing"); +} + +void +copy_frames(void) +{ + char *frame; + + frame = malloc(frame_bytes); + if (frame == NULL) fail("cannot malloc frame"); + while (read_header("FRAME")) { + if (fread(frame, 1, frame_bytes, stdin) != frame_bytes) { + free(frame); + fail("malformed frame"); + } + else if (write(dev_fd, frame, frame_bytes) != frame_bytes) { + free(frame); + sysfail("write"); + } + } + + free(frame); +} + +#define vidioc(op, arg) \ + if (ioctl(dev_fd, VIDIOC_##op, arg) == -1) \ + sysfail(#op); \ + else + +void +open_video(void) +{ + struct v4l2_format v; + + dev_fd = open(device, O_RDWR); + if (dev_fd == -1) sysfail(device); + v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + vidioc(G_FMT, &v); + v.fmt.pix.width = frame_width; + v.fmt.pix.height = frame_height; + v.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; + v.fmt.pix.sizeimage = frame_bytes; + vidioc(S_FMT, &v); +} + +int +main(int argc, char **argv) +{ + process_args(argc, argv); + process_header(); + open_video(); + copy_frames(); + return 0; +} diff --git a/extra_modules/v4l2loopback/man/touch b/extra_modules/v4l2loopback/man/touch new file mode 100644 index 00000000..e69de29b diff --git a/extra_modules/v4l2loopback/release.sh b/extra_modules/v4l2loopback/release.sh new file mode 100755 index 00000000..d790b91c --- /dev/null +++ b/extra_modules/v4l2loopback/release.sh @@ -0,0 +1,100 @@ +#!/bin/sh +#################################### +# prepare package for release + +# DONE: get current version from module source +# DONE: ChangeLog generator using git-dch +# DONE: update dkms.conf +# TODO: automatically update AUTHORS +# TODO: automatically prepare NEWS (from ChangeLog) +# TODO: automatically launch editors for ChangeLog/NEWS/AUTHORS +# TODO: automatically tag (if all went well) + +CHANGELOG=ChangeLog +AUTHORS=AUTHORS +NEWS=NEWS + +error() { + echo "$@" 1>&2 +} +fatal() { + error "$@" + exit 1 +} +usage() { + fatal "usage: $0 [] " 1>&2 +} + +getoldversion () { + dpkg-parsechangelog --count 1 -l${CHANGELOG} | egrep "^Version:" | head -1 | cut -f2 -d' ' +} +getmoduleversion() { + grep "^#define V4L2LOOPBACK_VERSION_CODE KERNEL_VERSION" v4l2loopback.c \ + | sed -e 's|^#define V4L2LOOPBACK_VERSION_CODE KERNEL_VERSION||' \ + -e 's|^[^0-9]*||' -e 's|[^0-9]*$||' \ + -e 's|[^0-9][^0-9]*|.|g' +} +getgitbranch() { + git rev-parse --abbrev-ref HEAD +} + +if [ "$(getgitbranch)" != "master" ]; then + fatal "current branch '$(getgitbranch)' is not 'master'" +fi + +if [ "x$2" = "x" ]; then +## guess current version + NEWVERSION=$1 + OLDVERSION=$(getoldversion) +else + OLDVERSION=$1 + NEWVERSION=$2 +fi + +if [ "x${NEWVERSION}" = "x" ]; then + NEWVERSION=$(getmoduleversion) +fi + +if git tag -l v${OLDVERSION} | grep . >/dev/null +then + : +else + fatal "it seems like there is no tag 'v${OLDVERSION}'" +fi + +if [ "x${OLDVERSION}" = "x" ]; then + usage +fi + +echo "updating from ${OLDVERSION}" + +if [ "x${NEWVERSION}" = "x" ]; then + usage +fi + +if dpkg --compare-versions ${OLDVERSION} ge ${NEWVERSION} +then + fatal "version mismatch: ${NEWVErSION} is not newer than ${OLDVERSION}" +fi + +echo "updating to ${NEWVERSION}" + +OK=false +mkdir debian +cp ${CHANGELOG} debian/changelog +gbp dch -R --since "v${OLDVERSION}" -N "${NEWVERSION}" && cat debian/changelog > ${CHANGELOG} && OK=true +rm -rf debian + +if [ "x${OK}" = "xtrue" ]; then + sed -e "s|^PACKAGE_VERSION=\".*\"$|PACKAGE_VERSION=\"${NEWVERSION}\"|" -i dkms.conf +fi + +if [ "x${OK}" = "xtrue" ]; then + echo "all went well" + echo "" + echo "- please check your ${CHANGELOG}" + echo "- please check&edit your ${NEWS}" + echo "- please check&edit your ${AUTHORS}" + echo "- and don't forget to git-tag the new version as v${NEWVERSION}" + echo " git tag v${NEWVERSION} -m \"\"" +fi diff --git a/extra_modules/v4l2loopback/tests/Makefile b/extra_modules/v4l2loopback/tests/Makefile new file mode 100644 index 00000000..a1f8b8b2 --- /dev/null +++ b/extra_modules/v4l2loopback/tests/Makefile @@ -0,0 +1 @@ +all: test_dqbuf diff --git a/extra_modules/v4l2loopback/tests/interlaced_w b/extra_modules/v4l2loopback/tests/interlaced_w new file mode 100755 index 00000000..fa476ee0 --- /dev/null +++ b/extra_modules/v4l2loopback/tests/interlaced_w @@ -0,0 +1,43 @@ +#!/bin/sh + +DEVICE=$1 +WIDTH=320 +HEIGHT=240 +#WIDTH=1920 +#HEIGHT=1080 + + +## uncomment the 'progressive' line to switch to non-interlaced +INTERLACED=interlaced +#INTERLACED=progressive +INTERLACED=mixed + +error() { + echo "$@" 1>&2 +} +debug() { + error "$@" + $@ +} + +if [ "x${GSTLAUNCH}" = "x" ]; then + GSTLAUNCH=$(which gst-launch-1.0) +fi +if [ "x${GSTLAUNCH}" = "x" ]; then + error "need gst-launch-1.0" + exit 1 +fi +if [ "x${DEVICE}" = "x" ]; then + DEVICE=/dev/video0 +fi + +if [ -c "${DEVICE}" ]; then + : +else + error "illegal device ${DEVICE}" + exit 1 +fi + +debug ${GSTLAUNCH} videotestsrc horizontal-speed=16 \ + ! video/x-raw, format=UYVY, width=${WIDTH}, height=${HEIGHT}, frame-rate=30000/1001, interlace-mode=${INTERLACED} \ + ! v4l2sink device=${DEVICE} diff --git a/extra_modules/v4l2loopback/tests/test_dqbuf.c b/extra_modules/v4l2loopback/tests/test_dqbuf.c new file mode 100644 index 00000000..b5e6d979 --- /dev/null +++ b/extra_modules/v4l2loopback/tests/test_dqbuf.c @@ -0,0 +1,131 @@ +/* + * v4l2loopback.c -- video4linux2 loopback driver + * + * Copyright (C) 2014 Nicolas Dufresne + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define COUNT 4 +#define sysfail(msg) { printf ("%s failed: %s\n", (msg), strerror (errno)); return -1; } + +void +usage(const char*progname) +{ + printf("usage: %s \n", progname); + exit(1); +} + +int +main (int argc, char **argv) +{ + struct v4l2_format fmt = { 0 }; + struct v4l2_requestbuffers breq = { 0 }; + struct v4l2_buffer bufs[COUNT]; + void *data[COUNT] = { 0 }; + int fd; + int i; + + if(argc<2) usage(argv[0]); + + fd = open (argv[1], O_RDWR); + if (fd < 0) + sysfail("open"); + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + fmt.fmt.pix.width = 320; + fmt.fmt.pix.height = 240; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32; + + if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) + sysfail ("S_FMT"); + + breq.count = COUNT; + breq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + breq.memory = V4L2_MEMORY_MMAP; + + if (ioctl (fd, VIDIOC_REQBUFS, &breq) < 0) + sysfail ("REQBUFS"); + + assert (breq.count == COUNT); + + memset (bufs, 0, sizeof (bufs)); + + for (i = 0; i < COUNT; i++) { + int p; + + bufs[i].index = i; + bufs[i].type = breq.type; + bufs[i].memory = breq.memory; + + if (ioctl (fd, VIDIOC_QUERYBUF, &bufs[i]) < 0) + sysfail ("QUERYBUF"); + + data[i] = mmap (NULL, bufs[i].length, PROT_WRITE, MAP_SHARED, fd, bufs[i].m.offset); + if (data[i] == MAP_FAILED) + sysfail ("mmap"); + + for (p = 0; p < (bufs[i].bytesused >> 2); p++) + ((unsigned int*)data[i])[p] = 0xFF00FF00; + } + + if (ioctl (fd, VIDIOC_QBUF, &bufs[0]) < 0) + sysfail ("QBUF"); + + if ((bufs[0].flags & V4L2_BUF_FLAG_QUEUED) == 0) { + printf ("BUG #1: Driver should set the QUEUED flag before returning from QBUF\n"); + bufs[0].flags |= V4L2_BUF_FLAG_QUEUED; + } + + if (ioctl (fd, VIDIOC_STREAMON, &fmt.type) < 0) + sysfail ("STREAMON"); + + i = 1; + while (1) { + struct v4l2_buffer buf = { 0 }; + + if (ioctl (fd, VIDIOC_QBUF, &bufs[i]) < 0) + sysfail ("QBUF"); + + + printf ("\tQUEUED=%d\tDONE=%d\n", + bufs[i].flags & V4L2_BUF_FLAG_QUEUED, + bufs[i].flags & V4L2_BUF_FLAG_DONE); + + if ((bufs[i].flags & V4L2_BUF_FLAG_QUEUED) == 0) { + printf ("BUG #1: Driver should set the QUEUED flag before returning from QBUF\n"); + bufs[i].flags |= V4L2_BUF_FLAG_QUEUED; + } + + buf.type = breq.type; + buf.memory = breq.memory; + + if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) + sysfail ("DBBUF"); + + i = buf.index; + + if ((bufs[i].flags & V4L2_BUF_FLAG_QUEUED) == 0) { + printf ("BUG #2: Driver should not dequeue a buffer that was not intially queued\n"); + } + +#if 0 + assert (bufs[i].flags & V4L2_BUF_FLAG_QUEUED); + assert (!(buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))); +#endif + bufs[i] = buf; + } + + return 0; +} diff --git a/extra_modules/v4l2loopback/utils/v4l2loopback-ctl b/extra_modules/v4l2loopback/utils/v4l2loopback-ctl new file mode 100755 index 00000000..58528b0f --- /dev/null +++ b/extra_modules/v4l2loopback/utils/v4l2loopback-ctl @@ -0,0 +1,156 @@ +#!/bin/bash + +usage() { +## ugly linebreaks in order to make help2man more happy + cat < /dev/videoX Set device fps (if format is already + negotiated). + + set-timeout-image /dev/videoX Set timeout on device, and + optionally the placeholder picture, + instead of default null frame. + + set-caps /dev/videoX Fix format for the device (using GStreamer + caps), so it will be maintained until reset, + regardless of future readers/writers. + +Options: + FPS frames per second, either as integer ('30') or fraction ('50/2') + IMAGE image file ("no-input.png"), or 'videotestsrc' + CAPS GStreamer caps ("video/x-raw-yuv, width=640, height=480"), + or 'any' + /dev/videoX the v4l2-loopback device file you want to act on +! + exit 1 +} + +version() { +cat < +Copyright (c) 2012 Anton Novikov (random.plant@gmail.com) +! + exit 1 +} +die() { + echo "$@" 1>&2 + exit 1 +} + +parse_device() { + if [ -e "$1" ]; then + device="$1" + elif [ -e "/dev/video$1" ]; then + device="/dev/video$1" + else + die "can't parse device" + fi + sysfs=/sys/devices/virtual/video4linux/${device##*/} +} + +check_application() { + which $1 > /dev/null || die "can't find $1" +} + + +set_fps() { + fps="$1" + parse_device "$2" + [ -z "$fps" ] && usage + + echo "@$fps" | sudo tee "$sysfs/format" >/dev/null || die "Set fps failed" + echo OK +} + +set_caps() { + caps="$1" + parse_device "$2" + [ -z "$caps" ] && usage + + [ "$caps" = 'any' ] && { + check_application v4l2-ctl + v4l2-ctl -d $device -c keep_format=0 + return + } + + [ -n "`cat $sysfs/format`" ] && die "Device is busy" + declare -a params + declare -a nofps_params + IFS=',' read -ra params <<< "$caps" + for p in "${params[@]}"; do + if echo "$p" | grep -q framerate; then + fps=`echo "$p" | sed -r 's/.*(=|\))//g'` + echo "$fps" | grep -q '[^0-9/]' && die "could not parse framerate param" + echo "@$fps" | sudo tee $sysfs/format >/dev/null || die "could not set fps attr" + #echo "fps: $fps" + else + nofps_params=("${nofps_params[@]}" "$p") + fi + done + { + IFS=',' + nofps_caps="${nofps_params[*]}" + } + #echo "nofps_caps: $nofps_caps" + check_application v4l2-ctl + check_application gst-launch-1.0 + + v4l2-ctl -d $device -c keep_format=1 || exit 1 + v4l2-ctl -d $device -c sustain_framerate=1 || exit 1 + gst-launch-1.0 videotestsrc num-buffers=1 ! "$nofps_caps" ! v4l2sink device=$device || die "output to $device failed" +} + +set_timeout_image() { + imagefile="$1" + parse_device "$2" + + [ -z "$imagefile" ] && return + [ -n "`cat $sysfs/format`" ] || die "Device has no format negotiated" + + check_application v4l2-ctl + check_application gst-launch-1.0 + + v4l2-ctl -d $device -c timeout_image_io=1 + if [ "$imagefile" = 'videotestsrc' ]; then + gst-launch-1.0 videotestsrc num-buffers=1 ! v4l2sink device=$device + else + uri="file://`readlink -f $imagefile`" || die "no file" + echo "Reading from $uri" + gst-launch-1.0 uridecodebin uri=$uri ! videoconvert ! videoscale ! imagefreeze ! identity error-after=2 ! v4l2sink show-preroll-frame=false device=$device + fi + timeout=`v4l2-ctl -d $device -C timeout | sed -n 's/^timeout: //p'` + [ -n "$timeout" ] || die "couldn't get timeout" + echo "timeout: $timeout" + [ "$timeout" = 0 ] && { + echo 'Timeout is currently disabled; you can set it to some positive value, e.g.:' + echo "$ v4l2-ctl -d $device -c timeout=3000" + } +} + +command="$1" +shift +case "$command" in + "-h"|"--help") + usage + ;; + "-v"|"--version") + version + ;; + "set-fps") + set_fps "$@" + ;; + "set-caps") + set_caps "$@" + ;; + "set-timeout-image") + set_timeout_image "$@" + ;; + *) + usage + ;; +esac diff --git a/extra_modules/v4l2loopback/v4l2loopback.c b/extra_modules/v4l2loopback/v4l2loopback.c new file mode 100644 index 00000000..f8b15cde --- /dev/null +++ b/extra_modules/v4l2loopback/v4l2loopback.c @@ -0,0 +1,2443 @@ +/* -*- c-file-style: "linux" -*- */ +/* + * v4l2loopback.c -- video4linux2 loopback driver + * + * Copyright (C) 2005-2009 Vasily Levin (vasaka@gmail.com) + * Copyright (C) 2010-2014 IOhannes m zmoelnig (zmoelnig@iem.at) + * Copyright (C) 2011 Stefan Diewald (stefan.diewald@mytum.de) + * Copyright (C) 2012 Anton Novikov (random.plant@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +# define HAVE__V4L2_DEVICE +# include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) +# define HAVE__V4L2_CTRLS +# include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,1) +# define kstrtoul strict_strtoul +#endif + +#define V4L2LOOPBACK_VERSION_CODE KERNEL_VERSION(0, 9, 1) + +MODULE_DESCRIPTION("V4L2 loopback video device"); +MODULE_AUTHOR("Vasily Levin, " \ + "IOhannes m zmoelnig ," \ + "Stefan Diewald," \ + "Anton Novikov" \ + "et al." \ + ); +MODULE_LICENSE("GPL"); + +/* + * helpers + */ +#define STRINGIFY(s) #s +#define STRINGIFY2(s) STRINGIFY(s) + +#define dprintk(fmt, args...) \ + do { if (debug > 0) { \ + printk(KERN_INFO "v4l2-loopback[" STRINGIFY2(__LINE__) "]: " fmt, ##args); \ + } } while (0) + +#define MARK() \ + do { if (debug > 1) { \ + printk(KERN_INFO "%s:%d[%s]\n", __FILE__, __LINE__, __func__); \ + } } while (0) + +#define dprintkrw(fmt, args...) \ + do { if (debug > 2) { \ + printk(KERN_INFO "v4l2-loopback[" STRINGIFY2(__LINE__)"]: " fmt, ##args); \ + } } while (0) + +/* + * compatibility hacks + */ + +#ifndef HAVE__V4L2_CTRLS +struct v4l2_ctrl_handler { + int error; +}; +struct v4l2_ctrl_config { + void *ops; + u32 id; + const char *name; + int type; + s32 min; + s32 max; + u32 step; + s32 def; +}; +int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler*hdl, + unsigned nr_of_controls_hint) +{ + hdl->error=0; + return 0; +} +void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) +{ +} +void*v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_config*conf, + void*priv) +{ + return NULL; +} +#endif /* HAVE__V4L2_CTRLS */ + + +#ifndef HAVE__V4L2_DEVICE +/* dummy v4l2_device struct/functions */ +# define V4L2_DEVICE_NAME_SIZE (20 + 16) +struct v4l2_device { + char name[V4L2_DEVICE_NAME_SIZE]; + struct v4l2_ctrl_handler*ctrl_handler; +}; +static inline int v4l2_device_register (void *dev, void *v4l2_dev) { return 0; } +static inline void v4l2_device_unregister(struct v4l2_device *v4l2_dev) { return; } +#endif /* HAVE__V4L2_DEVICE */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) +# define v4l2_file_operations file_operations +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) +void *v4l2l_vzalloc(unsigned long size) +{ + void *data = vmalloc(size); + + memset(data, 0, size); + return data; +} +#else +# define v4l2l_vzalloc vzalloc +#endif + + +/* module constants + * can be overridden during he build process using something like + * make KCPPFLAGS="-DMAX_DEVICES=100" + */ + + +/* maximum number of v4l2loopback devices that can be created */ +#ifndef MAX_DEVICES +# define MAX_DEVICES 8 +#endif + +/* when a producer is considered to have gone stale */ +#ifndef MAX_TIMEOUT +# define MAX_TIMEOUT (100 * 1000) /* in msecs */ +#endif + +/* max buffers that can be mapped, actually they + * are all mapped to max_buffers buffers */ +#ifndef MAX_BUFFERS +# define MAX_BUFFERS 32 +#endif + +/* module parameters */ +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "debugging level (higher values == more verbose)"); + +static int max_buffers = 8; +module_param(max_buffers, int, S_IRUGO); +MODULE_PARM_DESC(max_buffers, "how many buffers should be allocated"); + +/* how many times a device can be opened + * the per-module default value can be overridden on a per-device basis using + * the /sys/devices interface + * + * note that max_openers should be at least 2 in order to get a working system: + * one opener for the producer and one opener for the consumer + * however, we leave that to the user + */ +static int max_openers = 10; +module_param(max_openers, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(max_openers, "how many users can open loopback device"); + + +static int devices = -1; +module_param(devices, int, 0); +MODULE_PARM_DESC(devices, "how many devices should be created"); + + +static int video_nr[MAX_DEVICES] = { [0 ... (MAX_DEVICES - 1)] = -1 }; +module_param_array(video_nr, int, NULL, 0444); +MODULE_PARM_DESC(video_nr, "video device numbers (-1=auto, 0=/dev/video0, etc.)"); + +static char *card_label[MAX_DEVICES]; +module_param_array(card_label, charp, NULL, 0000); +MODULE_PARM_DESC(card_label, "card labels for every device"); + +static bool exclusive_caps[MAX_DEVICES] = { [0 ... (MAX_DEVICES - 1)] = 0 }; +module_param_array(exclusive_caps, bool, NULL, 0444); +/* FIXXME: wording */ +MODULE_PARM_DESC(exclusive_caps, "whether to announce OUTPUT/CAPTURE capabilities exclusively or not"); + + +/* format specifications */ +#define V4L2LOOPBACK_SIZE_MIN_WIDTH 48 +#define V4L2LOOPBACK_SIZE_MIN_HEIGHT 32 +#define V4L2LOOPBACK_SIZE_MAX_WIDTH 8192 +#define V4L2LOOPBACK_SIZE_MAX_HEIGHT 8192 + +#define V4L2LOOPBACK_SIZE_DEFAULT_WIDTH 640 +#define V4L2LOOPBACK_SIZE_DEFAULT_HEIGHT 480 + +static int max_width = V4L2LOOPBACK_SIZE_MAX_WIDTH; +module_param(max_width, int, S_IRUGO); +MODULE_PARM_DESC(max_width, "maximum frame width"); +static int max_height = V4L2LOOPBACK_SIZE_MAX_HEIGHT; +module_param(max_height, int, S_IRUGO); +MODULE_PARM_DESC(max_height, "maximum frame height"); + + +/* control IDs */ +#ifndef HAVE__V4L2_CTRLS +# define V4L2LOOPBACK_CID_BASE (V4L2_CID_PRIVATE_BASE) +#else +# define V4L2LOOPBACK_CID_BASE (V4L2_CID_USER_BASE | 0xf000) +#endif +#define CID_KEEP_FORMAT (V4L2LOOPBACK_CID_BASE + 0) +#define CID_SUSTAIN_FRAMERATE (V4L2LOOPBACK_CID_BASE + 1) +#define CID_TIMEOUT (V4L2LOOPBACK_CID_BASE + 2) +#define CID_TIMEOUT_IMAGE_IO (V4L2LOOPBACK_CID_BASE + 3) + +static int v4l2loopback_s_ctrl(struct v4l2_ctrl *ctrl); +static const struct v4l2_ctrl_ops v4l2loopback_ctrl_ops = { + .s_ctrl = v4l2loopback_s_ctrl, +}; +static const struct v4l2_ctrl_config v4l2loopback_ctrl_keepformat = { + .ops = &v4l2loopback_ctrl_ops, + .id = CID_KEEP_FORMAT, + .name = "keep_format", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 0, +}; +static const struct v4l2_ctrl_config v4l2loopback_ctrl_sustainframerate = { + .ops = &v4l2loopback_ctrl_ops, + .id = CID_SUSTAIN_FRAMERATE, + .name = "sustain_framerate", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 0, +}; +static const struct v4l2_ctrl_config v4l2loopback_ctrl_timeout = { + .ops = &v4l2loopback_ctrl_ops, + .id = CID_TIMEOUT, + .name = "timeout", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .max = MAX_TIMEOUT, + .step = 1, + .def = 0, +}; +static const struct v4l2_ctrl_config v4l2loopback_ctrl_timeoutimageio = { + .ops = &v4l2loopback_ctrl_ops, + .id = CID_TIMEOUT_IMAGE_IO, + .name = "timeout_image_io", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .min = 0, + .max = 1, + .step = 1, + .def = 0, +}; + + +/* module structures */ +struct v4l2loopback_private { + int devicenr; +}; + +/* TODO(vasaka) use typenames which are common to kernel, but first find out if + * it is needed */ +/* struct keeping state and settings of loopback device */ + +struct v4l2l_buffer { + struct v4l2_buffer buffer; + struct list_head list_head; + int use_count; +}; + +struct v4l2_loopback_device { + struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler ctrl_handler; + struct video_device *vdev; + /* pixel and stream format */ + struct v4l2_pix_format pix_format; + struct v4l2_captureparm capture_param; + unsigned long frame_jiffies; + + /* ctrls */ + int keep_format; /* CID_KEEP_FORMAT; stay ready_for_capture even when all + openers close() the device */ + int sustain_framerate; /* CID_SUSTAIN_FRAMERATE; duplicate frames to maintain + (close to) nominal framerate */ + + /* buffers stuff */ + u8 *image; /* pointer to actual buffers data */ + unsigned long int imagesize; /* size of buffers data */ + int buffers_number; /* should not be big, 4 is a good choice */ + struct v4l2l_buffer buffers[MAX_BUFFERS]; /* inner driver buffers */ + int used_buffers; /* number of the actually used buffers */ + int max_openers; /* how many times can this device be opened */ + + int write_position; /* number of last written frame + 1 */ + struct list_head outbufs_list; /* buffers in output DQBUF order */ + int bufpos2index[MAX_BUFFERS]; /* mapping of (read/write_position % used_buffers) + * to inner buffer index */ + long buffer_size; + + /* sustain_framerate stuff */ + struct timer_list sustain_timer; + unsigned int reread_count; + + /* timeout stuff */ + unsigned long timeout_jiffies; /* CID_TIMEOUT; 0 means disabled */ + int timeout_image_io; /* CID_TIMEOUT_IMAGE_IO; next opener will + * read/write to timeout_image */ + u8 *timeout_image; /* copy of it will be captured when timeout passes */ + struct v4l2l_buffer timeout_image_buffer; + struct timer_list timeout_timer; + int timeout_happened; + + /* sync stuff */ + atomic_t open_count; + + + int ready_for_capture;/* set to true when at least one writer opened + * device and negotiated format */ + int ready_for_output; /* set to true when no writer is currently attached + * this differs slightly from !ready_for_capture, + * e.g. when using fallback images */ + int announce_all_caps;/* set to false, if device caps (OUTPUT/CAPTURE) + * should only be announced if the resp. "ready" + * flag is set; default=TRUE */ + + wait_queue_head_t read_event; + spinlock_t lock; +}; + +/* types of opener shows what opener wants to do with loopback */ +enum opener_type { + UNNEGOTIATED = 0, + READER = 1, + WRITER = 2, +}; + +/* struct keeping state and type of opener */ +struct v4l2_loopback_opener { + enum opener_type type; + int vidioc_enum_frameintervals_calls; + int read_position; /* number of last processed frame + 1 or + * write_position - 1 if reader went out of sync */ + unsigned int reread_count; + struct v4l2_buffer *buffers; + int buffers_number; /* should not be big, 4 is a good choice */ + int timeout_image_io; +}; + +/* this is heavily inspired by the bttv driver found in the linux kernel */ +struct v4l2l_format { + char *name; + int fourcc; /* video4linux 2 */ + int depth; /* bit/pixel */ + int flags; +}; +/* set the v4l2l_format.flags to PLANAR for non-packed formats */ +#define FORMAT_FLAGS_PLANAR 0x01 +#define FORMAT_FLAGS_COMPRESSED 0x02 + +static const struct v4l2l_format formats[] = { +#include "v4l2loopback_formats.h" +}; + +static const unsigned int FORMATS = ARRAY_SIZE(formats); + + +static char *fourcc2str(unsigned int fourcc, char buf[4]) +{ + buf[0] = (fourcc >> 0) & 0xFF; + buf[1] = (fourcc >> 8) & 0xFF; + buf[2] = (fourcc >> 16) & 0xFF; + buf[3] = (fourcc >> 24) & 0xFF; + + return buf; +} + +static const struct v4l2l_format *format_by_fourcc(int fourcc) +{ + unsigned int i; + + for (i = 0; i < FORMATS; i++) { + if (formats[i].fourcc == fourcc) + return formats + i; + } + + dprintk("unsupported format '%c%c%c%c'\n", + (fourcc >> 0) & 0xFF, + (fourcc >> 8) & 0xFF, + (fourcc >> 16) & 0xFF, + (fourcc >> 24) & 0xFF); + return NULL; +} + +static void pix_format_set_size(struct v4l2_pix_format *f, + const struct v4l2l_format *fmt, + unsigned int width, unsigned int height) +{ + f->width = width; + f->height = height; + + if (fmt->flags & FORMAT_FLAGS_PLANAR) { + f->bytesperline = width; /* Y plane */ + f->sizeimage = (width * height * fmt->depth) >> 3; + } else if (fmt->flags & FORMAT_FLAGS_COMPRESSED) { + /* doesn't make sense for compressed formats */ + f->bytesperline = 0; + f->sizeimage = (width * height * fmt->depth) >> 3; + } else { + f->bytesperline = (width * fmt->depth) >> 3; + f->sizeimage = height * f->bytesperline; + } +} + +static int set_timeperframe(struct v4l2_loopback_device *dev, + struct v4l2_fract *tpf) +{ + if((tpf->denominator < 1) || (tpf->numerator < 1)) { + return -EINVAL; + } + dev->capture_param.timeperframe = *tpf; + dev->frame_jiffies = max(1UL, + msecs_to_jiffies(1000) * tpf->numerator / tpf->denominator); + return 0; +} + +static struct v4l2_loopback_device *v4l2loopback_cd2dev(struct device *cd); + +/* device attributes */ +/* available via sysfs: /sys/devices/virtual/video4linux/video* */ + +static ssize_t attr_show_format(struct device *cd, + struct device_attribute *attr, char *buf) +{ + /* gets the current format as "FOURCC:WxH@f/s", e.g. "YUYV:320x240@1000/30" */ + struct v4l2_loopback_device *dev = v4l2loopback_cd2dev(cd); + const struct v4l2_fract *tpf; + char buf4cc[5], buf_fps[32]; + + if (!dev || !dev->ready_for_capture) + return 0; + tpf = &dev->capture_param.timeperframe; + + fourcc2str(dev->pix_format.pixelformat, buf4cc); + if (tpf->numerator == 1) + snprintf(buf_fps, sizeof(buf_fps), "%d", tpf->denominator); + else + snprintf(buf_fps, sizeof(buf_fps), "%d/%d", + tpf->denominator, tpf->numerator); + + return sprintf(buf, "%4s:%dx%d@%s\n", + buf4cc, dev->pix_format.width, dev->pix_format.height, buf_fps); +} + +static ssize_t attr_store_format(struct device *cd, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct v4l2_loopback_device *dev = v4l2loopback_cd2dev(cd); + int fps_num = 0, fps_den = 1; + + /* only fps changing is supported */ + if (sscanf(buf, "@%d/%d", &fps_num, &fps_den) > 0) { + struct v4l2_fract f = { + .numerator = fps_den, + .denominator = fps_num + }; + int err=0; + if((err=set_timeperframe(dev, &f)) < 0) + return err; + return len; + } + return -EINVAL; +} + +static DEVICE_ATTR(format, S_IRUGO | S_IWUSR, attr_show_format, attr_store_format); + +static ssize_t attr_show_buffers(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct v4l2_loopback_device *dev = v4l2loopback_cd2dev(cd); + + return sprintf(buf, "%d\n", dev->used_buffers); +} + +static DEVICE_ATTR(buffers, S_IRUGO, attr_show_buffers, NULL); + +static ssize_t attr_show_maxopeners(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct v4l2_loopback_device *dev = v4l2loopback_cd2dev(cd); + + return sprintf(buf, "%d\n", dev->max_openers); +} + +static ssize_t attr_store_maxopeners(struct device *cd, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct v4l2_loopback_device *dev = NULL; + unsigned long curr = 0; + + if (kstrtoul(buf, 0, &curr)) + return -EINVAL; + + dev = v4l2loopback_cd2dev(cd); + + if (dev->max_openers == curr) + return len; + + if (dev->open_count.counter > curr) { + /* request to limit to less openers as are currently attached to us */ + return -EINVAL; + } + + dev->max_openers = (int)curr; + + return len; +} + + +static DEVICE_ATTR(max_openers, S_IRUGO | S_IWUSR, attr_show_maxopeners, attr_store_maxopeners); + +static void v4l2loopback_remove_sysfs(struct video_device *vdev) +{ +#define V4L2_SYSFS_DESTROY(x) device_remove_file(&vdev->dev, &dev_attr_##x) + + if (vdev) { + V4L2_SYSFS_DESTROY(format); + V4L2_SYSFS_DESTROY(buffers); + V4L2_SYSFS_DESTROY(max_openers); + /* ... */ + } +} + +static void v4l2loopback_create_sysfs(struct video_device *vdev) +{ + int res = 0; + +#define V4L2_SYSFS_CREATE(x) res = device_create_file(&vdev->dev, &dev_attr_##x); if (res < 0) break + if (!vdev) + return; + do { + V4L2_SYSFS_CREATE(format); + V4L2_SYSFS_CREATE(buffers); + V4L2_SYSFS_CREATE(max_openers); + /* ... */ + } while (0); + + if (res >= 0) + return; + dev_err(&vdev->dev, "%s error: %d\n", __func__, res); +} + +/* global module data */ +struct v4l2_loopback_device *devs[MAX_DEVICES]; + +static struct v4l2_loopback_device *v4l2loopback_cd2dev(struct device *cd) +{ + struct video_device *loopdev = to_video_device(cd); + struct v4l2loopback_private *ptr = + (struct v4l2loopback_private *)video_get_drvdata(loopdev); + int nr = ptr->devicenr; + + if (nr < 0 || nr >= devices) { + printk(KERN_ERR "v4l2-loopback: illegal device %d\n", nr); + return NULL; + } + return devs[nr]; +} + +static struct v4l2_loopback_device *v4l2loopback_getdevice(struct file *f) +{ + struct video_device *loopdev = video_devdata(f); + struct v4l2loopback_private *ptr = + (struct v4l2loopback_private *)video_get_drvdata(loopdev); + int nr = ptr->devicenr; + + if (nr < 0 || nr >= devices) { + printk(KERN_ERR "v4l2-loopback: illegal device %d\n", nr); + return NULL; + } + return devs[nr]; +} + +/* forward declarations */ +static void init_buffers(struct v4l2_loopback_device *dev); +static int allocate_buffers(struct v4l2_loopback_device *dev); +static int free_buffers(struct v4l2_loopback_device *dev); +static void try_free_buffers(struct v4l2_loopback_device *dev); +static int allocate_timeout_image(struct v4l2_loopback_device *dev); +static void check_timers(struct v4l2_loopback_device *dev); +static const struct v4l2_file_operations v4l2_loopback_fops; +static const struct v4l2_ioctl_ops v4l2_loopback_ioctl_ops; + +/* Queue helpers */ +/* next functions sets buffer flags and adjusts counters accordingly */ +static inline void set_done(struct v4l2l_buffer *buffer) +{ + buffer->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED; + buffer->buffer.flags |= V4L2_BUF_FLAG_DONE; +} + +static inline void set_queued(struct v4l2l_buffer *buffer) +{ + buffer->buffer.flags &= ~V4L2_BUF_FLAG_DONE; + buffer->buffer.flags |= V4L2_BUF_FLAG_QUEUED; +} + +static inline void unset_flags(struct v4l2l_buffer *buffer) +{ + buffer->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED; + buffer->buffer.flags &= ~V4L2_BUF_FLAG_DONE; +} + +static void vidioc_fill_name(char *buf, int len, int nr) +{ + if (card_label[nr] != NULL) { + snprintf(buf, len, card_label[nr]); + } else { + snprintf(buf, len, "Dummy video device (0x%04X)", nr); + } +} + +/* V4L2 ioctl caps and params calls */ +/* returns device capabilities + * called on VIDIOC_QUERYCAP + */ +static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + int devnr = ((struct v4l2loopback_private *)video_get_drvdata(dev->vdev))->devicenr; + + strlcpy(cap->driver, "v4l2 loopback", sizeof(cap->driver)); + + vidioc_fill_name(cap->card, sizeof(cap->card), devnr); + + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:v4l2loopback-%03d", devnr); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) + /* since 3.1.0, the v4l2-core system is supposed to set the version */ + cap->version = V4L2LOOPBACK_VERSION_CODE; +#endif + cap->capabilities = +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) + V4L2_CAP_DEVICE_CAPS | +#endif + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; + +#ifdef V4L2_CAP_VIDEO_M2M + cap->capabilities |= V4L2_CAP_VIDEO_M2M; +#endif /* V4L2_CAP_VIDEO_M2M */ + if (dev->announce_all_caps) { + cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT; + } else { + + if (dev->ready_for_capture) { + cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE; + } + if (dev->ready_for_output) { + cap->capabilities |= V4L2_CAP_VIDEO_OUTPUT; + } + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) + cap->device_caps = (cap->capabilities & ~V4L2_CAP_DEVICE_CAPS); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) + cap->device_caps = cap->capabilities; + cap->capabilities |= V4L2_CAP_DEVICE_CAPS; +#endif + + memset(cap->reserved, 0, sizeof(cap->reserved)); + return 0; +} + +static int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *argp) +{ + struct v4l2_loopback_device *dev; + + /* LATER: what does the index really mean? + * if it's about enumerating formats, we can safely ignore it + * (CHECK) + */ + + /* there can be only one... */ + if (argp->index) + return -EINVAL; + + dev = v4l2loopback_getdevice(file); + if (dev->ready_for_capture) { + /* format has already been negotiated + * cannot change during runtime + */ + argp->type = V4L2_FRMSIZE_TYPE_DISCRETE; + + argp->discrete.width = dev->pix_format.width; + argp->discrete.height = dev->pix_format.height; + } else { + /* if the format has not been negotiated yet, we accept anything + */ + argp->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + + argp->stepwise.min_width = V4L2LOOPBACK_SIZE_MIN_WIDTH; + argp->stepwise.min_height = V4L2LOOPBACK_SIZE_MIN_HEIGHT; + + argp->stepwise.max_width = max_width; + argp->stepwise.max_height = max_height; + + argp->stepwise.step_width = 1; + argp->stepwise.step_height = 1; + } + return 0; +} + +/* returns frameinterval (fps) for the set resolution + * called on VIDIOC_ENUM_FRAMEINTERVALS + */ +static int vidioc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *argp) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + struct v4l2_loopback_opener *opener = file->private_data; + + if (dev->ready_for_capture) { + if (opener->vidioc_enum_frameintervals_calls > 0) + return -EINVAL; + if (argp->width == dev->pix_format.width && + argp->height == dev->pix_format.height) { + argp->type = V4L2_FRMIVAL_TYPE_DISCRETE; + argp->discrete = dev->capture_param.timeperframe; + opener->vidioc_enum_frameintervals_calls++; + return 0; + } + return -EINVAL; + } + return 0; +} + +/* ------------------ CAPTURE ----------------------- */ + +/* returns device formats + * called on VIDIOC_ENUM_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_CAPTURE + */ +static int vidioc_enum_fmt_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) +{ + struct v4l2_loopback_device *dev; + MARK(); + + dev = v4l2loopback_getdevice(file); + + if (f->index) + return -EINVAL; + if (dev->ready_for_capture) { + const __u32 format = dev->pix_format.pixelformat; + + snprintf(f->description, sizeof(f->description), + "[%c%c%c%c]", + (format >> 0) & 0xFF, + (format >> 8) & 0xFF, + (format >> 16) & 0xFF, + (format >> 24) & 0xFF); + + f->pixelformat = dev->pix_format.pixelformat; + } else { + return -EINVAL; + } + f->flags = 0; + MARK(); + return 0; +} + +/* returns current video format format fmt + * called on VIDIOC_G_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_CAPTURE + */ +static int vidioc_g_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) +{ + struct v4l2_loopback_device *dev; + MARK(); + + dev = v4l2loopback_getdevice(file); + + if (!dev->ready_for_capture) + return -EINVAL; + + fmt->fmt.pix = dev->pix_format; + MARK(); + return 0; +} + +/* checks if it is OK to change to format fmt; + * actual check is done by inner_try_fmt_cap + * just checking that pixelformat is OK and set other parameters, app should + * obey this decision + * called on VIDIOC_TRY_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_CAPTURE + */ +static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) +{ + struct v4l2_loopback_opener *opener; + struct v4l2_loopback_device *dev; + char buf[5]; + + opener = file->private_data; + opener->type = READER; + + dev = v4l2loopback_getdevice(file); + + if (0 == dev->ready_for_capture) { + dprintk("setting fmt_cap not possible yet\n"); + return -EBUSY; + } + + if (fmt->fmt.pix.pixelformat != dev->pix_format.pixelformat) + return -EINVAL; + + fmt->fmt.pix = dev->pix_format; + + buf[4] = 0; + dprintk("capFOURCC=%s\n", fourcc2str(dev->pix_format.pixelformat, buf)); + return 0; +} + +/* sets new output format, if possible + * actually format is set by input and we even do not check it, just return + * current one, but it is possible to set subregions of input TODO(vasaka) + * called on VIDIOC_S_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_CAPTURE + */ +static int vidioc_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) +{ + return vidioc_try_fmt_cap(file, priv, fmt); +} + + +/* ------------------ OUTPUT ----------------------- */ + +/* returns device formats; + * LATER: allow all formats + * called on VIDIOC_ENUM_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_OUTPUT + */ +static int vidioc_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f) +{ + struct v4l2_loopback_device *dev; + const struct v4l2l_format *fmt; + + dev = v4l2loopback_getdevice(file); + + if (dev->ready_for_capture) { + const __u32 format = dev->pix_format.pixelformat; + + /* format has been fixed by the writer, so only one single format is supported */ + if (f->index) + return -EINVAL; + + fmt = format_by_fourcc(format); + if (NULL == fmt) + return -EINVAL; + + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + /* f->flags = ??; */ + snprintf(f->description, sizeof(f->description), "%s", fmt->name); + + f->pixelformat = dev->pix_format.pixelformat; + } else { + __u32 format; + /* fill in a dummy format */ + /* coverity[unsigned_compare] */ + if (f->index < 0 || f->index >= FORMATS) + return -EINVAL; + + fmt = &formats[f->index]; + + f->pixelformat = fmt->fourcc; + format = f->pixelformat; + + /* strlcpy(f->description, "dummy OUT format", sizeof(f->description)); */ + snprintf(f->description, sizeof(f->description), "%s", fmt->name); + + } + f->flags = 0; + + return 0; +} + +/* returns current video format format fmt */ +/* NOTE: this is called from the producer + * so if format has not been negotiated yet, + * it should return ALL of available formats, + * called on VIDIOC_G_FMT, with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_OUTPUT + */ +static int vidioc_g_fmt_out(struct file *file, void *priv, struct v4l2_format *fmt) +{ + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + + MARK(); + + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + opener->type = WRITER; + dev->ready_for_output = 1; + /* + * LATER: this should return the currently valid format + * gstreamer doesn't like it, if this returns -EINVAL, as it + * then concludes that there is _no_ valid format + * CHECK whether this assumption is wrong, + * or whether we have to always provide a valid format + */ + + fmt->fmt.pix = dev->pix_format; + return 0; +} + +/* checks if it is OK to change to format fmt; + * if format is negotiated do not change it + * called on VIDIOC_TRY_FMT with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_OUTPUT + */ +static int vidioc_try_fmt_out(struct file *file, void *priv, struct v4l2_format *fmt) +{ + struct v4l2_loopback_opener *opener; + struct v4l2_loopback_device *dev; + MARK(); + + opener = file->private_data; + opener->type = WRITER; + + dev = v4l2loopback_getdevice(file); + dev->ready_for_output = 1; + + /* TODO(vasaka) loopback does not care about formats writer want to set, + * maybe it is a good idea to restrict format somehow */ + if (dev->ready_for_capture) { + fmt->fmt.pix = dev->pix_format; + } else { + __u32 w = fmt->fmt.pix.width; + __u32 h = fmt->fmt.pix.height; + __u32 pixfmt = fmt->fmt.pix.pixelformat; + const struct v4l2l_format *format = format_by_fourcc(pixfmt); + + if (w > max_width) + w = max_width; + if (h > max_height) + h = max_height; + + dprintk("trying image %dx%d\n", w, h); + + if (w < 1) + w = V4L2LOOPBACK_SIZE_DEFAULT_WIDTH; + + if (h < 1) + h = V4L2LOOPBACK_SIZE_DEFAULT_HEIGHT; + + if (NULL == format) + format = &formats[0]; + + pix_format_set_size(&fmt->fmt.pix, format, w, h); + + fmt->fmt.pix.pixelformat = format->fourcc; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + + if (V4L2_FIELD_ANY == fmt->fmt.pix.field) + fmt->fmt.pix.field = V4L2_FIELD_NONE; + + /* FIXXME: try_fmt should never modify the device-state */ + dev->pix_format = fmt->fmt.pix; + } + return 0; +} + +/* sets new output format, if possible; + * allocate data here because we do not know if it will be streaming or + * read/write IO + * called on VIDIOC_S_FMT with v4l2_buf_type set to V4L2_BUF_TYPE_VIDEO_OUTPUT + */ +static int vidioc_s_fmt_out(struct file *file, void *priv, struct v4l2_format *fmt) +{ + struct v4l2_loopback_device *dev; + char buf[5]; + int ret; + MARK(); + + dev = v4l2loopback_getdevice(file); + ret = vidioc_try_fmt_out(file, priv, fmt); + + dprintk("s_fmt_out(%d) %d...%d\n", ret, dev->ready_for_capture, dev->pix_format.sizeimage); + + buf[4] = 0; + dprintk("outFOURCC=%s\n", fourcc2str(dev->pix_format.pixelformat, buf)); + + if (ret < 0) + return ret; + + if (!dev->ready_for_capture) { + dev->buffer_size = PAGE_ALIGN(dev->pix_format.sizeimage); + fmt->fmt.pix.sizeimage = dev->buffer_size; + allocate_buffers(dev); + } + return ret; +} + +/*#define V4L2L_OVERLAY*/ +#ifdef V4L2L_OVERLAY +/* ------------------ OVERLAY ----------------------- */ +/* currently unsupported */ +/* GSTreamer's v4l2sink is buggy, as it requires the overlay to work + * while it should only require it, if overlay is requested + * once the gstreamer element is fixed, remove the overlay dummies + */ +#warning OVERLAY dummies +static int vidioc_g_fmt_overlay(struct file *file, void *priv, struct v4l2_format *fmt) +{ + return 0; +} + +static int vidioc_s_fmt_overlay(struct file *file, void *priv, struct v4l2_format *fmt) +{ + return 0; +} +#endif /* V4L2L_OVERLAY */ + + +/* ------------------ PARAMs ----------------------- */ + +/* get some data flow parameters, only capability, fps and readbuffers has + * effect on this driver + * called on VIDIOC_G_PARM + */ +static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) +{ + /* do not care about type of opener, hope this enums would always be + * compatible */ + struct v4l2_loopback_device *dev; + MARK(); + + dev = v4l2loopback_getdevice(file); + parm->parm.capture = dev->capture_param; + return 0; +} + +/* get some data flow parameters, only capability, fps and readbuffers has + * effect on this driver + * called on VIDIOC_S_PARM + */ +static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm) +{ + struct v4l2_loopback_device *dev; + int err=0; + MARK(); + + dev = v4l2loopback_getdevice(file); + dprintk("vidioc_s_parm called frate=%d/%d\n", + parm->parm.capture.timeperframe.numerator, + parm->parm.capture.timeperframe.denominator); + + switch (parm->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if ((err=set_timeperframe(dev, &parm->parm.capture.timeperframe)) < 0) + return err; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if ((err=set_timeperframe(dev, &parm->parm.capture.timeperframe)) < 0) + return err; + break; + default: + return -1; + } + + parm->parm.capture = dev->capture_param; + return 0; +} + +#ifdef V4L2LOOPBACK_WITH_STD +/* sets a tv standard, actually we do not need to handle this any special way + * added to support effecttv + * called on VIDIOC_S_STD + */ +static int vidioc_s_std(struct file *file, void *private_data, v4l2_std_id *_std) +{ + v4l2_std_id req_std = 0, supported_std = 0; + const v4l2_std_id all_std = V4L2_STD_ALL, no_std = 0; + + if (_std) { + req_std = *_std; + *_std = all_std; + } + + /* we support everything in V4L2_STD_ALL, but not more... */ + supported_std = (all_std & req_std); + if (no_std == supported_std) + return -EINVAL; + + return 0; +} + + +/* gets a fake video standard + * called on VIDIOC_G_STD + */ +static int vidioc_g_std(struct file *file, void *private_data, v4l2_std_id *norm) +{ + if (norm) + *norm = V4L2_STD_ALL; + return 0; +} +/* gets a fake video standard + * called on VIDIOC_QUERYSTD + */ +static int vidioc_querystd(struct file *file, void *private_data, v4l2_std_id *norm) +{ + if (norm) + *norm = V4L2_STD_ALL; + return 0; +} +#endif /* V4L2LOOPBACK_WITH_STD */ + +/* get ctrls info + * called on VIDIOC_QUERYCTRL + */ +static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *q) +{ + const struct v4l2_ctrl_config *cnf = 0; + switch (q->id) { + case CID_KEEP_FORMAT: + cnf = &v4l2loopback_ctrl_keepformat; + break; + case CID_SUSTAIN_FRAMERATE: + cnf = &v4l2loopback_ctrl_sustainframerate; + break; + case CID_TIMEOUT: + cnf = &v4l2loopback_ctrl_timeout; + break; + case CID_TIMEOUT_IMAGE_IO: + cnf = &v4l2loopback_ctrl_timeoutimageio; + break; + default: + return -EINVAL; + } + if (!cnf) + BUG(); + + strcpy(q->name, cnf->name); + q->default_value=cnf->def; + q->type = cnf->type; + q->minimum = cnf->min; + q->maximum = cnf->max; + q->step = cnf->step; + + memset(q->reserved, 0, sizeof(q->reserved)); + return 0; +} + + +static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + + switch (c->id) { + case CID_KEEP_FORMAT: + c->value = dev->keep_format; + break; + case CID_SUSTAIN_FRAMERATE: + c->value = dev->sustain_framerate; + break; + case CID_TIMEOUT: + c->value = jiffies_to_msecs(dev->timeout_jiffies); + break; + case CID_TIMEOUT_IMAGE_IO: + c->value = dev->timeout_image_io; + break; + default: + return -EINVAL; + } + + return 0; +} + + +static int v4l2loopback_set_ctrl( struct v4l2_loopback_device *dev, + u32 id, + s64 val) +{ + switch (id) { + case CID_KEEP_FORMAT: + if (val < 0 || val > 1) + return -EINVAL; + dev->keep_format = val; + try_free_buffers(dev); + break; + case CID_SUSTAIN_FRAMERATE: + if (val < 0 || val > 1) + return -EINVAL; + spin_lock_bh(&dev->lock); + dev->sustain_framerate = val; + check_timers(dev); + spin_unlock_bh(&dev->lock); + break; + case CID_TIMEOUT: + if (val < 0 || val > MAX_TIMEOUT) + return -EINVAL; + spin_lock_bh(&dev->lock); + dev->timeout_jiffies = msecs_to_jiffies(val); + check_timers(dev); + spin_unlock_bh(&dev->lock); + allocate_timeout_image(dev); + break; + case CID_TIMEOUT_IMAGE_IO: + if (val < 0 || val > 1) + return -EINVAL; + dev->timeout_image_io = val; + break; + default: + return -EINVAL; + } + return 0; +} + +static int v4l2loopback_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct v4l2_loopback_device *dev = container_of(ctrl->handler, struct v4l2_loopback_device, ctrl_handler); + return v4l2loopback_set_ctrl(dev, ctrl->id, ctrl->val); +} +static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + return v4l2loopback_set_ctrl(dev, c->id, c->value); +} + +/* returns set of device outputs, in our case there is only one + * called on VIDIOC_ENUMOUTPUT + */ +static int vidioc_enum_output(struct file *file, void *fh, struct v4l2_output *outp) +{ + __u32 index = outp->index; + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + MARK(); + + if (!dev->announce_all_caps && !dev->ready_for_output) + return -ENOTTY; + + if (0 != index) + return -EINVAL; + + /* clear all data (including the reserved fields) */ + memset(outp, 0, sizeof(*outp)); + + outp->index = index; + strlcpy(outp->name, "loopback in", sizeof(outp->name)); + outp->type = V4L2_OUTPUT_TYPE_ANALOG; + outp->audioset = 0; + outp->modulator = 0; +#ifdef V4L2LOOPBACK_WITH_STD + outp->std = V4L2_STD_ALL; +# ifdef V4L2_OUT_CAP_STD + outp->capabilities |= V4L2_OUT_CAP_STD; +# endif /* V4L2_OUT_CAP_STD */ +#endif /* V4L2LOOPBACK_WITH_STD */ + + return 0; +} + +/* which output is currently active, + * called on VIDIOC_G_OUTPUT + */ +static int vidioc_g_output(struct file *file, void *fh, unsigned int *i) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + if (!dev->announce_all_caps && !dev->ready_for_output) + return -ENOTTY; + if (i) + *i = 0; + return 0; +} + +/* set output, can make sense if we have more than one video src, + * called on VIDIOC_S_OUTPUT + */ +static int vidioc_s_output(struct file *file, void *fh, unsigned int i) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + if (!dev->announce_all_caps && !dev->ready_for_output) + return -ENOTTY; + + if (i) + return -EINVAL; + + return 0; +} + + +/* returns set of device inputs, in our case there is only one, + * but later I may add more + * called on VIDIOC_ENUMINPUT + */ +static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *inp) +{ + __u32 index = inp->index; + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + MARK(); + if (!dev->announce_all_caps && !dev->ready_for_capture) + return -ENOTTY; + + if (0 != index) + return -EINVAL; + + /* clear all data (including the reserved fields) */ + memset(inp, 0, sizeof(*inp)); + + inp->index = index; + strlcpy(inp->name, "loopback", sizeof(inp->name)); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->audioset = 0; + inp->tuner = 0; + inp->status = 0; + +#ifdef V4L2LOOPBACK_WITH_STD + inp->std = V4L2_STD_ALL; +# ifdef V4L2_IN_CAP_STD + inp->capabilities |= V4L2_IN_CAP_STD; +# endif +#endif /* V4L2LOOPBACK_WITH_STD */ + + return 0; +} + +/* which input is currently active, + * called on VIDIOC_G_INPUT + */ +static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + if (!dev->announce_all_caps && !dev->ready_for_capture) + return -ENOTTY; + if (i) + *i = 0; + return 0; +} + +/* set input, can make sense if we have more than one video src, + * called on VIDIOC_S_INPUT + */ +static int vidioc_s_input(struct file *file, void *fh, unsigned int i) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + if (!dev->announce_all_caps && !dev->ready_for_capture) + return -ENOTTY; + if (i == 0) + return 0; + return -EINVAL; +} + +/* --------------- V4L2 ioctl buffer related calls ----------------- */ + +/* negotiate buffer type + * only mmap streaming supported + * called on VIDIOC_REQBUFS + */ +static int vidioc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b) +{ + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + int i; + MARK(); + + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + + dprintk("reqbufs: %d\t%d=%d\n", b->memory, b->count, dev->buffers_number); + if (opener->timeout_image_io) { + if (b->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + b->count = 1; + return 0; + } + + init_buffers(dev); + switch (b->memory) { + case V4L2_MEMORY_MMAP: + /* do nothing here, buffers are always allocated*/ + if (b->count < 1 || dev->buffers_number < 1) + return 0; + + if (b->count > dev->buffers_number) + b->count = dev->buffers_number; + + /* make sure that outbufs_list contains buffers from 0 to used_buffers-1 + * actually, it will have been already populated via v4l2_loopback_init() + * at this point */ + if (list_empty(&dev->outbufs_list)) { + for (i = 0; i < dev->used_buffers; ++i) + list_add_tail(&dev->buffers[i].list_head, &dev->outbufs_list); + } + + /* also, if dev->used_buffers is going to be decreased, we should remove + * out-of-range buffers from outbufs_list, and fix bufpos2index mapping */ + if (b->count < dev->used_buffers) { + struct v4l2l_buffer *pos, *n; + + list_for_each_entry_safe(pos, n, &dev->outbufs_list, list_head) { + if (pos->buffer.index >= b->count) + list_del(&pos->list_head); + } + + /* after we update dev->used_buffers, buffers in outbufs_list will + * correspond to dev->write_position + [0;b->count-1] range */ + i = dev->write_position; + list_for_each_entry(pos, &dev->outbufs_list, list_head) { + dev->bufpos2index[i % b->count] = pos->buffer.index; + ++i; + } + } + + opener->buffers_number = b->count; + if (opener->buffers_number < dev->used_buffers) + dev->used_buffers = opener->buffers_number; + return 0; + default: + return -EINVAL; + } +} + +/* returns buffer asked for; + * give app as many buffers as it wants, if it less than MAX, + * but map them in our inner buffers + * called on VIDIOC_QUERYBUF + */ +static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b) +{ + enum v4l2_buf_type type; + int index; + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + + MARK(); + + type = b->type; + index = b->index; + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + + if ((b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (b->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) { + return -EINVAL; + } + if (b->index > max_buffers) + return -EINVAL; + + if (opener->timeout_image_io) + *b = dev->timeout_image_buffer.buffer; + else + *b = dev->buffers[b->index % dev->used_buffers].buffer; + + b->type = type; + b->index = index; + dprintkrw("buffer type: %d (of %d with size=%ld)\n", b->memory, dev->buffers_number, dev->buffer_size); + return 0; +} + +static void buffer_written(struct v4l2_loopback_device *dev, struct v4l2l_buffer *buf) +{ + del_timer_sync(&dev->sustain_timer); + del_timer_sync(&dev->timeout_timer); + spin_lock_bh(&dev->lock); + + dev->bufpos2index[dev->write_position % dev->used_buffers] = buf->buffer.index; + list_move_tail(&buf->list_head, &dev->outbufs_list); + ++dev->write_position; + dev->reread_count = 0; + + check_timers(dev); + spin_unlock_bh(&dev->lock); +} + +/* put buffer to queue + * called on VIDIOC_QBUF + */ +static int vidioc_qbuf(struct file *file, void *private_data, struct v4l2_buffer *buf) +{ + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + struct v4l2l_buffer *b; + int index; + + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + + if (buf->index > max_buffers) + return -EINVAL; + if (opener->timeout_image_io) + return 0; + + index = buf->index % dev->used_buffers; + b = &dev->buffers[index]; + + switch (buf->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + dprintkrw("capture QBUF index: %d\n", index); + set_queued(b); + return 0; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + dprintkrw("output QBUF pos: %d index: %d\n", dev->write_position, index); + if (buf->timestamp.tv_sec == 0 && buf->timestamp.tv_usec == 0) + do_gettimeofday(&b->buffer.timestamp); + else + b->buffer.timestamp = buf->timestamp; + b->buffer.bytesused = buf->bytesused; + set_done(b); + buffer_written(dev, b); + wake_up_all(&dev->read_event); + return 0; + default: + return -EINVAL; + } +} + +static int can_read(struct v4l2_loopback_device *dev, struct v4l2_loopback_opener *opener) +{ + int ret; + + spin_lock_bh(&dev->lock); + check_timers(dev); + ret = dev->write_position > opener->read_position + || dev->reread_count > opener->reread_count + || dev->timeout_happened; + spin_unlock_bh(&dev->lock); + return ret; +} + +static int get_capture_buffer(struct file *file) +{ + struct v4l2_loopback_device *dev = v4l2loopback_getdevice(file); + struct v4l2_loopback_opener *opener = file->private_data; + int pos, ret; + int timeout_happened; + + if ((file->f_flags & O_NONBLOCK) && + (dev->write_position <= opener->read_position && + dev->reread_count <= opener->reread_count && !dev->timeout_happened)) + return -EAGAIN; + wait_event_interruptible(dev->read_event, can_read(dev, opener)); + + spin_lock_bh(&dev->lock); + if (dev->write_position == opener->read_position) { + if (dev->reread_count > opener->reread_count + 2) + opener->reread_count = dev->reread_count - 1; + ++opener->reread_count; + pos = (opener->read_position + dev->used_buffers - 1) % dev->used_buffers; + } else { + opener->reread_count = 0; + if (dev->write_position > opener->read_position + 2) + opener->read_position = dev->write_position - 1; + pos = opener->read_position % dev->used_buffers; + ++opener->read_position; + } + timeout_happened = dev->timeout_happened; + dev->timeout_happened = 0; + spin_unlock_bh(&dev->lock); + + ret = dev->bufpos2index[pos]; + if (timeout_happened) { + /* although allocated on-demand, timeout_image is freed only + * in free_buffers(), so we don't need to worry about it being + * deallocated suddenly */ + memcpy(dev->image + dev->buffers[ret].buffer.m.offset, + dev->timeout_image, dev->buffer_size); + } + return ret; +} + +/* put buffer to dequeue + * called on VIDIOC_DQBUF + */ +static int vidioc_dqbuf(struct file *file, void *private_data, struct v4l2_buffer *buf) +{ + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + int index; + struct v4l2l_buffer *b; + + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + if (opener->timeout_image_io) { + *buf = dev->timeout_image_buffer.buffer; + return 0; + } + + switch (buf->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + index = get_capture_buffer(file); + if (index < 0) + return index; + dprintkrw("capture DQBUF pos: %d index: %d\n", opener->read_position - 1, index); + if (!(dev->buffers[index].buffer.flags&V4L2_BUF_FLAG_MAPPED)) { + dprintk("trying to return not mapped buf[%d]\n", index); + return -EINVAL; + } + unset_flags(&dev->buffers[index]); + *buf = dev->buffers[index].buffer; + return 0; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + b = list_entry(dev->outbufs_list.next, struct v4l2l_buffer, list_head); + list_move_tail(&b->list_head, &dev->outbufs_list); + dprintkrw("output DQBUF index: %d\n", b->buffer.index); + unset_flags(b); + *buf = b->buffer; + buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + return 0; + default: + return -EINVAL; + } +} + +/* ------------- STREAMING ------------------- */ + +/* start streaming + * called on VIDIOC_STREAMON + */ +static int vidioc_streamon(struct file *file, void *private_data, enum v4l2_buf_type type) +{ + struct v4l2_loopback_device *dev; + int ret; + MARK(); + + dev = v4l2loopback_getdevice(file); + + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + dev->ready_for_output = 0; + if (!dev->ready_for_capture) { + ret = allocate_buffers(dev); + if (ret < 0) + return ret; + dev->ready_for_capture = 1; + } + return 0; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (!dev->ready_for_capture) + return -EIO; + return 0; + default: + return -EINVAL; + } +} + +/* stop streaming + * called on VIDIOC_STREAMOFF + */ +static int vidioc_streamoff(struct file *file, void *private_data, enum v4l2_buf_type type) +{ + MARK(); + dprintk("%d\n", type); + return 0; +} + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidiocgmbuf(struct file *file, void *fh, struct video_mbuf *p) +{ + struct v4l2_loopback_device *dev; + MARK(); + + dev = v4l2loopback_getdevice(file); + p->frames = dev->buffers_number; + p->offsets[0] = 0; + p->offsets[1] = 0; + p->size = dev->buffer_size; + return 0; +} +#endif + +/* file operations */ +static void vm_open(struct vm_area_struct *vma) +{ + struct v4l2l_buffer *buf; + MARK(); + + buf = vma->vm_private_data; + buf->use_count++; +} + +static void vm_close(struct vm_area_struct *vma) +{ + struct v4l2l_buffer *buf; + MARK(); + + buf = vma->vm_private_data; + buf->use_count--; +} + +static struct vm_operations_struct vm_ops = { + .open = vm_open, + .close = vm_close, +}; + +static int v4l2_loopback_mmap(struct file *file, struct vm_area_struct *vma) +{ + int i; + unsigned long addr; + unsigned long start; + unsigned long size; + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + struct v4l2l_buffer *buffer = NULL; + MARK(); + + start = (unsigned long) vma->vm_start; + size = (unsigned long) (vma->vm_end - vma->vm_start); + + dev = v4l2loopback_getdevice(file); + opener = file->private_data; + + if (size > dev->buffer_size) { + dprintk("userspace tries to mmap too much, fail\n"); + return -EINVAL; + } + if (opener->timeout_image_io) { + /* we are going to map the timeout_image_buffer */ + if ((vma->vm_pgoff << PAGE_SHIFT) != dev->buffer_size * MAX_BUFFERS) { + dprintk("invalid mmap offset for timeout_image_io mode\n"); + return -EINVAL; + } + } else if ((vma->vm_pgoff << PAGE_SHIFT) > + dev->buffer_size * (dev->buffers_number - 1)) { + dprintk("userspace tries to mmap too far, fail\n"); + return -EINVAL; + } + + /* FIXXXXXME: allocation should not happen here! */ + if (NULL == dev->image) + if (allocate_buffers(dev) < 0) + return -EINVAL; + + if (opener->timeout_image_io) { + buffer = &dev->timeout_image_buffer; + addr = (unsigned long)dev->timeout_image; + } else { + for (i = 0; i < dev->buffers_number; ++i) { + buffer = &dev->buffers[i]; + if ((buffer->buffer.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) + break; + } + + if (NULL == buffer) + return -EINVAL; + + addr = (unsigned long) dev->image + (vma->vm_pgoff << PAGE_SHIFT); + } + + while (size > 0) { + struct page *page; + + page = (void *)vmalloc_to_page((void *)addr); + + if (vm_insert_page(vma, start, page) < 0) + return -EAGAIN; + + start += PAGE_SIZE; + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + vma->vm_ops = &vm_ops; + vma->vm_private_data = buffer; + buffer->buffer.flags |= V4L2_BUF_FLAG_MAPPED; + + vm_open(vma); + + MARK(); + return 0; +} + +static unsigned int v4l2_loopback_poll(struct file *file, struct poll_table_struct *pts) +{ + struct v4l2_loopback_opener *opener; + struct v4l2_loopback_device *dev; + int ret_mask = 0; + MARK(); + + opener = file->private_data; + dev = v4l2loopback_getdevice(file); + + switch (opener->type) { + case WRITER: + ret_mask = POLLOUT | POLLWRNORM; + break; + case READER: + poll_wait(file, &dev->read_event, pts); + if (can_read(dev, opener)) + ret_mask = POLLIN | POLLRDNORM; + break; + default: + ret_mask = -POLLERR; + } + MARK(); + + return ret_mask; +} + +/* do not want to limit device opens, it can be as many readers as user want, + * writers are limited by means of setting writer field */ +static int v4l2_loopback_open(struct file *file) +{ + struct v4l2_loopback_device *dev; + struct v4l2_loopback_opener *opener; + MARK(); + + dev = v4l2loopback_getdevice(file); + + if (dev->open_count.counter >= dev->max_openers) + return -EBUSY; + /* kfree on close */ + opener = kzalloc(sizeof(*opener), GFP_KERNEL); + if (opener == NULL) + return -ENOMEM; + file->private_data = opener; + atomic_inc(&dev->open_count); + + opener->timeout_image_io = dev->timeout_image_io; + dev->timeout_image_io = 0; + + if (opener->timeout_image_io) { + int r = allocate_timeout_image(dev); + + if (r < 0) { + dprintk("timeout image allocation failed\n"); + return r; + } + } + dprintk("opened dev:%p with image:%p\n", dev, dev ? dev->image : NULL); + MARK(); + return 0; +} + +static int v4l2_loopback_close(struct file *file) +{ + struct v4l2_loopback_opener *opener; + struct v4l2_loopback_device *dev; + int iswriter=0; + MARK(); + + + opener = file->private_data; + dev = v4l2loopback_getdevice(file); + + if(WRITER == opener->type) + iswriter = 1; + + atomic_dec(&dev->open_count); + if (dev->open_count.counter == 0) { + del_timer_sync(&dev->sustain_timer); + del_timer_sync(&dev->timeout_timer); + } + try_free_buffers(dev); + kfree(opener); + if(iswriter) { + dev->ready_for_output = 1; + } + MARK(); + return 0; +} + +static ssize_t v4l2_loopback_read(struct file *file, + char __user *buf, size_t count, loff_t *ppos) +{ + int read_index; + struct v4l2_loopback_opener *opener; + struct v4l2_loopback_device *dev; + struct v4l2_buffer *b; + MARK(); + + opener = file->private_data; + dev = v4l2loopback_getdevice(file); + + read_index = get_capture_buffer(file); + if (read_index < 0) + return read_index; + if (count > dev->buffer_size) + count = dev->buffer_size; + b = &dev->buffers[read_index].buffer; + if (count > b->bytesused) + count = b->bytesused; + if (copy_to_user((void *)buf, (void *)(dev->image + b->m.offset), count)) { + printk(KERN_ERR + "v4l2-loopback: failed copy_from_user() in write buf\n"); + return -EFAULT; + } + dprintkrw("leave v4l2_loopback_read()\n"); + return count; +} + +static ssize_t v4l2_loopback_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + struct v4l2_loopback_device *dev; + int write_index; + struct v4l2_buffer *b; + int ret; + MARK(); + + dev = v4l2loopback_getdevice(file); + + /* there's at least one writer, so don'stop announcing output capabilities */ + dev->ready_for_output = 0; + + if (!dev->ready_for_capture) { + ret = allocate_buffers(dev); + if (ret < 0) + return ret; + dev->ready_for_capture = 1; + } + dprintkrw("v4l2_loopback_write() trying to write %zu bytes\n", count); + if (count > dev->buffer_size) + count = dev->buffer_size; + + write_index = dev->write_position % dev->used_buffers; + b = &dev->buffers[write_index].buffer; + + if (copy_from_user((void *)(dev->image + b->m.offset), (void *)buf, count)) { + printk(KERN_ERR + "v4l2-loopback: failed copy_from_user() in write buf, could not write %zu\n", + count); + return -EFAULT; + } + do_gettimeofday(&b->timestamp); + b->bytesused = count; + b->sequence = dev->write_position; + buffer_written(dev, &dev->buffers[write_index]); + wake_up_all(&dev->read_event); + dprintkrw("leave v4l2_loopback_write()\n"); + return count; +} + +/* init functions */ +/* frees buffers, if already allocated */ +static int free_buffers(struct v4l2_loopback_device *dev) +{ + MARK(); + dprintk("freeing image@%p for dev:%p\n", dev ? dev->image : NULL, dev); + if (dev->image) { + vfree(dev->image); + dev->image = NULL; + } + if (dev->timeout_image) { + vfree(dev->timeout_image); + dev->timeout_image = NULL; + } + dev->imagesize = 0; + + return 0; +} +/* frees buffers, if they are no longer needed */ +static void try_free_buffers(struct v4l2_loopback_device *dev) +{ + MARK(); + if (0 == dev->open_count.counter && !dev->keep_format) { + free_buffers(dev); + dev->ready_for_capture = 0; + dev->buffer_size = 0; + dev->write_position = 0; + } +} +/* allocates buffers, if buffer_size is set */ +static int allocate_buffers(struct v4l2_loopback_device *dev) +{ + MARK(); + /* vfree on close file operation in case no open handles left */ + if (0 == dev->buffer_size) + return -EINVAL; + + if (dev->image) { + dprintk("allocating buffers again: %ld %ld\n", + dev->buffer_size * dev->buffers_number, dev->imagesize); + /* FIXME: prevent double allocation more intelligently! */ + if (dev->buffer_size * dev->buffers_number == dev->imagesize) + return 0; + + /* if there is only one writer, no problem should occur */ + if (dev->open_count.counter == 1) + free_buffers(dev); + else + return -EINVAL; + } + + dev->imagesize = dev->buffer_size * dev->buffers_number; + + dprintk("allocating %ld = %ldx%d\n", dev->imagesize, dev->buffer_size, dev->buffers_number); + + dev->image = vmalloc(dev->imagesize); + if (dev->timeout_jiffies > 0) + allocate_timeout_image(dev); + + if (dev->image == NULL) + return -ENOMEM; + dprintk("vmallocated %ld bytes\n", dev->imagesize); + MARK(); + init_buffers(dev); + return 0; +} + +/* init inner buffers, they are capture mode and flags are set as + * for capture mod buffers */ +static void init_buffers(struct v4l2_loopback_device *dev) +{ + int i; + int buffer_size; + int bytesused; + MARK(); + + buffer_size = dev->buffer_size; + bytesused = dev->pix_format.sizeimage; + + for (i = 0; i < dev->buffers_number; ++i) { + struct v4l2_buffer *b = &dev->buffers[i].buffer; + b->index = i; + b->bytesused = bytesused; + b->length = buffer_size; + b->field = V4L2_FIELD_NONE; + b->flags = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 1) + b->input = 0; +#endif + b->m.offset = i * buffer_size; + b->memory = V4L2_MEMORY_MMAP; + b->sequence = 0; + b->timestamp.tv_sec = 0; + b->timestamp.tv_usec = 0; + b->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + do_gettimeofday(&b->timestamp); + } + dev->timeout_image_buffer = dev->buffers[0]; + dev->timeout_image_buffer.buffer.m.offset = MAX_BUFFERS * buffer_size; + MARK(); +} + +static int allocate_timeout_image(struct v4l2_loopback_device *dev) +{ + MARK(); + if (dev->buffer_size <= 0) + return -EINVAL; + + if (dev->timeout_image == NULL) { + dev->timeout_image = v4l2l_vzalloc(dev->buffer_size); + if (dev->timeout_image == NULL) + return -ENOMEM; + } + return 0; +} + +/* fills and register video device */ +static void init_vdev(struct video_device *vdev, int nr) +{ + MARK(); + vidioc_fill_name(vdev->name, sizeof(vdev->name), nr); + +#ifdef V4L2LOOPBACK_WITH_STD + vdev->tvnorms = V4L2_STD_ALL; +#endif /* V4L2LOOPBACK_WITH_STD */ + + vdev->vfl_type = VFL_TYPE_GRABBER; + vdev->fops = &v4l2_loopback_fops; + vdev->ioctl_ops = &v4l2_loopback_ioctl_ops; + vdev->release = &video_device_release; + vdev->minor = -1; + if (debug > 1) + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 20, 0) + vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; + #else + vdev->dev_debug = V4L2_DEV_DEBUG_IOCTL | V4L2_DEV_DEBUG_IOCTL_ARG; + #endif + + /* since kernel-3.7, there is a new field 'vfl_dir' that has to be + * set to VFL_DIR_M2M for bidrectional devices */ +#ifdef VFL_DIR_M2M + vdev->vfl_dir = VFL_DIR_M2M; +#endif + + MARK(); +} + +/* init default capture parameters, only fps may be changed in future */ +static void init_capture_param(struct v4l2_captureparm *capture_param) +{ + MARK(); + capture_param->capability = 0; + capture_param->capturemode = 0; + capture_param->extendedmode = 0; + capture_param->readbuffers = max_buffers; + capture_param->timeperframe.numerator = 1; + capture_param->timeperframe.denominator = 30; +} + +static void check_timers(struct v4l2_loopback_device *dev) +{ + if (!dev->ready_for_capture) + return; + + if (dev->timeout_jiffies > 0 && !timer_pending(&dev->timeout_timer)) + mod_timer(&dev->timeout_timer, jiffies + dev->timeout_jiffies); + if (dev->sustain_framerate && !timer_pending(&dev->sustain_timer)) + mod_timer(&dev->sustain_timer, jiffies + dev->frame_jiffies * 3 / 2); +} + +static void sustain_timer_clb(unsigned long nr) +{ + struct v4l2_loopback_device *dev = devs[nr]; + + spin_lock(&dev->lock); + if (dev->sustain_framerate) { + dev->reread_count++; + dprintkrw("reread: %d %d\n", dev->write_position, dev->reread_count); + if (dev->reread_count == 1) + mod_timer(&dev->sustain_timer, jiffies + max(1UL, dev->frame_jiffies / 2)); + else + mod_timer(&dev->sustain_timer, jiffies + dev->frame_jiffies); + wake_up_all(&dev->read_event); + } + spin_unlock(&dev->lock); +} + +static void timeout_timer_clb(unsigned long nr) +{ + struct v4l2_loopback_device *dev = devs[nr]; + + spin_lock(&dev->lock); + if (dev->timeout_jiffies > 0) { + dev->timeout_happened = 1; + mod_timer(&dev->timeout_timer, jiffies + dev->timeout_jiffies); + wake_up_all(&dev->read_event); + } + spin_unlock(&dev->lock); +} + +/* init loopback main structure */ +static int v4l2_loopback_init(struct v4l2_loopback_device *dev, int nr) +{ + int ret; + struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), + "v4l2loopback-%03d", nr); + ret = v4l2_device_register(NULL, &dev->v4l2_dev); + if (ret) + return ret; + + MARK(); + dev->vdev = video_device_alloc(); + if (dev->vdev == NULL) { + ret=-ENOMEM; + goto error; + } + + video_set_drvdata(dev->vdev, kzalloc(sizeof(struct v4l2loopback_private), GFP_KERNEL)); + if (video_get_drvdata(dev->vdev) == NULL) { + ret=-ENOMEM; + goto error; + } + ((struct v4l2loopback_private *)video_get_drvdata(dev->vdev))->devicenr = nr; + + init_vdev(dev->vdev, nr); + dev->vdev->v4l2_dev = &dev->v4l2_dev; + init_capture_param(&dev->capture_param); + set_timeperframe(dev, &dev->capture_param.timeperframe); + dev->keep_format = 0; + dev->sustain_framerate = 0; + dev->buffers_number = max_buffers; + dev->used_buffers = max_buffers; + dev->max_openers = max_openers; + dev->write_position = 0; + spin_lock_init(&dev->lock); + INIT_LIST_HEAD(&dev->outbufs_list); + if (list_empty(&dev->outbufs_list)) { + int i; + + for (i = 0; i < dev->used_buffers; ++i) + list_add_tail(&dev->buffers[i].list_head, &dev->outbufs_list); + } + memset(dev->bufpos2index, 0, sizeof(dev->bufpos2index)); + atomic_set(&dev->open_count, 0); + dev->ready_for_capture = 0; + dev->ready_for_output = 1; + dev->announce_all_caps = (!exclusive_caps[nr]); + + dev->buffer_size = 0; + dev->image = NULL; + dev->imagesize = 0; + setup_timer(&dev->sustain_timer, sustain_timer_clb, nr); + dev->reread_count = 0; + setup_timer(&dev->timeout_timer, timeout_timer_clb, nr); + dev->timeout_jiffies = 0; + dev->timeout_image = NULL; + dev->timeout_happened = 0; + + ret = v4l2_ctrl_handler_init(hdl, 1); + if(ret) + goto error; + v4l2_ctrl_new_custom(hdl, &v4l2loopback_ctrl_keepformat, NULL); + v4l2_ctrl_new_custom(hdl, &v4l2loopback_ctrl_sustainframerate, NULL); + v4l2_ctrl_new_custom(hdl, &v4l2loopback_ctrl_timeout, NULL); + v4l2_ctrl_new_custom(hdl, &v4l2loopback_ctrl_timeoutimageio, NULL); + if (hdl->error) { + ret = hdl->error; + goto error; + } + dev->v4l2_dev.ctrl_handler = hdl; + + /* FIXME set buffers to 0 */ + + /* Set initial format */ + dev->pix_format.width = 0; /* V4L2LOOPBACK_SIZE_DEFAULT_WIDTH; */ + dev->pix_format.height = 0; /* V4L2LOOPBACK_SIZE_DEFAULT_HEIGHT; */ + dev->pix_format.pixelformat = formats[0].fourcc; + dev->pix_format.colorspace = V4L2_COLORSPACE_SRGB; /* do we need to set this ? */ + dev->pix_format.field = V4L2_FIELD_NONE; + + dev->buffer_size = PAGE_ALIGN(dev->pix_format.sizeimage); + dprintk("buffer_size = %ld (=%d)\n", dev->buffer_size, dev->pix_format.sizeimage); + allocate_buffers(dev); + + init_waitqueue_head(&dev->read_event); + + MARK(); + return 0; + +error: + v4l2_ctrl_handler_free(&dev->ctrl_handler); + v4l2_device_unregister(&dev->v4l2_dev); + kfree(dev->vdev); + return ret; + +}; + +/* LINUX KERNEL */ +static const struct v4l2_file_operations v4l2_loopback_fops = { + .owner = THIS_MODULE, + .open = v4l2_loopback_open, + .release = v4l2_loopback_close, + .read = v4l2_loopback_read, + .write = v4l2_loopback_write, + .poll = v4l2_loopback_poll, + .mmap = v4l2_loopback_mmap, + .unlocked_ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops v4l2_loopback_ioctl_ops = { + .vidioc_querycap = &vidioc_querycap, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) + .vidioc_enum_framesizes = &vidioc_enum_framesizes, + .vidioc_enum_frameintervals = &vidioc_enum_frameintervals, +#endif + +#ifndef HAVE__V4L2_CTRLS + .vidioc_queryctrl = &vidioc_queryctrl, + .vidioc_g_ctrl = &vidioc_g_ctrl, + .vidioc_s_ctrl = &vidioc_s_ctrl, +#endif /* HAVE__V4L2_CTRLS */ + + .vidioc_enum_output = &vidioc_enum_output, + .vidioc_g_output = &vidioc_g_output, + .vidioc_s_output = &vidioc_s_output, + + .vidioc_enum_input = &vidioc_enum_input, + .vidioc_g_input = &vidioc_g_input, + .vidioc_s_input = &vidioc_s_input, + + .vidioc_enum_fmt_vid_cap = &vidioc_enum_fmt_cap, + .vidioc_g_fmt_vid_cap = &vidioc_g_fmt_cap, + .vidioc_s_fmt_vid_cap = &vidioc_s_fmt_cap, + .vidioc_try_fmt_vid_cap = &vidioc_try_fmt_cap, + + .vidioc_enum_fmt_vid_out = &vidioc_enum_fmt_out, + .vidioc_s_fmt_vid_out = &vidioc_s_fmt_out, + .vidioc_g_fmt_vid_out = &vidioc_g_fmt_out, + .vidioc_try_fmt_vid_out = &vidioc_try_fmt_out, + +#ifdef V4L2L_OVERLAY + .vidioc_s_fmt_vid_overlay = &vidioc_s_fmt_overlay, + .vidioc_g_fmt_vid_overlay = &vidioc_g_fmt_overlay, +#endif + +#ifdef V4L2LOOPBACK_WITH_STD + .vidioc_s_std = &vidioc_s_std, + .vidioc_g_std = &vidioc_g_std, + .vidioc_querystd = &vidioc_querystd, +#endif /* V4L2LOOPBACK_WITH_STD */ + + .vidioc_g_parm = &vidioc_g_parm, + .vidioc_s_parm = &vidioc_s_parm, + + .vidioc_reqbufs = &vidioc_reqbufs, + .vidioc_querybuf = &vidioc_querybuf, + .vidioc_qbuf = &vidioc_qbuf, + .vidioc_dqbuf = &vidioc_dqbuf, + + .vidioc_streamon = &vidioc_streamon, + .vidioc_streamoff = &vidioc_streamoff, + +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = &vidiocgmbuf, +#endif +}; + +static void zero_devices(void) +{ + int i; + + MARK(); + for (i = 0; i < MAX_DEVICES; i++) + devs[i] = NULL; +} + +static void free_devices(void) +{ + int i; + + MARK(); + for (i = 0; i < devices; i++) { + if (NULL != devs[i]) { + free_buffers(devs[i]); + v4l2loopback_remove_sysfs(devs[i]->vdev); + kfree(video_get_drvdata(devs[i]->vdev)); + video_unregister_device(devs[i]->vdev); + v4l2_device_unregister(&devs[i]->v4l2_dev); + v4l2_ctrl_handler_free(&devs[i]->ctrl_handler); + kfree(devs[i]); + devs[i] = NULL; + } + } +} + +static int __init v4l2loopback_init_module(void) +{ + int ret; + int i; + MARK(); + + zero_devices(); + if (devices < 0) { + devices = 1; + + /* try guessing the devices from the "video_nr" parameter */ + for (i = MAX_DEVICES - 1; i >= 0; i--) { + if (video_nr[i] >= 0) { + devices = i + 1; + break; + } + } + } + + if (devices > MAX_DEVICES) { + devices = MAX_DEVICES; + printk(KERN_INFO "v4l2loopback: number of devices is limited to: %d\n", MAX_DEVICES); + } + + if (max_buffers > MAX_BUFFERS) { + max_buffers = MAX_BUFFERS; + printk(KERN_INFO "v4l2loopback: number of buffers is limited to: %d\n", MAX_BUFFERS); + } + + if (max_openers < 0) { + printk(KERN_INFO "v4l2loopback: allowing %d openers rather than %d\n", 2, max_openers); + max_openers = 2; + } + + if (max_width < 1) { + max_width = V4L2LOOPBACK_SIZE_MAX_WIDTH; + printk(KERN_INFO "v4l2loopback: using max_width %d\n", max_width); + } + if (max_height < 1) { + max_height = V4L2LOOPBACK_SIZE_MAX_HEIGHT; + printk(KERN_INFO "v4l2loopback: using max_height %d\n", max_height); + } + + /* kfree on module release */ + for (i = 0; i < devices; i++) { + dprintk("creating v4l2loopback-device #%d\n", i); + devs[i] = kzalloc(sizeof(*devs[i]), GFP_KERNEL); + if (devs[i] == NULL) { + free_devices(); + return -ENOMEM; + } + ret = v4l2_loopback_init(devs[i], i); + if (ret < 0) { + free_devices(); + return ret; + } + /* register the device -> it creates /dev/video* */ + if (video_register_device(devs[i]->vdev, VFL_TYPE_GRABBER, video_nr[i]) < 0) { + video_device_release(devs[i]->vdev); + printk(KERN_ERR "v4l2loopback: failed video_register_device()\n"); + free_devices(); + return -EFAULT; + } + v4l2loopback_create_sysfs(devs[i]->vdev); + } + + dprintk("module installed\n"); + + printk(KERN_INFO "v4l2loopback driver version %d.%d.%d loaded\n", + (V4L2LOOPBACK_VERSION_CODE >> 16) & 0xff, + (V4L2LOOPBACK_VERSION_CODE >> 8) & 0xff, + (V4L2LOOPBACK_VERSION_CODE) & 0xff); + + return 0; +} + +static void v4l2loopback_cleanup_module(void) +{ + MARK(); + /* unregister the device -> it deletes /dev/video* */ + free_devices(); + dprintk("module removed\n"); +} + +#ifdef MODULE +int __init init_module(void) +{ + return v4l2loopback_init_module(); +} +void __exit cleanup_module(void) { + return v4l2loopback_cleanup_module(); +} +#else +late_initcall(v4l2loopback_init_module); +#endif + + + +/* + * fake usage of unused functions + */ +#ifdef HAVE__V4L2_CTRLS +static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *q) __attribute__ ((unused)); +static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) __attribute__ ((unused)); +static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) __attribute__ ((unused)); +#endif /* HAVE__V4L2_CTRLS */ diff --git a/extra_modules/v4l2loopback/v4l2loopback_formats.h b/extra_modules/v4l2loopback/v4l2loopback_formats.h new file mode 100644 index 00000000..998214ef --- /dev/null +++ b/extra_modules/v4l2loopback/v4l2loopback_formats.h @@ -0,0 +1,363 @@ + /* here come the packed formats */ +{ + .name = "32 bpp RGB, le", + .fourcc = V4L2_PIX_FMT_BGR32, + .depth = 32, + .flags = 0, + }, +{ + .name = "32 bpp RGB, be", + .fourcc = V4L2_PIX_FMT_RGB32, + .depth = 32, + .flags = 0, + }, +{ + .name = "24 bpp RGB, le", + .fourcc = V4L2_PIX_FMT_BGR24, + .depth = 24, + .flags = 0, + }, +{ + .name = "24 bpp RGB, be", + .fourcc = V4L2_PIX_FMT_RGB24, + .depth = 24, + .flags = 0, + }, +#ifdef V4L2_PIX_FMT_RGB332 +{ + .name = "8 bpp RGB-3-3-2", + .fourcc = V4L2_PIX_FMT_RGB332, + .depth = 8, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB332 */ +#ifdef V4L2_PIX_FMT_RGB444 +{ + .name = "16 bpp RGB (xxxxrrrr ggggbbbb)", + .fourcc = V4L2_PIX_FMT_RGB444, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB444 */ +#ifdef V4L2_PIX_FMT_RGB555 +{ + .name = "16 bpp RGB-5-5-5", + .fourcc = V4L2_PIX_FMT_RGB555, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB555 */ +#ifdef V4L2_PIX_FMT_RGB565 +{ + .name = "16 bpp RGB-5-6-5", + .fourcc = V4L2_PIX_FMT_RGB565, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB565 */ +#ifdef V4L2_PIX_FMT_RGB555X +{ + .name = "16 bpp RGB-5-5-5 BE", + .fourcc = V4L2_PIX_FMT_RGB555X, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB555X */ +#ifdef V4L2_PIX_FMT_RGB565X +{ + .name = "16 bpp RGB-5-6-5 BE", + .fourcc = V4L2_PIX_FMT_RGB565X, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_RGB565X */ +#ifdef V4L2_PIX_FMT_BGR666 +{ + .name = "18 bpp BGR-6-6-6", + .fourcc = V4L2_PIX_FMT_BGR666, + .depth = 18, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_BGR666 */ +{ + .name = "4:2:2, packed, YUYV", + .fourcc = V4L2_PIX_FMT_YUYV, + .depth = 16, + .flags = 0, + }, +{ + .name = "4:2:2, packed, UYVY", + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = 16, + .flags = 0, + }, +#ifdef V4L2_PIX_FMT_YVYU +{ + .name = "4:2:2, packed YVYU", + .fourcc = V4L2_PIX_FMT_YVYU, + .depth = 16, + .flags = 0, + }, +#endif +#ifdef V4L2_PIX_FMT_VYUY +{ + .name = "4:2:2, packed VYUY", + .fourcc = V4L2_PIX_FMT_VYUY, + .depth = 16, + .flags = 0, + }, +#endif +{ + .name = "4:2:2, packed YYUV", + .fourcc = V4L2_PIX_FMT_YYUV, + .depth = 16, + .flags = 0, + }, +{ + .name = "YUV-8-8-8-8", + .fourcc = V4L2_PIX_FMT_YUV32, + .depth = 32, + .flags = 0, + }, +{ + .name = "8 bpp, Greyscale", + .fourcc = V4L2_PIX_FMT_GREY, + .depth = 8, + .flags = 0, + }, +#ifdef V4L2_PIX_FMT_Y4 +{ + .name = "4 bpp Greyscale", + .fourcc = V4L2_PIX_FMT_Y4, + .depth = 4, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_Y4 */ +#ifdef V4L2_PIX_FMT_Y6 +{ + .name = "6 bpp Greyscale", + .fourcc = V4L2_PIX_FMT_Y6, + .depth = 6, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_Y6 */ +#ifdef V4L2_PIX_FMT_Y10 +{ + .name = "10 bpp Greyscale", + .fourcc = V4L2_PIX_FMT_Y10, + .depth = 10, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_Y10 */ +#ifdef V4L2_PIX_FMT_Y12 +{ + .name = "12 bpp Greyscale", + .fourcc = V4L2_PIX_FMT_Y12, + .depth = 12, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_Y12 */ +{ + .name = "16 bpp, Greyscale", + .fourcc = V4L2_PIX_FMT_Y16, + .depth = 16, + .flags = 0, + }, +#ifdef V4L2_PIX_FMT_YUV444 +{ + .name = "16 bpp xxxxyyyy uuuuvvvv", + .fourcc = V4L2_PIX_FMT_YUV444, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_YUV444 */ +#ifdef V4L2_PIX_FMT_YUV555 +{ + .name = "16 bpp YUV-5-5-5", + .fourcc = V4L2_PIX_FMT_YUV555, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_YUV555 */ +#ifdef V4L2_PIX_FMT_YUV565 +{ + .name = "16 bpp YUV-5-6-5", + .fourcc = V4L2_PIX_FMT_YUV565, + .depth = 16, + .flags = 0, + }, +#endif /* V4L2_PIX_FMT_YUV565 */ + + + /* here come the planar formats */ +{ + .name = "4:1:0, planar, Y-Cr-Cb", + .fourcc = V4L2_PIX_FMT_YVU410, + .depth = 9, + .flags = FORMAT_FLAGS_PLANAR, + }, +{ + .name = "4:2:0, planar, Y-Cr-Cb", + .fourcc = V4L2_PIX_FMT_YVU420, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, + }, +{ + .name = "4:1:0, planar, Y-Cb-Cr", + .fourcc = V4L2_PIX_FMT_YUV410, + .depth = 9, + .flags = FORMAT_FLAGS_PLANAR, + }, +{ + .name = "4:2:0, planar, Y-Cb-Cr", + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, + }, +#ifdef V4L2_PIX_FMT_YUV422P +{ + .name = "16 bpp YVU422 planar", + .fourcc = V4L2_PIX_FMT_YUV422P, + .depth = 16, + .flags = FORMAT_FLAGS_PLANAR, + }, +#endif /* V4L2_PIX_FMT_YUV422P */ +#ifdef V4L2_PIX_FMT_YUV411P +{ + .name = "16 bpp YVU411 planar", + .fourcc = V4L2_PIX_FMT_YUV411P, + .depth = 16, + .flags = FORMAT_FLAGS_PLANAR, + }, +#endif /* V4L2_PIX_FMT_YUV411P */ +#ifdef V4L2_PIX_FMT_Y41P +{ + .name = "12 bpp YUV 4:1:1", + .fourcc = V4L2_PIX_FMT_Y41P, + .depth = 12, + .flags = FORMAT_FLAGS_PLANAR, + }, +#endif /* V4L2_PIX_FMT_Y41P */ + + /* here come the compressed formats */ + +#ifdef V4L2_PIX_FMT_MJPEG +{ + .name = "Motion-JPEG", + .fourcc = V4L2_PIX_FMT_MJPEG, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_MJPEG */ +#ifdef V4L2_PIX_FMT_JPEG +{ + .name = "JFIF JPEG", + .fourcc = V4L2_PIX_FMT_JPEG, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_JPEG */ +#ifdef V4L2_PIX_FMT_DV +{ + .name = "DV1394", + .fourcc = V4L2_PIX_FMT_DV, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_DV */ +#ifdef V4L2_PIX_FMT_MPEG +{ + .name = "MPEG-1/2/4 Multiplexed", + .fourcc = V4L2_PIX_FMT_MPEG, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_MPEG */ +#ifdef V4L2_PIX_FMT_H264 +{ + .name = "H264 with start codes", + .fourcc = V4L2_PIX_FMT_H264, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_H264 */ +#ifdef V4L2_PIX_FMT_H264_NO_SC +{ + .name = "H264 without start codes", + .fourcc = V4L2_PIX_FMT_H264_NO_SC, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_H264_NO_SC */ +#ifdef V4L2_PIX_FMT_H264_MVC +{ + .name = "H264 MVC", + .fourcc = V4L2_PIX_FMT_H264_MVC, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_H264_MVC */ +#ifdef V4L2_PIX_FMT_H263 +{ + .name = "H263", + .fourcc = V4L2_PIX_FMT_H263, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_H263 */ +#ifdef V4L2_PIX_FMT_MPEG1 +{ + .name = "MPEG-1 ES", + .fourcc = V4L2_PIX_FMT_MPEG1, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_MPEG1 */ +#ifdef V4L2_PIX_FMT_MPEG2 +{ + .name = "MPEG-2 ES", + .fourcc = V4L2_PIX_FMT_MPEG2, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_MPEG2 */ +#ifdef V4L2_PIX_FMT_MPEG4 +{ + .name = "MPEG-4 part 2 ES", + .fourcc = V4L2_PIX_FMT_MPEG4, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_MPEG4 */ +#ifdef V4L2_PIX_FMT_XVID +{ + .name = "Xvid", + .fourcc = V4L2_PIX_FMT_XVID, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_XVID */ +#ifdef V4L2_PIX_FMT_VC1_ANNEX_G +{ + .name = "SMPTE 421M Annex G compliant stream", + .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_VC1_ANNEX_G */ +#ifdef V4L2_PIX_FMT_VC1_ANNEX_L +{ + .name = "SMPTE 421M Annex L compliant stream", + .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_VC1_ANNEX_L */ +#ifdef V4L2_PIX_FMT_VP8 +{ + .name = "VP8", + .fourcc = V4L2_PIX_FMT_VP8, + .depth = 32, + .flags = FORMAT_FLAGS_COMPRESSED, + }, +#endif /* V4L2_PIX_FMT_VP8 */ diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index d0e65c24..6b7385ff 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -236,10 +236,10 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_CFQ_GROUP_IOSCHED is not set -# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" # CONFIG_INLINE_SPIN_TRYLOCK is not set # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set # CONFIG_INLINE_SPIN_LOCK is not set @@ -1010,7 +1010,7 @@ CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" # CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set +CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set # CONFIG_WIMAX is not set @@ -1282,9 +1282,23 @@ CONFIG_WLAN=y CONFIG_USB_ZD1201=m # CONFIG_USB_NET_RNDIS_WLAN is not set CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y # CONFIG_MAC80211_HWSIM is not set # CONFIG_WIFI_CONTROL_FUNC is not set -# CONFIG_ATH_COMMON is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set # CONFIG_B43 is not set # CONFIG_B43LEGACY is not set CONFIG_BCMDHD=m diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/Makefile b/linux-3.4/arch/arm/mach-sunxi/power/brom/Makefile index 5bce9ee0..f7518b65 100755 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/Makefile +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/Makefile @@ -5,7 +5,7 @@ targets := resumes.elf #use "-Os" flags. #Don't use "-O2" flags. -KBUILD_CFLAGS := -g -c -nostdlib -march=armv7-a -marm -fno-unwind-tables -fno-asynchronous-unwind-tables -mlittle-endian -O2 --min_array_alignment=4 --no_unaligned_access +KBUILD_CFLAGS := -g -c -nostdlib -march=armv7-a -marm -fno-unwind-tables -fno-asynchronous-unwind-tables -mlittle-endian -O2 -mno-unaligned-access #Include the cur dir. KBUILD_CPPFLAGS += -I. diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index f9b2a111f638a4185c61ecec9ed99702562b49b3..1047a958288f556ada94910fa40dcd55e2a73b76 100755 GIT binary patch delta 48 zcmV-00MGxqk^;Gs0: - 0: 00003241 andeq r3, r0, r1, asr #4 + 0: 00003041 andeq r3, r0, r1, asr #32 4: 61656100 cmnvs r5, r0, lsl #2 8: 01006962 tsteq r0, r2, ror #18 - c: 00000028 andeq r0, r0, r8, lsr #32 + c: 00000026 andeq r0, r0, r6, lsr #32 10: 412d3705 teqmi sp, r5, lsl #14 14: 070a0600 streq r0, [sl, -r0, lsl #12] 18: 09010841 stmdbeq r1, {r0, r6, fp} @@ -367,6 +367,6 @@ Disassembly of section .ARM.attributes: 20: 15011404 strne r1, [r1, #-1028] ; 0x404 24: 18031701 stmdane r3, {r0, r8, r9, sl, ip} 28: 1b021a01 blne 86834 <__bss_end+0x86758> - 2c: 22021e03 andcs r1, r2, #48 ; 0x30 + 2c: 2c021e03 stccs 14, cr1, [r2], {3} 30: Address 0x00000030 is out of bounds. diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 9e7e898f..2ebc106c 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -85,8 +85,8 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) 0x00000000 0x0 arch/arm/mach-sunxi/power/brom/resume_head.o .ARM.attributes - 0x00000000 0x33 + 0x00000000 0x31 .ARM.attributes - 0x00000000 0x35 arch/arm/mach-sunxi/power/brom/resume_head.o + 0x00000000 0x33 arch/arm/mach-sunxi/power/brom/resume_head.o .ARM.attributes - 0x00000035 0x21 arch/arm/mach-sunxi/power/brom/resumes.o + 0x00000033 0x21 arch/arm/mach-sunxi/power/brom/resumes.o diff --git a/linux-3.4/arch/arm/mach-sunxi/sunxi-debug.c b/linux-3.4/arch/arm/mach-sunxi/sunxi-debug.c index 53ed9fcd..6a41c51f 100755 --- a/linux-3.4/arch/arm/mach-sunxi/sunxi-debug.c +++ b/linux-3.4/arch/arm/mach-sunxi/sunxi-debug.c @@ -24,7 +24,7 @@ static int sunxi_proc_su_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char *buf; - struct cred *cred; +// struct cred *cred; if (count < 1) return -EINVAL; @@ -39,16 +39,16 @@ static int sunxi_proc_su_write(struct file *file, const char __user *buffer, } if(!strncmp("rootmydevice",(char*)buf,12)){ - cred = (struct cred *)__task_cred(current); - cred->uid = 0; - cred->gid = 0; - cred->suid = 0; - cred->euid = 0; - cred->euid = 0; - cred->egid = 0; - cred->fsuid = 0; - cred->fsgid = 0; - printk("now you are root\n"); +// cred = (struct cred *)__task_cred(current); +// cred->uid = 0; +// cred->gid = 0; +// cred->suid = 0; +// cred->euid = 0; +// cred->euid = 0; +// cred->egid = 0; +// cred->fsuid = 0; +// cred->fsgid = 0; + printk("now you are not root!!\n"); } kfree(buf); diff --git a/linux-3.4/drivers/gpu/ion/ion_cma_heap.c b/linux-3.4/drivers/gpu/ion/ion_cma_heap.c index 86612c0c..2e95a9d1 100755 --- a/linux-3.4/drivers/gpu/ion/ion_cma_heap.c +++ b/linux-3.4/drivers/gpu/ion/ion_cma_heap.c @@ -48,7 +48,7 @@ struct ion_cma_buffer_info { struct page *dma_alloc_from_contiguous(struct device *dev, int count, unsigned int align); void __dma_clear_buffer(struct page *page, size_t size); -inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot); +pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot); void *__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, const void *caller); void __dma_remap(struct page *page, size_t size, pgprot_t prot); diff --git a/v4l2loopback b/v4l2loopback deleted file mode 160000 index 2fdda920..00000000 --- a/v4l2loopback +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2fdda92084b8dff39f041b44d76d3fc6942f7a5c From 251cf0e77c91de20958136d849476811306a089c Mon Sep 17 00:00:00 2001 From: Leonardo Lontra Date: Tue, 28 Jun 2016 21:22:40 -0300 Subject: [PATCH 05/26] bugs fixes rtl8189fs wifi driver added --- build/sun8iw7p1smp_lobo_defconfig | 8 +- extra_modules/rtl8192cu-fixes/Makefile | 2 +- extra_modules/v4l2loopback/Makefile | 2 +- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 8 +- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35129 -> 35105 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 194 +- .../arm/mach-sunxi/power/brom/resumes.map | 6 +- linux-3.4/drivers/cpufreq/sunxi-cpufreq.c | 47 +- linux-3.4/drivers/net/wireless/Kconfig | 1 + linux-3.4/drivers/net/wireless/Kconfig.orig | 298 - linux-3.4/drivers/net/wireless/Makefile | 1 + linux-3.4/drivers/net/wireless/Makefile.orig | 68 - .../drivers/net/wireless/rtl8189fs/Kconfig | 5 + .../drivers/net/wireless/rtl8189fs/Makefile | 1730 ++ .../drivers/net/wireless/rtl8189fs/clean | 5 + .../wireless/rtl8189fs/core/efuse/rtw_efuse.c | 1721 ++ .../net/wireless/rtl8189fs/core/rtw_ap.c | 4215 +++++ .../wireless/rtl8189fs/core/rtw_beamforming.c | 1244 ++ .../net/wireless/rtl8189fs/core/rtw_br_ext.c | 1699 ++ .../net/wireless/rtl8189fs/core/rtw_bt_mp.c | 1753 ++ .../net/wireless/rtl8189fs/core/rtw_btcoex.c | 1739 ++ .../net/wireless/rtl8189fs/core/rtw_cmd.c | 4584 +++++ .../net/wireless/rtl8189fs/core/rtw_debug.c | 3861 ++++ .../net/wireless/rtl8189fs/core/rtw_eeprom.c | 423 + .../wireless/rtl8189fs/core/rtw_ieee80211.c | 2834 +++ .../net/wireless/rtl8189fs/core/rtw_io.c | 737 + .../wireless/rtl8189fs/core/rtw_ioctl_query.c | 192 + .../wireless/rtl8189fs/core/rtw_ioctl_rtl.c | 1021 + .../wireless/rtl8189fs/core/rtw_ioctl_set.c | 1477 ++ .../net/wireless/rtl8189fs/core/rtw_iol.c | 390 + .../net/wireless/rtl8189fs/core/rtw_mem.c | 122 + .../net/wireless/rtl8189fs/core/rtw_mlme.c | 4835 +++++ .../wireless/rtl8189fs/core/rtw_mlme_ext.c | 15390 ++++++++++++++++ .../net/wireless/rtl8189fs/core/rtw_mp.c | 3540 ++++ .../wireless/rtl8189fs/core/rtw_mp_ioctl.c | 2946 +++ .../net/wireless/rtl8189fs/core/rtw_odm.c | 449 + .../net/wireless/rtl8189fs/core/rtw_p2p.c | 5636 ++++++ .../net/wireless/rtl8189fs/core/rtw_pwrctrl.c | 2699 +++ .../net/wireless/rtl8189fs/core/rtw_recv.c | 4963 +++++ .../net/wireless/rtl8189fs/core/rtw_rf.c | 741 + .../wireless/rtl8189fs/core/rtw_security.c | 3346 ++++ .../net/wireless/rtl8189fs/core/rtw_sreset.c | 369 + .../net/wireless/rtl8189fs/core/rtw_sta_mgt.c | 1021 + .../net/wireless/rtl8189fs/core/rtw_tdls.c | 3155 ++++ .../net/wireless/rtl8189fs/core/rtw_vht.c | 803 + .../net/wireless/rtl8189fs/core/rtw_wapi.c | 1326 ++ .../wireless/rtl8189fs/core/rtw_wapi_sms4.c | 923 + .../wireless/rtl8189fs/core/rtw_wlan_util.c | 4735 +++++ .../net/wireless/rtl8189fs/core/rtw_xmit.c | 5074 +++++ .../net/wireless/rtl8189fs/hal/HalPwrSeqCmd.c | 183 + .../rtl8189fs/hal/btc/HalBtc8188c2Ant.c | 1987 ++ .../rtl8189fs/hal/btc/HalBtc8188c2Ant.h | 149 + .../rtl8189fs/hal/btc/HalBtc8192d2Ant.c | 1992 ++ .../rtl8189fs/hal/btc/HalBtc8192d2Ant.h | 170 + .../rtl8189fs/hal/btc/HalBtc8192e1Ant.c | 3738 ++++ .../rtl8189fs/hal/btc/HalBtc8192e1Ant.h | 254 + .../rtl8189fs/hal/btc/HalBtc8192e2Ant.c | 5027 +++++ .../rtl8189fs/hal/btc/HalBtc8192e2Ant.h | 231 + .../rtl8189fs/hal/btc/HalBtc8703b1Ant.c | 5239 ++++++ .../rtl8189fs/hal/btc/HalBtc8703b1Ant.h | 386 + .../rtl8189fs/hal/btc/HalBtc8703b2Ant.c | 4864 +++++ .../rtl8189fs/hal/btc/HalBtc8703b2Ant.h | 228 + .../rtl8189fs/hal/btc/HalBtc8723a1Ant.c | 1544 ++ .../rtl8189fs/hal/btc/HalBtc8723a1Ant.h | 171 + .../rtl8189fs/hal/btc/HalBtc8723a2Ant.c | 3746 ++++ .../rtl8189fs/hal/btc/HalBtc8723a2Ant.h | 184 + .../rtl8189fs/hal/btc/HalBtc8723b1Ant.c | 5638 ++++++ .../rtl8189fs/hal/btc/HalBtc8723b1Ant.h | 337 + .../rtl8189fs/hal/btc/HalBtc8723b2Ant.c | 4933 +++++ .../rtl8189fs/hal/btc/HalBtc8723b2Ant.h | 234 + .../rtl8189fs/hal/btc/HalBtc8812a1Ant.c | 3717 ++++ .../rtl8189fs/hal/btc/HalBtc8812a1Ant.h | 258 + .../rtl8189fs/hal/btc/HalBtc8812a2Ant.c | 5434 ++++++ .../rtl8189fs/hal/btc/HalBtc8812a2Ant.h | 249 + .../rtl8189fs/hal/btc/HalBtc8821a1Ant.c | 3433 ++++ .../rtl8189fs/hal/btc/HalBtc8821a1Ant.h | 213 + .../rtl8189fs/hal/btc/HalBtc8821a2Ant.c | 4858 +++++ .../rtl8189fs/hal/btc/HalBtc8821a2Ant.h | 226 + .../rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.c | 4343 +++++ .../rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.h | 207 + .../wireless/rtl8189fs/hal/btc/HalBtcOutSrc.h | 747 + .../wireless/rtl8189fs/hal/btc/Mp_Precomp.h | 89 + .../wireless/rtl8189fs/hal/efuse/efuse_mask.h | 80 + .../efuse/rtl8188f/HalEfuseMask8188F_SDIO.c | 103 + .../efuse/rtl8188f/HalEfuseMask8188F_SDIO.h | 41 + .../efuse/rtl8188f/HalEfuseMask8188F_USB.c | 102 + .../efuse/rtl8188f/HalEfuseMask8188F_USB.h | 42 + .../net/wireless/rtl8189fs/hal/hal_btcoex.c | 3692 ++++ .../net/wireless/rtl8189fs/hal/hal_com.c | 8005 ++++++++ .../net/wireless/rtl8189fs/hal/hal_com_c2h.h | 45 + .../wireless/rtl8189fs/hal/hal_com_phycfg.c | 4440 +++++ .../net/wireless/rtl8189fs/hal/hal_dm.c | 193 + .../net/wireless/rtl8189fs/hal/hal_dm.h | 26 + .../wireless/rtl8189fs/hal/hal_hci/hal_sdio.c | 112 + .../net/wireless/rtl8189fs/hal/hal_intf.c | 1112 ++ .../net/wireless/rtl8189fs/hal/hal_mp.c | 2141 +++ .../net/wireless/rtl8189fs/hal/hal_phy.c | 285 + .../wireless/rtl8189fs/hal/led/hal_sdio_led.c | 2418 +++ .../wireless/rtl8189fs/hal/phydm/halhwimg.h | 123 + .../rtl8189fs/hal/phydm/halphyrf_ap.c | 2504 +++ .../rtl8189fs/hal/phydm/halphyrf_ap.h | 162 + .../rtl8189fs/hal/phydm/halphyrf_ce.c | 711 + .../rtl8189fs/hal/phydm/halphyrf_ce.h | 106 + .../rtl8189fs/hal/phydm/halphyrf_win.c | 716 + .../rtl8189fs/hal/phydm/halphyrf_win.h | 108 + .../wireless/rtl8189fs/hal/phydm/mp_precomp.h | 20 + .../net/wireless/rtl8189fs/hal/phydm/phydm.c | 2159 +++ .../net/wireless/rtl8189fs/hal/phydm/phydm.h | 1448 ++ .../wireless/rtl8189fs/hal/phydm/phydm_acs.c | 1306 ++ .../wireless/rtl8189fs/hal/phydm/phydm_acs.h | 129 + .../rtl8189fs/hal/phydm/phydm_adaptivity.c | 896 + .../rtl8189fs/hal/phydm/phydm_adaptivity.h | 166 + .../rtl8189fs/hal/phydm/phydm_antdect.c | 964 + .../rtl8189fs/hal/phydm/phydm_antdect.h | 98 + .../rtl8189fs/hal/phydm/phydm_antdiv.c | 4754 +++++ .../rtl8189fs/hal/phydm/phydm_antdiv.h | 567 + .../rtl8189fs/hal/phydm/phydm_beamforming.c | 1939 ++ .../rtl8189fs/hal/phydm/phydm_beamforming.h | 365 + .../rtl8189fs/hal/phydm/phydm_cfotracking.c | 347 + .../rtl8189fs/hal/phydm/phydm_cfotracking.h | 68 + .../rtl8189fs/hal/phydm/phydm_debug.c | 2005 ++ .../rtl8189fs/hal/phydm/phydm_debug.h | 330 + .../wireless/rtl8189fs/hal/phydm/phydm_dig.c | 2086 +++ .../wireless/rtl8189fs/hal/phydm/phydm_dig.h | 327 + .../hal/phydm/phydm_dynamicbbpowersaving.c | 219 + .../hal/phydm/phydm_dynamicbbpowersaving.h | 63 + .../hal/phydm/phydm_dynamictxpower.c | 633 + .../hal/phydm/phydm_dynamictxpower.h | 98 + .../hal/phydm/phydm_edcaturbocheck.c | 835 + .../hal/phydm/phydm_edcaturbocheck.h | 100 + .../rtl8189fs/hal/phydm/phydm_features.h | 115 + .../rtl8189fs/hal/phydm/phydm_hwconfig.c | 3331 ++++ .../rtl8189fs/hal/phydm/phydm_hwconfig.h | 506 + .../rtl8189fs/hal/phydm/phydm_interface.c | 1014 + .../rtl8189fs/hal/phydm/phydm_interface.h | 442 + .../rtl8189fs/hal/phydm/phydm_noisemonitor.c | 299 + .../rtl8189fs/hal/phydm/phydm_noisemonitor.h | 49 + .../rtl8189fs/hal/phydm/phydm_pathdiv.c | 2311 +++ .../rtl8189fs/hal/phydm/phydm_pathdiv.h | 324 + .../hal/phydm/phydm_powertracking_ap.c | 1050 ++ .../hal/phydm/phydm_powertracking_ap.h | 314 + .../hal/phydm/phydm_powertracking_ce.c | 670 + .../hal/phydm/phydm_powertracking_ce.h | 296 + .../hal/phydm/phydm_powertracking_win.c | 687 + .../hal/phydm/phydm_powertracking_win.h | 265 + .../rtl8189fs/hal/phydm/phydm_pre_define.h | 615 + .../rtl8189fs/hal/phydm/phydm_precomp.h | 320 + .../rtl8189fs/hal/phydm/phydm_rainfo.c | 2574 +++ .../rtl8189fs/hal/phydm/phydm_rainfo.h | 445 + .../wireless/rtl8189fs/hal/phydm/phydm_reg.h | 208 + .../rtl8189fs/hal/phydm/phydm_regdefine11ac.h | 90 + .../rtl8189fs/hal/phydm/phydm_regdefine11n.h | 199 + .../wireless/rtl8189fs/hal/phydm/phydm_rxhp.c | 1692 ++ .../wireless/rtl8189fs/hal/phydm/phydm_rxhp.h | 105 + .../rtl8189fs/hal/phydm/phydm_types.h | 259 + .../wireless/rtl8189fs/hal/phydm/rtchnlplan.c | 480 + .../wireless/rtl8189fs/hal/phydm/rtchnlplan.h | 699 + .../hal/phydm/rtl8188f/hal8188freg.h | 862 + .../hal/phydm/rtl8188f/halhwimg8188f_bb.c | 590 + .../hal/phydm/rtl8188f/halhwimg8188f_bb.h | 59 + .../hal/phydm/rtl8188f/halhwimg8188f_fw.c | 3547 ++++ .../hal/phydm/rtl8188f/halhwimg8188f_fw.h | 62 + .../hal/phydm/rtl8188f/halhwimg8188f_mac.c | 288 + .../hal/phydm/rtl8188f/halhwimg8188f_mac.h | 39 + .../hal/phydm/rtl8188f/halhwimg8188f_rf.c | 1130 ++ .../hal/phydm/rtl8188f/halhwimg8188f_rf.h | 79 + .../hal/phydm/rtl8188f/halphyrf_8188f.c | 3609 ++++ .../hal/phydm/rtl8188f/halphyrf_8188f.h | 135 + .../rtl8189fs/hal/phydm/rtl8188f/mp_precomp.h | 24 + .../hal/phydm/rtl8188f/phydm_regconfig8188f.c | 233 + .../hal/phydm/rtl8188f/phydm_regconfig8188f.h | 96 + .../hal/phydm/rtl8188f/phydm_rtl8188f.c | 72 + .../hal/phydm/rtl8188f/phydm_rtl8188f.h | 29 + .../hal/phydm/rtl8188f/version_rtl8188f.h | 10 + .../rtl8189fs/hal/phydm/txbf/halcomtxbf.c | 551 + .../rtl8189fs/hal/phydm/txbf/halcomtxbf.h | 181 + .../rtl8189fs/hal/phydm/txbf/haltxbf8192e.c | 392 + .../rtl8189fs/hal/phydm/txbf/haltxbf8192e.h | 52 + .../rtl8189fs/hal/phydm/txbf/haltxbf8814a.c | 653 + .../rtl8189fs/hal/phydm/txbf/haltxbf8814a.h | 70 + .../rtl8189fs/hal/phydm/txbf/haltxbf8821b.c | 400 + .../rtl8189fs/hal/phydm/txbf/haltxbf8821b.h | 43 + .../rtl8189fs/hal/phydm/txbf/haltxbf8822b.c | 1099 ++ .../rtl8189fs/hal/phydm/txbf/haltxbf8822b.h | 53 + .../hal/phydm/txbf/haltxbfinterface.c | 1384 ++ .../hal/phydm/txbf/haltxbfinterface.h | 158 + .../rtl8189fs/hal/phydm/txbf/haltxbfjaguar.c | 527 + .../rtl8189fs/hal/phydm/txbf/haltxbfjaguar.h | 67 + .../rtl8189fs/hal/rtl8188f/Hal8188FPwrSeq.c | 99 + .../rtl8189fs/hal/rtl8188f/rtl8188f_cmd.c | 1313 ++ .../rtl8189fs/hal/rtl8188f/rtl8188f_dm.c | 623 + .../hal/rtl8188f/rtl8188f_hal_init.c | 7165 +++++++ .../rtl8189fs/hal/rtl8188f/rtl8188f_phycfg.c | 1567 ++ .../rtl8189fs/hal/rtl8188f/rtl8188f_rf6052.c | 297 + .../rtl8189fs/hal/rtl8188f/rtl8188f_rxdesc.c | 69 + .../rtl8189fs/hal/rtl8188f/rtl8188f_sreset.c | 109 + .../hal/rtl8188f/sdio/rtl8189fs_led.c | 127 + .../hal/rtl8188f/sdio/rtl8189fs_recv.c | 711 + .../hal/rtl8188f/sdio/rtl8189fs_xmit.c | 769 + .../hal/rtl8188f/sdio/sdio_halinit.c | 1886 ++ .../rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c | 2350 +++ .../net/wireless/rtl8189fs/ifcfg-wlan0 | 4 + .../rtl8189fs/include/Hal8188EPhyCfg.h | 274 + .../rtl8189fs/include/Hal8188EPhyReg.h | 1106 ++ .../rtl8189fs/include/Hal8188EPwrSeq.h | 176 + .../rtl8189fs/include/Hal8188FPhyCfg.h | 149 + .../rtl8189fs/include/Hal8188FPhyReg.h | 1171 ++ .../rtl8189fs/include/Hal8188FPwrSeq.h | 199 + .../rtl8189fs/include/Hal8192EPhyCfg.h | 178 + .../rtl8189fs/include/Hal8192EPhyReg.h | 1133 ++ .../rtl8189fs/include/Hal8192EPwrSeq.h | 155 + .../rtl8189fs/include/Hal8703BPhyCfg.h | 144 + .../rtl8189fs/include/Hal8703BPhyReg.h | 1139 ++ .../rtl8189fs/include/Hal8703BPwrSeq.h | 184 + .../rtl8189fs/include/Hal8723BPhyCfg.h | 149 + .../rtl8189fs/include/Hal8723BPhyReg.h | 1137 ++ .../rtl8189fs/include/Hal8723BPwrSeq.h | 233 + .../rtl8189fs/include/Hal8723PwrSeq.h | 170 + .../rtl8189fs/include/Hal8812PhyCfg.h | 165 + .../rtl8189fs/include/Hal8812PhyReg.h | 739 + .../rtl8189fs/include/Hal8812PwrSeq.h | 210 + .../rtl8189fs/include/Hal8814PhyCfg.h | 282 + .../rtl8189fs/include/Hal8814PhyReg.h | 866 + .../rtl8189fs/include/Hal8814PwrSeq.h | 237 + .../rtl8189fs/include/Hal8821APwrSeq.h | 186 + .../wireless/rtl8189fs/include/HalPwrSeqCmd.h | 138 + .../wireless/rtl8189fs/include/HalVerDef.h | 202 + .../net/wireless/rtl8189fs/include/autoconf.h | 243 + .../wireless/rtl8189fs/include/basic_types.h | 385 + .../rtl8189fs/include/byteorder/big_endian.h | 88 + .../rtl8189fs/include/byteorder/generic.h | 213 + .../include/byteorder/little_endian.h | 90 + .../rtl8189fs/include/byteorder/swab.h | 141 + .../rtl8189fs/include/byteorder/swabb.h | 157 + .../net/wireless/rtl8189fs/include/circ_buf.h | 28 + .../wireless/rtl8189fs/include/cmd_osdep.h | 32 + .../wireless/rtl8189fs/include/custom_gpio.h | 32 + .../net/wireless/rtl8189fs/include/drv_conf.h | 201 + .../wireless/rtl8189fs/include/drv_types.h | 1304 ++ .../wireless/rtl8189fs/include/drv_types_ce.h | 93 + .../rtl8189fs/include/drv_types_gspi.h | 56 + .../rtl8189fs/include/drv_types_linux.h | 25 + .../rtl8189fs/include/drv_types_pci.h | 273 + .../rtl8189fs/include/drv_types_sdio.h | 81 + .../wireless/rtl8189fs/include/drv_types_xp.h | 95 + .../net/wireless/rtl8189fs/include/ethernet.h | 42 + .../net/wireless/rtl8189fs/include/gspi_hal.h | 36 + .../net/wireless/rtl8189fs/include/gspi_ops.h | 185 + .../rtl8189fs/include/gspi_ops_linux.h | 24 + .../wireless/rtl8189fs/include/gspi_osintf.h | 31 + .../net/wireless/rtl8189fs/include/h2clbk.h | 32 + .../wireless/rtl8189fs/include/hal_btcoex.h | 97 + .../net/wireless/rtl8189fs/include/hal_com.h | 533 + .../wireless/rtl8189fs/include/hal_com_h2c.h | 364 + .../wireless/rtl8189fs/include/hal_com_led.h | 398 + .../rtl8189fs/include/hal_com_phycfg.h | 285 + .../wireless/rtl8189fs/include/hal_com_reg.h | 1780 ++ .../net/wireless/rtl8189fs/include/hal_data.h | 653 + .../net/wireless/rtl8189fs/include/hal_gspi.h | 32 + .../wireless/rtl8189fs/include/hal_ic_cfg.h | 93 + .../net/wireless/rtl8189fs/include/hal_intf.h | 686 + .../net/wireless/rtl8189fs/include/hal_pg.h | 659 + .../net/wireless/rtl8189fs/include/hal_phy.h | 247 + .../wireless/rtl8189fs/include/hal_phy_reg.h | 31 + .../net/wireless/rtl8189fs/include/hal_sdio.h | 32 + .../wireless/rtl8189fs/include/ieee80211.h | 1828 ++ .../rtl8189fs/include/ieee80211_ext.h | 477 + .../net/wireless/rtl8189fs/include/if_ether.h | 113 + .../net/wireless/rtl8189fs/include/ip.h | 141 + .../rtl8189fs/include/linux/wireless.h | 97 + .../wireless/rtl8189fs/include/mlme_osdep.h | 37 + .../rtl8189fs/include/mp_custom_oid.h | 354 + .../net/wireless/rtl8189fs/include/nic_spec.h | 47 + .../wireless/rtl8189fs/include/osdep_intf.h | 173 + .../rtl8189fs/include/osdep_service.h | 634 + .../rtl8189fs/include/osdep_service_bsd.h | 749 + .../rtl8189fs/include/osdep_service_ce.h | 192 + .../rtl8189fs/include/osdep_service_linux.h | 425 + .../rtl8189fs/include/osdep_service_xp.h | 202 + .../net/wireless/rtl8189fs/include/pci_hal.h | 46 + .../net/wireless/rtl8189fs/include/pci_ops.h | 78 + .../wireless/rtl8189fs/include/pci_osintf.h | 32 + .../wireless/rtl8189fs/include/recv_osdep.h | 65 + .../wireless/rtl8189fs/include/rtl8188e_cmd.h | 186 + .../wireless/rtl8189fs/include/rtl8188e_dm.h | 37 + .../wireless/rtl8189fs/include/rtl8188e_hal.h | 332 + .../wireless/rtl8189fs/include/rtl8188e_led.h | 41 + .../rtl8189fs/include/rtl8188e_recv.h | 175 + .../wireless/rtl8189fs/include/rtl8188e_rf.h | 33 + .../rtl8189fs/include/rtl8188e_spec.h | 164 + .../rtl8189fs/include/rtl8188e_sreset.h | 30 + .../rtl8189fs/include/rtl8188e_xmit.h | 299 + .../wireless/rtl8189fs/include/rtl8188f_cmd.h | 218 + .../wireless/rtl8189fs/include/rtl8188f_dm.h | 48 + .../wireless/rtl8189fs/include/rtl8188f_hal.h | 322 + .../wireless/rtl8189fs/include/rtl8188f_led.h | 49 + .../rtl8189fs/include/rtl8188f_recv.h | 73 + .../wireless/rtl8189fs/include/rtl8188f_rf.h | 31 + .../rtl8189fs/include/rtl8188f_spec.h | 302 + .../rtl8189fs/include/rtl8188f_sreset.h | 30 + .../rtl8189fs/include/rtl8188f_xmit.h | 336 + .../wireless/rtl8189fs/include/rtl8192e_cmd.h | 175 + .../wireless/rtl8189fs/include/rtl8192e_dm.h | 38 + .../wireless/rtl8189fs/include/rtl8192e_hal.h | 350 + .../wireless/rtl8189fs/include/rtl8192e_led.h | 41 + .../rtl8189fs/include/rtl8192e_recv.h | 178 + .../wireless/rtl8189fs/include/rtl8192e_rf.h | 34 + .../rtl8189fs/include/rtl8192e_spec.h | 327 + .../rtl8189fs/include/rtl8192e_sreset.h | 30 + .../rtl8189fs/include/rtl8192e_xmit.h | 451 + .../wireless/rtl8189fs/include/rtl8703b_cmd.h | 217 + .../wireless/rtl8189fs/include/rtl8703b_dm.h | 48 + .../wireless/rtl8189fs/include/rtl8703b_hal.h | 326 + .../wireless/rtl8189fs/include/rtl8703b_led.h | 49 + .../rtl8189fs/include/rtl8703b_recv.h | 92 + .../wireless/rtl8189fs/include/rtl8703b_rf.h | 31 + .../rtl8189fs/include/rtl8703b_spec.h | 479 + .../rtl8189fs/include/rtl8703b_sreset.h | 30 + .../rtl8189fs/include/rtl8703b_xmit.h | 336 + .../wireless/rtl8189fs/include/rtl8723b_cmd.h | 217 + .../wireless/rtl8189fs/include/rtl8723b_dm.h | 48 + .../wireless/rtl8189fs/include/rtl8723b_hal.h | 326 + .../wireless/rtl8189fs/include/rtl8723b_led.h | 49 + .../rtl8189fs/include/rtl8723b_recv.h | 92 + .../wireless/rtl8189fs/include/rtl8723b_rf.h | 31 + .../rtl8189fs/include/rtl8723b_spec.h | 295 + .../rtl8189fs/include/rtl8723b_sreset.h | 30 + .../rtl8189fs/include/rtl8723b_xmit.h | 336 + .../wireless/rtl8189fs/include/rtl8812a_cmd.h | 177 + .../wireless/rtl8189fs/include/rtl8812a_dm.h | 37 + .../wireless/rtl8189fs/include/rtl8812a_hal.h | 373 + .../wireless/rtl8189fs/include/rtl8812a_led.h | 41 + .../rtl8189fs/include/rtl8812a_recv.h | 162 + .../wireless/rtl8189fs/include/rtl8812a_rf.h | 34 + .../rtl8189fs/include/rtl8812a_spec.h | 275 + .../rtl8189fs/include/rtl8812a_sreset.h | 30 + .../rtl8189fs/include/rtl8812a_xmit.h | 365 + .../wireless/rtl8189fs/include/rtl8814a_cmd.h | 153 + .../wireless/rtl8189fs/include/rtl8814a_dm.h | 34 + .../wireless/rtl8189fs/include/rtl8814a_hal.h | 341 + .../wireless/rtl8189fs/include/rtl8814a_led.h | 41 + .../rtl8189fs/include/rtl8814a_recv.h | 188 + .../wireless/rtl8189fs/include/rtl8814a_rf.h | 34 + .../rtl8189fs/include/rtl8814a_spec.h | 642 + .../rtl8189fs/include/rtl8814a_sreset.h | 30 + .../rtl8189fs/include/rtl8814a_xmit.h | 309 + .../rtl8189fs/include/rtl8821a_spec.h | 107 + .../rtl8189fs/include/rtl8821a_xmit.h | 180 + .../wireless/rtl8189fs/include/rtw_android.h | 113 + .../net/wireless/rtl8189fs/include/rtw_ap.h | 80 + .../rtl8189fs/include/rtw_beamforming.h | 150 + .../wireless/rtl8189fs/include/rtw_br_ext.h | 76 + .../wireless/rtl8189fs/include/rtw_bt_mp.h | 295 + .../wireless/rtl8189fs/include/rtw_btcoex.h | 436 + .../rtl8189fs/include/rtw_byteorder.h | 39 + .../net/wireless/rtl8189fs/include/rtw_cmd.h | 1320 ++ .../wireless/rtl8189fs/include/rtw_debug.h | 538 + .../wireless/rtl8189fs/include/rtw_eeprom.h | 123 + .../wireless/rtl8189fs/include/rtw_efuse.h | 216 + .../wireless/rtl8189fs/include/rtw_event.h | 137 + .../net/wireless/rtl8189fs/include/rtw_ht.h | 221 + .../net/wireless/rtl8189fs/include/rtw_io.h | 578 + .../wireless/rtl8189fs/include/rtw_ioctl.h | 329 + .../rtl8189fs/include/rtw_ioctl_query.h | 33 + .../rtl8189fs/include/rtw_ioctl_rtl.h | 81 + .../rtl8189fs/include/rtw_ioctl_set.h | 76 + .../net/wireless/rtl8189fs/include/rtw_iol.h | 137 + .../net/wireless/rtl8189fs/include/rtw_mem.h | 42 + .../net/wireless/rtl8189fs/include/rtw_mlme.h | 1078 ++ .../wireless/rtl8189fs/include/rtw_mlme_ext.h | 1226 ++ .../net/wireless/rtl8189fs/include/rtw_mp.h | 979 + .../wireless/rtl8189fs/include/rtw_mp_ioctl.h | 591 + .../rtl8189fs/include/rtw_mp_phy_regdef.h | 1100 ++ .../net/wireless/rtl8189fs/include/rtw_odm.h | 53 + .../net/wireless/rtl8189fs/include/rtw_p2p.h | 179 + .../wireless/rtl8189fs/include/rtw_pwrctrl.h | 514 + .../net/wireless/rtl8189fs/include/rtw_qos.h | 35 + .../net/wireless/rtl8189fs/include/rtw_recv.h | 879 + .../net/wireless/rtl8189fs/include/rtw_rf.h | 271 + .../wireless/rtl8189fs/include/rtw_security.h | 490 + .../wireless/rtl8189fs/include/rtw_sreset.h | 61 + .../net/wireless/rtl8189fs/include/rtw_tdls.h | 149 + .../wireless/rtl8189fs/include/rtw_version.h | 1 + .../net/wireless/rtl8189fs/include/rtw_vht.h | 143 + .../net/wireless/rtl8189fs/include/rtw_wapi.h | 222 + .../rtl8189fs/include/rtw_wifi_regd.h | 26 + .../net/wireless/rtl8189fs/include/rtw_xmit.h | 865 + .../net/wireless/rtl8189fs/include/sdio_hal.h | 56 + .../net/wireless/rtl8189fs/include/sdio_ops.h | 140 + .../wireless/rtl8189fs/include/sdio_ops_ce.h | 55 + .../rtl8189fs/include/sdio_ops_linux.h | 52 + .../wireless/rtl8189fs/include/sdio_ops_xp.h | 55 + .../wireless/rtl8189fs/include/sdio_osintf.h | 36 + .../net/wireless/rtl8189fs/include/sta_info.h | 591 + .../net/wireless/rtl8189fs/include/usb_hal.h | 61 + .../net/wireless/rtl8189fs/include/usb_ops.h | 148 + .../rtl8189fs/include/usb_ops_linux.h | 89 + .../wireless/rtl8189fs/include/usb_osintf.h | 32 + .../rtl8189fs/include/usb_vendor_req.h | 60 + .../net/wireless/rtl8189fs/include/wifi.h | 1397 ++ .../wireless/rtl8189fs/include/wlan_bssdef.h | 748 + .../wireless/rtl8189fs/include/xmit_osdep.h | 100 + .../os_dep/linux/custom_gpio_linux.c | 356 + .../rtl8189fs/os_dep/linux/ioctl_cfg80211.c | 6871 +++++++ .../rtl8189fs/os_dep/linux/ioctl_cfg80211.h | 212 + .../rtl8189fs/os_dep/linux/ioctl_linux.c | 13875 ++++++++++++++ .../rtl8189fs/os_dep/linux/ioctl_mp.c | 2308 +++ .../rtl8189fs/os_dep/linux/mlme_linux.c | 618 + .../rtl8189fs/os_dep/linux/os_intfs.c | 4535 +++++ .../rtl8189fs/os_dep/linux/recv_linux.c | 815 + .../rtl8189fs/os_dep/linux/rtw_android.c | 1293 ++ .../rtl8189fs/os_dep/linux/rtw_cfgvendor.c | 1340 ++ .../rtl8189fs/os_dep/linux/rtw_cfgvendor.h | 246 + .../rtl8189fs/os_dep/linux/rtw_proc.c | 2131 +++ .../rtl8189fs/os_dep/linux/rtw_proc.h | 52 + .../rtl8189fs/os_dep/linux/sdio_intf.c | 1058 ++ .../rtl8189fs/os_dep/linux/sdio_ops_linux.c | 910 + .../rtl8189fs/os_dep/linux/wifi_regd.c | 548 + .../rtl8189fs/os_dep/linux/xmit_linux.c | 546 + .../wireless/rtl8189fs/os_dep/osdep_service.c | 2526 +++ .../platform/platform_ARM_SUN50IW1P1_sdio.c | 91 + .../platform/platform_ARM_SUNnI_sdio.c | 114 + .../platform/platform_ARM_SUNxI_sdio.c | 95 + .../platform/platform_ARM_SUNxI_usb.c | 142 + .../platform/platform_ARM_WMT_sdio.c | 51 + .../rtl8189fs/platform/platform_RTK_DMP_usb.c | 36 + .../platform/platform_arm_act_sdio.c | 58 + .../rtl8189fs/platform/platform_ops.c | 46 + .../rtl8189fs/platform/platform_ops.h | 31 + .../rtl8189fs/platform/platform_sprd_sdio.c | 89 + .../drivers/net/wireless/rtl8189fs/runwpa | 20 + .../drivers/net/wireless/rtl8189fs/wlan0dhcp | 16 + .../drivers/thermal/cpu_budget_cooling.c | 90 +- linux-3.4/include/linux/vm_event_item.h | 1 + linux-3.4/mm/vmscan.c | 24 +- linux-3.4/mm/vmstat.c | 1 + .../src/devicedrv/mali/.tmp_versions/mali.mod | 4 +- .../driver/src/devicedrv/mali/Module.symvers | 42 +- .../src/devicedrv/ump/.tmp_versions/ump.mod | 4 +- .../driver/src/devicedrv/ump/Module.symvers | 18 +- .../mali_drm/.tmp_versions/mali_drm.mod | 4 +- 441 files changed, 354765 insertions(+), 536 deletions(-) delete mode 100755 linux-3.4/drivers/net/wireless/Kconfig.orig delete mode 100755 linux-3.4/drivers/net/wireless/Makefile.orig create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/Kconfig create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/Makefile create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/clean create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/efuse/rtw_efuse.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ap.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_beamforming.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_br_ext.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_bt_mp.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_btcoex.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_cmd.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_debug.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_eeprom.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_io.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_query.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_rtl.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_set.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_iol.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mem.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme_ext.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp_ioctl.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_odm.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_p2p.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_pwrctrl.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_recv.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_rf.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_security.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sreset.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sta_mgt.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_tdls.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_vht.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi_sms4.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wlan_util.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_xmit.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/HalPwrSeqCmd.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtcOutSrc.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/Mp_Precomp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/efuse_mask.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_btcoex.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_c2h.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_phycfg.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_dm.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_hci/hal_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_intf.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_mp.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_phy.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/led/hal_sdio_led.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halhwimg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/mp_precomp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_features.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pre_define.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_precomp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_reg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11ac.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11n.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_types.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/hal8188freg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/mp_precomp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/version_rtl8188f.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/Hal8188FPwrSeq.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_cmd.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_dm.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_hal_init.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_phycfg.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rf6052.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rxdesc.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_sreset.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_led.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_recv.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_xmit.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_halinit.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/ifcfg-wlan0 create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723PwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyCfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyReg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8821APwrSeq.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/HalPwrSeqCmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/HalVerDef.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/autoconf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/basic_types.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/big_endian.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/generic.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/little_endian.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swab.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swabb.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/circ_buf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/cmd_osdep.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/custom_gpio.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_conf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_ce.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_gspi.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_linux.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_pci.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_sdio.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_xp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/ethernet.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops_linux.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_osintf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/h2clbk.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_btcoex.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_h2c.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_phycfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_reg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_data.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_gspi.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_ic_cfg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_intf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_pg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy_reg.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_sdio.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211_ext.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/if_ether.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/ip.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/linux/wireless.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/mlme_osdep.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/mp_custom_oid.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/nic_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_intf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_bsd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_ce.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_linux.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_xp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_ops.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_osintf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/recv_osdep.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_dm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_led.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_spec.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_android.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ap.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_beamforming.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_br_ext.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_bt_mp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_btcoex.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_byteorder.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_cmd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_debug.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_eeprom.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_efuse.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_event.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ht.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_io.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_query.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_rtl.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_set.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_iol.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mem.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme_ext.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_ioctl.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_phy_regdef.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_odm.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_p2p.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_pwrctrl.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_qos.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_recv.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_rf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_security.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_sreset.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_tdls.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_version.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_vht.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_wapi.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_wifi_regd.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_xmit.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_ce.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_linux.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_xp.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_osintf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/sta_info.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_hal.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops_linux.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_osintf.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_vendor_req.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/wifi.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/wlan_bssdef.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/include/xmit_osdep.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/custom_gpio_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_mp.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/mlme_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/os_intfs.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/recv_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_android.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_intf.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_ops_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/wifi_regd.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/xmit_linux.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/osdep_service.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUN50IW1P1_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNnI_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_usb.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_WMT_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_RTK_DMP_usb.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_arm_act_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.h create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_sprd_sdio.c create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/runwpa create mode 100644 linux-3.4/drivers/net/wireless/rtl8189fs/wlan0dhcp diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 6b7385ff..78eac9b5 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -1013,7 +1013,8 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set @@ -1339,11 +1340,14 @@ CONFIG_ZD1211RW=m # CONFIG_MWIFIEX is not set CONFIG_RTL8188EU=m CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m CONFIG_RTL8723BS=m # -# Enable WiMAX (Networking options) to see the WiMAX drivers +# WiMAX Wireless Broadband devices # +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set # CONFIG_WAN is not set # CONFIG_ISDN is not set diff --git a/extra_modules/rtl8192cu-fixes/Makefile b/extra_modules/rtl8192cu-fixes/Makefile index dfbe076b..661e7aa0 100644 --- a/extra_modules/rtl8192cu-fixes/Makefile +++ b/extra_modules/rtl8192cu-fixes/Makefile @@ -538,7 +538,7 @@ EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_P2P_IPS ARCH := arm -CROSS_COMPILE := ../brandy/gcc-linaro/bin/arm-linux-gnueabi- +CROSS_COMPILE := ../../brandy/gcc-linaro/bin/arm-linux-gnueabi- KVER := 3.4 KSRC:= ../linux-3.4/ endif diff --git a/extra_modules/v4l2loopback/Makefile b/extra_modules/v4l2loopback/Makefile index 1cf1ea8c..e584c47a 100644 --- a/extra_modules/v4l2loopback/Makefile +++ b/extra_modules/v4l2loopback/Makefile @@ -3,7 +3,7 @@ KERNEL_DIR ?= /lib/modules/$(KERNELRELEASE)/build PWD := $(shell pwd) obj-m := v4l2loopback.o ARCH := arm -CROSS_COMPILE := ../brandy/gcc-linaro/bin/arm-linux-gnueabi- +CROSS_COMPILE := ../../brandy/gcc-linaro/bin/arm-linux-gnueabi- KVER := 3.4 KSRC:= ../linux-3.4/ diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index 6b7385ff..78eac9b5 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -1013,7 +1013,8 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set @@ -1339,11 +1340,14 @@ CONFIG_ZD1211RW=m # CONFIG_MWIFIEX is not set CONFIG_RTL8188EU=m CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m CONFIG_RTL8723BS=m # -# Enable WiMAX (Networking options) to see the WiMAX drivers +# WiMAX Wireless Broadband devices # +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set # CONFIG_WAN is not set # CONFIG_ISDN is not set diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 1047a958288f556ada94910fa40dcd55e2a73b76..5823357d6863a92d1192decc4af5265f3808e462 100755 GIT binary patch delta 334 zcmdlviD}^^rU?p+1sfHQH?TcrU|?Vjp8T#stbQSo$;<}gtD6H!CPt3=Ac~1qmk~s< z3j!$?7S_zX5(Z|V1OuaX97vvpT^uOE$_->2FxveCQfv)Cg3%!uNHQriu-ymo96=IH z$}DW`K*fws5IG(;ZIGNZnCGP|z%~)Yb%98Vuo;1Pu6!Wdl_l6@K|D7IPln9{#B+!6 z6xi%RJP!y@g-vDh*+xAcXOKl+sX!S{^Udr{x{Q;ZnwwNh^NKUm^HNh3k~0#E81ysp zb5r$mQuFf?i&FCS3ySiyQj<%HH-By}WMT}PoZ6<$m^-<%O`Y-LU|?WOocyjqtX>|-WM%{L)y;t<6C;N#h+<-OWdu>| znm~$$g*7v;gn=0-!N8~;2a;!D*9S_las$~0jCTKk6k8ui)*%=qtIWXm9mI14NiZq1 zu*m}zGde-!c-SmKa?W6$m$Crcd=S?KA}PY=0OGmwfoxZnVABTi+#oy|wlEOS9l}#! z^9AudAUqW|o5^Pz^?0H|7I~!tWjOsevp4B7@|NZmXQt<+rYIz5Bo<9JZf@4s&&bbB z)z3-I&r2*y$=7#DEzT~DQySb2wF>kVO in=)hT - 70: 008e0600 addeq r0, lr, r0, lsl #12 + 70: 00800600 addeq r0, r0, r0, lsl #12 74: 40010000 andmi r0, r1, r0 78: 00000053 andeq r0, r0, r3, asr r0 7c: 06002302 streq r2, [r0], -r2, lsl #6 - 80: 000000f7 strdeq r0, [r0], -r7 + 80: 000000df ldrdeq r0, [r0], -pc ; 84: 00fe4101 rscseq r4, lr, r1, lsl #2 88: 23020000 movwcs r0, #8192 ; 0x2000 - 8c: 011f0604 tsteq pc, r4, lsl #12 + 8c: 01070604 tsteq r7, r4, lsl #12 90: 42010000 andmi r0, r1, #0 94: 00000053 andeq r0, r0, r3, asr r0 98: 060c2302 streq r2, [ip], -r2, lsl #6 - 9c: 00000039 andeq r0, r0, r9, lsr r0 + 9c: 0000002b andeq r0, r0, fp, lsr #32 a0: 00534301 subseq r4, r3, r1, lsl #6 a4: 23020000 movwcs r0, #8192 ; 0x2000 - a8: 009f0610 addseq r0, pc, r0, lsl r6 ; + a8: 00910610 addseq r0, r1, r0, lsl r6 ac: 44010000 strmi r0, [r1], #-0 b0: 00000053 andeq r0, r0, r3, asr r0 b4: 06142302 ldreq r2, [r4], -r2, lsl #6 - b8: 00000040 andeq r0, r0, r0, asr #32 + b8: 00000032 andeq r0, r0, r2, lsr r0 bc: 010e4501 tsteq lr, r1, lsl #10 c0: 23020000 movwcs r0, #8192 ; 0x2000 - c4: 002b0618 eoreq r0, fp, r8, lsl r6 + c4: 001d0618 andseq r0, sp, r8, lsl r6 c8: 46010000 strmi r0, [r1], -r0 cc: 0000010e andeq r0, r0, lr, lsl #2 d0: 061c2302 ldreq r2, [ip], -r2, lsl #6 - d4: 00000056 andeq r0, r0, r6, asr r0 + d4: 00000048 andeq r0, r0, r8, asr #32 d8: 010e4701 tsteq lr, r1, lsl #14 dc: 23020000 movwcs r0, #8192 ; 0x2000 - e0: 004d0620 subeq r0, sp, r0, lsr #12 + e0: 003f0620 eorseq r0, pc, r0, lsr #12 e4: 48010000 stmdami r1, {} ; e8: 0000010e andeq r0, r0, lr, lsl #2 ec: 06242302 strteq r2, [r4], -r2, lsl #6 - f0: 0000013c andeq r0, r0, ip, lsr r1 + f0: 00000124 andeq r0, r0, r4, lsr #2 f4: 00fe4901 rscseq r4, lr, r1, lsl #18 f8: 23020000 movwcs r0, #8192 ; 0x2000 fc: 2c070028 stccs 0, cr0, [r7], {40} ; 0x28 @@ -143,10 +143,10 @@ Disassembly of section .debug_info: 110: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0} 114: 08000001 stmdaeq r0, {r0} 118: 0000005e andeq r0, r0, lr, asr r0 - 11c: 5b030003 blpl c0130 <__bss_end+0xc0054> + 11c: 43030003 movwmi r0, #12291 ; 0x3003 120: 01000001 tsteq r0, r1 124: 0000654a andeq r6, r0, sl, asr #10 - 128: 014f0900 cmpeq pc, r0, lsl #18 + 128: 01370900 teqeq r7, r0, lsl #18 12c: 25020000 strcs r0, [r2, #-0] 130: 0000013b andeq r0, r0, fp, lsr r1 134: 00030501 andeq r0, r3, r1, lsl #10 @@ -237,91 +237,85 @@ Disassembly of section .debug_str: 10: 665f656d ldrbvs r6, [pc], -sp, ror #10 14: 5f656c69 svcpl 0x00656c69 18: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 1c: 736e7500 cmnvc lr, #0 - 20: 656e6769 strbvs r6, [lr, #-1897]! ; 0x769 - 24: 68632064 stmdavs r3!, {r2, r5, r6, sp}^ - 28: 66007261 strvs r7, [r0], -r1, ror #4 - 2c: 5f656c69 svcpl 0x00656c69 - 30: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 34: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} - 38: 6e656c00 cdpvs 12, 6, cr6, cr5, cr0, {0} - 3c: 00687467 rsbeq r7, r8, r7, ror #8 - 40: 5f627570 svcpl 0x00627570 - 44: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 48: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} - 4c: 4f476500 svcmi 0x00476500 - 50: 73765f4e cmnvc r6, #312 ; 0x138 - 54: 6552006e ldrbvs r0, [r2, #-110] ; 0x6e - 58: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 - 5c: 6e73765f mrcvs 6, 3, r7, cr3, cr15, {2} - 60: 63726100 cmnvs r2, #0 - 64: 72612f68 rsbvc r2, r1, #416 ; 0x1a0 - 68: 616d2f6d cmnvs sp, sp, ror #30 - 6c: 732d6863 teqvc sp, #6488064 ; 0x630000 - 70: 69786e75 ldmdbvs r8!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ - 74: 776f702f strbvc r7, [pc, -pc, lsr #32]! - 78: 622f7265 eorvs r7, pc, #1342177286 ; 0x50000006 - 7c: 2f6d6f72 svccs 0x006d6f72 - 80: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 - 84: 685f656d ldmdavs pc, {r0, r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 88: 2e646165 powcssz f6, f4, f5 - 8c: 756a0063 strbvc r0, [sl, #-99]! ; 0x63 - 90: 695f706d ldmdbvs pc, {r0, r2, r3, r5, r6, ip, sp, lr}^ ; - 94: 7274736e rsbsvc r7, r4, #-1207959551 ; 0xb8000001 - 98: 69746375 ldmdbvs r4!, {r0, r2, r4, r5, r6, r8, r9, sp, lr}^ - 9c: 70006e6f andvc r6, r0, pc, ror #28 - a0: 685f6275 ldmdavs pc, {r0, r2, r4, r5, r6, r9, sp, lr}^ ; - a4: 5f646165 svcpl 0x00646165 - a8: 657a6973 ldrbvs r6, [sl, #-2419]! ; 0x973 + 1c: 6c696600 stclvs 6, cr6, [r9], #-0 + 20: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 + 24: 765f6461 ldrbvc r6, [pc], -r1, ror #8 + 28: 6c006e73 stcvs 14, cr6, [r0], {115} ; 0x73 + 2c: 74676e65 strbtvc r6, [r7], #-3685 ; 0xe65 + 30: 75700068 ldrbvc r0, [r0, #-104]! ; 0x68 + 34: 65685f62 strbvs r5, [r8, #-3938]! ; 0xf62 + 38: 765f6461 ldrbvc r6, [pc], -r1, ror #8 + 3c: 65006e73 strvs r6, [r0, #-3699] ; 0xe73 + 40: 5f4e4f47 svcpl 0x004e4f47 + 44: 006e7376 rsbeq r7, lr, r6, ror r3 + 48: 75736552 ldrbvc r6, [r3, #-1362]! ; 0x552 + 4c: 765f656d ldrbvc r6, [pc], -sp, ror #10 + 50: 61006e73 tstvs r0, r3, ror lr + 54: 2f686372 svccs 0x00686372 + 58: 2f6d7261 svccs 0x006d7261 + 5c: 6863616d stmdavs r3!, {r0, r2, r3, r5, r6, r8, sp, lr}^ + 60: 6e75732d cdpvs 3, 7, cr7, cr5, cr13, {1} + 64: 702f6978 eorvc r6, pc, r8, ror r9 ; + 68: 7265776f rsbvc r7, r5, #29097984 ; 0x1bc0000 + 6c: 6f72622f svcvs 0x0072622f + 70: 65722f6d ldrbvs r2, [r2, #-3949]! ; 0xf6d + 74: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 + 78: 6165685f cmnvs r5, pc, asr r8 + 7c: 00632e64 rsbeq r2, r3, r4, ror #28 + 80: 706d756a rsbvc r7, sp, sl, ror #10 + 84: 736e695f cmnvc lr, #1556480 ; 0x17c000 + 88: 63757274 cmnvs r5, #1073741831 ; 0x40000007 + 8c: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3} + 90: 62757000 rsbsvs r7, r5, #0 + 94: 6165685f cmnvs r5, pc, asr r8 + 98: 69735f64 ldmdbvs r3!, {r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 9c: 7500657a strvc r6, [r0, #-1402] ; 0x57a + a0: 6769736e strbvs r7, [r9, -lr, ror #6]! + a4: 2064656e rsbcs r6, r4, lr, ror #10 + a8: 72616863 rsbvc r6, r1, #6488064 ; 0x630000 ac: 6f682f00 svcvs 0x00682f00 b0: 6c2f656d cfstr32vs mvfx6, [pc], #-436 ; ffffff04 <__bss_end+0xfffffe28> b4: 616e6f65 cmnvs lr, r5, ror #30 b8: 2f6f6472 svccs 0x006f6472 - bc: 6b736544 blvs 1cd95d4 <__bss_end+0x1cd94f8> - c0: 2f706f74 svccs 0x00706f74 - c4: 65626d65 strbvs r6, [r2, #-3429]! ; 0xd65 - c8: 6f6f7464 svcvs 0x006f7464 - cc: 726f2f6c rsbvc r2, pc, #432 ; 0x1b0 - d0: 65676e61 strbvs r6, [r7, #-3681]! ; 0xe61 - d4: 654b6970 strbvs r6, [fp, #-2416] ; 0x970 - d8: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 - dc: 61724f2f cmnvs r2, pc, lsr #30 - e0: 5065676e rsbpl r6, r5, lr, ror #14 - e4: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 - e8: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 - ec: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} - f0: 332d7875 teqcc sp, #7667712 ; 0x750000 - f4: 6d00342e cfstrsvs mvf3, [r0, #-184] ; 0xffffff48 - f8: 63696761 cmnvs r9, #25427968 ; 0x1840000 - fc: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 - 100: 34204320 strtcc r4, [r0], #-800 ; 0x320 - 104: 332e362e teqcc lr, #48234496 ; 0x2e00000 - 108: 31303220 teqcc r0, r0, lsr #4 - 10c: 30323032 eorscc r3, r2, r2, lsr r0 - 110: 70282031 eorvc r2, r8, r1, lsr r0 - 114: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 - 118: 7361656c cmnvc r1, #452984832 ; 0x1b000000 - 11c: 63002965 movwvs r2, #2405 ; 0x965 - 120: 6b636568 blvs 18d96c8 <__bss_end+0x18d95ec> - 124: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 - 128: 6f687300 svcvs 0x00687300 - 12c: 75207472 strvc r7, [r0, #-1138]! ; 0x472 - 130: 6769736e strbvs r7, [r9, -lr, ror #6]! - 134: 2064656e rsbcs r6, r4, lr, ror #10 - 138: 00746e69 rsbseq r6, r4, r9, ror #28 - 13c: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 - 140: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 - 144: 6f687300 svcvs 0x00687300 - 148: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} - 14c: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 - 150: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 154: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - 158: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 - 15c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 160: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ - 164: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 168: 5f646165 svcpl 0x00646165 - 16c: Address 0x0000016c is out of bounds. + bc: 6a6f7270 bvs 1bdca84 <__bss_end+0x1bdc9a8> + c0: 73746365 cmnvc r4, #-1811939327 ; 0x94000001 + c4: 61724f2f cmnvs r2, pc, lsr #30 + c8: 5065676e rsbpl r6, r5, lr, ror #14 + cc: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 + d0: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 + d4: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} + d8: 332d7875 teqcc sp, #7667712 ; 0x750000 + dc: 6d00342e cfstrsvs mvf3, [r0, #-184] ; 0xffffff48 + e0: 63696761 cmnvs r9, #25427968 ; 0x1840000 + e4: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 + e8: 34204320 strtcc r4, [r0], #-800 ; 0x320 + ec: 332e362e teqcc lr, #48234496 ; 0x2e00000 + f0: 31303220 teqcc r0, r0, lsr #4 + f4: 30323032 eorscc r3, r2, r2, lsr r0 + f8: 70282031 eorvc r2, r8, r1, lsr r0 + fc: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 + 100: 7361656c cmnvc r1, #452984832 ; 0x1b000000 + 104: 63002965 movwvs r2, #2405 ; 0x965 + 108: 6b636568 blvs 18d96b0 <__bss_end+0x18d95d4> + 10c: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 + 110: 6f687300 svcvs 0x00687300 + 114: 75207472 strvc r7, [r0, #-1138]! ; 0x472 + 118: 6769736e strbvs r7, [r9, -lr, ror #6]! + 11c: 2064656e rsbcs r6, r4, lr, ror #10 + 120: 00746e69 rsbseq r6, r4, r9, ror #28 + 124: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 + 128: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 + 12c: 6f687300 svcvs 0x00687300 + 130: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} + 134: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 + 138: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 13c: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 + 140: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 + 144: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 148: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 14c: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 150: 5f646165 svcpl 0x00646165 + 154: Address 0x00000154 is out of bounds. Disassembly of section .comment: diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 2ebc106c..95e41507 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -71,9 +71,9 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) .debug_line 0x00000000 0x7b .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o -.debug_str 0x00000000 0x16e - .debug_str 0x00000000 0x16e arch/arm/mach-sunxi/power/brom/resume_head.o - 0x187 (size before relaxing) +.debug_str 0x00000000 0x156 + .debug_str 0x00000000 0x156 arch/arm/mach-sunxi/power/brom/resume_head.o + 0x16f (size before relaxing) .comment 0x00000000 0x64 .comment 0x00000000 0x64 arch/arm/mach-sunxi/power/brom/resume_head.o diff --git a/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c b/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c index ba0fbe74..74f3ac57 100755 --- a/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c +++ b/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c @@ -72,24 +72,35 @@ int table_length_syscfg = 0; struct cpufreq_dvfs dvfs_table_syscfg[16]; struct cpufreq_frequency_table sunxi_freq_tbl[] = { - { .frequency = 60000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 120000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 240000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 312000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 408000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 480000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 504000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 600000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 648000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 720000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 816000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 912000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1008000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1104000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1200000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1344000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1440000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1536000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 60000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 120000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 240000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 312000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 408000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 480000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 504000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 528000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 576000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 600000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 624000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 648000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 672000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 720000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 768000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 816000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 864000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 912000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 960000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1008000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1056000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1104000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1152000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1200000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1248000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1296000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1344000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1440000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, + { .frequency = 1536000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, /* table end */ { .frequency = CPUFREQ_TABLE_END, .index = 0, }, diff --git a/linux-3.4/drivers/net/wireless/Kconfig b/linux-3.4/drivers/net/wireless/Kconfig index f1e69797..c4ed5dba 100755 --- a/linux-3.4/drivers/net/wireless/Kconfig +++ b/linux-3.4/drivers/net/wireless/Kconfig @@ -295,5 +295,6 @@ source "drivers/net/wireless/zd1211rw/Kconfig" source "drivers/net/wireless/mwifiex/Kconfig" source "drivers/net/wireless/rtl8188eu/Kconfig" source "drivers/net/wireless/rtl8189es/Kconfig" +source "drivers/net/wireless/rtl8189fs/Kconfig" source "drivers/net/wireless/rtl8723bs/Kconfig" endif # WLAN diff --git a/linux-3.4/drivers/net/wireless/Kconfig.orig b/linux-3.4/drivers/net/wireless/Kconfig.orig deleted file mode 100755 index 4d649040..00000000 --- a/linux-3.4/drivers/net/wireless/Kconfig.orig +++ /dev/null @@ -1,298 +0,0 @@ -# -# Wireless LAN device configuration -# - -menuconfig WLAN - bool "Wireless LAN" - depends on !S390 - depends on NET - select WIRELESS - default y - ---help--- - This section contains all the pre 802.11 and 802.11 wireless - device drivers. For a complete list of drivers and documentation - on them refer to the wireless wiki: - - http://wireless.kernel.org/en/users/Drivers - -if WLAN - -config PCMCIA_RAYCS - tristate "Aviator/Raytheon 2.4GHz wireless support" - depends on PCMCIA - select WIRELESS_EXT - select WEXT_SPY - select WEXT_PRIV - ---help--- - Say Y here if you intend to attach an Aviator/Raytheon PCMCIA - (PC-card) wireless Ethernet networking card to your computer. - Please read the file for - details. - - To compile this driver as a module, choose M here: the module will be - called ray_cs. If unsure, say N. - -config LIBERTAS_THINFIRM - tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware" - depends on MAC80211 - select FW_LOADER - ---help--- - A library for Marvell Libertas 8xxx devices using thinfirm. - -config LIBERTAS_THINFIRM_DEBUG - bool "Enable full debugging output in the Libertas thin firmware module." - depends on LIBERTAS_THINFIRM - ---help--- - Debugging support. - -config LIBERTAS_THINFIRM_USB - tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" - depends on LIBERTAS_THINFIRM && USB - ---help--- - A driver for Marvell Libertas 8388 USB devices using thinfirm. - -config AIRO - tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" - depends on ISA_DMA_API && (PCI || BROKEN) - select WIRELESS_EXT - select CRYPTO - select WEXT_SPY - select WEXT_PRIV - ---help--- - This is the standard Linux driver to support Cisco/Aironet ISA and - PCI 802.11 wireless cards. - It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X - - with or without encryption) as well as card before the Cisco - acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). - - This driver support both the standard Linux Wireless Extensions - and Cisco proprietary API, so both the Linux Wireless Tools and the - Cisco Linux utilities can be used to configure the card. - - The driver can be compiled as a module and will be named "airo". - -config ATMEL - tristate "Atmel at76c50x chipset 802.11b support" - depends on (PCI || PCMCIA) - select WIRELESS_EXT - select WEXT_PRIV - select FW_LOADER - select CRC32 - ---help--- - A driver 802.11b wireless cards based on the Atmel fast-vnet - chips. This driver supports standard Linux wireless extensions. - - Many cards based on this chipset do not have flash memory - and need their firmware loaded at start-up. If yours is - one of these, you will need to provide a firmware image - to be loaded into the card by the driver. The Atmel - firmware package can be downloaded from - - -config PCI_ATMEL - tristate "Atmel at76c506 PCI cards" - depends on ATMEL && PCI - ---help--- - Enable support for PCI and mini-PCI cards containing the - Atmel at76c506 chip. - -config PCMCIA_ATMEL - tristate "Atmel at76c502/at76c504 PCMCIA cards" - depends on ATMEL && PCMCIA - select WIRELESS_EXT - select FW_LOADER - select CRC32 - ---help--- - Enable support for PCMCIA cards containing the - Atmel at76c502 and at76c504 chips. - -config AT76C50X_USB - tristate "Atmel at76c503/at76c505/at76c505a USB cards" - depends on MAC80211 && USB - select FW_LOADER - ---help--- - Enable support for USB Wireless devices using Atmel at76c503, - at76c505 or at76c505a chips. - -config AIRO_CS - tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" - depends on PCMCIA && (BROKEN || !M32R) - select WIRELESS_EXT - select WEXT_SPY - select WEXT_PRIV - select CRYPTO - select CRYPTO_AES - ---help--- - This is the standard Linux driver to support Cisco/Aironet PCMCIA - 802.11 wireless cards. This driver is the same as the Aironet - driver part of the Linux Pcmcia package. - It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X - - with or without encryption) as well as card before the Cisco - acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also - supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom - 802.11b cards. - - This driver support both the standard Linux Wireless Extensions - and Cisco proprietary API, so both the Linux Wireless Tools and the - Cisco Linux utilities can be used to configure the card. - -config PCMCIA_WL3501 - tristate "Planet WL3501 PCMCIA cards" - depends on EXPERIMENTAL && PCMCIA - select WIRELESS_EXT - select WEXT_SPY - help - A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet. - It has basic support for Linux wireless extensions and initial - micro support for ethtool. - -config PRISM54 - tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)' - depends on PCI && EXPERIMENTAL - select WIRELESS_EXT - select WEXT_SPY - select WEXT_PRIV - select FW_LOADER - ---help--- - This enables support for FullMAC PCI/Cardbus prism54 devices. This - driver is now deprecated in favor for the SoftMAC driver, p54pci. - p54pci supports FullMAC PCI/Cardbus devices as well. For details on - the scheduled removal of this driver on the kernel see the feature - removal schedule: - - Documentation/feature-removal-schedule.txt - - For more information refer to the p54 wiki: - - http://wireless.kernel.org/en/users/Drivers/p54 - - Note: You need a motherboard with DMA support to use any of these cards - - When built as module you get the module prism54 - -config USB_ZD1201 - tristate "USB ZD1201 based Wireless device support" - depends on USB - select WIRELESS_EXT - select WEXT_PRIV - select FW_LOADER - ---help--- - Say Y if you want to use wireless LAN adapters based on the ZyDAS - ZD1201 chip. - - This driver makes the adapter appear as a normal Ethernet interface, - typically on wlan0. - - The zd1201 device requires external firmware to be loaded. - This can be found at http://linux-lc100020.sourceforge.net/ - - To compile this driver as a module, choose M here: the - module will be called zd1201. - -config USB_NET_RNDIS_WLAN - tristate "Wireless RNDIS USB support" - depends on USB && EXPERIMENTAL - depends on CFG80211 - select USB_USBNET - select USB_NET_CDCETHER - select USB_NET_RNDIS_HOST - ---help--- - This is a driver for wireless RNDIS devices. - These are USB based adapters found in devices such as: - - Buffalo WLI-U2-KG125S - U.S. Robotics USR5421 - Belkin F5D7051 - Linksys WUSB54GSv2 - Linksys WUSB54GSC - Asus WL169gE - Eminent EM4045 - BT Voyager 1055 - Linksys WUSB54GSv1 - U.S. Robotics USR5420 - BUFFALO WLI-USB-G54 - - All of these devices are based on Broadcom 4320 chip which is the - only wireless RNDIS chip known to date. - - If you choose to build a module, it'll be called rndis_wlan. - -source "drivers/net/wireless/rtl818x/Kconfig" - -config ADM8211 - tristate "ADMtek ADM8211 support" - depends on MAC80211 && PCI && EXPERIMENTAL - select CRC32 - select EEPROM_93CX6 - ---help--- - This driver is for ADM8211A, ADM8211B, and ADM8211C based cards. - These are PCI/mini-PCI/Cardbus 802.11b chips found in cards such as: - - Xterasys Cardbus XN-2411b - Blitz NetWave Point PC - TrendNet 221pc - Belkin F5D6001 - SMC 2635W - Linksys WPC11 v1 - Fiberline FL-WL-200X - 3com Office Connect (3CRSHPW796) - Corega WLPCIB-11 - SMC 2602W V2 EU - D-Link DWL-520 Revision C - - However, some of these cards have been replaced with other chips - like the RTL8180L (Xterasys Cardbus XN-2411b, Belkin F5D6001) or - the Ralink RT2400 (SMC2635W) without a model number change. - - Thanks to Infineon-ADMtek for their support of this driver. - -config MAC80211_HWSIM - tristate "Simulated radio testing tool for mac80211" - depends on MAC80211 - ---help--- - This driver is a developer testing tool that can be used to test - IEEE 802.11 networking stack (mac80211) functionality. This is not - needed for normal wireless LAN usage and is only for testing. See - Documentation/networking/mac80211_hwsim for more information on how - to use this tool. - - To compile this driver as a module, choose M here: the module will be - called mac80211_hwsim. If unsure, say N. - -config MWL8K - tristate "Marvell 88W8xxx PCI/PCIe Wireless support" - depends on MAC80211 && PCI && EXPERIMENTAL - ---help--- - This driver supports Marvell TOPDOG 802.11 wireless cards. - - To compile this driver as a module, choose M here: the module - will be called mwl8k. If unsure, say N. - -config WIFI_CONTROL_FUNC - bool "Enable WiFi control function abstraction" - help - Enables Power/Reset/Carddetect function abstraction - -source "drivers/net/wireless/ath/Kconfig" -source "drivers/net/wireless/b43/Kconfig" -source "drivers/net/wireless/b43legacy/Kconfig" -source "drivers/net/wireless/bcmdhd/Kconfig" -source "drivers/net/wireless/brcm80211/Kconfig" -source "drivers/net/wireless/hostap/Kconfig" -source "drivers/net/wireless/ipw2x00/Kconfig" -source "drivers/net/wireless/iwlwifi/Kconfig" -source "drivers/net/wireless/iwlegacy/Kconfig" -source "drivers/net/wireless/iwmc3200wifi/Kconfig" -source "drivers/net/wireless/libertas/Kconfig" -source "drivers/net/wireless/orinoco/Kconfig" -source "drivers/net/wireless/p54/Kconfig" -source "drivers/net/wireless/rt2x00/Kconfig" -source "drivers/net/wireless/rtlwifi/Kconfig" -source "drivers/net/wireless/wl1251/Kconfig" -source "drivers/net/wireless/wl12xx/Kconfig" -source "drivers/net/wireless/zd1211rw/Kconfig" -source "drivers/net/wireless/mwifiex/Kconfig" -source "drivers/net/wireless/rtl8188eu/Kconfig" -source "drivers/net/wireless/rtl8189es/Kconfig" -source "drivers/net/wireless/rtl8723bs/Kconfig" -endif # WLAN diff --git a/linux-3.4/drivers/net/wireless/Makefile b/linux-3.4/drivers/net/wireless/Makefile index aee4b10e..1b1747d3 100755 --- a/linux-3.4/drivers/net/wireless/Makefile +++ b/linux-3.4/drivers/net/wireless/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_RTL8187) += rtl818x/ obj-$(CONFIG_RTLWIFI) += rtlwifi/ obj-$(CONFIG_RTL8188EU) += rtl8188eu/ obj-$(CONFIG_RTL8189ES) += rtl8189es/ +obj-$(CONFIG_RTL8189FS) += rtl8189fs/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ # 16-bit wireless PCMCIA client drivers diff --git a/linux-3.4/drivers/net/wireless/Makefile.orig b/linux-3.4/drivers/net/wireless/Makefile.orig deleted file mode 100755 index 2251acaf..00000000 --- a/linux-3.4/drivers/net/wireless/Makefile.orig +++ /dev/null @@ -1,68 +0,0 @@ -# -# Makefile for the Linux Wireless network device drivers. -# - -obj-$(CONFIG_IPW2100) += ipw2x00/ -obj-$(CONFIG_IPW2200) += ipw2x00/ - -obj-$(CONFIG_HERMES) += orinoco/ - -obj-$(CONFIG_AIRO) += airo.o -obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o - -obj-$(CONFIG_ATMEL) += atmel.o -obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o -obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o - -obj-$(CONFIG_AT76C50X_USB) += at76c50x-usb.o - -obj-$(CONFIG_PRISM54) += prism54/ - -obj-$(CONFIG_HOSTAP) += hostap/ -obj-$(CONFIG_B43) += b43/ -obj-$(CONFIG_B43LEGACY) += b43legacy/ -obj-$(CONFIG_ZD1211RW) += zd1211rw/ -obj-$(CONFIG_RTL8180) += rtl818x/ -obj-$(CONFIG_RTL8187) += rtl818x/ -obj-$(CONFIG_RTLWIFI) += rtlwifi/ -obj-$(CONFIG_RTL8188EU) += rtl8188eu/ -obj-$(CONFIG_RTL8189ES) += rtl8189es/ -obj-$(CONFIG_RTL8723BS) += rtl8723bs/ - -# 16-bit wireless PCMCIA client drivers -obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o -obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o - -obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o - -obj-$(CONFIG_USB_ZD1201) += zd1201.o -obj-$(CONFIG_LIBERTAS) += libertas/ - -obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ - -obj-$(CONFIG_ADM8211) += adm8211.o - -obj-$(CONFIG_MWL8K) += mwl8k.o - -obj-$(CONFIG_IWLWIFI) += iwlwifi/ -obj-$(CONFIG_IWLEGACY) += iwlegacy/ -obj-$(CONFIG_RT2X00) += rt2x00/ - -obj-$(CONFIG_P54_COMMON) += p54/ - -obj-$(CONFIG_ATH_COMMON) += ath/ - -obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o - -obj-$(CONFIG_WL1251) += wl1251/ -obj-$(CONFIG_WL12XX) += wl12xx/ -obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ - -obj-$(CONFIG_IWM) += iwmc3200wifi/ - -obj-$(CONFIG_MWIFIEX) += mwifiex/ - -obj-$(CONFIG_BCMDHD) += bcmdhd/ - -obj-$(CONFIG_BRCMFMAC) += brcm80211/ -obj-$(CONFIG_BRCMSMAC) += brcm80211/ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/Kconfig b/linux-3.4/drivers/net/wireless/rtl8189fs/Kconfig new file mode 100644 index 00000000..ca442c61 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/Kconfig @@ -0,0 +1,5 @@ +config RTL8189FS + tristate "Realtek 8189FS SDIO WiFi" + depends on USB + ---help--- + Help message of RTL8189FS diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/Makefile b/linux-3.4/drivers/net/wireless/rtl8189fs/Makefile new file mode 100644 index 00000000..df13f7b5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/Makefile @@ -0,0 +1,1730 @@ +EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS) +EXTRA_CFLAGS += -O1 +#EXTRA_CFLAGS += -O3 +#EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Wextra +#EXTRA_CFLAGS += -Werror +#EXTRA_CFLAGS += -pedantic +#EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes + +EXTRA_CFLAGS += -Wno-unused-variable +EXTRA_CFLAGS += -Wno-unused-value +EXTRA_CFLAGS += -Wno-unused-label +EXTRA_CFLAGS += -Wno-unused-parameter +EXTRA_CFLAGS += -Wno-unused-function +EXTRA_CFLAGS += -Wno-unused +#EXTRA_CFLAGS += -Wno-uninitialized +#EXTRA_CFLAGS += -Wno-error=date-time # Fix compile error on gcc 4.9 and later + +EXTRA_CFLAGS += -I$(src)/include +EXTRA_CFLAGS += -I$(src)/hal/phydm + +EXTRA_LDFLAGS += --strip-debug + +CONFIG_AUTOCFG_CP = n + +########################## WIFI IC ############################ +CONFIG_MULTIDRV = n +CONFIG_RTL8188E = n +CONFIG_RTL8812A = n +CONFIG_RTL8821A = n +CONFIG_RTL8192E = n +CONFIG_RTL8723B = n +CONFIG_RTL8814A = n +CONFIG_RTL8723C = n +CONFIG_RTL8188F = y +######################### Interface ########################### +CONFIG_USB_HCI = n +CONFIG_PCI_HCI = n +CONFIG_SDIO_HCI = y +CONFIG_GSPI_HCI = n +########################## Features ########################### +CONFIG_MP_INCLUDED = y +CONFIG_POWER_SAVING = n +CONFIG_USB_AUTOSUSPEND = n +CONFIG_HW_PWRP_DETECTION = n +CONFIG_WIFI_TEST = n +CONFIG_BT_COEXIST = n +CONFIG_INTEL_WIDI = n +CONFIG_WAPI_SUPPORT = n +CONFIG_EFUSE_CONFIG_FILE = n +CONFIG_EXT_CLK = n +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 = disable +CONFIG_RTW_ADAPTIVITY_MODE = normal +CONFIG_SIGNAL_SCALE_MAPPING = n +CONFIG_80211W = n +CONFIG_REDUCE_TX_CPU_LOADING = n +CONFIG_BR_EXT = n +CONFIG_ANTENNA_DIVERSITY = n +CONFIG_TDLS = n +CONFIG_WIFI_MONITOR = y +######################## Wake On Lan ########################## +CONFIG_WOWLAN = n +CONFIG_GPIO_WAKEUP = n +CONFIG_WAKEUP_GPIO_IDX = default +CONFIG_HIGH_ACTIVE = n +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 = n +###################### MP HW TX MODE FOR VHT ####################### +CONFIG_MP_VHT_HW_TX_MODE = n +###################### Platform Related ####################### +CONFIG_PLATFORM_I386_PC = n +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 +CONFIG_PLATFORM_ARM_S3C6K4 = n +CONFIG_PLATFORM_MIPS_RMI = n +CONFIG_PLATFORM_RTD2880B = n +CONFIG_PLATFORM_MIPS_AR9132 = n +CONFIG_PLATFORM_RTK_DMP = n +CONFIG_PLATFORM_MIPS_PLM = n +CONFIG_PLATFORM_MSTAR389 = n +CONFIG_PLATFORM_MT53XX = n +CONFIG_PLATFORM_ARM_MX51_241H = n +CONFIG_PLATFORM_FS_MX61 = n +CONFIG_PLATFORM_ACTIONS_ATJ227X = n +CONFIG_PLATFORM_TEGRA3_CARDHU = n +CONFIG_PLATFORM_TEGRA4_DALMORE = n +CONFIG_PLATFORM_ARM_TCC8900 = n +CONFIG_PLATFORM_ARM_TCC8920 = n +CONFIG_PLATFORM_ARM_TCC8920_JB42 = n +CONFIG_PLATFORM_ARM_TCC8930_JB42 = n +CONFIG_PLATFORM_ARM_RK2818 = n +CONFIG_PLATFORM_ARM_RK3066 = n +CONFIG_PLATFORM_ARM_RK3188 = n +CONFIG_PLATFORM_ARM_URBETTER = n +CONFIG_PLATFORM_ARM_TI_PANDA = n +CONFIG_PLATFORM_MIPS_JZ4760 = n +CONFIG_PLATFORM_DMP_PHILIPS = n +CONFIG_PLATFORM_MSTAR_TITANIA12 = n +CONFIG_PLATFORM_MSTAR = n +CONFIG_PLATFORM_SZEBOOK = n +CONFIG_PLATFORM_ARM_SUNxI = n +CONFIG_PLATFORM_ARM_SUN6I = n +CONFIG_PLATFORM_ARM_SUN7I = n +CONFIG_PLATFORM_ARM_SUN8I = y +CONFIG_PLATFORM_ACTIONS_ATM702X = n +CONFIG_PLATFORM_ACTIONS_ATV5201 = n +CONFIG_PLATFORM_ACTIONS_ATM705X = n +CONFIG_PLATFORM_ARM_SUN50IW1P1 = n +CONFIG_PLATFORM_ARM_RTD299X = n +CONFIG_PLATFORM_ARM_SPREADTRUM_6820 = n +CONFIG_PLATFORM_ARM_SPREADTRUM_8810 = n +CONFIG_PLATFORM_ARM_WMT = n +CONFIG_PLATFORM_TI_DM365 = n +CONFIG_PLATFORM_AML = n +CONFIG_PLATFORM_MOZART = n +CONFIG_PLATFORM_RTK119X = n +CONFIG_PLATFORM_NOVATEK_NT72668 = n +CONFIG_PLATFORM_HISILICON = n +############################################################### + +CONFIG_DRVEXT_MODULE = n + +export TopDIR ?= $(shell pwd) + +########### COMMON ################################# +ifeq ($(CONFIG_GSPI_HCI), y) +HCI_NAME = gspi +endif + +ifeq ($(CONFIG_SDIO_HCI), y) +HCI_NAME = sdio +endif + +ifeq ($(CONFIG_USB_HCI), y) +HCI_NAME = usb +endif + +ifeq ($(CONFIG_PCI_HCI), y) +HCI_NAME = pci +endif + + +_OS_INTFS_FILES := os_dep/osdep_service.o \ + os_dep/linux/os_intfs.o \ + os_dep/linux/$(HCI_NAME)_intf.o \ + os_dep/linux/$(HCI_NAME)_ops_linux.o \ + os_dep/linux/ioctl_linux.o \ + os_dep/linux/xmit_linux.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 + +ifeq ($(CONFIG_MP_INCLUDED), y) +_OS_INTFS_FILES += os_dep/linux/ioctl_mp.o +endif + +ifeq ($(CONFIG_SDIO_HCI), y) +_OS_INTFS_FILES += os_dep/linux/custom_gpio_linux.o +_OS_INTFS_FILES += os_dep/linux/$(HCI_NAME)_ops_linux.o +endif + +ifeq ($(CONFIG_GSPI_HCI), y) +_OS_INTFS_FILES += os_dep/linux/custom_gpio_linux.o +_OS_INTFS_FILES += os_dep/linux/$(HCI_NAME)_ops_linux.o +endif + + +_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_mp.o \ + hal/hal_hci/hal_$(HCI_NAME).o \ + hal/led/hal_$(HCI_NAME)_led.o + + +_OUTSRC_FILES := hal/phydm/phydm_debug.o \ + hal/phydm/phydm_antdiv.o\ + hal/phydm/phydm_antdect.o\ + hal/phydm/phydm_interface.o\ + hal/phydm/phydm_hwconfig.o\ + hal/phydm/phydm.o\ + hal/phydm/halphyrf_ce.o\ + hal/phydm/phydm_edcaturbocheck.o\ + hal/phydm/phydm_dig.o\ + hal/phydm/phydm_pathdiv.o\ + hal/phydm/phydm_rainfo.o\ + hal/phydm/phydm_dynamicbbpowersaving.o\ + hal/phydm/phydm_powertracking_ce.o\ + hal/phydm/phydm_dynamictxpower.o\ + hal/phydm/phydm_adaptivity.o\ + hal/phydm/phydm_cfotracking.o\ + hal/phydm/phydm_noisemonitor.o\ + hal/phydm/phydm_acs.o\ + hal/phydm/phydm_beamforming.o\ + hal/phydm/txbf/halcomtxbf.o\ + hal/phydm/txbf/haltxbfinterface.o + + +EXTRA_CFLAGS += -I$(src)/platform +_PLATFORM_FILES := platform/platform_ops.o + +ifeq ($(CONFIG_BT_COEXIST), y) +EXTRA_CFLAGS += -I$(src)/hal/btc +_OUTSRC_FILES += hal/btc/HalBtc8192e1Ant.o \ + hal/btc/HalBtc8192e2Ant.o \ + hal/btc/HalBtc8723b1Ant.o \ + hal/btc/HalBtc8723b2Ant.o \ + hal/btc/HalBtc8812a1Ant.o \ + hal/btc/HalBtc8812a2Ant.o \ + hal/btc/HalBtc8821a1Ant.o \ + hal/btc/HalBtc8821a2Ant.o \ + hal/btc/HalBtc8821aCsr2Ant.o \ + hal/btc/HalBtc8703b1Ant.o \ + hal/btc/HalBtc8703b2Ant.o +endif + + +########### HAL_RTL8188E ################################# +ifeq ($(CONFIG_RTL8188E), y) + +RTL871X = rtl8188e +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8189fs +endif + +ifeq ($(CONFIG_GSPI_HCI), y) +MODULE_NAME = 8189es +endif + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8188eu +endif + +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8188ee +endif +EXTRA_CFLAGS += -DCONFIG_RTL8188E + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8188EPwrSeq.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 \ + hal/$(RTL871X)/$(RTL871X)_dm.o \ + hal/$(RTL871X)/$(RTL871X)_rxdesc.o \ + hal/$(RTL871X)/$(RTL871X)_cmd.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 + +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +ifeq ($(CONFIG_GSPI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +endif +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8188E_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8188E_PCIE.o +endif +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8188E_SDIO.o +endif + +#hal/OUTSRC/$(RTL871X)/Hal8188EFWImg_CE.o +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8188e_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8188e_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8188e_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8188e_t_fw.o\ + hal/phydm/$(RTL871X)/halhwimg8188e_s_fw.o\ + hal/phydm/$(RTL871X)/halphyrf_8188e_ce.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8188e.o\ + hal/phydm/$(RTL871X)/hal8188erateadaptive.o\ + hal/phydm/$(RTL871X)/phydm_rtl8188e.o + +endif + +########### HAL_RTL8192E ################################# +ifeq ($(CONFIG_RTL8192E), y) + +RTL871X = rtl8192e +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8192es +endif + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8192eu +endif + +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8192ee +endif +EXTRA_CFLAGS += -DCONFIG_RTL8192E +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8192EPwrSeq.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 \ + hal/$(RTL871X)/$(RTL871X)_dm.o \ + hal/$(RTL871X)/$(RTL871X)_rxdesc.o \ + hal/$(RTL871X)/$(RTL871X)_cmd.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 + +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +ifeq ($(CONFIG_GSPI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +endif +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8192E_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8192E_PCIE.o +endif + +#hal/OUTSRC/$(RTL871X)/HalHWImg8188E_FW.o +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8192e_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8192e_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8192e_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8192e_fw.o\ + hal/phydm/$(RTL871X)/halphyrf_8192e_ce.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8192e.o\ + hal/phydm/$(RTL871X)/phydm_rtl8192e.o + +endif + +########### HAL_RTL8812A_RTL8821A ################################# + +ifneq ($(CONFIG_RTL8812A)_$(CONFIG_RTL8821A), n_n) + +RTL871X = rtl8812a +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8812au +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8812ae +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8812as +endif + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8812PwrSeq.o \ + hal/$(RTL871X)/Hal8821APwrSeq.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 \ + hal/$(RTL871X)/$(RTL871X)_dm.o \ + hal/$(RTL871X)/$(RTL871X)_rxdesc.o \ + hal/$(RTL871X)/$(RTL871X)_cmd.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 + +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +ifeq ($(CONFIG_GSPI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +endif +endif + +ifeq ($(CONFIG_RTL8812A), y) +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8812A_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8812A_PCIE.o +endif +endif +ifeq ($(CONFIG_RTL8821A), y) +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8821A_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8821A_PCIE.o +endif +endif + +ifeq ($(CONFIG_RTL8812A), y) +EXTRA_CFLAGS += -DCONFIG_RTL8812A +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8812a_fw.o\ + hal/phydm/$(RTL871X)/halhwimg8812a_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8812a_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8812a_rf.o\ + hal/phydm/$(RTL871X)/halphyrf_8812a_ce.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8812a.o\ + hal/phydm/$(RTL871X)/phydm_rtl8812a.o\ + hal/phydm/txbf/haltxbfjaguar.o +endif + +ifeq ($(CONFIG_RTL8821A), y) + +ifeq ($(CONFIG_RTL8812A), n) + +RTL871X = rtl8821a +ifeq ($(CONFIG_USB_HCI), y) +ifeq ($(CONFIG_BT_COEXIST), y) +MODULE_NAME := 8821au +else +MODULE_NAME := 8811au +endif +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME := 8821ae +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME := 8821as +endif + +endif + +EXTRA_CFLAGS += -DCONFIG_RTL8821A +_OUTSRC_FILES += hal/phydm/rtl8821a/halhwimg8821a_fw.o\ + hal/phydm/rtl8821a/halhwimg8821a_mac.o\ + hal/phydm/rtl8821a/halhwimg8821a_bb.o\ + hal/phydm/rtl8821a/halhwimg8821a_rf.o\ + hal/phydm/rtl8812a/halphyrf_8812a_ce.o\ + hal/phydm/rtl8821a/halphyrf_8821a_ce.o\ + hal/phydm/rtl8821a/phydm_regconfig8821a.o\ + hal/phydm/rtl8821a/phydm_rtl8821a.o\ + hal/phydm/rtl8821a/phydm_iqk_8821a_ce.o\ + hal/phydm/txbf/haltxbfjaguar.o + +endif + + +endif + +########### HAL_RTL8723B ################################# +ifeq ($(CONFIG_RTL8723B), y) + +RTL871X = rtl8723b +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8723bu +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8723be +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8723bs +endif + +EXTRA_CFLAGS += -DCONFIG_RTL8723B + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8723BPwrSeq.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 \ + 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 \ + 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_PCI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8723B_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8723B_PCIE.o +endif + +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8723b_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8723b_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8723b_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8723b_fw.o\ + hal/phydm/$(RTL871X)/halhwimg8723b_mp.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8723b.o\ + hal/phydm/$(RTL871X)/halphyrf_8723b_ce.o\ + hal/phydm/$(RTL871X)/phydm_rtl8723b.o + +endif + +########### HAL_RTL8814A ################################# +ifeq ($(CONFIG_RTL8814A), y) +## ADD NEW VHT MP HW TX MODE ## +EXTRA_CFLAGS += -DCONFIG_MP_VHT_HW_TX_MODE +CONFIG_MP_VHT_HW_TX_MODE = y +########################################## +RTL871X = rtl8814a +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8814au +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8814ae +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8814as +endif + +EXTRA_CFLAGS += -DCONFIG_RTL8814A + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8814PwrSeq.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 \ + 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 \ + 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 +ifeq ($(CONFIG_GSPI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +endif +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8814A_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8814A_PCIE.o +endif + +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8814a_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8814a_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8814a_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8814a_fw.o\ + hal/phydm/$(RTL871X)/phydm_iqk_8814a.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8814a.o\ + hal/phydm/$(RTL871X)/halphyrf_8814a_ce.o\ + hal/phydm/$(RTL871X)/phydm_rtl8814a.o\ + hal/phydm/txbf/haltxbf8814a.o + +endif + +########### HAL_RTL8723C ################################# +ifeq ($(CONFIG_RTL8723C), y) + +RTL871X = rtl8703b +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8723cu +MODULE_SUB_NAME = 8703bu +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8723ce +MODULE_SUB_NAME = 8703be +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8723cs +MODULE_SUB_NAME = 8703bs +endif + +EXTRA_CFLAGS += -DCONFIG_RTL8703B + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8703BPwrSeq.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 \ + 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 \ + hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_SUB_NAME)_led.o \ + hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_SUB_NAME)_xmit.o \ + hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_SUB_NAME)_recv.o + +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8703B_USB.o +endif +ifeq ($(CONFIG_PCI_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8703B_PCIE.o +endif + +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8703b_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8703b_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8703b_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8703b_fw.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8703b.o\ + hal/phydm/$(RTL871X)/halphyrf_8703b.o +endif + +########### HAL_RTL8188F ################################# +ifeq ($(CONFIG_RTL8188F), y) + +RTL871X = rtl8188f +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME = 8188fu +endif +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME = 8188fe +endif +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME = 8189fs +endif + +EXTRA_CFLAGS += -DCONFIG_RTL8188F + +_HAL_INTFS_FILES += hal/HalPwrSeqCmd.o \ + hal/$(RTL871X)/Hal8188FPwrSeq.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 \ + 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 \ + 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_PCI_HCI), y) +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o +else +_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o +endif + +ifeq ($(CONFIG_USB_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8188F_USB.o +endif + +ifeq ($(CONFIG_SDIO_HCI), y) +_HAL_INTFS_FILES +=hal/efuse/$(RTL871X)/HalEfuseMask8188F_SDIO.o +endif + +_OUTSRC_FILES += hal/phydm/$(RTL871X)/halhwimg8188f_bb.o\ + hal/phydm/$(RTL871X)/halhwimg8188f_mac.o\ + hal/phydm/$(RTL871X)/halhwimg8188f_rf.o\ + hal/phydm/$(RTL871X)/halhwimg8188f_fw.o\ + hal/phydm/$(RTL871X)/phydm_regconfig8188f.o\ + hal/phydm/$(RTL871X)/halphyrf_8188f.o \ + hal/phydm/$(RTL871X)/phydm_rtl8188f.o + +endif + +########### AUTO_CFG ################################# + +ifeq ($(CONFIG_AUTOCFG_CP), 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) +$(shell cp $(TopDIR)/autoconf_rtl8189e_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) +else ifeq ($(CONFIG_RTL8188F)$(CONFIG_SDIO_HCI),yy) +$(shell cp $(TopDIR)/autoconf_rtl8189f_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) +else ifeq ($(CONFIG_RTL8723C),y) +$(shell cp $(TopDIR)/autoconf_rtl8723c_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) +else +$(shell cp $(TopDIR)/autoconf_$(RTL871X)_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h) +endif +endif + +endif + +########### END OF PATH ################################# + + +ifeq ($(CONFIG_USB_HCI), y) +ifeq ($(CONFIG_USB_AUTOSUSPEND), y) +EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND +endif +endif + +ifeq ($(CONFIG_MP_INCLUDED), y) +#MODULE_NAME := $(MODULE_NAME)_mp +EXTRA_CFLAGS += -DCONFIG_MP_INCLUDED +endif + +ifeq ($(CONFIG_POWER_SAVING), y) +EXTRA_CFLAGS += -DCONFIG_POWER_SAVING +endif + +ifeq ($(CONFIG_HW_PWRP_DETECTION), y) +EXTRA_CFLAGS += -DCONFIG_HW_PWRP_DETECTION +endif + +ifeq ($(CONFIG_WIFI_TEST), y) +EXTRA_CFLAGS += -DCONFIG_WIFI_TEST +endif + +ifeq ($(CONFIG_BT_COEXIST), y) +EXTRA_CFLAGS += -DCONFIG_BT_COEXIST +endif + +ifeq ($(CONFIG_INTEL_WIDI), y) +EXTRA_CFLAGS += -DCONFIG_INTEL_WIDI +endif + +ifeq ($(CONFIG_WAPI_SUPPORT), y) +EXTRA_CFLAGS += -DCONFIG_WAPI_SUPPORT +endif + + +ifeq ($(CONFIG_EFUSE_CONFIG_FILE), y) +EXTRA_CFLAGS += -DCONFIG_EFUSE_CONFIG_FILE + +#EFUSE_MAP_PATH +USER_EFUSE_MAP_PATH ?= +ifneq ($(USER_EFUSE_MAP_PATH),) +EXTRA_CFLAGS += -DEFUSE_MAP_PATH=\"$(USER_EFUSE_MAP_PATH)\" +else 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 + +#WIFIMAC_PATH +USER_WIFIMAC_PATH ?= +ifneq ($(USER_WIFIMAC_PATH),) +EXTRA_CFLAGS += -DWIFIMAC_PATH=\"$(USER_WIFIMAC_PATH)\" +else +EXTRA_CFLAGS += -DWIFIMAC_PATH=\"/data/wifimac.txt\" +endif + +endif + +ifeq ($(CONFIG_EXT_CLK), y) +EXTRA_CFLAGS += -DCONFIG_EXT_CLK +endif + +ifeq ($(CONFIG_TRAFFIC_PROTECT), y) +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +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) +EXTRA_CFLAGS += -DCONFIG_CALIBRATE_TX_POWER_BY_REGULATORY +endif + +ifeq ($(CONFIG_CALIBRATE_TX_POWER_TO_MAX), y) +EXTRA_CFLAGS += -DCONFIG_CALIBRATE_TX_POWER_TO_MAX +endif + +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 +endif + +ifeq ($(CONFIG_RTW_ADAPTIVITY_MODE), normal) +EXTRA_CFLAGS += -DCONFIG_RTW_ADAPTIVITY_MODE=0 +else ifeq ($(CONFIG_RTW_ADAPTIVITY_MODE), carrier_sense) +EXTRA_CFLAGS += -DCONFIG_RTW_ADAPTIVITY_MODE=1 +endif + +ifeq ($(CONFIG_SIGNAL_SCALE_MAPPING), y) +EXTRA_CFLAGS += -DCONFIG_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) +EXTRA_CFLAGS += -DCONFIG_RTW_SDIO_PM_KEEP_POWER +endif +endif + +ifeq ($(CONFIG_AP_WOWLAN), y) +EXTRA_CFLAGS += -DCONFIG_AP_WOWLAN +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DCONFIG_RTW_SDIO_PM_KEEP_POWER +endif +endif + +ifeq ($(CONFIG_PNO_SUPPORT), y) +EXTRA_CFLAGS += -DCONFIG_PNO_SUPPORT +ifeq ($(CONFIG_PNO_SET_DEBUG), y) +EXTRA_CFLAGS += -DCONFIG_PNO_SET_DEBUG +endif +endif + +ifeq ($(CONFIG_GPIO_WAKEUP), y) +EXTRA_CFLAGS += -DCONFIG_GPIO_WAKEUP +ifeq ($(CONFIG_HIGH_ACTIVE), y) +EXTRA_CFLAGS += -DHIGH_ACTIVE=1 +else +EXTRA_CFLAGS += -DHIGH_ACTIVE=0 +endif +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_TDLS), y) +EXTRA_CFLAGS += -DCONFIG_TDLS +endif + +ifeq ($(CONFIG_WIFI_MONITOR), y) +EXTRA_CFLAGS += -DCONFIG_WIFI_MONITOR +endif + +ifeq ($(CONFIG_MP_VHT_HW_TX_MODE), y) +EXTRA_CFLAGS += -DCONFIG_MP_VHT_HW_TX_MODE +ifeq ($(CONFIG_PLATFORM_I386_PC), y) +## For I386 X86 ToolChain use Hardware FLOATING +EXTRA_CFLAGS += -mhard-float +else +## For ARM ToolChain use Hardware FLOATING +EXTRA_CFLAGS += -mfloat-abi=hard +endif +endif + +EXTRA_CFLAGS += -DDM_ODM_SUPPORT_TYPE=0x04 + +ifeq ($(CONFIG_PLATFORM_I386_PC), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) +ARCH ?= $(SUBARCH) +CROSS_COMPILE ?= +KVER := $(shell uname -r) +KSRC := /lib/modules/$(KVER)/build +MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/ +INSTALL_PREFIX := +endif + +ifeq ($(CONFIG_PLATFORM_ACTIONS_ATM702X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ACTIONS_ATM702X +#ARCH := arm +ARCH := $(R_ARCH) +#CROSS_COMPILE := arm-none-linux-gnueabi- +CROSS_COMPILE := $(R_CROSS_COMPILE) +KVER:= 3.4.0 +#KSRC := ../../../../build/out/kernel +KSRC := $(KERNEL_BUILD_PATH) +MODULE_NAME :=wlan +endif + + +ifeq ($(CONFIG_PLATFORM_ACTIONS_ATM705X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +#EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +# default setting for Android 4.1, 4.2, 4.3, 4.4 +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ACTIONS_ATM705X +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT + +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK + +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +_PLATFORM_FILES += platform/platform_arm_act_sdio.o +endif + +ARCH := arm +CROSS_COMPILE := /opt/arm-2011.09/bin/arm-none-linux-gnueabi- +KSRC := /home/android_sdk/Action-semi/705a_android_L/android/kernel +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN50IW1P1), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN50IW1P1 +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_RESUME_IN_WORKQUEUE +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS + +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK + +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_SUN50IW1P1_sdio.o +endif + +ARCH := arm64 +# ===Cross compile setting for Android 5.1(64) SDK === +CROSS_COMPILE := /home/android_sdk/Allwinner/a64/android-51/lichee/out/sun50iw1p1/android/common/buildroot/external-toolchain/bin/aarch64-linux-gnu- +KSRC :=/home/android_sdk/Allwinner/a64/android-51/lichee/linux-3.10/ +endif + +ifeq ($(CONFIG_PLATFORM_TI_AM3517), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_SHUTTLE +CROSS_COMPILE := arm-eabi- +KSRC := $(shell pwd)/../../../Android/kernel +ARCH := arm +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR_TITANIA12), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_PLATFORM_MSTAR_TITANIA12 +ARCH:=mips +CROSS_COMPILE:= /usr/src/Mstar_kernel/mips-4.3/bin/mips-linux-gnu- +KVER:= 2.6.28.9 +KSRC:= /usr/src/Mstar_kernel/2.6.28.9/ +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR), y) +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_USE_USB_BUFFER_ALLOC_TX -DCONFIG_FIX_NR_BULKIN_BUFFER -DCONFIG_PREALLOC_RX_SKB_BUFFER +EXTRA_CFLAGS += -DCONFIG_PLATFORM_MSTAR_HIGH +ARCH:=arm +CROSS_COMPILE:= /usr/src/bin/arm-none-linux-gnueabi- +KVER:= 3.1.10 +KSRC:= /usr/src/Mstar_kernel/3.1.10/ +endif + +ifeq ($(CONFIG_PLATFORM_ANDROID_X86), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) +ARCH := $(SUBARCH) +CROSS_COMPILE := /media/DATA-2/android-x86/ics-x86_20120130/prebuilt/linux-x86/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu- +KSRC := /media/DATA-2/android-x86/ics-x86_20120130/out/target/product/generic_x86/obj/kernel +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_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 +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/) +ARCH := $(SUBARCH) +CROSS_COMPILE := /home/android_sdk/android-x86_JB/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7/bin/i686-linux-android- +KSRC := /home/android_sdk/android-x86_JB/out/target/product/x86/obj/kernel/ +MODULE_NAME :=wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_PXA2XX), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 2.6.34.1 +KSRC ?= /usr/src/linux-2.6.34.1 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-linux- +KVER := 2.6.24.7_$(ARCH) +KSRC := /usr/src/kernels/linux-$(KVER) +endif + +ifeq ($(CONFIG_PLATFORM_ARM_S3C6K4), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 2.6.34.1 +KSRC ?= /usr/src/linux-2.6.34.1 +endif + +ifeq ($(CONFIG_PLATFORM_RTD2880B), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN -DCONFIG_PLATFORM_RTD2880B +ARCH:= +CROSS_COMPILE:= +KVER:= +KSRC:= +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_RMI), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH:=mips +CROSS_COMPILE:=mipsisa32r2-uclibc- +KVER:= +KSRC:= /root/work/kernel_realtek +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_PLM), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN +ARCH:=mips +CROSS_COMPILE:=mipsisa32r2-uclibc- +KVER:= +KSRC:= /root/work/kernel_realtek +endif + +ifeq ($(CONFIG_PLATFORM_MSTAR389), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR389 +ARCH:=mips +CROSS_COMPILE:= mips-linux-gnu- +KVER:= 2.6.28.10 +KSRC:= /home/mstar/mstar_linux/2.6.28.9/ +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_AR9132), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN +ARCH := mips +CROSS_COMPILE := mips-openwrt-linux- +KSRC := /home/alex/test_openwrt/tmp/linux-2.6.30.9 +endif + +ifeq ($(CONFIG_PLATFORM_DMP_PHILIPS), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM +ARCH := mips +#CROSS_COMPILE:=/usr/local/msdk-4.3.6-mips-EL-2.6.12.6-0.9.30.3/bin/mipsel-linux- +CROSS_COMPILE:=/usr/local/toolchain_mipsel/bin/mipsel-linux- +KSRC ?=/usr/local/Jupiter/linux-2.6.12 +endif + +ifeq ($(CONFIG_PLATFORM_RTK_DMP), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM -DCONFIG_WIRELESS_EXT +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +ifeq ($(CONFIG_USB_HCI), y) +_PLATFORM_FILES += platform/platform_RTK_DMP_usb.o +endif +ARCH:=mips +CROSS_COMPILE:=mipsel-linux- +KVER:= +KSRC ?= /usr/src/DMP_Kernel/jupiter/linux-2.6.12 +endif + +ifeq ($(CONFIG_PLATFORM_MT53XX), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MT53XX +ARCH:= arm +CROSS_COMPILE:= arm11_mtk_le- +KVER:= 2.6.27 +KSRC?= /proj/mtk00802/BD_Compare/BDP/Dev/BDP_V301/BDP_Linux/linux-2.6.27 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_MX51_241H), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_WISTRON_PLATFORM +ARCH := arm +CROSS_COMPILE := /opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi- +KVER := 2.6.31 +KSRC ?= /lib/modules/2.6.31-770-g0e46b52/source +endif + +ifeq ($(CONFIG_PLATFORM_FS_MX61), y) +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 +endif + + + +ifeq ($(CONFIG_PLATFORM_ACTIONS_ATJ227X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ACTIONS_ATJ227X +ARCH := mips +CROSS_COMPILE := /home/cnsd4/project/actions/tools-2.6.27/bin/mipsel-linux-gnu- +KVER := 2.6.27 +KSRC := /home/cnsd4/project/actions/linux-2.6.27.28 +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 +CROSS_COMPILE := /opt/montavista/pro5.0/devkit/arm/v5t_le/bin/arm-linux- +KSRC:= /home/vivotek/lsp/DM365/kernel_platform/kernel/linux-2.6.18 +KERNELOUTPUT := ${PRODUCTDIR}/tmp +KVER := 2.6.18 +endif + +ifeq ($(CONFIG_PLATFORM_AML), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -fno-pic +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_P2P_IPS -DRTW_USE_CFG80211_STA_EVENT +#EXTRA_CFLAGS += -DCONFIG_LPS_SLOW_TRANSITION +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK +#ARCH := arm +ARCH := arm64 +#CROSS_COMPILE := arm-linux-gnueabihf- +CROSS_COMPILE := aarch64-linux-gnu- +KSRC := /mnt/nfsroot/rongjun.chen/android64/common + +endif + +ifeq ($(CONFIG_PLATFORM_MOZART), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MOZART +ARCH := arm +CROSS_COMPILE := /home/vivotek/lsp/mozart3v2/Mozart3e_Toolchain/build_arm_nofpu/usr/bin/arm-linux- +KVER := $(shell uname -r) +KSRC:= /opt/Vivotek/lsp/mozart3v2/kernel_platform/kernel/mozart_kernel-1.17 +KERNELOUTPUT := /home/pink/sample/ODM/IP8136W-VINT/tmp/kernel +endif + +ifeq ($(CONFIG_PLATFORM_TEGRA3_CARDHU), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +ARCH := arm +CROSS_COMPILE := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/out/target/product/cardhu/obj/KERNEL +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_TEGRA4_DALMORE), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +ARCH := arm +CROSS_COMPILE := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +KSRC := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/out/target/product/dalmore/obj/KERNEL +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8900), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/SDK_2304_20110613/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/SDK_2304_20110613/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8920), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8920_JB42), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/kernel +MODULE_NAME := wlan +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 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_RK3188), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS +# 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 +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 +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_RK3066), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_RK3066 +EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DRTW_SUPPORT_PLATFORM_SHUTDOWN +endif +EXTRA_CFLAGS += -fno-pic +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Rockchip/rk3066_20130607/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi- +#CROSS_COMPILE := /home/android_sdk/Rockchip/Rk3066sdk/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi- +KSRC := /home/android_sdk/Rockchip/Rk3066sdk/kernel +MODULE_NAME :=wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_URBETTER), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN #-DCONFIG_MINIMAL_MEMORY_USAGE +ARCH := arm +CROSS_COMPILE := /media/DATA-1/urbetter/arm-2009q3/bin/arm-none-linux-gnueabi- +KSRC := /media/DATA-1/urbetter/ics-urbetter/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TI_PANDA), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN #-DCONFIG_MINIMAL_MEMORY_USAGE +ARCH := arm +#CROSS_COMPILE := /media/DATA-1/aosp/ics-aosp_20111227/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +#KSRC := /media/DATA-1/aosp/android-omap-panda-3.0_20120104 +CROSS_COMPILE := /media/DATA-1/android-4.0/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- +KSRC := /media/DATA-1/android-4.0/panda_kernel/omap +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_PLATFORM_MIPS_JZ4760), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_MINIMAL_MEMORY_USAGE +ARCH ?= mips +CROSS_COMPILE ?= /mnt/sdb5/Ingenic/Umido/mips-4.3/bin/mips-linux-gnu- +KSRC ?= /mnt/sdb5/Ingenic/Umido/kernel +endif + +ifeq ($(CONFIG_PLATFORM_SZEBOOK), y) +EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN +ARCH:=arm +CROSS_COMPILE:=/opt/crosstool2/bin/armeb-unknown-linux-gnueabi- +KVER:= 2.6.31.6 +KSRC:= ../code/linux-2.6.31.6-2020/ +endif + +#Add setting for MN10300 +ifeq ($(CONFIG_PLATFORM_MN10300), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MN10300 +ARCH := mn10300 +CROSS_COMPILE := mn10300-linux- +KVER := 2.6.32.2 +KSRC := /home/winuser/work/Plat_sLD2T_V3010/usr/src/linux-2.6.32.2 +INSTALL_PREFIX := +endif + + +ifeq ($(CONFIG_PLATFORM_ARM_SUNxI), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUNxI +# 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_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) +# default setting for A10-EVB mmc0 +#EXTRA_CFLAGS += -DCONFIG_WITS_EVB_V13 +_PLATFORM_FILES += platform/platform_ARM_SUNxI_sdio.o +endif + +ARCH := arm +#CROSS_COMPILE := arm-none-linux-gnueabi- +CROSS_COMPILE=/home/android_sdk/Allwinner/a10/android-jb42/lichee-jb42/buildroot/output/external-toolchain/bin/arm-none-linux-gnueabi- +KVER := 3.0.8 +#KSRC:= ../lichee/linux-3.0/ +KSRC=/home/android_sdk/Allwinner/a10/android-jb42/lichee-jb42/linux-3.0 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN6I +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +# default setting for Android 4.1, 4.2, 4.3, 4.4 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +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) +# default setting for A31-EVB mmc0 +EXTRA_CFLAGS += -DCONFIG_A31_EVB +_PLATFORM_FILES += platform/platform_ARM_SUNnI_sdio.o +endif + +ARCH := arm +#Android-JB42 +#CROSS_COMPILE := /home/android_sdk/Allwinner/a31/android-jb42/lichee/buildroot/output/external-toolchain/bin/arm-linux-gnueabi- +#KSRC :=/home/android_sdk/Allwinner/a31/android-jb42/lichee/linux-3.3 +#ifeq ($(CONFIG_USB_HCI), y) +#MODULE_NAME := 8188eu_sw +#endif +# ==== Cross compile setting for kitkat-a3x_v4.5 ===== +CROSS_COMPILE := /home/android_sdk/Allwinner/a31/kitkat-a3x_v4.5/lichee/buildroot/output/external-toolchain/bin/arm-linux-gnueabi- +KSRC :=/home/android_sdk/Allwinner/a31/kitkat-a3x_v4.5/lichee/linux-3.3 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN7I), 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, 4.3, 4.4 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +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.2 SDK === +#CROSS_COMPILE := /home/android_sdk/Allwinner/a20_evb/lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +#KSRC := /home/android_sdk/Allwinner/a20_evb/lichee/linux-3.3 +# ==== Cross compile setting for Android 4.3 SDK ===== +#CROSS_COMPILE := /home/android_sdk/Allwinner/a20/android-jb43/lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +#KSRC := /home/android_sdk/Allwinner/a20/android-jb43/lichee/linux-3.4 +# ==== Cross compile setting for kitkat-a20_v4.4 ===== +CROSS_COMPILE := /home/android_sdk/Allwinner/a20/kitkat-a20_v4.4/lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +KSRC := /home/android_sdk/Allwinner/a20/kitkat-a20_v4.4/lichee/linux-3.4 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN8I), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN8I +EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT + +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.2 SDK === +#CROSS_COMPILE := /home/android_sdk/Allwinner/a23/android-jb42/lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +#KSRC :=/home/android_sdk/Allwinner/a23/android-jb42/lichee/linux-3.4 +# ===Cross compile setting for Android 4.4 SDK === +CROSS_COMPILE := /home/android_sdk/Allwinner/a23/android-kk44/lichee/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +KSRC :=/home/android_sdk/Allwinner/a23/android-kk44/lichee/linux-3.4 +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SUN8I_W5P1), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN8I +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN8I_W5P1 +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 + +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK + +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 L SDK === +CROSS_COMPILE := /home/android_sdk/Allwinner/a33/android-L/lichee/out/sun8iw5p1/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- +KSRC :=/home/android_sdk/Allwinner/a33/android-L/lichee/linux-3.4 +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) +KSRC:= $(CFGDIR)/../../kernel/linux-$(KERNEL_VER) +endif + +ifeq ($(CONFIG_PLATFORM_ARM_RTD299X), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DUSB_XMITBUF_ALIGN_SZ=1024 -DUSB_PACKET_OFFSET_SZ=0 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +ifeq ($(CONFIG_ANDROID), y) +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +# Enable this for Android 5.0 +EXTRA_CFLAGS += -DCONFIG_RADIO_WORK +endif +#ARCH, CROSS_COMPILE, KSRC,and MODDESTDIR are provided by external makefile +INSTALL_PREFIX := +endif + +ifeq ($(CONFIG_PLATFORM_HISILICON), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_HISILICON +ifeq ($(SUPPORT_CONCURRENT),y) +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +endif +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +ARCH := arm +ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE = arm-hisiv200-linux- +endif +MODULE_NAME := rtl8192eu +ifeq ($(KSRC),) + KSRC := ../../../../../../kernel/linux-3.4.y +endif +endif + +# Platform setting +ifeq ($(CONFIG_PLATFORM_ARM_SPREADTRUM_6820), y) +ifeq ($(CONFIG_ANDROID_2X), y) +EXTRA_CFLAGS += -DANDROID_2X +endif +EXTRA_CFLAGS += -DCONFIG_PLATFORM_SPRD +EXTRA_CFLAGS += -DPLATFORM_SPREADTRUM_6820 +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ifeq ($(RTL871X), rtl8188e) +EXTRA_CFLAGS += -DSOFTAP_PS_DURATION=50 +endif +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +_PLATFORM_FILES += platform/platform_sprd_sdio.o +endif +endif + +ifeq ($(CONFIG_PLATFORM_ARM_SPREADTRUM_8810), y) +ifeq ($(CONFIG_ANDROID_2X), y) +EXTRA_CFLAGS += -DANDROID_2X +endif +EXTRA_CFLAGS += -DCONFIG_PLATFORM_SPRD +EXTRA_CFLAGS += -DPLATFORM_SPREADTRUM_8810 +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +ifeq ($(RTL871X), rtl8188e) +EXTRA_CFLAGS += -DSOFTAP_PS_DURATION=50 +endif +ifeq ($(CONFIG_SDIO_HCI), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +_PLATFORM_FILES += platform/platform_sprd_sdio.o +endif +endif + +ifeq ($(CONFIG_PLATFORM_ARM_WMT), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS +ifeq ($(CONFIG_SDIO_HCI), y) +_PLATFORM_FILES += platform/platform_ARM_WMT_sdio.o +endif +ARCH := arm +CROSS_COMPILE := /home/android_sdk/WonderMedia/wm8880-android4.4/toolchain/arm_201103_gcc4.5.2/mybin/arm_1103_le- +KSRC := /home/android_sdk/WonderMedia/wm8880-android4.4/kernel4.4/ +MODULE_NAME :=8189es_kk +endif + +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_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_PLATFORM_NOVATEK_NT72668), y) +EXTRA_CFLAGS += -DCONFIG_PLATFORM_NOVATEK_NT72668 +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_RX +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +ARCH ?= arm +CROSS_COMPILE := arm-linux-gnueabihf- +KVER := 3.8.0 +KSRC := /Custom/Novatek/TCL/linux-3.8_header +#KSRC := $(KERNELDIR) +endif + +ifeq ($(CONFIG_PLATFORM_ARM_TCC8930_JB42), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +# default setting for Android 4.1, 4.2 +EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE +EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT +ARCH := arm +CROSS_COMPILE := /home/android_sdk/Telechips/v13.05_r1-tcc-android-4.2.2_tcc893x-evm_build/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- +KSRC := /home/android_sdk/Telechips/v13.05_r1-tcc-android-4.2.2_tcc893x-evm_build/kernel +MODULE_NAME := wlan +endif + +ifeq ($(CONFIG_MULTIDRV), y) + +ifeq ($(CONFIG_SDIO_HCI), y) +MODULE_NAME := rtw_sdio +endif + +ifeq ($(CONFIG_USB_HCI), y) +MODULE_NAME := rtw_usb +endif + +ifeq ($(CONFIG_PCI_HCI), y) +MODULE_NAME := rtw_pci +endif + + +endif + +USER_MODULE_NAME ?= +ifneq ($(USER_MODULE_NAME),) +MODULE_NAME := $(USER_MODULE_NAME) +endif + +ifneq ($(KERNELRELEASE),) + +rtk_core := core/rtw_cmd.o \ + core/rtw_security.o \ + core/rtw_debug.o \ + core/rtw_io.o \ + core/rtw_ioctl_query.o \ + core/rtw_ioctl_set.o \ + core/rtw_ieee80211.o \ + core/rtw_mlme.o \ + core/rtw_mlme_ext.o \ + core/rtw_wlan_util.o \ + core/rtw_vht.o \ + core/rtw_pwrctrl.o \ + core/rtw_rf.o \ + core/rtw_recv.o \ + core/rtw_sta_mgt.o \ + core/rtw_ap.o \ + core/rtw_xmit.o \ + core/rtw_p2p.o \ + core/rtw_tdls.o \ + core/rtw_br_ext.o \ + core/rtw_iol.o \ + core/rtw_sreset.o \ + core/rtw_btcoex.o \ + core/rtw_beamforming.o \ + core/rtw_odm.o \ + core/efuse/rtw_efuse.o + +$(MODULE_NAME)-y += $(rtk_core) + +$(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) +$(MODULE_NAME)-y += $(_PLATFORM_FILES) + +$(MODULE_NAME)-$(CONFIG_MP_INCLUDED) += core/rtw_mp.o \ + core/rtw_mp_ioctl.o + +ifeq ($(CONFIG_RTL8723B), y) +$(MODULE_NAME)-$(CONFIG_MP_INCLUDED)+= core/rtw_bt_mp.o +endif + +obj-m := $(MODULE_NAME).o + +else + +export CONFIG_RTL8189FS = m + +all: modules + +modules: + $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules + +strip: + $(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded + +install: + install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) + /sbin/depmod -a ${KVER} + +uninstall: + rm -f $(MODDESTDIR)/$(MODULE_NAME).ko + /sbin/depmod -a ${KVER} + +config_r: + @echo "make config" + /bin/bash script/Configure script/config.in + + +.PHONY: modules clean + +clean: + cd hal/phydm/ ; rm -fr */*.mod.c */*.mod */*.o */.*.cmd */*.ko + cd hal/phydm/ ; 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 + cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd core/efuse ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + cd platform ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko + rm -fr Module.symvers ; rm -fr Module.markers ; rm -fr modules.order + rm -fr *.mod.c *.mod *.o .*.cmd *.ko *~ + rm -fr .tmp_versions +endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/clean b/linux-3.4/drivers/net/wireless/rtl8189fs/clean new file mode 100644 index 00000000..87664218 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/clean @@ -0,0 +1,5 @@ +#!/bin/bash +rmmod 8192cu +rmmod 8192ce +rmmod 8192du +rmmod 8192de diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/efuse/rtw_efuse.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/efuse/rtw_efuse.c new file mode 100644 index 00000000..ace255f3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/efuse/rtw_efuse.c @@ -0,0 +1,1721 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_EFUSE_C_ + +#include +#include + +#include "../hal/efuse/efuse_mask.h" + +/*------------------------Define local variable------------------------------*/ +u8 fakeEfuseBank=0; +u32 fakeEfuseUsedBytes=0; +u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]={0}; +u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]={0}; +u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]={0}; + +u32 BTEfuseUsedBytes=0; +u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0}; +u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0}; + +u32 fakeBTEfuseUsedBytes=0; +u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0}; +u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0}; + +u8 maskfileBuffer[32]; +/*------------------------Define local variable------------------------------*/ + +//------------------------------------------------------------------------------ +#define REG_EFUSE_CTRL 0x0030 +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +//------------------------------------------------------------------------------ + +BOOLEAN +Efuse_Read1ByteFromFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u8 *Value ); +BOOLEAN +Efuse_Read1ByteFromFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u8 *Value ) +{ + if(Offset >= EFUSE_MAX_HW_SIZE) + { + return _FALSE; + } + //DbgPrint("Read fake content, offset = %d\n", Offset); + if(fakeEfuseBank == 0) + *Value = fakeEfuseContent[Offset]; + else + *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset]; + return _TRUE; +} + +BOOLEAN +Efuse_Write1ByteToFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value ); +BOOLEAN +Efuse_Write1ByteToFakeContent( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value ) +{ + if(Offset >= EFUSE_MAX_HW_SIZE) + { + return _FALSE; + } + if(fakeEfuseBank == 0) + fakeEfuseContent[Offset] = Value; + else + { + fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value; + } + return _TRUE; +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_PowerSwitch + * + * Overview: When we want to enable write operation, we should change to + * pwr on state. When we stop write, we should switch to 500k mode + * and disable LDO 2.5V. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/17/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +Efuse_PowerSwitch( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState); +} + +VOID +BTEfuse_PowerSwitch( + IN PADAPTER pAdapter, + IN u8 bWrite, + IN u8 PwrState) +{ + if(pAdapter->HalFunc.BTEfusePowerSwitch) + pAdapter->HalFunc.BTEfusePowerSwitch(pAdapter, bWrite, PwrState); +} + +/*----------------------------------------------------------------------------- + * Function: efuse_GetCurrentSize + * + * Overview: Get current efuse size!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u16 +Efuse_GetCurrentSize( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest) +{ + u16 ret=0; + + ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest); + + return ret; +} + +/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ +u8 +Efuse_CalculateWordCnts(IN u8 word_en) +{ + u8 word_cnts = 0; + if(!(word_en & BIT(0))) word_cnts++; // 0 : write enable + if(!(word_en & BIT(1))) word_cnts++; + if(!(word_en & BIT(2))) word_cnts++; + if(!(word_en & BIT(3))) word_cnts++; + return word_cnts; +} + +// +// Description: +// Execute E-Fuse read byte operation. +// Refered from SD1 Richard. +// +// Assumption: +// 1. Boot from E-Fuse and successfully auto-load. +// 2. PASSIVE_LEVEL (USB interface) +// +// Created by Roger, 2008.10.21. +// +VOID +ReadEFuseByte( + PADAPTER Adapter, + u16 _offset, + u8 *pbuf, + IN BOOLEAN bPseudoTest) +{ + u32 value32; + u8 readbyte; + u16 retry; + //u32 start=rtw_get_current_time(); + + if(bPseudoTest) + { + Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); + return; + } + if (IS_HARDWARE_TYPE_8723B(Adapter)) + { + // <20130121, Kordan> For SMIC S55 EFUSE specificatoin. + //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) + PHY_SetMacReg(Adapter, EFUSE_TEST, BIT11, 0); + } + //Write Address + rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff)); + readbyte = rtw_read8(Adapter, EFUSE_CTRL+2); + rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); + + //Write bit 32 0 + readbyte = rtw_read8(Adapter, EFUSE_CTRL+3); + rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f)); + + //Check bit 32 read-ready + retry = 0; + value32 = rtw_read32(Adapter, EFUSE_CTRL); + //while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) + while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) + { + value32 = rtw_read32(Adapter, EFUSE_CTRL); + retry++; + } + + // 20100205 Joseph: Add delay suggested by SD1 Victor. + // This fix the problem that Efuse read error in high temperature condition. + // Designer says that there shall be some delay after ready bit is set, or the + // result will always stay on last data we read. + rtw_udelay_os(50); + value32 = rtw_read32(Adapter, EFUSE_CTRL); + + *pbuf = (u8)(value32 & 0xff); + //DBG_871X("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start)); + +} + +// +// Description: +// 1. Execute E-Fuse read byte operation according as map offset and +// save to E-Fuse table. +// 2. Refered from SD1 Richard. +// +// Assumption: +// 1. Boot from E-Fuse and successfully auto-load. +// 2. PASSIVE_LEVEL (USB interface) +// +// Created by Roger, 2008.10.21. +// +// 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. +// 2. Add efuse utilization collect. +// 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 +// write addr must be after sec5. +// + +VOID +efuse_ReadEFuse( + PADAPTER Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ); +VOID +efuse_ReadEFuse( + PADAPTER Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + IN BOOLEAN bPseudoTest + ) +{ + Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); +} + +VOID +EFUSE_GetEfuseDefinition( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN u8 type, + OUT void *pOut, + IN BOOLEAN bPseudoTest + ) +{ + pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest); +} + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Read1Byte + * + * Overview: Copy from WMAC fot EFUSE read 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ +u8 +EFUSE_Read1Byte( + IN PADAPTER Adapter, + IN u16 Address) +{ + u8 data; + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k=0; + u16 contentLen=0; + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE); + + if (Address < contentLen) //E-fuse 512Byte + { + //Write E-fuse Register address bit0~7 + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + //Write E-fuse Register address bit8~9 + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + //Write 0x30[31]=0 + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp & 0x7F; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + //Wait Write-ready (0x30[31]=1) + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while(!(Bytetemp & 0x80)) + { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if(k==1000) + { + k=0; + break; + } + } + data=rtw_read8(Adapter, EFUSE_CTRL); + return data; + } + else + return 0xFF; + +}/* EFUSE_Read1Byte */ + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Write1Byte + * + * Overview: Copy from WMAC fot EFUSE write 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ + +void +EFUSE_Write1Byte( + IN PADAPTER Adapter, + IN u16 Address, + IN u8 Value); +void +EFUSE_Write1Byte( + IN PADAPTER Adapter, + IN u16 Address, + IN u8 Value) +{ + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k=0; + u16 contentLen=0; + + //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value)); + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE); + + if( Address < contentLen) //E-fuse 512Byte + { + rtw_write8(Adapter, EFUSE_CTRL, Value); + + //Write E-fuse Register address bit0~7 + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + + //Write E-fuse Register address bit8~9 + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + //Write 0x30[31]=1 + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp | 0x80; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + //Wait Write-ready (0x30[31]=0) + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while(Bytetemp & 0x80) + { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if(k==100) + { + k=0; + break; + } + } + } +}/* EFUSE_Write1Byte */ + + +/* 11/16/2008 MH Read one byte from real Efuse. */ +u8 +efuse_OneByteRead( + IN PADAPTER pAdapter, + IN u16 addr, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u32 tmpidx = 0; + u8 bResult; + u8 readbyte; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //DBG_871X("===> EFUSE_OneByteRead(), addr = %x\n", addr); + //DBG_871X("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); + + if(bPseudoTest) + { + bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data); + return bResult; + } + + if( IS_HARDWARE_TYPE_8723B(pAdapter) || + (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) || + (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID)) + ) + { + // <20130121, Kordan> For SMIC EFUSE specificatoin. + //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) + //PHY_SetMacReg(pAdapter, 0x34, BIT11, 0); + rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter,0x34)& (~BIT11) ); + } + + // -----------------e-fuse reg ctrl --------------------------------- + //address + rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff)); + rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) | + (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC )); + + //rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);//read cmd + //Write bit 32 0 + readbyte = rtw_read8(pAdapter, EFUSE_CTRL+3); + rtw_write8(pAdapter, EFUSE_CTRL+3, (readbyte & 0x7f)); + + while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3))&&(tmpidx<1000)) + { + rtw_mdelay_os(1); + tmpidx++; + } + if(tmpidx<100) + { + *data=rtw_read8(pAdapter, EFUSE_CTRL); + bResult = _TRUE; + } + else + { + *data = 0xff; + bResult = _FALSE; + DBG_871X("%s: [ERROR] addr=0x%x bResult=%d time out 1s !!!\n", __FUNCTION__, addr, bResult); + DBG_871X("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL)); + } + + return bResult; +} + +/* 11/16/2008 MH Write one byte to reald Efuse. */ +u8 +efuse_OneByteWrite( + IN PADAPTER pAdapter, + IN u16 addr, + IN u8 data, + IN BOOLEAN bPseudoTest) +{ + u8 tmpidx = 0; + u8 bResult=_FALSE; + u32 efuseValue = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //DBG_871X("===> EFUSE_OneByteWrite(), addr = %x data=%x\n", addr, data); + //DBG_871X("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); + + if(bPseudoTest) + { + bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data); + return bResult; + } + + + // -----------------e-fuse reg ctrl --------------------------------- + //address + + + efuseValue = rtw_read32(pAdapter, EFUSE_CTRL); + efuseValue |= (BIT21|BIT31); + efuseValue &= ~(0x3FFFF); + efuseValue |= ((addr<<8 | data) & 0x3FFFF); + + // <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. + if ( IS_HARDWARE_TYPE_8723B(pAdapter) || + (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) || + (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID)) + ) { + // <20130121, Kordan> For SMIC EFUSE specificatoin. + //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) + //PHY_SetMacReg(pAdapter, 0x34, BIT11, 1); + rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter,0x34)| (BIT11) ); + rtw_write32(pAdapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data)) ); + } + else + { + rtw_write32(pAdapter, EFUSE_CTRL, efuseValue); + } + + while((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100) ){ + rtw_mdelay_os(1); + tmpidx++; + } + + if(tmpidx<100) + { + bResult = _TRUE; + } + else + { + bResult = _FALSE; + DBG_871X("%s: [ERROR] addr=0x%x ,efuseValue=0x%x ,bResult=%d time out 1s !!! \n", + __FUNCTION__, addr, efuseValue, bResult); + DBG_871X("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL)); + } + + // disable Efuse program enable + if ( IS_HARDWARE_TYPE_8723B(pAdapter) || + (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) || + (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID)) + ) { + PHY_SetMacReg(pAdapter, EFUSE_TEST, BIT(11), 0); + } + + return bResult; +} + +int +Efuse_PgPacketRead( IN PADAPTER pAdapter, + IN u8 offset, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret=0; + + ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest); + + return ret; +} + +int +Efuse_PgPacketWrite(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret; + + ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest); + + return ret; +} + + +int +Efuse_PgPacketWrite_BT(IN PADAPTER pAdapter, + IN u8 offset, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + int ret; + + ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, bPseudoTest); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: efuse_WordEnableDataRead + * + * Overview: Read allowed word in current efuse section data. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * 11/21/2008 MHC Fix Write bug when we only enable late word. + * + *---------------------------------------------------------------------------*/ +void +efuse_WordEnableDataRead(IN u8 word_en, + IN u8 *sourdata, + IN u8 *targetdata) +{ + if (!(word_en&BIT(0))) + { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + if (!(word_en&BIT(1))) + { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + if (!(word_en&BIT(2))) + { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + if (!(word_en&BIT(3))) + { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + + +u8 +Efuse_WordEnableDataWrite( IN PADAPTER pAdapter, + IN u16 efuse_addr, + IN u8 word_en, + IN u8 *data, + IN BOOLEAN bPseudoTest) +{ + u8 ret=0; + + ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest); + + return ret; +} + +static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value) +{ + return efuse_OneByteRead(padapter,address, value, _FALSE); +} + +static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value) +{ + return efuse_OneByteWrite(padapter,address, *value, _FALSE); +} + +/* + * read/wirte raw efuse data + */ +u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data) +{ + int i = 0; + u16 real_content_len = 0, max_available_size = 0; + u8 res = _FAIL ; + u8 (*rw8)(PADAPTER, u16, u8*); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&real_content_len, _FALSE); + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if (start_addr > real_content_len) + return _FAIL; + + if (_TRUE == bWrite) { + if ((start_addr + cnts) > max_available_size) + return _FAIL; + rw8 = &efuse_write8; + } else + rw8 = &efuse_read8; + + Efuse_PowerSwitch(padapter, bWrite, _TRUE); + + // e-fuse one byte read / write + for (i = 0; i < cnts; i++) { + if (start_addr >= real_content_len) { + res = _FAIL; + break; + } + + res = rw8(padapter, start_addr++, data++); + if (_FAIL == res) break; + } + + Efuse_PowerSwitch(padapter, bWrite, _FALSE); + + return res; +} +//------------------------------------------------------------------------------ +u16 efuse_GetMaxSize(PADAPTER padapter) +{ + u16 max_size; + + max_size = 0; + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE); + return max_size; +} +//------------------------------------------------------------------------------ +u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size) +{ + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE); + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} +//------------------------------------------------------------------------------ +u16 efuse_bt_GetMaxSize(PADAPTER padapter) +{ + u16 max_size; + + max_size = 0; + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE); + return max_size; +} + +u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size) +{ + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + *size = Efuse_GetCurrentSize(padapter, EFUSE_BT, _FALSE); + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} + +u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + + efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE); + + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} + +u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + Efuse_PowerSwitch(padapter, _FALSE, _TRUE); + + efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, _FALSE); + + Efuse_PowerSwitch(padapter, _FALSE, _FALSE); + + return _SUCCESS; +} + +BOOLEAN rtw_file_efuse_IsMasked( + PADAPTER pAdapter, + u16 Offset + ) +{ + int r = Offset/16; + int c = (Offset%16) / 2; + int result = 0; + + if(pAdapter->registrypriv.boffefusemask) + return FALSE; + + //DBG_871X(" %s ,Offset=%x r= %d , c=%d , maskfileBuffer[r]= %x \n",__func__,Offset,r,c,maskfileBuffer[r]); + if (c < 4) // Upper double word + result = (maskfileBuffer[r] & (0x10 << c)); + else + result = (maskfileBuffer[r] & (0x01 << (c-4))); + + return (result > 0) ? 0 : 1; + +} + + +u8 rtw_efuse_file_read(PADAPTER padapter,u8 *filepatch,u8 *buf,u32 len) +{ + char *ptmp; + char *ptmpbuf=NULL; + u32 rtStatus; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + ptmpbuf = rtw_zmalloc(2048); + + if (ptmpbuf == NULL) + return _FALSE; + + _rtw_memset(ptmpbuf,'\0',2048); + + rtStatus = rtw_retrieve_from_file(filepatch, ptmpbuf, 2048); + + if( rtStatus > 100 ) + { + u32 i,j; + for(i=0,j=0;jregistrypriv.boffefusemask) + return FALSE; + +#if DEV_BUS_TYPE == RT_USB_INTERFACE +#if defined(CONFIG_RTL8188E) + if (IS_HARDWARE_TYPE_8188E(pAdapter)) + return (IS_MASKED(8188E,_MUSB,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8812A) + if (IS_HARDWARE_TYPE_8812(pAdapter)) + return (IS_MASKED(8812A,_MUSB,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8821A) + //if (IS_HARDWARE_TYPE_8811AU(pAdapter)) + // return (IS_MASKED(8811A,_MUSB,Offset)) ? TRUE : FALSE; + if (IS_HARDWARE_TYPE_8821(pAdapter)) + return (IS_MASKED(8821A,_MUSB,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8192E) + if (IS_HARDWARE_TYPE_8192E(pAdapter)) + return (IS_MASKED(8192E,_MUSB,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8723B) + if (IS_HARDWARE_TYPE_8723B(pAdapter)) + return (IS_MASKED(8723B,_MUSB,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8703B) + if (IS_HARDWARE_TYPE_8703B(pAdapter)) + return (IS_MASKED(8703B, _MUSB, Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8814A) + if (IS_HARDWARE_TYPE_8814A(pAdapter)) + return (IS_MASKED(8814A, _MUSB, Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8188F) + if (IS_HARDWARE_TYPE_8188F(pAdapter)) + return (IS_MASKED(8188F, _MUSB, Offset)) ? TRUE : FALSE; +#endif +#elif DEV_BUS_TYPE == RT_PCI_INTERFACE +#if defined(CONFIG_RTL8188E) + if (IS_HARDWARE_TYPE_8188E(pAdapter)) + return (IS_MASKED(8188E,_MPCIE,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8192E) + if (IS_HARDWARE_TYPE_8192E(pAdapter)) + return (IS_MASKED(8192E,_MPCIE,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8812A) + if (IS_HARDWARE_TYPE_8812(pAdapter)) + return (IS_MASKED(8812A,_MPCIE,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8821A) + if (IS_HARDWARE_TYPE_8821(pAdapter)) + return (IS_MASKED(8821A,_MPCIE,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8723B) + if (IS_HARDWARE_TYPE_8723B(pAdapter)) + return (IS_MASKED(8723B,_MPCIE,Offset)) ? TRUE : FALSE; +#endif +#if defined(CONFIG_RTL8814A) + if (IS_HARDWARE_TYPE_8814A(pAdapter)) + return (IS_MASKED(8814A, _MPCIE, Offset)) ? TRUE : FALSE; +#endif + //else if (IS_HARDWARE_TYPE_8821B(pAdapter)) + // return (IS_MASKED(8821B,_MPCIE,Offset)) ? TRUE : FALSE; + +#elif DEV_BUS_TYPE == RT_SDIO_INTERFACE +#ifdef CONFIG_RTL8188E_SDIO + if (IS_HARDWARE_TYPE_8188E(pAdapter)) + return (IS_MASKED(8188E,_MSDIO,Offset)) ? TRUE : FALSE; +#endif +#ifdef CONFIG_RTL8188F_SDIO + if (IS_HARDWARE_TYPE_8188F(pAdapter)) + return (IS_MASKED(8188F, _MSDIO, Offset)) ? TRUE : FALSE; +#endif +#endif + + return FALSE; +} + +//------------------------------------------------------------------------------ +u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ +#define RT_ASSERT_RET(expr) \ + if(!(expr)) { \ + printk( "Assertion failed! %s at ......\n", #expr); \ + printk( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ + return _FAIL; \ + } + + u8 offset, word_en; + u8 *map; + u8 newdata[PGPKT_DATA_SIZE]; + s32 i, j, idx; + u8 ret = _SUCCESS; + u16 mapLen=0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment + RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy + + map = rtw_zmalloc(mapLen); + if(map == NULL){ + return _FAIL; + } + + _rtw_memset(map, 0xFF, mapLen); + + ret = rtw_efuse_map_read(padapter, 0, mapLen, map); + if (ret == _FAIL) goto exit; + + if(padapter->registrypriv.boffefusemask==0) + { + for (i =0; i < cnts; i++) + { + if(padapter->registrypriv.bFileMaskEfuse==_TRUE) + { + if (rtw_file_efuse_IsMasked(padapter, addr+i)) /*use file efuse mask. */ + data[i] = map[addr+i]; + } + else + { + if ( efuse_IsMasked(padapter, addr+i )) + data[i] = map[addr+i]; + } + DBG_8192C("%s , data[%d] = %x, map[addr+i]= %x\n", __func__, i, data[i], map[addr+i]); + } + } + Efuse_PowerSwitch(padapter, _TRUE, _TRUE); + + idx = 0; + offset = (addr >> 3); + while (idx < cnts) + { + word_en = 0xF; + j = (addr + idx) & 0x7; + _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE); + for (i = j; i> 1); + newdata[i] = data[idx]; +#ifdef CONFIG_RTL8723B + if( addr + idx == 0x8) + { + if (IS_C_CUT(pHalData->VersionID) || IS_B_CUT(pHalData->VersionID)) + { + if(pHalData->adjuseVoltageVal == 6) + { + newdata[i] = map[addr + idx]; + DBG_8192C(" %s ,\n adjuseVoltageVal = %d ,newdata[%d] = %x \n",__func__,pHalData->adjuseVoltageVal,i,newdata[i]); + } + } + } +#endif + } + } + + if (word_en != 0xF) { + ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE); + DBG_871X("offset=%x \n",offset); + DBG_871X("word_en=%x \n",word_en); + + for(i=0;iregistrypriv.boffefusemask == 0) { + + for (i = 0; i < cnts; i++) { + if (padapter->registrypriv.bFileMaskEfuse == _TRUE) { + if (rtw_file_efuse_IsMasked(padapter, addr+i)) /*use file efuse mask.*/ + data[i] = 0xff; + } else { + /*DBG_8192C(" %s , data[%d] = %x\n", __func__, i, data[i]);*/ + if (efuse_IsMasked(padapter, addr+i)) { + data[i] = 0xff; + /*DBG_8192C(" %s ,mask data[%d] = %x\n", __func__, i, data[i]);*/ + } + } + } + + } + return ret; + +} + +u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +{ +#define RT_ASSERT_RET(expr) \ + if(!(expr)) { \ + printk( "Assertion failed! %s at ......\n", #expr); \ + printk( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ + return _FAIL; \ + } + + u8 offset, word_en; + u8 *map; + u8 newdata[PGPKT_DATA_SIZE]; + s32 i=0, j=0, idx; + u8 ret = _SUCCESS; + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + if ((addr + cnts) > mapLen) + return _FAIL; + + RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment + RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy + + map = rtw_zmalloc(mapLen); + if(map == NULL){ + return _FAIL; + } + + ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map); + if (ret == _FAIL) goto exit; + DBG_871X("OFFSET\tVALUE(hex)\n"); + for (i=0; i<1024; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF + { + DBG_871X("0x%03x\t", i); + for (j=0; j<8; j++) { + DBG_871X("%02X ", map[i+j]); + } + DBG_871X("\t"); + for (; j<16; j++) { + DBG_871X("%02X ", map[i+j]); + } + DBG_871X("\n"); + } + DBG_871X("\n"); + Efuse_PowerSwitch(padapter, _TRUE, _TRUE); + + idx = 0; + offset = (addr >> 3); + while (idx < cnts) + { + word_en = 0xF; + j = (addr + idx) & 0x7; + _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE); + for (i = j; i> 1); + newdata[i] = data[idx]; + } + } + + if (word_en != 0xF) { + DBG_871X("offset=%x \n",offset); + DBG_871X("word_en=%x \n",word_en); + DBG_871X("%s: data=", __FUNCTION__); + for(i=0;iefuse_eeprom_data[Offset]; + +} // EFUSE_ShadowRead1Byte + +//---------------Read Two Bytes +static VOID +efuse_ShadowRead2Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u16 *Value) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + *Value = pHalData->efuse_eeprom_data[Offset]; + *Value |= pHalData->efuse_eeprom_data[Offset+1]<<8; + +} // EFUSE_ShadowRead2Byte + +//---------------Read Four Bytes +static VOID +efuse_ShadowRead4Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN OUT u32 *Value) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + *Value = pHalData->efuse_eeprom_data[Offset]; + *Value |= pHalData->efuse_eeprom_data[Offset+1]<<8; + *Value |= pHalData->efuse_eeprom_data[Offset+2]<<16; + *Value |= pHalData->efuse_eeprom_data[Offset+3]<<24; + +} // efuse_ShadowRead4Byte + + +/*----------------------------------------------------------------------------- + * Function: efuse_ShadowWrite1Byte + * efuse_ShadowWrite2Byte + * efuse_ShadowWrite4Byte + * + * Overview: Write efuse modify map by one/two/four byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +#ifdef PLATFORM +static VOID +efuse_ShadowWrite1Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value); +#endif //PLATFORM +static VOID +efuse_ShadowWrite1Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u8 Value) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + pHalData->efuse_eeprom_data[Offset] = Value; + +} // efuse_ShadowWrite1Byte + +//---------------Write Two Bytes +static VOID +efuse_ShadowWrite2Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u16 Value) +{ + + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + + pHalData->efuse_eeprom_data[Offset] = Value&0x00FF; + pHalData->efuse_eeprom_data[Offset+1] = Value>>8; + +} // efuse_ShadowWrite1Byte + +//---------------Write Four Bytes +static VOID +efuse_ShadowWrite4Byte( + IN PADAPTER pAdapter, + IN u16 Offset, + IN u32 Value) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + pHalData->efuse_eeprom_data[Offset] = (u8)(Value&0x000000FF); + pHalData->efuse_eeprom_data[Offset+1] = (u8)((Value>>8)&0x0000FF); + pHalData->efuse_eeprom_data[Offset+2] = (u8)((Value>>16)&0x00FF); + pHalData->efuse_eeprom_data[Offset+3] = (u8)((Value>>24)&0xFF); + +} // efuse_ShadowWrite1Byte + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowMapUpdate + * + * Overview: Transfer current EFUSE content to shadow init and modify map. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/13/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void EFUSE_ShadowMapUpdate( + IN PADAPTER pAdapter, + IN u8 efuseType, + IN BOOLEAN bPseudoTest) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + u16 mapLen=0; + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest); + + if (pHalData->bautoload_fail_flag == _TRUE) + { + _rtw_memset(pHalData->efuse_eeprom_data, 0xFF, mapLen); + } + else + { + #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + if(_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data)) { + #endif + + Efuse_ReadAllMap(pAdapter, efuseType, pHalData->efuse_eeprom_data, bPseudoTest); + + #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data); + } + #endif + } + + //PlatformMoveMemory((PVOID)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], + //(PVOID)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); +}// EFUSE_ShadowMapUpdate + + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowRead + * + * Overview: Read from efuse init map !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +EFUSE_ShadowRead( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 *Value ) +{ + if (Type == 1) + efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); + else if (Type == 2) + efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); + else if (Type == 4) + efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); + +} // EFUSE_ShadowRead + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowWrite + * + * Overview: Write efuse modify map for later update operation to use!!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +EFUSE_ShadowWrite( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 Value); +VOID +EFUSE_ShadowWrite( + IN PADAPTER pAdapter, + IN u8 Type, + IN u16 Offset, + IN OUT u32 Value) +{ +#if (MP_DRIVER == 0) + return; +#endif + if ( pAdapter->registrypriv.mp_mode == 0) + return; + + + if (Type == 1) + efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value); + else if (Type == 2) + efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value); + else if (Type == 4) + efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value); + +} // EFUSE_ShadowWrite + +VOID +Efuse_InitSomeVar( + IN PADAPTER pAdapter + ); +VOID +Efuse_InitSomeVar( + IN PADAPTER pAdapter + ) +{ + u8 i; + + _rtw_memset((PVOID)&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE); + _rtw_memset((PVOID)&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN); + _rtw_memset((PVOID)&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN); + + for(i=0; i + + int isAdaptorInfoFileValid(void) +{ + return _TRUE; +} + +int storeAdaptorInfoFile(char *path, u8* efuse_data) +{ + int ret =_SUCCESS; + + if(path && efuse_data) { + ret = rtw_store_to_file(path, efuse_data, EEPROM_MAX_SIZE_512); + if(ret == EEPROM_MAX_SIZE) + ret = _SUCCESS; + else + ret = _FAIL; + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = _FAIL; + } + return ret; +} + +int retriveAdaptorInfoFile(char *path, u8* efuse_data) +{ + int ret = _SUCCESS; + mm_segment_t oldfs; + struct file *fp; + + if(path && efuse_data) { + + ret = rtw_retrieve_from_file(path, efuse_data, EEPROM_MAX_SIZE); + + if(ret == EEPROM_MAX_SIZE) + ret = _SUCCESS; + else + ret = _FAIL; + + #if 0 + if(isAdaptorInfoFileValid()) { + return 0; + } else { + return _FAIL; + } + #endif + + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = _FAIL; + } + return ret; +} +#endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */ + +#ifdef CONFIG_EFUSE_CONFIG_FILE +u32 rtw_read_efuse_from_file(const char *path, u8 *buf) +{ + u32 i; + u8 temp[3]; + u32 ret = _FAIL; + + struct file *fp; + mm_segment_t fs; + loff_t pos = 0; + + fp = filp_open(path, O_RDONLY, 0); + if (fp == NULL || IS_ERR(fp)) { + if (fp != NULL) + DBG_871X_LEVEL(_drv_always_, "%s open %s fail, err:%ld\n" + , __func__, path, PTR_ERR(fp)); + else + DBG_871X_LEVEL(_drv_always_, "%s open %s fail, fp is NULL\n" + , __func__, path); + + goto exit; + } + + temp[2] = 0; /* add end of string '\0' */ + + fs = get_fs(); + set_fs(KERNEL_DS); + + for (i = 0 ; i < HWSET_MAX_SIZE ; i++) { + vfs_read(fp, temp, 2, &pos); + if (sscanf(temp, "%hhx", &buf[i]) != 1) { + if (0) + DBG_871X_LEVEL(_drv_err_, "%s sscanf fail\n", __func__); + buf[i] = 0xFF; + } + if ((i % EFUSE_FILE_COLUMN_NUM) == (EFUSE_FILE_COLUMN_NUM - 1)) { + /* Filter the lates space char. */ + vfs_read(fp, temp, 1, &pos); + if (strchr(temp, ' ') == NULL) { + pos--; + vfs_read(fp, temp, 2, &pos); + } + } else { + pos += 1; /* Filter the space character */ + } + } + + set_fs(fs); + + DBG_871X_LEVEL(_drv_always_, "efuse file: %s\n", path); +#ifdef CONFIG_DEBUG + for (i = 0; i < HWSET_MAX_SIZE; i++) { + if (i % 16 == 0) + DBG_871X_SEL_NL(RTW_DBGDUMP, "0x%03x: ", i); + + DBG_871X_SEL(RTW_DBGDUMP, "%02X%s" + , buf[i] + , ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? " " : " ") + ); + } + DBG_871X_SEL(RTW_DBGDUMP, "\n"); +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +u32 rtw_read_macaddr_from_file(const char *path, u8 *buf) +{ + struct file *fp; + mm_segment_t fs; + loff_t pos = 0; + + u8 source_addr[18]; + u8 *head, *end; + int i; + u32 ret = _FAIL; + + _rtw_memset(source_addr, 0, 18); + + fp = filp_open(path, O_RDONLY, 0); + if (fp == NULL || IS_ERR(fp)) { + if (fp != NULL) + DBG_871X_LEVEL(_drv_always_, "%s open %s fail, err:%ld\n" + , __func__, path, PTR_ERR(fp)); + else + DBG_871X_LEVEL(_drv_always_, "%s open %s fail, fp is NULL\n" + , __func__, path); + + goto exit; + } + + fs = get_fs(); + set_fs(KERNEL_DS); + + vfs_read(fp, source_addr, 18, &pos); + source_addr[17] = ':'; + + head = end = source_addr; + for (i = 0; i < ETH_ALEN; i++) { + while (end && (*end != ':')) + end++; + + if (end && (*end == ':')) + *end = '\0'; + + if (sscanf(head, "%hhx", &buf[i]) != 1) { + if (0) + DBG_871X_LEVEL(_drv_err_, "%s sscanf fail\n", __func__); + buf[i] = 0xFF; + } + + if (end) { + end++; + head = end; + } + } + + set_fs(fs); + + DBG_871X_LEVEL(_drv_always_, "wifi_mac file: %s\n", path); +#ifdef CONFIG_DEBUG + DBG_871X(MAC_FMT"\n", MAC_ARG(buf)); +#endif + + ret = _SUCCESS; + +exit: + return ret; +} +#endif /* CONFIG_EFUSE_CONFIG_FILE */ + +#endif /* PLATFORM_LINUX */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ap.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ap.c new file mode 100644 index 00000000..abc0fab2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ap.c @@ -0,0 +1,4215 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_AP_C_ + +#include + + +#ifdef CONFIG_AP_MODE + +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WMM_OUI[]; +extern unsigned char WPS_OUI[]; +extern unsigned char P2P_OUI[]; +extern unsigned char WFD_OUI[]; + +void init_mlme_ap_info(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + + _rtw_spinlock_init(&pmlmepriv->bcn_update_lock); + + //for ACL + _rtw_init_queue(&pacl_list->acl_node_q); + + //pmlmeext->bstart_bss = _FALSE; + + start_ap_mode(padapter); +} + +void free_mlme_ap_info(_adapter *padapter) +{ + _irqL irqL; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //stop_ap_mode(padapter); + + pmlmepriv->update_bcn = _FALSE; + pmlmeext->bstart_bss = _FALSE; + + rtw_sta_flush(padapter, _TRUE); + + pmlmeinfo->state = _HW_STATE_NOLINK_; + + //free_assoc_sta_resources + rtw_free_all_stainfo(padapter); + + //free bc/mc sta_info + psta = rtw_get_bcmc_stainfo(padapter); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + + _rtw_spinlock_free(&pmlmepriv->bcn_update_lock); + +} + +static void update_BCNTIM(_adapter *padapter) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); + unsigned char *pie = pnetwork_mlmeext->IEs; + +/* + //DBG_871X("%s\n", __FUNCTION__); + + //update TIM IE + //if(pstapriv->tim_bitmap) +*/ + if (_TRUE) { + u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL; + u16 tim_bitmap_le; + uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen; + + tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap); + + p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_); + if (p != NULL && tim_ielen > 0) { + tim_ielen += 2; + + premainder_ie = p + tim_ielen; + + tim_ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen; + + /*append TIM IE from dst_ie offset*/ + dst_ie = p; + } else { + tim_ielen = 0; + + /*calculate head_len*/ + offset = _FIXED_IE_LENGTH_; + + /* get ssid_ie len */ + p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + offset += tmp_len+2; + + /*get supported rates len*/ + p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + { + offset += tmp_len+2; + } + + /*DS Parameter Set IE, len=3*/ + offset += 3; + + premainder_ie = pie + offset; + + remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen; + + /*append TIM IE from offset*/ + dst_ie = pie + offset; + + } + + if (remainder_ielen > 0) { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + *dst_ie++=_TIM_IE_; + + if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe)) + tim_ielen = 5; + else + tim_ielen = 4; + + *dst_ie++ = tim_ielen; + + *dst_ie++ = 0;/*DTIM count*/ + *dst_ie++ = 1;/*DTIM period*/ + + if (pstapriv->tim_bitmap & BIT(0))/*for bc/mc frames*/ + *dst_ie++ = BIT(0);/*bitmap ctrl */ + else + *dst_ie++ = 0; + + if (tim_ielen == 4) { + u8 pvb = 0; + + if (pstapriv->tim_bitmap & 0x00fe) + pvb = (u8)tim_bitmap_le; + else if (pstapriv->tim_bitmap & 0xff00) + pvb = (u8)(tim_bitmap_le >> 8); + else + pvb = (u8)tim_bitmap_le; + + *dst_ie++ = pvb; + + } else if (tim_ielen == 5) { + _rtw_memcpy(dst_ie, &tim_bitmap_le, 2); + dst_ie += 2; + } + + /*copy remainder IE*/ + if (pbackup_remainder_ie) { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork_mlmeext->IELength = offset + remainder_ielen; + + } +} + +void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 bmatch = _FALSE; + u8 *pie = pnetwork->IEs; + u8 *p=NULL, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; + u32 i, offset, ielen, ie_offset, remainder_ielen = 0; + + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); + + if (pIE->ElementID > index) + { + break; + } + else if(pIE->ElementID == index) // already exist the same IE + { + p = (u8 *)pIE; + ielen = pIE->Length; + bmatch = _TRUE; + break; + } + + p = (u8 *)pIE; + ielen = pIE->Length; + i += (pIE->Length + 2); + } + + if (p != NULL && ielen>0) + { + ielen += 2; + + premainder_ie = p+ielen; + + ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork->IELength - ie_offset - ielen; + + if(bmatch) + dst_ie = p; + else + dst_ie = (p+ielen); + } + + if(dst_ie == NULL) + return; + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + *dst_ie++=index; + *dst_ie++=len; + + _rtw_memcpy(dst_ie, data, len); + dst_ie+=len; + + //copy remainder IE + if(pbackup_remainder_ie) + { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork->IELength = offset + remainder_ielen; +} + +void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index) +{ + u8 *p, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; + uint offset, ielen, ie_offset, remainder_ielen = 0; + u8 *pie = pnetwork->IEs; + + p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_); + if (p != NULL && ielen>0) + { + ielen += 2; + + premainder_ie = p+ielen; + + ie_offset = (sint)(p -pie); + + remainder_ielen = pnetwork->IELength - ie_offset - ielen; + + dst_ie = p; + } + else { + return; + } + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie && premainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + //copy remainder IE + if(pbackup_remainder_ie) + { + _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + } + + offset = (uint)(dst_ie - pie); + pnetwork->IELength = offset + remainder_ielen; +} + + +u8 chk_sta_is_alive(struct sta_info *psta); +u8 chk_sta_is_alive(struct sta_info *psta) +{ + u8 ret = _FALSE; + #ifdef DBG_EXPIRATION_CHK + DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n" + , MAC_ARG(psta->hwaddr) + , psta->rssi_stat.UndecoratedSmoothedPWDB + //, STA_RX_PKTS_ARG(psta) + , STA_RX_PKTS_DIFF_ARG(psta) + , psta->expire_to + , psta->state&WIFI_SLEEP_STATE?"PS, ":"" + , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":"" + , psta->sleepq_len + ); + #endif + + //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta)) + if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts)) + { + #if 0 + if(psta->state&WIFI_SLEEP_STATE) + ret = _TRUE; + #endif + } + else + { + ret = _TRUE; + } + + sta_update_last_rx_pkts(psta); + + return ret; +} + +void expire_timeout_chk(_adapter *padapter) +{ + _irqL irqL; + _list *phead, *plist; + u8 updated = _FALSE; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + int i; + + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + + phead = &pstapriv->auth_list; + plist = get_next(phead); + + //check auth_queue + #ifdef DBG_EXPIRATION_CHK + if (rtw_end_of_queue_search(phead, plist) == _FALSE) { + DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt); + } + #endif + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, auth_list); + + plist = get_next(plist); + + +#ifdef CONFIG_ATMEL_RC_PATCH + if (_TRUE == _rtw_memcmp((void *)(pstapriv->atmel_rc_pattern), (void *)(psta->hwaddr), ETH_ALEN)) + continue; + if (psta->flag_atmel_rc) + continue; +#endif + if(psta->expire_to>0) + { + psta->expire_to--; + if (psta->expire_to == 0) + { + rtw_list_delete(&psta->auth_list); + pstapriv->auth_list_cnt--; + + DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n", + psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]); + + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + } + } + + } + + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + psta = NULL; + + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + #ifdef DBG_EXPIRATION_CHK + if (rtw_end_of_queue_search(phead, plist) == _FALSE) { + DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt); + } + #endif + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); +#ifdef CONFIG_ATMEL_RC_PATCH + DBG_871X("%s:%d psta=%p, %02x,%02x||%02x,%02x \n\n", __func__, __LINE__, + psta,pstapriv->atmel_rc_pattern[0], pstapriv->atmel_rc_pattern[5], psta->hwaddr[0], psta->hwaddr[5]); + if (_TRUE == _rtw_memcmp((void *)pstapriv->atmel_rc_pattern, (void *)(psta->hwaddr), ETH_ALEN)) + continue; + if (psta->flag_atmel_rc) + continue; + DBG_871X("%s: debug line:%d \n", __func__, __LINE__); +#endif +#ifdef CONFIG_AUTO_AP_MODE + if(psta->isrc) + continue; +#endif + if (chk_sta_is_alive(psta) || !psta->expire_to) { + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; + #ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; + #endif // CONFIG_TX_MCAST2UNI + } else { + psta->expire_to--; + } + +#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_80211N_HT +#ifdef CONFIG_TX_MCAST2UNI + if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) { + // check sta by delba(addba) for 11n STA + // ToDo: use CCX report to check for all STAs + //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking); + + if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) { + DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2); + psta->under_exist_checking = 0; + psta->expire_to = 0; + } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) { + DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2); + psta->under_exist_checking = 1; + //tear down TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + } + } +#endif //CONFIG_TX_MCAST2UNI +#endif //CONFIG_80211N_HT +#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK + + if (psta->expire_to <= 0) + { + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (padapter->registrypriv.wifi_spec == 1) + { + psta->expire_to = pstapriv->expire_to; + continue; + } + +#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_80211N_HT + +#define KEEP_ALIVE_TRYCNT (3) + + if(psta->keep_alive_trycnt > 0 && psta->keep_alive_trycnt <= KEEP_ALIVE_TRYCNT) + { + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + else + psta->keep_alive_trycnt = 0; + + } + else if((psta->keep_alive_trycnt > KEEP_ALIVE_TRYCNT) && !(psta->state & WIFI_STA_ALIVE_CHK_STATE)) + { + psta->keep_alive_trycnt = 0; + } + if((psta->htpriv.ht_option==_TRUE) && (psta->htpriv.ampdu_enable==_TRUE)) + { + uint priority = 1; //test using BK + u8 issued=0; + + //issued = (psta->htpriv.agg_enable_bitmap>>priority)&0x1; + issued |= (psta->htpriv.candidate_tid_bitmap>>priority)&0x1; + + if(0==issued) + { + if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) + { + psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); + + if (psta->state & WIFI_SLEEP_STATE) + psta->expire_to = 2; // 2x2=4 sec + else + psta->expire_to = 1; // 2 sec + + psta->state |= WIFI_STA_ALIVE_CHK_STATE; + + //add_ba_hdl(padapter, (u8*)paddbareq_parm); + + DBG_871X("issue addba_req to check if sta alive, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt); + + issue_addba_req(padapter, psta->hwaddr, (u8)priority); + + _set_timer(&psta->addba_retry_timer, ADDBA_TO); + + psta->keep_alive_trycnt++; + + continue; + } + } + } + if(psta->keep_alive_trycnt > 0 && psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + psta->keep_alive_trycnt = 0; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + DBG_871X("change to another methods to check alive if staion is at ps mode\n"); + } + +#endif //CONFIG_80211N_HT +#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK + if (psta->state & WIFI_SLEEP_STATE) { + if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) { + //to check if alive by another methods if staion is at ps mode. + psta->expire_to = pstapriv->expire_to; + psta->state |= WIFI_STA_ALIVE_CHK_STATE; + + //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr)); + + //to update bcn with tim_bitmap for this station + pstapriv->tim_bitmap |= BIT(psta->aid); + update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + + if(!pmlmeext->active_keep_alive_check) + continue; + } + } + #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + if (pmlmeext->active_keep_alive_check) { + int stainfo_offset; + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + + continue; + } + #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); + updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _TRUE); + } + else + { + /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */ + if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt) + && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2) + ){ + DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__ + , MAC_ARG(psta->hwaddr) + , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt); + wakeup_sta_to_xmit(padapter, psta); + } + } + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +if (chk_alive_num) { + + u8 backup_oper_channel=0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + /* switch to correct channel of current network before issue keep-alive frames */ + if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { + backup_oper_channel = rtw_get_oper_ch(padapter); + SelectChannel(padapter, pmlmeext->cur_channel); + } + + /* issue null data to check sta alive*/ + for (i = 0; i < chk_alive_num; i++) { + int ret = _FAIL; + + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); +#ifdef CONFIG_ATMEL_RC_PATCH + if (_TRUE == _rtw_memcmp( pstapriv->atmel_rc_pattern, psta->hwaddr, ETH_ALEN)) + continue; + if (psta->flag_atmel_rc) + continue; +#endif + if(!(psta->state &_FW_LINKED)) + continue; + + if (psta->state & WIFI_SLEEP_STATE) + ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); + else + ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); + + psta->keep_alive_trycnt++; + if (ret == _SUCCESS) + { + DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr)); + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; + continue; + } + else if (psta->keep_alive_trycnt <= 3) + { + DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt); + psta->expire_to = 1; + continue; + } + + psta->keep_alive_trycnt = 0; + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING, _TRUE); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + + if (backup_oper_channel>0) /* back to the original operation channel */ + SelectChannel(padapter, backup_oper_channel); +} +#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); +} + +void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level) +{ + int i; + u8 rf_type; + unsigned char sta_band = 0, shortGIrate = _FALSE; + u64 tx_ra_bitmap = 0; + struct ht_priv *psta_ht = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + +#ifdef CONFIG_80211N_HT + if(psta) + psta_ht = &psta->htpriv; + else + return; +#endif //CONFIG_80211N_HT + + if(!(psta->state & _FW_LINKED)) + return; + +#if 0//gtest + if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R) + { + //is this a 2r STA? + if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid))) + { + priv->pshare->has_2r_sta |= BIT(pstat->aid); + if(rtw_read16(padapter, 0x102501f6) != 0xffff) + { + rtw_write16(padapter, 0x102501f6, 0xffff); + reset_1r_sta_RA(priv, 0xffff); + Switch_1SS_Antenna(priv, 3); + } + } + else// bg or 1R STA? + { + if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0) + { + if(rtw_read16(padapter, 0x102501f6) != 0x7777) + { // MCS7 SGI + rtw_write16(padapter, 0x102501f6,0x7777); + reset_1r_sta_RA(priv, 0x7777); + Switch_1SS_Antenna(priv, 2); + } + } + } + + } + + if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3)) + { + if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper) + pstat->rssi_level = 1; + else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) || + ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) && + (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) && + (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_)))) + pstat->rssi_level = 2; + else + pstat->rssi_level = 3; + } + + // rate adaptive by rssi + if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len) + { + if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R)) + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x100f0000; + break; + case 2: + pstat->tx_ra_bitmap &= 0x100ff000; + break; + case 3: + if (priv->pshare->is_40m_bw) + pstat->tx_ra_bitmap &= 0x100ff005; + else + pstat->tx_ra_bitmap &= 0x100ff001; + + break; + } + } + else + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x1f0f0000; + break; + case 2: + pstat->tx_ra_bitmap &= 0x1f0ff000; + break; + case 3: + if (priv->pshare->is_40m_bw) + pstat->tx_ra_bitmap &= 0x000ff005; + else + pstat->tx_ra_bitmap &= 0x000ff001; + + break; + } + + // Don't need to mask high rates due to new rate adaptive parameters + //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta + // pstat->tx_ra_bitmap &= 0x81ffffff; + + // NIC driver will report not supporting MCS15 and MCS14 in asoc req + //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta) + // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14 + } + } + else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat)) + { + switch (pstat->rssi_level) { + case 1: + pstat->tx_ra_bitmap &= 0x00000f00; + break; + case 2: + pstat->tx_ra_bitmap &= 0x00000ff0; + break; + case 3: + pstat->tx_ra_bitmap &= 0x00000ff5; + break; + } + } + else + { + pstat->tx_ra_bitmap &= 0x0000000d; + } + + // disable tx short GI when station cannot rx MCS15(AP is 2T2R) + // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R) + // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate + if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) || + (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R))) + { + pstat->tx_ra_bitmap &= ~BIT(28); + } +#endif + + rtw_hal_update_sta_rate_mask(padapter, psta); + tx_ra_bitmap = psta->ra_mask; + + shortGIrate = query_ra_short_GI(psta); + + if ( pcur_network->Configuration.DSConfig > 14 ) { + + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_5N ; + + if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11A; + + // 5G band + #ifdef CONFIG_80211AC_VHT + if (psta->vhtpriv.vht_option) { + sta_band = WIRELESS_11_5AC; + } + #endif + + } else { + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_24N; + + if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11G; + + if (tx_ra_bitmap & 0x0f) + sta_band |= WIRELESS_11B; + } + + psta->wireless_mode = sta_band; + psta->raid = rtw_hal_networktype_to_raid(padapter, psta); + + if (psta->aid < NUM_STA) + { + u8 arg[4] = {0}; + + arg[0] = psta->mac_id; + arg[1] = psta->raid; + arg[2] = shortGIrate; + arg[3] = psta->init_rate; + + DBG_871X("%s=> mac_id:%d , raid:%d , shortGIrate=%d, tx_ra_bitmap:0x%016llx, networkType:0x%02x\n", + __FUNCTION__, psta->mac_id, psta->raid, shortGIrate, tx_ra_bitmap, psta->wireless_mode); + + rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level); + } + else + { + DBG_871X("station aid %d exceed the max number\n", psta->aid); + } + +} + +void update_bmc_sta(_adapter *padapter) +{ + _irqL irqL; + unsigned char network_type; + int supportRateNum = 0; + u64 tx_ra_bitmap = 0; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct sta_info *psta = rtw_get_bcmc_stainfo(padapter); + + if(psta) + { + psta->aid = 0;//default set to 0 + psta->qos_option = 0; +#ifdef CONFIG_80211N_HT + psta->htpriv.ht_option = _FALSE; +#endif //CONFIG_80211N_HT + + psta->ieee8021x_blocked = 0; + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this. + + //prepare for add_RATid + supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates); + network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, pcur_network->Configuration.DSConfig); + if (IsSupportedTxCCK(network_type)) { + network_type = WIRELESS_11B; + } + else if (network_type == WIRELESS_INVALID) { // error handling + if ( pcur_network->Configuration.DSConfig > 14 ) + network_type = WIRELESS_11A; + else + network_type = WIRELESS_11B; + } + update_sta_basic_rate(psta, network_type); + psta->wireless_mode = network_type; + + rtw_hal_update_sta_rate_mask(padapter, psta); + tx_ra_bitmap = psta->ra_mask; + + psta->raid = rtw_hal_networktype_to_raid(padapter,psta); + + //ap mode + rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE); + + //if(pHalData->fw_ractrl == _TRUE) + { + u8 arg[4] = {0}; + + arg[0] = psta->mac_id; + arg[1] = psta->raid; + arg[2] = 0; + arg[3] = psta->init_rate; + + DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%016llx\n", + __FUNCTION__ , psta->mac_id, psta->raid , tx_ra_bitmap); + + rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0); + } + + rtw_sta_media_status_rpt(padapter, psta, 1); + + _enter_critical_bh(&psta->lock, &irqL); + psta->state = _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + } + else + { + DBG_871X("add_RATid_bmc_sta error!\n"); + } + +} + +//notes: +//AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode +//MAC_ID = AID+1 for sta in ap/adhoc mode +//MAC_ID = 1 for bc/mc for sta/ap/adhoc +//MAC_ID = 0 for bssid for sta/ap/adhoc +//CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1; + +void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; + struct ht_priv *phtpriv_sta = &psta->htpriv; +#endif //CONFIG_80211N_HT + u8 cur_ldpc_cap=0, cur_stbc_cap=0, cur_beamform_cap=0; + //set intf_tag to if1 + //psta->intf_tag = 0; + + DBG_871X("%s\n",__FUNCTION__); + + //psta->mac_id = psta->aid+4; + //psta->mac_id = psta->aid+1;//alloc macid when call rtw_alloc_stainfo(), + //release macid when call rtw_free_stainfo() + + //ap mode + rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE); + + if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X) + psta->ieee8021x_blocked = _TRUE; + else + psta->ieee8021x_blocked = _FALSE; + + + //update sta's cap + + //ERP + VCS_update(padapter, psta); +#ifdef CONFIG_80211N_HT + //HT related cap + if(phtpriv_sta->ht_option) + { + //check if sta supports rx ampdu + phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable; + + phtpriv_sta->rx_ampdu_min_spacing = (phtpriv_sta->ht_cap.ampdu_params_info&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2; + + // bwmode + if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) + { + psta->bw_mode = CHANNEL_WIDTH_40; + } + else + { + psta->bw_mode = CHANNEL_WIDTH_20; + } + + if (psta->ht_40mhz_intolerant) + psta->bw_mode = CHANNEL_WIDTH_20; + + if(pmlmeext->cur_bwmode < psta->bw_mode) + { + psta->bw_mode = pmlmeext->cur_bwmode; + } + + phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; + + + //check if sta support s Short GI 20M + if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) + { + phtpriv_sta->sgi_20m = _TRUE; + } + + //check if sta support s Short GI 40M + if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) + { + if(psta->bw_mode == CHANNEL_WIDTH_40) //according to psta->bw_mode + phtpriv_sta->sgi_40m = _TRUE; + else + phtpriv_sta->sgi_40m = _FALSE; + } + + psta->qos_option = _TRUE; + + // B0 Config LDPC Coding Capability + if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) && + 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); + } + + // B7 B8 B9 Config STBC setting + if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) && + 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); + } + +#ifdef CONFIG_BEAMFORMING + /*Config Tx beamforming setting*/ + if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP((u8 *)(&phtpriv_sta->ht_cap))) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); + /*Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 6); + } + + if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP((u8 *)(&phtpriv_sta->ht_cap))) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + /*Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS((u8 *)(&phtpriv_sta->ht_cap)) << 4); + } + if (cur_beamform_cap) { + DBG_871X("Client STA(%d) HT Beamforming Cap = 0x%02X\n", psta->aid, cur_beamform_cap); + } +#endif /*CONFIG_BEAMFORMING*/ + } + else + { + phtpriv_sta->ampdu_enable = _FALSE; + + phtpriv_sta->sgi_20m = _FALSE; + phtpriv_sta->sgi_40m = _FALSE; + psta->bw_mode = CHANNEL_WIDTH_20; + phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + phtpriv_sta->ldpc_cap = cur_ldpc_cap; + phtpriv_sta->stbc_cap = cur_stbc_cap; + phtpriv_sta->beamform_cap = cur_beamform_cap; + + //Rx AMPDU + send_delba(padapter, 0, psta->hwaddr);// recipient + + //TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + phtpriv_sta->agg_enable_bitmap = 0x0;//reset + phtpriv_sta->candidate_tid_bitmap = 0x0;//reset +#endif //CONFIG_80211N_HT + +#ifdef CONFIG_80211AC_VHT + update_sta_vht_info_apmode(padapter, psta); +#endif + + update_ldpc_stbc_cap(psta); + + //todo: init other variables + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + + //add ratid + //add_RATid(padapter, psta);//move to ap_sta_info_defer_update() + + + _enter_critical_bh(&psta->lock, &irqL); + psta->state |= _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + +} + +static void update_ap_info(_adapter *padapter, struct sta_info *psta) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; +#endif //CONFIG_80211N_HT + + psta->wireless_mode = pmlmeext->cur_wireless_mode; + + psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates); + _rtw_memcpy(psta->bssrateset, pnetwork->SupportedRates, psta->bssratelen); + +#ifdef CONFIG_80211N_HT + //HT related cap + if(phtpriv_ap->ht_option) + { + //check if sta supports rx ampdu + //phtpriv_ap->ampdu_enable = phtpriv_ap->ampdu_enable; + + //check if sta support s Short GI 20M + if((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) + { + phtpriv_ap->sgi_20m = _TRUE; + } + //check if sta support s Short GI 40M + if((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) + { + phtpriv_ap->sgi_40m = _TRUE; + } + + psta->qos_option = _TRUE; + } + else + { + phtpriv_ap->ampdu_enable = _FALSE; + + phtpriv_ap->sgi_20m = _FALSE; + phtpriv_ap->sgi_40m = _FALSE; + } + + psta->bw_mode = pmlmeext->cur_bwmode; + phtpriv_ap->ch_offset = pmlmeext->cur_ch_offset; + + phtpriv_ap->agg_enable_bitmap = 0x0;//reset + phtpriv_ap->candidate_tid_bitmap = 0x0;//reset + + _rtw_memcpy(&psta->htpriv, &pmlmepriv->htpriv, sizeof(struct ht_priv)); + +#ifdef CONFIG_80211AC_VHT + _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv)); +#endif //CONFIG_80211AC_VHT + +#endif //CONFIG_80211N_HT + + psta->state |= WIFI_AP_STATE; /* Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724 */ +} + +static void rtw_set_hw_wmm_param(_adapter *padapter) +{ + u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; + u8 acm_mask; + u16 TXOP; + u32 acParm, i; + u32 edca[4], inx[4]; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + + acm_mask = 0; + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || + (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) + aSifsTime = 16; + else + aSifsTime = 10; + + if (pmlmeinfo->WMM_enable == 0) { + padapter->mlmepriv.acm_mask = 0; + + AIFS = aSifsTime + (2 * pmlmeinfo->slotTime); + + if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) { + ECWMin = 4; + ECWMax = 10; + } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) { + ECWMin = 5; + ECWMax = 10; + } else { + ECWMin = 4; + ECWMax = 10; + } + + TXOP = 0; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); + + ECWMin = 2; + ECWMax = 3; + TXOP = 0x2f; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); + + } else { + edca[0] = edca[1] = edca[2] = edca[3] = 0; + + /*TODO:*/ + acm_mask = 0; + padapter->mlmepriv.acm_mask = acm_mask; + + /* + //BK + //AIFS = AIFSN * slot time + SIFS - r2t phy delay + */ + AIFS = (7 * pmlmeinfo->slotTime) + aSifsTime; + ECWMin = 4; + ECWMax = 10; + TXOP = 0; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); + edca[XMIT_BK_QUEUE] = acParm; + DBG_871X("WMM(BK): %x\n", acParm); + + /* BE */ + AIFS = (3 * pmlmeinfo->slotTime) + aSifsTime; + ECWMin = 4; + ECWMax = 6; + TXOP = 0; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); + edca[XMIT_BE_QUEUE] = acParm; + DBG_871X("WMM(BE): %x\n", acParm); + + /* VI */ + AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime; + ECWMin = 3; + ECWMax = 4; + TXOP = 94; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); + edca[XMIT_VI_QUEUE] = acParm; + DBG_871X("WMM(VI): %x\n", acParm); + + /* VO */ + AIFS = (1 * pmlmeinfo->slotTime) + aSifsTime; + ECWMin = 2; + ECWMax = 3; + TXOP = 47; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); + edca[XMIT_VO_QUEUE] = acParm; + DBG_871X("WMM(VO): %x\n", acParm); + + + if (padapter->registrypriv.acm_method == 1) + rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask)); + else + padapter->mlmepriv.acm_mask = acm_mask; + + inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; + + if (pregpriv->wifi_spec == 1) { + u32 j, tmp, change_inx = _FALSE; + + /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */ + for (i = 0 ; i < 4 ; i++) { + for (j = i+1 ; j < 4 ; j++) { + /* compare CW and AIFS */ + if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) { + change_inx = _TRUE; + } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) { + /* compare TXOP */ + if ((edca[j] >> 16) > (edca[i] >> 16)) + change_inx = _TRUE; + } + + if (change_inx) { + tmp = edca[i]; + edca[i] = edca[j]; + edca[j] = tmp; + + tmp = inx[i]; + inx[i] = inx[j]; + inx[j] = tmp; + + change_inx = _FALSE; + } + } + } + } + + for (i = 0 ; i < 4 ; i++) { + pxmitpriv->wmm_para_seq[i] = inx[i]; + DBG_871X("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); + } + + } + +} + +static void update_hw_ht_param(_adapter *padapter) +{ + unsigned char max_AMPDU_len; + unsigned char min_MPDU_spacing; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X("%s\n", __FUNCTION__); + + + //handle A-MPDU parameter field + /* + AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + AMPDU_para [4:2]:Min MPDU Start Spacing + */ + max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); + + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; + +} + +static void rtw_ap_check_scan(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + u32 delta_time, lifetime; + struct wlan_network *pnetwork = NULL; + WLAN_BSSID_EX *pbss = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + u8 do_scan = _FALSE; + + lifetime = SCANQUEUE_LIFETIME; /* 20 sec */ + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + if (rtw_end_of_queue_search(phead, get_next(phead)) == _TRUE) + if (padapter->registrypriv.wifi_spec) + do_scan = _TRUE; + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + if (padapter->registrypriv.acs_auto_scan) { + do_scan = _TRUE; + rtw_acs_start(padapter, _TRUE); + } +#endif + + if (_TRUE == do_scan) { + DBG_871X("%s : drv scans by itself and wait_completed\n", __func__); + rtw_drv_scan_by_self(padapter); + rtw_scan_wait_completed(padapter); + } + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + if (padapter->registrypriv.acs_auto_scan) + rtw_acs_start(padapter, _FALSE); +#endif + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) { + + if (rtw_end_of_queue_search(phead, plist) == _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 + && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE + && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))) { + delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned); + + if (delta_time < lifetime) { + + uint ie_len = 0; + u8 *pbuf = NULL; + u8 *ie = NULL; + + pbss = &pnetwork->network; + ie = pbss->IEs; + + /*check if HT CAP INFO IE exists or not*/ + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss->IELength - _BEACON_IE_OFFSET_)); + if (pbuf == NULL) { + /* HT CAP INFO IE don't exist, it is b/g mode bss.*/ + + if (pmlmepriv->olbc == _FALSE) + pmlmepriv->olbc = _TRUE; + + if (pmlmepriv->olbc_ht == _FALSE) + pmlmepriv->olbc_ht = _TRUE; + } + } + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + pmlmepriv->num_sta_no_ht = 0; /* reset to 0 after ap do scanning*/ + +} + +void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter) +{ + WLAN_BSSID_EX *pnetwork = &(adapter->mlmepriv.cur_network.network); + struct sta_info *sta = NULL; + + /* update cur_wireless_mode */ + update_wireless_mode(adapter); + + /* update RRSR and RTS_INIT_RATE register after set channel and bandwidth */ + UpdateBrateTbl(adapter, pnetwork->SupportedRates); + rtw_hal_set_hwreg(adapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates); + + /* update capability after cur_wireless_mode updated */ + update_capinfo(adapter, rtw_get_capability(pnetwork)); + + /* update bc/mc sta_info */ + update_bmc_sta(adapter); + + /* update AP's sta info */ + sta = rtw_get_stainfo(&adapter->stapriv, pnetwork->MacAddress); + if (!sta) { + DBG_871X(FUNC_ADPT_FMT" !sta for macaddr="MAC_FMT"\n", FUNC_ADPT_ARG(adapter), MAC_ARG(pnetwork->MacAddress)); + rtw_warn_on(1); + return; + } + + update_ap_info(adapter, sta); +} + +void start_bss_network(_adapter *padapter, struct createbss_parm *parm) +{ +#define DUMP_ADAPTERS_STATUS 0 + + u8 val8; + u16 bcn_interval; + u32 acparm; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv* psecuritypriv=&(padapter->securitypriv); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; /* used as input */ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); + u8 req_ch, req_bw, req_offset; + bool ch_setting_changed = _FALSE; + u8 ch_to_set = 0, bw_to_set, offset_to_set; + u8 doiqk = _FALSE; + + if (parm->req_ch == 0) { + /* change to unspecificed ch, bw, offset, get from IE */ + goto get_cbhw_from_ie; + } else if (parm->req_ch > 0) { + /* change ch, bw, offset */ + req_ch = parm->req_ch; + req_bw = parm->req_bw; + req_offset = parm->req_offset; + goto change_chbw; + } + + bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; + + //check if there is wps ie, + //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, + //and at first time the security ie ( RSN/WPA IE) will not include in beacon. + if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL)) + { + pmlmeext->bstart_bss = _TRUE; + } + + //todo: update wmm, ht cap + //pmlmeinfo->WMM_enable; + //pmlmeinfo->HT_enable; + if(pmlmepriv->qospriv.qos_option) + pmlmeinfo->WMM_enable = _TRUE; +#ifdef CONFIG_80211N_HT + if(pmlmepriv->htpriv.ht_option) + { + pmlmeinfo->WMM_enable = _TRUE; + pmlmeinfo->HT_enable = _TRUE; + //pmlmeinfo->HT_info_enable = _TRUE; + //pmlmeinfo->HT_caps_enable = _TRUE; + + update_hw_ht_param(padapter); + } +#endif //#CONFIG_80211N_HT + +#ifdef CONFIG_80211AC_VHT + if(pmlmepriv->vhtpriv.vht_option) { + pmlmeinfo->VHT_enable = _TRUE; + update_hw_vht_param(padapter); + } +#endif //CONFIG_80211AC_VHT + + if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time + { + //WEP Key will be set before this function, do not clear CAM. + if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)) + flush_all_cam_entry(padapter); //clear CAM + } + + //set MSR to AP_Mode + Set_MSR(padapter, _HW_STATE_AP_); + + //Set BSSID REG + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress); + + //Set EDCA param reg +#ifdef CONFIG_CONCURRENT_MODE + acparm = 0x005ea42b; +#else + acparm = 0x002F3217; // VO +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E4317; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + //acparm = 0x00105320; // BE + acparm = 0x005ea42b; + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A444; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + + //Set Security + val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + //Beacon Control related register + rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval)); + +#if 0 + if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time + { + //u32 initialgain; + + //initialgain = 0x1e; + + + //disable dynamic functions, such as high power, DIG + /*rtw_phydm_ability_backup(padapter);*/ + /*rtw_phydm_func_disable_all(padapter);*/ + + //turn on all dynamic functions + /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);*/ + + /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/ + + } +#endif + +get_cbhw_from_ie: + rtw_ies_get_chbw(pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs) + , pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs) + , &req_ch, &req_bw, &req_offset); + +change_chbw: + rtw_warn_on(req_ch == 0); + + ch_setting_changed = rtw_ap_chbw_decision(padapter, req_ch, req_bw, req_offset + , &ch_to_set, &bw_to_set, &offset_to_set); + + //let pnetwork_mlmeext == pnetwork_mlme. + _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length); + + rtw_start_bss_hdl_after_chbw_decided(padapter); + + #if defined(CONFIG_DFS_MASTER) + rtw_dfs_master_status_apply(padapter, MLME_AP_STARTED); + #endif + + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + + if (ch_to_set != 0) + set_channel_bwmode(padapter, ch_to_set, offset_to_set, bw_to_set); + + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + if (DUMP_ADAPTERS_STATUS) { + DBG_871X(FUNC_ADPT_FMT" done\n", FUNC_ADPT_ARG(padapter)); + dump_adapters_status(RTW_DBGDUMP , adapter_to_dvobj(padapter)); + } + + if (_TRUE == pmlmeext->bstart_bss + && !check_fwstate(pmlmepriv, WIFI_SITE_MONITOR) + && !check_fwstate(pmlmepriv, WIFI_OP_CH_SWITCHING) + #ifdef CONFIG_CONCURRENT_MODE + && !check_buddy_fwstate(padapter, WIFI_SITE_MONITOR) + #endif + ) { + + if ((pmlmepriv->olbc == _TRUE) || (pmlmepriv->olbc_ht == _TRUE)) { + + /* AP is not starting a 40 MHz BSS in presence of an 802.11g BSS. */ + + pmlmepriv->ht_op_mode &= (~HT_INFO_OPERATION_MODE_OP_MODE_MASK); + pmlmepriv->ht_op_mode |= OP_MODE_MAY_BE_LEGACY_STAS; + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE); + } + + update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + + #if !defined(CONFIG_INTERRUPT_BASED_TXBCN) + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + /* other case will tx beacon when bcn interrupt coming in. */ + if (send_beacon(padapter) == _FAIL) + DBG_871X("issue_beacon, fail!\n"); + #endif + #endif /* !defined(CONFIG_INTERRUPT_BASED_TXBCN) */ + } + + /*Set EDCA param reg after update cur_wireless_mode & update_capinfo*/ + if (pregpriv->wifi_spec == 1) + rtw_set_hw_wmm_param(padapter); + + /*pmlmeext->bstart_bss = _TRUE;*/ +} + +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len) +{ + int ret=_SUCCESS; + u8 *p; + u8 *pHT_caps_ie=NULL; + u8 *pHT_info_ie=NULL; + u16 cap, ht_cap=_FALSE; + uint ie_len = 0; + int group_cipher, pairwise_cipher; + u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; + int supportRateNum = 0; + u8 OUI1[] = {0x00, 0x50, 0xf2,0x01}; + u8 wps_oui[4]={0x0,0x50,0xf2,0x04}; + u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ie = pbss_network->IEs; + u8 vht_cap=_FALSE; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 rf_num = 0; + + /* SSID */ + /* Supported rates */ + /* DS Params */ + /* WLAN_EID_COUNTRY */ + /* ERP Information element */ + /* Extended supported rates */ + /* WPA/WPA2 */ + /* Wi-Fi Wireless Multimedia Extensions */ + /* ht_capab, ht_oper */ + /* WPS IE */ + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return _FAIL; + + + if(len>MAX_IE_SZ) + return _FAIL; + + pbss_network->IELength = len; + + _rtw_memset(ie, 0, MAX_IE_SZ); + + _rtw_memcpy(ie, pbuf, pbss_network->IELength); + + + if(pbss_network->InfrastructureMode!=Ndis802_11APMode) + return _FAIL; + + + rtw_ap_check_scan(padapter); + + + pbss_network->Rssi = 0; + + _rtw_memcpy(pbss_network->MacAddress, adapter_mac_addr(padapter), ETH_ALEN); + + //beacon interval + p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability + //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); + pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p); + + //capability + //cap = *(unsigned short *)rtw_get_capability_from_ie(ie); + //cap = le16_to_cpu(cap); + cap = RTW_GET_LE16(ie); + + //SSID + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); + pbss_network->Ssid.SsidLength = ie_len; + #ifdef CONFIG_P2P + _rtw_memcpy(padapter->wdinfo.p2p_group_ssid, pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength); + padapter->wdinfo.p2p_group_ssid_len = pbss_network->Ssid.SsidLength; + #endif + } + + //chnnel + channel = 0; + pbss_network->Configuration.Length = 0; + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + channel = *(p + 2); + + pbss_network->Configuration.DSConfig = channel; + + + _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); + // get supported rates + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) + { + _rtw_memcpy(supportRate, p+2, ie_len); + supportRateNum = ie_len; + } + + //get ext_supported rates + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); + if (p != NULL) + { + _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len); + supportRateNum += ie_len; + + } + + network_type = rtw_check_network_type(supportRate, supportRateNum, channel); + + rtw_set_supported_rate(pbss_network->SupportedRates, network_type); + + + //parsing ERP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p); + } + + //update privacy/security + if (cap & BIT(4)) + pbss_network->Privacy = 1; + else + pbss_network->Privacy = 0; + + psecuritypriv->wpa_psk = 0; + + //wpa2 + group_cipher = 0; pairwise_cipher = 0; + psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; + psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + + psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x + psecuritypriv->wpa_psk |= BIT(1); + + psecuritypriv->wpa2_group_cipher = group_cipher; + psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher; +#if 0 + switch(group_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa2_group_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa2_group_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa2_group_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa2_group_cipher = _WEP104_; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa2_pairwise_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa2_pairwise_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa2_pairwise_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa2_pairwise_cipher = _WEP104_; + break; + } +#endif + } + + } + + //wpa + ie_len = 0; + group_cipher = 0; pairwise_cipher = 0; + psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; + psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; + for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) + { + p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if ((p) && (_rtw_memcmp(p+2, OUI1, 4))) + { + if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + + psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x + + psecuritypriv->wpa_psk |= BIT(0); + + psecuritypriv->wpa_group_cipher = group_cipher; + psecuritypriv->wpa_pairwise_cipher = pairwise_cipher; + +#if 0 + switch(group_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa_group_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa_group_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa_group_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa_group_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa_group_cipher = _WEP104_; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_; + break; + case WPA_CIPHER_WEP40: + psecuritypriv->wpa_pairwise_cipher = _WEP40_; + break; + case WPA_CIPHER_TKIP: + psecuritypriv->wpa_pairwise_cipher = _TKIP_; + break; + case WPA_CIPHER_CCMP: + psecuritypriv->wpa_pairwise_cipher = _AES_; + break; + case WPA_CIPHER_WEP104: + psecuritypriv->wpa_pairwise_cipher = _WEP104_; + break; + } +#endif + } + + break; + + } + + if ((p == NULL) || (ie_len == 0)) + { + break; + } + + } + + //wmm + ie_len = 0; + pmlmepriv->qospriv.qos_option = 0; + if(pregistrypriv->wmm_enable) + { + for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) + { + p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6)) + { + pmlmepriv->qospriv.qos_option = 1; + + *(p+8) |= BIT(7);//QoS Info, support U-APSD + + /* disable all ACM bits since the WMM admission control is not supported */ + *(p + 10) &= ~BIT(4); /* BE */ + *(p + 14) &= ~BIT(4); /* BK */ + *(p + 18) &= ~BIT(4); /* VI */ + *(p + 22) &= ~BIT(4); /* VO */ + + break; + } + + if ((p == NULL) || (ie_len == 0)) + { + break; + } + } + } +#ifdef CONFIG_80211N_HT + //parsing HT_CAP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + u8 rf_type=0; + 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; + network_type |= WIRELESS_11_24N; + + 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); + + if (pmlmepriv->htpriv.sgi_40m == _FALSE) + pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_40); + + if (!TEST_FLAG(pmlmepriv->htpriv.ldpc_cap, LDPC_HT_ENABLE_RX)) + { + pht_cap->cap_info &= ~(IEEE80211_HT_CAP_LDPC_CODING); + } + + if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_TX)) + { + pht_cap->cap_info &= ~(IEEE80211_HT_CAP_TX_STBC); + } + + if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX)) + { + 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)) + { + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + } + else + { + pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + } + + 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_memcpy(&(pmlmeinfo->HT_caps), pht_cap, sizeof(struct HT_caps_element)); + + /* 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: + set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_2R); + break; + case RF_3T3R: + set_mcs_rate_by_mask(HT_CAP_ELE_RX_MCS_MAP(pht_cap), MCS_RATE_3R); + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + } + 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 + // Use registry value to enable HT Beamforming. + // ToDo: use configure file to set these capability. + pht_cap->tx_BF_cap_info = 0; + + // HT Beamformer + if(TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) + { + // Transmit NDP Capable + SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(pht_cap, 1); + // Explicit Compressed Steering Capable + SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pht_cap, 1); + // Compressed Steering Number Antennas + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, 1); + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num); + SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pht_cap, rf_num); + } + + // HT Beamformee + if(TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) + { + // Receive NDP Capable + SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(pht_cap, 1); + // Explicit Compressed Beamforming Feedback Capable + SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pht_cap, 2); + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num); + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, rf_num); + } +#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 + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + pHT_info_ie=p; + } +#endif //CONFIG_80211N_HT + switch(network_type) + { + case WIRELESS_11B: + pbss_network->NetworkTypeInUse = Ndis802_11DS; + break; + case WIRELESS_11G: + case WIRELESS_11BG: + case WIRELESS_11G_24N: + case WIRELESS_11BG_24N: + pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; + break; + case WIRELESS_11A: + pbss_network->NetworkTypeInUse = Ndis802_11OFDM5; + break; + default : + pbss_network->NetworkTypeInUse = Ndis802_11OFDM24; + break; + } + + pmlmepriv->cur_network.network_type = network_type; + +#ifdef CONFIG_80211N_HT + pmlmepriv->htpriv.ht_option = _FALSE; + + if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || + (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP)) + { + //todo: + //ht_cap = _FALSE; + } + + //ht_cap + if(pregistrypriv->ht_enable && ht_cap==_TRUE) + { + pmlmepriv->htpriv.ht_option = _TRUE; + pmlmepriv->qospriv.qos_option = 1; + + if(pregistrypriv->ampdu_enable==1) + { + pmlmepriv->htpriv.ampdu_enable = _TRUE; + } + + HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie); + + HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie); + } +#endif + +#ifdef CONFIG_80211AC_VHT + + //Parsing VHT CAP IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if(p && ie_len>0) + { + vht_cap = _TRUE; + } + //Parsing VHT OPERATION IE + + + pmlmepriv->vhtpriv.vht_option = _FALSE; + // if channel in 5G band, then add vht ie . + if ((pbss_network->Configuration.DSConfig > 14) + && (pmlmepriv->htpriv.ht_option == _TRUE) + && (pregistrypriv->vht_enable) + && (!pmlmepriv->country_ent || COUNTRY_CHPLAN_EN_11AC(pmlmepriv->country_ent)) + ) { + if(vht_cap == _TRUE) + { + pmlmepriv->vhtpriv.vht_option = _TRUE; + } + else if(pregistrypriv->vht_enable == 2) // auto enabled + { + u8 cap_len, operation_len; + + rtw_vht_use_default_setting(padapter); + + { + /* VHT Operation mode notifiy bit in Extended IE (127) */ + uint len = 0; + + SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(pmlmepriv->ext_capab_ie_data, 1); + pmlmepriv->ext_capab_ie_len = 10; + rtw_set_ie(pbss_network->IEs + pbss_network->IELength, EID_EXTCapability, 8, pmlmepriv->ext_capab_ie_data, &len); + pbss_network->IELength += pmlmepriv->ext_capab_ie_len; + } + + // VHT Capabilities element + cap_len = rtw_build_vht_cap_ie(padapter, pbss_network->IEs + pbss_network->IELength); + pbss_network->IELength += cap_len; + + // VHT Operation element + operation_len = rtw_build_vht_operation_ie(padapter, pbss_network->IEs + pbss_network->IELength, pbss_network->Configuration.DSConfig); + pbss_network->IELength += operation_len; + + pmlmepriv->vhtpriv.vht_option = _TRUE; + } + } +#endif //CONFIG_80211AC_VHT + + pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network); + + rtw_ies_get_chbw(pbss_network->IEs + _BEACON_IE_OFFSET_, pbss_network->IELength - _BEACON_IE_OFFSET_ + , &pmlmepriv->ori_ch, &pmlmepriv->ori_bw, &pmlmepriv->ori_offset); + rtw_warn_on(pmlmepriv->ori_ch == 0); + +{ + /* alloc sta_info for ap itself */ + + struct sta_info *sta; + + sta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress); + if (!sta) { + sta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress); + if (sta == NULL) + return _FAIL; + } +} + + rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK); + + rtw_indicate_connect( padapter); + + pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon + + //update bc/mc sta_info + //update_bmc_sta(padapter); + + return ret; + +} + +void rtw_set_macaddr_acl(_adapter *padapter, int mode) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + DBG_871X("%s, mode=%d\n", __func__, mode); + + pacl_list->mode = mode; +} + +int rtw_acl_add_sta(_adapter *padapter, u8 *addr) +{ + _irqL irqL; + _list *plist, *phead; + u8 added = _FALSE; + int i, ret=0; + struct rtw_wlan_acl_node *paclnode; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr)); + + if((NUM_ACL-1) < pacl_list->num) + return (-1); + + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + added = _TRUE; + DBG_871X("%s, sta has been added\n", __func__); + break; + } + } + } + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + + if(added == _TRUE) + return ret; + + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + for(i=0; i< NUM_ACL; i++) + { + paclnode = &pacl_list->aclnode[i]; + + if(paclnode->valid == _FALSE) + { + _rtw_init_listhead(&paclnode->list); + + _rtw_memcpy(paclnode->addr, addr, ETH_ALEN); + + paclnode->valid = _TRUE; + + rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q)); + + pacl_list->num++; + + break; + } + } + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + return ret; +} + +int rtw_acl_remove_sta(_adapter *padapter, u8 *addr) +{ + _irqL irqL; + _list *plist, *phead; + int i, ret=0; + struct rtw_wlan_acl_node *paclnode; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //Baddr is used for clearing acl_list + + DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr)); + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN) || _rtw_memcmp(baddr, addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + paclnode->valid = _FALSE; + + rtw_list_delete(&paclnode->list); + + pacl_list->num--; + } + } + } + + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + + return ret; + +} + +u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + + + psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy; + + _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN); + + _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16); + + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +static int rtw_ap_set_key(_adapter *padapter, u8 *key, u8 alg, int keyid, u8 set_tx) +{ + u8 keylen; + struct cmd_obj* pcmd; + struct setkey_parm *psetkeyparm; + struct cmd_priv *pcmdpriv=&(padapter->cmdpriv); + int res=_SUCCESS; + + //DBG_871X("%s\n", __FUNCTION__); + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; + goto exit; + } + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm)); + + psetkeyparm->keyid=(u8)keyid; + if (is_wep_enc(alg)) + padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); + + psetkeyparm->algorithm = alg; + + psetkeyparm->set_tx = set_tx; + + switch(alg) + { + case _WEP40_: + keylen = 5; + break; + case _WEP104_: + keylen = 13; + break; + case _TKIP_: + case _TKIP_WTMIC_: + case _AES_: + default: + keylen = 16; + } + + _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen); + + pcmd->cmdcode = _SetKey_CMD_; + pcmd->parmbuf = (u8 *)psetkeyparm; + pcmd->cmdsz = (sizeof(struct setkey_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + + return res; +} + +int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid) +{ + DBG_871X("%s\n", __FUNCTION__); + + return rtw_ap_set_key(padapter, key, alg, keyid, 1); +} + +int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx) +{ + u8 alg; + + switch(keylen) + { + case 5: + alg =_WEP40_; + break; + case 13: + alg =_WEP104_; + break; + default: + alg =_NO_PRIVACY_; + } + + DBG_871X("%s\n", __FUNCTION__); + + return rtw_ap_set_key(padapter, key, alg, keyid, set_tx); +} + +u8 rtw_ap_bmc_frames_hdl(_adapter *padapter) +{ +#define HIQ_XMIT_COUNTS (6) + _irqL irqL; + struct sta_info *psta_bmc; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + bool update_tim = _FALSE; + + + if (padapter->registrypriv.wifi_spec != 1) + return H2C_SUCCESS; + + + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if (!psta_bmc) + return H2C_SUCCESS; + + + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) { + int tx_counts = 0; + + _update_beacon(padapter, _TIM_IE_, NULL, _FALSE, "update TIM with TIB=1"); + + DBG_871X("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len); + + xmitframe_phead = get_list_head(&psta_bmc->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta_bmc->sleepq_len--; + tx_counts++; + + if (psta_bmc->sleepq_len > 0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + if (tx_counts == HIQ_XMIT_COUNTS) + pxmitframe->attrib.mdata = 0; + + pxmitframe->attrib.triggered = 1; + + if (xmitframe_hiq_filter(pxmitframe) == _TRUE) + pxmitframe->attrib.qsel = QSLT_HIGH;/*HIQ*/ + + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + if (tx_counts == HIQ_XMIT_COUNTS) + break; + + } + + } else { + if (psta_bmc->sleepq_len == 0) { + + /*DBG_871X("sleepq_len of bmc_sta = %d\n", psta_bmc->sleepq_len);*/ + + if (pstapriv->tim_bitmap & BIT(0)) + update_tim = _TRUE; + + pstapriv->tim_bitmap &= ~BIT(0); + pstapriv->sta_dz_bitmap &= ~BIT(0); + + if (update_tim == _TRUE) { + DBG_871X("clear TIB\n"); + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "bmc sleepq and HIQ empty"); + } + } + } + + _exit_critical_bh(&pxmitpriv->lock, &irqL); + +/* + //HIQ Check + rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); + + while (_FALSE == empty && rtw_get_passing_time_ms(start) < 3000) + { + rtw_msleep_os(100); + rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); + } + + + printk("check if hiq empty=%d\n", empty); +*/ + + return H2C_SUCCESS; +} + +#ifdef CONFIG_NATIVEAP_MLME + +static void associated_stainfo_update(_adapter *padapter, struct sta_info *psta, u32 sta_info_type) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + DBG_871X("%s: "MAC_FMT", updated_type=0x%x\n", __func__, MAC_ARG(psta->hwaddr), sta_info_type); + + if (sta_info_type & STA_INFO_UPDATE_BW) { + + if ((psta->flags & WLAN_STA_HT) && !psta->ht_20mhz_set) { + if (pmlmepriv->sw_to_20mhz) { + psta->bw_mode = CHANNEL_WIDTH_20; + /*psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;*/ + psta->htpriv.sgi_40m = _FALSE; + } else { + /*TODO: Switch back to 40MHZ?80MHZ*/ + } + } + } + +/* + if (sta_info_type & STA_INFO_UPDATE_RATE) { + + } +*/ + + if (sta_info_type & STA_INFO_UPDATE_PROTECTION_MODE) + VCS_update(padapter, psta); + +/* + if (sta_info_type & STA_INFO_UPDATE_CAP) { + + } + + if (sta_info_type & STA_INFO_UPDATE_HT_CAP) { + + } + + if (sta_info_type & STA_INFO_UPDATE_VHT_CAP) { + + } +*/ + +} + +static void update_bcn_ext_capab_ie(_adapter *padapter) +{ + sint ie_len = 0; + unsigned char *pbuf; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + u8 *ie = pnetwork->IEs; + u8 null_extcap_data[8] = {0}; + + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if (pbuf && ie_len > 0) + rtw_remove_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_); + + if ((pmlmepriv->ext_capab_ie_len > 0) && + (_rtw_memcmp(pmlmepriv->ext_capab_ie_data, null_extcap_data, sizeof(null_extcap_data)) == _FALSE)) + rtw_add_bcn_ie(padapter, pnetwork, _EXT_CAP_IE_, pmlmepriv->ext_capab_ie_data, pmlmepriv->ext_capab_ie_len); + +} + +static void update_bcn_fixed_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_erpinfo_ie(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + unsigned char *p, *ie = pnetwork->IEs; + u32 len = 0; + + DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable); + + if(!pmlmeinfo->ERP_enable) + return; + + //parsing ERP_IE + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(p && len>0) + { + PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p; + + if (pmlmepriv->num_sta_non_erp == 1) + pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION; + else + pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION); + + if(pmlmepriv->num_sta_no_short_preamble > 0) + pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE; + else + pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE); + + ERP_IE_handler(padapter, pIE); + } + +} + +static void update_bcn_htcap_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_htinfo_ie(_adapter *padapter) +{ + /* + u8 beacon_updated = _FALSE; + u32 sta_info_update_type = STA_INFO_UPDATE_NONE; + */ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + unsigned char *p, *ie = pnetwork->IEs; + u32 len = 0; + + if (pmlmepriv->htpriv.ht_option == _FALSE) + return; + + if (pmlmeinfo->HT_info_enable != 1) + return; + + + DBG_871X("%s current operation mode=0x%X\n", + __FUNCTION__, pmlmepriv->ht_op_mode); + + DBG_871X("num_sta_40mhz_intolerant(%d), 20mhz_width_req(%d), intolerant_ch_rpt(%d), olbc(%d)\n", + pmlmepriv->num_sta_40mhz_intolerant, pmlmepriv->ht_20mhz_width_req, pmlmepriv->ht_intolerant_ch_reported, pmlmepriv->olbc); + + /*parsing HT_INFO_IE, currently only update ht_op_mode - pht_info->infos[1] & pht_info->infos[2] for wifi logo test*/ + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if (p && len > 0) { + struct HT_info_element *pht_info = NULL; + + pht_info = (struct HT_info_element *)(p + 2); + + /* for STA Channel Width/Secondary Channel Offset*/ + if ((pmlmepriv->sw_to_20mhz == 0) && (pmlmeext->cur_channel <= 14)) { + if ((pmlmepriv->num_sta_40mhz_intolerant > 0) || (pmlmepriv->ht_20mhz_width_req == _TRUE) + || (pmlmepriv->ht_intolerant_ch_reported == _TRUE) || (pmlmepriv->olbc == _TRUE)) { + SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info, 0); + SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 0); + + pmlmepriv->sw_to_20mhz = 1; + /* + sta_info_update_type |= STA_INFO_UPDATE_BW; + beacon_updated = _TRUE; + */ + + DBG_871X("%s:switching to 20Mhz\n", __FUNCTION__); + + /*TODO : cur_bwmode/cur_ch_offset switches to 20Mhz*/ + } + } else { + + if ((pmlmepriv->num_sta_40mhz_intolerant == 0) && (pmlmepriv->ht_20mhz_width_req == _FALSE) + && (pmlmepriv->ht_intolerant_ch_reported == _FALSE) && (pmlmepriv->olbc == _FALSE)) { + + if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_40) { + + SET_HT_OP_ELE_STA_CHL_WIDTH(pht_info, 1); + + SET_HT_OP_ELE_2ND_CHL_OFFSET(pht_info, + (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) ? + HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE : HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW); + + pmlmepriv->sw_to_20mhz = 0; + /* + sta_info_update_type |= STA_INFO_UPDATE_BW; + beacon_updated = _TRUE; + */ + + DBG_871X("%s:switching back to 40Mhz\n", __FUNCTION__); + } + } + } + + /* to update ht_op_mode*/ + *(u16 *)(pht_info->infos + 1) = cpu_to_le16(pmlmepriv->ht_op_mode); + + } + + /*associated_clients_update(padapter, beacon_updated, sta_info_update_type);*/ + +} + +static void update_bcn_rsn_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wpa_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wmm_ie(_adapter *padapter) +{ + DBG_871X("%s\n", __FUNCTION__); + +} + +static void update_bcn_wps_ie(_adapter *padapter) +{ + u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL; + uint wps_ielen=0, wps_offset, remainder_ielen; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + unsigned char *ie = pnetwork->IEs; + u32 ielen = pnetwork->IELength; + + + DBG_871X("%s\n", __FUNCTION__); + + pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen); + + if(pwps_ie==NULL || wps_ielen==0) + return; + + pwps_ie_src = pmlmepriv->wps_beacon_ie; + if(pwps_ie_src == NULL) + return; + + wps_offset = (uint)(pwps_ie-ie); + + premainder_ie = pwps_ie + wps_ielen; + + remainder_ielen = ielen - wps_offset - wps_ielen; + + if(remainder_ielen>0) + { + pbackup_remainder_ie = rtw_malloc(remainder_ielen); + if(pbackup_remainder_ie) + _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); + } + + wps_ielen = (uint)pwps_ie_src[1];//to get ie data len + if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ) + { + _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2); + pwps_ie += (wps_ielen+2); + + if(pbackup_remainder_ie) + _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen); + + //update IELength + pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen; + } + + if(pbackup_remainder_ie) + rtw_mfree(pbackup_remainder_ie, remainder_ielen); + + // deal with the case without set_tx_beacon_cmd() in update_beacon() +#if defined( CONFIG_INTERRUPT_BASED_TXBCN ) || defined( CONFIG_PCI_HCI ) + if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + u8 sr = 0; + rtw_get_wps_attr_content(pwps_ie_src, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + + if( sr ) { + set_fwstate(pmlmepriv, WIFI_UNDER_WPS); + DBG_871X("%s, set WIFI_UNDER_WPS\n", __func__); + } + } +#endif +} + +static void update_bcn_p2p_ie(_adapter *padapter) +{ + +} + +static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui) +{ + DBG_871X("%s\n", __FUNCTION__); + + if(_rtw_memcmp(RTW_WPA_OUI, oui, 4)) + { + update_bcn_wpa_ie(padapter); + } + else if(_rtw_memcmp(WMM_OUI, oui, 4)) + { + update_bcn_wmm_ie(padapter); + } + else if(_rtw_memcmp(WPS_OUI, oui, 4)) + { + update_bcn_wps_ie(padapter); + } + else if(_rtw_memcmp(P2P_OUI, oui, 4)) + { + update_bcn_p2p_ie(padapter); + } + else + { + DBG_871X("unknown OUI type!\n"); + } + + +} + +void _update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx, const char *tag) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv; + struct mlme_ext_priv *pmlmeext; + //struct mlme_ext_info *pmlmeinfo; + + //DBG_871X("%s\n", __FUNCTION__); + + if(!padapter) + return; + + pmlmepriv = &(padapter->mlmepriv); + pmlmeext = &(padapter->mlmeextpriv); + //pmlmeinfo = &(pmlmeext->mlmext_info); + + if(_FALSE == pmlmeext->bstart_bss) + return; + + _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); + + switch(ie_id) + { + case 0xFF: + + update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability + + break; + + case _TIM_IE_: + + update_BCNTIM(padapter); + + break; + + case _ERPINFO_IE_: + + update_bcn_erpinfo_ie(padapter); + + break; + + case _HT_CAPABILITY_IE_: + + update_bcn_htcap_ie(padapter); + + break; + + case _RSN_IE_2_: + + update_bcn_rsn_ie(padapter); + + break; + + case _HT_ADD_INFO_IE_: + + update_bcn_htinfo_ie(padapter); + + break; + + case _EXT_CAP_IE_: + + update_bcn_ext_capab_ie(padapter); + + break; + + case _VENDOR_SPECIFIC_IE_: + + update_bcn_vendor_spec_ie(padapter, oui); + + break; + + default: + break; + } + + pmlmepriv->update_bcn = _TRUE; + + _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); + +#ifndef CONFIG_INTERRUPT_BASED_TXBCN +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + 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 + { + //PCI will issue beacon when BCN interrupt occurs. + } +#endif +#endif //!CONFIG_INTERRUPT_BASED_TXBCN + +} + +#ifdef CONFIG_80211N_HT + +void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len) +{ + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + uint frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr); + u8 category, action; + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (psta == NULL) + return; + + + category = frame_body[0]; + action = frame_body[1]; + + if (frame_body_len > 0) { + if ((frame_body[2] == EID_BSSCoexistence) && (frame_body[3] > 0)) { + u8 ie_data = frame_body[4]; + + if (ie_data & RTW_WLAN_20_40_BSS_COEX_40MHZ_INTOL) { + if (psta->ht_40mhz_intolerant == 0) { + psta->ht_40mhz_intolerant = 1; + pmlmepriv->num_sta_40mhz_intolerant++; + beacon_updated = _TRUE; + } + } else if (ie_data & RTW_WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) { + if (pmlmepriv->ht_20mhz_width_req == _FALSE) { + pmlmepriv->ht_20mhz_width_req = _TRUE; + beacon_updated = _TRUE; + } + } else + beacon_updated = _FALSE; + } + } + + if (frame_body_len > 8) { + /* if EID_BSSIntolerantChlReport ie exists */ + if ((frame_body[5] == EID_BSSIntolerantChlReport) && (frame_body[6] > 0)) { + /*todo:*/ + if (pmlmepriv->ht_intolerant_ch_reported == _FALSE) { + pmlmepriv->ht_intolerant_ch_reported = _TRUE; + beacon_updated = _TRUE; + } + } + } + + if (beacon_updated) { + + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE); + + associated_stainfo_update(padapter, psta, STA_INFO_UPDATE_BW); + } + + + +} + +void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field) +{ + u8 e_field, m_field; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + psta = rtw_get_stainfo(pstapriv, ta); + if (psta == NULL) + return; + + e_field = (ctrl_field & BIT(0)) ? 1 : 0; + m_field = (ctrl_field & BIT(1)) ? 1 : 0; + + if (e_field) { + + /* enable */ + /* 0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/ + + if (m_field) /*mode*/ + psta->htpriv.smps_cap = 1; + else + psta->htpriv.smps_cap = 0; + } else { + /*disable*/ + psta->htpriv.smps_cap = 3; + } + + rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta); + +} + +/* +op_mode +Set to 0 (HT pure) under the followign conditions + - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or + - all STAs in the BSS are 20 MHz HT in 20 MHz BSS +Set to 1 (HT non-member protection) if there may be non-HT STAs + in both the primary and the secondary channel +Set to 2 if only HT STAs are associated in BSS, + however and at least one 20 MHz HT STA is associated +Set to 3 (HT mixed mode) when one or more non-HT STAs are associated + (currently non-GF HT station is considered as non-HT STA also) +*/ +static int rtw_ht_operation_update(_adapter *padapter) +{ + u16 cur_op_mode, new_op_mode; + int op_mode_changes = 0; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; + + if (pmlmepriv->htpriv.ht_option == _FALSE) + return 0; + + /*if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) + return 0;*/ + + DBG_871X("%s current operation mode=0x%X\n", + __FUNCTION__, pmlmepriv->ht_op_mode); + + if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) + && pmlmepriv->num_sta_ht_no_gf) { + pmlmepriv->ht_op_mode |= + HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; + op_mode_changes++; + } else if ((pmlmepriv->ht_op_mode & + HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) && + pmlmepriv->num_sta_ht_no_gf == 0) { + pmlmepriv->ht_op_mode &= + ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT; + op_mode_changes++; + } + + if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && + (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) { + pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; + op_mode_changes++; + } else if ((pmlmepriv->ht_op_mode & + HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) && + (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) { + pmlmepriv->ht_op_mode &= + ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT; + op_mode_changes++; + } + + /* Note: currently we switch to the MIXED op mode if HT non-greenfield + * station is associated. Probably it's a theoretical case, since + * it looks like all known HT STAs support greenfield. + */ + new_op_mode = 0; + if (pmlmepriv->num_sta_no_ht /*|| + (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/) + new_op_mode = OP_MODE_MIXED; + else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH) + && pmlmepriv->num_sta_ht_20mhz) + new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED; + else if (pmlmepriv->olbc_ht) + new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS; + else + new_op_mode = OP_MODE_PURE; + + cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK; + if (cur_op_mode != new_op_mode) { + pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK; + pmlmepriv->ht_op_mode |= new_op_mode; + op_mode_changes++; + } + + DBG_871X("%s new operation mode=0x%X changes=%d\n", + __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes); + + return op_mode_changes; + +} + +#endif /* CONFIG_80211N_HT */ + +void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type) +{ + //update associcated stations cap. + if(updated == _TRUE) + { + _irqL irqL; + _list *phead, *plist; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + associated_stainfo_update(padapter, psta, sta_info_type); + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + +} + +/* called > TSR LEVEL for USB or SDIO Interface*/ +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta) +{ + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + +#if 0 + if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && + !psta->no_short_preamble_set) { + psta->no_short_preamble_set = 1; + pmlmepriv->num_sta_no_short_preamble++; + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 1)) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + + if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) + { + if(!psta->no_short_preamble_set) + { + psta->no_short_preamble_set = 1; + + pmlmepriv->num_sta_no_short_preamble++; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 1)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + else + { + if(psta->no_short_preamble_set) + { + psta->no_short_preamble_set = 0; + + pmlmepriv->num_sta_no_short_preamble--; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_preamble == 0)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + +#if 0 + if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) { + psta->nonerp_set = 1; + pmlmepriv->num_sta_non_erp++; + if (pmlmepriv->num_sta_non_erp == 1) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + if(psta->flags & WLAN_STA_NONERP) + { + if(!psta->nonerp_set) + { + psta->nonerp_set = 1; + + pmlmepriv->num_sta_non_erp++; + + if (pmlmepriv->num_sta_non_erp == 1) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + } + else + { + if(psta->nonerp_set) + { + psta->nonerp_set = 0; + + pmlmepriv->num_sta_non_erp--; + + if (pmlmepriv->num_sta_non_erp == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + } + + +#if 0 + if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) && + !psta->no_short_slot_time_set) { + psta->no_short_slot_time_set = 1; + pmlmepriv->num_sta_no_short_slot_time++; + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 1)) + ieee802_11_set_beacons(hapd->iface); + } +#endif + + if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) + { + if(!psta->no_short_slot_time_set) + { + psta->no_short_slot_time_set = 1; + + pmlmepriv->num_sta_no_short_slot_time++; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 1)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + + } + } + else + { + if(psta->no_short_slot_time_set) + { + psta->no_short_slot_time_set = 0; + + pmlmepriv->num_sta_no_short_slot_time--; + + if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && + (pmlmepriv->num_sta_no_short_slot_time == 0)) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + } + +#ifdef CONFIG_80211N_HT + + if (psta->flags & WLAN_STA_HT) + { + u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info); + + DBG_871X("HT: STA " MAC_FMT " HT Capabilities " + "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab); + + if (psta->no_ht_set) { + psta->no_ht_set = 0; + pmlmepriv->num_sta_no_ht--; + } + + if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) { + if (!psta->no_ht_gf_set) { + psta->no_ht_gf_set = 1; + pmlmepriv->num_sta_ht_no_gf++; + } + DBG_871X("%s STA " MAC_FMT " - no " + "greenfield, num of non-gf stations %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_ht_no_gf); + } + + if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) { + if (!psta->ht_20mhz_set) { + psta->ht_20mhz_set = 1; + pmlmepriv->num_sta_ht_20mhz++; + } + DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, " + "num of 20MHz HT STAs %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_ht_20mhz); + } + + + if (ht_capab & RTW_IEEE80211_HT_CAP_40MHZ_INTOLERANT) { + + if (!psta->ht_40mhz_intolerant) { + psta->ht_40mhz_intolerant = 1; + pmlmepriv->num_sta_40mhz_intolerant++; + DBG_871X("%s STA " MAC_FMT " - HT_CAP_40MHZ_INTOLERANT is set\n" , + __FUNCTION__, MAC_ARG(psta->hwaddr)); + beacon_updated = _TRUE; + } + +/* + if (pmlmepriv->ht_40mhz_intolerant == _FALSE) { + + pmlmepriv->ht_40mhz_intolerant = _TRUE; + + DBG_871X("%s STA " MAC_FMT " - HT_CAP_40MHZ_INTOLERANT is set\n" , + __FUNCTION__, MAC_ARG(psta->hwaddr)); + + beacon_updated = _TRUE; + } +*/ + + /*update ext_capab_ie_len & ext_capab_ie_data for beacon, probersp, assocrsp.*/ + if (pmlmepriv->ext_capab_ie_len == 0) + pmlmepriv->ext_capab_ie_len = 1; + SET_EXT_CAPABILITY_ELE_BSS_COEXIST(pmlmepriv->ext_capab_ie_data, 1); + + update_beacon(padapter, _EXT_CAP_IE_, NULL, _FALSE); + } + + } + else + { + if (!psta->no_ht_set) { + psta->no_ht_set = 1; + pmlmepriv->num_sta_no_ht++; + } + if(pmlmepriv->htpriv.ht_option == _TRUE) { + DBG_871X("%s STA " MAC_FMT + " - no HT, num of non-HT stations %d\n", + __FUNCTION__, MAC_ARG(psta->hwaddr), + pmlmepriv->num_sta_no_ht); + } + } + + if (rtw_ht_operation_update(padapter) > 0) { + update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE); + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE); + /*beacon_updated = _TRUE;*/ + } + +#endif /* CONFIG_80211N_HT */ + + //update associcated stations cap. + associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL); + + DBG_871X("%s, updated=%d\n", __func__, beacon_updated); + +} + +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta) +{ + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + if(!psta) + return beacon_updated; + + if (psta->no_short_preamble_set) { + psta->no_short_preamble_set = 0; + pmlmepriv->num_sta_no_short_preamble--; + if (pmlmeext->cur_wireless_mode > WIRELESS_11B + && pmlmepriv->num_sta_no_short_preamble == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + + if (psta->nonerp_set) { + psta->nonerp_set = 0; + pmlmepriv->num_sta_non_erp--; + if (pmlmepriv->num_sta_non_erp == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE); + } + } + + if (psta->no_short_slot_time_set) { + psta->no_short_slot_time_set = 0; + pmlmepriv->num_sta_no_short_slot_time--; + if (pmlmeext->cur_wireless_mode > WIRELESS_11B + && pmlmepriv->num_sta_no_short_slot_time == 0) + { + beacon_updated = _TRUE; + update_beacon(padapter, 0xFF, NULL, _TRUE); + } + } + +#ifdef CONFIG_80211N_HT + + if (psta->no_ht_gf_set) { + psta->no_ht_gf_set = 0; + pmlmepriv->num_sta_ht_no_gf--; + } + + if (psta->no_ht_set) { + psta->no_ht_set = 0; + pmlmepriv->num_sta_no_ht--; + } + + if (psta->ht_20mhz_set) { + psta->ht_20mhz_set = 0; + pmlmepriv->num_sta_ht_20mhz--; + } + + if (psta->ht_40mhz_intolerant) { + psta->ht_40mhz_intolerant = 0; + pmlmepriv->num_sta_40mhz_intolerant--; + + /*update ext_capab_ie_len & ext_capab_ie_data for beacon, probersp, assocrsp.*/ + if ((pmlmepriv->ext_capab_ie_len > 0) && (pmlmepriv->num_sta_40mhz_intolerant == 0)) { + SET_EXT_CAPABILITY_ELE_BSS_COEXIST(pmlmepriv->ext_capab_ie_data, 0); + update_beacon(padapter, _EXT_CAP_IE_, NULL, _FALSE); + } + + beacon_updated = _TRUE; + + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _FALSE); + } + + if (rtw_ht_operation_update(padapter) > 0) { + update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE); + update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE); + } + +#endif /* CONFIG_80211N_HT */ + + /* update associated stations cap. + associated_clients_update(padapter, beacon_updated, STA_INFO_UPDATE_ALL); //move it to avoid deadlock + */ + + DBG_871X("%s, updated=%d\n", __func__, beacon_updated); + + return beacon_updated; + +} + +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue) +{ + _irqL irqL; + u8 beacon_updated = _FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + if(!psta) + return beacon_updated; + + if (active == _TRUE) + { +#ifdef CONFIG_80211N_HT + //tear down Rx AMPDU + send_delba(padapter, 0, psta->hwaddr);// recipient + + //tear down TX AMPDU + send_delba(padapter, 1, psta->hwaddr);// // originator + +#endif //CONFIG_80211N_HT + + issue_deauth(padapter, psta->hwaddr, reason); + } + +#ifdef CONFIG_BEAMFORMING + beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, psta->hwaddr, ETH_ALEN, 1); +#endif + + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset + + //clear cam entry / key + rtw_clearstakey_cmd(padapter, psta, enqueue); + + + _enter_critical_bh(&psta->lock, &irqL); + psta->state &= ~_FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + #ifdef CONFIG_IOCTL_CFG80211 + if (1) { + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason); + #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */ + #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + } else + #endif //CONFIG_IOCTL_CFG80211 + { + rtw_indicate_sta_disassoc_event(padapter, psta); + } + + report_del_sta_event(padapter, psta->hwaddr, reason, enqueue); + + beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + + return beacon_updated; + +} + +int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset) +{ + _irqL irqL; + _list *phead, *plist; + int ret=0; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return ret; + + DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + /* for each sta in asoc_queue */ + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset); + psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); + + return ret; +} + +int rtw_sta_flush(_adapter *padapter, bool enqueue) +{ + _irqL irqL; + _list *phead, *plist; + int ret = 0; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 flush_num = 0; + char flush_list[NUM_STA]; + int i; + + if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return ret; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); + + /* pick sta from sta asoc_queue */ + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) + flush_list[flush_num++] = stainfo_offset; + else + rtw_warn_on(1); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + /* call ap_free_sta() for each sta picked */ + for (i = 0; i < flush_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, flush_list[i]); + ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, enqueue); + } + + issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); + + associated_clients_update(padapter, _TRUE, STA_INFO_UPDATE_ALL); + + return ret; +} + +/* called > TSR LEVEL for USB or SDIO Interface*/ +void sta_info_update(_adapter *padapter, struct sta_info *psta) +{ + int flags = psta->flags; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + + //update wmm cap. + if(WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if(pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + +#ifdef CONFIG_80211N_HT + //update 802.11n ht cap. + if(WLAN_STA_HT&flags) + { + psta->htpriv.ht_option = _TRUE; + psta->qos_option = 1; + + psta->htpriv.smps_cap = (psta->htpriv.ht_cap.cap_info & IEEE80211_HT_CAP_SM_PS)>>2; + } + else + { + psta->htpriv.ht_option = _FALSE; + } + + if(pmlmepriv->htpriv.ht_option == _FALSE) + psta->htpriv.ht_option = _FALSE; +#endif + +#ifdef CONFIG_80211AC_VHT + //update 802.11AC vht cap. + if(WLAN_STA_VHT&flags) + { + psta->vhtpriv.vht_option = _TRUE; + } + else + { + psta->vhtpriv.vht_option = _FALSE; + } + + if(pmlmepriv->vhtpriv.vht_option == _FALSE) + psta->vhtpriv.vht_option = _FALSE; +#endif + + + update_sta_info_apmode(padapter, psta); + + +} + +/* called >= TSR LEVEL for USB or SDIO Interface*/ +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta) +{ + if (psta->state & _FW_LINKED) { + //add ratid + add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT + } +} +/* restore hw setting from sw data structures */ +void rtw_ap_restore_network(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_info *psta; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + _irqL irqL; + _list *phead, *plist; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + int i; + + rtw_setopmode_cmd(padapter, Ndis802_11APMode,_FALSE); + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + rtw_startbss_cmd(padapter, RTW_CMDF_DIRECTLY); + + if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) + { + /* restore group key, WEP keys is restored in ips_leave() */ + rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0,_FALSE); + } + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + + if (psta == NULL) { + DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter)); + } else if (psta->state &_FW_LINKED) { + rtw_sta_media_status_rpt(padapter, psta, 1); + Update_RA_Entry(padapter, psta); + //pairwise key + /* per sta pairwise key and settings */ + if( (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) + { + rtw_setstakey_cmd(padapter, psta, UNICAST_KEY,_FALSE); + } + } + } + +} + +void start_ap_mode(_adapter *padapter) +{ + int i; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + + pmlmepriv->update_bcn = _FALSE; + + /*init_mlme_ap_info(padapter);*/ + + pmlmeext->bstart_bss = _FALSE; + + pmlmepriv->num_sta_non_erp = 0; + + pmlmepriv->num_sta_no_short_slot_time = 0; + + pmlmepriv->num_sta_no_short_preamble = 0; + + pmlmepriv->num_sta_ht_no_gf = 0; +#ifdef CONFIG_80211N_HT + pmlmepriv->num_sta_no_ht = 0; +#endif //CONFIG_80211N_HT + pmlmeinfo->HT_info_enable = 0; + pmlmeinfo->HT_caps_enable = 0; + pmlmeinfo->HT_enable = 0; + + pmlmepriv->num_sta_ht_20mhz = 0; + pmlmepriv->num_sta_40mhz_intolerant = 0; + pmlmepriv->olbc = _FALSE; + pmlmepriv->olbc_ht = _FALSE; + +#ifdef CONFIG_80211N_HT + pmlmepriv->ht_20mhz_width_req = _FALSE; + pmlmepriv->ht_intolerant_ch_reported = _FALSE; + pmlmepriv->ht_op_mode = 0; + pmlmepriv->sw_to_20mhz = 0; +#endif + + _rtw_memset(pmlmepriv->ext_capab_ie_data, 0, sizeof(pmlmepriv->ext_capab_ie_data)); + pmlmepriv->ext_capab_ie_len = 0; + + for (i = 0 ; i < NUM_STA ; i++) + pstapriv->sta_aid[i] = NULL; + + //for ACL + _rtw_init_listhead(&(pacl_list->acl_node_q.queue)); + pacl_list->num = 0; + pacl_list->mode = 0; + for(i = 0; i < NUM_ACL; i++) + { + _rtw_init_listhead(&pacl_list->aclnode[i].list); + pacl_list->aclnode[i].valid = _FALSE; + } + +} + +void stop_ap_mode(_adapter *padapter) +{ + _irqL irqL; + _list *phead, *plist; + struct rtw_wlan_acl_node *paclnode; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + 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 + _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + + #ifdef CONFIG_DFS_MASTER + rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED); + #endif + + /* free scan queue */ + rtw_free_network_queue(padapter, _TRUE); + + //for ACL + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(paclnode->valid == _TRUE) + { + paclnode->valid = _FALSE; + + rtw_list_delete(&paclnode->list); + + pacl_list->num--; + } + } + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num); + + rtw_sta_flush(padapter, _TRUE); + + //free_assoc_sta_resources + rtw_free_all_stainfo(padapter); + + psta = rtw_get_bcmc_stainfo(padapter); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + rtw_init_bcmc_stainfo(padapter); + + rtw_free_mlme_priv_ie_data(pmlmepriv); + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_MediaStatusNotify(padapter, 0); //disconnect +#endif + +} + +#endif //CONFIG_NATIVEAP_MLME + +void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset) +{ +#define UPDATE_VHT_CAP 1 +#define UPDATE_HT_CAP 1 + +#ifdef CONFIG_80211AC_VHT + { + struct vht_priv *vhtpriv = &adapter->mlmepriv.vhtpriv; + u8 *vht_cap_ie, *vht_op_ie; + int vht_cap_ielen, vht_op_ielen; + u8 center_freq; + + vht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + vht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + center_freq = rtw_get_center_ch(ch, bw, offset); + + /* update vht cap ie */ + if (vht_cap_ie && vht_cap_ielen) { + #if UPDATE_VHT_CAP + /* if ((bw == CHANNEL_WIDTH_160 || bw == CHANNEL_WIDTH_80_80) && pvhtpriv->sgi_160m) + SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvht_cap_ie + 2, 1); + else */ + SET_VHT_CAPABILITY_ELE_SHORT_GI160M(vht_cap_ie + 2, 0); + + if (bw >= CHANNEL_WIDTH_80 && vhtpriv->sgi_80m) + SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 1); + else + SET_VHT_CAPABILITY_ELE_SHORT_GI80M(vht_cap_ie + 2, 0); + #endif + } + + /* update vht op ie */ + if (vht_op_ie && vht_op_ielen) { + if (bw < CHANNEL_WIDTH_80) { + SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 0); + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, 0); + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0); + } else if (bw == CHANNEL_WIDTH_80) { + SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2, 1); + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op_ie + 2, center_freq); + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op_ie + 2, 0); + } else { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" unsupported BW:%u\n", FUNC_ADPT_ARG(adapter), bw); + rtw_warn_on(1); + } + } + } +#endif /* CONFIG_80211AC_VHT */ +#ifdef CONFIG_80211N_HT + { + struct ht_priv *htpriv = &adapter->mlmepriv.htpriv; + u8 *ht_cap_ie, *ht_op_ie; + int ht_cap_ielen, ht_op_ielen; + + ht_cap_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTCapability, &ht_cap_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + ht_op_ie = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_HTInfo, &ht_op_ielen, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + + /* update ht cap ie */ + if (ht_cap_ie && ht_cap_ielen) { + #if UPDATE_HT_CAP + if (bw >= CHANNEL_WIDTH_40) + SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 1); + else + SET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2, 0); + + if (bw >= CHANNEL_WIDTH_40 && htpriv->sgi_40m) + SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 1); + else + SET_HT_CAP_ELE_SHORT_GI40M(ht_cap_ie + 2, 0); + + if (htpriv->sgi_20m) + SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 1); + else + SET_HT_CAP_ELE_SHORT_GI20M(ht_cap_ie + 2, 0); + #endif + } + + /* update ht op ie */ + if (ht_op_ie && ht_op_ielen) { + SET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2, ch); + switch (offset) { + case HAL_PRIME_CHNL_OFFSET_LOWER: + SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCA); + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCB); + break; + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + default: + SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2, SCN); + break; + } + + if (bw >= CHANNEL_WIDTH_40) + SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 1); + else + SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2, 0); + } + } +#endif /* CONFIG_80211N_HT */ + +{ + u8 *p; + int ie_len; + u8 old_ch = bss->Configuration.DSConfig; + bool change_band = _FALSE; + + if ((ch <= 14 && old_ch >= 36) || (ch >= 36 && old_ch <= 14)) + change_band = _TRUE; + + /* update channel in IE */ + p = rtw_get_ie((bss->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (bss->IELength - sizeof(NDIS_802_11_FIXED_IEs))); + if (p && ie_len > 0) + *(p + 2) = ch; + + bss->Configuration.DSConfig = ch; + + /* band is changed, update ERP, support rate, ext support rate IE */ + if (change_band == _TRUE) + change_band_update_ie(adapter, bss, ch); +} + +} + +bool rtw_ap_chbw_decision(_adapter *adapter, u8 req_ch, u8 req_bw, u8 req_offset + , u8 *ch, u8 *bw, u8 *offset) +{ + u8 dec_ch, dec_bw, dec_offset; + u8 u_ch = 0, u_offset, u_bw; + bool changed = _FALSE; + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + u8 sta_num; + u8 ld_sta_num; + u8 lg_sta_num; + u8 ap_num; + u8 ld_ap_num; + bool set_u_ch = _FALSE, set_dec_ch = _FALSE; + + dec_ch = req_ch; + dec_bw = req_bw; + dec_offset = req_offset; + + rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num); + DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, lg_sta_num%u, ap_num:%u\n" + , FUNC_ADPT_ARG(adapter), ld_sta_num, lg_sta_num, ap_num); + + if (ld_sta_num || ap_num) { + /* has linked STA or AP mode, follow */ + + rtw_warn_on(!rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset)); + + DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset); + + rtw_adjust_chbw(adapter, u_ch, &dec_bw, &dec_offset); + + rtw_sync_chbw(&dec_ch, &dec_bw, &dec_offset + , &u_ch, &u_bw, &u_offset); + + rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network) + , dec_ch, dec_bw, dec_offset); + + set_u_ch = _TRUE; + } else if (lg_sta_num) { + /* has linking STA */ + + rtw_warn_on(!rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset)); + + DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset); + + rtw_adjust_chbw(adapter, dec_ch, &dec_bw, &dec_offset); + + if (rtw_is_chbw_grouped(u_ch, u_bw, u_offset, dec_ch, dec_bw, dec_offset)) { + + rtw_sync_chbw(&dec_ch, &dec_bw, &dec_offset + , &u_ch, &u_bw, &u_offset); + + rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network) + , dec_ch, dec_bw, dec_offset); + + set_u_ch = _TRUE; + } else { + /* set this for possible ch change when join down*/ + set_fwstate(&adapter->mlmepriv, WIFI_OP_CH_SWITCHING); + } + } else { + /* single AP mode */ + + DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), req_ch, req_bw, req_offset); + rtw_adjust_chbw(adapter, dec_ch, &dec_bw, &dec_offset); + + #if defined(CONFIG_DFS_MASTER) + /* check NOL */ + if (rtw_chset_is_ch_non_ocp(mlmeext->channel_set, dec_ch, dec_bw, dec_offset)) { + /* choose 5G DFS channel for debug */ + if (adapter_to_rfctl(adapter)->dbg_dfs_master_choose_dfs_ch_first + && rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_NON_DFS) == _TRUE) { + DBG_871X(FUNC_ADPT_FMT" choose 5G DFS channel for debug\n", FUNC_ADPT_ARG(adapter)); + } else + /* choose from 5G no DFS */ + if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_DFS) == _FALSE) { + /* including 5G DFS, not long CAC */ + if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G|RTW_CHF_LONG_CAC) == _FALSE) { + /* including 5G DFS, long CAC */ + if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_2G) == _FALSE) { + /* including 2.4G channel */ + if (rtw_choose_available_chbw(adapter, req_bw, &dec_ch, &dec_bw, &dec_offset, RTW_CHF_5G) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" no available ch\n", FUNC_ADPT_ARG(adapter)); + rtw_warn_on(1); + } + } + } + } + } + #endif /* defined(CONFIG_DFS_MASTER) */ + + rtw_ap_update_bss_chbw(adapter, &(adapter->mlmepriv.cur_network.network) + , dec_ch, dec_bw, dec_offset); + + set_dec_ch = _TRUE; + } + + if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) + #ifdef CONFIG_CONCURRENT_MODE + || check_buddy_fwstate(adapter, _FW_UNDER_SURVEY) + #endif + ) { + /* scanning, leave ch setting to scan state machine */ + set_u_ch = set_dec_ch = _FALSE; + } + + if (mlmeext->cur_channel != dec_ch + || mlmeext->cur_bwmode != dec_bw + || mlmeext->cur_ch_offset != dec_offset) + changed = _TRUE; + + if (changed == _TRUE && rtw_linked_check(adapter) == _TRUE) { + #ifdef CONFIG_SPCT_CH_SWITCH + if (1) + rtw_ap_inform_ch_switch(adapter, dec_ch, dec_offset); + else + #endif + rtw_sta_flush(adapter, _FALSE); + } + + mlmeext->cur_channel = dec_ch; + mlmeext->cur_bwmode = dec_bw; + mlmeext->cur_ch_offset = dec_offset; + + if (u_ch != 0) + DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + + DBG_871X(FUNC_ADPT_FMT" dec: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), dec_ch, dec_bw, dec_offset); + + if (set_u_ch == _TRUE) { + *ch = u_ch; + *bw = u_bw; + *offset = u_offset; + } else if (set_dec_ch == _TRUE) { + *ch = dec_ch; + *bw = dec_bw; + *offset = dec_offset; + } + + return changed; +} + +#endif //CONFIG_AP_MODE + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_beamforming.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_beamforming.c new file mode 100644 index 00000000..0b52972f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_beamforming.c @@ -0,0 +1,1244 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_BEAMFORMING_C_ + +#include +#include + +#ifdef CONFIG_BEAMFORMING + +#if (BEAMFORMING_SUPPORT == 0) /*for diver defined beamforming*/ +struct beamforming_entry *beamforming_get_entry_by_addr(struct mlme_priv *pmlmepriv, u8* ra,u8* idx) +{ + u8 i = 0; + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + + for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++) + { + if( pBeamInfo->beamforming_entry[i].bUsed && + (_rtw_memcmp(ra,pBeamInfo->beamforming_entry[i].mac_addr, ETH_ALEN))) + { + *idx = i; + return &(pBeamInfo->beamforming_entry[i]); + } + } + + return NULL; +} + +BEAMFORMING_CAP beamforming_get_entry_beam_cap_by_mac_id(PVOID pmlmepriv ,u8 mac_id) +{ + u8 i = 0; + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO((struct mlme_priv *)pmlmepriv); + BEAMFORMING_CAP BeamformEntryCap = BEAMFORMING_CAP_NONE; + + for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++) + { + if( pBeamInfo->beamforming_entry[i].bUsed && + (mac_id == pBeamInfo->beamforming_entry[i].mac_id)) + { + BeamformEntryCap = pBeamInfo->beamforming_entry[i].beamforming_entry_cap; + i = BEAMFORMING_ENTRY_NUM; + } + } + + return BeamformEntryCap; +} + +struct beamforming_entry *beamforming_get_free_entry(struct mlme_priv *pmlmepriv, u8* idx) +{ + u8 i = 0; + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + + for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++) + { + if(pBeamInfo->beamforming_entry[i].bUsed == _FALSE) + { + *idx = i; + return &(pBeamInfo->beamforming_entry[i]); + } + } + return NULL; +} + + +struct beamforming_entry *beamforming_add_entry(PADAPTER adapter, u8* ra, u16 aid, + u16 mac_id, CHANNEL_WIDTH bw, BEAMFORMING_CAP beamfrom_cap, u8* idx) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct beamforming_entry *pEntry = beamforming_get_free_entry(pmlmepriv, idx); + + if(pEntry != NULL) + { + pEntry->bUsed = _TRUE; + pEntry->aid = aid; + pEntry->mac_id = mac_id; + pEntry->sound_bw = bw; + if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + u16 BSSID = ((*(adapter_mac_addr(adapter) + 5) & 0xf0) >> 4) ^ + (*(adapter_mac_addr(adapter) + 5) & 0xf); /* BSSID[44:47] xor BSSID[40:43] */ + pEntry->p_aid = (aid + BSSID * 32) & 0x1ff; // (dec(A) + dec(B)*32) mod 512 + pEntry->g_id = 63; + } + else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) + { + pEntry->p_aid = 0; + pEntry->g_id = 63; + } + else + { + pEntry->p_aid = ra[5]; // BSSID[39:47] + pEntry->p_aid = (pEntry->p_aid << 1) | (ra[4] >> 7 ); + pEntry->g_id = 0; + } + _rtw_memcpy(pEntry->mac_addr, ra, ETH_ALEN); + pEntry->bSound = _FALSE; + + //3 TODO SW/FW sound period + pEntry->sound_period = 200; + pEntry->beamforming_entry_cap = beamfrom_cap; + pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + + + pEntry->PreLogSeq = 0; /*Modified by Jeffery @2015-04-13*/ + pEntry->LogSeq = 0; /*Modified by Jeffery @2014-10-29*/ + pEntry->LogRetryCnt = 0; /*Modified by Jeffery @2014-10-29*/ + pEntry->LogSuccess = 0; /*LogSuccess is NOT needed to be accumulated, so LogSuccessCnt->LogSuccess, 2015-04-13, Jeffery*/ + pEntry->ClockResetTimes = 0; /*Modified by Jeffery @2015-04-13*/ + pEntry->LogStatusFailCnt = 0; + + return pEntry; + } + else + return NULL; +} + +BOOLEAN beamforming_remove_entry(struct mlme_priv *pmlmepriv, u8* ra, u8* idx) +{ + struct beamforming_entry *pEntry = beamforming_get_entry_by_addr(pmlmepriv, ra, idx); + + if(pEntry != NULL) + { + pEntry->bUsed = _FALSE; + pEntry->beamforming_entry_cap = BEAMFORMING_CAP_NONE; + pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + return _TRUE; + } + else + return _FALSE; +} + +/* Used for BeamformingStart_V1 */ +void beamforming_dym_ndpa_rate(PADAPTER adapter) +{ + u16 NDPARate = MGN_6M; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + + if(pHalData->MinUndecoratedPWDBForDM > 30) // link RSSI > 30% + NDPARate = MGN_24M; + else + NDPARate = MGN_6M; + + //BW = CHANNEL_WIDTH_20; + NDPARate = NDPARate << 8; + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_RATE, (u8 *)&NDPARate); +} + +void beamforming_dym_period(PADAPTER Adapter) +{ + u8 Idx; + BOOLEAN bChangePeriod = _FALSE; + u16 SoundPeriod_SW, SoundPeriod_FW; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); + struct beamforming_entry *pBeamformEntry; + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(( &Adapter->mlmepriv)); + struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info); + + //3 TODO per-client throughput caculation. + + if(pdvobjpriv->traffic_stat.cur_tx_tp + pdvobjpriv->traffic_stat.cur_rx_tp > 2) + { + SoundPeriod_SW = 32*20; + SoundPeriod_FW = 2; + } + else + { + SoundPeriod_SW = 32*2000; + SoundPeriod_FW = 200; + } + + for(Idx = 0; Idx < BEAMFORMING_ENTRY_NUM; Idx++) + { + pBeamformEntry = pBeamInfo->beamforming_entry+Idx; + if(pBeamformEntry->bDefaultCSI) + { + SoundPeriod_SW = 32*2000; + SoundPeriod_FW = 200; + } + + if(pBeamformEntry->beamforming_entry_cap & (BEAMFORMER_CAP_HT_EXPLICIT |BEAMFORMER_CAP_VHT_SU)) + { + if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER) + { + if(pBeamformEntry->sound_period != SoundPeriod_FW) + { + pBeamformEntry->sound_period = SoundPeriod_FW; + bChangePeriod = _TRUE; // Only FW sounding need to send H2C packet to change sound period. + } + } + else if(pBeamformEntry->sound_period != SoundPeriod_SW) + { + pBeamformEntry->sound_period = SoundPeriod_SW; + } + } + } + + if(bChangePeriod) + rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&Idx); +} + +BOOLEAN issue_ht_sw_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c}; + u8 *pframe; + u16 *fctrl; + u16 duration = 0; + u8 aSifsTime = 0; + u8 NDPTxRate = 0; + + DBG_871X("%s: issue_ht_sw_ndpa_packet!\n", __func__); + + NDPTxRate = MGN_MCS8; + DBG_871X("%s: NDPTxRate =%d\n", __func__, NDPTxRate); + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) + return _FALSE; + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + pattrib->qsel = QSLT_MGNT; + pattrib->rate = NDPTxRate; + pattrib->bwmode = bw; + pattrib->order = 1; + pattrib->subtype = WIFI_ACTION_NOACK; + + _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; + + SetOrderBit(pframe); + SetFrameSubType(pframe, WIFI_ACTION_NOACK); + + _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + if (pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + duration = 2*aSifsTime + 40; + + if (bw == CHANNEL_WIDTH_40) + duration += 87; + else + duration += 180; + + SetDuration(pframe, duration); + + /*HT control field*/ + SET_HT_CTRL_CSI_STEERING(pframe+24, 3); + SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1); + + _rtw_memcpy(pframe+28, ActionHdr, 4); + + pattrib->pktlen = 32; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; + + +} +BOOLEAN issue_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c}; + u8 *pframe; + u16 *fctrl; + u16 duration = 0; + u8 aSifsTime = 0; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) + return _FALSE; + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + + if (qidx == BCN_QUEUE_INX) + pattrib->qsel = QSLT_BEACON; + pattrib->rate = MGN_MCS8; + pattrib->bwmode = bw; + pattrib->order = 1; + pattrib->subtype = WIFI_ACTION_NOACK; + + _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; + + SetOrderBit(pframe); + SetFrameSubType(pframe, WIFI_ACTION_NOACK); + + _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + if( pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + duration = 2*aSifsTime + 40; + + if(bw == CHANNEL_WIDTH_40) + duration+= 87; + else + duration+= 180; + + SetDuration(pframe, duration); + + //HT control field + SET_HT_CTRL_CSI_STEERING(pframe+24, 3); + SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1); + + _rtw_memcpy(pframe+28, ActionHdr, 4); + + pattrib->pktlen = 32; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; +} + +BOOLEAN beamforming_send_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx) +{ + return issue_ht_ndpa_packet(Adapter, ra, bw, qidx); +} +BOOLEAN issue_vht_sw_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct rtw_ndpa_sta_info sta_info; + u8 NDPTxRate = 0; + + u8 *pframe; + u16 *fctrl; + u16 duration = 0; + u8 sequence = 0, aSifsTime = 0; + + DBG_871X("%s: issue_vht_sw_ndpa_packet!\n", __func__); + + + NDPTxRate = MGN_VHT2SS_MCS0; + DBG_871X("%s: NDPTxRate =%d\n", __func__, NDPTxRate); + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X("%s, alloc mgnt frame fail\n", __func__); + return _FALSE; + } + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + pattrib->qsel = QSLT_MGNT; + pattrib->rate = NDPTxRate; + pattrib->bwmode = bw; + pattrib->subtype = WIFI_NDPA; + + _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; + + SetFrameSubType(pframe, WIFI_NDPA); + + _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN); + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode)) + aSifsTime = 16; + else + aSifsTime = 10; + + duration = 2*aSifsTime + 44; + + if (bw == CHANNEL_WIDTH_80) + duration += 40; + else if (bw == CHANNEL_WIDTH_40) + duration += 87; + else + duration += 180; + + SetDuration(pframe, duration); + + sequence = pBeamInfo->sounding_sequence << 2; + if (pBeamInfo->sounding_sequence >= 0x3f) + pBeamInfo->sounding_sequence = 0; + else + pBeamInfo->sounding_sequence++; + + _rtw_memcpy(pframe+16, &sequence, 1); + if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + aid = 0; + + sta_info.aid = aid; + sta_info.feedback_type = 0; + sta_info.nc_index = 0; + + _rtw_memcpy(pframe+17, (u8 *)&sta_info, 2); + + pattrib->pktlen = 19; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + + return _TRUE; + +} +BOOLEAN issue_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct rtw_ndpa_sta_info sta_info; + u8 *pframe; + u16 *fctrl; + u16 duration = 0; + u8 sequence = 0, aSifsTime = 0; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return _FALSE; + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + + if (qidx == BCN_QUEUE_INX) + pattrib->qsel = QSLT_BEACON; + pattrib->rate = MGN_VHT2SS_MCS0; + pattrib->bwmode = bw; + pattrib->subtype = WIFI_NDPA; + + _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; + + SetFrameSubType(pframe, WIFI_NDPA); + + _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN); + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode)) + aSifsTime = 16; + else + aSifsTime = 10; + + duration = 2*aSifsTime + 44; + + if(bw == CHANNEL_WIDTH_80) + duration += 40; + else if(bw == CHANNEL_WIDTH_40) + duration+= 87; + else + duration+= 180; + + SetDuration(pframe, duration); + + sequence = pBeamInfo->sounding_sequence<< 2; + if (pBeamInfo->sounding_sequence >= 0x3f) + pBeamInfo->sounding_sequence = 0; + else + pBeamInfo->sounding_sequence++; + + _rtw_memcpy(pframe+16, &sequence,1); + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + aid = 0; + + sta_info.aid = aid; + sta_info.feedback_type = 0; + sta_info.nc_index= 0; + + _rtw_memcpy(pframe+17, (u8 *)&sta_info, 2); + + pattrib->pktlen = 19; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; +} + +BOOLEAN beamforming_send_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx) +{ + return issue_vht_ndpa_packet(Adapter, ra, aid, bw, qidx); +} + +BOOLEAN beamfomring_bSounding(struct beamforming_info *pBeamInfo) +{ + BOOLEAN bSounding = _FALSE; + + if(( beamforming_get_beamform_cap(pBeamInfo) & BEAMFORMER_CAP) == 0) + bSounding = _FALSE; + else + bSounding = _TRUE; + + return bSounding; +} + +u8 beamforming_sounding_idx(struct beamforming_info *pBeamInfo) +{ + u8 idx = 0; + u8 i; + + for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++) + { + if (pBeamInfo->beamforming_entry[i].bUsed && + (_FALSE == pBeamInfo->beamforming_entry[i].bSound)) + { + idx = i; + break; + } + } + + return idx; +} + +SOUNDING_MODE beamforming_sounding_mode(struct beamforming_info *pBeamInfo, u8 idx) +{ + struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx]; + SOUNDING_MODE mode; + + if(BeamEntry.beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU) + { + mode = SOUNDING_FW_VHT_TIMER; + } + else if(BeamEntry.beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT) + { + mode = SOUNDING_FW_HT_TIMER; + } + else + { + mode = SOUNDING_STOP_All_TIMER; + } + + return mode; +} + +u16 beamforming_sounding_time(struct beamforming_info *pBeamInfo, SOUNDING_MODE mode, u8 idx) +{ + u16 sounding_time = 0xffff; + struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx]; + + sounding_time = BeamEntry.sound_period; + + return sounding_time; +} + +CHANNEL_WIDTH beamforming_sounding_bw(struct beamforming_info *pBeamInfo, SOUNDING_MODE mode, u8 idx) +{ + CHANNEL_WIDTH sounding_bw = CHANNEL_WIDTH_20; + struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx]; + + sounding_bw = BeamEntry.sound_bw; + + return sounding_bw; +} + +BOOLEAN beamforming_select_beam_entry(struct beamforming_info *pBeamInfo) +{ + struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info); + + pSoundInfo->sound_idx = beamforming_sounding_idx(pBeamInfo); + + if(pSoundInfo->sound_idx < BEAMFORMING_ENTRY_NUM) + pSoundInfo->sound_mode = beamforming_sounding_mode(pBeamInfo, pSoundInfo->sound_idx); + else + pSoundInfo->sound_mode = SOUNDING_STOP_All_TIMER; + + if(SOUNDING_STOP_All_TIMER == pSoundInfo->sound_mode) + { + return _FALSE; + } + else + { + pSoundInfo->sound_bw = beamforming_sounding_bw(pBeamInfo, pSoundInfo->sound_mode, pSoundInfo->sound_idx ); + pSoundInfo->sound_period = beamforming_sounding_time(pBeamInfo, pSoundInfo->sound_mode, pSoundInfo->sound_idx ); + return _TRUE; + } +} + +BOOLEAN beamforming_start_fw(PADAPTER adapter, u8 idx) +{ + u8 *RA = NULL; + struct beamforming_entry *pEntry; + BOOLEAN ret = _TRUE; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + + pEntry = &(pBeamInfo->beamforming_entry[idx]); + if(pEntry->bUsed == _FALSE) + { + DBG_871X("Skip Beamforming, no entry for Idx =%d\n", idx); + return _FALSE; + } + + pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSING; + pEntry->bSound = _TRUE; + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&idx); + + return _TRUE; +} + +void beamforming_end_fw(PADAPTER adapter) +{ + u8 idx = 0; + + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&idx); + + DBG_871X("%s\n", __FUNCTION__); +} + +BOOLEAN beamforming_start_period(PADAPTER adapter) +{ + BOOLEAN ret = _TRUE; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info); + + beamforming_dym_ndpa_rate(adapter); + + beamforming_select_beam_entry(pBeamInfo); + + if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER) + { + ret = beamforming_start_fw(adapter, pSoundInfo->sound_idx); + } + else + { + ret = _FALSE; + } + + DBG_871X("%s Idx %d Mode %d BW %d Period %d\n", __FUNCTION__, + pSoundInfo->sound_idx, pSoundInfo->sound_mode, pSoundInfo->sound_bw, pSoundInfo->sound_period); + + return ret; +} + +void beamforming_end_period(PADAPTER adapter) +{ + u8 idx = 0; + struct beamforming_entry *pBeamformEntry; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info); + + + if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER) + { + beamforming_end_fw(adapter); + } +} + +void beamforming_notify(PADAPTER adapter) +{ + BOOLEAN bSounding = _FALSE; + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(&(adapter->mlmepriv)); + + bSounding = beamfomring_bSounding(pBeamInfo); + + if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_IDLE) + { + if(bSounding) + { + if(beamforming_start_period(adapter) == _TRUE) + pBeamInfo->beamforming_state = BEAMFORMING_STATE_START; + } + } + else if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_START) + { + if(bSounding) + { + if(beamforming_start_period(adapter) == _FALSE) + pBeamInfo->beamforming_state = BEAMFORMING_STATE_END; + } + else + { + beamforming_end_period(adapter); + pBeamInfo->beamforming_state = BEAMFORMING_STATE_END; + } + } + else if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_END) + { + if(bSounding) + { + if(beamforming_start_period(adapter) == _TRUE) + pBeamInfo->beamforming_state = BEAMFORMING_STATE_START; + } + } + else + { + DBG_871X("%s BeamformState %d\n", __FUNCTION__, pBeamInfo->beamforming_state); + } + + DBG_871X("%s BeamformState %d bSounding %d\n", __FUNCTION__, pBeamInfo->beamforming_state, bSounding); +} + +BOOLEAN beamforming_init_entry(PADAPTER adapter, struct sta_info *psta, u8* idx) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct ht_priv *phtpriv = &(pmlmepriv->htpriv); +#ifdef CONFIG_80211AC_VHT + struct vht_priv *pvhtpriv = &(pmlmepriv->vhtpriv); +#endif + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct beamforming_entry *pBeamformEntry = NULL; + u8 *ra; + u16 aid, mac_id; + u8 wireless_mode; + CHANNEL_WIDTH bw = CHANNEL_WIDTH_20; + BEAMFORMING_CAP beamform_cap = BEAMFORMING_CAP_NONE; + + // The current setting does not support Beaforming + if (0 == phtpriv->beamform_cap +#ifdef CONFIG_80211AC_VHT + && 0 == pvhtpriv->beamform_cap +#endif + ) { + DBG_871X("The configuration disabled Beamforming! Skip...\n"); + return _FALSE; + } + + aid = psta->aid; + ra = psta->hwaddr; + mac_id = psta->mac_id; + wireless_mode = psta->wireless_mode; + bw = psta->bw_mode; + + if (IsSupportedHT(wireless_mode) || IsSupportedVHT(wireless_mode)) { + //3 // HT + u8 cur_beamform; + + cur_beamform = psta->htpriv.beamform_cap; + + // We are Beamformee because the STA is Beamformer + if(TEST_FLAG(cur_beamform, BEAMFORMING_HT_BEAMFORMER_ENABLE)) + beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMEE_CAP_HT_EXPLICIT); + + // We are Beamformer because the STA is Beamformee + if(TEST_FLAG(cur_beamform, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) + beamform_cap =(BEAMFORMING_CAP)(beamform_cap | BEAMFORMER_CAP_HT_EXPLICIT); +#ifdef CONFIG_80211AC_VHT + if (IsSupportedVHT(wireless_mode)) { + //3 // VHT + cur_beamform = psta->vhtpriv.beamform_cap; + + // We are Beamformee because the STA is Beamformer + if(TEST_FLAG(cur_beamform, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) + beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMEE_CAP_VHT_SU); + // We are Beamformer because the STA is Beamformee + if(TEST_FLAG(cur_beamform, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) + beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMER_CAP_VHT_SU); + } +#endif //CONFIG_80211AC_VHT + + if(beamform_cap == BEAMFORMING_CAP_NONE) + return _FALSE; + + DBG_871X("Beamforming Config Capability = 0x%02X\n", beamform_cap); + + pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ra, idx); + if (pBeamformEntry == NULL) { + pBeamformEntry = beamforming_add_entry(adapter, ra, aid, mac_id, bw, beamform_cap, idx); + if(pBeamformEntry == NULL) + return _FALSE; + else + pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZEING; + } else { + // Entry has been created. If entry is initialing or progressing then errors occur. + if (pBeamformEntry->beamforming_entry_state != BEAMFORMING_ENTRY_STATE_INITIALIZED && + pBeamformEntry->beamforming_entry_state != BEAMFORMING_ENTRY_STATE_PROGRESSED) { + DBG_871X("Error State of Beamforming"); + return _FALSE; + } else { + pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZEING; + } + } + + pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZED; + psta->txbf_paid = pBeamformEntry->p_aid; + psta->txbf_gid = pBeamformEntry->g_id; + + DBG_871X("%s Idx %d\n", __FUNCTION__, *idx); + } else { + return _FALSE; + } + + return _SUCCESS; +} + +void beamforming_deinit_entry(PADAPTER adapter, u8* ra) +{ + u8 idx = 0; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + + if(beamforming_remove_entry(pmlmepriv, ra, &idx) == _TRUE) + { + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_LEAVE, (u8 *)&idx); + } + + DBG_871X("%s Idx %d\n", __FUNCTION__, idx); +} + +void beamforming_reset(PADAPTER adapter) +{ + u8 idx = 0; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + + for(idx = 0; idx < BEAMFORMING_ENTRY_NUM; idx++) + { + if(pBeamInfo->beamforming_entry[idx].bUsed == _TRUE) + { + pBeamInfo->beamforming_entry[idx].bUsed = _FALSE; + pBeamInfo->beamforming_entry[idx].beamforming_entry_cap = BEAMFORMING_CAP_NONE; + pBeamInfo->beamforming_entry[idx].beamforming_entry_state= BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_LEAVE, (u8 *)&idx); + } + } + + DBG_871X("%s\n", __FUNCTION__); +} + +void beamforming_sounding_fail(PADAPTER Adapter) +{ + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct beamforming_entry *pEntry = &(pBeamInfo->beamforming_entry[pBeamInfo->beamforming_cur_idx]); + + pEntry->bSound = _FALSE; + rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&pBeamInfo->beamforming_cur_idx); + beamforming_deinit_entry(Adapter, pEntry->mac_addr); +} + +void beamforming_check_sounding_success(PADAPTER Adapter,BOOLEAN status) +{ + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv); + struct beamforming_entry *pEntry = &(pBeamInfo->beamforming_entry[pBeamInfo->beamforming_cur_idx]); + + if(status == 1) + { + pEntry->LogStatusFailCnt = 0; + } + else + { + pEntry->LogStatusFailCnt++; + DBG_871X("%s LogStatusFailCnt %d\n", __FUNCTION__, pEntry->LogStatusFailCnt); + } + if(pEntry->LogStatusFailCnt > 20) + { + DBG_871X("%s LogStatusFailCnt > 20, Stop SOUNDING\n", __FUNCTION__); + //pEntry->bSound = _FALSE; + //rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&pBeamInfo->beamforming_cur_idx); + //beamforming_deinit_entry(Adapter, pEntry->mac_addr); + beamforming_wk_cmd(Adapter, BEAMFORMING_CTRL_SOUNDING_FAIL, NULL, 0, 1); + } +} + +void beamforming_enter(PADAPTER adapter, PVOID psta) +{ + u8 idx = 0xff; + + if(beamforming_init_entry(adapter, (struct sta_info *)psta, &idx)) + rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_ENTER, (u8 *)&idx); + + //DBG_871X("%s Idx %d\n", __FUNCTION__, idx); +} + +void beamforming_leave(PADAPTER adapter,u8* ra) +{ + if(ra == NULL) + beamforming_reset(adapter); + else + beamforming_deinit_entry(adapter, ra); + + beamforming_notify(adapter); +} + +BEAMFORMING_CAP beamforming_get_beamform_cap(struct beamforming_info *pBeamInfo) +{ + u8 i; + BOOLEAN bSelfBeamformer = _FALSE; + BOOLEAN bSelfBeamformee = _FALSE; + struct beamforming_entry beamforming_entry; + BEAMFORMING_CAP beamform_cap = BEAMFORMING_CAP_NONE; + + for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++) + { + beamforming_entry = pBeamInfo->beamforming_entry[i]; + + if(beamforming_entry.bUsed) + { + if( (beamforming_entry.beamforming_entry_cap & BEAMFORMEE_CAP_VHT_SU) || + (beamforming_entry.beamforming_entry_cap & BEAMFORMEE_CAP_HT_EXPLICIT)) + bSelfBeamformee = _TRUE; + if( (beamforming_entry.beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU) || + (beamforming_entry.beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT)) + bSelfBeamformer = _TRUE; + } + + if(bSelfBeamformer && bSelfBeamformee) + i = BEAMFORMING_ENTRY_NUM; + } + + if(bSelfBeamformer) + beamform_cap |= BEAMFORMER_CAP; + if(bSelfBeamformee) + beamform_cap |= BEAMFORMEE_CAP; + + return beamform_cap; +} + +void beamforming_watchdog(PADAPTER Adapter) +{ + struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(( &(Adapter->mlmepriv))); + + if(pBeamInfo->beamforming_state != BEAMFORMING_STATE_START) + return; + + beamforming_dym_period(Adapter); + beamforming_dym_ndpa_rate(Adapter); +} +#endif/* #if (BEAMFORMING_SUPPORT ==0) - for diver defined beamforming*/ + +u32 beamforming_get_report_frame(PADAPTER Adapter, union recv_frame *precv_frame) +{ + u32 ret = _SUCCESS; +#if (BEAMFORMING_SUPPORT == 1) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + ret = Beamforming_GetReportFrame(pDM_Odm, precv_frame); + +#else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/ + struct beamforming_entry *pBeamformEntry = NULL; + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + u8 *pframe = precv_frame->u.hdr.rx_data; + u32 frame_len = precv_frame->u.hdr.len; + u8 *ta; + u8 idx, offset; + + /*DBG_871X("beamforming_get_report_frame\n");*/ + + /*Memory comparison to see if CSI report is the same with previous one*/ + ta = GetAddr2Ptr(pframe); + pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ta, &idx); + if (pBeamformEntry->beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU) + offset = 31; /*24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/ + else if (pBeamformEntry->beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT) + offset = 34; /*24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/ + else + return ret; + + /*DBG_871X("%s MacId %d offset=%d\n", __FUNCTION__, pBeamformEntry->mac_id, offset);*/ + + if (_rtw_memcmp(pBeamformEntry->PreCsiReport + offset, pframe+offset, frame_len-offset) == _FALSE) + pBeamformEntry->DefaultCsiCnt = 0; + else + pBeamformEntry->DefaultCsiCnt++; + + _rtw_memcpy(&pBeamformEntry->PreCsiReport, pframe, frame_len); + + pBeamformEntry->bDefaultCSI = _FALSE; + + if (pBeamformEntry->DefaultCsiCnt > 20) + pBeamformEntry->bDefaultCSI = _TRUE; + else + pBeamformEntry->bDefaultCSI = _FALSE; +#endif + return ret; +} + +void beamforming_get_ndpa_frame(PADAPTER Adapter, union recv_frame *precv_frame) +{ +#if (BEAMFORMING_SUPPORT == 1) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + Beamforming_GetNDPAFrame(pDM_Odm, precv_frame); + +#else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/ + u8 *ta; + u8 idx, Sequence; + u8 *pframe = precv_frame->u.hdr.rx_data; + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct beamforming_entry *pBeamformEntry = NULL; + + /*DBG_871X("beamforming_get_ndpa_frame\n");*/ + + if (IS_HARDWARE_TYPE_8812(Adapter) == _FALSE) + return; + else if (GetFrameSubType(pframe) != WIFI_NDPA) + return; + + ta = GetAddr2Ptr(pframe); + /*Remove signaling TA. */ + ta[0] = ta[0] & 0xFE; + + pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ta, &idx); + + if (pBeamformEntry == NULL) + return; + else if (!(pBeamformEntry->beamforming_entry_cap & BEAMFORMEE_CAP_VHT_SU)) + return; + /*LogSuccess: As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is NO LONGER needed !2015-04-10, Jeffery*/ + /*ClockResetTimes: While BFer entry always doesn't receive our CSI, clock will reset again and again.So ClockResetTimes is limited to 5 times.2015-04-13, Jeffery*/ + else if ((pBeamformEntry->LogSuccess == 1) || (pBeamformEntry->ClockResetTimes == 5)) { + DBG_871X("[%s] LogSeq=%d, PreLogSeq=%d\n", __func__, pBeamformEntry->LogSeq, pBeamformEntry->PreLogSeq); + return; + } + + Sequence = (pframe[16]) >> 2; + DBG_871X("[%s] Start, Sequence=%d, LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, ClockResetTimes=%d, LogSuccess=%d\n", + __func__, Sequence, pBeamformEntry->LogSeq, pBeamformEntry->PreLogSeq, pBeamformEntry->LogRetryCnt, pBeamformEntry->ClockResetTimes, pBeamformEntry->LogSuccess); + + if ((pBeamformEntry->LogSeq != 0) && (pBeamformEntry->PreLogSeq != 0)) { + /*Success condition*/ + if ((pBeamformEntry->LogSeq != Sequence) && (pBeamformEntry->PreLogSeq != pBeamformEntry->LogSeq)) { + /* break option for clcok reset, 2015-03-30, Jeffery */ + pBeamformEntry->LogRetryCnt = 0; + /*As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is no longer needed.*/ + /*That is, LogSuccess is NOT needed to be reset to zero, 2015-04-13, Jeffery*/ + pBeamformEntry->LogSuccess = 1; + + } else {/*Fail condition*/ + + if (pBeamformEntry->LogRetryCnt == 5) { + pBeamformEntry->ClockResetTimes++; + pBeamformEntry->LogRetryCnt = 0; + + DBG_871X("[%s] Clock Reset!!! ClockResetTimes=%d\n", __func__, pBeamformEntry->ClockResetTimes); + beamforming_wk_cmd(Adapter, BEAMFORMING_CTRL_SOUNDING_CLK, NULL, 0, 1); + + } else + pBeamformEntry->LogRetryCnt++; + } + } + + /*Update LogSeq & PreLogSeq*/ + pBeamformEntry->PreLogSeq = pBeamformEntry->LogSeq; + pBeamformEntry->LogSeq = Sequence; + +#endif + +} + + + + +void beamforming_wk_hdl(_adapter *padapter, u8 type, u8 *pbuf) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); +_func_enter_; + +#if (BEAMFORMING_SUPPORT == 1) /*(BEAMFORMING_SUPPORT == 1)- for PHYDM beamfoming*/ + switch (type) { + case BEAMFORMING_CTRL_ENTER: + { + struct sta_info *psta = (PVOID)pbuf; + u16 staIdx = psta->mac_id; + + Beamforming_Enter(pDM_Odm, staIdx); + break; + } + case BEAMFORMING_CTRL_LEAVE: + Beamforming_Leave(pDM_Odm, pbuf); + break; + default: + break; + + } +#else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/ + switch (type) { + case BEAMFORMING_CTRL_ENTER: + beamforming_enter(padapter, (PVOID)pbuf); + break; + + case BEAMFORMING_CTRL_LEAVE: + beamforming_leave(padapter, pbuf); + break; + + case BEAMFORMING_CTRL_SOUNDING_FAIL: + beamforming_sounding_fail(padapter); + break; + + case BEAMFORMING_CTRL_SOUNDING_CLK: + rtw_hal_set_hwreg(padapter, HW_VAR_SOUNDING_CLK, NULL); + break; + + default: + break; + } +#endif +_func_exit_; +} + +u8 beamforming_wk_cmd(_adapter*padapter, s32 type, u8 *pbuf, s32 size, u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + if(enqueue) + { + u8 *wk_buf; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + if (pbuf != NULL) { + wk_buf = rtw_zmalloc(size); + if(wk_buf==NULL){ + rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm)); + res= _FAIL; + goto exit; + } + + _rtw_memcpy(wk_buf, pbuf, size); + } else { + wk_buf = NULL; + size = 0; + } + + pdrvextra_cmd_parm->ec_id = BEAMFORMING_WK_CID; + pdrvextra_cmd_parm->type = type; + pdrvextra_cmd_parm->size = size; + pdrvextra_cmd_parm->pbuf = wk_buf; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else + { + beamforming_wk_hdl(padapter, type, pbuf); + } + +exit: + +_func_exit_; + + return res; +} + +void update_attrib_txbf_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta) +{ + if (psta) { + pattrib->txbf_g_id = psta->txbf_gid; + pattrib->txbf_p_aid = psta->txbf_paid; + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_br_ext.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_br_ext.c new file mode 100644 index 00000000..024049cf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_br_ext.c @@ -0,0 +1,1699 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_BR_EXT_C_ + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#endif + +#if 1 // rtw_wifi_driver +#include +#else // rtw_wifi_driver +#include "./8192cd_cfg.h" + +#ifndef __KERNEL__ +#include "./sys-support.h" +#endif + +#include "./8192cd.h" +#include "./8192cd_headers.h" +#include "./8192cd_br_ext.h" +#include "./8192cd_debug.h" +#endif // rtw_wifi_driver + +#ifdef CL_IPV6_PASS +#ifdef __KERNEL__ +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) +#include +#else +#include +#endif +#endif +#endif + +#ifdef CONFIG_BR_EXT + +//#define BR_EXT_DEBUG + +#define NAT25_IPV4 01 +#define NAT25_IPV6 02 +#define NAT25_IPX 03 +#define NAT25_APPLE 04 +#define NAT25_PPPOE 05 + +#define RTL_RELAY_TAG_LEN (ETH_ALEN) +#define TAG_HDR_LEN 4 + +#define MAGIC_CODE 0x8186 +#define MAGIC_CODE_LEN 2 +#define WAIT_TIME_PPPOE 5 // waiting time for pppoe server in sec + +/*----------------------------------------------------------------- + How database records network address: + 0 1 2 3 4 5 6 7 8 9 10 + |----|----|----|----|----|----|----|----|----|----|----| + IPv4 |type| | IP addr | + IPX |type| Net addr | Node addr | + IPX |type| Net addr |Sckt addr| + Apple |type| Network |node| + PPPoE |type| SID | AC MAC | +-----------------------------------------------------------------*/ + + +//Find a tag in pppoe frame and return the pointer +static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) +{ + unsigned char *cur_ptr, *start_ptr; + unsigned short tagLen, tagType; + + start_ptr = cur_ptr = (unsigned char *)ph->tag; + while((cur_ptr - start_ptr) < ntohs(ph->length)) { + // prevent un-alignment access + tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); + tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); + if(tagType == type) + return cur_ptr; + cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen; + } + return 0; +} + + +static __inline__ int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) +{ + struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); + int data_len; + + data_len = tag->tag_len + TAG_HDR_LEN; + if (skb_tailroom(skb) < data_len) { + _DEBUG_ERR("skb_tailroom() failed in add SID tag!\n"); + return -1; + } + + skb_put(skb, data_len); + // have a room for new tag + memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length)); + ph->length = htons(ntohs(ph->length) + data_len); + memcpy((unsigned char *)ph->tag, tag, data_len); + return data_len; +} + +static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) +{ + int tail_len; + unsigned long end, tail; + + if ((src+len) > skb_tail_pointer(skb) || skb->len < len) + return -1; + + tail = (unsigned long)skb_tail_pointer(skb); + end = (unsigned long)src+len; + if (tail < end) + return -1; + + tail_len = (int)(tail-end); + if (tail_len > 0) + memmove(src, src+len, tail_len); + + skb_trim(skb, skb->len-len); + return 0; +} + +static __inline__ unsigned long __nat25_timeout(_adapter *priv) +{ + unsigned long timeout; + + timeout = jiffies - NAT25_AGEING_TIME*HZ; + + return timeout; +} + + +static __inline__ int __nat25_has_expired(_adapter *priv, + struct nat25_network_db_entry *fdb) +{ + if(time_before_eq(fdb->ageing_timer, __nat25_timeout(priv))) + return 1; + + return 0; +} + + +static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, + unsigned int *ipAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPV4; + memcpy(networkAddr+7, (unsigned char *)ipAddr, 4); +} + + +static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr+5, ipxNodeAddr, 6); +} + + +static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, + unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPX; + memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4); + memcpy(networkAddr+5, (unsigned char *)ipxSocketAddr, 2); +} + + +static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr, + unsigned short *network, unsigned char *node) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_APPLE; + memcpy(networkAddr+1, (unsigned char *)network, 2); + networkAddr[3] = *node; +} + + +static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, + unsigned char *ac_mac, unsigned short *sid) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_PPPOE; + memcpy(networkAddr+1, (unsigned char *)sid, 2); + memcpy(networkAddr+3, (unsigned char *)ac_mac, 6); +} + + +#ifdef CL_IPV6_PASS +static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr, + unsigned int *ipAddr) +{ + memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); + + networkAddr[0] = NAT25_IPV6; + memcpy(networkAddr+1, (unsigned char *)ipAddr, 16); +} + + +static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b) +{ + while (len > 0) { + if (*data == tag && *(data+1) == len8b && len >= len8b*8) + return data+2; + + len -= (*(data+1))*8; + data += (*(data+1))*8; + } + return NULL; +} + + +static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac) +{ + struct icmp6hdr *icmphdr = (struct icmp6hdr *)data; + unsigned char *mac; + + if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) { + if (len >= 8) { + mac = scan_tlv(&data[8], len-8, 1, 1); + if (mac) { + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) { + if (len >= 16) { + mac = scan_tlv(&data[16], len-16, 1, 1); + if (mac) { + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) { + if (len >= 24) { + mac = scan_tlv(&data[24], len-24, 1, 1); + if (mac) { + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { + if (len >= 24) { + mac = scan_tlv(&data[24], len-24, 2, 1); + if (mac) { + 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); + return 1; + } + } + } + else if (icmphdr->icmp6_type == NDISC_REDIRECT) { + if (len >= 40) { + mac = scan_tlv(&data[40], len-40, 2, 1); + if (mac) { + 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); + return 1; + } + } + } + return 0; +} + + +static void convert_ipv6_mac_to_mc(struct sk_buff *skb) +{ + struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); + unsigned char *dst_mac = skb->data; + + //dst_mac[0] = 0xff; + //dst_mac[1] = 0xff; + /*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/ + dst_mac[0] = 0x33; + dst_mac[1] = 0x33; + memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4); + #if defined(__LINUX_2_6__) + /*modified by qinjunjie,warning:should not remove next line*/ + skb->pkt_type = PACKET_MULTICAST; + #endif +} +#endif /* CL_IPV6_PASS */ + + +static __inline__ int __nat25_network_hash(unsigned char *networkAddr) +{ + if(networkAddr[0] == NAT25_IPV4) + { + unsigned long x; + + x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_IPX) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ + networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_APPLE) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; + + return x & (NAT25_HASH_SIZE - 1); + } + else if(networkAddr[0] == NAT25_PPPOE) + { + unsigned long x; + + x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; + + return x & (NAT25_HASH_SIZE - 1); + } +#ifdef CL_IPV6_PASS + else if(networkAddr[0] == NAT25_IPV6) + { + unsigned long x; + + x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ + networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^ + networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^ + networkAddr[16]; + + return x & (NAT25_HASH_SIZE - 1); + } +#endif + else + { + unsigned long x = 0; + int i; + + for (i=0; ibr_ext_lock, &irqL); + + ent->next_hash = priv->nethash[hash]; + if(ent->next_hash != NULL) + ent->next_hash->pprev_hash = &ent->next_hash; + priv->nethash[hash] = ent; + ent->pprev_hash = &priv->nethash[hash]; + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static __inline__ void __network_hash_unlink(struct nat25_network_db_entry *ent) +{ + // Caller must _enter_critical_bh already! + //_irqL irqL; + //_enter_critical_bh(&priv->br_ext_lock, &irqL); + + *(ent->pprev_hash) = ent->next_hash; + if(ent->next_hash != NULL) + ent->next_hash->pprev_hash = ent->pprev_hash; + ent->next_hash = NULL; + ent->pprev_hash = NULL; + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static int __nat25_db_network_lookup_and_replace(_adapter *priv, + struct sk_buff *skb, unsigned char *networkAddr) +{ + struct nat25_network_db_entry *db; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + db = priv->nethash[__nat25_network_hash(networkAddr)]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) + { + if(!__nat25_has_expired(priv, db)) + { + // replace the destination mac address + memcpy(skb->data, db->macAddr, ETH_ALEN); + atomic_inc(&db->use_count); + +#ifdef CL_IPV6_PASS + 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], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10], + db->networkAddr[11], + db->networkAddr[12], + db->networkAddr[13], + db->networkAddr[14], + db->networkAddr[15], + db->networkAddr[16]); +#else + 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], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10]); +#endif + } + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return 1; + } + + db = db->next_hash; + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return 0; +} + + +static void __nat25_db_network_insert(_adapter *priv, + unsigned char *macAddr, unsigned char *networkAddr) +{ + struct nat25_network_db_entry *db; + int hash; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + hash = __nat25_network_hash(networkAddr); + db = priv->nethash[hash]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) + { + memcpy(db->macAddr, macAddr, ETH_ALEN); + db->ageing_timer = jiffies; + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return; + } + + db = db->next_hash; + } + + db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db)); + if(db == NULL) { + _exit_critical_bh(&priv->br_ext_lock, &irqL); + return; + } + + memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); + memcpy(db->macAddr, macAddr, ETH_ALEN); + atomic_set(&db->use_count, 1); + db->ageing_timer = jiffies; + + __network_hash_link(priv, db, hash); + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +static void __nat25_db_print(_adapter *priv) +{ + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + +#ifdef BR_EXT_DEBUG + static int counter = 0; + int i, j; + struct nat25_network_db_entry *db; + + counter++; + if((counter % 16) != 0) + return; + + for(i=0, j=0; inethash[i]; + + while (db != NULL) + { +#ifdef CL_IPV6_PASS + panic_printk("NAT25: DB(%d) H(%02d) C(%d) 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", + j, + i, + atomic_read(&db->use_count), + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10], + db->networkAddr[11], + db->networkAddr[12], + db->networkAddr[13], + db->networkAddr[14], + db->networkAddr[15], + db->networkAddr[16]); +#else + panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + j, + i, + atomic_read(&db->use_count), + db->macAddr[0], + db->macAddr[1], + db->macAddr[2], + db->macAddr[3], + db->macAddr[4], + db->macAddr[5], + db->networkAddr[0], + db->networkAddr[1], + db->networkAddr[2], + db->networkAddr[3], + db->networkAddr[4], + db->networkAddr[5], + db->networkAddr[6], + db->networkAddr[7], + db->networkAddr[8], + db->networkAddr[9], + db->networkAddr[10]); +#endif + j++; + + db = db->next_hash; + } + } +#endif + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + + + +/* + * NAT2.5 interface + */ + +void nat25_db_cleanup(_adapter *priv) +{ + int i; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + for(i=0; inethash[i]; + while (f != NULL) { + struct nat25_network_db_entry *g; + + g = f->next_hash; + if(priv->scdb_entry == f) + { + memset(priv->scdb_mac, 0, ETH_ALEN); + memset(priv->scdb_ip, 0, 4); + priv->scdb_entry = NULL; + } + __network_hash_unlink(f); + rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); + + f = g; + } + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +void nat25_db_expire(_adapter *priv) +{ + int i; + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + + //if(!priv->ethBrExtInfo.nat25_disable) + { + for (i=0; inethash[i]; + + while (f != NULL) + { + struct nat25_network_db_entry *g; + g = f->next_hash; + + if(__nat25_has_expired(priv, f)) + { + if(atomic_dec_and_test(&f->use_count)) + { +#ifdef BR_EXT_DEBUG +#ifdef CL_IPV6_PASS + panic_printk("NAT25 Expire H(%02d) 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", + i, + f->macAddr[0], + f->macAddr[1], + f->macAddr[2], + f->macAddr[3], + f->macAddr[4], + f->macAddr[5], + f->networkAddr[0], + f->networkAddr[1], + f->networkAddr[2], + f->networkAddr[3], + f->networkAddr[4], + f->networkAddr[5], + f->networkAddr[6], + f->networkAddr[7], + f->networkAddr[8], + f->networkAddr[9], + f->networkAddr[10], + f->networkAddr[11], + f->networkAddr[12], + f->networkAddr[13], + f->networkAddr[14], + f->networkAddr[15], + f->networkAddr[16]); +#else + + panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + i, + f->macAddr[0], + f->macAddr[1], + f->macAddr[2], + f->macAddr[3], + f->macAddr[4], + f->macAddr[5], + f->networkAddr[0], + f->networkAddr[1], + f->networkAddr[2], + f->networkAddr[3], + f->networkAddr[4], + f->networkAddr[5], + f->networkAddr[6], + f->networkAddr[7], + f->networkAddr[8], + f->networkAddr[9], + f->networkAddr[10]); +#endif +#endif + if(priv->scdb_entry == f) + { + memset(priv->scdb_mac, 0, ETH_ALEN); + memset(priv->scdb_ip, 0, 4); + priv->scdb_entry = NULL; + } + __network_hash_unlink(f); + rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); + } + } + + f = g; + } + } + } + + _exit_critical_bh(&priv->br_ext_lock, &irqL); +} + + +#ifdef SUPPORT_TX_MCAST2UNI +static int checkIPMcAndReplace(_adapter *priv, struct sk_buff *skb, unsigned int *dst_ip) +{ + struct stat_info *pstat; + struct list_head *phead, *plist; + int i; + + phead = &priv->asoc_list; + plist = phead->next; + + while (plist != phead) { + pstat = list_entry(plist, struct stat_info, asoc_list); + plist = plist->next; + + if (pstat->ipmc_num == 0) + continue; + + for (i=0; iipmc[i].used && !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip)+1, 3)) { + memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN); + return 1; + } + } + } + return 0; +} +#endif + +int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) +{ + unsigned short protocol; + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + + if(skb == NULL) + return -1; + + if((method <= NAT25_MIN) || (method >= NAT25_MAX)) + return -1; + + protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); + + /*---------------------------------------------------*/ + /* Handle IP frame */ + /*---------------------------------------------------*/ + if(protocol == __constant_htons(ETH_P_IP)) + { + struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + + if(((unsigned char*)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) + { + DEBUG_WARN("NAT25: malformed IP packet !\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + { + //some muticast with source IP is all zero, maybe other case is illegal + //in class A, B, C, host address is all zero or all one is illegal + if (iph->saddr == 0) + return 0; + 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); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + 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)) + == (WIFI_STATION_STATE|WIFI_ASOC_STATE)) && + !checkIPMcAndReplace(priv, skb, &iph->daddr)) || + (OPMODE & WIFI_ADHOC_STATE))) +#endif + { + __nat25_generate_ipv4_network_addr(networkAddr, &iph->daddr); + + 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 + DBG_871X("NAT25: Set DA as boardcast\n"); + memset(skb->data, 0xff, ETH_ALEN); + } + else { + // forward unknow IP packet to upper TCP/IP + 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"); + netdev_br_init(priv->pnetdev); + } + memcpy(skb->data, priv->br_mac, ETH_ALEN); + } + } + } + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle ARP frame */ + /*---------------------------------------------------*/ + else if(protocol == __constant_htons(ETH_P_ARP)) + { + struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); + unsigned char *arp_ptr = (unsigned char *)(arp + 1); + unsigned int *sender, *target; + + if(arp->ar_pro != __constant_htons(ETH_P_IP)) + { + DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro)); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return 0; // skb_copy for all ARP frame + + case NAT25_INSERT: + { + 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 + memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); + + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + + __nat25_generate_ipv4_network_addr(networkAddr, sender); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DBG_871X("NAT25: Lookup ARP\n"); + + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + arp_ptr += (arp->ar_hln + arp->ar_pln); + target = (unsigned int *)arp_ptr; + + __nat25_generate_ipv4_network_addr(networkAddr, target); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // change to ARP target mac address to Lookup result + arp_ptr = (unsigned char *)(arp + 1); + arp_ptr += (arp->ar_hln + arp->ar_pln); + memcpy(arp_ptr, skb->data, ETH_ALEN); + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle IPX and Apple Talk frame */ + /*---------------------------------------------------*/ + 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; + struct elapaarp *ea = NULL; + struct ddpehdr *ddp = NULL; + unsigned char *framePtr = skb->data + ETH_HLEN; + + if(protocol == __constant_htons(ETH_P_IPX)) + { + DBG_871X("NAT25: Protocol=IPX (Ethernet II)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else //if(protocol <= __constant_htons(ETH_FRAME_LEN)) + { + if(!memcmp(ipx_header, framePtr, 2)) + { + DBG_871X("NAT25: Protocol=IPX (Ethernet 802.3)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else + { + unsigned char ipx_8022_type = 0xE0; + unsigned char snap_8022_type = 0xAA; + + if(*framePtr == snap_8022_type) + { + unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; // IPX SNAP ID + unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; // Apple Talk AARP SNAP ID + unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; // Apple Talk DDP SNAP ID + + framePtr += 3; // eliminate the 802.2 header + + if(!memcmp(ipx_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + DBG_871X("NAT25: Protocol=IPX (Ethernet SNAP)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else if(!memcmp(aarp_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + ea = (struct elapaarp *)framePtr; + } + else if(!memcmp(ddp_snap_id, framePtr, 5)) + { + framePtr += 5; // eliminate the SNAP header + + ddp = (struct ddpehdr *)framePtr; + } + else + { + DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], + framePtr[1], framePtr[2], framePtr[3], framePtr[4]); + return -1; + } + } + else if(*framePtr == ipx_8022_type) + { + framePtr += 3; // eliminate the 802.2 header + + if(!memcmp(ipx_header, framePtr, 2)) + { + DBG_871X("NAT25: Protocol=IPX (Ethernet 802.2)\n"); + ipx = (struct ipxhdr *)framePtr; + } + else + return -1; + } + } + } + + /* IPX */ + if(ipx != NULL) + { + switch(method) + { + case NAT25_CHECK: + if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) + { + DBG_871X("NAT25: Check IPX skb_copy\n"); + return 0; + } + return -1; + + case NAT25_INSERT: + { + 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], + ipx->ipx_dest.node[2], + ipx->ipx_dest.node[3], + ipx->ipx_dest.node[4], + ipx->ipx_dest.node[5], + ipx->ipx_dest.sock, + ipx->ipx_source.net, + ipx->ipx_source.node[0], + ipx->ipx_source.node[1], + ipx->ipx_source.node[2], + ipx->ipx_source.node[3], + ipx->ipx_source.node[4], + ipx->ipx_source.node[5], + ipx->ipx_source.sock); + + if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) + { + 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); + + // change IPX source node addr to wlan STA address + memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); + } + else + { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); + } + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + if(!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) + { + 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); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // replace IPX destination node addr with Lookup destination MAC addr + memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); + } + else + { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + } + return 0; + + default: + return -1; + } + } + + /* AARP */ + else if(ea != NULL) + { + /* Sanity check fields. */ + if(ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) + { + DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + return 0; + + case NAT25_INSERT: + { + // change to AARP source mac address to wlan STA address + memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); + + DBG_871X("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DBG_871X("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); + + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + + // change to AARP destination mac address to Lookup result + memcpy(ea->hw_dst, skb->data, ETH_ALEN); + } + return 0; + + default: + return -1; + } + } + + /* DDP */ + else if(ddp != NULL) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + { + DBG_871X("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + } + return 0; + + case NAT25_LOOKUP: + { + DBG_871X("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); + + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + return 0; + + default: + return -1; + } + } + + return -1; + } + + /*---------------------------------------------------*/ + /* Handle PPPoE frame */ + /*---------------------------------------------------*/ + else if((protocol == __constant_htons(ETH_P_PPP_DISC)) || + (protocol == __constant_htons(ETH_P_PPP_SES))) + { + struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); + unsigned short *pMagic; + + switch(method) + { + case NAT25_CHECK: + if (ph->sid == 0) + return 0; + return 1; + + case NAT25_INSERT: + if(ph->sid == 0) // Discovery phase according to tag + { + if(ph->code == PADI_CODE || ph->code == PADR_CODE) + { + if (priv->ethBrExtInfo.addPPPoETag) { + struct pppoe_tag *tag, *pOldTag; + unsigned char tag_buf[40]; + int old_tag_len=0; + + tag = (struct pppoe_tag *)tag_buf; + pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); + if (pOldTag) { // if SID existed, copy old value and delete it + old_tag_len = ntohs(pOldTag->tag_len); + if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { + DEBUG_ERR("SID tag length too long!\n"); + return -1; + } + + memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, + pOldTag->tag_data, old_tag_len); + + if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); + } + + tag->tag_type = PTT_RELAY_SID; + tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); + + // insert the magic_code+client mac in relay tag + pMagic = (unsigned short *)tag->tag_data; + *pMagic = htons(MAGIC_CODE); + memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); + + //Add relay tag + if(__nat25_add_pppoe_tag(skb, tag) < 0) + return -1; + + DBG_871X("NAT25: Insert PPPoE, forward %s packet\n", + (ph->code == PADI_CODE ? "PADI" : "PADR")); + } + else { // not add relay tag + if (priv->pppoe_connection_in_progress && + memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { + DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); + return -2; + } + + if (priv->pppoe_connection_in_progress == 0) + memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); + + priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; + } + } + else + return -1; + } + else // session phase + { + DBG_871X("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); + + __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); + + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + + if (!priv->ethBrExtInfo.addPPPoETag && + priv->pppoe_connection_in_progress && + !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) + priv->pppoe_connection_in_progress = 0; + } + return 0; + + case NAT25_LOOKUP: + if(ph->code == PADO_CODE || ph->code == PADS_CODE) + { + if (priv->ethBrExtInfo.addPPPoETag) { + struct pppoe_tag *tag; + unsigned char *ptr; + unsigned short tagType, tagLen; + int offset=0; + + if((ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID))) == 0) { + DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n"); + return -1; + } + + tag = (struct pppoe_tag *)ptr; + tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); + tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); + + if((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) { + DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); + return -1; + } + + pMagic = (unsigned short *)tag->tag_data; + if (ntohs(*pMagic) != MAGIC_CODE) { + DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n", + (ph->code == PADO_CODE ? "PADO" : "PADS")); + return -1; + } + + memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN); + + if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN) + offset = TAG_HDR_LEN; + + if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset)); + if (offset > 0) + tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN); + + 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 + if (!priv->pppoe_connection_in_progress) { + DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n"); + return -1; + } + memcpy(skb->data, priv->pppoe_addr, ETH_ALEN); + priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; + } + } + else { + if(ph->sid != 0) + { + 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); + + __nat25_db_print(priv); + } + else + return -1; + + } + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle EAP frame */ + /*---------------------------------------------------*/ + else if(protocol == __constant_htons(0x888e)) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + return 0; + + case NAT25_LOOKUP: + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle C-Media proprietary frame */ + /*---------------------------------------------------*/ + else if((protocol == __constant_htons(0xe2ae)) || + (protocol == __constant_htons(0xe2af))) + { + switch(method) + { + case NAT25_CHECK: + return -1; + + case NAT25_INSERT: + return 0; + + case NAT25_LOOKUP: + return 0; + + default: + return -1; + } + } + + /*---------------------------------------------------*/ + /* Handle IPV6 frame */ + /*---------------------------------------------------*/ +#ifdef CL_IPV6_PASS + else if(protocol == __constant_htons(ETH_P_IPV6)) + { + struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); + + if (sizeof(*iph) >= (skb->len - ETH_HLEN)) + { + DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); + return -1; + } + + switch(method) + { + case NAT25_CHECK: + if (skb->data[0] & 1) + return 0; + return -1; + + case NAT25_INSERT: + { + 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], + iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); + + if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); + + if (iph->nexthdr == IPPROTO_ICMPV6 && + skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { + if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), + skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { + struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); + hdr->icmp6_cksum = 0; + hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, + iph->payload_len, + IPPROTO_ICMPV6, + csum_partial((__u8 *)hdr, iph->payload_len, 0)); + } + } + } + } + return 0; + + case NAT25_LOOKUP: + 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], + iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); + + + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); + if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { +#ifdef SUPPORT_RX_UNI2MCAST + if (iph->daddr.s6_addr[0] == 0xff) + convert_ipv6_mac_to_mc(skb); +#endif + } + return 0; + + default: + return -1; + } + } +#endif // CL_IPV6_PASS + + return -1; +} + + +int nat25_handle_frame(_adapter *priv, struct sk_buff *skb) +{ +#ifdef BR_EXT_DEBUG + if((!priv->ethBrExtInfo.nat25_disable) && (!(skb->data[0] & 1))) + { + panic_printk("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n", + skb->data[0], + skb->data[1], + skb->data[2], + skb->data[3], + skb->data[4], + skb->data[5], + skb->data[6], + skb->data[7], + skb->data[8], + skb->data[9], + skb->data[10], + skb->data[11]); + } +#endif + + if(!(skb->data[0] & 1)) + { + int is_vlan_tag=0, i, retval=0; + unsigned short vlan_hdr=0; + + if (*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2)); + skb_pull(skb, 4); + } + + if (!priv->ethBrExtInfo.nat25_disable) + { + _irqL irqL; + _enter_critical_bh(&priv->br_ext_lock, &irqL); + /* + * This function look up the destination network address from + * the NAT2.5 database. Return value = -1 means that the + * corresponding network protocol is NOT support. + */ + if (!priv->ethBrExtInfo.nat25sc_disable && + (*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) && + !memcmp(priv->scdb_ip, skb->data+ETH_HLEN+16, 4)) { + memcpy(skb->data, priv->scdb_mac, ETH_ALEN); + + _exit_critical_bh(&priv->br_ext_lock, &irqL); + } + else { + _exit_critical_bh(&priv->br_ext_lock, &irqL); + + retval = nat25_db_handle(priv, skb, NAT25_LOOKUP); + } + } + else { + if (((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) && + !memcmp(priv->br_ip, skb->data+ETH_HLEN+16, 4)) || + ((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_ARP)) && + !memcmp(priv->br_ip, skb->data+ETH_HLEN+24, 4))) { + // for traffic to upper TCP/IP + retval = nat25_db_handle(priv, skb, NAT25_LOOKUP); + } + } + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr; + } + + if(retval == -1) { + //DEBUG_ERR("NAT25: Lookup fail!\n"); + return -1; + } + } + + return 0; +} + +#if 0 +void mac_clone(_adapter *priv, unsigned char *addr) +{ + struct sockaddr sa; + + memcpy(sa.sa_data, addr, ETH_ALEN); + 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); +} + + +int mac_clone_handle_frame(_adapter *priv, struct sk_buff *skb) +{ + if(priv->ethBrExtInfo.macclone_enable && !priv->macclone_completed) + { + if(!(skb->data[ETH_ALEN] & 1)) //// check any other particular MAC add + { + if(memcmp(skb->data+ETH_ALEN, GET_MY_HWADDR(priv), ETH_ALEN) && + ((priv->dev->br_port) && + memcmp(skb->data+ETH_ALEN, priv->br_mac, ETH_ALEN))) + { + mac_clone(priv, skb->data+ETH_ALEN); + priv->macclone_completed = 1; + } + } + } + + return 0; +} +#endif // 0 + +#define SERVER_PORT 67 +#define CLIENT_PORT 68 +#define DHCP_MAGIC 0x63825363 +#define BROADCAST_FLAG 0x8000 + +struct dhcpMessage { + u_int8_t op; + u_int8_t htype; + u_int8_t hlen; + u_int8_t hops; + u_int32_t xid; + u_int16_t secs; + u_int16_t flags; + u_int32_t ciaddr; + u_int32_t yiaddr; + u_int32_t siaddr; + u_int32_t giaddr; + u_int8_t chaddr[16]; + u_int8_t sname[64]; + u_int8_t file[128]; + u_int32_t cookie; + u_int8_t options[308]; /* 312 - cookie */ +}; + +void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb) +{ + if(skb == NULL) + return; + + if(!priv->ethBrExtInfo.dhcp_bcst_disable) + { + unsigned short protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN)); + + if(protocol == __constant_htons(ETH_P_IP)) // IP + { + struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + + if(iph->protocol == IPPROTO_UDP) // UDP + { + struct udphdr *udph = (struct udphdr *)((SIZE_PTR)iph + (iph->ihl << 2)); + + if((udph->source == __constant_htons(CLIENT_PORT)) + && (udph->dest == __constant_htons(SERVER_PORT))) // DHCP request + { + struct dhcpMessage *dhcph = + (struct dhcpMessage *)((SIZE_PTR)udph + sizeof(struct udphdr)); + + if(dhcph->cookie == __constant_htonl(DHCP_MAGIC)) // match magic word + { + if(!(dhcph->flags & htons(BROADCAST_FLAG))) // if not broadcast + { + register int sum = 0; + + DBG_871X("DHCP: change flag of DHCP request to broadcast.\n"); + // or BROADCAST flag + dhcph->flags |= htons(BROADCAST_FLAG); + // recalculate checksum + sum = ~(udph->check) & 0xffff; + sum += dhcph->flags; + while(sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + udph->check = ~sum; + } + } + } + } + } + } +} + + +void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, + unsigned char *ipAddr) +{ + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; + struct nat25_network_db_entry *db; + int hash; + //_irqL irqL; + //_enter_critical_bh(&priv->br_ext_lock, &irqL); + + __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); + hash = __nat25_network_hash(networkAddr); + db = priv->nethash[hash]; + while (db != NULL) + { + if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { + //_exit_critical_bh(&priv->br_ext_lock, &irqL); + return (void *)db; + } + + db = db->next_hash; + } + + //_exit_critical_bh(&priv->br_ext_lock, &irqL); + return NULL; +} + +#endif // CONFIG_BR_EXT + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_bt_mp.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_bt_mp.c new file mode 100644 index 00000000..30cf14e5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_bt_mp.c @@ -0,0 +1,1753 @@ +/****************************************************************************** + * + * 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 + +#if defined(CONFIG_RTL8723B) +#include +#endif + +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A) +void MPh2c_timeout_handle(void *FunctionContext) +{ + PADAPTER pAdapter; + PMPT_CONTEXT pMptCtx; + + + DBG_8192C("[MPT], MPh2c_timeout_handle \n"); + + pAdapter = (PADAPTER)FunctionContext; + pMptCtx = &pAdapter->mppriv.MptCtx; + + pMptCtx->bMPh2c_timeout = _TRUE; + + if ((_FALSE == pMptCtx->MptH2cRspEvent) + || ((_TRUE == pMptCtx->MptH2cRspEvent) + && (_FALSE == pMptCtx->MptBtC2hEvent))) + { + _rtw_up_sema(&pMptCtx->MPh2c_Sema); + } +} + +u32 WaitC2Hevent(PADAPTER pAdapter, u8 *C2H_event, u32 delay_time) +{ + PMPT_CONTEXT pMptCtx=&(pAdapter->mppriv.MptCtx); + pMptCtx->bMPh2c_timeout=_FALSE; + + if( pAdapter->registrypriv.mp_mode == 0 ) + { + DBG_8192C("[MPT], Error!! WaitC2Hevent mp_mode == 0!!\n"); + return _FALSE; + } + + _set_timer( &pMptCtx->MPh2c_timeout_timer, delay_time ); + + _rtw_down_sema(&pMptCtx->MPh2c_Sema); + + if (pMptCtx->bMPh2c_timeout == _TRUE) + { + *C2H_event = _FALSE; + + return _FALSE; + } + + // for safty, cancel timer here again + _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer); + + return _TRUE; +} + +BT_CTRL_STATUS +mptbt_CheckC2hFrame( + PADAPTER Adapter, + PBT_H2C pH2c, + PBT_EXT_C2H pExtC2h + ) +{ + BT_CTRL_STATUS c2hStatus = BT_STATUS_C2H_SUCCESS; + + //DBG_8192C("[MPT], MPT rsp C2H hex: %x %x %x %x %x %x \n"), pExtC2h , pExtC2h+1 ,pExtC2h+2 ,pExtC2h+3 ,pExtC2h+4 ,pExtC2h+5); + + DBG_8192C("[MPT], statusCode = 0x%x\n", pExtC2h->statusCode); + DBG_8192C("[MPT], retLen = %d\n", pExtC2h->retLen); + DBG_8192C("[MPT], opCodeVer : req/rsp=%d/%d\n", pH2c->opCodeVer, pExtC2h->opCodeVer); + DBG_8192C("[MPT], reqNum : req/rsp=%d/%d\n", pH2c->reqNum, pExtC2h->reqNum); + if(pExtC2h->reqNum != pH2c->reqNum) + { + c2hStatus = BT_STATUS_C2H_REQNUM_MISMATCH; + DBG_8192C("[MPT], Error!! C2H reqNum Mismatch!!\n"); + } + else if(pExtC2h->opCodeVer != pH2c->opCodeVer) + { + c2hStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH; + DBG_8192C("[MPT], Error!! OPCode version L mismatch!!\n"); + } + + return c2hStatus; +} + +BT_CTRL_STATUS +mptbt_SendH2c( + PADAPTER Adapter, + PBT_H2C pH2c, + u2Byte h2cCmdLen + ) +{ + //KIRQL OldIrql = KeGetCurrentIrql(); + BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS; + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + u1Byte i; + + DBG_8192C("[MPT], mptbt_SendH2c()=========>\n"); + + //PlatformResetEvent(&pMptCtx->MptH2cRspEvent); + //PlatformResetEvent(&pMptCtx->MptBtC2hEvent); + +// if(OldIrql == PASSIVE_LEVEL) +// { + //RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex: \n"), pH2c, h2cCmdLen); + + for(i=0; iMptH2cRspEvent = _FALSE; + pMptCtx->MptBtC2hEvent = _FALSE; + +#if defined(CONFIG_RTL8723B) + rtl8723b_set_FwBtMpOper_cmd(Adapter, pH2c->opCode, pH2c->opCodeVer, pH2c->reqNum, pH2c->buf); +#endif + pMptCtx->h2cReqNum++; + pMptCtx->h2cReqNum %= 16; + + if(WaitC2Hevent(Adapter, &pMptCtx->MptH2cRspEvent, 100)) + { + DBG_8192C("[MPT], Received WiFi MptH2cRspEvent!!!\n"); + if(WaitC2Hevent(Adapter, &pMptCtx->MptBtC2hEvent, 400)) + { + DBG_8192C("[MPT], Received MptBtC2hEvent!!!\n"); + break; + } + else + { + DBG_8192C("[MPT], Error!!BT MptBtC2hEvent timeout!!\n"); + h2cStatus = BT_STATUS_H2C_BT_NO_RSP; + } + } + else + { + DBG_8192C("[MPT], Error!!WiFi MptH2cRspEvent timeout!!\n"); + h2cStatus = BT_STATUS_H2C_TIMTOUT; + } + } +// } +// else +// { +// RT_ASSERT(FALSE, ("[MPT], mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n")); +// h2cStatus = BT_STATUS_WRONG_LEVEL; +// } + + DBG_8192C("[MPT], mptbt_SendH2c()<=========\n"); + return h2cStatus; +} + + + +BT_CTRL_STATUS +mptbt_CheckBtRspStatus( + PADAPTER Adapter, + PBT_EXT_C2H pExtC2h + ) +{ + BT_CTRL_STATUS retStatus=BT_OP_STATUS_SUCCESS; + + switch(pExtC2h->statusCode) + { + case BT_OP_STATUS_SUCCESS: + retStatus = BT_STATUS_BT_OP_SUCCESS; + DBG_8192C("[MPT], BT status : BT_STATUS_SUCCESS\n"); + break; + case BT_OP_STATUS_VERSION_MISMATCH: + retStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH; + DBG_8192C("[MPT], BT status : BT_STATUS_OPCODE_L_VERSION_MISMATCH\n"); + break; + case BT_OP_STATUS_UNKNOWN_OPCODE: + retStatus = BT_STATUS_UNKNOWN_OPCODE_L; + DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_OPCODE_L\n"); + break; + case BT_OP_STATUS_ERROR_PARAMETER: + retStatus = BT_STATUS_PARAMETER_FORMAT_ERROR_L; + DBG_8192C("[MPT], BT status : BT_STATUS_PARAMETER_FORMAT_ERROR_L\n"); + break; + default: + retStatus = BT_STATUS_UNKNOWN_STATUS_L; + DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n"); + break; + } + + return retStatus; +} + + + +BT_CTRL_STATUS +mptbt_BtFwOpCodeProcess( + PADAPTER Adapter, + u1Byte btFwOpCode, + u1Byte opCodeVer, + pu1Byte pH2cPar, + u1Byte h2cParaLen + ) +{ + u1Byte H2C_Parameter[6] ={0}; + PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0]; + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0]; + u2Byte paraLen=0,i; + BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS, c2hStatus=BT_STATUS_C2H_SUCCESS; + BT_CTRL_STATUS retStatus=BT_STATUS_H2C_BT_NO_RSP; + + if( Adapter->registrypriv.mp_mode == 0 ) + { + DBG_8192C("[MPT], Error!! mptbt_BtFwOpCodeProces mp_mode == 0!!\n"); + return _FALSE; + } + + pH2c->opCode = btFwOpCode; + pH2c->opCodeVer = opCodeVer; + pH2c->reqNum = pMptCtx->h2cReqNum; + //PlatformMoveMemory(&pH2c->buf[0], pH2cPar, h2cParaLen); + //_rtw_memcpy(&pH2c->buf[0], pH2cPar, h2cParaLen); + _rtw_memcpy(pH2c->buf, pH2cPar, h2cParaLen); + + DBG_8192C("[MPT], pH2c->opCode=%d\n", pH2c->opCode); + DBG_8192C("[MPT], pH2c->opCodeVer=%d\n", pH2c->opCodeVer); + DBG_8192C("[MPT], pH2c->reqNum=%d\n", pH2c->reqNum); + DBG_8192C("[MPT], h2c parameter length=%d\n", h2cParaLen); + for (i=0; ibuf[i]); + } + + h2cStatus = mptbt_SendH2c(Adapter, pH2c, h2cParaLen+2); + if(BT_STATUS_H2C_SUCCESS == h2cStatus) + { + // if reach here, it means H2C get the correct c2h response, + c2hStatus = mptbt_CheckC2hFrame(Adapter, pH2c, pExtC2h); + if(BT_STATUS_C2H_SUCCESS == c2hStatus) + { + retStatus = mptbt_CheckBtRspStatus(Adapter, pExtC2h); + } + else + { + DBG_8192C("[MPT], Error!! C2H failed for pH2c->opCode=%d\n", pH2c->opCode); + // check c2h status error, return error status code to upper layer. + retStatus = c2hStatus; + } + } + else + { + DBG_8192C("[MPT], Error!! H2C failed for pH2c->opCode=%d\n", pH2c->opCode); + // check h2c status error, return error status code to upper layer. + retStatus = h2cStatus; + } + + return retStatus; +} + + + + +u2Byte +mptbt_BtReady( + PADAPTER Adapter, + PBT_REQ_CMD pBtReq, + PBT_RSP_CMD pBtRsp + ) +{ + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0]; + u1Byte i; + u1Byte btFwVer=0, bdAddr[6]={0}; + u2Byte btRealFwVer=0; + pu2Byte pu2Tmp=NULL; + + // + // check upper layer parameters + // + + // 1. check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + + pBtRsp->pParamStart[0] = MP_BT_NOT_READY; + paraLen = 10; + // + // execute lower layer opcodes + // + + // Get BT FW version + // fill h2c parameters + btOpcode = BT_LO_OP_GET_BT_VERSION; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + else + { + pu2Tmp = (pu2Byte)&pExtC2h->buf[0]; + btRealFwVer = *pu2Tmp; + btFwVer = pExtC2h->buf[1]; + DBG_8192C("[MPT], btRealFwVer=0x%x, btFwVer=0x%x\n", btRealFwVer, btFwVer); + } + + // Get BD Address + // fill h2c parameters + btOpcode = BT_LO_OP_GET_BD_ADDR_L; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + else + { + bdAddr[5] = pExtC2h->buf[0]; + bdAddr[4] = pExtC2h->buf[1]; + bdAddr[3] = pExtC2h->buf[2]; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_GET_BD_ADDR_H; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + else + { + bdAddr[2] = pExtC2h->buf[0]; + bdAddr[1] = pExtC2h->buf[1]; + bdAddr[0] = pExtC2h->buf[2]; + } + DBG_8192C("[MPT], Local BDAddr:"); + for(i=0; i<6; i++) + { + DBG_8192C(" 0x%x ", bdAddr[i]); + } + pBtRsp->status = BT_STATUS_SUCCESS; + pBtRsp->pParamStart[0] = MP_BT_READY; + pu2Tmp = (pu2Byte)&pBtRsp->pParamStart[1]; + *pu2Tmp = btRealFwVer; + pBtRsp->pParamStart[3] = btFwVer; + for(i=0; i<6; i++) + { + pBtRsp->pParamStart[4+i] = bdAddr[5-i]; + } + + return paraLen; +} + +void mptbt_close_WiFiRF(PADAPTER Adapter) +{ + PHY_SetBBReg(Adapter, 0x824, 0xF, 0x0); + PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x0); + PHY_SetRFReg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x0); +} + +void mptbt_open_WiFiRF(PADAPTER Adapter) +{ + PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x3); + PHY_SetBBReg(Adapter, 0x824, 0xF, 0x2); + PHY_SetRFReg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x3); +} + +u4Byte mptbt_switch_RF(PADAPTER Adapter, u1Byte Enter) +{ + u2Byte tmp_2byte = 0; + + //Enter test mode + if (Enter) { + ////1>. close WiFi RF + mptbt_close_WiFiRF(Adapter); + + ////2>. change ant switch to BT + tmp_2byte = rtw_read16(Adapter, 0x860); + tmp_2byte = tmp_2byte | BIT(9); + tmp_2byte = tmp_2byte & (~BIT(8)); + rtw_write16(Adapter, 0x860, tmp_2byte); + rtw_write16(Adapter, 0x870, 0x300); + } else { + ////1>. Open WiFi RF + mptbt_open_WiFiRF(Adapter); + + ////2>. change ant switch back + tmp_2byte = rtw_read16(Adapter, 0x860); + tmp_2byte = tmp_2byte | BIT(8); + tmp_2byte = tmp_2byte & (~BIT(9)); + rtw_write16(Adapter, 0x860, tmp_2byte); + rtw_write16(Adapter, 0x870, 0x300); + } + + return 0; +} + +u2Byte +mptbt_BtSetMode( + PADAPTER Adapter, + PBT_REQ_CMD pBtReq, + PBT_RSP_CMD pBtRsp + ) +{ + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + u1Byte btModeToSet=0; + + // + // check upper layer parameters + // + // 1. check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + // 2. check upper layer parameter length + if(1 == pBtReq->paraLength) + { + btModeToSet = pBtReq->pParamStart[0]; + DBG_8192C("[MPT], BtTestMode=%d \n", btModeToSet); + } + else + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + + // + // execute lower layer opcodes + // + + // 1. fill h2c parameters + // check bt mode + btOpcode = BT_LO_OP_SET_BT_MODE; + if(btModeToSet >= MP_BT_MODE_MAX) + { + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + mptbt_switch_RF(Adapter, 1); + + h2cParaBuf[0] = btModeToSet; + h2cParaLen = 1; + // 2. execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // 3. construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS == retStatus) + { + pBtRsp->status = BT_STATUS_SUCCESS; + } + else + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + } + + return paraLen; +} + + +VOID +MPTBT_FwC2hBtMpCtrl( + PADAPTER Adapter, + pu1Byte tmpBuf, + u1Byte length + ) +{ + u32 i; + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)tmpBuf; + + if(Adapter->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0 ) + { + //DBG_8192C("Ignore C2H BT MP Info since not in MP mode \n"); + return; + } + if( length > 32 || length < 3 ) + { + DBG_8192C("\n [MPT], pExtC2h->buf hex: length=%d > 32 || < 3\n",length); + return; + } + + //cancel_timeout for h2c handle + _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer); + + for (i=0; iextendId=0x%x\n", pExtC2h->extendId); + + switch(pExtC2h->extendId) + { + case EXT_C2H_WIFI_FW_ACTIVE_RSP: + DBG_8192C("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n"); +#if 0 + DBG_8192C("[MPT], pExtC2h->buf hex: \n"); + for (i=0; i<(length-3); i++) + { + DBG_8192C(" 0x%x ", pExtC2h->buf[i]); + } +#endif + if ((_FALSE == pMptCtx->bMPh2c_timeout) + && (_FALSE == pMptCtx->MptH2cRspEvent)) + { + pMptCtx->MptH2cRspEvent = _TRUE; + _rtw_up_sema(&pMptCtx->MPh2c_Sema); + } + break; + + case EXT_C2H_TRIG_BY_BT_FW: + DBG_8192C("[MPT], EXT_C2H_TRIG_BY_BT_FW\n"); + _rtw_memcpy(&pMptCtx->c2hBuf[0], tmpBuf, length); + DBG_8192C("[MPT], pExtC2h->statusCode=0x%x\n", pExtC2h->statusCode); + DBG_8192C("[MPT], pExtC2h->retLen=0x%x\n", pExtC2h->retLen); + DBG_8192C("[MPT], pExtC2h->opCodeVer=0x%x\n", pExtC2h->opCodeVer); + DBG_8192C("[MPT], pExtC2h->reqNum=0x%x\n", pExtC2h->reqNum); + for (i=0; i<(length-3); i++) + { + DBG_8192C("[MPT], pExtC2h->buf[%d]=0x%02x\n", i, pExtC2h->buf[i]); + } + + if ((_FALSE == pMptCtx->bMPh2c_timeout) + && (_TRUE == pMptCtx->MptH2cRspEvent) + && (_FALSE == pMptCtx->MptBtC2hEvent)) + { + pMptCtx->MptBtC2hEvent = _TRUE; + _rtw_up_sema(&pMptCtx->MPh2c_Sema); + } + break; + + default: + DBG_8192C("[MPT], EXT_C2H Target not found,pExtC2h->extendId =%d ,pExtC2h->reqNum=%d\n",pExtC2h->extendId,pExtC2h->reqNum); + break; + } + + + +} + + +u2Byte +mptbt_BtGetGeneral( + IN PADAPTER Adapter, + IN PBT_REQ_CMD pBtReq, + IN PBT_RSP_CMD pBtRsp + ) +{ + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0]; + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode, bdAddr[6]={0}; + u1Byte btOpcodeVer=0; + u1Byte getType=0, i; + u2Byte getParaLen=0, validParaLen=0; + u1Byte regType=0, reportType=0; + u4Byte regAddr=0, regValue=0; + pu4Byte pu4Tmp; + pu2Byte pu2Tmp; + pu1Byte pu1Tmp; + + // + // check upper layer parameters + // + + // check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + // check upper layer parameter length + if(pBtReq->paraLength < 1) + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + getParaLen = pBtReq->paraLength - 1; + getType = pBtReq->pParamStart[0]; + + DBG_8192C("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen); + + // check parameter first + switch(getType) + { + case BT_GGET_REG: + DBG_8192C("[MPT], [BT_GGET_REG]\n"); + validParaLen = 5; + if(getParaLen == validParaLen) + { + btOpcode = BT_LO_OP_READ_REG; + regType = pBtReq->pParamStart[1]; + pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2]; + regAddr = *pu4Tmp; + DBG_8192C("[MPT], BT_GGET_REG regType=0x%02x, regAddr=0x%08x!!\n", + regType, regAddr); + if(regType >= BT_REG_MAX) + { + pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) || + ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) || + ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) || + ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) || + ((BT_REG_LE==regType)&&(regAddr>0xfff)) ) + { + pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + } + } + break; + case BT_GGET_STATUS: + DBG_8192C("[MPT], [BT_GGET_STATUS]\n"); + validParaLen = 0; + break; + case BT_GGET_REPORT: + DBG_8192C("[MPT], [BT_GGET_REPORT]\n"); + validParaLen = 1; + if(getParaLen == validParaLen) + { + reportType = pBtReq->pParamStart[1]; + DBG_8192C("[MPT], BT_GGET_REPORT reportType=0x%x!!\n", reportType); + if(reportType >= BT_REPORT_MAX) + { + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + } + break; + default: + { + DBG_8192C("[MPT], Error!! getType=%d, out of range\n", getType); + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + break; + } + if(getParaLen != validParaLen) + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_GET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n", + getParaLen, getType, validParaLen); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + + // + // execute lower layer opcodes + // + if(BT_GGET_REG == getType) + { + // fill h2c parameters + // here we should write reg value first then write the address, adviced by Austin + btOpcode = BT_LO_OP_READ_REG; + h2cParaBuf[0] = regType; + h2cParaBuf[1] = pBtReq->pParamStart[2]; + h2cParaBuf[2] = pBtReq->pParamStart[3]; + h2cParaLen = 3; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + pu2Tmp = (pu2Byte)&pExtC2h->buf[0]; + regValue = *pu2Tmp; + DBG_8192C("[MPT], read reg regType=0x%02x, regAddr=0x%08x, regValue=0x%04x\n", + regType, regAddr, regValue); + + pu4Tmp = (pu4Byte)&pBtRsp->pParamStart[0]; + *pu4Tmp = regValue; + paraLen = 4; + } + else if(BT_GGET_STATUS == getType) + { + btOpcode = BT_LO_OP_GET_BT_STATUS; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + pBtRsp->pParamStart[0] = pExtC2h->buf[0]; + pBtRsp->pParamStart[1] = pExtC2h->buf[1]; + DBG_8192C("[MPT], read bt status, testMode=0x%x, testStatus=0x%x\n", + pBtRsp->pParamStart[0], pBtRsp->pParamStart[1]); + paraLen = 2; + } + else if(BT_GGET_REPORT == getType) + { + switch(reportType) + { + case BT_REPORT_RX_PACKET_CNT: + { + DBG_8192C("[MPT], [Rx Packet Counts]\n"); + btOpcode = BT_LO_OP_GET_RX_PKT_CNT_L; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[0] = pExtC2h->buf[0]; + pBtRsp->pParamStart[1] = pExtC2h->buf[1]; + + btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[2] = pExtC2h->buf[0]; + pBtRsp->pParamStart[3] = pExtC2h->buf[1]; + paraLen = 4; + } + break; + case BT_REPORT_RX_ERROR_BITS: + { + DBG_8192C("[MPT], [Rx Error Bits]\n"); + btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_L; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[0] = pExtC2h->buf[0]; + pBtRsp->pParamStart[1] = pExtC2h->buf[1]; + + btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[2] = pExtC2h->buf[0]; + pBtRsp->pParamStart[3] = pExtC2h->buf[1]; + paraLen = 4; + } + break; + case BT_REPORT_RSSI: + { + DBG_8192C("[MPT], [RSSI]\n"); + btOpcode = BT_LO_OP_GET_RSSI; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[0] = pExtC2h->buf[0]; + pBtRsp->pParamStart[1] = pExtC2h->buf[1]; + paraLen = 2; + } + break; + case BT_REPORT_CFO_HDR_QUALITY: + { + DBG_8192C("[MPT], [CFO & Header Quality]\n"); + btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_L; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[0] = pExtC2h->buf[0]; + pBtRsp->pParamStart[1] = pExtC2h->buf[1]; + + btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + pBtRsp->pParamStart[2] = pExtC2h->buf[0]; + pBtRsp->pParamStart[3] = pExtC2h->buf[1]; + paraLen = 4; + } + break; + case BT_REPORT_CONNECT_TARGET_BD_ADDR: + { + DBG_8192C("[MPT], [Connected Target BD ADDR]\n"); + btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_L; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + bdAddr[5] = pExtC2h->buf[0]; + bdAddr[4] = pExtC2h->buf[1]; + bdAddr[3] = pExtC2h->buf[2]; + + btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + bdAddr[2] = pExtC2h->buf[0]; + bdAddr[1] = pExtC2h->buf[1]; + bdAddr[0] = pExtC2h->buf[2]; + + DBG_8192C("[MPT], Connected Target BDAddr:%s", bdAddr); + for(i=0; i<6; i++) + { + pBtRsp->pParamStart[i] = bdAddr[5-i]; + } + paraLen = 6; + } + break; + default: + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + break; + } + } + + pBtRsp->status = BT_STATUS_SUCCESS; + return paraLen; +} + + + +u2Byte +mptbt_BtSetGeneral( + IN PADAPTER Adapter, + IN PBT_REQ_CMD pBtReq, + IN PBT_RSP_CMD pBtRsp + ) +{ + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + u1Byte setType=0; + u2Byte setParaLen=0, validParaLen=0; + u1Byte regType=0, bdAddr[6]={0}, calVal=0; + u4Byte regAddr=0, regValue=0; + pu4Byte pu4Tmp; + pu2Byte pu2Tmp; + pu1Byte pu1Tmp; + + // + // check upper layer parameters + // + + // check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + // check upper layer parameter length + if(pBtReq->paraLength < 1) + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + setParaLen = pBtReq->paraLength - 1; + setType = pBtReq->pParamStart[0]; + + DBG_8192C("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen); + + // check parameter first + switch(setType) + { + case BT_GSET_REG: + DBG_8192C ("[MPT], [BT_GSET_REG]\n"); + validParaLen = 9; + if(setParaLen == validParaLen) + { + btOpcode = BT_LO_OP_WRITE_REG_VALUE; + regType = pBtReq->pParamStart[1]; + pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2]; + regAddr = *pu4Tmp; + pu4Tmp = (pu4Byte)&pBtReq->pParamStart[6]; + regValue = *pu4Tmp; + DBG_8192C("[MPT], BT_GSET_REG regType=0x%x, regAddr=0x%x, regValue=0x%x!!\n", + regType, regAddr, regValue); + if(regType >= BT_REG_MAX) + { + pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) || + ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) || + ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) || + ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) || + ((BT_REG_LE==regType)&&(regAddr>0xfff)) ) + { + pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + } + } + break; + case BT_GSET_RESET: + DBG_8192C("[MPT], [BT_GSET_RESET]\n"); + validParaLen = 0; + break; + case BT_GSET_TARGET_BD_ADDR: + DBG_8192C("[MPT], [BT_GSET_TARGET_BD_ADDR]\n"); + validParaLen = 6; + if(setParaLen == validParaLen) + { + btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H; + if( (pBtReq->pParamStart[1]==0) && + (pBtReq->pParamStart[2]==0) && + (pBtReq->pParamStart[3]==0) && + (pBtReq->pParamStart[4]==0) && + (pBtReq->pParamStart[5]==0) && + (pBtReq->pParamStart[6]==0) ) + { + DBG_8192C("[MPT], Error!! targetBDAddr=all zero\n"); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + if( (pBtReq->pParamStart[1]==0xff) && + (pBtReq->pParamStart[2]==0xff) && + (pBtReq->pParamStart[3]==0xff) && + (pBtReq->pParamStart[4]==0xff) && + (pBtReq->pParamStart[5]==0xff) && + (pBtReq->pParamStart[6]==0xff) ) + { + DBG_8192C("[MPT], Error!! targetBDAddr=all 0xf\n"); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + bdAddr[0] = pBtReq->pParamStart[6]; + bdAddr[1] = pBtReq->pParamStart[5]; + bdAddr[2] = pBtReq->pParamStart[4]; + bdAddr[3] = pBtReq->pParamStart[3]; + bdAddr[4] = pBtReq->pParamStart[2]; + bdAddr[5] = pBtReq->pParamStart[1]; + DBG_8192C ("[MPT], target BDAddr:%x,%x,%x,%x,%x,%x\n", + bdAddr[0],bdAddr[1],bdAddr[2],bdAddr[3],bdAddr[4],bdAddr[5]); + } + break; + case BT_GSET_TX_PWR_FINETUNE: + DBG_8192C("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n"); + validParaLen = 1; + if(setParaLen == validParaLen) + { + btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION; + calVal = pBtReq->pParamStart[1]; + if( (calVal<1) || (calVal>9) ) + { + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + DBG_8192C ("[MPT], calVal=%d\n", calVal); + } + break; + case BT_SET_TRACKING_INTERVAL: + DBG_871X("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d \n",setParaLen); + + validParaLen = 1; + if(setParaLen == validParaLen) + calVal = pBtReq->pParamStart[1]; + break; + case BT_SET_THERMAL_METER: + DBG_871X("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d \n",setParaLen); + validParaLen = 1; + if(setParaLen == validParaLen) + calVal = pBtReq->pParamStart[1]; + break; + case BT_ENABLE_CFO_TRACKING: + DBG_871X("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d \n",setParaLen); + validParaLen = 1; + if(setParaLen == validParaLen) + calVal = pBtReq->pParamStart[1]; + break; + case BT_GSET_UPDATE_BT_PATCH: + + break; + default: + { + DBG_8192C ("[MPT], Error!! setType=%d, out of range\n", setType); + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + break; + } + if(setParaLen != validParaLen) + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_SET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n", + setParaLen, setType, validParaLen); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + + // + // execute lower layer opcodes + // + if(BT_GSET_REG == setType) + { + // fill h2c parameters + // here we should write reg value first then write the address, adviced by Austin + btOpcode = BT_LO_OP_WRITE_REG_VALUE; + h2cParaBuf[0] = pBtReq->pParamStart[6]; + h2cParaBuf[1] = pBtReq->pParamStart[7]; + h2cParaBuf[2] = pBtReq->pParamStart[8]; + h2cParaLen = 3; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // write reg address + btOpcode = BT_LO_OP_WRITE_REG_ADDR; + h2cParaBuf[0] = regType; + h2cParaBuf[1] = pBtReq->pParamStart[2]; + h2cParaBuf[2] = pBtReq->pParamStart[3]; + h2cParaLen = 3; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_GSET_RESET == setType) + { + btOpcode = BT_LO_OP_RESET; + h2cParaLen = 0; + // execute h2c and check respond c2h from bt fw is correct or not + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_GSET_TARGET_BD_ADDR == setType) + { + // fill h2c parameters + btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_L; + h2cParaBuf[0] = pBtReq->pParamStart[1]; + h2cParaBuf[1] = pBtReq->pParamStart[2]; + h2cParaBuf[2] = pBtReq->pParamStart[3]; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H; + h2cParaBuf[0] = pBtReq->pParamStart[4]; + h2cParaBuf[1] = pBtReq->pParamStart[5]; + h2cParaBuf[2] = pBtReq->pParamStart[6]; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_GSET_TX_PWR_FINETUNE == setType) + { + // fill h2c parameters + btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION; + h2cParaBuf[0] = calVal; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_SET_TRACKING_INTERVAL == setType) + { + // BT_LO_OP_SET_TRACKING_INTERVAL = 0x22, + // BT_LO_OP_SET_THERMAL_METER = 0x23, + // BT_LO_OP_ENABLE_CFO_TRACKING = 0x24, + btOpcode = BT_LO_OP_SET_TRACKING_INTERVAL; + h2cParaBuf[0] = calVal; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_SET_THERMAL_METER == setType) + { + btOpcode = BT_LO_OP_SET_THERMAL_METER; + h2cParaBuf[0] = calVal; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + else if(BT_ENABLE_CFO_TRACKING == setType) + { + btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING; + h2cParaBuf[0] = calVal; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + } + + pBtRsp->status = BT_STATUS_SUCCESS; + return paraLen; +} + + + +u2Byte +mptbt_BtSetTxRxPars( + IN PADAPTER Adapter, + IN PBT_REQ_CMD pBtReq, + IN PBT_RSP_CMD pBtRsp + ) +{ + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + PBT_TXRX_PARAMETERS pTxRxPars=(PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0]; + u2Byte lenTxRx=sizeof(BT_TXRX_PARAMETERS); + u1Byte i; + u1Byte bdAddr[6]={0}; + + // + // check upper layer parameters + // + + // 1. check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + // 2. check upper layer parameter length + if(pBtReq->paraLength == sizeof(BT_TXRX_PARAMETERS)) + { + DBG_8192C ("[MPT], pTxRxPars->txrxChannel=0x%x \n", pTxRxPars->txrxChannel); + DBG_8192C ("[MPT], pTxRxPars->txrxTxPktCnt=0x%8x \n", pTxRxPars->txrxTxPktCnt); + DBG_8192C ("[MPT], pTxRxPars->txrxTxPktInterval=0x%x \n", pTxRxPars->txrxTxPktInterval); + DBG_8192C ("[MPT], pTxRxPars->txrxPayloadType=0x%x \n", pTxRxPars->txrxPayloadType); + DBG_8192C ("[MPT], pTxRxPars->txrxPktType=0x%x \n", pTxRxPars->txrxPktType); + DBG_8192C ("[MPT], pTxRxPars->txrxPayloadLen=0x%x \n", pTxRxPars->txrxPayloadLen); + DBG_8192C ("[MPT], pTxRxPars->txrxPktHeader=0x%x \n", pTxRxPars->txrxPktHeader); + DBG_8192C ("[MPT], pTxRxPars->txrxWhitenCoeff=0x%x \n", pTxRxPars->txrxWhitenCoeff); + bdAddr[0] = pTxRxPars->txrxBdaddr[5]; + bdAddr[1] = pTxRxPars->txrxBdaddr[4]; + bdAddr[2] = pTxRxPars->txrxBdaddr[3]; + bdAddr[3] = pTxRxPars->txrxBdaddr[2]; + bdAddr[4] = pTxRxPars->txrxBdaddr[1]; + bdAddr[5] = pTxRxPars->txrxBdaddr[0]; + DBG_8192C ("[MPT], pTxRxPars->txrxBdaddr: %s", &bdAddr[0]); + DBG_8192C ("[MPT], pTxRxPars->txrxTxGainIndex=0x%x \n", pTxRxPars->txrxTxGainIndex); + } + else + { + DBG_8192C ("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + + // + // execute lower layer opcodes + // + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_PKT_HEADER; + if(pTxRxPars->txrxPktHeader > 0x3ffff) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPktHeader=0x%x is out of range, (should be between 0x0~0x3ffff)\n", pTxRxPars->txrxPktHeader); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + h2cParaBuf[0] = (u1Byte)(pTxRxPars->txrxPktHeader&0xff); + h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff00)>>8); + h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff0000)>>16); + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN; + { + u2Byte payloadLenLimit=0; + switch(pTxRxPars->txrxPktType) + { + case MP_BT_PKT_DH1: + payloadLenLimit = 27*8; + break; + case MP_BT_PKT_DH3: + payloadLenLimit = 183*8; + break; + case MP_BT_PKT_DH5: + payloadLenLimit = 339*8; + break; + case MP_BT_PKT_2DH1: + payloadLenLimit = 54*8; + break; + case MP_BT_PKT_2DH3: + payloadLenLimit = 367*8; + break; + case MP_BT_PKT_2DH5: + payloadLenLimit = 679*8; + break; + case MP_BT_PKT_3DH1: + payloadLenLimit = 83*8; + break; + case MP_BT_PKT_3DH3: + payloadLenLimit = 552*8; + break; + case MP_BT_PKT_3DH5: + payloadLenLimit = 1021*8; + break; + case MP_BT_PKT_LE: + payloadLenLimit = 39*8; + break; + default: + { + DBG_8192C ("[MPT], Error!! Unknown pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + break; + } + + if(pTxRxPars->txrxPayloadLen > payloadLenLimit) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadLen=0x%x, (should smaller than %d)\n", + pTxRxPars->txrxPayloadLen, payloadLenLimit); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + + h2cParaBuf[0] = pTxRxPars->txrxPktType; + h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff)); + h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff00)>>8); + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_PKT_CNT_L_PL_TYPE; + if(pTxRxPars->txrxPayloadType > MP_BT_PAYLOAD_MAX) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadType=0x%x, (should be between 0~4)\n", pTxRxPars->txrxPayloadType); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff)); + h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff00)>>8); + h2cParaBuf[2] = pTxRxPars->txrxPayloadType; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_PKT_CNT_H_PKT_INTV; + if(pTxRxPars->txrxTxPktInterval > 15) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxPktInterval=0x%x, (should be between 0~15)\n", pTxRxPars->txrxTxPktInterval); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff0000)>>16); + h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff000000)>>24); + h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_WHITENCOEFF; + { + h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_CHNL_TX_GAIN; + if( (pTxRxPars->txrxChannel > 78) || + (pTxRxPars->txrxTxGainIndex > 7) ) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxChannel=0x%x, (should be between 0~78)\n", pTxRxPars->txrxChannel); + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxGainIndex=0x%x, (should be between 0~7)\n", pTxRxPars->txrxTxGainIndex); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + h2cParaBuf[0] = pTxRxPars->txrxChannel; + h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex; + h2cParaLen = 2; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + // fill h2c parameters + btOpcode = BT_LO_OP_SET_BD_ADDR_L; + if( (pTxRxPars->txrxBdaddr[0]==0) && + (pTxRxPars->txrxBdaddr[1]==0) && + (pTxRxPars->txrxBdaddr[2]==0) && + (pTxRxPars->txrxBdaddr[3]==0) && + (pTxRxPars->txrxBdaddr[4]==0) && + (pTxRxPars->txrxBdaddr[5]==0) ) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all zero\n"); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + if( (pTxRxPars->txrxBdaddr[0]==0xff) && + (pTxRxPars->txrxBdaddr[1]==0xff) && + (pTxRxPars->txrxBdaddr[2]==0xff) && + (pTxRxPars->txrxBdaddr[3]==0xff) && + (pTxRxPars->txrxBdaddr[4]==0xff) && + (pTxRxPars->txrxBdaddr[5]==0xff) ) + { + DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all 0xf\n"); + pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + + { + h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0]; + h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1]; + h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2]; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + btOpcode = BT_LO_OP_SET_BD_ADDR_H; + { + h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3]; + h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4]; + h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5]; + h2cParaLen = 3; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + // ckeck bt return status. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + pBtRsp->status = BT_STATUS_SUCCESS; + return paraLen; +} + + + +u2Byte +mptbt_BtTestCtrl( + IN PADAPTER Adapter, + IN PBT_REQ_CMD pBtReq, + IN PBT_RSP_CMD pBtRsp + ) +{ + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + u1Byte testCtrl=0; + + // + // check upper layer parameters + // + + // 1. check upper layer opcode version + if(pBtReq->opCodeVer != 1) + { + DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n"); + pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH; + return paraLen; + } + // 2. check upper layer parameter length + if(1 == pBtReq->paraLength) + { + testCtrl = pBtReq->pParamStart[0]; + DBG_8192C("[MPT], testCtrl=%d \n", testCtrl); + } + else + { + DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength); + pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U; + return paraLen; + } + + // + // execute lower layer opcodes + // + + // 1. fill h2c parameters + // check bt mode + btOpcode = BT_LO_OP_TEST_CTRL; + if(testCtrl >= MP_BT_TEST_MAX) + { + DBG_8192C("[MPT], Error!! testCtrl=0x%x, (should be between smaller or equal to 0x%x)\n", + testCtrl, MP_BT_TEST_MAX-1); + pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U; + return paraLen; + } + else + { + h2cParaBuf[0] = testCtrl; + h2cParaLen = 1; + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + } + + // 3. construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + pBtRsp->status = BT_STATUS_SUCCESS; + return paraLen; +} + + +u2Byte +mptbt_TestBT( + IN PADAPTER Adapter, + IN PBT_REQ_CMD pBtReq, + IN PBT_RSP_CMD pBtRsp + ) +{ + + u1Byte h2cParaBuf[6] ={0}; + u1Byte h2cParaLen=0; + u2Byte paraLen=0; + u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS; + u1Byte btOpcode; + u1Byte btOpcodeVer=0; + u1Byte testCtrl=0; + + // 1. fill h2c parameters + btOpcode = 0x11; + h2cParaBuf[0] = 0x11; + h2cParaBuf[1] = 0x0; + h2cParaBuf[2] = 0x0; + h2cParaBuf[3] = 0x0; + h2cParaBuf[4] = 0x0; + h2cParaLen = 1; + // retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); + retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen); + + + // 3. construct respond status code and data. + if(BT_STATUS_BT_OP_SUCCESS != retStatus) + { + pBtRsp->status = ((btOpcode<<8)|retStatus); + DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status); + return paraLen; + } + + pBtRsp->status = BT_STATUS_SUCCESS; + return paraLen; +} + +VOID +mptbt_BtControlProcess( + PADAPTER Adapter, + PVOID pInBuf + ) +{ + u1Byte H2C_Parameter[6] ={0}; + PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0]; + PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx); + PBT_REQ_CMD pBtReq=(PBT_REQ_CMD)pInBuf; + PBT_RSP_CMD pBtRsp; + u1Byte i; + + + DBG_8192C("[MPT], mptbt_BtControlProcess()=========>\n"); + + DBG_8192C("[MPT], input opCodeVer=%d\n", pBtReq->opCodeVer); + DBG_8192C("[MPT], input OpCode=%d\n", pBtReq->OpCode); + DBG_8192C("[MPT], paraLength=%d \n", pBtReq->paraLength); + if(pBtReq->paraLength) + { + //DBG_8192C("[MPT], parameters(hex):0x%x %d \n",&pBtReq->pParamStart[0], pBtReq->paraLength); + } + + _rtw_memset((void*)pMptCtx->mptOutBuf, 0, 100); + pMptCtx->mptOutLen = 4; //length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength) + + pBtRsp = (PBT_RSP_CMD)pMptCtx->mptOutBuf; + pBtRsp->status = BT_STATUS_SUCCESS; + pBtRsp->paraLength = 0x0; + + // The following we should maintain the User OP codes sent by upper layer + switch(pBtReq->OpCode) + { + case BT_UP_OP_BT_READY: + DBG_8192C("[MPT], OPcode : [BT_READY]\n"); + pBtRsp->paraLength = mptbt_BtReady(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_BT_SET_MODE: + DBG_8192C("[MPT], OPcode : [BT_SET_MODE]\n"); + pBtRsp->paraLength = mptbt_BtSetMode(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_BT_SET_TX_RX_PARAMETER: + DBG_8192C("[MPT], OPcode : [BT_SET_TXRX_PARAMETER]\n"); + pBtRsp->paraLength = mptbt_BtSetTxRxPars(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_BT_SET_GENERAL: + DBG_8192C("[MPT], OPcode : [BT_SET_GENERAL]\n"); + pBtRsp->paraLength = mptbt_BtSetGeneral(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_BT_GET_GENERAL: + DBG_8192C("[MPT], OPcode : [BT_GET_GENERAL]\n"); + pBtRsp->paraLength = mptbt_BtGetGeneral(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_BT_TEST_CTRL: + DBG_8192C("[MPT], OPcode : [BT_TEST_CTRL]\n"); + pBtRsp->paraLength = mptbt_BtTestCtrl(Adapter, pBtReq, pBtRsp); + break; + case BT_UP_OP_TEST_BT: + DBG_8192C("[MPT], OPcode : [TEST_BT]\n"); + pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp); + break; + default: + DBG_8192C("[MPT], Error!! OPcode : UNDEFINED!!!!\n"); + pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U; + pBtRsp->paraLength = 0x0; + break; + } + + pMptCtx->mptOutLen += pBtRsp->paraLength; + + DBG_8192C("[MPT], pMptCtx->mptOutLen=%d, pBtRsp->paraLength=%d\n", pMptCtx->mptOutLen, pBtRsp->paraLength); + DBG_8192C("[MPT], mptbt_BtControlProcess()<=========\n"); +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_btcoex.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_btcoex.c new file mode 100644 index 00000000..aafdd72c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_btcoex.c @@ -0,0 +1,1739 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +#ifdef CONFIG_BT_COEXIST + +#include +#include +#include + + +void rtw_btcoex_Initialize(PADAPTER padapter) +{ + hal_btcoex_Initialize(padapter); +} + +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); +} + +void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_IpsNotify(padapter, type); +} + +void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_LpsNotify(padapter, type); +} + +void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type) +{ + PHAL_DATA_TYPE pHalData; +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + struct bt_coex_info *pcoex_info = &padapter->coex_info; + PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == type) && (padapter->pbuddy_adapter)) + { + PADAPTER pbuddy = padapter->pbuddy_adapter; + if (check_fwstate(&pbuddy->mlmepriv, WIFI_SITE_MONITOR) == _TRUE) + return; + } +#endif + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + if(pBtMgnt->ExtConfig.bEnableWifiScanNotify) + rtw_btcoex_SendScanNotify(padapter, type); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + hal_btcoex_ScanNotify(padapter, type); +} + +void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + +#ifdef DBG_CONFIG_ERROR_RESET + if (_TRUE == rtw_hal_sreset_inprogress(padapter)) + { + DBG_8192C(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n", + FUNC_ADPT_ARG(padapter)); + return; + } +#endif // DBG_CONFIG_ERROR_RESET + +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == action) && (padapter->pbuddy_adapter)) + { + PADAPTER pbuddy = padapter->pbuddy_adapter; + if (check_fwstate(&pbuddy->mlmepriv, WIFI_UNDER_LINKING) == _TRUE) + return; + } +#endif + + hal_btcoex_ConnectNotify(padapter, action); +} + +void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + +#ifdef DBG_CONFIG_ERROR_RESET + if (_TRUE == rtw_hal_sreset_inprogress(padapter)) + { + DBG_8192C(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n", + FUNC_ADPT_ARG(padapter)); + return; + } +#endif // DBG_CONFIG_ERROR_RESET + +#ifdef CONFIG_CONCURRENT_MODE + if ((RT_MEDIA_DISCONNECT == mediaStatus) && (padapter->pbuddy_adapter)) + { + PADAPTER pbuddy = padapter->pbuddy_adapter; + if (check_fwstate(&pbuddy->mlmepriv, WIFI_ASOC_STATE) == _TRUE) + return; + } +#endif // CONFIG_CONCURRENT_MODE + + if ((RT_MEDIA_CONNECT == mediaStatus) + && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) + { + rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL); + } + + hal_btcoex_MediaStatusNotify(padapter, mediaStatus); +} + +void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_SpecialPacketNotify(padapter, pktType); +} + +void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_IQKNotify(padapter, state); +} + +void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_BtInfoNotify(padapter, length, tmpBuf); +} + +void rtw_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + if (padapter->registrypriv.mp_mode == 1) + return; + + hal_btcoex_BtMpRptNotify(padapter, length, tmpBuf); +} + +void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_SuspendNotify(padapter, state); +} + +void rtw_btcoex_HaltNotify(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + if (_FALSE == padapter->bup) + { + DBG_871X(FUNC_ADPT_FMT ": bup=%d Skip!\n", + FUNC_ADPT_ARG(padapter), padapter->bup); + + return; + } + + if (rtw_is_surprise_removed(padapter)) { + DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved=%s Skip!\n", + FUNC_ADPT_ARG(padapter), rtw_is_surprise_removed(padapter)?"True":"False"); + + return; + } + + hal_btcoex_HaltNotify(padapter); +} + +void rtw_btcoex_ScoreBoardStatusNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + + hal_btcoex_ScoreBoardStatusNotify(padapter, length, tmpBuf); +} + +void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter) +{ + hal_btcoex_SwitchBtTRxMask(padapter); +} + +void rtw_btcoex_Switch(PADAPTER padapter, u8 enable) +{ + hal_btcoex_SetBTCoexist(padapter, enable); +} + +u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter) +{ + return hal_btcoex_IsBtDisabled(padapter); +} + +void rtw_btcoex_Handler(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + + if (_FALSE == pHalData->EEPROMBluetoothCoexist) + return; + +#if defined(CONFIG_CONCURRENT_MODE) + if (padapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + + + hal_btcoex_Hanlder(padapter); +} + +s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter) +{ + s32 coexctrl; + + coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter); + + return coexctrl; +} + +s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter) +{ + s32 coexctrl; + + coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter); + + return coexctrl; +} + +u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter) +{ + u32 size; + + size = hal_btcoex_GetAMPDUSize(padapter); + + return size; +} + +void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual) +{ + if (_TRUE == manual) + { + hal_btcoex_SetManualControl(padapter, _TRUE); + } + else + { + hal_btcoex_SetManualControl(padapter, _FALSE); + } +} + +u8 rtw_btcoex_1Ant(PADAPTER padapter) +{ + return hal_btcoex_1Ant(padapter); +} + +u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter) +{ + return hal_btcoex_IsBtControlLps(padapter); +} + +u8 rtw_btcoex_IsLpsOn(PADAPTER padapter) +{ + return hal_btcoex_IsLpsOn(padapter); +} + +u8 rtw_btcoex_RpwmVal(PADAPTER padapter) +{ + return hal_btcoex_RpwmVal(padapter); +} + +u8 rtw_btcoex_LpsVal(PADAPTER padapter) +{ + return hal_btcoex_LpsVal(padapter); +} + +void rtw_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist) +{ + hal_btcoex_SetBTCoexist(padapter, bBtExist); +} + +void rtw_btcoex_SetChipType(PADAPTER padapter, u8 chipType) +{ + hal_btcoex_SetChipType(padapter, chipType); +} + +void rtw_btcoex_SetPGAntNum(PADAPTER padapter, u8 antNum) +{ + hal_btcoex_SetPgAntNum(padapter, antNum); +} + +u8 rtw_btcoex_GetPGAntNum(PADAPTER padapter) +{ + return hal_btcoex_GetPgAntNum(padapter); +} + +void rtw_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath) +{ + hal_btcoex_SetSingleAntPath(padapter, singleAntPath); +} + +u32 rtw_btcoex_GetRaMask(PADAPTER padapter) +{ + return hal_btcoex_GetRaMask(padapter); +} + +void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen) +{ + hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen); +} + +void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize) +{ + hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize); +} + +void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule) +{ + hal_btcoex_SetDBG(padapter, pDbgModule); +} + +u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize) +{ + return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize); +} + +u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter) +{ + return hal_btcoex_IncreaseScanDeviceNum(padapter); +} + +u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter) +{ + return hal_btcoex_IsBtLinkExist(padapter); +} + +void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer, u16 btPatchVer) +{ + hal_btcoex_SetBtPatchVersion(padapter,btHciVer,btPatchVer); +} + +void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion) +{ + hal_btcoex_SetHciVersion(padapter, hciVersion); +} + +void rtw_btcoex_StackUpdateProfileInfo(void) +{ + hal_btcoex_StackUpdateProfileInfo(); +} + +void rtw_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON) +{ + hal_btcoex_BTOffOnNotify(padapter, bBTON); +} + +// ================================================== +// Below Functions are called by BT-Coex +// ================================================== +void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter) +{ + rtw_rx_ampdu_apply(padapter); +} + +void rtw_btcoex_LPS_Enter(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrpriv; + u8 lpsVal; + + + pwrpriv = adapter_to_pwrctl(padapter); + + pwrpriv->bpower_saving = _TRUE; + lpsVal = rtw_btcoex_LpsVal(padapter); + rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX"); +} + +void rtw_btcoex_LPS_Leave(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrpriv; + + + pwrpriv = adapter_to_pwrctl(padapter); + + if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) + { + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX"); + LPS_RF_ON_check(padapter, 100); + pwrpriv->bpower_saving = _FALSE; + } +} + +u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data) +{ + return hal_btcoex_btreg_read(padapter, type, addr, data); +} + +u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val) +{ + return hal_btcoex_btreg_write(padapter, type, addr, val); +} + + +// ================================================== +// Below Functions are BT-Coex socket related function +// ================================================== + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX +_adapter *pbtcoexadapter = NULL; +u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + u8 *btinfo; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + btinfo = rtw_zmalloc(len); + if (btinfo == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8*)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = len; + pdrvextra_cmd_parm->pbuf = btinfo; + + _rtw_memcpy(btinfo, buf, len); + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + return res; +} + +u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status, u8 event_code, u8 opcode_low, u8 opcode_high,u8 *dbg_msg) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0,tx_event_length = 0; + rtw_HCI_event *pEvent; + + pEvent = (rtw_HCI_event*)(&localBuf[0]); + + pEvent->EventCode = event_code; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = opcode_low; + pEvent->Data[2] = opcode_high; + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg); +#endif + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + + return status; +} + +/* +Ref: +Realtek Wi-Fi Driver +Host Controller Interface for +Bluetooth 3.0 + HS V1.4 2013/02/07 + +Window team code & BT team code + */ + + +u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + #define BT_INFO_LENGTH 8 + + u8 curPollEnable = pcmd[0]; + u8 curPollTime = pcmd[1]; + u8 btInfoReason = pcmd[2]; + u8 btInfoLen = pcmd[3]; + u8 btinfo[BT_INFO_LENGTH]; + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0,tx_event_length = 0; + RTW_HCI_STATUS status = HCI_STATUS_SUCCESS; + rtw_HCI_event *pEvent; + + /* DBG_871X("%s\n",__func__); + DBG_871X("current Poll Enable: %d, currrent Poll Time: %d\n",curPollEnable,curPollTime); + DBG_871X("BT Info reason: %d, BT Info length: %d\n",btInfoReason,btInfoLen); + DBG_871X("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" + ,pcmd[4],pcmd[5],pcmd[6],pcmd[7],pcmd[8],pcmd[9],pcmd[10],pcmd[11]);*/ + + _rtw_memset(btinfo, 0, BT_INFO_LENGTH); + +#if 1 + if(BT_INFO_LENGTH != btInfoLen) + { + status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE; + DBG_871X("Error BT Info Length: %d\n",btInfoLen); + //return _FAIL; + } + else +#endif + { + if(0x1 == btInfoReason || 0x2 == btInfoReason) + { + _rtw_memcpy(btinfo, &pcmd[4], btInfoLen); + btinfo[0] = btInfoReason; + rtw_btcoex_btinfo_cmd(padapter,btinfo,btInfoLen); + } + else + { + DBG_871X("Other BT info reason\n"); + } + } + + //send complete event to BT + { + + pEvent = (rtw_HCI_event*)(&localBuf[0]); + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_INFO_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_INFO_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length,"BT_info_event"); +#endif + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + u16 btPatchVer=0x0, btHciVer=0x0; + //u16 *pU2tmp; + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + + btHciVer = pcmd[0] | pcmd[1]<<8; + btPatchVer = pcmd[2] | pcmd[3]<<8; + + + DBG_871X("%s, cmd:%02x %02x %02x %02x\n",__func__, pcmd[0] ,pcmd[1] ,pcmd[2] ,pcmd[3]); + DBG_871X("%s, HCI Ver:%d, Patch Ver:%d\n",__func__, btHciVer,btPatchVer); + + rtw_btcoex_SetBtPatchVersion(padapter,btHciVer,btPatchVer); + + + //send complete event to BT + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length,"BT_patch_event"); +#endif + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + u16 hciver = pcmd[0] | pcmd[1] <<8; + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + + struct bt_coex_info *pcoex_info = &padapter->coex_info; + PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt; + pBtMgnt->ExtConfig.HCIExtensionVer = hciver; + DBG_871X("%s, HCI Version: %d\n",__func__,pBtMgnt->ExtConfig.HCIExtensionVer); + if(pBtMgnt->ExtConfig.HCIExtensionVer < 4) + { + status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE; + DBG_871X("%s, Version = %d, HCI Version < 4\n",__func__,pBtMgnt->ExtConfig.HCIExtensionVer ); + } + else + { + rtw_btcoex_SetHciVersion(padapter,hciver); + } + //send complete event to BT + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } + +} + +u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + + struct bt_coex_info *pcoex_info = &padapter->coex_info; + PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt; + pBtMgnt->ExtConfig.bEnableWifiScanNotify= pcmd[0]; + DBG_871X("%s, bEnableWifiScanNotify: %d\n",__func__,pBtMgnt->ExtConfig.bEnableWifiScanNotify); + + //send complete event to BT + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + struct bt_coex_info *pcoex_info=&padapter->coex_info; + PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt; + //PBT_DBG pBtDbg=&padapter->MgntInfo.BtInfo.BtDbg; + u8 i, numOfHandle=0, numOfAcl=0; + u16 conHandle; + u8 btProfile, btCoreSpec, linkRole; + u8 *pTriple; + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + + //pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; + //RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n", + // &pHciCmd->Data[0], pHciCmd->Length); + + DBG_871X("BTLinkStatusNotify\n"); + + // Current only RTL8723 support this command. + //pBtMgnt->bSupportProfile = TRUE; + pBtMgnt->bSupportProfile = _FALSE; + + pBtMgnt->ExtConfig.NumberOfACL = 0; + pBtMgnt->ExtConfig.NumberOfSCO = 0; + + numOfHandle = pcmd[0]; + //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("numOfHandle = 0x%x\n", numOfHandle)); + //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer)); + DBG_871X("numOfHandle = 0x%x\n", numOfHandle); + DBG_871X("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer); + + pTriple = &pcmd[1]; + for(i=0; iExtConfig.HCIExtensionVer < 1) + { + conHandle = *((u8 *)&pTriple[0]); + btProfile = pTriple[2]; + btCoreSpec = pTriple[3]; + if(BT_PROFILE_SCO == btProfile) + { + pBtMgnt->ExtConfig.NumberOfSCO++; + } + else + { + pBtMgnt->ExtConfig.NumberOfACL++; + pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle; + pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile; + pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec; + } + //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, + // ("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", + // conHandle, btProfile, btCoreSpec)); + DBG_871X("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", conHandle, btProfile, btCoreSpec); + pTriple += 4; + } + else if(pBtMgnt->ExtConfig.HCIExtensionVer >= 1) + { + conHandle = *((pu2Byte)&pTriple[0]); + btProfile = pTriple[2]; + btCoreSpec = pTriple[3]; + linkRole = pTriple[4]; + if(BT_PROFILE_SCO == btProfile) + { + pBtMgnt->ExtConfig.NumberOfSCO++; + } + else + { + pBtMgnt->ExtConfig.NumberOfACL++; + pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle; + pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile; + pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec; + pBtMgnt->ExtConfig.aclLink[i].linkRole = linkRole; + } + //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, + DBG_871X("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d, LinkRole=%d\n", + conHandle, btProfile, btCoreSpec, linkRole); + pTriple += 5; + } + } + rtw_btcoex_StackUpdateProfileInfo(); + + //send complete event to BT + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } + + +} + +u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_COEX_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_COEX_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + DBG_871X("%s, OP code: %d\n",__func__,pcmd[0]); + + switch(pcmd[0]) + { + case HCI_BT_OP_NONE: + DBG_871X("[bt operation] : Operation None!!\n"); + break; + case HCI_BT_OP_INQUIRY_START: + DBG_871X("[bt operation] : Inquiry start!!\n"); + break; + case HCI_BT_OP_INQUIRY_FINISH: + DBG_871X("[bt operation] : Inquiry finished!!\n"); + break; + case HCI_BT_OP_PAGING_START: + DBG_871X("[bt operation] : Paging is started!!\n"); + break; + case HCI_BT_OP_PAGING_SUCCESS: + DBG_871X("[bt operation] : Paging complete successfully!!\n"); + break; + case HCI_BT_OP_PAGING_UNSUCCESS: + DBG_871X("[bt operation] : Paging complete unsuccessfully!!\n"); + break; + case HCI_BT_OP_PAIRING_START: + DBG_871X("[bt operation] : Pairing start!!\n"); + break; + case HCI_BT_OP_PAIRING_FINISH: + DBG_871X("[bt operation] : Pairing finished!!\n"); + break; + case HCI_BT_OP_BT_DEV_ENABLE: + DBG_871X("[bt operation] : BT Device is enabled!!\n"); + break; + case HCI_BT_OP_BT_DEV_DISABLE: + DBG_871X("[bt operation] : BT Device is disabled!!\n"); + break; + default: + DBG_871X("[bt operation] : Unknown, error!!\n"); + break; + } + + //send complete event to BT + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen) +{ + u8 localBuf[6] = ""; + u8 *pRetPar; + u8 len=0, tx_event_length =0; + rtw_HCI_event *pEvent; + RTW_HCI_STATUS status=HCI_STATUS_SUCCESS; + + { + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + + pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; + pEvent->Data[0] = 0x1; //packet # + pEvent->Data[1] = HCIOPCODELOW(HCI_QUERY_RF_STATUS, OGF_EXTENSION); + pEvent->Data[2] = HCIOPCODEHIGHT(HCI_QUERY_RF_STATUS, OGF_EXTENSION); + len = len + 3; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + pRetPar[0] = status; //status + + len++; + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; + + status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + return status; + //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); + } +} + +/***************************************** +* HCI cmd format : +*| 15 - 0 | +*| OPcode (OCF|OGF<<10) | +*| 15 - 8 |7 - 0 | +*|Cmd para |Cmd para Length | +*|Cmd para...... | +******************************************/ + +//bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// | OCF | OGF | +void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len,const u16 hci_OCF) +{ + + DBG_871X("%s: OCF: %x\n",__func__,hci_OCF); + switch(hci_OCF) + { + case HCI_EXTENSION_VERSION_NOTIFY: + DBG_871X("HCI_EXTENSION_VERSION_NOTIFY\n"); + rtw_btcoex_parse_HCI_Ver_notify_cmd(padapter,pcmd, len); + break; + case HCI_LINK_STATUS_NOTIFY: + DBG_871X("HCI_LINK_STATUS_NOTIFY\n"); + rtw_btcoex_parse_HCI_link_status_notify_cmd(padapter,pcmd, len); + break; + case HCI_BT_OPERATION_NOTIFY: + // only for 8723a 2ant + DBG_871X("HCI_BT_OPERATION_NOTIFY\n"); + rtw_btcoex_parse_HCI_BT_operation_notify_cmd(padapter,pcmd, len); + // + break; + case HCI_ENABLE_WIFI_SCAN_NOTIFY: + DBG_871X("HCI_ENABLE_WIFI_SCAN_NOTIFY\n"); + rtw_btcoex_parse_WIFI_scan_notify_cmd(padapter,pcmd, len); + break; + case HCI_QUERY_RF_STATUS: + // only for 8723b 2ant + DBG_871X("HCI_QUERY_RF_STATUS\n"); + rtw_btcoex_parse_HCI_query_RF_status_cmd(padapter,pcmd, len); + break; + case HCI_BT_ABNORMAL_NOTIFY: + DBG_871X("HCI_BT_ABNORMAL_NOTIFY\n"); + rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(padapter,pcmd, len); + break; + case HCI_BT_INFO_NOTIFY: + DBG_871X("HCI_BT_INFO_NOTIFY\n"); + rtw_btcoex_parse_BT_info_notify_cmd(padapter,pcmd, len); + break; + case HCI_BT_COEX_NOTIFY: + DBG_871X("HCI_BT_COEX_NOTIFY\n"); + rtw_btcoex_parse_HCI_BT_coex_notify_cmd(padapter,pcmd, len); + break; + case HCI_BT_PATCH_VERSION_NOTIFY: + DBG_871X("HCI_BT_PATCH_VERSION_NOTIFY\n"); + rtw_btcoex_parse_BT_patch_ver_info_cmd(padapter,pcmd, len); + break; + case HCI_BT_AFH_MAP_NOTIFY: + DBG_871X("HCI_BT_AFH_MAP_NOTIFY\n"); + rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(padapter,pcmd, len); + break; + case HCI_BT_REGISTER_VALUE_NOTIFY: + DBG_871X("HCI_BT_REGISTER_VALUE_NOTIFY\n"); + rtw_btcoex_parse_BT_register_val_notify_cmd(padapter,pcmd, len); + break; + default: + DBG_871X("ERROR!!! Unknown OCF: %x\n",hci_OCF); + break; + + } +} + +void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len) +{ + u16 opcode = pcmd[0] | pcmd[1]<<8; + u16 hci_OGF = HCI_OGF(opcode); + u16 hci_OCF = HCI_OCF(opcode); + u8 cmdlen = len -3; + u8 pare_len = pcmd[2]; + + DBG_871X("%s OGF: %x,OCF: %x\n", __func__, hci_OGF, hci_OCF); + switch(hci_OGF) + { + case OGF_EXTENSION: + DBG_871X("HCI_EXTENSION_CMD_OGF\n"); + rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF); + break; + default: + DBG_871X("Other OGF: %x\n",hci_OGF); + break; + } +} + +u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size) +{ + u8 cmp_msg1[32] = attend_ack; + u8 cmp_msg2[32] = leave_ack; + u8 cmp_msg3[32] = bt_leave; + u8 cmp_msg4[32] = invite_req; + u8 cmp_msg5[32] = attend_req; + u8 cmp_msg6[32] = invite_rsp; + u8 res = OTHER; + + if (_rtw_memcmp(cmp_msg1, msg, msg_size) == _TRUE) { + /*DBG_871X("%s, msg:%s\n",__func__,msg);*/ + res = RX_ATTEND_ACK; + } else if (_rtw_memcmp(cmp_msg2, msg, msg_size) == _TRUE) { + /*DBG_871X("%s, msg:%s\n",__func__,msg);*/ + res = RX_LEAVE_ACK; + } else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) { + /*DBG_871X("%s, msg:%s\n",__func__,msg);*/ + res = RX_BT_LEAVE; + } else if (_rtw_memcmp(cmp_msg4, msg, msg_size) == _TRUE) { + /*DBG_871X("%s, msg:%s\n",__func__,msg);*/ + res = RX_INVITE_REQ; + } else if (_rtw_memcmp(cmp_msg5, msg, msg_size) == _TRUE) { + res = RX_ATTEND_REQ; + } else if (_rtw_memcmp(cmp_msg6, msg, msg_size) == _TRUE) { + res = RX_INVITE_RSP; + } else { + /*DBG_871X("%s, %s\n", __func__, msg);*/ + res = OTHER; + } + + /*DBG_871X("%s, res:%d\n", __func__, res);*/ + + return res; +} + +void rtw_btcoex_recvmsgbysocket(void *data) +{ + u8 recv_data[255]; + u8 tx_msg[255] = leave_ack; + u32 len = 0; + u16 recv_length = 0; + u16 parse_res = 0; +#if 0 + u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0; + u8 btinfo[BT_INFO_LEN] = {0}; +#endif + + struct bt_coex_info *pcoex_info = NULL; + struct sock *sk = NULL; + struct sk_buff *skb = NULL; + + /*DBG_871X("%s\n",__func__);*/ + + if (pbtcoexadapter == NULL) { + DBG_871X("%s: btcoexadapter NULL!\n", __func__); + return; + } + + pcoex_info = &pbtcoexadapter->coex_info; + sk = pcoex_info->sk_store; + + if (sk == NULL) { + DBG_871X("%s: critical error when receive socket data!\n", __func__); + return; + } + + len = skb_queue_len(&sk->sk_receive_queue); + while (len > 0) { + skb = skb_dequeue(&sk->sk_receive_queue); + + /*important: cut the udp header from skb->data! header length is 8 byte*/ + recv_length = skb->len-8; + _rtw_memset(recv_data, 0, sizeof(recv_data)); + _rtw_memcpy(recv_data, skb->data+8, recv_length); + + parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length); +/* + if (RX_ATTEND_ACK == parse_res) { + //attend ack + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + } else if (RX_ATTEND_REQ == parse_res) { + //attend req from BT + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE); + } else if (RX_INVITE_REQ == parse_res) { + //invite req from BT + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE); + } else if (RX_INVITE_RSP == parse_res) { + //invite rsp + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + } else if (RX_LEAVE_ACK == parse_res) { + //mean BT know wifi will leave + pcoex_info->BT_attend = _FALSE; + DBG_871X("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + } else if (RX_BT_LEAVE == parse_res) { + //BT leave + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); // no ack + pcoex_info->BT_attend = _FALSE; + DBG_871X("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + } else { + //todo: check if recv data are really hci cmds + if (_TRUE == pcoex_info->BT_attend) + rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length); + } +*/ + switch (parse_res) { + case RX_ATTEND_ACK: + /* attend ack */ + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + case RX_ATTEND_REQ: + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + case RX_INVITE_REQ: + /* invite req from BT */ + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + case RX_INVITE_RSP: + /*invite rsp*/ + pcoex_info->BT_attend = _TRUE; + DBG_871X("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + case RX_LEAVE_ACK: + /* mean BT know wifi will leave */ + pcoex_info->BT_attend = _FALSE; + DBG_871X("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + case RX_BT_LEAVE: + /* BT leave */ + rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */ + pcoex_info->BT_attend = _FALSE; + DBG_871X("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend); + break; + + default: + if (_TRUE == pcoex_info->BT_attend) + rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length); + else + DBG_871X("ERROR!! BT is UP\n"); + break; + + } + + len--; + kfree_skb(skb); + } +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)) +void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes) +#else +void rtw_btcoex_recvmsg_init(struct sock *sk_in) +#endif +{ + struct bt_coex_info *pcoex_info = NULL; + + if (pbtcoexadapter == NULL) { + DBG_871X("%s: btcoexadapter NULL\n", __func__); + return; + } + pcoex_info = &pbtcoexadapter->coex_info; + pcoex_info->sk_store = sk_in; + if (pcoex_info->btcoex_wq != NULL) + queue_delayed_work(pcoex_info->btcoex_wq, &pcoex_info->recvmsg_work, 0); + else + DBG_871X("%s: BTCOEX workqueue NULL\n", __func__); +} + +u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force) +{ + u8 error; + struct msghdr udpmsg; + mm_segment_t oldfs; + struct iovec iov; + struct bt_coex_info *pcoex_info = &padapter->coex_info; + + /* DBG_871X("%s: msg:%s, force:%s\n", __func__, msg, force == _TRUE?"TRUE":"FALSE"); */ + if (_FALSE == force) { + if (_FALSE == pcoex_info->BT_attend) { + DBG_871X("TX Blocked: WiFi-BT disconnected\n"); + return _FAIL; + } + } + + iov.iov_base = (void *)msg; + iov.iov_len = msg_size; + udpmsg.msg_name = &pcoex_info->bt_sockaddr; + udpmsg.msg_namelen = sizeof(struct sockaddr_in); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + /* referece:sock_xmit in kernel code + * WRITE for sock_sendmsg, READ for sock_recvmsg + * third parameter for msg_iovlen + * last parameter for iov_len + */ + iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size); +#else + udpmsg.msg_iov = &iov; + udpmsg.msg_iovlen = 1; +#endif + udpmsg.msg_control = NULL; + udpmsg.msg_controllen = 0; + udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; + oldfs = get_fs(); + set_fs(KERNEL_DS); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + error = sock_sendmsg(pcoex_info->udpsock, &udpmsg); +#else + error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size); +#endif + set_fs(oldfs); + if (error < 0) { + DBG_871X("Error when sendimg msg, error:%d\n", error); + return _FAIL; + } else + return _SUCCESS; +} + +u8 rtw_btcoex_create_kernel_socket(_adapter *padapter) +{ + s8 kernel_socket_err; + u8 tx_msg[255] = attend_req; + struct bt_coex_info *pcoex_info = &padapter->coex_info; + s32 sock_reuse = 1; + u8 status = _FAIL; + + DBG_871X("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT); + + if (NULL == pcoex_info) { + DBG_871X("coex_info: NULL\n"); + status = _FAIL; + } + + kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock); + + if (kernel_socket_err < 0) { + DBG_871X("Error during creation of socket error:%d\n", kernel_socket_err); + status = _FAIL; + } else { + _rtw_memset(&(pcoex_info->wifi_sockaddr), 0, sizeof(pcoex_info->wifi_sockaddr)); + pcoex_info->wifi_sockaddr.sin_family = AF_INET; + pcoex_info->wifi_sockaddr.sin_port = htons(CONNECT_PORT); + pcoex_info->wifi_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + _rtw_memset(&(pcoex_info->bt_sockaddr), 0, sizeof(pcoex_info->bt_sockaddr)); + pcoex_info->bt_sockaddr.sin_family = AF_INET; + pcoex_info->bt_sockaddr.sin_port = htons(CONNECT_PORT_BT); + pcoex_info->bt_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + pcoex_info->sk_store = NULL; + kernel_socket_err = pcoex_info->udpsock->ops->bind(pcoex_info->udpsock, (struct sockaddr *)&pcoex_info->wifi_sockaddr, + sizeof(pcoex_info->wifi_sockaddr)); + if (kernel_socket_err == 0) { + DBG_871X("binding socket success\n"); + pcoex_info->udpsock->sk->sk_data_ready = rtw_btcoex_recvmsg_init; + pcoex_info->sock_open |= KERNEL_SOCKET_OK; + pcoex_info->BT_attend = _FALSE; + DBG_871X("WIFI sending attend_req\n"); + rtw_btcoex_sendmsgbysocket(padapter, attend_req, sizeof(attend_req), _TRUE); + status = _SUCCESS; + } else { + pcoex_info->BT_attend = _FALSE; + sock_release(pcoex_info->udpsock); /* bind fail release socket */ + DBG_871X("Error binding socket: %d\n", kernel_socket_err); + status = _FAIL; + } + + } + + return status; +} + +void rtw_btcoex_close_kernel_socket(_adapter *padapter) +{ + struct bt_coex_info *pcoex_info = &padapter->coex_info; + if (pcoex_info->sock_open & KERNEL_SOCKET_OK) { + DBG_871X("release kernel socket\n"); + sock_release(pcoex_info->udpsock); + pcoex_info->sock_open &= ~(KERNEL_SOCKET_OK); + if (_TRUE == pcoex_info->BT_attend) + pcoex_info->BT_attend = _FALSE; + + DBG_871X("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend); + } +} + +void rtw_btcoex_init_socket(_adapter *padapter) +{ + + u8 is_invite = _FALSE; + struct bt_coex_info *pcoex_info = &padapter->coex_info; + DBG_871X("%s\n", __func__); + if (_FALSE == pcoex_info->is_exist) { + _rtw_memset(pcoex_info,0,sizeof(struct bt_coex_info)); + pcoex_info->btcoex_wq = create_workqueue("BTCOEX"); + INIT_DELAYED_WORK(&pcoex_info->recvmsg_work, + (void *)rtw_btcoex_recvmsgbysocket); + pbtcoexadapter = padapter; + /* We expect BT is off if BT don't send ack to wifi */ + DBG_871X("We expect BT is off if BT send ack to wifi\n"); + rtw_btcoex_BTOffOnNotify(pbtcoexadapter, _FALSE); + if (rtw_btcoex_create_kernel_socket(padapter) == _SUCCESS) { + pcoex_info->is_exist = _TRUE; + } else { + pcoex_info->is_exist = _FALSE; + pbtcoexadapter = NULL; + } + + DBG_871X("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n" + , __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE?"TRUE":"FALSE"); + } +} + +void rtw_btcoex_close_socket(_adapter *padapter) +{ + struct bt_coex_info *pcoex_info = &padapter->coex_info; + + DBG_871X("%s--coex_info->is_exist: %s, pcoex_info->BT_attend:%s\n" + , __func__, pcoex_info->is_exist == _TRUE?"TRUE":"FALSE", pcoex_info->BT_attend == _TRUE?"TRUE":"FALSE"); + + if (_TRUE == pcoex_info->is_exist) { + if (_TRUE == pcoex_info->BT_attend) { + /*inform BT wifi leave*/ + rtw_btcoex_sendmsgbysocket(padapter, wifi_leave, sizeof(wifi_leave), _FALSE); + msleep(50); + } + + if (pcoex_info->btcoex_wq != NULL) { + flush_workqueue(pcoex_info->btcoex_wq); + destroy_workqueue(pcoex_info->btcoex_wq); + } + + rtw_btcoex_close_kernel_socket(padapter); + pbtcoexadapter = NULL; + pcoex_info->is_exist = _FALSE; + } +} + +void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name) +{ + u8 i = 0; + DBG_871X("======> Msg name: %s\n", msg_name); + for(i=0;iEventCode = HCI_EVENT_EXTENSION_RTK; + pEvent->Data[0] = HCI_EVENT_EXT_BT_COEX_CONTROL; //extension event code + len ++; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + _rtw_memcpy(&pRetPar[0], pData, dataLen); + + len += dataLen; + + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE); +#endif + rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + +} + +/* Porting from Windows team */ +void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData) +{ + rtw_HCI_event *pEvent; + u8 *pRetPar; + u8 len=0, tx_event_length = 0; + u8 localBuf[32] = ""; + + struct bt_coex_info *pcoex_info = &padapter->coex_info; + PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt; + + /* DBG_871X("%s\n",__func__);*/ + if(pBtMgnt->ExtConfig.HCIExtensionVer < 4) //not support + { + DBG_871X("ERROR: HCIExtensionVer = %d, HCIExtensionVer<4 !!!!\n",pBtMgnt->ExtConfig.HCIExtensionVer); + return; + } + + pEvent = (rtw_HCI_event *)(&localBuf[0]); + + //len += bthci_ExtensionEventHeaderRtk(&localBuf[0], + // HCI_EVENT_EXT_BT_INFO_CONTROL); + pEvent->EventCode = HCI_EVENT_EXTENSION_RTK; + pEvent->Data[0] = HCI_EVENT_EXT_BT_INFO_CONTROL; //extension event code + len ++; + + // Return parameters starts from here + pRetPar = &pEvent->Data[len]; + _rtw_memcpy(&pRetPar[0], pData, dataLen); + + len += dataLen; + + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL"); +#endif + rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); + +} + +void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType) +{ + u8 len=0, tx_event_length=0; + u8 localBuf[7] = ""; + u8 *pRetPar; + u8 *pu1Temp; + rtw_HCI_event *pEvent; + struct bt_coex_info *pcoex_info = &padapter->coex_info; + PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt; + +// if(!pBtMgnt->BtOperationOn) +// return; + + pEvent = (rtw_HCI_event *)(&localBuf[0]); + +// len += bthci_ExtensionEventHeaderRtk(&localBuf[0], +// HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); + + pEvent->EventCode = HCI_EVENT_EXTENSION_RTK; + pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY; //extension event code + len ++; + + // Return parameters starts from here + //pRetPar = &PPacketIrpEvent->Data[len]; + //pu1Temp = (u8 *)&pRetPar[0]; + //*pu1Temp = scanType; + pEvent->Data[len] = scanType; + len += 1; + + pEvent->Length = len; + + //total tx event length + EventCode length + sizeof(length) + tx_event_length = pEvent->Length + 2; +#if 0 + rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION"); +#endif + rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE); +} +#endif //CONFIG_BT_COEXIST_SOCKET_TRX +#endif // CONFIG_BT_COEXIST + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_cmd.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_cmd.c new file mode 100644 index 00000000..e2759028 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_cmd.c @@ -0,0 +1,4584 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_CMD_C_ + +#include +#include + +#ifndef DBG_CMD_EXECUTE + #define DBG_CMD_EXECUTE 0 +#endif + +/* +Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. +No irqsave is necessary. +*/ + +sint _rtw_init_cmd_priv (struct cmd_priv *pcmdpriv) +{ + sint res=_SUCCESS; + +_func_enter_; + + _rtw_init_sema(&(pcmdpriv->cmd_queue_sema), 0); + //_rtw_init_sema(&(pcmdpriv->cmd_done_sema), 0); + _rtw_init_sema(&(pcmdpriv->terminate_cmdthread_sema), 0); + + + _rtw_init_queue(&(pcmdpriv->cmd_queue)); + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + + pcmdpriv->cmd_seq = 1; + + pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); + + if (pcmdpriv->cmd_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + + pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ( (SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); + + pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); + + if (pcmdpriv->rsp_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + + pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ( (SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); + + pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0; + + _rtw_mutex_init(&pcmdpriv->sctx_mutex); +exit: + +_func_exit_; + + return res; + +} + +#ifdef CONFIG_C2H_WK +static void c2h_wk_callback(_workitem *work); +#endif +sint _rtw_init_evt_priv(struct evt_priv *pevtpriv) +{ + sint res=_SUCCESS; + +_func_enter_; + +#ifdef CONFIG_H2CLBK + _rtw_init_sema(&(pevtpriv->lbkevt_done), 0); + pevtpriv->lbkevt_limit = 0; + pevtpriv->lbkevt_num = 0; + pevtpriv->cmdevt_parm = NULL; +#endif + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + ATOMIC_SET(&pevtpriv->event_seq, 0); + pevtpriv->evt_done_cnt = 0; + +#ifdef CONFIG_EVENT_THREAD_MODE + + _rtw_init_sema(&(pevtpriv->evt_notify), 0); + _rtw_init_sema(&(pevtpriv->terminate_evtthread_sema), 0); + + pevtpriv->evt_allocated_buf = rtw_zmalloc(MAX_EVTSZ + 4); + if (pevtpriv->evt_allocated_buf == NULL){ + res= _FAIL; + goto exit; + } + pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 - ((unsigned int)(pevtpriv->evt_allocated_buf) & 3); + + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pevtpriv->allocated_c2h_mem = rtw_zmalloc(C2H_MEM_SZ +4); + + if (pevtpriv->allocated_c2h_mem == NULL){ + res= _FAIL; + goto exit; + } + + pevtpriv->c2h_mem = pevtpriv->allocated_c2h_mem + 4\ + - ( (u32)(pevtpriv->allocated_c2h_mem) & 3); +#ifdef PLATFORM_OS_XP + pevtpriv->pc2h_mdl= IoAllocateMdl((u8 *)pevtpriv->c2h_mem, C2H_MEM_SZ , FALSE, FALSE, NULL); + + if(pevtpriv->pc2h_mdl == NULL){ + res= _FAIL; + goto exit; + } + MmBuildMdlForNonPagedPool(pevtpriv->pc2h_mdl); +#endif +#endif //end of CONFIG_SDIO_HCI + + _rtw_init_queue(&(pevtpriv->evt_queue)); + +exit: + +#endif //end of CONFIG_EVENT_THREAD_MODE + +#ifdef CONFIG_C2H_WK + _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); + pevtpriv->c2h_wk_alive = _FALSE; + pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1); +#endif + +_func_exit_; + + return res; +} + +void _rtw_free_evt_priv (struct evt_priv *pevtpriv) +{ +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("+_rtw_free_evt_priv \n")); + +#ifdef CONFIG_EVENT_THREAD_MODE + _rtw_free_sema(&(pevtpriv->evt_notify)); + _rtw_free_sema(&(pevtpriv->terminate_evtthread_sema)); + + + if (pevtpriv->evt_allocated_buf) + rtw_mfree(pevtpriv->evt_allocated_buf, MAX_EVTSZ + 4); +#endif + +#ifdef CONFIG_C2H_WK + _cancel_workitem_sync(&pevtpriv->c2h_wk); + while(pevtpriv->c2h_wk_alive) + rtw_msleep_os(10); + + while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { + void *c2h; + if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL + && c2h != (void *)pevtpriv) { + rtw_mfree(c2h, 16); + } + } + rtw_cbuf_free(pevtpriv->c2h_queue); +#endif + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n")); + +_func_exit_; + +} + +void _rtw_free_cmd_priv (struct cmd_priv *pcmdpriv) +{ +_func_enter_; + + if(pcmdpriv){ + _rtw_spinlock_free(&(pcmdpriv->cmd_queue.lock)); + _rtw_free_sema(&(pcmdpriv->cmd_queue_sema)); + //_rtw_free_sema(&(pcmdpriv->cmd_done_sema)); + _rtw_free_sema(&(pcmdpriv->terminate_cmdthread_sema)); + + if (pcmdpriv->cmd_allocated_buf) + rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ); + + if (pcmdpriv->rsp_allocated_buf) + rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4); + + _rtw_mutex_free(&pcmdpriv->sctx_mutex); + } +_func_exit_; +} + +/* +Calling Context: + +rtw_enqueue_cmd can only be called between kernel thread, +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, bool to_head) +{ + _irqL irqL; + +_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); + + if (to_head) + rtw_list_insert_head(&obj->list, &queue->queue); + else + 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); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +struct cmd_obj *_rtw_dequeue_cmd(_queue *queue) +{ + _irqL irqL; + struct cmd_obj *obj; + +_func_enter_; + + //_enter_critical_bh(&(queue->lock), &irqL); + _enter_critical(&queue->lock, &irqL); + + #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); + } + + //_exit_critical_bh(&(queue->lock), &irqL); + _exit_critical(&queue->lock, &irqL); + +_func_exit_; + + return obj; +} + +u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) +{ + u32 res; +_func_enter_; + res = _rtw_init_cmd_priv (pcmdpriv); +_func_exit_; + return res; +} + +u32 rtw_init_evt_priv (struct evt_priv *pevtpriv) +{ + int res; +_func_enter_; + res = _rtw_init_evt_priv(pevtpriv); +_func_exit_; + return res; +} + +void rtw_free_evt_priv (struct evt_priv *pevtpriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_evt_priv\n")); + _rtw_free_evt_priv(pevtpriv); +_func_exit_; +} + +void rtw_free_cmd_priv (struct cmd_priv *pcmdpriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_cmd_priv\n")); + _rtw_free_cmd_priv(pcmdpriv); +_func_exit_; +} + +int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); +int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) +{ + u8 bAllow = _FALSE; //set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE + + #ifdef SUPPORT_HW_RFOFF_DETECTED + //To decide allow or not + if( (adapter_to_pwrctl(pcmdpriv->padapter)->bHWPwrPindetect) + &&(!pcmdpriv->padapter->registrypriv.usbss_enable) + ) + { + if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ) + { + struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; + if(pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) + { + //DBG_871X("==>enqueue POWER_SAVING_CTRL_WK_CID\n"); + bAllow = _TRUE; + } + } + } + #endif + +#ifndef CONFIG_C2H_PACKET_EN + /* C2H should be always allowed */ + if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; + if(pdrvextra_cmd_parm->ec_id == C2H_WK_CID) { + bAllow = _TRUE; + } + } +#endif + + if(cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) + bAllow = _TRUE; + + if (cmd_obj->no_io) + bAllow = _TRUE; + + if ((!rtw_is_hw_init_completed(pcmdpriv->padapter) && (bAllow == _FALSE)) + || ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _FALSE //com_thread not running + ) { + if (DBG_CMD_EXECUTE) + DBG_871X(ADPT_FMT" drop "CMD_FMT" hw_init_completed:%u, cmdthd_running:%u\n", ADPT_ARG(cmd_obj->padapter) + , CMD_ARG(cmd_obj), rtw_get_hw_init_completed(cmd_obj->padapter), ATOMIC_READ(&pcmdpriv->cmdthd_running)); + if (0) + rtw_warn_on(1); + + return _FAIL; + } + return _SUCCESS; +} + + + +u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) +{ + int res = _FAIL; + PADAPTER padapter = pcmdpriv->padapter; + +_func_enter_; + + if (cmd_obj == NULL) { + goto exit; + } + + cmd_obj->padapter = padapter; + +#ifdef CONFIG_CONCURRENT_MODE + //change pcmdpriv to primary's pcmdpriv + if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter) + pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv); +#endif + + if( _FAIL == (res=rtw_cmd_filter(pcmdpriv, cmd_obj)) ) { + if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + struct drvextra_cmd_parm *extra_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; + + if (extra_parm->pbuf && extra_parm->size > 0) + rtw_mfree(extra_parm->pbuf, extra_parm->size); + } + rtw_free_cmd_obj(cmd_obj); + goto exit; + } + + res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj, 0); + + if(res == _SUCCESS) + _rtw_up_sema(&pcmdpriv->cmd_queue_sema); + +exit: + +_func_exit_; + + return res; +} + +struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) +{ + struct cmd_obj *cmd_obj; + +_func_enter_; + + cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); + +_func_exit_; + return cmd_obj; +} + +void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) +{ +_func_enter_; + pcmdpriv->cmd_done_cnt++; + //_rtw_up_sema(&(pcmdpriv->cmd_done_sema)); +_func_exit_; +} + +void rtw_free_cmd_obj(struct cmd_obj *pcmd) +{ + struct drvextra_cmd_parm *extra_parm = NULL; +_func_enter_; + + if (pcmd->parmbuf != NULL) { + /* free parmbuf in cmd_obj */ + rtw_mfree((unsigned char *)pcmd->parmbuf, pcmd->cmdsz); + } + if(pcmd->rsp!=NULL) + { + if(pcmd->rspsz!= 0) + { + //free rsp in cmd_obj + rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz); + } + } + + //free cmd_obj + rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj)); + +_func_exit_; +} + + +void rtw_stop_cmd_thread(_adapter *adapter) +{ + if(adapter->cmdThread && + ATOMIC_READ(&(adapter->cmdpriv.cmdthd_running)) == _TRUE && + adapter->cmdpriv.stop_req == 0) + { + adapter->cmdpriv.stop_req = 1; + _rtw_up_sema(&adapter->cmdpriv.cmd_queue_sema); + _rtw_down_sema(&adapter->cmdpriv.terminate_cmdthread_sema); + } +} + +thread_return rtw_cmd_thread(thread_context context) +{ + u8 ret; + struct cmd_obj *pcmd; + u8 *pcmdbuf, *prspbuf; + u32 cmd_start_time; + u32 cmd_process_time; + u8 (*cmd_hdl)(_adapter *padapter, u8* pbuf); + void (*pcmd_callback)(_adapter *dev, struct cmd_obj *pcmd); + 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"); + + pcmdbuf = pcmdpriv->cmd_buf; + prspbuf = pcmdpriv->rsp_buf; + + pcmdpriv->stop_req = 0; + ATOMIC_SET(&(pcmdpriv->cmdthd_running), _TRUE); + _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("start r871x rtw_cmd_thread !!!!\n")); + + while (1) { + if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break\n", FUNC_ADPT_ARG(padapter)); + break; + } + + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%s) SurpriseRemoved(%s) break at line %d\n", + __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False" + , __LINE__); + break; + } + + if (pcmdpriv->stop_req) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req); + 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); + +_next: + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%s) SurpriseRemoved(%s) break at line %d\n", + __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False" + , __LINE__); + break; + } + + pcmd = rtw_dequeue_cmd(pcmdpriv); + if (!pcmd) { + #ifdef CONFIG_LPS_LCLK + rtw_unregister_cmd_alive(padapter); + #endif + continue; + } + + cmd_start_time = rtw_get_current_time(); + pcmdpriv->cmd_issued_cnt++; + + if (pcmd->cmdsz > MAX_CMDSZ) { + DBG_871X_LEVEL(_drv_err_, "%s cmdsz:%d > MAX_CMDSZ:%d\n", __func__, pcmd->cmdsz, MAX_CMDSZ); + pcmd->res = H2C_PARAMETERS_ERROR; + goto post_process; + } + + if (pcmd->cmdcode >= (sizeof(wlancmds) / sizeof(struct cmd_hdl))) { + DBG_871X_LEVEL(_drv_err_, "%s undefined cmdcode:%d\n", __func__, pcmd->cmdcode); + pcmd->res = H2C_PARAMETERS_ERROR; + goto post_process; + } + + cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; + if (!cmd_hdl) { + DBG_871X_LEVEL(_drv_err_, "%s no cmd_hdl for cmdcode:%d\n", __func__, pcmd->cmdcode); + pcmd->res = H2C_PARAMETERS_ERROR; + goto post_process; + } + + 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; + } + + #ifdef CONFIG_LPS_LCLK + if (pcmd->no_io) { + rtw_unregister_cmd_alive(padapter); + } else { + if (rtw_register_cmd_alive(padapter) != _SUCCESS) { + if (DBG_CMD_EXECUTE) + DBG_871X_LEVEL(_drv_always_, "%s: wait to leave LPS_LCLK\n", __func__); + + pcmd->res = H2C_ENQ_HEAD; + ret = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, pcmd, 1); + if (ret == _SUCCESS) { + if (DBG_CMD_EXECUTE) + DBG_871X(ADPT_FMT" "CMD_FMT" ENQ_HEAD\n", ADPT_ARG(pcmd->padapter), CMD_ARG(pcmd)); + continue; + } + + DBG_871X(ADPT_FMT" "CMD_FMT" ENQ_HEAD_FAIL\n", ADPT_ARG(pcmd->padapter), CMD_ARG(pcmd)); + pcmd->res = H2C_ENQ_HEAD_FAIL; + rtw_warn_on(1); + } + } + #endif /* CONFIG_LPS_LCLK */ + + if (DBG_CMD_EXECUTE) + DBG_871X(ADPT_FMT" "CMD_FMT" %sexecute\n", ADPT_ARG(pcmd->padapter), CMD_ARG(pcmd) + , pcmd->res == H2C_ENQ_HEAD ? "ENQ_HEAD " : (pcmd->res == H2C_ENQ_HEAD_FAIL ? "ENQ_HEAD_FAIL " : "")); + + _rtw_memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); + ret = cmd_hdl(pcmd->padapter, pcmdbuf); + pcmd->res = ret; + + pcmdpriv->cmd_seq++; + +post_process: + + _enter_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL); + if (pcmd->sctx) { + if (0) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n", + FUNC_ADPT_ARG(pcmd->padapter)); + if (pcmd->res == H2C_SUCCESS) + rtw_sctx_done(&pcmd->sctx); + else + rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR); + } + _exit_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL); + + cmd_process_time = rtw_get_passing_time_ms(cmd_start_time); + if (cmd_process_time > 1000) { + DBG_871X(ADPT_FMT" "CMD_FMT" process_time=%d\n", ADPT_ARG(pcmd->padapter), CMD_ARG(pcmd), cmd_process_time); + if (0) + rtw_warn_on(1); + } + + //call callback function for post-processed + if(pcmd->cmdcode < (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback))) + { + pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; + if(pcmd_callback == NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("mlme_cmd_hdl(): pcmd_callback=0x%p, cmdcode=0x%x\n", pcmd_callback, pcmd->cmdcode)); + rtw_free_cmd_obj(pcmd); + } + else + { + //todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL) + pcmd_callback(pcmd->padapter, pcmd);//need conider that free cmd_obj in rtw_cmd_callback + } + } + else + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("%s: cmdcode=0x%x callback not defined!\n", __FUNCTION__, pcmd->cmdcode)); + rtw_free_cmd_obj(pcmd); + } + + flush_signals_thread(); + + goto _next; + + } + +#ifdef CONFIG_LPS_LCLK + rtw_unregister_cmd_alive(padapter); +#endif + + /* free all cmd_obj resources */ + do { + pcmd = rtw_dequeue_cmd(pcmdpriv); + if (pcmd == NULL) + break; + + if (0) + DBG_871X("%s: leaving... drop "CMD_FMT"\n", __func__, CMD_ARG(pcmd)); + + if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; + if(extra_parm->pbuf && extra_parm->size > 0) { + rtw_mfree(extra_parm->pbuf, extra_parm->size); + } + } + + rtw_free_cmd_obj(pcmd); + } while (1); + + _rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema); + ATOMIC_SET(&(pcmdpriv->cmdthd_running), _FALSE); + +_func_exit_; + + thread_exit(); + +} + + +#ifdef CONFIG_EVENT_THREAD_MODE +u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj) +{ + _irqL irqL; + int res; + _queue *queue = &pevtpriv->evt_queue; + +_func_enter_; + + res = _SUCCESS; + + if (obj == NULL) { + res = _FAIL; + goto exit; + } + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_insert_tail(&obj->list, &queue->queue); + + _exit_critical_bh(&queue->lock, &irqL); + + //rtw_evt_notify_isr(pevtpriv); + +exit: + +_func_exit_; + + return res; +} + +struct evt_obj *rtw_dequeue_evt(_queue *queue) +{ + _irqL irqL; + struct evt_obj *pevtobj; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (rtw_is_list_empty(&(queue->queue))) + pevtobj = NULL; + else + { + pevtobj = LIST_CONTAINOR(get_next(&(queue->queue)), struct evt_obj, list); + rtw_list_delete(&pevtobj->list); + } + + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; + + return pevtobj; +} + +void rtw_free_evt_obj(struct evt_obj *pevtobj) +{ +_func_enter_; + + if(pevtobj->parmbuf) + rtw_mfree((unsigned char*)pevtobj->parmbuf, pevtobj->evtsz); + + rtw_mfree((unsigned char*)pevtobj, sizeof(struct evt_obj)); + +_func_exit_; +} + +void rtw_evt_notify_isr(struct evt_priv *pevtpriv) +{ +_func_enter_; + pevtpriv->evt_done_cnt++; + _rtw_up_sema(&(pevtpriv->evt_notify)); +_func_exit_; +} +#endif + + +/* +u8 rtw_setstandby_cmd(unsigned char *adapter) +*/ +u8 rtw_setstandby_cmd(_adapter *padapter, uint action) +{ + struct cmd_obj* ph2c; + struct usb_suspend_parm* psetusbsuspend; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + + u8 ret = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + ret = _FAIL; + goto exit; + } + + psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm)); + if (psetusbsuspend == NULL) { + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + ret = _FAIL; + goto exit; + } + + psetusbsuspend->action = action; + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); + + ret = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return ret; +} + +/* +rtw_sitesurvey_cmd(~) + ### NOTE:#### (!!!!) + MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock +*/ +u8 rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *ssid, int ssid_num, + struct rtw_ieee80211_channel *ch, int ch_num) +{ + u8 res = _FAIL; + struct cmd_obj *ph2c; + struct sitesurvey_parm *psurveyPara; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + +_func_enter_; + +#ifdef CONFIG_LPS + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE){ + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); + } +#endif + +#ifdef CONFIG_P2P_PS + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1); + } +#endif //CONFIG_P2P_PS + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) + return _FAIL; + + psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm)); + if (psurveyPara == NULL) { + rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj)); + return _FAIL; + } + + rtw_free_network_queue(padapter, _FALSE); + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __FUNCTION__)); + + init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + + /* psurveyPara->bsslimit = 48; */ + psurveyPara->scan_mode = pmlmepriv->scan_mode; + + /* prepare ssid list */ + if (ssid) { + int i; + for (i=0; issid[i], &ssid[i], sizeof(NDIS_802_11_SSID)); + psurveyPara->ssid_num++; + if (0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter), + psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength); + } + } + } + + /* prepare channel list */ + if (ch) { + int i; + for (i=0; ich[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); + psurveyPara->ch_num++; + if (0) + DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), + psurveyPara->ch[i].hw_value); + } + } + } + + set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + if(res == _SUCCESS) { + + pmlmepriv->scan_start_time = rtw_get_current_time(); + +#ifdef CONFIG_SCAN_BACKOP + if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) + { + if(IsSupported5G(padapter->registrypriv.wireless_mode) + && IsSupported24G(padapter->registrypriv.wireless_mode)) //dual band + mlme_set_scan_to_timer(pmlmepriv, CONC_SCANNING_TIMEOUT_DUAL_BAND); + else //single band + mlme_set_scan_to_timer(pmlmepriv, CONC_SCANNING_TIMEOUT_SINGLE_BAND); + } + else +#endif /* CONFIG_SCAN_BACKOP */ + mlme_set_scan_to_timer(pmlmepriv, SCANNING_TIMEOUT); + + rtw_led_control(padapter, LED_CTL_SITE_SURVEY); + } else { + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + } + +_func_exit_; + + return res; +} + +u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset) +{ + struct cmd_obj* ph2c; + struct setdatarate_parm* pbsetdataratepara; + struct cmd_priv* pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm)); + if (pbsetdataratepara == NULL) { + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); +#ifdef MP_FIRMWARE_OFFLOAD + pbsetdataratepara->curr_rateidx = *(u32*)rateset; +// _rtw_memcpy(pbsetdataratepara, rateset, sizeof(u32)); +#else + pbsetdataratepara->mac_id = 5; + _rtw_memcpy(pbsetdataratepara->datarates, rateset, NumRates); +#endif + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset) +{ + struct cmd_obj* ph2c; + struct setbasicrate_parm* pssetbasicratepara; + struct cmd_priv* pcmdpriv=&padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res= _FAIL; + goto exit; + } + pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm)); + + if (pssetbasicratepara == NULL) { + rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); + + _rtw_memcpy(pssetbasicratepara->basicrates, rateset, NumRates); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; +} + + +/* +unsigned char rtw_setphy_cmd(unsigned char *adapter) + +1. be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program +2. for AdHoc/Ap mode or mp mode? + +*/ +u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch) +{ + struct cmd_obj* ph2c; + struct setphy_parm* psetphypara; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +// struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +// struct registry_priv* pregistry_priv = &padapter->registrypriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm)); + + if(psetphypara==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem)); + + psetphypara->modem = modem; + psetphypara->rfchannel = ch; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_getmacreg_cmd(_adapter *padapter, u8 len, u32 addr) +{ + struct cmd_obj *ph2c; + struct readMAC_parm *preadmacparm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + preadmacparm = (struct readMAC_parm *)rtw_zmalloc(sizeof(struct readMAC_parm)); + + if (preadmacparm == NULL) { + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, preadmacparm, GEN_CMD_CODE(_GetMACReg)); + + preadmacparm->len = len; + preadmacparm->addr = addr; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: +_func_exit_; + return res; +} + +void rtw_usb_catc_trigger_cmd(_adapter *padapter, const char *caller) +{ + DBG_871X("%s caller:%s\n", __func__, caller); + rtw_getmacreg_cmd(padapter, 1, 0x1c4); +} + +u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val) +{ + struct cmd_obj* ph2c; + struct writeBB_parm* pwritebbparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm)); + + if(pwritebbparm==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); + + pwritebbparm->offset = offset; + pwritebbparm->value = val; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_getbbreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +{ + struct cmd_obj* ph2c; + struct readBB_parm* prdbbparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res=_FAIL; + goto exit; + } + prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm)); + + if(prdbbparm ==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + return _FAIL; + } + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg); + ph2c->parmbuf = (unsigned char *)prdbbparm; + ph2c->cmdsz = sizeof(struct readBB_parm); + ph2c->rsp = pval; + ph2c->rspsz = sizeof(struct readBB_rsp); + + prdbbparm ->offset = offset; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_setrfreg_cmd(_adapter *padapter, u8 offset, u32 val) +{ + struct cmd_obj* ph2c; + struct writeRF_parm* pwriterfparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm)); + + if(pwriterfparm==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); + + pwriterfparm->offset = offset; + pwriterfparm->value = val; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; +} + +u8 rtw_getrfreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +{ + struct cmd_obj* ph2c; + struct readRF_parm* prdrfparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm)); + if(prdrfparm ==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg); + ph2c->parmbuf = (unsigned char *)prdrfparm; + ph2c->cmdsz = sizeof(struct readRF_parm); + ph2c->rsp = pval; + ph2c->rspsz = sizeof(struct readRF_rsp); + + prdrfparm ->offset = offset; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} + +void rtw_getbbrfreg_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _func_enter_; + + //rtw_free_cmd_obj(pcmd); + rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); + rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + padapter->mppriv.workparam.bcompleted= _TRUE; +#endif +_func_exit_; +} + +void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _func_enter_; + + rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); + rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + padapter->mppriv.workparam.bcompleted= _TRUE; +#endif + +_func_exit_; +} + +static u8 rtw_createbss_cmd(_adapter *adapter, int flags, bool adhoc + , s16 req_ch, u8 req_bw, u8 req_offset) +{ + struct cmd_obj *cmdobj; + struct createbss_parm *parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + + /* prepare cmd parameter */ + parm = (struct createbss_parm *)rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) { + res = _FAIL; + goto exit; + } + + if (adhoc) { + /* for now, adhoc doesn't support ch,bw,offset request */ + parm->adhoc = 1; + } else { + parm->adhoc = 0; + parm->req_ch = req_ch; + parm->req_bw = req_bw; + parm->req_offset = req_offset; + } + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != createbss_hdl(adapter, (u8 *)parm)) + res = _FAIL; + rtw_mfree((u8 *)parm, sizeof(*parm)); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; + rtw_mfree((u8 *)parm, sizeof(*parm)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_CreateBss)); + + if (flags & RTW_CMDF_WAIT_ACK) { + cmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 2000); + } + + res = rtw_enqueue_cmd(pcmdpriv, cmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + cmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + } + } + +exit: + return res; +} + +inline u8 rtw_create_ibss_cmd(_adapter *adapter, int flags) +{ + return rtw_createbss_cmd(adapter, flags + , 1 + , -1, 0, 0 /* for now, adhoc doesn't support ch,bw,offset request */ + ); +} + +inline u8 rtw_startbss_cmd(_adapter *adapter, int flags) +{ + return rtw_createbss_cmd(adapter, flags + , 0 + , -1, 0, 0 /* doesn't request ch, bw, offset */ + ); +} + +inline u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags, u8 req_ch, u8 req_bw, u8 req_offset) +{ + return rtw_createbss_cmd(adapter, flags + , 0 + , req_ch, req_bw, req_offset + ); +} + +u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork) +{ + u8 *auth, res = _SUCCESS; + uint t_len = 0; + WLAN_BSSID_EX *psecnetwork; + struct cmd_obj *pcmd; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv = &pmlmepriv->htpriv; +#endif //CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; +#endif //CONFIG_80211AC_VHT + NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u32 tmp_len; + u8 *ptmp=NULL; +_func_enter_; + + rtw_led_control(padapter, LED_CTL_START_TO_LINK); + + if (pmlmepriv->assoc_ssid.SsidLength == 0){ + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); + } else { + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid=[%s]\n", pmlmepriv->assoc_ssid.Ssid)); + } + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res=_FAIL; + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); + goto exit; + } + /* // for IEs is pointer + t_len = sizeof (ULONG) + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) + + sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + + sizeof (NDIS_802_11_CONFIGURATION) + + sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) + + sizeof (NDIS_802_11_RATES_EX)+ sizeof(WLAN_PHY_INFO)+ sizeof (ULONG) + MAX_IE_SZ; + */ + //for IEs is fix buf size + t_len = sizeof(WLAN_BSSID_EX); + + + //for hidden ap to set fw_state here + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != _TRUE) + { + switch(ndis_network_mode) + { + case Ndis802_11IBSS: + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + break; + + case Ndis802_11Infrastructure: + set_fwstate(pmlmepriv, WIFI_STATION_STATE); + break; + + case Ndis802_11APMode: + case Ndis802_11AutoUnknown: + case Ndis802_11InfrastructureMax: + case Ndis802_11Monitor: + break; + + } + } + + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); + + /* + Modified by Arvin 2015/05/13 + Solution for allocating a new WLAN_BSSID_EX to avoid race condition issue between disconnect and joinbss + */ + psecnetwork = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX)); + if(psecnetwork==NULL) + { + if(pcmd !=NULL) + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + + res=_FAIL; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork==NULL!!!\n")); + + goto exit; + } + + _rtw_memset(psecnetwork, 0, t_len); + + _rtw_memcpy(psecnetwork, &pnetwork->network, get_WLAN_BSSID_EX_sz(&pnetwork->network)); + + auth=&psecuritypriv->authenticator_ie[0]; + psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength; + + if((psecnetwork->IELength-12) < (256-1)) { + _rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12); + } else { + _rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); + } + + psecnetwork->IELength = 0; + // Added by Albert 2009/02/18 + // If the the driver wants to use the bssid to create the connection. + // If not, we have to copy the connecting AP's MAC address to it so that + // the driver just has the bssid information for PMKIDList searching. + + if ( pmlmepriv->assoc_by_bssid == _FALSE ) + { + _rtw_memcpy( &pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN ); + } + + psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); + + + pqospriv->qos_option = 0; + + if(pregistrypriv->wmm_enable) + { + tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); + + if (psecnetwork->IELength != tmp_len) + { + psecnetwork->IELength = tmp_len; + pqospriv->qos_option = 1; //There is WMM IE in this corresp. beacon + } + else + { + pqospriv->qos_option = 0;//There is no WMM IE in this corresp. beacon + } + } + +#ifdef CONFIG_80211N_HT + phtpriv->ht_option = _FALSE; + ptmp = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &tmp_len, pnetwork->network.IELength-12); + if(pregistrypriv->ht_enable && ptmp && tmp_len>0) + { + // Added by Albert 2010/06/23 + // For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. + // Especially for Realtek 8192u SoftAP. + if ( ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_ ) && + ( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_ ) && + ( padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_ )) + { + rtw_ht_use_default_setting(padapter); + + 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], + pnetwork->network.IELength-12, &psecnetwork->IELength, + pnetwork->network.Configuration.DSConfig); + } + } + +#ifdef CONFIG_80211AC_VHT + pvhtpriv->vht_option = _FALSE; + if (phtpriv->ht_option && pregistrypriv->vht_enable + && (!pmlmepriv->country_ent || COUNTRY_CHPLAN_EN_11AC(pmlmepriv->country_ent)) + ) { + rtw_restructure_vht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], + pnetwork->network.IELength, &psecnetwork->IELength); + } +#endif + + rtw_append_exented_cap(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength); + +#endif //CONFIG_80211N_HT + + #if 0 + psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength; + + if(psecnetwork->IELength < (256-1)) + { + _rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], psecnetwork->IELength); + } + else + { + _rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], (256-1)); + } + #endif + + pcmd->cmdsz = sizeof(WLAN_BSSID_EX); + +#ifdef CONFIG_RTL8712 + //wlan_network endian conversion + psecnetwork->Length = cpu_to_le32(psecnetwork->Length); + psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength); + psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy); + psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi); + psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse); + psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow); + psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod); + psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig); + psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime); + psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern); + psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet); + psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length); + psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length); + psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode); + psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength); +#endif + + _rtw_init_listhead(&pcmd->list); + pcmd->cmdcode = _JoinBss_CMD_;//GEN_CMD_CODE(_JoinBss) + pcmd->parmbuf = (unsigned char *)psecnetwork; + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_disassoc_cmd(_adapter*padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ +{ + struct cmd_obj *cmdobj = NULL; + struct disconnect_parm *param = NULL; + struct cmd_priv *cmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n")); + + /* prepare cmd parameter */ + param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param)); + if (param == NULL) { + res = _FAIL; + goto exit; + } + param->deauth_timeout_ms = deauth_timeout_ms; + + if (enqueue) { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; + rtw_mfree((u8 *)param, sizeof(*param)); + goto exit; + } + init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); + res = rtw_enqueue_cmd(cmdpriv, cmdobj); + } else { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) + res = _FAIL; + rtw_mfree((u8 *)param, sizeof(*param)); + } + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue) +{ + struct cmd_obj* ph2c; + struct setopmode_parm* psetop; + + struct cmd_priv *pcmdpriv= &padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm)); + + if(psetop==NULL){ + res=_FAIL; + goto exit; + } + psetop->mode = (u8)networktype; + + if(enqueue){ + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + rtw_mfree((u8 *)psetop, sizeof(*psetop)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else{ + setopmode_hdl(padapter, (u8 *)psetop); + rtw_mfree((u8 *)psetop, sizeof(*psetop)); + } +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool enqueue) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct set_stakey_rsp *psetstakey_rsp = NULL; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 res=_SUCCESS; + +_func_enter_; + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + res=_FAIL; + goto exit; + } + + _rtw_memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){ + psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm; + }else{ + GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE); + } + + if (key_type == GROUP_KEY) { + _rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); + } + else if (key_type == UNICAST_KEY) { + _rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); + } +#ifdef CONFIG_TDLS + else if(key_type == TDLS_KEY){ + _rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, 16); + psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy; + } +#endif /* CONFIG_TDLS */ + + //jeff: set this becasue at least sw key is ready + padapter->securitypriv.busetkipkey=_TRUE; + + if(enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + res= _FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + ph2c->rsp = (u8 *) psetstakey_rsp; + ph2c->rspsz = sizeof(struct set_stakey_rsp); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else{ + set_stakey_hdl(padapter, (u8 *)psetstakey_para); + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + } +exit: + +_func_exit_; + + return res; +} + +u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue) +{ + struct cmd_obj* ph2c; + struct set_stakey_parm *psetstakey_para; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + struct set_stakey_rsp *psetstakey_rsp = NULL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + s16 cam_id = 0; + u8 res=_SUCCESS; + +_func_enter_; + + if(!enqueue) + { + while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1, -1)) >= 0) { + DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(sta->hwaddr), cam_id); + clear_cam_entry(padapter, cam_id); + rtw_camid_free(padapter, cam_id); + } + } + else + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ + res= _FAIL; + goto exit; + } + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); + ph2c->rsp = (u8 *) psetstakey_rsp; + ph2c->rspsz = sizeof(struct set_stakey_rsp); + + _rtw_memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); + + psetstakey_para->algorithm = _NO_PRIVACY_; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + } + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table) +{ + struct cmd_obj* ph2c; + struct setratable_parm * psetrttblparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm)); + + if(psetrttblparm==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); + + _rtw_memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; + +} + +u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval) +{ + struct cmd_obj* ph2c; + struct getratable_parm * pgetrttblparm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm)); + + if(pgetrttblparm==NULL){ + rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + +// init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); + + _rtw_init_listhead(&ph2c->list); + ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable); + ph2c->parmbuf = (unsigned char *)pgetrttblparm; + ph2c->cmdsz = sizeof(struct getratable_parm); + ph2c->rsp = (u8*)pval; + ph2c->rspsz = sizeof(struct getratable_rsp); + + pgetrttblparm ->rsvd = 0x0; + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: +_func_exit_; + return res; + +} + +u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr) +{ + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct cmd_obj* ph2c; + struct set_assocsta_parm *psetassocsta_para; + struct set_stakey_rsp *psetassocsta_rsp = NULL; + + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm)); + if(psetassocsta_para==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + res=_FAIL; + goto exit; + } + + psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp)); + if(psetassocsta_rsp==NULL){ + rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm)); + return _FAIL; + } + + init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); + ph2c->rsp = (u8 *) psetassocsta_rsp; + ph2c->rspsz = sizeof(struct set_assocsta_rsp); + + _rtw_memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + } + +u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr) +{ + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct cmd_obj* ph2c; + struct addBaReq_parm *paddbareq_parm; + + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm)); + if(paddbareq_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + paddbareq_parm->tid = tid; + _rtw_memcpy(paddbareq_parm->addr, addr, ETH_ALEN); + + init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); + + //DBG_871X("rtw_addbareq_cmd, tid=%d\n", tid); + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} +//add for CONFIG_IEEE80211W, none 11w can use it +u8 rtw_reset_securitypriv_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + +u8 rtw_free_assoc_resources_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + +u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter) +{ + struct cmd_obj* ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv=&padapter->cmdpriv; + u8 res=_SUCCESS; + +_func_enter_; + + //only primary padapter does this cmd +/* +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter) + pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv); +#endif +*/ + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + + //rtw_enqueue_cmd(pcmdpriv, ph2c); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} + +u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) +{ + struct cmd_obj *pcmdobj; + struct set_ch_parm *set_ch_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); + + /* check input parameter */ + + /* prepare cmd parameter */ + set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm)); + if (set_ch_parm == NULL) { + res= _FAIL; + goto exit; + } + set_ch_parm->ch = ch; + set_ch_parm->bw = bw; + set_ch_parm->ch_offset = ch_offset; + + if (enqueue) { + /* need enqueue, prepare cmd_obj and enqueue */ + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); + res=_FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + } else { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) ) + res = _FAIL; + + rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); + } + + /* do something based on res... */ + +exit: + + DBG_871X(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); + +_func_exit_; + + return res; +} + +u8 _rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, const struct country_chplan *country_ent, u8 swconfig) +{ + struct cmd_obj *cmdobj; + struct SetChannelPlan_param *parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct submit_ctx sctx; + u8 res = _SUCCESS; + +_func_enter_; + + /* check if allow software config */ + if (swconfig && rtw_hal_is_disable_sw_channel_plan(adapter) == _TRUE) { + res = _FAIL; + goto exit; + } + + /* if country_entry is provided, replace chplan */ + if (country_ent) + chplan = country_ent->chplan; + + /* check input parameter */ + if (!rtw_is_channel_plan_valid(chplan)) { + res = _FAIL; + goto exit; + } + + /* prepare cmd parameter */ + parm = (struct SetChannelPlan_param *)rtw_zmalloc(sizeof(*parm)); + if (parm == NULL) { + res = _FAIL; + goto exit; + } + parm->country_ent = country_ent; + parm->channel_plan = chplan; + + if (flags & RTW_CMDF_DIRECTLY) { + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != set_chplan_hdl(adapter, (u8 *)parm)) + res = _FAIL; + rtw_mfree((u8 *)parm, sizeof(*parm)); + } else { + /* need enqueue, prepare cmd_obj and enqueue */ + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; + rtw_mfree((u8 *)parm, sizeof(*parm)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmdobj, parm, GEN_CMD_CODE(_SetChannelPlan)); + + if (flags & RTW_CMDF_WAIT_ACK) { + cmdobj->sctx = &sctx; + rtw_sctx_init(&sctx, 2000); + } + + res = rtw_enqueue_cmd(pcmdpriv, cmdobj); + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); + _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + if (sctx.status == RTW_SCTX_SUBMITTED) + cmdobj->sctx = NULL; + _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); + } + } + +exit: + +_func_exit_; + + return res; +} + +inline u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig) +{ + return _rtw_set_chplan_cmd(adapter, flags, chplan, NULL, swconfig); +} + +inline u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig) +{ + const struct country_chplan *ent; + + if (is_alpha(country_code[0]) == _FALSE + || is_alpha(country_code[1]) == _FALSE + ) { + DBG_871X_LEVEL(_drv_always_, "%s input country_code is not alpha2\n", __func__); + return _FAIL; + } + + ent = rtw_get_chplan_from_country(country_code); + + if (ent == NULL) { + DBG_871X_LEVEL(_drv_always_, "%s unsupported country_code:\"%c%c\"\n", __func__, country_code[0], country_code[1]); + return _FAIL; + } + + DBG_871X_LEVEL(_drv_always_, "%s country_code:\"%c%c\" mapping to chplan:0x%02x\n", __func__, country_code[0], country_code[1], ent->chplan); + + return _rtw_set_chplan_cmd(adapter, flags, RTW_CHPLAN_MAX, ent, swconfig); +} + +u8 rtw_led_blink_cmd(_adapter*padapter, PVOID pLed) +{ + struct cmd_obj* pcmdobj; + struct LedBlink_param *ledBlink_param; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + ledBlink_param = (struct LedBlink_param *)rtw_zmalloc(sizeof(struct LedBlink_param)); + if(ledBlink_param == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + ledBlink_param->pLed=pLed; + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no) +{ + struct cmd_obj* pcmdobj; + struct SetChannelSwitch_param*setChannelSwitch_param; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct SetChannelSwitch_param)); + if(setChannelSwitch_param == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + setChannelSwitch_param->new_ch_no=new_ch_no; + + init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +exit: + +_func_exit_; + + return res; +} + +u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option) +{ + struct cmd_obj* pcmdobj; + struct TDLSoption_param *TDLSoption; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res=_SUCCESS; + +_func_enter_; + +#ifdef CONFIG_TDLS + + RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_tdls_cmd\n")); + + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ + res=_FAIL; + goto exit; + } + + TDLSoption= (struct TDLSoption_param *)rtw_zmalloc(sizeof(struct TDLSoption_param)); + if(TDLSoption == NULL) { + rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_spinlock(&(padapter->tdlsinfo.cmd_lock)); + if (addr != NULL) + _rtw_memcpy(TDLSoption->addr, addr, 6); + TDLSoption->option = option; + _rtw_spinunlock(&(padapter->tdlsinfo.cmd_lock)); + init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS)); + res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); + +#endif //CONFIG_TDLS + +exit: + + +_func_exit_; + + return res; +} + +u8 rtw_enable_hw_update_tsf_cmd(_adapter *padapter) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + + ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = EN_HW_UPDATE_TSF_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + return res; +} + + +static void collect_traffic_statistics(_adapter *padapter) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + // Tx + pdvobjpriv->traffic_stat.tx_bytes = padapter->xmitpriv.tx_bytes; + pdvobjpriv->traffic_stat.tx_pkts = padapter->xmitpriv.tx_pkts; + pdvobjpriv->traffic_stat.tx_drop = padapter->xmitpriv.tx_drop; + + // Rx + pdvobjpriv->traffic_stat.rx_bytes = padapter->recvpriv.rx_bytes; + pdvobjpriv->traffic_stat.rx_pkts = padapter->recvpriv.rx_pkts; + pdvobjpriv->traffic_stat.rx_drop = padapter->recvpriv.rx_drop; + +#ifdef CONFIG_CONCURRENT_MODE + // Add secondary adapter statistics + if(rtw_buddy_adapter_up(padapter)) + { + // Tx + pdvobjpriv->traffic_stat.tx_bytes += padapter->pbuddy_adapter->xmitpriv.tx_bytes; + pdvobjpriv->traffic_stat.tx_pkts += padapter->pbuddy_adapter->xmitpriv.tx_pkts; + pdvobjpriv->traffic_stat.tx_drop += padapter->pbuddy_adapter->xmitpriv.tx_drop; + + // Rx + pdvobjpriv->traffic_stat.rx_bytes += padapter->pbuddy_adapter->recvpriv.rx_bytes; + pdvobjpriv->traffic_stat.rx_pkts += padapter->pbuddy_adapter->recvpriv.rx_pkts; + pdvobjpriv->traffic_stat.rx_drop += padapter->pbuddy_adapter->recvpriv.rx_drop; + } +#endif + + // Calculate throughput in last interval + pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes; + pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes; + pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes; + pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes; + + pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes *8/2/1024/1024); + 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; + u16 BusyThresholdHigh; + u16 BusyThresholdLow; + u16 BusyThreshold; + u8 bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE; + u8 bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE; + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo); + struct tdls_txmgmt txmgmt; + u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +#endif //CONFIG_TDLS + + RT_LINK_DETECT_T * link_detect = &pmlmepriv->LinkDetectInfo; + +#ifdef CONFIG_BT_COEXIST + if (padapter->registrypriv.wifi_spec != 1) { + BusyThresholdHigh = 25; + BusyThresholdLow = 10; + } else +#endif /* CONFIG_BT_COEXIST */ + { + BusyThresholdHigh = 100; + BusyThresholdLow = 75; + } + BusyThreshold = BusyThresholdHigh; + + collect_traffic_statistics(padapter); + + // + // Determine if our traffic is busy now + // + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) + { + // if we raise bBusyTraffic in last watchdog, using lower threshold. + if (pmlmepriv->LinkDetectInfo.bBusyTraffic) + BusyThreshold = BusyThresholdLow; + + if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold ) + { + bBusyTraffic = _TRUE; + + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + bRxBusyTraffic = _TRUE; + else + bTxBusyTraffic = _TRUE; + } + + // Higher Tx/Rx data. + if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000 ) + { + bHigherBusyTraffic = _TRUE; + + if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) + bHigherBusyRxTraffic = _TRUE; + else + bHigherBusyTxTraffic = _TRUE; + } + +#ifdef CONFIG_TRAFFIC_PROTECT +#define TX_ACTIVE_TH 10 +#define RX_ACTIVE_TH 20 +#define TRAFFIC_PROTECT_PERIOD_MS 4500 + + if (link_detect->NumTxOkInPeriod > TX_ACTIVE_TH + || link_detect->NumRxUnicastOkInPeriod > RX_ACTIVE_TH) { + + DBG_871X_LEVEL(_drv_info_, FUNC_ADPT_FMT" acqiure wake_lock for %u ms(tx:%d,rx_unicast:%d)\n", + FUNC_ADPT_ARG(padapter), + TRAFFIC_PROTECT_PERIOD_MS, + link_detect->NumTxOkInPeriod, + link_detect->NumRxUnicastOkInPeriod); + + rtw_lock_traffic_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS); + } +#endif + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_AUTOSETUP + /* TDLS_WATCHDOG_PERIOD * 2sec, periodically send */ + if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _TRUE) { + if ((ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD) == 0) { + _rtw_memcpy(txmgmt.peer, baddr, ETH_ALEN); + issue_tdls_dis_req(padapter, &txmgmt); + } + ptdlsinfo->watchdog_count++; + } +#endif //CONFIG_TDLS_AUTOSETUP +#endif //CONFIG_TDLS + +#ifdef CONFIG_LPS + // check traffic for powersaving. + if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || +#ifdef CONFIG_LPS_SLOW_TRANSITION + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) +#else //CONFIG_LPS_SLOW_TRANSITION + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4) +#endif //CONFIG_LPS_SLOW_TRANSITION + ) + { +#ifdef DBG_RX_COUNTER_DUMP + if( padapter->dump_rx_cnt_mode & DUMP_DRV_TRX_COUNTER_DATA) + DBG_871X("(-)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); +#endif + bEnterPS= _FALSE; +#ifdef CONFIG_LPS_SLOW_TRANSITION + if(bBusyTraffic == _TRUE) + { + if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4) + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 4; + + pmlmepriv->LinkDetectInfo.TrafficTransitionCount++; + + //DBG_871X("Set TrafficTransitionCount to %d\n", pmlmepriv->LinkDetectInfo.TrafficTransitionCount); + + if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount > 30/*TrafficTransitionLevel*/) + { + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30; + } + } +#endif //CONFIG_LPS_SLOW_TRANSITION + + } + else + { +#ifdef DBG_RX_COUNTER_DUMP + if( padapter->dump_rx_cnt_mode & DUMP_DRV_TRX_COUNTER_DATA) + DBG_871X("(+)Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); +#endif +#ifdef CONFIG_LPS_SLOW_TRANSITION + if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount>=2) + pmlmepriv->LinkDetectInfo.TrafficTransitionCount -=2; + else + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; + + if(pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0) + bEnterPS= _TRUE; +#else //CONFIG_LPS_SLOW_TRANSITION + bEnterPS= _TRUE; +#endif //CONFIG_LPS_SLOW_TRANSITION + } + +#ifdef CONFIG_DYNAMIC_DTIM + if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount == 8) + bEnterPS= _FALSE; + + DBG_871X("LowPowerTransitionCount=%d\n", pmlmepriv->LinkDetectInfo.LowPowerTransitionCount); +#endif //CONFIG_DYNAMIC_DTIM + + // LeisurePS only work in infra mode. + if(bEnterPS) + { + if(!from_timer) + { +#ifdef CONFIG_DYNAMIC_DTIM + if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount < 8) + { + adapter_to_pwrctl(padapter)->dtim = 1; + } + else + { + adapter_to_pwrctl(padapter)->dtim = 3; + } +#endif //CONFIG_DYNAMIC_DTIM + LPS_Enter(padapter, "TRAFFIC_IDLE"); + } + else + { + //do this at caller + //rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); + //rtw_hal_dm_watchdog_in_lps(padapter); + } +#ifdef CONFIG_DYNAMIC_DTIM + if (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode ==_TRUE ) + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount++; +#endif //CONFIG_DYNAMIC_DTIM + } + else + { +#ifdef CONFIG_DYNAMIC_DTIM + if(pmlmepriv->LinkDetectInfo.LowPowerTransitionCount != 8) + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; + else + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount++; +#endif //CONFIG_DYNAMIC_DTIM + if(!from_timer) + { + LPS_Leave(padapter, "TRAFFIC_BUSY"); + } + else + { +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type == IFACE_PORT0) +#endif + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_TRAFFIC_BUSY, 1); + } + } + +#endif // CONFIG_LPS + } + else + { +#ifdef CONFIG_LPS + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + int n_assoc_iface = 0; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE)) + n_assoc_iface++; + } + + if(!from_timer && n_assoc_iface == 0) + LPS_Leave(padapter, "NON_LINKED"); +#endif + } + + session_tracker_chk_cmd(padapter, NULL); + + pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; + pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; + pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; + pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; + + return bEnterPS; + +} + +void dynamic_chk_wk_hdl(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv; + pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + expire_timeout_chk(padapter); + } +#endif +#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK + +#ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_xmit_status_check(padapter); + rtw_hal_sreset_linked_status_check(padapter); +#endif + + //for debug purpose + _linked_info_dump(padapter); + + + //if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE) + { + linked_status_chk(padapter, 0); + traffic_status_watchdog(padapter, 0); + #ifdef DBG_RX_COUNTER_DUMP + rtw_dump_rx_counters(padapter); + #endif + dm_DynamicUsbTxAgg(padapter, 0); + } + +#ifdef CONFIG_BEAMFORMING +#if (BEAMFORMING_SUPPORT == 0) /*for diver defined beamforming*/ + beamforming_watchdog(padapter); +#endif +#endif + + rtw_hal_dm_watchdog(padapter); + + //check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type); + +#ifdef CONFIG_BT_COEXIST + // + // BT-Coexist + // + rtw_btcoex_Handler(padapter); +#endif + + +#ifdef CONFIG_IPS_CHECK_IN_WD + //always call rtw_ps_processor() at last one. + if (is_primary_adapter(padapter)) + rtw_ps_processor(padapter); +#endif +} + +#ifdef CONFIG_LPS + +void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type); +void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 mstatus; + +_func_enter_; + + if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) + || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + { + return; + } + + switch(lps_ctrl_type) + { + case LPS_CTRL_SCAN: + //DBG_871X("LPS_CTRL_SCAN \n"); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(padapter, _TRUE); +#endif // CONFIG_BT_COEXIST + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + // connect + LPS_Leave(padapter, "LPS_CTRL_SCAN"); + } + break; + case LPS_CTRL_JOINBSS: + //DBG_871X("LPS_CTRL_JOINBSS \n"); + LPS_Leave(padapter, "LPS_CTRL_JOINBSS"); + break; + case LPS_CTRL_CONNECT: + //DBG_871X("LPS_CTRL_CONNECT \n"); + mstatus = 1;//connect + // Reset LPS Setting + pwrpriv->LpsIdleCount = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_MediaStatusNotify(padapter, mstatus); +#endif // CONFIG_BT_COEXIST + break; + case LPS_CTRL_DISCONNECT: + //DBG_871X("LPS_CTRL_DISCONNECT \n"); + mstatus = 0;//disconnect +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_MediaStatusNotify(padapter, mstatus); +#endif // CONFIG_BT_COEXIST + LPS_Leave(padapter, "LPS_CTRL_DISCONNECT"); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); + break; + case LPS_CTRL_SPECIAL_PACKET: + //DBG_871X("LPS_CTRL_SPECIAL_PACKET \n"); + pwrpriv->DelayLPSLastTimeStamp = rtw_get_current_time(); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_SpecialPacketNotify(padapter, PACKET_DHCP); +#endif // CONFIG_BT_COEXIST + LPS_Leave(padapter, "LPS_CTRL_SPECIAL_PACKET"); + break; + case LPS_CTRL_LEAVE: + LPS_Leave(padapter, "LPS_CTRL_LEAVE"); + break; + case LPS_CTRL_LEAVE_CFG80211_PWRMGMT: + LPS_Leave(padapter, "CFG80211_PWRMGMT"); + 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; + } + +_func_exit_; +} + +u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + //struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + u8 res = _SUCCESS; + +_func_enter_; + + //if(!pwrctrlpriv->bLeisurePs) + // return res; + + if(enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; + pdrvextra_cmd_parm->type = lps_ctrl_type; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else + { + lps_ctrl_wk_hdl(padapter, lps_ctrl_type); + } + +exit: + +_func_exit_; + + return res; + +} + +void rtw_dm_in_lps_hdl(_adapter*padapter) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_DM_IN_LPS, NULL); +} + +u8 rtw_dm_in_lps_wk_cmd(_adapter*padapter) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = DM_IN_LPS_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +void rtw_lps_change_dtim_hdl(_adapter *padapter, u8 dtim) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + if(dtim <=0 || dtim > 16) + return; + +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE) + return; +#endif + +#ifdef CONFIG_LPS_LCLK + _enter_pwrlock(&pwrpriv->lock); +#endif + + if(pwrpriv->dtim!=dtim) + { + DBG_871X("change DTIM from %d to %d, bFwCurrentInPSMode=%d, ps_mode=%d\n", pwrpriv->dtim, dtim, + pwrpriv->bFwCurrentInPSMode, pwrpriv->pwr_mode); + + pwrpriv->dtim = dtim; + } + + if((pwrpriv->bFwCurrentInPSMode ==_TRUE) && (pwrpriv->pwr_mode > PS_MODE_ACTIVE)) + { + u8 ps_mode = pwrpriv->pwr_mode; + + //DBG_871X("change DTIM from %d to %d, ps_mode=%d\n", pwrpriv->dtim, dtim, ps_mode); + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + } + +#ifdef CONFIG_LPS_LCLK + _exit_pwrlock(&pwrpriv->lock); +#endif + +} + +#endif + +u8 rtw_lps_change_dtim_cmd(_adapter*padapter, u8 dtim) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; +/* +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type != IFACE_PORT0) + return res; +#endif +*/ + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = LPS_CHANGE_DTIM_CID; + pdrvextra_cmd_parm->type = dtim; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + +exit: + + return res; + +} + +#if (RATE_ADAPTIVE_SUPPORT==1) +void rpt_timer_setting_wk_hdl(_adapter *padapter, u16 minRptTime) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&minRptTime)); +} + +u8 rtw_rpt_timer_cfg_cmd(_adapter*padapter, u16 minRptTime) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res = _SUCCESS; + +_func_enter_; + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID; + pdrvextra_cmd_parm->type = minRptTime; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + res = rtw_enqueue_cmd(pcmdpriv, ph2c); +exit: + +_func_exit_; + + return res; + +} + +#endif + +#ifdef CONFIG_ANTENNA_DIVERSITY +void antenna_select_wk_hdl(_adapter *padapter, u8 antenna) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna)); +} + +u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 bSupportAntDiv = _FALSE; + u8 res = _SUCCESS; + +_func_enter_; + rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv)); + if(_FALSE == bSupportAntDiv ) return res; + + if(_TRUE == enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID; + pdrvextra_cmd_parm->type = antenna; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else{ + antenna_select_wk_hdl(padapter,antenna ); + } +exit: + +_func_exit_; + + return res; + +} +#endif + +void rtw_dm_ra_mask_hdl(_adapter *padapter, struct sta_info *psta) +{ + if (psta) { + set_sta_rate(padapter, psta); + } +} + +u8 rtw_dm_ra_mask_wk_cmd(_adapter*padapter, u8 *psta) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = DM_RA_MSK_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = psta; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +void power_saving_wk_hdl(_adapter *padapter) +{ + rtw_ps_processor(padapter); +} + +//add for CONFIG_IEEE80211W, none 11w can use it +void reset_securitypriv_hdl(_adapter *padapter) +{ + rtw_reset_securitypriv(padapter); +} + +void free_assoc_resources_hdl(_adapter *padapter) +{ + rtw_free_assoc_resources(padapter, 1); +} + +#ifdef CONFIG_P2P +u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType ) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + return res; + } + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID; + pdrvextra_cmd_parm->type = intCmdType; // As the command tppe. + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; // Must be NULL here + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; + +} +#endif //CONFIG_P2P + +u8 rtw_ps_cmd(_adapter*padapter) +{ + struct cmd_obj *ppscmd; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + u8 res = _SUCCESS; +_func_enter_; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type != PRIMARY_ADAPTER) + goto exit; +#endif + + ppscmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ppscmd==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ppscmd); + +exit: + +_func_exit_; + + return res; + +} + +#ifdef CONFIG_AP_MODE + +static void rtw_chk_hi_queue_hdl(_adapter *padapter) +{ + struct sta_info *psta_bmc; + struct sta_priv *pstapriv = &padapter->stapriv; + u32 start = rtw_get_current_time(); + u8 empty = _FALSE; + + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if(!psta_bmc) + return; + + rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &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); + } + + if(psta_bmc->sleepq_len==0) + { + if(empty == _SUCCESS) + { + bool update_tim = _FALSE; + + if (pstapriv->tim_bitmap & BIT(0)) + update_tim = _TRUE; + + pstapriv->tim_bitmap &= ~BIT(0); + pstapriv->sta_dz_bitmap &= ~BIT(0); + + if (update_tim == _TRUE) + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "bmc sleepq and HIQ empty"); + } + else //re check again + { + rtw_chk_hi_queue_cmd(padapter); + } + + } + +} + +u8 rtw_chk_hi_queue_cmd(_adapter*padapter) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; + +} + +#ifdef CONFIG_DFS_MASTER +u8 rtw_dfs_master_hdl(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + struct mlme_priv *mlme = &adapter->mlmepriv; + + if (!rfctl->dfs_master_enabled) + goto exit; + + if (rtw_get_on_cur_ch_time(adapter) == 0 + || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 300 + ) { + /* offchannel , by pass radar detect */ + goto cac_status_chk; + } + + if (rfctl->dbg_dfs_master_fake_radar_detect_cnt + || rtw_odm_radar_detect(adapter) == _TRUE + ) { + if (rfctl->dbg_dfs_master_fake_radar_detect_cnt != 0) { + DBG_871X(FUNC_ADPT_FMT" fake radar detect, cnt:%d\n", FUNC_ADPT_ARG(adapter) + , rfctl->dbg_dfs_master_fake_radar_detect_cnt); + rfctl->dbg_dfs_master_fake_radar_detect_cnt--; + } + + if (rfctl->dbg_dfs_master_radar_detect_trigger_non) { + /* radar detect debug mode, trigger no mlme flow */ + DBG_871X(FUNC_ADPT_FMT" radar detected, trigger no mlme flow for debug\n", FUNC_ADPT_ARG(adapter)); + } else { + /* TODO: move timer to rfctl */ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (!dvobj->padapters[i]) + continue; + if (check_fwstate(&dvobj->padapters[i]->mlmepriv, WIFI_AP_STATE) + && check_fwstate(&dvobj->padapters[i]->mlmepriv, WIFI_AP_STATE)) + break; + } + + if (i >= dvobj->iface_nums) { + /* what? */ + rtw_warn_on(1); + } else { + rtw_chset_update_non_ocp(dvobj->padapters[i]->mlmeextpriv.channel_set + , rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset); + + /* change op ch, inform ch switch */ + rtw_change_bss_chbw_cmd(dvobj->padapters[i], RTW_CMDF_DIRECTLY, 0, 0, 0); + } + + if (rfctl->dfs_master_enabled) + goto set_timer; + goto exit; + } + } + +cac_status_chk: + + if (!IS_UNDER_CAC(rfctl) && !IS_CAC_STOPPED(rfctl)) { + u8 pause = 0x00; + + rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause); + rfctl->cac_end_time = RTW_CAC_STOPPED; + } + +set_timer: + _set_timer(&mlme->dfs_master_timer, DFS_MASTER_TIMER_MS); + +exit: + return H2C_SUCCESS; +} + +u8 rtw_dfs_master_cmd(_adapter *adapter, bool enqueue) +{ + struct cmd_obj *cmdobj; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + u8 res = _FAIL; + + if (enqueue) { + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (cmdobj == NULL) + goto exit; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj)); + goto exit; + } + + pdrvextra_cmd_parm->ec_id = DFS_MASTER_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(cmdobj, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + res = rtw_enqueue_cmd(pcmdpriv, cmdobj); + } else { + rtw_dfs_master_hdl(adapter); + res = _SUCCESS; + } + +exit: + return res; +} + +void rtw_dfs_master_timer_hdl(RTW_TIMER_HDL_ARGS) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + rtw_dfs_master_cmd(adapter, _TRUE); +} + +void rtw_dfs_master_enable(_adapter *adapter, u8 ch, u8 bw, u8 offset) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + /* TODO: move timer to rfctl */ + adapter = GET_PRIMARY_ADAPTER(adapter); + + DBG_871X(FUNC_ADPT_FMT" on %u,%u,%u\n", FUNC_ADPT_ARG(adapter), ch, bw, offset); + + rfctl->pre_radar_detect_by_sta_link = rfctl->radar_detect_by_sta_link; + rfctl->radar_detect_by_sta_link = _FALSE; + + rfctl->pre_radar_detect_ch = rfctl->radar_detect_ch; + rfctl->pre_radar_detect_bw = rfctl->radar_detect_bw; + rfctl->pre_radar_detect_offset = rfctl->radar_detect_offset; + rfctl->radar_detect_ch = ch; + rfctl->radar_detect_bw = bw; + rfctl->radar_detect_offset = offset; + + if (rtw_is_cac_reset_needed(adapter) == _TRUE) + rtw_rfctl_reset_cac(adapter_to_rfctl(adapter)); + + if (!rfctl->dfs_master_enabled) { + DBG_871X(FUNC_ADPT_FMT" set dfs_master_enabled\n", FUNC_ADPT_ARG(adapter)); + rfctl->dfs_master_enabled = 1; + _set_timer(&adapter->mlmepriv.dfs_master_timer, DFS_MASTER_TIMER_MS); + + if (rtw_rfctl_overlap_radar_detect_ch(rfctl)) { + if (IS_UNDER_CAC(rfctl)) { + u8 pause = 0xFF; + + rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause); + } + rtw_odm_radar_detect_enable(adapter); + } + } +} + +void rtw_dfs_master_disable(_adapter *adapter, bool ld_sta_in_dfs) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + /* TODO: move timer to rfctl */ + adapter = GET_PRIMARY_ADAPTER(adapter); + + rfctl->pre_radar_detect_by_sta_link = rfctl->radar_detect_by_sta_link; + rfctl->radar_detect_by_sta_link = ld_sta_in_dfs; + + if (rfctl->dfs_master_enabled) { + bool overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl); + + DBG_871X(FUNC_ADPT_FMT" clear dfs_master_enabled\n", FUNC_ADPT_ARG(adapter)); + + rfctl->dfs_master_enabled = 0; + rfctl->radar_detect_ch = rfctl->pre_radar_detect_ch = 0; + rfctl->radar_detect_bw = rfctl->pre_radar_detect_bw = 0; + rfctl->radar_detect_offset = rfctl->pre_radar_detect_offset = 0; + rfctl->cac_end_time = RTW_CAC_STOPPED; + _cancel_timer_ex(&adapter->mlmepriv.dfs_master_timer); + + if (overlap_radar_detect_ch) { + u8 pause = 0x00; + + rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &pause); + rtw_odm_radar_detect_disable(adapter); + } + } +} + +void rtw_dfs_master_status_apply(_adapter *adapter, u8 self_action) +{ + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + u8 ld_sta_num, lg_sta_num, ap_num; + u8 u_ch, u_bw, u_offset; + bool ld_sta_in_dfs = _FALSE; + bool sync_ch = _FALSE; /* _FALSE: asign channel directly */ + bool needed = _FALSE; + + rtw_dev_iface_status_no_self(adapter, NULL, &ld_sta_num, &lg_sta_num, &ap_num, NULL); + rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset); + if (u_ch != 0) + sync_ch = _TRUE; + + switch (self_action) { + case MLME_STA_CONNECTING: + lg_sta_num++; + break; + case MLME_STA_CONNECTED: + ld_sta_num++; + break; + case MLME_AP_STARTED: + ap_num++; + break; + case MLME_AP_STOPPED: + case MLME_STA_DISCONNECTED: + default: + break; + } + + if (sync_ch == _TRUE) { + if (!rtw_is_chbw_grouped(mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset, u_ch, u_bw, u_offset)) { + DBG_871X(FUNC_ADPT_FMT" can't sync %u,%u,%u with %u,%u,%u\n", FUNC_ADPT_ARG(adapter) + , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset, u_ch, u_bw, u_offset); + goto apply; + } + + rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset + , &u_ch, &u_bw, &u_offset); + } else { + u_ch = mlmeext->cur_channel; + u_bw = mlmeext->cur_bwmode; + u_offset = mlmeext->cur_ch_offset; + } + + if (ld_sta_num > 0) { + /* rely on AP on which STA mode connects */ + if (rtw_is_dfs_ch(u_ch, u_bw, u_offset)) + ld_sta_in_dfs = _TRUE; + goto apply; + } + + if (lg_sta_num > 0) { + /* STA mode is linking */ + goto apply; + } + + if (ap_num == 0) { + /* No working AP mode */ + goto apply; + } + + if (rtw_is_dfs_ch(u_ch, u_bw, u_offset)) + needed = _TRUE; + +apply: + + DBG_871X(FUNC_ADPT_FMT" needed:%d, self_action:%u\n" + , FUNC_ADPT_ARG(adapter), needed, self_action); + DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, lg_sta_num:%u, ap_num:%u, %u,%u,%u\n" + , FUNC_ADPT_ARG(adapter), ld_sta_num, lg_sta_num, ap_num, u_ch, u_bw, u_offset); + + if (needed == _TRUE) + rtw_dfs_master_enable(adapter, u_ch, u_bw, u_offset); + else + rtw_dfs_master_disable(adapter, ld_sta_in_dfs); +} +#endif /* CONFIG_DFS_MASTER */ + +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_BT_COEXIST +struct btinfo { + u8 cid; + u8 len; + + u8 bConnection:1; + u8 bSCOeSCO:1; + u8 bInQPage:1; + u8 bACLBusy:1; + u8 bSCOBusy:1; + u8 bHID:1; + u8 bA2DP:1; + u8 bFTP:1; + + u8 retry_cnt:4; + u8 rsvd_34:1; + u8 rsvd_35:1; + u8 rsvd_36:1; + u8 rsvd_37:1; + + u8 rssi; + + u8 rsvd_50:1; + u8 rsvd_51:1; + u8 rsvd_52:1; + u8 rsvd_53:1; + u8 rsvd_54:1; + u8 rsvd_55:1; + u8 eSCO_SCO:1; + u8 Master_Slave:1; + + u8 rsvd_6; + u8 rsvd_7; +}; + +void btinfo_evt_dump(void *sel, void *buf) +{ + struct btinfo *info = (struct btinfo *)buf; + + DBG_871X_SEL_NL(sel, "cid:0x%02x, len:%u\n", info->cid, info->len); + + if (info->len > 2) + DBG_871X_SEL_NL(sel, "byte2:%s%s%s%s%s%s%s%s\n" + , info->bConnection?"bConnection ":"" + , info->bSCOeSCO?"bSCOeSCO ":"" + , info->bInQPage?"bInQPage ":"" + , info->bACLBusy?"bACLBusy ":"" + , info->bSCOBusy?"bSCOBusy ":"" + , info->bHID?"bHID ":"" + , info->bA2DP?"bA2DP ":"" + , info->bFTP?"bFTP":"" + ); + + if (info->len > 3) + DBG_871X_SEL_NL(sel, "retry_cnt:%u\n", info->retry_cnt); + + if (info->len > 4) + DBG_871X_SEL_NL(sel, "rssi:%u\n", info->rssi); + + if (info->len > 5) + DBG_871X_SEL_NL(sel, "byte5:%s%s\n" + , info->eSCO_SCO?"eSCO_SCO ":"" + , info->Master_Slave?"Master_Slave ":"" + ); +} + +static void rtw_btinfo_hdl(_adapter *adapter, u8 *buf, u16 buf_len) +{ + #define BTINFO_WIFI_FETCH 0x23 + #define BTINFO_BT_AUTO_RPT 0x27 +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + struct btinfo_8761ATV *info = (struct btinfo_8761ATV *)buf; +#else //!CONFIG_BT_COEXIST_SOCKET_TRX + struct btinfo *info = (struct btinfo *)buf; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + u8 cmd_idx; + u8 len; + + cmd_idx = info->cid; + + if (info->len > buf_len-2) { + rtw_warn_on(1); + len = buf_len-2; + } else { + len = info->len; + } + +//#define DBG_PROC_SET_BTINFO_EVT +#ifdef DBG_PROC_SET_BTINFO_EVT +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + DBG_871X("%s: btinfo[0]=%x,btinfo[1]=%x,btinfo[2]=%x,btinfo[3]=%x btinfo[4]=%x,btinfo[5]=%x,btinfo[6]=%x,btinfo[7]=%x\n" + , __func__, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); +#else//!CONFIG_BT_COEXIST_SOCKET_TRX + btinfo_evt_dump(RTW_DBGDUMP, info); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX +#endif // DBG_PROC_SET_BTINFO_EVT + + /* transform BT-FW btinfo to WiFI-FW C2H format and notify */ + if (cmd_idx == BTINFO_WIFI_FETCH) + buf[1] = 0; + else if (cmd_idx == BTINFO_BT_AUTO_RPT) + buf[1] = 2; +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + else if(0x01 == cmd_idx || 0x02 == cmd_idx) + buf[1] = buf[0]; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + rtw_btcoex_BtInfoNotify(adapter ,len+1, &buf[1]); +} + +u8 rtw_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + u8 *btinfo; + struct cmd_priv *pcmdpriv = &adapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + btinfo = rtw_zmalloc(len); + if (btinfo == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + rtw_mfree((u8*)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = len; + pdrvextra_cmd_parm->pbuf = btinfo; + + _rtw_memcpy(btinfo, buf, len); + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + return res; +} +#endif //CONFIG_BT_COEXIST + +//#ifdef CONFIG_C2H_PACKET_EN +u8 rtw_c2h_packet_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = C2H_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = length; + pdrvextra_cmd_parm->pbuf = pbuf; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + return res; +} + +//#else //CONFIG_C2H_PACKET_EN +/* dont call R/W in this function, beucase SDIO interrupt have claim host */ +/* or deadlock will happen and cause special-systemserver-died in android */ + +u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if (ph2c == NULL) { + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { + rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = C2H_WK_CID; + pdrvextra_cmd_parm->type = 0; + pdrvextra_cmd_parm->size = c2h_evt?16:0; + pdrvextra_cmd_parm->pbuf = c2h_evt; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + + return res; +} +//#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; + u8 buf[16]; + + if (!c2h_evt) { + /* No c2h event in cmd_obj, read c2h event before handling*/ + if (rtw_hal_c2h_evt_read(adapter, buf) == _SUCCESS) { + c2h_evt = buf; + + if (filter && filter(c2h_evt) == _FALSE) + goto exit; + + ret = rtw_hal_c2h_handler(adapter, c2h_evt); + } + } else { + + if (filter && filter(c2h_evt) == _FALSE) + goto exit; + + ret = rtw_hal_c2h_handler(adapter, c2h_evt); + } +exit: + return ret; +} + +#ifdef CONFIG_C2H_WK +static void c2h_wk_callback(_workitem *work) +{ + struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); + _adapter *adapter = container_of(evtpriv, _adapter, evtpriv); + u8 *c2h_evt; + c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); + + evtpriv->c2h_wk_alive = _TRUE; + + while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { + if ((c2h_evt = (u8 *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) { + /* This C2H event is read, clear it */ + c2h_evt_clear(adapter); + } else if ((c2h_evt = (u8 *)rtw_malloc(16)) != NULL) { + /* This C2H event is not read, read & clear now */ + if (rtw_hal_c2h_evt_read(adapter, c2h_evt) != _SUCCESS) { + rtw_mfree(c2h_evt, 16); + continue; + } + } else { + rtw_warn_on(1); + continue; + } + + /* Special pointer to trigger c2h_evt_clear only */ + if ((void *)c2h_evt == (void *)evtpriv) + continue; + + if (!rtw_hal_c2h_valid(adapter, c2h_evt)) { + rtw_mfree(c2h_evt, 16); + continue; + } + + if (ccx_id_filter(c2h_evt) == _TRUE) { + /* Handle CCX report here */ + rtw_hal_c2h_handler(adapter, c2h_evt); + rtw_mfree(c2h_evt, 16); + } else { + /* Enqueue into cmd_thread for others */ + rtw_c2h_wk_cmd(adapter, c2h_evt); + } + } + + evtpriv->c2h_wk_alive = _FALSE; +} +#endif + +u8 session_tracker_cmd(_adapter *adapter, u8 cmd, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + struct cmd_priv *cmdpriv = &adapter->cmdpriv; + struct cmd_obj *cmdobj; + struct drvextra_cmd_parm *cmd_parm; + struct st_cmd_parm *st_parm; + u8 res = _SUCCESS; + + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (cmdobj == NULL) { + res = _FAIL; + goto exit; + } + + cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (cmd_parm == NULL) { + rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + st_parm = (struct st_cmd_parm *)rtw_zmalloc(sizeof(struct st_cmd_parm)); + if (st_parm == NULL) { + rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj)); + rtw_mfree((u8 *)cmd_parm, sizeof(struct drvextra_cmd_parm)); + res = _FAIL; + goto exit; + } + + st_parm->cmd = cmd; + st_parm->sta = sta; + if (cmd != ST_CMD_CHK) { + _rtw_memcpy(&st_parm->local_naddr, local_naddr, 4); + _rtw_memcpy(&st_parm->local_port, local_port, 2); + _rtw_memcpy(&st_parm->remote_naddr, remote_naddr, 4); + _rtw_memcpy(&st_parm->remote_port, remote_port, 2); + } + + cmd_parm->ec_id = SESSION_TRACKER_WK_CID; + cmd_parm->type = 0; + cmd_parm->size = sizeof(struct st_cmd_parm); + cmd_parm->pbuf = (u8 *)st_parm; + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + cmdobj->no_io = 1; + + res = rtw_enqueue_cmd(cmdpriv, cmdobj); + +exit: + return res; +} + +inline u8 session_tracker_chk_cmd(_adapter *adapter, struct sta_info *sta) +{ + return session_tracker_cmd(adapter, ST_CMD_CHK, sta, NULL, NULL, NULL, NULL); +} + +inline u8 session_tracker_add_cmd(_adapter *adapter, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + return session_tracker_cmd(adapter, ST_CMD_ADD, sta, local_naddr, local_port, remote_naddr, remote_port); +} + +inline u8 session_tracker_del_cmd(_adapter *adapter, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + return session_tracker_cmd(adapter, ST_CMD_DEL, sta, local_naddr, local_port, remote_naddr, remote_port); +} + +void session_tracker_chk_for_sta(_adapter *adapter, struct sta_info *sta) +{ + struct st_ctl_t *st_ctl = &sta->st_ctl; + int i; + _irqL irqL; + _list *plist, *phead, *pnext; + _list dlist; + struct session_tracker *st = NULL; + u8 op_wfd_mode = MIRACAST_DISABLED; + + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" sta:%p\n", FUNC_ADPT_ARG(adapter), sta); + + if (!(sta->state & _FW_LINKED)) + goto exit; + + for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) { + if (st_ctl->reg[i].s_proto != 0) + break; + } + if (i >= SESSION_TRACKER_REG_ID_NUM) + goto chk_sta; + + _rtw_init_listhead(&dlist); + + _enter_critical_bh(&st_ctl->tracker_q.lock, &irqL); + + phead = &st_ctl->tracker_q.queue; + plist = get_next(phead); + pnext = get_next(plist); + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + st = LIST_CONTAINOR(plist, struct session_tracker, list); + plist = pnext; + pnext = get_next(pnext); + + if (st->status != ST_STATUS_ESTABLISH + && rtw_get_passing_time_ms(st->set_time) > ST_EXPIRE_MS + ) { + rtw_list_delete(&st->list); + rtw_list_insert_tail(&st->list, &dlist); + } + + /* TODO: check OS for status update */ + if (st->status == ST_STATUS_CHECK) + st->status = ST_STATUS_ESTABLISH; + + if (st->status != ST_STATUS_ESTABLISH) + continue; + + #ifdef CONFIG_WFD + if (0) + DBG_871X(FUNC_ADPT_FMT" local:%u, remote:%u, rtsp:%u, %u, %u\n", FUNC_ADPT_ARG(adapter) + , ntohs(st->local_port), ntohs(st->remote_port), adapter->wfd_info.rtsp_ctrlport, adapter->wfd_info.tdls_rtsp_ctrlport + , adapter->wfd_info.peer_rtsp_ctrlport); + if (ntohs(st->local_port) == adapter->wfd_info.rtsp_ctrlport) + op_wfd_mode |= MIRACAST_SINK; + if (ntohs(st->local_port) == adapter->wfd_info.tdls_rtsp_ctrlport) + op_wfd_mode |= MIRACAST_SINK; + if (ntohs(st->remote_port) == adapter->wfd_info.peer_rtsp_ctrlport) + op_wfd_mode |= MIRACAST_SOURCE; + #endif + } + + _exit_critical_bh(&st_ctl->tracker_q.lock, &irqL); + + plist = get_next(&dlist); + while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) { + st = LIST_CONTAINOR(plist, struct session_tracker, list); + plist = get_next(plist); + rtw_mfree((u8 *)st, sizeof(struct session_tracker)); + } + +chk_sta: + if (STA_OP_WFD_MODE(sta) != op_wfd_mode) { + STA_SET_OP_WFD_MODE(sta, op_wfd_mode); + rtw_sta_media_status_rpt_cmd(adapter, sta, 1); + } + +exit: + return; +} + +void session_tracker_chk_for_adapter(_adapter *adapter) +{ + struct sta_priv *stapriv = &adapter->stapriv; + struct sta_info *sta; + int i; + _irqL irqL; + _list *plist, *phead; + u8 op_wfd_mode = MIRACAST_DISABLED; + + _enter_critical_bh(&stapriv->sta_hash_lock, &irqL); + + for (i = 0; i < NUM_STA; i++) { + phead = &(stapriv->sta_hash[i]); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + sta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + plist = get_next(plist); + + session_tracker_chk_for_sta(adapter, sta); + + op_wfd_mode |= STA_OP_WFD_MODE(sta); + } + } + + _exit_critical_bh(&stapriv->sta_hash_lock, &irqL); + +#ifdef CONFIG_WFD + adapter->wfd_info.op_wfd_mode = MIRACAST_MODE_REVERSE(op_wfd_mode); +#endif +} + +void session_tracker_cmd_hdl(_adapter *adapter, struct st_cmd_parm *parm) +{ + u8 cmd = parm->cmd; + struct sta_info *sta = parm->sta; + + if (cmd == ST_CMD_CHK) { + if (sta) + session_tracker_chk_for_sta(adapter, sta); + else + session_tracker_chk_for_adapter(adapter); + + goto exit; + + } else if (cmd == ST_CMD_ADD || cmd == ST_CMD_DEL) { + struct st_ctl_t *st_ctl; + u32 local_naddr = parm->local_naddr; + u16 local_port = parm->local_port; + u32 remote_naddr = parm->remote_naddr; + u16 remote_port = parm->remote_port; + struct session_tracker *st = NULL; + _irqL irqL; + _list *plist, *phead; + u8 free_st = 0; + u8 alloc_st = 0; + + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" cmd:%u, sta:%p, local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT"\n" + , FUNC_ADPT_ARG(adapter), cmd, sta + , IP_ARG(&local_naddr), PORT_ARG(&local_port) + , IP_ARG(&remote_naddr), PORT_ARG(&remote_port) + ); + + if (!(sta->state & _FW_LINKED)) + goto exit; + + st_ctl = &sta->st_ctl; + + _enter_critical_bh(&st_ctl->tracker_q.lock, &irqL); + + phead = &st_ctl->tracker_q.queue; + plist = get_next(phead); + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + st = LIST_CONTAINOR(plist, struct session_tracker, list); + + if (st->local_naddr == local_naddr + && st->local_port == local_port + && st->remote_naddr == remote_naddr + && st->remote_port == remote_port) + break; + + plist = get_next(plist); + } + + if (rtw_end_of_queue_search(phead, plist) == _TRUE) + st = NULL; + + switch (cmd) { + case ST_CMD_DEL: + if (st) { + rtw_list_delete(plist); + free_st = 1; + } + goto unlock; + case ST_CMD_ADD: + if (!st) + alloc_st = 1; + } + +unlock: + _exit_critical_bh(&st_ctl->tracker_q.lock, &irqL); + + if (free_st) { + rtw_mfree((u8 *)st, sizeof(struct session_tracker)); + goto exit; + } + + if (alloc_st) { + st = (struct session_tracker *)rtw_zmalloc(sizeof(struct session_tracker)); + if (!st) + goto exit; + + st->local_naddr = local_naddr; + st->local_port = local_port; + st->remote_naddr = remote_naddr; + st->remote_port = remote_port; + st->set_time = rtw_get_current_time(); + st->status = ST_STATUS_CHECK; + + _enter_critical_bh(&st_ctl->tracker_q.lock, &irqL); + rtw_list_insert_tail(&st->list, phead); + _exit_critical_bh(&st_ctl->tracker_q.lock, &irqL); + } + } + +exit: + return; +} + +u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct drvextra_cmd_parm *pdrvextra_cmd; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + pdrvextra_cmd = (struct drvextra_cmd_parm*)pbuf; + + switch (pdrvextra_cmd->ec_id) { + case STA_MSTATUS_RPT_WK_CID: + rtw_sta_media_status_rpt_cmd_hdl(padapter, (struct sta_media_status_rpt_cmd_parm *)pdrvextra_cmd->pbuf); + break; + + case DYNAMIC_CHK_WK_CID:/*only primary padapter go to this cmd, but execute dynamic_chk_wk_hdl() for two interfaces */ +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) + dynamic_chk_wk_hdl(padapter->pbuddy_adapter); +#endif + dynamic_chk_wk_hdl(padapter); + break; + case POWER_SAVING_CTRL_WK_CID: + power_saving_wk_hdl(padapter); + break; +#ifdef CONFIG_LPS + case LPS_CTRL_WK_CID: + lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type); + break; + case DM_IN_LPS_WK_CID: + rtw_dm_in_lps_hdl(padapter); + break; + case LPS_CHANGE_DTIM_CID: + rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type); + break; +#endif +#if (RATE_ADAPTIVE_SUPPORT==1) + case RTP_TIMER_CFG_WK_CID: + rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type); + break; +#endif +#ifdef CONFIG_ANTENNA_DIVERSITY + case ANT_SELECT_WK_CID: + antenna_select_wk_hdl(padapter, pdrvextra_cmd->type); + break; +#endif +#ifdef CONFIG_P2P_PS + case P2P_PS_WK_CID: + p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type); + break; +#endif +#ifdef CONFIG_P2P + case P2P_PROTO_WK_CID: + /* + * Commented by Albert 2011/07/01 + * I used the type_size as the type command + */ + p2p_protocol_wk_hdl(padapter, pdrvextra_cmd->type); + break; +#endif +#ifdef CONFIG_AP_MODE + case CHECK_HIQ_WK_CID: + rtw_chk_hi_queue_hdl(padapter); + break; +#endif +#ifdef CONFIG_INTEL_WIDI + case INTEl_WIDI_WK_CID: + intel_widi_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); + break; +#endif + /* add for CONFIG_IEEE80211W, none 11w can use it */ + case RESET_SECURITYPRIV: + reset_securitypriv_hdl(padapter); + break; + case FREE_ASSOC_RESOURCES: + free_assoc_resources_hdl(padapter); + break; + case C2H_WK_CID: +#ifdef CONFIG_C2H_PACKET_EN + rtw_hal_set_hwreg_with_buf(padapter, HW_VAR_C2H_HANDLE, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); +#else + c2h_evt_hdl(padapter, pdrvextra_cmd->pbuf, NULL); +#endif + break; +#ifdef CONFIG_BEAMFORMING + case BEAMFORMING_WK_CID: + beamforming_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); + break; +#endif + case DM_RA_MSK_WK_CID: + rtw_dm_ra_mask_hdl(padapter, (struct sta_info *)pdrvextra_cmd->pbuf); + break; +#ifdef CONFIG_BT_COEXIST + case BTINFO_WK_CID: + rtw_btinfo_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); + break; +#endif +#ifdef CONFIG_DFS_MASTER + case DFS_MASTER_WK_CID: + rtw_dfs_master_hdl(padapter); + break; +#endif + case SESSION_TRACKER_WK_CID: + session_tracker_cmd_hdl(padapter, (struct st_cmd_parm *)pdrvextra_cmd->pbuf); + break; + + case EN_HW_UPDATE_TSF_WK_CID: + rtw_hal_set_hwreg(padapter, HW_VAR_EN_HW_UPDATE_TSF, NULL); + break; + + default: + break; + } + + if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size>0) + { + rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->size); + } + + return H2C_SUCCESS; +} + +void rtw_survey_cmd_callback(_adapter* padapter , struct cmd_obj *pcmd) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(pcmd->res == H2C_DROPPED) + { + //TODO: cancel timer and do timeout handler directly... + //need to make timeout handlerOS independent + mlme_set_scan_to_timer(pmlmepriv, 1); + } + else if (pcmd->res != H2C_SUCCESS) { + mlme_set_scan_to_timer(pmlmepriv, 1); + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); + } + + // free cmd + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} +void rtw_disassoc_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if (pcmd->res != H2C_SUCCESS) + { + _enter_critical_bh(&pmlmepriv->lock, &irqL); + set_fwstate(pmlmepriv, _FW_LINKED); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n.")); + + goto exit; + } +#ifdef CONFIG_BR_EXT + else //clear bridge database + nat25_db_cleanup(padapter); +#endif //CONFIG_BR_EXT + + // free cmd + rtw_free_cmd_obj(pcmd); + +exit: + +_func_exit_; +} + + +void rtw_getmacreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd) +{ + +_func_enter_; + + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} + +void rtw_joinbss_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(pcmd->res == H2C_DROPPED) + { + //TODO: cancel timer and do timeout handler directly... + //need to make timeout handlerOS independent + _set_timer(&pmlmepriv->assoc_timer, 1); + } + else if(pcmd->res != H2C_SUCCESS) + { + _set_timer(&pmlmepriv->assoc_timer, 1); + } + + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} + +void rtw_create_ibss_post_hdl(_adapter *padapter, int status) +{ + _irqL irqL; + u8 timer_cancelled; + struct sta_info *psta = NULL; + struct wlan_network *pwlan = NULL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network; + struct wlan_network *mlme_cur_network = &(pmlmepriv->cur_network); + + if (status != H2C_SUCCESS) + _set_timer(&pmlmepriv->assoc_timer, 1); + + _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + { + _irqL irqL; + + pwlan = _rtw_alloc_network(pmlmepriv); + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + if (pwlan == NULL) { + pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); + if (pwlan == NULL) { + RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("Error: can't get pwlan in rtw_joinbss_event_callback\n")); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto createbss_cmd_fail; + } + pwlan->last_scanned = rtw_get_current_time(); + } else { + rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); + } + + pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network); + _rtw_memcpy(&(pwlan->network), pdev_network, pdev_network->Length); + //pwlan->fixed = _TRUE; + + /* copy pdev_network information to pmlmepriv->cur_network */ + _rtw_memcpy(&mlme_cur_network->network, pdev_network, (get_WLAN_BSSID_EX_sz(pdev_network))); + + #if 0 + /* reset DSConfig */ + mlme_cur_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pdev_network->Configuration.DSConfig); + #endif + + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ + } + +createbss_cmd_fail: + _exit_critical_bh(&pmlmepriv->lock, &irqL); +exit: + return; +} + + + +void rtw_setstaKey_cmdrsp_callback(_adapter* padapter , struct cmd_obj *pcmd) +{ + + struct sta_priv * pstapriv = &padapter->stapriv; + struct set_stakey_rsp* psetstakey_rsp = (struct set_stakey_rsp*) (pcmd->rsp); + struct sta_info* psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); + +_func_enter_; + + if(psta==NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info \n\n")); + goto exit; + } + + //psta->aid = psta->mac_id = psetstakey_rsp->keyid; //CAM_ID(CAM_ENTRY) + +exit: + + rtw_free_cmd_obj(pcmd); + +_func_exit_; + +} +void rtw_setassocsta_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ + _irqL irqL; + struct sta_priv * pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct set_assocsta_parm* passocsta_parm = (struct set_assocsta_parm*)(pcmd->parmbuf); + struct set_assocsta_rsp* passocsta_rsp = (struct set_assocsta_rsp*) (pcmd->rsp); + struct sta_info* psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); + +_func_enter_; + + if(psta==NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info \n\n")); + goto exit; + } + + psta->aid = psta->mac_id = passocsta_rsp->cam_id; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)) + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + set_fwstate(pmlmepriv, _FW_LINKED); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + rtw_free_cmd_obj(pcmd); + +_func_exit_; +} + +void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); +void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +{ +_func_enter_; + + rtw_free_cmd_obj(pcmd); +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + padapter->mppriv.workparam.bcompleted=_TRUE; +#endif + +_func_exit_; + +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_debug.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_debug.c new file mode 100644 index 00000000..e88c1ef2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_debug.c @@ -0,0 +1,3861 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_DEBUG_C_ + +#include +#include + +u32 GlobalDebugLevel = _drv_err_; + +#ifdef CONFIG_DEBUG_RTL871X + + u64 GlobalDebugComponents = \ + _module_rtl871x_xmit_c_ | + _module_xmit_osdep_c_ | + _module_rtl871x_recv_c_ | + _module_recv_osdep_c_ | + _module_rtl871x_mlme_c_ | + _module_mlme_osdep_c_ | + _module_rtl871x_sta_mgt_c_ | + _module_rtl871x_cmd_c_ | + _module_cmd_osdep_c_ | + _module_rtl871x_io_c_ | + _module_io_osdep_c_ | + _module_os_intfs_c_| + _module_rtl871x_security_c_| + _module_rtl871x_eeprom_c_| + _module_hal_init_c_| + _module_hci_hal_init_c_| + _module_rtl871x_ioctl_c_| + _module_rtl871x_ioctl_set_c_| + _module_rtl871x_ioctl_query_c_| + _module_rtl871x_pwrctrl_c_| + _module_hci_intfs_c_| + _module_hci_ops_c_| + _module_hci_ops_os_c_| + _module_rtl871x_ioctl_os_c| + _module_rtl8712_cmd_c_| + _module_hal_xmit_c_| + _module_rtl8712_recv_c_ | + _module_mp_ | + _module_efuse_; + +#endif /* CONFIG_DEBUG_RTL871X */ + +#include + +#ifdef CONFIG_TDLS +#define TDLS_DBG_INFO_SPACE_BTWN_ITEM_AND_VALUE 41 +#endif + +void dump_drv_version(void *sel) +{ + DBG_871X_SEL_NL(sel, "%s %s\n", DRV_NAME, DRIVERVERSION); + //DBG_871X_SEL_NL(sel, "build time: %s %s\n", __DATE__, __TIME__); +} + +void dump_drv_cfg(void *sel) +{ + char *kernel_version = utsname()->release; + + DBG_871X_SEL_NL(sel, "\nKernel Version: %s\n", kernel_version); + DBG_871X_SEL_NL(sel, "Driver Version: %s\n", DRIVERVERSION); + DBG_871X_SEL_NL(sel, "------------------------------------------------\n"); +#ifdef CONFIG_IOCTL_CFG80211 + DBG_871X_SEL_NL(sel, "CFG80211\n"); + #ifdef RTW_USE_CFG80211_STA_EVENT + DBG_871X_SEL_NL(sel, "RTW_USE_CFG80211_STA_EVENT\n"); + #endif +#else + DBG_871X_SEL_NL(sel, "WEXT\n"); +#endif + + DBG_871X_SEL_NL(sel, "DBG:%d\n", DBG); +#ifdef CONFIG_DEBUG + DBG_871X_SEL_NL(sel, "CONFIG_DEBUG\n"); +#endif + +#ifdef CONFIG_CONCURRENT_MODE + DBG_871X_SEL_NL(sel, "CONFIG_CONCURRENT_MODE\n"); +#endif + +#ifdef CONFIG_POWER_SAVING + DBG_871X_SEL_NL(sel, "CONFIG_POWER_SAVING\n"); +#endif + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + DBG_871X_SEL_NL(sel, "LOAD_PHY_PARA_FROM_FILE - REALTEK_CONFIG_PATH=%s\n", REALTEK_CONFIG_PATH); + #ifdef CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY + DBG_871X_SEL_NL(sel, "CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY\n"); + #endif + #ifdef CONFIG_CALIBRATE_TX_POWER_TO_MAX + DBG_871X_SEL_NL(sel, "CONFIG_CALIBRATE_TX_POWER_TO_MAX\n"); + #endif +#endif + +#ifdef CONFIG_DISABLE_ODM + DBG_871X_SEL_NL(sel, "CONFIG_DISABLE_ODM\n"); +#endif + +#ifdef CONFIG_MINIMAL_MEMORY_USAGE + DBG_871X_SEL_NL(sel, "CONFIG_MINIMAL_MEMORY_USAGE\n"); +#endif + + DBG_871X_SEL_NL(sel, "CONFIG_RTW_ADAPTIVITY_EN = %d\n", CONFIG_RTW_ADAPTIVITY_EN); +#if (CONFIG_RTW_ADAPTIVITY_EN) + DBG_871X_SEL_NL(sel, "ADAPTIVITY_MODE = %s\n", (CONFIG_RTW_ADAPTIVITY_MODE) ? "carrier_sense" : "normal"); +#endif + +#ifdef CONFIG_WOWLAN + DBG_871X_SEL_NL(sel, "CONFIG_WOWLAN - "); + + #ifdef CONFIG_GPIO_WAKEUP + DBG_871X_SEL_NL(sel, "CONFIG_GPIO_WAKEUP - WAKEUP_GPIO_IDX:%d\n", WAKEUP_GPIO_IDX); + #endif +#endif + +#ifdef CONFIG_USB_HCI + #ifdef CONFIG_SUPPORT_USB_INT + DBG_871X_SEL_NL(sel, "CONFIG_SUPPORT_USB_INT\n"); + #endif + #ifdef CONFIG_USB_INTERRUPT_IN_PIPE + DBG_871X_SEL_NL(sel, "CONFIG_USB_INTERRUPT_IN_PIPE\n"); + #endif + #ifdef CONFIG_USB_TX_AGGREGATION + DBG_871X_SEL_NL(sel, "CONFIG_USB_TX_AGGREGATION\n"); + #endif + #ifdef CONFIG_USB_RX_AGGREGATION + DBG_871X_SEL_NL(sel, "CONFIG_USB_RX_AGGREGATION\n"); + #endif + #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + DBG_871X_SEL_NL(sel, "CONFIG_USE_USB_BUFFER_ALLOC_TX\n"); + #endif + #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + DBG_871X_SEL_NL(sel, "CONFIG_USE_USB_BUFFER_ALLOC_RX\n"); + #endif + #ifdef CONFIG_PREALLOC_RECV_SKB + DBG_871X_SEL_NL(sel, "CONFIG_PREALLOC_RECV_SKB\n"); + #endif + #ifdef CONFIG_FIX_NR_BULKIN_BUFFER + DBG_871X_SEL_NL(sel, "CONFIG_FIX_NR_BULKIN_BUFFER\n"); + #endif +#endif /*CONFIG_USB_HCI*/ + +#ifdef CONFIG_SDIO_HCI + #ifdef CONFIG_TX_AGGREGATION + DBG_871X_SEL_NL(sel, "CONFIG_TX_AGGREGATION\n"); + #endif + #ifdef CONFIG_RX_AGGREGATION + DBG_871X_SEL_NL(sel, "CONFIG_RX_AGGREGATION\n"); + #endif +#endif /*CONFIG_SDIO_HCI*/ + +#ifdef CONFIG_PCI_HCI +#endif + + DBG_871X_SEL_NL(sel, "MAX_XMITBUF_SZ = %d\n", MAX_XMITBUF_SZ); + DBG_871X_SEL_NL(sel, "MAX_RECVBUF_SZ = %d\n", MAX_RECVBUF_SZ); + +} + +void dump_log_level(void *sel) +{ + DBG_871X_SEL_NL(sel, "log_level:%d\n", GlobalDebugLevel); +} + +#ifdef CONFIG_SDIO_HCI +void sd_f0_reg_dump(void *sel, _adapter *adapter) +{ + int i; + + for(i=0x0;i<=0xff;i++) + { + if(i%16==0) + DBG_871X_SEL_NL(sel, "0x%02x ",i); + + DBG_871X_SEL(sel, "%02x ", rtw_sd_f0_read8(adapter, i)); + + if(i%16==15) + DBG_871X_SEL(sel, "\n"); + else if(i%8==7) + DBG_871X_SEL(sel, "\t"); + } +} + +void sdio_local_reg_dump(void *sel, _adapter *adapter) +{ + int i, j = 1; + + for (i = 0x0; i < 0x100; i += 4) { + if (j % 4 == 1) + DBG_871X_SEL_NL(sel, "0x%02x", i); + DBG_871X_SEL(sel, " 0x%08x ", rtw_read32(adapter, (0x1025 << 16) | i)); + if ((j++) % 4 == 0) + DBG_871X_SEL(sel, "\n"); + } +} +#endif /* CONFIG_SDIO_HCI */ + +void mac_reg_dump(void *sel, _adapter *adapter) +{ + int i, j = 1; + + DBG_871X_SEL_NL(sel, "======= MAC REG =======\n"); + + for(i=0x0;i<0x800;i+=4) + { + if(j%4==1) + DBG_871X_SEL_NL(sel, "0x%03x",i); + DBG_871X_SEL(sel, " 0x%08x ", rtw_read32(adapter,i)); + if((j++)%4 == 0) + DBG_871X_SEL(sel, "\n"); + } + +#ifdef CONFIG_RTL8814A + { + for(i=0x1000;i<0x1650;i+=4) + { + if(j%4==1) + DBG_871X_SEL_NL(sel, "0x%03x",i); + DBG_871X_SEL(sel, " 0x%08x ", rtw_read32(adapter,i)); + if((j++)%4 == 0) + DBG_871X_SEL(sel, "\n"); + } + } +#endif /* CONFIG_RTL8814A */ +} + +void bb_reg_dump(void *sel, _adapter *adapter) +{ + int i, j = 1; + + DBG_871X_SEL_NL(sel, "======= BB REG =======\n"); + for(i=0x800;i<0x1000;i+=4) + { + if(j%4==1) + DBG_871X_SEL_NL(sel, "0x%03x",i); + DBG_871X_SEL(sel, " 0x%08x ", rtw_read32(adapter,i)); + if((j++)%4 == 0) + DBG_871X_SEL(sel, "\n"); + } +} + +void rf_reg_dump(void *sel, _adapter *adapter) +{ + int i, j = 1, path; + u32 value; + u8 rf_type = 0; + u8 path_nums = 0; + + rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if((RF_1T2R == rf_type) ||(RF_1T1R ==rf_type )) + path_nums = 1; + else + path_nums = 2; + + DBG_871X_SEL_NL(sel, "======= RF REG =======\n"); + + for (path=0;pathrecvpriv); + 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); + } + } +} + +void sta_rx_reorder_ctl_dump(void *sel, struct sta_info *sta) +{ + struct recv_reorder_ctrl *reorder_ctl; + int i; + + for (i = 0; i < 16; i++) { + reorder_ctl = &sta->recvreorder_ctrl[i]; + if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID || reorder_ctl->indicate_seq != 0xFFFF) { + DBG_871X_SEL_NL(sel, "tid=%d, enable=%d, ampdu_size=%u, indicate_seq=%u\n" + , i, reorder_ctl->enable, reorder_ctl->ampdu_size, reorder_ctl->indicate_seq + ); + } + } +} + +void dump_adapters_status(void *sel, struct dvobj_priv *dvobj) +{ + struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj); + int i; + _adapter *iface; + u8 u_ch, u_bw, u_offset; + + DBG_871X_SEL_NL(sel, "%-2s %-8s %-17s %-4s %-7s %s\n" + , "id", "ifname", "macaddr", "port", "ch", "status"); + + DBG_871X_SEL_NL(sel, "------------------------------------------\n"); + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (iface) { + DBG_871X_SEL_NL(sel, "%2d %-8s "MAC_FMT" %4hhu %3u,%u,%u "MLME_STATE_FMT" %s%s\n" + , i, ADPT_ARG(iface) + , MAC_ARG(adapter_mac_addr(iface)) + , get_iface_type(iface) + , iface->mlmeextpriv.cur_channel + , iface->mlmeextpriv.cur_bwmode + , iface->mlmeextpriv.cur_ch_offset + , MLME_STATE_ARG(iface) + , rtw_is_surprise_removed(iface)?" SR":"" + , rtw_is_drv_stopped(iface)?" DS":"" + ); + } + } + + DBG_871X_SEL_NL(sel, "------------------------------------------\n"); + + rtw_get_ch_setting_union(dvobj->padapters[IFACE_ID0], &u_ch, &u_bw, &u_offset); + DBG_871X_SEL_NL(sel, "%34s %3u,%u,%u\n" + , "union:" + , u_ch, u_bw, u_offset + ); + + DBG_871X_SEL_NL(sel, "%34s %3u,%u,%u\n" + , "oper:" + , dvobj->oper_channel + , dvobj->oper_bwmode + , dvobj->oper_ch_offset + ); + + #ifdef CONFIG_DFS_MASTER + if (rfctl->radar_detect_ch != 0) { + DBG_871X_SEL_NL(sel, "%34s %3u,%u,%u" + , "radar_detect:" + , rfctl->radar_detect_ch + , rfctl->radar_detect_bw + , rfctl->radar_detect_offset + ); + + if (IS_UNDER_CAC(rfctl)) + DBG_871X_SEL(sel, ", cac:%d\n", rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time())); + else + DBG_871X_SEL(sel, "\n"); + } + #endif +} + +#define SEC_CAM_ENT_ID_TITLE_FMT "%-2s" +#define SEC_CAM_ENT_ID_TITLE_ARG "id" +#define SEC_CAM_ENT_ID_VALUE_FMT "%2u" +#define SEC_CAM_ENT_ID_VALUE_ARG(id) (id) + +#define SEC_CAM_ENT_TITLE_FMT "%-6s %-17s %-32s %-3s %-7s %-2s %-2s %-5s" +#define SEC_CAM_ENT_TITLE_ARG "ctrl", "addr", "key", "kid", "type", "MK", "GK", "valid" +#define SEC_CAM_ENT_VALUE_FMT "0x%04x "MAC_FMT" "KEY_FMT" %3u %-7s %2u %2u %5u" +#define SEC_CAM_ENT_VALUE_ARG(ent) \ + (ent)->ctrl \ + , MAC_ARG((ent)->mac) \ + , KEY_ARG((ent)->key) \ + , ((ent)->ctrl) & 0x03 \ + , security_type_str((((ent)->ctrl) >> 2) & 0x07) \ + , (((ent)->ctrl) >> 5) & 0x01 \ + , (((ent)->ctrl) >> 6) & 0x01 \ + , (((ent)->ctrl) >> 15) & 0x01 + +void dump_sec_cam_ent(void *sel, struct sec_cam_ent *ent, int id) +{ + if (id >= 0) { + DBG_871X_SEL_NL(sel, SEC_CAM_ENT_ID_VALUE_FMT " " SEC_CAM_ENT_VALUE_FMT"\n" + , SEC_CAM_ENT_ID_VALUE_ARG(id), SEC_CAM_ENT_VALUE_ARG(ent)); + } else { + DBG_871X_SEL_NL(sel, SEC_CAM_ENT_VALUE_FMT"\n", SEC_CAM_ENT_VALUE_ARG(ent)); + } +} + +void dump_sec_cam_ent_title(void *sel, u8 has_id) +{ + if (has_id) { + DBG_871X_SEL_NL(sel, SEC_CAM_ENT_ID_TITLE_FMT " " SEC_CAM_ENT_TITLE_FMT"\n" + , SEC_CAM_ENT_ID_TITLE_ARG, SEC_CAM_ENT_TITLE_ARG); + } else { + DBG_871X_SEL_NL(sel, SEC_CAM_ENT_TITLE_FMT"\n", SEC_CAM_ENT_TITLE_ARG); + } +} + +void dump_sec_cam(void *sel, _adapter *adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + struct sec_cam_ent ent; + int i; + + DBG_871X_SEL_NL(sel, "HW sec cam:\n"); + dump_sec_cam_ent_title(sel, 1); + for (i = 0; i < cam_ctl->num; i++) { + rtw_sec_read_cam_ent(adapter, i, (u8 *)(&ent.ctrl), ent.mac, ent.key); + dump_sec_cam_ent(sel , &ent, i); + } +} + +#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) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 addr, val, len; + + if (count < 3) + { + DBG_871X("argument size is less than 3\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x %x %x", &addr, &val, &len); + + if (num != 3) { + DBG_871X("invalid write_reg parameter!\n"); + return count; + } + + switch(len) + { + case 1: + rtw_write8(padapter, addr, (u8)val); + break; + case 2: + rtw_write16(padapter, addr, (u16)val); + break; + case 4: + rtw_write32(padapter, addr, val); + break; + default: + DBG_871X("error write length=%d", len); + break; + } + + } + + return count; + +} + +static u32 proc_get_read_addr=0xeeeeeeee; +static u32 proc_get_read_len=0x4; + +int proc_get_read_reg(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + if (proc_get_read_addr==0xeeeeeeee) { + DBG_871X_SEL_NL(m, "address not initialized\n"); + return 0; + } + + switch(proc_get_read_len) + { + case 1: + DBG_871X_SEL_NL(m, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr)); + break; + case 2: + DBG_871X_SEL_NL(m, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr)); + break; + case 4: + DBG_871X_SEL_NL(m, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr)); + break; + default: + DBG_871X_SEL_NL(m, "error read length=%d\n", proc_get_read_len); + break; + } + + return 0; +} + +ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + char tmp[16]; + u32 addr, len; + + if (count < 2) + { + DBG_871X("argument size is less than 2\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x %x", &addr, &len); + + if (num != 2) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + + proc_get_read_addr = addr; + + proc_get_read_len = len; + } + + return count; + +} + +int proc_get_fwstate(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + DBG_871X_SEL_NL(m, "fwstate=0x%x\n", get_fwstate(pmlmepriv)); + + return 0; +} + +int proc_get_sec_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct security_priv *sec = &padapter->securitypriv; + + DBG_871X_SEL_NL(m, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + sec->dot11AuthAlgrthm, sec->dot11PrivacyAlgrthm, + sec->ndisauthtype, sec->ndisencryptstatus); + + DBG_871X_SEL_NL(m, "hw_decrypted=%d\n", sec->hw_decrypted); + +#ifdef DBG_SW_SEC_CNT + DBG_871X_SEL_NL(m, "wep_sw_enc_cnt=%llu, %llu, %llu\n" + , sec->wep_sw_enc_cnt_bc , sec->wep_sw_enc_cnt_mc, sec->wep_sw_enc_cnt_uc); + DBG_871X_SEL_NL(m, "wep_sw_dec_cnt=%llu, %llu, %llu\n" + , sec->wep_sw_dec_cnt_bc , sec->wep_sw_dec_cnt_mc, sec->wep_sw_dec_cnt_uc); + + DBG_871X_SEL_NL(m, "tkip_sw_enc_cnt=%llu, %llu, %llu\n" + , sec->tkip_sw_enc_cnt_bc , sec->tkip_sw_enc_cnt_mc, sec->tkip_sw_enc_cnt_uc); + DBG_871X_SEL_NL(m, "tkip_sw_dec_cnt=%llu, %llu, %llu\n" + , sec->tkip_sw_dec_cnt_bc , sec->tkip_sw_dec_cnt_mc, sec->tkip_sw_dec_cnt_uc); + + DBG_871X_SEL_NL(m, "aes_sw_enc_cnt=%llu, %llu, %llu\n" + , sec->aes_sw_enc_cnt_bc , sec->aes_sw_enc_cnt_mc, sec->aes_sw_enc_cnt_uc); + DBG_871X_SEL_NL(m, "aes_sw_dec_cnt=%llu, %llu, %llu\n" + , sec->aes_sw_dec_cnt_bc , sec->aes_sw_dec_cnt_mc, sec->aes_sw_dec_cnt_uc); +#endif /* DBG_SW_SEC_CNT */ + + return 0; +} + +int proc_get_mlmext_state(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X_SEL_NL(m, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state); + + return 0; +} + +#ifdef CONFIG_LAYER2_ROAMING +int proc_get_roam_flags(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, "0x%02x\n", rtw_roam_flags(adapter)); + + return 0; +} + +ssize_t proc_set_roam_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + char tmp[32]; + u8 flags; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx", &flags); + + if (num == 1) + rtw_assign_roam_flags(adapter, flags); + } + + return count; + +} + +int proc_get_roam_param(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + + DBG_871X_SEL_NL(m, "%12s %12s %11s\n", "rssi_diff_th", "scanr_exp_ms", "scan_int_ms"); + DBG_871X_SEL_NL(m, "%-12u %-12u %-11u\n" + , mlme->roam_rssi_diff_th + , mlme->roam_scanr_exp_ms + , mlme->roam_scan_int_ms + ); + + return 0; +} + +ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + + char tmp[32]; + u8 rssi_diff_th; + u32 scanr_exp_ms; + u32 scan_int_ms; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %u %u", &rssi_diff_th, &scanr_exp_ms, &scan_int_ms); + + if (num >= 1) + mlme->roam_rssi_diff_th = rssi_diff_th; + if (num >= 2) + mlme->roam_scanr_exp_ms = scanr_exp_ms; + if (num >= 3) + mlme->roam_scan_int_ms = scan_int_ms; + } + + return count; + +} + +ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + char tmp[32]; + u8 addr[ETH_ALEN]; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", addr, addr+1, addr+2, addr+3, addr+4, addr+5); + if (num == 6) + _rtw_memcpy(adapter->mlmepriv.roam_tgt_addr, addr, ETH_ALEN); + + DBG_871X("set roam_tgt_addr to "MAC_FMT"\n", MAC_ARG(adapter->mlmepriv.roam_tgt_addr)); + } + + return count; +} +#endif /* CONFIG_LAYER2_ROAMING */ + +int proc_get_qos_option(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + DBG_871X_SEL_NL(m, "qos_option=%d\n", pmlmepriv->qospriv.qos_option); + + return 0; +} + +int proc_get_ht_option(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_80211N_HT + DBG_871X_SEL_NL(m, "ht_option=%d\n", pmlmepriv->htpriv.ht_option); +#endif //CONFIG_80211N_HT + + return 0; +} + +int proc_get_rf_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + DBG_871X_SEL_NL(m, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n", + pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + + DBG_871X_SEL_NL(m, "oper_ch=%d, oper_bw=%d, oper_ch_offet=%d\n", + rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter)); + + return 0; +} + +int proc_get_scan_param(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + struct ss_res *ss = &mlmeext->sitesurvey_res; + +#define SCAN_PARAM_TITLE_FMT "%10s" +#define SCAN_PARAM_VALUE_FMT "%-10u" +#define SCAN_PARAM_TITLE_ARG , "scan_ch_ms" +#define SCAN_PARAM_VALUE_ARG , ss->scan_ch_ms +#ifdef CONFIG_80211N_HT + #define SCAN_PARAM_TITLE_FMT_HT " %15s %13s" + #define SCAN_PARAM_VALUE_FMT_HT " %-15u %-13u" + #define SCAN_PARAM_TITLE_ARG_HT , "rx_ampdu_accept", "rx_ampdu_size" + #define SCAN_PARAM_VALUE_ARG_HT , ss->rx_ampdu_accept, ss->rx_ampdu_size +#else + #define SCAN_PARAM_TITLE_FMT_HT "" + #define SCAN_PARAM_VALUE_FMT_HT "" + #define SCAN_PARAM_TITLE_ARG_HT + #define SCAN_PARAM_VALUE_ARG_HT +#endif +#ifdef CONFIG_SCAN_BACKOP + #define SCAN_PARAM_TITLE_FMT_BACKOP " %9s %12s" + #define SCAN_PARAM_VALUE_FMT_BACKOP " %-9u %-12u" + #define SCAN_PARAM_TITLE_ARG_BACKOP , "backop_ms", "scan_cnt_max" + #define SCAN_PARAM_VALUE_ARG_BACKOP , ss->backop_ms, ss->scan_cnt_max +#else + #define SCAN_PARAM_TITLE_FMT_BACKOP "" + #define SCAN_PARAM_VALUE_FMT_BACKOP "" + #define SCAN_PARAM_TITLE_ARG_BACKOP + #define SCAN_PARAM_VALUE_ARG_BACKOP +#endif + + DBG_871X_SEL_NL(m, + SCAN_PARAM_TITLE_FMT + SCAN_PARAM_TITLE_FMT_HT + SCAN_PARAM_TITLE_FMT_BACKOP + "\n" + SCAN_PARAM_TITLE_ARG + SCAN_PARAM_TITLE_ARG_HT + SCAN_PARAM_TITLE_ARG_BACKOP + ); + + DBG_871X_SEL_NL(m, + SCAN_PARAM_VALUE_FMT + SCAN_PARAM_VALUE_FMT_HT + SCAN_PARAM_VALUE_FMT_BACKOP + "\n" + SCAN_PARAM_VALUE_ARG + SCAN_PARAM_VALUE_ARG_HT + SCAN_PARAM_VALUE_ARG_BACKOP + ); + + return 0; +} + +ssize_t proc_set_scan_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + struct ss_res *ss = &mlmeext->sitesurvey_res; + + char tmp[32] = {0}; + +u16 scan_ch_ms; +#define SCAN_PARAM_INPUT_FMT "%hu" +#define SCAN_PARAM_INPUT_ARG , &scan_ch_ms +#ifdef CONFIG_80211N_HT + u8 rx_ampdu_accept; + u8 rx_ampdu_size; + #define SCAN_PARAM_INPUT_FMT_HT " %hhu %hhu" + #define SCAN_PARAM_INPUT_ARG_HT , &rx_ampdu_accept, &rx_ampdu_size +#else + #define SCAN_PARAM_INPUT_FMT_HT "" + #define SCAN_PARAM_INPUT_ARG_HT +#endif +#ifdef CONFIG_SCAN_BACKOP + u16 backop_ms; + u8 scan_cnt_max; + #define SCAN_PARAM_INPUT_FMT_BACKOP " %hu %hhu" + #define SCAN_PARAM_INPUT_ARG_BACKOP , &backop_ms, &scan_cnt_max +#else + #define SCAN_PARAM_INPUT_FMT_BACKOP "" + #define SCAN_PARAM_INPUT_ARG_BACKOP +#endif + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, + SCAN_PARAM_INPUT_FMT + SCAN_PARAM_INPUT_FMT_HT + SCAN_PARAM_INPUT_FMT_BACKOP + SCAN_PARAM_INPUT_ARG + SCAN_PARAM_INPUT_ARG_HT + SCAN_PARAM_INPUT_ARG_BACKOP + ); + + if (num-- > 0) + ss->scan_ch_ms = scan_ch_ms; + #ifdef CONFIG_80211N_HT + if (num-- > 0) + ss->rx_ampdu_accept = rx_ampdu_accept; + if (num-- > 0) + ss->rx_ampdu_size = rx_ampdu_size; + #endif + #ifdef CONFIG_SCAN_BACKOP + if (num-- > 0) + ss->backop_ms = backop_ms; + if (num-- > 0) + ss->scan_cnt_max = scan_cnt_max; + #endif + } + + return count; +} + +int proc_get_scan_abort(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + u32 pass_ms; + + pass_ms = rtw_scan_abort_timeout(adapter, 10000); + + DBG_871X_SEL_NL(m, "%u\n", pass_ms); + + return 0; +} + +#ifdef CONFIG_SCAN_BACKOP +int proc_get_backop_flags_sta(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + + DBG_871X_SEL_NL(m, "0x%02x\n", mlmeext_scan_backop_flags_sta(mlmeext)); + + return 0; +} + +ssize_t proc_set_backop_flags_sta(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + + char tmp[32]; + u8 flags; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx", &flags); + + if (num == 1) + mlmeext_assign_scan_backop_flags_sta(mlmeext, flags); + } + + return count; +} + +int proc_get_backop_flags_ap(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + + DBG_871X_SEL_NL(m, "0x%02x\n", mlmeext_scan_backop_flags_ap(mlmeext)); + + return 0; +} + +ssize_t proc_set_backop_flags_ap(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + + char tmp[32]; + u8 flags; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx", &flags); + + if (num == 1) + mlmeext_assign_scan_backop_flags_ap(mlmeext, flags); + } + + return count; +} + +#endif /* CONFIG_SCAN_BACKOP */ + +int proc_get_survey_info(struct seq_file *m, void *v) +{ + _irqL irqL; + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + _list *plist, *phead; + s32 notify_signal; + s16 notify_noise = 0; + u16 index = 0, ie_cap = 0; + unsigned char *ie_wpa = NULL, *ie_wpa2 = NULL, *ie_wps = NULL; + unsigned char *ie_p2p = NULL, *ssid = NULL; + char flag_str[64]; + int ielen = 0; + u32 wpsielen = 0; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + if(!phead) + return 0; + plist = get_next(phead); + if (!plist) + return 0; + + DBG_871X_SEL_NL(m, "%5s %-17s %3s %-3s %-4s %-4s %5s %32s %32s\n", "index", "bssid", "ch", "RSSI", "SdBm", "Noise", "age", "flag", "ssid"); + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (!pnetwork) + break; + + if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE && + is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { + notify_signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm + } else { + notify_signal = translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm + } + + #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(notify_noise)); + #endif + + ie_wpa = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &ielen, pnetwork->network.IELength-12); + ie_wpa2 = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &ielen, pnetwork->network.IELength-12); + ie_cap = rtw_get_capability(&pnetwork->network); + ie_wps = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength-12, NULL, &wpsielen); + ie_p2p = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength-12, NULL, &ielen); + ssid = pnetwork->network.Ssid.Ssid; + sprintf(flag_str, "%s%s%s%s%s%s%s", + (ie_wpa) ? "[WPA]":"", + (ie_wpa2) ? "[WPA2]":"", + (!ie_wpa && !ie_wpa && ie_cap & BIT(4)) ? "[WEP]":"", + (ie_wps) ? "[WPS]":"", + (pnetwork->network.InfrastructureMode == Ndis802_11IBSS) ? "[IBSS]":"", + (ie_cap & BIT(0)) ? "[ESS]":"", + (ie_p2p) ? "[P2P]":""); + DBG_871X_SEL_NL(m, "%5d "MAC_FMT" %3d %3d %4d %4d %5d %32s %32s\n", + ++index, + MAC_ARG(pnetwork->network.MacAddress), + pnetwork->network.Configuration.DSConfig, + (int)pnetwork->network.Rssi, + notify_signal, + notify_noise, + rtw_get_passing_time_ms((u32)pnetwork->last_scanned), + flag_str, + pnetwork->network.Ssid.Ssid); + plist = get_next(plist); + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + return 0; +} + +ssize_t proc_set_survey_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + _irqL irqL; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + bool need_indicate_scan_done = _FALSE; + u8 _status = _FALSE; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + + if (count < 1) + return -EFAULT; + +#ifdef CONFIG_MP_INCLUDED + if ((padapter->registrypriv.mp_mode == 1) +#ifdef CONFIG_CONCURRENT_MODE + || ((padapter->pbuddy_adapter) && (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)) +#endif + ){ + DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } +#endif + rtw_ps_deny(padapter, PS_DENY_SCAN); + if (_FAIL == rtw_pwr_wakeup(padapter)) + goto exit; + + if (rtw_is_drv_stopped(padapter)) { + DBG_871X("scan abort!! bDriverStopped=_TRUE\n"); + goto exit; + } + + if (!padapter->bup) { + DBG_871X("scan abort!! bup=%d\n", padapter->bup); + goto exit; + } + + if (!rtw_is_hw_init_completed(padapter)) { + DBG_871X("scan abort!! hw_init_completed=FALSE\n"); + goto exit; + } + + if (rtw_is_scan_deny(padapter)) { + DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } + + if ((pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) +#ifdef CONFIG_CONCURRENT_MODE + || (rtw_get_buddy_bBusyTraffic(padapter) == _TRUE) +#endif + ) { + DBG_871X("scan abort!! BusyTraffic == _TRUE\n"); + goto exit; + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { + DBG_8192C("scan abort!! fwstate=0x%x\n", pmlmepriv->fw_state); + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, + _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) { + DBG_871X("scan abort!! buddy_fwstate=0x%x\n", + get_fwstate(&(padapter->pbuddy_adapter->mlmepriv))); + goto exit; + } +#endif + _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); + +exit: + rtw_ps_deny_cancel(padapter, PS_DENY_SCAN); + return count; +} + +int proc_get_ap_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct sta_info *psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct sta_priv *pstapriv = &padapter->stapriv; + + psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(psta) + { + int i; + struct recv_reorder_ctrl *preorder_ctrl; + + DBG_871X_SEL_NL(m, "SSID=%s\n", cur_network->network.Ssid.Ssid); + DBG_871X_SEL_NL(m, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X_SEL_NL(m, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + DBG_871X_SEL_NL(m, "wireless_mode=0x%x, rtsen=%d, cts2slef=%d\n", psta->wireless_mode, psta->rtsen, psta->cts2self); + DBG_871X_SEL_NL(m, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); +#ifdef CONFIG_80211N_HT + DBG_871X_SEL_NL(m, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X_SEL_NL(m, "bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); + DBG_871X_SEL_NL(m, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X_SEL_NL(m, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); + DBG_871X_SEL_NL(m, "ldpc_cap=0x%x, stbc_cap=0x%x, beamform_cap=0x%x\n", psta->htpriv.ldpc_cap, psta->htpriv.stbc_cap, psta->htpriv.beamform_cap); +#endif //CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT + DBG_871X_SEL_NL(m, "vht_en=%d, vht_sgi_80m=%d\n", psta->vhtpriv.vht_option, psta->vhtpriv.sgi_80m); + DBG_871X_SEL_NL(m, "vht_ldpc_cap=0x%x, vht_stbc_cap=0x%x, vht_beamform_cap=0x%x\n", psta->vhtpriv.ldpc_cap, psta->vhtpriv.stbc_cap, psta->vhtpriv.beamform_cap); + DBG_871X_SEL_NL(m, "vht_mcs_map=0x%x, vht_highest_rate=0x%x, vht_ampdu_len=%d\n", *(u16*)psta->vhtpriv.vht_mcs_map, psta->vhtpriv.vht_highest_rate, psta->vhtpriv.ampdu_len); +#endif + + sta_rx_reorder_ctl_dump(m, psta); + } + else + { + DBG_871X_SEL_NL(m, "can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); + } + + return 0; +} + +ssize_t proc_reset_trx_info(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 dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + char cmd[32] = {0}; + u8 cnt = 0; + + if (count > sizeof(cmd)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(cmd, buffer, count)) { + int num = sscanf(cmd, "%hhx", &cnt); + + if (0 == cnt) { + pdbgpriv->dbg_rx_ampdu_drop_count = 0; + pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0; + pdbgpriv->dbg_rx_ampdu_loss_count = 0; + pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0; + pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0; + pdbgpriv->dbg_rx_conflic_mac_addr_cnt = 0; + } + } + + return count; +} + +int proc_get_trx_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + 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" + , pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt); + DBG_871X_SEL_NL(m, "free_recvframe_cnt=%d\n" + , precvpriv->free_recvframe_cnt); + + for(i = 0; i < 4; i++) + { + phwxmit = pxmitpriv->hwxmits + i; + DBG_871X_SEL_NL(m, "%d, hwq.accnt=%d\n", i, phwxmit->accnt); + } + +#ifdef CONFIG_USB_HCI + DBG_871X_SEL_NL(m, "rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt))); +#endif + + //Folowing are RX info + //Counts of packets whose seq_num is less than preorder_ctrl->indicate_seq, Ex delay, retransmission, redundant packets and so on + DBG_871X_SEL_NL(m,"Rx: Counts of Packets Whose Seq_Num Less Than Reorder Control Seq_Num: %llu\n",(unsigned long long)pdbgpriv->dbg_rx_ampdu_drop_count); + //How many times the Rx Reorder Timer is triggered. + DBG_871X_SEL_NL(m,"Rx: Reorder Time-out Trigger Counts: %llu\n",(unsigned long long)pdbgpriv->dbg_rx_ampdu_forced_indicate_count); + //Total counts of packets loss + DBG_871X_SEL_NL(m,"Rx: Packet Loss Counts: %llu\n",(unsigned long long)pdbgpriv->dbg_rx_ampdu_loss_count); + DBG_871X_SEL_NL(m,"Rx: Duplicate Management Frame Drop Count: %llu\n",(unsigned long long)pdbgpriv->dbg_rx_dup_mgt_frame_drop_count); + DBG_871X_SEL_NL(m,"Rx: AMPDU BA window shift Count: %llu\n",(unsigned long long)pdbgpriv->dbg_rx_ampdu_window_shift_cnt); + /*The same mac addr counts*/ + DBG_871X_SEL_NL(m, "Rx: Conflict MAC Address Frames Count: %llu\n", (unsigned long long)pdbgpriv->dbg_rx_conflic_mac_addr_cnt); + 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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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) { + 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) + , data_rate>DESC_RATE54M?(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"); + } + + return 0; +} + +ssize_t proc_set_rate_ctl(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u8 fix_rate; + u8 data_fb; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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; +} +#ifdef DBG_RX_COUNTER_DUMP +int proc_get_rx_cnt_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, "BIT0- Dump RX counters of DRV \n"); + DBG_871X_SEL_NL(m, "BIT1- Dump RX counters of MAC \n"); + DBG_871X_SEL_NL(m, "BIT2- Dump RX counters of PHY \n"); + DBG_871X_SEL_NL(m, "BIT3- Dump TRX data frame of DRV \n"); + DBG_871X_SEL_NL(m, "dump_rx_cnt_mode = 0x%02x \n", adapter->dump_rx_cnt_mode); + + return 0; +} +ssize_t proc_set_rx_cnt_dump(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u8 dump_rx_cnt_mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx", &dump_rx_cnt_mode); + + rtw_dump_phy_rxcnts_preprocess(adapter,dump_rx_cnt_mode); + adapter->dump_rx_cnt_mode = dump_rx_cnt_mode; + + } + + return count; +} +#endif +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; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) + num = sscanf(tmp, "%hhu %hhu", &fwdl_test_chksum_fail, &fwdl_test_wintint_rdy_fail); + + return count; +} + +ssize_t proc_set_del_rx_ampdu_test_case(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]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) + num = sscanf(tmp, "%hhu", &del_rx_ampdu_test_no_tx_fail); + + return count; +} + +#ifdef CONFIG_DFS_MASTER +int proc_get_dfs_master_test_case(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + + DBG_871X_SEL_NL(m, "%-24s %-19s\n", "radar_detect_trigger_non", "choose_dfs_ch_first"); + DBG_871X_SEL_NL(m, "%24hhu %19hhu\n" + , rfctl->dbg_dfs_master_radar_detect_trigger_non + , rfctl->dbg_dfs_master_choose_dfs_ch_first + ); + + return 0; +} + +ssize_t proc_set_dfs_master_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char tmp[32]; + u8 radar_detect_trigger_non; + u8 choose_dfs_ch_first; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhu %hhu", &radar_detect_trigger_non, &choose_dfs_ch_first); + + if (num >= 1) + rfctl->dbg_dfs_master_radar_detect_trigger_non = radar_detect_trigger_non; + if (num >= 2) + rfctl->dbg_dfs_master_choose_dfs_ch_first = choose_dfs_ch_first; + } + + return count; +} +#endif /* CONFIG_DFS_MASTER */ + +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; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) + num = sscanf(tmp, "%u", &g_wait_hiq_empty_ms); + + return count; +} + +int proc_get_suspend_resume_info(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, "dbg_sdio_alloc_irq_cnt=%d\n", pdbgpriv->dbg_sdio_alloc_irq_cnt); + DBG_871X_SEL_NL(m, "dbg_sdio_free_irq_cnt=%d\n", pdbgpriv->dbg_sdio_free_irq_cnt); + DBG_871X_SEL_NL(m, "dbg_sdio_alloc_irq_error_cnt=%d\n",pdbgpriv->dbg_sdio_alloc_irq_error_cnt); + DBG_871X_SEL_NL(m, "dbg_sdio_free_irq_error_cnt=%d\n", pdbgpriv->dbg_sdio_free_irq_error_cnt); + DBG_871X_SEL_NL(m, "dbg_sdio_init_error_cnt=%d\n",pdbgpriv->dbg_sdio_init_error_cnt); + DBG_871X_SEL_NL(m, "dbg_sdio_deinit_error_cnt=%d\n", pdbgpriv->dbg_sdio_deinit_error_cnt); + DBG_871X_SEL_NL(m, "dbg_suspend_error_cnt=%d\n", pdbgpriv->dbg_suspend_error_cnt); + DBG_871X_SEL_NL(m, "dbg_suspend_cnt=%d\n",pdbgpriv->dbg_suspend_cnt); + DBG_871X_SEL_NL(m, "dbg_resume_cnt=%d\n", pdbgpriv->dbg_resume_cnt); + DBG_871X_SEL_NL(m, "dbg_resume_error_cnt=%d\n", pdbgpriv->dbg_resume_error_cnt); + DBG_871X_SEL_NL(m, "dbg_deinit_fail_cnt=%d\n",pdbgpriv->dbg_deinit_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_carddisable_cnt=%d\n", pdbgpriv->dbg_carddisable_cnt); + DBG_871X_SEL_NL(m, "dbg_ps_insuspend_cnt=%d\n",pdbgpriv->dbg_ps_insuspend_cnt); + DBG_871X_SEL_NL(m, "dbg_dev_unload_inIPS_cnt=%d\n", pdbgpriv->dbg_dev_unload_inIPS_cnt); + DBG_871X_SEL_NL(m, "dbg_scan_pwr_state_cnt=%d\n", pdbgpriv->dbg_scan_pwr_state_cnt); + DBG_871X_SEL_NL(m, "dbg_downloadfw_pwr_state_cnt=%d\n", pdbgpriv->dbg_downloadfw_pwr_state_cnt); + DBG_871X_SEL_NL(m, "dbg_carddisable_error_cnt=%d\n", pdbgpriv->dbg_carddisable_error_cnt); + DBG_871X_SEL_NL(m, "dbg_fw_read_ps_state_fail_cnt=%d\n", pdbgpriv->dbg_fw_read_ps_state_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_leave_ips_fail_cnt=%d\n", pdbgpriv->dbg_leave_ips_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_leave_lps_fail_cnt=%d\n", pdbgpriv->dbg_leave_lps_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_h2c_leave32k_fail_cnt=%d\n", pdbgpriv->dbg_h2c_leave32k_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_diswow_dload_fw_fail_cnt=%d\n", pdbgpriv->dbg_diswow_dload_fw_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_enwow_dload_fw_fail_cnt=%d\n", pdbgpriv->dbg_enwow_dload_fw_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_ips_drvopen_fail_cnt=%d\n", pdbgpriv->dbg_ips_drvopen_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_poll_fail_cnt=%d\n", pdbgpriv->dbg_poll_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_rpwm_toogle_cnt=%d\n", pdbgpriv->dbg_rpwm_toogle_cnt); + DBG_871X_SEL_NL(m, "dbg_rpwm_timeout_fail_cnt=%d\n", pdbgpriv->dbg_rpwm_timeout_fail_cnt); + DBG_871X_SEL_NL(m, "dbg_sreset_cnt=%d\n", pdbgpriv->dbg_sreset_cnt); + + return 0; +} + +#ifdef CONFIG_DBG_COUNTER + +int proc_get_rx_logs(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct rx_logs *rx_logs = &padapter->rx_logs; + + DBG_871X_SEL_NL(m, + "intf_rx=%d\n" + "intf_rx_err_recvframe=%d\n" + "intf_rx_err_skb=%d\n" + "intf_rx_report=%d\n" + "core_rx=%d\n" + "core_rx_pre=%d\n" + "core_rx_pre_ver_err=%d\n" + "core_rx_pre_mgmt=%d\n" + "core_rx_pre_mgmt_err_80211w=%d\n" + "core_rx_pre_mgmt_err=%d\n" + "core_rx_pre_ctrl=%d\n" + "core_rx_pre_ctrl_err=%d\n" + "core_rx_pre_data=%d\n" + "core_rx_pre_data_wapi_seq_err=%d\n" + "core_rx_pre_data_wapi_key_err=%d\n" + "core_rx_pre_data_handled=%d\n" + "core_rx_pre_data_err=%d\n" + "core_rx_pre_data_unknown=%d\n" + "core_rx_pre_unknown=%d\n" + "core_rx_enqueue=%d\n" + "core_rx_dequeue=%d\n" + "core_rx_post=%d\n" + "core_rx_post_decrypt=%d\n" + "core_rx_post_decrypt_wep=%d\n" + "core_rx_post_decrypt_tkip=%d\n" + "core_rx_post_decrypt_aes=%d\n" + "core_rx_post_decrypt_wapi=%d\n" + "core_rx_post_decrypt_hw=%d\n" + "core_rx_post_decrypt_unknown=%d\n" + "core_rx_post_decrypt_err=%d\n" + "core_rx_post_defrag_err=%d\n" + "core_rx_post_portctrl_err=%d\n" + "core_rx_post_indicate=%d\n" + "core_rx_post_indicate_in_oder=%d\n" + "core_rx_post_indicate_reoder=%d\n" + "core_rx_post_indicate_err=%d\n" + "os_indicate=%d\n" + "os_indicate_ap_mcast=%d\n" + "os_indicate_ap_forward=%d\n" + "os_indicate_ap_self=%d\n" + "os_indicate_err=%d\n" + "os_netif_ok=%d\n" + "os_netif_err=%d\n", + rx_logs->intf_rx, + rx_logs->intf_rx_err_recvframe, + rx_logs->intf_rx_err_skb, + rx_logs->intf_rx_report, + rx_logs->core_rx, + rx_logs->core_rx_pre, + rx_logs->core_rx_pre_ver_err, + rx_logs->core_rx_pre_mgmt, + rx_logs->core_rx_pre_mgmt_err_80211w, + rx_logs->core_rx_pre_mgmt_err, + rx_logs->core_rx_pre_ctrl, + rx_logs->core_rx_pre_ctrl_err, + rx_logs->core_rx_pre_data, + rx_logs->core_rx_pre_data_wapi_seq_err, + rx_logs->core_rx_pre_data_wapi_key_err, + rx_logs->core_rx_pre_data_handled, + rx_logs->core_rx_pre_data_err, + rx_logs->core_rx_pre_data_unknown, + rx_logs->core_rx_pre_unknown, + rx_logs->core_rx_enqueue, + rx_logs->core_rx_dequeue, + rx_logs->core_rx_post, + rx_logs->core_rx_post_decrypt, + rx_logs->core_rx_post_decrypt_wep, + rx_logs->core_rx_post_decrypt_tkip, + rx_logs->core_rx_post_decrypt_aes, + rx_logs->core_rx_post_decrypt_wapi, + rx_logs->core_rx_post_decrypt_hw, + rx_logs->core_rx_post_decrypt_unknown, + rx_logs->core_rx_post_decrypt_err, + rx_logs->core_rx_post_defrag_err, + rx_logs->core_rx_post_portctrl_err, + rx_logs->core_rx_post_indicate, + rx_logs->core_rx_post_indicate_in_oder, + rx_logs->core_rx_post_indicate_reoder, + rx_logs->core_rx_post_indicate_err, + rx_logs->os_indicate, + rx_logs->os_indicate_ap_mcast, + rx_logs->os_indicate_ap_forward, + rx_logs->os_indicate_ap_self, + rx_logs->os_indicate_err, + rx_logs->os_netif_ok, + rx_logs->os_netif_err + ); + + return 0; +} + +int proc_get_tx_logs(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tx_logs *tx_logs = &padapter->tx_logs; + + DBG_871X_SEL_NL(m, + "os_tx=%d\n" + "os_tx_err_up=%d\n" + "os_tx_err_xmit=%d\n" + "os_tx_m2u=%d\n" + "os_tx_m2u_ignore_fw_linked=%d\n" + "os_tx_m2u_ignore_self=%d\n" + "os_tx_m2u_entry=%d\n" + "os_tx_m2u_entry_err_xmit=%d\n" + "os_tx_m2u_entry_err_skb=%d\n" + "os_tx_m2u_stop=%d\n" + "core_tx=%d\n" + "core_tx_err_pxmitframe=%d\n" + "core_tx_err_brtx=%d\n" + "core_tx_upd_attrib=%d\n" + "core_tx_upd_attrib_adhoc=%d\n" + "core_tx_upd_attrib_sta=%d\n" + "core_tx_upd_attrib_ap=%d\n" + "core_tx_upd_attrib_unknown=%d\n" + "core_tx_upd_attrib_dhcp=%d\n" + "core_tx_upd_attrib_icmp=%d\n" + "core_tx_upd_attrib_active=%d\n" + "core_tx_upd_attrib_err_ucast_sta=%d\n" + "core_tx_upd_attrib_err_ucast_ap_link=%d\n" + "core_tx_upd_attrib_err_sta=%d\n" + "core_tx_upd_attrib_err_link=%d\n" + "core_tx_upd_attrib_err_sec=%d\n" + "core_tx_ap_enqueue_warn_fwstate=%d\n" + "core_tx_ap_enqueue_warn_sta=%d\n" + "core_tx_ap_enqueue_warn_nosta=%d\n" + "core_tx_ap_enqueue_warn_link=%d\n" + "core_tx_ap_enqueue_warn_trigger=%d\n" + "core_tx_ap_enqueue_mcast=%d\n" + "core_tx_ap_enqueue_ucast=%d\n" + "core_tx_ap_enqueue=%d\n" + "intf_tx=%d\n" + "intf_tx_pending_ac=%d\n" + "intf_tx_pending_fw_under_survey=%d\n" + "intf_tx_pending_fw_under_linking=%d\n" + "intf_tx_pending_xmitbuf=%d\n" + "intf_tx_enqueue=%d\n" + "core_tx_enqueue=%d\n" + "core_tx_enqueue_class=%d\n" + "core_tx_enqueue_class_err_sta=%d\n" + "core_tx_enqueue_class_err_nosta=%d\n" + "core_tx_enqueue_class_err_fwlink=%d\n" + "intf_tx_direct=%d\n" + "intf_tx_direct_err_coalesce=%d\n" + "intf_tx_dequeue=%d\n" + "intf_tx_dequeue_err_coalesce=%d\n" + "intf_tx_dump_xframe=%d\n" + "intf_tx_dump_xframe_err_txdesc=%d\n" + "intf_tx_dump_xframe_err_port=%d\n", + tx_logs->os_tx, + tx_logs->os_tx_err_up, + tx_logs->os_tx_err_xmit, + tx_logs->os_tx_m2u, + tx_logs->os_tx_m2u_ignore_fw_linked, + tx_logs->os_tx_m2u_ignore_self, + tx_logs->os_tx_m2u_entry, + tx_logs->os_tx_m2u_entry_err_xmit, + tx_logs->os_tx_m2u_entry_err_skb, + tx_logs->os_tx_m2u_stop, + tx_logs->core_tx, + tx_logs->core_tx_err_pxmitframe, + tx_logs->core_tx_err_brtx, + tx_logs->core_tx_upd_attrib, + tx_logs->core_tx_upd_attrib_adhoc, + tx_logs->core_tx_upd_attrib_sta, + tx_logs->core_tx_upd_attrib_ap, + tx_logs->core_tx_upd_attrib_unknown, + tx_logs->core_tx_upd_attrib_dhcp, + tx_logs->core_tx_upd_attrib_icmp, + tx_logs->core_tx_upd_attrib_active, + tx_logs->core_tx_upd_attrib_err_ucast_sta, + tx_logs->core_tx_upd_attrib_err_ucast_ap_link, + tx_logs->core_tx_upd_attrib_err_sta, + tx_logs->core_tx_upd_attrib_err_link, + tx_logs->core_tx_upd_attrib_err_sec, + tx_logs->core_tx_ap_enqueue_warn_fwstate, + tx_logs->core_tx_ap_enqueue_warn_sta, + tx_logs->core_tx_ap_enqueue_warn_nosta, + tx_logs->core_tx_ap_enqueue_warn_link, + tx_logs->core_tx_ap_enqueue_warn_trigger, + tx_logs->core_tx_ap_enqueue_mcast, + tx_logs->core_tx_ap_enqueue_ucast, + tx_logs->core_tx_ap_enqueue, + tx_logs->intf_tx, + tx_logs->intf_tx_pending_ac, + tx_logs->intf_tx_pending_fw_under_survey, + tx_logs->intf_tx_pending_fw_under_linking, + tx_logs->intf_tx_pending_xmitbuf, + tx_logs->intf_tx_enqueue, + tx_logs->core_tx_enqueue, + tx_logs->core_tx_enqueue_class, + tx_logs->core_tx_enqueue_class_err_sta, + tx_logs->core_tx_enqueue_class_err_nosta, + tx_logs->core_tx_enqueue_class_err_fwlink, + tx_logs->intf_tx_direct, + tx_logs->intf_tx_direct_err_coalesce, + tx_logs->intf_tx_dequeue, + tx_logs->intf_tx_dequeue_err_coalesce, + tx_logs->intf_tx_dump_xframe, + tx_logs->intf_tx_dump_xframe_err_txdesc, + tx_logs->intf_tx_dump_xframe_err_port + ); + + return 0; +} + +int proc_get_int_logs(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, + "all=%d\n" + "err=%d\n" + "tbdok=%d\n" + "tbder=%d\n" + "bcnderr=%d\n" + "bcndma=%d\n" + "bcndma_e=%d\n" + "rx=%d\n" + "rx_rdu=%d\n" + "rx_fovw=%d\n" + "txfovw=%d\n" + "mgntok=%d\n" + "highdok=%d\n" + "bkdok=%d\n" + "bedok=%d\n" + "vidok=%d\n" + "vodok=%d\n", + padapter->int_logs.all, + padapter->int_logs.err, + padapter->int_logs.tbdok, + padapter->int_logs.tbder, + padapter->int_logs.bcnderr, + padapter->int_logs.bcndma, + padapter->int_logs.bcndma_e, + padapter->int_logs.rx, + padapter->int_logs.rx_rdu, + padapter->int_logs.rx_fovw, + padapter->int_logs.txfovw, + padapter->int_logs.mgntok, + padapter->int_logs.highdok, + padapter->int_logs.bkdok, + padapter->int_logs.bedok, + padapter->int_logs.vidok, + padapter->int_logs.vodok + ); + + return 0; +} + +#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; + + if (pdbgpriv->dbg_rx_fifo_last_overflow == 1 + && pdbgpriv->dbg_rx_fifo_curr_overflow == 1 + && pdbgpriv->dbg_rx_fifo_diff_overflow == 1 + ) { + DBG_871X_SEL_NL(m, "RX FIFO full count: no implementation\n"); + } else { + DBG_871X_SEL_NL(m, "RX FIFO full count: last_time=%llu, current_time=%llu, differential=%llu\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; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + DBG_871X_SEL_NL(m, "rssi:%d\n", padapter->recvpriv.rssi); + //DBG_871X_SEL_NL(m, "rxpwdb:%d\n", padapter->recvpriv.rxpwdb); + DBG_871X_SEL_NL(m, "signal_strength:%u\n", padapter->recvpriv.signal_strength); + DBG_871X_SEL_NL(m, "signal_qual:%u\n", padapter->recvpriv.signal_qual); + + rtw_get_noise(padapter); + DBG_871X_SEL_NL(m, "noise:%d\n", padapter->recvpriv.noise); + #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA + rtw_odm_get_perpkt_rssi(m,padapter); + rtw_get_raw_rssi_info(m,padapter); + #endif + 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; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 is_signal_dbg, signal_strength; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength); + + is_signal_dbg = is_signal_dbg==0?0:1; + + if(is_signal_dbg && num!=2) + return count; + + signal_strength = signal_strength>100?100:signal_strength; + + padapter->recvpriv.is_signal_dbg = is_signal_dbg; + padapter->recvpriv.signal_strength_dbg=signal_strength; + + if(is_signal_dbg) + DBG_871X("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength); + else + DBG_871X("set %s\n", "HW_SIGNAL_STRENGTH"); + + } + + return count; + +} +#ifdef CONFIG_80211N_HT + +int proc_get_ht_enable(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; + + if(pregpriv) + DBG_871X_SEL_NL(m, "%d\n", pregpriv->ht_enable); + + return 0; +} + +ssize_t proc_set_ht_enable(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 registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode < 2 ) + { + pregpriv->ht_enable= mode; + DBG_871X("ht_enable=%d\n", pregpriv->ht_enable); + } + } + + return count; + +} + +int proc_get_bw_mode(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; + + if(pregpriv) + DBG_871X_SEL_NL(m, "0x%02x\n", pregpriv->bw_mode); + + return 0; +} + +ssize_t proc_set_bw_mode(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 registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode < 2 ) + { + + pregpriv->bw_mode = mode; + printk("bw_mode=%d\n", mode); + + } + } + + return count; + +} + +int proc_get_ampdu_enable(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; + + if(pregpriv) + DBG_871X_SEL_NL(m, "%d\n", pregpriv->ampdu_enable); + + return 0; +} + +ssize_t proc_set_ampdu_enable(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 registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode < 3 ) + { + pregpriv->ampdu_enable= mode; + printk("ampdu_enable=%d\n", mode); + } + + } + + return count; + +} + +int proc_get_mac_rptbuf(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u16 i; + u16 mac_id; + u32 shcut_addr = 0; + u32 read_addr = 0; +#ifdef CONFIG_RTL8814A + DBG_871X_SEL_NL(m, "TX ShortCut:\n"); + for (mac_id = 0; mac_id < 64; mac_id++) { + rtw_write16(padapter, 0x140, 0x662 | ((mac_id & BIT5)>>5)); + shcut_addr = 0x8000; + shcut_addr = shcut_addr | ((mac_id&0x1f) << 7); + DBG_871X_SEL_NL(m, "mac_id=%d, 0x140=%x =>\n", mac_id, 0x662 | ((mac_id & BIT5)>>5)); + for (i = 0; i < 30; i++) { + read_addr = 0; + read_addr = shcut_addr | (i<<2); + DBG_871X_SEL_NL(m, "i=%02d: MAC_%04x= %08x ", i, read_addr, rtw_read32(padapter, read_addr)); + if (!((i+1) % 4)) + DBG_871X_SEL_NL(m, "\n"); + if (i == 29) + DBG_871X_SEL_NL(m, "\n"); + } + } +#endif /* CONFIG_RTL8814A */ + return 0; +} + + +int proc_get_rx_ampdu(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL(m, "accept: "); + if (padapter->fix_rx_ampdu_accept == RX_AMPDU_ACCEPT_INVALID) + DBG_871X_SEL_NL(m, "%u%s\n", rtw_rx_ampdu_is_accept(padapter), "(auto)"); + else + DBG_871X_SEL_NL(m, "%u%s\n", padapter->fix_rx_ampdu_accept, "(fixed)"); + + DBG_871X_SEL(m, "size: "); + if (padapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID) + DBG_871X_SEL_NL(m, "%u%s\n", rtw_rx_ampdu_size(padapter), "(auto)"); + else + DBG_871X_SEL_NL(m, "%u%s\n", padapter->fix_rx_ampdu_size, "(fixed)"); + + DBG_871X_SEL_NL(m, "%19s %17s\n", "fix_rx_ampdu_accept", "fix_rx_ampdu_size"); + + DBG_871X_SEL(m, "%-19d %-17u\n" + , padapter->fix_rx_ampdu_accept + , padapter->fix_rx_ampdu_size); + + return 0; +} + +ssize_t proc_set_rx_ampdu(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 registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + char tmp[32]; + u8 accept; + u8 size; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %hhu", &accept, &size); + + if (num >= 1) + rtw_rx_ampdu_set_accept(padapter, accept, RX_AMPDU_DRV_FIXED); + if (num >= 2) + rtw_rx_ampdu_set_size(padapter, size, RX_AMPDU_DRV_FIXED); + + rtw_rx_ampdu_apply(padapter); + } + +exit: + 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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pregpriv) + DBG_871X_SEL_NL(m, "check_fw_ps = %d , 1:enable get FW PS state , 0: disable get FW PS state\n" + , pregpriv->check_fw_ps); + + return 0; +} + +ssize_t proc_set_en_fwps(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 registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && mode < 2 ) + { + pregpriv->check_fw_ps = mode; + DBG_871X("pregpriv->check_fw_ps=%d \n",pregpriv->check_fw_ps); + } + + } + + return count; +} + +/* +int proc_get_two_path_rssi(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, "%d %d\n", + padapter->recvpriv.RxRssi[0], padapter->recvpriv.RxRssi[1]); + + return 0; +} +*/ +#ifdef CONFIG_80211N_HT +int proc_get_rx_stbc(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; + + if(pregpriv) + DBG_871X_SEL_NL(m, "%d\n", pregpriv->rx_stbc); + + return 0; +} + +ssize_t proc_set_rx_stbc(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 registry_priv *pregpriv = &padapter->registrypriv; + char tmp[32]; + u32 mode; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &mode); + + if( pregpriv && (mode == 0 || mode == 1|| mode == 2|| mode == 3)) + { + pregpriv->rx_stbc= mode; + printk("rx_stbc=%d\n", mode); + } + } + + return count; + +} +#endif //CONFIG_80211N_HT + +/*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) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + u32 enable=0; + + if (count < 1) + { + DBG_8192C("argument size is less than 1\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x", &enable); + + if (num != 1) { + DBG_8192C("invalid set_rssi_disp parameter!\n"); + return count; + } + + if(enable) + { + DBG_8192C("Linked info Function Enable\n"); + padapter->bLinkInfoDump = enable ; + } + else + { + DBG_8192C("Linked info Function Disable\n"); + padapter->bLinkInfoDump = 0 ; + } + + } + + return count; + +} + +*/ +#ifdef CONFIG_AP_MODE + +int proc_get_all_sta_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _irqL irqL; + struct sta_info *psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapter->stapriv; + int i; + _list *plist, *phead; + + DBG_871X_SEL_NL(m, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); + + _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(extra_arg == psta->aid) + { + DBG_871X_SEL_NL(m, "==============================\n"); + DBG_871X_SEL_NL(m, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X_SEL_NL(m, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + DBG_871X_SEL_NL(m, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); +#ifdef CONFIG_80211N_HT + DBG_871X_SEL_NL(m, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X_SEL_NL(m, "bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); + DBG_871X_SEL_NL(m, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X_SEL_NL(m, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); +#endif //CONFIG_80211N_HT + DBG_871X_SEL_NL(m, "sleepq_len=%d\n", psta->sleepq_len); + DBG_871X_SEL_NL(m, "sta_xmitpriv.vo_q_qcnt=%d\n", psta->sta_xmitpriv.vo_q.qcnt); + DBG_871X_SEL_NL(m, "sta_xmitpriv.vi_q_qcnt=%d\n", psta->sta_xmitpriv.vi_q.qcnt); + DBG_871X_SEL_NL(m, "sta_xmitpriv.be_q_qcnt=%d\n", psta->sta_xmitpriv.be_q.qcnt); + DBG_871X_SEL_NL(m, "sta_xmitpriv.bk_q_qcnt=%d\n", psta->sta_xmitpriv.bk_q.qcnt); + + DBG_871X_SEL_NL(m, "capability=0x%x\n", psta->capability); + DBG_871X_SEL_NL(m, "flags=0x%x\n", psta->flags); + DBG_871X_SEL_NL(m, "wpa_psk=0x%x\n", psta->wpa_psk); + DBG_871X_SEL_NL(m, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); + DBG_871X_SEL_NL(m, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); + DBG_871X_SEL_NL(m, "qos_info=0x%x\n", psta->qos_info); + DBG_871X_SEL_NL(m, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); + + sta_rx_reorder_ctl_dump(m, psta); + +#ifdef CONFIG_TDLS + DBG_871X_SEL_NL(m, "tdls_sta_state=0x%08x\n", psta->tdls_sta_state); + DBG_871X_SEL_NL(m, "PeerKey_Lifetime=%d\n", psta->TDLS_PeerKey_Lifetime); + DBG_871X_SEL_NL(m, "rx_data_pkts=%llu\n", psta->sta_stats.rx_data_pkts); + DBG_871X_SEL_NL(m, "rx_bytes=%llu\n", psta->sta_stats.rx_bytes); + DBG_871X_SEL_NL(m, "tx_data_pkts=%llu\n", psta->sta_stats.tx_pkts); + DBG_871X_SEL_NL(m, "tx_bytes=%llu\n", psta->sta_stats.tx_bytes); +#endif //CONFIG_TDLS + + dump_st_ctl(m, &psta->st_ctl); + + if (STA_OP_WFD_MODE(psta)) + DBG_871X_SEL_NL(m, "op_wfd_mode:0x%02x\n", STA_OP_WFD_MODE(psta)); + + DBG_871X_SEL_NL(m, "==============================\n"); + } + + } + + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + return 0; +} + +#endif + +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER +int proc_get_rtkm_info(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; + struct recv_buf *precvbuf; + + precvbuf = (struct recv_buf *)precvpriv->precv_buf; + + DBG_871X_SEL_NL(m, "============[RTKM Info]============\n"); + DBG_871X_SEL_NL(m, "MAX_RTKM_NR_PREALLOC_RECV_SKB: %d\n", rtw_rtkm_get_nr_recv_skb()); + DBG_871X_SEL_NL(m, "MAX_RTKM_RECVBUF_SZ: %d\n", rtw_rtkm_get_buff_size()); + + DBG_871X_SEL_NL(m, "============[Driver Info]============\n"); + DBG_871X_SEL_NL(m, "NR_PREALLOC_RECV_SKB: %d\n", NR_PREALLOC_RECV_SKB); + DBG_871X_SEL_NL(m, "MAX_RECVBUF_SZ: %d\n", precvbuf->alloc_sz); + + return 0; +} +#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */ + +#ifdef DBG_MEMORY_LEAK +#include +extern atomic_t _malloc_cnt;; +extern atomic_t _malloc_size;; + +int proc_get_malloc_cnt(struct seq_file *m, void *v) +{ + DBG_871X_SEL_NL(m, "_malloc_cnt=%d\n", atomic_read(&_malloc_cnt)); + DBG_871X_SEL_NL(m, "_malloc_size=%d\n", atomic_read(&_malloc_size)); + + return 0; +} +#endif /* DBG_MEMORY_LEAK */ + +#ifdef CONFIG_FIND_BEST_CHANNEL +int proc_get_best_channel(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0; + + for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + if ( pmlmeext->channel_set[i].ChannelNum == 1) + index_24G = i; + if ( pmlmeext->channel_set[i].ChannelNum == 36) + index_5G = 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 ) { + index_24G = i; + best_channel_24G = pmlmeext->channel_set[i].ChannelNum; + } + } + + // 5G + if ( pmlmeext->channel_set[i].ChannelNum >= 36 + && pmlmeext->channel_set[i].ChannelNum < 140 ) { + // Find primary channel + if ( (( pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } + + if ( pmlmeext->channel_set[i].ChannelNum >= 149 + && pmlmeext->channel_set[i].ChannelNum < 165) { + // find primary channel + if ( (( pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } +#if 1 // debug + DBG_871X_SEL_NL(m, "The rx cnt of channel %3d = %d\n", + pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count); +#endif + } + + DBG_871X_SEL_NL(m, "best_channel_5G = %d\n", best_channel_5G); + DBG_871X_SEL_NL(m, "best_channel_24G = %d\n", best_channel_24G); + + return 0; +} + +ssize_t proc_set_best_channel(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 mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + char tmp[32]; + + if(count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int i; + for(i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) + { + pmlmeext->channel_set[i].rx_count = 0; + } + + DBG_871X("set %s\n", "Clean Best Channel Count"); + } + + return count; +} +#endif /* CONFIG_FIND_BEST_CHANNEL */ + +#ifdef CONFIG_BT_COEXIST +int proc_get_btcoex_dbg(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + PADAPTER padapter; + char buf[512] = {0}; + padapter = (PADAPTER)rtw_netdev_priv(dev); + + rtw_btcoex_GetDBG(padapter, buf, 512); + + DBG_871X_SEL(m, "%s", buf); + + return 0; +} + +ssize_t proc_set_btcoex_dbg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + PADAPTER padapter; + u8 tmp[80] = {0}; + u32 module[2] = {0}; + u32 num; + + padapter = (PADAPTER)rtw_netdev_priv(dev); + +// DBG_871X("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter)); + + if (NULL == buffer) + { + DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n", + FUNC_ADPT_ARG(padapter)); + + return -EFAULT; + } + + if (count < 1) + { + DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n", + FUNC_ADPT_ARG(padapter)); + + return -EFAULT; + } + + num = count; + if (num > (sizeof(tmp) - 1)) + num = (sizeof(tmp) - 1); + + if (copy_from_user(tmp, buffer, num)) + { + DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n", + FUNC_ADPT_ARG(padapter)); + + return -EFAULT; + } + + num = sscanf(tmp, "%x %x", module, module+1); + if (1 == num) + { + if (0 == module[0]) + _rtw_memset(module, 0, sizeof(module)); + else + _rtw_memset(module, 0xFF, sizeof(module)); + } + else if (2 != num) + { + DBG_871X(FUNC_ADPT_FMT ": input(\"%s\") format incorrect!\n", + FUNC_ADPT_ARG(padapter), tmp); + + if (0 == num) + return -EFAULT; + } + + DBG_871X(FUNC_ADPT_FMT ": input 0x%08X 0x%08X\n", + FUNC_ADPT_ARG(padapter), module[0], module[1]); + rtw_btcoex_SetDBG(padapter, module); + + return count; +} + +int proc_get_btcoex_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + PADAPTER padapter; + const u32 bufsize = 30*100; + u8 *pbuf = NULL; + + padapter = (PADAPTER)rtw_netdev_priv(dev); + + pbuf = rtw_zmalloc(bufsize); + if (NULL == pbuf) { + return -ENOMEM; + } + + rtw_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize); + + DBG_871X_SEL(m, "%s\n", pbuf); + + rtw_mfree(pbuf, bufsize); + + return 0; +} +#endif /* CONFIG_BT_COEXIST */ + +#if defined(DBG_CONFIG_ERROR_DETECT) +int proc_get_sreset(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + return 0; +} + +ssize_t proc_set_sreset(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]; + s32 trigger_point; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d", &trigger_point); + + if (trigger_point == SRESET_TGP_NULL) + rtw_hal_sreset_reset(padapter); + else + sreset_set_trigger_point(padapter, trigger_point); + } + + return count; + +} +#endif /* DBG_CONFIG_ERROR_DETECT */ + +#ifdef CONFIG_PCI_HCI + +int proc_get_rx_ring(struct seq_file *m, void *v) +{ + _irqL irqL; + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *) rtw_netdev_priv(dev); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct recv_priv *precvpriv = &padapter->recvpriv; + struct rtw_rx_ring *rx_ring = &precvpriv->rx_ring[RX_MPDU_QUEUE]; + int i, j; + + DBG_871X_SEL_NL(m, "rx ring (%p)\n", rx_ring); + DBG_871X_SEL_NL(m, " dma: 0x%08x\n", (int) rx_ring->dma); + DBG_871X_SEL_NL(m, " idx: %d\n", rx_ring->idx); + + _enter_critical(&pdvobjpriv->irq_th_lock, &irqL); + for (i=0; irxringcount; i++) + { + struct recv_stat *entry = &rx_ring->desc[i]; + struct sk_buff *skb = rx_ring->rx_buf[i]; + + DBG_871X_SEL_NL(m, " desc[%03d]: %p, rx_buf[%03d]: 0x%08x\n", + i, entry, i, cpu_to_le32(*((dma_addr_t *)skb->cb))); + + for (j=0; jirq_th_lock, &irqL); + + return 0; +} + +int proc_get_tx_ring(struct seq_file *m, void *v) +{ + _irqL irqL; + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *) rtw_netdev_priv(dev); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + int i, j, k; + + _enter_critical(&pdvobjpriv->irq_th_lock, &irqL); + for (i = 0; i < PCI_MAX_TX_QUEUE_COUNT; i++) + { + struct rtw_tx_ring *tx_ring = &pxmitpriv->tx_ring[i]; + + DBG_871X_SEL_NL(m, "tx ring[%d] (%p)\n", i, tx_ring); + DBG_871X_SEL_NL(m, " dma: 0x%08x\n", (int) tx_ring->dma); + DBG_871X_SEL_NL(m, " idx: %d\n", tx_ring->idx); + DBG_871X_SEL_NL(m, " entries: %d\n", tx_ring->entries); +// DBG_871X_SEL_NL(m, " queue: %d\n", tx_ring->queue); + DBG_871X_SEL_NL(m, " qlen: %d\n", tx_ring->qlen); + + for (j=0; j < pxmitpriv->txringcount[i]; j++) + { + struct tx_desc *entry = &tx_ring->desc[j]; + + DBG_871X_SEL_NL(m, " desc[%03d]: %p\n", j, entry); + for (k=0; k < sizeof(*entry)/4; k++) + { + if ((k % 4) == 0) + DBG_871X_SEL_NL(m, " 0x%03x", k); + + DBG_871X_SEL_NL(m, " 0x%08x ", ((int *) entry)[k]); + + if ((k % 4) == 3) + DBG_871X_SEL_NL(m, "\n"); + } + } + } + _exit_critical(&pdvobjpriv->irq_th_lock, &irqL); + + return 0; +} +#endif + +#ifdef CONFIG_GPIO_WAKEUP +int proc_get_wowlan_gpio_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 val = pwrpriv->is_high_active; + + DBG_871X_SEL_NL(m, "wakeup_gpio_idx: %d\n", WAKEUP_GPIO_IDX); + DBG_871X_SEL_NL(m, "high_active: %d\n", val); + + return 0; +} + +ssize_t proc_set_wowlan_gpio_info(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 pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + char tmp[32] = {0}; + int num = 0; + u32 is_high_active = 0; + u8 val8 = 0; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + num = sscanf(tmp, "%u", &is_high_active); + + is_high_active = is_high_active == 0 ? 0 : 1; + + pwrpriv->is_high_active = is_high_active; + + rtw_ps_deny(padapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(padapter); + val8 = (pwrpriv->is_high_active == 0) ? 1 : 0; + rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); + rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); + + DBG_871X("set %s %d\n", "gpio_high_active", + pwrpriv->is_high_active); + DBG_871X("%s: set GPIO_%d %d as default.\n", + __func__, WAKEUP_GPIO_IDX, val8); + } + + return count; +} +#endif /* CONFIG_GPIO_WAKEUP */ + +#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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) + sscanf(tmp, "%d ", &new_bcn_max); + + return count; +} + +#ifdef CONFIG_POWER_SAVING +int proc_get_ps_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 ips_mode = pwrpriv->ips_mode; + u8 lps_mode = pwrpriv->power_mgnt; + char *str = ""; + + DBG_871X_SEL_NL(m, "======Power Saving Info:======\n"); + DBG_871X_SEL_NL(m, "*IPS:\n"); + + if (ips_mode == IPS_NORMAL) { +#ifdef CONFIG_FWLPS_IN_IPS + str = "FW_LPS_IN_IPS"; +#else + str = "Card Disable"; +#endif + } else if (ips_mode == IPS_NONE) { + str = "NO IPS"; + } else if (ips_mode == IPS_LEVEL_2) { + str = "IPS_LEVEL_2"; + } else { + str = "invalid ips_mode"; + } + + DBG_871X_SEL_NL(m, " IPS mode: %s\n", str); + DBG_871X_SEL_NL(m, " IPS enter count:%d, IPS leave count:%d\n", + pwrpriv->ips_enter_cnts, pwrpriv->ips_leave_cnts); + DBG_871X_SEL_NL(m, "------------------------------\n"); + DBG_871X_SEL_NL(m, "*LPS:\n"); + + if (lps_mode == PS_MODE_ACTIVE) { + str = "NO LPS"; + } else if (lps_mode == PS_MODE_MIN) { + str = "MIN"; + } else if (lps_mode == PS_MODE_MAX) { + str = "MAX"; + } else if (lps_mode == PS_MODE_DTIM) { + str = "DTIM"; + } else { + sprintf(str, "%d", lps_mode); + } + + DBG_871X_SEL_NL(m, " LPS mode: %s\n", str); + + if (pwrpriv->dtim != 0) + DBG_871X_SEL_NL(m, " DTIM: %d\n", pwrpriv->dtim); + DBG_871X_SEL_NL(m, " LPS enter count:%d, LPS leave count:%d\n", + pwrpriv->lps_enter_cnts, pwrpriv->lps_leave_cnts); + DBG_871X_SEL_NL(m, "=============================\n"); + return 0; +} +#endif //CONFIG_POWER_SAVING + +#ifdef CONFIG_TDLS +static int proc_tdls_display_tdls_function_info(struct seq_file *m) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 SpaceBtwnItemAndValue = TDLS_DBG_INFO_SPACE_BTWN_ITEM_AND_VALUE; + u8 SpaceBtwnItemAndValueTmp = 0; + BOOLEAN FirstMatchFound = _FALSE; + int j= 0; + + DBG_871X_SEL_NL(m, "============[TDLS Function Info]============\n"); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Prohibited", (ptdlsinfo->ap_prohibited == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Channel Switch Prohibited", (ptdlsinfo->ch_switch_prohibited == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Link Established", (ptdlsinfo->link_established == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %d/%d\n", SpaceBtwnItemAndValue, "TDLS STA Num (Linked/Allowed)", ptdlsinfo->sta_cnt, MAX_ALLOWED_TDLS_STA_NUM); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Allowed STA Num Reached", (ptdlsinfo->sta_maximum == _TRUE) ? "_TRUE" : "_FALSE"); + +#ifdef CONFIG_TDLS_CH_SW + DBG_871X_SEL_NL(m, "%-*s =", SpaceBtwnItemAndValue, "TDLS CH SW State"); + if (ptdlsinfo->chsw_info.ch_sw_state == TDLS_STATE_NONE) + { + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_STATE_NONE"); + } + else + { + for (j = 0; j < 32; j++) + { + if (ptdlsinfo->chsw_info.ch_sw_state & BIT(j)) + { + if (FirstMatchFound == _FALSE) + { + SpaceBtwnItemAndValueTmp = 1; + FirstMatchFound = _TRUE; + } + else + { + SpaceBtwnItemAndValueTmp = SpaceBtwnItemAndValue + 3; + } + switch (BIT(j)) + { + case TDLS_INITIATOR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_INITIATOR_STATE"); + break; + case TDLS_RESPONDER_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_RESPONDER_STATE"); + break; + case TDLS_LINKED_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_LINKED_STATE"); + break; + case TDLS_WAIT_PTR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_WAIT_PTR_STATE"); + break; + case TDLS_ALIVE_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_ALIVE_STATE"); + break; + case TDLS_CH_SWITCH_ON_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_CH_SWITCH_ON_STATE"); + break; + case TDLS_PEER_AT_OFF_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_PEER_AT_OFF_STATE"); + break; + case TDLS_CH_SW_INITIATOR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_CH_SW_INITIATOR_STATE"); + break; + case TDLS_WAIT_CH_RSP_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValue, " ", "TDLS_WAIT_CH_RSP_STATE"); + break; + default: + DBG_871X_SEL_NL(m, "%-*sBIT(%d)\n", SpaceBtwnItemAndValueTmp, " ", j); + break; + } + } + } + } + + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS CH SW On", (ATOMIC_READ(&ptdlsinfo->chsw_info.chsw_on) == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %d\n", SpaceBtwnItemAndValue, "TDLS CH SW Off-Channel Num", ptdlsinfo->chsw_info.off_ch_num); + DBG_871X_SEL_NL(m, "%-*s = %d\n", SpaceBtwnItemAndValue, "TDLS CH SW Channel Offset", ptdlsinfo->chsw_info.ch_offset); + DBG_871X_SEL_NL(m, "%-*s = %d\n", SpaceBtwnItemAndValue, "TDLS CH SW Current Time", ptdlsinfo->chsw_info.cur_time); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS CH SW Delay Switch Back", (ptdlsinfo->chsw_info.delay_switch_back == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %d\n", SpaceBtwnItemAndValue, "TDLS CH SW Dump Back", ptdlsinfo->chsw_info.dump_stack); +#endif + + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Device Discovered", (ptdlsinfo->dev_discovered == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Enable", (ptdlsinfo->tdls_enable == _TRUE) ? "_TRUE" : "_FALSE"); + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "TDLS Driver Setup", (ptdlsinfo->driver_setup == _TRUE) ? "_TRUE" : "_FALSE"); + + return 0; +} + +static int proc_tdls_display_network_info(struct seq_file *m) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + int i = 0; + u8 SpaceBtwnItemAndValue = TDLS_DBG_INFO_SPACE_BTWN_ITEM_AND_VALUE; + + /* Display the linked AP/GO info */ + DBG_871X_SEL_NL(m, "============[Associated AP/GO Info]============\n"); + + if ((pmlmepriv->fw_state & WIFI_STATION_STATE) && (pmlmepriv->fw_state & _FW_LINKED)) + { + DBG_871X_SEL_NL(m, "%-*s = %s\n", SpaceBtwnItemAndValue, "BSSID", cur_network->network.Ssid.Ssid); + DBG_871X_SEL_NL(m, "%-*s = "MAC_FMT"\n", SpaceBtwnItemAndValue, "Mac Address", MAC_ARG(cur_network->network.MacAddress)); + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Wireless Mode"); + for (i = 0; i < 8; i++) + { + if (pmlmeext->cur_wireless_mode & BIT(i)) + { + switch (BIT(i)) + { + case WIRELESS_11B: + DBG_871X_SEL_NL(m, "%4s", "11B "); + break; + case WIRELESS_11G: + DBG_871X_SEL_NL(m, "%4s", "11G "); + break; + case WIRELESS_11A: + DBG_871X_SEL_NL(m, "%4s", "11A "); + break; + case WIRELESS_11_24N: + DBG_871X_SEL_NL(m, "%7s", "11_24N "); + break; + case WIRELESS_11_5N: + DBG_871X_SEL_NL(m, "%6s", "11_5N "); + break; + case WIRELESS_AUTO: + DBG_871X_SEL_NL(m, "%5s", "AUTO "); + break; + case WIRELESS_11AC: + DBG_871X_SEL_NL(m, "%5s", "11AC "); + break; + } + } + } + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Privacy"); + switch (padapter->securitypriv.dot11PrivacyAlgrthm) + { + case _NO_PRIVACY_: + DBG_871X_SEL_NL(m, "%s\n", "NO PRIVACY"); + break; + case _WEP40_: + DBG_871X_SEL_NL(m, "%s\n", "WEP 40"); + break; + case _TKIP_: + DBG_871X_SEL_NL(m, "%s\n", "TKIP"); + break; + case _TKIP_WTMIC_: + DBG_871X_SEL_NL(m, "%s\n", "TKIP WTMIC"); + break; + case _AES_: + DBG_871X_SEL_NL(m, "%s\n", "AES"); + break; + case _WEP104_: + DBG_871X_SEL_NL(m, "%s\n", "WEP 104"); + break; + case _WEP_WPA_MIXED_: + DBG_871X_SEL_NL(m, "%s\n", "WEP/WPA Mixed"); + break; + case _SMS4_: + DBG_871X_SEL_NL(m, "%s\n", "SMS4"); + break; +#ifdef CONFIG_IEEE80211W + case _BIP_: + DBG_871X_SEL_NL(m, "%s\n", "BIP"); + break; +#endif //CONFIG_IEEE80211W + } + + DBG_871X_SEL_NL(m, "%-*s = %d\n", SpaceBtwnItemAndValue, "Channel", pmlmeext->cur_channel); + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Channel Offset"); + switch (pmlmeext->cur_ch_offset) + { + case HAL_PRIME_CHNL_OFFSET_DONT_CARE: + DBG_871X_SEL_NL(m, "%s\n", "N/A"); + break; + case HAL_PRIME_CHNL_OFFSET_LOWER: + DBG_871X_SEL_NL(m, "%s\n", "Lower"); + break; + case HAL_PRIME_CHNL_OFFSET_UPPER: + DBG_871X_SEL_NL(m, "%s\n", "Upper"); + break; + } + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Bandwidth Mode"); + switch (pmlmeext->cur_bwmode) + { + case CHANNEL_WIDTH_20: + DBG_871X_SEL_NL(m, "%s\n", "20MHz"); + break; + case CHANNEL_WIDTH_40: + DBG_871X_SEL_NL(m, "%s\n", "40MHz"); + break; + case CHANNEL_WIDTH_80: + DBG_871X_SEL_NL(m, "%s\n", "80MHz"); + break; + case CHANNEL_WIDTH_160: + DBG_871X_SEL_NL(m, "%s\n", "160MHz"); + break; + case CHANNEL_WIDTH_80_80: + DBG_871X_SEL_NL(m, "%s\n", "80MHz + 80MHz"); + break; + } + } + else + { + DBG_871X_SEL_NL(m, "No association with AP/GO exists!\n"); + } + + return 0; +} + +static int proc_tdls_display_tdls_sta_info(struct seq_file *m) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapter->stapriv; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_info *psta; + int i = 0, j = 0; + _irqL irqL; + _list *plist, *phead; + u8 SpaceBtwnItemAndValue = TDLS_DBG_INFO_SPACE_BTWN_ITEM_AND_VALUE; + u8 SpaceBtwnItemAndValueTmp = 0; + u8 NumOfTdlsStaToShow = 0; + BOOLEAN FirstMatchFound = _FALSE; + + /* Search for TDLS sta info to display */ + _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 (psta->tdls_sta_state != TDLS_STATE_NONE) + { + /* We got one TDLS sta info to show */ + DBG_871X_SEL_NL(m, "============[TDLS Peer STA Info: STA %d]============\n", ++NumOfTdlsStaToShow); + DBG_871X_SEL_NL(m, "%-*s = "MAC_FMT"\n", SpaceBtwnItemAndValue, "Mac Address", MAC_ARG(psta->hwaddr)); + DBG_871X_SEL_NL(m, "%-*s =", SpaceBtwnItemAndValue, "TDLS STA State"); + SpaceBtwnItemAndValueTmp = 0; + FirstMatchFound = _FALSE; + for (j = 0; j < 32; j++) + { + if (psta->tdls_sta_state & BIT(j)) + { + if (FirstMatchFound == _FALSE) + { + SpaceBtwnItemAndValueTmp = 1; + FirstMatchFound = _TRUE; + } + else + { + SpaceBtwnItemAndValueTmp = SpaceBtwnItemAndValue + 3; + } + switch (BIT(j)) + { + case TDLS_INITIATOR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_INITIATOR_STATE"); + break; + case TDLS_RESPONDER_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_RESPONDER_STATE"); + break; + case TDLS_LINKED_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_LINKED_STATE"); + break; + case TDLS_WAIT_PTR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_WAIT_PTR_STATE"); + break; + case TDLS_ALIVE_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_ALIVE_STATE"); + break; + case TDLS_CH_SWITCH_ON_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_CH_SWITCH_ON_STATE"); + break; + case TDLS_PEER_AT_OFF_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_PEER_AT_OFF_STATE"); + break; + case TDLS_CH_SW_INITIATOR_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValueTmp, " ", "TDLS_CH_SW_INITIATOR_STATE"); + break; + case TDLS_WAIT_CH_RSP_STATE: + DBG_871X_SEL_NL(m, "%-*s%s\n", SpaceBtwnItemAndValue, " ", "TDLS_WAIT_CH_RSP_STATE"); + break; + default: + DBG_871X_SEL_NL(m, "%-*sBIT(%d)\n", SpaceBtwnItemAndValueTmp, " ", j); + break; + } + } + } + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Wireless Mode"); + for (j = 0; j < 8; j++) + { + if (psta->wireless_mode & BIT(j)) + { + switch (BIT(j)) + { + case WIRELESS_11B: + DBG_871X_SEL_NL(m, "%4s", "11B "); + break; + case WIRELESS_11G: + DBG_871X_SEL_NL(m, "%4s", "11G "); + break; + case WIRELESS_11A: + DBG_871X_SEL_NL(m, "%4s", "11A "); + break; + case WIRELESS_11_24N: + DBG_871X_SEL_NL(m, "%7s", "11_24N "); + break; + case WIRELESS_11_5N: + DBG_871X_SEL_NL(m, "%6s", "11_5N "); + break; + case WIRELESS_AUTO: + DBG_871X_SEL_NL(m, "%5s", "AUTO "); + break; + case WIRELESS_11AC: + DBG_871X_SEL_NL(m, "%5s", "11AC "); + break; + } + } + } + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Bandwidth Mode"); + switch (psta->bw_mode) + { + case CHANNEL_WIDTH_20: + DBG_871X_SEL_NL(m, "%s\n", "20MHz"); + break; + case CHANNEL_WIDTH_40: + DBG_871X_SEL_NL(m, "%s\n", "40MHz"); + break; + case CHANNEL_WIDTH_80: + DBG_871X_SEL_NL(m, "%s\n", "80MHz"); + break; + case CHANNEL_WIDTH_160: + DBG_871X_SEL_NL(m, "%s\n", "160MHz"); + break; + case CHANNEL_WIDTH_80_80: + DBG_871X_SEL_NL(m, "%s\n", "80MHz + 80MHz"); + break; + } + + DBG_871X_SEL_NL(m, "%-*s = ", SpaceBtwnItemAndValue, "Privacy"); + switch (psta->dot118021XPrivacy) + { + case _NO_PRIVACY_: + DBG_871X_SEL_NL(m, "%s\n", "NO PRIVACY"); + break; + case _WEP40_: + DBG_871X_SEL_NL(m, "%s\n", "WEP 40"); + break; + case _TKIP_: + DBG_871X_SEL_NL(m, "%s\n", "TKIP"); + break; + case _TKIP_WTMIC_: + DBG_871X_SEL_NL(m, "%s\n", "TKIP WTMIC"); + break; + case _AES_: + DBG_871X_SEL_NL(m, "%s\n", "AES"); + break; + case _WEP104_: + DBG_871X_SEL_NL(m, "%s\n", "WEP 104"); + break; + case _WEP_WPA_MIXED_: + DBG_871X_SEL_NL(m, "%s\n", "WEP/WPA Mixed"); + break; + case _SMS4_: + DBG_871X_SEL_NL(m, "%s\n", "SMS4"); + break; +#ifdef CONFIG_IEEE80211W + case _BIP_: + DBG_871X_SEL_NL(m, "%s\n", "BIP"); + break; +#endif //CONFIG_IEEE80211W + } + + DBG_871X_SEL_NL(m, "%-*s = %d sec/%d sec\n", SpaceBtwnItemAndValue, "TPK Lifetime (Current/Expire)", psta->TPK_count, psta->TDLS_PeerKey_Lifetime); + DBG_871X_SEL_NL(m, "%-*s = %llu\n", SpaceBtwnItemAndValue, "Tx Packets Over Direct Link", psta->sta_stats.tx_pkts); + DBG_871X_SEL_NL(m, "%-*s = %llu\n", SpaceBtwnItemAndValue, "Rx Packets Over Direct Link", psta->sta_stats.rx_data_pkts); + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + if (NumOfTdlsStaToShow == 0) + { + DBG_871X_SEL_NL(m, "============[TDLS Peer STA Info]============\n"); + DBG_871X_SEL_NL(m, "No TDLS direct link exists!\n"); + } + + return 0; +} + +int proc_get_tdls_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct sta_priv *pstapriv = &padapter->stapriv; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_info *psta; + int i = 0, j = 0; + _irqL irqL; + _list *plist, *phead; + u8 SpaceBtwnItemAndValue = 41; + u8 SpaceBtwnItemAndValueTmp = 0; + u8 NumOfTdlsStaToShow = 0; + BOOLEAN FirstMatchFound = _FALSE; + + if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) { + DBG_871X_SEL_NL(m, "No tdls info can be shown since hal doesn't support tdls\n"); + return 0; + } + + proc_tdls_display_tdls_function_info(m); + proc_tdls_display_network_info(m); + proc_tdls_display_tdls_sta_info(m); + + return 0; +} +#endif + +int proc_get_monitor(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if (WIFI_MONITOR_STATE == get_fwstate(pmlmepriv)) { + DBG_871X_SEL_NL(m, "Monitor mode : Enable\n"); + + DBG_871X_SEL_NL(m, "ch=%d, ch_offset=%d, bw=%d\n", + rtw_get_oper_ch(padapter), rtw_get_oper_choffset(padapter), rtw_get_oper_bw(padapter)); + } else { + DBG_871X_SEL_NL(m, "Monitor mode : Disable\n"); + } + + return 0; +} + +ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + char tmp[32]; + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 target_chan, target_offset, target_bw; + + if (count < 3) { + DBG_871X("argument size is less than 3\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhu %hhu %hhu", &target_chan, &target_offset, &target_bw); + + if (num != 3) { + DBG_871X("invalid write_reg parameter!\n"); + return count; + } + + padapter->mlmeextpriv.cur_channel = target_chan; + set_channel_bwmode(padapter, target_chan, target_offset, target_bw); + } + + return count; +} + +#include +int proc_get_efuse_map(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; + int i, j; + u8 ips_mode = IPS_NUM; + int mapLen = EFUSE_MAP_SIZE; + + ips_mode = pwrctrlpriv->ips_mode; + rtw_pm_set_ips(padapter, IPS_NONE); + if (rtw_efuse_map_read(padapter, EFUSE_WIFI, mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) + DBG_871X_SEL_NL(m, "WARN - Read Realmap Failed\n"); + + DBG_871X_SEL_NL(m, "\n"); + for (i = 0; i < EFUSE_MAP_SIZE; i += 16) { + DBG_871X_SEL_NL(m, "0x%02x\t", i); + for (j = 0; j < 8; j++) + DBG_871X_SEL_NL(m, "%02X ", pEfuseHal->fakeEfuseInitMap[i+j]); + + DBG_871X_SEL_NL(m, "\t"); + + for (; j < 16; j++) + DBG_871X_SEL_NL(m, "%02X ", pEfuseHal->fakeEfuseInitMap[i+j]); + + DBG_871X_SEL_NL(m, "\n"); + + } + rtw_pm_set_ips(padapter, ips_mode); + return 0; +} + +ssize_t proc_set_efuse_map(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ +#if 0 + char tmp[256] = {0}; + u32 addr, cnts; + u8 efuse_data; + + int jj, kk; + + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + u8 ips_mode = IPS_NUM; + + if (count < 3) { + DBG_871X("argument size is less than 3\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x %d %x", &addr, &cnts, &efuse_data); + + if (num != 3) { + DBG_871X("invalid write_reg parameter!\n"); + return count; + } + } + ips_mode = pwrctrlpriv->ips_mode; + rtw_pm_set_ips(padapter, IPS_NONE); + if (rtw_efuse_map_write(padapter, addr, cnts, &efuse_data) == _FAIL) + DBG_871X("WARN - rtw_efuse_map_write error!!\n"); + rtw_pm_set_ips(padapter, ips_mode); +#endif + return count; +} + +#ifdef CONFIG_IEEE80211W +ssize_t proc_set_tx_sa_query(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 mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + struct sta_info *psta; + _list *plist, *phead; + _irqL irqL; + char tmp[16]; + u8 mac_addr[NUM_STA][ETH_ALEN]; + u32 key_type; + u8 index; + + if (count > 2) { + DBG_871X("argument size is more than 2\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x", &key_type); + + if (num != 1) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + DBG_871X("0: set sa query request , key_type=%d\n", key_type); + } + + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && padapter->securitypriv.binstallBIPkey == _TRUE) { + DBG_871X("STA:"MAC_FMT"\n", MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); + /* TX unicast sa_query to AP */ + issue_action_SA_Query(padapter, get_my_bssid(&(pmlmeinfo->network)), 0, 0, (u8)key_type); + } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) { + /* TX unicast sa_query to every client STA */ + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for (index = 0; index < NUM_STA; index++) { + psta = NULL; + + phead = &(pstapriv->sta_hash[index]); + 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); + _rtw_memcpy(&mac_addr[psta->mac_id][0], psta->hwaddr, ETH_ALEN); + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for (index = 0; index < macid_ctl->num && index < NUM_STA; index++) { + if (rtw_macid_is_used(macid_ctl, index) && !rtw_macid_is_bmc(macid_ctl, index)) { + if (!_rtw_memcmp(get_my_bssid(&(pmlmeinfo->network)), &mac_addr[index][0], ETH_ALEN) + && !IS_MCAST(&mac_addr[index][0])) { + issue_action_SA_Query(padapter, &mac_addr[index][0], 0, 0, (u8)key_type); + DBG_871X("STA[%u]:"MAC_FMT"\n", index , MAC_ARG(&mac_addr[index][0])); + } + } + } + } + + return count; +} + +int proc_get_tx_sa_query(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, "%s\n", __func__); + return 0; +} + +ssize_t proc_set_tx_deauth(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 mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + struct sta_info *psta; + _list *plist, *phead; + _irqL irqL; + char tmp[16]; + u8 mac_addr[NUM_STA][ETH_ALEN]; + u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u32 key_type; + u8 index; + + + if (count > 2) { + DBG_871X("argument size is more than 2\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x", &key_type); + + if (num != 1) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + DBG_871X("key_type=%d\n", key_type); + } + if (key_type < 0 || key_type > 4) + return count; + + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if (key_type == 3) /* key_type 3 only for AP mode */ + return count; + /* TX unicast deauth to AP */ + issue_deauth_11w(padapter, get_my_bssid(&(pmlmeinfo->network)), 0, (u8)key_type); + } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { + + if (key_type == 3) + issue_deauth_11w(padapter, bc_addr, 0, IEEE80211W_RIGHT_KEY); + + /* TX unicast deauth to every client STA */ + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for (index = 0; index < NUM_STA; index++) { + psta = NULL; + + phead = &(pstapriv->sta_hash[index]); + 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); + _rtw_memcpy(&mac_addr[psta->mac_id][0], psta->hwaddr, ETH_ALEN); + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for (index = 0; index < macid_ctl->num && index < NUM_STA; index++) { + if (rtw_macid_is_used(macid_ctl, index) && !rtw_macid_is_bmc(macid_ctl, index)) { + if (!_rtw_memcmp(get_my_bssid(&(pmlmeinfo->network)), &mac_addr[index][0], ETH_ALEN)) { + if (key_type != 3) + issue_deauth_11w(padapter, &mac_addr[index][0], 0, (u8)key_type); + + psta = rtw_get_stainfo(pstapriv, &mac_addr[index][0]); + if (psta && key_type != IEEE80211W_WRONG_KEY && key_type != IEEE80211W_NO_KEY) { + u8 updated = _FALSE; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); + } + + DBG_871X("STA[%u]:"MAC_FMT"\n", index , MAC_ARG(&mac_addr[index][0])); + } + } + } + } + + return count; +} + +int proc_get_tx_deauth(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, "%s\n", __func__); + return 0; +} + +ssize_t proc_set_tx_auth(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 mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + struct sta_info *psta; + _list *plist, *phead; + _irqL irqL; + char tmp[16]; + u8 mac_addr[NUM_STA][ETH_ALEN]; + u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u32 tx_auth; + u8 index; + + + if (count > 2) { + DBG_871X("argument size is more than 2\n"); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { + + int num = sscanf(tmp, "%x", &tx_auth); + + if (num != 1) { + DBG_871X("invalid read_reg parameter!\n"); + return count; + } + DBG_871X("1: setnd auth, 2: send assoc request. tx_auth=%d\n", tx_auth); + } + + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { + if (tx_auth == 1) { + /* TX unicast auth to AP */ + issue_auth(padapter, NULL, 0); + } else if (tx_auth == 2) { + /* TX unicast auth to AP */ + issue_assocreq(padapter); + } + } + + return count; +} + +int proc_get_tx_auth(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X_SEL_NL(m, "%s\n", __func__); + return 0; +} +#endif /* CONFIG_IEEE80211W */ + +#endif /* CONFIG_PROC_DEBUG */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_eeprom.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_eeprom.c new file mode 100644 index 00000000..e83c090a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_eeprom.c @@ -0,0 +1,423 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_EEPROM_C_ + +#include +#include +#include + +void up_clk(_adapter* padapter, u16 *x) +{ +_func_enter_; + *x = *x | _EESK; + rtw_write8(padapter, EE_9346CR, (u8)*x); + rtw_udelay_os(CLOCK_RATE); + +_func_exit_; + +} + +void down_clk(_adapter * padapter, u16 *x ) +{ +_func_enter_; + *x = *x & ~_EESK; + rtw_write8(padapter, EE_9346CR, (u8)*x); + rtw_udelay_os(CLOCK_RATE); +_func_exit_; +} + +void shift_out_bits(_adapter * padapter, u16 data, u16 count) +{ + u16 x,mask; +_func_enter_; + + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + mask = 0x01 << (count - 1); + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDO | _EEDI); + + do + { + x &= ~_EEDI; + if(data & mask) + x |= _EEDI; + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + rtw_write8(padapter, EE_9346CR, (u8)x); + rtw_udelay_os(CLOCK_RATE); + up_clk(padapter, &x); + down_clk(padapter, &x); + mask = mask >> 1; + } while(mask); + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x &= ~_EEDI; + rtw_write8(padapter, EE_9346CR, (u8)x); +out: +_func_exit_; +} + +u16 shift_in_bits (_adapter * padapter) +{ + u16 x,d=0,i; +_func_enter_; + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + + x &= ~( _EEDO | _EEDI); + d = 0; + + for(i=0; i<16; i++) + { + d = d << 1; + up_clk(padapter, &x); + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDI); + if(x & _EEDO) + d |= 1; + + down_clk(padapter, &x); + } +out: +_func_exit_; + + return d; +} + +void standby(_adapter * padapter ) +{ + u8 x; +_func_enter_; + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EECS | _EESK); + rtw_write8(padapter, EE_9346CR,x); + + rtw_udelay_os(CLOCK_RATE); + x |= _EECS; + rtw_write8(padapter, EE_9346CR, x); + rtw_udelay_os(CLOCK_RATE); +_func_exit_; +} + +u16 wait_eeprom_cmd_done(_adapter* padapter) +{ + u8 x; + u16 i,res=_FALSE; +_func_enter_; + standby(padapter ); + for (i=0; i<200; i++) + { + x = rtw_read8(padapter, EE_9346CR); + if (x & _EEDO){ + res=_TRUE; + goto exit; + } + rtw_udelay_os(CLOCK_RATE); + } +exit: +_func_exit_; + return res; +} + +void eeprom_clean(_adapter * padapter) +{ + u16 x; +_func_enter_; + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x = rtw_read8(padapter, EE_9346CR); + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + x &= ~(_EECS | _EEDI); + rtw_write8(padapter, EE_9346CR, (u8)x); + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + up_clk(padapter, &x); + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + down_clk(padapter, &x); +out: +_func_exit_; +} + +void eeprom_write16(_adapter * padapter, u16 reg, u16 data) +{ + u8 x; +#ifdef CONFIG_RTL8712 + u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new; + tmp8_ori=rtw_read8(padapter, 0x102502f1); + tmp8_new=tmp8_ori & 0xf7; + if(tmp8_ori != tmp8_new){ + rtw_write8(padapter, 0x102502f1, tmp8_new); + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n")); + } + tmp8_clk_ori=rtw_read8(padapter,0x10250003); + tmp8_clk_new=tmp8_clk_ori|0x20; + if(tmp8_clk_new!=tmp8_clk_ori){ + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n")); + rtw_write8(padapter, 0x10250003, tmp8_clk_new); + } +#endif +_func_enter_; + + x = rtw_read8(padapter, EE_9346CR); + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, x); + + shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); + + if(padapter->EepromAddressSize==8) //CF+ and SDIO + shift_out_bits(padapter, 0, 6); + else //USB + shift_out_bits(padapter, 0, 4); + + standby( padapter); + +// Commented out by rcnjko, 2004.0 +// // Erase this particular word. Write the erase opcode and register +// // number in that order. The opcode is 3bits in length; reg is 6 bits long. +// shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3); +// shift_out_bits(Adapter, reg, Adapter->EepromAddressSize); +// +// if (wait_eeprom_cmd_done(Adapter ) == FALSE) +// { +// return; +// } + + + standby(padapter ); + + // write the new word to the EEPROM + + // send the write opcode the EEPORM + shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); + + // select which word in the EEPROM that we are writing to. + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + // write the data to the selected EEPROM word. + shift_out_bits(padapter, data, 16); + + if (wait_eeprom_cmd_done(padapter ) == _FALSE) + { + + goto exit; + } + + standby(padapter ); + + shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); + shift_out_bits(padapter, reg, 4); + + eeprom_clean(padapter ); +exit: +#ifdef CONFIG_RTL8712 + if(tmp8_clk_new!=tmp8_clk_ori) + rtw_write8(padapter, 0x10250003, tmp8_clk_ori); + if(tmp8_new!=tmp8_ori) + rtw_write8(padapter, 0x102502f1, tmp8_ori); + +#endif +_func_exit_; + return; +} + +u16 eeprom_read16(_adapter * padapter, u16 reg) //ReadEEprom +{ + + u16 x; + u16 data=0; +#ifdef CONFIG_RTL8712 + u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new; + tmp8_ori= rtw_read8(padapter, 0x102502f1); + tmp8_new = tmp8_ori & 0xf7; + if(tmp8_ori != tmp8_new){ + rtw_write8(padapter, 0x102502f1, tmp8_new); + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n")); + } + tmp8_clk_ori=rtw_read8(padapter,0x10250003); + tmp8_clk_new=tmp8_clk_ori|0x20; + if(tmp8_clk_new!=tmp8_clk_ori){ + RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n")); + rtw_write8(padapter, 0x10250003, tmp8_clk_new); + } +#endif +_func_enter_; + + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + // select EEPROM, reset bits, set _EECS + x = rtw_read8(padapter, EE_9346CR); + + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, (unsigned char)x); + + // write the read opcode and register number in that order + // The opcode is 3bits in length, reg is 6 bits long + shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + // Now read the data (16 bits) in from the selected EEPROM word + data = shift_in_bits(padapter); + + eeprom_clean(padapter); +out: +#ifdef CONFIG_RTL8712 + if(tmp8_clk_new!=tmp8_clk_ori) + rtw_write8(padapter, 0x10250003, tmp8_clk_ori); + if(tmp8_new!=tmp8_ori) + rtw_write8(padapter, 0x102502f1, tmp8_ori); + +#endif +_func_exit_; + return data; + + +} + + + + +//From even offset +void eeprom_read_sz(_adapter * padapter, u16 reg, u8* data, u32 sz) +{ + + u16 x, data16; + u32 i; +_func_enter_; + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + // select EEPROM, reset bits, set _EECS + x = rtw_read8(padapter, EE_9346CR); + + if (rtw_is_surprise_removed(padapter)) { + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_err_, ("padapter->bSurpriseRemoved==_TRUE")); + goto out; + } + + x &= ~(_EEDI | _EEDO | _EESK | _EEM0); + x |= _EEM1 | _EECS; + rtw_write8(padapter, EE_9346CR, (unsigned char)x); + + // write the read opcode and register number in that order + // The opcode is 3bits in length, reg is 6 bits long + shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); + shift_out_bits(padapter, reg, padapter->EepromAddressSize); + + + for(i=0; i>8; + } + + eeprom_clean(padapter); +out: +_func_exit_; + + + +} + + +//addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg) +u8 eeprom_read(_adapter * padapter, u32 addr_off, u8 sz, u8* rbuf) +{ + u8 quotient, remainder, addr_2align_odd; + u16 reg, stmp , i=0, idx = 0; +_func_enter_; + reg = (u16)(addr_off >> 1); + addr_2align_odd = (u8)(addr_off & 0x1); + + if(addr_2align_odd) //read that start at high part: e.g 1,3,5,7,9,... + { + stmp = eeprom_read16(padapter, reg); + rbuf[idx++] = (u8) ((stmp>>8)&0xff); //return hogh-part of the short + reg++; sz--; + } + + quotient = sz >> 1; + remainder = sz & 0x1; + + for( i=0 ; i < quotient; i++) + { + stmp = eeprom_read16(padapter, reg+i); + rbuf[idx++] = (u8) (stmp&0xff); + rbuf[idx++] = (u8) ((stmp>>8)&0xff); + } + + reg = reg+i; + if(remainder){ //end of read at lower part of short : 0,2,4,6,... + stmp = eeprom_read16(padapter, reg); + rbuf[idx] = (u8)(stmp & 0xff); + } +_func_exit_; + return _TRUE; +} + + + +VOID read_eeprom_content(_adapter * padapter) +{ + +_func_enter_; + + +_func_exit_; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c new file mode 100644 index 00000000..893be78f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c @@ -0,0 +1,2834 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _IEEE80211_C + +#ifdef CONFIG_PLATFORM_INTEL_BYT +#include +#endif +#include + + +u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; +u16 RTW_WPA_VERSION = 1; +u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 }; +u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; +u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; +u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; +u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; +u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; +u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 }; +u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; +u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; + +u16 RSN_VERSION_BSD = 1; +u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; +u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; +u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; +u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; +u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; +u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 }; +u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; +u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; +//----------------------------------------------------------- +// for adhoc-master to generate ie and provide supported-rate to fw +//----------------------------------------------------------- + +static u8 WIFI_CCKRATES[] = +{(IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), + (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK)}; + +static u8 WIFI_OFDMRATES[] = +{(IEEE80211_OFDM_RATE_6MB), + (IEEE80211_OFDM_RATE_9MB), + (IEEE80211_OFDM_RATE_12MB), + (IEEE80211_OFDM_RATE_18MB), + (IEEE80211_OFDM_RATE_24MB), + IEEE80211_OFDM_RATE_36MB, + IEEE80211_OFDM_RATE_48MB, + IEEE80211_OFDM_RATE_54MB}; + +u8 mgn_rates_cck[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; +u8 mgn_rates_ofdm[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}; +u8 mgn_rates_mcs0_7[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}; +u8 mgn_rates_mcs8_15[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15}; +u8 mgn_rates_mcs16_23[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23}; +u8 mgn_rates_mcs24_31[8] = {MGN_MCS24, MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31}; +u8 mgn_rates_vht1ss[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4 + , MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9}; +u8 mgn_rates_vht2ss[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4 + , MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9}; +u8 mgn_rates_vht3ss[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4 + , MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9}; +u8 mgn_rates_vht4ss[10] = {MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4 + , MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9}; + +static const char * const _rate_section_str[] = { + "CCK", + "OFDM", + "HT_1SS", + "HT_2SS", + "HT_3SS", + "HT_4SS", + "VHT_1SS", + "VHT_2SS", + "VHT_3SS", + "VHT_4SS", + "RATE_SECTION_UNKNOWN", +}; + +const char *rate_section_str(u8 section) +{ + section = (section >= RATE_SECTION_NUM) ? RATE_SECTION_NUM : section; + return _rate_section_str[section]; +} + +struct rate_section_ent rates_by_sections[RATE_SECTION_NUM] = { + {RF_1TX, 4, mgn_rates_cck}, + {RF_1TX, 8, mgn_rates_ofdm}, + {RF_1TX, 8, mgn_rates_mcs0_7}, + {RF_2TX, 8, mgn_rates_mcs8_15}, + {RF_3TX, 8, mgn_rates_mcs16_23}, + {RF_4TX, 8, mgn_rates_mcs24_31}, + {RF_1TX, 10, mgn_rates_vht1ss}, + {RF_2TX, 10, mgn_rates_vht2ss}, + {RF_3TX, 10, mgn_rates_vht3ss}, + {RF_4TX, 10, mgn_rates_vht4ss}, +}; + +int rtw_get_bit_value_from_ieee_value(u8 val) +{ + unsigned char dot11_rate_table[]={2,4,11,22,12,18,24,36,48,72,96,108,0}; // last element must be zero!! + + int i=0; + while(dot11_rate_table[i] != 0) { + if (dot11_rate_table[i] == val) + return BIT(i); + i++; + } + return 0; +} + +uint rtw_is_cckrates_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + i++; + } + + return _FALSE; +} + +uint rtw_is_cckratesonly_included(u8 *rate) +{ + u32 i = 0; + + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + return _FALSE; + + i++; + } + + return _TRUE; + +} + +int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) +{ + if (channel > 14) + { + if ((rtw_is_cckrates_included(rate)) == _TRUE) + return WIRELESS_INVALID; + else + return WIRELESS_11A; + } + else // could be pure B, pure G, or B/G + { + if ((rtw_is_cckratesonly_included(rate)) == _TRUE) + return WIRELESS_11B; + else if((rtw_is_cckrates_included(rate)) == _TRUE) + return WIRELESS_11BG; + else + return WIRELESS_11G; + } + +} + +u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, + unsigned int *frlen) +{ + _rtw_memcpy((void *)pbuf, (void *)source, len); + *frlen = *frlen + len; + return (pbuf + len); +} + +// rtw_set_ie will update frame length +u8 *rtw_set_ie +( + u8 *pbuf, + sint index, + uint len, + u8 *source, + uint *frlen //frame length +) +{ + *pbuf = (u8)index; + + *(pbuf + 1) = (u8)len; + + if (len > 0) + _rtw_memcpy((void *)(pbuf + 2), (void *)source, len); + + *frlen = *frlen + (len + 2); + + return (pbuf + len + 2); +} + +inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, + u8 new_ch, u8 ch_switch_cnt) +{ + u8 ie_data[3]; + + ie_data[0] = ch_switch_mode; + ie_data[1] = new_ch; + ie_data[2] = ch_switch_cnt; + return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len); +} + +inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset) +{ + if (ch_offset == SCN) + return HAL_PRIME_CHNL_OFFSET_DONT_CARE; + else if(ch_offset == SCA) + return HAL_PRIME_CHNL_OFFSET_UPPER; + else if(ch_offset == SCB) + return HAL_PRIME_CHNL_OFFSET_LOWER; + + return HAL_PRIME_CHNL_OFFSET_DONT_CARE; +} + +inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset) +{ + if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) + return SCN; + else if(ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + return SCB; + else if(ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) + return SCA; + + return SCN; +} + +inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset) +{ + return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET, 1, &secondary_ch_offset, buf_len); +} + +inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, + u8 flags, u16 reason, u16 precedence) +{ + u8 ie_data[6]; + + ie_data[0] = ttl; + ie_data[1] = flags; + RTW_PUT_LE16((u8*)&ie_data[2], reason); + RTW_PUT_LE16((u8*)&ie_data[4], precedence); + + return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len); +} + +/*---------------------------------------------------------------------------- +index: the information element id index, limit is the limit for search +-----------------------------------------------------------------------------*/ +u8 *rtw_get_ie(u8 *pbuf, sint index, sint *len, sint limit) +{ + sint tmp,i; + u8 *p; +_func_enter_; + if (limit < 1){ + _func_exit_; + return NULL; + } + + p = pbuf; + i = 0; + *len = 0; + while(1) + { + if (*p == index) + { + *len = *(p + 1); + return (p); + } + else + { + tmp = *(p + 1); + p += (tmp + 2); + i += (tmp + 2); + } + if (i >= limit) + break; + } +_func_exit_; + return NULL; +} + +/** + * rtw_get_ie_ex - Search specific IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @eid: Element ID to match + * @oui: OUI to match + * @oui_len: OUI length + * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE + * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE + * + * Returns: The address of the specific IE found, or NULL + */ +u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen) +{ + uint cnt; + u8 *target_ie = NULL; + + + if(ielen) + *ielen = 0; + + if(!in_ie || in_len<=0) + return target_ie; + + cnt = 0; + + while(cnt 12) + break; + + i++; + } +_func_exit_; + return i; +} + +int rtw_generate_ie(struct registry_priv *pregistrypriv) +{ + u8 wireless_mode; + int sz = 0, rateLen; + WLAN_BSSID_EX* pdev_network = &pregistrypriv->dev_network; + u8* ie = pdev_network->IEs; + +_func_enter_; + + //timestamp will be inserted by hardware + sz += 8; + ie += sz; + + //beacon interval : 2bytes + *(u16*)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);//BCN_INTERVAL; + sz += 2; + ie += 2; + + //capability info + *(u16*)ie = 0; + + *(u16*)ie |= cpu_to_le16(cap_IBSS); + + if(pregistrypriv->preamble == PREAMBLE_SHORT) + *(u16*)ie |= cpu_to_le16(cap_ShortPremble); + + if (pdev_network->Privacy) + *(u16*)ie |= cpu_to_le16(cap_Privacy); + + sz += 2; + ie += 2; + + //SSID + ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz); + + //supported rates + if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) { + if(pdev_network->Configuration.DSConfig > 14) + wireless_mode = WIRELESS_11A_5N; + else + wireless_mode = WIRELESS_11BG_24N; + } else if (pregistrypriv->wireless_mode == WIRELESS_MODE_MAX) { /* WIRELESS_11ABGN | WIRELESS_11AC */ + if (pdev_network->Configuration.DSConfig > 14) + wireless_mode = WIRELESS_11_5AC; + else + wireless_mode = WIRELESS_11BG_24N; + } else + wireless_mode = pregistrypriv->wireless_mode; + + rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode) ; + + rateLen = rtw_get_rateset_len(pdev_network->SupportedRates); + + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz); + //ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); + } + else + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz); + } + + //DS parameter set + ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz); + + + //IBSS Parameter Set + + ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz); + + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); + } + +#ifdef CONFIG_80211N_HT + //HT Cap. + if(((pregistrypriv->wireless_mode&WIRELESS_11_5N)||(pregistrypriv->wireless_mode&WIRELESS_11_24N)) + && (pregistrypriv->ht_enable==_TRUE)) + { + //todo: + } +#endif //CONFIG_80211N_HT + + //pdev_network->IELength = sz; //update IELength + +_func_exit_; + + //return _SUCCESS; + + return sz; + +} + +unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) +{ + int len; + u16 val16; + unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; + u8 *pbuf = pie; + int limit_new = limit; + + while(1) + { + pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit_new); + + if (pbuf) { + + //check if oui matches... + if (_rtw_memcmp((pbuf + 2), wpa_oui_type, sizeof (wpa_oui_type)) == _FALSE) { + + goto check_next_ie; + } + + //check version... + _rtw_memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16)); + + val16 = le16_to_cpu(val16); + if (val16 != 0x0001) + goto check_next_ie; + + *wpa_ie_len = *(pbuf + 1); + + return pbuf; + + } + else { + + *wpa_ie_len = 0; + return NULL; + } + +check_next_ie: + + limit_new = limit - (pbuf - pie) - 2 - len; + + if (limit_new <= 0) + break; + + pbuf += (2 + len); + + } + + *wpa_ie_len = 0; + + return NULL; + +} + +unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit) +{ + + return rtw_get_ie(pie, _WPA2_IE_ID_,rsn_ie_len, limit); + +} + +int rtw_get_wpa_cipher_suite(u8 *s) +{ + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_NONE; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP40; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_TKIP; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_CCMP; + if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP104; + + return 0; +} + +int rtw_get_wpa2_cipher_suite(u8 *s) +{ + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_NONE; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP40; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_TKIP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_CCMP; + if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == _TRUE) + return WPA_CIPHER_WEP104; + + return 0; +} + + +int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) +{ + int i, ret=_SUCCESS; + int left, count; + u8 *pos; + u8 SUITE_1X[4] = {0x00, 0x50, 0xf2, 1}; + + if (wpa_ie_len <= 0) { + /* No WPA IE - fail silently */ + return _FAIL; + } + + + if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) || + (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != _TRUE) ) + { + return _FAIL; + } + + pos = wpa_ie; + + pos += 8; + left = wpa_ie_len - 8; + + + //group_cipher + if (left >= WPA_SELECTOR_LEN) { + + *group_cipher = rtw_get_wpa_cipher_suite(pos); + + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + + } + else if (left > 0) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); + + return _FAIL; + } + + + //pairwise_cipher + if (left >= 2) + { + //count = le16_to_cpu(*(u16*)pos); + count = RTW_GET_LE16(pos); + pos += 2; + left -= 2; + + if (count == 0 || left < count * WPA_SELECTOR_LEN) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " + "count %u left %u", __FUNCTION__, count, left)); + return _FAIL; + } + + for (i = 0; i < count; i++) + { + *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); + + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + } + + } + else if (left == 1) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); + return _FAIL; + } + + if (is_8021x) { + if (left >= 6) { + pos += 2; + if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s : there has 802.1x auth\n", __FUNCTION__)); + *is_8021x = 1; + } + } + } + + return ret; + +} + +int rtw_parse_wpa2_ie(u8* rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) +{ + int i, ret=_SUCCESS; + int left, count; + u8 *pos; + u8 SUITE_1X[4] = {0x00,0x0f, 0xac, 0x01}; + + if (rsn_ie_len <= 0) { + /* No RSN IE - fail silently */ + return _FAIL; + } + + + if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2))) + { + return _FAIL; + } + + pos = rsn_ie; + pos += 4; + left = rsn_ie_len - 4; + + //group_cipher + if (left >= RSN_SELECTOR_LEN) { + + *group_cipher = rtw_get_wpa2_cipher_suite(pos); + + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + + } else if (left > 0) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); + return _FAIL; + } + + //pairwise_cipher + if (left >= 2) + { + //count = le16_to_cpu(*(u16*)pos); + count = RTW_GET_LE16(pos); + pos += 2; + left -= 2; + + if (count == 0 || left < count * RSN_SELECTOR_LEN) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " + "count %u left %u", __FUNCTION__, count, left)); + return _FAIL; + } + + for (i = 0; i < count; i++) + { + *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); + + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + } + + } + else if (left == 1) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); + + return _FAIL; + } + + if (is_8021x) { + if (left >= 6) { + pos += 2; + if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s (): there has 802.1x auth\n", __FUNCTION__)); + *is_8021x = 1; + } + } + } + + return ret; + +} + +//#ifdef CONFIG_WAPI_SUPPORT +int rtw_get_wapi_ie(u8 *in_ie,uint in_len,u8 *wapi_ie,u16 *wapi_len) +{ + int len = 0; + u8 authmode, i; + uint cnt; + u8 wapi_oui1[4]={0x0,0x14,0x72,0x01}; + u8 wapi_oui2[4]={0x0,0x14,0x72,0x02}; + +_func_enter_; + + if(wapi_len) + *wapi_len = 0; + + if(!in_ie || in_len<=0) + return len; + + cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); + + while(cnt found WPS_IE.....\n"); + *wps_ielen = ie_ptr[1]+2; + match=_TRUE; + } + return match; +} + +u8 *rtw_get_wps_ie_from_scan_queue(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen, u8 frame_type) +{ + u8* wps = NULL; + + DBG_871X( "[%s] frame_type = %d\n", __FUNCTION__, frame_type ); + switch( frame_type ) + { + case 1: + case 3: + { // Beacon or Probe Response + wps = rtw_get_wps_ie(in_ie + _PROBERSP_IE_OFFSET_, in_len - _PROBERSP_IE_OFFSET_, wps_ie, wps_ielen); + break; + } + case 2: + { // Probe Request + wps = rtw_get_wps_ie(in_ie + _PROBEREQ_IE_OFFSET_ , in_len - _PROBEREQ_IE_OFFSET_ , wps_ie, wps_ielen); + break; + } + } + return wps; +} + +/** + * rtw_get_wps_ie - Search WPS IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie + * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE + * + * Returns: The address of the WPS IE found, or NULL + */ +u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) +{ + uint cnt; + u8 *wpsie_ptr = NULL; + u8 eid, wps_oui[4] = {0x00, 0x50, 0xf2, 0x04}; + + if (wps_ielen) + *wps_ielen = 0; + + if (!in_ie) { + rtw_warn_on(1); + return wpsie_ptr; + } + + if (in_len <= 0) + return wpsie_ptr; + + cnt = 0; + + while (cnt + 1 + 4 < in_len) { + eid = in_ie[cnt]; + + if (cnt + 1 + 4 >= MAX_IE_SZ) { + rtw_warn_on(1); + return NULL; + } + + if (eid == WLAN_EID_VENDOR_SPECIFIC && _rtw_memcmp(&in_ie[cnt + 2], wps_oui, 4) == _TRUE) { + wpsie_ptr = in_ie + cnt; + + if (wps_ie) + _rtw_memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); + + if (wps_ielen) + *wps_ielen = in_ie[cnt + 1] + 2; + + break; + } else { + cnt += in_ie[cnt + 1] + 2; + } + + } + + return wpsie_ptr; +} + +/** + * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE + * @wps_ie: Address of WPS IE to search + * @wps_ielen: Length limit from wps_ie + * @target_attr_id: The attribute ID of WPS attribute to search + * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr + * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute + * + * Returns: the address of the specific WPS attribute found, or NULL + */ +u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr) +{ + u8 *attr_ptr = NULL; + u8 * target_attr_ptr = NULL; + u8 wps_oui[4]={0x00,0x50,0xF2,0x04}; + + if(len_attr) + *len_attr = 0; + + if ( ( wps_ie[0] != _VENDOR_SPECIFIC_IE_ ) || + ( _rtw_memcmp( wps_ie + 2, wps_oui , 4 ) != _TRUE ) ) + { + return attr_ptr; + } + + // 6 = 1(Element ID) + 1(Length) + 4(WPS OUI) + attr_ptr = wps_ie + 6; //goto first attr + + while(attr_ptr - wps_ie < wps_ielen) + { + // 4 = 2(Attribute ID) + 2(Length) + u16 attr_id = RTW_GET_BE16(attr_ptr); + u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2); + u16 attr_len = attr_data_len + 4; + + //DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __FUNCTION__, attr_ptr, attr_id, attr_data_len); + if( attr_id == target_attr_id ) + { + target_attr_ptr = attr_ptr; + + if(buf_attr) + _rtw_memcpy(buf_attr, attr_ptr, attr_len); + + if(len_attr) + *len_attr = attr_len; + + break; + } + else + { + attr_ptr += attr_len; //goto next + } + + } + + return target_attr_ptr; +} + +/** + * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE + * @wps_ie: Address of WPS IE to search + * @wps_ielen: Length limit from wps_ie + * @target_attr_id: The attribute ID of WPS attribute to search + * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content + * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content + * + * Returns: the address of the specific WPS attribute content found, or NULL + */ +u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content) +{ + u8 *attr_ptr; + u32 attr_len; + + if(len_content) + *len_content = 0; + + attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len); + + if(attr_ptr && attr_len) + { + if(buf_content) + _rtw_memcpy(buf_content, attr_ptr+4, attr_len-4); + + if(len_content) + *len_content = attr_len-4; + + return attr_ptr+4; + } + + return NULL; +} + +static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, + struct rtw_ieee802_11_elems *elems, + int show_errors) +{ + unsigned int oui; + + /* first 3 bytes in vendor specific information element are the IEEE + * OUI of the vendor. The following byte is used a vendor specific + * sub-type. */ + if (elen < 4) { + if (show_errors) { + DBG_871X("short vendor specific " + "information element ignored (len=%lu)\n", + (unsigned long) elen); + } + return -1; + } + + oui = RTW_GET_BE24(pos); + switch (oui) { + case OUI_MICROSOFT: + /* Microsoft/Wi-Fi information elements are further typed and + * subtyped */ + switch (pos[3]) { + case 1: + /* Microsoft OUI (00:50:F2) with OUI Type 1: + * real WPA information element */ + elems->wpa_ie = pos; + elems->wpa_ie_len = elen; + break; + case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ + if (elen < 5) { + DBG_871X("short WME " + "information element ignored " + "(len=%lu)\n", + (unsigned long) elen); + return -1; + } + switch (pos[4]) { + case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: + case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: + elems->wme = pos; + elems->wme_len = elen; + break; + case WME_OUI_SUBTYPE_TSPEC_ELEMENT: + elems->wme_tspec = pos; + elems->wme_tspec_len = elen; + break; + default: + DBG_871X_LEVEL(_drv_warning_, "unknown WME " + "information element ignored " + "(subtype=%d len=%lu)\n", + pos[4], (unsigned long) elen); + return -1; + } + break; + case 4: + /* Wi-Fi Protected Setup (WPS) IE */ + elems->wps_ie = pos; + elems->wps_ie_len = elen; + break; + default: + DBG_871X_LEVEL(_drv_warning_, "Unknown Microsoft " + "information element ignored " + "(type=%d len=%lu)\n", + pos[3], (unsigned long) elen); + return -1; + } + break; + + case OUI_BROADCOM: + switch (pos[3]) { + case VENDOR_HT_CAPAB_OUI_TYPE: + elems->vendor_ht_cap = pos; + elems->vendor_ht_cap_len = elen; + break; + default: + DBG_871X_LEVEL(_drv_warning_, "Unknown Broadcom " + "information element ignored " + "(type=%d len=%lu)\n", + pos[3], (unsigned long) elen); + return -1; + } + break; + + default: + 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); + return -1; + } + + return 0; + +} + +/** + * ieee802_11_parse_elems - Parse information elements in management frames + * @start: Pointer to the start of IEs + * @len: Length of IE buffer in octets + * @elems: Data structure for parsed elements + * @show_errors: Whether to show parsing errors in debug log + * Returns: Parsing result + */ +ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, + struct rtw_ieee802_11_elems *elems, + int show_errors) +{ + uint left = len; + u8 *pos = start; + int unknown = 0; + + _rtw_memset(elems, 0, sizeof(*elems)); + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) { + if (show_errors) { + DBG_871X("IEEE 802.11 element " + "parse failed (id=%d elen=%d " + "left=%lu)\n", + id, elen, (unsigned long) left); + } + return ParseFailed; + } + + switch (id) { + case WLAN_EID_SSID: + elems->ssid = pos; + elems->ssid_len = elen; + break; + case WLAN_EID_SUPP_RATES: + elems->supp_rates = pos; + elems->supp_rates_len = elen; + break; + case WLAN_EID_FH_PARAMS: + elems->fh_params = pos; + elems->fh_params_len = elen; + break; + case WLAN_EID_DS_PARAMS: + elems->ds_params = pos; + elems->ds_params_len = elen; + break; + case WLAN_EID_CF_PARAMS: + elems->cf_params = pos; + elems->cf_params_len = elen; + break; + case WLAN_EID_TIM: + elems->tim = pos; + elems->tim_len = elen; + break; + case WLAN_EID_IBSS_PARAMS: + elems->ibss_params = pos; + elems->ibss_params_len = elen; + break; + case WLAN_EID_CHALLENGE: + elems->challenge = pos; + elems->challenge_len = elen; + break; + case WLAN_EID_ERP_INFO: + elems->erp_info = pos; + elems->erp_info_len = elen; + break; + case WLAN_EID_EXT_SUPP_RATES: + elems->ext_supp_rates = pos; + elems->ext_supp_rates_len = elen; + break; + case WLAN_EID_VENDOR_SPECIFIC: + if (rtw_ieee802_11_parse_vendor_specific(pos, elen, + elems, + show_errors)) + unknown++; + break; + case WLAN_EID_RSN: + elems->rsn_ie = pos; + elems->rsn_ie_len = elen; + break; + case WLAN_EID_PWR_CAPABILITY: + elems->power_cap = pos; + elems->power_cap_len = elen; + break; + case WLAN_EID_SUPPORTED_CHANNELS: + elems->supp_channels = pos; + elems->supp_channels_len = elen; + break; + case WLAN_EID_MOBILITY_DOMAIN: + elems->mdie = pos; + elems->mdie_len = elen; + break; + case WLAN_EID_FAST_BSS_TRANSITION: + elems->ftie = pos; + elems->ftie_len = elen; + break; + case WLAN_EID_TIMEOUT_INTERVAL: + elems->timeout_int = pos; + elems->timeout_int_len = elen; + break; + case WLAN_EID_HT_CAP: + elems->ht_capabilities = pos; + elems->ht_capabilities_len = elen; + break; + case WLAN_EID_HT_OPERATION: + elems->ht_operation = pos; + elems->ht_operation_len = elen; + break; + case WLAN_EID_VHT_CAPABILITY: + elems->vht_capabilities = pos; + elems->vht_capabilities_len = elen; + break; + case WLAN_EID_VHT_OPERATION: + elems->vht_operation = pos; + elems->vht_operation_len = elen; + break; + case WLAN_EID_VHT_OP_MODE_NOTIFY: + elems->vht_op_mode_notify = pos; + elems->vht_op_mode_notify_len = elen; + break; + default: + unknown++; + if (!show_errors) + break; + DBG_871X_LEVEL(_drv_warning_, + "IEEE 802.11 element parse " + "ignored unknown element (id=%d elen=%d)\n", + id, elen); + break; + } + + left -= elen; + pos += elen; + } + + if (left) + return ParseFailed; + + return unknown ? ParseUnknown : ParseOK; + +} + +static u8 key_char2num(u8 ch); +static u8 key_char2num(u8 ch) +{ + if((ch>='0')&&(ch<='9')) + return ch - '0'; + else if ((ch>='a')&&(ch<='f')) + return ch - 'a' + 10; + else if ((ch>='A')&&(ch<='F')) + return ch - 'A' + 10; + else + return 0xff; +} + +u8 str_2char2num(u8 hch, u8 lch); +u8 str_2char2num(u8 hch, u8 lch) +{ + return ((key_char2num(hch) * 10 ) + key_char2num(lch)); +} + +u8 key_2char2num(u8 hch, u8 lch); +u8 key_2char2num(u8 hch, u8 lch) +{ + return ((key_char2num(hch) << 4) | key_char2num(lch)); +} + +void macstr2num(u8 *dst, u8 *src); +void macstr2num(u8 *dst, u8 *src) +{ + int jj, kk; + for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) + { + dst[jj] = key_2char2num(src[kk], src[kk + 1]); + } +} + +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_retrieve_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 + +/* + * Description: + * rtw_check_invalid_mac_address: + * This is only used for checking mac address valid or not. + * + * Input: + * adapter: mac_address pointer. + * check_local_bit: check locally bit or not. + * + * Output: + * _TRUE: The mac address is invalid. + * _FALSE: The mac address is valid. + * + * Auther: Isaac.Li + */ +u8 rtw_check_invalid_mac_address(u8 *mac_addr, u8 check_local_bit) +{ + u8 null_mac_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + u8 multi_mac_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 res = _FALSE; + + if (_rtw_memcmp(mac_addr, null_mac_addr, ETH_ALEN)) { + res = _TRUE; + goto func_exit; + } + + if (_rtw_memcmp(mac_addr, multi_mac_addr, ETH_ALEN)) { + res = _TRUE; + goto func_exit; + } + + if (mac_addr[0] & BIT0) { + res = _TRUE; + goto func_exit; + } + + if (check_local_bit == _TRUE) { + if (mac_addr[0] & BIT1) { + res = _TRUE; + goto func_exit; + } + } + +func_exit: + return res; +} + +extern char* rtw_initmac; +/** + * rtw_macaddr_cfg - Decide the mac address used + * @out: buf to store mac address decided + * @hw_mac_addr: mac address from efuse/epprom + */ +void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr) +{ +#define DEFAULT_RANDOM_MACADDR 1 + u8 mac[ETH_ALEN]; + + if (out == NULL) { + rtw_warn_on(1); + return; + } + + /* Users specify the mac address */ + if (rtw_initmac) { + int jj,kk; + + for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) + mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk + 1]); + + goto err_chk; + } + + /* platform specified */ +#ifdef CONFIG_PLATFORM_INTEL_BYT + if (rtw_get_mac_addr_intel(mac) == 0) + goto err_chk; +#endif + + /* Use the mac address stored in the Efuse */ + if (hw_mac_addr) { + _rtw_memcpy(mac, hw_mac_addr, ETH_ALEN); + goto err_chk; + } + +err_chk: + if (rtw_check_invalid_mac_address(mac, _TRUE) == _TRUE) { + #if DEFAULT_RANDOM_MACADDR + DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign random MAC\n", MAC_ARG(mac)); + *((u32 *)(&mac[2])) = rtw_random32(); + mac[0] = 0x00; + mac[1] = 0xe0; + mac[2] = 0x4c; + #else + DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign default one\n", MAC_ARG(mac)); + mac[0] = 0x00; + mac[1] = 0xe0; + mac[2] = 0x4c; + mac[3] = 0x87; + mac[4] = 0x00; + mac[5] = 0x00; + #endif + } + + _rtw_memcpy(out, mac, ETH_ALEN); + DBG_871X("%s mac addr:"MAC_FMT"\n", __func__, MAC_ARG(out)); +} + +#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+1 0) + *ch = *(p + 2); + +#ifdef CONFIG_80211N_HT +{ + u8 *ht_cap_ie, *ht_op_ie; + int ht_cap_ielen, ht_op_ielen; + + ht_cap_ie = rtw_get_ie(ies, EID_HTCapability, &ht_cap_ielen, ies_len); + if (ht_cap_ie && ht_cap_ielen) { + if (GET_HT_CAP_ELE_CHL_WIDTH(ht_cap_ie + 2)) + *bw = CHANNEL_WIDTH_40; + } + + ht_op_ie = rtw_get_ie(ies, EID_HTInfo, &ht_op_ielen, ies_len); + if (ht_op_ie && ht_op_ielen) { + if (*ch == 0) { + *ch = GET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2); + } else if (*ch != 0 && *ch != GET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2)) { + DBG_871X("%s ch inconsistent, DSSS:%u, HT primary:%u\n" + , __func__, *ch, GET_HT_OP_ELE_PRI_CHL(ht_op_ie + 2)); + } + + if (!GET_HT_OP_ELE_STA_CHL_WIDTH(ht_op_ie + 2)) + *bw = CHANNEL_WIDTH_20; + + if (*bw == CHANNEL_WIDTH_40) { + switch (GET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op_ie + 2)) { + case SCA: + *offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case SCB: + *offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + } + } + } +} +#endif /* CONFIG_80211N_HT */ +#ifdef CONFIG_80211AC_VHT +{ + u8 *vht_op_ie; + int vht_op_ielen; + + vht_op_ie = rtw_get_ie(ies, EID_VHTOperation, &vht_op_ielen, ies_len); + if (vht_op_ie && vht_op_ielen) { + if (GET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op_ie + 2) >= 1) + *bw = CHANNEL_WIDTH_80; + } +} +#endif +} + +void rtw_bss_get_chbw(WLAN_BSSID_EX *bss, u8 *ch, u8 *bw, u8 *offset) +{ + rtw_ies_get_chbw(bss->IEs + sizeof(NDIS_802_11_FIXED_IEs) + , bss->IELength - sizeof(NDIS_802_11_FIXED_IEs) + , ch, bw, offset); + + if (*ch == 0) { + *ch = bss->Configuration.DSConfig; + } else if (*ch != bss->Configuration.DSConfig) { + DBG_871X("inconsistent ch - ies:%u bss->Configuration.DSConfig:%u\n" + , *ch, bss->Configuration.DSConfig); + *ch = bss->Configuration.DSConfig; + rtw_warn_on(1); + } +} + +/** + * rtw_is_chbw_grouped - test if the two ch settings can be grouped together + * @ch_a: ch of set a + * @bw_a: bw of set a + * @offset_a: offset of set a + * @ch_b: ch of set b + * @bw_b: bw of set b + * @offset_b: offset of set b + */ +bool rtw_is_chbw_grouped(u8 ch_a, u8 bw_a, u8 offset_a + , u8 ch_b, u8 bw_b, u8 offset_b) +{ + bool is_grouped = _FALSE; + + if (ch_a != ch_b) { + /* ch is different */ + goto exit; + } else if ((bw_a == CHANNEL_WIDTH_40 || bw_a == CHANNEL_WIDTH_80) + && (bw_b == CHANNEL_WIDTH_40 || bw_b == CHANNEL_WIDTH_80) + ) { + if (offset_a != offset_b) + goto exit; + } + + is_grouped = _TRUE; + +exit: + return is_grouped; +} + +/** + * rtw_sync_chbw - obey g_ch, adjust g_bw, g_offset, bw, offset + * @req_ch: pointer of the request ch, may be modified further + * @req_bw: pointer of the request bw, may be modified further + * @req_offset: pointer of the request offset, may be modified further + * @g_ch: pointer of the ongoing group ch + * @g_bw: pointer of the ongoing group bw, may be modified further + * @g_offset: pointer of the ongoing group offset, may be modified further + */ +void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset + , u8 *g_ch, u8 *g_bw, u8 *g_offset) +{ + + *req_ch = *g_ch; + + if (*req_bw == CHANNEL_WIDTH_80 && *g_ch <= 14) { + /*2.4G ch, downgrade to 40Mhz */ + *req_bw = CHANNEL_WIDTH_40; + } + + switch (*req_bw) { + case CHANNEL_WIDTH_80: + if (*g_bw == CHANNEL_WIDTH_40 || *g_bw == CHANNEL_WIDTH_80) + *req_offset = *g_offset; + else if (*g_bw == CHANNEL_WIDTH_20) + *req_offset = rtw_get_offset_by_ch(*req_ch); + + if (*req_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) { + DBG_871X_LEVEL(_drv_err_, "%s req 80MHz BW without offset, down to 20MHz\n", __func__); + rtw_warn_on(1); + *req_bw = CHANNEL_WIDTH_20; + } + break; + case CHANNEL_WIDTH_40: + if (*g_bw == CHANNEL_WIDTH_40 || *g_bw == CHANNEL_WIDTH_80) + *req_offset = *g_offset; + else if (*g_bw == CHANNEL_WIDTH_20) + *req_offset = rtw_get_offset_by_ch(*req_ch); + + if (*req_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) { + DBG_871X_LEVEL(_drv_err_, "%s req 40MHz BW without offset, down to 20MHz\n", __func__); + rtw_warn_on(1); + *req_bw = CHANNEL_WIDTH_20; + } + break; + case CHANNEL_WIDTH_20: + *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + default: + DBG_871X_LEVEL(_drv_err_, "%s req unsupported BW:%u\n", __func__, *req_bw); + rtw_warn_on(1); + } + + if (*req_bw > *g_bw) { + *g_bw = *req_bw; + *g_offset = *req_offset; + } +} + +/** + * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies. + * @in_ie: Pointer of the first p2p ie + * @in_len: Total len of muiltiple p2p ies + * Returns: Length of merged p2p ie length + */ +u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 }; + int i=0; + int j=0, len=0; + + while( i < in_len) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i); + + if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) ) + { + len += pIE->Length-4; // 4 is P2P OUI length, don't count it in this loop + } + + i += (pIE->Length + 2); + } + + return len + 4; // Append P2P OUI length at last. +} + +/** + * rtw_p2p_merge_ies - Merge muitiple p2p ies into one + * @in_ie: Pointer of the first p2p ie + * @in_len: Total len of muiltiple p2p ies + * @merge_ie: Pointer of merged ie + * Returns: Length of merged p2p ie + */ +int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie) +{ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 len = 0; + u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 }; + u8 ELOUI[6] = { 0xDD, 0x00, 0x50, 0x6f, 0x9a, 0x09 }; //EID;Len;OUI, Len would copy at the end of function + int i=0; + + if( merge_ie != NULL) + { + //Set first P2P OUI + _rtw_memcpy(merge_ie, ELOUI, 6); + merge_ie += 6; + + while( i < in_len) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i); + + // Take out the rest of P2P OUIs + if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) ) + { + _rtw_memcpy( merge_ie, pIE->data +4, pIE->Length -4); + len += pIE->Length-4; + merge_ie += pIE->Length-4; + } + + i += (pIE->Length + 2); + } + + return len + 4; // 4 is for P2P OUI + + } + + return 0; +} + +void dump_p2p_ie(void *sel, u8 *ie, u32 ie_len) +{ + u8* pos = (u8*)ie; + u8 id; + u16 len; + + u8 *p2p_ie; + uint p2p_ielen; + + p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen); + if (p2p_ie != ie || p2p_ielen == 0) + return; + + pos += 6; + while (pos - ie + 3 <= ie_len) { + id = *pos; + len = RTW_GET_LE16(pos + 1); + + DBG_871X_SEL_NL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); + + pos += (3 + len); + } +} + +/** + * rtw_get_p2p_ie - Search P2P IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie + * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE + * + * Returns: The address of the P2P IE found, or NULL + */ +u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen) +{ + uint cnt; + u8 *p2p_ie_ptr = NULL; + u8 eid, p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; + + if (p2p_ielen) + *p2p_ielen = 0; + + if (!in_ie || in_len < 0) { + rtw_warn_on(1); + return p2p_ie_ptr; + } + + if (in_len <= 0) + return p2p_ie_ptr; + + cnt = 0; + + while (cnt + 1 + 4 < in_len) { + eid = in_ie[cnt]; + + if (cnt + 1 + 4 >= MAX_IE_SZ) { + rtw_warn_on(1); + return NULL; + } + + if (eid == WLAN_EID_VENDOR_SPECIFIC && _rtw_memcmp(&in_ie[cnt + 2], p2p_oui, 4) == _TRUE) { + p2p_ie_ptr = in_ie + cnt; + + if (p2p_ie) + _rtw_memcpy(p2p_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); + + if (p2p_ielen) + *p2p_ielen = in_ie[cnt + 1] + 2; + + break; + } else { + cnt += in_ie[cnt + 1] + 2; + } + + } + + return p2p_ie_ptr; +} + +/** + * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE + * @p2p_ie: Address of P2P IE to search + * @p2p_ielen: Length limit from p2p_ie + * @target_attr_id: The attribute ID of P2P attribute to search + * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr + * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute + * + * Returns: the address of the specific WPS attribute found, or NULL + */ +u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr) +{ + u8 *attr_ptr = NULL; + u8 *target_attr_ptr = NULL; + u8 p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09}; + + if (len_attr) + *len_attr = 0; + + if (!p2p_ie + || p2p_ielen <= 6 + || (p2p_ie[0] != WLAN_EID_VENDOR_SPECIFIC) + || (_rtw_memcmp(p2p_ie + 2, p2p_oui, 4) != _TRUE)) + return attr_ptr; + + /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */ + attr_ptr = p2p_ie + 6; /* goto first attr */ + + while ((attr_ptr - p2p_ie + 3) <= p2p_ielen) { + /* 3 = 1(Attribute ID) + 2(Length) */ + u8 attr_id = *attr_ptr; + u16 attr_data_len = RTW_GET_LE16(attr_ptr + 1); + u16 attr_len = attr_data_len + 3; + + if (0) + DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __func__, attr_ptr, attr_id, attr_data_len); + + if ((attr_ptr - p2p_ie + attr_len) > p2p_ielen) + break; + + if (attr_id == target_attr_id) { + target_attr_ptr = attr_ptr; + + if (buf_attr) + _rtw_memcpy(buf_attr, attr_ptr, attr_len); + + if (len_attr) + *len_attr = attr_len; + + break; + } else { + attr_ptr += attr_len; + } + } + + return target_attr_ptr; +} + +/** + * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE + * @p2p_ie: Address of P2P IE to search + * @p2p_ielen: Length limit from p2p_ie + * @target_attr_id: The attribute ID of P2P attribute to search + * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content + * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content + * + * Returns: the address of the specific P2P attribute content found, or NULL + */ +u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content) +{ + u8 *attr_ptr; + u32 attr_len; + + if (len_content) + *len_content = 0; + + attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len); + + if (attr_ptr && attr_len) { + if (buf_content) + _rtw_memcpy(buf_content, attr_ptr + 3, attr_len - 3); + + if (len_content) + *len_content = attr_len - 3; + + return attr_ptr + 3; + } + + return NULL; +} + +u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr) +{ + u32 a_len; + + *pbuf = attr_id; + + //*(u16*)(pbuf + 1) = cpu_to_le16(attr_len); + RTW_PUT_LE16(pbuf + 1, attr_len); + + if(pdata_attr) + _rtw_memcpy(pbuf + 3, pdata_attr, attr_len); + + a_len = attr_len + 3; + + return a_len; +} + +uint rtw_del_p2p_ie(u8 *ies, uint ies_len_ori, const char *msg) +{ +#define DBG_DEL_P2P_IE 0 + + u8 *target_ie; + u32 target_ie_len; + uint ies_len = ies_len_ori; + int index = 0; + + while (1) { + target_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &target_ie_len); + if (target_ie && target_ie_len) { + u8 *next_ie = target_ie + target_ie_len; + uint remain_len = ies_len - (next_ie - ies); + + if (DBG_DEL_P2P_IE && msg) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + + DBG_871X("ies:%p, ies_len:%u\n", ies, ies_len); + DBG_871X("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); + DBG_871X("next_ie:%p, remain_len:%u\n", next_ie, remain_len); + } + + _rtw_memmove(target_ie, next_ie, remain_len); + _rtw_memset(target_ie + remain_len, 0, target_ie_len); + ies_len -= target_ie_len; + + if (DBG_DEL_P2P_IE && msg) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + } + + index++; + } else { + break; + } + } + + return ies_len; +} + +uint rtw_del_p2p_attr(u8 *ie, uint ielen_ori, u8 attr_id) +{ +#define DBG_DEL_P2P_ATTR 0 + + u8 *target_attr; + u32 target_attr_len; + uint ielen = ielen_ori; + int index = 0; + + while(1) { + target_attr = rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len); + if (target_attr && target_attr_len) { + u8 *next_attr = target_attr + target_attr_len; + uint remain_len = ielen - (next_attr - ie); + + if (DBG_DEL_P2P_ATTR) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ie, ielen); + + DBG_871X("ie:%p, ielen:%u\n", ie, ielen); + DBG_871X("target_attr:%p, target_attr_len:%u\n", target_attr, target_attr_len); + DBG_871X("next_attr:%p, remain_len:%u\n", next_attr, remain_len); + } + + _rtw_memmove(target_attr, next_attr, remain_len); + _rtw_memset(target_attr + remain_len, 0, target_attr_len); + *(ie + 1) -= target_attr_len; + ielen -= target_attr_len; + + if (DBG_DEL_P2P_ATTR) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ie, ielen); + } + + index++; + } else { + break; + } + } + + return ielen; +} + +inline u8 *rtw_bss_ex_get_p2p_ie(WLAN_BSSID_EX *bss_ex, u8 *p2p_ie, uint *p2p_ielen) +{ + return rtw_get_p2p_ie(BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex), p2p_ie, p2p_ielen); +} + +void rtw_bss_ex_del_p2p_ie(WLAN_BSSID_EX *bss_ex) +{ +#define DBG_BSS_EX_DEL_P2P_IE 0 + + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); + uint ies_len; + + ies_len = rtw_del_p2p_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_P2P_IE ? __func__ : NULL); + bss_ex->IELength -= ies_len_ori - ies_len; +} + +void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) +{ +#define DBG_BSS_EX_DEL_P2P_ATTR 0 + + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len = BSS_EX_TLV_IES_LEN(bss_ex); + + u8 *ie; + uint ie_len, ie_len_ori; + + int index = 0; + + while (1) { + ie = rtw_get_p2p_ie(ies, ies_len, NULL, &ie_len_ori); + if (ie) { + u8 *next_ie_ori = ie + ie_len_ori; + uint remain_len = bss_ex->IELength - (next_ie_ori - bss_ex->IEs); + u8 has_target_attr = 0; + + if (DBG_BSS_EX_DEL_P2P_ATTR) { + if (rtw_get_p2p_attr(ie, ie_len_ori, attr_id, NULL, NULL)) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex)); + + DBG_871X("ies:%p, ies_len:%u\n", ies, ies_len); + DBG_871X("ie:%p, ie_len_ori:%u\n", ie, ie_len_ori); + DBG_871X("next_ie_ori:%p, remain_len:%u\n", next_ie_ori, remain_len); + has_target_attr = 1; + } + } + + ie_len = rtw_del_p2p_attr(ie, ie_len_ori, attr_id); + if (ie_len != ie_len_ori) { + u8 *next_ie = ie + ie_len; + + _rtw_memmove(next_ie, next_ie_ori, remain_len); + _rtw_memset(next_ie + remain_len, 0, ie_len_ori - ie_len); + bss_ex->IELength -= ie_len_ori - ie_len; + + ies = next_ie; + } else { + ies = next_ie_ori; + } + + if (DBG_BSS_EX_DEL_P2P_ATTR) { + if (has_target_attr) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex)); + } + } + + ies_len = remain_len; + + index++; + } else { + break; + } + } +} + +void dump_wfd_ie(void *sel, u8 *ie, u32 ie_len) +{ + u8* pos = (u8*)ie; + u8 id; + u16 len; + + u8 *wfd_ie; + uint wfd_ielen; + + wfd_ie = rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen); + if (wfd_ie != ie || wfd_ielen == 0) + return; + + pos += 6; + while (pos - ie + 3 <= ie_len) { + id = *pos; + len = RTW_GET_BE16(pos + 1); + + DBG_871X_SEL_NL(sel, "%s ID:%u, LEN:%u%s\n", __func__, id, len + , ((pos - ie + 3 + len) <= ie_len) ? "" : "(exceed ie_len)"); + + pos += (3 + len); + } +} + +/** + * rtw_get_wfd_ie - Search WFD IE from a series of IEs + * @in_ie: Address of IEs to search + * @in_len: Length limit from in_ie + * @wfd_ie: If not NULL and WFD IE is found, WFD IE will be copied to the buf starting from wfd_ie + * @wfd_ielen: If not NULL and WFD IE is found, will set to the length of the entire WFD IE + * + * Returns: The address of the P2P IE found, or NULL + */ +u8 *rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen) +{ + uint cnt; + u8 *wfd_ie_ptr = NULL; + u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A}; + + if (wfd_ielen) + *wfd_ielen = 0; + + if (!in_ie || in_len < 0) { + rtw_warn_on(1); + return wfd_ie_ptr; + } + + if (in_len <= 0) + return wfd_ie_ptr; + + cnt = 0; + + while (cnt + 1 + 4 < in_len) { + eid = in_ie[cnt]; + + if (cnt + 1 + 4 >= MAX_IE_SZ) { + rtw_warn_on(1); + return NULL; + } + + if (eid == WLAN_EID_VENDOR_SPECIFIC && _rtw_memcmp(&in_ie[cnt + 2], wfd_oui, 4) == _TRUE) { + wfd_ie_ptr = in_ie + cnt; + + if (wfd_ie) + _rtw_memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); + + if (wfd_ielen) + *wfd_ielen = in_ie[cnt + 1] + 2; + + break; + } else { + cnt += in_ie[cnt + 1] + 2; + } + + } + + return wfd_ie_ptr; +} + +/** + * rtw_get_wfd_attr - Search a specific WFD attribute from a given WFD IE + * @wfd_ie: Address of WFD IE to search + * @wfd_ielen: Length limit from wfd_ie + * @target_attr_id: The attribute ID of WFD attribute to search + * @buf_attr: If not NULL and the WFD attribute is found, WFD attribute will be copied to the buf starting from buf_attr + * @len_attr: If not NULL and the WFD attribute is found, will set to the length of the entire WFD attribute + * + * Returns: the address of the specific WPS attribute found, or NULL + */ +u8 *rtw_get_wfd_attr(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr) +{ + u8 *attr_ptr = NULL; + u8 *target_attr_ptr = NULL; + u8 wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A}; + + if (len_attr) + *len_attr = 0; + + if (!wfd_ie + || wfd_ielen <= 6 + || (wfd_ie[0] != WLAN_EID_VENDOR_SPECIFIC) + || (_rtw_memcmp(wfd_ie + 2, wfd_oui, 4) != _TRUE)) + return attr_ptr; + + /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */ + attr_ptr = wfd_ie + 6; /* goto first attr */ + + while ((attr_ptr - wfd_ie + 3) <= wfd_ielen) { + /* 3 = 1(Attribute ID) + 2(Length) */ + u8 attr_id = *attr_ptr; + u16 attr_data_len = RTW_GET_BE16(attr_ptr + 1); + u16 attr_len = attr_data_len + 3; + + if (0) + DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __func__, attr_ptr, attr_id, attr_data_len); + + if ((attr_ptr - wfd_ie + attr_len) > wfd_ielen) + break; + + if (attr_id == target_attr_id) { + target_attr_ptr = attr_ptr; + + if (buf_attr) + _rtw_memcpy(buf_attr, attr_ptr, attr_len); + + if (len_attr) + *len_attr = attr_len; + + break; + } else { + attr_ptr += attr_len; + } + } + + return target_attr_ptr; +} + +/** + * rtw_get_wfd_attr_content - Search a specific WFD attribute content from a given WFD IE + * @wfd_ie: Address of WFD IE to search + * @wfd_ielen: Length limit from wfd_ie + * @target_attr_id: The attribute ID of WFD attribute to search + * @buf_content: If not NULL and the WFD attribute is found, WFD attribute content will be copied to the buf starting from buf_content + * @len_content: If not NULL and the WFD attribute is found, will set to the length of the WFD attribute content + * + * Returns: the address of the specific WFD attribute content found, or NULL + */ +u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content) +{ + u8 *attr_ptr; + u32 attr_len; + + if (len_content) + *len_content = 0; + + attr_ptr = rtw_get_wfd_attr(wfd_ie, wfd_ielen, target_attr_id, NULL, &attr_len); + + if (attr_ptr && attr_len) { + if (buf_content) + _rtw_memcpy(buf_content, attr_ptr + 3, attr_len - 3); + + if (len_content) + *len_content = attr_len - 3; + + return attr_ptr + 3; + } + + return NULL; +} + +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg) +{ +#define DBG_DEL_WFD_IE 0 + + u8 *target_ie; + u32 target_ie_len; + uint ies_len = ies_len_ori; + int index = 0; + + while (1) { + target_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &target_ie_len); + if (target_ie && target_ie_len) { + u8 *next_ie = target_ie + target_ie_len; + uint remain_len = ies_len - (next_ie - ies); + + if (DBG_DEL_WFD_IE && msg) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + + DBG_871X("ies:%p, ies_len:%u\n", ies, ies_len); + DBG_871X("target_ie:%p, target_ie_len:%u\n", target_ie, target_ie_len); + DBG_871X("next_ie:%p, remain_len:%u\n", next_ie, remain_len); + } + + _rtw_memmove(target_ie, next_ie, remain_len); + _rtw_memset(target_ie + remain_len, 0, target_ie_len); + ies_len -= target_ie_len; + + if (DBG_DEL_WFD_IE && msg) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ies, ies_len); + } + + index++; + } else { + break; + } + } + + return ies_len; +} + +uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id) +{ +#define DBG_DEL_WFD_ATTR 0 + + u8 *target_attr; + u32 target_attr_len; + uint ielen = ielen_ori; + int index = 0; + + while (1) { + target_attr = rtw_get_wfd_attr(ie, ielen, attr_id, NULL, &target_attr_len); + if (target_attr && target_attr_len) { + u8 *next_attr = target_attr + target_attr_len; + uint remain_len = ielen - (next_attr - ie); + + if (DBG_DEL_WFD_ATTR) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, ie, ielen); + + DBG_871X("ie:%p, ielen:%u\n", ie, ielen); + DBG_871X("target_attr:%p, target_attr_len:%u\n", target_attr, target_attr_len); + DBG_871X("next_attr:%p, remain_len:%u\n", next_attr, remain_len); + } + + _rtw_memmove(target_attr, next_attr, remain_len); + _rtw_memset(target_attr + remain_len, 0, target_attr_len); + *(ie + 1) -= target_attr_len; + ielen -= target_attr_len; + + if (DBG_DEL_WFD_ATTR) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, ie, ielen); + } + + index++; + } else { + break; + } + } + + return ielen; +} + +inline u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ielen) +{ + return rtw_get_wfd_ie(BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex), wfd_ie, wfd_ielen); +} + +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex) +{ +#define DBG_BSS_EX_DEL_WFD_IE 0 + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len_ori = BSS_EX_TLV_IES_LEN(bss_ex); + uint ies_len; + + ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_BSS_EX_DEL_WFD_IE ? __func__ : NULL); + bss_ex->IELength -= ies_len_ori - ies_len; +} + +void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id) +{ +#define DBG_BSS_EX_DEL_WFD_ATTR 0 + + u8 *ies = BSS_EX_TLV_IES(bss_ex); + uint ies_len = BSS_EX_TLV_IES_LEN(bss_ex); + + u8 *ie; + uint ie_len, ie_len_ori; + + int index = 0; + + while (1) { + ie = rtw_get_wfd_ie(ies, ies_len, NULL, &ie_len_ori); + if (ie) { + u8 *next_ie_ori = ie + ie_len_ori; + uint remain_len = bss_ex->IELength - (next_ie_ori - bss_ex->IEs); + u8 has_target_attr = 0; + + if (DBG_BSS_EX_DEL_WFD_ATTR) { + if (rtw_get_wfd_attr(ie, ie_len_ori, attr_id, NULL, NULL)) { + DBG_871X("%s %d before\n", __func__, index); + dump_ies(RTW_DBGDUMP, BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex)); + + DBG_871X("ies:%p, ies_len:%u\n", ies, ies_len); + DBG_871X("ie:%p, ie_len_ori:%u\n", ie, ie_len_ori); + DBG_871X("next_ie_ori:%p, remain_len:%u\n", next_ie_ori, remain_len); + has_target_attr = 1; + } + } + + ie_len = rtw_del_wfd_attr(ie, ie_len_ori, attr_id); + if (ie_len != ie_len_ori) { + u8 *next_ie = ie + ie_len; + + _rtw_memmove(next_ie, next_ie_ori, remain_len); + _rtw_memset(next_ie + remain_len, 0, ie_len_ori - ie_len); + bss_ex->IELength -= ie_len_ori - ie_len; + + ies = next_ie; + } else { + ies = next_ie_ori; + } + + if (DBG_BSS_EX_DEL_WFD_ATTR) { + if (has_target_attr) { + DBG_871X("%s %d after\n", __func__, index); + dump_ies(RTW_DBGDUMP, BSS_EX_TLV_IES(bss_ex), BSS_EX_TLV_IES_LEN(bss_ex)); + } + } + + ies_len = remain_len; + + index++; + } else { + break; + } + } +} + +//Baron adds to avoid FreeBSD warning +int ieee80211_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +int ieee80211_get_hdrlen(u16 fc) +{ + int hdrlen = 24; + + switch (WLAN_FC_GET_TYPE(fc)) { + case RTW_IEEE80211_FTYPE_DATA: + if (fc & RTW_IEEE80211_STYPE_QOS_DATA) + hdrlen += 2; + if ((fc & RTW_IEEE80211_FCTL_FROMDS) && (fc & RTW_IEEE80211_FCTL_TODS)) + hdrlen += 6; /* Addr4 */ + break; + case RTW_IEEE80211_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case RTW_IEEE80211_STYPE_CTS: + case RTW_IEEE80211_STYPE_ACK: + hdrlen = 10; + break; + default: + hdrlen = 16; + break; + } + break; + } + + return hdrlen; +} + +int rtw_get_cipher_info(struct wlan_network *pnetwork) +{ + u32 wpa_ielen; + unsigned char *pbuf; + int group_cipher = 0, pairwise_cipher = 0, is8021x = 0; + int ret = _FAIL; + pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + + if(pbuf && (wpa_ielen>0)) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_cipher_info: wpa_ielen: %d", wpa_ielen)); + if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { + + pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; + pnetwork->BcnInfo.group_cipher = group_cipher; + pnetwork->BcnInfo.is_8021x = is8021x; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s: pnetwork->pairwise_cipher: %d, is_8021x is %d", + __func__, pnetwork->BcnInfo.pairwise_cipher, pnetwork->BcnInfo.is_8021x)); + ret = _SUCCESS; + } + } else { + + pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + + if(pbuf && (wpa_ielen>0)) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("get RSN IE\n")); + if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("get RSN IE OK!!!\n")); + pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher; + pnetwork->BcnInfo.group_cipher = group_cipher; + pnetwork->BcnInfo.is_8021x = is8021x; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s: pnetwork->pairwise_cipher: %d," + "pnetwork->group_cipher is %d, is_8021x is %d", __func__, pnetwork->BcnInfo.pairwise_cipher, + pnetwork->BcnInfo.group_cipher,pnetwork->BcnInfo.is_8021x)); + ret = _SUCCESS; + } + } + } + + return ret; +} + +void rtw_get_bcn_info(struct wlan_network *pnetwork) +{ + unsigned short cap = 0; + u8 bencrypt = 0; + //u8 wpa_ie[255],rsn_ie[255]; + u16 wpa_len=0,rsn_len=0; + struct HT_info_element *pht_info = NULL; + struct rtw_ieee80211_ht_cap *pht_cap = NULL; + unsigned int len; + unsigned char *p; + + _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); + cap = le16_to_cpu(cap); + if (cap & WLAN_CAPABILITY_PRIVACY) { + bencrypt = 1; + pnetwork->network.Privacy = 1; + } else { + pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS; + } + rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,NULL,&rsn_len,NULL,&wpa_len); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: ssid=%s\n",pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: ssid=%s\n",pnetwork->network.Ssid.Ssid)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len)); + + if (rsn_len > 0) { + pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2; + } else if (wpa_len > 0) { + pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA; + } else { + if (bencrypt) + pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP; + } + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: pnetwork->encryp_protocol is %x\n", + pnetwork->BcnInfo.encryp_protocol)); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_get_bcn_info: pnetwork->encryp_protocol is %x\n", + pnetwork->BcnInfo.encryp_protocol)); + rtw_get_cipher_info(pnetwork); + + /* get bwmode and ch_offset */ + /* parsing HT_CAP_IE */ + p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); + if(p && len>0) { + pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); + pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info; + } else { + pnetwork->BcnInfo.ht_cap_info = 0; + } + /* parsing HT_INFO_IE */ + p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_); + if(p && len>0) { + pht_info = (struct HT_info_element *)(p + 2); + pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0]; + } else { + pnetwork->BcnInfo.ht_info_infos_0 = 0; + } +} + +u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set) +{ + u8 nss = 1; + + if (supp_mcs_set[3]) + nss = 4; + else if (supp_mcs_set[2]) + nss = 3; + else if (supp_mcs_set[1]) + nss = 2; + else if (supp_mcs_set[0]) + nss = 1; + else + DBG_871X("%s,%d, warning! supp_mcs_set is zero\n", __func__, __LINE__); + /* DBG_871X("%s HT: %dSS\n", __FUNCTION__, nss); */ + return nss; +} + +//show MCS rate, unit: 100Kbps +u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI, unsigned char * MCS_rate) +{ + u16 max_rate = 0; + + /*MCS_rate[2] = 3T3R , MCS_rate[1] = 2T2R , MCS_rate[0] = 1T1R*/ + if (MCS_rate[2]) { + if (MCS_rate[2] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI)?4500:4050):((short_GI)?2167:1950); + else if (MCS_rate[2] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI)?4050:3645):((short_GI)?1950:1750); + else if (MCS_rate[2] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI)?3600:3240):((short_GI)?1733:1560); + else if (MCS_rate[2] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI)?2700:2430):((short_GI)?1300:1170); + else if (MCS_rate[2] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI)?1800:1620):((short_GI)?867:780); + else if (MCS_rate[2] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI)?1350:1215):((short_GI)?650:585); + else if (MCS_rate[2] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); + else if (MCS_rate[2] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI)?450:405):((short_GI)?217:195); + } else if (MCS_rate[1]) { + if(MCS_rate[1] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI)?3000:2700):((short_GI)?1444:1300); + else if(MCS_rate[1] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI)?2700:2430):((short_GI)?1300:1170); + else if(MCS_rate[1] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI)?2400:2160):((short_GI)?1156:1040); + else if(MCS_rate[1] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI)?1800:1620):((short_GI)?867:780); + else if(MCS_rate[1] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI)?1200:1080):((short_GI)?578:520); + else if(MCS_rate[1] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); + else if(MCS_rate[1] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI)?600:540):((short_GI)?289:260); + else if(MCS_rate[1] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); + } else { + if(MCS_rate[0] & BIT(7)) + max_rate = (bw_40MHz) ? ((short_GI)?1500:1350):((short_GI)?722:650); + else if(MCS_rate[0] & BIT(6)) + max_rate = (bw_40MHz) ? ((short_GI)?1350:1215):((short_GI)?650:585); + else if(MCS_rate[0] & BIT(5)) + max_rate = (bw_40MHz) ? ((short_GI)?1200:1080):((short_GI)?578:520); + else if(MCS_rate[0] & BIT(4)) + max_rate = (bw_40MHz) ? ((short_GI)?900:810):((short_GI)?433:390); + else if(MCS_rate[0] & BIT(3)) + max_rate = (bw_40MHz) ? ((short_GI)?600:540):((short_GI)?289:260); + else if(MCS_rate[0] & BIT(2)) + max_rate = (bw_40MHz) ? ((short_GI)?450:405):((short_GI)?217:195); + else if(MCS_rate[0] & BIT(1)) + max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130); + else if(MCS_rate[0] & BIT(0)) + max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65); + } + + return max_rate; +} + +int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8* category, u8 *action) +{ + const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u16 fc; + u8 c; + u8 a = ACT_PUBLIC_MAX; + + fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl); + + if ((fc & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)) + != (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION) + ) + { + return _FALSE; + } + + c = frame_body[0]; + + switch(c) { + case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */ + break; + default: + a = frame_body[1]; + } + + if (category) + *category = c; + if (action) + *action = a; + + return _TRUE; +} + +static const char *_action_public_str[] = { + "ACT_PUB_BSSCOEXIST", + "ACT_PUB_DSE_ENABLE", + "ACT_PUB_DSE_DEENABLE", + "ACT_PUB_DSE_REG_LOCATION", + "ACT_PUB_EXT_CHL_SWITCH", + "ACT_PUB_DSE_MSR_REQ", + "ACT_PUB_DSE_MSR_RPRT", + "ACT_PUB_MP", + "ACT_PUB_DSE_PWR_CONSTRAINT", + "ACT_PUB_VENDOR", + "ACT_PUB_GAS_INITIAL_REQ", + "ACT_PUB_GAS_INITIAL_RSP", + "ACT_PUB_GAS_COMEBACK_REQ", + "ACT_PUB_GAS_COMEBACK_RSP", + "ACT_PUB_TDLS_DISCOVERY_RSP", + "ACT_PUB_LOCATION_TRACK", + "ACT_PUB_RSVD", +}; + +const char *action_public_str(u8 action) +{ + action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action; + return _action_public_str[action]; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_io.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_io.c new file mode 100644 index 00000000..d08c16da --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_io.c @@ -0,0 +1,737 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/* + +The purpose of rtw_io.c + +a. provides the API + +b. provides the protocol engine + +c. provides the software interface between caller and the hardware interface + + +Compiler Flag Option: + +1. CONFIG_SDIO_HCI: + a. USE_SYNC_IRP: Only sync operations are provided. + b. USE_ASYNC_IRP:Both sync/async operations are provided. + +2. CONFIG_USB_HCI: + a. USE_ASYNC_IRP: Both sync/async operations are provided. + +3. CONFIG_CFIO_HCI: + b. USE_SYNC_IRP: Only sync operations are provided. + + +Only sync read/rtw_write_mem operations are provided. + +jackson@realtek.com.tw + +*/ + +#define _RTW_IO_C_ + +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) +#error "Shall be Linux or Windows, but not both!\n" +#endif + +#ifdef CONFIG_SDIO_HCI +#define rtw_le16_to_cpu(val) val +#define rtw_le32_to_cpu(val) val +#define rtw_cpu_to_le16(val) val +#define rtw_cpu_to_le32(val) val +#else +#define rtw_le16_to_cpu(val) le16_to_cpu(val) +#define rtw_le32_to_cpu(val) le32_to_cpu(val) +#define rtw_cpu_to_le16(val) cpu_to_le16(val) +#define rtw_cpu_to_le32(val) cpu_to_le32(val) +#endif + + +u8 _rtw_read8(_adapter *adapter, u32 addr) +{ + u8 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read8 = pintfhdl->io_ops._read8; + + r_val = _read8(pintfhdl, addr); + _func_exit_; + return r_val; +} + +u16 _rtw_read16(_adapter *adapter, u32 addr) +{ + u16 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read16 = pintfhdl->io_ops._read16; + + r_val = _read16(pintfhdl, addr); + _func_exit_; + return rtw_le16_to_cpu(r_val); +} + +u32 _rtw_read32(_adapter *adapter, u32 addr) +{ + u32 r_val; + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); + _func_enter_; + _read32 = pintfhdl->io_ops._read32; + + r_val = _read32(pintfhdl, addr); + _func_exit_; + return rtw_le32_to_cpu(r_val); + +} + +int _rtw_write8(_adapter *adapter, u32 addr, u8 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int ret; + _func_enter_; + _write8 = pintfhdl->io_ops._write8; + + ret = _write8(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write16(_adapter *adapter, u32 addr, u16 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int ret; + _func_enter_; + _write16 = pintfhdl->io_ops._write16; + + val = rtw_cpu_to_le16(val); + ret = _write16(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write32(_adapter *adapter, u32 addr, u32 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int ret; + _func_enter_; + _write32 = pintfhdl->io_ops._write32; + + val = rtw_cpu_to_le32(val); + ret = _write32(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} + +int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf)); + int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata); + int ret; + _func_enter_; + _writeN = pintfhdl->io_ops._writeN; + + ret = _writeN(pintfhdl, addr,length,pdata); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} + +#ifdef CONFIG_SDIO_HCI +u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr) +{ + u8 r_val = 0x00; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr); + + _func_enter_; + _sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8; + + if (_sd_f0_read8) + r_val = _sd_f0_read8(pintfhdl, addr); + else + DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + _func_exit_; + return r_val; +} + +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +u8 _rtw_sd_iread8(_adapter *adapter, u32 addr) +{ + u8 r_val = 0x00; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u8 (*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr); + + _sd_iread8 = pintfhdl->io_ops._sd_iread8; + + if (_sd_iread8) + r_val = _sd_iread8(pintfhdl, addr); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iread8 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return r_val; +} + +u16 _rtw_sd_iread16(_adapter *adapter, u32 addr) +{ + u16 r_val = 0x00; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u16 (*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr); + + _sd_iread16 = pintfhdl->io_ops._sd_iread16; + + if (_sd_iread16) + r_val = _sd_iread16(pintfhdl, addr); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iread16 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return r_val; +} + +u32 _rtw_sd_iread32(_adapter *adapter, u32 addr) +{ + u32 r_val = 0x00; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u32 (*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr); + + _sd_iread32 = pintfhdl->io_ops._sd_iread32; + + if (_sd_iread32) + r_val = _sd_iread32(pintfhdl, addr); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iread32 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return r_val; +} + +int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val) +{ + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int ret = -1; + + _sd_iwrite8 = pintfhdl->io_ops._sd_iwrite8; + + if (_sd_iwrite8) + ret = _sd_iwrite8(pintfhdl, addr, val); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iwrite8 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return RTW_STATUS_CODE(ret); +} + +int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val) +{ + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int ret = -1; + + _sd_iwrite16 = pintfhdl->io_ops._sd_iwrite16; + + if (_sd_iwrite16) + ret = _sd_iwrite16(pintfhdl, addr, val); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iwrite16 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return RTW_STATUS_CODE(ret); +} +int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val) +{ + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int ret = -1; + + _sd_iwrite32 = pintfhdl->io_ops._sd_iwrite32; + + if (_sd_iwrite32) + ret = _sd_iwrite32(pintfhdl, addr, val); + else + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" _sd_iwrite32 callback is NULL\n", FUNC_ADPT_ARG(adapter)); + + return RTW_STATUS_CODE(ret); +} + +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ + +#endif /* CONFIG_SDIO_HCI */ + +int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int ret; + _func_enter_; + _write8_async = pintfhdl->io_ops._write8_async; + + ret = _write8_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int ret; + _func_enter_; + _write16_async = pintfhdl->io_ops._write16_async; + val = rtw_cpu_to_le16(val); + ret = _write16_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} +int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val) +{ + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int ret; + _func_enter_; + _write32_async = pintfhdl->io_ops._write32_async; + val = rtw_cpu_to_le32(val); + ret = _write32_async(pintfhdl, addr, val); + _func_exit_; + + return RTW_STATUS_CODE(ret); +} + +void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + if (RTW_CANNOT_RUN(adapter)) { + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%s) OR bSurpriseRemoved(%s)" + , rtw_is_drv_stopped(adapter)?"True":"False" + , rtw_is_surprise_removed(adapter)?"True":"False")); + return; + } + + _read_mem = pintfhdl->io_ops._read_mem; + + _read_mem(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + _write_mem = pintfhdl->io_ops._write_mem; + + _write_mem(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _func_enter_; + + if (RTW_CANNOT_RUN(adapter)) { + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%s) OR bSurpriseRemoved(%s)" + , rtw_is_drv_stopped(adapter)?"True":"False" + , rtw_is_surprise_removed(adapter)?"True":"False")); + return; + } + + _read_port = pintfhdl->io_ops._read_port; + + _read_port(pintfhdl, addr, cnt, pmem); + + _func_exit_; + +} + +void _rtw_read_port_cancel(_adapter *adapter) +{ + void (*_read_port_cancel)(struct intf_hdl *pintfhdl); + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _read_port_cancel = pintfhdl->io_ops._read_port_cancel; + + RTW_DISABLE_FUNC(adapter, DF_RX_BIT); + + if(_read_port_cancel) + _read_port_cancel(pintfhdl); +} + +u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem) +{ + u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + u32 ret = _SUCCESS; + + _func_enter_; + + _write_port = pintfhdl->io_ops._write_port; + + ret = _write_port(pintfhdl, addr, cnt, pmem); + + _func_exit_; + + return ret; +} + +u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms) +{ + int ret = _SUCCESS; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem; + struct submit_ctx sctx; + + rtw_sctx_init(&sctx, timeout_ms); + pxmitbuf->sctx = &sctx; + + ret = _rtw_write_port(adapter, addr, cnt, pmem); + + if (ret == _SUCCESS) + ret = rtw_sctx_wait(&sctx, __func__); + + return ret; +} + +void _rtw_write_port_cancel(_adapter *adapter) +{ + void (*_write_port_cancel)(struct intf_hdl *pintfhdl); + struct io_priv *pio_priv = &adapter->iopriv; + struct intf_hdl *pintfhdl = &(pio_priv->intf); + + _write_port_cancel = pintfhdl->io_ops._write_port_cancel; + + RTW_DISABLE_FUNC(adapter, DF_TX_BIT); + + if(_write_port_cancel) + _write_port_cancel(pintfhdl); +} +int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops)) +{ + struct io_priv *piopriv = &padapter->iopriv; + struct intf_hdl *pintf = &piopriv->intf; + + if (set_intf_ops == NULL) + return _FAIL; + + piopriv->padapter = padapter; + pintf->padapter = padapter; + pintf->pintf_dev = adapter_to_dvobj(padapter); + + set_intf_ops(padapter,&pintf->io_ops); + + return _SUCCESS; +} + +/* +* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR +* @return _TRUE: +* @return _FALSE: +*/ +int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj) +{ + int ret = _FALSE; + int value; + if( (value=ATOMIC_INC_RETURN(&dvobj->continual_io_error)) > MAX_CONTINUAL_IO_ERR) { + DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR); + ret = _TRUE; + } else { + //DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value); + } + return ret; +} + +/* +* Set the continual_io_error of this @param dvobjprive to 0 +*/ +void rtw_reset_continual_io_error(struct dvobj_priv *dvobj) +{ + ATOMIC_SET(&dvobj->continual_io_error, 0); +} + +#ifdef DBG_IO + +u32 read_sniff_ranges[][2] = { + //{0x520, 0x523}, +}; + +u32 write_sniff_ranges[][2] = { + //{0x520, 0x523}, + //{0x4c, 0x4c}, +}; + +int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u32)/2; +int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u32)/2; + +bool match_read_sniff_ranges(u32 addr, u16 len) +{ + int i; + for (i = 0; i read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1]) + return _TRUE; + } + + return _FALSE; +} + +bool match_write_sniff_ranges(u32 addr, u16 len) +{ + int i; + for (i = 0; i write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1]) + return _TRUE; + } + + return _FALSE; +} + +struct rf_sniff_ent { + u8 path; + u16 reg; + u32 mask; +}; + +struct rf_sniff_ent rf_read_sniff_ranges[] = { + /* example for all path addr 0x55 with all RF Reg mask */ + /* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */ +}; + +struct rf_sniff_ent rf_write_sniff_ranges[] = { + /* example for all path addr 0x55 with all RF Reg mask */ + /* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */ +}; + +int rf_read_sniff_num = sizeof(rf_read_sniff_ranges)/sizeof(struct rf_sniff_ent); +int rf_write_sniff_num = sizeof(rf_write_sniff_ranges)/sizeof(struct rf_sniff_ent); + +bool match_rf_read_sniff_ranges(u8 path, u32 addr, u32 mask) +{ + int i; + + for (i = 0; i < rf_read_sniff_num; i++) { + if (rf_read_sniff_ranges[i].path == MAX_RF_PATH || rf_read_sniff_ranges[i].path == path) + if (addr == rf_read_sniff_ranges[i].reg && (mask & rf_read_sniff_ranges[i].mask)) + return _TRUE; + } + + return _FALSE; +} + +bool match_rf_write_sniff_ranges(u8 path, u32 addr, u32 mask) +{ + int i; + + for (i = 0; i < rf_write_sniff_num; i++) { + if (rf_write_sniff_ranges[i].path == MAX_RF_PATH || rf_write_sniff_ranges[i].path == path) + if (addr == rf_write_sniff_ranges[i].reg && (mask & rf_write_sniff_ranges[i].mask)) + return _TRUE; + } + + return _FALSE; +} + +u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u8 val = _rtw_read8(adapter, addr); + + if (match_read_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val); + + return val; +} + +u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u16 val = _rtw_read16(adapter, addr); + + if (match_read_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val); + + return val; +} + +u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u32 val = _rtw_read32(adapter, addr); + + if (match_read_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val); + + return val; +} + +int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val); + + return _rtw_write8(adapter, addr, val); +} +int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val); + + return _rtw_write16(adapter, addr, val); +} +int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val); + + return _rtw_write32(adapter, addr, val); +} +int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, length)) + DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length); + + return _rtw_writeN(adapter, addr, length, data); +} + +#ifdef CONFIG_SDIO_HCI +u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u8 val = _rtw_sd_f0_read8(adapter, addr); + + #if 0 + if (match_read_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_sd_f0_read8(0x%04x) return 0x%02x\n", caller, line, addr, val); + #endif + + return val; +} + +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u8 val = rtw_sd_iread8(adapter, addr); + + if (match_read_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_sd_iread8(0x%04x) return 0x%02x\n", caller, line, addr, val); + + return val; +} + +u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u16 val = _rtw_sd_iread16(adapter, addr); + + if (match_read_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_sd_iread16(0x%04x) return 0x%04x\n", caller, line, addr, val); + + return val; +} + +u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line) +{ + u32 val = _rtw_sd_iread32(adapter, addr); + + if (match_read_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_sd_iread32(0x%04x) return 0x%08x\n", caller, line, addr, val); + + return val; +} + +int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d rtw_sd_iwrite8(0x%04x, 0x%02x)\n", caller, line, addr, val); + + return _rtw_sd_iwrite8(adapter, addr, val); +} +int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d rtw_sd_iwrite16(0x%04x, 0x%04x)\n", caller, line, addr, val); + + return _rtw_sd_iwrite16(adapter, addr, val); +} +int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d rtw_sd_iwrite32(0x%04x, 0x%08x)\n", caller, line, addr, val); + + return _rtw_sd_iwrite32(adapter, addr, val); +} + +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ + +#endif /* CONFIG_SDIO_HCI */ + +#endif + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_query.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_query.c new file mode 100644 index 00000000..d7cd8859 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_query.c @@ -0,0 +1,192 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_QUERY_C_ + +#include + + +#ifdef PLATFORM_WINDOWS +// +// Added for WPA2-PSK, by Annie, 2005-09-20. +// +u8 +query_802_11_capability( + _adapter* Adapter, + u8* pucBuf, + u32 * pulOutLen +) +{ + static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] = + { + {Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled}, + {Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled}, + {Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled}, + {Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled}, + {Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled}, + {Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled}, + {Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled} + }; + static ULONG ulNumOfPairSupported = sizeof(szAuthEnc)/sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION); + NDIS_802_11_CAPABILITY * pCap = (NDIS_802_11_CAPABILITY *)pucBuf; + u8* pucAuthEncryptionSupported = (u8*) pCap->AuthenticationEncryptionSupported; + + + pCap->Length = sizeof(NDIS_802_11_CAPABILITY); + if(ulNumOfPairSupported > 1 ) + pCap->Length += (ulNumOfPairSupported-1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION); + + pCap->Version = 2; + pCap->NoOfPMKIDs = NUM_PMKID_CACHE; + pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported; + + if( sizeof (szAuthEnc) <= 240 ) // 240 = 256 - 4*4 // SecurityInfo.szCapability: only 256 bytes in size. + { + _rtw_memcpy( pucAuthEncryptionSupported, (u8*)szAuthEnc, sizeof (szAuthEnc) ); + *pulOutLen = pCap->Length; + return _TRUE; + } + else + { + *pulOutLen = 0; + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("_query_802_11_capability(): szAuthEnc size is too large.\n")); + return _FALSE; + } +} + +u8 query_802_11_association_information( _adapter *padapter,PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo) +{ + struct wlan_network *tgt_network; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv *psecuritypriv=&(padapter->securitypriv); + WLAN_BSSID_EX *psecnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + u8 * pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + unsigned char i,*auth_ie,*supp_ie; + + //NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); + _rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); + //pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + + //------------------------------------------------------ + // Association Request related information + //------------------------------------------------------ + // Req_1. AvailableRequestFixedIEs + if(psecnetwork!=NULL){ + + pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES|NDIS_802_11_AI_REQFI_CURRENTAPADDRESS; + pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short)* & psecnetwork->IEs[10]; + _rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress, + & psecnetwork->MacAddress, 6); + + pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); + + if(check_fwstate( pmlmepriv, _FW_UNDER_LINKING|_FW_LINKED)==_TRUE) + { + + if(psecuritypriv->ndisauthtype>=Ndis802_11AuthModeWPA2) + pDest[0] =48; //RSN Information Element + else + pDest[0] =221; //WPA(SSN) Information Element + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n Adapter->ndisauthtype==Ndis802_11AuthModeWPA)?0xdd:0x30 [%d]",pDest[0])); + supp_ie=&psecuritypriv->supplicant_ie[0]; + for(i=0;inetwork.IELength=%d\n\n", i,(int)psecnetwork->IELength)); + while((iRequestIELength += (2 + supp_ie[1+i]);// (2 + psecnetwork->IEs[1+i]+4); + + } + + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n psecnetwork != NULL,fwstate==_FW_UNDER_LINKING \n")); + + } + + + //------------------------------------------------------ + // Association Response related information + //------------------------------------------------------ + + if(check_fwstate( pmlmepriv, _FW_LINKED)==_TRUE) + { + tgt_network =&(pmlmepriv->cur_network); + if(tgt_network!=NULL){ + pAssocInfo->AvailableResponseFixedIEs = + NDIS_802_11_AI_RESFI_CAPABILITIES + |NDIS_802_11_AI_RESFI_ASSOCIATIONID + ; + + pAssocInfo->ResponseFixedIEs.Capabilities =(unsigned short)* & tgt_network->network.IEs[10]; + pAssocInfo->ResponseFixedIEs.StatusCode = 0; + pAssocInfo->ResponseFixedIEs.AssociationId =(unsigned short) tgt_network->aid; + + pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+pAssocInfo->RequestIELength; + auth_ie=&psecuritypriv->authenticator_ie[0]; + + for(i=0;i0){ + _rtw_memcpy((u8 *)&pDest[0],&auth_ie[1],i); + pAssocInfo->ResponseIELength =i; + } + + + pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength; + + + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n tgt_network != NULL,fwstate==_FW_LINKED \n")); + } + } + RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n exit query_802_11_association_information \n")); +_func_exit_; + + return _TRUE; +} +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_rtl.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_rtl.c new file mode 100644 index 00000000..99896597 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_rtl.c @@ -0,0 +1,1021 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_RTL_C_ + +#include + +#ifdef CONFIG_MP_INCLUDED +#include +#endif + +struct oid_obj_priv oid_rtl_seg_01_01[] = +{ + {1, &oid_null_function}, //0x80 + {1, &oid_null_function}, //0x81 + {1, &oid_null_function}, //0x82 + {1, &oid_null_function}, //0x83//OID_RT_SET_SNIFFER_MODE + {1, &oid_rt_get_signal_quality_hdl}, //0x84 + {1, &oid_rt_get_small_packet_crc_hdl}, //0x85 + {1, &oid_rt_get_middle_packet_crc_hdl}, //0x86 + {1, &oid_rt_get_large_packet_crc_hdl}, //0x87 + {1, &oid_rt_get_tx_retry_hdl}, //0x88 + {1, &oid_rt_get_rx_retry_hdl}, //0x89 + {1, &oid_rt_pro_set_fw_dig_state_hdl}, //0x8A + {1, &oid_rt_pro_set_fw_ra_state_hdl} , //0x8B + {1, &oid_null_function}, //0x8C + {1, &oid_null_function}, //0x8D + {1, &oid_null_function}, //0x8E + {1, &oid_null_function}, //0x8F + {1, &oid_rt_get_rx_total_packet_hdl}, //0x90 + {1, &oid_rt_get_tx_beacon_ok_hdl}, //0x91 + {1, &oid_rt_get_tx_beacon_err_hdl}, //0x92 + {1, &oid_rt_get_rx_icv_err_hdl}, //0x93 + {1, &oid_rt_set_encryption_algorithm_hdl}, //0x94 + {1, &oid_null_function}, //0x95 + {1, &oid_rt_get_preamble_mode_hdl}, //0x96 + {1, &oid_null_function}, //0x97 + {1, &oid_rt_get_ap_ip_hdl}, //0x98 + {1, &oid_rt_get_channelplan_hdl}, //0x99 + {1, &oid_rt_set_preamble_mode_hdl}, //0x9A + {1, &oid_rt_set_bcn_intvl_hdl}, //0x9B + {1, &oid_null_function}, //0x9C + {1, &oid_rt_dedicate_probe_hdl}, //0x9D + {1, &oid_null_function}, //0x9E + {1, &oid_null_function}, //0x9F + {1, &oid_null_function}, //0xA0 + {1, &oid_null_function}, //0xA1 + {1, &oid_null_function}, //0xA2 + {1, &oid_null_function}, //0xA3 + {1, &oid_null_function}, //0xA4 + {1, &oid_null_function}, //0xA5 + {1, &oid_null_function}, //0xA6 + {1, &oid_rt_get_total_tx_bytes_hdl}, //0xA7 + {1, &oid_rt_get_total_rx_bytes_hdl}, //0xA8 + {1, &oid_rt_current_tx_power_level_hdl}, //0xA9 + {1, &oid_rt_get_enc_key_mismatch_count_hdl}, //0xAA + {1, &oid_rt_get_enc_key_match_count_hdl}, //0xAB + {1, &oid_rt_get_channel_hdl}, //0xAC + {1, &oid_rt_set_channelplan_hdl}, //0xAD + {1, &oid_rt_get_hardware_radio_off_hdl}, //0xAE + {1, &oid_null_function}, //0xAF + {1, &oid_null_function}, //0xB0 + {1, &oid_null_function}, //0xB1 + {1, &oid_null_function}, //0xB2 + {1, &oid_null_function}, //0xB3 + {1, &oid_rt_get_key_mismatch_hdl}, //0xB4 + {1, &oid_null_function}, //0xB5 + {1, &oid_null_function}, //0xB6 + {1, &oid_null_function}, //0xB7 + {1, &oid_null_function}, //0xB8 + {1, &oid_null_function}, //0xB9 + {1, &oid_null_function}, //0xBA + {1, &oid_rt_supported_wireless_mode_hdl}, //0xBB + {1, &oid_rt_get_channel_list_hdl}, //0xBC + {1, &oid_rt_get_scan_in_progress_hdl}, //0xBD + {1, &oid_null_function}, //0xBE + {1, &oid_null_function}, //0xBF + {1, &oid_null_function}, //0xC0 + {1, &oid_rt_forced_data_rate_hdl}, //0xC1 + {1, &oid_rt_wireless_mode_for_scan_list_hdl}, //0xC2 + {1, &oid_rt_get_bss_wireless_mode_hdl}, //0xC3 + {1, &oid_rt_scan_with_magic_packet_hdl}, //0xC4 + {1, &oid_null_function}, //0xC5 + {1, &oid_null_function}, //0xC6 + {1, &oid_null_function}, //0xC7 + {1, &oid_null_function}, //0xC8 + {1, &oid_null_function}, //0xC9 + {1, &oid_null_function}, //0xCA + {1, &oid_null_function}, //0xCB + {1, &oid_null_function}, //0xCC + {1, &oid_null_function}, //0xCD + {1, &oid_null_function}, //0xCE + {1, &oid_null_function}, //0xCF + +}; + +struct oid_obj_priv oid_rtl_seg_01_03[] = +{ + {1, &oid_rt_ap_get_associated_station_list_hdl}, //0x00 + {1, &oid_null_function}, //0x01 + {1, &oid_rt_ap_switch_into_ap_mode_hdl}, //0x02 + {1, &oid_null_function}, //0x03 + {1, &oid_rt_ap_supported_hdl}, //0x04 + {1, &oid_rt_ap_set_passphrase_hdl}, //0x05 + +}; + +struct oid_obj_priv oid_rtl_seg_01_11[] = +{ + {1, &oid_null_function}, //0xC0 OID_RT_PRO_RX_FILTER + {1, &oid_null_function}, //0xC1 OID_CE_USB_WRITE_REGISTRY + {1, &oid_null_function}, //0xC2 OID_CE_USB_READ_REGISTRY + {1, &oid_null_function}, //0xC3 OID_RT_PRO_SET_INITIAL_GAIN + {1, &oid_null_function}, //0xC4 OID_RT_PRO_SET_BB_RF_STANDBY_MODE + {1, &oid_null_function}, //0xC5 OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE + {1, &oid_null_function}, //0xC6 OID_RT_PRO_SET_TX_CHARGE_PUMP + {1, &oid_null_function}, //0xC7 OID_RT_PRO_SET_RX_CHARGE_PUMP + {1, &oid_rt_pro_rf_write_registry_hdl}, //0xC8 + {1, &oid_rt_pro_rf_read_registry_hdl}, //0xC9 + {1, &oid_null_function} //0xCA OID_RT_PRO_QUERY_RF_TYPE + +}; + +struct oid_obj_priv oid_rtl_seg_03_00[] = +{ + {1, &oid_null_function}, //0x00 + {1, &oid_rt_get_connect_state_hdl}, //0x01 + {1, &oid_null_function}, //0x02 + {1, &oid_null_function}, //0x03 + {1, &oid_rt_set_default_key_id_hdl}, //0x04 + + +}; + + +//************** oid_rtl_seg_01_01 section start ************** + +NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + + _func_enter_; + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len >= sizeof(struct setdig_parm)) + { + //DEBUG_ERR(("===> oid_rt_pro_set_fw_dig_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); + if(!rtw_setfwdig_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf ))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_NOT_ACCEPTED; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv* poid_par_priv) +{ + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + + _func_enter_; + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + + _irqlevel_changed_(&oldirql,LOWER); + + if(poid_par_priv->information_buf_len >= sizeof(struct setra_parm)) + { + //DEBUG_ERR(("===> oid_rt_pro_set_fw_ra_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf ))); + if(!rtw_setfwra_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf ))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_NOT_ACCEPTED; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + //DEBUG_ERR(("<**********************oid_rt_get_signal_quality_hdl \n")); + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + +#if 0 + if(pMgntInfo->mAssoc || pMgntInfo->mIbss) + { + ulInfo = pAdapter->RxStats.SignalQuality; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + ulInfo = 0xffffffff; // It stands for -1 in 4-byte integer. + } + break; +#endif + + return status; +} + +//------------------------------------------------------------------------------ + +NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_smallpacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_middlepacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_largepacket_crcerr; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len >= sizeof(ULONG) ) + { + *(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_pkts + padapter->recvpriv.rx_drop; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(u32)) + { + //_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); + *(uint *)poid_par_priv->information_buf = padapter->recvpriv.rx_icv_err; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG preamblemode = 0 ; + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + if(padapter->registrypriv.preamble == PREAMBLE_LONG) + preamblemode = 0; + else if (padapter->registrypriv.preamble == PREAMBLE_AUTO) + preamblemode = 1; + else if (padapter->registrypriv.preamble == PREAMBLE_SHORT) + preamblemode = 2; + + + *(ULONG *)poid_par_priv->information_buf = preamblemode ; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + *(u16 *)poid_par_priv->information_buf = padapter->mlmepriv.ChannelPlan ; + + return status; +} +NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + padapter->mlmepriv.ChannelPlan = *(u16 *)poid_par_priv->information_buf ; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG preamblemode = 0; + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + preamblemode = *(ULONG *)poid_par_priv->information_buf ; + if( preamblemode == 0) + padapter->registrypriv.preamble = PREAMBLE_LONG; + else if (preamblemode==1 ) + padapter->registrypriv.preamble = PREAMBLE_AUTO; + else if ( preamblemode==2 ) + padapter->registrypriv.preamble = PREAMBLE_SHORT; + + *(ULONG *)poid_par_priv->information_buf = preamblemode ; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + *(u64 *)poid_par_priv->information_buf = padapter->xmitpriv.tx_bytes; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len>= sizeof(ULONG)) + { + //_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32)); + *(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_bytes; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else + { + status = NDIS_STATUS_INVALID_LENGTH ; + } + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + NDIS_802_11_CONFIGURATION *pnic_Config; + + ULONG channelnum; + + _func_enter_; + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + pnic_Config = &pmlmepriv->cur_network.network.Configuration; + else + pnic_Config = &padapter->registrypriv.dev_network.Configuration; + + channelnum = pnic_Config->DSConfig; + *(ULONG *)poid_par_priv->information_buf = channelnum; + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + _func_exit_; + + + + return status; +} +NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + ULONG ulInfo = 0 ; + //DEBUG_ERR(("<**********************oid_rt_supported_wireless_mode_hdl \n")); + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if(poid_par_priv->information_buf_len >= sizeof(ULONG)){ + ulInfo |= 0x0100; //WIRELESS_MODE_B + ulInfo |= 0x0200; //WIRELESS_MODE_G + ulInfo |= 0x0400; //WIRELESS_MODE_A + + *(ULONG *) poid_par_priv->information_buf = ulInfo; + //DEBUG_ERR(("<===oid_rt_supported_wireless_mode %x\n",ulInfo)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } + else{ + status = NDIS_STATUS_INVALID_LENGTH; + } + + return status; +} +NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + + +NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +//************** oid_rtl_seg_01_01 section end ************** + +//************** oid_rtl_seg_01_03 section start ************** +NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + return status; +} +NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} + +//************** oid_rtl_seg_01_03 section end ************** + +//**************** oid_rtl_seg_01_11 section start **************** +NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + _func_enter_; + //DEBUG_ERR(("<**********************oid_rt_pro_rf_write_registry_hdl \n")); + if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3)) + { + //RegOffsetValue - The offset of RF register to write. + //RegDataWidth - The data width of RF register to write. + //RegDataValue - The value to write. + //RegOffsetValue = *((unsigned long*)InformationBuffer); + //RegDataWidth = *((unsigned long*)InformationBuffer+1); + //RegDataValue = *((unsigned long*)InformationBuffer+2); + if(!rtw_setrfreg_cmd(Adapter, + *(unsigned char*)poid_par_priv->information_buf, + (unsigned long)(*((unsigned long*)poid_par_priv->information_buf+2)))) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + + } + else{ + status = NDIS_STATUS_INVALID_LENGTH; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; + + return status; +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + _irqL oldirql; + _func_enter_; + + //DEBUG_ERR(("<**********************oid_rt_pro_rf_read_registry_hdl \n")); + if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql,LOWER); + if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3)) + { + if(Adapter->mppriv.act_in_progress == _TRUE) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + else + { + //init workparam + Adapter->mppriv.act_in_progress = _TRUE; + Adapter->mppriv.workparam.bcompleted= _FALSE; + Adapter->mppriv.workparam.act_type = MPT_READ_RF; + Adapter->mppriv.workparam.io_offset = *(unsigned long*)poid_par_priv->information_buf; + Adapter->mppriv.workparam.io_value = 0xcccccccc; + + //RegOffsetValue - The offset of RF register to read. + //RegDataWidth - The data width of RF register to read. + //RegDataValue - The value to read. + //RegOffsetValue = *((unsigned long*)InformationBuffer); + //RegDataWidth = *((unsigned long*)InformationBuffer+1); + //RegDataValue = *((unsigned long*)InformationBuffer+2); + if(!rtw_getrfreg_cmd(Adapter, + *(unsigned char*)poid_par_priv->information_buf, + (unsigned char*)&Adapter->mppriv.workparam.io_value)) + { + status = NDIS_STATUS_NOT_ACCEPTED; + } + } + + + } + else { + status = NDIS_STATUS_INVALID_LENGTH; + } + _irqlevel_changed_(&oldirql,RAISE); + _func_exit_; +#endif + return status; +} + +//**************** oid_rtl_seg_01_11 section end**************** + + +//************** oid_rtl_seg_03_00 section start ************** +enum _CONNECT_STATE_{ + CHECKINGSTATUS, + ASSOCIATED, + ADHOCMODE, + NOTASSOCIATED +}; + +NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + ULONG ulInfo; + + if(poid_par_priv->type_of_oid != QUERY_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + // nStatus==0 CheckingStatus + // nStatus==1 Associated + // nStatus==2 AdHocMode + // nStatus==3 NotAssociated + + if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + ulInfo = CHECKINGSTATUS; + else if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + ulInfo = ASSOCIATED; + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)== _TRUE) + ulInfo = ADHOCMODE; + else + ulInfo = NOTASSOCIATED ; + + *(ULONG *)poid_par_priv->information_buf = ulInfo; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +#if 0 + // Rearrange the order to let the UI still shows connection when scan is in progress + RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("===> Query OID_RT_GET_CONNECT_STATE.\n")); + if(pMgntInfo->mAssoc) + ulInfo = 1; + else if(pMgntInfo->mIbss) + ulInfo = 2; + else if(pMgntInfo->bScanInProgress) + ulInfo = 0; + else + ulInfo = 3; + ulInfoLen = sizeof(ULONG); + RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("<=== Query OID_RT_GET_CONNECT_STATE: %d\n", ulInfo)); +#endif + + return status; +} + +NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv* poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + + if(poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + return status; +} +//************** oid_rtl_seg_03_00 section end ************** + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_set.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_set.c new file mode 100644 index 00000000..7ba82cf5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ioctl_set.c @@ -0,0 +1,1477 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_IOCTL_SET_C_ + +#include +#include + + +extern void indicate_wx_scan_complete_event(_adapter *padapter); + +#define IS_MAC_ADDRESS_BROADCAST(addr) \ +( \ + ( (addr[0] == 0xff) && (addr[1] == 0xff) && \ + (addr[2] == 0xff) && (addr[3] == 0xff) && \ + (addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \ +) + +u8 rtw_validate_bssid(u8 *bssid) +{ + u8 ret = _TRUE; + + if (is_zero_mac_addr(bssid) + || is_broadcast_mac_addr(bssid) + || is_multicast_mac_addr(bssid) + ) { + ret = _FALSE; + } + + return ret; +} + +u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid) +{ + u8 i; + u8 ret=_TRUE; + +_func_enter_; + + if (ssid->SsidLength > 32) { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n")); + ret= _FALSE; + goto exit; + } + +#ifdef CONFIG_VALIDATE_SSID + for(i = 0; i < ssid->SsidLength; i++) + { + //wifi, printable ascii code must be supported + if(!( (ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e) )){ + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n")); + ret= _FALSE; + break; + } + } +#endif /* CONFIG_VALIDATE_SSID */ + +exit: + +_func_exit_; + + return ret; +} + +u8 rtw_do_join(_adapter * padapter); +u8 rtw_do_join(_adapter * padapter) +{ + _irqL irqL; + _list *plist, *phead; + u8* pibss = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + u8 ret=_SUCCESS; + +_func_enter_; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + plist = get_next(phead); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n rtw_do_join: phead = %p; plist = %p \n\n\n", phead, plist)); + + pmlmepriv->cur_network.join_res = -2; + + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + pmlmepriv->pscanned = plist; + + pmlmepriv->to_join = _TRUE; + + if(_rtw_queue_empty(queue)== _TRUE) + { + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + //when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty + //we try to issue sitesurvey firstly + + if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE + || rtw_to_roam(padapter) > 0 + ) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_do_join(): site survey if scanned_queue is empty\n.")); + // submit site_survey_cmd + if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) { + pmlmepriv->to_join = _FALSE; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_do_join(): site survey return error\n.")); + } + } + else + { + pmlmepriv->to_join = _FALSE; + ret = _FAIL; + } + + goto exit; + } + else + { + int select_ret; + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS) + { + pmlmepriv->to_join = _FALSE; + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + } + else + { + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) + { + // submit createbss_cmd to change to a ADHOC_MASTER + + //pmlmepriv->lock has been acquired by caller... + WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network); + + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + + pibss = padapter->registrypriv.dev_network.MacAddress; + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(padapter); + + rtw_generate_random_ibss(pibss); + + if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error=>do_goin: rtw_create_ibss_cmd status FAIL***\n")); + ret = _FALSE; + goto exit; + } + + pmlmepriv->to_join = _FALSE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n ")); + + } + else + { + // can't associate ; reset under-linking + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + +#if 0 + if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) + { + if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) + { + // for funk to do roaming + // funk will reconnect, but funk will not sitesurvey before reconnect + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming")); + if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) + rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); + } + + } +#endif + + //when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue + //we try to issue sitesurvey firstly + if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE + || rtw_to_roam(padapter) > 0 + ) + { + //DBG_871X("rtw_do_join() when no desired bss in scanning queue \n"); + if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){ + pmlmepriv->to_join = _FALSE; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("do_join(): site survey return error\n.")); + } + } + else + { + ret = _FAIL; + pmlmepriv->to_join = _FALSE; + } + } + + } + + } + +exit: + +_func_exit_; + + return ret; +} + +#ifdef PLATFORM_WINDOWS +u8 rtw_pnp_set_power_wakeup(_adapter* padapter) +{ + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_wakeup!!!\n")); + + res = rtw_setstandby_cmd(padapter, 0); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_wakeup!!!\n")); + +_func_exit_; + + return res; +} + +u8 rtw_pnp_set_power_sleep(_adapter* padapter) +{ + u8 res=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_sleep!!!\n")); + //DbgPrint("+rtw_pnp_set_power_sleep\n"); + + res = rtw_setstandby_cmd(padapter, 1); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_sleep!!!\n")); + +_func_exit_; + + return res; +} + +u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults) +{ +_func_enter_; + + switch( reloadDefaults) + { + case Ndis802_11ReloadWEPKeys: + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("SetInfo OID_802_11_RELOAD_DEFAULTS : Ndis802_11ReloadWEPKeys\n")); + break; + } + + // SecClearAllKeys(Adapter); + // 8711 CAM was not for En/Decrypt only + // so, we can't clear all keys. + // should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM + + //TO DO... + +_func_exit_; + + return _TRUE; +} + +u8 set_802_11_test(_adapter* padapter, NDIS_802_11_TEST *test) +{ + u8 ret=_TRUE; + +_func_enter_; + + switch(test->Type) + { + case 1: + NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8); + NdisMIndicateStatusComplete(padapter->hndis_adapter); + break; + + case 2: + NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI)); + NdisMIndicateStatusComplete(padapter->hndis_adapter); + break; + + default: + ret=_FALSE; + break; + } + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_pmkid(_adapter* padapter, NDIS_802_11_PMKID *pmkid) +{ + u8 ret=_SUCCESS; + + return ret; +} + +#endif + +u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) +{ + _irqL irqL; + u8 status=_SUCCESS; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid); + + if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || + (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) + { + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + + DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); + + if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) + { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) + goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. + } else { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) )); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) )); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); + pmlmepriv->assoc_by_bssid=_TRUE; + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("rtw_set_802_11_bssid: status=%d\n", status)); + +_func_exit_; + + return status; +} + +u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) +{ + _irqL irqL; + u8 status = _SUCCESS; + u32 cur_time = 0; + + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *pnetwork = &pmlmepriv->cur_network; + +_func_enter_; + + DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n", + ssid->Ssid, get_fwstate(pmlmepriv)); + + if (!rtw_is_hw_init_completed(padapter)) { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, + ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); + + if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && + (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) + { + if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("Set SSID is the same ssid, fw_state=0x%08x\n", + get_fwstate(pmlmepriv))); + + if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE) + { + //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + else + { + goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. + } + } +#ifdef CONFIG_LPS + else { + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); + } +#endif + } + else + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + } + } + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + if (rtw_validate_ssid(ssid) == _FALSE) { + status = _FAIL; + goto release_mlme_lock; + } + + _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); + pmlmepriv->assoc_by_bssid=_FALSE; + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("-rtw_set_802_11_ssid: status=%d\n", status)); + +_func_exit_; + + return status; + +} + +u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid) +{ + _irqL irqL; + u8 status = _SUCCESS; + u32 cur_time = 0; + bool bssid_valid = _TRUE; + bool ssid_valid = _TRUE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if (!ssid || rtw_validate_ssid(ssid) == _FALSE) + ssid_valid = _FALSE; + + if (!bssid || rtw_validate_bssid(bssid) == _FALSE) + bssid_valid = _FALSE; + + if (ssid_valid == _FALSE && bssid_valid == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n", + FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid); + status = _FAIL; + goto exit; + } + + if (!rtw_is_hw_init_completed(padapter)) { + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, + ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); + status = _FAIL; + goto exit; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" fw_state=0x%08x\n", + FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + goto handle_tkip_countermeasure; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + goto release_mlme_lock; + } + +handle_tkip_countermeasure: + if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { + status = _FAIL; + goto release_mlme_lock; + } + + if (ssid && ssid_valid) + _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); + else + _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID)); + + if (bssid && bssid_valid) { + _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); + pmlmepriv->assoc_by_bssid = _TRUE; + } else { + pmlmepriv->assoc_by_bssid = _FALSE; + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + pmlmepriv->to_join = _TRUE; + } + else { + status = rtw_do_join(padapter); + } + +release_mlme_lock: + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +exit: + +_func_exit_; + + return status; +} + +u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter, + NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode); + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_, + ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n", + *pold_state, networktype, get_fwstate(pmlmepriv))); + + if(*pold_state != networktype) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!")); + //DBG_871X("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); + + if(*pold_state==Ndis802_11APMode) + { + //change to other mode from Ndis802_11APMode + cur_network->join_res = -1; + +#ifdef CONFIG_NATIVEAP_MLME + stop_ap_mode(padapter); +#endif + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS)) + rtw_disassoc_cmd(padapter, 0, _TRUE); + + if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) ) + rtw_free_assoc_resources(padapter, 1); + + if((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS)) + { + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + rtw_indicate_disconnect(padapter); //will clr Linked_state; before this function, we must have chked whether issue dis-assoc_cmd or not + } + } + + *pold_state = networktype; + + _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE); + + switch(networktype) + { + case Ndis802_11IBSS: + set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); + break; + + case Ndis802_11Infrastructure: + set_fwstate(pmlmepriv, WIFI_STATION_STATE); + break; + + case Ndis802_11APMode: + set_fwstate(pmlmepriv, WIFI_AP_STATE); +#ifdef CONFIG_NATIVEAP_MLME + start_ap_mode(padapter); + //rtw_indicate_connect(padapter); +#endif + + break; + + case Ndis802_11AutoUnknown: + case Ndis802_11InfrastructureMax: + break; + case Ndis802_11Monitor: + set_fwstate(pmlmepriv, WIFI_MONITOR_STATE); + break; + } + + //SecClearAllKeys(adapter); + + //RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", + // get_fwstate(pmlmepriv) )); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + } + +_func_exit_; + + return _TRUE; +} + + +u8 rtw_set_802_11_disassociate(_adapter *padapter) +{ + _irqL irqL; + struct mlme_priv * pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n")); + + rtw_disassoc_cmd(padapter, 0, _TRUE); + rtw_indicate_disconnect(padapter); + //modify for CONFIG_IEEE80211W, none 11w can use it + rtw_free_assoc_resources_cmd(padapter); + if (_FAIL == rtw_pwr_wakeup(padapter)) + DBG_871X("%s(): rtw_pwr_wakeup fail !!!\n",__FUNCTION__); + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +_func_exit_; + + return _TRUE; +} + +u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + u8 res=_TRUE; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("+rtw_set_802_11_bssid_list_scan(), fw_state=%x\n", get_fwstate(pmlmepriv))); + + if (padapter == NULL) { + res=_FALSE; + goto exit; + } + if (!rtw_is_hw_init_completed(padapter)) { + res = _FALSE; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n===rtw_set_802_11_bssid_list_scan:hw_init_completed==_FALSE===\n")); + goto exit; + } + + if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) || + (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) + { + // Scan or linking is in progress, do nothing. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv))); + res = _TRUE; + + if(check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))== _TRUE){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n")); + } else { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###pmlmepriv->sitesurveyctrl.traffic_busy==_TRUE\n\n")); + } + } else { + if (rtw_is_scan_deny(padapter)) { + DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter)); + indicate_wx_scan_complete_event(padapter); + return _SUCCESS; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + } +exit: + +_func_exit_; + + return res; +} + +u8 rtw_set_802_11_authentication_mode(_adapter* padapter, NDIS_802_11_AUTHENTICATION_MODE authmode) +{ + struct security_priv *psecuritypriv = &padapter->securitypriv; + int res; + u8 ret; + +_func_enter_; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_auth.mode(): mode=%x\n", authmode)); + + psecuritypriv->ndisauthtype=authmode; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d", psecuritypriv->ndisauthtype)); + + if(psecuritypriv->ndisauthtype>3) + psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_8021X; + +#ifdef CONFIG_WAPI_SUPPORT + if(psecuritypriv->ndisauthtype == 6) + psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_WAPI; +#endif + + res=rtw_set_auth(padapter,psecuritypriv); + + if(res==_SUCCESS) + ret=_TRUE; + else + ret=_FALSE; + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_add_wep(_adapter* padapter, NDIS_802_11_WEP *wep){ + + u8 bdefaultkey; + u8 btransmitkey; + sint keyid,res; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + u8 ret=_SUCCESS; + +_func_enter_; + + bdefaultkey=(wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; //for ??? + btransmitkey= (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; //for ??? + keyid=wep->KeyIndex & 0x3fffffff; + + if(keyid>=4) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MgntActrtw_set_802_11_add_wep:keyid>4=>fail\n")); + ret=_FALSE; + goto exit; + } + + switch(wep->KeyLength) + { + case 5: + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=5\n")); + break; + case 13: + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=13\n")); + break; + default: + psecuritypriv->dot11PrivacyAlgrthm=_NO_PRIVACY_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n")); + break; + } + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:befor memcpy, wep->KeyLength=0x%x wep->KeyIndex=0x%x keyid =%x\n",wep->KeyLength,wep->KeyIndex,keyid)); + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial),wep->KeyLength); + + psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength; + + psecuritypriv->dot11PrivacyKeyIndex=keyid; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x \n", + psecuritypriv->dot11DefKey[keyid].skey[0],psecuritypriv->dot11DefKey[keyid].skey[1],psecuritypriv->dot11DefKey[keyid].skey[2], + psecuritypriv->dot11DefKey[keyid].skey[3],psecuritypriv->dot11DefKey[keyid].skey[4],psecuritypriv->dot11DefKey[keyid].skey[5], + psecuritypriv->dot11DefKey[keyid].skey[6],psecuritypriv->dot11DefKey[keyid].skey[7],psecuritypriv->dot11DefKey[keyid].skey[8], + psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11], + psecuritypriv->dot11DefKey[keyid].skey[12])); + + res=rtw_set_key(padapter,psecuritypriv, keyid, 1, _TRUE); + + if(res==_FAIL) + ret= _FALSE; +exit: + +_func_exit_; + + return ret; + +} + +u8 rtw_set_802_11_remove_wep(_adapter* padapter, u32 keyindex){ + + u8 ret=_SUCCESS; + +_func_enter_; + + if (keyindex >= 0x80000000 || padapter == NULL){ + + ret=_FALSE; + goto exit; + + } + else + { + int res; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + if( keyindex < 4 ){ + + _rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16); + + res=rtw_set_key(padapter,psecuritypriv,keyindex, 0, _TRUE); + + psecuritypriv->dot11DefKeylen[keyindex]=0; + + if(res==_FAIL) + ret=_FAIL; + + } + else + { + ret=_FAIL; + } + + } + +exit: + +_func_exit_; + + return ret; + +} + +u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){ + + uint encryptionalgo; + u8 * pbssid; + struct sta_info *stainfo; + u8 bgroup = _FALSE; + u8 bgrouptkey = _FALSE;//can be remove later + u8 ret=_SUCCESS; + +_func_enter_; + + if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){ + + // It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, + // it must fail the request and return NDIS_STATUS_INVALID_DATA. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex)); + ret= _FAIL; + goto exit; + } + + if(key->KeyIndex & 0x40000000) + { + // Pairwise key + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n")); + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid); + + if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n")); + encryptionalgo=stainfo->dot118021XPrivacy; + } + else{ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n")); + encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; + } + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo )); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm)); + + if((stainfo!=NULL)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy)); + } + + if(key->KeyIndex & 0x000000FF){ + // The key index is specified in the lower 8 bits by values of zero to 255. + // The key index should be set to zero for a Pairwise key, and the driver should fail with + // NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n")); + ret= _FAIL; + goto exit; + } + + // check BSSID + if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){ + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n")); + ret= _FALSE; + goto exit; + } + + // Check key length for TKIP. + //if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) + if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){ + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength)); + ret=_FAIL; + goto exit; + + } + + // Check key length for AES. + if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) { + // For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. + if(key->KeyLength == 32) { + key->KeyLength = 16; + } else { + ret= _FAIL; + goto exit; + } + } + + /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. -> modify checking condition*/ + if (((encryptionalgo == _WEP40_) && (key->KeyLength != 5)) || ((encryptionalgo == _WEP104_) && (key->KeyLength != 13))) { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength)); + ret=_FAIL; + goto exit; + } + + bgroup = _FALSE; + + // Check the pairwise key. Added by Annie, 2005-07-06. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + + } + else + { + // Group key - KeyIndex(BIT30==0) + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n")); + + + // when add wep key through add key and didn't assigned encryption type before + if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0)) + { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy)); + + switch(key->KeyLength) + { + case 5: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + case 13: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + default: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength)); + break; + } + + encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm)); + + } + else + { + encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength)); + + } + + if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) { + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n")); + ret= _FAIL; + goto exit; + } + + // Check key length for TKIP + if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) { + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength)); + ret= _FAIL; + goto exit; + + } else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) { + + // Check key length for AES + // For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength)); + ret= _FAIL; + goto exit; + } + + // Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. + if((encryptionalgo== _AES_) && (key->KeyLength == 32) ) { + key->KeyLength = 16; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) ); + } + + if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000 + bgrouptkey = _TRUE; + } + + if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE)) + { + bgrouptkey = _TRUE; + } + + bgroup = _TRUE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") ); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") ); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3))); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ; + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")); + + } + + // If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). + if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_ || encryptionalgo== _WEP104_)) + { + u8 ret; + u32 keyindex; + u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength; + NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n")); + + wep->Length = len; + keyindex = key->KeyIndex&0x7fffffff; + wep->KeyIndex = keyindex ; + wep->KeyLength = key->KeyLength; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n")); + + _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength); + _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength); + + padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength; + padapter->securitypriv.dot11PrivacyKeyIndex=keyindex; + + ret = rtw_set_802_11_add_wep(padapter, wep); + + goto exit; + + } + + if(key->KeyIndex & 0x20000000){ + // SetRSC + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n")); + if(bgroup == _TRUE) + { + NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; + _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8); + } + else + { + NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL; + _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8); + } + + } + + // Indicate this key idx is used for TX + // Save the key in KeyMaterial + if(bgroup == _TRUE) // Group transmit key + { + int res; + + if(bgrouptkey == _TRUE) + { + padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex; + } + + if((key->KeyIndex&0x3) == 0){ + ret = _FAIL; + goto exit; + } + + _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16); + + if((key->KeyIndex & 0x10000000)) + { + _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); + _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); + + } + else + { + _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8); + _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5], + padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7])); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n")); + + } + + //set group key by index + _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength); + + key->KeyIndex=key->KeyIndex & 0x03; + + padapter->securitypriv.binstallGrpkey=_TRUE; + + padapter->securitypriv.bcheck_grpkey=_FALSE; + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key")); + + res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1, _TRUE); + + if(res==_FAIL) + ret= _FAIL; + + goto exit; + + } + else // Pairwise Key + { + u8 res; + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); + + if(stainfo!=NULL) + { + _rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer + + _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16); + + if(encryptionalgo== _TKIP_) + { + padapter->securitypriv.busetkipkey=_FALSE; + + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n")); + + // if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] + if((key->KeyIndex & 0x10000000)){ + _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8); + _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8); + + } else { + _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8); + _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8); + + } + + } + else if(encryptionalgo == _AES_) + { + + } + + + //Set key to CAM through H2C command + #if 0 + if(bgrouptkey)//never go to here + { + res=rtw_setstakey_cmd(padapter, stainfo, GROUP_KEY, _TRUE); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n")); + } + else{ + res=rtw_setstakey_cmd(padapter, stainfo, UNICAST_KEY, _TRUE); + RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); + } + #else + + res = rtw_setstakey_cmd(padapter, stainfo, UNICAST_KEY, _TRUE); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n")); + #endif + + if(res ==_FALSE) + ret= _FAIL; + + } + + } + +exit: + +_func_exit_; + + return ret; +} + +u8 rtw_set_802_11_remove_key(_adapter* padapter, NDIS_802_11_REMOVE_KEY *key){ + + uint encryptionalgo; + u8 * pbssid; + struct sta_info *stainfo; + u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE: _TRUE; + u8 keyIndex = (u8)key->KeyIndex & 0x03; + u8 ret=_SUCCESS; + +_func_enter_; + + if ((key->KeyIndex & 0xbffffffc) > 0) { + ret=_FAIL; + goto exit; + } + + if (bgroup == _TRUE) { + encryptionalgo= padapter->securitypriv.dot118021XGrpPrivacy; + // clear group key by index + //NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN); + //Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0; + + _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16); + + //! \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. + + } else { + + pbssid=get_bssid(&padapter->mlmepriv); + stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid ); + if(stainfo !=NULL){ + encryptionalgo=stainfo->dot118021XPrivacy; + + // clear key by BSSID + _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16); + + //! \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. + + } + else{ + ret= _FAIL; + goto exit; + } + } + +exit: + +_func_exit_; + + return _TRUE; + +} + +/* +* rtw_get_cur_max_rate - +* @adapter: pointer to _adapter structure +* +* Return 0 or 100Kbps +*/ +u16 rtw_get_cur_max_rate(_adapter *adapter) +{ + int i = 0; + u16 rate = 0, max_rate = 0; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + struct sta_info *psta = NULL; + u8 short_GI=0; +#ifdef CONFIG_80211N_HT + u8 rf_type = 0; +#endif + +#ifdef CONFIG_MP_INCLUDED + if (adapter->registrypriv.mp_mode == 1) + { + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + return 0; + } +#endif + + if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)) + return 0; + + psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv)); + if (psta == NULL) + return 0; + + short_GI = query_ra_short_GI(psta); + +#ifdef CONFIG_80211N_HT + if (IsSupportedHT(psta->wireless_mode)) { + rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + max_rate = rtw_mcs_rate( + rf_type, + ((psta->bw_mode == CHANNEL_WIDTH_40)?1:0), + short_GI, + psta->htpriv.ht_cap.supp_mcs_set + ); + } +#ifdef CONFIG_80211AC_VHT + else if (IsSupportedVHT(psta->wireless_mode)) { + max_rate = ((rtw_vht_mcs_to_data_rate(psta->bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10; + } +#endif //CONFIG_80211AC_VHT + else +#endif //CONFIG_80211N_HT + { + while( (pcur_bss->SupportedRates[i]!=0) && (pcur_bss->SupportedRates[i]!=0xFF)) + { + rate = pcur_bss->SupportedRates[i]&0x7F; + if(rate>max_rate) + max_rate = rate; + i++; + } + + max_rate = max_rate*10/2; + } + + return max_rate; +} + +/* +* rtw_set_scan_mode - +* @adapter: pointer to _adapter structure +* @scan_mode: +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode) +{ + if(scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE) + return _FAIL; + + adapter->mlmepriv.scan_mode = scan_mode; + + return _SUCCESS; +} + +/* +* rtw_set_channel_plan - +* @adapter: pointer to _adapter structure +* @channel_plan: +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan) +{ + struct registry_priv *pregistrypriv = &adapter->registrypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + //handle by cmd_thread to sync with scan operation + return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1); +} + +/* +* rtw_set_country - +* @adapter: pointer to _adapter structure +* @country_code: string of country code +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_country(_adapter *adapter, const char *country_code) +{ +#ifdef CONFIG_RTW_IOCTL_SET_COUNTRY + return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1); +#else + return _FAIL; +#endif +} + +/* +* rtw_set_band - +* @adapter: pointer to _adapter structure +* @band: band to set +* +* Return _SUCCESS or _FAIL +*/ +int rtw_set_band(_adapter *adapter, u8 band) +{ + if (rtw_band_valid(band)) { + DBG_871X(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band); + adapter->setband = band; + return _SUCCESS; + } + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band); + return _FAIL; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_iol.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_iol.c new file mode 100644 index 00000000..3524e1c5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_iol.c @@ -0,0 +1,390 @@ +/****************************************************************************** + * + * 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 + +#ifdef CONFIG_IOL +struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter) +{ + struct xmit_frame *xmit_frame; + struct xmit_buf *xmitbuf; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); + +#if 1 + if ((xmit_frame = rtw_alloc_xmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__); + goto exit; + } + + if ((xmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL) + { + DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__); + rtw_free_xmitframe(pxmitpriv, xmit_frame); + xmit_frame=NULL; + goto exit; + } + + xmit_frame->frame_tag = MGNT_FRAMETAG; + xmit_frame->pxmitbuf = xmitbuf; + xmit_frame->buf_addr = xmitbuf->pbuf; + xmitbuf->priv_data = xmit_frame; + + pattrib = &xmit_frame->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = QSLT_BEACON;//Beacon + pattrib->subtype = WIFI_BEACON; + pattrib->pktlen = pattrib->last_txcmdsz = 0; + +#else + if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__); + } + else { + pattrib = &xmit_frame->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = QSLT_BEACON; + pattrib->pktlen = pattrib->last_txcmdsz = 0; + } +#endif + +exit: + return xmit_frame; +} + + +int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) +{ + struct pkt_attrib *pattrib = &xmit_frame->attrib; + u16 buf_offset; + u32 ori_len; + + buf_offset = TXDESC_OFFSET; + ori_len = buf_offset+pattrib->pktlen; + + //check if the io_buf can accommodate new cmds + if(ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) { + DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__ + , ori_len + cmd_len + 8, MAX_XMITBUF_SZ); + return _FAIL; + } + + _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len); + pattrib->pktlen += cmd_len; + pattrib->last_txcmdsz += cmd_len; + + //DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); + + return _SUCCESS; +} + +bool rtw_IOL_applied(ADAPTER *adapter) +{ + if(1 == adapter->registrypriv.fw_iol) + return _TRUE; + +#ifdef CONFIG_USB_HCI + if((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter))) + return _TRUE; +#endif + + return _FALSE; +} + +int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) +{ + return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms,bndy_cnt); +} + +#ifdef CONFIG_IOL_NEW_GENERATION +int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) +{ + return _SUCCESS; +} +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask) +{ + struct ioreg_cfg cmd = {8,IOREG_CMD_WB_REG,0x0, 0x0,0x0}; + + //RTW_PUT_LE16((u8*)&cmd.address, addr); + //RTW_PUT_LE32((u8*)&cmd.value, (u32)value); + cmd.address = cpu_to_le16(addr); + cmd.data = cpu_to_le32(value); + + if(mask!=0xFF) + { + cmd.length = 12; + //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); + cmd.mask = cpu_to_le32(mask); + } + + //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length); + +} +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask) +{ + struct ioreg_cfg cmd = {8,IOREG_CMD_WW_REG,0x0, 0x0,0x0}; + + //RTW_PUT_LE16((u8*)&cmd.address, addr); + //RTW_PUT_LE32((u8*)&cmd.value, (u32)value); + cmd.address = cpu_to_le16(addr); + cmd.data = cpu_to_le32(value); + + if(mask!=0xFFFF) + { + cmd.length = 12; + //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); + cmd.mask = cpu_to_le32(mask); + } + + //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length); + +} +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask) +{ + struct ioreg_cfg cmd = {8,IOREG_CMD_WD_REG,0x0, 0x0,0x0}; + + //RTW_PUT_LE16((u8*)&cmd.address, addr); + //RTW_PUT_LE32((u8*)&cmd.value, (u32)value); + cmd.address = cpu_to_le16(addr); + cmd.data = cpu_to_le32(value); + + if(mask!=0xFFFFFFFF) + { + cmd.length = 12; + //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); + cmd.mask = cpu_to_le32(mask); + } + + //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length); + +} + +int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask) +{ + struct ioreg_cfg cmd = {8,IOREG_CMD_W_RF,0x0, 0x0,0x0}; + + //RTW_PUT_LE16((u8*)&cmd.address, addr); + //RTW_PUT_LE32((u8*)&cmd.value, (u32)value); + cmd.address = (rf_path<<8) |((addr) &0xFF); + cmd.data = cpu_to_le32(value); + + if(mask!=0x000FFFFF) + { + cmd.length = 12; + //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); + cmd.mask = cpu_to_le32(mask); + } + + //DBG_871X("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length); + +} + + + +int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) +{ + struct ioreg_cfg cmd = {4,IOREG_CMD_DELAY_US,0x0, 0x0,0x0}; + //RTW_PUT_LE16((u8*)&cmd.address, us); + cmd.address = cpu_to_le16(us); + + //DBG_871X("%s %u\n", __FUNCTION__, us); + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4); +} + +int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) +{ + struct ioreg_cfg cmd = {4,IOREG_CMD_DELAY_US,0x0, 0x0,0x0}; + + //RTW_PUT_LE16((u8*)&cmd.address, ms); + cmd.address = cpu_to_le16(ms); + + //DBG_871X("%s %u\n", __FUNCTION__, ms); + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4); +} +int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) +{ + struct ioreg_cfg cmd = {4,IOREG_CMD_END,0xFFFF, 0xFF,0x0}; + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4); + +} + +u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame) +{ + u8 is_cmd_bndy = _FALSE; + if(((pxmit_frame->attrib.pktlen+32)%256) + 8 >= 256){ + rtw_IOL_append_END_cmd(pxmit_frame); + pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen+32)/256)+1)*256 ); + + //printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); + pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen; + is_cmd_bndy = _TRUE; + } + return is_cmd_bndy; +} + +void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter,int buf_len,u8 *pbuf) +{ + int i; + int j=1; + + printk("###### %s ######\n",__FUNCTION__); + for(i=0;i< buf_len;i++){ + printk("%02x-",*(pbuf+i)); + + if(j%32 ==0) printk("\n");j++; + } + printk("\n"); + printk("============= ioreg_cmd len = %d =============== \n",buf_len); +} + + +#else //CONFIG_IOL_NEW_GENERATION +int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) +{ + IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)page_boundary); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0}; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0}; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value) +{ + IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0}; + u8* pos = (u8 *)&cmd; + + RTW_PUT_BE16((u8*)&cmd.address, (u16)addr); + RTW_PUT_BE32((u8*)&cmd.value, (u32)value); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +#ifdef DBG_IO +int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 1)) + DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value); +} + +int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 2)) + DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value); +} + +int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line) +{ + if (match_write_sniff_ranges(addr, 4)) + DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value); + + return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value); +} +#endif + +int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) +{ + IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)us); + + //DBG_871X("%s %u\n", __FUNCTION__, us); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) +{ + IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0}; + + RTW_PUT_BE32((u8*)&cmd.value, (u32)ms); + + //DBG_871X("%s %u\n", __FUNCTION__, ms); + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8); +} + +int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) +{ + IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0}; + + + return rtw_IOL_append_cmds(xmit_frame, (u8*)&end_cmd, 8); + +} + +int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms) +{ + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(adapter)) == NULL) + return _FAIL; + + if(rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num<<3) == _FAIL) + return _FAIL; + + return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms,0); +} + +int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms) +{ + IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0}; + return rtw_IOL_exec_cmd_array_sync(adapter, (u8*)&end_cmd, 1, max_wating_ms); +} +#endif //CONFIG_IOL_NEW_GENERATION + + + + +#endif //CONFIG_IOL + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mem.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mem.c new file mode 100644 index 00000000..d05e3af6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mem.c @@ -0,0 +1,122 @@ + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); +MODULE_AUTHOR("Realtek Semiconductor Corp."); +MODULE_VERSION("DRIVERVERSION"); + +struct sk_buff_head rtk_skb_mem_q; +struct u8* rtk_buf_mem[NR_RECVBUFF]; + +struct u8 * rtw_get_buf_premem(int index) +{ + printk("%s, rtk_buf_mem index : %d\n", __func__, index); + return rtk_buf_mem[index]; +} + +u16 rtw_rtkm_get_buff_size(void) +{ + return MAX_RTKM_RECVBUF_SZ; +} +EXPORT_SYMBOL(rtw_rtkm_get_buff_size); + +u8 rtw_rtkm_get_nr_recv_skb(void) +{ + return MAX_RTKM_NR_PREALLOC_RECV_SKB; +} +EXPORT_SYMBOL(rtw_rtkm_get_nr_recv_skb); + +struct sk_buff *rtw_alloc_skb_premem(u16 in_size) +{ + struct sk_buff *skb = NULL; + + if (in_size > MAX_RTKM_RECVBUF_SZ) { + pr_info("warning %s: driver buffer size(%d) > rtkm buffer size(%d)\n", __func__, in_size, MAX_RTKM_RECVBUF_SZ); + WARN_ON(1); + return skb; + } + + skb = skb_dequeue(&rtk_skb_mem_q); + + printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q)); + + return skb; +} +EXPORT_SYMBOL(rtw_alloc_skb_premem); + +int rtw_free_skb_premem(struct sk_buff *pskb) +{ + if(!pskb) + return -1; + + if (skb_queue_len(&rtk_skb_mem_q) >= MAX_RTKM_NR_PREALLOC_RECV_SKB) + return -1; + + skb_queue_tail(&rtk_skb_mem_q, pskb); + + printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q)); + + return 0; +} +EXPORT_SYMBOL(rtw_free_skb_premem); + +static int __init rtw_mem_init(void) +{ + int i; + SIZE_PTR tmpaddr=0; + SIZE_PTR alignment=0; + struct sk_buff *pskb=NULL; + + printk("%s\n", __func__); + pr_info("MAX_RTKM_NR_PREALLOC_RECV_SKB: %d\n", MAX_RTKM_NR_PREALLOC_RECV_SKB); + pr_info("MAX_RTKM_RECVBUF_SZ: %d\n", MAX_RTKM_RECVBUF_SZ); + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + for(i=0; idata; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); + skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); + + skb_queue_tail(&rtk_skb_mem_q, pskb); + } + else + { + printk("%s, alloc skb memory fail!\n", __func__); + } + + pskb=NULL; + } + + printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q)); + + return 0; + +} + +static void __exit rtw_mem_exit(void) +{ + if (skb_queue_len(&rtk_skb_mem_q)) { + printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q)); + } + + skb_queue_purge(&rtk_skb_mem_q); + + printk("%s\n", __func__); +} + +module_init(rtw_mem_init); +module_exit(rtw_mem_exit); diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme.c new file mode 100644 index 00000000..8a0b7bc3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme.c @@ -0,0 +1,4835 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MLME_C_ + +#include + +extern void indicate_wx_scan_complete_event(_adapter *padapter); +extern u8 rtw_do_join(_adapter * padapter); + + +sint _rtw_init_mlme_priv (_adapter* padapter) +{ + sint i; + u8 *pbuf; + struct wlan_network *pnetwork; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + sint res = _SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); + + pmlmepriv->nic_hdl = (u8 *)padapter; + + pmlmepriv->pscanned = NULL; + pmlmepriv->fw_state = WIFI_STATION_STATE; // Must sync with rtw_wdev_alloc() + // wdev->iftype = NL80211_IFTYPE_STATION + pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown; + pmlmepriv->scan_mode=SCAN_ACTIVE;// 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) + + _rtw_spinlock_init(&(pmlmepriv->lock)); + _rtw_init_queue(&(pmlmepriv->free_bss_pool)); + _rtw_init_queue(&(pmlmepriv->scanned_queue)); + + set_scanned_network_val(pmlmepriv, 0); + + _rtw_memset(&pmlmepriv->assoc_ssid,0,sizeof(NDIS_802_11_SSID)); + + pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network))); + + if (pbuf == NULL){ + res=_FAIL; + goto exit; + } + pmlmepriv->free_bss_buf = pbuf; + + pnetwork = (struct wlan_network *)pbuf; + + for(i = 0; i < MAX_BSS_CNT; i++) + { + _rtw_init_listhead(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue)); + + pnetwork++; + } + + //allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf + + rtw_clear_scan_deny(padapter); +#ifdef CONFIG_ARP_KEEP_ALIVE + pmlmepriv->bGetGateway = 0; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + #define RTW_ROAM_SCAN_RESULT_EXP_MS 5*1000 + #define RTW_ROAM_RSSI_DIFF_TH 10 + #define RTW_ROAM_SCAN_INTERVAL_MS 10*1000 + + pmlmepriv->roam_flags = 0 + | RTW_ROAM_ON_EXPIRED + #ifdef CONFIG_LAYER2_ROAMING_RESUME + | RTW_ROAM_ON_RESUME + #endif + #ifdef CONFIG_LAYER2_ROAMING_ACTIVE + | RTW_ROAM_ACTIVE + #endif + ; + + pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS; + pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH; + pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS; +#endif /* CONFIG_LAYER2_ROAMING */ + + rtw_init_mlme_timer(padapter); + +exit: + +_func_exit_; + + return res; +} + +void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv); +void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv) +{ + _rtw_spinlock_free(&pmlmepriv->lock); + _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock)); + _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock)); +} + +static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen) +{ + if(*ppie) + { + rtw_mfree(*ppie, *plen); + *plen = 0; + *ppie=NULL; + } +} + +void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv) +{ +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); + rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len); + + rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len); +#endif + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) + rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len); + rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len); +#endif + +} + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) +int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_len) +{ + _adapter *adapter = mlme_to_adapter(mlme); + struct wifi_display_info *wfd_info = &adapter->wfd_info; + u8 clear = 0; + u8 **t_ie = NULL; + u32 *t_ie_len = NULL; + int ret = _FAIL; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto success; + + if (wfd_info->wfd_enable == _TRUE) + goto success; /* WFD IE is build by self */ + + if (!ie && !ie_len) { + clear = 1; + } else if (!ie || !ie_len) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" type:%u, ie:%p, ie_len:%u" + , FUNC_ADPT_ARG(adapter), type, ie, ie_len); + rtw_warn_on(1); + goto exit; + } + + switch (type) { + case MLME_BEACON_IE: + t_ie = &mlme->wfd_beacon_ie; + t_ie_len = &mlme->wfd_beacon_ie_len; + break; + case MLME_PROBE_REQ_IE: + t_ie = &mlme->wfd_probe_req_ie; + t_ie_len = &mlme->wfd_probe_req_ie_len; + break; + case MLME_PROBE_RESP_IE: + t_ie = &mlme->wfd_probe_resp_ie; + t_ie_len = &mlme->wfd_probe_resp_ie_len; + break; + case MLME_GO_PROBE_RESP_IE: + t_ie = &mlme->wfd_go_probe_resp_ie; + t_ie_len = &mlme->wfd_go_probe_resp_ie_len; + break; + case MLME_ASSOC_REQ_IE: + t_ie = &mlme->wfd_assoc_req_ie; + t_ie_len = &mlme->wfd_assoc_req_ie_len; + break; + case MLME_ASSOC_RESP_IE: + t_ie = &mlme->wfd_assoc_resp_ie; + t_ie_len = &mlme->wfd_assoc_resp_ie_len; + break; + default: + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" unsupported type:%u" + , FUNC_ADPT_ARG(adapter), type); + rtw_warn_on(1); + goto exit; + } + + if (*t_ie) { + u32 free_len = *t_ie_len; + *t_ie_len = 0; + rtw_mfree(*t_ie, free_len); + *t_ie = NULL; + } + + if (!clear) { + *t_ie = rtw_malloc(ie_len); + if (*t_ie == NULL) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" type:%u, rtw_malloc() fail\n" + , FUNC_ADPT_ARG(adapter), type); + goto exit; + } + _rtw_memcpy(*t_ie, ie, ie_len); + *t_ie_len = ie_len; + } + + if (*t_ie && *t_ie_len) { + u8 *attr_content; + u32 attr_contentlen = 0; + + attr_content = rtw_get_wfd_attr_content(*t_ie, *t_ie_len, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen); + if (attr_content && attr_contentlen) { + if (RTW_GET_BE16(attr_content + 2) != wfd_info->rtsp_ctrlport) { + wfd_info->rtsp_ctrlport = RTW_GET_BE16(attr_content + 2); + DBG_871X(FUNC_ADPT_FMT" type:%u, RTSP CTRL port = %u\n" + , FUNC_ADPT_ARG(adapter), type, wfd_info->rtsp_ctrlport); + } + } + } + +success: + ret = _SUCCESS; + +exit: + return ret; +} +#endif /* defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) */ + +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){ + rtw_mfree_mlme_priv_lock (pmlmepriv); + + if (pmlmepriv->free_bss_buf) { + rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network)); + } + } +exit: +_func_exit_; +} + +sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork) +{ + _irqL irqL; + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_insert_tail(&pnetwork->list, &queue->queue); + + _exit_critical_bh(&queue->lock, &irqL); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +/* +struct wlan_network *_rtw_dequeue_network(_queue *queue) +{ + _irqL irqL; + + struct wlan_network *pnetwork; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (_rtw_queue_empty(queue) == _TRUE) + + pnetwork = NULL; + + else + { + pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list); + + rtw_list_delete(&(pnetwork->list)); + } + + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; + + return pnetwork; +} +*/ + +struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv )//(_queue *free_queue) +{ + _irqL irqL; + struct wlan_network *pnetwork; + _queue *free_queue = &pmlmepriv->free_bss_pool; + _list* plist = NULL; + +_func_enter_; + + _enter_critical_bh(&free_queue->lock, &irqL); + + if (_rtw_queue_empty(free_queue) == _TRUE) { + pnetwork=NULL; + goto exit; + } + plist = get_next(&(free_queue->queue)); + + pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list); + + rtw_list_delete(&pnetwork->list); + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist)); + pnetwork->network_type = 0; + pnetwork->fixed = _FALSE; + pnetwork->last_scanned = rtw_get_current_time(); + pnetwork->aid=0; + pnetwork->join_res=0; + + pmlmepriv->num_of_scanned ++; + +exit: + _exit_critical_bh(&free_queue->lock, &irqL); + +_func_exit_; + + return pnetwork; +} + +void _rtw_free_network(struct mlme_priv *pmlmepriv ,struct wlan_network *pnetwork, u8 isfreeall) +{ + u32 delta_time; + u32 lifetime = SCANQUEUE_LIFETIME; + _irqL irqL; + _queue *free_queue = &(pmlmepriv->free_bss_pool); + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + if (pnetwork->fixed == _TRUE) + goto exit; + + if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) ) + lifetime = 1; + + if(!isfreeall) + { + delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned); + if(delta_time < lifetime)// unit:msec + goto exit; + } + + _enter_critical_bh(&free_queue->lock, &irqL); + + rtw_list_delete(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list),&(free_queue->queue)); + + pmlmepriv->num_of_scanned --; + + + //DBG_871X("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid); + + _exit_critical_bh(&free_queue->lock, &irqL); + +exit: + +_func_exit_; + +} + +void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork) +{ + + _queue *free_queue = &(pmlmepriv->free_bss_pool); + +_func_enter_; + + if (pnetwork == NULL) + goto exit; + + if (pnetwork->fixed == _TRUE) + goto exit; + + //_enter_critical(&free_queue->lock, &irqL); + + rtw_list_delete(&(pnetwork->list)); + + rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue)); + + pmlmepriv->num_of_scanned --; + + //_exit_critical(&free_queue->lock, &irqL); + +exit: + +_func_exit_; + +} + + +/* + return the wlan_network with the matching addr + + Shall be calle under atomic context... to avoid possible racing condition... +*/ +struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr) +{ + + //_irqL irqL; + _list *phead, *plist; + struct wlan_network *pnetwork = NULL; + u8 zero_addr[ETH_ALEN] = {0,0,0,0,0,0}; + +_func_enter_; + + if(_rtw_memcmp(zero_addr, addr, ETH_ALEN)){ + pnetwork=NULL; + goto exit; + } + + //_enter_critical_bh(&scanned_queue->lock, &irqL); + + phead = get_list_head(scanned_queue); + plist = get_next(phead); + + while (plist != phead) + { + pnetwork = LIST_CONTAINOR(plist, struct wlan_network ,list); + + if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) + break; + + plist = get_next(plist); + } + + if(plist == phead) + pnetwork = NULL; + + //_exit_critical_bh(&scanned_queue->lock, &irqL); + +exit: + +_func_exit_; + + return pnetwork; + +} + + +void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall) +{ + _irqL irqL; + _list *phead, *plist; + struct wlan_network *pnetwork; + struct mlme_priv* pmlmepriv = &padapter->mlmepriv; + _queue *scanned_queue = &pmlmepriv->scanned_queue; + +_func_enter_; + + + _enter_critical_bh(&scanned_queue->lock, &irqL); + + phead = get_list_head(scanned_queue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + plist = get_next(plist); + + _rtw_free_network(pmlmepriv,pnetwork, isfreeall); + + } + + _exit_critical_bh(&scanned_queue->lock, &irqL); + +_func_exit_; + +} + + + + +sint rtw_if_up(_adapter *padapter) { + + sint res; +_func_enter_; + + if (RTW_CANNOT_RUN(padapter) || + (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) { + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up:bDriverStopped(%s) OR bSurpriseRemoved(%s)" + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + res=_FALSE; + } + else + res= _TRUE; + +_func_exit_; + return res; +} + + +void rtw_generate_random_ibss(u8* pibss) +{ + *((u32 *)(&pibss[2])) = rtw_random32(); + pibss[0] = 0x02; /* in ad-hoc mode local bit must set to 1 */ + pibss[1] = 0x11; + pibss[2] = 0x87; +} + +u8 *rtw_get_capability_from_ie(u8 *ie) +{ + return (ie + 8 + 2); +} + + +u16 rtw_get_capability(WLAN_BSSID_EX *bss) +{ + u16 val; +_func_enter_; + + _rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2); + +_func_exit_; + return le16_to_cpu(val); +} + +u8 *rtw_get_timestampe_from_ie(u8 *ie) +{ + return (ie + 0); +} + +u8 *rtw_get_beacon_interval_from_ie(u8 *ie) +{ + return (ie + 8); +} + + +int rtw_init_mlme_priv (_adapter *padapter)//(struct mlme_priv *pmlmepriv) +{ + int res; +_func_enter_; + res = _rtw_init_mlme_priv(padapter);// (pmlmepriv); +_func_exit_; + return res; +} + +void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_mlme_priv\n")); + _rtw_free_mlme_priv (pmlmepriv); +_func_exit_; +} + +int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); +int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork) +{ + int res; +_func_enter_; + res = _rtw_enqueue_network(queue, pnetwork); +_func_exit_; + return res; +} + +/* +static struct wlan_network *rtw_dequeue_network(_queue *queue) +{ + struct wlan_network *pnetwork; +_func_enter_; + pnetwork = _rtw_dequeue_network(queue); +_func_exit_; + return pnetwork; +} +*/ + +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv ); +struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv )//(_queue *free_queue) +{ + struct wlan_network *pnetwork; +_func_enter_; + pnetwork = _rtw_alloc_network(pmlmepriv); +_func_exit_; + return pnetwork; +} + +void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall); +void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall)//(struct wlan_network *pnetwork, _queue *free_queue) +{ +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid)); + _rtw_free_network(pmlmepriv, pnetwork, is_freeall); +_func_exit_; +} + +void rtw_free_network_nolock(_adapter * padapter, struct wlan_network *pnetwork ); +void rtw_free_network_nolock(_adapter * padapter, struct wlan_network *pnetwork ) +{ +_func_enter_; + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid)); + _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork); +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_unlink_bss(padapter, pnetwork); +#endif //CONFIG_IOCTL_CFG80211 +_func_exit_; +} + + +void rtw_free_network_queue(_adapter* dev, u8 isfreeall) +{ +_func_enter_; + _rtw_free_network_queue(dev, isfreeall); +_func_exit_; +} + +/* + return the wlan_network with the matching addr + + Shall be calle under atomic context... to avoid possible racing condition... +*/ +struct wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr) +{ + struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr); + + return pnetwork; +} + +int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork) +{ + int ret=_TRUE; + struct security_priv *psecuritypriv = &adapter->securitypriv; + + if ( (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) && + ( pnetwork->network.Privacy == 0 ) ) + { + ret=_FALSE; + } + else if((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ ) && + ( pnetwork->network.Privacy == 1 ) ) + { + ret=_FALSE; + } + else + { + ret=_TRUE; + } + + return ret; + +} + +inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b) +{ + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(%s,%d)(%s,%d)\n", + // a->Ssid.Ssid,a->Ssid.SsidLength,b->Ssid.Ssid,b->Ssid.SsidLength)); + return (a->Ssid.SsidLength == b->Ssid.SsidLength) + && _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength)==_TRUE; +} + +int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature) +{ + u16 s_cap, d_cap; + +_func_enter_; + + if(rtw_bug_check(dst, src, &s_cap, &d_cap)==_FALSE) + return _FALSE; + + _rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2); + _rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2); + + + s_cap = le16_to_cpu(s_cap); + d_cap = le16_to_cpu(d_cap); + +_func_exit_; + +#ifdef CONFIG_P2P + if ((feature == 1) && // 1: P2P supported + (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN) == _TRUE) + ) { + return _TRUE; + } +#endif + + return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) && + // (src->Configuration.DSConfig == dst->Configuration.DSConfig) && + ( (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) && + ( (_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) && + ((s_cap & WLAN_CAPABILITY_IBSS) == + (d_cap & WLAN_CAPABILITY_IBSS)) && + ((s_cap & WLAN_CAPABILITY_BSS) == + (d_cap & WLAN_CAPABILITY_BSS))); + +} + +struct wlan_network *_rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network) +{ + _list *phead, *plist; + struct wlan_network *found = NULL; + + phead = get_list_head(scanned_queue); + plist = get_next(phead); + + while (plist != phead) { + found = LIST_CONTAINOR(plist, struct wlan_network ,list); + + if (is_same_network(&network->network, &found->network,0)) + break; + + plist = get_next(plist); + } + + if(plist == phead) + found = NULL; +exit: + return found; +} + +struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network) +{ + _irqL irqL; + struct wlan_network *found = NULL; + + if (scanned_queue == NULL || network == NULL) + goto exit; + + _enter_critical_bh(&scanned_queue->lock, &irqL); + found = _rtw_find_same_network(scanned_queue, network); + _exit_critical_bh(&scanned_queue->lock, &irqL); + +exit: + return found; +} + +struct wlan_network * rtw_get_oldest_wlan_network(_queue *scanned_queue) +{ + _list *plist, *phead; + + + struct wlan_network *pwlan = NULL; + struct wlan_network *oldest = NULL; +_func_enter_; + phead = get_list_head(scanned_queue); + + plist = get_next(phead); + + while(1) + { + + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pwlan= LIST_CONTAINOR(plist, struct wlan_network, list); + + if(pwlan->fixed!=_TRUE) + { + if (oldest == NULL ||time_after(oldest->last_scanned, pwlan->last_scanned)) + oldest = pwlan; + } + + plist = get_next(plist); + } +_func_exit_; + return oldest; + +} + +void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, + _adapter * padapter, bool update_ie) +{ + u8 ss_ori = dst->PhyInfo.SignalStrength; + u8 sq_ori = dst->PhyInfo.SignalQuality; + long rssi_ori = dst->Rssi; + + u8 ss_smp = src->PhyInfo.SignalStrength; + u8 sq_smp = src->PhyInfo.SignalQuality; + long rssi_smp = src->Rssi; + + u8 ss_final; + u8 sq_final; + long rssi_final; + +_func_enter_; + +#ifdef CONFIG_ANTENNA_DIVERSITY + rtw_hal_antdiv_rssi_compared(padapter, dst, src); //this will update src.Rssi, need consider again +#endif + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1 + if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n" + , FUNC_ADPT_ARG(padapter) + , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig + ,ss_ori, sq_ori, rssi_ori + ,ss_smp, sq_smp, rssi_smp + ); + } + #endif + + /* The rule below is 1/5 for sample value, 4/5 for history value */ + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) { + /* Take the recvpriv's value for the connected AP*/ + ss_final = padapter->recvpriv.signal_strength; + sq_final = padapter->recvpriv.signal_qual; + /* the rssi value here is undecorated, and will be used for antenna diversity */ + if(sq_smp != 101) /* from the right channel */ + rssi_final = (src->Rssi+dst->Rssi*4)/5; + else + rssi_final = rssi_ori; + } + else { + if(sq_smp != 101) { /* from the right channel */ + ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5; + sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5; + rssi_final = (src->Rssi+dst->Rssi*4)/5; + } else { + /* bss info not receving from the right channel, use the original RX signal infos */ + ss_final = dst->PhyInfo.SignalStrength; + sq_final = dst->PhyInfo.SignalQuality; + rssi_final = dst->Rssi; + } + + } + + if (update_ie) { + dst->Reserved[0] = src->Reserved[0]; + dst->Reserved[1] = src->Reserved[1]; + _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src)); + } + + dst->PhyInfo.SignalStrength = ss_final; + dst->PhyInfo.SignalQuality = sq_final; + dst->Rssi = rssi_final; + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1 + if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n" + , FUNC_ADPT_ARG(padapter) + , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi); + } + #endif + +#if 0 // old codes, may be useful one day... +// DBG_871X("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi); + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) + { + + //DBG_871X("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal); + if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) + { + padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index]; + padapter->recvpriv.signal_qual_data.total_val -= last_evm; + } + padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi); + + padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi); + if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX) + padapter->recvpriv.signal_qual_data.index = 0; + + //DBG_871X("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi); + + // <1> Showed on UI for user,in percentage. + tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num; + padapter->recvpriv.signal=(u8)tmpVal;//Link quality + + src->Rssi= translate_percentage_to_dbm(padapter->recvpriv.signal) ; + } + else{ +// DBG_871X("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi); + src->Rssi=(src->Rssi +dst->Rssi)/2;//dBM + } + +// DBG_871X("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal); + +#endif + +_func_exit_; +} + +static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +_func_enter_; + + rtw_bug_check(&(pmlmepriv->cur_network.network), + &(pmlmepriv->cur_network.network), + &(pmlmepriv->cur_network.network), + &(pmlmepriv->cur_network.network)); + + if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n"); + + //if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) + { + update_network(&(pmlmepriv->cur_network.network), pnetwork,adapter, _TRUE); + rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), + pmlmepriv->cur_network.network.IELength); + } + } + +_func_exit_; + +} + + +/* + +Caller must hold pmlmepriv->lock first. + + +*/ +void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target) +{ + _irqL irqL; + _list *plist, *phead; + ULONG bssid_ex_sz; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); +#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; + int target_find = 0; + u8 feature = 0; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + plist = get_next(phead); + +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + feature = 1; // p2p enable +#endif + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork); + +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && + (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE)) + { + target_find = 1; + break; + } +#endif + + if (is_same_network(&(pnetwork->network), target, feature)) + { + target_find = 1; + break; + } + + if (rtw_roam_flags(adapter)) { + /* TODO: don't select netowrk in the same ess as oldest if it's new enough*/ + } + + if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned)) + oldest = pnetwork; + + plist = get_next(plist); + + } + + + /* If we didn't find a match, then get a new network slot to initialize + * with this beacon's information */ + //if (rtw_end_of_queue_search(phead,plist)== _TRUE) { + if (!target_find) { + if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) { + /* If there are no more slots, expire the oldest */ + //list_del_init(&oldest->list); + pnetwork = oldest; + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n")); + goto exit; + } +#ifdef CONFIG_ANTENNA_DIVERSITY + //target->PhyInfo.Optimum_antenna = pHalData->CurAntenna;//optimum_antenna=>For antenna diversity + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna)); +#endif + _rtw_memcpy(&(pnetwork->network), target, get_WLAN_BSSID_EX_sz(target)); + //pnetwork->last_scanned = rtw_get_current_time(); + // variable initialize + pnetwork->fixed = _FALSE; + pnetwork->last_scanned = rtw_get_current_time(); + + pnetwork->network_type = 0; + pnetwork->aid=0; + pnetwork->join_res=0; + + /* bss info not receving from the right channel */ + if (pnetwork->network.PhyInfo.SignalQuality == 101) + pnetwork->network.PhyInfo.SignalQuality = 0; + } + else { + /* Otherwise just pull from the free list */ + + pnetwork = rtw_alloc_network(pmlmepriv); // will update scan_time + + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n")); + goto exit; + } + + bssid_ex_sz = get_WLAN_BSSID_EX_sz(target); + target->Length = bssid_ex_sz; +#ifdef CONFIG_ANTENNA_DIVERSITY + //target->PhyInfo.Optimum_antenna = pHalData->CurAntenna; + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna)); +#endif + _rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz ); + + pnetwork->last_scanned = rtw_get_current_time(); + + /* bss info not receving from the right channel */ + if (pnetwork->network.PhyInfo.SignalQuality == 101) + pnetwork->network.PhyInfo.SignalQuality = 0; + + rtw_list_insert_tail(&(pnetwork->list),&(queue->queue)); + + } + } + else { + /* we have an entry and we are going to update it. But this entry may + * be already expired. In this case we do the same as we found a new + * net and call the new_net handler + */ + bool update_ie = _TRUE; + + pnetwork->last_scanned = rtw_get_current_time(); + + //target.Reserved[0]==1, means that scaned network is a bcn frame. + if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1)) + update_ie = _FALSE; + + // probe resp(3) > beacon(1) > probe req(2) + if ((target->Reserved[0] != 2) && + (target->Reserved[0] >= pnetwork->network.Reserved[0]) + ) { + update_ie = _TRUE; + } + else { + update_ie = _FALSE; + } + + update_network(&(pnetwork->network), target,adapter, update_ie); + } + +exit: + _exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; +} + +void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork); +void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &(((_adapter *)adapter)->mlmepriv); + //_queue *queue = &(pmlmepriv->scanned_queue); + +_func_enter_; + + //_enter_critical_bh(&queue->lock, &irqL); + + #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO) + if (adapter->registrypriv.wifi_spec == 0) + rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); + #endif + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + rtw_bss_ex_del_wfd_ie(pnetwork); + + update_current_network(adapter, pnetwork); + + rtw_update_scanned_network(adapter, pnetwork); + + //_exit_critical_bh(&queue->lock, &irqL); + +_func_exit_; +} + +//select the desired network based on the capability of the (i)bss. +// check items: (1) security +// (2) network_type +// (3) WMM +// (4) HT +// (5) others +int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork); +int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u32 desired_encmode; + u32 privacy; + + //u8 wps_ie[512]; + uint wps_ielen; + + int bselected = _TRUE; + + desired_encmode = psecuritypriv->ndisencryptstatus; + privacy = pnetwork->network.Privacy; + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + if(rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!=NULL) + { + return _TRUE; + } + else + { + return _FALSE; + } + } + if (adapter->registrypriv.wifi_spec == 1) //for correct flow of 8021X to do.... + { + u8 *p=NULL; + uint ie_len=0; + + if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0)) + bselected = _FALSE; + + if ( psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) { + p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_)); + if (p && ie_len>0) { + bselected = _TRUE; + } else { + bselected = _FALSE; + } + } + } + + + if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) { + DBG_871X("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy); + bselected = _FALSE; + } + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) + bselected = _FALSE; + } + + + return bselected; +} + +/* TODO: Perry : For Power Management */ +void rtw_atimdone_event_callback(_adapter *adapter , u8 *pbuf) +{ + +_func_enter_; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n")); +_func_exit_; + return; +} + + +void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + u32 len; + WLAN_BSSID_EX *pnetwork; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +_func_enter_; + + pnetwork = (WLAN_BSSID_EX *)pbuf; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_callback, ssid=%s\n", pnetwork->Ssid.Ssid)); + +#ifdef CONFIG_RTL8712 + //endian_convert + pnetwork->Length = le32_to_cpu(pnetwork->Length); + pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); + pnetwork->Privacy =le32_to_cpu( pnetwork->Privacy); + pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); + pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse); + pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow); + pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod); + pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig); + pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); + pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); + pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); + pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length); + pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length); + pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode); + pnetwork->IELength = le32_to_cpu(pnetwork->IELength); +#endif + + len = get_WLAN_BSSID_EX_sz(pnetwork); + if(len > (sizeof(WLAN_BSSID_EX))) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n ****rtw_survey_event_callback: return a wrong bss ***\n")); + return; + } + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + // update IBSS_network 's timestamp + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"rtw_survey_event_callback : WIFI_ADHOC_MASTER_STATE \n\n"); + if(_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) + { + struct wlan_network* ibss_wlan = NULL; + _irqL irqL; + + _rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8); + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress); + if(ibss_wlan) + { + _rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto exit; + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + } + } + + // lock pmlmepriv->lock when you accessing network_q + if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE) + { + if( pnetwork->Ssid.Ssid[0] == 0 ) + { + pnetwork->Ssid.SsidLength = 0; + } + rtw_add_network(adapter, pnetwork); + } + +exit: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +_func_exit_; + + return; +} + +void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + u8 timer_cancelled; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + +#ifdef CONFIG_MLME_EXT + mlmeext_surveydone_event_callback(adapter); +#endif + +_func_enter_; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if (pmlmepriv->wps_probe_req_ie) { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv))); + + if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); + //rtw_warn_on(1); + } + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&adapter->recvpriv); + #endif + + if(pmlmepriv->to_join == _TRUE) + { + if((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) ) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)==_FALSE) + { + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS) + { + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + } + else + { + WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network); + u8 *pibss = adapter->registrypriv.dev_network.MacAddress; + + //pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;//because don't set assoc_timer + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("switching to adhoc master\n")); + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(adapter); + rtw_generate_random_ibss(pibss); + + + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + + if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS) + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Error=>rtw_create_ibss_cmd status FAIL\n")); + + pmlmepriv->to_join = _FALSE; + } + } + } + else + { + int s_ret; + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + pmlmepriv->to_join = _FALSE; + if(_SUCCESS == (s_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))) + { + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + } + else if(s_ret == 2)//there is no need to wait for join + { + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + rtw_indicate_connect(adapter); + } + else + { + DBG_871X("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter)); + + if (rtw_to_roam(adapter) != 0) { + if(rtw_dec_to_roam(adapter) == 0 + || _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0) + ) { + rtw_set_to_roam(adapter, 0); +#ifdef CONFIG_INTEL_WIDI + if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + rtw_free_assoc_resources(adapter, 1); + rtw_indicate_disconnect(adapter); + } else { + pmlmepriv->to_join = _TRUE; + } + } + else + { + rtw_indicate_disconnect(adapter); + } + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + } + } + } else { + if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED)) + { + if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) { + receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress + , WLAN_REASON_ACTIVE_ROAM); + } + } + } + } + + //DBG_871X("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time)); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +#ifdef CONFIG_P2P_PS + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0); + } +#endif // CONFIG_P2P_PS + + rtw_os_xmit_schedule(adapter); +#ifdef CONFIG_CONCURRENT_MODE + rtw_os_xmit_schedule(adapter->pbuddy_adapter); +#endif + +#ifdef CONFIG_DRVEXT_MODULE_WSC + drvext_surveydone_callback(&adapter->drvextpriv); +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + if(pmlmeext->sitesurvey_res.bss_cnt == 0){ + //rtw_hal_sreset_reset(adapter); + } + } +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_surveydone_event_callback(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_scan_done(adapter, _FALSE); + +#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211) + if (adapter->pbuddy_adapter) { + _adapter *buddy_adapter = adapter->pbuddy_adapter; + struct mlme_priv *buddy_mlme = &(buddy_adapter->mlmepriv); + struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(buddy_adapter); + bool indicate_buddy_scan = _FALSE; + + _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + if (buddy_wdev_priv->scan_request && buddy_mlme->scanning_via_buddy_intf == _TRUE) { + buddy_mlme->scanning_via_buddy_intf = _FALSE; + clr_fwstate(buddy_mlme, _FW_UNDER_SURVEY); + indicate_buddy_scan = _TRUE; + } + _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + + if (indicate_buddy_scan == _TRUE) { + #ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_surveydone_event_callback(buddy_adapter); + #endif + rtw_indicate_scan_done(buddy_adapter, _FALSE); + } + } +#endif /* CONFIG_CONCURRENT_MODE */ + +_func_exit_; + +} + +void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf) +{ + +} + +void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf) +{ + +} + +static void free_scanqueue(struct mlme_priv *pmlmepriv) +{ + _irqL irqL, irqL0; + _queue *free_queue = &pmlmepriv->free_bss_pool; + _queue *scan_queue = &pmlmepriv->scanned_queue; + _list *plist, *phead, *ptemp; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n")); + _enter_critical_bh(&scan_queue->lock, &irqL0); + _enter_critical_bh(&free_queue->lock, &irqL); + + phead = get_list_head(scan_queue); + plist = get_next(phead); + + while (plist != phead) + { + ptemp = get_next(plist); + rtw_list_delete(plist); + rtw_list_insert_tail(plist, &free_queue->queue); + plist =ptemp; + pmlmepriv->num_of_scanned --; + } + + _exit_critical_bh(&free_queue->lock, &irqL); + _exit_critical_bh(&scan_queue->lock, &irqL0); + +_func_exit_; +} + +void rtw_reset_rx_info(struct debug_priv *pdbgpriv){ + pdbgpriv->dbg_rx_ampdu_drop_count = 0; + pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0; + pdbgpriv->dbg_rx_ampdu_loss_count = 0; + pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0; + pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0; +} + +/* +*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock +*/ +void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue) +{ + _irqL irqL; + struct wlan_network* pwlan = NULL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct sta_priv *pstapriv = &adapter->stapriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + struct dvobj_priv *psdpriv = adapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#endif //CONFIG_TDLS +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n")); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress="MAC_FMT" ssid=%s\n", + MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid)); + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + struct sta_info* psta; + + psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress); + +#ifdef CONFIG_TDLS + if (ptdlsinfo->link_established == _TRUE) { + rtw_tdls_cmd(adapter, NULL, TDLS_RS_RCR); + rtw_reset_tdls_info(adapter); + rtw_free_all_stainfo(adapter); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + } + else +#endif //CONFIG_TDLS + { + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + } + + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + } + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) { + struct sta_info* psta; + + rtw_free_all_stainfo(adapter); + + psta = rtw_get_bcmc_stainfo(adapter); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + rtw_init_bcmc_stainfo(adapter); + } + + if(lock_scanned_queue) + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + 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)) + { + rtw_set_scan_deny(adapter, 2000); + //rtw_clear_scan_deny(adapter); + } +#endif //CONFIG_P2P + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_assoc_resources : pwlan== NULL \n\n")); + } + + + if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count== 1)) + /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/) + { + if (pwlan) + rtw_free_network_nolock(adapter, pwlan); + } + + if(lock_scanned_queue) + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + adapter->securitypriv.key_mask = 0; + + rtw_reset_rx_info(pdbgpriv); + +_func_exit_; + +} + +/* +*rtw_indicate_connect: the caller has to lock pmlmepriv->lock +*/ +void rtw_indicate_connect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n")); + + pmlmepriv->to_join = _FALSE; + + if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + + set_fwstate(pmlmepriv, _FW_LINKED); + + rtw_led_control(padapter, LED_CTL_LINK); + + +#ifdef CONFIG_DRVEXT_MODULE + if(padapter->drvextpriv.enable_wpa) + { + indicate_l2_connect(padapter); + } + else +#endif + { + rtw_os_indicate_connect(padapter); + } + + } + + rtw_set_to_roam(padapter, 0); +#ifdef CONFIG_INTEL_WIDI + if(padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + + rtw_set_scan_deny(padapter, 3000); + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv))); + +_func_exit_; + +} + + +/* +*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock +*/ +void rtw_indicate_disconnect( _adapter *padapter ) +{ + 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); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *wps_ie=NULL; + uint wpsie_len=0; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n")); + + _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) + _clr_fwstate_(pmlmepriv, _FW_LINKED); + +#ifdef CONFIG_WAPI_SUPPORT + psta = rtw_get_stainfo(pstapriv,cur_network->MacAddress); + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + rtw_wapi_return_one_sta_info(padapter, psta->hwaddr); + } + else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || + check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) + { + rtw_wapi_return_all_sta_info(padapter); + } +#endif + + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED) + || (rtw_to_roam(padapter) <= 0) + ) + { + rtw_os_indicate_disconnect(padapter); + + //set ips_deny_time to avoid enter IPS before LPS leave + rtw_set_ips_deny(padapter, 3000); + + _clr_fwstate_(pmlmepriv, _FW_LINKED); + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + rtw_clear_scan_deny(padapter); + } + +#ifdef CONFIG_P2P_PS + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); +#endif // CONFIG_P2P_PS + +#ifdef CONFIG_LPS + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1); +#endif + +#ifdef CONFIG_BEAMFORMING + beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, cur_network->MacAddress, ETH_ALEN, 1); +#endif /*CONFIG_BEAMFORMING*/ + +_func_exit_; +} + +inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted) +{ + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + rtw_os_indicate_scan_done(padapter, aborted); + +#ifdef CONFIG_IPS + if (is_primary_adapter(padapter) + && (_FALSE == adapter_to_pwrctl(padapter)->bInSuspend) + && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_UNDER_LINKING) == _FALSE)) + { + struct pwrctrl_priv *pwrpriv; + + pwrpriv = adapter_to_pwrctl(padapter); + rtw_set_ips_deny(padapter, 0); +#ifdef CONFIG_IPS_CHECK_IN_WD + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1); +#else // !CONFIG_IPS_CHECK_IN_WD + _rtw_set_pwr_state_check_timer(pwrpriv, 1); +#endif // !CONFIG_IPS_CHECK_IN_WD + } +#endif // CONFIG_IPS +} + +static u32 _rtw_wait_scan_done(_adapter *adapter, u8 abort, u32 timeout_ms) +{ + u32 start; + u32 pass_ms; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + + start = rtw_get_current_time(); + + pmlmeext->scan_abort = abort; + + while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) + && rtw_get_passing_time_ms(start) <= timeout_ms) { + + if (RTW_CANNOT_RUN(adapter)) + break; + + DBG_871X(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev)); + rtw_msleep_os(20); + } + + if (_TRUE == abort) { + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + if (!RTW_CANNOT_RUN(adapter)) + DBG_871X(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev)); + #ifdef CONFIG_PLATFORM_MSTAR + /*_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);*/ + set_survey_timer(pmlmeext, 0); + 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_wait_completed(_adapter *adapter) +{ + u32 scan_to = SCANNING_TIMEOUT; + +#ifdef CONFIG_SCAN_BACKOP + if (IsSupported5G(adapter->registrypriv.wireless_mode) + && IsSupported24G(adapter->registrypriv.wireless_mode)) /*dual band*/ + scan_to = CONC_SCANNING_TIMEOUT_DUAL_BAND; + else /*single band*/ + scan_to = CONC_SCANNING_TIMEOUT_SINGLE_BAND; +#endif /* CONFIG_SCAN_BACKOP */ + + _rtw_wait_scan_done(adapter, _FALSE, scan_to); +} + +u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms) +{ + return _rtw_wait_scan_done(adapter, _TRUE, timeout_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) +{ + int i; + struct sta_info *bmc_sta, *psta=NULL; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress); + if(psta==NULL) { + psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress); + } + + if(psta) //update ptarget_sta + { + DBG_871X("%s\n", __FUNCTION__); + + psta->aid = pnetwork->join_res; + +#if 0 //alloc macid when call rtw_alloc_stainfo(), and release macid when call rtw_free_stainfo() +#ifdef CONFIG_CONCURRENT_MODE + + if(PRIMARY_ADAPTER == padapter->adapter_type) + psta->mac_id=0; + else + psta->mac_id=2; +#else + psta->mac_id=0; +#endif +#endif //removed + + update_sta_info(padapter, psta); + + //update station supportRate + psta->bssratelen = rtw_get_rateset_len(pnetwork->network.SupportedRates); + _rtw_memcpy(psta->bssrateset, pnetwork->network.SupportedRates, psta->bssratelen); + rtw_hal_update_sta_rate_mask(padapter, psta); + + psta->wireless_mode = pmlmeext->cur_wireless_mode; + psta->raid = rtw_hal_networktype_to_raid(padapter,psta); + + + //sta mode + rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE); + + //security related + if(padapter->securitypriv.dot11AuthAlgrthm== dot11AuthAlgrthm_8021X) + { + padapter->securitypriv.binstallGrpkey=_FALSE; + padapter->securitypriv.busetkipkey=_FALSE; + padapter->securitypriv.bgrpkey_handshake=_FALSE; + + psta->ieee8021x_blocked=_TRUE; + psta->dot118021XPrivacy=padapter->securitypriv.dot11PrivacyAlgrthm; + + _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype)); + + _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype)); + _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype)); + + _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48)); + psta->dot11txpn.val = psta->dot11txpn.val + 1; +#ifdef CONFIG_IEEE80211W + _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof (union pn48)); +#endif //CONFIG_IEEE80211W + _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48)); + } + + // Commented by Albert 2012/07/21 + // When doing the WPS, the wps_ie_len won't equal to 0 + // And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. + if ( padapter->securitypriv.wps_ie_len != 0 ) + { + psta->ieee8021x_blocked=_TRUE; + padapter->securitypriv.wps_ie_len = 0; + } + + + //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info + //if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff + //todo: check if AP can send A-MPDU packets + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &psta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; + } + + + bmc_sta = rtw_get_bcmc_stainfo(padapter); + if(bmc_sta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; + } + } + } + + return psta; + +} + +//pnetwork : returns from rtw_joinbss_event_callback +//ptarget_wlan: found from scanned_queue +static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + + DBG_871X("%s\n", __FUNCTION__); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\nfw_state:%x, BSSID:"MAC_FMT"\n" + ,get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress))); + + + // why not use ptarget_wlan?? + _rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length); + // some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs + cur_network->network.IELength = ptarget_wlan->network.IELength; + _rtw_memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ); + + cur_network->aid = pnetwork->join_res; + + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength; + padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality; + //the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) + padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength); + #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1 + DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u" + "\n" + , FUNC_ADPT_ARG(padapter) + , padapter->recvpriv.signal_strength + , padapter->recvpriv.rssi + , padapter->recvpriv.signal_qual + ); + #endif +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + + //update fw_state //will clr _FW_UNDER_LINKING here indirectly + switch(pnetwork->network.InfrastructureMode) + { + case Ndis802_11Infrastructure: + + if(pmlmepriv->fw_state&WIFI_UNDER_WPS) + pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS; + else + pmlmepriv->fw_state = WIFI_STATION_STATE; + + break; + case Ndis802_11IBSS: + pmlmepriv->fw_state = WIFI_ADHOC_STATE; + break; + default: + pmlmepriv->fw_state = WIFI_NULL_STATE; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Invalid network_mode\n")); + break; + } + + rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof (NDIS_802_11_FIXED_IEs), + (cur_network->network.IELength)); + +#ifdef CONFIG_80211N_HT + rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig); +#endif +} + +//Notes: the fucntion could be > passive_level (the same context as Rx tasklet) +//pnetwork : returns from rtw_joinbss_event_callback +//ptarget_wlan: found from scanned_queue +//if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. +//if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. +//if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL). +// +//#define REJOIN +void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL,irqL2; + static u8 retry=0; + u8 timer_cancelled; + struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct wlan_network *pnetwork = (struct wlan_network *)pbuf; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; + unsigned int the_same_macaddr = _FALSE; + +_func_enter_; + +#ifdef CONFIG_RTL8712 + //endian_convert + pnetwork->join_res = le32_to_cpu(pnetwork->join_res); + pnetwork->network_type = le32_to_cpu(pnetwork->network_type); + pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); + pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength); + pnetwork->network.Privacy =le32_to_cpu( pnetwork->network.Privacy); + pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); + pnetwork->network.NetworkTypeInUse =le32_to_cpu(pnetwork->network.NetworkTypeInUse) ; + pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); + pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); + pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig); + pnetwork->network.Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime); + pnetwork->network.Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern); + pnetwork->network.Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); + pnetwork->network.Configuration.FHConfig.Length=le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); + pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length); + pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode); + pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength ); +#endif + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("joinbss event call back received with res=%d\n", pnetwork->join_res)); + + rtw_get_encrypt_decrypt_from_registrypriv(adapter); + + + if (pmlmepriv->assoc_ssid.SsidLength == 0) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@ joinbss event call back for Any SSid\n")); + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); + } + + the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN); + + pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network); + if(pnetwork->network.Length > sizeof(WLAN_BSSID_EX)) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n")); + goto ignore_joinbss_callback; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_joinbss_event_callback !! _enter_critical \n")); + + if(pnetwork->join_res > 0) + { + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + retry = 0; + if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING) ) + { + //s1. find ptarget_wlan + if(check_fwstate(pmlmepriv, _FW_LINKED) ) + { + if(the_same_macaddr == _TRUE) + { + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + } + else + { + pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + if(pcur_wlan) pcur_wlan->fixed = _FALSE; + + pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(pcur_sta){ + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + rtw_free_stainfo(adapter, pcur_sta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + } + + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress); + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){ + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + } + } + + } + else + { + ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork); + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){ + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + } + } + + //s2. update cur_network + if(ptarget_wlan) + { + rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork); + } + else + { + DBG_871X_LEVEL(_drv_always_, "Can't find ptarget_wlan when joinbss_event callback\n"); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + + + //s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { + ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); + if (ptarget_sta == NULL) { + DBG_871X_LEVEL(_drv_err_, "Can't update stainfo when joinbss_event callback\n"); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + } + + //s4. indicate connect + if (MLME_IS_STA(adapter) || MLME_IS_ADHOC(adapter)) { + pmlmepriv->cur_network_scanned = ptarget_wlan; + rtw_indicate_connect(adapter); + } + + //s5. Cancle assoc_timer + _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("Cancle assoc_timer \n")); + + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv))); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + goto ignore_joinbss_callback; + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + } + else if(pnetwork->join_res == -4) + { + rtw_reset_securitypriv(adapter); + _set_timer(&pmlmepriv->assoc_timer, 1); + + //rtw_free_assoc_resources(adapter, 1); + + if((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv))); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + } + + } + else //if join_res < 0 (join fails), then try again + { + + #ifdef REJOIN + res = _FAIL; + if(retry < 2) { + res = rtw_select_and_join_from_scanned_queue(pmlmepriv); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_select_and_join_from_scanned_queue again! res:%d\n",res)); + } + + if(res == _SUCCESS) + { + //extend time of assoc_timer + _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); + retry++; + } + else if(res == 2)//there is no need to wait for join + { + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + rtw_indicate_connect(adapter); + } + else + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Set Assoc_Timer = 1; can't find match ssid in scanned_q \n")); + #endif + + _set_timer(&pmlmepriv->assoc_timer, 1); + //rtw_free_assoc_resources(adapter, 1); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + #ifdef REJOIN + retry = 0; + } + #endif + } + +ignore_joinbss_callback: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + _func_exit_; +} + +void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf) +{ + struct wlan_network *pnetwork = (struct wlan_network *)pbuf; + +_func_enter_; + + mlmeext_joinbss_event_callback(adapter, pnetwork->join_res); + + rtw_os_xmit_schedule(adapter); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_os_xmit_schedule(adapter->pbuddy_adapter); +#endif + +_func_exit_; +} + +void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected) +{ + struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl; + bool miracast_enabled = 0; + bool miracast_sink = 0; + u8 role = H2C_MSR_ROLE_RSVD; + + if (sta == NULL) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" sta is NULL\n" + , FUNC_ADPT_ARG(adapter)); + rtw_warn_on(1); + return; + } + + if (sta->mac_id >= macid_ctl->num) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" invalid macid:%u\n" + , FUNC_ADPT_ARG(adapter), sta->mac_id); + rtw_warn_on(1); + return; + } + + if (!rtw_macid_is_used(macid_ctl, sta->mac_id)) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u not is used, set connected to 0\n" + , FUNC_ADPT_ARG(adapter), sta->mac_id); + connected = 0; + rtw_warn_on(1); + } + + if (connected && !rtw_macid_is_bmc(macid_ctl, sta->mac_id)) { + miracast_enabled = STA_OP_WFD_MODE(sta) != 0 && is_miracast_enabled(adapter); + miracast_sink = miracast_enabled && (STA_OP_WFD_MODE(sta) & MIRACAST_SINK); + + #ifdef CONFIG_TDLS + if (sta->tdls_sta_state & TDLS_LINKED_STATE) + role = H2C_MSR_ROLE_TDLS; + else + #endif + if (MLME_IS_STA(adapter)) { + if (MLME_IS_GC(adapter)) + role = H2C_MSR_ROLE_GO; + else + role = H2C_MSR_ROLE_AP; + } else if (MLME_IS_AP(adapter)) { + if (MLME_IS_GO(adapter)) + role = H2C_MSR_ROLE_GC; + else + role = H2C_MSR_ROLE_STA; + } else if (MLME_IS_ADHOC(adapter) || MLME_IS_ADHOC_MASTER(adapter)) + role = H2C_MSR_ROLE_ADHOC; + + #ifdef CONFIG_WFD + if (role == H2C_MSR_ROLE_GC + || role == H2C_MSR_ROLE_GO + || role == H2C_MSR_ROLE_TDLS + ) { + if (adapter->wfd_info.rtsp_ctrlport + || adapter->wfd_info.tdls_rtsp_ctrlport + || adapter->wfd_info.peer_rtsp_ctrlport) + rtw_wfd_st_switch(sta, 1); + } + #endif + } + + rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter + , connected + , miracast_enabled + , miracast_sink + , role + , sta->mac_id + ); +} + +u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected) +{ + struct cmd_priv *cmdpriv = &adapter->cmdpriv; + struct cmd_obj *cmdobj; + struct drvextra_cmd_parm *cmd_parm; + struct sta_media_status_rpt_cmd_parm *rpt_parm; + u8 res = _SUCCESS; + + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (cmdobj == NULL) { + res = _FAIL; + goto exit; + } + + cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (cmd_parm == NULL) { + rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj)); + res = _FAIL; + goto exit; + } + + rpt_parm = (struct sta_media_status_rpt_cmd_parm *)rtw_zmalloc(sizeof(struct sta_media_status_rpt_cmd_parm)); + if (rpt_parm == NULL) { + rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj)); + rtw_mfree((u8 *)cmd_parm, sizeof(struct drvextra_cmd_parm)); + res = _FAIL; + goto exit; + } + + rpt_parm->sta = sta; + rpt_parm->connected = connected; + + cmd_parm->ec_id = STA_MSTATUS_RPT_WK_CID; + cmd_parm->type = 0; + cmd_parm->size = sizeof(struct sta_media_status_rpt_cmd_parm); + cmd_parm->pbuf = (u8 *)rpt_parm; + init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(cmdpriv, cmdobj); + +exit: + return res; +} + +inline void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm) +{ + rtw_sta_media_status_rpt(adapter, parm->sta, parm->connected); +} + +void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + struct sta_info *psta; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct stassoc_event *pstassoc = (struct stassoc_event*)pbuf; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wlan_network *ptarget_wlan = NULL; + +_func_enter_; + + if(rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE) + return; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); + if(psta) + { + u8 *passoc_req = NULL; + u32 assoc_req_len = 0; + + rtw_sta_media_status_rpt(adapter, psta, 1); + +#ifndef CONFIG_AUTO_AP_MODE + + ap_sta_info_defer_update(adapter, psta); + + //report to upper layer + DBG_871X("indicate_sta_assoc_event to upper layer - hostapd\n"); +#ifdef CONFIG_IOCTL_CFG80211 + _enter_critical_bh(&psta->lock, &irqL); + if(psta->passoc_req && psta->assoc_req_len>0) + { + passoc_req = rtw_zmalloc(psta->assoc_req_len); + if(passoc_req) + { + assoc_req_len = psta->assoc_req_len; + _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len); + + rtw_mfree(psta->passoc_req , psta->assoc_req_len); + psta->passoc_req = NULL; + psta->assoc_req_len = 0; + } + } + _exit_critical_bh(&psta->lock, &irqL); + + if(passoc_req && assoc_req_len>0) + { + rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len); + + rtw_mfree(passoc_req, assoc_req_len); + } +#else //!CONFIG_IOCTL_CFG80211 + rtw_indicate_sta_assoc_event(adapter, psta); +#endif //!CONFIG_IOCTL_CFG80211 +#endif //!CONFIG_AUTO_AP_MODE + +#ifdef CONFIG_BEAMFORMING + beamforming_wk_cmd(adapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0); +#endif/*CONFIG_BEAMFORMING*/ + } + goto exit; + } +#endif //defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + + /* for AD-HOC mode */ + psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); + if (psta == NULL) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" get no sta_info with "MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(pstassoc->macaddr)); + rtw_warn_on(1); + goto exit; + } + + rtw_hal_set_odm_var(adapter,HAL_ODM_STA_INFO,psta,_TRUE); + + rtw_sta_media_status_rpt(adapter, psta, 1); + + if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X) + psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm; + + + psta->ieee8021x_blocked = _FALSE; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) ) + { + if(adapter->stapriv.asoc_sta_count== 2) + { + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress); + pmlmepriv->cur_network_scanned = ptarget_wlan; + if(ptarget_wlan) ptarget_wlan->fixed = _TRUE; + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + // a sta + bc/mc_stainfo (not Ibss_stainfo) + rtw_indicate_connect(adapter); + } + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + + mlmeext_sta_add_event_callback(adapter, psta); + +#ifdef CONFIG_RTL8711 + //submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta + rtw_setstakey_cmd(adapter, psta, GROUP_KEY, _TRUE); +#endif + +exit: + +_func_exit_; + +} + +#ifdef CONFIG_IEEE80211W +void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL; + struct sta_info *psta; + struct stadel_event *pstadel = (struct stadel_event *)pbuf; + struct sta_priv *pstapriv = &adapter->stapriv; + +_func_enter_; + + psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); + + if (psta) { + u8 updated = _FALSE; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(adapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL); + } + + +_func_exit_; + +} +#endif /* CONFIG_IEEE80211W */ + +void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf) +{ + _irqL irqL,irqL2; + int mac_id = (-1); + struct sta_info *psta; + struct wlan_network* pwlan = NULL; + WLAN_BSSID_EX *pdev_network=NULL; + u8* pibss = NULL; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct stadel_event *pstadel = (struct stadel_event*)pbuf; + struct sta_priv *pstapriv = &adapter->stapriv; + struct wlan_network *tgt_network = &(pmlmepriv->cur_network); + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl; + +_func_enter_; + + psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr); + if(psta) + mac_id = psta->mac_id; + else + mac_id = pstadel->mac_id; + + DBG_871X("%s(mac_id=%d)=" MAC_FMT "\n", __func__, mac_id, MAC_ARG(pstadel->macaddr)); + + if (mac_id >= 0 && mac_id < macid_ctl->num) { + rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter, 0, 0, 0, 0, mac_id); + /* + * For safety, prevent from keeping macid sleep. + * If we can sure all power mode enter/leave are paired, + * this check can be removed. + * Lucas@20131113 + */ + /* wakeup macid after disconnect. */ + if (MLME_IS_STA(adapter)) + rtw_hal_macid_wakeup(adapter, mac_id); + + if (psta) + rtw_wfd_st_switch(psta, 0); + } else { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" invalid macid:%u\n" + , FUNC_ADPT_ARG(adapter), mac_id); + rtw_warn_on(1); + } + + //if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { +#ifdef CONFIG_IOCTL_CFG80211 + #ifdef COMPAT_KERNEL_RELEASE + + #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16*)pstadel->rsvd); + #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) +#endif //CONFIG_IOCTL_CFG80211 + + return; + } + + + mlmeext_sta_del_event_callback(adapter); + + _enter_critical_bh(&pmlmepriv->lock, &irqL2); + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) ) + { + u16 reason = *((unsigned short *)(pstadel->rsvd)); + bool roam = _FALSE; + struct wlan_network *roam_target = NULL; + + #ifdef CONFIG_LAYER2_ROAMING + if(adapter->registrypriv.wifi_spec==1) { + roam = _FALSE; + } else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED)) { + roam = _TRUE; + } else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { + roam = _TRUE; + roam_target = pmlmepriv->roam_network; + } +#ifdef CONFIG_INTEL_WIDI + else if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_CONNECTED) { + roam = _TRUE; + } +#endif // CONFIG_INTEL_WIDI + + if (roam == _TRUE) { + if (rtw_to_roam(adapter) > 0) + rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */ + else if (rtw_to_roam(adapter) == 0) + rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times); + } else { + rtw_set_to_roam(adapter, 0); + } + #endif /* CONFIG_LAYER2_ROAMING */ + + rtw_free_uc_swdec_pending_queue(adapter); + + 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 + pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + if (pwlan) { + pwlan->fixed = _FALSE; + rtw_free_network_nolock(adapter, pwlan); + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +#ifdef CONFIG_INTEL_WIDI + if (!rtw_to_roam(adapter)) + process_intel_widi_disconnect(adapter, 1); +#endif // CONFIG_INTEL_WIDI + + _rtw_roaming(adapter, roam_target); + } + + if ( check_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE) || + check_fwstate(pmlmepriv,WIFI_ADHOC_STATE)) + { + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(adapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo) + { + //rtw_indicate_disconnect(adapter);//removed@20091105 + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + //free old ibss network + //pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); + pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress); + if(pwlan) + { + pwlan->fixed = _FALSE; + rtw_free_network_nolock(adapter, pwlan); + } + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + //re-create ibss + pdev_network = &(adapter->registrypriv.dev_network); + pibss = adapter->registrypriv.dev_network.MacAddress; + + _rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network)); + + _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(adapter); + + rtw_generate_random_ibss(pibss); + + if(check_fwstate(pmlmepriv,WIFI_ADHOC_STATE)) + { + set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); + _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); + } + + if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS) + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error=>stadel_event_callback: rtw_create_ibss_cmd status FAIL***\n")); + + } + + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL2); + +_func_exit_; + +} + + +void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf) +{ +#ifdef CONFIG_LPS_LCLK + struct reportpwrstate_parm *preportpwrstate; +#endif + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("+rtw_cpwm_event_callback !!!\n")); +#ifdef CONFIG_LPS_LCLK + preportpwrstate = (struct reportpwrstate_parm*)pbuf; + preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80); + cpwm_int_hdl(padapter, preportpwrstate); +#endif + +_func_exit_; + +} + + +void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf) +{ +_func_enter_; + + WMMOnAssocRsp(padapter); + +_func_exit_; + +} + +/* +* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss +* @adapter: pointer to _adapter structure +*/ +void _rtw_join_timeout_handler (_adapter *adapter) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + +#if 0 + if (rtw_is_drv_stopped(adapter)) { + _rtw_up_sema(&pmlmepriv->assoc_terminate); + return; + } +#endif + +_func_enter_; + + + DBG_871X("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv)); + + if (RTW_CANNOT_RUN(adapter)) + return; + + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + #ifdef CONFIG_LAYER2_ROAMING + if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */ + while(1) { + rtw_dec_to_roam(adapter); + if (rtw_to_roam(adapter) != 0) { /* try another */ + int do_join_r; + DBG_871X("%s try another roaming\n", __FUNCTION__); + if( _SUCCESS!=(do_join_r=rtw_do_join(adapter)) ) { + DBG_871X("%s roaming do_join return %d\n", __FUNCTION__ ,do_join_r); + continue; + } + break; + } else { +#ifdef CONFIG_INTEL_WIDI + if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) + { + _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN); + intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL, 0); + DBG_871X("change to widi listen\n"); + } +#endif // CONFIG_INTEL_WIDI + DBG_871X("%s We've try roaming but fail\n", __FUNCTION__); + rtw_indicate_disconnect(adapter); + break; + } + } + + } else + #endif + { + rtw_indicate_disconnect(adapter); + free_scanqueue(pmlmepriv);//??? + +#ifdef CONFIG_IOCTL_CFG80211 + //indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED + rtw_cfg80211_indicate_disconnect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + +#ifdef CONFIG_DRVEXT_MODULE_WSC + drvext_assoc_fail_indicate(&adapter->drvextpriv); +#endif + + +_func_exit_; + +} + +/* +* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey +* @adapter: pointer to _adapter structure +*/ +void rtw_scan_timeout_handler (_adapter *adapter) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + DBG_871X(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv)); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_surveydone_event_callback(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_scan_done(adapter, _TRUE); + +#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211) + if (adapter->pbuddy_adapter) { + _adapter *buddy_adapter = adapter->pbuddy_adapter; + struct mlme_priv *buddy_mlme = &(buddy_adapter->mlmepriv); + struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(buddy_adapter); + bool indicate_buddy_scan = _FALSE; + + _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + if (buddy_wdev_priv->scan_request && buddy_mlme->scanning_via_buddy_intf == _TRUE) { + buddy_mlme->scanning_via_buddy_intf = _FALSE; + clr_fwstate(buddy_mlme, _FW_UNDER_SURVEY); + indicate_buddy_scan = _TRUE; + } + _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + + if (indicate_buddy_scan == _TRUE) { + rtw_indicate_scan_done(buddy_adapter, _TRUE); + } + } +#endif /* CONFIG_CONCURRENT_MODE */ +} + +void rtw_mlme_reset_auto_scan_int(_adapter *adapter) +{ + struct mlme_priv *mlme = &adapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) { + mlme->auto_scan_int_ms = 0; /* disabled */ + goto exit; + } +#endif + if(pmlmeinfo->VHT_enable) //disable auto scan when connect to 11AC AP + { + mlme->auto_scan_int_ms = 0; + } + else if(adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter) == _TRUE) { + mlme->auto_scan_int_ms = 60*1000; +#ifdef CONFIG_LAYER2_ROAMING + } else if(rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { + if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED)) + mlme->auto_scan_int_ms = mlme->roam_scan_int_ms; +#endif + } else { + mlme->auto_scan_int_ms = 0; /* disabled */ + } +exit: + return; +} + +void rtw_drv_scan_by_self(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if (!padapter->registrypriv.wifi_spec) { + if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) { + DBG_871X(FUNC_ADPT_FMT" _FW_UNDER_SURVEY|_FW_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } + + if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) { + DBG_871X(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } + } + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { + if ((check_buddy_fwstate(padapter, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)) == _TRUE) || + (padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)) { + DBG_871X(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or BusyTraffic\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } + } +#endif + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); + +exit: + return; +} + +static void rtw_auto_scan_handler(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + rtw_mlme_reset_auto_scan_int(padapter); + + if (pmlmepriv->auto_scan_int_ms != 0 + && rtw_get_passing_time_ms(pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) + rtw_drv_scan_by_self(padapter); + +} + +void rtw_dynamic_check_timer_handlder(_adapter *adapter) +{ +#ifdef CONFIG_AP_MODE + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; +#endif //CONFIG_AP_MODE + struct registry_priv *pregistrypriv = &adapter->registrypriv; +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = adapter->pbuddy_adapter; +#endif + + if(!adapter) + return; + + if (!rtw_is_hw_init_completed(adapter)) + return; + + if (RTW_CANNOT_RUN(adapter)) + return; + + +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_adapter) + { + if(adapter->net_closed == _TRUE && pbuddy_adapter->net_closed == _TRUE) + { + return; + } + } + else +#endif //CONFIG_CONCURRENT_MODE + if(adapter->net_closed == _TRUE) + { + return; + } + +#ifdef CONFIG_BT_COEXIST + if (is_primary_adapter(adapter)) { + if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) + DBG_871X("IsBtDisabled=%d, IsBtControlLps=%d\n" , rtw_btcoex_IsBtDisabled(adapter) , rtw_btcoex_IsBtControlLps(adapter)); + } +#endif + +#ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/ + if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode ==_TRUE ) +#ifdef CONFIG_BT_COEXIST + && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE) +#endif + ) + { + u8 bEnterPS; + + linked_status_chk(adapter, 1); + + bEnterPS = traffic_status_watchdog(adapter, 1); + if(bEnterPS) + { + //rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); + rtw_hal_dm_watchdog_in_lps(adapter); + } + else + { + //call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog() + } + + } + else +#endif //CONFIG_LPS_LCLK_WD_TIMER + { + if(is_primary_adapter(adapter)) + { + rtw_dynamic_chk_wk_cmd(adapter); + } + } + + /* auto site survey */ + rtw_auto_scan_handler(adapter); + +#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + expire_timeout_chk(adapter); + } +#endif +#endif //!CONFIG_ACTIVE_KEEP_ALIVE_CHECK + +#ifdef CONFIG_BR_EXT + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if( adapter->pnetdev->br_port +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if( rcu_dereference(adapter->pnetdev->rx_handler_data) +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) + { + // expire NAT2.5 entry + void nat25_db_expire(_adapter *priv); + nat25_db_expire(adapter); + + if (adapter->pppoe_connection_in_progress > 0) { + adapter->pppoe_connection_in_progress--; + } + + // due to rtw_dynamic_check_timer_handlder() is called every 2 seconds + if (adapter->pppoe_connection_in_progress > 0) { + adapter->pppoe_connection_in_progress--; + } + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + +#endif // CONFIG_BR_EXT + +} + + +#ifdef CONFIG_SET_SCAN_DENY_TIMER +inline bool rtw_is_scan_deny(_adapter *adapter) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; + return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE; +} + +inline void rtw_clear_scan_deny(_adapter *adapter) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; + ATOMIC_SET(&mlmepriv->set_scan_deny, 0); + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter)); +} + +void rtw_set_scan_deny_timer_hdl(_adapter *adapter) +{ + rtw_clear_scan_deny(adapter); +} + +void rtw_set_scan_deny(_adapter *adapter, u32 ms) +{ + struct mlme_priv *mlmepriv = &adapter->mlmepriv; +#ifdef CONFIG_CONCURRENT_MODE + struct mlme_priv *b_mlmepriv; +#endif + + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter)); + ATOMIC_SET(&mlmepriv->set_scan_deny, 1); + _set_timer(&mlmepriv->set_scan_deny_timer, ms); + +#ifdef CONFIG_CONCURRENT_MODE + if (!adapter->pbuddy_adapter) + return; + + if (0) + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter)); + b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv; + ATOMIC_SET(&b_mlmepriv->set_scan_deny, 1); + _set_timer(&b_mlmepriv->set_scan_deny_timer, ms); +#endif + +} +#endif + +#ifdef CONFIG_LAYER2_ROAMING +/* +* Select a new roaming candidate from the original @param candidate and @param competitor +* @return _TRUE: candidate is updated +* @return _FALSE: candidate is not updated +*/ +static int rtw_check_roaming_candidate(struct mlme_priv *mlme + , struct wlan_network **candidate, struct wlan_network *competitor) +{ + int updated = _FALSE; + _adapter *adapter = container_of(mlme, _adapter, mlmepriv); + + if(is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE) + goto exit; + + if(rtw_is_desired_network(adapter, competitor) == _FALSE) + goto exit; + + DBG_871X("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n", + (competitor == mlme->cur_network_scanned)?"*":" " , + competitor->network.Ssid.Ssid, + MAC_ARG(competitor->network.MacAddress), + competitor->network.Configuration.DSConfig, + (int)competitor->network.Rssi, + rtw_get_passing_time_ms(competitor->last_scanned) + ); + + /* got specific addr to roam */ + if (!is_zero_mac_addr(mlme->roam_tgt_addr)) { + if(_rtw_memcmp(mlme->roam_tgt_addr, competitor->network.MacAddress, ETH_ALEN) == _TRUE) + goto update; + else + goto exit; + } + #if 1 + if(rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms) + goto exit; + + if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th) + goto exit; + + if(*candidate != NULL && (*candidate)->network.Rssi>=competitor->network.Rssi) + goto exit; + #else + goto exit; + #endif + +update: + *candidate = competitor; + updated = _TRUE; + +exit: + return updated; +} + +int rtw_select_roaming_candidate(struct mlme_priv *mlme) +{ + _irqL irqL; + int ret = _FAIL; + _list *phead; + _adapter *adapter; + _queue *queue = &(mlme->scanned_queue); + struct wlan_network *pnetwork = NULL; + struct wlan_network *candidate = NULL; + u8 bSupportAntDiv = _FALSE; + +_func_enter_; + + if (mlme->cur_network_scanned == NULL) { + rtw_warn_on(1); + goto exit; + } + + _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL); + phead = get_list_head(queue); + adapter = (_adapter *)mlme->nic_hdl; + + mlme->pscanned = get_next(phead); + + while (!rtw_end_of_queue_search(phead, mlme->pscanned)) { + + pnetwork = LIST_CONTAINOR(mlme->pscanned, struct wlan_network, list); + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__)); + ret = _FAIL; + goto exit; + } + + mlme->pscanned = get_next(mlme->pscanned); + + if (0) + DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n" + , pnetwork->network.Ssid.Ssid + , MAC_ARG(pnetwork->network.MacAddress) + , pnetwork->network.Configuration.DSConfig + , (int)pnetwork->network.Rssi); + + rtw_check_roaming_candidate(mlme, &candidate, pnetwork); + + } + + if(candidate == NULL) { + DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__); + ret = _FAIL; + goto exit; + } else { + DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__, + candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress), + candidate->network.Configuration.DSConfig); + + mlme->roam_network = candidate; + + if (_rtw_memcmp(candidate->network.MacAddress, mlme->roam_tgt_addr, ETH_ALEN) == _TRUE) + _rtw_memset(mlme->roam_tgt_addr,0, ETH_ALEN); + } + + ret = _SUCCESS; +exit: + _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL); + + return ret; +} +#endif /* CONFIG_LAYER2_ROAMING */ + +/* +* Select a new join candidate from the original @param candidate and @param competitor +* @return _TRUE: candidate is updated +* @return _FALSE: candidate is not updated +*/ +static int rtw_check_join_candidate(struct mlme_priv *mlme + , struct wlan_network **candidate, struct wlan_network *competitor) +{ + int updated = _FALSE; + _adapter *adapter = container_of(mlme, _adapter, mlmepriv); + + + //check bssid, if needed + if(mlme->assoc_by_bssid==_TRUE) { + if(_rtw_memcmp(competitor->network.MacAddress, mlme->assoc_bssid, ETH_ALEN) ==_FALSE) + goto exit; + } + + //check ssid, if needed + if(mlme->assoc_ssid.Ssid[0] && mlme->assoc_ssid.SsidLength) { + if( competitor->network.Ssid.SsidLength != mlme->assoc_ssid.SsidLength + || _rtw_memcmp(competitor->network.Ssid.Ssid, mlme->assoc_ssid.Ssid, mlme->assoc_ssid.SsidLength) == _FALSE + ) + goto exit; + } + + if(rtw_is_desired_network(adapter, competitor) == _FALSE) + goto exit; + +#ifdef CONFIG_LAYER2_ROAMING + if(rtw_to_roam(adapter) > 0) { + if( rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms + || is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE + ) + goto exit; + } +#endif + + if(*candidate == NULL ||(*candidate)->network.Rssinetwork.Rssi ) + { + *candidate = competitor; + updated = _TRUE; + } + + if(updated){ + DBG_871X("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] " + "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n", + mlme->assoc_by_bssid, + mlme->assoc_ssid.Ssid, + rtw_to_roam(adapter), + (*candidate)->network.Ssid.Ssid, + MAC_ARG((*candidate)->network.MacAddress), + (*candidate)->network.Configuration.DSConfig, + (int)(*candidate)->network.Rssi + ); + } + +exit: + return updated; +} + +/* +Calling context: +The caller of the sub-routine will be in critical section... + +The caller must hold the following spinlock + +pmlmepriv->lock + + +*/ + +int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv ) +{ + _irqL irqL; + int ret; + _list *phead; + _adapter *adapter; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + struct wlan_network *candidate = NULL; + u8 bSupportAntDiv = _FALSE; + +_func_enter_; + + adapter = (_adapter *)pmlmepriv->nic_hdl; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + #ifdef CONFIG_LAYER2_ROAMING + if (pmlmepriv->roam_network) { + candidate = pmlmepriv->roam_network; + pmlmepriv->roam_network = NULL; + goto candidate_exist; + } + #endif + + phead = get_list_head(queue); + pmlmepriv->pscanned = get_next(phead); + + while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) { + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + if(pnetwork==NULL){ + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__)); + ret = _FAIL; + goto exit; + } + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + if (0) + DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n" + , pnetwork->network.Ssid.Ssid + , MAC_ARG(pnetwork->network.MacAddress) + , pnetwork->network.Configuration.DSConfig + , (int)pnetwork->network.Rssi); + + rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); + + } + + if(candidate == NULL) { + DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__); +#ifdef CONFIG_WOWLAN + _clr_fwstate_(pmlmepriv, _FW_LINKED|_FW_UNDER_LINKING); +#endif + ret = _FAIL; + goto exit; + } else { + DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__, + candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress), + candidate->network.Configuration.DSConfig); + goto candidate_exist; + } + +candidate_exist: + + // check for situation of _FW_LINKED + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { + DBG_871X("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__); + + #if 0 // for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... + if(is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) + { + DBG_871X("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__); + + rtw_indicate_connect(adapter);//rtw_indicate_connect again + + ret = 2; + goto exit; + } + else + #endif + { + rtw_disassoc_cmd(adapter, 0, _TRUE); + rtw_indicate_disconnect(adapter); + rtw_free_assoc_resources(adapter, 0); + } + } + + #ifdef CONFIG_ANTENNA_DIVERSITY + rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv)); + if(_TRUE == bSupportAntDiv) + { + u8 CurrentAntenna; + rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna)); + DBG_871X("#### Opt_Ant_(%s) , cur_Ant(%s)\n", + (2==candidate->network.PhyInfo.Optimum_antenna)?"A":"B", + (2==CurrentAntenna)?"A":"B" + ); + } + #endif + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + ret = rtw_joinbss_cmd(adapter, candidate); + +exit: + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +_func_exit_; + + return ret; +} + +sint rtw_set_auth(_adapter * adapter,struct security_priv *psecuritypriv) +{ + struct cmd_obj* pcmd; + struct setauth_parm *psetauthparm; + struct cmd_priv *pcmdpriv=&(adapter->cmdpriv); + sint res=_SUCCESS; + +_func_enter_; + + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + res= _FAIL; //try again + goto exit; + } + + psetauthparm=(struct setauth_parm*)rtw_zmalloc(sizeof(struct setauth_parm)); + if(psetauthparm==NULL){ + rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm)); + psetauthparm->mode=(unsigned char)psecuritypriv->dot11AuthAlgrthm; + + pcmd->cmdcode = _SetAuth_CMD_; + pcmd->parmbuf = (unsigned char *)psetauthparm; + pcmd->cmdsz = (sizeof(struct setauth_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + + _rtw_init_listhead(&pcmd->list); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("after enqueue set_auth_cmd, auth_mode=%x\n", psecuritypriv->dot11AuthAlgrthm)); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +exit: + +_func_exit_; + + return res; + +} + + +sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx, bool enqueue) +{ + u8 keylen; + struct cmd_obj *pcmd; + struct setkey_parm *psetkeyparm; + struct cmd_priv *pcmdpriv = &(adapter->cmdpriv); + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + sint res=_SUCCESS; + +_func_enter_; + + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ + res= _FAIL; + goto exit; + } + _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm)); + + if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){ + psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n", psetkeyparm->algorithm)); + } + else{ + psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm; + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n", psetkeyparm->algorithm)); + + } + psetkeyparm->keyid = (u8)keyid;//0~3 + psetkeyparm->set_tx = set_tx; + if (is_wep_enc(psetkeyparm->algorithm)) + adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid); + + DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid, adapter->securitypriv.key_mask); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid)); + + switch(psetkeyparm->algorithm){ + + case _WEP40_: + keylen=5; + _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + break; + case _WEP104_: + keylen=13; + _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen); + break; + case _TKIP_: + keylen=16; + _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); + psetkeyparm->grpkey=1; + break; + case _AES_: + keylen=16; + _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen); + psetkeyparm->grpkey=1; + break; + default: + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",psecuritypriv->dot11PrivacyAlgrthm)); + res= _FAIL; + rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm)); + goto exit; + } + + + if(enqueue){ + pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmd==NULL){ + rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm)); + res= _FAIL; //try again + goto exit; + } + + pcmd->cmdcode = _SetKey_CMD_; + pcmd->parmbuf = (u8 *)psetkeyparm; + pcmd->cmdsz = (sizeof(struct setkey_parm)); + pcmd->rsp = NULL; + pcmd->rspsz = 0; + + _rtw_init_listhead(&pcmd->list); + + //_rtw_init_sema(&(pcmd->cmd_sem), 0); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + } + else{ + setkey_hdl(adapter, (u8 *)psetkeyparm); + rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm)); + } +exit: +_func_exit_; + return res; + +} + + +//adjust IEs for rtw_joinbss_cmd in WMM +int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len) +{ + unsigned int ielength=0; + unsigned int i, j; + + i = 12; //after the fixed IE + while(i=0 :if there is pre-auth key, and return the entry id +// +// + +static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid) +{ + struct security_priv *psecuritypriv=&Adapter->securitypriv; + int i=0; + + do + { + if( ( psecuritypriv->PMKIDList[i].bUsed ) && + ( _rtw_memcmp( psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN ) == _TRUE ) ) + { + break; + } + else + { + i++; + //continue; + } + + }while(isecuritypriv; + + 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;imlmepriv; + struct security_priv *psecuritypriv=&adapter->securitypriv; + uint ndisauthmode=psecuritypriv->ndisauthtype; + uint ndissecuritytype = psecuritypriv->ndisencryptstatus; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n", + ndisauthmode, ndissecuritytype)); + + //copy fixed ie only + _rtw_memcpy(out_ie, in_ie,12); + ielength=12; + if((ndisauthmode==Ndis802_11AuthModeWPA)||(ndisauthmode==Ndis802_11AuthModeWPAPSK)) + authmode=_WPA_IE_ID_; + if((ndisauthmode==Ndis802_11AuthModeWPA2)||(ndisauthmode==Ndis802_11AuthModeWPA2PSK)) + authmode=_WPA2_IE_ID_; + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + _rtw_memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); + + ielength += psecuritypriv->wps_ie_len; + } + else if((authmode==_WPA_IE_ID_)||(authmode==_WPA2_IE_ID_)) + { + //copy RSN or SSN + _rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2); + /* debug for CONFIG_IEEE80211W + { + int jj; + printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2); + for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++) + printk(" %02x ", psecuritypriv->supplicant_ie[jj]); + printk("\n"); + }*/ + ielength+=psecuritypriv->supplicant_ie[1]+2; + rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); + +#ifdef CONFIG_DRVEXT_MODULE + drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie); +#endif + } + + iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); + if(iEntry<0) + { + 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_; + + return ielength; +} + +void rtw_init_registrypriv_dev_network( _adapter* adapter) +{ + struct registry_priv* pregistrypriv = &adapter->registrypriv; + WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network; + u8 *myhwaddr = adapter_mac_addr(adapter); + +_func_enter_; + + _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); + + _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID)); + + pdev_network->Configuration.Length=sizeof(NDIS_802_11_CONFIGURATION); + pdev_network->Configuration.BeaconPeriod = 100; + pdev_network->Configuration.FHConfig.Length = 0; + pdev_network->Configuration.FHConfig.HopPattern = 0; + pdev_network->Configuration.FHConfig.HopSet = 0; + pdev_network->Configuration.FHConfig.DwellTime = 0; + + +_func_exit_; + +} + +void rtw_update_registrypriv_dev_network(_adapter* adapter) +{ + int sz=0; + struct registry_priv* pregistrypriv = &adapter->registrypriv; + WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network; + struct security_priv* psecuritypriv = &adapter->securitypriv; + struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; + //struct xmit_priv *pxmitpriv = &adapter->xmitpriv; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + +_func_enter_; + +#if 0 + pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; + pxmitpriv->vcs = pregistrypriv->vcs_type; + pxmitpriv->vcs_type = pregistrypriv->vcs_type; + //pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; + pxmitpriv->frag_len = pregistrypriv->frag_thresh; + + adapter->qospriv.qos_option = pregistrypriv->wmm_enable; +#endif + + pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; // adhoc no 802.1x + + pdev_network->Rssi = 0; + + switch(pregistrypriv->wireless_mode) + { + case WIRELESS_11B: + pdev_network->NetworkTypeInUse = (Ndis802_11DS); + break; + case WIRELESS_11G: + case WIRELESS_11BG: + case WIRELESS_11_24N: + case WIRELESS_11G_24N: + case WIRELESS_11BG_24N: + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); + break; + case WIRELESS_11A: + case WIRELESS_11A_5N: + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5); + break; + case WIRELESS_11ABGN: + if(pregistrypriv->channel > 14) + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5); + else + pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24); + break; + default : + // TODO + break; + } + + pdev_network->Configuration.DSConfig = (pregistrypriv->channel); + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig)); + + if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) { + pdev_network->Configuration.ATIMWindow = (0); + + if (pmlmeext->cur_channel != 0) + pdev_network->Configuration.DSConfig = pmlmeext->cur_channel; + else + pdev_network->Configuration.DSConfig = 1; + } + + pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode); + + // 1. Supported rates + // 2. IE + + //rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; // will be called in rtw_generate_ie + sz = rtw_generate_ie(pregistrypriv); + + pdev_network->IELength = sz; + + pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pdev_network); + + //notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); + //pdev_network->IELength = cpu_to_le32(sz); + +_func_exit_; + +} + +void rtw_get_encrypt_decrypt_from_registrypriv(_adapter* adapter) +{ +_func_enter_; + + +_func_exit_; + +} + +//the fucntion is at passive_level +void rtw_joinbss_reset(_adapter *padapter) +{ + u8 threshold; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + //todo: if you want to do something io/reg/hw setting before join_bss, please add code here + +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + + pmlmepriv->num_FortyMHzIntolerant = 0; + + pmlmepriv->num_sta_no_ht = 0; + + phtpriv->ampdu_enable = _FALSE;//reset to disabled + +#if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) + // TH=1 => means that invalidate usb rx aggregation + // TH=0 => means that validate usb rx aggregation, use init value. + if(phtpriv->ht_option) + { + if(padapter->registrypriv.wifi_spec==1) + threshold = 1; + else + threshold = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } + else + { + threshold = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } +#endif//#if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) + +#endif//#ifdef CONFIG_80211N_HT + +} + + +#ifdef CONFIG_80211N_HT +void rtw_ht_use_default_setting(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE; + BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE; + + if (pregistrypriv->wifi_spec) + phtpriv->bss_coexist = 1; + else + phtpriv->bss_coexist = 0; + + phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? _TRUE : _FALSE; + phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? _TRUE : _FALSE; + + // LDPC support + rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport); + CLEAR_FLAGS(phtpriv->ldpc_cap); + if(bHwLDPCSupport) + { + if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT4)) + SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX); + } + rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport); + if(bHwLDPCSupport) + { + if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT5)) + SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX); + } + if (phtpriv->ldpc_cap) + DBG_871X("[HT] HAL Support LDPC = 0x%02X\n", phtpriv->ldpc_cap); + + // STBC + rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport); + CLEAR_FLAGS(phtpriv->stbc_cap); + if(bHwSTBCSupport) + { + if(TEST_FLAG(pregistrypriv->stbc_cap, BIT5)) + SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX); + } + rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport); + if(bHwSTBCSupport) + { + if(TEST_FLAG(pregistrypriv->stbc_cap, BIT4)) + SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX); + } + if (phtpriv->stbc_cap) + DBG_871X("[HT] HAL Support STBC = 0x%02X\n", phtpriv->stbc_cap); + + // Beamforming setting + rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer); + rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee); + CLEAR_FLAGS(phtpriv->beamform_cap); + if(TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer) + { + SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); + DBG_871X("[HT] HAL Support Beamformer\n"); + } + if(TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee) + { + SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + DBG_871X("[HT] HAL Support Beamformee\n"); + } +} +void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len) +{ + unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; + int out_len; + u8 *pframe; + + if(padapter->mlmepriv.qospriv.qos_option == 0) + { + out_len = *pout_len; + pframe = rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_, + _WMM_IE_Length_, WMM_IE, pout_len); + + padapter->mlmepriv.qospriv.qos_option = 1; + } +} + +/* the fucntion is >= passive_level */ +unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel) +{ + u32 ielen, out_len; + HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor; + HT_CAP_AMPDU_DENSITY best_ampdu_density; + unsigned char *p, *pframe; + struct rtw_ieee80211_ht_cap ht_capie; + u8 cbw40_enable = 0, rf_type = 0, operation_bw = 0, rf_num = 0, rx_stbc_nss = 0; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + phtpriv->ht_option = _FALSE; + + out_len = *pout_len; + + _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap)); + + ht_capie.cap_info = IEEE80211_HT_CAP_DSSSCCK40; + + if (phtpriv->sgi_20m) + ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_20; + + /* Get HT BW */ + if (in_ie == NULL) { + /* TDLS: TODO 20/40 issue */ + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + operation_bw = padapter->mlmeextpriv.cur_bwmode; + if (operation_bw > CHANNEL_WIDTH_40) + operation_bw = CHANNEL_WIDTH_40; + } else + /* TDLS: TODO 40? */ + operation_bw = CHANNEL_WIDTH_40; + } else { + p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len); + if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { + struct HT_info_element *pht_info = (struct HT_info_element *)(p+2); + if (pht_info->infos[0] & BIT(2)) { + switch (pht_info->infos[0] & 0x3) { + case 1: + case 3: + operation_bw = CHANNEL_WIDTH_40; + break; + default: + operation_bw = CHANNEL_WIDTH_20; + break; + } + } else { + operation_bw = CHANNEL_WIDTH_20; + } + } + } + + /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */ + if (hal_chk_bw_cap(padapter, BW_CAP_40M)) { + if (channel > 14) { + if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } else { + if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } + } + + if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) { + ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH; + if (phtpriv->sgi_40m) + ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_40; + } + + /* todo: disable SM power save mode */ + ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS; + + /* RX LDPC */ + if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) { + ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; + DBG_871X("[HT] Declare supporting RX LDPC\n"); + } + + /* TX STBC */ + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) { + ht_capie.cap_info |= IEEE80211_HT_CAP_TX_STBC; + DBG_871X("[HT] Declare supporting TX STBC\n"); + } + + /* RX STBC */ + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) { + if((pregistrypriv->rx_stbc == 0x3) || /* enable for 2.4/5 GHz */ + ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */ + ((channel > 14) && (pregistrypriv->rx_stbc == 0x2)) || /* enable for 5GHz */ + (pregistrypriv->wifi_spec == 1)) { + /* HAL_DEF_RX_STBC means STBC RX spatial stream, todo: VHT 4 streams */ + rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss)); + SET_HT_CAP_ELE_RX_STBC(&ht_capie, rx_stbc_nss); + DBG_871X("[HT] Declare supporting RX STBC = %d\n", rx_stbc_nss); + } + } + + //fill default supported_mcs_set + _rtw_memcpy(ht_capie.supp_mcs_set, pmlmeext->default_supported_mcs_set, 16); + + //update default supported_mcs_set + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + switch(rf_type) + { + case RF_1T1R: + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R); + break; + + case RF_2T2R: + case RF_1T2R: + #ifdef CONFIG_DISABLE_MCS13TO15 + if(((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) && (pregistrypriv->wifi_spec!=1)) + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R_13TO15_OFF); + else + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R); + #else //CONFIG_DISABLE_MCS13TO15 + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R); + #endif //CONFIG_DISABLE_MCS13TO15 + break; + case RF_3T3R: + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R); + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + } + + { + u32 rx_packet_offset, max_recvbuf_sz; + rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); + rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); + //if(max_recvbuf_sz-rx_packet_offset>(8191-256)) { + // DBG_871X("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__); + // ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU; + //} + } + /* + AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + AMPDU_para [4:2]:Min MPDU Start Spacing + */ + + /* + #if defined(CONFIG_RTL8188E )&& defined (CONFIG_SDIO_HCI) + ht_capie.ampdu_params_info = 2; + #else + ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03); + #endif + */ + + if(padapter->driver_rx_ampdu_factor != 0xFF) + max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor; + else + rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); + + //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->driver_rx_ampdu_spacing != 0xFF) + { + ht_capie.ampdu_params_info |= (( padapter->driver_rx_ampdu_spacing&0x07) <<2); + } + else + { + if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) { + /* + * Todo : Each chip must to ask DD , this chip best ampdu_density setting + * By yiwei.sun + */ + rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density); + + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2)); + + } else + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + } +#ifdef CONFIG_BEAMFORMING + ht_capie.tx_BF_cap_info = 0; + + /* HT Beamformer*/ + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + /* Transmit NDP Capable */ + SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(&ht_capie, 1); + /* Explicit Compressed Steering Capable */ + SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(&ht_capie, 1); + /* Compressed Steering Number Antennas */ + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, 1); + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num); + SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(&ht_capie, rf_num); + } + + /* HT Beamformee */ + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) { + /* Receive NDP Capable */ + SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(&ht_capie, 1); + /* Explicit Compressed Beamforming Feedback Capable */ + SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(&ht_capie, 2); + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num); + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, rf_num); + } +#endif/*CONFIG_BEAMFORMING*/ + + pframe = rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_, + sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, pout_len); + + phtpriv->ht_option = _TRUE; + + if(in_ie!=NULL) + { + p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len); + if(p && (ielen==sizeof(struct ieee80211_ht_addt_info))) + { + out_len = *pout_len; + pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len); + } + } + + return (phtpriv->ht_option); + +} + +//the fucntion is > passive_level (in critical_section) +void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel) +{ + u8 *p, max_ampdu_sz; + int len; + //struct sta_info *bmc_sta, *psta; + struct rtw_ieee80211_ht_cap *pht_capie; + struct ieee80211_ht_addt_info *pht_addtinfo; + //struct recv_reorder_ctrl *preorder_ctrl; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + //struct recv_priv *precvpriv = &padapter->recvpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + //struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 cbw40_enable=0; + + + if(!phtpriv->ht_option) + return; + + if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable)) + return; + + DBG_871X("+rtw_update_ht_cap()\n"); + + //maybe needs check if ap supports rx ampdu. + if((phtpriv->ampdu_enable==_FALSE) &&(pregistrypriv->ampdu_enable==1)) + { + if(pregistrypriv->wifi_spec==1) + { + //remove this part because testbed AP should disable RX AMPDU + //phtpriv->ampdu_enable = _FALSE; + phtpriv->ampdu_enable = _TRUE; + } + else + { + phtpriv->ampdu_enable = _TRUE; + } + } + else if(pregistrypriv->ampdu_enable==2) + { + //remove this part because testbed AP should disable RX AMPDU + //phtpriv->ampdu_enable = _TRUE; + } + + + //check Max Rx A-MPDU Size + len = 0; + p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs)); + if(p && len>0) + { + pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2); + max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR); + max_ampdu_sz = 1 << (max_ampdu_sz+3); // max_ampdu_sz (kbytes); + + //DBG_871X("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); + phtpriv->rx_ampdu_maxlen = max_ampdu_sz; + + } + + + len=0; + p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs)); + if(p && len>0) + { + pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2); + //todo: + } + + if (hal_chk_bw_cap(padapter, BW_CAP_40M)) { + if (channel > 14) { + if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } else { + if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } + } + + //update cur_bwmode & cur_ch_offset + if ((cbw40_enable) && + (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && + (pmlmeinfo->HT_info.infos[0] & BIT(2))) + { + int i; + u8 rf_type = RF_1T1R; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + //update the MCS set + for (i = 0; i < 16; i++) + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; + + //update the MCS rates + switch(rf_type) + { + case RF_1T1R: + case RF_1T2R: + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); + break; + case RF_2T2R: + #ifdef CONFIG_DISABLE_MCS13TO15 + if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 ) + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF); + else + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R); +#else //CONFIG_DISABLE_MCS13TO15 + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R); +#endif //CONFIG_DISABLE_MCS13TO15 + break; + case RF_3T3R: + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R); + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + } + + //switch to the 40M Hz mode accoring to the AP + //pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; + switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) + { + case EXTCHNL_OFFSET_UPPER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case EXTCHNL_OFFSET_LOWER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + } + + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; + + + +#if 0 //move to rtw_update_sta_info_client() + //for A-MPDU Rx reordering buffer control for bmc_sta & sta_info + //if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff + //todo: check if AP can send A-MPDU packets + bmc_sta = rtw_get_bcmc_stainfo(padapter); + if(bmc_sta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + } + + psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress); + if(psta) + { + for(i=0; i < 16 ; i++) + { + //preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; + preorder_ctrl = &psta->recvreorder_ctrl[i]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32 + } + } +#endif + +} + +#ifdef CONFIG_TDLS +void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct pkt_attrib *pattrib =&pxmitframe->attrib; + struct sta_info *ptdls_sta = NULL; + u8 issued; + int priority; + struct ht_priv *phtpriv; + + priority = pattrib->priority; + + if (pattrib->direct_link == _TRUE) { + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst); + if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) { + phtpriv = &ptdls_sta->htpriv; + + if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) { + issued = (phtpriv->agg_enable_bitmap>>priority)&0x1; + issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1; + + if (0 == issued) { + DBG_871X("[%s], p=%d\n", __FUNCTION__, priority); + ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); + rtw_addbareq_cmd(padapter,(u8)priority, pattrib->dst); + } + } + } + } +} +#endif //CONFIG_TDLS + +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + u8 issued; + int priority; + struct sta_info *psta=NULL; + struct ht_priv *phtpriv; + struct pkt_attrib *pattrib =&pxmitframe->attrib; + s32 bmcst = IS_MCAST(pattrib->ra); + + //if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE)) + if(bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod<100)) + return; + + priority = pattrib->priority; + +#ifdef CONFIG_TDLS + rtw_issue_addbareq_cmd_tdls(padapter, pxmitframe); +#endif //CONFIG_TDLS + + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return; + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return; + } + + + phtpriv = &psta->htpriv; + + if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) + { + issued = (phtpriv->agg_enable_bitmap>>priority)&0x1; + issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1; + + if(0==issued) + { + DBG_871X("rtw_issue_addbareq_cmd, p=%d\n", priority); + psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); + rtw_addbareq_cmd(padapter,(u8) priority, pattrib->ra); + } + } + +} + +void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; +#ifdef CONFIG_80211AC_VHT + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; +#endif //CONFIG_80211AC_VHT + u8 cap_content[8] = { 0 }; + u8 *pframe; + u8 null_content[8] = {0}; + + if (phtpriv->bss_coexist) { + SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1); + } + +#ifdef CONFIG_80211AC_VHT + if (pvhtpriv->vht_option) { + SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1); + } +#endif //CONFIG_80211AC_VHT + /* + From 802.11 specification,if a STA does not support any of capabilities defined + in the Extended Capabilities element, then the STA is not required to + transmit the Extended Capabilities element. + */ + if (_FALSE == _rtw_memcmp(cap_content, null_content, 8)) + pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len); +} +#endif + +#ifdef CONFIG_LAYER2_ROAMING +inline void rtw_set_to_roam(_adapter *adapter, u8 to_roam) +{ + if (to_roam == 0) + adapter->mlmepriv.to_join = _FALSE; + adapter->mlmepriv.to_roam = to_roam; +} + +inline u8 rtw_dec_to_roam(_adapter *adapter) +{ + adapter->mlmepriv.to_roam--; + return adapter->mlmepriv.to_roam; +} + +inline u8 rtw_to_roam(_adapter *adapter) +{ + return adapter->mlmepriv.to_roam; +} + +void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _rtw_roaming(padapter, tgt_network); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} +void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; + int do_join_r; + + if(0 < rtw_to_roam(padapter)) { + DBG_871X("roaming from %s("MAC_FMT"), length:%d\n", + cur_network->network.Ssid.Ssid, MAC_ARG(cur_network->network.MacAddress), + cur_network->network.Ssid.SsidLength); + _rtw_memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.Ssid, sizeof(NDIS_802_11_SSID)); + + pmlmepriv->assoc_by_bssid = _FALSE; + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_return_all_sta_info(padapter); +#endif + + while(1) { + if( _SUCCESS==(do_join_r=rtw_do_join(padapter)) ) { + break; + } else { + DBG_871X("roaming do_join return %d\n", do_join_r); + rtw_dec_to_roam(padapter); + + if(rtw_to_roam(padapter) > 0) { + continue; + } else { + DBG_871X("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__,__LINE__); + rtw_indicate_disconnect(padapter); + break; + } + } + } + } + +} +#endif /* CONFIG_LAYER2_ROAMING */ + +bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset) +{ + struct registry_priv *regsty = adapter_to_regsty(adapter); + u8 allowed_bw; + + if (req_ch <= 14) + allowed_bw = REGSTY_BW_2G(regsty); + else + allowed_bw = REGSTY_BW_5G(regsty); + + allowed_bw = hal_largest_bw(adapter, allowed_bw); + + if (allowed_bw == CHANNEL_WIDTH_80 && *req_bw > CHANNEL_WIDTH_80) + *req_bw = CHANNEL_WIDTH_80; + else if (allowed_bw == CHANNEL_WIDTH_40 && *req_bw > CHANNEL_WIDTH_40) + *req_bw = CHANNEL_WIDTH_40; + else if (allowed_bw == CHANNEL_WIDTH_20 && *req_bw > CHANNEL_WIDTH_20) { + *req_bw = CHANNEL_WIDTH_20; + *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } else + return _FALSE; + + return _TRUE; +} + +sint rtw_linked_check(_adapter *padapter) +{ + if( (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) || + (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + if(padapter->stapriv.asoc_sta_count > 2) + return _TRUE; + } + else + { //Station mode + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _TRUE) + return _TRUE; + } + return _FALSE; +} + +#ifdef CONFIG_CONCURRENT_MODE +sint rtw_buddy_adapter_up(_adapter *padapter) +{ + sint res = _FALSE; + + if(padapter == NULL) + return res; + + + if(padapter->pbuddy_adapter == NULL) + res = _FALSE; + else if (RTW_CANNOT_RUN(padapter) || + (padapter->pbuddy_adapter->bup == _FALSE) || (!rtw_is_hw_init_completed(padapter))) + res = _FALSE; + else + res = _TRUE; + + return res; + +} + +sint check_buddy_fwstate(_adapter *padapter, sint state) +{ + if(padapter == NULL) + return _FALSE; + + if(padapter->pbuddy_adapter == NULL) + return _FALSE; + + if ((state == WIFI_FW_NULL_STATE) && + (padapter->pbuddy_adapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE)) + return _TRUE; + + if (padapter->pbuddy_adapter->mlmepriv.fw_state & state) + return _TRUE; + + return _FALSE; +} + +u8 rtw_get_buddy_bBusyTraffic(_adapter *padapter) +{ + if(padapter == NULL) + return _FALSE; + + if(padapter->pbuddy_adapter == NULL) + return _FALSE; + + return padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic; +} + +#endif //CONFIG_CONCURRENT_MODE + +bool is_miracast_enabled(_adapter *adapter) +{ + bool enabled = 0; +#ifdef CONFIG_WFD + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + enabled = (wfdinfo->stack_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK)) + || (wfdinfo->op_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK)); +#endif + + return enabled; +} + +bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode) +{ + bool ret = 0; +#ifdef CONFIG_WFD + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + ret = (wfdinfo->stack_wfd_mode & mode) || (wfdinfo->op_wfd_mode & mode); +#endif + + return ret; +} + +const char *get_miracast_mode_str(int mode) +{ + if (mode == MIRACAST_SOURCE) + return "SOURCE"; + else if (mode == MIRACAST_SINK) + return "SINK"; + else if (mode == (MIRACAST_SOURCE | MIRACAST_SINK)) + return "SOURCE&SINK"; + else if (mode == MIRACAST_DISABLED) + return "DISABLED"; + else + return "INVALID"; +} + +#ifdef CONFIG_WFD +static bool wfd_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + if (ntohs(*((u16 *)local_port)) == wfdinfo->rtsp_ctrlport + || ntohs(*((u16 *)local_port)) == wfdinfo->tdls_rtsp_ctrlport + || ntohs(*((u16 *)remote_port)) == wfdinfo->peer_rtsp_ctrlport) + return _TRUE; + return _FALSE; +} + +static struct st_register wfd_st_reg = { + .s_proto = 0x06, + .rule = wfd_st_match_rule, +}; +#endif /* CONFIG_WFD */ + +inline void rtw_wfd_st_switch(struct sta_info *sta, bool on) +{ +#ifdef CONFIG_WFD + if (on) + rtw_st_ctl_register(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD, &wfd_st_reg); + else + rtw_st_ctl_unregister(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD); +#endif +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme_ext.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme_ext.c new file mode 100644 index 00000000..549113e8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mlme_ext.c @@ -0,0 +1,15390 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_MLME_EXT_C_ + +#include +#ifdef CONFIG_IOCTL_CFG80211 +#include +#endif //CONFIG_IOCTL_CFG80211 +#include + + +struct mlme_handler mlme_sta_tbl[]={ + {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, + {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, + {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, + {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, + {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, + {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, + + /*---------------------------------------------------------- + below 2 are reserved + -----------------------------------------------------------*/ + {0, "DoReserved", &DoReserved}, + {0, "DoReserved", &DoReserved}, + {WIFI_BEACON, "OnBeacon", &OnBeacon}, + {WIFI_ATIM, "OnATIM", &OnAtim}, + {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, + {WIFI_AUTH, "OnAuth", &OnAuthClient}, + {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, + {WIFI_ACTION, "OnAction", &OnAction}, + {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction}, +}; + +#ifdef _CONFIG_NATIVEAP_MLME_ +struct mlme_handler mlme_ap_tbl[]={ + {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, + {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, + {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, + {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, + {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, + {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, + + /*---------------------------------------------------------- + below 2 are reserved + -----------------------------------------------------------*/ + {0, "DoReserved", &DoReserved}, + {0, "DoReserved", &DoReserved}, + {WIFI_BEACON, "OnBeacon", &OnBeacon}, + {WIFI_ATIM, "OnATIM", &OnAtim}, + {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, + {WIFI_AUTH, "OnAuth", &OnAuth}, + {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, + {WIFI_ACTION, "OnAction", &OnAction}, + {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction}, +}; +#endif + +struct action_handler OnAction_tbl[]={ + {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, + {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos}, + {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls}, + {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, + {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, + {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, + {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, + {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, +#ifdef CONFIG_IEEE80211W + {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query}, +#else + {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved}, +#endif //CONFIG_IEEE80211W + //add for CONFIG_IEEE80211W + {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved}, + {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved}, + {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm}, + {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht}, + {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p}, +}; + + +u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0}; + +/************************************************** +OUI definitions for the vendor specific IE +***************************************************/ +unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; +unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; +unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; +unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09}; +unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A}; + +unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; +unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + +unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02}; +unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02}; + +extern unsigned char REALTEK_96B_IE[]; + +#ifdef LEGACY_CHANNEL_PLAN_REF +/******************************************************** +ChannelPlan definitions +*********************************************************/ +static RT_CHANNEL_PLAN legacy_channel_plan[] = { + /* 0x00, RTW_CHPLAN_FCC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 32}, + /* 0x01, RTW_CHPLAN_IC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 31}, + /* 0x02, RTW_CHPLAN_ETSI */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32}, + /* 0x03, RTW_CHPLAN_SPAIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 0x04, RTW_CHPLAN_FRANCE */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 0x05, RTW_CHPLAN_MKK */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 0x06, RTW_CHPLAN_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 0x07, RTW_CHPLAN_ISRAEL */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, + /* 0x08, RTW_CHPLAN_TELEC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, + /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, + /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 0x0B, RTW_CHPLAN_TAIWAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 26}, + /* 0x0C, RTW_CHPLAN_CHINA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 149, 153, 157, 161, 165}, 18}, + /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, + /* 0x0E, RTW_CHPLAN_KOREA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 31}, + /* 0x0F, RTW_CHPLAN_TURKEY */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, + /* 0x10, RTW_CHPLAN_JAPAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32}, + /* 0x11, RTW_CHPLAN_FCC_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165}, 20}, + /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48}, 17}, + /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 37}, + /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 149, 153, 157, 161, 165}, 19}, +}; +#endif + +static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[] = { + /* 0, RTW_RD_2G_NULL */ {{}, 0}, + /* 1, RTW_RD_2G_WORLD */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 2, RTW_RD_2G_ETSI1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + /* 3, RTW_RD_2G_FCC1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, + /* 4, RTW_RD_2G_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, + /* 5, RTW_RD_2G_ETSI2 */ {{10, 11, 12, 13}, 4}, + /* 6, RTW_RD_2G_GLOBAL */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, + /* 7, RTW_RD_2G_MKK2 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, +}; + +static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[] = { + /* 0, RTW_RD_5G_NULL */ {{}, 0}, + /* 1, RTW_RD_5G_ETSI1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, + /* 2, RTW_RD_5G_ETSI2 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, + /* 3, RTW_RD_5G_ETSI3 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, + /* 4, RTW_RD_5G_FCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, + /* 5, RTW_RD_5G_FCC2 */ {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, + /* 6, RTW_RD_5G_FCC3 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, + /* 7, RTW_RD_5G_FCC4 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, + /* 8, RTW_RD_5G_FCC5 */ {{149, 153, 157, 161, 165}, 5}, + /* 9, RTW_RD_5G_FCC6 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, + /* 10, RTW_RD_5G_FCC7 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, + /* 11, RTW_RD_5G_KCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161}, 19}, + /* 12, RTW_RD_5G_MKK1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, + /* 13, RTW_RD_5G_MKK2 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, + /* 14, RTW_RD_5G_MKK3 */ {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, + /* 15, RTW_RD_5G_NCC1 */ {{56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 16}, + /* 16, RTW_RD_5G_NCC2 */ {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, + /* 17, RTW_RD_5G_NCC3 */ {{149, 153, 157, 161, 165}, 5}, + /* 18, RTW_RD_5G_ETSI4 */ {{36, 40, 44, 48}, 4}, + /* 19, RTW_RD_5G_ETSI5 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, + /* 20, RTW_RD_5G_FCC8 */ {{149, 153, 157, 161}, 4}, + /* 21, RTW_RD_5G_ETSI6 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, + /* 22, RTW_RD_5G_ETSI7 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, + /* 23, RTW_RD_5G_ETSI8 */ {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, + /* 24, RTW_RD_5G_ETSI9 */ {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, + /* 25, RTW_RD_5G_ETSI10 */ {{149, 153, 157, 161, 165}, 5}, + /* 26, RTW_RD_5G_ETSI11 */ {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16}, + /* 27, RTW_RD_5G_NCC4 */ {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17}, + /* 28, RTW_RD_5G_ETSI12 */ {{149, 153, 157, 161}, 4}, + /* 29, RTW_RD_5G_FCC9 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, + /* 30, RTW_RD_5G_ETSI13 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140}, 16}, + /* 31, RTW_RD_5G_FCC10 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20}, + /* 32, RTW_RD_5G_MKK4 */ {{36, 40, 44, 48}, 4}, + /* 33, RTW_RD_5G_ETSI14 */ {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140}, 11}, + + /* === Below are driver defined for legacy channel plan compatible, NO static index assigned ==== */ + /* RTW_RD_5G_OLD_FCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, + /* RTW_RD_5G_OLD_NCC1 */ {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, + /* RTW_RD_5G_OLD_KCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, +}; + +static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[] = { + /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */ + {RTW_RD_2G_FCC1, RTW_RD_5G_KCC1, TXPWR_LMT_FCC}, /* 0x00, RTW_CHPLAN_FCC */ + {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_FCC1, TXPWR_LMT_FCC}, /* 0x01, RTW_CHPLAN_IC */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI}, /* 0x02, RTW_CHPLAN_ETSI */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x03, RTW_CHPLAN_SPAIN */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x04, RTW_CHPLAN_FRANCE */ + {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x05, RTW_CHPLAN_MKK */ + {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x06, RTW_CHPLAN_MKK1 */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI}, /* 0x07, RTW_CHPLAN_ISRAEL */ + {RTW_RD_2G_MKK1, RTW_RD_5G_FCC6, TXPWR_LMT_MKK}, /* 0x08, RTW_CHPLAN_TELEC */ + {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ + {RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_NCC1, TXPWR_LMT_FCC}, /* 0x0B, RTW_CHPLAN_TAIWAN */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI}, /* 0x0C, RTW_CHPLAN_CHINA */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC3, TXPWR_LMT_WW}, /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ /* ETSI:Singapore, India. FCC:Mexico => WW */ + {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_KCC1, TXPWR_LMT_ETSI}, /* 0x0E, RTW_CHPLAN_KOREA */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI}, /* 0x0F, RTW_CHPLAN_TURKEY */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_MKK}, /* 0x10, RTW_CHPLAN_JAPAN */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x11, RTW_CHPLAN_FCC_NO_DFS */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK}, /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_WW}, /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC}, /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_ETSI}, /* 0x15, RTW_CHPLAN_ETSI_NO_DFS */ + {RTW_RD_2G_WORLD, RTW_RD_5G_NCC1, TXPWR_LMT_ETSI}, /* 0x16, RTW_CHPLAN_KOREA_NO_DFS */ + {RTW_RD_2G_MKK1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK}, /* 0x17, RTW_CHPLAN_JAPAN_NO_DFS */ + {RTW_RD_2G_NULL, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI}, /* 0x18, RTW_CHPLAN_PAKISTAN_NO_DFS */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC}, /* 0x19, RTW_CHPLAN_TAIWAN2_NO_DFS */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1A, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1B, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1C, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1D, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1E, */ + {RTW_RD_2G_NULL, RTW_RD_5G_FCC1, TXPWR_LMT_WW}, /* 0x1F, RTW_CHPLAN_WORLD_WIDE_ONLY_5G */ + + /* ===== 0x20 ~ 0x7F, new channel plan ===== */ + {RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x20, RTW_CHPLAN_WORLD_NULL */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x21, RTW_CHPLAN_ETSI1_NULL */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NULL, TXPWR_LMT_FCC}, /* 0x22, RTW_CHPLAN_FCC1_NULL */ + {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x23, RTW_CHPLAN_MKK1_NULL */ + {RTW_RD_2G_ETSI2, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x24, RTW_CHPLAN_ETSI2_NULL */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC1, TXPWR_LMT_FCC}, /* 0x25, RTW_CHPLAN_FCC1_FCC1 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI}, /* 0x26, RTW_CHPLAN_WORLD_ETSI1 */ + {RTW_RD_2G_MKK1, RTW_RD_5G_MKK1, TXPWR_LMT_MKK}, /* 0x27, RTW_CHPLAN_MKK1_MKK1 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_KCC1, TXPWR_LMT_ETSI}, /* 0x28, RTW_CHPLAN_WORLD_KCC1 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x29, RTW_CHPLAN_WORLD_FCC2 */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2A, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2B, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2C, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2D, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2E, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2F, */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC3, TXPWR_LMT_FCC}, /* 0x30, RTW_CHPLAN_WORLD_FCC3 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC4, TXPWR_LMT_FCC}, /* 0x31, RTW_CHPLAN_WORLD_FCC4 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC5, TXPWR_LMT_FCC}, /* 0x32, RTW_CHPLAN_WORLD_FCC5 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_FCC6, TXPWR_LMT_FCC}, /* 0x33, RTW_CHPLAN_WORLD_FCC6 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC7, TXPWR_LMT_FCC}, /* 0x34, RTW_CHPLAN_FCC1_FCC7 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI}, /* 0x35, RTW_CHPLAN_WORLD_ETSI2 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI3, TXPWR_LMT_ETSI}, /* 0x36, RTW_CHPLAN_WORLD_ETSI3 */ + {RTW_RD_2G_MKK1, RTW_RD_5G_MKK2, TXPWR_LMT_MKK}, /* 0x37, RTW_CHPLAN_MKK1_MKK2 */ + {RTW_RD_2G_MKK1, RTW_RD_5G_MKK3, TXPWR_LMT_MKK}, /* 0x38, RTW_CHPLAN_MKK1_MKK3 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NCC1, TXPWR_LMT_FCC}, /* 0x39, RTW_CHPLAN_FCC1_NCC1 */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3A, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3B, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3C, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3D, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3E, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3F, */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC}, /* 0x40, RTW_CHPLAN_FCC1_NCC2 */ + {RTW_RD_2G_GLOBAL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x41, RTW_CHPLAN_GLOBAL_NULL */ + {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI4, TXPWR_LMT_ETSI}, /* 0x42, RTW_CHPLAN_ETSI1_ETSI4 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x43, RTW_CHPLAN_FCC1_FCC2 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NCC3, TXPWR_LMT_FCC}, /* 0x44, RTW_CHPLAN_FCC1_NCC3 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI5, TXPWR_LMT_ETSI}, /* 0x45, RTW_CHPLAN_WORLD_ETSI5 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC8, TXPWR_LMT_FCC}, /* 0x46, RTW_CHPLAN_FCC1_FCC8 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI}, /* 0x47, RTW_CHPLAN_WORLD_ETSI6 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI7, TXPWR_LMT_ETSI}, /* 0x48, RTW_CHPLAN_WORLD_ETSI7 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI}, /* 0x49, RTW_CHPLAN_WORLD_ETSI8 */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4A, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4B, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4C, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4D, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4E, */ + {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4F, */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI9, TXPWR_LMT_ETSI}, /* 0x50, RTW_CHPLAN_WORLD_ETSI9 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI10, TXPWR_LMT_ETSI}, /* 0x51, RTW_CHPLAN_WORLD_ETSI10 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI11, TXPWR_LMT_ETSI}, /* 0x52, RTW_CHPLAN_WORLD_ETSI11 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_NCC4, TXPWR_LMT_FCC}, /* 0x53, RTW_CHPLAN_FCC1_NCC4 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI}, /* 0x54, RTW_CHPLAN_WORLD_ETSI12 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC9, TXPWR_LMT_FCC}, /* 0x55, RTW_CHPLAN_FCC1_FCC9 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI13, TXPWR_LMT_ETSI}, /* 0x56, RTW_CHPLAN_WORLD_ETSI13 */ + {RTW_RD_2G_FCC1, RTW_RD_5G_FCC10, TXPWR_LMT_FCC}, /* 0x57, RTW_CHPLAN_FCC1_FCC10 */ + {RTW_RD_2G_MKK2, RTW_RD_5G_MKK4, TXPWR_LMT_MKK}, /* 0x58, RTW_CHPLAN_MKK2_MKK4 */ + {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI14, TXPWR_LMT_ETSI}, /* 0x59, RTW_CHPLAN_WORLD_ETSI14 */ +}; + +static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = { + RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_FCC /* 0x7F, Realtek Define */ +}; + +bool rtw_chplan_is_empty(u8 id) +{ + RT_CHANNEL_PLAN_MAP *chplan_map; + + if (id == RTW_CHPLAN_REALTEK_DEFINE) + chplan_map = &RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE; + else + chplan_map = &RTW_ChannelPlanMap[id]; + + if (chplan_map->Index2G == RTW_RD_2G_NULL + && chplan_map->Index5G == RTW_RD_5G_NULL) + return _TRUE; + + return _FALSE; +} + +#ifdef CONFIG_DFS_MASTER +void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl) +{ + if (rtw_is_long_cac_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset)) + rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_CE_MS); + else + rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_MS); +} + +/* +* check if channel coverage includes new range and the new range is in DFS range +* called after radar_detect_ch,bw,offset is updated +*/ +bool rtw_is_cac_reset_needed(_adapter *adapter) +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + bool needed = _FALSE; + u32 pre_hi, pre_lo, hi, lo; + + if (0) + DBG_871X("pre_radar_detect_ch:%d, pre_radar_detect_by_sta_link:%d\n" + , rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_by_sta_link); + + if (rfctl->pre_radar_detect_by_sta_link == _TRUE) + goto exit; + + if (rfctl->pre_radar_detect_ch == 0) { + needed = _TRUE; + goto exit; + } + + if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &hi, &lo) == _FALSE) + rtw_warn_on(1); + if (rtw_chbw_to_freq_range(rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_bw, rfctl->pre_radar_detect_offset, &pre_hi, &pre_lo) == _FALSE) + rtw_warn_on(1); + + if (!rtw_is_range_a_in_b(hi, lo, pre_hi, pre_lo)) { + if (rtw_is_range_a_in_b(pre_hi, pre_lo, hi, lo)) { + /* currrent is supper set of previous */ + if (rtw_is_dfs_range(hi, lo)) + needed = _TRUE; + } else if (rtw_is_range_overlap(hi, lo, pre_hi, pre_lo)) { + /* currrent is not supper set of previous, but has overlap */ + u32 new_hi, new_lo; + + if (lo < pre_lo) { + new_hi = pre_lo; + new_lo = lo; + if (hi <= pre_lo || hi >= pre_hi) { + DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n" + , hi, lo, pre_hi, pre_lo); + rtw_warn_on(1); + goto exit; + } + } else if (hi > pre_hi) { + new_hi = hi; + new_lo = pre_hi; + if (lo >= pre_hi && lo <= pre_lo) { + DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n" + , hi, lo, pre_hi, pre_lo); + rtw_warn_on(1); + goto exit; + } + } else { + DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n" + , hi, lo, pre_hi, pre_lo); + rtw_warn_on(1); + goto exit; + } + + if (rtw_is_dfs_range(new_hi, new_lo)) + needed = _TRUE; + + } else { + /* no overlap */ + if (rtw_is_dfs_range(hi, lo)) + needed = _TRUE; + } + } + +exit: + return needed; +} + +bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset) +{ + bool ret = _FALSE; + u32 hi = 0, lo = 0; + u32 r_hi = 0, r_lo = 0; + int i; + + if (rfctl->radar_detect_ch == 0) + goto exit; + + if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) { + rtw_warn_on(1); + goto exit; + } + + if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch + , rfctl->radar_detect_bw, rfctl->radar_detect_offset + , &r_hi, &r_lo) == _FALSE) { + rtw_warn_on(1); + goto exit; + } + + if (rtw_is_range_overlap(hi, lo, r_hi, r_lo)) + ret = _TRUE; + +exit: + return ret; +} + +bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl) +{ + return _rtw_rfctl_overlap_radar_detect_ch(rfctl + , rfctl_to_dvobj(rfctl)->oper_channel + , rfctl_to_dvobj(rfctl)->oper_bwmode + , rfctl_to_dvobj(rfctl)->oper_ch_offset); +} + +bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl) +{ + return (rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_UNDER_CAC(rfctl)); +} + +bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) +{ + bool ret = _FALSE; + u32 hi = 0, lo = 0; + int i; + + if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) + goto exit; + + for (i = 0; ch_set[i].ChannelNum != 0; i++) { + if (!rtw_ch2freq(ch_set[i].ChannelNum)) { + rtw_warn_on(1); + continue; + } + + if (!CH_IS_NON_OCP(&ch_set[i])) + continue; + + if (lo <= rtw_ch2freq(ch_set[i].ChannelNum) + && rtw_ch2freq(ch_set[i].ChannelNum) <= hi + ) { + ret = _TRUE; + break; + } + } + +exit: + return ret; +} + +/** + * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set + * @ch_set: the given channel set + * @ch: channel number on which radar is detected + * @bw: bandwidth on which radar is detected + * @offset: bandwidth offset on which radar is detected + * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS + */ +static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +{ + u32 hi = 0, lo = 0; + int i; + + if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) + goto exit; + + for (i = 0; ch_set[i].ChannelNum != 0; i++) { + if (!rtw_ch2freq(ch_set[i].ChannelNum)) { + rtw_warn_on(1); + continue; + } + + if (lo <= rtw_ch2freq(ch_set[i].ChannelNum) + && rtw_ch2freq(ch_set[i].ChannelNum) <= hi + ) { + if (ms >= 0) + ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms); + else + ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS); + } + } + +exit: + return; +} + +inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset) +{ + _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1); +} + +inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms) +{ + _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms); +} +#endif /* CONFIG_DFS_MASTER */ + +bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags) +{ + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + int i; + + if (!dec_ch || !dec_bw || !dec_offset) { + rtw_warn_on(1); + return _FAIL; + } + + for (i = 0; i < mlmeext->max_chan_nums; i++) { + + *dec_ch = mlmeext->channel_set[i].ChannelNum; + *dec_bw = req_bw; + if (*dec_bw == CHANNEL_WIDTH_20) + *dec_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + else + *dec_offset = rtw_get_offset_by_ch(*dec_ch); + + if ((d_flags & RTW_CHF_2G) && *dec_ch <= 14) + continue; + + if ((d_flags & RTW_CHF_5G) && *dec_ch > 14) + continue; + + rtw_adjust_chbw(adapter, *dec_ch, dec_bw, dec_offset); + + if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset)) + continue; + + if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset)) + continue; + + if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset)) + continue; + + if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset)) + continue; + + if (!rtw_chset_is_ch_non_ocp(mlmeext->channel_set, *dec_ch, *dec_bw, *dec_offset)) + break; + } + + return (i < mlmeext->max_chan_nums)?_TRUE:_FALSE; +} + +void dump_country_chplan(void *sel, const struct country_chplan *ent) +{ + DBG_871X_SEL(sel, "\"%c%c\", 0x%02X%s\n" + , ent->alpha2[0], ent->alpha2[1], ent->chplan + , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : "" + ); +} + +void dump_country_chplan_map(void *sel) +{ + const struct country_chplan *ent; + u8 code[2]; + +#if RTW_DEF_MODULE_REGULATORY_CERT + DBG_871X_SEL(sel, "RTW_DEF_MODULE_REGULATORY_CERT:0x%x\n", RTW_DEF_MODULE_REGULATORY_CERT); +#endif +#ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP + DBG_871X_SEL(sel, "CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP\n"); +#endif + + for (code[0] = 'A'; code[0] <= 'Z'; code[0]++) { + for (code[1] = 'A'; code[1] <= 'Z'; code[1]++) { + ent = rtw_get_chplan_from_country(code); + if (!ent) + continue; + + dump_country_chplan(sel, ent); + } + } +} + +void dump_chplan_id_list(void *sel) +{ + int i; + + for (i = 0; i < RTW_CHPLAN_MAX; i++) { + if (!rtw_is_channel_plan_valid(i)) + continue; + + DBG_871X_SEL(sel, "0x%02X ", i); + } + + DBG_871X_SEL_NL(sel, "0x7F\n"); +} + +void dump_chplan_test(void *sel) +{ + int i, j; + + /* check invalid channel */ + for (i = 0; i < RTW_RD_2G_MAX; i++) { + for (j = 0; j < RTW_ChannelPlan2G[i].Len; j++) { + if (rtw_ch2freq(RTW_ChannelPlan2G[i].Channel[j]) == 0) + DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan2G[i].Channel[j], i, j); + } + } + + for (i = 0; i < RTW_RD_5G_MAX; i++) { + for (j = 0; j < RTW_ChannelPlan5G[i].Len; j++) { + if (rtw_ch2freq(RTW_ChannelPlan5G[i].Channel[j]) == 0) + DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan5G[i].Channel[j], i, j); + } + } +} + +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set) +{ + u8 i; + + for (i = 0; ch_set[i].ChannelNum != 0; i++) { + DBG_871X_SEL_NL(sel, "ch:%3u, freq:%u, scan_type:%d" + , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType); + + #ifdef CONFIG_FIND_BEST_CHANNEL + DBG_871X_SEL(sel, ", rx_count:%u", ch_set[i].rx_count); + #endif + + #ifdef CONFIG_DFS_MASTER + if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) { + if (CH_IS_NON_OCP(&ch_set[i])) + DBG_871X_SEL(sel, ", non_ocp:%d" + , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time())); + else + DBG_871X_SEL(sel, ", non_ocp:N/A"); + } + #endif + + DBG_871X_SEL(sel, "\n"); + } + + DBG_871X_SEL_NL(sel, "total ch number:%d\n", i); +} + +void dump_cur_chset(void *sel, _adapter *adapter) +{ + struct mlme_priv *mlme = &adapter->mlmepriv; + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (mlme->country_ent) + dump_country_chplan(sel, mlme->country_ent); + else + DBG_871X_SEL_NL(sel, "chplan:0x%02X\n", mlme->ChannelPlan); + + DBG_871X_SEL_NL(sel, "2G_PLS:%u, 5G_PLS:%u\n" + , hal_data->Regulation2_4G, hal_data->Regulation5G); + dump_chset(sel, mlmeext->channel_set); +} + +/* + * Search the @param ch in given @param ch_set + * @ch_set: the given channel set + * @ch: the given channel number + * + * return the index of channel_num in channel_set, -1 if not found + */ +int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch) +{ + int i; + for(i=0;ch_set[i].ChannelNum!=0;i++){ + if(ch == ch_set[i].ChannelNum) + break; + } + + if(i >= ch_set[i].ChannelNum) + return -1; + return i; +} + +/* + * Check the @param ch is fit with setband setting of @param adapter + * @adapter: the given adapter + * @ch: the given channel number + * + * return _TRUE when check valid, _FALSE not valid + */ +bool rtw_mlme_band_check(_adapter *adapter, const u32 ch) +{ + if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */ + || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */ + || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */ + ) { + return _TRUE; + } + return _FALSE; +} + +/**************************************************************************** + +Following are the initialization functions for WiFi MLME + +*****************************************************************************/ + +int init_hw_mlme_ext(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + //set_opmode_cmd(padapter, infra_client_with_mlme);//removed + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + return _SUCCESS; +} + +void init_mlme_default_rate_set(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + 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, 0xff, 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); + + _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set)); +} + +static void init_mlme_ext_priv_value(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + ATOMIC_SET(&pmlmeext->event_seq, 0); + pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode +#ifdef CONFIG_IEEE80211W + pmlmeext->sa_query_seq = 0; + pmlmeext->mgnt_80211w_IPN=0; + pmlmeext->mgnt_80211w_IPN_rx=0; +#endif //CONFIG_IEEE80211W + pmlmeext->cur_channel = padapter->registrypriv.channel; + pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + pmlmeext->retry = 0; + + pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; + + init_mlme_default_rate_set(padapter); + + if(pmlmeext->cur_channel > 14) + pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB; + else + pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; + + mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE); + pmlmeext->sitesurvey_res.channel_idx = 0; + pmlmeext->sitesurvey_res.bss_cnt = 0; + pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO; + pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID; + pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID; + #ifdef CONFIG_SCAN_BACKOP + mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME); + mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN|SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME); + pmlmeext->sitesurvey_res.scan_cnt = 0; + pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH; + pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS; + #endif + #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) + pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0; + #endif + pmlmeext->scan_abort = _FALSE; + + pmlmeinfo->state = WIFI_FW_NULL_STATE; + pmlmeinfo->reauth_count = 0; + pmlmeinfo->reassoc_count = 0; + pmlmeinfo->link_count = 0; + pmlmeinfo->auth_seq = 0; + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; + pmlmeinfo->key_index = 0; + pmlmeinfo->iv = 0; + + pmlmeinfo->enc_algo = _NO_PRIVACY_; + pmlmeinfo->authModeToggle = 0; + + _rtw_memset(pmlmeinfo->chg_txt, 0, 128); + + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + pmlmeinfo->preamble_mode = PREAMBLE_AUTO; + + pmlmeinfo->dialogToken = 0; + + pmlmeext->action_public_rxseq = 0xffff; + pmlmeext->action_public_dialog_token = 0xff; +} + +static int has_channel(RT_CHANNEL_INFO *channel_set, + u8 chanset_size, + u8 chan) { + int i; + + for (i = 0; i < chanset_size; i++) { + if (channel_set[i].ChannelNum == chan) { + return 1; + } + } + + return 0; +} + +static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set, + u8 chanset_size, + struct p2p_channels *channel_list) { + struct registry_priv *regsty = adapter_to_regsty(padapter); + + struct p2p_oper_class_map op_class[] = { + { IEEE80211G, 81, 1, 13, 1, BW20 }, + { IEEE80211G, 82, 14, 14, 1, BW20 }, +#if 0 /* Do not enable HT40 on 2 GHz */ + { IEEE80211G, 83, 1, 9, 1, BW40PLUS }, + { IEEE80211G, 84, 5, 13, 1, BW40MINUS }, +#endif + { IEEE80211A, 115, 36, 48, 4, BW20 }, + { IEEE80211A, 116, 36, 44, 8, BW40PLUS }, + { IEEE80211A, 117, 40, 48, 8, BW40MINUS }, + { IEEE80211A, 124, 149, 161, 4, BW20 }, + { IEEE80211A, 125, 149, 169, 4, BW20 }, + { IEEE80211A, 126, 149, 157, 8, BW40PLUS }, + { IEEE80211A, 127, 153, 161, 8, BW40MINUS }, + { -1, 0, 0, 0, 0, BW20 } + }; + + int cla, op; + + cla = 0; + + for (op = 0; op_class[op].op_class; op++) { + u8 ch; + struct p2p_oper_class_map *o = &op_class[op]; + struct p2p_reg_class *reg = NULL; + + for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { + if (!has_channel(channel_set, chanset_size, ch)) { + continue; + } + + if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) + continue; + + if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) && + ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) + continue; + + if (reg == NULL) { + reg = &channel_list->reg_class[cla]; + cla++; + reg->reg_class = o->op_class; + reg->channels = 0; + } + reg->channel[reg->channels] = ch; + reg->channels++; + } + } + channel_list->reg_classes = cla; + +} + +static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set) +{ + u8 index,chanset_size = 0; + u8 b5GBand = _FALSE, b2_4GBand = _FALSE; + u8 Index2G = 0, Index5G=0; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + + if (!rtw_is_channel_plan_valid(ChannelPlan)) { + DBG_871X_LEVEL(_drv_err_, "ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan); + return chanset_size; + } + + _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM); + + if (IsSupported24G(padapter->registrypriv.wireless_mode)) + b2_4GBand = _TRUE; + + if (IsSupported5G(padapter->registrypriv.wireless_mode)) + b5GBand = _TRUE; + + if (b2_4GBand) { + if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) + Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; + else + Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; + + for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) { + channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index]; + + if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan + || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan + ) { + /* Channel 1~11 is active, and 12~14 is passive */ + if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan + || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan + || RTW_RD_2G_WORLD == Index2G + ) { + /* channel 12~13, passive scan */ + if(channel_set[chanset_size].ChannelNum <= 11) + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + else + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } else { + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + } + + chanset_size++; + } + } + + if (b5GBand) { + if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) + Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G; + else + Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G; + + for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) { +#ifdef CONFIG_DFS + channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index]; + if ( channel_set[chanset_size].ChannelNum <= 48 + || channel_set[chanset_size].ChannelNum >= 149 ) + { + if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */ + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + else + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + } + else + { + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + } + chanset_size++; +#else /* CONFIG_DFS */ + if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48 + || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 + ) { + channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index]; + if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */ + channel_set[chanset_size].ScanType = SCAN_PASSIVE; + else + channel_set[chanset_size].ScanType = SCAN_ACTIVE; + DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum); + chanset_size++; + } +#endif /* CONFIG_DFS */ + } + } + + if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) { + hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd; + hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd; + } else { + hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd; + hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd; + } + + DBG_871X(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n" + , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size); + + return chanset_size; +} + +int init_mlme_ext_priv(_adapter* padapter) +{ + int res = _SUCCESS; + struct registry_priv* pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); + + pmlmeext->padapter = padapter; + + //fill_fwpriv(padapter, &(pmlmeext->fwpriv)); + + init_mlme_ext_priv_value(padapter); + pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq; + + init_mlme_ext_timer(padapter); + +#ifdef CONFIG_AP_MODE + init_mlme_ap_info(padapter); +#endif + + pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set); + init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); + pmlmeext->last_scan_time = 0; + pmlmeext->mlmeext_init = _TRUE; + + +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + pmlmeext->active_keep_alive_check = _TRUE; +#else + pmlmeext->active_keep_alive_check = _FALSE; +#endif + +#ifdef DBG_FIXED_CHAN + pmlmeext->fixed_chan = 0xFF; +#endif + + return res; + +} + +void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext) +{ + _adapter *padapter = pmlmeext->padapter; + + if (!padapter) + return; + + if (rtw_is_drv_stopped(padapter)) { + _cancel_timer_ex(&pmlmeext->survey_timer); + _cancel_timer_ex(&pmlmeext->link_timer); + //_cancel_timer_ex(&pmlmeext->ADDBA_timer); + } +} + +static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len) +{ // if the channel is same, return 0. else return channel differential + uint len; + u8 channel; + u8 *p; + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_); + if (p) + { + channel = *(p + 2); + if(padapter->mlmeextpriv.cur_channel >= channel) + { + return (padapter->mlmeextpriv.cur_channel - channel); + } + else + { + return (channel-padapter->mlmeextpriv.cur_channel); + } + } + else + { + return 0; + } +} + +static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame) +{ + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 *pframe = precv_frame->u.hdr.rx_data; + + if(ptable->func) + { + //receive the frames that ra(a1) is my address or ra(a1) is bc address. + if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) && + !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) + { + return; + } + + ptable->func(padapter, precv_frame); + } + +} + +void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) +{ + int index; + struct mlme_handler *ptable; +#ifdef CONFIG_AP_MODE + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //CONFIG_AP_MODE + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u8 *pframe = precv_frame->u.hdr.rx_data; + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, + ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n", + GetFrameType(pframe), GetFrameSubType(pframe))); + +#if 0 + { + u8 *pbuf; + pbuf = GetAddr1Ptr(pframe); + DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + pbuf = GetAddr2Ptr(pframe); + DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + pbuf = GetAddr3Ptr(pframe); + DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5)); + } +#endif + + if (GetFrameType(pframe) != WIFI_MGT_TYPE) + { + RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe))); + return; + } + + //receive the frames that ra(a1) is my address or ra(a1) is bc address. + if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) && + !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) + { + return; + } + + ptable = mlme_sta_tbl; + + index = GetFrameSubType(pframe) >> 4; + +#ifdef CONFIG_TDLS + if((index << 4)==WIFI_ACTION){ + /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */ + if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) { + DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe))); + On_TDLS_Dis_Rsp(padapter, precv_frame); + } + } +#endif //CONFIG_TDLS + + if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler))) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index)); + return; + } + ptable += index; + +#if 1 + if (psta != NULL) + { + if (GetRetry(pframe)) + { + if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) + { + /* drop the duplicate management frame */ + pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++; + DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num); + return; + } + } + psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num; + } +#else + + if(GetRetry(pframe)) + { + //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n")); + //return; + } +#endif + +#ifdef CONFIG_AP_MODE + switch (GetFrameSubType(pframe)) + { + case WIFI_AUTH: + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + ptable->func = &OnAuth; + else + ptable->func = &OnAuthClient; + //pass through + case WIFI_ASSOCREQ: + case WIFI_REASSOCREQ: + _mgt_dispatcher(padapter, ptable, precv_frame); +#ifdef CONFIG_HOSTAPD_MLME + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_hostapd_mlme_rx(padapter, precv_frame); +#endif + break; + case WIFI_PROBEREQ: + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_HOSTAPD_MLME + rtw_hostapd_mlme_rx(padapter, precv_frame); +#else + _mgt_dispatcher(padapter, ptable, precv_frame); +#endif + } + else + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + case WIFI_BEACON: + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + case WIFI_ACTION: + //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + _mgt_dispatcher(padapter, ptable, precv_frame); + break; + default: + _mgt_dispatcher(padapter, ptable, precv_frame); + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_hostapd_mlme_rx(padapter, precv_frame); + break; + } +#else + + _mgt_dispatcher(padapter, ptable, precv_frame); + +#endif + +} + +#ifdef CONFIG_P2P +u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da) +{ + bool response = _TRUE; + +#ifdef CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE + || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel + || adapter_wdev_data(padapter)->p2p_enabled == _FALSE + || padapter->mlmepriv.wps_probe_resp_ie == NULL + || padapter->mlmepriv.p2p_probe_resp_ie == NULL + ) + { +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ", + adapter_wdev_data(padapter)->p2p_enabled, + padapter->mlmepriv.wps_probe_resp_ie, + padapter->mlmepriv.p2p_probe_resp_ie); + DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n", + padapter->cfg80211_wdinfo.is_ro_ch, + rtw_get_oper_ch(padapter), + padapter->wdinfo.listen_channel); +#endif + response = _FALSE; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_WEXT ) + { + // do nothing if the device name is empty + if ( !padapter->wdinfo.device_name_len ) + { + response = _FALSE; + } + } + + if (response == _TRUE) + issue_probersp_p2p( padapter, da); + + return _SUCCESS; +} +#endif //CONFIG_P2P + + +/**************************************************************************** + +Following are the callback functions for each subtype of the management frames + +*****************************************************************************/ + +unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ielen; + unsigned char *p; + 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 = &(pmlmeinfo->network); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 is_valid_p2p_probereq = _FALSE; + +#ifdef CONFIG_ATMEL_RC_PATCH + u8 *target_ie=NULL, *wps_ie=NULL; + u8 *start; + uint search_len = 0, wps_ielen = 0, target_ielen = 0; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; +#endif + + +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + u8 wifi_test_chk_rate = 1; + +#ifdef CONFIG_IOCTL_CFG80211 + if ((pwdinfo->driver_interface == DRIVER_CFG80211) + && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) + && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE) + ) { + rtw_cfg80211_rx_probe_request(padapter, pframe, len); + return _SUCCESS; + } +#endif /* CONFIG_IOCTL_CFG80211 */ + + if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && + !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) && + !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) + ) + { + // Commented by Albert 2011/03/17 + // mcs_rate = 0 -> CCK 1M rate + // mcs_rate = 1 -> CCK 2M rate + // mcs_rate = 2 -> CCK 5.5M rate + // mcs_rate = 3 -> CCK 11M rate + // In the P2P mode, the driver should not support the CCK rate + + // 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 + if (padapter->registrypriv.wifi_spec == 1) + { + if ( pattrib->data_rate <= 3 ) + { + wifi_test_chk_rate = 0; + } + } + + if( wifi_test_chk_rate == 1 ) + { + if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE) + { + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) + { + // FIXME + if( padapter->wdinfo.driver_interface == DRIVER_WEXT ) + report_survey_event(padapter, precv_frame); + + p2p_listen_state_process( padapter, get_sa(pframe)); + + return _SUCCESS; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + goto _continue; + } + } + } + } + +_continue: +#endif //CONFIG_P2P + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + return _SUCCESS; + } + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE && + check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE) + { + return _SUCCESS; + } + + + //DBG_871X("+OnProbeReq\n"); + + +#ifdef CONFIG_ATMEL_RC_PATCH + if ((wps_ie = rtw_get_wps_ie( + pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, + NULL, &wps_ielen))) { + + target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen); + } + if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) { + //psta->flag_atmel_rc = 1; + unsigned char *sa_addr = get_sa(pframe); + printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n", + __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5)); + _rtw_memcpy( pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN); + } +#endif + + +#ifdef CONFIG_AUTO_AP_MODE + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + pmlmepriv->cur_network.join_res == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + u8 *mac_addr, *peer_addr; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A}; + //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + if(!p || ielen !=14) + goto _non_rc_device; + + if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI))) + goto _non_rc_device; + + if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN)) + { + DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__, + MAC_ARG(get_sa(pframe)), MAC_ARG(p+6)); + + goto _non_rc_device; + } + + DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe))); + + //new a station + psta = rtw_get_stainfo(pstapriv, get_sa(pframe)); + if (psta == NULL) + { + // allocate a new one + DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe))); + psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe)); + if (psta == NULL) + { + //TODO: + DBG_871X(" Exceed the upper limit of supported clients...\n"); + return _SUCCESS; + } + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&psta->asoc_list)) + { + psta->expire_to = pstapriv->expire_to; + rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list); + pstapriv->asoc_list_cnt++; + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + //generate pairing ID + mac_addr = adapter_mac_addr(padapter); + peer_addr = psta->hwaddr; + psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5])); + + //update peer stainfo + psta->isrc = _TRUE; + //psta->aid = 0; + //psta->mac_id = 2; + + /* get a unique AID */ + if (psta->aid > 0) { + DBG_871X("old AID %d\n", psta->aid); + } else { + for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++) + if (pstapriv->sta_aid[psta->aid - 1] == NULL) + break; + + if (psta->aid > pstapriv->max_num_sta) { + psta->aid = 0; + DBG_871X("no room for more AIDs\n"); + return _SUCCESS; + } else { + pstapriv->sta_aid[psta->aid - 1] = psta; + DBG_871X("allocate new AID = (%d)\n", psta->aid); + } + } + + psta->qos_option = 1; + psta->bw_mode = CHANNEL_WIDTH_20; + psta->ieee8021x_blocked = _FALSE; +#ifdef CONFIG_80211N_HT + psta->htpriv.ht_option = _TRUE; + psta->htpriv.ampdu_enable = _FALSE; + psta->htpriv.sgi_20m = _FALSE; + psta->htpriv.sgi_40m = _FALSE; + psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset +#endif + + rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE); + + _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); + + _enter_critical_bh(&psta->lock, &irqL); + psta->state |= _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + + report_add_sta_event(padapter, psta->hwaddr); + + } + + issue_probersp(padapter, get_sa(pframe), _FALSE); + + return _SUCCESS; + + } + +_non_rc_device: + + return _SUCCESS; + +#endif //CONFIG_AUTO_AP_MODE + + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process probe req + return _SUCCESS; + } +#endif + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + + //check (wildcard) SSID + if (p != NULL) + { + if(is_valid_p2p_probereq == _TRUE) + { + goto _issue_probersp; + } + + if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) + || (ielen == 0 && pmlmeinfo->hidden_ssid_mode) + ) + { + return _SUCCESS; + } + +_issue_probersp: + if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && + pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) + { + //DBG_871X("+issue_probersp during ap mode\n"); + issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); + } + + } + + return _SUCCESS; + +} + +unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct sta_info *psta; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) + { + if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) + { + pwdinfo->tx_prov_disc_info.benable = _FALSE; + issue_p2p_provision_request( padapter, + pwdinfo->tx_prov_disc_info.ssid.Ssid, + pwdinfo->tx_prov_disc_info.ssid.SsidLength, + pwdinfo->tx_prov_disc_info.peerDevAddr ); + } + else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) ) + { + pwdinfo->tx_prov_disc_info.benable = _FALSE; + issue_p2p_provision_request( padapter, + NULL, + 0, + pwdinfo->tx_prov_disc_info.peerDevAddr ); + } + } + } + return _SUCCESS; + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + if ( _TRUE == pwdinfo->nego_req_info.benable ) + { + DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ ); + if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + pwdinfo->nego_req_info.benable = _FALSE; + issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr); + } + } + } + else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) ) + { + if ( _TRUE == pwdinfo->invitereq_info.benable ) + { + DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ ); + if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) ) + { + pwdinfo->invitereq_info.benable = _FALSE; + issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr ); + } + } + } +#endif + + + if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) { + report_survey_event(padapter, precv_frame); +#ifdef CONFIG_CONCURRENT_MODE + report_survey_event(padapter->pbuddy_adapter, precv_frame); +#endif + return _SUCCESS; + } + + #if 0 //move to validate_recv_mgnt_frame + if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) + { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL) + { + psta->sta_stats.rx_mgnt_pkts++; + } + } + } + #endif + + return _SUCCESS; + +} + +unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame) +{ + struct sta_info *psta; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + WLAN_BSSID_EX *pbss; + int ret = _SUCCESS; + u8 *p = NULL; + u32 ielen = 0; +#ifdef CONFIG_TDLS + struct sta_info *ptdls_sta; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#endif /* CONFIG_TDLS */ + +#ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR + p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_); + if ((p != NULL) && (ielen > 0)) + { + if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) + { + /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ + DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe))); + *(p + 1) = ielen - 1; + } + } +#endif + + if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) { + report_survey_event(padapter, precv_frame); +#ifdef CONFIG_CONCURRENT_MODE + report_survey_event(padapter->pbuddy_adapter, precv_frame); +#endif + return _SUCCESS; + } + + if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) + { + if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) + { + //we should update current network before auth, or some IE is wrong + 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)); + } + + //check the vendor of the assoc AP + pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr)); + + //update TSF Value + update_TSF(pmlmeext, pframe, len); + + //reset for adaptive_early_32k + pmlmeext->adaptive_tsf_done = _FALSE; + pmlmeext->DrvBcnEarly = 0xff; + pmlmeext->DrvBcnTimeOut = 0xff; + pmlmeext->bcn_cnt = 0; + _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt)); + _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio)); + +#ifdef CONFIG_P2P_PS + process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); +#endif //CONFIG_P2P_PS + +#if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE) + if (padapter->registrypriv.wifi_spec) { + if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) { + if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) { + DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n "); + return _SUCCESS; + } + } + } +#endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE + + //start auth + start_clnt_auth(padapter); + + return _SUCCESS; + } + + if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + { + if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL) + { + #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL + //Merge from 8712 FW code + if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0) + { // join wrong channel, deauth and reconnect + issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING); + + report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE); + pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS); + return _SUCCESS; + } + #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL + + ret = rtw_check_bcn_info(padapter, pframe, len); + if (!ret) { + DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n "); + receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0); + return _SUCCESS; + } + //update WMM, ERP in the beacon + //todo: the timer is used instead of the number of the beacon received + if ((sta_rx_pkts(psta) & 0xf) == 0) + { + //DBG_871X("update_bcn_info\n"); + update_beacon_info(padapter, pframe, len, psta); + } + + adaptive_early_32k(pmlmeext, pframe, len); + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (padapter->tdlsinfo.ch_switch_prohibited == _FALSE) + { + /* Send TDLS Channel Switch Request when receiving Beacon */ + if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) { + ptdlsinfo->chsw_info.ch_sw_state |= TDLS_WAIT_CH_RSP_STATE; + /* DBG_871X("[%s] issue_tdls_ch_switch_req to "MAC_FMT"\n", __FUNCTION__, MAC_ARG(padapter->tdlsinfo.chsw_info.addr)); */ + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr); + if (ptdls_sta != NULL) { + if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE) + issue_tdls_ch_switch_req(padapter, ptdls_sta); + } + } + } +#endif +#endif /* CONFIG_TDLS */ + +#ifdef CONFIG_DFS + process_csa_ie(padapter, pframe, len); //channel switch announcement +#endif //CONFIG_DFS + +#ifdef CONFIG_P2P_PS + process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); +#endif //CONFIG_P2P_PS + + if (pmlmeext->en_hw_update_tsf) + rtw_enable_hw_update_tsf_cmd(padapter); + + #if 0 //move to validate_recv_mgnt_frame + psta->sta_stats.rx_mgnt_pkts++; + #endif + } + + } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { + _irqL irqL; + u8 rate_set[16]; + u8 rate_num = 0; + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (psta != NULL) { + /* + * update WMM, ERP in the beacon + * todo: the timer is used instead of the number of the beacon received + */ + if ((sta_rx_pkts(psta) & 0xf) == 0) + update_beacon_info(padapter, pframe, len, psta); + + if (pmlmeext->en_hw_update_tsf) + rtw_enable_hw_update_tsf_cmd(padapter); + + } else { + rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num); + if (rate_num == 0) { + DBG_871X(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter)); + goto _END_ONBEACON_; + } + + psta = rtw_alloc_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (psta == NULL) { + DBG_871X(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter)); + goto _END_ONBEACON_; + } + + psta->expire_to = pstapriv->adhoc_expire_to; + + _rtw_memcpy(psta->bssrateset, rate_set, rate_num); + psta->bssratelen = rate_num; + + //update TSF Value + update_TSF(pmlmeext, pframe, len); + + //report sta add event + report_add_sta_event(padapter, GetAddr2Ptr(pframe)); + } + } + } + +_END_ONBEACON_: + + return _SUCCESS; + +} + +unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + _irqL irqL; + unsigned int auth_mode, seq, ie_len; + unsigned char *sa, *p; + u16 algorithm; + int status; + static struct sta_info stat; + struct sta_info *pstat=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 offset = 0; + + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process auth request; + return _SUCCESS; + } +#endif //CONFIG_CONCURRENT_MODE + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return _FAIL; + + DBG_871X("+OnAuth\n"); + + sa = GetAddr2Ptr(pframe); + + auth_mode = psecuritypriv->dot11AuthAlgrthm; + + if (GetPrivacy(pframe)) + { + u8 *iv; + struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib); + + prxattrib->hdrlen = WLAN_HDR_A3_LEN; + prxattrib->encrypt = _WEP40_; + + iv = pframe+prxattrib->hdrlen; + prxattrib->key_index = ((iv[3]>>6)&0x3); + + prxattrib->iv_len = 4; + prxattrib->icv_len = 4; + + rtw_wep_decrypt(padapter, (u8 *)precv_frame); + + offset = 4; + } + + algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset)); + seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); + + DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq); + + if (auth_mode == 2 && + psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && + psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) + auth_mode = 0; + + if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled + (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled + { + DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n", + algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); + + status = _STATS_NO_SUPP_ALG_; + + goto auth_fail; + } + +#if 0 //ACL control + phead = &priv->wlan_acl_list; + plist = phead->next; + //check sa + if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected. + res = FAIL; + else + res = SUCCESS; + + while(plist != phead) + { + paclnode = list_entry(plist, struct rtw_wlan_acl_node, list); + plist = plist->next; + if (!memcmp((void *)sa, paclnode->addr, 6)) { + if (paclnode->mode & 2) { // deny + res = FAIL; + break; + } + else { + res = SUCCESS; + break; + } + } + } + + if (res != SUCCESS) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n"); + return FAIL; + } +#else + if(rtw_access_ctrl(padapter, sa) == _FALSE) + { + status = _STATS_UNABLE_HANDLE_STA_; + goto auth_fail; + } +#endif + + pstat = rtw_get_stainfo(pstapriv, sa); + if (pstat == NULL) + { + + // allocate a new one + DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa)); + pstat = rtw_alloc_stainfo(pstapriv, sa); + if (pstat == NULL) + { + DBG_871X(" Exceed the upper limit of supported clients...\n"); + status = _STATS_UNABLE_HANDLE_STA_; + goto auth_fail; + } + + pstat->state = WIFI_FW_AUTH_NULL; + pstat->auth_seq = 0; + + //pstat->flags = 0; + //pstat->capability = 0; + } else { +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) +#endif /* CONFIG_IEEE80211W */ + { + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) { + rtw_list_delete(&pstat->asoc_list); + pstapriv->asoc_list_cnt--; + if (pstat->expire_to > 0) + ;/* TODO: STA re_auth within expire_to */ + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + if (seq == 1) + ; /* TODO: STA re_auth and auth timeout */ + + } + } + +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) +#endif /* CONFIG_IEEE80211W */ + { + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + if (rtw_is_list_empty(&pstat->auth_list)) { + + rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list); + pstapriv->auth_list_cnt++; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + } + + if (pstat->auth_seq == 0) + pstat->expire_to = pstapriv->auth_to; + + + if ((pstat->auth_seq + 1) != seq) + { + DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + + if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) + { + if (seq == 1) + { +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) +#endif /* CONFIG_IEEE80211W */ + { + pstat->state &= ~WIFI_FW_AUTH_NULL; + pstat->state |= WIFI_FW_AUTH_SUCCESS; + pstat->expire_to = pstapriv->assoc_to; + } + pstat->authalg = algorithm; + } + else + { + DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + } + else // shared system or auto authentication + { + if (seq == 1) + { + //prepare for the challenging txt... + + //get_random_bytes((void *)pstat->chg_txt, 128);//TODO: + _rtw_memset((void *)pstat->chg_txt, 78, 128); +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) +#endif /* CONFIG_IEEE80211W */ + { + pstat->state &= ~WIFI_FW_AUTH_NULL; + pstat->state |= WIFI_FW_AUTH_STATE; + } + pstat->authalg = algorithm; + pstat->auth_seq = 2; + } + else if (seq == 3) + { + //checking for challenging txt... + DBG_871X("checking for challenging txt...\n"); + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len, + len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); + + if((p==NULL) || (ie_len<=0)) + { + DBG_871X("auth rejected because challenge failure!(1)\n"); + status = _STATS_CHALLENGE_FAIL_; + goto auth_fail; + } + + if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) + { +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) +#endif /* CONFIG_IEEE80211W */ + { + pstat->state &= (~WIFI_FW_AUTH_STATE); + pstat->state |= WIFI_FW_AUTH_SUCCESS; + /* challenging txt is correct... */ + pstat->expire_to = pstapriv->assoc_to; + } + } + else + { + DBG_871X("auth rejected because challenge failure!\n"); + status = _STATS_CHALLENGE_FAIL_; + goto auth_fail; + } + } + else + { + DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n", + seq, pstat->auth_seq+1); + status = _STATS_OUT_OF_AUTH_SEQ_; + goto auth_fail; + } + } + + + // Now, we are going to issue_auth... + pstat->auth_seq = seq + 1; + +#ifdef CONFIG_NATIVEAP_MLME + issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); +#endif + + if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS)) + pstat->auth_seq = 0; + + + return _SUCCESS; + +auth_fail: + + if(pstat) + rtw_free_stainfo(padapter , pstat); + + pstat = &stat; + _rtw_memset((char *)pstat, '\0', sizeof(stat)); + pstat->auth_seq = 2; + _rtw_memcpy(pstat->hwaddr, sa, 6); + +#ifdef CONFIG_NATIVEAP_MLME + issue_auth(padapter, pstat, (unsigned short)status); +#endif + +#endif + return _FAIL; + +} + +unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int seq, len, status, algthm, offset; + unsigned char *p; + unsigned int go2asoc = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; + + DBG_871X("%s\n", __FUNCTION__); + + //check A1 matches or not + if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN)) + return _SUCCESS; + + if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) + return _SUCCESS; + + offset = (GetPrivacy(pframe))? 4: 0; + + algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset)); + seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); + status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4)); + + if (status != 0) + { + DBG_871X("clnt auth fail, status: %d\n", status); + if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) + { + if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; + else + pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; + //pmlmeinfo->reauth_count = 0; + } + + set_link_timer(pmlmeext, 1); + goto authclnt_fail; + } + + if (seq == 2) + { + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + { + // legendary shared system + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len, + pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); + + if (p == NULL) + { + //DBG_871X("marc: no challenge text?\n"); + goto authclnt_fail; + } + + _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); + pmlmeinfo->auth_seq = 3; + issue_auth(padapter, NULL, 0); + set_link_timer(pmlmeext, REAUTH_TO); + + return _SUCCESS; + } + else + { + // open system + go2asoc = 1; + } + } + else if (seq == 4) + { + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) + { + go2asoc = 1; + } + else + { + goto authclnt_fail; + } + } + else + { + // this is also illegal + //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq); + goto authclnt_fail; + } + + if (go2asoc) + { + DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n"); + start_clnt_assoc(padapter); + return _SUCCESS; + } + +authclnt_fail: + + //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); + + return _FAIL; + +} + +unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + _irqL irqL; + u16 capab_info, listen_interval; + struct rtw_ieee802_11_elems elems; + struct sta_info *pstat; + unsigned char reassoc, *p, *pos, *wpa_ie; + unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; + int i, ie_len, wpa_ie_len, left; + u8 rate_set[16]; + u8 rate_num; + unsigned short status = _STATS_SUCCESSFUL_; + unsigned short frame_type, ie_offset=0; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 p2p_status_code = P2P_STATUS_SUCCESS; + u8 *p2pie; + u32 p2pielen = 0; +#endif //CONFIG_P2P + +#ifdef CONFIG_CONCURRENT_MODE + if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)) + { + //don't process assoc request; + return _SUCCESS; + } +#endif //CONFIG_CONCURRENT_MODE + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + return _FAIL; + + frame_type = GetFrameSubType(pframe); + if (frame_type == WIFI_ASSOCREQ) + { + reassoc = 0; + ie_offset = _ASOCREQ_IE_OFFSET_; + } + else // WIFI_REASSOCREQ + { + reassoc = 1; + ie_offset = _REASOCREQ_IE_OFFSET_; + } + + + if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) { + DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)" + "\n", reassoc, (unsigned long)pkt_len); + return _FAIL; + } + + pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (pstat == (struct sta_info *)NULL) + { + status = _RSON_CLS2_; + goto asoc_class2_error; + } + + capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN); + //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); + listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2); + + left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset); + pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset); + + + DBG_871X("%s\n", __FUNCTION__); + + // check if this stat has been successfully authenticated/assocated + if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) + { + if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) + { + status = _RSON_CLS2_; + goto asoc_class2_error; + } + else + { + pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); + pstat->state |= WIFI_FW_ASSOC_STATE; + } + } + else + { + pstat->state &= (~WIFI_FW_AUTH_SUCCESS); + pstat->state |= WIFI_FW_ASSOC_STATE; + } + + +#if 0// todo:tkip_countermeasures + if (hapd->tkip_countermeasures) { + resp = WLAN_REASON_MICHAEL_MIC_FAILURE; + goto fail; + } +#endif + + pstat->capability = capab_info; + +#if 0//todo: + //check listen_interval + if (listen_interval > hapd->conf->max_listen_interval) { + hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_DEBUG, + "Too large Listen Interval (%d)", + listen_interval); + resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; + goto fail; + } + + pstat->listen_interval = listen_interval; +#endif + + //now parse all ieee802_11 ie to point to elems + if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || + !elems.ssid) { + DBG_871X("STA " MAC_FMT " sent invalid association request\n", + MAC_ARG(pstat->hwaddr)); + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + + + // now we should check all the fields... + // checking SSID + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len, + pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p == NULL) + { + status = _STATS_FAILURE_; + } + + if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq + status = _STATS_FAILURE_; + else + { + // check if ssid match + if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) + status = _STATS_FAILURE_; + + if (ie_len != cur->Ssid.SsidLength) + status = _STATS_FAILURE_; + } + + if(_STATS_SUCCESSFUL_ != status) + goto OnAssocReqFail; + + rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num); + if (rate_num == 0) { + DBG_871X(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter)); + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + _rtw_memcpy(pstat->bssrateset, rate_set, rate_num); + pstat->bssratelen = rate_num; + UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen); + + //check RSN/WPA/WPS + pstat->dot8021xalg = 0; + pstat->wpa_psk = 0; + pstat->wpa_group_cipher = 0; + pstat->wpa2_group_cipher = 0; + pstat->wpa_pairwise_cipher = 0; + pstat->wpa2_pairwise_cipher = 0; + _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); + if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { + + int group_cipher=0, pairwise_cipher=0; + + wpa_ie = elems.rsn_ie; + wpa_ie_len = elems.rsn_ie_len; + + if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + pstat->dot8021xalg = 1;//psk, todo:802.1x + pstat->wpa_psk |= BIT(1); + + pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher; + pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher; + + if(!pstat->wpa2_group_cipher) + status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + + if(!pstat->wpa2_pairwise_cipher) + status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; + } + else + { + status = WLAN_STATUS_INVALID_IE; + } + + } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { + + int group_cipher=0, pairwise_cipher=0; + + wpa_ie = elems.wpa_ie; + wpa_ie_len = elems.wpa_ie_len; + + if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + pstat->dot8021xalg = 1;//psk, todo:802.1x + pstat->wpa_psk |= BIT(0); + + pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher; + pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher; + + if(!pstat->wpa_group_cipher) + status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; + + if(!pstat->wpa_pairwise_cipher) + status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; + + } + else + { + status = WLAN_STATUS_INVALID_IE; + } + + } else { + wpa_ie = NULL; + wpa_ie_len = 0; + } + + if(_STATS_SUCCESSFUL_ != status) + goto OnAssocReqFail; + + pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); + //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS + if(wpa_ie == NULL) { + if (elems.wps_ie) { + DBG_871X("STA included WPS IE in " + "(Re)Association Request - assume WPS is " + "used\n"); + pstat->flags |= WLAN_STA_WPS; + //wpabuf_free(sta->wps_ie); + //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, + // elems.wps_ie_len - 4); + } else { + DBG_871X("STA did not include WPA/RSN IE " + "in (Re)Association Request - possible WPS " + "use\n"); + pstat->flags |= WLAN_STA_MAYBE_WPS; + } + + + // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready + // that the selected registrar of AP is _FLASE + if((psecuritypriv->wpa_psk >0) + && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) + { + if(pmlmepriv->wps_beacon_ie) + { + u8 selected_registrar = 0; + + rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL); + + if(!selected_registrar) + { + DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n"); + + status = _STATS_UNABLE_HANDLE_STA_; + + goto OnAssocReqFail; + } + } + } + + } + else + { + int copy_len; + + if(psecuritypriv->wpa_psk == 0) + { + DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association " + "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr)); + + status = WLAN_STATUS_INVALID_IE; + + goto OnAssocReqFail; + + } + + if (elems.wps_ie) { + DBG_871X("STA included WPS IE in " + "(Re)Association Request - WPS is " + "used\n"); + pstat->flags |= WLAN_STA_WPS; + copy_len=0; + } + else + { + copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2); + } + + + if(copy_len>0) + _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len); + + } + + + // check if there is WMM IE & support WWM-PS + pstat->flags &= ~WLAN_STA_WME; + pstat->qos_option = 0; + pstat->qos_info = 0; + pstat->has_legacy_ac = _TRUE; + pstat->uapsd_vo = 0; + pstat->uapsd_vi = 0; + pstat->uapsd_be = 0; + pstat->uapsd_bk = 0; + if (pmlmepriv->qospriv.qos_option) + { + p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; + for (;;) + { + p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); + if (p != NULL) { + if (_rtw_memcmp(p+2, WMM_IE, 6)) { + + pstat->flags |= WLAN_STA_WME; + + pstat->qos_option = 1; + pstat->qos_info = *(p+8); + + pstat->max_sp_len = (pstat->qos_info>>5)&0x3; + + if((pstat->qos_info&0xf) !=0xf) + pstat->has_legacy_ac = _TRUE; + else + pstat->has_legacy_ac = _FALSE; + + if(pstat->qos_info&0xf) + { + if(pstat->qos_info&BIT(0)) + pstat->uapsd_vo = BIT(0)|BIT(1); + else + pstat->uapsd_vo = 0; + + if(pstat->qos_info&BIT(1)) + pstat->uapsd_vi = BIT(0)|BIT(1); + else + pstat->uapsd_vi = 0; + + if(pstat->qos_info&BIT(2)) + pstat->uapsd_bk = BIT(0)|BIT(1); + else + pstat->uapsd_bk = 0; + + if(pstat->qos_info&BIT(3)) + pstat->uapsd_be = BIT(0)|BIT(1); + else + pstat->uapsd_be = 0; + + } + + break; + } + } + else { + break; + } + p = p + ie_len + 2; + } + } + + +#ifdef CONFIG_80211N_HT + /* save HT capabilities in the sta object */ + _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap)); + if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) + { + pstat->flags |= WLAN_STA_HT; + + pstat->flags |= WLAN_STA_WME; + + _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap)); + + } else + pstat->flags &= ~WLAN_STA_HT; + + + if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT)) + { + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } + +#endif /* CONFIG_80211N_HT */ + +#ifdef CONFIG_80211AC_VHT + _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv)); + if (elems.vht_capabilities && elems.vht_capabilities_len == 12) { + pstat->flags |= WLAN_STA_VHT; + + _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12); + + if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) { + _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1); + } + else // for Frame without Operating Mode notify ie; default: 80M + { + pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80; + } + } + else { + pstat->flags &= ~WLAN_STA_VHT; + } + + if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT)) + { + status = _STATS_FAILURE_; + goto OnAssocReqFail; + } +#endif /* CONFIG_80211AC_VHT */ + + if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) && + ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || + (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) { + + DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr)); + + pstat->flags &= ~WLAN_STA_HT; + pstat->flags &= ~WLAN_STA_VHT; + /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; + * goto OnAssocReqFail; + */ + } + + + // + //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//? + pstat->flags |= WLAN_STA_NONERP; + for (i = 0; i < pstat->bssratelen; i++) { + if ((pstat->bssrateset[i] & 0x7f) > 22) { + pstat->flags &= ~WLAN_STA_NONERP; + break; + } + } + + if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + pstat->flags |= WLAN_STA_SHORT_PREAMBLE; + else + pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; + + + + if (status != _STATS_SUCCESSFUL_) + goto OnAssocReqFail; + +#ifdef CONFIG_P2P + pstat->is_p2p_device = _FALSE; + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen))) + { + pstat->is_p2p_device = _TRUE; + if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0) + { + pstat->p2p_status_code = p2p_status_code; + status = _STATS_CAP_FAIL_; + goto OnAssocReqFail; + } + } + #ifdef CONFIG_WFD + rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__); + #endif + } + pstat->p2p_status_code = p2p_status_code; +#endif //CONFIG_P2P + + //TODO: identify_proprietary_vendor_ie(); + // Realtek proprietary IE + // identify if this is Broadcom sta + // identify if this is ralink sta + // Customer proprietary IE + + + + /* get a unique AID */ + if (pstat->aid > 0) { + DBG_871X(" old AID %d\n", pstat->aid); + } else { + for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) { + if (pstapriv->sta_aid[pstat->aid - 1] == NULL) { + if (pstat->aid > pstapriv->max_num_sta) { + pstat->aid = 0; + + DBG_871X(" no room for more AIDs\n"); + + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + + goto OnAssocReqFail; + + + } else { + pstapriv->sta_aid[pstat->aid - 1] = pstat; + DBG_871X("allocate new AID = (%d)\n", pstat->aid); + break; + } + } + } + } + + + pstat->state &= (~WIFI_FW_ASSOC_STATE); + pstat->state |= WIFI_FW_ASSOC_SUCCESS; + /* DBG_871X("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n" + , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */ +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE) +#endif /* CONFIG_IEEE80211W */ + { + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); + if (!rtw_is_list_empty(&pstat->auth_list)) { + rtw_list_delete(&pstat->auth_list); + pstapriv->auth_list_cnt--; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (rtw_is_list_empty(&pstat->asoc_list)) { + pstat->expire_to = pstapriv->expire_to; + rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list); + pstapriv->asoc_list_cnt++; + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + } + + // now the station is qualified to join our BSS... + if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status)) + { +#ifdef CONFIG_NATIVEAP_MLME +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE) +#endif /* CONFIG_IEEE80211W */ + { + /* .1 bss_cap_update & sta_info_update */ + bss_cap_update_on_sta_join(padapter, pstat); + sta_info_update(padapter, pstat); + } +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed == _TRUE) + status = _STATS_REFUSED_TEMPORARILY_; +#endif /* CONFIG_IEEE80211W */ + //.2 issue assoc rsp before notify station join event. + if (frame_type == WIFI_ASSOCREQ) + issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); + else + issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); + +#ifdef CONFIG_IOCTL_CFG80211 + _enter_critical_bh(&pstat->lock, &irqL); + if(pstat->passoc_req) + { + rtw_mfree(pstat->passoc_req, pstat->assoc_req_len); + pstat->passoc_req = NULL; + pstat->assoc_req_len = 0; + } + + pstat->passoc_req = rtw_zmalloc(pkt_len); + if(pstat->passoc_req) + { + _rtw_memcpy(pstat->passoc_req, pframe, pkt_len); + pstat->assoc_req_len = pkt_len; + } + _exit_critical_bh(&pstat->lock, &irqL); +#endif //CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed != _TRUE) +#endif /* CONFIG_IEEE80211W */ + { + /* .3-(1) report sta add event */ + report_add_sta_event(padapter, pstat->hwaddr); + } +#ifdef CONFIG_IEEE80211W + if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) { + DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr)); + issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY); + } +#endif /* CONFIG_IEEE80211W */ +#endif //CONFIG_NATIVEAP_MLME + } + + return _SUCCESS; + +asoc_class2_error: + +#ifdef CONFIG_NATIVEAP_MLME + issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); +#endif + + return _FAIL; + +OnAssocReqFail: + + +#ifdef CONFIG_NATIVEAP_MLME + pstat->aid = 0; + if (frame_type == WIFI_ASSOCREQ) + issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); + else + issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); +#endif + + +#endif /* CONFIG_AP_MODE */ + + return _FAIL; + +} + +unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame) +{ + uint i; + int res; + unsigned short status; + PNDIS_802_11_VARIABLE_IEs pIE; + 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 *pframe = precv_frame->u.hdr.rx_data; + uint pkt_len = precv_frame->u.hdr.len; + PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL; + + DBG_871X("%s\n", __FUNCTION__); + + //check A1 matches or not + if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN)) + return _SUCCESS; + + if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) + return _SUCCESS; + + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + return _SUCCESS; + + _cancel_timer_ex(&pmlmeext->link_timer); + + //status + if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0) + { + DBG_871X("assoc reject, status code: %d\n", status); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + res = -4; + goto report_assoc_result; + } + + //get capabilities + pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + //set slot time + pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20; + + //AID + res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff); + + //following are moved to join event callback function + //to handle HT, WMM, rate adaptive, update MAC reg + //for not to handle the synchronous IO in the tasklet + for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM + { + WMM_param_handler(padapter, pIE); + } +#if defined(CONFIG_P2P) && defined(CONFIG_WFD) + else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD + { + rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__); + } +#endif + break; + +#ifdef CONFIG_WAPI_SUPPORT + case _WAPI_IE_: + pWapiIE = pIE; + break; +#endif + + case _HT_CAPABILITY_IE_: //HT caps + HT_caps_handler(padapter, pIE); + break; + + case _HT_EXTRA_INFO_IE_: //HT info + HT_info_handler(padapter, pIE); + break; + +#ifdef CONFIG_80211AC_VHT + case EID_VHTCapability: + VHT_caps_handler(padapter, pIE); + break; + + case EID_VHTOperation: + VHT_operation_handler(padapter, pIE); + break; +#endif + + case _ERPINFO_IE_: + ERP_IE_handler(padapter, pIE); + break; +#ifdef CONFIG_TDLS + case _EXT_CAP_IE_: + if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE) + padapter->tdlsinfo.ap_prohibited = _TRUE; + if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE) + padapter->tdlsinfo.ch_switch_prohibited = _TRUE; + break; +#endif /* CONFIG_TDLS */ + default: + break; + } + + i += (pIE->Length + 2); + } + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_on_assoc_ok(padapter, pIE); +#endif + + pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + + //Update Basic Rate Table for spec, 2010-12-28 , by thomas + UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); + +report_assoc_result: + if (res > 0) { + rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); + } else { + rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); + } + + report_join_res(padapter, res); + + return _SUCCESS; +} + +unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned short reason; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //check A3 + if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + + DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter)); + +#ifdef CONFIG_P2P + if ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + rtw_lock_rx_suspend_timeout(8000); + +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n" + , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe)); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if(psta) + { + u8 updated = _FALSE; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); + } + + + return _SUCCESS; + } + else +#endif + { + int ignore_received_deauth = 0; + + // Commented by Albert 20130604 + // Before sending the auth frame to start the STA/GC mode connection with AP/GO, + // we will send the deauth first. + // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. + // Added the following code to avoid this case. + if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) || + ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) ) + { + if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ) + { + ignore_received_deauth = 1; + } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { + // TODO: 802.11r + ignore_received_deauth = 1; + } + } + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n" + , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth); + + if ( 0 == ignore_received_deauth ) + { + receive_disconnect(padapter, GetAddr2Ptr(pframe), reason); + } + } + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + return _SUCCESS; + +} + +unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned short reason; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //check A3 + if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + + DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter)); + +#ifdef CONFIG_P2P + if ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); + + rtw_lock_rx_suspend_timeout(8000); + +#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _irqL irqL; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + //rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n" + , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe)); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if(psta) + { + u8 updated = _FALSE; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); + } + + return _SUCCESS; + } + else +#endif + { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n" + , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe)); + + receive_disconnect(padapter, GetAddr2Ptr(pframe), reason); + } + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + return _SUCCESS; + +} + +unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame) +{ + DBG_871X("%s\n", __FUNCTION__); + return _SUCCESS; +} + +unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len) +{ + unsigned int ret = _FAIL; + struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info); + + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { + ret = _SUCCESS; + goto exit; + } + + if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { + + int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1; + int ch_offset = -1; + u8 bwmode; + struct ieee80211_info_element *ie; + + DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n", + FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr)); + + for_each_ie(ie, ies, ies_len) { + if (ie->id == WLAN_EID_CHANNEL_SWITCH) { + ch_switch_mode = ie->data[0]; + ch = ie->data[1]; + ch_switch_cnt = ie->data[2]; + DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n", + ch_switch_mode, ch, ch_switch_cnt); + } + else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) { + ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]); + DBG_871X("ch_offset:%d\n", ch_offset); + } + } + + if (ch == -1) + return _SUCCESS; + + if (ch_offset == -1) + bwmode = mlmeext->cur_bwmode; + else + bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ? + CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40; + + ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset; + + /* todo: + * 1. the decision of channel switching + * 2. things after channel switching + */ + + ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE); + } + +exit: + return ret; +} + +unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + u8 category; + u8 action; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + + if (!psta) + goto exit; + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) + goto exit; + + action = frame_body[1]; + switch (action) { + case RTW_WLAN_ACTION_SPCT_MSR_REQ: + case RTW_WLAN_ACTION_SPCT_MSR_RPRT: + case RTW_WLAN_ACTION_SPCT_TPC_REQ: + case RTW_WLAN_ACTION_SPCT_TPC_RPRT: + break; + case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: + #ifdef CONFIG_SPCT_CH_SWITCH + ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2], + frame_len-(frame_body-pframe)-2); + #endif + break; + default: + break; + } + +exit: + return ret; +} + +unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +/** + * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter + * @adapter: the adapter to get target RX AMPDU buffer size + * + * Returns: the target RX AMPDU buffer size + */ +u8 rtw_rx_ampdu_size(_adapter *adapter) +{ + u8 size; + HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor; + + if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) { + size = adapter->fix_rx_ampdu_size; + goto exit; + } + +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) { + size = rtw_btcoex_GetAMPDUSize(adapter); + goto exit; + } +#endif + + /* for scan */ + if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE) + && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE) + && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID + ) { + size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size; + goto exit; + } + + /* default value based on max_rx_ampdu_factor */ + if (adapter->driver_rx_ampdu_factor != 0xFF) + max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor; + else + rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); + + if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor) + size = 64; + else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor) + size = 32; + else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor) + size = 16; + else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor) + size = 8; + else + size = 64; + +exit: + + if (size > 127) + size = 127; + + return size; +} + +/** + * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter + * @adapter: the adapter to get the permission if RX AMPDU should be set up + * + * Returns: accept or not + */ +bool rtw_rx_ampdu_is_accept(_adapter *adapter) +{ + bool accept; + + if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) { + accept = adapter->fix_rx_ampdu_accept; + goto exit; + } + +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) { + accept = _FALSE; + goto exit; + } +#endif + + /* for scan */ + if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE) + && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE) + && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID + ) { + accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept; + goto exit; + } + + /* default value for other cases */ + accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq; + +exit: + return accept; +} + +/** + * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason + * @adapter: the adapter to set target RX AMPDU buffer size + * @size: the target RX AMPDU buffer size to set + * @reason: reason for the target RX AMPDU buffer size setting + * + * Returns: whether the target RX AMPDU buffer size is changed + */ +bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason) +{ + bool is_adj = _FALSE; + struct mlme_ext_priv *mlmeext; + struct mlme_ext_info *mlmeinfo; + + mlmeext = &adapter->mlmeextpriv; + mlmeinfo = &mlmeext->mlmext_info; + + if (reason == RX_AMPDU_DRV_FIXED) { + if (adapter->fix_rx_ampdu_size != size) { + adapter->fix_rx_ampdu_size = size; + is_adj = _TRUE; + DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size); + } + } else if (reason == RX_AMPDU_DRV_SCAN) { + struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res; + + if (ss->rx_ampdu_size != size) { + ss->rx_ampdu_size = size; + is_adj = _TRUE; + DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size); + } + } + + return is_adj; +} + +/** + * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason + * @adapter: the adapter to set if RX AMPDU should be set up + * @accept: if RX AMPDU should be set up + * @reason: reason for the permission if RX AMPDU should be set up + * + * Returns: whether the permission if RX AMPDU should be set up is changed + */ +bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason) +{ + bool is_adj = _FALSE; + struct mlme_ext_priv *mlmeext; + struct mlme_ext_info *mlmeinfo; + + mlmeext = &adapter->mlmeextpriv; + mlmeinfo = &mlmeext->mlmext_info; + + if (reason == RX_AMPDU_DRV_FIXED) { + if (adapter->fix_rx_ampdu_accept != accept) { + adapter->fix_rx_ampdu_accept = accept; + is_adj = _TRUE; + DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept); + } + } else if (reason == RX_AMPDU_DRV_SCAN) { + if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) { + adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept; + is_adj = _TRUE; + DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept); + } + } + + return is_adj; +} + +/** + * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid + * @adapter: the adapter to which @sta belongs + * @sta: the sta to be checked + * @tid: the tid to be checked + * @accept: the target permission if RX AMPDU should be set up + * @size: the target RX AMPDU buffer size + * + * Returns: + * 0: no canceled + * 1: canceled by no permission + * 2: canceled by different buffer size + * 3: canceled by potential mismatched status + * + * Blocking function, may sleep + */ +u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size) +{ + u8 ret = 0; + struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid]; + + if (reorder_ctl->enable == _FALSE) { + if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) { + send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1); + ret = 3; + } + goto exit; + } + + if (accept == _FALSE) { + send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0); + ret = 1; + } else if (reorder_ctl->ampdu_size != size) { + send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0); + ret = 2; + } + +exit: + return ret; +} + +/** + * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta + * @adapter: the adapter to which @sta belongs + * @sta: the sta to be checked + * @accept: the target permission if RX AMPDU should be set up + * @size: the target RX AMPDU buffer size + * + * Returns: number of the RX AMPDU assciation canceled for applying current target setting + * + * Blocking function, may sleep + */ +u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size) +{ + u8 change_cnt = 0; + int i; + + for (i = 0; i < TID_NUM; i++) { + if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0) + change_cnt++; + } + + return change_cnt; +} + +/** + * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter + * @adapter: the adapter to be applied + * + * Returns: number of the RX AMPDU assciation canceled for applying current target setting + */ +u16 rtw_rx_ampdu_apply(_adapter *adapter) +{ + u16 adj_cnt = 0; + struct mlme_ext_priv *mlmeext; + struct sta_info *sta; + u8 accept = rtw_rx_ampdu_is_accept(adapter); + u8 size = rtw_rx_ampdu_size(adapter); + + mlmeext = &adapter->mlmeextpriv; + + if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) { + sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv)); + if (sta) + adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size); + + } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) { + _irqL irqL; + _list *phead, *plist; + u8 peer_num = 0; + char peers[NUM_STA]; + struct sta_priv *pstapriv = &adapter->stapriv; + int i; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + + sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + stainfo_offset = rtw_stainfo_offset(pstapriv, sta); + if (stainfo_offset_valid(stainfo_offset)) + peers[peer_num++] = stainfo_offset; + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + for (i = 0; i < peer_num; i++) { + sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]); + if (sta) + adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size); + } + } + + return adj_cnt; +} + +unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *addr; + struct sta_info *psta=NULL; + struct recv_reorder_ctrl *preorder_ctrl; + unsigned char *frame_body; + unsigned char category, action; + unsigned short tid, status, reason_code = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 *pframe = precv_frame->u.hdr.rx_data; + struct sta_priv *pstapriv = &padapter->stapriv; +#ifdef CONFIG_80211N_HT + + DBG_871X("%s\n", __FUNCTION__); + + //check RA matches or not + if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + return _SUCCESS; + +/* + //check A1 matches or not + if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN)) + return _SUCCESS; +*/ + + if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + return _SUCCESS; + + addr = GetAddr2Ptr(pframe); + psta = rtw_get_stainfo(pstapriv, addr); + + if(psta==NULL) + return _SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack + { +#ifdef CONFIG_TDLS + if((psta->tdls_sta_state & TDLS_LINKED_STATE) && + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE)) + { + DBG_871X("Recv [%s] from direc link\n", __FUNCTION__); + } + else +#endif //CONFIG_TDLS + if (!pmlmeinfo->HT_enable) + { + return _SUCCESS; + } + + action = frame_body[1]; + DBG_871X("%s, action=%d\n", __FUNCTION__, action); + switch (action) + { + case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request + + _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request)); + //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); + process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr); + + break; + + case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response + + //status = frame_body[3] | (frame_body[4] << 8); //endian issue + status = RTW_GET_LE16(&frame_body[3]); + tid = ((frame_body[5] >> 2) & 0x7); + + if (status == 0) + { //successful + DBG_871X("agg_enable for TID=%d\n", tid); + psta->htpriv.agg_enable_bitmap |= 1 << tid; + psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); + } + else + { + psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + } + + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + DBG_871X("%s alive check - rx ADDBA response\n", __func__); + psta->htpriv.agg_enable_bitmap &= ~BIT(tid); + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } + + //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); + break; + + case RTW_WLAN_ACTION_DELBA: //DELBA + if ((frame_body[3] & BIT(3)) == 0) + { + psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); + psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf)); + + //reason_code = frame_body[4] | (frame_body[5] << 8); + reason_code = RTW_GET_LE16(&frame_body[4]); + } + else if((frame_body[3] & BIT(3)) == BIT(3)) + { + tid = (frame_body[3] >> 4) & 0x0F; + + preorder_ctrl = &psta->recvreorder_ctrl[tid]; + preorder_ctrl->enable = _FALSE; + preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; + } + + DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code); + //todo: how to notify the host while receiving DELETE BA + break; + + default: + break; + } + } +#endif //CONFIG_80211N_HT + return _SUCCESS; +} + +#ifdef CONFIG_P2P + +static int get_reg_classes_full_count(struct p2p_channels channel_list) { + int cnt = 0; + int i; + + for (i = 0; i < channel_list.reg_classes; i++) { + cnt += channel_list.reg_class[i].channels; + } + + return cnt; +} + +static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt ) +{ + int i = 0; + + *p24g_cnt = 0; + *p5gl_cnt = 0; + *p5gh_cnt = 0; + + for( i = 0; i < pmlmeext->max_chan_nums; i++ ) + { + if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 ) + { + (*p24g_cnt)++; + } + else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) ) + { + // Just include the channel 36, 40, 44, 48 channels for 5G low + (*p5gl_cnt)++; + } + else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) ) + { + // Just include the channel 149, 153, 157, 161 channels for 5G high + (*p5gh_cnt)++; + } + } +} + +void issue_p2p_GO_request(_adapter *padapter, u8* raddr) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_REQ; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 wpsielen = 0, p2pielen = 0, i; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + 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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value + pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen)); + + + + // 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 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC ); + } + else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); + } + else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC ) + { + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC ); + } + + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->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 20110306 + // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes + // 1. P2P Capability + // 2. Group Owner Intent + // 3. Configuration Timeout + // 4. Listen Channel + // 5. Extended Listen Timing + // 6. Intended P2P Interface Address + // 7. Channel List + // 8. P2P Device Info + // 9. Operating Channel + + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + 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: + // Todo the tie breaker bit. + p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) & 0xFE ); + + // 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 + + + // Listen Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_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->listen_channel; // listening channel number + + + // Extended Listen Timing ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + + // 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, adapter_mac_addr(padapter), 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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + *(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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + _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, adapter_mac_addr(padapter), 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; + + + // 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 + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + + +void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_RESP; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + uint wpsielen = 0; + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh; + u16 len_channellist_attr = 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); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); + +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result ); + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame. + pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen)); + + // Commented by Albert 20110328 + // Try to get the device password ID from the WPS IE of group negotiation request frame + // WiFi Direct test plan 5.1.15 + rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); + rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + _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; + + // Commented by Kurt 20120113 + // If some device wants to do p2p handshake without sending prov_disc_req + // We have to get peer_req_cm from here. + if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) ) + { + if ( wps_devicepassword_id == WPS_DPID_USER_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + } + else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + } + else + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + } + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->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: + p2pie[ p2pielen++ ] = result; + + // 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, adapter_mac_addr(padapter), 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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + *(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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + _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, adapter_mac_addr(padapter), 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, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_NEGO_CONF; + u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u8 wpsielen = 0, p2pielen = 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); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->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 20110306 + // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes + // 1. Status + // 2. P2P Capability + // 3. Operating Channel + // 4. Channel List + // 5. Group ID ( if this WiFi is GO ) + + // P2P Status + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_STATUS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = result; + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + 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; + } + + + // 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; + + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ) + { + if ( pwdinfo->peer_operating_ch <= 14 ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x51; + } + else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x73; + } + else + { + // Operating Class + p2pie[ p2pielen++ ] = 0x7c; + } + + p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch; + } + else + { + 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; // Use the listen channel as the operating channel + } + + + // Channel List + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST; + + *(u16*) ( p2pie + p2pielen ) = 6; + p2pielen += 2; + + // 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; + + // Value: + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ) + { + if ( pwdinfo->peer_operating_ch <= 14 ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x51; + } + else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) ) + { + // Operating Class + p2pie[ p2pielen++ ] = 0x73; + } + else + { + // Operating Class + p2pie[ p2pielen++ ] = 0x7c; + } + p2pie[ p2pielen++ ] = 1; + p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch; + } + else + { + 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++ ] = 1; + p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel + } + + 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, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_invitation_request(_adapter *padapter, u8* raddr ) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_INVIT_REQ; + u8 p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + u8 dialogToken = 3; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_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 + + 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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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 20101011 + // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes + // 1. Configuration Timeout + // 2. Invitation Flags + // 3. Operating Channel ( Only GO ) + // 4. P2P Group BSSID ( Should be included if I am the GO ) + // 5. Channel List + // 6. P2P Group ID + // 7. P2P Device Info + + // 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 + + // Invitation Flags + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 ); + p2pielen += 2; + + // Value: + p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT; + + + // 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->invitereq_info.operating_ch <= 14 ) + p2pie[ p2pielen++ ] = 0x51; + else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) ) + p2pie[ p2pielen++ ] = 0x73; + else + p2pie[ p2pielen++ ] = 0x7c; + + // Channel Number + p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number + + if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) + { + // 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, pwdinfo->invitereq_info.go_bssid, 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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + *(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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + _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 + + + // P2P Group ID + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen ); + p2pielen += 2; + + // Value: + // P2P Device Address for GO + _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN ); + p2pielen += ETH_ALEN; + + // SSID + _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen ); + p2pielen += pwdinfo->invitereq_info.ssidlen; + + + // 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, adapter_mac_addr(padapter), ETH_ALEN); + p2pielen += ETH_ALEN; + + // Config Method + // This field should be big endian. Noted by P2P specification. + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); + 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; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code) +{ + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_INVIT_RESP; + u8 p2pie[ 255 ] = { 0x00 }; + u8 p2pielen = 0, i; + u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0; + u16 len_channellist_attr = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_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 + + 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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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: + // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. + // Sent the event receiving the P2P Invitation Req frame to DMP UI. + // DMP had to compare the MAC address to find out the profile. + // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. + // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req + // to NB to rebuild the persistent group. + p2pie[ p2pielen++ ] = status_code; + + // 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 + + 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, adapter_mac_addr(padapter), 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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + *(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) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + _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 + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr ) +{ + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = 1; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_REQ; + u8 wpsie[ 100 ] = { 0x00 }; + u8 wpsielen = 0; + u32 p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + 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); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + //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, pdev_raddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr ); + + pframe += p2pielen; + pattrib->pktlen += p2pielen; + + 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 + + // 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->tx_prov_disc_info.wps_config_method_request ); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + + +u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo ) +{ + u8 i, match_result = 0; + + DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]); + + for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ ) + { + DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]); + if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) ) + { + match_result = 1; + DBG_871X( "[%s] Match!\n", __FUNCTION__ ); + break; + } + } + + return (match_result ); +} + +void issue_probersp_p2p(_adapter *padapter, unsigned char *da) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif +#ifdef CONFIG_INTEL_WIDI + u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 }; +#endif //CONFIG_INTEL_WIDI + + //DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; + + mac = adapter_mac_addr(padapter); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, da, 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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = pattrib->hdrlen; + pframe += pattrib->hdrlen; + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); + pframe += 2; + pattrib->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; + pattrib->pktlen += 2; + + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen); + +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && 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); + pattrib->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); + pattrib->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, mac, 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, &pattrib->pktlen ); + + + p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe); + pframe += p2pielen; + pattrib->pktlen += p2pielen; + } + +#ifdef CONFIG_WFD + wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac; + unsigned char bssrate[NumRates]; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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}; + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 }; + u16 wpsielen = 0, p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //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; + + mac = adapter_mac_addr(padapter); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + if (da) { + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN); + } else { + if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) ) + { + // This two flags will be set when this is only the P2P client mode. + _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN); + } + else + { + // broadcast probe request frame + _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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_PROBEREQ); + + pframe += sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen)); + } + else + { + pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen)); + } + // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen); + +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL ) + { + //WPS IE + _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; + pframe += pmlmepriv->wps_probe_req_ie_len; + + //P2P IE + _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len); + pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len; + pframe += pmlmepriv->p2p_probe_req_ie_len; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + + // WPS IE + // Noted by Albert 20110221 + // 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 + + if( pmlmepriv->wps_probe_req_ie == NULL ) + { + // 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, mac, ETH_ALEN); + } else { + _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 ); + } + wpsielen += 0x10; + + // 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; + } + + // 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; + + // 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_RTK_WIDI ); + wpsielen += 2; + + // OUI + *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI ); + wpsielen += 4; + + // Sub Category ID + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP ); + wpsielen += 2; + + // 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: + *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110221 + // According to the P2P Specification, the probe request frame should contain 5 P2P attributes + // 1. P2P Capability + // 2. P2P Device ID if this probe request wants to find the specific P2P device + // 3. Listen Channel + // 4. Extended Listen Timing + // 5. Operating Channel if this WiFi is working as the group owner now + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + // Listen Channel + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_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->listen_channel; // listen channel + + + // Extended Listen Timing + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) ) + { + // Operating Channel (if this WiFi is working as the group owner now) + // 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 + + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + + } + +#ifdef CONFIG_WFD + wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz)); + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +inline void issue_probereq_p2p(_adapter *adapter, u8 *da) +{ + _issue_probereq_p2p(adapter, da, _FALSE); +} + +/* + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + */ +int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + + do + { + ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE); + + i++; + + if (RTW_CANNOT_RUN(adapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((iu.hdr.adapter; + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + u8 *frame = rframe->u.hdr.rx_data; + u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num&0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf); + u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset); + + if (GetRetry(frame)) { + if ((seq_ctrl == mlmeext->action_public_rxseq) + && (token == mlmeext->action_public_dialog_token) + ) { + DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n", + FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token); + return _FAIL; + } + } + + /* TODO: per sta seq & token */ + mlmeext->action_public_rxseq = seq_ctrl; + mlmeext->action_public_dialog_token = token; + + return _SUCCESS; +} + +unsigned int on_action_public_p2p(union recv_frame *precv_frame) +{ + _adapter *padapter = precv_frame->u.hdr.adapter; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + u8 *frame_body; +#ifdef CONFIG_P2P + u8 *p2p_ie; + u32 p2p_ielen, wps_ielen; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 result = P2P_STATUS_SUCCESS; + u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u8 *merged_p2pie = NULL; + u32 merged_p2p_ielen= 0; +#endif //CONFIG_P2P + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + +#ifdef CONFIG_P2P + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) + { + rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len); + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + // Do nothing if the driver doesn't enable the P2P function. + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + return _SUCCESS; + + len -= sizeof(struct rtw_ieee80211_hdr_3addr); + + switch( frame_body[ 6 ] )//OUI Subtype + { + case P2P_GO_NEGO_REQ: + { + DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) + { + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + } + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + // Commented by Albert 20110526 + // In this case, this means the previous nego fail doesn't be reset yet. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + // Restore the previous p2p state + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + } +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Kurt 20110902 + //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + + // Commented by Kurt 20120113 + // Get peer_dev_addr here if peer doesn't issue prov_disc frame. + if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) ) + _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); + + result = process_p2p_group_negotation_req( pwdinfo, frame_body, len ); + issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result ); +#ifdef CONFIG_INTEL_WIDI + if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0); + } +#endif //CONFIG_INTEL_WIDI + + // Commented by Albert 20110718 + // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. +#ifdef CONFIG_CONCURRENT_MODE + // Commented by Albert 20120107 + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); +#else // CONFIG_CONCURRENT_MODE + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); +#endif // CONFIG_CONCURRENT_MODE + break; + } + case P2P_GO_NEGO_RESP: + { + DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + // Commented by Albert 20110425 + // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + pwdinfo->nego_req_info.benable = _FALSE; + result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len); + issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result); + if ( P2P_STATUS_SUCCESS == result ) + { + if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT ) + { + pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch; + #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1; + pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6; + pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11; + #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH ); + } + } + + // Reset the dialog token for group negotiation frames. + pwdinfo->negotiation_dialog_token = 1; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); + } + } + else + { + DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__); + } + + break; + } + case P2P_GO_NEGO_CONF: + { + DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__); + result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len); + if ( P2P_STATUS_SUCCESS == result ) + { + if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT ) + { + pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch; + #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1; + pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6; + pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11; + #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH ); + } + } + break; + } + case P2P_INVIT_REQ: + { + // Added by Albert 2010/10/05 + // Received the P2P Invite Request frame. + + DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ ); + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + // Parse the necessary information from the P2P Invitation Request frame. + // For example: The MAC address of sending this P2P Invitation Request frame. + u32 attr_contentlen = 0; + u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + struct group_id_info group_id; + u8 invitation_flag = 0; + int j=0; + + merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_); + + merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); // 2 is for EID and Length + if (merged_p2pie == NULL) + { + DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__); + goto exit; + } + _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen); + + merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie); + + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen); + if ( attr_contentlen ) + { + + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen); + // Commented by Albert 20120510 + // Copy to the pwdinfo->p2p_peer_interface_addr. + // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. + // #> iwpriv wlan0 p2p_get peer_ifa + // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. + + if ( attr_contentlen ) + { + DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__, + pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], + pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3], + pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] ); + } + + if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT ) + { + // Re-invoke the persistent group. + + _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) ); + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen); + if ( attr_contentlen ) + { + if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) + { + // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO ); + status_code = P2P_STATUS_SUCCESS; + } + else + { + // The p2p device sending this p2p invitation request wants to be the persistent GO. + if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) ) + { + u8 operatingch_info[5] = { 0x00 }; + if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 ) + { + // The operating channel is acceptable for this device. + pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4]; + #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1; + pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6; + pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11; + #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 1; + _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + status_code = P2P_STATUS_SUCCESS; + } + else + { + // The operating channel isn't supported by this device. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE ); + status_code = P2P_STATUS_FAIL_NO_COMMON_CH; + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); + } + } + else + { + // Commented by Albert 20121130 + // Intel will use the different P2P IE to store the operating channel information + // Workaround for Intel WiDi 3.5 + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + status_code = P2P_STATUS_SUCCESS; + } + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + #ifdef CONFIG_INTEL_WIDI + _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + #endif //CONFIG_INTEL_WIDI + + status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; + } + } + } + else + { + DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + } + else + { + // Received the invitation to join a P2P group. + + _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) ); + rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen); + if ( attr_contentlen ) + { + if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) + { + // In this case, the GO can't be myself. + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + else + { + // The p2p device sending this p2p invitation request wants to join an existing P2P group + // Commented by Albert 2012/06/28 + // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. + // The peer device address should be the destination address for the provisioning discovery request. + // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. + // The peer interface address should be the address for WPS mac address + _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN ); + rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN ); + status_code = P2P_STATUS_SUCCESS; + } + } + else + { + DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + } + } + else + { + DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + + DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code ); + + pwdinfo->inviteresp_info.token = frame_body[ 7 ]; + issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code ); + _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 ); + } +#ifdef CONFIG_INTEL_WIDI + if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0); + } +#endif //CONFIG_INTEL_WIDI + break; + } + case P2P_INVIT_RESP: + { + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + + DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + pwdinfo->invitereq_info.benable = _FALSE; + + if ( attr_content == P2P_STATUS_SUCCESS ) + { + if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN)) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO ); + else + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK ); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ); + } + + if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 ); + } + break; + } + case P2P_DEVDISC_REQ: + + process_p2p_devdisc_req(pwdinfo, pframe, len); + + break; + + case P2P_DEVDISC_RESP: + + process_p2p_devdisc_resp(pwdinfo, pframe, len); + + break; + + case P2P_PROVISION_DISC_REQ: + DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ ); + process_p2p_provdisc_req(pwdinfo, pframe, len); + _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN); + + //20110902 Kurt + //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ)) + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ); + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); +#ifdef CONFIG_INTEL_WIDI + if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) { + padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION; + _cancel_timer_ex(&(padapter->mlmepriv.listen_timer)); + intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0); + } +#endif //CONFIG_INTEL_WIDI + break; + + case P2P_PROVISION_DISC_RESP: + // Commented by Albert 20110707 + // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? + DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ ); + // Commented by Albert 20110426 + // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP); + process_p2p_provdisc_resp(pwdinfo, pframe); + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); + break; + + } + } + + +exit: + + if(merged_p2pie) + { + rtw_mfree(merged_p2pie, merged_p2p_ielen + 2); + } +#endif //CONFIG_P2P + return _SUCCESS; +} + +unsigned int on_action_public_vendor(union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + + if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) { + if (rtw_action_public_decache(precv_frame, 7) == _FAIL) + goto exit; + + if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST)) + rtw_rframe_del_wfd_ie(precv_frame, 8); + + ret = on_action_public_p2p(precv_frame); + } + +exit: + return ret; +} + +unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 token; + _adapter *adapter = precv_frame->u.hdr.adapter; + int cnt = 0; + char msg[64]; + + token = frame_body[2]; + + if (rtw_action_public_decache(precv_frame, 2) == _FAIL) + goto exit; + + #ifdef CONFIG_IOCTL_CFG80211 + cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token); + rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg); + #endif + + ret = _SUCCESS; + +exit: + return ret; +} + +unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame) +{ + unsigned int ret = _FAIL; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 category, action; + + /* check RA matches or not */ + if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + goto exit; + + category = frame_body[0]; + if (category != RTW_WLAN_CATEGORY_PUBLIC) + goto exit; + + action = frame_body[1]; + switch (action) { + case ACT_PUBLIC_BSSCOEXIST: +#ifdef CONFIG_80211N_HT +#ifdef CONFIG_AP_MODE + /*20/40 BSS Coexistence Management frame is a Public Action frame*/ + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_process_public_act_bsscoex(padapter, pframe, frame_len); +#endif /*CONFIG_AP_MODE*/ +#endif /*CONFIG_80211N_HT*/ + break; + case ACT_PUBLIC_VENDOR: + ret = on_action_public_vendor(precv_frame); + break; + default: + ret = on_action_public_default(precv_frame, action); + break; + } + +exit: + return ret; +} + +unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 category, action; + + /* check RA matches or not */ + if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + goto exit; + + category = frame_body[0]; + if (category != RTW_WLAN_CATEGORY_HT) + goto exit; + + action = frame_body[1]; + switch (action) { + case RTW_WLAN_ACTION_HT_SM_PS: +#ifdef CONFIG_80211N_HT +#ifdef CONFIG_AP_MODE + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) + rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]); +#endif /*CONFIG_AP_MODE*/ +#endif /*CONFIG_80211N_HT*/ + break; + case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING: +#ifdef CONFIG_BEAMFORMING + /*DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/ + beamforming_get_report_frame(padapter, precv_frame); +#endif /*CONFIG_BEAMFORMING*/ + break; + default: + break; + } + +exit: + + return _SUCCESS; +} + +#ifdef CONFIG_IEEE80211W +unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *pframe = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u16 tid; + //Baron + + DBG_871X("OnAction_sa_query\n"); + + switch (pframe[WLAN_HDR_A3_LEN+1]) + { + case 0: //SA Query req + _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16)); + DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n" + , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]); + issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY); + break; + + case 1: //SA Query rsp + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (psta != NULL) + _cancel_timer_ex(&psta->dot11w_expire_timer); + + _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16)); + DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid); + break; + default: + break; + } + if(0) + { + int pp; + printk("pattrib->pktlen = %d =>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", pframe[pp]); + printk("\n"); + } + + return _SUCCESS; +} +#endif //CONFIG_IEEE80211W + +unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame) +{ + return _SUCCESS; +} + +unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_80211AC_VHT + struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint frame_len = precv_frame->u.hdr.len; + struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe; + u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 category, action; + struct sta_info *psta = NULL; + + /* check RA matches or not */ + if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + goto exit; + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_VHT) + goto exit; + + action = frame_body[1]; + switch (action) { + case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING: +#ifdef CONFIG_BEAMFORMING + /*DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/ + beamforming_get_report_frame(padapter, precv_frame); +#endif /*CONFIG_BEAMFORMING*/ + break; + case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION: + // CategoryCode(1) + ActionCode(1) + OpModeNotification(1) + //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n"); + psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2); + if (psta) + rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta); + break; + default: + break; + } + +exit: +#endif //CONFIG_80211AC_VHT + + return _SUCCESS; +} + +unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_P2P + u8 *frame_body; + u8 category, OUI_Subtype, dialogToken=0; + u8 *pframe = precv_frame->u.hdr.rx_data; + uint len = precv_frame->u.hdr.len; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + //check RA matches or not + if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN)) + return _SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + if(category != RTW_WLAN_CATEGORY_P2P) + return _SUCCESS; + + if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI ) + return _SUCCESS; + +#ifdef CONFIG_IOCTL_CFG80211 + if (adapter_wdev_data(padapter)->p2p_enabled + && pwdinfo->driver_interface == DRIVER_CFG80211 + ) { + rtw_cfg80211_rx_action_p2p(padapter, pframe, len); + return _SUCCESS; + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + len -= sizeof(struct rtw_ieee80211_hdr_3addr); + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + + switch(OUI_Subtype) + { + case P2P_NOTICE_OF_ABSENCE: + + break; + + case P2P_PRESENCE_REQUEST: + + process_p2p_presence_req(pwdinfo, pframe, len); + + break; + + case P2P_PRESENCE_RESPONSE: + + break; + + case P2P_GO_DISC_REQUEST: + + break; + + default: + break; + + } + } +#endif //CONFIG_P2P + + return _SUCCESS; + +} + +unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame) +{ + int i; + unsigned char category; + struct action_handler *ptable; + unsigned char *frame_body; + u8 *pframe = precv_frame->u.hdr.rx_data; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + category = frame_body[0]; + + for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++) + { + ptable = &OnAction_tbl[i]; + + if(category == ptable->num) + ptable->func(padapter, precv_frame); + + } + + return _SUCCESS; + +} + +unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame) +{ + + //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); + return _SUCCESS; +} + +struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once) +{ + struct xmit_frame *pmgntframe; + struct xmit_buf *pxmitbuf; + + if (once) + pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv); + else + pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once); + goto exit; + } + + if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) { + DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter)); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pmgntframe = NULL; + goto exit; + } + + pmgntframe->frame_tag = MGNT_FRAMETAG; + pmgntframe->pxmitbuf = pxmitbuf; + pmgntframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pmgntframe; + +exit: + return pmgntframe; + +} + +inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) +{ + return _alloc_mgtxmitframe(pxmitpriv, _FALSE); +} + +inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv) +{ + return _alloc_mgtxmitframe(pxmitpriv, _TRUE); +} + + +/**************************************************************************** + +Following are some TX fuctions for WiFi MLME + +*****************************************************************************/ + +void update_mgnt_tx_rate(_adapter *padapter, u8 rate) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + pmlmeext->tx_rate = rate; + //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate); +} + + +void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 wireless_mode; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *pbcmc_sta = NULL; + + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + pbcmc_sta = rtw_get_bcmc_stainfo(padapter); + + pattrib->hdrlen = 24; + pattrib->nr_frags = 1; + pattrib->priority = 7; + + if (pbcmc_sta) + pattrib->mac_id = pbcmc_sta->mac_id; + else { + pattrib->mac_id = 0; + DBG_871X("mgmt use mac_id 0 will affect RA\n"); + } + pattrib->qsel = QSLT_MGNT; + + pattrib->pktlen = 0; + + if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB) + wireless_mode = WIRELESS_11B; + else + wireless_mode = WIRELESS_11G; + + pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode); + #ifdef CONFIG_80211AC_VHT + if (pHalData->rf_type == RF_1T1R) + pattrib->raid = RATEID_IDX_VHT_1SS; + else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R) + pattrib->raid = RATEID_IDX_VHT_2SS; + else if (pHalData->rf_type == RF_3T3R) + pattrib->raid = RATEID_IDX_VHT_3SS; + else + pattrib->raid = RATEID_IDX_BGN_40M_1SS; + #endif + + #ifdef CONFIG_80211AC_VHT + pattrib->rate = MGN_VHT1SS_MCS9; + #else + pattrib->rate = MGN_MCS7; + #endif + + pattrib->encrypt = _NO_PRIVACY_; + pattrib->bswenc = _FALSE; + + pattrib->qos_en = _FALSE; + pattrib->ht_en = 1; + pattrib->bwmode = CHANNEL_WIDTH_20; + pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pattrib->sgi = _FALSE; + + pattrib->seqnum = pmlmeext->mgnt_seq; + + pattrib->retry_ctrl = _TRUE; + + pattrib->mbssid = 0; + pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; + +} + + +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; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *pbcmc_sta = NULL; + //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); + + pbcmc_sta = rtw_get_bcmc_stainfo(padapter); + + pattrib->hdrlen = 24; + pattrib->nr_frags = 1; + pattrib->priority = 7; + + if (pbcmc_sta) + pattrib->mac_id = pbcmc_sta->mac_id; + else { + pattrib->mac_id = 0; + DBG_871X("mgmt use mac_id 0 will affect RA\n"); + } + pattrib->qsel = QSLT_MGNT; + + pattrib->pktlen = 0; + + if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB) + wireless_mode = WIRELESS_11B; + else + wireless_mode = WIRELESS_11G; + pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode); + pattrib->rate = pmlmeext->tx_rate; + + pattrib->encrypt = _NO_PRIVACY_; + pattrib->bswenc = _FALSE; + + pattrib->qos_en = _FALSE; + pattrib->ht_en = _FALSE; + pattrib->bwmode = CHANNEL_WIDTH_20; + pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pattrib->sgi = _FALSE; + + pattrib->seqnum = pmlmeext->mgnt_seq; + + pattrib->retry_ctrl = _TRUE; + + pattrib->mbssid = 0; + pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no; + + #ifdef CONFIG_BEAMFORMING + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + if (psta) + update_attrib_txbf_info(padapter, pattrib, psta); + #endif + +} + +void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + u8 *pframe; + struct pkt_attrib *pattrib = &pmgntframe->attrib; + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN); +} + +void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + if (RTW_CANNOT_RUN(padapter)) { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return; + } + + rtw_hal_mgnt_xmit(padapter, pmgntframe); +} + +s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) +{ + s32 ret = _FAIL; + _irqL irqL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; + struct submit_ctx sctx; + + if (RTW_CANNOT_RUN(padapter)) { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return ret; + } + + rtw_sctx_init(&sctx, timeout_ms); + pxmitbuf->sctx = &sctx; + + ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); + + if (ret == _SUCCESS) + ret = rtw_sctx_wait(&sctx, __func__); + + _enter_critical(&pxmitpriv->lock_sctx, &irqL); + pxmitbuf->sctx = NULL; + _exit_critical(&pxmitpriv->lock_sctx, &irqL); + + return ret; +} + +s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe) +{ +#ifdef CONFIG_XMIT_ACK + static u8 seq_no = 0; + s32 ret = _FAIL; + u32 timeout_ms = 500;// 500ms + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + #ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter && !padapter->isprimary) + pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv); + #endif + + if (RTW_CANNOT_RUN(padapter)) { + rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); + return -1; + } + + _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); + pxmitpriv->ack_tx = _TRUE; + pxmitpriv->seq_no = seq_no++; + pmgntframe->ack_report = 1; + rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms); + if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { +#ifdef CONFIG_XMIT_ACK_POLLING + ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms); +#else + ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__); +#endif + } + + pxmitpriv->ack_tx = _FALSE; + _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL); + + return ret; +#else //!CONFIG_XMIT_ACK + dump_mgntframe(padapter, pmgntframe); + rtw_msleep_os(50); + return _SUCCESS; +#endif //!CONFIG_XMIT_ACK +} + +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; +} + +void issue_beacon(_adapter *padapter, int timeout_ms) +{ + 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); +#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_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 + + + //DBG_871X("%s\n", __FUNCTION__); + +#ifdef CONFIG_BCN_ICF + if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL) +#else + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) +#endif + { + DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__); + return; + } +#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) + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->qsel = QSLT_BEACON; + #ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type == IFACE_PORT1) + pattrib->mbssid = 1; + #endif + + _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, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), 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); + pattrib->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(adapter_wdev_data(padapter)->p2p_enabled && 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; + pattrib->pktlen += wps_offset; + + _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len); + pframe += pmlmepriv->wps_beacon_ie_len; + pattrib->pktlen += pmlmepriv->wps_beacon_ie_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->pktlen += remainder_ielen; + } + else + { + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pattrib->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); + pattrib->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; + pattrib->pktlen += insert_len; + + //copy remainder_ie to pframe + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->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); + pattrib->pktlen += (cur_network->IELength+len_diff); + } + + { + 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); + } + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + u32 len; +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && 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; + pattrib->pktlen += len; + + #ifdef CONFIG_WFD + len = rtw_append_beacon_wfd_ie(padapter, pframe); + pframe += len; + pattrib->pktlen += len; + #endif + } +#endif //CONFIG_P2P + + goto _issue_bcn; + + } + + //below for ad-hoc mode + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // capability info: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->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), &pattrib->pktlen); + + //ERP IE + pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); + } + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->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) + + if ((pattrib->pktlen + TXDESC_SIZE) > 512) + { + DBG_871X("beacon frame too large\n"); + return; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz); + if(timeout_ms > 0) + dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms); + else + dump_mgntframe(padapter, pmgntframe); + +} + +void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned char *mac, *bssid; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + u8 *pwps_ie; + uint wps_ielen; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + unsigned int rate_len; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif +#endif //CONFIG_P2P + + //DBG_871X("%s\n", __FUNCTION__); + + if(da == NULL) + return; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__); + return; + } + + + //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; + + mac = adapter_mac_addr(padapter); + bssid = cur_network->MacAddress; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = pattrib->hdrlen; + pframe += pattrib->hdrlen; + + + if(cur_network->IELength>MAX_IE_SZ) + return; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen); + + //inerset & update wps_probe_resp_ie + if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0)) + { + uint wps_offset, remainder_ielen; + u8 *premainder_ie; + + wps_offset = (uint)(pwps_ie - cur_network->IEs); + + premainder_ie = pwps_ie + wps_ielen; + + remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; + + _rtw_memcpy(pframe, cur_network->IEs, wps_offset); + pframe += wps_offset; + pattrib->pktlen += wps_offset; + + wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len + if((wps_offset+wps_ielen+2)<=MAX_IE_SZ) + { + _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2); + pframe += wps_ielen+2; + pattrib->pktlen += wps_ielen+2; + } + + if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ) + { + _rtw_memcpy(pframe, premainder_ie, remainder_ielen); + pframe += remainder_ielen; + pattrib->pktlen += remainder_ielen; + } + } + else + { + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pattrib->pktlen += cur_network->IELength; + } + + /* retrieve SSID IE from cur_network->Ssid */ + { + u8 *ssid_ie; + sint ssid_ielen; + sint ssid_ielen_diff; + u8 buf[MAX_IE_SZ]; + u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr); + + ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen, + (pframe-ies)-_FIXED_IE_LENGTH_); + + ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen; + + if (ssid_ie && cur_network->Ssid.SsidLength) { + uint remainder_ielen; + u8 *remainder_ie; + remainder_ie = ssid_ie+2; + remainder_ielen = (pframe-remainder_ie); + + if (remainder_ielen > MAX_IE_SZ) { + DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter)); + remainder_ielen = MAX_IE_SZ; + } + + _rtw_memcpy(buf, remainder_ie, remainder_ielen); + _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen); + *(ssid_ie+1) = cur_network->Ssid.SsidLength; + _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength); + + pframe += ssid_ielen_diff; + pattrib->pktlen += ssid_ielen_diff; + } + } + } + else +#endif + { + + //timestamp will be inserted by hardware + pframe += 8; + pattrib->pktlen += 8; + + // beacon interval: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + // capability info: 2 bytes + + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + pattrib->pktlen += 2; + + //below for ad-hoc mode + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->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, &pattrib->pktlen); + + // DS parameter set + pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->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), &pattrib->pktlen); + + //ERP IE + pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); + } + + + // EXTERNDED SUPPORTED RATE + if (rate_len > 8) + { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); + } + + + //todo:HT for adhoc + + } + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) + /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */ + && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec)) + { + u32 len; +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() + len = pmlmepriv->p2p_go_probe_resp_ie_len; + if(pmlmepriv->p2p_go_probe_resp_ie && len>0) + _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len); + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + len = build_probe_resp_p2p_ie(pwdinfo, pframe); + } + + pframe += len; + pattrib->pktlen += len; + + #ifdef CONFIG_WFD + len = rtw_append_probe_resp_wfd_ie(padapter, pframe); + pframe += len; + pattrib->pktlen += len; + #endif + } +#endif //CONFIG_P2P + + +#ifdef CONFIG_AUTO_AP_MODE +{ + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("(%s)\n", __FUNCTION__); + + //check rc station + psta = rtw_get_stainfo(pstapriv, da); + if (psta && psta->isrc && psta->pid>0) + { + u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A}; + u8 RC_INFO[14] = {0}; + //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] + u16 cu_ch = (u16)cur_network->Configuration.DSConfig; + + DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__, + psta->pid, MAC_ARG(psta->hwaddr), cu_ch); + + //append vendor specific ie + _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI)); + _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN); + _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2); + _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2); + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen); + } +} +#endif //CONFIG_AUTO_AP_MODE + + + pattrib->last_txcmdsz = pattrib->pktlen; + + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + 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}; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //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; + + mac = adapter_mac_addr(padapter); + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + if (da) + { + // unicast probe request frame + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN); + } + else + { + // broadcast probe request frame + _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, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_PROBEREQ); + + pframe += sizeof (struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); + + if(pssid) + pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); + else + pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen)); + + get_rate_set(padapter, bssrate, &bssrate_len); + + 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 + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + + if (ch) + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen); + + if (append_wps) { + //add wps_ie for wps2.0 + if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) + { + _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); + pframe += pmlmepriv->wps_probe_req_ie_len; + pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; + //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero + } + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz)); + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da) +{ + _issue_probereq(padapter, pssid, da, 0, 1, _FALSE); +} + +/* + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + */ +int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, + int try_cnt, int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + do + { + ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((ixmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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; + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_AUTH); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + + if(psta)// for AP mode + { +#ifdef CONFIG_NATIVEAP_MLME + + _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN); + + + // setting auth algo number + val16 = (u16)psta->authalg; + + if(status != _STATS_SUCCESSFUL_) + val16 = 0; + + if (val16) { + val16 = cpu_to_le16(val16); + use_shared_key = 1; + } + + pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting auth seq number + val16 =(u16)psta->auth_seq; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting status code... + val16 = status; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // added challenging text... + if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen)); + } +#endif + } + else + { + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); + + // setting auth algo number + val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key + if (val16) { + val16 = cpu_to_le16(val16); + use_shared_key = 1; + } + //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); + + //setting IV for auth seq #3 + if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); + val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); + val32 = cpu_to_le32(val32); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen)); + + pattrib->iv_len = 4; + } + + pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // setting auth seq number + val16 = pmlmeinfo->auth_seq; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen)); + + + // setting status code... + val16 = status; + val16 = cpu_to_le16(val16); + pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen)); + + // then checking to see if sending challenging text... + if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1)) + { + pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen)); + + SetPrivacy(fctrl); + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pattrib->encrypt = _WEP40_; + + pattrib->icv_len = 4; + + pattrib->pktlen += pattrib->icv_len; + + } + + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + rtw_wep_encrypt(padapter, (u8 *)pmgntframe); + DBG_871X("%s\n", __FUNCTION__); + dump_mgntframe(padapter, pmgntframe); + + return; +} + + +void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) +{ +#ifdef CONFIG_AP_MODE + struct xmit_frame *pmgntframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct pkt_attrib *pattrib; + unsigned char *pbuf, *pframe; + unsigned short val, ie_status; + unsigned short *fctrl; + 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); + WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network); + u8 *ie = pnetwork->IEs; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + +#endif //CONFIG_P2P + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); + _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) + SetFrameSubType(pwlanhdr, pkt_type); + else + return; + + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen += pattrib->hdrlen; + pframe += pattrib->hdrlen; + + //capability + val = *(unsigned short *)rtw_get_capability_from_ie(ie); + + pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen)); + + ie_status = cpu_to_le16(status); + pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen)); + + val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); + pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen)); + + if (pstat->bssratelen <= 8) + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen)); + } + else + { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen)); + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen)); + } + +#ifdef CONFIG_IEEE80211W + if (status == _STATS_REFUSED_TEMPORARILY_) { + u8 timeout_itvl[5]; + u32 timeout_interval = 3000; + /* Association Comeback time */ + timeout_itvl[0] = 0x03; + timeout_interval = cpu_to_le32(timeout_interval); + _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4); + pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } +#endif /* CONFIG_IEEE80211W */ + +#ifdef CONFIG_80211N_HT + if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) + { + uint ie_len=0; + + //FILL HT CAP INFO IE + //p = hostapd_eid_ht_capabilities_info(hapd, p); + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + + //FILL HT ADD INFO IE + //p = hostapd_eid_ht_operation(hapd, p); + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + + } +#endif + + /*adding EXT_CAPAB_IE */ + if (pmlmepriv->ext_capab_ie_len > 0) { + uint ie_len = 0; + + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if (pbuf && ie_len > 0) { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen += (ie_len+2); + } + } + +#ifdef CONFIG_80211AC_VHT + if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option) + && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP) + && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP)) + { + u32 ie_len=0; + + //FILL VHT CAP IE + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + + //FILL VHT OPERATION IE + pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); + if(pbuf && ie_len>0) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + } + } +#endif //CONFIG_80211AC_VHT + + //FILL WMM IE + if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) + { + uint ie_len=0; + unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + + for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2)) + { + pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); + if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6)) + { + _rtw_memcpy(pframe, pbuf, ie_len+2); + pframe += (ie_len+2); + pattrib->pktlen +=(ie_len+2); + + break; + } + + if ((pbuf == NULL) || (ie_len == 0)) + { + break; + } + } + + } + + + if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) + { + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen)); + } + + //add WPS IE ie for wps 2.0 + if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0) + { + _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); + + pframe += pmlmepriv->wps_assoc_resp_ie_len; + pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; + } + +#ifdef CONFIG_P2P + if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) { + u32 len; + + if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) { + len = 0; + if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) { + len = pmlmepriv->p2p_assoc_resp_ie_len; + _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len); + } + } else { + len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code); + } + pframe += len; + pattrib->pktlen += len; + } + + #ifdef CONFIG_WFD + if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { + wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + #endif + +#endif /* CONFIG_P2P */ + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +#endif +} + +void issue_assocreq(_adapter *padapter) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe, *p; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned short val16; + unsigned int i, j, ie_len, index=0; + unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates]; + PNDIS_802_11_VARIABLE_IEs pIE; + struct registry_priv *pregpriv = &padapter->registrypriv; + 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, sta_bssrate_len = 0; + u8 vs_ie_length = 0; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + u8 p2pie[ 255 ] = { 0x00 }; + u16 p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif +#endif //CONFIG_P2P + +#ifdef CONFIG_DFS + u16 cap; + + /* Dot H */ + u8 pow_cap_ele[2] = { 0x00 }; + u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel +#endif //CONFIG_DFS + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + //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, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_ASSOCREQ); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + //caps + +#ifdef CONFIG_DFS + _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + cap |= cap_SpecMgmt; + _rtw_memcpy(pframe, &cap, 2); +#else + _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); +#endif //CONFIG_DFS + + pframe += 2; + pattrib->pktlen += 2; + + //listen interval + //todo: listen interval for power saving + val16 = cpu_to_le16(3); + _rtw_memcpy(pframe ,(unsigned char *)&val16, 2); + pframe += 2; + pattrib->pktlen += 2; + + //SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen)); + +#ifdef CONFIG_DFS + /* Dot H */ + if(pmlmeext->cur_channel > 14) + { + pow_cap_ele[0] = 13; // Minimum transmit power capability + pow_cap_ele[1] = 21; // Maximum transmit power capability + pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen)); + + //supported channels + do{ + if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 ) + { + sup_ch[0] = 1; //First channel number + sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel + } + else + { + sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; + sup_ch[idx_5g++] = 1; + } + sup_ch_idx++; + } + while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 ); + pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen)); + } +#endif //CONFIG_DFS + + //supported rate & extended supported rate + +#if 1 // Check if the AP's supported rates are also supported by STA. + get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); + //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len); + + if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK) + { + sta_bssrate_len = 4; + } + + + //for (i = 0; i < sta_bssrate_len; i++) { + // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); + //} + + for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { + if (pmlmeinfo->network.SupportedRates[i] == 0) break; + DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]); + } + + + for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { + if (pmlmeinfo->network.SupportedRates[i] == 0) break; + + + // Check if the AP's supported rates are also supported by STA. + for (j=0; j < sta_bssrate_len; j++) { + // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP + if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK) + == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) { + //DBG_871X("match i = %d, j=%d\n", i, j); + break; + } else { + //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); + } + } + + if (j == sta_bssrate_len) { + // the rate is not supported by STA + DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]); + } else { + // the rate is supported by STA + bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; + } + } + + bssrate_len = index; + DBG_871X("bssrate_len = %d\n", bssrate_len); + +#else // Check if the AP's supported rates are also supported by STA. +#if 0 + get_rate_set(padapter, bssrate, &bssrate_len); +#else + for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) { + if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break; + + if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP + break; + + bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len]; + } +#endif +#endif // Check if the AP's supported rates are also supported by STA. + + 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) + { + 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 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 + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) || + (_rtw_memcmp(pIE->data, WMM_OUI, 4)) || + (_rtw_memcmp(pIE->data, WPS_OUI, 4))) + { + vs_ie_length = pIE->Length; + if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4))) + { + //Commented by Kurt 20110629 + //In some older APs, WPS handshake + //would be fail if we append vender extensions informations to AP + + vs_ie_length = 14; + } + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen)); + } + break; + + case EID_WPA2: + pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen)); + break; +#ifdef CONFIG_80211N_HT + case EID_HTCapability: + if(padapter->mlmepriv.htpriv.ht_option==_TRUE) { + if (!(is_ap_in_tkip(padapter))) + { + _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element)); + + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info); + + pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen)); + } + } + break; + + case EID_EXTCapability: + if(padapter->mlmepriv.htpriv.ht_option==_TRUE) { + pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen)); + } + break; +#endif //CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT + case EID_VHTCapability: + if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) { + pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen)); + } + break; + + case EID_OpModeNotification: + if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) { + pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen)); + } + break; +#endif // CONFIG_80211AC_VHT + default: + break; + } + + i += (pIE->Length + 2); + } + + if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) + { + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen)); + } + + +#ifdef CONFIG_WAPI_SUPPORT + rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib); +#endif + + +#ifdef CONFIG_P2P + +#ifdef CONFIG_IOCTL_CFG80211 + if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0) + { + _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len); + pframe += pmlmepriv->p2p_assoc_req_ie_len; + pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len; + } + } + else +#endif //CONFIG_IOCTL_CFG80211 + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + // Should add the P2P IE in the association request frame. + // P2P OUI + + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20101109 + // According to the P2P Specification, the association request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Extended Listen Timing + // 3. Device Info + // Commented by Albert 20110516 + // 4. P2P Interface + + // P2P Capability + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + // Extended Listen Timing + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + p2pielen += 2; + + // Value: + // Availability Period + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // Availability Interval + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + p2pielen += 2; + + // 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, adapter_mac_addr(padapter), ETH_ALEN); + p2pielen += ETH_ALEN; + + // Config Method + // This field should be big endian. Noted by P2P specification. + if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) || + ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) ) + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); + } + else + { + *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC ); + } + + 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; + + // P2P Interface + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE; + + // Length: + *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D ); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address + p2pielen += ETH_ALEN; + + p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count + + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List + p2pielen += ETH_ALEN; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen ); + } + } + +#endif //CONFIG_P2P + +#ifdef CONFIG_WFD + wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + dump_mgntframe(padapter, pmgntframe); + + ret = _SUCCESS; + +exit: + if (ret == _SUCCESS) + rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); + else + rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); + + return; +} + +//when wait_ack is ture, this function shoule be called at process context +static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct xmit_priv *pxmitpriv; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + + //DBG_871X("%s:%d\n", __FUNCTION__, power_mode); + + if(!padapter) + goto exit; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + pxmitpriv = &(padapter->xmitpriv); + pmlmeext = &(padapter->mlmeextpriv); + pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _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; + + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + SetFrDs(fctrl); + } + else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + SetToDs(fctrl); + } + + if (power_mode) + { + SetPwrMgt(fctrl); + } + + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if(wait_ack) + { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } + else + { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +/* + * [IMPORTANT] Don't call this function in interrupt context + * + * When wait_ms > 0, this function should be called at process context + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + * da == NULL for station mode + */ +int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_info *psta; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + /* da == NULL, assum it's null data for sta to ap*/ + if (da == NULL) + da = get_my_bssid(&(pmlmeinfo->network)); + + psta = rtw_get_stainfo(&padapter->stapriv, da); + if (psta) { + if (power_mode) + rtw_hal_macid_sleep(padapter, psta->mac_id); + else + rtw_hal_macid_wakeup(padapter, psta->mac_id); + } else { + DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n", + FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup"); + rtw_warn_on(1); + } + + do { + ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((imlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + /* da == NULL, assum it's null data for sta to ap*/ + if (da == NULL) + da = get_my_bssid(&(pmlmeinfo->network)); + + ret = _issue_nulldata(padapter, da, power_mode, _FALSE); + + return ret; +} + +//when wait_ack is ture, this function shoule be called at process context +static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl, *qc; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + + pattrib->hdrlen +=2; + pattrib->qos_en = _TRUE; + pattrib->eosp = 1; + pattrib->ack_policy = 0; + pattrib->mdata = 0; + + _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; + + if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + SetFrDs(fctrl); + } + else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + SetToDs(fctrl); + } + + if(pattrib->mdata) + SetMData(fctrl); + + qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); + + SetPriority(qc, tid); + + SetEOSP(qc, pattrib->eosp); + + SetAckpolicy(qc, pattrib->ack_policy); + + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if(wait_ack) + { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } + else + { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; +} + +/* + * when wait_ms >0 , this function should be called at process context + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + * da == NULL for station mode + */ +int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + /* da == NULL, assum it's null data for sta to ap*/ + if (da == NULL) + da = get_my_bssid(&(pmlmeinfo->network)); + + do + { + ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((ixmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int ret = _FAIL; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + +#ifdef CONFIG_P2P + if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) ) + { + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey ); + _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 ); + } +#endif //CONFIG_P2P + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + pattrib->key_type = key_type; + _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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_DEAUTH); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(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; + } + +exit: + return ret; +} + +int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason) +{ + DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY); +} + +#ifdef CONFIG_IEEE80211W +int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type) +{ + DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); + return _issue_deauth(padapter, da, reason, _FALSE, key_type); +} +#endif /* CONFIG_IEEE80211W */ + +/* + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + */ +int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt, + int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + do + { + ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((ixmitpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + return; + + //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, ra, ETH_ALEN); /* RA */ + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */ + _rtw_memcpy(pwlanhdr->addr3, ra, 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 */ + { + u8 category, action; + category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT; + action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH; + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + } + + pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0); + pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen), + hal_ch_offset_to_secondary_ch_offset(ch_offset)); + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +#ifdef CONFIG_IEEE80211W +void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type) +{ + u8 category = RTW_WLAN_CATEGORY_SA_QUERY; + u16 reason_code; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + DBG_871X("%s, %04x\n", __FUNCTION__, tid); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__); + return; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->key_type = key_type; + _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; + + if(raddr) + _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); + else + _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); + pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); + + switch (action) + { + case 0: //SA Query req + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen); + pmlmeext->sa_query_seq++; + /* send sa query request to AP, AP should reply sa query response in 1 second */ + if (pattrib->key_type == IEEE80211W_RIGHT_KEY) { + psta = rtw_get_stainfo(pstapriv, raddr); + if (psta != NULL) { + /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */ + _set_timer(&psta->dot11w_expire_timer, 1000); + } + } + break; + + case 1: //SA Query rsp + tid = cpu_to_le16(tid); + /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */ + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen); + break; + default: + break; + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); +} +#endif //CONFIG_IEEE80211W + +/** + * issue_action_ba - internal function to TX Block Ack action frame + * @padapter: the adapter to TX + * @raddr: receiver address + * @action: Block Ack Action + * @tid: tid + * @size: the announced AMPDU buffer size. used by ADDBA_RESP + * @status: status/reason code. used by ADDBA_RESP, DELBA + * @initiator: if we are the initiator of AMPDU association. used by DELBA + * @wait_ack: used xmit ack + * + * Returns: + * _SUCCESS: No xmit ack is used or acked + * _FAIL: not acked when using xmit ack + */ +static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action + , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack) +{ + int ret = _FAIL; + u8 category = RTW_WLAN_CATEGORY_BACK; + u16 start_seq; + u16 BA_para_set; + u16 BA_timeout_value; + u16 BA_starting_seqctrl; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + u8 *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + +#ifdef CONFIG_80211N_HT + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + //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, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + if (category == 3) + { + switch (action) + { + case RTW_WLAN_ACTION_ADDBA_REQ: + do { + pmlmeinfo->dialogToken++; + } while (pmlmeinfo->dialogToken == 0); + pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen)); + + #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI) + BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */ + #else + BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */ + #endif + + BA_para_set = cpu_to_le16(BA_para_set); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + + //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms) + BA_timeout_value = 5000;//~ 5ms + BA_timeout_value = cpu_to_le16(BA_timeout_value); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen)); + + //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) + if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL) + { + start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1; + + DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07); + + psta->BA_starting_seqctrl[tid & 0x07] = start_seq; + + BA_starting_seqctrl = start_seq << 4; + } + + BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen)); + break; + + case RTW_WLAN_ACTION_ADDBA_RESP: + pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen)); + status = cpu_to_le16(status); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen)); + + BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set); + + BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK; + BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK; + + BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; + BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; + + if (!padapter->registrypriv.wifi_spec) { + if(pregpriv->ampdu_amsdu==0)//disabled + BA_para_set &= ~BIT(0); + else if(pregpriv->ampdu_amsdu==1)//enabled + BA_para_set |= BIT(0); + } + + BA_para_set = cpu_to_le16(BA_para_set); + + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen)); + break; + + case RTW_WLAN_ACTION_DELBA: + BA_para_set = 0; + BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK; + BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK; + + BA_para_set = cpu_to_le16(BA_para_set); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen)); + status = cpu_to_le16(status); + pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen)); + break; + default: + break; + } + } + + pattrib->last_txcmdsz = pattrib->pktlen; + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: +#endif //CONFIG_80211N_HT + return ret; +} + +/** + * issue_addba_req - TX ADDBA_REQ + * @adapter: the adapter to TX + * @ra: receiver address + * @tid: tid + */ +inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid) +{ + issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ + , tid + , 0 /* unused */ + , 0 /* unused */ + , 0 /* unused */ + , _FALSE + ); + DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid); + +} + +/** + * issue_addba_rsp - TX ADDBA_RESP + * @adapter: the adapter to TX + * @ra: receiver address + * @tid: tid + * @status: status code + * @size: the announced AMPDU buffer size + */ +inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size) +{ + issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP + , tid + , size + , status + , 0 /* unused */ + , _FALSE + ); + DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size); +} + +/** + * issue_del_ba - TX DELBA + * @adapter: the adapter to TX + * @ra: receiver address + * @tid: tid + * @reason: reason code + * @initiator: if we are the initiator of AMPDU association. used by DELBA + */ +inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator) +{ + issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA + , tid + , 0 /* unused */ + , reason + , initiator + , _FALSE + ); + DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator); +} + +/** + * issue_del_ba_ex - TX DELBA with xmit ack options + * @adapter: the adapter to TX + * @ra: receiver address + * @tid: tid + * @reason: reason code + * @initiator: if we are the initiator of AMPDU association. used by DELBA + * @try_cnt: the maximal TX count to try + * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + */ +int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator + , int try_cnt, int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter))) + goto exit; + + do { + ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA + , tid + , 0 /* unused */ + , reason + , initiator + , wait_ms > 0?_TRUE:_FALSE + ); + + i++; + + if (RTW_CANNOT_RUN(adapter)) + break; + + if (i < try_cnt && wait_ms > 0 && ret == _FAIL) + rtw_msleep_os(wait_ms); + + } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); + + if (ret != _FAIL) { + ret = _SUCCESS; + #ifndef DBG_XMIT_ACK + /* goto exit; */ + #endif + } + + if (try_cnt && wait_ms) { + DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator + , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start)); + } +exit: + return ret; +} + +static void issue_action_BSSCoexistPacket(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + unsigned char category, action; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + struct wlan_network *pnetwork = NULL; + 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); + _queue *queue = &(pmlmepriv->scanned_queue); + u8 InfoContent[16] = {0}; + u8 ICS[8][15]; +#ifdef CONFIG_80211N_HT + if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0)) + return; + + if(_TRUE == pmlmeinfo->bwmode_updated) + return; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + return; + + DBG_871X("%s\n", __FUNCTION__); + + + category = RTW_WLAN_CATEGORY_PUBLIC; + action = ACT_PUBLIC_BSSCOEXIST; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + 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); + + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); + + + // + if(pmlmepriv->num_FortyMHzIntolerant>0) + { + u8 iedata=0; + + iedata |= BIT(2);//20 MHz BSS Width Request + + pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); + + } + + + // + _rtw_memset(ICS, 0, sizeof(ICS)); + if(pmlmepriv->num_sta_no_ht>0) + { + int i; + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + int len; + u8 *p; + WLAN_BSSID_EX *pbss_network; + + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + plist = get_next(plist); + + pbss_network = (WLAN_BSSID_EX *)&pnetwork->network; + + p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); + if((p==NULL) || (len==0))//non-HT + { + if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14)) + continue; + + ICS[0][pbss_network->Configuration.DSConfig]=1; + + if(ICS[0][0] == 0) + ICS[0][0] = 1; + } + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + + for(i= 0;i<8;i++) + { + if(ICS[i][0] == 1) + { + int j, k = 0; + + InfoContent[k] = i; + //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); + k++; + + for(j=1;j<=14;j++) + { + if(ICS[i][j]==1) + { + if(k<16) + { + InfoContent[k] = j; //channel number + //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); + k++; + } + } + } + + pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen)); + + } + + } + + + } + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); +#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 = _FAIL; + 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; + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + 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, adapter_mac_addr(padapter), 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; +} + +/* + * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + * try_cnt means the maximal TX count to try + */ +int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms) +{ + int ret = _FAIL; + int i = 0; + u32 start = rtw_get_current_time(); + + if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter))) + goto exit; + + do { + ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE ); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if(i < try_cnt && wait_ms > 0 && ret==_FAIL) + rtw_msleep_os(wait_ms); + + }while((irecvreorder_ctrl[tid].enable == _TRUE) { + u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size; + + sta->recvreorder_ctrl[tid].enable = _FALSE; + sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID; + + if (rtw_del_rx_ampdu_test_trigger_no_tx_fail()) + ret = _FAIL; + else if (wait_ack) + ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1); + else + issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator); + + if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE) + sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak; + } + } else if (initiator == 1) { + /* originator */ +#ifdef CONFIG_80211N_HT + if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) { + sta->htpriv.agg_enable_bitmap &= ~BIT(tid); + sta->htpriv.candidate_tid_bitmap &= ~BIT(tid); + issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator); + } +#endif + } + +exit: + return ret; +} + +inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid + , u8 force) +{ + return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0); +} + +inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid + , u8 force) +{ + return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1); +} + +unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u16 tid; + + if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) + if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) + return _SUCCESS; + + psta = rtw_get_stainfo(pstapriv, addr); + if(psta==NULL) + return _SUCCESS; + + #if 0 + DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR"); + if (initiator == 1) /* originator */ + DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); + #endif + + for (tid = 0; tid < TID_NUM; tid++) + send_delba_sta_tid(padapter, initiator, psta, tid, 0); + + return _SUCCESS; +} + +unsigned int send_beacon(_adapter *padapter) +{ + u8 bxmitok = _FALSE; + int issue=0; + int poll = 0; +#if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +#endif +//#ifdef CONFIG_CONCURRENT_MODE + //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + //_adapter *pbuddy_adapter = padapter->pbuddy_adapter; + //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); +//#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); + +#ifdef RTL8814AE_SW_BCN + if (pHalData->bCorrectBCN != 0) + DBG_871X("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__); + pHalData->bCorrectBCN = 1; +#endif + + return _SUCCESS; +#endif + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u32 start = rtw_get_current_time(); + + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + do{ + issue_beacon(padapter, 100); + issue++; + do { + rtw_yield_os(); + rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); + poll++; + } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter)); + + } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter)); + + if (RTW_CANNOT_RUN(padapter)) + return _FAIL; + + + if(_FALSE == bxmitok) + { + DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start)); + return _FAIL; + } + else + { + u32 passing_time = rtw_get_passing_time_ms(start); + + if(passing_time > 100 || issue > 3) + DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); + //else + // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); + + rtw_hal_fw_correct_bcn(padapter); + + return _SUCCESS; + } + +#endif + +} + +/**************************************************************************** + +Following are some utitity fuctions for WiFi MLME + +*****************************************************************************/ + +BOOLEAN IsLegal5GChannel( + IN PADAPTER Adapter, + IN u8 channel) +{ + + int i=0; + u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58, + 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122, + 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159, + 161,163,165}; + for(i=0;iu.hdr.rx_data; + u32 packet_len = precv_frame->u.hdr.len; + u8 ie_offset; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); + + if (len > MAX_IE_SZ) + { + //DBG_871X("IE too long for survey event\n"); + return _FAIL; + } + + _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX)); + + subtype = GetFrameSubType(pframe); + + if(subtype==WIFI_BEACON) { + bssid->Reserved[0] = 1; + ie_offset = _BEACON_IE_OFFSET_; + } else { + // FIXME : more type + if (subtype == WIFI_PROBERSP) { + ie_offset = _PROBERSP_IE_OFFSET_; + bssid->Reserved[0] = 3; + } + else if (subtype == WIFI_PROBEREQ) { + ie_offset = _PROBEREQ_IE_OFFSET_; + bssid->Reserved[0] = 2; + } + else { + bssid->Reserved[0] = 0; + ie_offset = _FIXED_IE_LENGTH_; + } + } + + bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len; + + //below is to copy the information element + bssid->IELength = len; + _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); + + //get the signal strength + //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index. + bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data + bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage + bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage +#ifdef CONFIG_ANTENNA_DIVERSITY + //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna)); + rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna); +#endif + + // checking SSID + if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL) + { + DBG_871X("marc: cannot find SSID for survey event\n"); + return _FAIL; + } + + if (*(p + 1)) + { + if (len > NDIS_802_11_LENGTH_SSID) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); + bssid->Ssid.SsidLength = *(p + 1); + } + else + { + bssid->Ssid.SsidLength = 0; + } + + _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); + + //checking rate info... + i = 0; + p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); + if (p != NULL) + { + if (len > NDIS_802_11_LENGTH_RATES_EX) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->SupportedRates, (p + 2), len); + i = len; + } + + p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); + if (p != NULL) + { + if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) + { + DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len); + return _FAIL; + } + _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len); + } + + //todo: +#if 0 + if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B) + { + bssid->NetworkTypeInUse = Ndis802_11DS; + } + else +#endif + { + bssid->NetworkTypeInUse = Ndis802_11OFDM24; + } + +#ifdef CONFIG_P2P + if (subtype == WIFI_PROBEREQ) + { + u8 *p2p_ie; + u32 p2p_ielen; + // Set Listion Channel + if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen))) + { + u32 attr_contentlen = 0; + u8 listen_ch[5] = { 0x00 }; + + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen); + bssid->Configuration.DSConfig = listen_ch[4]; + } else + { // use current channel + bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel; + DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig); + } + + // FIXME + bssid->InfrastructureMode = Ndis802_11Infrastructure; + _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); + bssid->Privacy = 1; + return _SUCCESS; + } +#endif //CONFIG_P2P + + if (bssid->IELength < 12) + return _FAIL; + + // Checking for DSConfig + p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset); + + bssid->Configuration.DSConfig = 0; + bssid->Configuration.Length = 0; + + if (p) + { + bssid->Configuration.DSConfig = *(p + 2); + } + else + {// In 5G, some ap do not have DSSET IE + // checking HT info for channel + p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset); + if(p) + { + struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); + bssid->Configuration.DSConfig = HT_info->primary_channel; + } + else + { // use current channel + bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); + } + } + + _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); + bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod); + + val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid); + + if (val16 & BIT(0)) + { + bssid->InfrastructureMode = Ndis802_11Infrastructure; + _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); + } + else + { + bssid->InfrastructureMode = Ndis802_11IBSS; + _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); + } + + if (val16 & BIT(4)) + bssid->Privacy = 1; + else + bssid->Privacy = 0; + + bssid->Configuration.ATIMWindow = 0; + + //20/40 BSS Coexistence check + if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated)) + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_80211N_HT + p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset); + if(p && len>0) + { + struct HT_caps_element *pHT_caps; + pHT_caps = (struct HT_caps_element *)(p + 2); + + if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14)) + { + pmlmepriv->num_FortyMHzIntolerant++; + } + } + else + { + pmlmepriv->num_sta_no_ht++; + } +#endif //CONFIG_80211N_HT + + } + +#ifdef CONFIG_INTEL_WIDI + //process_intel_widi_query_or_tigger(padapter, bssid); + if(process_intel_widi_query_or_tigger(padapter, bssid)) + { + return _FAIL; + } +#endif // CONFIG_INTEL_WIDI + + #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1 + if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { + DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n" + , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig + , rtw_get_oper_ch(padapter) + , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi + ); + } + #endif + + // mark bss info receving from nearby channel as SignalQuality 101 + if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) + { + bssid->PhyInfo.SignalQuality= 101; + } + + return _SUCCESS; +} + +void start_create_ibss(_adapter* padapter) +{ + unsigned short caps; + u8 val8; + u8 join_type; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + u8 doiqk = _FALSE; + pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; + pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); + + //update wireless mode + update_wireless_mode(padapter); + + //udpate capability + caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork); + update_capinfo(padapter, caps); + if(caps&cap_IBSS)//adhoc master + { + //set_opmode_cmd(padapter, adhoc);//removed + + val8 = 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + + //switch channel + //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); + set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + + beacon_timing_control(padapter); + + //set msr to WIFI_FW_ADHOC_STATE + pmlmeinfo->state = WIFI_FW_ADHOC_STATE; + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + + //issue beacon + if(send_beacon(padapter)==_FAIL) + { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n")); + + report_join_res(padapter, -1); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + } + else + { + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); + join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + + report_join_res(padapter, 1); + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + rtw_indicate_connect(padapter); + } + } + else + { + DBG_871X("start_create_ibss, invalid cap:%x\n", caps); + return; + } + //update bc/mc sta_info + update_bmc_sta(padapter); + +} + +void start_clnt_join(_adapter* padapter) +{ + unsigned short caps; + u8 val8; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + 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); + + //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); + + val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf; + +#ifdef CONFIG_WAPI_SUPPORT + if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) + { + //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. + val8 = 0x4c; + } +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + #ifdef CONFIG_DEAUTH_BEFORE_CONNECT + // Because of AP's not receiving deauth before + // AP may: 1)not response auth or 2)deauth us after link is complete + // issue deauth before issuing auth to deal with the situation + + // Commented by Albert 2012/07/21 + // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. + { + #ifdef CONFIG_P2P + _queue *queue = &(padapter->mlmepriv.scanned_queue); + _list *head = get_list_head(queue); + _list *pos = get_next(head); + struct wlan_network *scanned = NULL; + u8 ie_offset = 0; + _irqL irqL; + bool has_p2p_ie = _FALSE; + + _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL); + + for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) { + + scanned = LIST_CONTAINOR(pos, struct wlan_network, list); + + if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE + && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE + ) { + ie_offset = (scanned->network.Reserved[0] == 2? 0:12); + if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL)) + has_p2p_ie = _TRUE; + break; + } + } + + _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL); + + if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE) + #endif /* CONFIG_P2P */ + //To avoid connecting to AP fail during resume process, change retry count from 5 to 1 + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); + } + #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */ + + //here wait for receiving the beacon to start auth + //and enable a timer + beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval); + set_link_timer(pmlmeext, beacon_timeout); + _set_timer( &padapter->mlmepriv.assoc_timer, + (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout); + + pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; + } + else if (caps&cap_IBSS) //adhoc client + { + Set_MSR(padapter, WIFI_FW_ADHOC_STATE); + + val8 = 0xcf; + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + + beacon_timing_control(padapter); + + pmlmeinfo->state = WIFI_FW_ADHOC_STATE; + + report_join_res(padapter, 1); + } + else + { + //DBG_871X("marc: invalid cap:%x\n", caps); + return; + } + +} + +void start_clnt_auth(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + _cancel_timer_ex(&pmlmeext->link_timer); + + pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); + pmlmeinfo->state |= WIFI_FW_AUTH_STATE; + + pmlmeinfo->auth_seq = 1; + pmlmeinfo->reauth_count = 0; + pmlmeinfo->reassoc_count = 0; + pmlmeinfo->link_count = 0; + pmlmeext->retry = 0; + + + DBG_871X_LEVEL(_drv_always_, "start auth\n"); + issue_auth(padapter, NULL, 0); + + set_link_timer(pmlmeext, REAUTH_TO); + +} + + +void start_clnt_assoc(_adapter* padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + _cancel_timer_ex(&pmlmeext->link_timer); + + pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); + pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); + + issue_assocreq(padapter); + + set_link_timer(pmlmeext, REASSOC_TO); +} + +unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) + return _SUCCESS; + + DBG_871X("%s\n", __FUNCTION__); + + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_del_sta_event(padapter, MacAddr, reason, _TRUE); + + } + else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -2); + } else + DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter)); + } + + return _SUCCESS; +} + +#ifdef CONFIG_80211D +static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid) +{ + struct registry_priv *pregistrypriv; + struct mlme_ext_priv *pmlmeext; + RT_CHANNEL_INFO *chplan_new; + u8 channel; + u8 i; + + + pregistrypriv = &padapter->registrypriv; + pmlmeext = &padapter->mlmeextpriv; + + // Adjust channel plan by AP Country IE + if (pregistrypriv->enable80211d && + (!pmlmeext->update_channel_plan_by_ap_done)) + { + u8 *ie, *p; + u32 len; + RT_CHANNEL_PLAN chplan_ap; + RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM]; + u8 country[4]; + u8 fcn; // first channel number + u8 noc; // number of channel + u8 j, k; + + ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (!ie) return; + if (len < 6) return; + + ie += 2; + p = ie; + ie += len; + + _rtw_memset(country, 0, 4); + _rtw_memcpy(country, p, 3); + p += 3; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: 802.11d country=%s\n", __FUNCTION__, country)); + + i = 0; + while ((ie - p) >= 3) + { + fcn = *(p++); + noc = *(p++); + p++; + + for (j = 0; j < noc; j++) + { + if (fcn <= 14) channel = fcn + j; // 2.4 GHz + else channel = fcn + j*4; // 5 GHz + + chplan_ap.Channel[i++] = channel; + } + } + chplan_ap.Len = i; + +#ifdef CONFIG_DEBUG_RTL871X + i = 0; + DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid); + while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) + { + DBG_8192C("%02d,", chplan_ap.Channel[i]); + i++; + } + DBG_871X("}\n"); +#endif + + _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); +#ifdef CONFIG_DEBUG_RTL871X + i = 0; + DBG_871X("%s: STA channel plan {", __FUNCTION__); + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a'); + i++; + } + DBG_871X("}\n"); +#endif + + _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); + chplan_new = pmlmeext->channel_set; + + i = j = k = 0; + if (pregistrypriv->wireless_mode & WIRELESS_11G) + { + do { + if ((i == MAX_CHANNEL_NUM) || + (chplan_sta[i].ChannelNum == 0) || + (chplan_sta[i].ChannelNum > 14)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + i++; + j++; + k++; + } + else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } while (1); + + // change AP not support channel to Passive scan + while ((i < MAX_CHANNEL_NUM) && + (chplan_sta[i].ChannelNum != 0) && + (chplan_sta[i].ChannelNum <= 14)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + + // add channel AP supported + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } + else + { + // keep original STA 2.4G channel plan + while ((i < MAX_CHANNEL_NUM) && + (chplan_sta[i].ChannelNum != 0) && + (chplan_sta[i].ChannelNum <= 14)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + chplan_new[k].ScanType = chplan_sta[i].ScanType; + i++; + k++; + } + + // skip AP 2.4G channel plan + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) + { + j++; + } + } + + if (pregistrypriv->wireless_mode & WIRELESS_11A) + { + do { + if ((i >= MAX_CHANNEL_NUM) || + (chplan_sta[i].ChannelNum == 0)) + break; + + if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0)) + break; + + if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + i++; + j++; + k++; + } + else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } while (1); + + // change AP not support channel to Passive scan + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; +// chplan_new[k].ScanType = chplan_sta[i].ScanType; + chplan_new[k].ScanType = SCAN_PASSIVE; + i++; + k++; + } + + // add channel AP supported + while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) + { + chplan_new[k].ChannelNum = chplan_ap.Channel[j]; + chplan_new[k].ScanType = SCAN_ACTIVE; + j++; + k++; + } + } + else + { + // keep original STA 5G channel plan + while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) + { + chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; + chplan_new[k].ScanType = chplan_sta[i].ScanType; + i++; + k++; + } + } + + pmlmeext->update_channel_plan_by_ap_done = 1; + +#ifdef CONFIG_DEBUG_RTL871X + k = 0; + DBG_871X("%s: new STA channel plan {", __FUNCTION__); + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) + { + DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c'); + k++; + } + DBG_871X("}\n"); +#endif + +#if 0 + // recover the right channel index + channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; + k = 0; + while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) + { + if (chplan_new[k].ChannelNum == channel) { + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: change mlme_ext sitesurvey channel index from %d to %d\n", + __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k)); + pmlmeext->sitesurvey_res.channel_idx = k; + break; + } + k++; + } +#endif + } + + // If channel is used by AP, set channel scan type to active + channel = bssid->Configuration.DSConfig; + chplan_new = pmlmeext->channel_set; + i = 0; + while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) + { + if (chplan_new[i].ChannelNum == channel) + { + if (chplan_new[i].ScanType == SCAN_PASSIVE) + { + //5G Bnad 2, 3 (DFS) doesn't change to active scan + if(channel >= 52 && channel <= 144) + break; + + chplan_new[i].ScanType = SCAN_ACTIVE; + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, + ("%s: change channel %d scan type from passive to active\n", + __FUNCTION__, channel)); + } + break; + } + i++; + } +} +#endif + +/**************************************************************************** + +Following are the functions to report events + +*****************************************************************************/ + +void report_survey_event(_adapter *padapter, union recv_frame *precv_frame) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct survey_event *psurvey_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext; + struct cmd_priv *pcmdpriv; + //u8 *pframe = precv_frame->u.hdr.rx_data; + //uint len = precv_frame->u.hdr.len; + + if(!padapter) + return; + + pmlmeext = &padapter->mlmeextpriv; + pcmdpriv = &padapter->cmdpriv; + + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct survey_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + + if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + rtw_mfree((u8 *)pevtcmd, cmdsz); + return; + } + +#ifdef CONFIG_80211D + process_80211d(padapter, &psurvey_evt->bss); +#endif + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + pmlmeext->sitesurvey_res.bss_cnt++; + + return; + +} + +void report_surveydone_event(_adapter *padapter) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct surveydone_event *psurveydone_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct surveydone_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; + + DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter)); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; + +} + +void report_join_res(_adapter *padapter, int res) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct joinbss_event *pjoinbss_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct joinbss_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX)); + pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; + + DBG_871X("report_join_res(%d)\n", res); + + + rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); + + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; + +} + +void report_wmm_edca_update(_adapter *padapter) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct wmm_event *pwmm_event; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct wmm_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + pwmm_event->wmm =0; + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; + +} + +void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct sta_info *psta; + int mac_id = -1; + struct stadel_event *pdel_sta_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + + /* prepare cmd parameter */ + cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); + pevtcmd = (u8 *)rtw_zmalloc(cmdsz); + if (pevtcmd == NULL) { + res = _FAIL; + goto exit; + } + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct stadel_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); + _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2); + psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); + if(psta) + mac_id = (int)psta->mac_id; + else + mac_id = (-1); + pdel_sta_evt->mac_id = mac_id; + + if (!enqueue) { + /* do directly */ + rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt); + rtw_mfree(pevtcmd, cmdsz); + } else { + pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmd_obj == NULL) { + rtw_mfree(pevtcmd, cmdsz); + res = _FAIL; + goto exit; + } + + _rtw_init_listhead(&pcmd_obj->list); + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + } + +exit: + + DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res); + + return; +} + +void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct stassoc_event *padd_sta_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); + if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) + { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct stassoc_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN); + + DBG_871X("report_add_sta_event: add STA\n"); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; +} + + +bool rtw_port_switch_chk(_adapter *adapter) +{ + bool switch_needed = _FALSE; +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_RUNTIME_PORT_SWITCH + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj); + _adapter *if_port0 = NULL; + _adapter *if_port1 = NULL; + struct mlme_ext_info *if_port0_mlmeinfo = NULL; + struct mlme_ext_info *if_port1_mlmeinfo = NULL; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) { + if_port0 = dvobj->padapters[i]; + if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info); + } + else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) { + if_port1 = dvobj->padapters[i]; + if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info); + } + } + + if (if_port0 == NULL) { + rtw_warn_on(1); + goto exit; + } + + if (if_port1 == NULL) { + rtw_warn_on(1); + goto exit; + } + +#ifdef DBG_RUNTIME_PORT_SWITCH + DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n" + ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n" + ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n", + FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode, + ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE), + ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)); +#endif /* DBG_RUNTIME_PORT_SWITCH */ + +#ifdef CONFIG_WOWLAN + /* WOWLAN interface(primary, for now) should be port0 */ + if (pwrctl->wowlan_mode == _TRUE) { + if(!is_primary_adapter(if_port0)) { + DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1)); + switch_needed = _TRUE; + } + goto exit; + } +#endif /* CONFIG_WOWLAN */ + + /* AP should use port0 for ctl frame's ack */ + if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { + DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1)); + switch_needed = _TRUE; + goto exit; + } + + /* GC should use port0 for p2p ps */ + if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) + && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE) + && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS) + ) { + DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1)); + switch_needed = _TRUE; + goto exit; + } + + /* port1 linked, but port0 not linked */ + if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) + ) { + DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1)); + switch_needed = _TRUE; + goto exit; + } + +exit: +#ifdef DBG_RUNTIME_PORT_SWITCH + DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed); +#endif /* DBG_RUNTIME_PORT_SWITCH */ +#endif /* CONFIG_RUNTIME_PORT_SWITCH */ +#endif /* CONFIG_CONCURRENT_MODE */ + return switch_needed; +} + +/**************************************************************************** + +Following are the event callback functions + +*****************************************************************************/ + +//for sta/adhoc mode +void update_sta_info(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + //ERP + VCS_update(padapter, psta); + +#ifdef CONFIG_80211N_HT + //HT + if(pmlmepriv->htpriv.ht_option) + { + psta->htpriv.ht_option = _TRUE; + + psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; + + psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2; + + if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20)) + psta->htpriv.sgi_20m = _TRUE; + + if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40)) + psta->htpriv.sgi_40m = _TRUE; + + psta->qos_option = _TRUE; + + psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap; + psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap; + psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap; + + _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap)); + } + else +#endif //CONFIG_80211N_HT + { +#ifdef CONFIG_80211N_HT + psta->htpriv.ht_option = _FALSE; + + psta->htpriv.ampdu_enable = _FALSE; + + psta->htpriv.sgi_20m = _FALSE; + psta->htpriv.sgi_40m = _FALSE; +#endif //CONFIG_80211N_HT + psta->qos_option = _FALSE; + + } + +#ifdef CONFIG_80211N_HT + psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; + + psta->htpriv.agg_enable_bitmap = 0x0;//reset + psta->htpriv.candidate_tid_bitmap = 0x0;//reset +#endif //CONFIG_80211N_HT + + psta->bw_mode = pmlmeext->cur_bwmode; + + //QoS + if(pmlmepriv->qospriv.qos_option) + psta->qos_option = _TRUE; + +#ifdef CONFIG_80211AC_VHT + _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv)); +#endif //CONFIG_80211AC_VHT + + update_ldpc_stbc_cap(psta); + + _enter_critical_bh(&psta->lock, &irqL); + psta->state = _FW_LINKED; + _exit_critical_bh(&psta->lock, &irqL); + +} + +static void rtw_mlmeext_disconnect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + 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); + + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0); + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); + + //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) + { + if (rtw_port_switch_chk(padapter) == _TRUE) { + rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); + #ifdef CONFIG_LPS + { + _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter)); + if (port0_iface) + rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0); + } + #endif + } + } + + /* switch to the 20M Hz mode after disconnect */ + pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + +#ifdef CONFIG_FCS_MODE + if (EN_FCS(padapter)) + rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL); +#endif + +#ifdef CONFIG_DFS_MASTER + if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) + rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED); + else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED); +#endif + + { + u8 ch, bw, offset; + + if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) + set_channel_bwmode(padapter, ch, offset, bw); + } + + flush_all_cam_entry(padapter); + + _cancel_timer_ex(&pmlmeext->link_timer); + + //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; + +#ifdef CONFIG_TDLS + padapter->tdlsinfo.ap_prohibited = _FALSE; + + /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */ + if (padapter->registrypriv.wifi_spec == 1) + { + padapter->tdlsinfo.ch_switch_prohibited = _FALSE; + } +#endif /* CONFIG_TDLS */ + +} + +void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res) +{ + struct sta_info *psta, *psta_bmc; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + u8 join_type; +#ifdef CONFIG_ARP_KEEP_ALIVE + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif + struct security_priv *psecuritypriv = &padapter->securitypriv; + + if(join_res < 0) + { + join_type = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); + + goto exit_mlmeext_joinbss_event_callback; + } +#ifdef CONFIG_ARP_KEEP_ALIVE + pmlmepriv->bGetGateway = 1; +#endif + + if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + //update bc/mc sta_info + update_bmc_sta(padapter); + } + + + //turn on dynamic functions + /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */ + + // update IOT-releated issue + update_IOT_info(padapter); + + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); + + //BCN interval + rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); + + //udpate capability + update_capinfo(padapter, pmlmeinfo->capability); + + //WMM, Update EDCA param + WMMOnAssocRsp(padapter); + + //HT + HTOnAssocRsp(padapter); + +#ifdef CONFIG_80211AC_VHT + //VHT + VHTOnAssocRsp(padapter); +#endif + + psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); + if (psta) //only for infra. mode + { + //DBG_871X("set_sta_rate\n"); + + psta->wireless_mode = pmlmeext->cur_wireless_mode; + + //set per sta rate after updating HT cap. + set_sta_rate(padapter, psta); + + rtw_sta_media_status_rpt(padapter, psta, 1); + + /* wakeup macid after join bss successfully to ensure + the subsequent data frames can be sent out normally */ + rtw_hal_macid_wakeup(padapter, psta->mac_id); + } + +#ifndef CONFIG_IOCTL_CFG80211 + if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) + rtw_sec_restore_wep_key(padapter); +#endif /* CONFIG_IOCTL_CFG80211 */ + + if (rtw_port_switch_chk(padapter) == _TRUE) + rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); + + join_type = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + // correcting TSF + correct_TSF(padapter, pmlmeext); + + //set_link_timer(pmlmeext, DISCONNECT_TO); + } + +#ifdef CONFIG_LPS + if(get_iface_type(padapter) == IFACE_PORT0) + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); +#endif + +#ifdef CONFIG_BEAMFORMING + if (psta) + beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0); +#endif/*CONFIG_BEAMFORMING*/ + +exit_mlmeext_joinbss_event_callback: + + rtw_join_done_chk_ch(padapter, join_res); + + DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__); +} + +//currently only adhoc mode will go here +void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 join_type; + + DBG_871X("%s\n", __FUNCTION__); + + if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) + { + if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1 + { + //nothing to do + } + else//adhoc client + { + //update TSF Value + //update_TSF(pmlmeext, pframe, len); + + // correcting TSF + correct_TSF(padapter, pmlmeext); + + //start beacon + if (send_beacon(padapter) == _FAIL) + rtw_warn_on(1); + + pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; + } + + join_type = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + } + + //update adhoc sta_info + update_sta_info(padapter, psta); + + rtw_hal_update_sta_rate_mask(padapter, psta); + + // ToDo: HT for Ad-hoc + psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel); + psta->raid = rtw_hal_networktype_to_raid(padapter, psta); + + //rate radaptive + Update_RA_Entry(padapter, psta); +} + +void mlmeext_sta_del_event_callback(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) + { + rtw_mlmeext_disconnect(padapter); + } + +} + +/**************************************************************************** + +Following are the functions for the timer handlers + +*****************************************************************************/ +void _linked_info_dump(_adapter *padapter) +{ + int i; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int UndecoratedSmoothedPWDB = 0; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + + if(padapter->bLinkInfoDump){ + + DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter)); + + if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) + { + rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + + DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n", + MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB); + } + else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_) + { + _irqL irqL; + _list *phead, *plist; + + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n", + MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB); + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + for(i=0; inum; 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_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, NULL, _FALSE); + + } + + +} +void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer) +{ + int i = 0; + int ret = _SUCCESS; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + /* + IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300). + AP is originator.AP does not transmit unicast packets when STA response its BAR. + This case probably occur ap issue BAR after AP builds BA. + + Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup. + The inactivity timer is not reset when MPDUs corresponding to other TIDs are received. + */ + if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) { + for (i = 0; i < TID_NUM ; i++) { + if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) { + if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) { + if (psta->recvreorder_ctrl[i].enable) { + /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */ + if (!from_timer) + ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1); + else + issue_del_ba(padapter, psta->hwaddr, i, 39, 0); + psta->recvreorder_ctrl[i].enable = _FALSE; + if (ret != _FAIL) + psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID; + rtw_reset_continual_no_rx_packet(psta, i); + } + } + } + else{ + /* The inactivity timer is reset when MPDUs to the TID is received. */ + rtw_reset_continual_no_rx_packet(psta, i); + } + } + } +} + +u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta) +{ + u8 ret = _FALSE; + int i = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + #ifdef DBG_EXPIRATION_CHK + DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu" + /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/ + ", retry:%u\n" + , FUNC_ADPT_ARG(padapter) + , STA_RX_PKTS_DIFF_ARG(psta) + , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts + , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts + /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts + , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts + , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts + , pmlmeinfo->bcn_interval*/ + , pmlmeext->retry + ); + + DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter) + , padapter->xmitpriv.tx_pkts + , pmlmeinfo->link_count + ); + #endif + + if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) + && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) + && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta) + ) + { + ret = _FALSE; + } + else + { + ret = _TRUE; + } + + sta_update_last_rx_pkts(psta); + + /* + record last rx data packets for every tid. + */ + for (i = 0; i < TID_NUM; i++) + psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i]; + + return ret; +} + +u8 chk_adhoc_peer_is_alive(struct sta_info *psta) +{ + u8 ret = _TRUE; + + #ifdef DBG_EXPIRATION_CHK + DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu" + /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/ + ", expire_to:%u\n" + , MAC_ARG(psta->hwaddr) + , psta->rssi_stat.UndecoratedSmoothedPWDB + , STA_RX_PKTS_DIFF_ARG(psta) + , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts + , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts + /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts + , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts + , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts + , pmlmeinfo->bcn_interval*/ + , psta->expire_to + ); + #endif + + if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta) + && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) + && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)) + ret = _FALSE; + + sta_update_last_rx_pkts(psta); + + return ret; +} + +#ifdef CONFIG_TDLS +u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta) +{ + if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts) + && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts)) + return _FALSE; + + return _TRUE; +} + +void linked_status_chk_tdls(_adapter *padapter) +{ +struct candidate_pool{ + struct sta_info *psta; + u8 addr[ETH_ALEN]; +}; + struct sta_priv *pstapriv = &padapter->stapriv; + _irqL irqL; + u8 ack_chk; + struct sta_info *psta; + int i, num_teardown=0, num_checkalive=0; + _list *plist, *phead; + struct tdls_txmgmt txmgmt; + struct candidate_pool checkalive[NUM_STA]; + struct candidate_pool teardown[NUM_STA]; +#define ALIVE_MIN 2 +#define ALIVE_MAX 5 + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + _rtw_memset(checkalive, 0x00, sizeof(checkalive)); + _rtw_memset(teardown, 0x00, sizeof(teardown)); + + if((padapter->tdlsinfo.link_established == _TRUE)){ + _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(psta->tdls_sta_state & TDLS_LINKED_STATE) + { + psta->alive_count++; + if(psta->alive_count >= ALIVE_MIN) + { + if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) { + if (psta->alive_count < ALIVE_MAX) { + _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN); + checkalive[num_checkalive].psta = psta; + num_checkalive++; + } + else + { + _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN); + teardown[num_teardown].psta = psta; + num_teardown++; + } + } + else + { + psta->alive_count = 0; + } + } + psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts; + psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts; + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + if (num_checkalive > 0) { + for (i = 0; i < num_checkalive; i++) { + _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN); + issue_tdls_dis_req(padapter, &txmgmt); + issue_tdls_dis_req(padapter, &txmgmt); + issue_tdls_dis_req(padapter, &txmgmt); + } + } + + if(num_teardown > 0) + { + for(i=0; i< num_teardown; i++) + { + DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr)); + txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_; + _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN); + issue_tdls_teardown(padapter, &txmgmt, _FALSE); + } + } + } + +} +#endif //CONFIG_TDLS + +//from_timer == 1 means driver is in LPS +void linked_status_chk(_adapter *padapter, u8 from_timer) +{ + u32 i; + struct sta_info *psta; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; +#ifdef CONFIG_ARP_KEEP_ALIVE + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#endif + + + if (is_client_associated_to_ap(padapter)) + { + //linked infrastructure client mode + + int tx_chk = _SUCCESS, rx_chk = _SUCCESS; + int rx_chk_limit; + int link_count_limit; + + #if defined(DBG_ROAMING_TEST) + rx_chk_limit = 1; + #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER) + rx_chk_limit = 4; + #else + rx_chk_limit = 8; + #endif +#ifdef CONFIG_ARP_KEEP_ALIVE + if (!from_timer && pmlmepriv->bGetGateway == 1) { + DBG_871X("do rtw_gw_addr_query()"); + if (rtw_gw_addr_query(padapter) == 0) { + pmlmepriv->bGetGateway = 0; + } else { + _rtw_memset(pmlmepriv->gw_ip, 0, 4); + _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6); + } + } +#endif +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) + { + if(!from_timer) + link_count_limit = 3; // 8 sec + else + link_count_limit = 15; // 32 sec + } + else +#endif // CONFIG_P2P + { + if(!from_timer) + link_count_limit = 7; // 16 sec + else + link_count_limit = 29; // 60 sec + } + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE) + return; +#endif /* CONFIG_TDLS_CH_SW */ + +#ifdef CONFIG_TDLS_AUTOCHECKALIVE + linked_status_chk_tdls(padapter); +#endif /* CONFIG_TDLS_AUTOCHECKALIVE */ +#endif /* CONFIG_TDLS */ + + if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) + { + bool is_p2p_enable = _FALSE; + #ifdef CONFIG_P2P + is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE); + #endif + + /*issue delba when ap does not tx data packet that is Broadcom ap */ + rtw_delba_check(padapter, psta, from_timer); + + if (chk_ap_is_alive(padapter, psta) == _FALSE) + rx_chk = _FAIL; + + if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) + tx_chk = _FAIL; + + #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER) + if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) { + u8 backup_oper_channel=0; + + /* switch to correct channel of current network before issue keep-alive frames */ + if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { + backup_oper_channel = rtw_get_oper_ch(padapter); + SelectChannel(padapter, pmlmeext->cur_channel); + } + + if (rx_chk != _SUCCESS) + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1); + + if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) { + tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1); + /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */ + if (tx_chk == _SUCCESS && !is_p2p_enable) + rx_chk = _SUCCESS; + } + + /* back to the original operation channel */ + if(backup_oper_channel>0) + SelectChannel(padapter, backup_oper_channel); + + } + else + #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */ + { + if (rx_chk != _SUCCESS) { + if (pmlmeext->retry == 0) { + #ifdef DBG_EXPIRATION_CHK + DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry); + #endif + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); + issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); + } + } + + if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) { + #ifdef DBG_EXPIRATION_CHK + DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0); + #endif + tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0); + } + } + + if (rx_chk == _FAIL) { + pmlmeext->retry++; + if (pmlmeext->retry > rx_chk_limit) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n", + FUNC_ADPT_ARG(padapter)); + receive_disconnect(padapter, pmlmeinfo->network.MacAddress + , WLAN_REASON_EXPIRATION_CHK); + return; + } + } else { + pmlmeext->retry = 0; + } + + if (tx_chk == _FAIL) { + pmlmeinfo->link_count %= (link_count_limit+1); + } else { + pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; + pmlmeinfo->link_count = 0; + } + + } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) + + } else if (is_client_associated_to_ibss(padapter)) { + _irqL irqL; + _list *phead, *plist, dlist; + + _rtw_init_listhead(&dlist); + + _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 (is_broadcast_mac_addr(psta->hwaddr)) + continue; + + if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to) + psta->expire_to = pstapriv->adhoc_expire_to; + else + psta->expire_to--; + + if (psta->expire_to <= 0) { + rtw_list_delete(&psta->list); + rtw_list_insert_tail(&psta->list, &dlist); + } + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + plist = get_next(&dlist); + while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) { + psta = LIST_CONTAINOR(plist, struct sta_info, list); + plist = get_next(plist); + rtw_list_delete(&psta->list); + DBG_871X(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr)); + report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE); + } + } + +} + +void survey_timer_hdl(_adapter *padapter) +{ + struct cmd_obj *cmd; + struct sitesurvey_parm *psurveyPara; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + + if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) { + cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (cmd == NULL) { + rtw_warn_on(1); + goto exit; + } + + psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm)); + if (psurveyPara == NULL) { + rtw_warn_on(1); + rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj)); + goto exit; + } + + init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); + rtw_enqueue_cmd(pcmdpriv, cmd); + } + +exit: + return; +} + +void link_timer_hdl(_adapter *padapter) +{ + //static unsigned int rx_pkt = 0; + //static u64 tx_cnt = 0; + //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + //struct sta_priv *pstapriv = &padapter->stapriv; + + + if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) + { + DBG_871X("link_timer_hdl:no beacon while connecting\n"); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -3); + } + else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) + { + //re-auth timer + if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) + { + //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) + //{ + pmlmeinfo->state = 0; + report_join_res(padapter, -1); + return; + //} + //else + //{ + // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; + // pmlmeinfo->reauth_count = 0; + //} + } + + DBG_871X("link_timer_hdl: auth timeout and try again\n"); + pmlmeinfo->auth_seq = 1; + issue_auth(padapter, NULL, 0); + set_link_timer(pmlmeext, REAUTH_TO); + } + else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) + { + //re-assoc timer + if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) + { + pmlmeinfo->state = WIFI_FW_NULL_STATE; + report_join_res(padapter, -2); + return; + } + + DBG_871X("link_timer_hdl: assoc timeout and try again\n"); + issue_assocreq(padapter); + set_link_timer(pmlmeext, REASSOC_TO); + } + + return; +} + +void addba_timer_hdl(struct sta_info *psta) +{ +#ifdef CONFIG_80211N_HT + struct ht_priv *phtpriv; + + if(!psta) + return; + + phtpriv = &psta->htpriv; + + if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) + { + if(phtpriv->candidate_tid_bitmap) + phtpriv->candidate_tid_bitmap=0x0; + + } +#endif //CONFIG_80211N_HT +} + +#ifdef CONFIG_IEEE80211W +void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason) +{ + struct cmd_obj *pcmd_obj; + u8 *pevtcmd; + u32 cmdsz; + struct sta_info *psta; + int mac_id; + struct stadel_event *pdel_sta_evt; + struct C2HEvent_Header *pc2h_evt_hdr; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + + pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj)); + if (pcmd_obj == NULL) + return; + + cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); + pevtcmd = (u8 *)rtw_zmalloc(cmdsz); + if (pevtcmd == NULL) { + rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj)); + return; + } + + _rtw_init_listhead(&pcmd_obj->list); + + pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); + pcmd_obj->cmdsz = cmdsz; + pcmd_obj->parmbuf = pevtcmd; + + pcmd_obj->rsp = NULL; + pcmd_obj->rspsz = 0; + + pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); + pc2h_evt_hdr->len = sizeof(struct stadel_event); + pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA); + pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq); + + pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); + _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); + _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); + + + psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); + if (psta) + mac_id = (int)psta->mac_id; + else + mac_id = (-1); + + pdel_sta_evt->mac_id = mac_id; + + DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id); + + rtw_enqueue_cmd(pcmdpriv, pcmd_obj); + + return; +} + +void clnt_sa_query_timeout(_adapter *padapter) +{ + + rtw_disassoc_cmd(padapter, 0, _TRUE); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + + DBG_871X("SA query timeout client disconnect\n"); +} + +void sa_query_timer_hdl(struct sta_info *psta) +{ + _adapter *padapter = psta->padapter; + _irqL irqL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE && + check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + clnt_sa_query_timeout(padapter); + else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID); +} + +#endif //CONFIG_IEEE80211W + +u8 NULL_hdl(_adapter *padapter, u8 *pbuf) +{ + return H2C_SUCCESS; +} + +#ifdef CONFIG_AUTO_AP_MODE +void rtw_start_auto_ap(_adapter *adapter) +{ + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode); + + rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE); +} + +static int rtw_auto_ap_start_beacon(_adapter *adapter) +{ + int ret=0; + u8 *pbuf = NULL; + uint len; + u8 supportRate[16]; + int sz = 0, rateLen; + u8 * ie; + u8 wireless_mode, oper_channel; + u8 ssid[3] = {0}; //hidden ssid + u32 ssid_len = sizeof(ssid); + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + + len = 128; + pbuf = rtw_zmalloc(len); + if(!pbuf) + return -ENOMEM; + + + //generate beacon + ie = pbuf; + + //timestamp will be inserted by hardware + sz += 8; + ie += sz; + + //beacon interval : 2bytes + *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100; + sz += 2; + ie += 2; + + //capability info + *(u16*)ie = 0; + *(u16*)ie |= cpu_to_le16(cap_ESS); + *(u16*)ie |= cpu_to_le16(cap_ShortPremble); + //*(u16*)ie |= cpu_to_le16(cap_Privacy); + sz += 2; + ie += 2; + + //SSID + ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz); + + //supported rates + wireless_mode = WIRELESS_11BG_24N; + rtw_set_supported_rate(supportRate, wireless_mode) ; + rateLen = rtw_get_rateset_len(supportRate); + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz); + } + else + { + ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz); + } + + + //DS parameter set + if(check_buddy_fwstate(adapter, _FW_LINKED) && + check_buddy_fwstate(adapter, WIFI_STATION_STATE)) + { + PADAPTER pbuddy_adapter = adapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + oper_channel = pbuddy_mlmeext->cur_channel; + } + else + { + oper_channel = adapter_to_dvobj(adapter)->oper_channel; + } + ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz); + + //ext supported rates + if (rateLen > 8) + { + ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz); + } + + DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz); + + //lunch ap mode & start to issue beacon + if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) + { + + } + else + { + ret = -EINVAL; + } + + + rtw_mfree(pbuf, len); + + return ret; + +} +#endif//CONFIG_AUTO_AP_MODE + +u8 setopmode_hdl(_adapter *padapter, u8 *pbuf) +{ + u8 type; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; + + if(psetop->mode == Ndis802_11APMode) + { + pmlmeinfo->state = WIFI_FW_AP_STATE; + type = _HW_STATE_AP_; +#ifdef CONFIG_NATIVEAP_MLME + //start_ap_mode(padapter); +#endif + } + else if(psetop->mode == Ndis802_11Infrastructure) + { + pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state + pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE + type = _HW_STATE_STATION_; + } + else if(psetop->mode == Ndis802_11IBSS) + { + type = _HW_STATE_ADHOC_; + } else if (psetop->mode == Ndis802_11Monitor) { + type = _HW_STATE_MONITOR_; + } + else + { + type = _HW_STATE_NOLINK_; + } + + rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); + //Set_NETYPE0_MSR(padapter, type); + + +#ifdef CONFIG_AUTO_AP_MODE + if(psetop->mode == Ndis802_11APMode) + rtw_auto_ap_start_beacon(padapter); +#endif + + if (rtw_port_switch_chk(padapter) == _TRUE) + { + rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); + + if(psetop->mode == Ndis802_11APMode) + adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages + else if (psetop->mode == Ndis802_11Infrastructure) { + #ifdef CONFIG_LPS + _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter)); + if (port0_iface) + rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0); + #endif + } + } + +#ifdef CONFIG_BT_COEXIST + if (psetop->mode == Ndis802_11APMode) + { + // Do this after port switch to + // prevent from downloading rsvd page to wrong port + rtw_btcoex_MediaStatusNotify(padapter, 1); //connect + } +#endif // CONFIG_BT_COEXIST + + return H2C_SUCCESS; + +} + +u8 createbss_hdl(_adapter *padapter, u8 *pbuf) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network; + struct createbss_parm *parm = (struct createbss_parm *)pbuf; + u8 ret = H2C_SUCCESS; + //u8 initialgain; + +#ifdef CONFIG_AP_MODE + if (pmlmeinfo->state == WIFI_FW_AP_STATE) { + start_bss_network(padapter, parm); + goto exit; + } +#endif + + /* below is for ad-hoc master */ + if (parm->adhoc) { + rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS); + rtw_joinbss_reset(padapter); + + pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; + pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pmlmeinfo->ERP_enable = 0; + pmlmeinfo->WMM_enable = 0; + pmlmeinfo->HT_enable = 0; + pmlmeinfo->HT_caps_enable = 0; + pmlmeinfo->HT_info_enable = 0; + pmlmeinfo->agg_enable_bitmap = 0; + pmlmeinfo->candidate_tid_bitmap = 0; + + //config the initial gain under linking, need to write the BB registers + //initialgain = 0x1E; + /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/ + + //disable dynamic functions, such as high power, DIG + rtw_phydm_ability_backup(padapter); + rtw_phydm_func_disable_all(padapter); + + //cancel link timer + _cancel_timer_ex(&pmlmeext->link_timer); + + //clear CAM + flush_all_cam_entry(padapter); + + pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network); + _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); + pnetwork->IELength = pdev_network->IELength; + + if (pnetwork->IELength > MAX_IE_SZ) { + ret = H2C_PARAMETERS_ERROR; + goto ibss_post_hdl; + } + + _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength); + start_create_ibss(padapter); + } else { + rtw_warn_on(1); + ret = H2C_PARAMETERS_ERROR; + } + +ibss_post_hdl: + rtw_create_ibss_post_hdl(padapter, ret); + +exit: + return ret; +} + +u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf) +{ + u8 join_type; + PNDIS_802_11_VARIABLE_IEs pIE; + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); +#ifdef CONFIG_ANTENNA_DIVERSITY + struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; +#endif //CONFIG_ANTENNA_DIVERSITY + u32 i; + //u8 initialgain; + //u32 acparm; + u8 u_ch, u_bw, u_offset; + u8 doiqk = _FALSE; + + //check already connecting to AP or not + if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) + { + if (pmlmeinfo->state & WIFI_FW_STATION_STATE) + { + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); + } + pmlmeinfo->state = WIFI_FW_NULL_STATE; + + //clear CAM + flush_all_cam_entry(padapter); + + _cancel_timer_ex(&pmlmeext->link_timer); + + //set MSR to nolink -> infra. mode + //Set_MSR(padapter, _HW_STATE_NOLINK_); + Set_MSR(padapter, _HW_STATE_STATION_); + + + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0); + } + +#ifdef CONFIG_ANTENNA_DIVERSITY + rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE); +#endif + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_clear_all_cam_entry(padapter); +#endif + + rtw_joinbss_reset(padapter); + + pmlmeinfo->ERP_enable = 0; + pmlmeinfo->WMM_enable = 0; + pmlmeinfo->HT_enable = 0; + pmlmeinfo->HT_caps_enable = 0; + pmlmeinfo->HT_info_enable = 0; + pmlmeinfo->agg_enable_bitmap = 0; + pmlmeinfo->candidate_tid_bitmap = 0; + pmlmeinfo->bwmode_updated = _FALSE; + //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; + pmlmeinfo->VHT_enable = 0; + + _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); + pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength; + + if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength + return H2C_PARAMETERS_ERROR; + + if (pnetwork->IELength < 2) { + report_join_res(padapter, (-4)); + return H2C_SUCCESS; + } + _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength); + + pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); + + //Check AP vendor to move rtw_joinbss_cmd() + //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); + + //sizeof(NDIS_802_11_FIXED_IEs) + for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_://Get WMM IE. + if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) ) + { + WMM_param_handler(padapter, pIE); + } + break; + +#ifdef CONFIG_80211N_HT + case _HT_CAPABILITY_IE_: //Get HT Cap IE. + pmlmeinfo->HT_caps_enable = 1; + break; + + case _HT_EXTRA_INFO_IE_: //Get HT Info IE. + pmlmeinfo->HT_info_enable = 1; + break; +#endif /* CONFIG_80211N_HT */ + +#ifdef CONFIG_80211AC_VHT + case EID_VHTCapability://Get VHT Cap IE. + pmlmeinfo->VHT_enable = 1; + break; + + case EID_VHTOperation://Get VHT Operation IE. + break; +#endif /* CONFIG_80211AC_VHT */ + default: + break; + } + + i += (pIE->Length + 2); + } + + rtw_bss_get_chbw(pnetwork + , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset); + + rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset); + +#if 0 + if (padapter->registrypriv.wifi_spec) { + // for WiFi test, follow WMM test plan spec + acparm = 0x002F431C; // VO + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E541C; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + acparm = 0x0000A525; // BE + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A549; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + + // for WiFi test, mixed mode with intel STA under bg mode throughput issue + if (padapter->mlmepriv.htpriv.ht_option == _FALSE){ + acparm = 0x00004320; + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + } + } + else { + acparm = 0x002F3217; // VO + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm)); + acparm = 0x005E4317; // VI + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm)); + acparm = 0x00105320; // BE + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm)); + acparm = 0x0000A444; // BK + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm)); + } +#endif + + /* check channel, bandwidth, offset and switch */ + if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) { + report_join_res(padapter, (-4)); + return H2C_SUCCESS; + } + + //disable dynamic functions, such as high power, DIG + /*rtw_phydm_func_disable_all(padapter);*/ + + //config the initial gain under linking, need to write the BB registers + //initialgain = 0x1E; + /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/ + + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); + join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + + set_channel_bwmode(padapter, u_ch, u_offset, u_bw); + + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + + //cancel link timer + _cancel_timer_ex(&pmlmeext->link_timer); + + start_clnt_join(padapter); + + return H2C_SUCCESS; + +} + +u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct disconnect_parm *param = (struct disconnect_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + u8 val8; + + if (is_client_associated_to_ap(padapter)) + { +#ifdef CONFIG_DFS + if(padapter->mlmepriv.handle_dfs == _FALSE) +#endif //CONFIG_DFS +#ifdef CONFIG_PLATFORM_ROCKCHIPS + //To avoid connecting to AP fail during resume process, change retry count from 5 to 1 + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); +#else + issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); +#endif //CONFIG_PLATFORM_ROCKCHIPS + } + +#ifdef CONFIG_DFS + if( padapter->mlmepriv.handle_dfs == _TRUE ) + padapter->mlmepriv.handle_dfs = _FALSE; +#endif //CONFIG_DFS + + if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //Stop BCN + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); + } + + rtw_mlmeext_disconnect(padapter); + + rtw_free_uc_swdec_pending_queue(padapter); + + return H2C_SUCCESS; +} + +static const char * const _scan_state_str[] = { + "SCAN_DISABLE", + "SCAN_START", + "SCAN_PS_ANNC_WAIT", + "SCAN_ENTER", + "SCAN_PROCESS", + "SCAN_BACKING_OP", + "SCAN_BACK_OP", + "SCAN_LEAVING_OP", + "SCAN_LEAVE_OP", + "SCAN_SW_ANTDIV_BL", + "SCAN_TO_P2P_LISTEN", + "SCAN_P2P_LISTEN", + "SCAN_COMPLETE", + "SCAN_STATE_MAX", +}; + +const char *scan_state_str(u8 state) +{ + state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state; + return _scan_state_str[state]; +} + +static bool scan_abort_hdl(_adapter *adapter) +{ + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct ss_res *ss = &pmlmeext->sitesurvey_res; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &adapter->wdinfo; +#endif + bool ret = _FALSE; + + if (pmlmeext->scan_abort == _TRUE) { + #ifdef CONFIG_P2P + if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) { + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX); + ss->channel_idx = 3; + DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__ + , ss->channel_idx + , pwdinfo->find_phase_state_exchange_cnt + ); + } else + #endif + { + ss->channel_idx = ss->ch_num; + DBG_871X("%s idx:%d\n", __FUNCTION__ + , ss->channel_idx + ); + } + pmlmeext->scan_abort = _FALSE; + ret = _TRUE; + } + + return ret; +} + +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; + + if (is_miracast_enabled(adapter) + #ifdef CONFIG_CONCURRENT_MODE + || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter)) + #endif + ) + miracast_enabled = _TRUE; + + 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; + int set_idx; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + /* clear first */ + _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num); + + /* acquire channels from in */ + j = 0; + for (i=0;ichannel_set, in[i].hw_value)) >=0 + && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE + ) + { + if (j >= out_num) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", + FUNC_ADPT_ARG(padapter), out_num); + break; + } + + _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); + + if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) + out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; + + j++; + } + if(j>=out_num) + break; + } + + /* if out is empty, use channel_set as default */ + if(j == 0) { + for (i=0;imax_chan_nums;i++) { + + if (0) + DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum); + + if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) { + + if (j >= out_num) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", + FUNC_ADPT_ARG(padapter), out_num); + break; + } + + out[j].hw_value = pmlmeext->channel_set[i].ChannelNum; + + if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) + out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; + + j++; + } + } + } + + /* scan_sparse */ + j = rtw_scan_sparse(padapter, out, j); + + return j; +} + +static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm) +{ + struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res; + int i; + + ss->bss_cnt = 0; + ss->channel_idx = 0; +#ifdef CONFIG_SCAN_BACKOP + ss->scan_cnt = 0; +#endif +#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) + ss->is_sw_antdiv_bl_scan = 0; +#endif + + for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { + if (parm->ssid[i].SsidLength) { + _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); + ss->ssid[i].SsidLength = parm->ssid[i].SsidLength; + } else { + ss->ssid[i].SsidLength = 0; + } + } + + ss->ch_num = rtw_scan_ch_decision(adapter + , ss->ch, RTW_CHANNEL_SCAN_AMOUNT + , parm->ch, parm->ch_num + ); + + ss->scan_mode = parm->scan_mode; +} + +static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type) +{ + u8 next_state; + u8 scan_ch = 0; + RT_SCAN_TYPE scan_type = SCAN_PASSIVE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + struct ss_res *ss = &pmlmeext->sitesurvey_res; + +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + + /* handle scan abort request */ + scan_abort_hdl(padapter); + +#ifdef CONFIG_P2P + if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) { + if (pwdinfo->rx_invitereq_info.scan_op_ch_only) + scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx]; + else + scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx]; + scan_type = SCAN_ACTIVE; + } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) { + /* + * Commented by Albert 2011/06/03 + * The driver is in the find phase, it should go through the social channel. + */ + int ch_set_idx; + + scan_ch = pwdinfo->social_chan[ss->channel_idx]; + ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch); + if (ch_set_idx >= 0) + scan_type = pmlmeext->channel_set[ch_set_idx].ScanType; + else + scan_type = SCAN_ACTIVE; + } else +#endif /* CONFIG_P2P */ + { + struct rtw_ieee80211_channel *ch; + + if (ss->channel_idx < ss->ch_num) { + ch = &ss->ch[ss->channel_idx]; + scan_ch = ch->hw_value; + scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; + } + } + + if (scan_ch != 0) { + next_state = SCAN_PROCESS; + #ifdef CONFIG_SCAN_BACKOP + { + u8 sta_num; + u8 ld_sta_num; + u8 ap_num; + u8 ld_ap_num; + u8 backop_flags = 0; + + rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num); + + if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN)) + || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL)) + ) { + backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext); + } + + if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN)) + || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL)) + ) { + backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext); + } + + if (backop_flags) { + if (ss->scan_cnt < ss->scan_cnt_max) { + ss->scan_cnt++; + } else { + mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags); + next_state = SCAN_BACKING_OP; + } + } + } + #endif /* CONFIG_SCAN_BACKOP */ + } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) { + /* go p2p listen */ + next_state = SCAN_TO_P2P_LISTEN; + + #ifdef CONFIG_ANTENNA_DIVERSITY + } else if (rtw_hal_antdiv_before_linked(padapter)) { + /* go sw antdiv before link */ + next_state = SCAN_SW_ANTDIV_BL; + #endif + } else { + next_state = SCAN_COMPLETE; + + #if defined(DBG_SCAN_SW_ANTDIV_BL) + { + /* for SCAN_SW_ANTDIV_BL state testing */ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + int i; + bool is_linked = _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (rtw_linked_check(dvobj->padapters[i])) + is_linked = _TRUE; + } + + if (!is_linked) { + static bool fake_sw_antdiv_bl_state = 0; + + if (fake_sw_antdiv_bl_state == 0) { + next_state = SCAN_SW_ANTDIV_BL; + fake_sw_antdiv_bl_state = 1; + } else { + fake_sw_antdiv_bl_state = 0; + } + } + } + #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */ + } + + #ifdef CONFIG_SCAN_BACKOP + if (next_state != SCAN_PROCESS) + ss->scan_cnt = 0; + #endif + + +#ifdef DBG_FIXED_CHAN + if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS) + scan_ch = pmlmeext->fixed_chan; +#endif + + if (ch) + *ch = scan_ch; + if (type) + *type = scan_type; + + return next_state; +} + +void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#endif + + if (survey_channel != 0) { + set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + + #ifdef CONFIG_AUTO_CHNL_SEL_NHM + if (ACS_ENABLE == GET_ACS_STATE(padapter)) { + ACS_OP acs_op = ACS_RESET; + + rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE); + rtw_set_acs_channel(padapter, survey_channel); + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", + ADPT_ARG(padapter), rtw_get_acs_channel(padapter)); + #endif + } + #endif + + if (ScanType == SCAN_ACTIVE) { + #ifdef CONFIG_P2P + if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) + ) { + issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter, NULL); + issue_probereq_p2p(padapter, NULL); + } else + #endif /* CONFIG_P2P */ + { + int i; + + for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { + if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { + /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ + if (padapter->registrypriv.wifi_spec) + issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + else + issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0); + issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); + } + } + + if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { + /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ + if (padapter->registrypriv.wifi_spec) + issue_probereq(padapter, NULL, NULL); + else + issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0); + issue_probereq(padapter, NULL, NULL); + } + } + } + } else { + /* channel number is 0 or this channel is not valid. */ + rtw_warn_on(1); + } + + return; +} + +void survey_done_set_ch_bw(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 cur_channel = 0; + u8 cur_bwmode; + u8 cur_ch_offset; + + if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) { + if (0) + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset); + } else { + #ifdef CONFIG_P2P + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + _adapter *iface; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + + #ifdef CONFIG_IOCTL_CFG80211 + if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled) + continue; + #endif + + if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) { + cur_channel = iface->wdinfo.listen_channel; + cur_bwmode = CHANNEL_WIDTH_20; + cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset); + break; + } + } + #endif /* CONFIG_P2P */ + + if (cur_channel == 0) { + cur_channel = pmlmeext->cur_channel; + cur_bwmode = pmlmeext->cur_bwmode; + cur_ch_offset = pmlmeext->cur_ch_offset; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset); + } + } + + set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode); +} + +/** + * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj + * @dvobj: the dvobj to check + * @ps: power saving or not + * + * Returns: 0: no ps announcement is doing. 1: ps announcement is doing + */ +u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps) +{ + _adapter *adapter; + int i; + u8 ps_anc = 0; + + for (i = 0; i < dvobj->iface_nums; i++) { + adapter = dvobj->padapters[i]; + if (!adapter) + continue; + + if (ps) { + if (is_client_associated_to_ap(adapter) == _TRUE) { + /* TODO: TDLS peers */ + issue_nulldata(adapter, NULL, 1, 3, 500); + ps_anc = 1; + } + } else { + if (is_client_associated_to_ap(adapter) == _TRUE) { + /* TODO: TDLS peers */ + issue_nulldata(adapter, NULL, 0, 3, 500); + ps_anc = 1; + } + } + } + + return ps_anc; +} + +void sitesurvey_set_igi(_adapter *adapter, bool enter) +{ + u8 igi; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &adapter->wdinfo; +#endif + + if (enter) { +#ifdef CONFIG_P2P +#ifdef CONFIG_IOCTL_CFG80211 + if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211) + igi = 0x30; + else +#endif /* CONFIG_IOCTL_CFG80211 */ + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + igi = 0x28; + else +#endif /* CONFIG_P2P */ + igi = 0x1e; + } else { + igi = 0xff; /* restore RX GAIN */ + } + + rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE); +} + +u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf) +{ + struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; + struct dvobj_priv *dvobj = padapter->dvobj; + struct debug_priv *pdbgpriv = &dvobj->drv_dbg; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct ss_res *ss = &pmlmeext->sitesurvey_res; + u8 val8; + +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif + +#ifdef DBG_CHECK_FW_PS_STATE + if (rtw_fw_ps_state(padapter) == _FAIL) { + DBG_871X("scan without leave 32k\n"); + pdbgpriv->dbg_scan_pwr_state_cnt++; + } +#endif /* DBG_CHECK_FW_PS_STATE */ + + /* increase channel idx */ + if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) + ss->channel_idx++; + + /* update scan state to next state (assigned by previous cmd hdl) */ + if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext)) + mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext)); + +operation_by_state: + switch (mlmeext_scan_state(pmlmeext)) { + + case SCAN_DISABLE: + /* + * SW parameter initialization + */ + + sitesurvey_res_reset(padapter, pparm); + mlmeext_set_scan_state(pmlmeext, SCAN_START); + goto operation_by_state; + + case SCAN_START: + /* + * prepare to leave operating channel + */ + + /* apply rx ampdu setting */ + if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID + || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID + ) { + rtw_rx_ampdu_apply(padapter); + } + + /* clear HW TX queue before scan */ + rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + + /* power save state announcement */ + if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) { + mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT); + mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER); + set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */ + } else { + mlmeext_set_scan_state(pmlmeext, SCAN_ENTER); + goto operation_by_state; + } + + break; + + case SCAN_ENTER: + /* + * HW register and DM setting for enter scan + */ + + /* config the initial gain under scanning */ + sitesurvey_set_igi(padapter, 1); + + /* disable dynamic functions, such as high power, DIG */ + rtw_phydm_ability_backup(padapter); + rtw_phydm_func_for_offchannel(padapter); + + /* set MSR to no link state */ + Set_MSR(padapter, _HW_STATE_NOLINK_); + val8 = 1; /* under site survey */ + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS); + goto operation_by_state; + + case SCAN_PROCESS: + { + u8 scan_ch; + RT_SCAN_TYPE scan_type; + u8 next_state; + u32 scan_ms; + + #ifdef CONFIG_AUTO_CHNL_SEL_NHM + if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) { + ACS_OP acs_op = ACS_SELECT; + + rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE); + } + #endif + + next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type); + if (next_state != SCAN_PROCESS) { + #ifdef CONFIG_AUTO_CHNL_SEL_NHM + if (ACS_ENABLE == GET_ACS_STATE(padapter)) { + rtw_set_acs_channel(padapter, 0); + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter)); + #endif + } + #endif + + mlmeext_set_scan_state(pmlmeext, next_state); + goto operation_by_state; + } + + /* still SCAN_PROCESS state */ + if (0) + #ifdef CONFIG_P2P + DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n" + , FUNC_ADPT_ARG(padapter) + , mlmeext_scan_state_str(pmlmeext) + , scan_ch + , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx + , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) + , scan_type?'A':'P', ss->scan_mode?'A':'P' + , ss->ssid[0].SsidLength?'S':' ' + ); + #else + DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n" + , FUNC_ADPT_ARG(padapter) + , mlmeext_scan_state_str(pmlmeext) + , scan_ch + , ss->channel_idx + , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) + , scan_type?'A':'P', ss->scan_mode?'A':'P' + , ss->ssid[0].SsidLength?'S':' ' + ); + #endif /* CONFIG_P2P */ + + #ifdef DBG_FIXED_CHAN + if (pmlmeext->fixed_chan != 0xff) + DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan); + #endif + + site_survey(padapter, scan_ch, scan_type); + + #if defined(CONFIG_ATMEL_RC_PATCH) + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + scan_ms = 20; + else + scan_ms = 40; + #else + scan_ms = ss->scan_ch_ms; + #endif + + #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) + if (ss->is_sw_antdiv_bl_scan) + scan_ms = scan_ms/2; + #endif + + #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + { + struct noise_info info; + + info.bPauseDIG = _FALSE; + info.IGIValue = 0; + info.max_time = scan_ms/2; + info.chan = scan_ch; + rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE); + } + #endif + + set_survey_timer(pmlmeext, scan_ms); + break; + } + + #ifdef CONFIG_SCAN_BACKOP + case SCAN_BACKING_OP: + { + u8 back_ch, back_bw, back_ch_offset; + + if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) + rtw_warn_on(1); + + if (0) + DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n" + , FUNC_ADPT_ARG(padapter) + , mlmeext_scan_state_str(pmlmeext) + , back_ch, back_bw, back_ch_offset + , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time) + ); + + set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw); + + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + val8 = 0; /* survey done */ + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) { + sitesurvey_set_igi(padapter, 0); + sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0); + } + + mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP); + ss->backop_time = rtw_get_current_time(); + + if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) { + int i; + + /* resume TX */ + for (i = 0; i < dvobj->iface_nums; i++) { + if (!dvobj->padapters[i]) + continue; + + rtw_os_xmit_schedule(dvobj->padapters[i]); + } + } + + goto operation_by_state; + } + + case SCAN_BACK_OP: + if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms + || pmlmeext->scan_abort + ) { + mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP); + goto operation_by_state; + } + set_survey_timer(pmlmeext, 50); + break; + + case SCAN_LEAVING_OP: + /* + * prepare to leave operating channel + */ + + /* clear HW TX queue before scan */ + rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); + + if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC) + && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1) + ) { + mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT); + mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP); + set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */ + } else { + mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP); + goto operation_by_state; + } + + break; + + case SCAN_LEAVE_OP: + /* + * HW register and DM setting for enter scan + */ + + if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) { + /* config the initial gain under scanning */ + sitesurvey_set_igi(padapter, 1); + } + + /* set MSR to no link state */ + Set_MSR(padapter, _HW_STATE_NOLINK_); + val8 = 1; //under site survey + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS); + goto operation_by_state; + + #endif /* CONFIG_SCAN_BACKOP */ + + #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) + case SCAN_SW_ANTDIV_BL: + /* + * 20100721 + * For SW antenna diversity before link, it needs to switch to another antenna and scan again. + * It compares the scan result and select better one to do connection. + */ + ss->bss_cnt = 0; + ss->channel_idx = 0; + ss->is_sw_antdiv_bl_scan = 1; + + mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS); + set_survey_timer(pmlmeext, ss->scan_ch_ms); + break; + #endif + + #ifdef CONFIG_P2P + case SCAN_TO_P2P_LISTEN: + /* + * Set the P2P State to the listen state of find phase + * and set the current channel to the listen channel + */ + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN); + + /* turn on phy-dynamic functions */ + rtw_phydm_ability_restore(padapter); + + sitesurvey_set_igi(padapter, 0); + + mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN); + _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100)); + break; + + case SCAN_P2P_LISTEN: + mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS); + ss->channel_idx = 0; + goto operation_by_state; + #endif /* CONFIG_P2P */ + + case SCAN_COMPLETE: + #ifdef CONFIG_P2P + if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) + || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) + ) { + #ifdef CONFIG_CONCURRENT_MODE + if (pwdinfo->driver_interface == DRIVER_WEXT) { + if (check_buddy_fwstate(padapter, _FW_LINKED)) + _set_timer(&pwdinfo->ap_p2p_switch_timer, 500); + } + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + #else + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + #endif + } + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + #endif /* CONFIG_P2P */ + + /* switch channel */ + survey_done_set_ch_bw(padapter); + + /* config MSR */ + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + val8 = 0; /* survey done */ + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + + /* turn on phy-dynamic functions */ + rtw_phydm_ability_restore(padapter); + + sitesurvey_set_igi(padapter, 0); + + sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0); + + /* apply rx ampdu setting */ + rtw_rx_ampdu_apply(padapter); + + mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE); + + report_surveydone_event(padapter); + + issue_action_BSSCoexistPacket(padapter); + issue_action_BSSCoexistPacket(padapter); + issue_action_BSSCoexistPacket(padapter); + } + + return H2C_SUCCESS; +} + +u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct setauth_parm *pparm = (struct setauth_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (pparm->mode < 4) + { + pmlmeinfo->auth_algo = pparm->mode; + } + + return H2C_SUCCESS; +} + +u8 setkey_hdl(_adapter *padapter, u8 *pbuf) +{ + u16 ctrl = 0; + s16 cam_id = 0; + struct setkey_parm *pparm = (struct setkey_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + struct set_stakey_parm sta_pparm; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u8 *addr; + bool used; + + //main tx key for wep. + if(pparm->set_tx) + pmlmeinfo->key_index = pparm->keyid; + + cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used); + + if (cam_id < 0) + goto enable_mc; + + if (cam_id > 3) /* not default key, searched by A2 */ + addr = get_bssid(&padapter->mlmepriv); + else + addr = null_addr; + + #ifdef DYNAMIC_CAMID_ALLOC + /* cam entry searched is pairwise key */ + if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) { + s16 camid_clr; + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid); + + /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */ + rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH); + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL); + + /* clear group key */ + while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) { + DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr); + clear_cam_entry(padapter, camid_clr); + rtw_camid_free(padapter, camid_clr); + } + + goto enable_mc; + } + #endif + + ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid; + DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n" + , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm)); + write_cam(padapter, cam_id, ctrl, addr, pparm->key); + + #ifdef DYNAMIC_CAMID_ALLOC + if (cam_id >=0 && cam_id <=3) + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE); + #endif + /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */ + if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC) && is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + sta_pparm.algorithm = pparm->algorithm; + sta_pparm.keyid = pparm->keyid; + _rtw_memcpy(sta_pparm.key, pparm->key, 16); + _rtw_memcpy(sta_pparm.addr, get_bssid(pmlmepriv), ETH_ALEN); + set_stakey_hdl(padapter, (u8 *) &sta_pparm); + } + +enable_mc: + //allow multicast packets to driver + rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr); + + return H2C_SUCCESS; +} + +u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf) +{ + u16 ctrl = 0; + s16 cam_id = 0; + bool used; + u8 ret = H2C_SUCCESS; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; + + if(pparm->algorithm == _NO_PRIVACY_) + goto write_to_cam; + + psta = rtw_get_stainfo(pstapriv, pparm->addr); + if (!psta) { + DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr)); + ret = H2C_REJECTED; + goto exit; + } + + pmlmeinfo->enc_algo = pparm->algorithm; + cam_id = rtw_camid_alloc(padapter, psta, 0, &used); + if (cam_id < 0) + goto exit; + + #ifdef DYNAMIC_CAMID_ALLOC + /* cam entry searched is group key */ + if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) { + s16 camid_clr; + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid); + + /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */ + rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH); + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL); + + /* clear group key */ + while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) { + DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr); + clear_cam_entry(padapter, camid_clr); + rtw_camid_free(padapter, camid_clr); + } + } + #endif + +write_to_cam: + if(pparm->algorithm == _NO_PRIVACY_) { + while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) { + DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id); + clear_cam_entry(padapter, cam_id); + rtw_camid_free(padapter,cam_id); + } + } else { + DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n", + cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm)); + ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; + write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); + } + ret = H2C_SUCCESS_RSP; + +exit: + return ret; +} + +u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); + + if(!psta) + return H2C_SUCCESS; + +#ifdef CONFIG_80211N_HT + if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || + ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + { + //pmlmeinfo->ADDBA_retry_count = 0; + //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); + //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); + issue_addba_req(padapter, pparm->addr, (u8)pparm->tid); + //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); + _set_timer(&psta->addba_retry_timer, ADDBA_TO); + } +#ifdef CONFIG_TDLS + else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&& + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE) ) + { + issue_addba_req(padapter, pparm->addr, (u8)pparm->tid); + _set_timer(&psta->addba_retry_timer, ADDBA_TO); + } +#endif //CONFIG + else + { + psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); + } +#endif //CONFIG_80211N_HT + return H2C_SUCCESS; +} + + +u8 chk_bmc_sleepq_cmd(_adapter* padapter) +{ + struct cmd_obj *ph2c; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + u8 res = _SUCCESS; + +_func_enter_; + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + res= _FAIL; + goto exit; + } + + init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + +exit: + +_func_exit_; + + return res; +} + +u8 set_tx_beacon_cmd(_adapter* padapter) +{ + struct cmd_obj *ph2c; + struct Tx_Beacon_param *ptxBeacon_parm; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 res = _SUCCESS; + int len_diff = 0; + +_func_enter_; + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + res= _FAIL; + goto exit; + } + + if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL) + { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX)); + + len_diff = update_hidden_ssid( + ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_ + , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_ + , pmlmeinfo->hidden_ssid_mode + ); + ptxBeacon_parm->network.IELength += len_diff; + + init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + + +exit: + +_func_exit_; + + return res; +} + + +u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf) +{ + u8 evt_code, evt_seq; + u16 evt_sz; + uint *peventbuf; + void (*event_callback)(_adapter *dev, u8 *pbuf); + struct evt_priv *pevt_priv = &(padapter->evtpriv); + + if (pbuf == NULL) + goto _abort_event_; + + peventbuf = (uint*)pbuf; + evt_sz = (u16)(*peventbuf&0xffff); + evt_seq = (u8)((*peventbuf>>24)&0x7f); + evt_code = (u8)((*peventbuf>>16)&0xff); + + + #ifdef CHECK_EVENT_SEQ + // checking event sequence... + if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) ) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f))); + + pevt_priv->event_seq = (evt_seq+1)&0x7f; + + goto _abort_event_; + } + #endif + + // checking if event code is valid + if (evt_code >= MAX_C2HEVT) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code)); + goto _abort_event_; + } + + // checking if event size match the event parm size + if ((wlanevents[evt_code].parmsize != 0) && + (wlanevents[evt_code].parmsize != evt_sz)) + { + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n", + evt_code, wlanevents[evt_code].parmsize, evt_sz)); + goto _abort_event_; + + } + + ATOMIC_INC(&pevt_priv->event_seq); + + peventbuf += 2; + + if(peventbuf) + { + event_callback = wlanevents[evt_code].event_callback; + event_callback(padapter, (u8*)peventbuf); + + pevt_priv->evt_done_cnt++; + } + + +_abort_event_: + + + return H2C_SUCCESS; + +} + +u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf) +{ + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + return H2C_SUCCESS; +} + +u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf) +{ +#ifdef CONFIG_AP_MODE + _irqL irqL; + struct sta_info *psta_bmc; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + + //for BC/MC Frames + psta_bmc = rtw_get_bcmc_stainfo(padapter); + if(!psta_bmc) + return H2C_SUCCESS; + + if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0)) + { +#ifndef CONFIG_PCI_HCI + rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows +#endif + //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta_bmc->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta_bmc->sleepq_len--; + if(psta_bmc->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + pxmitframe->attrib.triggered=1; + + if (xmitframe_hiq_filter(pxmitframe) == _TRUE) + pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ + + #if 0 + _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + #endif + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + } + + //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + if (rtw_get_intf_type(padapter) != RTW_PCIE) { + /* check hi queue and bmc_sleepq */ + rtw_chk_hi_queue_cmd(padapter); + } + } +#endif + + return H2C_SUCCESS; +} + +u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf) +{ + if(send_beacon(padapter)==_FAIL) + { + DBG_871X("issue_beacon, fail!\n"); + return H2C_PARAMETERS_ERROR; + } + + + if (padapter->registrypriv.wifi_spec == 1) + return H2C_SUCCESS; + + /* tx bc/mc frames after update TIM */ + chk_bmc_sleepq_hdl(padapter, NULL); + + return H2C_SUCCESS; +} + +/* +* according to channel +* add/remove WLAN_BSSID_EX.IEs's ERP ie +* set WLAN_BSSID_EX.SupportedRates +* update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie +*/ +void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch) +{ + u8 network_type,rate_len, total_rate_len,remainder_rate_len; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 erpinfo=0x4; + + if (ch >= 36) { + network_type = WIRELESS_11A; + total_rate_len = IEEE80211_NUM_OFDM_RATESLEN; + rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_); + } else { + network_type = WIRELESS_11BG; + total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN; + rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1); + } + + rtw_set_supported_rate(pnetwork->SupportedRates, network_type); + + UpdateBrateTbl(padapter, pnetwork->SupportedRates); + + if(total_rate_len > 8) + { + rate_len = 8; + remainder_rate_len = total_rate_len - 8; + } + else + { + rate_len = total_rate_len; + remainder_rate_len = 0; + } + + rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len); + + if(remainder_rate_len) + { + rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len); + } + else + { + rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_); + } + + pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork); +} + +#ifdef CONFIG_CONCURRENT_MODE +sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state) +{ + PADAPTER pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext; + struct mlme_ext_info *pbuddy_mlmeinfo; + + if(padapter == NULL) + return _FALSE; + + pbuddy_adapter = padapter->pbuddy_adapter; + + if(pbuddy_adapter == NULL) + return _FALSE; + + + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info); + + if((pbuddy_mlmeinfo->state&0x03) == state) + return _TRUE; + + return _FALSE; + +} +#endif /* CONFIG_CONCURRENT_MODE */ + +void rtw_join_done_chk_ch(_adapter *adapter, int join_res) +{ +#define DUMP_ADAPTERS_STATUS 0 + + struct dvobj_priv *dvobj; + _adapter *iface; + struct mlme_priv *mlme; + struct mlme_ext_priv *mlmeext; + u8 u_ch, u_offset, u_bw; + int i; + + dvobj = adapter_to_dvobj(adapter); + + if (DUMP_ADAPTERS_STATUS) { + DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter)); + dump_adapters_status(RTW_DBGDUMP , dvobj); + } + + if (join_res >= 0) { + if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) { + dump_adapters_status(RTW_DBGDUMP , dvobj); + rtw_warn_on(1); + } + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + mlme = &iface->mlmepriv; + mlmeext = &iface->mlmeextpriv; + + if (!iface || iface == adapter) + continue; + + if (check_fwstate(mlme, WIFI_AP_STATE) + && check_fwstate(mlme, WIFI_ASOC_STATE) + ) { + bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset + , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset); + + if (is_grouped == _FALSE) { + /* handle AP which need to switch ch setting */ + + /* restore original bw, adjust bw by registry setting on target ch */ + mlmeext->cur_bwmode = mlme->ori_bw; + mlmeext->cur_channel = u_ch; + rtw_adjust_chbw(iface + , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset); + + rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset + , &u_ch, &u_bw, &u_offset); + + rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network) + , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset); + + _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX)); + + rtw_start_bss_hdl_after_chbw_decided(iface); + } + + update_beacon(iface, 0, NULL, _TRUE); + } + + clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); + } + + #ifdef CONFIG_DFS_MASTER + rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED); + #endif + } else { + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + mlme = &iface->mlmepriv; + mlmeext = &iface->mlmeextpriv; + + if (!iface || iface == adapter) + continue; + + if (check_fwstate(mlme, WIFI_AP_STATE) + && check_fwstate(mlme, WIFI_ASOC_STATE)) + update_beacon(iface, 0, NULL, _TRUE); + + clr_fwstate(mlme, WIFI_OP_CH_SWITCHING); + } + #ifdef CONFIG_DFS_MASTER + rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED); + #endif + } + + if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) + set_channel_bwmode(adapter, u_ch, u_offset, u_bw); + + if (DUMP_ADAPTERS_STATUS) { + DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter)); + dump_adapters_status(RTW_DBGDUMP , dvobj); + } +} + +int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset) +{ + bool chbw_allow = _TRUE; + bool connect_allow = _TRUE; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + u8 cur_ch, cur_bw, cur_ch_offset; + u8 u_ch, u_offset, u_bw; + + u_ch = cur_ch = pmlmeext->cur_channel; + u_bw = cur_bw = pmlmeext->cur_bwmode; + u_offset = cur_ch_offset = pmlmeext->cur_ch_offset; + + if (!ch || !bw || !offset) { + connect_allow = _FALSE; + rtw_warn_on(1); + goto exit; + } + + if (cur_ch == 0) { + connect_allow = _FALSE; + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n" + , FUNC_ADPT_ARG(adapter), cur_ch); + rtw_warn_on(1); + goto exit; + } + DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + +#ifdef CONFIG_CONCURRENT_MODE +{ + struct dvobj_priv *dvobj; + _adapter *iface; + struct mlme_priv *mlme; + struct mlme_ext_priv *mlmeext; + u8 sta_num; + u8 ld_sta_num; + u8 lg_sta_num; + u8 ap_num; + u8 ld_ap_num; + int i; + + dvobj = adapter_to_dvobj(adapter); + + rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num); + DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n" + , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num); + + if (!ld_sta_num && !ap_num) { + /* consider linking STA? */ + goto connect_allow_hdl; + } + + if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) { + dump_adapters_status(RTW_DBGDUMP , dvobj); + rtw_warn_on(1); + } + DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n" + , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + + /* chbw_allow? */ + chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset + , u_ch, u_bw, u_offset); + + DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n" + , FUNC_ADPT_ARG(adapter), chbw_allow); + + if (chbw_allow == _TRUE) { + rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset); + rtw_warn_on(cur_ch != pmlmeext->cur_channel); + rtw_warn_on(cur_bw != pmlmeext->cur_bwmode); + rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset); + goto connect_allow_hdl; + } + + /* chbw_allow is _FALSE, connect allow? */ + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + mlme = &iface->mlmepriv; + mlmeext = &iface->mlmeextpriv; + + #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT + if (check_fwstate(mlme, WIFI_STATION_STATE) + && check_fwstate(mlme, WIFI_ASOC_STATE) + #if defined(CONFIG_P2P) + && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE) + #endif + ) { + connect_allow = _FALSE; + break; + } + #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */ + } + DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n" + , FUNC_ADPT_ARG(adapter), connect_allow); + + if (connect_allow == _FALSE) + goto exit; + +connect_allow_hdl: + /* connect_allow == _TRUE */ + + #ifdef CONFIG_DFS_MASTER + rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING); + #endif + + if (chbw_allow == _FALSE) { + u_ch = cur_ch; + u_bw = cur_bw; + u_offset = cur_ch_offset; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + mlme = &iface->mlmepriv; + mlmeext = &iface->mlmeextpriv; + + if (!iface || iface == adapter) + continue; + + if (check_fwstate(mlme, WIFI_AP_STATE) + && check_fwstate(mlme, WIFI_ASOC_STATE) + ) { + #ifdef CONFIG_SPCT_CH_SWITCH + if (1) + rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset); + else + #endif + rtw_sta_flush(iface, _FALSE); + + rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0); + set_fwstate(mlme, WIFI_OP_CH_SWITCHING); + } else if (check_fwstate(mlme, WIFI_STATION_STATE) + && check_fwstate(mlme, WIFI_ASOC_STATE) + ) { + rtw_disassoc_cmd(iface, 500, _FALSE); + rtw_indicate_disconnect(iface); + rtw_free_assoc_resources(iface, 1); + } + } + } +} +#endif /* CONFIG_CONCURRENT_MODE */ + +exit: + + if (connect_allow == _TRUE) { + DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset); + *ch = u_ch; + *bw = u_bw; + *offset = u_offset; + } + + return connect_allow == _TRUE ? _SUCCESS : _FAIL; +} + +/* Find union about ch, bw, ch_offset of all linked/linking interfaces */ +int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + int i; + u8 ch_ret = 0; + u8 bw_ret = CHANNEL_WIDTH_20; + u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + int num = 0; + + if (ch) *ch = 0; + if (bw) *bw = CHANNEL_WIDTH_20; + if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + for (i = 0; iiface_nums; i++) { + iface = dvobj->padapters[i]; + mlmeext = &iface->mlmeextpriv; + + if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING)) + continue; + + if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING)) + continue; + + if (include_self == _FALSE && adapter == iface) + continue; + + if (num == 0) { + ch_ret = mlmeext->cur_channel; + bw_ret = mlmeext->cur_bwmode; + offset_ret = mlmeext->cur_ch_offset; + num++; + continue; + } + + if (ch_ret != mlmeext->cur_channel) { + num = 0; + break; + } + + if (bw_ret < mlmeext->cur_bwmode) { + bw_ret = mlmeext->cur_bwmode; + offset_ret = mlmeext->cur_ch_offset; + } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) { + num = 0; + break; + } + + num++; + } + + if (num) { + if (ch) *ch = ch_ret; + if (bw) *bw = bw_ret; + if (offset) *offset = offset_ret; + } + + return num; +} + +inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset) +{ + return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1); +} + +inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset) +{ + return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0); +} + +void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num + , u8 *ap_num, u8 *ld_ap_num, bool include_self) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + struct mlme_ext_info *mlmeextinfo; + int i; + u8 sta_num_ret = 0; + u8 ld_sta_num_ret = 0; + u8 lg_sta_num_ret = 0; + u8 ap_num_ret = 0; + u8 ld_ap_num_ret = 0; + + if (sta_num) + *sta_num = 0; + if (ld_sta_num) + *ld_sta_num = 0; + if (lg_sta_num) + *lg_sta_num = 0; + if (ap_num) + *ap_num = 0; + if (ld_ap_num) + *ld_ap_num = 0; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + + if (include_self == _FALSE && iface == adapter) + continue; + + mlmeext = &iface->mlmeextpriv; + + if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) { + sta_num_ret++; + if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) + ld_sta_num_ret++; + if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE) + lg_sta_num_ret++; + } + + if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE + && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE + ) { + ap_num_ret++; + if (iface->stapriv.asoc_sta_count > 2) + ld_ap_num_ret++; + } + } + + if (sta_num) + *sta_num = sta_num_ret; + if (ld_sta_num) + *ld_sta_num = ld_sta_num_ret; + if (lg_sta_num) + *lg_sta_num = lg_sta_num_ret; + if (ap_num) + *ap_num = ap_num_ret; + if (ld_ap_num) + *ld_ap_num = ld_ap_num_ret; +} + +inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num + , u8 *ap_num, u8 *ld_ap_num) +{ + return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1); +} + +inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num + , u8 *ap_num, u8 *ld_ap_num) +{ + return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0); +} + +u8 set_ch_hdl(_adapter *padapter, u8 *pbuf) +{ + struct set_ch_parm *set_ch_parm; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + set_ch_parm = (struct set_ch_parm *)pbuf; + + DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", + FUNC_NDEV_ARG(padapter->pnetdev), + set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); + + pmlmeext->cur_channel = set_ch_parm->ch; + pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; + pmlmeext->cur_bwmode = set_ch_parm->bw; + + set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); + + return H2C_SUCCESS; +} + +u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct SetChannelPlan_param *setChannelPlan_param; + struct mlme_priv *mlme = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; + + if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) { + return H2C_PARAMETERS_ERROR; + } + + mlme->country_ent = setChannelPlan_param->country_ent; + mlme->ChannelPlan = setChannelPlan_param->channel_plan; + + 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 + rtw_reg_notify_by_driver(padapter); +#endif //CONFIG_IOCTL_CFG80211 + + return H2C_SUCCESS; +} + +u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf) +{ + struct LedBlink_param *ledBlink_param; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + ledBlink_param = (struct LedBlink_param *)pbuf; + + #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD + BlinkHandler((PLED_DATA)ledBlink_param->pLed); + #endif + + return H2C_SUCCESS; +} + +u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf) +{ +#ifdef CONFIG_DFS + struct SetChannelSwitch_param *setChannelSwitch_param; + u8 new_ch_no; + u8 gval8 = 0x00, sval8 = 0xff; + + if(!pbuf) + return H2C_PARAMETERS_ERROR; + + setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf; + new_ch_no = setChannelSwitch_param->new_ch_no; + + rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8); + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8); + + DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no); + SelectChannel(padapter, new_ch_no); + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8); + + rtw_disassoc_cmd(padapter, 0, _FALSE); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + rtw_free_network_queue(padapter, _TRUE); + + if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) { + DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no); + } + + return H2C_SUCCESS; +#else + return H2C_REJECTED; +#endif //CONFIG_DFS + +} + +u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf) +{ +#ifdef CONFIG_TDLS + _irqL irqL; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#ifdef CONFIG_TDLS_CH_SW + struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; +#endif + struct TDLSoption_param *TDLSoption; + struct sta_info *ptdls_sta = NULL; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u8 survey_channel, i, min, option; + struct tdls_txmgmt txmgmt; + u32 setchtime, resp_sleep = 0, wait_time; + u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if (!pbuf) + return H2C_PARAMETERS_ERROR; + + TDLSoption = (struct TDLSoption_param *)pbuf; + option = TDLSoption->option; + + if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) { + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr ); + if (ptdls_sta == NULL) { + return H2C_REJECTED; + } + } else { + if (!(option == TDLS_RS_RCR || option == TDLS_CH_SW_BACK)) + return H2C_REJECTED; + } + + //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + //DBG_871X("[%s] option:%d\n", __FUNCTION__, option); + + switch (option) { + case TDLS_ESTABLISHED: + { + /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */ + /* So we can receive all kinds of data frames. */ + u8 sta_band = 0; + + //leave ALL PS when TDLS is established + rtw_pwr_wakeup(padapter); + + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0); + DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr)); + + /* Set TDLS sta rate. */ + /* Update station supportRate */ + rtw_hal_update_sta_rate_mask(padapter, ptdls_sta); + if (pmlmeext->cur_channel > 14) { + if (ptdls_sta->ra_mask & 0xffff000) + sta_band |= WIRELESS_11_5N ; + + if (ptdls_sta->ra_mask & 0xff0) + sta_band |= WIRELESS_11A; + + /* 5G band */ + #ifdef CONFIG_80211AC_VHT + if (ptdls_sta->vhtpriv.vht_option) + sta_band = WIRELESS_11_5AC; + #endif + + } else { + if (ptdls_sta->ra_mask & 0xffff000) + sta_band |= WIRELESS_11_24N; + + if (ptdls_sta->ra_mask & 0xff0) + sta_band |= WIRELESS_11G; + + if (ptdls_sta->ra_mask & 0x0f) + sta_band |= WIRELESS_11B; + } + ptdls_sta->wireless_mode = sta_band; + ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta); + set_sta_rate(padapter, ptdls_sta); + rtw_sta_media_status_rpt(padapter, ptdls_sta, 1); + /* Sta mode */ + rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE); + break; + } + case TDLS_ISSUE_PTI: + ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE; + issue_tdls_peer_traffic_indication(padapter, ptdls_sta); + _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME); + break; +#ifdef CONFIG_TDLS_CH_SW + case TDLS_CH_SW_RESP: + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + txmgmt.status_code = 0; + _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN); + + issue_nulldata(padapter, NULL, 1, 0, 0); + + DBG_871X("issue tdls channel switch response\n"); + issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE); + resp_sleep = 5; + rtw_msleep_os(resp_sleep); + + /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */ + /* then we just SelectChannel to AP's channel*/ + if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) { + SelectChannel(padapter, padapter->mlmeextpriv.cur_channel); + issue_nulldata(padapter, NULL, 0, 0, 0); + pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + break; + } + + _set_timer(&ptdls_sta->delay_timer, pmlmeinfo->bcn_interval - 40); + + /* Continue following actions */ + + case TDLS_CH_SW: + issue_nulldata(padapter, NULL, 1, 0, 0); + _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout)/1000); + + setchtime = rtw_systime_to_ms(rtw_get_current_time()); + SelectChannel(padapter, pchsw_info->off_ch_num); + setchtime = rtw_systime_to_ms(rtw_get_current_time()) - setchtime; + setchtime += resp_sleep; + + if (pmlmeext->cur_channel != rtw_get_oper_ch(padapter)) + issue_nulldata(padapter, NULL, 0, 0, 0); + pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE); + + if ((u32)ptdls_sta->ch_switch_time/1000 > setchtime) + wait_time = (u32)ptdls_sta->ch_switch_time/1000 - setchtime; + else + wait_time = 0; + + if (wait_time > 0) + rtw_msleep_os(wait_time); + + issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0); + issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0); + + break; + case TDLS_CH_SW_BACK: + pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + SelectChannel(padapter, padapter->mlmeextpriv.cur_channel); + issue_nulldata(padapter, NULL, 0, 0, 0); + break; +#endif + case TDLS_RS_RCR: + rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0); + DBG_871X("wirte REG_RCR, set bit6 on\n"); + break; + case TDLS_TEAR_STA: +#ifdef CONFIG_TDLS_CH_SW + if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) { + pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE | + TDLS_CH_SWITCH_ON_STATE | + TDLS_PEER_AT_OFF_STATE); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN); + } +#endif + rtw_sta_media_status_rpt(padapter, ptdls_sta, 0); + free_tdls_sta(padapter, ptdls_sta); + break; + } + + //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); + + return H2C_SUCCESS; +#else + return H2C_REJECTED; +#endif /* CONFIG_TDLS */ + +} + +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; +} + +u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf) +{ + + struct readMAC_parm *preadmacparm = NULL; + u8 sz = 0; + u32 addr = 0; + u32 value = 0; + + if (!pbuf) + return H2C_PARAMETERS_ERROR; + + preadmacparm = (struct readMAC_parm *) pbuf; + sz = preadmacparm->len; + addr = preadmacparm->addr; + value = 0; + + switch (sz) { + case 1: + value = rtw_read8(padapter, addr); + break; + case 2: + value = rtw_read16(padapter, addr); + break; + case 4: + value = rtw_read32(padapter, addr); + break; + default: + DBG_871X("%s: Unknown size\n", __func__); + break; + } + DBG_871X("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value); + + return H2C_SUCCESS; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp.c new file mode 100644 index 00000000..ef571140 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp.c @@ -0,0 +1,3540 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MP_C_ +#include +#ifdef PLATFORM_FREEBSD +#include /* for RFHIGHPID */ +#endif + +#include "../hal/phydm/phydm_precomp.h" +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A) +#include +#endif + +#ifdef CONFIG_MP_VHT_HW_TX_MODE +#define CEILING_POS(X) ((X - (int)(X)) > 0 ? (int)(X + 1) : (int)(X)) +#define CEILING_NEG(X) ((X - (int)(X)) < 0 ? (int)(X - 1) : (int)(X)) +#define ceil(X) (((X) > 0) ? CEILING_POS(X) : CEILING_NEG(X)) + +int rtfloor(float x) +{ +int i = x - 2; +while +(++i <= x - 1); +return i; +} +#endif + +#ifdef CONFIG_MP_INCLUDED + +u32 read_macreg(_adapter *padapter, u32 addr, u32 sz) +{ + u32 val = 0; + + switch(sz) + { + case 1: + val = rtw_read8(padapter, addr); + break; + case 2: + val = rtw_read16(padapter, addr); + break; + case 4: + val = rtw_read32(padapter, addr); + break; + default: + val = 0xffffffff; + break; + } + + return val; + +} + +void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz) +{ + switch(sz) + { + case 1: + rtw_write8(padapter, addr, (u8)val); + break; + case 2: + rtw_write16(padapter, addr, (u16)val); + break; + case 4: + rtw_write32(padapter, addr, val); + break; + default: + break; + } + +} + +u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask) +{ + return rtw_hal_read_bbreg(padapter, addr, bitmask); +} + +void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val) +{ + rtw_hal_write_bbreg(padapter, addr, bitmask, val); +} + +u32 _read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask) +{ + return rtw_hal_read_rfreg(padapter, rfpath, addr, bitmask); +} + +void _write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val) +{ + rtw_hal_write_rfreg(padapter, rfpath, addr, bitmask, val); +} + +u32 read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr) +{ + return _read_rfreg(padapter, rfpath, addr, bRFRegOffsetMask); +} + +void write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 val) +{ + _write_rfreg(padapter, rfpath, addr, bRFRegOffsetMask, val); +} + +static void _init_mp_priv_(struct mp_priv *pmp_priv) +{ + WLAN_BSSID_EX *pnetwork; + + _rtw_memset(pmp_priv, 0, sizeof(struct mp_priv)); + + pmp_priv->mode = MP_OFF; + + pmp_priv->channel = 1; + pmp_priv->bandwidth = CHANNEL_WIDTH_20; + pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + pmp_priv->rateidx = RATE_1M; + pmp_priv->txpoweridx = 0x2A; + + pmp_priv->antenna_tx = ANTENNA_A; + pmp_priv->antenna_rx = ANTENNA_AB; + + pmp_priv->check_mp_pkt = 0; + + pmp_priv->tx_pktcount = 0; + + pmp_priv->rx_bssidpktcount=0; + pmp_priv->rx_pktcount = 0; + pmp_priv->rx_crcerrpktcount = 0; + + pmp_priv->network_macaddr[0] = 0x00; + pmp_priv->network_macaddr[1] = 0xE0; + pmp_priv->network_macaddr[2] = 0x4C; + pmp_priv->network_macaddr[3] = 0x87; + pmp_priv->network_macaddr[4] = 0x66; + pmp_priv->network_macaddr[5] = 0x55; + + pmp_priv->bSetRxBssid = _FALSE; + pmp_priv->bRTWSmbCfg = _FALSE; + + pnetwork = &pmp_priv->mp_network.network; + _rtw_memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN); + + pnetwork->Ssid.SsidLength = 8; + _rtw_memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength); + + pmp_priv->tx.payload = 2; +#ifdef CONFIG_80211N_HT + pmp_priv->tx.attrib.ht_en = 1; +#endif + +} + +#ifdef PLATFORM_WINDOWS +/* +void mp_wi_callback( + IN NDIS_WORK_ITEM* pwk_item, + IN PVOID cntx + ) +{ + _adapter* padapter =(_adapter *)cntx; + struct mp_priv *pmppriv=&padapter->mppriv; + struct mp_wi_cntx *pmp_wi_cntx=&pmppriv->wi_cntx; + + // Execute specified action. + if(pmp_wi_cntx->curractfunc != NULL) + { + LARGE_INTEGER cur_time; + ULONGLONG start_time, end_time; + NdisGetCurrentSystemTime(&cur_time); // driver version + start_time = cur_time.QuadPart/10; // The return value is in microsecond + + pmp_wi_cntx->curractfunc(padapter); + + NdisGetCurrentSystemTime(&cur_time); // driver version + end_time = cur_time.QuadPart/10; // The return value is in microsecond + + RT_TRACE(_module_mp_, _drv_info_, + ("WorkItemActType: %d, time spent: %I64d us\n", + pmp_wi_cntx->param.act_type, (end_time-start_time))); + } + + NdisAcquireSpinLock(&(pmp_wi_cntx->mp_wi_lock)); + pmp_wi_cntx->bmp_wi_progress= _FALSE; + NdisReleaseSpinLock(&(pmp_wi_cntx->mp_wi_lock)); + + if (pmp_wi_cntx->bmpdrv_unload) + { + NdisSetEvent(&(pmp_wi_cntx->mp_wi_evt)); + } + +} +*/ + +static int init_mp_priv_by_os(struct mp_priv *pmp_priv) +{ + struct mp_wi_cntx *pmp_wi_cntx; + + if (pmp_priv == NULL) return _FAIL; + + pmp_priv->rx_testcnt = 0; + pmp_priv->rx_testcnt1 = 0; + pmp_priv->rx_testcnt2 = 0; + + pmp_priv->tx_testcnt = 0; + pmp_priv->tx_testcnt1 = 0; + + pmp_wi_cntx = &pmp_priv->wi_cntx + pmp_wi_cntx->bmpdrv_unload = _FALSE; + pmp_wi_cntx->bmp_wi_progress = _FALSE; + pmp_wi_cntx->curractfunc = NULL; + + return _SUCCESS; +} +#endif + +#ifdef PLATFORM_LINUX +static int init_mp_priv_by_os(struct mp_priv *pmp_priv) +{ + int i, res; + struct mp_xmit_frame *pmp_xmitframe; + + if (pmp_priv == NULL) return _FAIL; + + _rtw_init_queue(&pmp_priv->free_mp_xmitqueue); + + pmp_priv->pallocated_mp_xmitframe_buf = NULL; + pmp_priv->pallocated_mp_xmitframe_buf = rtw_zmalloc(NR_MP_XMITFRAME * sizeof(struct mp_xmit_frame) + 4); + if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) { + res = _FAIL; + goto _exit_init_mp_priv; + } + + pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + 4 - ((SIZE_PTR) (pmp_priv->pallocated_mp_xmitframe_buf) & 3); + + pmp_xmitframe = (struct mp_xmit_frame*)pmp_priv->pmp_xmtframe_buf; + + for (i = 0; i < NR_MP_XMITFRAME; i++) + { + _rtw_init_listhead(&pmp_xmitframe->list); + rtw_list_insert_tail(&pmp_xmitframe->list, &pmp_priv->free_mp_xmitqueue.queue); + + pmp_xmitframe->pkt = NULL; + pmp_xmitframe->frame_tag = MP_FRAMETAG; + pmp_xmitframe->padapter = pmp_priv->papdater; + + pmp_xmitframe++; + } + + pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; + + res = _SUCCESS; + +_exit_init_mp_priv: + + return res; +} +#endif + +static void mp_init_xmit_attrib(struct mp_tx *pmptx, PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + struct pkt_attrib *pattrib; + + // init xmitframe attribute + pattrib = &pmptx->attrib; + _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib)); + _rtw_memset(pmptx->desc, 0, TXDESC_SIZE); + + pattrib->ether_type = 0x8712; + #if 0 + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + #endif + _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN); + +// pattrib->dhcp_pkt = 0; +// pattrib->pktlen = 0; + pattrib->ack_policy = 0; +// pattrib->pkt_hdrlen = ETH_HLEN; + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA; + pattrib->priority = 0; + pattrib->qsel = pattrib->priority; +// do_queue_select(padapter, pattrib); + pattrib->nr_frags = 1; + pattrib->encrypt = 0; + pattrib->bswenc = _FALSE; + pattrib->qos_en = _FALSE; + + pattrib->pktlen = 1500; + +#ifdef CONFIG_80211AC_VHT + if (pHalData->rf_type == RF_1T1R) + pattrib->raid = RATEID_IDX_VHT_1SS; + else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R) + pattrib->raid = RATEID_IDX_VHT_2SS; + else if (pHalData->rf_type == RF_3T3R) + pattrib->raid = RATEID_IDX_VHT_3SS; + else + pattrib->raid = RATEID_IDX_BGN_40M_1SS; +#endif +} + +s32 init_mp_priv(PADAPTER padapter) +{ + struct mp_priv *pmppriv = &padapter->mppriv; + PHAL_DATA_TYPE pHalData; + + pHalData = GET_HAL_DATA(padapter); + + _init_mp_priv_(pmppriv); + pmppriv->papdater = padapter; + pmppriv->mp_dm =0; + pmppriv->tx.stop = 1; + pmppriv->bSetTxPower = 0; /*for manually set tx power*/ + pmppriv->bTxBufCkFail = _FALSE; + pmppriv->pktInterval = 0; + pmppriv->pktLength = 1000; + + mp_init_xmit_attrib(&pmppriv->tx, padapter); + + switch (padapter->registrypriv.rf_config) { + case RF_1T1R: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_A; + break; + case RF_1T2R: + default: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T2R: + case RF_2T2R_GREEN: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T4R: + pmppriv->antenna_tx = ANTENNA_BC; + pmppriv->antenna_rx = ANTENNA_ABCD; + break; + } + + pHalData->AntennaRxPath = pmppriv->antenna_rx; + pHalData->AntennaTxPath = pmppriv->antenna_tx; + + return _SUCCESS; +} + +void free_mp_priv(struct mp_priv *pmp_priv) +{ + if (pmp_priv->pallocated_mp_xmitframe_buf) { + rtw_mfree(pmp_priv->pallocated_mp_xmitframe_buf, 0); + pmp_priv->pallocated_mp_xmitframe_buf = NULL; + } + pmp_priv->pmp_xmtframe_buf = NULL; +} + + +static VOID PHY_IQCalibrate_default( + IN PADAPTER pAdapter, + IN BOOLEAN bReCovery + ) +{ + DBG_871X("%s\n", __func__); +} + +static VOID PHY_LCCalibrate_default( + IN PADAPTER pAdapter + ) +{ + DBG_871X("%s\n", __func__); +} + +static VOID PHY_SetRFPathSwitch_default( + IN PADAPTER pAdapter, + IN BOOLEAN bMain + ) +{ + DBG_871X("%s\n", __func__); +} + + +void mpt_InitHWConfig(PADAPTER Adapter) +{ + if (IS_HARDWARE_TYPE_8723B(Adapter)) { + // TODO: <20130114, Kordan> The following setting is only for DPDT and Fixed board type. + // TODO: A better solution is configure it according EFUSE during the run-time. + + PHY_SetMacReg(Adapter, 0x64, BIT20, 0x0); //0x66[4]=0 + PHY_SetMacReg(Adapter, 0x64, BIT24, 0x0); //0x66[8]=0 + PHY_SetMacReg(Adapter, 0x40, BIT4, 0x0); //0x40[4]=0 + PHY_SetMacReg(Adapter, 0x40, BIT3, 0x1); //0x40[3]=1 + PHY_SetMacReg(Adapter, 0x4C, BIT24, 0x1); //0x4C[24:23]=10 + PHY_SetMacReg(Adapter, 0x4C, BIT23, 0x0); //0x4C[24:23]=10 + PHY_SetBBReg(Adapter, 0x944, BIT1|BIT0, 0x3); //0x944[1:0]=11 + PHY_SetBBReg(Adapter, 0x930, bMaskByte0, 0x77); //0x930[7:0]=77 + PHY_SetMacReg(Adapter, 0x38, BIT11, 0x1); //0x38[11]=1 + + // TODO: <20130206, Kordan> The default setting is wrong, hard-coded here. + PHY_SetMacReg(Adapter, 0x778, 0x3, 0x3); // Turn off hardware PTA control (Asked by Scott) + PHY_SetMacReg(Adapter, 0x64, bMaskDWord, 0x36000000); //Fix BT S0/S1 + PHY_SetMacReg(Adapter, 0x948, bMaskDWord, 0x0); //Fix BT can't Tx + + /* <20130522, Kordan> Turn off equalizer to improve Rx sensitivity. (Asked by EEChou) */ + PHY_SetBBReg(Adapter, 0xA00, BIT8, 0x0); /*0xA01[0] = 0*/ + } else if (IS_HARDWARE_TYPE_8821(Adapter)) { + /* <20131121, VincentL> Add for 8821AU DPDT setting and fix switching antenna issue (Asked by Rock) + <20131122, VincentL> Enable for all 8821A/8811AU (Asked by Alex)*/ + PHY_SetMacReg(Adapter, 0x4C, BIT23, 0x0); /*0x4C[23:22]=01*/ + PHY_SetMacReg(Adapter, 0x4C, BIT22, 0x1); /*0x4C[23:22]=01*/ + } else if (IS_HARDWARE_TYPE_8188ES(Adapter)) + PHY_SetMacReg(Adapter, 0x4C , BIT23, 0); /*select DPDT_P and DPDT_N as output pin*/ +#ifdef CONFIG_RTL8814A + else if (IS_HARDWARE_TYPE_8814A(Adapter)) + PlatformEFIOWrite2Byte(Adapter, REG_RXFLTMAP1_8814A, 0x2000); +#endif + /* + else if(IS_HARDWARE_TYPE_8822B(Adapter)) + { + PlatformEFIOWrite2Byte(Adapter, REG_RXFLTMAP1_8822B, 0x2000); + }*/ +} + +#ifdef CONFIG_RTL8188E +#define PHY_IQCalibrate(a,b) PHY_IQCalibrate_8188E(a,b) +#define PHY_LCCalibrate(a) PHY_LCCalibrate_8188E(&(GET_HAL_DATA(a)->odmpriv)) +#define PHY_SetRFPathSwitch(a,b) PHY_SetRFPathSwitch_8188E(a,b) +#endif + +#ifdef CONFIG_RTL8814A +#define PHY_IQCalibrate(a,b) PHY_IQCalibrate_8814A(&(GET_HAL_DATA(a)->odmpriv), b) +#define PHY_LCCalibrate(a) PHY_LCCalibrate_8814A(&(GET_HAL_DATA(a)->odmpriv)) +#define PHY_SetRFPathSwitch(a,b) PHY_SetRFPathSwitch_8814A(a,b) +#endif /* CONFIG_RTL8814A */ + +#ifdef CONFIG_RTL8812A +#define PHY_IQCalibrate(_Adapter, b) PHY_IQCalibrate_8812A(_Adapter, b) +#define PHY_LCCalibrate(_Adapter) PHY_LCCalibrate_8812A(&(GET_HAL_DATA(_Adapter)->odmpriv)) +#define PHY_SetRFPathSwitch(_Adapter, b) PHY_SetRFPathSwitch_8812A(_Adapter, b) +#endif + +#ifdef CONFIG_RTL8821A +#define PHY_IQCalibrate(_Adapter, b) PHY_IQCalibrate_8821A(&(GET_HAL_DATA(_Adapter)->odmpriv), b) +#define PHY_LCCalibrate(_Adapter) PHY_LCCalibrate_8821A(&(GET_HAL_DATA(_Adapter)->odmpriv)) +#define PHY_SetRFPathSwitch(_Adapter, b) PHY_SetRFPathSwitch_8812A(_Adapter, b) +#endif + +#ifdef CONFIG_RTL8192E +#define PHY_IQCalibrate(a,b) PHY_IQCalibrate_8192E(a,b) +#define PHY_LCCalibrate(a) PHY_LCCalibrate_8192E(&(GET_HAL_DATA(a)->odmpriv)) +#define PHY_SetRFPathSwitch(a,b) PHY_SetRFPathSwitch_8192E(a,b) +#endif //CONFIG_RTL8812A_8821A + +#ifdef CONFIG_RTL8723B +static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) +{ + PHAL_DATA_TYPE pHalData; + 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; + + 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 + +#ifdef CONFIG_RTL8703B +static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) +{ + PHY_IQCalibrate_8703B(padapter, bReCovery); +} + + +#define PHY_LCCalibrate(a) PHY_LCCalibrate_8703B(&(GET_HAL_DATA(a)->odmpriv)) +#define PHY_SetRFPathSwitch(a, b) +#endif + +#ifdef CONFIG_RTL8188F +static void PHY_IQCalibrate(PADAPTER padapter, u8 bReCovery) +{ + PHY_IQCalibrate_8188F(padapter, bReCovery, _FALSE); +} + + +#define PHY_LCCalibrate(a) PHY_LCCalibrate_8188F(&(GET_HAL_DATA(a)->odmpriv)) +#define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188F(a, b) +#endif + +s32 +MPT_InitializeAdapter( + IN PADAPTER pAdapter, + IN u8 Channel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + s32 rtStatus = _SUCCESS; + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + u32 ledsetting; + struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; + + pMptCtx->bMptDrvUnload = _FALSE; + pMptCtx->bMassProdTest = _FALSE; + pMptCtx->bMptIndexEven = _TRUE; //default gain index is -6.0db + pMptCtx->h2cReqNum = 0x0; + //init for BT MP +#if defined(CONFIG_RTL8723B) + pMptCtx->bMPh2c_timeout = _FALSE; + pMptCtx->MptH2cRspEvent = _FALSE; + pMptCtx->MptBtC2hEvent = _FALSE; + _rtw_init_sema(&pMptCtx->MPh2c_Sema, 0); + _init_timer( &pMptCtx->MPh2c_timeout_timer, pAdapter->pnetdev, MPh2c_timeout_handle, pAdapter ); +#endif + + mpt_InitHWConfig(pAdapter); + +#ifdef CONFIG_RTL8723B + rtl8723b_InitAntenna_Selection(pAdapter); + if (IS_HARDWARE_TYPE_8723B(pAdapter)) + { + + /* <20130522, Kordan> Turn off equalizer to improve Rx sensitivity. (Asked by EEChou)*/ + PHY_SetBBReg(pAdapter, 0xA00, BIT8, 0x0); + PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); /*default use Main*/ + /*<20130522, Kordan> 0x51 and 0x71 should be set immediately after path switched, or they might be overwritten. */ + if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90)) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B10E); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B04E); + } + /*set ant to wifi side in mp mode*/ + rtw_write16(pAdapter, 0x870, 0x300); + rtw_write16(pAdapter, 0x860, 0x110); +#endif + + pMptCtx->bMptWorkItemInProgress = _FALSE; + pMptCtx->CurrMptAct = NULL; + pMptCtx->MptRfPath = ODM_RF_PATH_A; + //------------------------------------------------------------------------- + // Don't accept any packets + rtw_write32(pAdapter, REG_RCR, 0); + + //ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); + //rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS); + + //rtw_write32(pAdapter, REG_LEDCFG0, 0x08080); + ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); + + + PHY_LCCalibrate(pAdapter); + PHY_IQCalibrate(pAdapter, _FALSE); + //dm_CheckTXPowerTracking(&pHalData->odmpriv); //trigger thermal meter + + PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //default use Main + + pMptCtx->backup0xc50 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); + pMptCtx->backup0xc58 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); + pMptCtx->backup0xc30 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); + pMptCtx->backup0x52_RF_A = (u1Byte)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); + pMptCtx->backup0x52_RF_B = (u1Byte)PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0); +#ifdef CONFIG_RTL8188E + rtw_write32(pAdapter, REG_MACID_NO_LINK_0, 0x0); + rtw_write32(pAdapter, REG_MACID_NO_LINK_1, 0x0); +#endif +#ifdef CONFIG_RTL8814A + if (IS_HARDWARE_TYPE_8814A(pAdapter)) { + pHalData->BackUp_IG_REG_4_Chnl_Section[0] = (u1Byte)PHY_QueryBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0); + pHalData->BackUp_IG_REG_4_Chnl_Section[1] = (u1Byte)PHY_QueryBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0); + pHalData->BackUp_IG_REG_4_Chnl_Section[2] = (u1Byte)PHY_QueryBBReg(pAdapter, rC_IGI_Jaguar2, bMaskByte0); + pHalData->BackUp_IG_REG_4_Chnl_Section[3] = (u1Byte)PHY_QueryBBReg(pAdapter, rD_IGI_Jaguar2, bMaskByte0); + } +#endif + return rtStatus; +} + +/*----------------------------------------------------------------------------- + * Function: MPT_DeInitAdapter() + * + * Overview: Extra DeInitialization for Mass Production Test. + * + * Input: PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/08/2007 MHC Create Version 0. + * 05/18/2007 MHC Add normal driver MPHalt code. + * + *---------------------------------------------------------------------------*/ +VOID +MPT_DeInitAdapter( + IN PADAPTER pAdapter + ) +{ + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + + pMptCtx->bMptDrvUnload = _TRUE; + #if defined(CONFIG_RTL8723B) + _rtw_free_sema(&(pMptCtx->MPh2c_Sema)); + _cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer); + #endif + #if defined(CONFIG_RTL8723B) + PHY_SetBBReg(pAdapter,0xA01, BIT0, 1); ///suggestion by jerry for MP Rx. + #endif +#if 0 // for Windows + PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) ); + + while(pMptCtx->bMptWorkItemInProgress) + { + if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50)) + { + break; + } + } + NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); +#endif +} + +static u8 mpt_ProStartTest(PADAPTER padapter) +{ + PMPT_CONTEXT pMptCtx = &padapter->mppriv.MptCtx; + + pMptCtx->bMassProdTest = _TRUE; + pMptCtx->bStartContTx = _FALSE; + pMptCtx->bCckContTx = _FALSE; + pMptCtx->bOfdmContTx = _FALSE; + pMptCtx->bSingleCarrier = _FALSE; + pMptCtx->bCarrierSuppression = _FALSE; + pMptCtx->bSingleTone = _FALSE; + pMptCtx->HWTxmode = PACKETS_TX; + + return _SUCCESS; +} + +/* + * General use + */ +s32 SetPowerTracking(PADAPTER padapter, u8 enable) +{ + + hal_mpt_SetPowerTracking(padapter, enable); + return 0; +} + +void GetPowerTracking(PADAPTER padapter, u8 *enable) +{ + hal_mpt_GetPowerTracking(padapter, enable); +} + +static void disable_dm(PADAPTER padapter) +{ + u8 v8; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + + //3 1. disable firmware dynamic mechanism + // disable Power Training, Rate Adaptive + v8 = rtw_read8(padapter, REG_BCN_CTRL); + v8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, v8); + + //3 2. disable driver dynamic mechanism + rtw_phydm_func_disable_all(padapter); + + // enable APK, LCK and IQK but disable power tracking + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE; + rtw_phydm_func_set(padapter, ODM_RF_CALIBRATION); + +//#ifdef CONFIG_BT_COEXIST +// rtw_btcoex_Switch(padapter, 0); //remove for BT MP Down. +//#endif +} + + +void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + + if (bstart==1){ + DBG_871X("in MPT_PwrCtlDM start\n"); + rtw_phydm_func_set(padapter, ODM_RF_TX_PWR_TRACK | ODM_RF_CALIBRATION); + + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE; + padapter->mppriv.mp_dm =1; + + }else{ + DBG_871X("in MPT_PwrCtlDM stop \n"); + disable_dm(padapter); + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE; + padapter->mppriv.mp_dm = 0; + { + TXPWRTRACK_CFG c; + u1Byte chnl =0 ; + _rtw_memset(&c, 0, sizeof(TXPWRTRACK_CFG)); + ConfigureTxpowerTrack(pDM_Odm, &c); + ODM_ClearTxPowerTrackingState(pDM_Odm); + if (*c.ODM_TxPwrTrackSetPwr) { + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, ODM_RF_PATH_A, chnl); + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, ODM_RF_PATH_B, chnl); + } + } + } + +} + + +u32 mp_join(PADAPTER padapter,u8 mode) +{ + WLAN_BSSID_EX bssid; + struct sta_info *psta; + u32 length; + u8 val8; + _irqL irqL; + s32 res = _SUCCESS; + + struct mp_priv *pmppriv = &padapter->mppriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + +#ifdef CONFIG_IOCTL_CFG80211 + struct wireless_dev *pwdev = padapter->rtw_wdev; +#endif //#ifdef CONFIG_IOCTL_CFG80211 + // 1. initialize a new WLAN_BSSID_EX + _rtw_memset(&bssid, 0, sizeof(WLAN_BSSID_EX)); + DBG_8192C("%s ,pmppriv->network_macaddr=%x %x %x %x %x %x \n",__func__, + pmppriv->network_macaddr[0],pmppriv->network_macaddr[1],pmppriv->network_macaddr[2],pmppriv->network_macaddr[3],pmppriv->network_macaddr[4],pmppriv->network_macaddr[5]); + _rtw_memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN); + + if( mode==WIFI_FW_ADHOC_STATE ){ + bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc"); + _rtw_memcpy(bssid.Ssid.Ssid, (u8*)"mp_pseudo_adhoc", bssid.Ssid.SsidLength); + bssid.InfrastructureMode = Ndis802_11IBSS; + bssid.NetworkTypeInUse = Ndis802_11DS; + bssid.IELength = 0; + bssid.Configuration.DSConfig=pmppriv->channel; + + }else if(mode==WIFI_FW_STATION_STATE){ + bssid.Ssid.SsidLength = strlen("mp_pseudo_STATION"); + _rtw_memcpy(bssid.Ssid.Ssid, (u8*)"mp_pseudo_STATION", bssid.Ssid.SsidLength); + bssid.InfrastructureMode = Ndis802_11Infrastructure; + bssid.NetworkTypeInUse = Ndis802_11DS; + bssid.IELength = 0; + } + + length = get_WLAN_BSSID_EX_sz(&bssid); + if (length % 4) + bssid.Length = ((length >> 2) + 1) << 2; //round up to multiple of 4 bytes. + else + bssid.Length = length; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + goto end_of_mp_start_test; + + //init mp_start_test status + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + rtw_disassoc_cmd(padapter, 500, _TRUE); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + } + pmppriv->prev_fw_state = get_fwstate(pmlmepriv); + pmlmepriv->fw_state = WIFI_MP_STATE; + + set_fwstate(pmlmepriv, _FW_UNDER_LINKING); + + //3 2. create a new psta for mp driver + //clear psta in the cur_network, if any + psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress); + if (psta == NULL) { + RT_TRACE(_module_mp_, _drv_err_, ("mp_start_test: Can't alloc sta_info!\n")); + pmlmepriv->fw_state = pmppriv->prev_fw_state; + res = _FAIL; + goto end_of_mp_start_test; + } + set_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE); + //3 3. join psudo AdHoc + tgt_network->join_res = 1; + tgt_network->aid = psta->aid = 1; + + _rtw_memcpy(&padapter->registrypriv.dev_network, &bssid, length); + rtw_update_registrypriv_dev_network(padapter); + _rtw_memcpy(&tgt_network->network,&padapter->registrypriv.dev_network, padapter->registrypriv.dev_network.Length); + _rtw_memcpy(pnetwork,&padapter->registrypriv.dev_network, padapter->registrypriv.dev_network.Length); + + rtw_indicate_connect(padapter); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + set_fwstate(pmlmepriv,_FW_LINKED); + +end_of_mp_start_test: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + if(1) //(res == _SUCCESS) + { + // set MSR to WIFI_FW_ADHOC_STATE + if( mode==WIFI_FW_ADHOC_STATE ){ + + val8 = rtw_read8(padapter, MSR) & 0xFC; // 0x0102 + val8 |= WIFI_FW_ADHOC_STATE; + rtw_write8(padapter, MSR, val8); // Link in ad hoc network + } + else { + Set_MSR(padapter, WIFI_FW_STATION_STATE); + + DBG_8192C("%s , pmppriv->network_macaddr =%x %x %x %x %x %x\n",__func__, + pmppriv->network_macaddr[0],pmppriv->network_macaddr[1],pmppriv->network_macaddr[2],pmppriv->network_macaddr[3],pmppriv->network_macaddr[4],pmppriv->network_macaddr[5]); + + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmppriv->network_macaddr); + } + } + + return res; +} +//This function initializes the DUT to the MP test mode +s32 mp_start_test(PADAPTER padapter) +{ + struct mp_priv *pmppriv = &padapter->mppriv; + s32 res = _SUCCESS; + + padapter->registrypriv.mp_mode = 1; + + //3 disable dynamic mechanism + disable_dm(padapter); + #ifdef CONFIG_RTL8814A + rtl8814_InitHalDm(padapter); + #endif /* CONFIG_RTL8814A */ + #ifdef CONFIG_RTL8812A + rtl8812_InitHalDm(padapter); + #endif /* CONFIG_RTL8812A */ + #ifdef CONFIG_RTL8723B + rtl8723b_InitHalDm(padapter); + #endif /* CONFIG_RTL8723B */ + #ifdef CONFIG_RTL8703B + rtl8703b_InitHalDm(padapter); + #endif /* CONFIG_RTL8703B */ + #ifdef CONFIG_RTL8192E + rtl8192e_InitHalDm(padapter); + #endif + #ifdef CONFIG_RTL8188F + rtl8188f_InitHalDm(padapter); + #endif + + //3 0. update mp_priv + + if (padapter->registrypriv.rf_config == RF_MAX_TYPE) { +// switch (phal->rf_type) { + switch (GET_RF_TYPE(padapter)) { + case RF_1T1R: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_A; + break; + case RF_1T2R: + default: + pmppriv->antenna_tx = ANTENNA_A; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T2R: + case RF_2T2R_GREEN: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_AB; + break; + case RF_2T4R: + pmppriv->antenna_tx = ANTENNA_AB; + pmppriv->antenna_rx = ANTENNA_ABCD; + break; + } + } + + mpt_ProStartTest(padapter); + + mp_join(padapter,WIFI_FW_ADHOC_STATE); + + return res; +} +//------------------------------------------------------------------------------ +//This function change the DUT from the MP test mode into normal mode +void mp_stop_test(PADAPTER padapter) +{ + struct mp_priv *pmppriv = &padapter->mppriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *tgt_network = &pmlmepriv->cur_network; + struct sta_info *psta; + + _irqL irqL; + + if(pmppriv->mode==MP_ON) + { + pmppriv->bSetTxPower=0; + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE) + goto end_of_mp_stop_test; + + //3 1. disconnect psudo AdHoc + rtw_indicate_disconnect(padapter); + + //3 2. clear psta used in mp test mode. +// rtw_free_assoc_resources(padapter, 1); + psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + //3 3. return to normal state (default:station mode) + pmlmepriv->fw_state = pmppriv->prev_fw_state; // WIFI_STATION_STATE; + + //flush the cur_network + _rtw_memset(tgt_network, 0, sizeof(struct wlan_network)); + + _clr_fwstate_(pmlmepriv, WIFI_MP_STATE); + +end_of_mp_stop_test: + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + #ifdef CONFIG_RTL8812A + rtl8812_InitHalDm(padapter); + #endif + #ifdef CONFIG_RTL8723B + rtl8723b_InitHalDm(padapter); + #endif + #ifdef CONFIG_RTL8703B + rtl8703b_InitHalDm(padapter); + #endif + #ifdef CONFIG_RTL8192E + rtl8192e_InitHalDm(padapter); + #endif + #ifdef CONFIG_RTL8188F + rtl8188f_InitHalDm(padapter); + #endif + } +} +/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ +#if 0 +//#ifdef CONFIG_USB_HCI +static VOID mpt_AdjustRFRegByRateByChan92CU(PADAPTER pAdapter, u8 RateIdx, u8 Channel, u8 BandWidthID) +{ + u8 eRFPath; + u32 rfReg0x26; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + + if (RateIdx < MPT_RATE_6M) { // CCK rate,for 88cu + rfReg0x26 = 0xf400; + } + else if ((RateIdx >= MPT_RATE_6M) && (RateIdx <= MPT_RATE_54M)) {// OFDM rate,for 88cu + if ((4 == Channel) || (8 == Channel) || (12 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + else if ((RateIdx >= MPT_RATE_MCS0) && (RateIdx <= MPT_RATE_MCS15)) {// MCS 20M ,for 88cu // MCS40M rate,for 88cu + + if (CHANNEL_WIDTH_20 == BandWidthID) { + if ((4 == Channel) || (8 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + else{ + if ((4 == Channel) || (8 == Channel)) + rfReg0x26 = 0xf000; + else if ((5 == Channel) || (7 == Channel)) + rfReg0x26 = 0xf400; + else + rfReg0x26 = 0x4f200; + } + } + +// RT_TRACE(COMP_CMD, DBG_LOUD, ("\n mpt_AdjustRFRegByRateByChan92CU():Chan:%d Rate=%d rfReg0x26:0x%08x\n",Channel, RateIdx,rfReg0x26)); + for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { + write_rfreg(pAdapter, eRFPath, RF_SYN_G2, rfReg0x26); + } +} +#endif +/*----------------------------------------------------------------------------- + * Function: mpt_SwitchRfSetting + * + * Overview: Change RF Setting when we siwthc channel/rate/BW for MP. + * + * Input: IN PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series. + * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3. + * + *---------------------------------------------------------------------------*/ +static void mpt_SwitchRfSetting(PADAPTER pAdapter) +{ + hal_mpt_SwitchRfSetting(pAdapter); + } + +/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/ +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ +static void MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14) +{ + hal_mpt_CCKTxPowerAdjust(Adapter, bInCH14); +} + +static void MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven) +{ + hal_mpt_CCKTxPowerAdjustbyIndex(pAdapter, beven); + } + +/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/ + +/* + * SetChannel + * Description + * Use H2C command to change channel, + * not only modify rf register, but also other setting need to be done. + */ +void SetChannel(PADAPTER pAdapter) +{ + hal_mpt_SetChannel(pAdapter); +} + +/* + * Notice + * Switch bandwitdth may change center frequency(channel) + */ +void SetBandwidth(PADAPTER pAdapter) +{ + hal_mpt_SetBandwidth(pAdapter); + +} + +void SetAntenna(PADAPTER pAdapter) +{ + hal_mpt_SetAntenna(pAdapter); +} + +int SetTxPower(PADAPTER pAdapter) +{ + + hal_mpt_SetTxPower(pAdapter); + return _TRUE; +} + +void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset) +{ + u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D,tmpAGC; + + TxAGCOffset_B = (ulTxAGCOffset&0x000000ff); + TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8); + TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16); + + tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B); + write_bbreg(pAdapter, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC); +} + +void SetDataRate(PADAPTER pAdapter) +{ + hal_mpt_SetDataRate(pAdapter); +} + +void MP_PHY_SetRFPathSwitch(PADAPTER pAdapter ,BOOLEAN bMain) +{ + + PHY_SetRFPathSwitch(pAdapter, bMain); + +} + + +s32 SetThermalMeter(PADAPTER pAdapter, u8 target_ther) +{ + return hal_mpt_SetThermalMeter(pAdapter, target_ther); +} + +static void TriggerRFThermalMeter(PADAPTER pAdapter) +{ + hal_mpt_TriggerRFThermalMeter(pAdapter); +} + +static u8 ReadRFThermalMeter(PADAPTER pAdapter) +{ + return hal_mpt_ReadRFThermalMeter(pAdapter); +} + +void GetThermalMeter(PADAPTER pAdapter, u8 *value) +{ + hal_mpt_GetThermalMeter(pAdapter, value); +} + +void SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetSingleCarrierTx(pAdapter, bStart); +} + +void SetSingleToneTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetSingleToneTx(pAdapter, bStart); +} + +void SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetCarrierSuppressionTx(pAdapter, bStart); +} + +void SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetCCKContinuousTx(pAdapter, bStart); +} + +void SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetOFDMContinuousTx(pAdapter, bStart); +}/* mpt_StartOfdmContTx */ + +void SetContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + PhySetTxPowerLevel(pAdapter); + hal_mpt_SetContinuousTx(pAdapter, bStart); +} + + +void PhySetTxPowerLevel(PADAPTER pAdapter) +{ + struct mp_priv *pmp_priv = &pAdapter->mppriv; + + if (pmp_priv->bSetTxPower==0) // for NO manually set power index + { +#ifdef CONFIG_RTL8188E + PHY_SetTxPowerLevel8188E(pAdapter,pmp_priv->channel); +#endif +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + PHY_SetTxPowerLevel8812(pAdapter,pmp_priv->channel); +#endif +#if defined(CONFIG_RTL8192E) + PHY_SetTxPowerLevel8192E(pAdapter,pmp_priv->channel); +#endif +#if defined(CONFIG_RTL8723B) + PHY_SetTxPowerLevel8723B(pAdapter,pmp_priv->channel); +#endif +#if defined(CONFIG_RTL8188F) + PHY_SetTxPowerLevel8188F(pAdapter, pmp_priv->channel); +#endif + mpt_ProQueryCalTxPower(pAdapter,pmp_priv->antenna_tx); + + } +} + +//------------------------------------------------------------------------------ +static void dump_mpframe(PADAPTER padapter, struct xmit_frame *pmpframe) +{ + rtw_hal_mgnt_xmit(padapter, pmpframe); +} + +static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv) +{ + struct xmit_frame *pmpframe; + struct xmit_buf *pxmitbuf; + + if ((pmpframe = rtw_alloc_xmitframe(pxmitpriv)) == NULL) + { + return NULL; + } + + if ((pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL) + { + rtw_free_xmitframe(pxmitpriv, pmpframe); + return NULL; + } + + pmpframe->frame_tag = MP_FRAMETAG; + + pmpframe->pxmitbuf = pxmitbuf; + + pmpframe->buf_addr = pxmitbuf->pbuf; + + pxmitbuf->priv_data = pmpframe; + + return pmpframe; + +} + +static thread_return mp_xmit_packet_thread(thread_context context) +{ + struct xmit_frame *pxmitframe; + struct mp_tx *pmptx; + struct mp_priv *pmp_priv; + struct xmit_priv *pxmitpriv; + PADAPTER padapter; + + pmp_priv = (struct mp_priv *)context; + pmptx = &pmp_priv->tx; + padapter = pmp_priv->papdater; + pxmitpriv = &(padapter->xmitpriv); + + thread_enter("RTW_MP_THREAD"); + + DBG_871X("%s:pkTx Start\n", __func__); + while (1) { + pxmitframe = alloc_mp_xmitframe(pxmitpriv); + if (pxmitframe == NULL) { + if (pmptx->stop || + RTW_CANNOT_RUN(padapter)) { + goto exit; + } + else { + rtw_usleep_os(10); + continue; + } + } + _rtw_memcpy((u8 *)(pxmitframe->buf_addr+TXDESC_OFFSET), pmptx->buf, pmptx->write_size); + _rtw_memcpy(&(pxmitframe->attrib), &(pmptx->attrib), sizeof(struct pkt_attrib)); + + + rtw_usleep_os(padapter->mppriv.pktInterval); + dump_mpframe(padapter, pxmitframe); + + pmptx->sended++; + pmp_priv->tx_pktcount++; + + if (pmptx->stop || + RTW_CANNOT_RUN(padapter)) + goto exit; + if ((pmptx->count != 0) && + (pmptx->count == pmptx->sended)) + goto exit; + + flush_signals_thread(); + } + +exit: + //DBG_871X("%s:pkTx Exit\n", __func__); + rtw_mfree(pmptx->pallocated_buf, pmptx->buf_size); + pmptx->pallocated_buf = NULL; + pmptx->stop = 1; + + thread_exit(); +} + +void fill_txdesc_for_mp(PADAPTER padapter, u8 *ptxdesc) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + _rtw_memcpy(ptxdesc, pmp_priv->tx.desc, TXDESC_SIZE); +} + +#if defined(CONFIG_RTL8188E) +void fill_tx_desc_8188e(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + struct tx_desc *desc = (struct tx_desc *)&(pmp_priv->tx.desc); + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + u32 pkt_size = pattrib->last_txcmdsz; + s32 bmcast = IS_MCAST(pattrib->ra); +// offset 0 +#if !defined(CONFIG_RTL8188E_SDIO) && !defined(CONFIG_PCI_HCI) + desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); + desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); // packet size + desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); //32 bytes for TX Desc + if (bmcast) desc->txdw0 |= cpu_to_le32(BMC); // broadcast packet + + desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000); +#endif + + desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); //CAM_ID(MAC_ID) + desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); // Queue Select, TID + desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); // Rate Adaptive ID + // offset 8 + // desc->txdw2 |= cpu_to_le32(AGG_BK);//AGG BK + + desc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0x0fff0000); + desc->txdw4 |= cpu_to_le32(HW_SSN); + + desc->txdw4 |= cpu_to_le32(USERATE); + desc->txdw4 |= cpu_to_le32(DISDATAFB); + + if( pmp_priv->preamble ){ + if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_54M) + desc->txdw4 |= cpu_to_le32(DATA_SHORT); // CCK Short Preamble + } + + if (pmp_priv->bandwidth == CHANNEL_WIDTH_40) + desc->txdw4 |= cpu_to_le32(DATA_BW); + + // offset 20 + desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F); + + if( pmp_priv->preamble ){ + if (HwRateToMPTRate(pmp_priv->rateidx) > MPT_RATE_54M) + desc->txdw5 |= cpu_to_le32(SGI); // MCS Short Guard Interval + } + + desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); // retry limit enable + desc->txdw5 |= cpu_to_le32(0x00180000); // DATA/RTS Rate Fallback Limit + + +} +#endif + +#if defined(CONFIG_RTL8814A) +void fill_tx_desc_8814a(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + u8 *pDesc = (u8 *)&(pmp_priv->tx.desc); + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + + u32 pkt_size = pattrib->last_txcmdsz; + s32 bmcast = IS_MCAST(pattrib->ra); + u8 data_rate,pwr_status,offset; + + //SET_TX_DESC_FIRST_SEG_8814A(pDesc, 1); + SET_TX_DESC_LAST_SEG_8814A(pDesc, 1); + //SET_TX_DESC_OWN_(pDesc, 1); + + SET_TX_DESC_PKT_SIZE_8814A(pDesc, pkt_size); + + offset = TXDESC_SIZE + OFFSET_SZ; + + SET_TX_DESC_OFFSET_8814A(pDesc, offset); +#if defined(CONFIG_PCI_HCI) + SET_TX_DESC_PKT_OFFSET_8814A(pDesc, 0); /* 8814AE pkt_offset is 0 */ +#else + SET_TX_DESC_PKT_OFFSET_8814A(pDesc, 1); +#endif + + if (bmcast) { + SET_TX_DESC_BMC_8814A(pDesc, 1); + } + + SET_TX_DESC_MACID_8814A(pDesc, pattrib->mac_id); + SET_TX_DESC_RATE_ID_8814A(pDesc, pattrib->raid); + + //SET_TX_DESC_RATE_ID_8812(pDesc, RATEID_IDX_G); + SET_TX_DESC_QUEUE_SEL_8814A(pDesc, pattrib->qsel); + //SET_TX_DESC_QUEUE_SEL_8812(pDesc, QSLT_MGNT); + + if ( pmp_priv->preamble ){ + SET_TX_DESC_DATA_SHORT_8814A(pDesc, 1); + } + + if (!pattrib->qos_en) { + SET_TX_DESC_HWSEQ_EN_8814A(pDesc, 1); // Hw set sequence number + } else { + SET_TX_DESC_SEQ_8814A(pDesc, pattrib->seqnum); + } + + if (pmp_priv->bandwidth <= CHANNEL_WIDTH_160) { + SET_TX_DESC_DATA_BW_8814A(pDesc, pmp_priv->bandwidth); + } else { + DBG_871X("%s:Err: unknown bandwidth %d, use 20M\n", __func__,pmp_priv->bandwidth); + SET_TX_DESC_DATA_BW_8814A(pDesc, CHANNEL_WIDTH_20); + } + + SET_TX_DESC_DISABLE_FB_8814A(pDesc, 1); + SET_TX_DESC_USE_RATE_8814A(pDesc, 1); + SET_TX_DESC_TX_RATE_8814A(pDesc, pmp_priv->rateidx); + +} +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +void fill_tx_desc_8812a(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + u8 *pDesc = (u8 *)&(pmp_priv->tx.desc); + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + + u32 pkt_size = pattrib->last_txcmdsz; + s32 bmcast = IS_MCAST(pattrib->ra); + u8 data_rate,pwr_status,offset; + + SET_TX_DESC_FIRST_SEG_8812(pDesc, 1); + SET_TX_DESC_LAST_SEG_8812(pDesc, 1); + SET_TX_DESC_OWN_8812(pDesc, 1); + + SET_TX_DESC_PKT_SIZE_8812(pDesc, pkt_size); + + offset = TXDESC_SIZE + OFFSET_SZ; + + SET_TX_DESC_OFFSET_8812(pDesc, offset); + +#if defined(CONFIG_PCI_HCI) + SET_TX_DESC_PKT_OFFSET_8812(pDesc, 0); +#else + SET_TX_DESC_PKT_OFFSET_8812(pDesc, 1); +#endif + if (bmcast) { + SET_TX_DESC_BMC_8812(pDesc, 1); + } + + SET_TX_DESC_MACID_8812(pDesc, pattrib->mac_id); + SET_TX_DESC_RATE_ID_8812(pDesc, pattrib->raid); + + //SET_TX_DESC_RATE_ID_8812(pDesc, RATEID_IDX_G); + SET_TX_DESC_QUEUE_SEL_8812(pDesc, pattrib->qsel); + //SET_TX_DESC_QUEUE_SEL_8812(pDesc, QSLT_MGNT); + + if (!pattrib->qos_en) { + SET_TX_DESC_HWSEQ_EN_8812(pDesc, 1); // Hw set sequence number + } else { + SET_TX_DESC_SEQ_8812(pDesc, pattrib->seqnum); + } + + if (pmp_priv->bandwidth <= CHANNEL_WIDTH_160) { + SET_TX_DESC_DATA_BW_8812(pDesc, pmp_priv->bandwidth); + } else { + DBG_871X("%s:Err: unknown bandwidth %d, use 20M\n", __func__,pmp_priv->bandwidth); + SET_TX_DESC_DATA_BW_8812(pDesc, CHANNEL_WIDTH_20); + } + + SET_TX_DESC_DISABLE_FB_8812(pDesc, 1); + SET_TX_DESC_USE_RATE_8812(pDesc, 1); + SET_TX_DESC_TX_RATE_8812(pDesc, pmp_priv->rateidx); + +} +#endif +#if defined(CONFIG_RTL8192E) +void fill_tx_desc_8192e(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + u8 *pDesc = (u8 *)&(pmp_priv->tx.desc); + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + + u32 pkt_size = pattrib->last_txcmdsz; + s32 bmcast = IS_MCAST(pattrib->ra); + u8 data_rate,pwr_status,offset; + + + SET_TX_DESC_PKT_SIZE_92E(pDesc, pkt_size); + + offset = TXDESC_SIZE + OFFSET_SZ; + + SET_TX_DESC_OFFSET_92E(pDesc, offset); + #if defined(CONFIG_PCI_HCI) /* 8192EE */ + + SET_TX_DESC_PKT_OFFSET_92E(pDesc, 0); /* 8192EE pkt_offset is 0 */ + #else /* 8192EU 8192ES */ + SET_TX_DESC_PKT_OFFSET_92E(pDesc, 1); + #endif + + if (bmcast) { + SET_TX_DESC_BMC_92E(pDesc, 1); + } + + SET_TX_DESC_MACID_92E(pDesc, pattrib->mac_id); + SET_TX_DESC_RATE_ID_92E(pDesc, pattrib->raid); + + + SET_TX_DESC_QUEUE_SEL_92E(pDesc, pattrib->qsel); + //SET_TX_DESC_QUEUE_SEL_8812(pDesc, QSLT_MGNT); + + if (!pattrib->qos_en) { + 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); + } + + if ((pmp_priv->bandwidth == CHANNEL_WIDTH_20) || (pmp_priv->bandwidth == CHANNEL_WIDTH_40)) { + SET_TX_DESC_DATA_BW_92E(pDesc, pmp_priv->bandwidth); + } else { + DBG_871X("%s:Err: unknown bandwidth %d, use 20M\n", __func__,pmp_priv->bandwidth); + SET_TX_DESC_DATA_BW_92E(pDesc, CHANNEL_WIDTH_20); + } + + //SET_TX_DESC_DATA_SC_92E(pDesc, SCMapping_92E(padapter,pattrib)); + + SET_TX_DESC_DISABLE_FB_92E(pDesc, 1); + SET_TX_DESC_USE_RATE_92E(pDesc, 1); + SET_TX_DESC_TX_RATE_92E(pDesc, pmp_priv->rateidx); + +} +#endif + +#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; + + SET_TX_DESC_AGG_BREAK_8723B(ptxdesc, 1); + SET_TX_DESC_MACID_8723B(ptxdesc, pattrib->mac_id); + SET_TX_DESC_QUEUE_SEL_8723B(ptxdesc, pattrib->qsel); + + SET_TX_DESC_RATE_ID_8723B(ptxdesc, pattrib->raid); + SET_TX_DESC_SEQ_8723B(ptxdesc, pattrib->seqnum); + SET_TX_DESC_HWSEQ_EN_8723B(ptxdesc, 1); + SET_TX_DESC_USE_RATE_8723B(ptxdesc, 1); + SET_TX_DESC_DISABLE_FB_8723B(ptxdesc, 1); + + if (pmp_priv->preamble) { + if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_54M) + SET_TX_DESC_DATA_SHORT_8723B(ptxdesc, 1); + } + + if (pmp_priv->bandwidth == CHANNEL_WIDTH_40) { + SET_TX_DESC_DATA_BW_8723B(ptxdesc, 1); + } + + SET_TX_DESC_TX_RATE_8723B(ptxdesc, pmp_priv->rateidx); + + SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(ptxdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(ptxdesc, 0xF); +} +#endif + +#if defined(CONFIG_RTL8703B) +void fill_tx_desc_8703b(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + u8 *ptxdesc = pmp_priv->tx.desc; + + SET_TX_DESC_AGG_BREAK_8703B(ptxdesc, 1); + SET_TX_DESC_MACID_8703B(ptxdesc, pattrib->mac_id); + SET_TX_DESC_QUEUE_SEL_8703B(ptxdesc, pattrib->qsel); + + SET_TX_DESC_RATE_ID_8703B(ptxdesc, pattrib->raid); + SET_TX_DESC_SEQ_8703B(ptxdesc, pattrib->seqnum); + SET_TX_DESC_HWSEQ_EN_8703B(ptxdesc, 1); + SET_TX_DESC_USE_RATE_8703B(ptxdesc, 1); + SET_TX_DESC_DISABLE_FB_8703B(ptxdesc, 1); + + if (pmp_priv->preamble) { + if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_54M) + SET_TX_DESC_DATA_SHORT_8703B(ptxdesc, 1); + } + + if (pmp_priv->bandwidth == CHANNEL_WIDTH_40) + SET_TX_DESC_DATA_BW_8703B(ptxdesc, 1); + + SET_TX_DESC_TX_RATE_8703B(ptxdesc, pmp_priv->rateidx); + + SET_TX_DESC_DATA_RATE_FB_LIMIT_8703B(ptxdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT_8703B(ptxdesc, 0xF); +} +#endif + +#if defined(CONFIG_RTL8188F) +void fill_tx_desc_8188f(PADAPTER padapter) +{ + struct mp_priv *pmp_priv = &padapter->mppriv; + struct pkt_attrib *pattrib = &(pmp_priv->tx.attrib); + u8 *ptxdesc = pmp_priv->tx.desc; + + SET_TX_DESC_AGG_BREAK_8188F(ptxdesc, 1); + SET_TX_DESC_MACID_8188F(ptxdesc, pattrib->mac_id); + SET_TX_DESC_QUEUE_SEL_8188F(ptxdesc, pattrib->qsel); + + SET_TX_DESC_RATE_ID_8188F(ptxdesc, pattrib->raid); + SET_TX_DESC_SEQ_8188F(ptxdesc, pattrib->seqnum); + SET_TX_DESC_HWSEQ_EN_8188F(ptxdesc, 1); + SET_TX_DESC_USE_RATE_8188F(ptxdesc, 1); + SET_TX_DESC_DISABLE_FB_8188F(ptxdesc, 1); + + if (pmp_priv->preamble) + if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_54M) + SET_TX_DESC_DATA_SHORT_8188F(ptxdesc, 1); + + if (pmp_priv->bandwidth == CHANNEL_WIDTH_40) + SET_TX_DESC_DATA_BW_8188F(ptxdesc, 1); + + SET_TX_DESC_TX_RATE_8188F(ptxdesc, pmp_priv->rateidx); + + SET_TX_DESC_DATA_RATE_FB_LIMIT_8188F(ptxdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT_8188F(ptxdesc, 0xF); +} +#endif + +static void Rtw_MPSetMacTxEDCA(PADAPTER padapter) +{ + + rtw_write32(padapter, 0x508 , 0x00a422); //Disable EDCA BE Txop for MP pkt tx adjust Packet interval + //DBG_871X("%s:write 0x508~~~~~~ 0x%x\n", __func__,rtw_read32(padapter, 0x508)); + PHY_SetMacReg(padapter, 0x458 ,bMaskDWord , 0x0); + //DBG_8192C("%s()!!!!! 0x460 = 0x%x\n" ,__func__,PHY_QueryBBReg(padapter, 0x460, bMaskDWord)); + PHY_SetMacReg(padapter, 0x460 ,bMaskLWord , 0x0);//fast EDCA queue packet interval & time out vaule + //PHY_SetMacReg(padapter, ODM_EDCA_VO_PARAM ,bMaskLWord , 0x431C); + //PHY_SetMacReg(padapter, ODM_EDCA_BE_PARAM ,bMaskLWord , 0x431C); + //PHY_SetMacReg(padapter, ODM_EDCA_BK_PARAM ,bMaskLWord , 0x431C); + DBG_8192C("%s()!!!!! 0x460 = 0x%x\n" ,__func__,PHY_QueryBBReg(padapter, 0x460, bMaskDWord)); + +} + +void SetPacketTx(PADAPTER padapter) +{ + u8 *ptr, *pkt_start, *pkt_end,*fctrl; + u32 pkt_size,offset,startPlace,i; + struct rtw_ieee80211_hdr *hdr; + u8 payload; + s32 bmcast; + struct pkt_attrib *pattrib; + struct mp_priv *pmp_priv; + + pmp_priv = &padapter->mppriv; + + if (pmp_priv->tx.stop) return; + pmp_priv->tx.sended = 0; + pmp_priv->tx.stop = 0; + pmp_priv->tx_pktcount = 0; + + //3 1. update_attrib() + pattrib = &pmp_priv->tx.attrib; + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + bmcast = IS_MCAST(pattrib->ra); + if (bmcast) { + pattrib->mac_id = 1; + pattrib->psta = rtw_get_bcmc_stainfo(padapter); + } else { + pattrib->mac_id = 0; + pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + } + pattrib->mbssid = 0; + + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; + + //3 2. allocate xmit buffer + pkt_size = pattrib->last_txcmdsz; + + if (pmp_priv->tx.pallocated_buf) + rtw_mfree(pmp_priv->tx.pallocated_buf, pmp_priv->tx.buf_size); + pmp_priv->tx.write_size = pkt_size; + pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ; + pmp_priv->tx.pallocated_buf = rtw_zmalloc(pmp_priv->tx.buf_size); + if (pmp_priv->tx.pallocated_buf == NULL) { + DBG_871X("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size); + return; + } + pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ); + ptr = pmp_priv->tx.buf; + + _rtw_memset(pmp_priv->tx.desc, 0, TXDESC_SIZE); + pkt_start = ptr; + pkt_end = pkt_start + pkt_size; + + //3 3. init TX descriptor +#if defined(CONFIG_RTL8188E) + if(IS_HARDWARE_TYPE_8188E(padapter)) + fill_tx_desc_8188e(padapter); +#endif + +#if defined(CONFIG_RTL8814A) + if(IS_HARDWARE_TYPE_8814A(padapter)) + fill_tx_desc_8814a(padapter); +#endif /* defined(CONFIG_RTL8814A) */ + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + if(IS_HARDWARE_TYPE_8812(padapter) || IS_HARDWARE_TYPE_8821(padapter)) + fill_tx_desc_8812a(padapter); +#endif + +#if defined(CONFIG_RTL8192E) + if(IS_HARDWARE_TYPE_8192E(padapter)) + fill_tx_desc_8192e(padapter); +#endif +#if defined(CONFIG_RTL8723B) + if(IS_HARDWARE_TYPE_8723B(padapter)) + fill_tx_desc_8723b(padapter); +#endif +#if defined(CONFIG_RTL8703B) + if (IS_HARDWARE_TYPE_8703B(padapter)) + fill_tx_desc_8703b(padapter); +#endif + +#if defined(CONFIG_RTL8188F) + if (IS_HARDWARE_TYPE_8188F(padapter)) + fill_tx_desc_8188f(padapter); +#endif + + //3 4. make wlan header, make_wlanhdr() + hdr = (struct rtw_ieee80211_hdr *)pkt_start; + SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); + // + SetFrDs(&hdr->frame_ctl); + _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA + _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA + _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID + + //3 5. make payload + ptr = pkt_start + pattrib->hdrlen; + + switch (pmp_priv->tx.payload) { + case 0: + payload = 0x00; + break; + case 1: + payload = 0x5a; + break; + case 2: + payload = 0xa5; + break; + case 3: + payload = 0xff; + break; + default: + payload = 0x00; + break; + } + pmp_priv->TXradomBuffer = rtw_zmalloc(4096); + if(pmp_priv->TXradomBuffer == NULL) + { + DBG_871X("mp create random buffer fail!\n"); + goto exit; + } + + + 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"); + if (IS_ERR(pmp_priv->tx.PktTxThread)) + DBG_871X("Create PktTx Thread Fail !!!!!\n"); +#endif +#ifdef PLATFORM_FREEBSD +{ + struct proc *p; + struct thread *td; + pmp_priv->tx.PktTxThread = kproc_kthread_add(mp_xmit_packet_thread, pmp_priv, + &p, &td, RFHIGHPID, 0, "MPXmitThread", "MPXmitThread"); + + if (pmp_priv->tx.PktTxThread < 0) + DBG_871X("Create PktTx Thread Fail !!!!!\n"); +} +#endif + + Rtw_MPSetMacTxEDCA(padapter); +exit: + return; +} + +void SetPacketRx(PADAPTER pAdapter, u8 bStartRx, u8 bAB) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mp_priv *pmppriv = &pAdapter->mppriv; + u8 type; + type = _HW_STATE_AP_; + if(bStartRx) + { +#ifdef CONFIG_RTL8723B + PHY_SetMacReg(pAdapter, 0xe70, BIT23|BIT22, 0x3);// Power on adc (in RX_WAIT_CCA state) + write_bbreg(pAdapter, 0xa01, BIT0, bDisable);// improve Rx performance by jerry +#endif + if( pmppriv->bSetRxBssid == _TRUE ){ + //pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB |RCR_CBSSID_DATA| RCR_CBSSID_BCN| RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYST_RXFF; + pHalData->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB |RCR_AMF | RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | RCR_APP_MIC | RCR_APP_PHYST_RXFF ; + pHalData->ReceiveConfig |= ACRC32; + + DBG_8192C("%s , pmppriv->network_macaddr =%x %x %x %x %x %x\n",__func__, + pmppriv->network_macaddr[0],pmppriv->network_macaddr[1],pmppriv->network_macaddr[2],pmppriv->network_macaddr[3],pmppriv->network_macaddr[4],pmppriv->network_macaddr[5]); + //Set_MSR(pAdapter, WIFI_FW_AP_STATE); + //rtw_hal_set_hwreg(pAdapter, HW_VAR_BSSID, pmppriv->network_macaddr); + //rtw_hal_set_hwreg(pAdapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); + } + else + { + pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS; + pHalData->ReceiveConfig |= ACRC32; + rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); + // Accept all data frames + rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF); + // Accept CRC error and destination address + } + } + else + { +#ifdef CONFIG_RTL8723B + PHY_SetMacReg(pAdapter, 0xe70, BIT23|BIT22, 0x00);// Power off adc (in RX_WAIT_CCA state) + write_bbreg(pAdapter, 0xa01, BIT0, bEnable);// improve Rx performance by jerry +#endif + rtw_write32(pAdapter, REG_RCR, 0); + } + + if (bAB) + rtw_write32(pAdapter, REG_RCR, rtw_read32(pAdapter, REG_RCR)|RCR_AB); + else + rtw_write32(pAdapter, REG_RCR, rtw_read32(pAdapter, REG_RCR)&(~RCR_AB)); +} + +void ResetPhyRxPktCount(PADAPTER pAdapter) +{ + u32 i, phyrx_set = 0; + + for (i = 0; i <= 0xF; i++) { + phyrx_set = 0; + phyrx_set |= _RXERR_RPT_SEL(i); //select + phyrx_set |= RXERR_RPT_RST; // set counter to zero + rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); + } +} + +static u32 GetPhyRxPktCounts(PADAPTER pAdapter, u32 selbit) +{ + //selection + u32 phyrx_set = 0, count = 0; + + phyrx_set = _RXERR_RPT_SEL(selbit & 0xF); + rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set); + + //Read packet count + count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK; + + return count; +} + +u32 GetPhyRxPktReceived(PADAPTER pAdapter) +{ + u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; + + OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK); + CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK); + HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK); + + return OFDM_cnt + CCK_cnt + HT_cnt; +} + +u32 GetPhyRxPktCRC32Error(PADAPTER pAdapter) +{ + u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; + + OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL); + CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL); + HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL); + + return OFDM_cnt + CCK_cnt + HT_cnt; +} + +//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 +static u32 rtw_GetPSDData(PADAPTER pAdapter, u32 point) +{ + u32 psd_val=0; + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) + u16 psd_reg = 0x910; + u16 psd_regL= 0xF44; +#else + u16 psd_reg = 0x808; + u16 psd_regL= 0x8B4; +#endif + + psd_val = rtw_read32(pAdapter, psd_reg); + + psd_val &= 0xFFBFFC00; + psd_val |= point; + + rtw_write32(pAdapter, psd_reg, psd_val); + rtw_mdelay_os(1); + psd_val |= 0x00400000; + + rtw_write32(pAdapter, psd_reg, psd_val); + rtw_mdelay_os(1); + + psd_val = rtw_read32(pAdapter, psd_regL); + psd_val &= 0x0000FFFF; + + return psd_val; +} + +/* + * pts start_point_min stop_point_max + * 128 64 64 + 128 = 192 + * 256 128 128 + 256 = 384 + * 512 256 256 + 512 = 768 + * 1024 512 512 + 1024 = 1536 + * + */ +u32 mp_query_psd(PADAPTER pAdapter, u8 *data) +{ + u32 i, psd_pts=0, psd_start=0, psd_stop=0; + u32 psd_data=0; + + +#ifdef PLATFORM_LINUX + if (!netif_running(pAdapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! interface not opened!\n")); + return 0; + } +#endif + + if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! not in MP mode!\n")); + return 0; + } + + if (strlen(data) == 0) { //default value + psd_pts = 128; + psd_start = 64; + psd_stop = 128; + } else { + sscanf(data, "pts=%d,start=%d,stop=%d", &psd_pts, &psd_start, &psd_stop); + } + + data[0]='\0'; + + i = psd_start; + while (i < psd_stop) + { + if (i >= psd_pts) { + psd_data = rtw_GetPSDData(pAdapter, i-psd_pts); + } else { + psd_data = rtw_GetPSDData(pAdapter, i); + } + sprintf(data, "%s%x ", data, psd_data); + i++; + } + + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(100); + #else + rtw_mdelay_os(100); + #endif + + return strlen(data)+1; +} + + +#if 0 +void _rtw_mp_xmit_priv (struct xmit_priv *pxmitpriv) +{ + int i,res; + _adapter *padapter = pxmitpriv->adapter; + struct xmit_frame *pxmitframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; + + u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; + u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; + if(padapter->registrypriv.mp_mode ==0) + { + max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; + num_xmit_extbuf = NR_XMIT_EXTBUFF; + } + else + { + max_xmit_extbuf_size = 6000; + num_xmit_extbuf = 8; + } + + pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; + for(i=0; ipallocated_xmit_extbuf) { + rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, num_xmit_extbuf * sizeof(struct xmit_buf) + 4); + } + + if(padapter->registrypriv.mp_mode ==0) + { + max_xmit_extbuf_size = 6000; + num_xmit_extbuf = 8; + } + else + { + max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; + num_xmit_extbuf = NR_XMIT_EXTBUFF; + } + + // Init xmit extension buff + _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); + + pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4); + + if (pxmitpriv->pallocated_xmit_extbuf == NULL){ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_extbuf fail!\n")); + res= _FAIL; + goto exit; + } + + pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4); + + pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; + + for (i = 0; i < num_xmit_extbuf; i++) + { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->buf_tag = XMITBUF_MGNT; + + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,max_xmit_extbuf_size + XMITBUF_ALIGN_SZ, _TRUE)) == _FAIL) { + res= _FAIL; + goto exit; + } + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + max_xmit_extbuf_size; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + + rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue)); + #ifdef DBG_XMIT_BUF_EXT + pxmitbuf->no=i; + #endif + pxmitbuf++; + + } + + pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; + +exit: + ; +} +#endif + + +ULONG getPowerDiffByRate8188E( + IN PADAPTER pAdapter, + IN u1Byte CurrChannel, + IN ULONG RfPath + ) +{ + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + ULONG PwrGroup=0; + ULONG TxPower=0, Limit=0; + ULONG Pathmapping = (RfPath == ODM_RF_PATH_A?0:8); + + switch(pHalData->EEPROMRegulatory) + { + case 0: // driver-defined maximum power offset for longer communication range + // refer to power by rate table + PwrGroup = 0; + Limit = 0xff; + break; + case 1: // Power-limit table-defined maximum power offset range + // choosed by min(power by rate, power limit). + { + if(pHalData->pwrGroupCnt == 1) + PwrGroup = 0; + if(pHalData->pwrGroupCnt >= 3) + { + if(CurrChannel <= 3) + PwrGroup = 0; + else if(CurrChannel >= 4 && CurrChannel <= 9) + PwrGroup = 1; + else if(CurrChannel > 9) + PwrGroup = 2; + + if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_20) + PwrGroup++; + else + PwrGroup+=4; + } + Limit = 0xff; + } + break; + case 2: // not support power offset by rate. + // don't increase any power diff + PwrGroup = 0; + Limit = 0; + break; + default: + PwrGroup = 0; + Limit = 0xff; + break; + } + + + { + switch(pMptCtx->MptRateIndex) + { + case MPT_RATE_1M: + case MPT_RATE_2M: + case MPT_RATE_55M: + case MPT_RATE_11M: + //CCK rates, don't add any tx power index. + //RT_DISP(FPHY, PHY_TXPWR,("CCK rates!\n")); + break; + case MPT_RATE_6M: //0xe00 [31:0] = 18M,12M,09M,06M + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x, OFDM 6M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0], TxPower)); + break; + case MPT_RATE_9M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x, OFDM 9M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0], TxPower)); + break; + case MPT_RATE_12M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x, OFDM 12M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0], TxPower)); + break; + case MPT_RATE_18M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x, OFDM 24M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][0], TxPower)); + break; + case MPT_RATE_24M: //0xe04[31:0] = 54M,48M,36M,24M + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x, OFDM 24M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1], TxPower)); + break; + case MPT_RATE_36M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x, OFDM 36M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1], TxPower)); + break; + case MPT_RATE_48M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x, OFDM 48M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1], TxPower)); + break; + case MPT_RATE_54M: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x, OFDM 54M, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][1], TxPower)); + break; + case MPT_RATE_MCS0: //0xe10[31:0]= MCS=03,02,01,00 + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x, MCS0, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2], TxPower)); + break; + case MPT_RATE_MCS1: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x, MCS1, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2], TxPower)); + break; + case MPT_RATE_MCS2: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x, MCS2, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2], TxPower)); + break; + case MPT_RATE_MCS3: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x, MCS3, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][2], TxPower)); + break; + case MPT_RATE_MCS4: //0xe14[31:0]= MCS=07,06,05,04 + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x, MCS4, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3], TxPower)); + break; + case MPT_RATE_MCS5: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x, MCS5, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3], TxPower)); + break; + case MPT_RATE_MCS6: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x, MCS6, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3], TxPower)); + break; + case MPT_RATE_MCS7: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x, MCS7, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][3], TxPower)); + break; + + case MPT_RATE_MCS8: //0xe18[31:0]= MCS=11,10,09,08 + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x, MCS8, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4], TxPower)); + break; + case MPT_RATE_MCS9: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x, MCS9, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4], TxPower)); + break; + case MPT_RATE_MCS10: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x, MCS10, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4], TxPower)); + break; + case MPT_RATE_MCS11: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x, MCS11, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][4], TxPower)); + break; + case MPT_RATE_MCS12: //0xe1c[31:0]= MCS=15,14,13,12 + TxPower += ((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5+Pathmapping])&0xff); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x, MCS12, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5], TxPower)); + break; + case MPT_RATE_MCS13: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5+Pathmapping])&0xff00)>>8); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x, MCS13, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5], TxPower)); + break; + case MPT_RATE_MCS14: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5+Pathmapping])&0xff0000)>>16); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x, MCS14, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5], TxPower)); + break; + case MPT_RATE_MCS15: + TxPower += (((pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5+Pathmapping])&0xff000000)>>24); + //RT_DISP(FPHY, PHY_TXPWR,("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x, MCS15, TxPower = %d\n", + // PwrGroup, pHalData->MCSTxPowerLevelOriginalOffset[PwrGroup][5], TxPower)); + break; + default: + break; + } + } + + if(TxPower > Limit) + TxPower = Limit; + + return TxPower; +} + + + +static ULONG +mpt_ProQueryCalTxPower_8188E( + IN PADAPTER pAdapter, + IN u1Byte RfPath + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u1Byte TxCount=TX_1S, i = 0; //default set to 1S + //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + ULONG TxPower = 1, PwrGroup=0, PowerDiffByRate=0; + ULONG TxPowerCCK = 1, TxPowerOFDM = 1, TxPowerBW20 = 1, TxPowerBW40 = 1 ; + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u1Byte CurrChannel = pHalData->CurrentChannel; + u1Byte index = (CurrChannel -1); + u1Byte rf_path=(RfPath), rfPath; + u1Byte limit = 0, rate = 0; + + if(HAL_IsLegalChannel(pAdapter, CurrChannel) == FALSE) + { + CurrChannel = 1; + } + + if(pMptCtx->MptRateIndex <= MPT_RATE_11M ) + { + TxPower = pHalData->Index24G_CCK_Base[rf_path][index]; + } + else if(pMptCtx->MptRateIndex >= MPT_RATE_6M && + pMptCtx->MptRateIndex <= MPT_RATE_54M ) + { + TxPower = pHalData->Index24G_BW40_Base[rf_path][index]; + } + else if(pMptCtx->MptRateIndex >= MPT_RATE_MCS0 && + pMptCtx->MptRateIndex <= MPT_RATE_MCS7 ) + { + TxPower = pHalData->Index24G_BW40_Base[rf_path][index]; + } + + //RT_DISP(FPHY, PHY_TXPWR, ("HT40 rate(%d) Tx power(RF-%c) = 0x%x\n", pMptCtx->MptRateIndex, ((rf_path==0)?'A':'B'), TxPower)); + + + if(pMptCtx->MptRateIndex >= MPT_RATE_6M && + pMptCtx->MptRateIndex <= MPT_RATE_54M ) + { + TxPower += pHalData->OFDM_24G_Diff[rf_path][TxCount]; + ///RT_DISP(FPHY, PHY_TXPWR, ("+OFDM_PowerDiff(RF-%c) = 0x%x\n", ((rf_path==0)?'A':'B'), + // pHalData->OFDM_24G_Diff[rf_path][TxCount])); + } + + if(pMptCtx->MptRateIndex >= MPT_RATE_MCS0) + { + if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_20) + { + TxPower += pHalData->BW20_24G_Diff[rf_path][TxCount]; + // RT_DISP(FPHY, PHY_TXPWR, ("+HT20_PowerDiff(RF-%c) = 0x%x\n", ((rf_path==0)?'A':'B'), + // pHalData->BW20_24G_Diff[rf_path][TxCount])); + } + } + + +#ifdef ENABLE_POWER_BY_RATE + PowerDiffByRate = getPowerDiffByRate8188E(pAdapter, CurrChannel, RfPath); +#else + PowerDiffByRate = 0; +#endif + + // 2012/11/02 Awk: add power limit mechansim + if( pMptCtx->MptRateIndex <= MPT_RATE_11M ) + { + rate = MGN_1M; + } + else if(pMptCtx->MptRateIndex >= MPT_RATE_6M && + pMptCtx->MptRateIndex <= MPT_RATE_54M ) + { + rate = MGN_54M; + } + else if(pMptCtx->MptRateIndex >= MPT_RATE_MCS0 && + pMptCtx->MptRateIndex <= MPT_RATE_MCS7 ) + { + rate = MGN_MCS7; + } + + limit = (u8)PHY_GetTxPowerLimit(pAdapter, pMptCtx->RegTxPwrLimit, + pHalData->CurrentBandType, + pHalData->CurrentChannelBW,RfPath, + rate, CurrChannel); + + //RT_DISP(FPHY, PHY_TXPWR, ("+PowerDiffByRate(RF-%c) = 0x%x\n", ((rf_path==0)?'A':'B'), + // PowerDiffByRate)); + TxPower += PowerDiffByRate; + //RT_DISP(FPHY, PHY_TXPWR, ("PowerDiffByRate limit value(RF-%c) = %d\n", ((rf_path==0)?'A':'B'), + // limit)); + + TxPower += limit > (s8) PowerDiffByRate ? PowerDiffByRate : limit; + + return TxPower; +} + + +u8 +MptToMgntRate( + IN ULONG MptRateIdx + ) +{ +// Mapped to MGN_XXX defined in MgntGen.h + switch (MptRateIdx) + { + /* CCK rate. */ + 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 automatiMGN_VHT2SS_MCS1; + default: + DBG_871X("<===MptToMgntRate(), Invalid Rate: %d!!\n", MptRateIdx); + return 0x0; + } +} + + +u8 HwRateToMPTRate(u8 rate) +{ + u8 ret_rate = MGN_1M; + + switch (rate) { + case DESC_RATE1M: + ret_rate = MPT_RATE_1M; break; + case DESC_RATE2M: + ret_rate = MPT_RATE_2M; break; + case DESC_RATE5_5M: + ret_rate = MPT_RATE_55M; break; + case DESC_RATE11M: + ret_rate = MPT_RATE_11M; break; + case DESC_RATE6M: + ret_rate = MPT_RATE_6M; break; + case DESC_RATE9M: + ret_rate = MPT_RATE_9M; break; + case DESC_RATE12M: + ret_rate = MPT_RATE_12M; break; + case DESC_RATE18M: + ret_rate = MPT_RATE_18M; break; + case DESC_RATE24M: + ret_rate = MPT_RATE_24M; break; + case DESC_RATE36M: + ret_rate = MPT_RATE_36M; break; + case DESC_RATE48M: + ret_rate = MPT_RATE_48M; break; + case DESC_RATE54M: + ret_rate = MPT_RATE_54M; break; + case DESC_RATEMCS0: + ret_rate = MPT_RATE_MCS0; break; + case DESC_RATEMCS1: + ret_rate = MPT_RATE_MCS1; break; + case DESC_RATEMCS2: + ret_rate = MPT_RATE_MCS2; break; + case DESC_RATEMCS3: + ret_rate = MPT_RATE_MCS3; break; + case DESC_RATEMCS4: + ret_rate = MPT_RATE_MCS4; break; + case DESC_RATEMCS5: + ret_rate = MPT_RATE_MCS5; break; + case DESC_RATEMCS6: + ret_rate = MPT_RATE_MCS6; break; + case DESC_RATEMCS7: + ret_rate = MPT_RATE_MCS7; break; + case DESC_RATEMCS8: + ret_rate = MPT_RATE_MCS8; break; + case DESC_RATEMCS9: + ret_rate = MPT_RATE_MCS9; break; + case DESC_RATEMCS10: + ret_rate = MPT_RATE_MCS10; break; + case DESC_RATEMCS11: + ret_rate = MPT_RATE_MCS11; break; + case DESC_RATEMCS12: + ret_rate = MPT_RATE_MCS12; break; + case DESC_RATEMCS13: + ret_rate = MPT_RATE_MCS13; break; + case DESC_RATEMCS14: + ret_rate = MPT_RATE_MCS14; break; + case DESC_RATEMCS15: + ret_rate = MPT_RATE_MCS15; break; + case DESC_RATEMCS16: + ret_rate = MPT_RATE_MCS16; break; + case DESC_RATEMCS17: + ret_rate = MPT_RATE_MCS17; break; + case DESC_RATEMCS18: + ret_rate = MPT_RATE_MCS18; break; + case DESC_RATEMCS19: + ret_rate = MPT_RATE_MCS19; break; + case DESC_RATEMCS20: + ret_rate = MPT_RATE_MCS20; break; + case DESC_RATEMCS21: + ret_rate = MPT_RATE_MCS21; break; + case DESC_RATEMCS22: + ret_rate = MPT_RATE_MCS22; break; + case DESC_RATEMCS23: + ret_rate = MPT_RATE_MCS23; break; + case DESC_RATEMCS24: + ret_rate = MPT_RATE_MCS24; break; + case DESC_RATEMCS25: + ret_rate = MPT_RATE_MCS25; break; + case DESC_RATEMCS26: + ret_rate = MPT_RATE_MCS26; break; + case DESC_RATEMCS27: + ret_rate = MPT_RATE_MCS27; break; + case DESC_RATEMCS28: + ret_rate = MPT_RATE_MCS28; break; + case DESC_RATEMCS29: + ret_rate = MPT_RATE_MCS29; break; + case DESC_RATEMCS30: + ret_rate = MPT_RATE_MCS30; break; + case DESC_RATEMCS31: + ret_rate = MPT_RATE_MCS31; break; + case DESC_RATEVHTSS1MCS0: + ret_rate = MPT_RATE_VHT1SS_MCS0; break; + case DESC_RATEVHTSS1MCS1: + ret_rate = MPT_RATE_VHT1SS_MCS1; break; + case DESC_RATEVHTSS1MCS2: + ret_rate = MPT_RATE_VHT1SS_MCS2; break; + case DESC_RATEVHTSS1MCS3: + ret_rate = MPT_RATE_VHT1SS_MCS3; break; + case DESC_RATEVHTSS1MCS4: + ret_rate = MPT_RATE_VHT1SS_MCS4; break; + case DESC_RATEVHTSS1MCS5: + ret_rate = MPT_RATE_VHT1SS_MCS5; break; + case DESC_RATEVHTSS1MCS6: + ret_rate = MPT_RATE_VHT1SS_MCS6; break; + case DESC_RATEVHTSS1MCS7: + ret_rate = MPT_RATE_VHT1SS_MCS7; break; + case DESC_RATEVHTSS1MCS8: + ret_rate = MPT_RATE_VHT1SS_MCS8; break; + case DESC_RATEVHTSS1MCS9: + ret_rate = MPT_RATE_VHT1SS_MCS9; break; + case DESC_RATEVHTSS2MCS0: + ret_rate = MPT_RATE_VHT2SS_MCS0; break; + case DESC_RATEVHTSS2MCS1: + ret_rate = MPT_RATE_VHT2SS_MCS1; break; + case DESC_RATEVHTSS2MCS2: + ret_rate = MPT_RATE_VHT2SS_MCS2; break; + case DESC_RATEVHTSS2MCS3: + ret_rate = MPT_RATE_VHT2SS_MCS3; break; + case DESC_RATEVHTSS2MCS4: + ret_rate = MPT_RATE_VHT2SS_MCS4; break; + case DESC_RATEVHTSS2MCS5: + ret_rate = MPT_RATE_VHT2SS_MCS5; break; + case DESC_RATEVHTSS2MCS6: + ret_rate = MPT_RATE_VHT2SS_MCS6; break; + case DESC_RATEVHTSS2MCS7: + ret_rate = MPT_RATE_VHT2SS_MCS7; break; + case DESC_RATEVHTSS2MCS8: + ret_rate = MPT_RATE_VHT2SS_MCS8; break; + case DESC_RATEVHTSS2MCS9: + ret_rate = MPT_RATE_VHT2SS_MCS9; break; + case DESC_RATEVHTSS3MCS0: + ret_rate = MPT_RATE_VHT3SS_MCS0; break; + case DESC_RATEVHTSS3MCS1: + ret_rate = MPT_RATE_VHT3SS_MCS1; break; + case DESC_RATEVHTSS3MCS2: + ret_rate = MPT_RATE_VHT3SS_MCS2; break; + case DESC_RATEVHTSS3MCS3: + ret_rate = MPT_RATE_VHT3SS_MCS3; break; + case DESC_RATEVHTSS3MCS4: + ret_rate = MPT_RATE_VHT3SS_MCS4; break; + case DESC_RATEVHTSS3MCS5: + ret_rate = MPT_RATE_VHT3SS_MCS5; break; + case DESC_RATEVHTSS3MCS6: + ret_rate = MPT_RATE_VHT3SS_MCS6; break; + case DESC_RATEVHTSS3MCS7: + ret_rate = MPT_RATE_VHT3SS_MCS7; break; + case DESC_RATEVHTSS3MCS8: + ret_rate = MPT_RATE_VHT3SS_MCS8; break; + case DESC_RATEVHTSS3MCS9: + ret_rate = MPT_RATE_VHT3SS_MCS9; break; + case DESC_RATEVHTSS4MCS0: + ret_rate = MPT_RATE_VHT4SS_MCS0; break; + case DESC_RATEVHTSS4MCS1: + ret_rate = MPT_RATE_VHT4SS_MCS1; break; + case DESC_RATEVHTSS4MCS2: + ret_rate = MPT_RATE_VHT4SS_MCS2; break; + case DESC_RATEVHTSS4MCS3: + ret_rate = MPT_RATE_VHT4SS_MCS3; break; + case DESC_RATEVHTSS4MCS4: + ret_rate = MPT_RATE_VHT4SS_MCS4; break; + case DESC_RATEVHTSS4MCS5: + ret_rate = MPT_RATE_VHT4SS_MCS5; break; + case DESC_RATEVHTSS4MCS6: + ret_rate = MPT_RATE_VHT4SS_MCS6; break; + case DESC_RATEVHTSS4MCS7: + ret_rate = MPT_RATE_VHT4SS_MCS7; break; + case DESC_RATEVHTSS4MCS8: + ret_rate = MPT_RATE_VHT4SS_MCS8; break; + case DESC_RATEVHTSS4MCS9: + ret_rate = MPT_RATE_VHT4SS_MCS9; break; + + default: + DBG_871X("HwRateToMRate(): Non supported Rate [%x]!!!\n", rate); + break; + } + return ret_rate; +} + +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( + PADAPTER pAdapter, + u8 RfPath + ) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + + ULONG TxPower = 1, PwrGroup=0, PowerDiffByRate=0; + u1Byte limit = 0, rate = 0; + + #if defined(CONFIG_RTL8188E) + if (IS_HARDWARE_TYPE_8188E(pAdapter)) + { + //return mpt_ProQueryCalTxPower_8188E(pAdapter, RfPath); + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8188E(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + + } + #endif + + #if defined(CONFIG_RTL8723B) + if( IS_HARDWARE_TYPE_8723B(pAdapter) ) + { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8723B(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + + #if defined(CONFIG_RTL8192E) + if( IS_HARDWARE_TYPE_8192E(pAdapter) ) + { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8192E(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + if( IS_HARDWARE_TYPE_JAGUAR(pAdapter) ) + { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8812A(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + #if defined(CONFIG_RTL8814A) + if ( IS_HARDWARE_TYPE_8814A(pAdapter) ) + { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8814A(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + #if defined(CONFIG_RTL8703B) + if (IS_HARDWARE_TYPE_8703B(pAdapter)) { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8703B(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + + #if defined(CONFIG_RTL8188F) + if (IS_HARDWARE_TYPE_8188F(pAdapter)) { + rate = MptToMgntRate(pAdapter->mppriv.rateidx); + TxPower = PHY_GetTxPowerIndex_8188F(pAdapter, RfPath, rate, + pHalData->CurrentChannelBW, pHalData->CurrentChannel); + } + #endif + + DBG_8192C("txPower=%d ,CurrentChannelBW=%d ,CurrentChannel=%d ,rate =%d\n", + TxPower, pHalData->CurrentChannelBW, pHalData->CurrentChannel, rate); + + pAdapter->mppriv.txpoweridx = (u8)TxPower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_A] = (u8)TxPower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_B] = (u8)TxPower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_C] = (u8)TxPower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_D] = (u8)TxPower; + hal_mpt_SetTxPower(pAdapter); + + return TxPower; +} + +#ifdef CONFIG_MP_VHT_HW_TX_MODE +static inline void dump_buf(u8 *buf, u32 len) +{ + u32 i; + + DBG_871X("-----------------Len %d----------------\n", len); + for (i = 0; i < len; i++) + DBG_871X("%2.2x-", *(buf + i)); + DBG_871X("\n"); +} + +void ByteToBit( + UCHAR *out, + bool *in, + UCHAR in_size) +{ + UCHAR i = 0, j = 0; + + for (i = 0; i < in_size; i++) { + for (j = 0; j < 8; j++) { + if (in[8*i+j]) + out[i] |= (1 << j); + } + } +} + + +void CRC16_generator( + bool *out, + bool *in, + UCHAR in_size +) +{ + UCHAR i = 0; + bool temp = 0, reg[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + for (i = 0; i < in_size; i++) {/* take one's complement and bit reverse*/ + temp = in[i]^reg[15]; + reg[15] = reg[14]; + reg[14] = reg[13]; + reg[13] = reg[12]; + reg[12] = reg[11]; + reg[11] = reg[10]; + reg[10] = reg[9]; + reg[9] = reg[8]; + reg[8] = reg[7]; + + reg[7] = reg[6]; + reg[6] = reg[5]; + reg[5] = reg[4]; + reg[4] = reg[3]; + reg[3] = reg[2]; + reg[2] = reg[1]; + reg[1] = reg[0]; + reg[12] = reg[12] ^ temp; + reg[5] = reg[5] ^ temp; + reg[0] = temp; + } + for (i = 0; i < 16; i++) /* take one's complement and bit reverse*/ + out[i] = 1-reg[15-i]; +} + + + +/*======================================== + SFD SIGNAL SERVICE LENGTH CRC + 16 bit 8 bit 8 bit 16 bit 16 bit +========================================*/ +void CCK_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ) +{ + double ratio = 0; + bool crc16_in[32] = {0}, crc16_out[16] = {0}; + bool LengthExtBit; + double LengthExact; + double LengthPSDU; + UCHAR i; + UINT PacketLength = pPMacTxInfo->PacketLength; + + if (pPMacTxInfo->bSPreamble) + pPMacTxInfo->SFD = 0x05CF; + else + pPMacTxInfo->SFD = 0xF3A0; + + switch (pPMacPktInfo->MCS) { + case 0: + pPMacTxInfo->SignalField = 0xA; + ratio = 8; + /*CRC16_in(1,0:7)=[0 1 0 1 0 0 0 0]*/ + crc16_in[1] = crc16_in[3] = 1; + break; + case 1: + pPMacTxInfo->SignalField = 0x14; + ratio = 4; + /*CRC16_in(1,0:7)=[0 0 1 0 1 0 0 0];*/ + crc16_in[2] = crc16_in[4] = 1; + break; + case 2: + pPMacTxInfo->SignalField = 0x37; + ratio = 8.0/5.5; + /*CRC16_in(1,0:7)=[1 1 1 0 1 1 0 0];*/ + crc16_in[0] = crc16_in[1] = crc16_in[2] = crc16_in[4] = crc16_in[5] = 1; + break; + case 3: + pPMacTxInfo->SignalField = 0x6E; + ratio = 8.0/11.0; + /*CRC16_in(1,0:7)=[0 1 1 1 0 1 1 0];*/ + crc16_in[1] = crc16_in[2] = crc16_in[3] = crc16_in[5] = crc16_in[6] = 1; + break; + } + + LengthExact = PacketLength*ratio; + LengthPSDU = ceil(LengthExact); + + if ((pPMacPktInfo->MCS == 3) && + ((LengthPSDU-LengthExact) >= 0.727 || (LengthPSDU-LengthExact) <= -0.727)) + LengthExtBit = 1; + else + LengthExtBit = 0; + + + pPMacTxInfo->LENGTH = (UINT)LengthPSDU; + /* CRC16_in(1,16:31) = LengthPSDU[0:15]*/ + for (i = 0; i < 16; i++) + crc16_in[i+16] = (pPMacTxInfo->LENGTH >> i) & 0x1; + + if (LengthExtBit == 0) { + pPMacTxInfo->ServiceField = 0x0; + /* CRC16_in(1,8:15) = [0 0 0 0 0 0 0 0];*/ + } else { + pPMacTxInfo->ServiceField = 0x80; + /*CRC16_in(1,8:15)=[0 0 0 0 0 0 0 1];*/ + crc16_in[15] = 1; + } + + CRC16_generator(crc16_out, crc16_in, 32); + + _rtw_memset(pPMacTxInfo->CRC16, 0, 2); + ByteToBit(pPMacTxInfo->CRC16, crc16_out, 2); + +} + + +void PMAC_Get_Pkt_Param( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo) +{ + + UCHAR TX_RATE_HEX = 0, MCS = 0; + UCHAR TX_RATE = pPMacTxInfo->TX_RATE; + + /* TX_RATE & Nss */ + if (MPT_IS_2SS_RATE(TX_RATE)) + pPMacPktInfo->Nss = 2; + else if (MPT_IS_3SS_RATE(TX_RATE)) + pPMacPktInfo->Nss = 3; + else if (MPT_IS_4SS_RATE(TX_RATE)) + pPMacPktInfo->Nss = 4; + else + pPMacPktInfo->Nss = 1; + + DBG_871X("PMacTxInfo.Nss =%d\n", pPMacPktInfo->Nss); + + /* MCS & TX_RATE_HEX*/ + if (MPT_IS_CCK_RATE(TX_RATE)) { + switch (TX_RATE) { + case MPT_RATE_1M: + TX_RATE_HEX = MCS = 0; break; + case MPT_RATE_2M: + TX_RATE_HEX = MCS = 1; break; + case MPT_RATE_55M: + TX_RATE_HEX = MCS = 2; break; + case MPT_RATE_11M: + TX_RATE_HEX = MCS = 3; break; + } + } else if (MPT_IS_OFDM_RATE(TX_RATE)) { + MCS = TX_RATE - MPT_RATE_6M; + TX_RATE_HEX = MCS + 4; + } else if (MPT_IS_HT_RATE(TX_RATE)) { + MCS = TX_RATE - MPT_RATE_MCS0; + TX_RATE_HEX = MCS + 12; + } else if (MPT_IS_VHT_RATE(TX_RATE)) { + TX_RATE_HEX = TX_RATE - MPT_RATE_VHT1SS_MCS0 + 44; + + if (MPT_IS_VHT_2S_RATE(TX_RATE)) + MCS = TX_RATE - MPT_RATE_VHT2SS_MCS0; + else if (MPT_IS_VHT_3S_RATE(TX_RATE)) + MCS = TX_RATE - MPT_RATE_VHT3SS_MCS0; + else if (MPT_IS_VHT_4S_RATE(TX_RATE)) + MCS = TX_RATE - MPT_RATE_VHT4SS_MCS0; + else + MCS = TX_RATE - MPT_RATE_VHT1SS_MCS0; + } + + pPMacPktInfo->MCS = MCS; + pPMacTxInfo->TX_RATE_HEX = TX_RATE_HEX; + + DBG_871X(" MCS=%d, TX_RATE_HEX =0x%x\n", MCS, pPMacTxInfo->TX_RATE_HEX); + /* mSTBC & Nsts*/ + pPMacPktInfo->Nsts = pPMacPktInfo->Nss; + if (pPMacTxInfo->bSTBC) { + if (pPMacPktInfo->Nss == 1) { + pPMacTxInfo->m_STBC = 2; + pPMacPktInfo->Nsts = pPMacPktInfo->Nss*2; + } else + pPMacTxInfo->m_STBC = 1; + } else + pPMacTxInfo->m_STBC = 1; +} + + +UINT LDPC_parameter_generator( + UINT N_pld_int, + UINT N_CBPSS, + UINT N_SS, + UINT R, + UINT m_STBC, + UINT N_TCB_int +) +{ + double CR = 0.; + double N_pld = (double)N_pld_int; + double N_TCB = (double)N_TCB_int; + double N_CW = 0., N_shrt = 0., N_spcw = 0., N_fshrt = 0.; + double L_LDPC = 0., K_LDPC = 0., L_LDPC_info = 0.; + double N_punc = 0., N_ppcw = 0., N_fpunc = 0., N_rep = 0., N_rpcw = 0., N_frep = 0.; + double R_eff = 0.; + UINT VHTSIGA2B3 = 0;/* extra symbol from VHT-SIG-A2 Bit 3*/ + + if (R == 0) + CR = 0.5; + else if (R == 1) + CR = 2./3.; + else if (R == 2) + CR = 3./4.; + else if (R == 3) + CR = 5./6.; + + if (N_TCB <= 648.) { + N_CW = 1.; + if (N_TCB >= N_pld+912.*(1.-CR)) + L_LDPC = 1296.; + else + L_LDPC = 648.; + } else if (N_TCB <= 1296.) { + N_CW = 1.; + if (N_TCB >= (double)N_pld + 1464.*(1.-CR)) + L_LDPC = 1944.; + else + L_LDPC = 1296.; + } else if (N_TCB <= 1944.) { + N_CW = 1.; + L_LDPC = 1944.; + } else if (N_TCB <= 2592.) { + N_CW = 2.; + if (N_TCB >= N_pld+2916.*(1.-CR)) + L_LDPC = 1944.; + else + L_LDPC = 1296.; + } else { + N_CW = ceil(N_pld/1944./CR); + L_LDPC = 1944.; + } + /* Number of information bits per CW*/ + K_LDPC = L_LDPC*CR; + /* Number of shortening bits max(0, (N_CW * L_LDPC * R) - N_pld)*/ + N_shrt = (N_CW*K_LDPC-N_pld) > 0. ? (N_CW*K_LDPC-N_pld) : 0.; + /* Number of shortening bits per CW N_spcw = rtfloor(N_shrt/N_CW)*/ + N_spcw = rtfloor(N_shrt/N_CW); + /* The first N_fshrt CWs shorten 1 bit more*/ + N_fshrt = (double)((int)N_shrt % (int)N_CW); + /* Number of data bits for the last N_CW-N_fshrt CWs*/ + L_LDPC_info = K_LDPC-N_spcw; + /* Number of puncturing bits*/ + N_punc = (N_CW*L_LDPC-N_TCB-N_shrt) > 0. ? (N_CW*L_LDPC-N_TCB-N_shrt) : 0.; + if (((N_punc > .1 * N_CW * L_LDPC * (1.-CR)) && (N_shrt < 1.2 * N_punc * CR/(1.-CR))) || + (N_punc > 0.3*N_CW*L_LDPC*(1.-CR))) { + /*cout << "*** N_TCB and N_punc are Recomputed ***" << endl;*/ + VHTSIGA2B3 = 1; + N_TCB += (double)N_CBPSS*N_SS*m_STBC; + N_punc = (N_CW*L_LDPC-N_TCB-N_shrt) > 0. ? (N_CW*L_LDPC-N_TCB-N_shrt) : 0.; + } else + VHTSIGA2B3 = 0; + + return VHTSIGA2B3; +} /* function end of LDPC_parameter_generator */ + +/*======================================== + Data field of PPDU + Get N_sym and SIGA2BB3 +========================================*/ +void PMAC_Nsym_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo) +{ + UINT SIGA2B3 = 0; + UCHAR TX_RATE = pPMacTxInfo->TX_RATE; + + UINT R, R_list[10] = {0, 0, 2, 0, 2, 1, 2, 3, 2, 3}; + double CR = 0; + UINT N_SD, N_BPSC_list[10] = {1, 2, 2, 4, 4, 6, 6, 6, 8, 8}; + UINT N_BPSC = 0, N_CBPS = 0, N_DBPS = 0, N_ES = 0, N_SYM = 0, N_pld = 0, N_TCB = 0; + int D_R = 0; + + DBG_871X("TX_RATE = %d\n", TX_RATE); + /* N_SD*/ + if (pPMacTxInfo->BandWidth == 0) + N_SD = 52; + else if (pPMacTxInfo->BandWidth == 1) + N_SD = 108; + else + N_SD = 234; + + if (MPT_IS_HT_RATE(TX_RATE)) { + UCHAR MCS_temp; + + if (pPMacPktInfo->MCS > 23) + MCS_temp = pPMacPktInfo->MCS - 24; + else if (pPMacPktInfo->MCS > 15) + MCS_temp = pPMacPktInfo->MCS - 16; + else if (pPMacPktInfo->MCS > 7) + MCS_temp = pPMacPktInfo->MCS - 8; + else + MCS_temp = pPMacPktInfo->MCS; + + R = R_list[MCS_temp]; + + switch (R) { + case 0: + CR = .5; break; + case 1: + CR = 2./3.; break; + case 2: + CR = 3./4.; break; + case 3: + CR = 5./6.; break; + } + + N_BPSC = N_BPSC_list[MCS_temp]; + N_CBPS = N_BPSC*N_SD*pPMacPktInfo->Nss; + N_DBPS = (UINT)((double)N_CBPS*CR); + + if (pPMacTxInfo->bLDPC == FALSE) { + N_ES = (UINT)ceil((double)(N_DBPS * pPMacPktInfo->Nss)/4./300.); + DBG_871X("N_ES = %d\n", N_ES); + + /* N_SYM = m_STBC* (8*length+16+6*N_ES) / (m_STBC*N_DBPS)*/ + N_SYM = pPMacTxInfo->m_STBC*(UINT)ceil((double)(pPMacTxInfo->PacketLength*8+16+N_ES*6)/ + (double)(N_DBPS*pPMacTxInfo->m_STBC)); + + } else { + N_ES = 1; + /* N_pld = length * 8 + 16*/ + N_pld = pPMacTxInfo->PacketLength*8+16; + DBG_871X("N_pld = %d\n", N_pld); + N_SYM = pPMacTxInfo->m_STBC*(UINT)ceil((double)(N_pld)/ + (double)(N_DBPS*pPMacTxInfo->m_STBC)); + DBG_871X("N_SYM = %d\n", N_SYM); + /* N_avbits = N_CBPS *m_STBC *(N_pld/N_CBPS*R*m_STBC)*/ + N_TCB = N_CBPS*N_SYM; + DBG_871X("N_TCB = %d\n", N_TCB); + SIGA2B3 = LDPC_parameter_generator(N_pld, N_CBPS, pPMacPktInfo->Nss, R, pPMacTxInfo->m_STBC, N_TCB); + DBG_871X("SIGA2B3 = %d\n", SIGA2B3); + N_SYM = N_SYM + SIGA2B3*pPMacTxInfo->m_STBC; + DBG_871X("N_SYM = %d\n", N_SYM); + } + } else if (MPT_IS_VHT_RATE(TX_RATE)) { + R = R_list[pPMacPktInfo->MCS]; + + switch (R) { + case 0: + CR = .5; break; + case 1: + CR = 2./3.; break; + case 2: + CR = 3./4.; break; + case 3: + CR = 5./6.; break; + } + N_BPSC = N_BPSC_list[pPMacPktInfo->MCS]; + N_CBPS = N_BPSC*N_SD*pPMacPktInfo->Nss; + N_DBPS = (UINT)((double)N_CBPS*CR); + if (pPMacTxInfo->bLDPC == FALSE) { + if (pPMacTxInfo->bSGI) + N_ES = (UINT)ceil((double)(N_DBPS)/3.6/600.); + else + N_ES = (UINT)ceil((double)(N_DBPS)/4./600.); + /* N_SYM = m_STBC* (8*length+16+6*N_ES) / (m_STBC*N_DBPS)*/ + N_SYM = pPMacTxInfo->m_STBC*(UINT)ceil((double)(pPMacTxInfo->PacketLength*8+16+N_ES*6)/(double)(N_DBPS*pPMacTxInfo->m_STBC)); + SIGA2B3 = 0; + } else { + N_ES = 1; + /* N_SYM = m_STBC* (8*length+N_service) / (m_STBC*N_DBPS)*/ + N_SYM = pPMacTxInfo->m_STBC*(UINT)ceil((double)(pPMacTxInfo->PacketLength*8+16)/(double)(N_DBPS*pPMacTxInfo->m_STBC)); + /* N_avbits = N_sys_init * N_CBPS*/ + N_TCB = N_CBPS * N_SYM; + /* N_pld = N_sys_init * N_DBPS*/ + N_pld = N_SYM * N_DBPS; + SIGA2B3 = LDPC_parameter_generator(N_pld, N_CBPS, pPMacPktInfo->Nss, R, pPMacTxInfo->m_STBC, N_TCB); + N_SYM = N_SYM + SIGA2B3*pPMacTxInfo->m_STBC; + } + + switch (R) { + case 0: + D_R = 2; break; + case 1: + D_R = 3; break; + case 2: + D_R = 4; break; + case 3: + D_R = 6; break; + } + + if (((N_CBPS/N_ES)%D_R) != 0) { + DBG_871X("MCS= %d is not supported when Nss=%d and BW= %d !!\n", pPMacPktInfo->MCS, pPMacPktInfo->Nss, pPMacTxInfo->BandWidth); + return; + } + + DBG_871X("MCS= %d Nss=%d and BW= %d !!\n", pPMacPktInfo->MCS, pPMacPktInfo->Nss, pPMacTxInfo->BandWidth); + } + + pPMacPktInfo->N_sym = N_SYM; + pPMacPktInfo->SIGA2B3 = SIGA2B3; +} + +/*======================================== + L-SIG Rate R Length P Tail + 4b 1b 12b 1b 6b +========================================*/ + +void L_SIG_generator( + UINT N_SYM, /* Max: 750*/ + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo) +{ + u8 sig_bi[24] = {0}; /* 24 BIT*/ + UINT mode, LENGTH; + int i; + + if (MPT_IS_OFDM_RATE(pPMacTxInfo->TX_RATE)) { + mode = pPMacPktInfo->MCS; + LENGTH = pPMacTxInfo->PacketLength; + } else { + UCHAR N_LTF; + double T_data; + UINT OFDM_symbol; + + mode = 0; + + /* Table 20-13 Num of HT-DLTFs request*/ + if (pPMacPktInfo->Nsts <= 2) + N_LTF = pPMacPktInfo->Nsts; + else + N_LTF = 4; + + if (pPMacTxInfo->bSGI) + T_data = 3.6; + else + T_data = 4.0; + + /*(L-SIG, HT-SIG, HT-STF, HT-LTF....HT-LTF, Data)*/ + if (MPT_IS_VHT_RATE(pPMacTxInfo->TX_RATE)) + OFDM_symbol = (UINT)ceil((double)(8+4+N_LTF*4+N_SYM*T_data+4)/4.); + else + OFDM_symbol = (UINT)ceil((double)(8+4+N_LTF*4+N_SYM*T_data)/4.); + + DBG_871X("%s , OFDM_symbol =%d\n", __func__, OFDM_symbol); + LENGTH = OFDM_symbol*3-3; + DBG_871X("%s , LENGTH =%d\n", __func__, LENGTH); + + } + /* Rate Field*/ + switch (mode) { + case 0: + sig_bi[0] = 1; sig_bi[1] = 1; sig_bi[2] = 0; sig_bi[3] = 1; + break; + case 1: + sig_bi[0] = 1; sig_bi[1] = 1; sig_bi[2] = 1; sig_bi[3] = 1; + break; + case 2: + sig_bi[0] = 0; sig_bi[1] = 1; sig_bi[2] = 0; sig_bi[3] = 1; + break; + case 3: + sig_bi[0] = 0; sig_bi[1] = 1; sig_bi[2] = 1; sig_bi[3] = 1; + break; + case 4: + sig_bi[0] = 1; sig_bi[1] = 0; sig_bi[2] = 0; sig_bi[3] = 1; + break; + case 5: + sig_bi[0] = 1; sig_bi[1] = 0; sig_bi[2] = 1; sig_bi[3] = 1; + break; + case 6: + sig_bi[0] = 0; sig_bi[1] = 0; sig_bi[2] = 0; sig_bi[3] = 1; + break; + case 7: + sig_bi[0] = 0; sig_bi[1] = 0; sig_bi[2] = 1; sig_bi[3] = 1; + break; + } + /*Reserved bit*/ + sig_bi[4] = 0; + + /* Length Field*/ + for (i = 0; i < 12; i++) + sig_bi[i+5] = (LENGTH>>i) & 1; + + /* Parity Bit*/ + sig_bi[17] = 0; + for (i = 0; i < 17; i++) + sig_bi[17] = sig_bi[17] + sig_bi[i]; + + sig_bi[17] %= 2; + + /* Tail Field*/ + for (i = 18; i < 24; i++) + sig_bi[i] = 0; + + /* dump_buf(sig_bi,24);*/ + _rtw_memset(pPMacTxInfo->LSIG, 0, 3); + ByteToBit(pPMacTxInfo->LSIG, (bool *)sig_bi, 3); +} + + +void CRC8_generator( + bool *out, + bool *in, + UCHAR in_size + ) +{ + UCHAR i = 0; + bool temp = 0, reg[] = {1, 1, 1, 1, 1, 1, 1, 1}; + + for (i = 0; i < in_size; i++) { /* take one's complement and bit reverse*/ + temp = in[i]^reg[7]; + reg[7] = reg[6]; + reg[6] = reg[5]; + reg[5] = reg[4]; + reg[4] = reg[3]; + reg[3] = reg[2]; + reg[2] = reg[1] ^ temp; + reg[1] = reg[0] ^ temp; + reg[0] = temp; + } + for (i = 0; i < 8; i++)/* take one's complement and bit reverse*/ + out[i] = reg[7-i]^1; + } + +/*/================================================================================ + HT-SIG1 MCS CW Length 24BIT + 24BIT + 7b 1b 16b + HT-SIG2 Smoothing Not sounding Rsvd AGG STBC FEC SGI N_ELTF CRC Tail + 1b 1b 1b 1b 2b 1b 1b 2b 8b 6b +================================================================================*/ +void HT_SIG_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ) +{ + UINT i; + bool sig_bi[48] = {0}, crc8[8] = {0}; + /* MCS Field*/ + for (i = 0; i < 7; i++) + sig_bi[i] = (pPMacPktInfo->MCS >> i) & 0x1; + /* Packet BW Setting*/ + sig_bi[7] = pPMacTxInfo->BandWidth; + /* HT-Length Field*/ + for (i = 0; i < 16; i++) + sig_bi[i+8] = (pPMacTxInfo->PacketLength >> i) & 0x1; + /* Smoothing; 1->allow smoothing*/ + sig_bi[24] = 1; + /*Not Sounding*/ + sig_bi[25] = 1-pPMacTxInfo->NDP_sound; + /*Reserved bit*/ + sig_bi[26] = 1; + /*/Aggregate*/ + sig_bi[27] = 0; + /*STBC Field*/ + if (pPMacTxInfo->bSTBC) { + sig_bi[28] = 1; + sig_bi[29] = 0; + } else { + sig_bi[28] = 0; + sig_bi[29] = 0; + } + /*Advance Coding, 0: BCC, 1: LDPC*/ + sig_bi[30] = pPMacTxInfo->bLDPC; + /* Short GI*/ + sig_bi[31] = pPMacTxInfo->bSGI; + /* N_ELTFs*/ + if (pPMacTxInfo->NDP_sound == FALSE) { + sig_bi[32] = 0; + sig_bi[33] = 0; + } else { + int N_ELTF = pPMacTxInfo->Ntx - pPMacPktInfo->Nss; + + for (i = 0; i < 2; i++) + sig_bi[32+i] = (N_ELTF>>i)%2; + } + /* CRC-8*/ + CRC8_generator(crc8, sig_bi, 34); + + for (i = 0; i < 8; i++) + sig_bi[34+i] = crc8[i]; + + /*Tail*/ + for (i = 42; i < 48; i++) + sig_bi[i] = 0; + + _rtw_memset(pPMacTxInfo->HT_SIG, 0, 6); + ByteToBit(pPMacTxInfo->HT_SIG, sig_bi, 6); +} + + +/*====================================================================================== + VHT-SIG-A1 + BW Reserved STBC G_ID SU_Nsts P_AID TXOP_PS_NOT_ALLOW Reserved + 2b 1b 1b 6b 3b 9b 1b 2b 1b + VHT-SIG-A2 + SGI SGI_Nsym SU/MU coding LDPC_Extra SU_NCS Beamformed Reserved CRC Tail + 1b 1b 1b 1b 4b 1b 1b 8b 6b +======================================================================================*/ +void VHT_SIG_A_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo) +{ + UINT i; + bool sig_bi[48], crc8[8]; + + _rtw_memset(sig_bi, 0, 48); + _rtw_memset(crc8, 0, 8); + + /* BW Setting*/ + for (i = 0; i < 2; i++) + sig_bi[i] = (pPMacTxInfo->BandWidth>>i) & 0x1; + /* Reserved Bit*/ + sig_bi[2] = 1; + /*STBC Field*/ + sig_bi[3] = pPMacTxInfo->bSTBC; + /*Group ID: Single User -> A value of 0 or 63 indicates an SU PPDU. */ + for (i = 0; i < 6; i++) + sig_bi[4+i] = 0; + /* N_STS/Partial AID*/ + for (i = 0; i < 12; i++) { + if (i < 3) + sig_bi[10+i] = ((pPMacPktInfo->Nsts - 1)>>i) & 0x1; + else + sig_bi[10+i] = 0; + } + /*TXOP_PS_NOT_ALLPWED*/ + sig_bi[22] = 0; + /*Reserved Bits*/ + sig_bi[23] = 1; + /*Short GI*/ + sig_bi[24] = pPMacTxInfo->bSGI; + if (pPMacTxInfo->bSGI > 0 && (pPMacPktInfo->N_sym%10) == 9) + sig_bi[25] = 1; + else + sig_bi[25] = 0; + /* SU/MU[0] Coding*/ + sig_bi[26] = pPMacTxInfo->bLDPC; /* 0:BCC, 1:LDPC */ + sig_bi[27] = pPMacPktInfo->SIGA2B3; /*/ Record Extra OFDM Symols is added or not when LDPC is used*/ + /*SU MCS/MU[1-3] Coding*/ + for (i = 0; i < 4; i++) + sig_bi[28+i] = (pPMacPktInfo->MCS>>i) & 0x1; + /*SU Beamform */ + sig_bi[32] = 0; /*packet.TXBF_en;*/ + /*Reserved Bit*/ + sig_bi[33] = 1; + /*CRC-8*/ + CRC8_generator(crc8, sig_bi, 34); + for (i = 0; i < 8; i++) + sig_bi[34+i] = crc8[i]; + /*Tail*/ + for (i = 42; i < 48; i++) + sig_bi[i] = 0; + + _rtw_memset(pPMacTxInfo->VHT_SIG_A, 0, 6); + ByteToBit(pPMacTxInfo->VHT_SIG_A, sig_bi, 6); +} + +/*====================================================================================== + VHT-SIG-B + Length Resesrved Trail + 17/19/21 BIT 3/2/2 BIT 6b +======================================================================================*/ +void VHT_SIG_B_generator( + PRT_PMAC_TX_INFO pPMacTxInfo) +{ + bool sig_bi[32], crc8_bi[8]; + UINT i, len, res, tail = 6, total_len, crc8_in_len; + UINT sigb_len; + + _rtw_memset(sig_bi, 0, 32); + _rtw_memset(crc8_bi, 0, 8); + + /*Sounding Packet*/ + if (pPMacTxInfo->NDP_sound == 1) { + if (pPMacTxInfo->BandWidth == 0) { + bool sigb_temp[26] = {0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; + + _rtw_memcpy(sig_bi, sigb_temp, 26); + } else if (pPMacTxInfo->BandWidth == 1) { + bool sigb_temp[27] = {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}; + + _rtw_memcpy(sig_bi, sigb_temp, 27); + } else if (pPMacTxInfo->BandWidth == 2) { + bool sigb_temp[29] = {0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; + + _rtw_memcpy(sig_bi, sigb_temp, 29); + } + } else { /* Not NDP Sounding*/ + bool *sigb_temp[29] = {0}; + + if (pPMacTxInfo->BandWidth == 0) { + len = 17; res = 3; + } else if (pPMacTxInfo->BandWidth == 1) { + len = 19; res = 2; + } else if (pPMacTxInfo->BandWidth == 2) { + len = 21; res = 2; + } else { + len = 21; res = 2; + } + total_len = len+res+tail; + crc8_in_len = len+res; + + /*Length Field*/ + sigb_len = (pPMacTxInfo->PacketLength + 3) >> 2; + + for (i = 0; i < len; i++) + sig_bi[i] = (sigb_len>>i) & 0x1; + /*Reserved Field*/ + for (i = 0; i < res; i++) + sig_bi[len+i] = 1; + /* CRC-8*/ + CRC8_generator(crc8_bi, sig_bi, crc8_in_len); + + /* Tail */ + for (i = 0; i < tail; i++) + sig_bi[len+res+i] = 0; + } + + _rtw_memset(pPMacTxInfo->VHT_SIG_B, 0, 4); + ByteToBit(pPMacTxInfo->VHT_SIG_B, sig_bi, 4); + + pPMacTxInfo->VHT_SIG_B_CRC = 0; + ByteToBit(&(pPMacTxInfo->VHT_SIG_B_CRC), crc8_bi, 1); +} + +/*======================= + VHT Delimiter +=======================*/ +void VHT_Delimiter_generator( + PRT_PMAC_TX_INFO pPMacTxInfo + ) +{ + bool sig_bi[32] = {0}, crc8[8] = {0}; + UINT crc8_in_len = 16; + UINT PacketLength = pPMacTxInfo->PacketLength; + int j; + + /* Delimiter[0]: EOF*/ + sig_bi[0] = 1; + /* Delimiter[1]: Reserved*/ + sig_bi[1] = 0; + /* Delimiter[3:2]: MPDU Length High*/ + sig_bi[2] = ((PacketLength - 4) >> 12) % 2; + sig_bi[3] = ((PacketLength - 4) >> 13) % 2; + /* Delimiter[15:4]: MPDU Length Low*/ + for (j = 4; j < 16; j++) + sig_bi[j] = ((PacketLength - 4) >> (j-4)) % 2; + CRC8_generator(crc8, sig_bi, crc8_in_len); + for (j = 16; j < 24; j++) /* Delimiter[23:16]: CRC 8*/ + sig_bi[j] = crc8[j-16]; + for (j = 24; j < 32; j++) /* Delimiter[31:24]: Signature ('4E' in Hex, 78 in Dec)*/ + sig_bi[j] = (78 >> (j-24)) % 2; + + _rtw_memset(pPMacTxInfo->VHT_Delimiter, 0, 4); + ByteToBit(pPMacTxInfo->VHT_Delimiter, sig_bi, 4); +} + +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp_ioctl.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp_ioctl.c new file mode 100644 index 00000000..ff0c66b3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_mp_ioctl.c @@ -0,0 +1,2946 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_MP_IOCTL_C_ + +#include +#include +#include "../hal/phydm/phydm_precomp.h" + +//**************** oid_rtl_seg_81_85 section start **************** +NDIS_STATUS oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) { + Adapter->registrypriv.wireless_mode = *(u8*)poid_par_priv->information_buf; + } else if (poid_par_priv->type_of_oid == QUERY_OID) { + *(u8*)poid_par_priv->information_buf = Adapter->registrypriv.wireless_mode; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_info_, ("-query Wireless Mode=%d\n", Adapter->registrypriv.wireless_mode)); + } else { + status = NDIS_STATUS_NOT_ACCEPTED; + } + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_87_80 section start **************** +NDIS_STATUS oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct bb_reg_param *pbbreg; + u16 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_write_bb_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); + + offset = (u16)(pbbreg->offset) & 0xFFF; //0ffset :0x800~0xfff + if (offset < BB_REG_BASE_ADDR) offset |= BB_REG_BASE_ADDR; + + value = pbbreg->value; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_write_bb_reg_hdl: offset=0x%03X value=0x%08X\n", + offset, value)); + + _irqlevel_changed_(&oldirql, LOWER); + write_bbreg(Adapter, offset, 0xFFFFFFFF, value); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct bb_reg_param *pbbreg; + u16 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_bb_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); + + offset = (u16)(pbbreg->offset) & 0xFFF; //0ffset :0x800~0xfff + if (offset < BB_REG_BASE_ADDR) offset |= BB_REG_BASE_ADDR; + + _irqlevel_changed_(&oldirql, LOWER); + value = read_bbreg(Adapter, offset, 0xFFFFFFFF); + _irqlevel_changed_(&oldirql, RAISE); + + pbbreg->value = value; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_read_bb_reg_hdl: offset=0x%03X value:0x%08X\n", + offset, value)); +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct rf_reg_param *pbbreg; + u8 path; + u8 offset; + u32 value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_write_rf_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); + + if (pbbreg->path >= MAX_RF_PATH_NUMS) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->offset > 0xFF) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->value > 0xFFFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + path = (u8)pbbreg->path; + offset = (u8)pbbreg->offset; + value = pbbreg->value; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_write_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n", + path, offset, value)); + + _irqlevel_changed_(&oldirql, LOWER); + write_rfreg(Adapter, path, offset, value); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + struct rf_reg_param *pbbreg; + u8 path; + u8 offset; + u32 value; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_rf_reg_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) + return NDIS_STATUS_INVALID_LENGTH; + + pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); + + if (pbbreg->path >= MAX_RF_PATH_NUMS) + return NDIS_STATUS_NOT_ACCEPTED; + if (pbbreg->offset > 0xFF) + return NDIS_STATUS_NOT_ACCEPTED; + + path = (u8)pbbreg->path; + offset = (u8)pbbreg->offset; + + _irqlevel_changed_(&oldirql, LOWER); + value = read_rfreg(Adapter, path, offset); + _irqlevel_changed_(&oldirql, RAISE); + + pbbreg->value = value; + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_read_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n", + path, offset, value)); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_87_00 section end**************** +//------------------------------------------------------------------------------ + +//**************** oid_rtl_seg_81_80_00 section start **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 ratevalue;//4 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_set_data_rate_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + ratevalue = *((u32*)poid_par_priv->information_buf);//4 + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_data_rate_hdl: data rate idx=%d\n", ratevalue)); + if (ratevalue >= MPT_RATE_LAST) + return NDIS_STATUS_INVALID_DATA; + + Adapter->mppriv.rateidx = ratevalue; + + _irqlevel_changed_(&oldirql, LOWER); + SetDataRate(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 mode; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_start_test_hdl\n")); + + if (Adapter->registrypriv.mp_mode == 0) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + //IQCalibrateBcut(Adapter); + + mode = *((u32*)poid_par_priv->information_buf); + Adapter->mppriv.mode = mode;// 1 for loopback + + if (mp_start_test(Adapter) == _FAIL) { + status = NDIS_STATUS_NOT_ACCEPTED; + goto exit; + } + +exit: + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, ("-oid_rt_pro_start_test_hdl: mp_mode=%d\n", Adapter->mppriv.mode)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_STOP_TEST\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + mp_stop_test(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, ("-Set OID_RT_PRO_STOP_TEST\n")); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 Channel; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_channel_direct_call_hdl\n")); + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == QUERY_OID) { + *((u32*)poid_par_priv->information_buf) = Adapter->mppriv.channel; + return NDIS_STATUS_SUCCESS; + } + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + Channel = *((u32*)poid_par_priv->information_buf); + RT_TRACE(_module_mp_, _drv_notice_, ("oid_rt_pro_set_channel_direct_call_hdl: Channel=%d\n", Channel)); + if (Channel > 14) + return NDIS_STATUS_NOT_ACCEPTED; + Adapter->mppriv.channel = Channel; + + _irqlevel_changed_(&oldirql, LOWER); + SetChannel(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u16 bandwidth; + u16 channel_offset; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_set_bandwidth_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + bandwidth = *((u32*)poid_par_priv->information_buf);//4 + channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (bandwidth != CHANNEL_WIDTH_40) + bandwidth = CHANNEL_WIDTH_20; + padapter->mppriv.bandwidth = (u8)bandwidth; + padapter->mppriv.prime_channel_offset = (u8)channel_offset; + + _irqlevel_changed_(&oldirql, LOWER); + SetBandwidth(padapter); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_set_bandwidth_hdl: bandwidth=%d channel_offset=%d\n", + bandwidth, channel_offset)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 antenna; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_antenna_bb_hdl\n")); + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) + { + antenna = *(u32*)poid_par_priv->information_buf; + + Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); + Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_antenna_bb_hdl: tx_ant=0x%04x rx_ant=0x%04x\n", + Adapter->mppriv.antenna_tx, Adapter->mppriv.antenna_rx)); + + _irqlevel_changed_(&oldirql, LOWER); + SetAntenna(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + } else { + antenna = (Adapter->mppriv.antenna_tx << 16)|Adapter->mppriv.antenna_rx; + *(u32*)poid_par_priv->information_buf = antenna; + } + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 tx_pwr_idx; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_set_tx_power_control_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + tx_pwr_idx = *((u32*)poid_par_priv->information_buf); + if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) + return NDIS_STATUS_NOT_ACCEPTED; + + Adapter->mppriv.txpoweridx = (u8)tx_pwr_idx; + + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_set_tx_power_control_hdl: idx=0x%2x\n", + Adapter->mppriv.txpoweridx)); + + _irqlevel_changed_(&oldirql, LOWER); + SetTxPower(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +//------------------------------------------------------------------------------ +//**************** oid_rtl_seg_81_80_20 section start **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid !=QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.tx_pktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_query_rx_packet_received_hdl.\n")); + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.rx_pktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_alert_, ("recv_ok:%d \n",Adapter->mppriv.rx_pktcount)); + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_query_rx_packet_crc32_error_hdl.\n")); + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + *(ULONG*)poid_par_priv->information_buf = Adapter->mppriv.rx_crcerrpktcount; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + RT_TRACE(_module_mp_, _drv_alert_, ("recv_err:%d \n",Adapter->mppriv.rx_crcerrpktcount)); + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ + +NDIS_STATUS oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + RT_TRACE(_module_mp_, _drv_alert_, ("===> oid_rt_pro_reset_tx_packet_sent_hdl.\n")); + Adapter->mppriv.tx_pktcount = 0; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + if (poid_par_priv->information_buf_len == sizeof(ULONG)) { + Adapter->mppriv.rx_pktcount = 0; + Adapter->mppriv.rx_crcerrpktcount = 0; + } else { + status = NDIS_STATUS_INVALID_LENGTH; + } + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + _irqlevel_changed_(&oldirql, LOWER); + ResetPhyRxPktCount(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_get_phy_rx_packet_received_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len != sizeof(ULONG)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + *(ULONG*)poid_par_priv->information_buf = GetPhyRxPktReceived(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, ("-oid_rt_get_phy_rx_packet_received_hdl: recv_ok=%d\n", *(ULONG*)poid_par_priv->information_buf)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_get_phy_rx_packet_crc32_error_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + + if (poid_par_priv->information_buf_len != sizeof(ULONG)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + *(ULONG*)poid_par_priv->information_buf = GetPhyRxPktCRC32Error(Adapter); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_get_phy_rx_packet_crc32_error_hdl: recv_err=%d\n", *(ULONG*)poid_par_priv->information_buf)); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_80_20 section end **************** +NDIS_STATUS oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_continuous_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetContinuousTx(Adapter,(u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_alert_, ("+oid_rt_pro_set_single_carrier_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetSingleCarrierTx(Adapter, (u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_set_carrier_suppression_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetCarrierSuppressionTx(Adapter, (u8)bStartTest); + if (bStartTest) { + struct mp_priv *pmp_priv = &Adapter->mppriv; + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + DBG_871X("%s: pkt tx is running...\n", __func__); + rtw_msleep_os(5); + } + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(Adapter); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 bStartTest; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_alert_, ("+oid_rt_pro_set_single_tone_tx_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + bStartTest = *((u32*)poid_par_priv->information_buf); + + _irqlevel_changed_(&oldirql, LOWER); + SetSingleToneTx(Adapter,(u8)bStartTest); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_modulation_hdl(struct oid_par_priv* poid_par_priv) +{ + return 0; +} + +NDIS_STATUS oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv) +{ + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_hal_set_hwreg(Adapter, HW_VAR_TRIGGER_GPIO_0, 0); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//**************** oid_rtl_seg_81_80_00 section end **************** +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PNDIS_802_11_SSID pssid; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = (u32)sizeof(NDIS_802_11_SSID); + *poid_par_priv->bytes_rw = 0; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + pssid = (PNDIS_802_11_SSID)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (mp_start_joinbss(Adapter, pssid) == _FAIL) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = sizeof(NDIS_802_11_SSID); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pRW_Reg RegRWStruct; + u32 offset, width; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_pro_read_register_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RegRWStruct = (pRW_Reg)poid_par_priv->information_buf; + offset = RegRWStruct->offset; + width = RegRWStruct->width; + + if (offset > 0xFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + switch (width) { + case 1: + RegRWStruct->value = rtw_read8(Adapter, offset); + break; + case 2: + RegRWStruct->value = rtw_read16(Adapter, offset); + break; + default: + width = 4; + RegRWStruct->value = rtw_read32(Adapter, offset); + break; + } + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_read_register_hdl: offset:0x%04X value:0x%X\n", + offset, RegRWStruct->value)); + + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = width; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pRW_Reg RegRWStruct; + u32 offset, width, value; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, + ("+oid_rt_pro_write_register_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RegRWStruct = (pRW_Reg)poid_par_priv->information_buf; + offset = RegRWStruct->offset; + width = RegRWStruct->width; + value = RegRWStruct->value; + + if (offset > 0xFFF) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + switch (RegRWStruct->width) + { + case 1: + if (value > 0xFF) { + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + rtw_write8(padapter, offset, (u8)value); + break; + case 2: + if (value > 0xFFFF) { + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + rtw_write16(padapter, offset, (u16)value); + break; + case 4: + rtw_write32(padapter, offset, value); + break; + default: + status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_write_register_hdl: offset=0x%08X width=%d value=0x%X\n", + offset, width, value)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pBurst_RW_Reg pBstRwReg; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_burst_read_register_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pBstRwReg = (pBurst_RW_Reg)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_read_mem(padapter, pBstRwReg->offset, (u32)pBstRwReg->len, pBstRwReg->Data); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_burst_read_register_hdl\n")); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pBurst_RW_Reg pBstRwReg; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_burst_write_register_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pBstRwReg = (pBurst_RW_Reg)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + rtw_write_mem(padapter, pBstRwReg->offset, (u32)pBstRwReg->len, pBstRwReg->Data); + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_burst_write_register_hdl\n")); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + + TX_CMD_Desc *TxCmd_Info; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + RT_TRACE(_module_mp_, _drv_info_, ("+Set OID_RT_PRO_WRITE_TXCMD\n")); + + TxCmd_Info=(TX_CMD_Desc*)poid_par_priv->information_buf; + + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:Addr=%.8X\n", TxCmd_Info->offset)); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:1.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[0])); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:2.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[1])); + RT_TRACE(_module_mp_, _drv_info_, (("WRITE_TXCMD:3.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[2])); + RT_TRACE(_module_mp_, _drv_info_, ("WRITE_TXCMD:4.)%.8X\n", (ULONG)TxCmd_Info->TxCMD.value[3])); + + _irqlevel_changed_(&oldirql, LOWER); + + rtw_write32(Adapter, TxCmd_Info->offset + 0, (unsigned int)TxCmd_Info->TxCMD.value[0]); + rtw_write32(Adapter, TxCmd_Info->offset + 4, (unsigned int)TxCmd_Info->TxCMD.value[1]); + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_notice_, + ("-Set OID_RT_PRO_WRITE_TXCMD: status=0x%08X\n", status)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pEEPROM_RWParam pEEPROM; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+Query OID_RT_PRO_READ16_EEPROM\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pEEPROM = (pEEPROM_RWParam)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + pEEPROM->value = eeprom_read16(padapter, (u16)(pEEPROM->offset >> 1)); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-Query OID_RT_PRO_READ16_EEPROM: offset=0x%x value=0x%x\n", + pEEPROM->offset, pEEPROM->value)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write16_eeprom_hdl (struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + pEEPROM_RWParam pEEPROM; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_WRITE16_EEPROM\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pEEPROM = (pEEPROM_RWParam)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + eeprom_write16(padapter, (u16)(pEEPROM->offset >> 1), pEEPROM->value); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct mp_wiparam *pwi_param; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam)) + return NDIS_STATUS_INVALID_LENGTH; + + if (Adapter->mppriv.workparam.bcompleted == _FALSE) + return NDIS_STATUS_NOT_ACCEPTED; + + pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf; + + _rtw_memcpy(pwi_param, &Adapter->mppriv.workparam, sizeof(struct mp_wiparam)); + Adapter->mppriv.act_in_progress = _FALSE; +// RT_TRACE(_module_mp_, _drv_info_, ("rf:%x\n", pwiparam->IoValue)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro8711_pkt_loss_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(uint)*2) { + RT_TRACE(_module_mp_, _drv_err_, ("-oid_rt_pro8711_pkt_loss_hdl: buf_len=%d\n", (int)poid_par_priv->information_buf_len)); + return NDIS_STATUS_INVALID_LENGTH; + } + + if (*(uint*)poid_par_priv->information_buf == 1)//init==1 + Adapter->mppriv.rx_pktloss = 0; + + *((uint*)poid_par_priv->information_buf+1) = Adapter->mppriv.rx_pktloss; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)( poid_par_priv->adapter_context); + struct io_queue *pio_queue = (struct io_queue *)Adapter->pio_queue; + struct intf_hdl *pintfhdl = &pio_queue->intf; + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +#ifdef CONFIG_SDIO_HCI + void (*_attrib_read)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); +#endif + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Query OID_RT_RD_ATTRIB_MEM\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + +#ifdef CONFIG_SDIO_HCI + _irqlevel_changed_(&oldirql, LOWER); +{ + u32 *plmem = (u32*)poid_par_priv->information_buf+2; + _attrib_read = pintfhdl->io_ops._attrib_read; + _attrib_read(pintfhdl, *((u32*)poid_par_priv->information_buf), + *((u32*)poid_par_priv->information_buf+1), (u8*)plmem); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; +} + _irqlevel_changed_(&oldirql, RAISE); +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + struct io_queue *pio_queue = (struct io_queue *)Adapter->pio_queue; + struct intf_hdl *pintfhdl = &pio_queue->intf; + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +#ifdef CONFIG_SDIO_HCI + void (*_attrib_write)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); +#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + +#ifdef CONFIG_SDIO_HCI + _irqlevel_changed_(&oldirql, LOWER); +{ + u32 *plmem = (u32*)poid_par_priv->information_buf + 2; + _attrib_write = pintfhdl->io_ops._attrib_write; + _attrib_write(pintfhdl, *(u32*)poid_par_priv->information_buf, + *((u32*)poid_par_priv->information_buf+1), (u8*)plmem); +} + _irqlevel_changed_(&oldirql, RAISE); +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+OID_RT_PRO_SET_RF_INTFS\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setrfintfs_cmd(Adapter, *(unsigned char*)poid_par_priv->information_buf) == _FAIL) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _rtw_memcpy(poid_par_priv->information_buf, (unsigned char*)&Adapter->mppriv.rxstat, sizeof(struct recv_stat)); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + PCFG_DBG_MSG_STRUCT pdbg_msg; + +_func_enter_; + +// RT_TRACE(0xffffffffff,_drv_alert_,("===> oid_rt_pro_cfg_debug_message_hdl.\n")); + +#if 0//#ifdef CONFIG_DEBUG_RTL871X + + pdbg_msg = (PCFG_DBG_MSG_STRUCT)(poid_par_priv->information_buf); + + if (poid_par_priv->type_of_oid == SET_OID) { + RT_TRACE(0xffffffffff, _drv_alert_, + ("===>Set level :0x%08x, H32:0x%08x L32:0x%08x\n", + pdbg_msg->DebugLevel, pdbg_msg->DebugComponent_H32, pdbg_msg->DebugComponent_L32)); + + GlobalDebugLevel = pdbg_msg->DebugLevel; + GlobalDebugComponents = (pdbg_msg->DebugComponent_H32 << 32) | pdbg_msg->DebugComponent_L32; + RT_TRACE(0xffffffffff, _drv_alert_, + ("===> Set level :0x%08x, component:0x%016x\n", + GlobalDebugLevel, (u32)GlobalDebugComponents)); + } else { + pdbg_msg->DebugLevel = GlobalDebugLevel; + pdbg_msg->DebugComponent_H32 = (u32)(GlobalDebugComponents >> 32); + pdbg_msg->DebugComponent_L32 = (u32)GlobalDebugComponents; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(0xffffffffff, _drv_alert_, + ("===>Query level:0x%08x H32:0x%08x L32:0x%08x\n", + (u32)pdbg_msg->DebugLevel, (u32)pdbg_msg->DebugComponent_H32, (u32)pdbg_msg->DebugComponent_L32)); + } + +#endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv) +{ + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+OID_RT_PRO_SET_DATA_RATE_EX\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setdatarate_cmd(Adapter, poid_par_priv->information_buf) !=_SUCCESS) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + u8 thermal = 0; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_get_thermal_meter_hdl\n")); + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + GetThermalMeter(Adapter, &thermal); + _irqlevel_changed_(&oldirql, RAISE); + + *(u32*)poid_par_priv->information_buf = (u32)thermal; + *poid_par_priv->bytes_rw = sizeof(u32); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_read_tssi_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (Adapter->mppriv.act_in_progress == _TRUE) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + //init workparam + Adapter->mppriv.act_in_progress = _TRUE; + Adapter->mppriv.workparam.bcompleted = _FALSE; + Adapter->mppriv.workparam.act_type = MPT_READ_TSSI; + Adapter->mppriv.workparam.io_offset = 0; + Adapter->mppriv.workparam.io_value = 0xFFFFFFFF; + + _irqlevel_changed_(&oldirql, LOWER); + + if (!rtw_gettssi_cmd(Adapter,0, (u8*)&Adapter->mppriv.workparam.io_value)) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + +_func_enter_; + +// if (poid_par_priv->type_of_oid != SET_OID) +// return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + _irqlevel_changed_(&oldirql, LOWER); + if (poid_par_priv->type_of_oid == SET_OID) { + u8 enable; + + enable = *(u8*)poid_par_priv->information_buf; + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_set_power_tracking_hdl: enable=%d\n", enable)); + + SetPowerTracking(Adapter, enable); + } else { + GetPowerTracking(Adapter, (u8*)poid_par_priv->information_buf); + } + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//----------------------------------------------------------------------------- +NDIS_STATUS oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u32 ratevalue; + u8 datarates[NumRates]; + int i; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+OID_RT_PRO_SET_BASIC_RATE\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; +#if 0 + ratevalue = *((u32*)poid_par_priv->information_buf); + + for (i = 0; i < NumRates; i++) { + if (ratevalue == mpdatarate[i]) + datarates[i] = mpdatarate[i]; + else + datarates[i] = 0xff; + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_info_, ("basicrate_inx=%d\n", datarates[i])); + } + + _irqlevel_changed_(&oldirql, LOWER); + + if (rtw_setbasicrate_cmd(padapter, datarates) != _SUCCESS) + status = NDIS_STATUS_NOT_ACCEPTED; + + _irqlevel_changed_(&oldirql, RAISE); +#endif + RT_TRACE(_module_mp_, _drv_notice_, + ("-OID_RT_PRO_SET_BASIC_RATE: status=0x%08X\n", status)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < 8) + return NDIS_STATUS_INVALID_LENGTH; + + *poid_par_priv->bytes_rw = 8; + _rtw_memcpy(poid_par_priv->information_buf, &(adapter_to_pwrctl(Adapter)->pwr_mode), 8); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_qry_pwrstate_hdl: pwr_mode=%d smart_ps=%d\n", + adapter_to_pwrctl(Adapter)->pwr_mode, adapter_to_pwrctl(Adapter)->smart_ps)); + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + uint pwr_mode, smart_ps; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_SET_PWRSTATE\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_rw = 0; + *poid_par_priv->bytes_needed = 8; + + if (poid_par_priv->information_buf_len < 8) + return NDIS_STATUS_INVALID_LENGTH; + + pwr_mode = *(uint *)(poid_par_priv->information_buf); + smart_ps = *(uint *)((int)poid_par_priv->information_buf + 4); + + *poid_par_priv->bytes_rw = 8; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct setratable_parm *prate_table; + u8 res; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = sizeof(struct setratable_parm); + if (poid_par_priv->information_buf_len < sizeof(struct setratable_parm)) + return NDIS_STATUS_INVALID_LENGTH; + + prate_table = (struct setratable_parm*)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + res = rtw_setrttbl_cmd(Adapter, prate_table); + _irqlevel_changed_(&oldirql, RAISE); + + if (res == _FAIL) + status = NDIS_STATUS_FAILURE; + +_func_exit_; + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + #if 0 + struct mp_wi_cntx *pmp_wi_cntx=&(Adapter->mppriv.wi_cntx); + u8 res=_SUCCESS; + DEBUG_INFO(("===> Set OID_RT_PRO_H2C_GET_RATE_TABLE.\n")); + + if(pmp_wi_cntx->bmp_wi_progress ==_TRUE){ + DEBUG_ERR(("\n mp workitem is progressing, not allow to set another workitem right now!!!\n")); + Status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + else{ + pmp_wi_cntx->bmp_wi_progress=_TRUE; + pmp_wi_cntx->param.bcompleted=_FALSE; + pmp_wi_cntx->param.act_type=MPT_GET_RATE_TABLE; + pmp_wi_cntx->param.io_offset=0x0; + pmp_wi_cntx->param.bytes_cnt=sizeof(struct getratable_rsp); + pmp_wi_cntx->param.io_value=0xffffffff; + + res=rtw_getrttbl_cmd(Adapter,(struct getratable_rsp *)pmp_wi_cntx->param.data); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + if(res != _SUCCESS) + { + Status = NDIS_STATUS_NOT_ACCEPTED; + } + } + DEBUG_INFO(("\n <=== Set OID_RT_PRO_H2C_GET_RATE_TABLE.\n")); + #endif + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +//**************** oid_rtl_seg_87_12_00 section start **************** +NDIS_STATUS oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + struct security_priv *psecuritypriv = &Adapter->securitypriv; + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + ENCRY_CTRL_STATE encry_mode; + + + *poid_par_priv->bytes_needed = sizeof(u8); + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + if (poid_par_priv->type_of_oid == SET_OID) + { + encry_mode = *((u8*)poid_par_priv->information_buf); + switch (encry_mode) + { + case HW_CONTROL: + #if 0 + Adapter->registrypriv.software_decrypt=_FALSE; + Adapter->registrypriv.software_encrypt=_FALSE; + #else + psecuritypriv->sw_decrypt = _FALSE; + psecuritypriv->sw_encrypt = _FALSE; + #endif + break; + case SW_CONTROL: + #if 0 + Adapter->registrypriv.software_decrypt=_TRUE; + Adapter->registrypriv.software_encrypt=_TRUE; + #else + psecuritypriv->sw_decrypt = _TRUE; + psecuritypriv->sw_encrypt = _TRUE; + #endif + break; + case HW_ENCRY_SW_DECRY: + #if 0 + Adapter->registrypriv.software_decrypt=_TRUE; + Adapter->registrypriv.software_encrypt=_FALSE; + #else + psecuritypriv->sw_decrypt = _TRUE; + psecuritypriv->sw_encrypt = _FALSE; + #endif + break; + case SW_ENCRY_HW_DECRY: + #if 0 + Adapter->registrypriv.software_decrypt=_FALSE; + Adapter->registrypriv.software_encrypt=_TRUE; + #else + psecuritypriv->sw_decrypt = _FALSE; + psecuritypriv->sw_encrypt = _TRUE; + #endif + break; + } + + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_notice_, + ("-oid_rt_pro_encryption_ctrl_hdl: SET encry_mode=0x%x sw_encrypt=0x%x sw_decrypt=0x%x\n", + encry_mode, psecuritypriv->sw_encrypt, psecuritypriv->sw_decrypt)); + } + else { + #if 0 + if (Adapter->registrypriv.software_encrypt == _FALSE) { + if (Adapter->registrypriv.software_decrypt == _FALSE) + encry_mode = HW_CONTROL; + else + encry_mode = HW_ENCRY_SW_DECRY; + } + else { + if (Adapter->registrypriv.software_decrypt == _FALSE) + encry_mode = SW_ENCRY_HW_DECRY; + else + encry_mode = SW_CONTROL; + } + #else + + if ((psecuritypriv->sw_encrypt == _FALSE) && (psecuritypriv->sw_decrypt == _FALSE)) + encry_mode = HW_CONTROL; + else if ((psecuritypriv->sw_encrypt == _FALSE) && (psecuritypriv->sw_decrypt == _TRUE)) + encry_mode = HW_ENCRY_SW_DECRY; + else if ((psecuritypriv->sw_encrypt == _TRUE) && (psecuritypriv->sw_decrypt == _FALSE)) + encry_mode = SW_ENCRY_HW_DECRY; + else if ((psecuritypriv->sw_encrypt == _TRUE) && (psecuritypriv->sw_decrypt == _TRUE)) + encry_mode = SW_CONTROL; + + #endif + + *(u8*)poid_par_priv->information_buf = encry_mode; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_encryption_ctrl_hdl: QUERY encry_mode=0x%x\n", + encry_mode)); + } + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct sta_info *psta = NULL; + UCHAR *macaddr; + + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = ETH_ALEN; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + macaddr = (UCHAR *) poid_par_priv->information_buf ; + + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_notice_, + ("OID_RT_PRO_ADD_STA_INFO: addr="MAC_FMT"\n", MAC_ARG(macaddr) )); + + _irqlevel_changed_(&oldirql, LOWER); + + psta = rtw_get_stainfo(&Adapter->stapriv, macaddr); + + if (psta == NULL) { // the sta have been in sta_info_queue => do nothing + psta = rtw_alloc_stainfo(&Adapter->stapriv, macaddr); + + if (psta == NULL) { + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("Can't alloc sta_info when OID_RT_PRO_ADD_STA_INFO\n")); + status = NDIS_STATUS_FAILURE; + } + } else { //(between drv has received this event before and fw have not yet to set key to CAM_ENTRY) + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_err_, + ("Error: OID_RT_PRO_ADD_STA_INFO: sta has been in sta_hash_queue \n")); + } + + _irqlevel_changed_(&oldirql, RAISE); + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct sta_info *psta = NULL; + UCHAR *macaddr; + + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = ETH_ALEN; + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + macaddr = (UCHAR *) poid_par_priv->information_buf ; + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_notice_, + ("+OID_RT_PRO_ADD_STA_INFO: addr="MAC_FMT"\n", MAC_ARG(macaddr) )); + + psta = rtw_get_stainfo(&Adapter->stapriv, macaddr); + if (psta != NULL) { + //_enter_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + rtw_free_stainfo(Adapter, psta); + //_exit_critical(&(Adapter->stapriv.sta_hash_lock), &irqL); + } + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +#if 0 +static u32 mp_query_drv_var(_adapter *padapter, u8 offset, u32 var) +{ +#ifdef CONFIG_SDIO_HCI + + if (offset == 1) { + u16 tmp_blk_num; + tmp_blk_num = rtw_read16(padapter, SDIO_RX0_RDYBLK_NUM); + RT_TRACE(_module_mp_, _drv_err_, ("Query Information, mp_query_drv_var SDIO_RX0_RDYBLK_NUM=0x%x dvobj.rxblknum=0x%x\n", tmp_blk_num, adapter_to_dvobj(padapter)->rxblknum)); + if (adapter_to_dvobj(padapter)->rxblknum != tmp_blk_num) { + RT_TRACE(_module_mp_,_drv_err_, ("Query Information, mp_query_drv_var call recv rx\n")); + // sd_recv_rxfifo(padapter); + } + } + +#if 0 + if(offset <=100){ //For setting data rate and query data rate + if(offset==100){ //For query data rate + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d): query rate=0x%.2x \n",offset,padapter->registrypriv.tx_rate)); + var=padapter->registrypriv.tx_rate; + + } + else if(offset<0x1d){ //For setting data rate + padapter->registrypriv.tx_rate=offset; + var=padapter->registrypriv.tx_rate; + padapter->registrypriv.use_rate=_TRUE; + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d): set rate=0x%.2x \n",offset,padapter->registrypriv.tx_rate)); + } + else{ //not use the data rate + padapter->registrypriv.use_rate=_FALSE; + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d) out of rate range\n",offset)); + } + } + else if (offset<=110){ //for setting debug level + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d) for set debug level\n",offset)); + if(offset==110){ //For query data rate + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d): query dbg level=0x%.2x \n",offset,padapter->registrypriv.dbg_level)); + padapter->registrypriv.dbg_level=GlobalDebugLevel; + var=padapter->registrypriv.dbg_level; + } + else if(offset<110 && offset>100){ + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var: offset(%d): set dbg level=0x%.2x \n",offset,offset-100)); + padapter->registrypriv.dbg_level=GlobalDebugLevel=offset-100; + var=padapter->registrypriv.dbg_level; + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var(_drv_emerg_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_alert_, (" mp_query_drv_var(_drv_alert_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_crit_, (" mp_query_drv_var(_drv_crit_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_err_, (" mp_query_drv_var(_drv_err_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_warning_, (" mp_query_drv_var(_drv_warning_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_notice_, (" mp_query_drv_var(_drv_notice_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_info_, (" mp_query_drv_var(_drv_info_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + RT_TRACE(_module_mp_, _drv_debug_, (" mp_query_drv_var(_drv_debug_): offset(%d): set dbg level=0x%.2x \n",offset,GlobalDebugLevel)); + + } + } + else if(offset >110 &&offset <116){ + if(115==offset){ + RT_TRACE(_module_mp_, _drv_emerg_, (" mp_query_drv_var(_drv_emerg_): offset(%d): query TRX access type: [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + } + else { + switch(offset){ + case 111: + adapter_to_dvobj(padapter)->tx_block_mode=1; + adapter_to_dvobj(padapter)->rx_block_mode=1; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX block/RX block) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 112: + adapter_to_dvobj(padapter)->tx_block_mode=1; + adapter_to_dvobj(padapter)->rx_block_mode=0; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX block/RX byte) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 113: + adapter_to_dvobj(padapter)->tx_block_mode=0; + adapter_to_dvobj(padapter)->rx_block_mode=1; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX byte/RX block) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + case 114: + adapter_to_dvobj(padapter)->tx_block_mode=0; + adapter_to_dvobj(padapter)->rx_block_mode=0; + RT_TRACE(_module_mp_, _drv_emerg_, \ + (" mp_query_drv_var(_drv_emerg_): offset(%d): SET TRX access type:(TX byte/RX byte) [tx_block_mode=%x,rx_block_mode=%x]\n",\ + offset, adapter_to_dvobj(padapter)->tx_block_mode, adapter_to_dvobj(padapter)->rx_block_mode)); + break; + default : + break; + + } + + } + + } + else if(offset>=127){ + u64 prnt_dbg_comp; + u8 chg_idx; + u64 tmp_dbg_comp; + chg_idx=offset-0x80; + tmp_dbg_comp=BIT(chg_idx); + prnt_dbg_comp=padapter->registrypriv.dbg_component= GlobalDebugComponents; + RT_TRACE(_module_mp_, _drv_emerg_, (" 1: mp_query_drv_var: offset(%d;0x%x):for dbg conpoment prnt_dbg_comp=0x%.16x GlobalDebugComponents=0x%.16x padapter->registrypriv.dbg_component=0x%.16x\n",offset,offset,prnt_dbg_comp,GlobalDebugComponents,padapter->registrypriv.dbg_component)); + if(offset==127){ + // prnt_dbg_comp=padapter->registrypriv.dbg_component= GlobalDebugComponents; + var=(u32)(padapter->registrypriv.dbg_component); + RT_TRACE(0xffffffff, _drv_emerg_, ("2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) \n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_, ("2-1: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, ("2-2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + + } + else{ + RT_TRACE(0xffffffff, _drv_emerg_, ("3: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) chg_idx=%d\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp,chg_idx)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_,("3-1: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h) chg_idx=%d\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp,chg_idx));// ("3-1: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment=0x%x chg_idx=%d or0x%x BIT(chg_idx[%d]=0x%x)\n",offset,offset,prnt_dbg_comp,chg_idx,chg_idx,(chg_idx),tmp_dbg_comp) + prnt_dbg_comp=GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, ("3-2: mp_query_drv_var: offset(%d;0x%x):for query dbg conpoment=0x%x(l) 0x%x(h) GlobalDebugComponents=0x%x(l) 0x%x(h)\n",offset,offset,padapter->registrypriv.dbg_component,prnt_dbg_comp)); + + if(GlobalDebugComponents&tmp_dbg_comp){ + //this bit is already set, now clear it + GlobalDebugComponents=GlobalDebugComponents&(~tmp_dbg_comp); + } + else{ + //this bit is not set, now set it. + GlobalDebugComponents =GlobalDebugComponents|tmp_dbg_comp; + } + RT_TRACE(0xffffffff, _drv_emerg_, ("4: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment tmp_dbg_comp=0x%x GlobalDebugComponents=0x%x(l) 0x%x(h)",offset,offset,tmp_dbg_comp,prnt_dbg_comp)); + prnt_dbg_comp=GlobalDebugComponents; + RT_TRACE(0xffffffff, _drv_emerg_, ("4-1: mp_query_drv_var: offset(%d;0x%x):before set dbg conpoment tmp_dbg_comp=0x%x GlobalDebugComponents=0x%x(l) 0x%x(h)",offset,offset,tmp_dbg_comp,prnt_dbg_comp)); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_emerg_, ("0: mp_query_drv_var(_module_rtl871x_xmit_c_:0): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,prnt_dbg_comp)); + RT_TRACE(_module_xmit_osdep_c_, _drv_emerg_, ("1: mp_query_drv_var(_module_xmit_osdep_c_:1): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_recv_c_, _drv_emerg_, ("2: mp_query_drv_var(_module_rtl871x_recv_c_:2): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_recv_osdep_c_, _drv_emerg_, ("3: mp_query_drv_var(_module_recv_osdep_c_:3): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_emerg_, ("4: mp_query_drv_var(_module_rtl871x_mlme_c_:4): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_mlme_osdep_c_, _drv_emerg_, (" 5:mp_query_drv_var(_module_mlme_osdep_c_:5): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_emerg_, ("6: mp_query_drv_var(_module_rtl871x_sta_mgt_c_:6): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_cmd_c_, _drv_emerg_, ("7: mp_query_drv_var(_module_rtl871x_cmd_c_:7): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_cmd_osdep_c_, _drv_emerg_, ("8: mp_query_drv_var(_module_cmd_osdep_c_:8): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_io_c_, _drv_emerg_, ("9: mp_query_drv_var(_module_rtl871x_io_c_:9): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_io_osdep_c_, _drv_emerg_, ("10: mp_query_drv_var(_module_io_osdep_c_:10): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_os_intfs_c_, _drv_emerg_, ("11: mp_query_drv_var(_module_os_intfs_c_:11): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_security_c_, _drv_emerg_, ("12: mp_query_drv_var(_module_rtl871x_security_c_:12): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_eeprom_c_, _drv_emerg_, ("13: mp_query_drv_var(_module_rtl871x_eeprom_c_:13): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hal_init_c_, _drv_emerg_, ("14: mp_query_drv_var(_module_hal_init_c_:14): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_hal_init_c_, _drv_emerg_, ("15: mp_query_drv_var(_module_hci_hal_init_c_:15): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_c_, _drv_emerg_, ("16: mp_query_drv_var(_module_rtl871x_ioctl_c_:16): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_emerg_, ("17: mp_query_drv_var(_module_rtl871x_ioctl_set_c_:17): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_ioctl_query_c_, _drv_emerg_, ("18: mp_query_drv_var(_module_rtl871x_ioctl_query_c_:18): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_emerg_, ("19: mp_query_drv_var(_module_rtl871x_pwrctrl_c_:19): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_intfs_c_, _drv_emerg_, ("20: mp_query_drv_var(_module_hci_intfs_c_:20): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_ops_c_, _drv_emerg_, ("21: mp_query_drv_var(_module_hci_ops_c_:21): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_osdep_service_c_, _drv_emerg_, ("22: mp_query_drv_var(_module_osdep_service_c_:22): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_mp_, _drv_emerg_, ("23: mp_query_drv_var(_module_mp_:23): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + RT_TRACE(_module_hci_ops_os_c_, _drv_emerg_, ("24: mp_query_drv_var(_module_hci_ops_os_c_:24): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + var=(u32)(GlobalDebugComponents); + //GlobalDebugComponents=padapter->registrypriv.dbg_component; + RT_TRACE(0xffffffff, _drv_emerg_, (" ==mp_query_drv_var(_module_mp_): offset(%d;0x%x):before set dbg conpoment=0x%x(l) 0x%x(h)\n",offset,offset,GlobalDebugComponents)); + + } + } + else{ + RT_TRACE(_module_mp_, _drv_emerg_, ("\n mp_query_drv_var: offset(%d) >110\n",offset)); + } +#endif +#endif + + return var; +} +#endif + +NDIS_STATUS oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + DR_VARIABLE_STRUCT *pdrv_var; + + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + *poid_par_priv->bytes_needed = sizeof(DR_VARIABLE_STRUCT); + if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed) + return NDIS_STATUS_INVALID_LENGTH; + + RT_TRACE(_module_mp_, _drv_notice_, ("+Query Information, OID_RT_PRO_QUERY_DR_VARIABLE\n")); + + pdrv_var = (struct _DR_VARIABLE_STRUCT_ *)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset, pdrv_var->variable); + _irqlevel_changed_(&oldirql, RAISE); + + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_notice_, + ("-oid_rt_pro_query_dr_variable_hdl: offset=0x%x valule=0x%x\n", + pdrv_var->offset, pdrv_var->variable)); + + return status; +#else + return 0; +#endif +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + RT_TRACE(_module_mp_, _drv_err_, ("oid_rt_pro_rx_packet_type_hdl...................\n")); + + if (poid_par_priv->information_buf_len < sizeof (UCHAR)) { + status = NDIS_STATUS_INVALID_LENGTH; + *poid_par_priv->bytes_needed = sizeof(UCHAR); + return status; + } + + if (poid_par_priv->type_of_oid == SET_OID) { + Adapter->mppriv.rx_with_status = *(UCHAR *) poid_par_priv->information_buf; + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_, ("Query Information, OID_RT_PRO_RX_PACKET_TYPE:%d \n",\ + Adapter->mppriv.rx_with_status)); + + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("MAC addr=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x \n", + Adapter->eeprompriv.mac_addr[0],Adapter->eeprompriv.mac_addr[1],Adapter->eeprompriv.mac_addr[2],\ + Adapter->eeprompriv.mac_addr[3],Adapter->eeprompriv.mac_addr[4],Adapter->eeprompriv.mac_addr[5])); + + } + else { + *(UCHAR *) poid_par_priv->information_buf = Adapter->mppriv.rx_with_status; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_, ("Query Information, OID_RT_PRO_RX_PACKET_TYPE:%d \n", \ + Adapter->mppriv.rx_with_status)); + + //*(u32 *)&Adapter->eeprompriv.mac_addr[0]=rtw_read32(Adapter, 0x10250050); + //*(u16 *)&Adapter->eeprompriv.mac_addr[4]=rtw_read16(Adapter, 0x10250054); + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_err_,("MAC addr=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x \n", + Adapter->eeprompriv.mac_addr[0],Adapter->eeprompriv.mac_addr[1],Adapter->eeprompriv.mac_addr[2],\ + Adapter->eeprompriv.mac_addr[3],Adapter->eeprompriv.mac_addr[4],Adapter->eeprompriv.mac_addr[5])); + } +#endif + + return NDIS_STATUS_SUCCESS; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PEFUSE_ACCESS_STRUCT pefuse; + u8 *data; + u16 addr = 0, cnts = 0, max_available_size = 0; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(EFUSE_ACCESS_STRUCT)) + return NDIS_STATUS_INVALID_LENGTH; + + pefuse = (PEFUSE_ACCESS_STRUCT)poid_par_priv->information_buf; + addr = pefuse->start_addr; + cnts = pefuse->cnts; + data = pefuse->data; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_read_efuse_hd: buf_len=%d addr=%d cnts=%d\n", + poid_par_priv->information_buf_len, addr, cnts)); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_read_efuse_hdl: parameter error!\n")); + return NDIS_STATUS_NOT_ACCEPTED; + } + + _irqlevel_changed_(&oldirql, LOWER); + if (rtw_efuse_access(Adapter, _FALSE, addr, cnts, data) == _FAIL) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_read_efuse_hdl: rtw_efuse_access FAIL!\n")); + status = NDIS_STATUS_FAILURE; + } else + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PEFUSE_ACCESS_STRUCT pefuse; + u8 *data; + u16 addr = 0, cnts = 0, max_available_size = 0; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + pefuse = (PEFUSE_ACCESS_STRUCT)poid_par_priv->information_buf; + addr = pefuse->start_addr; + cnts = pefuse->cnts; + data = pefuse->data; + + RT_TRACE(_module_mp_, _drv_notice_, + ("+oid_rt_pro_write_efuse_hdl: buf_len=%d addr=0x%04x cnts=%d\n", + poid_par_priv->information_buf_len, addr, cnts)); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + + if ((addr + cnts) > max_available_size) { + RT_TRACE(_module_mp_, _drv_err_, ("!oid_rt_pro_write_efuse_hdl: parameter error")); + return NDIS_STATUS_NOT_ACCEPTED; + } + + _irqlevel_changed_(&oldirql, LOWER); + if (rtw_efuse_access(Adapter, _TRUE, addr, cnts, data) == _FAIL) + status = NDIS_STATUS_FAILURE; + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + PPGPKT_STRUCT ppgpkt; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + +// RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_rw_efuse_pgpkt_hdl\n")); + + *poid_par_priv->bytes_rw = 0; + + if (poid_par_priv->information_buf_len < sizeof(PGPKT_STRUCT)) + return NDIS_STATUS_INVALID_LENGTH; + + ppgpkt = (PPGPKT_STRUCT)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (poid_par_priv->type_of_oid == QUERY_OID) + { + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_rw_efuse_pgpkt_hdl: Read offset=0x%x\n",\ + ppgpkt->offset)); + + Efuse_PowerSwitch(Adapter, _FALSE, _TRUE); + if (Efuse_PgPacketRead(Adapter, ppgpkt->offset, ppgpkt->data, _FALSE) == _TRUE) + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + else + status = NDIS_STATUS_FAILURE; + Efuse_PowerSwitch(Adapter, _FALSE, _FALSE); + } else { + RT_TRACE(_module_mp_, _drv_notice_, + ("oid_rt_pro_rw_efuse_pgpkt_hdl: Write offset=0x%x word_en=0x%x\n",\ + ppgpkt->offset, ppgpkt->word_en)); + + Efuse_PowerSwitch(Adapter, _TRUE, _TRUE); + if (Efuse_PgPacketWrite(Adapter, ppgpkt->offset, ppgpkt->word_en, ppgpkt->data, _FALSE) == _TRUE) + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + else + status = NDIS_STATUS_FAILURE; + Efuse_PowerSwitch(Adapter, _TRUE, _FALSE); + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_rw_efuse_pgpkt_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u16 size; + u8 ret; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf = size; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + } else + status = NDIS_STATUS_FAILURE; + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + *(u32*)poid_par_priv->information_buf = efuse_GetMaxSize(Adapter); + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_get_efuse_max_size_hdl: size=%d status=0x%08X\n", + *(int*)poid_par_priv->information_buf, status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_info_, ("+oid_rt_pro_efuse_hdl\n")); + + if (poid_par_priv->type_of_oid == QUERY_OID) + status = oid_rt_pro_read_efuse_hdl(poid_par_priv); + else + status = oid_rt_pro_write_efuse_hdl(poid_par_priv); + + RT_TRACE(_module_mp_, _drv_info_, ("-oid_rt_pro_efuse_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 *data; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + u16 mapLen=0; + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_pro_efuse_map_hdl\n")); + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE); + + *poid_par_priv->bytes_rw = 0; + + if (poid_par_priv->information_buf_len < mapLen) + return NDIS_STATUS_INVALID_LENGTH; + + data = (u8*)poid_par_priv->information_buf; + + _irqlevel_changed_(&oldirql, LOWER); + + if (poid_par_priv->type_of_oid == QUERY_OID) + { + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_efuse_map_hdl: READ\n")); + + if (rtw_efuse_map_read(Adapter, 0, mapLen, data) == _SUCCESS) + *poid_par_priv->bytes_rw = mapLen; + else { + RT_TRACE(_module_mp_, _drv_err_, + ("oid_rt_pro_efuse_map_hdl: READ fail\n")); + status = NDIS_STATUS_FAILURE; + } + } else { + // SET_OID + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_efuse_map_hdl: WRITE\n")); + + if (rtw_efuse_map_write(Adapter, 0, mapLen, data) == _SUCCESS) + *poid_par_priv->bytes_rw = mapLen; + else { + RT_TRACE(_module_mp_, _drv_err_, + ("oid_rt_pro_efuse_map_hdl: WRITE fail\n")); + status = NDIS_STATUS_FAILURE; + } + } + + _irqlevel_changed_(&oldirql, RAISE); + + RT_TRACE(_module_mp_, _drv_info_, + ("-oid_rt_pro_efuse_map_hdl: status=0x%08X\n", status)); + +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + + u32 crystal_cap = 0; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf);//4 + if (crystal_cap > 0xf) + return NDIS_STATUS_NOT_ACCEPTED; + + Adapter->mppriv.curr_crystalcap = crystal_cap; + + _irqlevel_changed_(&oldirql,LOWER); + SetCrystalCap(Adapter); + _irqlevel_changed_(&oldirql,RAISE); + +_func_exit_; + +#endif + return status; +} + +NDIS_STATUS oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 rx_pkt_type; +// u32 rcr_val32; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +// PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); + +_func_enter_; + + RT_TRACE(_module_mp_, _drv_notice_, ("+oid_rt_set_rx_packet_type_hdl\n")); + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u8)) + return NDIS_STATUS_INVALID_LENGTH; + + rx_pkt_type = *((u8*)poid_par_priv->information_buf);//4 + + RT_TRACE(_module_mp_, _drv_info_, ("rx_pkt_type: %x\n",rx_pkt_type )); +#if 0 + _irqlevel_changed_(&oldirql, LOWER); +#if 0 + rcr_val8 = rtw_read8(Adapter, 0x10250048);//RCR + rcr_val8 &= ~(RCR_AB|RCR_AM|RCR_APM|RCR_AAP); + + if(rx_pkt_type == RX_PKT_BROADCAST){ + rcr_val8 |= (RCR_AB | RCR_ACRC32 ); + } + else if(rx_pkt_type == RX_PKT_DEST_ADDR){ + rcr_val8 |= (RCR_AAP| RCR_AM |RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_PHY_MATCH){ + rcr_val8 |= (RCR_APM|RCR_ACRC32); + } + else{ + rcr_val8 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + } + rtw_write8(padapter, 0x10250048,rcr_val8); +#else + rcr_val32 = rtw_read32(padapter, RCR);//RCR = 0x10250048 + rcr_val32 &= ~(RCR_CBSSID|RCR_AB|RCR_AM|RCR_APM|RCR_AAP); +#if 0 + if(rx_pkt_type == RX_PKT_BROADCAST){ + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_DEST_ADDR){ + //rcr_val32 |= (RCR_CBSSID|RCR_AAP|RCR_AM|RCR_ACRC32); + rcr_val32 |= (RCR_CBSSID|RCR_APM|RCR_ACRC32); + } + else if(rx_pkt_type == RX_PKT_PHY_MATCH){ + rcr_val32 |= (RCR_APM|RCR_ACRC32); + //rcr_val32 |= (RCR_AAP|RCR_ACRC32); + } + else{ + rcr_val32 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + } +#else + switch (rx_pkt_type) + { + case RX_PKT_BROADCAST : + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + break; + case RX_PKT_DEST_ADDR : + rcr_val32 |= (RCR_AB|RCR_AM|RCR_APM|RCR_AAP|RCR_ACRC32); + break; + case RX_PKT_PHY_MATCH: + rcr_val32 |= (RCR_APM|RCR_ACRC32); + break; + default: + rcr_val32 &= ~(RCR_AAP|RCR_APM|RCR_AM|RCR_AB|RCR_ACRC32); + break; + } + + if (rx_pkt_type == RX_PKT_DEST_ADDR) { + padapter->mppriv.check_mp_pkt = 1; + } else { + padapter->mppriv.check_mp_pkt = 0; + } +#endif + rtw_write32(padapter, RCR, rcr_val32); + +#endif + _irqlevel_changed_(&oldirql, RAISE); +#endif +_func_exit_; + + return status; +} + +NDIS_STATUS oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + u32 txagc; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len < sizeof(u32)) + return NDIS_STATUS_INVALID_LENGTH; + + txagc = *(u32*)poid_par_priv->information_buf; + RT_TRACE(_module_mp_, _drv_info_, + ("oid_rt_pro_set_tx_agc_offset_hdl: 0x%08x\n", txagc)); + + _irqlevel_changed_(&oldirql, LOWER); + SetTxAGCOffset(Adapter, txagc); + _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +NDIS_STATUS oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); + + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + struct mp_priv *pmppriv = &Adapter->mppriv; + u32 type; + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) + return NDIS_STATUS_NOT_ACCEPTED; + + if (poid_par_priv->information_buf_len information_buf; + + if (_LOOPBOOK_MODE_ == type) { + pmppriv->mode = type; + set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); //append txdesc + RT_TRACE(_module_mp_, _drv_info_, ("test mode change to loopback mode:0x%08x.\n", get_fwstate(pmlmepriv))); + } else if (_2MAC_MODE_ == type){ + pmppriv->mode = type; + _clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE); + RT_TRACE(_module_mp_, _drv_info_, ("test mode change to 2mac mode:0x%08x.\n", get_fwstate(pmlmepriv))); + } else + status = NDIS_STATUS_NOT_ACCEPTED; + +_func_exit_; + + return status; +#else + return 0; +#endif +} + +unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) +{ + PMP_XMIT_PARM pparm; + PADAPTER padapter; + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + + RT_TRACE(_module_mp_, _drv_notice_, ("+%s\n", __func__)); + + pparm = (PMP_XMIT_PARM)poid_par_priv->information_buf; + padapter = (PADAPTER)poid_par_priv->adapter_context; + pmp_priv = &padapter->mppriv; + + if (poid_par_priv->type_of_oid == QUERY_OID) { + pparm->enable = !pmp_priv->tx.stop; + pparm->count = pmp_priv->tx.sended; + } else { + if (pparm->enable == 0) { + pmp_priv->tx.stop = 1; + } else if (pmp_priv->tx.stop == 1) { + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = pparm->count; + pmp_priv->tx.payload = pparm->payload_type; + pattrib = &pmp_priv->tx.attrib; + pattrib->pktlen = pparm->length; + _rtw_memcpy(pattrib->dst, pparm->da, ETH_ALEN); + SetPacketTx(padapter); + } else + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + +#if 0 +unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) +{ + unsigned char *pframe, *pmp_pkt; + struct ethhdr *pethhdr; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + int llc_sz, payload_len; + struct mp_xmit_frame *pxframe= NULL; + struct mp_xmit_packet *pmp_xmitpkt = (struct mp_xmit_packet*)param; + u8 addr3[] = {0x02, 0xE0, 0x4C, 0x87, 0x66, 0x55}; + +// DBG_871X("+mp_ioctl_xmit_packet_hdl\n"); + + pxframe = alloc_mp_xmitframe(&padapter->mppriv); + if (pxframe == NULL) + { + DEBUG_ERR(("Can't alloc pmpframe %d:%s\n", __LINE__, __FILE__)); + return -1; + } + + //mp_xmit_pkt + payload_len = pmp_xmitpkt->len - 14; + pmp_pkt = (unsigned char*)pmp_xmitpkt->mem; + pethhdr = (struct ethhdr *)pmp_pkt; + + //DBG_871X("payload_len=%d, pkt_mem=0x%x\n", pmp_xmitpkt->len, (void*)pmp_xmitpkt->mem); + + //DBG_871X("pxframe=0x%x\n", (void*)pxframe); + //DBG_871X("pxframe->mem=0x%x\n", (void*)pxframe->mem); + + //update attribute + pattrib = &pxframe->attrib; + memset((u8 *)(pattrib), 0, sizeof (struct pkt_attrib)); + pattrib->pktlen = pmp_xmitpkt->len; + pattrib->ether_type = ntohs(pethhdr->h_proto); + pattrib->hdrlen = 24; + pattrib->nr_frags = 1; + pattrib->priority = 0; +#ifndef CONFIG_MP_LINUX + if(IS_MCAST(pethhdr->h_dest)) + pattrib->mac_id = 4; + else + pattrib->mac_id = 5; +#else + pattrib->mac_id = 5; +#endif + + // + memset(pxframe->mem, 0 , WLANHDR_OFFSET); + pframe = (u8 *)(pxframe->mem) + WLANHDR_OFFSET; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + SetFrameSubType(pframe, WIFI_DATA); + + _rtw_memcpy(pwlanhdr->addr1, pethhdr->h_dest, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pethhdr->h_source, ETH_ALEN); + + _rtw_memcpy(pwlanhdr->addr3, addr3, ETH_ALEN); + + pwlanhdr->seq_ctl = 0; + pframe += pattrib->hdrlen; + + llc_sz= rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + + _rtw_memcpy(pframe, (void*)(pmp_pkt+14), payload_len); + + pattrib->last_txcmdsz = pattrib->hdrlen + llc_sz + payload_len; + + DEBUG_INFO(("issuing mp_xmit_frame, tx_len=%d, ether_type=0x%x\n", pattrib->last_txcmdsz, pattrib->ether_type)); + xmit_mp_frame(padapter, pxframe); + + return _SUCCESS; +} +#endif +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) +{ +#ifdef PLATFORM_OS_XP + _irqL oldirql; +#endif + u8 bpwrup; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#ifdef PLATFORM_LINUX +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + PADAPTER padapter = (PADAPTER)(poid_par_priv->adapter_context); +#endif +#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != SET_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + + RT_TRACE(_module_mp_, _drv_info_, + ("\n ===> Setoid_rt_set_power_down_hdl.\n")); + + _irqlevel_changed_(&oldirql, LOWER); + + bpwrup = *(u8 *)poid_par_priv->information_buf; + //CALL the power_down function +#ifdef PLATFORM_LINUX +#if defined(CONFIG_RTL8712) //Linux MP insmod unknown symbol + dev_power_down(padapter,bpwrup); +#endif +#endif + _irqlevel_changed_(&oldirql, RAISE); + + //DEBUG_ERR(("\n <=== Query OID_RT_PRO_READ_REGISTER. + // Add:0x%08x Width:%d Value:0x%08x\n",RegRWStruct->offset,RegRWStruct->width,RegRWStruct->value)); + +_func_exit_; + + return status; +} +//------------------------------------------------------------------------------ +NDIS_STATUS oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) +{ +#if 0 + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + PADAPTER Adapter = (PADAPTER)(poid_par_priv->adapter_context); +//#ifdef PLATFORM_OS_XP +// _irqL oldirql; +//#endif + +_func_enter_; + + if (poid_par_priv->type_of_oid != QUERY_OID) { + status = NDIS_STATUS_NOT_ACCEPTED; + return status; + } + if (poid_par_priv->information_buf_len < sizeof(u32)) { + status = NDIS_STATUS_INVALID_LENGTH; + return status; + } + + RT_TRACE(_module_mp_, _drv_info_, + ("\n ===> oid_rt_get_power_mode_hdl.\n")); + +// _irqlevel_changed_(&oldirql, LOWER); + *(int*)poid_par_priv->information_buf = Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL; + *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; +// _irqlevel_changed_(&oldirql, RAISE); + +_func_exit_; + + return status; +#else + return 0; +#endif +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_odm.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_odm.c new file mode 100644 index 00000000..c5596d5e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_odm.c @@ -0,0 +1,449 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + +const char *odm_comp_str[] = { + /* BIT0 */"ODM_COMP_DIG", + /* BIT1 */"ODM_COMP_RA_MASK", + /* BIT2 */"ODM_COMP_DYNAMIC_TXPWR", + /* BIT3 */"ODM_COMP_FA_CNT", + /* BIT4 */"ODM_COMP_RSSI_MONITOR", + /* BIT5 */"ODM_COMP_CCK_PD", + /* BIT6 */"ODM_COMP_ANT_DIV", + /* BIT7 */"ODM_COMP_PWR_SAVE", + /* BIT8 */"ODM_COMP_PWR_TRAIN", + /* BIT9 */"ODM_COMP_RATE_ADAPTIVE", + /* BIT10 */"ODM_COMP_PATH_DIV", + /* BIT11 */"ODM_COMP_PSD", + /* BIT12 */"ODM_COMP_DYNAMIC_PRICCA", + /* BIT13 */"ODM_COMP_RXHP", + /* BIT14 */"ODM_COMP_MP", + /* BIT15 */"ODM_COMP_CFO_TRACKING", + /* BIT16 */"ODM_COMP_ACS", + /* BIT17 */"PHYDM_COMP_ADAPTIVITY", + /* BIT18 */"PHYDM_COMP_RA_DBG", + /* BIT19 */"PHYDM_COMP_TXBF", + /* BIT20 */"ODM_COMP_EDCA_TURBO", + /* BIT21 */"ODM_COMP_EARLY_MODE", + /* BIT22 */"ODM_FW_DEBUG_TRACE", + /* BIT23 */NULL, + /* BIT24 */"ODM_COMP_TX_PWR_TRACK", + /* BIT25 */"ODM_COMP_RX_GAIN_TRACK", + /* BIT26 */"ODM_COMP_CALIBRATION", + /* BIT27 */NULL, + /* BIT28 */"ODM_PHY_CONFIG", + /* BIT29 */"BEAMFORMING_DEBUG", + /* BIT30 */"ODM_COMP_COMMON", + /* BIT31 */"ODM_COMP_INIT", + /* BIT32 */"ODM_COMP_NOISY_DETECT", +}; + +#define RTW_ODM_COMP_MAX 33 + +const char *odm_ability_str[] = { + /* BIT0 */"ODM_BB_DIG", + /* BIT1 */"ODM_BB_RA_MASK", + /* BIT2 */"ODM_BB_DYNAMIC_TXPWR", + /* BIT3 */"ODM_BB_FA_CNT", + /* BIT4 */"ODM_BB_RSSI_MONITOR", + /* BIT5 */"ODM_BB_CCK_PD", + /* BIT6 */"ODM_BB_ANT_DIV", + /* BIT7 */"ODM_BB_PWR_SAVE", + /* BIT8 */"ODM_BB_PWR_TRAIN", + /* BIT9 */"ODM_BB_RATE_ADAPTIVE", + /* BIT10 */"ODM_BB_PATH_DIV", + /* BIT11 */"ODM_BB_PSD", + /* BIT12 */"ODM_BB_RXHP", + /* BIT13 */"ODM_BB_ADAPTIVITY", + /* BIT14 */"ODM_BB_CFO_TRACKING", + /* BIT15 */"ODM_BB_NHM_CNT", + /* BIT16 */"ODM_BB_PRIMARY_CCA", + /* BIT17 */"ODM_BB_TXBF", + /* BIT18 */NULL, + /* BIT19 */NULL, + /* BIT20 */"ODM_MAC_EDCA_TURBO", + /* BIT21 */"ODM_MAC_EARLY_MODE", + /* BIT22 */NULL, + /* BIT23 */NULL, + /* BIT24 */"ODM_RF_TX_PWR_TRACK", + /* BIT25 */"ODM_RF_RX_GAIN_TRACK", + /* BIT26 */"ODM_RF_CALIBRATION", +}; + +#define RTW_ODM_ABILITY_MAX 27 + +const char *odm_dbg_level_str[] = { + NULL, + "ODM_DBG_OFF", + "ODM_DBG_SERIOUS", + "ODM_DBG_WARNING", + "ODM_DBG_LOUD", + "ODM_DBG_TRACE", +}; + +#define RTW_ODM_DBG_LEVEL_NUM 6 + +void rtw_odm_dbg_comp_msg(void *sel, _adapter *adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); + DM_ODM_T *odm = &pHalData->odmpriv; + int cnt = 0; + u64 dbg_comp = 0; + int i; + + rtw_hal_get_odm_var(adapter, HAL_ODM_DBG_FLAG, &dbg_comp, NULL); + + DBG_871X_SEL_NL(sel, "odm.DebugComponents = 0x%016llx\n", dbg_comp); + for (i=0;iodmpriv; + int cnt = 0; + u32 dbg_level = 0; + int i; + + rtw_hal_get_odm_var(adapter, HAL_ODM_DBG_LEVEL, &dbg_level, NULL); + DBG_871X_SEL_NL(sel, "odm.DebugLevel = %u\n", dbg_level); + for (i=0;iodmpriv; + int cnt = 0; + u32 ability = 0; + int i; + + ability = rtw_phydm_ability_get(adapter); + DBG_871X_SEL_NL(sel, "odm.SupportAbility = 0x%08x\n", ability); + for (i=0;iregistrypriv; + struct mlme_priv *mlme = &adapter->mlmepriv; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + DM_ODM_T *odm = &hal_data->odmpriv; + + DBG_871X_SEL_NL(sel, "RTW_ADAPTIVITY_EN_"); + + if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_DISABLE) { + DBG_871X_SEL(sel, "DISABLE\n"); + } else if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE) { + DBG_871X_SEL(sel, "ENABLE\n"); + } else { + DBG_871X_SEL(sel, "INVALID\n"); + } +} + +#define RTW_ADAPTIVITY_MODE_NORMAL 0 +#define RTW_ADAPTIVITY_MODE_CARRIER_SENSE 1 + +void rtw_odm_adaptivity_mode_msg(void *sel, _adapter *adapter) +{ + struct registry_priv *regsty = &adapter->registrypriv; + + DBG_871X_SEL_NL(sel, "RTW_ADAPTIVITY_MODE_"); + + if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_NORMAL) { + DBG_871X_SEL(sel, "NORMAL\n"); + } else if (regsty->adaptivity_mode == RTW_ADAPTIVITY_MODE_CARRIER_SENSE) { + DBG_871X_SEL(sel, "CARRIER_SENSE\n"); + } else { + DBG_871X_SEL(sel, "INVALID\n"); + } +} + +#define RTW_ADAPTIVITY_DML_DISABLE 0 +#define RTW_ADAPTIVITY_DML_ENABLE 1 + +void rtw_odm_adaptivity_dml_msg(void *sel, _adapter *adapter) +{ + struct registry_priv *regsty = &adapter->registrypriv; + + DBG_871X_SEL_NL(sel, "RTW_ADAPTIVITY_DML_"); + + if (regsty->adaptivity_dml == RTW_ADAPTIVITY_DML_DISABLE) { + DBG_871X_SEL(sel, "DISABLE\n"); + } else if (regsty->adaptivity_dml == RTW_ADAPTIVITY_DML_ENABLE) { + DBG_871X_SEL(sel, "ENABLE\n"); + } else { + DBG_871X_SEL(sel, "INVALID\n"); + } +} + +void rtw_odm_adaptivity_dc_backoff_msg(void *sel, _adapter *adapter) +{ + struct registry_priv *regsty = &adapter->registrypriv; + + DBG_871X_SEL_NL(sel, "RTW_ADAPTIVITY_DC_BACKOFF:%u\n", regsty->adaptivity_dc_backoff); +} + +void rtw_odm_adaptivity_config_msg(void *sel, _adapter *adapter) +{ + rtw_odm_adaptivity_ver_msg(sel, adapter); + rtw_odm_adaptivity_en_msg(sel, adapter); + rtw_odm_adaptivity_mode_msg(sel, adapter); + rtw_odm_adaptivity_dml_msg(sel, adapter); + rtw_odm_adaptivity_dc_backoff_msg(sel, adapter); +} + +bool rtw_odm_adaptivity_needed(_adapter *adapter) +{ + struct registry_priv *regsty = &adapter->registrypriv; + struct mlme_priv *mlme = &adapter->mlmepriv; + bool ret = _FALSE; + + if (regsty->adaptivity_en == RTW_ADAPTIVITY_EN_ENABLE) + ret = _TRUE; + + return ret; +} + +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_config_msg(sel, adapter); + + DBG_871X_SEL_NL(sel, "%10s %16s %16s %22s %12s\n" + , "TH_L2H_ini", "TH_EDCCA_HL_diff", "TH_L2H_ini_mode2", "TH_EDCCA_HL_diff_mode2", "EDCCA_enable"); + DBG_871X_SEL_NL(sel, "0x%-8x %-16d 0x%-14x %-22d %-12d\n" + , (u8)odm->TH_L2H_ini + , odm->TH_EDCCA_HL_diff + , (u8)odm->TH_L2H_ini_mode2 + , odm->TH_EDCCA_HL_diff_mode2 + , odm->EDCCA_enable + ); + + DBG_871X_SEL_NL(sel, "%15s %9s\n", "AdapEnableState", "Adap_Flag"); + DBG_871X_SEL_NL(sel, "%-15x %-9x\n" + , odm->Adaptivity_enable + , odm->adaptivity_flag + ); +} + +void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff, s8 TH_L2H_ini_mode2, s8 TH_EDCCA_HL_diff_mode2, u8 EDCCA_enable) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); + DM_ODM_T *odm = &pHalData->odmpriv; + + odm->TH_L2H_ini = TH_L2H_ini; + odm->TH_EDCCA_HL_diff = TH_EDCCA_HL_diff; + odm->TH_L2H_ini_mode2 = TH_L2H_ini_mode2; + odm->TH_EDCCA_HL_diff_mode2 = TH_EDCCA_HL_diff_mode2; + odm->EDCCA_enable = EDCCA_enable; +} + +void rtw_odm_get_perpkt_rssi(void *sel, _adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + DM_ODM_T *odm = &(hal_data->odmpriv); + + DBG_871X_SEL_NL(sel,"RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", + HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B); +} + + +void rtw_odm_acquirespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + _irqL irqL; + + switch(type) + { + case RT_IQK_SPINLOCK: + _enter_critical_bh(&pHalData->IQKSpinLock, &irqL); + default: + break; + } +} + +void rtw_odm_releasespinlock(_adapter *adapter, RT_SPINLOCK_TYPE type) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter); + _irqL irqL; + + switch(type) + { + case RT_IQK_SPINLOCK: + _exit_critical_bh(&pHalData->IQKSpinLock, &irqL); + default: + break; + } +} + +#ifdef CONFIG_DFS_MASTER +VOID rtw_odm_radar_detect_reset(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + PDM_ODM_T pDM_Odm = &(hal_data->odmpriv); + + if (pDM_Odm->SupportICType & ODM_RTL8192D) { + ODM_SetBBReg(pDM_Odm, 0xc84 , BIT25, 0); + ODM_SetBBReg(pDM_Odm, 0xc84 , BIT25, 1); + } else if (pDM_Odm->SupportICType & ODM_RTL8821) { + ODM_SetBBReg(pDM_Odm, 0x924 , BIT15, 0); + ODM_SetBBReg(pDM_Odm, 0x924 , BIT15, 1); + } else { + /* not supported yet */ + rtw_warn_on(1); + } +} + +VOID rtw_odm_radar_detect_disable(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + PDM_ODM_T pDM_Odm = &(hal_data->odmpriv); + + if (pDM_Odm->SupportICType & ODM_RTL8192D) + ODM_SetBBReg(pDM_Odm, 0xc84 , BIT25, 0); + else if (pDM_Odm->SupportICType & ODM_RTL8821) + ODM_SetBBReg(pDM_Odm, 0x924 , BIT15, 0); + else + rtw_warn_on(1); +} + +/* called after ch, bw is set, chance to adjust parameter for different ch conditions */ +VOID rtw_odm_radar_detect_enable(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + PDM_ODM_T pDM_Odm = &(hal_data->odmpriv); + + if (pDM_Odm->SupportICType & ODM_RTL8192D) { + ODM_SetBBReg(pDM_Odm, 0xc38, BIT23 | BIT22, 2); + ODM_SetBBReg(pDM_Odm, 0x814, bMaskDWord, 0x04cc4d10); + ODM_SetBBReg(pDM_Odm, 0xc8c, BIT23 | BIT22, 3); + ODM_SetBBReg(pDM_Odm, 0xc30, 0xf, 0xa); + ODM_SetBBReg(pDM_Odm, 0xcdc, 0xf0000, 4); + } else if (pDM_Odm->SupportICType & ODM_RTL8821) { + ODM_SetBBReg(pDM_Odm, 0x814, 0x3fffffff, 0x04cc4d10); + ODM_SetBBReg(pDM_Odm, 0x834, bMaskByte0, 0x06); + ODM_SetBBReg(pDM_Odm, 0x918, bMaskDWord, 0x1c16ecdf); + ODM_SetBBReg(pDM_Odm, 0x924, bMaskDWord, 0x0152a400); + ODM_SetBBReg(pDM_Odm, 0x91c, bMaskDWord, 0x0fa21a20); + ODM_SetBBReg(pDM_Odm, 0x920, bMaskDWord, 0xe0f57204); + } else { + /* not supported yet */ + rtw_warn_on(1); + } + + rtw_odm_radar_detect_reset(adapter); +} + +BOOLEAN rtw_odm_radar_detect(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + PDM_ODM_T pDM_Odm = &(hal_data->odmpriv); + BOOLEAN enable_DFS = FALSE; + BOOLEAN bypass = FALSE; + BOOLEAN radar_detected = FALSE; + + static u8Byte last_tx_unicast = 0; + static u8Byte last_rx_unicast = 0; + static u8Byte throughput = 0; + int tp_th = ((*pDM_Odm->pBandWidth == ODM_BW40M) ? 45 : 20); /*refer AP team's testing number*/ + + throughput = (*(pDM_Odm->pNumTxBytesUnicast) - last_tx_unicast) + (*(pDM_Odm->pNumRxBytesUnicast) - last_rx_unicast); + last_tx_unicast = *(pDM_Odm->pNumTxBytesUnicast); + last_rx_unicast = *(pDM_Odm->pNumRxBytesUnicast); + + if (throughput>>18 > tp_th) { + if (pDM_Odm->SupportICType & ODM_RTL8192D) + ODM_SetBBReg(pDM_Odm, 0xcdc, BIT8|BIT9, 0); + bypass = TRUE; + } else { + if (pDM_Odm->SupportICType & ODM_RTL8192D) + ODM_SetBBReg(pDM_Odm, 0xcdc, BIT8|BIT9, 1); + } + + if (pDM_Odm->SupportICType & ODM_RTL8192D) { + if (ODM_GetBBReg(pDM_Odm , 0xc84, BIT25)) + enable_DFS = TRUE; + } else if (pDM_Odm->SupportICType & ODM_RTL8821) { + if (ODM_GetBBReg(pDM_Odm , 0x924, BIT15)) + enable_DFS = TRUE; + } + + if (pDM_Odm->SupportICType & ODM_RTL8192D) { + if (ODM_GetBBReg(pDM_Odm , 0xcf8, BIT23)) + radar_detected = TRUE; + } else if (pDM_Odm->SupportICType & ODM_RTL8821) { + if (ODM_GetBBReg(pDM_Odm , 0xf98, BIT17)) + radar_detected = TRUE; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD + , ("Radar detect: enable_DFS:%d, radar_detected:%d, bypass:%d\n" + , enable_DFS, radar_detected, bypass)); + if (0) + DBG_871X("Radar detect: enable_DFS:%d, radar_detected:%d, bypass:%d(throughput:%llu, tp_th:%d)\n" + , enable_DFS, radar_detected, bypass, throughput, tp_th); + + if (enable_DFS && radar_detected) + rtw_odm_radar_detect_reset(adapter); + +exit: + return (enable_DFS && radar_detected && !bypass); +} +#endif /* CONFIG_DFS_MASTER */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_p2p.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_p2p.c new file mode 100644 index 00000000..d96d00f9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_p2p.c @@ -0,0 +1,5636 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_P2P_C_ + +#include + +#ifdef CONFIG_P2P + +int rtw_p2p_is_channel_list_ok( u8 desired_ch, u8* ch_list, u8 ch_cnt ) +{ + int found = 0, i = 0; + + for( i = 0; i < ch_cnt; i++ ) + { + if ( ch_list[ i ] == desired_ch ) + { + found = 1; + break; + } + } + return( found ); +} + +int is_any_client_associated(_adapter *padapter) +{ + return padapter->stapriv.asoc_list_cnt ? _TRUE : _FALSE; +} + +static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + _irqL irqL; + _list *phead, *plist; + u32 len=0; + u16 attr_len = 0; + u8 tmplen, *pdata_attr, *pstart, *pcur; + struct sta_info *psta = NULL; + _adapter *padapter = pwdinfo->padapter; + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + 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; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //look up sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + + if(psta->is_p2p_device) + { + tmplen = 0; + + pcur++; + + //P2P device address + _rtw_memcpy(pcur, psta->dev_addr, ETH_ALEN); + pcur += ETH_ALEN; + + //P2P interface address + _rtw_memcpy(pcur, psta->hwaddr, ETH_ALEN); + pcur += ETH_ALEN; + + *pcur = psta->dev_cap; + pcur++; + + //*(u16*)(pcur) = cpu_to_be16(psta->config_methods); + RTW_PUT_BE16(pcur, psta->config_methods); + pcur += 2; + + _rtw_memcpy(pcur, psta->primary_dev_type, 8); + pcur += 8; + + *pcur = psta->num_of_secdev_type; + pcur++; + + _rtw_memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8); + pcur += psta->num_of_secdev_type*8; + + if(psta->dev_name_len>0) + { + //*(u16*)(pcur) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME); + pcur += 2; + + //*(u16*)(pcur) = cpu_to_be16( psta->dev_name_len ); + RTW_PUT_BE16(pcur, psta->dev_name_len); + pcur += 2; + + _rtw_memcpy(pcur, psta->dev_name, psta->dev_name_len); + pcur += psta->dev_name_len; + } + + + tmplen = (u8)(pcur-pstart); + + *pstart = (tmplen-1); + + attr_len += tmplen; + + //pstart += tmplen; + pstart = pcur; + + } + + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + if(attr_len>0) + { + len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr); + } + + rtw_mfree(pdata_attr, MAX_P2P_IE_LEN); + +_exit: + return len; + +} + +static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_GO_DISC_REQUEST; + u8 dialogToken=0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); + + 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); + + //Build P2P action frame header + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + //there is no IE in this P2P action frame + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_DEVDISC_RESP; + u8 p2pie[8] = { 0x00 }; + u32 p2pielen = 0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN); + + 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); + + //Build P2P public action frame header + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //Build P2P IE + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // P2P_ATTR_STATUS + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen); + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8* raddr, u8* frame_body, u16 config_method) +{ + _adapter *padapter = pwdinfo->padapter; + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = frame_body[7]; // The Dialog Token of provisioning discovery request frame. + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_RESP; + u8 wpsie[ 100 ] = { 0x00 }; + u8 wpsielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + 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 ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->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: + //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); + RTW_PUT_BE16(wpsie + wpsielen, config_method); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + return; + +} + +static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + _adapter *padapter = pwdinfo->padapter; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PRESENCE_RESPONSE; + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u8 noa_attr_content[32] = { 0x00 }; + u32 p2pielen = 0; + + DBG_871X("[%s]\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + //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, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN); + + 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); + + //Build P2P action frame header + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //Add P2P IE header + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + //Add Status attribute in P2P IE + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status); + + //Add NoA attribute in P2P IE + noa_attr_content[0] = 0x1;//index + noa_attr_content[1] = 0x0;//CTWindow and OppPS Parameters + + //todo: Notice of Absence Descriptor(s) + + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content); + + + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen)); + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + +} + +u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u16 capability=0; + u32 len=0, p2pielen = 0; + + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + + // According to the P2P Specification, the beacon frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. P2P Device ID + // 3. Notice of Absence ( NOA ) + + // P2P Capability ATTR + // Type: + // Length: + // Value: + // Device Capability Bitmap, 1 byte + // Be able to participate in additional P2P Groups and + // support the P2P Invitation Procedure + // Group Capability Bitmap, 1 byte + capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY; + capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8); + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + capability |= (P2P_GRPCAP_GROUP_FORMATION<<8); + + capability = cpu_to_le16(capability); + + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8*)&capability); + + + // P2P Device ID ATTR + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr); + + + // Notice of Absence ATTR + // Type: + // Length: + // Value: + + //go_add_noa_attr(pwdinfo); + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + +#ifdef CONFIG_WFD +u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u16 val16=0; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the beacon frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + if ( is_any_client_associated( pwdinfo->padapter ) ) + { + // WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + } + + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u16 val16=0; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + + if ( 1 == pwdinfo->wfd_tdls_enable ) + { + // WFD primary sink + available for WFD session + WiFi TDLS mode + WSC ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | + WFD_DEVINFO_SESSION_AVAIL | + WFD_DEVINFO_WSD | + WFD_DEVINFO_PC_TDLS; + RTW_PUT_BE16(wfdie + wfdielen, val16 ); + } + else + { + // WFD primary sink + available for WFD session + WiFi Direct mode + WSC ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | + WFD_DEVINFO_SESSION_AVAIL | + WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16 ); + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe response frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + // 4. WFD Session Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + + if ( _TRUE == pwdinfo->session_available ) + { + if ( P2P_ROLE_GO == pwdinfo->role ) + { + if ( is_any_client_associated( pwdinfo->padapter ) ) + { + if ( pwdinfo->wfd_tdls_enable ) + { + // TDLS mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + // WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + // available for WFD session + TDLS mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + + // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + } + } + else + { + if ( pwdinfo->wfd_tdls_enable ) + { + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD |WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT); + } + else + { + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT); + } + + } + + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_TDLS + if ( ( tunneled == 0 ) && ( padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1 ) ) + { + // Alternative MAC Address ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ALTER_MAC; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, ETH_ALEN ); + wfdielen += 2; + + // Value: + // Alternative MAC Address + _rtw_memcpy(wfdie + wfdielen, adapter_mac_addr(padapter->pbuddy_adapter), ETH_ALEN); + // This mac address is used to make the WFD session when TDLS is enable. + + wfdielen += ETH_ALEN; + } +#endif // CONFIG_TDLS +#endif // CONFIG_CONCURRENT_MODE + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u16 val16=0; + u32 len=0, wfdielen = 0; + _adapter *padapter = NULL; + struct mlme_priv *pmlmepriv = NULL; + struct wifi_display_info *pwfd_info = NULL; + + padapter = pwdinfo->padapter; + pmlmepriv = &padapter->mlmepriv; + pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + goto exit; + + /* WFD OUI */ + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110812 + // According to the WFD Specification, the probe request frame should contain 4 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID + // 3. Coupled Sink Information + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u16 val16=0; + u32 len=0, wfdielen = 0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + if ( P2P_ROLE_GO == pwdinfo->role ) + { + // WFD Session Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0000); + wfdielen += 2; + + // Todo: to add the list of WFD device info descriptor in WFD group. + + } + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} + +u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 len=0, wfdielen = 0; + u16 val16=0; + _adapter *padapter = pwdinfo->padapter; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + goto exit; + + // WFD OUI + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0 + + // Commented by Albert 20110825 + // According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes + // 1. WFD Device Information + // 2. Associated BSSID ( Optional ) + // 3. Local IP Adress ( Optional ) + + + // WFD Device Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value1: + // WFD device information + // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery ) + val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD; + RTW_PUT_BE16(wfdie + wfdielen, val16); + wfdielen += 2; + + // Value2: + // Session Management Control Port + // Default TCP port for RTSP messages is 554 + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport ); + wfdielen += 2; + + // Value3: + // WFD Device Maximum Throughput + // 300Mbps is the maximum throughput + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + // Associated BSSID ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + // Value: + // Associated BSSID + if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ) + { + _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN ); + } + else + { + _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN ); + } + + wfdielen += ETH_ALEN; + + // Coupled Sink Information ATTR + // Type: + wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO; + + // Length: + // Note: In the WFD specification, the size of length field is 2. + RTW_PUT_BE16(wfdie + wfdielen, 0x0007); + wfdielen += 2; + + // Value: + // Coupled Sink Status bitmap + // Not coupled/available for Coupling + wfdie[ wfdielen++ ] = 0; + // MAC Addr. + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + wfdie[ wfdielen++ ] = 0; + + rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len); + +exit: + return len; +} +#endif /* CONFIG_WFD */ + +u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; +#ifdef CONFIG_INTEL_WIDI + struct mlme_priv *pmlmepriv = &(pwdinfo->padapter->mlmepriv); + u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 }; + u8 widi_version = 0, i = 0; + + if( _rtw_memcmp( pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE ) + { + widi_version = 35; + } + else if( pmlmepriv->num_p2p_sdt != 0 ) + { + widi_version = 40; + } +#endif //CONFIG_INTEL_WIDI + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20100907 + // According to the P2P Specification, the probe response frame should contain 5 P2P attributes + // 1. P2P Capability + // 2. Extended Listen Timing + // 3. Notice of Absence ( NOA ) ( Only GO needs this ) + // 4. Device Info + // 5. Group Info ( Only GO need this ) + + // P2P Capability ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION; + + p2pielen++; + } + else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) ) + { + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + } + + // Extended Listen Timing ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0004); + p2pielen += 2; + + // Value: + // Availability Period + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); + p2pielen += 2; + + // Availability Interval + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF ); + RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF); + p2pielen += 2; + + + // Notice of Absence ATTR + // Type: + // Length: + // Value: + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + //go_add_noa_attr(pwdinfo); + } + + // Device Info ATTR + // 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 ); +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 35 ) + { + RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len); + } + else if( widi_version == 40 ) + { + RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 * pmlmepriv->num_p2p_sdt + pwdinfo->device_name_len); + } + else +#endif //CONFIG_INTEL_WIDI + RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + // P2P Device Address + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, 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 ); + RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm); + p2pielen += 2; + +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 40 ) + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_cid ); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_scid); + p2pielen += 2; + } + else +#endif //CONFIG_INTEL_WIDI + { + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER); + p2pielen += 2; + } + + // Number of Secondary Device Types +#ifdef CONFIG_INTEL_WIDI + if( widi_version == 35 ) + { + p2pie[ p2pielen++ ] = 0x01; + + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_DISPLAYS); + p2pielen += 2; + + RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI); + p2pielen += 4; + + RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK); + p2pielen += 2; + } + else if( widi_version == 40 ) + { + p2pie[ p2pielen++ ] = pmlmepriv->num_p2p_sdt; + for( ; i < pmlmepriv->num_p2p_sdt; i++ ) + { + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_cid[i]); + p2pielen += 2; + + RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI); + p2pielen += 4; + + RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_scid[i]); + p2pielen += 2; + } + } + else +#endif //CONFIG_INTEL_WIDI + p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List + + // Device Name + // Type: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); + p2pielen += 2; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); + RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len ); + p2pielen += pwdinfo->device_name_len; + + // Group Info ATTR + // Type: + // Length: + // Value: + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen); + } + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + +u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr ) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110301 + // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Device Info + // 3. Group ID ( When joining an operating P2P Group ) + + // P2P Capability ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2pie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT; + + // Group Capability Bitmap, 1 byte + if ( pwdinfo->persistent_supported ) + p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT; + else + p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT; + + + // Device Info ATTR + // 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 ); + RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len); + p2pielen += 2; + + // Value: + // P2P Device Address + _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); + p2pielen += ETH_ALEN; + + // Config Method + // This field should be big endian. Noted by P2P specification. + if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC ) + { + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC); + } + else + { + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY); + } + + p2pielen += 2; + + // Primary Device Type + // Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA); + p2pielen += 2; + + // OUI + //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI ); + RTW_PUT_BE32(p2pie + p2pielen, WPSOUI); + p2pielen += 4; + + // Sub Category ID + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER ); + RTW_PUT_BE16(p2pie + p2pielen, 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 ); + RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME); + p2pielen += 2; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len ); + RTW_PUT_BE16(p2pie + p2pielen, 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_CLIENT) ) + { + // Added by Albert 2011/05/19 + // In this case, the pdev_raddr is the device address of the group owner. + + // P2P Group ID ATTR + // Type: + p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + ussidlen ); + RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen); + p2pielen += 2; + + // Value: + _rtw_memcpy( p2pie + p2pielen, pdev_raddr, ETH_ALEN ); + p2pielen += ETH_ALEN; + + _rtw_memcpy( p2pie + p2pielen, pssid, ussidlen ); + p2pielen += ussidlen; + + } + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + + return len; + +} + + +u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code) +{ + u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 }; + u32 len=0, p2pielen = 0; + + // P2P OUI + p2pielen = 0; + p2pie[ p2pielen++ ] = 0x50; + p2pie[ p2pielen++ ] = 0x6F; + p2pie[ p2pielen++ ] = 0x9A; + p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // According to the P2P Specification, the Association response frame should contain 2 P2P attributes + // 1. Status + // 2. Extended Listen Timing (optional) + + + // Status ATTR + p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code); + + + // Extended Listen Timing ATTR + // Type: + // Length: + // Value: + + + pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len); + + return len; + +} + +u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf) +{ + u32 len=0; + + return len; +} + +u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *p; + u32 ret=_FALSE; + u8 *p2pie; + u32 p2pielen = 0; + int ssid_len=0, rate_cnt = 0; + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + if ( rate_cnt <= 4 ) + { + int i, g_rate =0; + + for( i = 0; i < rate_cnt; i++ ) + { + if ( ( ( *( p + 2 + i ) & 0xff ) != 0x02 ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x04 ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x0B ) && + ( ( *( p + 2 + i ) & 0xff ) != 0x16 ) ) + { + g_rate = 1; + } + } + + if ( g_rate == 0 ) + { + // There is no OFDM rate included in SupportedRates IE of this probe request frame + // The driver should response this probe request. + return ret; + } + } + else + { + // rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. + // We should proceed the following check for this probe request. + } + + // Added comments by Albert 20100906 + // There are several items we should check here. + // 1. This probe request frame must contain the P2P IE. (Done) + // 2. This probe request frame must contain the wildcard SSID. (Done) + // 3. Wildcard BSSID. (Todo) + // 4. Destination Address. ( Done in mgt_dispatcher function ) + // 5. Requested Device Type in WSC IE. (Todo) + // 6. Device ID attribute in P2P IE. (Todo) + + p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len, + len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); + + ssid_len &= 0xff; // Just last 1 byte is valid for ssid len of the probe request + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if((p2pie=rtw_get_p2p_ie( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen))) + { + if ( (p != NULL) && _rtw_memcmp( ( void * ) ( p+2 ), ( void * ) pwdinfo->p2p_wildcard_ssid , 7 )) + { + //todo: + //Check Requested Device Type attributes in WSC IE. + //Check Device ID attribute in P2P IE + + ret = _TRUE; + } + else if ( (p != NULL) && ( ssid_len == 0 ) ) + { + ret = _TRUE; + } + } + else + { + //non -p2p device + } + + } + + + return ret; + +} + +u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta) +{ + u8 status_code = P2P_STATUS_SUCCESS; + u8 *pbuf, *pattr_content=NULL; + u32 attr_contentlen = 0; + u16 cap_attr=0; + unsigned short frame_type, ie_offset=0; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + + if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + return P2P_STATUS_FAIL_REQUEST_UNABLE; + + frame_type = GetFrameSubType(pframe); + if (frame_type == WIFI_ASSOCREQ) + { + ie_offset = _ASOCREQ_IE_OFFSET_; + } + else // WIFI_REASSOCREQ + { + ie_offset = _REASOCREQ_IE_OFFSET_; + } + + ies = pframe + WLAN_HDR_A3_LEN + ie_offset; + ies_len = len - WLAN_HDR_A3_LEN - ie_offset; + + p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen); + + if ( !p2p_ie ) + { + DBG_8192C( "[%s] P2P IE not Found!!\n", __FUNCTION__ ); + status_code = P2P_STATUS_FAIL_INVALID_PARAM; + } + else + { + DBG_8192C( "[%s] P2P IE Found!!\n", __FUNCTION__ ); + } + + while ( p2p_ie ) + { + //Check P2P Capability ATTR + if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) ) + { + DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); + cap_attr = le16_to_cpu(cap_attr); + psta->dev_cap = cap_attr&0xff; + } + + //Check Extended Listen Timing ATTR + + + //Check P2P Device Info ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint*)&attr_contentlen)) + { + DBG_8192C( "[%s] Got P2P DEVICE INFO Attr!!\n", __FUNCTION__ ); + pattr_content = pbuf = rtw_zmalloc(attr_contentlen); + if(pattr_content) + { + u8 num_of_secdev_type; + u16 dev_name_len; + + + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint*)&attr_contentlen); + + _rtw_memcpy(psta->dev_addr, pattr_content, ETH_ALEN);//P2P Device Address + + pattr_content += ETH_ALEN; + + _rtw_memcpy(&psta->config_methods, pattr_content, 2);//Config Methods + psta->config_methods = be16_to_cpu(psta->config_methods); + + pattr_content += 2; + + _rtw_memcpy(psta->primary_dev_type, pattr_content, 8); + + pattr_content += 8; + + num_of_secdev_type = *pattr_content; + pattr_content += 1; + + if(num_of_secdev_type==0) + { + psta->num_of_secdev_type = 0; + } + else + { + u32 len; + + psta->num_of_secdev_type = num_of_secdev_type; + + len = (sizeof(psta->secdev_types_list)<(num_of_secdev_type*8)) ? (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8); + + _rtw_memcpy(psta->secdev_types_list, pattr_content, len); + + pattr_content += (num_of_secdev_type*8); + } + + + //dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8); + psta->dev_name_len=0; + if(WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(u16*)pattr_content)) + { + dev_name_len = be16_to_cpu(*(u16*)(pattr_content+2)); + + psta->dev_name_len = (sizeof(psta->dev_name)dev_name):dev_name_len; + + _rtw_memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len); + } + + rtw_mfree(pbuf, attr_contentlen); + + } + + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + return status_code; + +} + +u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *frame_body; + u8 status, dialogToken; + struct sta_info *psta = NULL; + _adapter *padapter = pwdinfo->padapter; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *p2p_ie; + u32 p2p_ielen = 0; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + dialogToken = frame_body[7]; + status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; + + if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) ) + { + u8 groupid[ 38 ] = { 0x00 }; + u8 dev_addr[ETH_ALEN] = { 0x00 }; + u32 attr_contentlen = 0; + + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) + { + if(_rtw_memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) && + _rtw_memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len)) + { + attr_contentlen=0; + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) + { + _irqL irqL; + _list *phead, *plist; + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //look up sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + if(psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) && + _rtw_memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) + { + + //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + //issue GO Discoverability Request + issue_group_disc_req(pwdinfo, psta->hwaddr); + //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + status = P2P_STATUS_SUCCESS; + + break; + } + else + { + status = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + } + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + } + else + { + status = P2P_STATUS_FAIL_INVALID_PARAM; + } + + } + else + { + status = P2P_STATUS_FAIL_INVALID_PARAM; + } + + } + + } + + + //issue Device Discoverability Response + issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); + + + return (status==P2P_STATUS_SUCCESS) ? _TRUE:_FALSE; + +} + +u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + return _TRUE; +} + +u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + u8 *frame_body; + u8 *wpsie; + uint wps_ielen = 0, attr_contentlen = 0; + u16 uconfig_method = 0; + + + frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + if ( (wpsie=rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) ) + { + if ( rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_CONF_METHOD , ( u8* ) &uconfig_method, &attr_contentlen) ) + { + uconfig_method = be16_to_cpu( uconfig_method ); + switch( uconfig_method ) + { + case WPS_CM_DISPLYA: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + break; + } + case WPS_CM_LABEL: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3 ); + break; + } + case WPS_CM_PUSH_BUTTON: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + break; + } + case WPS_CM_KEYPAD: + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + break; + } + } + issue_p2p_provision_resp( pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method); + } + } + DBG_871X( "[%s] config method = %s\n", __FUNCTION__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req ); + return _TRUE; + +} + +u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe) +{ + + return _TRUE; +} + +u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list) +{ + u8 i = 0, j = 0; + u8 temp = 0; + u8 ch_no = 0; + ch_content += 3; + ch_cnt -= 3; + + while( ch_cnt > 0) + { + ch_content += 1; + ch_cnt -= 1; + temp = *ch_content; + for( i = 0 ; i < temp ; i++, j++ ) + { + peer_ch_list[j] = *( ch_content + 1 + i ); + } + ch_content += (temp + 1); + ch_cnt -= (temp + 1); + ch_no += temp ; + } + + return ch_no; +} + +u8 rtw_p2p_check_peer_oper_ch(struct mlme_ext_priv *pmlmeext, u8 ch) +{ + u8 i = 0; + + for( i = 0; i < pmlmeext->max_chan_nums; i++ ) + { + if ( pmlmeext->channel_set[ i ].ChannelNum == ch ) + { + return _SUCCESS; + } + } + + return _FAIL; +} + +u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned) +{ + int i = 0, j = 0, temp = 0; + u8 ch_no = 0; + + for( i = 0; i < peer_ch_num; i++ ) + { + for( j = temp; j < pmlmeext->max_chan_nums; j++ ) + { + if( *( peer_ch_list + i ) == pmlmeext->channel_set[ j ].ChannelNum ) + { + ch_list_inclusioned[ ch_no++ ] = *( peer_ch_list + i ); + temp = j; + break; + } + } + } + + return ch_no; +} + +u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + _adapter *padapter = pwdinfo->padapter; + u8 result = P2P_STATUS_SUCCESS; + u32 p2p_ielen = 0, wps_ielen = 0; + u8 * ies; + u32 ies_len; + u8 *p2p_ie; + u8 *wpsie; + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; +#ifdef CONFIG_WFD +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#endif // CONFIG_TDLS +#endif // CONFIG_WFD +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = pwdinfo->padapter->pbuddy_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 + + if ( (wpsie=rtw_get_wps_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) ) + { + // Commented by Kurt 20120113 + // If some device wants to do p2p handshake without sending prov_disc_req + // We have to get peer_req_cm from here. + if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) ) + { + rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + if ( wps_devicepassword_id == WPS_DPID_USER_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 ); + } + else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC ) + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 ); + } + else + { + _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 ); + } + } + } + else + { + DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + return( result ); + } + + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + if ( !p2p_ie ) + { + DBG_871X( "[%s] P2P IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + + while ( p2p_ie ) + { + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + u8 ch_content[100] = { 0x00 }; + uint ch_cnt = 0; + u8 peer_ch_list[100] = { 0x00 }; + u8 peer_ch_num = 0; + u8 ch_list_inclusioned[100] = { 0x00 }; + u8 ch_num_inclusioned = 0; + u16 cap_attr; + u8 listen_ch_attr[5] = { 0x00 }; + + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); + + //Check P2P Capability ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) ) + { + cap_attr = le16_to_cpu(cap_attr); + +#if defined(CONFIG_WFD) && defined(CONFIG_TDLS) + if(!(cap_attr & P2P_GRPCAP_INTRABSS) ) + ptdlsinfo->ap_prohibited = _TRUE; +#endif //defined(CONFIG_WFD) && defined(CONFIG_TDLS) + } + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) ) + { + DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 ); + pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values. + + if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) ) + { + // Try to match the tie breaker value + if ( pwdinfo->intent == P2P_MAX_INTENT ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; + } + else + { + if ( attr_content & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + } + else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + // Store the group id information. + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen ); + } + } + + if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8 *)listen_ch_attr, (uint *) &attr_contentlen) && attr_contentlen == 5) + pwdinfo->nego_req_info.peer_ch = listen_ch_attr[4]; + + DBG_871X(FUNC_ADPT_FMT" listen channel :%u\n", FUNC_ADPT_ARG(padapter), pwdinfo->nego_req_info.peer_ch); + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) ) + { + if ( attr_contentlen != ETH_ALEN ) + { + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + } + } + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt) ) + { + peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list); + ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); + + if( ch_num_inclusioned == 0) + { + DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel, + ch_list_inclusioned, ch_num_inclusioned) ) + { +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_LINKED) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; + attr_contentlen = 0; + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + peer_operating_ch = operatingch_info[4]; + } + + if ( rtw_p2p_is_channel_list_ok( peer_operating_ch, + ch_list_inclusioned, ch_num_inclusioned) ) + { + /** + * Change our operating channel as peer's for compatibility. + */ + pwdinfo->operating_channel = peer_operating_ch; + DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel); + } + else + { + // Take first channel of ch_list_inclusioned as operating channel + pwdinfo->operating_channel = ch_list_inclusioned[0]; + DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel); + } + } + + } + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } + + if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) { + result = P2P_STATUS_FAIL_INFO_UNAVAILABLE; + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY); + return result; + } + + #ifdef CONFIG_WFD + rtw_process_wfd_ies(padapter, pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, __func__); + #endif + + return( result ); +} + +u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + _adapter *padapter = pwdinfo->padapter; + u8 result = P2P_STATUS_SUCCESS; + u32 p2p_ielen, wps_ielen; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; +#ifdef CONFIG_WFD +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; +#endif // CONFIG_TDLS +#endif // CONFIG_WFD + + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + // Be able to know which one is the P2P GO and which one is P2P client. + + if ( rtw_get_wps_ie( ies, ies_len, NULL, &wps_ielen) ) + { + + } + else + { + DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + if ( !p2p_ie ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM; + } + else + { + + u8 attr_content = 0x00; + u32 attr_contentlen = 0; + u8 operatingch_info[5] = { 0x00 }; + uint ch_cnt = 0; + u8 ch_content[100] = { 0x00 }; + u8 groupid[ 38 ]; + u16 cap_attr; + u8 peer_ch_list[100] = { 0x00 }; + u8 peer_ch_num = 0; + u8 ch_list_inclusioned[100] = { 0x00 }; + u8 ch_num_inclusioned = 0; + + while ( p2p_ie ) // Found the P2P IE. + { + + //Check P2P Capability ATTR + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) ) + { + cap_attr = le16_to_cpu(cap_attr); +#ifdef CONFIG_TDLS + if(!(cap_attr & P2P_GRPCAP_INTRABSS) ) + ptdlsinfo->ap_prohibited = _TRUE; +#endif // CONFIG_TDLS + } + + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + if ( attr_content == P2P_STATUS_SUCCESS ) + { + // Do nothing. + } + else + { + if ( P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content ) { + rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY); + } else { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = attr_content; + break; + } + } + + // Try to get the peer's interface address + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) ) + { + if ( attr_contentlen != ETH_ALEN ) + { + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + } + } + + // Try to get the peer's intent and tie breaker value. + attr_content = 0x00; + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) ) + { + DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 ); + pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values. + + if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) ) + { + // Try to match the tie breaker value + if ( pwdinfo->intent == P2P_MAX_INTENT ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + result = P2P_STATUS_FAIL_BOTH_GOINTENT_15; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + if ( attr_content & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + } + else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + // Store the group id information. + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen ); + + } + } + + // Try to get the operation channel information + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) + { + DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] ); + pwdinfo->peer_operating_ch = operatingch_info[4]; + } + + // Try to get the channel list information + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len ) ) + { + DBG_871X( "[%s] channel list attribute found, len = %d\n", __FUNCTION__, pwdinfo->channel_list_attr_len ); + + peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list); + ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned); + + if( ch_num_inclusioned == 0) + { + DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel, + ch_list_inclusioned, ch_num_inclusioned) ) + { +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_LINKED) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ ); + result = P2P_STATUS_FAIL_NO_COMMON_CH; + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0; + attr_contentlen = 0; + + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + peer_operating_ch = operatingch_info[4]; + } + + if ( rtw_p2p_is_channel_list_ok( peer_operating_ch, + ch_list_inclusioned, ch_num_inclusioned) ) + { + /** + * Change our operating channel as peer's for compatibility. + */ + pwdinfo->operating_channel = peer_operating_ch; + DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel); + } + else + { + // Take first channel of ch_list_inclusioned as operating channel + pwdinfo->operating_channel = ch_list_inclusioned[0]; + DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel); + } + } + + } + } + + } + else + { + DBG_871X( "[%s] channel list attribute not found!\n", __FUNCTION__); + } + + // Try to get the group id information if peer is GO + attr_contentlen = 0; + _rtw_memset( groupid, 0x00, 38 ); + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) ) + { + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN ); + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } + + } + + #ifdef CONFIG_WFD + rtw_process_wfd_ies(padapter, pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, __func__); + #endif + + return( result ); + +} + +u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ) +{ + _adapter *padapter = pwdinfo->padapter; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + u8 result = P2P_STATUS_SUCCESS; + ies = pframe + _PUBLIC_ACTION_IE_OFFSET_; + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + while ( p2p_ie ) // Found the P2P IE. + { + u8 attr_content = 0x00, operatingch_info[5] = { 0x00 }; + u8 groupid[ 38 ] = { 0x00 }; + u32 attr_contentlen = 0; + + pwdinfo->negotiation_dialog_token = 1; + rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen); + if ( attr_contentlen == 1 ) + { + DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content ); + result = attr_content; + + if ( attr_content == P2P_STATUS_SUCCESS ) + { + u8 bcancelled = 0; + + _cancel_timer( &pwdinfo->restore_p2p_state_timer, &bcancelled ); + + // Commented by Albert 20100911 + // Todo: Need to handle the case which both Intents are the same. + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + if ( ( pwdinfo->intent ) > ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + else if ( ( pwdinfo->intent ) < ( pwdinfo->peer_intent >> 1 ) ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + // Have to compare the Tie Breaker + if ( pwdinfo->peer_intent & 0x01 ) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter , _FW_LINKED) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + // Switch back to the AP channel soon. + _set_timer( &pwdinfo->ap_p2p_switch_timer, 100 ); + } +#endif + } + else + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL); + break; + } + } + + // Try to get the group id information + attr_contentlen = 0; + _rtw_memset( groupid, 0x00, 38 ); + if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) ) + { + DBG_871X( "[%s] Ssid = %s, ssidlen = %zu\n", __FUNCTION__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]) ); + _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN ); + _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN ); + } + + attr_contentlen = 0; + if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) ) + { + DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] ); + pwdinfo->peer_operating_ch = operatingch_info[4]; + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + return( result ); +} + +u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) +{ + u8 *frame_body; + u8 dialogToken=0; + u8 status = P2P_STATUS_SUCCESS; + + frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr)); + + dialogToken = frame_body[6]; + + //todo: check NoA attribute + + issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken); + + return _TRUE; +} + +void find_phase_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + NDIS_802_11_SSID ssid; + _irqL irqL; + u8 _status = 0; + +_func_enter_; + + _rtw_memset((unsigned char*)&ssid, 0, sizeof(NDIS_802_11_SSID)); + _rtw_memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ); + ssid.SsidLength = P2P_WILDCARD_SSID_LEN; + + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _status = rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + +_func_exit_; +} + +void p2p_concurrent_handler( _adapter* padapter ); + +void restore_p2p_state_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + } + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP)) + { + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + } +#endif + + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) + { +#ifdef CONFIG_CONCURRENT_MODE + p2p_concurrent_handler( padapter ); +#else + // In the P2P client mode, the driver should not switch back to its listen channel + // because this P2P client should stay at the operating channel of P2P GO. + set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); +#endif + } +_func_exit_; +} + +void pre_tx_invitereq_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +void pre_tx_provdisc_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +void pre_tx_negoreq_handler( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + u8 val8 = 1; +_func_enter_; + + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter , NULL); + /* WIN Phone only accept unicast probe request when nego back */ + issue_probereq_p2p(padapter , pwdinfo->nego_req_info.peerDevAddr); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +_func_exit_; +} + +#ifdef CONFIG_CONCURRENT_MODE +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; + //struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 val8; +_func_enter_; + + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel; + + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel); + + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + else if( pwdinfo->driver_interface == DRIVER_WEXT ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + // Now, the driver stays on the AP's channel. + // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel. + if ( pwdinfo->ext_listen_period > 0 ) + { + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period ); + + if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel ) + { + // Will switch to listen channel so that need to send the NULL data with PW bit to AP. + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + 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 ); + } + } + else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) || + ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) || + rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) ) + { + // Now, the driver is in the listen state of P2P mode. + DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval ); + + // Commented by Albert 2012/11/01 + // If the AP's channel is the same as the listen channel, we should still be in the listen state + // Other P2P device is still able to find this device out even this device is in the AP's channel. + // So, configure this device to be able to receive the probe request frame and set it to listen state. + 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); + if(!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&!(pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + { + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + } + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + + // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not. + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) + { + // The driver had finished the P2P handshake successfully. + val8 = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE) + { + val8 = 1; + set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE) + { + /* + val8 = 1; + set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); + issue_probereq_p2p(padapter, NULL); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + */ + } + } + } + else + { + /* In p2p+softap. When in P2P_STATE_GONEGO_OK, not back to listen channel.*/ + if (!rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK) || padapter->registrypriv.full_ch_in_p2p_handshake == 0) + set_channel_bwmode(padapter , pwdinfo->listen_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , CHANNEL_WIDTH_20); + else + DBG_871X("%s, buddy not linked, go nego ok, not back to listen channel\n", __func__); + } + +_func_exit_; +} +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +static void ro_ch_handler(_adapter *padapter) +{ + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ch, bw, offset; +_func_enter_; + + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + if (0) + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) { + ch = pwdinfo->listen_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + else { + ch = pcfg80211_wdinfo->restore_channel; + bw = CHANNEL_WIDTH_20; + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + if (0) + DBG_871X(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + } + + set_channel_bwmode(padapter, ch, offset, bw); + + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + + pcfg80211_wdinfo->is_ro_ch = _FALSE; + pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time(); + + 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, + pcfg80211_wdinfo->remain_on_ch_cookie, + &pcfg80211_wdinfo->remain_on_ch_channel, + pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL); + +_func_exit_; +} + +static void ro_ch_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + + //printk("%s \n", __FUNCTION__); + +#ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); +#endif + + p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK); +} + +static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while ( p2p_ie ) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) + { + *(pattr+4) = ch; + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +} + +static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch) +{ + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; ipbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; ipbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + u8 buddy_ch = pbuddy_mlmeext->cur_channel; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while (p2p_ie) { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) { + if (*(pattr+4) == buddy_ch) { + DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch); + fit = _TRUE; + break; + } + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } +#endif + return fit; +} + +static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len) +{ +#ifdef CONFIG_CONCURRENT_MODE + u8 *ies, *p2p_ie; + u32 ies_len, p2p_ielen; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_); + ies_len = len - _PUBLIC_ACTION_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen ); + + while ( p2p_ie ) + { + u32 attr_contentlen = 0; + u8 *pattr = NULL; + + //Check P2P_ATTR_CH_LIST + if((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) + { + int i; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + while(attr_contentlen>0) + { + num_of_ch = *(pattr_temp+1); + + for(i=0; icur_channel;//forcing to the same channel + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + } + + //Check P2P_ATTR_OPERATING_CH + attr_contentlen = 0; + pattr = NULL; + if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) + { + *(pattr+4) = pbuddy_mlmeext->cur_channel;//forcing to the same channel + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + +#endif +} + +#ifdef CONFIG_WFD +u32 rtw_xframe_build_wfd_ie(struct xmit_frame *xframe) +{ + _adapter *adapter = xframe->padapter; + struct wifidirect_info *wdinfo = &adapter->wdinfo; + u8 *frame = xframe->buf_addr + TXDESC_OFFSET; + u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 *frame_tail = frame + xframe->attrib.pktlen; + u8 category, action, OUI_Subtype, dialogToken = 0; + u32 wfdielen = 0; + + category = frame_body[0]; + if (category == RTW_WLAN_CATEGORY_PUBLIC) { + action = frame_body[1]; + if (action == ACT_PUBLIC_VENDOR + && _rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE + ) { + OUI_Subtype = frame_body[6]; + dialogToken = frame_body[7]; + + switch (OUI_Subtype) { + case P2P_GO_NEGO_REQ: + wfdielen = build_nego_req_wfd_ie(wdinfo, frame_tail); + break; + case P2P_GO_NEGO_RESP: + wfdielen = build_nego_resp_wfd_ie(wdinfo, frame_tail); + break; + case P2P_GO_NEGO_CONF: + wfdielen = build_nego_confirm_wfd_ie(wdinfo, frame_tail); + break; + case P2P_INVIT_REQ: + wfdielen = build_invitation_req_wfd_ie(wdinfo, frame_tail); + break; + case P2P_INVIT_RESP: + wfdielen = build_invitation_resp_wfd_ie(wdinfo, frame_tail); + break; + case P2P_PROVISION_DISC_REQ: + wfdielen = build_provdisc_req_wfd_ie(wdinfo, frame_tail); + break; + case P2P_PROVISION_DISC_RESP: + wfdielen = build_provdisc_resp_wfd_ie(wdinfo, frame_tail); + break; + case P2P_DEVDISC_REQ: + case P2P_DEVDISC_RESP: + default: + break; + } + + } + } else if (category == RTW_WLAN_CATEGORY_P2P) { + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n" + , cpu_to_be32(*((u32 *)(frame_body + 1))), OUI_Subtype, dialogToken); + #endif + + switch (OUI_Subtype) { + case P2P_NOTICE_OF_ABSENCE: + break; + case P2P_PRESENCE_REQUEST: + break; + case P2P_PRESENCE_RESPONSE: + break; + case P2P_GO_DISC_REQUEST: + break; + default: + break; + } + } else { + DBG_871X("%s, action frame category=%d\n", __func__, category); + } + + xframe->attrib.pktlen += wfdielen; + + return wfdielen; +} +#endif /* CONFIG_WFD */ + +bool rtw_xframe_del_wfd_ie(struct xmit_frame *xframe) +{ +#define DBG_XFRAME_DEL_WFD_IE 0 + + _adapter *adapter = xframe->padapter; + u8 *frame = xframe->buf_addr + TXDESC_OFFSET; + u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 *frame_tail = frame + xframe->attrib.pktlen; + u8 category, action, OUI_Subtype; + u8 *ies = NULL; + uint ies_len_ori = 0; + uint ies_len = 0; + + category = frame_body[0]; + if (category == RTW_WLAN_CATEGORY_PUBLIC) { + action = frame_body[1]; + if (action == ACT_PUBLIC_VENDOR + && _rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE + ) { + OUI_Subtype = frame_body[6]; + + switch (OUI_Subtype) { + case P2P_GO_NEGO_REQ: + case P2P_GO_NEGO_RESP: + case P2P_GO_NEGO_CONF: + case P2P_INVIT_REQ: + case P2P_INVIT_RESP: + case P2P_PROVISION_DISC_REQ: + case P2P_PROVISION_DISC_RESP: + ies = frame_body + 8; + ies_len_ori = frame_tail - (frame_body + 8); + break; + } + } + } + + if (ies && ies_len_ori) { + ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_XFRAME_DEL_WFD_IE ? __func__ : NULL); + xframe->attrib.pktlen -= (ies_len_ori - ies_len); + } + + return ies_len_ori != ies_len; +} + +/* +* rtw_xframe_chk_wfd_ie - +* +*/ +void rtw_xframe_chk_wfd_ie(struct xmit_frame *xframe) +{ + _adapter *adapter = xframe->padapter; + u8 *frame = xframe->buf_addr + TXDESC_OFFSET; + u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr); + u8 *frame_tail = frame + xframe->attrib.pktlen; + + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build = 0; + u8 del = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + del = 1; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + del = build = 1; + + if (del) + rtw_xframe_del_wfd_ie(xframe); + +#ifdef CONFIG_WFD + if (build) + rtw_xframe_build_wfd_ie(xframe); +#endif +} + +u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len) +{ + uint attr_contentlen = 0; + u8 *pattr = NULL; + int w_sz = 0; + u8 ch_cnt = 0; + u8 ch_list[40]; + bool continuous = _FALSE; + + if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) { + int i, j; + u32 num_of_ch; + u8 *pattr_temp = pattr + 3 ; + + attr_contentlen -= 3; + + _rtw_memset(ch_list, 0, 40); + + while (attr_contentlen>0) { + num_of_ch = *(pattr_temp+1); + + for(i=0; i=ch_cnt) + ch_list[ch_cnt++] = *(pattr_temp+2+i); + + } + + pattr_temp += (2+num_of_ch); + attr_contentlen -= (2+num_of_ch); + } + + for (j=0;j>1 == resp >>1) + return req&0x01 ? _TRUE : _FALSE; + else if (req>>1 > resp>>1) + return _TRUE; + else + return _FALSE; +} + +int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx) +{ + int is_p2p_frame = (-1); + unsigned char *frame_body; + u8 category, action, OUI_Subtype, dialogToken=0; + u8 *p2p_ie = NULL; + uint p2p_ielen = 0; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + int status = -1; + u8 ch_list_buf[128] = {'\0'}; + int op_ch = -1; + int listen_ch = -1; + u8 intent = 0; + + frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); + category = frame_body[0]; + //just for check + if(category == RTW_WLAN_CATEGORY_PUBLIC) + { + action = frame_body[1]; + if (action == ACT_PUBLIC_VENDOR + && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE + ) + { + OUI_Subtype = frame_body[6]; + dialogToken = frame_body[7]; + is_p2p_frame = OUI_Subtype; + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_PUBLIC: ACT_PUBLIC_VENDOR, OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n", + cpu_to_be32( *( ( u32* ) ( frame_body + 2 ) ) ), OUI_Subtype, dialogToken); + #endif + + p2p_ie = rtw_get_p2p_ie( + (u8 *)buf+sizeof(struct rtw_ieee80211_hdr_3addr)+_PUBLIC_ACTION_IE_OFFSET_, + len-sizeof(struct rtw_ieee80211_hdr_3addr)-_PUBLIC_ACTION_IE_OFFSET_, + NULL, &p2p_ielen); + + switch( OUI_Subtype )//OUI Subtype + { + u8 *cont; + uint cont_len; + case P2P_GO_NEGO_REQ: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + + if (tx) { + #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2 + if(pwdev_priv->provdisc_req_issued == _FALSE) + rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len); + #endif //CONFIG_DRV_ISSUE_PROV_REQ + + //pwdev_priv->provdisc_req_issued = _FALSE; + + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + rtw_cfg80211_adjust_p2pie_channel(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, NULL, &cont_len))) + listen_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + + if (nego_info->token != dialogToken) + rtw_wdev_nego_info_init(nego_info); + + _rtw_memcpy(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + nego_info->active = tx ? 1 : 0; + nego_info->token = dialogToken; + nego_info->req_op_ch = op_ch; + nego_info->req_listen_ch = listen_ch; + nego_info->req_intent = intent; + nego_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, listen_ch:%d, op_ch:%d, ch_list:%s, full_ch_in_p2p_handshake:%d\n" , + (tx == _TRUE)?"Tx":"Rx" , dialogToken , (intent>>1) , intent&0x1 ? "+" : "-" , listen_ch , op_ch , ch_list_buf , padapter->registrypriv.full_ch_in_p2p_handshake); + + if (!tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + + break; + } + case P2P_GO_NEGO_RESP: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + + if (tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + rtw_cfg80211_adjust_p2pie_channel(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len))) + intent = *cont; + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 0 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->rsp_op_ch= op_ch; + nego_info->rsp_intent = intent; + nego_info->state = 1; + if (status != 0) + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf); + + if (!tx) { + pwdev_priv->provdisc_req_issued = _FALSE; + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter, _FW_LINKED) + && rtw_chk_p2pie_ch_list_with_buddy(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + #endif + } + + break; + } + case P2P_GO_NEGO_CONF: + { + struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info; + bool is_go = _FALSE; + + if (tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter, _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + status = *cont; + + if (nego_info->token == dialogToken && nego_info->state == 1 + && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + nego_info->status = (status==-1) ? 0xff : status; + nego_info->conf_op_ch = (op_ch==-1) ? 0 : op_ch; + nego_info->state = 2; + + if (status == 0) { + if (rtw_p2p_nego_intent_compare(nego_info->req_intent, nego_info->rsp_intent) ^ !tx) + is_go = _TRUE; + } + + nego_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { + } + + break; + } + case P2P_INVIT_REQ: + { + struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; + int flags = -1; + + if (tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter, _FW_LINKED) + && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, NULL, &cont_len))) + flags = *cont; + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + + if (invit_info->token != dialogToken) + rtw_wdev_invit_info_init(invit_info); + + _rtw_memcpy(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN); + invit_info->active = tx ? 1 : 0; + invit_info->token = dialogToken; + invit_info->flags = (flags==-1) ? 0x0 : flags; + invit_info->req_op_ch= op_ch; + invit_info->state = 0; + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf); + + if (!tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) { + if (op_ch != -1 && rtw_chk_p2pie_op_ch_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" op_ch:%u has no intersect with buddy\n", FUNC_ADPT_ARG(padapter), op_ch); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } else if (rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) { + DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter)); + rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0); + } + } + #endif + } + + break; + } + case P2P_INVIT_RESP: + { + struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info; + + if (tx) { + #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT) + if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) + rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)); + #endif + } + + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len))) + { +#ifdef CONFIG_P2P_INVITE_IOT + if(tx && *cont==7) + { + DBG_871X("TX_P2P_INVITE_RESP, status is no common channel, change to unknown group\n"); + *cont = 8; //unknow group status + } +#endif //CONFIG_P2P_INVITE_IOT + status = *cont; + } + if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len))) + op_ch = *(cont+4); + + if (invit_info->token == dialogToken && invit_info->state == 0 + && _rtw_memcmp(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE + ) { + invit_info->status = (status==-1) ? 0xff : status; + invit_info->rsp_op_ch= op_ch; + invit_info->state = 1; + invit_info->token = 0; /* init */ + } + + dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128); + DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n", + (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf); + + if (!tx) { + } + + break; + } + case P2P_DEVDISC_REQ: + DBG_871X("RTW_%s:P2P_DEVDISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + break; + case P2P_DEVDISC_RESP: + cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len); + DBG_871X("RTW_%s:P2P_DEVDISC_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1); + break; + case P2P_PROVISION_DISC_REQ: + { + size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr); + u8 *p2p_ie; + uint p2p_ielen = 0; + uint contentlen = 0; + + DBG_871X("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + + //if(tx) + { + pwdev_priv->provdisc_req_issued = _FALSE; + + if( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen))) + { + + if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, NULL, &contentlen)) + { + pwdev_priv->provdisc_req_issued = _FALSE;//case: p2p_client join p2p GO + } + else + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("provdisc_req_issued is _TRUE\n"); + #endif //CONFIG_DEBUG_CFG80211 + pwdev_priv->provdisc_req_issued = _TRUE;//case: p2p_devices connection before Nego req. + } + + } + } + } + break; + case P2P_PROVISION_DISC_RESP: + DBG_871X("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken); + break; + default: + DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", OUI_Subtype, dialogToken); + break; + } + + } + + } + else if(category == RTW_WLAN_CATEGORY_P2P) + { + OUI_Subtype = frame_body[5]; + dialogToken = frame_body[6]; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n", + cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken); + #endif + + is_p2p_frame = OUI_Subtype; + + switch(OUI_Subtype) + { + case P2P_NOTICE_OF_ABSENCE: + DBG_871X("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_PRESENCE_REQUEST: + DBG_871X("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_PRESENCE_RESPONSE: + DBG_871X("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + case P2P_GO_DISC_REQUEST: + DBG_871X("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken); + break; + default: + DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", OUI_Subtype, dialogToken); + break; + } + + } + else + { + DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category); + } + + return is_p2p_frame; +} + +void rtw_init_cfg80211_wifidirect_info( _adapter* padapter) +{ + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info) ); + + _init_timer( &pcfg80211_wdinfo->remain_on_ch_timer, padapter->pnetdev, ro_ch_timer_process, padapter ); +} +#endif //CONFIG_IOCTL_CFG80211 + +void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType) +{ + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + +_func_enter_; + + switch(intCmdType) + { + case P2P_FIND_PHASE_WK: + { + find_phase_handler( padapter ); + break; + } + case P2P_RESTORE_STATE_WK: + { + restore_p2p_state_handler( padapter ); + break; + } + case P2P_PRE_TX_PROVDISC_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_provdisc_handler( padapter ); + } +#else + pre_tx_provdisc_handler( padapter ); +#endif + break; + } + case P2P_PRE_TX_INVITEREQ_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_invitereq_handler( padapter ); + } +#else + pre_tx_invitereq_handler( padapter ); +#endif + break; + } + case P2P_PRE_TX_NEGOREQ_PROCESS_WK: + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) ) + { + p2p_concurrent_handler( padapter ); + } + else + { + pre_tx_negoreq_handler( padapter ); + } +#else + pre_tx_negoreq_handler( padapter ); +#endif + break; + } +#ifdef CONFIG_P2P +#ifdef CONFIG_CONCURRENT_MODE + case P2P_AP_P2P_CH_SWITCH_PROCESS_WK: + { + p2p_concurrent_handler( padapter ); + break; + } +#endif +#endif +#ifdef CONFIG_IOCTL_CFG80211 + case P2P_RO_CH_WK: + { + ro_ch_handler( padapter ); + break; + } +#endif //CONFIG_IOCTL_CFG80211 + + } + +_func_exit_; +} + +int process_p2p_cross_connect_ie(PADAPTER padapter, u8 *IEs, u32 IELength) +{ + int ret = _TRUE; + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + u8 p2p_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2 + u32 attr_contentlen = 0; + + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + +_func_enter_; + + if(IELength <= _BEACON_IE_OFFSET_) + return ret; + + ies = IEs + _BEACON_IE_OFFSET_; + ies_len = IELength - _BEACON_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen); + + while(p2p_ie) + { + // Get P2P Manageability IE. + if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_MANAGEABILITY, p2p_attr, &attr_contentlen)) + { + if ((p2p_attr[0]&(BIT(0)|BIT(1))) == 0x01) { + ret = _FALSE; + } + break; + } + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + } + +_func_exit_; + return ret; +} + +#ifdef CONFIG_P2P_PS +void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength) +{ + u8 * ies; + u32 ies_len; + u8 * p2p_ie; + u32 p2p_ielen = 0; + u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2 + u32 attr_contentlen = 0; + + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 find_p2p = _FALSE, find_p2p_ps = _FALSE; + u8 noa_offset, noa_num, noa_index; + +_func_enter_; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + return; + } +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type != IFACE_PORT0) + return; +#endif + if(IELength <= _BEACON_IE_OFFSET_) + return; + + ies = IEs + _BEACON_IE_OFFSET_; + ies_len = IELength - _BEACON_IE_OFFSET_; + + p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen); + + while(p2p_ie) + { + find_p2p = _TRUE; + // Get Notice of Absence IE. + if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) + { + find_p2p_ps = _TRUE; + noa_index = noa_attr[0]; + + if( (pwdinfo->p2p_ps_mode == P2P_PS_NONE) || + (noa_index != pwdinfo->noa_index) )// if index change, driver should reconfigure related setting. + { + pwdinfo->noa_index = noa_index; + pwdinfo->opp_ps = noa_attr[1] >> 7; + pwdinfo->ctwindow = noa_attr[1] & 0x7F; + + noa_offset = 2; + noa_num = 0; + // NoA length should be n*(13) + 2 + if(attr_contentlen > 2) + { + while(noa_offset < attr_contentlen) + { + //_rtw_memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); + pwdinfo->noa_count[noa_num] = noa_attr[noa_offset]; + noa_offset += 1; + + _rtw_memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + _rtw_memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + _rtw_memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4); + noa_offset += 4; + + noa_num++; + } + } + pwdinfo->noa_num = noa_num; + + if( pwdinfo->opp_ps == 1 ) + { + pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + // driver should wait LPS for entering CTWindow + if(adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE) + { + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); + } + } + else if( pwdinfo->noa_num > 0 ) + { + pwdinfo->p2p_ps_mode = P2P_PS_NOA; + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1); + } + else if( pwdinfo->p2p_ps_mode > P2P_PS_NONE) + { + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); + } + } + + break; // find target, just break. + } + + //Get the next P2P IE + p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen); + + } + + if(find_p2p == _TRUE) + { + if( (pwdinfo->p2p_ps_mode > P2P_PS_NONE) && (find_p2p_ps == _FALSE) ) + { + p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1); + } + } + +_func_exit_; +} + +void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + +_func_enter_; + + // Pre action for p2p state + switch(p2p_ps_state) + { + case P2P_PS_DISABLE: + pwdinfo->p2p_ps_state = p2p_ps_state; + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + + pwdinfo->noa_index = 0; + pwdinfo->ctwindow = 0; + pwdinfo->opp_ps = 0; + pwdinfo->noa_num = 0; + pwdinfo->p2p_ps_mode = P2P_PS_NONE; + if(pwrpriv->bFwCurrentInPSMode == _TRUE) + { + if(pwrpriv->smart_ps == 0) + { + pwrpriv->smart_ps = 2; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + } + } + break; + case P2P_PS_ENABLE: + if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { + pwdinfo->p2p_ps_state = p2p_ps_state; + + if( pwdinfo->ctwindow > 0 ) + { + if(pwrpriv->smart_ps != 0) + { + pwrpriv->smart_ps = 0; + DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__); + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode))); + } + } + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + } + break; + case P2P_PS_SCAN: + case P2P_PS_SCAN_DONE: + case P2P_PS_ALLSTASLEEP: + if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) { + pwdinfo->p2p_ps_state = p2p_ps_state; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state)); + } + break; + default: + break; + } + +_func_exit_; +} + +u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue) +{ + struct cmd_obj *ph2c; + struct drvextra_cmd_parm *pdrvextra_cmd_parm; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 res = _SUCCESS; + +_func_enter_; + + if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) +#ifdef CONFIG_CONCURRENT_MODE + || (padapter->iface_type != IFACE_PORT0) +#endif + ) + { + return res; + } + + if(enqueue) + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + res= _FAIL; + goto exit; + } + + pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID; + pdrvextra_cmd_parm->type = p2p_ps_state; + pdrvextra_cmd_parm->size = 0; + pdrvextra_cmd_parm->pbuf = NULL; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); + + res = rtw_enqueue_cmd(pcmdpriv, ph2c); + } + else + { + p2p_ps_wk_hdl(padapter, p2p_ps_state); + } + +exit: + +_func_exit_; + + return res; + +} +#endif // CONFIG_P2P_PS + +static void reset_ch_sitesurvey_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + // Reset the operation channel information + pwdinfo->rx_invitereq_info.operation_ch[0] = 0; +#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[1] = 0; + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; +#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; +} + +static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + // Reset the operation channel information + pwdinfo->p2p_info.operation_ch[0] = 0; +#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[1] = 0; + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; +#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 0; +} + +static void restore_p2p_state_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + p2p_protocol_wk_cmd( adapter, P2P_RESTORE_STATE_WK ); +} + +static void pre_tx_scan_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *) FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + _irqL irqL; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 _status = 0; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) + { + if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) // the provision discovery request frame is trigger to send or not + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK ); + //issue_probereq_p2p(adapter, NULL); + //_set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + } + } + else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) + { + if ( _TRUE == pwdinfo->nego_req_info.benable ) + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK ); + } + } + else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) ) + { + if ( _TRUE == pwdinfo->invitereq_info.benable ) + { + p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK ); + } + } + else + { + DBG_8192C( "[%s] p2p_state is %d, ignore!!\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + } + + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +static void find_phase_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + + adapter->wdinfo.find_phase_state_exchange_cnt++; + + p2p_protocol_wk_cmd( adapter, P2P_FIND_PHASE_WK ); +} + +#ifdef CONFIG_CONCURRENT_MODE +void ap_p2p_switch_timer_process (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + struct wifidirect_info *pwdinfo = &adapter->wdinfo; +#ifdef CONFIG_IOCTL_CFG80211 + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); +#endif + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; + +#ifdef CONFIG_IOCTL_CFG80211 + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); +#endif + + p2p_protocol_wk_cmd( adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK ); +} +#endif + +void reset_global_wifidirect_info( _adapter* padapter ) +{ + struct wifidirect_info *pwdinfo; + + pwdinfo = &padapter->wdinfo; + pwdinfo->persistent_supported = 0; + pwdinfo->session_available = _TRUE; + rtw_tdls_wfd_enable(padapter, 0); + pwdinfo->wfd_tdls_weaksec = _TRUE; +} + +#ifdef CONFIG_WFD +int rtw_init_wifi_display_info(_adapter* padapter) +{ + int res = _SUCCESS; + struct wifi_display_info *pwfd_info = &padapter->wfd_info; + + // Used in P2P and TDLS + pwfd_info->init_rtsp_ctrlport = 554; +#ifdef CONFIG_IOCTL_CFG80211 + pwfd_info->rtsp_ctrlport = 0; +#else + pwfd_info->rtsp_ctrlport = pwfd_info->init_rtsp_ctrlport; /* set non-zero value for legacy wfd */ +#endif + pwfd_info->tdls_rtsp_ctrlport = 0; + pwfd_info->peer_rtsp_ctrlport = 0; // Reset to 0 + pwfd_info->wfd_enable = _FALSE; + pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK; + pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY; + + // Used in P2P + pwfd_info->peer_session_avail = _TRUE; + pwfd_info->wfd_pc = _FALSE; + + // Used in TDLS + _rtw_memset( pwfd_info->ip_address, 0x00, 4 ); + _rtw_memset( pwfd_info->peer_ip_address, 0x00, 4 ); + return res; + +} + +inline void rtw_wfd_enable(_adapter *adapter, bool on) +{ + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + if (on) { + wfdinfo->rtsp_ctrlport = wfdinfo->init_rtsp_ctrlport; + wfdinfo->wfd_enable = _TRUE; + + } else { + wfdinfo->wfd_enable = _FALSE; + wfdinfo->rtsp_ctrlport = 0; + } +} + +inline void rtw_wfd_set_ctrl_port(_adapter *adapter, u16 port) +{ + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + wfdinfo->init_rtsp_ctrlport = port; + if (wfdinfo->wfd_enable == _TRUE) + wfdinfo->rtsp_ctrlport = port; + if (adapter->wdinfo.wfd_tdls_enable == 1) + wfdinfo->tdls_rtsp_ctrlport = port; +} + +inline void rtw_tdls_wfd_enable(_adapter *adapter, bool on) +{ + struct wifi_display_info *wfdinfo = &adapter->wfd_info; + + if (on) { + wfdinfo->tdls_rtsp_ctrlport = wfdinfo->init_rtsp_ctrlport; + adapter->wdinfo.wfd_tdls_enable = 1; + + } else { + adapter->wdinfo.wfd_tdls_enable = 0; + wfdinfo->tdls_rtsp_ctrlport = 0; + } +} + +u32 rtw_append_beacon_wfd_ie(_adapter *adapter, u8 *pbuf) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build_ie_by_self = 0; + u32 len = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto exit; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + build_ie_by_self = 1; + + if (build_ie_by_self) + len = build_beacon_wfd_ie(wdinfo, pbuf); +#ifdef CONFIG_IOCTL_CFG80211 + else if (mlme->wfd_beacon_ie && mlme->wfd_beacon_ie_len > 0) { + len = mlme->wfd_beacon_ie_len; + _rtw_memcpy(pbuf, mlme->wfd_beacon_ie, len); + } +#endif + +exit: + return len; +} + +u32 rtw_append_probe_req_wfd_ie(_adapter *adapter, u8 *pbuf) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build_ie_by_self = 0; + u32 len = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto exit; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + build_ie_by_self = 1; + + if (build_ie_by_self) + len = build_probe_req_wfd_ie(wdinfo, pbuf); +#ifdef CONFIG_IOCTL_CFG80211 + else if (mlme->wfd_probe_req_ie && mlme->wfd_probe_req_ie_len > 0) { + len = mlme->wfd_probe_req_ie_len; + _rtw_memcpy(pbuf, mlme->wfd_probe_req_ie, len); + } +#endif + +exit: + return len; +} + +u32 rtw_append_probe_resp_wfd_ie(_adapter *adapter, u8 *pbuf) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build_ie_by_self = 0; + u32 len = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto exit; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + build_ie_by_self = 1; + + if (build_ie_by_self) + len = build_probe_resp_wfd_ie(wdinfo, pbuf, 0); +#ifdef CONFIG_IOCTL_CFG80211 + else if (mlme->wfd_probe_resp_ie && mlme->wfd_probe_resp_ie_len > 0) { + len = mlme->wfd_probe_resp_ie_len; + _rtw_memcpy(pbuf, mlme->wfd_probe_resp_ie, len); + } +#endif + +exit: + return len; +} + +u32 rtw_append_assoc_req_wfd_ie(_adapter *adapter, u8 *pbuf) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build_ie_by_self = 0; + u32 len = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto exit; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + build_ie_by_self = 1; + + if (build_ie_by_self) + len = build_assoc_req_wfd_ie(wdinfo, pbuf); +#ifdef CONFIG_IOCTL_CFG80211 + else if (mlme->wfd_assoc_req_ie && mlme->wfd_assoc_req_ie_len > 0) { + len = mlme->wfd_assoc_req_ie_len; + _rtw_memcpy(pbuf, mlme->wfd_assoc_req_ie, len); + } +#endif + +exit: + return len; +} + +u32 rtw_append_assoc_resp_wfd_ie(_adapter *adapter, u8 *pbuf) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + struct mlme_priv *mlme = &adapter->mlmepriv; + u8 build_ie_by_self = 0; + u32 len = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + goto exit; + +#ifdef CONFIG_IOCTL_CFG80211 + if (_TRUE == wdinfo->wfd_info->wfd_enable) +#endif + build_ie_by_self = 1; + + if (build_ie_by_self) + len = build_assoc_resp_wfd_ie(wdinfo, pbuf); +#ifdef CONFIG_IOCTL_CFG80211 + else if (mlme->wfd_assoc_resp_ie && mlme->wfd_assoc_resp_ie_len > 0) { + len = mlme->wfd_assoc_resp_ie_len; + _rtw_memcpy(pbuf, mlme->wfd_assoc_resp_ie, len); + } +#endif + +exit: + return len; +} + +#endif /* CONFIG_WFD */ + +void rtw_init_wifidirect_timers(_adapter* padapter) +{ + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + _init_timer( &pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter ); + _init_timer( &pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter ); + _init_timer( &pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter ); + _init_timer( &pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter ); + _init_timer( &pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter ); +#ifdef CONFIG_CONCURRENT_MODE + _init_timer( &pwdinfo->ap_p2p_switch_timer, padapter->pnetdev, ap_p2p_switch_timer_process, padapter ); +#endif +} + +void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + + /*init device&interface address */ + if (dev_addr) { + _rtw_memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN); + } + if (iface_addr) { + _rtw_memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN); + } +#endif +} + +void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role) +{ + struct wifidirect_info *pwdinfo; +#ifdef CONFIG_WFD + struct wifi_display_info *pwfd_info = &padapter->wfd_info; +#endif +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct wifidirect_info *pbuddy_wdinfo = NULL; + struct mlme_priv *pbuddy_mlmepriv = NULL; + struct mlme_ext_priv *pbuddy_mlmeext = NULL; +#endif + + pwdinfo = &padapter->wdinfo; + + pwdinfo->padapter = padapter; + + // 1, 6, 11 are the social channel defined in the WiFi Direct specification. + pwdinfo->social_chan[0] = 1; + pwdinfo->social_chan[1] = 6; + pwdinfo->social_chan[2] = 11; + pwdinfo->social_chan[3] = 0; // channel 0 for scanning ending in site survey function. + +#ifdef CONFIG_CONCURRENT_MODE + if (pbuddy_adapter) { + pbuddy_wdinfo = &pbuddy_adapter->wdinfo; + pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + } + + if ( ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) && + ( ( pbuddy_mlmeext->cur_channel == 1) || ( pbuddy_mlmeext->cur_channel == 6 ) || ( pbuddy_mlmeext->cur_channel == 11 ) ) + ) + { + // Use the AP's channel as the listen channel + // This will avoid the channel switch between AP's channel and listen channel. + pwdinfo->listen_channel = pbuddy_mlmeext->cur_channel; + } + else +#endif //CONFIG_CONCURRENT_MODE + { + // Use the channel 11 as the listen channel + pwdinfo->listen_channel = 11; + } + + if (role == P2P_ROLE_DEVICE) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + #ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE); + } + else + #endif + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + } + pwdinfo->intent = 1; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN); + } + else if (role == P2P_ROLE_CLIENT) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 1; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + } + else if (role == P2P_ROLE_GO) + { + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 15; + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK); + } + +// Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) + pwdinfo->support_rate[0] = 0x8c; // 6(B) + pwdinfo->support_rate[1] = 0x92; // 9(B) + pwdinfo->support_rate[2] = 0x18; // 12 + pwdinfo->support_rate[3] = 0x24; // 18 + pwdinfo->support_rate[4] = 0x30; // 24 + pwdinfo->support_rate[5] = 0x48; // 36 + pwdinfo->support_rate[6] = 0x60; // 48 + pwdinfo->support_rate[7] = 0x6c; // 54 + + _rtw_memcpy( ( void* ) pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7 ); + + _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN ); + pwdinfo->device_name_len = 0; + + _rtw_memset( &pwdinfo->invitereq_info, 0x00, sizeof( struct tx_invite_req_info ) ); + pwdinfo->invitereq_info.token = 3; // Token used for P2P invitation request frame. + + _rtw_memset( &pwdinfo->inviteresp_info, 0x00, sizeof( struct tx_invite_resp_info ) ); + pwdinfo->inviteresp_info.token = 0; + + pwdinfo->profileindex = 0; + _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM ); + + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + + pwdinfo->listen_dwell = ( u8 ) (( rtw_get_current_time() % 3 ) + 1); + //DBG_8192C( "[%s] listen_dwell time is %d00ms\n", __FUNCTION__, pwdinfo->listen_dwell ); + + _rtw_memset( &pwdinfo->tx_prov_disc_info, 0x00, sizeof( struct tx_provdisc_req_info ) ); + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE; + + _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) ); + + pwdinfo->device_password_id_for_nego = WPS_DPID_PBC; + pwdinfo->negotiation_dialog_token = 1; + + _rtw_memset( pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN ); + pwdinfo->nego_ssidlen = 0; + + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; +#ifdef CONFIG_WFD + pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC; + pwdinfo->wfd_info = pwfd_info; +#else + pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD; +#endif //CONFIG_WFD + pwdinfo->channel_list_attr_len = 0; + _rtw_memset( pwdinfo->channel_list_attr, 0x00, 100 ); + + _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4 ); + _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3 ); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->ext_listen_interval = 1000; //The interval to be available with legacy AP during p2p0-find/scan + pwdinfo->ext_listen_period = 3000; //The time period to be available for P2P during nego +#else //!CONFIG_IOCTL_CFG80211 + //pwdinfo->ext_listen_interval = 3000; + //pwdinfo->ext_listen_period = 400; + pwdinfo->ext_listen_interval = 1000; + pwdinfo->ext_listen_period = 1000; +#endif //!CONFIG_IOCTL_CFG80211 +#endif + +// Commented by Kurt 20130319 +// For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + + pwdinfo->wfd_tdls_enable = 0; + _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN ); + _rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN ); + + pwdinfo->rx_invitereq_info.operation_ch[0] = 0; + pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.operation_ch[2] = 0; + pwdinfo->rx_invitereq_info.operation_ch[3] = 0; + pwdinfo->rx_invitereq_info.operation_ch[4] = 0; +#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->rx_invitereq_info.scan_op_ch_only = 0; + pwdinfo->p2p_info.operation_ch[0] = 0; + pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function +#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.operation_ch[2] = 0; + pwdinfo->p2p_info.operation_ch[3] = 0; + pwdinfo->p2p_info.operation_ch[4] = 0; +#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH + pwdinfo->p2p_info.scan_op_ch_only = 0; +} + +#ifdef CONFIG_DBG_P2P + +/** + * rtw_p2p_role_txt - Get the p2p role name as a text string + * @role: P2P role + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_role_txt(enum P2P_ROLE role) +{ + switch (role) { + case P2P_ROLE_DISABLE: + return "P2P_ROLE_DISABLE"; + case P2P_ROLE_DEVICE: + return "P2P_ROLE_DEVICE"; + case P2P_ROLE_CLIENT: + return "P2P_ROLE_CLIENT"; + case P2P_ROLE_GO: + return "P2P_ROLE_GO"; + default: + return "UNKNOWN"; + } +} + +/** + * rtw_p2p_state_txt - Get the p2p state name as a text string + * @state: P2P state + * Returns: The state name as a printable text string + */ +const char * rtw_p2p_state_txt(enum P2P_STATE state) +{ + switch (state) { + case P2P_STATE_NONE: + return "P2P_STATE_NONE"; + case P2P_STATE_IDLE: + return "P2P_STATE_IDLE"; + case P2P_STATE_LISTEN: + return "P2P_STATE_LISTEN"; + case P2P_STATE_SCAN: + return "P2P_STATE_SCAN"; + case P2P_STATE_FIND_PHASE_LISTEN: + return "P2P_STATE_FIND_PHASE_LISTEN"; + case P2P_STATE_FIND_PHASE_SEARCH: + return "P2P_STATE_FIND_PHASE_SEARCH"; + case P2P_STATE_TX_PROVISION_DIS_REQ: + return "P2P_STATE_TX_PROVISION_DIS_REQ"; + case P2P_STATE_RX_PROVISION_DIS_RSP: + return "P2P_STATE_RX_PROVISION_DIS_RSP"; + case P2P_STATE_RX_PROVISION_DIS_REQ: + return "P2P_STATE_RX_PROVISION_DIS_REQ"; + case P2P_STATE_GONEGO_ING: + return "P2P_STATE_GONEGO_ING"; + case P2P_STATE_GONEGO_OK: + return "P2P_STATE_GONEGO_OK"; + case P2P_STATE_GONEGO_FAIL: + return "P2P_STATE_GONEGO_FAIL"; + case P2P_STATE_RECV_INVITE_REQ_MATCH: + return "P2P_STATE_RECV_INVITE_REQ_MATCH"; + case P2P_STATE_PROVISIONING_ING: + return "P2P_STATE_PROVISIONING_ING"; + case P2P_STATE_PROVISIONING_DONE: + return "P2P_STATE_PROVISIONING_DONE"; + case P2P_STATE_TX_INVITE_REQ: + return "P2P_STATE_TX_INVITE_REQ"; + case P2P_STATE_RX_INVITE_RESP_OK: + return "P2P_STATE_RX_INVITE_RESP_OK"; + case P2P_STATE_RECV_INVITE_REQ_DISMATCH: + return "P2P_STATE_RECV_INVITE_REQ_DISMATCH"; + case P2P_STATE_RECV_INVITE_REQ_GO: + return "P2P_STATE_RECV_INVITE_REQ_GO"; + case P2P_STATE_RECV_INVITE_REQ_JOIN: + return "P2P_STATE_RECV_INVITE_REQ_JOIN"; + case P2P_STATE_RX_INVITE_RESP_FAIL: + return "P2P_STATE_RX_INVITE_RESP_FAIL"; + case P2P_STATE_RX_INFOR_NOREADY: + return "P2P_STATE_RX_INFOR_NOREADY"; + case P2P_STATE_TX_INFOR_NOREADY: + return "P2P_STATE_TX_INFOR_NOREADY"; + default: + return "UNKNOWN"; + } +} + +void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line) +{ + if(!_rtw_p2p_chk_state(wdinfo, state)) { + enum P2P_STATE old_state = _rtw_p2p_state(wdinfo); + _rtw_p2p_set_state(wdinfo, state); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line + , rtw_p2p_state_txt(_rtw_p2p_state(wdinfo)) + ); + } +} +void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line) +{ + if(_rtw_p2p_pre_state(wdinfo) != state) { + enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo); + _rtw_p2p_set_pre_state(wdinfo, state); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line + , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line + , rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo)) + ); + } +} +#if 0 +void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line) +{ + if(wdinfo->pre_p2p_state != -1) { + DBG_871X("[CONFIG_DBG_P2P]%s:%d restore from %s to %s\n", caller, line + , p2p_state_str[wdinfo->p2p_state], p2p_state_str[wdinfo->pre_p2p_state] + ); + _rtw_p2p_restore_state(wdinfo); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d restore no pre state, cur state %s\n", caller, line + , p2p_state_str[wdinfo->p2p_state] + ); + } +} +#endif +void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line) +{ + if(wdinfo->role != role) { + enum P2P_ROLE old_role = wdinfo->role; + _rtw_p2p_set_role(wdinfo, role); + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line + , rtw_p2p_role_txt(old_role), rtw_p2p_role_txt(wdinfo->role) + ); + } else { + DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line + , rtw_p2p_role_txt(wdinfo->role) + ); + } +} +#endif //CONFIG_DBG_P2P + + +int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role) +{ + int ret = _SUCCESS; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO) + { + u8 channel, ch_offset; + u16 bwmode; + +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo; + // Commented by Albert 2011/12/30 + // The driver just supports 1 P2P group operation. + // So, this function will do nothing if the buddy adapter had enabled the P2P function. + if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) + { + // The buddy adapter had enabled the P2P function. + return ret; + } +#endif //CONFIG_CONCURRENT_MODE + + //leave IPS/Autosuspend + if (_FAIL == rtw_pwr_wakeup(padapter)) { + ret = _FAIL; + goto exit; + } + + // Added by Albert 2011/03/22 + // In the P2P mode, the driver should not support the b mode. + // So, the Tx packet shouldn't use the CCK rate + update_tx_basic_rate(padapter, WIRELESS_11AGN); + + //Enable P2P function + init_wifidirect_info(padapter, role); + + rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_TRUE); + #ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + rtw_hal_set_odm_var(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, _TRUE); + #endif + + } + else if (role == P2P_ROLE_DISABLE) + { +#ifdef CONFIG_INTEL_WIDI + if( padapter->mlmepriv.p2p_reject_disable == _TRUE ) + return ret; +#endif //CONFIG_INTEL_WIDI + +#ifdef CONFIG_IOCTL_CFG80211 + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + adapter_wdev_data(padapter)->p2p_enabled = _FALSE; +#endif //CONFIG_IOCTL_CFG80211 + + + //Disable P2P function + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey); + _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey2); + reset_ch_sitesurvey_timer_process( padapter ); + reset_ch_sitesurvey_timer_process2( padapter ); + #ifdef CONFIG_CONCURRENT_MODE + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer); + #endif + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_NONE); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE); + _rtw_memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info)); + + /* Remove profiles in wifidirect_info structure. */ + _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM ); + pwdinfo->profileindex = 0; + } + + rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_FALSE); + #ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + rtw_hal_set_odm_var(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, _FALSE); + #endif + + if (_FAIL == rtw_pwr_wakeup(padapter)) { + ret = _FAIL; + goto exit; + } + + //Restore to initial setting. + update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); + +#ifdef CONFIG_INTEL_WIDI + rtw_reset_widi_info(padapter); +#endif //CONFIG_INTEL_WIDI + + //For WiDi purpose. +#ifdef CONFIG_IOCTL_CFG80211 + pwdinfo->driver_interface = DRIVER_CFG80211; +#else + pwdinfo->driver_interface = DRIVER_WEXT; +#endif //CONFIG_IOCTL_CFG80211 + + } + +exit: + return ret; +} + +#endif //CONFIG_P2P + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_pwrctrl.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_pwrctrl.c new file mode 100644 index 00000000..2f0b7000 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_pwrctrl.c @@ -0,0 +1,2699 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_PWRCTRL_C_ + +#include +#include +#include + +int rtw_fw_ps_state(PADAPTER padapter) +{ + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + int ret=_FAIL, dont_care=0; + u16 fw_ps_state=0; + u32 start_time; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct registry_priv *registry_par = &padapter->registrypriv; + + if(registry_par->check_fw_ps != 1) + return _SUCCESS; + + _enter_pwrlock(&pwrpriv->check_32k_lock); + + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s: bSurpriseRemoved=%s , hw_init_completed=%d, bDriverStopped=%s\n", __func__ + , rtw_is_surprise_removed(padapter)?"True":"False" + , rtw_get_hw_init_completed(padapter) + , rtw_is_drv_stopped(padapter)?"True":"False"); + goto exit_fw_ps_state; + } + rtw_hal_set_hwreg(padapter, HW_VAR_SET_REQ_FW_PS, (u8 *)&dont_care); + { + //4. if 0x88[7]=1, driver set cmd to leave LPS/IPS. + //Else, hw will keep in active mode. + //debug info: + //0x88[7] = 32kpermission, + //0x88[6:0] = current_ps_state + //0x89[7:0] = last_rpwm + + rtw_hal_get_hwreg(padapter, HW_VAR_FW_PS_STATE, (u8 *)&fw_ps_state); + + if((fw_ps_state & 0x80) == 0) + ret=_SUCCESS; + else + { + pdbgpriv->dbg_poll_fail_cnt++; + DBG_871X("%s: fw_ps_state=%04x \n", __FUNCTION__, fw_ps_state); + } + } + + +exit_fw_ps_state: + _exit_pwrlock(&pwrpriv->check_32k_lock); + return ret; +} + +#ifdef CONFIG_IPS +void _ips_enter(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + pwrpriv->bips_processing = _TRUE; + + // syn ips_mode with request + pwrpriv->ips_mode = pwrpriv->ips_mode_req; + + pwrpriv->ips_enter_cnts++; + DBG_871X("==>ips_enter cnts:%d\n",pwrpriv->ips_enter_cnts); + + if(rf_off == pwrpriv->change_rfpwrstate ) + { + pwrpriv->bpower_saving = _TRUE; + DBG_871X_LEVEL(_drv_always_, "nolinked power save enter\n"); + + if(pwrpriv->ips_mode == IPS_LEVEL_2) + pwrpriv->bkeepfwalive = _TRUE; + + rtw_ips_pwr_down(padapter); + pwrpriv->rf_pwrstate = rf_off; + } + pwrpriv->bips_processing = _FALSE; + +} + +void ips_enter(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req); +#endif // CONFIG_BT_COEXIST + + _enter_pwrlock(&pwrpriv->lock); + _ips_enter(padapter); + _exit_pwrlock(&pwrpriv->lock); +} + +int _ips_leave(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int result = _SUCCESS; + + if((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing)) + { + pwrpriv->bips_processing = _TRUE; + pwrpriv->change_rfpwrstate = rf_on; + pwrpriv->ips_leave_cnts++; + DBG_871X("==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts); + + if ((result = rtw_ips_pwr_up(padapter)) == _SUCCESS) { + pwrpriv->rf_pwrstate = rf_on; + } + DBG_871X_LEVEL(_drv_always_, "nolinked power save leave\n"); + + DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtw_read32(padapter,0x4c)); + pwrpriv->bips_processing = _FALSE; + + pwrpriv->bkeepfwalive = _FALSE; + pwrpriv->bpower_saving = _FALSE; + } + + return result; +} + +int ips_leave(_adapter * padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + int ret; + + if(!is_primary_adapter(padapter)) + return _SUCCESS; + + _enter_pwrlock(&pwrpriv->lock); + ret = _ips_leave(padapter); +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("ips leave doesn't leave 32k\n"); + pdbgpriv->dbg_leave_ips_fail_cnt++; + } +#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); +#endif // CONFIG_BT_COEXIST + + return ret; +} +#endif /* CONFIG_IPS */ + +#ifdef CONFIG_AUTOSUSPEND +extern void autosuspend_enter(_adapter* padapter); +extern int autoresume_enter(_adapter* padapter); +#endif + +#ifdef SUPPORT_HW_RFOFF_DETECTED +int rtw_hw_suspend(_adapter *padapter ); +int rtw_hw_resume(_adapter *padapter); +#endif + +bool rtw_pwr_unassociated_idle(_adapter *adapter) +{ + _adapter *buddy = adapter->pbuddy_adapter; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct xmit_priv *pxmit_priv = &adapter->xmitpriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(adapter->wdinfo); +#ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &adapter->cfg80211_wdinfo; +#endif +#endif + + bool ret = _FALSE; + + if (adapter_to_pwrctl(adapter)->bpower_saving ==_TRUE ) { + //DBG_871X("%s: already in LPS or IPS mode\n", __func__); + goto exit; + } + + if (adapter_to_pwrctl(adapter)->ips_deny_time >= rtw_get_current_time()) { + //DBG_871X("%s ips_deny_time\n", __func__); + goto exit; + } + + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) + || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(pmlmepriv, WIFI_AP_STATE) + || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + || pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) + #endif + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + || rtw_get_passing_time_ms(pcfg80211_wdinfo->last_ro_ch_time) < 3000 + #endif + ) { + goto exit; + } + + /* consider buddy, if exist */ + if (buddy) { + struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv); + #ifdef CONFIG_P2P + struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo); + #ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *b_pcfg80211_wdinfo = &buddy->cfg80211_wdinfo; + #endif + #endif + + if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) + || check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(b_pmlmepriv, WIFI_AP_STATE) + || check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + || b_pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE) + #endif + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + || rtw_get_passing_time_ms(b_pcfg80211_wdinfo->last_ro_ch_time) < 3000 + #endif + ) { + goto exit; + } + } + +#if (MP_DRIVER == 1) + if (adapter->registrypriv.mp_mode == 1) + goto exit; +#endif + +#ifdef CONFIG_INTEL_PROXIM + if(adapter->proximity.proxim_on==_TRUE){ + return; + } +#endif + + if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF || + pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) { + DBG_871X_LEVEL(_drv_always_, "There are some pkts to transmit\n"); + DBG_871X_LEVEL(_drv_always_, "free_xmitbuf_cnt: %d, free_xmit_extbuf_cnt: %d\n", + pxmit_priv->free_xmitbuf_cnt, pxmit_priv->free_xmit_extbuf_cnt); + goto exit; + } + + ret = _TRUE; + +exit: + return ret; +} + + +/* + * ATTENTION: + * rtw_ps_processor() doesn't handle LPS. + */ +void rtw_ps_processor(_adapter*padapter) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); +#endif //CONFIG_P2P + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +#ifdef SUPPORT_HW_RFOFF_DETECTED + rt_rf_power_state rfpwrstate; +#endif //SUPPORT_HW_RFOFF_DETECTED + u32 ps_deny = 0; + + _enter_pwrlock(&adapter_to_pwrctl(padapter)->lock); + ps_deny = rtw_ps_deny_get(padapter); + _exit_pwrlock(&adapter_to_pwrctl(padapter)->lock); + if (ps_deny != 0) + { + DBG_871X(FUNC_ADPT_FMT ": ps_deny=0x%08X, skip power save!\n", + FUNC_ADPT_ARG(padapter), ps_deny); + goto exit; + } + + if(pwrpriv->bInSuspend == _TRUE){//system suspend or autosuspend + pdbgpriv->dbg_ps_insuspend_cnt++; + DBG_871X("%s, pwrpriv->bInSuspend == _TRUE ignore this process\n",__FUNCTION__); + return; + } + + pwrpriv->ps_processing = _TRUE; + +#ifdef SUPPORT_HW_RFOFF_DETECTED + if(pwrpriv->bips_processing == _TRUE) + goto exit; + + //DBG_871X("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca)); + if(pwrpriv->bHWPwrPindetect) + { + #ifdef CONFIG_AUTOSUSPEND + if(padapter->registrypriv.usbss_enable) + { + if(pwrpriv->rf_pwrstate == rf_on) + { + if(padapter->net_closed == _TRUE) + pwrpriv->ps_flag = _TRUE; + + rfpwrstate = RfOnOffDetect(padapter); + DBG_871X("@@@@- #1 %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off"); + if(rfpwrstate!= pwrpriv->rf_pwrstate) + { + if(rfpwrstate == rf_off) + { + pwrpriv->change_rfpwrstate = rf_off; + + pwrpriv->bkeepfwalive = _TRUE; + pwrpriv->brfoffbyhw = _TRUE; + + autosuspend_enter(padapter); + } + } + } + } + else + #endif //CONFIG_AUTOSUSPEND + { + rfpwrstate = RfOnOffDetect(padapter); + DBG_871X("@@@@- #2 %s==> rfstate:%s \n",__FUNCTION__,(rfpwrstate==rf_on)?"rf_on":"rf_off"); + + if(rfpwrstate!= pwrpriv->rf_pwrstate) + { + if(rfpwrstate == rf_off) + { + pwrpriv->change_rfpwrstate = rf_off; + pwrpriv->brfoffbyhw = _TRUE; + rtw_hw_suspend(padapter ); + } + else + { + pwrpriv->change_rfpwrstate = rf_on; + rtw_hw_resume(padapter ); + } + DBG_871X("current rf_pwrstate(%s)\n",(pwrpriv->rf_pwrstate == rf_off)?"rf_off":"rf_on"); + } + } + pwrpriv->pwr_state_check_cnts ++; + } +#endif //SUPPORT_HW_RFOFF_DETECTED + + if (pwrpriv->ips_mode_req == IPS_NONE) + goto exit; + + if (rtw_pwr_unassociated_idle(padapter) == _FALSE) + goto exit; + + if((pwrpriv->rf_pwrstate == rf_on) && ((pwrpriv->pwr_state_check_cnts%4)==0)) + { + DBG_871X("==>%s .fw_state(%x)\n",__FUNCTION__,get_fwstate(pmlmepriv)); + #if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + #else + pwrpriv->change_rfpwrstate = rf_off; + #endif + #ifdef CONFIG_AUTOSUSPEND + if(padapter->registrypriv.usbss_enable) + { + if(pwrpriv->bHWPwrPindetect) + pwrpriv->bkeepfwalive = _TRUE; + + if(padapter->net_closed == _TRUE) + pwrpriv->ps_flag = _TRUE; + + #if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + if (_TRUE==pwrpriv->bInternalAutoSuspend) { + DBG_871X("<==%s .pwrpriv->bInternalAutoSuspend)(%x)\n",__FUNCTION__,pwrpriv->bInternalAutoSuspend); + } else { + pwrpriv->change_rfpwrstate = rf_off; + DBG_871X("<==%s .pwrpriv->bInternalAutoSuspend)(%x) call autosuspend_enter\n",__FUNCTION__,pwrpriv->bInternalAutoSuspend); + autosuspend_enter(padapter); + } + #else + autosuspend_enter(padapter); + #endif //if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + } + else if(pwrpriv->bHWPwrPindetect) + { + } + else + #endif //CONFIG_AUTOSUSPEND + { + #if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + pwrpriv->change_rfpwrstate = rf_off; + #endif //defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + + #ifdef CONFIG_IPS + ips_enter(padapter); + #endif + } + } +exit: +#ifndef CONFIG_IPS_CHECK_IN_WD + rtw_set_pwr_state_check_timer(pwrpriv); +#endif + pwrpriv->ps_processing = _FALSE; + return; +} + +void pwr_state_check_handler(RTW_TIMER_HDL_ARGS); +void pwr_state_check_handler(RTW_TIMER_HDL_ARGS) +{ + _adapter *padapter = (_adapter *)FunctionContext; + rtw_ps_cmd(padapter); +} + +#ifdef CONFIG_LPS +void traffic_check_for_leave_lps(PADAPTER padapter, u8 tx, u32 tx_packets) +{ +#ifdef CONFIG_CHECK_LEAVE_LPS + static u32 start_time = 0; + static u32 xmit_cnt = 0; + u8 bLeaveLPS = _FALSE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + + + if(tx) //from tx + { + xmit_cnt += tx_packets; + + if (start_time== 0) + start_time= rtw_get_current_time(); + + if (rtw_get_passing_time_ms(start_time) > 2000) // 2 sec == watch dog timer + { + if(xmit_cnt > 8) + { + if ((adapter_to_pwrctl(padapter)->bLeisurePs) + && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) +#ifdef CONFIG_BT_COEXIST + && (rtw_btcoex_IsBtControlLps(padapter) == _FALSE) +#endif + ) + { + //DBG_871X("leave lps via Tx = %d\n", xmit_cnt); + bLeaveLPS = _TRUE; + } + } + + start_time= rtw_get_current_time(); + xmit_cnt = 0; + } + + } + else // from rx path + { + if(pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 4/*2*/) + { + if ((adapter_to_pwrctl(padapter)->bLeisurePs) + && (adapter_to_pwrctl(padapter)->pwr_mode != PS_MODE_ACTIVE) +#ifdef CONFIG_BT_COEXIST + && (rtw_btcoex_IsBtControlLps(padapter) == _FALSE) +#endif + ) + { + //DBG_871X("leave lps via Rx = %d\n", pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); + bLeaveLPS = _TRUE; + } + } + } + + if(bLeaveLPS) + { + //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, tx?LPS_CTRL_TX_TRAFFIC_LEAVE:LPS_CTRL_RX_TRAFFIC_LEAVE, tx?0:1); + } +#endif //CONFIG_CHECK_LEAVE_LPS +} + +/* + * Description: + * This function MUST be called under power lock protect + * + * Parameters + * padapter + * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4 + * + */ +void rtw_set_rpwm(PADAPTER padapter, u8 pslv) +{ + u8 rpwm; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + u8 cpwm_orig; +#endif // CONFIG_DETECT_CPWM_BY_POLLING + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +_func_enter_; + + pslv = PS_STATE(pslv); + +#ifdef CONFIG_LPS_RPWM_TIMER + if (pwrpriv->brpwmtimeout == _TRUE) + { + DBG_871X("%s: RPWM timeout, force to set RPWM(0x%02X) again!\n", __FUNCTION__, pslv); + } + else +#endif // CONFIG_LPS_RPWM_TIMER + { + if ( (pwrpriv->rpwm == pslv) +#ifdef CONFIG_LPS_LCLK + || ((pwrpriv->rpwm >= PS_STATE_S2)&&(pslv >= PS_STATE_S2)) +#endif + ) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_, + ("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __FUNCTION__, pwrpriv->rpwm, pslv)); + return; + } + } + + if (rtw_is_surprise_removed(padapter) || + (!rtw_is_hw_init_completed(padapter))) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("%s: SurpriseRemoved(%s) hw_init_completed(%s)\n" + , __func__ + , rtw_is_surprise_removed(padapter)?"True":"False" + , rtw_is_hw_init_completed(padapter)?"True":"False")); + + pwrpriv->cpwm = PS_STATE_S4; + + return; + } + + if (rtw_is_drv_stopped(padapter)) { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("%s: change power state(0x%02X) when DriverStopped\n", __FUNCTION__, pslv)); + + if (pslv < PS_STATE_S2) { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n", __FUNCTION__, pslv)); + return; + } + } + + rpwm = pslv | pwrpriv->tog; +#ifdef CONFIG_LPS_LCLK + // only when from PS_STATE S0/S1 to S2 and higher needs ACK + if ((pwrpriv->cpwm < PS_STATE_S2) && (pslv >= PS_STATE_S2)) + rpwm |= PS_ACK; +#endif + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_set_rpwm: rpwm=0x%02x cpwm=0x%02x\n", rpwm, pwrpriv->cpwm)); + + pwrpriv->rpwm = pslv; + +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + cpwm_orig = 0; + if (rpwm & PS_ACK) + { + rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig); + } +#endif + +#if defined(CONFIG_LPS_RPWM_TIMER) && !defined(CONFIG_DETECT_CPWM_BY_POLLING) + if (rpwm & PS_ACK) + _set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS); +#endif // CONFIG_LPS_RPWM_TIMER & !CONFIG_DETECT_CPWM_BY_POLLING + rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm)); + + pwrpriv->tog += 0x80; + +#ifdef CONFIG_LPS_LCLK + // No LPS 32K, No Ack + if (rpwm & PS_ACK) + { +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + u32 start_time; + u8 cpwm_now; + u8 poll_cnt=0; + + start_time = rtw_get_current_time(); + + // polling cpwm + do { + rtw_msleep_os(1); + poll_cnt++; + cpwm_now = 0; + rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now); + if ((cpwm_orig ^ cpwm_now) & 0x80) + { + pwrpriv->cpwm = PS_STATE_S4; + pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE; +#ifdef DBG_CHECK_FW_PS_STATE + DBG_871X("%s: polling cpwm OK! poll_cnt=%d, cpwm_orig=%02x, cpwm_now=%02x , 0x100=0x%x\n" + , __FUNCTION__,poll_cnt, cpwm_orig, cpwm_now, rtw_read8(padapter, REG_CR)); + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("leave 32k but fw state in 32k\n"); + pdbgpriv->dbg_rpwm_toogle_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + break; + } + + if (rtw_get_passing_time_ms(start_time) > LPS_RPWM_WAIT_MS) + { + DBG_871X("%s: polling cpwm timeout! poll_cnt=%d, cpwm_orig=%02x, cpwm_now=%02x \n", __FUNCTION__,poll_cnt, cpwm_orig, cpwm_now); +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("rpwm timeout and fw ps state in 32k\n"); + pdbgpriv->dbg_rpwm_timeout_fail_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE +#ifdef CONFIG_LPS_RPWM_TIMER + _set_timer(&pwrpriv->pwr_rpwm_timer, 1); +#endif // CONFIG_LPS_RPWM_TIMER + break; + } + } while (1); +#endif // CONFIG_DETECT_CPWM_BY_POLLING + } + else +#endif // CONFIG_LPS_LCLK + { + pwrpriv->cpwm = pslv; + } + +_func_exit_; +} + +u8 PS_RDY_CHECK(_adapter * padapter) +{ + u32 curr_time, delta_time; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); +#ifdef CONFIG_IOCTL_CFG80211 + struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; +#endif /* CONFIG_IOCTL_CFG80211 */ +#endif /* CONFIG_P2P */ + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + if(_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_mode) + return _TRUE; + else if(_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_ap_mode) + return _TRUE; + else if (_TRUE == pwrpriv->bInSuspend) + return _FALSE; +#else + if(_TRUE == pwrpriv->bInSuspend ) + return _FALSE; +#endif + + curr_time = rtw_get_current_time(); + + delta_time = curr_time -pwrpriv->DelayLPSLastTimeStamp; + + if(delta_time < LPS_DELAY_TIME) + { + return _FALSE; + } + + if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR) + || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) + || check_fwstate(pmlmepriv, WIFI_AP_STATE) + || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) + #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) + || pcfg80211_wdinfo->is_ro_ch + #elif defined(CONFIG_P2P) + || !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) + #endif + || rtw_is_scan_deny(padapter) +#ifdef CONFIG_TDLS + // TDLS link is established. + || ( padapter->tdlsinfo.link_established == _TRUE ) +#endif // CONFIG_TDLS + ) + return _FALSE; + + if( (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == _FALSE) ) + { + DBG_871X("Group handshake still in progress !!!\n"); + return _FALSE; + } + +#ifdef CONFIG_IOCTL_CFG80211 + if (!rtw_cfg80211_pwr_mgmt(padapter)) + return _FALSE; +#endif + + return _TRUE; +} + +#if defined(CONFIG_FWLPS_IN_IPS) +void rtw_set_fw_in_ips_mode(PADAPTER padapter, u8 enable) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int cnt=0; + u32 start_time; + u8 val8 = 0; + u8 cpwm_orig = 0, cpwm_now = 0; + u8 parm[H2C_INACTIVE_PS_LEN]={0}; + + if (padapter->netif_up == _FALSE) { + DBG_871X("%s: ERROR, netif is down\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__); + +#ifdef CONFIG_PNO_SUPPORT + parm[0] = 0x03; + parm[1] = pwrpriv->pnlo_info->fast_scan_iterations; + parm[2] = pwrpriv->pnlo_info->slow_scan_period; +#else + parm[0] = 0x03; + parm[1] = 0x0; + parm[2] = 0x0; +#endif//CONFIG_PNO_SUPPORT + + rtw_hal_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; + if (parm[1] == 0 || parm[2] == 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)); + } + } + } 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) { + 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; + rtw_hal_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); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); +#endif //CONFIG_P2P +#ifdef CONFIG_TDLS + struct sta_priv *pstapriv = &padapter->stapriv; + _irqL irqL; + int i, j; + _list *plist, *phead; + struct sta_info *ptdls_sta; +#endif //CONFIG_TDLS + +_func_enter_; + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("%s: PowerMode=%d Smart_PS=%d\n", + __FUNCTION__, ps_mode, smart_ps)); + + if(ps_mode > PM_Card_Disable) { + RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,("ps_mode:%d error\n", ps_mode)); + return; + } + + if (pwrpriv->pwr_mode == ps_mode) + { + if (PS_MODE_ACTIVE == ps_mode) return; + +#ifndef CONFIG_BT_COEXIST + if ((pwrpriv->smart_ps == smart_ps) && + (pwrpriv->bcn_ant_mode == bcn_ant_mode)) + { + return; + } +#endif // !CONFIG_BT_COEXIST + } + +#ifdef CONFIG_LPS_LCLK + _enter_pwrlock(&pwrpriv->lock); +#endif + + //if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + if(ps_mode == PS_MODE_ACTIVE) + { + if (1 +#ifdef CONFIG_BT_COEXIST + && (((rtw_btcoex_IsBtControlLps(padapter) == _FALSE) +#ifdef CONFIG_P2P_PS + && (pwdinfo->opp_ps == 0) +#endif // CONFIG_P2P_PS + ) + || ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE) + && (rtw_btcoex_IsLpsOn(padapter) == _FALSE)) + ) +#else // !CONFIG_BT_COEXIST +#ifdef CONFIG_P2P_PS + && (pwdinfo->opp_ps == 0) +#endif // CONFIG_P2P_PS +#endif // !CONFIG_BT_COEXIST + ) + { + DBG_871X(FUNC_ADPT_FMT" Leave 802.11 power save - %s\n", + FUNC_ADPT_ARG(padapter), msg); + + if (pwrpriv->lps_leave_cnts < UINT_MAX) + pwrpriv->lps_leave_cnts++; + else + pwrpriv->lps_leave_cnts = 0; +#ifdef CONFIG_TDLS + 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) + { + ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE ) + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0); + plist = get_next(plist); + } + } +#endif //CONFIG_TDLS + + pwrpriv->pwr_mode = ps_mode; + rtw_set_rpwm(padapter, PS_STATE_S4); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_P2P_WOWLAN) + if (pwrpriv->wowlan_mode == _TRUE || + pwrpriv->wowlan_ap_mode == _TRUE || + pwrpriv->wowlan_p2p_mode == _TRUE) + { + u32 start_time, delay_ms; + u8 val8; + delay_ms = 20; + start_time = rtw_get_current_time(); + do { + rtw_hal_get_hwreg(padapter, HW_VAR_SYS_CLKR, &val8); + if (!(val8 & BIT(4))){ //0x08 bit4 =1 --> in 32k, bit4 = 0 --> leave 32k + pwrpriv->cpwm = PS_STATE_S4; + break; + } + if (rtw_get_passing_time_ms(start_time) > delay_ms) + { + DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n", + __FUNCTION__, delay_ms); + pdbgpriv->dbg_wow_leave_ps_fail_cnt++; + break; + } + rtw_usleep_os(100); + } while (1); + } +#endif + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + pwrpriv->bFwCurrentInPSMode = _FALSE; + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_LpsNotify(padapter, ps_mode); +#endif // CONFIG_BT_COEXIST + } + } + else + { + if ((PS_RDY_CHECK(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) +#ifdef CONFIG_BT_COEXIST + || ((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; + + DBG_871X(FUNC_ADPT_FMT" Enter 802.11 power save - %s\n", + FUNC_ADPT_ARG(padapter), msg); + + if (pwrpriv->lps_enter_cnts < UINT_MAX) + pwrpriv->lps_enter_cnts++; + else + pwrpriv->lps_enter_cnts = 0; +#ifdef CONFIG_TDLS + 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) + { + ptdls_sta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if( ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE ) + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 0, 0); + plist = get_next(plist); + } + } +#endif //CONFIG_TDLS + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_LpsNotify(padapter, ps_mode); +#endif // CONFIG_BT_COEXIST + + pwrpriv->bFwCurrentInPSMode = _TRUE; + pwrpriv->pwr_mode = ps_mode; + pwrpriv->smart_ps = smart_ps; + pwrpriv->bcn_ant_mode = bcn_ant_mode; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); + +#ifdef CONFIG_P2P_PS + // Set CTWindow after LPS + if(pwdinfo->opp_ps == 1) + p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0); +#endif //CONFIG_P2P_PS + + pslv = PS_STATE_S2; +#ifdef CONFIG_LPS_LCLK + if (pwrpriv->alives == 0) + pslv = PS_STATE_S0; +#endif // CONFIG_LPS_LCLK + +#ifdef CONFIG_BT_COEXIST + if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE) + && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) + { + u8 val8; + + val8 = rtw_btcoex_LpsVal(padapter); + if (val8 & BIT(4)) + pslv = PS_STATE_S2; + + } +#endif // CONFIG_BT_COEXIST + + rtw_set_rpwm(padapter, pslv); + } + } + +#ifdef CONFIG_LPS_LCLK + _exit_pwrlock(&pwrpriv->lock); +#endif + +_func_exit_; +} + +/* + * Return: + * 0: Leave OK + * -1: Timeout + * -2: Other error + */ +s32 LPS_RF_ON_check(PADAPTER padapter, u32 delay_ms) +{ + u32 start_time; + u8 bAwake = _FALSE; + s32 err = 0; + + + start_time = rtw_get_current_time(); + while (1) + { + rtw_hal_get_hwreg(padapter, HW_VAR_FWLPS_RF_ON, &bAwake); + if (_TRUE == bAwake) + break; + + if (rtw_is_surprise_removed(padapter)) { + err = -2; + DBG_871X("%s: device surprise removed!!\n", __FUNCTION__); + break; + } + + if (rtw_get_passing_time_ms(start_time) > delay_ms) + { + err = -1; + DBG_871X("%s: Wait for FW LPS leave more than %u ms!!!\n", __FUNCTION__, delay_ms); + break; + } + rtw_usleep_os(100); + } + + return err; +} + +// +// Description: +// Enter the leisure power save mode. +// +void LPS_Enter(PADAPTER padapter, const char *msg) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _adapter *buddy = padapter->pbuddy_adapter; + int n_assoc_iface = 0; + int i; + char buf[32] = {0}; + +_func_enter_; + +// DBG_871X("+LeisurePSEnter\n"); + +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE) + return; +#endif + + /* Skip lps enter request if number of assocated adapters is not 1 */ + for (i = 0; i < dvobj->iface_nums; i++) { + if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE)) + n_assoc_iface++; + } + if (n_assoc_iface != 1) + return; + + /* Skip lps enter request for adapter not port0 */ + if (get_iface_type(padapter) != IFACE_PORT0) + return; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (PS_RDY_CHECK(dvobj->padapters[i]) == _FALSE) + 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. + if (pwrpriv->LpsIdleCount >= 2) // 4 Sec + { + if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + { + sprintf(buf, "WIFI-%s", msg); + pwrpriv->bpower_saving = _TRUE; + rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, padapter->registrypriv.smart_ps, 0, buf); + } + } + else + pwrpriv->LpsIdleCount++; + } + +// DBG_871X("-LeisurePSEnter\n"); + +_func_exit_; +} + +// +// Description: +// Leave the leisure power save mode. +// +void LPS_Leave(PADAPTER padapter, const char *msg) +{ +#define LPS_LEAVE_TIMEOUT_MS 100 + + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + u32 start_time; + u8 bAwake = _FALSE; + char buf[32] = {0}; + struct debug_priv *pdbgpriv = &dvobj->drv_dbg; + +_func_enter_; + +// DBG_871X("+LeisurePSLeave\n"); + +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE) + return; +#endif + + if (pwrpriv->bLeisurePs) + { + if(pwrpriv->pwr_mode != PS_MODE_ACTIVE) + { + sprintf(buf, "WIFI-%s", msg); + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, buf); + + if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) + LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); + } + } + + pwrpriv->bpower_saving = _FALSE; +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("leave lps, fw in 32k\n"); + pdbgpriv->dbg_leave_lps_fail_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE +// DBG_871X("-LeisurePSLeave\n"); + +_func_exit_; +} +#endif + +void LeaveAllPowerSaveModeDirect(PADAPTER Adapter) +{ + PADAPTER pri_padapter = GET_PRIMARY_ADAPTER(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter); + struct dvobj_priv *psdpriv = Adapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +#ifndef CONFIG_DETECT_CPWM_BY_POLLING + u8 cpwm_orig, cpwm_now; + u32 start_time; +#endif // CONFIG_DETECT_CPWM_BY_POLLING + +_func_enter_; + + DBG_871X("%s.....\n",__FUNCTION__); + + if (rtw_is_surprise_removed(Adapter)) { + DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(Adapter)); + return; + } + + if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) +#ifdef CONFIG_CONCURRENT_MODE + || (check_buddy_fwstate(Adapter,_FW_LINKED) == _TRUE) +#endif + ) + { //connect + + if(pwrpriv->pwr_mode == PS_MODE_ACTIVE) { + DBG_871X("%s: Driver Already Leave LPS\n",__FUNCTION__); + return; + } + +#ifdef CONFIG_LPS_LCLK + _enter_pwrlock(&pwrpriv->lock); + +#ifndef CONFIG_DETECT_CPWM_BY_POLLING + cpwm_orig = 0; + rtw_hal_get_hwreg(Adapter, HW_VAR_CPWM, &cpwm_orig); +#endif //CONFIG_DETECT_CPWM_BY_POLLING + rtw_set_rpwm(Adapter, PS_STATE_S4); + +#ifndef CONFIG_DETECT_CPWM_BY_POLLING + + start_time = rtw_get_current_time(); + + // polling cpwm + do { + rtw_mdelay_os(1); + + rtw_hal_get_hwreg(Adapter, HW_VAR_CPWM, &cpwm_now); + if ((cpwm_orig ^ cpwm_now) & 0x80) + { + pwrpriv->cpwm = PS_STATE_S4; + pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE; +#ifdef DBG_CHECK_FW_PS_STATE + DBG_871X("%s: polling cpwm OK! cpwm_orig=%02x, cpwm_now=%02x, 0x100=0x%x \n" + , __FUNCTION__, cpwm_orig, cpwm_now, rtw_read8(Adapter, REG_CR)); + if(rtw_fw_ps_state(Adapter) == _FAIL) + { + DBG_871X("%s: leave 32k but fw state in 32k\n", __FUNCTION__); + pdbgpriv->dbg_rpwm_toogle_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + break; + } + + if (rtw_get_passing_time_ms(start_time) > LPS_RPWM_WAIT_MS) + { + DBG_871X("%s: polling cpwm timeout! cpwm_orig=%02x, cpwm_now=%02x \n", __FUNCTION__, cpwm_orig, cpwm_now); +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(Adapter) == _FAIL) + { + DBG_871X("rpwm timeout and fw ps state in 32k\n"); + pdbgpriv->dbg_rpwm_timeout_fail_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + break; + } + } while (1); +#endif // CONFIG_DETECT_CPWM_BY_POLLING + + _exit_pwrlock(&pwrpriv->lock); +#endif + +#ifdef CONFIG_P2P_PS + p2p_ps_wk_cmd(pri_padapter, P2P_PS_DISABLE, 0); +#endif //CONFIG_P2P_PS + +#ifdef CONFIG_LPS + rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0); +#endif + } + else + { + if(pwrpriv->rf_pwrstate== rf_off) + { + #ifdef CONFIG_AUTOSUSPEND + if(Adapter->registrypriv.usbss_enable) + { + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev); + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;//autosuspend disabled by the user + #endif + } + else + #endif + { +#if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_RTL8188E) + #ifdef CONFIG_IPS + if(_FALSE == ips_leave(pri_padapter)) + { + DBG_871X("======> ips_leave fail.............\n"); + } + #endif +#endif //CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) + } + } + } + +_func_exit_; +} + +// +// Description: Leave all power save mode: LPS, FwLPS, IPS if needed. +// Move code to function by tynli. 2010.03.26. +// +void LeaveAllPowerSaveMode(IN PADAPTER Adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + u8 enqueue = 0; + int n_assoc_iface = 0; + int i; + +_func_enter_; + + //DBG_871X("%s.....\n",__FUNCTION__); + + if (_FALSE == Adapter->bup) + { + DBG_871X(FUNC_ADPT_FMT ": bup=%d Skip!\n", + FUNC_ADPT_ARG(Adapter), Adapter->bup); + return; + } + + if (rtw_is_surprise_removed(Adapter)) { + DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved=_TRUE Skip!\n", FUNC_ADPT_ARG(Adapter)); + return; + } + + for (i = 0; i < dvobj->iface_nums; i++) { + if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE)) + n_assoc_iface++; + } + + if (n_assoc_iface) + { //connect +#ifdef CONFIG_LPS_LCLK + enqueue = 1; +#endif + +#ifdef CONFIG_P2P_PS + p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue); +#endif //CONFIG_P2P_PS + +#ifdef CONFIG_LPS + rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue); +#endif + +#ifdef CONFIG_LPS_LCLK + LPS_Leave_check(Adapter); +#endif + } + else + { + if(adapter_to_pwrctl(Adapter)->rf_pwrstate== rf_off) + { + #ifdef CONFIG_AUTOSUSPEND + if(Adapter->registrypriv.usbss_enable) + { + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + usb_disable_autosuspend(adapter_to_dvobj(Adapter)->pusbdev); + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + adapter_to_dvobj(Adapter)->pusbdev->autosuspend_disabled = Adapter->bDisableAutosuspend;//autosuspend disabled by the user + #endif + } + else + #endif + { +#if defined(CONFIG_FWLPS_IN_IPS) || defined(CONFIG_SWLPS_IN_IPS) || (defined(CONFIG_PLATFORM_SPRD) && defined(CONFIG_RTL8188E)) + #ifdef CONFIG_IPS + if(_FALSE == ips_leave(Adapter)) + { + DBG_871X("======> ips_leave fail.............\n"); + } + #endif +#endif //CONFIG_SWLPS_IN_IPS || (CONFIG_PLATFORM_SPRD && CONFIG_RTL8188E) + } + } + } + +_func_exit_; +} + +#ifdef CONFIG_LPS_LCLK +void LPS_Leave_check( + PADAPTER padapter) +{ + struct pwrctrl_priv *pwrpriv; + u32 start_time; + u8 bReady; + +_func_enter_; + + pwrpriv = adapter_to_pwrctl(padapter); + + bReady = _FALSE; + start_time = rtw_get_current_time(); + + rtw_yield_os(); + + while(1) + { + _enter_pwrlock(&pwrpriv->lock); + + if (rtw_is_surprise_removed(padapter) + || (!rtw_is_hw_init_completed(padapter)) +#ifdef CONFIG_USB_HCI + || rtw_is_drv_stopped(padapter) +#endif + || (pwrpriv->pwr_mode == PS_MODE_ACTIVE) + ) + { + bReady = _TRUE; + } + + _exit_pwrlock(&pwrpriv->lock); + + if(_TRUE == bReady) + break; + + if(rtw_get_passing_time_ms(start_time)>100) + { + DBG_871X("Wait for cpwm event than 100 ms!!!\n"); + break; + } + rtw_msleep_os(1); + } + +_func_exit_; +} + +/* + * Caller:ISR handler... + * + * This will be called when CPWM interrupt is up. + * + * using to update cpwn of drv; and drv willl make a decision to up or down pwr level + */ +void cpwm_int_hdl( + PADAPTER padapter, + struct reportpwrstate_parm *preportpwrstate) +{ + struct pwrctrl_priv *pwrpriv; + +_func_enter_; + + pwrpriv = adapter_to_pwrctl(padapter); +#if 0 + if (pwrpriv->cpwm_tog == (preportpwrstate->state & PS_TOGGLE)) { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_, + ("cpwm_int_hdl: tog(old)=0x%02x cpwm(new)=0x%02x toggle bit didn't change!?\n", + pwrpriv->cpwm_tog, preportpwrstate->state)); + goto exit; + } +#endif + + _enter_pwrlock(&pwrpriv->lock); + +#ifdef CONFIG_LPS_RPWM_TIMER + if (pwrpriv->rpwm < PS_STATE_S2) + { + DBG_871X("%s: Redundant CPWM Int. RPWM=0x%02X CPWM=0x%02x\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); + _exit_pwrlock(&pwrpriv->lock); + goto exit; + } +#endif // CONFIG_LPS_RPWM_TIMER + + pwrpriv->cpwm = PS_STATE(preportpwrstate->state); + pwrpriv->cpwm_tog = preportpwrstate->state & PS_TOGGLE; + + if (pwrpriv->cpwm >= PS_STATE_S2) + { + if (pwrpriv->alives & CMD_ALIVE) + _rtw_up_sema(&padapter->cmdpriv.cmd_queue_sema); + + if (pwrpriv->alives & XMIT_ALIVE) + _rtw_up_sema(&padapter->xmitpriv.xmit_sema); + } + + _exit_pwrlock(&pwrpriv->lock); + +exit: + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("cpwm_int_hdl: cpwm=0x%02x\n", pwrpriv->cpwm)); + +_func_exit_; +} + +static void cpwm_event_callback(struct work_struct *work) +{ + struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event); + struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv); + _adapter *adapter = dvobj->padapters[IFACE_ID0]; + struct reportpwrstate_parm report; + + //DBG_871X("%s\n",__FUNCTION__); + + report.state = PS_STATE_S2; + cpwm_int_hdl(adapter, &report); +} + +#ifdef CONFIG_LPS_RPWM_TIMER +static void rpwmtimeout_workitem_callback(struct work_struct *work) +{ + PADAPTER padapter; + struct dvobj_priv *dvobj; + struct pwrctrl_priv *pwrpriv; + + + pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi); + dvobj = pwrctl_to_dvobj(pwrpriv); + padapter = dvobj->padapters[IFACE_ID0]; +// DBG_871X("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); + + _enter_pwrlock(&pwrpriv->lock); + if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) + { + DBG_871X("%s: rpwm=0x%02X cpwm=0x%02X CPWM done!\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); + goto exit; + } + _exit_pwrlock(&pwrpriv->lock); + + if (rtw_read8(padapter, 0x100) != 0xEA) + { +#if 1 + struct reportpwrstate_parm report; + + report.state = PS_STATE_S2; + DBG_871X("\n%s: FW already leave 32K!\n\n", __func__); + cpwm_int_hdl(padapter, &report); +#else + DBG_871X("\n%s: FW already leave 32K!\n\n", __func__); + cpwm_event_callback(&pwrpriv->cpwm_event); +#endif + return; + } + + _enter_pwrlock(&pwrpriv->lock); + + if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) + { + DBG_871X("%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm); + goto exit; + } + pwrpriv->brpwmtimeout = _TRUE; + rtw_set_rpwm(padapter, pwrpriv->rpwm); + pwrpriv->brpwmtimeout = _FALSE; + +exit: + _exit_pwrlock(&pwrpriv->lock); +} + +/* + * This function is a timer handler, can't do any IO in it. + */ +static void pwr_rpwm_timeout_handler(void *FunctionContext) +{ + PADAPTER padapter; + struct pwrctrl_priv *pwrpriv; + + + padapter = (PADAPTER)FunctionContext; + pwrpriv = adapter_to_pwrctl(padapter); + DBG_871X("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm); + + if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2)) + { + DBG_871X("+%s: cpwm=%d, nothing to do!\n", __func__, pwrpriv->cpwm); + return; + } + + _set_workitem(&pwrpriv->rpwmtimeoutwi); +} +#endif // CONFIG_LPS_RPWM_TIMER + +__inline static void register_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +{ + pwrctrl->alives |= tag; +} + +__inline static void unregister_task_alive(struct pwrctrl_priv *pwrctrl, u32 tag) +{ + pwrctrl->alives &= ~tag; +} + + +/* + * Description: + * Check if the fw_pwrstate is okay for I/O. + * If not (cpwm is less than S2), then the sub-routine + * will raise the cpwm to be greater than or equal to S2. + * + * Calling Context: Passive + * + * Constraint: + * 1. this function will request pwrctrl->lock + * + * Return Value: + * _SUCCESS hardware is ready for I/O + * _FAIL can't I/O right now + */ +s32 rtw_register_task_alive(PADAPTER padapter, u32 task) +{ + s32 res; + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + res = _SUCCESS; + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S2; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, task); + + if (pwrctrl->bFwCurrentInPSMode == _TRUE) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("%s: task=0x%x cpwm=0x%02x alives=0x%08x\n", + __FUNCTION__, task, pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm < pslv) + { + if (pwrctrl->cpwm < PS_STATE_S2) + res = _FAIL; + if (pwrctrl->rpwm < pslv) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + if (_FAIL == res) + { + if (pwrctrl->cpwm >= PS_STATE_S2) + res = _SUCCESS; + } +#endif // CONFIG_DETECT_CPWM_BY_POLLING + +_func_exit_; + + return res; +} + +/* + * Description: + * If task is done, call this func. to power down firmware again. + * + * Constraint: + * 1. this function will request pwrctrl->lock + * + * Return Value: + * none + */ +void rtw_unregister_task_alive(PADAPTER padapter, u32 task) +{ + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S0; + +#ifdef CONFIG_BT_COEXIST + if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE) + && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) + { + u8 val8; + + val8 = rtw_btcoex_LpsVal(padapter); + if (val8 & BIT(4)) + pslv = PS_STATE_S2; + + } +#endif // CONFIG_BT_COEXIST + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, task); + + if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) + && (pwrctrl->bFwCurrentInPSMode == _TRUE)) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("%s: cpwm=0x%02x alives=0x%08x\n", + __FUNCTION__, pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm > pslv) + { + if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0)) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +/* + * Caller: rtw_xmit_thread + * + * Check if the fw_pwrstate is okay for xmit. + * If not (cpwm is less than S3), then the sub-routine + * will raise the cpwm to be greater than or equal to S3. + * + * Calling Context: Passive + * + * Return Value: + * _SUCCESS rtw_xmit_thread can write fifo/txcmd afterwards. + * _FAIL rtw_xmit_thread can not do anything. + */ +s32 rtw_register_tx_alive(PADAPTER padapter) +{ + s32 res; + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + res = _SUCCESS; + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S2; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, XMIT_ALIVE); + + if (pwrctrl->bFwCurrentInPSMode == _TRUE) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_tx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm < pslv) + { + if (pwrctrl->cpwm < PS_STATE_S2) + res = _FAIL; + if (pwrctrl->rpwm < pslv) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + if (_FAIL == res) + { + if (pwrctrl->cpwm >= PS_STATE_S2) + res = _SUCCESS; + } +#endif // CONFIG_DETECT_CPWM_BY_POLLING + +_func_exit_; + + return res; +} + +/* + * Caller: rtw_cmd_thread + * + * Check if the fw_pwrstate is okay for issuing cmd. + * If not (cpwm should be is less than S2), then the sub-routine + * will raise the cpwm to be greater than or equal to S2. + * + * Calling Context: Passive + * + * Return Value: + * _SUCCESS rtw_cmd_thread can issue cmds to firmware afterwards. + * _FAIL rtw_cmd_thread can not do anything. + */ +s32 rtw_register_cmd_alive(PADAPTER padapter) +{ + s32 res; + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + res = _SUCCESS; + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S2; + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, CMD_ALIVE); + + if (pwrctrl->bFwCurrentInPSMode == _TRUE) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_, + ("rtw_register_cmd_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm < pslv) + { + if (pwrctrl->cpwm < PS_STATE_S2) + res = _FAIL; + if (pwrctrl->rpwm < pslv) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +#ifdef CONFIG_DETECT_CPWM_BY_POLLING + if (_FAIL == res) + { + if (pwrctrl->cpwm >= PS_STATE_S2) + res = _SUCCESS; + } +#endif // CONFIG_DETECT_CPWM_BY_POLLING + +_func_exit_; + + return res; +} + +/* + * Caller: rx_isr + * + * Calling Context: Dispatch/ISR + * + * Return Value: + * _SUCCESS + * _FAIL + */ +s32 rtw_register_rx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, RECV_ALIVE); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_rx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return _SUCCESS; +} + +/* + * Caller: evt_isr or evt_thread + * + * Calling Context: Dispatch/ISR or Passive + * + * Return Value: + * _SUCCESS + * _FAIL + */ +s32 rtw_register_evt_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + + _enter_pwrlock(&pwrctrl->lock); + + register_task_alive(pwrctrl, EVT_ALIVE); + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_register_evt_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; + + return _SUCCESS; +} + +/* + * Caller: ISR + * + * If ISR's txdone, + * No more pkts for TX, + * Then driver shall call this fun. to power down firmware again. + */ +void rtw_unregister_tx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S0; + +#ifdef CONFIG_BT_COEXIST + if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE) + && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) + { + u8 val8; + + val8 = rtw_btcoex_LpsVal(padapter); + if (val8 & BIT(4)) + pslv = PS_STATE_S2; + + } +#endif // CONFIG_BT_COEXIST + +#ifdef CONFIG_P2P_PS + if(padapter->wdinfo.p2p_ps_mode > P2P_PS_NONE) + { + pslv = PS_STATE_S2; + } +#ifdef CONFIG_CONCURRENT_MODE + else if(rtw_buddy_adapter_up(padapter)) + { + if(padapter->pbuddy_adapter->wdinfo.p2p_ps_mode > P2P_PS_NONE) + pslv = PS_STATE_S2; + } +#endif +#endif + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, XMIT_ALIVE); + + if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) + && (pwrctrl->bFwCurrentInPSMode == _TRUE)) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("%s: cpwm=0x%02x alives=0x%08x\n", + __FUNCTION__, pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm > pslv) + { + if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0)) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +/* + * Caller: ISR + * + * If all commands have been done, + * and no more command to do, + * then driver shall call this fun. to power down firmware again. + */ +void rtw_unregister_cmd_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + u8 pslv; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + pslv = PS_STATE_S0; + +#ifdef CONFIG_BT_COEXIST + if ((rtw_btcoex_IsBtDisabled(padapter) == _FALSE) + && (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)) + { + u8 val8; + + val8 = rtw_btcoex_LpsVal(padapter); + if (val8 & BIT(4)) + pslv = PS_STATE_S2; + + } +#endif // CONFIG_BT_COEXIST + +#ifdef CONFIG_P2P_PS + if(padapter->wdinfo.p2p_ps_mode > P2P_PS_NONE) + { + pslv = PS_STATE_S2; + } +#ifdef CONFIG_CONCURRENT_MODE + else if(rtw_buddy_adapter_up(padapter)) + { + if(padapter->pbuddy_adapter->wdinfo.p2p_ps_mode > P2P_PS_NONE) + pslv = PS_STATE_S2; + } +#endif +#endif + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, CMD_ALIVE); + + if ((pwrctrl->pwr_mode != PS_MODE_ACTIVE) + && (pwrctrl->bFwCurrentInPSMode == _TRUE)) + { + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_info_, + ("%s: cpwm=0x%02x alives=0x%08x\n", + __FUNCTION__, pwrctrl->cpwm, pwrctrl->alives)); + + if (pwrctrl->cpwm > pslv) + { + if ((pslv >= PS_STATE_S2) || (pwrctrl->alives == 0)) + rtw_set_rpwm(padapter, pslv); + } + } + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +/* + * Caller: ISR + */ +void rtw_unregister_rx_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + + _enter_pwrlock(&pwrctrl->lock); + + unregister_task_alive(pwrctrl, RECV_ALIVE); + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_rx_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} + +void rtw_unregister_evt_alive(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrl; + +_func_enter_; + + pwrctrl = adapter_to_pwrctl(padapter); + + unregister_task_alive(pwrctrl, EVT_ALIVE); + + RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_, + ("rtw_unregister_evt_alive: cpwm=0x%02x alives=0x%08x\n", + pwrctrl->cpwm, pwrctrl->alives)); + + _exit_pwrlock(&pwrctrl->lock); + +_func_exit_; +} +#endif /* CONFIG_LPS_LCLK */ + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +static void resume_workitem_callback(struct work_struct *work); +#endif //CONFIG_RESUME_IN_WORKQUEUE + +void rtw_init_pwrctrl_priv(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + int i = 0; + u8 val8 = 0; + +#if defined(CONFIG_CONCURRENT_MODE) + if (padapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + +_func_enter_; + +#ifdef PLATFORM_WINDOWS + pwrctrlpriv->pnp_current_pwr_state=NdisDeviceStateD0; +#endif + + _init_pwrlock(&pwrctrlpriv->lock); + _init_pwrlock(&pwrctrlpriv->check_32k_lock); + pwrctrlpriv->rf_pwrstate = rf_on; + pwrctrlpriv->ips_enter_cnts=0; + pwrctrlpriv->ips_leave_cnts=0; + pwrctrlpriv->lps_enter_cnts=0; + pwrctrlpriv->lps_leave_cnts=0; + pwrctrlpriv->bips_processing = _FALSE; + + pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode; + pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode; + + pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL; + pwrctrlpriv->pwr_state_check_cnts = 0; + pwrctrlpriv->bInternalAutoSuspend = _FALSE; + pwrctrlpriv->bInSuspend = _FALSE; + pwrctrlpriv->bkeepfwalive = _FALSE; + +#ifdef CONFIG_AUTOSUSPEND +#ifdef SUPPORT_HW_RFOFF_DETECTED + pwrctrlpriv->pwr_state_check_interval = (pwrctrlpriv->bHWPwrPindetect) ?1000:2000; +#endif +#endif + + pwrctrlpriv->LpsIdleCount = 0; + //pwrctrlpriv->FWCtrlPSMode =padapter->registrypriv.power_mgnt;// PS_MODE_MIN; + if (padapter->registrypriv.mp_mode == 1) + pwrctrlpriv->power_mgnt =PS_MODE_ACTIVE ; + else + pwrctrlpriv->power_mgnt =padapter->registrypriv.power_mgnt;// PS_MODE_MIN; + pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?_TRUE:_FALSE; + + pwrctrlpriv->bFwCurrentInPSMode = _FALSE; + + pwrctrlpriv->rpwm = 0; + pwrctrlpriv->cpwm = PS_STATE_S4; + + pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; + pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps; + pwrctrlpriv->bcn_ant_mode = 0; + pwrctrlpriv->dtim = 0; + + pwrctrlpriv->tog = 0x80; + +#ifdef CONFIG_LPS_LCLK + rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&pwrctrlpriv->rpwm)); + + _init_workitem(&pwrctrlpriv->cpwm_event, cpwm_event_callback, NULL); + +#ifdef CONFIG_LPS_RPWM_TIMER + pwrctrlpriv->brpwmtimeout = _FALSE; + _init_workitem(&pwrctrlpriv->rpwmtimeoutwi, rpwmtimeout_workitem_callback, NULL); + _init_timer(&pwrctrlpriv->pwr_rpwm_timer, padapter->pnetdev, pwr_rpwm_timeout_handler, padapter); +#endif // CONFIG_LPS_RPWM_TIMER +#endif // CONFIG_LPS_LCLK + + rtw_init_timer(&pwrctrlpriv->pwr_state_check_timer, padapter, pwr_state_check_handler); + + 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); + pwrctrlpriv->rtw_workqueue = create_singlethread_workqueue("rtw_workqueue"); + #endif //CONFIG_RESUME_IN_WORKQUEUE + + #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + pwrctrlpriv->early_suspend.suspend = NULL; + rtw_register_early_suspend(pwrctrlpriv); + #endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER + +#ifdef CONFIG_GPIO_WAKEUP + /*default low active*/ + pwrctrlpriv->is_high_active = HIGH_ACTIVE; + val8 = (pwrctrlpriv->is_high_active == 0) ? 1 : 0; + rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); + rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); + DBG_871X("%s: set GPIO_%d %d as default.\n", + __func__, WAKEUP_GPIO_IDX, val8); +#endif /* CONFIG_GPIO_WAKEUP */ + +#ifdef CONFIG_WOWLAN + pwrctrlpriv->wowlan_pattern_idx = 0; + for (i = 0 ; i < MAX_WKFM_NUM; i++) { + _rtw_memset(pwrctrlpriv->patterns[i].content, '\0', + sizeof(pwrctrlpriv->patterns[i].content)); + _rtw_memset(pwrctrlpriv->patterns[i].mask, '\0', + sizeof(pwrctrlpriv->patterns[i].mask)); + pwrctrlpriv->patterns[i].len = 0; + } + +#ifdef CONFIG_PNO_SUPPORT + pwrctrlpriv->pno_inited = _FALSE; + pwrctrlpriv->pnlo_info = NULL; + pwrctrlpriv->pscan_info = NULL; + pwrctrlpriv->pno_ssid_list = NULL; + pwrctrlpriv->pno_in_resume = _TRUE; +#endif /* CONFIG_PNO_SUPPORT */ +#endif /* CONFIG_WOWLAN */ + +_func_exit_; + +} + + +void rtw_free_pwrctrl_priv(PADAPTER adapter) +{ + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter); + +#if defined(CONFIG_CONCURRENT_MODE) + if (adapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + +_func_enter_; + + //_rtw_memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); + + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + if (pwrctrlpriv->rtw_workqueue) { + flush_workqueue(pwrctrlpriv->rtw_workqueue); + destroy_workqueue(pwrctrlpriv->rtw_workqueue); + } + #endif + +#ifdef CONFIG_WOWLAN +#ifdef CONFIG_PNO_SUPPORT + if (pwrctrlpriv->pnlo_info != NULL) + printk("****** pnlo_info memory leak********\n"); + + if (pwrctrlpriv->pscan_info != NULL) + printk("****** pscan_info memory leak********\n"); + + if (pwrctrlpriv->pno_ssid_list != NULL) + printk("****** pno_ssid_list memory leak********\n"); +#endif +#endif /* CONFIG_WOWLAN */ + + #if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + rtw_unregister_early_suspend(pwrctrlpriv); + #endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER + + _free_pwrlock(&pwrctrlpriv->lock); + _free_pwrlock(&pwrctrlpriv->check_32k_lock); + +_func_exit_; +} + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +extern int rtw_resume_process(_adapter *padapter); + +static void resume_workitem_callback(struct work_struct *work) +{ + struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, resume_work); + struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv); + _adapter *adapter = dvobj->padapters[IFACE_ID0]; + + DBG_871X("%s\n",__FUNCTION__); + + rtw_resume_process(adapter); + + rtw_resume_unlock_suspend(); +} + +void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv) +{ + // accquire system's suspend lock preventing from falliing asleep while resume in workqueue + //rtw_lock_suspend(); + + rtw_resume_lock_suspend(); + + #if 1 + queue_work(pwrpriv->rtw_workqueue, &pwrpriv->resume_work); + #else + _set_workitem(&pwrpriv->resume_work); + #endif +} +#endif //CONFIG_RESUME_IN_WORKQUEUE + +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) +inline bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv) +{ + return (pwrpriv->early_suspend.suspend) ? _TRUE : _FALSE; +} + +inline bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv) +{ + return (pwrpriv->do_late_resume) ? _TRUE : _FALSE; +} + +inline void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable) +{ + pwrpriv->do_late_resume = enable; +} +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND +extern int rtw_resume_process(_adapter *padapter); +static void rtw_early_suspend(struct early_suspend *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + DBG_871X("%s\n",__FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); +} + +static void rtw_late_resume(struct early_suspend *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv); + _adapter *adapter = dvobj->padapters[IFACE_ID0]; + + DBG_871X("%s\n",__FUNCTION__); + + if(pwrpriv->do_late_resume) { + rtw_set_do_late_resume(pwrpriv, _FALSE); + rtw_resume_process(adapter); + } +} + +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + DBG_871X("%s\n", __FUNCTION__); + + //jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit + pwrpriv->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20; + pwrpriv->early_suspend.suspend = rtw_early_suspend; + pwrpriv->early_suspend.resume = rtw_late_resume; + register_early_suspend(&pwrpriv->early_suspend); + + +} + +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); + + if (pwrpriv->early_suspend.suspend) + unregister_early_suspend(&pwrpriv->early_suspend); + + pwrpriv->early_suspend.suspend = NULL; + pwrpriv->early_suspend.resume = NULL; +} +#endif //CONFIG_HAS_EARLYSUSPEND + +#ifdef CONFIG_ANDROID_POWER +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +extern int rtw_resume_process(PADAPTER padapter); +#endif +static void rtw_early_suspend(android_early_suspend_t *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + DBG_871X("%s\n",__FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); +} + +static void rtw_late_resume(android_early_suspend_t *h) +{ + struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend); + struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv); + _adapter *adapter = dvobj->padapters[IFACE_ID0]; + + DBG_871X("%s\n",__FUNCTION__); + if(pwrpriv->do_late_resume) { + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + rtw_set_do_late_resume(pwrpriv, _FALSE); + rtw_resume_process(adapter); + #endif + } +} + +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + DBG_871X("%s\n", __FUNCTION__); + + //jeff: set the early suspend level before blank screen, so we wll do late resume after scree is lit + pwrpriv->early_suspend.level = ANDROID_EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 20; + pwrpriv->early_suspend.suspend = rtw_early_suspend; + pwrpriv->early_suspend.resume = rtw_late_resume; + android_register_early_suspend(&pwrpriv->early_suspend); +} + +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv) +{ + DBG_871X("%s\n", __FUNCTION__); + + rtw_set_do_late_resume(pwrpriv, _FALSE); + + if (pwrpriv->early_suspend.suspend) + android_unregister_early_suspend(&pwrpriv->early_suspend); + + pwrpriv->early_suspend.suspend = NULL; + pwrpriv->early_suspend.resume = NULL; +} +#endif //CONFIG_ANDROID_POWER + +u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val) +{ + u8 bResult = _TRUE; + rtw_hal_intf_ps_func(padapter,efunc_id,val); + + return bResult; +} + + +inline void rtw_set_ips_deny(_adapter *padapter, u32 ms) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms); +} + +/* +* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend +* @adapter: pointer to _adapter structure +* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup +* Return _SUCCESS or _FAIL +*/ + +int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj); + struct mlme_priv *pmlmepriv; + int ret = _SUCCESS; + int i; + u32 start = rtw_get_current_time(); + + /* for LPS */ + LeaveAllPowerSaveMode(padapter); + + /* IPS still bound with primary adapter */ + padapter = GET_PRIMARY_ADAPTER(padapter); + pmlmepriv = &padapter->mlmepriv; + + if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); + + + if (pwrpriv->ps_processing) { + DBG_871X("%s wait ps_processing...\n", __func__); + while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) + rtw_msleep_os(10); + if (pwrpriv->ps_processing) + DBG_871X("%s wait ps_processing timeout\n", __func__); + else + DBG_871X("%s wait ps_processing done\n", __func__); + } + +#ifdef DBG_CONFIG_ERROR_DETECT + if (rtw_hal_sreset_inprogress(padapter)) { + DBG_871X("%s wait sreset_inprogress...\n", __func__); + while (rtw_hal_sreset_inprogress(padapter) && rtw_get_passing_time_ms(start) <= 4000) + rtw_msleep_os(10); + if (rtw_hal_sreset_inprogress(padapter)) + DBG_871X("%s wait sreset_inprogress timeout\n", __func__); + else + DBG_871X("%s wait sreset_inprogress done\n", __func__); + } +#endif + + if (pwrpriv->bInternalAutoSuspend == _FALSE && pwrpriv->bInSuspend) { + DBG_871X("%s wait bInSuspend...\n", __func__); + while (pwrpriv->bInSuspend + && ((rtw_get_passing_time_ms(start) <= 3000 && !rtw_is_do_late_resume(pwrpriv)) + || (rtw_get_passing_time_ms(start) <= 500 && rtw_is_do_late_resume(pwrpriv))) + ) { + rtw_msleep_os(10); + } + if (pwrpriv->bInSuspend) + DBG_871X("%s wait bInSuspend timeout\n", __func__); + else + DBG_871X("%s wait bInSuspend done\n", __func__); + } + + //System suspend is not allowed to wakeup + if((pwrpriv->bInternalAutoSuspend == _FALSE) && (_TRUE == pwrpriv->bInSuspend )){ + ret = _FAIL; + goto exit; + } + + //block??? + if((pwrpriv->bInternalAutoSuspend == _TRUE) && (padapter->net_closed == _TRUE)) { + ret = _FAIL; + goto exit; + } + + //I think this should be check in IPS, LPS, autosuspend functions... + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) + { +#if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + if(_TRUE==pwrpriv->bInternalAutoSuspend){ + if(0==pwrpriv->autopm_cnt){ + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,33)) + if (usb_autopm_get_interface(adapter_to_dvobj(padapter)->pusbintf) < 0) + { + DBG_871X( "can't get autopm: \n"); + } + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,20)) + usb_autopm_disable(adapter_to_dvobj(padapter)->pusbintf); + #else + usb_autoresume_device(adapter_to_dvobj(padapter)->pusbdev, 1); + #endif + pwrpriv->autopm_cnt++; + } +#endif //#if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + ret = _SUCCESS; + goto exit; +#if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + } +#endif //#if defined (CONFIG_BT_COEXIST)&& defined (CONFIG_AUTOSUSPEND) + } + + if(rf_off == pwrpriv->rf_pwrstate ) + { +#ifdef CONFIG_USB_HCI +#ifdef CONFIG_AUTOSUSPEND + if(pwrpriv->brfoffbyhw==_TRUE) + { + DBG_8192C("hw still in rf_off state ...........\n"); + ret = _FAIL; + goto exit; + } + else if(padapter->registrypriv.usbss_enable) + { + DBG_8192C("%s call autoresume_enter....\n",__FUNCTION__); + if(_FAIL == autoresume_enter(padapter)) + { + DBG_8192C("======> autoresume fail.............\n"); + ret = _FAIL; + goto exit; + } + } + else +#endif +#endif + { +#ifdef CONFIG_IPS + DBG_8192C("%s call ips_leave....\n",__FUNCTION__); + if(_FAIL == ips_leave(padapter)) + { + DBG_8192C("======> ips_leave fail.............\n"); + ret = _FAIL; + goto exit; + } +#endif + } + } + + //TODO: the following checking need to be merged... + if (rtw_is_drv_stopped(padapter) + || !padapter->bup + || !rtw_is_hw_init_completed(padapter) + ) { + DBG_8192C("%s: bDriverStopped=%s, bup=%d, hw_init_completed=%u\n" + , caller + , rtw_is_drv_stopped(padapter)?"True":"False" + , padapter->bup + , rtw_get_hw_init_completed(padapter)); + ret= _FALSE; + goto exit; + } + +exit: + if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) + pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); + return ret; + +} + +int rtw_pm_set_lps(_adapter *padapter, u8 mode) +{ + int ret = 0; + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + if ( mode < PS_MODE_NUM ) + { + if(pwrctrlpriv->power_mgnt !=mode) + { + if(PS_MODE_ACTIVE == mode) + { + LeaveAllPowerSaveMode(padapter); + } + else + { + pwrctrlpriv->LpsIdleCount = 2; + } + pwrctrlpriv->power_mgnt = mode; + pwrctrlpriv->bLeisurePs = (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?_TRUE:_FALSE; + } + } + else + { + ret = -EINVAL; + } + + return ret; +} + +int rtw_pm_set_ips(_adapter *padapter, u8 mode) +{ + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + if( mode == IPS_NORMAL || mode == IPS_LEVEL_2 ) { + rtw_ips_mode_req(pwrctrlpriv, mode); + DBG_871X("%s %s\n", __FUNCTION__, mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2"); + return 0; + } + else if(mode ==IPS_NONE){ + rtw_ips_mode_req(pwrctrlpriv, mode); + DBG_871X("%s %s\n", __FUNCTION__, "IPS_NONE"); + if (!rtw_is_surprise_removed(padapter) && (_FAIL == rtw_pwr_wakeup(padapter))) + return -EFAULT; + } + else { + return -EINVAL; + } + return 0; +} + +/* + * ATTENTION: + * This function will request pwrctrl LOCK! + */ +void rtw_ps_deny(PADAPTER padapter, PS_DENY_REASON reason) +{ + struct pwrctrl_priv *pwrpriv; + s32 ret; + + +// DBG_871X("+" FUNC_ADPT_FMT ": Request PS deny for %d (0x%08X)\n", +// FUNC_ADPT_ARG(padapter), reason, BIT(reason)); + + pwrpriv = adapter_to_pwrctl(padapter); + + _enter_pwrlock(&pwrpriv->lock); + if (pwrpriv->ps_deny & BIT(reason)) + { + DBG_871X(FUNC_ADPT_FMT ": [WARNING] Reason %d had been set before!!\n", + FUNC_ADPT_ARG(padapter), reason); + } + pwrpriv->ps_deny |= BIT(reason); + _exit_pwrlock(&pwrpriv->lock); + +// DBG_871X("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n", +// FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); +} + +/* + * ATTENTION: + * This function will request pwrctrl LOCK! + */ +void rtw_ps_deny_cancel(PADAPTER padapter, PS_DENY_REASON reason) +{ + struct pwrctrl_priv *pwrpriv; + + +// DBG_871X("+" FUNC_ADPT_FMT ": Cancel PS deny for %d(0x%08X)\n", +// FUNC_ADPT_ARG(padapter), reason, BIT(reason)); + + pwrpriv = adapter_to_pwrctl(padapter); + + _enter_pwrlock(&pwrpriv->lock); + if ((pwrpriv->ps_deny & BIT(reason)) == 0) + { + DBG_871X(FUNC_ADPT_FMT ": [ERROR] Reason %d had been canceled before!!\n", + FUNC_ADPT_ARG(padapter), reason); + } + pwrpriv->ps_deny &= ~BIT(reason); + _exit_pwrlock(&pwrpriv->lock); + +// DBG_871X("-" FUNC_ADPT_FMT ": Now PS deny for 0x%08X\n", +// FUNC_ADPT_ARG(padapter), pwrpriv->ps_deny); +} + +/* + * ATTENTION: + * Before calling this function pwrctrl lock should be occupied already, + * otherwise it may return incorrect value. + */ +u32 rtw_ps_deny_get(PADAPTER padapter) +{ + u32 deny; + + + deny = adapter_to_pwrctl(padapter)->ps_deny; + + return deny; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_recv.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_recv.c new file mode 100644 index 00000000..75dffd41 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_recv.c @@ -0,0 +1,4963 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_RECV_C_ + +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS +void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS); + +enum { + SIGNAL_STAT_CALC_PROFILE_0 = 0, + SIGNAL_STAT_CALC_PROFILE_1, + SIGNAL_STAT_CALC_PROFILE_MAX +}; + +u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][2] = { + {4, 1}, /* Profile 0 => pre_stat : curr_stat = 4 : 1 */ + {3, 7} /* Profile 1 => pre_stat : curr_stat = 3 : 7 */ +}; + +#ifndef RTW_SIGNAL_STATE_CALC_PROFILE +#define RTW_SIGNAL_STATE_CALC_PROFILE SIGNAL_STAT_CALC_PROFILE_1 +#endif + +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) +{ + + +_func_enter_; + + _rtw_memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv)); + + _rtw_spinlock_init(&psta_recvpriv->lock); + + //for(i=0; iblk_strms[i]); + + _rtw_init_queue(&psta_recvpriv->defrag_q); + +_func_exit_; + +} + +sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter) +{ + sint i; + + union recv_frame *precvframe; + + sint res=_SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv)); + + _rtw_spinlock_init(&precvpriv->lock); + + _rtw_init_queue(&precvpriv->free_recv_queue); + _rtw_init_queue(&precvpriv->recv_pending_queue); + _rtw_init_queue(&precvpriv->uc_swdec_pending_queue); + + precvpriv->adapter = padapter; + + 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); + + if(precvpriv->pallocated_frame_buf==NULL){ + res= _FAIL; + goto exit; + } + //_rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); + + precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ); + //precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - + // ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); + + precvframe = (union recv_frame*) precvpriv->precv_frame_buf; + + + for(i=0; i < NR_RECVFRAME ; i++) + { + _rtw_init_listhead(&(precvframe->u.list)); + + rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue)); + + res = rtw_os_recv_resource_alloc(padapter, precvframe); + + precvframe->u.hdr.len = 0; + + precvframe->u.hdr.adapter =padapter; + precvframe++; + + } + +#ifdef CONFIG_USB_HCI + + ATOMIC_SET(&(precvpriv->rx_pending_cnt), 1); + + _rtw_init_sema(&precvpriv->allrxreturnevt, 0); + +#endif + + res = rtw_hal_init_recv_priv(padapter); + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_init_timer(&precvpriv->signal_stat_timer, padapter, RTW_TIMER_HDL_NAME(signal_stat)); + + precvpriv->signal_stat_sampling_interval = 2000; //ms + //precvpriv->signal_stat_converging_constant = 5000; //ms + + rtw_set_signal_stat_timer(precvpriv); +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +exit: + +_func_exit_; + + return res; + +} + +void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv); +void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv) +{ + _rtw_spinlock_free(&precvpriv->lock); +#ifdef CONFIG_RECV_THREAD_MODE + _rtw_free_sema(&precvpriv->recv_sema); + _rtw_free_sema(&precvpriv->terminate_recvthread_sema); +#endif + + _rtw_spinlock_free(&precvpriv->free_recv_queue.lock); + _rtw_spinlock_free(&precvpriv->recv_pending_queue.lock); + + _rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock); + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + _rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock); +#endif // CONFIG_USE_USB_BUFFER_ALLOC_RX +} + +void _rtw_free_recv_priv (struct recv_priv *precvpriv) +{ + _adapter *padapter = precvpriv->adapter; + +_func_enter_; + + rtw_free_uc_swdec_pending_queue(padapter); + + rtw_mfree_recv_priv_lock(precvpriv); + + rtw_os_recv_resource_free(precvpriv); + + if(precvpriv->pallocated_frame_buf) { + rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); + } + + rtw_hal_free_recv_priv(padapter); + +_func_exit_; + +} + +bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset) +{ +#define DBG_RFRAME_DEL_WFD_IE 0 + u8 *ies = rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + ies_offset; + uint ies_len_ori = rframe->u.hdr.len - (ies - rframe->u.hdr.rx_data); + uint ies_len; + + ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_RFRAME_DEL_WFD_IE ? __func__ : NULL); + rframe->u.hdr.len -= ies_len_ori - ies_len; + + return ies_len_ori != ies_len; +} + +union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue) +{ + + union recv_frame *precvframe; + _list *plist, *phead; + _adapter *padapter; + struct recv_priv *precvpriv; +_func_enter_; + + if(_rtw_queue_empty(pfree_recv_queue) == _TRUE) + { + precvframe = NULL; + } + else + { + phead = get_list_head(pfree_recv_queue); + + plist = get_next(phead); + + precvframe = LIST_CONTAINOR(plist, union recv_frame, u); + + rtw_list_delete(&precvframe->u.hdr.list); + padapter=precvframe->u.hdr.adapter; + if(padapter !=NULL){ + precvpriv=&padapter->recvpriv; + if(pfree_recv_queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt--; + } + } + +_func_exit_; + + return precvframe; + +} + +union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue) +{ + _irqL irqL; + union recv_frame *precvframe; + + _enter_critical_bh(&pfree_recv_queue->lock, &irqL); + + precvframe = _rtw_alloc_recvframe(pfree_recv_queue); + + _exit_critical_bh(&pfree_recv_queue->lock, &irqL); + + return precvframe; +} + +void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv) +{ + /* Perry: This can be removed */ + _rtw_init_listhead(&precvframe->u.hdr.list); + + precvframe->u.hdr.len=0; +} + +int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue) +{ + _irqL irqL; + _adapter *padapter=precvframe->u.hdr.adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + +_func_enter_; + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type > PRIMARY_ADAPTER) + { + padapter = padapter->pbuddy_adapter;//get primary_padapter + precvpriv = &padapter->recvpriv; + pfree_recv_queue = &precvpriv->free_recv_queue; + precvframe->u.hdr.adapter = padapter; + } +#endif + + rtw_os_free_recvframe(precvframe); + + + _enter_critical_bh(&pfree_recv_queue->lock, &irqL); + + rtw_list_delete(&(precvframe->u.hdr.list)); + + precvframe->u.hdr.len = 0; + + rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue)); + + if(padapter !=NULL){ + if(pfree_recv_queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt++; + } + + _exit_critical_bh(&pfree_recv_queue->lock, &irqL); + +_func_exit_; + + return _SUCCESS; + +} + + + + +sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + + _adapter *padapter=precvframe->u.hdr.adapter; + struct recv_priv *precvpriv = &padapter->recvpriv; + +_func_enter_; + + //_rtw_init_listhead(&(precvframe->u.hdr.list)); + rtw_list_delete(&(precvframe->u.hdr.list)); + + + rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue)); + + if (padapter != NULL) { + if (queue == &precvpriv->free_recv_queue) + precvpriv->free_recvframe_cnt++; + } + +_func_exit_; + + return _SUCCESS; +} + +sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + sint ret; + _irqL irqL; + + //_spinlock(&pfree_recv_queue->lock); + _enter_critical_bh(&queue->lock, &irqL); + ret = _rtw_enqueue_recvframe(precvframe, queue); + //_rtw_spinunlock(&pfree_recv_queue->lock); + _exit_critical_bh(&queue->lock, &irqL); + + return ret; +} + +/* +sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue) +{ + return rtw_free_recvframe(precvframe, queue); +} +*/ + + + + +/* +caller : defrag ; recvframe_chk_defrag in recv_thread (passive) +pframequeue: defrag_queue : will be accessed in recv_thread (passive) + +using spinlock to protect + +*/ + +void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue) +{ + union recv_frame *precvframe; + _list *plist, *phead; + +_func_enter_; + _rtw_spinlock(&pframequeue->lock); + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + precvframe = LIST_CONTAINOR(plist, union recv_frame, u); + + plist = get_next(plist); + + //rtw_list_delete(&precvframe->u.hdr.list); // will do this in rtw_free_recvframe() + + rtw_free_recvframe(precvframe, pfree_recv_queue); + } + + _rtw_spinunlock(&pframequeue->lock); + +_func_exit_; + +} + +u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter) +{ + u32 cnt = 0; + union recv_frame *pending_frame; + while((pending_frame=rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { + rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); + cnt++; + } + + if (cnt) + DBG_871X(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt); + + return cnt; +} + + +sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue) +{ + _irqL irqL; + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_delete(&precvbuf->list); + rtw_list_insert_head(&precvbuf->list, get_list_head(queue)); + + _exit_critical_bh(&queue->lock, &irqL); + + return _SUCCESS; +} + +sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue) +{ + _irqL irqL; +#ifdef CONFIG_SDIO_HCI + _enter_critical_bh(&queue->lock, &irqL); +#else + _enter_critical_ex(&queue->lock, &irqL); +#endif/*#ifdef CONFIG_SDIO_HCI*/ + + rtw_list_delete(&precvbuf->list); + + rtw_list_insert_tail(&precvbuf->list, get_list_head(queue)); +#ifdef CONFIG_SDIO_HCI + _exit_critical_bh(&queue->lock, &irqL); +#else + _exit_critical_ex(&queue->lock, &irqL); +#endif/*#ifdef CONFIG_SDIO_HCI*/ + return _SUCCESS; + +} + +struct recv_buf *rtw_dequeue_recvbuf (_queue *queue) +{ + _irqL irqL; + struct recv_buf *precvbuf; + _list *plist, *phead; + +#ifdef CONFIG_SDIO_HCI + _enter_critical_bh(&queue->lock, &irqL); +#else + _enter_critical_ex(&queue->lock, &irqL); +#endif/*#ifdef CONFIG_SDIO_HCI*/ + + if(_rtw_queue_empty(queue) == _TRUE) + { + precvbuf = NULL; + } + else + { + phead = get_list_head(queue); + + plist = get_next(phead); + + precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list); + + rtw_list_delete(&precvbuf->list); + + } + +#ifdef CONFIG_SDIO_HCI + _exit_critical_bh(&queue->lock, &irqL); +#else + _exit_critical_ex(&queue->lock, &irqL); +#endif/*#ifdef CONFIG_SDIO_HCI*/ + + return precvbuf; + +} + +sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe); +sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe){ + + sint i,res=_SUCCESS; + u32 datalen; + u8 miccode[8]; + u8 bmic_err=_FALSE,brpt_micerror = _TRUE; + u8 *pframe, *payload,*pframemic; + u8 *mickey; + //u8 *iv,rxdata_key_idx=0; + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib=&precvframe->u.hdr.attrib; + struct security_priv *psecuritypriv=&adapter->securitypriv; + + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); +_func_enter_; + + stainfo=rtw_get_stainfo(&adapter->stapriv ,&prxattrib->ta[0]); + + if(prxattrib->encrypt ==_TKIP_) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:prxattrib->encrypt ==_TKIP_\n")); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:da=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2],prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5])); + + //calculate mic code + if(stainfo!= NULL) + { + if(IS_MCAST(prxattrib->ra)) + { + //mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0]; + //iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; + //rxdata_key_idx =( ((iv[3])>>6)&0x3) ; + mickey=&psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0]; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic: bcmc key \n")); + //DBG_871X("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n", + // psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx); + + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n")); + DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"); + goto exit; + } + } + else{ + mickey=&stainfo->dot11tkiprxmickey.skey[0]; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic: unicast key \n")); + } + + datalen=precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;//icv_len included the mic code + pframe=precvframe->u.hdr.rx_data; + payload=pframe+prxattrib->hdrlen+prxattrib->iv_len; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n",prxattrib->iv_len,prxattrib->icv_len)); + + //rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data + + rtw_seccalctkipmic(mickey,pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data + + pframemic=payload+datalen; + + bmic_err=_FALSE; + + for(i=0;i<8;i++){ + if(miccode[i] != *(pframemic+i)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ",i,miccode[i],i,*(pframemic+i))); + bmic_err=_TRUE; + } + } + + + if(bmic_err==_TRUE){ + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-8)-*(pframemic-1)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + *(pframemic-8),*(pframemic-7),*(pframemic-6),*(pframemic-5),*(pframemic-4),*(pframemic-3),*(pframemic-2),*(pframemic-1))); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-16)-*(pframemic-9)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", + *(pframemic-16),*(pframemic-15),*(pframemic-14),*(pframemic-13),*(pframemic-12),*(pframemic-11),*(pframemic-10),*(pframemic-9))); + + { + uint i; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet (len=%d)======\n",precvframe->u.hdr.len)); + for(i=0;iu.hdr.len;i=i+8){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x", + *(precvframe->u.hdr.rx_data+i),*(precvframe->u.hdr.rx_data+i+1), + *(precvframe->u.hdr.rx_data+i+2),*(precvframe->u.hdr.rx_data+i+3), + *(precvframe->u.hdr.rx_data+i+4),*(precvframe->u.hdr.rx_data+i+5), + *(precvframe->u.hdr.rx_data+i+6),*(precvframe->u.hdr.rx_data+i+7))); + } + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet end [len=%d]======\n",precvframe->u.hdr.len)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n hrdlen=%d, \n",prxattrib->hdrlen)); + } + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ra=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey=%d ", + prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2], + prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5],psecuritypriv->binstallGrpkey)); + + // double check key_index for some timing issue , + // cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue + if((IS_MCAST(prxattrib->ra)==_TRUE) && (prxattrib->key_index != pmlmeinfo->key_index )) + brpt_micerror = _FALSE; + + if((prxattrib->bdecrypted ==_TRUE)&& (brpt_micerror == _TRUE)) + { + rtw_handle_tkip_mic_err(adapter, stainfo, (u8)IS_MCAST(prxattrib->ra)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" mic error :prxattrib->bdecrypted=%d ",prxattrib->bdecrypted)); + DBG_871X(" mic error :prxattrib->bdecrypted=%d\n",prxattrib->bdecrypted); + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" mic error :prxattrib->bdecrypted=%d ",prxattrib->bdecrypted)); + DBG_871X(" mic error :prxattrib->bdecrypted=%d\n",prxattrib->bdecrypted); + } + + res=_FAIL; + + } + else{ + //mic checked ok + if((psecuritypriv->bcheck_grpkey ==_FALSE)&&(IS_MCAST(prxattrib->ra)==_TRUE)){ + psecuritypriv->bcheck_grpkey =_TRUE; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->bcheck_grpkey =_TRUE")); + } + } + + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n")); + } + + recvframe_pull_tail(precvframe, 8); + + } + +exit: + +_func_exit_; + + return res; + +} + +//decrypt and set the ivlen,icvlen of the recv_frame +union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame); +union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame) +{ + + struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + union recv_frame *return_packet=precv_frame; + u32 res=_SUCCESS; + +_func_enter_; + + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n",prxattrib->bdecrypted,prxattrib->encrypt)); + + if(prxattrib->encrypt>0) + { + u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen; + prxattrib->key_index = ( ((iv[3])>>6)&0x3) ; + + if(prxattrib->key_index > WEP_KEYS) + { + DBG_871X("prxattrib->key_index(%d) > WEP_KEYS \n", prxattrib->key_index); + + switch(prxattrib->encrypt){ + case _WEP40_: + case _WEP104_: + prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex; + break; + case _TKIP_: + case _AES_: + default: + prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; + break; + } + } + } + + if((prxattrib->encrypt>0) && ((prxattrib->bdecrypted==0) ||(psecuritypriv->sw_decrypt==_TRUE))) + { + +#ifdef CONFIG_CONCURRENT_MODE + if(!IS_MCAST(prxattrib->ra))//bc/mc packets use sw decryption for concurrent mode +#endif + psecuritypriv->hw_decrypted=_FALSE; + + #ifdef DBG_RX_DECRYPTOR + DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", + __FUNCTION__, + __LINE__, + prxattrib->bdecrypted, + prxattrib->encrypt, + psecuritypriv->hw_decrypted); + #endif + + switch(prxattrib->encrypt){ + case _WEP40_: + case _WEP104_: + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep); + rtw_wep_decrypt(padapter, (u8 *)precv_frame); + break; + case _TKIP_: + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip); + res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); + break; + case _AES_: + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes); + res = rtw_aes_decrypt(padapter, (u8 * )precv_frame); + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wapi); + rtw_sms4_decrypt(padapter, (u8 * )precv_frame); + break; +#endif + default: + break; + } + } + else if(prxattrib->bdecrypted==1 + && prxattrib->encrypt >0 + && (psecuritypriv->busetkipkey==1 || prxattrib->encrypt !=_TKIP_ ) + ) + { +#if 0 + if((prxstat->icv==1)&&(prxattrib->encrypt!=_AES_)) + { + psecuritypriv->hw_decrypted=_FALSE; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->hw_decrypted=_FALSE")); + + rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue); + + return_packet=NULL; + + } + else +#endif + { + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw); + + psecuritypriv->hw_decrypted=_TRUE; + #ifdef DBG_RX_DECRYPTOR + DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", + __FUNCTION__, + __LINE__, + prxattrib->bdecrypted, + prxattrib->encrypt, + psecuritypriv->hw_decrypted); + + #endif + } + } + else { + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown); + #ifdef DBG_RX_DECRYPTOR + DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", + __FUNCTION__, + __LINE__, + prxattrib->bdecrypted, + prxattrib->encrypt, + psecuritypriv->hw_decrypted); + #endif + } + + if(res == _FAIL) + { + rtw_free_recvframe(return_packet,&padapter->recvpriv.free_recv_queue); + return_packet = NULL; + } + else + { + prxattrib->bdecrypted = _TRUE; + } + //recvframe_chkmic(adapter, precv_frame); //move to recvframme_defrag function + +_func_exit_; + + return return_packet; + +} +//###set the security information in the recv_frame +union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame); +union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame) +{ + u8 *psta_addr = NULL; + u8 *ptr; + uint auth_alg; + struct recv_frame_hdr *pfhdr; + struct sta_info *psta; + struct sta_priv *pstapriv ; + union recv_frame *prtnframe; + u16 ether_type=0; + u16 eapol_type = 0x888e;//for Funia BD's WPA issue + struct rx_pkt_attrib *pattrib; + +_func_enter_; + + pstapriv = &adapter->stapriv; + + auth_alg = adapter->securitypriv.dot11AuthAlgrthm; + + ptr = get_recvframe_data(precv_frame); + pfhdr = &precv_frame->u.hdr; + pattrib = &pfhdr->attrib; + psta_addr = pattrib->ta; + + prtnframe = NULL; + + psta = rtw_get_stainfo(pstapriv, psta_addr); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n",adapter->securitypriv.dot11AuthAlgrthm)); + + if(auth_alg==2) + { + if ((psta!=NULL) && (psta->ieee8021x_blocked)) + { + //blocked + //only accept EAPOL frame + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==1\n")); + + prtnframe=precv_frame; + + //get ether_type + ptr=ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE; + _rtw_memcpy(ðer_type,ptr, 2); + ether_type= ntohs((unsigned short )ether_type); + + if (ether_type == eapol_type) { + prtnframe=precv_frame; + } + else { + //free this frame + rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue); + prtnframe=NULL; + } + } + else + { + //allowed + //check decryption status, and decrypt the frame if needed + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==0\n")); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:precv_frame->hdr.attrib.privacy=%x\n",precv_frame->u.hdr.attrib.privacy)); + + if (pattrib->bdecrypted == 0) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:prxstat->decrypted=%x\n", pattrib->bdecrypted)); + } + + prtnframe=precv_frame; + //check is the EAPOL frame or not (Rekey) + //if(ether_type == eapol_type){ + // RT_TRACE(_module_rtl871x_recv_c_,_drv_notice_,("########portctrl:ether_type == 0x888e\n")); + //check Rekey + + // prtnframe=precv_frame; + //} + //else{ + // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:ether_type=0x%04x\n", ether_type)); + //} + } + } + else + { + prtnframe=precv_frame; + } + +_func_exit_; + + return prtnframe; + +} + +sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache); +sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache) +{ + sint tid = precv_frame->u.hdr.attrib.priority; + + u16 seq_ctrl = ( (precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | + (precv_frame->u.hdr.attrib.frag_num & 0xf); + +_func_enter_; + + if(tid>15) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl, tid)); + + return _FAIL; + } + + if(1)//if(bretry) + { + if(seq_ctrl == prxcache->tid_rxseq[tid]) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, seq_ctrl=0x%x, tid=0x%x, tid_rxseq=0x%x\n", seq_ctrl, tid, prxcache->tid_rxseq[tid])); + + return _FAIL; + } + } + + prxcache->tid_rxseq[tid] = seq_ctrl; + +_func_exit_; + + return _SUCCESS; + +} + +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame); +void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + unsigned char pwrbit; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL; + + psta = rtw_get_stainfo(pstapriv, pattrib->src); + + pwrbit = GetPwrMgt(ptr); + + if(psta) + { + if(pwrbit) + { + if(!(psta->state & WIFI_SLEEP_STATE)) + { + //psta->state |= WIFI_SLEEP_STATE; + //pstapriv->sta_dz_bitmap |= BIT(psta->aid); + + stop_sta_xmit(padapter, psta); + + //DBG_871X("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); + } + } + else + { + if(psta->state & WIFI_SLEEP_STATE) + { + //psta->state ^= WIFI_SLEEP_STATE; + //pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); + + wakeup_sta_to_xmit(padapter, psta); + + //DBG_871X("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); + } + } + + } + +#endif +} + +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame); +void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_AP_MODE + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL; + + psta = rtw_get_stainfo(pstapriv, pattrib->src); + + if(!psta) return; + +#ifdef CONFIG_TDLS + if( !(psta->tdls_sta_state & TDLS_LINKED_STATE ) ) + { +#endif //CONFIG_TDLS + + if(!psta->qos_option) + return; + + if(!(psta->qos_info&0xf)) + return; + +#ifdef CONFIG_TDLS + } +#endif //CONFIG_TDLS + + if(psta->state&WIFI_SLEEP_STATE) + { + u8 wmmps_ac=0; + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + if(wmmps_ac) + { + if(psta->sleepq_ac_len>0) + { + //process received triggered frame + xmit_delivery_enabled_frames(padapter, psta); + } + else + { + //issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) + issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0); + } + } + + } + + +#endif + +} + +#ifdef CONFIG_TDLS +sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + sint ret = _SUCCESS; + u8 *paction = get_recvframe_data(precv_frame); + u8 category_field = 1; +#ifdef CONFIG_WFD + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a }; +#endif /* CONFIG_WFD */ + struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo); + + /* point to action field */ + paction+=pattrib->hdrlen + + pattrib->iv_len + + SNAP_SIZE + + ETH_TYPE_LEN + + PAYLOAD_TYPE_LEN + + category_field; + + DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(*paction), MAC_ARG(pattrib->src)); + + if (hal_chk_wl_func(adapter, WL_FUNC_TDLS) == _FALSE) { + DBG_871X("Ignore tdls frame since hal doesn't support tdls\n"); + ret = _FAIL; + return ret; + } + + if (ptdlsinfo->tdls_enable == _FALSE) { + DBG_871X("recv tdls frame, " + "but tdls haven't enabled\n"); + ret = _FAIL; + return ret; + } + + switch(*paction){ + case TDLS_SETUP_REQUEST: + ret=On_TDLS_Setup_Req(adapter, precv_frame); + break; + case TDLS_SETUP_RESPONSE: + ret=On_TDLS_Setup_Rsp(adapter, precv_frame); + break; + case TDLS_SETUP_CONFIRM: + ret=On_TDLS_Setup_Cfm(adapter, precv_frame); + break; + case TDLS_TEARDOWN: + ret=On_TDLS_Teardown(adapter, precv_frame); + break; + case TDLS_DISCOVERY_REQUEST: + ret=On_TDLS_Dis_Req(adapter, precv_frame); + break; + case TDLS_PEER_TRAFFIC_INDICATION: + ret=On_TDLS_Peer_Traffic_Indication(adapter, precv_frame); + break; + case TDLS_PEER_TRAFFIC_RESPONSE: + ret=On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); + break; +#ifdef CONFIG_TDLS_CH_SW + case TDLS_CHANNEL_SWITCH_REQUEST: + ret=On_TDLS_Ch_Switch_Req(adapter, precv_frame); + break; + case TDLS_CHANNEL_SWITCH_RESPONSE: + ret=On_TDLS_Ch_Switch_Rsp(adapter, precv_frame); + break; +#endif +#ifdef CONFIG_WFD + /* First byte of WFA OUI */ + case 0x50: + if (_rtw_memcmp(WFA_OUI, paction, 3)) { + /* Probe request frame */ + if (*(paction + 3) == 0x04) { + /* WFDTDLS: for sigma test, do not setup direct link automatically */ + ptdlsinfo->dev_discovered = _TRUE; + DBG_871X("recv tunneled probe request frame\n"); + issue_tunneled_probe_rsp(adapter, precv_frame); + } + /* Probe response frame */ + if (*(paction + 3) == 0x05) { + /* WFDTDLS: for sigma test, do not setup direct link automatically */ + ptdlsinfo->dev_discovered = _TRUE; + DBG_871X("recv tunneled probe response frame\n"); + } + } + break; +#endif /* CONFIG_WFD */ + default: + DBG_871X("receive TDLS frame %d but not support\n", *paction); + ret=_FAIL; + break; + } + +exit: + return ret; + +} +#endif /* CONFIG_TDLS */ + +void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta); +void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta) +{ + int sz; + struct sta_info *psta = NULL; + struct stainfo_stats *pstats = NULL; + struct rx_pkt_attrib *pattrib = & prframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + sz = get_recvframe_len(prframe); + precvpriv->rx_bytes += sz; + + padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; + + if( (!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))){ + padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++; + } + + if(sta) + psta = sta; + else + psta = prframe->u.hdr.psta; + + if(psta) + { + pstats = &psta->sta_stats; + + pstats->rx_data_pkts++; + pstats->rx_bytes += sz; + + /*record rx packets for every tid*/ + pstats->rx_data_qos_pkts[pattrib->priority]++; + +#ifdef CONFIG_TDLS + if(psta->tdls_sta_state & TDLS_LINKED_STATE) + { + struct sta_info *pap_sta = NULL; + pap_sta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + if(pap_sta) + { + pstats = &pap_sta->sta_stats; + pstats->rx_data_pkts++; + pstats->rx_bytes += sz; + } + } +#endif //CONFIG_TDLS + } + +#ifdef CONFIG_CHECK_LEAVE_LPS + traffic_check_for_leave_lps(padapter, _FALSE, 0); +#endif //CONFIG_LPS + +} + +sint sta2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta +); +sint sta2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta +) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + sint ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + u8 * sta_addr = NULL; + sint bmcast = IS_MCAST(pattrib->dst); + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#ifdef CONFIG_TDLS_CH_SW + struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info; +#endif + struct sta_info *ptdls_sta=NULL; + u8 *psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + //frame body located after [+2]: ether-type, [+1]: payload type + u8 *pframe_body = psnap_type+2+1; +#endif + +_func_enter_; + + //DBG_871X("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + + // filter packets that SA is myself or multicast or broadcast + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n")); + ret= _FAIL; + goto exit; + } + + if( (!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast) ){ + ret= _FAIL; + goto exit; + } + + if( _rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) ) { + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->src; + + } + else if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { +#ifdef CONFIG_TDLS + + /* direct link data transfer */ + if (ptdlsinfo->link_established == _TRUE) { + ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src); + if (ptdls_sta == NULL) { + ret=_FAIL; + goto exit; + } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + /* filter packets that SA is myself or multicast or broadcast */ + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { + ret= _FAIL; + goto exit; + } + /* da should be for me */ + if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { + ret= _FAIL; + goto exit; + } + /* check BSSID */ + if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { + ret= _FAIL; + goto exit; + } + +#ifdef CONFIG_TDLS_CH_SW + pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; + + if(ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { + if (!(pchsw_info->ch_sw_state & TDLS_PEER_AT_OFF_STATE)) { + DBG_871X("%s %d\n", __FUNCTION__, __LINE__); + issue_nulldata_to_TDLS_peer_STA(adapter, ptdls_sta->hwaddr, 0, 0, 0); + pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE; + /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */ + } + } +#endif + + /* process UAPSD tdls sta */ + process_pwrbit_data(adapter, precv_frame); + + /* if NULL-frame, check pwrbit */ + if ((GetFrameSubType(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) { + /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */ + if (GetPwrMgt(ptr)) { + /* it would be triggered when we are off channel and receiving NULL DATA */ + /* we can confirm that peer STA is at off channel */ + DBG_871X("TDLS: recv peer null frame with pwr bit 1\n"); + //ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; + } + + /* TODO: Updated BSSID's seq. */ + //DBG_871X("drop Null Data\n"); + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + ret= _FAIL; + goto exit; + } + + /* receive some of all TDLS management frames, process it at ON_TDLS */ + if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) { + ret= OnTDLS(adapter, precv_frame); + goto exit; + } + + if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + process_wmmps_data(adapter, precv_frame); + } + + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + + } + + sta_addr = pattrib->src; + + } + else +#endif /* CONFIG_TDLS */ + { + // For Station mode, sa and bssid should always be BSSID, and DA is my mac-address + if(!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN) ) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("bssid != TA under STATION_MODE; drop pkt\n")); + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->bssid; + } + + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + if (bmcast) + { + // For AP mode, if DA == MCAST, then BSSID should be also MCAST + if (!IS_MCAST(pattrib->bssid)){ + ret= _FAIL; + goto exit; + } + } + else // not mc-frame + { + // For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID + if(!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { + ret= _FAIL; + goto exit; + } + + sta_addr = pattrib->src; + } + + } + else if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + _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); + + sta_addr = mybssid; + } + else + { + ret = _FAIL; + } + + + + if(bmcast) + *psta = rtw_get_bcmc_stainfo(adapter); + else + *psta = rtw_get_stainfo(pstapriv, sta_addr); // get ap_info + +#ifdef CONFIG_TDLS + if(ptdls_sta != NULL) + { + *psta = ptdls_sta; + } +#endif //CONFIG_TDLS + + if (*psta == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under sta2sta_data_frame ; drop pkt\n")); +#ifdef CONFIG_MP_INCLUDED + if (adapter->registrypriv.mp_mode == 1) + { + if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + adapter->mppriv.rx_pktloss++; + } +#endif + ret= _FAIL; + goto exit; + } + +exit: +_func_exit_; + return ret; + +} + +sint ap2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ); +sint ap2sta_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + sint ret = _SUCCESS; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + u8 *mybssid = get_bssid(pmlmepriv); + u8 *myhwaddr = adapter_mac_addr(adapter); + sint bmcast = IS_MCAST(pattrib->dst); + +_func_enter_; + + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE + || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE ) + ) + { + + // filter packets that SA is myself or multicast or broadcast + if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s SA="MAC_FMT", myhwaddr="MAC_FMT"\n", + __FUNCTION__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr)); + #endif + ret= _FAIL; + goto exit; + } + + // da should be for me + if((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast)) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_, + (" ap2sta_data_frame: compare DA fail; DA="MAC_FMT"\n", MAC_ARG(pattrib->dst))); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s DA="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst)); + #endif + ret= _FAIL; + goto exit; + } + + + // check BSSID + if( _rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || + (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) ) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_, + (" ap2sta_data_frame: compare BSSID fail ; BSSID="MAC_FMT"\n", MAC_ARG(pattrib->bssid))); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("mybssid="MAC_FMT"\n", MAC_ARG(mybssid))); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s BSSID="MAC_FMT", mybssid="MAC_FMT"\n", + __FUNCTION__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid)); + DBG_871X( "this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddy_adapter->adapter_type ); + #endif + + if(!bmcast) + { + DBG_871X("issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); + issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + + ret= _FAIL; + goto exit; + } + + if(bmcast) + *psta = rtw_get_bcmc_stainfo(adapter); + else + *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get ap_info + + if (*psta == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ap2sta: can't get psta under STATION_MODE ; drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __FUNCTION__); + #endif + ret= _FAIL; + goto exit; + } + + if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + } + + if (GetFrameSubType(ptr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, precv_frame, *psta); + ret = RTW_RX_HANDLED; + goto exit; + } + + } + else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && + (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ) + { + _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); + + // + if(adapter->mppriv.bRTWSmbCfg==_FALSE) + _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 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + /* Special case */ + ret = RTW_RX_HANDLED; + goto exit; + } + else + { + if(_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)&& (!bmcast)) + { + *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get sta_info + if (*psta == NULL) + { + + //for AP multicast issue , modify by yiwei + static u32 send_issue_deauth_time=0; + + //DBG_871X("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); + + if(rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0 ) + { + send_issue_deauth_time = rtw_get_current_time(); + + DBG_871X("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); + + issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + } + } + } + + ret = _FAIL; + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__, get_fwstate(pmlmepriv)); + #endif + } + +exit: + +_func_exit_; + + return ret; + +} + +sint sta2ap_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ); +sint sta2ap_data_frame( + _adapter *adapter, + union recv_frame *precv_frame, + struct sta_info**psta ) +{ + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + unsigned char *mybssid = get_bssid(pmlmepriv); + sint ret=_SUCCESS; + +_func_enter_; + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + //For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR + if(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) + { + ret= _FAIL; + goto exit; + } + + *psta = rtw_get_stainfo(pstapriv, pattrib->src); + if (*psta == NULL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under AP_MODE; drop pkt\n")); + DBG_871X("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); + + issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + + ret = RTW_RX_HANDLED; + goto exit; + } + + process_pwrbit_data(adapter, precv_frame); + + if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + process_wmmps_data(adapter, precv_frame); + } + + if (GetFrameSubType(ptr) & BIT(6)) { + /* No data, will not indicate to upper layer, temporily count it here */ + count_rx_stats(adapter, precv_frame, *psta); + ret = RTW_RX_HANDLED; + 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); + // + if(adapter->mppriv.bRTWSmbCfg == _FALSE) + _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 = adapter_mac_addr(adapter); + if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { + ret = RTW_RX_HANDLED; + goto exit; + } + DBG_871X("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); + issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + ret = RTW_RX_HANDLED; + goto exit; + } + +exit: + +_func_exit_; + + return ret; + +} + +sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame); +sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *pframe = precv_frame->u.hdr.rx_data; + struct sta_info *psta=NULL; + //uint len = precv_frame->u.hdr.len; + + //DBG_871X("+validate_recv_ctrl_frame\n"); + + if (GetFrameType(pframe) != WIFI_CTRL_TYPE) + { + return _FAIL; + } + + //receive the frames that ra(a1) is my address + if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN)) + return _FAIL; + + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + if (psta==NULL) + { + return _FAIL; + } + + //for rx pkt statistics + psta->sta_stats.rx_ctrl_pkts++; + + //only handle ps-poll + if(GetFrameSubType(pframe) == WIFI_PSPOLL) + { +#ifdef CONFIG_AP_MODE + u16 aid; + u8 wmmps_ac=0; + + aid = GetAid(pframe); + if(psta->aid!=aid) + { + return _FAIL; + } + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(0); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(0); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(0); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(0); + break; + } + + if(wmmps_ac) + return _FAIL; + + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + DBG_871X("%s alive check-rx ps-poll\n", __func__); + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } + + if((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) + { + _irqL irqL; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta->sleepq_len--; + + if(psta->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + pxmitframe->attrib.triggered = 1; + + //DBG_871X("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + +#if 0 + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta->sleep_q.lock, &irqL); +#endif + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + if(psta->sleepq_len==0) + { + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //DBG_871X("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap); + + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + } + else + { + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + //DBG_871X("no buffered packets to xmit\n"); + if(pstapriv->tim_bitmap&BIT(psta->aid)) + { + if(psta->sleepq_len==0) + { + 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, 0); + } + else + { + DBG_871X("error!psta->sleepq_len=%d\n", psta->sleepq_len); + psta->sleepq_len=0; + } + + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + } + } + } +#endif //CONFIG_AP_MODE + } + else if(GetFrameSubType(pframe) == WIFI_NDPA) { +#ifdef CONFIG_BEAMFORMING + beamforming_get_ndpa_frame(padapter, precv_frame); +#endif/*CONFIG_BEAMFORMING*/ + } + + return _FAIL; + +} + +union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame); +sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame); +sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame) +{ + //struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n")); + +#if 0 + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_NATIVEAP_MLME + mgt_dispatcher(padapter, precv_frame); +#else + rtw_hostapd_mlme_rx(padapter, precv_frame); +#endif + } + else + { + mgt_dispatcher(padapter, precv_frame); + } +#endif + + precv_frame = recvframe_chk_defrag(padapter, precv_frame); + if (precv_frame == NULL) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,("%s: fragment packet\n",__FUNCTION__)); + return _SUCCESS; + } + + { + //for rx pkt statistics + struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data)); + if (psta) { + psta->sta_stats.rx_mgnt_pkts++; + if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON) + psta->sta_stats.rx_beacon_pkts++; + else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ) + psta->sta_stats.rx_probereq_pkts++; + else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) { + if (_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == _TRUE) + psta->sta_stats.rx_probersp_pkts++; + else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)) + || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))) + psta->sta_stats.rx_probersp_bm_pkts++; + else + psta->sta_stats.rx_probersp_uo_pkts++; + } + } + } + +#ifdef CONFIG_INTEL_PROXIM + if(padapter->proximity.proxim_on==_TRUE) + { + struct rx_pkt_attrib * pattrib=&precv_frame->u.hdr.attrib; + struct recv_stat* prxstat=( struct recv_stat * ) precv_frame->u.hdr.rx_head ; + u8 * pda,*psa,*pbssid,*ptr; + ptr=precv_frame->u.hdr.rx_data; + 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); + break; + + case 1: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + break; + + case 2: + _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + break; + + case 3: + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n")); + break; + + default: + break; + + } + pattrib->priority=0; + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24; + + padapter->proximity.proxim_rx(padapter,precv_frame); + } +#endif + mgt_dispatcher(padapter, precv_frame); + + return _SUCCESS; + +} + +sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame); +sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame) +{ + u8 bretry; + u8 *psa, *pda, *pbssid; + struct sta_info *psta = NULL; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &adapter->stapriv; + struct security_priv *psecuritypriv = &adapter->securitypriv; + sint ret = _SUCCESS; + +_func_enter_; + + bretry = GetRetry(ptr); + pda = get_da(ptr); + psa = get_sa(ptr); + pbssid = get_hdr_bssid(ptr); + + if(pbssid == NULL){ + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__); + #endif + ret= _FAIL; + goto exit; + } + + _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(adapter, precv_frame, &psta); + break; + + case 1: + _rtw_memcpy(pattrib->ra, pda, ETH_ALEN); + _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN); + ret = ap2sta_data_frame(adapter, precv_frame, &psta); + break; + + case 2: + _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN); + _rtw_memcpy(pattrib->ta, psa, ETH_ALEN); + ret = sta2ap_data_frame(adapter, precv_frame, &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; + + } + + if(ret ==_FAIL){ + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __FUNCTION__, pattrib->to_fr_ds, ret); + #endif + goto exit; + } else if (ret == RTW_RX_HANDLED) { + goto exit; + } + + + if(psta==NULL){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" after to_fr_ds_chk; psta==NULL \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__); + #endif + ret= _FAIL; + goto exit; + } + + //psta->rssi = prxcmd->rssi; + //psta->signal_quality= prxcmd->sq; + precv_frame->u.hdr.psta = psta; + + + pattrib->amsdu=0; + pattrib->ack_policy = 0; + //parsing QC field + if(pattrib->qos == 1) + { + pattrib->priority = GetPriority((ptr + 24)); + pattrib->ack_policy = GetAckpolicy((ptr + 24)); + pattrib->amsdu = GetAMsdu((ptr + 24)); + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 32 : 26; + + if(pattrib->priority!=0 && pattrib->priority!=3) + adapter->recvpriv.bIsAnyNonBEPkts = _TRUE; + else + adapter->recvpriv.bIsAnyNonBEPkts = _FALSE; + } + else + { + pattrib->priority=0; + pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24; + } + + + if(pattrib->order)//HT-CTRL 11n + { + pattrib->hdrlen += 4; + } + + precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; + + // decache, drop duplicate recv packets + if(recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decache : drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__); + #endif + ret= _FAIL; + goto exit; + } + + if(pattrib->privacy){ + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("validate_recv_data_frame:pattrib->privacy=%x\n", pattrib->privacy)); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n ^^^^^^^^^^^IS_MCAST(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib->ra[0],IS_MCAST(pattrib->ra))); + +#ifdef CONFIG_TDLS + if((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy==_AES_)) + { + pattrib->encrypt=psta->dot118021XPrivacy; + } + else +#endif //CONFIG_TDLS + GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra)); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n pattrib->encrypt=%d\n",pattrib->encrypt)); + + SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); + } + else + { + pattrib->encrypt = 0; + pattrib->iv_len = pattrib->icv_len = 0; + } + +exit: + +_func_exit_; + + return ret; +} + +#ifdef CONFIG_IEEE80211W +static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_frame) +{ + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct sta_info *psta; + struct sta_priv *pstapriv = &adapter->stapriv; + u8 type; + u8 subtype; + + type = GetFrameType(ptr); + subtype = GetFrameSubType(ptr); //bit(7)~bit(2) + + if (adapter->securitypriv.binstallBIPkey == _TRUE) + { + //unicast management frame decrypt + if(pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) && + (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) + { + u8 *ppp, *mgmt_DATA; + u32 data_len=0; + ppp = GetAddr2Ptr(ptr); + + pattrib->bdecrypted = 0; + pattrib->encrypt = _AES_; + pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr); + //set iv and icv length + SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); + _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); + _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); + //actual management data frame body + data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; + mgmt_DATA = rtw_zmalloc(data_len); + if(mgmt_DATA == NULL) + { + DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__); + goto validate_80211w_fail; + } + /* //dump the packet content before decrypt + { + int pp; + printk("pattrib->pktlen = %d =>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", ptr[pp]); + printk("\n"); + }*/ + + precv_frame = decryptor(adapter, precv_frame); + //save actual management data frame body + _rtw_memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len); + //overwrite the iv field + _rtw_memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len); + //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 + { + int pp; + printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", ptr[pp]); + printk("\n"); + }*/ + if(!precv_frame) + { + DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __FUNCTION__); + goto validate_80211w_fail; + } + } + else if(IS_MCAST(GetAddr1Ptr(ptr)) && + (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) + { + sint BIP_ret = _SUCCESS; + //verify BIP MME IE of broadcast/multicast de-auth/disassoc packet + BIP_ret = rtw_BIP_verify(adapter, (u8 * )precv_frame); + if(BIP_ret == _FAIL) + { + //DBG_871X("802.11w BIP verify fail\n"); + goto validate_80211w_fail; + } + else if(BIP_ret == RTW_RX_HANDLED) + { + 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, 0); */ + goto validate_80211w_fail; + } + }//802.11w protect + else + { + psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(ptr)); + + if (subtype == WIFI_ACTION && psta && psta->bpairwise_key_installed == _TRUE) { + //according 802.11-2012 standard, these five types are not robust types + if( ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED && + ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) + { + DBG_871X("action frame category=%d should robust\n", ptr[WLAN_HDR_A3_LEN]); + goto validate_80211w_fail; + } + } + else if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) + { + 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, IEEE80211W_RIGHT_KEY); + } + goto validate_80211w_fail; + } + } + } + return _SUCCESS; + +validate_80211w_fail: + return _FAIL; + +} +#endif //CONFIG_IEEE80211W + +static inline void dump_rx_packet(u8 *ptr) +{ + int i; + + DBG_871X("############################# \n"); + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + DBG_871X("############################# \n"); +} + +sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame); +sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame) +{ + //shall check frame subtype, to / from ds, da, bssid + + //then call check if rx seq/frag. duplicated. + + u8 type; + u8 subtype; + sint retval = _SUCCESS; + + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + + u8 *ptr = precv_frame->u.hdr.rx_data; + u8 ver =(unsigned char) (*ptr)&0x3 ; +#ifdef CONFIG_FIND_BEST_CHANNEL + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; +#endif + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &adapter->tdlsinfo; +#endif //CONFIG_TDLS +#ifdef CONFIG_WAPI_SUPPORT + PRT_WAPI_T pWapiInfo = &adapter->wapiInfo; + struct recv_frame_hdr *phdr = &precv_frame->u.hdr; + u8 wai_pkt = 0; + u16 sc; + u8 external_len = 0; +#endif + +_func_enter_; + +#ifdef CONFIG_FIND_BEST_CHANNEL + if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { + int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter)); + if (ch_set_idx >= 0) + pmlmeext->channel_set[ch_set_idx].rx_count++; + } +#endif + +#ifdef CONFIG_TDLS + if(ptdlsinfo->ch_sensing==1 && ptdlsinfo->cur_channel !=0){ + ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel-1]++; + } +#endif //CONFIG_TDLS + +#ifdef RTK_DMP_PLATFORM + if ( 0 ) + { + DBG_871X("++\n"); + { + int i; + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + + } + DBG_871X("--\n"); + } +#endif //RTK_DMP_PLATFORM + + //add version chk + if(ver!=0){ + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! (ver!=0)\n")); + retval= _FAIL; + DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err); + goto exit; + } + + type = GetFrameType(ptr); + subtype = GetFrameSubType(ptr); //bit(7)~bit(2) + + 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); +#ifdef CONFIG_WAPI_SUPPORT + sc = (pattrib->seq_num<<4) | pattrib->frag_num; +#endif + +#if 1 //Dump rx packets +{ + u8 bDumpRxPkt = 0; + + rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); + if (bDumpRxPkt == 1) //dump all rx packets + dump_rx_packet(ptr); + else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE)) + dump_rx_packet(ptr); + else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE)) + dump_rx_packet(ptr); +} +#endif + switch (type) + { + case WIFI_MGT_TYPE: //mgnt + DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt); +#ifdef CONFIG_IEEE80211W + if(validate_80211w_mgmt(adapter, precv_frame) == _FAIL) + { + retval = _FAIL; + DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err_80211w); + break; + } +#endif //CONFIG_IEEE80211W + + retval = validate_recv_mgnt_frame(adapter, precv_frame); + if (retval == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_mgnt_frame fail\n")); + DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err); + } + retval = _FAIL; // only data frame return _SUCCESS + break; + case WIFI_CTRL_TYPE: //ctrl + DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl); + retval = validate_recv_ctrl_frame(adapter, precv_frame); + if (retval == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_ctrl_frame fail\n")); + DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err); + } + retval = _FAIL; // only data frame return _SUCCESS + break; + case WIFI_DATA_TYPE: //data + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data); +#ifdef CONFIG_WAPI_SUPPORT + if(pattrib->qos) + external_len = 2; + else + external_len= 0; + + wai_pkt = rtw_wapi_is_wai_packet(adapter,ptr); + + phdr->bIsWaiPacket = wai_pkt; + + if(wai_pkt !=0){ + if(sc != adapter->wapiInfo.wapiSeqnumAndFragNum) + { + adapter->wapiInfo.wapiSeqnumAndFragNum = sc; + } + else + { + retval = _FAIL; + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_seq_err); + break; + } + } + else{ + + if(rtw_wapi_drop_for_key_absent(adapter,GetAddr2Ptr(ptr))){ + retval=_FAIL; + WAPI_TRACE(WAPI_RX,"drop for key absent for rx \n"); + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_key_err); + break; + } + } + +#endif + + pattrib->qos = (subtype & BIT(7))? 1:0; + retval = validate_recv_data_frame(adapter, precv_frame); + if (retval == _FAIL) + { + struct recv_priv *precvpriv = &adapter->recvpriv; + //RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail\n")); + precvpriv->rx_drop++; + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err); + } + else if (retval == _SUCCESS) + { +#ifdef DBG_RX_DUMP_EAP + u8 bDumpRxPkt; + u16 eth_type; + + // dump eapol + rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); + // get ether_type + _rtw_memcpy(ð_type, ptr + pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE, 2); + eth_type = ntohs((unsigned short) eth_type); + if ((bDumpRxPkt == 4) && (eth_type == 0x888e)) + dump_rx_packet(ptr); +#endif + } + else + { + DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled); + } + break; + default: + DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown); + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! type=0x%x\n", type)); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type=0x%x\n", type); + #endif + retval = _FAIL; + break; + } + +exit: + +_func_exit_; + + return retval; +} + + +//remove the wlanhdr and add the eth_hdr +#if 1 + +sint wlanhdr_to_ethhdr ( union recv_frame *precvframe); +sint wlanhdr_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; + +#ifdef CONFIG_AUTO_AP_MODE + if (0x8899 == pattrib->eth_type) + { + struct sta_info *psta = precvframe->u.hdr.psta; + + DBG_871X("wlan rx: got eth_type=0x%x\n", pattrib->eth_type); + + if (psta && psta->isrc && psta->pid>0) + { + u16 rx_pid; + + rx_pid = *(u16*)(ptr+rmv_len+2); + + DBG_871X("wlan rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n", + rx_pid, MAC_ARG(psta->hwaddr), psta->pid); + + if(rx_pid == psta->pid) + { + int i; + u16 len = *(u16*)(ptr+rmv_len+4); + //u16 ctrl_type = *(u16*)(ptr+rmv_len+6); + + //DBG_871X("RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type); + DBG_871X("RC: len=0x%x\n", len); + + for(i=0;idst, ETH_ALEN); + _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); + + if(!bsnaphdr) { + len = htons(len); + _rtw_memcpy(ptr+12, &len, 2); + } + } + +exiting: +_func_exit_; + return ret; + +} + +#else + +sint wlanhdr_to_ethhdr ( union recv_frame *precvframe) +{ + sint rmv_len; + u16 eth_type; + 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; + struct _vlan *pvlan = NULL; + +_func_enter_; + + psnap=(struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); + psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + if (psnap->dsap==0xaa && psnap->ssap==0xaa && psnap->ctrl==0x03) + { + if (_rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)) + bsnaphdr=_TRUE;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042; + else if (_rtw_memcmp(psnap->oui, SNAP_HDR_APPLETALK_DDP, WLAN_IEEE_OUI_LEN) && + _rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_DDP, 2) ) + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK; + else if (_rtw_memcmp( psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN)) + bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL; + else { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("drop pkt due to invalid frame format!\n")); + ret= _FAIL; + goto exit; + } + + } else + bsnaphdr=_FALSE;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS; + + rmv_len = pattrib->hdrlen + pattrib->iv_len +(bsnaphdr?SNAP_SIZE:0); + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n", pattrib->hdrlen, pattrib->iv_len)); + + if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) + { + ptr += rmv_len ; + *ptr = 0x87; + *(ptr+1) = 0x12; + + //back to original pointer + ptr -= rmv_len; + } + + ptr += rmv_len ; + + _rtw_memcpy(ð_type, ptr, 2); + eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type + ptr +=2; + + if(pattrib->encrypt){ + recvframe_pull_tail(precvframe, pattrib->icv_len); + } + + if(eth_type == 0x8100) //vlan + { + pvlan = (struct _vlan *) ptr; + + //eth_type = get_vlan_encap_proto(pvlan); + //eth_type = pvlan->h_vlan_encapsulated_proto;//? + rmv_len += 4; + ptr+=4; + } + + if(eth_type==0x0800)//ip + { + //struct iphdr* piphdr = (struct iphdr*) ptr; + //__u8 tos = (unsigned char)(pattrib->priority & 0xff); + + //piphdr->tos = tos; + + //if (piphdr->protocol == 0x06) + //{ + // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", precvframe->u.hdr.len)); + //} + } + else if(eth_type==0x8712)// append rx status for mp test packets + { + //ptr -= 16; + //_rtw_memcpy(ptr, get_rxmem(precvframe), 16); + } + else + { +#ifdef PLATFORM_OS_XP + NDIS_PACKET_8021Q_INFO VlanPriInfo; + UINT32 UserPriority = precvframe->u.hdr.attrib.priority; + UINT32 VlanID = (pvlan!=NULL ? get_vlan_id(pvlan) : 0 ); + + VlanPriInfo.Value = // Get current value. + NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo); + + VlanPriInfo.TagHeader.UserPriority = UserPriority; + VlanPriInfo.TagHeader.VlanId = VlanID ; + + VlanPriInfo.TagHeader.CanonicalFormatId = 0; // Should be zero. + VlanPriInfo.TagHeader.Reserved = 0; // Should be zero. + NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo) = VlanPriInfo.Value; +#endif + } + + if(eth_type==0x8712)// append rx status for mp test packets + { + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); + _rtw_memcpy(ptr, get_rxmem(precvframe), 24); + ptr+=24; + } + else + ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)); + + _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN); + _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); + + eth_type = htons((unsigned short)eth_type) ; + _rtw_memcpy(ptr+12, ð_type, 2); + +exit: + +_func_exit_; + + return ret; +} +#endif + + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#ifdef PLATFORM_LINUX +static void recvframe_expand_pkt( + PADAPTER padapter, + union recv_frame *prframe) +{ + struct recv_frame_hdr *pfhdr; + _pkt *ppkt; + u8 shift_sz; + u32 alloc_sz; + u8 *ptr; + + + pfhdr = &prframe->u.hdr; + + // 6 is for IP header 8 bytes alignment in QoS packet case. + if (pfhdr->attrib.qos) + shift_sz = 6; + else + shift_sz = 0; + + // for first fragment packet, need to allocate + // (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet + // 8 is for skb->data 8 bytes alignment. +// alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); + alloc_sz = 1664; // round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment + + //3 1. alloc new skb + // prepare extra space for 4 bytes alignment + ppkt = rtw_skb_alloc(alloc_sz); + + if (!ppkt) return; // no way to expand + + //3 2. Prepare new skb to replace & release old skb + // force ppkt->data at 8-byte alignment address + skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7)); + // force ip_hdr at 8-byte alignment address according to shift_sz + skb_reserve(ppkt, shift_sz); + + // copy data to new pkt + ptr = skb_put(ppkt, pfhdr->len); + if (ptr) + _rtw_memcpy(ptr, pfhdr->rx_data, pfhdr->len); + + rtw_skb_free(pfhdr->pkt); + + // attach new pkt to recvframe + pfhdr->pkt = ppkt; + pfhdr->rx_head = ppkt->head; + pfhdr->rx_data = ppkt->data; + pfhdr->rx_tail = skb_tail_pointer(ppkt); + pfhdr->rx_end = skb_end_pointer(ppkt); +} +#else +#warning "recvframe_expand_pkt not implement, defrag may crash system" +#endif +#endif + +//perform defrag +union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q); +union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q) +{ + _list *plist, *phead; + u8 *data,wlanhdr_offset; + u8 curfragnum; + struct recv_frame_hdr *pfhdr,*pnfhdr; + union recv_frame* prframe, *pnextrframe; + _queue *pfree_recv_queue; + +_func_enter_; + + curfragnum=0; + pfree_recv_queue=&adapter->recvpriv.free_recv_queue; + + phead = get_list_head(defrag_q); + plist = get_next(phead); + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pfhdr=&prframe->u.hdr; + rtw_list_delete(&(prframe->u.list)); + + if(curfragnum!=pfhdr->attrib.frag_num) + { + //the first fragment number must be 0 + //free the whole queue + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + + return NULL; + } + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#ifndef CONFIG_SDIO_RX_COPY + recvframe_expand_pkt(adapter, prframe); +#endif +#endif + + curfragnum++; + + plist= get_list_head(defrag_q); + + plist = get_next(plist); + + data=get_recvframe_data(prframe); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u); + pnfhdr=&pnextrframe->u.hdr; + + + //check the fragment sequence (2nd ~n fragment frame) + + if(curfragnum!=pnfhdr->attrib.frag_num) + { + //the fragment number must be increasing (after decache) + //release the defrag_q & prframe + rtw_free_recvframe(prframe, pfree_recv_queue); + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + return NULL; + } + + curfragnum++; + + //copy the 2nd~n fragment frame's payload to the first fragment + //get the 2nd~last fragment frame's payload + + wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; + + recvframe_pull(pnextrframe, wlanhdr_offset); + + //append to first fragment frame's tail (if privacy frame, pull the ICV) + recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); + + //memcpy + _rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); + + recvframe_put(prframe, pnfhdr->len); + + pfhdr->attrib.icv_len=pnfhdr->attrib.icv_len; + plist = get_next(plist); + + }; + + //free the defrag_q queue and return the prframe + rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Performance defrag!!!!!\n")); + +_func_exit_; + + return prframe; +} + +//check if need to defrag, if needed queue the frame to defrag_q +union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame) +{ + u8 ismfrag; + u8 fragnum; + u8 *psta_addr; + struct recv_frame_hdr *pfhdr; + struct sta_info *psta; + struct sta_priv *pstapriv; + _list *phead; + union recv_frame *prtnframe = NULL; + _queue *pfree_recv_queue, *pdefrag_q; + +_func_enter_; + + pstapriv = &padapter->stapriv; + + pfhdr = &precv_frame->u.hdr; + + pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + + //need to define struct of wlan header frame ctrl + ismfrag = pfhdr->attrib.mfrag; + fragnum = pfhdr->attrib.frag_num; + + psta_addr = pfhdr->attrib.ta; + psta = rtw_get_stainfo(pstapriv, psta_addr); + if (psta == NULL) + { + u8 type = GetFrameType(pfhdr->rx_data); + if (type != WIFI_DATA_TYPE) { + psta = rtw_get_bcmc_stainfo(padapter); + pdefrag_q = &psta->sta_recvpriv.defrag_q; + } else + pdefrag_q = NULL; + } + else + pdefrag_q = &psta->sta_recvpriv.defrag_q; + + if ((ismfrag==0) && (fragnum==0)) + { + prtnframe = precv_frame;//isn't a fragment frame + } + + if (ismfrag==1) + { + //0~(n-1) fragment frame + //enqueue to defraf_g + if(pdefrag_q != NULL) + { + if(fragnum==0) + { + //the first fragment + if(_rtw_queue_empty(pdefrag_q) == _FALSE) + { + //free current defrag_q + rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue); + } + } + + + //Then enqueue the 0~(n-1) fragment into the defrag_q + + //_rtw_spinlock(&pdefrag_q->lock); + phead = get_list_head(pdefrag_q); + rtw_list_insert_tail(&pfhdr->list, phead); + //_rtw_spinunlock(&pdefrag_q->lock); + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum)); + + prtnframe=NULL; + + } + else + { + //can't find this ta's defrag_queue, so free this recv_frame + rtw_free_recvframe(precv_frame, pfree_recv_queue); + prtnframe=NULL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum)); + } + + } + + if((ismfrag==0)&&(fragnum!=0)) + { + //the last fragment frame + //enqueue the last fragment + if(pdefrag_q != NULL) + { + //_rtw_spinlock(&pdefrag_q->lock); + phead = get_list_head(pdefrag_q); + rtw_list_insert_tail(&pfhdr->list,phead); + //_rtw_spinunlock(&pdefrag_q->lock); + + //call recvframe_defrag to defrag + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("defrag: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum)); + precv_frame = recvframe_defrag(padapter, pdefrag_q); + prtnframe=precv_frame; + + } + else + { + //can't find this ta's defrag_queue, so free this recv_frame + rtw_free_recvframe(precv_frame, pfree_recv_queue); + prtnframe=NULL; + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum)); + } + + } + + + if((prtnframe!=NULL)&&(prtnframe->u.hdr.attrib.privacy)) + { + //after defrag we must check tkip mic code + if(recvframe_chkmic(padapter, prtnframe)==_FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic(padapter, prtnframe)==_FAIL\n")); + rtw_free_recvframe(prtnframe,pfree_recv_queue); + prtnframe=NULL; + } + } + +_func_exit_; + + return prtnframe; + +} + +int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe) +{ + int a_len, padding_len; + u16 nSubframe_Length; + u8 nr_subframes, i; + u8 *pdata; + _pkt *sub_pkt,*subframes[MAX_SUBFRAME_COUNT]; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &(precvpriv->free_recv_queue); + int ret = _SUCCESS; + + nr_subframes = 0; + + recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); + + if(prframe->u.hdr.attrib.iv_len >0) + { + recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); + } + + a_len = prframe->u.hdr.len; + + pdata = prframe->u.hdr.rx_data; + + while(a_len > ETH_HLEN) { + + /* Offset 12 denote 2 mac address */ + nSubframe_Length = RTW_GET_BE16(pdata + 12); + + if( a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length) ) { + DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n",a_len,nSubframe_Length); + break; + } + + sub_pkt = rtw_os_alloc_msdu_pkt(prframe, nSubframe_Length, pdata); + if (sub_pkt == NULL) { + DBG_871X("%s(): allocate sub packet fail !!!\n",__FUNCTION__); + break; + } + + /* move the data point to data content */ + pdata += ETH_HLEN; + a_len -= ETH_HLEN; + + subframes[nr_subframes++] = sub_pkt; + + if(nr_subframes >= MAX_SUBFRAME_COUNT) { + DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n"); + break; + } + + pdata += nSubframe_Length; + a_len -= nSubframe_Length; + if(a_len != 0) { + padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1)); + if(padding_len == 4) { + padding_len = 0; + } + + if(a_len < padding_len) { + DBG_871X("ParseSubframe(): a_len < padding_len !\n"); + break; + } + pdata += padding_len; + a_len -= padding_len; + } + } + + for(i=0; iu.hdr.attrib); + } + } + + prframe->u.hdr.len = 0; + rtw_free_recvframe(prframe, pfree_recv_queue);//free this recv_frame + + return ret; +} + +int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num); +int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) +{ + PADAPTER padapter = preorder_ctrl->padapter; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + u8 wsize = preorder_ctrl->wsize_b; + u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;//% 4096; + + // Rx Reorder initialize condition. + if (preorder_ctrl->indicate_seq == 0xFFFF) + { + preorder_ctrl->indicate_seq = seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + + //DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq); + } + + //DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + // Drop out the packet which SeqNum is smaller than WinStart + if( SN_LESS(seq_num, preorder_ctrl->indicate_seq) ) + { + //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); + //DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__, + preorder_ctrl->indicate_seq, seq_num); + #endif + + + return _FALSE; + } + + // + // Sliding window manipulation. Conditions includes: + // 1. Incoming SeqNum is equal to WinStart =>Window shift 1 + // 2. Incoming SeqNum is larger than the WinEnd => Window shift N + // + if( SN_EQUAL(seq_num, preorder_ctrl->indicate_seq) ) + { + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + } + else if(SN_LESS(wend, seq_num)) + { + //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); + //DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + // boundary situation, when seq_num cross 0xFFF + if(seq_num >= (wsize - 1)) + preorder_ctrl->indicate_seq = seq_num + 1 -wsize; + else + preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; + pdbgpriv->dbg_rx_ampdu_window_shift_cnt++; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, seq_num); + #endif + } + + //DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); + + return _TRUE; +} + +int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe); +int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe) +{ + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + _list *phead, *plist; + union recv_frame *pnextrframe; + struct rx_pkt_attrib *pnextattrib; + + //DbgPrint("+enqueue_reorder_recvframe()\n"); + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + + while(rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); + pnextattrib = &pnextrframe->u.hdr.attrib; + + if(SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) + { + plist = get_next(plist); + } + else if( SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) + { + //Duplicate entry is found!! Do not insert current entry. + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); + + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + return _FALSE; + } + else + { + break; + } + + //DbgPrint("enqueue_reorder_recvframe():while\n"); + + } + + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + rtw_list_delete(&(prframe->u.hdr.list)); + + rtw_list_insert_tail(&(prframe->u.hdr.list), plist); + + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); + return _TRUE; + +} + +void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq); +void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq) +{ + if(current_seq < prev_seq) + { + pdbgpriv->dbg_rx_ampdu_loss_count+= (4096 + current_seq - prev_seq); + + } + else + { + pdbgpriv->dbg_rx_ampdu_loss_count+= (current_seq - prev_seq); + } +} +int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced); +int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced) +{ + //_irqL irql; + //u8 bcancelled; + _list *phead, *plist; + union recv_frame *prframe; + struct rx_pkt_attrib *pattrib; + //u8 index = 0; + int bPktInBuf = _FALSE; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder); + + //DbgPrint("+recv_indicatepkts_in_order\n"); + + //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinlock_ex(&ppending_recvframe_queue->lock); + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + +#if 0 + // Check if there is any other indication thread running. + if(pTS->RxIndicateState == RXTS_INDICATE_PROCESSING) + return; +#endif + + // Handling some condition for forced indicate case. + if(bforced==_TRUE) + { + pdbgpriv->dbg_rx_ampdu_forced_indicate_count++; + if(rtw_is_list_empty(phead)) + { + // _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + return _TRUE; + } + + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pattrib = &prframe->u.hdr.attrib; + + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + recv_indicatepkts_pkt_loss_cnt(pdbgpriv,preorder_ctrl->indicate_seq,pattrib->seq_num); + preorder_ctrl->indicate_seq = pattrib->seq_num; + + } + + // Prepare indication list and indication. + // Check if there is any packet need indicate. + while(!rtw_is_list_empty(phead)) + { + + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + pattrib = &prframe->u.hdr.attrib; + + if(!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, + ("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n", + preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu)); + +#if 0 + // This protect buffer from overflow. + if(index >= REORDER_WIN_SIZE) + { + RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!! \n")); + bPktInBuf = TRUE; + break; + } +#endif + + plist = get_next(plist); + rtw_list_delete(&(prframe->u.hdr.list)); + + if(SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) + { + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + } + +#if 0 + index++; + if(index==1) + { + //Cancel previous pending timer. + //PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer); + if(bforced!=_TRUE) + { + //DBG_871X("_cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);\n"); + _cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled); + } + } +#endif + + //Set this as a lock to make sure that only one thread is indicating packet. + //pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; + + // Indicate packets + //RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!! \n")); + + + //indicate this recv_frame + //DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num); + if(!pattrib->amsdu) + { + //DBG_871X("recv_indicatepkts_in_order, amsdu!=1, indicate_seq=%d, seq_num=%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num); + + if (!RTW_CANNOT_RUN(padapter)) + rtw_recv_indicatepkt(padapter, prframe);/*indicate this recv_frame*/ + + } + else if(pattrib->amsdu==1) + { + if(amsdu_to_msdu(padapter, prframe)!=_SUCCESS) + { + rtw_free_recvframe(prframe, &precvpriv->free_recv_queue); + } + } + else + { + //error condition; + } + + + //Update local variables. + bPktInBuf = _FALSE; + + } + else + { + bPktInBuf = _TRUE; + break; + } + + //DbgPrint("recv_indicatepkts_in_order():while\n"); + + } + + //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + +/* + //Release the indication lock and set to new indication step. + if(bPktInBuf) + { + // Set new pending timer. + //pTS->RxIndicateState = RXTS_INDICATE_REORDER; + //PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime); + //DBG_871X("_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME)\n"); + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + } + else + { + //pTS->RxIndicateState = RXTS_INDICATE_IDLE; + } +*/ + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + + //return _TRUE; + return bPktInBuf; + +} + +int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe); +int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe) +{ + _irqL irql; + int retval = _SUCCESS; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder); + + if(!pattrib->amsdu) + { + //s1. + 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)) + if (pattrib->qos!=1) + { + if (!RTW_CANNOT_RUN(padapter)) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n" )); + + rtw_recv_indicatepkt(padapter, prframe); + return _SUCCESS; + + } + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__); + #endif + + return _FAIL; + + } + + if (preorder_ctrl->enable == _FALSE) + { + //indicate this recv_frame + preorder_ctrl->indicate_seq = pattrib->seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + rtw_recv_indicatepkt(padapter, prframe); + + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + return _SUCCESS; + } + +#ifndef CONFIG_RECV_REORDERING_CTRL + //indicate this recv_frame + rtw_recv_indicatepkt(padapter, prframe); + return _SUCCESS; +#endif + + } + else if(pattrib->amsdu==1) //temp filter -> means didn't support A-MSDUs in a A-MPDU + { + if (preorder_ctrl->enable == _FALSE) + { + preorder_ctrl->indicate_seq = pattrib->seq_num; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + retval = amsdu_to_msdu(padapter, prframe); + + preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq, pattrib->seq_num); + #endif + + if(retval != _SUCCESS){ + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__); + #endif + } + + return retval; + } + } + else + { + + } + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irql); + + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, + ("recv_indicatepkt_reorder: indicate=%d seq=%d\n", + preorder_ctrl->indicate_seq, pattrib->seq_num)); + + //s2. check if winstart_b(indicate_seq) needs to been updated + if(!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) + { + pdbgpriv->dbg_rx_ampdu_drop_count++; + //pHTInfo->RxReorderDropCounter++; + //ReturnRFDList(Adapter, pRfd); + //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("RxReorderIndicatePacket() ==> Packet Drop!!\n")); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //return _FAIL; + + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__); + #endif +#if 0 + rtw_recv_indicatepkt(padapter, prframe); + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + + goto _success_exit; +#else + goto _err_exit; +#endif + } + + + //s3. Insert all packet into Reorder Queue to maintain its ordering. + if(!enqueue_reorder_recvframe(preorder_ctrl, prframe)) + { + //DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); + //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql); + //return _FAIL; + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__); + #endif + goto _err_exit; + } + + + //s4. + // Indication process. + // After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets + // with the SeqNum smaller than latest WinStart and buffer other packets. + // + // For Rx Reorder condition: + // 1. All packets with SeqNum smaller than WinStart => Indicate + // 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. + // + + //recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); + if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE)==_TRUE) + { + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + } + else + { + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + } + + +_success_exit: + + return _SUCCESS; + +_err_exit: + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + + return _FAIL; +} + + +void rtw_reordering_ctrl_timeout_handler(void *pcontext) +{ + _irqL irql; + struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; + _adapter *padapter = preorder_ctrl->padapter; + _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + + if (RTW_CANNOT_RUN(padapter)) + return; + + //DBG_871X("+rtw_reordering_ctrl_timeout_handler()=>\n"); + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irql); + + if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE)==_TRUE) + { + _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); + } + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); + +} + +int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe); +int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe) +{ + int retval = _SUCCESS; + //struct recv_priv *precvpriv = &padapter->recvpriv; + //struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_TDLS + struct sta_info *psta = prframe->u.hdr.psta; +#endif //CONFIG_TDLS + +#ifdef CONFIG_80211N_HT + + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + + DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate); + +#ifdef CONFIG_TDLS + if( (phtpriv->ht_option==_TRUE) || + ((psta->tdls_sta_state & TDLS_LINKED_STATE) && + (psta->htpriv.ht_option==_TRUE) && + (psta->htpriv.ampdu_enable==_TRUE))) //B/G/N Mode +#else + if(phtpriv->ht_option==_TRUE) //B/G/N Mode +#endif //CONFIG_TDLS + { + //prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; + + if(recv_indicatepkt_reorder(padapter, prframe)!=_SUCCESS)// including perform A-MPDU Rx Ordering Buffer Control + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__); + #endif + + if (!RTW_CANNOT_RUN(padapter)) { + retval = _FAIL; + return retval; + } + } + } + else //B/G mode +#endif + { + 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 (!RTW_CANNOT_RUN(padapter)) { + //indicate this recv_frame + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n" )); + rtw_recv_indicatepkt(padapter, prframe); + } + else + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n" )); + + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)" + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + retval = _FAIL; + return retval; + } + + } + + return retval; + +} + +#ifdef CONFIG_MP_INCLUDED +int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame) +{ + int ret = _SUCCESS; + u8 *ptr = precv_frame->u.hdr.rx_data; + u8 type,subtype; + + if(!adapter->mppriv.bmac_filter) + return ret; +#if 0 + if (1){ + u8 bDumpRxPkt; + type = GetFrameType(ptr); + subtype = GetFrameSubType(ptr); //bit(7)~bit(2) + + rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); + if(bDumpRxPkt ==1){//dump all rx packets + int i; + DBG_871X("############ type:0x%02x subtype:0x%02x ################# \n",type,subtype); + + for(i=0; i<64;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + DBG_871X("############################# \n"); + } + } +#endif + + if(_rtw_memcmp( GetAddr2Ptr(ptr), adapter->mppriv.mac_filter, ETH_ALEN) == _FALSE ) + ret = _FAIL; + + return ret; +} +#endif + +static sint MPwlanhdr_to_ethhdr ( union recv_frame *precvframe) +{ + sint rmv_len; + u16 eth_type, len; + u8 bsnaphdr; + u8 *psnap_type; + u8 mcastheadermac[]={0x01,0x00,0x5e}; + + 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); + } + + + len = htons(pattrib->seq_num); + //DBG_871X("wlan seq = %d ,seq_num =%x\n",len,pattrib->seq_num); + _rtw_memcpy(ptr+12,&len, 2); + if(adapter->mppriv.bRTWSmbCfg==_TRUE) + { +// if(_rtw_memcmp(mcastheadermac, pattrib->dst, 3) == _TRUE)//SimpleConfig Dest. +// _rtw_memcpy(ptr+ETH_ALEN, pattrib->bssid, ETH_ALEN); + + if(_rtw_memcmp(mcastheadermac, pattrib->bssid, 3) == _TRUE) //SimpleConfig Dest. + _rtw_memcpy(ptr, pattrib->bssid, ETH_ALEN); + + } + + +_func_exit_; + return ret; + +} + + +int mp_recv_frame(_adapter *padapter, union recv_frame *rframe) +{ + int ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; +#ifdef CONFIG_MP_INCLUDED + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mp_priv *pmppriv = &padapter->mppriv; +#endif //CONFIG_MP_INCLUDED + 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); + + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) )//&&(padapter->mppriv.check_mp_pkt == 0)) + { + if (pattrib->crc_err == 1){ + padapter->mppriv.rx_crcerrpktcount++; + } + else{ + if(_SUCCESS == validate_mp_recv_frame(padapter, rframe)) + padapter->mppriv.rx_pktcount++; + else + padapter->mppriv.rx_pktcount_filter_out++; + } + + if(pmppriv->rx_bindicatePkt == _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 (!RTW_CANNOT_RUN(padapter)) { + 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(%s) OR bSurpriseRemoved(%s)" + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s ecv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)\n", __func__, + rtw_is_drv_stopped(padapter)?"True":"False", + rtw_is_surprise_removed(padapter)?"True":"False"); + #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; + +exit: + return ret; + +} + +static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf) +{ +#define CHAN2FREQ(a) ((a < 14)?(2407+5*a):(5000+5*a)) + +#if 0 +#define RTW_RX_RADIOTAP_PRESENT ( \ + (1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (0 << IEEE80211_RADIOTAP_FHSS) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ + (0 << IEEE80211_RADIOTAP_LOCK_QUALITY) | \ + (0 << IEEE80211_RADIOTAP_TX_ATTENUATION) | \ + (0 << IEEE80211_RADIOTAP_DB_TX_ATTENUATION) | \ + (0 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ + (0 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \ + (0 << IEEE80211_RADIOTAP_RX_FLAGS) | \ + (0 << IEEE80211_RADIOTAP_TX_FLAGS) | \ + (0 << IEEE80211_RADIOTAP_RTS_RETRIES) | \ + (0 << IEEE80211_RADIOTAP_DATA_RETRIES) | \ + (0 << IEEE80211_RADIOTAP_MCS) | \ + (0 << IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)| \ + (0 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | \ + (0 << IEEE80211_RADIOTAP_EXT) | \ + 0) + + /* (0 << IEEE80211_RADIOTAP_AMPDU_STATUS) | \ */ + /* (0 << IEEE80211_RADIOTAP_VHT) | \ */ +#endif +#ifndef IEEE80211_RADIOTAP_MCS +#define IEEE80211_RADIOTAP_MCS 19 +#endif +#ifndef IEEE80211_RADIOTAP_VHT +#define IEEE80211_RADIOTAP_VHT 21 +#endif + +#ifndef IEEE80211_RADIOTAP_F_BADFCS +#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */ +#endif + + sint ret = _SUCCESS; + _adapter *adapter = precvframe->u.hdr.adapter; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + u16 tmp_16bit = 0; + + u8 data_rate[] = { + 2, 4, 11, 22, /* CCK */ + 12, 18, 24, 36, 48, 72, 93, 108, /* OFDM */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 1 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 2 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 3 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 4 */ + }; + + _pkt *pskb = NULL; + + struct ieee80211_radiotap_header *rtap_hdr = NULL; + u8 *ptr = NULL; + + u8 hdr_buf[64] = {0}; + u16 rt_len = 8; + + /* create header */ + rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0]; + rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION; + + /* tsft */ + if (pattrib->tsfl) { + u64 tmp_64bit; + + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_TSFT); + tmp_64bit = cpu_to_le64(pattrib->tsfl); + memcpy(&hdr_buf[rt_len], &tmp_64bit, 8); + rt_len += 8; + } + + /* flags */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS); + if (0) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_CFP; + + if (0) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_SHORTPRE; + + if ((pattrib->encrypt == 1) || (pattrib->encrypt == 5)) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_WEP; + + if (pattrib->mfrag) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG; + + /* always append FCS */ + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS; + + if (0) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_DATAPAD; + + if (pattrib->crc_err) + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_BADFCS; + + if (pattrib->sgi) { + /* Currently unspecified but used */ + hdr_buf[rt_len] |= 0x80; + } + rt_len += 1; + + /* rate */ + if (pattrib->data_rate < 12) { + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE); + if (pattrib->data_rate < 4) { + /* CCK */ + hdr_buf[rt_len] = data_rate[pattrib->data_rate]; + } else { + /* OFDM */ + hdr_buf[rt_len] = data_rate[pattrib->data_rate]; + } + } + rt_len += 1; /* force padding 1 byte for aligned */ + + /* channel */ + tmp_16bit = 0; + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL); + tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter)); + /*tmp_16bit = CHAN2FREQ(pHalData->CurrentChannel);*/ + memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + + /* channel flags */ + tmp_16bit = 0; + if (pHalData->CurrentBandType == 0) + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ); + else + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ); + + if (pattrib->data_rate < 12) { + if (pattrib->data_rate < 4) { + /* CCK */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK); + } else { + /* OFDM */ + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM); + } + } else { + tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_DYN); + } + memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + + /* dBm Antenna Signal */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); + hdr_buf[rt_len] = pattrib->phy_info.RecvSignalPower; + rt_len += 1; + +#if 0 + /* dBm Antenna Noise */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); + hdr_buf[rt_len] = 0; + rt_len += 1; + + /* Signal Quality */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY); + hdr_buf[rt_len] = pattrib->phy_info.SignalQuality; + rt_len += 1; +#endif + + /* Antenna */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA); + hdr_buf[rt_len] = 0; /* pHalData->rf_type; */ + rt_len += 1; + + /* RX flags */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS); +#if 0 + tmp_16bit = cpu_to_le16(0); + memcpy(ptr, &tmp_16bit, 1); +#endif + rt_len += 2; + + /* MCS information */ + if (pattrib->data_rate >= 12 && pattrib->data_rate < 44) { + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS); + /* known, flag */ + hdr_buf[rt_len] |= BIT1; /* MCS index known */ + + /* bandwidth */ + hdr_buf[rt_len] |= BIT0; + hdr_buf[rt_len+1] |= (pattrib->bw & 0x03); + + /* guard interval */ + hdr_buf[rt_len] |= BIT2; + hdr_buf[rt_len+1] |= (pattrib->sgi & 0x01) << 2; + + /* STBC */ + hdr_buf[rt_len] |= BIT5; + hdr_buf[rt_len+1] |= (pattrib->stbc & 0x03) << 5; + + rt_len += 2; + + /* MCS rate index */ + hdr_buf[rt_len] = data_rate[pattrib->data_rate]; + rt_len += 1; + } + + /* VHT */ + if (pattrib->data_rate >= 44 && pattrib->data_rate < 84) { + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT); + + /* known 16 bit, flag 8 bit */ + tmp_16bit = 0; + + /* Bandwidth */ + tmp_16bit |= BIT6; + + /* Group ID */ + tmp_16bit |= BIT7; + + /* Partial AID */ + tmp_16bit |= BIT8; + + /* STBC */ + tmp_16bit |= BIT0; + hdr_buf[rt_len+2] |= (pattrib->stbc & 0x01); + + /* Guard interval */ + tmp_16bit |= BIT2; + hdr_buf[rt_len+2] |= (pattrib->sgi & 0x01) << 2; + + /* LDPC extra OFDM symbol */ + tmp_16bit |= BIT4; + hdr_buf[rt_len+2] |= (pattrib->ldpc & 0x01) << 4; + + memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 3; + + /* bandwidth */ + if (pattrib->bw == 0) + hdr_buf[rt_len] |= 0; + else if (pattrib->bw == 1) + hdr_buf[rt_len] |= 1; + else if (pattrib->bw == 2) + hdr_buf[rt_len] |= 4; + else if (pattrib->bw == 3) + hdr_buf[rt_len] |= 11; + rt_len += 1; + + /* mcs_nss */ + if (pattrib->data_rate >= 44 && pattrib->data_rate < 54) { + hdr_buf[rt_len] |= 1; + hdr_buf[rt_len] |= data_rate[pattrib->data_rate] << 4; + } else if (pattrib->data_rate >= 54 && pattrib->data_rate < 64) { + hdr_buf[rt_len + 1] |= 2; + hdr_buf[rt_len + 1] |= data_rate[pattrib->data_rate] << 4; + } else if (pattrib->data_rate >= 64 && pattrib->data_rate < 74) { + hdr_buf[rt_len + 2] |= 3; + hdr_buf[rt_len + 2] |= data_rate[pattrib->data_rate] << 4; + } else if (pattrib->data_rate >= 74 && pattrib->data_rate < 84) { + hdr_buf[rt_len + 3] |= 4; + hdr_buf[rt_len + 3] |= data_rate[pattrib->data_rate] << 4; + } + rt_len += 4; + + /* coding */ + hdr_buf[rt_len] = 0; + rt_len += 1; + + /* group_id */ + hdr_buf[rt_len] = 0; + rt_len += 1; + + /* partial_aid */ + tmp_16bit = 0; + memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; + } + + /* push to skb */ + pskb = (_pkt *)buf; + if (skb_headroom(pskb) < rt_len) { + DBG_871X("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__); + ret = _FAIL; + return ret; + } + + ptr = skb_push(pskb, rt_len); + if (ptr) { + rtap_hdr->it_len = cpu_to_le16(rt_len); + memcpy(ptr, rtap_hdr, rt_len); + } else { + ret = _FAIL; + } + + return ret; + +} + +int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) +{ + int ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + _pkt *pskb = NULL; + + /* read skb information from recv frame */ + pskb = rframe->u.hdr.pkt; + pskb->len = rframe->u.hdr.len; + pskb->data = rframe->u.hdr.rx_data; + skb_set_tail_pointer(pskb, rframe->u.hdr.len); + + /* fill radiotap header */ + if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) { + ret = _FAIL; + rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ + goto exit; + } + + /* write skb information to recv frame */ + skb_reset_mac_header(pskb); + rframe->u.hdr.len = pskb->len; + rframe->u.hdr.rx_data = pskb->data; + rframe->u.hdr.rx_head = pskb->head; + rframe->u.hdr.rx_tail = skb_tail_pointer(pskb); + rframe->u.hdr.rx_end = skb_end_pointer(pskb); + + if (!RTW_CANNOT_RUN(padapter)) { + /* indicate this recv_frame */ + ret = rtw_recv_monitor(padapter, rframe); + if (ret != _SUCCESS) { + ret = _FAIL; + rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ + goto exit; + } + } else { + ret = _FAIL; + rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ + goto exit; + } + +exit: + return ret; +} + +int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe) +{ + int ret = _SUCCESS; + struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + +#ifdef DBG_RX_COUNTER_DUMP + if( padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER ) + { + if (pattrib->crc_err == 1) + padapter->drv_rx_cnt_crcerror++; + else + padapter->drv_rx_cnt_ok++; + } +#endif + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1 || padapter->mppriv.bRTWSmbCfg ==_TRUE) + { + mp_recv_frame(padapter,rframe); + ret = _FAIL; + goto exit; + } + else +#endif + { + //check the frame crtl field and decache + ret = validate_recv_frame(padapter, rframe); + if (ret != _SUCCESS) + { + 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 + goto exit; + } + } +exit: + return ret; +} + +int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe) +{ + int ret = _SUCCESS; + union recv_frame *orig_prframe = prframe; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct recv_priv *precvpriv = &padapter->recvpriv; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; +#ifdef CONFIG_TDLS + u8 *psnap_type, *pcategory; +#endif //CONFIG_TDLS + + DBG_COUNTER(padapter->rx_logs.core_rx_post); + + // DATA FRAME + rtw_led_control(padapter, LED_CTL_RX); + + prframe = decryptor(padapter, prframe); + if (prframe == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decryptor: drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __FUNCTION__); + #endif + ret = _FAIL; + DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err); + goto _recv_data_drop; + } + +#if 0 + if ( padapter->adapter_type == PRIMARY_ADAPTER ) + { + DBG_871X("+++\n"); + { + int i; + u8 *ptr = get_recvframe_data(prframe); + for(i=0; i<140;i=i+8) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr+i), + *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); + + } + DBG_871X("---\n"); + } +#endif + +#ifdef CONFIG_TDLS + //check TDLS frame + psnap_type = get_recvframe_data(orig_prframe) + pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; + pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN; + + if((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN)) && + ((*pcategory==RTW_WLAN_CATEGORY_TDLS) || (*pcategory==RTW_WLAN_CATEGORY_P2P))){ + ret = OnTDLS(padapter, prframe); + if(ret == _FAIL) + goto _exit_recv_func; + } +#endif //CONFIG_TDLS + + prframe = recvframe_chk_defrag(padapter, prframe); + if(prframe==NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chk_defrag: drop pkt\n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __FUNCTION__); + #endif + DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err); + goto _recv_data_drop; + } + + prframe=portctrl(padapter, prframe); + if (prframe == NULL) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("portctrl: drop pkt \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __FUNCTION__); + #endif + ret = _FAIL; + DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err); + goto _recv_data_drop; + } + + count_rx_stats(padapter, prframe, NULL); + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_update_info(padapter, prframe); +#endif + +#ifdef CONFIG_80211N_HT + ret = process_recv_indicatepkts(padapter, prframe); + if (ret != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recv_func: process_recv_indicatepkts fail! \n")); + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __FUNCTION__); + #endif + rtw_free_recvframe(orig_prframe, pfree_recv_queue);//free this recv_frame + DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_err); + goto _recv_data_drop; + } +#else // CONFIG_80211N_HT + if (!pattrib->amsdu) + { + ret = wlanhdr_to_ethhdr (prframe); + 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(orig_prframe, pfree_recv_queue);//free this recv_frame + goto _recv_data_drop; + } + + if (!RTW_CANNOT_RUN(padapter)) { + 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, prframe); + if (ret != _SUCCESS) + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__); + #endif + goto _recv_data_drop; + } + } + 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(%s) OR bSurpriseRemoved(%s)\n", __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False"); + #endif + ret = _FAIL; + rtw_free_recvframe(orig_prframe, pfree_recv_queue); //free this recv_frame + } + + } + else if(pattrib->amsdu==1) + { + + ret = amsdu_to_msdu(padapter, prframe); + if(ret != _SUCCESS) + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__); + #endif + rtw_free_recvframe(orig_prframe, pfree_recv_queue); + goto _recv_data_drop; + } + } + else + { + #ifdef DBG_RX_DROP_FRAME + DBG_871X("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__); + #endif + goto _recv_data_drop; + } +#endif // CONFIG_80211N_HT + +_exit_recv_func: + return ret; + +_recv_data_drop: + precvpriv->rx_drop++; + return ret; +} + + +int recv_func(_adapter *padapter, union recv_frame *rframe); +int recv_func(_adapter *padapter, union recv_frame *rframe) +{ + int ret; + struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib; + struct recv_priv *recvpriv = &padapter->recvpriv; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + + if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) { + /* monitor mode */ + recv_frame_monitor(padapter, rframe); + ret = _SUCCESS; + goto exit; + } else + + /* check if need to handle uc_swdec_pending_queue*/ + if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) + { + union recv_frame *pending_frame; + int cnt = 0; + + while((pending_frame=rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) { + cnt++; + DBG_COUNTER(padapter->rx_logs.core_rx_dequeue); + recv_func_posthandle(padapter, pending_frame); + } + + if (cnt) + DBG_871X(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n", + FUNC_ADPT_ARG(padapter), cnt); + } + + DBG_COUNTER(padapter->rx_logs.core_rx); + ret = recv_func_prehandle(padapter, rframe); + + if(ret == _SUCCESS) { + + /* check if need to enqueue into uc_swdec_pending_queue*/ + if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && + !IS_MCAST(prxattrib->ra) && prxattrib->encrypt>0 && + (prxattrib->bdecrypted == 0 ||psecuritypriv->sw_decrypt == _TRUE) && + psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK && + !psecuritypriv->busetkipkey) + { + DBG_COUNTER(padapter->rx_logs.core_rx_enqueue); + rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); + //DBG_871X("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); + + if (recvpriv->free_recvframe_cnt < NR_RECVFRAME/4) { + /* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt */ + rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); + if (rframe) + goto do_posthandle; + } + goto exit; + } + +do_posthandle: + ret = recv_func_posthandle(padapter, rframe); + } + +exit: + return ret; +} + + +s32 rtw_recv_entry(union recv_frame *precvframe) +{ + _adapter *padapter; + struct recv_priv *precvpriv; + s32 ret=_SUCCESS; + +_func_enter_; + +// RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n")); + + padapter = precvframe->u.hdr.adapter; + + precvpriv = &padapter->recvpriv; + + + if ((ret = recv_func(padapter, precvframe)) == _FAIL) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("rtw_recv_entry: recv_func return fail!!!\n")); + goto _recv_entry_drop; + } + + + precvpriv->rx_pkts++; + +_func_exit_; + + return ret; + +_recv_entry_drop: + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + padapter->mppriv.rx_pktloss = precvpriv->rx_drop; +#endif + + //RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n")); + +_func_exit_; + + return ret; +} + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS +void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS){ + _adapter *adapter = (_adapter *)FunctionContext; + struct recv_priv *recvpriv = &adapter->recvpriv; + + u32 tmp_s, tmp_q; + u8 avg_signal_strength = 0; + u8 avg_signal_qual = 0; + u32 num_signal_strength = 0; + u32 num_signal_qual = 0; + u8 ratio_pre_stat = 0, ratio_curr_stat = 0, ratio_total = 0, ratio_profile = SIGNAL_STAT_CALC_PROFILE_0; + + if(adapter->recvpriv.is_signal_dbg) { + //update the user specific value, signal_strength_dbg, to signal_strength, rssi + adapter->recvpriv.signal_strength= adapter->recvpriv.signal_strength_dbg; + adapter->recvpriv.rssi=(s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); + } else { + + if(recvpriv->signal_strength_data.update_req == 0) {// update_req is clear, means we got rx + avg_signal_strength = recvpriv->signal_strength_data.avg_val; + num_signal_strength = recvpriv->signal_strength_data.total_num; + // after avg_vals are accquired, we can re-stat the signal values + recvpriv->signal_strength_data.update_req = 1; + } + + if(recvpriv->signal_qual_data.update_req == 0) {// update_req is clear, means we got rx + avg_signal_qual = recvpriv->signal_qual_data.avg_val; + num_signal_qual = recvpriv->signal_qual_data.total_num; + // after avg_vals are accquired, we can re-stat the signal values + recvpriv->signal_qual_data.update_req = 1; + } + + if (num_signal_strength == 0) { + if (rtw_get_on_cur_ch_time(adapter) == 0 + || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval + ) { + goto set_timer; + } + } + + if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE + || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE + ) { + goto set_timer; + } + + #ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE) + goto set_timer; + #endif + + if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX) + ratio_profile = RTW_SIGNAL_STATE_CALC_PROFILE; + + ratio_pre_stat = signal_stat_calc_profile[ratio_profile][0]; + ratio_curr_stat = signal_stat_calc_profile[ratio_profile][1]; + ratio_total = ratio_pre_stat + ratio_curr_stat; + + //update value of signal_strength, rssi, signal_qual + tmp_s = (ratio_curr_stat * avg_signal_strength + ratio_pre_stat * recvpriv->signal_strength); + if (tmp_s % ratio_total) + tmp_s = tmp_s / ratio_total + 1; + else + tmp_s = tmp_s / ratio_total; + if (tmp_s > 100) + tmp_s = 100; + + tmp_q = (ratio_curr_stat * avg_signal_qual + ratio_pre_stat * recvpriv->signal_qual); + if (tmp_q % ratio_total) + tmp_q = tmp_q / ratio_total + 1; + else + tmp_q = tmp_q / ratio_total; + if (tmp_q > 100) + tmp_q = 100; + + recvpriv->signal_strength = tmp_s; + recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); + recvpriv->signal_qual = tmp_q; + + #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1 + DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u" + ", num_signal_strength:%u, num_signal_qual:%u" + ", on_cur_ch_ms:%d" + "\n" + , FUNC_ADPT_ARG(adapter) + , recvpriv->signal_strength + , recvpriv->rssi + , recvpriv->signal_qual + , num_signal_strength, num_signal_qual + , rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0 + ); + #endif + } + +set_timer: + rtw_set_signal_stat_timer(recvpriv); + +} +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +static void rx_process_rssi(_adapter *padapter,union recv_frame *prframe) +{ + u32 last_rssi, tmp_val; + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + struct signal_stat * signal_stat = &padapter->recvpriv.signal_strength_data; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //DBG_8192C("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength); + //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) + { + #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + if(signal_stat->update_req) { + signal_stat->total_num = 0; + signal_stat->total_val = 0; + signal_stat->update_req = 0; + } + + signal_stat->total_num++; + signal_stat->total_val += pattrib->phy_info.SignalStrength; + signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; + #else //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //Adapter->RxStats.RssiCalculateCnt++; //For antenna Test + if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX) + { + padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index]; + padapter->recvpriv.signal_strength_data.total_val -= last_rssi; + } + padapter->recvpriv.signal_strength_data.total_val +=pattrib->phy_info.SignalStrength; + + padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.SignalStrength; + if(padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX) + padapter->recvpriv.signal_strength_data.index = 0; + + + tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num; + + if(padapter->recvpriv.is_signal_dbg) { + padapter->recvpriv.signal_strength= padapter->recvpriv.signal_strength_dbg; + padapter->recvpriv.rssi=(s8)translate_percentage_to_dbm(padapter->recvpriv.signal_strength_dbg); + } else { + padapter->recvpriv.signal_strength= tmp_val; + padapter->recvpriv.rssi=(s8)translate_percentage_to_dbm(tmp_val); + } + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("UI RSSI = %d, ui_rssi.TotalVal = %d, ui_rssi.TotalNum = %d\n", tmp_val, padapter->recvpriv.signal_strength_data.total_val,padapter->recvpriv.signal_strength_data.total_num)); + #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + } +} + +static void rx_process_link_qual(_adapter *padapter,union recv_frame *prframe) +{ + u32 last_evm=0, tmpVal; + struct rx_pkt_attrib *pattrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + struct signal_stat * signal_stat; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + if(prframe == NULL || padapter==NULL){ + return; + } + + pattrib = &prframe->u.hdr.attrib; +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + signal_stat = &padapter->recvpriv.signal_qual_data; +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + + //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual); + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + if(signal_stat->update_req) { + signal_stat->total_num = 0; + signal_stat->total_val = 0; + signal_stat->update_req = 0; + } + + signal_stat->total_num++; + signal_stat->total_val += pattrib->phy_info.SignalQuality; + signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; + +#else //CONFIG_NEW_SIGNAL_STAT_PROCESS + if(pattrib->phy_info.SignalQuality != 0) + { + // + // 1. Record the general EVM to the sliding window. + // + if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) + { + padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index]; + padapter->recvpriv.signal_qual_data.total_val -= last_evm; + } + padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.SignalQuality; + + padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.SignalQuality; + if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX) + padapter->recvpriv.signal_qual_data.index = 0; + + RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, pattrib->phy_info.SignalQuality)); + + // <1> Showed on UI for user, in percentage. + tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num; + padapter->recvpriv.signal_qual=(u8)tmpVal; + + } + else + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->phy_info.SignalQuality)); + } +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS +} + +void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe) +{ + /* Check RSSI */ + rx_process_rssi(padapter, rframe); + + /* Check PWDB */ + //process_PWDB(padapter, rframe); + + //UpdateRxSignalStatistics8192C(Adapter, pRfd); + + /* Check EVM */ + rx_process_link_qual(padapter, rframe); + #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA + rtw_store_phy_info( padapter, rframe); + #endif +} + +void rx_query_phy_status( + union recv_frame *precvframe, + u8 *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; + struct sta_priv *pstapriv; + struct sta_info *psta = NULL; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + //_irqL irqL; + + 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.bToSelf = (!pattrib->icv_err) && (!pattrib->crc_err) + && _rtw_memcmp(get_ra(wlanhdr), adapter_mac_addr(padapter), ETH_ALEN); + + pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID + && _rtw_memcmp(get_ra(wlanhdr), adapter_mac_addr(padapter), ETH_ALEN); + + pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID + && (GetFrameSubType(wlanhdr) == WIFI_BEACON); + + sa = get_ta(wlanhdr); + + pkt_info.StationID = 0xFF; + + if (_rtw_memcmp(adapter_mac_addr(padapter), sa, ETH_ALEN) == _TRUE) { + static u32 start_time = 0; + +#if 0 /*For debug */ + if (IsFrameTypeCtrl(wlanhdr)) { + DBG_871X("-->Control frame: Y\n"); + DBG_871X("-->pkt_len: %d\n", pattrib->pkt_len); + DBG_871X("-->Sub Type = 0x%X\n", GetFrameSubType(wlanhdr)); + } + + /* Dump first 40 bytes of header */ + int i = 0; + + for (i = 0; i < 40; i++) + DBG_871X("%d: %X\n", i, *((u8 *)wlanhdr + i)); + + DBG_871X("\n"); +#endif + + if ((start_time == 0) || (rtw_get_passing_time_ms(start_time) > 5000)) { + DBG_871X_LEVEL(_drv_always_, "Warning!!! %s: Confilc mac addr!!\n", __func__); + start_time = rtw_get_current_time(); + } + pdbgpriv->dbg_rx_conflic_mac_addr_cnt++; + } else{ + pstapriv = &padapter->stapriv; + psta = rtw_get_stainfo(pstapriv, sa); + if (psta) + pkt_info.StationID = psta->mac_id; + } + + pkt_info.DataRate = pattrib->data_rate; + + //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); + ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, 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; + rx_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; + } + rx_process_phy_info(padapter, precvframe); + } + } +} +/* +* Increase and check if the continual_no_rx_packet of this @param pmlmepriv is larger than MAX_CONTINUAL_NORXPACKET_COUNT +* @return _TRUE: +* @return _FALSE: +*/ +int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index) +{ + + int ret = _FALSE; + int value = ATOMIC_INC_RETURN(&sta->continual_no_rx_packet[tid_index]); + + if (value >= MAX_CONTINUAL_NORXPACKET_COUNT) + ret = _TRUE; + + return ret; +} + +/* +* Set the continual_no_rx_packet of this @param pmlmepriv to 0 +*/ +void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index) +{ + ATOMIC_SET(&sta->continual_no_rx_packet[tid_index], 0); +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_rf.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_rf.c new file mode 100644 index 00000000..a2299ec2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_rf.c @@ -0,0 +1,741 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_RF_C_ + +#include +#include + +u8 center_ch_5g_all[CENTER_CH_5G_ALL_NUM] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + +u8 center_ch_5g_20m[CENTER_CH_5G_20M_NUM] = { + 36, 40, 44, 48, + 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161, 165, 169, 173, 177 +}; + +u8 center_ch_5g_40m[CENTER_CH_5G_40M_NUM] = {38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159, 167, 175}; + +u8 center_ch_5g_80m[CENTER_CH_5G_80M_NUM] = {42, 58, 106, 122, 138, 155, 171}; + +struct center_chs_ent { + u8 ch_num; + u8 *chs; +}; + +struct center_chs_ent center_chs_5g_by_bw[] = { + {CENTER_CH_5G_20M_NUM, center_ch_5g_20m}, + {CENTER_CH_5G_40M_NUM, center_ch_5g_40m}, + {CENTER_CH_5G_80M_NUM, center_ch_5g_80m}, +}; + +inline u8 center_chs_5g_num(u8 bw) +{ + if (bw >= CHANNEL_WIDTH_160) + return 0; + + return center_chs_5g_by_bw[bw].ch_num; +} + +inline u8 center_chs_5g(u8 bw, u8 id) +{ + if (bw >= CHANNEL_WIDTH_160) + return 0; + + if (id >= center_chs_5g_num(bw)) + return 0; + + return center_chs_5g_by_bw[bw].chs[id]; +} + +int rtw_ch2freq(int chan) +{ + /* see 802.11 17.3.8.3.2 and Annex J + * there are overlapping channel numbers in 5GHz and 2GHz bands */ + + /* + * RTK: don't consider the overlapping channel numbers: 5G channel <= 14, + * because we don't support it. simply judge from channel number + */ + + if (chan >= 1 && chan <= 14) { + if (chan == 14) + return 2484; + else if (chan < 14) + return 2407 + chan * 5; + } else if (chan >= 36 && chan <= 177) { + return 5000 + chan * 5; + } + + return 0; /* not supported */ +} + +int rtw_freq2ch(int freq) +{ + /* see 802.11 17.3.8.3.2 and Annex J */ + if (freq == 2484) + return 14; + else if (freq < 2484) + return (freq - 2407) / 5; + else if (freq >= 4910 && freq <= 4980) + return (freq - 4000) / 5; + else if (freq <= 45000) /* DMG band lower limit */ + return (freq - 5000) / 5; + else if (freq >= 58320 && freq <= 64800) + return (freq - 56160) / 2160; + else + return 0; +} + +bool rtw_chbw_to_freq_range(u8 ch, u8 bw, u8 offset, u32 *hi, u32 *lo) +{ + u8 c_ch; + u32 freq; + u32 hi_ret = 0, lo_ret = 0; + int i; + bool valid = _FALSE; + + if (hi) + *hi = 0; + if (lo) + *lo = 0; + + c_ch = rtw_get_center_ch(ch, bw, offset); + freq = rtw_ch2freq(c_ch); + + if (!freq) { + rtw_warn_on(1); + goto exit; + } + + if (bw == CHANNEL_WIDTH_80) { + hi_ret = freq + 40; + lo_ret = freq - 40; + } else if (bw == CHANNEL_WIDTH_40) { + hi_ret = freq + 20; + lo_ret = freq - 20; + } else if (bw == CHANNEL_WIDTH_20) { + hi_ret = freq + 10; + lo_ret = freq - 10; + } else { + rtw_warn_on(1); + } + + if (hi) + *hi = hi_ret; + if (lo) + *lo = lo_ret; + + valid = _TRUE; + +exit: + return valid; +} + +const char * const _ch_width_str[] = { + "20MHz", + "40MHz", + "80MHz", + "160MHz", + "80_80MHz", + "CHANNEL_WIDTH_MAX", +}; + +const u8 _ch_width_to_bw_cap[] = { + BW_CAP_20M, + BW_CAP_40M, + BW_CAP_80M, + BW_CAP_160M, + BW_CAP_80_80M, + 0, +}; + +const char * const _band_str[] = { + "2.4G", + "5G", + "BOTH", + "BAND_MAX", +}; + +const u8 _band_to_band_cap[] = { + BAND_CAP_2G, + BAND_CAP_5G, + 0, + 0, +}; + +#ifdef CONFIG_80211AC_VHT +#define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) , .en_11ac = (_val) +#else +#define COUNTRY_CHPLAN_ASSIGN_EN_11AC(_val) +#endif + +#if RTW_DEF_MODULE_REGULATORY_CERT +#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) , .def_module_flags = (_val) +#else +#define COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_val) +#endif + +/* has def_module_flags specified, used by common map and HAL dfference map */ +#define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _en_11ac, _def_module_flags) \ + {.alpha2 = (_alpha2), .chplan = (_chplan) \ + COUNTRY_CHPLAN_ASSIGN_EN_11AC(_en_11ac) \ + COUNTRY_CHPLAN_ASSIGN_DEF_MODULE_FLAGS(_def_module_flags) \ + } + +#ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP + +#include "../platform/custom_country_chplan.h" + +#elif RTW_DEF_MODULE_REGULATORY_CERT + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AE_HMC_M2) +static const struct country_chplan RTL8821AE_HMC_M2_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("CN", 0x51, 1, 0xFB), /* China */ + COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0xFB), /* Russia(fac/gost), Kaliningrad */ + COUNTRY_CHPLAN_ENT("UA", 0x26, 0, 0xFB), /* Ukraine */ +}; +static const u16 RTL8821AE_HMC_M2_country_chplan_map_sz = sizeof(RTL8821AE_HMC_M2_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8821AU) +static const struct country_chplan RTL8821AU_country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("RU", 0x59, 0, 0xFB), /* Russia(fac/gost), Kaliningrad */ + COUNTRY_CHPLAN_ENT("UA", 0x26, 0, 0xFB), /* Ukraine */ +}; +static const u16 RTL8821AU_country_chplan_map_sz = sizeof(RTL8821AU_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AENF_NGFF) +static const struct country_chplan RTL8812AENF_NGFF_country_chplan_map[] = { +}; +static const u16 RTL8812AENF_NGFF_country_chplan_map_sz = sizeof(RTL8812AENF_NGFF_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8812AEBT_HMC) +static const struct country_chplan RTL8812AEBT_HMC_country_chplan_map[] = { +}; +static const u16 RTL8812AEBT_HMC_country_chplan_map_sz = sizeof(RTL8812AEBT_HMC_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8188EE_HMC_M2) +static const struct country_chplan RTL8188EE_HMC_M2_country_chplan_map[] = { +}; +static const u16 RTL8188EE_HMC_M2_country_chplan_map_sz = sizeof(RTL8188EE_HMC_M2_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BE_HMC_M2) +static const struct country_chplan RTL8723BE_HMC_M2_country_chplan_map[] = { +}; +static const u16 RTL8723BE_HMC_M2_country_chplan_map_sz = sizeof(RTL8723BE_HMC_M2_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8723BS_NGFF1216) +static const struct country_chplan RTL8723BS_NGFF1216_country_chplan_map[] = { +}; +static const u16 RTL8723BS_NGFF1216_country_chplan_map_sz = sizeof(RTL8723BS_NGFF1216_country_chplan_map)/sizeof(struct country_chplan); +#endif + +#if (RTW_DEF_MODULE_REGULATORY_CERT & RTW_MODULE_RTL8192EEBT_HMC_M2) +static const struct country_chplan RTL8192EEBT_HMC_M2_country_chplan_map[] = { +}; +static const u16 RTL8192EEBT_HMC_M2_country_chplan_map_sz = sizeof(RTL8192EEBT_HMC_M2_country_chplan_map)/sizeof(struct country_chplan); +#endif + +/** + * rtw_def_module_get_chplan_from_country - + * @country_code: string of country code + * @return: + * Return NULL for case referring to common map + */ +static const struct country_chplan *rtw_def_module_get_chplan_from_country(const char *country_code) +{ + const struct country_chplan *ent = NULL; + const struct country_chplan *hal_map = NULL; + u16 hal_map_sz = 0; + int i; + + /* TODO: runtime selection for multi driver */ +#if (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AE_HMC_M2) + hal_map = RTL8821AE_HMC_M2_country_chplan_map; + hal_map_sz = RTL8821AE_HMC_M2_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8821AU) + hal_map = RTL8821AU_country_chplan_map; + hal_map_sz = RTL8821AU_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AENF_NGFF) + hal_map = RTL8812AENF_NGFF_country_chplan_map; + hal_map_sz = RTL8812AENF_NGFF_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8812AEBT_HMC) + hal_map = RTL8812AEBT_HMC_country_chplan_map; + hal_map_sz = RTL8812AEBT_HMC_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8188EE_HMC_M2) + hal_map = RTL8188EE_HMC_M2_country_chplan_map; + hal_map_sz = RTL8188EE_HMC_M2_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BE_HMC_M2) + hal_map = RTL8723BE_HMC_M2_country_chplan_map; + hal_map_sz = RTL8723BE_HMC_M2_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8723BS_NGFF1216) + hal_map = RTL8723BS_NGFF1216_country_chplan_map; + hal_map_sz = RTL8723BS_NGFF1216_country_chplan_map_sz; +#elif (RTW_DEF_MODULE_REGULATORY_CERT == RTW_MODULE_RTL8192EEBT_HMC_M2) + hal_map = RTL8192EEBT_HMC_M2_country_chplan_map; + hal_map_sz = RTL8192EEBT_HMC_M2_country_chplan_map_sz; +#endif + + if (hal_map == NULL || hal_map_sz == 0) + goto exit; + + for (i = 0; i < hal_map_sz; i++) { + if (strncmp(country_code, hal_map[i].alpha2, 2) == 0) { + ent = &hal_map[i]; + break; + } + } + +exit: + return ent; +} +#endif /* CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP or RTW_DEF_MODULE_REGULATORY_CERT */ + +static const struct country_chplan country_chplan_map[] = { + COUNTRY_CHPLAN_ENT("AD", 0x26, 1, 0x00), /* Andorra */ + COUNTRY_CHPLAN_ENT("AE", 0x26, 1, 0xFB), /* United Arab Emirates */ + COUNTRY_CHPLAN_ENT("AF", 0x42, 1, 0x00), /* Afghanistan */ + COUNTRY_CHPLAN_ENT("AG", 0x30, 1, 0x00), /* Antigua & Barbuda */ + COUNTRY_CHPLAN_ENT("AI", 0x26, 1, 0x00), /* Anguilla(UK) */ + COUNTRY_CHPLAN_ENT("AL", 0x26, 1, 0xF1), /* Albania */ + COUNTRY_CHPLAN_ENT("AM", 0x26, 1, 0xB0), /* Armenia */ + COUNTRY_CHPLAN_ENT("AO", 0x26, 1, 0xE0), /* Angola */ + COUNTRY_CHPLAN_ENT("AQ", 0x26, 1, 0x00), /* Antarctica */ + COUNTRY_CHPLAN_ENT("AR", 0x57, 1, 0xF3), /* Argentina */ + COUNTRY_CHPLAN_ENT("AS", 0x34, 1, 0x00), /* American Samoa */ + COUNTRY_CHPLAN_ENT("AT", 0x26, 1, 0xFB), /* Austria */ + COUNTRY_CHPLAN_ENT("AU", 0x45, 1, 0xFB), /* Australia */ + COUNTRY_CHPLAN_ENT("AW", 0x34, 1, 0xB0), /* Aruba */ + COUNTRY_CHPLAN_ENT("AZ", 0x26, 1, 0xF1), /* Azerbaijan */ + COUNTRY_CHPLAN_ENT("BA", 0x26, 1, 0xF1), /* Bosnia & Herzegovina */ + COUNTRY_CHPLAN_ENT("BB", 0x34, 1, 0x50), /* Barbados */ + COUNTRY_CHPLAN_ENT("BD", 0x26, 1, 0xF1), /* Bangladesh */ + COUNTRY_CHPLAN_ENT("BE", 0x26, 1, 0xFB), /* Belgium */ + COUNTRY_CHPLAN_ENT("BF", 0x26, 1, 0xB0), /* Burkina Faso */ + COUNTRY_CHPLAN_ENT("BG", 0x26, 1, 0xF1), /* Bulgaria */ + COUNTRY_CHPLAN_ENT("BH", 0x47, 1, 0xF1), /* Bahrain */ + COUNTRY_CHPLAN_ENT("BI", 0x26, 1, 0xB0), /* Burundi */ + COUNTRY_CHPLAN_ENT("BJ", 0x26, 1, 0xB0), /* Benin */ + COUNTRY_CHPLAN_ENT("BN", 0x47, 1, 0x10), /* Brunei */ + COUNTRY_CHPLAN_ENT("BO", 0x30, 1, 0xF1), /* Bolivia */ + COUNTRY_CHPLAN_ENT("BR", 0x34, 1, 0xF1), /* Brazil */ + COUNTRY_CHPLAN_ENT("BS", 0x34, 1, 0x20), /* Bahamas */ + COUNTRY_CHPLAN_ENT("BW", 0x26, 1, 0xF1), /* Botswana */ + COUNTRY_CHPLAN_ENT("BY", 0x26, 1, 0xF1), /* Belarus */ + COUNTRY_CHPLAN_ENT("BZ", 0x34, 1, 0x00), /* Belize */ + COUNTRY_CHPLAN_ENT("CA", 0x34, 1, 0xFB), /* Canada */ + COUNTRY_CHPLAN_ENT("CC", 0x26, 1, 0x00), /* Cocos (Keeling) Islands (Australia) */ + COUNTRY_CHPLAN_ENT("CD", 0x26, 1, 0xB0), /* Congo, Republic of the */ + COUNTRY_CHPLAN_ENT("CF", 0x26, 1, 0xB0), /* Central African Republic */ + COUNTRY_CHPLAN_ENT("CG", 0x26, 1, 0xB0), /* Congo, Democratic Republic of the. Zaire */ + COUNTRY_CHPLAN_ENT("CH", 0x26, 1, 0xFB), /* Switzerland */ + COUNTRY_CHPLAN_ENT("CI", 0x26, 1, 0xF1), /* Cote d'Ivoire */ + COUNTRY_CHPLAN_ENT("CK", 0x26, 1, 0x00), /* Cook Islands */ + COUNTRY_CHPLAN_ENT("CL", 0x30, 1, 0xF1), /* Chile */ + COUNTRY_CHPLAN_ENT("CM", 0x26, 1, 0xB0), /* Cameroon */ + COUNTRY_CHPLAN_ENT("CN", 0x48, 1, 0xFB), /* China */ + COUNTRY_CHPLAN_ENT("CO", 0x34, 1, 0xF1), /* Colombia */ + COUNTRY_CHPLAN_ENT("CR", 0x34, 1, 0xF1), /* Costa Rica */ + COUNTRY_CHPLAN_ENT("CV", 0x26, 1, 0xB0), /* Cape Verde */ + COUNTRY_CHPLAN_ENT("CX", 0x45, 1, 0x00), /* Christmas Island (Australia) */ + COUNTRY_CHPLAN_ENT("CY", 0x26, 1, 0xFB), /* Cyprus */ + COUNTRY_CHPLAN_ENT("CZ", 0x26, 1, 0xFB), /* Czech Republic */ + COUNTRY_CHPLAN_ENT("DE", 0x26, 1, 0xFB), /* Germany */ + COUNTRY_CHPLAN_ENT("DJ", 0x26, 1, 0x80), /* Djibouti */ + COUNTRY_CHPLAN_ENT("DK", 0x26, 1, 0xFB), /* Denmark */ + COUNTRY_CHPLAN_ENT("DM", 0x34, 1, 0x00), /* Dominica */ + COUNTRY_CHPLAN_ENT("DO", 0x34, 1, 0xF1), /* Dominican Republic */ + COUNTRY_CHPLAN_ENT("DZ", 0x26, 1, 0xF1), /* Algeria */ + COUNTRY_CHPLAN_ENT("EC", 0x34, 1, 0xF1), /* Ecuador */ + COUNTRY_CHPLAN_ENT("EE", 0x26, 1, 0xFB), /* Estonia */ + COUNTRY_CHPLAN_ENT("EG", 0x47, 0, 0xF1), /* Egypt */ + COUNTRY_CHPLAN_ENT("EH", 0x47, 1, 0x80), /* Western Sahara */ + COUNTRY_CHPLAN_ENT("ER", 0x26, 1, 0x00), /* Eritrea */ + COUNTRY_CHPLAN_ENT("ES", 0x26, 1, 0xFB), /* Spain, Canary Islands, Ceuta, Melilla */ + COUNTRY_CHPLAN_ENT("ET", 0x26, 1, 0xB0), /* Ethiopia */ + COUNTRY_CHPLAN_ENT("FI", 0x26, 1, 0xFB), /* Finland */ + COUNTRY_CHPLAN_ENT("FJ", 0x34, 1, 0x00), /* Fiji */ + COUNTRY_CHPLAN_ENT("FK", 0x26, 1, 0x00), /* Falkland Islands (Islas Malvinas) (UK) */ + COUNTRY_CHPLAN_ENT("FM", 0x34, 1, 0x00), /* Micronesia, Federated States of (USA) */ + COUNTRY_CHPLAN_ENT("FO", 0x26, 1, 0x00), /* Faroe Islands (Denmark) */ + COUNTRY_CHPLAN_ENT("FR", 0x26, 1, 0xFB), /* France */ + COUNTRY_CHPLAN_ENT("GA", 0x26, 1, 0xB0), /* Gabon */ + COUNTRY_CHPLAN_ENT("GB", 0x26, 1, 0xFB), /* Great Britain (United Kingdom; England) */ + COUNTRY_CHPLAN_ENT("GD", 0x34, 1, 0xB0), /* Grenada */ + COUNTRY_CHPLAN_ENT("GE", 0x26, 1, 0x00), /* Georgia */ + COUNTRY_CHPLAN_ENT("GF", 0x26, 1, 0x80), /* French Guiana */ + COUNTRY_CHPLAN_ENT("GG", 0x26, 1, 0x00), /* Guernsey (UK) */ + COUNTRY_CHPLAN_ENT("GH", 0x26, 1, 0xF1), /* Ghana */ + COUNTRY_CHPLAN_ENT("GI", 0x26, 1, 0x00), /* Gibraltar (UK) */ + COUNTRY_CHPLAN_ENT("GL", 0x26, 1, 0x00), /* Greenland (Denmark) */ + COUNTRY_CHPLAN_ENT("GM", 0x26, 1, 0xB0), /* Gambia */ + COUNTRY_CHPLAN_ENT("GN", 0x26, 1, 0x10), /* Guinea */ + COUNTRY_CHPLAN_ENT("GP", 0x26, 1, 0x00), /* Guadeloupe (France) */ + COUNTRY_CHPLAN_ENT("GQ", 0x26, 1, 0xB0), /* Equatorial Guinea */ + COUNTRY_CHPLAN_ENT("GR", 0x26, 1, 0xFB), /* Greece */ + COUNTRY_CHPLAN_ENT("GS", 0x26, 1, 0x00), /* South Georgia and the Sandwich Islands (UK) */ + COUNTRY_CHPLAN_ENT("GT", 0x34, 1, 0xF1), /* Guatemala */ + COUNTRY_CHPLAN_ENT("GU", 0x34, 1, 0x00), /* Guam (USA) */ + COUNTRY_CHPLAN_ENT("GW", 0x26, 1, 0xB0), /* Guinea-Bissau */ + COUNTRY_CHPLAN_ENT("GY", 0x44, 1, 0x00), /* Guyana */ + COUNTRY_CHPLAN_ENT("HK", 0x26, 1, 0xFB), /* Hong Kong */ + COUNTRY_CHPLAN_ENT("HM", 0x45, 1, 0x00), /* Heard and McDonald Islands (Australia) */ + COUNTRY_CHPLAN_ENT("HN", 0x32, 1, 0xF1), /* Honduras */ + COUNTRY_CHPLAN_ENT("HR", 0x26, 1, 0xF9), /* Croatia */ + COUNTRY_CHPLAN_ENT("HT", 0x34, 1, 0x50), /* Haiti */ + COUNTRY_CHPLAN_ENT("HU", 0x26, 1, 0xFB), /* Hungary */ + COUNTRY_CHPLAN_ENT("ID", 0x54, 0, 0xF3), /* Indonesia */ + COUNTRY_CHPLAN_ENT("IE", 0x26, 1, 0xFB), /* Ireland */ + COUNTRY_CHPLAN_ENT("IL", 0x47, 1, 0xF1), /* Israel */ + COUNTRY_CHPLAN_ENT("IM", 0x26, 1, 0x00), /* Isle of Man (UK) */ + COUNTRY_CHPLAN_ENT("IN", 0x47, 1, 0xF1), /* India */ + COUNTRY_CHPLAN_ENT("IQ", 0x26, 1, 0x00), /* Iraq */ + COUNTRY_CHPLAN_ENT("IR", 0x26, 0, 0x00), /* Iran */ + COUNTRY_CHPLAN_ENT("IS", 0x26, 1, 0xFB), /* Iceland */ + COUNTRY_CHPLAN_ENT("IT", 0x26, 1, 0xFB), /* Italy */ + COUNTRY_CHPLAN_ENT("JE", 0x26, 1, 0x00), /* Jersey (UK) */ + COUNTRY_CHPLAN_ENT("JM", 0x51, 1, 0xF1), /* Jamaica */ + COUNTRY_CHPLAN_ENT("JO", 0x49, 1, 0xFB), /* Jordan */ + COUNTRY_CHPLAN_ENT("JP", 0x27, 1, 0xFF), /* Japan- Telec */ + COUNTRY_CHPLAN_ENT("KE", 0x47, 1, 0xF9), /* Kenya */ + COUNTRY_CHPLAN_ENT("KG", 0x26, 1, 0xF1), /* Kyrgyzstan */ + COUNTRY_CHPLAN_ENT("KH", 0x26, 1, 0xF1), /* Cambodia */ + COUNTRY_CHPLAN_ENT("KI", 0x26, 1, 0x00), /* Kiribati */ + COUNTRY_CHPLAN_ENT("KN", 0x34, 1, 0x00), /* Saint Kitts and Nevis */ + COUNTRY_CHPLAN_ENT("KR", 0x28, 1, 0xFB), /* South Korea */ + COUNTRY_CHPLAN_ENT("KW", 0x47, 1, 0xFB), /* Kuwait */ + COUNTRY_CHPLAN_ENT("KY", 0x34, 1, 0x00), /* Cayman Islands (UK) */ + COUNTRY_CHPLAN_ENT("KZ", 0x26, 1, 0x00), /* Kazakhstan */ + COUNTRY_CHPLAN_ENT("LA", 0x26, 1, 0x00), /* Laos */ + COUNTRY_CHPLAN_ENT("LB", 0x26, 1, 0xF1), /* Lebanon */ + COUNTRY_CHPLAN_ENT("LC", 0x34, 1, 0x00), /* Saint Lucia */ + COUNTRY_CHPLAN_ENT("LI", 0x26, 1, 0xFB), /* Liechtenstein */ + COUNTRY_CHPLAN_ENT("LK", 0x26, 1, 0xF1), /* Sri Lanka */ + COUNTRY_CHPLAN_ENT("LR", 0x26, 1, 0xB0), /* Liberia */ + COUNTRY_CHPLAN_ENT("LS", 0x26, 1, 0xF1), /* Lesotho */ + COUNTRY_CHPLAN_ENT("LT", 0x26, 1, 0xFB), /* Lithuania */ + COUNTRY_CHPLAN_ENT("LU", 0x26, 1, 0xFB), /* Luxembourg */ + COUNTRY_CHPLAN_ENT("LV", 0x26, 1, 0xFB), /* Latvia */ + COUNTRY_CHPLAN_ENT("LY", 0x26, 1, 0x00), /* Libya */ + COUNTRY_CHPLAN_ENT("MA", 0x47, 1, 0xF1), /* Morocco */ + COUNTRY_CHPLAN_ENT("MC", 0x26, 1, 0xFB), /* Monaco */ + COUNTRY_CHPLAN_ENT("MD", 0x26, 1, 0xF1), /* Moldova */ + COUNTRY_CHPLAN_ENT("ME", 0x26, 1, 0xF1), /* Montenegro */ + COUNTRY_CHPLAN_ENT("MF", 0x34, 1, 0x00), /* Saint Martin */ + COUNTRY_CHPLAN_ENT("MG", 0x26, 1, 0x20), /* Madagascar */ + COUNTRY_CHPLAN_ENT("MH", 0x34, 1, 0x00), /* Marshall Islands (USA) */ + COUNTRY_CHPLAN_ENT("MK", 0x26, 1, 0xF1), /* Republic of Macedonia (FYROM) */ + COUNTRY_CHPLAN_ENT("ML", 0x26, 1, 0xB0), /* Mali */ + COUNTRY_CHPLAN_ENT("MM", 0x26, 1, 0x00), /* Burma (Myanmar) */ + COUNTRY_CHPLAN_ENT("MN", 0x26, 1, 0x00), /* Mongolia */ + COUNTRY_CHPLAN_ENT("MO", 0x26, 1, 0x00), /* Macau */ + COUNTRY_CHPLAN_ENT("MP", 0x34, 1, 0x00), /* Northern Mariana Islands (USA) */ + COUNTRY_CHPLAN_ENT("MQ", 0x26, 1, 0x40), /* Martinique (France) */ + COUNTRY_CHPLAN_ENT("MR", 0x26, 1, 0xA0), /* Mauritania */ + COUNTRY_CHPLAN_ENT("MS", 0x26, 1, 0x00), /* Montserrat (UK) */ + COUNTRY_CHPLAN_ENT("MT", 0x26, 1, 0xFB), /* Malta */ + COUNTRY_CHPLAN_ENT("MU", 0x26, 1, 0xB0), /* Mauritius */ + COUNTRY_CHPLAN_ENT("MV", 0x26, 1, 0x00), /* Maldives */ + COUNTRY_CHPLAN_ENT("MW", 0x26, 1, 0xB0), /* Malawi */ + COUNTRY_CHPLAN_ENT("MX", 0x34, 1, 0xF1), /* Mexico */ + COUNTRY_CHPLAN_ENT("MY", 0x47, 1, 0xF1), /* Malaysia */ + COUNTRY_CHPLAN_ENT("MZ", 0x26, 1, 0xF1), /* Mozambique */ + COUNTRY_CHPLAN_ENT("NA", 0x26, 0, 0x00), /* Namibia */ + COUNTRY_CHPLAN_ENT("NC", 0x26, 1, 0x00), /* New Caledonia */ + COUNTRY_CHPLAN_ENT("NE", 0x26, 1, 0xB0), /* Niger */ + COUNTRY_CHPLAN_ENT("NF", 0x45, 1, 0x00), /* Norfolk Island (Australia) */ + COUNTRY_CHPLAN_ENT("NG", 0x50, 1, 0xF9), /* Nigeria */ + COUNTRY_CHPLAN_ENT("NI", 0x34, 1, 0xF1), /* Nicaragua */ + COUNTRY_CHPLAN_ENT("NL", 0x26, 1, 0xFB), /* Netherlands */ + COUNTRY_CHPLAN_ENT("NO", 0x26, 1, 0xFB), /* Norway */ + COUNTRY_CHPLAN_ENT("NP", 0x47, 1, 0xF0), /* Nepal */ + COUNTRY_CHPLAN_ENT("NR", 0x26, 1, 0x00), /* Nauru */ + COUNTRY_CHPLAN_ENT("NU", 0x45, 1, 0x00), /* Niue */ + COUNTRY_CHPLAN_ENT("NZ", 0x45, 1, 0xFB), /* New Zealand */ + COUNTRY_CHPLAN_ENT("OM", 0x26, 1, 0xF9), /* Oman */ + COUNTRY_CHPLAN_ENT("PA", 0x34, 1, 0xF1), /* Panama */ + COUNTRY_CHPLAN_ENT("PE", 0x34, 1, 0xF1), /* Peru */ + COUNTRY_CHPLAN_ENT("PF", 0x26, 1, 0x00), /* French Polynesia (France) */ + COUNTRY_CHPLAN_ENT("PG", 0x26, 1, 0xF1), /* Papua New Guinea */ + COUNTRY_CHPLAN_ENT("PH", 0x26, 1, 0xF1), /* Philippines */ + COUNTRY_CHPLAN_ENT("PK", 0x51, 1, 0xF1), /* Pakistan */ + COUNTRY_CHPLAN_ENT("PL", 0x26, 1, 0xFB), /* Poland */ + COUNTRY_CHPLAN_ENT("PM", 0x26, 1, 0x00), /* Saint Pierre and Miquelon (France) */ + COUNTRY_CHPLAN_ENT("PR", 0x34, 1, 0xF1), /* Puerto Rico */ + COUNTRY_CHPLAN_ENT("PT", 0x26, 1, 0xFB), /* Portugal */ + COUNTRY_CHPLAN_ENT("PW", 0x34, 1, 0x00), /* Palau */ + COUNTRY_CHPLAN_ENT("PY", 0x34, 1, 0xF1), /* Paraguay */ + COUNTRY_CHPLAN_ENT("QA", 0x51, 1, 0xF9), /* Qatar */ + COUNTRY_CHPLAN_ENT("RE", 0x26, 1, 0x00), /* Reunion (France) */ + COUNTRY_CHPLAN_ENT("RO", 0x26, 1, 0xF1), /* Romania */ + COUNTRY_CHPLAN_ENT("RS", 0x26, 1, 0xF1), /* Serbia, Kosovo */ + COUNTRY_CHPLAN_ENT("RU", 0x59, 1, 0xFB), /* Russia(fac/gost), Kaliningrad */ + COUNTRY_CHPLAN_ENT("RW", 0x26, 1, 0xB0), /* Rwanda */ + COUNTRY_CHPLAN_ENT("SA", 0x26, 1, 0xFB), /* Saudi Arabia */ + COUNTRY_CHPLAN_ENT("SB", 0x26, 1, 0x00), /* Solomon Islands */ + COUNTRY_CHPLAN_ENT("SC", 0x34, 1, 0x90), /* Seychelles */ + COUNTRY_CHPLAN_ENT("SE", 0x26, 1, 0xFB), /* Sweden */ + COUNTRY_CHPLAN_ENT("SG", 0x47, 1, 0xFB), /* Singapore */ + COUNTRY_CHPLAN_ENT("SH", 0x26, 1, 0x00), /* Saint Helena (UK) */ + COUNTRY_CHPLAN_ENT("SI", 0x26, 1, 0xFB), /* Slovenia */ + COUNTRY_CHPLAN_ENT("SJ", 0x26, 1, 0x00), /* Svalbard (Norway) */ + COUNTRY_CHPLAN_ENT("SK", 0x26, 1, 0xFB), /* Slovakia */ + COUNTRY_CHPLAN_ENT("SL", 0x26, 1, 0xB0), /* Sierra Leone */ + COUNTRY_CHPLAN_ENT("SM", 0x26, 1, 0x00), /* San Marino */ + COUNTRY_CHPLAN_ENT("SN", 0x26, 1, 0xF1), /* Senegal */ + COUNTRY_CHPLAN_ENT("SO", 0x26, 1, 0x00), /* Somalia */ + COUNTRY_CHPLAN_ENT("SR", 0x34, 1, 0x00), /* Suriname */ + COUNTRY_CHPLAN_ENT("ST", 0x34, 1, 0x80), /* Sao Tome and Principe */ + COUNTRY_CHPLAN_ENT("SV", 0x30, 1, 0xF1), /* El Salvador */ + COUNTRY_CHPLAN_ENT("SX", 0x34, 1, 0x00), /* Sint Marteen */ + COUNTRY_CHPLAN_ENT("SZ", 0x26, 1, 0x20), /* Swaziland */ + COUNTRY_CHPLAN_ENT("TC", 0x26, 1, 0x00), /* Turks and Caicos Islands (UK) */ + COUNTRY_CHPLAN_ENT("TD", 0x26, 1, 0xB0), /* Chad */ + COUNTRY_CHPLAN_ENT("TF", 0x26, 1, 0x80), /* French Southern and Antarctic Lands (FR Southern Territories) */ + COUNTRY_CHPLAN_ENT("TG", 0x26, 1, 0xB0), /* Togo */ + COUNTRY_CHPLAN_ENT("TH", 0x26, 1, 0xF1), /* Thailand */ + COUNTRY_CHPLAN_ENT("TJ", 0x26, 1, 0x40), /* Tajikistan */ + COUNTRY_CHPLAN_ENT("TK", 0x45, 1, 0x00), /* Tokelau */ + COUNTRY_CHPLAN_ENT("TM", 0x26, 1, 0x00), /* Turkmenistan */ + COUNTRY_CHPLAN_ENT("TN", 0x47, 1, 0xF1), /* Tunisia */ + COUNTRY_CHPLAN_ENT("TO", 0x26, 1, 0x00), /* Tonga */ + COUNTRY_CHPLAN_ENT("TR", 0x26, 1, 0xF1), /* Turkey, Northern Cyprus */ + COUNTRY_CHPLAN_ENT("TT", 0x42, 1, 0xF1), /* Trinidad & Tobago */ + COUNTRY_CHPLAN_ENT("TW", 0x39, 1, 0xFF), /* Taiwan */ + COUNTRY_CHPLAN_ENT("TZ", 0x26, 1, 0xF0), /* Tanzania */ + COUNTRY_CHPLAN_ENT("UA", 0x26, 1, 0xFB), /* Ukraine */ + COUNTRY_CHPLAN_ENT("UG", 0x26, 1, 0xF1), /* Uganda */ + COUNTRY_CHPLAN_ENT("US", 0x34, 1, 0xFF), /* United States of America (USA) */ + COUNTRY_CHPLAN_ENT("UY", 0x34, 1, 0xF1), /* Uruguay */ + COUNTRY_CHPLAN_ENT("UZ", 0x47, 1, 0xF0), /* Uzbekistan */ + COUNTRY_CHPLAN_ENT("VA", 0x26, 1, 0x00), /* Holy See (Vatican City) */ + COUNTRY_CHPLAN_ENT("VC", 0x34, 1, 0x10), /* Saint Vincent and the Grenadines */ + COUNTRY_CHPLAN_ENT("VE", 0x30, 1, 0xF1), /* Venezuela */ + COUNTRY_CHPLAN_ENT("VI", 0x34, 1, 0x00), /* United States Virgin Islands (USA) */ + COUNTRY_CHPLAN_ENT("VN", 0x26, 1, 0xF1), /* Vietnam */ + COUNTRY_CHPLAN_ENT("VU", 0x26, 1, 0x00), /* Vanuatu */ + COUNTRY_CHPLAN_ENT("WF", 0x26, 1, 0x00), /* Wallis and Futuna (France) */ + COUNTRY_CHPLAN_ENT("WS", 0x34, 1, 0x00), /* Samoa */ + COUNTRY_CHPLAN_ENT("YE", 0x26, 1, 0x40), /* Yemen */ + COUNTRY_CHPLAN_ENT("YT", 0x26, 1, 0x80), /* Mayotte (France) */ + COUNTRY_CHPLAN_ENT("ZA", 0x26, 1, 0xF1), /* South Africa */ + COUNTRY_CHPLAN_ENT("ZM", 0x26, 1, 0xB0), /* Zambia */ + COUNTRY_CHPLAN_ENT("ZW", 0x26, 1, 0xF1), /* Zimbabwe */ +}; + +u16 const country_chplan_map_sz = sizeof(country_chplan_map)/sizeof(struct country_chplan); + +/* +* rtw_get_chplan_from_country - +* @country_code: string of country code +* +* Return pointer of struct country_chplan entry or NULL when unsupported country_code is given +*/ +const struct country_chplan *rtw_get_chplan_from_country(const char *country_code) +{ + const struct country_chplan *ent = NULL; + const struct country_chplan *map = NULL; + u16 map_sz = 0; + char code[2]; + int i; + + code[0] = alpha_to_upper(country_code[0]); + code[1] = alpha_to_upper(country_code[1]); + +#if !defined(CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP) && RTW_DEF_MODULE_REGULATORY_CERT + ent = rtw_def_module_get_chplan_from_country(code); + if (ent != NULL) + goto exit; +#endif + +#ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP + map = CUSTOMIZED_country_chplan_map; + map_sz = CUSTOMIZED_country_chplan_map_sz; +#else + map = country_chplan_map; + map_sz = country_chplan_map_sz; +#endif + + for (i = 0; i < map_sz; i++) { + if (strncmp(code, map[i].alpha2, 2) == 0) { + ent = &map[i]; + break; + } + } + +exit: + #if RTW_DEF_MODULE_REGULATORY_CERT + if (ent && !(COUNTRY_CHPLAN_DEF_MODULE_FALGS(ent) & RTW_DEF_MODULE_REGULATORY_CERT)) + ent = NULL; + #endif + + return ent; +} + +int rtw_ch_to_bb_gain_sel(int ch) +{ + int sel = -1; + + if (ch >= 1 && ch <= 14) + sel = BB_GAIN_2G; +#ifdef CONFIG_IEEE80211_BAND_5GHZ + else if (ch >= 36 && ch < 48) + sel = BB_GAIN_5GLB1; + else if (ch >= 52 && ch <= 64) + sel = BB_GAIN_5GLB2; + else if (ch >= 100 && ch <= 120) + sel = BB_GAIN_5GMB1; + else if (ch >= 124 && ch <= 144) + sel = BB_GAIN_5GMB2; + else if (ch >= 149 && ch <= 177) + sel = BB_GAIN_5GHB; +#endif + + return sel; +} + +s8 rtw_rf_get_kfree_tx_gain_offset(_adapter *padapter, u8 path, u8 ch) +{ + s8 kfree_offset = 0; + +#ifdef CONFIG_RF_GAIN_OFFSET + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(padapter); + s8 bb_gain_sel = rtw_ch_to_bb_gain_sel(ch); + + if (bb_gain_sel < BB_GAIN_2G || bb_gain_sel >= BB_GAIN_NUM) { + rtw_warn_on(1); + goto exit; + } + + if (kfree_data->flag & KFREE_FLAG_ON) { + kfree_offset = kfree_data->bb_gain[bb_gain_sel][path]; + if (1) + DBG_871X("%s path:%u, ch:%u, bb_gain_sel:%d, kfree_offset:%d\n" + , __func__, path, ch, bb_gain_sel, kfree_offset); + } +exit: +#endif /* CONFIG_RF_GAIN_OFFSET */ + return kfree_offset; +} + +void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset) +{ + u8 write_value; + + DBG_871X("kfree gain_offset 0x55:0x%x ", rtw_hal_read_rfreg(adapter, path, 0x55, 0xffffffff)); + switch (rtw_get_chip_type(adapter)) { +#ifdef CONFIG_RTL8703B + case RTL8703B: + write_value = RF_TX_GAIN_OFFSET_8703B(offset); + rtw_hal_write_rfreg(adapter, path, 0x55, 0x0fc000, write_value); + break; +#endif /* CONFIG_RTL8703B */ +#ifdef CONFIG_RTL8188F + case RTL8188F: + write_value = RF_TX_GAIN_OFFSET_8188F(offset); + rtw_hal_write_rfreg(adapter, path, 0x55, 0x0fc000, write_value); + break; +#endif /* CONFIG_RTL8188F */ +#ifdef CONFIG_RTL8192E + case RTL8192E: + write_value = RF_TX_GAIN_OFFSET_8192E(offset); + rtw_hal_write_rfreg(adapter, path, 0x55, 0x0f8000, write_value); + break; +#endif /* CONFIG_RTL8188F */ + +#ifdef CONFIG_RTL8821A + case RTL8821: + write_value = RF_TX_GAIN_OFFSET_8821A(offset); + rtw_hal_write_rfreg(adapter, path, 0x55, 0x0f8000, write_value); + break; +#endif /* CONFIG_RTL8821A */ +#ifdef CONFIG_RTL8814A + case RTL8814A: + DBG_871X("\nkfree by PhyDM on the sw CH. path %d\n", path); + break; +#endif /* CONFIG_RTL8821A */ + + default: + rtw_warn_on(1); + break; + } + + DBG_871X(" after :0x%x\n", rtw_hal_read_rfreg(adapter, path, 0x55, 0xffffffff)); +} + +void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + s8 kfree_offset = 0; + s8 tx_pwr_track_offset = 0; /* TODO: 8814A should consider tx pwr track when setting tx gain offset */ + s8 total_offset; + int i; + + for (i = 0; i < hal_data->NumTotalRFPath; i++) { + kfree_offset = rtw_rf_get_kfree_tx_gain_offset(adapter, i, ch); + total_offset = kfree_offset + tx_pwr_track_offset; + rtw_rf_set_tx_gain_offset(adapter, i, total_offset); + } +} + +bool rtw_is_dfs_range(u32 hi, u32 lo) +{ + return rtw_is_range_overlap(hi, lo, 5720 + 10, 5260 - 10)?_TRUE:_FALSE; +} + +bool rtw_is_dfs_ch(u8 ch, u8 bw, u8 offset) +{ + u32 hi, lo; + + if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) + return _FALSE; + + return rtw_is_dfs_range(hi, lo)?_TRUE:_FALSE; +} + +bool rtw_is_long_cac_range(u32 hi, u32 lo) +{ + return rtw_is_range_overlap(hi, lo, 5660 + 10, 5600 - 10)?_TRUE:_FALSE; +} + +bool rtw_is_long_cac_ch(u8 ch, u8 bw, u8 offset) +{ + u32 hi, lo; + + if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) + return _FALSE; + + return rtw_is_long_cac_range(hi, lo)?_TRUE:_FALSE; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_security.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_security.c new file mode 100644 index 00000000..07295017 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_security.c @@ -0,0 +1,3346 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_SECURITY_C_ + +#include + +static const char *_security_type_str[] = { + "N/A", + "WEP40", + "TKIP", + "TKIP_WM", + "AES", + "WEP104", + "SMS4", + "WEP_WPA", + "BIP", +}; + +const char *security_type_str(u8 value) +{ +#ifdef CONFIG_IEEE80211W + if (value <= _BIP_) +#else + if (value <= _WEP_WPA_MIXED_) +#endif + return _security_type_str[value]; + return NULL; +} + +#ifdef DBG_SW_SEC_CNT +#define WEP_SW_ENC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->wep_sw_enc_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->wep_sw_enc_cnt_mc++; \ + else \ + sec->wep_sw_enc_cnt_uc++; + +#define WEP_SW_DEC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->wep_sw_dec_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->wep_sw_dec_cnt_mc++; \ + else \ + sec->wep_sw_dec_cnt_uc++; + +#define TKIP_SW_ENC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->tkip_sw_enc_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->tkip_sw_enc_cnt_mc++; \ + else \ + sec->tkip_sw_enc_cnt_uc++; + +#define TKIP_SW_DEC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->tkip_sw_dec_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->tkip_sw_dec_cnt_mc++; \ + else \ + sec->tkip_sw_dec_cnt_uc++; + +#define AES_SW_ENC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->aes_sw_enc_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->aes_sw_enc_cnt_mc++; \ + else \ + sec->aes_sw_enc_cnt_uc++; + +#define AES_SW_DEC_CNT_INC(sec, ra) \ + if (is_broadcast_mac_addr(ra)) \ + sec->aes_sw_dec_cnt_bc++; \ + else if (is_multicast_mac_addr(ra)) \ + sec->aes_sw_dec_cnt_mc++; \ + else \ + sec->aes_sw_dec_cnt_uc++; +#else +#define WEP_SW_ENC_CNT_INC(sec, ra) +#define WEP_SW_DEC_CNT_INC(sec, ra) +#define TKIP_SW_ENC_CNT_INC(sec, ra) +#define TKIP_SW_DEC_CNT_INC(sec, ra) +#define AES_SW_ENC_CNT_INC(sec, ra) +#define AES_SW_DEC_CNT_INC(sec, ra) +#endif /* DBG_SW_SEC_CNT */ + +//=====WEP related===== + +#define CRC32_POLY 0x04c11db7 + +struct arc4context +{ + u32 x; + u32 y; + u8 state[256]; +}; + + +static void arcfour_init(struct arc4context *parc4ctx, u8 * key,u32 key_len) +{ + u32 t, u; + u32 keyindex; + u32 stateindex; + u8 * state; + u32 counter; +_func_enter_; + state = parc4ctx->state; + parc4ctx->x = 0; + parc4ctx->y = 0; + for (counter = 0; counter < 256; counter++) + state[counter] = (u8)counter; + keyindex = 0; + stateindex = 0; + for (counter = 0; counter < 256; counter++) + { + t = state[counter]; + stateindex = (stateindex + key[keyindex] + t) & 0xff; + u = state[stateindex]; + state[stateindex] = (u8)t; + state[counter] = (u8)u; + if (++keyindex >= key_len) + keyindex = 0; + } +_func_exit_; +} +static u32 arcfour_byte( struct arc4context *parc4ctx) +{ + u32 x; + u32 y; + u32 sx, sy; + u8 * state; +_func_enter_; + state = parc4ctx->state; + x = (parc4ctx->x + 1) & 0xff; + sx = state[x]; + y = (sx + parc4ctx->y) & 0xff; + sy = state[y]; + parc4ctx->x = x; + parc4ctx->y = y; + state[y] = (u8)sx; + state[x] = (u8)sy; +_func_exit_; + return state[(sx + sy) & 0xff]; +} + + +static void arcfour_encrypt( struct arc4context *parc4ctx, + u8 * dest, + u8 * src, + u32 len) +{ + u32 i; +_func_enter_; + for (i = 0; i < len; i++) + dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); +_func_exit_; +} + +static sint bcrc32initialized = 0; +static u32 crc32_table[256]; + + +static u8 crc32_reverseBit( u8 data) +{ + return( (u8)((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) | ((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01) ); +} + +static void crc32_init(void) +{ +_func_enter_; + if (bcrc32initialized == 1) + goto exit; + else{ + sint i, j; + u32 c; + u8 *p=(u8 *)&c, *p1; + u8 k; + + c = 0x12340000; + + for (i = 0; i < 256; ++i) + { + k = crc32_reverseBit((u8)i); + for (c = ((u32)k) << 24, j = 8; j > 0; --j){ + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + } + p1 = (u8 *)&crc32_table[i]; + + p1[0] = crc32_reverseBit(p[3]); + p1[1] = crc32_reverseBit(p[2]); + p1[2] = crc32_reverseBit(p[1]); + p1[3] = crc32_reverseBit(p[0]); + } + bcrc32initialized= 1; + } +exit: +_func_exit_; +} + +static u32 getcrc32(u8 *buf, sint len) +{ + u8 *p; + u32 crc; +_func_enter_; + if (bcrc32initialized == 0) crc32_init(); + + crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ + + for (p = buf; len > 0; ++p, --len) + { + crc = crc32_table[ (crc ^ *p) & 0xff] ^ (crc >> 8); + } +_func_exit_; + return ~crc; /* transmit complement, per CRC-32 spec */ +} + + +/* + Need to consider the fragment situation +*/ +void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe) +{ // exclude ICV + + unsigned char crc[4]; + struct arc4context mycontext; + + sint curfragnum,length; + u32 keylength; + + u8 *pframe, *payload,*iv; //,*wepkey + u8 wepkey[16]; + u8 hw_hdr_offset=0; + struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + +_func_enter_; + + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + #ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET+EARLY_MODE_INFO_SIZE; + #else + hw_hdr_offset = TXDESC_OFFSET; + #endif +#endif + + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + hw_hdr_offset; + + //start to encrypt each fragment + if((pattrib->encrypt==_WEP40_)||(pattrib->encrypt==_WEP104_)) + { + keylength=psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex]; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++) + { + iv=pframe+pattrib->hdrlen; + _rtw_memcpy(&wepkey[0], iv, 3); + _rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0],keylength); + payload=pframe+pattrib->iv_len+pattrib->hdrlen; + + if((curfragnum+1)==pattrib->nr_frags) + { //the last fragment + + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length)); + + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + } + else + { + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length)); + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + pframe+=pxmitpriv->frag_len; + pframe=(u8 *)RND4((SIZE_PTR)(pframe)); + + } + + } + + WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra); + } + +_func_exit_; + +} + +void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe) +{ + // exclude ICV + u8 crc[4]; + struct arc4context mycontext; + sint length; + u32 keylength; + u8 *pframe, *payload,*iv,wepkey[16]; + u8 keyindex; + struct rx_pkt_attrib *prxattrib = &(((union recv_frame*)precvframe)->u.hdr.attrib); + struct security_priv *psecuritypriv=&padapter->securitypriv; + +_func_enter_; + + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + + //start to decrypt recvframe + if((prxattrib->encrypt==_WEP40_)||(prxattrib->encrypt==_WEP104_)) + { + iv=pframe+prxattrib->hdrlen; + //keyindex=(iv[3]&0x3); + keyindex = prxattrib->key_index; + keylength=psecuritypriv->dot11DefKeylen[keyindex]; + _rtw_memcpy(&wepkey[0], iv, 3); + //_rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0],keylength); + _rtw_memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0],keylength); + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + + payload=pframe+prxattrib->iv_len+prxattrib->hdrlen; + + //decrypt payload include icv + arcfour_init(&mycontext, wepkey,3+keylength); + arcfour_encrypt(&mycontext, payload, payload, length); + + //calculate icv and compare the icv + *((u32 *)crc)=le32_to_cpu(getcrc32(payload,length-4)); + + if(crc[3]!=payload[length-1] || crc[2]!=payload[length-2] || crc[1]!=payload[length-3] || crc[0]!=payload[length-4]) + { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n", + crc[3],payload[length-1],crc[2],payload[length-2],crc[1],payload[length-3],crc[0],payload[length-4])); + } + + WEP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra); + } + +_func_exit_; + + return; + +} + +//3 =====TKIP related===== + +static u32 secmicgetuint32( u8 * p ) +// Convert from Byte[] to Us4Byte32 in a portable way +{ + s32 i; + u32 res = 0; +_func_enter_; + for( i=0; i<4; i++ ) + { + res |= ((u32)(*p++)) << (8*i); + } +_func_exit_; + return res; +} + +static void secmicputuint32( u8 * p, u32 val ) +// Convert from Us4Byte32 to Byte[] in a portable way +{ + long i; +_func_enter_; + for( i=0; i<4; i++ ) + { + *p++ = (u8) (val & 0xff); + val >>= 8; + } +_func_exit_; +} + +static void secmicclear(struct mic_data *pmicdata) +{ +// Reset the state to the empty message. +_func_enter_; + pmicdata->L = pmicdata->K0; + pmicdata->R = pmicdata->K1; + pmicdata->nBytesInM = 0; + pmicdata->M = 0; +_func_exit_; +} + +void rtw_secmicsetkey(struct mic_data *pmicdata, u8 * key ) +{ + // Set the key +_func_enter_; + pmicdata->K0 = secmicgetuint32( key ); + pmicdata->K1 = secmicgetuint32( key + 4 ); + // and reset the message + secmicclear(pmicdata); +_func_exit_; +} + +void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b ) +{ +_func_enter_; + // Append the byte to our word-sized buffer + pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM); + pmicdata->nBytesInM++; + // Process the word if it is full. + if( pmicdata->nBytesInM >= 4 ) + { + pmicdata->L ^= pmicdata->M; + pmicdata->R ^= ROL32( pmicdata->L, 17 ); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ROL32( pmicdata->L, 3 ); + pmicdata->L += pmicdata->R; + pmicdata->R ^= ROR32( pmicdata->L, 2 ); + pmicdata->L += pmicdata->R; + // Clear the buffer + pmicdata->M = 0; + pmicdata->nBytesInM = 0; + } +_func_exit_; +} + +void rtw_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes ) +{ +_func_enter_; + // This is simple + while( nbytes > 0 ) + { + rtw_secmicappendbyte(pmicdata, *src++ ); + nbytes--; + } +_func_exit_; +} + +void rtw_secgetmic(struct mic_data *pmicdata, u8 * dst ) +{ +_func_enter_; + // Append the minimum padding + rtw_secmicappendbyte(pmicdata, 0x5a ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + rtw_secmicappendbyte(pmicdata, 0 ); + // and then zeroes until the length is a multiple of 4 + while( pmicdata->nBytesInM != 0 ) + { + rtw_secmicappendbyte(pmicdata, 0 ); + } + // The appendByte function has already computed the result. + secmicputuint32( dst, pmicdata->L ); + secmicputuint32( dst+4, pmicdata->R ); + // Reset to the empty message. + secmicclear(pmicdata); +_func_exit_; +} + + +void rtw_seccalctkipmic(u8 * key,u8 *header,u8 *data,u32 data_len,u8 *mic_code, u8 pri) +{ + + struct mic_data micdata; + u8 priority[4]={0x0,0x0,0x0,0x0}; +_func_enter_; + rtw_secmicsetkey(&micdata, key); + priority[0]=pri; + + /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ + if(header[1]&1){ //ToDS==1 + rtw_secmicappend(&micdata, &header[16], 6); //DA + if(header[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &header[24], 6); + else + rtw_secmicappend(&micdata, &header[10], 6); + } + else{ //ToDS==0 + rtw_secmicappend(&micdata, &header[4], 6); //DA + if(header[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &header[16], 6); + else + rtw_secmicappend(&micdata, &header[10], 6); + + } + rtw_secmicappend(&micdata, &priority[0], 4); + + + rtw_secmicappend(&micdata, data, data_len); + + rtw_secgetmic(&micdata,mic_code); +_func_exit_; +} + + + + +/* macros for extraction/creation of unsigned char/unsigned short values */ +#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) +#define Lo8(v16) ((u8)( (v16) & 0x00FF)) +#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) +#define Lo16(v32) ((u16)( (v32) & 0xFFFF)) +#define Hi16(v32) ((u16)(((v32) >>16) & 0xFFFF)) +#define Mk16(hi,lo) ((lo) ^ (((u16)(hi)) << 8)) + +/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ +#define TK16(N) Mk16(tk[2*(N)+1],tk[2*(N)]) + +/* S-box lookup: 16 bits --> 16 bits */ +#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) + +/* fixed algorithm "parameters" */ +#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ +#define TA_SIZE 6 /* 48-bit transmitter address */ +#define TK_SIZE 16 /* 128-bit temporal key */ +#define P1K_SIZE 10 /* 80-bit Phase1 key */ +#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ + + +/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ +static const unsigned short Sbox1[2][256]= /* Sbox for hash (can be in ROM) */ +{ { + 0xC6A5,0xF884,0xEE99,0xF68D,0xFF0D,0xD6BD,0xDEB1,0x9154, + 0x6050,0x0203,0xCEA9,0x567D,0xE719,0xB562,0x4DE6,0xEC9A, + 0x8F45,0x1F9D,0x8940,0xFA87,0xEF15,0xB2EB,0x8EC9,0xFB0B, + 0x41EC,0xB367,0x5FFD,0x45EA,0x23BF,0x53F7,0xE496,0x9B5B, + 0x75C2,0xE11C,0x3DAE,0x4C6A,0x6C5A,0x7E41,0xF502,0x834F, + 0x685C,0x51F4,0xD134,0xF908,0xE293,0xAB73,0x6253,0x2A3F, + 0x080C,0x9552,0x4665,0x9D5E,0x3028,0x37A1,0x0A0F,0x2FB5, + 0x0E09,0x2436,0x1B9B,0xDF3D,0xCD26,0x4E69,0x7FCD,0xEA9F, + 0x121B,0x1D9E,0x5874,0x342E,0x362D,0xDCB2,0xB4EE,0x5BFB, + 0xA4F6,0x764D,0xB761,0x7DCE,0x527B,0xDD3E,0x5E71,0x1397, + 0xA6F5,0xB968,0x0000,0xC12C,0x4060,0xE31F,0x79C8,0xB6ED, + 0xD4BE,0x8D46,0x67D9,0x724B,0x94DE,0x98D4,0xB0E8,0x854A, + 0xBB6B,0xC52A,0x4FE5,0xED16,0x86C5,0x9AD7,0x6655,0x1194, + 0x8ACF,0xE910,0x0406,0xFE81,0xA0F0,0x7844,0x25BA,0x4BE3, + 0xA2F3,0x5DFE,0x80C0,0x058A,0x3FAD,0x21BC,0x7048,0xF104, + 0x63DF,0x77C1,0xAF75,0x4263,0x2030,0xE51A,0xFD0E,0xBF6D, + 0x814C,0x1814,0x2635,0xC32F,0xBEE1,0x35A2,0x88CC,0x2E39, + 0x9357,0x55F2,0xFC82,0x7A47,0xC8AC,0xBAE7,0x322B,0xE695, + 0xC0A0,0x1998,0x9ED1,0xA37F,0x4466,0x547E,0x3BAB,0x0B83, + 0x8CCA,0xC729,0x6BD3,0x283C,0xA779,0xBCE2,0x161D,0xAD76, + 0xDB3B,0x6456,0x744E,0x141E,0x92DB,0x0C0A,0x486C,0xB8E4, + 0x9F5D,0xBD6E,0x43EF,0xC4A6,0x39A8,0x31A4,0xD337,0xF28B, + 0xD532,0x8B43,0x6E59,0xDAB7,0x018C,0xB164,0x9CD2,0x49E0, + 0xD8B4,0xACFA,0xF307,0xCF25,0xCAAF,0xF48E,0x47E9,0x1018, + 0x6FD5,0xF088,0x4A6F,0x5C72,0x3824,0x57F1,0x73C7,0x9751, + 0xCB23,0xA17C,0xE89C,0x3E21,0x96DD,0x61DC,0x0D86,0x0F85, + 0xE090,0x7C42,0x71C4,0xCCAA,0x90D8,0x0605,0xF701,0x1C12, + 0xC2A3,0x6A5F,0xAEF9,0x69D0,0x1791,0x9958,0x3A27,0x27B9, + 0xD938,0xEB13,0x2BB3,0x2233,0xD2BB,0xA970,0x0789,0x33A7, + 0x2DB6,0x3C22,0x1592,0xC920,0x8749,0xAAFF,0x5078,0xA57A, + 0x038F,0x59F8,0x0980,0x1A17,0x65DA,0xD731,0x84C6,0xD0B8, + 0x82C3,0x29B0,0x5A77,0x1E11,0x7BCB,0xA8FC,0x6DD6,0x2C3A, + }, + + + { /* second half of table is unsigned char-reversed version of first! */ + 0xA5C6,0x84F8,0x99EE,0x8DF6,0x0DFF,0xBDD6,0xB1DE,0x5491, + 0x5060,0x0302,0xA9CE,0x7D56,0x19E7,0x62B5,0xE64D,0x9AEC, + 0x458F,0x9D1F,0x4089,0x87FA,0x15EF,0xEBB2,0xC98E,0x0BFB, + 0xEC41,0x67B3,0xFD5F,0xEA45,0xBF23,0xF753,0x96E4,0x5B9B, + 0xC275,0x1CE1,0xAE3D,0x6A4C,0x5A6C,0x417E,0x02F5,0x4F83, + 0x5C68,0xF451,0x34D1,0x08F9,0x93E2,0x73AB,0x5362,0x3F2A, + 0x0C08,0x5295,0x6546,0x5E9D,0x2830,0xA137,0x0F0A,0xB52F, + 0x090E,0x3624,0x9B1B,0x3DDF,0x26CD,0x694E,0xCD7F,0x9FEA, + 0x1B12,0x9E1D,0x7458,0x2E34,0x2D36,0xB2DC,0xEEB4,0xFB5B, + 0xF6A4,0x4D76,0x61B7,0xCE7D,0x7B52,0x3EDD,0x715E,0x9713, + 0xF5A6,0x68B9,0x0000,0x2CC1,0x6040,0x1FE3,0xC879,0xEDB6, + 0xBED4,0x468D,0xD967,0x4B72,0xDE94,0xD498,0xE8B0,0x4A85, + 0x6BBB,0x2AC5,0xE54F,0x16ED,0xC586,0xD79A,0x5566,0x9411, + 0xCF8A,0x10E9,0x0604,0x81FE,0xF0A0,0x4478,0xBA25,0xE34B, + 0xF3A2,0xFE5D,0xC080,0x8A05,0xAD3F,0xBC21,0x4870,0x04F1, + 0xDF63,0xC177,0x75AF,0x6342,0x3020,0x1AE5,0x0EFD,0x6DBF, + 0x4C81,0x1418,0x3526,0x2FC3,0xE1BE,0xA235,0xCC88,0x392E, + 0x5793,0xF255,0x82FC,0x477A,0xACC8,0xE7BA,0x2B32,0x95E6, + 0xA0C0,0x9819,0xD19E,0x7FA3,0x6644,0x7E54,0xAB3B,0x830B, + 0xCA8C,0x29C7,0xD36B,0x3C28,0x79A7,0xE2BC,0x1D16,0x76AD, + 0x3BDB,0x5664,0x4E74,0x1E14,0xDB92,0x0A0C,0x6C48,0xE4B8, + 0x5D9F,0x6EBD,0xEF43,0xA6C4,0xA839,0xA431,0x37D3,0x8BF2, + 0x32D5,0x438B,0x596E,0xB7DA,0x8C01,0x64B1,0xD29C,0xE049, + 0xB4D8,0xFAAC,0x07F3,0x25CF,0xAFCA,0x8EF4,0xE947,0x1810, + 0xD56F,0x88F0,0x6F4A,0x725C,0x2438,0xF157,0xC773,0x5197, + 0x23CB,0x7CA1,0x9CE8,0x213E,0xDD96,0xDC61,0x860D,0x850F, + 0x90E0,0x427C,0xC471,0xAACC,0xD890,0x0506,0x01F7,0x121C, + 0xA3C2,0x5F6A,0xF9AE,0xD069,0x9117,0x5899,0x273A,0xB927, + 0x38D9,0x13EB,0xB32B,0x3322,0xBBD2,0x70A9,0x8907,0xA733, + 0xB62D,0x223C,0x9215,0x20C9,0x4987,0xFFAA,0x7850,0x7AA5, + 0x8F03,0xF859,0x8009,0x171A,0xDA65,0x31D7,0xC684,0xB8D0, + 0xC382,0xB029,0x775A,0x111E,0xCB7B,0xFCA8,0xD66D,0x3A2C, + } +}; + + /* +********************************************************************** +* Routine: Phase 1 -- generate P1K, given TA, TK, IV32 +* +* Inputs: +* tk[] = temporal key [128 bits] +* ta[] = transmitter's MAC address [ 48 bits] +* iv32 = upper 32 bits of IV [ 32 bits] +* Output: +* p1k[] = Phase 1 key [ 80 bits] +* +* Note: +* This function only needs to be called every 2**16 packets, +* although in theory it could be called every packet. +* +********************************************************************** +*/ +static void phase1(u16 *p1k,const u8 *tk,const u8 *ta,u32 iv32) +{ + sint i; +_func_enter_; + /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ + p1k[0] = Lo16(iv32); + p1k[1] = Hi16(iv32); + p1k[2] = Mk16(ta[1],ta[0]); /* use TA[] as little-endian */ + p1k[3] = Mk16(ta[3],ta[2]); + p1k[4] = Mk16(ta[5],ta[4]); + + /* Now compute an unbalanced Feistel cipher with 80-bit block */ + /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ + for (i=0; i < PHASE1_LOOP_CNT ;i++) + { /* Each add operation here is mod 2**16 */ + p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0)); + p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2)); + p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4)); + p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6)); + p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0)); + p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ + } +_func_exit_; +} + + +/* +********************************************************************** +* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 +* +* Inputs: +* tk[] = Temporal key [128 bits] +* p1k[] = Phase 1 output key [ 80 bits] +* iv16 = low 16 bits of IV counter [ 16 bits] +* Output: +* rc4key[] = the key used to encrypt the packet [128 bits] +* +* Note: +* The value {TA,IV32,IV16} for Phase1/Phase2 must be unique +* across all packets using the same key TK value. Then, for a +* given value of TK[], this TKIP48 construction guarantees that +* the final RC4KEY value is unique across all packets. +* +* Suggested implementation optimization: if PPK[] is "overlaid" +* appropriately on RC4KEY[], there is no need for the final +* for loop below that copies the PPK[] result into RC4KEY[]. +* +********************************************************************** +*/ +static void phase2(u8 *rc4key,const u8 *tk,const u16 *p1k,u16 iv16) +{ + sint i; + u16 PPK[6]; /* temporary key for mixing */ +_func_enter_; + /* Note: all adds in the PPK[] equations below are mod 2**16 */ + for (i=0;i<5;i++) PPK[i]=p1k[i]; /* first, copy P1K to PPK */ + PPK[5] = p1k[4] +iv16; /* next, add in IV16 */ + + /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ + PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ + PPK[1] += _S_(PPK[0] ^ TK16(1)); + PPK[2] += _S_(PPK[1] ^ TK16(2)); + PPK[3] += _S_(PPK[2] ^ TK16(3)); + PPK[4] += _S_(PPK[3] ^ TK16(4)); + PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ + + /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ + PPK[0] += RotR1(PPK[5] ^ TK16(6)); + PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ + PPK[2] += RotR1(PPK[1]); + PPK[3] += RotR1(PPK[2]); + PPK[4] += RotR1(PPK[3]); + PPK[5] += RotR1(PPK[4]); + /* Note: At this point, for a given key TK[0..15], the 96-bit output */ + /* value PPK[0..5] is guaranteed to be unique, as a function */ + /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */ + /* is now a keyed permutation of {TA,IV32,IV16}. */ + + /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ + rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ + rc4key[1] =(Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ + rc4key[2] = Lo8(iv16); + rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); + + + /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ + for (i=0;i<6;i++) + { + rc4key[4+2*i] = Lo8(PPK[i]); + rc4key[5+2*i] = Hi8(PPK[i]); + } +_func_exit_; +} + + +//The hlen isn't include the IV +u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe) +{ // exclude ICV + u16 pnl; + u32 pnh; + u8 rc4key[16]; + u8 ttkey[16]; + u8 crc[4]; + u8 hw_hdr_offset = 0; + struct arc4context mycontext; + sint curfragnum,length; + u32 prwskeylen; + + u8 *pframe, *payload,*iv,*prwskey; + union pn48 dot11txpn; + //struct sta_info *stainfo; + struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + u32 res=_SUCCESS; +_func_enter_; + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + #ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET+EARLY_MODE_INFO_SIZE; + #else + hw_hdr_offset = TXDESC_OFFSET; + #endif +#endif + + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + hw_hdr_offset; + //4 start to encrypt each fragment + if(pattrib->encrypt==_TKIP_){ + +/* + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } +*/ + //if (stainfo!=NULL) + { +/* + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } +*/ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_encrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(pattrib->ra)) + { + prwskey=psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + } + else + { + //prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + prwskey=pattrib->dot118021x_UncstKey.skey; + } + + prwskeylen=16; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + iv=pframe+pattrib->hdrlen; + payload=pframe+pattrib->iv_len+pattrib->hdrlen; + + GET_TKIP_PN(iv, dot11txpn); + + pnl=(u16)(dot11txpn.val); + pnh=(u32)(dot11txpn.val>>16); + + phase1((u16 *)&ttkey[0],prwskey,&pattrib->ta[0],pnh); + + phase2(&rc4key[0],prwskey,(u16 *)&ttkey[0],pnl); + + if((curfragnum+1)==pattrib->nr_frags){ //4 the last fragment + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + RT_TRACE(_module_rtl871x_security_c_,_drv_info_,("pattrib->iv_len =%x, pattrib->icv_len =%x\n", pattrib->iv_len,pattrib->icv_len)); + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));/* modified by Amy*/ + + arcfour_init(&mycontext, rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));/* modified by Amy*/ + arcfour_init(&mycontext,rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + arcfour_encrypt(&mycontext, payload+length, crc, 4); + + pframe+=pxmitpriv->frag_len; + pframe=(u8 *)RND4((SIZE_PTR)(pframe)); + + } + } + + TKIP_SW_ENC_CNT_INC(psecuritypriv,pattrib->ra); + } +/* + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_encrypt: stainfo==NULL!!!\n")); + DBG_871X("%s, psta==NUL\n", __func__); + res=_FAIL; + } +*/ + + } +_func_exit_; + return res; + +} + + +//The hlen isn't include the IV +u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe) +{ // exclude ICV + u16 pnl; + u32 pnh; + u8 rc4key[16]; + u8 ttkey[16]; + u8 crc[4]; + struct arc4context mycontext; + sint length; + u32 prwskeylen; + + u8 *pframe, *payload,*iv,*prwskey; + union pn48 dot11txpn; + struct sta_info *stainfo; + struct rx_pkt_attrib *prxattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; +// struct recv_priv *precvpriv=&padapter->recvpriv; + u32 res=_SUCCESS; + +_func_enter_; + + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + + //4 start to decrypt recvframe + if(prxattrib->encrypt==_TKIP_){ + + stainfo=rtw_get_stainfo(&padapter->stapriv ,&prxattrib->ta[0] ); + if (stainfo!=NULL){ + + if(IS_MCAST(prxattrib->ra)) + { + static u32 start = 0; + static u32 no_gkey_bc_cnt = 0; + static u32 no_gkey_mc_cnt = 0; + + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + + if (start == 0) + start = rtw_get_current_time(); + + if (is_broadcast_mac_addr(prxattrib->ra)) + no_gkey_bc_cnt++; + else + no_gkey_mc_cnt++; + + if (rtw_get_passing_time_ms(start) > 1000) { + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = rtw_get_current_time(); + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + } + goto exit; + } + + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = 0; + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + + //DBG_871X("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n"); + //prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + prwskeylen=16; + } + else + { + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + prwskeylen=16; + } + + iv=pframe+prxattrib->hdrlen; + payload=pframe+prxattrib->iv_len+prxattrib->hdrlen; + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + + GET_TKIP_PN(iv, dot11txpn); + + pnl=(u16)(dot11txpn.val); + pnh=(u32)(dot11txpn.val>>16); + + phase1((u16 *)&ttkey[0],prwskey,&prxattrib->ta[0],pnh); + phase2(&rc4key[0],prwskey,(unsigned short *)&ttkey[0],pnl); + + //4 decrypt payload include icv + + arcfour_init(&mycontext, rc4key,16); + arcfour_encrypt(&mycontext, payload, payload, length); + + *((u32 *)crc)=le32_to_cpu(getcrc32(payload,length-4)); + + if(crc[3]!=payload[length-1] || crc[2]!=payload[length-2] || crc[1]!=payload[length-3] || crc[0]!=payload[length-4]) + { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](%x) || crc[1](%x)!=payload[length-3](%x) || crc[0](%x)!=payload[length-4](%x)\n", + crc[3],payload[length-1],crc[2],payload[length-2],crc[1],payload[length-3],crc[0],payload[length-4])); + res=_FAIL; + } + + TKIP_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra); + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_tkip_decrypt: stainfo==NULL!!!\n")); + res=_FAIL; + } + + } +_func_exit_; +exit: + return res; + +} + + +//3 =====AES related===== + + + +#define MAX_MSG_SIZE 2048 +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + + static u8 sbox_table[256] = + { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + }; + +/*****************************/ +/**** Function Prototypes ****/ +/*****************************/ + +static void bitwise_xor(u8 *ina, u8 *inb, u8 *out); +static void construct_mic_iv( + u8 *mic_header1, + sint qc_exists, + sint a4_exists, + u8 *mpdu, + uint payload_length, + u8 * pn_vector, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void construct_mic_header1( + u8 *mic_header1, + sint header_length, + u8 *mpdu, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void construct_mic_header2( + u8 *mic_header2, + u8 *mpdu, + sint a4_exists, + sint qc_exists); +static void construct_ctr_preload( + u8 *ctr_preload, + sint a4_exists, + sint qc_exists, + u8 *mpdu, + u8 *pn_vector, + sint c, + uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use +static void xor_128(u8 *a, u8 *b, u8 *out); +static void xor_32(u8 *a, u8 *b, u8 *out); +static u8 sbox(u8 a); +static void next_key(u8 *key, sint round); +static void byte_sub(u8 *in, u8 *out); +static void shift_row(u8 *in, u8 *out); +static void mix_column(u8 *in, u8 *out); +#ifndef PLATFORM_FREEBSD +static void add_round_key( u8 *shiftrow_in, + u8 *mcol_in, + u8 *block_in, + sint round, + u8 *out); +#endif //PLATFORM_FREEBSD +static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext); + + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +static void xor_128(u8 *a, u8 *b, u8 *out) +{ + sint i; +_func_enter_; + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +_func_exit_; +} + + +static void xor_32(u8 *a, u8 *b, u8 *out) +{ + sint i; +_func_enter_; + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +_func_exit_; +} + + +static u8 sbox(u8 a) +{ + return sbox_table[(sint)a]; +} + + +static void next_key(u8 *key, sint round) +{ + u8 rcon; + u8 sbox_key[4]; + u8 rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; +_func_enter_; + sbox_key[0] = sbox(key[13]); + sbox_key[1] = sbox(key[14]); + sbox_key[2] = sbox(key[15]); + sbox_key[3] = sbox(key[12]); + + rcon = rcon_table[round]; + + xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon; + + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); +_func_exit_; +} + + +static void byte_sub(u8 *in, u8 *out) +{ + sint i; +_func_enter_; + for (i=0; i< 16; i++) + { + out[i] = sbox(in[i]); + } +_func_exit_; +} + + +static void shift_row(u8 *in, u8 *out) +{ +_func_enter_; + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; +_func_exit_; +} + + +static void mix_column(u8 *in, u8 *out) +{ + sint i; + u8 add1b[4]; + u8 add1bf7[4]; + u8 rotl[4]; + u8 swap_halfs[4]; + u8 andf7[4]; + u8 rotr[4]; + u8 temp[4]; + u8 tempb[4]; +_func_enter_; + for (i=0 ; i<4; i++) + { + if ((in[i] & 0x80)== 0x80) + add1b[i] = 0x1b; + else + add1b[i] = 0x00; + } + + swap_halfs[0] = in[2]; /* Swap halfs */ + swap_halfs[1] = in[3]; + swap_halfs[2] = in[0]; + swap_halfs[3] = in[1]; + + rotl[0] = in[3]; /* Rotate left 8 bits */ + rotl[1] = in[0]; + rotl[2] = in[1]; + rotl[3] = in[2]; + + andf7[0] = in[0] & 0x7f; + andf7[1] = in[1] & 0x7f; + andf7[2] = in[2] & 0x7f; + andf7[3] = in[3] & 0x7f; + + for (i = 3; i>0; i--) /* logical shift left 1 bit */ + { + andf7[i] = andf7[i] << 1; + if ((andf7[i-1] & 0x80) == 0x80) + { + andf7[i] = (andf7[i] | 0x01); + } + } + andf7[0] = andf7[0] << 1; + andf7[0] = andf7[0] & 0xfe; + + xor_32(add1b, andf7, add1bf7); + + xor_32(in, add1bf7, rotr); + + temp[0] = rotr[0]; /* Rotate right 8 bits */ + rotr[0] = rotr[1]; + rotr[1] = rotr[2]; + rotr[2] = rotr[3]; + rotr[3] = temp[0]; + + xor_32(add1bf7, rotr, temp); + xor_32(swap_halfs, rotl,tempb); + xor_32(temp, tempb, out); +_func_exit_; +} + + +static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) +{ + sint round; + sint i; + u8 intermediatea[16]; + u8 intermediateb[16]; + u8 round_key[16]; +_func_enter_; + for(i=0; i<16; i++) round_key[i] = key[i]; + + for (round = 0; round < 11; round++) + { + if (round == 0) + { + xor_128(round_key, data, ciphertext); + next_key(round_key, round); + } + else if (round == 10) + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + xor_128(intermediateb, round_key, ciphertext); + } + else /* 1 - 9 */ + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + mix_column(&intermediateb[0], &intermediatea[0]); + mix_column(&intermediateb[4], &intermediatea[4]); + mix_column(&intermediateb[8], &intermediatea[8]); + mix_column(&intermediateb[12], &intermediatea[12]); + xor_128(intermediatea, round_key, ciphertext); + next_key(round_key, round); + } + } +_func_exit_; +} + + +/************************************************/ +/* construct_mic_iv() */ +/* Builds the MIC IV from header fields and PN */ +/* Baron think the function is construct CCM */ +/* nonce */ +/************************************************/ +static void construct_mic_iv( + u8 *mic_iv, + sint qc_exists, + sint a4_exists, + u8 *mpdu, + uint payload_length, + u8 *pn_vector, + uint frtype// add for CONFIG_IEEE80211W, none 11w also can use + ) +{ + sint i; +_func_enter_; + mic_iv[0] = 0x59; + if (qc_exists && a4_exists) mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ + if (qc_exists && !a4_exists) mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ + if (!qc_exists) mic_iv[1] = 0x00; +#ifdef CONFIG_IEEE80211W + //802.11w management frame should set management bit(4) + if(frtype == WIFI_MGT_TYPE) + mic_iv[1] |= BIT(4); +#endif //CONFIG_IEEE80211W + for (i = 2; i < 8; i++) + mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ + #ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */ + #else + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ + #endif + mic_iv[14] = (unsigned char) (payload_length / 256); + mic_iv[15] = (unsigned char) (payload_length % 256); +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header1() */ +/* Builds the first MIC header block from */ +/* header fields. */ +/* Build AAD SC,A1,A2 */ +/************************************************/ +static void construct_mic_header1( + u8 *mic_header1, + sint header_length, + u8 *mpdu, + uint frtype// add for CONFIG_IEEE80211W, none 11w also can use + ) +{ +_func_enter_; + mic_header1[0] = (u8)((header_length - 2) / 256); + mic_header1[1] = (u8)((header_length - 2) % 256); +#ifdef CONFIG_IEEE80211W + //802.11w management frame don't AND subtype bits 4,5,6 of frame control field + if(frtype == WIFI_MGT_TYPE) + mic_header1[2] = mpdu[0]; + else +#endif //CONFIG_IEEE80211W + mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ + + mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ + mic_header1[4] = mpdu[4]; /* A1 */ + mic_header1[5] = mpdu[5]; + mic_header1[6] = mpdu[6]; + mic_header1[7] = mpdu[7]; + mic_header1[8] = mpdu[8]; + mic_header1[9] = mpdu[9]; + mic_header1[10] = mpdu[10]; /* A2 */ + mic_header1[11] = mpdu[11]; + mic_header1[12] = mpdu[12]; + mic_header1[13] = mpdu[13]; + mic_header1[14] = mpdu[14]; + mic_header1[15] = mpdu[15]; +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/************************************************/ +static void construct_mic_header2( + u8 *mic_header2, + u8 *mpdu, + sint a4_exists, + sint qc_exists + ) +{ + sint i; +_func_enter_; + for (i = 0; i<16; i++) mic_header2[i]=0x00; + + mic_header2[0] = mpdu[16]; /* A3 */ + mic_header2[1] = mpdu[17]; + mic_header2[2] = mpdu[18]; + mic_header2[3] = mpdu[19]; + mic_header2[4] = mpdu[20]; + mic_header2[5] = mpdu[21]; + + //mic_header2[6] = mpdu[22] & 0xf0; /* SC */ + mic_header2[6] = 0x00; + mic_header2[7] = 0x00; /* mpdu[23]; */ + + + if (!qc_exists && a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + } + + if (qc_exists && !a4_exists) + { + mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ + mic_header2[9] = mpdu[25] & 0x00; + } + + if (qc_exists && a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + mic_header2[14] = mpdu[30] & 0x0f; + mic_header2[15] = mpdu[31] & 0x00; + } + +_func_exit_; +} + + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/* Baron think the function is construct CCM */ +/* nonce */ +/************************************************/ +static void construct_ctr_preload( + u8 *ctr_preload, + sint a4_exists, + sint qc_exists, + u8 *mpdu, + u8 *pn_vector, + sint c, + uint frtype // add for CONFIG_IEEE80211W, none 11w also can use + ) +{ + sint i = 0; +_func_enter_; + for (i=0; i<16; i++) ctr_preload[i] = 0x00; + i = 0; + + ctr_preload[0] = 0x01; /* flag */ + if (qc_exists && a4_exists) + ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ + if (qc_exists && !a4_exists) + ctr_preload[1] = mpdu[24] & 0x0f; +#ifdef CONFIG_IEEE80211W + //802.11w management frame should set management bit(4) + if(frtype == WIFI_MGT_TYPE) + ctr_preload[1] |= BIT(4); +#endif //CONFIG_IEEE80211W + for (i = 2; i < 8; i++) + ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ + #ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */ + #else + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ + #endif + ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */ + ctr_preload[15] = (unsigned char) (c % 256); +_func_exit_; +} + + +/************************************/ +/* bitwise_xor() */ +/* A 128 bit, bitwise exclusive or */ +/************************************/ +static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) +{ + sint i; +_func_enter_; + for (i=0; i<16; i++) + { + out[i] = ina[i] ^ inb[i]; + } +_func_exit_; +} + + +static sint aes_cipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) +{ +// /*static*/ unsigned char message[MAX_MSG_SIZE]; + uint qc_exists, a4_exists, i, j, payload_remainder, + num_blocks, payload_index; + + u8 pn_vector[6]; + u8 mic_iv[16]; + u8 mic_header1[16]; + u8 mic_header2[16]; + u8 ctr_preload[16]; + + /* Intermediate Buffers */ + u8 chain_buffer[16]; + u8 aes_out[16]; + u8 padded_buffer[16]; + u8 mic[8]; +// uint offset = 0; + uint frtype = GetFrameType(pframe); + uint frsubtype = GetFrameSubType(pframe); + +_func_enter_; + frsubtype=frsubtype>>4; + + + _rtw_memset((void *)mic_iv, 0, 16); + _rtw_memset((void *)mic_header1, 0, 16); + _rtw_memset((void *)mic_header2, 0, 16); + _rtw_memset((void *)ctr_preload, 0, 16); + _rtw_memset((void *)chain_buffer, 0, 16); + _rtw_memset((void *)aes_out, 0, 16); + _rtw_memset((void *)padded_buffer, 0, 16); + + if ((hdrlen == WLAN_HDR_A3_LEN )||(hdrlen == WLAN_HDR_A3_QOS_LEN)) + a4_exists = 0; + else + a4_exists = 1; + + if ( + ((frtype|frsubtype) == WIFI_DATA_CFACK) || + ((frtype|frsubtype) == WIFI_DATA_CFPOLL)|| + ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) + { + qc_exists = 1; + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + } + // add for CONFIG_IEEE80211W, none 11w also can use + else if ((frtype == WIFI_DATA) && + ((frsubtype == 0x08) || + (frsubtype == 0x09)|| + (frsubtype == 0x0a)|| + (frsubtype == 0x0b))) + { + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + qc_exists = 1; + } + else + qc_exists = 0; + + pn_vector[0]=pframe[hdrlen]; + pn_vector[1]=pframe[hdrlen+1]; + pn_vector[2]=pframe[hdrlen+4]; + pn_vector[3]=pframe[hdrlen+5]; + pn_vector[4]=pframe[hdrlen+6]; + pn_vector[5]=pframe[hdrlen+7]; + + construct_mic_iv( + mic_iv, + qc_exists, + a4_exists, + pframe, //message, + plen, + pn_vector, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + construct_mic_header1( + mic_header1, + hdrlen, + pframe, //message + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + construct_mic_header2( + mic_header2, + pframe, //message, + a4_exists, + qc_exists + ); + + + payload_remainder = plen % 16; + num_blocks = plen / 16; + + /* Find start of payload */ + payload_index = (hdrlen + 8); + + /* Calculate MIC */ + aes128k128d(key, mic_iv, aes_out); + bitwise_xor(aes_out, mic_header1, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + bitwise_xor(aes_out, mic_header2, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + for (i = 0; i < num_blocks; i++) + { + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);//bitwise_xor(aes_out, &message[payload_index], chain_buffer); + + payload_index += 16; + aes128k128d(key, chain_buffer, aes_out); + } + + /* Add on the final payload block if it needs padding */ + if (payload_remainder > 0) + { + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index++];//padded_buffer[j] = message[payload_index++]; + } + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + } + + for (j = 0 ; j < 8; j++) mic[j] = aes_out[j]; + + /* Insert MIC into payload */ + for (j = 0; j < 8; j++) + pframe[payload_index+j] = mic[j]; //message[payload_index+j] = mic[j]; + + payload_index = hdrlen + 8; + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, //message, + pn_vector, + i+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);//bitwise_xor(aes_out, &message[payload_index], chain_buffer); + for (j=0; j<16;j++) pframe[payload_index++] = chain_buffer[j];//for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, //message, + pn_vector, + num_blocks+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index+j];//padded_buffer[j] = message[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; jattrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + +// uint offset = 0; + u32 res=_SUCCESS; +_func_enter_; + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return _FAIL; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + + (((struct xmit_frame*)pxmitframe)->pkt_offset * PACKET_OFFSET_SZ); +#else + #ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET+EARLY_MODE_INFO_SIZE; + #else + hw_hdr_offset = TXDESC_OFFSET; + #endif +#endif + + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + hw_hdr_offset; + + //4 start to encrypt each fragment + if((pattrib->encrypt==_AES_)){ +/* + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } +*/ + //if (stainfo!=NULL) + { +/* + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } +*/ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_encrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(pattrib->ra)) + { + prwskey=psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + } + else + { + //prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + prwskey=pattrib->dot118021x_UncstKey.skey; + } + +#ifdef CONFIG_TDLS + { + /* Swencryption */ + struct sta_info *ptdls_sta; + ptdls_sta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->dst[0] ); + if((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) ) + { + DBG_871X("[%s] for tdls link\n", __FUNCTION__); + prwskey=&ptdls_sta->tpk.tk[0]; + } + } +#endif //CONFIG_TDLS + + prwskeylen=16; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + + if((curfragnum+1)==pattrib->nr_frags){ //4 the last fragment + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len; + + aes_cipher(prwskey,pattrib->hdrlen,pframe, length); + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ; + + aes_cipher(prwskey,pattrib->hdrlen,pframe, length); + pframe+=pxmitpriv->frag_len; + pframe=(u8*)RND4((SIZE_PTR)(pframe)); + + } + } + + AES_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra); + } +/* + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_encrypt: stainfo==NULL!!!\n")); + DBG_871X("%s, psta==NUL\n", __func__); + res=_FAIL; + } +*/ + } + + + +_func_exit_; + return res; +} + +static sint aes_decipher(u8 *key, uint hdrlen, + u8 *pframe, uint plen) +{ + static u8 message[MAX_MSG_SIZE]; + uint qc_exists, a4_exists, i, j, payload_remainder, + num_blocks, payload_index; + sint res = _SUCCESS; + u8 pn_vector[6]; + u8 mic_iv[16]; + u8 mic_header1[16]; + u8 mic_header2[16]; + u8 ctr_preload[16]; + + /* Intermediate Buffers */ + u8 chain_buffer[16]; + u8 aes_out[16]; + u8 padded_buffer[16]; + u8 mic[8]; + + +// uint offset = 0; + uint frtype = GetFrameType(pframe); + uint frsubtype = GetFrameSubType(pframe); +_func_enter_; + frsubtype=frsubtype>>4; + + + _rtw_memset((void *)mic_iv, 0, 16); + _rtw_memset((void *)mic_header1, 0, 16); + _rtw_memset((void *)mic_header2, 0, 16); + _rtw_memset((void *)ctr_preload, 0, 16); + _rtw_memset((void *)chain_buffer, 0, 16); + _rtw_memset((void *)aes_out, 0, 16); + _rtw_memset((void *)padded_buffer, 0, 16); + + //start to decrypt the payload + + num_blocks = (plen-8) / 16; //(plen including LLC, payload_length and mic ) + + payload_remainder = (plen-8) % 16; + + pn_vector[0] = pframe[hdrlen]; + pn_vector[1] = pframe[hdrlen+1]; + pn_vector[2] = pframe[hdrlen+4]; + pn_vector[3] = pframe[hdrlen+5]; + pn_vector[4] = pframe[hdrlen+6]; + pn_vector[5] = pframe[hdrlen+7]; + + if ((hdrlen == WLAN_HDR_A3_LEN )||(hdrlen == WLAN_HDR_A3_QOS_LEN)) + a4_exists = 0; + else + a4_exists = 1; + + if ( + ((frtype|frsubtype) == WIFI_DATA_CFACK) || + ((frtype|frsubtype) == WIFI_DATA_CFPOLL)|| + ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) + { + qc_exists = 1; + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + }//only for data packet . add for CONFIG_IEEE80211W, none 11w also can use + else if ((frtype == WIFI_DATA) && + ((frsubtype == 0x08) || + (frsubtype == 0x09)|| + (frsubtype == 0x0a)|| + (frsubtype == 0x0b))) + { + if(hdrlen != WLAN_HDR_A3_QOS_LEN){ + + hdrlen += 2; + } + qc_exists = 1; + } + else + qc_exists = 0; + + + // now, decrypt pframe with hdrlen offset and plen long + + payload_index = hdrlen + 8; // 8 is for extiv + + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, + pn_vector, + i+1, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); + + for (j=0; j<16;j++) pframe[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + pframe, + pn_vector, + num_blocks+1, + frtype // add for CONFIG_IEEE80211W, none 11w also can use + ); + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = pframe[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; j 0) + { + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = message[payload_index++]; + } + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(key, chain_buffer, aes_out); + + } + + for (j = 0 ; j < 8; j++) mic[j] = aes_out[j]; + + /* Insert MIC into payload */ + for (j = 0; j < 8; j++) + message[payload_index+j] = mic[j]; + + payload_index = hdrlen + 8; + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + message, + pn_vector, + i+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, &message[payload_index], chain_buffer); + for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j]; + } + + if (payload_remainder > 0) /* If there is a short final block, then pad it,*/ + { /* encrypt it and copy the unpadded part back */ + construct_ctr_preload( + ctr_preload, + a4_exists, + qc_exists, + message, + pn_vector, + num_blocks+1, + frtype); // add for CONFIG_IEEE80211W, none 11w also can use + + for (j = 0; j < 16; j++) padded_buffer[j] = 0x00; + for (j = 0; j < payload_remainder; j++) + { + padded_buffer[j] = message[payload_index+j]; + } + aes128k128d(key, ctr_preload, aes_out); + bitwise_xor(aes_out, padded_buffer, chain_buffer); + for (j=0; ju.hdr.attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; +// struct recv_priv *precvpriv=&padapter->recvpriv; + u32 res=_SUCCESS; +_func_enter_; + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + //4 start to encrypt each fragment + if((prxattrib->encrypt==_AES_)){ + + stainfo=rtw_get_stainfo(&padapter->stapriv ,&prxattrib->ta[0] ); + if (stainfo!=NULL){ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_decrypt: stainfo!=NULL!!!\n")); + + if(IS_MCAST(prxattrib->ra)) + { + static u32 start = 0; + static u32 no_gkey_bc_cnt = 0; + static u32 no_gkey_mc_cnt = 0; + + //DBG_871X("rx bc/mc packets, to perform sw rtw_aes_decrypt\n"); + //prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey; + if(psecuritypriv->binstallGrpkey==_FALSE) + { + res=_FAIL; + + if (start == 0) + start = rtw_get_current_time(); + + if (is_broadcast_mac_addr(prxattrib->ra)) + no_gkey_bc_cnt++; + else + no_gkey_mc_cnt++; + + if (rtw_get_passing_time_ms(start) > 1000) { + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = rtw_get_current_time(); + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + } + + goto exit; + } + + if (no_gkey_bc_cnt || no_gkey_mc_cnt) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n", + FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt); + } + start = 0; + no_gkey_bc_cnt = 0; + no_gkey_mc_cnt = 0; + + prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; + if(psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) + { + DBG_871X("not match packet_index=%d, install_index=%d \n" + , prxattrib->key_index, psecuritypriv->dot118021XGrpKeyid); + res=_FAIL; + goto exit; + } + } + else + { + prwskey=&stainfo->dot118021x_UncstKey.skey[0]; + } + + length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len; + /*// add for CONFIG_IEEE80211W, debug + if(0) + printk("@@@@@@@@@@@@@@@@@@ length=%d, prxattrib->hdrlen=%d, prxattrib->pkt_len=%d \n" + , length, prxattrib->hdrlen, prxattrib->pkt_len); + if(0) + { + int no; + //test print PSK + printk("PSK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", prwskey[no]); + printk("\n"); + } + if(0) + { + int no; + //test print PSK + printk("frame:\n"); + for(no=0;nopkt_len;no++) + printk(" %02x ", pframe[no]); + printk("\n"); + }*/ + + res= aes_decipher(prwskey,prxattrib->hdrlen,pframe, length); + + AES_SW_DEC_CNT_INC(psecuritypriv, prxattrib->ra); + } + else{ + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("rtw_aes_decrypt: stainfo==NULL!!!\n")); + res=_FAIL; + } + + } +_func_exit_; +exit: + return res; +} + +#ifdef CONFIG_IEEE80211W +u32 rtw_BIP_verify(_adapter *padapter, u8 *precvframe) +{ + struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib; + u8 *pframe; + u8 *BIP_AAD, *p; + u32 res=_FAIL; + uint len, ori_len; + struct rtw_ieee80211_hdr *pwlanhdr; + u8 mic[16]; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE; + BIP_AAD = rtw_zmalloc(ori_len); + + if(BIP_AAD == NULL) + { + DBG_871X("BIP AAD allocate fail\n"); + return _FAIL; + } + //PKT start + pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + //mapping to wlan header + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //save the frame body + MME + _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN); + //find MME IE pointer + p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN); + //Baron + if(p) + { + u16 keyid=0; + u64 temp_ipn=0; + //save packet number + _rtw_memcpy(&temp_ipn, p+4, 6); + temp_ipn = le64_to_cpu(temp_ipn); + //BIP packet number should bigger than previous BIP packet + if (temp_ipn < pmlmeext->mgnt_80211w_IPN_rx) { + DBG_871X("replay BIP packet\n"); + goto BIP_exit; + } + //copy key index + _rtw_memcpy(&keyid, p+2, 2); + keyid = le16_to_cpu(keyid); + if(keyid != padapter->securitypriv.dot11wBIPKeyid) + { + DBG_871X("BIP key index error!\n"); + goto BIP_exit; + } + //clear the MIC field of MME to zero + _rtw_memset(p+2+len-8, 0, 8); + + //conscruct AAD, copy frame control field + _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); + ClearRetry(BIP_AAD); + ClearPwrMgt(BIP_AAD); + ClearMData(BIP_AAD); + //conscruct AAD, copy address 1 to address 3 + _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + + if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey + , BIP_AAD, ori_len, mic)) + goto BIP_exit; + + /*//management packet content + { + int pp; + DBG_871X("pkt: "); + for(pp=0;pp< pattrib->pkt_len; pp++) + printk(" %02x ", pframe[pp]); + DBG_871X("\n"); + //BIP AAD + management frame body + MME(MIC is zero) + DBG_871X("AAD+PKT: "); + for(pp=0;pp< ori_len; pp++) + DBG_871X(" %02x ", BIP_AAD[pp]); + DBG_871X("\n"); + //show the MIC result + DBG_871X("mic: "); + for(pp=0;pp<16; pp++) + DBG_871X(" %02x ", mic[pp]); + DBG_871X("\n"); + } + */ + //MIC field should be last 8 bytes of packet (packet without FCS) + if(_rtw_memcmp(mic, pframe+pattrib->pkt_len-8, 8)) + { + pmlmeext->mgnt_80211w_IPN_rx = temp_ipn; + res=_SUCCESS; + } + else + DBG_871X("BIP MIC error!\n"); + + } + else + res = RTW_RX_HANDLED; +BIP_exit: + + rtw_mfree(BIP_AAD, ori_len); + return res; +} +#endif //CONFIG_IEEE80211W + +#ifndef PLATFORM_FREEBSD +/* compress 512-bits */ +static int sha256_compress(struct sha256_state *md, unsigned char *buf) +{ + u32 S[8], W[64], t0, t1; + u32 t; + int i; + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; ++i) { + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + + /* feedback */ + for (i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} + +/* Initialize the hash state */ +static void sha256_init(struct sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +static int sha256_process(struct sha256_state *md, unsigned char *in, + unsigned long inlen) +{ + unsigned long n; +#define block_size 64 + + if (md->curlen > sizeof(md->buf)) + return -1; + + while (inlen > 0) { + if (md->curlen == 0 && inlen >= block_size) { + if (sha256_compress(md, (unsigned char *) in) < 0) + return -1; + md->length += block_size * 8; + in += block_size; + inlen -= block_size; + } else { + n = MIN(inlen, (block_size - md->curlen)); + _rtw_memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if (md->curlen == block_size) { + if (sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * block_size; + md->curlen = 0; + } + } + } + + return 0; +} + + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +static int sha256_done(struct sha256_state *md, unsigned char *out) +{ + int i; + + if (md->curlen >= sizeof(md->buf)) + return -1; + + /* increase the length of the message */ + md->length += md->curlen * 8; + + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char) 0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->curlen > 56) { + while (md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char) 0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char) 0; + } + + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + + /* copy output */ + for (i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + + return 0; +} + +/** + * sha256_vector - SHA256 hash for data vector + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 of failure + */ +static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) +{ + struct sha256_state ctx; + size_t i; + + sha256_init(&ctx); + for (i = 0; i < num_elem; i++) + if (sha256_process(&ctx, addr[i], len[i])) + return -1; + if (sha256_done(&ctx, mac)) + return -1; + return 0; +} + +static u8 os_strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + +static int os_memcmp(void *s1, void *s2, u8 n) +{ + unsigned char *p1 = s1, *p2 = s2; + + if (n == 0) + return 0; + + while (*p1 == *p2) { + p1++; + p2++; + n--; + if (n == 0) + return 0; + } + + return *p1 - *p2; +} + +/** + * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (32 bytes) + */ +static void hmac_sha256_vector(u8 *key, size_t key_len, size_t num_elem, + u8 *addr[], size_t *len, u8 *mac) +{ + unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ + unsigned char tk[32]; + u8 *_addr[6]; + size_t _len[6], i; + + if (num_elem > 5) { + /* + * Fixed limit on the number of fragments to avoid having to + * allocate memory (which could fail). + */ + return; + } + + /* if key is longer than 64 bytes reset it to key = SHA256(key) */ + if (key_len > 64) { + sha256_vector(1, &key, &key_len, tk); + key = tk; + key_len = 32; + } + + /* the HMAC_SHA256 transform looks like: + * + * SHA256(K XOR opad, SHA256(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected */ + + /* start out by storing key in ipad */ + _rtw_memset(k_pad, 0, sizeof(k_pad)); + _rtw_memcpy(k_pad, key, key_len); + /* XOR key with ipad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x36; + + /* perform inner SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + for (i = 0; i < num_elem; i++) { + _addr[i + 1] = addr[i]; + _len[i + 1] = len[i]; + } + sha256_vector(1 + num_elem, _addr, _len, mac); + + _rtw_memset(k_pad, 0, sizeof(k_pad)); + _rtw_memcpy(k_pad, key, key_len); + /* XOR key with opad values */ + for (i = 0; i < 64; i++) + k_pad[i] ^= 0x5c; + + /* perform outer SHA256 */ + _addr[0] = k_pad; + _len[0] = 64; + _addr[1] = mac; + _len[1] = 32; + sha256_vector(2, _addr, _len, mac); +} +#endif //PLATFORM_FREEBSD +/** + * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * + * This function is used to derive new, cryptographically separate keys from a + * given key. + */ +#ifndef PLATFORM_FREEBSD //Baron +static void sha256_prf(u8 *key, size_t key_len, char *label, + u8 *data, size_t data_len, u8 *buf, size_t buf_len) +{ + u16 counter = 1; + size_t pos, plen; + u8 hash[SHA256_MAC_LEN]; + u8 *addr[4]; + size_t len[4]; + u8 counter_le[2], length_le[2]; + + addr[0] = counter_le; + len[0] = 2; + addr[1] = (u8 *) label; + len[1] = os_strlen(label); + addr[2] = data; + len[2] = data_len; + addr[3] = length_le; + len[3] = sizeof(length_le); + + WPA_PUT_LE16(length_le, buf_len * 8); + pos = 0; + while (pos < buf_len) { + plen = buf_len - pos; + WPA_PUT_LE16(counter_le, counter); + if (plen >= SHA256_MAC_LEN) { + hmac_sha256_vector(key, key_len, 4, addr, len, + &buf[pos]); + pos += SHA256_MAC_LEN; + } else { + hmac_sha256_vector(key, key_len, 4, addr, len, hash); + _rtw_memcpy(&buf[pos], hash, plen); + break; + } + counter++; + } +} +#endif //PLATFORM_FREEBSD Baron + +/* AES tables*/ +const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +const u8 Td4s[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +const u8 rcons[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 + /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +#ifndef PLATFORM_FREEBSD //Baron +static void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]) +{ + int i; + u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + for (i = 0; i < 10; i++) { + temp = rk[3]; + rk[4] = rk[0] ^ + TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^ + RCON(i); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + rk += 4; + } +} + +static void rijndaelEncrypt(u32 rk[/*44*/], u8 pt[16], u8 ct[16]) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + int Nr = 10; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + +#define ROUND(i,d,s) \ +d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \ +d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \ +d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \ +d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3] + +#ifdef FULL_UNROLL + + ROUND(1,t,s); + ROUND(2,s,t); + ROUND(3,t,s); + ROUND(4,s,t); + ROUND(5,t,s); + ROUND(6,s,t); + ROUND(7,t,s); + ROUND(8,s,t); + ROUND(9,t,s); + + rk += Nr << 2; + +#else /* !FULL_UNROLL */ + + /* Nr - 1 full rounds: */ + r = Nr >> 1; + for (;;) { + ROUND(1,t,s); + rk += 8; + if (--r == 0) + break; + ROUND(0,s,t); + } + +#endif /* ?FULL_UNROLL */ + +#undef ROUND + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0]; + PUTU32(ct , s0); + s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3]; + PUTU32(ct + 12, s3); +} + +static void * aes_encrypt_init(u8 *key, size_t len) +{ + u32 *rk; + if (len != 16) + return NULL; + rk = (u32*)rtw_malloc(AES_PRIV_SIZE); + if (rk == NULL) + return NULL; + rijndaelKeySetupEnc(rk, key); + return rk; +} + +static void aes_128_encrypt(void *ctx, u8 *plain, u8 *crypt) +{ + rijndaelEncrypt(ctx, plain, crypt); +} + + +static void gf_mulx(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + +static void aes_encrypt_deinit(void *ctx) +{ + _rtw_memset(ctx, 0, AES_PRIV_SIZE); + rtw_mfree(ctx, AES_PRIV_SIZE); +} + + +/** + * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128 + * @key: 128-bit key for the hash operation + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ +static int omac1_aes_128_vector(u8 *key, size_t num_elem, + u8 *addr[], size_t *len, u8 *mac) +{ + void *ctx; + u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + u8 *pos, *end; + size_t i, e, left, total_len; + + ctx = aes_encrypt_init(key, 16); + if (ctx == NULL) + return -1; + _rtw_memset(cbc, 0, AES_BLOCK_SIZE); + + total_len = 0; + for (e = 0; e < num_elem; e++) + total_len += len[e]; + left = total_len; + + e = 0; + pos = addr[0]; + end = pos + len[0]; + + while (left >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + if (left > AES_BLOCK_SIZE) + aes_128_encrypt(ctx, cbc, cbc); + left -= AES_BLOCK_SIZE; + } + + _rtw_memset(pad, 0, AES_BLOCK_SIZE); + aes_128_encrypt(ctx, pad, pad); + gf_mulx(pad); + + if (left || total_len == 0) { + for (i = 0; i < left; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + cbc[left] ^= 0x80; + gf_mulx(pad); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + pad[i] ^= cbc[i]; + aes_128_encrypt(ctx, pad, mac); + aes_encrypt_deinit(ctx); + return 0; +} + + +/** + * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC) + * @key: 128-bit key for the hash operation + * @data: Data buffer for which a MAC is determined + * @data_len: Length of data buffer in bytes + * @mac: Buffer for MAC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + * + * This is a mode for using block cipher (AES in this case) for authentication. + * OMAC1 was standardized with the name CMAC by NIST in a Special Publication + * (SP) 800-38B. + */ //modify for CONFIG_IEEE80211W +int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac) +{ + return omac1_aes_128_vector(key, 1, &data, &data_len, mac); +} +#endif //PLATFORM_FREEBSD Baron + +#ifdef CONFIG_TDLS +void wpa_tdls_generate_tpk(_adapter *padapter, PVOID sta) +{ + struct sta_info *psta = (struct sta_info *)sta; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 *SNonce = psta->SNonce; + u8 *ANonce = psta->ANonce; + + u8 key_input[SHA256_MAC_LEN]; + u8 *nonce[2]; + size_t len[2]; + u8 data[3 * ETH_ALEN]; + + /* IEEE Std 802.11z-2010 8.5.9.1: + * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce)) + */ + len[0] = 32; + len[1] = 32; + if (os_memcmp(SNonce, ANonce, 32) < 0) { + nonce[0] = SNonce; + nonce[1] = ANonce; + } else { + nonce[0] = ANonce; + nonce[1] = SNonce; + } + + sha256_vector(2, nonce, len, key_input); + + /* + * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK", + * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY) + * TODO: is N_KEY really included in KDF Context and if so, in which + * presentation format (little endian 16-bit?) is it used? It gets + * added by the KDF anyway.. + */ + + if (os_memcmp(adapter_mac_addr(padapter), psta->hwaddr, ETH_ALEN) < 0) { + _rtw_memcpy(data, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, psta->hwaddr, ETH_ALEN); + } else { + _rtw_memcpy(data, psta->hwaddr, ETH_ALEN); + _rtw_memcpy(data + ETH_ALEN, adapter_mac_addr(padapter), ETH_ALEN); + } + _rtw_memcpy(data + 2 * ETH_ALEN, get_bssid(pmlmepriv), ETH_ALEN); + + sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data), (u8 *) &psta->tpk, sizeof(psta->tpk)); + + +} + +/** + * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC + * @kck: TPK-KCK + * @lnkid: Pointer to the beginning of Link Identifier IE + * @rsnie: Pointer to the beginning of RSN IE used for handshake + * @timeoutie: Pointer to the beginning of Timeout IE used for handshake + * @ftie: Pointer to the beginning of FT IE + * @mic: Pointer for writing MIC + * + * Calculate MIC for TDLS frame. + */ +int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie, + u8 *mic) +{ + u8 *buf, *pos; + struct wpa_tdls_ftie *_ftie; + struct wpa_tdls_lnkid *_lnkid; + int ret; + int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + 2 + rsnie[1] + + 2 + timeoutie[1] + 2 + ftie[1]; + buf = rtw_zmalloc(len); + if (!buf) { + DBG_871X("TDLS: No memory for MIC calculation\n"); + return -1; + } + + pos = buf; + _lnkid = (struct wpa_tdls_lnkid *) lnkid; + /* 1) TDLS initiator STA MAC address */ + _rtw_memcpy(pos, _lnkid->init_sta, ETH_ALEN); + pos += ETH_ALEN; + /* 2) TDLS responder STA MAC address */ + _rtw_memcpy(pos, _lnkid->resp_sta, ETH_ALEN); + pos += ETH_ALEN; + /* 3) Transaction Sequence number */ + *pos++ = trans_seq; + /* 4) Link Identifier IE */ + _rtw_memcpy(pos, lnkid, 2 + lnkid[1]); + pos += 2 + lnkid[1]; + /* 5) RSN IE */ + _rtw_memcpy(pos, rsnie, 2 + rsnie[1]); + pos += 2 + rsnie[1]; + /* 6) Timeout Interval IE */ + _rtw_memcpy(pos, timeoutie, 2 + timeoutie[1]); + pos += 2 + timeoutie[1]; + /* 7) FTIE, with the MIC field of the FTIE set to 0 */ + _rtw_memcpy(pos, ftie, 2 + ftie[1]); + _ftie = (struct wpa_tdls_ftie *) pos; + _rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN); + pos += 2 + ftie[1]; + + ret = omac1_aes_128(kck, buf, pos - buf, mic); + rtw_mfree(buf, len); + return ret; + +} + +/** + * wpa_tdls_teardown_ftie_mic - Calculate TDLS TEARDOWN FTIE MIC + * @kck: TPK-KCK + * @lnkid: Pointer to the beginning of Link Identifier IE + * @reason: Reason code of TDLS Teardown + * @dialog_token: Dialog token that was used in the MIC calculation for TPK Handshake Message 3 + * @trans_seq: Transaction Sequence number (1 octet) which shall be set to the value 4 + * @ftie: Pointer to the beginning of FT IE + * @mic: Pointer for writing MIC + * + * Calculate MIC for TDLS TEARDOWN frame according to Section 10.22.5 in IEEE 802.11 - 2012. + */ +int wpa_tdls_teardown_ftie_mic(u8 *kck, u8 *lnkid, u16 reason, + u8 dialog_token, u8 trans_seq, u8 *ftie, u8 *mic) +{ + u8 *buf, *pos; + struct wpa_tdls_ftie *_ftie; + int ret; + int len = 2 + lnkid[1] + 2 + 1 + 1 + 2 + ftie[1]; + + buf = rtw_zmalloc(len); + if (!buf) { + DBG_871X("TDLS: No memory for MIC calculation\n"); + return -1; + } + + pos = buf; + /* 1) Link Identifier IE */ + _rtw_memcpy(pos, lnkid, 2 + lnkid[1]); + pos += 2 + lnkid[1]; + /* 2) Reason Code */ + _rtw_memcpy(pos, (u8 *)&reason, 2); + pos += 2; + /* 3) Dialog Token */ + *pos++ = dialog_token; + /* 4) Transaction Sequence number */ + *pos++ = trans_seq; + /* 5) FTIE, with the MIC field of the FTIE set to 0 */ + _rtw_memcpy(pos, ftie, 2 + ftie[1]); + _ftie = (struct wpa_tdls_ftie *) pos; + _rtw_memset(_ftie->mic, 0, TDLS_MIC_LEN); + pos += 2 + ftie[1]; + + ret = omac1_aes_128(kck, buf, pos - buf, mic); + rtw_mfree(buf, len); + return ret; + +} + +int tdls_verify_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie) +{ + u8 *buf, *pos; + int len; + u8 mic[16]; + int ret; + u8 *rx_ftie, *tmp_ftie; + + if (lnkid == NULL || rsnie == NULL || + timeoutie == NULL || ftie == NULL){ + return _FAIL; + } + + len = 2 * ETH_ALEN + 1 + 2 + 18 + 2 + *(rsnie+1) + 2 + *(timeoutie+1) + 2 + *(ftie+1); + + buf = rtw_zmalloc(len); + if (buf == NULL) + return _FAIL; + + pos = buf; + /* 1) TDLS initiator STA MAC address */ + _rtw_memcpy(pos, lnkid + ETH_ALEN + 2, ETH_ALEN); + pos += ETH_ALEN; + /* 2) TDLS responder STA MAC address */ + _rtw_memcpy(pos, lnkid + 2 * ETH_ALEN + 2, ETH_ALEN); + pos += ETH_ALEN; + /* 3) Transaction Sequence number */ + *pos++ = trans_seq; + /* 4) Link Identifier IE */ + _rtw_memcpy(pos, lnkid, 2 + 18); + pos += 2 + 18; + /* 5) RSN IE */ + _rtw_memcpy(pos, rsnie, 2 + *(rsnie+1)); + pos += 2 + *(rsnie+1); + /* 6) Timeout Interval IE */ + _rtw_memcpy(pos, timeoutie, 2 + *(timeoutie+1)); + pos += 2 + *(timeoutie+1); + /* 7) FTIE, with the MIC field of the FTIE set to 0 */ + _rtw_memcpy(pos, ftie, 2 + *(ftie+1)); + pos += 2; + tmp_ftie = (u8 *) (pos+2); + _rtw_memset(tmp_ftie, 0, 16); + pos += *(ftie+1); + + ret = omac1_aes_128(kck, buf, pos - buf, mic); + rtw_mfree(buf, len); + if (ret) + return _FAIL; + rx_ftie = ftie+4; + + if (os_memcmp(mic, rx_ftie, 16) == 0) { + //Valid MIC + return _SUCCESS; + } + + //Invalid MIC + DBG_871X( "[%s] Invalid MIC\n", __FUNCTION__); + return _FAIL; + +} +#endif //CONFIG_TDLS + +void rtw_use_tkipkey_handler(RTW_TIMER_HDL_ARGS) +{ + _adapter *padapter = (_adapter *)FunctionContext; + +_func_enter_; + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler ^^^\n")); + +/* + if (RTW_CANNOT_RUN(padapter)) { + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler (padapter->bDriverStopped %s)(padapter->bSurpriseRemoved %s)^^^\n" + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + + return; + } + */ + + padapter->securitypriv.busetkipkey=_TRUE; + + RT_TRACE(_module_rtl871x_security_c_,_drv_err_,("^^^rtw_use_tkipkey_handler padapter->securitypriv.busetkipkey=%d^^^\n",padapter->securitypriv.busetkipkey)); + +_func_exit_; + +} + +/* Restore HW wep key setting according to key_mask */ +void rtw_sec_restore_wep_key(_adapter *adapter) +{ + struct security_priv* securitypriv=&(adapter->securitypriv); + sint keyid; + + if((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) { + for(keyid=0;keyid<4;keyid++){ + if(securitypriv->key_mask & BIT(keyid)){ + if(keyid == securitypriv->dot11PrivacyKeyIndex) + rtw_set_key(adapter,securitypriv, keyid, 1, _FALSE); + else + rtw_set_key(adapter,securitypriv, keyid, 0, _FALSE); + } + } + } +} + +u8 rtw_handle_tkip_countermeasure(_adapter* adapter, const char *caller) +{ + struct security_priv* securitypriv=&(adapter->securitypriv); + u8 status = _SUCCESS; + + if (securitypriv->btkip_countermeasure == _TRUE) { + u32 passing_ms = rtw_get_passing_time_ms(securitypriv->btkip_countermeasure_time); + if (passing_ms > 60*1000) { + DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%ds > 60s \n", + caller, ADPT_ARG(adapter), passing_ms/1000); + securitypriv->btkip_countermeasure = _FALSE; + securitypriv->btkip_countermeasure_time = 0; + } else { + DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%ds < 60s \n", + caller, ADPT_ARG(adapter), passing_ms/1000); + status = _FAIL; + } + } + + return status; +} + +#ifdef CONFIG_WOWLAN +u16 rtw_cal_crc16(u8 data, u16 crc) +{ + u8 shift_in, data_bit; + u8 crc_bit4, crc_bit11, crc_bit15; + u16 crc_result; + int index; + + for (index = 0; index < 8; index++) { + crc_bit15 = ((crc & BIT15) ? 1 : 0); + data_bit = (data & (BIT0 << index) ? 1 : 0); + shift_in = crc_bit15 ^ data_bit; + /*printf("crc_bit15=%d, DataBit=%d, shift_in=%d\n", + * crc_bit15, data_bit, shift_in);*/ + + crc_result = crc << 1; + + if (shift_in == 0) + crc_result &= (~BIT0); + else + crc_result |= BIT0; + /*printf("CRC =%x\n",CRC_Result);*/ + + crc_bit11 = ((crc & BIT11) ? 1 : 0) ^ shift_in; + + if (crc_bit11 == 0) + crc_result &= (~BIT12); + else + crc_result |= BIT12; + + /*printf("bit12 CRC =%x\n",CRC_Result);*/ + + crc_bit4 = ((crc & BIT4) ? 1 : 0) ^ shift_in; + + if (crc_bit4 == 0) + crc_result &= (~BIT5); + else + crc_result |= BIT5; + + /* printf("bit5 CRC =%x\n",CRC_Result); */ + /* repeat using the last result*/ + crc = crc_result; + } + return crc; +} + +/* + * function name :rtw_calc_crc + * + * input: char* pattern , pattern size + * + */ +u16 rtw_calc_crc(u8 *pdata, int length) +{ + u16 crc = 0xffff; + int i; + + for (i = 0; i < length; i++) + crc = rtw_cal_crc16(pdata[i], crc); + /* get 1' complement */ + crc = ~crc; + + return crc; +} +#endif /*CONFIG_WOWLAN*/ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sreset.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sreset.c new file mode 100644 index 00000000..e5d5661d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sreset.c @@ -0,0 +1,369 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + +void sreset_init_value(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + _rtw_mutex_init(&psrtpriv->silentreset_mutex); + psrtpriv->silent_reset_inprogress = _FALSE; + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + psrtpriv->last_tx_time =0; + psrtpriv->last_tx_complete_time =0; +#endif +} +void sreset_reset_value(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + psrtpriv->last_tx_time =0; + psrtpriv->last_tx_complete_time =0; +#endif +} + +u8 sreset_get_wifi_status(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + u8 status = WIFI_STATUS_SUCCESS; + u32 val32 = 0; + _irqL irqL; + if(psrtpriv->silent_reset_inprogress == _TRUE) + { + return status; + } + val32 =rtw_read32(padapter,REG_TXDMA_STATUS); + if(val32==0xeaeaeaea){ + psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST; + } + else if(val32!=0){ + DBG_8192C("txdmastatu(%x)\n",val32); + psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR; + } + + if(WIFI_STATUS_SUCCESS !=psrtpriv->Wifi_Error_Status) + { + DBG_8192C("==>%s error_status(0x%x) \n",__FUNCTION__,psrtpriv->Wifi_Error_Status); + status = (psrtpriv->Wifi_Error_Status &( ~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL))); + } + DBG_8192C("==> %s wifi_status(0x%x)\n",__FUNCTION__,status); + + //status restore + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + + return status; +#else + return WIFI_STATUS_SUCCESS; +#endif +} + +void sreset_set_wifi_error_status(_adapter *padapter, u32 status) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.Wifi_Error_Status = status; +#endif +} + +void sreset_set_trigger_point(_adapter *padapter, s32 tgp) +{ +#if defined(DBG_CONFIG_ERROR_DETECT) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->srestpriv.dbg_trigger_point = tgp; +#endif +} + +bool sreset_inprogress(_adapter *padapter) +{ +#if defined(DBG_CONFIG_ERROR_RESET) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + return pHalData->srestpriv.silent_reset_inprogress; +#else + return _FALSE; +#endif +} + +void sreset_restore_security_station(_adapter *padapter) +{ + u8 EntryId = 0; + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_info *psta; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info; + + { + u8 val8; + + if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) { + val8 = 0xcc; + #ifdef CONFIG_WAPI_SUPPORT + } else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) { + //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. + val8 = 0x4c; + #endif + } else { + val8 = 0xcf; + } + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); + } + + #if 0 + if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) || + ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ )) + { + + for(EntryId=0; EntryId<4; EntryId++) + { + if(EntryId == psecuritypriv->dot11PrivacyKeyIndex) + rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1,_FALSE); + else + rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0,_FALSE); + } + + } + else + #endif + if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) || + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) + { + psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + } + else + { + //pairwise key + rtw_setstakey_cmd(padapter, psta, UNICAST_KEY,_FALSE); + //group key + rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0,_FALSE); + } + } +} + +void sreset_restore_network_station(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 doiqk = _FALSE; + + #if 0 + { + //======================================================= + // reset related register of Beacon control + + //set MSR to nolink + Set_MSR(padapter, _HW_STATE_NOLINK_); + // reject all data frame + rtw_write16(padapter, REG_RXFLTMAP2,0x00); + //reset TSF + rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1))); + + // disable update TSF + SetBcnCtrlReg(padapter, BIT(4), 0); + + //======================================================= + } + #endif + + rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_FALSE); + + { + u8 threshold; + #ifdef CONFIG_USB_HCI + // TH=1 => means that invalidate usb rx aggregation + // TH=0 => means that validate usb rx aggregation, use init value. + if(mlmepriv->htpriv.ht_option) { + if(padapter->registrypriv.wifi_spec==1) + threshold = 1; + else + threshold = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } else { + threshold = 1; + rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold)); + } + #endif + } + + doiqk = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK , &doiqk); + + set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + doiqk = _FALSE; + rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk); + //disable dynamic functions, such as high power, DIG + /*rtw_phydm_func_disable_all(padapter);*/ + + rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); + + { + u8 join_type = 0; + rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); + } + + Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + + mlmeext_joinbss_event_callback(padapter, 1); + //restore Sequence No. + rtw_hal_set_hwreg(padapter, HW_VAR_RESTORE_HW_SEQ, 0); + + sreset_restore_security_station(padapter); +} + + +void sreset_restore_network_status(_adapter *padapter) +{ + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + sreset_restore_network_station(padapter); + } else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + rtw_ap_restore_network(padapter); + } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + } else { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv)); + } +} + +void sreset_stop_adapter(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if (padapter == NULL) + return; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + rtw_netif_stop_queue(padapter->pnetdev); + + rtw_cancel_all_timer(padapter); + + /* TODO: OS and HCI independent */ + #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI) + tasklet_kill(&pxmitpriv->xmit_tasklet); + #endif + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + rtw_scan_abort(padapter); + + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) + { + rtw_set_to_roam(padapter, 0); + _rtw_join_timeout_handler(padapter); + } + +} + +void sreset_start_adapter(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if (padapter == NULL) + return; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + if (check_fwstate(pmlmepriv, _FW_LINKED)) { + sreset_restore_network_status(padapter); + } + + /* TODO: OS and HCI independent */ + #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI) + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); + #endif + + if (is_primary_adapter(padapter)) + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + + rtw_netif_wake_queue(padapter->pnetdev); +} + +void sreset_reset(_adapter *padapter) +{ +#ifdef DBG_CONFIG_ERROR_RESET + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + u32 start = rtw_get_current_time(); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + DBG_871X("%s\n", __FUNCTION__); + + psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; + + +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "SRESET"); +#endif//#ifdef CONFIG_LPS + + _enter_pwrlock(&pwrpriv->lock); + + psrtpriv->silent_reset_inprogress = _TRUE; + pwrpriv->change_rfpwrstate = rf_off; + + sreset_stop_adapter(padapter); + #ifdef CONFIG_CONCURRENT_MODE + sreset_stop_adapter(padapter->pbuddy_adapter); + #endif + + #ifdef CONFIG_IPS + _ips_enter(padapter); + _ips_leave(padapter); + #endif + + sreset_start_adapter(padapter); + #ifdef CONFIG_CONCURRENT_MODE + sreset_start_adapter(padapter->pbuddy_adapter); + #endif + + psrtpriv->silent_reset_inprogress = _FALSE; + + _exit_pwrlock(&pwrpriv->lock); + + DBG_871X("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start)); + pdbgpriv->dbg_sreset_cnt++; +#endif +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sta_mgt.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sta_mgt.c new file mode 100644 index 00000000..b24e7874 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_sta_mgt.c @@ -0,0 +1,1021 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_STA_MGT_C_ + +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + + +bool test_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + if (ntohs(*((u16 *)local_port)) == 5001 || ntohs(*((u16 *)remote_port)) == 5001) + return _TRUE; + return _FALSE; +} + +struct st_register test_st_reg = { + .s_proto = 0x06, + .rule = test_st_match_rule, +}; + +inline void rtw_st_ctl_init(struct st_ctl_t *st_ctl) +{ + _rtw_memset(st_ctl->reg, 0 , sizeof(struct st_register) * SESSION_TRACKER_REG_ID_NUM); + _rtw_init_queue(&st_ctl->tracker_q); +} + +inline void rtw_st_ctl_clear_tracker_q(struct st_ctl_t *st_ctl) +{ + _irqL irqL; + _list *plist, *phead; + struct session_tracker *st; + + _enter_critical_bh(&st_ctl->tracker_q.lock, &irqL); + phead = &st_ctl->tracker_q.queue; + plist = get_next(phead); + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + st = LIST_CONTAINOR(plist, struct session_tracker, list); + plist = get_next(plist); + rtw_list_delete(&st->list); + rtw_mfree((u8 *)st, sizeof(struct session_tracker)); + } + _exit_critical_bh(&st_ctl->tracker_q.lock, &irqL); +} + +inline void rtw_st_ctl_deinit(struct st_ctl_t *st_ctl) +{ + rtw_st_ctl_clear_tracker_q(st_ctl); + _rtw_deinit_queue(&st_ctl->tracker_q); +} + +inline void rtw_st_ctl_register(struct st_ctl_t *st_ctl, u8 st_reg_id, struct st_register *reg) +{ + if (st_reg_id >= SESSION_TRACKER_REG_ID_NUM) { + rtw_warn_on(1); + return; + } + + st_ctl->reg[st_reg_id].s_proto = reg->s_proto; + st_ctl->reg[st_reg_id].rule = reg->rule; +} + +inline void rtw_st_ctl_unregister(struct st_ctl_t *st_ctl, u8 st_reg_id) +{ + int i; + + if (st_reg_id >= SESSION_TRACKER_REG_ID_NUM) { + rtw_warn_on(1); + return; + } + + st_ctl->reg[st_reg_id].s_proto = 0; + st_ctl->reg[st_reg_id].rule = NULL; + + /* clear tracker queue if no session trecker registered */ + for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) + if (st_ctl->reg[i].s_proto != 0) + break; + if (i >= SESSION_TRACKER_REG_ID_NUM) + rtw_st_ctl_clear_tracker_q(st_ctl); +} + +inline bool rtw_st_ctl_chk_reg_s_proto(struct st_ctl_t *st_ctl, u8 s_proto) +{ + bool ret = _FALSE; + int i; + + for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) { + if (st_ctl->reg[i].s_proto == s_proto) { + ret = _TRUE; + break; + } + } + + return ret; +} + +inline bool rtw_st_ctl_chk_reg_rule(struct st_ctl_t *st_ctl, _adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port) +{ + bool ret = _FALSE; + int i; + st_match_rule rule; + + for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) { + rule = st_ctl->reg[i].rule; + if (rule && rule(adapter, local_naddr, local_port, remote_naddr, remote_port) == _TRUE) { + ret = _TRUE; + break; + } + } + + return ret; +} + +#define SESSION_TRACKER_FMT IP_FMT":"PORT_FMT" "IP_FMT":"PORT_FMT" %u %d" +#define SESSION_TRACKER_ARG(st) IP_ARG(&(st)->local_naddr), PORT_ARG(&(st)->local_port), IP_ARG(&(st)->remote_naddr), PORT_ARG(&(st)->remote_port), (st)->status, rtw_get_passing_time_ms((st)->set_time) + +void dump_st_ctl(void *sel, struct st_ctl_t *st_ctl) +{ + int i; + _irqL irqL; + _list *plist, *phead; + struct session_tracker *st; + + if (!DBG_SESSION_TRACKER) + return; + + for (i = 0; i < SESSION_TRACKER_REG_ID_NUM; i++) + DBG_871X_SEL_NL(sel, "reg%d: %u %p\n", i, st_ctl->reg[i].s_proto, st_ctl->reg[i].rule); + + _enter_critical_bh(&st_ctl->tracker_q.lock, &irqL); + phead = &st_ctl->tracker_q.queue; + plist = get_next(phead); + while (rtw_end_of_queue_search(phead, plist) == _FALSE) { + st = LIST_CONTAINOR(plist, struct session_tracker, list); + plist = get_next(plist); + + DBG_871X_SEL_NL(sel, SESSION_TRACKER_FMT"\n", SESSION_TRACKER_ARG(st)); + } + _exit_critical_bh(&st_ctl->tracker_q.lock, &irqL); + +} + +void _rtw_init_stainfo(struct sta_info *psta); +void _rtw_init_stainfo(struct sta_info *psta) +{ + +_func_enter_; + + _rtw_memset((u8 *)psta, 0, sizeof (struct sta_info)); + + _rtw_spinlock_init(&psta->lock); + _rtw_init_listhead(&psta->list); + _rtw_init_listhead(&psta->hash_list); + //_rtw_init_listhead(&psta->asoc_list); + //_rtw_init_listhead(&psta->sleep_list); + //_rtw_init_listhead(&psta->wakeup_list); + + _rtw_init_queue(&psta->sleep_q); + psta->sleepq_len = 0; + + _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); + _rtw_init_sta_recv_priv(&psta->sta_recvpriv); + +#ifdef CONFIG_AP_MODE + + _rtw_init_listhead(&psta->asoc_list); + + _rtw_init_listhead(&psta->auth_list); + + psta->expire_to = 0; + + psta->flags = 0; + + psta->capability = 0; + + psta->bpairwise_key_installed = _FALSE; + + +#ifdef CONFIG_NATIVEAP_MLME + psta->nonerp_set = 0; + psta->no_short_slot_time_set = 0; + psta->no_short_preamble_set = 0; + psta->no_ht_gf_set = 0; + psta->no_ht_set = 0; + psta->ht_20mhz_set = 0; + psta->ht_40mhz_intolerant = 0; +#endif + +#ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; +#endif // CONFIG_TX_MCAST2UNI + + psta->keep_alive_trycnt = 0; + +#endif // CONFIG_AP_MODE + + rtw_st_ctl_init(&psta->st_ctl); + +_func_exit_; + +} + +u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) +{ + struct sta_info *psta; + s32 i; + +_func_enter_; + + pstapriv->pallocated_stainfo_buf = rtw_zvmalloc (sizeof(struct sta_info) * NUM_STA+ 4); + + if(!pstapriv->pallocated_stainfo_buf) + return _FAIL; + + pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - + ((SIZE_PTR)(pstapriv->pallocated_stainfo_buf ) & 3); + + _rtw_init_queue(&pstapriv->free_sta_queue); + + _rtw_spinlock_init(&pstapriv->sta_hash_lock); + + //_rtw_init_queue(&pstapriv->asoc_q); + pstapriv->asoc_sta_count = 0; + _rtw_init_queue(&pstapriv->sleep_q); + _rtw_init_queue(&pstapriv->wakeup_q); + + psta = (struct sta_info *)(pstapriv->pstainfo_buf); + + + for(i = 0; i < NUM_STA; i++) + { + _rtw_init_stainfo(psta); + + _rtw_init_listhead(&(pstapriv->sta_hash[i])); + + rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue)); + + psta++; + } + + pstapriv->adhoc_expire_to = 4; /* 4 * 2 = 8 sec */ + +#ifdef CONFIG_AP_MODE + + pstapriv->sta_dz_bitmap = 0; + pstapriv->tim_bitmap = 0; + + _rtw_init_listhead(&pstapriv->asoc_list); + _rtw_init_listhead(&pstapriv->auth_list); + _rtw_spinlock_init(&pstapriv->asoc_list_lock); + _rtw_spinlock_init(&pstapriv->auth_list_lock); + pstapriv->asoc_list_cnt = 0; + pstapriv->auth_list_cnt = 0; + + pstapriv->auth_to = 3; // 3*2 = 6 sec + pstapriv->assoc_to = 3; + //pstapriv->expire_to = 900;// 900*2 = 1800 sec = 30 min, expire after no any traffic. + //pstapriv->expire_to = 30;// 30*2 = 60 sec = 1 min, expire after no any traffic. +#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + pstapriv->expire_to = 3; // 3*2 = 6 sec +#else + pstapriv->expire_to = 60;// 60*2 = 120 sec = 2 min, expire after no any traffic. +#endif +#ifdef CONFIG_ATMEL_RC_PATCH + _rtw_memset( pstapriv->atmel_rc_pattern, 0, ETH_ALEN); +#endif + pstapriv->max_num_sta = NUM_STA; + +#endif + +_func_exit_; + + return _SUCCESS; + +} + +inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) +{ + int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info); + + if (!stainfo_offset_valid(offset)) + DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset); + + return offset; +} + +inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) +{ + if (!stainfo_offset_valid(offset)) + DBG_871X("%s invalid offset(%d), out of range!!!", __func__, offset); + + return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); +} + +void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv); +void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv) +{ +_func_enter_; + + _rtw_spinlock_free(&psta_xmitpriv->lock); + + _rtw_spinlock_free(&(psta_xmitpriv->be_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock)); + _rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock)); +_func_exit_; +} + +static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv) +{ +_func_enter_; + + _rtw_spinlock_free(&psta_recvpriv->lock); + + _rtw_spinlock_free(&(psta_recvpriv->defrag_q.lock)); + +_func_exit_; + +} + +void rtw_mfree_stainfo(struct sta_info *psta); +void rtw_mfree_stainfo(struct sta_info *psta) +{ +_func_enter_; + + if(&psta->lock != NULL) + _rtw_spinlock_free(&psta->lock); + + _rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv); + _rtw_free_sta_recv_priv_lock(&psta->sta_recvpriv); + +_func_exit_; +} + + +// this function is used to free the memory of lock || sema for all stainfos +void rtw_mfree_all_stainfo(struct sta_priv *pstapriv ); +void rtw_mfree_all_stainfo(struct sta_priv *pstapriv ) +{ + _irqL irqL; + _list *plist, *phead; + struct sta_info *psta = NULL; + +_func_enter_; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + phead = get_list_head(&pstapriv->free_sta_queue); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info ,list); + plist = get_next(plist); + + rtw_mfree_stainfo(psta); + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + +_func_exit_; + +} + +void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv); +void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv) +{ +#ifdef CONFIG_AP_MODE + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; +#endif + + rtw_mfree_all_stainfo(pstapriv); //be done before free sta_hash_lock + + _rtw_spinlock_free(&pstapriv->free_sta_queue.lock); + + _rtw_spinlock_free(&pstapriv->sta_hash_lock); + _rtw_spinlock_free(&pstapriv->wakeup_q.lock); + _rtw_spinlock_free(&pstapriv->sleep_q.lock); + +#ifdef CONFIG_AP_MODE + _rtw_spinlock_free(&pstapriv->asoc_list_lock); + _rtw_spinlock_free(&pstapriv->auth_list_lock); + _rtw_spinlock_free(&pacl_list->acl_node_q.lock); +#endif + +} + +u32 _rtw_free_sta_priv(struct sta_priv *pstapriv) +{ + _irqL irqL; + _list *phead, *plist; + struct sta_info *psta = NULL; + struct recv_reorder_ctrl *preorder_ctrl; + int index; + +_func_enter_; + if(pstapriv){ + + /* delete all reordering_ctrl_timer */ + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for(index = 0; index < NUM_STA; index++) + { + phead = &(pstapriv->sta_hash[index]); + plist = get_next(phead); + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + int i; + psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list); + plist = get_next(plist); + + for(i=0; i < 16 ; i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + /*===============================*/ + + rtw_mfree_sta_priv_lock(pstapriv); + + if(pstapriv->pallocated_stainfo_buf) { + rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4); + } + } + +_func_exit_; + return _SUCCESS; +} + + +//struct sta_info *rtw_alloc_stainfo(_queue *pfree_sta_queue, unsigned char *hwaddr) +struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) +{ + _irqL irqL, irqL2; + uint tmp_aid; + s32 index; + _list *phash_list; + struct sta_info *psta; + _queue *pfree_sta_queue; + struct recv_reorder_ctrl *preorder_ctrl; + int i = 0; + u16 wRxSeqInitialValue = 0xffff; + +_func_enter_; + + pfree_sta_queue = &pstapriv->free_sta_queue; + + //_enter_critical_bh(&(pfree_sta_queue->lock), &irqL); + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + if (_rtw_queue_empty(pfree_sta_queue) == _TRUE) + { + //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + psta = NULL; + } + else + { + psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list); + + rtw_list_delete(&(psta->list)); + + //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); + + tmp_aid = psta->aid; + + _rtw_init_stainfo(psta); + + psta->padapter = pstapriv->padapter; + + _rtw_memcpy(psta->hwaddr, hwaddr, ETH_ALEN); + + index = wifi_mac_hash(hwaddr); + + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("rtw_alloc_stainfo: index = %x", index)); + + if(index >= NUM_STA){ + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("ERROR=> rtw_alloc_stainfo: index >= NUM_STA")); + psta= NULL; + goto exit; + } + phash_list = &(pstapriv->sta_hash[index]); + + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + + rtw_list_insert_tail(&psta->hash_list, phash_list); + + pstapriv->asoc_sta_count ++ ; + + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + +// Commented by Albert 2009/08/13 +// For the SMC router, the sequence number of first packet of WPS handshake will be 0. +// In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. +// So, we initialize the tid_rxseq variable as the 0xffff. + + for( i = 0; i < 16; i++ ) + { + _rtw_memcpy( &psta->sta_recvpriv.rxcache.tid_rxseq[ i ], &wRxSeqInitialValue, 2 ); + } + + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc number_%d stainfo with hwaddr = %x %x %x %x %x %x \n", + pstapriv->asoc_sta_count , hwaddr[0], hwaddr[1], hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5])); + + init_addba_retry_timer(pstapriv->padapter, psta); +#ifdef CONFIG_IEEE80211W + init_dot11w_expire_timer(pstapriv->padapter, psta); +#endif /* CONFIG_IEEE80211W */ +#ifdef CONFIG_TDLS + rtw_init_tdls_timer(pstapriv->padapter, psta); +#endif //CONFIG_TDLS + + //for A-MPDU Rx reordering buffer control + for(i=0; i < 16 ; i++) + { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + + preorder_ctrl->padapter = pstapriv->padapter; + + preorder_ctrl->enable = _FALSE; + + preorder_ctrl->indicate_seq = 0xffff; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d\n", __FUNCTION__, __LINE__, + preorder_ctrl->indicate_seq); + #endif + preorder_ctrl->wend_b= 0xffff; + //preorder_ctrl->wsize_b = (NR_RECVBUFF-2); + preorder_ctrl->wsize_b = 64;//64; + preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; + + _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue); + + rtw_init_recv_timer(preorder_ctrl); + } + + + //init for DM + psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); + psta->rssi_stat.UndecoratedSmoothedCCK = (-1); +#ifdef CONFIG_ATMEL_RC_PATCH + psta->flag_atmel_rc = 0; +#endif + /* init for the sequence number of received management frame */ + psta->RxMgmtFrameSeqNum = 0xffff; + psta->ra_rpt_linked = _FALSE; + + //alloc mac id for non-bc/mc station, + rtw_alloc_macid(pstapriv->padapter, psta); + + } + +exit: + + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); + +_func_exit_; + + return psta; + + +} + + +// using pstapriv->sta_hash_lock to protect +u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta) +{ + int i; + _irqL irqL0; + _queue *pfree_sta_queue; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_xmit_priv *pstaxmitpriv; + 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; + _exit_critical_bh(&psta->lock, &irqL0); + + pfree_sta_queue = &pstapriv->free_sta_queue; + + + pstaxmitpriv = &psta->sta_xmitpriv; + + //rtw_list_delete(&psta->sleep_list); + + //rtw_list_delete(&psta->wakeup_list); + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); + psta->sleepq_len = 0; + + //vo + //_enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); + 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); + + //vi + //_enter_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); + 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); + + //be + //_enter_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->be_q.sta_pending); + 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); + + //bk + //_enter_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0); + rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); + 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); + + + // re-init sta_info; 20061114 // will be init in alloc_stainfo + //_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); + //_rtw_init_sta_recv_priv(&psta->sta_recvpriv); +#ifdef CONFIG_IEEE80211W + _cancel_timer_ex(&psta->dot11w_expire_timer); +#endif /* CONFIG_IEEE80211W */ + _cancel_timer_ex(&psta->addba_retry_timer); + +#ifdef CONFIG_TDLS + psta->tdls_sta_state = TDLS_STATE_NONE; + rtw_free_tdls_timer(psta); +#endif //CONFIG_TDLS + + //for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer + for(i=0; i < 16 ; i++) + { + _irqL irqL; + _list *phead, *plist; + union recv_frame *prframe; + _queue *ppending_recvframe_queue; + _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; + + preorder_ctrl = &psta->recvreorder_ctrl[i]; + + _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer); + + + ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; + + _enter_critical_bh(&ppending_recvframe_queue->lock, &irqL); + + phead = get_list_head(ppending_recvframe_queue); + plist = get_next(phead); + + while(!rtw_is_list_empty(phead)) + { + prframe = LIST_CONTAINOR(plist, union recv_frame, u); + + plist = get_next(plist); + + rtw_list_delete(&(prframe->u.hdr.list)); + + rtw_free_recvframe(prframe, pfree_recv_queue); + } + + _exit_critical_bh(&ppending_recvframe_queue->lock, &irqL); + + } + + if (!(psta->state & WIFI_AP_STATE)) + rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _FALSE); + + + //release mac id for non-bc/mc station, + rtw_release_macid(pstapriv->padapter, psta); + +#ifdef CONFIG_AP_MODE + +/* + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL0); + rtw_list_delete(&psta->asoc_list); + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL0); +*/ + _enter_critical_bh(&pstapriv->auth_list_lock, &irqL0); + if (!rtw_is_list_empty(&psta->auth_list)) { + rtw_list_delete(&psta->auth_list); + pstapriv->auth_list_cnt--; + } + _exit_critical_bh(&pstapriv->auth_list_lock, &irqL0); + + psta->expire_to = 0; +#ifdef CONFIG_ATMEL_RC_PATCH + psta->flag_atmel_rc = 0; +#endif + psta->sleepq_ac_len = 0; + psta->qos_info = 0; + + psta->max_sp_len = 0; + psta->uapsd_bk = 0; + psta->uapsd_be = 0; + psta->uapsd_vi = 0; + psta->uapsd_vo = 0; + + psta->has_legacy_ac = 0; + +#ifdef CONFIG_NATIVEAP_MLME + + pstapriv->sta_dz_bitmap &=~BIT(psta->aid); + pstapriv->tim_bitmap &=~BIT(psta->aid); + + //rtw_indicate_sta_disassoc_event(padapter, psta); + + if ((psta->aid >0)&&(pstapriv->sta_aid[psta->aid - 1] == psta)) + { + pstapriv->sta_aid[psta->aid - 1] = NULL; + psta->aid = 0; + } + +#endif // CONFIG_NATIVEAP_MLME + +#ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; +#endif // CONFIG_TX_MCAST2UNI + +#endif // CONFIG_AP_MODE + + rtw_st_ctl_deinit(&psta->st_ctl); + + _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: + +_func_exit_; + + return _SUCCESS; + +} + +// free all stainfo which in sta_hash[all] +void rtw_free_all_stainfo(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + s32 index; + 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_; + + if(pstapriv->asoc_sta_count==1) + goto exit; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for(index=0; index< NUM_STA; index++) + { + phead = &(pstapriv->sta_hash[index]); + 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(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: + +_func_exit_; + +} + +/* any station allocated can be searched by hash list */ +struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) +{ + + _irqL irqL; + + _list *plist, *phead; + + struct sta_info *psta = NULL; + + u32 index; + + u8 *addr; + + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + +_func_enter_; + + if(hwaddr==NULL) + return NULL; + + if(IS_MCAST(hwaddr)) + { + addr = bc_addr; + } + else + { + addr = hwaddr; + } + + index = wifi_mac_hash(addr); + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + phead = &(pstapriv->sta_hash[index]); + plist = get_next(phead); + + + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + + psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + + if ((_rtw_memcmp(psta->hwaddr, addr, ETH_ALEN))== _TRUE) + { // if found the matched address + break; + } + psta=NULL; + plist = get_next(plist); + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); +_func_exit_; + return psta; + +} + +u32 rtw_init_bcmc_stainfo(_adapter* padapter) +{ + + struct sta_info *psta; + struct tx_servq *ptxservq; + u32 res=_SUCCESS; + NDIS_802_11_MAC_ADDRESS bcast_addr= {0xff,0xff,0xff,0xff,0xff,0xff}; + + struct sta_priv *pstapriv = &padapter->stapriv; + //_queue *pstapending = &padapter->xmitpriv.bm_pending; + +_func_enter_; + + psta = rtw_alloc_stainfo(pstapriv, bcast_addr); + + if(psta==NULL){ + res=_FAIL; + RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("rtw_alloc_stainfo fail")); + goto exit; + } +#ifdef CONFIG_BEAMFORMING + psta->txbf_gid = 63; + psta->txbf_paid = 0; +#endif + ptxservq= &(psta->sta_xmitpriv.be_q); + +/* + _enter_critical(&pstapending->lock, &irqL0); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(pstapending)); + + _exit_critical(&pstapending->lock, &irqL0); +*/ + +exit: +_func_exit_; + return _SUCCESS; + +} + + +struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter) +{ + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +_func_enter_; + psta = rtw_get_stainfo(pstapriv, bc_addr); +_func_exit_; + return psta; + +} + +u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr) +{ + u8 res = _TRUE; +#ifdef CONFIG_AP_MODE + _irqL irqL; + _list *plist, *phead; + struct rtw_wlan_acl_node *paclnode; + u8 match = _FALSE; + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; + _queue *pacl_node_q =&pacl_list->acl_node_q; + + _enter_critical_bh(&(pacl_node_q->lock), &irqL); + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); + + if(_rtw_memcmp(paclnode->addr, mac_addr, ETH_ALEN)) + { + if(paclnode->valid == _TRUE) + { + match = _TRUE; + break; + } + } + } + _exit_critical_bh(&(pacl_node_q->lock), &irqL); + + + if(pacl_list->mode == 1)//accept unless in deny list + { + res = (match == _TRUE) ? _FALSE:_TRUE; + } + else if(pacl_list->mode == 2)//deny unless in accept list + { + res = (match == _TRUE) ? _TRUE:_FALSE; + } + else + { + res = _TRUE; + } + +#endif + + return res; + +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_tdls.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_tdls.c new file mode 100644 index 00000000..12bac1f3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_tdls.c @@ -0,0 +1,3155 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_TDLS_C_ + +#include + +#ifdef CONFIG_TDLS +#define ONE_SEC 1000 /* 1000 ms */ + +extern unsigned char MCS_rate_2R[16]; +extern unsigned char MCS_rate_1R[16]; +extern void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame); + +void rtw_reset_tdls_info(_adapter* padapter) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + ptdlsinfo->ap_prohibited = _FALSE; + + /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */ + if (padapter->registrypriv.wifi_spec == 1) + { + ptdlsinfo->ch_switch_prohibited = _FALSE; + } + else + { + ptdlsinfo->ch_switch_prohibited = _TRUE; + } + + ptdlsinfo->link_established = _FALSE; + ptdlsinfo->sta_cnt = 0; + ptdlsinfo->sta_maximum = _FALSE; + +#ifdef CONFIG_TDLS_CH_SW + ptdlsinfo->chsw_info.ch_sw_state = TDLS_STATE_NONE; + ATOMIC_SET(&ptdlsinfo->chsw_info.chsw_on, _FALSE); + ptdlsinfo->chsw_info.off_ch_num = 0; + ptdlsinfo->chsw_info.ch_offset = 0; + ptdlsinfo->chsw_info.cur_time = 0; + ptdlsinfo->chsw_info.delay_switch_back = _FALSE; + ptdlsinfo->chsw_info.dump_stack = _FALSE; +#endif + + ptdlsinfo->ch_sensing = 0; + ptdlsinfo->watchdog_count = 0; + ptdlsinfo->dev_discovered = _FALSE; + +#ifdef CONFIG_WFD + ptdlsinfo->wfd_info = &padapter->wfd_info; +#endif +} + +int rtw_init_tdls_info(_adapter* padapter) +{ + int res = _SUCCESS; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + rtw_reset_tdls_info(padapter); + + ptdlsinfo->tdls_enable = _TRUE; +#ifdef CONFIG_TDLS_DRIVER_SETUP + ptdlsinfo->driver_setup = _TRUE; +#else + ptdlsinfo->driver_setup = _FALSE; +#endif /* CONFIG_TDLS_DRIVER_SETUP */ + + _rtw_spinlock_init(&ptdlsinfo->cmd_lock); + _rtw_spinlock_init(&ptdlsinfo->hdl_lock); + + return res; + +} + +void rtw_free_tdls_info(struct tdls_info *ptdlsinfo) +{ + _rtw_spinlock_free(&ptdlsinfo->cmd_lock); + _rtw_spinlock_free(&ptdlsinfo->hdl_lock); + + _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) ); + +} + +int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len) +{ + u8 tdls_prohibited_bit = 0x40; /* bit(38); TDLS_prohibited */ + + if (pkt_len < 5) { + return _FALSE; + } + + pframe += 4; + if ((*pframe) & tdls_prohibited_bit) + return _TRUE; + + return _FALSE; +} + +int check_ap_tdls_ch_switching_prohibited(u8 *pframe, u8 pkt_len) +{ + u8 tdls_ch_swithcing_prohibited_bit = 0x80; /* bit(39); TDLS_channel_switching prohibited */ + + if (pkt_len < 5) { + return _FALSE; + } + + pframe += 4; + if ((*pframe) & tdls_ch_swithcing_prohibited_bit) + return _TRUE; + + return _FALSE; +} + +int _issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack) +{ + int ret = _FAIL; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl, *qc; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + + pattrib->hdrlen +=2; + pattrib->qos_en = _TRUE; + pattrib->eosp = 1; + pattrib->ack_policy = 0; + pattrib->mdata = 0; + pattrib->retry_ctrl = _FALSE; + + _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; + + if (power_mode) + SetPwrMgt(fctrl); + + qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); + + SetPriority(qc, 7); /* Set priority to VO */ + + SetEOSP(qc, pattrib->eosp); + + SetAckpolicy(qc, pattrib->ack_policy); + + _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos); + pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos); + + pattrib->last_txcmdsz = pattrib->pktlen; + + if (wait_ack) + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + return ret; + +} + +/* + *wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT + *wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX + *try_cnt means the maximal TX count to try + */ +int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) +{ + int ret; + int i = 0; + u32 start = rtw_get_current_time(); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + #if 0 + psta = rtw_get_stainfo(&padapter->stapriv, da); + if (psta) { + if (power_mode) + rtw_hal_macid_sleep(padapter, psta->mac_id); + else + rtw_hal_macid_wakeup(padapter, psta->mac_id); + } else { + DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n", + FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup"); + rtw_warn_on(1); + } + #endif + + do { + ret = _issue_nulldata_to_TDLS_peer_STA(padapter, da, power_mode, wait_ms>0 ? _TRUE : _FALSE); + + i++; + + if (RTW_CANNOT_RUN(padapter)) + break; + + if (i < try_cnt && wait_ms > 0 && ret == _FAIL) + rtw_msleep_os(wait_ms); + + } while ((i < try_cnt) && (ret==_FAIL || wait_ms==0)); + + if (ret != _FAIL) { + ret = _SUCCESS; + #ifndef DBG_XMIT_ACK + goto exit; + #endif + } + + if (try_cnt && wait_ms) { + if (da) + DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n", + FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter), + ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start)); + else + DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", + FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), + ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start)); + } +exit: + return ret; +} + +void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_priv *pstapriv = &padapter->stapriv; + _irqL irqL; + + /* free peer sta_info */ + _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + if (ptdlsinfo->sta_cnt != 0) + ptdlsinfo->sta_cnt--; + _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + /* -2: AP + BC/MC sta, -4: default key */ + if (ptdlsinfo->sta_cnt < MAX_ALLOWED_TDLS_STA_NUM) { + ptdlsinfo->sta_maximum = _FALSE; + _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) ); + } + + /* clear cam */ + rtw_clearstakey_cmd(padapter, ptdls_sta, _TRUE); + + if (ptdlsinfo->sta_cnt == 0) { + rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR); + ptdlsinfo->link_established = _FALSE; + } + else + DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt); + + rtw_free_stainfo(padapter, ptdls_sta); + +} + + +/* TDLS encryption(if needed) will always be CCMP */ +void rtw_tdls_set_key(_adapter *padapter, struct sta_info *ptdls_sta) +{ + ptdls_sta->dot118021XPrivacy=_AES_; + rtw_setstakey_cmd(padapter, ptdls_sta, TDLS_KEY, _TRUE); +} + +#ifdef CONFIG_80211N_HT +void rtw_tdls_process_ht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + u8 max_AMPDU_len, min_MPDU_spacing; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0; + + /* Save HT capabilities in the sta object */ + _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap)); + if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap)) { + ptdls_sta->flags |= WLAN_STA_HT; + ptdls_sta->flags |= WLAN_STA_WME; + + _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap)); + } else + ptdls_sta->flags &= ~WLAN_STA_HT; + + if (ptdls_sta->flags & WLAN_STA_HT) { + if (padapter->registrypriv.ht_enable == _TRUE) { + ptdls_sta->htpriv.ht_option = _TRUE; + ptdls_sta->qos_option = _TRUE; + } else { + ptdls_sta->htpriv.ht_option = _FALSE; + ptdls_sta->qos_option = _FALSE; + } + } + + /* HT related cap */ + if (ptdls_sta->htpriv.ht_option) { + /* Check if sta supports rx ampdu */ + if (padapter->registrypriv.ampdu_enable == 1) + ptdls_sta->htpriv.ampdu_enable = _TRUE; + + /* AMPDU Parameters field */ + /* Get MIN of MAX AMPDU Length Exp */ + if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (data[2] & 0x3)) + max_AMPDU_len = (data[2] & 0x3); + else + 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) > (data[2] & 0x1c)) + min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c); + else + min_MPDU_spacing = (data[2] & 0x1c); + ptdls_sta->htpriv.rx_ampdu_min_spacing = max_AMPDU_len | min_MPDU_spacing; + + /* Check if sta support s Short GI 20M */ + if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) + ptdls_sta->htpriv.sgi_20m = _TRUE; + + /* Check if sta support s Short GI 40M */ + if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) + ptdls_sta->htpriv.sgi_40m = _TRUE; + + /* Bwmode would still followed AP's setting */ + if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) { + if (padapter->mlmeextpriv.cur_bwmode >= CHANNEL_WIDTH_40) + ptdls_sta->bw_mode = CHANNEL_WIDTH_40; + ptdls_sta->htpriv.ch_offset = padapter->mlmeextpriv.cur_ch_offset; + } + + /* Config LDPC Coding Capability */ + if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(data)) { + SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX)); + DBG_871X("Enable HT Tx LDPC!\n"); + } + ptdls_sta->htpriv.ldpc_cap = cur_ldpc_cap; + + /* Config STBC setting */ + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(data)) { + SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX)); + DBG_871X("Enable HT Tx STBC!\n"); + } + ptdls_sta->htpriv.stbc_cap = cur_stbc_cap; + +#ifdef CONFIG_BEAMFORMING + /* Config Tx beamforming setting */ + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(data)) { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); + } + + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(data)) { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + } + ptdls_sta->htpriv.beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) + DBG_871X("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap); +#endif /* CONFIG_BEAMFORMING */ + } + +} + +u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + rtw_ht_use_default_setting(padapter); + + rtw_restructure_ht_ie(padapter, NULL, pframe, 0, &(pattrib->pktlen), padapter->mlmeextpriv.cur_channel); + + return pframe + pattrib->pktlen; +} +#endif + +#ifdef CONFIG_80211AC_VHT +void rtw_tdls_process_vht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0, rf_type = RF_1T1R; + u8 *pcap_mcs; + u8 vht_mcs[2]; + + _rtw_memset(&ptdls_sta->vhtpriv, 0, sizeof(struct vht_priv)); + if (data && Length == 12) { + ptdls_sta->flags |= WLAN_STA_VHT; + + _rtw_memcpy(ptdls_sta->vhtpriv.vht_cap, data, 12); + +#if 0 + if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) { + _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1); + } else /* for Frame without Operating Mode notify ie; default: 80M */ { + pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80; + } +#else + ptdls_sta->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80; +#endif + } else + ptdls_sta->flags &= ~WLAN_STA_VHT; + + if (ptdls_sta->flags & WLAN_STA_VHT) { + if (padapter->registrypriv.vht_enable != 0 + && (!pmlmepriv->country_ent || COUNTRY_CHPLAN_EN_11AC(pmlmepriv->country_ent))) + ptdls_sta->vhtpriv.vht_option = _TRUE; + else + ptdls_sta->vhtpriv.vht_option = _FALSE; + } + + /* B4 Rx LDPC */ + if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_LDPC(data)) { + SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX)); + DBG_871X("Current VHT LDPC Setting = %02X\n", cur_ldpc_cap); + } + ptdls_sta->vhtpriv.ldpc_cap = cur_ldpc_cap; + + /* B5 Short GI for 80 MHz */ + ptdls_sta->vhtpriv.sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(data) & pvhtpriv->sgi_80m) ? _TRUE : _FALSE; + + /* B8 B9 B10 Rx STBC */ + if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_STBC(data)) { + SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX)); + DBG_871X("Current VHT STBC Setting = %02X\n", cur_stbc_cap); + } + ptdls_sta->vhtpriv.stbc_cap = cur_stbc_cap; + + /* B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFEE(data)) { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE); + } + + /* B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFER(data)) { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE); + } + ptdls_sta->vhtpriv.beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) + DBG_871X("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap); + + /* B23 B24 B25 Maximum A-MPDU Length Exponent */ + ptdls_sta->vhtpriv.ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(data); + + pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(data); + _rtw_memcpy(vht_mcs, pcap_mcs, 2); + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) + vht_mcs[0] |= 0xfc; + else if (rf_type == RF_2T2R) + vht_mcs[0] |= 0xf0; + else if (rf_type == RF_3T3R) + vht_mcs[0] |= 0xc0; + + _rtw_memcpy(ptdls_sta->vhtpriv.vht_mcs_map, vht_mcs, 2); + + ptdls_sta->vhtpriv.vht_highest_rate = rtw_get_vht_highest_rate(ptdls_sta->vhtpriv.vht_mcs_map); +} + +u8 *rtw_tdls_set_aid(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + return rtw_set_ie(pframe, EID_AID, 2, (u8 *)&(padapter->mlmepriv.cur_network.aid), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_vht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + u32 ie_len = 0; + + rtw_vht_use_default_setting(padapter); + + ie_len = rtw_build_vht_cap_ie(padapter, pframe); + pattrib->pktlen += ie_len; + + return pframe + ie_len; +} + +u8 *rtw_tdls_set_vht_operation(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib, u8 channel) +{ + u32 ie_len = 0; + + ie_len = rtw_build_vht_operation_ie(padapter, pframe, channel); + pattrib->pktlen += ie_len; + + return pframe + ie_len; +} + +u8 *rtw_tdls_set_vht_op_mode_notify(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib, u8 bw) +{ + u32 ie_len = 0; + + ie_len = rtw_build_vht_op_mode_notify_ie(padapter, pframe, bw); + pattrib->pktlen += ie_len; + + return pframe + ie_len; +} +#endif + + +u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 sup_ch[30 * 2] = {0x00}, ch_set_idx = 0, sup_ch_idx = 2; + + do { + if (pmlmeext->channel_set[ch_set_idx].ChannelNum <= 14) { + sup_ch[0] = 1; /* First channel number */ + sup_ch[1] = pmlmeext->channel_set[ch_set_idx].ChannelNum; /* Number of channel */ + } else { + sup_ch[sup_ch_idx++] = pmlmeext->channel_set[ch_set_idx].ChannelNum; + sup_ch[sup_ch_idx++] = 1; + } + ch_set_idx++; + } while (pmlmeext->channel_set[ch_set_idx].ChannelNum != 0 && ch_set_idx < MAX_CHANNEL_NUM); + + return rtw_set_ie(pframe, _SUPPORTED_CH_IE_, sup_ch_idx, sup_ch, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_rsnie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, int init, struct sta_info *ptdls_sta) +{ + u8 *p = NULL; + int len = 0; + + if (ptxmgmt->len > 0) + p = rtw_get_ie(ptxmgmt->buf, _RSN_IE_2_, &len, ptxmgmt->len); + + if (p != NULL) + return rtw_set_ie(pframe, _RSN_IE_2_, len, p+2, &(pattrib->pktlen)); + else + if (init == _TRUE) + return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen)); + else + return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(ptdls_sta->TDLS_RSNIE), ptdls_sta->TDLS_RSNIE, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_ext_cap(u8 *pframe, struct pkt_attrib *pattrib) +{ + return rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_qos_cap(u8 *pframe, struct pkt_attrib *pattrib) +{ + return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_ftie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, u8 *ANonce, u8 *SNonce) +{ + struct wpa_tdls_ftie FTIE = {0}; + u8 *p = NULL; + int len = 0; + + if (ptxmgmt->len > 0) + p = rtw_get_ie(ptxmgmt->buf, _FTIE_, &len, ptxmgmt->len); + + if (p != NULL) + return rtw_set_ie(pframe, _FTIE_, len, p+2, &(pattrib->pktlen)); + else { + if (ANonce != NULL) + _rtw_memcpy(FTIE.Anonce, ANonce, WPA_NONCE_LEN); + if (SNonce != NULL) + _rtw_memcpy(FTIE.Snonce, SNonce, WPA_NONCE_LEN); + return rtw_set_ie(pframe, _FTIE_ , 82, (u8 *)FTIE.mic_ctrl, &(pattrib->pktlen)); + } +} + +u8 *rtw_tdls_set_timeout_interval(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, int init, struct sta_info *ptdls_sta) +{ + u8 timeout_itvl[5]; /* set timeout interval to maximum value */ + u32 timeout_interval= TPK_RESEND_COUNT; + u8 *p = NULL; + int len = 0; + + if (ptxmgmt->len > 0) + p = rtw_get_ie(ptxmgmt->buf, _TIMEOUT_ITVL_IE_, &len, ptxmgmt->len); + + if (p != NULL) + return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, len, p+2, &(pattrib->pktlen)); + else { + /* Timeout interval */ + timeout_itvl[0]=0x02; + if (init == _TRUE) + _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4); + else + _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4); + + return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen)); + } +} + +u8 *rtw_tdls_set_bss_coexist(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 iedata=0; + + if (padapter->mlmepriv.num_FortyMHzIntolerant > 0) + iedata |= BIT(2); /* 20 MHz BSS Width Request */ + + /* Information Bit should be set by TDLS test plan 5.9 */ + iedata |= BIT(0); + return rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_payload_type(u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 payload_type = 0x02; + return rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_category(u8 *pframe, struct pkt_attrib *pattrib, u8 category) +{ + return rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_action(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt) +{ + return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->action_code), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_status_code(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt) +{ + return rtw_set_fixed_ie(pframe, 2, (u8 *)&(ptxmgmt->status_code), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_dialog(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt) +{ + u8 dialogtoken = 1; + if (ptxmgmt->dialog_token) + return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->dialog_token), &(pattrib->pktlen)); + else + return rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_reg_class(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta) +{ + u8 reg_class = 1; + return rtw_set_fixed_ie(pframe, 1, &(reg_class), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_capability(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u8 cap_from_ie[2] = {0}; + + _rtw_memcpy(cap_from_ie, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); + + return rtw_set_fixed_ie(pframe, 2, cap_from_ie, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_supported_rate(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; + int bssrate_len = 0; + u8 more_supportedrates = 0; + + rtw_set_supported_rate(bssrate, (padapter->registrypriv.wireless_mode == WIRELESS_MODE_MAX) ? padapter->mlmeextpriv.cur_wireless_mode : padapter->registrypriv.wireless_mode); + bssrate_len = rtw_get_rateset_len(bssrate); + + if (bssrate_len > 8) { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen)); + more_supportedrates = 1; + } else { + pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen)); + } + + /* extended supported rates */ + if (more_supportedrates == 1) { + pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); + } + + return pframe; +} + +u8 *rtw_tdls_set_sup_reg_class(u8 *pframe, struct pkt_attrib *pattrib) +{ + return rtw_set_ie(pframe, _SRC_IE_ , sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_linkid(u8 *pframe, struct pkt_attrib *pattrib, u8 init) +{ + u8 link_id_addr[18] = {0}; + if (init == _TRUE) { + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->src, 6); + _rtw_memcpy((link_id_addr+12), pattrib->dst, 6); + } else { + _rtw_memcpy(link_id_addr, pattrib->ra, 6); + _rtw_memcpy((link_id_addr+6), pattrib->dst, 6); + _rtw_memcpy((link_id_addr+12), pattrib->src, 6); + } + return rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen)); +} + +#ifdef CONFIG_TDLS_CH_SW +u8 *rtw_tdls_set_target_ch(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + u8 target_ch = 1; + if (padapter->tdlsinfo.chsw_info.off_ch_num) + return rtw_set_fixed_ie(pframe, 1, &(padapter->tdlsinfo.chsw_info.off_ch_num), &(pattrib->pktlen)); + else + return rtw_set_fixed_ie(pframe, 1, &(target_ch), &(pattrib->pktlen)); +} + +u8 *rtw_tdls_set_ch_sw(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta) +{ + u8 ch_switch_timing[4] = {0}; + u16 switch_time = (ptdls_sta->ch_switch_time >= CH_SWITCH_TIME * 1000) ? + ptdls_sta->ch_switch_time : CH_SWITCH_TIME; + u16 switch_timeout = (ptdls_sta->ch_switch_timeout >= CH_SWITCH_TIMEOUT * 1000) ? + ptdls_sta->ch_switch_timeout : CH_SWITCH_TIMEOUT; + + _rtw_memcpy(ch_switch_timing, &switch_time, 2); + _rtw_memcpy(ch_switch_timing + 2, &switch_timeout, 2); + + return rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen)); +} +#endif + +u8 *rtw_tdls_set_wmm_params(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib) +{ + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 wmm_param_ele[24] = {0}; + + if (&pmlmeinfo->WMM_param) { + _rtw_memcpy(wmm_param_ele, WMM_PARA_OUI, 6); + if (_rtw_memcmp(&pmlmeinfo->WMM_param, &wmm_param_ele[6], 18) == _TRUE) + /* Use default WMM Param */ + _rtw_memcpy(wmm_param_ele + 6, (u8 *)&TDLS_WMM_PARAM_IE, sizeof(TDLS_WMM_PARAM_IE)); + else + _rtw_memcpy(wmm_param_ele + 6, (u8 *)&pmlmeinfo->WMM_param, sizeof(pmlmeinfo->WMM_param)); + return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 24, wmm_param_ele, &(pattrib->pktlen)); + } + else + return pframe; +} + +#ifdef CONFIG_WFD +void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length) +{ + u8 *wfd_ie; + u32 wfd_ielen = 0; + + if (!hal_chk_wl_func(tdls_info_to_adapter(ptdlsinfo), WL_FUNC_MIRACAST)) + return; + + /* Try to get the TCP port information when receiving the negotiation response. */ + + wfd_ie = rtw_get_wfd_ie(ptr, length, NULL, &wfd_ielen); + while (wfd_ie) { + u8 *attr_content; + u32 attr_contentlen = 0; + int i; + + DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ ); + attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen); + if (attr_content && attr_contentlen) { + ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 ); + DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport ); + } + + attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, NULL, &attr_contentlen); + if (attr_content && attr_contentlen) { + _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4); + DBG_871X("[%s] Peer IP = %02u.%02u.%02u.%02u\n", __FUNCTION__, + ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1], + ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]); + } + + wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ptr + length) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen); + } +} + +int issue_tunneled_probe_req(_adapter *padapter) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct tdls_txmgmt txmgmt; + int ret = _FAIL; + + DBG_871X("[%s]\n", __FUNCTION__); + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + txmgmt.action_code = TUNNELED_PROBE_REQ; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; +exit: + + return ret; +} + +int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct tdls_txmgmt txmgmt; + int ret = _FAIL; + + DBG_871X("[%s]\n", __FUNCTION__); + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + txmgmt.action_code = TUNNELED_PROBE_RSP; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, precv_frame->u.hdr.attrib.src, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; +exit: + + return ret; +} +#endif /* CONFIG_WFD */ + +int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta= NULL; + _irqL irqL; + int ret = _FAIL; + /* Retry timer should be set at least 301 sec, using TPK_count counting 301 times. */ + u32 timeout_interval= TPK_RESEND_COUNT; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_SETUP_REQUEST; + if (ptdlsinfo->ap_prohibited == _TRUE) + goto exit; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + + /* init peer sta_info */ + ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer); + if (ptdls_sta == NULL) { + ptdls_sta = rtw_alloc_stainfo(pstapriv, ptxmgmt->peer); + if (ptdls_sta == NULL) { + DBG_871X("[%s] rtw_alloc_stainfo fail\n", __FUNCTION__); + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + } + + if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) + ptdlsinfo->sta_cnt++; + + if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM) + ptdlsinfo->sta_maximum = _TRUE; + + ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE; + + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) { + ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval; + _set_timer(&ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME); + } + + pattrib->qsel = pattrib->priority; + + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) { + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + +exit: + + return ret; +} + +int _issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta=NULL; + _irqL irqL; + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_TEARDOWN; + ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer); + if (ptdls_sta == NULL) { + DBG_871X("Np tdls_sta for tearing down\n"); + goto exit; + } + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + rtw_set_scan_deny(padapter, 550); + + rtw_scan_abort(padapter); +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + rtw_scan_abort(padapter->pbuddy_adapter); +#endif /* CONFIG_CONCURRENT_MODE */ + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) + if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) + if (pattrib->encrypt) + _cancel_timer_ex(&ptdls_sta->TPK_timer); + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + + if (ret == _SUCCESS && rtw_tdls_is_driver_setup(padapter)) + rtw_tdls_cmd(padapter, ptxmgmt->peer, TDLS_TEAR_STA); + +exit: + + return ret; +} + +int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack) +{ + int ret = _FAIL; + + ret = _issue_tdls_teardown(padapter, ptxmgmt, wait_ack); + if ((ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) && (ret == _FAIL)) { + /* Change status code and send teardown again via AP */ + ptxmgmt->status_code = _RSON_TDLS_TEAR_TOOFAR_; + ret = _issue_tdls_teardown(padapter, ptxmgmt, wait_ack); + } + + return ret; +} + +int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_DISCOVERY_REQUEST; + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + dump_mgntframe(padapter, pmgntframe); + DBG_871X("issue tdls dis req\n"); + + ret = _SUCCESS; +exit: + + return ret; +} + +int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_SETUP_RESPONSE; + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(&(padapter->mlmepriv)), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + dump_mgntframe(padapter, pmgntframe); + + ret = _SUCCESS; +exit: + + return ret; + +} + +int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_SETUP_CONFIRM; + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(&padapter->mlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + dump_mgntframe(padapter, pmgntframe); + + ret = _SUCCESS; +exit: + + return ret; + +} + +/* TDLS Discovery Response frame is a management action frame */ +int issue_tdls_dis_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy) +{ + 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); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + 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; + + /* unicast probe request frame */ + _rtw_memcpy(pwlanhdr->addr1, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN); + + 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); + + rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, ptxmgmt, privacy); + + pattrib->nr_frags = 1; + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + +exit: + return ret; +} + +int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *ptdls_sta, struct tdls_txmgmt *ptxmgmt) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + ptxmgmt->action_code = TDLS_PEER_TRAFFIC_RESPONSE; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) { + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + +exit: + + return ret; +} + +int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct tdls_txmgmt txmgmt; + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + txmgmt.action_code = TDLS_PEER_TRAFFIC_INDICATION; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + /* PTI frame's priority should be AC_VO */ + pattrib->priority = 7; + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) { + rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + +exit: + + return ret; +} + +int issue_tdls_ch_switch_req(_adapter *padapter, struct sta_info *ptdls_sta) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct tdls_txmgmt txmgmt; + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { DBG_871X("[TDLS] Ignore %s since ch_switch_prohibited = _TRUE\n", __FUNCTION__); + goto exit; + } + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + txmgmt.action_code = TDLS_CHANNEL_SWITCH_REQUEST; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS) { + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; +exit: + + return ret; +} + +int issue_tdls_ch_switch_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + int ret = _FAIL; + + DBG_871X("[TDLS] %s\n", __FUNCTION__); + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { DBG_871X("[TDLS] Ignore %s since ch_switch_prohibited = _TRUE\n", __FUNCTION__); + goto exit; + } + + ptxmgmt->action_code = TDLS_CHANNEL_SWITCH_RESPONSE; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + goto exit; + + pattrib = &pmgntframe->attrib; + + pmgntframe->frame_tag = DATA_FRAMETAG; + pattrib->ether_type = 0x890d; + + _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN); + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + + update_tdls_attrib(padapter, pattrib); + pattrib->qsel = pattrib->priority; +/* + _enter_critical_bh(&pxmitpriv->lock, &irqL); + if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){ + _exit_critical_bh(&pxmitpriv->lock, &irqL); + return _FALSE; + } +*/ + if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) { + rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf); + rtw_free_xmitframe(pxmitpriv, pmgntframe); + goto exit; + } + + if (wait_ack) { + ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } + ret = _SUCCESS; +exit: + + return ret; +} + +int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(padapter->stapriv), get_bssid(&(padapter->mlmepriv))); + struct recv_priv *precvpriv = &(padapter->recvpriv); + u8 *ptr = precv_frame->u.hdr.rx_data, *psa; + struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib); + struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo); + u8 empty_addr[ETH_ALEN] = { 0x00 }; + int UndecoratedSmoothedPWDB; + struct tdls_txmgmt txmgmt; + int ret = _SUCCESS; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + /* WFDTDLS: for sigma test, not to setup direct link automatically */ + ptdlsinfo->dev_discovered = _TRUE; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), psa); + if (ptdls_sta != NULL) + ptdls_sta->sta_stats.rx_tdls_disc_rsp_pkts++; + +#ifdef CONFIG_TDLS_AUTOSETUP + if (ptdls_sta != NULL) { + /* Record the tdls sta with lowest signal strength */ + if (ptdlsinfo->sta_maximum == _TRUE && ptdls_sta->alive_count >= 1 ) { + if (_rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) { + _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN); + ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.RxPWDBAll; + } else { + if (ptdlsinfo->ss_record.RxPWDBAll < pattrib->phy_info.RxPWDBAll) { + _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN); + ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.RxPWDBAll; + } + } + } + } else { + if (ptdlsinfo->sta_maximum == _TRUE) { + if (_rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) { + /* All traffics are busy, do not set up another direct link. */ + ret = _FAIL; + goto exit; + } else { + if (pattrib->phy_info.RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll) { + _rtw_memcpy(txmgmt.peer, ptdlsinfo->ss_record.macaddr, ETH_ALEN); + /* issue_tdls_teardown(padapter, ptdlsinfo->ss_record.macaddr, _FALSE); */ + } else { + ret = _FAIL; + goto exit; + } + } + } + + rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + + if (pattrib->phy_info.RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB) { + DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->phy_info.RxPWDBAll, UndecoratedSmoothedPWDB); + _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN); + issue_tdls_setup_req(padapter, &txmgmt, _FALSE); + } + } +#endif /* CONFIG_TDLS_AUTOSETUP */ + +exit: + return ret; + +} + +sint On_TDLS_Setup_Req(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 *psa, *pmyid; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct security_priv *psecuritypriv = &padapter->securitypriv; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *prsnie, *ppairwise_cipher; + u8 i, k; + u8 ccmp_included=0, rsnie_included=0; + u16 j, pairwise_count; + u8 SNonce[32]; + u32 timeout_interval = TPK_RESEND_COUNT; + sint parsing_length; /* Frame body length, without icv_len */ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 5; + unsigned char supportRate[16]; + int supportRateNum = 0; + struct tdls_txmgmt txmgmt; + + if (ptdlsinfo->ap_prohibited == _TRUE) + goto exit; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + pmyid = adapter_mac_addr(padapter); + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + if (ptdls_sta == NULL) { + ptdls_sta = rtw_alloc_stainfo(pstapriv, psa); + } else { + if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + /* If the direct link is already set up */ + /* Process as re-setup after tear down */ + DBG_871X("re-setup a direct link\n"); + } + /* Already receiving TDLS setup request */ + else if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) { + DBG_871X("receive duplicated TDLS setup request frame in handshaking\n"); + goto exit; + } + /* When receiving and sending setup_req to the same link at the same time */ + /* STA with higher MAC_addr would be initiator */ + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) { + DBG_871X("receive setup_req after sending setup_req\n"); + for (i=0;i<6;i++){ + if(*(pmyid+i)==*(psa+i)){ + } + else if(*(pmyid+i)>*(psa+i)){ + ptdls_sta->tdls_sta_state = TDLS_INITIATOR_STATE; + break; + }else if(*(pmyid+i)<*(psa+i)){ + goto exit; + } + } + } + } + + if (ptdls_sta) { + txmgmt.dialog_token = *(ptr+2); /* Copy dialog token */ + txmgmt.status_code = _STATS_SUCCESSFUL_; + + /* Parsing information element */ + for (j=FIXED_IE; jElementID) { + case _SUPPORTEDRATES_IE_: + _rtw_memcpy(supportRate, pIE->data, pIE->Length); + supportRateNum = pIE->Length; + break; + case _COUNTRY_IE_: + break; + case _EXT_SUPPORTEDRATES_IE_: + if (supportRateNum<=sizeof(supportRate)) { + _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length); + supportRateNum += pIE->Length; + } + break; + case _SUPPORTED_CH_IE_: + break; + case _RSN_IE_2_: + rsnie_included=1; + if (prx_pkt_attrib->encrypt) { + prsnie=(u8*)pIE; + /* Check CCMP pairwise_cipher presence. */ + ppairwise_cipher=prsnie+10; + _rtw_memcpy(ptdls_sta->TDLS_RSNIE, pIE->data, pIE->Length); + pairwise_count = *(u16*)(ppairwise_cipher-2); + for (k=0; kencrypt) + _rtw_memcpy(SNonce, (ptr+j+52), 32); + break; + case _TIMEOUT_ITVL_IE_: + if (prx_pkt_attrib->encrypt) + timeout_interval = cpu_to_le32(*(u32*)(ptr+j+3)); + break; + case _RIC_Descriptor_IE_: + break; +#ifdef CONFIG_80211N_HT + case _HT_CAPABILITY_IE_: + rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length); + break; +#endif +#ifdef CONFIG_80211AC_VHT + case EID_AID: + break; + case EID_VHTCapability: + rtw_tdls_process_vht_cap(padapter, ptdls_sta, pIE->data, pIE->Length); + break; +#endif + case EID_BSSCoexistence: + break; + case _LINK_ID_IE_: + if (_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE) + txmgmt.status_code=_STATS_NOT_IN_SAME_BSS_; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + /* Check status code */ + /* If responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject */ + if (txmgmt.status_code == _STATS_SUCCESSFUL_) { + if (rsnie_included && prx_pkt_attrib->encrypt == 0) + txmgmt.status_code = _STATS_SEC_DISABLED_; + else if (rsnie_included==0 && prx_pkt_attrib->encrypt) + txmgmt.status_code = _STATS_INVALID_PARAMETERS_; + +#ifdef CONFIG_WFD + /* WFD test plan version 0.18.2 test item 5.1.5 */ + /* SoUT does not use TDLS if AP uses weak security */ + if (padapter->wdinfo.wfd_tdls_enable && (rsnie_included && prx_pkt_attrib->encrypt != _AES_)) + txmgmt.status_code = _STATS_SEC_DISABLED_; +#endif /* CONFIG_WFD */ + } + + ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE; + if (prx_pkt_attrib->encrypt) { + _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32); + + if (timeout_interval <= 300) + ptdls_sta->TDLS_PeerKey_Lifetime = TPK_RESEND_COUNT; + else + ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval; + } + + /* Update station supportRate */ + ptdls_sta->bssratelen = supportRateNum; + _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum); + + if (!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) + ptdlsinfo->sta_cnt++; + /* -2: AP + BC/MC sta, -4: default key */ + if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM) + ptdlsinfo->sta_maximum = _TRUE; + +#ifdef CONFIG_WFD + rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length); +#endif + + }else { + goto exit; + } + + _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN); + + if (rtw_tdls_is_driver_setup(padapter)) { + issue_tdls_setup_rsp(padapter, &txmgmt); + + if (txmgmt.status_code==_STATS_SUCCESSFUL_) { + _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME); + }else { + free_tdls_sta(padapter, ptdls_sta); + } + } + +exit: + + return _SUCCESS; +} + +int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + u16 status_code=0; + sint parsing_length; /* Frame body length, without icv_len */ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =7; + u8 ANonce[32]; + u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL; + u16 pairwise_count, j, k; + u8 verify_ccmp=0; + unsigned char supportRate[16]; + int supportRateNum = 0; + struct tdls_txmgmt txmgmt; + int ret = _SUCCESS; + u32 timeout_interval = TPK_RESEND_COUNT; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + if (NULL == ptdls_sta) { + ret = _FAIL; + goto exit; + } + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + _rtw_memcpy(&status_code, ptr+2, 2); + + if (status_code != 0) { + DBG_871X( "[TDLS] %s status_code = %d, free_tdls_sta\n", __FUNCTION__, status_code ); + free_tdls_sta(padapter, ptdls_sta); + ret = _FAIL; + goto exit; + } + + status_code = 0; + + /* parsing information element */ + for (j = FIXED_IE; jElementID) { + case _SUPPORTEDRATES_IE_: + _rtw_memcpy(supportRate, pIE->data, pIE->Length); + supportRateNum = pIE->Length; + break; + case _COUNTRY_IE_: + break; + case _EXT_SUPPORTEDRATES_IE_: + if (supportRateNum<=sizeof(supportRate)) { + _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length); + supportRateNum += pIE->Length; + } + break; + case _SUPPORTED_CH_IE_: + break; + case _RSN_IE_2_: + prsnie=(u8*)pIE; + /* Check CCMP pairwise_cipher presence. */ + ppairwise_cipher=prsnie+10; + _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2); + for (k=0;kwmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE)) + ptdls_sta->qos_option = _TRUE; + } + break; + case _FTIE_: + pftie=(u8*)pIE; + _rtw_memcpy(ANonce, (ptr+j+20), 32); + break; + case _TIMEOUT_ITVL_IE_: + ptimeout_ie=(u8*)pIE; + timeout_interval = cpu_to_le32(*(u32*)(ptimeout_ie+3)); + break; + case _RIC_Descriptor_IE_: + break; +#ifdef CONFIG_80211N_HT + case _HT_CAPABILITY_IE_: + rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length); + break; +#endif +#ifdef CONFIG_80211AC_VHT + case EID_AID: + /* todo in the future if necessary */ + break; + case EID_VHTCapability: + rtw_tdls_process_vht_cap(padapter, ptdls_sta, pIE->data, pIE->Length); + break; + case EID_OpModeNotification: + rtw_process_vht_op_mode_notify(padapter, pIE->data, ptdls_sta); + break; +#endif + case EID_BSSCoexistence: + break; + case _LINK_ID_IE_: + plinkid_ie=(u8*)pIE; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + ptdls_sta->bssratelen = supportRateNum; + _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum); + _rtw_memcpy(ptdls_sta->ANonce, ANonce, 32); + +#ifdef CONFIG_WFD + rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length); +#endif + + if (status_code != _STATS_SUCCESSFUL_) { + txmgmt.status_code = status_code; + } else { + if (prx_pkt_attrib->encrypt) { + if (verify_ccmp == 1) { + txmgmt.status_code = _STATS_SUCCESSFUL_; + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) { + wpa_tdls_generate_tpk(padapter, ptdls_sta); + if (tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL) { + DBG_871X( "[TDLS] %s tdls_verify_mic fail, free_tdls_sta\n", __FUNCTION__); + free_tdls_sta(padapter, ptdls_sta); + ret = _FAIL; + goto exit; + } + ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval; + } + } + else + { + txmgmt.status_code = _STATS_INVALID_RSNIE_; + } + + }else{ + txmgmt.status_code = _STATS_SUCCESSFUL_; + } + } + + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) { + _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN); + issue_tdls_setup_cfm(padapter, &txmgmt); + + if (txmgmt.status_code == _STATS_SUCCESSFUL_) { + ptdlsinfo->link_established = _TRUE; + + if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) { + ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; + ptdls_sta->state |= _FW_LINKED; + _cancel_timer_ex( &ptdls_sta->handshake_timer); + } + + if (prx_pkt_attrib->encrypt) + rtw_tdls_set_key(padapter, ptdls_sta); + + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED); + + } + } + +exit: + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) + return ret; + else + return _SUCCESS; + +} + +int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + _irqL irqL; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + u16 status_code=0; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE =5; + u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL; + u16 j, pairwise_count; + int ret = _SUCCESS; + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + if (ptdls_sta == NULL) { + DBG_871X("[%s] Direct Link Peer = "MAC_FMT" not found\n", __FUNCTION__, MAC_ARG(psa)); + ret = _FAIL; + goto exit; + } + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + _rtw_memcpy(&status_code, ptr+2, 2); + + if (status_code!= 0) { + DBG_871X("[%s] status_code = %d\n, free_tdls_sta", __FUNCTION__, status_code); + free_tdls_sta(padapter, ptdls_sta); + ret = _FAIL; + goto exit; + } + + /* Parsing information element */ + for (j = FIXED_IE; j < parsing_length;) { + + pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j); + + switch (pIE->ElementID) { + case _RSN_IE_2_: + prsnie = (u8 *)pIE; + break; + case _VENDOR_SPECIFIC_IE_: + if (_rtw_memcmp((u8 *)pIE + 2, WMM_PARA_OUI, 6) == _TRUE) { + /* WMM Parameter ID and OUI */ + ptdls_sta->qos_option = _TRUE; + } + break; + case _FTIE_: + pftie = (u8 *)pIE; + break; + case _TIMEOUT_ITVL_IE_: + ptimeout_ie = (u8 *)pIE; + break; +#ifdef CONFIG_80211N_HT + case _HT_EXTRA_INFO_IE_: + break; +#endif +#ifdef CONFIG_80211AC_VHT + case EID_VHTOperation: + break; + case EID_OpModeNotification: + rtw_process_vht_op_mode_notify(padapter, pIE->data, ptdls_sta); + break; +#endif + case _LINK_ID_IE_: + plinkid_ie = (u8 *)pIE; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + if (prx_pkt_attrib->encrypt) { + /* Verify mic in FTIE MIC field */ + if (rtw_tdls_is_driver_setup(padapter) && + (tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL)) { + free_tdls_sta(padapter, ptdls_sta); + ret = _FAIL; + goto exit; + } + } + + if (rtw_tdls_is_driver_setup(padapter)) { + ptdlsinfo->link_established = _TRUE; + + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) { + ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE; + ptdls_sta->state |= _FW_LINKED; + _cancel_timer_ex(&ptdls_sta->handshake_timer); + } + + if (prx_pkt_attrib->encrypt) { + rtw_tdls_set_key(padapter, ptdls_sta); + + /* Start TPK timer */ + ptdls_sta->TPK_count = 0; + _set_timer(&ptdls_sta->TPK_timer, ONE_SEC); + } + + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED); + } + +exit: + return ret; + +} + +int On_TDLS_Dis_Req(_adapter *padapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta_ap; + u8 *ptr = precv_frame->u.hdr.rx_data; + sint parsing_length; /* Frame body length, without icv_len */ + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 3, *dst; + u16 j; + struct tdls_txmgmt txmgmt; + int ret = _SUCCESS; + + if (rtw_tdls_is_driver_setup(padapter) == _FALSE) + goto exit; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + txmgmt.dialog_token = *(ptr+2); + _rtw_memcpy(&txmgmt.peer, precv_frame->u.hdr.attrib.src, ETH_ALEN); + txmgmt.action_code = TDLS_DISCOVERY_RESPONSE; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + /* Parsing information element */ + for (j=FIXED_IE; jElementID) { + case _LINK_ID_IE_: + psta_ap = rtw_get_stainfo(pstapriv, pIE->data); + if (psta_ap == NULL) + goto exit; + dst = pIE->data + 12; + if (MacAddr_isBcst(dst) == _FALSE && (_rtw_memcmp(adapter_mac_addr(padapter), dst, 6) == _FALSE)) + goto exit; + break; + default: + break; + } + + j += (pIE->Length + 2); + + } + + issue_tdls_dis_rsp(padapter, &txmgmt, prx_pkt_attrib->privacy); + +exit: + return ret; + +} + +int On_TDLS_Teardown(_adapter *padapter, union recv_frame *precv_frame) +{ + u8 *psa; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta= NULL; + _irqL irqL; + u8 reason; + + reason = *(ptr + prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN + 2); + DBG_871X("[TDLS] %s Reason code(%d)\n", __FUNCTION__,reason); + + psa = get_sa(ptr); + + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + if (ptdls_sta != NULL) { + if (rtw_tdls_is_driver_setup(padapter)) + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_TEAR_STA); + } + + return _SUCCESS; + +} + +#if 0 +u8 TDLS_check_ch_state(uint state){ + if (state & TDLS_CH_SWITCH_ON_STATE && + state & TDLS_PEER_AT_OFF_STATE) { + if (state & TDLS_PEER_SLEEP_STATE) + return 2; /* U-APSD + ch. switch */ + else + return 1; /* ch. switch */ + }else + return 0; +} +#endif + +int On_TDLS_Peer_Traffic_Indication(_adapter *padapter, union recv_frame *precv_frame) +{ + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src); + u8 *ptr = precv_frame->u.hdr.rx_data; + struct tdls_txmgmt txmgmt; + + ptr +=pattrib->hdrlen + pattrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + + if (ptdls_sta != NULL) { + txmgmt.dialog_token = *(ptr+2); + issue_tdls_peer_traffic_rsp(padapter, ptdls_sta, &txmgmt); + //issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0); + } else { + DBG_871X("from unknown sta:"MAC_FMT"\n", MAC_ARG(pattrib->src)); + return _FAIL; + } + + return _SUCCESS; +} + +/* We process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here */ +int On_TDLS_Peer_Traffic_Rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src); + u8 wmmps_ac=0; + /* u8 state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state); */ + int i; + + ptdls_sta->sta_stats.rx_data_pkts++; + + ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE); + + /* Check 4-AC queue bit */ + if (ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk) + wmmps_ac=1; + + /* If it's a direct link and have buffered frame */ + if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + if (wmmps_ac) { + _irqL irqL; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + + _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + xmitframe_phead = get_list_head(&ptdls_sta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + /* transmit buffered frames */ + while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + xmitframe_plist = get_next(xmitframe_plist); + rtw_list_delete(&pxmitframe->list); + + ptdls_sta->sleepq_len--; + ptdls_sta->sleepq_ac_len--; + if (ptdls_sta->sleepq_len>0) { + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + } else { + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + pxmitframe->attrib.triggered = 1; + + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + } + + if (ptdls_sta->sleepq_len==0) + DBG_871X("no buffered packets for tdls to xmit\n"); + else { + DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len); + ptdls_sta->sleepq_len=0; + } + + _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + } + + } + + return _SUCCESS; +} + +#ifdef CONFIG_TDLS_CH_SW +sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 4; + u16 j; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct tdls_txmgmt txmgmt; + u16 switch_time= CH_SWITCH_TIME * 1000, switch_timeout=CH_SWITCH_TIMEOUT * 1000; + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { DBG_871X("[TDLS] Ignore %s since ch_switch_prohibited = _TRUE\n", __FUNCTION__); + return _SUCCESS; + } + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + ptdls_sta->ch_switch_time=switch_time; + ptdls_sta->ch_switch_timeout=switch_timeout; + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + pchsw_info->off_ch_num = *(ptr + 2); + + if (*(ptr + 2) == 2) { + pchsw_info->off_ch_num = 11; + } + + if (pchsw_info->off_ch_num != pmlmeext->cur_channel) { + pchsw_info->delay_switch_back = _FALSE; + } + + /* Parsing information element */ + for (j=FIXED_IE; jElementID) { + case EID_SecondaryChnlOffset: + padapter->tdlsinfo.chsw_info.ch_offset = *(pIE->data); + break; + case _LINK_ID_IE_: + break; + case _CH_SWITCH_TIMING_: + ptdls_sta->ch_switch_time = (RTW_GET_LE16(pIE->data) >= CH_SWITCH_TIME * 1000) ? + RTW_GET_LE16(pIE->data) : CH_SWITCH_TIME * 1000; + ptdls_sta->ch_switch_timeout = (RTW_GET_LE16(pIE->data + 2) >= CH_SWITCH_TIMEOUT * 1000) ? + RTW_GET_LE16(pIE->data + 2) : CH_SWITCH_TIMEOUT * 1000; + DBG_871X("%s ch_switch_time:%d, ch_switch_timeout:%d\n" + , __FUNCTION__, RTW_GET_LE16(pIE->data), RTW_GET_LE16(pIE->data + 2)); + default: + break; + } + + j += (pIE->Length + 2); + } + + /* Todo: check status */ + txmgmt.status_code = 0; + _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN); + + ATOMIC_SET(&pchsw_info->chsw_on, _TRUE); + + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_RESP); + + return _SUCCESS; +} + +sint On_TDLS_Ch_Switch_Rsp(_adapter *padapter, union recv_frame *precv_frame) +{ + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + struct sta_info *ptdls_sta= NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ptr = precv_frame->u.hdr.rx_data; + struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib; + u8 *psa; + sint parsing_length; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 FIXED_IE = 4; + u16 status_code, j, switch_time, switch_timeout; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + int ret = _SUCCESS; + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { DBG_871X("[TDLS] Ignore %s since ch_switch_prohibited = _TRUE\n", __FUNCTION__); + return _SUCCESS; + } + + psa = get_sa(ptr); + ptdls_sta = rtw_get_stainfo(pstapriv, psa); + + /* If we receive Unsolicited TDLS Channel Switch Response when channel switch is running, */ + /* we will go back to base channel and terminate this channel switch procedure */ + if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) { + if (pmlmeext->cur_channel != rtw_get_oper_ch(padapter)) { + DBG_871X("receive unsolicited channel switch response \n"); + rtw_tdls_cmd(padapter, NULL, TDLS_CH_SW_BACK); + goto exit; + } + } + + ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN; + parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len + -prx_pkt_attrib->hdrlen + -prx_pkt_attrib->iv_len + -prx_pkt_attrib->icv_len + -LLC_HEADER_SIZE + -ETH_TYPE_LEN + -PAYLOAD_TYPE_LEN + -FIXED_IE; + + _rtw_memcpy(&status_code, ptr+2, 2); + + if (status_code != 0) { + DBG_871X("[%s] status_code:%d\n", __FUNCTION__, status_code); + pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + ret = _FAIL; + goto exit; + } + + /* Parsing information element */ + for (j = FIXED_IE; j < parsing_length;) { + pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j); + + switch (pIE->ElementID) { + case _LINK_ID_IE_: + break; + case _CH_SWITCH_TIMING_: + _rtw_memcpy(&switch_time, pIE->data, 2); + if (switch_time > ptdls_sta->ch_switch_time) + _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2); + + _rtw_memcpy(&switch_timeout, pIE->data + 2, 2); + if (switch_timeout > ptdls_sta->ch_switch_timeout) + _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2); + break; + default: + break; + } + + j += (pIE->Length + 2); + } + + if ((pmlmeext->cur_channel == rtw_get_oper_ch(padapter)) && + (pchsw_info->ch_sw_state & TDLS_WAIT_CH_RSP_STATE)) { + ATOMIC_SET(&pchsw_info->chsw_on, _TRUE); + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW); + } + +exit: + return ret; +} +#endif /* CONFIG_TDLS_CH_SW */ + +#ifdef CONFIG_WFD +void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen ) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info; + u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 }; + u32 wfdielen = 0; + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) + return; + + /* WFD OUI */ + wfdielen = 0; + wfdie[ wfdielen++ ] = 0x50; + wfdie[ wfdielen++ ] = 0x6F; + wfdie[ wfdielen++ ] = 0x9A; + wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */ + + /* + * Commented by Albert 20110825 + * According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes + * 1. WFD Device Information + * 2. Associated BSSID ( Optional ) + * 3. Local IP Adress ( Optional ) + */ + + /* WFD Device Information ATTR */ + /* Type: */ + wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO; + + /* Length: */ + /* Note: In the WFD specification, the size of length field is 2. */ + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + /* Value1: */ + /* WFD device information */ + /* available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery ) */ + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL + | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD); + wfdielen += 2; + + /* Value2: */ + /* Session Management Control Port */ + /* Default TCP port for RTSP messages is 554 */ + RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->tdls_rtsp_ctrlport); + wfdielen += 2; + + /* Value3: */ + /* WFD Device Maximum Throughput */ + /* 300Mbps is the maximum throughput */ + RTW_PUT_BE16(wfdie + wfdielen, 300); + wfdielen += 2; + + /* Associated BSSID ATTR */ + /* Type: */ + wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID; + + /* Length: */ + /* Note: In the WFD specification, the size of length field is 2. */ + RTW_PUT_BE16(wfdie + wfdielen, 0x0006); + wfdielen += 2; + + /* Value: */ + /* Associated BSSID */ + if (check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE) + _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN); + else + _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN); + + /* Local IP Address ATTR */ + wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR; + + /* Length: */ + /* Note: In the WFD specification, the size of length field is 2. */ + RTW_PUT_BE16(wfdie + wfdielen, 0x0005); + wfdielen += 2; + + /* Version: */ + /* 0x01: Version1;IPv4 */ + wfdie[ wfdielen++ ] = 0x01; + + /* IPv4 Address */ + _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 ); + wfdielen += 4; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen); + +} +#endif /* CONFIG_WFD */ + +void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst); + + int i = 0 ; + u32 time; + u8 *pframe_head; + + /* SNonce */ + if (pattrib->encrypt) { + for (i=0;i<8;i++) { + time=rtw_get_current_time(); + _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4); + } + } + + pframe_head = pframe; /* For rtw_tdls_set_ht_cap() */ + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + + pframe = rtw_tdls_set_capability(padapter, pframe, pattrib); + pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib); + pframe = rtw_tdls_set_sup_ch(&(padapter->mlmeextpriv), pframe, pattrib); + pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib); + + if (pattrib->encrypt) + pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta); + + pframe = rtw_tdls_set_ext_cap(pframe, pattrib); + + if (pattrib->encrypt) { + pframe = rtw_tdls_set_ftie(ptxmgmt + , pframe + , pattrib + , NULL + , ptdls_sta->SNonce); + + pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta); + } + +#ifdef CONFIG_80211N_HT + /* Sup_reg_classes(optional) */ + if (pregistrypriv->ht_enable == _TRUE) + pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib); +#endif + + pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib); + + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE)) + pframe = rtw_tdls_set_qos_cap(pframe, pattrib); + +#ifdef CONFIG_80211AC_VHT + if ((padapter->mlmepriv.htpriv.ht_option == _TRUE) && (pregistrypriv->vht_enable != 0) && (pmlmeext->cur_channel > 14) + && (!padapter->mlmepriv.country_ent || COUNTRY_CHPLAN_EN_11AC(padapter->mlmepriv.country_ent)) + ) { + pframe = rtw_tdls_set_aid(padapter, pframe, pattrib); + pframe = rtw_tdls_set_vht_cap(padapter, pframe, pattrib); + } +#endif + +#ifdef CONFIG_WFD + if (padapter->wdinfo.wfd_tdls_enable == 1) + wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen)); +#endif + +} + +void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta; + u8 k; /* for random ANonce */ + u8 *pftie=NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL; + u32 time; + u8 *pframe_head; + + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst); + + if (ptdls_sta == NULL) + DBG_871X("[%s] %d ptdls_sta is NULL\n", __FUNCTION__, __LINE__); + + if (pattrib->encrypt && ptdls_sta != NULL) { + for (k=0;k<8;k++) { + time = rtw_get_current_time(); + _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4); + } + } + + pframe_head = pframe; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt); + + if (ptxmgmt->status_code != 0) { + DBG_871X("[%s] status_code:%04x \n", __FUNCTION__, ptxmgmt->status_code); + return; + } + + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_capability(padapter, pframe, pattrib); + pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib); + pframe = rtw_tdls_set_sup_ch(&(padapter->mlmeextpriv), pframe, pattrib); + pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib); + + if (pattrib->encrypt) { + prsnie = pframe; + pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _FALSE, ptdls_sta); + } + + pframe = rtw_tdls_set_ext_cap(pframe, pattrib); + + if (pattrib->encrypt) { + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) + wpa_tdls_generate_tpk(padapter, ptdls_sta); + + pftie = pframe; + pftie_mic = pframe+4; + pframe = rtw_tdls_set_ftie(ptxmgmt + , pframe + , pattrib + , ptdls_sta->ANonce + , ptdls_sta->SNonce); + + ptimeout_ie = pframe; + pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _FALSE, ptdls_sta); + } + +#ifdef CONFIG_80211N_HT + /* Sup_reg_classes(optional) */ + if (pregistrypriv->ht_enable == _TRUE) + pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib); +#endif + + pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib); + + plinkid_ie = pframe; + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + + /* Fill FTIE mic */ + if (pattrib->encrypt && rtw_tdls_is_driver_setup(padapter) == _TRUE) + wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic); + + if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE)) + pframe = rtw_tdls_set_qos_cap(pframe, pattrib); + +#ifdef CONFIG_80211AC_VHT + if ((padapter->mlmepriv.htpriv.ht_option == _TRUE) && (pregistrypriv->vht_enable != 0) && (pmlmeext->cur_channel > 14) + && (!padapter->mlmepriv.country_ent || COUNTRY_CHPLAN_EN_11AC(padapter->mlmepriv.country_ent)) + ) { + pframe = rtw_tdls_set_aid(padapter, pframe, pattrib); + pframe = rtw_tdls_set_vht_cap(padapter, pframe, pattrib); + pframe = rtw_tdls_set_vht_op_mode_notify(padapter, pframe, pattrib, pmlmeext->cur_bwmode); + } +#endif + +#ifdef CONFIG_WFD + if (padapter->wdinfo.wfd_tdls_enable) + wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen)); +#endif + +} + +void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst); + + unsigned int ie_len; + unsigned char *p; + u8 wmm_param_ele[24] = {0}; + u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + + if (ptxmgmt->status_code!=0) + return; + + if (pattrib->encrypt) { + prsnie = pframe; + pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta); + } + + if (pattrib->encrypt) { + pftie = pframe; + pftie_mic = pframe+4; + pframe = rtw_tdls_set_ftie(ptxmgmt + , pframe + , pattrib + , ptdls_sta->ANonce + , ptdls_sta->SNonce); + + ptimeout_ie = pframe; + pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta); + + if (rtw_tdls_is_driver_setup(padapter) == _TRUE) { + /* Start TPK timer */ + ptdls_sta->TPK_count=0; + _set_timer(&ptdls_sta->TPK_timer, ONE_SEC); + } + } + + /* HT operation; todo */ + + plinkid_ie = pframe; + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE)) + wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic); + + if (ptdls_sta->qos_option == _TRUE) + pframe = rtw_tdls_set_wmm_params(padapter, pframe, pattrib); + +#ifdef CONFIG_80211AC_VHT + if ((padapter->mlmepriv.htpriv.ht_option == _TRUE) && (pregistrypriv->vht_enable == _TRUE) + && (ptdls_sta->vhtpriv.vht_option == _TRUE) && (pmlmeext->cur_channel > 14) + && (!padapter->mlmepriv.country_ent || COUNTRY_CHPLAN_EN_11AC(padapter->mlmepriv.country_ent)) + ) { + pframe = rtw_tdls_set_vht_operation(padapter, pframe, pattrib, pmlmeext->cur_channel); + pframe = rtw_tdls_set_vht_op_mode_notify(padapter, pframe, pattrib, pmlmeext->cur_bwmode); + } +#endif +} + +void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst); + u8 *pftie = NULL, *pftie_mic = NULL, *plinkid_ie = NULL; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt); + + if (pattrib->encrypt) { + pftie = pframe; + pftie_mic = pframe + 4; + pframe = rtw_tdls_set_ftie(ptxmgmt + , pframe + , pattrib + , ptdls_sta->ANonce + , ptdls_sta->SNonce); + } + + plinkid_ie = pframe; + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE)) + wpa_tdls_teardown_ftie_mic(ptdls_sta->tpk.kck, plinkid_ie, ptxmgmt->status_code, 1, 4, pftie, pftie_mic); +} + +void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + +} + +void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, u8 privacy) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 *pframe_head, pktlen_index; + + pktlen_index = pattrib->pktlen; + pframe_head = pframe; + + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_PUBLIC); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_capability(padapter, pframe, pattrib); + + pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib); + + pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib); + + if (privacy) + pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, NULL); + + pframe = rtw_tdls_set_ext_cap(pframe, pattrib); + + if (privacy) { + pframe = rtw_tdls_set_ftie(ptxmgmt, pframe, pattrib, NULL, NULL); + pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, NULL); + } + +#ifdef CONFIG_80211N_HT + if (pregistrypriv->ht_enable == _TRUE) + pframe = rtw_tdls_set_ht_cap(padapter, pframe_head - pktlen_index, pattrib); +#endif + + pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib); + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + +} + + +void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 AC_queue=0; + struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst); + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + /* PTI control */ + /* PU buffer status */ + if (ptdls_sta->uapsd_bk & BIT(1)) + AC_queue=BIT(0); + if (ptdls_sta->uapsd_be & BIT(1)) + AC_queue=BIT(1); + if (ptdls_sta->uapsd_vi & BIT(1)) + AC_queue=BIT(2); + if (ptdls_sta->uapsd_vo & BIT(1)) + AC_queue=BIT(3); + pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen)); + +} + +void rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst); + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt); + + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); +} + +#ifdef CONFIG_TDLS_CH_SW +void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + u16 switch_time= CH_SWITCH_TIME * 1000, switch_timeout=CH_SWITCH_TIMEOUT * 1000; + + ptdls_sta->ch_switch_time=switch_time; + ptdls_sta->ch_switch_timeout=switch_timeout; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_target_ch(padapter, pframe, pattrib); + pframe = rtw_tdls_set_reg_class(pframe, pattrib, ptdls_sta); + + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta); + +} + +void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst); + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS); + pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt); + pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt); + + if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE); + else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) + pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE); + + pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta); +} +#endif + +#ifdef CONFIG_WFD +void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo; + u8 category = RTW_WLAN_CATEGORY_P2P; + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a}; + u8 probe_req = 4; + u8 wfdielen = 0; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen)); + + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { + wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } else if (!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) { + wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + +} + +void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe) +{ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo; + u8 category = RTW_WLAN_CATEGORY_P2P; + u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a}; + u8 probe_rsp = 5; + u8 wfdielen = 0; + + pframe = rtw_tdls_set_payload_type(pframe, pattrib); + pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen)); + + if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { + wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } else if (!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) { + wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1); + pframe += wfdielen; + pattrib->pktlen += wfdielen; + } + +} +#endif /* CONFIG_WFD */ + +void _tdls_tpk_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + struct tdls_txmgmt txmgmt; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + ptdls_sta->TPK_count++; + /* TPK_timer expired in a second */ + /* Retry timer should set at least 301 sec. */ + if (ptdls_sta->TPK_count >= ptdls_sta->TDLS_PeerKey_Lifetime) { + DBG_871X("[TDLS] %s, Re-Setup TDLS link with "MAC_FMT" since TPK lifetime expires!\n", __FUNCTION__, MAC_ARG(ptdls_sta->hwaddr)); + ptdls_sta->TPK_count=0; + _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN); + issue_tdls_setup_req(ptdls_sta->padapter, &txmgmt, _FALSE); + } + + _set_timer(&ptdls_sta->TPK_timer, ONE_SEC); +} + +#ifdef CONFIG_TDLS_CH_SW +void _tdls_ch_switch_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + + //DBG_871X("%s %d, tdls_sta_state:0x%08x\n", __FUNCTION__, __LINE__, ptdls_sta->tdls_sta_state); + + if (padapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(padapter)) { + if (!(pchsw_info->ch_sw_state & TDLS_PEER_AT_OFF_STATE)) { + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_BACK); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + DBG_871X("[TDLS] %s, can't get traffic from op_ch:%d\n", __FUNCTION__, rtw_get_oper_ch(padapter)); + } else { + //DBG_871X("%s %d\n", __FUNCTION__, __LINE__); + //_set_timer(&ptdls_sta->delay_timer, padapter->mlmeextpriv.mlmext_info.bcn_interval - 5 - ptdls_sta->ch_switch_timeout/1000); + } + } else { + //DBG_871X("%s %d, op_ch:%d, tdls_state:0x%08x\n", __FUNCTION__, __LINE__, rtw_get_oper_ch(padapter), ptdls_sta->tdls_sta_state); + } + +#if 0 + if (!(pchsw_info->ch_sw_state & TDLS_PEER_AT_OFF_STATE)) { + //SelectChannel(padapter, padapter->mlmeextpriv.cur_channel); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + DBG_871X("%s %d, op_ch:%d, tdls_state:0x%08x\n", __FUNCTION__, __LINE__, rtw_get_oper_ch(padapter), ptdls_sta->tdls_sta_state); + } + + if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) { + if (padapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(padapter)) { + DBG_871X("%s %d\n", __FUNCTION__, __LINE__); + _set_timer(&ptdls_sta->delay_timer, padapter->mlmeextpriv.mlmext_info.bcn_interval - 5 - ptdls_sta->ch_switch_timeout/1000); + //_set_timer(&ptdls_sta->delay_timer, 1000); + } else { + DBG_871X("%s %d\n", __FUNCTION__, __LINE__); + issue_tdls_ch_switch_req(padapter, ptdls_sta); + //_set_timer(&ptdls_sta->delay_timer, 500); + } + } +#endif +} + +void _tdls_delay_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + + DBG_871X("[TDLS] %s, op_ch:%d, tdls_state:0x%08x\n", __FUNCTION__, rtw_get_oper_ch(padapter), ptdls_sta->tdls_sta_state); + pchsw_info->delay_switch_back = _TRUE; +} +#endif + +void _tdls_handshake_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_txmgmt txmgmt; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN); + txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_; + + if (ptdls_sta != NULL) { + DBG_871X("[TDLS] Handshake time out\n"); + if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) + { + issue_tdls_teardown(padapter, &txmgmt, _TRUE); + } + else + { + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_TEAR_STA); + } + } +} + +void _tdls_pti_timer_hdl(void *FunctionContext) +{ + struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext; + _adapter *padapter = ptdls_sta->padapter; + struct tdls_txmgmt txmgmt; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN); + txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_; + + if (ptdls_sta != NULL) { + if (ptdls_sta->tdls_sta_state & TDLS_WAIT_PTR_STATE) { + DBG_871X("[TDLS] Doesn't receive PTR from peer dev:"MAC_FMT"; " + "Send TDLS Tear Down\n", MAC_ARG(ptdls_sta->hwaddr)); + issue_tdls_teardown(padapter, &txmgmt, _FALSE); + } + } +} + +void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta) +{ + psta->padapter=padapter; + _init_timer(&psta->TPK_timer, padapter->pnetdev, _tdls_tpk_timer_hdl, psta); +#ifdef CONFIG_TDLS_CH_SW + _init_timer(&psta->ch_sw_timer, padapter->pnetdev, _tdls_ch_switch_timer_hdl, psta); + _init_timer(&psta->delay_timer, padapter->pnetdev, _tdls_delay_timer_hdl, psta); +#endif + _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta); + _init_timer(&psta->pti_timer, padapter->pnetdev, _tdls_pti_timer_hdl, psta); +} + +void rtw_free_tdls_timer(struct sta_info *psta) +{ + _cancel_timer_ex(&psta->TPK_timer); +#ifdef CONFIG_TDLS_CH_SW + _cancel_timer_ex(&psta->ch_sw_timer); + _cancel_timer_ex(&psta->delay_timer); +#endif + _cancel_timer_ex(&psta->handshake_timer); + _cancel_timer_ex(&psta->pti_timer); +} + +u8 update_sgi_tdls(_adapter *padapter, struct sta_info *psta) +{ + return query_ra_short_GI(psta); +} + +u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta) +{ + unsigned char sta_band = 0; + unsigned int tx_ra_bitmap=0; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + + rtw_hal_update_sta_rate_mask(padapter, psta); + tx_ra_bitmap = psta->ra_mask; + + if (pcur_network->Configuration.DSConfig > 14) { + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_5N | WIRELESS_11A; + else + sta_band |= WIRELESS_11A; + } else { + if (tx_ra_bitmap & 0xffff000) + sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; + else if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11G |WIRELESS_11B; + else + sta_band |= WIRELESS_11B; + } + + psta->wireless_mode = sta_band; + + psta->raid = rtw_hal_networktype_to_raid(padapter,psta); + tx_ra_bitmap |= ((psta->raid<<28)&0xf0000000); + return tx_ra_bitmap; +} + +int rtw_tdls_is_driver_setup(_adapter *padapter) +{ + return padapter->tdlsinfo.driver_setup; +} + +const char * rtw_tdls_action_txt(enum TDLS_ACTION_FIELD action) +{ + switch (action) { + case TDLS_SETUP_REQUEST: + return "TDLS_SETUP_REQUEST"; + case TDLS_SETUP_RESPONSE: + return "TDLS_SETUP_RESPONSE"; + case TDLS_SETUP_CONFIRM: + return "TDLS_SETUP_CONFIRM"; + case TDLS_TEARDOWN: + return "TDLS_TEARDOWN"; + case TDLS_PEER_TRAFFIC_INDICATION: + return "TDLS_PEER_TRAFFIC_INDICATION"; + case TDLS_CHANNEL_SWITCH_REQUEST: + return "TDLS_CHANNEL_SWITCH_REQUEST"; + case TDLS_CHANNEL_SWITCH_RESPONSE: + return "TDLS_CHANNEL_SWITCH_RESPONSE"; + case TDLS_PEER_PSM_REQUEST: + return "TDLS_PEER_PSM_REQUEST"; + case TDLS_PEER_PSM_RESPONSE: + return "TDLS_PEER_PSM_RESPONSE"; + case TDLS_PEER_TRAFFIC_RESPONSE: + return "TDLS_PEER_TRAFFIC_RESPONSE"; + case TDLS_DISCOVERY_REQUEST: + return "TDLS_DISCOVERY_REQUEST"; + case TDLS_DISCOVERY_RESPONSE: + return "TDLS_DISCOVERY_RESPONSE"; + default: + return "UNKNOWN"; + } +} + +#endif /* CONFIG_TDLS */ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_vht.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_vht.c new file mode 100644 index 00000000..0bdc2a38 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_vht.c @@ -0,0 +1,803 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTW_VHT_C + +#include + +#ifdef CONFIG_80211AC_VHT +// 20/40/80, ShortGI, MCS Rate +const u16 VHT_MCS_DATA_RATE[3][2][30] = + { { {13, 26, 39, 52, 78, 104, 117, 130, 156, 156, + 26, 52, 78, 104, 156, 208, 234, 260, 312, 312, + 39, 78, 117, 156, 234, 312, 351, 390, 468, 520}, // Long GI, 20MHz + {14, 29, 43, 58, 87, 116, 130, 144, 173, 173, + 29, 58, 87, 116, 173, 231, 260, 289, 347, 347, + 43, 87, 130, 173, 260, 347,390, 433, 520, 578} }, // Short GI, 20MHz + { {27, 54, 81, 108, 162, 216, 243, 270, 324, 360, + 54, 108, 162, 216, 324, 432, 486, 540, 648, 720, + 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080}, // Long GI, 40MHz + {30, 60, 90, 120, 180, 240, 270, 300,360, 400, + 60, 120, 180, 240, 360, 480, 540, 600, 720, 800, + 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200}}, // Short GI, 40MHz + { {59, 117, 176, 234, 351, 468, 527, 585, 702, 780, + 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, + 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340}, /* Long GI, 80MHz */ + {65, 130, 195, 260, 390, 520, 585, 650, 780, 867, + 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560,1734, + 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600} } /* Short GI, 80MHz */ + }; + +u8 rtw_get_vht_highest_rate(u8 *pvht_mcs_map) +{ + u8 i, j; + u8 bit_map; + u8 vht_mcs_rate = 0; + + for(i = 0; i < 2; i++) + { + if(pvht_mcs_map[i] != 0xff) + { + for(j = 0; j < 8; j += 2) + { + bit_map = (pvht_mcs_map[i] >> j) & 3; + + if(bit_map != 3) + vht_mcs_rate = MGN_VHT1SS_MCS7 + 10*j/2 + i*40 + bit_map; //VHT rate indications begin from 0x90 + } + } + } + + /* DBG_871X("HighestVHTMCSRate is %x\n", vht_mcs_rate); */ + return vht_mcs_rate; +} + +u8 rtw_vht_mcsmap_to_nss(u8 *pvht_mcs_map) +{ + u8 i, j; + u8 bit_map; + u8 nss = 0; + + for(i = 0; i < 2; i++) + { + if(pvht_mcs_map[i] != 0xff) + { + for(j = 0; j < 8; j += 2) + { + bit_map = (pvht_mcs_map[i] >> j) & 3; + + if(bit_map != 3) + nss++; + } + } + } + + /* DBG_871X("%s : %dSS\n", __FUNCTION__, nss); */ + return nss; +} + +void rtw_vht_nss_to_mcsmap(u8 nss, u8 *target_mcs_map, u8 *cur_mcs_map) +{ + u8 i, j; + u8 cur_rate, target_rate; + + for(i = 0; i < 2; i++) + { + target_mcs_map[i] = 0; + for(j = 0; j < 8; j+=2) + { + cur_rate = (cur_mcs_map[i] >> j) & 3; + if(cur_rate == 3) //0x3 indicates not supported that num of SS + target_rate = 3; + else if(nss <= ((j/2)+i*4)) + target_rate = 3; + else + target_rate = cur_rate; + + target_mcs_map[i] |= (target_rate << j); + } + } + + //DBG_871X("%s : %dSS\n", __FUNCTION__, nss); +} + +u16 rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate) +{ + if(vht_mcs_rate > MGN_VHT3SS_MCS9) + vht_mcs_rate = MGN_VHT3SS_MCS9; + /* DBG_871X("bw=%d, short_GI=%d, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)=%d\n", bw, short_GI, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)); */ + return VHT_MCS_DATA_RATE[bw][short_GI][((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)]; +} + +void rtw_vht_use_default_setting(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE; + BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE; + u8 rf_type = 0; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + pvhtpriv->sgi_80m = TEST_FLAG(pregistrypriv->short_gi, BIT2) ? _TRUE : _FALSE; + + // LDPC support + rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport); + CLEAR_FLAGS(pvhtpriv->ldpc_cap); + if(bHwLDPCSupport) + { + if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT0)) + SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX); + } + rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport); + if(bHwLDPCSupport) + { + if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT1)) + SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX); + } + if (pvhtpriv->ldpc_cap) + DBG_871X("[VHT] Support LDPC = 0x%02X\n", pvhtpriv->ldpc_cap); + + // STBC + rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport); + CLEAR_FLAGS(pvhtpriv->stbc_cap); + if(bHwSTBCSupport) + { + if(TEST_FLAG(pregistrypriv->stbc_cap, BIT1)) + SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX); + } + rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport); + if(bHwSTBCSupport) + { + if(TEST_FLAG(pregistrypriv->stbc_cap, BIT0)) + SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX); + } + if (pvhtpriv->stbc_cap) + DBG_871X("[VHT] Support STBC = 0x%02X\n", pvhtpriv->stbc_cap); + + // Beamforming setting + rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer); + rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee); + CLEAR_FLAGS(pvhtpriv->beamform_cap); + if (TEST_FLAG(pregistrypriv->beamform_cap, BIT0) && bHwSupportBeamformer) { + #ifdef CONFIG_CONCURRENT_MODE + if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { + SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE); + DBG_871X("[VHT] CONCURRENT AP Support Beamformer\n"); + } else + DBG_871X("[VHT] CONCURRENT not AP ;not allow Support Beamformer\n"); + #else + SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE); + DBG_871X("[VHT] Support Beamformer\n"); + #endif + } + if(TEST_FLAG(pregistrypriv->beamform_cap, BIT1) && bHwSupportBeamformee) + { + SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE); + DBG_871X("[VHT] Support Beamformee\n"); + } + + pvhtpriv->ampdu_len = pregistrypriv->ampdu_factor; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + if (rf_type == RF_3T3R) + pvhtpriv->vht_mcs_map[0] = 0xea; /* support 1SS MCS 0~9 2SS MCS 0~9 3SS MCS 0~9 */ + else if(rf_type == RF_2T2R) + pvhtpriv->vht_mcs_map[0] = 0xfa; /* support 1SS MCS 0~9 2SS MCS 0~9 */ + else + pvhtpriv->vht_mcs_map[0] = 0xfe; /* Only support 1SS MCS 0~9; */ + pvhtpriv->vht_mcs_map[1] = 0xff; + + if(pregistrypriv->vht_rate_sel == 1) + { + pvhtpriv->vht_mcs_map[0] = 0xfc; // support 1SS MCS 0~7 + } + else if(pregistrypriv->vht_rate_sel == 2) + { + pvhtpriv->vht_mcs_map[0] = 0xfd; // Support 1SS MCS 0~8 + } + else if(pregistrypriv->vht_rate_sel == 3) + { + pvhtpriv->vht_mcs_map[0] = 0xfe; // Support 1SS MCS 0~9 + } + else if(pregistrypriv->vht_rate_sel == 4) + { + pvhtpriv->vht_mcs_map[0] = 0xf0; // support 1SS MCS 0~7 2SS MCS 0~7 + } + else if(pregistrypriv->vht_rate_sel == 5) + { + pvhtpriv->vht_mcs_map[0] = 0xf5; // support 1SS MCS 0~8 2SS MCS 0~8 + } + else if(pregistrypriv->vht_rate_sel == 6) + { + pvhtpriv->vht_mcs_map[0] = 0xfa; // support 1SS MCS 0~9 2SS MCS 0~9 + } + else if(pregistrypriv->vht_rate_sel == 7) + { + pvhtpriv->vht_mcs_map[0] = 0xf8; // support 1SS MCS 0-7 2SS MCS 0~9 + } + else if(pregistrypriv->vht_rate_sel == 8) + { + pvhtpriv->vht_mcs_map[0] = 0xf9; // support 1SS MCS 0-8 2SS MCS 0~9 + } + else if(pregistrypriv->vht_rate_sel == 9) + { + pvhtpriv->vht_mcs_map[0] = 0xf4; // support 1SS MCS 0-7 2SS MCS 0~8 + } + + pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map); +} + +u64 rtw_vht_rate_to_bitmap(u8 *pVHTRate) +{ + + u8 i,j , tmpRate; + u64 RateBitmap = 0; + u8 Bits_3ss = 6; + + for(i = j= 0; i < Bits_3ss; i+=2, j+=10) + { + /* every two bits means single sptial stream */ + tmpRate = (pVHTRate[0] >> i) & 3; + + switch(tmpRate){ + case 2: + RateBitmap = RateBitmap | (0x03ff << j); + break; + case 1: + RateBitmap = RateBitmap | (0x01ff << j); + break; + + case 0: + RateBitmap = RateBitmap | (0x00ff << j); + break; + + default: + break; + } + } + DBG_871X("RateBitmap=%016llx , pVHTRate[0]=%02x, pVHTRate[1]=%02x\n", RateBitmap, pVHTRate[0], pVHTRate[1]); + return RateBitmap; +} + +void update_sta_vht_info_apmode(_adapter *padapter, PVOID sta) +{ + struct sta_info *psta = (struct sta_info *)sta; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct vht_priv *pvhtpriv_ap = &pmlmepriv->vhtpriv; + struct vht_priv *pvhtpriv_sta = &psta->vhtpriv; + struct ht_priv *phtpriv_sta = &psta->htpriv; + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, bw_mode = 0; + u16 cur_beamform_cap = 0; + u8 *pcap_mcs; + + if (pvhtpriv_sta->vht_option == _FALSE) { + return; + } + + bw_mode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&pvhtpriv_sta->vht_op_mode_notify); + + //if (bw_mode > psta->bw_mode) + psta->bw_mode = bw_mode; + + // B4 Rx LDPC + if (TEST_FLAG(pvhtpriv_ap->ldpc_cap, LDPC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_LDPC(pvhtpriv_sta->vht_cap)) + { + SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX)); + DBG_871X("Current STA(%d) VHT LDPC = %02X\n", psta->aid, cur_ldpc_cap); + } + pvhtpriv_sta->ldpc_cap = cur_ldpc_cap; + + if (psta->bw_mode > pmlmeext->cur_bwmode) + psta->bw_mode = pmlmeext->cur_bwmode; + + if (psta->bw_mode == CHANNEL_WIDTH_80) { + // B5 Short GI for 80 MHz + pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE; + //DBG_871X("Current STA ShortGI80MHz = %d\n", pvhtpriv_sta->sgi_80m); + } else if (psta->bw_mode >= CHANNEL_WIDTH_160) { + // B5 Short GI for 80 MHz + pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE; + //DBG_871X("Current STA ShortGI160MHz = %d\n", pvhtpriv_sta->sgi_80m); + } + + // B8 B9 B10 Rx STBC + if (TEST_FLAG(pvhtpriv_ap->stbc_cap, STBC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_STBC(pvhtpriv_sta->vht_cap)) + { + SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX)); + DBG_871X("Current STA(%d) VHT STBC = %02X\n", psta->aid, cur_stbc_cap); + } + pvhtpriv_sta->stbc_cap = cur_stbc_cap; + +#ifdef CONFIG_BEAMFORMING + // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee + if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFEE(pvhtpriv_sta->vht_cap)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE); + /*Shift to BEAMFORMING_VHT_BEAMFORMER_STS_CAP*/ + SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFEE_STS_CAP(pvhtpriv_sta->vht_cap)<<8); + } + + // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer + if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFER(pvhtpriv_sta->vht_cap)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE); + /*Shit to BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM*/ + SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(pvhtpriv_sta->vht_cap)<<12); + } + pvhtpriv_sta->beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) { + DBG_871X("Current STA(%d) VHT Beamforming Setting = %02X\n", psta->aid, cur_beamform_cap); + } + #endif + + // B23 B24 B25 Maximum A-MPDU Length Exponent + pvhtpriv_sta->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pvhtpriv_sta->vht_cap); + + pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pvhtpriv_sta->vht_cap); + _rtw_memcpy(pvhtpriv_sta->vht_mcs_map, pcap_mcs, 2); + + pvhtpriv_sta->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv_sta->vht_mcs_map); + +} + +void update_hw_vht_param(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 ht_AMPDU_len; + + ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + if(pvhtpriv->ampdu_len > ht_AMPDU_len) + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len)); +} + +void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, rf_type = RF_1T1R; + u16 cur_beamform_cap = 0; + u8 *pcap_mcs; + u8 vht_mcs[2]; + + if(pIE==NULL) return; + + if(pvhtpriv->vht_option == _FALSE) return; + + pmlmeinfo->VHT_enable = 1; + + // B4 Rx LDPC + if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_LDPC(pIE->data)) + { + SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX)); + DBG_871X("Current VHT LDPC Setting = %02X\n", cur_ldpc_cap); + } + pvhtpriv->ldpc_cap = cur_ldpc_cap; + + // B5 Short GI for 80 MHz + pvhtpriv->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pIE->data) & pvhtpriv->sgi_80m) ? _TRUE : _FALSE; + //DBG_871X("Current ShortGI80MHz = %d\n", pvhtpriv->sgi_80m); + + // B8 B9 B10 Rx STBC + if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) && + GET_VHT_CAPABILITY_ELE_RX_STBC(pIE->data)) + { + SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX)); + DBG_871X("Current VHT STBC Setting = %02X\n", cur_stbc_cap); + } + pvhtpriv->stbc_cap = cur_stbc_cap; +#ifdef CONFIG_BEAMFORMING + // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFEE(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE); + /*Shift to BEAMFORMING_VHT_BEAMFORMER_STS_CAP*/ + SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFEE_STS_CAP(pIE->data)<<8); + } + + // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) && + GET_VHT_CAPABILITY_ELE_SU_BFER(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE); + /*Shit to BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM*/ + SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(pIE->data)<<12); + + } + pvhtpriv->beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) { + DBG_871X("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap); + } + #endif + // B23 B24 B25 Maximum A-MPDU Length Exponent + pvhtpriv->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pIE->data); + + pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pIE->data); + _rtw_memcpy(vht_mcs, pcap_mcs, 2); + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R)) + vht_mcs[0] |= 0xfc; + else if (rf_type == RF_2T2R) + vht_mcs[0] |= 0xf0; + else if (rf_type == RF_3T3R) + vht_mcs[0] |= 0xc0; + + _rtw_memcpy(pvhtpriv->vht_mcs_map, vht_mcs, 2); + + pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map); +} + +void VHT_operation_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + + if(pIE==NULL) return; + + if(pvhtpriv->vht_option == _FALSE) return; +} + +void rtw_process_vht_op_mode_notify(_adapter *padapter, u8 *pframe, PVOID sta) +{ + struct sta_info *psta = (struct sta_info *)sta; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct registry_priv *regsty = adapter_to_regsty(padapter); + u8 target_bw; + u8 target_rxss, current_rxss; + u8 update_ra = _FALSE; + u8 vht_mcs_map[2] = {}; + + if(pvhtpriv->vht_option == _FALSE) + return; + + target_bw = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(pframe); + target_rxss = (GET_VHT_OPERATING_MODE_FIELD_RX_NSS(pframe)+1); + + if (target_bw != psta->bw_mode) { + if (hal_is_bw_support(padapter, target_bw) + && REGSTY_IS_BW_5G_SUPPORT(regsty, target_bw) + ) { + update_ra = _TRUE; + psta->bw_mode = target_bw; + } + } + + current_rxss = rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map); + if (target_rxss != current_rxss) { + update_ra = _TRUE; + + rtw_vht_nss_to_mcsmap(target_rxss, vht_mcs_map, psta->vhtpriv.vht_mcs_map); + _rtw_memcpy(psta->vhtpriv.vht_mcs_map, vht_mcs_map, 2); + + rtw_hal_update_sta_rate_mask(padapter, psta); + } + + if (update_ra) { + rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta); + } +} + +u32 rtw_build_vht_operation_ie(_adapter *padapter, u8 *pbuf, u8 channel) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + //struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u8 ChnlWidth, center_freq, bw_mode, rf_type = 0; + u32 len = 0; + u8 operation[5]; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + _rtw_memset(operation, 0, 5); + + bw_mode = REGSTY_BW_5G(pregistrypriv); /* TODO: control op bw with other info */ + + if (hal_chk_bw_cap(padapter, BW_CAP_80M | BW_CAP_160M) + && REGSTY_BW_5G(pregistrypriv) >= CHANNEL_WIDTH_80 + ) { + center_freq = rtw_get_center_ch(channel, bw_mode, HAL_PRIME_CHNL_OFFSET_LOWER); + ChnlWidth = 1; + } else { + center_freq = 0; + ChnlWidth = 0; + } + + + SET_VHT_OPERATION_ELE_CHL_WIDTH(operation, ChnlWidth); + //center frequency + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(operation, center_freq);//Todo: need to set correct center channel + SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(operation,0); + + if (padapter->registrypriv.rf_config != RF_MAX_TYPE) + rf_type = padapter->registrypriv.rf_config; + + switch (rf_type) { + case RF_1T1R: + operation[3] = 0xfe; + operation[4] = 0xff; + break; + case RF_1T2R: + case RF_2T2R: + case RF_2T2R_GREEN: + operation[3] = 0xfa; + operation[4] = 0xff; + break; + case RF_2T3R: + case RF_2T4R: + case RF_3T3R: + case RF_3T4R: + operation[3] = 0xea; + operation[4] = 0xff; + break; + case RF_4T4R: + operation[3] = 0xaa; + operation[4] = 0xff; + break; + default: + DBG_871X("%s, %d, unknown rf type\n", __func__, __LINE__); + } + + rtw_set_ie(pbuf, EID_VHTOperation, 5, operation, &len); + + return len; +} + +u32 rtw_build_vht_op_mode_notify_ie(_adapter *padapter, u8 *pbuf, u8 bw) +{ + //struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + u32 len = 0; + u8 opmode = 0, rf_type = 0; + u8 chnl_width, rx_nss; + + chnl_width = bw; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if(rf_type == RF_3T3R) + rx_nss = 3; + else if(rf_type == RF_2T2R) + rx_nss = 2; + else + rx_nss = 1; + + SET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&opmode, chnl_width); + SET_VHT_OPERATING_MODE_FIELD_RX_NSS(&opmode, (rx_nss-1)); + SET_VHT_OPERATING_MODE_FIELD_RX_NSS_TYPE(&opmode, 0); //Todo + + pvhtpriv->vht_op_mode_notify = opmode; + + pbuf = rtw_set_ie(pbuf, EID_OpModeNotification, 1, &opmode, &len); + + return len; +} + +u32 rtw_build_vht_cap_ie(_adapter *padapter, u8 *pbuf) +{ + u8 bw, rf_type, rf_num, rx_stbc_nss = 0; + u16 HighestRate; + u8 *pcap, *pcap_mcs; + u32 len = 0; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + + pcap = pvhtpriv->vht_cap; + _rtw_memset(pcap, 0, 32); + + /* B0 B1 Maximum MPDU Length */ + SET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pcap, 2); + + /* B2 B3 Supported Channel Width Set */ + if (hal_chk_bw_cap(padapter, BW_CAP_160M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_160)) { + if (hal_chk_bw_cap(padapter, BW_CAP_80_80M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_80_80)) + SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 2); + else + SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 1); + } else { + SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 0); + } + + // B4 Rx LDPC + if(TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX)) + { + SET_VHT_CAPABILITY_ELE_RX_LDPC(pcap, 1); + } + + // B5 ShortGI for 80MHz + SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pcap, pvhtpriv->sgi_80m? 1 : 0); // We can receive Short GI of 80M + + // B6 ShortGI for 160MHz + //SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pcap, pvhtpriv->sgi_80m? 1 : 0); + + // B7 Tx STBC + if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX)) + { + SET_VHT_CAPABILITY_ELE_TX_STBC(pcap, 1); + } + + // B8 B9 B10 Rx STBC + if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX)) + { + rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss)); + + SET_VHT_CAPABILITY_ELE_RX_STBC(pcap, rx_stbc_nss); + } + + // B11 SU Beamformer Capable + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + SET_VHT_CAPABILITY_ELE_SU_BFER(pcap, 1); + // B16 17 18 Number of Sounding Dimensions + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num); + SET_VHT_CAPABILITY_ELE_SOUNDING_DIMENSIONS(pcap, rf_num); + } + + // B12 SU Beamformee Capable + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { + SET_VHT_CAPABILITY_ELE_SU_BFEE(pcap, 1); + // B13 14 15 Compressed Steering Number of Beamformer Antennas Supported + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num); + SET_VHT_CAPABILITY_ELE_BFER_ANT_SUPP(pcap, rf_num); + } + + // B19 MU Beamformer Capable + SET_VHT_CAPABILITY_ELE_MU_BFER(pcap, 0); //HW don't support mu bfee/bfer + // B20 MU Beamformee Capable + SET_VHT_CAPABILITY_ELE_MU_BFEE(pcap, 0); + // B21 VHT TXOP PS + SET_VHT_CAPABILITY_ELE_TXOP_PS(pcap, 0); + // B22 +HTC-VHT Capable + SET_VHT_CAPABILITY_ELE_HTC_VHT(pcap, 1); + // B23 24 25 Maximum A-MPDU Length Exponent + if (pregistrypriv->ampdu_factor != 0xFE) + { + SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, pregistrypriv->ampdu_factor); + } + else + { + SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, 7); + } + // B26 27 VHT Link Adaptation Capable + SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(pcap, 0); + + pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pcap); + _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2); + + pcap_mcs = GET_VHT_CAPABILITY_ELE_TX_MCS(pcap); + _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2); + + /* find the largest bw supported by both registry and hal */ + bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv)); + + HighestRate = VHT_MCS_DATA_RATE[bw][pvhtpriv->sgi_80m][((pvhtpriv->vht_highest_rate - MGN_VHT1SS_MCS0)&0x3f)]; + HighestRate = (HighestRate+1) >> 1; + + SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest rx rate is 600Mbps. + SET_VHT_CAPABILITY_ELE_MCS_TX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest tx rate is 600Mbps. + + pbuf = rtw_set_ie(pbuf, EID_VHTCapability, 12, pcap, &len); + + return len; +} + +u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len) +{ + u32 ielen=0, out_len=0; + u8 cap_len=0, notify_len=0, notify_bw=0, operation_bw=0, supported_chnl_width=0; + u8 *p, *pframe; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + + rtw_vht_use_default_setting(padapter); + + p = rtw_get_ie(in_ie+12, EID_VHTCapability, &ielen, in_len-12); + if (p && ielen>0) { + supported_chnl_width = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2); + + // VHT Capabilities element + cap_len = rtw_build_vht_cap_ie(padapter, out_ie+*pout_len); + *pout_len += cap_len; + + // Get HT BW + p = rtw_get_ie(in_ie+12, _HT_EXTRA_INFO_IE_, &ielen, in_len-12); + if (p && ielen>0) { + struct HT_info_element *pht_info = (struct HT_info_element *)(p+2); + if (pht_info->infos[0] & BIT(2)) + operation_bw = CHANNEL_WIDTH_40; + else + operation_bw = CHANNEL_WIDTH_20; + } + + // VHT Operation element + p = rtw_get_ie(in_ie+12, EID_VHTOperation, &ielen, in_len-12); + if (p && ielen>0) { + out_len = *pout_len; + if (GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) { + if (supported_chnl_width == 2) + operation_bw = CHANNEL_WIDTH_80_80; + else if (supported_chnl_width == 1) + operation_bw = CHANNEL_WIDTH_160; + else + operation_bw = CHANNEL_WIDTH_80; + } + pframe = rtw_set_ie(out_ie+out_len, EID_VHTOperation, ielen, p+2 , pout_len); + } + + /* find the largest bw supported by both registry and hal */ + notify_bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv)); + + if (notify_bw > operation_bw) + notify_bw = operation_bw; + + // Operating Mode Notification element + notify_len = rtw_build_vht_op_mode_notify_ie(padapter, out_ie+*pout_len, notify_bw); + *pout_len += notify_len; + + pvhtpriv->vht_option = _TRUE; + } + + return (pvhtpriv->vht_option); + +} + +void VHTOnAssocRsp(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 ht_AMPDU_len; + + DBG_871X("%s\n", __FUNCTION__); + + if (!pmlmeinfo->HT_enable) + return; + + if (!pmlmeinfo->VHT_enable) + return; + + ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + if(pvhtpriv->ampdu_len > ht_AMPDU_len) + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len)); + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate)); +} + +#endif //CONFIG_80211AC_VHT + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi.c new file mode 100644 index 00000000..d4835daa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi.c @@ -0,0 +1,1326 @@ +#ifdef CONFIG_WAPI_SUPPORT + +#include +#include +#include +#include + + +u32 wapi_debug_component = +// WAPI_INIT | +// WAPI_API | +// WAPI_TX | +// WAPI_RX | + WAPI_ERR ; //always open err flags on + +void WapiFreeAllStaInfo(_adapter *padapter) +{ + PRT_WAPI_T pWapiInfo; + PRT_WAPI_STA_INFO pWapiStaInfo; + PRT_WAPI_BKID pWapiBkid; + + WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__); + pWapiInfo = &padapter->wapiInfo; + + //Pust to Idle List + rtw_wapi_return_all_sta_info(padapter); + + //Sta Info List + while(!list_empty(&(pWapiInfo->wapiSTAIdleList))) + { + pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list); + list_del_init(&pWapiStaInfo->list); + } + + //BKID List + while(!list_empty(&(pWapiInfo->wapiBKIDIdleList))) + { + pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list); + list_del_init(&pWapiBkid->list); + } + WAPI_TRACE(WAPI_INIT, "<=========== %s\n", __FUNCTION__); + return; +} + +void WapiSetIE(_adapter *padapter) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + //PRT_WAPI_BKID pWapiBkid; + u16 protocolVer = 1; + u16 akmCnt = 1; + u16 suiteCnt = 1; + u16 capability = 0; + u8 OUI[3]; + + OUI[0] = 0x00; + OUI[1] = 0x14; + OUI[2] = 0x72; + + pWapiInfo->wapiIELength = 0; +//protocol version + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &protocolVer, 2); + pWapiInfo->wapiIELength +=2; +//akm + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &akmCnt, 2); + pWapiInfo->wapiIELength +=2; + + if(pWapiInfo->bWapiPSK){ + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3); + pWapiInfo->wapiIELength +=3; + pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x2; + pWapiInfo->wapiIELength +=1; + }else{ + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3); + pWapiInfo->wapiIELength +=3; + pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1; + pWapiInfo->wapiIELength +=1; + } + +//usk + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &suiteCnt, 2); + pWapiInfo->wapiIELength +=2; + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3); + pWapiInfo->wapiIELength +=3; + pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1; + pWapiInfo->wapiIELength +=1; + +//msk + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3); + pWapiInfo->wapiIELength +=3; + pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1; + pWapiInfo->wapiIELength +=1; + +//Capbility + memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &capability, 2); + pWapiInfo->wapiIELength +=2; +} + + +/* PN1 > PN2, return 1, + * else return 0. + */ +u32 WapiComparePN(u8 *PN1, u8 *PN2) +{ + char i; + + if ((NULL == PN1) || (NULL == PN2)) + return 1; + + // overflow case + if ((PN2[15] - PN1[15]) & 0x80) + return 1; + + for (i=16; i>0; i--) + { + if(PN1[i-1] == PN2[i-1]) + continue; + else if(PN1[i-1] > PN2[i-1]) + return 1; + else + return 0; + } + + return 0; +} + +u8 +WapiGetEntryForCamWrite(_adapter *padapter,u8 *pMacAddr,u8 KID,BOOLEAN IsMsk) +{ + PRT_WAPI_T pWapiInfo=NULL; + //PRT_WAPI_CAM_ENTRY pEntry=NULL; + u8 i=0; + u8 ret = 0xff; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + pWapiInfo = &padapter->wapiInfo; + + //exist? + for(i=0;iwapiCamEntry[i].IsUsed + && (_rtw_memcmp(pMacAddr, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE) + && pWapiInfo->wapiCamEntry[i].keyidx == KID + && pWapiInfo->wapiCamEntry[i].type == IsMsk) + { + ret = pWapiInfo->wapiCamEntry[i].entry_idx; //cover it + break; + } + } + + if(i == WAPI_CAM_ENTRY_NUM) //not found + { + for(i=0;iwapiCamEntry[i].IsUsed == 0) + { + pWapiInfo->wapiCamEntry[i].IsUsed = 1; + pWapiInfo->wapiCamEntry[i].type = IsMsk; + pWapiInfo->wapiCamEntry[i].keyidx = KID; + _rtw_memcpy(pWapiInfo->wapiCamEntry[i].PeerMacAddr, pMacAddr,ETH_ALEN); + ret = pWapiInfo->wapiCamEntry[i].entry_idx; + break; + } + } + } + + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); + return ret; + +/* + if(RTIsListEmpty(&pWapiInfo->wapiCamIdleList)){ + RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n")); + return 0; + } + + pEntry = (PRT_WAPI_CAM_ENTRY)RTRemoveHeadList(&pWapiInfo->wapiCamIdleList); + RTInsertTailList(&pWapiInfo->wapiCamUsedList, &pEntry->list); + + RT_TRACE(COMP_SEC,DBG_LOUD,("<====WapiGetCamEntry(),Get Entry Idx:%d.but we just return 4 for test\n",pEntry->entry_idx)); + + return pEntry->entry_idx;*/ +} + +u8 WapiGetEntryForCamClear(_adapter *padapter,u8 *pPeerMac,u8 keyid,u8 IsMsk) +{ + PRT_WAPI_T pWapiInfo=NULL; + u8 i=0; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + pWapiInfo = &padapter->wapiInfo; + + for(i=0;iwapiCamEntry[i].IsUsed + && (_rtw_memcmp(pPeerMac, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE) + && pWapiInfo->wapiCamEntry[i].keyidx == keyid + && pWapiInfo->wapiCamEntry[i].type == IsMsk) + { + pWapiInfo->wapiCamEntry[i].IsUsed = 0; + pWapiInfo->wapiCamEntry[i].keyidx = 2; + _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr,0,ETH_ALEN); + + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); + return pWapiInfo->wapiCamEntry[i].entry_idx; + } + } + + WAPI_TRACE(WAPI_API,"<====WapiGetReturnCamEntry(), No this cam entry.\n"); + return 0xff; +/* + if(RTIsListEmpty(&pWapiInfo->wapiCamUsedList)){ + RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n")); + return FALSE; + } + + pList = &pWapiInfo->wapiCamUsedList; + while(pList->Flink != &pWapiInfo->wapiCamUsedList) + { + pEntry = (PRT_WAPI_CAM_ENTRY)pList->Flink; + if(PlatformCompareMemory(pPeerMac,pEntry->PeerMacAddr, ETHER_ADDRLEN)== 0 + && keyid == pEntry->keyidx) + { + RTRemoveEntryList(pList); + RTInsertHeadList(&pWapiInfo->wapiCamIdleList, pList); + return pEntry->entry_idx; + } + pList = pList->Flink; + } + + return 0; +*/ +} + +void +WapiResetAllCamEntry(_adapter *padapter) +{ + PRT_WAPI_T pWapiInfo; + int i; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + pWapiInfo = &padapter->wapiInfo; + + for (i=0;iwapiCamEntry[i].PeerMacAddr, 0, ETH_ALEN); + pWapiInfo->wapiCamEntry[i].IsUsed = 0; + pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid + pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2; + } + + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); + + return; +} + +u8 WapiWriteOneCamEntry( + _adapter *padapter, + u8 *pMacAddr, + u8 KeyId, + u8 EntryId, + u8 EncAlg, + u8 bGroupKey, + u8 *pKey +) +{ + u8 retVal = 0; + u16 usConfig = 0; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + if(EntryId >= 32) + { + WAPI_TRACE(WAPI_ERR, "<=== CamAddOneEntry(): ulKeyId exceed!\n"); + return retVal; + } + + usConfig=usConfig|(0x01<<15)|((u16)(EncAlg)<<2)|(KeyId); + + if(EncAlg == _SMS4_ ) + { + if(bGroupKey == 1) + usConfig |= (0x01<<6); + if((EntryId % 2)==1) // ==0 sec key; == 1mic key + usConfig |= (0x01<<5); + } + + write_cam(padapter, EntryId, usConfig, pMacAddr, pKey); + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + return 1; +} + +void rtw_wapi_init(_adapter *padapter) +{ + PRT_WAPI_T pWapiInfo; + int i; + + WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__); + RT_ASSERT_RET(padapter); + + if (!padapter->WapiSupport) + { + WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + pWapiInfo = &padapter->wapiInfo; + pWapiInfo->bWapiEnable = false; + + //Init BKID List + INIT_LIST_HEAD(&pWapiInfo->wapiBKIDIdleList); + INIT_LIST_HEAD(&pWapiInfo->wapiBKIDStoreList); + for(i=0;iwapiBKID[i].list, &pWapiInfo->wapiBKIDIdleList); + } + + //Init STA List + INIT_LIST_HEAD(&pWapiInfo->wapiSTAIdleList); + INIT_LIST_HEAD(&pWapiInfo->wapiSTAUsedList); + for(i=0;iwapiSta[i].list, &pWapiInfo->wapiSTAIdleList); + } + + for (i=0;iwapiCamEntry[i].IsUsed = 0; + pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid + pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2; + } + + WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__); +} + +void rtw_wapi_free(_adapter *padapter) +{ + WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__); + RT_ASSERT_RET(padapter); + + if (!padapter->WapiSupport) + { + WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + WapiFreeAllStaInfo(padapter); + + WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__); +} + +void rtw_wapi_disable_tx(_adapter *padapter) +{ + WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__); + RT_ASSERT_RET(padapter); + + if (!padapter->WapiSupport) + { + WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + padapter->wapiInfo.wapiTxMsk.bTxEnable = false; + padapter->wapiInfo.wapiTxMsk.bSet = false; + + WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__); +} + +u8 rtw_wapi_is_wai_packet(_adapter* padapter,u8 *pkt_data) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + PRT_WAPI_STA_INFO pWapiSta = NULL; + u8 WaiPkt = 0, *pTaddr, bFind = false; + u8 Offset_TypeWAI = 0 ; // (mac header len + llc length) + + WAPI_TRACE(WAPI_TX|WAPI_RX, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return 0; + } + + Offset_TypeWAI = 24 + 6 ; + + //YJ,add,091103. Data frame may also have skb->data[30]=0x88 and skb->data[31]=0xb4. + if ((pkt_data[1]&0x40) !=0) + { + //DBG_871X("data is privacy \n"); + return 0; + } + + pTaddr = GetAddr2Ptr(pkt_data); + if(list_empty(&pWapiInfo->wapiSTAUsedList)){ + bFind = false; + }else{ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){ + if (_rtw_memcmp(pTaddr, pWapiSta->PeerMacAddr, 6) == _TRUE) { + bFind = true; + break; + } + } + } + + WAPI_TRACE(WAPI_TX|WAPI_RX, "%s: bFind=%d pTaddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(pTaddr)); + + if (pkt_data[0] == WIFI_QOS_DATA_TYPE) + { + Offset_TypeWAI += 2; + } + + // 88b4? + if( (pkt_data[Offset_TypeWAI]==0x88) && (pkt_data[Offset_TypeWAI+1]==0xb4) ){ + WaiPkt = pkt_data[Offset_TypeWAI+5]; + + psecuritypriv->hw_decrypted = _TRUE; + }else{ + WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): non wai packet\n",__FUNCTION__); + } + + WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): Recvd WAI frame. IsWAIPkt(%d)\n",__FUNCTION__, WaiPkt); + + return WaiPkt; +} + + +void rtw_wapi_update_info(_adapter *padapter, union recv_frame *precv_frame) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + struct recv_frame_hdr *precv_hdr; + u8 *ptr; + u8 *pTA; + u8 *pRecvPN; + + + WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + precv_hdr = &precv_frame->u.hdr; + ptr = precv_hdr->rx_data; + + if (precv_hdr->attrib.qos == 1) + { + precv_hdr->UserPriority = GetTid(ptr); + } + else + { + precv_hdr->UserPriority = 0; + } + + pTA = GetAddr2Ptr(ptr); + _rtw_memcpy((u8 *)precv_hdr->WapiSrcAddr, pTA, 6); + pRecvPN = ptr + precv_hdr->attrib.hdrlen + 2; + _rtw_memcpy((u8 *)precv_hdr->WapiTempPN, pRecvPN, 16); + + WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__); +} + +/**************************************************************************** +TRUE-----------------Drop +FALSE---------------- handle +add to support WAPI to N-mode +*****************************************************************************/ +u8 rtw_wapi_check_for_drop( + _adapter *padapter, + union recv_frame *precv_frame +) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + u8 *pLastRecvPN = NULL; + u8 bFind = false; + PRT_WAPI_STA_INFO pWapiSta = NULL; + u8 bDrop = false; + struct recv_frame_hdr *precv_hdr = &precv_frame->u.hdr; + u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 *ptr = precv_frame->u.hdr.rx_data; + int i; + + WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return false; + } + + if(precv_hdr->bIsWaiPacket !=0) + { + if(precv_hdr->bIsWaiPacket== 0x8) + { + + DBG_871X("rtw_wapi_check_for_drop: dump packet \n"); + for(i=0;i<50;i++) + { + DBG_871X("%02X ",ptr[i]); + if((i+1) %8 ==0) + DBG_871X("\n"); + } + DBG_871X("\n rtw_wapi_check_for_drop: dump packet \n"); + + for(i=0;i<16;i++) + { + if(ptr[i+27] !=0) + break; + } + + if(i== 16) + { + WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: drop with zero BKID \n"); + return true; + } + else + { + return false; + } + } + else + return false; + } + + if(list_empty(&pWapiInfo->wapiSTAUsedList)){ + bFind = false; + }else{ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if (_rtw_memcmp(precv_hdr->WapiSrcAddr, pWapiSta->PeerMacAddr, ETH_ALEN) == _TRUE) { + bFind = true; + break; + } + } + } + WAPI_TRACE(WAPI_RX, "%s: bFind=%d prxb->WapiSrcAddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(precv_hdr->WapiSrcAddr)); + + if(bFind) + { + if(IS_MCAST(precv_hdr->attrib.ra)) + { + WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: multicast case \n"); + pLastRecvPN = pWapiSta->lastRxMulticastPN; + } + else + { + WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: unicast case \n"); + switch(precv_hdr->UserPriority) + { + case 0: + case 3: + pLastRecvPN = pWapiSta->lastRxUnicastPNBEQueue; + break; + case 1: + case 2: + pLastRecvPN = pWapiSta->lastRxUnicastPNBKQueue; + break; + case 4: + case 5: + pLastRecvPN = pWapiSta->lastRxUnicastPNVIQueue; + break; + case 6: + case 7: + pLastRecvPN = pWapiSta->lastRxUnicastPNVOQueue; + break; + default: + WAPI_TRACE(WAPI_ERR,"%s: Unknown TID \n",__FUNCTION__); + break; + } + } + + if(!WapiComparePN(precv_hdr->WapiTempPN,pLastRecvPN)) + { + WAPI_TRACE(WAPI_RX,"%s: Equal PN!!\n",__FUNCTION__); + if(IS_MCAST(precv_hdr->attrib.ra)) + _rtw_memcpy(pLastRecvPN,WapiAEMultiCastPNInitialValueSrc,16); + else + _rtw_memcpy(pLastRecvPN,WapiAEPNInitialValueSrc,16); + bDrop = true; + } + else + { + _rtw_memcpy(pLastRecvPN,precv_hdr->WapiTempPN,16); + } + } + + WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__); + return bDrop; +} + +void rtw_build_probe_resp_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + u8 WapiIELength = 0; + + WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + WapiSetIE(padapter); + WapiIELength = pWapiInfo->wapiIELength; + pframe[0] = _WAPI_IE_; + pframe[1] = WapiIELength; + _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength); + pframe += WapiIELength+2; + pattrib->pktlen += WapiIELength+2; + + WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__); +} + +void rtw_build_beacon_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + u8 WapiIELength = 0; + WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + WapiSetIE(padapter); + WapiIELength = pWapiInfo->wapiIELength; + pframe[0] = _WAPI_IE_; + pframe[1] = WapiIELength; + _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength); + pframe += WapiIELength+2; + pattrib->pktlen += WapiIELength+2; + + WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__); +} + +void rtw_build_assoc_req_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib) +{ + PRT_WAPI_BKID pWapiBKID; + u16 bkidNum; + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + u8 WapiIELength = 0; + + WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__); + return; + } + + WapiSetIE(padapter); + WapiIELength = pWapiInfo->wapiIELength; + bkidNum = 0; + if(!list_empty(&(pWapiInfo->wapiBKIDStoreList))){ + list_for_each_entry(pWapiBKID, &pWapiInfo->wapiBKIDStoreList, list) { + bkidNum ++; + _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength+2, pWapiBKID->bkid,16); + WapiIELength += 16; + } + } + _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength, &bkidNum, 2); + WapiIELength += 2; + + pframe[0] = _WAPI_IE_; + pframe[1] = WapiIELength; + _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength); + pframe += WapiIELength+2; + pattrib->pktlen += WapiIELength+2; + WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__); +} + +void rtw_wapi_on_assoc_ok(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo); + PRT_WAPI_STA_INFO pWapiSta; + u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + //u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + + WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + pWapiSta =(PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list); + list_del_init(&pWapiSta->list); + list_add_tail(&pWapiSta->list, &pWapiInfo->wapiSTAUsedList); + _rtw_memcpy(pWapiSta->PeerMacAddr,padapter->mlmeextpriv.mlmext_info.network.MacAddress,6); + _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16); + _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16); + + //For chenk PN error with Qos Data after s3: add by ylb 20111114 + _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16); + + WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__); +} + + +void rtw_wapi_return_one_sta_info(_adapter *padapter, u8 *MacAddr) +{ + PRT_WAPI_T pWapiInfo; + PRT_WAPI_STA_INFO pWapiStaInfo = NULL; + PRT_WAPI_BKID pWapiBkid = NULL; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + pWapiInfo = &padapter->wapiInfo; + + WAPI_TRACE(WAPI_API, "==========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + while(!list_empty(&(pWapiInfo->wapiBKIDStoreList))) + { + pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list); + list_del_init(&pWapiBkid->list); + _rtw_memset(pWapiBkid->bkid,0,16); + list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList); + } + } + + + WAPI_TRACE(WAPI_API, " %s: after clear bkid \n", __FUNCTION__); + + + //Remove STA info + if(list_empty(&(pWapiInfo->wapiSTAUsedList))){ + WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is null \n", __FUNCTION__); + return; + }else{ + + WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is not null \n", __FUNCTION__); +#if 0 + pWapiStaInfo=(PRT_WAPI_STA_INFO)list_entry((pWapiInfo->wapiSTAUsedList.next),RT_WAPI_STA_INFO,list); + + list_for_each_entry(pWapiStaInfo, &(pWapiInfo->wapiSTAUsedList), list) { + + DBG_871X("MAC Addr %02x-%02x-%02x-%02x-%02x-%02x \n",MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]); + + + DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]); + + if(pWapiStaInfo == NULL) + { + WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo == NULL Case \n", __FUNCTION__); + return; + } + + if(pWapiStaInfo->PeerMacAddr == NULL) + { + WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo->PeerMacAddr == NULL Case \n", __FUNCTION__); + return; + } + + if(MacAddr == NULL) + { + WAPI_TRACE(WAPI_API, " %s: MacAddr == NULL Case \n", __FUNCTION__); + return; + } + + if (_rtw_memcmp(pWapiStaInfo->PeerMacAddr, MacAddr, ETH_ALEN) == _TRUE) { + pWapiStaInfo->bAuthenticateInProgress = false; + pWapiStaInfo->bSetkeyOk = false; + _rtw_memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN); + list_del_init(&pWapiStaInfo->list); + list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList); + break; + } + + } +#endif + + while(!list_empty(&(pWapiInfo->wapiSTAUsedList))) + { + pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list); + + DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]); + + list_del_init(&pWapiStaInfo->list); + memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN); + pWapiStaInfo->bSetkeyOk = 0; + list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList); + } + + } + + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); + return; +} + +void rtw_wapi_return_all_sta_info(_adapter *padapter) +{ + PRT_WAPI_T pWapiInfo; + PRT_WAPI_STA_INFO pWapiStaInfo; + PRT_WAPI_BKID pWapiBkid; + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + pWapiInfo = &padapter->wapiInfo; + + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + //Sta Info List + while(!list_empty(&(pWapiInfo->wapiSTAUsedList))) + { + pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list); + list_del_init(&pWapiStaInfo->list); + memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN); + pWapiStaInfo->bSetkeyOk = 0; + list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList); + } + + //BKID List + while(!list_empty(&(pWapiInfo->wapiBKIDStoreList))) + { + pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list); + list_del_init(&pWapiBkid->list); + memset(pWapiBkid->bkid,0,16); + list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList); + } + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); +} + +void rtw_wapi_clear_cam_entry(_adapter *padapter, u8 *pMacAddr) +{ + u8 UcIndex = 0; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 0); + if(UcIndex != 0xff){ + //CAM_mark_invalid(Adapter, UcIndex); + CAM_empty_entry(padapter, UcIndex); + } + + UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 0); + if(UcIndex != 0xff){ + //CAM_mark_invalid(Adapter, UcIndex); + CAM_empty_entry(padapter, UcIndex); + } + + UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 1); + if(UcIndex != 0xff){ + //CAM_mark_invalid(Adapter, UcIndex); + CAM_empty_entry(padapter, UcIndex); + } + + UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 1); + if(UcIndex != 0xff){ + //CAM_mark_invalid(padapter, UcIndex); + CAM_empty_entry(padapter, UcIndex); + } + + WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__); +} + +void rtw_wapi_clear_all_cam_entry(_adapter *padapter) +{ + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) + { + WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + invalidate_cam_all(padapter); // is this ok? + WapiResetAllCamEntry(padapter); + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); +} + +void rtw_wapi_set_key(_adapter *padapter, RT_WAPI_KEY *pWapiKey, RT_WAPI_STA_INFO *pWapiSta, u8 bGroupKey, u8 bUseDefaultKey) +{ + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + u8 *pMacAddr = pWapiSta->PeerMacAddr; + u32 EntryId = 0; + BOOLEAN IsPairWise = false ; + u8 EncAlgo; + + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) + { + WAPI_TRACE(WAPI_API, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__); + return; + } + + EncAlgo = _SMS4_; + + //For Tx bc/mc pkt,use defualt key entry + if(bUseDefaultKey) + { + // when WAPI update key, keyid will be 0 or 1 by turns. + if (pWapiKey->keyId == 0) + EntryId = 0; + else + EntryId = 2; + } + else + { + // tx/rx unicast pkt, or rx broadcast, find the key entry by peer's MacAddr + EntryId = WapiGetEntryForCamWrite(padapter,pMacAddr,pWapiKey->keyId,bGroupKey); + } + + if(EntryId == 0xff){ + WAPI_TRACE(WAPI_API, "===>No entry for WAPI setkey! !!\n"); + return; + } + + //EntryId is also used to diff Sec key and Mic key + //Sec Key + WapiWriteOneCamEntry(padapter, + pMacAddr, + pWapiKey->keyId, //keyid + EntryId, //entry + EncAlgo, //type + bGroupKey, //pairwise or group key + pWapiKey->dataKey); + //MIC key + WapiWriteOneCamEntry(padapter, + pMacAddr, + pWapiKey->keyId, //keyid + EntryId+1, //entry + EncAlgo, //type + bGroupKey, //pairwise or group key + pWapiKey->micKey); + + WAPI_TRACE(WAPI_API, "Set Wapi Key :KeyId:%d,EntryId:%d,PairwiseKey:%d.\n",pWapiKey->keyId,EntryId,!bGroupKey); + WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__); + +} + +#if 0 +//YJ,test,091013 +void wapi_test_set_key(struct _adapter *padapter, u8* buf) +{ /*Data: keyType(1) + bTxEnable(1) + bAuthenticator(1) + bUpdate(1) + PeerAddr(6) + DataKey(16) + MicKey(16) + KeyId(1)*/ + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + PRT_WAPI_BKID pWapiBkid; + PRT_WAPI_STA_INFO pWapiSta; + u8 data[43]; + bool bTxEnable; + bool bUpdate; + bool bAuthenticator; + u8 PeerAddr[6]; + u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + + WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__); + + if (!padapter->WapiSupport){ + return; + } + + copy_from_user(data, buf, 43); + bTxEnable = data[1]; + bAuthenticator = data[2]; + bUpdate = data[3]; + memcpy(PeerAddr,data+4,6); + + if(data[0] == 0x3){ + if(!list_empty(&(pWapiInfo->wapiBKIDIdleList))){ + pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list); + list_del_init(&pWapiBkid->list); + memcpy(pWapiBkid->bkid, data+10, 16); + WAPI_DATA(WAPI_INIT, "SetKey - BKID", pWapiBkid->bkid, 16); + list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDStoreList); + } + }else{ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(!memcmp(pWapiSta->PeerMacAddr,PeerAddr,6)){ + pWapiSta->bAuthenticatorInUpdata = false; + switch(data[0]){ + case 1: //usk + if(bAuthenticator){ //authenticator + memcpy(pWapiSta->lastTxUnicastPN,WapiAEPNInitialValueSrc,16); + if(!bUpdate) { //first + WAPI_TRACE(WAPI_INIT,"AE fisrt set usk \n"); + pWapiSta->wapiUsk.bSet = true; + memcpy(pWapiSta->wapiUsk.dataKey,data+10,16); + memcpy(pWapiSta->wapiUsk.micKey,data+26,16); + pWapiSta->wapiUsk.keyId = *(data+42); + pWapiSta->wapiUsk.bTxEnable = true; + WAPI_DATA(WAPI_INIT, "SetKey - AE USK Data Key", pWapiSta->wapiUsk.dataKey, 16); + WAPI_DATA(WAPI_INIT, "SetKey - AE USK Mic Key", pWapiSta->wapiUsk.micKey, 16); + } + else //update + { + WAPI_TRACE(WAPI_INIT, "AE update usk \n"); + pWapiSta->wapiUskUpdate.bSet = true; + pWapiSta->bAuthenticatorInUpdata = true; + memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16); + memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16); + memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16); + pWapiSta->wapiUskUpdate.keyId = *(data+42); + pWapiSta->wapiUskUpdate.bTxEnable = true; + } + } + else{ + if(!bUpdate){ + WAPI_TRACE(WAPI_INIT,"ASUE fisrt set usk \n"); + if(bTxEnable){ + pWapiSta->wapiUsk.bTxEnable = true; + memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16); + }else{ + pWapiSta->wapiUsk.bSet = true; + memcpy(pWapiSta->wapiUsk.dataKey,data+10,16); + memcpy(pWapiSta->wapiUsk.micKey,data+26,16); + pWapiSta->wapiUsk.keyId = *(data+42); + pWapiSta->wapiUsk.bTxEnable = false; + } + }else{ + WAPI_TRACE(WAPI_INIT,"ASUE update usk \n"); + if(bTxEnable){ + pWapiSta->wapiUskUpdate.bTxEnable = true; + if(pWapiSta->wapiUskUpdate.bSet){ + memcpy(pWapiSta->wapiUsk.dataKey,pWapiSta->wapiUskUpdate.dataKey,16); + memcpy(pWapiSta->wapiUsk.micKey,pWapiSta->wapiUskUpdate.micKey,16); + pWapiSta->wapiUsk.keyId=pWapiSta->wapiUskUpdate.keyId; + memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16); + memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16); + pWapiSta->wapiUskUpdate.bTxEnable = false; + pWapiSta->wapiUskUpdate.bSet = false; + } + memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16); + }else{ + pWapiSta->wapiUskUpdate.bSet = true; + memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16); + memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16); + pWapiSta->wapiUskUpdate.keyId = *(data+42); + pWapiSta->wapiUskUpdate.bTxEnable = false; + } + } + } + break; + case 2: //msk + if(bAuthenticator){ //authenticator + pWapiInfo->wapiTxMsk.bSet = true; + memcpy(pWapiInfo->wapiTxMsk.dataKey,data+10,16); + memcpy(pWapiInfo->wapiTxMsk.micKey,data+26,16); + pWapiInfo->wapiTxMsk.keyId = *(data+42); + pWapiInfo->wapiTxMsk.bTxEnable = true; + memcpy(pWapiInfo->lastTxMulticastPN,WapiAEMultiCastPNInitialValueSrc,16); + + if(!bUpdate){ //first + WAPI_TRACE(WAPI_INIT, "AE fisrt set msk \n"); + if(!pWapiSta->bSetkeyOk) + pWapiSta->bSetkeyOk = true; + pWapiInfo->bFirstAuthentiateInProgress= false; + }else{ //update + WAPI_TRACE(WAPI_INIT,"AE update msk \n"); + } + + WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Data Key", pWapiInfo->wapiTxMsk.dataKey, 16); + WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Mic Key", pWapiInfo->wapiTxMsk.micKey, 16); + } + else{ + if(!bUpdate){ + WAPI_TRACE(WAPI_INIT,"ASUE fisrt set msk \n"); + pWapiSta->wapiMsk.bSet = true; + memcpy(pWapiSta->wapiMsk.dataKey,data+10,16); + memcpy(pWapiSta->wapiMsk.micKey,data+26,16); + pWapiSta->wapiMsk.keyId = *(data+42); + pWapiSta->wapiMsk.bTxEnable = false; + if(!pWapiSta->bSetkeyOk) + pWapiSta->bSetkeyOk = true; + pWapiInfo->bFirstAuthentiateInProgress= false; + WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Data Key", pWapiSta->wapiMsk.dataKey, 16); + WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Mic Key", pWapiSta->wapiMsk.micKey, 16); + }else{ + WAPI_TRACE(WAPI_INIT,"ASUE update msk \n"); + pWapiSta->wapiMskUpdate.bSet = true; + memcpy(pWapiSta->wapiMskUpdate.dataKey,data+10,16); + memcpy(pWapiSta->wapiMskUpdate.micKey,data+26,16); + pWapiSta->wapiMskUpdate.keyId = *(data+42); + pWapiSta->wapiMskUpdate.bTxEnable = false; + } + } + break; + default: + WAPI_TRACE(WAPI_ERR,"Unknown Flag \n"); + break; + } + } + } + } + WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__); +} + + +void wapi_test_init(struct _adapter *padapter) +{ + u8 keybuf[100]; + u8 mac_addr[6]={0x00,0xe0,0x4c,0x72,0x04,0x70}; + u8 UskDataKey[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + u8 UskMicKey[16]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}; + u8 UskId = 0; + u8 MskDataKey[16]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}; + u8 MskMicKey[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; + u8 MskId = 0; + + WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__); + + //Enable Wapi + WAPI_TRACE(WAPI_INIT, "%s: Enable wapi!!!!\n", __FUNCTION__); + padapter->wapiInfo.bWapiEnable = true; + padapter->pairwise_key_type = KEY_TYPE_SMS4; + ieee->group_key_type = KEY_TYPE_SMS4; + padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN; + padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN; + + //set usk + WAPI_TRACE(WAPI_INIT, "%s: Set USK!!!!\n", __FUNCTION__); + memset(keybuf,0,100); + keybuf[0] = 1; //set usk + keybuf[1] = 1; //enable tx + keybuf[2] = 1; //AE + keybuf[3] = 0; //not update + + memcpy(keybuf+4,mac_addr,6); + memcpy(keybuf+10,UskDataKey,16); + memcpy(keybuf+26,UskMicKey,16); + keybuf[42]=UskId; + wapi_test_set_key(padapter, keybuf); + + memset(keybuf,0,100); + keybuf[0] = 1; //set usk + keybuf[1] = 1; //enable tx + keybuf[2] = 0; //AE + keybuf[3] = 0; //not update + + memcpy(keybuf+4,mac_addr,6); + memcpy(keybuf+10,UskDataKey,16); + memcpy(keybuf+26,UskMicKey,16); + keybuf[42]=UskId; + wapi_test_set_key(padapter, keybuf); + + //set msk + WAPI_TRACE(WAPI_INIT, "%s: Set MSK!!!!\n", __FUNCTION__); + memset(keybuf,0,100); + keybuf[0] = 2; //set msk + keybuf[1] = 1; //Enable TX + keybuf[2] = 1; //AE + keybuf[3] = 0; //not update + memcpy(keybuf+4,mac_addr,6); + memcpy(keybuf+10,MskDataKey,16); + memcpy(keybuf+26,MskMicKey,16); + keybuf[42] = MskId; + wapi_test_set_key(padapter, keybuf); + + memset(keybuf,0,100); + keybuf[0] = 2; //set msk + keybuf[1] = 1; //Enable TX + keybuf[2] = 0; //AE + keybuf[3] = 0; //not update + memcpy(keybuf+4,mac_addr,6); + memcpy(keybuf+10,MskDataKey,16); + memcpy(keybuf+26,MskMicKey,16); + keybuf[42] = MskId; + wapi_test_set_key(padapter, keybuf); + WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__); +} +#endif + +void rtw_wapi_get_iv(_adapter *padapter,u8 *pRA, u8*IV) +{ + PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL; + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + bool bPNOverflow = false; + bool bFindMatchPeer = false; + PRT_WAPI_STA_INFO pWapiSta = NULL; + + pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)IV; + + WAPI_DATA(WAPI_RX,"wapi_get_iv: pra",pRA,6); + + if(IS_MCAST(pRA)){ + if(!pWapiInfo->wapiTxMsk.bTxEnable){ + WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__); + return; + } + + if(pWapiInfo->wapiTxMsk.keyId <= 1){ + pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId; + pWapiExt->Reserved = 0; + bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1); + memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16); + } + } + else + { + if(list_empty(&pWapiInfo->wapiSTAUsedList)){ + WAPI_TRACE(WAPI_RX,"rtw_wapi_get_iv: list is empty \n"); + _rtw_memset(IV,10,18); + return; + } + else{ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){ + WAPI_DATA(WAPI_RX,"rtw_wapi_get_iv: peermacaddr ",pWapiSta->PeerMacAddr,6); + if (_rtw_memcmp((u8*)pWapiSta->PeerMacAddr, pRA, 6) == _TRUE) { + bFindMatchPeer = true; + break; + } + } + + WAPI_TRACE(WAPI_RX,"bFindMatchPeer: %d \n",bFindMatchPeer); + WAPI_DATA(WAPI_RX,"Addr",pRA,6); + + if (bFindMatchPeer){ + if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)) + return; + + if (pWapiSta->wapiUsk.keyId <= 1){ + if(pWapiSta->wapiUskUpdate.bTxEnable) + pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId; + else + pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId; + + pWapiExt->Reserved = 0; + bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2); + _rtw_memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16); + + } + } + } + + } + +} + +bool rtw_wapi_drop_for_key_absent(_adapter *padapter,u8 *pRA) +{ + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + bool bFindMatchPeer = false; + bool bDrop = false; + PRT_WAPI_STA_INFO pWapiSta = NULL; + struct security_priv *psecuritypriv = &padapter->securitypriv; + + WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: ra ",pRA,6); + + if(psecuritypriv->dot11PrivacyAlgrthm == _SMS4_) + { + if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable)) + return true; + + if(IS_MCAST(pRA)){ + if(!pWapiInfo->wapiTxMsk.bTxEnable){ + bDrop = true; + WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: multicast key is absent \n"); + return bDrop; + } + } + else{ + if(!list_empty(&pWapiInfo->wapiSTAUsedList)){ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){ + WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: pWapiSta->PeerMacAddr ",pWapiSta->PeerMacAddr,6); + if (_rtw_memcmp(pRA, pWapiSta->PeerMacAddr, 6) == _TRUE){ + bFindMatchPeer = true; + break; + } + } + if (bFindMatchPeer) { + if (!pWapiSta->wapiUsk.bTxEnable){ + bDrop = true; + WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: unicast key is absent \n"); + return bDrop; + } + } + else{ + bDrop = true; + WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no peer find \n"); + return bDrop; + } + + } + else{ + bDrop = true; + WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no sta exist \n"); + return bDrop; + } + } + } + else + { + return bDrop; + } + + return bDrop; +} + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi_sms4.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi_sms4.c new file mode 100644 index 00000000..6126ed9a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wapi_sms4.c @@ -0,0 +1,923 @@ +#ifdef CONFIG_WAPI_SUPPORT + +#include +#include +#include +#include + + +#ifdef CONFIG_WAPI_SW_SMS4 + +#define WAPI_LITTLE_ENDIAN +//#define BIG_ENDIAN +#define ENCRYPT 0 +#define DECRYPT 1 + + +/********************************************************** + **********************************************************/ +const u8 Sbox[256] = { +0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05, +0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99, +0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62, +0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6, +0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8, +0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35, +0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87, +0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e, +0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1, +0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3, +0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f, +0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51, +0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8, +0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0, +0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84, +0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48 +}; + +const u32 CK[32] = { + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 }; + +#define Rotl(_x, _y) (((_x) << (_y)) | ((_x) >> (32 - (_y)))) + +#define ByteSub(_A) (Sbox[(_A) >> 24 & 0xFF] << 24 | \ + Sbox[(_A) >> 16 & 0xFF] << 16 | \ + Sbox[(_A) >> 8 & 0xFF] << 8 | \ + Sbox[(_A) & 0xFF]) + +#define L1(_B) ((_B) ^ Rotl(_B, 2) ^ Rotl(_B, 10) ^ Rotl(_B, 18) ^ Rotl(_B, 24)) +#define L2(_B) ((_B) ^ Rotl(_B, 13) ^ Rotl(_B, 23)) + +static void +xor_block(void *dst, void *src1, void *src2) +/* 128-bit xor: *dst = *src1 xor *src2. Pointers must be 32-bit aligned */ +{ + ((u32 *)dst)[0] = ((u32 *)src1)[0] ^ ((u32 *)src2)[0]; + ((u32 *)dst)[1] = ((u32 *)src1)[1] ^ ((u32 *)src2)[1]; + ((u32 *)dst)[2] = ((u32 *)src1)[2] ^ ((u32 *)src2)[2]; + ((u32 *)dst)[3] = ((u32 *)src1)[3] ^ ((u32 *)src2)[3]; +} + + +void SMS4Crypt(u8 *Input, u8 *Output, u32 *rk) +{ + u32 r, mid, x0, x1, x2, x3, *p; + p = (u32 *)Input; + x0 = p[0]; + x1 = p[1]; + x2 = p[2]; + x3 = p[3]; +#ifdef WAPI_LITTLE_ENDIAN + x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8); + x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8); + x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8); + x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8); +#endif + for (r = 0; r < 32; r += 4) + { + mid = x1 ^ x2 ^ x3 ^ rk[r + 0]; + mid = ByteSub(mid); + x0 ^= L1(mid); + mid = x2 ^ x3 ^ x0 ^ rk[r + 1]; + mid = ByteSub(mid); + x1 ^= L1(mid); + mid = x3 ^ x0 ^ x1 ^ rk[r + 2]; + mid = ByteSub(mid); + x2 ^= L1(mid); + mid = x0 ^ x1 ^ x2 ^ rk[r + 3]; + mid = ByteSub(mid); + x3 ^= L1(mid); + } +#ifdef WAPI_LITTLE_ENDIAN + x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8); + x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8); + x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8); + x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8); +#endif + p = (u32 *)Output; + p[0] = x3; + p[1] = x2; + p[2] = x1; + p[3] = x0; +} + + + +void SMS4KeyExt(u8 *Key, u32 *rk, u32 CryptFlag) +{ + u32 r, mid, x0, x1, x2, x3, *p; + + p = (u32 *)Key; + x0 = p[0]; + x1 = p[1]; + x2 = p[2]; + x3 = p[3]; +#ifdef WAPI_LITTLE_ENDIAN + x0 = Rotl(x0, 16); x0 = ((x0 & 0xFF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8); + x1 = Rotl(x1, 16); x1 = ((x1 & 0xFF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8); + x2 = Rotl(x2, 16); x2 = ((x2 & 0xFF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8); + x3 = Rotl(x3, 16); x3 = ((x3 & 0xFF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8); +#endif + + x0 ^= 0xa3b1bac6; + x1 ^= 0x56aa3350; + x2 ^= 0x677d9197; + x3 ^= 0xb27022dc; + for (r = 0; r < 32; r += 4) + { + mid = x1 ^ x2 ^ x3 ^ CK[r + 0]; + mid = ByteSub(mid); + rk[r + 0] = x0 ^= L2(mid); + mid = x2 ^ x3 ^ x0 ^ CK[r + 1]; + mid = ByteSub(mid); + rk[r + 1] = x1 ^= L2(mid); + mid = x3 ^ x0 ^ x1 ^ CK[r + 2]; + mid = ByteSub(mid); + rk[r + 2] = x2 ^= L2(mid); + mid = x0 ^ x1 ^ x2 ^ CK[r + 3]; + mid = ByteSub(mid); + rk[r + 3] = x3 ^= L2(mid); + } + if (CryptFlag == DECRYPT) + { + for (r = 0; r < 16; r++) + mid = rk[r], rk[r] = rk[31 - r], rk[31 - r] = mid; + } +} + + +void WapiSMS4Cryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength, + u8 *Output, u16 *OutputLength, u32 CryptFlag) +{ + u32 blockNum,i,j, rk[32]; + u16 remainder; + u8 blockIn[16],blockOut[16], tempIV[16], k; + + *OutputLength = 0; + remainder = InputLength & 0x0F; + blockNum = InputLength >> 4; + if(remainder !=0) + blockNum++; + else + remainder = 16; + + for(k=0;k<16;k++) + tempIV[k] = IV[15-k]; + + memcpy(blockIn, tempIV, 16); + + SMS4KeyExt((u8 *)Key, rk,CryptFlag); + + for(i=0; i> 4; + + for(k=0;k<16;k++) + tempIV[k] = IV[15-k]; + + memcpy(BlockIn, tempIV, 16); + + SMS4KeyExt((u8 *)Key, rk, ENCRYPT); + + SMS4Crypt((u8 *)BlockIn, BlockOut, rk); + + for(i=0; i> 4; + + for(i=0; i%s\n", __FUNCTION__); + + header = (struct ieee80211_hdr_3addr_qos *)pHeader; + memset(TempBuf, 0, 34); + memcpy(TempBuf, pHeader, 2); //FrameCtrl + pTemp = (u16*)TempBuf; + *pTemp &= 0xc78f; //bit4,5,6,11,12,13 + + memcpy((TempBuf+2), (pHeader+4), 12); //Addr1, Addr2 + memcpy((TempBuf+14), (pHeader+22), 2); // SeqCtrl + pTemp = (u16*)(TempBuf + 14); + *pTemp &= 0x000f; + + memcpy((TempBuf+16), (pHeader+16), 6); //Addr3 + + fc = le16_to_cpu(header->frame_ctl); + + + + if (GetFrDs((u16*)&fc) && GetToDs((u16 *)&fc)) + { + memcpy((TempBuf+22), (pHeader+24), 6); + QosOffset = 30; + }else{ + memset((TempBuf+22), 0, 6); + QosOffset = 24; + } + + if((fc & 0x0088) == 0x0088){ + memcpy((TempBuf+28), (pHeader+QosOffset), 2); + TempLen += 2; + //IV = pHeader + QosOffset + 2 + SNAP_SIZE + sizeof(u16) + 2; + IV = pHeader + QosOffset + 2 + 2; + }else{ + IV = pHeader + QosOffset + 2; + //IV = pHeader + QosOffset + SNAP_SIZE + sizeof(u16) + 2; + } + + TempBuf[TempLen-1] = (u8)(DataLen & 0xff); + TempBuf[TempLen-2] = (u8)((DataLen & 0xff00)>>8); + TempBuf[TempLen-4] = KeyIdx; + + WAPI_DATA(WAPI_TX, "CalculateMic - KEY", MicKey, 16); + WAPI_DATA(WAPI_TX, "CalculateMic - IV", IV, 16); + WAPI_DATA(WAPI_TX, "CalculateMic - TempBuf", TempBuf, TempLen); + WAPI_DATA(WAPI_TX, "CalculateMic - pData", pData, DataLen); + + WapiSMS4CalculateMic(MicKey, IV, TempBuf, TempLen, + pData, DataLen, MicBuffer, &MicLen); + + if (MicLen != 16) + WAPI_TRACE(WAPI_ERR,"%s: MIC Length Error!!\n",__FUNCTION__); + + WAPI_TRACE(WAPI_TX|WAPI_RX, "<=========%s\n", __FUNCTION__); +#endif +} + +/* AddCount: 1 or 2. + * If overflow, return 1, + * else return 0. + */ +u8 WapiIncreasePN(u8 *PN, u8 AddCount) +{ + u8 i; + + if (NULL == PN) + return 1; + //YJ,test,091102 + /* + if(AddCount == 2){ + DBG_8192C("############################%s(): PN[0]=0x%x\n", __FUNCTION__, PN[0]); + if(PN[0] == 0x48){ + PN[0] += AddCount; + return 1; + }else{ + PN[0] += AddCount; + return 0; + } + } + */ + //YJ,test,091102,end + + for (i=0; i<16; i++) + { + if (PN[i] + AddCount <= 0xff) + { + PN[i] += AddCount; + return 0; + } + else + { + PN[i] += AddCount; + AddCount = 1; + } + } + return 1; +} + + +void WapiGetLastRxUnicastPNForQoSData( + u8 UserPriority, + PRT_WAPI_STA_INFO pWapiStaInfo, + u8 *PNOut +) +{ + WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__); + switch(UserPriority) + { + case 0: + case 3: + memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBEQueue,16); + break; + case 1: + case 2: + memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBKQueue,16); + break; + case 4: + case 5: + memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVIQueue,16); + break; + case 6: + case 7: + memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVOQueue,16); + break; + default: + WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__); + break; + } + WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__); +} + + +void WapiSetLastRxUnicastPNForQoSData( + u8 UserPriority, + u8 *PNIn, + PRT_WAPI_STA_INFO pWapiStaInfo +) +{ + WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__); + switch(UserPriority) + { + case 0: + case 3: + memcpy(pWapiStaInfo->lastRxUnicastPNBEQueue,PNIn,16); + break; + case 1: + case 2: + memcpy(pWapiStaInfo->lastRxUnicastPNBKQueue,PNIn,16); + break; + case 4: + case 5: + memcpy(pWapiStaInfo->lastRxUnicastPNVIQueue,PNIn,16); + break; + case 6: + case 7: + memcpy(pWapiStaInfo->lastRxUnicastPNVOQueue,PNIn,16); + break; + default: + WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__); + break; + } + WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__); +} + + +/**************************************************************************** + FALSE not RX-Reorder + TRUE do RX Reorder +add to support WAPI to N-mode +*****************************************************************************/ +u8 WapiCheckPnInSwDecrypt( + _adapter *padapter, + struct sk_buff *pskb +) +{ + u8 ret = false; + +#if 0 + struct ieee80211_hdr_3addr_qos *header; + u16 fc; + u8 *pDaddr, *pTaddr, *pRaddr; + + header = (struct ieee80211_hdr_3addr_qos *)pskb->data; + pTaddr = header->addr2; + pRaddr = header->addr1; + fc = le16_to_cpu(header->frame_ctl); + + if(GetToDs(&fc)) + pDaddr = header->addr3; + else + pDaddr = header->addr1; + + if ((_rtw_memcmp(pRaddr, padapter->pnetdev->dev_addr, ETH_ALEN) == 0) + && ! (pDaddr) + && (GetFrameType(&fc) == WIFI_QOS_DATA_TYPE)) + //&& ieee->pHTInfo->bCurrentHTSupport && + //ieee->pHTInfo->bCurRxReorderEnable) + ret = false; + else + ret = true; +#endif + WAPI_TRACE(WAPI_RX, "%s: return %d\n", __FUNCTION__, ret); + return ret; +} + +int SecSMS4HeaderFillIV(_adapter *padapter, u8 *pxmitframe) +{ + struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib; + u8 * frame = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; + u8 *pSecHeader = NULL, *pos = NULL, *pRA = NULL; + u8 bPNOverflow = false, bFindMatchPeer = false, hdr_len = 0; + PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL; + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + PRT_WAPI_STA_INFO pWapiSta = NULL; + int ret = 0; + + WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__); + + return ret; +#if 0 + hdr_len = sMacHdrLng; + if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE) + { + hdr_len += 2; + } + //hdr_len += SNAP_SIZE + sizeof(u16); + + pos = skb_push(pskb, padapter->wapiInfo.extra_prefix_len); + memmove(pos, pos+padapter->wapiInfo.extra_prefix_len, hdr_len); + + pSecHeader = pskb->data + hdr_len; + pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)pSecHeader; + pRA = pskb->data + 4; + + WAPI_DATA(WAPI_TX, "FillIV - Before Fill IV", pskb->data, pskb->len); + + //Address 1 is always receiver's address + if( IS_MCAST(pRA) ){ + if(!pWapiInfo->wapiTxMsk.bTxEnable){ + WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__); + return -2; + } + if(pWapiInfo->wapiTxMsk.keyId <= 1){ + pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId; + pWapiExt->Reserved = 0; + bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1); + memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16); + if (bPNOverflow){ + // Update MSK Notification. + WAPI_TRACE(WAPI_ERR,"===============>%s():multicast PN overflow\n",__FUNCTION__); + rtw_wapi_app_event_handler(padapter,NULL,0,pRA, false, false, true, 0, false); + } + }else{ + WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Multicast KeyIdx!!\n",__FUNCTION__); + ret = -3; + } + } + else{ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(!memcmp(pWapiSta->PeerMacAddr,pRA,6)){ + bFindMatchPeer = true; + break; + } + } + if (bFindMatchPeer){ + if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)){ + WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__); + return -4; + } + if (pWapiSta->wapiUsk.keyId <= 1){ + if(pWapiSta->wapiUskUpdate.bTxEnable) + pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId; + else + pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId; + + pWapiExt->Reserved = 0; + bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2); + memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16); + if (bPNOverflow){ + // Update USK Notification. + WAPI_TRACE(WAPI_ERR,"===============>%s():unicast PN overflow\n",__FUNCTION__); + rtw_wapi_app_event_handler(padapter,NULL,0,pWapiSta->PeerMacAddr, false, true, false, 0, false); + } + }else{ + WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Unicast KeyIdx!!\n",__FUNCTION__); + ret = -5; + } + } + else{ + WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta "MAC_FMT"!!\n",__FUNCTION__, MAC_ARG(pRA)); + ret = -6; + } + } + + WAPI_DATA(WAPI_TX, "FillIV - After Fill IV", pskb->data, pskb->len); + WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__); + return ret; +#endif +} + +// WAPI SW Enc: must have done Coalesce! +void SecSWSMS4Encryption( + _adapter *padapter, + u8 * pxmitframe + ) +{ + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + PRT_WAPI_STA_INFO pWapiSta = NULL; + u8 *pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE; + struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib; + + u8 *SecPtr = NULL, *pRA, *pMicKey = NULL, *pDataKey = NULL, *pIV = NULL; + u8 IVOffset, DataOffset, bFindMatchPeer = false, KeyIdx = 0, MicBuffer[16]; + u16 OutputLength; + + WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__); + + WAPI_TRACE(WAPI_TX,"hdrlen: %d \n",pattrib->hdrlen); + + return; + + DataOffset = pattrib->hdrlen + pattrib->iv_len; + + pRA = pframe + 4; + + + if( IS_MCAST(pRA) ){ + KeyIdx = pWapiInfo->wapiTxMsk.keyId; + pIV = pWapiInfo->lastTxMulticastPN; + pMicKey = pWapiInfo->wapiTxMsk.micKey; + pDataKey = pWapiInfo->wapiTxMsk.dataKey; + }else{ + if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if (0 == memcmp(pWapiSta->PeerMacAddr, pRA, 6)){ + bFindMatchPeer = true; + break; + } + } + + if (bFindMatchPeer){ + if (pWapiSta->wapiUskUpdate.bTxEnable){ + KeyIdx = pWapiSta->wapiUskUpdate.keyId; + WAPI_TRACE(WAPI_TX, "%s(): Use update USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx); + pIV = pWapiSta->lastTxUnicastPN; + pMicKey = pWapiSta->wapiUskUpdate.micKey; + pDataKey = pWapiSta->wapiUskUpdate.dataKey; + }else{ + KeyIdx = pWapiSta->wapiUsk.keyId; + WAPI_TRACE(WAPI_TX, "%s(): Use USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx); + pIV = pWapiSta->lastTxUnicastPN; + pMicKey = pWapiSta->wapiUsk.micKey; + pDataKey = pWapiSta->wapiUsk.dataKey; + } + }else{ + WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta!!\n",__FUNCTION__); + return; + } + }else{ + WAPI_TRACE(WAPI_ERR,"%s: wapiSTAUsedList is empty!!\n",__FUNCTION__); + return; + } + } + + SecPtr = pframe; + SecCalculateMicSMS4(KeyIdx, pMicKey, SecPtr, (SecPtr+DataOffset), pattrib->pktlen, MicBuffer); + + WAPI_DATA(WAPI_TX, "Encryption - MIC", MicBuffer, padapter->wapiInfo.extra_postfix_len); + + memcpy(pframe+pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen-pattrib->icv_len, + (u8 *)MicBuffer, + padapter->wapiInfo.extra_postfix_len + ); + + + WapiSMS4Encryption(pDataKey, pIV, (SecPtr+DataOffset),pattrib->pktlen+pattrib->icv_len, (SecPtr+DataOffset), &OutputLength); + + WAPI_DATA(WAPI_TX, "Encryption - After SMS4 encryption",pframe,pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen); + + WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__); +} + +u8 SecSWSMS4Decryption( + _adapter *padapter, + u8 *precv_frame, + struct recv_priv *precv_priv + ) +{ + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + struct recv_frame_hdr *precv_hdr; + PRT_WAPI_STA_INFO pWapiSta = NULL; + u8 IVOffset, DataOffset, bFindMatchPeer = false, bUseUpdatedKey = false; + u8 KeyIdx, MicBuffer[16], lastRxPNforQoS[16]; + u8 *pRA, *pTA, *pMicKey, *pDataKey, *pLastRxPN, *pRecvPN, *pSecData, *pRecvMic, *pos; + u8 TID = 0; + u16 OutputLength, DataLen; + u8 bQosData; + struct sk_buff * pskb; + + WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__); + + return 0; + + precv_hdr = &((union recv_frame*)precv_frame)->u.hdr; + pskb = (struct sk_buff *)(precv_hdr->rx_data); + precv_hdr->bWapiCheckPNInDecrypt = WapiCheckPnInSwDecrypt(padapter, pskb); + WAPI_TRACE(WAPI_RX, "=========>%s: check PN %d\n", __FUNCTION__,precv_hdr->bWapiCheckPNInDecrypt); + WAPI_DATA(WAPI_RX, "Decryption - Before decryption", pskb->data, pskb->len); + + IVOffset = sMacHdrLng; + bQosData = GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE; + if (bQosData){ + IVOffset += 2; + } + + //if(GetHTC()) + // IVOffset += 4; + + //IVOffset += SNAP_SIZE + sizeof(u16); + + DataOffset = IVOffset + padapter->wapiInfo.extra_prefix_len; + + pRA = pskb->data + 4; + pTA = pskb->data + 10; + KeyIdx = *(pskb->data + IVOffset); + pRecvPN = pskb->data + IVOffset + 2; + pSecData = pskb->data + DataOffset; + DataLen = pskb->len - DataOffset; + pRecvMic = pskb->data + pskb->len - padapter->wapiInfo.extra_postfix_len; + TID = GetTid(pskb->data); + + if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){ + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if (0 == memcmp(pWapiSta->PeerMacAddr, pTA, 6)){ + bFindMatchPeer = true; + break; + } + } + } + + if (!bFindMatchPeer){ + WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT" for Key Info!!!\n", __FUNCTION__, MAC_ARG(pTA)); + return false; + } + + if( IS_MCAST(pRA) ){ + WAPI_TRACE(WAPI_RX, "%s: Multicast decryption !!!\n", __FUNCTION__); + if (pWapiSta->wapiMsk.keyId == KeyIdx && pWapiSta->wapiMsk.bSet){ + pLastRxPN = pWapiSta->lastRxMulticastPN; + if (!WapiComparePN(pRecvPN, pLastRxPN)){ + WAPI_TRACE(WAPI_ERR, "%s: MSK PN is not larger than last, Dropped!!!\n", __FUNCTION__); + WAPI_DATA(WAPI_ERR, "pRecvPN:", pRecvPN, 16); + WAPI_DATA(WAPI_ERR, "pLastRxPN:", pLastRxPN, 16); + return false; + } + + memcpy(pLastRxPN, pRecvPN, 16); + pMicKey = pWapiSta->wapiMsk.micKey; + pDataKey = pWapiSta->wapiMsk.dataKey; + }else if (pWapiSta->wapiMskUpdate.keyId == KeyIdx && pWapiSta->wapiMskUpdate.bSet){ + WAPI_TRACE(WAPI_RX, "%s: Use Updated MSK for Decryption !!!\n", __FUNCTION__); + bUseUpdatedKey = true; + memcpy(pWapiSta->lastRxMulticastPN, pRecvPN, 16); + pMicKey = pWapiSta->wapiMskUpdate.micKey; + pDataKey = pWapiSta->wapiMskUpdate.dataKey; + }else{ + WAPI_TRACE(WAPI_ERR, "%s: Can not find MSK with matched KeyIdx(%d), Dropped !!!\n", __FUNCTION__,KeyIdx); + return false; + } + } + else{ + WAPI_TRACE(WAPI_RX, "%s: Unicast decryption !!!\n", __FUNCTION__); + if (pWapiSta->wapiUsk.keyId == KeyIdx && pWapiSta->wapiUsk.bSet){ + WAPI_TRACE(WAPI_RX, "%s: Use USK for Decryption!!!\n", __FUNCTION__); + if(precv_hdr->bWapiCheckPNInDecrypt){ + if(GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE){ + WapiGetLastRxUnicastPNForQoSData(TID, pWapiSta, lastRxPNforQoS); + pLastRxPN = lastRxPNforQoS; + }else{ + pLastRxPN = pWapiSta->lastRxUnicastPN; + } + if (!WapiComparePN(pRecvPN, pLastRxPN)){ + return false; + } + if(bQosData){ + WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta); + }else{ + memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16); + } + }else{ + memcpy(precv_hdr->WapiTempPN,pRecvPN,16); + } + + if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) + { + if ((pRecvPN[0] & 0x1) == 0){ + WAPI_TRACE(WAPI_ERR, "%s: Rx USK PN is not odd when Infra STA mode, Dropped !!!\n", __FUNCTION__); + return false; + } + } + + pMicKey = pWapiSta->wapiUsk.micKey; + pDataKey = pWapiSta->wapiUsk.dataKey; + } + else if (pWapiSta->wapiUskUpdate.keyId == KeyIdx && pWapiSta->wapiUskUpdate.bSet ){ + WAPI_TRACE(WAPI_RX, "%s: Use Updated USK for Decryption!!!\n", __FUNCTION__); + if(pWapiSta->bAuthenticatorInUpdata) + bUseUpdatedKey = true; + else + bUseUpdatedKey = false; + + if(bQosData){ + WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta); + }else{ + memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16); + } + pMicKey = pWapiSta->wapiUskUpdate.micKey; + pDataKey = pWapiSta->wapiUskUpdate.dataKey; + }else{ + WAPI_TRACE(WAPI_ERR, "%s: No valid USK!!!KeyIdx=%d pWapiSta->wapiUsk.keyId=%d pWapiSta->wapiUskUpdate.keyId=%d\n", __FUNCTION__, KeyIdx, pWapiSta->wapiUsk.keyId, pWapiSta->wapiUskUpdate.keyId); + //dump_buf(pskb->data,pskb->len); + return false; + } + } + + WAPI_DATA(WAPI_RX, "Decryption - DataKey", pDataKey, 16); + WAPI_DATA(WAPI_RX, "Decryption - IV", pRecvPN, 16); + WapiSMS4Decryption(pDataKey, pRecvPN, pSecData, DataLen, pSecData, &OutputLength); + + if (OutputLength != DataLen) + WAPI_TRACE(WAPI_ERR, "%s: Output Length Error!!!!\n", __FUNCTION__); + + WAPI_DATA(WAPI_RX, "Decryption - After decryption", pskb->data, pskb->len); + + DataLen -= padapter->wapiInfo.extra_postfix_len; + + SecCalculateMicSMS4(KeyIdx, pMicKey, pskb->data, pSecData, DataLen, MicBuffer); + + WAPI_DATA(WAPI_RX, "Decryption - MIC received", pRecvMic, SMS4_MIC_LEN); + WAPI_DATA(WAPI_RX, "Decryption - MIC calculated", MicBuffer, SMS4_MIC_LEN); + + if (0 == memcmp(MicBuffer, pRecvMic, padapter->wapiInfo.extra_postfix_len)){ + WAPI_TRACE(WAPI_RX, "%s: Check MIC OK!!\n", __FUNCTION__); + if (bUseUpdatedKey){ + // delete the old key + if ( IS_MCAST(pRA) ){ + WAPI_TRACE(WAPI_API, "%s(): AE use new update MSK!!\n", __FUNCTION__); + pWapiSta->wapiMsk.keyId = pWapiSta->wapiMskUpdate.keyId; + memcpy(pWapiSta->wapiMsk.dataKey, pWapiSta->wapiMskUpdate.dataKey, 16); + memcpy(pWapiSta->wapiMsk.micKey, pWapiSta->wapiMskUpdate.micKey, 16); + pWapiSta->wapiMskUpdate.bTxEnable = pWapiSta->wapiMskUpdate.bSet = false; + }else{ + WAPI_TRACE(WAPI_API, "%s(): AE use new update USK!!\n", __FUNCTION__); + pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId; + memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16); + memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16); + pWapiSta->wapiUskUpdate.bTxEnable = pWapiSta->wapiUskUpdate.bSet = false; + } + } + }else{ + WAPI_TRACE(WAPI_ERR, "%s: Check MIC Error, Dropped !!!!\n", __FUNCTION__); + return false; + } + + pos = pskb->data; + memmove(pos+padapter->wapiInfo.extra_prefix_len, pos, IVOffset); + skb_pull(pskb, padapter->wapiInfo.extra_prefix_len); + + WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__); + + return true; +} + +u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe) +{ + + u8 *pframe; + u32 res = _SUCCESS; + + WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) + { + WAPI_TRACE(WAPI_TX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__); + return _FAIL; + } + + if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL) + return _FAIL; + + pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET; + + SecSWSMS4Encryption(padapter, pxmitframe); + + WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__); + return res; +} + +u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe) +{ + u8 *pframe; + u32 res = _SUCCESS; + + WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__); + + if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable)) + { + WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__); + return _FAIL; + } + + + //drop packet when hw decrypt fail + //return tempraily + return _FAIL; + + //pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data; + + if (false == SecSWSMS4Decryption(padapter, precvframe, &padapter->recvpriv)) + { + WAPI_TRACE(WAPI_ERR, "%s():SMS4 decrypt frame error\n",__FUNCTION__); + return _FAIL; + } + + WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__); + return res; +} + +#else + +u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe) +{ + WAPI_TRACE(WAPI_TX, "=========>Dummy %s\n", __FUNCTION__); + WAPI_TRACE(WAPI_TX, "<=========Dummy %s\n", __FUNCTION__); + return _SUCCESS; +} + +u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe) +{ + WAPI_TRACE(WAPI_RX, "=========>Dummy %s\n", __FUNCTION__); + WAPI_TRACE(WAPI_RX, "<=========Dummy %s\n", __FUNCTION__); + return _SUCCESS; +} + +#endif + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wlan_util.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wlan_util.c new file mode 100644 index 00000000..34702716 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_wlan_util.c @@ -0,0 +1,4735 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_WLAN_UTIL_C_ + +#include + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +#include +#endif + +unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f}; +unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74}; + +unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18}; +unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7}; +unsigned char BROADCOM_OUI3[] = {0x00, 0x05, 0xb5}; + + +unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96}; +unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43}; +unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43}; +unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c}; +unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5}; + +unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; + +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WPA_TKIP_CIPHER[4]; +extern unsigned char RSN_TKIP_CIPHER[4]; + +#define R2T_PHY_DELAY (0) + +//#define WAIT_FOR_BCN_TO_MIN (3000) +#define WAIT_FOR_BCN_TO_MIN (6000) +#define WAIT_FOR_BCN_TO_MAX (20000) + +#define DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS 1000 +#define DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD 3 + +static u8 rtw_basic_rate_cck[4] = { + IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK +}; + +static u8 rtw_basic_rate_ofdm[3] = { + IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK +}; + +static u8 rtw_basic_rate_mix[7] = { + IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK, + IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK +}; + +int new_bcn_max = 3; + +int cckrates_included(unsigned char *rate, int ratelen) +{ + int i; + + for(i = 0; i < ratelen; i++) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + } + + return _FALSE; + +} + +int cckratesonly_included(unsigned char *rate, int ratelen) +{ + int i; + + for(i = 0; i < ratelen; i++) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + return _FALSE; + } + + return _TRUE; +} + +s8 rtw_get_tx_nss(_adapter *adapter, struct sta_info *psta) +{ + u8 rf_type = RF_1T1R, custom_rf_type, vht_mcs[2]; + s8 nss = 1; + + custom_rf_type = adapter->registrypriv.rf_config; + rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + if (!psta) + return nss; + + /* rf_config is dependent on efuse or sw config */ + if (custom_rf_type != RF_MAX_TYPE) + rf_type = custom_rf_type; + +#ifdef CONFIG_80211AC_VHT + if (psta->vhtpriv.vht_option) { + u8 vht_mcs[2]; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + struct vht_priv *pvhtpriv_ap = &pmlmepriv->vhtpriv; + + _rtw_memcpy(vht_mcs, psta->vhtpriv.vht_mcs_map, 2); + /* doesn't support 5~8 SS so far */ + vht_mcs[1] = 0xff; + switch (rf_type) { + case RF_1T1R: + case RF_1T2R: + vht_mcs[0] |= 0xfc; + break; + case RF_2T2R: + case RF_2T4R: + case RF_2T2R_GREEN: + case RF_2T3R: + vht_mcs[0] |= 0xf0; + break; + case RF_3T3R: + case RF_3T4R: + vht_mcs[0] |= 0xc0; + break; + default: + DBG_871X("%s,%d, unknown rf type\n", __func__, __LINE__); + break; + } + nss = rtw_vht_mcsmap_to_nss(vht_mcs); + } else +#endif /* CONFIG_80211AC_VHT */ + if (psta->htpriv.ht_option) { + u8 supp_mcs_set[4]; + + _rtw_memcpy(supp_mcs_set, psta->htpriv.ht_cap.supp_mcs_set, 4); + + switch (rf_type) { + case RF_1T1R: + case RF_1T2R: + supp_mcs_set[1] = supp_mcs_set[2] = supp_mcs_set[3] = 0; + break; + case RF_2T2R: + case RF_2T4R: + case RF_2T2R_GREEN: + case RF_2T3R: + supp_mcs_set[2] = supp_mcs_set[3] = 0; + break; + case RF_3T3R: + case RF_3T4R: + supp_mcs_set[3] = 0; + break; + default: + DBG_871X("%s,%d, unknown rf type\n", __func__, __LINE__); + break; + } + nss = rtw_ht_mcsset_to_nss(supp_mcs_set); + } + + DBG_871X("%s: %d SS, rf_type=%d\n", __func__, nss, rf_type); + return nss; +} + +u8 networktype_to_raid(_adapter *adapter,struct sta_info *psta) +{ + unsigned char raid; + switch(psta->wireless_mode) + { + case WIRELESS_11B: + raid = RATR_INX_WIRELESS_B; + break; + case WIRELESS_11A: + case WIRELESS_11G: + raid = RATR_INX_WIRELESS_G; + break; + case WIRELESS_11BG: + raid = RATR_INX_WIRELESS_GB; + break; + case WIRELESS_11_24N: + case WIRELESS_11_5N: + raid = RATR_INX_WIRELESS_N; + break; + case WIRELESS_11A_5N: + case WIRELESS_11G_24N: + raid = RATR_INX_WIRELESS_NG; + break; + case WIRELESS_11BG_24N: + raid = RATR_INX_WIRELESS_NGB; + break; + default: + raid = RATR_INX_WIRELESS_GB; + break; + + } + return raid; + +} + +u8 networktype_to_raid_ex(_adapter *adapter, struct sta_info *psta) +{ + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + u8 raid = RATEID_IDX_BGN_40M_1SS, cur_rf_type, rf_type, custom_rf_type; + s8 tx_nss; + + tx_nss = rtw_get_tx_nss(adapter, psta); + + switch(psta->wireless_mode) + { + case WIRELESS_11B: + raid = RATEID_IDX_B; + break; + case WIRELESS_11A: + case WIRELESS_11G: + raid = RATEID_IDX_G; + break; + case WIRELESS_11BG: + raid = RATEID_IDX_BG; + break; + case WIRELESS_11_24N: + case WIRELESS_11_5N: + case WIRELESS_11A_5N: + case WIRELESS_11G_24N: + if (tx_nss == 1) + raid = RATEID_IDX_GN_N1SS; + else if (tx_nss == 2) + raid = RATEID_IDX_GN_N2SS; + else if (tx_nss == 3) + raid = RATEID_IDX_BGN_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + break; + case WIRELESS_11B_24N: + case WIRELESS_11BG_24N: + if (psta->bw_mode == CHANNEL_WIDTH_20) { + if (tx_nss == 1) + raid = RATEID_IDX_BGN_20M_1SS_BN; + else if (tx_nss == 2) + raid = RATEID_IDX_BGN_20M_2SS_BN; + else if (tx_nss == 3) + raid = RATEID_IDX_BGN_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + } else { + if (tx_nss == 1) + raid = RATEID_IDX_BGN_40M_1SS; + else if (tx_nss == 2) + raid = RATEID_IDX_BGN_40M_2SS; + else if (tx_nss == 3) + raid = RATEID_IDX_BGN_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + } + break; +#ifdef CONFIG_80211AC_VHT + case WIRELESS_11_5AC: + if (tx_nss == 1) + raid = RATEID_IDX_VHT_1SS; + else if (tx_nss == 2) + raid = RATEID_IDX_VHT_2SS; + else if (tx_nss == 3) + raid = RATEID_IDX_VHT_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + break; + case WIRELESS_11_24AC: + if (psta->bw_mode >= CHANNEL_WIDTH_80) + { + if (tx_nss == 1) + raid = RATEID_IDX_VHT_1SS; + else if (tx_nss == 2) + raid = RATEID_IDX_VHT_2SS; + else if (tx_nss == 3) + raid = RATEID_IDX_VHT_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + } + else + { + if (tx_nss == 1) + raid = RATEID_IDX_MIX1; + else if (tx_nss == 2) + raid = RATEID_IDX_MIX2; + else if (tx_nss == 3) + raid = RATEID_IDX_VHT_3SS; + else + DBG_871X("tx_nss error!(tx_nss=%d)\n", tx_nss); + } + break; +#endif + default: + DBG_871X("unexpected wireless mode!(psta->wireless_mode=%x)\n", psta->wireless_mode); + break; + + } + + /* DBG_871X("psta->wireless_mode=%x, tx_nss=%d\n", psta->wireless_mode, tx_nss); */ + + return raid; + +} + +u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen) +{ + u8 network_type = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + if(pmlmeext->cur_channel > 14) + { + if (pmlmeinfo->VHT_enable) + network_type = WIRELESS_11AC; + else if (pmlmeinfo->HT_enable) + network_type = WIRELESS_11_5N; + + network_type |= WIRELESS_11A; + } + else + { + if (pmlmeinfo->HT_enable) + { + network_type = WIRELESS_11_24N; + } + + if ((cckratesonly_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11B; + } + else if((cckrates_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11BG; + } + else + { + network_type |= WIRELESS_11G; + } + } + + return network_type; +} + +unsigned char ratetbl_val_2wifirate(unsigned char rate); +unsigned char ratetbl_val_2wifirate(unsigned char rate) +{ + unsigned char val = 0; + + switch (rate & 0x7f) + { + case 0: + val = IEEE80211_CCK_RATE_1MB; + break; + + case 1: + val = IEEE80211_CCK_RATE_2MB; + break; + + case 2: + val = IEEE80211_CCK_RATE_5MB; + break; + + case 3: + val = IEEE80211_CCK_RATE_11MB; + break; + + case 4: + val = IEEE80211_OFDM_RATE_6MB; + break; + + case 5: + val = IEEE80211_OFDM_RATE_9MB; + break; + + case 6: + val = IEEE80211_OFDM_RATE_12MB; + break; + + case 7: + val = IEEE80211_OFDM_RATE_18MB; + break; + + case 8: + val = IEEE80211_OFDM_RATE_24MB; + break; + + case 9: + val = IEEE80211_OFDM_RATE_36MB; + break; + + case 10: + val = IEEE80211_OFDM_RATE_48MB; + break; + + case 11: + val = IEEE80211_OFDM_RATE_54MB; + break; + + } + + return val; + +} + +int is_basicrate(_adapter *padapter, unsigned char rate); +int is_basicrate(_adapter *padapter, unsigned char rate) +{ + int i; + unsigned char val; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + for(i = 0; i < NumRates; i++) + { + val = pmlmeext->basicrate[i]; + + if ((val != 0xff) && (val != 0xfe)) + { + if (rate == ratetbl_val_2wifirate(val)) + { + return _TRUE; + } + } + } + + return _FALSE; +} + +unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset); +unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset) +{ + int i; + unsigned char rate; + unsigned int len = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + for (i = 0; i < NumRates; i++) + { + rate = pmlmeext->datarate[i]; + + switch (rate) + { + case 0xff: + return len; + + case 0xfe: + continue; + + default: + rate = ratetbl_val_2wifirate(rate); + + if (is_basicrate(padapter, rate) == _TRUE) + { + rate |= IEEE80211_BASIC_RATE_MASK; + } + + rateset[len] = rate; + len++; + break; + } + } + return len; +} + +void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len) +{ + unsigned char supportedrates[NumRates]; + + _rtw_memset(supportedrates, 0, NumRates); + *bssrate_len = ratetbl2rateset(padapter, supportedrates); + _rtw_memcpy(pbssrate, supportedrates, *bssrate_len); +} + +void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask) +{ + u8 mcs_rate_1r = (u8)(mask&0xff); + u8 mcs_rate_2r = (u8)((mask>>8)&0xff); + u8 mcs_rate_3r = (u8)((mask>>16)&0xff); + u8 mcs_rate_4r = (u8)((mask>>24)&0xff); + + mcs_set[0] &= mcs_rate_1r; + mcs_set[1] &= mcs_rate_2r; + mcs_set[2] &= mcs_rate_3r; + mcs_set[3] &= mcs_rate_4r; +} + +void UpdateBrateTbl( + IN PADAPTER Adapter, + IN u8 *mBratesOS +) +{ + u8 i; + u8 rate; + + // 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. + for(i=0;iiface_type == IFACE_PORT1) + { + Set_NETYPE1_MSR(padapter, type); + } + else +#endif + { + Set_NETYPE0_MSR(padapter, type); + } +} + +inline u8 rtw_get_oper_ch(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_channel; +} + +inline void rtw_set_oper_ch(_adapter *adapter, u8 ch) +{ +#ifdef DBG_CH_SWITCH + const int len = 128; + char msg[128] = {0}; + int cnt = 0; + int i = 0; +#endif /* DBG_CH_SWITCH */ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + + if (dvobj->oper_channel != ch) { + dvobj->on_oper_ch_time = rtw_get_current_time(); + +#ifdef DBG_CH_SWITCH + cnt += snprintf(msg+cnt, len-cnt, "switch to ch %3u", ch); + + for (i = 0; i < dvobj->iface_nums; i++) { + _adapter *iface = dvobj->padapters[i]; + cnt += snprintf(msg+cnt, len-cnt, " ["ADPT_FMT":", ADPT_ARG(iface)); + if (iface->mlmeextpriv.cur_channel == ch) + cnt += snprintf(msg+cnt, len-cnt, "C"); + else + cnt += snprintf(msg+cnt, len-cnt, "_"); + if (iface->wdinfo.listen_channel == ch && !rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_NONE)) + cnt += snprintf(msg+cnt, len-cnt, "L"); + else + cnt += snprintf(msg+cnt, len-cnt, "_"); + cnt += snprintf(msg+cnt, len-cnt, "]"); + } + + DBG_871X(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(adapter), msg); +#endif /* DBG_CH_SWITCH */ + } + + dvobj->oper_channel = ch; +} + +inline u8 rtw_get_oper_bw(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_bwmode; +} + +inline void rtw_set_oper_bw(_adapter *adapter, u8 bw) +{ + adapter_to_dvobj(adapter)->oper_bwmode = bw; +} + +inline u8 rtw_get_oper_choffset(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->oper_ch_offset; +} + +inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset) +{ + adapter_to_dvobj(adapter)->oper_ch_offset = offset; +} + +u8 rtw_get_offset_by_ch(u8 channel) +{ + u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if(channel>=1 && channel<=4) + { + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + } + else if(channel>=5 && channel<=14) + { + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + } + else + { + switch(channel) + { + case 36: + case 44: + case 52: + case 60: + case 100: + case 108: + case 116: + case 124: + case 132: + case 149: + case 157: + offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + case 40: + case 48: + case 56: + case 64: + case 104: + case 112: + case 120: + case 128: + case 136: + case 153: + case 161: + offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + default: + offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + } + + return offset; + +} + +u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset) +{ + u8 center_ch = channel; + + if(chnl_bw == CHANNEL_WIDTH_80) + { + if((channel == 36) || (channel == 40) || (channel == 44) || (channel == 48) ) + center_ch = 42; + if((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64) ) + center_ch = 58; + if((channel == 100) || (channel == 104) || (channel == 108) || (channel == 112) ) + center_ch = 106; + if((channel == 116) || (channel == 120) || (channel == 124) || (channel == 128) ) + center_ch = 122; + if((channel == 132) || (channel == 136) || (channel == 140) || (channel == 144) ) + center_ch = 138; + if((channel == 149) || (channel == 153) || (channel == 157) || (channel == 161) ) + center_ch = 155; + else if(channel <= 14) + center_ch = 7; + } + else if(chnl_bw == CHANNEL_WIDTH_40) + { + if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER) + center_ch = channel + 2; + else + center_ch = channel - 2; + } + + return center_ch; +} + +inline u32 rtw_get_on_oper_ch_time(_adapter *adapter) +{ + return adapter_to_dvobj(adapter)->on_oper_ch_time; +} + +inline u32 rtw_get_on_cur_ch_time(_adapter *adapter) +{ + if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel) + return adapter_to_dvobj(adapter)->on_oper_ch_time; + else + return 0; +} + +void SelectChannel(_adapter *padapter, unsigned char channel) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + +#ifdef CONFIG_DFS_MASTER +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl); + bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel + , adapter_to_dvobj(padapter)->oper_bwmode, adapter_to_dvobj(padapter)->oper_ch_offset); + + if (!ori_overlap_radar_detect_ch && new_overlap_radar_detect_ch) + rtw_odm_radar_detect_enable(padapter); + + if (new_overlap_radar_detect_ch && IS_UNDER_CAC(rfctl)) { + u8 pause = 0xFF; + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +#endif /* CONFIG_DFS_MASTER */ + + //saved channel info + rtw_set_oper_ch(padapter, channel); + + rtw_hal_set_chan(padapter, channel); + +#ifdef CONFIG_DFS_MASTER + if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) { + u8 pause = 0x00; + + rtw_odm_radar_detect_disable(padapter); + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +} +#endif /* CONFIG_DFS_MASTER */ + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + +} + +void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL); + +#ifdef CONFIG_DFS_MASTER +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl); + bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl + , adapter_to_dvobj(padapter)->oper_channel, bwmode, channel_offset); + + if (!ori_overlap_radar_detect_ch && new_overlap_radar_detect_ch) + rtw_odm_radar_detect_enable(padapter); + + if (new_overlap_radar_detect_ch && IS_UNDER_CAC(rfctl)) { + u8 pause = 0xFF; + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +#endif /* CONFIG_DFS_MASTER */ + + //saved bw info + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + + rtw_hal_set_bwmode(padapter, (CHANNEL_WIDTH)bwmode, channel_offset); + +#ifdef CONFIG_DFS_MASTER + if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) { + u8 pause = 0x00; + + rtw_odm_radar_detect_disable(padapter); + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +} +#endif /* CONFIG_DFS_MASTER */ + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL); +} + +void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode) +{ + u8 center_ch, chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if ( padapter->bNotifyChannelChange ) + { + DBG_871X( "[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode ); + } + + center_ch = rtw_get_center_ch(channel, bwmode, channel_offset); + + if(bwmode == CHANNEL_WIDTH_80) + { + if(center_ch > channel) + chnl_offset80 = HAL_PRIME_CHNL_OFFSET_LOWER; + else if(center_ch < channel) + chnl_offset80 = HAL_PRIME_CHNL_OFFSET_UPPER; + else + chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); + +#ifdef CONFIG_DFS_MASTER +{ + struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter); + bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl); + bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel, bwmode, channel_offset); + + if (!ori_overlap_radar_detect_ch && new_overlap_radar_detect_ch) + rtw_odm_radar_detect_enable(padapter); + + if (new_overlap_radar_detect_ch && IS_UNDER_CAC(rfctl)) { + u8 pause = 0xFF; + + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +#endif /* CONFIG_DFS_MASTER */ + + //set Channel + //saved channel/bw info + rtw_set_oper_ch(padapter, channel); + rtw_set_oper_bw(padapter, bwmode); + rtw_set_oper_choffset(padapter, channel_offset); + + rtw_hal_set_chnl_bw(padapter, center_ch, bwmode, channel_offset, chnl_offset80); // set center channel + +#ifdef CONFIG_DFS_MASTER + if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) { + u8 pause = 0x00; + + rtw_odm_radar_detect_disable(padapter); + rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause); + } +} +#endif /* CONFIG_DFS_MASTER */ + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL); +} + +int get_bsstype(unsigned short capability) +{ + if (capability & BIT(0)) + { + return WIFI_FW_AP_STATE; + } + else if (capability & BIT(1)) + { + return WIFI_FW_ADHOC_STATE; + } + else + { + return 0; + } +} + +__inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork) +{ + return (pnetwork->MacAddress); +} + +u16 get_beacon_interval(WLAN_BSSID_EX *bss) +{ + unsigned short val; + _rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2); + + return le16_to_cpu(val); + +} + +int is_client_associated_to_ap(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + + if(!padapter) + return _FAIL; + + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)) + { + return _TRUE; + } + else + { + return _FAIL; + } +} + +int is_client_associated_to_ibss(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) + { + return _TRUE; + } + else + { + return _FAIL; + } +} + +int is_IBSS_empty(_adapter *padapter) +{ + int i; + struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl; + + for (i = 0; i < macid_ctl->num; i++) { + if (!rtw_macid_is_used(macid_ctl, i)) + continue; + if (rtw_macid_get_if_g(macid_ctl, i) != padapter->iface_id) + continue; + if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[i])) + continue; + if (GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[i]) == H2C_MSR_ROLE_ADHOC) + return _FAIL; + } + + return _TRUE; +} + +unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval) +{ + if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN) + { + return WAIT_FOR_BCN_TO_MIN; + } + else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX) + { + return WAIT_FOR_BCN_TO_MAX; + } + else + { + return ((bcn_interval << 2)); + } +} + +void CAM_empty_entry( + PADAPTER Adapter, + u8 ucIndex +) +{ + rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex)); +} + +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, &val8); + + _enter_critical_bh(&cam_ctl->lock, &irqL); + rtw_sec_cam_map_clr_all(&cam_ctl->used); + _rtw_memset(dvobj->cam_cache, 0, sizeof(struct sec_cam_ent) * SEC_CAM_ENT_NUM_SW_LIMIT); + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +void _clear_cam_entry(_adapter *padapter, u8 entry) +{ + unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00}; + + rtw_sec_write_cam_ent(padapter, entry, 0, null_sta, null_key); +} + +inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) +{ +#ifdef CONFIG_WRITE_CACHE_ONLY + write_cam_cache(adapter, id ,ctrl, mac, key); +#else + rtw_sec_write_cam_ent(adapter, id, ctrl, mac, key); + write_cam_cache(adapter, id ,ctrl, mac, key); +#endif +} + +inline void clear_cam_entry(_adapter *adapter, u8 id) +{ + _clear_cam_entry(adapter, id); + clear_cam_cache(adapter, id); +} + +inline void write_cam_from_cache(_adapter *adapter, u8 id) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + struct sec_cam_ent cache; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + _rtw_memcpy(&cache, &dvobj->cam_cache[id], sizeof(struct sec_cam_ent)); + _exit_critical_bh(&cam_ctl->lock, &irqL); + + rtw_sec_write_cam_ent(adapter, id, cache.ctrl, cache.mac, cache.key); +} + +void write_cam_cache(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + + dvobj->cam_cache[id].ctrl = ctrl; + _rtw_memcpy(dvobj->cam_cache[id].mac, mac, ETH_ALEN); + _rtw_memcpy(dvobj->cam_cache[id].key, key, 16); + + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +void clear_cam_cache(_adapter *adapter, u8 id) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + + _rtw_memset(&(dvobj->cam_cache[id]), 0, sizeof(struct sec_cam_ent)); + + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +s16 rtw_get_camid(_adapter *adapter, struct sta_info *sta, s16 kid) +{ + u8 macid; + s16 camid; + + //cam_entry: + //0~3 for default key + + //for concurrent mode (ap+sta, sta+sta): + //default key is disable, using sw encrypt/decrypt + //camid 0, 1, 2, 3 is default entry for default key/group key + //macid = 1 is for bc/mc stainfo, no mapping to camid + //macid = 0 mapping to camid 4 + //for macid >=2, camid = macid+3; + + if (sta) { + struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info; + macid = sta->mac_id; + + if((mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { + if((macid == 1) || (macid>(NUM_STA-4))){ + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" failed, mac_id=%d\n", FUNC_ADPT_ARG(adapter), macid); + camid = -1; + goto exit; + } + } + + if(macid==0) + camid = 4; + else if(macid >=2) + camid = macid + 3; + else + camid = 4; + } + else { + /* default key is disabled */ + camid = -1; + } + +exit: + return (s16)camid; +} + +inline bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + + if (cam_ctl->sec_cap & cap) + return _TRUE; + return _FALSE; +} + +inline void _rtw_camctl_set_flags(_adapter *adapter, u32 flags) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + + cam_ctl->flags |= flags; +} + +inline void rtw_camctl_set_flags(_adapter *adapter, u32 flags) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + _rtw_camctl_set_flags(adapter, flags); + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +inline void _rtw_camctl_clr_flags(_adapter *adapter, u32 flags) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + + cam_ctl->flags &= ~flags; +} + +inline void rtw_camctl_clr_flags(_adapter *adapter, u32 flags) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + _rtw_camctl_clr_flags(adapter, flags); + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +inline bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + + if (cam_ctl->flags & flags) + return _TRUE; + return _FALSE; +} + +void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num) +{ + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m0); +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + if (max_num && max_num > 32) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m1); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + if (max_num && max_num > 64) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m2); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + if (max_num && max_num > 96) + DBG_871X_SEL_NL(sel, "0x%08x\n", map->m3); +#endif +} + +inline bool rtw_sec_camid_is_set(struct sec_cam_bmp *map, u8 id) +{ + if (id < 32) + return (map->m0 & BIT(id)); +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + else if (id < 64) + return (map->m1 & BIT(id - 32)); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + else if (id < 96) + return (map->m2 & BIT(id - 64)); +#endif +#if (SEC_CAM_ENT_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_sec_cam_map_set(struct sec_cam_bmp *map, u8 id) +{ + if (id < 32) + map->m0 |= BIT(id); +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + else if (id < 64) + map->m1 |= BIT(id - 32); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + else if (id < 96) + map->m2 |= BIT(id - 64); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + else if (id < 128) + map->m3 |= BIT(id - 96); +#endif + else + rtw_warn_on(1); +} + +inline void rtw_sec_cam_map_clr(struct sec_cam_bmp *map, u8 id) +{ + if (id < 32) + map->m0 &= ~BIT(id); +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + else if (id < 64) + map->m1 &= ~BIT(id-32); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + else if (id < 96) + map->m2 &= ~BIT(id-64); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + else if (id < 128) + map->m3 &= ~BIT(id-96); +#endif + else + rtw_warn_on(1); +} + +inline void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map) +{ + map->m0 = 0; +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + map->m1 = 0; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + map->m2 = 0; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + map->m3 = 0; +#endif +} + +inline bool rtw_sec_camid_is_drv_forbid(struct cam_ctl_t *cam_ctl, u8 id) +{ + struct sec_cam_bmp forbid_map; + + forbid_map.m0 = 0x00000ff0; +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + forbid_map.m1 = 0x00000000; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + forbid_map.m2 = 0x00000000; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + forbid_map.m3 = 0x00000000; +#endif + + if (id < 32) + return (forbid_map.m0 & BIT(id)); +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + else if (id < 64) + return (forbid_map.m1 & BIT(id - 32)); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + else if (id < 96) + return (forbid_map.m2 & BIT(id - 64)); +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + else if (id < 128) + return (forbid_map.m3 & BIT(id - 96)); +#endif + else + rtw_warn_on(1); + + return 1; +} + +bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id) +{ + bool ret = _FALSE; + + if (id >= cam_ctl->num) { + rtw_warn_on(1); + goto exit; + } + + #if 0 /* for testing */ + if (rtw_sec_camid_is_drv_forbid(cam_ctl, id)) { + ret = _TRUE; + goto exit; + } + #endif + + ret = rtw_sec_camid_is_set(&cam_ctl->used, id); + +exit: + return ret; +} + +inline bool rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id) +{ + _irqL irqL; + bool ret; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + ret = _rtw_sec_camid_is_used(cam_ctl, id); + _exit_critical_bh(&cam_ctl->lock, &irqL); + + return ret; +} + +inline bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + bool ret = _FALSE; + + if (cam_id >= cam_ctl->num) { + rtw_warn_on(1); + goto exit; + } + + if (_rtw_sec_camid_is_used(cam_ctl, cam_id) == _FALSE) + goto exit; + + ret = (dvobj->cam_cache[cam_id].ctrl&BIT6)?_TRUE:_FALSE; + +exit: + return ret; +} + +inline bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + bool ret; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + ret = _rtw_camid_is_gk(adapter, cam_id); + _exit_critical_bh(&cam_ctl->lock, &irqL); + + return ret; +} + +bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + bool ret = _FALSE; + + if (addr && _rtw_memcmp(dvobj->cam_cache[id].mac, addr, ETH_ALEN) == _FALSE) + goto exit; + if (kid >= 0 && kid != (dvobj->cam_cache[id].ctrl&0x03)) + goto exit; + if (gk != -1 && (gk?_TRUE:_FALSE) != _rtw_camid_is_gk(adapter, id)) + goto exit; + + ret = _TRUE; + +exit: + return ret; +} + +s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + int i; + s16 cam_id = -1; + + for (i = 0; i < cam_ctl->num; i++) { + if (cam_cache_chk(adapter, i, addr, kid, gk)) { + cam_id = i; + break; + } + } + + if (0) { + if (addr) + DBG_871X(FUNC_ADPT_FMT" addr:"MAC_FMT" kid:%d, gk:%d, return cam_id:%d\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid, gk, cam_id); + else + DBG_871X(FUNC_ADPT_FMT" addr:%p kid:%d, gk:%d, return cam_id:%d\n" + , FUNC_ADPT_ARG(adapter), addr, kid, gk, cam_id); + } + + return cam_id; +} + +s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + s16 cam_id = -1; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + cam_id = _rtw_camid_search(adapter, addr, kid, gk); + _exit_critical_bh(&cam_ctl->lock, &irqL); + + return cam_id; +} + +s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, bool *used) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + s16 cam_id = -1; + + *used = _FALSE; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + +#ifdef DYNAMIC_CAMID_ALLOC + { + struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info; + + if((((mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((mlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) + && !sta) { + /* AP/Ad-hoc mode group key: static alloction to default key by key ID */ + if (kid > 3) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with invalid key id:%u\n" + , FUNC_ADPT_ARG(adapter), kid); + rtw_warn_on(1); + goto bitmap_handle; + } + cam_id = kid; + } + else { + int i; + u8 *addr = sta?sta->hwaddr:NULL; + #if 0 /* for testing */ + static u8 start_id = 0; + #else + u8 start_id = 0; + #endif + + if(!sta) { + if (!(mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { + /* bypass STA mode group key setting before connected(ex:WEP) because bssid is not ready */ + goto bitmap_handle; + } + + addr = get_bssid(&adapter->mlmepriv); + } + + /* find cam entry which has the same addr, kid (, gk bit) */ + if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC) == _TRUE) + i = _rtw_camid_search(adapter, addr, kid, sta?_FALSE:_TRUE); + else + i = _rtw_camid_search(adapter, addr, kid, -1); + + if (i >= 0) { + cam_id = i; + goto bitmap_handle; + } + + for (i = 0; i < cam_ctl->num; i++) { + /* bypass default key which is allocated statically */ + if (((i + start_id) % cam_ctl->num) < 4) + continue; + + if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE) + break; + } + + if (i == cam_ctl->num) { + if (sta) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u no room\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid); + else + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u no room\n" + , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid); + rtw_warn_on(1); + goto bitmap_handle; + } + + cam_id = ((i + start_id) % cam_ctl->num); + start_id = ((i + start_id + 1) % cam_ctl->num); + } + } +#else + cam_id = rtw_get_camid(adapter, sta, kid); +#endif /* DYNAMIC_CAMID_ALLOC */ + +bitmap_handle: + if (cam_id >= 0) { + *used = _rtw_sec_camid_is_used(cam_ctl, cam_id); + rtw_sec_cam_map_set(&cam_ctl->used, cam_id); + } + + _exit_critical_bh(&cam_ctl->lock, &irqL); + + return cam_id; +} + +void rtw_camid_free(_adapter *adapter, u8 cam_id) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + _irqL irqL; + + _enter_critical_bh(&cam_ctl->lock, &irqL); + + if (cam_id < cam_ctl->num) + rtw_sec_cam_map_clr(&cam_ctl->used, cam_id); + + _exit_critical_bh(&cam_ctl->lock, &irqL); +} + +void flush_all_cam_entry(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE) + { + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)) + { + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; + + psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); + if(psta) { + if(psta->state & WIFI_AP_STATE) + {} //clear cam when ap free per sta_info + else { + rtw_clearstakey_cmd(padapter, psta, _FALSE); + } + } + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + /* clear default key */ + int i, cam_id; + u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0}; + + for (i=0;i<4;i++) { + cam_id = rtw_camid_search(padapter, null_addr, i, -1); + if (cam_id >= 0) { + clear_cam_entry(padapter, cam_id); + rtw_camid_free(padapter, cam_id); + } + } + + /* clear default key related key search setting */ + #ifdef DYNAMIC_CAMID_ALLOC + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_FALSE); + #endif + + /* leave pairwise key when ap free per sta_info */ + } + } + else +#endif //CONFIG_CONCURRENT_MODE + { + invalidate_cam_all(padapter); + /* clear default key related key search setting */ + #ifdef DYNAMIC_CAMID_ALLOC + rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_FALSE); + #endif + } +} + +#if defined(CONFIG_P2P) && defined(CONFIG_WFD) +void rtw_process_wfd_ie(_adapter *adapter, u8 *wfd_ie, u8 wfd_ielen, const char *tag) +{ + struct wifidirect_info *wdinfo = &adapter->wdinfo; + + u8 *attr_content; + u32 attr_contentlen = 0; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + return; + + DBG_871X("[%s] Found WFD IE\n", tag); + attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen); + if (attr_content && attr_contentlen) { + wdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16(attr_content + 2); + DBG_871X("[%s] Peer PORT NUM = %d\n", tag, wdinfo->wfd_info->peer_rtsp_ctrlport); + } +} + +void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag) +{ + u8 *wfd_ie; + u32 wfd_ielen; + + if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST)) + return; + + wfd_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &wfd_ielen); + while (wfd_ie) { + rtw_process_wfd_ie(adapter, wfd_ie, wfd_ielen, tag); + wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ies + ies_len) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen); + } +} +#endif /* defined(CONFIG_P2P) && defined(CONFIG_WFD) */ + +int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + //struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pmlmepriv->qospriv.qos_option==0) + { + pmlmeinfo->WMM_enable = 0; + return _FALSE; + } + + if(_rtw_memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element))) + { + return _FALSE; + } + else + { + _rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); + } + pmlmeinfo->WMM_enable = 1; + return _TRUE; + + /*if (pregpriv->wifi_spec == 1) + { + if (pmlmeinfo->WMM_enable == 1) + { + //todo: compare the parameter set count & decide wheher to update or not + return _FAIL; + } + else + { + pmlmeinfo->WMM_enable = 1; + _rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); + return _TRUE; + } + } + else + { + pmlmeinfo->WMM_enable = 0; + return _FAIL; + }*/ + +} + +void WMMOnAssocRsp(_adapter *padapter) +{ + u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime; + u8 acm_mask; + u16 TXOP; + u32 acParm, i; + u32 edca[4], inx[4]; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct registry_priv *pregpriv = &padapter->registrypriv; + + acm_mask = 0; + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || + (pmlmeext->cur_wireless_mode & WIRELESS_11_24N) ) + aSifsTime = 16; + else + aSifsTime = 10; + + if (pmlmeinfo->WMM_enable == 0) + { + padapter->mlmepriv.acm_mask = 0; + + AIFS = aSifsTime + (2 * pmlmeinfo->slotTime); + + if (pmlmeext->cur_wireless_mode & (WIRELESS_11G |WIRELESS_11A)) { + ECWMin = 4; + ECWMax = 10; + } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) { + ECWMin = 5; + ECWMax = 10; + } else { + ECWMin = 4; + ECWMax = 10; + } + + TXOP = 0; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); + + ECWMin = 2; + ECWMax = 3; + TXOP = 0x2f; + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); + } + else + { + edca[0] = edca[1] = edca[2] = edca[3] = 0; + + for (i = 0; i < 4; i++) + { + ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03; + ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01; + + //AIFS = AIFSN * slot time + SIFS - r2t phy delay + AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime; + + ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f); + ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4; + TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit); + + acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16); + + switch (ACI) + { + case 0x0: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(1):0); + edca[XMIT_BE_QUEUE] = acParm; + break; + + case 0x1: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm)); + //acm_mask |= (ACM? BIT(0):0); + edca[XMIT_BK_QUEUE] = acParm; + break; + + case 0x2: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(2):0); + edca[XMIT_VI_QUEUE] = acParm; + break; + + case 0x3: + rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm)); + acm_mask |= (ACM? BIT(3):0); + edca[XMIT_VO_QUEUE] = acParm; + break; + } + + DBG_871X("WMM(%x): %x, %x\n", ACI, ACM, acParm); + } + + if(padapter->registrypriv.acm_method == 1) + rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask)); + else + padapter->mlmepriv.acm_mask = acm_mask; + + inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; + + if(pregpriv->wifi_spec==1) + { + u32 j, tmp, change_inx=_FALSE; + + //entry indx: 0->vo, 1->vi, 2->be, 3->bk. + for(i=0; i<4; i++) + { + for(j=i+1; j<4; j++) + { + //compare CW and AIFS + if((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) + { + change_inx = _TRUE; + } + else if((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) + { + //compare TXOP + if((edca[j] >> 16) > (edca[i] >> 16)) + change_inx = _TRUE; + } + + if(change_inx) + { + tmp = edca[i]; + edca[i] = edca[j]; + edca[j] = tmp; + + tmp = inx[i]; + inx[i] = inx[j]; + inx[j] = tmp; + + change_inx = _FALSE; + } + } + } + } + + for(i=0; i<4; i++) { + pxmitpriv->wmm_para_seq[i] = inx[i]; + DBG_871X("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]); + } + } +} + +static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ +#ifdef CONFIG_80211N_HT + unsigned char new_bwmode; + unsigned char new_ch_offset; + struct HT_info_element *pHT_info; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + u8 cbw40_enable=0; + + if(!pIE) + return; + + if(phtpriv->ht_option == _FALSE) return; + + if(pmlmeext->cur_bwmode >= CHANNEL_WIDTH_80) return; + + if(pIE->Length > sizeof(struct HT_info_element)) + return; + + pHT_info = (struct HT_info_element *)pIE->data; + + if (hal_chk_bw_cap(padapter, BW_CAP_40M)) { + if (pmlmeext->cur_channel > 14) { + if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } else { + if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40)) + cbw40_enable = 1; + } + } + + if((pHT_info->infos[0] & BIT(2)) && cbw40_enable) + { + new_bwmode = CHANNEL_WIDTH_40; + + switch (pHT_info->infos[0] & 0x3) + { + case 1: + new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case 3: + new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + new_bwmode = CHANNEL_WIDTH_20; + new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + } + else + { + new_bwmode = CHANNEL_WIDTH_20; + new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + + if ((new_bwmode != pmlmeext->cur_bwmode || new_ch_offset != pmlmeext->cur_ch_offset) + && new_bwmode < pmlmeext->cur_bwmode + ) { + pmlmeinfo->bwmode_updated = _TRUE; + + pmlmeext->cur_bwmode = new_bwmode; + pmlmeext->cur_ch_offset = new_ch_offset; + + //update HT info also + HT_info_handler(padapter, pIE); + } + else + { + pmlmeinfo->bwmode_updated = _FALSE; + } + + + if(_TRUE == pmlmeinfo->bwmode_updated) + { + struct sta_info *psta; + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + struct sta_priv *pstapriv = &padapter->stapriv; + + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + + //update ap's stainfo + psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); + if(psta) + { + struct ht_priv *phtpriv_sta = &psta->htpriv; + + if(phtpriv_sta->ht_option) + { + // bwmode + psta->bw_mode = pmlmeext->cur_bwmode; + phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset; + } + else + { + psta->bw_mode = CHANNEL_WIDTH_20; + phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + } + + rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta); + } + + //pmlmeinfo->bwmode_updated = _FALSE;//bwmode_updated done, reset it! + } +#endif //CONFIG_80211N_HT +} + +void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ +#ifdef CONFIG_80211N_HT + unsigned int i; + u8 rf_type = RF_1T1R; + u8 max_AMPDU_len, min_MPDU_spacing; + u8 cur_ldpc_cap=0, cur_stbc_cap=0, cur_beamform_cap=0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + if(pIE==NULL) return; + + if(phtpriv->ht_option == _FALSE) return; + + pmlmeinfo->HT_caps_enable = 1; + + for (i = 0; i < (pIE->Length); i++) + { + if (i != 2) + { + // Commented by Albert 2010/07/12 + // Got the endian issue here. + pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]); + } + else + { + /* 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); + } + else + { + 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); + } + else + { + min_MPDU_spacing = (pIE->data[i] & 0x1c); + } + + pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; + } + } + + // Commented by Albert 2010/07/12 + // Have to handle the endian issue after copying. + // HT_ext_caps didn't be used yet. + pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info ); + pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps ); + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + + //update the MCS set + for (i = 0; i < 16; i++) + pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i]; + + //update the MCS rates + switch(rf_type) + { + case RF_1T1R: + case RF_1T2R: + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R); + break; + case RF_2T2R: + #ifdef CONFIG_DISABLE_MCS13TO15 + if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 ) + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF); + else + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R); +#else //CONFIG_DISABLE_MCS13TO15 + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R); +#endif //CONFIG_DISABLE_MCS13TO15 + break; + case RF_3T3R: + set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R); + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + } + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + // Config STBC setting + 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"); + } + phtpriv->stbc_cap = cur_stbc_cap; + +#ifdef CONFIG_BEAMFORMING + // Config Tx beamforming setting + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); + /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6); + } + + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4); + } + phtpriv->beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) { + DBG_871X("AP HT Beamforming Cap = 0x%02X\n", cur_beamform_cap); + } +#endif /*CONFIG_BEAMFORMING*/ + } else { + /*WIFI_STATION_STATEorI_ADHOC_STATE or WIFI_ADHOC_MASTER_STATE*/ + // Config LDPC Coding Capability + 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"); + } + phtpriv->ldpc_cap = cur_ldpc_cap; + + // Config STBC setting + 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"); + } + phtpriv->stbc_cap = cur_stbc_cap; + +#ifdef CONFIG_BEAMFORMING + // Config Tx beamforming setting + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE); + /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6); + } + + if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) + { + SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/ + SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4); + } + phtpriv->beamform_cap = cur_beamform_cap; + if (cur_beamform_cap) { + DBG_871X("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap); + } +#endif /*CONFIG_BEAMFORMING*/ + } + +#endif //CONFIG_80211N_HT +} + +void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ +#ifdef CONFIG_80211N_HT + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + + if(pIE==NULL) return; + + if(phtpriv->ht_option == _FALSE) return; + + + if(pIE->Length > sizeof(struct HT_info_element)) + return; + + pmlmeinfo->HT_info_enable = 1; + _rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length); +#endif //CONFIG_80211N_HT + return; +} + +void HTOnAssocRsp(_adapter *padapter) +{ + unsigned char max_AMPDU_len; + unsigned char min_MPDU_spacing; + //struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + DBG_871X("%s\n", __FUNCTION__); + + if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) + { + pmlmeinfo->HT_enable = 1; + } + else + { + pmlmeinfo->HT_enable = 0; + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + return; + } + + //handle A-MPDU parameter field + /* + AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k + AMPDU_para [4:2]:Min MPDU Start Spacing + */ + max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03; + + min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2; + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing)); + + rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len)); + +#if 0 //move to rtw_update_ht_cap() + if ((pregpriv->bw_mode > 0) && + (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && + (pmlmeinfo->HT_info.infos[0] & BIT(2))) + { + //switch to the 40M Hz mode accoring to the AP + pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; + switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) + { + case EXTCHNL_OFFSET_UPPER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + + case EXTCHNL_OFFSET_LOWER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); + } +#endif + + //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + +#if 0 //move to rtw_update_ht_cap() + // + // Config SM Power Save setting + // + pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2; + if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) + { + /*u8 i; + //update the MCS rates + for (i = 0; i < 16; i++) + { + pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i]; + }*/ + DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__); + } + + // + // Config current HT Protection mode. + // + pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; +#endif + +} + +void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if(pIE->Length>1) + return; + + pmlmeinfo->ERP_enable = 1; + _rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length); +} + +void VCS_update(_adapter *padapter, struct sta_info *psta) +{ + struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + switch (pregpriv->vrtl_carrier_sense)/* 0:off 1:on 2:auto */ + { + case 0: //off + psta->rtsen = 0; + psta->cts2self = 0; + break; + + case 1: //on + if (pregpriv->vcs_type == 1) /* 1:RTS/CTS 2:CTS to self */ + { + psta->rtsen = 1; + psta->cts2self = 0; + } + else + { + psta->rtsen = 0; + psta->cts2self = 1; + } + break; + + case 2: //auto + default: + if (((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) + /*||(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/ + ) { + if (pregpriv->vcs_type == 1) { + psta->rtsen = 1; + psta->cts2self = 0; + } else { + psta->rtsen = 0; + psta->cts2self = 1; + } + } else { + psta->rtsen = 0; + psta->cts2self = 0; + } + break; + } +} + +void update_ldpc_stbc_cap(struct sta_info *psta) +{ +#ifdef CONFIG_80211N_HT + +#ifdef CONFIG_80211AC_VHT + if (psta->vhtpriv.vht_option) { + if(TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX)) + psta->ldpc = 1; + + if(TEST_FLAG(psta->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX)) + psta->stbc = 1; + } + else +#endif //CONFIG_80211AC_VHT + if (psta->htpriv.ht_option) { + if(TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX)) + psta->ldpc = 1; + + if(TEST_FLAG(psta->htpriv.stbc_cap, STBC_HT_ENABLE_TX)) + psta->stbc = 1; + } else { + psta->ldpc = 0; + psta->stbc = 0; + } + +#endif //CONFIG_80211N_HT +} + + +/* + * 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; + struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network); + //u8 wpa_ie[255],rsn_ie[255]; + u16 wpa_len=0,rsn_len=0; + u8 encryp_protocol = 0; + WLAN_BSSID_EX *bssid; + int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0; + unsigned char *pbuf; + u32 wpa_ielen = 0; + u8 *pbssid = GetAddr3Ptr(pframe); + u32 hidden_ssid = 0; + u8 cur_network_type, network_type=0; + struct HT_info_element *pht_info = NULL; + struct rtw_ieee80211_ht_cap *pht_cap = NULL; + 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; + + len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr); + + if (len > MAX_IE_SZ) { + DBG_871X("%s IE too long for survey event\n", __func__); + return _FAIL; + } + + if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) { + DBG_871X("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT, + MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress)); + 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__); + return _TRUE; + } + + if ((pmlmepriv->timeBcnInfoChkStart != 0) && (rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart) > DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS)) + { + pmlmepriv->timeBcnInfoChkStart = 0; + pmlmepriv->NumOfBcnInfoChkFail = 0; + } + + subtype = GetFrameSubType(pframe) >> 4; + + if(subtype==WIFI_BEACON) + bssid->Reserved[0] = 1; + + bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len; + + /* below is to copy the information element */ + bssid->IELength = len; + _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength); + + /* check bw and channel offset */ + /* parsing HT_CAP_IE */ + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if(p && len>0) { + pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2); + ht_cap_info = pht_cap->cap_info; + } else { + ht_cap_info = 0; + } + /* parsing HT_INFO_IE */ + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if(p && len>0) { + pht_info = (struct HT_info_element *)(p + 2); + ht_info_infos_0 = pht_info->infos[0]; + } else { + ht_info_infos_0 = 0; + } + if (ht_cap_info != cur_network->BcnInfo.ht_cap_info || + ((ht_info_infos_0&0x03) != (cur_network->BcnInfo.ht_info_infos_0&0x03))) { + DBG_871X("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__, + ht_cap_info, ht_info_infos_0); + 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); + DBG_871X("%s bw mode change\n", __func__); + { + //bcn_info_update + cur_network->BcnInfo.ht_cap_info = ht_cap_info; + cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0; + //to do : need to check that whether modify related register of BB or not + } + //goto _mismatch; + } + + /* Checking for channel */ + p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if (p) { + bcn_channel = *(p + 2); + } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */ + rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); + if(pht_info) { + 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__); + bcn_channel = Adapter->mlmeextpriv.cur_channel; + } + } + if (bcn_channel != Adapter->mlmeextpriv.cur_channel) { + DBG_871X("%s beacon channel:%d cur channel:%d disconnect\n", __func__, + bcn_channel, Adapter->mlmeextpriv.cur_channel); + goto _mismatch; + } + + /* checking SSID */ + if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL) { + DBG_871X("%s marc: cannot find SSID for survey event\n", __func__); + hidden_ssid = _TRUE; + } else { + hidden_ssid = _FALSE; + } + + if((NULL != p) && (_FALSE == hidden_ssid && (*(p + 1)))) { + _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); + bssid->Ssid.SsidLength = *(p + 1); + } else { + bssid->Ssid.SsidLength = 0; + bssid->Ssid.Ssid[0] = '\0'; + } + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d " + "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid, + bssid->Ssid.SsidLength, cur_network->network.Ssid.Ssid, + cur_network->network.Ssid.SsidLength)); + + if (_rtw_memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) == _FALSE || + bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) { + if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */ + DBG_871X("%s(), SSID is not match\n", __func__); + goto _mismatch; + } + } + + /* check encryption info */ + val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid); + + if (val16 & BIT(4)) + bssid->Privacy = 1; + else + bssid->Privacy = 0; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_, + ("%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n", + __func__, cur_network->network.Privacy,bssid->Privacy)); + if (cur_network->network.Privacy != bssid->Privacy) { + DBG_871X("%s(), privacy is not match\n",__func__); + goto _mismatch; + } + + rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL,&rsn_len,NULL,&wpa_len); + + if (rsn_len > 0) { + encryp_protocol = ENCRYP_PROTOCOL_WPA2; + } else if (wpa_len > 0) { + encryp_protocol = ENCRYP_PROTOCOL_WPA; + } else { + if (bssid->Privacy) + encryp_protocol = ENCRYP_PROTOCOL_WEP; + } + + if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) { + DBG_871X("%s(): enctyp is not match\n",__func__); + goto _mismatch; + } + + if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) { + pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12); + if(pbuf && (wpa_ielen>0)) { + if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_, + ("%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n", __func__, + pairwise_cipher, group_cipher, is_8021x)); + } + } else { + pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12); + + if(pbuf && (wpa_ielen>0)) { + if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) { + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_, + ("%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher is %d, is_802x is %d\n", + __func__, pairwise_cipher, group_cipher, is_8021x)); + } + } + } + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_, + ("%s cur_network->group_cipher is %d: %d\n",__func__, cur_network->BcnInfo.group_cipher, group_cipher)); + if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) { + DBG_871X("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match\n",__func__, + pairwise_cipher, cur_network->BcnInfo.pairwise_cipher, + group_cipher, cur_network->BcnInfo.group_cipher); + goto _mismatch; + } + + if (is_8021x != cur_network->BcnInfo.is_8021x) { + DBG_871X("%s authentication is not match\n", __func__); + goto _mismatch; + } + } + + rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX)); + return _SUCCESS; + +_mismatch: + rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX)); + + if (pmlmepriv->NumOfBcnInfoChkFail == 0) + { + pmlmepriv->timeBcnInfoChkStart = rtw_get_current_time(); + } + + pmlmepriv->NumOfBcnInfoChkFail++; + DBG_871X("%s by "ADPT_FMT" - NumOfChkFail = %d (SeqNum of this Beacon frame = %d).\n", __func__, ADPT_ARG(Adapter), pmlmepriv->NumOfBcnInfoChkFail, GetSequence(pframe)); + + if ((pmlmepriv->timeBcnInfoChkStart != 0) && (rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart) <= DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS) + && (pmlmepriv->NumOfBcnInfoChkFail >= DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD)) + { + DBG_871X("%s by "ADPT_FMT" - NumOfChkFail = %d >= threshold : %d (in %d ms), return FAIL.\n", __func__, ADPT_ARG(Adapter), pmlmepriv->NumOfBcnInfoChkFail, + DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD, rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart)); + pmlmepriv->timeBcnInfoChkStart = 0; + pmlmepriv->NumOfBcnInfoChkFail = 0; + return _FAIL; + } + + return _SUCCESS; +#endif +} + +void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta) +{ + unsigned int i; + unsigned int len; + PNDIS_802_11_VARIABLE_IEs pIE; + +#ifdef CONFIG_TDLS + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; //bit(38): TDLS_prohibited +#endif //CONFIG_TDLS + + len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); + + for (i = 0; i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + //to update WMM paramter set while receiving beacon + if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6) && pIE->Length == WLAN_WMM_LEN) //WMM + { + (WMM_param_handler(padapter, pIE))? report_wmm_edca_update(padapter): 0; + } + + break; + + case _HT_EXTRA_INFO_IE_: //HT info + //HT_info_handler(padapter, pIE); + bwmode_update_check(padapter, pIE); + break; +#ifdef CONFIG_80211AC_VHT + case EID_OpModeNotification: + rtw_process_vht_op_mode_notify(padapter, pIE->data, psta); + break; +#endif //CONFIG_80211AC_VHT + case _ERPINFO_IE_: + ERP_IE_handler(padapter, pIE); + VCS_update(padapter, psta); + break; + +#ifdef CONFIG_TDLS + case _EXT_CAP_IE_: + if( check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE ) + ptdlsinfo->ap_prohibited = _TRUE; + if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE) + ptdlsinfo->ch_switch_prohibited = _TRUE; + break; +#endif //CONFIG_TDLS + default: + break; + } + + i += (pIE->Length + 2); + } +} + +#ifdef CONFIG_DFS +void process_csa_ie(_adapter *padapter, u8 *pframe, uint pkt_len) +{ + unsigned int i; + unsigned int len; + PNDIS_802_11_VARIABLE_IEs pIE; + u8 new_ch_no = 0; + + if(padapter->mlmepriv.handle_dfs == _TRUE ) + return; + + len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN); + + for (i = 0; i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i); + + switch (pIE->ElementID) + { + case _CH_SWTICH_ANNOUNCE_: + padapter->mlmepriv.handle_dfs = _TRUE; + _rtw_memcpy(&new_ch_no, pIE->data+1, 1); + rtw_set_csa_cmd(padapter, new_ch_no); + break; + default: + break; + } + + i += (pIE->Length + 2); + } +} +#endif //CONFIG_DFS + +unsigned int is_ap_in_tkip(_adapter *padapter) +{ + u32 i; + PNDIS_802_11_VARIABLE_IEs pIE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + + if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) + { + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))) + { + return _TRUE; + } + break; + + case _RSN_IE_2_: + if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4)) + { + return _TRUE; + } + + default: + break; + } + + i += (pIE->Length + 2); + } + + return _FALSE; + } + else + { + return _FALSE; + } + +} + +unsigned int should_forbid_n_rate(_adapter * padapter) +{ + u32 i; + PNDIS_802_11_VARIABLE_IEs pIE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + WLAN_BSSID_EX *cur_network = &pmlmepriv->cur_network.network; + + if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) + { + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < cur_network->IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(cur_network->IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4) && + ((_rtw_memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) || + (_rtw_memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4)))) + return _FALSE; + break; + + case _RSN_IE_2_: + if ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4)) || + (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4))) + return _FALSE; + + default: + break; + } + + i += (pIE->Length + 2); + } + + return _TRUE; + } + else + { + return _FALSE; + } + +} + + +unsigned int is_ap_in_wep(_adapter *padapter) +{ + u32 i; + PNDIS_802_11_VARIABLE_IEs pIE; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + + if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) + { + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) + return _FALSE; + break; + + case _RSN_IE_2_: + return _FALSE; + + default: + break; + } + + i += (pIE->Length + 2); + } + + return _TRUE; + } + else + { + return _FALSE; + } + +} + +int wifirate2_ratetbl_inx(unsigned char rate); +int wifirate2_ratetbl_inx(unsigned char rate) +{ + int inx = 0; + rate = rate & 0x7f; + + switch (rate) + { + case 54*2: + inx = 11; + break; + + case 48*2: + inx = 10; + break; + + case 36*2: + inx = 9; + break; + + case 24*2: + inx = 8; + break; + + case 18*2: + inx = 7; + break; + + case 12*2: + inx = 6; + break; + + case 9*2: + inx = 5; + break; + + case 6*2: + inx = 4; + break; + + case 11*2: + inx = 3; + break; + case 11: + inx = 2; + break; + + case 2*2: + inx = 1; + break; + + case 1*2: + inx = 0; + break; + + } + return inx; +} + +unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz) +{ + unsigned int i, num_of_rate; + unsigned int mask = 0; + + num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz; + + for (i = 0; i < num_of_rate; i++) + { + if ((*(ptn + i)) & 0x80) + { + mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); + } + } + return mask; +} + +unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz) +{ + unsigned int i, num_of_rate; + unsigned int mask = 0; + + num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz; + + for (i = 0; i < num_of_rate; i++) + { + mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i)); + } + + return mask; +} + +unsigned int update_MCS_rate(struct HT_caps_element *pHT_caps) +{ + unsigned int mask = 0; + + mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20)); + + return mask; +} + +int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode) +{ + unsigned char bit_offset; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + if (!(pmlmeinfo->HT_enable)) + return _FAIL; + + bit_offset = (bwmode & CHANNEL_WIDTH_40)? 6: 5; + + if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset)) + { + return _SUCCESS; + } + else + { + return _FAIL; + } +} + +unsigned char get_highest_rate_idx(u32 mask) +{ + int i; + unsigned char rate_idx=0; + + for(i=31; i>=0; i--) + { + if(mask & BIT(i)) + { + rate_idx = i; + break; + } + } + + return rate_idx; +} + +unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps); +unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps) +{ + int i, mcs_rate; + + mcs_rate = (pHT_caps->u.HT_cap_element.MCS_rate[0] | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 8)); + + for (i = 15; i >= 0; i--) + { + if (mcs_rate & (0x1 << i)) + { + break; + } + } + + return i; +} + +void Update_RA_Entry(_adapter *padapter, struct sta_info *psta) +{ + rtw_hal_update_ra_mask(psta, psta->rssi_level); +} + +void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta); +void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta) +{ + Update_RA_Entry(padapter, psta); +} + +void set_sta_rate(_adapter *padapter, struct sta_info *psta) +{ + //rate adaptive + enable_rate_adaptive(padapter, psta); +} + +// Update RRSR and Rate for USERATE +void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode) +{ + NDIS_802_11_RATES_EX supported_rates; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; + + // Added by Albert 2011/03/22 + // In the P2P mode, the driver should not support the b mode. + // So, the Tx packet shouldn't use the CCK rate + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + return; +#endif //CONFIG_P2P +#ifdef CONFIG_INTEL_WIDI + if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE) + return; +#endif //CONFIG_INTEL_WIDI + + _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX); + + //clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band. + if(pmlmeext->cur_channel > 14) + wirelessmode &= ~(WIRELESS_11B); + + if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) { + _rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4); + } else if (wirelessmode & WIRELESS_11B) { + _rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7); + } else { + _rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3); + } + + if (wirelessmode & WIRELESS_11B) + update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); + else + update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); + + rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates); +} + +unsigned char check_assoc_AP(u8 *pframe, uint len) +{ + unsigned int i; + PNDIS_802_11_VARIABLE_IEs pIE; + + for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) + { + pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i); + + switch (pIE->ElementID) + { + case _VENDOR_SPECIFIC_IE_: + if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3))) + { + DBG_871X("link to Artheros AP\n"); + return HT_IOT_PEER_ATHEROS; + } + else if ( (_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3)) + || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3)) + || (_rtw_memcmp(pIE->data, BROADCOM_OUI3, 3))) + { + DBG_871X("link to Broadcom AP\n"); + return HT_IOT_PEER_BROADCOM; + } + else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3)) + { + DBG_871X("link to Marvell AP\n"); + return HT_IOT_PEER_MARVELL; + } + else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3)) + { + DBG_871X("link to Ralink AP\n"); + return HT_IOT_PEER_RALINK; + } + else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3)) + { + DBG_871X("link to Cisco AP\n"); + return HT_IOT_PEER_CISCO; + } + else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3)) + { + u32 Vender = HT_IOT_PEER_REALTEK; + + if(pIE->Length >= 5) { + if(pIE->data[4]==1) + { + //if(pIE->data[5] & RT_HT_CAP_USE_LONG_PREAMBLE) + // bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_LONG_PREAMBLE; + + if(pIE->data[5] & RT_HT_CAP_USE_92SE) + { + //bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; + Vender = HT_IOT_PEER_REALTEK_92SE; + } + } + + if(pIE->data[5] & RT_HT_CAP_USE_SOFTAP) + Vender = HT_IOT_PEER_REALTEK_SOFTAP; + + if(pIE->data[4] == 2) + { + if(pIE->data[6] & RT_HT_CAP_USE_JAGUAR_BCUT) { + Vender = HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP; + DBG_871X("link to Realtek JAGUAR_BCUTAP\n"); + } + if(pIE->data[6] & RT_HT_CAP_USE_JAGUAR_CCUT) { + Vender = HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP; + DBG_871X("link to Realtek JAGUAR_CCUTAP\n"); + } + } + } + + DBG_871X("link to Realtek AP\n"); + return Vender; + } + else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI,3)) + { + DBG_871X("link to Airgo Cap\n"); + return HT_IOT_PEER_AIRGO; + } + else + { + break; + } + + default: + break; + } + + i += (pIE->Length + 2); + } + + DBG_871X("link to new AP\n"); + return HT_IOT_PEER_UNKNOWN; +} + +void update_capinfo(PADAPTER Adapter, u16 updateCap) +{ + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + BOOLEAN ShortPreamble; + + // Check preamble mode, 2005.01.06, by rcnjko. + // Mark to update preamble value forever, 2008.03.18 by lanhsin + //if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO ) + { + + if(updateCap & cShortPreamble) + { // Short Preamble + if(pmlmeinfo->preamble_mode != PREAMBLE_SHORT) // PREAMBLE_LONG or PREAMBLE_AUTO + { + ShortPreamble = _TRUE; + pmlmeinfo->preamble_mode = PREAMBLE_SHORT; + rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble ); + } + } + else + { // Long Preamble + if(pmlmeinfo->preamble_mode != PREAMBLE_LONG) // PREAMBLE_SHORT or PREAMBLE_AUTO + { + ShortPreamble = _FALSE; + pmlmeinfo->preamble_mode = PREAMBLE_LONG; + rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble ); + } + } + } + + if ( updateCap & cIBSS ) { + //Filen: See 802.11-2007 p.91 + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + else + { + //Filen: See 802.11-2007 p.90 + if( pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC)) + { + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + } + else if( pmlmeext->cur_wireless_mode & (WIRELESS_11G)) + { + if( (updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */) + { // Short Slot Time + pmlmeinfo->slotTime = SHORT_SLOT_TIME; + } + else + { // Long Slot Time + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + } + else + { + //B Mode + pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME; + } + } + + rtw_hal_set_hwreg( Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime ); + +} + +/* +* set adapter.mlmeextpriv.mlmext_info.HT_enable +* set adapter.mlmeextpriv.cur_wireless_mode +* set SIFS register +* set mgmt tx rate +*/ +void update_wireless_mode(_adapter *padapter) +{ + int ratelen, network_type = 0; + u32 SIFS_Timer; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + unsigned char *rate = cur_network->SupportedRates; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + + ratelen = rtw_get_rateset_len(cur_network->SupportedRates); + + if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) + { + pmlmeinfo->HT_enable = 1; + } + + if(pmlmeext->cur_channel > 14) + { + if (pmlmeinfo->VHT_enable) + network_type = WIRELESS_11AC; + else if (pmlmeinfo->HT_enable) + network_type = WIRELESS_11_5N; + + network_type |= WIRELESS_11A; + } + else + { + if (pmlmeinfo->VHT_enable) + network_type = WIRELESS_11AC; + else if (pmlmeinfo->HT_enable) + network_type = WIRELESS_11_24N; + + if ((cckratesonly_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11B; + } + else if((cckrates_included(rate, ratelen)) == _TRUE) + { + network_type |= WIRELESS_11BG; + } + else + { + network_type |= WIRELESS_11G; + } + } + + pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode; + /* DBG_871X("network_type=%02x, padapter->registrypriv.wireless_mode=%02x\n", network_type, padapter->registrypriv.wireless_mode); */ +/* + if((pmlmeext->cur_wireless_mode==WIRELESS_11G) || + (pmlmeext->cur_wireless_mode==WIRELESS_11BG))//WIRELESS_MODE_G) + SIFS_Timer = 0x0a0a;//CCK + else + SIFS_Timer = 0x0e0e;//pHalData->SifsTime; //OFDM +*/ + + SIFS_Timer = 0x0a0a0808; //0x0808 -> for CCK, 0x0a0a -> for OFDM + //change this value if having IOT issues. + + rtw_hal_set_hwreg( padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer); + + rtw_hal_set_hwreg( padapter, HW_VAR_WIRELESS_MODE, (u8 *)&(pmlmeext->cur_wireless_mode)); + + if ((pmlmeext->cur_wireless_mode & WIRELESS_11B) +#ifdef CONFIG_P2P + && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) +#endif /* CONFIG_P2P */ + ) + update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB); + else + update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB); +} + +void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value); +void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value) +{ +#if 0 + struct cmd_obj *ph2c; + struct reg_rw_parm *pwriteMacPara; + struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + + if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL) + { + return; + } + + if ((pwriteMacPara = (struct reg_rw_parm*)rtw_malloc(sizeof(struct reg_rw_parm))) == NULL) + { + rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); + return; + } + + pwriteMacPara->rw = 1; + pwriteMacPara->addr = addr; + pwriteMacPara->value = value; + + init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG)); + rtw_enqueue_cmd(pcmdpriv, ph2c); +#endif +} + +void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode) +{ + if(IsSupportedTxCCK(wireless_mode)) + { + // Only B, B/G, and B/G/N AP could use CCK rate + _rtw_memcpy(psta->bssrateset, rtw_basic_rate_cck, 4); + psta->bssratelen = 4; + } + else + { + _rtw_memcpy(psta->bssrateset, rtw_basic_rate_ofdm, 3); + psta->bssratelen = 3; + } +} + +int rtw_ies_get_supported_rate(u8 *ies, uint ies_len, u8 *rate_set, u8 *rate_num) +{ + u8 *ie; + unsigned int ie_len; + + if (!rate_set || !rate_num) + return _FALSE; + + *rate_num = 0; + + ie = rtw_get_ie(ies, _SUPPORTEDRATES_IE_, &ie_len, ies_len); + if (ie == NULL) + goto ext_rate; + + _rtw_memcpy(rate_set, ie + 2, ie_len); + *rate_num = ie_len; + +ext_rate: + ie = rtw_get_ie(ies, _EXT_SUPPORTEDRATES_IE_, &ie_len, ies_len); + if (ie) { + _rtw_memcpy(rate_set + *rate_num, ie + 2, ie_len); + *rate_num += ie_len; + } + + if (*rate_num == 0) + return _FAIL; + + if (0) { + int i; + + for (i = 0; i < *rate_num; i++) + DBG_871X("rate:0x%02x\n", *(rate_set + i)); + } + + return _SUCCESS; +} + +void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr) +{ + struct sta_info *psta; + u16 tid, start_seq, param; + struct recv_reorder_ctrl *preorder_ctrl; + struct sta_priv *pstapriv = &padapter->stapriv; + struct ADDBA_request *preq = (struct ADDBA_request*)paddba_req; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u8 size; + + psta = rtw_get_stainfo(pstapriv, addr); + if (!psta) + goto exit; + + start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4; + + param = le16_to_cpu(preq->BA_para_set); + tid = (param>>2)&0x0f; + + preorder_ctrl = &psta->recvreorder_ctrl[tid]; + + #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ + preorder_ctrl->indicate_seq = start_seq; + #ifdef DBG_RX_SEQ + DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__, + preorder_ctrl->indicate_seq, start_seq); + #endif + #else + preorder_ctrl->indicate_seq = 0xffff; + #endif + + preorder_ctrl->enable = rtw_rx_ampdu_is_accept(padapter); + size = rtw_rx_ampdu_size(padapter); + + if (preorder_ctrl->enable == _TRUE) { + preorder_ctrl->ampdu_size = size; + issue_addba_rsp(padapter, addr, tid, 0, size); + } else { + issue_addba_rsp(padapter, addr, tid, 37, size); /* reject ADDBA Req */ + } + +exit: + return; +} + +void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) +{ + u8* pIE; + u32 *pbuf; + + pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + pbuf = (u32*)pIE; + + pmlmeext->TSFValue = le32_to_cpu(*(pbuf+1)); + + pmlmeext->TSFValue = pmlmeext->TSFValue << 32; + + pmlmeext->TSFValue |= le32_to_cpu(*pbuf); +} + +void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext) +{ + rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, 0); +} + +void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len) +{ + int i; + u8* pIE; + u32 *pbuf; + u64 tsf=0; + u32 delay_ms; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + + pmlmeext->bcn_cnt++; + + pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + pbuf = (u32*)pIE; + + tsf = le32_to_cpu(*(pbuf+1)); + tsf = tsf << 32; + tsf |= le32_to_cpu(*pbuf); + + //DBG_871X("%s(): tsf_upper= 0x%08x, tsf_lower=0x%08x\n", __func__, (u32)(tsf>>32), (u32)tsf); + + //delay = (timestamp mod 1024*100)/1000 (unit: ms) + //delay_ms = do_div(tsf, (pmlmeinfo->bcn_interval*1024))/1000; + delay_ms = rtw_modular64(tsf, (pmlmeinfo->bcn_interval*1024)); + delay_ms = delay_ms/1000; + + if(delay_ms >= 8) + { + pmlmeext->bcn_delay_cnt[8]++; + //pmlmeext->bcn_delay_ratio[8] = (pmlmeext->bcn_delay_cnt[8] * 100) /pmlmeext->bcn_cnt; + } + else + { + pmlmeext->bcn_delay_cnt[delay_ms]++; + //pmlmeext->bcn_delay_ratio[delay_ms] = (pmlmeext->bcn_delay_cnt[delay_ms] * 100) /pmlmeext->bcn_cnt; + } + +/* + DBG_871X("%s(): (a)bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt); + + + for(i=0; i<9; 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]); + } +*/ + + //dump for adaptive_early_32k + if(pmlmeext->bcn_cnt > 100 && (pmlmeext->adaptive_tsf_done==_TRUE)) + { + u8 ratio_20_delay, ratio_80_delay; + u8 DrvBcnEarly, DrvBcnTimeOut; + + ratio_20_delay = 0; + ratio_80_delay = 0; + DrvBcnEarly = 0xff; + DrvBcnTimeOut = 0xff; + + 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]); + + ratio_20_delay += pmlmeext->bcn_delay_ratio[i]; + ratio_80_delay += pmlmeext->bcn_delay_ratio[i]; + + if(ratio_20_delay > 20 && DrvBcnEarly == 0xff) + { + DrvBcnEarly = i; + //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); + } + + //reset adaptive_early_32k cnt + pmlmeext->bcn_delay_cnt[i] = 0; + pmlmeext->bcn_delay_ratio[i] = 0; + } + + pmlmeext->DrvBcnEarly = DrvBcnEarly; + pmlmeext->DrvBcnTimeOut = DrvBcnTimeOut; + + pmlmeext->bcn_cnt = 0; + } + +} + + +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; + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + 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, adapter_mac_addr(padapter), ETH_ALEN)) { + psta->mac_id = macid_ctl->num; + 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); + macid_ctl->sta[1] = psta; + /* TODO ch_g? */ + _exit_critical_bh(&macid_ctl->lock, &irqL); + i = 1; + goto assigned; + } +#endif + + _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; + } + + 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); + macid_ctl->sta[i] = psta; + + /* TODO ch_g? */ + + last_id++; + last_id %= macid_ctl->num; + } + + _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) +{ + _irqL irqL; + u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + + if (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), ETH_ALEN)) + return; + +#ifdef CONFIG_SHARED_BMC_MACID + if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) + return; + + 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(&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); + macid_ctl->sta[psta->mac_id] = NULL; + } + + _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 *dvobj = adapter_to_dvobj(padapter); + struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj); + int i; + _irqL irqL; + + /* TODO: Only search for connected macid? */ + + _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; + + return max_mac_id; +} + +inline void rtw_macid_ctl_set_h2c_msr(struct macid_ctl_t *macid_ctl, u8 id, u8 h2c_msr) +{ + if (id >= macid_ctl->num) { + rtw_warn_on(1); + return; + } + + macid_ctl->h2c_msr[id] = h2c_msr; + if (0) + DBG_871X("macid:%u, h2c_msr:"H2C_MSR_FMT"\n", id, H2C_MSR_ARG(&macid_ctl->h2c_msr[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) +{ + unsigned short ATIMWindow; + unsigned char *pframe; + struct tx_desc *ptxdesc; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + unsigned int rate_len, len = 0; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + 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}; + + _rtw_memset(beacon_frame, 0, 256); + + pframe = beacon_frame + TXDESC_SIZE; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); + + SetFrameSubType(pframe, WIFI_BEACON); + + pframe += sizeof(struct rtw_ieee80211_hdr_3addr); + len = sizeof(struct rtw_ieee80211_hdr_3addr); + + //timestamp will be inserted by hardware + pframe += 8; + len += 8; + + // beacon interval: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); + + pframe += 2; + len += 2; + + // capability info: 2 bytes + _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); + + pframe += 2; + len += 2; + + // SSID + pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len); + + // 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, &len); + + // DS parameter set + pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len); + + // IBSS Parameter Set... + //ATIMWindow = cur->Configuration.ATIMWindow; + ATIMWindow = 0; + pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len); + + //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), &len); + } + + if ((len + TXDESC_SIZE) > 256) + { + //DBG_871X("marc: beacon frame too large\n"); + return 0; + } + + //fill the tx descriptor + ptxdesc = (struct tx_desc *)beacon_frame; + + //offset 0 + ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff); + ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); //default = 32 bytes for TX Desc + + //offset 4 + ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00); + + //offset 8 + ptxdesc->txdw2 |= cpu_to_le32(BMC); + ptxdesc->txdw2 |= cpu_to_le32(BK); + + //offset 16 + ptxdesc->txdw4 = 0x80000000; + + //offset 20 + ptxdesc->txdw5 = 0x00000000; //1M + + return (len + TXDESC_SIZE); +} +#endif + +_adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj) +{ + _adapter *port0_iface = NULL; + int i; + for (i=0;iiface_nums;i++) { + if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) + break; + } + + if (i<0 || i>=dvobj->iface_nums) + rtw_warn_on(1); + else + port0_iface = dvobj->padapters[i]; + + return port0_iface; +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct in_device *my_ip_ptr = padapter->pnetdev->ip_ptr; + u8 ipaddress[4]; + + if ( (pmlmeinfo->state & WIFI_FW_LINKING_STATE) || + pmlmeinfo->state & WIFI_FW_AP_STATE) { + if ( my_ip_ptr != NULL ) { + struct in_ifaddr *my_ifa_list = my_ip_ptr->ifa_list ; + if ( my_ifa_list != NULL ) { + ipaddress[0] = my_ifa_list->ifa_address & 0xFF; + ipaddress[1] = (my_ifa_list->ifa_address >> 8) & 0xFF; + ipaddress[2] = (my_ifa_list->ifa_address >> 16) & 0xFF; + ipaddress[3] = my_ifa_list->ifa_address >> 24; + DBG_871X("%s: %d.%d.%d.%d ==========\n", __func__, + ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]); + _rtw_memcpy(pcurrentip, ipaddress, 4); + } + } + } +} +#endif +#ifdef CONFIG_WOWLAN +bool rtw_check_pattern_valid(u8 *input, u8 len) +{ + int i = 0; + bool res = _FALSE; + + if (len != 2) + goto exit; + + for (i = 0 ; i < len ; i++) + if (IsHexDigit(input[i]) == _FALSE) + goto exit; + + res = _SUCCESS; + +exit: + return res; +} + +bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx) +{ + u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0; + u16 offset, rx_buf_ptr = 0; + u16 cam_start_offset = 0; + u16 ctrl_l = 0, ctrl_h = 0; + u8 count = 0, tmp = 0; + int i = 0; + bool res = _TRUE; + + if (idx > MAX_WKFM_NUM) { + DBG_871X("[Error]: %s, pattern index is out of range\n", + __func__); + return _FALSE; + } + + rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW, + (u8 *)&rx_dma_buff_sz); + + if (rx_dma_buff_sz == 0) { + DBG_871X("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__); + return _FALSE; + } + + rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz); + + if (page_sz == 0) { + DBG_871X("[Error]: %s, page_sz is 0!!\n", __func__); + return _FALSE; + } + + offset = (u16)PageNum(rx_dma_buff_sz, page_sz); + cam_start_offset = offset * page_sz; + + ctrl_l = 0x0; + ctrl_h = 0x0; + + /* Enable RX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT); + + /* Read the WKFM CAM */ + for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) { + /* + * Set Rx packet buffer offset. + * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer. + * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE + * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8 + * * Index: The index of the wake up frame mask + * * WKFMCAM_SIZE: the total size of one WKFM CAM + * * per entry offset of a WKFM CAM: Addr i * 4 bytes + */ + rx_buf_ptr = + (cam_start_offset + idx*WKFMCAM_SIZE + i*8) >> 3; + rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr); + + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l); + data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L); + data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H); + + DBG_871X("[%d]: %08x %08x\n", i, data_h, data_l); + + count = 0; + + do { + tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL); + rtw_udelay_os(2); + count++; + } while (!tmp && count < 100); + + if (count >= 100) { + DBG_871X("%s count:%d\n", __func__, count); + res = _FALSE; + } + } + + /* Disable RX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, + DISABLE_TRXPKT_BUF_ACCESS); + return res; +} + +bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, + struct rtl_wow_pattern *context) +{ + u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0; + u16 offset, rx_buf_ptr = 0; + u16 cam_start_offset = 0; + u16 ctrl_l = 0, ctrl_h = 0; + u8 count = 0, tmp = 0; + int res = 0, i = 0; + + if (idx > MAX_WKFM_NUM) { + DBG_871X("[Error]: %s, pattern index is out of range\n", + __func__); + return _FALSE; + } + + rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW, + (u8 *)&rx_dma_buff_sz); + + if (rx_dma_buff_sz == 0) { + DBG_871X("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__); + return _FALSE; + } + + rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz); + + if (page_sz == 0) { + DBG_871X("[Error]: %s, page_sz is 0!!\n", __func__); + return _FALSE; + } + + offset = (u16)PageNum(rx_dma_buff_sz, page_sz); + + cam_start_offset = offset * page_sz; + + if (IS_HARDWARE_TYPE_8188E(adapter)) { + ctrl_l = 0x0001; + ctrl_h = 0x0001; + } else { + ctrl_l = 0x0f01; + ctrl_h = 0xf001; + } + + /* Enable RX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT); + + /* Write the WKFM CAM */ + for (i = 0; i < WKFMCAM_ADDR_NUM; i++) { + /* + * Set Rx packet buffer offset. + * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer. + * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE + * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8 + * * Index: The index of the wake up frame mask + * * WKFMCAM_SIZE: the total size of one WKFM CAM + * * per entry offset of a WKFM CAM: Addr i * 4 bytes + */ + rx_buf_ptr = + (cam_start_offset + idx*WKFMCAM_SIZE + i*4) >> 3; + rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr); + + if (i == 0) { + if (context->type == PATTERN_VALID) + data = BIT(31); + else if (context->type == PATTERN_BROADCAST) + data = BIT(31) | BIT(26); + else if (context->type == PATTERN_MULTICAST) + data = BIT(31) | BIT(25); + else if (context->type == PATTERN_UNICAST) + data = BIT(31) | BIT(24); + + if (context->crc != 0) + data |= context->crc; + + rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data); + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l); + } else if (i == 1) { + data = 0; + rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data); + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h); + } else if (i == 2 || i == 4) { + data = context->mask[i - 2]; + rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data); + /* write to RX packet buffer*/ + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l); + } else if (i == 3 || i == 5) { + data = context->mask[i - 2]; + rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data); + /* write to RX packet buffer*/ + rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h); + } + + count = 0; + do { + tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL); + rtw_udelay_os(2); + count++; + } while (tmp && count < 100); + + if (count >= 100) + res = _FALSE; + else + res = _TRUE; + } + + /* Disable RX packet buffer access */ + rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, + DISABLE_TRXPKT_BUF_ACCESS); + + return res; +} + + +void rtw_dump_priv_pattern(_adapter *adapter, u8 idx) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + char str_1[128]; + char *p_str; + u8 val8 = 0; + int i = 0, j = 0, len = 0, max_len = 0; + + DBG_871X("=========[%d]========\n", idx); + + DBG_871X(">>>priv_pattern_content:\n"); + p_str = str_1; + max_len = sizeof(str_1); + for (i = 0 ; i < MAX_WKFM_PATTERN_SIZE/8 ; i++) { + _rtw_memset(p_str, 0, max_len); + len = 0; + for (j = 0 ; j < 8 ; j++) { + val8 = pwrctl->patterns[idx].content[i*8 + j]; + len += snprintf(p_str + len, max_len - len, + "%02x ", val8); + } + DBG_871X("%s\n", p_str); + } + + DBG_871X(">>>priv_pattern_mask:\n"); + for (i = 0 ; i < MAX_WKFM_SIZE/8 ; i++) { + _rtw_memset(p_str, 0, max_len); + len = 0; + for (j = 0 ; j < 8 ; j++) { + val8 = pwrctl->patterns[idx].mask[i*8 + j]; + len += snprintf(p_str + len, max_len - len, + "%02x ", val8); + } + DBG_871X("%s\n", p_str); + } +} + +void rtw_clean_pattern(_adapter *adapter) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + struct rtl_wow_pattern zero_pattern; + int i = 0; + + _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern)); + + zero_pattern.type = PATTERN_INVALID; + + for (i = 0; i < MAX_WKFM_NUM; i++) + rtw_write_to_frame_mask(adapter, i, &zero_pattern); + + pwrctl->wowlan_pattern_idx = 0; + rtw_write8(adapter, REG_WKFMCAM_NUM, pwrctl->wowlan_pattern_idx); +} + +void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr) +{ + struct sta_info *psta; + struct security_priv *psecpriv = &padapter->securitypriv; + + _rtw_memset(pcur_dot11txpn, 0, 8); + if(NULL == StaAddr) + return; + psta = rtw_get_stainfo(&padapter->stapriv, StaAddr); + DBG_871X("%s(): StaAddr: %02x %02x %02x %02x %02x %02x\n", + __func__, StaAddr[0], StaAddr[1], StaAddr[2], + StaAddr[3], StaAddr[4], StaAddr[5]); + + if(psta) + { + if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ && psta->dot11txpn.val > 0) + psta->dot11txpn.val--; + AES_IV(pcur_dot11txpn, psta->dot11txpn, 0); + + DBG_871X("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x \n" + , __func__, pcur_dot11txpn[0],pcur_dot11txpn[1], + pcur_dot11txpn[2],pcur_dot11txpn[3], pcur_dot11txpn[4], + pcur_dot11txpn[5],pcur_dot11txpn[6],pcur_dot11txpn[7]); + } +} +void rtw_set_sec_pn(PADAPTER padapter) +{ + struct sta_info *psta; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct security_priv *psecpriv = &padapter->securitypriv; + + psta = rtw_get_stainfo(&padapter->stapriv, + get_my_bssid(&pmlmeinfo->network)); + + if(psta) + { + if (pwrpriv->wowlan_fw_iv > psta->dot11txpn.val) + { + if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) + psta->dot11txpn.val = pwrpriv->wowlan_fw_iv + 2; + } else { + DBG_871X("%s(): FW IV is smaller than driver\n", __func__); + psta->dot11txpn.val += 2; + } + DBG_871X("%s: dot11txpn: 0x%016llx\n", __func__ ,psta->dot11txpn.val); + } +} +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_PNO_SUPPORT +#define CSCAN_TLV_TYPE_SSID_IE 'S' +#define CIPHER_IE "key_mgmt=" +#define CIPHER_NONE "NONE" +#define CIPHER_WPA_PSK "WPA-PSK" +#define CIPHER_WPA_EAP "WPA-EAP IEEE8021X" +/* + * SSIDs list parsing from cscan tlv list + */ +int rtw_parse_ssid_list_tlv(char** list_str, pno_ssid_t* ssid, + int max, int *bytes_left) { + char* str; + + int idx = 0; + + if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { + DBG_871X("%s error paramters\n", __func__); + return -1; + } + + str = *list_str; + while (*bytes_left > 0) { + + if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { + *list_str = str; + DBG_871X("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]); + return idx; + } + + /* Get proper CSCAN_TLV_TYPE_SSID_IE */ + *bytes_left -= 1; + str += 1; + + if (str[0] == 0) { + /* Broadcast SSID */ + ssid[idx].SSID_len = 0; + memset((char*)ssid[idx].SSID, 0x0, WLAN_SSID_MAXLEN); + *bytes_left -= 1; + str += 1; + + DBG_871X("BROADCAST SCAN left=%d\n", *bytes_left); + } + else if (str[0] <= WLAN_SSID_MAXLEN) { + /* Get proper SSID size */ + ssid[idx].SSID_len = str[0]; + *bytes_left -= 1; + str += 1; + + /* Get SSID */ + if (ssid[idx].SSID_len > *bytes_left) { + DBG_871X("%s out of memory range len=%d but left=%d\n", + __func__, ssid[idx].SSID_len, *bytes_left); + return -1; + } + + memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len); + + *bytes_left -= ssid[idx].SSID_len; + str += ssid[idx].SSID_len; + + DBG_871X("%s :size=%d left=%d\n", + (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left); + } + else { + DBG_871X("### SSID size more that %d\n", str[0]); + return -1; + } + + if (idx++ > max) { + DBG_871X("%s number of SSIDs more that %d\n", __func__, idx); + return -1; + } + } + + *list_str = str; + return idx; +} + +int rtw_parse_cipher_list(struct pno_nlo_info *nlo_info, char* list_str) { + + char *pch, *pnext, *pend; + u8 key_len = 0, index = 0; + + pch = list_str; + + if (nlo_info == NULL || list_str == NULL) { + DBG_871X("%s error paramters\n", __func__); + return -1; + } + + while (strlen(pch) != 0) { + pnext = strstr(pch, "key_mgmt="); + if (pnext != NULL) { + pch = pnext + strlen(CIPHER_IE); + pend = strstr(pch, "}"); + if (strncmp(pch, CIPHER_NONE, + strlen(CIPHER_NONE)) == 0) { + nlo_info->ssid_cipher_info[index] = 0x00; + } else if (strncmp(pch, CIPHER_WPA_PSK, + strlen(CIPHER_WPA_PSK)) == 0) { + nlo_info->ssid_cipher_info[index] = 0x66; + } else if (strncmp(pch, CIPHER_WPA_EAP, + strlen(CIPHER_WPA_EAP)) == 0) { + nlo_info->ssid_cipher_info[index] = 0x01; + } + index ++; + pch = pend + 1; + } else { + break; + } + } + return 0; +} + +int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t* ssid, + int num, int pno_time, int pno_repeat, int pno_freq_expo_max) { + + int i = 0; + struct file *fp; + mm_segment_t fs; + loff_t pos = 0; + u8 *source = NULL; + long len = 0; + + DBG_871X("+%s+\n", __func__); + + 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] + = ssid[i].SSID_len; + } + + /* cipher array */ + fp = filp_open("/data/misc/wifi/wpa_supplicant.conf", O_RDONLY, 0644); + if (IS_ERR(fp)) { + DBG_871X("Error, wpa_supplicant.conf doesn't exist.\n"); + DBG_871X("Error, cipher array using default value.\n"); + return 0; + } + + len = i_size_read(fp->f_path.dentry->d_inode); + if (len < 0 || len > 2048) { + DBG_871X("Error, file size is bigger than 2048.\n"); + DBG_871X("Error, cipher array using default value.\n"); + return 0; + } + + fs = get_fs(); + set_fs(KERNEL_DS); + + source = rtw_zmalloc(2048); + + if (source != NULL) { + len = vfs_read(fp, source, len, &pos); + rtw_parse_cipher_list(nlo_info, source); + rtw_mfree(source, 2048); + } + + set_fs(fs); + filp_close(fp, NULL); + + DBG_871X("-%s-\n", __func__); + return 0; +} + +int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list, + pno_ssid_t* ssid, u8 num) { + + int i = 0; + if(num > MAX_PNO_LIST_COUNT) + num = MAX_PNO_LIST_COUNT; + + 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; +} + +int rtw_dev_scan_info_set(_adapter *padapter, pno_ssid_t* ssid, + unsigned char ch, unsigned char ch_offset, unsigned short bw_mode) { + + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct pno_scan_info *scan_info = pwrctl->pscan_info; + int i; + + scan_info->channel_num = MAX_SCAN_LIST_COUNT; + scan_info->orig_ch = ch; + scan_info->orig_bw = bw_mode; + scan_info->orig_40_offset = ch_offset; + + for(i = 0 ; i < scan_info->channel_num ; i++) { + if (i < 11) + scan_info->ssid_channel_info[i].active = 1; + else + scan_info->ssid_channel_info[i].active = 0; + + scan_info->ssid_channel_info[i].timeout = 100; + + scan_info->ssid_channel_info[i].tx_power = + PHY_GetTxPowerIndex(padapter, 0, 0x02, bw_mode, i+1); + + scan_info->ssid_channel_info[i].channel = i+1; + } + + DBG_871X("%s, channel_num: %d, orig_ch: %d, orig_bw: %d orig_40_offset: %d\n", + __func__, scan_info->channel_num, scan_info->orig_ch, + scan_info->orig_bw, scan_info->orig_40_offset); + return 0; +} + +int rtw_dev_pno_set(struct net_device *net, pno_ssid_t* ssid, int num, + int pno_time, int pno_repeat, int pno_freq_expo_max) { + + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + int ret = -1; + + if (num == 0) { + DBG_871X("%s, nssid is zero, no need to setup pno ssid list\n", __func__); + return 0; + } + + if (pwrctl == NULL) { + DBG_871X("%s, ERROR: pwrctl is NULL\n", __func__); + return -1; + } else { + pwrctl->pnlo_info = + (pno_nlo_info_t*)rtw_zmalloc(sizeof(pno_nlo_info_t)); + pwrctl->pno_ssid_list = + (pno_ssid_list_t*)rtw_zmalloc(sizeof(pno_ssid_list_t)); + pwrctl->pscan_info = + (pno_scan_info_t*)rtw_zmalloc(sizeof(pno_scan_info_t)); + } + + if (pwrctl->pnlo_info == NULL || + pwrctl->pscan_info == NULL || + pwrctl->pno_ssid_list == NULL){ + DBG_871X("%s, ERROR: alloc nlo_info, ssid_list, scan_info fail\n", __func__); + goto failing; + } + + pwrctl->pno_in_resume = _FALSE; + + pwrctl->pno_inited = _TRUE; + /* NLO Info */ + ret = rtw_dev_nlo_info_set(pwrctl->pnlo_info, ssid, num, + pno_time, pno_repeat, pno_freq_expo_max); + + /* SSID Info */ + ret = rtw_dev_ssid_list_set(pwrctl->pno_ssid_list, ssid, num); + + /* SCAN Info */ + ret = rtw_dev_scan_info_set(padapter, ssid, pmlmeext->cur_channel, + pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); + + DBG_871X("+%s num: %d, pno_time: %d, pno_repeat:%d, pno_freq_expo_max:%d+\n", + __func__, num, pno_time, pno_repeat, pno_freq_expo_max); + + return 0; + +failing: + if (pwrctl->pnlo_info) { + rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t)); + pwrctl->pnlo_info = NULL; + } + if (pwrctl->pno_ssid_list) { + rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t)); + pwrctl->pno_ssid_list = NULL; + } + if (pwrctl->pscan_info) { + rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t)); + pwrctl->pscan_info = NULL; + } + + return -1; +} + +#ifdef CONFIG_PNO_SET_DEBUG +void rtw_dev_pno_debug(struct net_device *net) { + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + int i = 0, j = 0; + + DBG_871X("*******NLO_INFO********\n"); + DBG_871X("ssid_num: %d\n", pwrctl->pnlo_info->ssid_num); + DBG_871X("fast_scan_iterations: %d\n", + pwrctl->pnlo_info->fast_scan_iterations); + DBG_871X("fast_scan_period: %d\n", pwrctl->pnlo_info->fast_scan_period); + DBG_871X("slow_scan_period: %d\n", pwrctl->pnlo_info->slow_scan_period); + DBG_871X("ssid_length: "); + for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) { + printk("%d, ", pwrctl->pnlo_info->ssid_length[i]); + } + DBG_871X("\n"); + + DBG_871X("cipher_info: "); + for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) { + DBG_871X("%d, ", pwrctl->pnlo_info->ssid_cipher_info[i]); + } + DBG_871X("\n"); + + DBG_871X("channel_info: "); + for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) { + DBG_871X("%d, ", pwrctl->pnlo_info->ssid_channel_info[i]); + } + DBG_871X("\n"); + + DBG_871X("******SSID_LISD******\n"); + for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) { + DBG_871X("[%d]SSID: %s \n", i, + pwrctl->pno_ssid_list->node[i].SSID); + } + + DBG_871X("******SCAN_INFO******\n"); + DBG_871X("ch_num: %d\n", pwrctl->pscan_info->channel_num); + DBG_871X("orig_ch: %d\n", pwrctl->pscan_info->orig_ch); + DBG_871X("orig bw: %d\n", pwrctl->pscan_info->orig_bw); + DBG_871X("orig 40 offset: %d\n", pwrctl->pscan_info->orig_40_offset); + for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) { + DBG_871X("[%02d] avtive:%d, timeout:%d, tx_power:%d, ch:%02d\n", + i, pwrctl->pscan_info->ssid_channel_info[i].active, + pwrctl->pscan_info->ssid_channel_info[i].timeout, + pwrctl->pscan_info->ssid_channel_info[i].tx_power, + pwrctl->pscan_info->ssid_channel_info[i].channel); + } + DBG_871X("*****************\n"); +} +#endif //CONFIG_PNO_SET_DEBUG +#endif //CONFIG_PNO_SUPPORT diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_xmit.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_xmit.c new file mode 100644 index 00000000..04dedd3b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_xmit.c @@ -0,0 +1,5074 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTW_XMIT_C_ + +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) +#error "Shall be Linux or Windows, but not both!\n" +#endif + + +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; + +static void _init_txservq(struct tx_servq *ptxservq) +{ +_func_enter_; + _rtw_init_listhead(&ptxservq->tx_pending); + _rtw_init_queue(&ptxservq->sta_pending); + ptxservq->qcnt = 0; +_func_exit_; +} + + +void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) +{ + +_func_enter_; + + _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv)); + + _rtw_spinlock_init(&psta_xmitpriv->lock); + + //for(i = 0 ; i < MAX_NUMBLKS; i++) + // _init_txservq(&(psta_xmitpriv->blk_q[i])); + + _init_txservq(&psta_xmitpriv->be_q); + _init_txservq(&psta_xmitpriv->bk_q); + _init_txservq(&psta_xmitpriv->vi_q); + _init_txservq(&psta_xmitpriv->vo_q); + _rtw_init_listhead(&psta_xmitpriv->legacy_dz); + _rtw_init_listhead(&psta_xmitpriv->apsd); + +_func_exit_; + +} + +s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter) +{ + int i; + struct xmit_buf *pxmitbuf; + struct xmit_frame *pxframe; + sint res=_SUCCESS; + +_func_enter_; + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); + + _rtw_spinlock_init(&pxmitpriv->lock); + _rtw_spinlock_init(&pxmitpriv->lock_sctx); + _rtw_init_sema(&pxmitpriv->xmit_sema, 0); + _rtw_init_sema(&pxmitpriv->terminate_xmitthread_sema, 0); + + /* + Please insert all the queue initializaiton using _rtw_init_queue below + */ + + pxmitpriv->adapter = padapter; + + //for(i = 0 ; i < MAX_NUMBLKS; i++) + // _rtw_init_queue(&pxmitpriv->blk_strms[i]); + + _rtw_init_queue(&pxmitpriv->be_pending); + _rtw_init_queue(&pxmitpriv->bk_pending); + _rtw_init_queue(&pxmitpriv->vi_pending); + _rtw_init_queue(&pxmitpriv->vo_pending); + _rtw_init_queue(&pxmitpriv->bm_pending); + + //_rtw_init_queue(&pxmitpriv->legacy_dz_queue); + //_rtw_init_queue(&pxmitpriv->apsd_queue); + + _rtw_init_queue(&pxmitpriv->free_xmit_queue); + + /* + Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME, + and initialize free_xmit_frame below. + Please also apply free_txobj to link_up all the xmit_frames... + */ + + pxmitpriv->pallocated_frame_buf = rtw_zvmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4); + + if (pxmitpriv->pallocated_frame_buf == NULL){ + pxmitpriv->pxmit_frame_buf =NULL; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_frame fail!\n")); + res= _FAIL; + goto exit; + } + pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4); + //pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - + // ((SIZE_PTR) (pxmitpriv->pallocated_frame_buf) &3); + + pxframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf; + + for (i = 0; i < NR_XMITFRAME; i++) + { + _rtw_init_listhead(&(pxframe->list)); + + pxframe->padapter = padapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue)); + + pxframe++; + } + + pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; + + pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; + + + //init xmit_buf + _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue); + _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue); + + pxmitpriv->pallocated_xmitbuf = rtw_zvmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4); + + if (pxmitpriv->pallocated_xmitbuf == NULL){ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_buf fail!\n")); + res= _FAIL; + goto exit; + } + + pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4); + //pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - + // ((SIZE_PTR) (pxmitpriv->pallocated_xmitbuf) &3); + + pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmitbuf; + + for (i = 0; i < NR_XMITBUFF; i++) + { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->buf_tag = XMITBUF_DATA; + + /* Tx buf allocation may fail sometimes, so sleep and retry. */ + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE)) == _FAIL) { + rtw_msleep_os(10); + res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf,(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), _TRUE); + if (res == _FAIL) { + goto exit; + } + } + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + + pxmitbuf->flags = XMIT_VO_QUEUE; + + rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); + #ifdef DBG_XMIT_BUF + pxmitbuf->no=i; + #endif + + pxmitbuf++; + + } + + pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; + + /* init xframe_ext queue, the same count as extbuf */ + _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue); + + pxmitpriv->xframe_ext_alloc_addr = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4); + + if (pxmitpriv->xframe_ext_alloc_addr == NULL){ + pxmitpriv->xframe_ext = NULL; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xframe_ext fail!\n")); + res= _FAIL; + goto exit; + } + pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4); + pxframe = (struct xmit_frame*)pxmitpriv->xframe_ext; + + for (i = 0; i < NR_XMIT_EXTBUFF; i++) { + _rtw_init_listhead(&(pxframe->list)); + + pxframe->padapter = padapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + pxframe->ext_tag = 1; + + rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xframe_ext_queue.queue)); + + pxframe++; + } + pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF; + + // Init xmit extension buff + _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue); + + pxmitpriv->pallocated_xmit_extbuf = rtw_zvmalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4); + + if (pxmitpriv->pallocated_xmit_extbuf == NULL){ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("alloc xmit_extbuf fail!\n")); + res= _FAIL; + goto exit; + } + + pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4); + + pxmitbuf = (struct xmit_buf*)pxmitpriv->pxmit_extbuf; + + for (i = 0; i < NR_XMIT_EXTBUFF; i++) + { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->buf_tag = XMITBUF_MGNT; + + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf,MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, _TRUE)) == _FAIL) { + res= _FAIL; + goto exit; + } + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + + rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue)); + #ifdef DBG_XMIT_BUF_EXT + pxmitbuf->no=i; + #endif + pxmitbuf++; + + } + + pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF; + + for (i = 0; ipcmd_xmitbuf[i]; + if (pxmitbuf) { + _rtw_init_listhead(&pxmitbuf->list); + + pxmitbuf->priv_data = NULL; + pxmitbuf->padapter = padapter; + pxmitbuf->buf_tag = XMITBUF_CMD; + + if((res=rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, _TRUE)) == _FAIL) { + res= _FAIL; + goto exit; + } + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->phead = pxmitbuf->pbuf; + pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ; + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; +#endif + pxmitbuf->alloc_sz = MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ; + } + } + + rtw_alloc_hwxmits(padapter); + rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); + + for (i = 0; i < 4; i ++) + { + pxmitpriv->wmm_para_seq[i] = i; + } + +#ifdef CONFIG_USB_HCI + pxmitpriv->txirp_cnt=1; + + _rtw_init_sema(&(pxmitpriv->tx_retevt), 0); + + //per AC pending irp + pxmitpriv->beq_cnt = 0; + pxmitpriv->bkq_cnt = 0; + pxmitpriv->viq_cnt = 0; + pxmitpriv->voq_cnt = 0; +#endif + + +#ifdef CONFIG_XMIT_ACK + pxmitpriv->ack_tx = _FALSE; + _rtw_mutex_init(&pxmitpriv->ack_tx_mutex); + rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0); +#endif + + rtw_hal_init_xmit_priv(padapter); + +exit: + +_func_exit_; + + return res; +} + +void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv); +void rtw_mfree_xmit_priv_lock (struct xmit_priv *pxmitpriv) +{ + _rtw_spinlock_free(&pxmitpriv->lock); + _rtw_free_sema(&pxmitpriv->xmit_sema); + _rtw_free_sema(&pxmitpriv->terminate_xmitthread_sema); + + _rtw_spinlock_free(&pxmitpriv->be_pending.lock); + _rtw_spinlock_free(&pxmitpriv->bk_pending.lock); + _rtw_spinlock_free(&pxmitpriv->vi_pending.lock); + _rtw_spinlock_free(&pxmitpriv->vo_pending.lock); + _rtw_spinlock_free(&pxmitpriv->bm_pending.lock); + + //_rtw_spinlock_free(&pxmitpriv->legacy_dz_queue.lock); + //_rtw_spinlock_free(&pxmitpriv->apsd_queue.lock); + + _rtw_spinlock_free(&pxmitpriv->free_xmit_queue.lock); + _rtw_spinlock_free(&pxmitpriv->free_xmitbuf_queue.lock); + _rtw_spinlock_free(&pxmitpriv->pending_xmitbuf_queue.lock); +} + + +void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv) +{ + int i; + _adapter *padapter = pxmitpriv->adapter; + struct xmit_frame *pxmitframe = (struct xmit_frame*) pxmitpriv->pxmit_frame_buf; + struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; + + _func_enter_; + + rtw_hal_free_xmit_priv(padapter); + + rtw_mfree_xmit_priv_lock(pxmitpriv); + + if(pxmitpriv->pxmit_frame_buf==NULL) + goto out; + + for(i=0; ipallocated_frame_buf) { + rtw_vmfree(pxmitpriv->pallocated_frame_buf, NR_XMITFRAME * sizeof(struct xmit_frame) + 4); + } + + + if(pxmitpriv->pallocated_xmitbuf) { + rtw_vmfree(pxmitpriv->pallocated_xmitbuf, NR_XMITBUFF * sizeof(struct xmit_buf) + 4); + } + + /* free xframe_ext queue, the same count as extbuf */ + if ((pxmitframe = (struct xmit_frame*)pxmitpriv->xframe_ext)) { + for (i=0; ixframe_ext_alloc_addr) + rtw_vmfree(pxmitpriv->xframe_ext_alloc_addr, NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4); + _rtw_spinlock_free(&pxmitpriv->free_xframe_ext_queue.lock); + + // free xmit extension buff + _rtw_spinlock_free(&pxmitpriv->free_xmit_extbuf_queue.lock); + + pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; + for(i=0; ipallocated_xmit_extbuf) { + rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4); + } + + for (i=0; ipcmd_xmitbuf[i]; + if(pxmitbuf!=NULL) + rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ , _TRUE); + } + + rtw_free_hwxmits(padapter); + +#ifdef CONFIG_XMIT_ACK + _rtw_mutex_free(&pxmitpriv->ack_tx_mutex); +#endif + +out: + +_func_exit_; + +} + +u8 query_ra_short_GI(struct sta_info *psta) +{ + u8 sgi = _FALSE, sgi_20m = _FALSE, sgi_40m = _FALSE, sgi_80m = _FALSE; + +#ifdef CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT + if (psta->vhtpriv.vht_option) { + sgi_80m= psta->vhtpriv.sgi_80m; + } +#endif //CONFIG_80211AC_VHT + { + sgi_20m = psta->htpriv.sgi_20m; + sgi_40m = psta->htpriv.sgi_40m; + } +#endif + + switch(psta->bw_mode){ + case CHANNEL_WIDTH_80: + sgi = sgi_80m; + break; + case CHANNEL_WIDTH_40: + sgi = sgi_40m; + break; + case CHANNEL_WIDTH_20: + default: + sgi = sgi_20m; + break; + } + + return sgi; +} + +static void update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + u32 sz; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + //struct sta_info *psta = pattrib->psta; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +/* + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] ); + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return; + } +*/ + + if (pattrib->nr_frags != 1) + { + sz = padapter->xmitpriv.frag_len; + } + else //no frag + { + sz = pattrib->last_txcmdsz; + } + + // (1) RTS_Threshold is compared to the MPDU, not MSDU. + // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. + // Other fragments are protected by previous fragment. + // So we only need to check the length of first fragment. + if(pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) + { + if(sz > padapter->registrypriv.rts_thresh) + { + pattrib->vcs_mode = RTS_CTS; + } + else + { + if(pattrib->rtsen) + pattrib->vcs_mode = RTS_CTS; + else if(pattrib->cts2self) + pattrib->vcs_mode = CTS_TO_SELF; + else + pattrib->vcs_mode = NONE_VCS; + } + } + else + { + while (_TRUE) + { +#if 0 //Todo + //check IOT action + if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) + { + pattrib->vcs_mode = CTS_TO_SELF; + pattrib->rts_rate = MGN_24M; + break; + } + else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE)) + { + pattrib->vcs_mode = RTS_CTS; + pattrib->rts_rate = MGN_24M; + break; + } +#endif + + //IOT action + if((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en==_TRUE) && + (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )) + { + pattrib->vcs_mode = CTS_TO_SELF; + break; + } + + + //check ERP protection + if(pattrib->rtsen || pattrib->cts2self) + { + if(pattrib->rtsen) + pattrib->vcs_mode = RTS_CTS; + else if(pattrib->cts2self) + pattrib->vcs_mode = CTS_TO_SELF; + + break; + } + + //check HT op mode + if(pattrib->ht_en) + { + u8 HTOpMode = pmlmeinfo->HT_protection; + if((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) || + (!pmlmeext->cur_bwmode && HTOpMode == 3) ) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + } + + //check rts + if(sz > padapter->registrypriv.rts_thresh) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + + //to do list: check MIMO power save condition. + + //check AMPDU aggregation for TXOP + if((pattrib->ampdu_en==_TRUE) && (!IS_HARDWARE_TYPE_8812(padapter))) + { + pattrib->vcs_mode = RTS_CTS; + break; + } + + pattrib->vcs_mode = NONE_VCS; + break; + } + } + + //for debug : force driver control vrtl_carrier_sense. + if(padapter->driver_vcs_en==1) + { + //u8 driver_vcs_en; //Enable=1, Disable=0 driver control vrtl_carrier_sense. + //u8 driver_vcs_type;//force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. + pattrib->vcs_mode = padapter->driver_vcs_type; + } + +} + +static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta) +{ + struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv; + + pattrib->rtsen = psta->rtsen; + pattrib->cts2self = psta->cts2self; + + pattrib->mdata = 0; + pattrib->eosp = 0; + pattrib->triggered=0; + pattrib->ampdu_spacing = 0; + + //qos_en, ht_en, init rate, ,bw, ch_offset, sgi + pattrib->qos_en = psta->qos_option; + + pattrib->raid = psta->raid; + + if (mlmeext->cur_bwmode < psta->bw_mode) + pattrib->bwmode = mlmeext->cur_bwmode; + else + pattrib->bwmode = psta->bw_mode; + + pattrib->sgi = query_ra_short_GI(psta); + + pattrib->ldpc = psta->ldpc; + pattrib->stbc = psta->stbc; + +#ifdef CONFIG_80211N_HT + pattrib->ht_en = psta->htpriv.ht_option; + pattrib->ch_offset = psta->htpriv.ch_offset; + pattrib->ampdu_en = _FALSE; + + if(padapter->driver_ampdu_spacing != 0xFF) //driver control AMPDU Density for peer sta's rx + pattrib->ampdu_spacing = padapter->driver_ampdu_spacing; + else + pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing; +#endif //CONFIG_80211N_HT + //if(pattrib->ht_en && psta->htpriv.ampdu_enable) + //{ + // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) + // pattrib->ampdu_en = _TRUE; + //} + +#ifdef CONFIG_TDLS + if (pattrib->direct_link==_TRUE) { + psta = pattrib->ptdls_sta; + + pattrib->raid = psta->raid; +#ifdef CONFIG_80211N_HT + pattrib->bwmode = psta->bw_mode; + pattrib->ht_en = psta->htpriv.ht_option; + pattrib->ch_offset = psta->htpriv.ch_offset; + pattrib->sgi= query_ra_short_GI(psta); +#endif /* CONFIG_80211N_HT */ + } +#endif /* CONFIG_TDLS */ + + pattrib->retry_ctrl = _FALSE; + +#ifdef CONFIG_AUTO_AP_MODE + if(psta->isrc && psta->pid>0) + pattrib->pctrl = _TRUE; +#endif + +} + +static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta) +{ + sint res = _SUCCESS; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + sint bmcast = IS_MCAST(pattrib->ra); + + _rtw_memset(pattrib->dot118021x_UncstKey.skey, 0, 16); + _rtw_memset(pattrib->dot11tkiptxmickey.skey, 0, 16); + pattrib->mac_id = psta->mac_id; + + if (psta->ieee8021x_blocked == _TRUE) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\n psta->ieee8021x_blocked == _TRUE \n")); + + pattrib->encrypt = 0; + + if((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)) + { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("\npsta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%.4x) != 0x888e\n",pattrib->ether_type)); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s psta->ieee8021x_blocked == _TRUE, pattrib->ether_type(%04x) != 0x888e\n", __FUNCTION__,pattrib->ether_type); + #endif + res = _FAIL; + goto exit; + } + } + else + { + GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); + +#ifdef CONFIG_WAPI_SUPPORT + if(pattrib->ether_type == 0x88B4) + pattrib->encrypt=_NO_PRIVACY_; +#endif + + switch(psecuritypriv->dot11AuthAlgrthm) + { + case dot11AuthAlgrthm_Open: + case dot11AuthAlgrthm_Shared: + case dot11AuthAlgrthm_Auto: + pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex; + break; + case dot11AuthAlgrthm_8021X: + if(bmcast) + pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid; + else + pattrib->key_idx = 0; + break; + default: + pattrib->key_idx = 0; + break; + } + + //For WPS 1.0 WEP, driver should not encrypt EAPOL Packet for WPS handshake. + if (((pattrib->encrypt ==_WEP40_)||(pattrib->encrypt ==_WEP104_)) && (pattrib->ether_type == 0x888e)) + pattrib->encrypt=_NO_PRIVACY_; + + } + +#ifdef CONFIG_TDLS + if (pattrib->direct_link == _TRUE) { + if (pattrib->encrypt > 0) + pattrib->encrypt = _AES_; + } +#endif + + switch (pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + pattrib->iv_len = 4; + pattrib->icv_len = 4; + WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + break; + + case _TKIP_: + pattrib->iv_len = 8; + pattrib->icv_len = 4; + + if(psecuritypriv->busetkipkey==_FAIL) + { + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s psecuritypriv->busetkipkey(%d)==_FAIL drop packet\n", __FUNCTION__, psecuritypriv->busetkipkey); + #endif + res =_FAIL; + goto exit; + } + + if(bmcast) + TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + TKIP_IV(pattrib->iv, psta->dot11txpn, 0); + + + _rtw_memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16); + + break; + + case _AES_: + + pattrib->iv_len = 8; + pattrib->icv_len = 8; + + if(bmcast) + AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + AES_IV(pattrib->iv, psta->dot11txpn, 0); + + break; + +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + pattrib->iv_len = 18; + pattrib->icv_len = 16; + rtw_wapi_get_iv(padapter,pattrib->ra,pattrib->iv); + break; +#endif + default: + pattrib->iv_len = 0; + pattrib->icv_len = 0; + break; + } + + if(pattrib->encrypt>0) + _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, + ("update_attrib: encrypt=%d securitypriv.sw_encrypt=%d\n", + pattrib->encrypt, padapter->securitypriv.sw_encrypt)); + + if (pattrib->encrypt && + ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE))) + { + pattrib->bswenc = _TRUE; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_, + ("update_attrib: encrypt=%d securitypriv.hw_decrypted=%d bswenc=_TRUE\n", + pattrib->encrypt, padapter->securitypriv.sw_encrypt)); + } else { + pattrib->bswenc = _FALSE; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("update_attrib: bswenc=_FALSE\n")); + } + +#if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC) + if((pattrib->encrypt && bmcast) || (pattrib->encrypt ==_WEP40_) || (pattrib->encrypt ==_WEP104_)) + { + pattrib->bswenc = _TRUE;//force using sw enc. + } +#endif +#ifdef DYNAMIC_CAMID_ALLOC + if (pattrib->encrypt && bmcast && _rtw_camctl_chk_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH)) + pattrib->bswenc = _TRUE; +#endif + +#ifdef CONFIG_WAPI_SUPPORT + if(pattrib->encrypt == _SMS4_) + pattrib->bswenc = _FALSE; +#endif + +exit: + + return res; + +} + +u8 qos_acm(u8 acm_mask, u8 priority) +{ + u8 change_priority = priority; + + switch (priority) + { + case 0: + case 3: + if(acm_mask & BIT(1)) + change_priority = 1; + break; + case 1: + case 2: + break; + case 4: + case 5: + if(acm_mask & BIT(2)) + change_priority = 0; + break; + case 6: + case 7: + if(acm_mask & BIT(3)) + change_priority = 5; + break; + default: + DBG_871X("qos_acm(): invalid pattrib->priority: %d!!!\n", priority); + break; + } + + return change_priority; +} + +static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) +{ + struct ethhdr etherhdr; + struct iphdr ip_hdr; + s32 UserPriority = 0; + + + _rtw_open_pktfile(ppktfile->pkt, ppktfile); + _rtw_pktfile_read(ppktfile, (unsigned char*)ðerhdr, ETH_HLEN); + + // get UserPriority from IP hdr + if (pattrib->ether_type == 0x0800) { + _rtw_pktfile_read(ppktfile, (u8*)&ip_hdr, sizeof(ip_hdr)); +// UserPriority = (ntohs(ip_hdr.tos) >> 5) & 0x3; + UserPriority = ip_hdr.tos >> 5; + } +/* + else if (pattrib->ether_type == 0x888e) { + // "When priority processing of data frames is supported, + // a STA's SME should send EAPOL-Key frames at the highest priority." + UserPriority = 7; + } +*/ + pattrib->priority = UserPriority; + pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->subtype = WIFI_QOS_DATA_TYPE; +} + +#ifdef CONFIG_TDLS +u8 rtw_check_tdls_established(_adapter *padapter, struct pkt_attrib *pattrib) +{ + pattrib->ptdls_sta = NULL; + + pattrib->direct_link = _FALSE; + if (padapter->tdlsinfo.link_established == _TRUE) { + pattrib->ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst); +#if 1 + if((pattrib->ptdls_sta!=NULL)&& + (pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)&& + (pattrib->ether_type!=0x0806)){ + pattrib->direct_link = _TRUE; + //DBG_871X("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst)); + } +#else + if (pattrib->ptdls_sta != NULL && + pattrib->ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) { + pattrib->direct_link = _TRUE; + #if 0 + DBG_871X("send ptk to "MAC_FMT" using direct link\n", MAC_ARG(pattrib->dst)); + #endif + } + + /* ARP frame may be helped by AP*/ + if (pattrib->ether_type != 0x0806) { + pattrib->direct_link = _FALSE; + } +#endif + } + + return pattrib->direct_link; +} + +s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib) +{ + + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + + s32 res=_SUCCESS; + + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + if (psta == NULL) { + res =_FAIL; + goto exit; + } + + pattrib->mac_id = psta->mac_id; + pattrib->psta = psta; + pattrib->ack_policy = 0; + // get ether_hdr_len + pattrib->pkt_hdrlen = ETH_HLEN; + + // [TDLS] TODO: setup req/rsp should be AC_BK + if (pqospriv->qos_option && psta->qos_option) { + pattrib->priority = 4; //tdls management frame should be AC_VI + pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; + pattrib->subtype = WIFI_QOS_DATA_TYPE; + } else { + pattrib->priority = 0; + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA_TYPE; + } + + //TODO:_lock + if(update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) + { + res = _FAIL; + goto exit; + } + + update_attrib_phy_info(padapter, pattrib, psta); + + +exit: + + return res; +} + +#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; + struct pkt_file pktfile; + struct sta_info *psta = NULL; + struct ethhdr etherhdr; + + sint bmcast; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv= &pmlmepriv->qospriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + sint res = _SUCCESS; + + _func_enter_; + + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib); + + _rtw_open_pktfile(pkt, &pktfile); + i = _rtw_pktfile_read(&pktfile, (u8*)ðerhdr, ETH_HLEN); + + pattrib->ether_type = ntohs(etherhdr.h_proto); + + + _rtw_memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); + _rtw_memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); + + + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_adhoc); + } + else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { +#ifdef CONFIG_TDLS + if (rtw_check_tdls_established(padapter, pattrib) == _TRUE) + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); /* For TDLS direct link Tx, set ra to be same to dst */ + else +#endif + _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pattrib->ta, adapter_mac_addr(padapter), ETH_ALEN); + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_sta); + } + else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap); + } + else + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown); + + bmcast = IS_MCAST(pattrib->ra); + if (bmcast) { + psta = rtw_get_bcmc_stainfo(padapter); + if (psta == NULL) { /* if we cannot get psta => drop the pkt */ + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sta); + RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT "\n", MAC_ARG(pattrib->ra))); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra)); + #endif + res = _FAIL; + goto exit; + } + } else { + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + if (psta == NULL) { /* if we cannot get psta => drop the pkt */ + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_sta); + RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT"\n", MAC_ARG(pattrib->ra))); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s get sta_info fail, ra:" MAC_FMT"\n", __func__, MAC_ARG(pattrib->ra)); + #endif + res = _FAIL; + goto exit; + } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE && !(psta->state & _FW_LINKED)) { + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_ucast_ap_link); + res = _FAIL; + goto exit; + } + } + + if (!(psta->state & _FW_LINKED)) { + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_link); + DBG_871X("%s, psta("MAC_FMT")->state(0x%x) != _FW_LINKED\n", __func__, MAC_ARG(psta->hwaddr), psta->state); + res = _FAIL; + goto exit; + } + + pattrib->pktlen = pktfile.pkt_len; + + /* TODO: 802.1Q VLAN header */ + /* TODO: IPV6 */ + + if (ETH_P_IP == pattrib->ether_type) { + u8 ip[20]; + + _rtw_pktfile_read(&pktfile, ip, 20); + + if (GET_IPV4_IHL(ip) * 4 > 20) + _rtw_pktfile_read(&pktfile, NULL, GET_IPV4_IHL(ip) - 20); + + pattrib->icmp_pkt = 0; + pattrib->dhcp_pkt = 0; + + if (GET_IPV4_PROTOCOL(ip) == 0x01) { /* ICMP */ + pattrib->icmp_pkt = 1; + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_icmp); + + } else if (GET_IPV4_PROTOCOL(ip) == 0x11) { /* UDP */ + u8 udp[8]; + + _rtw_pktfile_read(&pktfile, udp, 8); + + if ((GET_UDP_SRC(udp) == 68 && GET_UDP_DST(udp) == 67) + || (GET_UDP_SRC(udp) == 67 && GET_UDP_DST(udp) == 68) + ) { + /* 67 : UDP BOOTP server, 68 : UDP BOOTP client */ + if (pattrib->pktlen > 282) { /* MINIMUM_DHCP_PACKET_SIZE */ + pattrib->dhcp_pkt = 1; + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_dhcp); + if (0) + DBG_871X("send DHCP packet\n"); + } + } + + } else if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */ + && rtw_st_ctl_chk_reg_s_proto(&psta->st_ctl, 0x06) == _TRUE + ) { + u8 tcp[20]; + + _rtw_pktfile_read(&pktfile, tcp, 20); + + if (rtw_st_ctl_chk_reg_rule(&psta->st_ctl, padapter, IPV4_SRC(ip), TCP_SRC(tcp), IPV4_DST(ip), TCP_DST(tcp)) == _TRUE) { + if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) { + session_tracker_add_cmd(padapter, psta + , IPV4_SRC(ip), TCP_SRC(tcp) + , IPV4_SRC(ip), TCP_DST(tcp)); + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n" + , FUNC_ADPT_ARG(padapter) + , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)) + , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))); + } + if (GET_TCP_FIN(tcp)) { + session_tracker_del_cmd(padapter, psta + , IPV4_SRC(ip), TCP_SRC(tcp) + , IPV4_SRC(ip), TCP_DST(tcp)); + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n" + , FUNC_ADPT_ARG(padapter) + , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)) + , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))); + } + } + } + + } else if (0x888e == pattrib->ether_type) { + DBG_871X_LEVEL(_drv_always_, "send eapol packet\n"); + } + + if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1)) + rtw_set_scan_deny(padapter, 3000); + +#ifdef CONFIG_LPS + // If EAPOL , ARP , OR DHCP packet, driver must be in active mode. +#ifdef CONFIG_WAPI_SUPPORT + if ( (pattrib->ether_type == 0x88B4) || (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) +#else //!CONFIG_WAPI_SUPPORT +#if 0 + if ( (pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) +#else // only ICMP/DHCP packets is as SPECIAL_PACKET, and leave LPS when tx IMCP/DHCP packets. + //if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1) ) + if (pattrib->icmp_pkt==1) + { + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); + } + else if(pattrib->dhcp_pkt==1) +#endif +#endif + { + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_active); + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1); + } +#endif //CONFIG_LPS + +#ifdef CONFIG_BEAMFORMING + update_attrib_txbf_info(padapter, pattrib, psta); +#endif + + //TODO:_lock + if(update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) + { + DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_err_sec); + res = _FAIL; + goto exit; + } + + update_attrib_phy_info(padapter, pattrib, psta); + + //DBG_8192C("%s ==> mac_id(%d)\n",__FUNCTION__,pattrib->mac_id ); + + pattrib->psta = psta; + //TODO:_unlock + + pattrib->pctrl = 0; + + pattrib->ack_policy = 0; + // get ether_hdr_len + pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag + + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA_TYPE; + pattrib->priority = 0; + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) + { + if(pattrib->qos_en) + set_qos(&pktfile, pattrib); + } + else + { +#ifdef CONFIG_TDLS + if (pattrib->direct_link == _TRUE) { + if (pattrib->qos_en) + set_qos(&pktfile, pattrib); + } else +#endif + { + if (pqospriv->qos_option) { + set_qos(&pktfile, pattrib); + + if (pmlmepriv->acm_mask != 0) + pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority); + } + } + } + + //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: + +_func_exit_; + + return res; +} + +static s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe){ + sint curfragnum,length; + u8 *pframe, *payload,mic[8]; + struct mic_data micdata; + //struct sta_info *stainfo; + struct qos_priv *pqospriv= &(padapter->mlmepriv.qospriv); + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct security_priv *psecuritypriv=&padapter->securitypriv; + struct xmit_priv *pxmitpriv=&padapter->xmitpriv; + u8 priority[4]={0x0,0x0,0x0,0x0}; + u8 hw_hdr_offset = 0; + sint bmcst = IS_MCAST(pattrib->ra); + +/* + if(pattrib->psta) + { + stainfo = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]); + } + + if(stainfo==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + if(!(stainfo->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state); + return _FAIL; + } +*/ + +_func_enter_; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);; +#else + #ifdef CONFIG_TX_EARLY_MODE + hw_hdr_offset = TXDESC_OFFSET+ EARLY_MODE_INFO_SIZE; + #else + hw_hdr_offset = TXDESC_OFFSET; + #endif +#endif + + if(pattrib->encrypt ==_TKIP_)//if(psecuritypriv->dot11PrivacyAlgrthm==_TKIP_PRIVACY_) + { + //encode mic code + //if(stainfo!= NULL) + { + u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; + + pframe = pxmitframe->buf_addr + hw_hdr_offset; + + if(bmcst) + { + if(_rtw_memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)==_TRUE){ + //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); + //rtw_msleep_os(10); + return _FAIL; + } + //start to calculate the mic code + rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey); + } + else + { + if(_rtw_memcmp(&pattrib->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){ + //DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey==0\n"); + //rtw_msleep_os(10); + return _FAIL; + } + //start to calculate the mic code + rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]); + } + + if(pframe[1]&1){ //ToDS==1 + rtw_secmicappend(&micdata, &pframe[16], 6); //DA + if(pframe[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &pframe[24], 6); + else + rtw_secmicappend(&micdata, &pframe[10], 6); + } + else{ //ToDS==0 + rtw_secmicappend(&micdata, &pframe[4], 6); //DA + if(pframe[1]&2) //From Ds==1 + rtw_secmicappend(&micdata, &pframe[16], 6); + else + rtw_secmicappend(&micdata, &pframe[10], 6); + + } + + //if(pqospriv->qos_option==1) + if(pattrib->qos_en) + priority[0]=(u8)pxmitframe->attrib.priority; + + + rtw_secmicappend(&micdata, &priority[0], 4); + + payload=pframe; + + for(curfragnum=0;curfragnumnr_frags;curfragnum++){ + payload=(u8 *)RND4((SIZE_PTR)(payload)); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("===curfragnum=%d, pframe= 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n", + curfragnum,*payload, *(payload+1),*(payload+2),*(payload+3),*(payload+4),*(payload+5),*(payload+6),*(payload+7))); + + payload=payload+pattrib->hdrlen+pattrib->iv_len; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",curfragnum,pattrib->hdrlen,pattrib->iv_len)); + if((curfragnum+1)==pattrib->nr_frags){ + length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0); + rtw_secmicappend(&micdata, payload,length); + payload=payload+length; + } + else{ + length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-( (pattrib->bswenc) ? pattrib->icv_len : 0); + rtw_secmicappend(&micdata, payload, length); + payload=payload+length+pattrib->icv_len; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("curfragnum=%d length=%d pattrib->icv_len=%d",curfragnum,length,pattrib->icv_len)); + } + } + rtw_secgetmic(&micdata,&(mic[0])); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: before add mic code!!!\n")); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: pattrib->last_txcmdsz=%d!!!\n",pattrib->last_txcmdsz)); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: mic[0]=0x%.2x ,mic[1]=0x%.2x ,mic[2]=0x%.2x ,mic[3]=0x%.2x \n\ + mic[4]=0x%.2x ,mic[5]=0x%.2x ,mic[6]=0x%.2x ,mic[7]=0x%.2x !!!!\n", + mic[0],mic[1],mic[2],mic[3],mic[4],mic[5],mic[6],mic[7])); + //add mic code and add the mic code length in last_txcmdsz + + _rtw_memcpy(payload, &(mic[0]),8); + pattrib->last_txcmdsz+=8; + + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("\n ========last pkt========\n")); + payload=payload-pattrib->last_txcmdsz+8; + for(curfragnum=0;curfragnumlast_txcmdsz;curfragnum=curfragnum+8) + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,(" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ", + *(payload+curfragnum), *(payload+curfragnum+1), *(payload+curfragnum+2),*(payload+curfragnum+3), + *(payload+curfragnum+4),*(payload+curfragnum+5),*(payload+curfragnum+6),*(payload+curfragnum+7))); + } +/* + else{ + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("xmitframe_addmic: rtw_get_stainfo==NULL!!!\n")); + } +*/ + } + +_func_exit_; + + return _SUCCESS; +} + +static s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe){ + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + //struct security_priv *psecuritypriv=&padapter->securitypriv; + +_func_enter_; + + //if((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) + if(pattrib->bswenc) + { + //DBG_871X("start xmitframe_swencrypt\n"); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_alert_,("### xmitframe_swencrypt\n")); + switch(pattrib->encrypt){ + case _WEP40_: + case _WEP104_: + rtw_wep_encrypt(padapter, (u8 *)pxmitframe); + break; + case _TKIP_: + rtw_tkip_encrypt(padapter, (u8 *)pxmitframe); + break; + case _AES_: + rtw_aes_encrypt(padapter, (u8 * )pxmitframe); + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + rtw_sms4_encrypt(padapter, (u8 * )pxmitframe); +#endif + default: + break; + } + + } else { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_notice_,("### xmitframe_hwencrypt\n")); + } + +_func_exit_; + + return _SUCCESS; +} + +s32 rtw_make_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib) +{ + u16 *qc; + + struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv = &pmlmepriv->qospriv; + u8 qos_option = _FALSE; + sint res = _SUCCESS; + u16 *fctrl = &pwlanhdr->frame_ctl; + + //struct sta_info *psta; + + //sint bmcst = IS_MCAST(pattrib->ra); + +_func_enter_; + +/* + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return; + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } +*/ + + _rtw_memset(hdr, 0, WLANHDR_OFFSET); + + SetFrameSubType(fctrl, pattrib->subtype); + + if (pattrib->subtype & WIFI_DATA_TYPE) + { + if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) { +#ifdef CONFIG_TDLS + if(pattrib->direct_link == _TRUE){ + //TDLS data transfer, ToDS=0, FrDs=0 + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + + if (pattrib->qos_en) + qos_option = _TRUE; + } + else +#endif //CONFIG_TDLS + { + //to_ds = 1, fr_ds = 0; + // 1.Data transfer to AP + // 2.Arp pkt will relayed by AP + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + + if (pqospriv->qos_option) + qos_option = _TRUE; + } + } + else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ) { + //to_ds = 0, fr_ds = 1; + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN); + + if(pattrib->qos_en) + qos_option = _TRUE; + } + else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->ta, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + + if(pattrib->qos_en) + qos_option = _TRUE; + } + else { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv))); + res = _FAIL; + goto exit; + } + + if(pattrib->mdata) + SetMData(fctrl); + + if (pattrib->encrypt) + SetPrivacy(fctrl); + + if (qos_option) + { + qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); + + if (pattrib->priority) + SetPriority(qc, pattrib->priority); + + SetEOSP(qc, pattrib->eosp); + + SetAckpolicy(qc, pattrib->ack_policy); + } + + //TODO: fill HT Control Field + + //Update Seq Num will be handled by f/w + { + struct sta_info *psta; + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return _FAIL; + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } + + + if(psta) + { + psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; + + SetSeqNum(hdr, pattrib->seqnum); + +#ifdef CONFIG_80211N_HT + //check if enable ampdu + if(pattrib->ht_en && psta->htpriv.ampdu_enable) + { + if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority)) + pattrib->ampdu_en = _TRUE; + } + + //re-check if enable ampdu by BA_starting_seqctrl + if(pattrib->ampdu_en == _TRUE) + { + u16 tx_seq; + + tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f]; + + //check BA_starting_seqctrl + if(SN_LESS(pattrib->seqnum, tx_seq)) + { + //DBG_871X("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); + pattrib->ampdu_en = _FALSE;//AGG BK + } + else if(SN_EQUAL(pattrib->seqnum, tx_seq)) + { + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff; + + pattrib->ampdu_en = _TRUE;//AGG EN + } + else + { + //DBG_871X("tx ampdu over run\n"); + psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff; + pattrib->ampdu_en = _TRUE;//AGG EN + } + + } +#endif //CONFIG_80211N_HT + } + } + + } + else + { + + } + +exit: + +_func_exit_; + + return res; +} + +s32 rtw_txframes_pending(_adapter *padapter) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + return ((_rtw_queue_empty(&pxmitpriv->be_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->bk_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->vi_pending) == _FALSE) || + (_rtw_queue_empty(&pxmitpriv->vo_pending) == _FALSE)); +} + +s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib) +{ + struct sta_info *psta; + struct tx_servq *ptxservq; + int priority = pattrib->priority; +/* + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0]); + } +*/ + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return 0; + } + + if(psta==NULL) + { + DBG_871X("%s, psta==NUL\n", __func__); + return 0; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return 0; + } + + switch(priority) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + break; + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + break; + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + break; + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + break; + + } + + return ptxservq->qcnt; +} + +#ifdef CONFIG_TDLS + +int rtw_build_tdls_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt) +{ + int res=_SUCCESS; + + switch(ptxmgmt->action_code){ + case TDLS_SETUP_REQUEST: + rtw_build_tdls_setup_req_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_SETUP_RESPONSE: + rtw_build_tdls_setup_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_SETUP_CONFIRM: + rtw_build_tdls_setup_cfm_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_TEARDOWN: + rtw_build_tdls_teardown_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_DISCOVERY_REQUEST: + rtw_build_tdls_dis_req_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_PEER_TRAFFIC_INDICATION: + rtw_build_tdls_peer_traffic_indication_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; +#ifdef CONFIG_TDLS_CH_SW + case TDLS_CHANNEL_SWITCH_REQUEST: + rtw_build_tdls_ch_switch_req_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; + case TDLS_CHANNEL_SWITCH_RESPONSE: + rtw_build_tdls_ch_switch_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; +#endif + case TDLS_PEER_TRAFFIC_RESPONSE: + rtw_build_tdls_peer_traffic_rsp_ies(padapter, pxmitframe, pframe, ptxmgmt); + break; +#ifdef CONFIG_WFD + case TUNNELED_PROBE_REQ: + rtw_build_tunneled_probe_req_ies(padapter, pxmitframe, pframe); + break; + case TUNNELED_PROBE_RSP: + rtw_build_tunneled_probe_rsp_ies(padapter, pxmitframe, pframe); + break; +#endif //CONFIG_WFD + default: + res=_FAIL; + break; + } + + return res; +} + +s32 rtw_make_tdls_wlanhdr (_adapter *padapter , u8 *hdr, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt) +{ + u16 *qc; + struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct qos_priv *pqospriv = &pmlmepriv->qospriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta=NULL, *ptdls_sta=NULL; + u8 tdls_seq=0, baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + sint res = _SUCCESS; + u16 *fctrl = &pwlanhdr->frame_ctl; + +_func_enter_; + + _rtw_memset(hdr, 0, WLANHDR_OFFSET); + + SetFrameSubType(fctrl, pattrib->subtype); + + switch(ptxmgmt->action_code){ + case TDLS_SETUP_REQUEST: + case TDLS_SETUP_RESPONSE: + case TDLS_SETUP_CONFIRM: + case TDLS_PEER_TRAFFIC_INDICATION: + case TDLS_PEER_PSM_REQUEST: + case TUNNELED_PROBE_REQ: + case TUNNELED_PROBE_RSP: + case TDLS_DISCOVERY_REQUEST: + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + break; + case TDLS_CHANNEL_SWITCH_REQUEST: + case TDLS_CHANNEL_SWITCH_RESPONSE: + case TDLS_PEER_PSM_RESPONSE: + case TDLS_PEER_TRAFFIC_RESPONSE: + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + tdls_seq=1; + break; + case TDLS_TEARDOWN: + if(ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) + { + _rtw_memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN); + tdls_seq=1; + } + else + { + SetToDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN); + } + break; + } + + if (pattrib->encrypt) + SetPrivacy(fctrl); + + if(ptxmgmt->action_code == TDLS_PEER_TRAFFIC_RESPONSE) + { + SetPwrMgt(fctrl); + } + + if (pqospriv->qos_option) + { + qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); + if (pattrib->priority) + SetPriority(qc, pattrib->priority); + SetAckpolicy(qc, pattrib->ack_policy); + } + + psta = pattrib->psta; + + // 1. update seq_num per link by sta_info + // 2. rewrite encrypt to _AES_, also rewrite iv_len, icv_len + if(tdls_seq==1){ + ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst); + if(ptdls_sta){ + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]; + SetSeqNum(hdr, pattrib->seqnum); + + if (pattrib->encrypt){ + pattrib->encrypt= _AES_; + pattrib->iv_len=8; + pattrib->icv_len=8; + pattrib->bswenc = _FALSE; + } + pattrib->mac_id = ptdls_sta->mac_id; + }else{ + res=_FAIL; + goto exit; + } + }else if(psta){ + psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; + psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; + pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; + SetSeqNum(hdr, pattrib->seqnum); + } + + +exit: + +_func_exit_; + + return res; +} + +s32 rtw_xmit_tdls_coalesce(_adapter * padapter, struct xmit_frame * pxmitframe, struct tdls_txmgmt *ptxmgmt) +{ + s32 llc_sz; + + u8 *pframe, *mem_start; + + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 *pbuf_start; + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _SUCCESS; + +_func_enter_; + + if (pattrib->psta) { + psta = pattrib->psta; + } else { + if(bmcst) { + psta = rtw_get_bcmc_stainfo(padapter); + } else { + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + } + + if (psta==NULL) { + res = _FAIL; + goto exit; + } + + if (pxmitframe->buf_addr == NULL) { + res = _FAIL; + goto exit; + } + + pbuf_start = pxmitframe->buf_addr; + mem_start = pbuf_start + TXDESC_OFFSET; + + if (rtw_make_tdls_wlanhdr(padapter, mem_start, pattrib, ptxmgmt) == _FAIL) { + res = _FAIL; + goto exit; + } + + pframe = mem_start; + pframe += pattrib->hdrlen; + + //adding icv, if necessary... + if (pattrib->iv_len) + { + if (psta != NULL) + { + switch(pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + break; + case _TKIP_: + if(bmcst) + TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + TKIP_IV(pattrib->iv, psta->dot11txpn, 0); + break; + case _AES_: + if(bmcst) + AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + AES_IV(pattrib->iv, psta->dot11txpn, 0); + break; + } + } + + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + pframe += pattrib->iv_len; + + } + + llc_sz = rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + + //pattrib->pktlen will be counted in rtw_build_tdls_ies + pattrib->pktlen = 0; + + rtw_build_tdls_ies(padapter, pxmitframe, pframe, ptxmgmt); + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + pframe += pattrib->pktlen; + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + + pattrib->nr_frags = 1; + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + llc_sz + + ((pattrib->bswenc) ? pattrib->icv_len : 0) + pattrib->pktlen; + + if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) + { + res = _FAIL; + goto exit; + } + + xmitframe_swencrypt(padapter, pxmitframe); + + update_attrib_vcs_info(padapter, pxmitframe); + +exit: + +_func_exit_; + + return res; +} +#endif //CONFIG_TDLS + +/* + * Calculate wlan 802.11 packet MAX size from pkt_attrib + * This function doesn't consider fragment case + */ +u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib) +{ + u32 len = 0; + + len = pattrib->hdrlen + pattrib->iv_len; // WLAN Header and IV + len += SNAP_SIZE + sizeof(u16); // LLC + len += pattrib->pktlen; + if (pattrib->encrypt == _TKIP_) len += 8; // MIC + len += ((pattrib->bswenc) ? pattrib->icv_len : 0); // ICV + + return len; +} + +/* + +This sub-routine will perform all the following: + +1. remove 802.3 header. +2. create wlan_header, based on the info in pxmitframe +3. append sta's iv/ext-iv +4. append LLC +5. move frag chunk from pframe to pxmitframe->mem +6. apply sw-encrypt, if necessary. + +*/ +s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe) +{ + struct pkt_file pktfile; + + s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; + + SIZE_PTR addr; + + u8 *pframe, *mem_start; + u8 hw_hdr_offset; + + //struct sta_info *psta; + //struct sta_priv *pstapriv = &padapter->stapriv; + //struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + u8 *pbuf_start; + + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _SUCCESS; + +_func_enter_; + +/* + if (pattrib->psta) + { + psta = pattrib->psta; + } else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + + if(psta==NULL) + { + + DBG_871X("%s, psta==NUL\n", __func__); + return _FAIL; + } + + + if(!(psta->state &_FW_LINKED)) + { + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } +*/ + if (pxmitframe->buf_addr == NULL){ + DBG_8192C("==> %s buf_addr==NULL \n",__FUNCTION__); + return _FAIL; + } + + pbuf_start = pxmitframe->buf_addr; + +#ifdef CONFIG_USB_TX_AGGREGATION + hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); +#else + #ifdef CONFIG_TX_EARLY_MODE //for SDIO && Tx Agg + hw_hdr_offset = TXDESC_OFFSET + EARLY_MODE_INFO_SIZE; + #else + hw_hdr_offset = TXDESC_OFFSET; + #endif +#endif + + mem_start = pbuf_start + hw_hdr_offset; + + if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n")); + DBG_8192C("rtw_xmitframe_coalesce: rtw_make_wlanhdr fail; drop pkt\n"); + res = _FAIL; + goto exit; + } + + _rtw_open_pktfile(pkt, &pktfile); + _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); + + frg_inx = 0; + frg_len = pxmitpriv->frag_len - 4;//2346-4 = 2342 + + while (1) + { + llc_sz = 0; + + mpdu_len = frg_len; + + pframe = mem_start; + + SetMFrag(mem_start); + + pframe += pattrib->hdrlen; + mpdu_len -= pattrib->hdrlen; + + //adding icv, if necessary... + if (pattrib->iv_len) + { +/* + //if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) + // psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + //else + // psta = rtw_get_stainfo(pstapriv, pattrib->ra); + + if (psta != NULL) + { + switch(pattrib->encrypt) + { + case _WEP40_: + case _WEP104_: + WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + break; + case _TKIP_: + if(bmcst) + TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + TKIP_IV(pattrib->iv, psta->dot11txpn, 0); + break; + case _AES_: + if(bmcst) + AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx); + else + AES_IV(pattrib->iv, psta->dot11txpn, 0); + break; +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + rtw_wapi_get_iv(padapter,pattrib->ra,pattrib->iv); + break; +#endif + } + } +*/ + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, + ("rtw_xmitframe_coalesce: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n", + padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3))); + + pframe += pattrib->iv_len; + + mpdu_len -= pattrib->iv_len; + } + + if (frg_inx == 0) { + llc_sz = rtw_put_snap(pframe, pattrib->ether_type); + pframe += llc_sz; + mpdu_len -= llc_sz; + } + + if ((pattrib->icv_len >0) && (pattrib->bswenc)) { + mpdu_len -= pattrib->icv_len; + } + + + if (bmcst) { + // don't do fragment to broadcat/multicast packets + mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen); + } else { + mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len); + } + + pframe += mem_sz; + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + + frg_inx++; + + if (bmcst || (rtw_endofpktfile(&pktfile) == _TRUE)) + { + pattrib->nr_frags = frg_inx; + + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags==1)? llc_sz:0) + + ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz; + + ClearMFrag(mem_start); + + break; + } else { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __FUNCTION__)); + } + + addr = (SIZE_PTR)(pframe); + + mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset; + _rtw_memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); + + } + + if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) + { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n")); + DBG_8192C("xmitframe_addmic(padapter, pxmitframe)==_FAIL\n"); + res = _FAIL; + goto exit; + } + + xmitframe_swencrypt(padapter, pxmitframe); + + if(bmcst == _FALSE) + update_attrib_vcs_info(padapter, pxmitframe); + else + pattrib->vcs_mode = NONE_VCS; + +exit: + +_func_exit_; + + return res; +} + +#ifdef CONFIG_IEEE80211W +//broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption +s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe) +{ + struct pkt_file pktfile; + s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; + SIZE_PTR addr; + u8 *pframe, *mem_start = NULL, *tmp_buf=NULL; + u8 hw_hdr_offset, subtype ; + struct sta_info *psta = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + u8 *pbuf_start; + s32 bmcst = IS_MCAST(pattrib->ra); + s32 res = _FAIL; + u8 *BIP_AAD=NULL; + u8 *MGMT_body=NULL; + + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct rtw_ieee80211_hdr *pwlanhdr; + u8 MME[_MME_IE_LENGTH_]; + + _irqL irqL; + u32 ori_len; + mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET; + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + +_func_enter_; + ori_len = BIP_AAD_SIZE+pattrib->pktlen; + tmp_buf = BIP_AAD = rtw_zmalloc(ori_len); + subtype = GetFrameSubType(pframe); //bit(7)~bit(2) + + if(BIP_AAD == NULL) + return _FAIL; + + _enter_critical_bh(&padapter->security_key_mutex, &irqL); + + + //IGTK key is not install, it may not support 802.11w + if(padapter->securitypriv.binstallBIPkey != _TRUE) + { + DBG_871X("no instll BIP key\n"); + goto xmitframe_coalesce_success; + } + //station mode doesn't need TX BIP, just ready the code + if(bmcst) + { + int frame_body_len; + u8 mic[16]; + + _rtw_memset(MME, 0, _MME_IE_LENGTH_); + + //other types doesn't need the BIP + if(GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC) + goto xmitframe_coalesce_fail; + + MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pattrib->pktlen; + + //octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0 + MME[0]=padapter->securitypriv.dot11wBIPKeyid; + //copy packet number + _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6); + //increase the packet number + pmlmeext->mgnt_80211w_IPN++; + + //add MME IE with MIC all zero, MME string doesn't include element id and length + pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen)); + pattrib->last_txcmdsz = pattrib->pktlen; + // total frame length - header length + frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr); + + //conscruct AAD, copy frame control field + _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2); + ClearRetry(BIP_AAD); + ClearPwrMgt(BIP_AAD); + ClearMData(BIP_AAD); + //conscruct AAD, copy address 1 to address 3 + _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18); + //copy management fram body + _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len); + /*//dump total packet include MME with zero MIC + { + int i; + printk("Total packet: "); + for(i=0; i < BIP_AAD_SIZE+frame_body_len; i++) + printk(" %02x ", BIP_AAD[i]); + printk("\n"); + }*/ + //calculate mic + if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey + , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic)) + goto xmitframe_coalesce_fail; + + /*//dump calculated mic result + { + int i; + printk("Calculated mic result: "); + for(i=0; i<16; i++) + printk(" %02x ", mic[i]); + printk("\n"); + }*/ + //copy right BIP mic value, total is 128bits, we use the 0~63 bits + _rtw_memcpy(pframe-8, mic, 8); + /*/dump all packet after mic ok + { + int pp; + printk("pattrib->pktlen = %d \n", pattrib->pktlen); + for(pp=0;pp< pattrib->pktlen; pp++) + printk(" %02x ", mem_start[pp]); + printk("\n"); + }*/ + } + else //unicast mgmt frame TX + { + //start to encrypt mgmt frame + if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || + subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) + { + if (pattrib->psta) + psta = pattrib->psta; + else + { + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + } + + if(psta==NULL) + { + + DBG_871X("%s, psta==NUL\n", __func__); + goto xmitframe_coalesce_fail; + } + + if (pxmitframe->buf_addr == NULL) { + DBG_871X("%s, pxmitframe->buf_addr\n", __func__); + goto xmitframe_coalesce_fail; + } + + //DBG_871X("%s, action frame category=%d \n", __func__, pframe[WLAN_HDR_A3_LEN]); + //according 802.11-2012 standard, these five types are not robust types + if(subtype == WIFI_ACTION && + (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED || + pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P)) + goto xmitframe_coalesce_fail; + //before encrypt dump the management packet content + /*{ + int i; + printk("Management pkt: "); + for(i=0; ipktlen; i++) + printk(" %02x ", pframe[i]); + printk("=======\n"); + }*/ + if(pattrib->encrypt>0) + _rtw_memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16); + + /* To use wrong key */ + if (pattrib->key_type == IEEE80211W_WRONG_KEY) { + DBG_871X("use wrong key\n"); + pattrib->dot118021x_UncstKey.skey[0] = 0xff; + } + + //bakeup original management packet + _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen); + //move to data portion + pframe += pattrib->hdrlen; + + //802.11w unicast management packet must be _AES_ + pattrib->iv_len = 8; + //it's MIC of AES + pattrib->icv_len = 8; + + switch(pattrib->encrypt) + { + case _AES_: + //set AES IV header + AES_IV(pattrib->iv, psta->dot11wtxpn, 0); + break; + default: + goto xmitframe_coalesce_fail; + } + //insert iv header into management frame + _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len); + pframe += pattrib->iv_len; + //copy mgmt data portion after CCMP header + _rtw_memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen); + //move pframe to end of mgmt pkt + pframe += pattrib->pktlen-pattrib->hdrlen; + //add 8 bytes CCMP IV header to length + pattrib->pktlen += pattrib->iv_len; + /*//dump management packet include AES IV header + { + int i; + printk("Management pkt + IV: "); + //for(i=0; ipktlen; i++) + //printk(" %02x ", mem_start[i]); + printk("@@@@@@@@@@@@@\n"); + }*/ + + if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) { + _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len); + pframe += pattrib->icv_len; + } + //add 8 bytes MIC + pattrib->pktlen += pattrib->icv_len; + //set final tx command size + pattrib->last_txcmdsz = pattrib->pktlen; + + //set protected bit must be beofre SW encrypt + SetPrivacy(mem_start); + /*//dump management packet include AES header + { + int i; + printk("prepare to enc Management pkt + IV: "); + for(i=0; ipktlen; i++) + printk(" %02x ", mem_start[i]); + printk("@@@@@@@@@@@@@\n"); + }*/ + //software encrypt + xmitframe_swencrypt(padapter, pxmitframe); + } + } + +xmitframe_coalesce_success: + _exit_critical_bh(&padapter->security_key_mutex, &irqL); + rtw_mfree(BIP_AAD, ori_len); +_func_exit_; + return _SUCCESS; + +xmitframe_coalesce_fail: + _exit_critical_bh(&padapter->security_key_mutex, &irqL); + rtw_mfree(BIP_AAD, ori_len); +_func_exit_; + + return _FAIL; +} +#endif //CONFIG_IEEE80211W + +/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header + * IEEE LLC/SNAP header contains 8 octets + * First 3 octets comprise the LLC portion + * SNAP portion, 5 octets, is divided into two fields: + * Organizationally Unique Identifier(OUI), 3 octets, + * type, defined by that organization, 2 octets. + */ +s32 rtw_put_snap(u8 *data, u16 h_proto) +{ + struct ieee80211_snap_hdr *snap; + u8 *oui; + +_func_enter_; + + snap = (struct ieee80211_snap_hdr *)data; + snap->dsap = 0xaa; + snap->ssap = 0xaa; + snap->ctrl = 0x03; + + if (h_proto == 0x8137 || h_proto == 0x80f3) + oui = P802_1H_OUI; + else + oui = RFC1042_OUI; + + snap->oui[0] = oui[0]; + snap->oui[1] = oui[1]; + snap->oui[2] = oui[2]; + + *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + +_func_exit_; + + return SNAP_SIZE + sizeof(u16); +} + +void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len) +{ + + uint protection; + u8 *perp; + sint erp_len; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + +_func_enter_; + + switch(pxmitpriv->vcs_setting) + { + case DISABLE_VCS: + pxmitpriv->vcs = NONE_VCS; + break; + + case ENABLE_VCS: + break; + + case AUTO_VCS: + default: + perp = rtw_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len); + if(perp == NULL) + { + pxmitpriv->vcs = NONE_VCS; + } + else + { + protection = (*(perp + 2)) & BIT(1); + if (protection) + { + if(pregistrypriv->vcs_type == RTS_CTS) + pxmitpriv->vcs = RTS_CTS; + else + pxmitpriv->vcs = CTS_TO_SELF; + } + else + pxmitpriv->vcs = NONE_VCS; + } + + break; + + } + +_func_exit_; + +} + +void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, int sz) +{ + struct sta_info *psta = NULL; + struct stainfo_stats *pstats = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 pkt_num = 1; + + if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) + { +#if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pkt_num = pxmitframe->agg_num; +#endif + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num; + + pxmitpriv->tx_pkts += pkt_num; + + pxmitpriv->tx_bytes += sz; + + psta = pxmitframe->attrib.psta; + if (psta) + { + pstats = &psta->sta_stats; + + pstats->tx_pkts += pkt_num; + + pstats->tx_bytes += sz; +#ifdef CONFIG_TDLS + if(pxmitframe->attrib.ptdls_sta != NULL) + { + pstats = &(pxmitframe->attrib.ptdls_sta->sta_stats); + pstats->tx_pkts += pkt_num; + pstats->tx_bytes += sz; + } +#endif //CONFIG_TDLS + } + +#ifdef CONFIG_CHECK_LEAVE_LPS + //traffic_check_for_leave_lps(padapter, _TRUE); +#endif //CONFIG_LPS + + } +} + +static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv, + enum cmdbuf_type buf_type) +{ + struct xmit_buf *pxmitbuf = NULL; + +_func_enter_; + + pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type]; + if (pxmitbuf != NULL) { + pxmitbuf->priv_data = NULL; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; + pxmitbuf->agg_num = 0; + pxmitbuf->pg_num = 0; +#endif +#ifdef CONFIG_PCI_HCI + pxmitbuf->len = 0; + pxmitbuf->desc = NULL; +#endif + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); + } + } else { + DBG_871X("%s fail, no xmitbuf available !!!\n", __func__); + } + +exit: + +_func_exit_; + + return pxmitbuf; +} + +struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv, + enum cmdbuf_type buf_type) +{ + struct xmit_frame *pcmdframe; + struct xmit_buf *pxmitbuf; + + if ((pcmdframe = rtw_alloc_xmitframe(pxmitpriv)) == NULL) + { + DBG_871X("%s, alloc xmitframe fail\n", __FUNCTION__); + return NULL; + } + + if ((pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type)) == NULL) { + DBG_871X("%s, alloc xmitbuf fail\n", __FUNCTION__); + rtw_free_xmitframe(pxmitpriv, pcmdframe); + return NULL; + } + + pcmdframe->frame_tag = MGNT_FRAMETAG; + + pcmdframe->pxmitbuf = pxmitbuf; + + pcmdframe->buf_addr = pxmitbuf->pbuf; + + pxmitbuf->priv_data = pcmdframe; + + return pcmdframe; + +} + +struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_buf *pxmitbuf = NULL; + _list *plist, *phead; + _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; + +_func_enter_; + + _enter_critical(&pfree_queue->lock, &irqL); + + if(_rtw_queue_empty(pfree_queue) == _TRUE) { + pxmitbuf = NULL; + } else { + + phead = get_list_head(pfree_queue); + + plist = get_next(phead); + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + + rtw_list_delete(&(pxmitbuf->list)); + } + + if (pxmitbuf != NULL) + { + pxmitpriv->free_xmit_extbuf_cnt--; + #ifdef DBG_XMIT_BUF_EXT + DBG_871X("DBG_XMIT_BUF_EXT ALLOC no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmit_extbuf_cnt); + #endif + + + pxmitbuf->priv_data = NULL; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; + pxmitbuf->agg_num = 1; +#endif +#ifdef CONFIG_PCI_HCI + pxmitbuf->len = 0; + pxmitbuf->desc = NULL; +#endif + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); + } + + } + + _exit_critical(&pfree_queue->lock, &irqL); + +_func_exit_; + + return pxmitbuf; +} + +s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + _irqL irqL; + _queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; + +_func_enter_; + + if(pxmitbuf==NULL) + { + return _FAIL; + } + + _enter_critical(&pfree_queue->lock, &irqL); + + rtw_list_delete(&pxmitbuf->list); + + rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue)); + pxmitpriv->free_xmit_extbuf_cnt++; + #ifdef DBG_XMIT_BUF_EXT + DBG_871X("DBG_XMIT_BUF_EXT FREE no=%d, free_xmit_extbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmit_extbuf_cnt); + #endif + + _exit_critical(&pfree_queue->lock, &irqL); + +_func_exit_; + + return _SUCCESS; +} + +struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_buf *pxmitbuf = NULL; + _list *plist, *phead; + _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; + +_func_enter_; + + //DBG_871X("+rtw_alloc_xmitbuf\n"); + + _enter_critical(&pfree_xmitbuf_queue->lock, &irqL); + + if(_rtw_queue_empty(pfree_xmitbuf_queue) == _TRUE) { + pxmitbuf = NULL; + } else { + + phead = get_list_head(pfree_xmitbuf_queue); + + plist = get_next(phead); + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + + rtw_list_delete(&(pxmitbuf->list)); + } + + if (pxmitbuf != NULL) + { + pxmitpriv->free_xmitbuf_cnt--; + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF ALLOC no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no, pxmitpriv->free_xmitbuf_cnt); + #endif + //DBG_871X("alloc, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); + + pxmitbuf->priv_data = NULL; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxmitbuf->len = 0; + pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; + pxmitbuf->agg_num = 0; + pxmitbuf->pg_num = 0; +#endif +#ifdef CONFIG_PCI_HCI + pxmitbuf->len = 0; + pxmitbuf->desc = NULL; +#endif + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); + } + } + #ifdef DBG_XMIT_BUF + else + { + DBG_871X("DBG_XMIT_BUF rtw_alloc_xmitbuf return NULL\n"); + } + #endif + + _exit_critical(&pfree_xmitbuf_queue->lock, &irqL); + +_func_exit_; + + return pxmitbuf; +} + +s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) +{ + _irqL irqL; + _queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; + +_func_enter_; + + //DBG_871X("+rtw_free_xmitbuf\n"); + + if(pxmitbuf==NULL) + { + return _FAIL; + } + + if (pxmitbuf->sctx) { + DBG_871X("%s pxmitbuf->sctx is not NULL\n", __func__); + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE); + } + + if(pxmitbuf->buf_tag == XMITBUF_CMD) { + } + else if(pxmitbuf->buf_tag == XMITBUF_MGNT) { + rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf); + } + else + { + _enter_critical(&pfree_xmitbuf_queue->lock, &irqL); + + rtw_list_delete(&pxmitbuf->list); + + rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue)); + + pxmitpriv->free_xmitbuf_cnt++; + //DBG_871X("FREE, free_xmitbuf_cnt=%d\n", pxmitpriv->free_xmitbuf_cnt); + #ifdef DBG_XMIT_BUF + DBG_871X("DBG_XMIT_BUF FREE no=%d, free_xmitbuf_cnt=%d\n",pxmitbuf->no ,pxmitpriv->free_xmitbuf_cnt); + #endif + _exit_critical(&pfree_xmitbuf_queue->lock, &irqL); + } + +_func_exit_; + + return _SUCCESS; +} + +void rtw_init_xmitframe(struct xmit_frame *pxframe) +{ + if (pxframe != NULL)//default value setting + { + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib)); + //pxframe->attrib.psta = NULL; + + pxframe->frame_tag = DATA_FRAMETAG; + +#ifdef CONFIG_USB_HCI + pxframe->pkt = NULL; +#ifdef USB_PACKET_OFFSET_SZ + pxframe->pkt_offset = (PACKET_OFFSET_SZ/8); +#else + pxframe->pkt_offset = 1;//default use pkt_offset to fill tx desc +#endif + +#ifdef CONFIG_USB_TX_AGGREGATION + pxframe->agg_num = 1; +#endif + +#endif //#ifdef CONFIG_USB_HCI + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pxframe->pg_num = 1; + pxframe->agg_num = 1; +#endif + +#ifdef CONFIG_XMIT_ACK + pxframe->ack_report = 0; +#endif + + } +} + +/* +Calling context: +1. OS_TXENTRY +2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) + +If we turn on USE_RXTHREAD, then, no need for critical section. +Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... + +Must be very very cautious... + +*/ +struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)//(_queue *pfree_xmit_queue) +{ + /* + Please remember to use all the osdep_service api, + and lock/unlock or _enter/_exit critical to protect + pfree_xmit_queue + */ + + _irqL irqL; + struct xmit_frame *pxframe = NULL; + _list *plist, *phead; + _queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; + +_func_enter_; + + _enter_critical_bh(&pfree_xmit_queue->lock, &irqL); + + if (_rtw_queue_empty(pfree_xmit_queue) == _TRUE) { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt)); + pxframe = NULL; + } else { + phead = get_list_head(pfree_xmit_queue); + + plist = get_next(phead); + + pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + rtw_list_delete(&(pxframe->list)); + pxmitpriv->free_xmitframe_cnt--; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt)); + } + + _exit_critical_bh(&pfree_xmit_queue->lock, &irqL); + + rtw_init_xmitframe(pxframe); + +_func_exit_; + + return pxframe; +} + +struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv) +{ + _irqL irqL; + struct xmit_frame *pxframe = NULL; + _list *plist, *phead; + _queue *queue = &pxmitpriv->free_xframe_ext_queue; + +_func_enter_; + + _enter_critical_bh(&queue->lock, &irqL); + + if (_rtw_queue_empty(queue) == _TRUE) { + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_alloc_xmitframe_ext:%d\n", pxmitpriv->free_xframe_ext_cnt)); + pxframe = NULL; + } else { + phead = get_list_head(queue); + plist = get_next(phead); + pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + rtw_list_delete(&(pxframe->list)); + pxmitpriv->free_xframe_ext_cnt--; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe_ext():free_xmitframe_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt)); + } + + _exit_critical_bh(&queue->lock, &irqL); + + rtw_init_xmitframe(pxframe); + +_func_exit_; + + return pxframe; +} + +struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv) +{ + struct xmit_frame *pxframe = NULL; + u8 *alloc_addr; + + alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4); + + if (alloc_addr == NULL) + goto exit; + + pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4); + pxframe->alloc_addr = alloc_addr; + + pxframe->padapter = pxmitpriv->adapter; + pxframe->frame_tag = NULL_FRAMETAG; + + pxframe->pkt = NULL; + + pxframe->buf_addr = NULL; + pxframe->pxmitbuf = NULL; + + rtw_init_xmitframe(pxframe); + + DBG_871X("################## %s ##################\n", __func__); + +exit: + return pxframe; +} + +s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + _queue *queue = NULL; + _adapter *padapter = pxmitpriv->adapter; + _pkt *pndis_pkt = NULL; + +_func_enter_; + + if (pxmitframe == NULL) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("======rtw_free_xmitframe():pxmitframe==NULL!!!!!!!!!!\n")); + goto exit; + } + + if (pxmitframe->pkt){ + pndis_pkt = pxmitframe->pkt; + pxmitframe->pkt = NULL; + } + + if (pxmitframe->alloc_addr) { + DBG_871X("################## %s with alloc_addr ##################\n", __func__); + rtw_mfree(pxmitframe->alloc_addr, sizeof(struct xmit_frame) + 4); + goto check_pkt_complete; + } + + if (pxmitframe->ext_tag == 0) + queue = &pxmitpriv->free_xmit_queue; + else if(pxmitframe->ext_tag == 1) + queue = &pxmitpriv->free_xframe_ext_queue; + else + rtw_warn_on(1); + + _enter_critical_bh(&queue->lock, &irqL); + + rtw_list_delete(&pxmitframe->list); + rtw_list_insert_tail(&pxmitframe->list, get_list_head(queue)); + if (pxmitframe->ext_tag == 0) { + pxmitpriv->free_xmitframe_cnt++; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt)); + } else if(pxmitframe->ext_tag == 1) { + pxmitpriv->free_xframe_ext_cnt++; + RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xframe_ext_cnt=%d\n", pxmitpriv->free_xframe_ext_cnt)); + } else { + } + + _exit_critical_bh(&queue->lock, &irqL); + +check_pkt_complete: + + if(pndis_pkt) + rtw_os_pkt_complete(padapter, pndis_pkt); + +exit: + +_func_exit_; + + return _SUCCESS; +} + +void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue) +{ + _irqL irqL; + _list *plist, *phead; + struct xmit_frame *pxmitframe; + +_func_enter_; + + _enter_critical_bh(&(pframequeue->lock), &irqL); + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + plist = get_next(plist); + + rtw_free_xmitframe(pxmitpriv,pxmitframe); + + } + _exit_critical_bh(&(pframequeue->lock), &irqL); + +_func_exit_; +} + +s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue); + if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) + { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, + ("rtw_xmitframe_enqueue: drop xmit pkt for classifier fail\n")); +// pxmitframe->pkt = NULL; + return _FAIL; + } + + return _SUCCESS; +} + +static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, _queue *pframe_queue) +{ + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + + xmitframe_phead = get_list_head(pframe_queue); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + /* xmitframe_plist = get_next(xmitframe_plist); */ + +/*#ifdef RTK_DMP_PLATFORM +#ifdef CONFIG_USB_TX_AGGREGATION + if((ptxservq->qcnt>0) && (ptxservq->qcnt<=2)) + { + pxmitframe = NULL; + + tasklet_schedule(&pxmitpriv->xmit_tasklet); + + break; + } +#endif +#endif*/ + rtw_list_delete(&pxmitframe->list); + + ptxservq->qcnt--; + + //rtw_list_insert_tail(&pxmitframe->list, &phwxmit->pending); + + //ptxservq->qcnt--; + + break; + + //pxmitframe = NULL; + + } + + return pxmitframe; +} + +struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry) +{ + _irqL irqL0; + _list *sta_plist, *sta_phead; + struct hw_xmit *phwxmit; + struct tx_servq *ptxservq = NULL; + _queue *pframe_queue = NULL; + struct xmit_frame *pxmitframe = NULL; + _adapter *padapter = pxmitpriv->adapter; + struct registry_priv *pregpriv = &padapter->registrypriv; + int i, inx[4]; +#ifdef CONFIG_USB_HCI +// int j, tmp, acirp_cnt[4]; +#endif + +_func_enter_; + + inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; + + if(pregpriv->wifi_spec==1) + { + int j, tmp, acirp_cnt[4]; +#if 0 + if(flagswmm_para_seq[j]; +#endif + } + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + for(i = 0; i < entry; i++) + { + phwxmit = phwxmit_i + inx[i]; + + //_enter_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + sta_phead = get_list_head(phwxmit->sta_queue); + sta_plist = get_next(sta_phead); + + while ((rtw_end_of_queue_search(sta_phead, sta_plist)) == _FALSE) + { + + ptxservq= LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending); + + pframe_queue = &ptxservq->sta_pending; + + pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue); + + if(pxmitframe) + { + phwxmit->accnt--; + + //Remove sta node when there is no pending packets. + if(_rtw_queue_empty(pframe_queue)) //must be done after get_next and before break + rtw_list_delete(&ptxservq->tx_pending); + + //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + goto exit; + } + + sta_plist = get_next(sta_plist); + + } + + //_exit_critical_ex(&phwxmit->sta_queue->lock, &irqL0); + + } + +exit: + + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + +_func_exit_; + + return pxmitframe; +} + +#if 1 +struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac) +{ + struct tx_servq *ptxservq=NULL; + +_func_enter_; + + switch (up) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + *(ac) = 3; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n")); + break; + + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + *(ac) = 1; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n")); + break; + + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + *(ac) = 0; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n")); + break; + + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + *(ac) = 2; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n")); + break; + + } + +_func_exit_; + + return ptxservq; +} +#else +__inline static struct tx_servq *rtw_get_sta_pending + (_adapter *padapter, _queue **ppstapending, struct sta_info *psta, sint up) +{ + struct tx_servq *ptxservq; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + +_func_enter_; + +#ifdef CONFIG_RTL8711 + + if(IS_MCAST(psta->hwaddr)) + { + ptxservq = &(psta->sta_xmitpriv.be_q); // we will use be_q to queue bc/mc frames in BCMC_stainfo + *ppstapending = &padapter->xmitpriv.bm_pending; + } + else +#endif + { + switch (up) + { + case 1: + case 2: + ptxservq = &(psta->sta_xmitpriv.bk_q); + *ppstapending = &padapter->xmitpriv.bk_pending; + (phwxmits+3)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BK \n")); + break; + + case 4: + case 5: + ptxservq = &(psta->sta_xmitpriv.vi_q); + *ppstapending = &padapter->xmitpriv.vi_pending; + (phwxmits+1)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VI\n")); + break; + + case 6: + case 7: + ptxservq = &(psta->sta_xmitpriv.vo_q); + *ppstapending = &padapter->xmitpriv.vo_pending; + (phwxmits+0)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : VO \n")); + break; + + case 0: + case 3: + default: + ptxservq = &(psta->sta_xmitpriv.be_q); + *ppstapending = &padapter->xmitpriv.be_pending; + (phwxmits+2)->accnt++; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_get_sta_pending : BE \n")); + break; + + } + + } + +_func_exit_; + + return ptxservq; +} +#endif + +/* + * Will enqueue pxmitframe to the proper queue, + * and indicate it to xx_pending list..... + */ +s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + //_irqL irqL0; + u8 ac_index; + struct sta_info *psta; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct sta_priv *pstapriv = &padapter->stapriv; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + sint res = _SUCCESS; + +_func_enter_; + + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class); + +/* + if (pattrib->psta) { + psta = pattrib->psta; + } else { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta = rtw_get_stainfo(pstapriv, pattrib->ra); + } +*/ + + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_sta); + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return _FAIL; + } + + if (psta == NULL) { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_nosta); + res = _FAIL; + DBG_8192C("rtw_xmit_classifier: psta == NULL\n"); + RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("rtw_xmit_classifier: psta == NULL\n")); + goto exit; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_COUNTER(padapter->tx_logs.core_tx_enqueue_class_err_fwlink); + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FAIL; + } + + ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); + + //_enter_critical(&pstapending->lock, &irqL0); + + if (rtw_is_list_empty(&ptxservq->tx_pending)) { + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue)); + } + + //_enter_critical(&ptxservq->sta_pending.lock, &irqL1); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); + ptxservq->qcnt++; + phwxmits[ac_index].accnt++; + + //_exit_critical(&ptxservq->sta_pending.lock, &irqL1); + + //_exit_critical(&pstapending->lock, &irqL0); + +exit: + +_func_exit_; + + return res; +} + +void rtw_alloc_hwxmits(_adapter *padapter) +{ + struct hw_xmit *hwxmits; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; + + pxmitpriv->hwxmits = NULL; + + pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry); + + if(pxmitpriv->hwxmits == NULL) + { + DBG_871X("alloc hwxmits fail!...\n"); + return; + } + + hwxmits = pxmitpriv->hwxmits; + + if(pxmitpriv->hwxmit_entry == 5) + { + //pxmitpriv->bmc_txqueue.head = 0; + //hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; + hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; + + //pxmitpriv->vo_txqueue.head = 0; + //hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; + hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; + + //pxmitpriv->vi_txqueue.head = 0; + //hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; + hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; + + //pxmitpriv->bk_txqueue.head = 0; + //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; + hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + + //pxmitpriv->be_txqueue.head = 0; + //hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; + hwxmits[4] .sta_queue = &pxmitpriv->be_pending; + + } + else if(pxmitpriv->hwxmit_entry == 4) + { + + //pxmitpriv->vo_txqueue.head = 0; + //hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; + hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; + + //pxmitpriv->vi_txqueue.head = 0; + //hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; + hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; + + //pxmitpriv->be_txqueue.head = 0; + //hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; + hwxmits[2] .sta_queue = &pxmitpriv->be_pending; + + //pxmitpriv->bk_txqueue.head = 0; + //hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; + hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; + } + else + { + + + } + + +} + +void rtw_free_hwxmits(_adapter *padapter) +{ + struct hw_xmit *hwxmits; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + hwxmits = pxmitpriv->hwxmits; + if(hwxmits) + rtw_mfree((u8 *)hwxmits, (sizeof (struct hw_xmit) * pxmitpriv->hwxmit_entry)); +} + +void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry) +{ + sint i; +_func_enter_; + for(i = 0; i < entry; i++, phwxmit++) + { + //_rtw_spinlock_init(&phwxmit->xmit_lock); + //_rtw_init_listhead(&phwxmit->pending); + //phwxmit->txcmdcnt = 0; + phwxmit->accnt = 0; + } +_func_exit_; +} + +#ifdef CONFIG_BR_EXT +int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + //if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb); + int res, is_vlan_tag=0, i, do_nat25=1; + unsigned short vlan_hdr=0; + void *br_port = NULL; + + //mac_clone_handle_frame(priv, skb); + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + _enter_critical_bh(&padapter->br_ext_lock, &irqL); + if ( !(skb->data[0] & 1) && + br_port && + memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) && + *((unsigned short *)(skb->data+MACADDRLEN*2)) != __constant_htons(ETH_P_8021Q) && + *((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP) && + !memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) { + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + padapter->scdb_entry->ageing_timer = jiffies; + _exit_critical_bh(&padapter->br_ext_lock, &irqL); + } + else + //if (!priv->pmib->ethBrExtInfo.nat25_disable) + { +// if (priv->dev->br_port && +// !memcmp(skb->data+MACADDRLEN, priv->br_mac, MACADDRLEN)) { +#if 1 + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2)); + skb_pull(skb, 4); + } + //if SA == br_mac && skb== IP => copy SIP to br_ip ?? why + if (!memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) && + (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP))) + memcpy(padapter->br_ip, skb->data+WLAN_ETHHDR_LEN+12, 4); + + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)) { + if (memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN)) { + void *scdb_findEntry(_adapter *priv, unsigned char *macAddr, unsigned char *ipAddr); + + if ((padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, + skb->data+MACADDRLEN, skb->data+WLAN_ETHHDR_LEN+12)) != NULL) { + memcpy(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN); + memcpy(padapter->scdb_ip, skb->data+WLAN_ETHHDR_LEN+12, 4); + padapter->scdb_entry->ageing_timer = jiffies; + do_nat25 = 0; + } + } + else { + if (padapter->scdb_entry) { + padapter->scdb_entry->ageing_timer = jiffies; + do_nat25 = 0; + } + else { + memset(padapter->scdb_mac, 0, MACADDRLEN); + memset(padapter->scdb_ip, 0, 4); + } + } + } + _exit_critical_bh(&padapter->br_ext_lock, &irqL); +#endif // 1 + if (do_nat25) + { + int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method); + if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) { + struct sk_buff *newskb; + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr; + } + + newskb = rtw_skb_copy(skb); + if (newskb == NULL) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n"); + //goto stop_proc; + return -1; + } + rtw_skb_free(skb); + + *pskb = skb = newskb; + if (is_vlan_tag) { + vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2)); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2)); + skb_pull(skb, 4); + } + } + + if (skb_is_nonlinear(skb)) + DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __FUNCTION__); + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + res = skb_linearize(skb, GFP_ATOMIC); +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + res = skb_linearize(skb); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) + if (res < 0) { + DEBUG_ERR("TX DROP: skb_linearize fail!\n"); + //goto free_and_stop; + return -1; + } + + res = nat25_db_handle(padapter, skb, NAT25_INSERT); + if (res < 0) { + if (res == -2) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: nat25_db_handle fail!\n"); + //goto free_and_stop; + return -1; + + } + // we just print warning message and let it go + //DEBUG_WARN("%s()-%d: nat25_db_handle INSERT Warning!\n", __FUNCTION__, __LINE__); + //return -1; // return -1 will cause system crash on 2011/08/30! + return 0; + } + } + + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + + dhcp_flag_bcast(padapter, skb); + + if (is_vlan_tag) { + skb_push(skb, 4); + for (i=0; i<6; i++) + *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); + *((unsigned short *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q); + *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr; + } + } +#if 0 + else{ + if (*((unsigned short *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) { + is_vlan_tag = 1; + } + + if(is_vlan_tag){ + if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A_VALN(skb->data)){ + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + } + }else + { + if(ICMPV6_MCAST_MAC(skb->data) && ICMPV6_PROTO1A(skb->data)){ + memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN); + } + } + } +#endif // 0 + + // check if SA is equal to our MAC + if (memcmp(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) { + //priv->ext_stats.tx_drops++; + DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n", + skb->data[6],skb->data[7],skb->data[8],skb->data[9],skb->data[10],skb->data[11]); + //goto free_and_stop; + return -1; + } + } + return 0; +} +#endif // CONFIG_BR_EXT + +u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe) +{ + u32 addr; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + + switch(pattrib->qsel) + { + case 0: + case 3: + addr = BE_QUEUE_INX; + break; + case 1: + case 2: + addr = BK_QUEUE_INX; + break; + case 4: + case 5: + addr = VI_QUEUE_INX; + break; + case 6: + case 7: + addr = VO_QUEUE_INX; + break; + case 0x10: + addr = BCN_QUEUE_INX; + break; + case 0x11://BC/MC in PS (HIQ) + addr = HIGH_QUEUE_INX; + break; + case 0x12: + default: + addr = MGT_QUEUE_INX; + break; + + } + + return addr; + +} + +static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib) +{ + u8 qsel; + + qsel = pattrib->priority; + RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("### do_queue_select priority=%d ,qsel = %d\n",pattrib->priority ,qsel)); + +#ifdef CONFIG_CONCURRENT_MODE +// if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) +// qsel = 7;// +#endif + + pattrib->qsel = qsel; +} + +/* + * The main transmit(tx) entry + * + * Return + * 1 enqueue + * 0 success, hardware will handle this xmit frame(packet) + * <0 fail + */ +s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev) +{ + int ret = 0; + int rtap_len; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + u16 frame_ctl; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + struct rtw_ieee80211_hdr *dot11_hdr; + struct ieee80211_radiotap_header *rtap_hdr; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + + if (skb) + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize); + + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) + goto fail; + + rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; + if (unlikely(rtap_hdr->it_version)) + goto fail; + + rtap_len = ieee80211_get_radiotap_len(skb->data); + if (unlikely(skb->len < rtap_len)) + goto fail; + + if (rtap_len != 12) { + DBG_8192C("radiotap len (should be 14): %d\n", rtap_len); + goto fail; + } + + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + + dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data; + frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl); + /* Check if the QoS bit is set */ + + if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) { + + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 *buf = skb->data; + u32 len = skb->len; + u8 category, action; + int type = -1; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) { + rtw_udelay_os(500); + goto fail; + } + pattrib = &pmgntframe->attrib; + + update_monitor_frame_attrib(padapter, pattrib); + + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void *)buf, len); + + pattrib->pktlen = len; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1)) + pattrib->rate = MGN_24M; + + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + } else { + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 *buf = skb->data; + u32 len = skb->len; + u8 category, action; + int type = -1; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + if (pmgntframe == NULL) + goto fail; + + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void *)buf, len); + + pattrib->pktlen = len; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + } + +fail: + + rtw_skb_free(skb); + + return 0; +} + +/* + * The main transmit(tx) entry + * + * Return + * 1 enqueue + * 0 success, hardware will handle this xmit frame(packet) + * <0 fail + */ +s32 rtw_xmit(_adapter *padapter, _pkt **ppkt) +{ + static u32 start = 0; + static u32 drop_cnt = 0; +#ifdef CONFIG_AP_MODE + _irqL irqL0; +#endif + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct xmit_frame *pxmitframe = NULL; +#ifdef CONFIG_BR_EXT + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + void *br_port = NULL; +#endif // CONFIG_BR_EXT + + s32 res; + + DBG_COUNTER(padapter->tx_logs.core_tx); + + if (start == 0) + start = rtw_get_current_time(); + + pxmitframe = rtw_alloc_xmitframe(pxmitpriv); + + if (rtw_get_passing_time_ms(start) > 2000) { + if (drop_cnt) + DBG_871X("DBG_TX_DROP_FRAME %s no more pxmitframe, drop_cnt:%u\n", __FUNCTION__, drop_cnt); + start = rtw_get_current_time(); + drop_cnt = 0; + } + + if (pxmitframe == NULL) { + drop_cnt ++; + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: no more pxmitframe\n")); + DBG_COUNTER(padapter->tx_logs.core_tx_err_pxmitframe); + return -1; + } + +#ifdef CONFIG_BR_EXT + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + + if( br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + res = rtw_br_client_tx(padapter, ppkt); + if (res == -1) + { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + DBG_COUNTER(padapter->tx_logs.core_tx_err_brtx); + return -1; + } + } + +#endif // CONFIG_BR_EXT + + res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); + +#ifdef CONFIG_WAPI_SUPPORT + if(pxmitframe->attrib.ether_type != 0x88B4) + { + if(rtw_wapi_drop_for_key_absent(padapter, pxmitframe->attrib.ra)) + { + WAPI_TRACE(WAPI_RX,"drop for key absend when tx \n"); + res = _FAIL; + } + } +#endif + if (res == _FAIL) { + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit: update attrib fail\n")); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s update attrib fail\n", __FUNCTION__); + #endif + rtw_free_xmitframe(pxmitpriv, pxmitframe); + return -1; + } + pxmitframe->pkt = *ppkt; + + rtw_led_control(padapter, LED_CTL_TX); + + do_queue_select(padapter, &pxmitframe->attrib); + +#ifdef CONFIG_AP_MODE + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) + { + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue); + return 1; + } + _exit_critical_bh(&pxmitpriv->lock, &irqL0); +#endif + + //pre_xmitframe + if (rtw_hal_xmit(padapter, pxmitframe) == _FALSE) + return 1; + + return 0; +} + +#ifdef CONFIG_TDLS +sint xmitframe_enqueue_for_tdls_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + sint ret=_FALSE; + + _irqL irqL; + struct sta_info *ptdls_sta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + int i; + + ptdls_sta=rtw_get_stainfo(pstapriv, pattrib->dst); + if(ptdls_sta==NULL){ + return ret; + }else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE){ + + if(pattrib->triggered==1) + { + ret = _TRUE; + return ret; + } + + _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + + if(ptdls_sta->state&WIFI_SLEEP_STATE) + { + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptdls_sta->sleep_q)); + + ptdls_sta->sleepq_len++; + ptdls_sta->sleepq_ac_len++; + + //indicate 4-AC queue bit in TDLS peer traffic indication + switch(pattrib->priority) + { + case 1: + case 2: + ptdls_sta->uapsd_bk |= BIT(1); + break; + case 4: + case 5: + ptdls_sta->uapsd_vi |= BIT(1); + break; + case 6: + case 7: + ptdls_sta->uapsd_vo |= BIT(1); + break; + case 0: + case 3: + default: + ptdls_sta->uapsd_be |= BIT(1); + break; + } + + /* Transmit TDLS PTI via AP */ + if(ptdls_sta->sleepq_len==1) + rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ISSUE_PTI); + + ret = _TRUE; + } + + _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL); + } + + return ret; + +} +#endif //CONFIG_TDLS + +#define RTW_HIQ_FILTER_ALLOW_ALL 0 +#define RTW_HIQ_FILTER_ALLOW_SPECIAL 1 +#define RTW_HIQ_FILTER_DENY_ALL 2 + +inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe) +{ + bool allow = _FALSE; + _adapter *adapter = xmitframe->padapter; + struct registry_priv *registry = &adapter->registrypriv; + +if (rtw_get_intf_type(adapter) != RTW_PCIE) { + + if (adapter->registrypriv.wifi_spec == 1) { + allow = _TRUE; + } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) { + + struct pkt_attrib *attrib = &xmitframe->attrib; + + if (attrib->ether_type == 0x0806 + || attrib->ether_type == 0x888e + #ifdef CONFIG_WAPI_SUPPORT + || attrib->ether_type == 0x88B4 + #endif + || attrib->dhcp_pkt + ) { + if (0) + DBG_871X(FUNC_ADPT_FMT" ether_type:0x%04x%s\n", FUNC_ADPT_ARG(xmitframe->padapter) + , attrib->ether_type, attrib->dhcp_pkt?" DHCP":""); + allow = _TRUE; + } + } + else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL) { + allow = _TRUE; + } + else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) { + } + else { + rtw_warn_on(1); + } +} + return allow; +} + +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) + +sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + _irqL irqL; + sint ret=_FALSE; + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + sint bmcst = IS_MCAST(pattrib->ra); + bool update_tim = _FALSE; +#ifdef CONFIG_TDLS + + if( padapter->tdlsinfo.link_established == _TRUE ) + { + ret = xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pxmitframe); + } +#endif //CONFIG_TDLS + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _FALSE) + { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_fwstate); + return ret; + } +/* + if(pattrib->psta) + { + psta = pattrib->psta; + } + else + { + DBG_871X("%s, call rtw_get_stainfo()\n", __func__); + psta=rtw_get_stainfo(pstapriv, pattrib->ra); + } +*/ + psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra); + if(pattrib->psta != psta) + { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_sta); + DBG_871X("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta); + return _FALSE; + } + + if(psta==NULL) + { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_nosta); + DBG_871X("%s, psta==NUL\n", __func__); + return _FALSE; + } + + if(!(psta->state &_FW_LINKED)) + { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_link); + DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); + return _FALSE; + } + + if(pattrib->triggered==1) + { + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_warn_trigger); + //DBG_871X("directly xmit pspoll_triggered packet\n"); + + //pattrib->triggered=0; + if (bmcst && xmitframe_hiq_filter(pxmitframe) == _TRUE) + pattrib->qsel = QSLT_HIGH;//HIQ + + return ret; + } + + + if(bmcst) + { + _enter_critical_bh(&psta->sleep_q.lock, &irqL); + + if(pstapriv->sta_dz_bitmap)//if anyone sta is in ps mode + { + //pattrib->qsel = QSLT_HIGH;//HIQ + + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); + + psta->sleepq_len++; + + if (!(pstapriv->tim_bitmap & BIT(0))) + update_tim = _TRUE; + + pstapriv->tim_bitmap |= BIT(0);// + pstapriv->sta_dz_bitmap |= BIT(0); + + //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + if (padapter->registrypriv.wifi_spec == 1) { + /* + *if (update_tim == _TRUE) + * rtw_chk_hi_queue_cmd(padapter); + */ + } else { + + if (update_tim == _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); + } + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + + ret = _TRUE; + + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_mcast); + + } + + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + + return ret; + + } + + + _enter_critical_bh(&psta->sleep_q.lock, &irqL); + + if(psta->state&WIFI_SLEEP_STATE) + { + u8 wmmps_ac=0; + + if(pstapriv->sta_dz_bitmap&BIT(psta->aid)) + { + rtw_list_delete(&pxmitframe->list); + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + + rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); + + psta->sleepq_len++; + + switch(pattrib->priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(0); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(0); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(0); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(0); + break; + } + + if(wmmps_ac) + psta->sleepq_ac_len++; + + if(((psta->has_legacy_ac) && (!wmmps_ac)) ||((!psta->has_legacy_ac)&&(wmmps_ac))) + { + if (!(pstapriv->tim_bitmap & BIT(psta->aid))) + update_tim = _TRUE; + + pstapriv->tim_bitmap |= BIT(psta->aid); + + //DBG_871X("enqueue, sq_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); + + if(update_tim == _TRUE) + { + //DBG_871X("sleepq_len==1, update BCNTIM\n"); + //upate BCN for TIM IE + _update_beacon(padapter, _TIM_IE_, NULL, _TRUE, "buffer UC"); + } + } + + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + + //if(psta->sleepq_len > (NR_XMITFRAME>>3)) + //{ + // wakeup_sta_to_xmit(padapter, psta); + //} + + ret = _TRUE; + + DBG_COUNTER(padapter->tx_logs.core_tx_ap_enqueue_ucast); + } + + } + + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + + return ret; + +} + +static void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue) +{ + sint ret; + _list *plist, *phead; + u8 ac_index; + struct tx_servq *ptxservq; + struct pkt_attrib *pattrib; + struct xmit_frame *pxmitframe; + struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; + + phead = get_list_head(pframequeue); + plist = get_next(phead); + + while (rtw_end_of_queue_search(phead, plist) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list); + + plist = get_next(plist); + + pattrib = &pxmitframe->attrib; + + pattrib->triggered = 0; + + ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe); + + if(_TRUE == ret) + { + ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); + + ptxservq->qcnt--; + phwxmits[ac_index].accnt--; + } + else + { + //DBG_871X("xmitframe_enqueue_for_sleeping_sta return _FALSE\n"); + } + + } + +} + +void stop_sta_xmit(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL0; + struct sta_info *psta_bmc; + struct sta_xmit_priv *pstaxmitpriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + pstaxmitpriv = &psta->sta_xmitpriv; + + //for BC/MC Frames + psta_bmc = rtw_get_bcmc_stainfo(padapter); + + + _enter_critical_bh(&pxmitpriv->lock, &irqL0); + + psta->state |= WIFI_SLEEP_STATE; + +#ifdef CONFIG_TDLS + if( !(psta->tdls_sta_state & TDLS_LINKED_STATE) ) +#endif //CONFIG_TDLS + pstapriv->sta_dz_bitmap |= BIT(psta->aid); + + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); + + + dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending)); + +#ifdef CONFIG_TDLS + if (!(psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta_bmc != NULL)) { +#endif //CONFIG_TDLS + + + //for BC/MC Frames + pstaxmitpriv = &psta_bmc->sta_xmitpriv; + dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending); + rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending)); + + +#ifdef CONFIG_TDLS + } +#endif //CONFIG_TDLS + _exit_critical_bh(&pxmitpriv->lock, &irqL0); + + +} + +void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + u8 update_mask=0, wmmps_ac=0; + struct sta_info *psta_bmc; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + psta_bmc = rtw_get_bcmc_stainfo(padapter); + + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + switch(pxmitframe->attrib.priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + psta->sleepq_len--; + if(psta->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + if(wmmps_ac) + { + psta->sleepq_ac_len--; + if(psta->sleepq_ac_len>0) + { + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + } + else + { + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + } + + pxmitframe->attrib.triggered = 1; + +/* + _exit_critical_bh(&psta->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta->sleep_q.lock, &irqL); +*/ + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + + } + + if(psta->sleepq_len==0) + { +#ifdef CONFIG_TDLS + if( psta->tdls_sta_state & TDLS_LINKED_STATE ) + { + if(psta->state&WIFI_SLEEP_STATE) + psta->state ^= WIFI_SLEEP_STATE; + + _exit_critical_bh(&pxmitpriv->lock, &irqL); + return; + } +#endif //CONFIG_TDLS + + if (pstapriv->tim_bitmap & BIT(psta->aid)) { + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_mask = BIT(0); + } + + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + if(psta->state&WIFI_SLEEP_STATE) + psta->state ^= WIFI_SLEEP_STATE; + + if(psta->state & WIFI_STA_ALIVE_CHK_STATE) + { + DBG_871X("%s alive check\n", __func__); + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } + + pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); + } + + //for BC/MC Frames + if(!psta_bmc) + goto _exit; + + if((pstapriv->sta_dz_bitmap&0xfffe) == 0x0)//no any sta in ps mode + { + xmitframe_phead = get_list_head(&psta_bmc->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + rtw_list_delete(&pxmitframe->list); + + psta_bmc->sleepq_len--; + if(psta_bmc->sleepq_len>0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; + + + pxmitframe->attrib.triggered = 1; +/* + _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE) + { + rtw_os_xmit_complete(padapter, pxmitframe); + } + _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + +*/ + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + } + + if(psta_bmc->sleepq_len==0) + { + if (pstapriv->tim_bitmap & BIT(0)) { + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_mask |= BIT(1); + } + pstapriv->tim_bitmap &= ~BIT(0); + pstapriv->sta_dz_bitmap &= ~BIT(0); + } + + } + +_exit: + + //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + if(update_mask) + { + //update_BCNTIM(padapter); + 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"); + } + +} + +void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta) +{ + _irqL irqL; + u8 wmmps_ac=0; + _list *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + + //_enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = get_next(xmitframe_phead); + + while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) + { + pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); + + xmitframe_plist = get_next(xmitframe_plist); + + switch(pxmitframe->attrib.priority) + { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk&BIT(1); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi&BIT(1); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo&BIT(1); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be&BIT(1); + break; + } + + if(!wmmps_ac) + continue; + + rtw_list_delete(&pxmitframe->list); + + psta->sleepq_len--; + psta->sleepq_ac_len--; + + if(psta->sleepq_ac_len>0) + { + pxmitframe->attrib.mdata = 1; + pxmitframe->attrib.eosp = 0; + } + else + { + pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.eosp = 1; + } + + pxmitframe->attrib.triggered = 1; + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); + + if((psta->sleepq_ac_len==0) && (!psta->has_legacy_ac) && (wmmps_ac)) + { +#ifdef CONFIG_TDLS + if(psta->tdls_sta_state & TDLS_LINKED_STATE ) + { + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + goto exit; + } +#endif //CONFIG_TDLS + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap); + //upate BCN for TIM IE + //update_BCNTIM(padapter); + update_beacon(padapter, _TIM_IE_, NULL, _TRUE); + //update_mask = BIT(0); + } + + } + +exit: + //_exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + + return; +} + +#endif /* defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) */ + +#ifdef CONFIG_XMIT_THREAD_MODE +void enqueue_pending_xmitbuf( + struct xmit_priv *pxmitpriv, + struct xmit_buf *pxmitbuf) +{ + _irqL irql; + _queue *pqueue; + _adapter *pri_adapter = pxmitpriv->adapter; + + pqueue = &pxmitpriv->pending_xmitbuf_queue; + + _enter_critical_bh(&pqueue->lock, &irql); + rtw_list_delete(&pxmitbuf->list); + rtw_list_insert_tail(&pxmitbuf->list, get_list_head(pqueue)); + _exit_critical_bh(&pqueue->lock, &irql); + + + +#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_CONCURRENT_MODE) + if (pri_adapter->adapter_type > PRIMARY_ADAPTER) + pri_adapter = pri_adapter->pbuddy_adapter; +#endif //SDIO_HCI + CONCURRENT + _rtw_up_sema(&(pri_adapter->xmitpriv.xmit_sema)); + +} + +void enqueue_pending_xmitbuf_to_head( + struct xmit_priv *pxmitpriv, + struct xmit_buf *pxmitbuf) +{ + _irqL irql; + _queue *pqueue; + _adapter *pri_adapter = pxmitpriv->adapter; + + pqueue = &pxmitpriv->pending_xmitbuf_queue; + + _enter_critical_bh(&pqueue->lock, &irql); + rtw_list_delete(&pxmitbuf->list); + rtw_list_insert_head(&pxmitbuf->list, get_list_head(pqueue)); + _exit_critical_bh(&pqueue->lock, &irql); +} + +struct xmit_buf* dequeue_pending_xmitbuf( + struct xmit_priv *pxmitpriv) +{ + _irqL irql; + struct xmit_buf *pxmitbuf; + _queue *pqueue; + + + pxmitbuf = NULL; + pqueue = &pxmitpriv->pending_xmitbuf_queue; + + _enter_critical_bh(&pqueue->lock, &irql); + + if (_rtw_queue_empty(pqueue) == _FALSE) + { + _list *plist, *phead; + + phead = get_list_head(pqueue); + plist = get_next(phead); + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + rtw_list_delete(&pxmitbuf->list); + } + + _exit_critical_bh(&pqueue->lock, &irql); + + return pxmitbuf; +} + +struct xmit_buf* dequeue_pending_xmitbuf_under_survey( + struct xmit_priv *pxmitpriv) +{ + _irqL irql; + struct xmit_buf *pxmitbuf; +#ifdef CONFIG_USB_HCI + struct xmit_frame *pxmitframe; +#endif + _queue *pqueue; + + + pxmitbuf = NULL; + pqueue = &pxmitpriv->pending_xmitbuf_queue; + + _enter_critical_bh(&pqueue->lock, &irql); + + if (_rtw_queue_empty(pqueue) == _FALSE) + { + _list *plist, *phead; + u8 type; + + phead = get_list_head(pqueue); + plist = phead; + do { + plist = get_next(plist); + if (plist == phead) break; + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + +#ifdef CONFIG_USB_HCI + pxmitframe = (struct xmit_frame*)pxmitbuf->priv_data; + if(pxmitframe) + { + type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ); + } + else + { + DBG_871X("%s, !!!ERROR!!! For USB, TODO ITEM \n", __FUNCTION__); + } +#else + type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_OFFSET); +#endif + + if ((type == WIFI_PROBEREQ) || + (type == WIFI_DATA_NULL) || + (type == WIFI_QOS_DATA_NULL)) + { + rtw_list_delete(&pxmitbuf->list); + break; + } + pxmitbuf = NULL; + } while (1); + } + + _exit_critical_bh(&pqueue->lock, &irql); + + return pxmitbuf; +} + +sint check_pending_xmitbuf( + struct xmit_priv *pxmitpriv) +{ + _irqL irql; + _queue *pqueue; + sint ret = _FALSE; + + pqueue = &pxmitpriv->pending_xmitbuf_queue; + + _enter_critical_bh(&pqueue->lock, &irql); + + if(_rtw_queue_empty(pqueue) == _FALSE) + ret = _TRUE; + + _exit_critical_bh(&pqueue->lock, &irql); + + return ret; +} + +thread_return rtw_xmit_thread(thread_context context) +{ + s32 err; + PADAPTER padapter; + + + err = _SUCCESS; + padapter = (PADAPTER)context; + + thread_enter("RTW_XMIT_THREAD"); + + do { + err = rtw_hal_xmit_thread_handler(padapter); + flush_signals_thread(); + } while (_SUCCESS == err); + + _rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema); + + thread_exit(); +} +#endif + +bool rtw_xmit_ac_blocked(_adapter *adapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + _adapter *iface; + struct mlme_ext_priv *mlmeext; + struct mlme_ext_info *mlmeextinfo; + bool blocked = _FALSE; + int i; + + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + mlmeext = &iface->mlmeextpriv; + + /* check scan state */ + if (mlmeext_scan_state(mlmeext) != SCAN_DISABLE + && mlmeext_scan_state(mlmeext) != SCAN_BACK_OP + ) { + blocked = _TRUE; + goto exit; + } + + if (mlmeext_scan_state(mlmeext) == SCAN_BACK_OP + && !mlmeext_chk_scan_backop_flags(mlmeext, SS_BACKOP_TX_RESUME) + ) { + blocked = _TRUE; + goto exit; + } + } + +exit: + return blocked; +} + +void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms) +{ + sctx->timeout_ms = timeout_ms; + sctx->submit_time= rtw_get_current_time(); +#ifdef PLATFORM_LINUX /* TODO: add condition wating interface for other os */ + init_completion(&sctx->done); +#endif + sctx->status = RTW_SCTX_SUBMITTED; +} + +int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg) +{ + int ret = _FAIL; + unsigned long expire; + int status = 0; + +#ifdef PLATFORM_LINUX + expire= sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT; + if (!wait_for_completion_timeout(&sctx->done, expire)) { + /* timeout, do something?? */ + status = RTW_SCTX_DONE_TIMEOUT; + DBG_871X("%s timeout: %s\n", __func__, msg); + } else { + status = sctx->status; + } +#endif + + if (status == RTW_SCTX_DONE_SUCCESS) { + ret = _SUCCESS; + } + + return ret; +} + +bool rtw_sctx_chk_waring_status(int status) +{ + switch(status) { + case RTW_SCTX_DONE_UNKNOWN: + case RTW_SCTX_DONE_BUF_ALLOC: + case RTW_SCTX_DONE_BUF_FREE: + + case RTW_SCTX_DONE_DRV_STOP: + case RTW_SCTX_DONE_DEV_REMOVE: + return _TRUE; + default: + return _FALSE; + } +} + +void rtw_sctx_done_err(struct submit_ctx **sctx, int status) +{ + if (*sctx) { + if (rtw_sctx_chk_waring_status(status)) + DBG_871X("%s status:%d\n", __func__, status); + (*sctx)->status = status; + #ifdef PLATFORM_LINUX + complete(&((*sctx)->done)); + #endif + *sctx = NULL; + } +} + +void rtw_sctx_done(struct submit_ctx **sctx) +{ + rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); +} + +#ifdef CONFIG_XMIT_ACK + +#ifdef CONFIG_XMIT_ACK_POLLING +s32 c2h_evt_hdl(_adapter *adapter, u8 *c2h_evt, c2h_id_filter filter); + +/** + * rtw_ack_tx_polling - + * @pxmitpriv: xmit_priv to address ack_tx_ops + * @timeout_ms: timeout msec + * + * Init ack_tx_ops and then do c2h_evt_hdl() and polling ack_tx_ops repeatedly + * till tx report or timeout + * Returns: _SUCCESS if TX report ok, _FAIL for others + */ +int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms) +{ + int ret = _FAIL; + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv); + + pack_tx_ops->submit_time = rtw_get_current_time(); + pack_tx_ops->timeout_ms = timeout_ms; + pack_tx_ops->status = RTW_SCTX_SUBMITTED; + + do { + c2h_evt_hdl(adapter, NULL, rtw_hal_c2h_id_filter_ccx(adapter)); + if (pack_tx_ops->status != RTW_SCTX_SUBMITTED) + break; + + if (rtw_is_drv_stopped(adapter)) { + pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP; + break; + } + if (rtw_is_surprise_removed(adapter)) { + pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE; + break; + } + + rtw_msleep_os(10); + } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms); + + if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) { + pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT; + DBG_871X("%s timeout\n", __func__); + } + + if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS) + ret = _SUCCESS; + + return ret; +} +#endif + +int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms) +{ +#ifdef CONFIG_XMIT_ACK_POLLING + return rtw_ack_tx_polling(pxmitpriv, timeout_ms); +#else + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + + pack_tx_ops->submit_time = rtw_get_current_time(); + pack_tx_ops->timeout_ms = timeout_ms; + pack_tx_ops->status = RTW_SCTX_SUBMITTED; + + return rtw_sctx_wait(pack_tx_ops, __func__); +#endif +} + +void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status) +{ + struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; + + if (pxmitpriv->ack_tx) { + rtw_sctx_done_err(&pack_tx_ops, status); + } else { + DBG_871X("%s ack_tx not set\n", __func__); + } +} +#endif //CONFIG_XMIT_ACK + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/HalPwrSeqCmd.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/HalPwrSeqCmd.c new file mode 100644 index 00000000..732c4d8f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/HalPwrSeqCmd.c @@ -0,0 +1,183 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/*++ +Copyright (c) Realtek Semiconductor Corp. All rights reserved. + +Module Name: + HalPwrSeqCmd.c + +Abstract: + Implement HW Power sequence configuration CMD handling routine for Realtek devices. + +Major Change History: + When Who What + ---------- --------------- ------------------------------- + 2011-10-26 Lucas Modify to be compatible with SD4-CE driver. + 2011-07-07 Roger Create. + +--*/ +#include + + +// +// Description: +// This routine deal with the Power Configuration CMDs parsing for RTL8723/RTL8188E Series IC. +// +// Assumption: +// We should follow specific format which was released from HW SD. +// +// 2011.07.07, added by Roger. +// +u8 HalPwrSeqCmdParsing( + PADAPTER padapter, + u8 CutVersion, + u8 FabVersion, + u8 InterfaceType, + WLAN_PWR_CFG PwrSeqCmd[]) +{ + WLAN_PWR_CFG PwrCfgCmd = {0}; + u8 bPollingBit = _FALSE; + u32 AryIdx = 0; + u8 value = 0; + u32 offset = 0; + u32 pollingCount = 0; // polling autoload done. + u32 maxPollingCnt = 5000; + + do { + PwrCfgCmd = PwrSeqCmd[AryIdx]; + + RT_TRACE(_module_hal_init_c_ , _drv_info_, + ("HalPwrSeqCmdParsing: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n", + GET_PWR_CFG_OFFSET(PwrCfgCmd), + GET_PWR_CFG_CUT_MASK(PwrCfgCmd), + GET_PWR_CFG_FAB_MASK(PwrCfgCmd), + GET_PWR_CFG_INTF_MASK(PwrCfgCmd), + GET_PWR_CFG_BASE(PwrCfgCmd), + GET_PWR_CFG_CMD(PwrCfgCmd), + GET_PWR_CFG_MASK(PwrCfgCmd), + GET_PWR_CFG_VALUE(PwrCfgCmd))); + + //2 Only Handle the command whose FAB, CUT, and Interface are matched + if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && + (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && + (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) + { + switch (GET_PWR_CFG_CMD(PwrCfgCmd)) + { + case PWR_CMD_READ: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_READ\n")); + break; + + case PWR_CMD_WRITE: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_WRITE\n")); + offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); + +#ifdef CONFIG_SDIO_HCI + // + // We should deal with interface specific address mapping for some interfaces, e.g., SDIO interface + // 2011.07.07. + // + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + { + // Read Back SDIO Local value + value = SdioLocalCmd52Read1Byte(padapter, offset); + + value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); + value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd)); + + // Write Back SDIO Local value + SdioLocalCmd52Write1Byte(padapter, offset, value); + } + else +#endif + { +#ifdef CONFIG_GSPI_HCI + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + offset = SPI_LOCAL_OFFSET | offset; +#endif + // Read the value from system register + value = rtw_read8(padapter, offset); + + value=value&(~(GET_PWR_CFG_MASK(PwrCfgCmd))); + value=value|(GET_PWR_CFG_VALUE(PwrCfgCmd)&GET_PWR_CFG_MASK(PwrCfgCmd)); + + // Write the value back to sytem register + rtw_write8(padapter, offset, value); + } + break; + + case PWR_CMD_POLLING: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n")); + + bPollingBit = _FALSE; + offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); +#ifdef CONFIG_GSPI_HCI + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + offset = SPI_LOCAL_OFFSET | offset; +#endif + do { +#ifdef CONFIG_SDIO_HCI + if (GET_PWR_CFG_BASE(PwrCfgCmd) == PWR_BASEADDR_SDIO) + value = SdioLocalCmd52Read1Byte(padapter, offset); + else +#endif + value = rtw_read8(padapter, offset); + + value=value&GET_PWR_CFG_MASK(PwrCfgCmd); + if (value == (GET_PWR_CFG_VALUE(PwrCfgCmd) & GET_PWR_CFG_MASK(PwrCfgCmd))) + bPollingBit = _TRUE; + else + rtw_udelay_os(10); + + if (pollingCount++ > maxPollingCnt) { + DBG_871X_LEVEL(_drv_err_, "HalPwrSeqCmdParsing: Fail to polling Offset[%#x]=%02x\n", offset, value); + return _FALSE; + } + } while (!bPollingBit); + + break; + + case PWR_CMD_DELAY: + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_DELAY\n")); + if (GET_PWR_CFG_VALUE(PwrCfgCmd) == PWRSEQ_DELAY_US) + rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)); + else + rtw_udelay_os(GET_PWR_CFG_OFFSET(PwrCfgCmd)*1000); + break; + + case PWR_CMD_END: + // When this command is parsed, end the process + RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_END\n")); + return _TRUE; + break; + + default: + RT_TRACE(_module_hal_init_c_ , _drv_err_, ("HalPwrSeqCmdParsing: Unknown CMD!!\n")); + break; + } + } + + AryIdx++;//Add Array Index + }while(1); + + return _TRUE; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.c new file mode 100644 index 00000000..d8d4a11f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.c @@ -0,0 +1,1987 @@ +//============================================================ +// Description: +// +// This file is for 92CE/92CU BT 1 Antenna Co-exist mechanism +// +// By cosa 02/11/2011 +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8188c2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8188C_2ANT GLCoexDm8188c2Ant; +static PCOEX_DM_8188C_2ANT pCoexDm=&GLCoexDm8188c2Ant; +static COEX_STA_8188C_2ANT GLCoexSta8188c2Ant; +static PCOEX_STA_8188C_2ANT pCoexSta=&GLCoexSta8188c2Ant; + +//============================================================ +// local function start with btdm_ +//============================================================ +u1Byte +halbtc8188c2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8188C_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8188C_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8188C_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +u1Byte +halbtc8188c2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + u1Byte algorithm=BT_8188C_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + if(!pStackInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No profile exists!!!\n")); + return algorithm; + } + + if(pStackInfo->bScoExist) + numOfDiffProfile++; + if(pStackInfo->bHidExist) + numOfDiffProfile++; + if(pStackInfo->bPanExist) + numOfDiffProfile++; + if(pStackInfo->bA2dpExist) + numOfDiffProfile++; + + if(pStackInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO algorithm\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_SCO; + } + else + { + if(numOfDiffProfile == 1) + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_A2DP; + } + else if(pStackInfo->bPanExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN only\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_PAN; + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_HID_A2DP; + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_HID_PAN; + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN + A2DP\n")); + algorithm = BT_8188C_2ANT_COEX_ALGO_PAN_A2DP; + } + } + } + return algorithm; +} + +VOID +halbtc8188c2ant_SetFwBalance( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBalanceOn, + IN u1Byte ms0, + IN u1Byte ms1 + ) +{ + u1Byte H2C_Parameter[3] ={0}; + + if(bBalanceOn) + { + H2C_Parameter[2] = 1; + H2C_Parameter[1] = ms1; + H2C_Parameter[0] = ms0; + } + else + { + H2C_Parameter[2] = 0; + H2C_Parameter[1] = 0; + H2C_Parameter[0] = 0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", + bBalanceOn?"ON":"OFF", ms0, ms1, + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0xc, 3, H2C_Parameter); +} + +VOID +halbtc8188c2ant_Balance( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bBalanceOn, + IN u1Byte ms0, + IN u1Byte ms1 + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Balance %s\n", + (bForceExec? "force to":""), (bBalanceOn? "ON":"OFF"))); + pCoexDm->bCurBalanceOn = bBalanceOn; + + if(!bForceExec) + { + if(pCoexDm->bPreBalanceOn == pCoexDm->bCurBalanceOn) + return; + } + halbtc8188c2ant_SetFwBalance(pBtCoexist, bBalanceOn, ms0, ms1); + + pCoexDm->bPreBalanceOn = pCoexDm->bCurBalanceOn; +} + +VOID +halbtc8188c2ant_SetFwDiminishWifi( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bDacOn, + IN BOOLEAN bInterruptOn, + IN u1Byte fwDacSwingLvl, + IN BOOLEAN bNavOn + ) +{ + u1Byte H2C_Parameter[3] ={0}; + + if((pBtCoexist->stackInfo.minBtRssi <= -5) && (fwDacSwingLvl == 0x20)) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n")); + fwDacSwingLvl = 0x18; + } + + H2C_Parameter[2] = 0; + H2C_Parameter[1] = fwDacSwingLvl; + H2C_Parameter[0] = 0; + if(bDacOn) + { + H2C_Parameter[2] |= 0x01; //BIT0 + if(bInterruptOn) + { + H2C_Parameter[2] |= 0x02; //BIT1 + } + } + if(bNavOn) + { + H2C_Parameter[2] |= 0x08; //BIT3 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bDacOn=%s, bInterruptOn=%s, bNavOn=%s, write 0xe=0x%x\n", + (bDacOn?"ON":"OFF"), (bInterruptOn?"ON":"OFF"), (bNavOn?"ON":"OFF"), + (H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]))); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0xe, 3, H2C_Parameter); +} + +VOID +halbtc8188c2ant_DiminishWifi( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacOn, + IN BOOLEAN bInterruptOn, + IN u1Byte fwDacSwingLvl, + IN BOOLEAN bNavOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set Diminish Wifi, bDacOn=%s, bInterruptOn=%s, fwDacSwingLvl=%d, bNavOn=%s\n", + (bForceExec? "force to":""), (bDacOn? "ON":"OFF"), (bInterruptOn? "ON":"OFF"), fwDacSwingLvl, (bNavOn? "ON":"OFF"))); + + pCoexDm->bCurDacOn = bDacOn; + pCoexDm->bCurInterruptOn = bInterruptOn; + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + pCoexDm->bCurNavOn = bNavOn; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacOn==pCoexDm->bCurDacOn) && + (pCoexDm->bPreInterruptOn==pCoexDm->bCurInterruptOn) && + (pCoexDm->preFwDacSwingLvl==pCoexDm->curFwDacSwingLvl) && + (pCoexDm->bPreNavOn==pCoexDm->bCurNavOn) ) + return; + } + halbtc8188c2ant_SetFwDiminishWifi(pBtCoexist, bDacOn, bInterruptOn, fwDacSwingLvl, bNavOn); + + pCoexDm->bPreDacOn = pCoexDm->bCurDacOn; + pCoexDm->bPreInterruptOn = pCoexDm->bCurInterruptOn; + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; + pCoexDm->bPreNavOn = pCoexDm->bCurNavOn; +} + +VOID +halbtc8188c2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xf0, 0xf); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xf0, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8188c2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8188c2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8188c2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8188c2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8188c2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8188c2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + u4Byte dacSwingLvl; + + if(bSwDacSwingOn) + { + if((pBtCoexist->stackInfo.minBtRssi <= -5) && (swDacSwingLvl == 0x20)) + { + dacSwingLvl = 0x18; + } + else + { + dacSwingLvl = swDacSwingLvl; + } + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xfc000000, dacSwingLvl); + } + else + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xfc000000, 0x30); + } +} + +VOID +halbtc8188c2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8188c2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8188c2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a07611); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a05611); + } +} + +VOID +halbtc8188c2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8188c2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8188c2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4e1c0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4d1d0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4c1e0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4b1f0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4a200001); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xdc000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x90000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x51000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x12000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x00255); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x641c0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x631d0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x621e0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x611f0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x60200001); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x32000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x71000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xb0000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xfc000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x10255); + } + + // set rssiAdjustVal for wifi module. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + + +VOID +halbtc8188c2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8188c2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8188c2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u4Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8188c2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u4Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8188c2ant_SetCoexTable(pBtCoexist, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8188c2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} +VOID +halbtc8188c2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + + +VOID +halbtc8188c2ant_MonitorBtState( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN stateChange=FALSE; + u4Byte BT_Polling, Ratio_Act, Ratio_STA; + u4Byte BT_Active, BT_State; + u4Byte regBTActive=0, regBTState=0, regBTPolling=0; + u4Byte btBusyThresh=0; + u4Byte fwVer=0; + static BOOLEAN bBtBusyTraffic=FALSE; + BOOLEAN bRejApAggPkt=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FirmwareVersion = 0x%x(%d)\n", fwVer, fwVer)); + if(fwVer < 62) + { + regBTActive = 0x488; + regBTState = 0x48c; + regBTPolling = 0x490; + } + else + { + regBTActive = 0x444; + regBTState = 0x448; + if(fwVer >= 74) + regBTPolling = 0x44c; + else + regBTPolling = 0x700; + } + btBusyThresh = 60; + + BT_Active = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTActive); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_Active(0x%x)=0x%x\n", regBTActive, BT_Active)); + BT_Active = BT_Active & 0x00ffffff; + + BT_State = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTState); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_State(0x%x)=0x%x\n", regBTState, BT_State)); + BT_State = BT_State & 0x00ffffff; + + BT_Polling = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTPolling); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_Polling(0x%x)=0x%x\n", regBTPolling, BT_Polling)); + + if(BT_Active==0xffffffff && BT_State==0xffffffff && BT_Polling==0xffffffff ) + return; + + // 2011/05/04 MH For Slim combo test meet a problem. Surprise remove and WLAN is running + // DHCP process. At the same time, the register read value might be zero. And cause BSOD 0x7f + // EXCEPTION_DIVIDED_BY_ZERO. In This case, the stack content may always be wrong due to + // HW divide trap. + if (BT_Polling==0) + return; + + Ratio_Act = BT_Active*1000/BT_Polling; + Ratio_STA = BT_State*1000/BT_Polling; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ratio_Act=%d\n", Ratio_Act)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ratio_STA=%d\n", Ratio_STA)); + + if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_STA < 60) // BT PAN idle + { + } + else + { + // Check if BT PAN (under BT 2.1) is uplink or downlink + if((Ratio_Act/Ratio_STA) < 2) + { // BT PAN Uplink + pCoexSta->bBtUplink = TRUE; + } + else + { // BT PAN downlink + pCoexSta->bBtUplink = FALSE; + } + } + } + + // Check BT is idle or not + if(!pBtCoexist->stackInfo.bBtLinkExist) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_Act<20) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + pCoexSta->bBtBusy = TRUE; + } + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_STA < btBusyThresh) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + pCoexSta->bBtBusy = TRUE; + } + + if( (Ratio_STA < btBusyThresh) || + (Ratio_Act<180 && Ratio_STA<130) ) + { + pCoexSta->bA2dpBusy = FALSE; + } + else + { + pCoexSta->bA2dpBusy = TRUE; + } + } + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &pCoexSta->bBtBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &pCoexSta->bBtBusy); + + if(bBtBusyTraffic != pCoexSta->bBtBusy) + { // BT idle or BT non-idle + bBtBusyTraffic = pCoexSta->bBtBusy; + stateChange = TRUE; + } + + if(stateChange) + { + if(!pCoexSta->bBtBusy) + { + halbtc8188c2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_CoexAllOff(pBtCoexist); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + } + else + { + halbtc8188c2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + } + } + + if(stateChange) + { + bRejApAggPkt = pCoexSta->bBtBusy; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejApAggPkt); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + } +} + +VOID +halbtc8188c2ant_ActionA2dpBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + + if(pCoexSta->bBtBusy) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0xc, 0x18); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0xc, 0x18); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + } + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionA2dpBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + BOOLEAN bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + if(pCoexSta->bA2dpBusy && bWifiBusy) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0xc, 0x18); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x18); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + } + else if(pCoexSta->bA2dpBusy) + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, TRUE, 0x18, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionA2dpBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionA2dpBc8(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionPanBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + if(bBtHsOn) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + else + { + if(pCoexSta->bBtBusy && bWifiBusy) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x10); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + } + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} + +VOID +halbtc8188c2ant_ActionPanBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + s4Byte wifiRssi; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(bBtHsOn) + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + else + { + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 3, 25, 50); + + if(pCoexSta->bBtBusy && bWifiBusy) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + if(pCoexSta->bBtUplink) + { + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + } + else if( (wifiRssiState == BTC_RSSI_STATE_MEDIUM) || + (wifiRssiState == BTC_RSSI_STATE_STAY_MEDIUM) ) + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE);//BT_FW_NAV_ON); + else + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + if(pCoexSta->bBtUplink) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE);//BT_FW_NAV_ON); + } + else + { + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + } + else + { + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + } + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else if(pCoexSta->bBtBusy && !bWifiBusy && (wifiRssi < 30)) + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x0a, 0x20); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + } +} + +VOID +halbtc8188c2ant_ActionPan( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionPanBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionPanBc8(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte wifiBw, wifiTrafficDir; + BOOLEAN bWifiBusy=FALSE; + + 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); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(!bWifiBusy) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + else if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} + + +VOID +halbtc8188c2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw; + + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + } +} + +VOID +halbtc8188c2ant_ActionHidA2dpBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + + if(pCoexSta->bBtBusy) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x7, 0x20); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x7, 0x20); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + } + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } +} +VOID +halbtc8188c2ant_ActionHidA2dpBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw; + + if(pCoexSta->bBtBusy) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + } + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionHidA2dpBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionHidA2dpBc8(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionHidPanBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(bBtHsOn) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else + { + 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); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x10); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(!bWifiBusy) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + } + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} +VOID +halbtc8188c2ant_ActionHidPanBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!bBtHsOn) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0); + if((pCoexSta->bBtBusy && bWifiBusy)) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x15, 0x20); + } + else + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x20); + } + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + } + else + { + if(BTC_INTF_USB == pBtCoexist->chipInterface) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8188c2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + } + else + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + } +} + +VOID +halbtc8188c2ant_ActionHidPan( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionHidPanBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionHidPanBc8(pBtCoexist); + } +} + +VOID +halbtc8188c2ant_ActionPanA2dpBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + if(bBtHsOn) + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + } + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + if(pCoexSta->bBtBusy && bWifiBusy) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x10); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } +} +VOID +halbtc8188c2ant_ActionPanA2dpBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!bBtHsOn) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + wifiRssiState = halbtc8188c2ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0); + if((pCoexSta->bBtBusy && bWifiBusy)) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x15, 0x20); + } + else + { + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x20); + } + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + } + else + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8188c2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8188c2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8188c2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8188c2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } +} + +VOID +halbtc8188c2ant_ActionPanA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionPanA2dpBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8188c2ant_ActionPanA2dpBc8(pBtCoexist); + } +} + +//============================================================ +// extern function start with EXhalbtc8188c2ant_ +//============================================================ +VOID +EXhalbtc8188c2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8188c2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xf0); + + if( (BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) || + (BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) ) + { + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd) & BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, u1Tmp); + + halbtc8188c2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0xaaaa9aaa, 0xffbd0040, 0x40000010); + } +} + +VOID +EXhalbtc8188c2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8188c2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8188c2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + // 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); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); + CL_PRINTF(cliBuf); + + if(pStackInfo->bProfileNotified) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + + // Sw mechanism + 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/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8188c2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + //halbtc8188c2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8188c2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + halbtc8188c2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + halbtc8188c2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8188c2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } +} + +VOID +EXhalbtc8188c2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8188c2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + +} + +VOID +EXhalbtc8188c2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8188c2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ +} + +VOID +EXhalbtc8188c2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + EXhalbtc8188c2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8188c2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Periodical!!\n")); + + // NOTE: + // sw mechanism must be done after fw mechanism + // + + if((BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) || + (BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) ) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_GET_BT_RSSI, NULL); + + halbtc8188c2ant_MonitorBtState(pBtCoexist); + algorithm = halbtc8188c2ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + switch(pCoexDm->curAlgorithm) + { + case BT_8188C_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO\n")); + halbtc8188c2ant_ActionSco(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID\n")); + halbtc8188c2ant_ActionHid(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP\n")); + halbtc8188c2ant_ActionA2dp(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_PAN: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN\n")); + halbtc8188c2ant_ActionPan(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP\n")); + halbtc8188c2ant_ActionHidA2dp(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_HID_PAN: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+HID\n")); + halbtc8188c2ant_ActionHidPan(pBtCoexist); + break; + case BT_8188C_2ANT_COEX_ALGO_PAN_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP\n")); + halbtc8188c2ant_ActionPanA2dp(pBtCoexist); + break; + default: + break; + } + } +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.h new file mode 100644 index 00000000..ce7ec564 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8188c2Ant.h @@ -0,0 +1,149 @@ +//=========================================== +// The following is for 8188C 2Ant BT Co-exist definition +//=========================================== +#define BTC_RSSI_COEX_THRESH_TOL_8188C_2ANT 6 + +typedef enum _BT_INFO_SRC_8188C_2ANT{ + BT_INFO_SRC_8188C_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8188C_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8188C_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8188C_2ANT_MAX +}BT_INFO_SRC_8188C_2ANT,*PBT_INFO_SRC_8188C_2ANT; + +typedef enum _BT_8188C_2ANT_BT_STATUS{ + BT_8188C_2ANT_BT_STATUS_IDLE = 0x0, + BT_8188C_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8188C_2ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8188C_2ANT_BT_STATUS_MAX +}BT_8188C_2ANT_BT_STATUS,*PBT_8188C_2ANT_BT_STATUS; + +typedef enum _BT_8188C_2ANT_COEX_ALGO{ + BT_8188C_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8188C_2ANT_COEX_ALGO_SCO = 0x1, + BT_8188C_2ANT_COEX_ALGO_HID = 0x2, + BT_8188C_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8188C_2ANT_COEX_ALGO_PAN = 0x4, + BT_8188C_2ANT_COEX_ALGO_HID_A2DP = 0x5, + BT_8188C_2ANT_COEX_ALGO_HID_PAN = 0x6, + BT_8188C_2ANT_COEX_ALGO_PAN_A2DP = 0x7, + BT_8188C_2ANT_COEX_ALGO_MAX +}BT_8188C_2ANT_COEX_ALGO,*PBT_8188C_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8188C_2ANT{ + // fw mechanism + BOOLEAN bPreBalanceOn; + BOOLEAN bCurBalanceOn; + + // diminishWifi + BOOLEAN bPreDacOn; + BOOLEAN bCurDacOn; + BOOLEAN bPreInterruptOn; + BOOLEAN bCurInterruptOn; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bPreNavOn; + BOOLEAN bCurNavOn; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + //u4Byte preVal0x6c0; + //u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u4Byte preVal0x6cc; + u4Byte curVal0x6cc; + //BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + //u1Byte btStatus; + //u1Byte wifiChnlInfo[3]; +} COEX_DM_8188C_2ANT, *PCOEX_DM_8188C_2ANT; + +typedef struct _COEX_STA_8188C_2ANT{ + u1Byte preWifiRssiState[4]; + BOOLEAN bBtBusy; + BOOLEAN bBtUplink; + BOOLEAN bBtDownLink; + BOOLEAN bA2dpBusy; +}COEX_STA_8188C_2ANT, *PCOEX_STA_8188C_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8188c2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8188c2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8188c2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8188c2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8188c2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8188c2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8188c2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8188c2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.c new file mode 100644 index 00000000..239c073c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.c @@ -0,0 +1,1992 @@ +//============================================================ +// Description: +// +// This file is for 92D BT 2 Antenna Co-exist mechanism +// +// By cosa 02/11/2011 +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8192d2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8192D_2ANT GLCoexDm8192d2Ant; +static PCOEX_DM_8192D_2ANT pCoexDm=&GLCoexDm8192d2Ant; +static COEX_STA_8192D_2ANT GLCoexSta8192d2Ant; +static PCOEX_STA_8192D_2ANT pCoexSta=&GLCoexSta8192d2Ant; + +//============================================================ +// local function start with btdm_ +//============================================================ +u1Byte +halbtc8192d2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192D_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192D_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192D_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +u1Byte +halbtc8192d2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8192D_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pStackInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No profile exists!!!\n")); + return algorithm; + } + + if(pStackInfo->bScoExist) + numOfDiffProfile++; + if(pStackInfo->bHidExist) + numOfDiffProfile++; + if(pStackInfo->bPanExist) + numOfDiffProfile++; + if(pStackInfo->bA2dpExist) + numOfDiffProfile++; + + if(pStackInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO algorithm\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_SCO; + } + else + { + if(numOfDiffProfile == 1) + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_A2DP; + } + else if(pStackInfo->bPanExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN only\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_PAN; + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_HID_A2DP; + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_HID_PAN; + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN + A2DP\n")); + algorithm = BT_8192D_2ANT_COEX_ALGO_PAN_A2DP; + } + } + } + return algorithm; +} + +VOID +halbtc8192d2ant_SetFwBalance( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBalanceOn, + IN u1Byte ms0, + IN u1Byte ms1 + ) +{ + u1Byte H2C_Parameter[3] ={0}; + + if(bBalanceOn) + { + H2C_Parameter[2] = 1; + H2C_Parameter[1] = ms1; + H2C_Parameter[0] = ms0; + } + else + { + H2C_Parameter[2] = 0; + H2C_Parameter[1] = 0; + H2C_Parameter[0] = 0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", + bBalanceOn?"ON":"OFF", ms0, ms1, + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0xc, 3, H2C_Parameter); +} + +VOID +halbtc8192d2ant_Balance( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bBalanceOn, + IN u1Byte ms0, + IN u1Byte ms1 + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Balance %s\n", + (bForceExec? "force to":""), (bBalanceOn? "ON":"OFF"))); + pCoexDm->bCurBalanceOn = bBalanceOn; + + if(!bForceExec) + { + if(pCoexDm->bPreBalanceOn == pCoexDm->bCurBalanceOn) + return; + } + halbtc8192d2ant_SetFwBalance(pBtCoexist, bBalanceOn, ms0, ms1); + + pCoexDm->bPreBalanceOn = pCoexDm->bCurBalanceOn; +} + +VOID +halbtc8192d2ant_SetFwDiminishWifi( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bDacOn, + IN BOOLEAN bInterruptOn, + IN u1Byte fwDacSwingLvl, + IN BOOLEAN bNavOn + ) +{ + u1Byte H2C_Parameter[3] ={0}; + + if((pBtCoexist->stackInfo.minBtRssi <= -5) && (fwDacSwingLvl == 0x20)) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n")); + fwDacSwingLvl = 0x18; + } + + H2C_Parameter[2] = 0; + H2C_Parameter[1] = fwDacSwingLvl; + H2C_Parameter[0] = 0; + if(bDacOn) + { + H2C_Parameter[2] |= 0x01; //BIT0 + if(bInterruptOn) + { + H2C_Parameter[2] |= 0x02; //BIT1 + } + } + if(bNavOn) + { + H2C_Parameter[2] |= 0x08; //BIT3 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bDacOn=%s, bInterruptOn=%s, bNavOn=%s, write 0x12=0x%x\n", + (bDacOn?"ON":"OFF"), (bInterruptOn?"ON":"OFF"), (bNavOn?"ON":"OFF"), + (H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]))); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x12, 3, H2C_Parameter); +} + + +VOID +halbtc8192d2ant_DiminishWifi( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacOn, + IN BOOLEAN bInterruptOn, + IN u1Byte fwDacSwingLvl, + IN BOOLEAN bNavOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set Diminish Wifi, bDacOn=%s, bInterruptOn=%s, fwDacSwingLvl=%d, bNavOn=%s\n", + (bForceExec? "force to":""), (bDacOn? "ON":"OFF"), (bInterruptOn? "ON":"OFF"), fwDacSwingLvl, (bNavOn? "ON":"OFF"))); + + pCoexDm->bCurDacOn = bDacOn; + pCoexDm->bCurInterruptOn = bInterruptOn; + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + pCoexDm->bCurNavOn = bNavOn; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacOn==pCoexDm->bCurDacOn) && + (pCoexDm->bPreInterruptOn==pCoexDm->bCurInterruptOn) && + (pCoexDm->preFwDacSwingLvl==pCoexDm->curFwDacSwingLvl) && + (pCoexDm->bPreNavOn==pCoexDm->bCurNavOn) ) + return; + } + halbtc8192d2ant_SetFwDiminishWifi(pBtCoexist, bDacOn, bInterruptOn, fwDacSwingLvl, bNavOn); + + pCoexDm->bPreDacOn = pCoexDm->bCurDacOn; + pCoexDm->bPreInterruptOn = pCoexDm->bCurInterruptOn; + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; + pCoexDm->bPreNavOn = pCoexDm->bCurNavOn; +} + +VOID +halbtc8192d2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf2ff7); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + + +VOID +halbtc8192d2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8192d2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8192d2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8192d2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8192d2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8192d2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + u4Byte dacSwingLvl; + + if(bSwDacSwingOn) + { + if((pBtCoexist->stackInfo.minBtRssi <= -5) && (swDacSwingLvl == 0x20)) + { + dacSwingLvl = 0x18; + } + else + { + dacSwingLvl = swDacSwingLvl; + } + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xfc000000, dacSwingLvl); + } + else + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xfc000000, 0x30); + } +} + +VOID +halbtc8192d2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8192d2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8192d2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a07611); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a05611); + } +} + +VOID +halbtc8192d2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8192d2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8192d2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0xa99); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xd4000); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b000001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b010001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b020001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b030001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b040001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b050001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b060001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b070001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b080001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b090001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b0A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7b0B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7a0C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x790D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x780E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x770F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x76100001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x75110001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x74120001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x73130001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x72140001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x71150001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x70160001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6f170001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6e180001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6d190001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6c1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6b1B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6a1C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x691D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4f1E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4e1F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4d200001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4c210001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4b220001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x4a230001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x49240001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x48250001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x47260001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x46270001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x45280001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x44290001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x432A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x422B0001); + + rssiAdjustVal = 12; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x30a99); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xdc000); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B000001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B010001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B020001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B030001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B040001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B050001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7B060001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x7A070001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x79080001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x78090001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x770A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x760B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x750C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x740D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x730E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x720F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x71100001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x70110001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6F120001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6E130001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6D140001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6C150001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6B160001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6A170001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x69180001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x68190001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x671A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x661B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x651C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x641D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x631E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x621F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x61200001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x60210001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x49220001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x48230001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x47240001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x46250001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x45260001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x44270001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x43280001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x42290001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x412A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x402B0001); + } + + // set rssiAdjustVal for wifi module. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + + + +VOID +halbtc8192d2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8192d2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8192d2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u4Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8192d2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u4Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8192d2ant_SetCoexTable(pBtCoexist, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8192d2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw mechanism + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} +VOID +halbtc8192d2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +halbtc8192d2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte btActive + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtDisabled=FALSE, bForceToRoam=FALSE; + u4Byte u4Tmp=0; + + // This function check if bt is disabled + if(btActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + + bForceToRoam = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_FORCE_TO_ROAM, &bForceToRoam); + + bPreBtDisabled = bBtDisabled; + } +} + +VOID +halbtc8192d2ant_MonitorBtState( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN stateChange=FALSE; + u4Byte BT_Polling, Ratio_Act, Ratio_STA; + u4Byte BT_Active, BT_State; + u4Byte regBTActive=0, regBTState=0, regBTPolling=0; + u4Byte btBusyThresh=0; + u4Byte fwVer=0; + static BOOLEAN bBtBusyTraffic=FALSE; + BOOLEAN bRejApAggPkt=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FirmwareVersion = 0x%x(%d)\n", fwVer, fwVer)); + + regBTActive = 0x444; + regBTState = 0x448; + regBTPolling = 0x44c; + + btBusyThresh = 40; + + BT_Active = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTActive); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_Active(0x%x)=0x%x\n", regBTActive, BT_Active)); + BT_Active = BT_Active & 0x00ffffff; + + BT_State = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTState); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_State(0x%x)=0x%x\n", regBTState, BT_State)); + BT_State = BT_State & 0x00ffffff; + + BT_Polling = pBtCoexist->fBtcRead4Byte(pBtCoexist, regBTPolling); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT_Polling(0x%x)=0x%x\n", regBTPolling, BT_Polling)); + + if(BT_Active==0xffffffff && BT_State==0xffffffff && BT_Polling==0xffffffff ) + return; + + // 2011/05/04 MH For Slim combo test meet a problem. Surprise remove and WLAN is running + // DHCP process. At the same time, the register read value might be zero. And cause BSOD 0x7f + // EXCEPTION_DIVIDED_BY_ZERO. In This case, the stack content may always be wrong due to + // HW divide trap. + if (BT_Polling==0) + return; + + halbtc8192d2ant_MonitorBtEnableDisable(pBtCoexist, BT_Active); + + Ratio_Act = BT_Active*1000/BT_Polling; + Ratio_STA = BT_State*1000/BT_Polling; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ratio_Act=%d\n", Ratio_Act)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ratio_STA=%d\n", Ratio_STA)); + + if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_STA < 60) // BT PAN idle + { + } + else + { + // Check if BT PAN (under BT 2.1) is uplink or downlink + if((Ratio_Act/Ratio_STA) < 2) + { // BT PAN Uplink + pCoexSta->bBtUplink = TRUE; + } + else + { // BT PAN downlink + pCoexSta->bBtUplink = FALSE; + } + } + } + + // Check BT is idle or not + if(!pBtCoexist->stackInfo.bBtLinkExist) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_Act<20) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + pCoexSta->bBtBusy = TRUE; + } + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + if(Ratio_STA < btBusyThresh) + { + pCoexSta->bBtBusy = FALSE; + } + else + { + pCoexSta->bBtBusy = TRUE; + } + + if( (Ratio_STA < btBusyThresh) || + (Ratio_Act<180 && Ratio_STA<130) ) + { + pCoexSta->bA2dpBusy = FALSE; + } + else + { + pCoexSta->bA2dpBusy = TRUE; + } + } + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &pCoexSta->bBtBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &pCoexSta->bBtBusy); + + if(bBtBusyTraffic != pCoexSta->bBtBusy) + { // BT idle or BT non-idle + bBtBusyTraffic = pCoexSta->bBtBusy; + stateChange = TRUE; + } + + if(stateChange) + { + if(!pCoexSta->bBtBusy) + { + halbtc8192d2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_CoexAllOff(pBtCoexist); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + } + else + { + halbtc8192d2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + } + } + + if(stateChange) + { + bRejApAggPkt = pCoexSta->bBtBusy; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejApAggPkt); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + } +} + +VOID +halbtc8192d2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw, wifiTrafficDir; + BOOLEAN bWifiBusy=FALSE; + + 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); + + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + if(pCoexSta->bA2dpBusy && bWifiBusy) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + } + else + { + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 25, 0); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 40, 0); + } + } + + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0xc, 0x18); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x18); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + } + else if(pCoexSta->bA2dpBusy) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, TRUE, 0x18, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } +} + +VOID +halbtc8192d2ant_ActionPan( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState, wifiRssiState1; + u4Byte wifiBw, wifiTrafficDir; + s4Byte wifiRssi; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(bBtHsOn) + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + else + { + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 3, 25, 50); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + } + else + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 25, 0); + } + + if(pCoexSta->bBtBusy && bWifiBusy) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + } + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + if(pCoexSta->bBtUplink) + { + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + } + else if( (wifiRssiState == BTC_RSSI_STATE_MEDIUM) || + (wifiRssiState == BTC_RSSI_STATE_STAY_MEDIUM) ) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE);//BT_FW_NAV_ON); + else + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x20); + + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + if(pCoexSta->bBtUplink) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE);//BT_FW_NAV_ON); + } + else + { + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + } + else + { + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + } + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else if(pCoexSta->bBtBusy && + !bWifiBusy && + (wifiRssi < 30)) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x0a, 0x20); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + } +} + + +VOID +halbtc8192d2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiTrafficDir; + BOOLEAN bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 45, 0); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 20, 0); + } + + if(pCoexSta->bBtBusy && bWifiBusy) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + // fw mechanism first + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, TRUE, 0x18, FALSE); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x15, 0x15); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x30, FALSE); + } + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } +} + + + +VOID +halbtc8192d2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } +} + +VOID +halbtc8192d2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1; + u4Byte wifiBw; + + if(pCoexSta->bBtBusy) + { + wifiRssiState1 = halbtc8192d2ant_WifiRssiState(pBtCoexist, 1, 2, 35, 0); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism first + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + // fw mechanism + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + } + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else + { + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + } + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } +} + + +VOID +halbtc8192d2ant_ActionHidPanBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(bBtHsOn) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8192d2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else + { + 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); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8192d2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8192d2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x10); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else if(!bWifiBusy) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + } + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); +} +VOID +halbtc8192d2ant_ActionHidPanBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + u4Byte wifiBw, wifiTrafficDir; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!bBtHsOn) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0); + if((pCoexSta->bBtBusy && bWifiBusy)) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x15, 0x20); + } + else + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x20); + } + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + } + else + { + if(BTC_INTF_USB == pBtCoexist->chipInterface) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir); + if(BTC_WIFI_TRAFFIC_TX == wifiTrafficDir) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + + halbtc8192d2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x000000f0, 0x40000010); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0xa0); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + else if(BTC_WIFI_TRAFFIC_RX == wifiTrafficDir) + { + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + } + } + else + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + } +} + +VOID +halbtc8192d2ant_ActionHidPan( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8192d2ant_ActionHidPanBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8192d2ant_ActionHidPanBc8(pBtCoexist); + } +} + +VOID +halbtc8192d2ant_ActionPanA2dpBc4( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x0); + if(bBtHsOn) + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + } + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + if(pCoexSta->bBtBusy && bWifiBusy) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x20, 0x10); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + } + else + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x0, FALSE); + } + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } +} +VOID +halbtc8192d2ant_ActionPanA2dpBc8( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE; + u1Byte wifiRssiState; + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!bBtHsOn) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + wifiRssiState = halbtc8192d2ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0); + if((pCoexSta->bBtBusy && bWifiBusy)) + { + // fw mechanism first + if(pCoexSta->bBtUplink) + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x15, 0x20); + } + else + { + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, TRUE, 0x10, 0x20); + } + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x20, FALSE); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } + else + { + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + } + else + { + if(pCoexSta->bBtBusy) + { + // fw mechanism + halbtc8192d2ant_Balance(pBtCoexist, NORMAL_EXEC, FALSE, 0, 0); + halbtc8192d2ant_DiminishWifi(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0, FALSE); + + // sw mechanism + halbtc8192d2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x20); + } + else + { + halbtc8192d2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0x30); + } + } +} + +VOID +halbtc8192d2ant_ActionPanA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + if(BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) + { + halbtc8192d2ant_ActionPanA2dpBc4(pBtCoexist); + } + else if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + halbtc8192d2ant_ActionPanA2dpBc8(pBtCoexist); + } +} + +BOOLEAN +halbtc8192d2ant_IsBtCoexistEnter( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte macPhyMode; + BOOLEAN bRet=TRUE; + BOOLEAN bWifiUnder5G=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_MAC_PHY_MODE, &macPhyMode); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + if(BTC_SMSP != macPhyMode) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Only support single mac single phy!!\n")); + bRet = FALSE; + } + + if(bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under 5G or A band\n")); + halbtc8192d2ant_CoexAllOff(pBtCoexist); + bRet = FALSE; + } + + return bRet; +} + +//============================================================ +// extern function start with EXhalbtc8192d2ant_ +//============================================================ +VOID +EXhalbtc8192d2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8192d2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + if( (BTC_CHIP_CSR_BC4 == pBtCoexist->boardInfo.btChipType) || + (BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) ) + { + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd) & BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, u1Tmp); + + halbtc8192d2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0xaaaa9aaa, 0xffbd0040, 0x40000010); + + // switch control, here we set pathA to control + // 0x878[13] = 1, 0:pathB, 1:pathA(default) + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x878, BIT13, 0x1); + + // antsel control, here we use phy0 and enable antsel. + // 0x87c[16:15] = b'11, enable antsel, antsel output pin + // 0x87c[30] = 0, 0: phy0, 1:phy 1 + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x87c, bMaskDWord, 0x1fff8); + + // antsel to Bt or Wifi, it depends Bt on/off. + // 0x860[9:8] = 'b10, b10:Bt On, WL2G off(default), b01:Bt off, WL2G on. + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x860, BIT9|BIT8, 0x2); + + // sw/hw control switch, here we set sw control + // 0x870[9:8] = 'b11 sw control, 'b00 hw control + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x870, BIT9|BIT8, 0x3); + } +} + +VOID +EXhalbtc8192d2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8192d2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8192d2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + // 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); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[BT Status]============"); + CL_PRINTF(cliBuf); + + if(pStackInfo->bProfileNotified) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + + // Sw mechanism + 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/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8192d2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + //halbtc8192d2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8192d2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + halbtc8192d2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + halbtc8192d2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8192d2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } +} + +VOID +EXhalbtc8192d2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8192d2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } +} + +VOID +EXhalbtc8192d2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8192d2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ +} + +VOID +EXhalbtc8192d2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + EXhalbtc8192d2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8192d2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Periodical!!\n")); + + // NOTE: + // sw mechanism must be done after fw mechanism + // + if(!halbtc8192d2ant_IsBtCoexistEnter(pBtCoexist)) + return; + + if(BTC_CHIP_CSR_BC8 == pBtCoexist->boardInfo.btChipType) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_GET_BT_RSSI, NULL); + + halbtc8192d2ant_MonitorBtState(pBtCoexist); + algorithm = halbtc8192d2ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + switch(pCoexDm->curAlgorithm) + { + case BT_8192D_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO\n")); + halbtc8192d2ant_ActionSco(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID\n")); + halbtc8192d2ant_ActionHid(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP\n")); + halbtc8192d2ant_ActionA2dp(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_PAN: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN\n")); + halbtc8192d2ant_ActionPan(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP\n")); + halbtc8192d2ant_ActionHidA2dp(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_HID_PAN: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+HID\n")); + halbtc8192d2ant_ActionHidPan(pBtCoexist); + break; + case BT_8192D_2ANT_COEX_ALGO_PAN_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP\n")); + halbtc8192d2ant_ActionPanA2dp(pBtCoexist); + break; + default: + break; + } + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.h new file mode 100644 index 00000000..85fd6742 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192d2Ant.h @@ -0,0 +1,170 @@ +//=========================================== +// The following is for 8192D 2Ant BT Co-exist definition +//=========================================== +#define BTC_RSSI_COEX_THRESH_TOL_8192D_2ANT 6 + +typedef enum _BT_INFO_SRC_8192D_2ANT{ + BT_INFO_SRC_8192D_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8192D_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8192D_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8192D_2ANT_MAX +}BT_INFO_SRC_8192D_2ANT,*PBT_INFO_SRC_8192D_2ANT; + +typedef enum _BT_8192D_2ANT_BT_STATUS{ + BT_8192D_2ANT_BT_STATUS_IDLE = 0x0, + BT_8192D_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8192D_2ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8192D_2ANT_BT_STATUS_MAX +}BT_8192D_2ANT_BT_STATUS,*PBT_8192D_2ANT_BT_STATUS; + +typedef enum _BT_8192D_2ANT_COEX_ALGO{ + BT_8192D_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8192D_2ANT_COEX_ALGO_SCO = 0x1, + BT_8192D_2ANT_COEX_ALGO_HID = 0x2, + BT_8192D_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8192D_2ANT_COEX_ALGO_PAN = 0x4, + BT_8192D_2ANT_COEX_ALGO_HID_A2DP = 0x5, + BT_8192D_2ANT_COEX_ALGO_HID_PAN = 0x6, + BT_8192D_2ANT_COEX_ALGO_PAN_A2DP = 0x7, + BT_8192D_2ANT_COEX_ALGO_MAX +}BT_8192D_2ANT_COEX_ALGO,*PBT_8192D_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8192D_2ANT{ + // fw mechanism + BOOLEAN bPreBalanceOn; + BOOLEAN bCurBalanceOn; + + // diminishWifi + BOOLEAN bPreDacOn; + BOOLEAN bCurDacOn; + BOOLEAN bPreInterruptOn; + BOOLEAN bCurInterruptOn; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bPreNavOn; + BOOLEAN bCurNavOn; + + + + + + //BOOLEAN bPreDecBtPwr; + //BOOLEAN bCurDecBtPwr; + + //u1Byte preFwDacSwingLvl; + //u1Byte curFwDacSwingLvl; + //BOOLEAN bCurIgnoreWlanAct; + //BOOLEAN bPreIgnoreWlanAct; + //u1Byte prePsTdma; + //u1Byte curPsTdma; + //u1Byte psTdmaPara[5]; + //u1Byte psTdmaDuAdjType; + //BOOLEAN bResetTdmaAdjust; + //BOOLEAN bPrePsTdmaOn; + //BOOLEAN bCurPsTdmaOn; + //BOOLEAN bPreBtAutoReport; + //BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + //u4Byte preVal0x6c0; + //u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u4Byte preVal0x6cc; + u4Byte curVal0x6cc; + //BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + //u1Byte btStatus; + //u1Byte wifiChnlInfo[3]; +} COEX_DM_8192D_2ANT, *PCOEX_DM_8192D_2ANT; + +typedef struct _COEX_STA_8192D_2ANT{ + u1Byte preWifiRssiState[4]; + BOOLEAN bBtBusy; + BOOLEAN bBtUplink; + BOOLEAN bBtDownLink; + BOOLEAN bA2dpBusy; +}COEX_STA_8192D_2ANT, *PCOEX_STA_8192D_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8192d2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192d2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8192d2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192d2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192d2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192d2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192d2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8192d2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.c new file mode 100644 index 00000000..86e006db --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.c @@ -0,0 +1,3738 @@ +//============================================================ +// Description: +// +// This file is for RTL8192E Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8192e1Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8192E_1ANT GLCoexDm8192e1Ant; +static PCOEX_DM_8192E_1ANT pCoexDm=&GLCoexDm8192e1Ant; +static COEX_STA_8192E_1ANT GLCoexSta8192e1Ant; +static PCOEX_STA_8192E_1ANT pCoexSta=&GLCoexSta8192e1Ant; + +const char *const GLBtInfoSrc8192e1Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8192e1Ant=20140527; +u4Byte GLCoexVer8192e1Ant=0x4f; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8192e1ant_ +//============================================================ +u1Byte +halbtc8192e1ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8192e1ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8192e1ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8192e1ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8192e1ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8192e1ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8192e1ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8192e1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8192e1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8192e1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8192e1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8192e1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8192e1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8192e1ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8192e1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +VOID +halbtc8192e1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp, u4Tmp1; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp, u1Tmp1; + s4Byte wifiRssi; + static u1Byte NumOfBtCounterChk = 0; + + //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; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if( (pCoexSta->lowPriorityTx >= 1050) && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->popEventCnt++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + regHPRx, regHPTx, regLPRx, regLPTx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); + + if ((regHPTx == 0) && (regHPRx ==0) && (regLPTx == 0) && (regLPRx == 0)) + { + NumOfBtCounterChk++; + if (NumOfBtCounterChk >= 3) + { + halbtc8192e1ant_QueryBtInfo(pBtCoexist); + NumOfBtCounterChk = 0; + } + } +} + + +VOID +halbtc8192e1ant_MonitorWiFiCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u2Byte u2Tmp[3]; + s4Byte wifiRssi=0; + BOOLEAN bWifiBusy = FALSE, bWifiUnderBMode = FALSE; + static u1Byte nCCKLockCounter = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + 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); + + if ( (bWifiBusy) && (wifiRssi >= 30) && (!bWifiUnderBMode)) + { + if ( (pCoexDm->btStatus == BT_8192E_1ANT_BT_STATUS_ACL_BUSY) || + (pCoexDm->btStatus == BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY) || + (pCoexDm->btStatus == BT_8192E_1ANT_BT_STATUS_SCO_BUSY) ) + { + if (pCoexSta->nCRCOK_CCK >(pCoexSta->nCRCOK_11g + pCoexSta->nCRCOK_11n + + pCoexSta->nCRCOK_11nAgg) ) + { + if (nCCKLockCounter < 5) + nCCKLockCounter++; + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + if (!pCoexSta->bPreCCKLock) + { + + if (nCCKLockCounter >= 5) + pCoexSta->bCCKLock = TRUE; + else + pCoexSta->bCCKLock = FALSE; + } + else + { + if (nCCKLockCounter == 0) + pCoexSta->bCCKLock = FALSE; + else + pCoexSta->bCCKLock = TRUE; + } + + pCoexSta->bPreCCKLock = pCoexSta->bCCKLock; + + +} + +BOOLEAN +halbtc8192e1ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; + BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + } + + return FALSE; +} + +VOID +halbtc8192e1ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8192e1ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8192E_1ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO only\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID only\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP only\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(HS) only\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(EDR) only\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP ==> SCO\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(EDR)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(EDR)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(EDR)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8192e1ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8192e1ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8192e1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8192e1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!") )); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8192e1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8192e1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8192e1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8192e1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8192e1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8192e1ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** CoexTable(%d) **********\n", type)); + + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 4: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 5: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaa5a5a5a, 0xffffff, 0x3); + break; + case 6: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 7: + halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8192e1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8192e1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8192e1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8192e1ant_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 +halbtc8192e1ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8192e1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8192e1ant_SwMechanism( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRA + ) +{ + halbtc8192e1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8192e1ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + u4Byte u4Tmp=0; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x944, 0x24); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x930, 0x700700); + if(pBtCoexist->chipInterface == BTC_INTF_USB) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30430004); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30030004); + + // 0x4c[27][24]='00', Set Antenna to BB + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &= ~BIT24; + u4Tmp &= ~BIT27; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + else if(bWifiOff) + { + if(pBtCoexist->chipInterface == BTC_INTF_USB) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30430004); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30030004); + + // 0x4c[27][24]='11', Set Antenna to BT, 0x64[8:7]=0, 0x64[2]=1 + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp |= BIT24; + u4Tmp |= BIT27; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x4); + break; + case BTC_ANT_PATH_BT: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x20); + break; + default: + case BTC_ANT_PATH_PTA: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x4); + break; + } +} + +VOID +halbtc8192e1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + + +VOID +halbtc8192e1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bTurnOnByCnt=FALSE, bWifiBusy=FALSE, bWiFiNoisy=FALSE; + u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0; + u1Byte psTdmaByte4Val = 0x50, psTdmaByte0Val = 0x51, psTdmaByte3Val = 0x10; + s1Byte nWiFiDurationAdjust = 0x0; + + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if (pCoexDm->bCurPsTdmaOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(off, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum <= 5) + nWiFiDurationAdjust = 5; + else if (pCoexSta->nScanAPNum >= 40) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nScanAPNum >= 20) + nWiFiDurationAdjust = -10; + + 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) ) + psTdmaByte4Val = psTdmaByte4Val & 0xbf; //no dynamic slot for multi-profile + + if (pBtLinkInfo->bSlaveRole == TRUE) + psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) + + if(bTurnOn) + { + switch(type) + { + default: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, psTdmaByte4Val); + break; + case 1: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 2: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 3: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, psTdmaByte4Val); + break; + case 4: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0); + break; + case 5: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x15, 0x3, 0x11, 0x11); + break; + case 6: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x20, 0x3, 0x11, 0x11); + break; + case 7: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0); + break; + case 8: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 9: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 10: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 12: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50); + break; + case 13: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x12, 0x12, 0x0, psTdmaByte4Val); + break; + case 14: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x21, 0x3, 0x10, psTdmaByte4Val); + break; + case 15: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0); + break; + case 16: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0); + break; + case 18: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 20: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x3f, 0x03, 0x11, 0x10); + break; + case 21: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11); + break; + case 22: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x10); + break; + case 23: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18); + break; + case 24: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18); + break; + case 25: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 26: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 27: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98); + break; + case 28: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0); + break; + case 29: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10); + break; + case 31: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58); + break; + case 32: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x3, 0x11, 0x11); + break; + case 33: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xa3, 0x25, 0x3, 0x30, 0x90); + break; + case 34: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50); + break; + case 40: // SoftAP only with no sta associated,BT disable ,TDMA mode for power saving + /* here softap mode screen off will cost 70-80mA for phone */ + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24); + break; + } + } + else + { + + // disable PS tdma + switch(type) + { + case 8: //PTA Control + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FALSE, FALSE); + break; + case 0: + default: //Software control, Antenna at BT side + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); + break; + case 9: //Software control, Antenna at WiFi side + halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FALSE, FALSE); + break; + } + } + rssiAdjustVal =0; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67))); + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8192e1ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // sw all off + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + // hw all off + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +BOOLEAN +halbtc8192e1ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n")); + + //halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + //halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n")); + + //halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + + //halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); + + //halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else + { + if (bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + } + + bCommon = FALSE; + } + + return bCommon; +} + + +VOID +halbtc8192e1ant_TdmaDurationAdjustForAcl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + static BOOLEAN bPreWifiBusy=FALSE; + BOOLEAN bWifiBusy = FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjustForAcl()\n")); + + if(BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifiStatus) + bWifiBusy = TRUE; + else + bWifiBusy = FALSE; + + if( (BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 3 && + pCoexDm->curPsTdma != 9 ) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { + if( (BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if(result == 1) + { + if( (BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + else //no change + { + /* Bryant Modify + if(bWifiBusy != bPreWifiBusy) //if busy / idle change + { + bPreWifiBusy = bWifiBusy; + halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, pCoexDm->curPsTdma); + } + */ + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 9 && + pCoexDm->curPsTdma != 11 ) + { + // recover to previous adjust type + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8192e1ant_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 + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8192e1ant_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: + halbtc8192e1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8192e1ant_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: + halbtc8192e1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + +VOID +halbtc8192e1ant_ActionWifiOnly( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); +} + +VOID +halbtc8192e1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + halbtc8192e1ant_ActionWifiOnly(pBtCoexist); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +//============================================= +// +// Software Coex Mechanism start +// +//============================================= + +// SCO only or SCO+PAN(HS) + +/* +VOID +halbtc8192e1ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); +} + + +VOID +halbtc8192e1ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8192e1ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8192e1ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8192e1ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(HS) only +VOID +halbtc8192e1ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(EDR)+A2DP +VOID +halbtc8192e1ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8192e1ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8192e1ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8192e1ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); +} + +*/ + +//============================================= +// +// Non-Software Coex Mechanism start +// +//============================================= +VOID +halbtc8192e1ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8192e1ant_ActionHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8192e1ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bApEnable=FALSE, bWifiBusy=FALSE, bBtBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if((!bWifiConnected) && (!pCoexSta->bWiFiIsHighPriTask)) + { + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + // SCO/HID/A2DP busy + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if ((pBtLinkInfo->bPanExist) || (bWifiBusy)) + { + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } +} + +VOID +halbtc8192e1ant_ActionBtScoHidOnlyBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // tdma and coex table + + if(pBtLinkInfo->bScoExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else //HID + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } +} + +VOID +halbtc8192e1ant_ActionWifiConnectedBtAclBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + u1Byte btRssiState; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + btRssiState = halbtc8192e1ant_BtRssiState(2, 28, 0); + + if ( (pCoexSta->lowPriorityRx >= 1000) && (pCoexSta->lowPriorityRx != 65535) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + if(pBtLinkInfo->bHidOnly) //HID + { + halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus); + pCoexDm->bAutoTdmaAdjust = FALSE; + return; + } + else if(pBtLinkInfo->bA2dpOnly) //A2DP + { + if(BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + halbtc8192e1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus); +#if 0 + if (pCoexSta->bCCKLock) + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else +#endif + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = TRUE; + } + } + else if ( ((pBtLinkInfo->bA2dpExist) && (pBtLinkInfo->bPanExist)) || + (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist&&pBtLinkInfo->bPanExist) ) //A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if(pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) //HID+A2DP + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->bAutoTdmaAdjust = FALSE; + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else if( (pBtLinkInfo->bPanOnly) || (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) ) //PAN(OPP,FTP), HID+PAN(OPP,FTP) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + //BT no-profile busy (0x9) + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } +} + +VOID +halbtc8192e1ant_ActionWifiNotConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8192e1ant_ActionWifiNotConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8192e1ant_ActionWifiNotConnectedAssoAuth( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bPanExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8192e1ant_ActionWifiConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8192e1ant_ActionWifiConnectedSpecialPacket( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if(pBtLinkInfo->bPanExist) + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8192e1ant_ActionWifiConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiBusy=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + BOOLEAN bUnder4way=FALSE, bApEnable=FALSE; + u4Byte wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect()===>\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + if(bUnder4way) + { + halbtc8192e1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n")); + return; + } + + 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) + { + if(bScan) + halbtc8192e1ant_ActionWifiConnectedScan(pBtCoexist); + else + halbtc8192e1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + // power save state + if(!bApEnable && BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->btLinkInfo.bHidOnly) + { + if(pBtCoexist->btLinkInfo.bA2dpOnly) //A2DP + { + if(!bWifiBusy) + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else //busy + { + if (pCoexSta->nScanAPNum >= BT_8192E_1ANT_WIFI_NOISY_THRESH) //no force LPS, no PS-TDMA, use pure TDMA + { + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + } + } + else if ((pCoexSta->bPanExist == FALSE) && (pCoexSta->bA2dpExist == FALSE) && (pCoexSta->bHidExist == FALSE)) + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + else + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(!bWifiBusy) + { + if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else + { + if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else + { + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } +} + +VOID +halbtc8192e1ant_RunSwCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm=0; + + algorithm = halbtc8192e1ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + + if(halbtc8192e1ant_IsCommonAction(pBtCoexist)) + { + + } + else + { + switch(pCoexDm->curAlgorithm) + { + case BT_8192E_1ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = SCO.\n")); + //halbtc8192e1ant_ActionSco(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID.\n")); + //halbtc8192e1ant_ActionHid(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP.\n")); + //halbtc8192e1ant_ActionA2dp(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n")); + //halbtc8192e1ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR).\n")); + //halbtc8192e1ant_ActionPanEdr(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HS mode.\n")); + //halbtc8192e1ant_ActionPanHs(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN+A2DP.\n")); + //halbtc8192e1ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n")); + //halbtc8192e1ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n")); + //halbtc8192e1ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8192E_1ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP.\n")); + //halbtc8192e1ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = coexist All Off!!\n")); + //halbtc8192e1ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8192e1ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + BOOLEAN bIncreaseScanDevNum=FALSE; + BOOLEAN bBtCtrlAggBufSize=FALSE; + BOOLEAN bMiracastPlusBt=FALSE; + u1Byte aggBufSize=5; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if( (BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bIncreaseScanDevNum = TRUE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, &bIncreaseScanDevNum); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], Multi-Port numOfWifiLink = %d, wifiLinkStatus = 0x%x\n", numOfWifiLink,wifiLinkStatus) ); + + if(pBtLinkInfo->bBtLinkExist) + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + bMiracastPlusBt = TRUE; + } + else + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + bMiracastPlusBt = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + + if ( (pBtLinkInfo->bA2dpExist) && (pCoexSta->bC2hBtInquiryPage) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8192e1ant_ActionBtInquiry(pBtCoexist); + } + else + halbtc8192e1ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + if ( (pBtLinkInfo->bBtLinkExist) && (bWifiConnected) ) + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + + if(pBtLinkInfo->bScoExist) + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x5); + else + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + halbtc8192e1ant_SwMechanism(pBtCoexist, TRUE); + halbtc8192e1ant_RunSwCoexistMechanism(pBtCoexist); //just print debug message + } + else + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + halbtc8192e1ant_RunSwCoexistMechanism(pBtCoexist); ////just print debug message + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8192e1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8192e1ant_ActionHs(pBtCoexist); + return; + } + + + if(!bWifiConnected) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is non connected-idle !!!\n")); + + 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) + { + if (bScan) + halbtc8192e1ant_ActionWifiNotConnectedScan(pBtCoexist); + else + halbtc8192e1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else + halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist); + } + else // wifi LPS/Busy + { + halbtc8192e1ant_ActionWifiConnected(pBtCoexist); + } +} + +VOID +halbtc8192e1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + + // sw all off + halbtc8192e1ant_SwMechanism(pBtCoexist, FALSE); + + //halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + pCoexSta->popEventCnt = 0; +} + +VOID +halbtc8192e1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + // antenna sw ctrl to bt + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, TRUE, FALSE); + + halbtc8192e1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + // antenna switch control parameter + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x858, 0x55555555); + + // coex parameters + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + // enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // enable PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); + // enable mailbox interface + u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x40); + u2Tmp |= BIT9; + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x40, u2Tmp); + + // enable PTA I2C mailbox + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x101); + u1Tmp |= BIT4; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x101, u1Tmp); + + // enable bt clock when wifi is disabled. + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x93); + u1Tmp |= BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x93, u1Tmp); + // enable bt clock when suspend. + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7); + u1Tmp |= BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x7, u1Tmp); +} + + +/* +VOID +halbtc8192e1ant_WifiOffHwCfg( + IN PBTC_COEXIST pBtCoexist + ) +{ + // set wlan_act to low + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); +} +*/ + +//============================================================ +// work around function start with wa_halbtc8192e1ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8192e1ant_ +//============================================================ +VOID +EXhalbtc8192e1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +#if 0 + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u1Byte u1Tmp=0x0; + u2Byte u2Tmp=0x0; + + pBtCoexist->bStopCoexDm = TRUE; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20); + + // enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. + 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); + + // + // S0 or S1 setting and Local register setting(By the setting fw can get ant number, S0/S1, ... info) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + 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) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } +#endif +} + +VOID +EXhalbtc8192e1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8192e1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8192e1ant_InitHwConfig(pBtCoexist, bWifiOnly); + pBtCoexist->bStopCoexDm = FALSE; +} + +VOID +EXhalbtc8192e1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + pBtCoexist->bStopCoexDm = FALSE; + + halbtc8192e1ant_InitCoexDm(pBtCoexist); + + halbtc8192e1ant_QueryBtInfo(pBtCoexist); +} + +VOID +EXhalbtc8192e1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + if(pBtCoexist->bStopCoexDm) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8192e1Ant, GLCoexVer8192e1Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((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")))), + pCoexSta->btRssi, 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); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8192e1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + if(!pBtCoexist->bManualControl) + { + // Sw mechanism + 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 = %s/ %s/ %d ", "DelBA/ BtCtrlAgg/ AggSize", \ + (pBtCoexist->btInfo.bRejectAggPkt? "Yes":"No"), (pBtCoexist->btInfo.bBtCtrlAggBufSize? "Yes":"No"), + pBtCoexist->btInfo.aggBufSize); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \ + pCoexDm->errorCondition); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc04); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xd04); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x90c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0xc04/ 0xd04/ 0x90c", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x92c); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x930); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x92c/ 0x930", \ + (u1Tmp[0]), u4Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4f); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x40/ 0x4f", \ + u1Tmp[0], u1Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(hp rx[31:16]/tx[15:0])", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 1) + halbtc8192e1ant_MonitorBtCtr(pBtCoexist); +#endif + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + +VOID +EXhalbtc8192e1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp=0; + + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + + halbtc8192e1ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8192e1ant_InitCoexDm(pBtCoexist); + halbtc8192e1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8192e1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8192e1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + u1Byte u1Tmpa, u1Tmpb; + u4Byte u4Tmp; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm ) + return; + + if(BTC_SCAN_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + + halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } + + if(pBtCoexist->btInfo.bBtDisabled) + return; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + halbtc8192e1ant_QueryBtInfo(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8192e1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8192e1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8192e1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_SCAN_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8192e1ant_ActionWifiNotConnectedScan(pBtCoexist); + } + else // wifi is connected + { + halbtc8192e1ant_ActionWifiConnectedScan(pBtCoexist); + } + } + else if(BTC_SCAN_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8192e1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8192e1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_ASSOCIATE_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + pCoexDm->nArpCnt = 0; + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + //pCoexDm->nArpCnt = 0; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8192e1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8192e1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8192e1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_ASSOCIATE_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + halbtc8192e1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8192e1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8192e1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + BOOLEAN bWifiUnderBMode = FALSE; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + //Set CCK Tx/Rx high Pri except 11b mode + if (bWifiUnderBMode) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x00); //CCK Rx + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x10); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); //CCK Rx + } + + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + pCoexDm->nArpCnt = 0; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x0); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x0); //CCK Rx + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + //H2C_Parameter[0] = 0x1; + H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8192e1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + if(BTC_PACKET_ARP == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet ARP notify\n")); + + pCoexDm->nArpCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ARP Packet Count = %d\n", pCoexDm->nArpCnt)); + + if(pCoexDm->nArpCnt >= 10) // if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet DHCP or EAPOL notify\n")); + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet [Type = %d] notify\n", type)); + } + + pCoexSta->specialPktPeriodCnt = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8192e1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8192e1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8192e1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8192e1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8192e1ant_ActionHs(pBtCoexist); + return; + } + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + ( (BTC_PACKET_ARP == type ) && (pCoexSta->bWiFiIsHighPriTask) ) ) + { + halbtc8192e1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + } +} + +VOID +EXhalbtc8192e1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bBtBusy=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8192E_1ANT_MAX) + rspSource = BT_INFO_SRC_8192E_1ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8192E_1ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btRetryCnt >= 1) + pCoexSta->popEventCnt++; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtPage = TRUE; + else + pCoexSta->bC2hBtPage = FALSE; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2-90; + //pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if(!pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if(pCoexSta->btInfoExt & BIT1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if(pCoexSta->btInfoExt & BIT3) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8192e1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8192E_1ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8192E_1ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8192E_1ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8192E_1ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8192E_1ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8192E_1ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + } + + halbtc8192e1ant_UpdateBtLinkInfo(pBtCoexist); + + btInfo = btInfo & 0x1f; //mask profile bit for connect-ilde identification ( for CSR case: A2DP idle --> 0x41) + + if(!(btInfo&BT_INFO_8192E_1ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8192E_1ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8192E_1ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8192E_1ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8192E_1ANT_B_ACL_BUSY) + { + if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus) + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + bBtBusy = TRUE; + else + bBtBusy = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + halbtc8192e1ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8192e1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa,u1Tmpb, u1Tmpc; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF Status notify\n")); + + if(BTC_RF_ON == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned ON!!\n")); + pBtCoexist->bStopCoexDm = FALSE; + } + else if(BTC_RF_OFF == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned OFF!!\n")); + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + + halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + pBtCoexist->bStopCoexDm = TRUE; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u1Tmpc = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb, u1Tmpc)); + + } +} + +VOID +EXhalbtc8192e1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + + halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + pBtCoexist->bStopCoexDm = TRUE; +} + +VOID +EXhalbtc8192e1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8192e1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + + pBtCoexist->bStopCoexDm = TRUE; + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + pBtCoexist->bStopCoexDm = FALSE; + halbtc8192e1ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8192e1ant_InitCoexDm(pBtCoexist); + halbtc8192e1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8192e1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], *****************Coex DM Reset*****************\n")); + + halbtc8192e1ant_InitHwConfig(pBtCoexist, FALSE); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x2, 0xfffff, 0x0); + halbtc8192e1ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8192e1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8192e1Ant, GLCoexVer8192e1Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 0) + halbtc8192e1ant_QueryBtInfo(pBtCoexist); + halbtc8192e1ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8192e1ant_MonitorBtCtr(pBtCoexist); + halbtc8192e1ant_MonitorWiFiCtr(pBtCoexist); + + if( halbtc8192e1ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust ) + { + + halbtc8192e1ant_RunCoexistMechanism(pBtCoexist); + } + + pCoexSta->specialPktPeriodCnt++; +#endif +} + + +VOID +EXhalbtc8192e1ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ) +{ + switch(opCode) + { + case BTC_DBG_SET_COEX_NORMAL: + pBtCoexist->bManualControl = FALSE; + halbtc8192e1ant_InitCoexDm(pBtCoexist); + break; + case BTC_DBG_SET_COEX_WIFI_ONLY: + pBtCoexist->bManualControl = TRUE; + halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + break; + case BTC_DBG_SET_COEX_BT_ONLY: + // todo + break; + default: + break; + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.h new file mode 100644 index 00000000..02914bca --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e1Ant.h @@ -0,0 +1,254 @@ +//=========================================== +// The following is for 8192E 1ANT BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8192E_1ANT 1 + +#define BT_INFO_8192E_1ANT_B_FTP BIT7 +#define BT_INFO_8192E_1ANT_B_A2DP BIT6 +#define BT_INFO_8192E_1ANT_B_HID BIT5 +#define BT_INFO_8192E_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8192E_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8192E_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8192E_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8192E_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT 2 + +#define BT_8192E_1ANT_WIFI_NOISY_THRESH 30 //max: 255 + +typedef enum _BT_INFO_SRC_8192E_1ANT{ + BT_INFO_SRC_8192E_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8192E_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8192E_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8192E_1ANT_MAX +}BT_INFO_SRC_8192E_1ANT,*PBT_INFO_SRC_8192E_1ANT; + +typedef enum _BT_8192E_1ANT_BT_STATUS{ + BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8192E_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8192E_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8192E_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8192E_1ANT_BT_STATUS_MAX +}BT_8192E_1ANT_BT_STATUS,*PBT_8192E_1ANT_BT_STATUS; + +typedef enum _BT_8192E_1ANT_WIFI_STATUS{ + BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8192E_1ANT_WIFI_STATUS_MAX +}BT_8192E_1ANT_WIFI_STATUS,*PBT_8192E_1ANT_WIFI_STATUS; + +typedef enum _BT_8192E_1ANT_COEX_ALGO{ + BT_8192E_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8192E_1ANT_COEX_ALGO_SCO = 0x1, + BT_8192E_1ANT_COEX_ALGO_HID = 0x2, + BT_8192E_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8192E_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8192E_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8192E_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8192E_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8192E_1ANT_COEX_ALGO_MAX = 0xb, +}BT_8192E_1ANT_COEX_ALGO,*PBT_8192E_1ANT_COEX_ALGO; + +typedef struct _COEX_DM_8192E_1ANT{ + // fw mechanism + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; + u4Byte nArpCnt; + + u1Byte errorCondition; +} COEX_DM_8192E_1ANT, *PCOEX_DM_8192E_1ANT; + +typedef struct _COEX_STA_8192E_1ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte specialPktPeriodCnt; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + s1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8192E_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8192E_1ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtPage; //Add for win8.1 page out issue + BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue + u1Byte btRetryCnt; + u1Byte btInfoExt; + u4Byte popEventCnt; + u1Byte nScanAPNum; + + u4Byte nCRCOK_CCK; + u4Byte nCRCOK_11g; + u4Byte nCRCOK_11n; + u4Byte nCRCOK_11nAgg; + + u4Byte nCRCErr_CCK; + u4Byte nCRCErr_11g; + u4Byte nCRCErr_11n; + u4Byte nCRCErr_11nAgg; + + BOOLEAN bCCKLock; + BOOLEAN bPreCCKLock; + u1Byte nCoexTableType; + + BOOLEAN bForceLpsOn; +}COEX_STA_8192E_1ANT, *PCOEX_STA_8192E_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8192e1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8192e1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8192e1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8192e1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e1ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.c new file mode 100644 index 00000000..648e6699 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.c @@ -0,0 +1,5027 @@ +//============================================================ +// Description: +// +// This file is for RTL8192E Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8192E_2ANT GLCoexDm8192e2Ant; +static PCOEX_DM_8192E_2ANT pCoexDm=&GLCoexDm8192e2Ant; +static COEX_STA_8192E_2ANT GLCoexSta8192e2Ant; +static PCOEX_STA_8192E_2ANT pCoexSta=&GLCoexSta8192e2Ant; + +const char *const GLBtInfoSrc8192e2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8192e2Ant=20150615; +u4Byte GLCoexVer8192e2Ant=0x41; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8192e2ant_ +//============================================================ +u1Byte +halbtc8192e2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8192e2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8192e2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + } + } +} + +u4Byte +halbtc8192e2ant_DecideRaMask( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte ssType, + IN u4Byte raMaskType + ) +{ + u4Byte disRaMask=0x0; + + switch(raMaskType) + { + case 0: // normal mode + if(ssType == 2) + disRaMask = 0x0; // enable 2ss + else + disRaMask = 0xfff00000; // disable 2ss + break; + case 1: // disable cck 1/2 + if(ssType == 2) + disRaMask = 0x00000003; // enable 2ss + else + disRaMask = 0xfff00003; // disable 2ss + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + if(ssType == 2) + disRaMask = 0x0001f1f7; // enable 2ss + else + disRaMask = 0xfff1f1f7; // disable 2ss + break; + default: + break; + } + + return disRaMask; +} + +VOID +halbtc8192e2ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8192e2ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8192e2ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8192e2ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8192e2ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + u4Byte disRaMask=0x0; + + pCoexDm->curRaMaskType = raMaskType; + disRaMask = halbtc8192e2ant_DecideRaMask(pBtCoexist, pCoexDm->curSsType, raMaskType); + halbtc8192e2ant_UpdateRaMask(pBtCoexist, bForceExec, disRaMask); + + halbtc8192e2ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8192e2ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8192e2ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8192e2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8192e2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8192e2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +BOOLEAN +halbtc8192e2ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + + + wifiRssiState = halbtc8192e2ant_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; +} + +VOID +halbtc8192e2ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8192e2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8192E_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO_PAN; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO_PAN; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8192e2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8192e2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte decBtPwrLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = decBtPwrLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power level = %d, FW write 0x62=0x%x\n", + decBtPwrLvl, H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, H2C_Parameter); +} + +VOID +halbtc8192e2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte decBtPwrLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power level = %d\n", + (bForceExec? "force to":""), decBtPwrLvl)); + pCoexDm->curBtDecPwrLvl = decBtPwrLvl; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], preBtDecPwrLvl=%d, curBtDecPwrLvl=%d\n", + pCoexDm->preBtDecPwrLvl, pCoexDm->curBtDecPwrLvl)); +#if 0 // work around, avoid h2c command fail. + if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl) + return; +#endif + } + halbtc8192e2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl); + + pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl; +} + +VOID +halbtc8192e2ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8192e2ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreBtAutoReport=%d, bCurBtAutoReport=%d\n", + pCoexDm->bPreBtAutoReport, pCoexDm->bCurBtAutoReport)); + + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8192e2ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8192e2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n", + pCoexDm->preFwDacSwingLvl, pCoexDm->curFwDacSwingLvl)); + + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8192e2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8192e2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8192e2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreRfRxLpfShrink=%d, bCurRfRxLpfShrink=%d\n", + pCoexDm->bPreRfRxLpfShrink, pCoexDm->bCurRfRxLpfShrink)); + + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8192e2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8192e2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!")) ); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8192e2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + //return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n", + pCoexDm->bPreLowPenaltyRa, pCoexDm->bCurLowPenaltyRa)); + + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8192e2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8192e2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x883, 0x3e, val); +} + +VOID +halbtc8192e2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8192e2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8192e2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8192e2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n", + pCoexDm->bPreDacSwingOn, pCoexDm->preDacSwingLvl, + pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl)); + + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8192e2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8192e2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x1); + } +} + +VOID +halbtc8192e2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n", + pCoexDm->bPreAdcBackOff, pCoexDm->bCurAdcBackOff)); + + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8192e2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8192e2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + //=================BB AGC Gain Table + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x0a1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x091B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x081C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x071D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x061E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x051F0001); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xaa1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa91B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa81C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa71D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa61E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa51F0001); + } + +#if 0 + //=================RF Gain + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + if(bAgcTableEn) + { + rssiAdjustVal = 8; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +#endif + +} + +VOID +halbtc8192e2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n", + pCoexDm->bPreAgcTableEn, pCoexDm->bCurAgcTableEn)); + + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8192e2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8192e2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8192e2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], preVal0x6c0=0x%x, preVal0x6c4=0x%x, preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n", + pCoexDm->preVal0x6c0, pCoexDm->preVal0x6c4, pCoexDm->preVal0x6c8, pCoexDm->preVal0x6cc)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x, curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n", + pCoexDm->curVal0x6c0, pCoexDm->curVal0x6c4, pCoexDm->curVal0x6c8, pCoexDm->curVal0x6cc)); + + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8192e2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8192e2ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 1: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5ffb5ffb, 0xffffff, 0x3); + break; + case 3: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x5fdf5fdf, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 4: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0xdfffdfff, 0x5ffb5ffb, 0xffffff, 0x3); + break; + case 5: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x5ddd5ddd, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 6: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + if(pCoexSta->nScanAPNum <= NOISY_AP_NUM_THRESH) + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xfafafafa, 0xffffff, 0x3); + else + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 8: + halbtc8192e2ant_CoexTable(pBtCoexist, bForceExec, 0x5f5f5f5f, 0x5a5a5a5a, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8192e2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + + +VOID +halbtc8192e2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n", + pCoexDm->bPreIgnoreWlanAct, pCoexDm->bCurIgnoreWlanAct)); + + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8192e2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + + +VOID +halbtc8192e2ant_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 +halbtc8192e2ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], preLps/curLps=0x%x/0x%x, preRpwm/curRpwm=0x%x/0x%x!!\n", + pCoexDm->preLps, pCoexDm->curLps, pCoexDm->preRpwm, pCoexDm->curRpwm)); + + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], LPS-RPWM_Last=0x%x , LPS-RPWM_Now=0x%x!!\n", + pCoexDm->preRpwm, pCoexDm->curRpwm)); + + return; + } + } + halbtc8192e2ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + + + +VOID +halbtc8192e2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + + +VOID +halbtc8192e2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + /* + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + */ + + halbtc8192e2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + //halbtc8192e2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8192e2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + halbtc8192e2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + //halbtc8192e2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + halbtc8192e2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8192e2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + u4Byte u4Tmp=0; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x944, 0x24); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x930, 0x700700); + if(pBtCoexist->chipInterface == BTC_INTF_USB) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30430004); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30030004); + + // 0x4c[27][24]='00', Set Antenna to BB + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &= ~BIT24; + u4Tmp &= ~BIT27; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + else if(bWifiOff) + { + if(pBtCoexist->chipInterface == BTC_INTF_USB) + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30430004); + else + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x64, 0x30030004); + + // 0x4c[27][24]='11', Set Antenna to BT, 0x64[8:7]=0, 0x64[2]=1 + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp |= BIT24; + u4Tmp |= BIT27; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x4); + break; + case BTC_ANT_PATH_BT: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x20); + break; + default: + case BTC_ANT_PATH_PTA: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x92c, 0x4); + break; + } +} + +VOID +halbtc8192e2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + s1Byte nWiFiDurationAdjust = 0x0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", + pCoexDm->bPrePsTdmaOn, pCoexDm->bCurPsTdmaOn)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", + pCoexDm->prePsTdma, pCoexDm->curPsTdma)); + + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum >= 40) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nScanAPNum >= 20) + nWiFiDurationAdjust = -10; + +/* + 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) ) + { + 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) + { + case 1: + default: //d1,wb + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x11, 0x10); + break; + case 2: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x11, 0x10); + break; + case 3: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x11, 0x10); + break; + case 4: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x11, 0x10); + break; + case 5: //d1,pb,TXpause + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x63, 0x3c, 0x03, 0x90, 0x10); + break; + case 6: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x63, 0x32, 0x03, 0x90, 0x10); + break; + case 7: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x63, 0x28, 0x03, 0x90, 0x10); + break; + case 8: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x63, 0x1e, 0x03, 0x90, 0x10); + break; + case 9: //d1,bb + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x31, 0x10); + break; + case 10: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x31, 0x10); + break; + case 11: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x31, 0x10); + break; + case 12: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x31, 0x10); + break; + case 13: //d1,bb,TXpause + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x30, 0x10); + break; + case 14: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x30, 0x10); + break; + case 15: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x30, 0x10); + break; + case 16: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x30, 0x10); + break; + case 17: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x61, 0x20, 0x03, 0x10, 0x10); + break; + case 18: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x03, 0x11, 0x11); + break; + case 71: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + break; + + // following cases is for wifi rssi low // bad antenna isolation, started from 81 + case 80: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x3c, 0x3, 0x90, 0x50); + break; + case 81: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x3a+nWiFiDurationAdjust, 0x3, 0x90, 0x50); + break; + case 82: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x30+nWiFiDurationAdjust, 0x03, 0x90, 0x50); + break; + case 83: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x21, 0x03, 0x90, 0x50); + break; + case 84: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x15, 0x3, 0x90, 0x50); + break; + case 85: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x3a, 0x03, 0x90, 0x50); + break; + case 86: + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x53, 0x21, 0x03, 0x90, 0x50); + break; + + } + } + else + { + // disable PS tdma + switch(type) + { + default: + case 0: //ANT2PTA, 0x778=1 + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + halbtc8192e2ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FALSE, FALSE); + break; + case 1: //ANT2BT, 0x778=3 + halbtc8192e2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0); + delay_ms(5); + halbtc8192e2ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); + break; + + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8192e2ant_SetSwitchSsType( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte ssType + ) +{ + u1Byte mimoPs=BTC_MIMO_PS_DYNAMIC; + u4Byte disRaMask=0x0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], REAL set SS Type = %d\n", ssType)); + + disRaMask = halbtc8192e2ant_DecideRaMask(pBtCoexist, ssType, pCoexDm->curRaMaskType); + halbtc8192e2ant_UpdateRaMask(pBtCoexist, FORCE_EXEC, disRaMask); + + if(ssType == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + // switch ofdm path + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xc04, 0x11); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xd04, 0x1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x90c, 0x81111111); + // switch cck patch + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x1); + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xa07, 0x81); + mimoPs=BTC_MIMO_PS_STATIC; + } + else if(ssType == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xc04, 0x33); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xd04, 0x3); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x90c, 0x81121313); + // remove, if 0xe77[2]=0x0 then CCK will fail, advised by Jenyu + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xe77, 0x4, 0x0); + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xa07, 0x41); + mimoPs=BTC_MIMO_PS_DYNAMIC; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimoPs); // set rx 1ss or 2ss +} + +VOID +halbtc8192e2ant_SwitchSsType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte newSsType + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], %s Switch SS Type = %d\n", + (bForceExec? "force to":""), newSsType)); + pCoexDm->curSsType = newSsType; + + if(!bForceExec) + { + if(pCoexDm->preSsType == pCoexDm->curSsType) + return; + } + halbtc8192e2ant_SetSwitchSsType(pBtCoexist, pCoexDm->curSsType); + + pCoexDm->preSsType = pCoexDm->curSsType; +} + +VOID +halbtc8192e2ant_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 + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8192e2ant_PowerSaveState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte psType, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bLowPwrDisable=FALSE; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + psType = BTC_PS_WIFI_NATIVE; + lpsVal = 0x0; + rpwmVal = 0x0; + } + + switch(psType) + { + case BTC_PS_WIFI_NATIVE: + // recover to original 32k low power setting + bLowPwrDisable = TRUE; + 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: + halbtc8192e2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8192e2ant_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: + halbtc8192e2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + + +VOID +halbtc8192e2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8192e2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0); + + halbtc8192e2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + halbtc8192e2ant_SwitchSsType(pBtCoexist, FORCE_EXEC, 2); + + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ +// BOOLEAN bLowPwrDisable=TRUE; + +// pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1); + + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 21); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionWiFiLinkProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + +} + +BOOLEAN +halbtc8192e2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + BOOLEAN bBtHsOn=FALSE, bLowPwrDisable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(pBtLinkInfo->bScoExist || pBtLinkInfo->bHidExist) + { + halbtc8192e2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 0, 0, 0); + } + else + { + halbtc8192e2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + } + + if(!bWifiConnected) + { +// bLowPwrDisable = FALSE; +// pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-connected idle!!\n")); + + if( (BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) || + (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { +// bLowPwrDisable = FALSE; +// pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else if(BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) + { +// bLowPwrDisable = TRUE; +// pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bBtHsOn) + return FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8192e2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { +// bLowPwrDisable = TRUE; +// pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + bCommon = FALSE; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 21); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + bCommon = TRUE; + } + } + } + + return bCommon; +} + + +VOID +halbtc8192e2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +VOID +halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow( + IN PBTC_COEXIST pBtCoexist//, + //IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow()\n")); +#if 0 + if( (BT_8192E_2ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8192E_2ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8192E_2ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 81 && + pCoexDm->curPsTdma != 82 && + pCoexDm->curPsTdma != 83 && + pCoexDm->curPsTdma != 84 ) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } +#endif + pCoexDm->bAutoTdmaAdjust = FALSE; + + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if(!pCoexDm->bAutoTdmaAdjustLowRssi) + { + pCoexDm->bAutoTdmaAdjustLowRssi = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjustForWifiRssiLow()!!\n")); + +/* + if(BT_INFO_8192E_2ANT_A2DP_BASIC_RATE(btInfoExt)) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else +*/ + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 81); + pCoexDm->psTdmaDuAdjType = 81; + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 +// retryCount = pCoexSta->btRetryCnt; +// btInfoExt = pCoexSta->btInfoExt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { +/* + if( (BT_INFO_8192E_2ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 81) ||(pCoexDm->curPsTdma == 82)) ) + if( (BT_INFO_8192E_2ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 81) ||(pCoexDm->curPsTdma == 82)) ) + + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 84); + pCoexDm->psTdmaDuAdjType = 84; + } +*/ + if(pCoexDm->curPsTdma == 80) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 81); + pCoexDm->psTdmaDuAdjType = 81; + } + else if(pCoexDm->curPsTdma == 81) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + else if(pCoexDm->curPsTdma == 82) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else if(pCoexDm->curPsTdma == 83) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 84); + pCoexDm->psTdmaDuAdjType = 84; + } + } + else if(result == 1) + { +/* + if( (BT_INFO_8192E_2ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 81) ||(pCoexDm->curPsTdma == 82)) ) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } +*/ + if(pCoexDm->curPsTdma == 84) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else if(pCoexDm->curPsTdma == 83) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + else if(pCoexDm->curPsTdma == 82) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 81); + pCoexDm->psTdmaDuAdjType = 81; + } + else if((pCoexDm->curPsTdma == 81)&&((pCoexSta->nScanAPNum <= NOISY_AP_NUM_THRESH))) + { + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 80); + pCoexDm->psTdmaDuAdjType = 80; + } + + } + + if( pCoexDm->curPsTdma != 80 && + pCoexDm->curPsTdma != 81 && + pCoexDm->curPsTdma != 82 && + pCoexDm->curPsTdma != 83 && + pCoexDm->curPsTdma != 84 ) + { + // recover to previous adjust type + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8192e2ant_GetBtRssiThreshold( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte pThres0, + IN pu1Byte pThres1 + ) +{ + u1Byte antType, btThreshold=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_ANT_TYPE, &antType); + + switch(antType) + { + case BTC_ANT_TYPE_0: // 92E with SPDT + *pThres0 = 100; + *pThres1 = 100; + break; + case BTC_ANT_TYPE_1: //92E without SPDT, poor antenna isolation + *pThres0 = 34; + *pThres1 = 42; + break; + case BTC_ANT_TYPE_2: //92E without SPDT, normal antenna isolation + *pThres0 = 34; //92E with coupler, goodl antenna isolation + *pThres1 = 42; + break; + case BTC_ANT_TYPE_3: + *pThres0 = 34; + *pThres1 = 42; + break; + case BTC_ANT_TYPE_4: + *pThres0 = 34; + *pThres1 = 42; + break; + default: + break; + } +} + + +//undefined +VOID +halbtc8192e2ant_ActionUndefined( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // decrease BT power + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + + +// SCO only or SCO+PAN(HS) +VOID +halbtc8192e2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + // halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, TRUE, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + else + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // decrease BT power + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionScoPan( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + + // pstdm + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); //shielding room + else if (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 10); //open space //antenna at BT + else //low RSSI + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); + + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte anttype=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_ANT_TYPE, &anttype); + +// halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); +// btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + // power save state & pstdma & coex table + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + + // power save state + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // decrease BT power + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8192e2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte anttype=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_ANT_TYPE, &anttype); + +// halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); +// btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + +// anttype = 4; + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); //shielding room + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x06); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + + if( (btRssiState == BTC_RSSI_STATE_LOW) || + (btRssiState == BTC_RSSI_STATE_STAY_LOW) ) + { + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + else if( (btRssiState == BTC_RSSI_STATE_MEDIUM) || + (btRssiState == BTC_RSSI_STATE_STAY_MEDIUM) ) + { + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 2); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + } + else if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 2); + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); //shielding room + else if (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); //open space //antenna at BT + else //low RSSI + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 85); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +//PAN(HS) only +VOID +halbtc8192e2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + +// halbtc8192e2ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + + if( (btRssiState == BTC_RSSI_STATE_LOW) || + (btRssiState == BTC_RSSI_STATE_STAY_LOW) ) + { + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + else if( (btRssiState == BTC_RSSI_STATE_MEDIUM) || + (btRssiState == BTC_RSSI_STATE_STAY_MEDIUM) ) + { + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + } + else if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + } + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +//PAN(EDR)+A2DP +VOID +halbtc8192e2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if((BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); //shielding room + else if (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); //open space //antenna at BT + else //low RSSI +{ + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); +} + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if((BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdm + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); //shielding room + else if (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); //open space //antenna at BT + else //low RSSI + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8192e2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + // btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + // power save state + if((BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); //6 + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); //shielding room + else if (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); //open space //antenna at BT + else //low RSSI + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); + } + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0, anttype=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_ANT_TYPE, &anttype); + + // halbtc8192e2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + // btRssiState = halbtc8192e2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8192e2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8192e2ant_BtRssiState(3, 34, 42); + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8192e2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8192e2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8192e2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8192e2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH) // BT HIGH RSSI & shielding room + halbtc8192e2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + + // limited Rx + halbtc8192e2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8192e2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + // sw mechanism + halbtc8192e2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); //shielding room + else if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH)) + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x06); //open space + else //low RSSI + halbtc8192e2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8192e2ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + +} + +VOID +halbtc8192e2ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + +} + +VOID +halbtc8192e2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiUnder5G=FALSE; + u1Byte btInfoOriginal=0, btRetryCnt=0; + u1Byte algorithm=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + algorithm = halbtc8192e2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bC2hBtInquiryPage && (BT_8192E_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8192e2ant_ActionBtInquiry(pBtCoexist); + return; + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8192e2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8192E_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8192e2ant_ActionSco(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_SCO_PAN: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO+PAN(EDR).\n")); + halbtc8192e2ant_ActionScoPan(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8192e2ant_ActionHid(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8192e2ant_ActionA2dp(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8192e2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8192e2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8192e2ant_ActionPanHs(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8192e2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8192e2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8192e2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8192E_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8192e2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = undefined!!\n")); + halbtc8192e2ant_ActionUndefined(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8192e2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp + ) +{ + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + if(bBackUp) + { + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + + // antenna sw ctrl to bt + halbtc8192e2ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, TRUE, FALSE); + + halbtc8192e2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + // antenna switch control parameter + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x858, 0x55555555); + + // coex parameters + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + // enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // enable PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); + // enable mailbox interface + u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x40); + u2Tmp |= BIT9; + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x40, u2Tmp); + + // enable PTA I2C mailbox + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x101); + u1Tmp |= BIT4; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x101, u1Tmp); + + // enable bt clock when wifi is disabled. + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x93); + u1Tmp |= BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x93, u1Tmp); + // enable bt clock when suspend. + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7); + u1Tmp |= BIT0; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x7, u1Tmp); +} + +//============================================================ +// work around function start with wa_halbtc8192e2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8192e2ant_ +//============================================================ +VOID +EXhalbtc8192e2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8192e2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8192e2ant_InitHwConfig(pBtCoexist, TRUE); +} + +VOID +EXhalbtc8192e2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8192e2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8192e2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u2Byte u2Tmp[4]; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "Antenna type:", \ + pBoardInfo->antType); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8192e2Ant, GLCoexVer8192e2Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": + ( (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + pCoexSta->btRssi, pCoexSta->btRetryCnt); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8192e2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } +/* + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type", \ + pCoexDm->curSsType); + CL_PRINTF(cliBuf); +*/ + // Sw mechanism + 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/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \ + pCoexDm->curBtDecPwrLvl, pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "backup ARFR1/ARFR2/RL/AMaxTime", \ + pCoexDm->backupArfrCnt1, pCoexDm->backupArfrCnt2, pCoexDm->backupRetryLimit, pCoexDm->backupAmpduMaxTime); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + u2Tmp[0] = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "0x430/0x434/0x42a/0x456", \ + u4Tmp[0], u4Tmp[1], u2Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc04); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xd04); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x90c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0xc04/ 0xd04/ 0x90c", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x92c); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x930); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x92c/ 0x930", \ + (u1Tmp[0]), u4Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4f); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x40/ 0x4f", \ + u1Tmp[0], u1Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(hp rx[31:16]/tx[15:0])", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 1) + halbtc8192e2ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8192e2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8192e2ant_CoexAllOff(pBtCoexist); + halbtc8192e2ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + } +} + +VOID +EXhalbtc8192e2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8192e2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + + } +} + +VOID +EXhalbtc8192e2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8192e2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8192e2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8192e2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8192E_2ANT_MAX) + rspSource = BT_INFO_SRC_8192E_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8192E_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + if(bWifiConnected) + { + EXhalbtc8192e2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8192e2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if( (pCoexSta->btInfoExt & BIT3) ) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8192e2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } + +#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8192e2ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8192E_2ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8192E_2ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8192E_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8192E_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8192E_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8192E_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + } + + halbtc8192e2ant_UpdateBtLinkInfo(pBtCoexist); + + if(!(btInfo&BT_INFO_8192E_2ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8192E_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8192E_2ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8192E_2ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8192E_2ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8192E_2ANT_B_ACL_BUSY) + { + pCoexDm->btStatus = BT_8192E_2ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8192E_2ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8192E_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8192E_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bBtBusy = TRUE; + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8192e2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8192e2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8192e2ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + halbtc8192e2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8192e2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8192e2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8192e2Ant, GLCoexVer8192e2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0) + halbtc8192e2ant_QueryBtInfo(pBtCoexist); + halbtc8192e2ant_MonitorBtCtr(pBtCoexist); + halbtc8192e2ant_MonitorBtEnableDisable(pBtCoexist); +#else + if( halbtc8192e2ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust) + { + halbtc8192e2ant_RunCoexistMechanism(pBtCoexist); + } +#endif +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.h new file mode 100644 index 00000000..1876bf47 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8192e2Ant.h @@ -0,0 +1,231 @@ +//=========================================== +// The following is for 8192E 2Ant BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8192E_2ANT 0 + +#define BT_INFO_8192E_2ANT_B_FTP BIT7 +#define BT_INFO_8192E_2ANT_B_A2DP BIT6 +#define BT_INFO_8192E_2ANT_B_HID BIT5 +#define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8192E_2ANT_B_CONNECTION BIT0 + +#define BT_INFO_8192E_2ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2 +#define NOISY_AP_NUM_THRESH 5 + +typedef enum _BT_INFO_SRC_8192E_2ANT{ + BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8192E_2ANT_MAX +}BT_INFO_SRC_8192E_2ANT,*PBT_INFO_SRC_8192E_2ANT; + +typedef enum _BT_8192E_2ANT_BT_STATUS{ + BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8192E_2ANT_BT_STATUS_MAX +}BT_8192E_2ANT_BT_STATUS,*PBT_8192E_2ANT_BT_STATUS; + +typedef enum _BT_8192E_2ANT_COEX_ALGO{ + BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8192E_2ANT_COEX_ALGO_SCO = 0x1, + BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2, + BT_8192E_2ANT_COEX_ALGO_HID = 0x3, + BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4, + BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5, + BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6, + BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7, + BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8, + BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9, + BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa, + BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb, + BT_8192E_2ANT_COEX_ALGO_MAX = 0xc +}BT_8192E_2ANT_COEX_ALGO,*PBT_8192E_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8192E_2ANT{ + // fw mechanism + u1Byte preBtDecPwrLvl; + u1Byte curBtDecPwrLvl; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bAutoTdmaAdjustLowRssi; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u1Byte preSsType; + u1Byte curSsType; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte curRaMaskType; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; +} COEX_DM_8192E_2ANT, *PCOEX_DM_8192E_2ANT; + +typedef struct _COEX_STA_8192E_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8192E_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8192E_2ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + u1Byte btRetryCnt; + u1Byte btInfoExt; + u1Byte nScanAPNum; + + 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_8192E_2ANT, *PCOEX_STA_8192E_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8192e2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8192e2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8192e2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8192e2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8192e2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.c new file mode 100644 index 00000000..ccc67ee8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.c @@ -0,0 +1,5239 @@ +//============================================================ +// Description: +// +// This file is for RTL8703B Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8703b1Ant.tmh" +#endif + +#if (RTL8703B_SUPPORT == 1) + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8703B_1ANT GLCoexDm8703b1Ant; +static PCOEX_DM_8703B_1ANT pCoexDm=&GLCoexDm8703b1Ant; +static COEX_STA_8703B_1ANT GLCoexSta8703b1Ant; +static PCOEX_STA_8703B_1ANT pCoexSta=&GLCoexSta8703b1Ant; +static PSDSCAN_STA_8703B_1ANT GLPsdScan8703b1Ant; +static PPSDSCAN_STA_8703B_1ANT pPsdScan = &GLPsdScan8703b1Ant; + + +const char *const GLBtInfoSrc8703b1Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8703b1Ant=20150904; +u4Byte GLCoexVer8703b1Ant=0x04; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8703b1ant_ +//============================================================ +u1Byte +halbtc8703b1ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8703b1ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8703b1ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8703b1ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8703b1ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8703b1ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8703b1ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8703b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8703b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8703b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8703b1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8703b1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8703b1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8703b1ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8703b1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +VOID +halbtc8703b1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp, u4Tmp1; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp, u1Tmp1; + s4Byte wifiRssi; + static u1Byte NumOfBtCounterChk = 0; + + //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; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if( (pCoexSta->lowPriorityTx > 1150) && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->popEventCnt++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + regHPRx, regHPTx, regLPRx, regLPTx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); + + if ((regHPTx == 0) && (regHPRx ==0) && (regLPTx == 0) && (regLPRx == 0)) + { + NumOfBtCounterChk++; + if (NumOfBtCounterChk >= 3) + { + halbtc8703b1ant_QueryBtInfo(pBtCoexist); + NumOfBtCounterChk = 0; + } + } +} + + +VOID +halbtc8703b1ant_MonitorWiFiCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u2Byte u2Tmp[3]; + s4Byte wifiRssi=0; + BOOLEAN bWifiBusy = FALSE, bWifiUnderBMode = FALSE; + static u1Byte nCCKLockCounter = 0; + u4Byte TotalCnt; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + 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); + + if ( (bWifiBusy) && (wifiRssi >= 30) && (!bWifiUnderBMode)) + { + TotalCnt = pCoexSta->nCRCOK_CCK + pCoexSta->nCRCOK_11g + pCoexSta->nCRCOK_11n + + pCoexSta->nCRCOK_11nAgg; + + if ( (pCoexDm->btStatus == BT_8703B_1ANT_BT_STATUS_ACL_BUSY) || + (pCoexDm->btStatus == BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY) || + (pCoexDm->btStatus == BT_8703B_1ANT_BT_STATUS_SCO_BUSY) ) + { + if (pCoexSta->nCRCOK_CCK >(TotalCnt -pCoexSta->nCRCOK_CCK)) + { + if (nCCKLockCounter < 3) + nCCKLockCounter++; + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + if (!pCoexSta->bPreCCKLock) + { + + if (nCCKLockCounter >= 3) + pCoexSta->bCCKLock = TRUE; + else + pCoexSta->bCCKLock = FALSE; + } + else + { + if (nCCKLockCounter == 0) + pCoexSta->bCCKLock = FALSE; + else + pCoexSta->bCCKLock = TRUE; + } + + if (pCoexSta->bCCKLock) + pCoexSta->bCCKEverLock = TRUE; + + pCoexSta->bPreCCKLock = pCoexSta->bCCKLock; + + +} + +BOOLEAN +halbtc8703b1ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; + BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + } + + return FALSE; +} + +VOID +halbtc8703b1ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + pBtLinkInfo->bBtHiPriLinkExist = pCoexSta->bBtHiPriLinkExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +VOID +halbtc8703b1ant_UpdateWifiChannelInfo( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + BOOLEAN bWifiUnderBMode = FALSE; + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; //enable BT AFH skip WL channel for 8703b because BT Rx LO interference + //H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); + +} + +u1Byte +halbtc8703b1ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8703B_1ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO only\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID only\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP only\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(HS) only\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(EDR) only\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP ==> SCO\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(EDR)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID_A2DP; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(EDR)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(EDR)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8703B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8703b1ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8703b1ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8703b1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID halbtc8703b1ant_WriteScoreBoard( + IN PBTC_COEXIST pBtCoexist, + IN u2Byte scoreboardval + ) +{ + u2Byte val; + + val = (scoreboardval & 0x7fff) | 0x8000; + + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0xaa, val); + +#if 0 + u1Byte H2C_Parameter[3] ={0,0,0}; + + + // write "Set Status" + H2C_Parameter[0] = 0x2; + + // write score board 15-bit value to H2C parameter + H2C_Parameter[1] = scoreboardval & 0xff; + H2C_Parameter[2] = (scoreboardval & 0x7f00) >> 8; + + // Set Interrupt to BT + H2C_Parameter[2] = H2C_Parameter[2] | 0x80; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Write BT Scoreboard: H2C 0x71[1:0]= %02x%02x\n", + H2C_Parameter[2], H2C_Parameter[1])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x71, 3, H2C_Parameter); + +#endif +} + +VOID halbtc8703b1ant_ReadScoreBoard( + IN PBTC_COEXIST pBtCoexist, + IN u2Byte* uScoreBoardVal + ) +{ + + *uScoreBoardVal = (pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xaa)) & 0x7fff; + + + +#if 0 + u1Byte H2C_Parameter[3] ={0,0,0}; + + // write "Get Status" + H2C_Parameter[0] = 0x1; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Read BT Scoreboard!!\n")); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x71, 3, H2C_Parameter); + + //the BT Scoreboard will be returned by C2H from EXhalbtc8703b1ant_ScoreBoardStatusNotify() +#endif +} + +VOID halbtc8703b1ant_PostActiveStateToBT( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiActive + ) +{ + + if(bWifiActive) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Post WL = Active in Scoreboard!!\n")); + halbtc8703b1ant_WriteScoreBoard(pBtCoexist, 0x0001); + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Post WL = Non-Active in Scoreboard!!\n")); + halbtc8703b1ant_WriteScoreBoard(pBtCoexist, 0x0000); + } + + // The BT should set "No Shunt-down" mode if WL = Active for BT Synthesizer on/off interference WL Lo issue at 8703b b-cut. + +} + +VOID +halbtc8703b1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!") )); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8703b1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8703b1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +u4Byte +halbtc8703b1ant_LTECoex_InDirectReadReg( +IN PBTC_COEXIST pBtCoexist, +IN u2Byte RegAddr +) +{ + u4Byte j =0; + + + //wait for ready bit before access 0x7c0 + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x7c0, 0x800F0000|RegAddr); + + do + { + j++; + }while( ((pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7c3) & BIT5) ==0) && (j fBtcRead4Byte(pBtCoexist, 0x7c8)); //get read data + +} + +VOID +halbtc8703b1ant_LTECoex_InDirectWriteReg( +IN PBTC_COEXIST pBtCoexist, +IN u2Byte RegAddr, +IN u4Byte BitMask, +IN u4Byte RegValue +) +{ + u4Byte val, i=0, j=0, bitpos = 0; + + + if (BitMask == 0x0) + return; + if (BitMask == 0xffffffff) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x7c4, RegValue); //put write data + + //wait for ready bit before access 0x7c0 + do + { + j++; + }while( ((pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7c3) & BIT5) ==0) && (j fBtcWrite4Byte(pBtCoexist, 0x7c0, 0xc00F0000|RegAddr); + } + else + { + for(i=0; i<=31; i++) + { + if ( ((BitMask >> i) & 0x1) == 0x1) + { + bitpos = i; + break; + } + } + + //read back register value before write + val = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, RegAddr); + val = (val & (~BitMask)) | (RegValue << bitpos); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x7c4, val); //put write data + + //wait for ready bit before access 0x7c0 + do + { + j++; + }while( ((pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7c3) & BIT5) ==0) && (j fBtcWrite4Byte(pBtCoexist, 0x7c0, 0xc00F0000|RegAddr); + + } + +} + +void +halbtc8703b1ant_LTECoex_Enable( +IN PBTC_COEXIST pBtCoexist, +IN BOOLEAN bEnable +) +{ + u1Byte val; + + val = (bEnable)? 1 : 0; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, 0x80, val); //0x38[7] + +} + +void +halbtc8703b1ant_LTECoex_PathControlOwner( +IN PBTC_COEXIST pBtCoexist, +IN BOOLEAN bWiFiControl +) +{ + u1Byte val; + + val = (bWiFiControl)? 1 : 0; + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x73, 0x4, val); //0x70[26] + +} + +void +halbtc8703b1ant_LTECoex_Set_GNT_BT( +IN PBTC_COEXIST pBtCoexist, +IN u1Byte nControlBlock, +IN BOOLEAN bSWControl, +IN u1Byte nState +) +{ + u4Byte val=0, BitMask; + + nState = nState & 0x1; + val = (bSWControl)? ((nState<<1) | 0x1) : 0; + + switch(nControlBlock) + { + case BT_8703B_1ANT_GNT_BLOCK_RFC_BB: + default: + BitMask = 0xc000; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[15:14] + BitMask = 0x0c00; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[11:10] + break; + case BT_8703B_1ANT_GNT_BLOCK_RFC: + BitMask = 0xc000; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[15:14] + break; + case BT_8703B_1ANT_GNT_BLOCK_BB: + BitMask = 0x0c00; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[11:10] + break; + + } + +} + +void +halbtc8703b1ant_LTECoex_Set_GNT_WL( +IN PBTC_COEXIST pBtCoexist, +IN u1Byte nControlBlock, +IN BOOLEAN bSWControl, +IN u1Byte nState +) +{ + u4Byte val=0, BitMask; + + nState = nState & 0x1; + val = (bSWControl)? ((nState<<1) | 0x1) : 0; + + switch(nControlBlock) + { + case BT_8703B_1ANT_GNT_BLOCK_RFC_BB: + default: + BitMask = 0x3000; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[13:12] + BitMask = 0x0300; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[9:8] + break; + case BT_8703B_1ANT_GNT_BLOCK_RFC: + BitMask = 0x3000; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[13:12] + break; + case BT_8703B_1ANT_GNT_BLOCK_BB: + BitMask = 0x0300; + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, 0x38, BitMask, val); // 0x38[9:8] + break; + + } + +} + +void +halbtc8703b1ant_LTECoex_Set_CoexTable( +IN PBTC_COEXIST pBtCoexist, +IN u1Byte nTableType, +IN u2Byte nTableContent +) +{ + u2Byte RegAddr = 0x0000; + + switch(nTableType) + { + case BT_8703B_1ANT_CTT_WL_VS_LTE: + RegAddr = 0xa0; + break; + case BT_8703B_1ANT_CTT_BT_VS_LTE: + RegAddr = 0xa4; + break; + } + + if (RegAddr != 0x0000) + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, RegAddr, 0xffff, nTableContent); // 0xa0[15:0] or 0xa4[15:0] + + +} + + +void +halbtc8703b1ant_LTECoex_Set_BreakTable( +IN PBTC_COEXIST pBtCoexist, +IN u1Byte nTableType, +IN u1Byte nTableContent +) +{ + u2Byte RegAddr = 0x0000; + + switch(nTableType) + { + case BT_8703B_1ANT_LBTT_WL_BREAK_LTE: + RegAddr = 0xa8; + break; + case BT_8703B_1ANT_LBTT_BT_BREAK_LTE: + RegAddr = 0xac; + break; + case BT_8703B_1ANT_LBTT_LTE_BREAK_WL: + RegAddr = 0xb0; + break; + case BT_8703B_1ANT_LBTT_LTE_BREAK_BT: + RegAddr = 0xb4; + break; + } + + if (RegAddr != 0x0000) + halbtc8703b1ant_LTECoex_InDirectWriteReg(pBtCoexist, RegAddr, 0xff, nTableContent); // 0xa8[15:0] or 0xb4[15:0] + + +} + +VOID +halbtc8703b1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8703b1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8703b1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8703b1ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + u4Byte nBreakTable; + u1Byte nSelectTable; + + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], ********** CoexTable(%d) **********\n", type)); + + pCoexSta->nCoexTableType = type; + + if (pCoexSta->bConCurrentRxModeOn == TRUE) + { + nBreakTable = 0xf0ffffff; //set WL hi-pri can break BT + nSelectTable = 0xb; //set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) + } + else + { + nBreakTable = 0xffffff; + nSelectTable = 0x3; + } + + switch(type) + { + case 0: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, nBreakTable, nSelectTable); + break; + case 1: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, nBreakTable, nSelectTable); + break; + case 2: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaa5a5a5a, 0xaa5a5a5a, nBreakTable, nSelectTable); + break; + case 3: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaa555555, 0xaa5a5a5a, nBreakTable, nSelectTable); + break; + case 4: + //if ( (pCoexSta->bCCKEverLock) && (pCoexSta->nScanAPNum <= 5) ) + // halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaa555555, 0xaaaa5a5a, nBreakTable, nSelectTable); + //else + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaa555555, 0xaa5a5a5a, nBreakTable, nSelectTable); + break; + case 5: + //if ( (pCoexSta->bCCKEverLock) && (pCoexSta->nScanAPNum <= 5) ) + // halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaa555555, 0xaaaa5a5a, nBreakTable, nSelectTable); + //else + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, nBreakTable, nSelectTable); + break; + case 6: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, nBreakTable, nSelectTable); + break; + case 7: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, nBreakTable, nSelectTable); + break; + case 8: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 9: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 10: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 11: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 12: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 13: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0xaaaaaaaa, nBreakTable, nSelectTable); + break; + case 14: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5ada5ada, nBreakTable, nSelectTable); + break; + case 15: + halbtc8703b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0xaaaaaaaa, nBreakTable, nSelectTable); + break; + default: + break; + } +} + +VOID +halbtc8703b1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8703b1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8703b1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8703b1ant_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 +halbtc8703b1ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8703b1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8703b1ant_SwMechanism( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRA + ) +{ + halbtc8703b1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8703b1ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bForceExec, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte fwVer=0, u4Tmp=0, cntBtCalChk=0; + BOOLEAN bPgExtSwitch=FALSE; + BOOLEAN bUseExtSwitch=FALSE; + BOOLEAN bIsInMpMode = FALSE; + u1Byte H2C_Parameter[2] ={0}, u1Tmp = 0; + u4Byte u4Tmp1=0, u4Tmp2=0; + + pCoexDm->curAntPosType = antPosType; + +#if 1 + u4Tmp1 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x38); + u4Tmp2 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x54); + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x73); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** (Before Setup) 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n", u1Tmp, u4Tmp1, u4Tmp2)); +#endif + + if(bInitHwCfg) + { + //Disable LTE Coex Function in WiFi side (this should be on if LTE coex is required) + halbtc8703b1ant_LTECoex_Enable(pBtCoexist, 0x0); + + //GNT_WL_LTE always = 1 (this should be config if LTE coex is required) + halbtc8703b1ant_LTECoex_Set_CoexTable(pBtCoexist, BT_8703B_1ANT_CTT_WL_VS_LTE, 0xffff); + + //GNT_BT_LTE always = 1 (this should be config if LTE coex is required) + halbtc8703b1ant_LTECoex_Set_CoexTable(pBtCoexist, BT_8703B_1ANT_CTT_BT_VS_LTE, 0xffff); + + // Wait If BT IQK running, because Path control owner is at BT during BT IQK (setup by WiFi firmware) + while(cntBtCalChk <= 20) + { + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49d); + cntBtCalChk++; + if(u1Tmp & BIT0) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ########### BT is calibrating (wait cnt=%d) ###########\n", cntBtCalChk)); + delay_ms(50); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)**********\n", cntBtCalChk)); + break; + } + } + + //set Path control owner to WL at initial step + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_WLSIDE); + } + else if(bWifiOff) + { + //Disable LTE Coex Function in WiFi side + halbtc8703b1ant_LTECoex_Enable(pBtCoexist, 0x0); + + //if MP mode + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, &bIsInMpMode); + if(bIsInMpMode) + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_WLSIDE); //set Path control owner to WiFI + else + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_BTSIDE);//set Path control owner to BT + } + else + { + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_WLSIDE); + } + + + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType) || bInitHwCfg || bWifiOff) + { + // internal switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + // set GNT_BT to low + halbtc8703b1ant_LTECoex_Set_GNT_BT(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_LOW); + //Set GNT_WL to high + halbtc8703b1ant_LTECoex_Set_GNT_WL(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_HIGH); + break; + case BTC_ANT_PATH_BT: + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_BTSIDE); + // set GNT_BT to high + /* halbtc8703b1ant_LTECoex_Set_GNT_BT(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_HIGH); */ + //Set GNT_WL to low + /* halbtc8703b1ant_LTECoex_Set_GNT_WL(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_LOW); */ + break; + default: + case BTC_ANT_PATH_PTA: + // set GNT_BT to PTA + halbtc8703b1ant_LTECoex_Set_GNT_BT(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_PTA, BT_8703B_1ANT_SIG_STA_SET_BY_HW); + //Set GNT_WL to PTA + halbtc8703b1ant_LTECoex_Set_GNT_WL(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_PTA, BT_8703B_1ANT_SIG_STA_SET_BY_HW); + break; + } + } + +#if 1 + u4Tmp1 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x38); + u4Tmp2 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x54); + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x73); + + if(bInitHwCfg) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** (After Init) 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n", u1Tmp, u4Tmp1, u4Tmp2)); + } + else if (bWifiOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** (After WiFi off) 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n", u1Tmp, u4Tmp1, u4Tmp2)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** (After Run time) 0x73 = 0x%x, 0x38= 0x%x, 0x54= 0x%x**********\n", u1Tmp, u4Tmp1, u4Tmp2)); + } +#endif + + pCoexDm->preAntPosType = pCoexDm->curAntPosType; +} + + +VOID +halbtc8703b1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + + +VOID +halbtc8703b1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bTurnOnByCnt=FALSE, bWifiBusy=FALSE, bWiFiNoisy=FALSE; + u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0; + u1Byte psTdmaByte4Val = 0x50, psTdmaByte0Val = 0x51, psTdmaByte3Val = 0x10; + s1Byte nWiFiDurationAdjust = 0x0; + static BOOLEAN bPreWifiBusy=FALSE; + + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if (bWifiBusy != bPreWifiBusy) + { + bForceExec = TRUE; + bPreWifiBusy = bWifiBusy; + } + + if (pCoexDm->bCurPsTdmaOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(off, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + // Adjust WiFi slot by AP number + if (pCoexSta->nScanAPNum <= 5) + nWiFiDurationAdjust = 5; + else if (pCoexSta->nScanAPNum >= 40) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nScanAPNum >= 20) + nWiFiDurationAdjust = -10; + + // for A2DP only case, PS-TDMA/ TDMA + if ((type == 1) || (type == 2) || (type == 9) || (type == 11) || (type == 101) + || (type == 102) || (type == 109) || (type == 101) || (type == 7) ) + { + if (!pCoexSta->bForceLpsOn) //Native power save TDMA, only for A2DP-only case 1/2/9/11 while wifi noisy threshold > 30 + { + psTdmaByte0Val = 0x61; //no null-pkt (TDMA) + psTdmaByte3Val = 0x11; // no tx-pause at BT-slot + + if (type == 7) + psTdmaByte4Val = 0x14; //BT-Auto-Slot + else + psTdmaByte4Val = 0x10; // 0x778 = d/1 toggle, no dynamic slot + } + else + { + psTdmaByte0Val = 0x51; //null-pkt (PS-TDMA) + psTdmaByte3Val = 0x10; //tx-pause at BT-slot + + if (type == 7) + psTdmaByte4Val = 0x14; //BT-Auto-Slot + else + psTdmaByte4Val = 0x50; // 0x778 = d/1 toggle, dynamic slot + } + } + else if ((type == 3) ||(type == 4) || (type == 13) || (type == 14) || (type == 103) || (type == 113) || (type == 114)) + { + psTdmaByte0Val = 0x51; //null-pkt (PS-TDMA) + psTdmaByte3Val = 0x10; //tx-pause at BT-slot + psTdmaByte4Val = 0x10; // 0x778 = d/1 toggle, no dynamic slot + } + else //native power save case + { + psTdmaByte0Val = 0x61; //no null-pkt (TDMA) + psTdmaByte3Val = 0x11; // no tx-pause at BT-slot + psTdmaByte4Val = 0x11; // 0x778 = d/1 toggle, no dynamic slot + //psTdmaByte4Va is not defne for 0x778 = d/1, 1/1 case + } + + // for A2DP slave + if ((pBtLinkInfo->bSlaveRole == TRUE) && (pBtLinkInfo->bA2dpExist)) + psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) + + // (for Antenna Detection Mechanism) + if (type > 100) + { + psTdmaByte0Val = psTdmaByte0Val | 0x82; //set antenna control by SW + psTdmaByte3Val = psTdmaByte3Val | 0x60; //set antenna no toggle, control by antenna diversity + } + + + if(bTurnOn) + { + switch(type) + { + default: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, psTdmaByte4Val); + break; + case 1: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 2: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 3: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 4: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 5: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x15, 0x3, psTdmaByte3Val, 0x11); + break; + case 6: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x20, 0x3, psTdmaByte3Val, 0x11); + break; + case 7: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x1e, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 8: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1e, 0x3, 0x10, 0x14); + break; + case 9: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 10: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 12: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50); + break; + case 13: + if (pCoexSta->nScanAPNum <= 3) // for Lenovo CPT test A2DP + OPP + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a, 0x3, psTdmaByte3Val, psTdmaByte4Val); + else + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 14: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 15: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0); + break; + case 16: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0); + break; + case 18: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 20: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3f, 0x03, psTdmaByte3Val, 0x10); + break; + case 21: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11); + break; + case 22: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x10); + break; + case 23: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18); + break; + case 24: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18); + break; + case 25: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 26: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 27: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98); + break; + case 28: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0); + break; + case 29: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10); + break; + case 31: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58); + break; + case 32: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x35, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 33: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x35, 0x3, psTdmaByte3Val, 0x10); + break; + case 34: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50); + break; + case 40: // SoftAP only with no sta associated,BT disable ,TDMA mode for power saving + /* here softap mode screen off will cost 70-80mA for phone */ + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24); + break; + + // 1-Ant translate to 2-Ant (for Antenna Detection Mechanism) + case 101: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 102: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 103: + //halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, psTdmaByte4Val); + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 105: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x15, 0x3, psTdmaByte3Val, 0x11); + break; + case 106: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x20, 0x3, psTdmaByte3Val, 0x11); + break; + case 109: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 111: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 113: + //halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x12, 0x12, 0x0, psTdmaByte4Val); + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 114: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 120: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3f, 0x03, psTdmaByte3Val, 0x10); + break; + case 122: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x10); + break; + case 132: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 133: + halbtc8703b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x11); + break; + + } + } + else + { + + // disable PS tdma + switch(type) + { + case 8: //PTA Control + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + break; + case 0: + default: //Software control, Antenna at BT side + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + break; + case 1: // 2-Ant, 0x778=3, antenna control by antenna diversity + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + break; +#if 0 + case 9: //Software control, Antenna at WiFi side + halbtc8703b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + halbtc8703b1ant_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); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67))); + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +BOOLEAN +halbtc8703b1ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8703B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n")); + + //halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8703B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + //halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n")); + + //halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + + //halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); + + //halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else + { + if (bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + } + + bCommon = FALSE; + } + + return bCommon; +} + + +VOID +halbtc8703b1ant_TdmaDurationAdjustForAcl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + static BOOLEAN bPreWifiBusy=FALSE; + BOOLEAN bWifiBusy = FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjustForAcl()\n")); + + if(BT_8703B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifiStatus) + bWifiBusy = TRUE; + else + bWifiBusy = FALSE; + + if( (BT_8703B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 3 && + pCoexDm->curPsTdma != 9 ) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { +/* if( (BT_INFO_8703B_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else */ if(pCoexDm->curPsTdma == 1) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if(result == 1) + { +/* if( (BT_INFO_8703B_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else */ if(pCoexDm->curPsTdma == 11) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + else //no change + { + /* Bryant Modify + if(bWifiBusy != bPreWifiBusy) //if busy / idle change + { + bPreWifiBusy = bWifiBusy; + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, pCoexDm->curPsTdma); + } + */ + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 9 && + pCoexDm->curPsTdma != 11 ) + { + // recover to previous adjust type + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8703b1ant_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 + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8703b1ant_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 + pCoexSta->bForceLpsOn = FALSE; + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + + break; + case BTC_PS_LPS_ON: + pCoexSta->bForceLpsOn = TRUE; + halbtc8703b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8703b1ant_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); + + break; + case BTC_PS_LPS_OFF: + pCoexSta->bForceLpsOn = FALSE; + halbtc8703b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + + break; + default: + break; + } +} + +VOID +halbtc8703b1ant_ActionWifiOnly( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); +} + +VOID +halbtc8703b1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + halbtc8703b1ant_ActionWifiOnly(pBtCoexist); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +//============================================= +// +// Software Coex Mechanism start +// +//============================================= + +// SCO only or SCO+PAN(HS) + +/* +VOID +halbtc8703b1ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); +} + + +VOID +halbtc8703b1ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8703b1ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8703b1ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8703b1ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(HS) only +VOID +halbtc8703b1ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(EDR)+A2DP +VOID +halbtc8703b1ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8703b1ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8703b1ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8703b1ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); +} + +*/ + +//============================================= +// +// Non-Software Coex Mechanism start +// +//============================================= +VOID +halbtc8703b1ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8703b1ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8703b1ant_ActionHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8703b1ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bApEnable=FALSE, bWifiBusy=FALSE, bBtBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if ( (!bWifiConnected) && (!pCoexSta->bWiFiIsHighPriTask) ) + { + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) + { + // SCO/HID/A2DP busy + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if ( (pBtLinkInfo->bPanExist) || (bWifiBusy) ) + { + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + //for BT inquiry/page fail after S4 resume + //halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + + + //halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + //halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } +} + +VOID +halbtc8703b1ant_ActionBtScoHidOnlyBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // tdma and coex table + + if(pBtLinkInfo->bScoExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else //HID + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } +} + +VOID +halbtc8703b1ant_ActionWifiConnectedBtAclBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + u1Byte btRssiState; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + btRssiState = halbtc8703b1ant_BtRssiState(2, 28, 0); + + if ( (pCoexSta->lowPriorityRx >= 950) && (!pCoexSta->bUnderIps) + && (pCoexSta->lowPriorityRx >= pCoexSta->lowPriorityTx) && (!pCoexSta->bC2hBtInquiryPage)) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + if(pBtLinkInfo->bHidOnly) //HID + { + halbtc8703b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus); + pCoexDm->bAutoTdmaAdjust = FALSE; + return; + } + else if(pBtLinkInfo->bA2dpOnly) //A2DP + { + if(BT_8703B_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + //halbtc8703b1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = TRUE; + } + } + else if ( ((pBtLinkInfo->bA2dpExist) && (pBtLinkInfo->bPanExist)) || + (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist&&pBtLinkInfo->bPanExist) ) //A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if(pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) //HID+A2DP + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->bAutoTdmaAdjust = FALSE; + + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if( (pBtLinkInfo->bPanOnly) || (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) ) //PAN(OPP,FTP), HID+PAN(OPP,FTP) + { + if(BT_8703B_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + else + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + //BT no-profile busy (0x9) + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 33); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } +} + +VOID +halbtc8703b1ant_ActionWifiNotConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8703b1ant_ActionWifiNotConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8703b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8703b1ant_ActionWifiNotConnectedAssoAuth( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + } + else if (pBtLinkInfo->bPanExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + } + else + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 2); + } +} + +VOID +halbtc8703b1ant_ActionWifiConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8703b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8703b1ant_ActionWifiConnectedSpecialPacket( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiBusy = FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + //no special packet process for both WiFi and BT very busy + if ((bWifiBusy) && ((pBtLinkInfo->bPanExist) || (pCoexSta->nNumOfProfile >= 2))) + return; + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist)) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else if (pBtLinkInfo->bA2dpExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if(pBtLinkInfo->bPanExist) + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8703b1ant_ActionWifiConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiBusy=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + BOOLEAN bUnder4way=FALSE, bApEnable=FALSE; + u4Byte wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect()===>\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + if(bUnder4way) + { + halbtc8703b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n")); + return; + } + + 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) + { + if(bScan) + halbtc8703b1ant_ActionWifiConnectedScan(pBtCoexist); + else + halbtc8703b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + // power save state + if(!bApEnable && BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->btLinkInfo.bHidOnly) + { + if(pBtCoexist->btLinkInfo.bA2dpOnly) //A2DP + { + if(!bWifiBusy) + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else //busy + { + if (pCoexSta->nScanAPNum >= BT_8703B_1ANT_WIFI_NOISY_THRESH) //no force LPS, no PS-TDMA, use pure TDMA + { + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + } + } + else if ((pCoexSta->bPanExist == FALSE) && (pCoexSta->bA2dpExist == FALSE) && (pCoexSta->bHidExist == FALSE)) + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + else + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(!bWifiBusy) + { + if(BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8703b1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else if( (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8703b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else + { + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + } + else + { + if(BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8703b1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else if( (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8703b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else + { + //halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + //halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } +} + +VOID +halbtc8703b1ant_RunSwCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm=0; + + algorithm = halbtc8703b1ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + + if(halbtc8703b1ant_IsCommonAction(pBtCoexist)) + { + + } + else + { + switch(pCoexDm->curAlgorithm) + { + case BT_8703B_1ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = SCO.\n")); + //halbtc8703b1ant_ActionSco(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID.\n")); + //halbtc8703b1ant_ActionHid(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP.\n")); + //halbtc8703b1ant_ActionA2dp(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n")); + //halbtc8703b1ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR).\n")); + //halbtc8703b1ant_ActionPanEdr(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HS mode.\n")); + //halbtc8703b1ant_ActionPanHs(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN+A2DP.\n")); + //halbtc8703b1ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n")); + //halbtc8703b1ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n")); + //halbtc8703b1ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8703B_1ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP.\n")); + //halbtc8703b1ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = coexist All Off!!\n")); + //halbtc8703b1ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8703b1ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + BOOLEAN bIncreaseScanDevNum=FALSE; + BOOLEAN bBtCtrlAggBufSize=FALSE; + BOOLEAN bMiracastPlusBt=FALSE; + u1Byte aggBufSize=5; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0, wifiBw; + u1Byte iotPeer=BTC_IOT_PEER_UNKNOWN; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if(pCoexSta->bBtWhckTest) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under WHCK TEST!!!\n")); + halbtc8703b1ant_ActionBtWhckTest(pBtCoexist); + return; + } + + if( (BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bIncreaseScanDevNum = TRUE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, &bIncreaseScanDevNum); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], Multi-Port numOfWifiLink = %d, wifiLinkStatus = 0x%x\n", numOfWifiLink,wifiLinkStatus) ); + + if(pBtLinkInfo->bBtLinkExist) + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + bMiracastPlusBt = TRUE; + } + else + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + bMiracastPlusBt = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + + if ( (pBtLinkInfo->bA2dpExist) && (pCoexSta->bC2hBtInquiryPage) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8703b1ant_ActionBtInquiry(pBtCoexist); + } + else + halbtc8703b1ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if ( (pBtLinkInfo->bBtLinkExist) && (bWifiConnected) ) + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_IOT_PEER, &iotPeer); + + if(BTC_IOT_PEER_CISCO != iotPeer) + { + if(pBtLinkInfo->bScoExist)//if (pBtLinkInfo->bBtHiPriLinkExist) + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); + else + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + } + else + { + if(pBtLinkInfo->bScoExist) + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); + else + { + if (BTC_WIFI_BW_HT40==wifiBw) + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x10); + else + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + } + } + + halbtc8703b1ant_SwMechanism(pBtCoexist, TRUE); + halbtc8703b1ant_RunSwCoexistMechanism(pBtCoexist); //just print debug message + } + else + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + halbtc8703b1ant_RunSwCoexistMechanism(pBtCoexist); ////just print debug message + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8703b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8703b1ant_ActionHs(pBtCoexist); + return; + } + + + if(!bWifiConnected) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is non connected-idle !!!\n")); + + 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) + { + if (bScan) + halbtc8703b1ant_ActionWifiNotConnectedScan(pBtCoexist); + else + halbtc8703b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else + halbtc8703b1ant_ActionWifiNotConnected(pBtCoexist); + } + else // wifi LPS/Busy + { + halbtc8703b1ant_ActionWifiConnected(pBtCoexist); + } +} + +u4Byte +halbtc8703b1ant_PSD_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 +halbtc8703b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + + // sw all off + halbtc8703b1ant_SwMechanism(pBtCoexist, FALSE); + + //halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + //halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + pCoexSta->popEventCnt = 0; +} + +VOID +halbtc8703b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp, + IN BOOLEAN bWifiOnly + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0;//, fwVer; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0, u1Tmpa=0, u1Tmpb=0; + u1Byte H2C_Parameter[2] ={0}; + + u4Byte u4Tmp1=0, u4Tmp2=0; + + + u4Tmp1 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x38); + u4Tmp2 = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x54); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** (Before Init HW config) 0x38= 0x%x, 0x54= 0x%x**********\n", u4Tmp1, u4Tmp2)); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x550, 0x8, 0x1); //enable TBTT nterrupt + + //BT report packet sample rate + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, 0x5); + + // Enable BT counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); + + //Enable PTA (3-wire function form BT side) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x41, 0x02, 0x1); + + //Enable PTA (tx/rx signal form WiFi side) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x4c6, 0x10, 0x1); + + //enable GNT_WL/GNT_BT debug signal to GPIO14/15 + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x73, 0x8, 0x1); + + //enable GNT_WL + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x4e, 0x40, 0x0); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x1, 0x0); + + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + + //Antenna config + if(bWifiOnly) + { + pCoexSta->bConCurrentRxModeOn = FALSE; + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FORCE_EXEC, TRUE, FALSE); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FORCE_EXEC, FALSE, FALSE); + } + else + { + pCoexSta->bConCurrentRxModeOn = TRUE; + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x953, 0x2, 0x1); + //RF 0x1[0] = 0 -> Set GNT_WL_RF_Rx always = 1 for con-current Rx + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0x1, 0x0); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, TRUE, FALSE); + } + + // PTA parameter + halbtc8703b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + +} + + + +VOID +halbtc8703b1ant_PSD_ShowData( + IN PBTC_COEXIST pBtCoexist + ) +{ + pu1Byte cliBuf=pBtCoexist->cliBuf; + u4Byte nDeltaFreqPerPoint; + u4Byte freq,freq1,freq2,n=0,i=0, j=0, m=0, PsdRep1, PsdRep2; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n\n============[PSD info] (%d)============\n", + pPsdScan->nPSDGenCount); + CL_PRINTF(cliBuf); + + if (pPsdScan->nPSDGenCount == 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) + if (0) + { + PsdRep1 = pPsdScan->nPSDMaxValue/100; + PsdRep2 = pPsdScan->nPSDMaxValue - PsdRep1 * 100; + + freq = ((pPsdScan->nRealCentFreq-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) \n", + PsdRep1, PsdRep2, pPsdScan->nPSDMaxValue); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, ", Value = %d.%d dB, (%d)\n", + PsdRep1, PsdRep2, pPsdScan->nPSDMaxValue); + + CL_PRINTF(cliBuf); + } + else + { + m = pPsdScan->nPSDStartPoint; + n = pPsdScan->nPSDStartPoint; + i = 1; + j = 1; + + while(1) + { + do + { + freq = ((pPsdScan->nRealCentFreq-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; + } + + } + } + + +} + +VOID +halbtc8703b1ant_PSD_MaxHoldData( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte GenCount + ) +{ + u4Byte i=0, i_max=0, val_max=0, j; + + if (GenCount== 1) + { + memcpy(pPsdScan->nPSDReport_MaxHold, pPsdScan->nPSDReport, BT_8703B_1ANT_ANTDET_PSD_POINTS*sizeof(u4Byte)); + + for (i= pPsdScan->nPSDStartPoint; i<=pPsdScan->nPSDStopPoint; i++) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i])); + } + + pPsdScan->nPSDMaxValuePoint = 0; + pPsdScan->nPSDMaxValue = 0; + + } + 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]; + } + } + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i])); + + } + + pPsdScan->nPSDMaxValuePoint = i_max; + pPsdScan->nPSDMaxValue = val_max; + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i_Max = %d, PSDReport_Max = %d dB\n", pPsdScan->nPSDMaxValuePoint + // ,pPsdScan->nPSDMaxValue)); + } + + +} + +u4Byte +halbtc8703b1ant_PSD_GetData( + 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 +halbtc8703b1ant_PSD_SweepPoint( +IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN s4Byte 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; + u4Byte WiFi_OriginalChannel = 1; + + pPsdScan->bIsPSDRunning = TRUE; + + do + { + switch(flag) + { + case 0: //Get PSD parameters + default: + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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; + pPsdScan->nRealCentFreq = centFreq; + pPsdScan->nRealOffset = offset; + pPsdScan->nRealSpan = span; + + + 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); + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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); + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), PSD Center Freq = %d\n", (centFreq + offset))); + + nStartP = pPsdScan->nPSDStartBase + (nPSDCenterFreq - span *(1000000)/2) /nDeltaFreqPerPoint; + pPsdScan->nPSDStartPoint = nStartP - pPsdScan->nPSDStartBase; + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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; + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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); + + //store WiFi original channel + WiFi_OriginalChannel = pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff); + + //Set RF channel + if (centFreq == 2484) + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, 0xe); + 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 RF Rx filter corner + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0x3e4); + + //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 = halbtc8703b1ant_PSD_GetData(pBtCoexist,i-nPoints); + } + else + { + psd_report = halbtc8703b1ant_PSD_GetData(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 * halbtc8703b1ant_PSD_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) + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.0%d MHz)", n, freq1, freq2)); + else + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.%d MHz)", n, freq1, freq2)); + + if (PsdRep2 < 10) + RT_TRACE(COMP_COEX, DBG_LOUD, (", PSDReport = %d (%d.0%d dB)\n",psd_report, PsdRep1, PsdRep2)); + else + RT_TRACE(COMP_COEX, DBG_LOUD, (", PSDReport = %d (%d.%d dB)\n",psd_report, PsdRep1,PsdRep2)); +*/ + i++; + + k=0; + + //Add Delay between PSD point + while(1) + { + if (k++ > 20000) + break; + } + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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, 0x1, 0xfffff, 0x780); + + //lock TRx Mask setup + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x0); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x0); + + //Set RF Rx filter corner + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0x0); + + //restore WiFi original channel + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, WiFi_OriginalChannel); + + outloop = TRUE; + break; + + } + + }while (!outloop); + + + + pPsdScan->bIsPSDRunning = FALSE; + + +} + +//============================================================ +// work around function start with wa_halbtc8703b1ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8703b1ant_ +//============================================================ +VOID +EXhalbtc8703b1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u1Byte u1Tmp=0x0; + u2Byte u2Tmp=0x0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx Execute 8703b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n")); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("Ant Det Finish = %s, Ant Det Number = %d\n", + (pBoardInfo->btdmAntDetFinish? "Yes":"No"), pBoardInfo->btdmAntNumByAntDet)); + + pBtCoexist->bStopCoexDm = TRUE; + + // enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. + u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x2); + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x2, u2Tmp|BIT0|BIT1); + + //set Path control owner to WiFi + halbtc8703b1ant_LTECoex_PathControlOwner(pBtCoexist, BT_8703B_1ANT_PCO_WLSIDE); + + // set GNT_BT to high + halbtc8703b1ant_LTECoex_Set_GNT_BT(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_HIGH); + //Set GNT_WL to low + halbtc8703b1ant_LTECoex_Set_GNT_WL(pBtCoexist, BT_8703B_1ANT_GNT_BLOCK_RFC_BB, BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW, BT_8703B_1ANT_SIG_STA_SET_TO_LOW); + + // set WLAN_ACT = 0 + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // + // S0 or S1 setting and Local register setting(By the setting fw can get ant number, S0/S1, ... info) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + + u1Tmp = 0; + pBoardInfo->btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + + if(pBtCoexist->chipInterface == BTC_INTF_USB) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** LTE coex Reg 0x38 (Power-On) = 0x%x**********\n", halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x38))); + + +#if 0 + 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) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } + +#endif +} + +VOID +EXhalbtc8703b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8703b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8703b1ant_InitHwConfig(pBtCoexist, TRUE, bWifiOnly); + pBtCoexist->bStopCoexDm = FALSE; +} + +VOID +EXhalbtc8703b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + pBtCoexist->bStopCoexDm = FALSE; + + halbtc8703b1ant_InitCoexDm(pBtCoexist); + + halbtc8703b1ant_QueryBtInfo(pBtCoexist); +} + +VOID +EXhalbtc8703b1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u2Byte u2Tmp[4]; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + static u1Byte PopReportIn10s = 0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + if(pBtCoexist->bStopCoexDm) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + if (pPsdScan->bAntDet_TryCount == 0) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Ant PG Num/ Mech/ Pos", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos); + CL_PRINTF(cliBuf); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d (%d/%d/%d)", "Ant PG Num/ Mech(Ant_Det)/ Pos", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNumByAntDet, pBoardInfo->btdmAntPos, + pPsdScan->bAntDet_TryCount, pPsdScan->bAntDet_FailCount, pPsdScan->nAntDet_Result); + CL_PRINTF(cliBuf); + + if (pBoardInfo->btdmAntDetFinish) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "Ant Det PSD Value", pPsdScan->nAntDet_PeakVal); + CL_PRINTF(cliBuf); + } + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8703b1Ant, GLCoexVer8703b1Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "WifibHiPri/ Ccklock/ CckEverLock", \ + (pCoexSta->bWiFiIsHighPriTask? "Yes":"No"), + (pCoexSta->bCCKLock? "Yes":"No"), + (pCoexSta->bCCKEverLock? "Yes":"No")); + CL_PRINTF(cliBuf); + + // 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); + + 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_8703B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": + ( (BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + pCoexSta->btRssi, pCoexSta->btRetryCnt, pCoexSta->popEventCnt); + CL_PRINTF(cliBuf); + + if (PopReportIn10s >= 5) + { + pCoexSta->popEventCnt = 0; + PopReportIn10s = 0; + } + + 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) + { + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + else + { + btInfoExt = pCoexSta->btInfoExt; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "BT Role/A2DP rate", \ + (pBtLinkInfo->bSlaveRole )? "Slave":"Master", (btInfoExt&BIT0)? "BR":"EDR"); + CL_PRINTF(cliBuf); + } + + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8703b1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism] (before Manual)============"); + } + else + { + 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[LowPenaltyRA]/RA Mask", \ + pCoexDm->bCurLowPenaltyRa, pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %d ", "NoAggr/ CtrlAggr/ AggrSize", \ + (pBtCoexist->btInfo.bRejectAggPkt? "Yes":"No"), (pBtCoexist->btInfo.bBtCtrlAggBufSize? "Yes":"No"), + pBtCoexist->btInfo.aggBufSize); + CL_PRINTF(cliBuf); + + // Fw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism] (before Manual) ============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + } + + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (%s,%s)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, + (pCoexDm->bCurPsTdmaOn? "On":"Off"), + (pCoexDm->bAutoTdmaAdjust? "Adj":"Fix") ); + + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "WL/BT Coex Table Type", \ + pCoexSta->nCoexTableType); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/0x6cc/IgnWlanAct", \ + u1Tmp[0], u4Tmp[0], pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + + u4Tmp[0] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xa0); + u4Tmp[1] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xa4); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "LTE Coex Table W_L/B_L", \ + u4Tmp[0]&0xffff, u4Tmp[1]&0xffff); + CL_PRINTF(cliBuf); + + u4Tmp[0] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xa8); + u4Tmp[1] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xac); + u4Tmp[2] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xb0); + u4Tmp[3] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0xb4); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "LTE Break Table W_L/B_L/L_W/L_B", \ + u4Tmp[0]&0xffff, u4Tmp[1]&0xffff, u4Tmp[2]&0xffff, u4Tmp[3]&0xffff); + CL_PRINTF(cliBuf); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + u2Tmp[0] = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "0x430/0x434/0x42a/0x456", \ + u4Tmp[0], u4Tmp[1], u2Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + + u4Tmp[0] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x38); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x73); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %s", "LTE CoexOn/Path Ctrl Owner", \ + ((u4Tmp[0]&BIT7)>> 7), ((u1Tmp[0]&BIT2)? "WL":"BT")); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "LTE 3Wire/OPMode/UART/UARTMode", \ + ((u4Tmp[0]&BIT6)>> 6), ((u4Tmp[0]&(BIT5|BIT4))>> 4),((u4Tmp[0]&BIT3)>> 3), (u4Tmp[0]&(BIT2|BIT1|BIT0))); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s", "GNT_WL_SWCtrl/GNT_BT_SWCtrl/Dbg", \ + ((u4Tmp[0]&BIT12)>> 12), ((u4Tmp[0]&BIT14)>> 14), ((u1Tmp[0]&BIT3)? "On":"Off")); + CL_PRINTF(cliBuf); + + u4Tmp[0] = halbtc8703b1ant_LTECoex_InDirectReadReg(pBtCoexist, 0x54); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "GNT_WL/GNT_BT/LTE_Busy/UART_Busy", \ + ((u4Tmp[0]&BIT2)>> 2), ((u4Tmp[0]&BIT3)>> 3), ((u4Tmp[0]&BIT1)>> 1), (u4Tmp[0]&BIT0)); + CL_PRINTF(cliBuf); + + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4c6); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x4c6[4]/0x40[5] (WL/BT PTA)", \ + ((u1Tmp[0] & BIT4)>>4), ((u1Tmp[1] & BIT5)>>5)); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x953); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ %s", "0x550(bcn ctrl)/0x522/4-RxAGC", \ + u4Tmp[0], u1Tmp[0], (u1Tmp[1]&0x2)? "On": "Off"); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcf0); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + + faOfdm = ((u4Tmp[0]&0xffff0000) >> 16) + ((u4Tmp[1]&0xffff0000) >> 16) + (u4Tmp[1] & 0xffff) + (u4Tmp[2] & 0xffff) + \ + ((u4Tmp[3]&0xffff0000) >> 16) + (u4Tmp[3] & 0xffff) ; + faCck = (u1Tmp[0] << 8) + u1Tmp[1]; + + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xc50/OFDM-CCA/OFDM-FA/CCK-FA", \ + u4Tmp[1]&0xff, 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); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); + + halbtc8703b1ant_ReadScoreBoard(pBtCoexist, &u2Tmp[0]); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %04x", "ScoreBoard[14:0] (from BT)", u2Tmp[0]); + CL_PRINTF(cliBuf); + +#if(BT_AUTO_REPORT_ONLY_8703B_1ANT == 1) + //halbtc8703b1ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8703b1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp=0; + + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + + //Write WL "Active" in Score-board for LPS off + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + + halbtc8703b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8703b1ant_InitCoexDm(pBtCoexist); + halbtc8703b1ant_QueryBtInfo(pBtCoexist); + + pCoexSta->bUnderIps = FALSE; + } +} + +VOID +EXhalbtc8703b1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + + if (pCoexSta->bForceLpsOn == TRUE) // LPS No-32K + { + //Write WL "Active" in Score-board for PS-TDMA + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + + } + else // LPS-32K, need check if this h2c 0x71 can work?? (2015/08/28) + { + //Write WL "Non-Active" in Score-board for Native-PS + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + + } + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + + + //Write WL "Active" in Score-board for LPS off + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + + } +} + +VOID +EXhalbtc8703b1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + u1Byte u1Tmpa, u1Tmpb; + u4Byte u4Tmp; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm ) + return; + + if(BTC_SCAN_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } + + if(pBtCoexist->btInfo.bBtDisabled) + return; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + halbtc8703b1ant_QueryBtInfo(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8703b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8703b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8703b1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_SCAN_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8703b1ant_ActionWifiNotConnectedScan(pBtCoexist); + } + else // wifi is connected + { + halbtc8703b1ant_ActionWifiConnectedScan(pBtCoexist); + } + } + else if(BTC_SCAN_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8703b1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8703b1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8703b1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_ASSOCIATE_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + pCoexDm->nArpCnt = 0; + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + //pCoexDm->nArpCnt = 0; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8703b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8703b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8703b1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_ASSOCIATE_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + halbtc8703b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8703b1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8703b1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8703b1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + BOOLEAN bWifiUnderBMode = FALSE; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8703b1ant_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 + if (bWifiUnderBMode) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x00); //CCK Rx + } + else + { + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x10); //CCK Tx + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); //CCK Rx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); //CCK Rx + } + + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + pCoexDm->nArpCnt = 0; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x0); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x0); //CCK Rx + + pCoexSta->bCCKEverLock = FALSE; + } + + halbtc8703b1ant_UpdateWifiChannelInfo(pBtCoexist, type); + +} + +VOID +EXhalbtc8703b1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE, bUnder4way=FALSE; + u1Byte aggBufSize=5; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + + if (BTC_PACKET_ARP == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet ARP notify\n")); + + pCoexDm->nArpCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ARP Packet Count = %d\n", pCoexDm->nArpCnt)); + + if((pCoexDm->nArpCnt >= 10) && (!bUnder4way)) // if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet DHCP or EAPOL notify\n")); + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet [Type = %d] notify\n", type)); + } + + pCoexSta->specialPktPeriodCnt = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8703b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8703b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8703b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8703b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8703b1ant_ActionHs(pBtCoexist); + return; + } + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + ( (BTC_PACKET_ARP == type ) && (pCoexSta->bWiFiIsHighPriTask) ) ) + { + halbtc8703b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + } +} + +VOID +EXhalbtc8703b1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bBtBusy=FALSE; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8703B_1ANT_MAX) + rspSource = BT_INFO_SRC_8703B_1ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + // if 0xff, it means BT is under WHCK test + if (btInfo == 0xff) + pCoexSta->bBtWhckTest = TRUE; + else + pCoexSta->bBtWhckTest = FALSE; + + if(BT_INFO_SRC_8703B_1ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btRetryCnt >= 1) + pCoexSta->popEventCnt++; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtPage = TRUE; + else + pCoexSta->bC2hBtPage = FALSE; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2-90; + //pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if(pCoexSta->btInfoExt & BIT1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + halbtc8703b1ant_UpdateWifiChannelInfo(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + halbtc8703b1ant_UpdateWifiChannelInfo(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if(pCoexSta->btInfoExt & BIT3) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8703b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8703B_1ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8703b1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8703B_1ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + pCoexSta->nNumOfProfile = 0; + + // set link exist status + if(!(btInfo&BT_INFO_8703B_1ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + + pCoexSta->bBtHiPriLinkExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8703B_1ANT_B_FTP) + { + pCoexSta->bPanExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8703B_1ANT_B_A2DP) + { + pCoexSta->bA2dpExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8703B_1ANT_B_HID) + { + pCoexSta->bHidExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8703B_1ANT_B_SCO_ESCO) + { + pCoexSta->bScoExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bScoExist = FALSE; + + if ((pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) &&( pCoexSta->bScoExist == FALSE)) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + { + pCoexSta->bHidExist = TRUE; + pCoexSta->wrongProfileNotification++; + pCoexSta->nNumOfProfile++; + btInfo = btInfo | 0x28; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT HID = true (Hi-Pri > 160)!\n")); + } + } + + //Add Hi-Pri Tx/Rx counter to avoid false detection + if (((pCoexSta->bHidExist) || (pCoexSta->bScoExist)) && (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->bBtHiPriLinkExist = TRUE; + else + pCoexSta->bBtHiPriLinkExist = FALSE; + + if((btInfo&BT_INFO_8703B_1ANT_B_ACL_BUSY) && (pCoexSta->nNumOfProfile == 0)) + { + if (pCoexSta->lowPriorityTx + pCoexSta->lowPriorityRx >= 160) + { + pCoexSta->bPanExist = TRUE; + pCoexSta->nNumOfProfile++; + pCoexSta->wrongProfileNotification++; + btInfo = btInfo | 0x88; + } + } + } + + halbtc8703b1ant_UpdateBtLinkInfo(pBtCoexist); + + btInfo = btInfo & 0x1f; //mask profile bit for connect-ilde identification ( for CSR case: A2DP idle --> 0x41) + + if(!(btInfo&BT_INFO_8703B_1ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8703B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8703B_1ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8703B_1ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8703B_1ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8703B_1ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8703B_1ANT_B_ACL_BUSY) + { + if(BT_8703B_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus) + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->btStatus = BT_8703B_1ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8703B_1ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8703B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + bBtBusy = TRUE; + else + bBtBusy = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + halbtc8703b1ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8703b1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa,u1Tmpb, u1Tmpc; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF Status notify\n")); + + if(BTC_RF_ON == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned ON!!\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + halbtc8703b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + pBtCoexist->bStopCoexDm = FALSE; + } + else if(BTC_RF_OFF == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned OFF!!\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + halbtc8703b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + pBtCoexist->bStopCoexDm = TRUE; + + } +} + +VOID +EXhalbtc8703b1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + + halbtc8703b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8703b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + pBtCoexist->bStopCoexDm = TRUE; +} + +VOID +EXhalbtc8703b1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, FALSE); + + halbtc8703b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8703b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + halbtc8703b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + + pBtCoexist->bStopCoexDm = TRUE; + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + halbtc8703b1ant_PostActiveStateToBT(pBtCoexist, TRUE); + + pBtCoexist->bStopCoexDm = FALSE; + halbtc8703b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8703b1ant_InitCoexDm(pBtCoexist); + halbtc8703b1ant_QueryBtInfo(pBtCoexist); + } +} + + +VOID +EXhalbtc8703b1ant_ScoreBoardStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + // + + +} + +VOID +EXhalbtc8703b1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], *****************Coex DM Reset*****************\n")); + + halbtc8703b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x2, 0xfffff, 0x0); + halbtc8703b1ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8703b1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8703b1Ant, GLCoexVer8703b1Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8703B_1ANT == 0) + halbtc8703b1ant_QueryBtInfo(pBtCoexist); + halbtc8703b1ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8703b1ant_MonitorBtCtr(pBtCoexist); + halbtc8703b1ant_MonitorWiFiCtr(pBtCoexist); +#if BT_8703B_1ANT_ANTDET_ENABLE + halbtc8703b1ant_MonitorBtEnableDisable(pBtCoexist); +#endif + + if( halbtc8703b1ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust ) + { + + halbtc8703b1ant_RunCoexistMechanism(pBtCoexist); + } + + pCoexSta->specialPktPeriodCnt++; + +#endif +} + +VOID +EXhalbtc8703b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + //No Antenna Detection required because 8730b is only 1-Ant +} + +VOID +EXhalbtc8703b1ant_AntennaIsolation( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + + +} + +VOID +EXhalbtc8703b1ant_PSDScan( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ) +{ + + +} + +VOID +EXhalbtc8703b1ant_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ) +{ + +} + +#endif + +#else // #if (RTL8723B_SUPPORT == 1) +VOID +EXhalbtc8703b1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ){} +VOID +EXhalbtc8703b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ){} +VOID +EXhalbtc8703b1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8703b1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ){} +VOID +EXhalbtc8703b1ant_ScoreBoardStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ){} +VOID +EXhalbtc8703b1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8703b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ){} +VOID +EXhalbtc8703b1ant_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ){} + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.h new file mode 100644 index 00000000..89484610 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b1Ant.h @@ -0,0 +1,386 @@ +//=========================================== +// The following is for 8703B 1ANT BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8703B_1ANT 1 + +#define BT_INFO_8703B_1ANT_B_FTP BIT7 +#define BT_INFO_8703B_1ANT_B_A2DP BIT6 +#define BT_INFO_8703B_1ANT_B_HID BIT5 +#define BT_INFO_8703B_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8703B_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8703B_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8703B_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8703B_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8703B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8703B_1ANT 2 + +#define BT_8703B_1ANT_WIFI_NOISY_THRESH 30 //max: 255 + +//for Antenna detection +#define BT_8703B_1ANT_ANTDET_PSDTHRES_BACKGROUND 50 +#define BT_8703B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION 70 +#define BT_8703B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION 55 +#define BT_8703B_1ANT_ANTDET_PSDTHRES_1ANT 35 +#define BT_8703B_1ANT_ANTDET_RETRY_INTERVAL 10 //retry timer if ant det is fail, unit: second +#define BT_8703B_1ANT_ANTDET_ENABLE 0 +#define BT_8703B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE 0 + +#define BT_8703B_1ANT_LTECOEX_INDIRECTREG_ACCESS_TIMEOUT 30000 + +typedef enum _BT_8703B_1ANT_SIGNAL_STATE{ + BT_8703B_1ANT_SIG_STA_SET_TO_LOW = 0x0, + BT_8703B_1ANT_SIG_STA_SET_BY_HW = 0x0, + BT_8703B_1ANT_SIG_STA_SET_TO_HIGH = 0x1, + BT_8703B_1ANT_SIG_STA_MAX +}BT_8703B_1ANT_SIGNAL_STATE,*PBT_8703B_1ANT_SIGNAL_STATE; + +typedef enum _BT_8703B_1ANT_PATH_CTRL_OWNER{ + BT_8703B_1ANT_PCO_BTSIDE = 0x0, + BT_8703B_1ANT_PCO_WLSIDE = 0x1, + BT_8703B_1ANT_PCO_MAX +}BT_8703B_1ANT_PATH_CTRL_OWNER,*PBT_8703B_1ANT_PATH_CTRL_OWNER; + +typedef enum _BT_8703B_1ANT_GNT_CTRL_TYPE{ + BT_8703B_1ANT_GNT_TYPE_CTRL_BY_PTA = 0x0, + BT_8703B_1ANT_GNT_TYPE_CTRL_BY_SW = 0x1, + BT_8703B_1ANT_GNT_TYPE_MAX +}BT_8703B_1ANT_GNT_CTRL_TYPE,*PBT_8703B_1ANT_GNT_CTRL_TYPE; + +typedef enum _BT_8703B_1ANT_GNT_CTRL_BLOCK{ + BT_8703B_1ANT_GNT_BLOCK_RFC_BB = 0x0, + BT_8703B_1ANT_GNT_BLOCK_RFC = 0x1, + BT_8703B_1ANT_GNT_BLOCK_BB = 0x2, + BT_8703B_1ANT_GNT_BLOCK_MAX +}BT_8703B_1ANT_GNT_CTRL_BLOCK,*PBT_8703B_1ANT_GNT_CTRL_BLOCK; + +typedef enum _BT_8703B_1ANT_LTE_COEX_TABLE_TYPE{ + BT_8703B_1ANT_CTT_WL_VS_LTE = 0x0, + BT_8703B_1ANT_CTT_BT_VS_LTE = 0x1, + BT_8703B_1ANT_CTT_MAX +}BT_8703B_1ANT_LTE_COEX_TABLE_TYPE,*PBT_8703B_1ANT_LTE_COEX_TABLE_TYPE; + +typedef enum _BT_8703B_1ANT_LTE_BREAK_TABLE_TYPE{ + BT_8703B_1ANT_LBTT_WL_BREAK_LTE = 0x0, + BT_8703B_1ANT_LBTT_BT_BREAK_LTE = 0x1, + BT_8703B_1ANT_LBTT_LTE_BREAK_WL = 0x2, + BT_8703B_1ANT_LBTT_LTE_BREAK_BT = 0x3, + BT_8703B_1ANT_LBTT_MAX +}BT_8703B_1ANT_LTE_BREAK_TABLE_TYPE,*PBT_8703B_1ANT_LTE_BREAK_TABLE_TYPE; + +typedef enum _BT_INFO_SRC_8703B_1ANT{ + BT_INFO_SRC_8703B_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8703B_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8703B_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8703B_1ANT_MAX +}BT_INFO_SRC_8703B_1ANT,*PBT_INFO_SRC_8703B_1ANT; + +typedef enum _BT_8703B_1ANT_BT_STATUS{ + BT_8703B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8703B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8703B_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8703B_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8703B_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8703B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8703B_1ANT_BT_STATUS_MAX +}BT_8703B_1ANT_BT_STATUS,*PBT_8703B_1ANT_BT_STATUS; + +typedef enum _BT_8703B_1ANT_WIFI_STATUS{ + BT_8703B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8703B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8703B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8703B_1ANT_WIFI_STATUS_MAX +}BT_8703B_1ANT_WIFI_STATUS,*PBT_8703B_1ANT_WIFI_STATUS; + +typedef enum _BT_8703B_1ANT_COEX_ALGO{ + BT_8703B_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8703B_1ANT_COEX_ALGO_SCO = 0x1, + BT_8703B_1ANT_COEX_ALGO_HID = 0x2, + BT_8703B_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8703B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8703B_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8703B_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8703B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8703B_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8703B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8703B_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8703B_1ANT_COEX_ALGO_MAX = 0xb, +}BT_8703B_1ANT_COEX_ALGO,*PBT_8703B_1ANT_COEX_ALGO; + +typedef struct _COEX_DM_8703B_1ANT{ + // hw setting + u1Byte preAntPosType; + u1Byte curAntPosType; + // fw mechanism + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; + u4Byte nArpCnt; + + u1Byte errorCondition; +} COEX_DM_8703B_1ANT, *PCOEX_DM_8703B_1ANT; + +typedef struct _COEX_STA_8703B_1ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + BOOLEAN bBtHiPriLinkExist; + u1Byte nNumOfProfile; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte specialPktPeriodCnt; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + s1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8703B_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8703B_1ANT_MAX]; + BOOLEAN bBtWhckTest; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtPage; //Add for win8.1 page out issue + BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue + u1Byte btRetryCnt; + u1Byte btInfoExt; + u4Byte popEventCnt; + u1Byte nScanAPNum; + + u4Byte nCRCOK_CCK; + u4Byte nCRCOK_11g; + u4Byte nCRCOK_11n; + u4Byte nCRCOK_11nAgg; + + u4Byte nCRCErr_CCK; + u4Byte nCRCErr_11g; + u4Byte nCRCErr_11n; + u4Byte nCRCErr_11nAgg; + + BOOLEAN bCCKLock; + BOOLEAN bPreCCKLock; + BOOLEAN bCCKEverLock; + u1Byte nCoexTableType; + + BOOLEAN bForceLpsOn; + u4Byte wrongProfileNotification; + + BOOLEAN bConCurrentRxModeOn; + + u2Byte nScoreBoard; +}COEX_STA_8703B_1ANT, *PCOEX_STA_8703B_1ANT; + +#define BT_8703B_1ANT_ANTDET_PSD_POINTS 256 //MAX:1024 +#define BT_8703B_1ANT_ANTDET_PSD_AVGNUM 1 //MAX:3 +#define BT_8703B_1ANT_ANTDET_BUF_LEN 16 + +typedef struct _PSDSCAN_STA_8703B_1ANT{ + +u4Byte nAntDet_BTLEChannel; //BT LE Channel ex:2412 +u4Byte nAntDet_BTTxTime; +u4Byte nAntDet_PrePSDScanPeakVal; +BOOLEAN nAntDet_IsAntDetAvailable; +u4Byte nAntDet_PSDScanPeakVal; +BOOLEAN nAntDet_IsBTReplyAvailable; +u4Byte nAntDet_PSDScanPeakFreq; + +u1Byte nAntDet_Result; +u1Byte nAntDet_PeakVal[BT_8703B_1ANT_ANTDET_BUF_LEN]; +u1Byte nAntDet_PeakFreq[BT_8703B_1ANT_ANTDET_BUF_LEN]; +u4Byte bAntDet_TryCount; +u4Byte bAntDet_FailCount; +u4Byte nAntDet_IntevalCount; +u4Byte nAntDet_ThresOffset; + +u4Byte nRealCentFreq; +s4Byte nRealOffset; +u4Byte nRealSpan; + +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; +BOOLEAN bIsPSDRunning; +BOOLEAN bIsPSDShowMaxOnly; +} PSDSCAN_STA_8703B_1ANT, *PPSDSCAN_STA_8703B_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8703b1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8703b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8703b1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8703b1ant_ScoreBoardStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8703b1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b1ant_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); +VOID +EXhalbtc8703b1ant_AntennaIsolation( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); + +VOID +EXhalbtc8703b1ant_PSDScan( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN u4Byte offset, + IN u4Byte span, + IN u4Byte seconds + ); +VOID +EXhalbtc8703b1ant_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.c new file mode 100644 index 00000000..d5c5c477 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.c @@ -0,0 +1,4864 @@ +//============================================================ +// Description: +// +// This file is for RTL8703B Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8703b2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8703B_2ANT GLCoexDm8703b2Ant; +static PCOEX_DM_8703B_2ANT pCoexDm=&GLCoexDm8703b2Ant; +static COEX_STA_8703B_2ANT GLCoexSta8703b2Ant; +static PCOEX_STA_8703B_2ANT pCoexSta=&GLCoexSta8703b2Ant; + +const char *const GLBtInfoSrc8703b2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8703b2Ant=20140903; +u4Byte GLCoexVer8703b2Ant=0x43; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8703b2ant_ +//============================================================ +u1Byte +halbtc8703b2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8703b2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8703b2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + } + } +} + +VOID +halbtc8703b2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +VOID +halbtc8703b2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if ( (pCoexSta->lowPriorityRx >= 950) && (pCoexSta->lowPriorityRx >= pCoexSta->lowPriorityTx) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8703b2ant_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 +halbtc8703b2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +BOOLEAN +halbtc8703b2ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist,3, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + + if ( (BTC_RSSI_STATE_HIGH ==wifiRssiState ) || (BTC_RSSI_STATE_LOW ==wifiRssiState )) + { + return TRUE; + } + + } + + return FALSE; +} + +VOID +halbtc8703b2ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + +#if(BT_AUTO_REPORT_ONLY_8703B_2ANT == 1) // profile from bt patch + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } +#else // profile from bt stack + pBtLinkInfo->bBtLinkExist = pStackInfo->bBtLinkExist; + pBtLinkInfo->bScoExist = pStackInfo->bScoExist; + pBtLinkInfo->bA2dpExist = pStackInfo->bA2dpExist; + pBtLinkInfo->bPanExist = pStackInfo->bPanExist; + pBtLinkInfo->bHidExist = pStackInfo->bHidExist; + + //for win-8 stack HID report error + if(!pStackInfo->bHidExist) + pStackInfo->bHidExist = pCoexSta->bHidExist; //sync BTInfo with BT firmware and stack + // when stack HID report error, here we use the info from bt fw. + if(!pStackInfo->bBtLinkExist) + pStackInfo->bBtLinkExist = pCoexSta->bBtLinkExist; +#endif + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8703b2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8703B_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { +#if 0 + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else +#endif + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8703B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8703b2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8703b2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte decBtPwrLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = decBtPwrLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power level = %d, FW write 0x62=0x%x\n", + decBtPwrLvl, H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, H2C_Parameter); +} + +VOID +halbtc8703b2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte decBtPwrLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power level = %d\n", + (bForceExec? "force to":""), decBtPwrLvl)); + pCoexDm->curBtDecPwrLvl = decBtPwrLvl; + + if(!bForceExec) + { + if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl) + return; + } + halbtc8703b2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl); + + pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl; +} + +VOID +halbtc8703b2ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8703b2ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8703b2ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8703b2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8703b2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8703b2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8703b2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8703b2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8703b2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!")) ); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8703b2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + //return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8703b2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8703b2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x883, 0x3e, val); +} + +VOID +halbtc8703b2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8703b2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8703b2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8703b2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8703b2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8703b2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x1); + } +} + +VOID +halbtc8703b2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8703b2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8703b2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + //=================BB AGC Gain Table + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6e1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6d1B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6c1C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6b1D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6a1E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x691F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x68200001); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xaa1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa91B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa81C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa71D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa61E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa51F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa4200001); + } + + + //=================RF Gain + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + if(bAgcTableEn) + { + rssiAdjustVal = 8; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + +VOID +halbtc8703b2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8703b2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8703b2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8703b2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8703b2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8703b2ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5afa5afa, 0xffffff, 0x3); + break; + case 2: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x5ada5ada, 0x5ada5ada, 0xffffff, 0x3); + break; + case 3: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffffff, 0x3); + break; + case 5: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffffff, 0x3); + break; + case 6: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 8: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + halbtc8703b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8703b2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8703b2ant_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 +halbtc8703b2ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8703b2ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8703b2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8703b2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8703b2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + 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; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = byte5; + + pCoexDm->psTdmaPara[0] = byte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = byte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + +VOID +halbtc8703b2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + /* + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + */ + + //halbtc8703b2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + halbtc8703b2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8703b2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + //halbtc8703b2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + //halbtc8703b2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + //halbtc8703b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8703b2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte fwVer=0, u4Tmp=0; + BOOLEAN bPgExtSwitch=FALSE; + BOOLEAN bUseExtSwitch=FALSE; + u1Byte H2C_Parameter[2] ={0}; + + 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 + + if((fwVer>0 && fwVer<0xc0000) || bPgExtSwitch) + bUseExtSwitch = TRUE; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x39, 0x8, 0x1); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x974, 0xff); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x944, 0x3, 0x3); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x930, 0x77); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); + + if(fwVer >= 0x180000) + { + /* 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, 0x18); + } + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); //WiFi 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) + { + //tell firmware "no antenna inverse" + H2C_Parameter[0] = 0; + } + else + { + //tell firmware "antenna inverse" + H2C_Parameter[0] = 1; + } + + if (bUseExtSwitch) + { + //ext switch type + H2C_Parameter[1] = 1; + } + else + { + //int switch type + H2C_Parameter[1] = 0; + } + 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) + { + if (bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); // fixed internal switch S1->WiFi, S0->BT + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); // ext switch main at wifi + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); // ext switch aux at wifi + break; + } + } + else // internal switch + { + if (bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp |= BIT23; + u4Tmp &=~BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x0); //fixed external switch S1->Main, S0->Aux + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); // fixed internal switch S1->WiFi, S0->BT + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); // fixed internal switch S0->WiFi, S1->BT + break; + } + } +} + +VOID +halbtc8703b2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + u1Byte wifiRssiState1, btRssiState; + + + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if (!(BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) && bTurnOn) + { + type = type +100; //for WiFi RSSI low or BT RSSI low + pCoexDm->bIsSwitchTo1dot5Ant = TRUE; + } + else + { + pCoexDm->bIsSwitchTo1dot5Ant = FALSE; + } + + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(bTurnOn) + { + switch(type) + { + case 1: + default: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 2: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); + break; + case 3: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); + break; + case 4: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x03, 0xf1, 0x90); + break; + case 5: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); + break; + case 6: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); + break; + case 7: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); + break; + case 8: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x10, 0x3, 0x70, 0x90); + break; + case 9: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 10: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); + break; + case 11: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); + break; + case 12: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0xf1, 0x90); + break; + case 13: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); + break; + case 14: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); + break; + case 15: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); + break; + case 16: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x90); + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0x70, 0x90); + break; + case 17: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x90); + break; + case 18: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 71: + //halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 171: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x3a, 0x03, 0x70, 0x50); + break; + case 102: + case 106: + case 110: + case 114: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x2d, 0x03, 0x70, 0x50); + break; + case 103: + case 107: + case 111: + case 115: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1c, 0x03, 0x70, 0x50); + break; + case 104: + case 108: + case 112: + case 116: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x10, 0x03, 0x70, 0x50); + break; + case 109: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 113: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x70, 0x90); + break; + case 121: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 22: + case 122: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x35, 0x03, 0x71, 0x11); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 0: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + case 1: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + break; + default: + halbtc8703b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8703b2ant_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 + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8703b2ant_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: + halbtc8703b2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8703b2ant_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: + halbtc8703b2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + + +VOID +halbtc8703b2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8703b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8703b2ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bLowPwrDisable=TRUE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_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); + + 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); + + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if(bScan || bLink || bRoam) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi link process + BT Inq/Page!!\n")); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT Inq/Page!!\n")); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi no-link + BT Inq/Page!!\n")); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +/* + pCoexDm->bNeedRecover0x948 = TRUE; + pCoexDm->backup0x948 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + + halbtc8703b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_AUX, FALSE, FALSE); +*/ +} + + +VOID +halbtc8703b2ant_ActionWiFiLinkProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa, u1Tmpb; + + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); +} + +BOOLEAN +halbtc8703b2ant_ActionWifiIdleProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + //wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES-20, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_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)) + { + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle process for BT HID+A2DP exist!!\n")); + + halbtc8703b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + return TRUE; + } + else + { + halbtc8703b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + return FALSE; + } + + +} + + + +BOOLEAN +halbtc8703b2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte btRssiState=BTC_RSSI_STATE_HIGH; + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + BOOLEAN bBtHsOn=FALSE, bLowPwrDisable=FALSE; + BOOLEAN bAsus8703b=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-connected idle!!\n")); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(BT_8703B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else if(BT_8703B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bBtHsOn) + return FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); +#if 0 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_IS_ASUS_8703B, &bAsus8703b); + if(!bAsus8703b) + bCommon = FALSE; + else + bCommon = halbtc8703b2ant_ActionWifiIdleProcess(pBtCoexist); +#else + bCommon = FALSE; +#endif + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + //bCommon = FALSE; + bCommon = halbtc8703b2ant_ActionWifiIdleProcess(pBtCoexist); + } + } + } + + return bCommon; +} +VOID +halbtc8703b2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 71) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 71) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +// SCO only or SCO+PAN(HS) +VOID +halbtc8703b2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 4); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for SCO quality at 11b/g mode + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + else //for SCO quality & wifi performance balance at 11n mode + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x4); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x4); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x4); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x4); + } + } +} + + +VOID +halbtc8703b2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 9); + } + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8703b2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_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) && BTC_RSSI_HIGH(btRssiState)) + { + //DbgPrint(" AP#>10(%d)\n", apNum); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + return; + + } + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + else + { + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8703b2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8703b2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 10); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + else + { + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + + +//PAN(HS) only +VOID +halbtc8703b2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8703b2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8703b2ant_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) ) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 12); + + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + else + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8703b2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8703b2ant_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) + { + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 3); + //halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + } + else + { + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + } + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + } + else + { + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8703b2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(2, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8703b2ant_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) ) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + else + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else + { + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8703b2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8703b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + //btRssiState = halbtc8703b2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8703b2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8703b2ant_BtRssiState(3, BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES, 37); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8703b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x5); + + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + else + { // only 802.11N mode we have to dec bt power to 4 degree + if(BTC_RSSI_HIGH(btRssiState)) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + // need to check ap Number of Not + if(apNum < 10) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + } + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else + { + halbtc8703b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8703b2ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8703b2ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8703b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8703b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8703b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8703b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8703b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8703b2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8703b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); +} + +VOID +halbtc8703b2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if(pCoexSta->bBtWhckTest) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under WHCK TEST!!!\n")); + halbtc8703b2ant_ActionBtWhckTest(pBtCoexist); + return; + } + + algorithm = halbtc8703b2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bC2hBtInquiryPage && (BT_8703B_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8703b2ant_ActionBtInquiry(pBtCoexist); + return; + } + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], WiFi is under Link Process !!\n")); + halbtc8703b2ant_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)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [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); + halbtc8703b2ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8703b2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8703B_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8703b2ant_ActionSco(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8703b2ant_ActionHid(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8703b2ant_ActionA2dp(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8703b2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8703b2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8703b2ant_ActionPanHs(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8703b2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8703b2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8703b2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8703B_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8703b2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8703b2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8703b2ant_WifiOffHwCfg( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bIsInMpMode = FALSE; + u1Byte H2C_Parameter[2] ={0}; + u4Byte fwVer=0; + + // set wlan_act to low + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); //WiFi goto standby while GNT_BT 0-->1 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + if(fwVer >= 0x180000) + { + /* Use H2C to set GNT_BT to HIGH */ + H2C_Parameter[0] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, &bIsInMpMode); + if(!bIsInMpMode) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x0); //BT select s0/s1 is controlled by BT + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi +} + +VOID +halbtc8703b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0, fwVer; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + //Antenna config + halbtc8703b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, TRUE, FALSE); + pCoexSta->disVerInfoCnt = 0; + + // PTA parameter + halbtc8703b2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + // Enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); +} + +//============================================================ +// work around function start with wa_halbtc8703b2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8703b2ant_ +//============================================================ +VOID +EXhalbtc8703b2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u2Byte u2Tmp=0x0; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20); + + // enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. + u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x2); + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x2, u2Tmp|BIT0|BIT1); + + 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 +EXhalbtc8703b2ant_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) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + if(pBtCoexist->chipInterface == BTC_INTF_USB) + { + // fixed at S0 for USB interface + u1Tmp |= 0x1; // antenna inverse + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp); + } + else + { + // for PCIE and SDIO interface, we check efuse 0xc3[6] + if(pBoardInfo->singleAntPath == 0) + { + } + else if(pBoardInfo->singleAntPath == 1) + { + // set to S0 + u1Tmp |= 0x1; // antenna inverse + } + + if(pBtCoexist->chipInterface == BTC_INTF_PCI) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } +} + +VOID +EXhalbtc8703b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8703b2ant_InitHwConfig(pBtCoexist, TRUE); +} + +VOID +EXhalbtc8703b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8703b2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8703b2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8703b2Ant, GLCoexVer8703b2Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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/ %ddBm/ %d] ", "BT [status/ rssi/ retryCnt]", \ + ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8703B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": + ( (BT_8703B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + 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", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8703b2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + // Sw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism] (before Manual)============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism] (before Manual) ============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + } + + psTdmaCase = pCoexDm->curPsTdma; + + if (pCoexDm->bIsSwitchTo1dot5Ant) + psTdmaCase = psTdmaCase + 100; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (%s,%s)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, + (pCoexDm->bCurPsTdmaOn? "On":"Off"), + (pCoexDm->bAutoTdmaAdjust? "Adj":"Fix") ); + 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); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x778/0x880[29:25]", \ + u1Tmp[0], (u4Tmp[0]&0x3e000000) >> 25); + CL_PRINTF(cliBuf); + + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x948/ 0x67[5] / 0x765", \ + u4Tmp[0], ((u1Tmp[0]&0x20)>> 5), u1Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x92c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x930); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x944); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", \ + u4Tmp[0]&0x3, u4Tmp[1]&0xff, u4Tmp[2]&0x3); + CL_PRINTF(cliBuf); + + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x39); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u1Tmp[2] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x64); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x38[11]/0x40/0x4c[24:23]/0x64[0]", \ + ((u1Tmp[0] & 0x8)>>3), u1Tmp[1], ((u4Tmp[0]&0x01800000)>>23), u1Tmp[2]&0x1); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(dig)/0x49c(null-drop)", \ + u4Tmp[0]&0xff, u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcf0); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + + faOfdm = ((u4Tmp[0]&0xffff0000) >> 16) + ((u4Tmp[1]&0xffff0000) >> 16) + (u4Tmp[1] & 0xffff) + (u4Tmp[2] & 0xffff) + \ + ((u4Tmp[3]&0xffff0000) >> 16) + (u4Tmp[3] & 0xffff) ; + faCck = (u1Tmp[0] << 8) + u1Tmp[1]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "OFDM-CCA/OFDM-FA/CCK-FA", \ + 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); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8703B_2ANT == 1) + //halbtc8703b2ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8703b2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8703b2ant_WifiOffHwCfg(pBtCoexist); + halbtc8703b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + halbtc8703b2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + halbtc8703b2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8703b2ant_InitCoexDm(pBtCoexist); + halbtc8703b2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8703b2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8703b2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); +} + +VOID +EXhalbtc8703b2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8703b2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + u1Byte apNum=0; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + if(apNum < 10) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8703b2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8703b2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE; + static BOOLEAN bPreScoExist=FALSE; + u4Byte raMask=0x0; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8703B_2ANT_MAX) + rspSource = BT_INFO_SRC_8703B_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n")); + return; + } + + // if 0xff, it means BT is under WHCK test + if (btInfo == 0xff) + pCoexSta->bBtWhckTest = TRUE; + else + pCoexSta->bBtWhckTest = FALSE; + + if(BT_INFO_SRC_8703B_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if (pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x01 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x01\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x01); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8703b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8703b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if( (pCoexSta->btInfoExt & BIT3) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8703b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8703B_2ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8703b2ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8703B_2ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8703B_2ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8703B_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8703B_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8703B_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8703B_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + + if ( (pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) && (pCoexSta->bScoExist == FALSE)) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + { + pCoexSta->bHidExist = TRUE; + btInfo = btInfo | 0x20; + } + } + } + + halbtc8703b2ant_UpdateBtLinkInfo(pBtCoexist); + + if(!(btInfo&BT_INFO_8703B_2ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8703B_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8703B_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8703B_2ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8703B_2ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8703B_2ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8703B_2ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8703B_2ANT_B_ACL_BUSY) + { + pCoexDm->btStatus = BT_8703B_2ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8703B_2ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8703B_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8703B_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8703B_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bBtBusy = TRUE; + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8703b2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8703b2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8703b2ant_WifiOffHwCfg(pBtCoexist); + //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 + halbtc8703b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8703b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8703b2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + halbtc8703b2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8703b2ant_InitCoexDm(pBtCoexist); + halbtc8703b2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8703b2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + //static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(pCoexSta->disVerInfoCnt <= 5) + { + pCoexSta->disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8703b2Ant, GLCoexVer8703b2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + + if (pCoexSta->disVerInfoCnt == 3) + { + //Antenna config to set 0x765 = 0x0 (GNT_BT control by PTA) after initial + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set GNT_BT control by PTA\n")); + halbtc8703b2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, FALSE, FALSE); + } + } + +#if(BT_AUTO_REPORT_ONLY_8703B_2ANT == 0) + halbtc8703b2ant_QueryBtInfo(pBtCoexist); + halbtc8703b2ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8703b2ant_MonitorBtCtr(pBtCoexist); + halbtc8703b2ant_MonitorWiFiCtr(pBtCoexist); + + if( halbtc8703b2ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust) + { + halbtc8703b2ant_RunCoexistMechanism(pBtCoexist); + } +#endif +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.h new file mode 100644 index 00000000..361c4436 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8703b2Ant.h @@ -0,0 +1,228 @@ +//=========================================== +// The following is for 8703B 2Ant BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8703B_2ANT 1 + + +#define BT_INFO_8703B_2ANT_B_FTP BIT7 +#define BT_INFO_8703B_2ANT_B_A2DP BIT6 +#define BT_INFO_8703B_2ANT_B_HID BIT5 +#define BT_INFO_8703B_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8703B_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8703B_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8703B_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8703B_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8703B_2ANT 2 + + +#define BT_8703B_2ANT_WIFI_RSSI_COEXSWITCH_THRES 42 //WiFi RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation +#define BT_8703B_2ANT_BT_RSSI_COEXSWITCH_THRES 46 //BT RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation + +typedef enum _BT_INFO_SRC_8703B_2ANT{ + BT_INFO_SRC_8703B_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8703B_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8703B_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8703B_2ANT_MAX +}BT_INFO_SRC_8703B_2ANT,*PBT_INFO_SRC_8703B_2ANT; + +typedef enum _BT_8703B_2ANT_BT_STATUS{ + BT_8703B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8703B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8703B_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8703B_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8703B_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8703B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8703B_2ANT_BT_STATUS_MAX +}BT_8703B_2ANT_BT_STATUS,*PBT_8703B_2ANT_BT_STATUS; + +typedef enum _BT_8703B_2ANT_COEX_ALGO{ + BT_8703B_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8703B_2ANT_COEX_ALGO_SCO = 0x1, + BT_8703B_2ANT_COEX_ALGO_HID = 0x2, + BT_8703B_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8703B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8703B_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8703B_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8703B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8703B_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8703B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8703B_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8703B_2ANT_COEX_ALGO_MAX = 0xb, +}BT_8703B_2ANT_COEX_ALGO,*PBT_8703B_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8703B_2ANT{ + // fw mechanism + u1Byte preBtDecPwrLvl; + u1Byte curBtDecPwrLvl; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + BOOLEAN bNeedRecover0x948; + u4Byte backup0x948; + + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + BOOLEAN bIsSwitchTo1dot5Ant; +} COEX_DM_8703B_2ANT, *PCOEX_DM_8703B_2ANT; + +typedef struct _COEX_STA_8703B_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8703B_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8703B_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_8703B_2ANT, *PCOEX_STA_8703B_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8703b2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8703b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8703b2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8703b2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8703b2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8703b2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.c new file mode 100644 index 00000000..db5b42e4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.c @@ -0,0 +1,1544 @@ +//============================================================ +// Description: +// +// This file is for RTL8723A Co-exist mechanism +// +// History +// 2012/08/22 Cosa first check in. +// 2012/11/14 Cosa Revise for 8723A 1Ant out sourcing. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8723a1Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8723A_1ANT GLCoexDm8723a1Ant; +static PCOEX_DM_8723A_1ANT pCoexDm=&GLCoexDm8723a1Ant; +static COEX_STA_8723A_1ANT GLCoexSta8723a1Ant; +static PCOEX_STA_8723A_1ANT pCoexSta=&GLCoexSta8723a1Ant; + +const char *const GLBtInfoSrc8723a1Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8723a1ant_ +//============================================================ +VOID +halbtc8723a1ant_Reg0x550Bit3( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSet + ) +{ + u1Byte u1tmp=0; + + u1tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x550); + if(bSet) + { + u1tmp |= BIT3; + } + else + { + u1tmp &= ~BIT3; + } + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x550, u1tmp); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], set 0x550[3]=%d\n", (bSet? 1:0))); +} + +VOID +halbtc8723a1ant_NotifyFwScan( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte scanType + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(BTC_SCAN_START == scanType) + H2C_Parameter[0] = 0x1; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Notify FW for wifi scan, write 0x3b=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x3b, 1, H2C_Parameter); +} + +VOID +halbtc8723a1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x38=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x38, 1, H2C_Parameter); +} + +VOID +halbtc8723a1ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8723a1ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8723a1ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8723a1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + tmpU1 |= BIT0; + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8723a1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8723a1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8723a1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8723a1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8723a1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8723a1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x25=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x25, 1, H2C_Parameter); +} + +VOID +halbtc8723a1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8723a1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8723a1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + // byte1[1:0] != 0 means enable pstdma + // for 2Ant bt coexist, if byte1 != 0 means enable pstdma + if(byte1) + { + if(bApEnable) + { + if(type != 5 && type != 12) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + } + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x3a(5bytes)=0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x3a, 5, H2C_Parameter); +} + +VOID +halbtc8723a1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(pCoexDm->bCurPsTdmaOn) + { + switch(pCoexDm->curPsTdma) + { + case 1: + default: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x1a, 0x1a, 0x0, 0x40); + break; + case 2: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x12, 0x12, 0x0, 0x40); + break; + case 3: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x3f, 0x3, 0x10, 0x40); + break; + case 4: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x15, 0x3, 0x10, 0x0); + break; + case 5: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0xa9, 0x15, 0x3, 0x35, 0xc0); + break; + + case 8: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 9: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 10: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x0, 0x40); + break; + case 12: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0xa9, 0xa, 0x3, 0x15, 0xc0); + break; + + case 18: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + + case 20: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x2a, 0x2a, 0x0, 0x0); + break; + case 21: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x20, 0x3, 0x10, 0x40); + break; + case 22: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x1a, 0x1a, 0x2, 0x40); + break; + case 23: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x12, 0x12, 0x2, 0x40); + break; + case 24: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x2, 0x40); + break; + case 25: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x2, 0x40); + break; + case 26: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 27: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x2, 0x40); + break; + case 28: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x3, 0x2f, 0x2f, 0x0, 0x0); + break; + + } + } + else + { + // disable PS tdma + switch(pCoexDm->curPsTdma) + { + case 8: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x8, 0x0, 0x0, 0x0, 0x0); + break; + case 0: + default: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x0, 0x0, 0x0, 0x0, 0x0); + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x860, 0x210); + break; + case 9: + halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x0, 0x0, 0x0, 0x0, 0x0); + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x860, 0x110); + break; + + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + + +VOID +halbtc8723a1ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // sw all off + halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + + // hw all off + halbtc8723a1ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); +} + +VOID +halbtc8723a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); +} + +VOID +halbtc8723a1ant_BtEnableAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); +} + +VOID +halbtc8723a1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8723a1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + halbtc8723a1ant_BtEnableAction(pBtCoexist); + } + else + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +VOID +halbtc8723a1ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + u1Byte btState; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + btState = pCoexDm->btStatus; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], TdmaDurationAdjust()\n")); + if(pCoexDm->psTdmaGlobalCnt != pCoexDm->psTdmaMonitorCnt) + { + pCoexDm->psTdmaMonitorCnt = 0; + pCoexDm->psTdmaGlobalCnt = 0; + } + if(pCoexDm->psTdmaMonitorCnt == 0) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], first run BT A2DP + WiFi busy state!!\n")); + if(btState == BT_STATE_8723A_1ANT_ACL_ONLY_BUSY) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + pCoexDm->psTdmaDuAdjType = 22; + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], retryCount = %d\n", retryCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT TxRx counter H+L <= 1200\n")); + if(btState != BT_STATE_8723A_1ANT_ACL_ONLY_BUSY) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], NOT ACL only busy!\n")); + if(BTC_WIFI_BW_HT40 != wifiBw) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 20MHz\n")); + if(result == -1) + { + if(pCoexDm->curPsTdma == 22) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + pCoexDm->psTdmaDuAdjType = 23; + } + else if(pCoexDm->curPsTdma == 23) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + pCoexDm->psTdmaDuAdjType = 24; + } + else if(pCoexDm->curPsTdma == 24) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 25); + pCoexDm->psTdmaDuAdjType = 25; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 25) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + pCoexDm->psTdmaDuAdjType = 24; + } + else if(pCoexDm->curPsTdma == 24) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + pCoexDm->psTdmaDuAdjType = 23; + } + else if(pCoexDm->curPsTdma == 23) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + pCoexDm->psTdmaDuAdjType = 22; + } + } + // error handle, if not in the following state, + // set psTdma again. + if( (pCoexDm->psTdmaDuAdjType != 22) && + (pCoexDm->psTdmaDuAdjType != 23) && + (pCoexDm->psTdmaDuAdjType != 24) && + (pCoexDm->psTdmaDuAdjType != 25) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], duration case out of handle!!\n")); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + pCoexDm->psTdmaDuAdjType = 23; + } + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 40MHz\n")); + if(result == -1) + { + if(pCoexDm->curPsTdma == 23) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + pCoexDm->psTdmaDuAdjType = 24; + } + else if(pCoexDm->curPsTdma == 24) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 25); + pCoexDm->psTdmaDuAdjType = 25; + } + else if(pCoexDm->curPsTdma == 25) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 27); + pCoexDm->psTdmaDuAdjType = 27; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 27) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 25); + pCoexDm->psTdmaDuAdjType = 25; + } + else if(pCoexDm->curPsTdma == 25) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + pCoexDm->psTdmaDuAdjType = 24; + } + else if(pCoexDm->curPsTdma == 24) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + pCoexDm->psTdmaDuAdjType = 23; + } + } + // error handle, if not in the following state, + // set psTdma again. + if( (pCoexDm->psTdmaDuAdjType != 23) && + (pCoexDm->psTdmaDuAdjType != 24) && + (pCoexDm->psTdmaDuAdjType != 25) && + (pCoexDm->psTdmaDuAdjType != 27) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], duration case out of handle!!\n")); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + pCoexDm->psTdmaDuAdjType = 24; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ACL only busy\n")); + if (result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 11) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + + // error handle, if not in the following state, + // set psTdma again. + if( (pCoexDm->psTdmaDuAdjType != 1) && + (pCoexDm->psTdmaDuAdjType != 2) && + (pCoexDm->psTdmaDuAdjType != 9) && + (pCoexDm->psTdmaDuAdjType != 11) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], duration case out of handle!!\n")); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } + pCoexDm->psTdmaMonitorCnt++; +} + + +VOID +halbtc8723a1ant_CoexForWifiConnect( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiConnected=FALSE, bWifiBusy=FALSE; + u1Byte btState, btInfoOriginal=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + btState = pCoexDm->btStatus; + btInfoOriginal = pCoexSta->btInfoC2h[BT_INFO_SRC_8723A_1ANT_BT_RSP][0]; + + if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi connected!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if( !bWifiBusy && + ((BT_STATE_8723A_1ANT_NO_CONNECTION == btState) || + (BT_STATE_8723A_1ANT_CONNECT_IDLE == btState)) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], [Wifi is idle] or [Bt is non connected idle or Bt is connected idle]!!\n")); + + if(BT_STATE_8723A_1ANT_NO_CONNECTION == btState) + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + else if(BT_STATE_8723A_1ANT_CONNECT_IDLE == btState) + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0); + } + else + { + if( (BT_STATE_8723A_1ANT_SCO_ONLY_BUSY == btState) || + (BT_STATE_8723A_1ANT_ACL_SCO_BUSY == btState) || + (BT_STATE_8723A_1ANT_HID_BUSY == btState) || + (BT_STATE_8723A_1ANT_HID_SCO_BUSY == btState) ) + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xff000000, 0x60); + } + else + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0); + } + switch(btState) + { + case BT_STATE_8723A_1ANT_NO_CONNECTION: + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + break; + case BT_STATE_8723A_1ANT_CONNECT_IDLE: + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + break; + case BT_STATE_8723A_1ANT_INQ_OR_PAG: + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + break; + case BT_STATE_8723A_1ANT_SCO_ONLY_BUSY: + case BT_STATE_8723A_1ANT_ACL_SCO_BUSY: + case BT_STATE_8723A_1ANT_HID_BUSY: + case BT_STATE_8723A_1ANT_HID_SCO_BUSY: + halbtc8723a1ant_TdmaDurationAdjust(pBtCoexist); + break; + case BT_STATE_8723A_1ANT_ACL_ONLY_BUSY: + if (btInfoOriginal&BT_INFO_8723A_1ANT_B_A2DP) + { + halbtc8723a1ant_TdmaDurationAdjust(pBtCoexist); + } + else if(btInfoOriginal&BT_INFO_8723A_1ANT_B_FTP) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + else if( (btInfoOriginal&BT_INFO_8723A_1ANT_B_A2DP) && + (btInfoOriginal&BT_INFO_8723A_1ANT_B_FTP) ) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + } + else + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], error!!!, undefined case in halbtc8723a1ant_CoexForWifiConnect()!!\n")); + break; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is disconnected!!\n")); + } + + pCoexDm->psTdmaGlobalCnt++; +} + +//============================================================ +// work around function start with wa_halbtc8723a1ant_ +//============================================================ +VOID +wa_halbtc8723a1ant_MonitorC2h( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte tmp1b=0x0; + u4Byte curC2hTotalCnt=0x0; + static u4Byte preC2hTotalCnt=0x0, sameCntPollingTime=0x0; + + curC2hTotalCnt+=pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8723A_1ANT_BT_RSP]; + + if(curC2hTotalCnt == preC2hTotalCnt) + { + sameCntPollingTime++; + } + else + { + preC2hTotalCnt = curC2hTotalCnt; + sameCntPollingTime = 0; + } + + if(sameCntPollingTime >= 2) + { + tmp1b = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x1af); + if(tmp1b != 0x0) + { + pCoexSta->c2hHangDetectCnt++; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x1af, 0x0); + } + } +} + +//============================================================ +// extern function start with EXhalbtc8723a1ant_ +//============================================================ +VOID +EXhalbtc8723a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); + + // enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // coex table + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, 0x0); // 1-Ant coex + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, 0xffff); // wifi break table + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, 0x55555555); //coex table + + // antenna switch control parameter + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x858, 0xaaaaaaaa); + + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x860, 0x210); //set antenna at wifi side if ANTSW is software control + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x870, 0x300); //SPDT(connected with TRSW) control by hardware PTA + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x874, 0x22804000); //ANTSW keep by GNT_BT + + // coexistence parameters + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); // enable RTK mode PTA +} + +VOID +EXhalbtc8723a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8723a1ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8723a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8723A_1ANT_BT_STATUS_IDLE == pCoexDm->btStatus)? "idle":( (BT_8723A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy"))), + pCoexSta->btRssi, pCoexSta->btRetryCnt); + CL_PRINTF(cliBuf); + + if(pStackInfo->bProfileNotified) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723a1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "write 0x1af=0x0 num", \ + pCoexSta->c2hHangDetectCnt); + CL_PRINTF(cliBuf); + + // Sw mechanism + 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/ %d/ %d", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + if(!pBtCoexist->bManualControl) + { + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x783); + u1Tmp[2] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x796); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \ + u1Tmp[0], u1Tmp[1], u1Tmp[2]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x484); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xdac); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770 (hp rx[31:16]/tx[15:0])", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8723a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + halbtc8723a1ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + //halbtc8723a1ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8723a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } +} + +VOID +EXhalbtc8723a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE; + + halbtc8723a1ant_NotifyFwScan(pBtCoexist, type); + + if(pBtCoexist->btInfo.bBtDisabled) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + } + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + //set 0x550[3]=1 before PsTdma + halbtc8723a1ant_Reg0x550Bit3(pBtCoexist, TRUE); + } + + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + halbtc8723a1ant_CoexForWifiConnect(pBtCoexist); + } + } + } +} + +VOID +EXhalbtc8723a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE; + + if(pBtCoexist->btInfo.bBtDisabled) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + } + else + { + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + //set 0x550[3]=1 before PsTdma + halbtc8723a1ant_Reg0x550Bit3(pBtCoexist, TRUE); + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); // extend wifi slot + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + halbtc8723a1ant_CoexForWifiConnect(pBtCoexist); + } + } + } +} + +VOID +EXhalbtc8723a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } +} + +VOID +EXhalbtc8723a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + if(pBtCoexist->btInfo.bBtDisabled) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + } + else + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 18); + } + } +} + +VOID +EXhalbtc8723a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtHsOn=FALSE, bBtBusy=FALSE, bForceLps=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = BT_INFO_SRC_8723A_1ANT_BT_RSP; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 0) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8723A_1ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = + pCoexSta->btInfoC2h[rspSource][1]; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][2]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][3]; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8723A_1ANT_B_INQ_PAGE) + { + pCoexSta->bC2hBtInquiryPage = TRUE; + } + else + { + pCoexSta->bC2hBtInquiryPage = FALSE; + } + btInfo &= ~BIT2; + if(!(btInfo & BIT0)) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_NO_CONNECTION; + bForceLps = FALSE; + } + else + { + bForceLps = TRUE; + if(btInfo == 0x1) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_CONNECT_IDLE; + } + else if(btInfo == 0x9) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_ACL_ONLY_BUSY; + bBtBusy = TRUE; + } + else if(btInfo == 0x13) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_SCO_ONLY_BUSY; + bBtBusy = TRUE; + } + else if(btInfo == 0x1b) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_ACL_SCO_BUSY; + bBtBusy = TRUE; + } + else if(btInfo == 0x29) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_HID_BUSY; + bBtBusy = TRUE; + } + else if(btInfo == 0x3b) + { + pCoexDm->btStatus = BT_STATE_8723A_1ANT_HID_SCO_BUSY; + bBtBusy = TRUE; + } + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bBtBusy); + if(bForceLps) + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_ENTER_LPS, NULL); + else + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + + if( (BT_STATE_8723A_1ANT_NO_CONNECTION == pCoexDm->btStatus) || + (BT_STATE_8723A_1ANT_CONNECT_IDLE == pCoexDm->btStatus) ) + { + if(pCoexSta->bC2hBtInquiryPage) + pCoexDm->btStatus = BT_STATE_8723A_1ANT_INQ_OR_PAG; + } +} + +VOID +EXhalbtc8723a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + + halbtc8723a1ant_LowPenaltyRa(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a1ant_RfShrink(pBtCoexist, FORCE_EXEC, FALSE); + + halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8723a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8723a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE, bWifiConnected=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Periodical!!\n")); + + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // work around for c2h hang + wa_halbtc8723a1ant_MonitorC2h(pBtCoexist); + + halbtc8723a1ant_QueryBtInfo(pBtCoexist); + halbtc8723a1ant_MonitorBtCtr(pBtCoexist); + halbtc8723a1ant_MonitorBtEnableDisable(pBtCoexist); + + + if(bScan) + return; + if(bLink) + return; + + if(bWifiConnected) + { + if(pBtCoexist->btInfo.bBtDisabled) + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + + halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + } + else + { + halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a1ant_CoexForWifiConnect(pBtCoexist); + } + } + else + { + halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + } +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.h new file mode 100644 index 00000000..e8c2fd00 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a1Ant.h @@ -0,0 +1,171 @@ +//=========================================== +// The following is for 8723A 1Ant BT Co-exist definition +//=========================================== +#define BT_INFO_8723A_1ANT_B_FTP BIT7 +#define BT_INFO_8723A_1ANT_B_A2DP BIT6 +#define BT_INFO_8723A_1ANT_B_HID BIT5 +#define BT_INFO_8723A_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723A_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723A_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723A_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723A_1ANT_B_CONNECTION BIT0 + +typedef enum _BT_STATE_8723A_1ANT{ + BT_STATE_8723A_1ANT_DISABLED = 0, + BT_STATE_8723A_1ANT_NO_CONNECTION = 1, + BT_STATE_8723A_1ANT_CONNECT_IDLE = 2, + BT_STATE_8723A_1ANT_INQ_OR_PAG = 3, + BT_STATE_8723A_1ANT_ACL_ONLY_BUSY = 4, + BT_STATE_8723A_1ANT_SCO_ONLY_BUSY = 5, + BT_STATE_8723A_1ANT_ACL_SCO_BUSY = 6, + BT_STATE_8723A_1ANT_HID_BUSY = 7, + BT_STATE_8723A_1ANT_HID_SCO_BUSY = 8, + BT_STATE_8723A_1ANT_MAX +}BT_STATE_8723A_1ANT, *PBT_STATE_8723A_1ANT; + +#define BTC_RSSI_COEX_THRESH_TOL_8723A_1ANT 2 + +typedef enum _BT_INFO_SRC_8723A_1ANT{ + BT_INFO_SRC_8723A_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8723A_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8723A_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723A_1ANT_MAX +}BT_INFO_SRC_8723A_1ANT,*PBT_INFO_SRC_8723A_1ANT; + +typedef enum _BT_8723A_1ANT_BT_STATUS{ + BT_8723A_1ANT_BT_STATUS_IDLE = 0x0, + BT_8723A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723A_1ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8723A_1ANT_BT_STATUS_MAX +}BT_8723A_1ANT_BT_STATUS,*PBT_8723A_1ANT_BT_STATUS; + +typedef enum _BT_8723A_1ANT_COEX_ALGO{ + BT_8723A_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723A_1ANT_COEX_ALGO_SCO = 0x1, + BT_8723A_1ANT_COEX_ALGO_HID = 0x2, + BT_8723A_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8723A_1ANT_COEX_ALGO_PANEDR = 0x4, + BT_8723A_1ANT_COEX_ALGO_PANHS = 0x5, + BT_8723A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x6, + BT_8723A_1ANT_COEX_ALGO_PANEDR_HID = 0x7, + BT_8723A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x8, + BT_8723A_1ANT_COEX_ALGO_HID_A2DP = 0x9, + BT_8723A_1ANT_COEX_ALGO_MAX +}BT_8723A_1ANT_COEX_ALGO,*PBT_8723A_1ANT_COEX_ALGO; + +typedef struct _COEX_DM_8723A_1ANT{ + // fw mechanism + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + u4Byte psTdmaMonitorCnt; + u4Byte psTdmaGlobalCnt; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; +} COEX_DM_8723A_1ANT, *PCOEX_DM_8723A_1ANT; + +typedef struct _COEX_STA_8723A_1ANT{ + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + u1Byte preBtRssiState; + u1Byte preBtRssiState1; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8723A_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8723A_1ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + u1Byte btRetryCnt; + u1Byte btInfoExt; + //BOOLEAN bHoldForStackOperation; + //u1Byte bHoldPeriodCnt; + // this is for c2h hang work-around + u4Byte c2hHangDetectCnt; +}COEX_STA_8723A_1ANT, *PCOEX_STA_8723A_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8723a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8723a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.c new file mode 100644 index 00000000..f32bd9f8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.c @@ -0,0 +1,3746 @@ +//============================================================ +// Description: +// +// This file is for RTL8723A Co-exist mechanism +// +// History +// 2012/08/22 Cosa first check in. +// 2012/11/14 Cosa Revise for 8723A 2Ant out sourcing. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8723a2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8723A_2ANT GLCoexDm8723a2Ant; +static PCOEX_DM_8723A_2ANT pCoexDm=&GLCoexDm8723a2Ant; +static COEX_STA_8723A_2ANT GLCoexSta8723a2Ant; +static PCOEX_STA_8723A_2ANT pCoexSta=&GLCoexSta8723a2Ant; + +const char *const GLBtInfoSrc8723a2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8723a2ant_ +//============================================================ +BOOLEAN +halbtc8723a2ant_IsWifiIdle( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiConnected=FALSE, bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &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); + + if(bWifiConnected) + return FALSE; + if(bScan) + return FALSE; + if(bLink) + return FALSE; + if(bRoam) + return FALSE; + + return TRUE; +} + +BOOLEAN +halbtc8723a2ant_IsWifiConnectedIdle( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiConnected=FALSE, bScan=FALSE, bLink=FALSE, bRoam=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(bScan) + return FALSE; + if(bLink) + return FALSE; + if(bRoam) + return FALSE; + if(bWifiConnected && !bWifiBusy) + return TRUE; + else + return FALSE; +} + +u1Byte +halbtc8723a2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8723a2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8723a2ant_IndicateWifiChnlBwInfo( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x19=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x19, 3, H2C_Parameter); +} + +VOID +halbtc8723a2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x38=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x38, 1, H2C_Parameter); +} +u1Byte +halbtc8723a2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bBtHsOn=FALSE, bBtBusy=FALSE, bLimitedDig=FALSE; + u1Byte algorithm=BT_8723A_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + //====================== + // here we get BT status first + //====================== + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_IDLE; + + if((pStackInfo->bScoExist) ||(bBtHsOn) ||(pStackInfo->bHidExist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE; + } + else + { + // A2dp profile + if( (pBtCoexist->stackInfo.numOfLink == 1) && + (pStackInfo->bA2dpExist) ) + { + if( (pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 100) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE; + } + } + // Pan profile + if( (pBtCoexist->stackInfo.numOfLink == 1) && + (pStackInfo->bPanExist) ) + { + if((pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 600) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE; + } + else + { + if(pCoexSta->lowPriorityTx) + { + if((pCoexSta->lowPriorityRx /pCoexSta->lowPriorityTx)>9 ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE; + } + } + } + if(BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN, set BT non-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE; + } + } + // Pan+A2dp profile + if( (pBtCoexist->stackInfo.numOfLink == 2) && + (pStackInfo->bA2dpExist) && + (pStackInfo->bPanExist) ) + { + if((pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 600) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE; + } + else + { + if(pCoexSta->lowPriorityTx) + { + if((pCoexSta->lowPriorityRx /pCoexSta->lowPriorityTx)>9 ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE; + } + } + } + if(BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n")); + pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE; + } + } + } + if(BT_8723A_2ANT_BT_STATUS_IDLE != pCoexDm->btStatus) + { + bBtBusy = TRUE; + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + //====================== + + if(!pStackInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No profile exists!!!\n")); + return algorithm; + } + + if(pStackInfo->bScoExist) + numOfDiffProfile++; + if(pStackInfo->bHidExist) + numOfDiffProfile++; + if(pStackInfo->bPanExist) + numOfDiffProfile++; + if(pStackInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pStackInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_SCO; + } + else + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_A2DP; + } + else if(pStackInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pStackInfo->bScoExist) + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_SCO; + } + else if(pStackInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP; + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pStackInfo->bScoExist) + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID; + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pStackInfo->bScoExist) + { + if( pStackInfo->bHidExist && + pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +BOOLEAN +halbtc8723a2ant_NeedToDecBtPwr( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bRet=FALSE; + BOOLEAN bBtHsOn=FALSE, bWifiConnected=FALSE; + s4Byte btHsRssi=0; + u1Byte btRssiState=BTC_RSSI_STATE_HIGH; + + btRssiState = halbtc8723a2ant_BtRssiState(2, 42, 0); + + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn)) + return FALSE; + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected)) + return FALSE; + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi)) + return FALSE; + if(BTC_RSSI_LOW(btRssiState)) + return FALSE; + + if(bWifiConnected) + { + if(bBtHsOn) + { + if(btHsRssi > 37) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Need to decrease bt power for HS mode!!\n")); + bRet = TRUE; + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Need to decrease bt power for Wifi is connected!!\n")); + bRet = TRUE; + } + } + + return bRet; +} + +VOID +halbtc8723a2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x29=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x29, 1, H2C_Parameter); +} + +VOID +halbtc8723a2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bDecBtPwr + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bDecBtPwr) + { + H2C_Parameter[0] |= BIT1; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power : %s, FW write 0x21=0x%x\n", + (bDecBtPwr? "Yes!!":"No!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x21, 1, H2C_Parameter); +} + +VOID +halbtc8723a2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDecBtPwr + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power = %s\n", + (bForceExec? "force to":""), ((bDecBtPwr)? "ON":"OFF"))); + pCoexDm->bCurDecBtPwr = bDecBtPwr; + + if(!bForceExec) + { + if(pCoexDm->bPreDecBtPwr == pCoexDm->bCurDecBtPwr) + return; + } + halbtc8723a2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->bCurDecBtPwr); + + pCoexDm->bPreDecBtPwr = pCoexDm->bCurDecBtPwr; +} + +VOID +halbtc8723a2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8723a2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8723a2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8723a2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8723a2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8723a2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + tmpU1 |= BIT0; + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8723a2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8723a2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8723a2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xff000000, swDacSwingLvl); + } + else + { + pBtCoexist->fBtcSetBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0); + } +} + + +VOID +halbtc8723a2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8723a2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8723a2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a07611); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc04,0x3a05611); + } +} + +VOID +halbtc8723a2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8723a2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8723a2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4e1c0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4d1d0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4c1e0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4b1f0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x4a200001); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xdc000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x90000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x51000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x12000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x00355); + + rssiAdjustVal = 6; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x641c0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x631d0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x621e0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x611f0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78,0x60200001); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x32000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x71000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xb0000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xfc000); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x30355); + } + + // set rssiAdjustVal for wifi module. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + + +VOID +halbtc8723a2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8723a2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8723a2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8723a2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8723a2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8723a2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x25=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x25, 1, H2C_Parameter); +} + +VOID +halbtc8723a2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8723a2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8723a2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + + H2C_Parameter[0] = byte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = byte5; + + pCoexDm->psTdmaPara[0] = byte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = byte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x3a(5bytes)=0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x3a, 5, H2C_Parameter); +} + +VOID +halbtc8723a2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + u4Byte btTxRxCnt=0; + + btTxRxCnt = pCoexSta->highPriorityTx+pCoexSta->highPriorityRx+ + pCoexSta->lowPriorityTx+pCoexSta->lowPriorityRx; + + if(btTxRxCnt > 3000) + { + pCoexDm->bCurPsTdmaOn = TRUE; + pCoexDm->curPsTdma = 8; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], turn ON PS TDMA, type=%d for BT tx/rx counters=%d(>3000)\n", + pCoexDm->curPsTdma, btTxRxCnt)); + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(pCoexDm->bCurPsTdmaOn) + { + switch(pCoexDm->curPsTdma) + { + case 1: + default: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x98); + break; + case 2: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x98); + break; + case 3: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x98); + break; + case 4: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x5, 0x5, 0xe1, 0x80); + break; + case 5: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x98); + break; + case 6: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x98); + break; + case 7: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x98); + break; + case 8: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x5, 0x5, 0x60, 0x80); + break; + case 9: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x98); + break; + case 10: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x98); + break; + case 11: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x98); + break; + case 12: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x98); + break; + case 13: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x98); + break; + case 14: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x98); + break; + case 15: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x98); + break; + case 16: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x98); + break; + case 17: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x80); + break; + case 18: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x98); + break; + case 19: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x98); + break; + case 20: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x98); + break; + } + } + else + { + // disable PS tdma + switch(pCoexDm->curPsTdma) + { + case 0: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0); + break; + case 1: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + break; + default: + halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + + +VOID +halbtc8723a2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + // sw all off + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + // hw all off + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); +} + +VOID +halbtc8723a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + halbtc8723a2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0x55555555, 0xffff, 0x3); + halbtc8723a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a2ant_RfShrink(pBtCoexist, FORCE_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, FORCE_EXEC, FALSE, 0xc0); +} + +VOID +halbtc8723a2ant_BtInquiryPage( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bLowPwrDisable=TRUE; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); +} + +VOID +halbtc8723a2ant_BtEnableAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiConnected=FALSE; + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); +} + +VOID +halbtc8723a2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8723a2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + halbtc8723a2ant_BtEnableAction(pBtCoexist); + } + } +} + +BOOLEAN +halbtc8723a2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE; + BOOLEAN bLowPwrDisable=FALSE; + + if(!pStackInfo->bBtLinkExist) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + } + else + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) && + BT_8723A_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle + Bt idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else if(!halbtc8723a2ant_IsWifiIdle(pBtCoexist) && + (BT_8723A_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-idle + BT idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) && + (BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle + Bt connected idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else if(!halbtc8723a2ant_IsWifiIdle(pBtCoexist) && + (BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-idle + Bt connected idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) && + (BT_8723A_2ANT_BT_STATUS_NON_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle + BT non-idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else if(halbtc8723a2ant_IsWifiConnectedIdle(pBtCoexist) && + (BT_8723A_2ANT_BT_STATUS_NON_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected-idle + BT non-idle!!\n")); + + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + + bCommon = TRUE; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-idle + BT non-idle!!\n")); + halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20); + + bCommon = FALSE; + } + + return bCommon; +} +VOID +halbtc8723a2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(pCoexDm->bResetTdmaAdjust) + { + pCoexDm->bResetTdmaAdjust = FALSE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +// SCO only or SCO+PAN(HS) +VOID +halbtc8723a2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1; + u4Byte wifiBw; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + + +VOID +halbtc8723a2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1; + u4Byte wifiBw; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8723a2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp rate, 1:basic /0:edr + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + } + else + { + if(btInfoExt&BIT0) //a2dp rate, 1:basic /0:edr + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + else + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp rate, 1:basic /0:edr + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + } + else + { + if(btInfoExt&BIT0) //a2dp rate, 1:basic /0:edr + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + else + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +VOID +halbtc8723a2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + + +//PAN(HS) only +VOID +halbtc8723a2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState; + u4Byte wifiBw; + + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8723a2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + } + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + } + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +VOID +halbtc8723a2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1; + u4Byte wifiBw; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + else + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8723a2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + } + else //a2dp edr rate + { + halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +VOID +halbtc8723a2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + + if(halbtc8723a2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 37, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else //a2dp edr rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 1); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 1); + } + } + + // sw mechanism + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + wifiRssiState = halbtc8723a2ant_WifiRssiState(pBtCoexist, 0, 2, 27, 0); + wifiRssiState1 = halbtc8723a2ant_WifiRssiState(pBtCoexist, 1, 2, 47, 0); + + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else //a2dp edr rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 1); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8723a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 1); + } + } + + // sw mechanism + if( (wifiRssiState1 == BTC_RSSI_STATE_HIGH) || + (wifiRssiState1 == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, TRUE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + else + { + halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE); + halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0); + } + } +} + +VOID +halbtc8723a2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + u1Byte btInfoOriginal=0, btRetryCnt=0; + u1Byte algorithm=0; + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Manual control!!!\n")); + return; + } + + if(pStackInfo->bProfileNotified) + { + if(pCoexSta->bHoldForStackOperation) + { + // if bt inquiry/page/pair, do not execute. + return; + } + + algorithm = halbtc8723a2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bHoldPeriodCnt && (BT_8723A_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex],Hold BT inquiry/page scan setting (cnt = %d)!!\n", + pCoexSta->bHoldPeriodCnt)); + if(pCoexSta->bHoldPeriodCnt >= 6) + { + pCoexSta->bHoldPeriodCnt = 0; + // next time the coexist parameters should be reset again. + } + else + pCoexSta->bHoldPeriodCnt++; + return; + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + if(halbtc8723a2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bResetTdmaAdjust = TRUE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bResetTdmaAdjust = TRUE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8723A_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8723a2ant_ActionSco(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8723a2ant_ActionHid(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8723a2ant_ActionA2dp(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8723a2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8723a2ant_ActionPanHs(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8723a2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8723a2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8723a2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8723A_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8723a2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8723a2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } + } +} + +//============================================================ +// work around function start with wa_halbtc8723a2ant_ +//============================================================ +VOID +wa_halbtc8723a2ant_MonitorC2h( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte tmp1b=0x0; + u4Byte curC2hTotalCnt=0x0; + static u4Byte preC2hTotalCnt=0x0, sameCntPollingTime=0x0; + + curC2hTotalCnt+=pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8723A_2ANT_BT_RSP]; + + if(curC2hTotalCnt == preC2hTotalCnt) + { + sameCntPollingTime++; + } + else + { + preC2hTotalCnt = curC2hTotalCnt; + sameCntPollingTime = 0; + } + + if(sameCntPollingTime >= 2) + { + tmp1b = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x1af); + if(tmp1b != 0x0) + { + pCoexSta->c2hHangDetectCnt++; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x1af, 0x0); + } + } +} + +//============================================================ +// extern function start with EXhalbtc8723a2ant_ +//============================================================ +VOID +EXhalbtc8723a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8723a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + u4Byte u4Tmp=0; + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + // Enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); +} + +VOID +EXhalbtc8723a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8723a2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8723a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8723A_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus)? "idle":( (BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy"))), + pCoexSta->btRssi, pCoexSta->btRetryCnt); + CL_PRINTF(cliBuf); + + if(pStackInfo->bProfileNotified) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723a2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "write 0x1af=0x0 num", \ + pCoexSta->c2hHangDetectCnt); + CL_PRINTF(cliBuf); + + // Sw mechanism + 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/ %d/ %d", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + if(!pBtCoexist->bManualControl) + { + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \ + pCoexDm->bCurDecBtPwr, pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x783); + u1Tmp[2] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x796); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \ + u1Tmp[0], u1Tmp[1], u1Tmp[2]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x484); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xdac); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770 (hp rx[31:16]/tx[15:0])", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8723a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + halbtc8723a2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + //halbtc8723a2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8723a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + } +} + +VOID +EXhalbtc8723a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } +} + +VOID +EXhalbtc8723a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8723a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, type); +} + +VOID +EXhalbtc8723a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8723a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = BT_INFO_SRC_8723A_2ANT_BT_RSP; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 0) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8723A_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = + pCoexSta->btInfoC2h[rspSource][1]; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][2]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][3]; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8723A_2ANT_B_INQ_PAGE) + { + pCoexSta->bC2hBtInquiryPage = TRUE; + } + else + { + pCoexSta->bC2hBtInquiryPage = FALSE; + } +} + +VOID +EXhalbtc8723a2ant_StackOperationNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_STACK_OP_INQ_PAGE_PAIR_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], StackOP Inquiry/page/pair start notify\n")); + pCoexSta->bHoldForStackOperation = TRUE; + pCoexSta->bHoldPeriodCnt = 1; + halbtc8723a2ant_BtInquiryPage(pBtCoexist); + } + else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], StackOP Inquiry/page/pair finish notify\n")); + pCoexSta->bHoldForStackOperation = FALSE; + } +} + +VOID +EXhalbtc8723a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8723a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8723a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Periodical!!\n")); + + // work around for c2h hang + wa_halbtc8723a2ant_MonitorC2h(pBtCoexist); + + halbtc8723a2ant_QueryBtInfo(pBtCoexist); + halbtc8723a2ant_MonitorBtCtr(pBtCoexist); + halbtc8723a2ant_MonitorBtEnableDisable(pBtCoexist); + + halbtc8723a2ant_RunCoexistMechanism(pBtCoexist); +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.h new file mode 100644 index 00000000..f0cc8b54 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723a2Ant.h @@ -0,0 +1,184 @@ +//=========================================== +// The following is for 8723A 2Ant BT Co-exist definition +//=========================================== +#define BT_INFO_8723A_2ANT_B_FTP BIT7 +#define BT_INFO_8723A_2ANT_B_A2DP BIT6 +#define BT_INFO_8723A_2ANT_B_HID BIT5 +#define BT_INFO_8723A_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723A_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723A_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723A_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723A_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT 2 + +typedef enum _BT_INFO_SRC_8723A_2ANT{ + BT_INFO_SRC_8723A_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8723A_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8723A_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723A_2ANT_MAX +}BT_INFO_SRC_8723A_2ANT,*PBT_INFO_SRC_8723A_2ANT; + +typedef enum _BT_8723A_2ANT_BT_STATUS{ + BT_8723A_2ANT_BT_STATUS_IDLE = 0x0, + BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723A_2ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8723A_2ANT_BT_STATUS_MAX +}BT_8723A_2ANT_BT_STATUS,*PBT_8723A_2ANT_BT_STATUS; + +typedef enum _BT_8723A_2ANT_COEX_ALGO{ + BT_8723A_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723A_2ANT_COEX_ALGO_SCO = 0x1, + BT_8723A_2ANT_COEX_ALGO_HID = 0x2, + BT_8723A_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8723A_2ANT_COEX_ALGO_PANEDR = 0x4, + BT_8723A_2ANT_COEX_ALGO_PANHS = 0x5, + BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x6, + BT_8723A_2ANT_COEX_ALGO_PANEDR_HID = 0x7, + BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x8, + BT_8723A_2ANT_COEX_ALGO_HID_A2DP = 0x9, + BT_8723A_2ANT_COEX_ALGO_MAX +}BT_8723A_2ANT_COEX_ALGO,*PBT_8723A_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8723A_2ANT{ + // fw mechanism + BOOLEAN bPreDecBtPwr; + BOOLEAN bCurDecBtPwr; + //BOOLEAN bPreBtLnaConstrain; + //BOOLEAN bCurBtLnaConstrain; + //u1Byte bPreBtPsdMode; + //u1Byte bCurBtPsdMode; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + //BOOLEAN bPreBtAutoReport; + //BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; +} COEX_DM_8723A_2ANT, *PCOEX_DM_8723A_2ANT; + +typedef struct _COEX_STA_8723A_2ANT{ + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + u1Byte preBtRssiState; + u1Byte preBtRssiState1; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8723A_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8723A_2ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + u1Byte btRetryCnt; + u1Byte btInfoExt; + BOOLEAN bHoldForStackOperation; + u1Byte bHoldPeriodCnt; + // this is for c2h hang work-around + u4Byte c2hHangDetectCnt; +}COEX_STA_8723A_2ANT, *PCOEX_STA_8723A_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8723a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8723a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8723a2ant_StackOperationNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.c new file mode 100644 index 00000000..265ef130 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.c @@ -0,0 +1,5638 @@ +//============================================================ +// Description: +// +// This file is for RTL8723B Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8723b1Ant.tmh" +#endif + +//#include +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +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]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8723b1Ant=20150119; +u4Byte GLCoexVer8723b1Ant=0x58; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8723b1ant_ +//============================================================ +u1Byte +halbtc8723b1ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8723b1ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8723b1ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8723b1ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8723b1ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8723b1ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8723b1ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8723b1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8723b1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8723b1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8723b1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8723b1ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8723b1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +VOID +halbtc8723b1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp, u4Tmp1; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp, u1Tmp1; + s4Byte wifiRssi; + static u4Byte NumOfBtCounterChk = 0; + + //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; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if( (pCoexSta->lowPriorityTx > 1050) && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->popEventCnt++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + regHPRx, regHPTx, regLPRx, regLPTx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); + + // This part is for wifi FW and driver to update BT's status as disabled. + // The flow is as the following + // 1. disable BT + // 2. if all BT Tx/Rx counter=0, after 6 sec we query bt info + // 3. Because BT will not rsp from mailbox, so wifi fw will know BT is disabled + // 4. FW will rsp c2h for BT that driver will know BT is disabled. + if ((regHPTx == 0) && (regHPRx ==0) && (regLPTx == 0) && (regLPRx == 0)) + { + NumOfBtCounterChk++; + if (NumOfBtCounterChk == 3) +{ + halbtc8723b1ant_QueryBtInfo(pBtCoexist); + } + } + else + { + NumOfBtCounterChk = 0; + } + } + + +VOID +halbtc8723b1ant_MonitorWiFiCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u2Byte u2Tmp[3]; + s4Byte wifiRssi=0; + BOOLEAN bWifiBusy = FALSE, bWifiUnderBMode = FALSE; + static u1Byte nCCKLockCounter = 0; + u4Byte TotalCnt; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + 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); + + if ( (bWifiBusy) && (wifiRssi >= 30) && (!bWifiUnderBMode)) + { + TotalCnt = pCoexSta->nCRCOK_CCK + pCoexSta->nCRCOK_11g + pCoexSta->nCRCOK_11n + + pCoexSta->nCRCOK_11nAgg; + + if ( (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) || + (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) || + (pCoexDm->btStatus == BT_8723B_1ANT_BT_STATUS_SCO_BUSY) ) + { + if (pCoexSta->nCRCOK_CCK >(TotalCnt -pCoexSta->nCRCOK_CCK)) + { + if (nCCKLockCounter < 3) + nCCKLockCounter++; + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + if (!pCoexSta->bPreCCKLock) + { + + if (nCCKLockCounter >= 3) + pCoexSta->bCCKLock = TRUE; + else + pCoexSta->bCCKLock = FALSE; + } + else + { + if (nCCKLockCounter == 0) + pCoexSta->bCCKLock = FALSE; + else + pCoexSta->bCCKLock = TRUE; + } + + if (pCoexSta->bCCKLock) + pCoexSta->bCCKEverLock = TRUE; + + pCoexSta->bPreCCKLock = pCoexSta->bCCKLock; + + +} + +BOOLEAN +halbtc8723b1ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + + + } + + return FALSE; +} + +VOID +halbtc8723b1ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + pBtLinkInfo->bBtHiPriLinkExist = pCoexSta->bBtHiPriLinkExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8723b1ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8723B_1ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO only\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID only\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP only\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(HS) only\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(EDR) only\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP ==> SCO\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(EDR)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(EDR)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(EDR)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8723b1ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8723b1ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8723b1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8723b1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!") )); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8723b1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8723b1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8723b1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8723b1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8723b1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8723b1ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + +#if BT_8723B_1ANT_ANTDET_ENABLE +#if BT_8723B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE + if (pBoardInfo->btdmAntNumByAntDet == 2) + { + if (type == 3) + type = 14; + else if (type == 4) + type = 13; + else if (type == 5) + type = 8; + } +#endif +#endif + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], ********** CoexTable(%d) **********\n", type)); + + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 4: + if ( pCoexSta->bCCKEverLock) + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + else + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 5: + if ( pCoexSta->bCCKEverLock) + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaa5a5a, 0xaaaa5a5a, 0xffffff, 0x3); + else + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 6: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 7: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 8: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + halbtc8723b1ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8723b1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8723b1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8723b1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8723b1ant_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 +halbtc8723b1ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8723b1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8723b1ant_SwMechanism( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRA + ) +{ + halbtc8723b1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8723b1ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bForceExec, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte fwVer=0, u4Tmp=0, cntBtCalChk=0; + BOOLEAN bPgExtSwitch=FALSE; + BOOLEAN bUseExtSwitch=FALSE; + 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 + + if((fwVer>0 && fwVer<0xc0000) || bPgExtSwitch) + bUseExtSwitch = TRUE; + +#if BT_8723B_1ANT_ANTDET_ENABLE +#if BT_8723B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE + if (antPosType == BTC_ANT_PATH_PTA) + { + if ((pBoardInfo->btdmAntDetFinish) && (pBoardInfo->btdmAntNumByAntDet == 2)) + { + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + antPosType = BTC_ANT_PATH_WIFI; + else + antPosType = BTC_ANT_PATH_BT; + } + } +#endif +#endif + + if(bInitHwCfg) + { + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); //WiFi 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) + { + /* Use H2C to set GNT_BT to HIGH */ + H2C_Parameter[0] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + // set grant_bt to high + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); + } + //set wlan_act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + 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); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x944, 0x3, 0x3); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x930, 0x77); + } + else if(bWifiOff) + { + if(fwVer >= 0x180000) + { + /* Use H2C to set GNT_BT to HIGH */ + H2C_Parameter[0] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + // set grant_bt to high + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); + } + //set wlan_act to always low + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, &bIsInMpMode); + if(!bIsInMpMode) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x0); //BT select s0/s1 is controlled by BT + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi + + // 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL BT Vendor 0xac=0xf002 + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &= ~BIT23; + u4Tmp &= ~BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + else + { + /* Use H2C to set GNT_BT to LOW */ + if(fwVer >= 0x180000) + { + if (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765) != 0) + { + H2C_Parameter[0] = 0; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + } + else + { + // BT calibration check + while(cntBtCalChk <= 20) + { + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49d); + cntBtCalChk++; + if(u1Tmp & BIT0) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ########### BT is calibrating (wait cnt=%d) ###########\n", cntBtCalChk)); + delay_ms(50); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)**********\n", cntBtCalChk)); + break; + } + } + + // set grant_bt to PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x0); + } + + if (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e) != 0xc) + { + //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) + { + if(bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); // fixed internal switch S1->WiFi, S0->BT + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + //tell firmware "no antenna inverse" + H2C_Parameter[0] = 0; + H2C_Parameter[1] = 1; //ext switch type + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + else + { + //tell firmware "antenna inverse" + H2C_Parameter[0] = 1; + H2C_Parameter[1] = 1; //ext switch type + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + } + + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType)) + { + // 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 + { + if(bInitHwCfg) + { + // 0x4c[23]=1, 0x4c[24]=0 Antenna control by 0x64 + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp |= BIT23; + u4Tmp &=~BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + //Fix Ext switch Main->S1, Aux->S0 + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x0); + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + + //tell firmware "no antenna inverse" + H2C_Parameter[0] = 0; + H2C_Parameter[1] = 0; //internal switch type + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + else + { + + //tell firmware "antenna inverse" + H2C_Parameter[0] = 1; + H2C_Parameter[1] = 0; //internal switch type + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + } + + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType)) + { + // 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 +halbtc8723b1ant_SetAntPathDCut( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAntennaAux, //For 1-Ant--> 1: Antenna at S0, 0: Antenna at S1. Set 0 for 2-Ant + IN BOOLEAN bExtSwitch, // 1: Ext Switch (SPDT) exist on module, 0: no Ext Switch (SPDT) exist on module + IN BOOLEAN bTwoAntenna, // 1: 2-Antenna, 0:1-Antenna + IN u1Byte antennaPos, //Set Antenna Pos, For 1-Ant: BTC_ANT_PATH_WIFI, BTC_ANT_PATH_BT, BTC_ANT_PATH_PTA, For 2-Ant:BTC_ANT_WIFI_AT_MAIN, BTC_ANT_WIFI_AT_Aux + IN u1Byte wifiState //BTC_WIFI_STAT_INIT, BTC_WIFI_STAT_IQK, BTC_WIFI_STAT_NORMAL_OFF, BTC_WIFI_STAT_MP_OFF, BTC_WIFI_STAT_NORMAL, BTC_WIFI_STAT_ANT_DIV + ) +{ + u1Byte dataLen=5; + u1Byte buf[6] = {0}; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set BT Ant, bAntennaAux/bExtSwitch/bTwoAntenna/antennaPos/wifiState=%d/%d/%d/%d/%d\n", + bAntennaAux, bExtSwitch, bTwoAntenna, antennaPos, wifiState)); + + buf[0] = dataLen; + + if(bAntennaAux) + buf[1] = 0x1; + + if(bExtSwitch) + buf[2] = 0x1; + + if(bTwoAntenna) + buf[3] = 0x1; + + buf[4] = antennaPos; + + buf[5] = wifiState; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_8723B_ANT, (PVOID)&buf[0]); +} + +VOID +halbtc8723b1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + + +VOID +halbtc8723b1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bTurnOnByCnt=FALSE, bWifiBusy=FALSE, bWiFiNoisy=FALSE; + u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0; + u1Byte psTdmaByte4Val = 0x50, psTdmaByte0Val = 0x51, psTdmaByte3Val = 0x10; + s1Byte nWiFiDurationAdjust = 0x0; + static BOOLEAN bPreWifiBusy=FALSE; + + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + +#if BT_8723B_1ANT_ANTDET_ENABLE +#if BT_8723B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE + if (pBoardInfo->btdmAntNumByAntDet == 2) + { + if (bTurnOn) + type = type +100; //for WiFi RSSI low or BT RSSI low + else + type = 1; //always translate to TDMA(off,1) for TDMA-off case + } + +#endif +#endif + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if (bWifiBusy != bPreWifiBusy) + { + bForceExec = TRUE; + bPreWifiBusy = bWifiBusy; + } + + if (pCoexDm->bCurPsTdmaOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(off, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum <= 5) + { + nWiFiDurationAdjust = 5; + + if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + } + else if (pCoexSta->nScanAPNum >= 40) + { + nWiFiDurationAdjust = -15; + + if (pCoexSta->nA2DPBitPool < 35) + nWiFiDurationAdjust = -5; + else if (pCoexSta->nA2DPBitPool < 45) + nWiFiDurationAdjust = -10; + } + else if (pCoexSta->nScanAPNum >= 20) + { + nWiFiDurationAdjust = -10; + + if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + } + else + { + nWiFiDurationAdjust = 0; + + if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + } + + if ((type == 1) || (type == 2) || (type == 9) || (type == 11) || (type == 101) + || (type == 102) || (type == 109) || (type == 101)) + { + if (!pCoexSta->bForceLpsOn) //Native power save TDMA, 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, no dynamic slot + } + else + { + psTdmaByte0Val = 0x51; //null-pkt + psTdmaByte3Val = 0x10; //tx-pause at BT-slot + psTdmaByte4Val = 0x50; // 0x778 = d/1 toggle, dynamic slot + } + } + else if ((type == 3) || (type == 13) || (type == 14) || (type == 103) || (type == 113) || (type == 114)) + { + psTdmaByte0Val = 0x51; //null-pkt + psTdmaByte3Val = 0x10; //tx-pause at BT-slot + psTdmaByte4Val = 0x10; // 0x778 = d/1 toggle, no dynamic slot +#if 0 + if (!bWifiBusy) + psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) +#endif + } + else //native power save case + { + psTdmaByte0Val = 0x61; //no null-pkt + psTdmaByte3Val = 0x11; // no tx-pause at BT-slot + psTdmaByte4Val = 0x11; // 0x778 = d/1 toggle, no dynamic slot + //psTdmaByte4Va is not defne for 0x778 = d/1, 1/1 case + } + + //if (pBtLinkInfo->bSlaveRole == TRUE) + if ((pBtLinkInfo->bSlaveRole == TRUE) && (pBtLinkInfo->bA2dpExist)) + psTdmaByte4Val = psTdmaByte4Val | 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) + + if (type > 100) + { + psTdmaByte0Val = psTdmaByte0Val | 0x82; //set antenna control by SW + psTdmaByte3Val = psTdmaByte3Val | 0x60; //set antenna no toggle, control by antenna diversity + } + + + if(bTurnOn) + { + switch(type) + { + default: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, psTdmaByte4Val); + break; + case 1: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 2: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 3: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 4: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0); + break; + case 5: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x15, 0x3, psTdmaByte3Val, 0x11); + break; + case 6: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x20, 0x3, psTdmaByte3Val, 0x11); + break; + case 7: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0); + break; + case 8: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 9: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 10: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 12: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50); + break; + case 13: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 14: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 15: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0); + break; + case 16: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0); + break; + case 18: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 20: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3f, 0x03, psTdmaByte3Val, 0x10); + break; + case 21: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11); + break; + case 22: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x10); + break; + case 23: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18); + break; + case 24: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18); + break; + case 25: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 26: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 27: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98); + break; + case 28: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0); + break; + case 29: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10); + break; + case 31: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58); + break; + case 32: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x35, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 33: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x35, 0x3, psTdmaByte3Val, 0x10); + break; + case 34: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50); + break; + case 40: // SoftAP only with no sta associated,BT disable ,TDMA mode for power saving + /* here softap mode screen off will cost 70-80mA for phone */ + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24); + break; + + //for 1-Ant translate to 2-Ant + case 101: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 102: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 103: + //halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, psTdmaByte4Val); + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 105: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x15, 0x3, psTdmaByte3Val, 0x11); + break; + case 106: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x20, 0x3, psTdmaByte3Val, 0x11); + break; + case 109: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 111: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 113: + //halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x51, 0x12, 0x12, 0x0, psTdmaByte4Val); + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 114: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 120: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3f, 0x03, psTdmaByte3Val, 0x10); + break; + case 122: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x10); + break; + case 132: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 133: + halbtc8723b1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x25, 0x03, psTdmaByte3Val, 0x11); + break; + + } + } + else + { + + // disable PS tdma + switch(type) + { + case 8: //PTA Control + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + break; + case 0: + default: //Software control, Antenna at BT side + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + break; + case 1: // 2-Ant, 0x778=3, antenna control by antenna diversity + halbtc8723b1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + 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); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765), pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67))); + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +BOOLEAN +halbtc8723b1ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n")); + + //halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + //halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n")); + + //halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + + //halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); + + //halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else + { + if (bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + } + + bCommon = FALSE; + } + + return bCommon; +} + + +VOID +halbtc8723b1ant_TdmaDurationAdjustForAcl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + static BOOLEAN bPreWifiBusy=FALSE; + BOOLEAN bWifiBusy = FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjustForAcl()\n")); + + if(BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifiStatus) + bWifiBusy = TRUE; + else + bWifiBusy = FALSE; + + if( (BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 3 && + pCoexDm->curPsTdma != 9 ) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { +/* if( (BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else */ if(pCoexDm->curPsTdma == 1) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if(result == 1) + { +/* if( (BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else */ if(pCoexDm->curPsTdma == 11) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + else //no change + { + /* Bryant Modify + if(bWifiBusy != bPreWifiBusy) //if busy / idle change + { + bPreWifiBusy = bWifiBusy; + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, pCoexDm->curPsTdma); + } + */ + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 9 && + pCoexDm->curPsTdma != 11 ) + { + // recover to previous adjust type + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8723b1ant_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 + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8723b1ant_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: + halbtc8723b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8723b1ant_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: + halbtc8723b1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + +VOID +halbtc8723b1ant_ActionWifiOnly( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); +} + +VOID +halbtc8723b1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + + bPreBtDisabled = bBtDisabled; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + if(bBtDisabled) + { + halbtc8723b1ant_ActionWifiOnly(pBtCoexist); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +//============================================= +// +// Software Coex Mechanism start +// +//============================================= + +// SCO only or SCO+PAN(HS) + +/* +VOID +halbtc8723b1ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); +} + + +VOID +halbtc8723b1ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8723b1ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8723b1ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8723b1ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(HS) only +VOID +halbtc8723b1ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(EDR)+A2DP +VOID +halbtc8723b1ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8723b1ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8723b1ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8723b1ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_SwMechanism(pBtCoexist, TRUE); +} + +*/ + +//============================================= +// +// 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 + ) +{ + 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); +} + +VOID +halbtc8723b1ant_ActionHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8723b1ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bApEnable=FALSE, bWifiBusy=FALSE, bBtBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if ( (!bWifiConnected) && (!pCoexSta->bWiFiIsHighPriTask) ) + { + 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) ) + { + // SCO/HID/A2DP busy + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if (pCoexSta->bC2hBtRemoteNameReq) + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 33); + else + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if ( (pBtLinkInfo->bPanExist) || (bWifiBusy) ) + { + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if (pCoexSta->bC2hBtRemoteNameReq) + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 33); + else + 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); + + } +} + +VOID +halbtc8723b1ant_ActionBtScoHidOnlyBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // tdma and coex table + + if(pBtLinkInfo->bScoExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else //HID + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } +} + +VOID +halbtc8723b1ant_ActionWifiConnectedBtAclBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + u1Byte btRssiState; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + btRssiState = halbtc8723b1ant_BtRssiState(2, 28, 0); + + if ( (pCoexSta->lowPriorityRx >= 950) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + if(pBtLinkInfo->bHidOnly) //HID + { + halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus); + pCoexDm->bAutoTdmaAdjust = FALSE; + return; + } + else if(pBtLinkInfo->bA2dpOnly) //A2DP + { + if(BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + halbtc8723b1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = TRUE; + } + } + else if ( ((pBtLinkInfo->bA2dpExist) && (pBtLinkInfo->bPanExist)) || + (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist&&pBtLinkInfo->bPanExist) ) //A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if(pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) //HID+A2DP + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->bAutoTdmaAdjust = FALSE; + + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else if( (pBtLinkInfo->bPanOnly) || (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) ) //PAN(OPP,FTP), HID+PAN(OPP,FTP) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + //BT no-profile busy (0x9) + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 33); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } +} + +VOID +halbtc8723b1ant_ActionWifiNotConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // 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); +} + +VOID +halbtc8723b1ant_ActionWifiNotConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //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); + } +} + +VOID +halbtc8723b1ant_ActionWifiNotConnectedAssoAuth( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + } + else if (pBtLinkInfo->bPanExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + 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); + } +} + +VOID +halbtc8723b1ant_ActionWifiConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //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); + } +} + +VOID +halbtc8723b1ant_ActionWifiConnectedSpecialPacket( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiBusy = FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + //no special packet process for both WiFi and BT very busy + if ((bWifiBusy) && ((pBtLinkInfo->bPanExist) || (pCoexSta->nNumOfProfile >= 2))) + return; + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist)) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else if (pBtLinkInfo->bA2dpExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if(pBtLinkInfo->bPanExist) + { + halbtc8723b1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + 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); + } +} + +VOID +halbtc8723b1ant_ActionWifiConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiBusy=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + BOOLEAN bUnder4way=FALSE, bApEnable=FALSE; + u4Byte wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect()===>\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + if(bUnder4way) + { + halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n")); + return; + } + + 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) + { + if(bScan) + halbtc8723b1ant_ActionWifiConnectedScan(pBtCoexist); + else + halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + // power save state + if(!bApEnable && BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->btLinkInfo.bHidOnly) + { + if(pBtCoexist->btLinkInfo.bA2dpOnly) //A2DP + { + if(!bWifiBusy) + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else //busy + { + if (pCoexSta->nScanAPNum >= BT_8723B_1ANT_WIFI_NOISY_THRESH) //no force LPS, no PS-TDMA, use pure TDMA + { + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + } + } + else if ((pCoexSta->bPanExist == FALSE) && (pCoexSta->bA2dpExist == FALSE) && (pCoexSta->bHidExist == FALSE)) + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + else + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(!bWifiBusy) + { + if(BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8723b1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else if( (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + 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 + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else + { + if(BT_8723B_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8723b1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else if( (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8723b1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + 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 + halbtc8723b1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } +} + +VOID +halbtc8723b1ant_RunSwCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm=0; + + algorithm = halbtc8723b1ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + + if(halbtc8723b1ant_IsCommonAction(pBtCoexist)) + { + + } + else + { + switch(pCoexDm->curAlgorithm) + { + case BT_8723B_1ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = SCO.\n")); + //halbtc8723b1ant_ActionSco(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID.\n")); + //halbtc8723b1ant_ActionHid(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP.\n")); + //halbtc8723b1ant_ActionA2dp(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n")); + //halbtc8723b1ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR).\n")); + //halbtc8723b1ant_ActionPanEdr(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HS mode.\n")); + //halbtc8723b1ant_ActionPanHs(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN+A2DP.\n")); + //halbtc8723b1ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n")); + //halbtc8723b1ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n")); + //halbtc8723b1ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8723B_1ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP.\n")); + //halbtc8723b1ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = coexist All Off!!\n")); + //halbtc8723b1ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8723b1ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE, bWifiBusy = FALSE; + BOOLEAN bIncreaseScanDevNum=FALSE; + BOOLEAN bBtCtrlAggBufSize=FALSE; + BOOLEAN bMiracastPlusBt=FALSE; + u1Byte aggBufSize=5; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0, wifiBw; + u1Byte iotPeer=BTC_IOT_PEER_UNKNOWN; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if(pCoexSta->bBtWhckTest) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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) ) + { + bIncreaseScanDevNum = TRUE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, &bIncreaseScanDevNum); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], Multi-Port numOfWifiLink = %d, wifiLinkStatus = 0x%x\n", numOfWifiLink,wifiLinkStatus) ); + + if(pBtLinkInfo->bBtLinkExist) + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + bMiracastPlusBt = TRUE; + } + else + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + bMiracastPlusBt = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + + if (( (pBtLinkInfo->bA2dpExist) || (bWifiBusy) ) && (pCoexSta->bC2hBtInquiryPage) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8723b1ant_ActionBtInquiry(pBtCoexist); + } + else + halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if ( (pBtLinkInfo->bBtLinkExist) && (bWifiConnected) ) + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_IOT_PEER, &iotPeer); + + if(BTC_IOT_PEER_CISCO != iotPeer) + { + if(pBtLinkInfo->bScoExist)//if (pBtLinkInfo->bBtHiPriLinkExist) + //halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + else + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + //halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + } + else + { + 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_SwMechanism(pBtCoexist, TRUE); + halbtc8723b1ant_RunSwCoexistMechanism(pBtCoexist); //just print debug message + } + else + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + halbtc8723b1ant_RunSwCoexistMechanism(pBtCoexist); ////just print debug message + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8723b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8723b1ant_ActionHs(pBtCoexist); + return; + } + + + if(!bWifiConnected) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is non connected-idle !!!\n")); + + 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) + { + if (bScan) + halbtc8723b1ant_ActionWifiNotConnectedScan(pBtCoexist); + else + halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else + halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist); + } + else // wifi LPS/Busy + { + halbtc8723b1ant_ActionWifiConnected(pBtCoexist); + } +} + +u4Byte +halbtc8723b1ant_PSD_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 + ) +{ + // force to reset coex mechanism + + // sw all off + halbtc8723b1ant_SwMechanism(pBtCoexist, FALSE); + + //halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + //halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + pCoexSta->popEventCnt = 0; +} + +VOID +halbtc8723b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp, + IN BOOLEAN bWifiOnly + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0;//, fwVer; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0, u1Tmpa=0, u1Tmpb=0; + u1Byte H2C_Parameter[2] ={0}; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + pPsdScan->nAntDet_IsAntDetAvailable = FALSE; + + //0xf0[15:12] --> Chip Cut information + pCoexSta->nCutVersion = (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xf1) & 0xf0) >> 4; + +#if 0//move to BTC_MEDIA_CONNECT + if(bBackUp) + { + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } +#endif + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x550, 0x8, 0x1); //enable TBTT nterrupt + + // 0x790[5:0]=0x5 + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, 0x5); + + // Enable counter statistics + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); + + + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi + + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + + //Antenna config + if(bWifiOnly) + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FORCE_EXEC, TRUE, FALSE); + else + 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, 8); + } + else + halbtc8723b1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_INIT); +#endif + + + + // PTA parameter + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); +} + + + + + +VOID +halbtc8723b1ant_MechanismSwitch( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwitchTo2Antenna + ) +{ + + if (bSwitchTo2Antenna) // 1-Ant -> 2-Ant + { + //un-lock TRx Mask setup for 8723b f-cut + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x1); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x1); + //WiFi TRx Mask on + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + //BT TRx Mask un-lock 0x2c[0], 0x30[0] = 1 + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x2c, 0x7c45); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x30, 0x7c45); + + //BT TRx Mask on + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x1); + + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, FALSE); + } + else + { + //WiFi TRx Mask on + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + + //lock TRx Mask setup for 8723b f-cut + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x0); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x0); + + //BT TRx Mask on + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); + + //BT TRx Mask ock 0x2c[0], 0x30[0] = 0 + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x2c, 0x7c44); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x30, 0x7c44); + + + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + } + +} + + + + +VOID +halbtc8723b1ant_PSD_ShowAntennaDetectResult( + IN PBTC_COEXIST pBtCoexist + ) +{ + pu1Byte cliBuf=pBtCoexist->cliBuf; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n============[Antenna Detection info] ============\n"); + CL_PRINTF(cliBuf); + + if (pPsdScan->nAntDet_Result == 1) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s (>%d)", "Ant Det Result", "2-Antenna (Bad-Isolation)", + BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION); + else if (pPsdScan->nAntDet_Result == 2) + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s (%d~%d)", "Ant Det Result", "2-Antenna (Good-Isolation)", + BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION+pPsdScan->nAntDet_ThresOffset, BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s (%d~%d)", "Ant Det Result", "1-Antenna", + BT_8723B_1ANT_ANTDET_PSDTHRES_1ANT, BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION+pPsdScan->nAntDet_ThresOffset); + + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s ", "Antenna Detection Finish", + (pBoardInfo->btdmAntDetFinish? "Yes":"No")); + CL_PRINTF(cliBuf); + + switch(pPsdScan->nAntDet_Result) + { + case 0: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is not available)"); + break; + case 1: // 2-Ant bad-isolation + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is available)"); + break; + case 2: // 2-Ant good-isolation + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is available)"); + break; + case 3: // 1-Ant + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is available)"); + break; + case 4: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(Uncertainty result)"); + break; + case 5: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(Pre-Scan fai)"); + break; + case 6: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(WiFi is Scanning)"); + break; + case 7: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is not idle)"); + break; + case 8: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(Abort by WiFi Scanning)"); + break; + case 9: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(Antenna Init is not ready)"); + break; + case 10: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is Inquiry or page)"); + break; + case 11: + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "(BT is Disabled)"); + break; +} + CL_PRINTF(cliBuf); + + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "Ant Detect Total Count",pPsdScan->bAntDet_TryCount); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "Ant Detect Fail Count",pPsdScan->bAntDet_FailCount); + CL_PRINTF(cliBuf); + + if ( (!pBoardInfo->btdmAntDetFinish) && (pPsdScan->nAntDet_Result != 5) ) + return; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Response",(pPsdScan->nAntDet_Result? "ok":"fail")); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ms", "BT Tx Time", pPsdScan->nAntDet_BTTxTime); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "BT Tx Ch", pPsdScan->nAntDet_BTLEChannel); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "WiFi PSD Cent-Ch/Offset/Span", + pPsdScan->nRealCentFreq, pPsdScan->nRealOffset, pPsdScan->nRealSpan); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d dB", "PSD Pre-Scan Peak Value", pPsdScan->nAntDet_PrePSDScanPeakVal/100); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s (<= %d)", "PSD Pre-Scan result", + (pPsdScan->nAntDet_Result != 5? "ok":"fail"), BT_8723B_1ANT_ANTDET_PSDTHRES_BACKGROUND+pPsdScan->nAntDet_ThresOffset); + CL_PRINTF(cliBuf); + + if (pPsdScan->nAntDet_Result == 5) + return; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s dB", "PSD Scan Peak Value", pPsdScan->nAntDet_PeakVal); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s MHz", "PSD Scan Peak Freq", pPsdScan->nAntDet_PeakFreq); + CL_PRINTF(cliBuf); + + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "TFBGA Package", + (pBoardInfo->bTfbgaPackage)? "Yes":"No"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "PSD Threshold Offset", pPsdScan->nAntDet_ThresOffset); + CL_PRINTF(cliBuf); + +} + +VOID +halbtc8723b1ant_PSD_ShowData( + IN PBTC_COEXIST pBtCoexist + ) +{ + pu1Byte cliBuf=pBtCoexist->cliBuf; + u4Byte nDeltaFreqPerPoint; + u4Byte freq,freq1,freq2,n=0,i=0, j=0, m=0, PsdRep1, PsdRep2; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n\n============[PSD info] (%d)============\n", + pPsdScan->nPSDGenCount); + CL_PRINTF(cliBuf); + + if (pPsdScan->nPSDGenCount == 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) + if (0) + { + PsdRep1 = pPsdScan->nPSDMaxValue/100; + PsdRep2 = pPsdScan->nPSDMaxValue - PsdRep1 * 100; + + freq = ((pPsdScan->nRealCentFreq-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) \n", + PsdRep1, PsdRep2, pPsdScan->nPSDMaxValue); + else + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, ", Value = %d.%d dB, (%d)\n", + PsdRep1, PsdRep2, pPsdScan->nPSDMaxValue); + + CL_PRINTF(cliBuf); + } + else + { + m = pPsdScan->nPSDStartPoint; + n = pPsdScan->nPSDStartPoint; + i = 1; + j = 1; + + while(1) + { + do + { + freq = ((pPsdScan->nRealCentFreq-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; + } + + } + } + + +} + +VOID +halbtc8723b1ant_PSD_MaxHoldData( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte GenCount + ) +{ + u4Byte i=0, i_max=0, val_max=0, j; + + if (GenCount== 1) + { + memcpy(pPsdScan->nPSDReport_MaxHold, pPsdScan->nPSDReport, BT_8723B_1ANT_ANTDET_PSD_POINTS*sizeof(u4Byte)); + + for (i= pPsdScan->nPSDStartPoint; i<=pPsdScan->nPSDStopPoint; i++) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i])); + } + + pPsdScan->nPSDMaxValuePoint = 0; + pPsdScan->nPSDMaxValue = 0; + + } + 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]; + } + } + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i = %d, PSDReport = %d dB\n", i, pPsdScan->nPSDReport_MaxHold[i])); + + } + + pPsdScan->nPSDMaxValuePoint = i_max; + pPsdScan->nPSDMaxValue = val_max; + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), Max_Hold i_Max = %d, PSDReport_Max = %d dB\n", pPsdScan->nPSDMaxValuePoint + // ,pPsdScan->nPSDMaxValue)); + } + + +} + +u4Byte +halbtc8723b1ant_PSD_GetData( + 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_PSD_SweepPoint( +IN PBTC_COEXIST pBtCoexist, + IN u4Byte centFreq, + IN s4Byte 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; + u4Byte WiFi_OriginalChannel = 1; + + pPsdScan->bIsPSDRunning = TRUE; + + do + { + switch(flag) + { + case 0: //Get PSD parameters + default: + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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; + pPsdScan->nRealCentFreq = centFreq; + pPsdScan->nRealOffset = offset; + pPsdScan->nRealSpan = span; + + + 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); + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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); + //RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), PSD Center Freq = %d\n", (centFreq + offset))); + + nStartP = pPsdScan->nPSDStartBase + (nPSDCenterFreq - span *(1000000)/2) /nDeltaFreqPerPoint; + pPsdScan->nPSDStartPoint = nStartP - pPsdScan->nPSDStartBase; + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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; + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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); + + //store WiFi original channel + WiFi_OriginalChannel = pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff); + + //Set RF channel + if (centFreq == 2484) + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, 0xe); + 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 RF Rx filter corner + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0x3e4); + + //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_PSD_GetData(pBtCoexist,i-nPoints); + } + else + { + psd_report = halbtc8723b1ant_PSD_GetData(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_PSD_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) + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.0%d MHz)", n, freq1, freq2)); + else + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx SweepPSDPoint(), i = %d (%d.%d MHz)", n, freq1, freq2)); + + if (PsdRep2 < 10) + RT_TRACE(COMP_COEX, DBG_LOUD, (", PSDReport = %d (%d.0%d dB)\n",psd_report, PsdRep1, PsdRep2)); + else + RT_TRACE(COMP_COEX, DBG_LOUD, (", PSDReport = %d (%d.%d dB)\n",psd_report, PsdRep1,PsdRep2)); +*/ + i++; + + k=0; + + //Add Delay between PSD point + while(1) + { + if (k++ > 20000) + break; + } + + //RT_TRACE(COMP_COEX, DBG_LOUD, ("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, 0x1, 0xfffff, 0x780); + + //lock TRx Mask setup + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdd, 0x80, 0x0); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xdf, 0x1, 0x0); + + //Set RF Rx filter corner + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0x0); + + //restore WiFi original channel + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x18, 0x3ff, WiFi_OriginalChannel); + + outloop = TRUE; + break; + + } + + }while (!outloop); + + + + pPsdScan->bIsPSDRunning = FALSE; + + +} + +VOID +halbtc8723b1ant_PSD_AntennaDetection( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte BTTxTime, + IN u4Byte BTLEChannel + ) +{ + u4Byte realseconds = 0, i=0, j=0; + u4Byte WLPSD_CentFreq = 2484, WLPSD_Span = 2, WLPSD_SweepCount = 50; + s4Byte WLPSD_Offset = -4; + u1Byte BTLECh[13] = {3,6,8,11,13,16,18,21,23,26,28,31,33}; + + u1Byte H2C_Parameter[3] ={0},u1Tmpa,u1Tmpb; + + u1Byte state=0; + BOOLEAN outloop = FALSE, BTResp = FALSE, bScan ,bRoam; + u4Byte freq,freq1,freq2,PsdRep1, PsdRep2, nDeltaFreqPerPoint,u4Tmp; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + pBoardInfo->btdmAntDetFinish = FALSE; + memset(pPsdScan->nAntDet_PeakVal, 0, 16*sizeof(UCHAR)); + memset(pPsdScan->nAntDet_PeakFreq, 0, 16*sizeof(UCHAR)); + + if (pBoardInfo->bTfbgaPackage) //for TFBGA + pPsdScan->nAntDet_ThresOffset = 5; + else + pPsdScan->nAntDet_ThresOffset = 0; + + do + { + switch(state) + { + case 0: + if (BTLEChannel == 39) + WLPSD_CentFreq = 2484; + else + { + for (i=1; i<=13; i++) + { + if (BTLECh[i-1] == BTLEChannel) + { + WLPSD_CentFreq = 2412 + (i-1) * 5; + break; + } + } + + if (i == 14) + { + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Abort!!, Invalid LE channel = %d\n ", BTLEChannel)); + outloop = TRUE; + break; + } + } + + WLPSD_SweepCount = BTTxTime * 238 /100; //BTTxTime/0.42 + + if (WLPSD_SweepCount % 5 != 0) + WLPSD_SweepCount = (WLPSD_SweepCount/5 + 1) * 5; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), BT_LETxTime=%d, BT_LECh = %d\n", BTTxTime, BTLEChannel)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), WLPSD_CentFreq=%d, WLPSD_Offset = %d, WLPSD_Span = %d, WLPSD_SweepCount = %d\n", + WLPSD_CentFreq, WLPSD_Offset, WLPSD_Span,WLPSD_SweepCount)); + + state = 1; + break; + case 1: //stop coex DM & set antenna path + //Stop Coex DM + pBtCoexist->bStopCoexDm = TRUE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Stop Coex DM!!\n")); + + //set native power save + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + //Set TDMA off, + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + + //Set coex table + halbtc8723b1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna at Main Port\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna at Aux Port\n")); + } + + //Set Antenna path, switch WiFi to un-certain antenna port + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, FALSE); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Set Antenna to BT!!\n")); + + //Set AFH mask on at WiFi channel 2472MHz +/- 10MHz + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = 0xd; + H2C_Parameter[2] = 0x14; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Set AFH on, Cent-Ch= %d, Mask=%d\n", + H2C_Parameter[1],H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x778=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); + + state =2; + break; + case 2: //Pre-sweep background psd + for (pPsdScan->nPSDGenCount=1; pPsdScan->nPSDGenCount<=3; pPsdScan->nPSDGenCount++) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), PSDGenCount = %d\n ", pPsdScan->nPSDGenCount)); + halbtc8723b1ant_PSD_SweepPoint(pBtCoexist, WLPSD_CentFreq, WLPSD_Offset, WLPSD_Span, BT_8723B_1ANT_ANTDET_PSD_POINTS, BT_8723B_1ANT_ANTDET_PSD_AVGNUM); + halbtc8723b1ant_PSD_MaxHoldData(pBtCoexist, pPsdScan->nPSDGenCount); + } + + pPsdScan->nAntDet_PrePSDScanPeakVal = pPsdScan->nPSDMaxValue; + + if (pPsdScan->nPSDMaxValue > (BT_8723B_1ANT_ANTDET_PSDTHRES_BACKGROUND+pPsdScan->nAntDet_ThresOffset)*100) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Abort Antenna Detection!! becaus background = %d > thres (%d)\n", + pPsdScan->nPSDMaxValue/100, BT_8723B_1ANT_ANTDET_PSDTHRES_BACKGROUND+pPsdScan->nAntDet_ThresOffset)); + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + pPsdScan->nAntDet_Result = 5; + state = 99; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Start Antenna Detection!! becaus background = %d <= thres (%d)\n", + pPsdScan->nPSDMaxValue/100, BT_8723B_1ANT_ANTDET_PSDTHRES_BACKGROUND+pPsdScan->nAntDet_ThresOffset)); + state = 3; + } + break; + case 3: + BTResp = pBtCoexist->fBtcSetBtAntDetection(pBtCoexist, (u1Byte)(BTTxTime&0xff), (u1Byte)(BTLEChannel&0xff)); + + for (pPsdScan->nPSDGenCount=1; pPsdScan->nPSDGenCount<=WLPSD_SweepCount; pPsdScan->nPSDGenCount++) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), PSDGenCount = %d\n ", pPsdScan->nPSDGenCount)); + halbtc8723b1ant_PSD_SweepPoint(pBtCoexist, WLPSD_CentFreq, WLPSD_Offset, WLPSD_Span, BT_8723B_1ANT_ANTDET_PSD_POINTS, BT_8723B_1ANT_ANTDET_PSD_AVGNUM); + halbtc8723b1ant_PSD_MaxHoldData(pBtCoexist, pPsdScan->nPSDGenCount); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + + if (bScan ||bRoam) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + pPsdScan->nAntDet_Result = 8; + state = 99; + break; + } + } + + pPsdScan->nAntDet_PSDScanPeakVal = pPsdScan->nPSDMaxValue; + pPsdScan->nAntDet_PSDScanPeakFreq = pPsdScan->nPSDMaxValuePoint; + state = 4; + break; + case 4: + + if (pPsdScan->nPSDPoint == 0) + nDeltaFreqPerPoint = 0; + else + nDeltaFreqPerPoint = pPsdScan->nPSDBandWidth/pPsdScan->nPSDPoint; + + PsdRep1 = pPsdScan->nPSDMaxValue/100; + PsdRep2 = pPsdScan->nPSDMaxValue - PsdRep1 * 100; + + freq = ((pPsdScan->nRealCentFreq-20) * 1000000 + pPsdScan->nPSDMaxValuePoint * nDeltaFreqPerPoint); + freq1 = freq/1000000; + freq2 = freq/1000 - freq1 * 1000; + + if (freq2 < 100) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Max Value: Freq = %d.0%d MHz", freq1, freq2)); + CL_SPRINTF(pPsdScan->nAntDet_PeakFreq, BT_8723B_1ANT_ANTDET_BUF_LEN, "%d.0%d", freq1,freq2); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Max Value: Freq = %d.%d MHz", freq1, freq2)); + CL_SPRINTF(pPsdScan->nAntDet_PeakFreq, BT_8723B_1ANT_ANTDET_BUF_LEN, "%d.%d", freq1,freq2); + } + + if (PsdRep2 < 10) + { + RT_TRACE(COMP_COEX, DBG_LOUD, (", Value = %d.0%d dB\n", PsdRep1, PsdRep2)); + CL_SPRINTF(pPsdScan->nAntDet_PeakVal, BT_8723B_1ANT_ANTDET_BUF_LEN, "%d.0%d", PsdRep1,PsdRep2); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, (", Value = %d.%d dB\n",PsdRep1, PsdRep2)); + CL_SPRINTF(pPsdScan->nAntDet_PeakVal, BT_8723B_1ANT_ANTDET_BUF_LEN, "%d.%d", PsdRep1,PsdRep2); + } + + pPsdScan->nAntDet_IsBTReplyAvailable = TRUE; + + if (BTResp == FALSE) + { + pPsdScan->nAntDet_IsBTReplyAvailable = FALSE; + pPsdScan->nAntDet_Result = 0; + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), BT Response = Fail \n ")); + } + else if (pPsdScan->nPSDMaxValue > (BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION)*100) + { + pPsdScan->nAntDet_Result = 1; + pBoardInfo->btdmAntDetFinish = TRUE; + pBoardInfo->btdmAntNumByAntDet = 2; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Detect Result = 2-Ant, Bad-Isolation!! \n")); + } + else if (pPsdScan->nPSDMaxValue > (BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION+pPsdScan->nAntDet_ThresOffset)*100) + { + pPsdScan->nAntDet_Result = 2; + pBoardInfo->btdmAntDetFinish = TRUE; + pBoardInfo->btdmAntNumByAntDet = 2; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Detect Result = 2-Ant, Good-Isolation!! \n")); + } + else if (pPsdScan->nPSDMaxValue > (BT_8723B_1ANT_ANTDET_PSDTHRES_1ANT)*100) + { + pPsdScan->nAntDet_Result = 3; + pBoardInfo->btdmAntDetFinish = TRUE; + pBoardInfo->btdmAntNumByAntDet = 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Detect Result = 1-Ant!!\n")); + } + else + { + pPsdScan->nAntDet_Result = 4; + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Detect Result = 1-Ant, un-certainity!!\n")); + } + + state = 99; + break; + case 99: //restore setup + + //Set AFH mask off at WiFi channel 2472MHz +/- 10MHz + H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = 0x0; + H2C_Parameter[2] = 0x0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Set AFH on, Cent-Ch= %d, Mask=%d\n", + H2C_Parameter[1],H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); + + //Set Antenna Path + halbtc8723b1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Set Antenna to PTA\n!!")); + + //Resume Coex DM + pBtCoexist->bStopCoexDm = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Resume Coex DM\n!!")); + + //stimulate coex running + halbtc8723b1ant_RunCoexistMechanism(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Stimulate Coex running\n!!")); + + outloop = TRUE; + break; + } + + }while(!outloop); + + + + } + +VOID +halbtc8723b1ant_PSD_AntennaDetectionCheck( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u4Byte AntDetCount = 0, AntDetFailCount = 0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + BOOLEAN bScan, bRoam; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + + + pPsdScan->nAntDet_BTTxTime = 20; //0.42ms*50 = 20ms + pPsdScan->nAntDet_BTLEChannel = 39; + + AntDetCount++; + + pPsdScan->bAntDet_TryCount = AntDetCount; + + if (bScan ||bRoam) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 6; + } + else if(pBtCoexist->btInfo.bBtDisabled) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 11; + } + else if (pCoexSta->nNumOfProfile >= 1) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 7; + } + else if (!pPsdScan->nAntDet_IsAntDetAvailable) //Antenna initial setup is not ready + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 9; + } + else if (pCoexSta->bC2hBtInquiryPage) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 10; + } + else + { + halbtc8723b1ant_PSD_AntennaDetection(pBtCoexist, pPsdScan->nAntDet_BTTxTime, pPsdScan->nAntDet_BTLEChannel); + } + + if (!pBoardInfo->btdmAntDetFinish) + AntDetFailCount++; + + pPsdScan->bAntDet_FailCount = AntDetFailCount; + +} + + +//============================================================ +// work around function start with wa_halbtc8723b1ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8723b1ant_ +//============================================================ +VOID +EXhalbtc8723b1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u1Byte u1Tmp=0x0; + u2Byte u2Tmp=0x0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx Execute 8723b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n")); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("Ant Det Finish = %s, Ant Det Number = %d\n", + (pBoardInfo->btdmAntDetFinish? "Yes":"No"), pBoardInfo->btdmAntNumByAntDet)); + + pBtCoexist->bStopCoexDm = TRUE; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20); + + // enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. + 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); + + // + // S0 or S1 setting and Local register setting(By the setting fw can get ant number, S0/S1, ... info) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + 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) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } +} + +VOID +EXhalbtc8723b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8723b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8723b1ant_InitHwConfig(pBtCoexist, TRUE, bWifiOnly); + pBtCoexist->bStopCoexDm = FALSE; +} + +VOID +EXhalbtc8723b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + pBtCoexist->bStopCoexDm = FALSE; + + halbtc8723b1ant_InitCoexDm(pBtCoexist); + + halbtc8723b1ant_QueryBtInfo(pBtCoexist); +} + +VOID +EXhalbtc8723b1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u2Byte u2Tmp[4]; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + static u1Byte PopReportIn10s = 0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + if(pBtCoexist->bStopCoexDm) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + if (pPsdScan->bAntDet_TryCount == 0) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Ant PG Num/ Mech/ Pos", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos); + CL_PRINTF(cliBuf); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d (%d/%d/%d)", "Ant PG Num/ Mech(Ant_Det)/ Pos", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNumByAntDet, pBoardInfo->btdmAntPos, + pPsdScan->bAntDet_TryCount, pPsdScan->bAntDet_FailCount, pPsdScan->nAntDet_Result); + CL_PRINTF(cliBuf); + + if (pBoardInfo->btdmAntDetFinish) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "Ant Det PSD Value", pPsdScan->nAntDet_PeakVal); + CL_PRINTF(cliBuf); + } + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)/ %c", "Version Coex/ Fw/ Patch/ Cut", \ + GLCoexVerDate8723b1Ant, GLCoexVer8723b1Ant, fwVer, btPatchVer, btPatchVer, pCoexSta->nCutVersion+65); + CL_PRINTF(cliBuf); + + 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); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "WifibHiPri/ Ccklock/ CckEverLock", \ + (pCoexSta->bWiFiIsHighPriTask? "Yes":"No"), + (pCoexSta->bCCKLock? "Yes":"No"), + (pCoexSta->bCCKEverLock? "Yes":"No")); + CL_PRINTF(cliBuf); + + // 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); + + 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": + ( (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + pCoexSta->btRssi, pCoexSta->btRetryCnt, pCoexSta->popEventCnt); + CL_PRINTF(cliBuf); + + if (PopReportIn10s >= 5) + { + pCoexSta->popEventCnt = 0; + PopReportIn10s = 0; + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d / %d / %d", "SCO/HID/PAN/A2DP/NameReq/WHQL", \ + pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist, pCoexSta->bC2hBtRemoteNameReq, pCoexSta->bBtWhckTest ); + 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/ %d", "A2DP Rate/Bitpool", \ + (btInfoExt&BIT0)? "BR":"EDR", pCoexSta->nA2DPBitPool); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723b1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism] (before Manual)============"); + } + else + { + 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", "SM[LowPenaltyRA]", \ + pCoexDm->bCurLowPenaltyRa); + 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); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism] (before Manual) ============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + } + + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + if (pBoardInfo->btdmAntNumByAntDet == 2) + { + if (pCoexDm->bCurPsTdmaOn) + psTdmaCase = psTdmaCase +100; //for WiFi RSSI low or BT RSSI low + else + psTdmaCase = 1; //always translate to TDMA(off,1) for TDMA-off case + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (%s,%s)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, + (pCoexDm->bCurPsTdmaOn? "On":"Off"), + (pCoexDm->bAutoTdmaAdjust? "Adj":"Fix") ); + + 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", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + + /* + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \ + pCoexDm->errorCondition); + CL_PRINTF(cliBuf); + */ + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "backup ARFR1/ARFR2/RL/AMaxTime", \ + pCoexDm->backupArfrCnt1, pCoexDm->backupArfrCnt2, pCoexDm->backupRetryLimit, pCoexDm->backupAmpduMaxTime); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + u2Tmp[0] = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "0x430/0x434/0x42a/0x456", \ + u4Tmp[0], u4Tmp[1], u2Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6cc); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/0x6cc/0x880[29:25]", \ + u1Tmp[0], u4Tmp[0], (u4Tmp[1]&0x3e000000) >> 25); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x764); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x948/ 0x67[5] / 0x764 / 0x76e", \ + u4Tmp[0], ((u1Tmp[0]&0x20)>> 5), (u4Tmp[1] & 0xffff), u1Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x92c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x930); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x944); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", \ + u4Tmp[0]&0x3, u4Tmp[1]&0xff, u4Tmp[2]&0x3); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x39); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u1Tmp[2] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x64); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x38[11]/0x40/0x4c[24:23]/0x64[0]", \ + ((u1Tmp[0] & 0x8)>>3), u1Tmp[1], ((u4Tmp[0]&0x01800000)>>23), u1Tmp[2]&0x1); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(dig)/0x49c(null-drop)", \ + u4Tmp[0]&0xff, u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcf0); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + + faOfdm = ((u4Tmp[0]&0xffff0000) >> 16) + ((u4Tmp[1]&0xffff0000) >> 16) + (u4Tmp[1] & 0xffff) + (u4Tmp[2] & 0xffff) + \ + ((u4Tmp[3]&0xffff0000) >> 16) + (u4Tmp[3] & 0xffff) ; + faCck = (u1Tmp[0] << 8) + u1Tmp[1]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "OFDM-CCA/OFDM-FA/CCK-FA", \ + 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); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 1) + //halbtc8723b1ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8723b1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp=0; + + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + 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_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + + halbtc8723b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8723b1ant_InitCoexDm(pBtCoexist); + halbtc8723b1ant_QueryBtInfo(pBtCoexist); + + pCoexSta->bUnderIps = FALSE; + } +} + +VOID +EXhalbtc8723b1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8723b1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + u1Byte u1Tmpa, u1Tmpb; + u4Byte u4Tmp; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm ) + return; + + if(BTC_SCAN_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + pPsdScan->nAntDet_IsAntDetAvailable = 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); + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } + + if(pBtCoexist->btInfo.bBtDisabled) + return; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + halbtc8723b1ant_QueryBtInfo(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8723b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8723b1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_SCAN_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8723b1ant_ActionWifiNotConnectedScan(pBtCoexist); + } + else // wifi is connected + { + halbtc8723b1ant_ActionWifiConnectedScan(pBtCoexist); + } + } + else if(BTC_SCAN_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8723b1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8723b1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_ASSOCIATE_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + pPsdScan->nAntDet_IsAntDetAvailable = 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); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + pCoexDm->nArpCnt = 0; + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + //pCoexDm->nArpCnt = 0; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8723b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8723b1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_ASSOCIATE_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + halbtc8723b1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8723b1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8723b1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8723b1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + BOOLEAN bWifiUnderBMode = FALSE; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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); + pPsdScan->nAntDet_IsAntDetAvailable = TRUE; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + //Set CCK Tx/Rx high Pri except 11b mode + if (bWifiUnderBMode) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x00); //CCK Rx + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x10); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); //CCK Rx + } + + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + pCoexDm->nArpCnt = 0; + + 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 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + //H2C_Parameter[0] = 0x1; + H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8723b1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE, bUnder4way=FALSE; + u1Byte aggBufSize=5; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + if (BTC_PACKET_ARP == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet ARP notify\n")); + + pCoexDm->nArpCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ARP Packet Count = %d\n", pCoexDm->nArpCnt)); + + if((pCoexDm->nArpCnt >= 10) && (!bUnder4way)) // if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet DHCP or EAPOL notify\n")); + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet [Type = %d] notify\n", type)); + } + + pCoexSta->specialPktPeriodCnt = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8723b1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8723b1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8723b1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8723b1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8723b1ant_ActionHs(pBtCoexist); + return; + } + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + ( (BTC_PACKET_ARP == type ) && (pCoexSta->bWiFiIsHighPriTask) ) ) + { + halbtc8723b1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + } +} + +VOID +EXhalbtc8723b1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bBtBusy=FALSE; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8723B_1ANT_MAX) + rspSource = BT_INFO_SRC_8723B_1ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + // 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] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btRetryCnt >= 1) + pCoexSta->popEventCnt++; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtRemoteNameReq = TRUE; + else + pCoexSta->bC2hBtRemoteNameReq = FALSE; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2-90; + //pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + if (pCoexSta->btInfoC2h[rspSource][1] == 0x49) + { + pCoexSta->nA2DPBitPool = + pCoexSta->btInfoC2h[rspSource][6]; + } + else + pCoexSta->nA2DPBitPool = 0; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + +#if BT_8723B_1ANT_ANTDET_ENABLE +#if BT_8723B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE + if ((pBoardInfo->btdmAntDetFinish) && (pBoardInfo->btdmAntNumByAntDet == 2)) + { + if(pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x1\n")); + + //BT TRx Mask un-lock 0x2c[0], 0x30[0] = 1 + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x2c, 0x7c45); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x30, 0x7c45); + + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x1); + } + } + else +#endif +#endif + + { + if(!pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); + + //BT TRx Mask lock 0x2c[0], 0x30[0] = 0 + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x2c, 0x7c44); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x30, 0x7c44); + } + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if(pCoexSta->btInfoExt & BIT1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if(pCoexSta->btInfoExt & BIT3) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8723b1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8723b1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8723B_1ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + pCoexSta->nNumOfProfile = 0; + + // set link exist status + if(!(btInfo&BT_INFO_8723B_1ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + + pCoexSta->bBtHiPriLinkExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8723B_1ANT_B_FTP) + { + pCoexSta->bPanExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8723B_1ANT_B_A2DP) + { + pCoexSta->bA2dpExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8723B_1ANT_B_HID) + { + pCoexSta->bHidExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8723B_1ANT_B_SCO_ESCO) + { + pCoexSta->bScoExist = TRUE; + pCoexSta->nNumOfProfile++; + } + else + pCoexSta->bScoExist = FALSE; + + if ((pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) &&( pCoexSta->bScoExist == FALSE)) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + { + pCoexSta->bHidExist = TRUE; + pCoexSta->wrongProfileNotification++; + pCoexSta->nNumOfProfile++; + btInfo = btInfo | 0x28; + } + } + + //Add Hi-Pri Tx/Rx counter to avoid false detection + if (((pCoexSta->bHidExist) || (pCoexSta->bScoExist)) && (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->bBtHiPriLinkExist = TRUE; + + if((btInfo&BT_INFO_8723B_1ANT_B_ACL_BUSY) && (pCoexSta->nNumOfProfile == 0)) + { + if (pCoexSta->lowPriorityTx + pCoexSta->lowPriorityRx >= 160) + { + pCoexSta->bPanExist = TRUE; + pCoexSta->nNumOfProfile++; + pCoexSta->wrongProfileNotification++; + btInfo = btInfo | 0x88; + } + } + } + + halbtc8723b1ant_UpdateBtLinkInfo(pBtCoexist); + + btInfo = btInfo & 0x1f; //mask profile bit for connect-ilde identification ( for CSR case: A2DP idle --> 0x41) + + if(!(btInfo&BT_INFO_8723B_1ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8723B_1ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8723B_1ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8723B_1ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8723B_1ANT_B_ACL_BUSY) + { + if(BT_8723B_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus) + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8723B_1ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + 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) ) + bBtBusy = TRUE; + else + bBtBusy = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + halbtc8723b1ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8723b1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa,u1Tmpb, u1Tmpc; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF Status notify\n")); + + if(BTC_RF_ON == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned ON!!\n")); + pBtCoexist->bStopCoexDm = FALSE; + } + else if(BTC_RF_OFF == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned OFF!!\n")); + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + 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); + pBtCoexist->bStopCoexDm = TRUE; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u1Tmpc = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb, u1Tmpc)); + + } +} + +VOID +EXhalbtc8723b1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8723b1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8723b1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + 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); + + EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + pBtCoexist->bStopCoexDm = TRUE; +} + +VOID +EXhalbtc8723b1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + + 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_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); + + pBtCoexist->bStopCoexDm = TRUE; + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + pBtCoexist->bStopCoexDm = FALSE; + halbtc8723b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8723b1ant_InitCoexDm(pBtCoexist); + halbtc8723b1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8723b1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], *****************Coex DM Reset*****************\n")); + + halbtc8723b1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x2, 0xfffff, 0x0); + halbtc8723b1ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8723b1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8723b1Ant, GLCoexVer8723b1Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8723B_1ANT == 0) + halbtc8723b1ant_QueryBtInfo(pBtCoexist); + halbtc8723b1ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8723b1ant_MonitorBtCtr(pBtCoexist); + halbtc8723b1ant_MonitorWiFiCtr(pBtCoexist); +#if BT_8723B_1ANT_ANTDET_ENABLE + halbtc8723b1ant_MonitorBtEnableDisable(pBtCoexist); +#endif + + if ( (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx < 50) && (pBtLinkInfo->bHidExist == TRUE)) + { + pBtLinkInfo->bHidExist = FALSE; + } + + if( halbtc8723b1ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust ) + { + halbtc8723b1ant_RunCoexistMechanism(pBtCoexist); + } + + pCoexSta->specialPktPeriodCnt++; + + // sample to set bt to execute Ant detection + //pBtCoexist->fBtcSetBtAntDetection(pBtCoexist, 20, 14); +/* + 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 + ) +{ + static u4Byte AntDetCount = 0, AntDetFailCount = 0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + BOOLEAN bScan, bRoam; + +#if BT_8723B_1ANT_ANTDET_ENABLE + + if (seconds == 0) + { + pPsdScan->bAntDet_TryCount = 0; + pPsdScan->bAntDet_FailCount = 0; + AntDetCount = 0; + AntDetFailCount = 0; + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + return; + } + + if (!pBoardInfo->btdmAntDetFinish) + { + pPsdScan->nAntDet_IntevalCount = pPsdScan->nAntDet_IntevalCount+2; + + if (pPsdScan->nAntDet_IntevalCount >= BT_8723B_1ANT_ANTDET_RETRY_INTERVAL) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna Det Timer is up, Try Detect!!\n")); + halbtc8723b1ant_PSD_AntennaDetectionCheck(pBtCoexist); + + if (pBoardInfo->btdmAntDetFinish) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna Det Success!!\n")); +#if 1 + if (pBoardInfo->btdmAntNumByAntDet == 2) + halbtc8723b1ant_MechanismSwitch(pBtCoexist, TRUE); + else + halbtc8723b1ant_MechanismSwitch(pBtCoexist, FALSE); +#endif + } + else + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna Det Fail!!\n")); + + pPsdScan->nAntDet_IntevalCount = 0; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("xxxxxxxxxxxxxxxx AntennaDetect(), Antenna Det Timer is not up! (%d)\n", pPsdScan->nAntDet_IntevalCount)); + } + + } +#endif + + +/* + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam); + + + pPsdScan->nAntDet_BTTxTime = seconds; //0.42ms*50 = 20ms + pPsdScan->nAntDet_BTLEChannel = centFreq; + + if (seconds == 0) + { + pPsdScan->bAntDet_TryCount = 0; + pPsdScan->bAntDet_FailCount = 0; + AntDetCount = 0; + AntDetFailCount = 0; + pBoardInfo->btdmAntDetFinish = FALSE; + pBoardInfo->btdmAntNumByAntDet = 1; + return; + } + else + { + AntDetCount++; + + pPsdScan->bAntDet_TryCount = AntDetCount; + + if (bScan ||bRoam) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 6; + } + else if (pCoexSta->nNumOfProfile >= 1) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 7; + } + else if (!pPsdScan->nAntDet_IsAntDetAvailable) //Antenna initial setup is not ready + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 9; + } + else if (pCoexSta->bC2hBtInquiryPage) + { + pBoardInfo->btdmAntDetFinish = FALSE; + pPsdScan->nAntDet_Result = 10; + } + else + { + //halbtc8723b1ant_PSD_AntennaDetection(pBtCoexist, pPsdScan->nAntDet_BTTxTime, pPsdScan->nAntDet_BTLEChannel); + } + + if (!pBoardInfo->btdmAntDetFinish) + AntDetFailCount++; + + pPsdScan->bAntDet_FailCount = AntDetFailCount; + } +*/ +} + +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_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + +#if BT_8723B_1ANT_ANTDET_ENABLE + if (pPsdScan->bAntDet_TryCount != 0) + { + halbtc8723b1ant_PSD_ShowAntennaDetectResult(pBtCoexist); + + if (pBoardInfo->btdmAntDetFinish) + halbtc8723b1ant_PSD_ShowData(pBtCoexist); + return; + } +#endif + + //halbtc8723b1ant_ShowPSDData(pBtCoexist); +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.h new file mode 100644 index 00000000..8e70ac66 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b1Ant.h @@ -0,0 +1,337 @@ +//=========================================== +// The following is for 8723B 1ANT BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8723B_1ANT 1 + +#define BT_INFO_8723B_1ANT_B_FTP BIT7 +#define BT_INFO_8723B_1ANT_B_A2DP BIT6 +#define BT_INFO_8723B_1ANT_B_HID BIT5 +#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723B_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT 2 + +#define BT_8723B_1ANT_WIFI_NOISY_THRESH 50 //30 //max: 255 + +//for Antenna detection +#define BT_8723B_1ANT_ANTDET_PSDTHRES_BACKGROUND 50 +#define BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_BADISOLATION 70 +#define BT_8723B_1ANT_ANTDET_PSDTHRES_2ANT_GOODISOLATION 55 +#define BT_8723B_1ANT_ANTDET_PSDTHRES_1ANT 35 +#define BT_8723B_1ANT_ANTDET_RETRY_INTERVAL 10 //retry timer if ant det is fail, unit: second +#define BT_8723B_1ANT_ANTDET_ENABLE 0 +#define BT_8723B_1ANT_ANTDET_COEXMECHANISMSWITCH_ENABLE 0 + +typedef enum _BT_INFO_SRC_8723B_1ANT{ + BT_INFO_SRC_8723B_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8723B_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723B_1ANT_MAX +}BT_INFO_SRC_8723B_1ANT,*PBT_INFO_SRC_8723B_1ANT; + +typedef enum _BT_8723B_1ANT_BT_STATUS{ + BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8723B_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8723B_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_1ANT_BT_STATUS_MAX +}BT_8723B_1ANT_BT_STATUS,*PBT_8723B_1ANT_BT_STATUS; + +typedef enum _BT_8723B_1ANT_WIFI_STATUS{ + BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8723B_1ANT_WIFI_STATUS_MAX +}BT_8723B_1ANT_WIFI_STATUS,*PBT_8723B_1ANT_WIFI_STATUS; + +typedef enum _BT_8723B_1ANT_COEX_ALGO{ + BT_8723B_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723B_1ANT_COEX_ALGO_SCO = 0x1, + BT_8723B_1ANT_COEX_ALGO_HID = 0x2, + BT_8723B_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8723B_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8723B_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8723B_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8723B_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8723B_1ANT_COEX_ALGO_MAX = 0xb, +}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; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; + u4Byte nArpCnt; + + u1Byte errorCondition; +} COEX_DM_8723B_1ANT, *PCOEX_DM_8723B_1ANT; + +typedef struct _COEX_STA_8723B_1ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + BOOLEAN bBtHiPriLinkExist; + u1Byte nNumOfProfile; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte specialPktPeriodCnt; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + s1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8723B_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8723B_1ANT_MAX]; + BOOLEAN bBtWhckTest; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtRemoteNameReq; + BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue + u1Byte btRetryCnt; + u1Byte btInfoExt; + u4Byte popEventCnt; + u1Byte nScanAPNum; + + u4Byte nCRCOK_CCK; + u4Byte nCRCOK_11g; + u4Byte nCRCOK_11n; + u4Byte nCRCOK_11nAgg; + + u4Byte nCRCErr_CCK; + u4Byte nCRCErr_11g; + u4Byte nCRCErr_11n; + u4Byte nCRCErr_11nAgg; + + BOOLEAN bCCKLock; + BOOLEAN bPreCCKLock; + BOOLEAN bCCKEverLock; + u1Byte nCoexTableType; + + BOOLEAN bForceLpsOn; + u4Byte wrongProfileNotification; + + u1Byte nA2DPBitPool; + u1Byte nCutVersion; +}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 +#define BT_8723B_1ANT_ANTDET_BUF_LEN 16 + +typedef struct _PSDSCAN_STA_8723B_1ANT{ + +u4Byte nAntDet_BTLEChannel; //BT LE Channel ex:2412 +u4Byte nAntDet_BTTxTime; +u4Byte nAntDet_PrePSDScanPeakVal; +BOOLEAN nAntDet_IsAntDetAvailable; +u4Byte nAntDet_PSDScanPeakVal; +BOOLEAN nAntDet_IsBTReplyAvailable; +u4Byte nAntDet_PSDScanPeakFreq; + +u1Byte nAntDet_Result; +u1Byte nAntDet_PeakVal[BT_8723B_1ANT_ANTDET_BUF_LEN]; +u1Byte nAntDet_PeakFreq[BT_8723B_1ANT_ANTDET_BUF_LEN]; +u4Byte bAntDet_TryCount; +u4Byte bAntDet_FailCount; +u4Byte nAntDet_IntevalCount; +u4Byte nAntDet_ThresOffset; + +u4Byte nRealCentFreq; +s4Byte nRealOffset; +u4Byte nRealSpan; + +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; +BOOLEAN bIsPSDRunning; +BOOLEAN bIsPSDShowMaxOnly; +} PSDSCAN_STA_8723B_1ANT, *PPSDSCAN_STA_8723B_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8723b1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8723b1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8723b1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8723b1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +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_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.c new file mode 100644 index 00000000..6273bcc7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.c @@ -0,0 +1,4933 @@ +//============================================================ +// Description: +// +// This file is for RTL8723B Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8723b2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8723B_2ANT GLCoexDm8723b2Ant; +static PCOEX_DM_8723B_2ANT pCoexDm=&GLCoexDm8723b2Ant; +static COEX_STA_8723B_2ANT GLCoexSta8723b2Ant; +static PCOEX_STA_8723B_2ANT pCoexSta=&GLCoexSta8723b2Ant; + +const char *const GLBtInfoSrc8723b2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8723b2Ant=20150119; +u4Byte GLCoexVer8723b2Ant=0x44; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8723b2ant_ +//============================================================ +u1Byte +halbtc8723b2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8723b2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8723b2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + + bPreBtDisabled = bBtDisabled; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + if(bBtDisabled) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + + +VOID +halbtc8723b2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +VOID +halbtc8723b2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if( (pCoexSta->lowPriorityTx > 1050) && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->popEventCnt++; + + if ( (pCoexSta->lowPriorityRx >= 950) && (pCoexSta->lowPriorityRx >= pCoexSta->lowPriorityTx) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + 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 + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +BOOLEAN +halbtc8723b2ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + 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; +} + +VOID +halbtc8723b2ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + +#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) // profile from bt patch + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } +#else // profile from bt stack + pBtLinkInfo->bBtLinkExist = pStackInfo->bBtLinkExist; + pBtLinkInfo->bScoExist = pStackInfo->bScoExist; + pBtLinkInfo->bA2dpExist = pStackInfo->bA2dpExist; + pBtLinkInfo->bPanExist = pStackInfo->bPanExist; + pBtLinkInfo->bHidExist = pStackInfo->bHidExist; + + //for win-8 stack HID report error + if(!pStackInfo->bHidExist) + pStackInfo->bHidExist = pCoexSta->bHidExist; //sync BTInfo with BT firmware and stack + // when stack HID report error, here we use the info from bt fw. + if(!pStackInfo->bBtLinkExist) + pStackInfo->bBtLinkExist = pCoexSta->bBtLinkExist; +#endif + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8723b2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8723B_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { +#if 0 + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else +#endif + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8723b2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8723b2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte decBtPwrLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = decBtPwrLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power level = %d, FW write 0x62=0x%x\n", + decBtPwrLvl, H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, H2C_Parameter); +} + +VOID +halbtc8723b2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte decBtPwrLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power level = %d\n", + (bForceExec? "force to":""), decBtPwrLvl)); + pCoexDm->curBtDecPwrLvl = decBtPwrLvl; + + if(!bForceExec) + { + if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl) + return; + } + halbtc8723b2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl); + + pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl; +} + +VOID +halbtc8723b2ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8723b2ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8723b2ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8723b2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8723b2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8723b2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8723b2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8723b2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8723b2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!")) ); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8723b2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + //return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8723b2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8723b2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x883, 0x3e, val); +} + +VOID +halbtc8723b2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8723b2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8723b2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8723b2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8723b2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8723b2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc05, 0x30, 0x1); + } +} + +VOID +halbtc8723b2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8723b2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8723b2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + //=================BB AGC Gain Table + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6e1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6d1B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6c1C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6b1D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6a1E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x691F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x68200001); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xaa1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa91B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa81C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa71D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa61E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa51F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa4200001); + } + + + //=================RF Gain + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + if(bAgcTableEn) + { + rssiAdjustVal = 8; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + +VOID +halbtc8723b2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8723b2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8723b2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8723b2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8723b2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8723b2ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5afa5afa, 0xffffff, 0x3); + break; + case 2: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5ada5ada, 0x5ada5ada, 0xffffff, 0x3); + break; + case 3: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffffff, 0x3); + break; + case 5: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffffff, 0x3); + break; + case 6: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 8: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + halbtc8723b2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + 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; + } +} + +VOID +halbtc8723b2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + 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; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (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, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8723b2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8723b2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + 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; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = byte5; + + pCoexDm->psTdmaPara[0] = byte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = byte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + +VOID +halbtc8723b2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + /* + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + */ + + //halbtc8723b2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + halbtc8723b2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8723b2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + //halbtc8723b2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + //halbtc8723b2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + //halbtc8723b2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8723b2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte fwVer=0, u4Tmp=0; + BOOLEAN bPgExtSwitch=FALSE; + BOOLEAN bUseExtSwitch=FALSE; + u1Byte H2C_Parameter[2] ={0}; + + 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 + + if((fwVer>0 && fwVer<0xc0000) || bPgExtSwitch) + bUseExtSwitch = TRUE; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x39, 0x8, 0x1); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x974, 0xff); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x944, 0x3, 0x3); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x930, 0x77); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); + + if(fwVer >= 0x180000) + { + /* 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, 0x18); + } + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); //WiFi 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) + { + //tell firmware "no antenna inverse" + H2C_Parameter[0] = 0; + } + else + { + //tell firmware "antenna inverse" + H2C_Parameter[0] = 1; + } + + if (bUseExtSwitch) + { + //ext switch type + H2C_Parameter[1] = 1; + } + else + { + //int switch type + H2C_Parameter[1] = 0; + } + 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) + { + if (bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); // fixed internal switch S1->WiFi, S0->BT + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x1); // ext switch main at wifi + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x92c, 0x3, 0x2); // ext switch aux at wifi + break; + } + } + else // internal switch + { + if (bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp |= BIT23; + u4Tmp &=~BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + } + + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x0); //fixed external switch S1->Main, S0->Aux + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x0); // fixed internal switch S1->WiFi, S0->BT + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x948, 0x280); // fixed internal switch S0->WiFi, S1->BT + break; + } + } +} + +VOID +halbtc8723b2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + u1Byte wifiRssiState1, btRssiState; + s1Byte nWiFiDurationAdjust = 0x0; + u1Byte psTdmaByte4Modify = 0x0; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + + 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); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if (!(BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) && bTurnOn) + { + type = type +100; //for WiFi RSSI low or BT RSSI low + pCoexDm->bIsSwitchTo1dot5Ant = TRUE; + } + else + { + pCoexDm->bIsSwitchTo1dot5Ant = FALSE; + } + + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum <= 5) + { + if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else + nWiFiDurationAdjust = 5; + } + else if (pCoexSta->nScanAPNum <= 20) + { + if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else + nWiFiDurationAdjust = 0; + } + else if (pCoexSta->nScanAPNum <= 40) + { + if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else + nWiFiDurationAdjust = -5; + } + else + { + if (pCoexSta->nA2DPBitPool >= 45) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nA2DPBitPool >= 35) + nWiFiDurationAdjust = -10; + else + nWiFiDurationAdjust = -10; + } + + if ( (pBtLinkInfo->bSlaveRole == TRUE) && (pBtLinkInfo->bA2dpExist) ) + psTdmaByte4Modify = 0x1; //0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) + + + if(bTurnOn) + { + switch(type) + { + case 1: + default: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c+nWiFiDurationAdjust, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 2: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d+nWiFiDurationAdjust, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 3: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 4: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 5: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c+nWiFiDurationAdjust, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 6: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d+nWiFiDurationAdjust, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 7: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 8: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x10, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 9: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c+nWiFiDurationAdjust, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 10: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d+nWiFiDurationAdjust, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 11: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 12: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 13: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c+nWiFiDurationAdjust, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 14: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d+nWiFiDurationAdjust, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 15: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 16: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0x70, 0x90|psTdmaByte4Modify); + break; + case 17: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x90); + break; + case 18: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 71: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c+nWiFiDurationAdjust, 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 171: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x3a+nWiFiDurationAdjust, 0x03, 0x70, 0x50|psTdmaByte4Modify); + break; + case 102: + case 106: + case 110: + case 114: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x2d+nWiFiDurationAdjust, 0x03, 0x70, 0x50|psTdmaByte4Modify); + break; + case 103: + case 107: + case 111: + case 115: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1c, 0x03, 0x70, 0x50|psTdmaByte4Modify); + break; + case 104: + case 108: + case 112: + case 116: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x10, 0x03, 0x70, 0x50|psTdmaByte4Modify); + break; + case 109: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90|psTdmaByte4Modify); + break; + case 113: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x70, 0x90|psTdmaByte4Modify); + break; + case 121: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90|psTdmaByte4Modify); + break; + case 22: + case 122: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x35, 0x03, 0x71, 0x11); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 0: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + case 1: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + break; + default: + halbtc8723b2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + 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); + + // 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); +} + +VOID +halbtc8723b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // 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); + + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + pCoexSta->popEventCnt = 0; + +} + +VOID +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); + + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi link process + BT Inq/Page!!\n")); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT Inq/Page!!\n")); + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [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)) + { + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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 + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-connected idle!!\n")); + + 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); + + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + 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); + + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else if(BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bBtHsOn) + return FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + 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); + + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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 + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + //bCommon = FALSE; + bCommon = halbtc8723b2ant_ActionWifiIdleProcess(pBtCoexist); + } + } + } + + return bCommon; +} +VOID +halbtc8723b2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 71) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 71) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +// SCO only or SCO+PAN(HS) +VOID +halbtc8723b2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 4); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for SCO quality at 11b/g mode + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + else //for SCO quality & wifi performance balance at 11n mode + { + 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 + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x4); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x4); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x4); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x4); + } + } +} + + +VOID +halbtc8723b2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8723b2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8723b2ant_BtRssiState(2, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //for HID quality & wifi performance balance at 11n mode + { + 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) ) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8723b2ant_ActionA2dp( + 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); + 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) && 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, 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 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + return; + + } + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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) ) + { + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + else + { + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8723b2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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); + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8723b2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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) ) + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + else + { + halbtc8723b2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + + +//PAN(HS) only +VOID +halbtc8723b2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + 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); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8723b2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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 + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else + { + halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8723b2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + } + else + { + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + } + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + } + else + { + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8723b2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8723b2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + 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->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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); + } + + 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, 3); + else + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else + { + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8723b2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + 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(3, BT_8723B_2ANT_BT_RSSI_COEXSWITCH_THRES, 37); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8723b2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x5); + + halbtc8723b2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + else + { // only 802.11N mode we have to dec bt power to 4 degree + if(BTC_RSSI_HIGH(btRssiState)) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + // need to check ap Number of Not + if(apNum < 10) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + else + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + } + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8723b2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + 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) ) + { + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else + { + halbtc8723b2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8723b2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8723b2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +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 + ) +{ + 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; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if(pCoexSta->bBtWhckTest) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8723b2ant_ActionBtInquiry(pBtCoexist); + return; + } + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [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; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8723b2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8723B_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8723b2ant_ActionSco(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8723b2ant_ActionHid(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8723b2ant_ActionA2dp(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8723b2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8723b2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8723b2ant_ActionPanHs(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8723b2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8723b2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8723b2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8723B_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8723b2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8723b2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8723b2ant_WifiOffHwCfg( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bIsInMpMode = FALSE; + u1Byte H2C_Parameter[2] ={0}; + u4Byte fwVer=0; + + // set wlan_act to low + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); //WiFi goto standby while GNT_BT 0-->1 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + if(fwVer >= 0x180000) + { + /* Use H2C to set GNT_BT to HIGH */ + H2C_Parameter[0] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, &bIsInMpMode); + if(!bIsInMpMode) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x0); //BT select s0/s1 is controlled by BT + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x67, 0x20, 0x1); //BT select s0/s1 is controlled by WiFi +} + +VOID +halbtc8723b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0, fwVer; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + //0xf0[15:12] --> Chip Cut information + pCoexSta->nCutVersion = (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xf1) & 0xf0) >> 4; + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + //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, 0x4); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); +} + +//============================================================ +// work around function start with wa_halbtc8723b2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8723b2ant_ +//============================================================ +VOID +EXhalbtc8723b2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u2Byte u2Tmp=0x0; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x67, 0x20); + + // enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. + u2Tmp = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x2); + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x2, u2Tmp|BIT0|BIT1); + + 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) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + if(pBtCoexist->chipInterface == BTC_INTF_USB) + { + // fixed at S0 for USB interface + u1Tmp |= 0x1; // antenna inverse + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp); + } + else + { + // for PCIE and SDIO interface, we check efuse 0xc3[6] + if(pBoardInfo->singleAntPath == 0) + { + } + else if(pBoardInfo->singleAntPath == 1) + { + // set to S0 + u1Tmp |= 0x1; // antenna inverse + } + + if(pBtCoexist->chipInterface == BTC_INTF_PCI) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } +} + +VOID +EXhalbtc8723b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8723b2ant_InitHwConfig(pBtCoexist, TRUE); +} + +VOID +EXhalbtc8723b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8723b2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8723b2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + static u1Byte PopReportIn10s = 0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)/ %c", "Version Coex/ Fw/ Patch/ Cut", \ + GLCoexVerDate8723b2Ant, GLCoexVer8723b2Ant, fwVer, btPatchVer, btPatchVer, pCoexSta->nCutVersion+65); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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": + ( (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + pCoexSta->btRssi-100, pCoexSta->btRetryCnt, pCoexSta->popEventCnt); + CL_PRINTF(cliBuf); + + if (PopReportIn10s >= 5) + { + pCoexSta->popEventCnt = 0; + PopReportIn10s = 0; + } + + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d / %d / %d", "SCO/HID/PAN/A2DP/NameReq/WHQL", \ + pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist, pCoexSta->bC2hBtRemoteNameReq, pCoexSta->bBtWhckTest ); + 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 / %d", "A2DP Rate/Bitpool", \ + (btInfoExt&BIT0)? "BR":"EDR", pCoexSta->nA2DPBitPool); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723b2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + // Sw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism] (before Manual)============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============"); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism] (before Manual) ============"); + } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + } + + psTdmaCase = pCoexDm->curPsTdma; + + if (pCoexDm->bIsSwitchTo1dot5Ant) + psTdmaCase = psTdmaCase + 100; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (%s,%s)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, + (pCoexDm->bCurPsTdmaOn? "On":"Off"), + (pCoexDm->bAutoTdmaAdjust? "Adj":"Fix") ); + 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); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x778/0x880[29:25]", \ + u1Tmp[0], (u4Tmp[0]&0x3e000000) >> 25); + CL_PRINTF(cliBuf); + + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x948); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x67); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x948/ 0x67[5] / 0x765", \ + u4Tmp[0], ((u1Tmp[0]&0x20)>> 5), u1Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x92c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x930); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x944); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", \ + u4Tmp[0]&0x3, u4Tmp[1]&0xff, u4Tmp[2]&0x3); + CL_PRINTF(cliBuf); + + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x39); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u1Tmp[2] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x64); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x38[11]/0x40/0x4c[24:23]/0x64[0]", \ + ((u1Tmp[0] & 0x8)>>3), u1Tmp[1], ((u4Tmp[0]&0x01800000)>>23), u1Tmp[2]&0x1); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(dig)/0x49c(null-drop)", \ + u4Tmp[0]&0xff, u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcf0); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + + faOfdm = ((u4Tmp[0]&0xffff0000) >> 16) + ((u4Tmp[1]&0xffff0000) >> 16) + (u4Tmp[1] & 0xffff) + (u4Tmp[2] & 0xffff) + \ + ((u4Tmp[3]&0xffff0000) >> 16) + (u4Tmp[3] & 0xffff) ; + faCck = (u1Tmp[0] << 8) + u1Tmp[1]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "OFDM-CCA/OFDM-FA/CCK-FA", \ + 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); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) + //halbtc8723b2ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8723b2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8723b2ant_WifiOffHwCfg(pBtCoexist); + halbtc8723b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + halbtc8723b2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + halbtc8723b2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8723b2ant_InitCoexDm(pBtCoexist); + halbtc8723b2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8723b2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8723b2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x76e=0x%x\n", + u4Tmp, u1Tmpa, u1Tmpb)); +} + +VOID +EXhalbtc8723b2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8723b2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + u1Byte apNum=0; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + if(apNum < 10) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8723b2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8723b2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE; + static BOOLEAN bPreScoExist=FALSE; + u4Byte raMask=0x0; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8723B_2ANT_MAX) + rspSource = BT_INFO_SRC_8723B_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n")); + 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] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btRetryCnt >= 1) + pCoexSta->popEventCnt++; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtRemoteNameReq = TRUE; + else + pCoexSta->bC2hBtRemoteNameReq = FALSE; + + if (pCoexSta->btInfoC2h[rspSource][1] == 0x49) + { + pCoexSta->nA2DPBitPool = + pCoexSta->btInfoC2h[rspSource][6]; + } + else + pCoexSta->nA2DPBitPool = 0; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if (pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x01 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x01\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x01); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8723b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8723b2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if( (pCoexSta->btInfoExt & BIT3) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8723b2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8723b2ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8723B_2ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8723B_2ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8723B_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8723B_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8723B_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8723B_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + + if ( (pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) && (pCoexSta->bScoExist == FALSE)) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + { + pCoexSta->bHidExist = TRUE; + btInfo = btInfo | 0x28; + } + } + } + + halbtc8723b2ant_UpdateBtLinkInfo(pBtCoexist); + + if(!(btInfo&BT_INFO_8723B_2ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8723B_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8723B_2ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8723B_2ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8723B_2ANT_B_ACL_BUSY) + { + pCoexDm->btStatus = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8723B_2ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8723B_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bBtBusy = TRUE; + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8723b2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8723b2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8723b2ant_WifiOffHwCfg(pBtCoexist); + //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); +} + +VOID +EXhalbtc8723b2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + halbtc8723b2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8723b2ant_InitCoexDm(pBtCoexist); + halbtc8723b2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8723b2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + //static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(pCoexSta->disVerInfoCnt <= 5) + { + pCoexSta->disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8723b2Ant, GLCoexVer8723b2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + + if (pCoexSta->disVerInfoCnt == 3) + { + //Antenna config to set 0x765 = 0x0 (GNT_BT control by PTA) after initial + RT_TRACE(COMP_COEX, DBG_LOUD, ("[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_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8723b2ant_MonitorBtCtr(pBtCoexist); + halbtc8723b2ant_MonitorWiFiCtr(pBtCoexist); + + //for some BT speaker that Hi-Pri pkt appear begore start play, this will cause HID exist + if ( (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx < 50) && (pBtLinkInfo->bHidExist == TRUE)) + { + pBtLinkInfo->bHidExist = FALSE; + } + + if( halbtc8723b2ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust) + { + halbtc8723b2ant_RunCoexistMechanism(pBtCoexist); + } +#endif +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.h new file mode 100644 index 00000000..de7a9bda --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8723b2Ant.h @@ -0,0 +1,234 @@ +//=========================================== +// The following is for 8723B 2Ant BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8723B_2ANT 1 + + +#define BT_INFO_8723B_2ANT_B_FTP BIT7 +#define BT_INFO_8723B_2ANT_B_A2DP BIT6 +#define BT_INFO_8723B_2ANT_B_HID BIT5 +#define BT_INFO_8723B_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8723B_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8723B_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8723B_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8723B_2ANT_B_CONNECTION BIT0 + +#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, + BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8723B_2ANT_MAX +}BT_INFO_SRC_8723B_2ANT,*PBT_INFO_SRC_8723B_2ANT; + +typedef enum _BT_8723B_2ANT_BT_STATUS{ + BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8723B_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8723B_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_2ANT_BT_STATUS_MAX +}BT_8723B_2ANT_BT_STATUS,*PBT_8723B_2ANT_BT_STATUS; + +typedef enum _BT_8723B_2ANT_COEX_ALGO{ + BT_8723B_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8723B_2ANT_COEX_ALGO_SCO = 0x1, + BT_8723B_2ANT_COEX_ALGO_HID = 0x2, + BT_8723B_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8723B_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8723B_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8723B_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8723B_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8723B_2ANT_COEX_ALGO_MAX = 0xb, +}BT_8723B_2ANT_COEX_ALGO,*PBT_8723B_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8723B_2ANT{ + // fw mechanism + u1Byte preBtDecPwrLvl; + u1Byte curBtDecPwrLvl; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + BOOLEAN bNeedRecover0x948; + u4Byte backup0x948; + + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + BOOLEAN bIsSwitchTo1dot5Ant; +} COEX_DM_8723B_2ANT, *PCOEX_DM_8723B_2ANT; + +typedef struct _COEX_STA_8723B_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8723B_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8723B_2ANT_MAX]; + BOOLEAN bBtWhckTest; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtRemoteNameReq; + u1Byte btRetryCnt; + u1Byte btInfoExt; + u4Byte popEventCnt; + u1Byte nScanAPNum; + + 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; + + u1Byte nA2DPBitPool; + u1Byte nCutVersion; +}COEX_STA_8723B_2ANT, *PCOEX_STA_8723B_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8723b2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8723b2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8723b2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8723b2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8723b2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8723b2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.c new file mode 100644 index 00000000..b911f31d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.c @@ -0,0 +1,3717 @@ +//============================================================ +// Description: +// +// This file is for RTL8812A Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8812a1Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8812A_1ANT GLCoexDm8812a1Ant; +static PCOEX_DM_8812A_1ANT pCoexDm=&GLCoexDm8812a1Ant; +static COEX_STA_8812A_1ANT GLCoexSta8812a1Ant; +static PCOEX_STA_8812A_1ANT pCoexSta=&GLCoexSta8812a1Ant; + +const char *const GLBtInfoSrc8812a1Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8812a1Ant=20140708; +u4Byte GLCoexVer8812a1Ant=0x52; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8812a1ant_ +//============================================================ +u1Byte +halbtc8812a1ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8812a1ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8812a1ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +//to check 0x430/0x434 is correct?? +VOID +halbtc8812a1ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +//to check 0x42a ?? +VOID +halbtc8812a1ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +//to check 0x456?? +VOID +halbtc8812a1ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8812a1ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8812a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8812a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8812a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8812a1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8812a1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8812a1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8812a1ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8812a1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte dataLen=3; + u1Byte buf[5] = {0}; + + if(!pBtCoexist->btInfo.bBtDisabled) + { + if(!pCoexSta->btInfoQueryCnt || + (pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8812A_1ANT_BT_RSP]-pCoexSta->btInfoQueryCnt)>2) + { + buf[0] = dataLen; + buf[1] = 0x1; // polling enable, 1=enable, 0=disable + buf[2] = 0x2; // polling time in seconds + buf[3] = 0x1; // auto report enable, 1=enable, 0=disable + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_INFO, (PVOID)&buf[0]); + } + } + pCoexSta->btInfoQueryCnt++; +} + +VOID +halbtc8812a1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp, u4Tmp1; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp, u1Tmp1; + s4Byte wifiRssi; + static u1Byte NumOfBtCounterChk = 0; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if( (pCoexSta->lowPriorityTx > 1150) && (!pCoexSta->bC2hBtInquiryPage)) + pCoexSta->popEventCnt++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n", + regHPRx, regHPTx, regLPRx, regLPTx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); + + if ((regHPTx == 0) && (regHPRx ==0) && (regLPTx == 0) && (regLPRx == 0)) + { + NumOfBtCounterChk++; + if (NumOfBtCounterChk >= 3) + { + halbtc8812a1ant_QueryBtInfo(pBtCoexist); + NumOfBtCounterChk = 0; + } + } +} + +//to check registers +VOID +halbtc8812a1ant_MonitorWiFiCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + u2Byte u2Tmp[3]; + s4Byte wifiRssi=0; + BOOLEAN bWifiBusy = FALSE, bWifiUnderBMode = FALSE; + static u1Byte nCCKLockCounter = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + + 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->fBtcRead2Byte(pBtCoexist, 0xf04); + pCoexSta->nCRCOK_11g = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf14); + pCoexSta->nCRCOK_11n = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf10); + pCoexSta->nCRCOK_11nAgg= pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf40); + + pCoexSta->nCRCErr_CCK = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf06); + pCoexSta->nCRCErr_11g = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf16); + pCoexSta->nCRCErr_11n = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf12); + pCoexSta->nCRCErr_11nAgg = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0xf42); + } + + + //reset counter + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xb58, 0x1, 0x1); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xb58, 0x1, 0x0); + + if ( (bWifiBusy) && (wifiRssi >= 30) && (!bWifiUnderBMode)) + { + if ( (pCoexDm->btStatus == BT_8812A_1ANT_BT_STATUS_ACL_BUSY) || + (pCoexDm->btStatus == BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY) || + (pCoexDm->btStatus == BT_8812A_1ANT_BT_STATUS_SCO_BUSY) ) + { + if (pCoexSta->nCRCOK_CCK >(pCoexSta->nCRCOK_11g + pCoexSta->nCRCOK_11n + + pCoexSta->nCRCOK_11nAgg) ) + { + if (nCCKLockCounter < 5) + nCCKLockCounter++; + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + } + else + { + if (nCCKLockCounter > 0) + nCCKLockCounter--; + } + + if (!pCoexSta->bPreCCKLock) + { + + if (nCCKLockCounter >= 5) + pCoexSta->bCCKLock = TRUE; + else + pCoexSta->bCCKLock = FALSE; + } + else + { + if (nCCKLockCounter == 0) + pCoexSta->bCCKLock = FALSE; + else + pCoexSta->bCCKLock = TRUE; + } + + pCoexSta->bPreCCKLock = pCoexSta->bCCKLock; + + +} + +BOOLEAN +halbtc8812a1ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; + BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + } + + return FALSE; +} + +VOID +halbtc8812a1ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8812a1ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8812A_1ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO only\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID only\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP only\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(HS) only\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(EDR) only\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP ==> SCO\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(EDR)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(EDR)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(EDR)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8812a1ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8812a1ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8812a1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +//to check +VOID +halbtc8812a1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + tmpU1 |= BIT0; + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8812a1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8812a1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8812a1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8812a1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8812a1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8812a1ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** CoexTable(%d) **********\n", type)); + + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 4: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 5: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaa5a5a5a, 0xffffff, 0x3); + break; + case 6: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 7: + halbtc8812a1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8812a1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte dataLen=3; + u1Byte buf[5] = {0}; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Ignore Wlan_Act\n", + (bEnable? "Enable":"Disable"))); + + buf[0] = dataLen; + buf[1] = 0x1; // OP_Code + buf[2] = 0x1; // OP_Code_Length + if(bEnable) + buf[3] = 0x1; // OP_Code_Content + else + buf[3] = 0x0; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); +} + +VOID +halbtc8812a1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8812a1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8812a1ant_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 +halbtc8812a1ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8812a1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8812a1ant_SwMechanism( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRA + ) +{ + halbtc8812a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +//to check bForceExec +VOID +halbtc8812a1ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bForceExec, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + u1Byte u1Tmp=0; + + pCoexDm->curAntPosType = antPosType; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb3, 0x77); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x900, 0x00000400); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76d, 0x1); + } + else if(bWifiOff) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb3, 0x77); + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u1Tmp &= ~BIT3; + u1Tmp |= BIT2; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb7, u1Tmp); + } + + if(bForceExec || (pCoexDm->curAntPosType != pCoexDm->preAntPosType)) + { + // ext switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u1Tmp |= BIT3; + u1Tmp &= ~BIT2; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb7, u1Tmp); + break; + case BTC_ANT_PATH_BT: + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u1Tmp &= ~BIT3; + u1Tmp |= BIT2; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb7, u1Tmp); + break; + default: + case BTC_ANT_PATH_PTA: + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u1Tmp |= BIT3; + u1Tmp &= ~BIT2; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb7, u1Tmp); + break; + } + } + + pCoexDm->preAntPosType = pCoexDm->curAntPosType; +} + +VOID +halbtc8812a1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + + +VOID +halbtc8812a1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bTurnOnByCnt=FALSE, bWifiBusy=FALSE, bWiFiNoisy=FALSE; + u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0; + u1Byte psTdmaByte4Val = 0x50, psTdmaByte0Val = 0x51, psTdmaByte3Val = 0x10; + s1Byte nWiFiDurationAdjust = 0x0; + static BOOLEAN bPreWifiBusy=FALSE; + + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if (bWifiBusy != bPreWifiBusy) + { + bForceExec = TRUE; + bPreWifiBusy = bWifiBusy; + } + + if (pCoexDm->bCurPsTdmaOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(off, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum <= 5) + nWiFiDurationAdjust = 2; + else if (pCoexSta->nScanAPNum >= 40) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nScanAPNum >= 20) + nWiFiDurationAdjust = -10; + + 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) ) + { + 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: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, psTdmaByte4Val); + break; + case 1: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x3a+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 2: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x2d+nWiFiDurationAdjust, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 3: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, psTdmaByte4Val); + break; + case 4: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0); + break; + case 5: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x15, 0x3, 0x11, 0x11); + break; + case 6: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x20, 0x3, 0x11, 0x11); + break; + case 7: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0); + break; + case 8: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 9: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x3, psTdmaByte3Val, psTdmaByte4Val); + break; + case 10: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, psTdmaByte0Val, 0x21, 0x03, psTdmaByte3Val, psTdmaByte4Val); + break; + case 12: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50); + break; + case 13: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x12, 0x12, 0x0, psTdmaByte4Val); + break; + case 14: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x21, 0x3, 0x10, psTdmaByte4Val); + break; + case 15: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0); + break; + case 16: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0); + break; + case 18: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 20: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x3f, 0x03, 0x11, 0x10); + break; + case 21: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11); + break; + case 22: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x10); + break; + case 23: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18); + break; + case 24: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18); + break; + case 25: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 26: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + break; + case 27: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98); + break; + case 28: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0); + break; + case 29: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10); + break; + case 31: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58); + break; + case 32: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x3, 0x11, 0x11); + break; + case 33: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xa3, 0x25, 0x3, 0x30, 0x90); + break; + case 34: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50); + break; + case 40: // SoftAP only with no sta associated,BT disable ,TDMA mode for power saving + /* here softap mode screen off will cost 70-80mA for phone */ + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24); + break; + } + } + else + { + + // disable PS tdma + switch(type) + { + case 8: //PTA Control + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + break; + case 0: + default: //Software control, Antenna at BT side + halbtc8812a1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + break; + } + } + rssiAdjustVal =0; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal); + + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +BOOLEAN +halbtc8812a1ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n")); + + //halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + //halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n")); + + //halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + + //halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); + + //halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else + { + if (bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + } + + bCommon = FALSE; + } + + return bCommon; +} + + +VOID +halbtc8812a1ant_TdmaDurationAdjustForAcl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + static BOOLEAN bPreWifiBusy=FALSE; + BOOLEAN bWifiBusy = FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjustForAcl()\n")); + + if(BT_8812A_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifiStatus) + bWifiBusy = TRUE; + else + bWifiBusy = FALSE; + + if( (BT_8812A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 3 && + pCoexDm->curPsTdma != 9 ) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if ( (pCoexSta->lowPriorityTx) > 1150 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { + if( (BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if(result == 1) + { + if( (BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + else //no change + { + /* Bryant Modify + if(bWifiBusy != bPreWifiBusy) //if busy / idle change + { + bPreWifiBusy = bWifiBusy; + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, pCoexDm->curPsTdma); + } + */ + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 9 && + pCoexDm->curPsTdma != 11 ) + { + // recover to previous adjust type + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8812a1ant_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 + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8812a1ant_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: + halbtc8812a1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8812a1ant_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: + halbtc8812a1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + +VOID +halbtc8812a1ant_ActionWifiOnly( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); +} + +VOID +halbtc8812a1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + halbtc8812a1ant_ActionWifiOnly(pBtCoexist); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +//============================================= +// +// Software Coex Mechanism start +// +//============================================= + +// SCO only or SCO+PAN(HS) + +/* +VOID +halbtc8812a1ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); +} + + +VOID +halbtc8812a1ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8812a1ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8812a1ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8812a1ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(HS) only +VOID +halbtc8812a1ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(EDR)+A2DP +VOID +halbtc8812a1ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8812a1ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8812a1ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8812a1ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); +} + +*/ + +//============================================= +// +// Non-Software Coex Mechanism start +// +//============================================= +VOID +halbtc8812a1ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8812a1ant_ActionHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8812a1ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bApEnable=FALSE, bWifiBusy=FALSE, bBtBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if((!bWifiConnected) && (!pCoexSta->bWiFiIsHighPriTask)) + { + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + // SCO/HID/A2DP busy + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if ((pBtLinkInfo->bPanExist) || (bWifiBusy)) + { + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } +} + +VOID +halbtc8812a1ant_ActionBtScoHidOnlyBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // tdma and coex table + + if(pBtLinkInfo->bScoExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else //HID + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } +} + +VOID +halbtc8812a1ant_ActionWifiConnectedBtAclBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + u1Byte btRssiState; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + btRssiState = halbtc8812a1ant_BtRssiState(2, 28, 0); + + if ( (pCoexSta->lowPriorityRx >= 950) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + if(pBtLinkInfo->bHidOnly) //HID + { + halbtc8812a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus); + pCoexDm->bAutoTdmaAdjust = FALSE; + return; + } + else if(pBtLinkInfo->bA2dpOnly) //A2DP + { + if(BT_8812A_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + halbtc8812a1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = TRUE; + } + } + else if ( ((pBtLinkInfo->bA2dpExist) && (pBtLinkInfo->bPanExist)) || + (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist&&pBtLinkInfo->bPanExist) ) //A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if(pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) //HID+A2DP + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->bAutoTdmaAdjust = FALSE; + + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else if( (pBtLinkInfo->bPanOnly) || (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) ) //PAN(OPP,FTP), HID+PAN(OPP,FTP) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + //BT no-profile busy (0x9) + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + pCoexDm->bAutoTdmaAdjust = FALSE; + } +} + +VOID +halbtc8812a1ant_ActionWifiNotConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8812a1ant_ActionWifiNotConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8812a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8812a1ant_ActionWifiNotConnectedAssoAuth( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist) ) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + } + else if (pBtLinkInfo->bPanExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 4); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 2); + } +} + +VOID +halbtc8812a1ant_ActionWifiConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8812a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //Bryant Add + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8812a1ant_ActionWifiConnectedSpecialPacket( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if(pBtLinkInfo->bPanExist) + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8812a1ant_ActionWifiConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiBusy=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + BOOLEAN bUnder4way=FALSE, bApEnable=FALSE; + u4Byte wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect()===>\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + if(bUnder4way) + { + halbtc8812a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n")); + return; + } + + 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) + { + if(bScan) + halbtc8812a1ant_ActionWifiConnectedScan(pBtCoexist); + else + halbtc8812a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + // power save state + if(!bApEnable && BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->btLinkInfo.bHidOnly) + { + if(pBtCoexist->btLinkInfo.bA2dpOnly) //A2DP + { + if(!bWifiBusy) + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else //busy + { + if (pCoexSta->nScanAPNum >= BT_8812A_1ANT_WIFI_NOISY_THRESH) //no force LPS, no PS-TDMA, use pure TDMA + { + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + } + } + else if ((pCoexSta->bPanExist == FALSE) && (pCoexSta->bA2dpExist == FALSE) && (pCoexSta->bHidExist == FALSE)) + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + else + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(!bWifiBusy) + { + if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8812a1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8812a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else + { + if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8812a1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8812a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else + { + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, FALSE, FALSE); + if ( (pCoexSta->highPriorityTx) + (pCoexSta->highPriorityRx) <= 60 ) + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } +} + +VOID +halbtc8812a1ant_RunSwCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm=0; + + algorithm = halbtc8812a1ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + + if(halbtc8812a1ant_IsCommonAction(pBtCoexist)) + { + + } + else + { + switch(pCoexDm->curAlgorithm) + { + case BT_8812A_1ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = SCO.\n")); + //halbtc8812a1ant_ActionSco(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID.\n")); + //halbtc8812a1ant_ActionHid(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP.\n")); + //halbtc8812a1ant_ActionA2dp(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n")); + //halbtc8812a1ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR).\n")); + //halbtc8812a1ant_ActionPanEdr(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HS mode.\n")); + //halbtc8812a1ant_ActionPanHs(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN+A2DP.\n")); + //halbtc8812a1ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n")); + //halbtc8812a1ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n")); + //halbtc8812a1ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8812A_1ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP.\n")); + //halbtc8812a1ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = coexist All Off!!\n")); + //halbtc8812a1ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8812a1ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + BOOLEAN bIncreaseScanDevNum=FALSE; + BOOLEAN bBtCtrlAggBufSize=FALSE; + BOOLEAN bMiracastPlusBt=FALSE; + u1Byte aggBufSize=5; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0, wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if( (BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bIncreaseScanDevNum = TRUE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, &bIncreaseScanDevNum); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], Multi-Port numOfWifiLink = %d, wifiLinkStatus = 0x%x\n", numOfWifiLink,wifiLinkStatus) ); + + if(pBtLinkInfo->bBtLinkExist) + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + bMiracastPlusBt = TRUE; + } + else + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + bMiracastPlusBt = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + + if ( (pBtLinkInfo->bA2dpExist) && (pCoexSta->bC2hBtInquiryPage) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8812a1ant_ActionBtInquiry(pBtCoexist); + } + else + halbtc8812a1ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if ( (pBtLinkInfo->bBtLinkExist) && (bWifiConnected) ) + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 0, 1); + + if(pBtLinkInfo->bScoExist) + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, TRUE, FALSE, 0x5); + else + { + if (BTC_WIFI_BW_HT40==wifiBw) + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x10); + else + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + } + + halbtc8812a1ant_SwMechanism(pBtCoexist, TRUE); + halbtc8812a1ant_RunSwCoexistMechanism(pBtCoexist); //just print debug message + } + else + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x5); + + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + halbtc8812a1ant_RunSwCoexistMechanism(pBtCoexist); ////just print debug message + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], BT Is Inquirying \n") ); + halbtc8812a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8812a1ant_ActionHs(pBtCoexist); + return; + } + + + if(!bWifiConnected) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is non connected-idle !!!\n")); + + 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) + { + if (bScan) + halbtc8812a1ant_ActionWifiNotConnectedScan(pBtCoexist); + else + halbtc8812a1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else + halbtc8812a1ant_ActionWifiNotConnected(pBtCoexist); + } + else // wifi LPS/Busy + { + halbtc8812a1ant_ActionWifiConnected(pBtCoexist); + } +} + +VOID +halbtc8812a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + + // sw all off + halbtc8812a1ant_SwMechanism(pBtCoexist, FALSE); + + //halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + //halbtc8812a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + pCoexSta->popEventCnt = 0; +} + +VOID +halbtc8812a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp, + IN BOOLEAN bWifiOnly + ) +{ + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + //ant sw control to BT + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, TRUE, FALSE); + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + // PTA parameter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, 0xffff); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, 0x55555555); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, 0x55555555); + + // coex parameters + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); + + // enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // enable PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); + + // bt clock related + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4); + u1Tmp |= BIT7; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4, u1Tmp); + + // bt clock related + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7); + u1Tmp |= BIT1; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x7, u1Tmp); +} + +//============================================================ +// work around function start with wa_halbtc8812a1ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8812a1ant_ +//============================================================ +VOID +EXhalbtc8812a1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8812a1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8812a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8812a1ant_InitHwConfig(pBtCoexist, TRUE, bWifiOnly); + pBtCoexist->bStopCoexDm = FALSE; +} + +VOID +EXhalbtc8812a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + pBtCoexist->bStopCoexDm = FALSE; + + halbtc8812a1ant_InitCoexDm(pBtCoexist); + + halbtc8812a1ant_QueryBtInfo(pBtCoexist); +} + +VOID +EXhalbtc8812a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + if(pBtCoexist->bStopCoexDm) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8812a1Ant, GLCoexVer8812a1Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((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")))), + pCoexSta->btRssi, 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); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8812a1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + if(!pBtCoexist->bManualControl) + { + // Sw mechanism + 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 = %s/ %s/ %d ", "DelBA/ BtCtrlAgg/ AggSize", \ + (pBtCoexist->btInfo.bRejectAggPkt? "Yes":"No"), (pBtCoexist->btInfo.bBtCtrlAggBufSize? "Yes":"No"), + pBtCoexist->btInfo.aggBufSize); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \ + pCoexDm->errorCondition); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb3); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x900); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0xcb3/0xcb7/0x900", \ + u1Tmp[0], u1Tmp[1], u4Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ + u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(hp rx[31:16]/tx[15:0])", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + + +VOID +EXhalbtc8812a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp=0; + + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + + halbtc8812a1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8812a1ant_InitCoexDm(pBtCoexist); + halbtc8812a1ant_QueryBtInfo(pBtCoexist); + + pCoexSta->bUnderIps = FALSE; + } +} + +VOID +EXhalbtc8812a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8812a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + u1Byte u1Tmpa, u1Tmpb; + u4Byte u4Tmp; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm ) + return; + + if(BTC_SCAN_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } + + if(pBtCoexist->btInfo.bBtDisabled) + return; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + halbtc8812a1ant_QueryBtInfo(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8812a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8812a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8812a1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_SCAN_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8812a1ant_ActionWifiNotConnectedScan(pBtCoexist); + } + else // wifi is connected + { + halbtc8812a1ant_ActionWifiConnectedScan(pBtCoexist); + } + } + else if(BTC_SCAN_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8812a1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8812a1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8812a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_ASSOCIATE_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + pCoexDm->nArpCnt = 0; + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + //pCoexDm->nArpCnt = 0; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8812a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8812a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8812a1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_ASSOCIATE_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + halbtc8812a1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8812a1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8812a1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +//to check registers... +VOID +EXhalbtc8812a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte dataLen=5; + u1Byte buf[6] = {0}; + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + BOOLEAN bWifiUnderBMode = FALSE; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FORCE_EXEC, FALSE, FALSE); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); +#if 0 + //Set CCK Tx/Rx high Pri except 11b mode + if (bWifiUnderBMode) + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x00); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x00); //CCK Rx + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x10); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x10); //CCK Rx + } +#endif + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + pCoexDm->nArpCnt = 0; + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cd, 0x0); //CCK Tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cf, 0x0); //CCK Rx + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + //H2C_Parameter[0] = 0x1; + H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + buf[0] = dataLen; + buf[1] = 0x5; // OP_Code + buf[2] = 0x3; // OP_Code_Length + buf[3] = H2C_Parameter[0]; // OP_Code_Content + buf[4] = H2C_Parameter[1]; + buf[5] = H2C_Parameter[2]; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); +} + +VOID +EXhalbtc8812a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + if(BTC_PACKET_ARP == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet ARP notify\n")); + + pCoexDm->nArpCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ARP Packet Count = %d\n", pCoexDm->nArpCnt)); + + if(pCoexDm->nArpCnt >= 10) // if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet DHCP or EAPOL notify\n")); + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet [Type = %d] notify\n", type)); + } + + pCoexSta->specialPktPeriodCnt = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8812a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8812a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8812a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8812a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8812a1ant_ActionHs(pBtCoexist); + return; + } + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + ( (BTC_PACKET_ARP == type ) && (pCoexSta->bWiFiIsHighPriTask) ) ) + { + halbtc8812a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + } +} + +VOID +EXhalbtc8812a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bBtBusy=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8812A_1ANT_MAX) + rspSource = BT_INFO_SRC_8812A_1ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8812A_1ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btRetryCnt >= 1) + pCoexSta->popEventCnt++; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtPage = TRUE; + else + pCoexSta->bC2hBtPage = FALSE; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2-90; + //pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if(!pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if(pCoexSta->btInfoExt & BIT1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8812a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8812a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if(pCoexSta->btInfoExt & BIT3) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8812a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8812A_1ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8812a1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8812A_1ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8812A_1ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8812A_1ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8812A_1ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8812A_1ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8812A_1ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + } + + halbtc8812a1ant_UpdateBtLinkInfo(pBtCoexist); + + btInfo = btInfo & 0x1f; //mask profile bit for connect-ilde identification ( for CSR case: A2DP idle --> 0x41) + + if(!(btInfo&BT_INFO_8812A_1ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8812A_1ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8812A_1ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8812A_1ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8812A_1ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8812A_1ANT_B_ACL_BUSY) + { + if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus) + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->btStatus = BT_8812A_1ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8812A_1ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8812A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + bBtBusy = TRUE; + else + bBtBusy = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + halbtc8812a1ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8812a1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp; + u1Byte u1Tmpa,u1Tmpb, u1Tmpc; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF Status notify\n")); + + if(BTC_RF_ON == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned ON!!\n")); + pBtCoexist->bStopCoexDm = FALSE; + } + else if(BTC_RF_OFF == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RF is turned OFF!!\n")); + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + + halbtc8812a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + pBtCoexist->bStopCoexDm = TRUE; + } +} + +VOID +EXhalbtc8812a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + + halbtc8812a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8812a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + pBtCoexist->bStopCoexDm = TRUE; +} + +VOID +EXhalbtc8812a1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8812a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FORCE_EXEC, FALSE, TRUE); + halbtc8812a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + + pBtCoexist->bStopCoexDm = TRUE; + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + pBtCoexist->bStopCoexDm = FALSE; + halbtc8812a1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8812a1ant_InitCoexDm(pBtCoexist); + halbtc8812a1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8812a1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], *****************Coex DM Reset*****************\n")); + + halbtc8812a1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8812a1ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8812a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8812a1Ant, GLCoexVer8812a1Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8812A_1ANT == 0) + halbtc8812a1ant_QueryBtInfo(pBtCoexist); + halbtc8812a1ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8812a1ant_MonitorBtCtr(pBtCoexist); + halbtc8812a1ant_MonitorWiFiCtr(pBtCoexist); + + if( halbtc8812a1ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust ) + { + halbtc8812a1ant_RunCoexistMechanism(pBtCoexist); + } + + pCoexSta->specialPktPeriodCnt++; +#endif +} + +VOID +EXhalbtc8812a1ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ) +{ + switch(opCode) + { + case BTC_DBG_SET_COEX_NORMAL: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set CoexMode to Normal\n")); + pBtCoexist->bManualControl = FALSE; + halbtc8812a1ant_InitCoexDm(pBtCoexist); + break; + case BTC_DBG_SET_COEX_WIFI_ONLY: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set CoexMode to Wifi Only\n")); + pBtCoexist->bManualControl = TRUE; + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); + break; + case BTC_DBG_SET_COEX_BT_ONLY: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set CoexMode to BT only\n")); + pBtCoexist->bManualControl = TRUE; + halbtc8812a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + break; + case BTC_DBG_SET_COEX_DEC_BT_PWR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set Dec BT power\n")); + { + u1Byte dataLen=4; + u1Byte buf[6] = {0}; + u1Byte decBtPwr=0, pwrLevel=0; + if(opLen == 2) + { + decBtPwr = pData[0]; + pwrLevel = pData[1]; + + buf[0] = dataLen; + buf[1] = 0x3; // OP_Code + buf[2] = 0x2; // OP_Code_Length + + buf[3] = decBtPwr; // OP_Code_Content + buf[4] = pwrLevel; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set Dec BT power=%d, pwrLevel=%d\n", decBtPwr, pwrLevel)); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + + case BTC_DBG_SET_COEX_BT_AFH_MAP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT AFH Map\n")); + { + u1Byte dataLen=5; + u1Byte buf[6] = {0}; + if(opLen == 3) + { + buf[0] = dataLen; + buf[1] = 0x5; // OP_Code + buf[2] = 0x3; // OP_Code_Length + + buf[3] = pData[0]; // OP_Code_Content + buf[4] = pData[1]; + buf[5] = pData[2]; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT AFH Map = %02x %02x %02x\n", + pData[0], pData[1], pData[2])); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + + case BTC_DBG_SET_COEX_BT_IGNORE_WLAN_ACT: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT Ignore Wlan Active\n")); + { + u1Byte dataLen=3; + u1Byte buf[6] = {0}; + if(opLen == 1) + { + buf[0] = dataLen; + buf[1] = 0x1; // OP_Code + buf[2] = 0x1; // OP_Code_Length + + buf[3] = pData[0]; // OP_Code_Content + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT Ignore Wlan Active = 0x%x\n", + pData[0])); + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + default: + break; + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.h new file mode 100644 index 00000000..c4ec1a4c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a1Ant.h @@ -0,0 +1,258 @@ +//=========================================== +// The following is for 8812A 1ANT BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8812A_1ANT 1 + +#define BT_INFO_8812A_1ANT_B_FTP BIT7 +#define BT_INFO_8812A_1ANT_B_A2DP BIT6 +#define BT_INFO_8812A_1ANT_B_HID BIT5 +#define BT_INFO_8812A_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8812A_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8812A_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8812A_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8812A_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT 2 + +#define BT_8812A_1ANT_WIFI_NOISY_THRESH 30 //max: 255 + +typedef enum _BT_INFO_SRC_8812A_1ANT{ + BT_INFO_SRC_8812A_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8812A_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8812A_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8812A_1ANT_MAX +}BT_INFO_SRC_8812A_1ANT,*PBT_INFO_SRC_8812A_1ANT; + +typedef enum _BT_8812A_1ANT_BT_STATUS{ + BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8812A_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8812A_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8812A_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8812A_1ANT_BT_STATUS_MAX +}BT_8812A_1ANT_BT_STATUS,*PBT_8812A_1ANT_BT_STATUS; + +typedef enum _BT_8812A_1ANT_WIFI_STATUS{ + BT_8812A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8812A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8812A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8812A_1ANT_WIFI_STATUS_MAX +}BT_8812A_1ANT_WIFI_STATUS,*PBT_8812A_1ANT_WIFI_STATUS; + +typedef enum _BT_8812A_1ANT_COEX_ALGO{ + BT_8812A_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8812A_1ANT_COEX_ALGO_SCO = 0x1, + BT_8812A_1ANT_COEX_ALGO_HID = 0x2, + BT_8812A_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8812A_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8812A_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8812A_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8812A_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8812A_1ANT_COEX_ALGO_MAX = 0xb, +}BT_8812A_1ANT_COEX_ALGO,*PBT_8812A_1ANT_COEX_ALGO; + +typedef struct _COEX_DM_8812A_1ANT{ + // hw setting + u1Byte preAntPosType; + u1Byte curAntPosType; + // fw mechanism + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; + u4Byte nArpCnt; + + u1Byte errorCondition; +} COEX_DM_8812A_1ANT, *PCOEX_DM_8812A_1ANT; + +typedef struct _COEX_STA_8812A_1ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte specialPktPeriodCnt; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + s1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8812A_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8812A_1ANT_MAX]; + u4Byte btInfoQueryCnt; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtPage; //Add for win8.1 page out issue + BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue + u1Byte btRetryCnt; + u1Byte btInfoExt; + u4Byte popEventCnt; + u1Byte nScanAPNum; + + u4Byte nCRCOK_CCK; + u4Byte nCRCOK_11g; + u4Byte nCRCOK_11n; + u4Byte nCRCOK_11nAgg; + + u4Byte nCRCErr_CCK; + u4Byte nCRCErr_11g; + u4Byte nCRCErr_11n; + u4Byte nCRCErr_11nAgg; + + BOOLEAN bCCKLock; + BOOLEAN bPreCCKLock; + u1Byte nCoexTableType; + + BOOLEAN bForceLpsOn; +}COEX_STA_8812A_1ANT, *PCOEX_STA_8812A_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8812a1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8812a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8812a1ant_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8812a1ant_CoexDmReset( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a1ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ); +VOID +EXhalbtc8812a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.c new file mode 100644 index 00000000..34ebffb8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.c @@ -0,0 +1,5434 @@ +//============================================================ +// Description: +// +// This file is for RTL8812A Co-exist mechanism +// +// History +// 2012/08/22 Cosa first check in. +// 2012/11/14 Cosa Revise for 8812A 2Ant out sourcing. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8812a2Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8812A_2ANT GLCoexDm8812a2Ant; +static PCOEX_DM_8812A_2ANT pCoexDm=&GLCoexDm8812a2Ant; +static COEX_STA_8812A_2ANT GLCoexSta8812a2Ant; +static PCOEX_STA_8812A_2ANT pCoexSta=&GLCoexSta8812a2Ant; + +const char *const GLBtInfoSrc8812a2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8812a2Ant=20150408; +u4Byte GLCoexVer8812a2Ant=0x39; +//improve 8761ATV D-cut BT off/on fail issue +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8812a2ant_ +//============================================================ +u1Byte +halbtc8812a2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8812a2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8812a2ant_SetEnablePTA( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnablePTA + ) +{ + if(bEnablePTA) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PTA is enable!\n")); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PTA is disable!\n")); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x00); + + } +} + +VOID +halbtc8812a2ant_EnablePTA( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE (COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Enable PTA %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurEnablePTA = bEnable; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bPreEnablePTA = %d, bCurEnablePTA = %d!!\n", + pCoexDm->bPreEnablePTA, pCoexDm->bCurEnablePTA)); + + if(pCoexDm->bPreEnablePTA == pCoexDm->bCurEnablePTA) + return; + } + halbtc8812a2ant_SetEnablePTA(pBtCoexist, bEnable); + + + pCoexDm->bPreEnablePTA = pCoexDm->bCurEnablePTA; +} + +VOID +halbtc8812a2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + // only 8812a need to consider if core stack is installed. + if(!pStackInfo->hciVersion) + { + bBtActive = FALSE; + } +/* + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } +*/ + + if((pCoexSta->prebtInfoC2hCnt_BT_RSP == pCoexSta->btInfoC2hCnt[1]) && + (pCoexSta->prebtInfoC2hCnt_BT_SEND == pCoexSta->btInfoC2hCnt[2])) + { + bBtActive = FALSE; + } + + pCoexSta->prebtInfoC2hCnt_BT_RSP = pCoexSta->btInfoC2hCnt[1]; + pCoexSta->prebtInfoC2hCnt_BT_SEND = pCoexSta->btInfoC2hCnt[2]; + + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt is detected as disabled %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(pCoexSta->preBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (pCoexSta->preBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + pCoexSta->preBtDisabled = bBtDisabled; + + if(!bBtDisabled) + { + // enable PTA +// halbtc8812a2ant_EnablePTA(pBtCoexist,FORCE_EXEC, TRUE); + } + else + { + // disable PTA +// halbtc8812a2ant_EnablePTA(pBtCoexist,FORCE_EXEC, FALSE); + } + } +} + +u4Byte +halbtc8812a2ant_DecideRaMask( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte raMaskType + ) +{ + u4Byte disRaMask=0x0; + + switch(raMaskType) + { + case 0: // normal mode + disRaMask = 0x0; + break; + case 1: // disable cck 1/2 + disRaMask = 0x00000003; + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + disRaMask = 0x0001f1f7; + break; + default: + break; + } + + return disRaMask; +} + +VOID +halbtc8812a2ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8812a2ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8812a2ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8812a2ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8812a2ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + u4Byte disRaMask=0x0; + + pCoexDm->curRaMaskType = raMaskType; + disRaMask = halbtc8812a2ant_DecideRaMask(pBtCoexist, raMaskType); + halbtc8812a2ant_UpdateRaMask(pBtCoexist, bForceExec, disRaMask); + + halbtc8812a2ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8812a2ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8812a2ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8812a2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8812a2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8812a2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte dataLen=3; + u1Byte buf[5] = {0}; +//8812a watch btifo to check BT enable/disable +// if(!pBtCoexist->btInfo.bBtDisabled) + { + if(!pCoexSta->btInfoQueryCnt || + (pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8812A_2ANT_BT_RSP]-pCoexSta->btInfoQueryCnt)>2) + { + buf[0] = dataLen; + buf[1] = 0x1; // polling enable, 1=enable, 0=disable + buf[2] = 0x2; // polling time in seconds + buf[3] = 0x1; // auto report enable, 1=enable, 0=disable + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_INFO, (PVOID)&buf[0]); + } + } + pCoexSta->btInfoQueryCnt++; +} + +BOOLEAN +halbtc8812a2ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; + BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + } + + return FALSE; +} + +VOID +halbtc8812a2ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + +#if 1//(BT_AUTO_REPORT_ONLY_8812A_2ANT == 1) // profile from bt patch + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + pBtLinkInfo->bAclBusy = pCoexSta->bAclBusy; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } +#else // profile from bt stack + pBtLinkInfo->bBtLinkExist = pStackInfo->bBtLinkExist; + pBtLinkInfo->bScoExist = pStackInfo->bScoExist; + pBtLinkInfo->bA2dpExist = pStackInfo->bA2dpExist; + pBtLinkInfo->bPanExist = pStackInfo->bPanExist; + pBtLinkInfo->bHidExist = pStackInfo->bHidExist; + + //for win-8 stack HID report error + if(!pStackInfo->bHidExist) + pStackInfo->bHidExist = pCoexSta->bHidExist; //sync BTInfo with BT firmware and stack + // when stack HID report error, here we use the info from bt fw. + if(!pStackInfo->bBtLinkExist) + pStackInfo->bBtLinkExist = pCoexSta->bBtLinkExist; +#endif + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8812a2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8812A_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 0) + { + if(pBtLinkInfo->bAclBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ACL Busy only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR; + } + } + else if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8812A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8812a2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8812a2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte decBtPwrLvl + ) +{ + u1Byte dataLen=4; + u1Byte buf[6] = {0}; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power level = %d\n", + decBtPwrLvl)); + + buf[0] = dataLen; + buf[1] = 0x3; // OP_Code + buf[2] = 0x2; // OP_Code_Length + if(decBtPwrLvl) + buf[3] = 0x1; // OP_Code_Content + else + buf[3] = 0x0; + buf[4] = decBtPwrLvl;// pwrLevel + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); +} + +VOID +halbtc8812a2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte decBtPwrLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power level = %d\n", + (bForceExec? "force to":""), decBtPwrLvl)); + pCoexDm->curBtDecPwrLvl = decBtPwrLvl; + + if(!bForceExec) + { + if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl) + return; + } + halbtc8812a2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl); + + pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl; +} + +VOID +halbtc8812a2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8812a2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8812a2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8812a2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8812a2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8812a2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte tmpU1; + + tmpU1 = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4fd); + tmpU1 |= BIT0; + if(bLowPenaltyRa) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set low penalty!!\n")); + tmpU1 &= ~BIT2; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Tx rate adaptive, set normal!!\n")); + tmpU1 |= BIT2; + } + + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4fd, tmpU1); +} + +VOID +halbtc8812a2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8812a2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8812a2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc5b, 0x3e, val); +} + +VOID +halbtc8812a2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8812a2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8812a2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8812a2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8812a2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8812a2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x1); + } +} + +VOID +halbtc8812a2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8812a2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8812a2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28F4B); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x10AB2); + rssiAdjustVal = 8; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x2884B); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x104B2); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + +VOID +halbtc8812a2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8812a2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8812a2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8812a2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8812a2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8812a2ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + switch(type) + { + case 0: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 1: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5ffb5ffb, 0xffffff, 0x3); + break; + case 3: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fdf5fdf, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 4: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0xdfffdfff, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 5: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x5ddd5ddd, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 6: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + if(pCoexSta->nScanAPNum <= 5) + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xfafafafa, 0xffffff, 0x3); + else + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 8: + halbtc8812a2ant_CoexTable(pBtCoexist, bForceExec, 0x5f5f5f5f, 0x5a5a5a5a, 0xffffff, 0x3); + break; + + default: + break; + } +} + +VOID +halbtc8812a2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte dataLen=3; + u1Byte buf[5] = {0}; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Ignore Wlan_Act\n", + (bEnable? "Enable":"Disable"))); + + buf[0] = dataLen; + buf[1] = 0x1; // OP_Code + buf[2] = 0x1; // OP_Code_Length + if(bEnable) + buf[3] = 0x1; // OP_Code_Content + else + buf[3] = 0x0; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); +} + +VOID +halbtc8812a2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8812a2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8812a2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + +VOID +halbtc8812a2ant_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 +halbtc8812a2ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8812a2ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8812a2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + /* + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + */ + + halbtc8812a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + //halbtc8812a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8812a2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + //halbtc8812a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + halbtc8812a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + halbtc8812a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8812a2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + u1Byte u1Tmp=0; + + if(bInitHwCfg) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x900, 0x00000400); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76d, 0x1); + } + else if(bWifiOff) + { + + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_WIFI_AT_CPL_MAIN: + break; + case BTC_ANT_WIFI_AT_CPL_AUX: + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + u1Tmp &= ~BIT3; + u1Tmp |= BIT2; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb7, u1Tmp); + break; + default: + break; + } +} + +VOID +halbtc8812a2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + s1Byte nWiFiDurationAdjust = 0x0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if(!bForceExec) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", + pCoexDm->bPrePsTdmaOn, pCoexDm->bCurPsTdmaOn)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", + pCoexDm->prePsTdma, pCoexDm->curPsTdma)); + + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + + if (pCoexSta->nScanAPNum >= 40) + nWiFiDurationAdjust = -15; + else if (pCoexSta->nScanAPNum >= 20) + nWiFiDurationAdjust = -10; + +/* + 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) ) + { + 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) + { + case 1: + default: //d1,wb + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x11, 0x10); + break; + case 2: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x11, 0x10); + break; + case 3: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x11, 0x10); + break; + case 4: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x11, 0x10); + break; + case 5: //d1,pb,TXpause + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x63, 0x3c, 0x03, 0x90, 0x10); + break; + case 6: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x63, 0x32, 0x03, 0x90, 0x10); + break; + case 7: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x63, 0x28, 0x03, 0x90, 0x10); + break; + case 8: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x63, 0x1e, 0x03, 0x90, 0x10); + break; + case 9: //d1,bb + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x31, 0x10); + break; + case 10: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x31, 0x10); + break; + case 11: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x31, 0x10); + break; + case 12: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x31, 0x10); + break; + case 13: //d1,bb,TXpause + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x30, 0x10); + break; + case 14: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x32, 0x03, 0x30, 0x10); + break; + case 15: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x28, 0x03, 0x30, 0x10); + break; + case 16: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0x30, 0x10); + break; + case 17: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x3, 0x11, 0x11); + break; + case 18: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x70, 0x90); + break; + case 22: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x61, 0x1a, 0x1a, 0x21, 0x10); + break; + case 23: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x03, 0x31, 0x10); + break; + + case 71: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + break; + + // following cases is for wifi rssi low, started from 81 + case 80: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x3c, 0x3, 0x90, 0x50); + break; + case 81: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x3a+nWiFiDurationAdjust, 0x3, 0x90, 0x50); + break; + case 82: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x30+nWiFiDurationAdjust, 0x03, 0x90, 0x50); + break; + case 83: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x21, 0x03, 0x90, 0x50); + break; + case 84: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x15, 0x3, 0x90, 0x50); + break; + case 85: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x1d, 0x1d, 0x80, 0x50); + break; + case 86: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x53, 0x15, 0x15, 0x80, 0x50); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 0: //ANT2PTA, 0x778=0x1 + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + break; + case 1: //ANT2BT, 0x778=3 + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0); + delay_ms(5); + halbtc8812a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_CPL_AUX, FALSE, FALSE); + break; + default: + halbtc8812a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8812a2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8812a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0); + + halbtc8812a2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8812a2ant_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 + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8812a2ant_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 = TRUE; + 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: + halbtc8812a2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8812a2ant_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: + halbtc8812a2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + +VOID +halbtc8812a2ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +BOOLEAN +halbtc8812a2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + + if(pCoexSta->bC2hBtInquiryPage) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8812a2ant_ActionBtInquiry(pBtCoexist); + return TRUE; + } + + if(pBtLinkInfo->bScoExist || pBtLinkInfo->bHidExist) + { + halbtc8812a2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 0, 0, 0); + } + else + { + halbtc8812a2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + } + + if(!bWifiConnected) + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-connected idle!!\n")); + + if( (BT_8812A_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) || + (BT_8812A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(BT_8812A_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else if(BT_8812A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) + { + if(bBtHsOn) + return FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + bCommon = FALSE; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 17); + + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + bCommon = TRUE; + } + } + } + + return bCommon; +} + +VOID +halbtc8812a2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +//================== +// pstdma for wifi rssi low +//================== +VOID +halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow( + IN PBTC_COEXIST pBtCoexist//, + //IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow()\n")); +#if 0 + if( (BT_8812A_2ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8812A_2ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8812A_2ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 81 && + pCoexDm->curPsTdma != 82 && + pCoexDm->curPsTdma != 83 && + pCoexDm->curPsTdma != 84 ) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } +#endif + pCoexDm->bAutoTdmaAdjust = FALSE; + + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + + if(!pCoexDm->bAutoTdmaAdjustLowRssi) + { + pCoexDm->bAutoTdmaAdjustLowRssi = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjustForWifiRssiLow()!!\n")); + + if(BT_INFO_8812A_2ANT_A2DP_BASIC_RATE(btInfoExt)) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 +// retryCount = pCoexSta->btRetryCnt; +// btInfoExt = pCoexSta->btInfoExt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if ( (pCoexSta->lowPriorityTx) > 1050 || (pCoexSta->lowPriorityRx) > 1250 ) + retryCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { +/* + if( (BT_INFO_8812A_2ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 81) ||(pCoexDm->curPsTdma == 82)) ) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 84); + pCoexDm->psTdmaDuAdjType = 84; + } +*/ + if(pCoexDm->curPsTdma == 80) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + else if(pCoexDm->curPsTdma == 81) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + else if(pCoexDm->curPsTdma == 82) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else if(pCoexDm->curPsTdma == 83) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 84); + pCoexDm->psTdmaDuAdjType = 84; + } + } + else if(result == 1) + { +/* + if( (BT_INFO_8812A_2ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 81) ||(pCoexDm->curPsTdma == 82)) ) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } +*/ + if(pCoexDm->curPsTdma == 84) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 83); + pCoexDm->psTdmaDuAdjType = 83; + } + else if(pCoexDm->curPsTdma == 83) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 82); + pCoexDm->psTdmaDuAdjType = 82; + } + else if(pCoexDm->curPsTdma == 82) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 81); + pCoexDm->psTdmaDuAdjType = 81; + } + else if((pCoexDm->curPsTdma == 81)&&((pCoexSta->nScanAPNum <= 5))) + { + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 81); + pCoexDm->psTdmaDuAdjType = 81; + } + } + + if( pCoexDm->curPsTdma != 80 && + pCoexDm->curPsTdma != 81 && + pCoexDm->curPsTdma != 82 && + pCoexDm->curPsTdma != 83 && + pCoexDm->curPsTdma != 84 ) + { + // recover to previous adjust type + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8812a2ant_GetBtRssiThreshold( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte pThres0, + IN pu1Byte pThres1 + ) +{ + u1Byte antType, btThreshold=0; + +// pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_ANT_TYPE, &antType); + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + antType = pBoardInfo->antType; + + + switch(antType) + { + case BTC_ANT_TYPE_0: + *pThres0 = 100; + *pThres1 = 100; + break; + case BTC_ANT_TYPE_1: + *pThres0 = 34; + *pThres1 = 42; + break; + case BTC_ANT_TYPE_2: + *pThres0 = 34; + *pThres1 = 42; + break; + case BTC_ANT_TYPE_3: + *pThres0 = 34; + *pThres1 = 42; + break; + case BTC_ANT_TYPE_4: + *pThres0 = 34; + *pThres1 = 42; + break; + default: + break; + } +} + + + +VOID +halbtc8812a2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + + // pstdma + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + else + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x6); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x6); + } + } +} + +VOID +halbtc8812a2ant_ActionScoHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + + // pstdma + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + else + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x6); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x6); + } + } +} + +VOID +halbtc8812a2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte anttype=0; + BOOLEAN bApEnable=FALSE; + + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + anttype = pBoardInfo->antType; + + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); +// btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + // power save state & pstdma & coex table + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 9); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8812a2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte anttype=0; + BOOLEAN bApEnable=FALSE; + + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + anttype = pBoardInfo->antType; + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); +// btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + +// anttype = 4; + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + + if((pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + + // power save state & pstdma & coex table +/* + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } +*/ + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); //shielding room + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // decrease BT power +/* + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A) // BT HIGH RSSI & shielding room + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8812a2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 2); + else + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x6); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x6); + } + } +} + +VOID +halbtc8812a2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + else + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 85); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(HS) only +VOID +halbtc8812a2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + + // pstdma + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8812a2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + else + { + pCoexDm->bAutoTdmaAdjust = FALSE; + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); + } + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8812a2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); +// btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + else + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 85); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8812a2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); +// btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + if((bApEnable == TRUE) || (BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + else + { + pCoexDm->bAutoTdmaAdjust = FALSE; + halbtc8812a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 86); + } + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8812a2ant_ActionHidA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0; + + halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); + btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); +// btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + // power save state + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 3); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + else + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + // pstdma + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + else + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else if(BTC_RSSI_LOW(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState))) + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + else + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8812a2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH, btRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiBw; + u1Byte btThresh0=0, btThresh1=0, anttype=0; + BOOLEAN bApEnable=FALSE; + + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + anttype = pBoardInfo->antType; + + +// halbtc8812a2ant_GetBtRssiThreshold(pBtCoexist, &btThresh0, &btThresh1); +// btRssiState = halbtc8812a2ant_BtRssiState(3, btThresh0, btThresh1); + + wifiRssiState = halbtc8812a2ant_WifiRssiState(pBtCoexist, 0, 2, 34, 0); + btRssiState = halbtc8812a2ant_BtRssiState(3, 34, 42); + + if(anttype == 0)//ANTTYPE = 0 92E 2ant with SPDT + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 1) //92E 2ant with coupler and bad ant. isolation, 92E 3ant with bad ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 2)//ANTTYPE = 2, 92E 2ant with coupler and normal/good ant. isolation, 92E 3ant with normal ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, TRUE, 83); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + } + } + else if(anttype == 3) //ANTTYPE = 3, 92E 3ant with good ant. isolation + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + } + else //WIFI RSSI || BT RSSI == low + { + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8812a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + } + else //ANTTYPE = 4 for test + { + // power save state & pstdma & coex table + if(BTC_RSSI_HIGH(wifiRssiState) && (!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & shielding room + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else if (BTC_RSSI_HIGH(wifiRssiState)&&(!BTC_RSSI_LOW(btRssiState)) && (pCoexSta->nScanAPNum > NOISY_AP_NUM_THRESH_8812A)) + { //WIFI RSSI = high & BT RSSI = high & noisy enviroment + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //WIFI RSSI || BT RSSI == low + { + halbtc8812a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + halbtc8812a2ant_TdmaDurationAdjustForWifiRssiLow(pBtCoexist); + halbtc8812a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + } + + // decrease BT power + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + +/* + // decrease BT power + if(BTC_RSSI_LOW(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if (pCoexSta->nScanAPNum < NOISY_AP_NUM_THRESH_8812A) // BT HIGH RSSI & shielding room + halbtc8812a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); +*/ + // limited Rx + halbtc8812a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + // fw dac swing level + halbtc8812a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if(BTC_RSSI_HIGH(wifiRssiState)) + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8812a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8812a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8812a2ant_CoexUnder5G( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8812a2ant_CoexAllOff(pBtCoexist); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Under 5G, force set BT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, TRUE); +} +//==================================================== +VOID +halbtc8812a2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiUnder5G=FALSE, bBtHsOn=FALSE; + u1Byte btInfoOriginal=0, btRetryCnt=0; + u1Byte algorithm=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + if(bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n")); + halbtc8812a2ant_CoexUnder5G(pBtCoexist); + return; + } + + + algorithm = halbtc8812a2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bC2hBtInquiryPage && (BT_8812A_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8812a2ant_ActionBtInquiry(pBtCoexist); + return; + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8812a2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->bAutoTdmaAdjustLowRssi = FALSE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8812A_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8812a2ant_ActionSco(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_SCO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO+HID.\n")); + halbtc8812a2ant_ActionScoHid(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8812a2ant_ActionHid(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8812a2ant_ActionA2dp(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8812a2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8812a2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8812a2ant_ActionPanHs(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8812a2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8812a2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8812a2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN(HS).\n")); + halbtc8812a2ant_ActionHidA2dpPanHs(pBtCoexist); + break; + case BT_8812A_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8812a2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8812a2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } + +} + +VOID +halbtc8812a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp + ) +{ + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + if(bBackUp) + { + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + + //ant sw control to BT + halbtc8812a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_CPL_AUX, TRUE, FALSE); + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + // PTA parameter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, 0xffff); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, 0x55555555); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, 0x55555555); + + // coex parameters + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x1); + + // enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + // disable PTA to avoid BT insn't on + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x00); + + // bt clock related + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4); + u1Tmp |= BIT7; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4, u1Tmp); + + // bt clock related + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7); + u1Tmp |= BIT1; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x7, u1Tmp); +} + +//============================================================ +// work around function start with wa_halbtc8812a2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8812a2ant_ +//============================================================ +VOID +EXhalbtc8812a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8812a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8812a2ant_InitHwConfig(pBtCoexist, TRUE); +} + +VOID +EXhalbtc8812a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8812a2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8812a2ant_BTOffOnNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte BTstatus + ) +{ + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BToff/on notify\n")); + DBG_871X("%s, BTstatus:%d", __func__, BTstatus); + + if(BTC_BT_OFF == BTstatus) + { + //PTA off + pBtCoexist->btInfo.bBtDisabled = TRUE; + halbtc8812a2ant_EnablePTA(pBtCoexist,FORCE_EXEC, FALSE); + + } + else + { + //PTA on + pBtCoexist->btInfo.bBtDisabled = FALSE; + halbtc8812a2ant_EnablePTA(pBtCoexist,FORCE_EXEC, TRUE); + } + +} + + + +VOID +EXhalbtc8812a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u2Byte u2Tmp[4]; + u4Byte u4Tmp[4]; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "Antenna type:", \ + pBoardInfo->antType); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8812a2Ant, GLCoexVer8812a2Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((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")))), + pCoexSta->btRssi, 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); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8812a2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + // Sw mechanism + 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/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d/%d)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust, pCoexDm->bAutoTdmaAdjustLowRssi); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \ + pCoexDm->curBtDecPwrLvl, pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "backup ARFR1/ARFR2/RL/AMaxTime", \ + pCoexDm->backupArfrCnt1, pCoexDm->backupArfrCnt2, pCoexDm->backupRetryLimit, pCoexDm->backupAmpduMaxTime); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + u2Tmp[0] = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "0x430/0x434/0x42a/0x456", \ + u4Tmp[0], u4Tmp[1], u2Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x ", "0x778 (W_Act)/ 0x6cc (CoTab Sel)", \ + u1Tmp[0], u1Tmp[1]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x8db); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xc5b); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x8db(ADC)/0xc5b[29:25](DAC)", \ + ((u1Tmp[0]&0x60)>>5), ((u1Tmp[1]&0x3e)>>1)); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb3); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xcb7); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xcb3/ 0xcb7", \ + u1Tmp[0], u1Tmp[1]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x974); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x40/ 0x4c[24:23]/ 0x974", \ + u1Tmp[0], ((u4Tmp[0]&0x01800000)>>23), u4Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa0a); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(DIG)/0xa0a(CCK-TH)", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf48); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xf48/ 0xa5b (FA cnt-- OFDM : CCK)", \ + u4Tmp[0], (u1Tmp[0]<<8) + u1Tmp[1] ); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8812A_2ANT == 1) + halbtc8812a2ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8812a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnder5G=FALSE; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8812a2ant_CoexAllOff(pBtCoexist); + halbtc8812a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_CPL_AUX, FALSE, TRUE); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS notify, force set BT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8812a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + if(!bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS notify, force set BT NOT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } +} + +VOID +EXhalbtc8812a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8812a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &pCoexSta->nScanAPNum); + } +} + +VOID +EXhalbtc8812a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8812a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte dataLen=5; + u1Byte buf[6] = {0}; + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + buf[0] = dataLen; + buf[1] = 0x5; // OP_Code + buf[2] = 0x3; // OP_Code_Length + buf[3] = H2C_Parameter[0]; // OP_Code_Content + buf[4] = H2C_Parameter[1]; + buf[5] = H2C_Parameter[2]; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); +} + +VOID +EXhalbtc8812a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } + +} + +VOID +EXhalbtc8812a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE, bWifiUnder5G=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8812A_2ANT_MAX) + rspSource = BT_INFO_SRC_8812A_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8812A_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8812a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8812a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if( (pCoexSta->btInfoExt&BIT3) && !bWifiUnder5G) + { + // BT already ignored WlanAct + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + if(!pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + + if(pCoexSta->bUnderIps) + { + // work around for 8812a combo hw bug => when IPS, wlanAct is always high. + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS, set BT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + } + } + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8812A_2ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8812A_2ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + pCoexSta->bAclBusy = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8812A_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8812A_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8812A_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8812A_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + if(btInfo & BT_INFO_8812A_2ANT_B_ACL_BUSY) + pCoexSta->bAclBusy = TRUE; + else + pCoexSta->bAclBusy = FALSE; + + } + + halbtc8812a2ant_UpdateBtLinkInfo(pBtCoexist); + + if(!(btInfo&BT_INFO_8812A_2ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8812A_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8812A_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8812A_2ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8812A_2ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8812A_2ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8812A_2ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8812A_2ANT_B_ACL_BUSY) + { + pCoexDm->btStatus = BT_8812A_2ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8812A_2ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8812A_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8812A_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8812A_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bBtBusy = TRUE; + if(!bWifiUnder5G) + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8812a2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8812a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte u1Tmp=0; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8812a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_CPL_AUX, FALSE, TRUE); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify, force set BT to ignore Wlan active!!\n")); + halbtc8812a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8812a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + // 0x522=0xff, pause tx + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x522, 0xff); + // 0x40[7:6]=2'b01, modify BT mode. + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0xc0, 0x2); + //PTA off. + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x0); + +} + +VOID +EXhalbtc8812a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8812a2Ant, GLCoexVer8812a2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8812A_2ANT == 0) + halbtc8812a2ant_QueryBtInfo(pBtCoexist); + halbtc8812a2ant_MonitorBtCtr(pBtCoexist); +// halbtc8812a2ant_MonitorBtEnableDisable(pBtCoexist); +#else + if( halbtc8812a2ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust || + pCoexDm->bAutoTdmaAdjustLowRssi) + { + halbtc8812a2ant_RunCoexistMechanism(pBtCoexist); + } +#endif +} + +VOID +EXhalbtc8812a2ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ) +{ + switch(opCode) + { + case BTC_DBG_SET_COEX_DEC_BT_PWR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set Dec BT power\n")); + { + u1Byte dataLen=4; + u1Byte buf[6] = {0}; + u1Byte decBtPwr=0, pwrLevel=0; + if(opLen == 2) + { + decBtPwr = pData[0]; + pwrLevel = pData[1]; + + buf[0] = dataLen; + buf[1] = 0x3; // OP_Code + buf[2] = 0x2; // OP_Code_Length + + buf[3] = decBtPwr; // OP_Code_Content + buf[4] = pwrLevel; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set Dec BT power=%d, pwrLevel=%d\n", decBtPwr, pwrLevel)); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + + case BTC_DBG_SET_COEX_BT_AFH_MAP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT AFH Map\n")); + { + u1Byte dataLen=5; + u1Byte buf[6] = {0}; + if(opLen == 3) + { + buf[0] = dataLen; + buf[1] = 0x5; // OP_Code + buf[2] = 0x3; // OP_Code_Length + + buf[3] = pData[0]; // OP_Code_Content + buf[4] = pData[1]; + buf[5] = pData[2]; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT AFH Map = %02x %02x %02x\n", + pData[0], pData[1], pData[2])); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + + case BTC_DBG_SET_COEX_BT_IGNORE_WLAN_ACT: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT Ignore Wlan Active\n")); + { + u1Byte dataLen=3; + u1Byte buf[6] = {0}; + if(opLen == 1) + { + buf[0] = dataLen; + buf[1] = 0x1; // OP_Code + buf[2] = 0x1; // OP_Code_Length + + buf[3] = pData[0]; // OP_Code_Content + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set BT Ignore Wlan Active = 0x%x\n", + pData[0])); + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]); + } + } + break; + + default: + break; + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.h new file mode 100644 index 00000000..ac86e98d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8812a2Ant.h @@ -0,0 +1,249 @@ +//=========================================== +// The following is for 8812A 2Ant BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8812A_2ANT 0 + +#define BT_INFO_8812A_2ANT_B_FTP BIT7 +#define BT_INFO_8812A_2ANT_B_A2DP BIT6 +#define BT_INFO_8812A_2ANT_B_HID BIT5 +#define BT_INFO_8812A_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8812A_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8812A_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8812A_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8812A_2ANT_B_CONNECTION BIT0 + +#define BT_INFO_8812A_2ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8812A_2ANT 2 +#define NOISY_AP_NUM_THRESH_8812A 50 + + +typedef enum _BT_INFO_SRC_8812A_2ANT{ + BT_INFO_SRC_8812A_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8812A_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8812A_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8812A_2ANT_MAX +}BT_INFO_SRC_8812A_2ANT,*PBT_INFO_SRC_8812A_2ANT; + +typedef enum _BT_8812A_2ANT_BT_STATUS{ + BT_8812A_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8812A_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8812A_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8812A_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8812A_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8812A_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8812A_2ANT_BT_STATUS_MAX +}BT_8812A_2ANT_BT_STATUS,*PBT_8812A_2ANT_BT_STATUS; + +typedef enum _BT_8812A_2ANT_COEX_ALGO{ + BT_8812A_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8812A_2ANT_COEX_ALGO_SCO = 0x1, + BT_8812A_2ANT_COEX_ALGO_SCO_HID = 0x2, + BT_8812A_2ANT_COEX_ALGO_HID = 0x3, + BT_8812A_2ANT_COEX_ALGO_A2DP = 0x4, + BT_8812A_2ANT_COEX_ALGO_A2DP_PANHS = 0x5, + BT_8812A_2ANT_COEX_ALGO_PANEDR = 0x6, + BT_8812A_2ANT_COEX_ALGO_PANHS = 0x7, + BT_8812A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8, + BT_8812A_2ANT_COEX_ALGO_PANEDR_HID = 0x9, + BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa, + BT_8812A_2ANT_COEX_ALGO_HID_A2DP_PANHS = 0xb, + BT_8812A_2ANT_COEX_ALGO_HID_A2DP = 0xc, + BT_8812A_2ANT_COEX_ALGO_MAX = 0xd +}BT_8812A_2ANT_COEX_ALGO,*PBT_8812A_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8812A_2ANT{ + // fw mechanism + u1Byte preBtDecPwrLvl; + u1Byte curBtDecPwrLvl; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bAutoTdmaAdjustLowRssi; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + BOOLEAN bPreEnablePTA; + BOOLEAN bCurEnablePTA; + + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte curRaMaskType; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; +} COEX_DM_8812A_2ANT, *PCOEX_DM_8812A_2ANT; + +typedef struct _COEX_STA_8812A_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + BOOLEAN bAclBusy; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + u1Byte preBtRssiState; + u1Byte preBtDisabled; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8812A_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8812A_2ANT_MAX]; + u4Byte prebtInfoC2hCnt_BT_RSP; + u4Byte prebtInfoC2hCnt_BT_SEND; + u4Byte btInfoQueryCnt; + BOOLEAN bC2hBtInquiryPage; + u1Byte btRetryCnt; + u1Byte btInfoExt; + u1Byte nScanAPNum; + + 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_8812A_2ANT, *PCOEX_STA_8812A_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8812a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8812a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8812a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8812a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8812a2ant_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + IN pu1Byte pData + ); +VOID +EXhalbtc8812a2ant_BTOffOnNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte BTstatus + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.c new file mode 100644 index 00000000..c840c779 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.c @@ -0,0 +1,3433 @@ +//============================================================ +// Description: +// +// This file is for 8821A_1ANT Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8821a1Ant.tmh" +#endif + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8821A_1ANT GLCoexDm8821a1Ant; +static PCOEX_DM_8821A_1ANT pCoexDm=&GLCoexDm8821a1Ant; +static COEX_STA_8821A_1ANT GLCoexSta8821a1Ant; +static PCOEX_STA_8821A_1ANT pCoexSta=&GLCoexSta8821a1Ant; + +const char *const GLBtInfoSrc8821a1Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8821a1Ant=20140306; +u4Byte GLCoexVer8821a1Ant=0x4b; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8821a1ant_ +//============================================================ +u1Byte +halbtc8821a1ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8821a1ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8821a1ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8821a1ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8821a1ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8821a1ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8821a1ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8821a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8821a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8821a1ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8821a1ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8821a1ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8821a1ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); +} + +VOID +halbtc8821a1ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); + + +} + +VOID +halbtc8821a1ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp, u4Tmp1; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp, u1Tmp1; + s4Byte wifiRssi; +#if 0 + //to avoid 0x76e[3] = 1 (WLAN_Act control by PTA) during IPS + if (! (pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e) & 0x8) ) + { + pCoexSta->highPriorityTx = 65535; + pCoexSta->highPriorityRx = 65535; + pCoexSta->lowPriorityTx = 65535; + pCoexSta->lowPriorityRx = 65535; + return; + } +#endif + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8821a1ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +BOOLEAN +halbtc8821a1ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE; + BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE; + BOOLEAN bWifiConnected=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + } + + return FALSE; +} + +VOID +halbtc8821a1ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } + + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8821a1ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8821A_1ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO only\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID only\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP only\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(HS) only\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = PAN(EDR) only\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP ==> SCO\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + PAN(EDR)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + PAN(EDR)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8821a1ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8821a1ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8821a1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8821a1ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!") )); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8821a1ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8821a1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8821a1ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8821a1ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8821a1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8821a1ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** CoexTable(%d) **********\n", type)); + + switch(type) + { + case 0: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 2: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 3: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 5: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 6: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0xaaaa5a5a, 0xffffff, 0x3); + break; + case 7: + halbtc8821a1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8821a1ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8821a1ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8821a1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8821a1ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + u1Byte realByte1=byte1, realByte5=byte5; + BOOLEAN bApEnable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + + if(bApEnable) + { + if(byte1&BIT4 && !(byte1&BIT5)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW for 1Ant AP mode\n")); + realByte1 &= ~BIT4; + realByte1 |= BIT5; + + realByte5 |= BIT5; + realByte5 &= ~BIT6; + } + } + + H2C_Parameter[0] = realByte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = realByte5; + + pCoexDm->psTdmaPara[0] = realByte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = realByte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + +VOID +halbtc8821a1ant_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 +halbtc8821a1ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8821a1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8821a1ant_SwMechanism( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRA + ) +{ + halbtc8821a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8821a1ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte fwVer=0, u4Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + if(bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + //0x765 = 0x18 + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x765, 0x18, 0x3); + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + //tell firmware "antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 1; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x1); //Main Ant to BT for IPS case 0x4c[23]=1 + } + else + { + //tell firmware "no antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 0; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + + //pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x64, 0x1, 0x0); //Aux Ant to BT for IPS case 0x4c[23]=1 + } + } + else if(bWifiOff) + { + // 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL BT Vendor 0xac=0xf002 + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &= ~BIT23; + u4Tmp &= ~BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + //0x765 = 0x18 + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x765, 0x18, 0x3); + } + else + { + //0x765 = 0x0 + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x765, 0x18, 0x0); + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_PATH_WIFI: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb4, 0x77); + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x1); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x2); + break; + case BTC_ANT_PATH_BT: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb4, 0x77); + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x2); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x1); + break; + default: + case BTC_ANT_PATH_PTA: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb4, 0x66); + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x1); + else + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x2); + break; + } +} + +VOID +halbtc8821a1ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0; + //u4Byte fwVer=0; + + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if (pCoexDm->bCurPsTdmaOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(off, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(bTurnOn) + { + switch(type) + { + default: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1a, 0x1a, 0x0, 0x50); + break; + case 1: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x3a, 0x03, 0x10, 0x50); + rssiAdjustVal = 11; + break; + case 2: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x2b, 0x03, 0x10, 0x50); + rssiAdjustVal = 14; + break; + case 3: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x1d, 0x1d, 0x0, 0x52); + break; + case 4: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0); + rssiAdjustVal = 17; + break; + case 5: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x15, 0x3, 0x11, 0x10); + break; + case 6: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x20, 0x3, 0x11, 0x13); + break; + case 7: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0); + break; + case 8: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + break; + case 9: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x21, 0x3, 0x10, 0x50); + rssiAdjustVal = 18; + break; + case 10: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40); + break; + case 11: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x15, 0x03, 0x10, 0x50); + rssiAdjustVal = 20; + break; + case 12: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x0a, 0x0a, 0x0, 0x50); + break; + case 13: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x12, 0x12, 0x0, 0x50); + break; + case 14: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x21, 0x3, 0x10, 0x52); + break; + case 15: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0); + break; + case 16: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0); + rssiAdjustVal = 18; + break; + case 18: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0); + rssiAdjustVal = 14; + break; + case 20: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x03, 0x11, 0x10); + break; + case 21: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x11); + break; + case 22: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x25, 0x03, 0x11, 0x10); + break; + case 23: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18); + rssiAdjustVal = 22; + break; + case 24: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18); + rssiAdjustVal = 22; + break; + case 25: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + rssiAdjustVal = 22; + break; + case 26: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18); + rssiAdjustVal = 22; + break; + case 27: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98); + rssiAdjustVal = 22; + break; + case 28: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0); + break; + case 29: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10); + break; + case 30: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x51, 0x30, 0x3, 0x10, 0x10); + break; + case 31: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58); + break; + case 32: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x61, 0x35, 0x3, 0x11, 0x11); + break; + case 33: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xa3, 0x25, 0x3, 0x30, 0x90); + break; + case 34: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1a, 0x1a, 0x0, 0x10); + break; + case 35: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x63, 0x1a, 0x1a, 0x0, 0x10); + break; + case 36: + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50); + break; + case 40: // SoftAP only with no sta associated,BT disable ,TDMA mode for power saving + /* here softap mode screen off will cost 70-80mA for phone */ + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x23, 0x18, 0x00, 0x10, 0x24); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 8: //PTA Control + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, FALSE, FALSE); + break; + case 0: + default: //Software control, Antenna at BT side + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); + break; + case 9: //Software control, Antenna at WiFi side + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_WIFI, FALSE, FALSE); + break; + case 10: // under 5G + halbtc8821a1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, FALSE); + break; + } + } + rssiAdjustVal =0; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal); + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8821a1ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // sw all off + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + // hw all off + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +BOOLEAN +halbtc8821a1ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n")); + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n")); + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + bCommon = TRUE; + } + else + { + if (bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + } + + bCommon = FALSE; + } + + return bCommon; +} + + +VOID +halbtc8821a1ant_TdmaDurationAdjustForAcl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0, btInfoExt; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjustForAcl()\n")); + + if( (BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) || + (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) || + (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) ) + { + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 3 && + pCoexDm->curPsTdma != 9 ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + return; + } + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + btInfoExt = pCoexSta->btInfoExt; + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + if(result == -1) + { + if( (BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + else if(result == 1) + { + if( (BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(btInfoExt)) && + ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + } + else //no change + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ********** TDMA(on, %d) **********\n", + pCoexDm->curPsTdma)); + } + + if( pCoexDm->curPsTdma != 1 && + pCoexDm->curPsTdma != 2 && + pCoexDm->curPsTdma != 9 && + pCoexDm->curPsTdma != 11 ) + { + // recover to previous adjust type + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + } +} + +VOID +halbtc8821a1ant_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 + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8821a1ant_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); + break; + case BTC_PS_LPS_ON: + halbtc8821a1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8821a1ant_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); + break; + case BTC_PS_LPS_OFF: + halbtc8821a1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + break; + default: + break; + } +} + +VOID +halbtc8821a1ant_CoexUnder5G( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8821a1ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, TRUE); + + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 10); + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 5); +} + +VOID +halbtc8821a1ant_ActionWifiOnly( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9); +} + +VOID +halbtc8821a1ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + halbtc8821a1ant_ActionWifiOnly(pBtCoexist); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL); + } + } +} + +//============================================= +// +// Software Coex Mechanism start +// +//============================================= + +// SCO only or SCO+PAN(HS) +VOID +halbtc8821a1ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8821a1ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, TRUE); +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8821a1ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8821a1ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8821a1ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(HS) only +VOID +halbtc8821a1ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); +} + +//PAN(EDR)+A2DP +VOID +halbtc8821a1ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); +} + +VOID +halbtc8821a1ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, TRUE); +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8821a1ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, TRUE); +} + +VOID +halbtc8821a1ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_SwMechanism(pBtCoexist, TRUE); +} + +//============================================= +// +// Non-Software Coex Mechanism start +// +//============================================= +VOID +halbtc8821a1ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8821a1ant_ActionHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); +} + +VOID +halbtc8821a1ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bApEnable=FALSE, bWifiBusy=FALSE, bBtBusy=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if((!bWifiConnected) && (!pCoexSta->bWiFiIsHighPriTask)) + { + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + } + else if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + // SCO/HID/A2DP busy + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if ((pBtLinkInfo->bPanExist) || (bWifiBusy)) + { + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } +} + +VOID +halbtc8821a1ant_ActionBtScoHidOnlyBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + // tdma and coex table + + if(pBtLinkInfo->bScoExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + else //HID + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 5); + } +} + +VOID +halbtc8821a1ant_ActionWifiConnectedBtAclBusy( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte wifiStatus + ) +{ + u1Byte btRssiState; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + btRssiState = halbtc8821a1ant_BtRssiState(2, 28, 0); + + if(pBtLinkInfo->bHidOnly) //HID + { + halbtc8821a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus); + pCoexDm->bAutoTdmaAdjust = FALSE; + return; + } + else if(pBtLinkInfo->bA2dpOnly) //A2DP + { + if(BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifiStatus) + { + //halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + //halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + } + else //for low BT RSSI + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + } + else if(pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) //HID+A2DP + { + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else //for low BT RSSI + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 6); + } + else if( (pBtLinkInfo->bPanOnly) || (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) ) //PAN(OPP,FTP), HID+PAN(OPP,FTP) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 6); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else if ( ((pBtLinkInfo->bA2dpExist) && (pBtLinkInfo->bPanExist)) || + (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist&&pBtLinkInfo->bPanExist) ) //A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + pCoexDm->bAutoTdmaAdjust = FALSE; + } +} + +VOID +halbtc8821a1ant_ActionWifiNotConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + // power save state + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + halbtc8821a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8821a1ant_ActionWifiNotConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8821a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + //halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + + //Bryant Add + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8821a1ant_ActionWifiNotConnectedAssoAuth( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if( (pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if( (pBtLinkInfo->bA2dpExist) || (pBtLinkInfo->bPanExist) ) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8821a1ant_ActionWifiConnectedScan( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + if (pBtLinkInfo->bA2dpExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if (pBtLinkInfo->bA2dpExist && pBtLinkInfo->bPanExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + } + else if( (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8821a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); + } + else + { + //halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + //halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1); + + //Bryant Add + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8821a1ant_ActionWifiConnectedSpecialPacket( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if((pBtLinkInfo->bScoExist) || (pBtLinkInfo->bHidExist) || (pBtLinkInfo->bA2dpExist)) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 32); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else if(pBtLinkInfo->bPanExist) + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 20); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 4); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } +} + +VOID +halbtc8821a1ant_ActionWifiConnected( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bWifiBusy=FALSE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + BOOLEAN bUnder4way=FALSE, bApEnable=FALSE; + u4Byte wifiBw; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect()===>\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + if(bUnder4way) + { + halbtc8821a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n")); + return; + } + + 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) + { + if(bScan) + halbtc8821a1ant_ActionWifiConnectedScan(pBtCoexist); + else + halbtc8821a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + // power save state + if(!bApEnable && BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->btLinkInfo.bHidOnly) + { + if(!bWifiBusy && pBtCoexist->btLinkInfo.bA2dpOnly) //A2DP + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + else + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + // tdma and coex table + if(!bWifiBusy) + { + if(BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8821a1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else if( (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8821a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + } + else + { + if(BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) + { + halbtc8821a1ant_ActionWifiConnectedBtAclBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else if( (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + halbtc8821a1ant_ActionBtScoHidOnlyBusy(pBtCoexist, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); + } + else + { + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + } +} + +VOID +halbtc8821a1ant_RunSwCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte algorithm=0; + + algorithm = halbtc8821a1ant_ActionAlgorithm(pBtCoexist); + pCoexDm->curAlgorithm = algorithm; + + if(halbtc8821a1ant_IsCommonAction(pBtCoexist)) + { + + } + else + { + switch(pCoexDm->curAlgorithm) + { + case BT_8821A_1ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = SCO.\n")); + halbtc8821a1ant_ActionSco(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID.\n")); + halbtc8821a1ant_ActionHid(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP.\n")); + halbtc8821a1ant_ActionA2dp(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n")); + halbtc8821a1ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR).\n")); + halbtc8821a1ant_ActionPanEdr(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HS mode.\n")); + halbtc8821a1ant_ActionPanHs(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN+A2DP.\n")); + halbtc8821a1ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n")); + halbtc8821a1ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n")); + halbtc8821a1ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8821A_1ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = HID+A2DP.\n")); + halbtc8821a1ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action algorithm = coexist All Off!!\n")); + //halbtc8821a1ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8821a1ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + BOOLEAN bIncreaseScanDevNum=FALSE; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + u1Byte wifiRssiState=BTC_RSSI_STATE_HIGH; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bWifiUnder5G=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + if(pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n")); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + if(bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for 5G <===\n")); + halbtc8821a1ant_CoexUnder5G(pBtCoexist); + return; + } + + if( (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bIncreaseScanDevNum = TRUE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, &bIncreaseScanDevNum); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if((numOfWifiLink>=2) || (wifiLinkStatus&WIFI_P2P_GO_CONNECTED)) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8821a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(!pBtLinkInfo->bScoExist && !pBtLinkInfo->bHidExist) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + } + else + { + if(bWifiConnected) + { + wifiRssiState = halbtc8821a1ant_WifiRssiState(pBtCoexist, 1, 2, 30, 0); + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 1, 1); + } + else + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 1, 1, 1, 1); + } + } + else + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + } + + } + + if(pBtLinkInfo->bScoExist) + { + bBtCtrlAggBufSize = TRUE; + aggBufSize = 0x3; + } + else if(pBtLinkInfo->bHidExist) + { + bBtCtrlAggBufSize = TRUE; + aggBufSize = 0x5; + } + else if(pBtLinkInfo->bA2dpExist || pBtLinkInfo->bPanExist) + { + bBtCtrlAggBufSize = TRUE; + aggBufSize = 0x8; + } + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + + halbtc8821a1ant_RunSwCoexistMechanism(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8821a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8821a1ant_ActionHs(pBtCoexist); + return; + } + + + if(!bWifiConnected) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is non connected-idle !!!\n")); + + 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) + { + if (bScan) + halbtc8821a1ant_ActionWifiNotConnectedScan(pBtCoexist); + else + halbtc8821a1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else + halbtc8821a1ant_ActionWifiNotConnected(pBtCoexist); + } + else // wifi LPS/Busy + { + halbtc8821a1ant_ActionWifiConnected(pBtCoexist); + } +} + +VOID +halbtc8821a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + // sw all off + halbtc8821a1ant_SwMechanism(pBtCoexist, FALSE); + + //halbtc8821a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); +} + +VOID +halbtc8821a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp, + IN BOOLEAN bWifiOnly + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + BOOLEAN bWifiUnder5G=FALSE; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 1Ant Init HW Config!!\n")); + + if(bWifiOnly) + return; + + if(bBackUp) + { + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + } + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + //Antenna config + if(bWifiUnder5G) + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, TRUE, FALSE); + else + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_PTA, TRUE, FALSE); + + // PTA parameter + halbtc8821a1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + // Enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); +} + +//============================================================ +// work around function start with wa_halbtc8821a1ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8821a1ant_ +//============================================================ +VOID +EXhalbtc8821a1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8821a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8821a1ant_InitHwConfig(pBtCoexist, TRUE, bWifiOnly); +} + +VOID +EXhalbtc8821a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + pBtCoexist->bStopCoexDm = FALSE; + + halbtc8821a1ant_InitCoexDm(pBtCoexist); + + halbtc8821a1ant_QueryBtInfo(pBtCoexist); +} + +VOID +EXhalbtc8821a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u2Byte u2Tmp[4]; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + if(pBtCoexist->bStopCoexDm) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Ant PG Num/ Ant Mech/ Ant Pos:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8821a1Ant, GLCoexVer8821a1Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": + ( (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + pCoexSta->btRssi, 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); + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8821a1Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + if(!pBtCoexist->bManualControl) + { + // Sw mechanism + 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", "SM[LowPenaltyRA]", \ + pCoexDm->bCurLowPenaltyRa); + 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); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \ + pBtCoexist->btInfo.raMask); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \ + pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \ + pCoexDm->errorCondition); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "backup ARFR1/ARFR2/RL/AMaxTime", \ + pCoexDm->backupArfrCnt1, pCoexDm->backupArfrCnt2, pCoexDm->backupRetryLimit, pCoexDm->backupAmpduMaxTime); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + u2Tmp[0] = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", "0x430/0x434/0x42a/0x456", \ + u4Tmp[0], u4Tmp[1], u2Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc58); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]", \ + u1Tmp[0], (u4Tmp[0]&0x3e000000) >> 25); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x8db); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8db[6:5]", \ + ((u1Tmp[0]&0x60)>>5)); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x975); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcb4); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]", \ + (u4Tmp[0]&0x30000000)>>28, u4Tmp[0]&0xff, u1Tmp[0]& 0x3); + CL_PRINTF(cliBuf); + + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x64); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x40/0x4c[24:23]/0x64[0]", \ + u1Tmp[0], ((u4Tmp[0]&0x01800000)>>23), u1Tmp[1]&0x1); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ + u4Tmp[0]&0xff); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf48); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5d); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA", \ + u4Tmp[0], (u1Tmp[0]<<8) + u1Tmp[1] ); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8821A_1ANT == 1) + halbtc8821a1ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8821a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u4Byte u4Tmp=0; + + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + //halbtc8821a1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + + halbtc8821a1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8821a1ant_InitCoexDm(pBtCoexist); + halbtc8821a1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8821a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(pBtCoexist->bManualControl || pBtCoexist->bStopCoexDm) + return; + + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8821a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm ) + return; + + if(BTC_SCAN_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + + halbtc8821a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8); //Force antenna setup for no scan result issue + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } + + if(pBtCoexist->btInfo.bBtDisabled) + return; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + halbtc8821a1ant_QueryBtInfo(pBtCoexist); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8821a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8821a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8821a1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_SCAN_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8821a1ant_ActionWifiNotConnectedScan(pBtCoexist); + } + else // wifi is connected + { + halbtc8821a1ant_ActionWifiConnectedScan(pBtCoexist); + } + } + else if(BTC_SCAN_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + if(!bWifiConnected) // non-connected scan + { + halbtc8821a1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8821a1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8821a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_ASSOCIATE_START == type) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + pCoexDm->nArpCnt = 0; + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + pCoexDm->nArpCnt = 0; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8821a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8821a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8821a1ant_ActionHs(pBtCoexist); + return; + } + + if(BTC_ASSOCIATE_START == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + halbtc8821a1ant_ActionWifiNotConnectedAssoAuth(pBtCoexist); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(!bWifiConnected) // non-connected scan + { + halbtc8821a1ant_ActionWifiNotConnected(pBtCoexist); + } + else + { + halbtc8821a1ant_ActionWifiConnected(pBtCoexist); + } + } +} + +VOID +EXhalbtc8821a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + pCoexDm->nArpCnt = 0; + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + //H2C_Parameter[0] = 0x1; + H2C_Parameter[0] = 0x0; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8821a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + BOOLEAN bBtHsOn=FALSE; + u4Byte wifiLinkStatus=0; + u4Byte numOfWifiLink=0; + BOOLEAN bBtCtrlAggBufSize=FALSE; + u1Byte aggBufSize=5; + + if(pBtCoexist->bManualControl || + pBtCoexist->bStopCoexDm || + pBtCoexist->btInfo.bBtDisabled ) + return; + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + pCoexSta->bWiFiIsHighPriTask = TRUE; + + if(BTC_PACKET_ARP == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet ARP notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet DHCP or EAPOL notify\n")); + } + } + else + { + pCoexSta->bWiFiIsHighPriTask = FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet [Type = %d] notify\n", type)); + } + + pCoexSta->specialPktPeriodCnt = 0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_LINK_STATUS, &wifiLinkStatus); + numOfWifiLink = wifiLinkStatus>>16; + if(numOfWifiLink >= 2) + { + halbtc8821a1ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0); + halbtc8821a1ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, bBtCtrlAggBufSize, aggBufSize); + halbtc8821a1ant_ActionWifiMultiPort(pBtCoexist); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + if(pCoexSta->bC2hBtInquiryPage) + { + halbtc8821a1ant_ActionBtInquiry(pBtCoexist); + return; + } + else if(bBtHsOn) + { + halbtc8821a1ant_ActionHs(pBtCoexist); + return; + } + + if( BTC_PACKET_DHCP == type || + BTC_PACKET_EAPOL == type || + BTC_PACKET_ARP == type ) + { + //RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], special Packet(%d) notify\n", type)); + if(BTC_PACKET_ARP == type) + { + pCoexDm->nArpCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ARP Packet Count = %d\n", pCoexDm->nArpCnt)); + if(pCoexDm->nArpCnt >= 10) // if APR PKT > 10 after connect, do not go to ActionWifiConnectedSpecialPacket(pBtCoexist) + return; + } + + halbtc8821a1ant_ActionWifiConnectedSpecialPacket(pBtCoexist); + } +} + +VOID +EXhalbtc8821a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bBtBusy=FALSE; + BOOLEAN bWifiUnder5G=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8821A_1ANT_MAX) + rspSource = BT_INFO_SRC_8821A_1ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(BT_INFO_SRC_8821A_1ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + if (pCoexSta->btInfoC2h[rspSource][2]&0x20) + pCoexSta->bC2hBtPage = TRUE; + else + pCoexSta->bC2hBtPage = FALSE; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if(!pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x15 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x15); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if(pCoexSta->btInfoExt & BIT1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(bWifiConnected) + { + EXhalbtc8821a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8821a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + if( (pCoexSta->btInfoExt & BIT3) && !bWifiUnder5G) + { + if(!pBtCoexist->bManualControl && !pBtCoexist->bStopCoexDm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8821a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + } +#if(BT_AUTO_REPORT_ONLY_8821A_1ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8821a1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8821A_1ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8821A_1ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8821A_1ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8821A_1ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8821A_1ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8821A_1ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + } + + halbtc8821a1ant_UpdateBtLinkInfo(pBtCoexist); + + btInfo = btInfo & 0x1f; //mask profile bit for connect-ilde identification ( for CSR case: A2DP idle --> 0x41) + + if(!(btInfo&BT_INFO_8821A_1ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8821A_1ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8821A_1ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8821A_1ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8821A_1ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8821A_1ANT_B_ACL_BUSY) + { + if(BT_8821A_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus) + pCoexDm->bAutoTdmaAdjust = FALSE; + pCoexDm->btStatus = BT_8821A_1ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8821A_1ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + bBtBusy = TRUE; + else + bBtBusy = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + halbtc8821a1ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8821a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte u4Tmp; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + //halbtc8821a1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); + + halbtc8821a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8821a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + + pBtCoexist->bStopCoexDm = TRUE; +} + +VOID +EXhalbtc8821a1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + + halbtc8821a1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8821a1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + halbtc8821a1ant_SetAntPath(pBtCoexist, BTC_ANT_PATH_BT, FALSE, TRUE); + //halbtc8821a1ant_SetAntPathDCut(pBtCoexist, FALSE, FALSE, FALSE, BTC_ANT_PATH_BT, BTC_WIFI_STAT_NORMAL_OFF); + + pBtCoexist->bStopCoexDm = TRUE; + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + pBtCoexist->bStopCoexDm = FALSE; + halbtc8821a1ant_InitHwConfig(pBtCoexist, FALSE, FALSE); + halbtc8821a1ant_InitCoexDm(pBtCoexist); + halbtc8821a1ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8821a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8821a1Ant, GLCoexVer8821a1Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + +#if(BT_AUTO_REPORT_ONLY_8821A_1ANT == 0) + halbtc8821a1ant_QueryBtInfo(pBtCoexist); + halbtc8821a1ant_MonitorBtCtr(pBtCoexist); + halbtc8821a1ant_MonitorBtEnableDisable(pBtCoexist); +#else + if( halbtc8821a1ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust ) + { + //if(pCoexSta->specialPktPeriodCnt > 2) + //{ + halbtc8821a1ant_RunCoexistMechanism(pBtCoexist); + //} + } + + pCoexSta->specialPktPeriodCnt++; +#endif +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.h new file mode 100644 index 00000000..4c7469ef --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a1Ant.h @@ -0,0 +1,213 @@ +//=========================================== +// The following is for 8821A 1ANT BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8821A_1ANT 1 + +#define BT_INFO_8821A_1ANT_B_FTP BIT7 +#define BT_INFO_8821A_1ANT_B_A2DP BIT6 +#define BT_INFO_8821A_1ANT_B_HID BIT5 +#define BT_INFO_8821A_1ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8821A_1ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8821A_1ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8821A_1ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8821A_1ANT_B_CONNECTION BIT0 + +#define BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ + (((_BT_INFO_EXT_&BIT0))? TRUE:FALSE) + +#define BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT 2 + +typedef enum _BT_INFO_SRC_8821A_1ANT{ + BT_INFO_SRC_8821A_1ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8821A_1ANT_BT_RSP = 0x1, + BT_INFO_SRC_8821A_1ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8821A_1ANT_MAX +}BT_INFO_SRC_8821A_1ANT,*PBT_INFO_SRC_8821A_1ANT; + +typedef enum _BT_8821A_1ANT_BT_STATUS{ + BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8821A_1ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8821A_1ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8821A_1ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8821A_1ANT_BT_STATUS_MAX +}BT_8821A_1ANT_BT_STATUS,*PBT_8821A_1ANT_BT_STATUS; + +typedef enum _BT_8821A_1ANT_WIFI_STATUS{ + BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, + BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, + BT_8821A_1ANT_WIFI_STATUS_MAX +}BT_8821A_1ANT_WIFI_STATUS,*PBT_8821A_1ANT_WIFI_STATUS; + +typedef enum _BT_8821A_1ANT_COEX_ALGO{ + BT_8821A_1ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8821A_1ANT_COEX_ALGO_SCO = 0x1, + BT_8821A_1ANT_COEX_ALGO_HID = 0x2, + BT_8821A_1ANT_COEX_ALGO_A2DP = 0x3, + BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8821A_1ANT_COEX_ALGO_PANEDR = 0x5, + BT_8821A_1ANT_COEX_ALGO_PANHS = 0x6, + BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8821A_1ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8821A_1ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8821A_1ANT_COEX_ALGO_MAX = 0xb, +}BT_8821A_1ANT_COEX_ALGO,*PBT_8821A_1ANT_COEX_ALGO; + +typedef struct _COEX_DM_8821A_1ANT{ + // fw mechanism + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; + + // sw mechanism + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + + u4Byte backupArfrCnt1; // Auto Rate Fallback Retry cnt + u4Byte backupArfrCnt2; // Auto Rate Fallback Retry cnt + u2Byte backupRetryLimit; + u1Byte backupAmpduMaxTime; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + u4Byte preRaMask; + u4Byte curRaMask; + u1Byte preArfrType; + u1Byte curArfrType; + u1Byte preRetryLimitType; + u1Byte curRetryLimitType; + u1Byte preAmpduTimeType; + u1Byte curAmpduTimeType; + u4Byte nArpCnt; + + u1Byte errorCondition; +} COEX_DM_8821A_1ANT, *PCOEX_DM_8821A_1ANT; + +typedef struct _COEX_STA_8821A_1ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte specialPktPeriodCnt; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8821A_1ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8821A_1ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + BOOLEAN bC2hBtPage; //Add for win8.1 page out issue + BOOLEAN bWiFiIsHighPriTask; //Add for win8.1 page out issue + u1Byte btRetryCnt; + u1Byte btInfoExt; +}COEX_STA_8821A_1ANT, *PCOEX_STA_8821A_1ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8821a1ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a1ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8821a1ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a1ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a1ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8821a1ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a1ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8821a1ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a1ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.c new file mode 100644 index 00000000..f107bb84 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.c @@ -0,0 +1,4858 @@ +//============================================================ +// Description: +// +// This file is for RTL8821A Co-exist mechanism +// +// History +// 2012/11/15 Cosa first check in. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtc8821a2Ant.tmh" +#endif + +#if (RTL8821A_SUPPORT == 1) + +#if(BT_30_SUPPORT == 1) +//============================================================ +// Global variables, these are static variables +//============================================================ +static COEX_DM_8821A_2ANT GLCoexDm8821a2Ant; +static PCOEX_DM_8821A_2ANT pCoexDm=&GLCoexDm8821a2Ant; +static COEX_STA_8821A_2ANT GLCoexSta8821a2Ant; +static PCOEX_STA_8821A_2ANT pCoexSta=&GLCoexSta8821a2Ant; + +const char *const GLBtInfoSrc8821a2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8821a2Ant=20150921; +u4Byte GLCoexVer8821a2Ant=0x58; +//modify 20140903v43 a2dpandhid tdmaonoff a2dp glitch _ tdma off 778=3(case1)->778=1(case0) +//and to improve tp while a2dphid case23->case25 , case123->case125 for asus spec +//and modify for asus bt WHQL test _ tdma off_ 778=3->1_ +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8821a2ant_ +//============================================================ +u1Byte +halbtc8821a2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8821a2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8821a2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + } + } +} + +VOID +halbtc8821a2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +VOID +halbtc8821a2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + if ( (pCoexSta->lowPriorityRx >= 950) && (pCoexSta->lowPriorityRx >= pCoexSta->lowPriorityTx) && (!pCoexSta->bUnderIps) ) + { + pBtLinkInfo->bSlaveRole = TRUE; + } + else + { + pBtLinkInfo->bSlaveRole = FALSE; + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); +} + +VOID +halbtc8821a2ant_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 +halbtc8821a2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +BOOLEAN +halbtc8821a2ant_IsWifiStatusChanged( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way); + + if(bWifiConnected) + { + if(bWifiBusy != bPreWifiBusy) + { + bPreWifiBusy = bWifiBusy; + return TRUE; + } + if(bUnder4way != bPreUnder4way) + { + bPreUnder4way = bUnder4way; + return TRUE; + } + if(bBtHsOn != bPreBtHsOn) + { + bPreBtHsOn = bBtHsOn; + return TRUE; + } + + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist,3, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + + if ( (BTC_RSSI_STATE_HIGH ==wifiRssiState ) || (BTC_RSSI_STATE_LOW ==wifiRssiState )) + { + return TRUE; + } + + } + + return FALSE; +} + +VOID +halbtc8821a2ant_UpdateBtLinkInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + +#if(BT_AUTO_REPORT_ONLY_8821A_2ANT == 1) // profile from bt patch + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pBtLinkInfo->bScoExist = pCoexSta->bScoExist; + pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist; + pBtLinkInfo->bPanExist = pCoexSta->bPanExist; + pBtLinkInfo->bHidExist = pCoexSta->bHidExist; + + // work around for HS mode. + if(bBtHsOn) + { + pBtLinkInfo->bPanExist = TRUE; + pBtLinkInfo->bBtLinkExist = TRUE; + } +#else // profile from bt stack + pBtLinkInfo->bBtLinkExist = pStackInfo->bBtLinkExist; + pBtLinkInfo->bScoExist = pStackInfo->bScoExist; + pBtLinkInfo->bA2dpExist = pStackInfo->bA2dpExist; + pBtLinkInfo->bPanExist = pStackInfo->bPanExist; + pBtLinkInfo->bHidExist = pStackInfo->bHidExist; + + //for win-8 stack HID report error + if(!pStackInfo->bHidExist) + pStackInfo->bHidExist = pCoexSta->bHidExist; //sync BTInfo with BT firmware and stack + // when stack HID report error, here we use the info from bt fw. + if(!pStackInfo->bBtLinkExist) + pStackInfo->bBtLinkExist = pCoexSta->bBtLinkExist; +#endif + // check if Sco only + if( pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bScoOnly = TRUE; + else + pBtLinkInfo->bScoOnly = FALSE; + + // check if A2dp only + if( !pBtLinkInfo->bScoExist && + pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bA2dpOnly = TRUE; + else + pBtLinkInfo->bA2dpOnly = FALSE; + + // check if Pan only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + pBtLinkInfo->bPanExist && + !pBtLinkInfo->bHidExist ) + pBtLinkInfo->bPanOnly = TRUE; + else + pBtLinkInfo->bPanOnly = FALSE; + + // check if Hid only + if( !pBtLinkInfo->bScoExist && + !pBtLinkInfo->bA2dpExist && + !pBtLinkInfo->bPanExist && + pBtLinkInfo->bHidExist ) + pBtLinkInfo->bHidOnly = TRUE; + else + pBtLinkInfo->bHidOnly = FALSE; +} + +u1Byte +halbtc8821a2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8821A_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(!pBtLinkInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No BT link exists!!!\n")); + return algorithm; + } + + if(pBtLinkInfo->bScoExist) + numOfDiffProfile++; + if(pBtLinkInfo->bHidExist) + numOfDiffProfile++; + if(pBtLinkInfo->bPanExist) + numOfDiffProfile++; + if(pBtLinkInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pBtLinkInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pBtLinkInfo->bScoExist) + { + if(pBtLinkInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else if(pBtLinkInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { +#if 0 + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else +#endif + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> SCO\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS) ==> SCO\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR) ==> SCO\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + else if( pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } + else + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pBtLinkInfo->bScoExist) + { + if( pBtLinkInfo->bHidExist && + pBtLinkInfo->bPanExist && + pBtLinkInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; + } + } + } + } + + return algorithm; +} + +VOID +halbtc8821a2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8821a2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte decBtPwrLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = decBtPwrLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power level = %d, FW write 0x62=0x%x\n", + decBtPwrLvl, H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, H2C_Parameter); +} + +VOID +halbtc8821a2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte decBtPwrLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power level = %d\n", + (bForceExec? "force to":""), decBtPwrLvl)); + pCoexDm->curBtDecPwrLvl = decBtPwrLvl; + + if(!bForceExec) + { + if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl) + return; + } + halbtc8821a2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl); + + pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl; +} + +VOID +halbtc8821a2ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8821a2ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + halbtc8821a2ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8821a2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8821a2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8821a2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8821a2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8821a2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8821a2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf5; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xa0; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xa0; //MCS5 or OFDM36 + //H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + //H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + //H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!")) ); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8821a2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + //return; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8821a2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8821a2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc5b, 0x3e, val); +} + +VOID +halbtc8821a2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8821a2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8821a2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8821a2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8821a2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8821a2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x1); + } +} + +VOID +halbtc8821a2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8821a2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8821a2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + //=================BB AGC Gain Table + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table On!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6e1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6d1B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6c1C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6b1D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x6a1E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x691F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0x68200001); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB Agc Table Off!\n")); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xaa1A0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa91B0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa81C0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa71D0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa61E0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa51F0001); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0xc78, 0xa4200001); + } + + + //=================RF Gain + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38fff); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x38ffe); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x380c3); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x40, 0xfffff, 0x28ce6); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + if(bAgcTableEn) + { + rssiAdjustVal = 8; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + +VOID +halbtc8821a2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8821a2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8821a2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8821a2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8821a2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8821a2ant_CoexTableWithType( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexSta->nCoexTableType = type; + + switch(type) + { + case 0: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3); + break; + case 1: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5afa5afa, 0xffffff, 0x3); + break; + case 2: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x5ada5ada, 0x5ada5ada, 0xffffff, 0x3); + break; + case 3: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 4: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffffff, 0x3); + break; + case 5: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffffff, 0x3); + break; + case 6: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffffff, 0x3); + break; + case 7: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 8: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 9: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 10: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 11: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 12: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0x5ada5ada, 0xffffff, 0x3); + break; + case 13: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 14: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5ada5ada, 0xffffff, 0x3); + break; + case 15: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x55dd55dd, 0xaaaaaaaa, 0xffffff, 0x3); + break; + case 16: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0x5fdf5fdf, 0x5fdb5fdb, 0xffffff, 0x3); + break; + case 17: + halbtc8821a2ant_CoexTable(pBtCoexist, bForceExec, 0xfafafafa, 0xfafafafa, 0xffffff, 0x3); + break; + default: + break; + } +} + +VOID +halbtc8821a2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8821a2ant_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 +halbtc8821a2ant_LpsRpwm( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte lpsVal, + IN u1Byte rpwmVal + ) +{ + BOOLEAN bForceExecPwrCmd=FALSE; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n", + (bForceExec? "force to":""), lpsVal, rpwmVal)); + pCoexDm->curLps = lpsVal; + pCoexDm->curRpwm = rpwmVal; + + if(!bForceExec) + { + if( (pCoexDm->preLps == pCoexDm->curLps) && + (pCoexDm->preRpwm == pCoexDm->curRpwm) ) + { + return; + } + } + halbtc8821a2ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal); + + pCoexDm->preLps = pCoexDm->curLps; + pCoexDm->preRpwm = pCoexDm->curRpwm; +} + +VOID +halbtc8821a2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + halbtc8821a2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8821a2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[5] ={0}; + + H2C_Parameter[0] = byte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = byte5; + + pCoexDm->psTdmaPara[0] = byte1; + pCoexDm->psTdmaPara[1] = byte2; + pCoexDm->psTdmaPara[2] = byte3; + pCoexDm->psTdmaPara[3] = byte4; + pCoexDm->psTdmaPara[4] = byte5; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 5, H2C_Parameter); +} + +VOID +halbtc8821a2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + /* + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + */ + + //halbtc8821a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + halbtc8821a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); +} + +VOID +halbtc8821a2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + //halbtc8821a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + //halbtc8821a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + halbtc8821a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8821a2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + if(bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x974, 0x3ff); + //pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb4, 0x77); + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + //tell firmware "antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 1; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + else + { + //tell firmware "no antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 0; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x1); + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x2); + break; + } +} + +VOID +halbtc8821a2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + u1Byte wifiRssiState1, btRssiState; + + + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_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 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(bTurnOn) + { + switch(type) + { + case 1: + default: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 2: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); + break; + case 3: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); + break; + case 4: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x03, 0xf1, 0x90); + break; + case 5: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); + break; + case 6: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); + break; + case 7: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); + break; + case 8: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x10, 0x3, 0x70, 0x90); + break; + case 9: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 10: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x03, 0xf1, 0x90); + break; + case 11: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); + break; + case 12: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0xf1, 0x90); + break; + case 13: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x3, 0x70, 0x90); + break; + case 14: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x2d, 0x3, 0x70, 0x90); + break; + case 15: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); + break; + case 16: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x90); + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x3, 0x70, 0x90); + break; + case 17: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x90); + break; + case 18: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 23: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1e, 0x03, 0xf0, 0x14); + break; + case 24: + case 124: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x3c, 0x03, 0x70, 0x50); + break; + //case25/case125 : for lenovo bt pan tp degrade<30% while wifi downlink + case 25: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x14, 0x03, 0xf1, 0x90); + break; + case 26: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x30, 0x03, 0xf1, 0x90); + break; + case 71: + //halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 101: + case 105: + case 171: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x3a, 0x03, 0x70, 0x50); + break; + case 102: + case 106: + case 110: + case 114: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x2d, 0x03, 0x70, 0x50); + break; + case 103: + case 107: + case 111: + case 115: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1c, 0x03, 0x70, 0x50); + break; + case 104: + case 108: + case 112: + case 116: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x10, 0x03, 0x70, 0x50); + break; + case 109: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0xf1, 0x90); + break; + case 113: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x3c, 0x03, 0x70, 0x90); + break; + case 121: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 22: + case 122: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x35, 0x03, 0x71, 0x11); + break; + case 123: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1c, 0x03, 0x70, 0x54); + break; + //case25/case125 : for lenovo bt pan tp degrade<30% while wifi downlink + case 125: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x14, 0x03, 0x70, 0x50); + break; + case 126: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0xd3, 0x30, 0x03, 0x70, 0x50); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 0: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + case 1: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + break; + default: + halbtc8821a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8821a2ant_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 + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + } + else // NO PS state + { + if(bNewPsState) + { + // will enter LPS state, turn off psTdma first + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + // keep state under NO PS state, do nothing. + } + } +} + +VOID +halbtc8821a2ant_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: + halbtc8821a2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, TRUE); + halbtc8821a2ant_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: + halbtc8821a2ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL); + pCoexSta->bForceLpsOn = FALSE; + break; + default: + break; + } +} + + +VOID +halbtc8821a2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8821a2ant_CoexUnder5G( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a2ant_CoexAllOff(pBtCoexist); + + halbtc8821a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, TRUE); +} + +VOID +halbtc8821a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8821a2ant_ActionBtInquiry( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + BOOLEAN bWifiConnected=FALSE; + BOOLEAN bLowPwrDisable=TRUE; + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_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); + + 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); + + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + if(bScan || bLink || bRoam) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi link process + BT Inq/Page!!\n")); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT Inq/Page!!\n")); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi no-link + BT Inq/Page!!\n")); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + +} + + +VOID +halbtc8821a2ant_ActionWiFiLinkProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte u1Tmpa, u1Tmpb; + + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 15); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + + + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x765=0x%x, 0x76e=0x%x\n", u1Tmpa, u1Tmpb)); +} + +BOOLEAN +halbtc8821a2ant_ActionWifiIdleProcess( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + //wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES-20, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_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)) + { + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle process for BT HID+A2DP exist!!\n")); + + halbtc8821a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + return TRUE; + } + + // + else if (pCoexSta->bPanExist== TRUE) + { + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi idle process for BT PAN exist!!\n")); + + halbtc8821a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + return TRUE; + } + + else + { + halbtc8821a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, TRUE, 0x18); + return FALSE; + } + + +} + + + +BOOLEAN +halbtc8821a2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte btRssiState=BTC_RSSI_STATE_HIGH; + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + BOOLEAN bBtHsOn=FALSE, bLowPwrDisable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi non-connected idle!!\n")); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + if(BT_8821A_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT non connected-idle!!\n")); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else if(BT_8821A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bBtHsOn) + return FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi connected + BT connected-idle!!\n")); + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xb); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + bCommon = TRUE; + } + else + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Busy + BT Busy!!\n")); + bCommon = FALSE; + //bCommon = halbtc8821a2ant_ActionWifiIdleProcess(pBtCoexist); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Connected-Idle + BT Busy!!\n")); + //bCommon = FALSE; + bCommon = halbtc8821a2ant_ActionWifiIdleProcess(pBtCoexist); + } + } + } + + return bCommon; +} +VOID +halbtc8821a2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(!pCoexDm->bAutoTdmaAdjust) + { + pCoexDm->bAutoTdmaAdjust = TRUE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 71) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 71) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } +} + +// SCO only or SCO+PAN(HS) +VOID +halbtc8821a2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 4); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for SCO quality at 11b/g mode + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + else //for SCO quality & wifi performance balance at 11n mode + { + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 8); + else + { + if(pBtLinkInfo->bScoOnly) + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 17); + else + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 12); + } + } + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x18); + } + } +} + + +VOID +halbtc8821a2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2); + } + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 24); + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8821a2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_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) && BTC_RSSI_HIGH(btRssiState)) + { + //DbgPrint(" AP#>10(%d)\n", apNum); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + //halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,TRUE,0x6); + } + return; + + } + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + //halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + } + else + { + //halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821a2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821a2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 10); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 26); + } + else + { + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 26); + } + + // sw mechanism + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + + +//PAN(HS) only +VOID +halbtc8821a2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8821a2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + else + halbtc8821a2ant_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) ) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 12); + + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + else + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 13); + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821a2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8821a2ant_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) + { + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 3); + //halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 11); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); + } + else + { + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + } + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + } + else + { + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + //halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8821a2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,wifiRssiState1, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(2, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 0); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, FALSE, 0x8); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8821a2ant_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) ) + { + if(BTC_WIFI_BW_HT40 == wifiBw) + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + else + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else + { + halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821a2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, wifiRssiState1, btRssiState; + u4Byte wifiBw; + u1Byte apNum=0; + + wifiRssiState = halbtc8821a2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + //btRssiState = halbtc8821a2ant_BtRssiState(2, 29, 0); + wifiRssiState1 = halbtc8821a2ant_WifiRssiState(pBtCoexist, 1, 2, BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES, 0); + btRssiState = halbtc8821a2ant_BtRssiState(3, BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES, 37); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + + halbtc8821a2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x5); + + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_LEGACY == wifiBw) + { + if(BTC_RSSI_HIGH(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + else + { // only 802.11N mode we have to dec bt power to 4 degree + if(BTC_RSSI_HIGH(btRssiState)) + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + // need to check ap Number of Not + if(apNum < 10) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 4); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + } + else if(BTC_RSSI_MEDIUM(btRssiState)) + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2); + else + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + } + + if (BTC_RSSI_HIGH(wifiRssiState1) && BTC_RSSI_HIGH(btRssiState)) + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + } + else + { + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 14); + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x4); + } + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + //halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + } + else + { + //halbtc8821a2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + } + + // sw mechanism + if(BTC_WIFI_BW_HT40 == wifiBw) + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821a2ant_ActionBtWhckTest( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); +} + +VOID +halbtc8821a2ant_ActionWifiMultiPort( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0); + + // sw all off + halbtc8821a2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821a2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + //pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + halbtc8821a2ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0); + + halbtc8821a2ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); + halbtc8821a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); +} + +VOID +halbtc8821a2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + 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; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism()===>\n")); + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + if(bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n")); + halbtc8821a2ant_CoexUnder5G(pBtCoexist); + return; + } + + if(pCoexSta->bUnderIps) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi is under IPS !!!\n")); + return; + } + + if(pCoexSta->bBtWhckTest) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under WHCK TEST!!!\n")); + halbtc8821a2ant_ActionBtWhckTest(pBtCoexist); + return; + } + + algorithm = halbtc8821a2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bC2hBtInquiryPage && (BT_8821A_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8821a2ant_ActionBtInquiry(pBtCoexist); + return; + } + else + { + + } + + 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) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], WiFi is under Link Process !!\n")); + halbtc8821a2ant_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)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [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); + halbtc8821a2ant_ActionWifiMultiPort(pBtCoexist); + + return; + } + else + { + bMiracastPlusBt = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_MIRACAST_PLUS_BT, &bMiracastPlusBt); + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8821a2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bAutoTdmaAdjust = FALSE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8821A_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8821a2ant_ActionSco(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8821a2ant_ActionHid(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8821a2ant_ActionA2dp(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8821a2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8821a2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8821a2ant_ActionPanHs(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8821a2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8821a2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8821a2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8821A_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8821a2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8821a2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } +} + +VOID +halbtc8821a2ant_WifiOffHwCfg( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bIsInMpMode = FALSE; + u1Byte H2C_Parameter[2] ={0}; + u4Byte fwVer=0; + + // set wlan_act to low + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); //WiFi goto standby while GNT_BT 0-->1 + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + if(fwVer >= 0x180000) + { + /* Use H2C to set GNT_BT to HIGH */ + H2C_Parameter[0] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x6E, 1, H2C_Parameter); + } + else + { + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x765, 0x18); + } +} + +VOID +halbtc8821a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bBackUp + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0, fwVer; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = + pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + + //Antenna config + halbtc8821a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, TRUE, FALSE); + pCoexSta->disVerInfoCnt = 0; + + // PTA parameter + halbtc8821a2ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0); + + // Enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x4); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); +} + +//============================================================ +// work around function start with wa_halbtc8821a2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8821a2ant_ +//============================================================ +VOID +EXhalbtc8821a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ + +} + +VOID +EXhalbtc8821a2ant_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) + // Local setting bit define + // BIT0: "0" for no antenna inverse; "1" for antenna inverse + // BIT1: "0" for internal switch; "1" for external switch + // BIT2: "0" for one antenna; "1" for two antenna + // NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and BIT2=0 + if(pBtCoexist->chipInterface == BTC_INTF_USB) + { + // fixed at S0 for USB interface + u1Tmp |= 0x1; // antenna inverse + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0xfe08, u1Tmp); + } + else + { + // for PCIE and SDIO interface, we check efuse 0xc3[6] + if(pBoardInfo->singleAntPath == 0) + { + } + else if(pBoardInfo->singleAntPath == 1) + { + // set to S0 + u1Tmp |= 0x1; // antenna inverse + } + + if(pBtCoexist->chipInterface == BTC_INTF_PCI) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x384, u1Tmp); + } + else if(pBtCoexist->chipInterface == BTC_INTF_SDIO) + { + pBtCoexist->fBtcWriteLocalReg1Byte(pBtCoexist, 0x60, u1Tmp); + } + } +} + +VOID +EXhalbtc8821a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + halbtc8821a2ant_InitHwConfig(pBtCoexist, TRUE); +} + +VOID +EXhalbtc8821a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8821a2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8821a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte faOfdm, faCck; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============"); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n =========================================="); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8821a2Ant, GLCoexVer8821a2Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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/ %ddBm/ %d] ", "BT [status/ rssi/ retryCnt]", \ + ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8821A_2ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle": + ( (BT_8821A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))), + 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", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8821a2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + // Sw mechanism + 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/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + 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); + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xc5b); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x880); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/0x880[29:25]/0xc58[29:25]", \ + u1Tmp[0], (u4Tmp[0]&0x3e000000) >> 25, ((u1Tmp[1]&0x3e)>>1)); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x764); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x764/ 0x765/ 0x76e", \ + (u4Tmp[0]&0xff), (u4Tmp[0]&0xff00)>>8, u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcb4); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)", \ + u4Tmp[0]&0xff, ((u4Tmp[0]&0x30000000)>>28)); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x974); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x40/ 0x4c[24:23]/ 0x974", \ + u1Tmp[0], ((u4Tmp[0]&0x01800000)>>23), u4Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x49c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(dig)/0x49c(null-drop)", \ + u4Tmp[0]&0xff, u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xda8); + u4Tmp[3] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcf0); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + + faOfdm = ((u4Tmp[0]&0xffff0000) >> 16) + ((u4Tmp[1]&0xffff0000) >> 16) + (u4Tmp[1] & 0xffff) + (u4Tmp[2] & 0xffff) + \ + ((u4Tmp[3]&0xffff0000) >> 16) + (u4Tmp[3] & 0xffff) ; + faCck = (u1Tmp[0] << 8) + u1Tmp[1]; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "OFDM-CCA/OFDM-FA/CCK-FA", \ + 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); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); +#if(BT_AUTO_REPORT_ONLY_8821A_2ANT == 1) + //halbtc8821a2ant_MonitorBtCtr(pBtCoexist); +#endif + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8821a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8821a2ant_WifiOffHwCfg(pBtCoexist); + halbtc8821a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + halbtc8821a2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + halbtc8821a2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8821a2ant_InitCoexDm(pBtCoexist); + halbtc8821a2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8821a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8821a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte u1Tmpa, u1Tmpb; + + u1Tmpa = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x765); + u1Tmpb = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x76e); + + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } + + RT_TRACE(COMP_COEX, DBG_LOUD, ("############# [BTCoex], 0x765=0x%x, 0x76e=0x%x\n", u1Tmpa, u1Tmpb)); +} + +VOID +EXhalbtc8821a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8821a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + u1Byte apNum=0; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + { + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_AP_NUM, &apNum); + if(apNum < 10) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + } + + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); +} + +VOID +EXhalbtc8821a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8821a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->btLinkInfo; + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE, bWifiUnder5G=FALSE; + static BOOLEAN bPreScoExist=FALSE; + u4Byte raMask=0x0; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8821A_2ANT_MAX) + rspSource = BT_INFO_SRC_8821A_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n")); + return; + } + + // if 0xff, it means BT is under WHCK test + if (btInfo == 0xff) + pCoexSta->bBtWhckTest = TRUE; + else + pCoexSta->bBtWhckTest = FALSE; + + if(BT_INFO_SRC_8821A_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + pCoexSta->bBtTxRxMask = (pCoexSta->btInfoC2h[rspSource][2]&0x40); + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TX_RX_MASK, &pCoexSta->bBtTxRxMask); + if(pCoexSta->bBtTxRxMask) + { + /* BT into is responded by BT FW and BT RF REG 0x3C != 0x01 => Need to switch BT TRx Mask */ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x01\n")); + pBtCoexist->fBtcSetBtReg(pBtCoexist, BTC_BT_REG_RF, 0x3c, 0x01); + } + + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n")); + if(bWifiConnected) + { + EXhalbtc8821a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8821a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + + + if(!pBtCoexist->bManualControl && !bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info = 0x%x!!\n", pCoexSta->btInfoExt)); + if( (pCoexSta->btInfoExt&BIT3) ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3=1, bWifiConnected=%d\n", bWifiConnected)); + if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8821a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3=0, bWifiConnected=%d\n", bWifiConnected)); + // BT already NOT ignore Wlan active, do nothing here. + if(!bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT to ignore Wlan active!!\n")); + halbtc8821a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + } + } + } + +#if(BT_AUTO_REPORT_ONLY_8821A_2ANT == 0) + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8821a2ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } +#endif + } + + // check BIT2 first ==> check if bt is under inquiry or page scan + if(btInfo & BT_INFO_8821A_2ANT_B_INQ_PAGE) + pCoexSta->bC2hBtInquiryPage = TRUE; + else + pCoexSta->bC2hBtInquiryPage = FALSE; + + // set link exist status + if(!(btInfo&BT_INFO_8821A_2ANT_B_CONNECTION)) + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + } + else // connection exists + { + pCoexSta->bBtLinkExist = TRUE; + if(btInfo & BT_INFO_8821A_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + if(btInfo & BT_INFO_8821A_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + if(btInfo & BT_INFO_8821A_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + if(btInfo & BT_INFO_8821A_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + + if ( (pCoexSta->bHidExist == FALSE) && (pCoexSta->bC2hBtInquiryPage == FALSE) && (pCoexSta->bScoExist == FALSE)) + { + if (pCoexSta->highPriorityTx + pCoexSta->highPriorityRx >= 160) + pCoexSta->bHidExist = TRUE; + } + } + + halbtc8821a2ant_UpdateBtLinkInfo(pBtCoexist); + + if(!(btInfo&BT_INFO_8821A_2ANT_B_CONNECTION)) + { + pCoexDm->btStatus = BT_8821A_2ANT_BT_STATUS_NON_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n")); + } + else if(btInfo == BT_INFO_8821A_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexDm->btStatus = BT_8821A_2ANT_BT_STATUS_CONNECTED_IDLE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n")); + } + else if((btInfo&BT_INFO_8821A_2ANT_B_SCO_ESCO) || + (btInfo&BT_INFO_8821A_2ANT_B_SCO_BUSY)) + { + pCoexDm->btStatus = BT_8821A_2ANT_BT_STATUS_SCO_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT SCO busy!!!\n")); + } + else if(btInfo&BT_INFO_8821A_2ANT_B_ACL_BUSY) + { + pCoexDm->btStatus = BT_8821A_2ANT_BT_STATUS_ACL_BUSY; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT ACL busy!!!\n")); + } + else + { + pCoexDm->btStatus = BT_8821A_2ANT_BT_STATUS_MAX; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n")); + } + + if( (BT_8821A_2ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) || + (BT_8821A_2ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) || + (BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) ) + { + bBtBusy = TRUE; + bLimitedDig = TRUE; + } + else + { + bBtBusy = FALSE; + bLimitedDig = FALSE; + } + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8821a2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8821a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8821a2ant_WifiOffHwCfg(pBtCoexist); + //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 + halbtc8821a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + + EXhalbtc8821a2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8821a2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + halbtc8821a2ant_InitHwConfig(pBtCoexist, FALSE); + halbtc8821a2ant_InitCoexDm(pBtCoexist); + halbtc8821a2ant_QueryBtInfo(pBtCoexist); + } +} + +VOID +EXhalbtc8821a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + //static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(pCoexSta->disVerInfoCnt <= 5) + { + pCoexSta->disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8821a2Ant, GLCoexVer8821a2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + + if (pCoexSta->disVerInfoCnt == 3) + { + //Antenna config to set 0x765 = 0x0 (GNT_BT control by PTA) after initial + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Set GNT_BT control by PTA\n")); + halbtc8821a2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, FALSE, FALSE); + } + } + +#if(BT_AUTO_REPORT_ONLY_8821A_2ANT == 0) + halbtc8821a2ant_QueryBtInfo(pBtCoexist); + halbtc8821a2ant_MonitorBtEnableDisable(pBtCoexist); +#else + halbtc8821a2ant_MonitorBtCtr(pBtCoexist); + halbtc8821a2ant_MonitorWiFiCtr(pBtCoexist); + + if( halbtc8821a2ant_IsWifiStatusChanged(pBtCoexist) || + pCoexDm->bAutoTdmaAdjust) + { + halbtc8821a2ant_RunCoexistMechanism(pBtCoexist); + } +#endif +} + + +#endif + +#else // #if (RTL8821A_SUPPORT == 1) +VOID +EXhalbtc8821a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8821a2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8821a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ){} +VOID +EXhalbtc8821a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8821a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ){} +VOID +EXhalbtc8821a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ){} +VOID +EXhalbtc8821a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8821a2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ){} +VOID +EXhalbtc8821a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ){} +VOID +EXhalbtc8821a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ){} +#endif // #if (RTL8821A_SUPPORT == 1) \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.h new file mode 100644 index 00000000..6b465e33 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821a2Ant.h @@ -0,0 +1,226 @@ +//=========================================== +// The following is for 8821A 2Ant BT Co-exist definition +//=========================================== +#define BT_AUTO_REPORT_ONLY_8821A_2ANT 1 + + +#define BT_INFO_8821A_2ANT_B_FTP BIT7 +#define BT_INFO_8821A_2ANT_B_A2DP BIT6 +#define BT_INFO_8821A_2ANT_B_HID BIT5 +#define BT_INFO_8821A_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8821A_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8821A_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8821A_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8821A_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT 2 + + +#define BT_8821A_2ANT_WIFI_RSSI_COEXSWITCH_THRES 42 //WiFi RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation +#define BT_8821A_2ANT_BT_RSSI_COEXSWITCH_THRES 46 //BT RSSI Threshold for 2-Ant TDMA/1-Ant PS-TDMA translation + +typedef enum _BT_INFO_SRC_8821A_2ANT{ + BT_INFO_SRC_8821A_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8821A_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8821A_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8821A_2ANT_MAX +}BT_INFO_SRC_8821A_2ANT,*PBT_INFO_SRC_8821A_2ANT; + +typedef enum _BT_8821A_2ANT_BT_STATUS{ + BT_8821A_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8821A_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8821A_2ANT_BT_STATUS_INQ_PAGE = 0x2, + BT_8821A_2ANT_BT_STATUS_ACL_BUSY = 0x3, + BT_8821A_2ANT_BT_STATUS_SCO_BUSY = 0x4, + BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8821A_2ANT_BT_STATUS_MAX +}BT_8821A_2ANT_BT_STATUS,*PBT_8821A_2ANT_BT_STATUS; + +typedef enum _BT_8821A_2ANT_COEX_ALGO{ + BT_8821A_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8821A_2ANT_COEX_ALGO_SCO = 0x1, + BT_8821A_2ANT_COEX_ALGO_HID = 0x2, + BT_8821A_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8821A_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8821A_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8821A_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8821A_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8821A_2ANT_COEX_ALGO_MAX = 0xb, +}BT_8821A_2ANT_COEX_ALGO,*PBT_8821A_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8821A_2ANT{ + // fw mechanism + u1Byte preBtDecPwrLvl; + u1Byte curBtDecPwrLvl; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[5]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bAutoTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; + + BOOLEAN bNeedRecover0x948; + u4Byte backup0x948; + + u1Byte preLps; + u1Byte curLps; + u1Byte preRpwm; + u1Byte curRpwm; +} COEX_DM_8821A_2ANT, *PCOEX_DM_8821A_2ANT; + +typedef struct _COEX_STA_8821A_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + BOOLEAN bBtTxRxMask; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8821A_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8821A_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_8821A_2ANT, *PCOEX_STA_8821A_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8821a2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a2ant_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8821a2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821a2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8821a2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8821a2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821a2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.c new file mode 100644 index 00000000..bd60df4e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.c @@ -0,0 +1,4343 @@ +//============================================================ +// Description: +// +// This file is for RTL8821A_CSR_CSR Co-exist mechanism +// +// History +// 2012/08/22 Cosa first check in. +// 2012/11/14 Cosa Revise for 8821A_CSR 2Ant out sourcing. +// +//============================================================ + +//============================================================ +// include files +//============================================================ +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HalBtcCsr8821a2Ant.tmh" +#endif + +#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 +//============================================================ +static COEX_DM_8821A_CSR_2ANT GLCoexDm8821aCsr2Ant; +static PCOEX_DM_8821A_CSR_2ANT pCoexDm=&GLCoexDm8821aCsr2Ant; +static COEX_STA_8821A_CSR_2ANT GLCoexSta8821aCsr2Ant; +static PCOEX_STA_8821A_CSR_2ANT pCoexSta=&GLCoexSta8821aCsr2Ant; + +const char *const GLBtInfoSrc8821aCsr2Ant[]={ + "BT Info[wifi fw]", + "BT Info[bt rsp]", + "BT Info[bt auto report]", +}; + +u4Byte GLCoexVerDate8821aCsr2Ant=20140901; +u4Byte GLCoexVer8821aCsr2Ant=0x51; + +//============================================================ +// local function proto type if needed +//============================================================ +//============================================================ +// local function start with halbtc8821aCsr2ant_ +//============================================================ +u1Byte +halbtc8821aCsr2ant_BtRssiState( + u1Byte levelNum, + u1Byte rssiThresh, + u1Byte rssiThresh1 + ) +{ + s4Byte btRssi=0; + u1Byte btRssiState=pCoexSta->preBtRssiState; + + btRssi = pCoexSta->btRssi; + + if(levelNum == 2) + { + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT Rssi thresh error!!\n")); + return pCoexSta->preBtRssiState; + } + + if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW)) + { + if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + btRssiState = BTC_RSSI_STATE_HIGH; + } + else if(btRssi < rssiThresh) + { + btRssiState = BTC_RSSI_STATE_LOW; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(btRssi < rssiThresh1) + { + btRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + btRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preBtRssiState = btRssiState; + + return btRssiState; +} + +u1Byte +halbtc8821aCsr2ant_WifiRssiState( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte index, + IN u1Byte levelNum, + IN u1Byte rssiThresh, + IN u1Byte rssiThresh1 + ) +{ + s4Byte wifiRssi=0; + u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index]; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi); + + if(levelNum == 2) + { + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else + { + if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + else if(levelNum == 3) + { + if(rssiThresh > rssiThresh1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], wifi RSSI thresh error!!\n")); + return pCoexSta->preWifiRssiState[index]; + } + + if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW)) + { + if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_LOW; + } + } + else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) || + (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM)) + { + if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT)) + { + wifiRssiState = BTC_RSSI_STATE_HIGH; + } + else if(wifiRssi < rssiThresh) + { + wifiRssiState = BTC_RSSI_STATE_LOW; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM; + } + } + else + { + if(wifiRssi < rssiThresh1) + { + wifiRssiState = BTC_RSSI_STATE_MEDIUM; + } + else + { + wifiRssiState = BTC_RSSI_STATE_STAY_HIGH; + } + } + } + + pCoexSta->preWifiRssiState[index] = wifiRssiState; + + return wifiRssiState; +} + +VOID +halbtc8821aCsr2ant_MonitorBtEnableDisable( + IN PBTC_COEXIST pBtCoexist + ) +{ + static BOOLEAN bPreBtDisabled=FALSE; + static u4Byte btDisableCnt=0; + BOOLEAN bBtActive=TRUE, bBtDisabled=FALSE; + + // This function check if bt is disabled + + if( pCoexSta->highPriorityTx == 0 && + pCoexSta->highPriorityRx == 0 && + pCoexSta->lowPriorityTx == 0 && + pCoexSta->lowPriorityRx == 0) + { + bBtActive = FALSE; + } + if( pCoexSta->highPriorityTx == 0xffff && + pCoexSta->highPriorityRx == 0xffff && + pCoexSta->lowPriorityTx == 0xffff && + pCoexSta->lowPriorityRx == 0xffff) + { + bBtActive = FALSE; + } + if(bBtActive) + { + btDisableCnt = 0; + bBtDisabled = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is enabled !!\n")); + } + else + { + btDisableCnt++; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], bt all counters=0, %d times!!\n", + btDisableCnt)); + if(btDisableCnt >= 2) + { + bBtDisabled = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is disabled !!\n")); + } + } + if(bPreBtDisabled != bBtDisabled) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is from %s to %s!!\n", + (bPreBtDisabled ? "disabled":"enabled"), + (bBtDisabled ? "disabled":"enabled"))); + bPreBtDisabled = bBtDisabled; + if(!bBtDisabled) + { + } + else + { + } + } +} + +VOID +halbtc8821aCsr2ant_MonitorBtCtr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u4Byte regHPTxRx, regLPTxRx, u4Tmp; + u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0; + u1Byte u1Tmp; + + regHPTxRx = 0x770; + regLPTxRx = 0x774; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regHPTxRx); + regHPTx = u4Tmp & bMaskLWord; + regHPRx = (u4Tmp & bMaskHWord)>>16; + + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, regLPTxRx); + regLPTx = u4Tmp & bMaskLWord; + regLPRx = (u4Tmp & bMaskHWord)>>16; + + pCoexSta->highPriorityTx = regHPTx; + pCoexSta->highPriorityRx = regHPRx; + pCoexSta->lowPriorityTx = regLPTx; + pCoexSta->lowPriorityRx = regLPRx; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n", + regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx)); + + // reset counter + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0x5d); +} + +VOID +halbtc8821aCsr2ant_UpdateRaMask( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte disRateMask + ) +{ + pCoexDm->curRaMask = disRateMask; + + if( bForceExec || (pCoexDm->preRaMask != pCoexDm->curRaMask)) + { + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_UPDATE_RAMASK, &pCoexDm->curRaMask); + } + pCoexDm->preRaMask = pCoexDm->curRaMask; +} + +VOID +halbtc8821aCsr2ant_AutoRateFallbackRetry( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + BOOLEAN bWifiUnderBMode=FALSE; + + pCoexDm->curArfrType = type; + + if( bForceExec || (pCoexDm->preArfrType != pCoexDm->curArfrType)) + { + switch(pCoexDm->curArfrType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, pCoexDm->backupArfrCnt1); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, pCoexDm->backupArfrCnt2); + break; + case 1: + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, &bWifiUnderBMode); + if(bWifiUnderBMode) + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x01010101); + } + else + { + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x430, 0x0); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x434, 0x04030201); + } + break; + default: + break; + } + } + + pCoexDm->preArfrType = pCoexDm->curArfrType; +} + +VOID +halbtc8821aCsr2ant_RetryLimit( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curRetryLimitType = type; + + if( bForceExec || (pCoexDm->preRetryLimitType != pCoexDm->curRetryLimitType)) + { + switch(pCoexDm->curRetryLimitType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, pCoexDm->backupRetryLimit); + break; + case 1: // retry limit=8 + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x42a, 0x0808); + break; + default: + break; + } + } + + pCoexDm->preRetryLimitType = pCoexDm->curRetryLimitType; +} + +VOID +halbtc8821aCsr2ant_AmpduMaxTime( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduTimeType = type; + + if( bForceExec || (pCoexDm->preAmpduTimeType != pCoexDm->curAmpduTimeType)) + { + switch(pCoexDm->curAmpduTimeType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, pCoexDm->backupAmpduMaxTime); + break; + case 1: // AMPDU timw = 0x38 * 32us + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x38); + break; + case 2: + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x456, 0x17); + break; + default: + break; + } + } + + pCoexDm->preAmpduTimeType = pCoexDm->curAmpduTimeType; +} + +VOID +halbtc8821aCsr2Ant_AmpduMaxNum( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte type + ) +{ + pCoexDm->curAmpduNumType = type; + + if( bForceExec || (pCoexDm->preAmpduNumType != pCoexDm->curAmpduNumType)) + { + switch(pCoexDm->curAmpduNumType) + { + case 0: // normal mode + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x4ca, pCoexDm->backupAmpduMaxNum); + break; + case 1: + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x4ca, 0x0808); + break; + case 2: + pBtCoexist->fBtcWrite2Byte(pBtCoexist, 0x4ca, 0x1f1f); + break; + default: + break; + } + } + + pCoexDm->preAmpduNumType = pCoexDm->curAmpduNumType; + +} + +VOID +halbtc8821aCsr2ant_LimitedTx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte raMaskType, + IN u1Byte arfrType, + IN u1Byte retryLimitType, + IN u1Byte ampduTimeType, + IN u1Byte ampduNumType + ) +{ + switch(raMaskType) + { + case 0: // normal mode + halbtc8821aCsr2ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0); + break; + case 1: // disable cck 1/2 + halbtc8821aCsr2ant_UpdateRaMask(pBtCoexist, bForceExec, 0x00000003); + break; + case 2: // disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 + halbtc8821aCsr2ant_UpdateRaMask(pBtCoexist, bForceExec, 0x0001f1f7); + break; + default: + break; + } + + halbtc8821aCsr2ant_AutoRateFallbackRetry(pBtCoexist, bForceExec, arfrType); + halbtc8821aCsr2ant_RetryLimit(pBtCoexist, bForceExec, retryLimitType); + halbtc8821aCsr2ant_AmpduMaxTime(pBtCoexist, bForceExec, ampduTimeType); + halbtc8821aCsr2Ant_AmpduMaxNum(pBtCoexist, bForceExec, ampduNumType); +} + + + +VOID +halbtc8821aCsr2ant_LimitedRx( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRejApAggPkt, + IN BOOLEAN bBtCtrlAggBufSize, + IN u1Byte aggBufSize + ) +{ + BOOLEAN bRejectRxAgg=bRejApAggPkt; + BOOLEAN bBtCtrlRxAggSize=bBtCtrlAggBufSize; + u1Byte rxAggSize=aggBufSize; + + //============================================ + // Rx Aggregation related setting + //============================================ + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejectRxAgg); + // decide BT control aggregation buf size or not + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bBtCtrlRxAggSize); + // aggregation buf size, only work when BT control Rx aggregation size. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxAggSize); + // real update aggregation setting + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); +} + +VOID +halbtc8821aCsr2ant_QueryBtInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + pCoexSta->bC2hBtInfoReqSent = TRUE; + + H2C_Parameter[0] |= BIT0; // trigger + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n", + H2C_Parameter[0])); + + rtw_warn_on(_BTCOEX_CSR); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x61, 1, H2C_Parameter); +} + +u1Byte +halbtc8821aCsr2ant_ActionAlgorithm( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bBtHsOn=FALSE; + u1Byte algorithm=BT_8821A_CSR_2ANT_COEX_ALGO_UNDEFINED; + u1Byte numOfDiffProfile=0; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + //sync StackInfo with BT firmware and stack + pStackInfo->bHidExist = pCoexSta->bHidExist; + pStackInfo->bBtLinkExist = pCoexSta->bBtLinkExist; + pStackInfo->bScoExist = pCoexSta->bScoExist; + pStackInfo->bPanExist = pCoexSta->bPanExist; + pStackInfo->bA2dpExist = pCoexSta->bA2dpExist; + + if(!pStackInfo->bBtLinkExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], No profile exists!!!\n")); + return algorithm; + } + + if(pStackInfo->bScoExist) + numOfDiffProfile++; + if(pStackInfo->bHidExist) + numOfDiffProfile++; + if(pStackInfo->bPanExist) + numOfDiffProfile++; + if(pStackInfo->bA2dpExist) + numOfDiffProfile++; + + if(numOfDiffProfile == 1) + { + if(pStackInfo->bScoExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO only\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_SCO; + } + else + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID only\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP only\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_A2DP; + } + else if(pStackInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(HS) only\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PAN(EDR) only\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR; + } + } + } + } + else if(numOfDiffProfile == 2) + { + if(pStackInfo->bScoExist) + { + if(pStackInfo->bHidExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pStackInfo->bA2dpExist) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP ==> SCO\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + else if(pStackInfo->bPanExist) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_SCO; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + PAN(EDR)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + if(pStackInfo->numOfHid >= 2) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID*2 + A2DP\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP; + } + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + PAN(EDR)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_A2DP_PANHS; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_A2DP; + } + } + } + } + else if(numOfDiffProfile == 3) + { + if(pStackInfo->bScoExist) + { + if( pStackInfo->bHidExist && + pStackInfo->bA2dpExist ) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP ==> HID\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + else if( pStackInfo->bHidExist && + pStackInfo->bPanExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + PAN(EDR)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + } + else if( pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + else + { + if( pStackInfo->bHidExist && + pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(HS)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP_PANEDR; + } + } + } + } + else if(numOfDiffProfile >= 3) + { + if(pStackInfo->bScoExist) + { + if( pStackInfo->bHidExist && + pStackInfo->bPanExist && + pStackInfo->bA2dpExist ) + { + if(bBtHsOn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); + + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n")); + algorithm = BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID; + } + } + } + } + + return algorithm; +} + +BOOLEAN +halbtc8821aCsr2ant_NeedToDecBtPwr( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bRet=FALSE; + BOOLEAN bBtHsOn=FALSE, bWifiConnected=FALSE; + s4Byte btHsRssi=0; + u1Byte btRssiState; + + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn)) + return FALSE; + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected)) + return FALSE; + if(!pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi)) + return FALSE; + + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + if(bWifiConnected) + { + if(bBtHsOn) + { + if(btHsRssi > 37) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Need to decrease bt power for HS mode!!\n")); + bRet = TRUE; + } + } + else + { + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Need to decrease bt power for Wifi is connected!!\n")); + bRet = TRUE; + } + } + } + + return bRet; +} + +VOID +halbtc8821aCsr2ant_SetFwDacSwingLevel( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte dacSwingLvl + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + // There are several type of dacswing + // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 + H2C_Parameter[0] = dacSwingLvl; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x64, 1, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_SetFwDecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bDecBtPwr + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bDecBtPwr) + { + H2C_Parameter[0] |= BIT1; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n", + (bDecBtPwr? "Yes!!":"No!!"), H2C_Parameter[0])); + + rtw_warn_on(_BTCOEX_CSR); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x62, 1, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_DecBtPwr( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDecBtPwr + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s Dec BT power = %s\n", + (bForceExec? "force to":""), ((bDecBtPwr)? "ON":"OFF"))); + pCoexDm->bCurDecBtPwr = bDecBtPwr; + + if(!bForceExec) + { + if(pCoexDm->bPreDecBtPwr == pCoexDm->bCurDecBtPwr) + return; + } + + /* TODO: may CSR consider to decrease BT power? */ + //halbtc8821aCsr2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->bCurDecBtPwr); + + pCoexDm->bPreDecBtPwr = pCoexDm->bCurDecBtPwr; +} + +VOID +halbtc8821aCsr2ant_SetBtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnableAutoReport + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + H2C_Parameter[0] = 0; + + if(bEnableAutoReport) + { + H2C_Parameter[0] |= BIT0; + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n", + (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0])); + + rtw_warn_on(_BTCOEX_CSR); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x68, 1, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_BtAutoReport( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnableAutoReport + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s BT Auto report = %s\n", + (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled"))); + pCoexDm->bCurBtAutoReport = bEnableAutoReport; + + if(!bForceExec) + { + if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport) + return; + } + //halbtc8821aCsr2ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport); + + pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport; +} + +VOID +halbtc8821aCsr2ant_FwDacSwingLvl( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u1Byte fwDacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s set FW Dac Swing level = %d\n", + (bForceExec? "force to":""), fwDacSwingLvl)); + pCoexDm->curFwDacSwingLvl = fwDacSwingLvl; + + if(!bForceExec) + { + if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl) + return; + } + + halbtc8821aCsr2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl); + + pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl; +} + +VOID +halbtc8821aCsr2ant_SetSwRfRxLpfCorner( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bRxRfShrinkOn + ) +{ + if(bRxRfShrinkOn) + { + //Shrink RF Rx LPF corner + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Shrink RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xffffc); + } + else + { + //Resume RF Rx LPF corner + // After initialized, we can use pCoexDm->btRf0x1eBackup + if(pBtCoexist->bInitilized) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Resume RF Rx LPF corner!!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup); + } + } +} + +VOID +halbtc8821aCsr2ant_RfShrink( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bRxRfShrinkOn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Rx RF Shrink = %s\n", + (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF"))); + pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn; + + if(!bForceExec) + { + if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink) + return; + } + halbtc8821aCsr2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink); + + pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink; +} + +VOID +halbtc8821aCsr2ant_SetSwPenaltyTxRateAdaptive( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bLowPenaltyRa + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = 0x6; // opCode, 0x6= Retry_Penalty + + if(bLowPenaltyRa) + { + H2C_Parameter[1] |= BIT0; + H2C_Parameter[2] = 0x00; //normal rate except MCS7/6/5, OFDM54/48/36 + H2C_Parameter[3] = 0xf7; //MCS7 or OFDM54 + H2C_Parameter[4] = 0xf8; //MCS6 or OFDM48 + H2C_Parameter[5] = 0xf9; //MCS5 or OFDM36 + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set WiFi Low-Penalty Retry: %s", + (bLowPenaltyRa? "ON!!":"OFF!!") )); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x69, 6, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_LowPenaltyRa( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bLowPenaltyRa + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn LowPenaltyRA = %s\n", + (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF"))); + pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa; + + if(!bForceExec) + { + if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa) + return; + } + halbtc8821aCsr2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa); + + pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa; +} + +VOID +halbtc8821aCsr2ant_SetDacSwingReg( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte level + ) +{ + u1Byte val=(u1Byte)level; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Write SwDacSwing = 0x%x\n", level)); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xc5b, 0x3e, val); +} + +VOID +halbtc8821aCsr2ant_SetSwFullTimeDacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bSwDacSwingOn, + IN u4Byte swDacSwingLvl + ) +{ + if(bSwDacSwingOn) + { + halbtc8821aCsr2ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl); + } + else + { + halbtc8821aCsr2ant_SetDacSwingReg(pBtCoexist, 0x18); + } +} + + +VOID +halbtc8821aCsr2ant_DacSwing( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bDacSwingOn, + IN u4Byte dacSwingLvl + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n", + (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl)); + pCoexDm->bCurDacSwingOn = bDacSwingOn; + pCoexDm->curDacSwingLvl = dacSwingLvl; + + if(!bForceExec) + { + if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) && + (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) ) + return; + } + delay_ms(30); + halbtc8821aCsr2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl); + + pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn; + pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl; +} + +VOID +halbtc8821aCsr2ant_SetAdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAdcBackOff + ) +{ + if(bAdcBackOff) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level On!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x3); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BB BackOff Level Off!\n")); + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x8db, 0x60, 0x1); + } +} + +VOID +halbtc8821aCsr2ant_AdcBackOff( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAdcBackOff + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn AdcBackOff = %s\n", + (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF"))); + pCoexDm->bCurAdcBackOff = bAdcBackOff; + + if(!bForceExec) + { + if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff) + return; + } + halbtc8821aCsr2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff); + + pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff; +} + +VOID +halbtc8821aCsr2ant_SetAgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAgcTableEn + ) +{ + u1Byte rssiAdjustVal=0; + + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); + if(bAgcTableEn) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table On!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x28F4B); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x10AB2); + rssiAdjustVal = 8; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Agc Table Off!\n")); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x2884B); + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x104B2); + } + pBtCoexist->fBtcSetRfReg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + + // set rssiAdjustVal for wifi module. + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal); +} + +VOID +halbtc8821aCsr2ant_AgcTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bAgcTableEn + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s %s Agc Table\n", + (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable"))); + pCoexDm->bCurAgcTableEn = bAgcTableEn; + + if(!bForceExec) + { + if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn) + return; + } + halbtc8821aCsr2ant_SetAgcTable(pBtCoexist, bAgcTableEn); + + pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn; +} + +VOID +halbtc8821aCsr2ant_SetCoexTable( + IN PBTC_COEXIST pBtCoexist, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, val0x6c0); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, val0x6c4); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8)); + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, val0x6c8); + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc)); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, val0x6cc); +} + +VOID +halbtc8821aCsr2ant_CoexTable( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN u4Byte val0x6c0, + IN u4Byte val0x6c4, + IN u4Byte val0x6c8, + IN u1Byte val0x6cc + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", + (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc)); + pCoexDm->curVal0x6c0 = val0x6c0; + pCoexDm->curVal0x6c4 = val0x6c4; + pCoexDm->curVal0x6c8 = val0x6c8; + pCoexDm->curVal0x6cc = val0x6cc; + + if(!bForceExec) + { + if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) && + (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) && + (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) && + (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) ) + return; + } + halbtc8821aCsr2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc); + + pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0; + pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4; + pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8; + pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc; +} + +VOID +halbtc8821aCsr2ant_SetFwIgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bEnable + ) +{ + u1Byte H2C_Parameter[1] ={0}; + + if(bEnable) + { + H2C_Parameter[0] |= BIT0; // function enable + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n", + H2C_Parameter[0])); + + rtw_warn_on(_BTCOEX_CSR); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x63, 1, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_IgnoreWlanAct( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bEnable + ) +{ + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn Ignore WlanAct %s\n", + (bForceExec? "force to":""), (bEnable? "ON":"OFF"))); + pCoexDm->bCurIgnoreWlanAct = bEnable; + + if(!bForceExec) + { + if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct) + return; + } + //halbtc8821aCsr2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable); + + pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct; +} + +VOID +halbtc8821aCsr2ant_SetFwPstdma( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3, + IN u1Byte byte4, + IN u1Byte byte5 + ) +{ + u1Byte H2C_Parameter[6] ={0}; + + H2C_Parameter[0] = byte1; + H2C_Parameter[1] = byte2; + H2C_Parameter[2] = byte3; + H2C_Parameter[3] = byte4; + H2C_Parameter[4] = byte5; + 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] = 0x01; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x60(6bytes)=0x%x%08x%02x\n", + H2C_Parameter[0], + H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4], H2C_Parameter[5])); + + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x60, 6, H2C_Parameter); +} + +VOID +halbtc8821aCsr2ant_SwMechanism1( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bShrinkRxLPF, + IN BOOLEAN bLowPenaltyRA, + IN BOOLEAN bLimitedDIG, + IN BOOLEAN bBTLNAConstrain + ) +{ + u4Byte wifiBw; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 != wifiBw) //only shrink RF Rx LPF for HT40 + { + if (bShrinkRxLPF) + bShrinkRxLPF = FALSE; + } + + halbtc8821aCsr2ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF); + halbtc8821aCsr2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA); + + //no limited DIG + //halbtc8821aCsr2ant_SetBtLnaConstrain(pBtCoexist, NORMAL_EXEC, bBTLNAConstrain); +} + +VOID +halbtc8821aCsr2ant_SwMechanism2( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bAGCTableShift, + IN BOOLEAN bADCBackOff, + IN BOOLEAN bSWDACSwing, + IN u4Byte dacSwingLvl + ) +{ + //halbtc8821aCsr2ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift); + halbtc8821aCsr2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff); + halbtc8821aCsr2ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl); +} + +VOID +halbtc8821aCsr2ant_SetAntPath( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte antPosType, + IN BOOLEAN bInitHwCfg, + IN BOOLEAN bWifiOff + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + if(bInitHwCfg) + { + // 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT + u4Tmp = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp &=~BIT23; + u4Tmp |= BIT24; + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x4c, u4Tmp); + + pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x974, 0x3ff); + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0xcb4, 0x77); + + if(pBoardInfo->btdmAntPos == BTC_ANTENNA_AT_MAIN_PORT) + { + //tell firmware "antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 1; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + else + { + //tell firmware "no antenna inverse" ==> WRONG firmware antenna control code.==>need fw to fix + H2C_Parameter[0] = 0; + H2C_Parameter[1] = 1; + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x65, 2, H2C_Parameter); + } + } + + // ext switch setting + switch(antPosType) + { + case BTC_ANT_WIFI_AT_MAIN: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x1); + break; + case BTC_ANT_WIFI_AT_AUX: + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0xcb7, 0x30, 0x2); + break; + } +} + +VOID +halbtc8821aCsr2ant_PsTdma( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bForceExec, + IN BOOLEAN bTurnOn, + IN u1Byte type + ) +{ + BOOLEAN bTurnOnByCnt=FALSE; + u1Byte psTdmaTypeByCnt=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], %s turn %s PS TDMA, type=%d\n", + (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type)); + pCoexDm->bCurPsTdmaOn = bTurnOn; + pCoexDm->curPsTdma = type; + + if(!bForceExec) + { + if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) && + (pCoexDm->prePsTdma == pCoexDm->curPsTdma) ) + return; + } + if(bTurnOn) + { + switch(type) + { + case 1: + default: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + break; + case 2: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + break; + case 3: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0xf1, 0x90); + break; + case 4: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x10, 0x03, 0xf1, 0x90); + break; + case 5: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + break; + case 6: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + break; + case 7: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1c, 0x3, 0x70, 0x90); + break; + case 8: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x10, 0x3, 0x70, 0x90); + break; + case 9: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + break; + case 10: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90); + break; + case 11: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x90); + break; + case 12: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 13: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x90); + break; + case 14: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x90); + break; + case 15: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x90); + break; + case 16: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x90); + break; + case 17: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x90); + break; + case 18: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x90); + break; + case 19: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x90); + break; + case 20: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x90); + break; + case 21: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x03, 0x70, 0x90); + break; + case 22: //ad2dp master + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xeb, 0x11, 0x11, 0x21, 0x10); + break; + case 23: //a2dp slave + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xeb, 0x12, 0x12, 0x20, 0x10); + break; + case 71: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x90); + break; + } + } + else + { + // disable PS tdma + switch(type) + { + case 0: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + case 1: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x48, 0x0); + break; + default: + halbtc8821aCsr2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x40, 0x0); + break; + } + } + + // update pre state + pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn; + pCoexDm->prePsTdma = pCoexDm->curPsTdma; +} + +VOID +halbtc8821aCsr2ant_CoexAllOff( + IN PBTC_COEXIST pBtCoexist + ) +{ + // fw all off + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + // sw all off + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + + // hw all off + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3); +} + +VOID +halbtc8821aCsr2ant_CoexUnder5G( + IN PBTC_COEXIST pBtCoexist + ) +{ + halbtc8821aCsr2ant_CoexAllOff(pBtCoexist); + + halbtc8821aCsr2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, TRUE); +} + +VOID +halbtc8821aCsr2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + // force to reset coex mechanism + halbtc8821aCsr2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3); + + halbtc8821aCsr2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 1); + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); +} + +VOID +halbtc8821aCsr2ant_BtInquiryPage( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bLowPwrDisable=TRUE; + + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5afa5afa, 0xffff, 0x3); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); +} +BOOLEAN +halbtc8821aCsr2ant_IsCommonAction( + IN PBTC_COEXIST pBtCoexist + ) +{ + BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE; + BOOLEAN bLowPwrDisable=FALSE; + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy); + + if(!bWifiConnected && + BT_8821A_CSR_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi IPS + BT IPS!!\n")); + + + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 0); + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, 0, 0, 0); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8821A_CSR_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus) ) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Busy + BT IPS!!\n")); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi LPS + BT IPS!!\n")); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 0); + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, 0, 0, 0); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8821A_CSR_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi IPS + BT LPS!!\n")); + + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 0); + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, 0, 0, 0); + + bCommon = TRUE; + } + else if(bWifiConnected && + (BT_8821A_CSR_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) ) + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Busy + BT LPS!!\n")); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi LPS + BT LPS!!\n")); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,TRUE,TRUE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 0); + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, 0, 0, 0); + + bCommon = TRUE; + } + else if(!bWifiConnected && + (BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE == pCoexDm->btStatus) ) + { + bLowPwrDisable = FALSE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi IPS + BT Busy!!\n")); + + //halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 0); + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, 0, 0, 0); + + bCommon = TRUE; + } + else + { + bLowPwrDisable = TRUE; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable); + + if(bWifiBusy) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi Busy + BT Busy!!\n")); + bCommon = FALSE; + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Wifi LPS + BT Busy!!\n")); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 21); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + bCommon = TRUE; + } + + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,TRUE,TRUE); + } + + if (bCommon == TRUE) + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5afa5afa, 0xffff, 0x3); + + return bCommon; +} +VOID +halbtc8821aCsr2ant_TdmaDurationAdjust( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bScoHid, + IN BOOLEAN bTxPause, + IN u1Byte maxInterval + ) +{ + static s4Byte up,dn,m,n,WaitCount; + s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration + u1Byte retryCount=0; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); + + if(pCoexDm->bResetTdmaAdjust) + { + pCoexDm->bResetTdmaAdjust = FALSE; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); + { + if(bScoHid) + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(maxInterval == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(maxInterval == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + else + { + if(maxInterval == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(maxInterval == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(maxInterval == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + else + { + if(bTxPause) + { + if(maxInterval == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(maxInterval == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(maxInterval == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + } + else + { + if(maxInterval == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(maxInterval == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(maxInterval == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + } + } + } + //============ + up = 0; + dn = 0; + m = 1; + n= 3; + result = 0; + WaitCount = 0; + } + else + { + //accquire the BT TRx retry count from BT_Info byte2 + retryCount = pCoexSta->btRetryCnt; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n", + up, dn, m, n, WaitCount)); + result = 0; + WaitCount++; + + if(retryCount == 0) // no retry in the last 2-second duration + { + up++; + dn--; + + if (dn <= 0) + dn = 0; + + if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration + { + WaitCount = 0; + n = 3; + up = 0; + dn = 0; + result = 1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Increase wifi duration!!\n")); + } + } + else if (retryCount <= 3) // <=3 retry in the last 2-second duration + { + up--; + dn++; + + if (up <= 0) + up = 0; + + if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration + { + if (WaitCount <= 2) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); + } + } + else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration + { + if (WaitCount == 1) + m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ + else + m = 1; + + if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. + m = 20; + + n = 3*m; + up = 0; + dn = 0; + WaitCount = 0; + result = -1; + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); + } + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); + if(maxInterval == 1) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + + if(pCoexDm->curPsTdma == 71) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + pCoexDm->psTdmaDuAdjType = 5; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + pCoexDm->psTdmaDuAdjType = 13; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + + if(result == -1) + { + if(pCoexDm->curPsTdma == 71) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + pCoexDm->psTdmaDuAdjType = 1; + } + else if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 71); + pCoexDm->psTdmaDuAdjType = 71; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + pCoexDm->psTdmaDuAdjType = 9; + } + } + } + } + else if(maxInterval == 2) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 6); + pCoexDm->psTdmaDuAdjType = 6; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + pCoexDm->psTdmaDuAdjType = 14; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 2); + pCoexDm->psTdmaDuAdjType = 2; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + pCoexDm->psTdmaDuAdjType = 10; + } + } + } + } + else if(maxInterval == 3) + { + if(bTxPause) + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 1\n")); + if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 8); + pCoexDm->psTdmaDuAdjType = 8; + } + else if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 16); + pCoexDm->psTdmaDuAdjType = 16; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 7); + pCoexDm->psTdmaDuAdjType = 7; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 15); + pCoexDm->psTdmaDuAdjType = 15; + } + } + } + else + { + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], TxPause = 0\n")); + if(pCoexDm->curPsTdma == 5) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 6) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 7) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 8) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + if(pCoexDm->curPsTdma == 13) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 14) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 15) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 16) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + if(result == -1) + { + if(pCoexDm->curPsTdma == 1) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 4); + pCoexDm->psTdmaDuAdjType = 4; + } + else if(pCoexDm->curPsTdma == 9) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 12); + pCoexDm->psTdmaDuAdjType = 12; + } + } + else if (result == 1) + { + if(pCoexDm->curPsTdma == 4) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 3) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 2) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 3); + pCoexDm->psTdmaDuAdjType = 3; + } + else if(pCoexDm->curPsTdma == 12) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 11) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + else if(pCoexDm->curPsTdma == 10) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 11); + pCoexDm->psTdmaDuAdjType = 11; + } + } + } + } + } + + // if current PsTdma not match with the recorded one (when scan, dhcp...), + // then we have to adjust it back to the previous record one. + if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType) + { + BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n", + pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType)); + + 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) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, pCoexDm->psTdmaDuAdjType); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); + } + } + + // when halbtc8821aCsr2ant_TdmaDurationAdjust() is called, fw dac swing is included in the function. + //if(pCoexDm->psTdmaDuAdjType == 71) + // halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0xc); //Skip because A2DP get worse at HT40 + //else + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x6); +} + +// SCO only or SCO+PAN(HS) +VOID +halbtc8821aCsr2ant_ActionSco( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState,btRssiState; + u4Byte wifiBw; + + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffffff, 0x3); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); + + halbtc8821aCsr2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, TRUE); + + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 1, 0, 2, 0); + + if(pCoexSta->bSlave == FALSE) + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x4); + else + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x2); + +/* + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 4); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for SCO quality at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3); + } + else //for SCO quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + + // fw mechanism + //halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + //halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0); //for voice quality + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +*/ +} + + +VOID +halbtc8821aCsr2ant_ActionHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5aea5aea, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 9); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 13); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//A2DP only / PAN(EDR) only/ A2DP+PAN(HS) +VOID +halbtc8821aCsr2ant_ActionA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + halbtc8821aCsr2ant_LimitedRx(pBtCoexist, NORMAL_EXEC, FALSE, TRUE, 0x8); + + if(pCoexSta->bSlave == FALSE) + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0xfdfdfdfd, 0xdfdadfda, 0xffffff, 0x3); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 22); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 1); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x0c); + } + else + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0xfdfdfdfd, 0xdfdadfda, 0xffffff, 0x3); + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 23); + halbtc8821aCsr2ant_LimitedTx(pBtCoexist, NORMAL_EXEC, 0, 0, 0, 0, 2); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,TRUE,0x18); + } + +/* + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + //fw dac swing is called in halbtc8821aCsr2ant_TdmaDurationAdjust() + //halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + else + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 1); + } + else + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +*/ +} + +VOID +halbtc8821aCsr2ant_ActionA2dpPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2,35, 0); + + //fw dac swing is called in halbtc8821aCsr2ant_TdmaDurationAdjust() + //halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 2); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 1); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821aCsr2ant_ActionPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5aff5aff, 0xffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5aff5aff, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 1); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 5); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + + +//PAN(HS) only +VOID +halbtc8821aCsr2ant_ActionPanHs( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + } + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + } + else + { + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + } + + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 1); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +//PAN(EDR)+A2DP +VOID +halbtc8821aCsr2ant_ActionPanEdrA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5afa5afa, 0xffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5afa5afa, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + }; + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, FALSE, 3); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, FALSE, TRUE, 3); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821aCsr2ant_ActionPanEdrHid( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState; + u4Byte wifiBw; + + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5f5a5f, 0xffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5f5a5f, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 3); + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 10); + } + else + { + halbtc8821aCsr2ant_PsTdma(pBtCoexist, NORMAL_EXEC, TRUE, 14); + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +// HID+A2DP+PAN(EDR) +VOID +halbtc8821aCsr2ant_ActionHidA2dpPanEdr( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + halbtc8821aCsr2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 6); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 3); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 3); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821aCsr2ant_ActionHidA2dp( + IN PBTC_COEXIST pBtCoexist + ) +{ + u1Byte wifiRssiState, btRssiState, btInfoExt; + u4Byte wifiBw; + + btInfoExt = pCoexSta->btInfoExt; + wifiRssiState = halbtc8821aCsr2ant_WifiRssiState(pBtCoexist, 0, 2, 15, 0); + btRssiState = halbtc8821aCsr2ant_BtRssiState(2, 35, 0); + + if(halbtc8821aCsr2ant_NeedToDecBtPwr(pBtCoexist)) + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, TRUE); + else + halbtc8821aCsr2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + + if (BTC_WIFI_BW_LEGACY == wifiBw) //for HID at 11b/g mode + { +//Allen halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5f5b5f5b, 0xffffff, 0x3); + } + else //for HID quality & wifi performance balance at 11n mode + { +//Allen halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5a5a5a5a, 0xffff, 0x3); + halbtc8821aCsr2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55ff55ff, 0x5f5b5f5b, 0xffffff, 0x3); + + } + + if(BTC_WIFI_BW_HT40 == wifiBw) + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,TRUE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } + else + { + // fw mechanism + if( (btRssiState == BTC_RSSI_STATE_HIGH) || + (btRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + if(btInfoExt&BIT0) //a2dp basic rate + { +// halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + + } + else //a2dp edr rate + { +//Allen halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, FALSE, 2); + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + } + else + { + if(btInfoExt&BIT0) //a2dp basic rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + else //a2dp edr rate + { + halbtc8821aCsr2ant_TdmaDurationAdjust(pBtCoexist, TRUE, TRUE, 2); + } + } + + // sw mechanism + if( (wifiRssiState == BTC_RSSI_STATE_HIGH) || + (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) ) + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,TRUE,FALSE,FALSE,0x18); + } + else + { + halbtc8821aCsr2ant_SwMechanism1(pBtCoexist,FALSE,TRUE,FALSE,FALSE); + halbtc8821aCsr2ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18); + } + } +} + +VOID +halbtc8821aCsr2ant_RunCoexistMechanism( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + BOOLEAN bWifiUnder5G=FALSE; + u1Byte btInfoOriginal=0, btRetryCnt=0; + u1Byte algorithm=0; + + if(pBtCoexist->bManualControl) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Manual control!!!\n")); + return; + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + if(bWifiUnder5G) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n")); + halbtc8821aCsr2ant_CoexUnder5G(pBtCoexist); + return; + } + + //if(pStackInfo->bProfileNotified) + { + algorithm = halbtc8821aCsr2ant_ActionAlgorithm(pBtCoexist); + if(pCoexSta->bC2hBtInquiryPage && (BT_8821A_CSR_2ANT_COEX_ALGO_PANHS!=algorithm)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT is under inquiry/page scan !!\n")); + halbtc8821aCsr2ant_BtInquiryPage(pBtCoexist); + return; + } + + pCoexDm->curAlgorithm = algorithm; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Algorithm = %d \n", pCoexDm->curAlgorithm)); + + if(halbtc8821aCsr2ant_IsCommonAction(pBtCoexist)) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant common.\n")); + pCoexDm->bResetTdmaAdjust = TRUE; + } + else + { + if(pCoexDm->curAlgorithm != pCoexDm->preAlgorithm) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], preAlgorithm=%d, curAlgorithm=%d\n", + pCoexDm->preAlgorithm, pCoexDm->curAlgorithm)); + pCoexDm->bResetTdmaAdjust = TRUE; + } + switch(pCoexDm->curAlgorithm) + { + case BT_8821A_CSR_2ANT_COEX_ALGO_SCO: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = SCO.\n")); + halbtc8821aCsr2ant_ActionSco(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID.\n")); + halbtc8821aCsr2ant_ActionHid(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP.\n")); + halbtc8821aCsr2ant_ActionA2dp(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_A2DP_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n")); + halbtc8821aCsr2ant_ActionA2dpPanHs(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n")); + halbtc8821aCsr2ant_ActionPanEdr(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_PANHS: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HS mode.\n")); + halbtc8821aCsr2ant_ActionPanHs(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n")); + halbtc8821aCsr2ant_ActionPanEdrA2dp(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); + halbtc8821aCsr2ant_ActionPanEdrHid(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP_PANEDR: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); + halbtc8821aCsr2ant_ActionHidA2dpPanEdr(pBtCoexist); + break; + case BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n")); + halbtc8821aCsr2ant_ActionHidA2dp(pBtCoexist); + break; + default: + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n")); + halbtc8821aCsr2ant_CoexAllOff(pBtCoexist); + break; + } + pCoexDm->preAlgorithm = pCoexDm->curAlgorithm; + } + } +} + + + +//============================================================ +// work around function start with wa_halbtc8821aCsr2ant_ +//============================================================ +//============================================================ +// extern function start with EXhalbtc8821aCsr2ant_ +//============================================================ +VOID +EXhalbtc8821aCsr2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ) +{ +} + +VOID +EXhalbtc8821aCsr2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + u4Byte u4Tmp=0; + u2Byte u2Tmp=0; + u1Byte u1Tmp=0; + u1Byte H2C_Parameter[2] ={0}; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], 2Ant Init HW Config!!\n")); + + if(bWifiOnly) + return; + + //if(bBackUp) + { + // backup rf 0x1e value + pCoexDm->btRf0x1eBackup = pBtCoexist->fBtcGetRfReg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff); + pCoexDm->backupArfrCnt1 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x430); + pCoexDm->backupArfrCnt2 = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x434); + pCoexDm->backupRetryLimit = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x42a); + pCoexDm->backupAmpduMaxTime = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x456); + pCoexDm->backupAmpduMaxNum = pBtCoexist->fBtcRead2Byte(pBtCoexist, 0x4ca); + } + + #if 0 /* REMOVE */ + // 0x790[5:0]=0x5 + u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x790); + u1Tmp &= 0xc0; + u1Tmp |= 0x5; + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x790, u1Tmp); + #endif + + //Antenna config + halbtc8821aCsr2ant_SetAntPath(pBtCoexist, BTC_ANT_WIFI_AT_MAIN, TRUE, FALSE); + + // PTA parameter + halbtc8821aCsr2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3); + + // Enable counter statistics + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); //0x76e[3] =1, WLAN_Act control by PTA + pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); + + #if 0 /* REMOVE */ + pBtCoexist->fBtcWrite1ByteBitMask(pBtCoexist, 0x40, 0x20, 0x1); + #endif +} + +VOID +EXhalbtc8821aCsr2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Coex Mechanism Init!!\n")); + + halbtc8821aCsr2ant_InitCoexDm(pBtCoexist); +} + +VOID +EXhalbtc8821aCsr2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ) +{ + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + pu1Byte cliBuf=pBtCoexist->cliBuf; + u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0; + u4Byte u4Tmp[4]; + u4Byte fwVer=0, btPatchVer=0; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \ + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum); + CL_PRINTF(cliBuf); + + if(pBtCoexist->bManualControl) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); + CL_PRINTF(cliBuf); + } + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \ + GLCoexVerDate8821aCsr2Ant, GLCoexVer8821aCsr2Ant, fwVer, btPatchVer, btPatchVer); + CL_PRINTF(cliBuf); + + 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); + + // 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); + + 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]", \ + ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8821A_CSR_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus)? "idle":( (BT_8821A_CSR_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy"))), + pCoexSta->btRssi, pCoexSta->btRetryCnt); + CL_PRINTF(cliBuf); + + if(pStackInfo->bProfileNotified) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \ + pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO); + } + + btInfoExt = pCoexSta->btInfoExt; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \ + (btInfoExt&BIT0)? "Basic rate":"EDR rate"); + CL_PRINTF(cliBuf); + + for(i=0; ibtInfoC2hCnt[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8821aCsr2Ant[i], \ + pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1], + pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3], + pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5], + pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]); + CL_PRINTF(cliBuf); + } + } + + // Sw mechanism + 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/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig]", \ + pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->bLimitedDig); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \ + pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl); + CL_PRINTF(cliBuf); + + // Fw mechanism + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============"); + CL_PRINTF(cliBuf); + + if(!pBtCoexist->bManualControl) + { + psTdmaCase = pCoexDm->curPsTdma; + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \ + pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1], + pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3], + pCoexDm->psTdmaPara[4], psTdmaCase); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \ + pCoexDm->bCurDecBtPwr, pCoexDm->bCurIgnoreWlanAct); + CL_PRINTF(cliBuf); + } + + // Hw setting + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============"); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \ + pCoexDm->btRf0x1eBackup); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x778); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x6cc); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x ", "0x778 (W_Act)/ 0x6cc (CoTab Sel)", \ + u1Tmp[0], u1Tmp[1]); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x8db); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xc5b); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x8db(ADC)/0xc5b[29:25](DAC)", \ + ((u1Tmp[0]&0x60)>>5), ((u1Tmp[1]&0x3e)>>1)); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xcb4); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)", \ + u4Tmp[0]&0xff, ((u4Tmp[0]&0x30000000)>>28)); + CL_PRINTF(cliBuf); + + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x40); + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x4c); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x974); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x40/ 0x4c[24:23]/ 0x974", \ + u1Tmp[0], ((u4Tmp[0]&0x01800000)>>23), u4Tmp[1]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x550); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x522); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xc50); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa0a); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xc50(DIG)/0xa0a(CCK-TH)", \ + u4Tmp[0], u1Tmp[0]); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0xf48); + u1Tmp[0] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5b); + u1Tmp[1] = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0xa5c); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA", \ + u4Tmp[0], (u1Tmp[0]<<8) + u1Tmp[1] ); + CL_PRINTF(cliBuf); + + u4Tmp[0] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c0); + u4Tmp[1] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c4); + u4Tmp[2] = pBtCoexist->fBtcRead4Byte(pBtCoexist, 0x6c8); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8", \ + u4Tmp[0], u4Tmp[1], u4Tmp[2]); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770 (hi-pri Rx/Tx)", \ + pCoexSta->highPriorityRx, pCoexSta->highPriorityTx); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(low-pri Rx/Tx)", \ + pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx); + CL_PRINTF(cliBuf); + + pBtCoexist->fBtcDispDbgMsg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS); +} + + +VOID +EXhalbtc8821aCsr2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_IPS_ENTER == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS ENTER notify\n")); + pCoexSta->bUnderIps = TRUE; + halbtc8821aCsr2ant_CoexAllOff(pBtCoexist); + } + else if(BTC_IPS_LEAVE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], IPS LEAVE notify\n")); + pCoexSta->bUnderIps = FALSE; + //halbtc8821aCsr2ant_InitCoexDm(pBtCoexist); + } +} + +VOID +EXhalbtc8821aCsr2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_LPS_ENABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS ENABLE notify\n")); + pCoexSta->bUnderLps = TRUE; + } + else if(BTC_LPS_DISABLE == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], LPS DISABLE notify\n")); + pCoexSta->bUnderLps = FALSE; + } +} + +VOID +EXhalbtc8821aCsr2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_SCAN_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN START notify\n")); + } + else if(BTC_SCAN_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], SCAN FINISH notify\n")); + } +} + +VOID +EXhalbtc8821aCsr2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(BTC_ASSOCIATE_START == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT START notify\n")); + } + else if(BTC_ASSOCIATE_FINISH == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CONNECT FINISH notify\n")); + } +} + +VOID +EXhalbtc8821aCsr2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + u1Byte H2C_Parameter[3] ={0}; + u4Byte wifiBw; + u1Byte wifiCentralChnl; + + if(BTC_MEDIA_CONNECT == type) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA connect notify\n")); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], MEDIA disconnect notify\n")); + } + + // only 2.4G we need to inform bt the chnl mask + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl); + if( (BTC_MEDIA_CONNECT == type) && + (wifiCentralChnl <= 14) ) + { + H2C_Parameter[0] = 0x1; + H2C_Parameter[1] = wifiCentralChnl; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw); + if(BTC_WIFI_BW_HT40 == wifiBw) + H2C_Parameter[2] = 0x30; + else + H2C_Parameter[2] = 0x20; + } + + #if 0 /* REMOVE */ + pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0]; + pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1]; + pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2]; + + RT_TRACE(COMP_COEX, DBG_TRACE, ("[BTCoex], FW write 0x66=0x%x\n", + H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); + + rtw_warn_on(_BTCOEX_CSR); + pBtCoexist->fBtcFillH2c(pBtCoexist, 0x66, 3, H2C_Parameter); + #endif +} + +VOID +EXhalbtc8821aCsr2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(type == BTC_PACKET_DHCP) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], DHCP Packet notify\n")); + } +} + +VOID +EXhalbtc8821aCsr2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ) +{ + u1Byte btInfo=0; + u1Byte i, rspSource=0; + BOOLEAN bBtBusy=FALSE, bLimitedDig=FALSE; + BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE, bWifiUnder5G=FALSE; + + pCoexSta->bC2hBtInfoReqSent = FALSE; + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G); + + rspSource = tmpBuf[0]&0xf; + if(rspSource >= BT_INFO_SRC_8821A_CSR_2ANT_MAX) + rspSource = BT_INFO_SRC_8821A_CSR_2ANT_WIFI_FW; + pCoexSta->btInfoC2hCnt[rspSource]++; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length)); + for(i=0; ibtInfoC2h[rspSource][i] = tmpBuf[i]; + if(i == 1) + btInfo = tmpBuf[i]; + if(i == length-1) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x]\n", tmpBuf[i])); + } + else + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("0x%02x, ", tmpBuf[i])); + } + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected); + if(BT_INFO_SRC_8821A_CSR_2ANT_WIFI_FW != rspSource) + { + pCoexSta->btRetryCnt = // [3:0] + pCoexSta->btInfoC2h[rspSource][2]&0xf; + + pCoexSta->btRssi = + pCoexSta->btInfoC2h[rspSource][3]*2+10; + + pCoexSta->btInfoExt = + pCoexSta->btInfoC2h[rspSource][4]; + + #if 0 /* REMOVE */ + // Here we need to resend some wifi info to BT + // because bt is reset and loss of the info. + if( (pCoexSta->btInfoExt & BIT1) ) + { + + if(bWifiConnected) + { + EXhalbtc8821aCsr2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT); + } + else + { + EXhalbtc8821aCsr2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); + } + } + #endif + + #if 0 /* REMOVE */ + if(!pBtCoexist->bManualControl && !bWifiUnder5G) + { + if( (pCoexSta->btInfoExt&BIT3) ) + { + if(bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n")); + halbtc8821aCsr2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE); + } + } + else + { + // BT already NOT ignore Wlan active, do nothing here. + if(!bWifiConnected) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT ext info bit3 check, set BT to ignore Wlan active!!\n")); + halbtc8821aCsr2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + } + } + } + #endif + + #if 0 /* REMOVE */ + if( (pCoexSta->btInfoExt & BIT4) ) + { + // BT auto report already enabled, do nothing + } + else + { + halbtc8821aCsr2ant_BtAutoReport(pBtCoexist, FORCE_EXEC, TRUE); + } + #endif + } + + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn); + + if(btInfo == BT_INFO_8821A_CSR_2ANT_B_CONNECTION) // connection exists but no busy + { + pCoexSta->bBtLinkExist = TRUE; + pCoexDm->btStatus = BT_8821A_CSR_2ANT_BT_STATUS_CONNECTED_IDLE; + } + else if(btInfo & BT_INFO_8821A_CSR_2ANT_B_CONNECTION) // connection exists and some link is busy + { + pCoexSta->bBtLinkExist = TRUE; + + if(btInfo & BT_INFO_8821A_CSR_2ANT_B_FTP) + pCoexSta->bPanExist = TRUE; + else + pCoexSta->bPanExist = FALSE; + + if(btInfo & BT_INFO_8821A_CSR_2ANT_B_A2DP) + pCoexSta->bA2dpExist = TRUE; + else + pCoexSta->bA2dpExist = FALSE; + + if(btInfo & BT_INFO_8821A_CSR_2ANT_B_HID) + pCoexSta->bHidExist = TRUE; + else + pCoexSta->bHidExist = FALSE; + + if(btInfo & BT_INFO_8821A_CSR_2ANT_B_SCO_ESCO) + pCoexSta->bScoExist = TRUE; + else + pCoexSta->bScoExist = FALSE; + + if (pCoexSta->btInfoExt & 0x80) + pCoexSta->bSlave = TRUE; //Slave + else + pCoexSta->bSlave = FALSE; //Master + + pCoexDm->btStatus = BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE; + } + else + { + pCoexSta->bBtLinkExist = FALSE; + pCoexSta->bPanExist = FALSE; + pCoexSta->bA2dpExist = FALSE; + pCoexSta->bSlave = FALSE; + pCoexSta->bHidExist = FALSE; + pCoexSta->bScoExist = FALSE; + pCoexDm->btStatus = BT_8821A_CSR_2ANT_BT_STATUS_IDLE; + } + + if(bBtHsOn) + { + pCoexDm->btStatus = BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE; + } + + if(btInfo & BT_INFO_8821A_CSR_2ANT_B_INQ_PAGE) + { + pCoexSta->bC2hBtInquiryPage = TRUE; + pCoexDm->btStatus = BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE; + } + else + { + pCoexSta->bC2hBtInquiryPage = FALSE; + } + + + if(BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE == pCoexDm->btStatus) + { + bBtBusy = TRUE; + } + else + { + bBtBusy = FALSE; + } + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy); + + if(BT_8821A_CSR_2ANT_BT_STATUS_IDLE != pCoexDm->btStatus) + { + bLimitedDig = TRUE; + } + else + { + bLimitedDig = FALSE; + } + pCoexDm->bLimitedDig = bLimitedDig; + pBtCoexist->fBtcSet(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bLimitedDig); + + halbtc8821aCsr2ant_RunCoexistMechanism(pBtCoexist); +} + +VOID +EXhalbtc8821aCsr2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Halt notify\n")); + + halbtc8821aCsr2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + EXhalbtc8821aCsr2ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT); +} + +VOID +EXhalbtc8821aCsr2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify\n")); + + if(BTC_WIFI_PNP_SLEEP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to SLEEP\n")); + halbtc8821aCsr2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, TRUE); + } + else if(BTC_WIFI_PNP_WAKE_UP == pnpState) + { + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Pnp notify to WAKE UP\n")); + } +} + +VOID +EXhalbtc8821aCsr2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ) +{ + static u1Byte disVerInfoCnt=0; + u4Byte fwVer=0, btPatchVer=0; + PBTC_BOARD_INFO pBoardInfo=&pBtCoexist->boardInfo; + PBTC_STACK_INFO pStackInfo=&pBtCoexist->stackInfo; + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ==========================Periodical===========================\n")); + + if(disVerInfoCnt <= 5) + { + disVerInfoCnt += 1; + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", + pBoardInfo->pgAntNum, pBoardInfo->btdmAntNum, pBoardInfo->btdmAntPos)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", + ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion)); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer); + pBtCoexist->fBtcGet(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", + GLCoexVerDate8821aCsr2Ant, GLCoexVer8821aCsr2Ant, fwVer, btPatchVer, btPatchVer)); + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], ****************************************************************\n")); + } + + //halbtc8821aCsr2ant_QueryBtInfo(pBtCoexist); + //halbtc8821aCsr2ant_RunCoexistMechanism(pBtCoexist); + halbtc8821aCsr2ant_MonitorBtCtr(pBtCoexist); + halbtc8821aCsr2ant_MonitorBtEnableDisable(pBtCoexist); +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.h new file mode 100644 index 00000000..aeebf821 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtc8821aCsr2Ant.h @@ -0,0 +1,207 @@ +//=========================================== +// The following is for 8821A_CSR 2Ant BT Co-exist definition +//=========================================== +#define BT_INFO_8821A_CSR_2ANT_B_FTP BIT7 +#define BT_INFO_8821A_CSR_2ANT_B_A2DP BIT6 +#define BT_INFO_8821A_CSR_2ANT_B_HID BIT5 +#define BT_INFO_8821A_CSR_2ANT_B_SCO_BUSY BIT4 +#define BT_INFO_8821A_CSR_2ANT_B_ACL_BUSY BIT3 +#define BT_INFO_8821A_CSR_2ANT_B_INQ_PAGE BIT2 +#define BT_INFO_8821A_CSR_2ANT_B_SCO_ESCO BIT1 +#define BT_INFO_8821A_CSR_2ANT_B_CONNECTION BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8821A_CSR_2ANT 2 + +typedef enum _BT_INFO_SRC_8821A_CSR_2ANT{ + BT_INFO_SRC_8821A_CSR_2ANT_WIFI_FW = 0x0, + BT_INFO_SRC_8821A_CSR_2ANT_BT_RSP = 0x1, + BT_INFO_SRC_8821A_CSR_2ANT_BT_ACTIVE_SEND = 0x2, + BT_INFO_SRC_8821A_CSR_2ANT_MAX +}BT_INFO_SRC_8821A_CSR_2ANT,*PBT_INFO_SRC_8821A_CSR_2ANT; + +typedef enum _BT_8821A_CSR_2ANT_BT_STATUS{ + BT_8821A_CSR_2ANT_BT_STATUS_IDLE = 0x0, + BT_8821A_CSR_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, + BT_8821A_CSR_2ANT_BT_STATUS_NON_IDLE = 0x2, + BT_8821A_CSR_2ANT_BT_STATUS_MAX +}BT_8821A_CSR_2ANT_BT_STATUS,*PBT_8821A_CSR_2ANT_BT_STATUS; + +typedef enum _BT_8821A_CSR_2ANT_COEX_ALGO{ + BT_8821A_CSR_2ANT_COEX_ALGO_UNDEFINED = 0x0, + BT_8821A_CSR_2ANT_COEX_ALGO_SCO = 0x1, + BT_8821A_CSR_2ANT_COEX_ALGO_HID = 0x2, + BT_8821A_CSR_2ANT_COEX_ALGO_A2DP = 0x3, + BT_8821A_CSR_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, + BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR = 0x5, + BT_8821A_CSR_2ANT_COEX_ALGO_PANHS = 0x6, + BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, + BT_8821A_CSR_2ANT_COEX_ALGO_PANEDR_HID = 0x8, + BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, + BT_8821A_CSR_2ANT_COEX_ALGO_HID_A2DP = 0xa, + BT_8821A_CSR_2ANT_COEX_ALGO_MAX = 0xb, +}BT_8821A_CSR_2ANT_COEX_ALGO,*PBT_8821A_CSR_2ANT_COEX_ALGO; + +typedef struct _COEX_DM_8821A_CSR_2ANT{ + // fw mechanism + BOOLEAN bPreDecBtPwr; + BOOLEAN bCurDecBtPwr; + u1Byte preFwDacSwingLvl; + u1Byte curFwDacSwingLvl; + BOOLEAN bCurIgnoreWlanAct; + BOOLEAN bPreIgnoreWlanAct; + u1Byte prePsTdma; + u1Byte curPsTdma; + u1Byte psTdmaPara[6]; + u1Byte psTdmaDuAdjType; + BOOLEAN bResetTdmaAdjust; + BOOLEAN bPrePsTdmaOn; + BOOLEAN bCurPsTdmaOn; + BOOLEAN bPreBtAutoReport; + BOOLEAN bCurBtAutoReport; + + // sw mechanism + BOOLEAN bPreRfRxLpfShrink; + BOOLEAN bCurRfRxLpfShrink; + u4Byte btRf0x1eBackup; + BOOLEAN bPreLowPenaltyRa; + BOOLEAN bCurLowPenaltyRa; + BOOLEAN bPreDacSwingOn; + u4Byte preDacSwingLvl; + BOOLEAN bCurDacSwingOn; + u4Byte curDacSwingLvl; + BOOLEAN bPreAdcBackOff; + BOOLEAN bCurAdcBackOff; + BOOLEAN bPreAgcTableEn; + BOOLEAN bCurAgcTableEn; + u4Byte preVal0x6c0; + u4Byte curVal0x6c0; + u4Byte preVal0x6c4; + u4Byte curVal0x6c4; + u4Byte preVal0x6c8; + u4Byte curVal0x6c8; + u1Byte preVal0x6cc; + u1Byte curVal0x6cc; + BOOLEAN bLimitedDig; + + u4Byte preRaMask; + u4Byte curRaMask; + + u1Byte curAmpduNumType; + u1Byte preAmpduNumType; + u2Byte backupAmpduMaxNum; + + u1Byte curAmpduTimeType; + u1Byte preAmpduTimeType; + u1Byte backupAmpduMaxTime; + + u1Byte curArfrType; + u1Byte preArfrType; + u4Byte backupArfrCnt1; + u4Byte backupArfrCnt2; + + u1Byte curRetryLimitType; + u1Byte preRetryLimitType; + u2Byte backupRetryLimit; + + // algorithm related + u1Byte preAlgorithm; + u1Byte curAlgorithm; + u1Byte btStatus; + u1Byte wifiChnlInfo[3]; +} COEX_DM_8821A_CSR_2ANT, *PCOEX_DM_8821A_CSR_2ANT; + +typedef struct _COEX_STA_8821A_CSR_2ANT{ + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bA2dpExist; + BOOLEAN bSlave; + BOOLEAN bHidExist; + BOOLEAN bPanExist; + + BOOLEAN bUnderLps; + BOOLEAN bUnderIps; + u4Byte highPriorityTx; + u4Byte highPriorityRx; + u4Byte lowPriorityTx; + u4Byte lowPriorityRx; + u1Byte btRssi; + u1Byte preBtRssiState; + u1Byte preWifiRssiState[4]; + BOOLEAN bC2hBtInfoReqSent; + u1Byte btInfoC2h[BT_INFO_SRC_8821A_CSR_2ANT_MAX][10]; + u4Byte btInfoC2hCnt[BT_INFO_SRC_8821A_CSR_2ANT_MAX]; + BOOLEAN bC2hBtInquiryPage; + u1Byte btRetryCnt; + u1Byte btInfoExt; +}COEX_STA_8821A_CSR_2ANT, *PCOEX_STA_8821A_CSR_2ANT; + +//=========================================== +// The following is interface which will notify coex module. +//=========================================== +VOID +EXhalbtc8821aCsr2ant_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821aCsr2ant_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtc8821aCsr2ant_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821aCsr2ant_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtc8821aCsr2ant_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtc8821aCsr2ant_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821aCsr2ant_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtc8821aCsr2ant_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtc8821aCsr2ant_DisplayCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtcOutSrc.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtcOutSrc.h new file mode 100644 index 00000000..6dbdcec2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/HalBtcOutSrc.h @@ -0,0 +1,747 @@ +#ifndef __HALBTC_OUT_SRC_H__ +#define __HALBTC_OUT_SRC_H__ + +#define NORMAL_EXEC FALSE +#define FORCE_EXEC TRUE + +#define BTC_RF_OFF 0x0 +#define BTC_RF_ON 0x1 + +#define BTC_RF_A 0x0 +#define BTC_RF_B 0x1 +#define BTC_RF_C 0x2 +#define BTC_RF_D 0x3 + +#define BTC_SMSP SINGLEMAC_SINGLEPHY +#define BTC_DMDP DUALMAC_DUALPHY +#define BTC_DMSP DUALMAC_SINGLEPHY +#define BTC_MP_UNKNOWN 0xff + +#define BT_COEX_ANT_TYPE_PG 0 +#define BT_COEX_ANT_TYPE_ANTDIV 1 +#define BT_COEX_ANT_TYPE_DETECTED 2 + +#define BTC_MIMO_PS_STATIC 0 // 1ss +#define BTC_MIMO_PS_DYNAMIC 1 // 2ss + +#define BTC_RATE_DISABLE 0 +#define BTC_RATE_ENABLE 1 + +// single Antenna definition +#define BTC_ANT_PATH_WIFI 0 +#define BTC_ANT_PATH_BT 1 +#define BTC_ANT_PATH_PTA 2 +// dual Antenna definition +#define BTC_ANT_WIFI_AT_MAIN 0 +#define BTC_ANT_WIFI_AT_AUX 1 +// coupler Antenna definition +#define BTC_ANT_WIFI_AT_CPL_MAIN 0 +#define BTC_ANT_WIFI_AT_CPL_AUX 1 + +typedef enum _BTC_POWERSAVE_TYPE{ + BTC_PS_WIFI_NATIVE = 0, // wifi original power save behavior + BTC_PS_LPS_ON = 1, + BTC_PS_LPS_OFF = 2, + BTC_PS_MAX +} BTC_POWERSAVE_TYPE, *PBTC_POWERSAVE_TYPE; + +typedef enum _BTC_BT_REG_TYPE{ + BTC_BT_REG_RF = 0, + BTC_BT_REG_MODEM = 1, + BTC_BT_REG_BLUEWIZE = 2, + BTC_BT_REG_VENDOR = 3, + BTC_BT_REG_LE = 4, + BTC_BT_REG_MAX +} BTC_BT_REG_TYPE, *PBTC_BT_REG_TYPE; + +typedef enum _BTC_CHIP_INTERFACE{ + BTC_INTF_UNKNOWN = 0, + BTC_INTF_PCI = 1, + BTC_INTF_USB = 2, + BTC_INTF_SDIO = 3, + BTC_INTF_MAX +} BTC_CHIP_INTERFACE, *PBTC_CHIP_INTERFACE; + +typedef enum _BTC_CHIP_TYPE{ + BTC_CHIP_UNDEF = 0, + BTC_CHIP_CSR_BC4 = 1, + BTC_CHIP_CSR_BC8 = 2, + BTC_CHIP_RTL8723A = 3, + BTC_CHIP_RTL8821 = 4, + BTC_CHIP_RTL8723B = 5, + BTC_CHIP_MAX +} BTC_CHIP_TYPE, *PBTC_CHIP_TYPE; + +// following is for wifi link status +#define WIFI_STA_CONNECTED BIT0 +#define WIFI_AP_CONNECTED BIT1 +#define WIFI_HS_CONNECTED BIT2 +#define WIFI_P2P_GO_CONNECTED BIT3 +#define WIFI_P2P_GC_CONNECTED BIT4 + +// following is for command line utility +#define CL_SPRINTF rsprintf +#define CL_PRINTF DCMD_Printf + + +typedef struct _BTC_BOARD_INFO{ + // The following is some board information + u1Byte btChipType; + u1Byte pgAntNum; // pg ant number + u1Byte btdmAntNum; // ant number for btdm + u1Byte btdmAntNumByAntDet; // ant number for btdm after antenna detection + u1Byte btdmAntPos; //Bryant Add to indicate Antenna Position for (pgAntNum = 2) && (btdmAntNum =1) (DPDT+1Ant case) + u1Byte singleAntPath; // current used for 8723b only, 1=>s0, 0=>s1 + u1Byte bTfbgaPackage; //for Antenna detect threshold + u1Byte btdmAntDetFinish; + u1Byte antType; +} BTC_BOARD_INFO, *PBTC_BOARD_INFO; + +typedef enum _BTC_DBG_OPCODE{ + BTC_DBG_SET_COEX_NORMAL = 0x0, + BTC_DBG_SET_COEX_WIFI_ONLY = 0x1, + BTC_DBG_SET_COEX_BT_ONLY = 0x2, + BTC_DBG_SET_COEX_DEC_BT_PWR = 0x3, + BTC_DBG_SET_COEX_BT_AFH_MAP = 0x4, + BTC_DBG_SET_COEX_BT_IGNORE_WLAN_ACT = 0x5, + BTC_DBG_MAX +}BTC_DBG_OPCODE,*PBTC_DBG_OPCODE; + +typedef enum _BTC_RSSI_STATE{ + BTC_RSSI_STATE_HIGH = 0x0, + BTC_RSSI_STATE_MEDIUM = 0x1, + BTC_RSSI_STATE_LOW = 0x2, + BTC_RSSI_STATE_STAY_HIGH = 0x3, + BTC_RSSI_STATE_STAY_MEDIUM = 0x4, + BTC_RSSI_STATE_STAY_LOW = 0x5, + BTC_RSSI_MAX +}BTC_RSSI_STATE,*PBTC_RSSI_STATE; +#define BTC_RSSI_HIGH(_rssi_) ((_rssi_==BTC_RSSI_STATE_HIGH||_rssi_==BTC_RSSI_STATE_STAY_HIGH)? TRUE:FALSE) +#define BTC_RSSI_MEDIUM(_rssi_) ((_rssi_==BTC_RSSI_STATE_MEDIUM||_rssi_==BTC_RSSI_STATE_STAY_MEDIUM)? TRUE:FALSE) +#define BTC_RSSI_LOW(_rssi_) ((_rssi_==BTC_RSSI_STATE_LOW||_rssi_==BTC_RSSI_STATE_STAY_LOW)? TRUE:FALSE) + +typedef enum _BTC_WIFI_ROLE{ + BTC_ROLE_STATION = 0x0, + BTC_ROLE_AP = 0x1, + BTC_ROLE_IBSS = 0x2, + BTC_ROLE_HS_MODE = 0x3, + 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; + +typedef enum _BTC_WIFI_TRAFFIC_DIR{ + BTC_WIFI_TRAFFIC_TX = 0x0, + BTC_WIFI_TRAFFIC_RX = 0x1, + BTC_WIFI_TRAFFIC_MAX +}BTC_WIFI_TRAFFIC_DIR,*PBTC_WIFI_TRAFFIC_DIR; + +typedef enum _BTC_WIFI_PNP{ + BTC_WIFI_PNP_WAKE_UP = 0x0, + BTC_WIFI_PNP_SLEEP = 0x1, + BTC_WIFI_PNP_MAX +}BTC_WIFI_PNP,*PBTC_WIFI_PNP; + +typedef enum _BTC_IOT_PEER +{ + BTC_IOT_PEER_UNKNOWN = 0, + BTC_IOT_PEER_REALTEK = 1, + BTC_IOT_PEER_REALTEK_92SE = 2, + BTC_IOT_PEER_BROADCOM = 3, + BTC_IOT_PEER_RALINK = 4, + BTC_IOT_PEER_ATHEROS = 5, + BTC_IOT_PEER_CISCO = 6, + BTC_IOT_PEER_MERU = 7, + BTC_IOT_PEER_MARVELL = 8, + BTC_IOT_PEER_REALTEK_SOFTAP = 9,// peer is RealTek SOFT_AP, by Bohn, 2009.12.17 + BTC_IOT_PEER_SELF_SOFTAP = 10, // Self is SoftAP + BTC_IOT_PEER_AIRGO = 11, + BTC_IOT_PEER_INTEL = 12, + BTC_IOT_PEER_RTK_APCLIENT = 13, + BTC_IOT_PEER_REALTEK_81XX = 14, + BTC_IOT_PEER_REALTEK_WOW = 15, + BTC_IOT_PEER_REALTEK_JAGUAR_BCUTAP = 16, + BTC_IOT_PEER_REALTEK_JAGUAR_CCUTAP = 17, + BTC_IOT_PEER_MAX, +}BTC_IOT_PEER, *PBTC_IOT_PEER; + +//for 8723b-d cut large current issue +typedef enum _BT_WIFI_COEX_STATE{ + BTC_WIFI_STAT_INIT, + BTC_WIFI_STAT_IQK, + BTC_WIFI_STAT_NORMAL_OFF, + BTC_WIFI_STAT_MP_OFF, + BTC_WIFI_STAT_NORMAL, + BTC_WIFI_STAT_ANT_DIV, + 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 + BTC_GET_BL_HS_OPERATION, + BTC_GET_BL_HS_CONNECTING, + BTC_GET_BL_WIFI_CONNECTED, + BTC_GET_BL_WIFI_BUSY, + BTC_GET_BL_WIFI_SCAN, + BTC_GET_BL_WIFI_LINK, + BTC_GET_BL_WIFI_ROAM, + BTC_GET_BL_WIFI_4_WAY_PROGRESS, + BTC_GET_BL_WIFI_UNDER_5G, + BTC_GET_BL_WIFI_AP_MODE_ENABLE, + BTC_GET_BL_WIFI_ENABLE_ENCRYPTION, + 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, + BTC_GET_S4_HS_RSSI, + + // type u4Byte + BTC_GET_U4_WIFI_BW, + BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, + BTC_GET_U4_WIFI_FW_VER, + BTC_GET_U4_WIFI_LINK_STATUS, + BTC_GET_U4_BT_PATCH_VER, + + // type u1Byte + BTC_GET_U1_WIFI_DOT11_CHNL, + BTC_GET_U1_WIFI_CENTRAL_CHNL, + BTC_GET_U1_WIFI_HS_CHNL, + BTC_GET_U1_MAC_PHY_MODE, + BTC_GET_U1_AP_NUM, + BTC_GET_U1_ANT_TYPE, + BTC_GET_U1_IOT_PEER, + + //===== for 1Ant ====== + BTC_GET_U1_LPS_MODE, + + BTC_GET_MAX +}BTC_GET_TYPE,*PBTC_GET_TYPE; + +// defined for BFP_BTC_SET +typedef enum _BTC_SET_TYPE{ + // type BOOLEAN + BTC_SET_BL_BT_DISABLE, + BTC_SET_BL_BT_TRAFFIC_BUSY, + BTC_SET_BL_BT_LIMITED_DIG, + BTC_SET_BL_FORCE_TO_ROAM, + BTC_SET_BL_TO_REJ_AP_AGG_PKT, + BTC_SET_BL_BT_CTRL_AGG_SIZE, + BTC_SET_BL_INC_SCAN_DEV_NUM, + BTC_SET_BL_BT_TX_RX_MASK, + BTC_SET_BL_MIRACAST_PLUS_BT, + + // type u1Byte + BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, + BTC_SET_U1_AGG_BUF_SIZE, + + // type trigger some action + BTC_SET_ACT_GET_BT_RSSI, + BTC_SET_ACT_AGGREGATE_CTRL, + //===== for 1Ant ====== + // type BOOLEAN + + // type u1Byte + BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, + BTC_SET_U1_LPS_VAL, + BTC_SET_U1_RPWM_VAL, + // type trigger some action + BTC_SET_ACT_LEAVE_LPS, + BTC_SET_ACT_ENTER_LPS, + BTC_SET_ACT_NORMAL_LPS, + BTC_SET_ACT_DISABLE_LOW_POWER, + BTC_SET_ACT_UPDATE_RAMASK, + BTC_SET_ACT_SEND_MIMO_PS, + // BT Coex related + BTC_SET_ACT_CTRL_BT_INFO, + BTC_SET_ACT_CTRL_BT_COEX, + BTC_SET_ACT_CTRL_8723B_ANT, + //================= + BTC_SET_MAX +}BTC_SET_TYPE,*PBTC_SET_TYPE; + +typedef enum _BTC_DBG_DISP_TYPE{ + BTC_DBG_DISP_COEX_STATISTICS = 0x0, + BTC_DBG_DISP_BT_LINK_INFO = 0x1, + BTC_DBG_DISP_WIFI_STATUS = 0x2, + BTC_DBG_DISP_MAX +}BTC_DBG_DISP_TYPE,*PBTC_DBG_DISP_TYPE; + +typedef enum _BTC_NOTIFY_TYPE_IPS{ + BTC_IPS_LEAVE = 0x0, + BTC_IPS_ENTER = 0x1, + BTC_IPS_MAX +}BTC_NOTIFY_TYPE_IPS,*PBTC_NOTIFY_TYPE_IPS; +typedef enum _BTC_NOTIFY_TYPE_LPS{ + BTC_LPS_DISABLE = 0x0, + BTC_LPS_ENABLE = 0x1, + BTC_LPS_MAX +}BTC_NOTIFY_TYPE_LPS,*PBTC_NOTIFY_TYPE_LPS; +typedef enum _BTC_NOTIFY_TYPE_SCAN{ + BTC_SCAN_FINISH = 0x0, + BTC_SCAN_START = 0x1, + BTC_SCAN_MAX +}BTC_NOTIFY_TYPE_SCAN,*PBTC_NOTIFY_TYPE_SCAN; +typedef enum _BTC_NOTIFY_TYPE_ASSOCIATE{ + BTC_ASSOCIATE_FINISH = 0x0, + BTC_ASSOCIATE_START = 0x1, + BTC_ASSOCIATE_MAX +}BTC_NOTIFY_TYPE_ASSOCIATE,*PBTC_NOTIFY_TYPE_ASSOCIATE; +typedef enum _BTC_NOTIFY_TYPE_MEDIA_STATUS{ + BTC_MEDIA_DISCONNECT = 0x0, + BTC_MEDIA_CONNECT = 0x1, + BTC_MEDIA_MAX +}BTC_NOTIFY_TYPE_MEDIA_STATUS,*PBTC_NOTIFY_TYPE_MEDIA_STATUS; +typedef enum _BTC_NOTIFY_TYPE_SPECIAL_PACKET{ + BTC_PACKET_UNKNOWN = 0x0, + BTC_PACKET_DHCP = 0x1, + BTC_PACKET_ARP = 0x2, + BTC_PACKET_EAPOL = 0x3, + BTC_PACKET_MAX +}BTC_NOTIFY_TYPE_SPECIAL_PACKET,*PBTC_NOTIFY_TYPE_SPECIAL_PACKET; +typedef enum _BTC_NOTIFY_TYPE_STACK_OPERATION{ + BTC_STACK_OP_NONE = 0x0, + BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, + BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2, + BTC_STACK_OP_MAX +}BTC_NOTIFY_TYPE_STACK_OPERATION,*PBTC_NOTIFY_TYPE_STACK_OPERATION; + +//Bryant Add +typedef enum _BTC_ANTENNA_POS{ + BTC_ANTENNA_AT_MAIN_PORT = 0x1, + BTC_ANTENNA_AT_AUX_PORT = 0x2, +}BTC_ANTENNA_POS,*PBTC_ANTENNA_POS; + +//Bryant Add +typedef enum _BTC_BT_OFFON{ + BTC_BT_OFF = 0x0, + BTC_BT_ON = 0x1, +}BTC_BTOFFON,*PBTC_BT_OFFON; + +typedef u1Byte +(*BFP_BTC_R1)( + IN PVOID pBtcContext, + IN u4Byte RegAddr + ); +typedef u2Byte +(*BFP_BTC_R2)( + IN PVOID pBtcContext, + IN u4Byte RegAddr + ); +typedef u4Byte +(*BFP_BTC_R4)( + IN PVOID pBtcContext, + IN u4Byte RegAddr + ); +typedef VOID +(*BFP_BTC_W1)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u1Byte Data + ); +typedef VOID +(*BFP_BTC_W1_BIT_MASK)( + IN PVOID pBtcContext, + IN u4Byte regAddr, + IN u1Byte bitMask, + IN u1Byte data1b + ); +typedef VOID +(*BFP_BTC_W2)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u2Byte Data + ); +typedef VOID +(*BFP_BTC_W4)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u4Byte Data + ); +typedef VOID +(*BFP_BTC_LOCAL_REG_W1)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u1Byte Data + ); +typedef VOID +(*BFP_BTC_SET_BB_REG)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); +typedef u4Byte +(*BFP_BTC_GET_BB_REG)( + IN PVOID pBtcContext, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); +typedef VOID +(*BFP_BTC_SET_RF_REG)( + IN PVOID pBtcContext, + IN u1Byte eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); +typedef u4Byte +(*BFP_BTC_GET_RF_REG)( + IN PVOID pBtcContext, + IN u1Byte eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); +typedef VOID +(*BFP_BTC_FILL_H2C)( + IN PVOID pBtcContext, + IN u1Byte elementId, + IN u4Byte cmdLen, + IN pu1Byte pCmdBuffer + ); + +typedef BOOLEAN +(*BFP_BTC_GET)( + IN PVOID pBtCoexist, + IN u1Byte getType, + OUT PVOID pOutBuf + ); + +typedef BOOLEAN +(*BFP_BTC_SET)( + IN PVOID pBtCoexist, + IN u1Byte setType, + OUT PVOID pInBuf + ); +typedef u2Byte +(*BFP_BTC_SET_BT_REG)( + IN PVOID pBtcContext, + IN u1Byte regType, + IN u4Byte offset, + IN u4Byte value + ); +typedef BOOLEAN +(*BFP_BTC_SET_BT_ANT_DETECTION)( + IN PVOID pBtcContext, + IN u1Byte txTime, + IN u1Byte btChnl + ); +typedef u2Byte +(*BFP_BTC_GET_BT_REG)( + IN PVOID pBtcContext, + IN u1Byte regType, + IN u4Byte offset, + IN pu4Byte data + ); +typedef VOID +(*BFP_BTC_DISP_DBG_MSG)( + IN PVOID pBtCoexist, + IN u1Byte dispType + ); + +typedef struct _BTC_BT_INFO{ + BOOLEAN bBtDisabled; + u1Byte rssiAdjustForAgcTableOn; + u1Byte rssiAdjustFor1AntCoexType; + BOOLEAN bPreBtCtrlAggBufSize; + BOOLEAN bBtCtrlAggBufSize; + BOOLEAN bPreRejectAggPkt; + BOOLEAN bRejectAggPkt; + BOOLEAN bIncreaseScanDevNum; + BOOLEAN bBtTxRxMask; + u1Byte preAggBufSize; + u1Byte aggBufSize; + BOOLEAN bBtBusy; + BOOLEAN bLimitedDig; + u2Byte btHciVer; + u2Byte btRealFwVer; + u1Byte btFwVer; + u4Byte getBtFwVerCnt; + BOOLEAN bMiracastPlusBt; + + BOOLEAN bBtDisableLowPwr; + + BOOLEAN bBtCtrlLps; + BOOLEAN bBtLpsOn; + BOOLEAN bForceToRoam; // for 1Ant solution + u1Byte lpsVal; + u1Byte rpwmVal; + u4Byte raMask; +} BTC_BT_INFO, *PBTC_BT_INFO; + +typedef struct _BTC_STACK_INFO{ + BOOLEAN bProfileNotified; + u2Byte hciVersion; // stack hci version + u1Byte numOfLink; + BOOLEAN bBtLinkExist; + BOOLEAN bScoExist; + BOOLEAN bAclExist; + BOOLEAN bA2dpExist; + BOOLEAN bHidExist; + u1Byte numOfHid; + BOOLEAN bPanExist; + BOOLEAN bUnknownAclExist; + s1Byte minBtRssi; +} BTC_STACK_INFO, *PBTC_STACK_INFO; + +typedef struct _BTC_BT_LINK_INFO{ + BOOLEAN bBtLinkExist; + BOOLEAN bBtHiPriLinkExist; + BOOLEAN bScoExist; + BOOLEAN bScoOnly; + BOOLEAN bA2dpExist; + BOOLEAN bA2dpOnly; + BOOLEAN bHidExist; + BOOLEAN bHidOnly; + 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; + u4Byte cntLpsNotify; + u4Byte cntScanNotify; + u4Byte cntConnectNotify; + u4Byte cntMediaStatusNotify; + u4Byte cntSpecialPacketNotify; + u4Byte cntBtInfoNotify; + u4Byte cntRfStatusNotify; + u4Byte cntPeriodical; + u4Byte cntCoexDmSwitch; + u4Byte cntStackOperationNotify; + u4Byte cntDbgCtrl; +} BTC_STATISTICS, *PBTC_STATISTICS; + +typedef struct _BTC_COEXIST{ + BOOLEAN bBinded; // make sure only one adapter can bind the data context + PVOID Adapter; // default adapter + BTC_BOARD_INFO boardInfo; + BTC_BT_INFO btInfo; // some bt info referenced by non-bt module + BTC_STACK_INFO stackInfo; + BTC_BT_LINK_INFO btLinkInfo; + BTC_CHIP_INTERFACE chipInterface; + + BOOLEAN bInitilized; + BOOLEAN bStopCoexDm; + BOOLEAN bManualControl; + pu1Byte cliBuf; + BTC_STATISTICS statistics; + u1Byte pwrModeVal[10]; + + // function pointers + // io related + BFP_BTC_R1 fBtcRead1Byte; + BFP_BTC_W1 fBtcWrite1Byte; + BFP_BTC_W1_BIT_MASK fBtcWrite1ByteBitMask; + BFP_BTC_R2 fBtcRead2Byte; + BFP_BTC_W2 fBtcWrite2Byte; + BFP_BTC_R4 fBtcRead4Byte; + BFP_BTC_W4 fBtcWrite4Byte; + BFP_BTC_LOCAL_REG_W1 fBtcWriteLocalReg1Byte; + // read/write bb related + BFP_BTC_SET_BB_REG fBtcSetBbReg; + BFP_BTC_GET_BB_REG fBtcGetBbReg; + + // read/write rf related + BFP_BTC_SET_RF_REG fBtcSetRfReg; + BFP_BTC_GET_RF_REG fBtcGetRfReg; + + // fill h2c related + BFP_BTC_FILL_H2C fBtcFillH2c; + // other + BFP_BTC_DISP_DBG_MSG fBtcDispDbgMsg; + // normal get/set related + BFP_BTC_GET fBtcGet; + BFP_BTC_SET fBtcSet; + + BFP_BTC_GET_BT_REG fBtcGetBtReg; + BFP_BTC_SET_BT_REG fBtcSetBtReg; + + BFP_BTC_SET_BT_ANT_DETECTION fBtcSetBtAntDetection; +} BTC_COEXIST, *PBTC_COEXIST; + +extern BTC_COEXIST GLBtCoexist; + +BOOLEAN +EXhalbtcoutsrc_InitlizeVariables( + IN PVOID Adapter + ); +VOID +EXhalbtcoutsrc_PowerOnSetting( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_PreLoadFirmware( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_InitHwConfig( + IN PBTC_COEXIST pBtCoexist, + IN BOOLEAN bWifiOnly + ); +VOID +EXhalbtcoutsrc_InitCoexDm( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_IpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtcoutsrc_LpsNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtcoutsrc_ScanNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtcoutsrc_ConnectNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte action + ); +VOID +EXhalbtcoutsrc_MediaStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN RT_MEDIA_STATUS mediaStatus + ); +VOID +EXhalbtcoutsrc_SpecialPacketNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pktType + ); +VOID +EXhalbtcoutsrc_BtInfoNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtcoutsrc_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtcoutsrc_StackOperationNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ); +VOID +EXhalbtcoutsrc_HaltNotify( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_PnpNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte pnpState + ); +VOID +EXhalbtcoutsrc_ScoreBoardStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN pu1Byte tmpBuf, + IN u1Byte length + ); +VOID +EXhalbtcoutsrc_CoexDmSwitch( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_Periodical( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_DbgControl( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte opCode, + IN u1Byte opLen, + 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 + ); +VOID +EXhalbtcoutsrc_SetHciVersion( + IN u2Byte hciVersion + ); +VOID +EXhalbtcoutsrc_SetBtPatchVersion( + IN u2Byte btHciVersion, + IN u2Byte btPatchVersion + ); +VOID +EXhalbtcoutsrc_UpdateMinBtRssi( + IN s1Byte btRssi + ); +#if 0 +VOID +EXhalbtcoutsrc_SetBtExist( + IN BOOLEAN bBtExist + ); +#endif +VOID +EXhalbtcoutsrc_SetChipType( + IN u1Byte chipType + ); +VOID +EXhalbtcoutsrc_SetAntNum( + IN u1Byte type, + IN u1Byte antNum + ); +VOID +EXhalbtcoutsrc_SetSingleAntPath( + IN u1Byte singleAntPath + ); +VOID +EXhalbtcoutsrc_DisplayBtCoexInfo( + IN PBTC_COEXIST pBtCoexist + ); +VOID +EXhalbtcoutsrc_DisplayAntDetection( + IN PBTC_COEXIST pBtCoexist + ); + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/Mp_Precomp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/Mp_Precomp.h new file mode 100644 index 00000000..62abb5e2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/btc/Mp_Precomp.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 __MP_PRECOMP_H__ +#define __MP_PRECOMP_H__ + +#include +#include + +#define BT_TMP_BUF_SIZE 100 + +#ifdef PLATFORM_LINUX +#define rsprintf snprintf +#elif defined(PLATFORM_WINDOWS) +#define rsprintf sprintf_s +#endif + +#define DCMD_Printf DBG_BT_INFO + +#define delay_ms(ms) rtw_mdelay_os(ms) + +#ifdef bEnable +#undef bEnable +#endif + +#define WPP_SOFTWARE_TRACE 0 + +typedef enum _BTC_MSG_COMP_TYPE{ + COMP_COEX = 0, + COMP_MAX +}BTC_MSG_COMP_TYPE; +extern u4Byte GLBtcDbgType[]; + +#define DBG_OFF 0 +#define DBG_SEC 1 +#define DBG_SERIOUS 2 +#define DBG_WARNING 3 +#define DBG_LOUD 4 +#define DBG_TRACE 5 + +#if DBG +#ifdef RT_TRACE +#undef RT_TRACE +#define RT_TRACE(dbgtype, dbgflag, printstr)\ +do {\ + if (GLBtcDbgType[dbgtype] & BIT(dbgflag))\ + {\ + DbgPrint printstr;\ + }\ +} while (0) +#endif +#else +#define RT_TRACE(dbgtype, dbgflag, printstr) +#endif + +#include "HalBtcOutSrc.h" +#include "HalBtc8188c2Ant.h" +#include "HalBtc8192d2Ant.h" +#include "HalBtc8192e1Ant.h" +#include "HalBtc8192e2Ant.h" +#include "HalBtc8723a1Ant.h" +#include "HalBtc8723a2Ant.h" +#include "HalBtc8723b1Ant.h" +#include "HalBtc8723b2Ant.h" +#include "HalBtc8812a1Ant.h" +#include "HalBtc8812a2Ant.h" +#include "HalBtc8821a1Ant.h" +#include "HalBtc8821a2Ant.h" +#include "HalBtc8821aCsr2Ant.h" +#include "HalBtc8703b1Ant.h" +#include "HalBtc8703b2Ant.h" + +#endif // __MP_PRECOMP_H__ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/efuse_mask.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/efuse_mask.h new file mode 100644 index 00000000..9611e48f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/efuse_mask.h @@ -0,0 +1,80 @@ + +#if DEV_BUS_TYPE == RT_USB_INTERFACE + + #if defined(CONFIG_RTL8188E) + #include "rtl8188e/HalEfuseMask8188E_USB.h" + #endif + + #if defined(CONFIG_RTL8812A) + #include "rtl8812a/HalEfuseMask8812A_USB.h" + #endif + + #if defined(CONFIG_RTL8821A) + #include "rtl8812a/HalEfuseMask8821A_USB.h" + #endif + + #if defined(CONFIG_RTL8192E) + #include "rtl8192e/HalEfuseMask8192E_USB.h" + #endif + + #if defined(CONFIG_RTL8723B) + #include "rtl8723b/HalEfuseMask8723B_USB.h" + #endif + + #if defined(CONFIG_RTL8814A) + #include "rtl8814a/HalEfuseMask8814A_USB.h" + #endif + + #if defined(CONFIG_RTL8703B) + #include "rtl8703b/HalEfuseMask8703B_USB.h" + #endif + + #if defined(CONFIG_RTL8188F) + #include "rtl8188f/HalEfuseMask8188F_USB.h" + #endif + +#elif DEV_BUS_TYPE == RT_PCI_INTERFACE + + #if defined(CONFIG_RTL8188E) + #include "rtl8188e/HalEfuseMask8188E_PCIE.h" + #endif + + #if defined(CONFIG_RTL8812A) + #include "rtl8812a/HalEfuseMask8812A_PCIE.h" + #endif + + #if defined(CONFIG_RTL8821A) + #include "rtl8812a/HalEfuseMask8821A_PCIE.h" + #endif + + #if defined(CONFIG_RTL8192E) + #include "rtl8192e/HalEfuseMask8192E_PCIE.h" + #endif + + #if defined(CONFIG_RTL8723B) + #include "rtl8723b/HalEfuseMask8723B_PCIE.h" + #endif + + #if defined(CONFIG_RTL8814A) + #include "rtl8814a/HalEfuseMask8814A_PCIE.h" + #endif + + #if defined(CONFIG_RTL8703B) + #include "rtl8703b/HalEfuseMask8703B_PCIE.h" + #endif + +#elif DEV_BUS_TYPE == RT_SDIO_INTERFACE + + #if defined(CONFIG_RTL8188E) + #include "rtl8188e/HalEfuseMask8188E_SDIO.h" + #endif + + #if defined(CONFIG_RTL8703B) + #include "rtl8703b/HalEfuseMask8703B_SDIO.h" + #endif + + #if defined(CONFIG_RTL8188F) + #include "rtl8188f/HalEfuseMask8188F_SDIO.h" + #endif + +#endif \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.c new file mode 100644 index 00000000..4840acb6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.c @@ -0,0 +1,103 @@ +/****************************************************************************** +* +* 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 "../odm_precomp.h" + +#include + +#include "HalEfuseMask8188F_SDIO.h" + + + +/****************************************************************************** +* MSDIO.TXT +******************************************************************************/ + +u1Byte Array_MP_8188F_MSDIO[] = { +0xFF, +0xF3, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x0F, +0xF1, +0xFF, +0xFF, +0xFF, +0xFF, +0xFF, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +}; + +u2Byte +EFUSE_GetArrayLen_MP_8188F_MSDIO(VOID) +{ + return sizeof(Array_MP_8188F_MSDIO)/sizeof(u1Byte); +} + +VOID +EFUSE_GetMaskArray_MP_8188F_MSDIO( + IN OUT pu1Byte Array + ) +{ + u2Byte len = EFUSE_GetArrayLen_MP_8188F_MSDIO(), i = 0; + + for (i = 0; i < len; ++i) + Array[i] = Array_MP_8188F_MSDIO[i]; +} +BOOLEAN +EFUSE_IsAddressMasked_MP_8188F_MSDIO( + IN u2Byte Offset + ) +{ + int r = Offset/16; + int c = (Offset%16) / 2; + int result = 0; + + if (c < 4) // Upper double word + result = (Array_MP_8188F_MSDIO[r] & (0x10 << c)); + else + result = (Array_MP_8188F_MSDIO[r] & (0x01 << (c-4))); + + return (result > 0) ? 0 : 1; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.h new file mode 100644 index 00000000..3fa4e3e7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_SDIO.h @@ -0,0 +1,41 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + + + +/****************************************************************************** +* MSDIO.TXT +******************************************************************************/ + + +u2Byte +EFUSE_GetArrayLen_MP_8188F_MSDIO(VOID); + +VOID +EFUSE_GetMaskArray_MP_8188F_MSDIO( + IN OUT pu1Byte Array +); + +BOOLEAN +EFUSE_IsAddressMasked_MP_8188F_MSDIO( // TC: Test Chip, MP: MP Chip + IN u2Byte Offset +); + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.c new file mode 100644 index 00000000..9912f5d1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.c @@ -0,0 +1,102 @@ +/****************************************************************************** +* +* 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 "../odm_precomp.h" + +#include + +#include "HalEfuseMask8188F_USB.h" + + +/****************************************************************************** +* MUSB.TXT +******************************************************************************/ + +u1Byte Array_MP_8188F_MUSB[] = { +0xFF, +0xF3, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x0F, +0xF1, +0xFF, +0xFF, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, +0x00, + +}; + +u2Byte +EFUSE_GetArrayLen_MP_8188F_MUSB(VOID) +{ + return sizeof(Array_MP_8188F_MUSB)/sizeof(u1Byte); +} + +VOID +EFUSE_GetMaskArray_MP_8188F_MUSB( + IN OUT pu1Byte Array + ) +{ + u2Byte len = EFUSE_GetArrayLen_MP_8188F_MUSB(), i = 0; + + for (i = 0; i < len; ++i) + Array[i] = Array_MP_8188F_MUSB[i]; +} +BOOLEAN +EFUSE_IsAddressMasked_MP_8188F_MUSB( + IN u2Byte Offset + ) +{ + int r = Offset/16; + int c = (Offset%16) / 2; + int result = 0; + + if (c < 4) // Upper double word + result = (Array_MP_8188F_MUSB[r] & (0x10 << c)); + else + result = (Array_MP_8188F_MUSB[r] & (0x01 << (c-4))); + + return (result > 0) ? 0 : 1; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.h new file mode 100644 index 00000000..e4890cad --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/efuse/rtl8188f/HalEfuseMask8188F_USB.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + + + +/****************************************************************************** +* MUSB.TXT +******************************************************************************/ + + +u2Byte +EFUSE_GetArrayLen_MP_8188F_MUSB(VOID); + +VOID +EFUSE_GetMaskArray_MP_8188F_MUSB( + IN OUT pu1Byte Array +); + +BOOLEAN +EFUSE_IsAddressMasked_MP_8188F_MUSB( // TC: Test Chip, MP: MP Chip + IN u2Byte Offset +); + + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_btcoex.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_btcoex.c new file mode 100644 index 00000000..1c26fd92 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_btcoex.c @@ -0,0 +1,3692 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +#define __HAL_BTCOEX_C__ + +#ifdef CONFIG_BT_COEXIST + +#include +#include +#include + +//==================================== +// Global variables +//==================================== +const char *const BtProfileString[] = +{ + "NONE", + "A2DP", + "PAN", + "HID", + "SCO", +}; + +const char *const BtSpecString[] = +{ + "1.0b", + "1.1", + "1.2", + "2.0+EDR", + "2.1+EDR", + "3.0+HS", + "4.0", +}; + +const char *const BtLinkRoleString[] = +{ + "Master", + "Slave", +}; + +const char *const h2cStaString[] = +{ + "successful", + "h2c busy", + "rf off", + "fw not read", +}; + +const char *const ioStaString[] = +{ + "success", + "can not IO", + "rf off", + "fw not read", + "wait io timeout", + "invalid len", + "idle Q empty", + "insert waitQ fail", + "unknown fail", + "wrong level", + "h2c stopped", +}; + +const char *const GLBtcWifiBwString[]={ + "11bg", + "HT20", + "HT40", + "HT80", + "HT160" +}; + +const char *const GLBtcWifiFreqString[]={ + "2.4G", + "5G" +}; + +const char *const GLBtcIotPeerString[] = { + "UNKNOWN", + "REALTEK", + "REALTEK_92SE", + "BROADCOM", + "RALINK", + "ATHEROS", + "CISCO", + "MERU", + "MARVELL", + "REALTEK_SOFTAP", /* peer is RealTek SOFT_AP, by Bohn, 2009.12.17 */ + "SELF_SOFTAP", /* Self is SoftAP */ + "AIRGO", + "INTEL", + "RTK_APCLIENT", + "REALTEK_81XX", + "REALTEK_WOW", + "REALTEK_JAGUAR_BCUTAP", + "REALTEK_JAGUAR_CCUTAP" +}; + +#define HALBTCOUTSRC_AGG_CHK_WINDOW_IN_MS 8000 + +BTC_COEXIST GLBtCoexist; +u8 GLBtcWiFiInScanState; +u8 GLBtcWiFiInIQKState; +u8 GLBtcWiFiInIPS; +u8 GLBtcWiFiInLPS; +u8 GLBtcBtCoexAliveRegistered; + +/* + * BT control H2C/C2H + */ +/* EXT_EID */ +typedef enum _bt_ext_eid { + C2H_WIFI_FW_ACTIVE_RSP = 0, + C2H_TRIG_BY_BT_FW +} BT_EXT_EID; + +/* C2H_STATUS */ +typedef enum _bt_c2h_status { + BT_STATUS_OK = 0, + BT_STATUS_VERSION_MISMATCH, + BT_STATUS_UNKNOWN_OPCODE, + BT_STATUS_ERROR_PARAMETER +} BT_C2H_STATUS; + +/* C2H BT OP CODES */ +typedef enum _bt_op_code { + BT_OP_GET_BT_VERSION = 0, + BT_OP_WRITE_REG_ADDR = 12, + BT_OP_WRITE_REG_VALUE, + BT_OP_READ_REG = 17 +} BT_OP_CODE; + +#define BTC_MPOPER_TIMEOUT 50 /* unit: ms */ + +#define C2H_MAX_SIZE 16 +u8 GLBtcBtMpOperSeq; +_mutex GLBtcBtMpOperLock; +_timer GLBtcBtMpOperTimer; +_sema GLBtcBtMpRptSema; +u8 GLBtcBtMpRptSeq; +u8 GLBtcBtMpRptStatus; +u8 GLBtcBtMpRptRsp[C2H_MAX_SIZE]; +u8 GLBtcBtMpRptRspSize; +u8 GLBtcBtMpRptWait; +u8 GLBtcBtMpRptWiFiOK; +u8 GLBtcBtMpRptBTOK; + +/* + * Debug + */ +u32 GLBtcDbgType[COMP_MAX]; +u8 GLBtcDbgBuf[BT_TMP_BUF_SIZE]; + +typedef struct _btcoexdbginfo +{ + u8 *info; + u32 size; // buffer total size + u32 len; // now used length +} BTCDBGINFO, *PBTCDBGINFO; + +BTCDBGINFO GLBtcDbgInfo; + +#define BT_Operation(Adapter) _FALSE + +static void DBG_BT_INFO_INIT(PBTCDBGINFO pinfo, u8 *pbuf, u32 size) +{ + if (NULL == pinfo) return; + + _rtw_memset(pinfo, 0, sizeof(BTCDBGINFO)); + + if (pbuf && size) { + pinfo->info = pbuf; + pinfo->size = size; + } +} + +void DBG_BT_INFO(u8 *dbgmsg) +{ + PBTCDBGINFO pinfo; + u32 msglen, buflen; + u8 *pbuf; + + + pinfo = &GLBtcDbgInfo; + + if (NULL == pinfo->info) + return; + + msglen = strlen(dbgmsg); + if (pinfo->len + msglen > pinfo->size) + return; + + pbuf = pinfo->info + pinfo->len; + _rtw_memcpy(pbuf, dbgmsg, msglen); + pinfo->len += msglen; +} + +//==================================== +// Debug related function +//==================================== +static u8 halbtcoutsrc_IsBtCoexistAvailable(PBTC_COEXIST pBtCoexist) +{ + if (!pBtCoexist->bBinded || + NULL == pBtCoexist->Adapter) + { + return _FALSE; + } + return _TRUE; +} + +static void halbtcoutsrc_DbgInit(void) +{ + u8 i; + + for (i = 0; i < COMP_MAX; i++) + GLBtcDbgType[i] = 0; +} + +static u8 halbtcoutsrc_IsCsrBtCoex(PBTC_COEXIST pBtCoexist) +{ + if (pBtCoexist->boardInfo.btChipType == BTC_CHIP_CSR_BC4 + || pBtCoexist->boardInfo.btChipType == BTC_CHIP_CSR_BC8 + ){ + return _TRUE; + } + return _FALSE; +} + +static u8 halbtcoutsrc_IsHwMailboxExist(PBTC_COEXIST pBtCoexist) +{ + if (pBtCoexist->boardInfo.btChipType == BTC_CHIP_CSR_BC4 + || pBtCoexist->boardInfo.btChipType == BTC_CHIP_CSR_BC8 + ){ + return _FALSE; + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + return _FALSE; + } + else + return _TRUE; +} + +static void halbtcoutsrc_LeaveLps(PBTC_COEXIST pBtCoexist) +{ + PADAPTER padapter; + + + padapter = pBtCoexist->Adapter; + + pBtCoexist->btInfo.bBtCtrlLps = _TRUE; + pBtCoexist->btInfo.bBtLpsOn = _FALSE; + + rtw_btcoex_LPS_Leave(padapter); +} + +void halbtcoutsrc_EnterLps(PBTC_COEXIST pBtCoexist) +{ + PADAPTER padapter; + + + padapter = pBtCoexist->Adapter; + + pBtCoexist->btInfo.bBtCtrlLps = _TRUE; + pBtCoexist->btInfo.bBtLpsOn = _TRUE; + + rtw_btcoex_LPS_Enter(padapter); +} + +void halbtcoutsrc_NormalLps(PBTC_COEXIST pBtCoexist) +{ + PADAPTER padapter; + + + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Normal LPS behavior!!!\n")); + + padapter = pBtCoexist->Adapter; + + if (pBtCoexist->btInfo.bBtCtrlLps) + { + pBtCoexist->btInfo.bBtLpsOn = _FALSE; + rtw_btcoex_LPS_Leave(padapter); + pBtCoexist->btInfo.bBtCtrlLps = _FALSE; + + // recover the LPS state to the original +#if 0 + padapter->HalFunc.UpdateLPSStatusHandler( + padapter, + pPSC->RegLeisurePsMode, + pPSC->RegPowerSaveMode); +#endif + } +} + +/* + * Constraint: + * 1. this function will request pwrctrl->lock + */ +void halbtcoutsrc_LeaveLowPower(PBTC_COEXIST pBtCoexist) +{ +#ifdef CONFIG_LPS_LCLK + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + struct pwrctrl_priv *pwrctrl; + s32 ready; + u32 stime; + s32 utime; + u32 timeout; // unit: ms + + + padapter = pBtCoexist->Adapter; + pHalData = GET_HAL_DATA(padapter); + pwrctrl = adapter_to_pwrctl(padapter); + ready = _FAIL; +#ifdef LPS_RPWM_WAIT_MS + timeout = LPS_RPWM_WAIT_MS; +#else // !LPS_RPWM_WAIT_MS + 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); + if (_SUCCESS == ready) + break; + + utime = rtw_get_passing_time_ms(stime); + if (utime > timeout) + break; + + rtw_msleep_os(1); + } while (1); + + GLBtcBtCoexAliveRegistered = _TRUE; +#endif // CONFIG_LPS_LCLK +} + +/* + * Constraint: + * 1. this function will request pwrctrl->lock + */ +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 +} + +void halbtcoutsrc_DisableLowPower(PBTC_COEXIST pBtCoexist, u8 bLowPwrDisable) +{ + pBtCoexist->btInfo.bBtDisableLowPwr = bLowPwrDisable; + if (bLowPwrDisable) + halbtcoutsrc_LeaveLowPower(pBtCoexist); // leave 32k low power. + else + halbtcoutsrc_NormalLowPower(pBtCoexist); // original 32k low power behavior. +} + +void halbtcoutsrc_AggregationCheck(PBTC_COEXIST pBtCoexist) +{ + PADAPTER padapter; + BOOLEAN bNeedToAct = _FALSE; + static u32 preTime = 0; + u32 curTime = 0; + + padapter = pBtCoexist->Adapter; + + //===================================== + // 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) + { + bNeedToAct = _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) + { + bNeedToAct = _TRUE; + pBtCoexist->btInfo.bPreBtCtrlAggBufSize = pBtCoexist->btInfo.bBtCtrlAggBufSize; + } + + if (pBtCoexist->btInfo.bBtCtrlAggBufSize) + { + if (pBtCoexist->btInfo.preAggBufSize != + pBtCoexist->btInfo.aggBufSize) + { + bNeedToAct = _TRUE; + } + pBtCoexist->btInfo.preAggBufSize = pBtCoexist->btInfo.aggBufSize; + } + } + + if (bNeedToAct) + rtw_btcoex_rx_ampdu_apply(padapter); +} + +u8 halbtcoutsrc_IsWifiBusy(PADAPTER padapter) +{ + struct mlme_priv *pmlmepriv; + + + pmlmepriv = &padapter->mlmepriv; + + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) + { + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return _TRUE; + if (_TRUE == pmlmepriv->LinkDetectInfo.bBusyTraffic) + return _TRUE; + } + +#if defined(CONFIG_CONCURRENT_MODE) + pmlmepriv = &padapter->pbuddy_adapter->mlmepriv; + + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) + { + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return _TRUE; + if (_TRUE == pmlmepriv->LinkDetectInfo.bBusyTraffic) + return _TRUE; + } +#endif + + return _FALSE; +} + +static u32 _halbtcoutsrc_GetWifiLinkStatus(PADAPTER padapter) +{ + struct mlme_priv *pmlmepriv; + u8 bp2p; + u32 portConnectedStatus; + + + pmlmepriv = &padapter->mlmepriv; + bp2p = _FALSE; + portConnectedStatus = 0; + +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) + bp2p = _TRUE; +#endif // CONFIG_P2P + + if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) + { + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + if (_TRUE == bp2p) + portConnectedStatus |= WIFI_P2P_GO_CONNECTED; + else + portConnectedStatus |= WIFI_AP_CONNECTED; + } + else + { + if (_TRUE == bp2p) + portConnectedStatus |= WIFI_P2P_GC_CONNECTED; + else + portConnectedStatus |= WIFI_STA_CONNECTED; + } + } + + return portConnectedStatus; +} + +u32 halbtcoutsrc_GetWifiLinkStatus(PBTC_COEXIST pBtCoexist) +{ + //================================= + // return value: + // [31:16]=> connected port number + // [15:0]=> port connected bit define + //================================ + + PADAPTER padapter; + u32 retVal; + u32 portConnectedStatus, numOfConnectedPort; + + + padapter = pBtCoexist->Adapter; + retVal = 0; + portConnectedStatus = 0; + numOfConnectedPort = 0; + + retVal = _halbtcoutsrc_GetWifiLinkStatus(padapter); + if (retVal) + { + portConnectedStatus |= retVal; + numOfConnectedPort++; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) + { + retVal = _halbtcoutsrc_GetWifiLinkStatus(padapter->pbuddy_adapter); + if (retVal) + { + portConnectedStatus |= retVal; + numOfConnectedPort++; + } + } +#endif // CONFIG_CONCURRENT_MODE + + retVal = (numOfConnectedPort << 16) | portConnectedStatus; + + return retVal; +} + +static u8 _is_btfwver_valid(PBTC_COEXIST pBtCoexist, u16 btfwver) +{ + if (!btfwver) + return _FALSE; + + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + if (btfwver == 0x8723) + return _FALSE; + + return _TRUE; +} + +static void _btmpoper_timer_hdl(void *p) +{ + if (GLBtcBtMpRptWait) { + GLBtcBtMpRptWait = 0; + _rtw_up_sema(&GLBtcBtMpRptSema); + } +} + +/* + * !IMPORTANT! + * Before call this function, caller should acquire "GLBtcBtMpOperLock"! + * Othrewise there will be racing problem and something may go wrong. + */ +static u8 _btmpoper_cmd(PBTC_COEXIST pBtCoexist, u8 opcode, u8 opcodever, u8 *cmd, u8 size) +{ + PADAPTER padapter; + u8 buf[H2C_BTMP_OPER_LEN] = {0}; + u8 buflen; + u8 seq; + u8 timer_cancelled; + s32 ret; + + + if (!cmd && size) + size = 0; + if ((size + 2) > H2C_BTMP_OPER_LEN) + return BT_STATUS_H2C_LENGTH_EXCEEDED; + buflen = size + 2; + + seq = GLBtcBtMpOperSeq & 0xF; + GLBtcBtMpOperSeq++; + + buf[0] = (opcodever & 0xF) | (seq << 4); + buf[1] = opcode; + if (cmd && size) + _rtw_memcpy(buf+2, cmd, size); + + GLBtcBtMpRptWait = 1; + GLBtcBtMpRptWiFiOK = 0; + GLBtcBtMpRptBTOK = 0; + GLBtcBtMpRptStatus = 0; + padapter = pBtCoexist->Adapter; + _set_timer(&GLBtcBtMpOperTimer, BTC_MPOPER_TIMEOUT); + if (rtw_hal_fill_h2c_cmd(padapter, H2C_BT_MP_OPER, buflen, buf) == _FAIL) { + _cancel_timer(&GLBtcBtMpOperTimer, &timer_cancelled); + ret = BT_STATUS_H2C_FAIL; + goto exit; + } + + _rtw_down_sema(&GLBtcBtMpRptSema); + /* GLBtcBtMpRptWait should be 0 here*/ + + if (!GLBtcBtMpRptWiFiOK) { + DBG_871X("%s: Didn't get H2C Rsp Event!\n", __FUNCTION__); + ret = BT_STATUS_H2C_TIMTOUT; + goto exit; + } + if (!GLBtcBtMpRptBTOK) { + DBG_871X("%s: Didn't get BT response!\n", __FUNCTION__); + ret = BT_STATUS_H2C_BT_NO_RSP; + goto exit; + } + if (seq != GLBtcBtMpRptSeq) { + DBG_871X("%s: Sequence number not match!(%d!=%d)!\n", + __FUNCTION__, seq, GLBtcBtMpRptSeq); + ret = BT_STATUS_C2H_REQNUM_MISMATCH; + goto exit; + } + + switch (GLBtcBtMpRptStatus) { + /* Examine the status reported from C2H */ + case BT_STATUS_OK: + ret = BT_STATUS_BT_OP_SUCCESS; + DBG_871X("%s: C2H status = BT_STATUS_BT_OP_SUCCESS\n", __FUNCTION__); + break; + case BT_STATUS_VERSION_MISMATCH: + ret = BT_STATUS_OPCODE_L_VERSION_MISMATCH; + DBG_871X("%s: C2H status = BT_STATUS_OPCODE_L_VERSION_MISMATCH\n", __FUNCTION__); + break; + case BT_STATUS_UNKNOWN_OPCODE: + ret = BT_STATUS_UNKNOWN_OPCODE_L; + DBG_871X("%s: C2H status = MP_BT_STATUS_UNKNOWN_OPCODE_L\n", __FUNCTION__); + break; + case BT_STATUS_ERROR_PARAMETER: + ret = BT_STATUS_PARAMETER_FORMAT_ERROR_L; + DBG_871X("%s: C2H status = MP_BT_STATUS_PARAMETER_FORMAT_ERROR_L\n", __FUNCTION__); + break; + default: + ret = BT_STATUS_UNKNOWN_STATUS_L; + DBG_871X("%s: C2H status = MP_BT_STATUS_UNKNOWN_STATUS_L\n", __FUNCTION__); + break; + } + +exit: + return ret; +} + +u32 halbtcoutsrc_GetBtPatchVer(PBTC_COEXIST pBtCoexist) +{ + if (_is_btfwver_valid(pBtCoexist, pBtCoexist->btInfo.btRealFwVer) == _TRUE) + goto exit; + + if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) { + _irqL irqL; + u8 ret; + + + _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL); + + ret = _btmpoper_cmd(pBtCoexist, BT_OP_GET_BT_VERSION, 0, NULL, 0); + if (BT_STATUS_BT_OP_SUCCESS == ret) { + pBtCoexist->btInfo.btRealFwVer = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp); + pBtCoexist->btInfo.btFwVer = *(GLBtcBtMpRptRsp+2); + } + pBtCoexist->btInfo.getBtFwVerCnt++; + + _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL); + } else { +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + u1Byte dataLen = 2; + u1Byte buf[4] = {0}; + + buf[0] = 0x0; /* OP_Code */ + buf[1] = 0x0; /* OP_Code_Length */ + BT_SendEventExtBtCoexControl(pBtCoexist->Adapter, _FALSE, dataLen, &buf[0]); +#endif /* !CONFIG_BT_COEXIST_SOCKET_TRX */ + } + +exit: + return pBtCoexist->btInfo.btRealFwVer; +} + +s32 halbtcoutsrc_GetWifiRssi(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + s32 UndecoratedSmoothedPWDB = 0; + + pHalData = GET_HAL_DATA(padapter); + + UndecoratedSmoothedPWDB = pHalData->EntryMinUndecoratedSmoothedPWDB; + + return UndecoratedSmoothedPWDB; +} + +static u8 halbtcoutsrc_GetWifiScanAPNum(PADAPTER padapter) +{ + struct mlme_priv *pmlmepriv; + struct mlme_ext_priv *pmlmeext; + static u8 scan_AP_num = 0; + + + pmlmepriv = &padapter->mlmepriv; + pmlmeext = &padapter->mlmeextpriv; + + if (GLBtcWiFiInScanState == _FALSE) { + if (pmlmepriv->num_of_scanned > 0xFF) + scan_AP_num = 0xFF; + else + scan_AP_num = (u8)pmlmepriv->num_of_scanned; + } + + return scan_AP_num; +} + +u8 halbtcoutsrc_Get(void *pBtcContext, u8 getType, void *pOutBuf) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + struct mlme_ext_priv *mlmeext; + u8 bSoftApExist, bVwifiExist; + u8 *pu8; + s32 *pS4Tmp; + u32 *pU4Tmp; + u8 *pU1Tmp; + u8 ret; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return _FALSE; + + padapter = pBtCoexist->Adapter; + pHalData = GET_HAL_DATA(padapter); + mlmeext = &padapter->mlmeextpriv; + bSoftApExist = _FALSE; + bVwifiExist = _FALSE; + pu8 = (u8*)pOutBuf; + pS4Tmp = (s32*)pOutBuf; + pU4Tmp = (u32*)pOutBuf; + pU1Tmp = (u8*)pOutBuf; + ret = _TRUE; + + switch (getType) + { + case BTC_GET_BL_HS_OPERATION: + *pu8 = _FALSE; + ret = _FALSE; + break; + + case BTC_GET_BL_HS_CONNECTING: + *pu8 = _FALSE; + ret = _FALSE; + break; + + case BTC_GET_BL_WIFI_CONNECTED: + *pu8 = check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE); +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == *pu8) && padapter->pbuddy_adapter) + { + *pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_ASOC_STATE); + } +#endif // CONFIG_CONCURRENT_MODE + break; + + case BTC_GET_BL_WIFI_BUSY: + *pu8 = halbtcoutsrc_IsWifiBusy(padapter); + break; + + case BTC_GET_BL_WIFI_SCAN: +#if 0 + *pu8 = check_fwstate(&padapter->mlmepriv, WIFI_SITE_MONITOR); +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == *pu8) && padapter->pbuddy_adapter) + { + *pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_SITE_MONITOR); + } +#endif // CONFIG_CONCURRENT_MODE +#else + /* Use the value of the new variable GLBtcWiFiInScanState to judge whether WiFi is in scan state or not, since the originally used flag + WIFI_SITE_MONITOR in fwstate may not be cleared in time */ + *pu8 = GLBtcWiFiInScanState; +#endif + break; + + case BTC_GET_BL_WIFI_LINK: + *pu8 = check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING); +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == *pu8) && padapter->pbuddy_adapter) + { + *pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_UNDER_LINKING); + } +#endif // CONFIG_CONCURRENT_MODE + break; + + case BTC_GET_BL_WIFI_ROAM: + *pu8 = check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING); +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == *pu8) && padapter->pbuddy_adapter) + { + *pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_UNDER_LINKING); + } +#endif // CONFIG_CONCURRENT_MODE + break; + + case BTC_GET_BL_WIFI_4_WAY_PROGRESS: + *pu8 = _FALSE; + break; + + case BTC_GET_BL_WIFI_UNDER_5G: + *pu8 = (pHalData->CurrentBandType == 1)? _TRUE : _FALSE; + break; + + case BTC_GET_BL_WIFI_AP_MODE_ENABLE: + *pu8 = check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE); +#ifdef CONFIG_CONCURRENT_MODE + if ((_FALSE == *pu8) && padapter->pbuddy_adapter) + { + *pu8 = check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE); + } +#endif // CONFIG_CONCURRENT_MODE + break; + + case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION: + *pu8 = padapter->securitypriv.dot11PrivacyAlgrthm == 0? _FALSE: _TRUE; + break; + + case BTC_GET_BL_WIFI_UNDER_B_MODE: + if (mlmeext->cur_wireless_mode == WIRELESS_11B) + *pu8 = _TRUE; + else + *pu8 = _FALSE; + break; + + case BTC_GET_BL_WIFI_IS_IN_MP_MODE: + if (padapter->registrypriv.mp_mode == 0) + { + *pu8 = _FALSE; + } + else + { + *pu8 = _TRUE; + } + break; + + 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); + break; + + case BTC_GET_S4_HS_RSSI: + *pS4Tmp = 0; + ret = _FALSE; + break; + + case BTC_GET_U4_WIFI_BW: + if (IsLegacyOnly(mlmeext->cur_wireless_mode)) + *pU4Tmp = BTC_WIFI_BW_LEGACY; + else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_20) + *pU4Tmp = BTC_WIFI_BW_HT20; + else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) + *pU4Tmp = BTC_WIFI_BW_HT40; + else + *pU4Tmp = BTC_WIFI_BW_HT40; /* todo */ + break; + + case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: + { + PRT_LINK_DETECT_T plinkinfo; + plinkinfo = &padapter->mlmepriv.LinkDetectInfo; + + if (plinkinfo->NumTxOkInPeriod > plinkinfo->NumRxOkInPeriod) + *pU4Tmp = BTC_WIFI_TRAFFIC_TX; + else + *pU4Tmp = BTC_WIFI_TRAFFIC_RX; + } + break; + + case BTC_GET_U4_WIFI_FW_VER: + *pU4Tmp = pHalData->FirmwareVersion << 16; + *pU4Tmp |= pHalData->FirmwareSubVersion; + break; + + case BTC_GET_U4_WIFI_LINK_STATUS: + *pU4Tmp = halbtcoutsrc_GetWifiLinkStatus(pBtCoexist); + break; + + case BTC_GET_U4_BT_PATCH_VER: + *pU4Tmp = halbtcoutsrc_GetBtPatchVer(pBtCoexist); + break; + + case BTC_GET_U1_WIFI_DOT11_CHNL: + *pU1Tmp = padapter->mlmeextpriv.cur_channel; + break; + + case BTC_GET_U1_WIFI_CENTRAL_CHNL: + *pU1Tmp = pHalData->CurrentChannel; + break; + + case BTC_GET_U1_WIFI_HS_CHNL: + *pU1Tmp = 0; + ret = _FALSE; + break; + + case BTC_GET_U1_MAC_PHY_MODE: +// *pU1Tmp = BTC_SMSP; +// *pU1Tmp = BTC_DMSP; +// *pU1Tmp = BTC_DMDP; +// *pU1Tmp = BTC_MP_UNKNOWN; + break; + + case BTC_GET_U1_AP_NUM: + *pU1Tmp = halbtcoutsrc_GetWifiScanAPNum(padapter); + break; + case BTC_GET_U1_ANT_TYPE: + switch(pHalData->bt_coexist.btAntisolation) + { + case 0: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_0; + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_0; + break; + case 1: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_1; + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_1; + break; + case 2: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_2; + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_2; + break; + case 3: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_3; + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_3; + break; + case 4: + *pU1Tmp = (u1Byte)BTC_ANT_TYPE_4; + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_4; + break; + } + break; + case BTC_GET_U1_IOT_PEER: + *pU1Tmp = mlmeext->mlmext_info.assoc_AP_vendor; + break; + + //=======1Ant=========== + case BTC_GET_U1_LPS_MODE: + *pU1Tmp = padapter->dvobj->pwrctl_priv.pwr_mode; + break; + + default: + ret = _FALSE; + break; + } + + return ret; +} + +u8 halbtcoutsrc_Set(void *pBtcContext, u8 setType, void *pInBuf) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + u8 *pu8; + u8 *pU1Tmp; + u32 *pU4Tmp; + u8 ret; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + pHalData = GET_HAL_DATA(padapter); + pu8 = (u8*)pInBuf; + pU1Tmp = (u8*)pInBuf; + pU4Tmp = (u32*)pInBuf; + ret = _TRUE; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return _FALSE; + + switch (setType) + { + // set some u8 type variables. + case BTC_SET_BL_BT_DISABLE: + pBtCoexist->btInfo.bBtDisabled = *pu8; + break; + + case BTC_SET_BL_BT_TRAFFIC_BUSY: + pBtCoexist->btInfo.bBtBusy = *pu8; + break; + + case BTC_SET_BL_BT_LIMITED_DIG: + pBtCoexist->btInfo.bLimitedDig = *pu8; + break; + + case BTC_SET_BL_FORCE_TO_ROAM: + pBtCoexist->btInfo.bForceToRoam = *pu8; + break; + + case BTC_SET_BL_TO_REJ_AP_AGG_PKT: + pBtCoexist->btInfo.bRejectAggPkt = *pu8; + break; + + case BTC_SET_BL_BT_CTRL_AGG_SIZE: + pBtCoexist->btInfo.bBtCtrlAggBufSize = *pu8; + break; + + case BTC_SET_BL_INC_SCAN_DEV_NUM: + pBtCoexist->btInfo.bIncreaseScanDevNum = *pu8; + break; + + case BTC_SET_BL_BT_TX_RX_MASK: + pBtCoexist->btInfo.bBtTxRxMask = *pu8; + break; + + case BTC_SET_BL_MIRACAST_PLUS_BT: + pBtCoexist->btInfo.bMiracastPlusBt = *pu8; + break; + + // set some u8 type variables. + case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON: + pBtCoexist->btInfo.rssiAdjustForAgcTableOn = *pU1Tmp; + break; + + case BTC_SET_U1_AGG_BUF_SIZE: + pBtCoexist->btInfo.aggBufSize = *pU1Tmp; + break; + + // the following are some action which will be triggered + case BTC_SET_ACT_GET_BT_RSSI: +#if 0 + BT_SendGetBtRssiEvent(padapter); +#else + ret = _FALSE; +#endif + break; + + case BTC_SET_ACT_AGGREGATE_CTRL: + halbtcoutsrc_AggregationCheck(pBtCoexist); + break; + + //=======1Ant=========== + // set some u8 type variables. + case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE: + pBtCoexist->btInfo.rssiAdjustFor1AntCoexType = *pU1Tmp; + break; + + case BTC_SET_U1_LPS_VAL: + pBtCoexist->btInfo.lpsVal = *pU1Tmp; + break; + + case BTC_SET_U1_RPWM_VAL: + pBtCoexist->btInfo.rpwmVal = *pU1Tmp; + break; + + // the following are some action which will be triggered + case BTC_SET_ACT_LEAVE_LPS: + halbtcoutsrc_LeaveLps(pBtCoexist); + break; + + case BTC_SET_ACT_ENTER_LPS: + halbtcoutsrc_EnterLps(pBtCoexist); + break; + + case BTC_SET_ACT_NORMAL_LPS: + halbtcoutsrc_NormalLps(pBtCoexist); + break; + + case BTC_SET_ACT_DISABLE_LOW_POWER: + halbtcoutsrc_DisableLowPower(pBtCoexist, *pu8); + break; + + case BTC_SET_ACT_UPDATE_RAMASK: + pBtCoexist->btInfo.raMask = *pU4Tmp; + + if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) + { + struct sta_info *psta; + PWLAN_BSSID_EX cur_network; + + cur_network = &padapter->mlmeextpriv.mlmext_info.network; + psta = rtw_get_stainfo(&padapter->stapriv, cur_network->MacAddress); + rtw_hal_update_ra_mask(psta, 0); + } + break; + + case BTC_SET_ACT_SEND_MIMO_PS: + { + 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) { + /* 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); + } + } + break; + + case BTC_SET_ACT_CTRL_BT_INFO: +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + { + u8 dataLen = *pU1Tmp; + u8 tmpBuf[20]; + if (dataLen) + { + _rtw_memcpy(tmpBuf, pU1Tmp+1, dataLen); + } + BT_SendEventExtBtInfoControl(padapter, dataLen, &tmpBuf[0]); + } +#else //!CONFIG_BT_COEXIST_SOCKET_TRX + ret = _FALSE; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + break; + + case BTC_SET_ACT_CTRL_BT_COEX: +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + { + u8 dataLen = *pU1Tmp; + u8 tmpBuf[20]; + if (dataLen) + { + _rtw_memcpy(tmpBuf, pU1Tmp+1, dataLen); + } + BT_SendEventExtBtCoexControl(padapter, _FALSE, dataLen, &tmpBuf[0]); + } +#else //!CONFIG_BT_COEXIST_SOCKET_TRX + ret = _FALSE; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + break; + case BTC_SET_ACT_CTRL_8723B_ANT: +#if 0 + { + u1Byte dataLen=*pU1Tmp; + u1Byte tmpBuf[20]; + if(dataLen) + { + PlatformMoveMemory(&tmpBuf[0], pU1Tmp+1, dataLen); + } + BT_Set8723bAnt(Adapter, dataLen, &tmpBuf[0]); + } +#else + ret = _FALSE; +#endif + break; + //===================== + default: + ret = _FALSE; + break; + } + + 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 + PADAPTER padapter = (PADAPTER)pBtCoexist->Adapter; + PBT_MGNT pBtMgnt = &padapter->MgntInfo.BtInfo.BtMgnt; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8 *cliBuf = pBtCoexist->cliBuf; + u8 i; + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Statistics]============"); + CL_PRINTF(cliBuf); + +#if (H2C_USE_IO_THREAD != 1) + for(i=0; ih2cStatistics[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s] = %d", "H2C statistics", \ + h2cStaString[i], pHalData->h2cStatistics[i]); + CL_PRINTF(cliBuf); + } + } +#else + for(i=0; iioComStr.ioH2cStatistics[i]) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s] = %d", "H2C statistics", \ + ioStaString[i], Adapter->ioComStr.ioH2cStatistics[i]); + CL_PRINTF(cliBuf); + } + } +#endif +#if 0 + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \ + pHalData->LastHMEBoxNum); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "LastOkH2c/FirstFailH2c(fwNotRead)", \ + pHalData->lastSuccessH2cEid, pHalData->firstFailedH2cEid); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "c2hIsr/c2hIntr/clr1AF/noRdy/noBuf", \ + pHalData->InterruptLog.nIMR_C2HCMD, DBG_Var.c2hInterruptCnt, DBG_Var.c2hClrReadC2hCnt, + DBG_Var.c2hNotReadyCnt, DBG_Var.c2hBufAlloFailCnt); + CL_PRINTF(cliBuf); + + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "c2hPacket", \ + DBG_Var.c2hPacketCnt); + CL_PRINTF(cliBuf); +#endif + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Periodical/ DbgCtrl", \ + pBtCoexist->statistics.cntPeriodical, pBtCoexist->statistics.cntDbgCtrl); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d", "PowerOn/InitHw/InitCoexDm/RfStatus", \ + pBtCoexist->statistics.cntPowerOn, pBtCoexist->statistics.cntInitHwConfig, pBtCoexist->statistics.cntInitCoexDm, + pBtCoexist->statistics.cntRfStatusNotify); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", "Ips/Lps/Scan/Connect/Mstatus", \ + pBtCoexist->statistics.cntIpsNotify, pBtCoexist->statistics.cntLpsNotify, + pBtCoexist->statistics.cntScanNotify, pBtCoexist->statistics.cntConnectNotify, + pBtCoexist->statistics.cntMediaStatusNotify); + CL_PRINTF(cliBuf); + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "Special pkt/Bt info/ bind", + pBtCoexist->statistics.cntSpecialPacketNotify, pBtCoexist->statistics.cntBtInfoNotify, + pBtCoexist->statistics.cntBind); + CL_PRINTF(cliBuf); +#endif +} + +void halbtcoutsrc_DisplayBtLinkInfo(PBTC_COEXIST pBtCoexist) +{ +#if 0 + PADAPTER padapter = (PADAPTER)pBtCoexist->Adapter; + PBT_MGNT pBtMgnt = &padapter->MgntInfo.BtInfo.BtMgnt; + u8 *cliBuf = pBtCoexist->cliBuf; + u8 i; + + + if (pBtCoexist->stackInfo.bProfileNotified) + { + for (i=0; iExtConfig.NumberOfACL; i++) + { + if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role", \ + BtProfileString[pBtMgnt->ExtConfig.aclLink[i].BTProfile], + BtSpecString[pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec], + BtLinkRoleString[pBtMgnt->ExtConfig.aclLink[i].linkRole]); + CL_PRINTF(cliBuf); } + else + { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \ + BtProfileString[pBtMgnt->ExtConfig.aclLink[i].BTProfile], + BtSpecString[pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec]); + CL_PRINTF(cliBuf); + } + } + } +#endif +} + +void halbtcoutsrc_DisplayWifiStatus(PBTC_COEXIST pBtCoexist) +{ + 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; + + 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); + + if (wifiLinkStatus&WIFI_STA_CONNECTED) { + CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "IOT Peer", GLBtcIotPeerString[padapter->mlmeextpriv.mlmext_info.assoc_AP_vendor]); + 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->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 +//==================================== +u8 halbtcoutsrc_Read1Byte(void *pBtcContext, u32 RegAddr) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + return rtw_read8(padapter, RegAddr); +} + +u16 halbtcoutsrc_Read2Byte(void *pBtcContext, u32 RegAddr) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + return rtw_read16(padapter, RegAddr); +} + +u32 halbtcoutsrc_Read4Byte(void *pBtcContext, u32 RegAddr) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + return rtw_read32(padapter, RegAddr); +} + +void halbtcoutsrc_Write1Byte(void *pBtcContext, u32 RegAddr, u8 Data) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + rtw_write8(padapter, RegAddr, Data); +} + +void halbtcoutsrc_BitMaskWrite1Byte(void *pBtcContext, u32 regAddr, u8 bitMask, u8 data1b) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + u8 originalValue, bitShift; + u8 i; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + originalValue = 0; + bitShift = 0; + + if(bitMask != 0xff) + { + originalValue = rtw_read8(padapter, regAddr); + + for (i=0; i<=7; i++) + { + if ((bitMask>>i)&0x1) + break; + } + bitShift = i; + + data1b = (originalValue & ~bitMask) | ((data1b << bitShift) & bitMask); + } + + rtw_write8(padapter, regAddr, data1b); +} + +void halbtcoutsrc_Write2Byte(void *pBtcContext, u32 RegAddr, u16 Data) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + rtw_write16(padapter, RegAddr, Data); +} + +void halbtcoutsrc_Write4Byte(void *pBtcContext, u32 RegAddr, u32 Data) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + rtw_write32(padapter, RegAddr, Data); +} + +void halbtcoutsrc_WriteLocalReg1Byte(void *pBtcContext, u32 RegAddr, u8 Data) +{ + PBTC_COEXIST pBtCoexist=(PBTC_COEXIST)pBtcContext; + PADAPTER Adapter=pBtCoexist->Adapter; + + if(BTC_INTF_SDIO == pBtCoexist->chipInterface) + { + rtw_write8(Adapter, SDIO_LOCAL_BASE | RegAddr, Data); + } + else + { + rtw_write8(Adapter, RegAddr, Data); + } +} + +void halbtcoutsrc_SetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask, u32 Data) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + PHY_SetBBReg(padapter, RegAddr, BitMask, Data); +} + + +u32 halbtcoutsrc_GetBbReg(void *pBtcContext, u32 RegAddr, u32 BitMask) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + return PHY_QueryBBReg(padapter, RegAddr, BitMask); +} + +void halbtcoutsrc_SetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + PHY_SetRFReg(padapter, eRFPath, RegAddr, BitMask, Data); +} + +u32 halbtcoutsrc_GetRfReg(void *pBtcContext, u8 eRFPath, u32 RegAddr, u32 BitMask) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + return PHY_QueryRFReg(padapter, eRFPath, RegAddr, BitMask); +} + +u16 halbtcoutsrc_SetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr, u32 Data) +{ + PBTC_COEXIST pBtCoexist; + u16 ret = BT_STATUS_BT_OP_SUCCESS; + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + + if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) { + u8 buf[3] = {0}; + _irqL irqL; + u8 op_code; + u8 status; + + _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL); + + Data = cpu_to_le32(Data); + op_code = BT_OP_WRITE_REG_VALUE; + status = _btmpoper_cmd(pBtCoexist, op_code, 0, (u8 *)&Data, 3); + if (status != BT_STATUS_BT_OP_SUCCESS) + ret = SET_BT_MP_OPER_RET(op_code, status); + else { + buf[0] = RegType; + *(u16 *)(buf+1) = cpu_to_le16((u16)RegAddr); + op_code = BT_OP_WRITE_REG_ADDR; + status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3); + if (status != BT_STATUS_BT_OP_SUCCESS) + ret = SET_BT_MP_OPER_RET(op_code, status); + } + + _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL); + } else + ret = BT_STATUS_NOT_IMPLEMENT; + + return ret; +} + +u8 halbtcoutsrc_SetBtAntDetection(void *pBtcContext, u8 txTime, u8 btChnl) +{ +/* Always return _FALSE since we don't implement this yet */ +#if 0 + PBTC_COEXIST pBtCoexist = (PBTC_COEXIST)pBtcContext; + PADAPTER Adapter = pBtCoexist->Adapter; + u1Byte btCanTx = 0; + BOOLEAN bStatus = FALSE; + + bStatus = NDBG_SetBtAntDetection(Adapter, txTime, btChnl, &btCanTx); + if (bStatus && btCanTx) + return _TRUE; + else + return _FALSE; +#else + return _FALSE; +#endif +} + +u16 halbtcoutsrc_GetBtReg(void *pBtcContext, u8 RegType, u32 RegAddr, u32 *data) +{ + PBTC_COEXIST pBtCoexist; + u16 ret = BT_STATUS_BT_OP_SUCCESS; + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + + if (halbtcoutsrc_IsHwMailboxExist(pBtCoexist) == _TRUE) { + u8 buf[3] = {0}; + _irqL irqL; + u8 op_code; + u8 status; + + buf[0] = RegType; + *(u16 *)(buf+1) = cpu_to_le16((u16)RegAddr); + + _enter_critical_mutex(&GLBtcBtMpOperLock, &irqL); + + op_code = BT_OP_READ_REG; + status = _btmpoper_cmd(pBtCoexist, op_code, 0, buf, 3); + if (status == BT_STATUS_BT_OP_SUCCESS) + *data = le16_to_cpu(*(u16 *)GLBtcBtMpRptRsp); + else + ret = SET_BT_MP_OPER_RET(op_code, status); + + _exit_critical_mutex(&GLBtcBtMpOperLock, &irqL); + + } else + ret = BT_STATUS_NOT_IMPLEMENT; + + return ret; +} + +void halbtcoutsrc_FillH2cCmd(void *pBtcContext, u8 elementId, u32 cmdLen, u8 *pCmdBuffer) +{ + PBTC_COEXIST pBtCoexist; + PADAPTER padapter; + + + pBtCoexist = (PBTC_COEXIST)pBtcContext; + padapter = pBtCoexist->Adapter; + + rtw_hal_fill_h2c_cmd(padapter, elementId, cmdLen, pCmdBuffer); +} + +//==================================== +// Extern functions called by other module +//==================================== +u8 EXhalbtcoutsrc_IsTfbgaPackageType(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + +#ifdef CONFIG_RTL8723B + if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80) + || (pHalData->PackageType == PACKAGE_TFBGA90)) { + return _TRUE; + } +#endif + + return _FALSE; +} + +u8 EXhalbtcoutsrc_BindBtCoexWithAdapter(void *padapter) +{ + PBTC_COEXIST pBtCoexist=&GLBtCoexist; + u1Byte antNum=2, chipType; + + if(pBtCoexist->bBinded) + return _FALSE; + else + pBtCoexist->bBinded = _TRUE; + + pBtCoexist->statistics.cntBind++; + + pBtCoexist->Adapter = padapter; + + pBtCoexist->stackInfo.bProfileNotified = _FALSE; + + pBtCoexist->btInfo.bBtCtrlAggBufSize = _FALSE; + pBtCoexist->btInfo.aggBufSize = 5; + + pBtCoexist->btInfo.bIncreaseScanDevNum = _FALSE; + pBtCoexist->btInfo.bMiracastPlusBt = _FALSE; + +#if 0 + chipType = HALBT_GetBtChipType(Adapter); + EXhalbtcoutsrc_SetChipType(chipType); + antNum = HALBT_GetPgAntNum(Adapter); + EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_PG, antNum); +#endif + // set default antenna position to main port + pBtCoexist->boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + + pBtCoexist->boardInfo.btdmAntDetFinish = _FALSE; + pBtCoexist->boardInfo.btdmAntNumByAntDet = 1; + + pBtCoexist->boardInfo.bTfbgaPackage = EXhalbtcoutsrc_IsTfbgaPackageType((PADAPTER)padapter); + + if (pBtCoexist->boardInfo.bTfbgaPackage) + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Package Type = TFBGA\n")); + else + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], Package Type = Non-TFBGA\n")); + + return _TRUE; +} + +u8 EXhalbtcoutsrc_InitlizeVariables(void *padapter) +{ + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + + //pBtCoexist->statistics.cntBind++; + + halbtcoutsrc_DbgInit(); + +#ifdef CONFIG_PCI_HCI + pBtCoexist->chipInterface = BTC_INTF_PCI; +#elif defined(CONFIG_USB_HCI) + pBtCoexist->chipInterface = BTC_INTF_USB; +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + pBtCoexist->chipInterface = BTC_INTF_SDIO; +#else + pBtCoexist->chipInterface = BTC_INTF_UNKNOWN; +#endif + + EXhalbtcoutsrc_BindBtCoexWithAdapter(padapter); + + pBtCoexist->fBtcRead1Byte = halbtcoutsrc_Read1Byte; + pBtCoexist->fBtcWrite1Byte = halbtcoutsrc_Write1Byte; + pBtCoexist->fBtcWrite1ByteBitMask = halbtcoutsrc_BitMaskWrite1Byte; + pBtCoexist->fBtcRead2Byte = halbtcoutsrc_Read2Byte; + pBtCoexist->fBtcWrite2Byte = halbtcoutsrc_Write2Byte; + pBtCoexist->fBtcRead4Byte = halbtcoutsrc_Read4Byte; + pBtCoexist->fBtcWrite4Byte = halbtcoutsrc_Write4Byte; + pBtCoexist->fBtcWriteLocalReg1Byte = halbtcoutsrc_WriteLocalReg1Byte; + + pBtCoexist->fBtcSetBbReg = halbtcoutsrc_SetBbReg; + pBtCoexist->fBtcGetBbReg = halbtcoutsrc_GetBbReg; + + pBtCoexist->fBtcSetRfReg = halbtcoutsrc_SetRfReg; + pBtCoexist->fBtcGetRfReg = halbtcoutsrc_GetRfReg; + + pBtCoexist->fBtcFillH2c = halbtcoutsrc_FillH2cCmd; + pBtCoexist->fBtcDispDbgMsg = halbtcoutsrc_DisplayDbgMsg; + + pBtCoexist->fBtcGet = halbtcoutsrc_Get; + pBtCoexist->fBtcSet = halbtcoutsrc_Set; + pBtCoexist->fBtcGetBtReg = halbtcoutsrc_GetBtReg; + pBtCoexist->fBtcSetBtReg = halbtcoutsrc_SetBtReg; + pBtCoexist->fBtcSetBtAntDetection = halbtcoutsrc_SetBtAntDetection; + + pBtCoexist->cliBuf = &GLBtcDbgBuf[0]; + + pBtCoexist->boardInfo.singleAntPath = 0; + + GLBtcWiFiInScanState = _FALSE; + + GLBtcWiFiInIQKState = _FALSE; + + GLBtcWiFiInIPS = _FALSE; + + GLBtcWiFiInLPS = _FALSE; + + GLBtcBtCoexAliveRegistered = _FALSE; + + /* BT Control H2C/C2H*/ + GLBtcBtMpOperSeq = 0; + _rtw_mutex_init(&GLBtcBtMpOperLock); + _init_timer(&GLBtcBtMpOperTimer, ((PADAPTER)padapter)->pnetdev, _btmpoper_timer_hdl, pBtCoexist); + _rtw_init_sema(&GLBtcBtMpRptSema, 0); + GLBtcBtMpRptSeq = 0; + GLBtcBtMpRptStatus = 0; + _rtw_memset(GLBtcBtMpRptRsp, 0, C2H_MAX_SIZE); + GLBtcBtMpRptRspSize = 0; + GLBtcBtMpRptWait = 0; + GLBtcBtMpRptWiFiOK = 0; + GLBtcBtMpRptBTOK = 0; + + return _TRUE; +} + +void EXhalbtcoutsrc_PowerOnSetting(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + /* Power on setting function is only added in 8723B currently */ + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_PowerOnSetting(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_PowerOnSetting(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)) + return; + + pBtCoexist->statistics.cntInitHwConfig++; + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_InitHwConfig(pBtCoexist, bWifiOnly); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_InitHwConfig(pBtCoexist, bWifiOnly); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_InitHwConfig(pBtCoexist, bWifiOnly); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_InitHwConfig(pBtCoexist, bWifiOnly); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_InitHwConfig(pBtCoexist, bWifiOnly); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_InitHwConfig(pBtCoexist, bWifiOnly); + } +} + +void EXhalbtcoutsrc_InitCoexDm(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntInitCoexDm++; + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_InitCoexDm(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_InitCoexDm(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_InitCoexDm(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_InitCoexDm(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_InitCoexDm(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_InitCoexDm(pBtCoexist); + } + + pBtCoexist->bInitilized = _TRUE; +} + +void EXhalbtcoutsrc_IpsNotify(PBTC_COEXIST pBtCoexist, u8 type) +{ + u8 ipsType; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntIpsNotify++; + if (pBtCoexist->bManualControl) + 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); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_IpsNotify(pBtCoexist, ipsType); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_IpsNotify(pBtCoexist, ipsType); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_IpsNotify(pBtCoexist, ipsType); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_IpsNotify(pBtCoexist, ipsType); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_IpsNotify(pBtCoexist, ipsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_IpsNotify(pBtCoexist, ipsType); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_LpsNotify(PBTC_COEXIST pBtCoexist, u8 type) +{ + u8 lpsType; + + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntLpsNotify++; + if (pBtCoexist->bManualControl) + 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) + EXhalbtc8821aCsr2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_LpsNotify(pBtCoexist, lpsType); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_LpsNotify(pBtCoexist, lpsType); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_LpsNotify(pBtCoexist, lpsType); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_LpsNotify(pBtCoexist, lpsType); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_LpsNotify(pBtCoexist, lpsType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_LpsNotify(pBtCoexist, lpsType); + } +} + +void EXhalbtcoutsrc_ScanNotify(PBTC_COEXIST pBtCoexist, u8 type) +{ + u8 scanType; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntScanNotify++; + if (pBtCoexist->bManualControl) + return; + + if (type) + { + scanType = BTC_SCAN_START; + GLBtcWiFiInScanState = _TRUE; + } + else + { + scanType = BTC_SCAN_FINISH; + GLBtcWiFiInScanState = _FALSE; + } + + // All notify is called in cmd thread, don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_ScanNotify(pBtCoexist, scanType); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_ScanNotify(pBtCoexist, scanType); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_ScanNotify(pBtCoexist, scanType); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_ScanNotify(pBtCoexist, scanType); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_ScanNotify(pBtCoexist, scanType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_ScanNotify(pBtCoexist, scanType); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_ConnectNotify(PBTC_COEXIST pBtCoexist, u8 action) +{ + u8 assoType; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntConnectNotify++; + if (pBtCoexist->bManualControl) + return; + + if (action) + assoType = BTC_ASSOCIATE_START; + else + assoType = BTC_ASSOCIATE_FINISH; + + // All notify is called in cmd thread, don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_ConnectNotify(pBtCoexist, assoType); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_ConnectNotify(pBtCoexist, assoType); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_ConnectNotify(pBtCoexist, assoType); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_ConnectNotify(pBtCoexist, assoType); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_ConnectNotify(pBtCoexist, assoType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_ConnectNotify(pBtCoexist, assoType); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_MediaStatusNotify(PBTC_COEXIST pBtCoexist, RT_MEDIA_STATUS mediaStatus) +{ + u8 mStatus; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntMediaStatusNotify++; + if (pBtCoexist->bManualControl) + return; + + if (RT_MEDIA_CONNECT == mediaStatus) + mStatus = BTC_MEDIA_CONNECT; + else + mStatus = BTC_MEDIA_DISCONNECT; + + // All notify is called in cmd thread, don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_MediaStatusNotify(pBtCoexist, mStatus); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_MediaStatusNotify(pBtCoexist, mStatus); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_MediaStatusNotify(pBtCoexist, mStatus); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, mStatus); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_MediaStatusNotify(pBtCoexist, mStatus); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_MediaStatusNotify(pBtCoexist, mStatus); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_SpecialPacketNotify(PBTC_COEXIST pBtCoexist, u8 pktType) +{ + u8 packetType; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntSpecialPacketNotify++; + if (pBtCoexist->bManualControl) + return; + + if (PACKET_DHCP == pktType) + packetType = BTC_PACKET_DHCP; + else if (PACKET_EAPOL == pktType) + packetType = BTC_PACKET_EAPOL; + else if (PACKET_ARP == pktType) + packetType = BTC_PACKET_ARP; + else + { + packetType = BTC_PACKET_UNKNOWN; + return; + } + + // All notify is called in cmd thread, don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_SpecialPacketNotify(pBtCoexist, packetType); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_SpecialPacketNotify(pBtCoexist, packetType); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_SpecialPacketNotify(pBtCoexist, packetType); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_SpecialPacketNotify(pBtCoexist, packetType); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_SpecialPacketNotify(pBtCoexist, packetType); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_SpecialPacketNotify(pBtCoexist, packetType); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_BtInfoNotify(PBTC_COEXIST pBtCoexist, u8 *tmpBuf, u8 length) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntBtInfoNotify++; + + // All notify is called in cmd thread, don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_BtInfoNotify(pBtCoexist, tmpBuf, length); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +VOID +EXhalbtcoutsrc_RfStatusNotify( + IN PBTC_COEXIST pBtCoexist, + IN u1Byte type + ) +{ + if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntRfStatusNotify++; + + if(IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + } + else if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_RfStatusNotify(pBtCoexist, type); + } + else if(IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_RfStatusNotify(pBtCoexist, type); + } + else if(IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + } + else if(IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + } +} + +void EXhalbtcoutsrc_StackOperationNotify(PBTC_COEXIST pBtCoexist, u8 type) +{ +#if 0 + u8 stackOpType; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntStackOperationNotify++; + if (pBtCoexist->bManualControl) + return; + + if ((HCI_BT_OP_INQUIRY_START == type) || + (HCI_BT_OP_PAGING_START == type) || + (HCI_BT_OP_PAIRING_START == type)) + { + stackOpType = BTC_STACK_OP_INQ_PAGE_PAIR_START; + } + else if ((HCI_BT_OP_INQUIRY_FINISH == type) || + (HCI_BT_OP_PAGING_SUCCESS == type) || + (HCI_BT_OP_PAGING_UNSUCCESS == type) || + (HCI_BT_OP_PAIRING_FINISH == type) ) + { + stackOpType = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH; + } + else + { + stackOpType = BTC_STACK_OP_NONE; + } + +#endif +} + +void EXhalbtcoutsrc_HaltNotify(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_HaltNotify(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_HaltNotify(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_HaltNotify(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_HaltNotify(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_HaltNotify(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_HaltNotify(pBtCoexist); + } + + pBtCoexist->bBinded = FALSE; +} + +void EXhalbtcoutsrc_SwitchBtTRxMask(PBTC_COEXIST pBtCoexist) +{ + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + { + halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x01); //BT goto standby while GNT_BT 1-->0 + } + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + { + halbtcoutsrc_SetBtReg(pBtCoexist, 0, 0x3c, 0x15); //BT goto standby while GNT_BT 1-->0 + } + } +} + +void EXhalbtcoutsrc_PnpNotify(PBTC_COEXIST pBtCoexist, u8 pnpState) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + // + // currently only 1ant we have to do the notification, + // once pnp is notified to sleep state, we have to leave LPS that we can sleep normally. + // + + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_PnpNotify(pBtCoexist,pnpState); + else if(pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_PnpNotify(pBtCoexist,pnpState); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_PnpNotify(pBtCoexist,pnpState); + else if(pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_PnpNotify(pBtCoexist,pnpState); + } + else if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_PnpNotify(pBtCoexist, pnpState); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_PnpNotify(pBtCoexist,pnpState); + else if(pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_PnpNotify(pBtCoexist,pnpState); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_PnpNotify(pBtCoexist, pnpState); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_PnpNotify(pBtCoexist, pnpState); + } +} + +void EXhalbtcoutsrc_ScoreBoardStatusNotify(PBTC_COEXIST pBtCoexist, u8 *tmpBuf, u8 length) +{ + if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_ScoreBoardStatusNotify(pBtCoexist, tmpBuf, length); + } +} + +void EXhalbtcoutsrc_CoexDmSwitch(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntCoexDmSwitch++; + + halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + { + pBtCoexist->bStopCoexDm = TRUE; + EXhalbtc8723b1ant_CoexDmReset(pBtCoexist); + EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_DETECTED, 2); + EXhalbtc8723b2ant_InitHwConfig(pBtCoexist, FALSE); + EXhalbtc8723b2ant_InitCoexDm(pBtCoexist); + pBtCoexist->bStopCoexDm = FALSE; + } + } + + halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_Periodical(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + pBtCoexist->statistics.cntPeriodical++; + + // Periodical should be called in cmd thread, + // don't need to leave low power again +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + { + if (!halbtcoutsrc_UnderIps(pBtCoexist)) + { + EXhalbtc8821a1ant_Periodical(pBtCoexist); + } + } + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_Periodical(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_Periodical(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_Periodical(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_Periodical(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_Periodical(pBtCoexist); + } + +// halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_DbgControl(PBTC_COEXIST pBtCoexist, u8 opCode, u8 opLen, u8 *pData) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->statistics.cntDbgCtrl++; + + // This function doesn't be called yet, + // default no need to leave low power to avoid deadlock +// halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_DbgControl(pBtCoexist, opCode, opLen, pData); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_DbgControl(pBtCoexist, opCode, opLen, pData); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_DbgControl(pBtCoexist, opCode, opLen, pData); + } + +// 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) +{ +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + PADAPTER padapter = (PADAPTER)GLBtCoexist.Adapter; + PBT_MGNT pBtMgnt = &padapter->coex_info.BtMgnt; + u8 i; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->stackInfo.bProfileNotified = _TRUE; + + pBtCoexist->stackInfo.numOfLink = + pBtMgnt->ExtConfig.NumberOfACL+pBtMgnt->ExtConfig.NumberOfSCO; + + // reset first + pBtCoexist->stackInfo.bBtLinkExist = _FALSE; + pBtCoexist->stackInfo.bScoExist = _FALSE; + pBtCoexist->stackInfo.bAclExist = _FALSE; + pBtCoexist->stackInfo.bA2dpExist = _FALSE; + pBtCoexist->stackInfo.bHidExist = _FALSE; + pBtCoexist->stackInfo.numOfHid = 0; + pBtCoexist->stackInfo.bPanExist = _FALSE; + + if (!pBtMgnt->ExtConfig.NumberOfACL) + pBtCoexist->stackInfo.minBtRssi = 0; + + if (pBtCoexist->stackInfo.numOfLink) + { + pBtCoexist->stackInfo.bBtLinkExist = _TRUE; + if (pBtMgnt->ExtConfig.NumberOfSCO) + pBtCoexist->stackInfo.bScoExist = _TRUE; + if (pBtMgnt->ExtConfig.NumberOfACL) + pBtCoexist->stackInfo.bAclExist = _TRUE; + } + + for (i=0; iExtConfig.NumberOfACL; i++) + { + if (BT_PROFILE_A2DP == pBtMgnt->ExtConfig.aclLink[i].BTProfile) + { + pBtCoexist->stackInfo.bA2dpExist = _TRUE; + } + else if (BT_PROFILE_PAN == pBtMgnt->ExtConfig.aclLink[i].BTProfile) + { + pBtCoexist->stackInfo.bPanExist = _TRUE; + } + else if (BT_PROFILE_HID == pBtMgnt->ExtConfig.aclLink[i].BTProfile) + { + pBtCoexist->stackInfo.bHidExist = _TRUE; + pBtCoexist->stackInfo.numOfHid++; + } + else + { + pBtCoexist->stackInfo.bUnknownAclExist = _TRUE; + } + } +#endif //CONFIG_BT_COEXIST_SOCKET_TRX +} + +void EXhalbtcoutsrc_UpdateMinBtRssi(s8 btRssi) +{ + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->stackInfo.minBtRssi = btRssi; +} + +void EXhalbtcoutsrc_SetHciVersion(u16 hciVersion) +{ + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->stackInfo.hciVersion = hciVersion; +} + +void EXhalbtcoutsrc_SetBtPatchVersion(u16 btHciVersion, u16 btPatchVersion) +{ + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + pBtCoexist->btInfo.btRealFwVer = btPatchVersion; + pBtCoexist->btInfo.btHciVer = btHciVersion; +} + +#if 0 +void EXhalbtcoutsrc_SetBtExist(u8 bBtExist) +{ + GLBtCoexist.boardInfo.bBtExist = bBtExist; +} +#endif +void EXhalbtcoutsrc_SetChipType(u8 chipType) +{ + switch(chipType) + { + default: + case BT_2WIRE: + case BT_ISSC_3WIRE: + case BT_ACCEL: + case BT_RTL8756: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_UNDEF; + break; + case BT_CSR_BC4: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_CSR_BC4; + break; + case BT_CSR_BC8: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_CSR_BC8; + break; + case BT_RTL8723A: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_RTL8723A; + break; + case BT_RTL8821: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_RTL8821; + break; + case BT_RTL8723B: + GLBtCoexist.boardInfo.btChipType = BTC_CHIP_RTL8723B; + break; + } +} + +void EXhalbtcoutsrc_SetAntNum(u8 type, u8 antNum) +{ + if (BT_COEX_ANT_TYPE_PG == type) + { + GLBtCoexist.boardInfo.pgAntNum = antNum; + GLBtCoexist.boardInfo.btdmAntNum = antNum; +#if 0 + //The antenna position: Main (default) or Aux for pgAntNum=2 && btdmAntNum =1 + //The antenna position should be determined by auto-detect mechanism + // The following is assumed to main, and those must be modified if y auto-detect mechanism is ready + if ((GLBtCoexist.boardInfo.pgAntNum == 2) && (GLBtCoexist.boardInfo.btdmAntNum == 1) ) + GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + else + GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; +#endif + } + else if (BT_COEX_ANT_TYPE_ANTDIV == type) + { + GLBtCoexist.boardInfo.btdmAntNum = antNum; + //GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + } + else if (BT_COEX_ANT_TYPE_DETECTED == type) + { + GLBtCoexist.boardInfo.btdmAntNum = antNum; + //GLBtCoexist.boardInfo.btdmAntPos = BTC_ANTENNA_AT_MAIN_PORT; + } +} + +// +// Currently used by 8723b only, S0 or S1 +// +void EXhalbtcoutsrc_SetSingleAntPath(u8 singleAntPath) +{ + GLBtCoexist.boardInfo.singleAntPath = singleAntPath; +} + +void EXhalbtcoutsrc_DisplayBtCoexInfo(PBTC_COEXIST pBtCoexist) +{ + if (!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if (IS_HARDWARE_TYPE_8821(pBtCoexist->Adapter)) + { + if (halbtcoutsrc_IsCsrBtCoex(pBtCoexist) == _TRUE) + EXhalbtc8821aCsr2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8821a2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8821a1ant_DisplayCoexInfo(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8723b2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_DisplayCoexInfo(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8703B(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8703b2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8703b1ant_DisplayCoexInfo(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8192E(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8192e2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8192e1ant_DisplayCoexInfo(pBtCoexist); + } + else if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) + { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_DisplayCoexInfo(pBtCoexist); + else if (pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8812a1ant_DisplayCoexInfo(pBtCoexist); + } + + halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_DisplayAntDetection(PBTC_COEXIST pBtCoexist) +{ + if(!halbtcoutsrc_IsBtCoexistAvailable(pBtCoexist)) + return; + + halbtcoutsrc_LeaveLowPower(pBtCoexist); + + if(IS_HARDWARE_TYPE_8723B(pBtCoexist->Adapter)) + { + if(pBtCoexist->boardInfo.btdmAntNum == 1) + EXhalbtc8723b1ant_DisplayAntDetection(pBtCoexist); + } + + halbtcoutsrc_NormalLowPower(pBtCoexist); +} + +void EXhalbtcoutsrc_BTOffOnNotify(PBTC_COEXIST pBtCoexist, u8 bBTON) +{ + + if (IS_HARDWARE_TYPE_8812(pBtCoexist->Adapter)) { + if (pBtCoexist->boardInfo.btdmAntNum == 2) + EXhalbtc8812a2ant_BTOffOnNotify(pBtCoexist, (bBTON == _TRUE)?BTC_BT_ON:BTC_BT_OFF); + } + +} + +static void halbt_InitHwConfig92C(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 u1Tmp; + + + pHalData = GET_HAL_DATA(padapter); + if( (pHalData->bt_coexist.btChipType == BT_CSR_BC4) || + (pHalData->bt_coexist.btChipType == BT_CSR_BC8)) + { + if (pHalData->rf_type == RF_1T1R) + { + // Config to 1T1R + u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable); + u1Tmp &= ~BIT(1); + rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp); + RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp)); + + u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable); + u1Tmp &= ~BIT(1); + rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp); + RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp)); + } + } +} + +static void halbt_InitHwConfig92D(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 u1Tmp; + + pHalData = GET_HAL_DATA(padapter); + if ((pHalData->bt_coexist.btChipType == BT_CSR_BC4) || + (pHalData->bt_coexist.btChipType == BT_CSR_BC8)) + { + if (pHalData->rf_type == RF_1T1R) + { + // Config to 1T1R + u1Tmp = rtw_read8(padapter, rOFDM0_TRxPathEnable); + u1Tmp &= ~BIT(1); + rtw_write8(padapter, rOFDM0_TRxPathEnable, u1Tmp); + RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xC04 = 0x%x\n", u1Tmp)); + + u1Tmp = rtw_read8(padapter, rOFDM1_TRxPathEnable); + u1Tmp &= ~BIT(1); + rtw_write8(padapter, rOFDM1_TRxPathEnable, u1Tmp); + RT_DISP(FBT, BT_TRACE, ("[BTCoex], BT write 0xD04 = 0x%x\n", u1Tmp)); + } + } +} + +/* + * Description: + * Run BT-Coexist mechansim or not + * + */ +void hal_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + pHalData->bt_coexist.bBtExist = bBtExist; + + //EXhalbtcoutsrc_SetBtExist(bBtExist); +} + +/* + * Dewcription: + * Check is co-exist mechanism enabled or not + * + * Return: + * _TRUE Enable BT co-exist mechanism + * _FALSE Disable BT co-exist mechanism + */ +u8 hal_btcoex_IsBtExist(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + return pHalData->bt_coexist.bBtExist; +} + +u8 hal_btcoex_IsBtDisabled(PADAPTER padapter) +{ + if (!hal_btcoex_IsBtExist(padapter)) + return _TRUE; + + if (GLBtCoexist.btInfo.bBtDisabled) + return _TRUE; + else + return _FALSE; +} + +void hal_btcoex_SetChipType(PADAPTER padapter, u8 chipType) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + pHalData->bt_coexist.btChipType = chipType; + + EXhalbtcoutsrc_SetChipType(chipType); +} + +u8 hal_btcoex_GetChipType(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + return pHalData->bt_coexist.btChipType; +} + +void hal_btcoex_SetPgAntNum(PADAPTER padapter, u8 antNum) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + + pHalData->bt_coexist.btTotalAntNum = antNum; + EXhalbtcoutsrc_SetAntNum(BT_COEX_ANT_TYPE_PG, antNum); +} + +u8 hal_btcoex_GetPgAntNum(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + + return pHalData->bt_coexist.btTotalAntNum; +} + +void hal_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath) +{ + EXhalbtcoutsrc_SetSingleAntPath(singleAntPath); +} + +u8 hal_btcoex_Initialize(PADAPTER padapter) +{ + u8 ret1; + u8 ret2; + + + _rtw_memset(&GLBtCoexist, 0, sizeof(GLBtCoexist)); + ret1 = EXhalbtcoutsrc_InitlizeVariables((void*)padapter); + ret2 = (ret1==_TRUE) ? _TRUE : _FALSE; + + return ret2; +} + +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)) + return; + + EXhalbtcoutsrc_InitHwConfig(&GLBtCoexist, bWifiOnly); + EXhalbtcoutsrc_InitCoexDm(&GLBtCoexist); +} + +void hal_btcoex_IpsNotify(PADAPTER padapter, u8 type) +{ + EXhalbtcoutsrc_IpsNotify(&GLBtCoexist, type); +} + +void hal_btcoex_LpsNotify(PADAPTER padapter, u8 type) +{ + EXhalbtcoutsrc_LpsNotify(&GLBtCoexist, type); +} + +void hal_btcoex_ScanNotify(PADAPTER padapter, u8 type) +{ + EXhalbtcoutsrc_ScanNotify(&GLBtCoexist, type); +} + +void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action) +{ + EXhalbtcoutsrc_ConnectNotify(&GLBtCoexist, action); +} + +void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus) +{ + EXhalbtcoutsrc_MediaStatusNotify(&GLBtCoexist, mediaStatus); +} + +void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType) +{ + EXhalbtcoutsrc_SpecialPacketNotify(&GLBtCoexist, pktType); +} + +void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state) +{ + GLBtcWiFiInIQKState = state; +} + +void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + if (GLBtcWiFiInIQKState == _TRUE) + return; + + EXhalbtcoutsrc_BtInfoNotify(&GLBtCoexist, tmpBuf, length); +} + +void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + u8 extid, status, len, seq; + + + if (!GLBtcBtMpRptWait) + return; + + if ((length < 3) || (!tmpBuf)) + return; + + extid = tmpBuf[0]; + /* not response from BT FW then exit*/ + switch (extid) { + case C2H_WIFI_FW_ACTIVE_RSP: + GLBtcBtMpRptWiFiOK = 1; + return; + + case C2H_TRIG_BY_BT_FW: + _cancel_timer_ex(&GLBtcBtMpOperTimer); + GLBtcBtMpRptWait = 0; + GLBtcBtMpRptBTOK = 1; + break; + + default: + return; + } + + status = tmpBuf[1] & 0xF; + len = tmpBuf[1] >> 4; + seq = tmpBuf[2] >> 4; + + GLBtcBtMpRptSeq = seq; + GLBtcBtMpRptStatus = status; + _rtw_memcpy(GLBtcBtMpRptRsp, tmpBuf+3, len); + GLBtcBtMpRptRspSize = len; + _rtw_up_sema(&GLBtcBtMpRptSema); +} + +void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state) +{ + if (state == 1) + state = BTC_WIFI_PNP_SLEEP; + else + state = BTC_WIFI_PNP_WAKE_UP; + + EXhalbtcoutsrc_PnpNotify(&GLBtCoexist, state); +} + +void hal_btcoex_HaltNotify(PADAPTER padapter) +{ + EXhalbtcoutsrc_HaltNotify(&GLBtCoexist); +} + +void hal_btcoex_ScoreBoardStatusNotify(PADAPTER padapter, u8 length, u8 *tmpBuf) +{ + EXhalbtcoutsrc_ScoreBoardStatusNotify(&GLBtCoexist, tmpBuf, length); +} + +void hal_btcoex_SwitchBtTRxMask(PADAPTER padapter) +{ + EXhalbtcoutsrc_SwitchBtTRxMask(&GLBtCoexist); +} + +void hal_btcoex_Hanlder(PADAPTER padapter) +{ + EXhalbtcoutsrc_Periodical(&GLBtCoexist); +} + +s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter) +{ + return (s32)GLBtCoexist.btInfo.bRejectAggPkt; +} + +s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter) +{ + return (s32)GLBtCoexist.btInfo.bBtCtrlAggBufSize; +} + +u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter) +{ + return (u32)GLBtCoexist.btInfo.aggBufSize; +} + +void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual) +{ + GLBtCoexist.bManualControl = bmanual; +} + +u8 hal_btcoex_1Ant(PADAPTER padapter) +{ + if (hal_btcoex_IsBtExist(padapter) == _FALSE) + return _FALSE; + + if (GLBtCoexist.boardInfo.btdmAntNum == 1) + return _TRUE; + + return _FALSE; +} + +u8 hal_btcoex_IsBtControlLps(PADAPTER padapter) +{ + if (hal_btcoex_IsBtExist(padapter) == _FALSE) + return _FALSE; + + if (GLBtCoexist.btInfo.bBtDisabled) + return _FALSE; + + if (GLBtCoexist.btInfo.bBtCtrlLps) + return _TRUE; + + return _FALSE; +} + +u8 hal_btcoex_IsLpsOn(PADAPTER padapter) +{ + if (hal_btcoex_IsBtExist(padapter) == _FALSE) + return _FALSE; + + if (GLBtCoexist.btInfo.bBtDisabled) + return _FALSE; + + if (GLBtCoexist.btInfo.bBtLpsOn) + return _TRUE; + + return _FALSE; +} + +u8 hal_btcoex_RpwmVal(PADAPTER padapter) +{ + return GLBtCoexist.btInfo.rpwmVal; +} + +u8 hal_btcoex_LpsVal(PADAPTER padapter) +{ + return GLBtCoexist.btInfo.lpsVal; +} + +u32 hal_btcoex_GetRaMask(PADAPTER padapter) +{ + if (!hal_btcoex_IsBtExist(padapter)) + return 0; + + if (GLBtCoexist.btInfo.bBtDisabled) + 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; +} + +void hal_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen) +{ + RT_TRACE(COMP_COEX, DBG_LOUD, ("[BTCoex], FW write pwrModeCmd=0x%04x%08x\n", + pCmdBuf[0]<<8|pCmdBuf[1], + pCmdBuf[2]<<24|pCmdBuf[3]<<16|pCmdBuf[4]<<8|pCmdBuf[5])); + + _rtw_memcpy(GLBtCoexist.pwrModeVal, pCmdBuf, cmdLen); +} + +void hal_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize) +{ + PBTCDBGINFO pinfo; + + + pinfo = &GLBtcDbgInfo; + DBG_BT_INFO_INIT(pinfo, pbuf, bufsize); + EXhalbtcoutsrc_DisplayBtCoexInfo(&GLBtCoexist); + DBG_BT_INFO_INIT(pinfo, NULL, 0); +} + +void hal_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule) +{ + u32 i; + + + if (NULL == pDbgModule) + return; + + for (i = 0; i < COMP_MAX; i++) + GLBtcDbgType[i] = pDbgModule[i]; +} + +u32 hal_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize) +{ + s32 count; + u8 *pstr; + u32 leftSize; + + + if ((NULL == pStrBuf) || (0 == bufSize)) + return 0; + + count = 0; + pstr = pStrBuf; + leftSize = bufSize; +// DBG_871X(FUNC_ADPT_FMT ": bufsize=%d\n", FUNC_ADPT_ARG(padapter), bufSize); + + count = rtw_sprintf(pstr, leftSize, "#define DBG\t%d\n", DBG); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + + count = rtw_sprintf(pstr, leftSize, "BTCOEX Debug Setting:\n"); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + + count = rtw_sprintf(pstr, leftSize, + "COMP_COEX: 0x%08X\n\n", + GLBtcDbgType[COMP_COEX]); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + +#if 0 + count = rtw_sprintf(pstr, leftSize, "INTERFACE Debug Setting Definition:\n"); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[0]=%d for INTF_INIT\n", + GLBtcDbgType[BTC_MSG_INTERFACE]&INTF_INIT?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[2]=%d for INTF_NOTIFY\n\n", + GLBtcDbgType[BTC_MSG_INTERFACE]&INTF_NOTIFY?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + + count = rtw_sprintf(pstr, leftSize, "ALGORITHM Debug Setting Definition:\n"); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[0]=%d for BT_RSSI_STATE\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_BT_RSSI_STATE?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[1]=%d for WIFI_RSSI_STATE\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_WIFI_RSSI_STATE?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[2]=%d for BT_MONITOR\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_BT_MONITOR?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[3]=%d for TRACE\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[4]=%d for TRACE_FW\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[5]=%d for TRACE_FW_DETAIL\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW_DETAIL?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[6]=%d for TRACE_FW_EXEC\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_FW_EXEC?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[7]=%d for TRACE_SW\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[8]=%d for TRACE_SW_DETAIL\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW_DETAIL?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; + count = rtw_sprintf(pstr, leftSize, "\tbit[9]=%d for TRACE_SW_EXEC\n", + GLBtcDbgType[BTC_MSG_ALGORITHM]&ALGO_TRACE_SW_EXEC?1:0); + if ((count < 0) || (count >= leftSize)) + goto exit; + pstr += count; + leftSize -= count; +#endif + +exit: + count = pstr - pStrBuf; +// DBG_871X(FUNC_ADPT_FMT ": usedsize=%d\n", FUNC_ADPT_ARG(padapter), count); + + return count; +} + +u8 hal_btcoex_IncreaseScanDeviceNum(PADAPTER padapter) +{ + if (!hal_btcoex_IsBtExist(padapter)) + return _FALSE; + + if (GLBtCoexist.btInfo.bIncreaseScanDevNum) + return _TRUE; + + return _FALSE; +} + +u8 hal_btcoex_IsBtLinkExist(PADAPTER padapter) +{ + if (GLBtCoexist.btLinkInfo.bBtLinkExist) + return _TRUE; + + return _FALSE; +} + +void hal_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer,u16 btPatchVer) +{ + EXhalbtcoutsrc_SetBtPatchVersion(btHciVer,btPatchVer); +} + +void hal_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion) +{ + EXhalbtcoutsrc_SetHciVersion(hciVersion); +} + +void hal_btcoex_StackUpdateProfileInfo(void) +{ + EXhalbtcoutsrc_StackUpdateProfileInfo(); +} + +void hal_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON) +{ + EXhalbtcoutsrc_BTOffOnNotify(&GLBtCoexist, bBTON); +} + +/* + * Description: + * Setting BT coex antenna isolation type . + * coex mechanisn/ spital stream/ best throughput + * anttype = 0 , PSTDMA / 2SS / 0.5T , bad isolation , WiFi/BT ANT Distance<15cm , (<20dB) for 2,3 antenna + * anttype = 1 , PSTDMA / 1SS / 0.5T , normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 2 antenna + * anttype = 2 , TDMA / 2SS / T , normal isolaiton , 50cm>WiFi/BT ANT Distance>15cm , (>20dB) for 3 antenna + * anttype = 3 , no TDMA / 1SS / 0.5T , good isolation , WiFi/BT ANT Distance >50cm , (>40dB) for 2 antenna + * anttype = 4 , no TDMA / 2SS / T , good isolation , WiFi/BT ANT Distance >50cm , (>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; + PBTC_COEXIST pBtCoexist = &GLBtCoexist; + + /*DBG_871X("####%s , anttype = %d , %d\n" , __func__ , anttype , __LINE__); */ + pHalData = GET_HAL_DATA(padapter); + + + pHalData->bt_coexist.btAntisolation = anttype; + + switch (pHalData->bt_coexist.btAntisolation) { + case 0: + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_0; + break; + case 1: + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_1; + break; + case 2: + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_2; + break; + case 3: + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_3; + break; + case 4: + pBtCoexist->boardInfo.antType = (u1Byte)BTC_ANT_TYPE_4; + break; + } + +} + +#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 , rfe_type = 1; + + 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}, + {"RFE_TYPE" , &rfe_type}, + {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" , __func__ , 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 if (!GetU1ByteIntegerFromStringInDecimal(param_value_string , ant_isolation_param[j].value)) + DBG_871X("Fail to GetU1ByteIntegerFromStringInDecimal\n"); + + break; + } + } + } + } + } + + /* YiWei 20140716 , for BT coex antenna isolation control */ + /* rfe_type = 0 was SPDT , rfe_type = 1 was coupler */ + if (ant_num == 3 && ant_distance >= 50) + anttype = 3; + else if (ant_num == 2 && ant_distance >= 50 && rfe_type == 1) + anttype = 2; + else if (ant_num == 3 && ant_distance >= 15 && ant_distance < 50) + anttype = 2; + else if (ant_num == 2 && ant_distance >= 15 && ant_distance < 50 && rfe_type == 1) + anttype = 2; + else if ((ant_num == 2 && ant_distance < 15 && rfe_type == 1) || (ant_num == 3 && ant_distance < 15)) + anttype = 1; + else if (ant_num == 2 && rfe_type == 0) + anttype = 0; + else + anttype = 0; + + hal_btcoex_SetAntIsolationType(Adapter, anttype); + + DBG_871X("%s : ant_num = %d\n" , __func__ , ant_num); + DBG_871X("%s : ant_distance = %d\n" , __func__ , ant_distance); + DBG_871X("%s : rfe_type = %d\n" , __func__ , rfe_type); + /* 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; + + _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_retrieve_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", __func__ , pFileName);*/ + rtStatus = hal_btcoex_ParseAntIsolationConfigFile(Adapter , pHalData->para_file_buf); + } else { + DBG_871X("%s(): No File %s, Load from *** Array!\n" , __func__ , pFileName); + } + + return rtStatus; +} +#endif // CONFIG_LOAD_PHY_PARA_FROM_FILE + +u16 hal_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data) +{ + u16 ret = 0; + + halbtcoutsrc_LeaveLowPower(&GLBtCoexist); + + ret = halbtcoutsrc_GetBtReg(&GLBtCoexist, type, addr, data); + + halbtcoutsrc_NormalLowPower(&GLBtCoexist); + + return ret; +} + +u16 hal_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val) +{ + u16 ret = 0; + + halbtcoutsrc_LeaveLowPower(&GLBtCoexist); + + ret = halbtcoutsrc_SetBtReg(&GLBtCoexist, type, addr, val); + + halbtcoutsrc_NormalLowPower(&GLBtCoexist); + + return ret; +} +#endif // CONFIG_BT_COEXIST + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com.c new file mode 100644 index 00000000..e3a98534 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com.c @@ -0,0 +1,8005 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HAL_COM_C_ + +#include +#include "hal_com_h2c.h" + +#include "hal_data.h" + +//#define CONFIG_GTK_OL_DBG + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +char file_path[PATH_LENGTH_MAX]; +#endif + +void dump_chip_info(HAL_VERSION ChipVersion) +{ + int cnt = 0; + u8 buf[128]={0}; + + if (IS_8188E(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188E_"); + else if (IS_8188F(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188F_"); + else if (IS_8812_SERIES(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8812_"); + else if (IS_8192E(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8192E_"); + else if (IS_8821_SERIES(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8821_"); + else if (IS_8723B_SERIES(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8723B_"); + else if (IS_8703B_SERIES(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8703B_"); + else if (IS_8814A_SERIES(ChipVersion)) + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8814A_"); + else + cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_UNKNOWN_"); + + cnt += sprintf((buf+cnt), "%s_", IS_NORMAL_CHIP(ChipVersion)?"Normal_Chip":"Test_Chip"); + if(IS_CHIP_VENDOR_TSMC(ChipVersion)) + cnt += sprintf((buf+cnt), "%s_","TSMC"); + else if(IS_CHIP_VENDOR_UMC(ChipVersion)) + cnt += sprintf((buf+cnt), "%s_","UMC"); + else if(IS_CHIP_VENDOR_SMIC(ChipVersion)) + cnt += sprintf((buf+cnt), "%s_","SMIC"); + + if (IS_A_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "A_CUT_"); + else if (IS_B_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "B_CUT_"); + else if (IS_C_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "C_CUT_"); + else if (IS_D_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "D_CUT_"); + else if (IS_E_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "E_CUT_"); + else if (IS_F_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "F_CUT_"); + else if (IS_I_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "I_CUT_"); + else if (IS_J_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "J_CUT_"); + else if (IS_K_CUT(ChipVersion)) + cnt += sprintf((buf+cnt), "K_CUT_"); + else + cnt += sprintf((buf+cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion); + + if(IS_1T1R(ChipVersion)) cnt += sprintf((buf+cnt), "1T1R_"); + else if(IS_1T2R(ChipVersion)) cnt += sprintf((buf+cnt), "1T2R_"); + else if(IS_2T2R(ChipVersion)) cnt += sprintf((buf+cnt), "2T2R_"); + else if(IS_3T3R(ChipVersion)) cnt += sprintf((buf+cnt), "3T3R_"); + else if(IS_3T4R(ChipVersion)) cnt += sprintf((buf+cnt), "3T4R_"); + else if(IS_4T4R(ChipVersion)) cnt += sprintf((buf+cnt), "4T4R_"); + else cnt += sprintf((buf+cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType); + + cnt += sprintf((buf+cnt), "RomVer(%d)\n", ChipVersion.ROMVer); + + DBG_871X("%s", buf); +} +void rtw_hal_config_rftype(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (IS_1T1R(pHalData->VersionID)) { + pHalData->rf_type = RF_1T1R; + pHalData->NumTotalRFPath = 1; + } + else if (IS_2T2R(pHalData->VersionID)) { + pHalData->rf_type = RF_2T2R; + pHalData->NumTotalRFPath = 2; + } + else if (IS_1T2R(pHalData->VersionID)) { + pHalData->rf_type = RF_1T2R; + pHalData->NumTotalRFPath = 2; + } + else if(IS_3T3R(pHalData->VersionID)) { + pHalData->rf_type = RF_3T3R; + pHalData->NumTotalRFPath = 3; + } + else if(IS_4T4R(pHalData->VersionID)) { + pHalData->rf_type = RF_4T4R; + pHalData->NumTotalRFPath = 4; + } + else { + pHalData->rf_type = RF_1T1R; + pHalData->NumTotalRFPath = 1; + } + + DBG_871X("%s RF_Type is %d TotalTxPath is %d \n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath); +} + +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +/* + * Description: + * Use hardware(efuse), driver parameter(registry) and default channel plan + * to decide which one should be used. + * + * Parameters: + * padapter pointer of adapter + * hw_alpha2 country code from HW (efuse/eeprom/mapfile) + * hw_chplan channel plan from HW (efuse/eeprom/mapfile) + * BIT[7] software configure mode; 0:Enable, 1:disable + * BIT[6:0] Channel Plan + * sw_alpha2 country code from HW (registry/module param) + * sw_chplan channel plan from SW (registry/module param) + * def_chplan channel plan used when HW/SW both invalid + * AutoLoadFail efuse autoload fail or not + * + * Return: + * Final channel plan decision + * + */ +u8 hal_com_config_channel_plan( + IN PADAPTER padapter, + IN char *hw_alpha2, + IN u8 hw_chplan, + IN char *sw_alpha2, + IN u8 sw_chplan, + IN u8 def_chplan, + IN BOOLEAN AutoLoadFail + ) +{ + PHAL_DATA_TYPE pHalData; + u8 force_hw_chplan = _FALSE; + int chplan = -1; + const struct country_chplan *country_ent = NULL, *ent; + + pHalData = GET_HAL_DATA(padapter); + + /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */ + if (hw_chplan == 0xFF) + goto chk_hw_country_code; + + if (AutoLoadFail == _TRUE) + goto chk_sw_config; + + #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN + if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) + force_hw_chplan = _TRUE; + #endif + + hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK); + +chk_hw_country_code: + if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) { + ent = rtw_get_chplan_from_country(hw_alpha2); + if (ent) { + /* get chplan from hw country code, by pass hw chplan setting */ + country_ent = ent; + chplan = ent->chplan; + goto chk_sw_config; + } else + DBG_871X_LEVEL(_drv_always_, "%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]); + } + + if (rtw_is_channel_plan_valid(hw_chplan)) + chplan = hw_chplan; + else if (force_hw_chplan == _TRUE) { + DBG_871X_LEVEL(_drv_always_, "%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan); + /* hw infomaton invalid, refer to sw information */ + force_hw_chplan = _FALSE; + } + +chk_sw_config: + if (force_hw_chplan == _TRUE) + goto done; + + if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) { + ent = rtw_get_chplan_from_country(sw_alpha2); + if (ent) { + /* get chplan from sw country code, by pass sw chplan setting */ + country_ent = ent; + chplan = ent->chplan; + goto done; + } else + DBG_871X_LEVEL(_drv_always_, "%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]); + } + + if (rtw_is_channel_plan_valid(sw_chplan)) { + /* cancel hw_alpha2 because chplan is specified by sw_chplan*/ + country_ent = NULL; + chplan = sw_chplan; + } else if (sw_chplan != RTW_CHPLAN_MAX) + DBG_871X_LEVEL(_drv_always_, "%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan); + +done: + if (chplan == -1) { + DBG_871X_LEVEL(_drv_always_, "%s use def_chplan:0x%02X\n", __func__, def_chplan); + chplan = def_chplan; + } else if (country_ent) { + DBG_871X_LEVEL(_drv_always_, "%s country code:\"%c%c\" with chplan:0x%02X\n", __func__ + , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan); + } else + DBG_871X_LEVEL(_drv_always_, "%s chplan:0x%02X\n", __func__, chplan); + + padapter->mlmepriv.country_ent = country_ent; + pHalData->bDisableSWChannelPlan = force_hw_chplan; + + return chplan; +} + +BOOLEAN +HAL_IsLegalChannel( + IN PADAPTER Adapter, + IN u32 Channel + ) +{ + BOOLEAN bLegalChannel = _TRUE; + + if (Channel > 14) { + if(IsSupported5G(Adapter->registrypriv.wireless_mode) == _FALSE) { + bLegalChannel = _FALSE; + DBG_871X("Channel > 14 but wireless_mode do not support 5G\n"); + } + } else if ((Channel <= 14) && (Channel >=1)){ + if(IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) { + bLegalChannel = _FALSE; + DBG_871X("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n"); + } + } else { + bLegalChannel = _FALSE; + DBG_871X("Channel is Invalid !!!\n"); + } + + return bLegalChannel; +} + +u8 MRateToHwRate(u8 rate) +{ + u8 ret = DESC_RATE1M; + + switch(rate) + { + case MGN_1M: ret = DESC_RATE1M; break; + case MGN_2M: ret = DESC_RATE2M; break; + case MGN_5_5M: ret = DESC_RATE5_5M; break; + case MGN_11M: ret = DESC_RATE11M; break; + case MGN_6M: ret = DESC_RATE6M; break; + case MGN_9M: ret = DESC_RATE9M; break; + case MGN_12M: ret = DESC_RATE12M; break; + case MGN_18M: ret = DESC_RATE18M; break; + case MGN_24M: ret = DESC_RATE24M; break; + case MGN_36M: ret = DESC_RATE36M; break; + case MGN_48M: ret = DESC_RATE48M; break; + case MGN_54M: ret = DESC_RATE54M; break; + + case MGN_MCS0: ret = DESC_RATEMCS0; break; + case MGN_MCS1: ret = DESC_RATEMCS1; break; + case MGN_MCS2: ret = DESC_RATEMCS2; break; + case MGN_MCS3: ret = DESC_RATEMCS3; break; + case MGN_MCS4: ret = DESC_RATEMCS4; break; + case MGN_MCS5: ret = DESC_RATEMCS5; break; + case MGN_MCS6: ret = DESC_RATEMCS6; break; + case MGN_MCS7: ret = DESC_RATEMCS7; break; + case MGN_MCS8: ret = DESC_RATEMCS8; break; + case MGN_MCS9: ret = DESC_RATEMCS9; break; + case MGN_MCS10: ret = DESC_RATEMCS10; break; + case MGN_MCS11: ret = DESC_RATEMCS11; break; + case MGN_MCS12: ret = DESC_RATEMCS12; break; + case MGN_MCS13: ret = DESC_RATEMCS13; break; + case MGN_MCS14: ret = DESC_RATEMCS14; break; + case MGN_MCS15: ret = DESC_RATEMCS15; break; + case MGN_MCS16: ret = DESC_RATEMCS16; break; + case MGN_MCS17: ret = DESC_RATEMCS17; break; + case MGN_MCS18: ret = DESC_RATEMCS18; break; + case MGN_MCS19: ret = DESC_RATEMCS19; break; + case MGN_MCS20: ret = DESC_RATEMCS20; break; + case MGN_MCS21: ret = DESC_RATEMCS21; break; + case MGN_MCS22: ret = DESC_RATEMCS22; break; + case MGN_MCS23: ret = DESC_RATEMCS23; break; + case MGN_MCS24: ret = DESC_RATEMCS24; break; + case MGN_MCS25: ret = DESC_RATEMCS25; break; + case MGN_MCS26: ret = DESC_RATEMCS26; break; + case MGN_MCS27: ret = DESC_RATEMCS27; break; + case MGN_MCS28: ret = DESC_RATEMCS28; break; + case MGN_MCS29: ret = DESC_RATEMCS29; break; + case MGN_MCS30: ret = DESC_RATEMCS30; break; + case MGN_MCS31: ret = DESC_RATEMCS31; break; + + case MGN_VHT1SS_MCS0: ret = DESC_RATEVHTSS1MCS0; break; + case MGN_VHT1SS_MCS1: ret = DESC_RATEVHTSS1MCS1; break; + case MGN_VHT1SS_MCS2: ret = DESC_RATEVHTSS1MCS2; break; + case MGN_VHT1SS_MCS3: ret = DESC_RATEVHTSS1MCS3; break; + case MGN_VHT1SS_MCS4: ret = DESC_RATEVHTSS1MCS4; break; + case MGN_VHT1SS_MCS5: ret = DESC_RATEVHTSS1MCS5; break; + case MGN_VHT1SS_MCS6: ret = DESC_RATEVHTSS1MCS6; break; + case MGN_VHT1SS_MCS7: ret = DESC_RATEVHTSS1MCS7; break; + case MGN_VHT1SS_MCS8: ret = DESC_RATEVHTSS1MCS8; break; + case MGN_VHT1SS_MCS9: ret = DESC_RATEVHTSS1MCS9; break; + case MGN_VHT2SS_MCS0: ret = DESC_RATEVHTSS2MCS0; break; + case MGN_VHT2SS_MCS1: ret = DESC_RATEVHTSS2MCS1; break; + case MGN_VHT2SS_MCS2: ret = DESC_RATEVHTSS2MCS2; break; + case MGN_VHT2SS_MCS3: ret = DESC_RATEVHTSS2MCS3; break; + case MGN_VHT2SS_MCS4: ret = DESC_RATEVHTSS2MCS4; break; + case MGN_VHT2SS_MCS5: ret = DESC_RATEVHTSS2MCS5; break; + case MGN_VHT2SS_MCS6: ret = DESC_RATEVHTSS2MCS6; break; + case MGN_VHT2SS_MCS7: ret = DESC_RATEVHTSS2MCS7; break; + case MGN_VHT2SS_MCS8: ret = DESC_RATEVHTSS2MCS8; break; + case MGN_VHT2SS_MCS9: ret = DESC_RATEVHTSS2MCS9; break; + case MGN_VHT3SS_MCS0: ret = DESC_RATEVHTSS3MCS0; break; + case MGN_VHT3SS_MCS1: ret = DESC_RATEVHTSS3MCS1; break; + case MGN_VHT3SS_MCS2: ret = DESC_RATEVHTSS3MCS2; break; + case MGN_VHT3SS_MCS3: ret = DESC_RATEVHTSS3MCS3; break; + case MGN_VHT3SS_MCS4: ret = DESC_RATEVHTSS3MCS4; break; + case MGN_VHT3SS_MCS5: ret = DESC_RATEVHTSS3MCS5; break; + case MGN_VHT3SS_MCS6: ret = DESC_RATEVHTSS3MCS6; break; + case MGN_VHT3SS_MCS7: ret = DESC_RATEVHTSS3MCS7; break; + case MGN_VHT3SS_MCS8: ret = DESC_RATEVHTSS3MCS8; break; + case MGN_VHT3SS_MCS9: ret = DESC_RATEVHTSS3MCS9; break; + case MGN_VHT4SS_MCS0: ret = DESC_RATEVHTSS4MCS0; break; + case MGN_VHT4SS_MCS1: ret = DESC_RATEVHTSS4MCS1; break; + case MGN_VHT4SS_MCS2: ret = DESC_RATEVHTSS4MCS2; break; + case MGN_VHT4SS_MCS3: ret = DESC_RATEVHTSS4MCS3; break; + case MGN_VHT4SS_MCS4: ret = DESC_RATEVHTSS4MCS4; break; + case MGN_VHT4SS_MCS5: ret = DESC_RATEVHTSS4MCS5; break; + case MGN_VHT4SS_MCS6: ret = DESC_RATEVHTSS4MCS6; break; + case MGN_VHT4SS_MCS7: ret = DESC_RATEVHTSS4MCS7; break; + case MGN_VHT4SS_MCS8: ret = DESC_RATEVHTSS4MCS8; break; + case MGN_VHT4SS_MCS9: ret = DESC_RATEVHTSS4MCS9; break; + default: break; + } + + return ret; +} + +u8 HwRateToMRate(u8 rate) +{ + u8 ret_rate = MGN_1M; + + switch(rate) + { + + case DESC_RATE1M: ret_rate = MGN_1M; break; + case DESC_RATE2M: ret_rate = MGN_2M; break; + case DESC_RATE5_5M: ret_rate = MGN_5_5M; break; + case DESC_RATE11M: ret_rate = MGN_11M; break; + case DESC_RATE6M: ret_rate = MGN_6M; break; + case DESC_RATE9M: ret_rate = MGN_9M; break; + case DESC_RATE12M: ret_rate = MGN_12M; break; + case DESC_RATE18M: ret_rate = MGN_18M; break; + case DESC_RATE24M: ret_rate = MGN_24M; break; + case DESC_RATE36M: ret_rate = MGN_36M; break; + case DESC_RATE48M: ret_rate = MGN_48M; break; + case DESC_RATE54M: ret_rate = MGN_54M; break; + case DESC_RATEMCS0: ret_rate = MGN_MCS0; break; + case DESC_RATEMCS1: ret_rate = MGN_MCS1; break; + case DESC_RATEMCS2: ret_rate = MGN_MCS2; break; + case DESC_RATEMCS3: ret_rate = MGN_MCS3; break; + case DESC_RATEMCS4: ret_rate = MGN_MCS4; break; + case DESC_RATEMCS5: ret_rate = MGN_MCS5; break; + case DESC_RATEMCS6: ret_rate = MGN_MCS6; break; + case DESC_RATEMCS7: ret_rate = MGN_MCS7; break; + case DESC_RATEMCS8: ret_rate = MGN_MCS8; break; + case DESC_RATEMCS9: ret_rate = MGN_MCS9; break; + case DESC_RATEMCS10: ret_rate = MGN_MCS10; break; + case DESC_RATEMCS11: ret_rate = MGN_MCS11; break; + case DESC_RATEMCS12: ret_rate = MGN_MCS12; break; + case DESC_RATEMCS13: ret_rate = MGN_MCS13; break; + case DESC_RATEMCS14: ret_rate = MGN_MCS14; break; + case DESC_RATEMCS15: ret_rate = MGN_MCS15; break; + case DESC_RATEMCS16: ret_rate = MGN_MCS16; break; + case DESC_RATEMCS17: ret_rate = MGN_MCS17; break; + case DESC_RATEMCS18: ret_rate = MGN_MCS18; break; + case DESC_RATEMCS19: ret_rate = MGN_MCS19; break; + case DESC_RATEMCS20: ret_rate = MGN_MCS20; break; + case DESC_RATEMCS21: ret_rate = MGN_MCS21; break; + case DESC_RATEMCS22: ret_rate = MGN_MCS22; break; + case DESC_RATEMCS23: ret_rate = MGN_MCS23; break; + case DESC_RATEMCS24: ret_rate = MGN_MCS24; break; + case DESC_RATEMCS25: ret_rate = MGN_MCS25; break; + case DESC_RATEMCS26: ret_rate = MGN_MCS26; break; + case DESC_RATEMCS27: ret_rate = MGN_MCS27; break; + case DESC_RATEMCS28: ret_rate = MGN_MCS28; break; + case DESC_RATEMCS29: ret_rate = MGN_MCS29; break; + case DESC_RATEMCS30: ret_rate = MGN_MCS30; break; + case DESC_RATEMCS31: ret_rate = MGN_MCS31; break; + case DESC_RATEVHTSS1MCS0: ret_rate = MGN_VHT1SS_MCS0; break; + case DESC_RATEVHTSS1MCS1: ret_rate = MGN_VHT1SS_MCS1; break; + case DESC_RATEVHTSS1MCS2: ret_rate = MGN_VHT1SS_MCS2; break; + case DESC_RATEVHTSS1MCS3: ret_rate = MGN_VHT1SS_MCS3; break; + case DESC_RATEVHTSS1MCS4: ret_rate = MGN_VHT1SS_MCS4; break; + case DESC_RATEVHTSS1MCS5: ret_rate = MGN_VHT1SS_MCS5; break; + case DESC_RATEVHTSS1MCS6: ret_rate = MGN_VHT1SS_MCS6; break; + case DESC_RATEVHTSS1MCS7: ret_rate = MGN_VHT1SS_MCS7; break; + case DESC_RATEVHTSS1MCS8: ret_rate = MGN_VHT1SS_MCS8; break; + case DESC_RATEVHTSS1MCS9: ret_rate = MGN_VHT1SS_MCS9; break; + case DESC_RATEVHTSS2MCS0: ret_rate = MGN_VHT2SS_MCS0; break; + case DESC_RATEVHTSS2MCS1: ret_rate = MGN_VHT2SS_MCS1; break; + case DESC_RATEVHTSS2MCS2: ret_rate = MGN_VHT2SS_MCS2; break; + case DESC_RATEVHTSS2MCS3: ret_rate = MGN_VHT2SS_MCS3; break; + case DESC_RATEVHTSS2MCS4: ret_rate = MGN_VHT2SS_MCS4; break; + case DESC_RATEVHTSS2MCS5: ret_rate = MGN_VHT2SS_MCS5; break; + case DESC_RATEVHTSS2MCS6: ret_rate = MGN_VHT2SS_MCS6; break; + case DESC_RATEVHTSS2MCS7: ret_rate = MGN_VHT2SS_MCS7; break; + case DESC_RATEVHTSS2MCS8: ret_rate = MGN_VHT2SS_MCS8; break; + case DESC_RATEVHTSS2MCS9: ret_rate = MGN_VHT2SS_MCS9; break; + case DESC_RATEVHTSS3MCS0: ret_rate = MGN_VHT3SS_MCS0; break; + case DESC_RATEVHTSS3MCS1: ret_rate = MGN_VHT3SS_MCS1; break; + case DESC_RATEVHTSS3MCS2: ret_rate = MGN_VHT3SS_MCS2; break; + case DESC_RATEVHTSS3MCS3: ret_rate = MGN_VHT3SS_MCS3; break; + case DESC_RATEVHTSS3MCS4: ret_rate = MGN_VHT3SS_MCS4; break; + case DESC_RATEVHTSS3MCS5: ret_rate = MGN_VHT3SS_MCS5; break; + case DESC_RATEVHTSS3MCS6: ret_rate = MGN_VHT3SS_MCS6; break; + case DESC_RATEVHTSS3MCS7: ret_rate = MGN_VHT3SS_MCS7; break; + case DESC_RATEVHTSS3MCS8: ret_rate = MGN_VHT3SS_MCS8; break; + case DESC_RATEVHTSS3MCS9: ret_rate = MGN_VHT3SS_MCS9; break; + case DESC_RATEVHTSS4MCS0: ret_rate = MGN_VHT4SS_MCS0; break; + case DESC_RATEVHTSS4MCS1: ret_rate = MGN_VHT4SS_MCS1; break; + case DESC_RATEVHTSS4MCS2: ret_rate = MGN_VHT4SS_MCS2; break; + case DESC_RATEVHTSS4MCS3: ret_rate = MGN_VHT4SS_MCS3; break; + case DESC_RATEVHTSS4MCS4: ret_rate = MGN_VHT4SS_MCS4; break; + case DESC_RATEVHTSS4MCS5: ret_rate = MGN_VHT4SS_MCS5; break; + case DESC_RATEVHTSS4MCS6: ret_rate = MGN_VHT4SS_MCS6; break; + case DESC_RATEVHTSS4MCS7: ret_rate = MGN_VHT4SS_MCS7; break; + case DESC_RATEVHTSS4MCS8: ret_rate = MGN_VHT4SS_MCS8; break; + case DESC_RATEVHTSS4MCS9: ret_rate = MGN_VHT4SS_MCS9; break; + + default: + DBG_871X("HwRateToMRate(): Non supported Rate [%x]!!!\n",rate ); + break; + } + + return ret_rate; +} + +void HalSetBrateCfg( + IN PADAPTER Adapter, + IN u8 *mBratesOS, + OUT u16 *pBrateCfg) +{ + u8 i, is_brate, brate; + + for(i=0;iQueue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD +} + +static VOID +_TwoOutPipeMapping( + IN PADAPTER pAdapter, + IN BOOLEAN bWIFICfg + ) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); + + if(bWIFICfg){ //WMM + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 0, 1, 0, 1, 0, 0, 0, 0, 0 }; + //0:ep_0 num, 1:ep_1 num + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + + } + else{//typical setting + + + //BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + //0:ep_0 num, 1:ep_1 num + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + + } + +} + +static VOID _ThreeOutPipeMapping( + IN PADAPTER pAdapter, + IN BOOLEAN bWIFICfg + ) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); + + if(bWIFICfg){//for WMM + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 1, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H, 1:N, 2:L + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + + } + else{//typical setting + + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 2, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H, 1:N, 2:L + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + } + +} +static VOID _FourOutPipeMapping( + IN PADAPTER pAdapter, + IN BOOLEAN bWIFICfg + ) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); + + if(bWIFICfg){//for WMM + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 1, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H, 1:N, 2:L ,3:E + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + + } + else{//typical setting + + + // BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA + //{ 2, 2, 1, 0, 0, 0, 0, 0, 0 }; + //0:H, 1:N, 2:L + + pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO + pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI + pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE + pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK + + pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN + pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT + pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH + pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD + } + +} +BOOLEAN +Hal_MappingOutPipe( + IN PADAPTER pAdapter, + IN u8 NumOutPipe + ) +{ + struct registry_priv *pregistrypriv = &pAdapter->registrypriv; + + BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ?_TRUE:_FALSE; + + BOOLEAN result = _TRUE; + + switch(NumOutPipe) + { + case 2: + _TwoOutPipeMapping(pAdapter, bWIFICfg); + break; + case 3: + case 4: + _ThreeOutPipeMapping(pAdapter, bWIFICfg); + break; + case 1: + _OneOutPipeMapping(pAdapter); + break; + default: + result = _FALSE; + break; + } + + return result; + +} + +void hal_init_macaddr(_adapter *adapter) +{ + rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(adapter)); +#ifdef CONFIG_CONCURRENT_MODE + if (adapter->pbuddy_adapter) + rtw_hal_set_hwreg(adapter->pbuddy_adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(adapter->pbuddy_adapter)); +#endif +} + +void rtw_init_hal_com_default_value(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + pHalData->AntDetection = 1; +} + +/* +* C2H event format: +* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID +* BITS [127:120] [119:16] [15:8] [7:4] [3:0] +*/ + +void c2h_evt_clear(_adapter *adapter) +{ + rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); +} + +s32 c2h_evt_read(_adapter *adapter, u8 *buf) +{ + s32 ret = _FAIL; + struct c2h_evt_hdr *c2h_evt; + int i; + u8 trigger; + + if (buf == NULL) + goto exit; + +#if defined (CONFIG_RTL8188E) + + trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); + + if (trigger == C2H_EVT_HOST_CLOSE) { + goto exit; /* Not ready */ + } else if (trigger != C2H_EVT_FW_CLOSE) { + goto clear_evt; /* Not a valid value */ + } + + c2h_evt = (struct c2h_evt_hdr *)buf; + + _rtw_memset(c2h_evt, 0, 16); + + *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); + *(buf+1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ", + &c2h_evt , sizeof(c2h_evt)); + + if (0) { + DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__ + , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger); + } + + /* Read the content */ + for (i = 0; i < c2h_evt->plen; i++) + c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n", + c2h_evt->payload, c2h_evt->plen); + + ret = _SUCCESS; + +clear_evt: + /* + * Clear event to notify FW we have read the command. + * If this field isn't clear, the FW won't update the next command message. + */ + c2h_evt_clear(adapter); +#endif +exit: + return ret; +} + +/* +* C2H event format: +* Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID +* BITS [127:120] [119:112] [111:16] [15:8] [7:0] +*/ +s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf) +{ + s32 ret = _FAIL; + struct c2h_evt_hdr_88xx *c2h_evt; + int i; + u8 trigger; + + if (buf == NULL) + goto exit; + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) + + trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); + + if (trigger == C2H_EVT_HOST_CLOSE) { + goto exit; /* Not ready */ + } else if (trigger != C2H_EVT_FW_CLOSE) { + goto clear_evt; /* Not a valid value */ + } + + c2h_evt = (struct c2h_evt_hdr_88xx *)buf; + + _rtw_memset(c2h_evt, 0, 16); + + c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); + c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX); + c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ", + &c2h_evt , sizeof(c2h_evt)); + + if (0) { + DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__ + , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger); + } + + /* Read the content */ + for (i = 0; i < c2h_evt->plen; i++) + c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n", + c2h_evt->payload, c2h_evt->plen); + + ret = _SUCCESS; + +clear_evt: + /* + * Clear event to notify FW we have read the command. + * If this field isn't clear, the FW won't update the next command message. + */ + c2h_evt_clear(adapter); +#endif +exit: + return ret; +} + + +u8 rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta) +{ + if(IS_NEW_GENERATION_IC(adapter)){ + return networktype_to_raid_ex(adapter,psta); + } + else{ + return networktype_to_raid(adapter,psta); + } + +} +u8 rtw_get_mgntframe_raid(_adapter *adapter,unsigned char network_type) +{ + + u8 raid; + if(IS_NEW_GENERATION_IC(adapter)){ + + raid = (network_type & WIRELESS_11B) ?RATEID_IDX_B + :RATEID_IDX_G; + } + else{ + raid = (network_type & WIRELESS_11B) ?RATR_INX_WIRELESS_B + :RATR_INX_WIRELESS_G; + } + return raid; +} + +void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta) +{ + u8 i, rf_type, limit; + u64 tx_ra_bitmap; + + if(psta == NULL) + { + return; + } + + tx_ra_bitmap = 0; + + //b/g mode ra_bitmap + for (i=0; ibssrateset); i++) + { + if (psta->bssrateset[i]) + tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f); + } + +#ifdef CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT + //AC mode ra_bitmap + if(psta->vhtpriv.vht_option) + { + tx_ra_bitmap |= (rtw_vht_rate_to_bitmap(psta->vhtpriv.vht_mcs_map) << 12); + } + else +#endif //CONFIG_80211AC_VHT + { + //n mode ra_bitmap + if(psta->htpriv.ht_option) + { + rf_type = RF_1T1R; + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + if(rf_type == RF_2T2R) + limit=16;// 2R + else if(rf_type == RF_3T3R) + limit=24;// 3R + else + limit=8;// 1R + + + /* Handling SMPS mode for AP MODE only*/ + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) { + /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/ + if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) { + /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/ + limit = 8;/* 1R*/ + } + } + + for (i=0; ihtpriv.ht_cap.supp_mcs_set[i/8] & BIT(i%8)) + tx_ra_bitmap |= BIT(i+12); + } + } + } +#endif //CONFIG_80211N_HT + DBG_871X("supp_mcs_set = %02x, %02x, %02x, rf_type=%d, tx_ra_bitmap=%016llx\n" + , psta->htpriv.ht_cap.supp_mcs_set[0], psta->htpriv.ht_cap.supp_mcs_set[1], psta->htpriv.ht_cap.supp_mcs_set[2], rf_type, tx_ra_bitmap); + psta->ra_mask = tx_ra_bitmap; + psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f; +} + +#ifndef SEC_CAM_ACCESS_TIMEOUT_MS + #define SEC_CAM_ACCESS_TIMEOUT_MS 200 +#endif + +#ifndef DBG_SEC_CAM_ACCESS + #define DBG_SEC_CAM_ACCESS 0 +#endif + +u32 rtw_sec_read_cam(_adapter *adapter, u8 addr) +{ + _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex; + u32 rdata; + u32 cnt = 0; + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + + _enter_critical_mutex(mutex, NULL); + + rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr); + + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(adapter)) { + sr = 1; + break; + } + + cnt++; + if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG)) + break; + + if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + + rdata = rtw_read32(adapter, REG_CAMREAD); + + _exit_critical_mutex(mutex, NULL); + + if (DBG_SEC_CAM_ACCESS || timeout) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n" + , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end)); + } + + return rdata; +} + +void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata) +{ + _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex; + u32 cnt = 0; + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + + _enter_critical_mutex(mutex, NULL); + + rtw_write32(adapter, REG_CAMWRITE, wdata); + rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr); + + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(adapter)) { + sr = 1; + break; + } + + cnt++; + if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG)) + break; + + if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + + _exit_critical_mutex(mutex, NULL); + + if (DBG_SEC_CAM_ACCESS || timeout) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n" + , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end)); + } +} + +void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key) +{ + unsigned int val, addr; + u8 i; + u32 rdata; + u8 begin = 0; + u8 end = 5; /* TODO: consider other key length accordingly */ + + if (!ctrl && !mac && !key) { + rtw_warn_on(1); + goto exit; + } + + /* TODO: check id range */ + + if (!ctrl && !mac) + begin = 2; /* read from key */ + + if (!key && !mac) + end = 0; /* read to ctrl */ + else if (!key) + end = 2; /* read to mac */ + + for (i = begin; i <= end; i++) { + rdata = rtw_sec_read_cam(adapter, (id << 3) | i); + + switch (i) { + case 0: + if (ctrl) + _rtw_memcpy(ctrl, (u8 *)(&rdata), 2); + if (mac) + _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2); + break; + case 1: + if (mac) + _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4); + break; + default: + if (key) + _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4); + break; + } + } + +exit: + return; +} + + +void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key) +{ + unsigned int i; + int j; + u8 addr; + u32 wdata; + + /* TODO: consider other key length accordingly */ +#if 0 + switch ((ctrl & 0x1c) >> 2) { + case _WEP40_: + case _TKIP_ + case _AES_ + case _WEP104_ + + } +#else + j = 5; +#endif + + for (; j >= 0; j--) { + switch (j) { + case 0: + wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24)); + break; + case 1: + wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24)); + break; + default: + i = (j - 2) << 2; + wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24)); + break; + } + + addr = (id << 3) + j; + + rtw_sec_write_cam(adapter, addr, wdata); + } +} + +bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id) +{ + bool res; + u16 ctrl; + + rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL); + + res = (ctrl & BIT6) ? _TRUE : _FALSE; + return res; +} + +void hw_var_port_switch(_adapter *adapter) +{ +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_RUNTIME_PORT_SWITCH +/* +0x102: MSR +0x550: REG_BCN_CTRL +0x551: REG_BCN_CTRL_1 +0x55A: REG_ATIMWND +0x560: REG_TSFTR +0x568: REG_TSFTR1 +0x570: REG_ATIMWND_1 +0x610: REG_MACID +0x618: REG_BSSID +0x700: REG_MACID1 +0x708: REG_BSSID1 +*/ + + int i; + u8 msr; + u8 bcn_ctrl; + u8 bcn_ctrl_1; + u8 atimwnd[2]; + u8 atimwnd_1[2]; + u8 tsftr[8]; + u8 tsftr_1[8]; + u8 macid[6]; + u8 bssid[6]; + u8 macid_1[6]; + u8 bssid_1[6]; + + u8 iface_type; + + 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); + +#ifdef DBG_RUNTIME_PORT_SWITCH + DBG_871X(FUNC_ADPT_FMT" before switch\n" + "msr:0x%02x\n" + "bcn_ctrl:0x%02x\n" + "bcn_ctrl_1:0x%02x\n" + "atimwnd:0x%04x\n" + "atimwnd_1:0x%04x\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 */ + + /* disable bcn function, disable update TSF */ + rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT); + rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT); + + /* switch msr */ + msr = (msr&0xf0) |((msr&0x03) << 2) | ((msr&0x0c) >> 2); + rtw_write8(adapter, MSR, msr); + + /* write port0 */ + rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION); + for (i=0; i<2; i++) + rtw_write8(adapter, REG_ATIMWND+i, atimwnd_1[i]); + for (i=0; i<8; i++) + rtw_write8(adapter, REG_TSFTR+i, tsftr_1[i]); + for (i=0; i<6; i++) + rtw_write8(adapter, REG_MACID+i, macid_1[i]); + for (i=0; i<6; i++) + rtw_write8(adapter, REG_BSSID+i, bssid_1[i]); + + /* write port1 */ + rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION); + for (i=0; i<2; i++) + rtw_write8(adapter, REG_ATIMWND_1+1, atimwnd[i]); + for (i=0; i<8; i++) + rtw_write8(adapter, REG_TSFTR1+i, tsftr[i]); + for (i=0; i<6; i++) + rtw_write8(adapter, REG_MACID1+i, macid[i]); + for (i=0; i<6; i++) + rtw_write8(adapter, REG_BSSID1+i, bssid[i]); + + /* write bcn ctl */ +#ifdef CONFIG_BT_COEXIST +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) + // 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 */ +} + +const char * const _h2c_msr_role_str[] = { + "RSVD", + "STA", + "AP", + "GC", + "GO", + "TDLS", + "ADHOC", + "INVALID", +}; + +/* +* rtw_hal_set_FwMediaStatusRpt_cmd - +* +* @adapter: +* @opmode: 0:disconnect, 1:connect +* @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario +* @miracast_sink: 0:source. 1:sink +* @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS +* @macid: +* @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end +* @macid_end: +*/ +s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end) +{ + struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl; + u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0}; + int i; + s32 ret; + + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind); + SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast); + SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink); + SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role); + SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid); + SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN); + + ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm); + if (ret != _SUCCESS) + goto exit; + +#if defined(CONFIG_RTL8188E) + if (rtw_get_chip_type(adapter) == RTL8188E) { + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + /* 8188E FW doesn't set macid no link, driver does it by self */ + if (opmode) + rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid); + else + rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid); + + /* for 8188E RA */ + #if (RATE_ADAPTIVE_SUPPORT == 1) + if (hal_data->fw_ractrl == _FALSE) { + u8 max_macid; + + max_macid = rtw_search_max_mac_id(adapter); + rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid); + } + #endif + } +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + /* TODO: this should move to IOT issue area */ + if (rtw_get_chip_type(adapter) == RTL8812 + || rtw_get_chip_type(adapter) == RTL8821 + ) { + if (MLME_IS_STA(adapter)) + Hal_PatchwithJaguar_8812(adapter, opmode); + } +#endif + + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + if (macid_ind == 0) + macid_end = macid; + + for (i = macid; macid <= macid_end; macid++) + rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]); + +exit: + return ret; +} + +inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid) +{ + return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0); +} + +inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end) +{ + return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end); +} + +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); + + ret = rtw_hal_fill_h2c_cmd(padapter, + H2C_RSVD_PAGE, + H2C_RSVDPAGE_LOC_LEN, + u1H2CRsvdPageParm); + +} + +#ifdef CONFIG_GPIO_WAKEUP +void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable) +{ + /* + * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail. + * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO, + * and implement HAL function. + * TODO: GPIO_8 multi function? + */ + if (index == 13 || index == 14) + rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable)); +} + +void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval) +{ + 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 */ + + 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); + } +} +#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 + ret = rtw_hal_fill_h2c_cmd(padapter, + H2C_AOAC_RSVD_PAGE, + H2C_AOAC_RSVDPAGE_LOC_LEN, + u1H2CAoacRsvdPageParm); + } +#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); + ret = rtw_hal_fill_h2c_cmd(padapter, + H2C_AOAC_RSVDPAGE3, + H2C_AOAC_RSVDPAGE_LOC_LEN, + u1H2CAoacRsvdPageParm); + } + } +#endif //CONFIG_PNO_SUPPORT +#endif // CONFIG_WOWLAN +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +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)); +} + +static void rtw_hal_release_rx_dma(_adapter *adapter) +{ + u32 val32 = 0; + + val32 = rtw_read32(adapter, REG_RXPKT_NUM); + + rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN))); + + DBG_871X("%s, [0x%04x]: 0x%08x\n", + __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN))); +} + +static u8 rtw_hal_pause_rx_dma(_adapter *adapter) +{ + u8 ret = 0; + s8 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 +#ifdef CONFIG_USB_HCI + else { + if (adapter->intf_start) + adapter->intf_start(adapter); + tmp = rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE; + if (tmp) { + if (adapter->intf_stop) + adapter->intf_stop(adapter); + RTW_ENABLE_FUNC(adapter, DF_RX_BIT); + RTW_ENABLE_FUNC(adapter, DF_TX_BIT); + } + } +#endif + }while(trycnt--); + + if (trycnt < 0) { + tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3); + + DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed......\n"); + DBG_871X_LEVEL(_drv_always_, "%s, RXPKT_NUM: 0x%04x\n", + __func__, tmp); + tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2); + if (tmp & BIT(3)) + DBG_871X_LEVEL(_drv_always_, "%s, RX DMA has req\n", + __func__); + else + DBG_871X_LEVEL(_drv_always_, "%s, RX DMA no req\n", + __func__); + 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 */ +#endif /* CONFIG_WOWLAN || CONFIG_AP_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(20); + } + 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(20); + } + + 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_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)); +} + +#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, -1); + 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 { + rtw_sec_read_cam_ent(adapter, cam_id, NULL, NULL, 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(index < 4); + + rtw_write8(adapter, REG_SECCFG, 0xcc); +} + +static void rtw_hal_update_gtk_offload_info(_adapter *adapter) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + u8 default_cam_id = 0; + u8 cam_id=5; + u8 *addr; + u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + u8 gtk_keyindex=0; + u8 get_key[16]; + u8 index = 1; + 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(get_key, 0, sizeof(get_key)); + + algorithm = psecuritypriv->dot11PrivacyAlgrthm; + + if(psecuritypriv->binstallKCK_KEK == _TRUE) { + + //read gtk key index + gtk_keyindex = rtw_read8(adapter, 0x48c); + do{ + /* chech if GK */ + if (rtw_sec_read_cam_is_gk(adapter, default_cam_id) == _TRUE) { + rtw_sec_read_cam_ent(adapter, default_cam_id, NULL, NULL, get_key); + algorithm = psecuritypriv->dot11PrivacyAlgrthm; + /* in default cam entry, cam id = key id */ + ctrl = BIT(15) | BIT6 | (algorithm << 2) | default_cam_id; + write_cam(adapter, cam_id, ctrl, addr, get_key); + cam_id++; + ctrl = 0; + write_cam(adapter, default_cam_id, ctrl, null_addr, get_key); + } + + if (gtk_keyindex < 4 && (default_cam_id == 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]); + } + default_cam_id++; + } while (default_cam_id < 4); + + rtw_write8(adapter, REG_SECCFG, 0x0c); +#ifdef CONFIG_GTK_OL_DBG + //if (gtk_keyindex != 5) + dump_sec_cam(RTW_DBGDUMP, 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); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_KEEP_ALIVE, + H2C_KEEP_ALIVE_CTRL_LEN, + u1H2CKeepAliveParm); + + 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); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_DISCON_DECISION, + H2C_DISCON_DECISION_LEN, + u1H2CDisconDecisionParm); + return ret; +} + +static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit) +{ + 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, gpio_pulse_en = 0; + u8 sdio_wakeup_enable = 1; + u8 gpio_high_active = 0; + u8 pattern_en = 0; + u8 magic_pkt = 0; + u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/ + u8 ret = _FAIL; + +#ifdef CONFIG_GPIO_WAKEUP + gpio_high_active = ppwrpriv->is_high_active; + gpionum = WAKEUP_GPIO_IDX; + sdio_wakeup_enable = 0; +#endif //CONFIG_GPIO_WAKEUP + + if (!ppwrpriv->wowlan_pno_enable) + magic_pkt = enable; + + if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_) + hw_unicast = 1; + else + hw_unicast = 0; + + if (ppwrpriv->wowlan_pattern) { + if (enable) + pattern_en = 1; + else + pattern_en = 0; + } + + DBG_871X("%s(): enable=%d change_unit=%d\n", __func__, + enable, change_unit); + + /* time = (gpio_dur/2) * gpio_unit, default:256 ms */ + if (enable && change_unit) { + gpio_dur = 0x40; + gpio_unit = 1; + gpio_pulse_en = 1; + } + +#ifdef CONFIG_PLATFORM_ARM_RK3188 + if (enable) { + gpio_pulse_en = 1; + gpio_pulse_cnt = 0x04; + } +#endif + + SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable); + SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, pattern_en); + 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); + +#ifdef CONFIG_GTK_OL + if (enable == _TRUE) { + /* GTK rekey only for AES, if GTK rekey is TKIP, then wake up*/ + if (psecpriv->dot118021XGrpPrivacy == _AES_) + SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0); + else if (psecpriv->dot118021XGrpPrivacy == _TKIP_) + SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1); + } +#else + 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); + SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit); + + SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en); + SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_WOWLAN, + H2C_WOWLAN_LEN, + u1H2CWoWlanCtrlParm); + 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, + !ppwrpriv->wowlan_pattern); + + /* + * filter NetBios name service pkt to avoid being waked-up + * by this kind of unicast pkt this exceptional modification + * is used for match competitor's behavior + */ + SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN( + u1H2CRemoteWakeCtrlParm, !ppwrpriv->wowlan_pattern); + + 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); + } + + SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP( + 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 + + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_REMOTE_WAKE_CTRL, + H2C_REMOTE_WAKE_CTRL_LEN, + u1H2CRemoteWakeCtrlParm); + 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); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_AOAC_GLOBAL_INFO, + H2C_AOAC_GLOBAL_INFO_LEN, + u1H2CAOACGlobalInfoParm); + + 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_NLO_IPS_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); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_D0_SCAN_OFFLOAD_INFO, + H2C_SCAN_OFFLOAD_CTRL_LEN, + u1H2CScanOffloadInfoParm); + 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, _FALSE); + + 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(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize); + dump_TX_FIFO(padapter, 4, PageSize); + } +#endif + + rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable); + } +_func_exit_; + DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__); +} +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_AP_WOWLAN +static u8 rtw_hal_set_ap_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 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0}; + u8 gpionum = 0, gpio_dur = 0; + u8 gpio_pulse = enable; + u8 sdio_wakeup_enable = 1; + u8 gpio_high_active = 0; + u8 ret = _FAIL; + +#ifdef CONFIG_GPIO_WAKEUP + gpio_high_active = ppwrpriv->is_high_active; + gpionum = WAKEUP_GPIO_IDX; + sdio_wakeup_enable = 0; +#endif /*CONFIG_GPIO_WAKEUP*/ + + DBG_871X("%s(): enable=%d\n", __func__, enable); + + SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm, + gpionum); + SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm, + gpio_pulse); + SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm, + gpio_high_active); + SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm, + enable); + SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm, + gpio_dur); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_AP_WOW_GPIO_CTRL, + H2C_AP_WOW_GPIO_CTRL_LEN, + u1H2CAPWoWlanCtrlParm); + + 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); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_AP_OFFLOAD, + H2C_AP_OFFLOAD_LEN, + u1H2CAPOffloadCtrlParm); + + return ret; +} + +static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable) +{ + struct hal_ops *pHalFunc = &adapter->HalFunc; + u8 ap_ps_parm[H2C_AP_PS_LEN] = {0}; + u8 ret = _FAIL; + + DBG_871X("%s(): enable=%d\n" , __func__ , enable); + + SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable); +#ifndef CONFIG_USB_HCI + SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable); +#endif /*CONFIG_USB_HCI*/ + SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable); + + if (enable) + SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32); + else + SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0); + + ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_, + H2C_AP_PS_LEN, ap_ps_parm); + + return ret; +} + +static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter, + PRSVDPAGE_LOC rsvdpageloc) +{ + struct hal_ops *pHalFunc = &padapter->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; + } + + header = rtw_read8(padapter, 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 = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE, + H2C_BCN_RSVDPAGE_LEN, rsvdparm); + + if (ret == _FAIL) + DBG_871X("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__); + + rtw_msleep_os(10); + + _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm)); + + SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm, + rsvdpageloc->LocProbeRsp + header); + + ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE, + H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm); + + if (ret == _FAIL) + DBG_871X("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__); + + rtw_msleep_os(10); +} + +static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable) +{ + rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable); + rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable); + rtw_hal_set_ap_ps_cmd(padapter, enable); +} + +static void rtw_hal_ap_wow_enable(_adapter *padapter) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct hal_ops *pHalFunc = &padapter->HalFunc; + struct sta_info *psta = NULL; +#ifdef DBG_CHECK_FW_PS_STATE + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +#endif /*DBG_CHECK_FW_PS_STATE*/ + int res; + u16 media_status_rpt; + + DBG_871X("%s, WOWLAN_AP_ENABLE\n", __func__); +#ifdef DBG_CHECK_FW_PS_STATE + if (rtw_fw_ps_state(padapter) == _FAIL) { + pdbgpriv->dbg_enwow_dload_fw_fail_cnt++; + DBG_871X_LEVEL(_drv_always_, "wowlan enable no leave 32k\n"); + } +#endif /*DBG_CHECK_FW_PS_STATE*/ + + /* 1. Download WOWLAN FW*/ + if (pHalFunc->hal_set_wowlan_fw != NULL) + pHalFunc->hal_set_wowlan_fw(padapter, _TRUE); + else + DBG_871X("hal_set_wowlan_fw is null\n"); + + media_status_rpt = RT_MEDIA_CONNECT; + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)&media_status_rpt); + + issue_beacon(padapter, 0); + + rtw_msleep_os(2); + + if (IS_HARDWARE_TYPE_8188E(padapter)) + rtw_hal_disable_tx_report(padapter); + + /* RX DMA stop */ + res = rtw_hal_pause_rx_dma(padapter); + 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(padapter); + if (res == _FAIL) + DBG_871X_LEVEL(_drv_always_, "[WARNING] enable cpwm2 fail\n"); +#endif + +#ifdef CONFIG_GPIO_WAKEUP + rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE); +#endif + /* 5. Set Enable WOWLAN H2C command. */ + DBG_871X_LEVEL(_drv_always_, "Set Enable AP WOWLan cmd\n"); + rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1); + + rtw_write8(padapter, REG_MCUTST_WOWLAN, 0); +#ifdef CONFIG_USB_HCI + if (padapter->intf_stop) + padapter->intf_stop(padapter); +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter))/*free buddy adapter's resource*/ + padapter->pbuddy_adapter->intf_stop(padapter->pbuddy_adapter); +#endif /*CONFIG_CONCURRENT_MODE*/ + /* Invoid SE0 reset signal during suspending*/ + rtw_write8(padapter, REG_RSV_CTRL, 0x20); + rtw_write8(padapter, REG_RSV_CTRL, 0x60); +#endif /*CONFIG_USB_HCI*/ +} + +static void rtw_hal_ap_wow_disable(_adapter *padapter) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct hal_ops *pHalFunc = &padapter->HalFunc; +#ifdef DBG_CHECK_FW_PS_STATE + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; +#endif /*DBG_CHECK_FW_PS_STATE*/ + u16 media_status_rpt; + u8 val8; + + DBG_871X("%s, WOWLAN_AP_DISABLE\n", __func__); + /* 1. Read wakeup reason*/ + pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN); + + DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n", + pwrctl->wowlan_wake_reason); + + rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0); + + rtw_msleep_os(2); +#ifdef DBG_CHECK_FW_PS_STATE + if (rtw_fw_ps_state(padapter) == _FAIL) { + pdbgpriv->dbg_diswow_dload_fw_fail_cnt++; + DBG_871X_LEVEL(_drv_always_, "wowlan enable no leave 32k\n"); + } +#endif /*DBG_CHECK_FW_PS_STATE*/ + + if (IS_HARDWARE_TYPE_8188E(padapter)) + rtw_hal_enable_tx_report(padapter); + + rtw_hal_force_enable_rxdma(padapter); + + if (pHalFunc->hal_set_wowlan_fw != NULL) + pHalFunc->hal_set_wowlan_fw(padapter, _FALSE); + else + DBG_871X("hal_set_wowlan_fw is null\n"); +#ifdef CONFIG_GPIO_WAKEUP + val8 = (pwrctl->is_high_active == 0) ? 1 : 0; + DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to default(%d).\n", val8); + rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8); +#endif + media_status_rpt = RT_MEDIA_CONNECT; + + rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)&media_status_rpt); + + issue_beacon(padapter, 0); +} +#endif /*CONFIG_AP_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, adapter_mac_addr(padapter), 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 + len = rtw_append_beacon_wfd_ie(padapter, pframe); + pframe += len; + pktlen += len; + #endif + + } +#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 +#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 = adapter_mac_addr(padapter); + + 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, mac, 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 + wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe); + pframe += wfdielen; + pktlen += wfdielen; +#endif + + *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 + + //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, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), 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 + + *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 + + //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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), 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 + + *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, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), 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 + + *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); + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_P2P_OFFLOAD_RSVD_PAGE, + H2C_P2PRSVDPAGE_LOC_LEN, + u1H2CP2PRsvdPageParm); + + 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]); + + ret = rtw_hal_fill_h2c_cmd(adapter, + H2C_P2P_OFFLOAD, + H2C_P2P_OFFLOAD_LEN, + offload_cmd); + 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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), ETH_ALEN); + break; + case Ndis802_11IBSS: + default: + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), 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; +} + +void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, + u8 *StaAddr, BOOLEAN bHideSSID) +{ + struct rtw_ieee80211_hdr *pwlanhdr; + u16 *fctrl; + u8 *mac, *bssid; + u32 pktlen; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); + + /*DBG_871X("%s\n", __FUNCTION__);*/ + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + mac = adapter_mac_addr(padapter); + bssid = cur_network->MacAddress; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); + + SetSeqNum(pwlanhdr, 0); + SetFrameSubType(fctrl, WIFI_PROBERSP); + + pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); + pframe += pktlen; + + if (cur_network->IELength > MAX_IE_SZ) + return; + + _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength); + pframe += cur_network->IELength; + pktlen += cur_network->IELength; + + *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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter)); + SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress); +#ifdef CONFIG_ARP_KEEP_ALIVE + if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) { + 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 = adapter_mac_addr(padapter); + + 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, + adapter_mac_addr(padapter), 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 + +void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index, + u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len, + RSVDPAGE_LOC *rsvd_page_loc) +{ + struct security_priv *psecuritypriv = &adapter->securitypriv; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + u32 ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0; + u32 SSIDLegnth = 0, ProbeReqLength = 0; + u8 CurtPktPageNum = 0; + 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 pno_index; + u8 ssid_num; +#endif //CONFIG_PNO_SUPPORT + + pmlmeext = &adapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + if (pwrctl->wowlan_pno_enable == _FALSE) { + //ARP RSP * 1 page + rtw_get_current_ip_address(adapter, currentip); + + rsvd_page_loc->LocArpRsp = *page_num; + + DBG_871X("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp); + + rtw_hal_construct_ARPRsp( adapter, &pframe[index], + &ARPLegnth, currentip); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index-tx_desc], + ARPLegnth, _FALSE, _FALSE, _TRUE); + + CurtPktPageNum = (u8)PageNum(tx_desc + ARPLegnth, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //3 SEC IV * 1 page + rtw_get_sec_iv(adapter, cur_dot11txpn, + get_my_bssid(&pmlmeinfo->network)); + + rsvd_page_loc->LocRemoteCtrlInfo = *page_num; + + DBG_871X("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo); + + _rtw_memcpy(pframe+index-tx_desc, cur_dot11txpn, _AES_IV_LEN_); + + CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size); + + *page_num += CurtPktPageNum; + + *total_pkt_len = index + _AES_IV_LEN_; +#ifdef CONFIG_GTK_OL + index += (CurtPktPageNum * page_size); + + //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 + rsvd_page_loc->LocGTKInfo = *page_num; + DBG_871X("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo); + + if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) { + struct security_priv *psecpriv = NULL; + + psecpriv = &adapter->securitypriv; + _rtw_memcpy(pframe+index-tx_desc, + &psecpriv->dot11PrivacyAlgrthm, 1); + _rtw_memcpy(pframe+index-tx_desc+1, + &psecpriv->dot118021XGrpPrivacy, 1); + _rtw_memcpy(pframe+index-tx_desc+2, + kck, RTW_KCK_LEN); + _rtw_memcpy(pframe+index-tx_desc+2+RTW_KCK_LEN, + kek, RTW_KEK_LEN); + CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size); + } else { + _rtw_memcpy(pframe+index-tx_desc, kck, RTW_KCK_LEN); + _rtw_memcpy(pframe+index-tx_desc+RTW_KCK_LEN, kek, RTW_KEK_LEN); + CurtPktPageNum = (u8)PageNum(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN, page_size); + } + + + +#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"); + } + + DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", + __FUNCTION__, &pframe[index-tx_desc], + (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN)); +#endif + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //3 GTK Response + rsvd_page_loc->LocGTKRsp= *page_num; + DBG_871X("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp); + rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLegnth); + + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + GTKLegnth, _FALSE, _FALSE, _TRUE); +#if 0 + { + int gj; + printk("123GTK pkt=> \n"); + for(gj=0; gj < GTKLegnth+tx_desc; gj++) { + printk(" %02x ", pframe[index-tx_desc+gj]); + if ((gj + 1)%16==0) + printk("\n"); + } + printk(" <=end\n"); + } + + DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", + __FUNCTION__, &pframe[index-tx_desc], + (tx_desc + GTKLegnth)); +#endif + + CurtPktPageNum = (u8)PageNum(tx_desc + GTKLegnth, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //below page is empty for GTK extension memory + //3(11) GTK EXT MEM + rsvd_page_loc->LocGTKEXTMEM = *page_num; + + CurtPktPageNum = 2; + + if (page_size >= 256) + CurtPktPageNum = 1; + + *page_num += CurtPktPageNum; + //extension memory for FW + *total_pkt_len = index + (page_size * CurtPktPageNum); + +#endif //CONFIG_GTK_OL + } else { +#ifdef CONFIG_PNO_SUPPORT + if (pwrctl->pno_in_resume == _FALSE && + pwrctl->pno_inited == _TRUE) { + + //Broadcast Probe Request + rsvd_page_loc->LocProbePacket = *page_num; + + DBG_871X("loc_probe_req: %d\n", + rsvd_page_loc->LocProbePacket); + + rtw_hal_construct_ProbeReq( + adapter, + &pframe[index], + &ProbeReqLength, + NULL); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index-tx_desc], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = + (u8)PageNum(tx_desc + ProbeReqLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //Hidden SSID Probe Request + ssid_num = pwrctl->pnlo_info->hidden_ssid_num; + + for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) { + pwrctl->pnlo_info->loc_probe_req[pno_index] = + *page_num; + + rtw_hal_construct_ProbeReq( + adapter, + &pframe[index], + &ProbeReqLength, + &pwrctl->pno_ssid_list->node[pno_index]); + + rtw_hal_fill_fake_txdesc(adapter, + &pframe[index - tx_desc], + ProbeReqLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = + (u8)PageNum(tx_desc + ProbeReqLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + } + + //PNO INFO Page + rsvd_page_loc->LocPNOInfo = *page_num; + DBG_871X("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo); + rtw_hal_construct_PNO_info(adapter, + &pframe[index - tx_desc], + &PNOLength); + + CurtPktPageNum = (u8)PageNum(PNOLength, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + + //SSID List Page + rsvd_page_loc->LocSSIDInfo = *page_num; + DBG_871X("LocSSIDInfo: %d\n", rsvd_page_loc->LocSSIDInfo); + rtw_hal_construct_ssid_list(adapter, + &pframe[index - tx_desc], + &SSIDLegnth); + + CurtPktPageNum = (u8)PageNum(SSIDLegnth, page_size); + *page_num += CurtPktPageNum; + index += (CurtPktPageNum * page_size); + + //Scan Info Page + rsvd_page_loc->LocScanInfo = *page_num; + DBG_871X("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo); + rtw_hal_construct_scan_info(adapter, + &pframe[index - tx_desc], + &ScanInfoLength); + + CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size); + *page_num += CurtPktPageNum; + *total_pkt_len = index + ScanInfoLength; + index += (CurtPktPageNum * page_size); + + } +#endif //CONFIG_PNO_SUPPORT + } +} + +static void rtw_hal_gate_bb(_adapter *adapter, bool stop) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + u8 val8 = 0; + u16 val16 = 0; + + if (stop) { + /* Pause TX*/ + pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE); + rtw_write8(adapter, REG_TXPAUSE, 0xff); + val8 = rtw_read8(adapter, REG_SYS_FUNC_EN); + val8 &= ~BIT(0); + rtw_write8(adapter, REG_SYS_FUNC_EN, val8); + DBG_871X("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n", + __func__, + rtw_read8(adapter, REG_SYS_FUNC_EN), + pwrpriv->wowlan_txpause_status); + } else { + val8 = rtw_read8(adapter, REG_SYS_FUNC_EN); + val8 |= BIT(0); + rtw_write8(adapter, REG_SYS_FUNC_EN, val8); + DBG_871X("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n", + __func__, rtw_read8(adapter, REG_SYS_FUNC_EN), + pwrpriv->wowlan_txpause_status); + /* release TX*/ + rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status); + } +} + +static void rtw_hal_reset_mac_rx(_adapter *adapter) +{ + u8 val8 = 0; + /* Set REG_CR bit1, bit3, bit7 to 0*/ + val8 = rtw_read8(adapter, REG_CR); + val8 &= 0x75; + rtw_write8(adapter, REG_CR, val8); + val8 = rtw_read8(adapter, REG_CR); + /* Set REG_CR bit1, bit3, bit7 to 1*/ + val8 |= 0x8a; + rtw_write8(adapter, REG_CR, val8); + DBG_871X("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR)); +} + +static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode) +{ + u8 val8 = 0; + u16 rxff_bndy = 0; + u32 rx_dma_buff_sz = 0; + + val8 = rtw_read8(adapter, REG_FIFOPAGE + 3); + if (val8 != 0) + DBG_871X("%s:[%04x]some PKTs in TXPKTBUF\n", + __func__, (REG_FIFOPAGE + 3)); + + rtw_hal_reset_mac_rx(adapter); + + if (wow_mode) { + rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW, + (u8 *)&rx_dma_buff_sz); + rxff_bndy = rx_dma_buff_sz - 1; + + rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); + DBG_871X("%s: wow mode, 0x%04x: 0x%04x\n", __func__, + REG_TRXFF_BNDY + 2, + rtw_read16(adapter, (REG_TRXFF_BNDY+2))); + } else { + rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ, + (u8 *)&rx_dma_buff_sz); + rxff_bndy = rx_dma_buff_sz - 1; + rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); + DBG_871X("%s: normal mode, 0x%04x: 0x%04x\n", __func__, + REG_TRXFF_BNDY + 2, + rtw_read16(adapter, (REG_TRXFF_BNDY+2))); + } +} + +static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern, + u8 len, u8 *mask) +{ + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter); + struct mlme_ext_priv *pmlmeext = NULL; + struct mlme_ext_info *pmlmeinfo = NULL; + struct rtl_wow_pattern wow_pattern; + u8 mask_hw[MAX_WKFM_SIZE] = {0}; + u8 content[MAX_WKFM_PATTERN_SIZE] = {0}; + u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 multicast_addr1[2] = {0x33, 0x33}; + u8 multicast_addr2[3] = {0x01, 0x00, 0x5e}; + u8 res = _FALSE, index = 0, mask_len = 0; + u8 mac_addr[ETH_ALEN] = {0}; + u16 count = 0; + int i, j; + + if (pwrctl->wowlan_pattern_idx > MAX_WKFM_NUM) { + DBG_871X("%s pattern_idx is more than MAX_FMC_NUM: %d\n", + __func__, MAX_WKFM_NUM); + return _FALSE; + } + + pmlmeext = &adapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN); + _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern)); + + mask_len = DIV_ROUND_UP(len, 8); + + /* 1. setup A1 table */ + if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0) + wow_pattern.type = PATTERN_BROADCAST; + else if (memcmp(pattern, multicast_addr1, 2) == 0) + wow_pattern.type = PATTERN_MULTICAST; + else if (memcmp(pattern, multicast_addr2, 3) == 0) + wow_pattern.type = PATTERN_MULTICAST; + else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0) + wow_pattern.type = PATTERN_UNICAST; + else + wow_pattern.type = PATTERN_INVALID; + + /* translate mask from os to mask for hw */ + +/****************************************************************************** + * pattern from OS uses 'ethenet frame', like this: + + | 6 | 6 | 2 | 20 | Variable | 4 | + |--------+--------+------+-----------+------------+-----| + | 802.3 Mac Header | IP Header | TCP Packet | FCS | + | DA | SA | Type | + + * BUT, packet catched by our HW is in '802.11 frame', begin from LLC, + + | 24 or 30 | 6 | 2 | 20 | Variable | 4 | + |-------------------+--------+------+-----------+------------+-----| + | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | + | Others | Tpye | + + * Therefore, we need translate mask_from_OS to mask_to_hw. + * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, + * because new mask[0~5] means 'SA', but our HW packet begins from LLC, + * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. + ******************************************************************************/ + /* Shift 6 bits */ + for (i = 0; i < mask_len - 1; i++) { + mask_hw[i] = mask[i] >> 6; + mask_hw[i] |= (mask[i + 1] & 0x3F) << 2; + } + + mask_hw[i] = (mask[i] >> 6) & 0x3F; + /* Set bit 0-5 to zero */ + mask_hw[0] &= 0xC0; + + for (i = 0; i < (MAX_WKFM_SIZE/4); i++) { + wow_pattern.mask[i] = mask_hw[i * 4]; + wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8); + wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16); + wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24); + } + + /* To get the wake up pattern from the mask. + * We do not count first 12 bits which means + * DA[6] and SA[6] in the pattern to match HW design. */ + count = 0; + for (i = 12; i < len; i++) { + if ((mask[i / 8] >> (i % 8)) & 0x01) { + content[count] = pattern[i]; + count++; + } + } + + wow_pattern.crc = rtw_calc_crc(content, count); + + if (wow_pattern.crc != 0) { + if (wow_pattern.type == PATTERN_INVALID) + wow_pattern.type = PATTERN_VALID; + } + + index = rtw_read8(adapter, REG_WKFMCAM_NUM); + + if (!pwrctl->bInSuspend) + index += 2; + + /* write pattern */ + res = rtw_write_to_frame_mask(adapter, index, &wow_pattern); + + if (res == _TRUE) { + pwrctl->wowlan_pattern_idx++; + rtw_write8(adapter, + REG_WKFMCAM_NUM, + pwrctl->wowlan_pattern_idx); + } else { + DBG_871X("%s: ERROR write_to_frame_mask_cam fail\n", __func__); + } + + return res; +} + +static void rtw_hal_dl_pattern(_adapter *adapter, u8 clean_all) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter); + int i = 0, total = 0; + + total = pwrpriv->wowlan_pattern_idx; + + rtw_clean_pattern(adapter); + + if (!clean_all) { + for (i = 0 ; i < total ; i++) { + rtw_hal_set_pattern(adapter, + pwrpriv->patterns[i].content, + pwrpriv->patterns[i].len, + pwrpriv->patterns[i].mask); + } + DBG_871X("pattern downloaded\n"); + } else { + for (i = 0 ; i < MAX_WKFM_NUM ; i++) { + _rtw_memset(pwrpriv->patterns[i].content, '\0', + sizeof(pwrpriv->patterns[i].content)); + _rtw_memset(pwrpriv->patterns[i].mask, '\0', + sizeof(pwrpriv->patterns[i].mask)); + pwrpriv->patterns[i].len = 0; + } + DBG_871X("clean all pattern\n"); + } +} + +static void rtw_hal_wow_enable(_adapter *adapter) +{ + 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; + + + DBG_871X_LEVEL(_drv_always_, "%s, WOWLAN_ENABLE\n", __func__); + rtw_hal_gate_bb(adapter, _TRUE); +#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); + + /* RX DMA stop */ + if (IS_HARDWARE_TYPE_8188E(adapter)) + rtw_hal_disable_tx_report(adapter); + + res = rtw_hal_pause_rx_dma(adapter); + if (res == _FAIL) + DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n"); + + /* Reconfig RX_FF Boundary */ + rtw_hal_set_wow_rxff_boundary(adapter, _TRUE); + + /* redownload pattern match */ + if (pwrctl->wowlan_pattern) + rtw_hal_dl_pattern(adapter, _FALSE); + + rtw_hal_set_wowlan_fw(adapter, _TRUE); + media_status_rpt = RT_MEDIA_CONNECT; + rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)&media_status_rpt); + + if (!pwrctl->wowlan_pno_enable) { + psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv)); + if (psta != NULL) + rtw_sta_media_status_rpt(adapter, psta, 1); + } + +#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 +#ifdef CONFIG_GPIO_WAKEUP + rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE); +#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_sec_cam(RTW_DBGDUMP, adapter); +#endif +#ifdef CONFIG_USB_HCI + if (adapter->intf_stop) /* free adapter's resource */ + adapter->intf_stop(adapter); + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(adapter)) /*free buddy adapter's resource*/ + adapter->pbuddy_adapter->intf_stop(adapter->pbuddy_adapter); +#endif /*CONFIG_CONCURRENT_MODE*/ + /* Invoid SE0 reset signal during suspending*/ + rtw_write8(adapter, REG_RSV_CTRL, 0x20); + rtw_write8(adapter, REG_RSV_CTRL, 0x60); +#endif /*CONFIG_USB_HCI*/ + + rtw_hal_gate_bb(adapter, _FALSE); +} + +static void rtw_hal_wow_disable(_adapter *adapter) +{ + 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; + + DBG_871X_LEVEL(_drv_always_, "%s, WOWLAN_DISABLE\n", __func__); + + if (!pwrctl->wowlan_pno_enable) { + psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv)); + if (psta != NULL) + rtw_sta_media_status_rpt(adapter, psta, 0); + 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); + } + + rtw_hal_gate_bb(adapter, _TRUE); + + res = rtw_hal_pause_rx_dma(adapter); + if (res == _FAIL) + DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n"); + + /* clean pattern match */ + if (pwrctl->wowlan_pattern) + rtw_hal_dl_pattern(adapter, _TRUE); + + /* config RXFF boundary to original */ + rtw_hal_set_wow_rxff_boundary(adapter, _FALSE); + + rtw_hal_release_rx_dma(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*/ + + rtw_hal_set_wowlan_fw(adapter, _FALSE); + +#ifdef CONFIG_GPIO_WAKEUP + val8 = (pwrctl->is_high_active == 0) ? 1 : 0; + DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to default(%d).\n", val8); + rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8); +#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)) { + + media_status_rpt = RT_MEDIA_CONNECT; + rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT, + (u8 *)&media_status_rpt); + + if (psta != NULL) + rtw_sta_media_status_rpt(adapter, psta, 1); + } + rtw_hal_gate_bb(adapter, _FALSE); +} +#endif /*CONFIG_WOWLAN*/ + +#ifdef CONFIG_P2P_WOWLAN +void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter* adapter, u8 *pframe, u16 index, + u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len, + RSVDPAGE_LOC* rsvd_page_loc) +{ + u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0; + u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0; + u8 CurtPktPageNum = 0; + + /* P2P Beacon */ + rsvd_page_loc->LocP2PBeacon = *page_num; + rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + P2PBCNLength, _FALSE, _FALSE, _FALSE); + +#if 0 + DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", + __FUNCTION__, &pframe[index-tx_desc], (P2PBCNLength+tx_desc)); +#endif + + CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + // P2P Probe rsp + rsvd_page_loc->LocP2PProbeRsp = *page_num; + rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index], + &P2PProbeRspLength); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + P2PProbeRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", + // __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); + + CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //P2P nego rsp + rsvd_page_loc->LocNegoRsp = *page_num; + rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index], + &P2PNegoRspLength); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + P2PNegoRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + // __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); + + CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //P2P invite rsp + rsvd_page_loc->LocInviteRsp = *page_num; + rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index], + &P2PInviteRspLength); + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + P2PInviteRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + //__FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); + + CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size); + + *page_num += CurtPktPageNum; + + index += (CurtPktPageNum * page_size); + + //P2P provision discovery rsp + rsvd_page_loc->LocPDRsp = *page_num; + rtw_hal_construct_P2PProvisionDisRsp( adapter, + &pframe[index], &P2PPDRspLength); + + rtw_hal_fill_fake_txdesc(adapter, &pframe[index-tx_desc], + P2PPDRspLength, _FALSE, _FALSE, _FALSE); + + //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", + // __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); + + CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size); + + *page_num += CurtPktPageNum; + + *total_pkt_len = index + P2PPDRspLength; + + index += (CurtPktPageNum * page_size); + + +} +#endif //CONFIG_P2P_WOWLAN + +/* + * 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 DBG_CONFIG_ERROR_DETECT + struct sreset_priv *psrtpriv; +#endif /* DBG_CONFIG_ERROR_DETECT */ + + + 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); + + if (PageSize == 0) { + DBG_871X("[Error]: %s, PageSize is zero!!\n", __func__); + return; + } + + if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE) + RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE); + else + RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE); + + DBG_871X("%s PageSize: %d, RsvdPageNUm: %d\n",__func__, PageSize, RsvdPageNum); + + MaxRsvdPageBufSize = RsvdPageNum*PageSize; + + if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) { + DBG_871X("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)", + __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ); + rtw_warn_on(1); + return; + } + + 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((TxDescLen + BeaconLength), PageSize); + /* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/ + if (CurtPktPageNum == 1) + CurtPktPageNum += 1; + + TotalPageNum += CurtPktPageNum; + + BufIndex += (CurtPktPageNum*PageSize); + + if (pwrctl->wowlan_ap_mode == _TRUE) { + /* (4) probe response*/ + RsvdPageLoc.LocProbeRsp = TotalPageNum; + rtw_hal_construct_ProbeRsp( + adapter, &ReservedPagePacket[BufIndex], + &ProbeRspLength, + get_my_bssid(&pmlmeinfo->network), _FALSE); + rtw_hal_fill_fake_txdesc(adapter, + &ReservedPagePacket[BufIndex-TxDescLen], + ProbeRspLength, _FALSE, _FALSE, _FALSE); + + CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize); + TotalPageNum += CurtPktPageNum; + TotalPacketLen = BufIndex + ProbeRspLength; + BufIndex += (CurtPktPageNum*PageSize); + goto download_page; + } + + /* 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; + + TotalPacketLen = BufIndex + QosNullLength; + + BufIndex += (CurtPktPageNum*PageSize); + +#ifdef CONFIG_WOWLAN + if (pwrctl->wowlan_mode == _TRUE && + check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket, + BufIndex, TxDescLen, PageSize, + &TotalPageNum, &TotalPacketLen, &RsvdPageLoc); + } +#endif /* CONFIG_WOWLAN */ + +#ifdef CONFIG_P2P_WOWLAN + if(_TRUE == pwrctl->wowlan_p2p_mode) { + rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket, + BufIndex, TxDescLen, PageSize, + &TotalPageNum, &TotalPacketLen, &RsvdPageLoc); + } +#endif /* CONFIG_P2P_WOWLAN */ + +download_page: + /* DBG_871X("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/ + DBG_871X("%s PageNum(%d), pktlen(%d)\n", + __func__, TotalPageNum, TotalPacketLen); + + if (TotalPacketLen > MaxRsvdPageBufSize) { + DBG_871X("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n", + __FUNCTION__, TotalPacketLen,MaxRsvdPageBufSize); + rtw_warn_on(1); + goto error; + } else { + /* update attribute */ + pattrib = &pcmdframe->attrib; + update_mgntframe_attrib(adapter, pattrib); + pattrib->qsel = QSLT_BEACON; + pattrib->pktlen = TotalPacketLen - TxDescOffset; + pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; +#ifdef CONFIG_PCI_HCI + dump_mgntframe(adapter, pcmdframe); +#else + dump_mgntframe_and_wait(adapter, pcmdframe, 100); +#endif + } + + 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); +#ifdef CONFIG_AP_WOWLAN + if (pwrctl->wowlan_ap_mode == _TRUE) + rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc); +#endif /* CONFIG_AP_WOWLAN */ + } 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); +} + +void SetHwReg(_adapter *adapter, u8 variable, u8 *val) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); +_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; + + if (IS_8188E(*hal_ver)) { + + 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); + } + } + 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_ori; + u16 reg_scr; + + reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG); + reg_scr |= (SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable); + + if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC)) + reg_scr |= SCR_CHK_BMC; + + if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH)) + reg_scr |= SCR_NoSKMC; + + if (reg_scr != reg_scr_ori) + rtw_write16(adapter, REG_SECCFG, reg_scr); + #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 */ + { + 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_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; +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + case HW_VAR_WOWLAN: + { + struct wowlan_ioctl_param *poidparam; + + poidparam = (struct wowlan_ioctl_param *)val; + switch (poidparam->subcode) { +#ifdef CONFIG_WOWLAN + case WOWLAN_PATTERN_CLEAN: + rtw_hal_dl_pattern(adapter, _TRUE); + break; + case WOWLAN_ENABLE: + rtw_hal_wow_enable(adapter); + break; + case WOWLAN_DISABLE: + rtw_hal_wow_disable(adapter); + break; +#endif /*CONFIG_WOWLAN*/ +#ifdef CONFIG_AP_WOWLAN + case WOWLAN_AP_ENABLE: + rtw_hal_ap_wow_enable(adapter); + break; + case WOWLAN_AP_DISABLE: + rtw_hal_ap_wow_disable(adapter); + break; +#endif /*CONFIG_AP_WOWLAN*/ + default: + break; + } + } + break; +#endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_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_; +} + +void GetHwReg(_adapter *adapter, u8 variable, u8 *val) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + +_func_enter_; + + switch (variable) { + case HW_VAR_BASIC_RATE: + *((u16*)val) = hal_data->BasicRateSet; + break; + case HW_VAR_RF_TYPE: + *((u8*)val) = hal_data->rf_type; + break; + default: + if (0) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n", + FUNC_ADPT_ARG(adapter), variable); + break; + } + +_func_exit_; +} + +u8 +SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 bResult = _SUCCESS; + + switch(variable) { + + case HAL_DEF_DBG_DUMP_RXPKT: + hal_data->bDumpRxPkt = *((u8*)value); + break; + case HAL_DEF_DBG_DUMP_TXPKT: + hal_data->bDumpTxPkt = *((u8*)value); + break; + 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; + break; + } + + return bResult; +} + +#ifdef CONFIG_BEAMFORMING +u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter) +{ + struct registry_priv *pregistrypriv = &adapter->registrypriv; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter))) + return pregistrypriv->beamformer_rf_num; + else if (IS_HARDWARE_TYPE_8814AE(adapter) +/* +#if defined(CONFIG_USB_HCI) + || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) //for USB3.0 +#endif +*/ + ) { + /*BF cap provided by Yu Chen, Sean, 2015, 01 */ + if (hal_data->rf_type == RF_3T3R) + return 2; + else if (hal_data->rf_type == RF_4T4R) + return 3; + else + return 1; + } else + return 1; + +} +u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter) +{ + struct registry_priv *pregistrypriv = &adapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter))) + return pregistrypriv->beamformee_rf_num; + else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) { + if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) + return 2; + else + return 2;/*TODO: May be 3 in the future, by ChenYu. */ + } else + return 1; + +} +#endif + +u8 +GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 bResult = _SUCCESS; + + switch(variable) { + case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: + { + struct mlme_priv *pmlmepriv; + struct sta_priv *pstapriv; + struct sta_info *psta; + + pmlmepriv = &adapter->mlmepriv; + pstapriv = &adapter->stapriv; + psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress); + if (psta) + { + *((int*)value) = psta->rssi_stat.UndecoratedSmoothedPWDB; + } + } + break; + case HAL_DEF_DBG_DUMP_RXPKT: + *((u8*)value) = hal_data->bDumpRxPkt; + break; + case HAL_DEF_DBG_DUMP_TXPKT: + *((u8*)value) = hal_data->bDumpTxPkt; + break; + case HAL_DEF_ANT_DETECT: + *((u8 *)value) = hal_data->AntDetection; + break; + case HAL_DEF_MACID_SLEEP: + *(u8*)value = _FALSE; + break; + case HAL_DEF_TX_PAGE_SIZE: + *(( u32*)value) = PAGE_SIZE_128; + break; + case HAL_DEF_DBG_DIS_PWT: + *(u8*)value = hal_data->bDisableTXPowerTraining; + break; +#ifdef CONFIG_BEAMFORMING + case HAL_DEF_BEAMFORMER_CAP: + *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter); + break; + case HAL_DEF_BEAMFORMEE_CAP: + *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter); + break; +#endif + default: + DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable); + bResult = _FAIL; + break; + } + + return bResult; +} + +void SetHalODMVar( + PADAPTER Adapter, + HAL_ODM_VARIABLE eVariable, + PVOID pValue1, + BOOLEAN bSet) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T podmpriv = &pHalData->odmpriv; + //_irqL irqL; + switch(eVariable){ + case HAL_ODM_STA_INFO: + { + struct sta_info *psta = (struct sta_info *)pValue1; + if(bSet){ + DBG_8192C("### Set STA_(%d) info ###\n",psta->mac_id); + ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,psta); + } + else{ + DBG_8192C("### Clean STA_(%d) info ###\n",psta->mac_id); + //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); + ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,NULL); + + //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); + } + } + break; + case HAL_ODM_P2P_STATE: + ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DIRECT,bSet); + break; + 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: + { + struct noise_info *pinfo = (struct noise_info *)pValue1; + + #ifdef DBG_NOISE_MONITOR + DBG_8192C("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n", + pinfo->chan,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time); + #endif + + pHalData->noise[pinfo->chan] = ODM_InbandNoise_Monitor(podmpriv,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time); + DBG_871X("chan_%d, noise = %d (dBm)\n",pinfo->chan,pHalData->noise[pinfo->chan]); + #ifdef DBG_NOISE_MONITOR + DBG_871X("noise_a = %d, noise_b = %d noise_all:%d \n", + podmpriv->noise_level.noise[ODM_RF_PATH_A], + podmpriv->noise_level.noise[ODM_RF_PATH_B], + podmpriv->noise_level.noise_all); + #endif + } + break; +#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/ + + case HAL_ODM_INITIAL_GAIN: + { + u8 rx_gain = *((u8 *)(pValue1)); + /*printk("rx_gain:%x\n",rx_gain);*/ + if (rx_gain == 0xff) {/*restore rx gain*/ + /*ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);*/ + odm_PauseDIG(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain); + } else { + /*pDigTable->BackupIGValue = pDigTable->CurIGValue;*/ + /*ODM_Write_DIG(podmpriv,rx_gain);*/ + odm_PauseDIG(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain); + } + } + break; + case HAL_ODM_FA_CNT_DUMP: + if (*((u8 *)pValue1)) + podmpriv->DebugComponents |= (ODM_COMP_DIG | ODM_COMP_FA_CNT); + else + podmpriv->DebugComponents &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT); + break; + case HAL_ODM_DBG_FLAG: + ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_COMP, *((u8Byte *)pValue1)); + break; + case HAL_ODM_DBG_LEVEL: + ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u4Byte *)pValue1)); + break; + case HAL_ODM_RX_INFO_DUMP: + { + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure(podmpriv , PHYDM_FALSEALMCNT); + pDIG_T pDM_DigTable = &podmpriv->DM_DigTable; + + DBG_871X("============ Rx Info dump ===================\n"); + DBG_871X("bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x\n", + podmpriv->bLinked, podmpriv->RSSI_Min, pDM_DigTable->CurIGValue); + if (FalseAlmCnt) + DBG_871X("Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n", + FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all); + + if (podmpriv->bLinked) { + DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", + HDATA_RATE(podmpriv->RxRate), podmpriv->RSSI_A, podmpriv->RSSI_B); + + #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA + rtw_dump_raw_rssi_info(Adapter); + #endif + } + } + break; + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + case HAL_ODM_AUTO_CHNL_SEL: + { + ACS_OP acs_op = *(ACS_OP *)pValue1; + + rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT); + + if (ACS_INIT == acs_op) { + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter)); + #endif + odm_AutoChannelSelectInit(podmpriv); + } else if (ACS_RESET == acs_op) { + /* Reset statistics for auto channel selection mechanism.*/ + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter)); + #endif + odm_AutoChannelSelectReset(podmpriv); + + } else if (ACS_SELECT == acs_op) { + /* Collect NHM measurement result after current channel */ + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter)); + #endif + odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter)); + } else + DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter)); + + } + break; +#endif + + default: + break; + } +} + +void GetHalODMVar( + PADAPTER Adapter, + HAL_ODM_VARIABLE eVariable, + PVOID pValue1, + PVOID pValue2) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T podmpriv = &pHalData->odmpriv; + + switch (eVariable) { +#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + case HAL_ODM_NOISE_MONITOR: + { + u8 chan = *(u8 *)pValue1; + *(s16 *)pValue2 = pHalData->noise[chan]; + #ifdef DBG_NOISE_MONITOR + DBG_8192C("### Noise monitor chan(%d)-noise:%d (dBm) ###\n", + chan, pHalData->noise[chan]); + #endif + } + break; +#endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/ + case HAL_ODM_DBG_FLAG: + *((u8Byte *)pValue1) = podmpriv->DebugComponents; + break; + case HAL_ODM_DBG_LEVEL: + *((u4Byte *)pValue1) = podmpriv->DebugLevel; + break; + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + case HAL_ODM_AUTO_CHNL_SEL: + { + #ifdef DBG_AUTO_CHNL_SEL_NHM + DBG_871X("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter)); + #endif + /* Retrieve better channel from NHM mechanism */ + if (IsSupported24G(Adapter->registrypriv.wireless_mode)) + *((u8 *)(pValue1)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_2_4G); + if (IsSupported5G(Adapter->registrypriv.wireless_mode)) + *((u8 *)(pValue2)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_5G); + } + break; +#endif + + default: + break; + } +} + + +u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); + PDM_ODM_T podmpriv = &pHalData->odmpriv; + u32 result = 0; + + switch (ops) { + case HAL_PHYDM_DIS_ALL_FUNC: + podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE; + break; + case HAL_PHYDM_FUNC_SET: + podmpriv->SupportAbility |= ability; + break; + case HAL_PHYDM_FUNC_CLR: + podmpriv->SupportAbility &= ~(ability); + break; + case HAL_PHYDM_ABILITY_BK: + /* dm flag backup*/ + podmpriv->BK_SupportAbility = podmpriv->SupportAbility; + break; + case HAL_PHYDM_ABILITY_RESTORE: + /* restore dm flag */ + podmpriv->SupportAbility = podmpriv->BK_SupportAbility; + break; + case HAL_PHYDM_ABILITY_SET: + podmpriv->SupportAbility = ability; + break; + case HAL_PHYDM_ABILITY_GET: + result = podmpriv->SupportAbility; + break; + } + return result; +} + + +BOOLEAN +eqNByte( + u8* str1, + u8* str2, + u32 num + ) +{ + if(num==0) + return _FALSE; + while(num>0) + { + num--; + if(str1[num]!=str2[num]) + return _FALSE; + } + return _TRUE; +} + +// +// Description: +// Translate a character to hex digit. +// +u32 +MapCharToHexDigit( + IN char chTmp +) +{ + if(chTmp >= '0' && chTmp <= '9') + return (chTmp - '0'); + else if(chTmp >= 'a' && chTmp <= 'f') + return (10 + (chTmp - 'a')); + else if(chTmp >= 'A' && chTmp <= 'F') + return (10 + (chTmp - 'A')); + else + return 0; +} + + + +// +// Description: +// Parse hex number from the string pucStr. +// +BOOLEAN +GetHexValueFromString( + IN char* szStr, + IN OUT u32* pu4bVal, + IN OUT u32* pu4bMove +) +{ + char* szScan = szStr; + + // Check input parameter. + if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) + { + DBG_871X("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove); + return _FALSE; + } + + // Initialize output. + *pu4bMove = 0; + *pu4bVal = 0; + + // Skip leading space. + while( *szScan != '\0' && + (*szScan == ' ' || *szScan == '\t') ) + { + szScan++; + (*pu4bMove)++; + } + + // Skip leading '0x' or '0X'. + if(*szScan == '0' && (*(szScan+1) == 'x' || *(szScan+1) == 'X')) + { + szScan += 2; + (*pu4bMove) += 2; + } + + // Check if szScan is now pointer to a character for hex digit, + // if not, it means this is not a valid hex number. + if(!IsHexDigit(*szScan)) + { + return _FALSE; + } + + // Parse each digit. + do + { + (*pu4bVal) <<= 4; + *pu4bVal += MapCharToHexDigit(*szScan); + + szScan++; + (*pu4bMove)++; + } while(IsHexDigit(*szScan)); + + return _TRUE; +} + +BOOLEAN +GetFractionValueFromString( + IN char* szStr, + IN OUT u8* pInteger, + IN OUT u8* pFraction, + IN OUT u32* pu4bMove +) +{ + char *szScan = szStr; + + // Initialize output. + *pu4bMove = 0; + *pInteger = 0; + *pFraction = 0; + + // Skip leading space. + while ( *szScan != '\0' && (*szScan == ' ' || *szScan == '\t') ) { + ++szScan; + ++(*pu4bMove); + } + + // Parse each digit. + do { + (*pInteger) *= 10; + *pInteger += ( *szScan - '0' ); + + ++szScan; + ++(*pu4bMove); + + if ( *szScan == '.' ) + { + ++szScan; + ++(*pu4bMove); + + if ( *szScan < '0' || *szScan > '9' ) + return _FALSE; + else { + *pFraction = *szScan - '0'; + ++szScan; + ++(*pu4bMove); + return _TRUE; + } + } + } while(*szScan >= '0' && *szScan <= '9'); + + return _TRUE; +} + +// +// Description: +// Return TRUE if szStr is comment out with leading "//". +// +BOOLEAN +IsCommentString( + IN char *szStr +) +{ + if(*szStr == '/' && *(szStr+1) == '/') + { + return _TRUE; + } + else + { + return _FALSE; + } +} + +BOOLEAN +GetU1ByteIntegerFromStringInDecimal( + IN char* Str, + IN OUT u8* pInt + ) +{ + u16 i = 0; + *pInt = 0; + + while ( Str[i] != '\0' ) + { + if ( Str[i] >= '0' && Str[i] <= '9' ) + { + *pInt *= 10; + *pInt += ( Str[i] - '0' ); + } + else + { + return _FALSE; + } + ++i; + } + + return _TRUE; +} + +// <20121004, Kordan> For example, +// ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]". +// If RightQualifier does not exist, it will hang on in the while loop +BOOLEAN +ParseQualifiedString( + IN char* In, + IN OUT u32* Start, + OUT char* Out, + IN char LeftQualifier, + IN char RightQualifier + ) +{ + u32 i = 0, j = 0; + char c = In[(*Start)++]; + + if (c != LeftQualifier) + return _FALSE; + + i = (*Start); + while ((c = In[(*Start)++]) != RightQualifier) + ; // find ']' + j = (*Start) - 2; + strncpy((char *)Out, (const char*)(In+i), j-i+1); + + return _TRUE; +} + +BOOLEAN +isAllSpaceOrTab( + u8* data, + u8 size + ) +{ + u8 cnt = 0, NumOfSpaceAndTab = 0; + + while( size > cnt ) + { + if ( data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0' ) + ++NumOfSpaceAndTab; + + ++cnt; + } + + return size == NumOfSpaceAndTab; +} + + +void rtw_hal_check_rxfifo_full(_adapter *adapter) +{ + struct dvobj_priv *psdpriv = adapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter); + int save_cnt=_FALSE; + + //switch counter to RX fifo + if (IS_8188E(pHalData->VersionID) || IS_8188F(pHalData->VersionID) + || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID) + || IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID) || IS_8703B_SERIES(pHalData->VersionID)) + { + rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); + save_cnt = _TRUE; + } + else + { + //todo: other chips + } + + + if (save_cnt) { + pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow; + pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT); + pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow; + } else { + /* special value to indicate no implementation */ + pdbgpriv->dbg_rx_fifo_last_overflow = 1; + pdbgpriv->dbg_rx_fifo_curr_overflow = 1; + pdbgpriv->dbg_rx_fifo_diff_overflow = 1; + } +} + +void linked_info_dump(_adapter *padapter,u8 benable) +{ + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + if(padapter->bLinkInfoDump == benable) + return; + + DBG_871X("%s %s \n",__FUNCTION__,(benable)?"enable":"disable"); + + if(benable){ + #ifdef CONFIG_LPS + pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;//keep org value + rtw_pm_set_lps(padapter,PS_MODE_ACTIVE); + #endif + + #ifdef CONFIG_IPS + pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;//keep org value + rtw_pm_set_ips(padapter,IPS_NONE); + #endif + } + else{ + #ifdef CONFIG_IPS + rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode); + #endif // CONFIG_IPS + + #ifdef CONFIG_LPS + rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt ); + #endif // CONFIG_LPS + } + padapter->bLinkInfoDump = benable ; +} + +#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA +void rtw_get_raw_rssi_info(void *sel, _adapter *padapter) +{ + u8 isCCKrate,rf_path; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; + + DBG_871X_SEL_NL(sel,"RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", + HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); + isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE; + + if(isCCKrate) + psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; + + for(rf_path = 0;rf_pathNumTotalRFPath;rf_path++) + { + DBG_871X_SEL_NL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n" + , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]); + + if(!isCCKrate){ + DBG_871X_SEL_NL(sel,"\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", + psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]); + } + } +} + +void rtw_dump_raw_rssi_info(_adapter *padapter) +{ + u8 isCCKrate,rf_path; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; + DBG_871X("============ RAW Rx Info dump ===================\n"); + DBG_871X("RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", + HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); + + isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE; + + if(isCCKrate) + psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball; + + for(rf_path = 0;rf_pathNumTotalRFPath;rf_path++) + { + DBG_871X("RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)" + , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]); + + if(!isCCKrate){ + printk(",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", + psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]); + }else{ + printk("\n"); + } + } +} + +void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe) +{ + u8 isCCKrate,rf_path; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + + PODM_PHY_INFO_T pPhyInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); + struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info; + + psample_pkt_rssi->data_rate = pattrib->data_rate; + isCCKrate = (pattrib->data_rate <= DESC_RATE11M)?TRUE :FALSE; + + psample_pkt_rssi->pwdball = pPhyInfo->RxPWDBAll; + psample_pkt_rssi->pwr_all = pPhyInfo->RecvSignalPower; + + for(rf_path = 0;rf_pathNumTotalRFPath;rf_path++) + { + psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->RxMIMOSignalStrength[rf_path]; + psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->RxMIMOSignalQuality[rf_path]; + if(!isCCKrate){ + psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path]; + psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path]; + } + } +} +#endif + +int check_phy_efuse_tx_power_info_valid(PADAPTER padapter) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8* pContent = pHalData->efuse_eeprom_data; + int index = 0; + u16 tx_index_offset = 0x0000; + + switch (rtw_get_chip_type(padapter)) { + case RTL8723B: + tx_index_offset = EEPROM_TX_PWR_INX_8723B; + break; + case RTL8703B: + tx_index_offset = EEPROM_TX_PWR_INX_8703B; + break; + case RTL8188E: + tx_index_offset = EEPROM_TX_PWR_INX_88E; + break; + case RTL8188F: + tx_index_offset = EEPROM_TX_PWR_INX_8188F; + break; + case RTL8192E: + tx_index_offset = EEPROM_TX_PWR_INX_8192E; + break; + case RTL8821: + tx_index_offset = EEPROM_TX_PWR_INX_8821; + break; + case RTL8812: + tx_index_offset = EEPROM_TX_PWR_INX_8812; + break; + case RTL8814A: + tx_index_offset = EEPROM_TX_PWR_INX_8814; + break; + default: + tx_index_offset = 0x0010; + break; + } + + /* TODO: chacking length by ICs */ + for (index = 0 ; index < 11 ; index++) { + if (pContent[tx_index_offset + index] == 0xFF) + return _FALSE; + } + return _TRUE; +} + +int hal_efuse_macaddr_offset(_adapter *adapter) +{ + u8 interface_type = 0; + int addr_offset = -1; + + interface_type = rtw_get_intf_type(adapter); + + switch (rtw_get_chip_type(adapter)) { +#ifdef CONFIG_RTL8723B + case RTL8723B: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8723BU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8723BS; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_8723BE; + break; +#endif +#ifdef CONFIG_RTL8703B + case RTL8703B: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8703BU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8703BS; + break; +#endif +#ifdef CONFIG_RTL8188E + case RTL8188E: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_88EU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_88ES; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_88EE; + break; +#endif +#ifdef CONFIG_RTL8188F + case RTL8188F: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8188FU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8188FS; + break; +#endif +#ifdef CONFIG_RTL8812A + case RTL8812: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8812AU; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_8812AE; + break; +#endif +#ifdef CONFIG_RTL8821A + case RTL8821: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8821AU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8821AS; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_8821AE; + break; +#endif +#ifdef CONFIG_RTL8192E + case RTL8192E: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8192EU; + else if (interface_type == RTW_SDIO) + addr_offset = EEPROM_MAC_ADDR_8192ES; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_8192EE; + break; +#endif +#ifdef CONFIG_RTL8814A + case RTL8814A: + if (interface_type == RTW_USB) + addr_offset = EEPROM_MAC_ADDR_8814AU; + else if (interface_type == RTW_PCIE) + addr_offset = EEPROM_MAC_ADDR_8814AE; + break; +#endif + } + + if (addr_offset == -1) { + DBG_871X_LEVEL(_drv_err_, "%s: unknown combination - chip_type:%u, interface:%u\n" + , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter)); + } + + return addr_offset; +} + +int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr) +{ + int ret = _FAIL; + int addr_offset; + + addr_offset = hal_efuse_macaddr_offset(padapter); + if (addr_offset == -1) + goto exit; + + ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr); + +exit: + return ret; +} + +#ifdef CONFIG_EFUSE_CONFIG_FILE +u32 Hal_readPGDataFromConfigFile(PADAPTER padapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + u32 ret; + + ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data); + hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED); + + return ret; +} + +u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + u32 ret = _FAIL; + + if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS + && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE + ) { + hal_data->macaddr_file_status = MACADDR_FILE_LOADED; + ret = _SUCCESS; + } else { + hal_data->macaddr_file_status = MACADDR_FILE_FAILED; + } + + return ret; +} +#endif /* CONFIG_EFUSE_CONFIG_FILE */ + +int hal_config_macaddr(_adapter *adapter, bool autoload_fail) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + u8 addr[ETH_ALEN]; + int addr_offset = hal_efuse_macaddr_offset(adapter); + u8 *hw_addr = NULL; + int ret = _SUCCESS; + + if (autoload_fail) + goto bypass_hw_pg; + + if (addr_offset != -1) + hw_addr = &hal_data->efuse_eeprom_data[addr_offset]; + +#ifdef CONFIG_EFUSE_CONFIG_FILE + /* if the hw_addr is written by efuse file, set to NULL */ + if (hal_data->efuse_file_status == EFUSE_FILE_LOADED) + hw_addr = NULL; +#endif + + if (!hw_addr) { + /* try getting hw pg data */ + if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS) + hw_addr = addr; + } + + /* check hw pg data */ + if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) { + _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN); + goto exit; + } + +bypass_hw_pg: + +#ifdef CONFIG_EFUSE_CONFIG_FILE + /* check wifi mac file */ + if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) { + _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN); + goto exit; + } +#endif + + _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN); + ret = _FAIL; + +exit: + return ret; +} + +#ifdef CONFIG_RF_GAIN_OFFSET +u32 Array_kfreemap[] = { +0x08,0xe, +0x06,0xc, +0x04,0xa, +0x02,0x8, +0x00,0x6, +0x03,0x4, +0x05,0x2, +0x07,0x0, +0x09,0x0, +0x0c,0x0, +}; + +void rtw_bb_rf_gain_offset(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct registry_priv *registry_par = &padapter->registrypriv; + struct kfree_data_t *kfree_data = &pHalData->kfree_data; + u8 value = pHalData->EEPROMRFGainOffset; + u8 tmp = 0x3e; + u32 res, i = 0; + u4Byte ArrayLen = sizeof(Array_kfreemap)/sizeof(u32); + pu4Byte Array = Array_kfreemap; + u4Byte v1 = 0, v2 = 0, GainValue = 0, target = 0; + + if (registry_par->RegRfKFreeEnable == 2) { + DBG_871X("Registry kfree default force disable.\n"); + return; + } + +#if defined(CONFIG_RTL8723B) + if (value & BIT4 || (registry_par->RegRfKFreeEnable == 1)) { + DBG_871X("Offset RF Gain.\n"); + DBG_871X("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n",pHalData->EEPROMRFGainVal); + + if(pHalData->EEPROMRFGainVal != 0xff){ + + if(pHalData->ant_path == ODM_RF_PATH_A) { + GainValue=(pHalData->EEPROMRFGainVal & 0x0f); + + } else { + GainValue=(pHalData->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 ) { + DBG_871X("Offset RF Gain. got v1 =0x%x ,v2 =0x%x \n",v1,v2); + target=v2; + break; + } + } + DBG_871X("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n",pHalData->EEPROMRFGainVal,target); + + res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); + DBG_871X("Offset RF Gain. before reg 0x7f=0x%08x\n",res); + PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target); + res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff); + + DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res); + + }else { + + DBG_871X("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n",pHalData->EEPROMRFGainVal); + } + } else { + DBG_871X("Using the default RF gain.\n"); + } + +#elif defined(CONFIG_RTL8188E) + if (value & BIT4 || (registry_par->RegRfKFreeEnable == 1)) { + DBG_871X("8188ES Offset RF Gain.\n"); + DBG_871X("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n", + pHalData->EEPROMRFGainVal); + + if (pHalData->EEPROMRFGainVal != 0xff) { + res = rtw_hal_read_rfreg(padapter, RF_PATH_A, + REG_RF_BB_GAIN_OFFSET, 0xffffffff); + + DBG_871X("Offset RF Gain. reg 0x55=0x%x\n",res); + res &= 0xfff87fff; + + res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15; + DBG_871X("Offset RF Gain. res=0x%x\n",res); + + rtw_hal_write_rfreg(padapter, RF_PATH_A, + REG_RF_BB_GAIN_OFFSET, + RF_GAIN_OFFSET_MASK, res); + } else { + DBG_871X("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n", + pHalData->EEPROMRFGainVal); + } + } else { + DBG_871X("Using the default RF gain.\n"); + } +#else + /* TODO: call this when channel switch */ + if (kfree_data->flag & KFREE_FLAG_ON) + rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */ +#endif + +} +#endif //CONFIG_RF_GAIN_OFFSET + +bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data) +{ +#ifdef CONFIG_RF_GAIN_OFFSET + int i, j; + + for (i = 0; i < BB_GAIN_NUM; i++) + for (j = 0; j < RF_PATH_MAX; j++) + if (data->bb_gain[i][j] != 0) + return 0; +#endif + return 1; +} + +#ifdef CONFIG_USB_RX_AGGREGATION +void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + if(cur_wireless_mode < WIRELESS_11_24N + && cur_wireless_mode > 0) //ABG mode + { +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + u32 remainder = 0; + u8 quotient = 0; + + remainder = MAX_RECVBUF_SZ % (4*1024); + quotient = (u8)(MAX_RECVBUF_SZ >> 12); + + if (quotient > 5) { + pHalData->RegAcUsbDmaSize = 0x6; + pHalData->RegAcUsbDmaTime = 0x10; + } else { + if (remainder >= 2048) { + pHalData->RegAcUsbDmaSize = quotient; + pHalData->RegAcUsbDmaTime = 0x10; + } else { + pHalData->RegAcUsbDmaSize = (quotient-1); + pHalData->RegAcUsbDmaTime = 0x10; + } + } +#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */ + if(0x6 != pHalData->RegAcUsbDmaSize || 0x10 !=pHalData->RegAcUsbDmaTime) + { + pHalData->RegAcUsbDmaSize = 0x6; + pHalData->RegAcUsbDmaTime = 0x10; + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, + pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8)); + } +#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */ + + } + else if(cur_wireless_mode >= WIRELESS_11_24N + && cur_wireless_mode <= WIRELESS_MODE_MAX)//N AC mode + { +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + u32 remainder = 0; + u8 quotient = 0; + + remainder = MAX_RECVBUF_SZ % (4*1024); + quotient = (u8)(MAX_RECVBUF_SZ >> 12); + + if (quotient > 5) { + pHalData->RegAcUsbDmaSize = 0x5; + pHalData->RegAcUsbDmaTime = 0x20; + } else { + if (remainder >= 2048) { + pHalData->RegAcUsbDmaSize = quotient; + pHalData->RegAcUsbDmaTime = 0x10; + } else { + pHalData->RegAcUsbDmaSize = (quotient-1); + pHalData->RegAcUsbDmaTime = 0x10; + } + } +#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */ + if(0x5 != pHalData->RegAcUsbDmaSize || 0x20 !=pHalData->RegAcUsbDmaTime) + { + pHalData->RegAcUsbDmaSize = 0x5; + pHalData->RegAcUsbDmaTime = 0x20; + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, + pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8)); + } +#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */ + + } + else + { + /* DBG_871X("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */ + } +} + +void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (cur_wireless_mode < WIRELESS_11_24N + && cur_wireless_mode > 0) { /* ABG mode */ + if (Legacy_UsbDmaSize != pHalData->RegAcUsbDmaSize + || 0x10 != pHalData->RegAcUsbDmaTime) { + pHalData->RegAcUsbDmaSize = Legacy_UsbDmaSize; + pHalData->RegAcUsbDmaTime = 0x10; + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, + pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8)); + } + } else if (cur_wireless_mode >= WIRELESS_11_24N + && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */ + if (UsbDmaSize != pHalData->RegAcUsbDmaSize + || 0x20 != pHalData->RegAcUsbDmaTime) { + pHalData->RegAcUsbDmaSize = UsbDmaSize; + pHalData->RegAcUsbDmaTime = 0x20; + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, + pHalData->RegAcUsbDmaSize | (pHalData->RegAcUsbDmaTime<<8)); + } + } else { + /* DBG_871X("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */ + } +} + +void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode) +{ +#ifdef CONFIG_PLATFORM_NOVATEK_NT72668 + rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3); + return; +#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */ + + rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode); +} +#endif //CONFIG_USB_RX_AGGREGATION + +//To avoid RX affect TX throughput +void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeextpriv = &(padapter->mlmeextpriv); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 cur_wireless_mode = pmlmeextpriv->cur_wireless_mode; +#ifdef CONFIG_CONCURRENT_MODE + struct mlme_ext_priv *pbuddymlmeextpriv = &(padapter->pbuddy_adapter->mlmeextpriv); +#endif //CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_USB_RX_AGGREGATION + if(IS_HARDWARE_TYPE_8821U(padapter) )//|| IS_HARDWARE_TYPE_8192EU(padapter)) + { + //This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB + 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); + else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30) + rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006); + else + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x2005); //dmc agg th 20K + + //DBG_871X("TX_TP=%u, RX_TP=%u \n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); + } + } + else if(IS_HARDWARE_TYPE_8812(padapter)) + { +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_linked_check(padapter) == _TRUE && rtw_linked_check(padapter->pbuddy_adapter) == _TRUE) + { + if(pbuddymlmeextpriv->cur_wireless_mode >= pmlmeextpriv->cur_wireless_mode) + cur_wireless_mode = pbuddymlmeextpriv->cur_wireless_mode; + else + cur_wireless_mode = pmlmeextpriv->cur_wireless_mode; + + rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode); + } + else if (rtw_linked_check(padapter) == _TRUE && rtw_linked_check(padapter->pbuddy_adapter) == _FALSE) + { + rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode); + } +#else //!CONFIG_CONCURRENT_MODE + rtw_set_usb_agg_by_mode(padapter,cur_wireless_mode); +#endif //CONFIG_CONCURRENT_MODE + } +#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, 512byte. + */ +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 > 512) { + 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, bool 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, bool 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; +} +int rtw_hal_register_gpio_interrupt(_adapter* adapter, int gpio_num, void(*callback)(u8 level)) +{ + u8 value; + u8 direction; + PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter); + + if (IS_HARDWARE_TYPE_8188E(adapter)){ + if(gpio_num > 7 || gpio_num < 4) + { + DBG_871X_LEVEL(_drv_always_, "%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(direction){ + DBG_871X_LEVEL(_drv_always_, "%s Can't register output gpio as interrupt.\n",__FUNCTION__); + return -1; + } + + /* Config GPIO Mode */ + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num)); + + /* Register GPIO interrupt handler*/ + adapter->gpiointpriv.callback[gpio_num] = callback; + + /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */ + value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num); + adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2)^value; + rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode); + + /* Enable GPIO interrupt */ + adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num); + rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask); + + rtw_hal_update_hisr_hsisr_ind(adapter, 1); + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + + return 0; +} +int rtw_hal_disable_gpio_interrupt(_adapter* adapter, int gpio_num) +{ + u8 value; + u8 direction; + PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter); + + 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; + } + } + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + + LeaveAllPowerSaveModeDirect(adapter); + + /* Config GPIO Mode */ + rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) &~ BIT(gpio_num)); + + /* Unregister GPIO interrupt handler*/ + adapter->gpiointpriv.callback[gpio_num] = NULL; + + /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */ + adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) &~ BIT(gpio_num); + rtw_write8(adapter, REG_GPIO_INTM, 0x00); + + /* Disable GPIO interrupt */ + adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) &~ BIT(gpio_num); + rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask); + + if(!adapter->gpiointpriv.interrupt_enable_mask) + rtw_hal_update_hisr_hsisr_ind(adapter, 0); + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + + return 0; +} +#endif + +void rtw_dump_mac_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter) +{ + u32 mac_cck_ok=0, mac_ofdm_ok=0, mac_ht_ok=0, mac_vht_ok=0; + u32 mac_cck_err=0, mac_ofdm_err=0, mac_ht_err=0, mac_vht_err=0; + u32 mac_cck_fa=0, mac_ofdm_fa=0, mac_ht_fa=0; + u32 DropPacket=0; + + if(!rx_counter){ + rtw_warn_on(1); + return; + } + + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x3); + mac_cck_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x0); + mac_ofdm_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x6); + mac_ht_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + mac_vht_ok = 0; + if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x0); + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1); + mac_vht_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + } + + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x4); + mac_cck_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x1); + mac_ofdm_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x7); + mac_ht_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + mac_vht_err = 0; + if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) { + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x1); + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1); + mac_vht_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + } + + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x5); + mac_cck_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x2); + mac_ofdm_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28|BIT29|BIT30|BIT31, 0x9); + mac_ht_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);// [15:0] + + //Mac_DropPacket + rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT)& 0x0FFFFFFF)| Mac_DropPacket); + DropPacket = rtw_read32(padapter, REG_RXERR_RPT)& 0x0000FFFF; + + rx_counter->rx_pkt_ok = mac_cck_ok+mac_ofdm_ok+mac_ht_ok+mac_vht_ok; + rx_counter->rx_pkt_crc_error = mac_cck_err+mac_ofdm_err+mac_ht_err+mac_vht_err; + rx_counter->rx_cck_fa = mac_cck_fa; + rx_counter->rx_ofdm_fa = mac_ofdm_fa; + rx_counter->rx_ht_fa = mac_ht_fa; + rx_counter->rx_pkt_drop = DropPacket; +} +void rtw_reset_mac_rx_counters(_adapter* padapter) +{ + + if (IS_HARDWARE_TYPE_8703B(padapter) || IS_HARDWARE_TYPE_8188F(padapter)) + PHY_SetMacReg(padapter, 0x608, BIT19, 0x1); /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/ + + //reset mac counter + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x1); + PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x0); +} + +void rtw_dump_phy_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter) +{ + u32 cckok=0,cckcrc=0,ofdmok=0,ofdmcrc=0,htok=0,htcrc=0,OFDM_FA=0,CCK_FA=0,vht_ok=0,vht_err=0; + if(!rx_counter){ + rtw_warn_on(1); + return; + } + if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)){ + cckok = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF); // [13:0] + ofdmok = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF); // [13:0] + htok = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF); // [13:0] + vht_ok = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF); // [13:0] + cckcrc = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); // [29:16] + ofdmcrc = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); // [29:16] + htcrc = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); // [29:16] + vht_err = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); // [29:16] + CCK_FA = PHY_QueryBBReg(padapter, 0xA5C, bMaskLWord); + OFDM_FA = PHY_QueryBBReg(padapter, 0xF48, bMaskLWord); + } + else + { + cckok = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord); + ofdmok = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord); + htok = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord); + vht_ok = 0; + cckcrc = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord); + ofdmcrc = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord); + htcrc = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord); + vht_err = 0; + OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) + + PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) + + PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord); + + CCK_FA=(rtw_read8(padapter, 0xA5B )<<8 ) | (rtw_read8(padapter, 0xA5C)); + } + + rx_counter->rx_pkt_ok = cckok+ofdmok+htok+vht_ok; + rx_counter->rx_pkt_crc_error = cckcrc+ofdmcrc+htcrc+vht_err; + rx_counter->rx_ofdm_fa = OFDM_FA; + rx_counter->rx_cck_fa = CCK_FA; + +} + +void rtw_reset_phy_rx_counters(_adapter* padapter) +{ + //reset phy counter + if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) + { + PHY_SetBBReg(padapter, 0xB58, BIT0, 0x1); + PHY_SetBBReg(padapter, 0xB58, BIT0, 0x0); + + PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x1);//reset OFDA FA counter + PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x0); + + PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);//reset CCK FA counter + PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1); + } + else + { + PHY_SetBBReg(padapter, 0xF14, BIT16, 0x1); + rtw_msleep_os(10); + PHY_SetBBReg(padapter, 0xF14, BIT16, 0x0); + + PHY_SetBBReg(padapter, 0xD00, BIT27, 0x1);//reset OFDA FA counter + PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x1);//reset OFDA FA counter + PHY_SetBBReg(padapter, 0xD00, BIT27, 0x0); + PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x0); + + PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);//reset CCK FA counter + PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1); + } +} +#ifdef DBG_RX_COUNTER_DUMP +void rtw_dump_drv_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + if(!rx_counter){ + rtw_warn_on(1); + return; + } + rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok; + rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror; + rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop; +} +void rtw_reset_drv_rx_counters(_adapter* padapter) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + padapter->drv_rx_cnt_ok = 0; + padapter->drv_rx_cnt_crcerror = 0; + padapter->drv_rx_cnt_drop = precvpriv->rx_drop; +} +void rtw_dump_phy_rxcnts_preprocess(_adapter* padapter,u8 rx_cnt_mode) +{ + u8 initialgain; + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + DM_ODM_T *odm = &(hal_data->odmpriv); + DIG_T *pDigTable = &odm->DM_DigTable; + + if((!(padapter->dump_rx_cnt_mode& DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) + { + initialgain = pDigTable->CurIGValue; + DBG_871X("%s CurIGValue:0x%02x\n",__FUNCTION__,initialgain); + rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE); + /*disable dynamic functions, such as high power, DIG*/ + rtw_phydm_ability_backup(padapter); + rtw_phydm_func_clr(padapter, (ODM_BB_DIG|ODM_BB_FA_CNT)); + } + else if((padapter->dump_rx_cnt_mode& DUMP_PHY_RX_COUNTER) &&(!(rx_cnt_mode & DUMP_PHY_RX_COUNTER ))) + { + //turn on phy-dynamic functions + rtw_phydm_ability_restore(padapter); + initialgain = 0xff; //restore RX GAIN + rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE); + + } +} + +void rtw_dump_rx_counters(_adapter* padapter) +{ + struct dbg_rx_counter rx_counter; + + if( padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER ){ + _rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter)); + rtw_dump_drv_rx_counters(padapter,&rx_counter); + DBG_871X( "Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n", + rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error,rx_counter.rx_pkt_drop); + rtw_reset_drv_rx_counters(padapter); + } + + if( padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER ){ + _rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter)); + rtw_dump_mac_rx_counters(padapter,&rx_counter); + DBG_871X( "Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n", + rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error, + rx_counter.rx_cck_fa+rx_counter.rx_ofdm_fa+rx_counter.rx_ht_fa, + rx_counter.rx_pkt_drop); + rtw_reset_mac_rx_counters(padapter); + } + + if(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER ){ + _rtw_memset(&rx_counter,0,sizeof(struct dbg_rx_counter)); + rtw_dump_phy_rx_counters(padapter,&rx_counter); + //DBG_871X("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); + //DBG_871X("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); + DBG_871X("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n",rx_counter.rx_pkt_ok,rx_counter.rx_pkt_crc_error, + rx_counter.rx_ofdm_fa+rx_counter.rx_cck_fa); + rtw_reset_phy_rx_counters(padapter); + } +} +#endif +void rtw_get_noise(_adapter* padapter) +{ +#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct noise_info info; + if(rtw_linked_check(padapter)){ + info.bPauseDIG = _TRUE; + info.IGIValue = 0x1e; + info.max_time = 100;//ms + info.chan = pmlmeext->cur_channel ;//rtw_get_oper_ch(padapter); + rtw_ps_deny(padapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(padapter); + + rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, _FALSE); + //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 + +} + +u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u8 rate_id = 0; + +#if (RATE_ADAPTIVE_SUPPORT == 1) + rate_id = ODM_RA_GetDecisionRate_8188E(pDM_Odm, macid); +#else + rate_id = (pRA_Table->link_tx_rate[macid]) & 0x7f; +#endif + + return rate_id; + +} + +#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(PADAPTER padapter, u8 *pdata, u8 len) +{ + int i = 0; + int cnt = 0, total_length = 0; + u8 buf[128] = {0}; + u8 more_data = _FALSE; + u8 *nextdata = NULL; + u8 test = 0; + + u8 data_len; + u8 seq_no; + + nextdata = pdata; + do { + data_len = *(nextdata + 1); + seq_no = *(nextdata + 2); + + 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; + } + + 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*/ +void update_IOT_info(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + + switch (pmlmeinfo->assoc_AP_vendor) + { + case HT_IOT_PEER_MARVELL: + pmlmeinfo->turboMode_cts2self = 1; + pmlmeinfo->turboMode_rtsen = 0; + break; + + case HT_IOT_PEER_RALINK: + pmlmeinfo->turboMode_cts2self = 0; + pmlmeinfo->turboMode_rtsen = 1; + //disable high power + rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR); + break; + case HT_IOT_PEER_REALTEK: + //rtw_write16(padapter, 0x4cc, 0xffff); + //rtw_write16(padapter, 0x546, 0x01c0); + //disable high power + rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR); + break; + default: + pmlmeinfo->turboMode_cts2self = 0; + pmlmeinfo->turboMode_rtsen = 1; + break; + } + +} +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +void rtw_acs_start(_adapter *padapter, bool bStart) +{ + if (_TRUE == bStart) { + ACS_OP acs_op = ACS_INIT; + + rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE); + rtw_set_acs_channel(padapter, 0); + SET_ACS_STATE(padapter, ACS_ENABLE); + } else { + SET_ACS_STATE(padapter, ACS_DISABLE); + #ifdef DBG_AUTO_CHNL_SEL_NHM + if (1) { + u8 best_24g_ch = 0; + u8 best_5g_ch = 0; + + rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch)); + DBG_871X("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch); + DBG_871X("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch); + } + #endif + } +} +#endif + +/* TODO: merge with phydm, see odm_SetCrystalCap() */ +void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap) +{ + crystal_cap = crystal_cap & 0x3F; + + switch (rtw_get_chip_type(adapter)) { +#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) + case RTL8188E: + case RTL8188F: + /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */ + PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6))); + break; +#endif +#if defined(CONFIG_RTL8812A) + case RTL8812: + /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */ + PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6))); + break; +#endif +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192E) + case RTL8723B: + case RTL8703B: + case RTL8821: + case RTL8192E: + /* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */ + PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6))); + break; +#endif +#if defined(CONFIG_RTL8814A) + case RTL8814A: + /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/ + PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6))); + break; +#endif +#if defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) + case RTL8821B: + case RTL8822B: + /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */ + crystal_cap = crystal_cap & 0x3F; + PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap); + PHY_SetBBReg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap); + break; +#endif + default: + rtw_warn_on(1); + } +} + +int hal_spec_init(_adapter *adapter) +{ + u8 interface_type = 0; + int ret = _SUCCESS; + + interface_type = rtw_get_intf_type(adapter); + + switch (rtw_get_chip_type(adapter)) { +#ifdef CONFIG_RTL8723B + case RTL8723B: + init_hal_spec_8723b(adapter); + break; +#endif +#ifdef CONFIG_RTL8703B + case RTL8703B: + init_hal_spec_8703b(adapter); + break; +#endif +#ifdef CONFIG_RTL8188E + case RTL8188E: + init_hal_spec_8188e(adapter); + break; +#endif +#ifdef CONFIG_RTL8188F + case RTL8188F: + init_hal_spec_8188f(adapter); + break; +#endif +#ifdef CONFIG_RTL8812A + case RTL8812: + init_hal_spec_8812a(adapter); + break; +#endif +#ifdef CONFIG_RTL8821A + case RTL8821: + init_hal_spec_8821a(adapter); + break; +#endif +#ifdef CONFIG_RTL8192E + case RTL8192E: + init_hal_spec_8192e(adapter); + break; +#endif +#ifdef CONFIG_RTL8814A + case RTL8814A: + init_hal_spec_8814a(adapter); + break; +#endif + default: + DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n" + , __func__, rtw_get_chip_type(adapter)); + ret = _FAIL; + break; + } + + return ret; +} + +static const char * const _band_cap_str[] = { + /* BIT0 */"2G", + /* BIT1 */"5G", +}; + +static const char * const _bw_cap_str[] = { + /* BIT0 */"5M", + /* BIT1 */"10M", + /* BIT2 */"20M", + /* BIT3 */"40M", + /* BIT4 */"80M", + /* BIT5 */"160M", + /* BIT6 */"80_80M", +}; + +static const char * const _wl_func_str[] = { + /* BIT0 */"P2P", + /* BIT1 */"MIRACAST", + /* BIT2 */"TDLS", + /* BIT3 */"FTM", +}; + +void dump_hal_spec(void *sel, _adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + int i; + + DBG_871X_SEL_NL(sel, "macid_num:%u\n", hal_spec->macid_num); + DBG_871X_SEL_NL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap); + DBG_871X_SEL_NL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num); + DBG_871X_SEL_NL(sel, "nss_num:%u\n", hal_spec->nss_num); + + DBG_871X_SEL_NL(sel, "band_cap:"); + for (i = 0; i < BAND_CAP_BIT_NUM; i++) { + if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i]) + DBG_871X_SEL(sel, "%s ", _band_cap_str[i]); + } + DBG_871X_SEL(sel, "\n"); + + DBG_871X_SEL_NL(sel, "bw_cap:"); + for (i = 0; i < BW_CAP_BIT_NUM; i++) { + if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i]) + DBG_871X_SEL(sel, "%s ", _bw_cap_str[i]); + } + DBG_871X_SEL(sel, "\n"); + + DBG_871X_SEL_NL(sel, "wl_func:"); + for (i = 0; i < WL_FUNC_BIT_NUM; i++) { + if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i]) + DBG_871X_SEL(sel, "%s ", _wl_func_str[i]); + } + DBG_871X_SEL(sel, "\n"); +} + +inline bool hal_chk_band_cap(_adapter *adapter, u8 cap) +{ + return (GET_HAL_SPEC(adapter)->band_cap & cap); +} + +inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap) +{ + return (GET_HAL_SPEC(adapter)->bw_cap & cap); +} + +inline bool hal_chk_wl_func(_adapter *adapter, u8 func) +{ + return (GET_HAL_SPEC(adapter)->wl_func & func); +} + +inline bool hal_is_band_support(_adapter *adapter, u8 band) +{ + return (GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band)); +} + +inline bool hal_is_bw_support(_adapter *adapter, u8 bw) +{ + return (GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw)); +} + +/* +* hal_largest_bw - starting from in_bw, get largest bw supported by HAL +* @adapter: +* @in_bw: starting bw, value of CHANNEL_WIDTH +* +* Returns: value of CHANNEL_WIDTH +*/ +u8 hal_largest_bw(_adapter *adapter, u8 in_bw) +{ + for (; in_bw > CHANNEL_WIDTH_20; in_bw--) { + if (hal_is_bw_support(adapter, in_bw)) + break; + } + + if (!hal_is_bw_support(adapter, in_bw)) + rtw_warn_on(1); + + return in_bw; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_c2h.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_c2h.h new file mode 100644 index 00000000..78a1ace6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_c2h.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __COMMON_C2H_H__ +#define __COMMON_C2H_H__ + +typedef enum _C2H_EVT { + C2H_DBG = 0x00, + C2H_LB = 0x01, + C2H_TXBF = 0x02, + C2H_CCX_TX_RPT = 0x03, + C2H_BT_INFO = 0x09, + C2H_BT_MP_INFO = 0x0B, + C2H_RA_RPT = 0x0C, + C2H_RA_PARA_RPT = 0x0E, + C2H_FW_SWCHNL = 0x10, + C2H_IQK_FINISH = 0x11, + C2H_MAILBOX_STATUS = 0x15, + C2H_P2P_RPORT = 0x16, + C2H_BT_SCOREBOARD_STATUS = 0x20, + C2H_EXTEND = 0xff, +} C2H_EVT; + +typedef enum _EXTEND_C2H_EVT { + EXTEND_C2H_DBG_PRINT = 0 +} EXTEND_C2H_EVT; + +#endif /* __COMMON_C2H_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_phycfg.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_phycfg.c new file mode 100644 index 00000000..70f96d9e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_com_phycfg.c @@ -0,0 +1,4440 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HAL_COM_PHYCFG_C_ + +#include +#include + +/* +* rtw_regsty_get_target_tx_power - +* +* Return dBm or -1 for undefined +*/ +s8 rtw_regsty_get_target_tx_power( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN RATE_SECTION RateSection + ) +{ + struct registry_priv *regsty = adapter_to_regsty(Adapter); + s8 value = 0; + + if (RfPath > RF_PATH_D) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath); + return -1; + } + + if (Band != BAND_ON_2_4G + #ifdef CONFIG_IEEE80211_BAND_5GHZ + && Band != BAND_ON_5G + #endif + ) { + DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band); + return -1; + } + + if (RateSection >= RATE_SECTION_NUM + #ifdef CONFIG_IEEE80211_BAND_5GHZ + || (Band == BAND_ON_5G && RateSection == CCK) + #endif + ) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in Band:%d, RfPath:%d\n", __func__ + , RateSection, Band, RfPath); + return -1; + } + + if (Band == BAND_ON_2_4G) + value = regsty->target_tx_pwr_2g[RfPath][RateSection]; +#ifdef CONFIG_IEEE80211_BAND_5GHZ + else /* BAND_ON_5G */ + value = regsty->target_tx_pwr_5g[RfPath][RateSection - 1]; +#endif + + return value; +} + +bool rtw_regsty_chk_target_tx_power_valid(_adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + int path, tx_num, band, rs; + s8 target; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + if (!hal_is_band_support(adapter, band)) + continue; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num >= hal_spec->nss_num) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + continue; + + target = rtw_regsty_get_target_tx_power(adapter, band, path, rs); + if (target == -1) + return _FALSE; + } + } + } + + return _TRUE; +} + +/* +* PHY_GetTxPowerByRateBase - +* +* Return 2 times of dBm +*/ +u8 +PHY_GetTxPowerByRateBase( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN u8 TxNum, + IN RATE_SECTION RateSection + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 value = 0; + + if (RfPath > RF_PATH_D) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath); + return 0; + } + + if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { + DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band); + return 0; + } + + if (RateSection >= RATE_SECTION_NUM + || (Band == BAND_ON_5G && RateSection == CCK) + ) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in Band:%d, RfPath:%d, TxNum:%d\n", __func__ + , RateSection, Band, RfPath, TxNum); + return 0; + } + + if (Band == BAND_ON_2_4G) + value = pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection]; + else /* BAND_ON_5G */ + value = pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1]; + + return value; +} + +VOID +phy_SetTxPowerByRateBase( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN RATE_SECTION RateSection, + IN u8 TxNum, + IN u8 Value + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if (RfPath > RF_PATH_D) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RfPath:%d\n", __func__, RfPath); + return; + } + + if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { + DBG_871X_LEVEL(_drv_always_, "%s invalid Band:%d\n", __func__, Band); + return; + } + + if (RateSection >= RATE_SECTION_NUM + || (Band == BAND_ON_5G && RateSection == CCK) + ) { + DBG_871X_LEVEL(_drv_always_, "%s invalid RateSection:%d in %sG, RfPath:%d, TxNum:%d\n", __func__ + , RateSection, (Band == BAND_ON_2_4G) ? "2.4" : "5", RfPath, TxNum); + return; + } + + if (Band == BAND_ON_2_4G) + pHalData->TxPwrByRateBase2_4G[RfPath][TxNum][RateSection] = Value; + else /* BAND_ON_5G */ + pHalData->TxPwrByRateBase5G[RfPath][TxNum][RateSection - 1] = Value; +} + +/* +* phy_get_target_tx_power - +* +* Return 2 times of dBm +*/ +u8 phy_get_target_tx_power( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN RATE_SECTION RateSection + ) +{ + struct registry_priv *regsty = adapter_to_regsty(Adapter); + s16 target_power; + + if (phy_is_tx_power_by_rate_needed(Adapter) == _FALSE && regsty->target_tx_pwr_valid == _TRUE) + target_power = 2 * rtw_regsty_get_target_tx_power(Adapter, Band, RfPath, RateSection); + else + target_power = PHY_GetTxPowerByRateBase(Adapter, Band, RfPath, rate_section_to_tx_num(RateSection), RateSection); + + return target_power; +} + +#ifdef TX_POWER_BY_RATE_OLD +VOID +phy_StoreTxPowerByRateBaseOld( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + u16 rawValue = 0; + u8 base = 0; + u8 path = 0; + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] >> 8 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, CCK, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][1] >> 24 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, OFDM, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][3] >> 24 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS0_MCS7, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][5] >> 24 ) & 0xFF; + base = ( rawValue >> 4) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, HT_MCS8_MCS15, RF_2TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][7] & 0xFF ); + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, CCK, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][9] >> 24 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, OFDM, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][11] >> 24 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS0_MCS7, RF_1TX, base ); + + rawValue = ( u16 ) ( pHalData->MCSTxPowerLevelOriginalOffset[0][13] >> 24 ) & 0xFF; + base = ( rawValue >> 4 ) * 10 + ( rawValue & 0xF ); + phy_SetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, HT_MCS8_MCS15, RF_2TX, base ); +} +#endif /* TX_POWER_BY_RATE_OLD */ + +VOID +phy_StoreTxPowerByRateBase( + IN PADAPTER pAdapter + ) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(pAdapter); + + u8 rate_sec_base[RATE_SECTION_NUM] = { + MGN_11M, + MGN_54M, + MGN_MCS7, + MGN_MCS15, + MGN_MCS23, + MGN_MCS31, + MGN_VHT1SS_MCS7, + MGN_VHT2SS_MCS7, + MGN_VHT3SS_MCS7, + MGN_VHT4SS_MCS7, + }; + + u8 band, path, rs, tx_num, base, index; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + + for (path = RF_PATH_A; path < RF_PATH_MAX; path++) { + /* TODO: 8814A's NumTotalRFPath differs at probe(3) and up(4), need fixed + if (path >= hal_data->NumTotalRFPath) + break; + */ + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num >= hal_spec->nss_num) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + base = _PHY_GetTxPowerByRate(pAdapter, band, path, tx_num, rate_sec_base[rs]); + phy_SetTxPowerByRateBase(pAdapter, band, path, rs, tx_num, base); + } + } + } +} + +#ifdef TX_POWER_BY_RATE_OLD +u8 +PHY_GetRateSectionIndexOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + u8 index = 0; + + if ( pDM_Odm->PhyRegPgVersion == 0 ) + { + switch ( RegAddr ) + { + case rTxAGC_A_Rate18_06: index = 0; break; + case rTxAGC_A_Rate54_24: index = 1; break; + case rTxAGC_A_CCK1_Mcs32: index = 6; break; + case rTxAGC_B_CCK11_A_CCK2_11: + if ( BitMask == bMaskH3Bytes ) + index = 7; + else if ( BitMask == 0x000000ff ) + index = 15; + break; + + case rTxAGC_A_Mcs03_Mcs00: index = 2; break; + case rTxAGC_A_Mcs07_Mcs04: index = 3; break; + case rTxAGC_A_Mcs11_Mcs08: index = 4; break; + case rTxAGC_A_Mcs15_Mcs12: index = 5; break; + case rTxAGC_B_Rate18_06: index = 8; break; + case rTxAGC_B_Rate54_24: index = 9; break; + case rTxAGC_B_CCK1_55_Mcs32: index = 14; break; + case rTxAGC_B_Mcs03_Mcs00: index = 10; break; + case rTxAGC_B_Mcs07_Mcs04: index = 11; break; + case rTxAGC_B_Mcs11_Mcs08: index = 12; break; + case rTxAGC_B_Mcs15_Mcs12: index = 13; break; + default: + DBG_871X("Invalid RegAddr 0x3%x in PHY_GetRateSectionIndexOfTxPowerByRate()", RegAddr ); + break; + }; + } + + return index; +} +#endif /* TX_POWER_BY_RATE_OLD */ + +VOID +PHY_GetRateValuesOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Value, + OUT u8 *Rate, + OUT s8 *PwrByRateVal, + OUT u8 *RateNum + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + u8 index = 0, i = 0; + + switch ( RegAddr ) + { + case rTxAGC_A_Rate18_06: + case rTxAGC_B_Rate18_06: + Rate[0] = MGN_6M; + Rate[1] = MGN_9M; + Rate[2] = MGN_12M; + Rate[3] = MGN_18M; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case rTxAGC_A_Rate54_24: + case rTxAGC_B_Rate54_24: + Rate[0] = MGN_24M; + Rate[1] = MGN_36M; + Rate[2] = MGN_48M; + Rate[3] = MGN_54M; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case rTxAGC_A_CCK1_Mcs32: + Rate[0] = MGN_1M; + PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> (8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> 8 ) & 0xF ) ); + *RateNum = 1; + break; + + case rTxAGC_B_CCK11_A_CCK2_11: + if ( BitMask == 0xffffff00 ) + { + Rate[0] = MGN_2M; + Rate[1] = MGN_5_5M; + Rate[2] = MGN_11M; + for ( i = 1; i < 4; ++ i ) + { + PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 3; + } + else if ( BitMask == 0x000000ff ) + { + Rate[0] = MGN_11M; + PwrByRateVal[0] = ( s8 ) ( ( ( ( Value >> 4 ) & 0xF ) ) * 10 + + ( Value & 0xF ) ); + *RateNum = 1; + } + break; + + case rTxAGC_A_Mcs03_Mcs00: + case rTxAGC_B_Mcs03_Mcs00: + Rate[0] = MGN_MCS0; + Rate[1] = MGN_MCS1; + Rate[2] = MGN_MCS2; + Rate[3] = MGN_MCS3; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case rTxAGC_A_Mcs07_Mcs04: + case rTxAGC_B_Mcs07_Mcs04: + Rate[0] = MGN_MCS4; + Rate[1] = MGN_MCS5; + Rate[2] = MGN_MCS6; + Rate[3] = MGN_MCS7; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case rTxAGC_A_Mcs11_Mcs08: + case rTxAGC_B_Mcs11_Mcs08: + Rate[0] = MGN_MCS8; + Rate[1] = MGN_MCS9; + Rate[2] = MGN_MCS10; + Rate[3] = MGN_MCS11; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case rTxAGC_A_Mcs15_Mcs12: + case rTxAGC_B_Mcs15_Mcs12: + Rate[0] = MGN_MCS12; + Rate[1] = MGN_MCS13; + Rate[2] = MGN_MCS14; + Rate[3] = MGN_MCS15; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + + break; + + case rTxAGC_B_CCK1_55_Mcs32: + Rate[0] = MGN_1M; + Rate[1] = MGN_2M; + Rate[2] = MGN_5_5M; + for ( i = 1; i < 4; ++ i ) + { + PwrByRateVal[i - 1] = ( s8 ) ( ( ( ( Value >> ( i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> ( i * 8) ) & 0xF ) ); + } + *RateNum = 3; + break; + + case 0xC20: + case 0xE20: + case 0x1820: + case 0x1a20: + Rate[0] = MGN_1M; + Rate[1] = MGN_2M; + Rate[2] = MGN_5_5M; + Rate[3] = MGN_11M; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC24: + case 0xE24: + case 0x1824: + case 0x1a24: + Rate[0] = MGN_6M; + Rate[1] = MGN_9M; + Rate[2] = MGN_12M; + Rate[3] = MGN_18M; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC28: + case 0xE28: + case 0x1828: + case 0x1a28: + Rate[0] = MGN_24M; + Rate[1] = MGN_36M; + Rate[2] = MGN_48M; + Rate[3] = MGN_54M; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC2C: + case 0xE2C: + case 0x182C: + case 0x1a2C: + Rate[0] = MGN_MCS0; + Rate[1] = MGN_MCS1; + Rate[2] = MGN_MCS2; + Rate[3] = MGN_MCS3; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC30: + case 0xE30: + case 0x1830: + case 0x1a30: + Rate[0] = MGN_MCS4; + Rate[1] = MGN_MCS5; + Rate[2] = MGN_MCS6; + Rate[3] = MGN_MCS7; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC34: + case 0xE34: + case 0x1834: + case 0x1a34: + Rate[0] = MGN_MCS8; + Rate[1] = MGN_MCS9; + Rate[2] = MGN_MCS10; + Rate[3] = MGN_MCS11; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC38: + case 0xE38: + case 0x1838: + case 0x1a38: + Rate[0] = MGN_MCS12; + Rate[1] = MGN_MCS13; + Rate[2] = MGN_MCS14; + Rate[3] = MGN_MCS15; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC3C: + case 0xE3C: + case 0x183C: + case 0x1a3C: + Rate[0] = MGN_VHT1SS_MCS0; + Rate[1] = MGN_VHT1SS_MCS1; + Rate[2] = MGN_VHT1SS_MCS2; + Rate[3] = MGN_VHT1SS_MCS3; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC40: + case 0xE40: + case 0x1840: + case 0x1a40: + Rate[0] = MGN_VHT1SS_MCS4; + Rate[1] = MGN_VHT1SS_MCS5; + Rate[2] = MGN_VHT1SS_MCS6; + Rate[3] = MGN_VHT1SS_MCS7; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC44: + case 0xE44: + case 0x1844: + case 0x1a44: + Rate[0] = MGN_VHT1SS_MCS8; + Rate[1] = MGN_VHT1SS_MCS9; + Rate[2] = MGN_VHT2SS_MCS0; + Rate[3] = MGN_VHT2SS_MCS1; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC48: + case 0xE48: + case 0x1848: + case 0x1a48: + Rate[0] = MGN_VHT2SS_MCS2; + Rate[1] = MGN_VHT2SS_MCS3; + Rate[2] = MGN_VHT2SS_MCS4; + Rate[3] = MGN_VHT2SS_MCS5; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xC4C: + case 0xE4C: + case 0x184C: + case 0x1a4C: + Rate[0] = MGN_VHT2SS_MCS6; + Rate[1] = MGN_VHT2SS_MCS7; + Rate[2] = MGN_VHT2SS_MCS8; + Rate[3] = MGN_VHT2SS_MCS9; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xCD8: + case 0xED8: + case 0x18D8: + case 0x1aD8: + Rate[0] = MGN_MCS16; + Rate[1] = MGN_MCS17; + Rate[2] = MGN_MCS18; + Rate[3] = MGN_MCS19; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xCDC: + case 0xEDC: + case 0x18DC: + case 0x1aDC: + Rate[0] = MGN_MCS20; + Rate[1] = MGN_MCS21; + Rate[2] = MGN_MCS22; + Rate[3] = MGN_MCS23; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xCE0: + case 0xEE0: + case 0x18E0: + case 0x1aE0: + Rate[0] = MGN_VHT3SS_MCS0; + Rate[1] = MGN_VHT3SS_MCS1; + Rate[2] = MGN_VHT3SS_MCS2; + Rate[3] = MGN_VHT3SS_MCS3; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xCE4: + case 0xEE4: + case 0x18E4: + case 0x1aE4: + Rate[0] = MGN_VHT3SS_MCS4; + Rate[1] = MGN_VHT3SS_MCS5; + Rate[2] = MGN_VHT3SS_MCS6; + Rate[3] = MGN_VHT3SS_MCS7; + for ( i = 0; i < 4; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 4; + break; + + case 0xCE8: + case 0xEE8: + case 0x18E8: + case 0x1aE8: + Rate[0] = MGN_VHT3SS_MCS8; + Rate[1] = MGN_VHT3SS_MCS9; + for ( i = 0; i < 2; ++ i ) + { + PwrByRateVal[i] = ( s8 ) ( ( ( ( Value >> (i * 8 + 4) ) & 0xF ) ) * 10 + + ( ( Value >> (i * 8) ) & 0xF ) ); + } + *RateNum = 2; + break; + + default: + DBG_871X_LEVEL(_drv_always_, "Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__); + break; + }; +} + +void +PHY_StoreTxPowerByRateNew( + IN PADAPTER pAdapter, + IN u32 Band, + IN u32 RfPath, + IN u32 TxNum, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 i = 0, rates[4] = {0}, rateNum = 0; + s8 PwrByRateVal[4] = {0}; + + PHY_GetRateValuesOfTxPowerByRate(pAdapter, RegAddr, BitMask, Data, rates, PwrByRateVal, &rateNum); + + if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { + DBG_871X_LEVEL(_drv_always_, "Invalid Band %d\n", Band); + return; + } + + if (RfPath > ODM_RF_PATH_D) { + DBG_871X_LEVEL(_drv_always_, "Invalid RfPath %d\n", RfPath); + return; + } + + if (TxNum > ODM_RF_PATH_D) { + DBG_871X_LEVEL(_drv_always_, "Invalid TxNum %d\n", TxNum); + return; + } + + for (i = 0; i < rateNum; ++i) { + u8 rate_idx = PHY_GetRateIndexOfTxPowerByRate(rates[i]); + + if (IS_1T_RATE(rates[i])) + pHalData->TxPwrByRateOffset[Band][RfPath][RF_1TX][rate_idx] = PwrByRateVal[i]; + else if (IS_2T_RATE(rates[i])) + pHalData->TxPwrByRateOffset[Band][RfPath][RF_2TX][rate_idx] = PwrByRateVal[i]; + else if (IS_3T_RATE(rates[i])) + pHalData->TxPwrByRateOffset[Band][RfPath][RF_3TX][rate_idx] = PwrByRateVal[i]; + else if (IS_4T_RATE(rates[i])) + pHalData->TxPwrByRateOffset[Band][RfPath][RF_4TX][rate_idx] = PwrByRateVal[i]; + else + rtw_warn_on(1); + } +} + +#ifdef TX_POWER_BY_RATE_OLD +void +PHY_StoreTxPowerByRateOld( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 index = PHY_GetRateSectionIndexOfTxPowerByRate( pAdapter, RegAddr, BitMask ); + + pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][index] = Data; + //DBG_871X("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", pHalData->pwrGroupCnt, + // pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0]); +} +#endif /* TX_POWER_BY_RATE_OLD */ + +VOID +PHY_InitTxPowerByRate( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 band = 0, rfPath = 0, TxNum = 0, rate = 0, i = 0, j = 0; + + if ( IS_HARDWARE_TYPE_8188E( pAdapter ) ) + { + for ( i = 0; i < MAX_PG_GROUP; ++i ) + for ( j = 0; j < 16; ++j ) + pHalData->MCSTxPowerLevelOriginalOffset[i][j] = 0; + } + else + { + for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band ) + for ( rfPath = 0; rfPath < TX_PWR_BY_RATE_NUM_RF; ++rfPath ) + for ( TxNum = 0; TxNum < TX_PWR_BY_RATE_NUM_RF; ++TxNum ) + for ( rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; ++rate ) + pHalData->TxPwrByRateOffset[band][rfPath][TxNum][rate] = 0; + } +} + +VOID +PHY_StoreTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 Band, + IN u32 RfPath, + IN u32 TxNum, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + + if ( pDM_Odm->PhyRegPgVersion > 0 ) + { + PHY_StoreTxPowerByRateNew( pAdapter, Band, RfPath, TxNum, RegAddr, BitMask, Data ); + } +#ifdef TX_POWER_BY_RATE_OLD + else if ( pDM_Odm->PhyRegPgVersion == 0 ) + { + PHY_StoreTxPowerByRateOld( pAdapter, RegAddr, BitMask, Data ); + + if ( RegAddr == rTxAGC_A_Mcs15_Mcs12 && pHalData->rf_type == RF_1T1R ) + pHalData->pwrGroupCnt++; + else if ( RegAddr == rTxAGC_B_Mcs15_Mcs12 && pHalData->rf_type != RF_1T1R ) + pHalData->pwrGroupCnt++; + } +#endif + else + DBG_871X("Invalid PHY_REG_PG.txt version %d\n", pDM_Odm->PhyRegPgVersion ); + +} + +#ifdef TX_POWER_BY_RATE_OLD +VOID +phy_ConvertTxPowerByRateByBase( + IN u32* pData, + IN u8 Start, + IN u8 End, + IN u8 BaseValue + ) +{ + s8 i = 0; + u8 TempValue = 0; + u32 TempData = 0; + + for ( i = 3; i >= 0; --i ) + { + if ( i >= Start && i <= End ) + { + // Get the exact value + TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xF; + TempValue += ( ( u8 ) ( ( *pData >> ( i * 8 + 4 ) ) & 0xF ) ) * 10; + + // Change the value to a relative value + TempValue = ( TempValue > BaseValue ) ? TempValue - BaseValue : BaseValue - TempValue; + } + else + { + TempValue = ( u8 ) ( *pData >> ( i * 8 ) ) & 0xFF; + } + + TempData <<= 8; + TempData |= TempValue; + } + + *pData = TempData; +} + + +VOID +PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + u8 base = 0; + + //DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" ); + + // CCK + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, CCK ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][6] ), 1, 1, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][7] ), 1, 3, base ); + + // OFDM + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, OFDM ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][0] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][1] ), 0, 3, base ); + + // HT MCS0~7 + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, HT_MCS0_MCS7 ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][2] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][3] ), 0, 3, base ); + + // HT MCS8~15 + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_2TX, HT_MCS8_MCS15 ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][4] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][5] ), 0, 3, base ); + + // CCK + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, CCK ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][14] ), 1, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][15] ), 0, 0, base ); + + // OFDM + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, OFDM ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][8] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][9] ), 0, 3, base ); + + // HT MCS0~7 + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_1TX, HT_MCS0_MCS7 ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][10] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][11] ), 0, 3, base ); + + // HT MCS8~15 + base = PHY_GetTxPowerByRateBase( pAdapter, BAND_ON_2_4G, ODM_RF_PATH_B, RF_2TX, HT_MCS8_MCS15 ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][12] ), 0, 3, base ); + phy_ConvertTxPowerByRateByBase( + &( pHalData->MCSTxPowerLevelOriginalOffset[0][13] ), 0, 3, base ); + + //DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValuesOld()\n" ); +} +#endif /* TX_POWER_BY_RATE_OLD */ + +VOID +phy_ConvertTxPowerByRateInDbmToRelativeValues( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + u8 base = 0, i = 0, value = 0, + band = 0, path = 0, txNum = 0, index = 0, + startIndex = 0, endIndex = 0; + u8 cckRates[4] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}, + ofdmRates[8] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}, + mcs0_7Rates[8] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}, + mcs8_15Rates[8] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15}, + mcs16_23Rates[8] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23}, + vht1ssRates[10] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9}, + vht2ssRates[10] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9}, + vht3ssRates[10] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9}; + + //DBG_871X("===>PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); + + for ( band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band ) + { + for ( path = ODM_RF_PATH_A; path <= ODM_RF_PATH_D; ++path ) + { + for ( txNum = RF_1TX; txNum < RF_MAX_TX_NUM; ++txNum ) + { + // CCK + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_11M ); + for ( i = 0; i < sizeof( cckRates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, cckRates[i], value - base ); + } + + // OFDM + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_54M ); + for ( i = 0; i < sizeof( ofdmRates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, ofdmRates[i], value - base ); + } + + // HT MCS0~7 + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS7 ); + for ( i = 0; i < sizeof( mcs0_7Rates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs0_7Rates[i], value - base ); + } + + // HT MCS8~15 + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS15 ); + for ( i = 0; i < sizeof( mcs8_15Rates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs8_15Rates[i], value - base ); + } + + // HT MCS16~23 + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_MCS23 ); + for ( i = 0; i < sizeof( mcs16_23Rates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, mcs16_23Rates[i], value - base ); + } + + // VHT 1SS + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT1SS_MCS7 ); + for ( i = 0; i < sizeof( vht1ssRates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht1ssRates[i], value - base ); + } + + // VHT 2SS + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT2SS_MCS7 ); + for ( i = 0; i < sizeof( vht2ssRates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht2ssRates[i], value - base ); + } + + // VHT 3SS + base = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, MGN_VHT3SS_MCS7 ); + for ( i = 0; i < sizeof( vht3ssRates ); ++i ) + { + value = PHY_GetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i] ); + PHY_SetTxPowerByRate( pAdapter, band, path, txNum, vht3ssRates[i], value - base ); + } + } + } + } + + //DBG_871X("<===PHY_ConvertTxPowerByRateInDbmToRelativeValues()\n" ); +} + +/* + * This function must be called if the value in the PHY_REG_PG.txt(or header) + * is exact dBm values + */ +VOID +PHY_TxPowerByRateConfiguration( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter); + + phy_StoreTxPowerByRateBase( pAdapter ); + phy_ConvertTxPowerByRateInDbmToRelativeValues( pAdapter ); +} + +VOID +PHY_SetTxPowerIndexByRateSection( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Channel, + IN u8 RateSection + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + + if ( RateSection == CCK ) + { + u8 cckRates[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; + if ( pHalData->CurrentBandType == BAND_ON_2_4G ) + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + cckRates, sizeof(cckRates)/sizeof(u8) ); + + } + else if ( RateSection == OFDM ) + { + u8 ofdmRates[] = {MGN_6M, MGN_9M, MGN_12M, MGN_18M, MGN_24M, MGN_36M, MGN_48M, MGN_54M}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + ofdmRates, sizeof(ofdmRates)/sizeof(u8)); + + } + else if ( RateSection == HT_MCS0_MCS7 ) + { + u8 htRates1T[] = {MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, MGN_MCS5, MGN_MCS6, MGN_MCS7}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + htRates1T, sizeof(htRates1T)/sizeof(u8)); + + } + else if ( RateSection == HT_MCS8_MCS15 ) + { + u8 htRates2T[] = {MGN_MCS8, MGN_MCS9, MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, MGN_MCS15}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + htRates2T, sizeof(htRates2T)/sizeof(u8)); + + } + else if ( RateSection == HT_MCS16_MCS23 ) + { + u1Byte htRates3T[] = {MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + htRates3T, sizeof(htRates3T)/sizeof(u1Byte)); + + } + else if ( RateSection == HT_MCS24_MCS31 ) + { + u1Byte htRates4T[] = {MGN_MCS24, MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, MGN_MCS30, MGN_MCS31}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + htRates4T, sizeof(htRates4T)/sizeof(u1Byte)); + + } + else if ( RateSection == VHT_1SSMCS0_1SSMCS9 ) + { + u8 vhtRates1T[] = {MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9}; + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + vhtRates1T, sizeof(vhtRates1T)/sizeof(u8)); + + } + else if ( RateSection == VHT_2SSMCS0_2SSMCS9 ) + { + u8 vhtRates2T[] = {MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9}; + + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + vhtRates2T, sizeof(vhtRates2T)/sizeof(u8)); + } + else if ( RateSection == VHT_3SSMCS0_3SSMCS9 ) + { + u1Byte vhtRates3T[] = {MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9}; + + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + vhtRates3T, sizeof(vhtRates3T)/sizeof(u1Byte)); + } + else if ( RateSection == VHT_4SSMCS0_4SSMCS9 ) + { + u1Byte vhtRates4T[] = {MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, + MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9}; + + PHY_SetTxPowerIndexByRateArray( pAdapter, RFPath, pHalData->CurrentChannelBW, Channel, + vhtRates4T, sizeof(vhtRates4T)/sizeof(u1Byte)); + } + else + { + DBG_871X("Invalid RateSection %d in %s", RateSection, __FUNCTION__ ); + } +} + +BOOLEAN +phy_GetChnlIndex( + IN u8 Channel, + OUT u8* ChannelIdx + ) +{ + u8 i = 0; + BOOLEAN bIn24G=_TRUE; + + if (Channel <= 14) { + bIn24G = _TRUE; + *ChannelIdx = Channel - 1; + } else { + bIn24G = _FALSE; + + for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) { + if (center_ch_5g_all[i] == Channel) { + *ChannelIdx = i; + return bIn24G; + } + } + } + + return bIn24G; +} + +u8 +PHY_GetTxPowerIndexBase( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + OUT PBOOLEAN bIn24G + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + u8 i = 0; //default set to 1S + u8 txPower = 0; + u8 chnlIdx = (Channel-1); + + if (HAL_IsLegalChannel(pAdapter, Channel) == _FALSE) + { + chnlIdx = 0; + DBG_871X("Illegal channel!!\n"); + } + + *bIn24G = phy_GetChnlIndex(Channel, &chnlIdx); + + //DBG_871X("[%s] Channel Index: %d\n", (*bIn24G?"2.4G":"5G"), chnlIdx); + + if (*bIn24G) //3 ============================== 2.4 G ============================== + { + if ( IS_CCK_RATE(Rate) ) + { + txPower = pHalData->Index24G_CCK_Base[RFPath][chnlIdx]; + } + else if ( MGN_6M <= Rate ) + { + txPower = pHalData->Index24G_BW40_Base[RFPath][chnlIdx]; + } + else + { + DBG_871X("PHY_GetTxPowerIndexBase: INVALID Rate.\n"); + } + + //DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", + // ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); + + // OFDM-1T + if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate) ) + { + txPower += pHalData->OFDM_24G_Diff[RFPath][TX_1S]; + //DBG_871X("+PowerDiff 2.4G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_24G_Diff[RFPath][TX_1S]); + } + // BW20-1S, BW20-2S + if (BandWidth == CHANNEL_WIDTH_20) + { + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_24G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_24G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_24G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_24G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 2.4G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW20_24G_Diff[RFPath][TX_1S], pHalData->BW20_24G_Diff[RFPath][TX_2S], + // pHalData->BW20_24G_Diff[RFPath][TX_3S], pHalData->BW20_24G_Diff[RFPath][TX_4S]); + } + // BW40-1S, BW40-2S + else if (BandWidth == CHANNEL_WIDTH_40) + { + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], + // pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); + } + // Willis suggest adopt BW 40M power index while in BW 80 mode + else if ( BandWidth == CHANNEL_WIDTH_80 ) + { + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_24G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 2.4G (RF-%c): (BW40-1S, BW40-2S, BW40-3S, BW40-4T) = (%d, %d, %d, %d) P.S. Current is in BW 80MHz\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW40_24G_Diff[RFPath][TX_1S], pHalData->BW40_24G_Diff[RFPath][TX_2S], + // pHalData->BW40_24G_Diff[RFPath][TX_3S], pHalData->BW40_24G_Diff[RFPath][TX_4S]); + } + } + else //3 ============================== 5 G ============================== + { + if ( MGN_6M <= Rate ) + { + txPower = pHalData->Index5G_BW40_Base[RFPath][chnlIdx]; + } + else + { + DBG_871X("===> mpt_ProQueryCalTxPower_Jaguar: INVALID Rate.\n"); + } + + //DBG_871X("Base Tx power(RF-%c, Rate #%d, Channel Index %d) = 0x%X\n", + // ((RFPath==0)?'A':'B'), Rate, chnlIdx, txPower); + + // OFDM-1T + if ( (MGN_6M <= Rate && Rate <= MGN_54M) && ! IS_CCK_RATE(Rate)) + { + txPower += pHalData->OFDM_5G_Diff[RFPath][TX_1S]; + //DBG_871X("+PowerDiff 5G (RF-%c): (OFDM-1T) = (%d)\n", ((RFPath==0)?'A':'B'), pHalData->OFDM_5G_Diff[RFPath][TX_1S]); + } + + // BW20-1S, BW20-2S + if (BandWidth == CHANNEL_WIDTH_20) + { + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_5G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_5G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_5G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW20_5G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 5G (RF-%c): (BW20-1S, BW20-2S, BW20-3S, BW20-4S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW20_5G_Diff[RFPath][TX_1S], pHalData->BW20_5G_Diff[RFPath][TX_2S], + // pHalData->BW20_5G_Diff[RFPath][TX_3S], pHalData->BW20_5G_Diff[RFPath][TX_4S]); + } + // BW40-1S, BW40-2S + else if (BandWidth == CHANNEL_WIDTH_40) + { + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_5G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_5G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_5G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS24 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW40_5G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 5G(RF-%c): (BW40-1S, BW40-2S) = (%d, %d, %d, %d)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW40_5G_Diff[RFPath][TX_1S], pHalData->BW40_5G_Diff[RFPath][TX_2S], + // pHalData->BW40_5G_Diff[RFPath][TX_3S], pHalData->BW40_5G_Diff[RFPath][TX_4S]); + } + // BW80-1S, BW80-2S + else if (BandWidth== CHANNEL_WIDTH_80) + { + // <20121220, Kordan> Get the index of array "Index5G_BW80_Base". + for (i = 0; i < CENTER_CH_5G_80M_NUM; ++i) + if (center_ch_5g_80m[i] == Channel) + chnlIdx = i; + + txPower = pHalData->Index5G_BW80_Base[RFPath][chnlIdx]; + + if ( (MGN_MCS0 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT1SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += + pHalData->BW80_5G_Diff[RFPath][TX_1S]; + if ( (MGN_MCS8 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT2SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW80_5G_Diff[RFPath][TX_2S]; + if ( (MGN_MCS16 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT3SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW80_5G_Diff[RFPath][TX_3S]; + if ( (MGN_MCS23 <= Rate && Rate <= MGN_MCS31) || (MGN_VHT4SS_MCS0 <= Rate && Rate <= MGN_VHT4SS_MCS9)) + txPower += pHalData->BW80_5G_Diff[RFPath][TX_4S]; + + //DBG_871X("+PowerDiff 5G(RF-%c): (BW80-1S, BW80-2S, BW80-3S, BW80-4S) = (%d, %d, %d, %d)\n",((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), + // pHalData->BW80_5G_Diff[RFPath][TX_1S], pHalData->BW80_5G_Diff[RFPath][TX_2S], + // pHalData->BW80_5G_Diff[RFPath][TX_3S], pHalData->BW80_5G_Diff[RFPath][TX_4S]); + } + } + + return txPower; +} + +s8 +PHY_GetTxPowerTrackingOffset( + PADAPTER pAdapter, + u8 RFPath, + u8 Rate + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + s8 offset = 0; + + if( pDM_Odm->RFCalibrateInfo.TxPowerTrackControl == _FALSE) + return offset; + + if ((Rate == MGN_1M) ||(Rate == MGN_2M)||(Rate == MGN_5_5M)||(Rate == MGN_11M)) + { + offset = pDM_Odm->RFCalibrateInfo.Remnant_CCKSwingIdx; + /*DBG_871X("+Remnant_CCKSwingIdx = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_CCKSwingIdx);*/ + } + else + { + offset = pDM_Odm->RFCalibrateInfo.Remnant_OFDMSwingIdx[RFPath]; + /*DBG_871X("+Remanant_OFDMSwingIdx[RFPath %u][Rate 0x%x] = 0x%x\n", RFPath, Rate, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath]); */ + + } + + return offset; +} + +u8 +PHY_GetRateIndexOfTxPowerByRate( + IN u8 Rate + ) +{ + u8 index = 0; + switch ( Rate ) + { + case MGN_1M: index = 0; break; + case MGN_2M: index = 1; break; + case MGN_5_5M: index = 2; break; + case MGN_11M: index = 3; break; + case MGN_6M: index = 4; break; + case MGN_9M: index = 5; break; + case MGN_12M: index = 6; break; + case MGN_18M: index = 7; break; + case MGN_24M: index = 8; break; + case MGN_36M: index = 9; break; + case MGN_48M: index = 10; break; + case MGN_54M: index = 11; break; + case MGN_MCS0: index = 12; break; + case MGN_MCS1: index = 13; break; + case MGN_MCS2: index = 14; break; + case MGN_MCS3: index = 15; break; + case MGN_MCS4: index = 16; break; + case MGN_MCS5: index = 17; break; + case MGN_MCS6: index = 18; break; + case MGN_MCS7: index = 19; break; + case MGN_MCS8: index = 20; break; + case MGN_MCS9: index = 21; break; + case MGN_MCS10: index = 22; break; + case MGN_MCS11: index = 23; break; + case MGN_MCS12: index = 24; break; + case MGN_MCS13: index = 25; break; + case MGN_MCS14: index = 26; break; + case MGN_MCS15: index = 27; break; + case MGN_MCS16: index = 28; break; + case MGN_MCS17: index = 29; break; + case MGN_MCS18: index = 30; break; + case MGN_MCS19: index = 31; break; + case MGN_MCS20: index = 32; break; + case MGN_MCS21: index = 33; break; + case MGN_MCS22: index = 34; break; + case MGN_MCS23: index = 35; break; + case MGN_MCS24: index = 36; break; + case MGN_MCS25: index = 37; break; + case MGN_MCS26: index = 38; break; + case MGN_MCS27: index = 39; break; + case MGN_MCS28: index = 40; break; + case MGN_MCS29: index = 41; break; + case MGN_MCS30: index = 42; break; + case MGN_MCS31: index = 43; break; + case MGN_VHT1SS_MCS0: index = 44; break; + case MGN_VHT1SS_MCS1: index = 45; break; + case MGN_VHT1SS_MCS2: index = 46; break; + case MGN_VHT1SS_MCS3: index = 47; break; + case MGN_VHT1SS_MCS4: index = 48; break; + case MGN_VHT1SS_MCS5: index = 49; break; + case MGN_VHT1SS_MCS6: index = 50; break; + case MGN_VHT1SS_MCS7: index = 51; break; + case MGN_VHT1SS_MCS8: index = 52; break; + case MGN_VHT1SS_MCS9: index = 53; break; + case MGN_VHT2SS_MCS0: index = 54; break; + case MGN_VHT2SS_MCS1: index = 55; break; + case MGN_VHT2SS_MCS2: index = 56; break; + case MGN_VHT2SS_MCS3: index = 57; break; + case MGN_VHT2SS_MCS4: index = 58; break; + case MGN_VHT2SS_MCS5: index = 59; break; + case MGN_VHT2SS_MCS6: index = 60; break; + case MGN_VHT2SS_MCS7: index = 61; break; + case MGN_VHT2SS_MCS8: index = 62; break; + case MGN_VHT2SS_MCS9: index = 63; break; + case MGN_VHT3SS_MCS0: index = 64; break; + case MGN_VHT3SS_MCS1: index = 65; break; + case MGN_VHT3SS_MCS2: index = 66; break; + case MGN_VHT3SS_MCS3: index = 67; break; + case MGN_VHT3SS_MCS4: index = 68; break; + case MGN_VHT3SS_MCS5: index = 69; break; + case MGN_VHT3SS_MCS6: index = 70; break; + case MGN_VHT3SS_MCS7: index = 71; break; + case MGN_VHT3SS_MCS8: index = 72; break; + case MGN_VHT3SS_MCS9: index = 73; break; + case MGN_VHT4SS_MCS0: index = 74; break; + case MGN_VHT4SS_MCS1: index = 75; break; + case MGN_VHT4SS_MCS2: index = 76; break; + case MGN_VHT4SS_MCS3: index = 77; break; + case MGN_VHT4SS_MCS4: index = 78; break; + case MGN_VHT4SS_MCS5: index = 79; break; + case MGN_VHT4SS_MCS6: index = 80; break; + case MGN_VHT4SS_MCS7: index = 81; break; + case MGN_VHT4SS_MCS8: index = 82; break; + case MGN_VHT4SS_MCS9: index = 83; break; + default: + DBG_871X("Invalid rate 0x%x in %s\n", Rate, __FUNCTION__ ); + break; + }; + + return index; +} + +s8 +_PHY_GetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 Rate + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + s8 value = 0; + u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); + + if (Band != BAND_ON_2_4G && Band != BAND_ON_5G) { + DBG_871X("Invalid band %d in %s\n", Band, __func__); + goto exit; + } + if (RFPath > ODM_RF_PATH_D) { + DBG_871X("Invalid RfPath %d in %s\n", RFPath, __func__); + goto exit; + } + if (TxNum >= RF_MAX_TX_NUM) { + DBG_871X("Invalid TxNum %d in %s\n", TxNum, __func__); + goto exit; + } + if (rateIndex >= TX_PWR_BY_RATE_NUM_RATE) { + DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __func__); + goto exit; + } + + value = pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex]; + +exit: + return value; +} + + +s8 +PHY_GetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 Rate + ) +{ + if (!phy_is_tx_power_by_rate_needed(pAdapter)) + return 0; + + return _PHY_GetTxPowerByRate(pAdapter, Band, RFPath, TxNum, Rate); +} + +VOID +PHY_SetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 Rate, + IN s8 Value + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA( pAdapter ); + u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate( Rate ); + + if ( Band != BAND_ON_2_4G && Band != BAND_ON_5G ) + { + DBG_871X("Invalid band %d in %s\n", Band, __FUNCTION__ ); + return; + } + if ( RFPath > ODM_RF_PATH_D ) + { + DBG_871X("Invalid RfPath %d in %s\n", RFPath, __FUNCTION__ ); + return; + } + if ( TxNum >= RF_MAX_TX_NUM ) + { + DBG_871X( "Invalid TxNum %d in %s\n", TxNum, __FUNCTION__ ); + return; + } + if ( rateIndex >= TX_PWR_BY_RATE_NUM_RATE ) + { + DBG_871X("Invalid RateIndex %d in %s\n", rateIndex, __FUNCTION__ ); + return; + } + + pHalData->TxPwrByRateOffset[Band][RFPath][TxNum][rateIndex] = Value; +} + +VOID +PHY_SetTxPowerLevelByPath( + IN PADAPTER Adapter, + IN u8 channel, + IN u8 path + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + BOOLEAN bIsIn24G = (pHalData->CurrentBandType == BAND_ON_2_4G ); + + //if ( pMgntInfo->RegNByteAccess == 0 ) + { + if ( bIsIn24G ) + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, CCK ); + + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, OFDM ); + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS0_MCS7 ); + + if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter)) + PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_1SSMCS0_1SSMCS9); + + if (pHalData->NumTotalRFPath >= 2) + { + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS8_MCS15 ); + + if (IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter)) + PHY_SetTxPowerIndexByRateSection(Adapter, path, channel, VHT_2SSMCS0_2SSMCS9); + + if (IS_HARDWARE_TYPE_8814A(Adapter)) + { + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, HT_MCS16_MCS23 ); + PHY_SetTxPowerIndexByRateSection( Adapter, path, channel, VHT_3SSMCS0_3SSMCS9 ); + } + } + } +} + +VOID +PHY_SetTxPowerIndexByRateArray( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + IN u8* Rates, + IN u8 RateArraySize + ) +{ + u32 powerIndex = 0; + int i = 0; + + for (i = 0; i < RateArraySize; ++i) + { + powerIndex = PHY_GetTxPowerIndex(pAdapter, RFPath, Rates[i], BandWidth, Channel); + PHY_SetTxPowerIndex(pAdapter, powerIndex, RFPath, Rates[i]); + } +} + +s8 +phy_GetWorldWideLimit( + s8* LimitTable +) +{ + s8 min = LimitTable[0]; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + if (LimitTable[i] < min) + min = LimitTable[i]; + } + + return min; +} + +s8 +phy_GetChannelIndexOfTxPowerLimit( + IN u8 Band, + IN u8 Channel + ) +{ + s8 channelIndex = -1; + u8 i = 0; + + if (Band == BAND_ON_2_4G) { + channelIndex = Channel - 1; + } else if (Band == BAND_ON_5G) { + for (i = 0; i < CENTER_CH_5G_ALL_NUM; ++i) { + if (center_ch_5g_all[i] == Channel) + channelIndex = i; + } + } else { + DBG_871X_LEVEL(_drv_always_, "Invalid Band %d in %s\n", Band, __func__); + } + + if (channelIndex == -1) + DBG_871X_LEVEL(_drv_always_, "Invalid Channel %d of Band %d in %s\n", Channel, Band, __func__); + + return channelIndex; +} + +s8 +PHY_GetTxPowerLimit( + IN PADAPTER Adapter, + IN u32 RegPwrTblSel, + IN BAND_TYPE Band, + IN CHANNEL_WIDTH Bandwidth, + IN u8 RfPath, + IN u8 DataRate, + IN u8 Channel + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s16 band = -1, regulation = -1, bandwidth = -1, + rateSection = -1, channel = -1; + s8 powerLimit = MAX_POWER_INDEX; + + if ( ( Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory != 1 ) || + Adapter->registrypriv.RegEnableTxPowerLimit == 0 ) + return MAX_POWER_INDEX; + + switch (RegPwrTblSel) { + case 1: + regulation = TXPWR_LMT_ETSI; + break; + case 2: + regulation = TXPWR_LMT_MKK; + break; + case 3: + regulation = TXPWR_LMT_FCC; + break; + case 4: + regulation = TXPWR_LMT_WW; + break; + default: + regulation = (Band == BAND_ON_2_4G) ? pHalData->Regulation2_4G : pHalData->Regulation5G; + break; + } + + //DBG_871X("pMgntInfo->RegPwrTblSel %d, final regulation %d\n", Adapter->registrypriv.RegPwrTblSel, regulation ); + + + if ( Band == BAND_ON_2_4G ) band = 0; + else if ( Band == BAND_ON_5G ) band = 1; + + if ( Bandwidth == CHANNEL_WIDTH_20 ) bandwidth = 0; + else if ( Bandwidth == CHANNEL_WIDTH_40 ) bandwidth = 1; + else if ( Bandwidth == CHANNEL_WIDTH_80 ) bandwidth = 2; + else if ( Bandwidth == CHANNEL_WIDTH_160 ) bandwidth = 3; + + switch ( DataRate ) + { + case MGN_1M: case MGN_2M: case MGN_5_5M: case MGN_11M: + rateSection = 0; + break; + + case MGN_6M: case MGN_9M: case MGN_12M: case MGN_18M: + case MGN_24M: case MGN_36M: case MGN_48M: case MGN_54M: + rateSection = 1; + break; + + case MGN_MCS0: case MGN_MCS1: case MGN_MCS2: case MGN_MCS3: + case MGN_MCS4: case MGN_MCS5: case MGN_MCS6: case MGN_MCS7: + rateSection = 2; + break; + + case MGN_MCS8: case MGN_MCS9: case MGN_MCS10: case MGN_MCS11: + case MGN_MCS12: case MGN_MCS13: case MGN_MCS14: case MGN_MCS15: + rateSection = 3; + break; + + case MGN_MCS16: case MGN_MCS17: case MGN_MCS18: case MGN_MCS19: + case MGN_MCS20: case MGN_MCS21: case MGN_MCS22: case MGN_MCS23: + rateSection = 4; + break; + + case MGN_MCS24: case MGN_MCS25: case MGN_MCS26: case MGN_MCS27: + case MGN_MCS28: case MGN_MCS29: case MGN_MCS30: case MGN_MCS31: + rateSection = 5; + break; + + case MGN_VHT1SS_MCS0: case MGN_VHT1SS_MCS1: case MGN_VHT1SS_MCS2: + case MGN_VHT1SS_MCS3: case MGN_VHT1SS_MCS4: case MGN_VHT1SS_MCS5: + case MGN_VHT1SS_MCS6: case MGN_VHT1SS_MCS7: case MGN_VHT1SS_MCS8: + case MGN_VHT1SS_MCS9: + rateSection = 6; + break; + + case MGN_VHT2SS_MCS0: case MGN_VHT2SS_MCS1: case MGN_VHT2SS_MCS2: + case MGN_VHT2SS_MCS3: case MGN_VHT2SS_MCS4: case MGN_VHT2SS_MCS5: + case MGN_VHT2SS_MCS6: case MGN_VHT2SS_MCS7: case MGN_VHT2SS_MCS8: + case MGN_VHT2SS_MCS9: + rateSection = 7; + break; + + case MGN_VHT3SS_MCS0: case MGN_VHT3SS_MCS1: case MGN_VHT3SS_MCS2: + case MGN_VHT3SS_MCS3: case MGN_VHT3SS_MCS4: case MGN_VHT3SS_MCS5: + case MGN_VHT3SS_MCS6: case MGN_VHT3SS_MCS7: case MGN_VHT3SS_MCS8: + case MGN_VHT3SS_MCS9: + rateSection = 8; + break; + + case MGN_VHT4SS_MCS0: case MGN_VHT4SS_MCS1: case MGN_VHT4SS_MCS2: + case MGN_VHT4SS_MCS3: case MGN_VHT4SS_MCS4: case MGN_VHT4SS_MCS5: + case MGN_VHT4SS_MCS6: case MGN_VHT4SS_MCS7: case MGN_VHT4SS_MCS8: + case MGN_VHT4SS_MCS9: + rateSection = 9; + break; + + default: + DBG_871X("Wrong rate 0x%x\n", DataRate ); + break; + } + + if ( Band == BAND_ON_5G && rateSection == 0 ) + DBG_871X("Wrong rate 0x%x: No CCK in 5G Band\n", DataRate ); + + // workaround for wrong index combination to obtain tx power limit, + // OFDM only exists in BW 20M + if ( rateSection == 1 ) + bandwidth = 0; + + // workaround for wrong index combination to obtain tx power limit, + // CCK table will only be given in BW 20M + if ( rateSection == 0 ) + bandwidth = 0; + + // workaround for wrong indxe combination to obtain tx power limit, + // HT on 80M will reference to HT on 40M + if ( ( rateSection == 2 || rateSection == 3 ) && Band == BAND_ON_5G && bandwidth == 2 ) { + bandwidth = 1; + } + + if ( Band == BAND_ON_2_4G ) + channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_2_4G, Channel ); + else if ( Band == BAND_ON_5G ) + channel = phy_GetChannelIndexOfTxPowerLimit( BAND_ON_5G, Channel ); + else if ( Band == BAND_ON_BOTH ) + { + // BAND_ON_BOTH don't care temporarily + } + + if ( band == -1 || regulation == -1 || bandwidth == -1 || + rateSection == -1 || channel == -1 ) + { + //DBG_871X("Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnlGroup %d]\n", + // band, regulation, bandwidth, RfPath, rateSection, channelGroup ); + + return MAX_POWER_INDEX; + } + + if ( Band == BAND_ON_2_4G ) { + s8 limits[10] = {0}; u8 i = 0; + if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) + bandwidth = MAX_2_4G_BANDWIDTH_NUM - 1; + for (i = 0; i < MAX_REGULATION_NUM; ++i) + limits[i] = pHalData->TxPwrLimit_2_4G[i][bandwidth][rateSection][channel][RfPath]; + + powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) : + pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channel][RfPath]; + + } else if ( Band == BAND_ON_5G ) { + s8 limits[10] = {0}; u8 i = 0; + for (i = 0; i < MAX_REGULATION_NUM; ++i) + limits[i] = pHalData->TxPwrLimit_5G[i][bandwidth][rateSection][channel][RfPath]; + + powerLimit = (regulation == TXPWR_LMT_WW) ? phy_GetWorldWideLimit(limits) : + pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channel][RfPath]; + } else + DBG_871X("No power limit table of the specified band\n" ); + + // combine 5G VHT & HT rate + // 5G 20M and 40M HT and VHT can cross reference + /* + if ( Band == BAND_ON_5G && powerLimit == MAX_POWER_INDEX ) { + if ( bandwidth == 0 || bandwidth == 1 ) { + RT_TRACE( COMP_INIT, DBG_LOUD, ( "No power limit table of the specified band %d, bandwidth %d, ratesection %d, rf path %d\n", + band, bandwidth, rateSection, RfPath ) ); + if ( rateSection == 2 ) + powerLimit = pHalData->TxPwrLimit_5G[regulation] + [bandwidth][4][channelGroup][RfPath]; + else if ( rateSection == 4 ) + powerLimit = pHalData->TxPwrLimit_5G[regulation] + [bandwidth][2][channelGroup][RfPath]; + else if ( rateSection == 3 ) + powerLimit = pHalData->TxPwrLimit_5G[regulation] + [bandwidth][5][channelGroup][RfPath]; + else if ( rateSection == 5 ) + powerLimit = pHalData->TxPwrLimit_5G[regulation] + [bandwidth][3][channelGroup][RfPath]; + } + } + */ + //DBG_871X("TxPwrLmt[Regulation %d][Band %d][BW %d][RFPath %d][Rate 0x%x][Chnl %d] = %d\n", + // regulation, pHalData->CurrentBandType, Bandwidth, RfPath, DataRate, Channel, powerLimit); + return powerLimit; +} + +VOID +phy_CrossReferenceHTAndVHTTxPowerLimit( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 regulation, bw, channel, rs, ref_rs; + int ht_ref_vht_5g_20_40 = 0; + int vht_ref_ht_5g_20_40 = 0; + int ht_has_ref_5g_20_40 = 0; + int vht_has_ref_5g_20_40 = 0; + + pHalData->tx_pwr_lmt_5g_20_40_ref = 0; + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + + for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) { + + for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) { + + /* 5G 20M 40M VHT and HT can cross reference */ + if (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40) { + if (rs == HT_1SS) + ref_rs = VHT_1SS; + else if (rs == HT_2SS) + ref_rs = VHT_2SS; + else if (rs == HT_3SS) + ref_rs = VHT_3SS; + else if (rs == HT_4SS) + ref_rs = VHT_4SS; + else if (rs == VHT_1SS) + ref_rs = HT_1SS; + else if (rs == VHT_2SS) + ref_rs = HT_2SS; + else if (rs == VHT_3SS) + ref_rs = HT_3SS; + else if (rs == VHT_4SS) + ref_rs = HT_4SS; + else + continue; + + if (pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A] == MAX_POWER_INDEX) + continue; + + if (IS_HT_RATE_SECTION(rs)) + ht_has_ref_5g_20_40++; + else if (IS_VHT_RATE_SECTION(rs)) + vht_has_ref_5g_20_40++; + else + continue; + + if (pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] != MAX_POWER_INDEX) + continue; + + if (IS_HT_RATE_SECTION(rs) && IS_VHT_RATE_SECTION(ref_rs)) + ht_ref_vht_5g_20_40++; + else if (IS_VHT_RATE_SECTION(rs) && IS_HT_RATE_SECTION(ref_rs)) + vht_ref_ht_5g_20_40++; + + if (0) + DBG_871X("reg:%u, bw:%u, ch:%u, %s ref %s\n" + , regulation, bw, channel + , rate_section_str(rs), rate_section_str(ref_rs)); + + pHalData->TxPwrLimit_5G[regulation][bw][rs][channel][RF_PATH_A] = + pHalData->TxPwrLimit_5G[regulation][bw][ref_rs][channel][RF_PATH_A]; + } + + } + } + } + } + + if (0) { + DBG_871X("ht_ref_vht_5g_20_40:%d, ht_has_ref_5g_20_40:%d\n", ht_ref_vht_5g_20_40, ht_has_ref_5g_20_40); + DBG_871X("vht_ref_hht_5g_20_40:%d, vht_has_ref_5g_20_40:%d\n", vht_ref_ht_5g_20_40, vht_has_ref_5g_20_40); + } + + /* 5G 20M&40M HT all come from VHT*/ + if (ht_ref_vht_5g_20_40 && ht_has_ref_5g_20_40 == ht_ref_vht_5g_20_40) + pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_HT_FROM_VHT; + + /* 5G 20M&40M VHT all come from HT*/ + if (vht_ref_ht_5g_20_40 && vht_has_ref_5g_20_40 == vht_ref_ht_5g_20_40) + pHalData->tx_pwr_lmt_5g_20_40_ref |= TX_PWR_LMT_REF_VHT_FROM_HT; +} + +VOID +PHY_ConvertTxPowerLimitToPowerIndex( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 base; + u8 regulation, bw, channel, rateSection; + s8 tempValue = 0, tempPwrLmt = 0; + u8 rfPath = 0; + + if (pHalData->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) { + rtw_warn_on(1); + return; + } + + phy_CrossReferenceHTAndVHTTxPowerLimit(Adapter); + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + + for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) { + + for (channel = 0; channel < CENTER_CH_2G_NUM; ++channel) { + + for (rateSection = CCK; rateSection <= HT_4SS; ++rateSection) { + tempPwrLmt = pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][RF_PATH_A]; + + if (tempPwrLmt != MAX_POWER_INDEX) { + + for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) { + base = phy_get_target_tx_power(Adapter, BAND_ON_2_4G, rfPath, rateSection); + tempValue = tempPwrLmt - base; + pHalData->TxPwrLimit_2_4G[regulation][bw][rateSection][channel][rfPath] = tempValue; + } + } + } + } + } + } + + if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) { + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + + for (channel = 0; channel < CENTER_CH_5G_ALL_NUM; ++channel) { + + for (rateSection = OFDM; rateSection <= VHT_4SS; ++rateSection) { + tempPwrLmt = pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][RF_PATH_A]; + + if (tempPwrLmt != MAX_POWER_INDEX) { + + for (rfPath = RF_PATH_A; rfPath < MAX_RF_PATH; ++rfPath) { + base = phy_get_target_tx_power(Adapter, BAND_ON_5G, rfPath, rateSection); + tempValue = tempPwrLmt - base; + pHalData->TxPwrLimit_5G[regulation][bw][rateSection][channel][rfPath] = tempValue; + } + } + } + } + } + } + } +} + +/* +* PHY_InitTxPowerLimit - Set all hal_data.TxPwrLimit_2_4G, TxPwrLimit_5G array to MAX_POWER_INDEX +*/ +VOID +PHY_InitTxPowerLimit( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 i, j, k, l, m; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) + for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CENTER_CH_2G_NUM; ++m) + for (l = 0; l < MAX_RF_PATH; ++l) + pHalData->TxPwrLimit_2_4G[i][j][k][m][l] = MAX_POWER_INDEX; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) + for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CENTER_CH_5G_ALL_NUM; ++m) + for (l = 0; l < MAX_RF_PATH; ++l) + pHalData->TxPwrLimit_5G[i][j][k][m][l] = MAX_POWER_INDEX; +} + +/* +* PHY_SetTxPowerLimit - Parsing TX power limit from phydm array, called by odm_ConfigBB_TXPWR_LMT_XXX in phydm +*/ +VOID +PHY_SetTxPowerLimit( + IN PDM_ODM_T pDM_Odm, + IN u8 *Regulation, + IN u8 *Band, + IN u8 *Bandwidth, + IN u8 *RateSection, + IN u8 *RfPath, + IN u8 *Channel, + IN u8 *PowerLimit + ) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 regulation = 0, bandwidth = 0, rateSection = 0, channel; + s8 powerLimit = 0, prevPowerLimit, channelIndex; + + if (0) + DBG_871X("Index of power limit table [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s][val %s]\n" + , Band, Regulation, Bandwidth, RateSection, RfPath, Channel, PowerLimit); + + if (GetU1ByteIntegerFromStringInDecimal((s8 *)Channel, &channel) == _FALSE + || GetU1ByteIntegerFromStringInDecimal((s8 *)PowerLimit, &powerLimit) == _FALSE + ){ + DBG_871X_LEVEL(_drv_always_, "Illegal index of power limit table [ch %s][val %s]\n", Channel, PowerLimit); + return; + } + + powerLimit = powerLimit > MAX_POWER_INDEX ? MAX_POWER_INDEX : powerLimit; + + if (eqNByte(Regulation, (u8 *)("FCC"), 3)) + regulation = TXPWR_LMT_FCC; + else if (eqNByte(Regulation, (u8 *)("MKK"), 3)) + regulation = TXPWR_LMT_MKK; + else if (eqNByte(Regulation, (u8 *)("ETSI"), 4)) + regulation = TXPWR_LMT_ETSI; + else if (eqNByte(Regulation, (u8 *)("WW13"), 4)) + regulation = TXPWR_LMT_WW; + else { + DBG_871X_LEVEL(_drv_always_, "unknown regulation:%s", Regulation); + return; + } + + if (eqNByte(RateSection, (u8 *)("CCK"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2)) + rateSection = CCK; + else if (eqNByte(RateSection, (u8 *)("OFDM"), 4) && eqNByte(RfPath, (u8 *)("1T"), 2)) + rateSection = OFDM; + else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("1T"), 2)) + rateSection = HT_1SS; + else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("2T"), 2)) + rateSection = HT_2SS; + else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("3T"), 2)) + rateSection = HT_3SS; + else if (eqNByte(RateSection, (u8 *)("HT"), 2) && eqNByte(RfPath, (u8 *)("4T"), 2)) + rateSection = HT_4SS; + else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("1T"), 2)) + rateSection = VHT_1SS; + else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("2T"), 2)) + rateSection = VHT_2SS; + else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("3T"), 2)) + rateSection = VHT_3SS; + else if (eqNByte(RateSection, (u8 *)("VHT"), 3) && eqNByte(RfPath, (u8 *)("4T"), 2)) + rateSection = VHT_4SS; + else { + DBG_871X_LEVEL(_drv_always_, "Wrong rate section: (%s,%s)\n", RateSection, RfPath); + return; + } + + if (eqNByte(Bandwidth, (u8 *)("20M"), 3)) + bandwidth = CHANNEL_WIDTH_20; + else if (eqNByte(Bandwidth, (u8 *)("40M"), 3)) + bandwidth = CHANNEL_WIDTH_40; + else if (eqNByte(Bandwidth, (u8 *)("80M"), 3)) + bandwidth = CHANNEL_WIDTH_80; + else { + DBG_871X_LEVEL(_drv_always_, "unknown bandwidth: %s\n", Bandwidth); + return; + } + + if (eqNByte(Band, (u8 *)("2.4G"), 4)) { + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_2_4G, channel); + + if (channelIndex == -1) { + DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 2.4G\n", channel); + return; + } + + if (bandwidth >= MAX_2_4G_BANDWIDTH_NUM) { + DBG_871X_LEVEL(_drv_always_, "unsupported bandwidth: %s at 2.4G\n", Bandwidth); + return; + } + + prevPowerLimit = pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]; + + if (prevPowerLimit != MAX_POWER_INDEX) + DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n" + , Band, Regulation, Bandwidth, RateSection, RfPath, Channel); + + if (powerLimit < prevPowerLimit) + pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit; + + if (0) + DBG_871X("2.4G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n" + , regulation, bandwidth, rateSection, channelIndex, pHalData->TxPwrLimit_2_4G[regulation][bandwidth][rateSection][channelIndex][ODM_RF_PATH_A]); + } else if (eqNByte(Band, (u8 *)("5G"), 2)) { + + channelIndex = phy_GetChannelIndexOfTxPowerLimit(BAND_ON_5G, channel); + + if (channelIndex == -1) { + DBG_871X_LEVEL(_drv_always_, "unsupported channel: %d at 5G\n", channel); + return; + } + + prevPowerLimit = pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]; + + if (prevPowerLimit != MAX_POWER_INDEX) + DBG_871X_LEVEL(_drv_always_, "duplicate tx power limit combination [band %s][regulation %s][bw %s][rate section %s][rf path %s][chnl %s]\n" + , Band, Regulation, Bandwidth, RateSection, RfPath, Channel); + + if (powerLimit < prevPowerLimit) + pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A] = powerLimit; + + if (0) + DBG_871X("5G Band value : [regulation %d][bw %d][rate_section %d][chnl %d][val %d]\n" + , regulation, bandwidth, rateSection, channel, pHalData->TxPwrLimit_5G[regulation][bandwidth][rateSection][channelIndex][RF_PATH_A]); + } else { + DBG_871X_LEVEL(_drv_always_, "Cannot recognize the band info in %s\n", Band); + return; + } +} + +u8 +PHY_GetTxPowerIndex( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ) +{ + u8 txPower = 0x3E; + + if (IS_HARDWARE_TYPE_8814A(pAdapter)) { +#if (RTL8814A_SUPPORT == 1) + txPower = PHY_GetTxPowerIndex_8814A(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) { +#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1)) + txPower = PHY_GetTxPowerIndex_8812A(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } + else if (IS_HARDWARE_TYPE_8723B(pAdapter)) { +#if (RTL8723B_SUPPORT == 1) + txPower = PHY_GetTxPowerIndex_8723B(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } + else if (IS_HARDWARE_TYPE_8703B(pAdapter)) { +#if (RTL8703B_SUPPORT == 1) + txPower = PHY_GetTxPowerIndex_8703B(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } + else if (IS_HARDWARE_TYPE_8192E(pAdapter)) { +#if (RTL8192E_SUPPORT==1) + txPower = PHY_GetTxPowerIndex_8192E(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } + else if (IS_HARDWARE_TYPE_8188E(pAdapter)) { +#if (RTL8188E_SUPPORT==1) + txPower = PHY_GetTxPowerIndex_8188E(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) { +#if (RTL8188F_SUPPORT == 1) + txPower = PHY_GetTxPowerIndex_8188F(pAdapter, RFPath, Rate, BandWidth, Channel); +#endif + } + + return txPower; +} + +VOID +PHY_SetTxPowerIndex( + IN PADAPTER pAdapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ) +{ + if (IS_HARDWARE_TYPE_8814A(pAdapter)) { +#if (RTL8814A_SUPPORT == 1) + PHY_SetTxPowerIndex_8814A(pAdapter, PowerIndex, RFPath, Rate); +#endif + } + else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) { +#if ((RTL8812A_SUPPORT==1) || (RTL8821A_SUPPORT == 1)) + PHY_SetTxPowerIndex_8812A( pAdapter, PowerIndex, RFPath, Rate ); +#endif + } + else if (IS_HARDWARE_TYPE_8723B(pAdapter)) { +#if (RTL8723B_SUPPORT==1) + PHY_SetTxPowerIndex_8723B( pAdapter, PowerIndex, RFPath, Rate ); +#endif + } + else if (IS_HARDWARE_TYPE_8703B(pAdapter)) { +#if (RTL8703B_SUPPORT==1) + PHY_SetTxPowerIndex_8703B( pAdapter, PowerIndex, RFPath, Rate ); +#endif + } + else if (IS_HARDWARE_TYPE_8192E(pAdapter)) { +#if (RTL8192E_SUPPORT==1) + PHY_SetTxPowerIndex_8192E( pAdapter, PowerIndex, RFPath, Rate ); +#endif + } + else if (IS_HARDWARE_TYPE_8188E(pAdapter)) { +#if (RTL8188E_SUPPORT==1) + PHY_SetTxPowerIndex_8188E( pAdapter, PowerIndex, RFPath, Rate ); +#endif + } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) { +#if (RTL8188F_SUPPORT == 1) + PHY_SetTxPowerIndex_8188F(pAdapter, PowerIndex, RFPath, Rate); +#endif + } +} + +bool phy_is_tx_power_limit_needed(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + + if (regsty->RegEnableTxPowerLimit == 1 + || (regsty->RegEnableTxPowerLimit == 2 && hal_data->EEPROMRegulatory == 1)) + return _TRUE; + return _FALSE; +} + +bool phy_is_tx_power_by_rate_needed(_adapter *adapter) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + + if (regsty->RegEnableTxPowerByRate == 1 + || (regsty->RegEnableTxPowerByRate == 2 && hal_data->EEPROMRegulatory != 2)) + return _TRUE; + return _FALSE; +} + +int phy_load_tx_power_by_rate(_adapter *adapter, const char *hal_file_name, u8 force) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + int ret = _FAIL; + + if (!force + && !rtw_is_phy_file_readable(hal_file_name) + && hal_data->txpwr_by_rate_loaded == 1 + && hal_data->txpwr_by_rate_from_file == 0 + ) { + /* No file and already load default(compile-time) table */ + ret = _SUCCESS; + goto exit; + } + + hal_data->txpwr_by_rate_loaded = 0; + PHY_InitTxPowerByRate(adapter); + + /* tx power limit is based on tx power by rate */ + hal_data->txpwr_limit_loaded = 0; + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (rtw_is_phy_file_readable(hal_file_name) + && phy_ConfigBBWithPgParaFile(adapter, hal_file_name) == _SUCCESS + ) { + hal_data->txpwr_by_rate_from_file = 1; + goto post_hdl; + } +#endif + +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_SUCCESS == ODM_ConfigBBWithHeaderFile(&hal_data->odmpriv, CONFIG_BB_PHY_REG_PG)) { + DBG_871X("default power by rate loaded\n"); + hal_data->txpwr_by_rate_from_file = 0; + goto post_hdl; + } +#endif + + DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power by rate fail\n", __func__); + goto exit; + +post_hdl: + if (hal_data->odmpriv.PhyRegPgValueType != PHY_REG_PG_EXACT_VALUE) { + rtw_warn_on(1); + goto exit; + } + + PHY_TxPowerByRateConfiguration(adapter); + hal_data->txpwr_by_rate_loaded = 1; + + ret = _SUCCESS; + +exit: + return ret; +} + +int phy_load_tx_power_limit(_adapter *adapter, const char *hal_file_name, u8 force) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + int ret = _FAIL; + + if (!force + && !rtw_is_phy_file_readable(hal_file_name) + && hal_data->txpwr_by_rate_loaded == 1 + && hal_data->txpwr_by_rate_from_file == 0 + ) { + /* No file and already load default(compile-time) table */ + ret = _SUCCESS; + goto exit; + } + + hal_data->txpwr_limit_loaded = 0; + PHY_InitTxPowerLimit(adapter); + + if (!hal_data->txpwr_by_rate_loaded && regsty->target_tx_pwr_valid != _TRUE) { + DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit before target tx power is specify\n", __func__); + goto exit; + } + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (rtw_is_phy_file_readable(hal_file_name) + && PHY_ConfigRFWithPowerLimitTableParaFile(adapter, hal_file_name) == _SUCCESS + ) { + hal_data->txpwr_limit_from_file = 1; + goto post_hdl; + } +#endif + +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_SUCCESS == ODM_ConfigRFWithHeaderFile(&hal_data->odmpriv, CONFIG_RF_TXPWR_LMT, (ODM_RF_RADIO_PATH_E)0)) { + DBG_871X("default power limit loaded\n"); + hal_data->txpwr_limit_from_file = 0; + goto post_hdl; + } +#endif + + DBG_871X_LEVEL(_drv_err_, "%s():Read Tx power limit fail\n", __func__); + goto exit; + +post_hdl: + PHY_ConvertTxPowerLimitToPowerIndex(adapter); + hal_data->txpwr_limit_loaded = 1; + ret = _SUCCESS; + +exit: + return ret; +} + +const char *hal_phy_reg_pg_str(_adapter *adapter) +{ + u8 interface_type = 0; + const char *str = NULL; + + interface_type = rtw_get_intf_type(adapter); + + switch (rtw_get_chip_type(adapter)) { +#ifdef CONFIG_RTL8723B + case RTL8723B: + str = RTL8723B_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8703B + case RTL8703B: + str = RTL8703B_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8188E + case RTL8188E: + str = RTL8188E_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8188F + case RTL8188F: + str = RTL8188F_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8812A + case RTL8812: + str = RTL8812_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8821A + case RTL8821: + str = RTL8821_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8192E + case RTL8192E: + str = RTL8192E_PHY_REG_PG; + break; +#endif +#ifdef CONFIG_RTL8814A + case RTL8814A: + str = RTL8814A_PHY_REG_PG; + break; +#endif + } + + if (str == NULL) { + DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n" + , __func__, rtw_get_chip_type(adapter)); + } + + return str; +} + +const char *hal_txpwr_lmt_str(_adapter *adapter) +{ + u8 interface_type = 0; + const char *str = NULL; + + interface_type = rtw_get_intf_type(adapter); + + switch (rtw_get_chip_type(adapter)) { +#ifdef CONFIG_RTL8723B + case RTL8723B: + str = RTL8723B_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8703B + case RTL8703B: + str = RTL8703B_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8188E + case RTL8188E: + str = RTL8188E_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8188F + case RTL8188F: + str = RTL8188F_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8812A + case RTL8812: + str = RTL8812_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8821A + case RTL8821: + str = RTL8821_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8192E + case RTL8192E: + str = RTL8192E_TXPWR_LMT; + break; +#endif +#ifdef CONFIG_RTL8814A + case RTL8814A: + str = RTL8814A_TXPWR_LMT; + break; +#endif + } + + if (str == NULL) { + DBG_871X_LEVEL(_drv_err_, "%s: unknown chip_type:%u\n" + , __func__, rtw_get_chip_type(adapter)); + } + + return str; +} + +void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file, u8 force) +{ + struct registry_priv *regsty = adapter_to_regsty(adapter); + const char *str = NULL; + + /* check registy target tx power */ + regsty->target_tx_pwr_valid = rtw_regsty_chk_target_tx_power_valid(adapter); + + /* power by rate and limit */ + if (phy_is_tx_power_by_rate_needed(adapter) + || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE) + ) { + str = chk_file ? hal_phy_reg_pg_str(adapter) : NULL; + phy_load_tx_power_by_rate(adapter, str, force); + } + + if (phy_is_tx_power_limit_needed(adapter)) { + str = chk_file ? hal_txpwr_lmt_str(adapter) : NULL; + phy_load_tx_power_limit(adapter, str, force); + } +} + +inline void phy_reload_tx_power_ext_info(_adapter *adapter) +{ + phy_load_tx_power_ext_info(adapter, 1, 1); +} + +inline void phy_reload_default_tx_power_ext_info(_adapter *adapter) +{ + phy_load_tx_power_ext_info(adapter, 0, 1); +} + +void dump_tx_power_ext_info(void *sel, _adapter *adapter) +{ + struct registry_priv *regsty = adapter_to_regsty(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + + if (phy_is_tx_power_by_rate_needed(adapter) + || (phy_is_tx_power_limit_needed(adapter) && regsty->target_tx_pwr_valid != _TRUE)) + DBG_871X_SEL_NL(sel, "target_tx_power: from powr by rate\n"); + else if (regsty->target_tx_pwr_valid == _TRUE) + DBG_871X_SEL_NL(sel, "target_tx_power: from registry\n"); + else + DBG_871X_SEL_NL(sel, "target_tx_power: unavailable\n"); + + + DBG_871X_SEL_NL(sel, "tx_power_by_rate: %s, %s, %s\n" + , phy_is_tx_power_by_rate_needed(adapter) ? "enabled" : "disabled" + , hal_data->txpwr_by_rate_loaded ? "loaded" : "unloaded" + , hal_data->txpwr_by_rate_from_file ? "file" : "default" + ); + + DBG_871X_SEL_NL(sel, "tx_power_limit: %s, %s, %s\n" + , phy_is_tx_power_limit_needed(adapter) ? "enabled" : "disabled" + , hal_data->txpwr_limit_loaded ? "loaded" : "unloaded" + , hal_data->txpwr_limit_from_file ? "file" : "default" + ); +} + +void dump_target_tx_power(void *sel, _adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = adapter_to_regsty(adapter); + int path, tx_num, band, rs; + u8 target; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + if (!hal_is_band_support(adapter, band)) + continue; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + + DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path)); + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num >= hal_spec->nss_num) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + continue; + + target = phy_get_target_tx_power(adapter, band, path, rs); + + if (target % 2) + DBG_871X_SEL(sel, "%7s: %2d.5\n", rate_section_str(rs), target / 2); + else + DBG_871X_SEL(sel, "%7s: %4d\n", rate_section_str(rs), target / 2); + } + } + } + +exit: + return; +} + +void dump_tx_power_by_rate(void *sel, _adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + int path, tx_num, band, n, rs; + u8 rate_num, max_rate_num, base; + s8 by_rate_offset; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + if (!hal_is_band_support(adapter, band)) + continue; + + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + + DBG_871X_SEL_NL(sel, "[%s][%c]\n", band_str(band), rf_path_char(path)); + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + tx_num = rate_section_to_tx_num(rs); + if (tx_num >= hal_spec->nss_num) + continue; + + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + continue; + + if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + max_rate_num = 10; + else + max_rate_num = 8; + rate_num = rate_section_rate_num(rs); + base = PHY_GetTxPowerByRateBase(adapter, band, path, tx_num, rs); + + DBG_871X_SEL_NL(sel, "%7s: ", rate_section_str(rs)); + + /* dump power by rate in db */ + for (n = rate_num - 1; n >= 0; n--) { + by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]); + + if ((base + by_rate_offset) % 2) + DBG_871X_SEL(sel, "%2d.5 ", (base + by_rate_offset) / 2); + else + DBG_871X_SEL(sel, "%4d ", (base + by_rate_offset) / 2); + } + for (n = 0; n < max_rate_num - rate_num; n++) + DBG_871X_SEL(sel, "%4s ", ""); + + DBG_871X_SEL(sel, "|"); + + /* dump power by rate in offset */ + for (n = rate_num - 1; n >= 0; n--) { + by_rate_offset = PHY_GetTxPowerByRate(adapter, band, path, tx_num, rates_by_sections[rs].rates[n]); + DBG_871X_SEL(sel, "%3d ", by_rate_offset); + } + DBG_871X_SEL_NL(sel, "\n"); + + } + } + } +} + +void dump_tx_power_limit(void *sel, _adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter)); + + int bw, band, ch_num, rs, i, path; + u8 ch, n, rd; + + if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + DBG_871X_SEL_NL(sel, "tx_pwr_lmt_5g_20_40_ref:0x%02x\n", hal_data->tx_pwr_lmt_5g_20_40_ref); + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + if (!hal_is_band_support(adapter, band)) + continue; + + rd = (band == BAND_ON_2_4G ? hal_data->Regulation2_4G : hal_data->Regulation5G); + + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; bw++) { + + if (bw >= CHANNEL_WIDTH_160) + break; + if (band == BAND_ON_2_4G && bw >= CHANNEL_WIDTH_80) + break; + + if (band == BAND_ON_2_4G) + ch_num = CENTER_CH_2G_NUM; + else + ch_num = center_chs_5g_num(bw); + + if (ch_num == 0) { + rtw_warn_on(1); + break; + } + + for (rs = 0; rs < RATE_SECTION_NUM; rs++) { + if (band == BAND_ON_2_4G && IS_VHT_RATE_SECTION(rs)) + continue; + if (band == BAND_ON_5G && IS_CCK_RATE_SECTION(rs)) + continue; + if (bw > CHANNEL_WIDTH_20 && (IS_CCK_RATE_SECTION(rs) || IS_OFDM_RATE_SECTION(rs))) + continue; + if (bw > CHANNEL_WIDTH_40 && IS_HT_RATE_SECTION(rs)) + continue; + + if (rate_section_to_tx_num(rs) >= hal_spec->nss_num) + continue; + + if (IS_VHT_RATE_SECTION(rs) && !IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter)) + continue; + + /* by pass 5G 20M, 40M pure reference */ + if (band == BAND_ON_5G && (bw == CHANNEL_WIDTH_20 || bw == CHANNEL_WIDTH_40)) { + if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_HT_FROM_VHT) { + if (IS_HT_RATE_SECTION(rs)) + continue; + } else if (hal_data->tx_pwr_lmt_5g_20_40_ref == TX_PWR_LMT_REF_VHT_FROM_HT) { + if (IS_VHT_RATE_SECTION(rs) && bw <= CHANNEL_WIDTH_40) + continue; + } + } + + DBG_871X_SEL_NL(sel, "[%s][%s][%s]\n" + , band_str(band) + , ch_width_str(bw) + , rate_section_str(rs) + ); + + /* header for limit in db */ + DBG_871X_SEL_NL(sel, "%3s %5s %5s %5s %5s " + , "ch" + , (rd == TXPWR_LMT_FCC ? "*FCC" : "FCC") + , (rd == TXPWR_LMT_ETSI ? "*ETSI" : "ETSI") + , (rd == TXPWR_LMT_MKK ? "*MKK" : "MKK") + , (rd == TXPWR_LMT_WW ? "*WW" : "WW") + ); + + /* header for limit offset */ + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + DBG_871X_SEL(sel, "|%3c %3c %3c %3c " + , (rd == TXPWR_LMT_FCC ? rf_path_char(path) : ' ') + , (rd == TXPWR_LMT_ETSI ? rf_path_char(path) : ' ') + , (rd == TXPWR_LMT_MKK ? rf_path_char(path) : ' ') + , (rd == TXPWR_LMT_WW ? rf_path_char(path) : ' ') + ); + } + DBG_871X_SEL(sel, "\n"); + + for (n = 0; n < ch_num; n++) { + s8 limit_idx[RF_PATH_MAX][MAX_REGULATION_NUM]; + s8 limit_offset[MAX_REGULATION_NUM]; + u8 base; + + if (band == BAND_ON_2_4G) + ch = n + 1; + else + ch = center_chs_5g(bw, n); + + if (ch == 0) { + rtw_warn_on(1); + break; + } + + /* dump limit in db (calculate from path A) */ + limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* FCC */ + limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* ETSI */ + limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* MKK */ + limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, RF_PATH_A, rates_by_sections[rs].rates[0], ch); /* WW */ + + base = phy_get_target_tx_power(adapter, band, RF_PATH_A, rs); + + DBG_871X_SEL_NL(sel, "%3u ", ch); + for (i = 0; i < MAX_REGULATION_NUM; i++) { + if (limit_offset[i] == MAX_POWER_INDEX) { + limit_idx[0][i] = MAX_POWER_INDEX; + DBG_871X_SEL(sel, "%5s ", "NA"); + } else { + limit_idx[0][i] = limit_offset[i] + base; + if ((limit_offset[i] + base) % 2) + DBG_871X_SEL(sel, "%3d.5 ", (limit_offset[i] + base) / 2); + else + DBG_871X_SEL(sel, "%5d ", (limit_offset[i] + base) / 2); + } + } + + /* dump limit offset of each path */ + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + limit_offset[0] = PHY_GetTxPowerLimit(adapter, 3, band, bw, path, rates_by_sections[rs].rates[0], ch); /* FCC */ + limit_offset[1] = PHY_GetTxPowerLimit(adapter, 1, band, bw, path, rates_by_sections[rs].rates[0], ch); /* ETSI */ + limit_offset[2] = PHY_GetTxPowerLimit(adapter, 2, band, bw, path, rates_by_sections[rs].rates[0], ch); /* MKK */ + limit_offset[3] = PHY_GetTxPowerLimit(adapter, 4, band, bw, path, rates_by_sections[rs].rates[0], ch); /* WW */ + + base = phy_get_target_tx_power(adapter, band, path, rs); + + DBG_871X_SEL(sel, "|"); + for (i = 0; i < MAX_REGULATION_NUM; i++) { + if (limit_offset[i] == MAX_POWER_INDEX) { + limit_idx[path][i] = MAX_POWER_INDEX; + DBG_871X_SEL(sel, "%3s ", "NA"); + } else { + limit_idx[path][i] = limit_offset[i] + base; + DBG_871X_SEL(sel, "%3d ", limit_offset[i]); + } + } + } + + /* compare limit_idx of each path, print 'x' when mismatch */ + if (hal_data->NumTotalRFPath > 1) { + for (i = 0; i < MAX_REGULATION_NUM; i++) { + for (path = 0; path < RF_PATH_MAX; path++) { + if (path >= hal_data->NumTotalRFPath) + break; + if (limit_idx[path][i] != limit_idx[(path + 1) % hal_data->NumTotalRFPath][i]) + break; + } + if (path >= hal_data->NumTotalRFPath) + DBG_871X_SEL(sel, " "); + else + DBG_871X_SEL(sel, "x"); + } + } + DBG_871X_SEL(sel, "\n"); + + } + DBG_871X_SEL_NL(sel, "\n"); + } + } + } +} + +int rtw_is_phy_file_readable(const char *hal_file_name) +{ +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (hal_file_name) { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, hal_file_name); + return rtw_is_file_readable(file_path); + } +#endif + return _FALSE; +} + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +int +phy_ConfigMACWithParaFile( + IN PADAPTER Adapter, + IN char* pFileName +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + char *szLine, *ptmp; + u32 u4bRegOffset, u4bRegValue, u4bMove; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_MAC_PARA_FILE)) + return rtStatus; + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if ((pHalData->mac_reg_len == 0) && (pHalData->mac_reg == NULL)) + { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pHalData->mac_reg = rtw_zvmalloc(rlen); + if(pHalData->mac_reg) { + _rtw_memcpy(pHalData->mac_reg, pHalData->para_file_buf, rlen); + pHalData->mac_reg_len = rlen; + } + else { + DBG_871X("%s mac_reg alloc fail !\n",__FUNCTION__); + } + } + } + } + else + { + if ((pHalData->mac_reg_len != 0) && (pHalData->mac_reg != NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pHalData->mac_reg, pHalData->mac_reg_len); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if (rtStatus == _SUCCESS) + { + ptmp = pHalData->para_file_buf; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if(!IsCommentString(szLine)) + { + // Get 1st hex value as register offset + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + if(u4bRegOffset == 0xffff) + { // Ending. + break; + } + + // Get 2nd hex value as register value. + szLine += u4bMove; + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + rtw_write8(Adapter, u4bRegOffset, (u8)u4bRegValue); + } + } + } + } + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +int +phy_ConfigBBWithParaFile( + IN PADAPTER Adapter, + IN char* pFileName, + IN u32 ConfigType +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + char *szLine, *ptmp; + u32 u4bRegOffset, u4bRegValue, u4bMove; + char *pBuf = NULL; + u32 *pBufLen = NULL; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PARA_FILE)) + return rtStatus; + + switch(ConfigType) + { + case CONFIG_BB_PHY_REG: + pBuf = pHalData->bb_phy_reg; + pBufLen = &pHalData->bb_phy_reg_len; + break; + case CONFIG_BB_AGC_TAB: + pBuf = pHalData->bb_agc_tab; + pBufLen = &pHalData->bb_agc_tab_len; + break; + default: + DBG_871X("Unknown ConfigType!! %d\r\n", ConfigType); + break; + } + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) + { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pBuf = rtw_zvmalloc(rlen); + if(pBuf) { + _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen); + *pBufLen = rlen; + + switch(ConfigType) + { + case CONFIG_BB_PHY_REG: + pHalData->bb_phy_reg = pBuf; + break; + case CONFIG_BB_AGC_TAB: + pHalData->bb_agc_tab = pBuf; + break; + } + } + else { + DBG_871X("%s(): ConfigType %d alloc fail !\n",__FUNCTION__,ConfigType); + } + } + } + } + else + { + if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if (rtStatus == _SUCCESS) + { + ptmp = pHalData->para_file_buf; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if(!IsCommentString(szLine)) + { + // Get 1st hex value as register offset. + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + if(u4bRegOffset == 0xffff) + { // Ending. + break; + } + else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) + { + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(50); + #else + rtw_mdelay_os(50); + #endif + } + else if (u4bRegOffset == 0xfd) + { + rtw_mdelay_os(5); + } + else if (u4bRegOffset == 0xfc) + { + rtw_mdelay_os(1); + } + else if (u4bRegOffset == 0xfb) + { + rtw_udelay_os(50); + } + else if (u4bRegOffset == 0xfa) + { + rtw_udelay_os(5); + } + else if (u4bRegOffset == 0xf9) + { + rtw_udelay_os(1); + } + + // Get 2nd hex value as register value. + szLine += u4bMove; + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + //DBG_871X("[BB-ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); + PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue); + + if (u4bRegOffset == 0xa24) + pHalData->odmpriv.RFCalibrateInfo.RegA24 = u4bRegValue; + + // Add 1us delay between BB/RF register setting. + rtw_udelay_os(1); + } + } + } + } + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +VOID +phy_DecryptBBPgParaFile( + PADAPTER Adapter, + char* buffer + ) +{ + u32 i = 0, j = 0; + u8 map[95] = {0}; + u8 currentChar; + char *BufOfLines, *ptmp; + + //DBG_871X("=====>phy_DecryptBBPgParaFile()\n"); + // 32 the ascii code of the first visable char, 126 the last one + for ( i = 0; i < 95; ++i ) + map[i] = ( u8 ) ( 94 - i ); + + ptmp = buffer; + i = 0; + for (BufOfLines = GetLineFromBuffer(ptmp); BufOfLines != NULL; BufOfLines = GetLineFromBuffer(ptmp)) + { + //DBG_871X("Encrypted Line: %s\n", BufOfLines); + + for ( j = 0; j < strlen(BufOfLines); ++j ) + { + currentChar = BufOfLines[j]; + + if ( currentChar == '\0' ) + break; + + currentChar -= (u8) ( ( ( ( i + j ) * 3 ) % 128 ) ); + + BufOfLines[j] = map[currentChar - 32] + 32; + } + //DBG_871X("Decrypted Line: %s\n", BufOfLines ); + if (strlen(BufOfLines) != 0) + i++; + BufOfLines[strlen(BufOfLines)] = '\n'; + } +} + +int +phy_ParseBBPgParaFile( + PADAPTER Adapter, + char* buffer + ) +{ + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + char *szLine, *ptmp; + u32 u4bRegOffset, u4bRegMask, u4bRegValue; + u32 u4bMove; + BOOLEAN firstLine = _TRUE; + u8 tx_num = 0; + u8 band = 0, rf_path = 0; + + //DBG_871X("=====>phy_ParseBBPgParaFile()\n"); + + if ( Adapter->registrypriv.RegDecryptCustomFile == 1 ) + phy_DecryptBBPgParaFile( Adapter, buffer); + + ptmp = buffer; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if (isAllSpaceOrTab(szLine, sizeof(*szLine))) + continue; + + if(!IsCommentString(szLine)) + { + // Get header info (relative value or exact value) + if ( firstLine ) + { + if ( eqNByte( szLine, (u8 *)("#[v1]"), 5 ) ) + { + + pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0'; + //DBG_871X("This is a new format PHY_REG_PG.txt \n"); + } + else if ( eqNByte( szLine, (u8 *)("#[v0]"), 5 )) + { + pHalData->odmpriv.PhyRegPgVersion = szLine[3] - '0'; + //DBG_871X("This is a old format PHY_REG_PG.txt ok\n"); + } + else + { + DBG_871X("The format in PHY_REG_PG are invalid %s\n", szLine); + return _FAIL; + } + + if ( eqNByte( szLine + 5, (u8 *)("[Exact]#"), 8 ) ) + { + pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE; + //DBG_871X("The values in PHY_REG_PG are exact values ok\n"); + firstLine = _FALSE; + continue; + } + else if ( eqNByte( szLine + 5, (pu1Byte)("[Relative]#"), 11 ) ) + { + pHalData->odmpriv.PhyRegPgValueType = PHY_REG_PG_RELATIVE_VALUE; + //DBG_871X("The values in PHY_REG_PG are relative values ok\n"); + firstLine = _FALSE; + continue; + } + else + { + DBG_871X("The values in PHY_REG_PG are invalid %s\n", szLine); + return _FAIL; + } + } + + if ( pHalData->odmpriv.PhyRegPgVersion == 0 ) + { + // Get 1st hex value as register offset. + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + szLine += u4bMove; + if(u4bRegOffset == 0xffff) + { // Ending. + break; + } + + // Get 2nd hex value as register mask. + if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) ) + szLine += u4bMove; + else + return _FAIL; + + if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) + { + // Get 3rd hex value as register value. + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, u4bRegValue); + //DBG_871X("[ADDR] %03X=%08X Mask=%08x\n", u4bRegOffset, u4bRegValue, u4bRegMask); + } + else + { + return _FAIL; + } + } + else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) + { + u32 combineValue = 0; + u8 integer = 0, fraction = 0; + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + PHY_StoreTxPowerByRate(Adapter, 0, 0, 1, u4bRegOffset, u4bRegMask, combineValue); + + //DBG_871X("[ADDR] 0x%3x = 0x%4x\n", u4bRegOffset, combineValue ); + } + } + } + else if ( pHalData->odmpriv.PhyRegPgVersion > 0 ) + { + u32 index = 0, cnt = 0; + + if ( eqNByte( szLine, "0xffff", 6 ) ) + break; + + if( !eqNByte( "#[END]#", szLine, 7 ) ) + { + // load the table label info + if ( szLine[0] == '#' ) + { + index = 0; + if ( eqNByte( szLine, "#[2.4G]" , 7 ) ) + { + band = BAND_ON_2_4G; + index += 8; + } + else if ( eqNByte( szLine, "#[5G]", 5) ) + { + band = BAND_ON_5G; + index += 6; + } + else + { + DBG_871X("Invalid band %s in PHY_REG_PG.txt \n", szLine ); + return _FAIL; + } + + rf_path= szLine[index] - 'A'; + //DBG_871X(" Table label Band %d, RfPath %d\n", band, rf_path ); + } + else // load rows of tables + { + if ( szLine[1] == '1' ) + tx_num = RF_1TX; + else if ( szLine[1] == '2' ) + tx_num = RF_2TX; + else if ( szLine[1] == '3' ) + tx_num = RF_3TX; + else if ( szLine[1] == '4' ) + tx_num = RF_4TX; + else + { + DBG_871X("Invalid row in PHY_REG_PG.txt '%c'(%d)\n", szLine[1], szLine[1]); + return _FAIL; + } + + while ( szLine[index] != ']' ) + ++index; + ++index;// skip ] + + // Get 2nd hex value as register offset. + szLine += index; + if ( GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove) ) + szLine += u4bMove; + else + return _FAIL; + + // Get 2nd hex value as register mask. + if ( GetHexValueFromString(szLine, &u4bRegMask, &u4bMove) ) + szLine += u4bMove; + else + return _FAIL; + + if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_RELATIVE_VALUE ) + { + // Get 3rd hex value as register value. + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, u4bRegValue); + //DBG_871X("[ADDR] %03X (tx_num %d) =%08X Mask=%08x\n", u4bRegOffset, tx_num, u4bRegValue, u4bRegMask); + } + else + { + return _FAIL; + } + } + else if ( pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE ) + { + u32 combineValue = 0; + u8 integer = 0, fraction = 0; + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + + if ( GetFractionValueFromString( szLine, &integer, &fraction, &u4bMove ) ) + szLine += u4bMove; + else + return _FAIL; + + integer *= 2; + if ( fraction == 5 ) integer += 1; + combineValue <<= 8; + combineValue |= ( ( ( integer / 10 ) << 4 ) + ( integer % 10 ) ); + //DBG_871X(" %d", integer ); + PHY_StoreTxPowerByRate(Adapter, band, rf_path, tx_num, u4bRegOffset, u4bRegMask, combineValue); + + //DBG_871X("[ADDR] 0x%3x (tx_num %d) = 0x%4x\n", u4bRegOffset, tx_num, combineValue ); + } + } + } + } + } + } + //DBG_871X("<=====phy_ParseBBPgParaFile()\n"); + return rtStatus; +} + +int +phy_ConfigBBWithPgParaFile( + IN PADAPTER Adapter, + IN const char *pFileName) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_PG_PARA_FILE)) + return rtStatus; + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if (pHalData->bb_phy_reg_pg == NULL) { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pHalData->bb_phy_reg_pg = rtw_zvmalloc(rlen); + if(pHalData->bb_phy_reg_pg) { + _rtw_memcpy(pHalData->bb_phy_reg_pg, pHalData->para_file_buf, rlen); + pHalData->bb_phy_reg_pg_len = rlen; + } + else { + DBG_871X("%s bb_phy_reg_pg alloc fail !\n",__FUNCTION__); + } + } + } + } else { + if ((pHalData->bb_phy_reg_pg_len != 0) && (pHalData->bb_phy_reg_pg != NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if(rtStatus == _SUCCESS) + { + //DBG_871X("phy_ConfigBBWithPgParaFile(): read %s ok\n", pFileName); + phy_ParseBBPgParaFile(Adapter, pHalData->para_file_buf); + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +#if (MP_DRIVER == 1 ) + +int +phy_ConfigBBWithMpParaFile( + IN PADAPTER Adapter, + IN char* pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + char *szLine, *ptmp; + u32 u4bRegOffset, u4bRegValue, u4bMove; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_BB_MP_PARA_FILE)) + return rtStatus; + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if ((pHalData->bb_phy_reg_mp_len == 0) && (pHalData->bb_phy_reg_mp == NULL)) + { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pHalData->bb_phy_reg_mp = rtw_zvmalloc(rlen); + if(pHalData->bb_phy_reg_mp) { + _rtw_memcpy(pHalData->bb_phy_reg_mp, pHalData->para_file_buf, rlen); + pHalData->bb_phy_reg_mp_len = rlen; + } + else { + DBG_871X("%s bb_phy_reg_mp alloc fail !\n",__FUNCTION__); + } + } + } + } + else + { + if ((pHalData->bb_phy_reg_mp_len != 0) && (pHalData->bb_phy_reg_mp != NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if(rtStatus == _SUCCESS) + { + //DBG_871X("phy_ConfigBBWithMpParaFile(): read %s ok\n", pFileName); + + ptmp = pHalData->para_file_buf; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if(!IsCommentString(szLine)) + { + // Get 1st hex value as register offset. + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + if(u4bRegOffset == 0xffff) + { // Ending. + break; + } + else if (u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) + { + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(50); + #else + rtw_mdelay_os(50); + #endif + } + else if (u4bRegOffset == 0xfd) + { + rtw_mdelay_os(5); + } + else if (u4bRegOffset == 0xfc) + { + rtw_mdelay_os(1); + } + else if (u4bRegOffset == 0xfb) + { + rtw_udelay_os(50); + } + else if (u4bRegOffset == 0xfa) + { + rtw_udelay_os(5); + } + else if (u4bRegOffset == 0xf9) + { + rtw_udelay_os(1); + } + + // Get 2nd hex value as register value. + szLine += u4bMove; + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + //DBG_871X("[ADDR]%03lX=%08lX\n", u4bRegOffset, u4bRegValue); + PHY_SetBBReg(Adapter, u4bRegOffset, bMaskDWord, u4bRegValue); + + // Add 1us delay between BB/RF register setting. + rtw_udelay_os(1); + } + } + } + } + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +#endif + +int +PHY_ConfigRFWithParaFile( + IN PADAPTER Adapter, + IN char* pFileName, + IN u8 eRFPath +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + char *szLine, *ptmp; + u32 u4bRegOffset, u4bRegValue, u4bMove; + u16 i; + char *pBuf = NULL; + u32 *pBufLen = NULL; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_PARA_FILE)) + return rtStatus; + + switch(eRFPath) + { + case ODM_RF_PATH_A: + pBuf = pHalData->rf_radio_a; + pBufLen = &pHalData->rf_radio_a_len; + break; + case ODM_RF_PATH_B: + pBuf = pHalData->rf_radio_b; + pBufLen = &pHalData->rf_radio_b_len; + break; + default: + DBG_871X("Unknown RF path!! %d\r\n", eRFPath); + break; + } + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) + { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pBuf = rtw_zvmalloc(rlen); + if(pBuf) { + _rtw_memcpy(pBuf, pHalData->para_file_buf, rlen); + *pBufLen = rlen; + + switch(eRFPath) + { + case ODM_RF_PATH_A: + pHalData->rf_radio_a = pBuf; + break; + case ODM_RF_PATH_B: + pHalData->rf_radio_b = pBuf; + break; + } + } + else { + DBG_871X("%s(): eRFPath=%d alloc fail !\n",__FUNCTION__,eRFPath); + } + } + } + } + else + { + if ((pBufLen != NULL) && (*pBufLen == 0) && (pBuf == NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pBuf, *pBufLen); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if(rtStatus == _SUCCESS) + { + //DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName); + + ptmp = pHalData->para_file_buf; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if(!IsCommentString(szLine)) + { + // Get 1st hex value as register offset. + if(GetHexValueFromString(szLine, &u4bRegOffset, &u4bMove)) + { + if(u4bRegOffset == 0xfe || u4bRegOffset == 0xffe) + { // Deay specific ms. Only RF configuration require delay. + #ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(50); + #else + rtw_mdelay_os(50); + #endif + } + else if (u4bRegOffset == 0xfd) + { + //delay_ms(5); + for(i=0;i<100;i++) + rtw_udelay_os(MAX_STALL_TIME); + } + else if (u4bRegOffset == 0xfc) + { + //delay_ms(1); + for(i=0;i<20;i++) + rtw_udelay_os(MAX_STALL_TIME); + } + else if (u4bRegOffset == 0xfb) + { + rtw_udelay_os(50); + } + else if (u4bRegOffset == 0xfa) + { + rtw_udelay_os(5); + } + else if (u4bRegOffset == 0xf9) + { + rtw_udelay_os(1); + } + else if(u4bRegOffset == 0xffff) + { + break; + } + + // Get 2nd hex value as register value. + szLine += u4bMove; + if(GetHexValueFromString(szLine, &u4bRegValue, &u4bMove)) + { + PHY_SetRFReg(Adapter, eRFPath, u4bRegOffset, bRFRegOffsetMask, u4bRegValue); + + // Temp add, for frequency lock, if no delay, that may cause + // frequency shift, ex: 2412MHz => 2417MHz + // If frequency shift, the following action may works. + // Fractional-N table in radio_a.txt + //0x2a 0x00001 // channel 1 + //0x2b 0x00808 frequency divider. + //0x2b 0x53333 + //0x2c 0x0000c + rtw_udelay_os(1); + } + } + } + } + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +VOID +initDeltaSwingIndexTables( + PADAPTER Adapter, + char* Band, + char* Path, + char* Sign, + char* Channel, + char* Rate, + char* Data +) +{ + #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \ + ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\ + (strcmp(Rate, _rate) == 0) && (strcmp(Channel, _chnl) == 0)\ + ) + #define STR_EQUAL_2G(_band, _path, _sign, _rate) \ + ((strcmp(Band, _band) == 0) && (strcmp(Path, _path) == 0) && (strcmp(Sign, _sign) == 0) &&\ + (strcmp(Rate, _rate) == 0)\ + ) + + #define STORE_SWING_TABLE(_array, _iteratedIdx) \ + for(token = strsep(&Data, delim); token != NULL; token = strsep(&Data, delim))\ + {\ + sscanf(token, "%d", &idx);\ + _array[_iteratedIdx++] = (u8)idx;\ + }\ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + u32 j = 0; + char *token; + char delim[] = ","; + u32 idx = 0; + + //DBG_871X("===>initDeltaSwingIndexTables(): Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n", + // Band, Path, Sign, Channel, Rate, Data); + + if ( STR_EQUAL_2G("2G", "A", "+", "CCK") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, j); + } + else if ( STR_EQUAL_2G("2G", "A", "-", "CCK") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, j); + } + else if ( STR_EQUAL_2G("2G", "B", "+", "CCK") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, j); + } + else if ( STR_EQUAL_2G("2G", "B", "-", "CCK") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, j); + } + else if ( STR_EQUAL_2G("2G", "A", "+", "ALL") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, j); + } + else if ( STR_EQUAL_2G("2G", "A", "-", "ALL") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, j); + } + else if ( STR_EQUAL_2G("2G", "B", "+", "ALL") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, j); + } + else if ( STR_EQUAL_2G("2G", "B", "-", "ALL") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, j); + } + else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "0") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[0], j); + } + else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "0") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[0], j); + } + else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "0") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[0], j); + } + else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "0") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[0], j); + } + else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "1") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[1], j); + } + else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "1") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[1], j); + } + else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "1") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[1], j); + } + else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "1") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[1], j); + } + else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "2") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[2], j); + } + else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "2") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[2], j); + } + else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "2") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[2], j); + } + else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "2") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[2], j); + } + else if ( STR_EQUAL_5G("5G", "A", "+", "ALL", "3") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[3], j); + } + else if ( STR_EQUAL_5G("5G", "A", "-", "ALL", "3") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[3], j); + } + else if ( STR_EQUAL_5G("5G", "B", "+", "ALL", "3") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[3], j); + } + else if ( STR_EQUAL_5G("5G", "B", "-", "ALL", "3") ) + { + STORE_SWING_TABLE(pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[3], j); + } + else + { + DBG_871X("===>initDeltaSwingIndexTables(): The input is invalid!!\n"); + } +} + +int +PHY_ConfigRFWithTxPwrTrackParaFile( + IN PADAPTER Adapter, + IN char* pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + int rlen = 0, rtStatus = _FAIL; + char *szLine, *ptmp; + u32 i = 0, j = 0; + char c = 0; + + if(!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE)) + return rtStatus; + + _rtw_memset(pHalData->para_file_buf, 0, MAX_PARA_FILE_BUF_LEN); + + if ((pHalData->rf_tx_pwr_track_len == 0) && (pHalData->rf_tx_pwr_track == NULL)) + { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pHalData->rf_tx_pwr_track = rtw_zvmalloc(rlen); + if(pHalData->rf_tx_pwr_track) { + _rtw_memcpy(pHalData->rf_tx_pwr_track, pHalData->para_file_buf, rlen); + pHalData->rf_tx_pwr_track_len = rlen; + } + else { + DBG_871X("%s rf_tx_pwr_track alloc fail !\n",__FUNCTION__); + } + } + } + } + else + { + if ((pHalData->rf_tx_pwr_track_len != 0) && (pHalData->rf_tx_pwr_track != NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if(rtStatus == _SUCCESS) + { + //DBG_871X("%s(): read %s successfully\n", __FUNCTION__, pFileName); + + ptmp = pHalData->para_file_buf; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if ( ! IsCommentString(szLine) ) + { + char band[5]="", path[5]="", sign[5] = ""; + char chnl[5]="", rate[10]=""; + char data[300]=""; // 100 is too small + + if (strlen(szLine) < 10 || szLine[0] != '[') + continue; + + strncpy(band, szLine+1, 2); + strncpy(path, szLine+5, 1); + strncpy(sign, szLine+8, 1); + + i = 10; // szLine+10 + if ( ! ParseQualifiedString(szLine, &i, rate, '[', ']') ) { + //DBG_871X("Fail to parse rate!\n"); + } + if ( ! ParseQualifiedString(szLine, &i, chnl, '[', ']') ) { + //DBG_871X("Fail to parse channel group!\n"); + } + while ( szLine[i] != '{' && i < strlen(szLine)) + i++; + if ( ! ParseQualifiedString(szLine, &i, data, '{', '}') ) { + //DBG_871X("Fail to parse data!\n"); + } + + initDeltaSwingIndexTables(Adapter, band, path, sign, chnl, rate, data); + } + } + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } +#if 0 + for (i = 0; i < DELTA_SWINGIDX_SIZE; ++i) + { + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P[i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[%d] = %d\n", i, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N[i]); + + for (j = 0; j < 3; ++j) + { + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P[j][i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N[j][i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P[j][i]); + DBG_871X("pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[%d][%d] = %d\n", j, i, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N[j][i]); + } + } +#endif + return rtStatus; +} + +int +phy_ParsePowerLimitTableFile( + PADAPTER Adapter, + char* buffer +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + u32 i = 0, forCnt = 0; + u8 loadingStage = 0, limitValue = 0, fraction = 0; + char *szLine, *ptmp; + int rtStatus = _SUCCESS; + char band[10], bandwidth[10], rateSection[10], + regulation[TXPWR_LMT_MAX_REGULATION_NUM][10], rfPath[10],colNumBuf[10]; + u8 colNum = 0; + + DBG_871X("===>phy_ParsePowerLimitTableFile()\n" ); + + if ( Adapter->registrypriv.RegDecryptCustomFile == 1 ) + phy_DecryptBBPgParaFile( Adapter, buffer); + + ptmp = buffer; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) + { + if (isAllSpaceOrTab(szLine, sizeof(*szLine))) + continue; + + // skip comment + if ( IsCommentString( szLine ) ) { + continue; + } + + if( loadingStage == 0 ) { + for ( forCnt = 0; forCnt < TXPWR_LMT_MAX_REGULATION_NUM; ++forCnt ) + _rtw_memset( ( PVOID ) regulation[forCnt], 0, 10 ); + _rtw_memset( ( PVOID ) band, 0, 10 ); + _rtw_memset( ( PVOID ) bandwidth, 0, 10 ); + _rtw_memset( ( PVOID ) rateSection, 0, 10 ); + _rtw_memset( ( PVOID ) rfPath, 0, 10 ); + _rtw_memset( ( PVOID ) colNumBuf, 0, 10 ); + + if ( szLine[0] != '#' || szLine[1] != '#' ) + continue; + + // skip the space + i = 2; + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + szLine[--i] = ' '; // return the space in front of the regulation info + + // Parse the label of the table + if ( ! ParseQualifiedString( szLine, &i, band, ' ', ',' ) ) { + DBG_871X( "Fail to parse band!\n"); + return _FAIL; + } + if ( ! ParseQualifiedString( szLine, &i, bandwidth, ' ', ',' ) ) { + DBG_871X("Fail to parse bandwidth!\n"); + return _FAIL; + } + if ( ! ParseQualifiedString( szLine, &i, rfPath, ' ', ',' ) ) { + DBG_871X("Fail to parse rf path!\n"); + return _FAIL; + } + if ( ! ParseQualifiedString( szLine, &i, rateSection, ' ', ',' ) ) { + DBG_871X("Fail to parse rate!\n"); + return _FAIL; + } + + loadingStage = 1; + } + else if ( loadingStage == 1 ) + { + if ( szLine[0] != '#' || szLine[1] != '#' ) + continue; + + // skip the space + i = 2; + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + if ( !eqNByte( (u8 *)(szLine + i), (u8 *)("START"), 5 ) ) { + DBG_871X("Lost \"## START\" label\n"); + return _FAIL; + } + + loadingStage = 2; + } + else if ( loadingStage == 2 ) + { + if ( szLine[0] != '#' || szLine[1] != '#' ) + continue; + + // skip the space + i = 2; + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + if ( ! ParseQualifiedString( szLine, &i, colNumBuf, '#', '#' ) ) { + DBG_871X("Fail to parse column number!\n"); + return _FAIL; + } + + if ( !GetU1ByteIntegerFromStringInDecimal( colNumBuf, &colNum ) ) + return _FAIL; + + if ( colNum > TXPWR_LMT_MAX_REGULATION_NUM ) { + DBG_871X("unvalid col number %d (greater than max %d)\n", + colNum, TXPWR_LMT_MAX_REGULATION_NUM ); + return _FAIL; + } + + for ( forCnt = 0; forCnt < colNum; ++forCnt ) + { + u8 regulation_name_cnt = 0; + + // skip the space + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + while ( szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0' ) + regulation[forCnt][regulation_name_cnt++] = szLine[i++]; + //DBG_871X("regulation %s!\n", regulation[forCnt]); + + if ( regulation_name_cnt == 0 ) { + DBG_871X("unvalid number of regulation!\n"); + return _FAIL; + } + } + + loadingStage = 3; + } + else if ( loadingStage == 3 ) + { + char channel[10] = {0}, powerLimit[10] = {0}; + u8 cnt = 0; + + // the table ends + if ( szLine[0] == '#' && szLine[1] == '#' ) { + i = 2; + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + if ( eqNByte( (u8 *)(szLine + i), (u8 *)("END"), 3 ) ) { + loadingStage = 0; + continue; + } + else { + DBG_871X("Wrong format\n"); + DBG_871X("<===== phy_ParsePowerLimitTableFile()\n"); + return _FAIL; + } + } + + if ( ( szLine[0] != 'c' && szLine[0] != 'C' ) || + ( szLine[1] != 'h' && szLine[1] != 'H' ) ) { + DBG_871X("Meet wrong channel => power limt pair '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]); + continue; + } + i = 2;// move to the location behind 'h' + + // load the channel number + cnt = 0; + while ( szLine[i] >= '0' && szLine[i] <= '9' ) { + channel[cnt] = szLine[i]; + ++cnt; + ++i; + } + //DBG_871X("chnl %s!\n", channel); + + for ( forCnt = 0; forCnt < colNum; ++forCnt ) + { + // skip the space between channel number and the power limit value + while ( szLine[i] == ' ' || szLine[i] == '\t' ) + ++i; + + // load the power limit value + cnt = 0; + fraction = 0; + _rtw_memset( ( PVOID ) powerLimit, 0, 10 ); + while ( ( szLine[i] >= '0' && szLine[i] <= '9' ) || szLine[i] == '.' ) + { + if ( szLine[i] == '.' ){ + if ( ( szLine[i+1] >= '0' && szLine[i+1] <= '9' ) ) { + fraction = szLine[i+1]; + i += 2; + } + else { + DBG_871X("Wrong fraction in TXPWR_LMT.txt\n"); + return _FAIL; + } + + break; + } + + powerLimit[cnt] = szLine[i]; + ++cnt; + ++i; + } + + if ( powerLimit[0] == '\0' ) { + powerLimit[0] = '6'; + powerLimit[1] = '3'; + i += 2; + } + else { + if ( !GetU1ByteIntegerFromStringInDecimal( powerLimit, &limitValue ) ) + return _FAIL; + + limitValue *= 2; + cnt = 0; + if ( fraction == '5' ) + ++limitValue; + + // the value is greater or equal to 100 + if ( limitValue >= 100 ) { + powerLimit[cnt++] = limitValue/100 + '0'; + limitValue %= 100; + + if ( limitValue >= 10 ) { + powerLimit[cnt++] = limitValue/10 + '0'; + limitValue %= 10; + } + else { + powerLimit[cnt++] = '0'; + } + + powerLimit[cnt++] = limitValue + '0'; + } + // the value is greater or equal to 10 + else if ( limitValue >= 10 ) { + powerLimit[cnt++] = limitValue/10 + '0'; + limitValue %= 10; + powerLimit[cnt++] = limitValue + '0'; + } + // the value is less than 10 + else + powerLimit[cnt++] = limitValue + '0'; + + powerLimit[cnt] = '\0'; + } + + //DBG_871X("ch%s => %s\n", channel, powerLimit); + + // store the power limit value + PHY_SetTxPowerLimit(pDM_Odm, (u8 *)regulation[forCnt], (u8 *)band, + (u8 *)bandwidth, (u8 *)rateSection, (u8 *)rfPath, (u8 *)channel, (u8 *)powerLimit ); + + } + } + else + { + DBG_871X("Abnormal loading stage in phy_ParsePowerLimitTableFile()!\n"); + rtStatus = _FAIL; + break; + } + } + + DBG_871X("<===phy_ParsePowerLimitTableFile()\n"); + return rtStatus; +} + +int +PHY_ConfigRFWithPowerLimitTableParaFile( + IN PADAPTER Adapter, + IN const char *pFileName +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rlen = 0, rtStatus = _FAIL; + + 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); + + if (pHalData->rf_tx_pwr_lmt == NULL) { + rtw_merge_string(file_path, PATH_LENGTH_MAX, rtw_phy_file_path, pFileName); + + if (rtw_is_file_readable(file_path) == _TRUE) + { + rlen = rtw_retrieve_from_file(file_path, pHalData->para_file_buf, MAX_PARA_FILE_BUF_LEN); + if (rlen > 0) + { + rtStatus = _SUCCESS; + pHalData->rf_tx_pwr_lmt = rtw_zvmalloc(rlen); + if(pHalData->rf_tx_pwr_lmt) { + _rtw_memcpy(pHalData->rf_tx_pwr_lmt, pHalData->para_file_buf, rlen); + pHalData->rf_tx_pwr_lmt_len = rlen; + } + else { + DBG_871X("%s rf_tx_pwr_lmt alloc fail !\n",__FUNCTION__); + } + } + } + } else { + if ((pHalData->rf_tx_pwr_lmt_len != 0) && (pHalData->rf_tx_pwr_lmt != NULL)) { + _rtw_memcpy(pHalData->para_file_buf, pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len); + rtStatus = _SUCCESS; + } + else { + DBG_871X("%s(): Critical Error !!!\n",__FUNCTION__); + } + } + + if(rtStatus == _SUCCESS) + { + //DBG_871X("%s(): read %s ok\n", __FUNCTION__, pFileName); + rtStatus = phy_ParsePowerLimitTableFile( Adapter, pHalData->para_file_buf ); + } + else + { + DBG_871X("%s(): No File %s, Load from HWImg Array!\n", __FUNCTION__, pFileName); + } + + return rtStatus; +} + +void phy_free_filebuf_mask(_adapter *padapter, u8 mask) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (pHalData->mac_reg && (mask & LOAD_MAC_PARA_FILE)) { + rtw_vmfree(pHalData->mac_reg, pHalData->mac_reg_len); + pHalData->mac_reg = NULL; + } + if (mask & LOAD_BB_PARA_FILE) { + if (pHalData->bb_phy_reg) { + rtw_vmfree(pHalData->bb_phy_reg, pHalData->bb_phy_reg_len); + pHalData->bb_phy_reg = NULL; + } + if (pHalData->bb_agc_tab) { + rtw_vmfree(pHalData->bb_agc_tab, pHalData->bb_agc_tab_len); + pHalData->bb_agc_tab = NULL; + } + } + if (pHalData->bb_phy_reg_pg && (mask & LOAD_BB_PG_PARA_FILE)) { + rtw_vmfree(pHalData->bb_phy_reg_pg, pHalData->bb_phy_reg_pg_len); + pHalData->bb_phy_reg_pg = NULL; + } + if (pHalData->bb_phy_reg_mp && (mask & LOAD_BB_MP_PARA_FILE)) { + rtw_vmfree(pHalData->bb_phy_reg_mp, pHalData->bb_phy_reg_mp_len); + pHalData->bb_phy_reg_mp = NULL; + } + if (mask & LOAD_RF_PARA_FILE) { + if (pHalData->rf_radio_a) { + rtw_vmfree(pHalData->rf_radio_a, pHalData->rf_radio_a_len); + pHalData->rf_radio_a = NULL; + } + if (pHalData->rf_radio_b) { + rtw_vmfree(pHalData->rf_radio_b, pHalData->rf_radio_b_len); + pHalData->rf_radio_b = NULL; + } + } + if (pHalData->rf_tx_pwr_track && (mask & LOAD_RF_TXPWR_TRACK_PARA_FILE)) { + rtw_vmfree(pHalData->rf_tx_pwr_track, pHalData->rf_tx_pwr_track_len); + pHalData->rf_tx_pwr_track = NULL; + } + if (pHalData->rf_tx_pwr_lmt && (mask & LOAD_RF_TXPWR_LMT_PARA_FILE)) { + rtw_vmfree(pHalData->rf_tx_pwr_lmt, pHalData->rf_tx_pwr_lmt_len); + pHalData->rf_tx_pwr_lmt = NULL; + } +} + +inline void phy_free_filebuf(_adapter *padapter) +{ + phy_free_filebuf_mask(padapter, 0xFF); +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_dm.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_dm.c new file mode 100644 index 00000000..4547dbe6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_dm.c @@ -0,0 +1,193 @@ +/****************************************************************************** + * + * 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); + 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 (rtw_get_intf_type(adapter) == RTW_GSPI) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO); + else + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_INTERFACE, rtw_get_intf_type(adapter)); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID)); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, adapter->registrypriv.wifi_spec); + + + if (pHalData->rf_type == RF_1T1R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); + else if (pHalData->rf_type == RF_1T2R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); + else if (pHalData->rf_type == RF_2T2R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); + else if (pHalData->rf_type == RF_2T2R_GREEN) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN); + else if (pHalData->rf_type == RF_2T3R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T3R); + else if (pHalData->rf_type == RF_2T4R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T4R); + else if (pHalData->rf_type == RF_3T3R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T3R); + else if (pHalData->rf_type == RF_3T4R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_3T4R); + else if (pHalData->rf_type == RF_4T4R) + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_4T4R); + else + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_XTXR); + + +{ + //1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= + u8 odm_board_type = ODM_BOARD_DEFAULT; + + 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; + + 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)); + /*Add by Yuchen for phydm beamforming*/ + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_TP, &(dvobj->traffic_stat.cur_tx_tp)); + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_TP, &(dvobj->traffic_stat.cur_rx_tp)); +#ifdef CONFIG_USB_HCI + ODM_CmnInfoHook(pDM_Odm, ODM_CMNINFO_HUBUSBMODE, &(dvobj->usb_speed)); +#endif + for(i=0; i +#include + +u8 rtw_hal_sdio_max_txoqt_free_space(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if(pHalData->SdioTxOQTMaxFreeSpace < 8 ) + pHalData->SdioTxOQTMaxFreeSpace = 8; + + return pHalData->SdioTxOQTMaxFreeSpace; +} + +u8 rtw_hal_sdio_query_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if ((pHalData->SdioTxFIFOFreePage[PageIdx]+pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]) >= (RequiredPageNum)) + return _TRUE; + else + return _FALSE; +} + +void rtw_hal_sdio_update_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 DedicatedPgNum = 0; + u8 RequiredPublicFreePgNum = 0; + //_irqL irql; + + //_enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); + + DedicatedPgNum = pHalData->SdioTxFIFOFreePage[PageIdx]; + if (RequiredPageNum <= DedicatedPgNum) { + pHalData->SdioTxFIFOFreePage[PageIdx] -= RequiredPageNum; + } else { + pHalData->SdioTxFIFOFreePage[PageIdx] = 0; + RequiredPublicFreePgNum = RequiredPageNum - DedicatedPgNum; + pHalData->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= RequiredPublicFreePgNum; + } + + //_exit_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); +} + +void rtw_hal_set_sdio_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u32 page_size; + u32 lenHQ, lenNQ, lenLQ; + + rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE,&page_size); + + lenHQ = ((numHQ + numPubQ) >> 1) * page_size; + lenNQ = ((numNQ + numPubQ) >> 1) * page_size; + lenLQ = ((numLQ + numPubQ) >> 1) * page_size; + + pHalData->sdio_tx_max_len[HI_QUEUE_IDX] = (lenHQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenHQ; + pHalData->sdio_tx_max_len[MID_QUEUE_IDX] = (lenNQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenNQ; + pHalData->sdio_tx_max_len[LOW_QUEUE_IDX] = (lenLQ > MAX_XMITBUF_SZ)? MAX_XMITBUF_SZ:lenLQ; +} + +u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u32 deviceId, max_len; + + + deviceId = ffaddr2deviceId(pdvobjpriv, queue_idx); + switch (deviceId) { + case WLAN_TX_HIQ_DEVICE_ID: + max_len = pHalData->sdio_tx_max_len[HI_QUEUE_IDX]; + break; + + case WLAN_TX_MIQ_DEVICE_ID: + max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX]; + break; + + case WLAN_TX_LOQ_DEVICE_ID: + max_len = pHalData->sdio_tx_max_len[LOW_QUEUE_IDX]; + break; + + default: + max_len = pHalData->sdio_tx_max_len[MID_QUEUE_IDX]; + break; + } + + return max_len; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_intf.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_intf.c new file mode 100644 index 00000000..b9869880 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_intf.c @@ -0,0 +1,1112 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ + +#define _HAL_INTF_C_ + +#include +#include + +void rtw_hal_chip_configure(_adapter *padapter) +{ + padapter->HalFunc.intf_chip_configure(padapter); +} + +void rtw_hal_read_chip_info(_adapter *padapter) +{ + u8 hci_type = rtw_get_intf_type(padapter); + u32 start = rtw_get_current_time(); + + /* before access eFuse, make sure card enable has been called */ + if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI) + && !rtw_is_hw_init_completed(padapter)) + rtw_hal_power_on(padapter); + + padapter->HalFunc.read_adapter_info(padapter); + + if ((hci_type == RTW_SDIO || hci_type == RTW_GSPI) + && !rtw_is_hw_init_completed(padapter)) + rtw_hal_power_off(padapter); + + DBG_871X("%s in %d ms\n", __func__, rtw_get_passing_time_ms(start)); +} + +void rtw_hal_read_chip_version(_adapter *padapter) +{ + padapter->HalFunc.read_chip_version(padapter); +} + +void rtw_hal_def_value_init(_adapter *padapter) +{ + if (is_primary_adapter(padapter)) { + padapter->HalFunc.init_default_value(padapter); + + rtw_init_hal_com_default_value(padapter); + + { + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); + + /* hal_spec is ready here */ + dvobj->macid_ctl.num = rtw_min(hal_spec->macid_num, MACID_NUM_SW_LIMIT); + + dvobj->cam_ctl.sec_cap = hal_spec->sec_cap; + dvobj->cam_ctl.num = rtw_min(hal_spec->sec_cam_ent_num, SEC_CAM_ENT_NUM_SW_LIMIT); + } + } +} + +u8 rtw_hal_data_init(_adapter *padapter) +{ + if (is_primary_adapter(padapter)) { + padapter->hal_data_sz = sizeof(HAL_DATA_TYPE); + padapter->HalData = rtw_zvmalloc(padapter->hal_data_sz); + if(padapter->HalData == NULL){ + 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->HalData) + { + #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + phy_free_filebuf(padapter); + #endif + rtw_vmfree(padapter->HalData, padapter->hal_data_sz); + padapter->HalData = NULL; + padapter->hal_data_sz = 0; + } + } +} + +void rtw_hal_free_data(_adapter *padapter) +{ + //free HAL Data + rtw_hal_data_deinit(padapter); +} +void rtw_hal_dm_init(_adapter *padapter) +{ + if (is_primary_adapter(padapter)) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + padapter->HalFunc.dm_init(padapter); + + _rtw_spinlock_init(&pHalData->IQKSpinLock); + + phy_load_tx_power_ext_info(padapter, 1, 1); + } +} +void rtw_hal_dm_deinit(_adapter *padapter) +{ + if (is_primary_adapter(padapter)) { + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + padapter->HalFunc.dm_deinit(padapter); + + _rtw_spinlock_free(&pHalData->IQKSpinLock); + } +} +void rtw_hal_sw_led_init(_adapter *padapter) +{ + if(padapter->HalFunc.InitSwLeds) + padapter->HalFunc.InitSwLeds(padapter); +} + +void rtw_hal_sw_led_deinit(_adapter *padapter) +{ + if(padapter->HalFunc.DeInitSwLeds) + padapter->HalFunc.DeInitSwLeds(padapter); +} + +u32 rtw_hal_power_on(_adapter *padapter) +{ + return padapter->HalFunc.hal_power_on(padapter); +} +void rtw_hal_power_off(_adapter *padapter) +{ + struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl; + + _rtw_memset(macid_ctl->h2c_msr, 0, MACID_NUM_SW_LIMIT); + + padapter->HalFunc.hal_power_off(padapter); +} + + +void rtw_hal_init_opmode(_adapter *padapter) +{ + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType = Ndis802_11InfrastructureMax; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + sint fw_state; + + fw_state = get_fwstate(pmlmepriv); + + if (fw_state & WIFI_ADHOC_STATE) + networkType = Ndis802_11IBSS; + else if (fw_state & WIFI_STATION_STATE) + networkType = Ndis802_11Infrastructure; + else if (fw_state & WIFI_AP_STATE) + networkType = Ndis802_11APMode; + else + return; + + rtw_setopmode_cmd(padapter, networkType, _FALSE); +} + +uint rtw_hal_init(_adapter *padapter) +{ + uint status = _SUCCESS; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + int i; + + status = padapter->HalFunc.hal_init(padapter); + + if (status == _SUCCESS) { + pHalData->hw_init_completed = _TRUE; + + if (padapter->registrypriv.notch_filter == 1) + rtw_hal_notch_filter(padapter, 1); + + for (i = 0; iiface_nums; i++) + rtw_sec_restore_wep_key(dvobj->padapters[i]); + + 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); +#endif //CONFIG_RF_GAIN_OFFSET + + } else { + pHalData->hw_init_completed = _FALSE; + DBG_871X("rtw_hal_init: hal__init fail\n"); + } + + RT_TRACE(_module_hal_init_c_,_drv_err_,("-rtl871x_hal_init:status=0x%x\n",status)); + + return status; + +} + +uint rtw_hal_deinit(_adapter *padapter) +{ + uint status = _SUCCESS; + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + int i; +_func_enter_; + + status = padapter->HalFunc.hal_deinit(padapter); + + if(status == _SUCCESS){ + rtw_led_control(padapter, LED_CTL_POWER_OFF); + pHalData->hw_init_completed = _FALSE; + } + else + { + DBG_871X("\n rtw_hal_deinit: hal_init fail\n"); + } + +_func_exit_; + + return status; +} + +void rtw_hal_set_hwreg(_adapter *padapter, u8 variable, u8 *val) +{ + padapter->HalFunc.SetHwRegHandler(padapter, variable, val); +} + +void rtw_hal_get_hwreg(_adapter *padapter, u8 variable, u8 *val) +{ + padapter->HalFunc.GetHwRegHandler(padapter, variable, val); +} + +#ifdef CONFIG_C2H_PACKET_EN +void rtw_hal_set_hwreg_with_buf(_adapter *padapter, u8 variable, u8 *pbuf, int len) +{ + if (padapter->HalFunc.SetHwRegHandlerWithBuf) + padapter->HalFunc.SetHwRegHandlerWithBuf(padapter, variable, pbuf, len); +} +#endif + +u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue) +{ + return padapter->HalFunc.SetHalDefVarHandler(padapter,eVariable,pValue); +} +u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue) +{ + return padapter->HalFunc.GetHalDefVarHandler(padapter,eVariable,pValue); +} + +void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet) +{ + padapter->HalFunc.SetHalODMVarHandler(padapter,eVariable,pValue1,bSet); +} +void rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,PVOID pValue2) +{ + padapter->HalFunc.GetHalODMVarHandler(padapter,eVariable,pValue1,pValue2); +} + +/* FOR SDIO & PCIE */ +void rtw_hal_enable_interrupt(_adapter *padapter) +{ +#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) + padapter->HalFunc.enable_interrupt(padapter); +#endif //#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) +} + +/* FOR SDIO & PCIE */ +void rtw_hal_disable_interrupt(_adapter *padapter) +{ +#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) + padapter->HalFunc.disable_interrupt(padapter); +#endif //#if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) +} + + +u8 rtw_hal_check_ips_status(_adapter *padapter) +{ + u8 val = _FALSE; + if (padapter->HalFunc.check_ips_status) + val = padapter->HalFunc.check_ips_status(padapter); + else + DBG_871X("%s: HalFunc.check_ips_status is NULL!\n", __FUNCTION__); + + return val; +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtw_hal_clear_interrupt(_adapter *padapter) +{ +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + padapter->HalFunc.clear_interrupt(padapter); +#endif +} +void rtw_hal_set_wowlan_fw(_adapter *padapter, u8 sleep) +{ + padapter->HalFunc.hal_set_wowlan_fw(padapter, sleep); +} + +#endif + +#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI) +u32 rtw_hal_inirp_init(_adapter *padapter) +{ + if (is_primary_adapter(padapter)) + return padapter->HalFunc.inirp_init(padapter); + return _SUCCESS; +} +u32 rtw_hal_inirp_deinit(_adapter *padapter) +{ + + if (is_primary_adapter(padapter)) + return padapter->HalFunc.inirp_deinit(padapter); + + return _SUCCESS; +} +#endif //#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI) + +#if defined(CONFIG_PCI_HCI) +void rtw_hal_irp_reset(_adapter *padapter) +{ + padapter->HalFunc.irp_reset(padapter); +} +#endif //#if defined(CONFIG_PCI_HCI) + +/* for USB Auto-suspend */ +u8 rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val) +{ + if(padapter->HalFunc.interface_ps_func) + return padapter->HalFunc.interface_ps_func(padapter,efunc_id,val); + return _FAIL; +} + +s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); +} + +s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + return padapter->HalFunc.hal_xmit(padapter, pxmitframe); +} + +/* + * [IMPORTANT] This function would be run in interrupt context. + */ +s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe) +{ + s32 ret = _FAIL; + u8 *pframe, subtype; + struct rtw_ieee80211_hdr *pwlanhdr; + struct sta_info *psta; + struct sta_priv *pstapriv = &padapter->stapriv; + + update_mgntframe_attrib_addr(padapter, pmgntframe); + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + subtype = GetFrameSubType(pframe); /* bit(7)~bit(2) */ + + //pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //_rtw_memcpy(pmgntframe->attrib.ra, pwlanhdr->addr1, ETH_ALEN); + +#ifdef CONFIG_IEEE80211W + if (padapter->securitypriv.binstallBIPkey == _TRUE && (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || + subtype == WIFI_ACTION)) + { + if (IS_MCAST(pmgntframe->attrib.ra) && pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) { + pmgntframe->attrib.encrypt = _BIP_; + /* pmgntframe->attrib.bswenc = _TRUE; */ + } else if (pmgntframe->attrib.key_type != IEEE80211W_NO_KEY) { + psta = rtw_get_stainfo(pstapriv, pmgntframe->attrib.ra); + if (psta && psta->bpairwise_key_installed == _TRUE) { + pmgntframe->attrib.encrypt = _AES_; + pmgntframe->attrib.bswenc = _TRUE; + } else { + DBG_871X("%s, %d, bpairwise_key_installed is FALSE\n", __func__, __LINE__); + goto no_mgmt_coalesce; + } + } + DBG_871X("encrypt=%d, bswenc=%d\n", pmgntframe->attrib.encrypt, pmgntframe->attrib.bswenc); + rtw_mgmt_xmitframe_coalesce(padapter, pmgntframe->pkt, pmgntframe); + } +#endif //CONFIG_IEEE80211W +no_mgmt_coalesce: + ret = padapter->HalFunc.mgnt_xmit(padapter, pmgntframe); + return ret; +} + +s32 rtw_hal_init_xmit_priv(_adapter *padapter) +{ + return padapter->HalFunc.init_xmit_priv(padapter); +} +void rtw_hal_free_xmit_priv(_adapter *padapter) +{ + padapter->HalFunc.free_xmit_priv(padapter); +} + +s32 rtw_hal_init_recv_priv(_adapter *padapter) +{ + return padapter->HalFunc.init_recv_priv(padapter); +} +void rtw_hal_free_recv_priv(_adapter *padapter) +{ + padapter->HalFunc.free_recv_priv(padapter); +} + +void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level) +{ + _adapter *padapter; + struct mlme_priv *pmlmepriv; + + if(!psta) + return; + + padapter = psta->padapter; + + pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + add_RATid(padapter, psta, rssi_level); + } + else + { + padapter->HalFunc.UpdateRAMaskHandler(padapter, psta->mac_id, rssi_level); + } +} + +void rtw_hal_add_ra_tid(_adapter *padapter, u64 bitmap, u8 *arg, u8 rssi_level) +{ + padapter->HalFunc.Add_RateATid(padapter, bitmap, arg, rssi_level); +} + +/* Start specifical interface thread */ +void rtw_hal_start_thread(_adapter *padapter) +{ +#if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) +#ifndef CONFIG_SDIO_TX_TASKLET + padapter->HalFunc.run_thread(padapter); +#endif +#endif +} +/* Start specifical interface thread */ +void rtw_hal_stop_thread(_adapter *padapter) +{ +#if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) +#ifndef CONFIG_SDIO_TX_TASKLET + + padapter->HalFunc.cancel_thread(padapter); + +#endif +#endif +} + +u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask) +{ + u32 data = 0; + if(padapter->HalFunc.read_bbreg) + data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask); + return data; +} +void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data) +{ + if(padapter->HalFunc.write_bbreg) + padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data); +} + +u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask) +{ + u32 data = 0; + + if (padapter->HalFunc.read_rfreg) { + data = padapter->HalFunc.read_rfreg(padapter, eRFPath, RegAddr, BitMask); + + if (match_rf_read_sniff_ranges(eRFPath, RegAddr, BitMask)) { + DBG_871X("DBG_IO rtw_hal_read_rfreg(%u, 0x%04x, 0x%08x) read:0x%08x(0x%08x)\n" + , eRFPath, RegAddr, BitMask, (data << PHY_CalculateBitShift(BitMask)), data); + } + } + + return data; +} + +void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data) +{ + if (padapter->HalFunc.write_rfreg) { + + if (match_rf_write_sniff_ranges(eRFPath, RegAddr, BitMask)) { + DBG_871X("DBG_IO rtw_hal_write_rfreg(%u, 0x%04x, 0x%08x) write:0x%08x(0x%08x)\n" + , eRFPath, RegAddr, BitMask, (Data << PHY_CalculateBitShift(BitMask)), Data); + } + + padapter->HalFunc.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data); + +#ifdef CONFIG_PCI_HCI + if (!IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(padapter)) /*For N-Series IC, suggest by Jenyu*/ + rtw_udelay_os(2); +#endif + } +} + +#if defined(CONFIG_PCI_HCI) +s32 rtw_hal_interrupt_handler(_adapter *padapter) +{ + s32 ret = _FAIL; + ret = padapter->HalFunc.interrupt_handler(padapter); + return ret; +} +#endif +#if defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT) +void rtw_hal_interrupt_handler(_adapter *padapter, u16 pkt_len, u8 *pbuf) +{ + padapter->HalFunc.interrupt_handler(padapter, pkt_len, pbuf); +} +#endif + +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); + + 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); + + 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); + + 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) +{ + if(padapter->HalFunc.set_tx_power_level_handler) + padapter->HalFunc.set_tx_power_level_handler(padapter, channel); +} + +void rtw_hal_get_tx_power_level(_adapter *padapter, s32 *powerlevel) +{ + if(padapter->HalFunc.get_tx_power_level_handler) + padapter->HalFunc.get_tx_power_level_handler(padapter, powerlevel); +} + +void rtw_hal_dm_watchdog(_adapter *padapter) +{ + if (!is_primary_adapter(padapter)) + return; + + padapter->HalFunc.hal_dm_watchdog(padapter); + +} + +#ifdef CONFIG_LPS_LCLK_WD_TIMER +void rtw_hal_dm_watchdog_in_lps(_adapter *padapter) +{ +#if defined(CONFIG_CONCURRENT_MODE) + if (padapter->iface_type != IFACE_PORT0) + return; +#endif + + if (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode ==_TRUE ) { + padapter->HalFunc.hal_dm_watchdog_in_lps(padapter);//this fuction caller is in interrupt context + } +} +#endif + +void rtw_hal_bcn_related_reg_setting(_adapter *padapter) +{ + padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter); +} + + +#ifdef CONFIG_ANTENNA_DIVERSITY +u8 rtw_hal_antdiv_before_linked(_adapter *padapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + int i; + + if (!padapter->HalFunc.AntDivBeforeLinkHandler) + return _FALSE; + + for (i = 0; i < dvobj->iface_nums; i++) { + if (rtw_linked_check(dvobj->padapters[i])) + return _FALSE; + } + + return padapter->HalFunc.AntDivBeforeLinkHandler(padapter); +} +void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src) +{ + if(padapter->HalFunc.AntDivCompareHandler) + padapter->HalFunc.AntDivCompareHandler(padapter, dst, src); +} +#endif + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt) +{ + if(padapter->HalFunc.hostap_mgnt_xmit_entry) + return padapter->HalFunc.hostap_mgnt_xmit_entry(padapter, pkt); + return _FAIL; +} +#endif //CONFIG_HOSTAPD_MLME + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtw_hal_sreset_init(_adapter *padapter) +{ + padapter->HalFunc.sreset_init_value(padapter); +} +void rtw_hal_sreset_reset(_adapter *padapter) +{ + padapter = GET_PRIMARY_ADAPTER(padapter); + padapter->HalFunc.silentreset(padapter); +} + +void rtw_hal_sreset_reset_value(_adapter *padapter) +{ + padapter->HalFunc.sreset_reset_value(padapter); +} + +void rtw_hal_sreset_xmit_status_check(_adapter *padapter) +{ + if (!is_primary_adapter(padapter)) + return; + + padapter->HalFunc.sreset_xmit_status_check(padapter); +} +void rtw_hal_sreset_linked_status_check(_adapter *padapter) +{ + if (!is_primary_adapter(padapter)) + return; + padapter->HalFunc.sreset_linked_status_check(padapter); +} +u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter) +{ + return padapter->HalFunc.sreset_get_wifi_status(padapter); +} + +bool rtw_hal_sreset_inprogress(_adapter *padapter) +{ + padapter = GET_PRIMARY_ADAPTER(padapter); + return padapter->HalFunc.sreset_inprogress(padapter); +} +#endif //DBG_CONFIG_ERROR_DETECT + +#ifdef CONFIG_IOL +int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) +{ + if(adapter->HalFunc.IOL_exec_cmds_sync) + return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms,bndy_cnt); + return _FAIL; +} +#endif + +#ifdef CONFIG_XMIT_THREAD_MODE +s32 rtw_hal_xmit_thread_handler(_adapter *padapter) +{ + return padapter->HalFunc.xmit_thread_handler(padapter); +} +#endif + +void rtw_hal_notch_filter(_adapter *adapter, bool enable) +{ + if(adapter->HalFunc.hal_notch_filter) + adapter->HalFunc.hal_notch_filter(adapter,enable); +} + +bool rtw_hal_c2h_valid(_adapter *adapter, u8 *buf) +{ + HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter); + HAL_VERSION *hal_ver = &HalData->VersionID; + bool ret = _FAIL; + + if (IS_8188E(*hal_ver)) { + ret = c2h_evt_valid((struct c2h_evt_hdr *)buf); + } else if(IS_8192E(*hal_ver) || IS_8812_SERIES(*hal_ver) || IS_8821_SERIES(*hal_ver) || IS_8723B_SERIES(*hal_ver)) { + ret = c2h_evt_valid((struct c2h_evt_hdr_88xx*)buf); + } else { + rtw_warn_on(1); + } + + return ret; +} + +s32 rtw_hal_c2h_evt_read(_adapter *adapter, u8 *buf) +{ + HAL_DATA_TYPE *HalData = GET_HAL_DATA(adapter); + HAL_VERSION *hal_ver = &HalData->VersionID; + s32 ret = _FAIL; + + if (IS_8188E(*hal_ver)) { + ret = c2h_evt_read(adapter, buf); + } else if(IS_8192E(*hal_ver) || IS_8812_SERIES(*hal_ver) || IS_8821_SERIES(*hal_ver) || IS_8723B_SERIES(*hal_ver)) { + ret = c2h_evt_read_88xx(adapter, buf); + } else { + rtw_warn_on(1); + } + + return ret; +} + +s32 rtw_hal_c2h_handler(_adapter *adapter, u8 *c2h_evt) +{ + s32 ret = _FAIL; + if (adapter->HalFunc.c2h_handler) + ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); + return ret; +} + +c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *adapter) +{ + return adapter->HalFunc.c2h_id_filter_ccx; +} + +s32 rtw_hal_is_disable_sw_channel_plan(PADAPTER padapter) +{ + return GET_HAL_DATA(padapter)->bDisableSWChannelPlan; +} + +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; + + 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, 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; + + 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; +} + +s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) +{ + _adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter); + + if (pri_adapter->bFWReady == _TRUE) + return padapter->HalFunc.fill_h2c_cmd(padapter, ElementID, CmdLen, pCmdBuffer); + else if (padapter->registrypriv.mp_mode == 0) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" FW doesn't exit when no MP mode, by pass H2C id:0x%02x\n" + , FUNC_ADPT_ARG(padapter), ElementID); + return _FAIL; +} + +void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame) +{ + padapter->HalFunc.fill_fake_txdesc(padapter, pDesc, BufferLen,IsPsPoll, IsBTQosNull, bDataFrame); + +} +u8 rtw_hal_get_txbuff_rsvd_page_num(_adapter *adapter, bool wowlan) +{ + return adapter->HalFunc.hal_get_tx_buff_rsvd_page_num(adapter, wowlan); +} + +#ifdef CONFIG_GPIO_API +void rtw_hal_update_hisr_hsisr_ind(_adapter *padapter, u32 flag) +{ + if (padapter->HalFunc.update_hisr_hsisr_ind) + padapter->HalFunc.update_hisr_hsisr_ind(padapter, flag); +} +#endif + +void rtw_hal_fw_correct_bcn(_adapter *padapter) +{ + if (padapter->HalFunc.fw_correct_bcn) + padapter->HalFunc.fw_correct_bcn(padapter); +} + +#define rtw_hal_error_msg(ops_fun) \ + DBG_871X_LEVEL(_drv_always_, "### %s - Error : Please hook HalFunc.%s ###\n",__FUNCTION__,ops_fun) + +u8 rtw_hal_ops_check(_adapter *padapter) +{ + u8 ret = _SUCCESS; +#if 1 + /*** initialize section ***/ + if (NULL == padapter->HalFunc.read_chip_version) { + rtw_hal_error_msg("read_chip_version"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.init_default_value) { + rtw_hal_error_msg("init_default_value"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.intf_chip_configure) { + rtw_hal_error_msg("intf_chip_configure"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.read_adapter_info) { + rtw_hal_error_msg("read_adapter_info"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.hal_power_on) { + rtw_hal_error_msg("hal_power_on"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.hal_power_off) { + rtw_hal_error_msg("hal_power_off"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.hal_init) { + rtw_hal_error_msg("hal_init"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.hal_deinit) { + rtw_hal_error_msg("hal_deinit"); + ret = _FAIL; + } + + /*** xmit section ***/ + if (NULL == padapter->HalFunc.init_xmit_priv) { + rtw_hal_error_msg("init_xmit_priv"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.free_xmit_priv) { + rtw_hal_error_msg("free_xmit_priv"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.hal_xmit) { + rtw_hal_error_msg("hal_xmit"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.mgnt_xmit) { + rtw_hal_error_msg("mgnt_xmit"); + ret = _FAIL; + } + #ifdef CONFIG_XMIT_THREAD_MODE + if (NULL == padapter->HalFunc.xmit_thread_handler) { + rtw_hal_error_msg("xmit_thread_handler"); + ret = _FAIL; + } + #endif + if (NULL == padapter->HalFunc.hal_xmitframe_enqueue) { + rtw_hal_error_msg("hal_xmitframe_enqueue"); + ret = _FAIL; + } + #if defined(CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) + #ifndef CONFIG_SDIO_TX_TASKLET + if (NULL == padapter->HalFunc.run_thread) { + rtw_hal_error_msg("run_thread"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.cancel_thread) { + rtw_hal_error_msg("cancel_thread"); + ret = _FAIL; + } + #endif + #endif + + /*** recv section ***/ + if (NULL == padapter->HalFunc.init_recv_priv) { + rtw_hal_error_msg("init_recv_priv"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.free_recv_priv) { + rtw_hal_error_msg("free_recv_priv"); + ret = _FAIL; + } + #if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI) + if (NULL == padapter->HalFunc.inirp_init) { + rtw_hal_error_msg("inirp_init"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.inirp_deinit) { + rtw_hal_error_msg("inirp_deinit"); + ret = _FAIL; + } + #endif //#if defined(CONFIG_USB_HCI) || defined (CONFIG_PCI_HCI) + + + /*** interrupt hdl section ***/ + #if defined(CONFIG_PCI_HCI) + if (NULL == padapter->HalFunc.irp_reset) { + rtw_hal_error_msg("irp_reset"); + ret = _FAIL; + } + #endif/*#if defined(CONFIG_PCI_HCI)*/ + #if (defined(CONFIG_PCI_HCI)) || (defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT)) + if (NULL == padapter->HalFunc.interrupt_handler) { + rtw_hal_error_msg("interrupt_handler"); + ret = _FAIL; + } + #endif /*#if (defined(CONFIG_PCI_HCI)) || (defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT))*/ + + #if defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) + if (NULL == padapter->HalFunc.enable_interrupt) { + rtw_hal_error_msg("enable_interrupt"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.disable_interrupt) { + rtw_hal_error_msg("disable_interrupt"); + ret = _FAIL; + } + #endif //defined(CONFIG_PCI_HCI) || defined (CONFIG_SDIO_HCI) || defined (CONFIG_GSPI_HCI) + + + /*** DM section ***/ + if (NULL == padapter->HalFunc.dm_init) { + rtw_hal_error_msg("dm_init"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.dm_deinit) { + rtw_hal_error_msg("dm_deinit"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.hal_dm_watchdog) { + rtw_hal_error_msg("hal_dm_watchdog"); + ret = _FAIL; + } + #ifdef CONFIG_LPS_LCLK_WD_TIMER + if (NULL == padapter->HalFunc.hal_dm_watchdog_in_lps) { + rtw_hal_error_msg("hal_dm_watchdog_in_lps"); + ret = _FAIL; + } + #endif + + /*** xxx section ***/ + if (NULL == padapter->HalFunc.set_bwmode_handler) { + rtw_hal_error_msg("set_bwmode_handler"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.set_channel_handler) { + rtw_hal_error_msg("set_channel_handler"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.set_chnl_bw_handler) { + rtw_hal_error_msg("set_chnl_bw_handler"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.SetHwRegHandler) { + rtw_hal_error_msg("SetHwRegHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.GetHwRegHandler) { + rtw_hal_error_msg("GetHwRegHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.GetHalDefVarHandler) { + rtw_hal_error_msg("GetHalDefVarHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.SetHalDefVarHandler) { + rtw_hal_error_msg("SetHalDefVarHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.GetHalODMVarHandler) { + rtw_hal_error_msg("GetHalODMVarHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.SetHalODMVarHandler) { + rtw_hal_error_msg("SetHalODMVarHandler"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.UpdateRAMaskHandler) { + rtw_hal_error_msg("UpdateRAMaskHandler"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.SetBeaconRelatedRegistersHandler) { + rtw_hal_error_msg("SetBeaconRelatedRegistersHandler"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.Add_RateATid) { + rtw_hal_error_msg("Add_RateATid"); + ret = _FAIL; + } + + if (NULL == padapter->HalFunc.fill_h2c_cmd) { + rtw_hal_error_msg("fill_h2c_cmd"); + ret = _FAIL; + } + #if defined(CONFIG_LPS) || defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + if (NULL == padapter->HalFunc.fill_fake_txdesc) { + rtw_hal_error_msg("fill_fake_txdesc"); + ret = _FAIL; + } + #endif + if (NULL == padapter->HalFunc.hal_get_tx_buff_rsvd_page_num) { + rtw_hal_error_msg("hal_get_tx_buff_rsvd_page_num"); + ret = _FAIL; + } + + #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + if (NULL == padapter->HalFunc.clear_interrupt) { + rtw_hal_error_msg("clear_interrupt"); + ret = _FAIL; + } + #endif + if (NULL == padapter->HalFunc.hal_set_wowlan_fw) { + rtw_hal_error_msg("hal_set_wowlan_fw"); + ret = _FAIL; + } + #endif //CONFIG_WOWLAN + if ((IS_HARDWARE_TYPE_8814A(padapter) + || IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8822BS(padapter)) + && NULL == padapter->HalFunc.fw_correct_bcn) { + rtw_hal_error_msg("fw_correct_bcn"); + ret = _FAIL; + } + + + /*** SReset section ***/ + #ifdef DBG_CONFIG_ERROR_DETECT + if (NULL == padapter->HalFunc.sreset_init_value) { + rtw_hal_error_msg("sreset_init_value"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.sreset_reset_value) { + rtw_hal_error_msg("sreset_reset_value"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.silentreset) { + rtw_hal_error_msg("silentreset"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.sreset_xmit_status_check) { + rtw_hal_error_msg("sreset_xmit_status_check"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.sreset_linked_status_check) { + rtw_hal_error_msg("sreset_linked_status_check"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.sreset_get_wifi_status) { + rtw_hal_error_msg("sreset_get_wifi_status"); + ret = _FAIL; + } + if (NULL == padapter->HalFunc.sreset_inprogress) { + rtw_hal_error_msg("sreset_inprogress"); + ret = _FAIL; + } + #endif //#ifdef DBG_CONFIG_ERROR_DETECT + +#endif + return ret; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_mp.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_mp.c new file mode 100644 index 00000000..fbf9d3ab --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_mp.c @@ -0,0 +1,2141 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HAL_MP_C_ +#ifdef CONFIG_MP_INCLUDED + +#ifdef CONFIG_RTL8188E +#include +#endif +#ifdef CONFIG_RTL8723B +#include +#endif +#ifdef CONFIG_RTL8192E +#include +#endif +#ifdef CONFIG_RTL8814A +#include +#endif +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +#include +#endif +#ifdef CONFIG_RTL8703B +#include +#endif +#ifdef CONFIG_RTL8188F +#include +#endif + + +u8 MgntQuery_NssTxRate(u16 Rate) +{ + u8 NssNum = RF_TX_NUM_NONIMPLEMENT; + + if ((Rate >= MGN_MCS8 && Rate <= MGN_MCS15) || + (Rate >= MGN_VHT2SS_MCS0 && Rate <= MGN_VHT2SS_MCS9)) + NssNum = RF_2TX; + else if ((Rate >= MGN_MCS16 && Rate <= MGN_MCS23) || + (Rate >= MGN_VHT3SS_MCS0 && Rate <= MGN_VHT3SS_MCS9)) + NssNum = RF_3TX; + else if ((Rate >= MGN_MCS24 && Rate <= MGN_MCS31) || + (Rate >= MGN_VHT4SS_MCS0 && Rate <= MGN_VHT4SS_MCS9)) + NssNum = RF_4TX; + else + NssNum = RF_1TX; + + return NssNum; +} + +void hal_mpt_SwitchRfSetting(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u8 ChannelToSw = pMptCtx->MptChannelToSw; + ULONG ulRateIdx = pMptCtx->MptRateIndex; + ULONG ulbandwidth = pMptCtx->MptBandWidth; + + /* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis.*/ + if (IS_HARDWARE_TYPE_8188ES(pAdapter) && (1 <= ChannelToSw && ChannelToSw <= 11) && + (ulRateIdx == MPT_RATE_MCS0 || ulRateIdx == MPT_RATE_1M || ulRateIdx == MPT_RATE_6M)) { + pMptCtx->backup0x52_RF_A = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0); + pMptCtx->backup0x52_RF_B = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0); + + if ((PlatformEFIORead4Byte(pAdapter, 0xF4)&BIT29) == BIT29) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xB); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xB); + } else { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xD); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xD); + } + } else if (IS_HARDWARE_TYPE_8188EE(pAdapter)) { /* <20140903, VincentL> Asked by RF Eason and Edlu*/ + + if (ChannelToSw == 3 && ulbandwidth == MPT_BW_40MHZ) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0xB); /*RF 0x52 = 0x0007E4BD*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0xB); /*RF 0x52 = 0x0007E4BD*/ + } else { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, 0x9); /*RF 0x52 = 0x0007E49D*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, 0x9); /*RF 0x52 = 0x0007E49D*/ + } + + } else if (IS_HARDWARE_TYPE_8188E(pAdapter)) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_A); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_0x52, 0x000F0, pMptCtx->backup0x52_RF_B); + } +} + +s32 hal_mpt_SetPowerTracking(PADAPTER padapter, u8 enable) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + + if (!netif_running(padapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: interface not opened!\n")); + return _FAIL; + } + + if (check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetPowerTracking! Fail: not in MP mode!\n")); + return _FAIL; + } + if (enable) + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE; + else + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE; + + return _SUCCESS; +} + +void hal_mpt_GetPowerTracking(PADAPTER padapter, u8 *enable) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + + *enable = pDM_Odm->RFCalibrateInfo.TxPowerTrackControl; +} + + +void hal_mpt_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14) +{ + u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0; + u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12; + u8 i; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx); + u1Byte u1Channel = pHalData->CurrentChannel; + ULONG ulRateIdx = pMptCtx->MptRateIndex; + u1Byte DataRate = 0xFF; + + DataRate = MptToMgntRate(ulRateIdx); + + if (u1Channel == 14 && IS_CCK_RATE(DataRate)) + pHalData->bCCKinCH14 = TRUE; + else + pHalData->bCCKinCH14 = FALSE; + + if (IS_HARDWARE_TYPE_8703B(Adapter)) { + if ((u1Channel == 14) && IS_CCK_RATE(DataRate)) { + /* Channel 14 in CCK, need to set 0xA26~0xA29 to 0 for 8703B */ + PHY_SetBBReg(Adapter, rCCK0_TxFilter2, bMaskHWord, 0); + PHY_SetBBReg(Adapter, rCCK0_DebugPort, bMaskLWord, 0); + + RT_TRACE(_module_mp_, DBG_LOUD, ("MPT_CCKTxPowerAdjust 8703B CCK in Channel %u\n", u1Channel)); + } else { + /* Normal setting for 8703B, just recover to the default setting. */ + /* This hardcore values reference from the parameter which BB team gave. */ + for (i = 0 ; i < 2 ; ++i) + PHY_SetBBReg(Adapter, pHalData->RegForRecover[i].offset, bMaskDWord, pHalData->RegForRecover[i].value); + + RT_TRACE(_module_mp_, DBG_LOUD, ("MPT_CCKTxPowerAdjust 8703B in Channel %u restore to default setting\n", u1Channel)); + } + } else if (IS_HARDWARE_TYPE_8188F(Adapter)) { + /* No difference between CCK in CH14 and others, no need to change TX filter */ + } else { + + /* get current cck swing value and check 0xa22 & 0xa23 later to match the table.*/ + CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord); + + if (!pHalData->bCCKinCH14) { + /* Readback the current bb cck swing value and compare with the table to */ + /* get the current swing index */ + for (i = 0; i < CCK_TABLE_SIZE; i++) { + if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) && + (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) { + CCKSwingIndex = i; + RT_TRACE(_module_mp_, DBG_LOUD, ("Ch1~13, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n", + (rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex)); + break; + } + } + + /*Write 0xa22 0xa23*/ + TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1]<<8); + + + /*Write 0xa24 ~ 0xa27*/ + TempVal2 = 0; + TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3]<<8) + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4]<<16) + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5]<<24); + + /*Write 0xa28 0xa29*/ + TempVal3 = 0; + TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] + + (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7]<<8); + } else { + for (i = 0; i < CCK_TABLE_SIZE; i++) { + if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch14[i][0]) && + (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch14[i][1])) { + CCKSwingIndex = i; + RT_TRACE(_module_mp_, DBG_LOUD, ("Ch14, Current reg0x%x = 0x%lx, CCKSwingIndex=0x%x\n", + (rCCK0_TxFilter1+2), CurrCCKSwingVal, CCKSwingIndex)); + break; + } + } + + /*Write 0xa22 0xa23*/ + TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] + + (CCKSwingTable_Ch14[CCKSwingIndex][1]<<8); + + /*Write 0xa24 ~ 0xa27*/ + TempVal2 = 0; + TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] + + (CCKSwingTable_Ch14[CCKSwingIndex][3]<<8) + + (CCKSwingTable_Ch14[CCKSwingIndex][4]<<16) + + (CCKSwingTable_Ch14[CCKSwingIndex][5]<<24); + + /*Write 0xa28 0xa29*/ + TempVal3 = 0; + TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] + + (CCKSwingTable_Ch14[CCKSwingIndex][7]<<8); + } + + write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal); + write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2); + write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3); + + } + +} + +void hal_mpt_SetChannel(PADAPTER pAdapter) +{ + u8 eRFPath; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + struct mp_priv *pmp = &pAdapter->mppriv; + u8 channel = pmp->channel; + u8 bandwidth = pmp->bandwidth; + u8 rate = pmp->rateidx; + + hal_mpt_SwitchRfSetting(pAdapter); + + SelectChannel(pAdapter, channel); + + pHalData->bSwChnl = _TRUE; + pHalData->bSetChnlBW = _TRUE; + rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0); + + hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14); + +} + +/* + * Notice + * Switch bandwitdth may change center frequency(channel) + */ +void hal_mpt_SetBandwidth(PADAPTER pAdapter) +{ + struct mp_priv *pmp = &pAdapter->mppriv; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + u8 channel = pmp->channel; + u8 bandwidth = pmp->bandwidth; + + SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset); + pHalData->bSwChnl = _TRUE; + pHalData->bSetChnlBW = _TRUE; + rtw_hal_set_chnl_bw(pAdapter, channel, bandwidth, 0, 0); + + hal_mpt_SwitchRfSetting(pAdapter); +} + +void mpt_SetTxPower_Old(PADAPTER pAdapter, MPT_TXPWR_DEF Rate, u8 *pTxPower) +{ + RT_TRACE(_module_mp_, DBG_LOUD, ("===>mpt_SetTxPower_Old(): Case = %d\n", Rate)); + switch (Rate) { + case MPT_CCK: + { + u4Byte TxAGC = 0, pwr = 0; + u1Byte rf; + + pwr = pTxPower[ODM_RF_PATH_A]; + if (pwr < 0x3f) { + TxAGC = (pwr<<16)|(pwr<<8)|(pwr); + PHY_SetBBReg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pTxPower[ODM_RF_PATH_A]); + PHY_SetBBReg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC); + } + pwr = pTxPower[ODM_RF_PATH_B]; + if (pwr < 0x3f) { + TxAGC = (pwr<<16)|(pwr<<8)|(pwr); + PHY_SetBBReg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, pTxPower[ODM_RF_PATH_B]); + PHY_SetBBReg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, TxAGC); + } + + } break; + + case MPT_OFDM_AND_HT: + { + u4Byte TxAGC = 0; + u1Byte pwr = 0, rf; + + pwr = pTxPower[0]; + if (pwr < 0x3f) { + TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr); + DBG_871X("HT Tx-rf(A) Power = 0x%x\n", TxAGC); + + PHY_SetBBReg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); + } + TxAGC = 0; + pwr = pTxPower[1]; + if (pwr < 0x3f) { + TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr); + DBG_871X("HT Tx-rf(B) Power = 0x%x\n", TxAGC); + + PHY_SetBBReg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC); + PHY_SetBBReg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC); + } + } break; + + default: + break; + } + DBG_871X("<===mpt_SetTxPower_Old()\n"); +} + + + +void +mpt_SetTxPower( + PADAPTER pAdapter, + MPT_TXPWR_DEF Rate, + pu1Byte pTxPower + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + u1Byte path = 0 , i = 0, MaxRate = MGN_6M; + u1Byte StartPath = ODM_RF_PATH_A, EndPath = ODM_RF_PATH_B; + + if (IS_HARDWARE_TYPE_8814A(pAdapter)) + EndPath = ODM_RF_PATH_D; + + switch (Rate) { + case MPT_CCK: + { + u1Byte rate[] = {MGN_1M, MGN_2M, MGN_5_5M, MGN_11M}; + + for (path = StartPath; path <= EndPath; path++) + for (i = 0; i < sizeof(rate); ++i) + PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]); + } + break; + + case MPT_OFDM: + { + u1Byte rate[] = { + MGN_6M, MGN_9M, MGN_12M, MGN_18M, + MGN_24M, MGN_36M, MGN_48M, MGN_54M, + }; + + for (path = StartPath; path <= EndPath; path++) + for (i = 0; i < sizeof(rate); ++i) + PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]); + } break; + + case MPT_HT: + { + u1Byte rate[] = { + MGN_MCS0, MGN_MCS1, MGN_MCS2, MGN_MCS3, MGN_MCS4, + MGN_MCS5, MGN_MCS6, MGN_MCS7, MGN_MCS8, MGN_MCS9, + MGN_MCS10, MGN_MCS11, MGN_MCS12, MGN_MCS13, MGN_MCS14, + MGN_MCS15, MGN_MCS16, MGN_MCS17, MGN_MCS18, MGN_MCS19, + MGN_MCS20, MGN_MCS21, MGN_MCS22, MGN_MCS23, MGN_MCS24, + MGN_MCS25, MGN_MCS26, MGN_MCS27, MGN_MCS28, MGN_MCS29, + MGN_MCS30, MGN_MCS31, + }; + if (pHalData->rf_type == RF_3T3R) + MaxRate = MGN_MCS23; + else if (pHalData->rf_type == RF_2T2R) + MaxRate = MGN_MCS15; + else + MaxRate = MGN_MCS7; + + for (path = StartPath; path <= EndPath; path++) { + for (i = 0; i < sizeof(rate); ++i) { + if (rate[i] > MaxRate) + break; + PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]); + } + } + } break; + + case MPT_VHT: + { + u1Byte rate[] = { + MGN_VHT1SS_MCS0, MGN_VHT1SS_MCS1, MGN_VHT1SS_MCS2, MGN_VHT1SS_MCS3, MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, MGN_VHT1SS_MCS6, MGN_VHT1SS_MCS7, MGN_VHT1SS_MCS8, MGN_VHT1SS_MCS9, + MGN_VHT2SS_MCS0, MGN_VHT2SS_MCS1, MGN_VHT2SS_MCS2, MGN_VHT2SS_MCS3, MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, MGN_VHT2SS_MCS6, MGN_VHT2SS_MCS7, MGN_VHT2SS_MCS8, MGN_VHT2SS_MCS9, + MGN_VHT3SS_MCS0, MGN_VHT3SS_MCS1, MGN_VHT3SS_MCS2, MGN_VHT3SS_MCS3, MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, MGN_VHT3SS_MCS6, MGN_VHT3SS_MCS7, MGN_VHT3SS_MCS8, MGN_VHT3SS_MCS9, + MGN_VHT4SS_MCS0, MGN_VHT4SS_MCS1, MGN_VHT4SS_MCS2, MGN_VHT4SS_MCS3, MGN_VHT4SS_MCS4, + MGN_VHT4SS_MCS5, MGN_VHT4SS_MCS6, MGN_VHT4SS_MCS7, MGN_VHT4SS_MCS8, MGN_VHT4SS_MCS9, + }; + + if (pHalData->rf_type == RF_3T3R) + MaxRate = MGN_VHT3SS_MCS9; + else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R) + MaxRate = MGN_VHT2SS_MCS9; + else + MaxRate = MGN_VHT1SS_MCS9; + + for (path = StartPath; path <= EndPath; path++) { + for (i = 0; i < sizeof(rate); ++i) { + if (rate[i] > MaxRate) + break; + PHY_SetTxPowerIndex(pAdapter, pTxPower[path], path, rate[i]); + } + } + } break; + + default: + DBG_871X("<===mpt_SetTxPower: Illegal channel!!\n"); + break; + } + +} + + +void hal_mpt_SetTxPower(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + + if (pHalData->rf_chip < RF_TYPE_MAX) { + if (IS_HARDWARE_TYPE_8188E(pAdapter) || + IS_HARDWARE_TYPE_8723B(pAdapter) || + IS_HARDWARE_TYPE_8192E(pAdapter) || + IS_HARDWARE_TYPE_8703B(pAdapter) || + IS_HARDWARE_TYPE_8188F(pAdapter)) { + u8 path = (pHalData->AntennaTxPath == ANTENNA_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B); + + DBG_8192C("===> MPT_ProSetTxPower: Old\n"); + + RT_TRACE(_module_mp_, DBG_LOUD, ("===> MPT_ProSetTxPower[Old]:\n")); + mpt_SetTxPower_Old(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel); + mpt_SetTxPower_Old(pAdapter, MPT_OFDM_AND_HT, pMptCtx->TxPwrLevel); + + } else { + DBG_871X("===> MPT_ProSetTxPower: Jaguar\n"); + mpt_SetTxPower(pAdapter, MPT_CCK, pMptCtx->TxPwrLevel); + mpt_SetTxPower(pAdapter, MPT_OFDM, pMptCtx->TxPwrLevel); + mpt_SetTxPower(pAdapter, MPT_HT, pMptCtx->TxPwrLevel); + mpt_SetTxPower(pAdapter, MPT_VHT, pMptCtx->TxPwrLevel); + + } + } else + DBG_8192C("RFChipID < RF_TYPE_MAX, the RF chip is not supported - %d\n", pHalData->rf_chip); + + ODM_ClearTxPowerTrackingState(pDM_Odm); + +} + + +void hal_mpt_SetDataRate(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u32 DataRate; + + DataRate = MptToMgntRate(pAdapter->mppriv.rateidx); + + hal_mpt_SwitchRfSetting(pAdapter); + + hal_mpt_CCKTxPowerAdjust(pAdapter, pHalData->bCCKinCH14); +#ifdef CONFIG_RTL8723B + if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter)) { + if (IS_CCK_RATE(DataRate)) { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0x6); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0x6); + } else { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0xE); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0xE); + } + } + + if ((IS_HARDWARE_TYPE_8723BS(pAdapter) && + ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90)))) { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, 0xF, 0xE); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x71, 0xF, 0xE); + } +#endif +} + + +#define RF_PATH_AB 22 + +#ifdef CONFIG_RTL8814A +VOID mpt_ToggleIG_8814A(PADAPTER pAdapter) +{ + u1Byte Path = 0; + u4Byte IGReg = rA_IGI_Jaguar, IGvalue = 0; + + for (Path; Path <= ODM_RF_PATH_D; Path++) { + switch (Path) { + case ODM_RF_PATH_B: + IGReg = rB_IGI_Jaguar; + break; + case ODM_RF_PATH_C: + IGReg = rC_IGI_Jaguar2; + break; + case ODM_RF_PATH_D: + IGReg = rD_IGI_Jaguar2; + break; + default: + IGReg = rA_IGI_Jaguar; + break; + } + + IGvalue = PHY_QueryBBReg(pAdapter, IGReg, bMaskByte0); + PHY_SetBBReg(pAdapter, IGReg, bMaskByte0, IGvalue+2); + PHY_SetBBReg(pAdapter, IGReg, bMaskByte0, IGvalue); + } +} + +VOID mpt_SetRFPath_8814A(PADAPTER pAdapter) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + R_ANTENNA_SELECT_OFDM *p_ofdm_tx; /* OFDM Tx register */ + R_ANTENNA_SELECT_CCK *p_cck_txrx; + + u8 ForcedDataRate = HwRateToMRate(pAdapter->mppriv.rateidx); + u8 HtStbcCap = pAdapter->registrypriv.stbc_cap; + /*/PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo);*/ + /*/PRT_VERY_HIGH_THROUGHPUT pVHTInfo = GET_VHT_INFO(pMgntInfo);*/ + + u32 ulAntennaTx = pHalData->AntennaTxPath; + u32 ulAntennaRx = pHalData->AntennaRxPath; + u8 NssforRate = MgntQuery_NssTxRate(ForcedDataRate); + + if (NssforRate == RF_2TX) { + DBG_871X("===> SetAntenna 2T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx); + + switch (ulAntennaTx) { + case ANTENNA_BC: + pMptCtx->MptRfPath = ODM_RF_PATH_BC; + /*pHalData->ValidTxPath = 0x06; linux no use */ + PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x106); /*/ 0x940[15:4]=12'b0000_0100_0011*/ + break; + + case ANTENNA_CD: + pMptCtx->MptRfPath = ODM_RF_PATH_CD; + /*pHalData->ValidTxPath = 0x0C;*/ + PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x40c); /*/ 0x940[15:4]=12'b0000_0100_0011*/ + break; + case ANTENNA_AB: default: + pMptCtx->MptRfPath = ODM_RF_PATH_AB; + /*pHalData->ValidTxPath = 0x03;*/ + PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0000fff0, 0x043); /*/ 0x940[15:4]=12'b0000_0100_0011*/ + break; + } + + } else if (NssforRate == RF_3TX) { + DBG_871X("===> SetAntenna 3T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx); + + switch (ulAntennaTx) { + case ANTENNA_BCD: + pMptCtx->MptRfPath = ODM_RF_PATH_BCD; + /*pHalData->ValidTxPath = 0x0e;*/ + PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0fff0000, 0x90e); /*/ 0x940[27:16]=12'b0010_0100_0111*/ + break; + + case ANTENNA_ABC: default: + pMptCtx->MptRfPath = ODM_RF_PATH_ABC; + /*pHalData->ValidTxPath = 0x0d;*/ + PHY_SetBBReg(pAdapter, rTxAnt_23Nsts_Jaguar2, 0x0fff0000, 0x247); /*/ 0x940[27:16]=12'b0010_0100_0111*/ + break; + } + + } else { /*/if(NssforRate == RF_1TX)*/ + DBG_871X("===> SetAntenna 1T ForcedDataRate %d NssforRate %d AntennaTx %d\n", ForcedDataRate, NssforRate, ulAntennaTx); + switch (ulAntennaTx) { + case ANTENNA_B: + pMptCtx->MptRfPath = ODM_RF_PATH_B; + /*pHalData->ValidTxPath = 0x02;*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x4); /*/ 0xa07[7:4] = 4'b0100*/ + PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x002); /*/ 0x93C[31:20]=12'b0000_0000_0010*/ + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x2); /* 0x80C[7:4] = 4'b0010*/ + break; + + case ANTENNA_C: + pMptCtx->MptRfPath = ODM_RF_PATH_C; + /*pHalData->ValidTxPath = 0x04;*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x2); /*/ 0xa07[7:4] = 4'b0010*/ + PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x004); /*/ 0x93C[31:20]=12'b0000_0000_0100*/ + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x4); /*/ 0x80C[7:4] = 4'b0100*/ + break; + + case ANTENNA_D: + pMptCtx->MptRfPath = ODM_RF_PATH_D; + /*pHalData->ValidTxPath = 0x08;*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x1); /*/ 0xa07[7:4] = 4'b0001*/ + PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x008); /*/ 0x93C[31:20]=12'b0000_0000_1000*/ + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x8); /*/ 0x80C[7:4] = 4'b1000*/ + break; + + case ANTENNA_A: default: + pMptCtx->MptRfPath = ODM_RF_PATH_A; + /*pHalData->ValidTxPath = 0x01;*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0xf0000000, 0x8); /*/ 0xa07[7:4] = 4'b1000*/ + PHY_SetBBReg(pAdapter, rTxAnt_1Nsts_Jaguar2, 0xfff00000, 0x001); /*/ 0x93C[31:20]=12'b0000_0000_0001*/ + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, 0xf0, 0x1); /*/ 0x80C[7:4] = 4'b0001*/ + break; + } + } + + switch (ulAntennaRx) { + case ANTENNA_A: + /*pHalData->ValidRxPath = 0x01;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x11); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x0); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_A_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_B: + /*pHalData->ValidRxPath = 0x02;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x22); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x1); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_C: + /*pHalData->ValidRxPath = 0x04;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x44); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x2); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_D: + /*pHalData->ValidRxPath = 0x08;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x88); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0C000000, 0x3); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_C_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_BC: + /*pHalData->ValidRxPath = 0x06;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x66); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x6); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, Rx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_D_0x0[19:16] = 1, Standby mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_CD: + /*pHalData->ValidRxPath = 0x0C;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xcc); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0xB); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, Rx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x5); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0xA); + break; + + case ANTENNA_BCD: + /*pHalData->ValidRxPath = 0x0e;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xee); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x6); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_A_0x0[19:16] = 1, Standby mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, Rx mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x3); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0x8); + break; + + case ANTENNA_ABCD: + /*pHalData->ValidRxPath = 0x0f;*/ + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x2); + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0xff); + PHY_SetBBReg(pAdapter, 0x1000, bMaskByte2, 0x3); + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, 0x0f000000, 0x1); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_A_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_C, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_C_0x0[19:16] = 3, RX mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_D, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_D_0x0[19:16] = 3, RX mode*/ + /*/ CCA related PD_delay_th*/ + PHY_SetBBReg(pAdapter, rAGC_table_Jaguar, 0x0F000000, 0x3); + PHY_SetBBReg(pAdapter, rPwed_TH_Jaguar, 0x0000000F, 0x8); + break; + + default: + RT_TRACE(_module_mp_, _drv_warning_, ("Unknown Rx antenna.\n")); + break; + } + + PHY_Set_SecCCATH_by_RXANT_8814A(pAdapter, ulAntennaRx); + + mpt_ToggleIG_8814A(pAdapter); + RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n")); +} + +VOID +mpt_SetSingleTone_8814A( + IN PADAPTER pAdapter, + IN BOOLEAN bSingleTone, + IN BOOLEAN bEnPMacTx) +{ + + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u1Byte StartPath = ODM_RF_PATH_A, EndPath = ODM_RF_PATH_A; + static u4Byte regIG0 = 0, regIG1 = 0, regIG2 = 0, regIG3 = 0; + + if (bSingleTone) { + regIG0 = PHY_QueryBBReg(pAdapter, rA_TxScale_Jaguar, bMaskDWord); /*/ 0xC1C[31:21]*/ + regIG1 = PHY_QueryBBReg(pAdapter, rB_TxScale_Jaguar, bMaskDWord); /*/ 0xE1C[31:21]*/ + regIG2 = PHY_QueryBBReg(pAdapter, rC_TxScale_Jaguar2, bMaskDWord); /*/ 0x181C[31:21]*/ + regIG3 = PHY_QueryBBReg(pAdapter, rD_TxScale_Jaguar2, bMaskDWord); /*/ 0x1A1C[31:21]*/ + + switch (pMptCtx->MptRfPath) { + case ODM_RF_PATH_A: case ODM_RF_PATH_B: + case ODM_RF_PATH_C: case ODM_RF_PATH_D: + StartPath = pMptCtx->MptRfPath; + EndPath = pMptCtx->MptRfPath; + break; + case ODM_RF_PATH_AB: + EndPath = ODM_RF_PATH_B; + break; + case ODM_RF_PATH_BC: + StartPath = ODM_RF_PATH_B; + EndPath = ODM_RF_PATH_C; + break; + case ODM_RF_PATH_ABC: + EndPath = ODM_RF_PATH_C; + break; + case ODM_RF_PATH_BCD: + StartPath = ODM_RF_PATH_B; + EndPath = ODM_RF_PATH_D; + break; + case ODM_RF_PATH_ABCD: + EndPath = ODM_RF_PATH_D; + break; + } + + if (bEnPMacTx == FALSE) { + hal_mpt_SetOFDMContinuousTx(pAdapter, _TRUE); + issue_nulldata(pAdapter, NULL, 1, 3, 500); + } + + PHY_SetBBReg(pAdapter, rCCAonSec_Jaguar, BIT1, 0x1); /*/ Disable CCA*/ + + for (StartPath; StartPath <= EndPath; StartPath++) { + PHY_SetRFReg(pAdapter, StartPath, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */ + PHY_SetRFReg(pAdapter, StartPath, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/ + + PHY_SetRFReg(pAdapter, StartPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/ + } + + PHY_SetBBReg(pAdapter, rA_TxScale_Jaguar, 0xFFE00000, 0); /*/ 0xC1C[31:21]*/ + PHY_SetBBReg(pAdapter, rB_TxScale_Jaguar, 0xFFE00000, 0); /*/ 0xE1C[31:21]*/ + PHY_SetBBReg(pAdapter, rC_TxScale_Jaguar2, 0xFFE00000, 0); /*/ 0x181C[31:21]*/ + PHY_SetBBReg(pAdapter, rD_TxScale_Jaguar2, 0xFFE00000, 0); /*/ 0x1A1C[31:21]*/ + + } else { + + switch (pMptCtx->MptRfPath) { + case ODM_RF_PATH_A: case ODM_RF_PATH_B: + case ODM_RF_PATH_C: case ODM_RF_PATH_D: + StartPath = pMptCtx->MptRfPath; + EndPath = pMptCtx->MptRfPath; + break; + case ODM_RF_PATH_AB: + EndPath = ODM_RF_PATH_B; + break; + case ODM_RF_PATH_BC: + StartPath = ODM_RF_PATH_B; + EndPath = ODM_RF_PATH_C; + break; + case ODM_RF_PATH_ABC: + EndPath = ODM_RF_PATH_C; + break; + case ODM_RF_PATH_BCD: + StartPath = ODM_RF_PATH_B; + EndPath = ODM_RF_PATH_D; + break; + case ODM_RF_PATH_ABCD: + EndPath = ODM_RF_PATH_D; + break; + } + + for (StartPath; StartPath <= EndPath; StartPath++) + PHY_SetRFReg(pAdapter, StartPath, LNA_Low_Gain_3, BIT1, 0x0); /*// RF LO disabled*/ + + + PHY_SetBBReg(pAdapter, rCCAonSec_Jaguar, BIT1, 0x0); /* Enable CCA*/ + + if (bEnPMacTx == FALSE) + hal_mpt_SetOFDMContinuousTx(pAdapter, _FALSE); + + PHY_SetBBReg(pAdapter, rA_TxScale_Jaguar, bMaskDWord, regIG0); /* 0xC1C[31:21]*/ + PHY_SetBBReg(pAdapter, rB_TxScale_Jaguar, bMaskDWord, regIG1); /* 0xE1C[31:21]*/ + PHY_SetBBReg(pAdapter, rC_TxScale_Jaguar2, bMaskDWord, regIG2); /* 0x181C[31:21]*/ + PHY_SetBBReg(pAdapter, rD_TxScale_Jaguar2, bMaskDWord, regIG3); /* 0x1A1C[31:21]*/ + } +} + +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +void mpt_SetRFPath_8812A(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; + u32 ulAntennaTx, ulAntennaRx; + + ulAntennaTx = pHalData->AntennaTxPath; + ulAntennaRx = pHalData->AntennaRxPath; + + switch (ulAntennaTx) { + case ANTENNA_A: + pMptCtx->MptRfPath = ODM_RF_PATH_A; + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x1111); + if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter)) + PHY_SetBBReg(pAdapter, r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x0); + break; + case ANTENNA_B: + pMptCtx->MptRfPath = ODM_RF_PATH_B; + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x2222); + if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter)) + PHY_SetBBReg(pAdapter, r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x1); + break; + case ANTENNA_AB: + pMptCtx->MptRfPath = ODM_RF_PATH_AB; + PHY_SetBBReg(pAdapter, rTxPath_Jaguar, bMaskLWord, 0x3333); + if (pHalData->RFEType == 3 && IS_HARDWARE_TYPE_8812(pAdapter)) + PHY_SetBBReg(pAdapter, r_ANTSEL_SW_Jaguar, bMask_AntselPathFollow_Jaguar, 0x0); + break; + default: + pMptCtx->MptRfPath = ODM_RF_PATH_AB; + DBG_871X("Unknown Tx antenna.\n"); + break; + } + + switch (ulAntennaRx) { + u32 reg0xC50 = 0; + case ANTENNA_A: + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x11); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x1); /*/ RF_B_0x0[19:16] = 1, Standby mode*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, BIT19|BIT18|BIT17|BIT16, 0x3); + + /*/ <20121101, Kordan> To prevent gain table from not switched, asked by Ynlin.*/ + reg0xC50 = PHY_QueryBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0); + PHY_SetBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0, reg0xC50+2); + PHY_SetBBReg(pAdapter, rA_IGI_Jaguar, bMaskByte0, reg0xC50); + break; + case ANTENNA_B: + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x22); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, 0xF0000, 0x1);/*/ RF_A_0x0[19:16] = 1, Standby mode */ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x1); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, BIT19|BIT18|BIT17|BIT16, 0x3); + + /*/ <20121101, Kordan> To prevent gain table from not switched, asked by Ynlin.*/ + reg0xC50 = PHY_QueryBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0); + PHY_SetBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0, reg0xC50+2); + PHY_SetBBReg(pAdapter, rB_IGI_Jaguar, bMaskByte0, reg0xC50); + break; + case ANTENNA_AB: + PHY_SetBBReg(pAdapter, rRxPath_Jaguar, bMaskByte0, 0x33); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_AC_Jaguar, 0xF0000, 0x3); /*/ RF_B_0x0[19:16] = 3, Rx mode*/ + PHY_SetBBReg(pAdapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0); + break; + default: + DBG_871X("Unknown Rx antenna.\n"); + break; + } + RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n")); +} +#endif + + +#ifdef CONFIG_RTL8723B +void mpt_SetRFPath_8723B(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u32 ulAntennaTx, ulAntennaRx; + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ulAntennaTx = pHalData->AntennaTxPath; + ulAntennaRx = pHalData->AntennaRxPath; + + if (pHalData->rf_chip >= RF_TYPE_MAX) { + DBG_8192C("This RF chip ID is not supported\n"); + return; + } + + switch (pAdapter->mppriv.antenna_tx) { + u8 p = 0, i = 0; + case ANTENNA_A: /*/ Actually path S1 (Wi-Fi)*/ + { + pMptCtx->MptRfPath = ODM_RF_PATH_A; + PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x0); + PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x0); /* AGC Table Sel*/ + + /*/<20130522, Kordan> 0x51 and 0x71 should be set immediately after path switched, or they might be overwritten.*/ + if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90)) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B10E); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B04E); + + + for (i = 0; i < 3; ++i) { + u4Byte offset = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][0]; + u4Byte data = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][1]; + + if (offset != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_8192C("Switch to S1 TxIQC(offset, data) = (0x%X, 0x%X)\n", offset, data); + } + + } + for (i = 0; i < 2; ++i) { + u4Byte offset = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][0]; + u4Byte data = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][1]; + + if (offset != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_8192C("Switch to S1 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + } + break; + case ANTENNA_B: /*/ Actually path S0 (BT)*/ + { + u4Byte offset; + u4Byte data; + + pMptCtx->MptRfPath = ODM_RF_PATH_B; + PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x5); + PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x1); /*/ AGC Table Sel.*/ + + /* <20130522, Kordan> 0x51 and 0x71 should be set immediately after path switched, or they might be overwritten.*/ + if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA90)) + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B10E); + else + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x51, bRFRegOffsetMask, 0x6B04E); + + for (i = 0; i < 3; ++i) { + /*/ <20130603, Kordan> Because BB suppors only 1T1R, we restore IQC to S1 instead of S0.*/ + offset = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_A][i][0]; + data = pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_B][i][1]; + if (pRFCalibrateInfo->TxIQC_8723B[ODM_RF_PATH_B][i][0] != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_8192C("Switch to S0 TxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + /*/ <20130603, Kordan> Because BB suppors only 1T1R, we restore IQC to S1 instead of S0.*/ + for (i = 0; i < 2; ++i) { + offset = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_A][i][0]; + data = pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_B][i][1]; + + if (pRFCalibrateInfo->RxIQC_8723B[ODM_RF_PATH_B][i][0] != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_8192C("Switch to S0 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + } + break; + default: + pMptCtx->MptRfPath = RF_PATH_AB; + RT_TRACE(_module_mp_, _drv_notice_, ("Unknown Tx antenna.\n")); + break; + } + RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n")); +} +#endif + +#ifdef CONFIG_RTL8703B +void mpt_SetRFPath_8703B(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u4Byte ulAntennaTx, ulAntennaRx; + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ulAntennaTx = pHalData->AntennaTxPath; + ulAntennaRx = pHalData->AntennaRxPath; + + if (pHalData->rf_chip >= RF_TYPE_MAX) { + DBG_871X("This RF chip ID is not supported\n"); + return; + } + + switch (pAdapter->mppriv.antenna_tx) { + u1Byte p = 0, i = 0; + + case ANTENNA_A: /* Actually path S1 (Wi-Fi) */ + { + pMptCtx->MptRfPath = ODM_RF_PATH_A; + PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x0); + PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x0); /* AGC Table Sel*/ + + for (i = 0; i < 3; ++i) { + u4Byte offset = pRFCalibrateInfo->TxIQC_8703B[i][0]; + u4Byte data = pRFCalibrateInfo->TxIQC_8703B[i][1]; + + if (offset != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_871X("Switch to S1 TxIQC(offset, data) = (0x%X, 0x%X)\n", offset, data); + } + + } + for (i = 0; i < 2; ++i) { + u4Byte offset = pRFCalibrateInfo->RxIQC_8703B[i][0]; + u4Byte data = pRFCalibrateInfo->RxIQC_8703B[i][1]; + + if (offset != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_871X("Switch to S1 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + } + break; + case ANTENNA_B: /* Actually path S0 (BT)*/ + { + pMptCtx->MptRfPath = ODM_RF_PATH_B; + PHY_SetBBReg(pAdapter, rS0S1_PathSwitch, BIT9|BIT8|BIT7, 0x5); + PHY_SetBBReg(pAdapter, 0xB2C, BIT31, 0x1); /* AGC Table Sel */ + + for (i = 0; i < 3; ++i) { + u4Byte offset = pRFCalibrateInfo->TxIQC_8703B[i][0]; + u4Byte data = pRFCalibrateInfo->TxIQC_8703B[i][1]; + + if (pRFCalibrateInfo->TxIQC_8703B[i][0] != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_871X("Switch to S0 TxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + for (i = 0; i < 2; ++i) { + u4Byte offset = pRFCalibrateInfo->RxIQC_8703B[i][0]; + u4Byte data = pRFCalibrateInfo->RxIQC_8703B[i][1]; + + if (pRFCalibrateInfo->RxIQC_8703B[i][0] != 0) { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, data); + DBG_871X("Switch to S0 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data); + } + } + } + break; + default: + pMptCtx->MptRfPath = RF_PATH_AB; + RT_TRACE(_module_mp_, _drv_notice_, ("Unknown Tx antenna.\n")); + break; + } + + RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n")); +} +#endif + + +VOID mpt_SetRFPath_819X(PADAPTER pAdapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u4Byte ulAntennaTx, ulAntennaRx; + R_ANTENNA_SELECT_OFDM *p_ofdm_tx; /* OFDM Tx register */ + R_ANTENNA_SELECT_CCK *p_cck_txrx; + u1Byte r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0; + u1Byte chgTx = 0, chgRx = 0; + u4Byte r_ant_sel_cck_val = 0, r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0; + + ulAntennaTx = pHalData->AntennaTxPath; + ulAntennaRx = pHalData->AntennaRxPath; + + p_ofdm_tx = (R_ANTENNA_SELECT_OFDM *)&r_ant_select_ofdm_val; + p_cck_txrx = (R_ANTENNA_SELECT_CCK *)&r_ant_select_cck_val; + + p_ofdm_tx->r_ant_ht1 = 0x1; + p_ofdm_tx->r_ant_ht2 = 0x2;/*Second TX RF path is A*/ + p_ofdm_tx->r_ant_non_ht = 0x3;/*/ 0x1+0x2=0x3 */ + + switch (ulAntennaTx) { + case ANTENNA_A: + p_ofdm_tx->r_tx_antenna = 0x1; + r_ofdm_tx_en_val = 0x1; + p_ofdm_tx->r_ant_l = 0x1; + p_ofdm_tx->r_ant_ht_s1 = 0x1; + p_ofdm_tx->r_ant_non_ht_s1 = 0x1; + p_cck_txrx->r_ccktx_enable = 0x8; + chgTx = 1; + /*/ From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/ + /*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/ + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); + r_ofdm_tx_en_val = 0x3; + /*/ Power save*/ + /*/cosa r_ant_select_ofdm_val = 0x11111111;*/ + /*/ We need to close RFB by SW control*/ + if (pHalData->rf_type == RF_2T2R) { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 0); + } + } + pMptCtx->MptRfPath = ODM_RF_PATH_A; + break; + case ANTENNA_B: + p_ofdm_tx->r_tx_antenna = 0x2; + r_ofdm_tx_en_val = 0x2; + p_ofdm_tx->r_ant_l = 0x2; + p_ofdm_tx->r_ant_ht_s1 = 0x2; + p_ofdm_tx->r_ant_non_ht_s1 = 0x2; + p_cck_txrx->r_ccktx_enable = 0x4; + chgTx = 1; + /*/ From SD3 Willis suggestion !!! Set RF A as standby*/ + /*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/ + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); + + /*/ 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table.*/ + /*/ 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control*/ + if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0); + /*/PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/ + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 0); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1); + } + } + pMptCtx->MptRfPath = ODM_RF_PATH_B; + break; + case ANTENNA_AB:/*/ For 8192S*/ + p_ofdm_tx->r_tx_antenna = 0x3; + r_ofdm_tx_en_val = 0x3; + p_ofdm_tx->r_ant_l = 0x3; + p_ofdm_tx->r_ant_ht_s1 = 0x3; + p_ofdm_tx->r_ant_non_ht_s1 = 0x3; + p_cck_txrx->r_ccktx_enable = 0xC; + chgTx = 1; + /*/ From SD3Willis suggestion !!! Set RF B as standby*/ + /*/if (IS_HARDWARE_TYPE_8192S(pAdapter))*/ + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); + /* Disable Power save*/ + /*cosa r_ant_select_ofdm_val = 0x3321333;*/ + /* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control*/ + if (pHalData->rf_type == RF_2T2R) { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0); + + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0); + /*/PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);*/ + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1); + } + } + pMptCtx->MptRfPath = ODM_RF_PATH_AB; + break; + default: + break; + } + + + +/*// r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D +// r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D +// r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D */ + switch (ulAntennaRx) { + case ANTENNA_A: + r_rx_antenna_ofdm = 0x1; /* A*/ + p_cck_txrx->r_cckrx_enable = 0x0; /* default: A*/ + p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A*/ + chgRx = 1; + break; + case ANTENNA_B: + r_rx_antenna_ofdm = 0x2; /*/ B*/ + p_cck_txrx->r_cckrx_enable = 0x1; /*/ default: B*/ + p_cck_txrx->r_cckrx_enable_2 = 0x1; /*/ option: B*/ + chgRx = 1; + break; + case ANTENNA_AB:/*/ For 8192S and 8192E/U...*/ + r_rx_antenna_ofdm = 0x3;/*/ AB*/ + p_cck_txrx->r_cckrx_enable = 0x0;/*/ default:A*/ + p_cck_txrx->r_cckrx_enable_2 = 0x1;/*/ option:B*/ + chgRx = 1; + break; + default: + break; + } + + + if (chgTx && chgRx) { + switch (pHalData->rf_chip) { + case RF_8225: + case RF_8256: + case RF_6052: + /*/r_ant_sel_cck_val = r_ant_select_cck_val;*/ + PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); /*/OFDM Tx*/ + PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); /*/OFDM Tx*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /*/OFDM Rx*/ + PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /*/OFDM Rx*/ + if (IS_HARDWARE_TYPE_8192E(pAdapter)) { + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x000000F0, r_rx_antenna_ofdm); /*/OFDM Rx*/ + PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x000000F0, r_rx_antenna_ofdm); /*/OFDM Rx*/ + } + PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val);/*/r_ant_sel_cck_val); /CCK TxRx*/ + break; + + default: + DBG_871X("Unsupported RFChipID for switching antenna.\n"); + break; + } + } +} /* MPT_ProSetRFPath */ + + +void hal_mpt_SetAntenna(PADAPTER pAdapter) + +{ + DBG_871X("Do %s\n", __func__); +#ifdef CONFIG_RTL8814A + if (IS_HARDWARE_TYPE_8814A(pAdapter)) { + mpt_SetRFPath_8814A(pAdapter); + return; + } +#endif +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) { + mpt_SetRFPath_8812A(pAdapter); + return; + } +#endif +#ifdef CONFIG_RTL8723B + if (IS_HARDWARE_TYPE_8723B(pAdapter)) { + mpt_SetRFPath_8723B(pAdapter); + return; + } +#endif +#ifdef CONFIG_RTL8703B + if (IS_HARDWARE_TYPE_8703B(pAdapter)) { + mpt_SetRFPath_8703B(pAdapter); + return; + } +#endif + +/* else if (IS_HARDWARE_TYPE_8821B(pAdapter)) + mpt_SetRFPath_8821B(pAdapter); + Prepare for 8822B + else if (IS_HARDWARE_TYPE_8822B(Context)) + mpt_SetRFPath_8822B(Context); +*/ + mpt_SetRFPath_819X(pAdapter); + DBG_871X("mpt_SetRFPath_819X Do %s\n", __func__); + +} + + +s32 hal_mpt_SetThermalMeter(PADAPTER pAdapter, u8 target_ther) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + if (!netif_running(pAdapter->pnetdev)) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter! Fail: interface not opened!\n")); + return _FAIL; + } + + + if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) { + RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter: Fail! not in MP mode!\n")); + return _FAIL; + } + + + target_ther &= 0xff; + if (target_ther < 0x07) + target_ther = 0x07; + else if (target_ther > 0x1d) + target_ther = 0x1d; + + pHalData->EEPROMThermalMeter = target_ther; + + return _SUCCESS; +} + + +void hal_mpt_TriggerRFThermalMeter(PADAPTER pAdapter) +{ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x42, BIT17 | BIT16, 0x03); + +} + + +u8 hal_mpt_ReadRFThermalMeter(PADAPTER pAdapter) + +{ + u32 ThermalValue = 0; + + ThermalValue = (u1Byte)PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, 0x42, 0xfc00); /*0x42: RF Reg[15:10]*/ + return (u8)ThermalValue; + +} + + +void hal_mpt_GetThermalMeter(PADAPTER pAdapter, u8 *value) +{ +#if 0 + fw_cmd(pAdapter, IOCMD_GET_THERMAL_METER); + rtw_msleep_os(1000); + fw_cmd_data(pAdapter, value, 1); + *value &= 0xFF; +#else + hal_mpt_TriggerRFThermalMeter(pAdapter); + rtw_msleep_os(1000); + *value = hal_mpt_ReadRFThermalMeter(pAdapter); +#endif + +} + + +void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + pAdapter->mppriv.MptCtx.bSingleCarrier = bStart; + + if (bStart) {/*/ Start Single Carrier.*/ + RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleCarrierTx: test start\n")); + /*/ Start Single Carrier.*/ + /*/ 1. if OFDM block on?*/ + if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1); /*set OFDM block on*/ + + /*/ 2. set CCK test mode off, set to CCK normal mode*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0); + + /*/ 3. turn on scramble setting*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 1); + + /*/ 4. Turn On Continue Tx and turn off the other test modes.*/ +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/) + PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_SingleCarrier); + else +#endif + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_SingleCarrier); + + } else { + /*/ Stop Single Carrier.*/ + /*/ Stop Single Carrier.*/ + /*/ Turn off all test modes.*/ +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/) + PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_ALL_OFF); + else +#endif + + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + + rtw_msleep_os(10); + /*/BB Reset*/ + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } +} + + +void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u4Byte ulAntennaTx = pHalData->AntennaTxPath; + static u4Byte regRF = 0, regBB0 = 0, regBB1 = 0, regBB2 = 0, regBB3 = 0; + u8 rfPath; + + switch (ulAntennaTx) { + case ANTENNA_B: + rfPath = ODM_RF_PATH_B; + break; + case ANTENNA_C: + rfPath = ODM_RF_PATH_C; + break; + case ANTENNA_D: + rfPath = ODM_RF_PATH_D; + break; + case ANTENNA_A: + default: + rfPath = ODM_RF_PATH_A; + break; + } + + pAdapter->mppriv.MptCtx.bSingleTone = bStart; + if (bStart) { + /*/ Start Single Tone.*/ + /*/ <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu)*/ + if (IS_HARDWARE_TYPE_8188E(pAdapter)) { + regRF = PHY_QueryRFReg(pAdapter, rfPath, LNA_Low_Gain_3, bRFRegOffsetMask); + + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/ + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0); + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0); + } else if (IS_HARDWARE_TYPE_8192E(pAdapter)) { /*/ USB need to do RF LO disable first, PCIE isn't required to follow this order.*/ + /*/Set MAC REG 88C: Prevent SingleTone Fail*/ + PHY_SetMacReg(pAdapter, 0x88C, 0xF00000, 0xF); + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO disabled*/ + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/ + } else if (IS_HARDWARE_TYPE_8723B(pAdapter)) { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x56, 0xF, 0x1); /*/ RF LO enabled*/ + } else { + /*/ S0/S1 both use PATH A to configure*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /*/ Tx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x76, 0xF, 0x1); /*/ RF LO enabled*/ + } + } else if (IS_HARDWARE_TYPE_8703B(pAdapter)) { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x2); /* Tx mode */ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x53, 0xF000, 0x1); /* RF LO enabled */ + } + } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) { + /*Set BB REG 88C: Prevent SingleTone Fail*/ + PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, 0xF00000, 0xF); + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1); + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x2); + + } else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) { +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + u1Byte p = ODM_RF_PATH_A; + + regRF = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_AC_Jaguar, bRFRegOffsetMask); + regBB0 = PHY_QueryBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, bMaskDWord); + regBB1 = PHY_QueryBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, bMaskDWord); + regBB2 = PHY_QueryBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, bMaskDWord); + regBB3 = PHY_QueryBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, bMaskDWord); + + PHY_SetBBReg(pAdapter, rOFDMCCKEN_Jaguar, BIT29|BIT28, 0x0); /*/ Disable CCK and OFDM*/ + + if (pMptCtx->MptRfPath == ODM_RF_PATH_AB) { + for (p = ODM_RF_PATH_A; p <= ODM_RF_PATH_B; ++p) { + PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */ + PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/ + PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/ + } + } else { + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC_Jaguar, 0xF0000, 0x2); /*/ Tx mode: RF0x00[19:16]=4'b0010 */ + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC_Jaguar, 0x1F, 0x0); /*/ Lowest RF gain index: RF_0x0[4:0] = 0*/ + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x1); /*/ RF LO enabled*/ + } + + PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, 0xFF00F0, 0x77007); /*/ 0xCB0[[23:16, 7:4] = 0x77007*/ + PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, 0xFF00F0, 0x77007); /*/ 0xCB0[[23:16, 7:4] = 0x77007*/ + + if (pHalData->ExternalPA_5G) { + PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x12); /*/ 0xCB4[23:16] = 0x12*/ + PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x12); /*/ 0xEB4[23:16] = 0x12*/ + } else if (pHalData->ExternalPA_2G) { + PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x11); /*/ 0xCB4[23:16] = 0x11*/ + PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, 0xFF00000, 0x11); /*/ 0xEB4[23:16] = 0x11*/ + } +#endif + } +#ifdef CONFIG_RTL8814A + else if (IS_HARDWARE_TYPE_8814A(pAdapter)) + mpt_SetSingleTone_8814A(pAdapter, TRUE, FALSE); +#endif + else /*/ Turn On SingleTone and turn off the other test modes.*/ + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_SingleTone); + + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + } else {/*/ Stop Single Ton e.*/ + + if (IS_HARDWARE_TYPE_8188E(pAdapter)) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, regRF); + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1); + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1); + } else if (IS_HARDWARE_TYPE_8192E(pAdapter)) { + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x3);/*/ Tx mode*/ + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x0);/*/ RF LO disabled */ + /*/ RESTORE MAC REG 88C: Enable RF Functions*/ + PHY_SetMacReg(pAdapter, 0x88C, 0xF00000, 0x0); + } else if (IS_HARDWARE_TYPE_8723B(pAdapter)) { + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) { + + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /*/ Rx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x56, 0xF, 0x0); /*/ RF LO disabled*/ + } else { + /*/ S0/S1 both use PATH A to configure*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /*/ Rx mode*/ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x76, 0xF, 0x0); /*/ RF LO disabled*/ + } + } else if (IS_HARDWARE_TYPE_8703B(pAdapter)) { + + if (pMptCtx->MptRfPath == ODM_RF_PATH_A) { + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, 0xF0000, 0x3); /* Rx mode */ + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, 0x53, 0xF000, 0x0); /* RF LO disabled */ + } + } else if (IS_HARDWARE_TYPE_8188F(pAdapter)) { + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, RF_AC, 0xF0000, 0x3); /*Tx mode*/ + PHY_SetRFReg(pAdapter, pMptCtx->MptRfPath, LNA_Low_Gain_3, BIT1, 0x0); /*RF LO disabled*/ + /*Set BB REG 88C: Prevent SingleTone Fail*/ + PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, 0xF00000, 0xc); + } else if (IS_HARDWARE_TYPE_JAGUAR(pAdapter)) { +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) + u1Byte p = ODM_RF_PATH_A; + + PHY_SetBBReg(pAdapter, rOFDMCCKEN_Jaguar, BIT29|BIT28, 0x3); /*/ Disable CCK and OFDM*/ + + if (pMptCtx->MptRfPath == ODM_RF_PATH_AB) { + for (p = ODM_RF_PATH_A; p <= ODM_RF_PATH_B; ++p) { + PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, bRFRegOffsetMask, regRF); + PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x0); /*/ RF LO disabled*/ + } + } else { + PHY_SetRFReg(pAdapter, p, RF_AC_Jaguar, bRFRegOffsetMask, regRF); + PHY_SetRFReg(pAdapter, p, LNA_Low_Gain_3, BIT1, 0x0); /*/ RF LO disabled*/ + } + + PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar, bMaskDWord, regBB0); + PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar, bMaskDWord, regBB1); + PHY_SetBBReg(pAdapter, rA_RFE_Pinmux_Jaguar+4, bMaskDWord, regBB2); + PHY_SetBBReg(pAdapter, rB_RFE_Pinmux_Jaguar+4, bMaskDWord, regBB3); +#endif + } +#ifdef CONFIG_RTL8814A + else if (IS_HARDWARE_TYPE_8814A(pAdapter)) + mpt_SetSingleTone_8814A(pAdapter, FALSE, FALSE); + + else/*/ Turn off all test modes.*/ + PHY_SetBBReg(pAdapter, rSingleTone_ContTx_Jaguar, BIT18|BIT17|BIT16, OFDM_ALL_OFF); +#endif + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + + } +} + + +void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart) +{ + u8 Rate; + pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart; + + Rate = HwRateToMPTRate(pAdapter->mppriv.rateidx); + if (bStart) {/* Start Carrier Suppression.*/ + RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test start\n")); + if (Rate <= MPT_RATE_11M) { + /*/ 1. if CCK block on?*/ + if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/ + + /*/Turn Off All Test Mode*/ + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF);/* rSingleTone_ContTx_Jaguar*/ + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*/transmit mode*/ + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); /*/turn off scramble setting*/ + + /*/Set CCK Tx Test Rate*/ + write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); /*/Set FTxRate to 1Mbps*/ + } + + /*Set for dynamic set Power index*/ + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + } else {/* Stop Carrier Suppression.*/ + RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test stop\n")); + + if (Rate <= MPT_RATE_11M) { + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*normal mode*/ + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/ + + /*BB Reset*/ + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + } + /*Stop for dynamic set Power index*/ + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + } + DBG_871X("\n MPT_ProSetCarrierSupp() is finished.\n"); +} + +void hal_mpt_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + u32 cckrate; + + if (bStart) { + RT_TRACE(_module_mp_, _drv_alert_, + ("SetCCKContinuousTx: test start\n")); + + /*/ 1. if CCK block on?*/ + if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn)) + write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/*set CCK block on*/ + + /*/Turn Off All Test Mode*/ + if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter)) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF);/*rSingleTone_ContTx_Jaguar*/ + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + + /*/Set CCK Tx Test Rate*/ + + cckrate = pAdapter->mppriv.rateidx; + + write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*/transmit mode*/ + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /*/turn on scramble setting*/ + + if (!IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter)) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3); /* rCCK0_RxHP 0xa15[1:0] = 11 force cck rxiq = 0*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /*/ 0xc08[16] = 1 force ofdm rxiq = ofdm txiq*/ + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 1); + PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 1); + } + + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + } else { + RT_TRACE(_module_mp_, _drv_info_, + ("SetCCKContinuousTx: test stop\n")); + + write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*/normal mode*/ + write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /*/turn on scramble setting*/ + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_8814A(pAdapter) /* && !IS_HARDWARE_TYPE_8822B(pAdapter) */) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0);/* rCCK0_RxHP 0xa15[1:0] = 2b00*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0); /*/ 0xc08[16] = 0*/ + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 0); + PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 0); + } + + /*/BB Reset*/ + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + } + + pAdapter->mppriv.MptCtx.bCckContTx = bStart; + pAdapter->mppriv.MptCtx.bOfdmContTx = _FALSE; +} + +void hal_mpt_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + if (bStart) { + RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test start\n"));/*/ 1. if OFDM block on?*/ + if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1);/*/set OFDM block on*/ + + /*/ 2. set CCK test mode off, set to CCK normal mode*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0); + + /*/ 3. turn on scramble setting*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 1); + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_8814A(pAdapter) /*&& !IS_HARDWARE_TYPE_8822B(pAdapter)*/) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3); /* rCCK0_RxHP 0xa15[1:0] = 2b'11*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1*/ + } + + /*/ 4. Turn On Continue Tx and turn off the other test modes.*/ + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ContinuousTx);/*rSingleTone_ContTx_Jaguar*/ + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ContinuousTx); + + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + } else { + RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test stop\n")); + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter) /*|| IS_HARDWARE_TYPE_8822B(pAdapter)*/) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF); + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + /*/Delay 10 ms*/ + rtw_msleep_os(10); + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_8814A(pAdapter) /*&&! IS_HARDWARE_TYPE_8822B(pAdapter)*/) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0);/*/ 0xa15[1:0] = 0*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0);/*/ 0xc08[16] = 0*/ + } + + /*/BB Reset*/ + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + + write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + } + + pAdapter->mppriv.MptCtx.bCckContTx = _FALSE; + pAdapter->mppriv.MptCtx.bOfdmContTx = bStart; +} + +void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart) +{ + u8 Rate; + RT_TRACE(_module_mp_, _drv_info_, + ("SetContinuousTx: rate:%d\n", pAdapter->mppriv.rateidx)); + + Rate = HwRateToMPTRate(pAdapter->mppriv.rateidx); + pAdapter->mppriv.MptCtx.bStartContTx = bStart; + + if (Rate <= MPT_RATE_11M) + hal_mpt_SetCCKContinuousTx(pAdapter, bStart); + else if (Rate >= MPT_RATE_6M) + hal_mpt_SetOFDMContinuousTx(pAdapter, bStart); +} + +#ifdef CONFIG_MP_VHT_HW_TX_MODE +static VOID mpt_StopCckContTx( + PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u1Byte u1bReg; + + pMptCtx->bCckContTx = FALSE; + pMptCtx->bOfdmContTx = FALSE; + + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /*normal mode*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/ + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR2(pAdapter)) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0); /* 0xa15[1:0] = 2b00*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0); /* 0xc08[16] = 0*/ + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 0); + PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 0); + } + + /*BB Reset*/ + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); + +} /* mpt_StopCckContTx */ + + +static VOID mpt_StopOfdmContTx( + PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u1Byte u1bReg; + u4Byte data; + + pMptCtx->bCckContTx = FALSE; + pMptCtx->bOfdmContTx = FALSE; + + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_JAGUAR2(pAdapter)) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF); + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + + rtw_mdelay_os(10); + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR2(pAdapter)) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x0); /* 0xa15[1:0] = 0*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x0); /* 0xc08[16] = 0*/ + } + + /*BB Reset*/ + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); + PHY_SetBBReg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100); +} /* mpt_StopOfdmContTx */ + + +static VOID mpt_StartCckContTx( + PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + u4Byte cckrate; + + /* 1. if CCK block on */ + if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn)) + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 1);/*set CCK block on*/ + + /*Turn Off All Test Mode*/ + if (IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter)) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ALL_OFF); + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ALL_OFF); + + cckrate = pAdapter->mppriv.rateidx; + + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); + + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /*transmit mode*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /*turn on scramble setting*/ + + if (!IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(pAdapter)) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 11 force cck rxiq = 0*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1 force ofdm rxiq = ofdm txiq*/ + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, BIT14, 1); + PHY_SetBBReg(pAdapter, 0x0B34, BIT14, 1); + } + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + pMptCtx->bCckContTx = TRUE; + pMptCtx->bOfdmContTx = FALSE; + +} /* mpt_StartCckContTx */ + + +static VOID mpt_StartOfdmContTx( + PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); + + /* 1. if OFDM block on?*/ + if (!PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) + PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 1);/*set OFDM block on*/ + + /* 2. set CCK test mode off, set to CCK normal mode*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKBBMode, 0); + + /* 3. turn on scramble setting*/ + PHY_SetBBReg(pAdapter, rCCK0_System, bCCKScramble, 1); + + if (!IS_HARDWARE_TYPE_JAGUAR(pAdapter) && !IS_HARDWARE_TYPE_JAGUAR2(pAdapter)) { + PHY_SetBBReg(pAdapter, 0xa14, 0x300, 0x3); /* 0xa15[1:0] = 2b'11*/ + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, 0x10000, 0x1); /* 0xc08[16] = 1*/ + } + + /* 4. Turn On Continue Tx and turn off the other test modes.*/ + if (IS_HARDWARE_TYPE_JAGUAR(pAdapter) || IS_HARDWARE_TYPE_JAGUAR2(pAdapter)) + PHY_SetBBReg(pAdapter, 0x914, BIT18|BIT17|BIT16, OFDM_ContinuousTx); + else + PHY_SetBBReg(pAdapter, rOFDM1_LSTF, BIT30|BIT29|BIT28, OFDM_ContinuousTx); + + PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500); + PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500); + + pMptCtx->bCckContTx = FALSE; + pMptCtx->bOfdmContTx = TRUE; +} /* mpt_StartOfdmContTx */ + + +VOID mpt_ProSetPMacTx(PADAPTER Adapter) +{ + PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx); + RT_PMAC_TX_INFO PMacTxInfo = pMptCtx->PMacTxInfo; + u32 u4bTmp; + + DbgPrint("SGI %d bSPreamble %d bSTBC %d bLDPC %d NDP_sound %d\n", PMacTxInfo.bSGI, PMacTxInfo.bSPreamble, PMacTxInfo.bSTBC, PMacTxInfo.bLDPC, PMacTxInfo.NDP_sound); + DbgPrint("TXSC %d BandWidth %d PacketPeriod %d PacketCount %d PacketLength %d PacketPattern %d\n", PMacTxInfo.TX_SC, PMacTxInfo.BandWidth, PMacTxInfo.PacketPeriod, PMacTxInfo.PacketCount, PMacTxInfo.PacketLength, PMacTxInfo.PacketPattern); +#if 0 + PRINT_DATA("LSIG ", PMacTxInfo.LSIG, 3); + PRINT_DATA("HT_SIG", PMacTxInfo.HT_SIG, 6); + PRINT_DATA("VHT_SIG_A", PMacTxInfo.VHT_SIG_A, 6); + PRINT_DATA("VHT_SIG_B", PMacTxInfo.VHT_SIG_B, 4); + DbgPrint("VHT_SIG_B_CRC %x\n", PMacTxInfo.VHT_SIG_B_CRC); + PRINT_DATA("VHT_Delimiter", PMacTxInfo.VHT_Delimiter, 4); + + PRINT_DATA("Src Address", Adapter->mac_addr, 6); + PRINT_DATA("Dest Address", PMacTxInfo.MacAddress, 6); +#endif + + if (PMacTxInfo.bEnPMacTx == FALSE) { + if (PMacTxInfo.Mode == CONTINUOUS_TX) { + PHY_SetBBReg(Adapter, 0xb04, 0xf, 2); /* TX Stop*/ + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) + mpt_StopCckContTx(Adapter); + else + mpt_StopOfdmContTx(Adapter); + } else if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) { + u4bTmp = PHY_QueryBBReg(Adapter, 0xf50, bMaskLWord); + PHY_SetBBReg(Adapter, 0xb1c, bMaskLWord, u4bTmp+50); + PHY_SetBBReg(Adapter, 0xb04, 0xf, 2); /*TX Stop*/ + } else + PHY_SetBBReg(Adapter, 0xb04, 0xf, 2); /* TX Stop*/ + + if (PMacTxInfo.Mode == OFDM_Single_Tone_TX) { + /* Stop HW TX -> Stop Continuous TX -> Stop RF Setting*/ + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) + mpt_StopCckContTx(Adapter); + else + mpt_StopOfdmContTx(Adapter); + + mpt_SetSingleTone_8814A(Adapter, FALSE, TRUE); + } + + return; + } + + if (PMacTxInfo.Mode == CONTINUOUS_TX) { + PMacTxInfo.PacketCount = 1; + + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) + mpt_StartCckContTx(Adapter); + else + mpt_StartOfdmContTx(Adapter); + } else if (PMacTxInfo.Mode == OFDM_Single_Tone_TX) { + /* Continuous TX -> HW TX -> RF Setting */ + PMacTxInfo.PacketCount = 1; + + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) + mpt_StartCckContTx(Adapter); + else + mpt_StartOfdmContTx(Adapter); + } else if (PMacTxInfo.Mode == PACKETS_TX) { + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE) && PMacTxInfo.PacketCount == 0) + PMacTxInfo.PacketCount = 0xffff; + } + + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) { + /* 0xb1c[0:15] TX packet count 0xb1C[31:16] SFD*/ + u4bTmp = PMacTxInfo.PacketCount|(PMacTxInfo.SFD << 16); + PHY_SetBBReg(Adapter, 0xb1c, bMaskDWord, u4bTmp); + /* 0xb40 7:0 SIGNAL 15:8 SERVICE 31:16 LENGTH*/ + u4bTmp = PMacTxInfo.SignalField|(PMacTxInfo.ServiceField << 8)|(PMacTxInfo.LENGTH << 16); + PHY_SetBBReg(Adapter, 0xb40, bMaskDWord, u4bTmp); + u4bTmp = PMacTxInfo.CRC16[0] | (PMacTxInfo.CRC16[1] << 8); + PHY_SetBBReg(Adapter, 0xb44, bMaskLWord, u4bTmp); + + if (PMacTxInfo.bSPreamble) + PHY_SetBBReg(Adapter, 0xb0c, BIT27, 0); + else + PHY_SetBBReg(Adapter, 0xb0c, BIT27, 1); + } else { + PHY_SetBBReg(Adapter, 0xb18, 0xfffff, PMacTxInfo.PacketCount); + + u4bTmp = PMacTxInfo.LSIG[0]|((PMacTxInfo.LSIG[1]) << 8)|((PMacTxInfo.LSIG[2]) << 16)|((PMacTxInfo.PacketPattern) << 24); + PHY_SetBBReg(Adapter, 0xb08, bMaskDWord, u4bTmp); /* Set 0xb08[23:0] = LSIG, 0xb08[31:24] = Data init octet*/ + + if (PMacTxInfo.PacketPattern == 0x12) + u4bTmp = 0x3000000; + else + u4bTmp = 0; + } + + if (IS_MPT_HT_RATE(PMacTxInfo.TX_RATE)) { + u4bTmp |= PMacTxInfo.HT_SIG[0]|((PMacTxInfo.HT_SIG[1]) << 8)|((PMacTxInfo.HT_SIG[2]) << 16); + PHY_SetBBReg(Adapter, 0xb0c, bMaskDWord, u4bTmp); + u4bTmp = PMacTxInfo.HT_SIG[3]|((PMacTxInfo.HT_SIG[4]) << 8)|((PMacTxInfo.HT_SIG[5]) << 16); + PHY_SetBBReg(Adapter, 0xb10, 0xffffff, u4bTmp); + } else if (IS_MPT_VHT_RATE(PMacTxInfo.TX_RATE)) { + u4bTmp |= PMacTxInfo.VHT_SIG_A[0]|((PMacTxInfo.VHT_SIG_A[1]) << 8)|((PMacTxInfo.VHT_SIG_A[2]) << 16); + PHY_SetBBReg(Adapter, 0xb0c, bMaskDWord, u4bTmp); + u4bTmp = PMacTxInfo.VHT_SIG_A[3]|((PMacTxInfo.VHT_SIG_A[4]) << 8)|((PMacTxInfo.VHT_SIG_A[5]) << 16); + PHY_SetBBReg(Adapter, 0xb10, 0xffffff, u4bTmp); + + _rtw_memcpy(&u4bTmp, PMacTxInfo.VHT_SIG_B, 4); + PHY_SetBBReg(Adapter, 0xb14, bMaskDWord, u4bTmp); + } + + if (IS_MPT_VHT_RATE(PMacTxInfo.TX_RATE)) { + u4bTmp = (PMacTxInfo.VHT_SIG_B_CRC << 24)|PMacTxInfo.PacketPeriod; /* for TX interval */ + PHY_SetBBReg(Adapter, 0xb20, bMaskDWord, u4bTmp); + + _rtw_memcpy(&u4bTmp, PMacTxInfo.VHT_Delimiter, 4); + PHY_SetBBReg(Adapter, 0xb24, bMaskDWord, u4bTmp); + + /* 0xb28 - 0xb34 24 byte Probe Request MAC Header*/ + /*& Duration & Frame control*/ + PHY_SetBBReg(Adapter, 0xb28, bMaskDWord, 0x00000040); + + /* Address1 [0:3]*/ + u4bTmp = PMacTxInfo.MacAddress[0]|(PMacTxInfo.MacAddress[1] << 8)|(PMacTxInfo.MacAddress[2] << 16)|(PMacTxInfo.MacAddress[3] << 24); + PHY_SetBBReg(Adapter, 0xb2C, bMaskDWord, u4bTmp); + + /* Address3 [3:0]*/ + PHY_SetBBReg(Adapter, 0xb38, bMaskDWord, u4bTmp); + + /* Address2[0:1] & Address1 [5:4]*/ + u4bTmp = PMacTxInfo.MacAddress[4]|(PMacTxInfo.MacAddress[5] << 8)|(Adapter->mac_addr[0] << 16)|(Adapter->mac_addr[1] << 24); + PHY_SetBBReg(Adapter, 0xb30, bMaskDWord, u4bTmp); + + /* Address2 [5:2]*/ + u4bTmp = Adapter->mac_addr[2]|(Adapter->mac_addr[3] << 8)|(Adapter->mac_addr[4] << 16)|(Adapter->mac_addr[5] << 24); + PHY_SetBBReg(Adapter, 0xb34, bMaskDWord, u4bTmp); + + /* Sequence Control & Address3 [5:4]*/ + /*u4bTmp = PMacTxInfo.MacAddress[4]|(PMacTxInfo.MacAddress[5] << 8) ;*/ + /*PHY_SetBBReg(Adapter, 0xb38, bMaskDWord, u4bTmp);*/ + } else { + PHY_SetBBReg(Adapter, 0xb20, bMaskDWord, PMacTxInfo.PacketPeriod); /* for TX interval*/ + /* & Duration & Frame control */ + PHY_SetBBReg(Adapter, 0xb24, bMaskDWord, 0x00000040); + + /* 0xb24 - 0xb38 24 byte Probe Request MAC Header*/ + /* Address1 [0:3]*/ + u4bTmp = PMacTxInfo.MacAddress[0]|(PMacTxInfo.MacAddress[1] << 8)|(PMacTxInfo.MacAddress[2] << 16)|(PMacTxInfo.MacAddress[3] << 24); + PHY_SetBBReg(Adapter, 0xb28, bMaskDWord, u4bTmp); + + /* Address3 [3:0]*/ + PHY_SetBBReg(Adapter, 0xb34, bMaskDWord, u4bTmp); + + /* Address2[0:1] & Address1 [5:4]*/ + u4bTmp = PMacTxInfo.MacAddress[4]|(PMacTxInfo.MacAddress[5] << 8)|(Adapter->mac_addr[0] << 16)|(Adapter->mac_addr[1] << 24); + PHY_SetBBReg(Adapter, 0xb2c, bMaskDWord, u4bTmp); + + /* Address2 [5:2] */ + u4bTmp = Adapter->mac_addr[2]|(Adapter->mac_addr[3] << 8)|(Adapter->mac_addr[4] << 16)|(Adapter->mac_addr[5] << 24); + PHY_SetBBReg(Adapter, 0xb30, bMaskDWord, u4bTmp); + + /* Sequence Control & Address3 [5:4]*/ + u4bTmp = PMacTxInfo.MacAddress[4] | (PMacTxInfo.MacAddress[5] << 8); + PHY_SetBBReg(Adapter, 0xb38, bMaskDWord, u4bTmp); + } + + PHY_SetBBReg(Adapter, 0xb48, bMaskByte3, PMacTxInfo.TX_RATE_HEX); + + /* 0xb4c 3:0 TXSC 5:4 BW 7:6 m_STBC 8 NDP_Sound*/ + u4bTmp = (PMacTxInfo.TX_SC)|((PMacTxInfo.BandWidth) << 4)|((PMacTxInfo.m_STBC - 1) << 6)|((PMacTxInfo.NDP_sound) << 8); + PHY_SetBBReg(Adapter, 0xb4c, 0x1ff, u4bTmp); + + if (IS_HARDWARE_TYPE_8814A(Adapter) || IS_HARDWARE_TYPE_8822B(Adapter)) { + u4Byte offset = 0xb44; + + if (IS_MPT_OFDM_RATE(PMacTxInfo.TX_RATE)) + PHY_SetBBReg(Adapter, offset, 0xc0000000, 0); + else if (IS_MPT_HT_RATE(PMacTxInfo.TX_RATE)) + PHY_SetBBReg(Adapter, offset, 0xc0000000, 1); + else if (IS_MPT_VHT_RATE(PMacTxInfo.TX_RATE)) + PHY_SetBBReg(Adapter, offset, 0xc0000000, 2); + } + + PHY_SetBBReg(Adapter, 0xb00, BIT8, 1); /* Turn on PMAC*/ +/* //PHY_SetBBReg(Adapter, 0xb04, 0xf, 2); //TX Stop*/ + if (IS_MPT_CCK_RATE(PMacTxInfo.TX_RATE)) { + PHY_SetBBReg(Adapter, 0xb04, 0xf, 8); /*TX CCK ON*/ + PHY_SetBBReg(Adapter, 0xA84, BIT31, 0); + } else + PHY_SetBBReg(Adapter, 0xb04, 0xf, 4); /* TX Ofdm ON */ + + if (PMacTxInfo.Mode == OFDM_Single_Tone_TX) + mpt_SetSingleTone_8814A(Adapter, TRUE, TRUE); + +} +#endif /* CONFIG_MP_VHT_HW_TX_MODE */ + +#endif /* CONFIG_MP_INCLUDE*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_phy.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_phy.c new file mode 100644 index 00000000..feb619ed --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/hal_phy.c @@ -0,0 +1,285 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _HAL_PHY_C_ + +#include + +//================================================================================ +// Constant. +//================================================================================ +// 2008/11/20 MH For Debug only, RF +static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG]; + +/** +* Function: PHY_CalculateBitShift +* +* OverView: Get shifted position of the BitMask +* +* Input: +* u4Byte BitMask, +* +* Output: none +* Return: u4Byte Return the shift bit bit position of the mask +*/ +u32 +PHY_CalculateBitShift( + u32 BitMask + ) +{ + u32 i; + + for(i=0; i<=31; i++) + { + if ( ((BitMask>>i) & 0x1 ) == 1) + break; + } + + return (i); +} + + +// +// ==> RF shadow Operation API Code Section!!! +// +/*----------------------------------------------------------------------------- + * Function: PHY_RFShadowRead + * PHY_RFShadowWrite + * PHY_RFShadowCompare + * PHY_RFShadowRecorver + * PHY_RFShadowCompareAll + * PHY_RFShadowRecorverAll + * PHY_RFShadowCompareFlagSet + * PHY_RFShadowRecorverFlagSet + * + * Overview: When we set RF register, we must write shadow at first. + * When we are running, we must compare shadow abd locate error addr. + * Decide to recorver or not. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/20/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u32 +PHY_RFShadowRead( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset) +{ + return RF_Shadow[eRFPath][Offset].Value; + +} /* PHY_RFShadowRead */ + + +VOID +PHY_RFShadowWrite( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u32 Data) +{ + RF_Shadow[eRFPath][Offset].Value = (Data & bRFRegOffsetMask); + RF_Shadow[eRFPath][Offset].Driver_Write = _TRUE; + +} /* PHY_RFShadowWrite */ + + +BOOLEAN +PHY_RFShadowCompare( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset) +{ + u32 reg; + // Check if we need to check the register + if (RF_Shadow[eRFPath][Offset].Compare == _TRUE) + { + reg = rtw_hal_read_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask); + // Compare shadow and real rf register for 20bits!! + if (RF_Shadow[eRFPath][Offset].Value != reg) + { + // Locate error position. + RF_Shadow[eRFPath][Offset].ErrorOrNot = _TRUE; + //RT_TRACE(COMP_INIT, DBG_LOUD, + //("PHY_RFShadowCompare RF-%d Addr%02lx Err = %05lx\n", + //eRFPath, Offset, reg)); + } + return RF_Shadow[eRFPath][Offset].ErrorOrNot ; + } + return _FALSE; +} /* PHY_RFShadowCompare */ + + +VOID +PHY_RFShadowRecorver( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset) +{ + // Check if the address is error + if (RF_Shadow[eRFPath][Offset].ErrorOrNot == _TRUE) + { + // Check if we need to recorver the register. + if (RF_Shadow[eRFPath][Offset].Recorver == _TRUE) + { + rtw_hal_write_rfreg(Adapter, eRFPath, Offset, bRFRegOffsetMask, + RF_Shadow[eRFPath][Offset].Value); + //RT_TRACE(COMP_INIT, DBG_LOUD, + //("PHY_RFShadowRecorver RF-%d Addr%02lx=%05lx", + //eRFPath, Offset, RF_Shadow[eRFPath][Offset].Value)); + } + } + +} /* PHY_RFShadowRecorver */ + + +VOID +PHY_RFShadowCompareAll( + IN PADAPTER Adapter) +{ + u8 eRFPath = 0 ; + u32 Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter); + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset < maxReg; Offset++) + { + PHY_RFShadowCompare(Adapter, eRFPath, Offset); + } + } + +} /* PHY_RFShadowCompareAll */ + + +VOID +PHY_RFShadowRecorverAll( + IN PADAPTER Adapter) +{ + u8 eRFPath =0; + u32 Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter); + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset < maxReg; Offset++) + { + PHY_RFShadowRecorver(Adapter, eRFPath, Offset); + } + } + +} /* PHY_RFShadowRecorverAll */ + + +VOID +PHY_RFShadowCompareFlagSet( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u8 Type) +{ + // Set True or False!!! + RF_Shadow[eRFPath][Offset].Compare = Type; + +} /* PHY_RFShadowCompareFlagSet */ + + +VOID +PHY_RFShadowRecorverFlagSet( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u8 Type) +{ + // Set True or False!!! + RF_Shadow[eRFPath][Offset].Recorver= Type; + +} /* PHY_RFShadowRecorverFlagSet */ + + +VOID +PHY_RFShadowCompareFlagSetAll( + IN PADAPTER Adapter) +{ + u8 eRFPath = 0; + u32 Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter); + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset < maxReg; Offset++) + { + // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! + if (Offset != 0x26 && Offset != 0x27) + PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _FALSE); + else + PHY_RFShadowCompareFlagSet(Adapter, eRFPath, Offset, _TRUE); + } + } + +} /* PHY_RFShadowCompareFlagSetAll */ + + +VOID +PHY_RFShadowRecorverFlagSetAll( + IN PADAPTER Adapter) +{ + u8 eRFPath = 0; + u32 Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter); + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset < maxReg; Offset++) + { + // 2008/11/20 MH For S3S4 test, we only check reg 26/27 now!!!! + if (Offset != 0x26 && Offset != 0x27) + PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _FALSE); + else + PHY_RFShadowRecorverFlagSet(Adapter, eRFPath, Offset, _TRUE); + } + } + +} /* PHY_RFShadowCompareFlagSetAll */ + +VOID +PHY_RFShadowRefresh( + IN PADAPTER Adapter) +{ + u8 eRFPath = 0; + u32 Offset = 0, maxReg= GET_RF6052_REAL_MAX_REG(Adapter); + + for (eRFPath = 0; eRFPath < RF6052_MAX_PATH; eRFPath++) + { + for (Offset = 0; Offset < maxReg; Offset++) + { + RF_Shadow[eRFPath][Offset].Value = 0; + RF_Shadow[eRFPath][Offset].Compare = _FALSE; + RF_Shadow[eRFPath][Offset].Recorver = _FALSE; + RF_Shadow[eRFPath][Offset].ErrorOrNot = _FALSE; + RF_Shadow[eRFPath][Offset].Driver_Write = _FALSE; + } + } + +} /* PHY_RFShadowRead */ + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/led/hal_sdio_led.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/led/hal_sdio_led.c new file mode 100644 index 00000000..2f6d49c0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/led/hal_sdio_led.c @@ -0,0 +1,2418 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + +// +// Description: +// Implementation of LED blinking behavior. +// It toggle off LED and schedule corresponding timer if necessary. +// +void +SwLedBlink( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + // Determine if we shall change LED state again. + pLed->BlinkTimes--; + switch(pLed->CurrLedState) + { + + case LED_BLINK_NORMAL: + if(pLed->BlinkTimes == 0) + { + bStopBlinking = _TRUE; + } + break; + + case LED_BLINK_StartToBlink: + if( check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) ) + { + bStopBlinking = _TRUE; + } + if( check_fwstate(pmlmepriv, _FW_LINKED) && + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ) + { + bStopBlinking = _TRUE; + } + else if(pLed->BlinkTimes == 0) + { + bStopBlinking = _TRUE; + } + break; + + case LED_BLINK_WPS: + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + break; + + + default: + bStopBlinking = _TRUE; + break; + + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (pLed->bLedOn == _FALSE)) + { + SwLedOn(padapter, pLed); + } + else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) && pLed->bLedOn == _TRUE) + { + SwLedOff(padapter, pLed); + } + + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + // Assign LED state to toggle. + if( pLed->BlinkingLedState == RTW_LED_ON ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + // Schedule a timer to toggle LED state. + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_SLOWLY: + case LED_BLINK_StartToBlink: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + + case LED_BLINK_WPS: + { + if( pLed->BlinkingLedState == RTW_LED_ON ) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + else + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + break; + + default: + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + break; + } + } +} + +void +SwLedBlink1( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PLED_SDIO pLed1 = &(ledpriv->SwLed1); + u8 bStopBlinking = _FALSE; + + if(pHalData->CustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + + if(pHalData->CustomerID == RT_CID_DEFAULT) + { + if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + if(!pLed1->bSWLedCtrl) + { + SwLedOn(padapter, pLed1); + pLed1->bSWLedCtrl = _TRUE; + } + else if(!pLed1->bLedOn) + SwLedOn(padapter, pLed1); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn on pLed1\n")); + } + else + { + if(!pLed1->bSWLedCtrl) + { + SwLedOff(padapter, pLed1); + pLed1->bSWLedCtrl = _TRUE; + } + else if(pLed1->bLedOn) + SwLedOff(padapter, pLed1); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn off pLed1\n")); + } + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_BLINK_NORMAL: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + break; + + case LED_BLINK_SCAN: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_TXRX: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + break; + + case LED_BLINK_WPS_STOP: //WPS success + if(pLed->BlinkingLedState == RTW_LED_ON) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + bStopBlinking = _FALSE; + } + else + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedWPSBlinkInProgress = _FALSE; + } + break; + + default: + break; + } + +} + +void +SwLedBlink2( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SCAN: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_TXRX: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState)); + + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + default: + break; + } + +} + +void +SwLedBlink3( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + if(pLed->CurrLedState != LED_BLINK_WPS_STOP) + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SCAN: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( !pLed->bLedOn ) + SwLedOn(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedOn ) + SwLedOff(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_TXRX: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + + if( !pLed->bLedOn ) + SwLedOn(padapter, pLed); + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedOn ) + SwLedOff(padapter, pLed); + + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + break; + + case LED_BLINK_WPS_STOP: //WPS success + if(pLed->BlinkingLedState == RTW_LED_ON) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + bStopBlinking = _FALSE; + } + else + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on ) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + pLed->bLedWPSBlinkInProgress = _FALSE; + } + break; + + + default: + break; + } + +} + + +void +SwLedBlink4( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PLED_SDIO pLed1 = &(ledpriv->SwLed1); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) + { + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + SwLedOff(padapter, pLed1); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_BLINK_StartToBlink: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_BLINK_SCAN: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _FALSE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = _FALSE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_TXRX: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_BLINK_WPS_STOP: //WPS authentication fail + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + break; + + case LED_BLINK_WPS_STOP_OVERLAP: //WPS session overlap + pLed->BlinkTimes--; + if(pLed->BlinkTimes == 0) + { + if(pLed->bLedOn) + { + pLed->BlinkTimes = 1; + } + else + { + bStopBlinking = _TRUE; + } + } + + if(bStopBlinking) + { + pLed->BlinkTimes = 10; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState)); + + +} + +void +SwLedBlink5( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SCAN: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if(pLed->bLedOn) + SwLedOff(padapter, pLed); + } + else + { pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if(!pLed->bLedOn) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + + pLed->bLedScanBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + } + break; + + + case LED_BLINK_TXRX: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = _TRUE; + } + + if(bStopBlinking) + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if(pLed->bLedOn) + SwLedOff(padapter, pLed); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if(!pLed->bLedOn) + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + + pLed->bLedBlinkInProgress = _FALSE; + } + else + { + if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) + { + SwLedOff(padapter, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + } + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState)); + + +} + +void +SwLedBlink6( + PLED_SDIO pLed + ) +{ + _adapter *padapter = pLed->padapter; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 bStopBlinking = _FALSE; + + // Change LED according to BlinkingLedState specified. + if( pLed->BlinkingLedState == RTW_LED_ON ) + { + SwLedOn(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes)); + } + else + { + SwLedOff(padapter, pLed); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes)); + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("<==== blink6\n")); +} + +// +// Description: +// Handler function of LED Blinking. +// We dispatch acture LED blink action according to LedStrategy. +// +void BlinkHandler(PLED_SDIO pLed) +{ + _adapter *padapter = pLed->padapter; + struct led_priv *ledpriv = &(padapter->ledpriv); + + //DBG_871X("%s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) { + DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n" + , __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False"); + + return; + } + + switch(ledpriv->LedStrategy) + { + case SW_LED_MODE0: + SwLedBlink(pLed); + break; + + case SW_LED_MODE1: + SwLedBlink1(pLed); + break; + + case SW_LED_MODE2: + SwLedBlink2(pLed); + break; + + case SW_LED_MODE3: + SwLedBlink3(pLed); + break; + + case SW_LED_MODE4: + SwLedBlink4(pLed); + break; + + case SW_LED_MODE5: + SwLedBlink5(pLed); + break; + + case SW_LED_MODE6: + SwLedBlink6(pLed); + break; + + default: + //RT_TRACE(COMP_LED, DBG_LOUD, ("BlinkWorkItemCallback 0x%x \n", pHalData->LedStrategy)); + //SwLedBlink(pLed); + break; + } +} + +// +// Description: +// Callback function of LED BlinkTimer, +// it just schedules to corresponding BlinkWorkItem/led_blink_hdl +// +void BlinkTimerCallback(void *data) +{ + PLED_SDIO pLed = (PLED_SDIO)data; + _adapter *padapter = pLed->padapter; + + //DBG_871X("%s\n", __FUNCTION__); + + if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) { + /*DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n" + , __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False" );*/ + return; + } + + #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD + rtw_led_blink_cmd(padapter, pLed); + #else + _set_workitem(&(pLed->BlinkWorkItem)); + #endif +} + +// +// Description: +// Callback function of LED BlinkWorkItem. +// We dispatch acture LED blink action according to LedStrategy. +// +void BlinkWorkItemCallback(_workitem *work) +{ + PLED_SDIO pLed = container_of(work, LED_SDIO, BlinkWorkItem); + BlinkHandler(pLed); +} + +static void +SwLedControlMode0( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + PLED_SDIO pLed = &(ledpriv->SwLed1); + + // Decide led state + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + break; + + case LED_CTL_START_TO_LINK: + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_StartToBlink; + pLed->BlinkTimes = 24; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->CurrLedState = LED_BLINK_StartToBlink; + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_NO_LINK: + pLed->CurrLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress == _FALSE ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + if(pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + SwLedOff(padapter, pLed); + break; + + case LED_CTL_START_WPS: + if( pLed->bLedBlinkInProgress == _FALSE || pLed->CurrLedState == RTW_LED_ON) + { + pLed->bLedBlinkInProgress = _TRUE; + + pLed->CurrLedState = LED_BLINK_WPS; + pLed->BlinkTimes = 20; + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); + } + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedBlinkInProgress) + { + pLed->CurrLedState = RTW_LED_OFF; + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + break; + + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); + +} + + //ALPHA, added by chiyoko, 20090106 +static void +SwLedControlMode1( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + PLED_SDIO pLed = &(ledpriv->SwLed0); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + if(pHalData->CustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if( pLed->bLedNoLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + if( pLed->bLedLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SCAN; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_TXRX; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + + case LED_CTL_STOP_WPS: + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress == _TRUE ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + } + else + { + pLed->bLedWPSBlinkInProgress = _TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedNoLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + //Arcadyan/Sitecom , added by chiyoko, 20090216 +static void +SwLedControlMode2( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_SDIO pLed = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(pmlmepriv->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SCAN; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_TXRX; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS: + pLed->bLedWPSBlinkInProgress = _FALSE; + if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + else + { + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + pLed->bLedWPSBlinkInProgress = _FALSE; + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); +} + + //COREGA, added by chiyoko, 20090316 + static void + SwLedControlMode3( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_SDIO pLed = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(pmlmepriv->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SCAN; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_TXRX; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_LINK: + if(IS_LED_WPS_BLINKING(pLed)) + return; + + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + else + { + pLed->bLedWPSBlinkInProgress = _TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), 0); + } + + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState)); +} + + + //Edimax-Belkin, added by chiyoko, 20090413 +static void +SwLedControlMode4( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_SDIO pLed = &(ledpriv->SwLed0); + PLED_SDIO pLed1 = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_START_TO_LINK: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + + if( pLed->bLedStartToLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedNoLinkBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + + pLed->bLedStartToLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_StartToBlink; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + } + break; + + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + //LED1 settings + if(LedAction == LED_CTL_LINK) + { + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + } + + if( pLed->bLedNoLinkBlinkInProgress == _FALSE ) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + } + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SCAN; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_TXRX; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_START_WPS: //wait until xinpin finish + case LED_CTL_START_WPS_BOTTON: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = _FALSE; + _cancel_timer_ex(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = RTW_LED_OFF; + pLed1->CurrLedState = RTW_LED_OFF; + + if(pLed1->bLedOn) + _set_timer(&(pLed->BlinkTimer), 0); + } + + if(pLed->bLedWPSBlinkInProgress ==_FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == _TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if(pLed->bLedScanBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + pLed->bLedWPSBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = RTW_LED_OFF; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); + } + else + { + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + } + } + break; + + case LED_CTL_STOP_WPS: //WPS connect success + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + break; + + case LED_CTL_STOP_WPS_FAIL: //WPS authentication fail + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + //LED1 settings + if(pLed1->bLedWPSBlinkInProgress) + _cancel_timer_ex(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = _TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = RTW_LED_OFF; + else + pLed1->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + + break; + + case LED_CTL_STOP_WPS_FAIL_OVERLAP: //WPS session overlap + if(pLed->bLedWPSBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); + + //LED1 settings + if(pLed1->bLedWPSBlinkInProgress) + _cancel_timer_ex(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = _TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; + pLed1->BlinkTimes = 10; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = RTW_LED_OFF; + else + pLed1->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); + + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedNoLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = _FALSE; + } + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = _FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = _FALSE; + } + if( pLed->bLedStartToLinkBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedStartToLinkBlinkInProgress = _FALSE; + } + + if( pLed1->bLedWPSBlinkInProgress ) + { + _cancel_timer_ex(&(pLed1->BlinkTimer)); + pLed1->bLedWPSBlinkInProgress = _FALSE; + } + + pLed1->BlinkingLedState = LED_UNKNOWN; + SwLedOff(padapter, pLed); + SwLedOff(padapter, pLed1); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + + + //Sercomm-Belkin, added by chiyoko, 20090415 +static void +SwLedControlMode5( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PLED_SDIO pLed = &(ledpriv->SwLed0); + + if(pHalData->CustomerID == RT_CID_819x_CAMEO) + pLed = &(ledpriv->SwLed1); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_NO_LINK: + case LED_CTL_LINK: //solid blue + pLed->CurrLedState = RTW_LED_ON; + pLed->BlinkingLedState = RTW_LED_ON; + + _set_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_SITE_SURVEY: + if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)) + ; + else if(pLed->bLedScanBlinkInProgress ==_FALSE) + { + if(pLed->bLedBlinkInProgress ==_TRUE) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + pLed->bLedScanBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_SCAN; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==_FALSE) + { + if(pLed->CurrLedState == LED_BLINK_SCAN) + { + return; + } + pLed->bLedBlinkInProgress = _TRUE; + pLed->CurrLedState = LED_BLINK_TXRX; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = RTW_LED_OFF; + else + pLed->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = RTW_LED_OFF; + pLed->BlinkingLedState = RTW_LED_OFF; + + if( pLed->bLedBlinkInProgress) + { + _cancel_timer_ex(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = _FALSE; + } + + SwLedOff(padapter, pLed); + break; + + default: + break; + + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState)); +} + + //WNC-Corega, added by chiyoko, 20090902 +static void +SwLedControlMode6( + _adapter *padapter, + LED_CTL_MODE LedAction +) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PLED_SDIO pLed0 = &(ledpriv->SwLed0); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + _cancel_timer_ex(&(pLed0->BlinkTimer)); + pLed0->CurrLedState = RTW_LED_ON; + pLed0->BlinkingLedState = RTW_LED_ON; + _set_timer(&(pLed0->BlinkTimer), 0); + break; + + case LED_CTL_POWER_OFF: + SwLedOff(padapter, pLed0); + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("ledcontrol 6 Led %d\n", pLed0->CurrLedState)); +} + +void +LedControlSDIO( + _adapter *padapter, + LED_CTL_MODE LedAction + ) +{ + struct led_priv *ledpriv = &(padapter->ledpriv); + + #if(MP_DRIVER == 1) + if (padapter->registrypriv.mp_mode == 1) + return; +#endif + + if (RTW_CANNOT_RUN(padapter) || (!rtw_is_hw_init_completed(padapter))) { + /*DBG_871X("%s bDriverStopped:%s, bSurpriseRemoved:%s\n" + , __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False");*/ + return; + } + + if( ledpriv->bRegUseLed == _FALSE) + return; + + //if(priv->bInHctTest) + // return; + +#ifdef CONFIG_CONCURRENT_MODE + // Only do led action for PRIMARY_ADAPTER + if (padapter->adapter_type != PRIMARY_ADAPTER) + return; +#endif + + if( (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && + adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) && + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || + LedAction == LED_CTL_SITE_SURVEY || + LedAction == LED_CTL_LINK || + LedAction == LED_CTL_NO_LINK || + LedAction == LED_CTL_POWER_ON) ) + { + return; + } + + switch(ledpriv->LedStrategy) + { + case SW_LED_MODE0: + SwLedControlMode0(padapter, LedAction); + break; + + case SW_LED_MODE1: + SwLedControlMode1(padapter, LedAction); + break; + case SW_LED_MODE2: + SwLedControlMode2(padapter, LedAction); + break; + + case SW_LED_MODE3: + SwLedControlMode3(padapter, LedAction); + break; + + case SW_LED_MODE4: + SwLedControlMode4(padapter, LedAction); + break; + + case SW_LED_MODE5: + SwLedControlMode5(padapter, LedAction); + break; + + case SW_LED_MODE6: + SwLedControlMode6(padapter, LedAction); + break; + + default: + break; + } + + RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy,LedAction)); +} + +// +// Description: +// Reset status of LED_871x object. +// +void ResetLedStatus(PLED_SDIO pLed) { + + pLed->CurrLedState = RTW_LED_OFF; // Current LED state. + pLed->bLedOn = _FALSE; // true if LED is ON, false if LED is OFF. + + pLed->bLedBlinkInProgress = _FALSE; // true if it is blinking, false o.w.. + pLed->bLedWPSBlinkInProgress = _FALSE; + + pLed->BlinkTimes = 0; // Number of times to toggle led state for blinking. + pLed->BlinkingLedState = LED_UNKNOWN; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. + + pLed->bLedNoLinkBlinkInProgress = _FALSE; + pLed->bLedLinkBlinkInProgress = _FALSE; + pLed->bLedStartToLinkBlinkInProgress = _FALSE; + pLed->bLedScanBlinkInProgress = _FALSE; +} + + // +// Description: +// Initialize an LED_871x object. +// +void +InitLed( + _adapter *padapter, + PLED_SDIO pLed, + LED_PIN LedPin + ) +{ + pLed->padapter = padapter; + pLed->LedPin = LedPin; + + ResetLedStatus(pLed); + + _init_timer(&(pLed->BlinkTimer), padapter->pnetdev, BlinkTimerCallback, pLed); + + _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed); +} + + +// +// Description: +// DeInitialize an LED_871x object. +// +void +DeInitLed( + PLED_SDIO pLed + ) +{ + _cancel_workitem_sync(&(pLed->BlinkWorkItem)); + _cancel_timer_ex(&(pLed->BlinkTimer)); + ResetLedStatus(pLed); +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halhwimg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halhwimg.h new file mode 100644 index 00000000..108f7150 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halhwimg.h @@ -0,0 +1,123 @@ +#pragma once +#ifndef __INC_HW_IMG_H +#define __INC_HW_IMG_H + +// +// 2011/03/15 MH Add for different IC HW image file selection. code size consideration. +// +#if RT_PLATFORM == PLATFORM_LINUX + + #if (DEV_BUS_TYPE == RT_PCI_INTERFACE) + // For 92C + #define RTL8192CE_HWIMG_SUPPORT 1 + #define RTL8192CE_TEST_HWIMG_SUPPORT 0 + #define RTL8192CU_HWIMG_SUPPORT 0 + #define RTL8192CU_TEST_HWIMG_SUPPORT 0 + + // For 92D + #define RTL8192DE_HWIMG_SUPPORT 1 + #define RTL8192DE_TEST_HWIMG_SUPPORT 0 + #define RTL8192DU_HWIMG_SUPPORT 0 + #define RTL8192DU_TEST_HWIMG_SUPPORT 0 + + // For 8723 + #define RTL8723E_HWIMG_SUPPORT 1 + #define RTL8723U_HWIMG_SUPPORT 0 + #define RTL8723S_HWIMG_SUPPORT 0 + + //For 88E + #define RTL8188EE_HWIMG_SUPPORT 0 + #define RTL8188EU_HWIMG_SUPPORT 0 + #define RTL8188ES_HWIMG_SUPPORT 0 + + #elif (DEV_BUS_TYPE == RT_USB_INTERFACE) + // For 92C + #define RTL8192CE_HWIMG_SUPPORT 0 + #define RTL8192CE_TEST_HWIMG_SUPPORT 0 + #define RTL8192CU_HWIMG_SUPPORT 1 + #define RTL8192CU_TEST_HWIMG_SUPPORT 0 + + //For 92D + #define RTL8192DE_HWIMG_SUPPORT 0 + #define RTL8192DE_TEST_HWIMG_SUPPORT 0 + #define RTL8192DU_HWIMG_SUPPORT 1 + #define RTL8192DU_TEST_HWIMG_SUPPORT 0 + + // For 8723 + #define RTL8723E_HWIMG_SUPPORT 0 + #define RTL8723U_HWIMG_SUPPORT 1 + #define RTL8723S_HWIMG_SUPPORT 0 + + //For 88E + #define RTL8188EE_HWIMG_SUPPORT 0 + #define RTL8188EU_HWIMG_SUPPORT 0 + #define RTL8188ES_HWIMG_SUPPORT 0 + + #elif (DEV_BUS_TYPE == RT_SDIO_INTERFACE) + // For 92C + #define RTL8192CE_HWIMG_SUPPORT 0 + #define RTL8192CE_TEST_HWIMG_SUPPORT 0 + #define RTL8192CU_HWIMG_SUPPORT 1 + #define RTL8192CU_TEST_HWIMG_SUPPORT 0 + + //For 92D + #define RTL8192DE_HWIMG_SUPPORT 0 + #define RTL8192DE_TEST_HWIMG_SUPPORT 0 + #define RTL8192DU_HWIMG_SUPPORT 1 + #define RTL8192DU_TEST_HWIMG_SUPPORT 0 + + // For 8723 + #define RTL8723E_HWIMG_SUPPORT 0 + #define RTL8723U_HWIMG_SUPPORT 0 + #define RTL8723S_HWIMG_SUPPORT 1 + + //For 88E + #define RTL8188EE_HWIMG_SUPPORT 0 + #define RTL8188EU_HWIMG_SUPPORT 0 + #define RTL8188ES_HWIMG_SUPPORT 0 + #endif + +#else // PLATFORM_WINDOWS & MacOSX + +//For 92C +#define RTL8192CE_HWIMG_SUPPORT 1 +#define RTL8192CE_TEST_HWIMG_SUPPORT 1 +#define RTL8192CU_HWIMG_SUPPORT 1 +#define RTL8192CU_TEST_HWIMG_SUPPORT 1 + +// For 92D +#define RTL8192DE_HWIMG_SUPPORT 1 +#define RTL8192DE_TEST_HWIMG_SUPPORT 1 +#define RTL8192DU_HWIMG_SUPPORT 1 +#define RTL8192DU_TEST_HWIMG_SUPPORT 1 + + #if defined(UNDER_CE) + // For 8723 + #define RTL8723E_HWIMG_SUPPORT 0 + #define RTL8723U_HWIMG_SUPPORT 0 + #define RTL8723S_HWIMG_SUPPORT 1 + + // For 88E + #define RTL8188EE_HWIMG_SUPPORT 0 + #define RTL8188EU_HWIMG_SUPPORT 0 + #define RTL8188ES_HWIMG_SUPPORT 0 + + #else + + // For 8723 + #define RTL8723E_HWIMG_SUPPORT 1 + //#define RTL_8723E_TEST_HWIMG_SUPPORT 1 + #define RTL8723U_HWIMG_SUPPORT 1 + //#define RTL_8723U_TEST_HWIMG_SUPPORT 1 + #define RTL8723S_HWIMG_SUPPORT 1 + //#define RTL_8723S_TEST_HWIMG_SUPPORT 1 + + //For 88E + #define RTL8188EE_HWIMG_SUPPORT 1 + #define RTL8188EU_HWIMG_SUPPORT 1 + #define RTL8188ES_HWIMG_SUPPORT 1 + #endif + +#endif + +#endif //__INC_HW_IMG_H diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.c new file mode 100644 index 00000000..f9d60710 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.c @@ -0,0 +1,2504 @@ +/****************************************************************************** + * + * 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" + +#ifndef index_mapping_NUM_88E + #define index_mapping_NUM_88E 15 +#endif + +//#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + +#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \ + do {\ + for(_offset = 0; _offset < _size; _offset++)\ + {\ + if(_deltaThermal < thermalThreshold[_direction][_offset])\ + {\ + if(_offset != 0)\ + _offset--;\ + break;\ + }\ + } \ + if(_offset >= _size)\ + _offset = _size-1;\ + } while(0) + + +void ConfigureTxpowerTrack( + IN PVOID pDM_VOID, + OUT PTXPWRTRACK_CFG pConfig + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if RTL8812A_SUPPORT +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + //if (IS_HARDWARE_TYPE_8812(pDM_Odm->Adapter)) + if(pDM_Odm->SupportICType==ODM_RTL8812) + ConfigureTxpowerTrack_8812A(pConfig); + //else +#endif +#endif + +#if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType== ODM_RTL8814A) + ConfigureTxpowerTrack_8814A(pConfig); +#endif + + +#if RTL8188E_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8188E) + ConfigureTxpowerTrack_8188E(pConfig); +#endif +} + +#if (RTL8192E_SUPPORT==1) +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_92E( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte ThermalValue = 0, delta, delta_IQK, delta_LCK, channel, is_decrease, rf_mimo_mode; + u1Byte ThermalValue_AVG_count = 0; + u1Byte OFDM_min_index = 10; //OFDM BB Swing should be less than +2.5dB, which is required by Arthur + s1Byte OFDM_index[2], index ; + u4Byte ThermalValue_AVG = 0, Reg0x18; + u4Byte i = 0, j = 0, rf; + s4Byte value32, CCK_index = 0, ele_A, ele_D, ele_C, X, Y; + prtl8192cd_priv priv = pDM_Odm->priv; + + rf_mimo_mode = pDM_Odm->RFType; + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("%s:%d rf_mimo_mode:%d\n", __FUNCTION__, __LINE__, rf_mimo_mode)); + +#ifdef MP_TEST + if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) { + channel = priv->pshare->working_channel; + if (priv->pshare->mp_txpwr_tracking == FALSE) + return; + } else +#endif + { + channel = (priv->pmib->dot11RFEntry.dot11channel); + } + + ThermalValue = (unsigned char)ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_RF_T_METER_92E, 0xfc00); //0x42: RF Reg[15:10] 88E + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther)); + + + switch (rf_mimo_mode) { + case MIMO_1T1R: + rf = 1; + break; + case MIMO_2T2R: + rf = 2; + break; + default: + rf = 2; + break; + } + + //Query OFDM path A default setting Bit[31:21] + ele_D = PHY_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskOFDM_D); + for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) { + if (ele_D == (OFDMSwingTable_92E[i] >> 22)) { + OFDM_index[0] = (unsigned char)i; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("PathA 0xC80[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[0])); + break; + } + } + + //Query OFDM path B default setting + if (rf_mimo_mode == MIMO_2T2R) { + ele_D = PHY_QueryBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskOFDM_D); + for (i = 0; i < OFDM_TABLE_SIZE_92E; i++) { + if (ele_D == (OFDMSwingTable_92E[i] >> 22)) { + OFDM_index[1] = (unsigned char)i; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("PathB 0xC88[31:22] = 0x%x, OFDM_index=%d\n", ele_D, OFDM_index[1])); + break; + } + } + } + + /* calculate average thermal meter */ + { + priv->pshare->ThermalValue_AVG_88XX[priv->pshare->ThermalValue_AVG_index_88XX] = ThermalValue; + priv->pshare->ThermalValue_AVG_index_88XX++; + if (priv->pshare->ThermalValue_AVG_index_88XX == AVG_THERMAL_NUM_88XX) + priv->pshare->ThermalValue_AVG_index_88XX = 0; + + for (i = 0; i < AVG_THERMAL_NUM_88XX; i++) { + if (priv->pshare->ThermalValue_AVG_88XX[i]) { + ThermalValue_AVG += priv->pshare->ThermalValue_AVG_88XX[i]; + ThermalValue_AVG_count++; + } + } + + if (ThermalValue_AVG_count) { + ThermalValue = (unsigned char)(ThermalValue_AVG / ThermalValue_AVG_count); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("AVG Thermal Meter = 0x%x \n", ThermalValue)); + } + } + + /* Initialize */ + if (!priv->pshare->ThermalValue) { + priv->pshare->ThermalValue = priv->pmib->dot11RFEntry.ther; + priv->pshare->ThermalValue_IQK = ThermalValue; + priv->pshare->ThermalValue_LCK = ThermalValue; + } + + if (ThermalValue != priv->pshare->ThermalValue) { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\n******** START POWER TRACKING ********\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther)); + + delta = RTL_ABS(ThermalValue, priv->pmib->dot11RFEntry.ther); + delta_IQK = RTL_ABS(ThermalValue, priv->pshare->ThermalValue_IQK); + delta_LCK = RTL_ABS(ThermalValue, priv->pshare->ThermalValue_LCK); + is_decrease = ((ThermalValue < priv->pmib->dot11RFEntry.ther) ? 1 : 0); + +#ifdef _TRACKING_TABLE_FILE + if (priv->pshare->rf_ft_var.pwr_track_file) { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Diff: (%s)%d ==> get index from table : %d)\n", (is_decrease?"-":"+"), delta, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0))); + + if (is_decrease) { + for (i = 0; i < rf; i++) { + OFDM_index[i] = priv->pshare->OFDM_index0[i] + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0); + OFDM_index[i] = ((OFDM_index[i] > (OFDM_TABLE_SIZE_92E- 1)) ? (OFDM_TABLE_SIZE_92E - 1) : OFDM_index[i]); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0))); + CCK_index = priv->pshare->CCK_index0 + get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1); + CCK_index = ((CCK_index > (CCK_TABLE_SIZE_92E - 1)) ? (CCK_TABLE_SIZE_92E - 1) : CCK_index); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> Decrese power ---> new CCK_INDEX:%d (%d + %d)\n", CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1))); + } + } else { + for (i = 0; i < rf; i++) { + OFDM_index[i] = priv->pshare->OFDM_index0[i] - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0); + OFDM_index[i] = ((OFDM_index[i] < OFDM_min_index) ? OFDM_min_index : OFDM_index[i]); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> Increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[i], priv->pshare->OFDM_index0[i], get_tx_tracking_index(priv, channel, i, delta, is_decrease, 0))); + CCK_index = priv->pshare->CCK_index0 - get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1); + CCK_index = ((CCK_index < 0 )? 0 : CCK_index); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> Increse power ---> new CCK_INDEX:%d (%d - %d)\n", CCK_index, priv->pshare->CCK_index0, get_tx_tracking_index(priv, channel, i, delta, is_decrease, 1))); + } + } + } +#endif //CFG_TRACKING_TABLE_FILE + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("OFDMSwingTable_92E[(unsigned int)OFDM_index[0]] = %x \n",OFDMSwingTable_92E[(unsigned int)OFDM_index[0]])); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("OFDMSwingTable_92E[(unsigned int)OFDM_index[1]] = %x \n",OFDMSwingTable_92E[(unsigned int)OFDM_index[1]])); + + //Adujst OFDM Ant_A according to IQK result + ele_D = (OFDMSwingTable_92E[(unsigned int)OFDM_index[0]] & 0xFFC00000) >> 22; + X = priv->pshare->RegE94; + Y = priv->pshare->RegE9C; + + if (X != 0) { + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + ele_A = ((X * ele_D) >> 8) & 0x000003FF; + + //new element C = element D x Y + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + ele_C = ((Y * ele_D) >> 8) & 0x000003FF; + + //wirte new elements A, C, D to regC80 and regC94, element B is always 0 + value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; + PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C&0x000003C0)>>6; + PHY_SetBBReg(priv, rOFDM0_XCTxAFE, bMaskH4Bits, value32); + + value32 = ((X * ele_D)>>7)&0x01; + PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(24), value32); + } else { + PHY_SetBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_92E[(unsigned int)OFDM_index[0]]); + PHY_SetBBReg(priv, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00); + PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(24), 0x00); + } + + set_CCK_swing_index(priv, CCK_index); + + if (rf == 2) { + ele_D = (OFDMSwingTable_92E[(unsigned int)OFDM_index[1]] & 0xFFC00000) >> 22; + X = priv->pshare->RegEB4; + Y = priv->pshare->RegEBC; + + if (X != 0) { + if ((X & 0x00000200) != 0) //consider minus + X = X | 0xFFFFFC00; + ele_A = ((X * ele_D) >> 8) & 0x000003FF; + + //new element C = element D x Y + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + ele_C = ((Y * ele_D) >> 8) & 0x00003FF; + + //wirte new elements A, C, D to regC88 and regC9C, element B is always 0 + value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; + PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C & 0x000003C0) >> 6; + PHY_SetBBReg(priv, rOFDM0_XDTxAFE, bMaskH4Bits, value32); + + value32 = ((X * ele_D) >> 7) & 0x01; + PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(28), value32); + } else { + PHY_SetBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_92E[(unsigned int)OFDM_index[1]]); + PHY_SetBBReg(priv, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); + PHY_SetBBReg(priv, rOFDM0_ECCAThreshold, BIT(28), 0x00); + } + + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xc80 = 0x%x \n", PHY_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord))); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("0xc88 = 0x%x \n", PHY_QueryBBReg(priv, rOFDM0_XBTxIQImbalance, bMaskDWord))); + + if (delta_IQK > 3) { + priv->pshare->ThermalValue_IQK = ThermalValue; +#ifdef MP_TEST + if (!(priv->pshare->rf_ft_var.mp_specific && (OPMODE & (WIFI_MP_CTX_BACKGROUND | WIFI_MP_CTX_PACKET)))) +#endif + PHY_IQCalibrate_8192E(pDM_Odm,false); + } + + if (delta_LCK > 8) { + RTL_W8(0x522, 0xff); + Reg0x18 = PHY_QueryRFReg(priv, RF_PATH_A, 0x18, bMask20Bits, 1); + PHY_SetRFReg(priv, RF_PATH_A, 0xB4, BIT(14), 1); + PHY_SetRFReg(priv, RF_PATH_A, 0x18, BIT(15), 1); + delay_ms(1); + PHY_SetRFReg(priv, RF_PATH_A, 0xB4, BIT(14), 0); + PHY_SetRFReg(priv, RF_PATH_A, 0x18, bMask20Bits, Reg0x18); + RTL_W8(0x522, 0x0); + priv->pshare->ThermalValue_LCK = ThermalValue; + } + } + + //update thermal meter value + priv->pshare->ThermalValue = ThermalValue; + for (i = 0 ; i < rf ; i++) + priv->pshare->OFDM_index[i] = OFDM_index[i]; + priv->pshare->CCK_index = CCK_index; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("\n******** END:%s() ********\n", __FUNCTION__)); +} +#endif + +#if (RTL8814A_SUPPORT ==1) + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries2( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, channel, is_increase; + u1Byte ThermalValue_AVG_count = 0, p = 0, i = 0; + u4Byte ThermalValue_AVG = 0, Reg0x18; + u4Byte BBSwingReg[4] = {rA_TxScale_Jaguar,rB_TxScale_Jaguar,rC_TxScale_Jaguar2,rD_TxScale_Jaguar2}; + s4Byte ele_D; + u4Byte BBswingIdx; + prtl8192cd_priv priv = pDM_Odm->priv; + TXPWRTRACK_CFG c; + BOOLEAN bTSSIenable = FALSE; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + //4 1. The following TWO tables decide the final index of OFDM/CCK swing table. + pu1Byte deltaSwingTableIdx_TUP_A = NULL, deltaSwingTableIdx_TDOWN_A = NULL; + pu1Byte deltaSwingTableIdx_TUP_B = NULL, deltaSwingTableIdx_TDOWN_B = NULL; + //for 8814 add by Yu Chen + pu1Byte deltaSwingTableIdx_TUP_C = NULL, deltaSwingTableIdx_TDOWN_C = NULL; + pu1Byte deltaSwingTableIdx_TUP_D = NULL, deltaSwingTableIdx_TDOWN_D = NULL; + +#ifdef MP_TEST + if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) { + channel = priv->pshare->working_channel; + if (priv->pshare->mp_txpwr_tracking == FALSE) + return; + } else +#endif + { + channel = (priv->pmib->dot11RFEntry.dot11channel); + } + + ConfigureTxpowerTrack(pDM_Odm, &c); + pRFCalibrateInfo->DefaultOfdmIndex = priv->pshare->OFDM_index0[ODM_RF_PATH_A]; + + (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A, + (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B); + + if(pDM_Odm->SupportICType & ODM_RTL8814A) // for 8814 path C & D + (*c.GetDeltaSwingTable8814only)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_C, (pu1Byte*)&deltaSwingTableIdx_TDOWN_C, + (pu1Byte*)&deltaSwingTableIdx_TUP_D, (pu1Byte*)&deltaSwingTableIdx_TDOWN_D); + + ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\nReadback Thermal Meter = 0x%x, pre thermal meter 0x%x, EEPROMthermalmeter 0x%x\n", ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue, priv->pmib->dot11RFEntry.ther)); + + /* Initialize */ + if (!pDM_Odm->RFCalibrateInfo.ThermalValue) { + pDM_Odm->RFCalibrateInfo.ThermalValue = priv->pmib->dot11RFEntry.ther; + } + + if (!pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) { + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = priv->pmib->dot11RFEntry.ther; + } + + if (!pDM_Odm->RFCalibrateInfo.ThermalValue_IQK) { + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = priv->pmib->dot11RFEntry.ther; + } + + bTSSIenable = (BOOLEAN)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, rRF_TxGainOffset, BIT7); // check TSSI enable + + //4 Query OFDM BB swing default setting Bit[31:21] + for(p = ODM_RF_PATH_A ; p < c.RfPathCount ; p++) + { + ele_D = ODM_GetBBReg(pDM_Odm, BBSwingReg[p], 0xffe00000); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("0x%x:0x%x ([31:21] = 0x%x)\n", BBSwingReg[p], ODM_GetBBReg(pDM_Odm, BBSwingReg[p], bMaskDWord), ele_D)); + + for (BBswingIdx = 0; BBswingIdx < TXSCALE_TABLE_SIZE; BBswingIdx++) {//4 + if (ele_D == TxScalingTable_Jaguar[BBswingIdx]) { + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = (u1Byte)BBswingIdx; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("OFDM_index[%d]=%d\n",p, pDM_Odm->RFCalibrateInfo.OFDM_index[p])); + break; + } + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("KfreeOffset[%d]=%d\n",p, pRFCalibrateInfo->KfreeOffset[p])); + + } + + /* calculate average thermal meter */ + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++; + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum) //Average times = c.AverageThermalNum + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; + + for(i = 0; i < c.AverageThermalNum; i++) + { + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) + { + ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]; + ThermalValue_AVG_count++; + } + } + + if(ThermalValue_AVG_count) //Calculate Average ThermalValue after average enough times + { + ThermalValue = (u1Byte)(ThermalValue_AVG / ThermalValue_AVG_count); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("AVG Thermal Meter = 0x%X, EEPROMthermalmeter = 0x%X\n", ThermalValue, priv->pmib->dot11RFEntry.ther)); + } + + //4 Calculate delta, delta_LCK, delta_IQK. + delta = RTL_ABS(ThermalValue, priv->pmib->dot11RFEntry.ther); + delta_LCK = RTL_ABS(ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue_LCK); + delta_IQK = RTL_ABS(ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue_IQK); + is_increase = ((ThermalValue < priv->pmib->dot11RFEntry.ther) ? 0 : 1); + + //4 if necessary, do LCK. + if (!(pDM_Odm->SupportICType & ODM_RTL8821)) { + if (delta_LCK > c.Threshold_IQK) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= Threshold_IQK(%d)\n", delta_LCK, c.Threshold_IQK)); + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; + if (c.PHY_LCCalibrate) + (*c.PHY_LCCalibrate)(pDM_Odm); + } + } + + if (delta_IQK > c.Threshold_IQK) + { + panic_printk("%s(%d)\n", __FUNCTION__, __LINE__); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_IQK(%d) >= Threshold_IQK(%d)\n", delta_IQK, c.Threshold_IQK)); + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; + if(c.DoIQK) + (*c.DoIQK)(pDM_Odm, TRUE, 0, 0); + } + + if(!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/ + return; + + //4 Do Power Tracking + + if(bTSSIenable == TRUE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter PURE TSSI MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, TSSI_MODE, p, 0); + } + else if (ThermalValue != pDM_Odm->RFCalibrateInfo.ThermalValue) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\n******** START POWER TRACKING ********\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue, priv->pmib->dot11RFEntry.ther)); + +#ifdef _TRACKING_TABLE_FILE + if (priv->pshare->rf_ft_var.pwr_track_file) + { + if (is_increase) // thermal is higher than base + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + switch(p) + { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_B[%d] = %d\n", delta, deltaSwingTableIdx_TUP_B[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_B[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_C[%d] = %d\n", delta, deltaSwingTableIdx_TUP_C[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_C[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_D[%d] = %d\n", delta, deltaSwingTableIdx_TUP_D[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_D[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_A[%d] = %d\n", delta, deltaSwingTableIdx_TUP_A[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_A[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + } + } + else // thermal is lower than base + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + switch(p) + { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_B[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_C[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_C[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_D[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_D[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_A[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_A[delta])); + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + } + } + + if (is_increase) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> increse power ---> \n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> decrese power --->\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0); + } + } +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\n******** END:%s() ********\n", __FUNCTION__)); + //update thermal meter value + pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue; + + } +} + +#elif(ODM_IC_11AC_SERIES_SUPPORT) +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + unsigned char ThermalValue = 0, delta, delta_LCK, channel, is_decrease; + unsigned char ThermalValue_AVG_count = 0; + unsigned int ThermalValue_AVG = 0, Reg0x18; + unsigned int BBSwingReg[4]={0xc1c,0xe1c,0x181c,0x1a1c}; + int ele_D, value32; + char OFDM_index[2], index; + unsigned int i = 0, j = 0, rf_path, max_rf_path =2 ,rf; + prtl8192cd_priv priv = pDM_Odm->priv; + unsigned char OFDM_min_index = 7; //OFDM BB Swing should be less than +2.5dB, which is required by Arthur and Mimic + +#ifdef MP_TEST + if ((OPMODE & WIFI_MP_STATE) || priv->pshare->rf_ft_var.mp_specific) { + channel = priv->pshare->working_channel; + if (priv->pshare->mp_txpwr_tracking == FALSE) + return; + } else +#endif + { + channel = (priv->pmib->dot11RFEntry.dot11channel); + } + +#if RTL8881A_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8881A) { + max_rf_path = 1; + if ((get_bonding_type_8881A() == BOND_8881AM ||get_bonding_type_8881A() == BOND_8881AN) + && priv->pshare->rf_ft_var.use_intpa8881A && (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G)) + OFDM_min_index = 6; // intPA - upper bond set to +3 dB (base: -2 dB)ot11RFEntry.phyBandSelect == PHY_BAND_2G)) + else + OFDM_min_index = 10; //OFDM BB Swing should be less than +1dB, which is required by Arthur and Mimic + } +#endif + + + ThermalValue = (unsigned char)PHY_QueryRFReg(priv, RF_PATH_A, 0x42, 0xfc00, 1); //0x42: RF Reg[15:10] 88E + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther)); + + + //4 Query OFDM BB swing default setting Bit[31:21] + for(rf_path = 0 ; rf_path < max_rf_path ; rf_path++){ + ele_D = PHY_QueryBBReg(priv, BBSwingReg[rf_path], 0xffe00000); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("0x%x:0x%x ([31:21] = 0x%x)\n",BBSwingReg[rf_path], PHY_QueryBBReg(priv, BBSwingReg[rf_path], bMaskDWord),ele_D)); + for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {//4 + if (ele_D == OFDMSwingTable_8812[i]) { + OFDM_index[rf_path] = (unsigned char)i; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("OFDM_index[%d]=%d\n",rf_path, OFDM_index[rf_path])); + break; + } + } + } +#if 0 + //Query OFDM path A default setting Bit[31:21] + ele_D = PHY_QueryBBReg(priv, 0xc1c, 0xffe00000); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("0xc1c:0x%x ([31:21] = 0x%x)\n", PHY_QueryBBReg(priv, 0xc1c, bMaskDWord),ele_D)); + for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) {//4 + if (ele_D == OFDMSwingTable_8812[i]) { + OFDM_index[0] = (unsigned char)i; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("OFDM_index[0]=%d\n", OFDM_index[0])); + break; + } + } + //Query OFDM path B default setting + if (rf == 2) { + ele_D = PHY_QueryBBReg(priv, 0xe1c, 0xffe00000); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("0xe1c:0x%x ([32:21] = 0x%x)\n", PHY_QueryBBReg(priv, 0xe1c, bMaskDWord),ele_D)); + for (i = 0; i < OFDM_TABLE_SIZE_8812; i++) { + if (ele_D == OFDMSwingTable_8812[i]) { + OFDM_index[1] = (unsigned char)i; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("OFDM_index[1]=%d\n", OFDM_index[1])); + break; + } + } + } +#endif + /* Initialize */ + if (!priv->pshare->ThermalValue) { + priv->pshare->ThermalValue = priv->pmib->dot11RFEntry.ther; + priv->pshare->ThermalValue_LCK = ThermalValue; + } + + /* calculate average thermal meter */ + { + priv->pshare->ThermalValue_AVG_8812[priv->pshare->ThermalValue_AVG_index_8812] = ThermalValue; + priv->pshare->ThermalValue_AVG_index_8812++; + if (priv->pshare->ThermalValue_AVG_index_8812 == AVG_THERMAL_NUM_8812) + priv->pshare->ThermalValue_AVG_index_8812 = 0; + + for (i = 0; i < AVG_THERMAL_NUM_8812; i++) { + if (priv->pshare->ThermalValue_AVG_8812[i]) { + ThermalValue_AVG += priv->pshare->ThermalValue_AVG_8812[i]; + ThermalValue_AVG_count++; + } + } + + if (ThermalValue_AVG_count) { + ThermalValue = (unsigned char)(ThermalValue_AVG / ThermalValue_AVG_count); + //printk("AVG Thermal Meter = 0x%x \n", ThermalValue); + } + } + + + //4 If necessary, do power tracking + + if(!priv->pmib->dot11RFEntry.ther) /*Don't do power tracking since no calibrated thermal value*/ + return; + + if (ThermalValue != priv->pshare->ThermalValue) { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\n******** START POWER TRACKING ********\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\nReadback Thermal Meter = 0x%x pre thermal meter 0x%x EEPROMthermalmeter 0x%x\n", ThermalValue, priv->pshare->ThermalValue, priv->pmib->dot11RFEntry.ther)); + delta = RTL_ABS(ThermalValue, priv->pmib->dot11RFEntry.ther); + delta_LCK = RTL_ABS(ThermalValue, priv->pshare->ThermalValue_LCK); + is_decrease = ((ThermalValue < priv->pmib->dot11RFEntry.ther) ? 1 : 0); + //if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) + { +#ifdef _TRACKING_TABLE_FILE + if (priv->pshare->rf_ft_var.pwr_track_file) { + for (rf_path = 0; rf_path < max_rf_path; rf_path++) { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Diff: (%s)%d ==> get index from table : %d)\n", (is_decrease?"-":"+"), delta, get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0))); + if (is_decrease) { + OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] + get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0); + OFDM_index[rf_path] = ((OFDM_index[rf_path] > (OFDM_TABLE_SIZE_8812 - 1)) ? (OFDM_TABLE_SIZE_8812 - 1) : OFDM_index[rf_path]); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> decrese power ---> new OFDM_INDEX:%d (%d + %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0))); +#if 0// RTL8881A_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8881A){ + if(priv->pshare->rf_ft_var.pwrtrk_TxAGC_enable){ + if(priv->pshare->AddTxAGC){//TxAGC has been added + AddTxPower88XX_AC(priv,0); + priv->pshare->AddTxAGC = 0; + priv->pshare->AddTxAGC_index = 0; + } + } + } +#endif + } else { + + OFDM_index[rf_path] = priv->pshare->OFDM_index0[rf_path] - get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0); +#if 0// RTL8881A_SUPPORT + if(pDM_Odm->SupportICType == ODM_RTL8881A){ + if(priv->pshare->rf_ft_var.pwrtrk_TxAGC_enable){ + if(OFDM_index[i] < OFDM_min_index){ + priv->pshare->AddTxAGC_index = (OFDM_min_index - OFDM_index[i])/2; // Calculate Remnant TxAGC Value, 2 index for 1 TxAGC + AddTxPower88XX_AC(priv,priv->pshare->AddTxAGC_index); + priv->pshare->AddTxAGC = 1; //AddTxAGC Flag = 1 + OFDM_index[i] = OFDM_min_index; + } + else{ + if(priv->pshare->AddTxAGC){// TxAGC been added + priv->pshare->AddTxAGC = 0; + priv->pshare->AddTxAGC_index = 0; + AddTxPower88XX_AC(priv,0); //minus the added TPI + } + } + } + } +#else + OFDM_index[rf_path] = ((OFDM_index[rf_path] < OFDM_min_index) ? OFDM_min_index : OFDM_index[rf_path]); +#endif + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,(">>> increse power ---> new OFDM_INDEX:%d (%d - %d)\n", OFDM_index[rf_path], priv->pshare->OFDM_index0[rf_path], get_tx_tracking_index(priv, channel, rf_path, delta, is_decrease, 0))); + } + } + } +#endif + //4 Set new BB swing index + for (rf_path = 0; rf_path < max_rf_path; rf_path++) { + PHY_SetBBReg(priv, BBSwingReg[rf_path], 0xffe00000, OFDMSwingTable_8812[(unsigned int)OFDM_index[rf_path]]); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Readback 0x%x[31:21] = 0x%x, OFDM_index:%d\n",BBSwingReg[rf_path], PHY_QueryBBReg(priv, BBSwingReg[rf_path], 0xffe00000), OFDM_index[rf_path])); + } + + } + if (delta_LCK > 8) { + RTL_W8(0x522, 0xff); + Reg0x18 = PHY_QueryRFReg(priv, RF_PATH_A, 0x18, bMask20Bits, 1); + PHY_SetRFReg(priv, RF_PATH_A, 0xB4, BIT(14), 1); + PHY_SetRFReg(priv, RF_PATH_A, 0x18, BIT(15), 1); + delay_ms(200); // frequency deviation + PHY_SetRFReg(priv, RF_PATH_A, 0xB4, BIT(14), 0); + PHY_SetRFReg(priv, RF_PATH_A, 0x18, bMask20Bits, Reg0x18); + #ifdef CONFIG_RTL_8812_SUPPORT + if (GET_CHIP_VER(priv)== VERSION_8812E) + UpdateBBRFVal8812(priv, priv->pmib->dot11RFEntry.dot11channel); + #endif + RTL_W8(0x522, 0x0); + priv->pshare->ThermalValue_LCK = ThermalValue; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("\n******** END:%s() ********\n", __FUNCTION__)); + + //update thermal meter value + priv->pshare->ThermalValue = ThermalValue; + for (rf_path = 0; rf_path < max_rf_path; rf_path++) + priv->pshare->OFDM_index[rf_path] = OFDM_index[rf_path]; + } +} + +#endif + + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); +#if (RTL8814A_SUPPORT == 1) //use this function to do power tracking after 8814 by YuChen + if (pDM_Odm->SupportICType & ODM_RTL8814A) { + ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries2(pDM_Odm); + return; + } +#elif ODM_IC_11AC_SERIES_SUPPORT + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { + ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries(pDM_Odm); + return; + } +#endif + +#if (RTL8192E_SUPPORT == 1) + if (pDM_Odm->SupportICType==ODM_RTL8192E) { + ODM_TXPowerTrackingCallback_ThermalMeter_92E(pDM_Odm); + return; + } +#endif + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + //PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; +#endif + + u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, offset; + u1Byte ThermalValue_AVG_count = 0; + u4Byte ThermalValue_AVG = 0; +// s4Byte ele_A=0, ele_D, TempCCk, X, value32; +// s4Byte Y, ele_C=0; +// s1Byte OFDM_index[2], CCK_index=0, OFDM_index_old[2]={0,0}, CCK_index_old=0, index; +// s1Byte deltaPowerIndex = 0; + u4Byte i = 0;//, j = 0; + BOOLEAN is2T = FALSE; +// BOOLEAN bInteralPA = FALSE; + + u1Byte OFDM_max_index = 34, rf = (is2T) ? 2 : 1; //OFDM BB Swing should be less than +3.0dB, which is required by Arthur + u1Byte Indexforchannel = 0;/*GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ + enum _POWER_DEC_INC { POWER_DEC, POWER_INC }; + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + #endif + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + #endif + + TXPWRTRACK_CFG c; + + + //4 1. The following TWO tables decide the final index of OFDM/CCK swing table. + s1Byte deltaSwingTableIdx[2][index_mapping_NUM_88E] = { + // {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} + {0,0,2,3,4,4,5,6,7,7,8,9,10,10,11}, {0,0,1,2,3,4,4,4,4,5,7,8,9,9,10} + }; + u1Byte thermalThreshold[2][index_mapping_NUM_88E]={ + // {{Power decreasing(lower temperature)}, {Power increasing(higher temperature)}} + {0,2,4,6,8,10,12,14,16,18,20,22,24,26,27}, {0,2,4,6,8,10,12,14,16,18,20,22,25,25,25} + }; + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + prtl8192cd_priv priv = pDM_Odm->priv; +#endif + + //4 2. Initilization ( 7 steps in total ) + + ConfigureTxpowerTrack(pDM_Odm, &c); + + pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; //cosa add for debug + pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = TRUE; + +#if (MP_DRIVER == 1) + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = pHalData->TxPowerTrackControl; // We should keep updating the control variable according to HalData. + // RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. + pDM_Odm->RFCalibrateInfo.RegA24 = 0x090e1317; +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) && defined(MP_TEST) + if ((OPMODE & WIFI_MP_STATE) || pDM_Odm->priv->pshare->rf_ft_var.mp_specific) { + if(pDM_Odm->priv->pshare->mp_txpwr_tracking == FALSE) + return; + } +#endif + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("===>odm_TXPowerTrackingCallback_ThermalMeter_8188E, pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase: %d \n", pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->BbSwingIdxOfdmBase)); +/* + if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) { + ODM_SetRFReg(pDM_Odm, RF_PATH_A, c.ThermalRegAddr, BIT17 | BIT16, 0x3); + pDM_Odm->RFCalibrateInfo.TM_Trigger = 1; + return; + } +*/ + ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if( ! ThermalValue || ! pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) +#else + if( ! pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) +#endif + return; + + //4 3. Initialize ThermalValues of RFCalibrateInfo + + if( ! pDM_Odm->RFCalibrateInfo.ThermalValue) + { + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; + } + + if(pDM_Odm->RFCalibrateInfo.bReloadtxpowerindex) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n")); + } + + //4 4. Calculate average thermal meter + + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++; + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum) + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; + + for(i = 0; i < c.AverageThermalNum; i++) + { + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) + { + ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]; + ThermalValue_AVG_count++; + } + } + + if(ThermalValue_AVG_count) + { + // Give the new thermo value a weighting + ThermalValue_AVG += (ThermalValue*4); + + ThermalValue = (u1Byte)(ThermalValue_AVG / (ThermalValue_AVG_count+4)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("AVG Thermal Meter = 0x%x \n", ThermalValue)); + } + + //4 5. Calculate delta, delta_LCK, delta_IQK. + + delta = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue):(pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue); + delta_LCK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK):(pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); + delta_IQK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_IQK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_IQK):(pDM_Odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue); + + //4 6. If necessary, do LCK. + if (!(pDM_Odm->SupportICType & ODM_RTL8821)) { + /*if((delta_LCK > pHalData->Delta_LCK) && (pHalData->Delta_LCK != 0))*/ + if (delta_LCK >= c.Threshold_IQK) { + /*Delta temperature is equal to or larger than 20 centigrade.*/ + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; + (*c.PHY_LCCalibrate)(pDM_Odm); + } + } + + //3 7. If necessary, move the index of swing table to adjust Tx power. + + if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) + { +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + delta = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue); +#else + delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue); +#endif + + + //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(ThermalValue > pHalData->EEPROMThermalMeter) { +#else + if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) { +#endif + CALCULATE_SWINGTALBE_OFFSET(offset, POWER_INC, index_mapping_NUM_88E, delta); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex = deltaSwingTableIdx[POWER_INC][offset]; + + } else { + + CALCULATE_SWINGTALBE_OFFSET(offset, POWER_DEC, index_mapping_NUM_88E, delta); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex = (-1)*deltaSwingTableIdx[POWER_DEC][offset]; + } + + if (pDM_Odm->RFCalibrateInfo.DeltaPowerIndex == pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast) + pDM_Odm->RFCalibrateInfo.PowerIndexOffset = 0; + else + pDM_Odm->RFCalibrateInfo.PowerIndexOffset = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast; + + for(i = 0; i < rf; i++) + pDM_Odm->RFCalibrateInfo.OFDM_index[i] = pRFCalibrateInfo->BbSwingIdxOfdmBase + pDM_Odm->RFCalibrateInfo.PowerIndexOffset; + pDM_Odm->RFCalibrateInfo.CCK_index = pRFCalibrateInfo->BbSwingIdxCckBase + pDM_Odm->RFCalibrateInfo.PowerIndexOffset; + + pRFCalibrateInfo->BbSwingIdxCck = pDM_Odm->RFCalibrateInfo.CCK_index; + pRFCalibrateInfo->BbSwingIdxOfdm[RF_PATH_A] = pDM_Odm->RFCalibrateInfo.OFDM_index[RF_PATH_A]; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxCck, pRFCalibrateInfo->BbSwingIdxCckBase, pDM_Odm->RFCalibrateInfo.PowerIndexOffset)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("The 'OFDM' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxOfdm[RF_PATH_A], pRFCalibrateInfo->BbSwingIdxOfdmBase, pDM_Odm->RFCalibrateInfo.PowerIndexOffset)); + + //4 7.1 Handle boundary conditions of index. + + + for(i = 0; i < rf; i++) + { + if(pDM_Odm->RFCalibrateInfo.OFDM_index[i] > OFDM_max_index) + { + pDM_Odm->RFCalibrateInfo.OFDM_index[i] = OFDM_max_index; + } + else if (pDM_Odm->RFCalibrateInfo.OFDM_index[i] < 0) + { + pDM_Odm->RFCalibrateInfo.OFDM_index[i] = 0; + } + } + + if(pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1) + pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1; + else if (pDM_Odm->RFCalibrateInfo.CCK_index < 0) + pDM_Odm->RFCalibrateInfo.CCK_index = 0; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The thermal meter is unchanged or TxPowerTracking OFF: ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d)\n", ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue)); + pDM_Odm->RFCalibrateInfo.PowerIndexOffset = 0; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", pDM_Odm->RFCalibrateInfo.CCK_index, pRFCalibrateInfo->BbSwingIdxCckBase)); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index: %d\n", pDM_Odm->RFCalibrateInfo.OFDM_index[RF_PATH_A], pRFCalibrateInfo->BbSwingIdxOfdmBase)); + + if (pDM_Odm->RFCalibrateInfo.PowerIndexOffset != 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) + { + //4 7.2 Configure the Swing Table to adjust Tx Power. + + pDM_Odm->RFCalibrateInfo.bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking. + // + // 2012/04/23 MH According to Luke's suggestion, we can not write BB digital + // to increase TX power. Otherwise, EVM will be bad. + // + // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. + if (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) + { + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + // ("Temperature Increasing: delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + // pDM_Odm->RFCalibrateInfo.PowerIndexOffset, delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue)); + } + else if (ThermalValue < pDM_Odm->RFCalibrateInfo.ThermalValue)// Low temperature + { + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + // ("Temperature Decreasing: delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + // pDM_Odm->RFCalibrateInfo.PowerIndexOffset, delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue)); + } +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if (ThermalValue > pHalData->EEPROMThermalMeter) +#else + if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) +#endif + { +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Temperature(%d) hugher than PG value(%d), increases the power by TxAGC\n", ThermalValue, pHalData->EEPROMThermalMeter)); + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, TXAGC, 0, 0); + } + else + { + // ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("Temperature(%d) lower than PG value(%d), increases the power by TxAGC\n", ThermalValue, pHalData->EEPROMThermalMeter)); + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, RF_PATH_A, Indexforchannel); + if(is2T) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, RF_PATH_B, Indexforchannel); + } + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->BbSwingIdxCck; + pRFCalibrateInfo->BbSwingIdxOfdmBase = pRFCalibrateInfo->BbSwingIdxOfdm[RF_PATH_A]; + pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue; + + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + // if((delta_IQK > pHalData->Delta_IQK) && (pHalData->Delta_IQK != 0)) + if ((delta_IQK >= 8)) // Delta temperature is equal to or larger than 20 centigrade. + (*c.DoIQK)(pDM_Odm, delta_IQK, ThermalValue, 8); +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("<===dm_TXPowerTrackingCallback_ThermalMeter_8188E\n")); + + pDM_Odm->RFCalibrateInfo.TXPowercount = 0; +} + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + + +VOID +phy_PathAStandBy( + IN PADAPTER pAdapter + ) +{ + RTPRINT(FINIT, INIT_IQK, ("Path-A standby mode!\n")); + + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x0); + PHY_SetBBReg(pAdapter, 0x840, bMaskDWord, 0x00010000); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x808000); +} + +//1 7. IQK +//#define MAX_TOLERANCE 5 +//#define IQK_DELAY_TIME 1 //ms + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathA_IQK_8192C( + IN PADAPTER pAdapter, + IN BOOLEAN configPathB + ) +{ + + u4Byte regEAC, regE94, regE9C, regEA4; + u1Byte result = 0x00; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + RTPRINT(FINIT, INIT_IQK, ("Path A IQK!\n")); + + //path-A IQK setting + RTPRINT(FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + if(pAdapter->interfaceIndex == 0) + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); + } + else + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x10008c22); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x10008c22); + } + + PHY_SetBBReg(pAdapter, rTx_IQK_PI_A, bMaskDWord, 0x82140102); + + PHY_SetBBReg(pAdapter, rRx_IQK_PI_A, bMaskDWord, configPathB ? 0x28160202 : + IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202:0x28160502); + + //path-B IQK setting + if(configPathB) + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x10008c22); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x10008c22); + PHY_SetBBReg(pAdapter, rTx_IQK_PI_B, bMaskDWord, 0x82140102); + PHY_SetBBReg(pAdapter, rRx_IQK_PI_B, bMaskDWord, 0x28160202); + } + + //LO calibration setting + RTPRINT(FINIT, INIT_IQK, ("LO calibration setting!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Rsp, bMaskDWord, 0x001028d1); + + //One shot, path A LOK & IQK + RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms + RTPRINT(FINIT, INIT_IQK, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME)); + PlatformStallExecution(IQK_DELAY_TIME*1000); + + // Check failed + regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", regEAC)); + regE94 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xe94 = 0x%x\n", regE94)); + regE9C= PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xe9c = 0x%x\n", regE9C)); + regEA4= PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regEA4)); + + if(!(regEAC & BIT28) && + (((regE94 & 0x03FF0000)>>16) != 0x142) && + (((regE9C & 0x03FF0000)>>16) != 0x42) ) + result |= 0x01; + else //if Tx not OK, ignore Rx + return result; + + if(!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK + (((regEA4 & 0x03FF0000)>>16) != 0x132) && + (((regEAC & 0x03FF0000)>>16) != 0x36)) + result |= 0x02; + else + RTPRINT(FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); + + return result; + + +} + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathB_IQK_8192C( + IN PADAPTER pAdapter + ) +{ + u4Byte regEAC, regEB4, regEBC, regEC4, regECC; + u1Byte result = 0x00; + RTPRINT(FINIT, INIT_IQK, ("Path B IQK!\n")); + + //One shot, path B LOK & IQK + RTPRINT(FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000002); + PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000000); + + // delay x ms + RTPRINT(FINIT, INIT_IQK, ("Delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME)); + PlatformStallExecution(IQK_DELAY_TIME*1000); + + // Check failed + regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xeac = 0x%x\n", regEAC)); + regEB4 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regEB4)); + regEBC= PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xebc = 0x%x\n", regEBC)); + regEC4= PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regEC4)); + regECC= PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord); + RTPRINT(FINIT, INIT_IQK, ("0xecc = 0x%x\n", regECC)); + + if(!(regEAC & BIT31) && + (((regEB4 & 0x03FF0000)>>16) != 0x142) && + (((regEBC & 0x03FF0000)>>16) != 0x42)) + result |= 0x01; + else + return result; + + if(!(regEAC & BIT30) && + (((regEC4 & 0x03FF0000)>>16) != 0x132) && + (((regECC & 0x03FF0000)>>16) != 0x36)) + result |= 0x02; + else + RTPRINT(FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n")); + + + return result; + +} + +VOID +phy_PathAFillIQKMatrix( + IN PADAPTER pAdapter, + IN BOOLEAN bIQKOK, + IN s4Byte result[][8], + IN u1Byte final_candidate, + IN BOOLEAN bTxOnly + ) +{ + u4Byte Oldval_0, X, TX0_A, reg; + s4Byte Y, TX0_C; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + RTPRINT(FINIT, INIT_IQK, ("Path A IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed")); + + if(final_candidate == 0xFF) + return; + + else if(bIQKOK) + { + Oldval_0 = (PHY_QueryBBReg(pAdapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][0]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX0_A = (X * Oldval_0) >> 8; + RTPRINT(FINIT, INIT_IQK, ("X = 0x%x, TX0_A = 0x%x, Oldval_0 0x%x\n", X, TX0_A, Oldval_0)); + PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0>>7) & 0x1)); + + Y = result[final_candidate][1]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + + //path B IQK result + 3 + if(pAdapter->interfaceIndex == 1 && pHalData->CurrentBandType == BAND_ON_5G) + Y += 3; + + TX0_C = (Y * Oldval_0) >> 8; + RTPRINT(FINIT, INIT_IQK, ("Y = 0x%x, TX = 0x%x\n", Y, TX0_C)); + PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6)); + PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0>>7) & 0x1)); + + if(bTxOnly) + { + RTPRINT(FINIT, INIT_IQK, ("phy_PathAFillIQKMatrix only Tx OK\n")); + return; + } + + reg = result[final_candidate][2]; + PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0x3FF, reg); + + reg = result[final_candidate][3] & 0x3F; + PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0xFC00, reg); + + reg = (result[final_candidate][3] >> 6) & 0xF; + PHY_SetBBReg(pAdapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg); + } +} + +VOID +phy_PathBFillIQKMatrix( + IN PADAPTER pAdapter, + IN BOOLEAN bIQKOK, + IN s4Byte result[][8], + IN u1Byte final_candidate, + IN BOOLEAN bTxOnly //do Tx only + ) +{ + u4Byte Oldval_1, X, TX1_A, reg; + s4Byte Y, TX1_C; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + RTPRINT(FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n",(bIQKOK)?"Success":"Failed")); + + if(final_candidate == 0xFF) + return; + + else if(bIQKOK) + { + Oldval_1 = (PHY_QueryBBReg(pAdapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][4]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX1_A = (X * Oldval_1) >> 8; + RTPRINT(FINIT, INIT_IQK, ("X = 0x%x, TX1_A = 0x%x\n", X, TX1_A)); + PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1>>7) & 0x1)); + + Y = result[final_candidate][5]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + if(pHalData->CurrentBandType == BAND_ON_5G) + Y += 3; //temp modify for preformance + TX1_C = (Y * Oldval_1) >> 8; + RTPRINT(FINIT, INIT_IQK, ("Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C)); + PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6)); + PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F)); + PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1>>7) & 0x1)); + + if(bTxOnly) + return; + + reg = result[final_candidate][6]; + PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg); + + reg = result[final_candidate][7] & 0x3F; + PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg); + + reg = (result[final_candidate][7] >> 6) & 0xF; + PHY_SetBBReg(pAdapter, rOFDM0_AGCRSSITable, 0x0000F000, reg); + } +} + + +BOOLEAN +phy_SimularityCompare_92C( + IN PADAPTER pAdapter, + IN s4Byte result[][8], + IN u1Byte c1, + IN u1Byte c2 + ) +{ + u4Byte i, j, diff, SimularityBitMap, bound = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u1Byte final_candidate[2] = {0xFF, 0xFF}; //for path A and path B + BOOLEAN bResult = TRUE, is2T = IS_92C_SERIAL( pHalData->VersionID); + + if(is2T) + bound = 8; + else + bound = 4; + + SimularityBitMap = 0; + + for( i = 0; i < bound; i++ ) + { + diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]); + if (diff > MAX_TOLERANCE) + { + if((i == 2 || i == 6) && !SimularityBitMap) + { + if(result[c1][i]+result[c1][i+1] == 0) + final_candidate[(i/4)] = c2; + else if (result[c2][i]+result[c2][i+1] == 0) + final_candidate[(i/4)] = c1; + else + SimularityBitMap = SimularityBitMap|(1< do IQK again +*/ +BOOLEAN +phy_SimularityCompare( + IN PADAPTER pAdapter, + IN s4Byte result[][8], + IN u1Byte c1, + IN u1Byte c2 + ) +{ + return phy_SimularityCompare_92C(pAdapter, result, c1, c2); + +} + +VOID +phy_IQCalibrate_8192C( + IN PADAPTER pAdapter, + IN s4Byte result[][8], + IN u1Byte t, + IN BOOLEAN is2T + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u4Byte i; + u1Byte PathAOK, PathBOK; + u4Byte ADDA_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 }; + u4Byte IQK_MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; + + //since 92C & 92D have the different define in IQK_BB_REG + u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, + rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, + rFPGA0_XB_RFInterfaceOE, /*rFPGA0_RFMOD*/ rCCK0_AFESetting + }; + + u4Byte IQK_BB_REG_92D[IQK_BB_REG_NUM_92D] = { //for normal + rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, + rFPGA0_XB_RFInterfaceOE, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rOFDM0_TRxPathEnable, + /*rFPGA0_RFMOD*/ rCCK0_AFESetting, rFPGA0_AnalogParameter4, + rOFDM0_XAAGCCore1, rOFDM0_XBAGCCore1 + }; +#if MP_DRIVER + const u4Byte retryCount = 9; +#else + const u4Byte retryCount = 2; +#endif + //Neil Chen--2011--05--19-- + //3 Path Div + u1Byte rfPathSwitch=0x0; + + // Note: IQ calibration must be performed after loading + // PHY_REG.txt , and radio_a, radio_b.txt + + u4Byte bbvalue; + + if(t==0) + { + //bbvalue = PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bMaskDWord); + // RTPRINT(FINIT, INIT_IQK, ("phy_IQCalibrate_8192C()==>0x%08x\n",bbvalue)); + + RTPRINT(FINIT, INIT_IQK, ("IQ Calibration for %s\n", (is2T ? "2T2R" : "1T1R"))); + + // Save ADDA parameters, turn Path A ADDA on + phy_SaveADDARegisters(pAdapter, ADDA_REG, pHalData->ADDA_backup, IQK_ADDA_REG_NUM); + phy_SaveMACRegisters(pAdapter, IQK_MAC_REG, pHalData->IQK_MAC_backup); + phy_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pHalData->IQK_BB_backup, IQK_BB_REG_NUM); + } + + phy_PathADDAOn(pAdapter, ADDA_REG, TRUE, is2T); + + if(t==0) + { + pHalData->bRfPiEnable = (u1Byte)PHY_QueryBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, BIT(8)); + } + + if(!pHalData->bRfPiEnable){ + // Switch BB to PI mode to do IQ Calibration. + phy_PIModeSwitch(pAdapter, TRUE); + } + + //MAC settings + phy_MACSettingCalibration(pAdapter, IQK_MAC_REG, pHalData->IQK_MAC_backup); + + //PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, BIT24, 0x00); + PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskDWord, (0x0f000000 | (PHY_QueryBBReg(pAdapter, rCCK0_AFESetting, bMaskDWord))) ); + PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); + PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); + PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); + { + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); + PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); + PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); + } + + if(is2T) + { + PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); + PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); + } + + { + //Page B init + PHY_SetBBReg(pAdapter, rConfig_AntA, bMaskDWord, 0x00080000); + + if(is2T) + { + PHY_SetBBReg(pAdapter, rConfig_AntB, bMaskDWord, 0x00080000); + } + } + // IQ calibration setting + RTPRINT(FINIT, INIT_IQK, ("IQK setting!\n")); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x808000); + PHY_SetBBReg(pAdapter, rTx_IQK, bMaskDWord, 0x01007c00); + PHY_SetBBReg(pAdapter, rRx_IQK, bMaskDWord, 0x01004800); + + for(i = 0 ; i < retryCount ; i++){ + PathAOK = phy_PathA_IQK_8192C(pAdapter, is2T); + if(PathAOK == 0x03){ + RTPRINT(FINIT, INIT_IQK, ("Path A IQK Success!!\n")); + result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][2] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; + result[t][3] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; + break; + } + else if (i == (retryCount-1) && PathAOK == 0x01) //Tx IQK OK + { + RTPRINT(FINIT, INIT_IQK, ("Path A IQK Only Tx Success!!\n")); + + result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + } + } + + if(0x00 == PathAOK){ + RTPRINT(FINIT, INIT_IQK, ("Path A IQK failed!!\n")); + } + + if(is2T){ + phy_PathAStandBy(pAdapter); + + // Turn Path B ADDA on + phy_PathADDAOn(pAdapter, ADDA_REG, FALSE, is2T); + + for(i = 0 ; i < retryCount ; i++){ + PathBOK = phy_PathB_IQK_8192C(pAdapter); + if(PathBOK == 0x03){ + RTPRINT(FINIT, INIT_IQK, ("Path B IQK Success!!\n")); + result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][6] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; + result[t][7] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; + break; + } + else if (i == (retryCount - 1) && PathBOK == 0x01) //Tx IQK OK + { + RTPRINT(FINIT, INIT_IQK, ("Path B Only Tx IQK Success!!\n")); + result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; + result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; + } + } + + if(0x00 == PathBOK){ + RTPRINT(FINIT, INIT_IQK, ("Path B IQK failed!!\n")); + } + } + + //Back to BB mode, load original value + RTPRINT(FINIT, INIT_IQK, ("IQK:Back to BB mode, load original value!\n")); + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0); + + if(t!=0) + { + if(!pHalData->bRfPiEnable){ + // Switch back BB to SI mode after finish IQ Calibration. + phy_PIModeSwitch(pAdapter, FALSE); + } + + // Reload ADDA power saving parameters + phy_ReloadADDARegisters(pAdapter, ADDA_REG, pHalData->ADDA_backup, IQK_ADDA_REG_NUM); + + // Reload MAC parameters + phy_ReloadMACRegisters(pAdapter, IQK_MAC_REG, pHalData->IQK_MAC_backup); + + // Reload BB parameters + phy_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pHalData->IQK_BB_backup, IQK_BB_REG_NUM); + + /*Restore RX initial gain*/ + PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); + if (is2T) + PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); + //load 0xe30 IQC default value + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + + } + RTPRINT(FINIT, INIT_IQK, ("phy_IQCalibrate_8192C() <==\n")); + +} + + +VOID +phy_LCCalibrate92C( + IN PADAPTER pAdapter, + IN BOOLEAN is2T + ) +{ + u1Byte tmpReg; + u4Byte RF_Amode=0, RF_Bmode=0, LC_Cal; +// HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //Check continuous TX and Packet TX + tmpReg = PlatformEFIORead1Byte(pAdapter, 0xd03); + + if((tmpReg&0x70) != 0) //Deal with contisuous TX case + PlatformEFIOWrite1Byte(pAdapter, 0xd03, tmpReg&0x8F); //disable all continuous TX + else // Deal with Packet TX case + PlatformEFIOWrite1Byte(pAdapter, REG_TXPAUSE, 0xFF); // block all queues + + if((tmpReg&0x70) != 0) + { + //1. Read original RF mode + //Path-A + RF_Amode = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits); + + //Path-B + if(is2T) + RF_Bmode = PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits); + + //2. Set RF mode = standby mode + //Path-A + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000); + + //Path-B + if(is2T) + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000); + } + + //3. Read RF reg18 + LC_Cal = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits); + + //4. Set LC calibration begin bit15 + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000); + + delay_ms(100); + + + //Restore original situation + if((tmpReg&0x70) != 0) //Deal with contisuous TX case + { + //Path-A + PlatformEFIOWrite1Byte(pAdapter, 0xd03, tmpReg); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); + + //Path-B + if(is2T) + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); + } + else // Deal with Packet TX case + { + PlatformEFIOWrite1Byte(pAdapter, REG_TXPAUSE, 0x00); + } +} + + +VOID +phy_LCCalibrate( + IN PADAPTER pAdapter, + IN BOOLEAN is2T + ) +{ + phy_LCCalibrate92C(pAdapter, is2T); +} + + + +//Analog Pre-distortion calibration +#define APK_BB_REG_NUM 8 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +VOID +phy_APCalibrate_8192C( + IN PADAPTER pAdapter, + IN s1Byte delta, + IN BOOLEAN is2T + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + u4Byte regD[PATH_NUM]; + u4Byte tmpReg, index, offset, i, apkbound; + u1Byte path, pathbound = PATH_NUM; + u4Byte BB_backup[APK_BB_REG_NUM]; + u4Byte BB_REG[APK_BB_REG_NUM] = { + rFPGA1_TxBlock, rOFDM0_TRxPathEnable, + rFPGA0_RFMOD, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW, + rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE }; + u4Byte BB_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 }; + u4Byte BB_normal_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 }; + + u4Byte AFE_backup[IQK_ADDA_REG_NUM]; + u4Byte AFE_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 }; + + u4Byte MAC_backup[IQK_MAC_REG_NUM]; + u4Byte MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG}; + + u4Byte APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u4Byte APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, //path settings equal to path b settings + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u4Byte APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u4Byte APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, //path settings equal to path b settings + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; +#if 0 + u4Byte APK_RF_value_A[PATH_NUM][APK_BB_REG_NUM] = { + {0x1adb0, 0x1adb0, 0x1ada0, 0x1ad90, 0x1ad80}, + {0x00fb0, 0x00fb0, 0x00fa0, 0x00f90, 0x00f80} + }; +#endif + u4Byte AFE_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4}; //path A on path B off / path A off path B on + + u4Byte APK_offset[PATH_NUM] = { + rConfig_AntA, rConfig_AntB}; + + u4Byte APK_normal_offset[PATH_NUM] = { + rConfig_Pmpd_AntA, rConfig_Pmpd_AntB}; + + u4Byte APK_value[PATH_NUM] = { + 0x92fc0000, 0x12fc0000}; + + u4Byte APK_normal_value[PATH_NUM] = { + 0x92680000, 0x12680000}; + + s1Byte APK_delta_mapping[APK_BB_REG_NUM][13] = { + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + u4Byte APK_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + u4Byte APK_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + u4Byte APK_result[PATH_NUM][APK_BB_REG_NUM]; //val_1_1a, val_1_2a, val_2a, val_3a, val_4a +// u4Byte AP_curve[PATH_NUM][APK_CURVE_REG_NUM]; + + s4Byte BB_offset, delta_V, delta_offset; + +#if MP_DRIVER == 1 + PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx); + + pMptCtx->APK_bound[0] = 45; + pMptCtx->APK_bound[1] = 52; +#endif + + RTPRINT(FINIT, INIT_IQK, ("==>phy_APCalibrate_8192C() delta %d\n", delta)); + RTPRINT(FINIT, INIT_IQK, ("AP Calibration for %s\n", (is2T ? "2T2R" : "1T1R"))); + if(!is2T) + pathbound = 1; + + //2 FOR NORMAL CHIP SETTINGS + +// Temporarily do not allow normal driver to do the following settings because these offset +// and value will cause RF internal PA to be unpredictably disabled by HW, such that RF Tx signal +// will disappear after disable/enable card many times on 88CU. RF SD and DD have not find the +// root cause, so we remove these actions temporarily. Added by tynli and SD3 Allen. 2010.05.31. +#if MP_DRIVER != 1 + return; +#endif + //settings adjust for normal chip + for(index = 0; index < PATH_NUM; index ++) + { + APK_offset[index] = APK_normal_offset[index]; + APK_value[index] = APK_normal_value[index]; + AFE_on_off[index] = 0x6fdb25a4; + } + + for(index = 0; index < APK_BB_REG_NUM; index ++) + { + for(path = 0; path < pathbound; path++) + { + APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index]; + APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index]; + } + BB_AP_MODE[index] = BB_normal_AP_MODE[index]; + } + + apkbound = 6; + + //save BB default value + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + if(index == 0) //skip + continue; + BB_backup[index] = PHY_QueryBBReg(pAdapter, BB_REG[index], bMaskDWord); + } + + //save MAC default value + phy_SaveMACRegisters(pAdapter, MAC_REG, MAC_backup); + + //save AFE default value + phy_SaveADDARegisters(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + for(path = 0; path < pathbound; path++) + { + + + if(path == RF_PATH_A) + { + //path A APK + //load APK setting + //path-A + offset = rPdp_AntA; + for(index = 0; index < 11; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); + + offset = rConfig_AntA; + for(; index < 13; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x400000); + + //path A + offset = rPdp_AntA; + for(index = 0; index < 16; index++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_2[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0); + } + else if(path == RF_PATH_B) + { + //path B APK + //load APK setting + //path-B + offset = rPdp_AntB; + for(index = 0; index < 10; index ++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000); + + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); + + offset = rConfig_AntA; + index = 11; + for(; index < 13; index ++) //offset 0xb68, 0xb6c + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_1[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x400000); + + //path B + offset = 0xb60; + for(index = 0; index < 16; index++) + { + PHY_SetBBReg(pAdapter, offset, bMaskDWord, APK_normal_setting_value_2[index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", offset, PHY_QueryBBReg(pAdapter, offset, bMaskDWord))); + + offset += 0x04; + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0); + } + + //save RF default value + regD[path] = PHY_QueryRFReg(pAdapter, path, RF_TXBIAS_A, bRFRegOffsetMask); + + //Path A AFE all on, path B AFE All off or vise versa + for(index = 0; index < IQK_ADDA_REG_NUM ; index++) + PHY_SetBBReg(pAdapter, AFE_REG[index], bMaskDWord, AFE_on_off[path]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0xe70 %x\n", PHY_QueryBBReg(pAdapter, rRx_Wait_CCA, bMaskDWord))); + + //BB to AP mode + if(path == 0) + { + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + + if(index == 0) //skip + continue; + else if (index < 5) + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_AP_MODE[index]); + else if (BB_REG[index] == 0x870) + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_backup[index]|BIT10|BIT26); + else + PHY_SetBBReg(pAdapter, BB_REG[index], BIT10, 0x0); + } + + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + } + else //path B + { + PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00); + PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00); + + } + + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x800 %x\n", PHY_QueryBBReg(pAdapter, 0x800, bMaskDWord))); + + //MAC settings + phy_MACSettingCalibration(pAdapter, MAC_REG, MAC_backup); + + if(path == RF_PATH_A) //Path B to standby mode + { + PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bRFRegOffsetMask, 0x10000); + } + else //Path A to standby mode + { + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0x10000); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE1, bRFRegOffsetMask, 0x1000f); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE2, bRFRegOffsetMask, 0x20103); + } + + delta_offset = ((delta+14)/2); + if(delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + //AP calibration + for(index = 0; index < APK_BB_REG_NUM; index++) + { + if(index != 1) //only DO PA11+PAD01001, AP RF setting + continue; + + tmpReg = APK_RF_init_value[path][index]; +#if 1 + if(!pHalData->bAPKThermalMeterIgnore) + { + BB_offset = (tmpReg & 0xF0000) >> 16; + + if(!(tmpReg & BIT15)) //sign bit 0 + { + BB_offset = -BB_offset; + } + + delta_V = APK_delta_mapping[index][delta_offset]; + + BB_offset += delta_V; + + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() APK index %d tmpReg 0x%x delta_V %d delta_offset %d\n", index, tmpReg, delta_V, delta_offset)); + + if(BB_offset < 0) + { + tmpReg = tmpReg & (~BIT15); + BB_offset = -BB_offset; + } + else + { + tmpReg = tmpReg | BIT15; + } + tmpReg = (tmpReg & 0xFFF0FFFF) | (BB_offset << 16); + } +#endif + +#if DEV_BUS_TYPE==RT_PCI_INTERFACE + if(IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) + PHY_SetRFReg(pAdapter, path, RF_IPA_A, bRFRegOffsetMask, 0x894ae); + else +#endif + PHY_SetRFReg(pAdapter, path, RF_IPA_A, bRFRegOffsetMask, 0x8992e); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0xc %x\n", PHY_QueryRFReg(pAdapter, path, RF_IPA_A, bRFRegOffsetMask))); + PHY_SetRFReg(pAdapter, path, RF_AC, bRFRegOffsetMask, APK_RF_value_0[path][index]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x0 %x\n", PHY_QueryRFReg(pAdapter, path, RF_AC, bRFRegOffsetMask))); + PHY_SetRFReg(pAdapter, path, RF_TXBIAS_A, bRFRegOffsetMask, tmpReg); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0xd %x\n", PHY_QueryRFReg(pAdapter, path, RF_TXBIAS_A, bRFRegOffsetMask))); + + // PA11+PAD01111, one shot + i = 0; + do + { + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0x800000); + { + PHY_SetBBReg(pAdapter, APK_offset[path], bMaskDWord, APK_value[0]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", APK_offset[path], PHY_QueryBBReg(pAdapter, APK_offset[path], bMaskDWord))); + delay_ms(3); + PHY_SetBBReg(pAdapter, APK_offset[path], bMaskDWord, APK_value[1]); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0x%x value 0x%x\n", APK_offset[path], PHY_QueryBBReg(pAdapter, APK_offset[path], bMaskDWord))); + + delay_ms(20); + } + PHY_SetBBReg(pAdapter, rFPGA0_IQK, 0xffffff00, 0); + + if(path == RF_PATH_A) + tmpReg = PHY_QueryBBReg(pAdapter, rAPK, 0x03E00000); + else + tmpReg = PHY_QueryBBReg(pAdapter, rAPK, 0xF8000000); + RTPRINT(FINIT, INIT_IQK, ("phy_APCalibrate_8192C() offset 0xbd8[25:21] %x\n", tmpReg)); + + + i++; + } + while(tmpReg > apkbound && i < 4); + + APK_result[path][index] = tmpReg; + } + } + + //reload MAC default value + phy_ReloadMACRegisters(pAdapter, MAC_REG, MAC_backup); + + //reload BB default value + for(index = 0; index < APK_BB_REG_NUM ; index++) + { + + if(index == 0) //skip + continue; + PHY_SetBBReg(pAdapter, BB_REG[index], bMaskDWord, BB_backup[index]); + } + + //reload AFE default value + phy_ReloadADDARegisters(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + //reload RF path default value + for(path = 0; path < pathbound; path++) + { + PHY_SetRFReg(pAdapter, path, RF_TXBIAS_A, bRFRegOffsetMask, regD[path]); + if(path == RF_PATH_B) + { + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE1, bRFRegOffsetMask, 0x1000f); + PHY_SetRFReg(pAdapter, RF_PATH_A, RF_MODE2, bRFRegOffsetMask, 0x20101); + } + + //note no index == 0 + if (APK_result[path][1] > 6) + APK_result[path][1] = 6; + RTPRINT(FINIT, INIT_IQK, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1])); + } + + RTPRINT(FINIT, INIT_IQK, ("\n")); + + + for(path = 0; path < pathbound; path++) + { + PHY_SetRFReg(pAdapter, path, RF_BS_PA_APSET_G1_G4, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1])); + if(path == RF_PATH_A) + PHY_SetRFReg(pAdapter, path, RF_BS_PA_APSET_G5_G8, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05)); + else + PHY_SetRFReg(pAdapter, path, RF_BS_PA_APSET_G5_G8, bRFRegOffsetMask, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05)); + + PHY_SetRFReg(pAdapter, path, RF_BS_PA_APSET_G9_G11, bRFRegOffsetMask, ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08)); + } + + pHalData->bAPKdone = TRUE; + + RTPRINT(FINIT, INIT_IQK, ("<==phy_APCalibrate_8192C()\n")); +} + + +VOID +PHY_IQCalibrate_8192C( + IN PADAPTER pAdapter, + IN BOOLEAN bReCovery + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + s4Byte result[4][8]; //last is final result + u1Byte i, final_candidate, Indexforchannel; + BOOLEAN bPathAOK, bPathBOK; + s4Byte RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0; + BOOLEAN is12simular, is13simular, is23simular; + BOOLEAN bStartContTx = FALSE, bSingleTone = FALSE, bCarrierSuppression = FALSE; + u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, + rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, + rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, + rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, + rOFDM0_RxIQExtAnta}; + + if (ODM_CheckPowerStatus(pAdapter) == FALSE) + return; + +#if MP_DRIVER == 1 + bStartContTx = pAdapter->MptCtx.bStartContTx; + bSingleTone = pAdapter->MptCtx.bSingleTone; + bCarrierSuppression = pAdapter->MptCtx.bCarrierSuppression; +#endif + + //ignore IQK when continuous Tx + if(bStartContTx || bSingleTone || bCarrierSuppression) + return; + +#ifdef DISABLE_BB_RF + return; +#endif + if(pAdapter->bSlaveOfDMSP) + return; + + if (bReCovery) + { + phy_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pHalData->IQK_BB_backup_recover, 9); + return; + + } + + RTPRINT(FINIT, INIT_IQK, ("IQK:Start!!!\n")); + + for(i = 0; i < 8; i++) + { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + bPathAOK = FALSE; + bPathBOK = FALSE; + is12simular = FALSE; + is23simular = FALSE; + is13simular = FALSE; + + AcquireCCKAndRWPageAControl(pAdapter); + /*RT_TRACE(COMP_INIT,DBG_LOUD,("Acquire Mutex in IQCalibrate\n"));*/ + for (i=0; i<3; i++) + { + /*For 88C 1T1R*/ + phy_IQCalibrate_8192C(pAdapter, result, i, FALSE); + + if(i == 1) + { + is12simular = phy_SimularityCompare(pAdapter, result, 0, 1); + if(is12simular) + { + final_candidate = 0; + break; + } + } + + if(i == 2) + { + is13simular = phy_SimularityCompare(pAdapter, result, 0, 2); + if(is13simular) + { + final_candidate = 0; + break; + } + + is23simular = phy_SimularityCompare(pAdapter, result, 1, 2); + if(is23simular) + final_candidate = 1; + else + { + for(i = 0; i < 8; i++) + RegTmp += result[3][i]; + + if(RegTmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } +// RT_TRACE(COMP_INIT,DBG_LOUD,("Release Mutex in IQCalibrate \n")); + ReleaseCCKAndRWPageAControl(pAdapter); + + for (i=0; i<4; i++) + { + RegE94 = result[i][0]; + RegE9C = result[i][1]; + RegEA4 = result[i][2]; + RegEAC = result[i][3]; + RegEB4 = result[i][4]; + RegEBC = result[i][5]; + RegEC4 = result[i][6]; + RegECC = result[i][7]; + RTPRINT(FINIT, INIT_IQK, ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC)); + } + + if(final_candidate != 0xff) + { + pHalData->RegE94 = RegE94 = result[final_candidate][0]; + pHalData->RegE9C = RegE9C = result[final_candidate][1]; + RegEA4 = result[final_candidate][2]; + RegEAC = result[final_candidate][3]; + pHalData->RegEB4 = RegEB4 = result[final_candidate][4]; + pHalData->RegEBC = RegEBC = result[final_candidate][5]; + RegEC4 = result[final_candidate][6]; + RegECC = result[final_candidate][7]; + RTPRINT(FINIT, INIT_IQK, ("IQK: final_candidate is %x\n",final_candidate)); + RTPRINT(FINIT, INIT_IQK, ("IQK: RegE94=%x RegE9C=%x RegEA4=%x RegEAC=%x RegEB4=%x RegEBC=%x RegEC4=%x RegECC=%x\n ", RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC)); + bPathAOK = bPathBOK = TRUE; + } + else + { + RegE94 = RegEB4 = pHalData->RegE94 = pHalData->RegEB4 = 0x100; //X default value + RegE9C = RegEBC = pHalData->RegE9C = pHalData->RegEBC = 0x0; //Y default value + } + + if((RegE94 != 0)/*&&(RegEA4 != 0)*/) + { + if(pHalData->CurrentBandType == BAND_ON_5G) + phy_PathAFillIQKMatrix_5G_Normal(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); + else + phy_PathAFillIQKMatrix(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); + + } + + if (IS_92C_SERIAL(pHalData->VersionID) || IS_92D_SINGLEPHY(pHalData->VersionID)) + { + if((RegEB4 != 0)/*&&(RegEC4 != 0)*/) + { + if(pHalData->CurrentBandType == BAND_ON_5G) + phy_PathBFillIQKMatrix_5G_Normal(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); + else + phy_PathBFillIQKMatrix(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); + } + } + + phy_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pHalData->IQK_BB_backup_recover, 9); + +} + + +VOID +PHY_LCCalibrate_8192C( + IN PADAPTER pAdapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + BOOLEAN bStartContTx = FALSE, bSingleTone = FALSE, bCarrierSuppression = FALSE; + PMGNT_INFO pMgntInfo=&pAdapter->MgntInfo; + PMGNT_INFO pMgntInfoBuddyAdapter; + u4Byte timeout = 2000, timecount = 0; + PADAPTER BuddyAdapter = pAdapter->BuddyAdapter; + +#if MP_DRIVER == 1 + bStartContTx = pAdapter->MptCtx.bStartContTx; + bSingleTone = pAdapter->MptCtx.bSingleTone; + bCarrierSuppression = pAdapter->MptCtx.bCarrierSuppression; +#endif + +#ifdef DISABLE_BB_RF + return; +#endif + + //ignore LCK when continuous Tx + if(bStartContTx || bSingleTone || bCarrierSuppression) + return; + + if(BuddyAdapter != NULL && + ((pAdapter->interfaceIndex == 0 && pHalData->CurrentBandType == BAND_ON_2_4G) || + (pAdapter->interfaceIndex == 1 && pHalData->CurrentBandType == BAND_ON_5G))) + { + pMgntInfoBuddyAdapter=&BuddyAdapter->MgntInfo; + while(pMgntInfoBuddyAdapter->bScanInProgress && timecount < timeout) + { + delay_ms(50); + timecount += 50; + } + } + + while(pMgntInfo->bScanInProgress && timecount < timeout) + { + delay_ms(50); + timecount += 50; + } + + pHalData->bLCKInProgress = TRUE; + + RTPRINT(FINIT, INIT_IQK, ("LCK:Start!!!interface %d currentband %x delay %d ms\n", pAdapter->interfaceIndex, pHalData->CurrentBandType, timecount)); + + //if(IS_92C_SERIAL(pHalData->VersionID) || IS_92D_SINGLEPHY(pHalData->VersionID)) + if(IS_2T2R(pHalData->VersionID)) + { + phy_LCCalibrate(pAdapter, TRUE); + } + else{ + // For 88C 1T1R + phy_LCCalibrate(pAdapter, FALSE); + } + + pHalData->bLCKInProgress = FALSE; + + RTPRINT(FINIT, INIT_IQK, ("LCK:Finish!!!interface %d\n", pAdapter->interfaceIndex)); + + +} + +VOID +PHY_APCalibrate_8192C( + IN PADAPTER pAdapter, + IN s1Byte delta + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + //default disable APK, because Tx NG issue, suggest by Jenyu, 2011.11.25 + return; + +#ifdef DISABLE_BB_RF + return; +#endif + +#if FOR_BRAZIL_PRETEST != 1 + if(pHalData->bAPKdone) +#endif + return; + + if(IS_92C_SERIAL( pHalData->VersionID)){ + phy_APCalibrate_8192C(pAdapter, delta, TRUE); + } + else{ + // For 88C 1T1R + phy_APCalibrate_8192C(pAdapter, delta, FALSE); + } +} + + +#endif + + +//3============================================================ +//3 IQ Calibration +//3============================================================ + +VOID +ODM_ResetIQKResult( + IN PVOID pDM_VOID +) +{ + return; +} +#if 1//!(DM_ODM_SUPPORT_TYPE & ODM_AP) +u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl) +{ + u1Byte channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = + {1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,161,163,165}; + u1Byte place = chnl; + + + if(chnl > 14) + { + for(place = 14; placeAdapter; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*pDM_Odm->pIsFcsModeEnable) + return; +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if (!IS_HARDWARE_TYPE_JAGUAR(Adapter)) + return; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + else if (IS_HARDWARE_TYPE_8812AU(Adapter)) + return; +#endif +#endif + +#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*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PHY_IQCalibrate_8821A(pDM_Odm, FALSE); +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHY_IQCalibrate(Adapter, FALSE); +#else + PHY_IQCalibrate_8821A(Adapter, FALSE); +#endif + } + } else + pDM_Odm->LinkedInterval = 0; +#endif +} + +void phydm_rf_init(IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + odm_TXPowerTrackingInit(pDM_Odm); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + ODM_ClearTxPowerTrackingState(pDM_Odm); +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8814A) + PHY_IQCalibrate_8814A_Init(pDM_Odm); +#endif +#endif + +} + +void phydm_rf_watchdog(IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#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); +#endif +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.h new file mode 100644 index 00000000..3fdbc72e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ap.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_RF_H__ + #define __HAL_PHY_RF_H__ + +#include "phydm_powertracking_ap.h" +#if (RTL8814A_SUPPORT == 1) +#include "rtl8814a/phydm_iqk_8814a.h" +#endif + +#if (RTL8822B_SUPPORT == 1) +#include "rtl8822b/phydm_iqk_8822b.h" +#endif + + +typedef enum _PWRTRACK_CONTROL_METHOD { + BBSWING, + TXAGC, + MIX_MODE, + TSSI_MODE +} PWRTRACK_METHOD; + +typedef VOID (*FuncSetPwr)(PVOID, PWRTRACK_METHOD, u1Byte, u1Byte); +typedef VOID(*FuncIQK)(PVOID, u1Byte, u1Byte, u1Byte); +typedef VOID (*FuncLCK)(PVOID); + //refine by YuChen for 8814A +typedef VOID (*FuncSwing)(PVOID, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); +typedef VOID (*FuncSwing8814only)(PVOID, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); + +typedef struct _TXPWRTRACK_CFG { + u1Byte SwingTableSize_CCK; + u1Byte SwingTableSize_OFDM; + u1Byte Threshold_IQK; + u1Byte Threshold_DPK; + u1Byte AverageThermalNum; + u1Byte RfPathCount; + u4Byte ThermalRegAddr; + FuncSetPwr ODM_TxPwrTrackSetPwr; + FuncIQK DoIQK; + FuncLCK PHY_LCCalibrate; + FuncSwing GetDeltaSwingTable; + FuncSwing8814only GetDeltaSwingTable8814only; +} TXPWRTRACK_CFG, *PTXPWRTRACK_CFG; + +VOID +ConfigureTxpowerTrack( + IN PVOID pDM_VOID, + OUT PTXPWRTRACK_CFG pConfig + ); + + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ); + +#if (RTL8192E_SUPPORT==1) +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_92E( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ); +#endif + +#if (RTL8814A_SUPPORT == 1) +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries2( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ); + +#elif ODM_IC_11AC_SERIES_SUPPORT +VOID +ODM_TXPowerTrackingCallback_ThermalMeter_JaguarSeries( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ); +#endif + +#define IS_CCK_RATE(_rate) (ODM_MGN_1M == _rate || _rate == ODM_MGN_2M || _rate == ODM_MGN_5_5M || _rate == ODM_MGN_11M ) + + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms + + // +// BB/MAC/RF other monitor API +// + +void PHY_SetMonitorMode8192C(IN PADAPTER pAdapter, + IN BOOLEAN bEnableMonitorMode ); + +// +// IQ calibrate +// +void +PHY_IQCalibrate_8192C( IN PADAPTER pAdapter, + IN BOOLEAN bReCovery); + +// +// LC calibrate +// +void +PHY_LCCalibrate_8192C( IN PADAPTER pAdapter); + +// +// AP calibrate +// +void +PHY_APCalibrate_8192C( IN PADAPTER pAdapter, + IN s1Byte delta); +#endif + +#define ODM_TARGET_CHNL_NUM_2G_5G 59 + + +VOID +ODM_ResetIQKResult( + IN PVOID pDM_VOID +); +u1Byte +ODM_GetRightChnlPlaceforIQK( + IN u1Byte chnl +); + +void phydm_rf_init(IN PVOID pDM_VOID); +void phydm_rf_watchdog(IN PVOID pDM_VOID); + +#endif // #ifndef __HAL_PHY_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.c new file mode 100644 index 00000000..adad98ed --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.c @@ -0,0 +1,711 @@ +/****************************************************************************** + * + * 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" + + +#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \ + do {\ + for(_offset = 0; _offset < _size; _offset++)\ + {\ + if(_deltaThermal < thermalThreshold[_direction][_offset])\ + {\ + if(_offset != 0)\ + _offset--;\ + break;\ + }\ + } \ + if(_offset >= _size)\ + _offset = _size-1;\ + } while(0) + +void ConfigureTxpowerTrack( + IN PVOID pDM_VOID, + OUT PTXPWRTRACK_CFG pConfig + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + +#if RTL8192E_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8192E) + ConfigureTxpowerTrack_8192E(pConfig); +#endif +#if RTL8821A_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8821) + ConfigureTxpowerTrack_8821A(pConfig); +#endif +#if RTL8812A_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8812) + ConfigureTxpowerTrack_8812A(pConfig); +#endif +#if RTL8188E_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8188E) + ConfigureTxpowerTrack_8188E(pConfig); +#endif + +#if RTL8723B_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8723B) + ConfigureTxpowerTrack_8723B(pConfig); +#endif + +#if RTL8814A_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8814A) + ConfigureTxpowerTrack_8814A(pConfig); +#endif + +#if RTL8703B_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8703B) + ConfigureTxpowerTrack_8703B(pConfig); +#endif + +#if RTL8188F_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8188F) + ConfigureTxpowerTrack_8188F(pConfig); +#endif +} + +//====================================================================== +// <20121113, Kordan> This function should be called when TxAGC changed. +// Otherwise the previous compensation is gone, because we record the +// delta of temperature between two TxPowerTracking watch dogs. +// +// NOTE: If Tx BB swing or Tx scaling is varified during run-time, still +// need to call this function. +//====================================================================== +VOID +ODM_ClearTxPowerTrackingState( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pDM_Odm->Adapter); + u1Byte p = 0; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex; + pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->DefaultCckIndex; + pDM_Odm->RFCalibrateInfo.CCK_index = 0; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) + { + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex; + + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + pRFCalibrateInfo->DeltaPowerIndex[p] = 0; + pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0; + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = 0; /* Initial Mix mode power tracking*/ + pRFCalibrateInfo->Remnant_OFDMSwingIdx[p] = 0; + pRFCalibrateInfo->KfreeOffset[p] = 0; + } + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = FALSE; /*Initial at Modify Tx Scaling Mode*/ + pRFCalibrateInfo->Modify_TxAGC_Flag_PathB = FALSE; /*Initial at Modify Tx Scaling Mode*/ + pRFCalibrateInfo->Modify_TxAGC_Flag_PathC = FALSE; /*Initial at Modify Tx Scaling Mode*/ + pRFCalibrateInfo->Modify_TxAGC_Flag_PathD = FALSE; /*Initial at Modify Tx Scaling Mode*/ + pRFCalibrateInfo->Remnant_CCKSwingIdx = 0; + pRFCalibrateInfo->ThermalValue = pHalData->EEPROMThermalMeter; + + pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0; //modify by Mingzhi.Guo + pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0; //modify by Mingzhi.Guo +} + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER Adapter +#endif + ) +{ + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + #endif +#endif + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0; + s1Byte diff_DPK[4] = {0}; + u1Byte ThermalValue_AVG_count = 0; + u4Byte ThermalValue_AVG = 0; + + u1Byte OFDM_min_index = 0; // OFDM BB Swing should be less than +3.0dB, which is required by Arthur + u1Byte Indexforchannel = 0; // GetRightChnlPlaceforIQK(pHalData->CurrentChannel) + BOOLEAN bTSSIenable = FALSE; + + TXPWRTRACK_CFG c; + + //4 1. The following TWO tables decide the final index of OFDM/CCK swing table. + pu1Byte deltaSwingTableIdx_TUP_A; + pu1Byte deltaSwingTableIdx_TDOWN_A; + pu1Byte deltaSwingTableIdx_TUP_B; + pu1Byte deltaSwingTableIdx_TDOWN_B; + /*for 8814 add by Yu Chen*/ + pu1Byte deltaSwingTableIdx_TUP_C; + pu1Byte deltaSwingTableIdx_TDOWN_C; + pu1Byte deltaSwingTableIdx_TUP_D; + pu1Byte deltaSwingTableIdx_TDOWN_D; + + //4 2. Initilization ( 7 steps in total ) + + ConfigureTxpowerTrack(pDM_Odm, &c); + + (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A, + (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B); + + if (pDM_Odm->SupportICType & ODM_RTL8814A) /*for 8814 path C & D*/ + (*c.GetDeltaSwingTable8814only)(pDM_Odm, (pu1Byte *)&deltaSwingTableIdx_TUP_C, (pu1Byte *)&deltaSwingTableIdx_TDOWN_C, + (pu1Byte *)&deltaSwingTableIdx_TUP_D, (pu1Byte *)&deltaSwingTableIdx_TDOWN_D); + + + pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; //cosa add for debug + pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = TRUE; + +#if (MP_DRIVER == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = pHalData->TxPowerTrackControl; // We should keep updating the control variable according to HalData. +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + 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; +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("===>ODM_TXPowerTrackingCallback_ThermalMeter Start\n pRFCalibrateInfo->BbSwingIdxCckBase: %d, pRFCalibrateInfo->BbSwingIdxOfdmBase[A]: %d, pRFCalibrateInfo->DefaultOfdmIndex: %d\n", + pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->BbSwingIdxOfdmBase[ODM_RF_PATH_A], pRFCalibrateInfo->DefaultOfdmIndex)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("pDM_Odm->RFCalibrateInfo.TxPowerTrackControl %d, pHalData->EEPROMThermalMeter %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl, pHalData->EEPROMThermalMeter)); + ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E + if( ! pDM_Odm->RFCalibrateInfo.TxPowerTrackControl || pHalData->EEPROMThermalMeter == 0 || + pHalData->EEPROMThermalMeter == 0xFF) + return; + + + //4 3. Initialize ThermalValues of RFCalibrateInfo + + if(pDM_Odm->RFCalibrateInfo.bReloadtxpowerindex) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n")); + } + + //4 4. Calculate average thermal meter + + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++; + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum) //Average times = c.AverageThermalNum + pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; + + for(i = 0; i < c.AverageThermalNum; i++) + { + if(pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) + { + ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]; + ThermalValue_AVG_count++; + } + } + + if(ThermalValue_AVG_count) //Calculate Average ThermalValue after average enough times + { + ThermalValue = (u1Byte)(ThermalValue_AVG / ThermalValue_AVG_count); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", ThermalValue, pHalData->EEPROMThermalMeter)); + } + + //4 5. Calculate delta, delta_LCK, delta_IQK. + + //"delta" here is used to determine whether thermal value changes or not. + delta = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue):(pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue); + delta_LCK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK):(pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); + delta_IQK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_IQK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_IQK):(pDM_Odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue); + + if (pDM_Odm->RFCalibrateInfo.ThermalValue_IQK == 0xff) { /*no PG, use thermal value for IQK*/ + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; + delta_IQK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_IQK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_IQK):(pDM_Odm->RFCalibrateInfo.ThermalValue_IQK - ThermalValue); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use ThermalValue for IQK\n")); + } + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + diff_DPK[p] = (s1Byte)ThermalValue - (s1Byte)pDM_Odm->RFCalibrateInfo.DpkThermal[p]; + + /*4 6. If necessary, do LCK.*/ + if (!(pDM_Odm->SupportICType & ODM_RTL8821)) { + + if (pDM_Odm->RFCalibrateInfo.ThermalValue_LCK == 0xff) { + /*no PG , do LCK at initial status*/ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n")); + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; + if (c.PHY_LCCalibrate) + (*c.PHY_LCCalibrate)(pDM_Odm); + delta_LCK = (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK)?(ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK):(pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK)); + /*DBG_871X("(delta, delta_LCK, delta_IQK) = (%d, %d, %d), %d\n", delta, delta_LCK, delta_IQK, c.Threshold_IQK);*/ + + /* 4 6. If necessary, do LCK.*/ + + if (delta_LCK >= c.Threshold_IQK) { + /* Delta temperature is equal to or larger than 20 centigrade.*/ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= Threshold_IQK(%d)\n", delta_LCK, c.Threshold_IQK)); + pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; + if (c.PHY_LCCalibrate) + (*c.PHY_LCCalibrate)(pDM_Odm); + } + } + //3 7. If necessary, move the index of swing table to adjust Tx power. + + if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) + { + //"delta" here is used to record the absolute value of differrence. +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + delta = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue); +#else + delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue); +#endif + if (delta >= TXPWR_TRACK_TABLE_SIZE) + delta = TXPWR_TRACK_TABLE_SIZE - 1; + + //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(ThermalValue > pHalData->EEPROMThermalMeter) { +#else + if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) { +#endif + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) { + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p]; /* recording power index offset */ + switch (p) { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_B[%d] = %d\n", delta, deltaSwingTableIdx_TUP_B[delta])); + + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_B[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_B[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A])); + + + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_C[%d] = %d\n", delta, deltaSwingTableIdx_TUP_C[delta])); + + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_C[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_C[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_D[%d] = %d\n", delta, deltaSwingTableIdx_TUP_D[delta])); + + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_D[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_D[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_A[%d] = %d\n", delta, deltaSwingTableIdx_TUP_A[delta])); + + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_A[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_A[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + } + } else { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) { + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p]; /* recording poer index offset */ + switch (p) { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_B[delta])); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_C[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_C[delta])); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_D[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_D[delta])); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_A[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_A[delta])); + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; /* Record delta swing for mix mode power tracking */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + } + } + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\n\n=========================== [Path-%d] Calculating PowerIndexOffset===========================\n", p)); + if (pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] == pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]) /* If Thermal value changes but lookup table value still the same */ + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; + else + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]; /* Power Index Diff between 2 times Power Tracking */ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("[Path-%d] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", p, pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p], pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p], pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p])); + + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pRFCalibrateInfo->BbSwingIdxOfdmBase[p] + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]; + pDM_Odm->RFCalibrateInfo.CCK_index = pRFCalibrateInfo->BbSwingIdxCckBase + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]; + + pRFCalibrateInfo->BbSwingIdxCck = pDM_Odm->RFCalibrateInfo.CCK_index; + pRFCalibrateInfo->BbSwingIdxOfdm[p] = pDM_Odm->RFCalibrateInfo.OFDM_index[p]; + + + + /* *************Print BB Swing Base and Index Offset************* */ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxCck, pRFCalibrateInfo->BbSwingIdxCckBase, pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p])); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxOfdm[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p], pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p])); + + //4 7.1 Handle boundary conditions of index. + + if(pDM_Odm->RFCalibrateInfo.OFDM_index[p] > c.SwingTableSize_OFDM-1) + { + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = c.SwingTableSize_OFDM-1; + } + else if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] < OFDM_min_index) + { + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = OFDM_min_index; + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\n\n========================================================================================================\n")); + if(pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1) + pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1; + else if (pDM_Odm->RFCalibrateInfo.CCK_index <= 0) + pDM_Odm->RFCalibrateInfo.CCK_index = 0; + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl, ThermalValue, pDM_Odm->RFCalibrateInfo.ThermalValue)); + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", + pDM_Odm->RFCalibrateInfo.CCK_index, pRFCalibrateInfo->BbSwingIdxCckBase)); /*Print Swing base & current*/ + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%d]: %d\n", + pDM_Odm->RFCalibrateInfo.OFDM_index[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p])); + } + + if ((pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A] != 0 || + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_B] != 0 || + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_C] != 0 || + pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_D] != 0) && + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl && (pHalData->EEPROMThermalMeter != 0xff)) + { + //4 7.2 Configure the Swing Table to adjust Tx Power. + + pDM_Odm->RFCalibrateInfo.bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking. + // + // 2012/04/23 MH According to Luke's suggestion, we can not write BB digital + // to increase TX power. Otherwise, EVM will be bad. + // + // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. + if (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature Increasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue)); + } + } + else if (ThermalValue < pDM_Odm->RFCalibrateInfo.ThermalValue)// Low temperature + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature Decreasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pDM_Odm->RFCalibrateInfo.ThermalValue)); + } + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if (ThermalValue > pHalData->EEPROMThermalMeter) +#else + if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) +#endif + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature(%d) higher than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter)); + + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8821 || + pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || + pDM_Odm->SupportICType == ODM_RTL8822B || pDM_Odm->SupportICType == ODM_RTL8188F || pDM_Odm->SupportICType == ODM_RTL8703B) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0); + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel); + } + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature(%d) lower than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter)); + + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8821 || + pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || + pDM_Odm->SupportICType == ODM_RTL8822B || pDM_Odm->SupportICType == ODM_RTL8188F || pDM_Odm->SupportICType == ODM_RTL8703B) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking MIX_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel); + } + else + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("**********Enter POWER Tracking BBSWING_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel); + } + + } + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->BbSwingIdxCck; /*Record last time Power Tracking result as base.*/ + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->BbSwingIdxOfdm[p]; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", pDM_Odm->RFCalibrateInfo.ThermalValue, ThermalValue)); + + pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue; /*Record last Power Tracking Thermal Value*/ + + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + if (!IS_HARDWARE_TYPE_8723B(Adapter) && !IS_HARDWARE_TYPE_8192E(Adapter) && !IS_HARDWARE_TYPE_8703B(Adapter)) { + /* Delta temperature is equal to or larger than 20 centigrade (When threshold is 8).*/ + if (delta_IQK >= c.Threshold_IQK) { + if (!pDM_Odm->RFCalibrateInfo.bIQKInProgress) + (*c.DoIQK)(pDM_Odm, delta_IQK, ThermalValue, 8); + } + } + if (!(pDM_Odm->SupportICType & ODM_RTL8814A)) { + if (pDM_Odm->RFCalibrateInfo.DpkThermal[ODM_RF_PATH_A] != 0) { + if (diff_DPK[ODM_RF_PATH_A] >= c.Threshold_DPK) { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK)); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.Threshold_DPK)) { + s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK); + + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, value); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, 0); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } + } + if (pDM_Odm->RFCalibrateInfo.DpkThermal[ODM_RF_PATH_B] != 0) { + if (diff_DPK[ODM_RF_PATH_B] >= c.Threshold_DPK) { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK)); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.Threshold_DPK)) { + s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK); + + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, value); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, 0); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } + } + } + +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("<===ODM_TXPowerTrackingCallback_ThermalMeter End\n")); + + pDM_Odm->RFCalibrateInfo.TXPowercount = 0; +} + + +//3============================================================ +//3 IQ Calibration +//3============================================================ + +VOID +ODM_ResetIQKResult( + IN PVOID pDM_VOID +) +{ + return; + +} +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl) +{ + u1Byte channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = + {1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,161,163,165}; + u1Byte place = chnl; + + + if(chnl > 14) + { + for(place = 14; placeAdapter; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*pDM_Odm->pIsFcsModeEnable) + return; +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if (!IS_HARDWARE_TYPE_JAGUAR(Adapter)) + return; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + else if (IS_HARDWARE_TYPE_8812AU(Adapter)) + return; +#endif +#endif + +#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*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + /*Change channel will do IQK , cancel duplicate doIQK by YiWei*/ + /*PHY_IQCalibrate_8821A(pDM_Odm, FALSE);*/ +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHY_IQCalibrate(Adapter, FALSE); +#else + PHY_IQCalibrate_8821A(Adapter, FALSE); +#endif + } + } else + pDM_Odm->LinkedInterval = 0; +#endif +} + +void phydm_rf_init(IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + odm_TXPowerTrackingInit(pDM_Odm); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + ODM_ClearTxPowerTrackingState(pDM_Odm); +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8814A) + PHY_IQCalibrate_8814A_Init(pDM_Odm); +#endif +#endif + +} + +void phydm_rf_watchdog(IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#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); +#endif +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.h new file mode 100644 index 00000000..78333d63 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_ce.h @@ -0,0 +1,106 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_RF_H__ + #define __HAL_PHY_RF_H__ + +/*#include "phydm_kfree.h"*/ +#if (RTL8814A_SUPPORT == 1) +#include "rtl8814a/phydm_iqk_8814a.h" +#endif + +#if (RTL8822B_SUPPORT == 1) +#include "rtl8822b/phydm_iqk_8822b.h" +#endif +#include "phydm_powertracking_ce.h" + + +typedef enum _SPUR_CAL_METHOD { + PLL_RESET, + AFE_PHASE_SEL +} SPUR_CAL_METHOD; + +typedef enum _PWRTRACK_CONTROL_METHOD { + BBSWING, + TXAGC, + MIX_MODE, + TSSI_MODE +} PWRTRACK_METHOD; + +typedef VOID (*FuncSetPwr)(PVOID, PWRTRACK_METHOD, u1Byte, u1Byte); +typedef VOID(*FuncIQK)(PVOID, u1Byte, u1Byte, u1Byte); +typedef VOID (*FuncLCK)(PVOID); +typedef VOID (*FuncSwing)(PVOID, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); +typedef VOID (*FuncSwing8814only)(PVOID, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); + +typedef struct _TXPWRTRACK_CFG { + u1Byte SwingTableSize_CCK; + u1Byte SwingTableSize_OFDM; + u1Byte Threshold_IQK; + u1Byte Threshold_DPK; + u1Byte AverageThermalNum; + u1Byte RfPathCount; + u4Byte ThermalRegAddr; + FuncSetPwr ODM_TxPwrTrackSetPwr; + FuncIQK DoIQK; + FuncLCK PHY_LCCalibrate; + FuncSwing GetDeltaSwingTable; + FuncSwing8814only GetDeltaSwingTable8814only; +} TXPWRTRACK_CFG, *PTXPWRTRACK_CFG; + +void ConfigureTxpowerTrack( + IN PVOID pDM_VOID, + OUT PTXPWRTRACK_CFG pConfig + ); + + +VOID +ODM_ClearTxPowerTrackingState( + IN PVOID pDM_VOID + ); + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PVOID pDM_VOID +#else + IN PADAPTER Adapter +#endif + ); + + + +#define ODM_TARGET_CHNL_NUM_2G_5G 59 + + +VOID +ODM_ResetIQKResult( + IN PVOID pDM_VOID +); +u1Byte +ODM_GetRightChnlPlaceforIQK( + IN u1Byte chnl +); + +void phydm_rf_init( IN PVOID pDM_VOID); +void phydm_rf_watchdog( IN PVOID pDM_VOID); + +#endif // #ifndef __HAL_PHY_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.c new file mode 100644 index 00000000..32f39858 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.c @@ -0,0 +1,716 @@ +/****************************************************************************** + * + * 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(DM_ODM_SUPPORT_TYPE & ODM_WIN) + +#define CALCULATE_SWINGTALBE_OFFSET(_offset, _direction, _size, _deltaThermal) \ + do {\ + for(_offset = 0; _offset < _size; _offset++)\ + {\ + if(_deltaThermal < thermalThreshold[_direction][_offset])\ + {\ + if(_offset != 0)\ + _offset--;\ + break;\ + }\ + } \ + if(_offset >= _size)\ + _offset = _size-1;\ + } while(0) + + +void ConfigureTxpowerTrack( + IN PDM_ODM_T pDM_Odm, + OUT PTXPWRTRACK_CFG pConfig + ) +{ +#if RTL8192E_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8192E) + ConfigureTxpowerTrack_8192E(pConfig); +#endif +#if RTL8821A_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8821) + ConfigureTxpowerTrack_8821A(pConfig); +#endif +#if RTL8812A_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8812) + ConfigureTxpowerTrack_8812A(pConfig); +#endif +#if RTL8188E_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8188E) + ConfigureTxpowerTrack_8188E(pConfig); +#endif + +#if RTL8188F_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8188F) + ConfigureTxpowerTrack_8188F(pConfig); +#endif + +#if RTL8723B_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8723B) + ConfigureTxpowerTrack_8723B(pConfig); +#endif + +#if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8814A) + ConfigureTxpowerTrack_8814A(pConfig); +#endif + +#if RTL8821B_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8821B) + ConfigureTxpowerTrack_8821B(pConfig); +#endif + +#if RTL8703B_SUPPORT + if(pDM_Odm->SupportICType==ODM_RTL8703B) + ConfigureTxpowerTrack_8703B(pConfig); +#endif + +} + +//====================================================================== +// <20121113, Kordan> This function should be called when TxAGC changed. +// Otherwise the previous compensation is gone, because we record the +// delta of temperature between two TxPowerTracking watch dogs. +// +// NOTE: If Tx BB swing or Tx scaling is varified during run-time, still +// need to call this function. +//====================================================================== +VOID +ODM_ClearTxPowerTrackingState( + IN PDM_ODM_T pDM_Odm + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pDM_Odm->Adapter); + u1Byte p = 0; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex; + pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->DefaultCckIndex; + pRFCalibrateInfo->CCK_index = 0; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) + { + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex; + + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + pRFCalibrateInfo->DeltaPowerIndex[p] = 0; + pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0; + + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = 0; // Initial Mix mode power tracking + pRFCalibrateInfo->Remnant_OFDMSwingIdx[p] = 0; + pRFCalibrateInfo->KfreeOffset[p] = 0; + } + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA= FALSE; //Initial at Modify Tx Scaling Mode + pRFCalibrateInfo->Modify_TxAGC_Flag_PathB= FALSE; //Initial at Modify Tx Scaling Mode + pRFCalibrateInfo->Modify_TxAGC_Flag_PathC= FALSE; //Initial at Modify Tx Scaling Mode + pRFCalibrateInfo->Modify_TxAGC_Flag_PathD= FALSE; //Initial at Modify Tx Scaling Mode + pRFCalibrateInfo->Remnant_CCKSwingIdx= 0; + pRFCalibrateInfo->ThermalValue = pHalData->EEPROMThermalMeter; + + pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0; //modify by Mingzhi.Guo + pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0; //modify by Mingzhi.Guo + +} + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER Adapter +#endif + ) +{ + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + u1Byte ThermalValue = 0, delta, delta_LCK, delta_IQK, p = 0, i = 0, pathName = 0; + s1Byte diff_DPK[4] = {0}; + u1Byte ThermalValue_AVG_count = 0; + u4Byte ThermalValue_AVG = 0; + + u1Byte OFDM_min_index = 0; // OFDM BB Swing should be less than +3.0dB, which is required by Arthur + u1Byte Indexforchannel = 0; // GetRightChnlPlaceforIQK(pHalData->CurrentChannel) + BOOLEAN bTSSIenable = FALSE; + + TXPWRTRACK_CFG c; + + //4 1. The following TWO tables decide the final index of OFDM/CCK swing table. + pu1Byte deltaSwingTableIdx_TUP_A, deltaSwingTableIdx_TDOWN_A; + pu1Byte deltaSwingTableIdx_TUP_B, deltaSwingTableIdx_TDOWN_B; + //for 8814 add by Yu Chen + pu1Byte deltaSwingTableIdx_TUP_C = NULL, deltaSwingTableIdx_TDOWN_C = NULL; + pu1Byte deltaSwingTableIdx_TUP_D= NULL, deltaSwingTableIdx_TDOWN_D = NULL; + + //4 2. Initilization ( 7 steps in total ) + + ConfigureTxpowerTrack(pDM_Odm, &c); + + (*c.GetDeltaSwingTable)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_A, (pu1Byte*)&deltaSwingTableIdx_TDOWN_A, + (pu1Byte*)&deltaSwingTableIdx_TUP_B, (pu1Byte*)&deltaSwingTableIdx_TDOWN_B); + + if(pDM_Odm->SupportICType & ODM_RTL8814A) // for 8814 path C & D + (*c.GetDeltaSwingTable8814only)(pDM_Odm, (pu1Byte*)&deltaSwingTableIdx_TUP_C, (pu1Byte*)&deltaSwingTableIdx_TDOWN_C, + (pu1Byte*)&deltaSwingTableIdx_TUP_D, (pu1Byte*)&deltaSwingTableIdx_TDOWN_D); + + + pRFCalibrateInfo->TXPowerTrackingCallbackCnt++; //cosa add for debug + pRFCalibrateInfo->bTXPowerTrackingInit = TRUE; + +#if (MP_DRIVER == 1) + /*pRFCalibrateInfo->TxPowerTrackControl = pHalData->TxPowerTrackControl; + We should keep updating the control variable according to HalData. + RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */ + pRFCalibrateInfo->RegA24 = 0x090e1317; +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("===>ODM_TXPowerTrackingCallback_ThermalMeter, \ + \n pRFCalibrateInfo->BbSwingIdxCckBase: %d, pRFCalibrateInfo->BbSwingIdxOfdmBase[A]: %d, pRFCalibrateInfo->DefaultOfdmIndex: %d\n", + pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->BbSwingIdxOfdmBase[ODM_RF_PATH_A], pRFCalibrateInfo->DefaultOfdmIndex)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("pRFCalibrateInfo->TxPowerTrackControl %d, pHalData->EEPROMThermalMeter %d\n", pRFCalibrateInfo->TxPowerTrackControl, pHalData->EEPROMThermalMeter)); + ThermalValue = (u1Byte)ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, c.ThermalRegAddr, 0xfc00); //0x42: RF Reg[15:10] 88E + + + if( ! pRFCalibrateInfo->TxPowerTrackControl ) + return; + + + //4 3. Initialize ThermalValues of RFCalibrateInfo + + if(pRFCalibrateInfo->bReloadtxpowerindex) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("reload ofdm index for band switch\n")); + } + + //4 4. Calculate average thermal meter + + pRFCalibrateInfo->ThermalValue_AVG[pRFCalibrateInfo->ThermalValue_AVG_index] = ThermalValue; + pRFCalibrateInfo->ThermalValue_AVG_index++; + if(pRFCalibrateInfo->ThermalValue_AVG_index == c.AverageThermalNum) //Average times = c.AverageThermalNum + pRFCalibrateInfo->ThermalValue_AVG_index = 0; + + for(i = 0; i < c.AverageThermalNum; i++) + { + if(pRFCalibrateInfo->ThermalValue_AVG[i]) + { + ThermalValue_AVG += pRFCalibrateInfo->ThermalValue_AVG[i]; + ThermalValue_AVG_count++; + } + } + + if(ThermalValue_AVG_count) //Calculate Average ThermalValue after average enough times + { + ThermalValue = (u1Byte)(ThermalValue_AVG / ThermalValue_AVG_count); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", ThermalValue, pHalData->EEPROMThermalMeter)); + } + + //4 5. Calculate delta, delta_LCK, delta_IQK. + + //"delta" here is used to determine whether thermal value changes or not. + delta = (ThermalValue > pRFCalibrateInfo->ThermalValue)?(ThermalValue - pRFCalibrateInfo->ThermalValue):(pRFCalibrateInfo->ThermalValue - ThermalValue); + delta_LCK = (ThermalValue > pRFCalibrateInfo->ThermalValue_LCK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_LCK):(pRFCalibrateInfo->ThermalValue_LCK - ThermalValue); + delta_IQK = (ThermalValue > pRFCalibrateInfo->ThermalValue_IQK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_IQK):(pRFCalibrateInfo->ThermalValue_IQK - ThermalValue); + + if(pRFCalibrateInfo->ThermalValue_IQK == 0xff) //no PG, use thermal value for IQK + { + pRFCalibrateInfo->ThermalValue_IQK = ThermalValue; + delta_IQK = (ThermalValue > pRFCalibrateInfo->ThermalValue_IQK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_IQK):(pRFCalibrateInfo->ThermalValue_IQK - ThermalValue); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, use ThermalValue for IQK\n")); + } + + for(p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + diff_DPK[p] = (s1Byte)ThermalValue - (s1Byte)pRFCalibrateInfo->DpkThermal[p]; + } + + //4 6. If necessary, do LCK. + + if (!(pDM_Odm->SupportICType & ODM_RTL8821)) { + /*no PG , do LCK at initial status*/ + if (pRFCalibrateInfo->ThermalValue_LCK == 0xff) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("no PG, do LCK\n")); + pRFCalibrateInfo->ThermalValue_LCK = ThermalValue; + if(c.PHY_LCCalibrate) + (*c.PHY_LCCalibrate)(pDM_Odm); + delta_LCK = (ThermalValue > pRFCalibrateInfo->ThermalValue_LCK)?(ThermalValue - pRFCalibrateInfo->ThermalValue_LCK):(pRFCalibrateInfo->ThermalValue_LCK - ThermalValue); + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", delta, delta_LCK, delta_IQK)); + + /* Delta temperature is equal to or larger than 20 centigrade.*/ + if (delta_LCK >= c.Threshold_IQK) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("delta_LCK(%d) >= Threshold_IQK(%d)\n", delta_LCK, c.Threshold_IQK)); + pRFCalibrateInfo->ThermalValue_LCK = ThermalValue; + if(c.PHY_LCCalibrate) + (*c.PHY_LCCalibrate)(pDM_Odm); + } + } + + //3 7. If necessary, move the index of swing table to adjust Tx power. + + if (delta > 0 && pRFCalibrateInfo->TxPowerTrackControl) + { + //"delta" here is used to record the absolute value of differrence. +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + delta = ThermalValue > pHalData->EEPROMThermalMeter?(ThermalValue - pHalData->EEPROMThermalMeter):(pHalData->EEPROMThermalMeter - ThermalValue); +#else + delta = (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther)?(ThermalValue - pDM_Odm->priv->pmib->dot11RFEntry.ther):(pDM_Odm->priv->pmib->dot11RFEntry.ther - ThermalValue); +#endif + if (delta >= TXPWR_TRACK_TABLE_SIZE) + delta = TXPWR_TRACK_TABLE_SIZE - 1; + + //4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if(ThermalValue > pHalData->EEPROMThermalMeter) { +#else + if(ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) { +#endif + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p]; //recording poer index offset + switch(p) + { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_B[%d] = %d\n", delta, deltaSwingTableIdx_TUP_B[delta])); + + pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_B[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_B[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_C[%d] = %d\n", delta, deltaSwingTableIdx_TUP_C[delta])); + + pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_C[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_C[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_D[%d] = %d\n", delta, deltaSwingTableIdx_TUP_D[delta])); + + pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_D[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_D[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TUP_A[%d] = %d\n", delta, deltaSwingTableIdx_TUP_A[delta])); + + pRFCalibrateInfo->DeltaPowerIndex[p] = deltaSwingTableIdx_TUP_A[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = deltaSwingTableIdx_TUP_A[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is higher and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + + } + + } + else { + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + pRFCalibrateInfo->DeltaPowerIndexLast[p] = pRFCalibrateInfo->DeltaPowerIndex[p]; //recording poer index offset + switch(p) + { + case ODM_RF_PATH_B: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_B[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_B[delta])); + pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_B[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_C: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_C[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_C[delta])); + pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_C[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_C] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + case ODM_RF_PATH_D: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_D[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_D[delta])); + pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_D[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_D] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("deltaSwingTableIdx_TDOWN_A[%d] = %d\n", delta, deltaSwingTableIdx_TDOWN_A[delta])); + pRFCalibrateInfo->DeltaPowerIndex[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; + pRFCalibrateInfo->Absolute_OFDMSwingIdx[p] = -1 * deltaSwingTableIdx_TDOWN_A[delta]; // Record delta swing for mix mode power tracking + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Temp is lower and pRFCalibrateInfo->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", pRFCalibrateInfo->Absolute_OFDMSwingIdx[p])); + break; + } + + } + + } + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\n\n=========================== [Path-%d] Calculating PowerIndexOffset===========================\n", p)); + + if(pRFCalibrateInfo->DeltaPowerIndex[p] == pRFCalibrateInfo->DeltaPowerIndexLast[p]) // If Thermal value changes but lookup table value still the same + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + else + pRFCalibrateInfo->PowerIndexOffset[p] = pRFCalibrateInfo->DeltaPowerIndex[p] - pRFCalibrateInfo->DeltaPowerIndexLast[p]; // Power Index Diff between 2 times Power Tracking + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("[Path-%d] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", p, pRFCalibrateInfo->PowerIndexOffset[p], pRFCalibrateInfo->DeltaPowerIndex[p], pRFCalibrateInfo->DeltaPowerIndexLast[p])); + + pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->BbSwingIdxOfdmBase[p] + pRFCalibrateInfo->PowerIndexOffset[p]; + pRFCalibrateInfo->CCK_index = pRFCalibrateInfo->BbSwingIdxCckBase + pRFCalibrateInfo->PowerIndexOffset[p]; + + pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->CCK_index; + pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->OFDM_index[p]; + + // *************Print BB Swing Base and Index Offset************* + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxCck, pRFCalibrateInfo->BbSwingIdxCckBase, pRFCalibrateInfo->PowerIndexOffset[p])); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The 'OFDM' final index(%d) = BaseIndex[%d](%d) + PowerIndexOffset(%d)\n", pRFCalibrateInfo->BbSwingIdxOfdm[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p], pRFCalibrateInfo->PowerIndexOffset[p])); + + //4 7.1 Handle boundary conditions of index. + + if(pRFCalibrateInfo->OFDM_index[p] > c.SwingTableSize_OFDM-1) + { + pRFCalibrateInfo->OFDM_index[p] = c.SwingTableSize_OFDM-1; + } + else if (pRFCalibrateInfo->OFDM_index[p] <= OFDM_min_index) + { + pRFCalibrateInfo->OFDM_index[p] = OFDM_min_index; + } + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("\n\n========================================================================================================\n")); + if(pRFCalibrateInfo->CCK_index > c.SwingTableSize_CCK-1) + pRFCalibrateInfo->CCK_index = c.SwingTableSize_CCK-1; + else if (pRFCalibrateInfo->CCK_index <= 0) + pRFCalibrateInfo->CCK_index = 0; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pRFCalibrateInfo->ThermalValue: %d\n", + pRFCalibrateInfo->TxPowerTrackControl, ThermalValue, pRFCalibrateInfo->ThermalValue)); + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", + pRFCalibrateInfo->CCK_index, pRFCalibrateInfo->BbSwingIdxCckBase)); //Print Swing base & current + + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%d]: %d\n", + pRFCalibrateInfo->OFDM_index[p], p, pRFCalibrateInfo->BbSwingIdxOfdmBase[p])); + } + + if ((pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_A] != 0 || + pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_B] != 0 || + pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_C] != 0 || + pRFCalibrateInfo->PowerIndexOffset[ODM_RF_PATH_D] != 0) && + pRFCalibrateInfo->TxPowerTrackControl && (pHalData->EEPROMThermalMeter != 0xff)) + { + //4 7.2 Configure the Swing Table to adjust Tx Power. + + pRFCalibrateInfo->bTxPowerChanged = TRUE; // Always TRUE after Tx Power is adjusted by power tracking. + // + // 2012/04/23 MH According to Luke's suggestion, we can not write BB digital + // to increase TX power. Otherwise, EVM will be bad. + // + // 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. + if (ThermalValue > pRFCalibrateInfo->ThermalValue) + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature Increasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, pRFCalibrateInfo->PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pRFCalibrateInfo->ThermalValue)); + } + } + + else if (ThermalValue < pRFCalibrateInfo->ThermalValue)// Low temperature + { + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature Decreasing(%d): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", + p, pRFCalibrateInfo->PowerIndexOffset[p], delta, ThermalValue, pHalData->EEPROMThermalMeter, pRFCalibrateInfo->ThermalValue)); + } + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if (ThermalValue > pHalData->EEPROMThermalMeter) +#else + if (ThermalValue > pDM_Odm->priv->pmib->dot11RFEntry.ther) +#endif + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature(%d) higher than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter)); + + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E ||pDM_Odm->SupportICType == ODM_RTL8821 || + pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || pDM_Odm->SupportICType == ODM_RTL8703B || pDM_Odm->SupportICType == ODM_RTL8188F) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking BBSWING_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("Temperature(%d) lower than PG value(%d)\n", ThermalValue, pHalData->EEPROMThermalMeter)); + + if (pDM_Odm->SupportICType == ODM_RTL8188E || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8821 || + pDM_Odm->SupportICType == ODM_RTL8812 || pDM_Odm->SupportICType == ODM_RTL8723B || pDM_Odm->SupportICType == ODM_RTL8814A || pDM_Odm->SupportICType == ODM_RTL8703B || pDM_Odm->SupportICType == ODM_RTL8188F) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking MIX_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel); + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("**********Enter POWER Tracking BBSWING_MODE**********\n")); + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, BBSWING, p, Indexforchannel); + } + + } + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->BbSwingIdxCck; // Record last time Power Tracking result as base. + for (p = ODM_RF_PATH_A; p < c.RfPathCount; p++) + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->BbSwingIdxOfdm[p]; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("pRFCalibrateInfo->ThermalValue = %d ThermalValue= %d\n", pRFCalibrateInfo->ThermalValue, ThermalValue)); + + pRFCalibrateInfo->ThermalValue = ThermalValue; //Record last Power Tracking Thermal Value + + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + if(!IS_HARDWARE_TYPE_8723B(Adapter)) + { + // Delta temperature is equal to or larger than 20 centigrade (When threshold is 8). + if ((delta_IQK >= c.Threshold_IQK)) { + if ( ! pRFCalibrateInfo->bIQKInProgress) + (*c.DoIQK)(pDM_Odm, delta_IQK, ThermalValue, 8); + } + } + if (pRFCalibrateInfo->DpkThermal[ODM_RF_PATH_A] != 0) { + if ((diff_DPK[ODM_RF_PATH_A] >= c.Threshold_DPK)) { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK)); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else if ((diff_DPK[ODM_RF_PATH_A] <= -1 * c.Threshold_DPK)) { + s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_A] / c.Threshold_DPK); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, value); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xcc4, BIT14|BIT13|BIT12|BIT11|BIT10, 0); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } + } + if (pRFCalibrateInfo->DpkThermal[ODM_RF_PATH_B] != 0) { + if ((diff_DPK[ODM_RF_PATH_B] >= c.Threshold_DPK)) { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK)); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else if ((diff_DPK[ODM_RF_PATH_B] <= -1 * c.Threshold_DPK)) { + s4Byte value = 0x20 + (diff_DPK[ODM_RF_PATH_B] / c.Threshold_DPK); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, value); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } else { + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x1); + ODM_SetBBReg(pDM_Odm, 0xec4, BIT14|BIT13|BIT12|BIT11|BIT10, 0); + ODM_SetBBReg(pDM_Odm, 0x82c, BIT(31), 0x0); + } + } + +#endif + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("<===ODM_TXPowerTrackingCallback_ThermalMeter\n")); + + pRFCalibrateInfo->TXPowercount = 0; +} + + + +//3============================================================ +//3 IQ Calibration +//3============================================================ + +VOID +ODM_ResetIQKResult( + IN PDM_ODM_T pDM_Odm +) +{ + return; +} +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +u1Byte ODM_GetRightChnlPlaceforIQK(u1Byte chnl) +{ + u1Byte channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = + {1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,161,163,165}; + u1Byte place = chnl; + + + if(chnl > 14) + { + for(place = 14; placeAdapter; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (*pDM_Odm->pIsFcsModeEnable) + return; +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + if (!IS_HARDWARE_TYPE_JAGUAR(Adapter)) + return; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + else if (IS_HARDWARE_TYPE_8812AU(Adapter)) + return; +#endif +#endif + +#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*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PHY_IQCalibrate_8821A(pDM_Odm, FALSE); +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHY_IQCalibrate(Adapter, FALSE); +#else + PHY_IQCalibrate_8821A(Adapter, FALSE); +#endif + } + } else + pDM_Odm->LinkedInterval = 0; +#endif +} + +void phydm_rf_init(IN PDM_ODM_T pDM_Odm) +{ + + odm_TXPowerTrackingInit(pDM_Odm); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + ODM_ClearTxPowerTrackingState(pDM_Odm); +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8814A) + PHY_IQCalibrate_8814A_Init(pDM_Odm); +#endif +#endif + +} + +void phydm_rf_watchdog(IN PDM_ODM_T 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); +#endif +} \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.h new file mode 100644 index 00000000..40104217 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/halphyrf_win.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_RF_H__ + #define __HAL_PHY_RF_H__ + +#include "phydm_kfree.h" +#if (RTL8814A_SUPPORT == 1) +#include "rtl8814a/phydm_iqk_8814a.h" +#endif + +#if (RTL8822B_SUPPORT == 1) +#include "rtl8822b/phydm_iqk_8822b.h" +#endif +#include "phydm_powertracking_win.h" + +typedef enum _SPUR_CAL_METHOD { + PLL_RESET, + AFE_PHASE_SEL +} SPUR_CAL_METHOD; + +typedef enum _PWRTRACK_CONTROL_METHOD { + BBSWING, + TXAGC, + MIX_MODE, + TSSI_MODE +} PWRTRACK_METHOD; + +typedef VOID (*FuncSetPwr)(PDM_ODM_T, PWRTRACK_METHOD, u1Byte, u1Byte); +typedef VOID(*FuncIQK)(PVOID, u1Byte, u1Byte, u1Byte); +typedef VOID (*FuncLCK)(PDM_ODM_T); + //refine by YuChen for 8814A +typedef VOID (*FuncSwing)(PDM_ODM_T, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); +typedef VOID (*FuncSwing8814only)(PDM_ODM_T, pu1Byte*, pu1Byte*, pu1Byte*, pu1Byte*); + +typedef struct _TXPWRTRACK_CFG { + u1Byte SwingTableSize_CCK; + u1Byte SwingTableSize_OFDM; + u1Byte Threshold_IQK; + u1Byte Threshold_DPK; + u1Byte AverageThermalNum; + u1Byte RfPathCount; + u4Byte ThermalRegAddr; + FuncSetPwr ODM_TxPwrTrackSetPwr; + FuncIQK DoIQK; + FuncLCK PHY_LCCalibrate; + FuncSwing GetDeltaSwingTable; + FuncSwing8814only GetDeltaSwingTable8814only; +} TXPWRTRACK_CFG, *PTXPWRTRACK_CFG; + +VOID +ConfigureTxpowerTrack( + IN PDM_ODM_T pDM_Odm, + OUT PTXPWRTRACK_CFG pConfig + ); + + +VOID +ODM_ClearTxPowerTrackingState( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER Adapter +#endif + ); + + + +#define ODM_TARGET_CHNL_NUM_2G_5G 59 + + +VOID +ODM_ResetIQKResult( + IN PDM_ODM_T pDM_Odm +); +u1Byte +ODM_GetRightChnlPlaceforIQK( + IN u1Byte chnl +); + +VOID odm_IQCalibrate(IN PDM_ODM_T pDM_Odm); +VOID phydm_rf_init( IN PDM_ODM_T pDM_Odm); +VOID phydm_rf_watchdog( IN PDM_ODM_T pDM_Odm); + +#endif // #ifndef __HAL_PHY_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/mp_precomp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/mp_precomp.h new file mode 100644 index 00000000..2ae81105 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/mp_precomp.h @@ -0,0 +1,20 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.c new file mode 100644 index 00000000..ecace00b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.c @@ -0,0 +1,2159 @@ +/****************************************************************************** + * + * 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[12][8] = { + { 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. +//============================================================ + +/* START------------COMMON INFO RELATED--------------- */ + +VOID +odm_GlobalAdapterCheck( + IN VOID + ); + +//move to odm_PowerTacking.h by YuChen + + + +VOID +odm_UpdatePowerTrainingState( + IN PDM_ODM_T pDM_Odm +); + +//============================================================ +//3 Export Interface +//============================================================ + +/*Y = 10*log(X)*/ +s4Byte +ODM_PWdB_Conversion( + IN s4Byte X, + IN u4Byte TotalBit, + IN u4Byte DecimalBit + ) +{ + s4Byte Y, integer = 0, decimal = 0; + u4Byte i; + + if(X == 0) + X = 1; // log2(x), x can't be 0 + + for(i = (TotalBit-1); i > 0; i--) + { + if(X & BIT(i)) + { + integer = i; + if(i > 0) + decimal = (X & BIT(i-1))?2:0; //decimal is 0.5dB*3=1.5dB~=2dB + break; + } + } + + Y = 3*(integer-DecimalBit)+decimal; //10*log(x)=3*log2(x), + + return Y; +} + +s4Byte +ODM_SignConversion( + IN s4Byte value, + IN u4Byte TotalBit + ) +{ + if(value&BIT(TotalBit-1)) + value -= BIT(TotalBit); + return value; +} + +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 +PHYDM_InitTRXAntennaSetting( + IN PDM_ODM_T pDM_Odm +) +{ +#if (RTL8814A_SUPPORT == 1) + + if (pDM_Odm->SupportICType & (ODM_RTL8814A)) { + u1Byte RxAnt = 0, TxAnt = 0; + + RxAnt = (u1Byte)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_RX_PATH, pDM_Odm), ODM_BIT(BB_RX_PATH, pDM_Odm)); + TxAnt = (u1Byte)ODM_GetBBReg(pDM_Odm, ODM_REG(BB_TX_PATH, pDM_Odm), ODM_BIT(BB_TX_PATH, pDM_Odm)); + pDM_Odm->TXAntStatus = (TxAnt & 0xf); + pDM_Odm->RXAntStatus = (RxAnt & 0xf); + } +#endif +} + +VOID +phydm_Init_cck_setting( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte value_824,value_82c; + + pDM_Odm->bCckHighPower = (BOOLEAN) ODM_GetBBReg(pDM_Odm, ODM_REG(CCK_RPT_FORMAT,pDM_Odm), ODM_BIT(CCK_RPT_FORMAT,pDM_Odm)); + + #if (RTL8192E_SUPPORT == 1) + if(pDM_Odm->SupportICType & (ODM_RTL8192E)) + { + /* 0x824[9] = 0x82C[9] = 0xA80[7] these regiaters settinh should be equal or CCK RSSI report may inaccurate */ + value_824 = ODM_GetBBReg(pDM_Odm, 0x824, BIT9); + value_82c = ODM_GetBBReg(pDM_Odm, 0x82c, BIT9); + + if(value_824 != value_82c) + { + ODM_SetBBReg(pDM_Odm, 0x82c , BIT9, value_824); + } + ODM_SetBBReg(pDM_Odm, 0xa80 , BIT7, value_824); + pDM_Odm->cck_agc_report_type = (BOOLEAN)value_824; + } + #endif + + #if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType & (ODM_RTL8703B)) { + + pDM_Odm->cck_agc_report_type = ODM_GetBBReg(pDM_Odm, 0x950, BIT11) ? 1 : 0; /*1: 4bit LNA , 0: 3bit LNA */ + + if (pDM_Odm->cck_agc_report_type != 1) { + DbgPrint("[Warning] 8703B CCK should be 4bit LNA, ie. 0x950[11] = 1\n"); + /**/ + } + } + #endif + +} + +u1Byte DummyHubUsbMode = 1;/* USB 2.0 */ +void phydm_hook_dummy_member( + IN PDM_ODM_T pDM_Odm + ) +{ + if (pDM_Odm->HubUsbMode == NULL) + pDM_Odm->HubUsbMode = &DummyHubUsbMode; +} + + +VOID +odm_CommonInfoSelfInit( + IN PDM_ODM_T pDM_Odm + ) +{ + phydm_Init_cck_setting(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); + PHYDM_InitTRXAntennaSetting(pDM_Odm); + + pDM_Odm->TxRate = 0xFF; + + pDM_Odm->number_linked_client = 0; + pDM_Odm->pre_number_linked_client = 0; + pDM_Odm->number_active_client = 0; + pDM_Odm->pre_number_active_client = 0; + phydm_hook_dummy_member(pDM_Odm); + +} + +VOID +odm_CommonInfoSelfUpdate( + IN PDM_ODM_T pDM_Odm + ) +{ + u1Byte EntryCnt = 0, num_active_client = 0; + u4Byte i, OneEntry_MACID = 0, ma_rx_tp = 0; + 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 + +/* THis variable cannot be used because it is wrong*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + 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 if (*(pDM_Odm->pBandWidth) == ODM_BW80M) { + if (*(pDM_Odm->pSecChOffset) == 1) + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) + 6; + else if (*(pDM_Odm->pSecChOffset) == 2) + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) - 6; + } else + pDM_Odm->ControlChannel = *(pDM_Odm->pChannel); +#else + 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); +#endif + + for (i=0; ipODM_StaInfo[i]; + if(IS_STA_VALID(pEntry)) + { + EntryCnt++; + if(EntryCnt==1) + { + OneEntry_MACID=i; + } + + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + ma_rx_tp = (pEntry->rx_byte_cnt_LowMAW)<<3; /* low moving average RX TP ( bit /sec)*/ + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("ClientTP[%d]: ((%d )) bit/sec\n", i, ma_rx_tp)); + + if (ma_rx_tp > ACTIVE_TP_THRESHOLD) + num_active_client++; + #endif + } + } + + if(EntryCnt == 1) + { + pDM_Odm->bOneEntryOnly = TRUE; + pDM_Odm->OneEntry_MACID=OneEntry_MACID; + } + else + pDM_Odm->bOneEntryOnly = FALSE; + + pDM_Odm->pre_number_linked_client = pDM_Odm->number_linked_client; + pDM_Odm->pre_number_active_client = pDM_Odm->number_active_client; + + pDM_Odm->number_linked_client = EntryCnt; + pDM_Odm->number_active_client = num_active_client; + + /* 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; + + case PHYDM_ADAPTIVITY: + pStruct = &(pDM_Odm->Adaptivity); + break; + + default: + break; + } + +#else + switch (Structure_Type){ + case PHYDM_FALSEALMCNT: + pStruct = &(pDM_Odm->FalseAlmCnt); + break; + + case PHYDM_CFOTRACK: + pStruct = &(pDM_Odm->DM_CfoTrack); + break; + + case PHYDM_ADAPTIVITY: + pStruct = &(pDM_Odm->Adaptivity); + 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); + phydm_ra_info_init(pDM_Odm); + odm_RateAdaptiveMaskInit(pDM_Odm); + odm_RA_ParaAdjust_init(pDM_Odm); + ODM_CfoTrackingInit(pDM_Odm); + ODM_EdcaTurboInit(pDM_Odm); + odm_RSSIMonitorInit(pDM_Odm); + phydm_rf_init(pDM_Odm); + odm_TXPowerTrackingInit(pDM_Odm); + odm_AntennaDiversityInit(pDM_Odm); + odm_AutoChannelSelectInit(pDM_Odm); + odm_PathDiversityInit(pDM_Odm); +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + phydm_Beamforming_Init(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 + +#endif + + } + +} + +VOID +ODM_DMReset( + IN PDM_ODM_T pDM_Odm + ) +{ + ODM_AntDivReset(pDM_Odm); +} + + +VOID +phydm_support_ablity_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte pre_support_ability; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + + pre_support_ability = pDM_Odm->SupportAbility ; + PHYDM_SNPRINTF((output+used, out_len-used,"\n%s\n", "================================")); + if(dm_value[0] == 100) + { + PHYDM_SNPRINTF((output+used, out_len-used, "[Supportablity] PhyDM Selection\n")); + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "================================")); + PHYDM_SNPRINTF((output+used, out_len-used, "00. (( %s ))DIG \n", ((pDM_Odm->SupportAbility & ODM_BB_DIG)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "01. (( %s ))RA_MASK \n", ((pDM_Odm->SupportAbility & ODM_BB_RA_MASK)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "02. (( %s ))DYNAMIC_TXPWR \n", ((pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "03. (( %s ))FA_CNT \n", ((pDM_Odm->SupportAbility & ODM_BB_FA_CNT)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "04. (( %s ))RSSI_MONITOR \n", ((pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "05. (( %s ))CCK_PD \n", ((pDM_Odm->SupportAbility & ODM_BB_CCK_PD)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "06. (( %s ))ANT_DIV \n", ((pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "07. (( %s ))PWR_SAVE \n", ((pDM_Odm->SupportAbility & ODM_BB_PWR_SAVE)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "08. (( %s ))PWR_TRAIN \n", ((pDM_Odm->SupportAbility & ODM_BB_PWR_TRAIN)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "09. (( %s ))RATE_ADAPTIVE \n", ((pDM_Odm->SupportAbility & ODM_BB_RATE_ADAPTIVE)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "10. (( %s ))PATH_DIV \n", ((pDM_Odm->SupportAbility & ODM_BB_PATH_DIV)?("V"):(".")))); + PHYDM_SNPRINTF((output+used, out_len-used, "11. (( %s ))PSD \n", ((pDM_Odm->SupportAbility & ODM_BB_PSD)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "12. (( %s ))RXHP \n", ((pDM_Odm->SupportAbility & ODM_BB_RXHP)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "13. (( %s ))ADAPTIVITY \n", ((pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "14. (( %s ))CFO_TRACKING \n", ((pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "15. (( %s ))NHM_CNT \n", ((pDM_Odm->SupportAbility & ODM_BB_NHM_CNT)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "16. (( %s ))PRIMARY_CCA \n", ((pDM_Odm->SupportAbility & ODM_BB_PRIMARY_CCA)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "20. (( %s ))EDCA_TURBO \n", ((pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "21. (( %s ))EARLY_MODE \n", ((pDM_Odm->SupportAbility & ODM_MAC_EARLY_MODE)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "24. (( %s ))TX_PWR_TRACK \n", ((pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "25. (( %s ))RX_GAIN_TRACK \n", ((pDM_Odm->SupportAbility & ODM_RF_RX_GAIN_TRACK)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used, "26. (( %s ))RF_CALIBRATION \n", ((pDM_Odm->SupportAbility & ODM_RF_CALIBRATION)?("V"):(".")) )); + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "================================")); + } + /* + else if(dm_value[0] == 101) + { + pDM_Odm->SupportAbility = 0 ; + DbgPrint("Disable all SupportAbility components \n"); + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "Disable all SupportAbility components")); + } + */ + else + { + + if(dm_value[1] == 1) //enable + { + pDM_Odm->SupportAbility |= BIT(dm_value[0]) ; + if(BIT(dm_value[0]) & ODM_BB_PATH_DIV) + { + odm_PathDiversityInit(pDM_Odm); + } + } + else if(dm_value[1] == 2) //disable + { + pDM_Odm->SupportAbility &= ~(BIT(dm_value[0])) ; + } + else + { + //DbgPrint("\n[Warning!!!] 1:enable, 2:disable \n\n"); + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "[Warning!!!] 1:enable, 2:disable")); + } + } + PHYDM_SNPRINTF((output+used, out_len-used,"pre-SupportAbility = 0x%x\n", pre_support_ability )); + PHYDM_SNPRINTF((output+used, out_len-used,"Curr-SupportAbility = 0x%x\n", pDM_Odm->SupportAbility )); + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n", "================================")); +} + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +// +//tmp modify for LC Only +// +VOID +ODM_DMWatchdog_LPS( + IN PDM_ODM_T pDM_Odm + ) +{ + odm_CommonInfoSelfUpdate(pDM_Odm); + odm_FalseAlarmCounterStatistics(pDM_Odm); + odm_RSSIMonitorCheck(pDM_Odm); + odm_DIGbyRSSI_LPS(pDM_Odm); + odm_CCKPacketDetectionThresh(pDM_Odm); + odm_CommonInfoSelfReset(pDM_Odm); + + if(*(pDM_Odm->pbPowerSaving)==TRUE) + return; +} +#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_CommonInfoSelfUpdate(pDM_Odm); + phydm_BasicDbgMessage(pDM_Odm); + odm_HWSetting(pDM_Odm); + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + { + prtl8192cd_priv priv = pDM_Odm->priv; + if( (priv->auto_channel != 0) && (priv->auto_channel != 2) )//if ACS running, do not do FA/CCA counter read + return; + } +#endif + odm_FalseAlarmCounterStatistics(pDM_Odm); + phydm_NoisyDetection(pDM_Odm); + + odm_RSSIMonitorCheck(pDM_Odm); + + if(*(pDM_Odm->pbPowerSaving) == TRUE) + { + odm_DIGbyRSSI_LPS(pDM_Odm); + { + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + Phydm_Adaptivity(pDM_Odm, pDM_DigTable->CurIGValue); + } + 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; + Phydm_Adaptivity(pDM_Odm, pDM_DigTable->CurIGValue); + } + odm_CCKPacketDetectionThresh(pDM_Odm); + phydm_ra_dynamic_retry_limit(pDM_Odm); + phydm_ra_dynamic_retry_count(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)) + phydm_Beamforming_Watchdog(pDM_Odm); +#endif + + phydm_rf_watchdog(pDM_Odm); + + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + +#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 +#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 = (u2Byte)Value; + break; + case ODM_CMNINFO_APA: + pDM_Odm->TypeAPA = (u2Byte)Value; + break; + case ODM_CMNINFO_GLNA: + pDM_Odm->TypeGLNA = (u2Byte)Value; + break; + case ODM_CMNINFO_ALNA: + pDM_Odm->TypeALNA = (u2Byte)Value; + break; + + case ODM_CMNINFO_EXT_TRSW: + pDM_Odm->ExtTRSW = (u1Byte)Value; + break; + case ODM_CMNINFO_EXT_LNA_GAIN: + pDM_Odm->ExtLNAGain = (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_CONFIG_BB_RF: + pDM_Odm->ConfigBBRF = (BOOLEAN)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.bP2PInProcess = (u1Byte *)pValue; + break; + + case ODM_CMNINFO_IS1ANTENNA: + pDM_Odm->pIs1Antenna = (BOOLEAN *)pValue; + break; + + case ODM_CMNINFO_RFDEFAULTPATH: + pDM_Odm->pRFDefaultPath= (u1Byte *)pValue; + break; + + case ODM_CMNINFO_FCS_MODE: + pDM_Odm->pIsFcsModeEnable = (BOOLEAN *)pValue; + break; + /*add by YuChen for beamforming PhyDM*/ + case ODM_CMNINFO_HUBUSBMODE: + pDM_Odm->HubUsbMode = (u1Byte *)pValue; + break; + case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS: + pDM_Odm->pbFwDwRsvdPageInProgress = (BOOLEAN *)pValue; + break; + case ODM_CMNINFO_TX_TP: + pDM_Odm->pCurrentTxTP = (u4Byte *)pValue; + break; + case ODM_CMNINFO_RX_TP: + pDM_Odm->pCurrentRxTP = (u4Byte *)pValue; + break; + case ODM_CMNINFO_SOUNDING_SEQ: + pDM_Odm->pSoundingSeq = (u1Byte *)pValue; + break; + //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; + + if (IS_STA_VALID(pDM_Odm->pODM_StaInfo[Index])) + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pDM_Odm->platform2phydm_macid_table[((PSTA_INFO_T)pValue)->AssociatedMacId] = Index; /*AssociatedMacId are unique bttween different Adapter*/ + #elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + pDM_Odm->platform2phydm_macid_table[((PSTA_INFO_T)pValue)->aid] = Index; + #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + pDM_Odm->platform2phydm_macid_table[((PSTA_INFO_T)pValue)->mac_id] = Index; + #endif + + 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; +#if defined(BT_30_SUPPORT) && (BT_30_SUPPORT == 1) + // 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_DIG: + pDM_Odm->btHsDigVal = (u1Byte)Value; + break; + + case ODM_CMNINFO_BT_BUSY: + pDM_Odm->bBtBusy = (BOOLEAN)Value; + break; + + case ODM_CMNINFO_BT_DISABLE_EDCA: + pDM_Odm->bBtDisableEdcaTurbo = (BOOLEAN)Value; + break; +#endif + +#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_AP_TOTAL_NUM: + pDM_Odm->APTotalNum = (u1Byte)Value; + break; + + case ODM_CMNINFO_POWER_TRAINING: + pDM_Odm->bDisablePowerTraining = (BOOLEAN)Value; + break; + +/* + 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 ) +{ + + PADAPTER pAdapter = pDM_Odm->Adapter; +#if USE_WORKITEM + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + ODM_InitializeWorkItem( pDM_Odm, + &pDM_Odm->DM_SWAT_Table.phydm_SwAntennaSwitchWorkitem, + (RT_WORKITEM_CALL_BACK)ODM_SW_AntDiv_WorkitemCallback, + (PVOID)pAdapter, + "AntennaSwitchWorkitem"); + #endif + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + ODM_InitializeWorkItem(pDM_Odm, + &pDM_Odm->dm_sat_table.hl_smart_antenna_workitem, + (RT_WORKITEM_CALL_BACK)phydm_beam_switch_workitem_callback, + (PVOID)pAdapter, + "hl_smart_ant_workitem"); + + ODM_InitializeWorkItem(pDM_Odm, + &pDM_Odm->dm_sat_table.hl_smart_antenna_decision_workitem, + (RT_WORKITEM_CALL_BACK)phydm_beam_decision_workitem_callback, + (PVOID)pAdapter, + "hl_smart_ant_decision_workitem"); + #endif + + 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_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->FastAntTrainingWorkitem), + (RT_WORKITEM_CALL_BACK)odm_FastAntTrainingWorkItemCallback, + (PVOID)pAdapter, + "FastAntTrainingWorkitem"); +#endif + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->DM_RXHP_Table.PSDTimeWorkitem), + (RT_WORKITEM_CALL_BACK)odm_PSD_RXHPWorkitemCallback, + (PVOID)pAdapter, + "PSDRXHP_WorkItem"); + +#endif /*#if USE_WORKITEM*/ + +#if (BEAMFORMING_SUPPORT == 1) + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_EnterWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_EnterWorkItemCallback, + (PVOID)pAdapter, + "Txbf_EnterWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_LeaveWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_LeaveWorkItemCallback, + (PVOID)pAdapter, + "Txbf_LeaveWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_FwNdpaWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_FwNdpaWorkItemCallback, + (PVOID)pAdapter, + "Txbf_FwNdpaWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_ClkWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_ClkWorkItemCallback, + (PVOID)pAdapter, + "Txbf_ClkWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_RateWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_RateWorkItemCallback, + (PVOID)pAdapter, + "Txbf_RateWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_StatusWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_StatusWorkItemCallback, + (PVOID)pAdapter, + "Txbf_StatusWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_ResetTxPathWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_ResetTxPathWorkItemCallback, + (PVOID)pAdapter, + "Txbf_ResetTxPathWorkItem"); + + ODM_InitializeWorkItem( + pDM_Odm, + &(pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_GetTxRateWorkItem), + (RT_WORKITEM_CALL_BACK)halComTxbf_GetTxRateWorkItemCallback, + (PVOID)pAdapter, + "Txbf_GetTxRateWorkItem"); +#endif +} + +VOID +ODM_FreeAllWorkItems(IN PDM_ODM_T pDM_Odm ) +{ +#if USE_WORKITEM + +#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + ODM_FreeWorkItem(&(pDM_Odm->DM_SWAT_Table.phydm_SwAntennaSwitchWorkitem)); +#endif + +#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + ODM_FreeWorkItem(&(pDM_Odm->dm_sat_table.hl_smart_antenna_workitem)); + ODM_FreeWorkItem(&(pDM_Odm->dm_sat_table.hl_smart_antenna_decision_workitem)); +#endif + + ODM_FreeWorkItem(&(pDM_Odm->PathDivSwitchWorkitem)); + ODM_FreeWorkItem(&(pDM_Odm->CCKPathDiversityWorkitem)); +#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + ODM_FreeWorkItem(&(pDM_Odm->FastAntTrainingWorkitem)); +#endif + ODM_FreeWorkItem(&(pDM_Odm->MPT_DIGWorkitem)); + ODM_FreeWorkItem(&(pDM_Odm->RaRptWorkitem)); + ODM_FreeWorkItem((&pDM_Odm->DM_RXHP_Table.PSDTimeWorkitem)); + /*ODM_FreeWorkItem((&pDM_Odm->sbdcnt_workitem));*/ +#endif + +#if (BEAMFORMING_SUPPORT == 1) + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_EnterWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_LeaveWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_FwNdpaWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_ClkWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_RateWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_StatusWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_ResetTxPathWorkItem)); + ODM_FreeWorkItem((&pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_GetTxRateWorkItem)); +#endif + +} +#endif /*#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)*/ + +/* +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; +} +*/ + +VOID +ODM_InitAllTimers( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,INIT_ANTDIV_TIMMER); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#ifdef MP_TEST + if (pDM_Odm->priv->pshare->rf_ft_var.mp_specific) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer, + (RT_TIMER_CALL_BACK)odm_MPT_DIGCallback, NULL, "MPT_DIGTimer"); +#endif +#elif(DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer, + (RT_TIMER_CALL_BACK)odm_MPT_DIGCallback, NULL, "MPT_DIGTimer"); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->PSDTimer, + (RT_TIMER_CALL_BACK)dm_PSDMonitorCallback, NULL, "PSDTimer"); + 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->DM_RXHP_Table.PSDTimer, + (RT_TIMER_CALL_BACK)odm_PSD_RXHPCallback, NULL, "PSDRXHPTimer"); + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->sbdcnt_timer, + (RT_TIMER_CALL_BACK)phydm_sbd_callback, NULL, "SbdTimer"); +#if (BEAMFORMING_SUPPORT == 1) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_FwNdpaTimer, + (RT_TIMER_CALL_BACK)halComTxbf_FwNdpaTimerCallback, NULL, "Txbf_FwNdpaTimer"); +#endif +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (BEAMFORMING_SUPPORT == 1) + ODM_InitializeTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.BeamformingTimer, + (RT_TIMER_CALL_BACK)Beamforming_SWTimerCallback, NULL, "BeamformingTimer"); +#endif +#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_PHYDM_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,CANCEL_ANTDIV_TIMMER); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#ifdef MP_TEST + if (pDM_Odm->priv->pshare->rf_ft_var.mp_specific) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); +#endif +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->PSDTimer); + 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); + ODM_CancelTimer(pDM_Odm, &pDM_Odm->sbdcnt_timer); +#if (BEAMFORMING_SUPPORT == 1) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_FwNdpaTimer); +#endif +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (BEAMFORMING_SUPPORT == 1) + ODM_CancelTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.BeamformingTimer); +#endif +#endif + +} + + +VOID +ODM_ReleaseAllTimers( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + ODM_AntDivTimers(pDM_Odm,RELEASE_ANTDIV_TIMMER); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + #ifdef MP_TEST + if (pDM_Odm->priv->pshare->rf_ft_var.mp_specific) + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); + #endif +#elif(DM_ODM_SUPPORT_TYPE == ODM_WIN) +ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->MPT_DIGTimer); +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->PSDTimer); + 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); + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->sbdcnt_timer); +#if (BEAMFORMING_SUPPORT == 1) + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.TxbfInfo.Txbf_FwNdpaTimer); +#endif +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (BEAMFORMING_SUPPORT == 1) + ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->BeamformingInfo.BeamformingTimer); +#endif +#endif +} + + +//3============================================================ +//3 Tx Power Tracking +//3============================================================ + + + + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +VOID +ODM_InitAllThreads( + IN PDM_ODM_T pDM_Odm + ) +{ + #ifdef TPT_THREAD + kTPT_task_init(pDM_Odm->priv); + #endif +} + +VOID +ODM_StopAllThreads( + IN PDM_ODM_T pDM_Odm + ) +{ + #ifdef TPT_THREAD + kTPT_task_stop(pDM_Odm->priv); + #endif +} +#endif + + +#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\n")); + 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; +} +#elif( DM_ODM_SUPPORT_TYPE == ODM_AP) +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,COMP_INIT, 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,COMP_INIT, 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) (odm_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; + +} +#endif + +u4Byte +odm_ConvertTo_dB( + u4Byte Value) +{ + u1Byte i; + u1Byte j; + u4Byte dB; + + Value = Value & 0xFFFF; + + for (i = 0; i < 12; i++) + { + if (Value <= dB_Invert_Table[i][7]) + { + break; + } + } + + if (i >= 12) + { + return (96); // maximum 96 dB + } + + for (j = 0; j < 8; j++) + { + if (Value <= dB_Invert_Table[i][j]) + { + break; + } + } + + dB = (i << 3) + j + 1; + + return (dB); +} + +u4Byte +odm_ConvertTo_linear( + u4Byte Value) +{ + u1Byte i; + u1Byte j; + u4Byte linear; + + /* 1dB~96dB */ + + Value = Value & 0xFF; + + i = (u1Byte)((Value - 1) >> 3); + j = (u1Byte)(Value - 1) - (i << 3); + + linear = dB_Invert_Table[i][j]; + + return (linear); +} + +#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 + +// +// 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 +} + + + +/*===========================================================*/ +/* The following is for compile only*/ +/*===========================================================*/ +/*#define TARGET_CHNL_NUM_2G_5G 59*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +u1Byte GetRightChnlPlaceforIQK(u1Byte chnl) +{ + u1Byte channel_all[TARGET_CHNL_NUM_2G_5G] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 100, + 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159, 161, 163, 165}; + u1Byte place = chnl; + + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) { + if (channel_all[place] == chnl) + return place-13; + } + } + + return 0; +} + +VOID +FillH2CCmd92C( + IN PADAPTER Adapter, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +) +{} +VOID +PHY_SetTxPowerLevel8192C( + IN PADAPTER Adapter, + IN u1Byte channel + ) +{ +} +#endif +/*===========================================================*/ + +VOID +phydm_NoisyDetection( + IN PDM_ODM_T pDM_Odm + ) +{ + u4Byte Total_FA_Cnt, Total_CCA_Cnt; + u4Byte Score = 0, i, Score_Smooth; + + Total_CCA_Cnt = pDM_Odm->FalseAlmCnt.Cnt_CCA_all; + Total_FA_Cnt = pDM_Odm->FalseAlmCnt.Cnt_all; + +/* + if( Total_FA_Cnt*16>=Total_CCA_Cnt*14 ) // 87.5 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*12 ) // 75 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*10 ) // 56.25 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*8 ) // 50 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*7 ) // 43.75 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*6 ) // 37.5 + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*5 ) // 31.25% + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*4 ) // 25% + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*3 ) // 18.75% + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*2 ) // 12.5% + + else if( Total_FA_Cnt*16>=Total_CCA_Cnt*1 ) // 6.25% +*/ + for(i=0;i<=16;i++) + { + if( Total_FA_Cnt*16>=Total_CCA_Cnt*(16-i) ) + { + Score = 16-i; + break; + } + } + + // NoisyDecision_Smooth = NoisyDecision_Smooth>>1 + (Score<<3)>>1; + pDM_Odm->NoisyDecision_Smooth = (pDM_Odm->NoisyDecision_Smooth>>1) + (Score<<2); + + // Round the NoisyDecision_Smooth: +"3" comes from (2^3)/2-1 + Score_Smooth = (Total_CCA_Cnt>=300)?((pDM_Odm->NoisyDecision_Smooth+3)>>3):0; + + pDM_Odm->NoisyDecision = (Score_Smooth>=3)?1:0; +/* + switch(Score_Smooth) + { + case 0: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=0%%\n")); + break; + case 1: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=6.25%%\n")); + break; + case 2: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=12.5%%\n")); + break; + case 3: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=18.75%%\n")); + break; + case 4: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=25%%\n")); + break; + case 5: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=31.25%%\n")); + break; + case 6: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=37.5%%\n")); + break; + case 7: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=43.75%%\n")); + break; + case 8: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=50%%\n")); + break; + case 9: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=56.25%%\n")); + break; + case 10: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=62.5%%\n")); + break; + case 11: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=68.75%%\n")); + break; + case 12: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=75%%\n")); + break; + case 13: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=81.25%%\n")); + break; + case 14: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=87.5%%\n")); + break; + case 15: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=93.75%%\n")); + break; + case 16: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Total_FA_Cnt/Total_CCA_Cnt=100%%\n")); + break; + default: + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("[NoisyDetection] Unknown Value!! Need Check!!\n")); + } +*/ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_NOISY_DETECT, ODM_DBG_LOUD, + ("[NoisyDetection] Total_CCA_Cnt=%d, Total_FA_Cnt=%d, NoisyDecision_Smooth=%d, Score=%d, Score_Smooth=%d, pDM_Odm->NoisyDecision=%d\n", + Total_CCA_Cnt, Total_FA_Cnt, pDM_Odm->NoisyDecision_Smooth, Score, Score_Smooth, pDM_Odm->NoisyDecision)); + +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.h new file mode 100644 index 00000000..0e8b88e2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm.h @@ -0,0 +1,1448 @@ +/****************************************************************************** + * + * 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_pre_define.h" +#include "phydm_dig.h" +#include "phydm_edcaturbocheck.h" +#include "phydm_pathdiv.h" +#include "phydm_antdiv.h" +#include "phydm_antdect.h" +#include "phydm_dynamicbbpowersaving.h" +#include "phydm_rainfo.h" +#include "phydm_dynamictxpower.h" +#include "phydm_cfotracking.h" +#include "phydm_acs.h" +#include "phydm_adaptivity.h" + + +#if (RTL8814A_SUPPORT == 1) +#include "rtl8814a/phydm_iqk_8814a.h" +#endif + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#include "halphyrf_ap.h" +#include "phydm_powertracking_ap.h" +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) +#include "phydm_beamforming.h" +#include "phydm_noisemonitor.h" +#include "halphyrf_ce.h" +#include "phydm_powertracking_ce.h" +#endif + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +#include "phydm_beamforming.h" +#include "phydm_rxhp.h" +#include "halphyrf_win.h" +#include "phydm_powertracking_win.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. +// + +//For SW AntDiv, PathDiv, 8192C AntDiv joint use +#define TP_MODE 0 +#define RSSI_MODE 1 + +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 +#define TRAFFIC_ULTRA_LOW 2 +#define TRAFFIC_MID 3 + + +#define NONE 0 + + + + +//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 + + +//============================================================ +// 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 + +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; + + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + + +#ifdef ADSL_AP_BUILD_WORKAROUND +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms +#endif +#if 0//defined in 8192cd.h +// +// 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 +#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 IQK_THRESHOLD 8 +#define DPK_THRESHOLD 4 + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +__PACK typedef struct _ODM_Phy_Status_Info_ +{ + u1Byte RxPWDBAll; + u1Byte SignalQuality; /* in 0-100 index. */ + u1Byte RxMIMOSignalStrength[4]; /* in 0~100 index */ + s1Byte RxMIMOSignalQuality[4]; /* EVM */ + s1Byte RxSNR[4]; /* per-path's SNR */ +#if (RTL8822B_SUPPORT == 1) + u1Byte RxCount; /* RX path counter---*/ +#endif + u1Byte BandWidth; + +} __WLAN_ATTRIB_PACK__ ODM_PHY_INFO_T, *PODM_PHY_INFO_T; + +typedef struct _ODM_Phy_Status_Info_Append_ +{ + u1Byte MAC_CRC32; + +}ODM_PHY_INFO_Append_T,*PODM_PHY_INFO_Append_T; + +#else + +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 */ + s2Byte Cfo_short[4]; /* per-path's Cfo_short */ + s2Byte Cfo_tail[4]; /* per-path's Cfo_tail */ + 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 */ + s1Byte RxSNR[4]; /* per-path's SNR */ +#if (RTL8822B_SUPPORT == 1) + u1Byte RxCount:2; /* RX path counter---*/ + u1Byte BandWidth:2; + u1Byte rxsc:4; /* sub-channel---*/ +#else + u1Byte BandWidth; +#endif + u1Byte btCoexPwrAdjust; +#if (RTL8822B_SUPPORT == 1) + u1Byte channel; /* channel number---*/ + BOOLEAN bMuPacket; /* is MU packet or not---*/ + BOOLEAN bBeamformed; /* BF packet---*/ +#endif +}ODM_PHY_INFO_T,*PODM_PHY_INFO_T; +#endif + +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; +#if (RTL8822B_SUPPORT == 1) + u4Byte NumQryMuPkt; + u4Byte NumQryBfPkt; +#endif + u1Byte NumQryBeaconPkt; + //Others + s4Byte RxEVM[4]; + +}ODM_PHY_DBG_INFO_T; + + +typedef struct _ODM_Mac_Status_Info_ +{ + u1Byte test; + +}ODM_MAC_INFO; + +// +// 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_EXT_LNA_GAIN, + ODM_CMNINFO_PATCH_ID, //CUSTOMER ID + ODM_CMNINFO_BINHCT_TEST, + ODM_CMNINFO_BWIFI_TEST, + ODM_CMNINFO_SMART_CONCURRENT, + ODM_CMNINFO_CONFIG_BB_RF, + ODM_CMNINFO_DOMAIN_CODE_2G, + ODM_CMNINFO_DOMAIN_CODE_5G, + ODM_CMNINFO_IQKFWOFFLOAD, + ODM_CMNINFO_HUBUSBMODE, + ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS, + ODM_CMNINFO_TX_TP, + ODM_CMNINFO_RX_TP, + ODM_CMNINFO_SOUNDING_SEQ, + //-----------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_DIG, + ODM_CMNINFO_BT_BUSY, //Check Bt is using or not//neil + ODM_CMNINFO_BT_DISABLE_EDCA, +#if(DM_ODM_SUPPORT_TYPE & ODM_AP) // for repeater mode add by YuChen 2014.06.23 +#ifdef UNIVERSAL_REPEATER + ODM_CMNINFO_VXD_LINK, +#endif +#endif + ODM_CMNINFO_AP_TOTAL_NUM, + ODM_CMNINFO_POWER_TRAINING, +//------------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, + ODM_BB_TXBF = BIT17, + + // + // 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; + +//Move some non-DM enum,define, struc. form phydm.h to phydm_types.h by Dino + +// 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; + +//move RAInfo to Phydm_RaInfo.h + +//Remove struct PATHDIV_PARA to odm_PathDiv.h + +//Remove struct to odm_PowerTracking.h by YuChen +// +// ODM Dynamic common info value definition +// +//Move AntDiv form phydm.h to Phydm_AntDiv.h by Dino + +//move PathDiv to Phydm_PathDiv.h + +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; + +// +// 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; + u2Byte TypeGLNA; + u2Byte TypeGPA; + u2Byte TypeALNA; + u2Byte TypeAPA; + // with external LNA NO/Yes = 0/1 + u1Byte ExtLNA; // 2G + u1Byte ExtLNA5G; //5G + // with external PA NO/Yes = 0/1 + u1Byte ExtPA; // 2G + u1Byte ExtPA5G; //5G + // with external TRSW NO/Yes = 0/1 + u1Byte ExtTRSW; + u1Byte ExtLNAGain; // 2G + u1Byte PatchID; //Customer ID + BOOLEAN bInHctTest; + BOOLEAN bWIFITest; + + BOOLEAN bDualMacSmartConcurrent; + u4Byte BK_SupportAbility; + u1Byte AntDivType; + BOOLEAN ConfigBBRF; + 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; + pu1Byte HubUsbMode; + BOOLEAN *pbFwDwRsvdPageInProgress; + u4Byte *pCurrentTxTP; + u4Byte *pCurrentRxTP; + u1Byte *pSoundingSeq; +//------------CALL BY VALUE-------------// + BOOLEAN bLinkInProcess; + BOOLEAN bWIFI_Direct; + BOOLEAN bWIFI_Display; + BOOLEAN bLinked; + BOOLEAN bsta_state; +#if(DM_ODM_SUPPORT_TYPE & ODM_AP) // for repeater mode add by YuChen 2014.06.23 +#ifdef UNIVERSAL_REPEATER + BOOLEAN VXD_bLinked; +#endif +#endif // for repeater mode add by YuChen 2014.06.23 + u1Byte RSSI_Min; + u1Byte InterfaceIndex; /*Add for 92D dual MAC: 0--Mac0 1--Mac1*/ + BOOLEAN bIsMPChip; + BOOLEAN bOneEntryOnly; + BOOLEAN mp_mode; + u4Byte OneEntry_MACID; + u1Byte pre_number_linked_client; + u1Byte number_linked_client; + u1Byte pre_number_active_client; + u1Byte number_active_client; + // 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 + u1Byte btHsDigVal; // use BT rssi to decide the DIG value + BOOLEAN bBtDisableEdcaTurbo; // Under some condition, don't enable the EDCA Turbo + BOOLEAN bBtBusy; // BT is busy. + BOOLEAN bBtLimitedDig; // BT is busy. + BOOLEAN bDisablePhyApi; +//------------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 TXAntStatus; + u1Byte RXAntStatus; + u1Byte cck_lna_idx; + u1Byte cck_vga_idx; + u1Byte ofdm_agc_idx[4]; + + u1Byte RxRate; + BOOLEAN bNoisyState; + u1Byte TxRate; + u1Byte LinkedInterval; + u1Byte preChannel; + u4Byte TxagcOffsetValueA; + BOOLEAN IsTxagcOffsetPositiveA; + u4Byte TxagcOffsetValueB; + BOOLEAN IsTxagcOffsetPositiveB; + u4Byte tx_tp; + u4Byte rx_tp; + u4Byte total_tp; + u8Byte curTxOkCnt; + u8Byte curRxOkCnt; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u4Byte BbSwingOffsetA; + BOOLEAN IsBbSwingOffsetPositiveA; + u4Byte BbSwingOffsetB; + BOOLEAN IsBbSwingOffsetPositiveB; + u1Byte antdiv_rssi; + u1Byte fat_comb_a; + u1Byte fat_comb_b; + u1Byte antdiv_intvl; + u1Byte AntType; + u1Byte pre_AntType; + u1Byte antdiv_period; + u1Byte antdiv_select; + u1Byte path_select; + u1Byte antdiv_evm_en; + u1Byte bdc_holdstate; + u1Byte NdpaPeriod; + BOOLEAN H2C_RARpt_connect; + BOOLEAN cck_agc_report_type; + + u1Byte dm_dig_max_TH; + u1Byte dm_dig_min_TH; + u1Byte print_agc; + u1Byte TrafficLoad; + u1Byte pre_TrafficLoad; + + + //For Adaptivtiy + u2Byte NHM_cnt_0; + u2Byte NHM_cnt_1; + s1Byte TH_L2H_default; + s1Byte TH_EDCCA_HL_diff_default; + s1Byte TH_L2H_ini; + s1Byte TH_EDCCA_HL_diff; + s1Byte TH_L2H_ini_mode2; + s1Byte TH_EDCCA_HL_diff_mode2; + BOOLEAN Carrier_Sense_enable; + u1Byte Adaptivity_IGI_upper; + BOOLEAN adaptivity_flag; + u1Byte DCbackoff; + BOOLEAN Adaptivity_enable; + u1Byte APTotalNum; + BOOLEAN EDCCA_enable; + ADAPTIVITY_STATISTICS Adaptivity; + //For Adaptivtiy + u1Byte LastUSBHub; + u1Byte TxBfDataRate; + + u1Byte c2h_cmd_start; + u1Byte fw_debug_trace[60]; + u1Byte pre_c2h_seq; + BOOLEAN fw_buff_is_enpty; + u4Byte data_frame_num; + + /*for noise detection*/ + BOOLEAN NoisyDecision; /*b_noisy*/ + BOOLEAN pre_b_noisy; + u4Byte NoisyDecision_Smooth; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + ODM_NOISE_MONITOR noise_level;//[ODM_MAX_CHANNEL_NUM]; +#endif + // + //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]; + u2Byte platform2phydm_macid_table[ODM_ASSOCIATE_ENTRY_NUM]; /* platform_macid_table[platform_macid] = phydm_macid */ + +#if (RATE_ADAPTIVE_SUPPORT == 1) + u2Byte CurrminRptTime; + ODM_RA_INFO_T RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; //Use MacID as array index. STA MacID=0, VWiFi Client MacID={1, ODM_ASSOCIATE_ENTRY_NUM-1} //YJ,add,120119 +#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 + // +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + BDC_T DM_BdcTable; + #endif + + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + SAT_T dm_sat_table; + #endif + +#endif + 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; + SWAT_T DM_SWAT_Table; + CFO_TRACKING DM_CfoTrack; + ACS DM_ACS; + + +#if (RTL8814A_SUPPORT == 1) + IQK_INFO IQK_info; +#endif /* (RTL8814A_SUPPORT==1) */ + + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + //Path Div Struct + PATHDIV_PARA pathIQK; +#endif +#if(defined(CONFIG_PATH_DIVERSITY)) + PATHDIV_T DM_PathDiv; +#endif + + EDCA_T DM_EDCA_Table; + u4Byte WMMEDCA_BE; + + // 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. + + 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; +//#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if(defined(CONFIG_ANT_DETECTION)) + ANT_DETECTED_INFO AntDetectedInfo; // Antenna detected information for RSSI tool +#endif + ODM_RF_CAL_T RFCalibrateInfo; + + + // + // Dynamic ATC switch + // + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + // + // Power Training + // + u1Byte ForcePowerTrainingState; + BOOLEAN bChangeState; + u4Byte PT_score; + u8Byte OFDM_RX_Cnt; + u8Byte CCK_RX_Cnt; +#endif + BOOLEAN bDisablePowerTraining; + + // + // ODM system resource. + // + + // ODM relative time. + RT_TIMER PathDivSwitchTimer; + //2011.09.27 add for Path Diversity + RT_TIMER CCKPathDiversityTimer; + RT_TIMER FastAntTrainingTimer; +#ifdef ODM_EVM_ENHANCE_ANTDIV + RT_TIMER EVM_FastAntTrainingTimer; +#endif + RT_TIMER sbdcnt_timer; + + // 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; + RT_WORK_ITEM sbdcnt_workitem; +#endif +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +#if (BEAMFORMING_SUPPORT == 1) + RT_BEAMFORMING_INFO BeamformingInfo; +#endif +#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 + + +typedef enum _PHYDM_STRUCTURE_TYPE{ + PHYDM_FALSEALMCNT, + PHYDM_CFOTRACK, + PHYDM_ADAPTIVITY, + PHYDM_ROMINFO, + +}PHYDM_STRUCTURE_TYPE; + + + + 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_AP_2, + 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=========================================================== + + + +//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; + + +// +// Extern Global Variables. +// +//PowerTracking move to odm_powerTrakcing.h 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 + +//Remove DIG by yuchen + +//Remove BB power saving by Yuchen + +//remove PT 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 + + + +u4Byte odm_ConvertTo_dB(u4Byte Value); + +u4Byte odm_ConvertTo_linear(u4Byte Value); + +#if((DM_ODM_SUPPORT_TYPE==ODM_WIN)||(DM_ODM_SUPPORT_TYPE==ODM_CE)) + +u4Byte +GetPSDData( + PDM_ODM_T pDM_Odm, + unsigned int point, + u1Byte initial_gain_psd); + +#endif + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +VOID +ODM_DMWatchdog_LPS( + IN PDM_ODM_T pDM_Odm +); +#endif + + +s4Byte +ODM_PWdB_Conversion( + IN s4Byte X, + IN u4Byte TotalBit, + IN u4Byte DecimalBit + ); + +s4Byte +ODM_SignConversion( + IN s4Byte value, + IN u4Byte TotalBit + ); + +VOID +ODM_DMInit( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_DMReset( + IN PDM_ODM_T pDM_Odm + ); + +VOID +phydm_support_ablity_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ); + +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 + ); + +#if(DM_ODM_SUPPORT_TYPE==ODM_AP) +VOID +ODM_InitAllThreads( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_StopAllThreads( + IN PDM_ODM_T pDM_Odm + ); +#endif + +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 + ); + + + + +#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 ); + + + +u8Byte +PlatformDivision64( + IN u8Byte x, + IN u8Byte y +); + +//==================================================== +//3 PathDiV End +//==================================================== + + +#define DM_ChangeDynamicInitGainThresh ODM_ChangeDynamicInitGainThresh +//void ODM_ChangeDynamicInitGainThresh(IN PADAPTER pAdapter, +// IN INT32 DM_Type, +// IN INT32 DM_Value); +// +// PathDiveristy Remove by RS_James + +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) + +VOID +ODM_AsocEntry_Init( + 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_WIN) ||(DM_ODM_SUPPORT_TYPE == ODM_CE) +/*===========================================================*/ +/* The following is for compile only*/ +/*===========================================================*/ + +#define IS_HARDWARE_TYPE_8723A(_Adapter) FALSE +#define IS_HARDWARE_TYPE_8723AE(_Adapter) FALSE +#define IS_HARDWARE_TYPE_8192C(_Adapter) FALSE +#define IS_HARDWARE_TYPE_8192D(_Adapter) FALSE +#define RF_T_METER_92D 0x42 + + +#define SET_TX_DESC_ANTSEL_A_92C(__pTxDesc, __Value) SET_BITS_TO_LE_1BYTE(__pTxDesc+8+3, 0, 1, __Value) +#define SET_TX_DESC_TX_ANTL_92C(__pTxDesc, __Value) SET_BITS_TO_LE_1BYTE(__pTxDesc+8+3, 4, 2, __Value) +#define SET_TX_DESC_TX_ANT_HT_92C(__pTxDesc, __Value) SET_BITS_TO_LE_1BYTE(__pTxDesc+8+3, 6, 2, __Value) +#define SET_TX_DESC_TX_ANT_CCK_92C(__pTxDesc, __Value) SET_BITS_TO_LE_1BYTE(__pTxDesc+8+3, 2, 2, __Value) + +#define GET_RX_STATUS_DESC_RX_MCS(__pRxStatusDesc) LE_BITS_TO_1BYTE( __pRxStatusDesc+12, 0, 6) + +#define RX_HAL_IS_CCK_RATE_92C(pDesc)\ + (GET_RX_STATUS_DESC_RX_MCS(pDesc) == DESC_RATE1M ||\ + GET_RX_STATUS_DESC_RX_MCS(pDesc) == DESC_RATE2M ||\ + GET_RX_STATUS_DESC_RX_MCS(pDesc) == DESC_RATE5_5M ||\ + GET_RX_STATUS_DESC_RX_MCS(pDesc) == DESC_RATE11M) + +#define H2C_92C_PSD_RESULT 16 + +#define rConfig_ram64x16 0xb2c + +#define TARGET_CHNL_NUM_2G_5G 59 +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +FillH2CCmd92C( + IN PADAPTER Adapter, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +); +VOID +PHY_SetTxPowerLevel8192C( + IN PADAPTER Adapter, + IN u1Byte channel + ); +u1Byte GetRightChnlPlaceforIQK(u1Byte chnl); + +#endif + +//=========================================================== +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +void odm_dtc(PDM_ODM_T pDM_Odm); +#endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_CE) */ + + +VOID phydm_NoisyDetection(IN PDM_ODM_T pDM_Odm ); + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.c new file mode 100644 index 00000000..4b607ce0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.c @@ -0,0 +1,1306 @@ +/****************************************************************************** + * + * 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 +} + +#if ( DM_ODM_SUPPORT_TYPE & ODM_AP ) + +VOID +phydm_AutoChannelSelectSettingAP( + IN PVOID pDM_VOID, + IN u4Byte setting, // 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING + IN u4Byte acs_step +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + PACS pACS = &pDM_Odm->DM_ACS; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSettingAP()=========> \n")); + + //3 Store Default Setting + if(setting == STORE_DEFAULT_NHM_SETTING) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("STORE_DEFAULT_NHM_SETTING\n")); + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0 + { + pACS->Reg0x990 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC); // Reg0x990 + pACS->Reg0x994 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC); // Reg0x994 + pACS->Reg0x998 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC); // Reg0x998 + pACS->Reg0x99C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC); // Reg0x99c + pACS->Reg0x9A0 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC); // Reg0x9a0, u1Byte + } + else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + pACS->Reg0x890 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N); // Reg0x890 + pACS->Reg0x894 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N); // Reg0x894 + pACS->Reg0x898 = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N); // Reg0x898 + pACS->Reg0x89C = ODM_Read4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N); // Reg0x89c + pACS->Reg0xE28 = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N); // Reg0xe28, u1Byte + } + } + + //3 Restore Default Setting + else if(setting == RESTORE_DEFAULT_NHM_SETTING) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("RESTORE_DEFAULT_NHM_SETTING\n")); + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) // store Reg0x990, Reg0x994, Reg0x998, Reg0x99C, Reg0x9a0 + { + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC, pACS->Reg0x990); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, pACS->Reg0x994); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, pACS->Reg0x998); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, pACS->Reg0x99C); + ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC, pACS->Reg0x9A0); + } + else if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, pACS->Reg0x890); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N, pACS->Reg0x894); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, pACS->Reg0x898); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, pACS->Reg0x89C); + ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N, pACS->Reg0xE28); + } + } + + //3 ACS Setting + else if(setting == ACS_NHM_SETTING) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("ACS_NHM_SETTING\n")); + u2Byte period; + period = 0x61a8; + pACS->ACS_Step = acs_step; + + if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + //4 Set NHM period, 0x990[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC+2, period); + //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0 + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC,BIT8|BIT9|BIT10, 3); + + if(pACS->ACS_Step == 0) + { + //4 Set IGI + ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E); + if (get_rf_mimo_mode(priv) != MIMO_1T1R) + ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E); + + //4 Set ACS NHM threshold + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x82786e64); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff8c); + ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11AC, 0xff); + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC+2, 0xffff); + + } + else if(pACS->ACS_Step == 1) + { + //4 Set IGI + ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A); + if (get_rf_mimo_mode(priv) != MIMO_1T1R) + ODM_SetBBReg(pDM_Odm,0xe50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A); + + //4 Set ACS NHM threshold + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x5a50463c); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff64); + + } + + } + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + //4 Set NHM period, 0x894[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, period); + //4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0 + ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N,BIT8|BIT9|BIT10, 3); + + if(pACS->ACS_Step == 0) + { + //4 Set IGI + ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E); + if (get_rf_mimo_mode(priv) != MIMO_1T1R) + ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x3E); + + //4 Set ACS NHM threshold + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x82786e64); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff8c); + ODM_Write1Byte(pDM_Odm, ODM_REG_NHM_TH8_11N, 0xff); + ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); + + } + else if(pACS->ACS_Step == 1) + { + //4 Set IGI + ODM_SetBBReg(pDM_Odm,0xc50,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A); + if (get_rf_mimo_mode(priv) != MIMO_1T1R) + ODM_SetBBReg(pDM_Odm,0xc58,BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6,0x2A); + + //4 Set ACS NHM threshold + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x5a50463c); + ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff64); + + } + } + } + +} + +VOID +phydm_GetNHMStatisticsAP( + IN PVOID pDM_VOID, + IN u4Byte idx, // @ 2G, Real channel number = idx+1 + IN u4Byte acs_step +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + prtl8192cd_priv priv = pDM_Odm->priv; + PACS pACS = &pDM_Odm->DM_ACS; + u4Byte value32 = 0; + u1Byte i; + + pACS->ACS_Step = acs_step; + + if(pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + { + //4 Check if NHM result is ready + for (i=0; i<20; i++) { + + ODM_delay_ms(1); + if ( ODM_GetBBReg(pDM_Odm,rFPGA0_PSDReport,BIT17) ) + break; + } + + //4 Get NHM Statistics + if ( pACS->ACS_Step==1 ) { + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11N); + + pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8; + pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0); + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N); // ODM_REG_NHM_CNT3_TO_CNT0_11N + + pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24; + pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16; + pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8; + + } else if (pACS->ACS_Step==2) { + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11N); // ODM_REG_NHM_CNT3_TO_CNT0_11N + + pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11N); + pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24; + pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16; + pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8; + pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0); + } + } + else if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + { + //4 Check if NHM result is ready + for (i=0; i<20; i++) { + + ODM_delay_ms(1); + if (ODM_GetBBReg(pDM_Odm,ODM_REG_NHM_DUR_READY_11AC,BIT17)) + break; + } + + if ( pACS->ACS_Step==1 ) { + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT7_TO_CNT4_11AC); + + pACS->NHM_Cnt[idx][9] = (value32 & bMaskByte1) >> 8; + pACS->NHM_Cnt[idx][8] = (value32 & bMaskByte0); + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC); // ODM_REG_NHM_CNT3_TO_CNT0_11AC + + pACS->NHM_Cnt[idx][7] = (value32 & bMaskByte3) >> 24; + pACS->NHM_Cnt[idx][6] = (value32 & bMaskByte2) >> 16; + pACS->NHM_Cnt[idx][5] = (value32 & bMaskByte1) >> 8; + + } else if (pACS->ACS_Step==2) { + + value32 = ODM_Read4Byte(pDM_Odm,ODM_REG_NHM_CNT_11AC); // ODM_REG_NHM_CNT3_TO_CNT0_11AC + + pACS->NHM_Cnt[idx][4] = ODM_Read1Byte(pDM_Odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC); + pACS->NHM_Cnt[idx][3] = (value32 & bMaskByte3) >> 24; + pACS->NHM_Cnt[idx][2] = (value32 & bMaskByte2) >> 16; + pACS->NHM_Cnt[idx][1] = (value32 & bMaskByte1) >> 8; + pACS->NHM_Cnt[idx][0] = (value32 & bMaskByte0); + } + } + +} + + +//#define ACS_DEBUG_INFO //acs debug default off +/* +int phydm_AutoChannelSelectAP( + IN PVOID pDM_VOID, + IN u4Byte ACS_Type, // 0: RXCount_Type, 1:NHM_Type + IN u4Byte available_chnl_num // amount of all channels + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PACS pACS = &pDM_Odm->DM_ACS; + prtl8192cd_priv priv = pDM_Odm->priv; + + static u4Byte score2G[MAX_2G_CHANNEL_NUM], score5G[MAX_5G_CHANNEL_NUM]; + u4Byte score[MAX_BSS_NUM], use_nhm = 0; + u4Byte minScore=0xffffffff; + u4Byte tmpScore, tmpIdx=0; + u4Byte traffic_check = 0; + u4Byte fa_count_weighting = 1; + int i, j, idx=0, idx_2G_end=-1, idx_5G_begin=-1, minChan=0; + struct bss_desc *pBss=NULL; + +#ifdef _DEBUG_RTL8192CD_ + char tmpbuf[400]; + int len=0; +#endif + + memset(score2G, '\0', sizeof(score2G)); + memset(score5G, '\0', sizeof(score5G)); + + for (i=0; iavailable_chnl_num; i++) { + if (priv->available_chnl[i] <= 14) + idx_2G_end = i; + else + break; + } + + for (i=0; iavailable_chnl_num; i++) { + if (priv->available_chnl[i] > 14) { + idx_5G_begin = i; + break; + } + } + +// DELETE +#ifndef CONFIG_RTL_NEW_AUTOCH + for (i=0; isite_survey->count; i++) { + pBss = &priv->site_survey->bss[i]; + for (idx=0; idxavailable_chnl_num; idx++) { + if (pBss->channel == priv->available_chnl[idx]) { + if (pBss->channel <= 14) + setChannelScore(idx, score2G, 0, MAX_2G_CHANNEL_NUM-1); + else + score5G[idx - idx_5G_begin] += 5; + break; + } + } + } +#endif + + if (idx_2G_end >= 0) + for (i=0; i<=idx_2G_end; i++) + score[i] = score2G[i]; + if (idx_5G_begin >= 0) + for (i=idx_5G_begin; iavailable_chnl_num; i++) + score[i] = score5G[i - idx_5G_begin]; + +#ifdef CONFIG_RTL_NEW_AUTOCH + { + u4Byte y, ch_begin=0, ch_end= priv->available_chnl_num; + + u4Byte do_ap_check = 1, ap_ratio = 0; + + if (idx_2G_end >= 0) + ch_end = idx_2G_end+1; + if (idx_5G_begin >= 0) + ch_begin = idx_5G_begin; + +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + for (y=ch_begin; yavailable_chnl[y], + priv->chnl_ss_mac_rx_count[y], + priv->chnl_ss_mac_rx_count_40M[y], + priv->chnl_ss_fa_count[y], + score[y]); + printk("\n"); +#endif + +#if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_WLAN_HAL_8192EE) + if( pDM_Odm->SupportICType&(ODM_RTL8188E|ODM_RTL8192E)&& priv->pmib->dot11RFEntry.acs_type ) + { + u4Byte tmp_score[MAX_BSS_NUM]; + memcpy(tmp_score, score, sizeof(score)); + if (find_clean_channel(priv, ch_begin, ch_end, tmp_score)) { + //memcpy(score, tmp_score, sizeof(score)); +#ifdef _DEBUG_RTL8192CD_ + printk("!! Found clean channel, select minimum FA channel\n"); +#endif + goto USE_CLN_CH; + } +#ifdef _DEBUG_RTL8192CD_ + printk("!! Not found clean channel, use NHM algorithm\n"); +#endif + use_nhm = 1; +USE_CLN_CH: + for (y=ch_begin; ynhm_cnt[y][i]; + for (j=0; jL, score: %d\n", + y+1, priv->nhm_cnt[y][9], priv->nhm_cnt[y][8], priv->nhm_cnt[y][7], + priv->nhm_cnt[y][6], priv->nhm_cnt[y][5], priv->nhm_cnt[y][4], + priv->nhm_cnt[y][3], priv->nhm_cnt[y][2], priv->nhm_cnt[y][1], + priv->nhm_cnt[y][0], score[y]); +#endif + } + + if (!use_nhm) + memcpy(score, tmp_score, sizeof(score)); + + goto choose_ch; + } +#endif + + // For each channel, weighting behind channels with MAC RX counter + //For each channel, weighting the channel with FA counter + + for (y=ch_begin; ychnl_ss_mac_rx_count[y]; + if (priv->chnl_ss_mac_rx_count[y] > 30) + do_ap_check = 0; + if( priv->chnl_ss_mac_rx_count[y] > MAC_RX_COUNT_THRESHOLD ) + traffic_check = 1; + +#ifdef RTK_5G_SUPPORT + if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G) +#endif + { + if ((int)(y-4) >= (int)ch_begin) + score[y-4] += 2 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y-3) >= (int)ch_begin) + score[y-3] += 8 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y-2) >= (int)ch_begin) + score[y-2] += 8 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 10 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 10 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y+2) < (int)ch_end) + score[y+2] += 8 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y+3) < (int)ch_end) + score[y+3] += 8 * priv->chnl_ss_mac_rx_count[y]; + if ((int)(y+4) < (int)ch_end) + score[y+4] += 2 * priv->chnl_ss_mac_rx_count[y]; + } + + //this is for CH_LOAD caculation + if( priv->chnl_ss_cca_count[y] > priv->chnl_ss_fa_count[y]) + priv->chnl_ss_cca_count[y]-= priv->chnl_ss_fa_count[y]; + else + priv->chnl_ss_cca_count[y] = 0; + } + +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + for (y=ch_begin; yavailable_chnl[y], score[y]); + printk("\n"); +#endif + + for (y=ch_begin; ychnl_ss_mac_rx_count_40M[y]) { + score[y] += 5 * priv->chnl_ss_mac_rx_count_40M[y]; + if (priv->chnl_ss_mac_rx_count_40M[y] > 30) + do_ap_check = 0; + if( priv->chnl_ss_mac_rx_count_40M[y] > MAC_RX_COUNT_THRESHOLD ) + traffic_check = 1; + +#ifdef RTK_5G_SUPPORT + if (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G) +#endif + { + if ((int)(y-6) >= (int)ch_begin) + score[y-6] += 1 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y-5) >= (int)ch_begin) + score[y-5] += 4 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y-4) >= (int)ch_begin) + score[y-4] += 4 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y-3) >= (int)ch_begin) + score[y-3] += 5 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y-2) >= (int)ch_begin) + score[y-2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 5 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 5 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y+2) < (int)ch_end) + score[y+2] += (5 * priv->chnl_ss_mac_rx_count_40M[y])/2; + if ((int)(y+3) < (int)ch_end) + score[y+3] += 5 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y+4) < (int)ch_end) + score[y+4] += 4 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y+5) < (int)ch_end) + score[y+5] += 4 * priv->chnl_ss_mac_rx_count_40M[y]; + if ((int)(y+6) < (int)ch_end) + score[y+6] += 1 * priv->chnl_ss_mac_rx_count_40M[y]; + } + } + } + +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + for (y=ch_begin; yavailable_chnl[y], score[y]); + printk("\n"); + printk("4. do_ap_check=%d traffic_check=%d\n", do_ap_check, traffic_check); + printk("\n"); +#endif + + if( traffic_check == 0) + fa_count_weighting = 5; + else + fa_count_weighting = 1; + + for (y=ch_begin; ychnl_ss_fa_count[y]; + } + +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + for (y=ch_begin; yavailable_chnl[y], score[y]); + printk("\n"); +#endif + + if (do_ap_check) { + for (i=0; isite_survey->count; i++) { + pBss = &priv->site_survey->bss[i]; + for (y=ch_begin; ychannel == priv->available_chnl[y]) { + if (pBss->channel <= 14) { +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + printk("chnl[%d] has ap rssi=%d bw[0x%02x]\n", + pBss->channel, pBss->rssi, pBss->t_stamp[1]); + printk("\n"); +#endif + if (pBss->rssi > 60) + ap_ratio = 4; + else if (pBss->rssi > 35) + ap_ratio = 2; + else + ap_ratio = 1; + + if ((pBss->t_stamp[1] & 0x6) == 0) { + score[y] += 50 * ap_ratio; + if ((int)(y-4) >= (int)ch_begin) + score[y-4] += 10 * ap_ratio; + if ((int)(y-3) >= (int)ch_begin) + score[y-3] += 20 * ap_ratio; + if ((int)(y-2) >= (int)ch_begin) + score[y-2] += 30 * ap_ratio; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 40 * ap_ratio; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 40 * ap_ratio; + if ((int)(y+2) < (int)ch_end) + score[y+2] += 30 * ap_ratio; + if ((int)(y+3) < (int)ch_end) + score[y+3] += 20 * ap_ratio; + if ((int)(y+4) < (int)ch_end) + score[y+4] += 10 * ap_ratio; + } + else if ((pBss->t_stamp[1] & 0x4) == 0) { + score[y] += 50 * ap_ratio; + if ((int)(y-3) >= (int)ch_begin) + score[y-3] += 20 * ap_ratio; + if ((int)(y-2) >= (int)ch_begin) + score[y-2] += 30 * ap_ratio; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 40 * ap_ratio; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 50 * ap_ratio; + if ((int)(y+2) < (int)ch_end) + score[y+2] += 50 * ap_ratio; + if ((int)(y+3) < (int)ch_end) + score[y+3] += 50 * ap_ratio; + if ((int)(y+4) < (int)ch_end) + score[y+4] += 50 * ap_ratio; + if ((int)(y+5) < (int)ch_end) + score[y+5] += 40 * ap_ratio; + if ((int)(y+6) < (int)ch_end) + score[y+6] += 30 * ap_ratio; + if ((int)(y+7) < (int)ch_end) + score[y+7] += 20 * ap_ratio; + } + else { + score[y] += 50 * ap_ratio; + if ((int)(y-7) >= (int)ch_begin) + score[y-7] += 20 * ap_ratio; + if ((int)(y-6) >= (int)ch_begin) + score[y-6] += 30 * ap_ratio; + if ((int)(y-5) >= (int)ch_begin) + score[y-5] += 40 * ap_ratio; + if ((int)(y-4) >= (int)ch_begin) + score[y-4] += 50 * ap_ratio; + if ((int)(y-3) >= (int)ch_begin) + score[y-3] += 50 * ap_ratio; + if ((int)(y-2) >= (int)ch_begin) + score[y-2] += 50 * ap_ratio; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 50 * ap_ratio; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 40 * ap_ratio; + if ((int)(y+2) < (int)ch_end) + score[y+2] += 30 * ap_ratio; + if ((int)(y+3) < (int)ch_end) + score[y+3] += 20 * ap_ratio; + } + } + else { + if ((pBss->t_stamp[1] & 0x6) == 0) { + score[y] += 500; + } + else if ((pBss->t_stamp[1] & 0x4) == 0) { + score[y] += 500; + if ((int)(y+1) < (int)ch_end) + score[y+1] += 500; + } + else { + score[y] += 500; + if ((int)(y-1) >= (int)ch_begin) + score[y-1] += 500; + } + } + break; + } + } + } + } + +#ifdef ACS_DEBUG_INFO//for debug + printk("\n"); + for (y=ch_begin; yavailable_chnl[y],score[y]); + printk("\n"); +#endif + +#ifdef SS_CH_LOAD_PROC + + // caculate noise level -- suggested by wilson + for (y=ch_begin; ychnl_ss_fa_count[y]>1000) { + fa_lv = 100; + } else if (priv->chnl_ss_fa_count[y]>500) { + fa_lv = 34 * (priv->chnl_ss_fa_count[y]-500) / 500 + 66; + } else if (priv->chnl_ss_fa_count[y]>200) { + fa_lv = 33 * (priv->chnl_ss_fa_count[y] - 200) / 300 + 33; + } else if (priv->chnl_ss_fa_count[y]>100) { + fa_lv = 18 * (priv->chnl_ss_fa_count[y] - 100) / 100 + 15; + } else { + fa_lv = 15 * priv->chnl_ss_fa_count[y] / 100; + } + if (priv->chnl_ss_cca_count[y]>400) { + cca_lv = 100; + } else if (priv->chnl_ss_cca_count[y]>200) { + cca_lv = 34 * (priv->chnl_ss_cca_count[y] - 200) / 200 + 66; + } else if (priv->chnl_ss_cca_count[y]>80) { + cca_lv = 33 * (priv->chnl_ss_cca_count[y] - 80) / 120 + 33; + } else if (priv->chnl_ss_cca_count[y]>40) { + cca_lv = 18 * (priv->chnl_ss_cca_count[y] - 40) / 40 + 15; + } else { + cca_lv = 15 * priv->chnl_ss_cca_count[y] / 40; + } + + priv->chnl_ss_load[y] = (((fa_lv > cca_lv)? fa_lv : cca_lv)*75+((score[y]>100)?100:score[y])*25)/100; + + DEBUG_INFO("ch:%d f=%d (%d), c=%d (%d), fl=%d, cl=%d, sc=%d, cu=%d\n", + priv->available_chnl[y], + priv->chnl_ss_fa_count[y], fa_thd, + priv->chnl_ss_cca_count[y], cca_thd, + fa_lv, + cca_lv, + score[y], + priv->chnl_ss_load[y]); + + } +#endif + } +#endif + +choose_ch: + +#ifdef DFS + // heavy weighted DFS channel + if (idx_5G_begin >= 0){ + for (i=idx_5G_begin; iavailable_chnl_num; i++) { + if (!priv->pmib->dot11DFSEntry.disable_DFS && is_DFS_channel(priv->available_chnl[i]) + && (score[i]!= 0xffffffff)){ + score[i] += 1600; + } + } + } +#endif + + +//prevent Auto Channel selecting wrong channel in 40M mode----------------- + if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) + && priv->pshare->is_40m_bw) { +#if 0 + if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 1) { + //Upper Primary Channel, cannot select the two lowest channels + if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) { + score[0] = 0xffffffff; + score[1] = 0xffffffff; + score[2] = 0xffffffff; + score[3] = 0xffffffff; + score[4] = 0xffffffff; + + score[13] = 0xffffffff; + score[12] = 0xffffffff; + score[11] = 0xffffffff; + } + +// if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) { +// score[idx_5G_begin] = 0xffffffff; +// score[idx_5G_begin + 1] = 0xffffffff; +// } + } + else if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 2) { + //Lower Primary Channel, cannot select the two highest channels + if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) { + score[0] = 0xffffffff; + score[1] = 0xffffffff; + score[2] = 0xffffffff; + + score[13] = 0xffffffff; + score[12] = 0xffffffff; + score[11] = 0xffffffff; + score[10] = 0xffffffff; + score[9] = 0xffffffff; + } + +// if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) { +// score[priv->available_chnl_num - 2] = 0xffffffff; +// score[priv->available_chnl_num - 1] = 0xffffffff; +// } + } +#endif + for (i=0; i<=idx_2G_end; ++i) + if (priv->available_chnl[i] == 14) + score[i] = 0xffffffff; // mask chan14 + +#ifdef RTK_5G_SUPPORT + if (idx_5G_begin >= 0) { + for (i=idx_5G_begin; iavailable_chnl_num; i++) { + int ch = priv->available_chnl[i]; + if(priv->available_chnl[i] > 144) + --ch; + if((ch%4) || ch==140 || ch == 164 ) //mask ch 140, ch 165, ch 184... + score[i] = 0xffffffff; + } + } +#endif + + + } + + if (priv->pmib->dot11RFEntry.disable_ch1213) { + for (i=0; i<=idx_2G_end; ++i) { + int ch = priv->available_chnl[i]; + if ((ch == 12) || (ch == 13)) + score[i] = 0xffffffff; + } + } + + if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_GLOBAL) || + (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_WORLD_WIDE)) && + (idx_2G_end >= 11) && (idx_2G_end < 14)) { + score[13] = 0xffffffff; // mask chan14 + score[12] = 0xffffffff; // mask chan13 + score[11] = 0xffffffff; // mask chan12 + } + +//------------------------------------------------------------------ + +#ifdef _DEBUG_RTL8192CD_ + for (i=0; iavailable_chnl_num; i++) { + len += sprintf(tmpbuf+len, "ch%d:%u ", priv->available_chnl[i], score[i]); + } + strcat(tmpbuf, "\n"); + panic_printk("%s", tmpbuf); + +#endif + + if ( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) + && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) + { + for (i=0; iavailable_chnl_num; i++) { + if (is80MChannel(priv->available_chnl, priv->available_chnl_num, priv->available_chnl[i])) { + tmpScore = 0; + for (j=0; j<4; j++) { + if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff)) + tmpScore += score[i+j]; + else + tmpScore = 0xffffffff; + } + tmpScore = tmpScore / 4; + if (minScore > tmpScore) { + minScore = tmpScore; + + tmpScore = 0xffffffff; + for (j=0; j<4; j++) { + if (score[i+j] < tmpScore) { + tmpScore = score[i+j]; + tmpIdx = i+j; + } + } + + idx = tmpIdx; + } + i += 3; + } + } + if (minScore == 0xffffffff) { + // there is no 80M channels + priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20; + for (i=0; iavailable_chnl_num; i++) { + if (score[i] < minScore) { + minScore = score[i]; + idx = i; + } + } + } + } + else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) + && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)) + { + for (i=0; iavailable_chnl_num; i++) { + if(is40MChannel(priv->available_chnl,priv->available_chnl_num,priv->available_chnl[i])) { + tmpScore = 0; + for(j=0;j<2;j++) { + if ((tmpScore != 0xffffffff) && (score[i+j] != 0xffffffff)) + tmpScore += score[i+j]; + else + tmpScore = 0xffffffff; + } + tmpScore = tmpScore / 2; + if(minScore > tmpScore) { + minScore = tmpScore; + + tmpScore = 0xffffffff; + for (j=0; j<2; j++) { + if (score[i+j] < tmpScore) { + tmpScore = score[i+j]; + tmpIdx = i+j; + } + } + + idx = tmpIdx; + } + i += 1; + } + } + if (minScore == 0xffffffff) { + // there is no 40M channels + priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20; + for (i=0; iavailable_chnl_num; i++) { + if (score[i] < minScore) { + minScore = score[i]; + idx = i; + } + } + } + } + else if( (priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_2G) + && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40) + && (priv->available_chnl_num >= 8) ) + { + u4Byte groupScore[14]; + + memset(groupScore, 0xff , sizeof(groupScore)); + for (i=0; iavailable_chnl_num-4; i++) { + if (score[i] != 0xffffffff && score[i+4] != 0xffffffff) { + groupScore[i] = score[i] + score[i+4]; + DEBUG_INFO("groupScore, ch %d,%d: %d\n", i+1, i+5, groupScore[i]); + if (groupScore[i] < minScore) { +#ifdef AUTOCH_SS_SPEEDUP + if(priv->pmib->miscEntry.autoch_1611_enable) + { + if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11) + { + minScore = groupScore[i]; + idx = i; + } + } + else +#endif + { + minScore = groupScore[i]; + idx = i; + } + } + } + } + + if (score[idx] < score[idx+4]) { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE; + } else { + idx = idx + 4; + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW; + } + } + else + { + for (i=0; iavailable_chnl_num; i++) { + if (score[i] < minScore) { +#ifdef AUTOCH_SS_SPEEDUP + if(priv->pmib->miscEntry.autoch_1611_enable) + { + if(priv->available_chnl[i]==1 || priv->available_chnl[i]==6 || priv->available_chnl[i]==11) + { + minScore = score[i]; + idx = i; + } + } + else +#endif + { + minScore = score[i]; + idx = i; + } + } + } + } + + if (IS_A_CUT_8881A(priv) && + (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) { + if ((priv->available_chnl[idx] == 36) || + (priv->available_chnl[idx] == 52) || + (priv->available_chnl[idx] == 100) || + (priv->available_chnl[idx] == 116) || + (priv->available_chnl[idx] == 132) || + (priv->available_chnl[idx] == 149) || + (priv->available_chnl[idx] == 165)) + idx++; + else if ((priv->available_chnl[idx] == 48) || + (priv->available_chnl[idx] == 64) || + (priv->available_chnl[idx] == 112) || + (priv->available_chnl[idx] == 128) || + (priv->available_chnl[idx] == 144) || + (priv->available_chnl[idx] == 161) || + (priv->available_chnl[idx] == 177)) + idx--; + } + + minChan = priv->available_chnl[idx]; + + // skip channel 14 if don't support ofdm + if ((priv->pmib->dot11RFEntry.disable_ch14_ofdm) && + (minChan == 14)) { + score[idx] = 0xffffffff; + + minScore = 0xffffffff; + for (i=0; iavailable_chnl_num; i++) { + if (score[i] < minScore) { + minScore = score[i]; + idx = i; + } + } + minChan = priv->available_chnl[idx]; + } + +#if 0 + //Check if selected channel available for 80M/40M BW or NOT ? + if(priv->pmib->dot11RFEntry.phyBandSelect == PHY_BAND_5G) + { + if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80) + { + if(!is80MChannel(priv->available_chnl,priv->available_chnl_num,minChan)) + { + //printk("BW=80M, selected channel = %d is unavaliable! reduce to 40M\n", minChan); + //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20_40; + priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20_40; + } + } + + if(priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40) + { + if(!is40MChannel(priv->available_chnl,priv->available_chnl_num,minChan)) + { + //printk("BW=40M, selected channel = %d is unavaliable! reduce to 20M\n", minChan); + //priv->pmib->dot11nConfigEntry.dot11nUse40M = HT_CHANNEL_WIDTH_20; + priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20; + } + } + } +#endif + +#ifdef CONFIG_RTL_NEW_AUTOCH + RTL_W32(RXERR_RPT, RXERR_RPT_RST); +#endif + +// auto adjust contro-sideband + if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) + && (priv->pshare->is_40m_bw ==1 || priv->pshare->is_40m_bw ==2)) { + +#ifdef RTK_5G_SUPPORT + if (priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G) { + if( (minChan>144) ? ((minChan-1)%8) : (minChan%8)) { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE; + } else { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW; + } + + } else +#endif + { +#if 0 +#ifdef CONFIG_RTL_NEW_AUTOCH + unsigned int ch_max; + + if (priv->available_chnl[idx_2G_end] >= 13) + ch_max = 13; + else + ch_max = priv->available_chnl[idx_2G_end]; + + if ((minChan >= 5) && (minChan <= (ch_max-5))) { + if (score[minChan+4] > score[minChan-4]) { // what if some channels were cancelled? + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW; + } else { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE; + } + } else +#endif + { + if (minChan < 5) { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE; + } + else if (minChan > 7) { + GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; + priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW; + } + } +#endif + } + } +//----------------------- + +#if defined(__ECOS) && defined(CONFIG_SDIO_HCI) + panic_printk("Auto channel choose ch:%d\n", minChan); +#else +#ifdef _DEBUG_RTL8192CD_ + panic_printk("Auto channel choose ch:%d\n", minChan); +#endif +#endif +#ifdef ACS_DEBUG_INFO//for debug + printk("7. minChan:%d 2nd_offset:%d\n", minChan, priv->pshare->offset_2nd_chan); +#endif + + return minChan; +} +*/ + +#endif + +VOID +phydm_CLMInit( + IN PVOID pDM_VOID, + IN u2Byte sampleNum /*unit : 4us*/ +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_TIME_PERIOD_11AC, bMaskLWord, sampleNum); /*4us sample 1 time*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_11AC, BIT8, 0x1); /*Enable CCX for CLM*/ + } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_TIME_PERIOD_11N, bMaskLWord, sampleNum); /*4us sample 1 time*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_11N, BIT8, 0x1); /*Enable CCX for CLM*/ + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[%s] : CLM sampleNum = %d\n", __func__, sampleNum)); + +} + +VOID +phydm_CLMtrigger( + 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_CLM_11AC, BIT0, 0x0); /*Trigger CLM*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_11AC, BIT0, 0x1); + } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_11N, BIT0, 0x0); /*Trigger CLM*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_CLM_11N, BIT0, 0x1); + } +} + +BOOLEAN +phydm_checkCLMready( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32 = 0; + BOOLEAN ret = FALSE; + + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_CLM_RESULT_11AC, bMaskDWord); /*make sure CLM calc is ready*/ + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_CLM_READY_11N, bMaskDWord); /*make sure CLM calc is ready*/ + + if (value32 & BIT16) + ret = TRUE; + else + ret = FALSE; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[%s] : CLM ready = %d\n", __func__, ret)); + + return ret; +} + +u2Byte +phydm_getCLMresult( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32 = 0; + u2Byte results = 0; + + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_CLM_RESULT_11AC, bMaskDWord); /*read CLM calc result*/ + else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_CLM_RESULT_11N, bMaskDWord); /*read CLM calc result*/ + + results = (u2Byte)(value32 & bMaskLWord); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[%s] : CLM result = %d\n", __func__, results)); + + return results; +/*results are number of CCA times in sampleNum*/ +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.h new file mode 100644 index 00000000..d193eab4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_acs.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * 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 CLM_VERSION "1.0" + +#define ODM_MAX_CHANNEL_2G 14 +#define ODM_MAX_CHANNEL_5G 24 + +// For phydm_AutoChannelSelectSettingAP() +#define STORE_DEFAULT_NHM_SETTING 0 +#define RESTORE_DEFAULT_NHM_SETTING 1 +#define ACS_NHM_SETTING 2 + +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]; + +#if ( DM_ODM_SUPPORT_TYPE & ODM_AP ) + u1Byte ACS_Step; + // NHM Count 0-11 + u1Byte NHM_Cnt[14][11]; + + // AC-Series, for storing previous setting + u4Byte Reg0x990; + u4Byte Reg0x994; + u4Byte Reg0x998; + u4Byte Reg0x99C; + u1Byte Reg0x9A0; // u1Byte + + // N-Series, for storing previous setting + u4Byte Reg0x890; + u4Byte Reg0x894; + u4Byte Reg0x898; + u4Byte Reg0x89C; + u1Byte Reg0xE28; // u1Byte +#endif + +}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 +); + +#if ( DM_ODM_SUPPORT_TYPE & ODM_AP ) + +VOID +phydm_AutoChannelSelectSettingAP( + IN PVOID pDM_VOID, + IN u4Byte Setting, // 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING + IN u4Byte acs_step +); + +VOID +phydm_GetNHMStatisticsAP( + IN PVOID pDM_VOID, + IN u4Byte idx, // @ 2G, Real channel number = idx+1 + IN u4Byte acs_step +); + +#endif //#if ( DM_ODM_SUPPORT_TYPE & ODM_AP ) + + +VOID +phydm_CLMInit( + IN PVOID pDM_VOID, + IN u2Byte sampleNum +); + +VOID +phydm_CLMtrigger( + IN PVOID pDM_VOID +); + +BOOLEAN +phydm_checkCLMready( + IN PVOID pDM_VOID +); + +u2Byte +phydm_getCLMresult( + IN PVOID pDM_VOID +); + + +#endif //#ifndef __PHYDMACS_H__ \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.c new file mode 100644 index 00000000..07d1a94b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.c @@ -0,0 +1,896 @@ +/****************************************************************************** + * + * 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) +#if WPP_SOFTWARE_TRACE +#include "PhyDM_Adaptivity.tmh" +#endif +#endif + + +VOID +Phydm_CheckAdaptivity( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTIVITY_STATISTICS Adaptivity = (PADAPTIVITY_STATISTICS)PhyDM_Get_Structure(pDM_Odm, PHYDM_ADAPTIVITY); + + if (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (pDM_Odm->APTotalNum > Adaptivity->APNumTH) { + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("AP total num > %d!!, disable adaptivity\n", Adaptivity->APNumTH)); + } else +#endif + { + if (Adaptivity->DynamicLinkAdaptivity == TRUE) { + if (pDM_Odm->bLinked && Adaptivity->bCheck == FALSE) { + Phydm_NHMCounterStatistics(pDM_Odm); + Phydm_CheckEnvironment(pDM_Odm); + } else if (!pDM_Odm->bLinked) + Adaptivity->bCheck = FALSE; + } else { + pDM_Odm->Adaptivity_enable = TRUE; + + if (pDM_Odm->SupportICType & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) + pDM_Odm->adaptivity_flag = FALSE; + else + pDM_Odm->adaptivity_flag = TRUE; + } + } + } else { + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + } + + + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +BOOLEAN +Phydm_CheckChannelPlan( + 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); + PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + + if (pMgntInfo->RegEnableAdaptivity == 2) { + 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)); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + } 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)); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + + } 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")); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + } + } else { + if ((*pDM_Odm->pBandType == ODM_BAND_5G) && + !(pDM_Odm->odm_Regulation5G == REGULATION_MKK || 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)); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + } + + else if ((*pDM_Odm->pBandType == ODM_BAND_2_4G) && + !(pDM_Odm->odm_Regulation2_4G == REGULATION_MKK || 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)); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + + } 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")); + pDM_Odm->Adaptivity_enable = FALSE; + pDM_Odm->adaptivity_flag = FALSE; + return TRUE; + } + } + } + + return FALSE; + +} +#endif + +VOID +Phydm_NHMCounterStatisticsInit( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + 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_TH9_TH10_11N + 2, 0xffff); /*0x890[31:16]=0xffff th_9, th_10*/ + 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, 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*/ + } +#if (RTL8195A_SUPPORT == 0) + else 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, 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, 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*/ + + } +#endif +} + +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 (RTL8195A_SUPPORT == 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) +#endif + 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_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); + } +#if (RTL8195A_SUPPORT == 0) + else 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); + } + +#endif + +} + +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, bMaskByte2|bMaskByte0, (u4Byte)((u1Byte)L2H|(u1Byte)H2L<<16)); +#if (RTL8195A_SUPPORT == 0) + else if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + ODM_SetBBReg(pDM_Odm, rFPGA0_XB_LSSIReadBack, bMaskLWord, (u2Byte)((u1Byte)L2H|(u1Byte)H2L<<8)); +#endif + +} + +VOID +Phydm_SetLNA( + IN PVOID pDM_VOID, + IN PhyDM_set_LNA type +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & (ODM_RTL8188E | ODM_RTL8192E)) { + if (type == PhyDM_disable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0x37f82); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + if (pDM_Odm->RFType > ODM_1T1R) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0x37f82); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0); + } + } else if (type == PhyDM_enable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0x77f82); /*back to normal*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + if (pDM_Odm->RFType > ODM_1T1R) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0x77f82); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0); + } + } + } else if (pDM_Odm->SupportICType & ODM_RTL8723B) { + if (type == PhyDM_disable_LNA) { + /*S0*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0001f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xe6137); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + /*S1*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x43, 0xfffff, 0x3008d); /*select Rx mode and disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0); + } else if (type == PhyDM_enable_LNA) { + /*S0*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0001f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xe6177); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + /*S1*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x43, 0xfffff, 0x300bd); /*select Rx mode and disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0); + } + + } else if (pDM_Odm->SupportICType & ODM_RTL8812) { + if (type == PhyDM_disable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3f7ff); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xc22bf); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + if (pDM_Odm->RFType > ODM_1T1R) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3f7ff); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xc22bf); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0); + } + } else if (type == PhyDM_enable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3f7ff); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xc26bf); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + if (pDM_Odm->RFType > ODM_1T1R) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3f7ff); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xc26bf); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0); + } + } + } else if (pDM_Odm->SupportICType & (ODM_RTL8821 | ODM_RTL8881A)) { + if (type == PhyDM_disable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0002f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xfb09b); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + } else if (type == PhyDM_enable_LNA) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x30, 0xfffff, 0x18000); /*select Rx mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x0002f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xfb0bb); /*disable LNA*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); + } + } +} + + + +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*/ + } + } +#if (RTL8195A_SUPPORT == 0) + 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*/ + } + } +#endif + +} + +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 */ + } + 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; + PADAPTIVITY_STATISTICS Adaptivity = (PADAPTIVITY_STATISTICS)PhyDM_Get_Structure(pDM_Odm, PHYDM_ADAPTIVITY); + BOOLEAN isCleanEnvironment = FALSE; + + if (Adaptivity->bFirstLink == TRUE) { + if (pDM_Odm->SupportICType & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) + pDM_Odm->adaptivity_flag = FALSE; + else + pDM_Odm->adaptivity_flag = TRUE; + + Adaptivity->bFirstLink = FALSE; + return; + } else { + if (Adaptivity->NHMWait < 3) { /*Start enter NHM after 4 NHMWait*/ + Adaptivity->NHMWait++; + Phydm_NHMCounterStatistics(pDM_Odm); + return; + } else { + Phydm_NHMCounterStatistics(pDM_Odm); + isCleanEnvironment = Phydm_CalNHMcnt(pDM_Odm); + if (isCleanEnvironment == TRUE) { + pDM_Odm->TH_L2H_ini = Adaptivity->TH_L2H_ini_backup; /*adaptivity mode*/ + pDM_Odm->TH_EDCCA_HL_diff = Adaptivity->TH_EDCCA_HL_diff_backup; + + pDM_Odm->Adaptivity_enable = TRUE; + + if (pDM_Odm->SupportICType & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) + pDM_Odm->adaptivity_flag = FALSE; + else + pDM_Odm->adaptivity_flag = TRUE; + } else { + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; /*mode2*/ + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_mode2; + + pDM_Odm->adaptivity_flag = FALSE; + pDM_Odm->Adaptivity_enable = FALSE; + } + Adaptivity->NHMWait = 0; + Adaptivity->bFirstLink = TRUE; + Adaptivity->bCheck = TRUE; + } + + } + + +} + +VOID +Phydm_SearchPwdBLowerBound( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTIVITY_STATISTICS Adaptivity = (PADAPTIVITY_STATISTICS)PhyDM_Get_Structure(pDM_Odm, PHYDM_ADAPTIVITY); + u4Byte value32 = 0; + u1Byte cnt, IGI = 0x45; /*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; + + if (pDM_Odm->SupportICType & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) + Phydm_SetLNA(pDM_Odm, PhyDM_disable_LNA); + else { + Phydm_SetTRxMux(pDM_Odm, PhyDM_STANDBY_MODE, PhyDM_STANDBY_MODE); + odm_PauseDIG(pDM_Odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x7e); + } + + 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); +#if (RTL8195A_SUPPORT == 0) + else if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC, bMaskDWord); +#endif + 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 > 1) { + 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); + if (TH_L2H_dmc == 10) { + bAdjust = FALSE; + Adaptivity->H2L_lb = TH_H2L_dmc; + Adaptivity->L2H_lb = TH_L2H_dmc; + pDM_Odm->Adaptivity_IGI_upper = IGI; + } + + txEdcca1 = 0; + txEdcca0 = 0; + + } else { + bAdjust = FALSE; + Adaptivity->H2L_lb = TH_H2L_dmc; + Adaptivity->L2H_lb = TH_L2H_dmc; + pDM_Odm->Adaptivity_IGI_upper = IGI; + txEdcca1 = 0; + txEdcca0 = 0; + } + } + + pDM_Odm->Adaptivity_IGI_upper = pDM_Odm->Adaptivity_IGI_upper - pDM_Odm->DCbackoff; + Adaptivity->H2L_lb = Adaptivity->H2L_lb + pDM_Odm->DCbackoff; + Adaptivity->L2H_lb = Adaptivity->L2H_lb + pDM_Odm->DCbackoff; + + if (pDM_Odm->SupportICType & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) + Phydm_SetLNA(pDM_Odm, PhyDM_enable_LNA); + else { + Phydm_SetTRxMux(pDM_Odm, PhyDM_TX_MODE, PhyDM_RX_MODE); + odm_PauseDIG(pDM_Odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, NONE); + } + + 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; + PADAPTIVITY_STATISTICS Adaptivity = (PADAPTIVITY_STATISTICS)PhyDM_Get_Structure(pDM_Odm, PHYDM_ADAPTIVITY); + s1Byte IGItarget = 0x32; +#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->DCbackoff = (u1Byte)pMgntInfo->RegDCbackoff; + Adaptivity->DynamicLinkAdaptivity = (BOOLEAN)pMgntInfo->RegDmLinkAdaptivity; + Adaptivity->APNumTH = (u1Byte)pMgntInfo->RegAPNumTH; +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + pDM_Odm->Carrier_Sense_enable = (pDM_Odm->Adapter->registrypriv.adaptivity_mode != 0) ? TRUE : FALSE; + pDM_Odm->DCbackoff = pDM_Odm->Adapter->registrypriv.adaptivity_dc_backoff; + Adaptivity->DynamicLinkAdaptivity = (pDM_Odm->Adapter->registrypriv.adaptivity_dml != 0) ? TRUE : FALSE; +#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 +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (pDM_Odm->Adapter->registrypriv.adaptivity_th_l2h_ini != 0) + pDM_Odm->TH_L2H_ini = pDM_Odm->Adapter->registrypriv.adaptivity_th_l2h_ini; + else +#endif + pDM_Odm->TH_L2H_ini = 0xf5; + } else + pDM_Odm->TH_L2H_ini = 0xa; + +#if(DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (pMgntInfo->RegHLDiffForAdaptivity != 0) + pDM_Odm->TH_EDCCA_HL_diff = pMgntInfo->RegHLDiffForAdaptivity; + else +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + if (pDM_Odm->Adapter->registrypriv.adaptivity_th_edcca_hl_diff != 0) + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->Adapter->registrypriv.adaptivity_th_edcca_hl_diff; + else +#endif + pDM_Odm->TH_EDCCA_HL_diff = 7; + + Adaptivity->TH_L2H_ini_backup = pDM_Odm->TH_L2H_ini; + Adaptivity->TH_EDCCA_HL_diff_backup = 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 = 0xa; + pDM_Odm->TH_EDCCA_HL_diff = 7; + } else { + Adaptivity->TH_L2H_ini_backup = pDM_Odm->TH_L2H_ini; /*set by mib*/ + pDM_Odm->TH_EDCCA_HL_diff = 7; + } + + Adaptivity->TH_EDCCA_HL_diff_backup = pDM_Odm->TH_EDCCA_HL_diff; + if (priv->pshare->rf_ft_var.adaptivity_enable == 2) + Adaptivity->DynamicLinkAdaptivity = TRUE; + else + Adaptivity->DynamicLinkAdaptivity = FALSE; + +#endif + + pDM_Odm->Adaptivity_IGI_upper = 0; + pDM_Odm->Adaptivity_enable = FALSE; /*use this flag to decide enable or disable*/ + + pDM_Odm->EDCCA_enable = TRUE; /*even no adaptivity, we still enable EDCCA*/ + + pDM_Odm->TH_L2H_ini_mode2 = 20; + pDM_Odm->TH_EDCCA_HL_diff_mode2 = 8; + + Adaptivity->IGI_Base = 0x32; + Adaptivity->IGI_target = 0x1c; + Adaptivity->H2L_lb = 0; + Adaptivity->L2H_lb = 0; + Adaptivity->NHMWait = 0; + Adaptivity->bCheck = FALSE; + Adaptivity->bFirstLink = TRUE; + Adaptivity->AdajustIGILevel = 0; + + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + + /*Search pwdB lower bound*/ + if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11N, bMaskDWord, 0x208); +#if (RTL8195A_SUPPORT == 0) + else if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC, bMaskDWord, 0x209); +#endif + + if (pDM_Odm->SupportICType & ODM_IC_11N_GAIN_IDX_EDCCA) { + /*ODM_SetBBReg(pDM_Odm, ODM_REG_EDCCA_DOWN_OPT_11N, BIT12 | BIT11 | BIT10, 0x7);*/ /*interfernce need > 2^x us, and then EDCCA will be 1*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_EDCCA_DCNF_11N, BIT21 | BIT20, 0x1); /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/ + } +#if (RTL8195A_SUPPORT == 0) + if (pDM_Odm->SupportICType & ODM_IC_11AC_GAIN_IDX_EDCCA) { /*8814a no need to find pwdB lower bound, maybe*/ + /*ODM_SetBBReg(pDM_Odm, ODM_REG_EDCCA_DOWN_OPT, BIT30 | BIT29 | BIT28, 0x7);*/ /*interfernce need > 2^x us, and then EDCCA will be 1*/ + ODM_SetBBReg(pDM_Odm, ODM_REG_ACBB_EDCCA_ENHANCE, BIT29 | BIT28, 0x1); /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/ + } + + if(!(pDM_Odm->SupportICType & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))) + Phydm_SearchPwdBLowerBound(pDM_Odm); +#endif + +/*we need to consider PwdB upper bound for 8814 later IC*/ + Adaptivity->AdajustIGILevel = (u1Byte)((pDM_Odm->TH_L2H_ini + IGItarget) - PwdBUpperBound + DFIRloss); /*IGI = L2H - PwdB - DFIRloss*/ + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("TH_L2H_ini = 0x%x, TH_EDCCA_HL_diff = 0x%x, Adaptivity->AdajustIGILevel = 0x%x\n", pDM_Odm->TH_L2H_ini, pDM_Odm->TH_EDCCA_HL_diff, Adaptivity->AdajustIGILevel)); + +} + + +VOID +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; + s1Byte Diff = 0, IGI_target; + PADAPTIVITY_STATISTICS Adaptivity = (PADAPTIVITY_STATISTICS)PhyDM_Get_Structure(pDM_Odm, PHYDM_ADAPTIVITY); +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER pAdapter = pDM_Odm->Adapter; + 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; +#endif + + if ((pDM_Odm->EDCCA_enable == FALSE) || (pDM_Odm->bWIFITest == TRUE)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Disable EDCCA!!!\n")); + return; + } + + if (!(pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("adaptivity disable, enable EDCCA mode!!!\n")); + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_mode2; + } +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + else{ + if (Phydm_CheckChannelPlan(pDM_Odm) || (pDM_Odm->APTotalNum > Adaptivity->APNumTH)) { + pDM_Odm->TH_L2H_ini = pDM_Odm->TH_L2H_ini_mode2; + pDM_Odm->TH_EDCCA_HL_diff = pDM_Odm->TH_EDCCA_HL_diff_mode2; + } + } +#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, ("IGI_Base=0x%x, TH_L2H_ini = %d, TH_EDCCA_HL_diff = %d\n", + Adaptivity->IGI_Base, pDM_Odm->TH_L2H_ini, pDM_Odm->TH_EDCCA_HL_diff)); +#if (RTL8195A_SUPPORT == 0) + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { + /*fix AC series when enable EDCCA hang issue*/ + ODM_SetBBReg(pDM_Odm, 0x800, BIT10, 1); /*ADC_mask disable*/ + ODM_SetBBReg(pDM_Odm, 0x800, BIT10, 0); /*ADC_mask enable*/ + } +#endif + if (*pDM_Odm->pBandWidth == ODM_BW20M) /*CHANNEL_WIDTH_20*/ + IGI_target = Adaptivity->IGI_Base; + else if (*pDM_Odm->pBandWidth == ODM_BW40M) + IGI_target = Adaptivity->IGI_Base + 2; +#if (RTL8195A_SUPPORT == 0) + else if (*pDM_Odm->pBandWidth == ODM_BW80M) + IGI_target = Adaptivity->IGI_Base + 2; +#endif + else + IGI_target = Adaptivity->IGI_Base; + Adaptivity->IGI_target = (u1Byte) IGI_target; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("BandWidth=%s, IGI_target=0x%x, DynamicLinkAdaptivity = %d\n", + (*pDM_Odm->pBandWidth == ODM_BW80M) ? "80M" : ((*pDM_Odm->pBandWidth == ODM_BW40M) ? "40M" : "20M"), IGI_target, Adaptivity->DynamicLinkAdaptivity)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("RSSI_min = %d, Adaptivity->AdajustIGILevel= 0x%x, adaptivity_flag = %d, Adaptivity_enable = %d\n", + pDM_Odm->RSSI_Min, Adaptivity->AdajustIGILevel, pDM_Odm->adaptivity_flag, pDM_Odm->Adaptivity_enable)); + + if ((Adaptivity->DynamicLinkAdaptivity == TRUE) && (!pDM_Odm->bLinked) && (pDM_Odm->Adaptivity_enable == FALSE)) { + Phydm_SetEDCCAThreshold(pDM_Odm, 0x7f, 0x7f); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("In DynamicLink mode(noisy) and No link, Turn off EDCCA!!\n")); + return; + } + + if (pDM_Odm->SupportICType & (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) { + if ((Adaptivity->AdajustIGILevel > IGI) && (pDM_Odm->Adaptivity_enable == TRUE)) + Diff = Adaptivity->AdajustIGILevel - IGI; + + TH_L2H_dmc = pDM_Odm->TH_L2H_ini - Diff + IGI_target; + TH_H2L_dmc = TH_L2H_dmc - pDM_Odm->TH_EDCCA_HL_diff; + } +#if (RTL8195A_SUPPORT == 0) + else { + Diff = IGI_target - (s1Byte)IGI; + TH_L2H_dmc = pDM_Odm->TH_L2H_ini + Diff; + if (TH_L2H_dmc > 10 && (pDM_Odm->Adaptivity_enable == TRUE)) + 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 < Adaptivity->H2L_lb) + TH_H2L_dmc = Adaptivity->H2L_lb; + if (TH_L2H_dmc < Adaptivity->L2H_lb) + TH_L2H_dmc = Adaptivity->L2H_lb; + } +#endif + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("IGI=0x%x, TH_L2H_dmc = %d, TH_H2L_dmc = %d\n", IGI, TH_L2H_dmc, TH_H2L_dmc)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_ADAPTIVITY, ODM_DBG_LOUD, ("Adaptivity_IGI_upper=0x%x, H2L_lb = 0x%x, L2H_lb = 0x%x\n", pDM_Odm->Adaptivity_IGI_upper, Adaptivity->H2L_lb, Adaptivity->L2H_lb)); + + Phydm_SetEDCCAThreshold(pDM_Odm, TH_H2L_dmc, TH_L2H_dmc); + return; +} + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +Phydm_AdaptivityBSOD( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER pAdapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + u1Byte count = 0; + u4Byte u4Value; + + /* + 1. turn off RF (TRX Mux in standby mode) + 2. H2C mac id drop + 3. ignore EDCCA + 4. wait for clear FIFO + 5. don't ignore EDCCA + 6. turn on RF (TRX Mux in TRx mdoe) + 7. H2C mac id resume + */ + + RT_TRACE(COMP_MLME, DBG_WARNING, ("MAC id drop packet!!!!!\n")); + + pAdapter->dropPktByMacIdCnt++; + pMgntInfo->bDropPktInProgress = TRUE; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_MAX_Q_PAGE_NUM, (pu1Byte)(&u4Value)); + RT_TRACE(COMP_INIT, DBG_LOUD, ("Queue Reserved Page Number = 0x%08x\n", u4Value)); + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_AVBL_Q_PAGE_NUM, (pu1Byte)(&u4Value)); + RT_TRACE(COMP_INIT, DBG_LOUD, ("Available Queue Page Number = 0x%08x\n", u4Value)); + +#if 1 + + /*Standby mode*/ + Phydm_SetTRxMux(pDM_Odm, PhyDM_STANDBY_MODE, PhyDM_STANDBY_MODE); + ODM_Write_DIG(pDM_Odm, 0x20); + + /*H2C mac id drop*/ + MacIdIndicateDisconnect(pAdapter); + + /*Ignore EDCCA*/ + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); + + delay_ms(50); + count = 5; + +#else + + do { + + u8Byte diffTime, curTime, oldestTime; + u1Byte queueIdx + + //3 Standby mode + Phydm_SetTRxMux(pDM_Odm, PhyDM_STANDBY_MODE, PhyDM_STANDBY_MODE); + ODM_Write_DIG(pDM_Odm, 0x20); + + //3 H2C mac id drop + MacIdIndicateDisconnect(pAdapter); + + //3 Ignore EDCCA + Phydm_MACEDCCAState(pDM_Odm, PhyDM_IGNORE_EDCCA); + + count++; + delay_ms(10); + + // Check latest packet + curTime = PlatformGetCurrentTime(); + oldestTime = 0xFFFFFFFFFFFFFFFF; + + for (queueIdx = 0; queueIdx < MAX_TX_QUEUE; queueIdx++) { + if (!IS_DATA_QUEUE(queueIdx)) + continue; + + if (!pAdapter->bTcbBusyQEmpty[queueIdx]) { + RT_TRACE(COMP_MLME, DBG_WARNING, ("oldestTime = %llu\n", oldestTime)); + RT_TRACE(COMP_MLME, DBG_WARNING, ("Q[%d] = %llu\n", queueIdx, pAdapter->firstTcbSysTime[queueIdx])); + if (pAdapter->firstTcbSysTime[queueIdx] < oldestTime) + oldestTime = pAdapter->firstTcbSysTime[queueIdx]; + } + } + + diffTime = curTime - oldestTime; + + RT_TRACE(COMP_MLME, DBG_WARNING, ("diff s = %llu\n", (diffTime / 1000000))); + + } while (((diffTime / 1000000) >= 4) && (oldestTime != 0xFFFFFFFFFFFFFFFF)); +#endif + + /*Resume EDCCA*/ + Phydm_MACEDCCAState(pDM_Odm, PhyDM_DONT_IGNORE_EDCCA); + + /*Turn on TRx mode*/ + Phydm_SetTRxMux(pDM_Odm, PhyDM_TX_MODE, PhyDM_RX_MODE); + ODM_Write_DIG(pDM_Odm, 0x20); + + /*Resume H2C macid*/ + MacIdRecoverMediaStatus(pAdapter); + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_AVBL_Q_PAGE_NUM, (pu1Byte)(&u4Value)); + RT_TRACE(COMP_INIT, DBG_LOUD, ("Available Queue Page Number = 0x%08x\n", u4Value)); + + pMgntInfo->bDropPktInProgress = FALSE; + RT_TRACE(COMP_MLME, DBG_WARNING, ("End of MAC id drop packet, spent %dms\n", count * 10)); + +} + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.h new file mode 100644 index 00000000..ea1ab38a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_adaptivity.h @@ -0,0 +1,166 @@ + +/****************************************************************************** + * + * 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 "9.0" + +#define PwdBUpperBound 7 +#define DFIRloss 5 + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +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_set_LNA { + PhyDM_disable_LNA = 0, + PhyDM_enable_LNA = 1, +} PhyDM_set_LNA; + + +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; + +typedef struct _ADAPTIVITY_STATISTICS { + s1Byte TH_L2H_ini_backup; + s1Byte TH_EDCCA_HL_diff_backup; + s1Byte IGI_Base; + u1Byte IGI_target; + u1Byte NHMWait; + s1Byte H2L_lb; + s1Byte L2H_lb; + BOOLEAN bFirstLink; + BOOLEAN bCheck; + BOOLEAN DynamicLinkAdaptivity; + u1Byte APNumTH; + u1Byte AdajustIGILevel; +} ADAPTIVITY_STATISTICS, *PADAPTIVITY_STATISTICS; + +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_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 + ); + +VOID +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 +); + +VOID +Phydm_AdaptivityBSOD( + IN PVOID pDM_VOID +); + +#endif + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.c new file mode 100644 index 00000000..862c5971 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.c @@ -0,0 +1,964 @@ +/****************************************************************************** + * + * 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)) +#if(defined(CONFIG_ANT_DETECTION)) + +//IS_ANT_DETECT_SUPPORT_SINGLE_TONE(Adapter) +//IS_ANT_DETECT_SUPPORT_RSSI(Adapter) +//IS_ANT_DETECT_SUPPORT_PSD(Adapter) + +//1 [1. Single Tone Method] =================================================== + +// +// 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 PVOID pDM_VOID, + IN u1Byte mode + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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; + 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_RTL8723B)) + return bResult; + + // Retrieve antenna detection registry info, added by Roger, 2012.11.27. + if(!IS_ANT_DETECT_SUPPORT_SINGLE_TONE(pAdapter)) + return bResult; + + //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) { + 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_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_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_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); + + //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_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; + } + + //Close IQK Single Tone function + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, 0xffffff00, 0x000000); + + //1 Return to antanna A + 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_RTL8723B) + ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, AFE_rRx_Wait_CCA); + + 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] ================================================== + + + + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PVOID pDM_VOID + ) +{ + +#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM) + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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_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; + 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_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 )); + + + } + + // 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 PVOID pDM_VOID, + IN u2Byte point, + IN u1Byte initial_gain) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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) (odm_ConvertTo_dB(psd_report));//+(u4Byte)(initial_gain); + return psd_report; +} + + + +VOID +ODM_SingleDualAntennaDetection_PSD( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 +void +odm_SwAntDetectInit( + IN PVOID pDM_VOID + ) +{ +#if(defined(CONFIG_ANT_DETECTION)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + //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; +#endif +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.h new file mode 100644 index 00000000..419d9ea9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdect.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * 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 "2.1" /*2015.07.29 by YuChen*/ + +#if(defined(CONFIG_ANT_DETECTION)) +//#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) +//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*/ + +#define MAX_ANTENNA_DETECTION_CNT 10 + + +typedef struct _ANT_DETECTED_INFO{ + BOOLEAN bAntDetected; + u4Byte dBForAntA; + u4Byte dBForAntB; + u4Byte dBForAntO; +}ANT_DETECTED_INFO, *PANT_DETECTED_INFO; + + +typedef enum tag_SW_Antenna_Switch_Definition +{ + Antenna_A = 1, + Antenna_B = 2, + Antenna_MAX = 3, +}DM_SWAS_E; + + + +//1 [1. Single Tone Method] =================================================== + + + +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PVOID pDM_VOID + ); + +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PVOID pDM_VOID, + IN u1Byte mode + ); + +//1 [2. Scan AP RSSI Method] ================================================== + +#define SwAntDivCheckBeforeLink ODM_SwAntDivCheckBeforeLink + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PVOID pDM_VOID + ); + + + + +//1 [3. PSD Method] ========================================================== + + +VOID +ODM_SingleDualAntennaDetection_PSD( + IN PVOID pDM_VOID +); + +#endif + +VOID +odm_SwAntDetectInit( + IN PVOID pDM_VOID + ); + + +#endif + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.c new file mode 100644 index 00000000..73f215a2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.c @@ -0,0 +1,4754 @@ +/****************************************************************************** + * + * 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + // 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 PVOID pDM_VOID, + IN u1Byte antSetting // 0=A, 1=B, 2=C, .... + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte i; + + if (pDM_Odm->AntDivType == S0S1_SW_ANTDIV) { + + pDM_SWAT_Table->try_flag = SWAW_STEP_INIT; + 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_PHYDM_ANTENNA_DIVERSITY)) +VOID +odm_AntDiv_on_off( + IN PVOID pDM_VOID , + IN u1Byte swch + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(pDM_FatTable->AntDiv_OnOff != swch) + { + if (pDM_Odm->AntDivType == S0S1_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 + 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 + } + } + } + } + pDM_FatTable->AntDiv_OnOff =swch; + +} + +VOID +phydm_FastTraining_enable( + IN PVOID pDM_VOID, + IN u1Byte swch + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte enable; + + if (swch == FAT_ON) + enable=1; + else + enable=0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fast Ant Training_en = ((%d))\n", enable)); + + if (pDM_Odm->SupportICType == ODM_RTL8188E) { + ODM_SetBBReg(pDM_Odm, 0xe08 , BIT16, enable); /*enable fast training*/ + /**/ + } else if (pDM_Odm->SupportICType == ODM_RTL8192E) { + ODM_SetBBReg(pDM_Odm, 0xB34 , BIT28, enable); /*enable fast training (path-A)*/ + /*ODM_SetBBReg(pDM_Odm, 0xB34 , BIT29, enable);*/ /*enable fast training (path-B)*/ + } else if (pDM_Odm->SupportICType == ODM_RTL8821) { + ODM_SetBBReg(pDM_Odm, 0x900 , BIT19, enable); /*enable fast training */ + /**/ + } +} + +VOID +odm_Tx_By_TxDesc_or_Reg( + IN PVOID pDM_VOID, + IN u1Byte swch + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte enable; + + enable = (swch == TX_BY_DESC) ? 1 : 0; + + if(pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) + { + if(pDM_Odm->SupportICType & ODM_N_ANTDIV_SUPPORT) + { + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, enable); + } + else if(pDM_Odm->SupportICType & ODM_AC_ANTDIV_SUPPORT) + { + ODM_SetBBReg(pDM_Odm, 0x900 , BIT18, enable); + } + } +} + +VOID +ODM_UpdateRxIdleAnt( + IN PVOID pDM_VOID, + IN u1Byte Ant + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte DefaultAnt, OptionalAnt,value32; + + 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 + } + #if (RTL8723B_SUPPORT == 1) + 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")); + /**/ + } + } + #endif + else { /*8188E & 8188F*/ + + #if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) { + phydm_update_rx_idle_antenna_8188F(pDM_Odm, DefaultAnt); + /**/ + } + #endif + + 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 PVOID pDM_VOID, + IN u1Byte Ant, + IN u4Byte MacId + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u1Byte TxAnt; + + if (pDM_Odm->AntDivType==CG_TRX_SMART_ANTDIV) + { + TxAnt=Ant; + } + else + { + 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; + + //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] )); + +} + +#ifdef BEAMFORMING_SUPPORT +#if(DM_ODM_SUPPORT_TYPE == ODM_AP) + +VOID +odm_BDC_Init( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pBDC_T pDM_BdcTable=&pDM_Odm->DM_BdcTable; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n[ BDC Initialization......] \n")); + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + pDM_BdcTable->BDC_Mode=BDC_MODE_NULL; + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDCcoexType_wBfer=0; + pDM_Odm->bdc_holdstate=0xff; + + if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + ODM_SetBBReg(pDM_Odm, 0xd7c , 0x0FFFFFFF, 0x1081008); + ODM_SetBBReg(pDM_Odm, 0xd80 , 0x0FFFFFFF, 0); + } + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + ODM_SetBBReg(pDM_Odm, 0x9b0 , 0x0FFFFFFF, 0x1081008); //0x9b0[30:0] = 01081008 + ODM_SetBBReg(pDM_Odm, 0x9b4 , 0x0FFFFFFF, 0); //0x9b4[31:0] = 00000000 + } + +} + + +VOID +odm_CSI_on_off( + IN PVOID pDM_VOID, + IN u1Byte CSI_en + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(CSI_en==CSI_ON) + { + if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + ODM_SetMACReg(pDM_Odm, 0xd84 , BIT11, 1); //0xd84[11]=1 + } + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + ODM_SetMACReg(pDM_Odm, 0x9b0 , BIT31, 1); //0x9b0[31]=1 + } + + } + else if(CSI_en==CSI_OFF) + { + if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + ODM_SetMACReg(pDM_Odm, 0xd84 , BIT11, 0); //0xd84[11]=0 + } + else if(pDM_Odm->SupportICType == ODM_RTL8812) + { + ODM_SetMACReg(pDM_Odm, 0x9b0 , BIT31, 0); //0x9b0[31]=0 + } + } +} + +VOID +odm_BDCcoexType_withBferClient( + IN PVOID pDM_VOID, + IN u1Byte swch + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + u1Byte BDCcoexType_wBfer; + + if(swch==DIVON_CSIOFF) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[BDCcoexType: 1] {DIV,CSI} ={1,0} \n")); + BDCcoexType_wBfer=1; + + if(BDCcoexType_wBfer != pDM_BdcTable->BDCcoexType_wBfer) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + odm_CSI_on_off(pDM_Odm,CSI_OFF); + pDM_BdcTable->BDCcoexType_wBfer=1; + } + } + else if(swch==DIVOFF_CSION) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[BDCcoexType: 2] {DIV,CSI} ={0,1}\n")); + BDCcoexType_wBfer=2; + + if(BDCcoexType_wBfer != pDM_BdcTable->BDCcoexType_wBfer) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + odm_CSI_on_off(pDM_Odm,CSI_ON); + pDM_BdcTable->BDCcoexType_wBfer=2; + } + } +} + +VOID +odm_BF_AntDiv_ModeArbitration( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + u1Byte current_BDC_Mode; + + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n")); + + //2 Mode 1 + if((pDM_BdcTable->num_Txbfee_Client !=0) && (pDM_BdcTable->num_Txbfer_Client == 0)) + { + current_BDC_Mode=BDC_MODE_1; + + if(current_BDC_Mode != pDM_BdcTable->BDC_Mode) + { + pDM_BdcTable->BDC_Mode=BDC_MODE_1; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + pDM_BdcTable->BDC_RxIdleUpdate_counter=1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Change to (( Mode1 ))\n")); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Antdiv + BF coextance Mode] : (( Mode1 ))\n")); + } + //2 Mode 2 + else if((pDM_BdcTable->num_Txbfee_Client ==0) && (pDM_BdcTable->num_Txbfer_Client != 0)) + { + current_BDC_Mode=BDC_MODE_2; + + if(current_BDC_Mode != pDM_BdcTable->BDC_Mode) + { + pDM_BdcTable->BDC_Mode=BDC_MODE_2; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + pDM_BdcTable->BDC_Try_flag=0; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Change to (( Mode2 ))\n")); + + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Antdiv + BF coextance Mode] : (( Mode2 ))\n")); + } + //2 Mode 3 + else if((pDM_BdcTable->num_Txbfee_Client !=0) && (pDM_BdcTable->num_Txbfer_Client != 0)) + { + current_BDC_Mode=BDC_MODE_3; + + if(current_BDC_Mode != pDM_BdcTable->BDC_Mode) + { + pDM_BdcTable->BDC_Mode=BDC_MODE_3; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_RxIdleUpdate_counter=1; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Change to (( Mode3 ))\n")); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Antdiv + BF coextance Mode] : (( Mode3 ))\n")); + } + //2 Mode 4 + else if((pDM_BdcTable->num_Txbfee_Client ==0) && (pDM_BdcTable->num_Txbfer_Client == 0)) + { + current_BDC_Mode=BDC_MODE_4; + + if(current_BDC_Mode != pDM_BdcTable->BDC_Mode) + { + pDM_BdcTable->BDC_Mode=BDC_MODE_4; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Change to (( Mode4 ))\n")); + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Antdiv + BF coextance Mode] : (( Mode4 ))\n")); + } + #endif + +} + +VOID +odm_DivTrainState_setting( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pBDC_T pDM_BdcTable=&pDM_Odm->DM_BdcTable; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n*****[S T A R T ]***** [2-0. DIV_TRAIN_STATE] \n")); + pDM_BdcTable->BDC_Try_counter =2; + pDM_BdcTable->BDC_Try_flag=1; + pDM_BdcTable->BDC_state=BDC_BFer_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); +} + +VOID +odm_BDCcoex_BFeeRxDiv_Arbitration( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + BOOLEAN StopBF_flag; + u1Byte BDC_active_Mode; + + + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***{ num_BFee, num_BFer , num_Client} = (( %d , %d , %d)) \n",pDM_BdcTable->num_Txbfee_Client,pDM_BdcTable->num_Txbfer_Client,pDM_BdcTable->num_Client)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***{ num_BF_tars, num_DIV_tars } = (( %d , %d )) \n",pDM_BdcTable->num_BfTar , pDM_BdcTable->num_DivTar )); + + //2 [ MIB control ] + if (pDM_Odm->bdc_holdstate==2) + { + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + pDM_BdcTable->BDC_state=BDC_BF_HOLD_STATE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Force in [ BF STATE] \n")); + return; + } + else if (pDM_Odm->bdc_holdstate==1) + { + pDM_BdcTable->BDC_state=BDC_DIV_HOLD_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Force in [ DIV STATE] \n")); + return; + } + + //------------------------------------------------------------ + + + + //2 Mode 2 & 3 + if(pDM_BdcTable->BDC_Mode==BDC_MODE_2 ||pDM_BdcTable->BDC_Mode==BDC_MODE_3) + { + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n{ Try_flag , Try_counter } = { %d , %d } \n",pDM_BdcTable->BDC_Try_flag,pDM_BdcTable->BDC_Try_counter)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BDCcoexType = (( %d )) \n\n", pDM_BdcTable->BDCcoexType_wBfer)); + + // All Client have Bfer-Cap------------------------------- + if(pDM_BdcTable->num_Txbfer_Client == pDM_BdcTable->num_Client) //BFer STA Only?: yes + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BFer STA only? (( Yes ))\n")); + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + return; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BFer STA only? (( No ))\n")); + } + // + if(pDM_BdcTable->bAll_BFSta_Idle==FALSE && pDM_BdcTable->bAll_DivSta_Idle==TRUE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("All DIV-STA are idle, but BF-STA not\n")); + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_BFer_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + return; + } + else if(pDM_BdcTable->bAll_BFSta_Idle==TRUE && pDM_BdcTable->bAll_DivSta_Idle==FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("All BF-STA are idle, but DIV-STA not\n")); + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + return; + } + + //Select active mode-------------------------------------- + if(pDM_BdcTable->num_BfTar ==0) // Selsect_1, Selsect_2 + { + if(pDM_BdcTable->num_DivTar ==0) // Selsect_3 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Select active mode (( 1 )) \n")); + pDM_BdcTable->BDC_active_Mode=1; + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Select active mode (( 2 ))\n")); + pDM_BdcTable->BDC_active_Mode=2; + } + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + return; + } + else // num_BfTar > 0 + { + if(pDM_BdcTable->num_DivTar ==0) // Selsect_3 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Select active mode (( 3 ))\n")); + pDM_BdcTable->BDC_active_Mode=3; + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_BFer_TRAIN_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + return; + } + else // Selsect_4 + { + BDC_active_Mode=4; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Select active mode (( 4 ))\n")); + + if(BDC_active_Mode!=pDM_BdcTable->BDC_active_Mode) + { + pDM_BdcTable->BDC_active_Mode=4; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Change to active mode (( 4 )) & return!!! \n")); + return; + } + } + } + +#if 1 + if (pDM_Odm->bdc_holdstate==0xff) + { + pDM_BdcTable->BDC_state=BDC_DIV_HOLD_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Force in [ DIV STATE] \n")); + return; + } +#endif + + // Does Client number changed ? ------------------------------- + if(pDM_BdcTable->num_Client !=pDM_BdcTable->pre_num_Client) + { + pDM_BdcTable->BDC_Try_flag=0; + pDM_BdcTable->BDC_state=BDC_DIV_TRAIN_STATE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ The number of client has been changed !!!] return to (( BDC_DIV_TRAIN_STATE )) \n")); + } + pDM_BdcTable->pre_num_Client=pDM_BdcTable->num_Client; + + if( pDM_BdcTable->BDC_Try_flag==0) + { + //2 DIV_TRAIN_STATE (Mode 2-0) + if(pDM_BdcTable->BDC_state==BDC_DIV_TRAIN_STATE) + { + odm_DivTrainState_setting( pDM_Odm); + } + //2 BFer_TRAIN_STATE (Mode 2-1) + else if(pDM_BdcTable->BDC_state==BDC_BFer_TRAIN_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*****[2-1. BFer_TRAIN_STATE ]***** \n")); + + //if(pDM_BdcTable->num_BfTar==0) + //{ + // ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BF_tars exist? : (( No )), [ BDC_BFer_TRAIN_STATE ] >> [BDC_DIV_TRAIN_STATE] \n")); + // odm_DivTrainState_setting( pDM_Odm); + //} + //else //num_BfTar != 0 + //{ + pDM_BdcTable->BDC_Try_counter=2; + pDM_BdcTable->BDC_Try_flag=1; + pDM_BdcTable->BDC_state=BDC_DECISION_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BF_tars exist? : (( Yes )), [ BDC_BFer_TRAIN_STATE ] >> [BDC_DECISION_STATE] \n")); + //} + } + //2 DECISION_STATE (Mode 2-2) + else if(pDM_BdcTable->BDC_state==BDC_DECISION_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*****[2-2. DECISION_STATE]***** \n")); + //if(pDM_BdcTable->num_BfTar==0) + //{ + // ODM_AntDiv_Printk(("BF_tars exist? : (( No )), [ DECISION_STATE ] >> [BDC_DIV_TRAIN_STATE] \n")); + // odm_DivTrainState_setting( pDM_Odm); + //} + //else //num_BfTar != 0 + //{ + if(pDM_BdcTable->BF_pass==FALSE || pDM_BdcTable->DIV_pass == FALSE) + StopBF_flag=TRUE; + else + StopBF_flag=FALSE; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BF_tars exist? : (( Yes )), {BF_pass, DIV_pass, StopBF_flag } = { %d, %d, %d } \n" ,pDM_BdcTable->BF_pass,pDM_BdcTable->DIV_pass,StopBF_flag)); + + if(StopBF_flag==TRUE) //DIV_en + { + pDM_BdcTable->BDC_Hold_counter=10; //20 + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + pDM_BdcTable->BDC_state=BDC_DIV_HOLD_STATE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ StopBF_flag= ((TRUE)), BDC_DECISION_STATE ] >> [BDC_DIV_HOLD_STATE] \n")); + } + else //BF_en + { + pDM_BdcTable->BDC_Hold_counter=10; //20 + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + pDM_BdcTable->BDC_state=BDC_BF_HOLD_STATE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[StopBF_flag= ((FALSE)), BDC_DECISION_STATE ] >> [BDC_BF_HOLD_STATE] \n")); + } + //} + } + //2 BF-HOLD_STATE (Mode 2-3) + else if(pDM_BdcTable->BDC_state==BDC_BF_HOLD_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*****[2-3. BF_HOLD_STATE ]*****\n")); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BDC_Hold_counter = (( %d )) \n",pDM_BdcTable->BDC_Hold_counter )); + + if(pDM_BdcTable->BDC_Hold_counter==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ BDC_BF_HOLD_STATE ] >> [BDC_DIV_TRAIN_STATE] \n")); + odm_DivTrainState_setting( pDM_Odm); + } + else + { + pDM_BdcTable->BDC_Hold_counter--; + + //if(pDM_BdcTable->num_BfTar==0) + //{ + // ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BF_tars exist? : (( No )), [ BDC_BF_HOLD_STATE ] >> [BDC_DIV_TRAIN_STATE] \n")); + // odm_DivTrainState_setting( pDM_Odm); + //} + //else //num_BfTar != 0 + //{ + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BF_tars exist? : (( Yes ))\n")); + pDM_BdcTable->BDC_state=BDC_BF_HOLD_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVOFF_CSION); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ BDC_BF_HOLD_STATE ] >> [BDC_BF_HOLD_STATE] \n")); + //} + } + + } + //2 DIV-HOLD_STATE (Mode 2-4) + else if(pDM_BdcTable->BDC_state==BDC_DIV_HOLD_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*****[2-4. DIV_HOLD_STATE ]*****\n")); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("BDC_Hold_counter = (( %d )) \n",pDM_BdcTable->BDC_Hold_counter )); + + if(pDM_BdcTable->BDC_Hold_counter==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ BDC_DIV_HOLD_STATE ] >> [BDC_DIV_TRAIN_STATE] \n")); + odm_DivTrainState_setting( pDM_Odm); + } + else + { + pDM_BdcTable->BDC_Hold_counter--; + pDM_BdcTable->BDC_state=BDC_DIV_HOLD_STATE; + odm_BDCcoexType_withBferClient( pDM_Odm, DIVON_CSIOFF); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ BDC_DIV_HOLD_STATE ] >> [BDC_DIV_HOLD_STATE] \n")); + } + + } + + } + else if( pDM_BdcTable->BDC_Try_flag==1) + { + //2 Set Training Counter + if(pDM_BdcTable->BDC_Try_counter >1) + { + pDM_BdcTable->BDC_Try_counter--; + if(pDM_BdcTable->BDC_Try_counter ==1) + pDM_BdcTable->BDC_Try_flag=0; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Training !!\n")); + //return ; + } + + } + + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n[end]\n")); + + #endif //#if(DM_ODM_SUPPORT_TYPE == ODM_AP) + + + + + + +} + +#endif +#endif //#ifdef BEAMFORMING_SUPPORT + + +#if (RTL8188E_SUPPORT == 1) + + +VOID +odm_RX_HWAntDiv_Init_88E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + + if(pDM_Odm->mp_mode == TRUE) + { + 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 + + pDM_FatTable->enable_ctrl_frame_antdiv = 1; +} + +VOID +odm_TRX_HWAntDiv_Init_88E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(pDM_Odm->mp_mode == TRUE) + { + 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, 0x0201); /*Reg914=3'b010, Reg915=3'b001*/ + + pDM_FatTable->enable_ctrl_frame_antdiv = 1; +} + + +#if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) +VOID +odm_Smart_HWAntDiv_Init_88E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte value32, i; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + 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; + } + + pDM_FatTable->TrainIdx = 0; + pDM_FatTable->FAT_State = FAT_PREPARE_STATE; + + pDM_Odm->fat_comb_a=5; + pDM_Odm->antdiv_intvl = 0x64; // 100ms + + for(i=0; i<6; i++) + { + pDM_FatTable->Bssid[i] = 0; + } + for(i=0; i< (pDM_Odm->fat_comb_a) ; i++) + { + pDM_FatTable->antSumRSSI[i] = 0; + pDM_FatTable->antRSSIcnt[i] = 0; + pDM_FatTable->antAveRSSI[i] = 0; + } + + //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, 0); //Regb2c[31]=1'b1 //output at CS only + ODM_SetBBReg(pDM_Odm, 0xca4 , bMaskDWord, 0x000000a0); + + //antenna mapping table + if(pDM_Odm->fat_comb_a == 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(!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, 4); // 0: 3b'000 + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte1, 2); // 1: 3b'001 + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte2, 0); // 2: 3b'010 + ODM_SetBBReg(pDM_Odm, 0x914 , bMaskByte3, 1); // 3: 3b'011 + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte0, 3); // 4: 3b'100 + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte1, 5); // 5: 3b'101 + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte2, 6); // 6: 3b'110 + ODM_SetBBReg(pDM_Odm, 0x918 , bMaskByte3, 255); // 7: 3b'111 + } + } + + //Default Ant Setting when no fast training + 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, 0);//Default TX + + //Enter Traing state + ODM_SetBBReg(pDM_Odm, 0x864 , BIT2|BIT1|BIT0, (pDM_Odm->fat_comb_a-1)); //Reg864[2:0]=3'd6 //ant combination=reg864[2:0]+1 + + //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 + +#endif //#if (RTL8188E_SUPPORT == 1) + + +#if (RTL8192E_SUPPORT == 1) +VOID +odm_RX_HWAntDiv_Init_92E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(pDM_Odm->mp_mode == TRUE) + { + 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, 0); //(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 + + #ifdef ODM_EVM_ENHANCE_ANTDIV + //EVM enhance AntDiv method init---------------------------------------------------------------------- + pDM_FatTable->EVM_method_enable=0; + pDM_FatTable->FAT_State = NORMAL_STATE_MIAN; + pDM_Odm->antdiv_intvl = 0x64; + ODM_SetBBReg(pDM_Odm, 0x910 , 0x3f, 0xf ); + pDM_Odm->antdiv_evm_en=1; + //pDM_Odm->antdiv_period=1; + + #endif + +} + +VOID +odm_TRX_HWAntDiv_Init_92E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + if(pDM_Odm->mp_mode == TRUE) + { + 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=[ Only for DIR605, 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 + ODM_SetMACReg(pDM_Odm, 0x4c, BIT29, 1); //path-A , RFE_CTRL_8 + //[BB] + ODM_SetBBReg(pDM_Odm, 0x944 , BIT3, 1); //RFE_buffer + ODM_SetBBReg(pDM_Odm, 0x944 , BIT8, 1); + ODM_SetBBReg(pDM_Odm, 0x940 , BIT7|BIT6, 0x0); // r_rfe_path_sel_ (RFE_CTRL_3) + ODM_SetBBReg(pDM_Odm, 0x940 , BIT17|BIT16, 0x0); // r_rfe_path_sel_ (RFE_CTRL_8) + 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 , BIT8, 1); //rfe_inv (RFE_CTRL_8) + ODM_SetBBReg(pDM_Odm, 0x930 , 0xF000, 0x8); //path-A , RFE_CTRL_3 + ODM_SetBBReg(pDM_Odm, 0x934 , 0xF, 0x8); //path-A , RFE_CTRL_8 + //3 ------------------------- + + //Pin Settings + ODM_SetBBReg(pDM_Odm, 0xC50 , BIT8, 0); //path-A //disable CS/CG switch + +/* Let it follows PHY_REG for bit9 setting + if(pDM_Odm->priv->pshare->rf_ft_var.use_ext_pa || pDM_Odm->priv->pshare->rf_ft_var.use_ext_lna) + ODM_SetBBReg(pDM_Odm, 0xC50 , BIT9, 1);//path-A //output at CS + else + ODM_SetBBReg(pDM_Odm, 0xC50 , BIT9, 0); //path-A //output at CG ->normal power +*/ + + 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, 0); //(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) + + #ifdef ODM_EVM_ENHANCE_ANTDIV + //EVM enhance AntDiv method init---------------------------------------------------------------------- + pDM_FatTable->EVM_method_enable=0; + pDM_FatTable->FAT_State = NORMAL_STATE_MIAN; + pDM_Odm->antdiv_intvl = 0x64; + ODM_SetBBReg(pDM_Odm, 0x910 , 0x3f, 0xf ); + pDM_Odm->antdiv_evm_en=1; + //pDM_Odm->antdiv_period=1; + #endif +} + +#if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) +VOID +odm_Smart_HWAntDiv_Init_92E( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8192E AntDiv_Init => AntDivType=[CG_TRX_SMART_ANTDIV]\n")); +} +#endif + +#endif //#if (RTL8192E_SUPPORT == 1) + + +#if (RTL8723B_SUPPORT == 1) +VOID +odm_TRX_HWAntDiv_Init_8723B( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 + +} + + + +VOID +odm_S0S1_SWAntDiv_Init_8723B( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 = SWAW_STEP_INIT; + pDM_SWAT_Table->Double_chk_flag = 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] + ODM_SetBBReg(pDM_Odm, 0x80C , BIT21, 0); //TX Ant by Reg + +} + +VOID +ODM_UpdateRxIdleAnt_8723B( + IN PVOID pDM_VOID, + IN u1Byte Ant, + IN u4Byte DefaultAnt, + IN u4Byte OptionalAnt +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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; + + 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; + } + +#if 0 + // 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); +#else + + 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: Success to set RX antenna\n")); + +#endif +} + +BOOLEAN +phydm_IsBtEnable_8723b( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte bt_state; + /*u4Byte reg75;*/ + + /*reg75 = ODM_GetBBReg(pDM_Odm, 0x74 , BIT8);*/ + /*ODM_SetBBReg(pDM_Odm, 0x74 , BIT8, 0x0);*/ + ODM_SetBBReg(pDM_Odm, 0xa0 , BIT24|BIT25|BIT26, 0x5); + bt_state = ODM_GetBBReg(pDM_Odm, 0xa0 , (BIT3|BIT2|BIT1|BIT0)); + /*ODM_SetBBReg(pDM_Odm, 0x74 , BIT8, reg75);*/ + + if ((bt_state == 4) || (bt_state == 7) || (bt_state == 9) || (bt_state == 13)) + return TRUE; + else + return FALSE; +} +#endif //#if (RTL8723B_SUPPORT == 1) + +#if (RTL8821A_SUPPORT == 1) +#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 +VOID +phydm_hl_smart_ant_type1_init_8821a( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte value32; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***8821A SmartAnt_Init => AntDivType=[Hong-Lin Smart Ant Type1]\n")); + + /*---------------------------------------- + GPIO 2-3 for Beam control + reg0x66[2]=0 + reg0x44[27:26] = 0 + reg0x44[23:16] //enable_output for P_GPIO[7:0] + reg0x44[15:8] //output_value for P_GPIO[7:0] + reg0x40[1:0] = 0 //GPIO function + ------------------------------------------*/ + + /*GPIO Setting*/ + ODM_SetMACReg(pDM_Odm, 0x64 , BIT18, 0); + ODM_SetMACReg(pDM_Odm, 0x44 , BIT27|BIT26, 0); + ODM_SetMACReg(pDM_Odm, 0x44 , BIT19|BIT18, 0x3); /*enable_output for P_GPIO[3:2]*/ + /*ODM_SetMACReg(pDM_Odm, 0x44 , BIT11|BIT10, 0);*/ /*output value*/ + ODM_SetMACReg(pDM_Odm, 0x40 , BIT1|BIT0, 0); /*GPIO function*/ + + /*Hong_lin smart antenna HW Setting*/ + pdm_sat_table->data_codeword_bit_num = 24;/*max=32*/ + pdm_sat_table->beam_patten_num_each_ant = 4; + + #if DEV_BUS_TYPE == RT_SDIO_INTERFACE + pdm_sat_table->latch_time = 100; /*mu sec*/ + #elif DEV_BUS_TYPE == RT_USB_INTERFACE + pdm_sat_table->latch_time = 100; /*mu sec*/ + #endif + pdm_sat_table->pkt_skip_statistic_en = 0; + + pdm_sat_table->ant_num = 2;/*max=8*/ + + pdm_sat_table->fix_beam_pattern_en = 0; + pdm_sat_table->decision_holding_period = 0; + + /*beam training setting*/ + pdm_sat_table->pkt_counter = 0; + pdm_sat_table->per_beam_training_pkt_num = 10; + + /*set default beam*/ + pdm_sat_table->fast_training_beam_num = 0; + pdm_sat_table->pre_fast_training_beam_num = pdm_sat_table->fast_training_beam_num; + phydm_set_all_ant_same_beam_num(pDM_Odm); + + pDM_FatTable->FAT_State = FAT_BEFORE_LINK_STATE; + + /*[BB] FAT Setting*/ + ODM_SetBBReg(pDM_Odm, 0xc08 , BIT18|BIT17|BIT16, pdm_sat_table->ant_num); + ODM_SetBBReg(pDM_Odm, 0xc08 , BIT31, 0); /*increase ant num every FAT period 0:+1, 1+2*/ + ODM_SetBBReg(pDM_Odm, 0x8c4 , BIT2|BIT1, 1); /*change cca antenna timming threshold if no CCA occurred: 0:200ms / 1:100ms / 2:no use / 3: 300*/ + ODM_SetBBReg(pDM_Odm, 0x8c4 , BIT0, 1); /*FAT_watchdog_en*/ + + 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 match MAC Addr*/ + ODM_SetMACReg(pDM_Odm, 0x7b4, 0xFFFF, 0);/*Match MAC ADDR*/ + ODM_SetMACReg(pDM_Odm, 0x7b0, bMaskDWord, 0); + +} +#endif + +VOID +odm_TRX_HWAntDiv_Init_8821A( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + 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); + + //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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + + 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); + + //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 = SWAW_STEP_INIT; + pDM_SWAT_Table->Double_chk_flag = 0; + 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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) + +#if (RTL8188F_SUPPORT == 1) +VOID +odm_S0S1_SWAntDiv_Init_8188F( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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, ("***8188F AntDiv_Init => AntDivType=[ S0S1_SW_AntDiv]\n")); + + + /*GPIO Setting*/ + /*ODM_SetMACReg(pDM_Odm, 0x64 , BIT18, 0); */ + /*ODM_SetMACReg(pDM_Odm, 0x44 , BIT28|BIT27, 0);*/ + ODM_SetMACReg(pDM_Odm, 0x44 , BIT20|BIT19, 0x3); /*enable_output for P_GPIO[4:3]*/ + /*ODM_SetMACReg(pDM_Odm, 0x44 , BIT12|BIT11, 0);*/ /*output value*/ + /*ODM_SetMACReg(pDM_Odm, 0x40 , BIT1|BIT0, 0);*/ /*GPIO function*/ + + pDM_FatTable->bBecomeLinked = FALSE; + pDM_SWAT_Table->try_flag = SWAW_STEP_INIT; + pDM_SWAT_Table->Double_chk_flag = 0; +} + +VOID +phydm_update_rx_idle_antenna_8188F( + IN PVOID pDM_VOID, + IN u4Byte default_ant +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte codeword; + + if (default_ant == ANT1_2G) + codeword = 1; /*2'b01*/ + else + codeword = 2;/*2'b10*/ + + ODM_SetMACReg(pDM_Odm, 0x44 , (BIT12|BIT11), codeword); /*GPIO[4:3] output value*/ +} + +#endif + + + +#ifdef ODM_EVM_ENHANCE_ANTDIV + +VOID +odm_EVM_FastAnt_Reset( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + pDM_FatTable->EVM_method_enable=0; + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + pDM_FatTable->FAT_State = NORMAL_STATE_MIAN; + pDM_Odm->antdiv_period=0; + ODM_SetMACReg(pDM_Odm, 0x608, BIT8, 0); +} + + +VOID +odm_EVM_Enhance_AntDiv( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte Main_RSSI, Aux_RSSI ; + u4Byte Main_CRC_utility=0,Aux_CRC_utility=0,utility_ratio=1; + u4Byte Main_EVM, Aux_EVM,Diff_RSSI=0,diff_EVM=0; + u1Byte score_EVM=0,score_CRC=0; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte value32, i; + BOOLEAN Main_above1=FALSE,Aux_above1=FALSE; + BOOLEAN Force_antenna=FALSE; + PSTA_INFO_T pEntry; + pDM_FatTable->TargetAnt_enhance=0xFF; + + + if((pDM_Odm->SupportICType & ODM_EVM_ENHANCE_ANTDIV_SUPPORT_IC)) + { + if(pDM_Odm->bOneEntryOnly) + { + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[One Client only] \n")); + i = pDM_Odm->OneEntry_MACID; + + 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((Main_RSSI==0 && Aux_RSSI !=0 && Aux_RSSI>=FORCE_RSSI_DIFF) || (Main_RSSI!=0 && Aux_RSSI==0 && Main_RSSI>=FORCE_RSSI_DIFF)) + { + Diff_RSSI=FORCE_RSSI_DIFF; + } + else if(Main_RSSI!=0 && Aux_RSSI !=0) + { + Diff_RSSI = (Main_RSSI>=Aux_RSSI)?(Main_RSSI-Aux_RSSI):(Aux_RSSI-Main_RSSI); + } + + + 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)); + + if( ((Main_RSSI>=Evm_RSSI_TH_High||Aux_RSSI>=Evm_RSSI_TH_High )|| (pDM_FatTable->EVM_method_enable==1) ) + //&& (Diff_RSSI <= FORCE_RSSI_DIFF + 1) + ) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[> TH_H || EVM_method_enable==1] && ")); + + if(((Main_RSSI>=Evm_RSSI_TH_Low)||(Aux_RSSI>=Evm_RSSI_TH_Low) )) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[> TH_L ] \n")); + + //2 [ Normal state Main] + if(pDM_FatTable->FAT_State == NORMAL_STATE_MIAN) + { + + pDM_FatTable->EVM_method_enable=1; + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + pDM_Odm->antdiv_period=3; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ start training: MIAN] \n")); + pDM_FatTable->MainAntEVM_Sum[i] = 0; + pDM_FatTable->AuxAntEVM_Sum[i] = 0; + pDM_FatTable->MainAntEVM_Cnt[i] = 0; + pDM_FatTable->AuxAntEVM_Cnt[i] = 0; + + pDM_FatTable->FAT_State = NORMAL_STATE_AUX; + ODM_SetMACReg(pDM_Odm, 0x608, BIT8, 1); //Accept CRC32 Error packets. + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + + pDM_FatTable->CRC32_Ok_Cnt=0; + pDM_FatTable->CRC32_Fail_Cnt=0; + ODM_SetTimer(pDM_Odm,&pDM_Odm->EVM_FastAntTrainingTimer, pDM_Odm->antdiv_intvl ); //m + } + //2 [ Normal state Aux ] + else if(pDM_FatTable->FAT_State == NORMAL_STATE_AUX) + { + pDM_FatTable->MainCRC32_Ok_Cnt=pDM_FatTable->CRC32_Ok_Cnt; + pDM_FatTable->MainCRC32_Fail_Cnt=pDM_FatTable->CRC32_Fail_Cnt; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ start training: AUX] \n")); + pDM_FatTable->FAT_State = TRAINING_STATE; + ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT); + + pDM_FatTable->CRC32_Ok_Cnt=0; + pDM_FatTable->CRC32_Fail_Cnt=0; + ODM_SetTimer(pDM_Odm,&pDM_Odm->EVM_FastAntTrainingTimer, pDM_Odm->antdiv_intvl ); //ms + } + else if(pDM_FatTable->FAT_State == TRAINING_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Training state ] \n")); + pDM_FatTable->FAT_State = NORMAL_STATE_MIAN; + + //3 [CRC32 statistic] + pDM_FatTable->AuxCRC32_Ok_Cnt=pDM_FatTable->CRC32_Ok_Cnt; + pDM_FatTable->AuxCRC32_Fail_Cnt=pDM_FatTable->CRC32_Fail_Cnt; + + if( (pDM_FatTable->MainCRC32_Ok_Cnt >= ((pDM_FatTable->AuxCRC32_Ok_Cnt)<<1)) || (Diff_RSSI>=18)) + { + pDM_FatTable->TargetAnt_CRC32=MAIN_ANT; + Force_antenna=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CRC32 Force Main \n")); + } + else if((pDM_FatTable->AuxCRC32_Ok_Cnt >= ((pDM_FatTable->MainCRC32_Ok_Cnt)<<1)) || (Diff_RSSI>=18)) + { + pDM_FatTable->TargetAnt_CRC32=AUX_ANT; + Force_antenna=TRUE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("CRC32 Force Aux \n")); + } + else + { + if(pDM_FatTable->MainCRC32_Fail_Cnt<=5) + pDM_FatTable->MainCRC32_Fail_Cnt=5; + + if(pDM_FatTable->AuxCRC32_Fail_Cnt<=5) + pDM_FatTable->AuxCRC32_Fail_Cnt=5; + + if(pDM_FatTable->MainCRC32_Ok_Cnt >pDM_FatTable->MainCRC32_Fail_Cnt ) + Main_above1=TRUE; + + if(pDM_FatTable->AuxCRC32_Ok_Cnt >pDM_FatTable->AuxCRC32_Fail_Cnt ) + Aux_above1=TRUE; + + if(Main_above1==TRUE && Aux_above1==FALSE) + { + Force_antenna=TRUE; + pDM_FatTable->TargetAnt_CRC32=MAIN_ANT; + } + else if(Main_above1==FALSE && Aux_above1==TRUE) + { + Force_antenna=TRUE; + pDM_FatTable->TargetAnt_CRC32=AUX_ANT; + } + else if(Main_above1==TRUE && Aux_above1==TRUE) + { + Main_CRC_utility=((pDM_FatTable->MainCRC32_Ok_Cnt)<<7)/pDM_FatTable->MainCRC32_Fail_Cnt; + Aux_CRC_utility=((pDM_FatTable->AuxCRC32_Ok_Cnt)<<7)/pDM_FatTable->AuxCRC32_Fail_Cnt; + pDM_FatTable->TargetAnt_CRC32 = (Main_CRC_utility==Aux_CRC_utility)?(pDM_FatTable->pre_TargetAnt_enhance):((Main_CRC_utility>=Aux_CRC_utility)?MAIN_ANT:AUX_ANT); + + if(Main_CRC_utility!=0 && Aux_CRC_utility!=0) + { + if(Main_CRC_utility>=Aux_CRC_utility) + utility_ratio=(Main_CRC_utility<<1)/Aux_CRC_utility; + else + utility_ratio=(Aux_CRC_utility<<1)/Main_CRC_utility; + } + } + else if(Main_above1==FALSE && Aux_above1==FALSE) + { + if(pDM_FatTable->MainCRC32_Ok_Cnt==0) + pDM_FatTable->MainCRC32_Ok_Cnt=1; + if(pDM_FatTable->AuxCRC32_Ok_Cnt==0) + pDM_FatTable->AuxCRC32_Ok_Cnt=1; + + Main_CRC_utility=((pDM_FatTable->MainCRC32_Fail_Cnt)<<7)/pDM_FatTable->MainCRC32_Ok_Cnt; + Aux_CRC_utility=((pDM_FatTable->AuxCRC32_Fail_Cnt)<<7)/pDM_FatTable->AuxCRC32_Ok_Cnt; + pDM_FatTable->TargetAnt_CRC32 = (Main_CRC_utility==Aux_CRC_utility)?(pDM_FatTable->pre_TargetAnt_enhance):((Main_CRC_utility<=Aux_CRC_utility)?MAIN_ANT:AUX_ANT); + + if(Main_CRC_utility!=0 && Aux_CRC_utility!=0) + { + if(Main_CRC_utility>=Aux_CRC_utility) + utility_ratio=(Main_CRC_utility<<1)/(Aux_CRC_utility); + else + utility_ratio=(Aux_CRC_utility<<1)/(Main_CRC_utility); + } + } + } + ODM_SetMACReg(pDM_Odm, 0x608, BIT8, 0);//NOT Accept CRC32 Error packets. + + //3 [EVM statistic] + Main_EVM = (pDM_FatTable->MainAntEVM_Cnt[i]!=0)?(pDM_FatTable->MainAntEVM_Sum[i]/pDM_FatTable->MainAntEVM_Cnt[i]):0; + Aux_EVM = (pDM_FatTable->AuxAntEVM_Cnt[i]!=0)?(pDM_FatTable->AuxAntEVM_Sum[i]/pDM_FatTable->AuxAntEVM_Cnt[i]):0; + pDM_FatTable->TargetAnt_EVM = (Main_EVM==Aux_EVM)?(pDM_FatTable->pre_TargetAnt_enhance):((Main_EVM>=Aux_EVM)?MAIN_ANT:AUX_ANT); + + if((Main_EVM==0 || Aux_EVM==0)) + diff_EVM=0; + else if(Main_EVM>=Aux_EVM) + diff_EVM=Main_EVM-Aux_EVM; + else + diff_EVM=Aux_EVM-Main_EVM; + + //2 [ Decision state ] + if(pDM_FatTable->TargetAnt_EVM ==pDM_FatTable->TargetAnt_CRC32 ) + { + if( (utility_ratio<2 && Force_antenna==FALSE) && diff_EVM<=2) + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->pre_TargetAnt_enhance; + else + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->TargetAnt_EVM; + } + else if(diff_EVM<=2 && (utility_ratio > 4 && Force_antenna==FALSE)) + { + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->TargetAnt_CRC32; + } + else if(diff_EVM>=20) // + { + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->TargetAnt_EVM; + } + else if(utility_ratio>=6 && Force_antenna==FALSE) // utility_ratio>3 + { + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->TargetAnt_CRC32; + } + else + { + if(Force_antenna==TRUE) + score_CRC=3; + else if(utility_ratio>=4) //>2 + score_CRC=2; + else if(utility_ratio>=3) //>1.5 + score_CRC=1; + else + score_CRC=0; + + if(diff_EVM>=10) + score_EVM=2; + else if(diff_EVM>=5) + score_EVM=1; + else + score_EVM=0; + + if(score_CRC>score_EVM) + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->TargetAnt_CRC32; + else if(score_CRCTargetAnt_enhance=pDM_FatTable->TargetAnt_EVM; + else + pDM_FatTable->TargetAnt_enhance=pDM_FatTable->pre_TargetAnt_enhance; + } + pDM_FatTable->pre_TargetAnt_enhance=pDM_FatTable->TargetAnt_enhance; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : MainEVM_Cnt = (( %d )) , Main_EVM= (( %d )) \n",i, pDM_FatTable->MainAntEVM_Cnt[i], Main_EVM)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : AuxEVM_Cnt = (( %d )) , Aux_EVM = (( %d )) \n" ,i, pDM_FatTable->AuxAntEVM_Cnt[i] , Aux_EVM)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** TargetAnt_EVM = (( %s ))\n", ( pDM_FatTable->TargetAnt_EVM ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("M_CRC_Ok = (( %d )) , M_CRC_Fail = (( %d )), Main_CRC_utility = (( %d )) \n" , pDM_FatTable->MainCRC32_Ok_Cnt, pDM_FatTable->MainCRC32_Fail_Cnt,Main_CRC_utility)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("A_CRC_Ok = (( %d )) , A_CRC_Fail = (( %d )), Aux_CRC_utility = (( %d )) \n" , pDM_FatTable->AuxCRC32_Ok_Cnt, pDM_FatTable->AuxCRC32_Fail_Cnt,Aux_CRC_utility)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** TargetAnt_CRC32 = (( %s ))\n", ( pDM_FatTable->TargetAnt_CRC32 ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("****** TargetAnt_enhance = (( %s ))******\n", ( pDM_FatTable->TargetAnt_enhance ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + + + } + } + else // RSSI< = Evm_RSSI_TH_Low + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ TH_L ] \n")); + odm_EVM_FastAnt_Reset(pDM_Odm); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[escape from> TH_H || EVM_method_enable==1] \n")); + odm_EVM_FastAnt_Reset(pDM_Odm); + } + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[multi-Client] \n")); + odm_EVM_FastAnt_Reset(pDM_Odm); + } + } +} + +VOID +odm_EVM_FastAntTrainingCallback( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_EVM_FastAntTrainingCallback****** \n")); + odm_HW_AntDiv(pDM_Odm); +} +#endif + +VOID +odm_HW_AntDiv( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte i,MinMaxRSSI=0xFF, AntDivMaxRSSI=0, MaxRSSI=0, LocalMaxRSSI; + u4Byte Main_RSSI, Aux_RSSI; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u1Byte RxIdleAnt = pDM_FatTable->RxIdleAnt, TargetAnt = 7; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + PSTA_INFO_T pEntry; + + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + u4Byte TH1=500000; + u4Byte TH2=10000000; + u4Byte MA_rx_Temp, degrade_TP_temp, improve_TP_temp; + u1Byte Monitor_RSSI_threshold=30; + + pDM_BdcTable->BF_pass=TRUE; + pDM_BdcTable->DIV_pass=TRUE; + pDM_BdcTable->bAll_DivSta_Idle=TRUE; + pDM_BdcTable->bAll_BFSta_Idle=TRUE; + pDM_BdcTable->num_BfTar=0 ; + pDM_BdcTable->num_DivTar=0; + pDM_BdcTable->num_Client=0; + #endif + #endif + + 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_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_REG); + pDM_Odm->antdiv_period=0; + + 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); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm , TX_BY_DESC); + + //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_RTL8881A) + // 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] + } + + //2 BDC Init + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + odm_BDC_Init(pDM_Odm); + #endif + #endif + + #ifdef ODM_EVM_ENHANCE_ANTDIV + odm_EVM_FastAnt_Reset(pDM_Odm); + #endif + } + } + + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n AntDiv Start =>\n")); + + #ifdef ODM_EVM_ENHANCE_ANTDIV + if(pDM_Odm->antdiv_evm_en==1) + { + odm_EVM_Enhance_AntDiv(pDM_Odm); + if(pDM_FatTable->FAT_State !=NORMAL_STATE_MIAN) + return; + } + else + { + odm_EVM_FastAnt_Reset(pDM_Odm); + } + #endif + + //2 BDC Mode Arbitration + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_Odm->antdiv_evm_en == 0 ||pDM_FatTable->EVM_method_enable==0) + { + odm_BF_AntDiv_ModeArbitration(pDM_Odm); + } + #endif + #endif + + 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); + + //ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,ODM_DBG_LOUD,("*** SupportICType=[%d] \n",pDM_Odm->SupportICType)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : Main_Cnt = (( %d )) , Main_RSSI= (( %d )) \n",i, pDM_FatTable->MainAnt_Cnt[i], Main_RSSI)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : Aux_Cnt = (( %d )) , Aux_RSSI = (( %d )) \n" ,i, 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))); + + 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; + } + + #ifdef ODM_EVM_ENHANCE_ANTDIV + if(pDM_Odm->antdiv_evm_en==1) + { + if(pDM_FatTable->TargetAnt_enhance!=0xFF) + { + TargetAnt=pDM_FatTable->TargetAnt_enhance; + RxIdleAnt = pDM_FatTable->TargetAnt_enhance; + } + } + #endif + + //2 Select TX Antenna + if(pDM_Odm->AntDivType != CGCS_RX_HW_ANTDIV) + { + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_BdcTable->w_BFee_Client[i]==0) + #endif + #endif + { + odm_UpdateTxAnt(pDM_Odm, TargetAnt, i); + } + } + + //------------------------------------------------------------ + + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + + pDM_BdcTable->num_Client++; + + if(pDM_BdcTable->BDC_Mode==BDC_MODE_2 ||pDM_BdcTable->BDC_Mode==BDC_MODE_3) + { + //2 Byte Counter + + MA_rx_Temp= (pEntry->rx_byte_cnt_LowMAW)<<3 ; // RX TP ( bit /sec) + + if(pDM_BdcTable->BDC_state==BDC_BFer_TRAIN_STATE) + { + pDM_BdcTable->MA_rx_TP_DIV[i]= MA_rx_Temp ; + } + else + { + pDM_BdcTable->MA_rx_TP[i] =MA_rx_Temp ; + } + + if( (MA_rx_Temp < TH2) && (MA_rx_Temp > TH1) && (LocalMaxRSSI<=Monitor_RSSI_threshold)) + { + if(pDM_BdcTable->w_BFer_Client[i]==1) // Bfer_Target + { + pDM_BdcTable->num_BfTar++; + + if(pDM_BdcTable->BDC_state==BDC_DECISION_STATE && pDM_BdcTable->BDC_Try_flag==0) + { + improve_TP_temp = (pDM_BdcTable->MA_rx_TP_DIV[i] * 9)>>3 ; //* 1.125 + pDM_BdcTable->BF_pass = (pDM_BdcTable->MA_rx_TP[i] > improve_TP_temp)?TRUE:FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : { MA_rx_TP,improve_TP_temp , MA_rx_TP_DIV, BF_pass}={ %d, %d, %d , %d } \n" ,i,pDM_BdcTable->MA_rx_TP[i],improve_TP_temp,pDM_BdcTable->MA_rx_TP_DIV[i], pDM_BdcTable->BF_pass )); + } + } + else// DIV_Target + { + pDM_BdcTable->num_DivTar++; + + if(pDM_BdcTable->BDC_state==BDC_DECISION_STATE && pDM_BdcTable->BDC_Try_flag==0) + { + degrade_TP_temp=(pDM_BdcTable->MA_rx_TP_DIV[i]*5)>>3;//* 0.625 + pDM_BdcTable->DIV_pass = (pDM_BdcTable->MA_rx_TP[i] >degrade_TP_temp)?TRUE:FALSE; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : { MA_rx_TP, degrade_TP_temp , MA_rx_TP_DIV, DIV_pass}=\n{ %d, %d, %d , %d } \n" ,i,pDM_BdcTable->MA_rx_TP[i],degrade_TP_temp,pDM_BdcTable->MA_rx_TP_DIV[i], pDM_BdcTable->DIV_pass )); + } + } + } + + if(MA_rx_Temp > TH1) + { + if(pDM_BdcTable->w_BFer_Client[i]==1) // Bfer_Target + { + pDM_BdcTable->bAll_BFSta_Idle=FALSE; + } + else// DIV_Target + { + pDM_BdcTable->bAll_DivSta_Idle=FALSE; + } + } + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : { BFmeeCap , BFmerCap} = { %d , %d } \n" ,i, pDM_BdcTable->w_BFee_Client[i] , pDM_BdcTable->w_BFer_Client[i])); + + if(pDM_BdcTable->BDC_state==BDC_BFer_TRAIN_STATE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : MA_rx_TP_DIV = (( %d )) \n",i,pDM_BdcTable->MA_rx_TP_DIV[i] )); + + } + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** Client[ %d ] : MA_rx_TP = (( %d )) \n",i,pDM_BdcTable->MA_rx_TP[i] )); + } + + } + #endif + #endif + + } + + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_BdcTable->BDC_Try_flag==0) + #endif + #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 & TX Antenna(Because of HW Bug ) + #if(DM_ODM_SUPPORT_TYPE == ODM_AP ) + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** RxIdleAnt = (( %s ))\n\n", ( RxIdleAnt ==MAIN_ANT)?"MAIN_ANT":"AUX_ANT")); + + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_BdcTable->BDC_Mode==BDC_MODE_1 ||pDM_BdcTable->BDC_Mode==BDC_MODE_3) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("*** BDC_RxIdleUpdate_counter = (( %d ))\n", pDM_BdcTable->BDC_RxIdleUpdate_counter)); + + if(pDM_BdcTable->BDC_RxIdleUpdate_counter==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***Update RxIdle Antenna!!! \n")); + pDM_BdcTable->BDC_RxIdleUpdate_counter=30; + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt); + } + else + { + pDM_BdcTable->BDC_RxIdleUpdate_counter--; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***NOT update RxIdle Antenna because of BF ( need to fix TX-ant)\n")); + } + } + else + #endif + #endif + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt); + #else + + ODM_UpdateRxIdleAnt(pDM_Odm, RxIdleAnt); + + #endif//#if(DM_ODM_SUPPORT_TYPE == ODM_AP) + + + + //2 BDC Main Algorithm + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + if(pDM_Odm->antdiv_evm_en ==0 ||pDM_FatTable->EVM_method_enable==0) + { + odm_BDCcoex_BFeeRxDiv_Arbitration(pDM_Odm); + } + #endif + #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; +} + + + +#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + +VOID +odm_S0S1_SWAntDiv_Reset( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 = SWAW_STEP_INIT; + pDM_SWAT_Table->Double_chk_flag = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_S0S1_SWAntDiv_Reset(): pDM_FatTable->bBecomeLinked = %d\n", pDM_FatTable->bBecomeLinked)); +} + +VOID +odm_S0S1_SwAntDiv( + IN PVOID pDM_VOID, + IN u1Byte Step + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u4Byte i, MinMaxRSSI = 0xFF, LocalMaxRSSI, LocalMinRSSI; + u4Byte Main_RSSI, Aux_RSSI; + u1Byte HighTraffic_TrainTime_U = 0x32, HighTraffic_TrainTime_L = 0, Train_time_temp; + u1Byte LowTraffic_TrainTime_U = 200, LowTraffic_TrainTime_L = 0; + u1Byte RxIdleAnt = pDM_SWAT_Table->PreAntenna, TargetAnt, nextAnt = 0; + PSTA_INFO_T pEntry = NULL; + u4Byte value32; + + + 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) + { + if (pDM_Odm->SupportICType == ODM_RTL8723B) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set REG 948[9:6]=0x0\n")); + 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 (RTL8723B_SUPPORT == 1) + 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); + #endif + + 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_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + } + + 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 == SWAW_STEP_INIT) { + + pDM_SWAT_Table->try_flag = SWAW_STEP_PEEK; + 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 peek!\n\n")); + return; + + } else { + + //1 Normal State (Begin Trying) + if (pDM_SWAT_Table->try_flag == SWAW_STEP_PEEK) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("TxOkCnt=(( %llu )), RxOkCnt=(( %llu )), TrafficLoad = (%d))\n", pDM_Odm->curTxOkCnt, pDM_Odm->curRxOkCnt, pDM_Odm->TrafficLoad)); + + if (pDM_Odm->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; /*10ms~200ms*/ + + 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)); + + } else if ((pDM_Odm->TrafficLoad == TRAFFIC_MID) || (pDM_Odm->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; /*10ms~200ms*/ + + 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)); + + } else { + pDM_SWAT_Table->Train_time = 0xc8; /*200ms*/ + + } + + //----------------- + + 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 >= RSSI_CHECK_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)); + + pDM_SWAT_Table->reset_idx++; + + //---double check flag--- + if ((pDM_FatTable->MinMaxRSSI > RSSI_CHECK_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, RSSI_CHECK_THRESHOLD)); + + pDM_SWAT_Table->Double_chk_flag =1; + pDM_SWAT_Table->try_flag = SWAW_STEP_DETERMINE; + 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->phydm_SwAntennaSwitchTimer), pDM_SWAT_Table->Train_time); /*ms*/ + return; + } + + nextAnt = (pDM_FatTable->RxIdleAnt == MAIN_ANT)? AUX_ANT : MAIN_ANT; + + pDM_SWAT_Table->try_flag = SWAW_STEP_DETERMINE; + + 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_PEEK); + 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 == SWAW_STEP_DETERMINE) && (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 == SWAW_STEP_DETERMINE) && (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 > RSSI_CHECK_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 = SWAW_STEP_PEEK; + + if( pDM_SWAT_Table->Double_chk_flag==1) + { + pDM_SWAT_Table->Double_chk_flag=0; + + if (pDM_FatTable->MinMaxRSSI > RSSI_CHECK_THRESHOLD) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [Double check] MinMaxRSSI ((%d)) > %d again!!\n", + pDM_FatTable->MinMaxRSSI, RSSI_CHECK_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, RSSI_CHECK_THRESHOLD)); + + nextAnt = (pDM_FatTable->RxIdleAnt == MAIN_ANT)? AUX_ANT : MAIN_ANT; + pDM_SWAT_Table->try_flag = SWAW_STEP_PEEK; + pDM_SWAT_Table->reset_idx = RSSI_CHECK_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 < RSSI_CHECK_THRESHOLD) + pDM_SWAT_Table->reset_idx = RSSI_CHECK_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->phydm_SwAntennaSwitchTimer), 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->phydm_SwAntennaSwitchWorkitem); + #else + { + //DbgPrint("SW_antdiv_Callback"); + odm_S0S1_SwAntDiv(&pHalData->DM_OutSrc, SWAW_STEP_DETERMINE); + } + #endif + #else + ODM_ScheduleWorkItem(&pDM_SWAT_Table->phydm_SwAntennaSwitchWorkitem); + #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 + +VOID +odm_S0S1_SwAntDivByCtrlFrame( + IN PVOID pDM_VOID, + IN u1Byte Step + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + switch(Step) + { + case SWAW_STEP_PEEK: + 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 peek 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 peek\n")); + break; + default: + pDM_SWAT_Table->bSWAntDivByCtrlFrame = FALSE; + break; + } +} + +VOID +odm_AntselStatisticsOfCtrlFrame( + IN PVOID pDM_VOID, + IN u1Byte antsel_tr_mux, + IN u4Byte RxPWDBAll + + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void + //IN PODM_PHY_INFO_T pPhyInfo, + //IN PODM_PACKET_INFO_T pPktinfo + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_PHY_INFO_T pPhyInfo=(PODM_PHY_INFO_T)p_phy_info_void; + PODM_PACKET_INFO_T pPktinfo=(PODM_PACKET_INFO_T)p_pkt_info_void; + 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 (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + + + + +VOID +odm_SetNextMACAddrTarget( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + PSTA_INFO_T pEntry; + u4Byte value32, i; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("odm_SetNextMACAddrTarget() ==>\n")); + + if (pDM_Odm->bLinked) + { + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + + if ((pDM_FatTable->TrainIdx+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_CE)) + 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);/*0x7b4~0x7b5*/ + + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE)) + 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);/*0x7b0~0x7b3*/ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_FatTable->TrainIdx=%d\n", pDM_FatTable->TrainIdx)); + + #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE)) + 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 + +} + +#if (defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY)) || (defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY)) + +VOID +odm_FastAntTraining( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + u4Byte MaxRSSI_pathA=0, Pckcnt_pathA=0; + u1Byte i,TargetAnt_pathA=0; + BOOLEAN bPktFilterMacth_pathA = FALSE; + #if(RTL8192E_SUPPORT == 1) + u4Byte MaxRSSI_pathB=0, Pckcnt_pathB=0; + u1Byte TargetAnt_pathB=0; + BOOLEAN bPktFilterMacth_pathB = FALSE; + #endif + + + 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_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + phydm_FastTraining_enable(pDM_Odm , FAT_OFF); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_REG); + 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_Tx_By_TxDesc_or_Reg(pDM_Odm , TX_BY_DESC); + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + } + + + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + ODM_SetBBReg(pDM_Odm, 0x864 , BIT2|BIT1|BIT0, ((pDM_Odm->fat_comb_a)-1)); + } + #if(RTL8192E_SUPPORT == 1) + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT2|BIT1|BIT0, ((pDM_Odm->fat_comb_a)-1) ); //path-A // ant combination=regB38[2:0]+1 + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT18|BIT17|BIT16, ((pDM_Odm->fat_comb_b)-1) ); //path-B // ant combination=regB38[18:16]+1 + } + #endif + + 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) + { + //2 Caculate RSSI per Antenna + + //3 [path-A]--------------------------- + for (i=0; i<(pDM_Odm->fat_comb_a); i++) // i : antenna index + { + 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_pathA = TRUE; + } + + if(pDM_FatTable->antAveRSSI[i] > MaxRSSI_pathA) + { + MaxRSSI_pathA = pDM_FatTable->antAveRSSI[i]; + Pckcnt_pathA = pDM_FatTable ->antRSSIcnt[i]; + TargetAnt_pathA = i ; + } + else if(pDM_FatTable->antAveRSSI[i] == MaxRSSI_pathA) + { + if( (pDM_FatTable->antRSSIcnt[i] ) > Pckcnt_pathA) + { + MaxRSSI_pathA = pDM_FatTable->antAveRSSI[i]; + Pckcnt_pathA = pDM_FatTable ->antRSSIcnt[i]; + TargetAnt_pathA = i ; + } + } + + ODM_RT_TRACE("*** Ant-Index : [ %d ], Counter = (( %d )), Avg RSSI = (( %d )) \n", i, pDM_FatTable->antRSSIcnt[i], pDM_FatTable->antAveRSSI[i] ); + } + + + /* + #if(RTL8192E_SUPPORT == 1) + //3 [path-B]--------------------------- + for (i=0; i<(pDM_Odm->fat_comb_b); i++) + { + if(pDM_FatTable->antRSSIcnt_pathB[i] == 0) + pDM_FatTable->antAveRSSI_pathB[i] = 0; + else // (antRSSIcnt[i] != 0) + { + pDM_FatTable->antAveRSSI_pathB[i] = pDM_FatTable->antSumRSSI_pathB[i] /pDM_FatTable->antRSSIcnt_pathB[i]; + bPktFilterMacth_pathB = TRUE; + } + if(pDM_FatTable->antAveRSSI_pathB[i] > MaxRSSI_pathB) + { + MaxRSSI_pathB = pDM_FatTable->antAveRSSI_pathB[i]; + Pckcnt_pathB = pDM_FatTable ->antRSSIcnt_pathB[i]; + TargetAnt_pathB = (u1Byte) i; + } + if(pDM_FatTable->antAveRSSI_pathB[i] == MaxRSSI_pathB) + { + if(pDM_FatTable ->antRSSIcnt_pathB > Pckcnt_pathB) + { + MaxRSSI_pathB = pDM_FatTable->antAveRSSI_pathB[i]; + TargetAnt_pathB = (u1Byte) i; + } + } + if (pDM_Odm->fat_print_rssi==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***{Path-B}: Sum RSSI[%d] = (( %d )), cnt RSSI [%d] = (( %d )), Avg RSSI[%d] = (( %d )) \n", + i, pDM_FatTable->antSumRSSI_pathB[i], i, pDM_FatTable->antRSSIcnt_pathB[i], i, pDM_FatTable->antAveRSSI_pathB[i])); + } + } + #endif + */ + + //1 DECISION STATE + + //2 Select TRX Antenna + + phydm_FastTraining_enable(pDM_Odm, FAT_OFF); + + //3 [path-A]--------------------------- + if(bPktFilterMacth_pathA == FALSE) + { + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("{Path-A}: None Packet is matched\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("{Path-A}: None Packet is matched\n")); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + } + else + { + ODM_RT_TRACE("TargetAnt_pathA = (( %d )) , MaxRSSI_pathA = (( %d )) \n",TargetAnt_pathA,MaxRSSI_pathA); + + //3 [ update RX-optional ant ] Default RX is Omni, Optional RX is the best decision by FAT + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + ODM_SetBBReg(pDM_Odm, 0x864 , BIT8|BIT7|BIT6, TargetAnt_pathA); + } + else if(pDM_Odm->SupportICType == ODM_RTL8192E) + { + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT8|BIT7|BIT6, TargetAnt_pathA);//Optional RX [pth-A] + } + //3 [ update TX ant ] + odm_UpdateTxAnt(pDM_Odm, TargetAnt_pathA, (pDM_FatTable->TrainIdx)); + + if(TargetAnt_pathA == 0) + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + } + /* + #if(RTL8192E_SUPPORT == 1) + //3 [path-B]--------------------------- + if(bPktFilterMacth_pathB == FALSE) + { + if (pDM_Odm->fat_print_rssi==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("***[%d]{Path-B}: None Packet is matched\n\n\n",__LINE__)); + } + } + else + { + if (pDM_Odm->fat_print_rssi==1) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, + (" ***TargetAnt_pathB = (( %d )) *** MaxRSSI = (( %d ))***\n\n\n",TargetAnt_pathB,MaxRSSI_pathB)); + } + ODM_SetBBReg(pDM_Odm, 0xB38 , BIT21|BIT20|BIT19, TargetAnt_pathB); //Default RX is Omni, Optional RX is the best decision by FAT + ODM_SetBBReg(pDM_Odm, 0x80c , BIT21, 1); //Reg80c[21]=1'b1 //from TX Info + + pDM_FatTable->antsel_pathB[pDM_FatTable->TrainIdx] = TargetAnt_pathB; + } + #endif + */ + + //2 Reset Counter + for(i=0; i<(pDM_Odm->fat_comb_a); i++) + { + pDM_FatTable->antSumRSSI[i] = 0; + pDM_FatTable->antRSSIcnt[i] = 0; + } + /* + #if(RTL8192E_SUPPORT == 1) + for(i=0; i<=(pDM_Odm->fat_comb_b); i++) + { + pDM_FatTable->antSumRSSI_pathB[i] = 0; + pDM_FatTable->antRSSIcnt_pathB[i] = 0; + } + #endif + */ + + pDM_FatTable->FAT_State = FAT_PREPARE_STATE; + return; + } + + //1 NORMAL STATE + if (pDM_FatTable->FAT_State == FAT_PREPARE_STATE) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Start Prepare State ]\n")); + + odm_SetNextMACAddrTarget(pDM_Odm); + + //2 Prepare Training + pDM_FatTable->FAT_State = FAT_TRAINING_STATE; + phydm_FastTraining_enable(pDM_Odm , FAT_ON); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); //enable HW AntDiv + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Start Training State]\n")); + + ODM_SetTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer, pDM_Odm->antdiv_intvl ); //ms + } + +} + +VOID +odm_FastAntTrainingCallback( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + +#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_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_FastAntTrainingCallback****** \n")); + odm_FastAntTraining(pDM_Odm); +#endif +} + +VOID +odm_FastAntTrainingWorkItemCallback( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("******odm_FastAntTrainingWorkItemCallback****** \n")); + odm_FastAntTraining(pDM_Odm); +} + +#endif + +#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + +u4Byte +phydm_construct_hl_beam_codeword( + IN PVOID pDM_VOID, + IN u4Byte *beam_pattern_idx, + IN u4Byte ant_num + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte codeword = 0; + u4Byte data_tmp; + u1Byte i; + + if (ant_num < 8) { + for (i = 0; i < ant_num; i++) { + /*ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("beam_pattern_num[%x] = %x\n",i,beam_pattern_num[i] ));*/ + if (beam_pattern_idx[i] == 0) { + data_tmp = 0x1; + /**/ + } else if (beam_pattern_idx[i] == 1) { + data_tmp = 0x2; + /**/ + } else if (beam_pattern_idx[i] == 2) { + data_tmp = 0x4; + /**/ + } else if (beam_pattern_idx[i] == 3) { + data_tmp = 0x8; + /**/ + } + codeword |= (data_tmp<<(i*4)); + } + } + + return codeword; +} + +VOID +phydm_update_beam_pattern( + IN PVOID pDM_VOID, + IN u4Byte codeword, + IN u4Byte codeword_length + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + u1Byte i; + BOOLEAN beam_ctrl_signal; + u4Byte one = 0x1; + u4Byte reg44_tmp_p, reg44_tmp_n, reg44_ori; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Set Beam Pattern =0x%x\n", codeword)); + + reg44_ori = ODM_GetMACReg(pDM_Odm, 0x44, bMaskDWord); + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("reg44_ori =0x%x\n", reg44_ori));*/ + + for (i = 0; i <= (codeword_length-1); i++) { + beam_ctrl_signal = (BOOLEAN)((codeword&BIT(i)) >> i); + + if (pDM_Odm->DebugComponents & ODM_COMP_ANT_DIV) { + + if (i == (codeword_length-1)) { + DbgPrint("%d ]\n", beam_ctrl_signal); + /**/ + } else if (i == 0) { + DbgPrint("Send codeword[1:24] ---> [ %d ", beam_ctrl_signal); + /**/ + } else if ((i % 4) == 3) { + DbgPrint("%d | ", beam_ctrl_signal); + /**/ + } else { + DbgPrint("%d ", beam_ctrl_signal); + /**/ + } + } + + #if 1 + reg44_tmp_p = reg44_ori & (~(BIT11|BIT10)); /*clean bit 10 & 11*/ + reg44_tmp_p |= ((1<<11) | (beam_ctrl_signal<<10)); + reg44_tmp_n = reg44_ori & (~(BIT11|BIT10)); + + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("reg44_tmp_p =(( 0x%x )), reg44_tmp_n = (( 0x%x ))\n", reg44_tmp_p, reg44_tmp_n));*/ + ODM_SetMACReg(pDM_Odm, 0x44 , bMaskDWord, reg44_tmp_p); + ODM_SetMACReg(pDM_Odm, 0x44 , bMaskDWord, reg44_tmp_n); + #else + ODM_SetMACReg(pDM_Odm, 0x44 , BIT11|BIT10, ((1<<1) | beam_ctrl_signal)); + ODM_SetMACReg(pDM_Odm, 0x44 , BIT11, 0); + #endif + + } +} + +VOID +phydm_update_rx_idle_beam( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + u4Byte i; + + pdm_sat_table->update_beam_codeword = phydm_construct_hl_beam_codeword(pDM_Odm, &(pdm_sat_table->rx_idle_beam[0]), pdm_sat_table->ant_num); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Set target beam_pattern codeword = (( 0x%x ))\n", pdm_sat_table->update_beam_codeword)); + + for (i = 0; i < (pdm_sat_table->ant_num); i++) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ Update Rx-Idle-Beam ] RxIdleBeam[%d] =%d\n", i, pdm_sat_table->rx_idle_beam[i])); + /**/ + } + + #if DEV_BUS_TYPE == RT_PCI_INTERFACE + phydm_update_beam_pattern(pDM_Odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num); + #else + ODM_ScheduleWorkItem(&pdm_sat_table->hl_smart_antenna_workitem); + /*ODM_StallExecution(1);*/ + #endif + + pdm_sat_table->pre_codeword = pdm_sat_table->update_beam_codeword; +} + +VOID +phydm_hl_smart_ant_cmd( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + u4Byte used = *_used; + u4Byte out_len = *_out_len; + u4Byte one = 0x1; + u4Byte codeword_length = pdm_sat_table->data_codeword_bit_num; + u4Byte beam_ctrl_signal, i; + + if (dm_value[0] == 1) { /*fix beam pattern*/ + + pdm_sat_table->fix_beam_pattern_en = dm_value[1]; + + if (pdm_sat_table->fix_beam_pattern_en == 1) { + + pdm_sat_table->fix_beam_pattern_codeword = dm_value[2]; + + if (pdm_sat_table->fix_beam_pattern_codeword > (one<fix_beam_pattern_codeword, codeword_length)); + (pdm_sat_table->fix_beam_pattern_codeword) &= 0xffffff; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Auto modify to (0x%x)\n", pdm_sat_table->fix_beam_pattern_codeword)); + } + + pdm_sat_table->update_beam_codeword = pdm_sat_table->fix_beam_pattern_codeword; + + /*---------------------------------------------------------*/ + PHYDM_SNPRINTF((output+used, out_len-used, "Fix Beam Pattern\n")); + for (i = 0; i <= (codeword_length-1); i++) { + beam_ctrl_signal = (BOOLEAN)((pdm_sat_table->update_beam_codeword&BIT(i)) >> i); + + if (i == (codeword_length-1)) { + PHYDM_SNPRINTF((output+used, out_len-used, "%d]\n", beam_ctrl_signal)); + /**/ + } else if (i == 0) { + PHYDM_SNPRINTF((output+used, out_len-used, "Send Codeword[1:24] to RFU -> [%d", beam_ctrl_signal)); + /**/ + } else if ((i % 4) == 3) { + PHYDM_SNPRINTF((output+used, out_len-used, "%d|", beam_ctrl_signal)); + /**/ + } else { + PHYDM_SNPRINTF((output+used, out_len-used, "%d", beam_ctrl_signal)); + /**/ + } + } + /*---------------------------------------------------------*/ + + + #if DEV_BUS_TYPE == RT_PCI_INTERFACE + phydm_update_beam_pattern(pDM_Odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num); + #else + ODM_ScheduleWorkItem(&pdm_sat_table->hl_smart_antenna_workitem); + /*ODM_StallExecution(1);*/ + #endif + } else if (pdm_sat_table->fix_beam_pattern_en == 0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Smart Antenna: Enable\n")); + } + + } else if (dm_value[0] == 2) { /*set latch time*/ + + pdm_sat_table->latch_time = dm_value[1]; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] latch_time =0x%x\n", pdm_sat_table->latch_time)); + } else if (dm_value[0] == 3) { + + pdm_sat_table->fix_training_num_en = dm_value[1]; + + if (pdm_sat_table->fix_training_num_en == 1) { + pdm_sat_table->per_beam_training_pkt_num = dm_value[2]; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Fix per_beam_training_pkt_num = (( 0x%x ))\n", pdm_sat_table->per_beam_training_pkt_num)); + } else if (pdm_sat_table->fix_training_num_en == 0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] AUTO per_beam_training_pkt_num\n")); + /**/ + } + } + +} + + +void +phydm_set_all_ant_same_beam_num( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + + if (pDM_Odm->AntDivType == HL_SW_SMART_ANT_TYPE1) { /*2Ant for 8821A*/ + + pdm_sat_table->rx_idle_beam[0] = pdm_sat_table->fast_training_beam_num; + pdm_sat_table->rx_idle_beam[1] = pdm_sat_table->fast_training_beam_num; + } + + pdm_sat_table->update_beam_codeword = phydm_construct_hl_beam_codeword(pDM_Odm, &(pdm_sat_table->rx_idle_beam[0]), pdm_sat_table->ant_num); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Set all ant beam_pattern: codeword = (( 0x%x ))\n", pdm_sat_table->update_beam_codeword)); + + #if DEV_BUS_TYPE == RT_PCI_INTERFACE + phydm_update_beam_pattern(pDM_Odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num); + #else + ODM_ScheduleWorkItem(&pdm_sat_table->hl_smart_antenna_workitem); + /*ODM_StallExecution(1);*/ + #endif +} + +VOID +odm_FastAntTraining_hl_smart_antenna_type1( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + pFAT_T pDM_FatTable = &(pDM_Odm->DM_FatTable); + pSWAT_T pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; + u4Byte codeword = 0, i, j; + u4Byte TargetAnt; + u4Byte avg_rssi_tmp; + u4Byte target_ant_beam_max_rssi[SUPPORT_RF_PATH_NUM] = {0}; + u4Byte max_beam_ant_rssi = 0; + u4Byte target_ant_beam[SUPPORT_RF_PATH_NUM] = {0}; + u4Byte beam_tmp; + + + if (!pDM_Odm->bLinked) { + 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, ("Link -> no Link\n")); + pDM_FatTable->FAT_State = FAT_BEFORE_LINK_STATE; + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_REG); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("change to (( %d )) FAT_state\n", pDM_FatTable->FAT_State)); + + 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")); + + pDM_FatTable->FAT_State = FAT_PREPARE_STATE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("change to (( %d )) FAT_state\n", pDM_FatTable->FAT_State)); + + /*pdm_sat_table->fast_training_beam_num = 0;*/ + /*phydm_set_all_ant_same_beam_num(pDM_Odm);*/ + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_DESC); + + pDM_FatTable->bBecomeLinked = pDM_Odm->bLinked; + } + } + + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("HL Smart Ant Training: State (( %d ))\n", pDM_FatTable->FAT_State));*/ + + /* [DECISION STATE] */ + /*=======================================================================================*/ + if (pDM_FatTable->FAT_State == FAT_DECISION_STATE) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 3. In Decision State]\n")); + phydm_FastTraining_enable(pDM_Odm , FAT_OFF); + + /*compute target beam in each antenna*/ + for (i = 0; i < (pdm_sat_table->ant_num); i++) { + for (j = 0; j < (pdm_sat_table->beam_patten_num_each_ant); j++) { + + if (pdm_sat_table->pkt_rssi_cnt[i][j] == 0) { + avg_rssi_tmp = pdm_sat_table->pkt_rssi_pre[i][j]; + /**/ + } else { + avg_rssi_tmp = (pdm_sat_table->pkt_rssi_sum[i][j]) / (pdm_sat_table->pkt_rssi_cnt[i][j]); + pdm_sat_table->pkt_rssi_pre[i][j] = avg_rssi_tmp; + /**/ + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant[%d], Beam[%d]: pkt_num=(( %d )), avg_rssi=(( %d ))\n", i, j, pdm_sat_table->pkt_rssi_cnt[i][j], avg_rssi_tmp)); + + if (avg_rssi_tmp > target_ant_beam_max_rssi[i]) { + target_ant_beam[i] = j; + target_ant_beam_max_rssi[i] = avg_rssi_tmp; + } + + /*reset counter value*/ + pdm_sat_table->pkt_rssi_sum[i][j] = 0; + pdm_sat_table->pkt_rssi_cnt[i][j] = 0; + + } + pdm_sat_table->rx_idle_beam[i] = target_ant_beam[i]; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("---------> Target of Ant[%d]: Beam_num-(( %d )) RSSI= ((%d))\n", + i, target_ant_beam[i], target_ant_beam_max_rssi[i])); + + if (target_ant_beam_max_rssi[i] > max_beam_ant_rssi) { + TargetAnt = i; + max_beam_ant_rssi = target_ant_beam_max_rssi[i]; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Target of Ant = (( %d )) max_beam_ant_rssi = (( %d ))\n", + TargetAnt, max_beam_ant_rssi)); + } + } + + if (TargetAnt == 0) + TargetAnt = MAIN_ANT; + else if (TargetAnt == 1) + TargetAnt = AUX_ANT; + + /* [ update RX ant ]*/ + ODM_UpdateRxIdleAnt(pDM_Odm, (u1Byte)TargetAnt); + + /* [ update TX ant ]*/ + odm_UpdateTxAnt(pDM_Odm, (u1Byte)TargetAnt, (pDM_FatTable->TrainIdx)); + + /*set beam in each antenna*/ + phydm_update_rx_idle_beam(pDM_Odm); + + phydm_FastTraining_enable(pDM_Odm , FAT_OFF); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_ON); + pDM_FatTable->FAT_State = FAT_PREPARE_STATE; + + } + /* [TRAINING STATE] */ + else if (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ 2. In Training State]\n")); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("fat_beam_n = (( %d )), pre_fat_beam_n = (( %d ))\n", + pdm_sat_table->fast_training_beam_num, pdm_sat_table->pre_fast_training_beam_num)); + + if (pdm_sat_table->fast_training_beam_num > pdm_sat_table->pre_fast_training_beam_num) { + + pdm_sat_table->force_update_beam_en = 0; + + } else { + + pdm_sat_table->force_update_beam_en = 1; + + pdm_sat_table->pkt_counter = 0; + beam_tmp = pdm_sat_table->fast_training_beam_num; + if (pdm_sat_table->fast_training_beam_num >= (pdm_sat_table->beam_patten_num_each_ant-1)) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Timeout Update] Beam_num (( %d )) -> (( decision ))\n", pdm_sat_table->fast_training_beam_num)); + phydm_FastTraining_enable(pDM_Odm , FAT_OFF); + pDM_FatTable->FAT_State = FAT_DECISION_STATE; + odm_FastAntTraining_hl_smart_antenna_type1(pDM_Odm); + + } else { + pdm_sat_table->fast_training_beam_num++; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Timeout Update] Beam_num (( %d )) -> (( %d ))\n", beam_tmp, pdm_sat_table->fast_training_beam_num)); + phydm_set_all_ant_same_beam_num(pDM_Odm); + pDM_FatTable->FAT_State = FAT_TRAINING_STATE; + + } + } + pdm_sat_table->pre_fast_training_beam_num = pdm_sat_table->fast_training_beam_num; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Update Pre_Beam =(( %d ))\n", pdm_sat_table->pre_fast_training_beam_num)); + } + /* [Prepare State] */ + /*=======================================================================================*/ + else if (pDM_FatTable->FAT_State == FAT_PREPARE_STATE) { + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("\n\n[ 1. In Prepare State]\n")); + + if (pDM_Odm->pre_TrafficLoad == (pDM_Odm->TrafficLoad)) { + if (pdm_sat_table->decision_holding_period != 0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Holding_period = (( %d )), return!!!\n", pdm_sat_table->decision_holding_period)); + pdm_sat_table->decision_holding_period--; + return; + } + } + + + /* Set training packet number*/ + if (pdm_sat_table->fix_training_num_en == 0) { + + switch (pDM_Odm->TrafficLoad) { + + case TRAFFIC_HIGH: + pdm_sat_table->per_beam_training_pkt_num = 20; + pdm_sat_table->decision_holding_period = 0; + break; + case TRAFFIC_MID: + pdm_sat_table->per_beam_training_pkt_num = 10; + pdm_sat_table->decision_holding_period = 1; + break; + case TRAFFIC_LOW: + pdm_sat_table->per_beam_training_pkt_num = 5; /*ping 60000*/ + pdm_sat_table->decision_holding_period = 3; + break; + case TRAFFIC_ULTRA_LOW: + pdm_sat_table->per_beam_training_pkt_num = 2; + pdm_sat_table->decision_holding_period = 5; + break; + default: + break; + } + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Fix_training_num = (( %d )), per_beam_training_pkt_num = (( %d ))\n", + pdm_sat_table->fix_training_num_en , pdm_sat_table->per_beam_training_pkt_num)); + + /* Set training MAC Addr. of target */ + odm_SetNextMACAddrTarget(pDM_Odm); + + phydm_FastTraining_enable(pDM_Odm , FAT_ON); + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + pdm_sat_table->pkt_counter = 0; + pdm_sat_table->fast_training_beam_num = 0; + phydm_set_all_ant_same_beam_num(pDM_Odm); + pdm_sat_table->pre_fast_training_beam_num = pdm_sat_table->fast_training_beam_num; + pDM_FatTable->FAT_State = FAT_TRAINING_STATE; + } + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +phydm_beam_switch_workitem_callback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + + #if DEV_BUS_TYPE != RT_PCI_INTERFACE + pdm_sat_table->pkt_skip_statistic_en = 1; + #endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Beam Switch Workitem Callback, pkt_skip_statistic_en = (( %d ))\n", pdm_sat_table->pkt_skip_statistic_en)); + + phydm_update_beam_pattern(pDM_Odm, pdm_sat_table->update_beam_codeword, pdm_sat_table->data_codeword_bit_num); + + #if DEV_BUS_TYPE != RT_PCI_INTERFACE + /*ODM_StallExecution(pdm_sat_table->latch_time);*/ + pdm_sat_table->pkt_skip_statistic_en = 0; + #endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pkt_skip_statistic_en = (( %d )), latch_time = (( %d ))\n", pdm_sat_table->pkt_skip_statistic_en, pdm_sat_table->latch_time)); +} + +VOID +phydm_beam_decision_workitem_callback( + IN PVOID pContext + ) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] Beam decision Workitem Callback\n")); + odm_FastAntTraining_hl_smart_antenna_type1(pDM_Odm); +} +#endif + +#endif /*#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1*/ + +VOID +ODM_AntDivInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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")); + } + +#endif + //--- + + //2 [--General---] + pDM_Odm->antdiv_period=0; + + pDM_FatTable->bBecomeLinked =FALSE; + pDM_FatTable->AntDiv_OnOff =0xff; + + //3 - AP - + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + + #ifdef BEAMFORMING_SUPPORT + #if(DM_ODM_SUPPORT_TYPE == ODM_AP) + odm_BDC_Init(pDM_Odm); + #endif + #endif + + //3 - WIN - + #elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + 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; + #endif + + //2 [---Set MAIN_ANT as default antenna if Auto-Ant enable---] + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + + pDM_Odm->AntType = ODM_AUTO_ANT; + + pDM_FatTable->RxIdleAnt = 0xff; /*to make RX-idle-antenna will be updated absolutly*/ + ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT); + + //2 [---Set TX Antenna---] + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_REG); + + + //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); + #if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + else if(pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) + odm_Smart_HWAntDiv_Init_88E(pDM_Odm); + #endif + #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); + #if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + else if(pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV) + odm_Smart_HWAntDiv_Init_92E(pDM_Odm); + #endif + + } + #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) + { + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + pDM_Odm->AntDivType = HL_SW_SMART_ANT_TYPE1; + + if (pDM_Odm->AntDivType == HL_SW_SMART_ANT_TYPE1) { + + odm_TRX_HWAntDiv_Init_8821A(pDM_Odm); + phydm_hl_smart_ant_type1_init_8821a(pDM_Odm); + } else + #endif + { + /*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 + + /*[--8188F---]*/ + #if (RTL8188F_SUPPORT == 1) + else if (pDM_Odm->SupportICType == ODM_RTL8188F) { + + pDM_Odm->AntDivType = S0S1_SW_ANTDIV; + odm_S0S1_SWAntDiv_Init_8188F(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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER pAdapter = pDM_Odm->Adapter; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + #endif + + 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; + } + + //---------- + 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 (pDM_FatTable->enable_ctrl_frame_antdiv) { + + if ((pDM_Odm->data_frame_num <= 10) && (pDM_Odm->bLinked)) + pDM_FatTable->use_ctrl_frame_antdiv = 1; + else + pDM_FatTable->use_ctrl_frame_antdiv = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("use_ctrl_frame_antdiv = (( %d )), data_frame_num = (( %d ))\n", pDM_FatTable->use_ctrl_frame_antdiv, pDM_Odm->data_frame_num)); + pDM_Odm->data_frame_num = 0; + } + + 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_FatTable->fix_ant_bfee == 0) + { + odm_AntDiv_on_off(pDM_Odm, ANTDIV_OFF); + pDM_FatTable->fix_ant_bfee = 1; + } + return; + } + else // BFmee Off && Div Off -> Div On + { + if((pDM_FatTable->fix_ant_bfee == 1) && 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_FatTable->fix_ant_bfee = 0; + } + } + #endif + } +#elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + //----------just for fool proof + + if(pDM_Odm->antdiv_rssi) + pDM_Odm->DebugComponents |= ODM_COMP_ANT_DIV; + else + pDM_Odm->DebugComponents &= ~ODM_COMP_ANT_DIV; + + 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); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm, TX_BY_REG); + + 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); + odm_Tx_By_TxDesc_or_Reg(pDM_Odm , TX_BY_DESC); + } + 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( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + 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 || pDM_Odm->AntDivType==CG_TRX_HW_ANTDIV) + odm_HW_AntDiv(pDM_Odm); + + #if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + 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 (phydm_IsBtEnable_8723b(pDM_Odm)) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[BT is enable!!!] AntDiv: OFF\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 = FALSE; + } + } else { + if (pDM_Odm->AntDivType == S0S1_SW_ANTDIV) { + + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_PEEK); + #endif + } 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) + { + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + if (pDM_Odm->AntDivType == HL_SW_SMART_ANT_TYPE1) { + + if (pdm_sat_table->fix_beam_pattern_en != 0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, (" [ SmartAnt ] Fix SmartAnt Pattern = 0x%x\n", pdm_sat_table->fix_beam_pattern_codeword)); + /*return;*/ + } else { + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ SmartAnt ] AntDivType = HL_SW_SMART_ANT_TYPE1\n"));*/ + odm_FastAntTraining_hl_smart_antenna_type1(pDM_Odm); + } + + } else + #endif + { + 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) { + + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_PEEK); + #endif + } 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 + + #if (RTL8188F_SUPPORT == 1) + /* [--8188F---]*/ + else if (pDM_Odm->SupportICType == ODM_RTL8188F) { + + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + odm_S0S1_SwAntDiv(pDM_Odm, SWAW_STEP_PEEK); + #endif + } + #endif + +} + + +VOID +odm_AntselStatistics( + IN PVOID pDM_VOID, + IN u1Byte antsel_tr_mux, + IN u4Byte MacId, + IN u4Byte utility, + IN u1Byte method + + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + if(method==RSSI_METHOD) + { + if(antsel_tr_mux == ANT1_2G) + { + pDM_FatTable->MainAnt_Sum[MacId]+=utility; + pDM_FatTable->MainAnt_Cnt[MacId]++; + } + else + { + pDM_FatTable->AuxAnt_Sum[MacId]+=utility; + pDM_FatTable->AuxAnt_Cnt[MacId]++; + } + } + #ifdef ODM_EVM_ENHANCE_ANTDIV + else if(method==EVM_METHOD) + { + if(antsel_tr_mux == ANT1_2G) + { + pDM_FatTable->MainAntEVM_Sum[MacId]+=(utility<<5); + pDM_FatTable->MainAntEVM_Cnt[MacId]++; + } + else + { + pDM_FatTable->AuxAntEVM_Sum[MacId]+=(utility<<5); + pDM_FatTable->AuxAntEVM_Cnt[MacId]++; + } + } + else if(method==CRC32_METHOD) + { + if(utility==0) + pDM_FatTable->CRC32_Fail_Cnt++; + else + pDM_FatTable->CRC32_Ok_Cnt+=utility; + } + #endif +} + + +VOID +ODM_Process_RSSIForAntDiv( + IN OUT PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void + //IN PODM_PHY_INFO_T pPhyInfo, + //IN PODM_PACKET_INFO_T pPktinfo + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_PHY_INFO_T pPhyInfo=(PODM_PHY_INFO_T)p_phy_info_void; + PODM_PACKET_INFO_T pPktinfo=(PODM_PACKET_INFO_T)p_pkt_info_void; + u1Byte isCCKrate=0,CCKMaxRate=ODM_RATE11M; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + pSAT_T pdm_sat_table = &(pDM_Odm->dm_sat_table); + u4Byte beam_tmp; + #endif + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + u4Byte RxPower_Ant0, RxPower_Ant1; + u4Byte RxEVM_Ant0, RxEVM_Ant1; + #else + u1Byte RxPower_Ant0, RxPower_Ant1; + u1Byte RxEVM_Ant0, RxEVM_Ant1; + #endif + + CCKMaxRate=ODM_RATE11M; + isCCKrate = (pPktinfo->DataRate <= CCKMaxRate)?TRUE:FALSE; + + if ((pDM_Odm->SupportICType & (ODM_RTL8192E|ODM_RTL8812)) && (pPktinfo->DataRate > CCKMaxRate)) + { + RxPower_Ant0 = pPhyInfo->RxMIMOSignalStrength[0]; + RxPower_Ant1= pPhyInfo->RxMIMOSignalStrength[1]; + + RxEVM_Ant0 =pPhyInfo->RxMIMOSignalQuality[0]; + RxEVM_Ant1 =pPhyInfo->RxMIMOSignalQuality[1]; + } + else + RxPower_Ant0=pPhyInfo->RxPWDBAll; + + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + if (pDM_Odm->AntDivType == HL_SW_SMART_ANT_TYPE1) + { + if ((pDM_Odm->SupportICType & ODM_HL_SMART_ANT_TYPE1_SUPPORT) && + (pPktinfo->bPacketToSelf) && + (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) + ) { + + if (pdm_sat_table->pkt_skip_statistic_en == 0) { + /* + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antsel_pathA = ((%d)), hw_antsw_occur = ((%d)), Beam_num = ((%d)), RSSI = ((%d))\n", + pPktinfo->StationID, pDM_FatTable->antsel_rx_keep_0, pDM_FatTable->hw_antsw_occur, pdm_sat_table->fast_training_beam_num, RxPower_Ant0)); + */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antsel_pathA = ((%d)), bPacketToSelf = ((%d)), Beam_num = ((%d)), RSSI = ((%d))\n", + pPktinfo->StationID, pDM_FatTable->antsel_rx_keep_0, pPktinfo->bPacketToSelf, pdm_sat_table->fast_training_beam_num, RxPower_Ant0)); + + + pdm_sat_table->pkt_rssi_sum[pDM_FatTable->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num] += RxPower_Ant0; + pdm_sat_table->pkt_rssi_cnt[pDM_FatTable->antsel_rx_keep_0][pdm_sat_table->fast_training_beam_num]++; + pdm_sat_table->pkt_counter++; + + /*swich beam every N pkt*/ + if ((pdm_sat_table->pkt_counter) >= (pdm_sat_table->per_beam_training_pkt_num)) { + + pdm_sat_table->pkt_counter = 0; + beam_tmp = pdm_sat_table->fast_training_beam_num; + + if (pdm_sat_table->fast_training_beam_num >= (pdm_sat_table->beam_patten_num_each_ant-1)) { + + pDM_FatTable->FAT_State = FAT_DECISION_STATE; + + #if DEV_BUS_TYPE == RT_PCI_INTERFACE + odm_FastAntTraining_hl_smart_antenna_type1(pDM_Odm); + #else + ODM_ScheduleWorkItem(&pdm_sat_table->hl_smart_antenna_decision_workitem); + #endif + + + } else { + pdm_sat_table->fast_training_beam_num++; + phydm_set_all_ant_same_beam_num(pDM_Odm); + + pDM_FatTable->FAT_State = FAT_TRAINING_STATE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Update Beam_num (( %d )) -> (( %d ))\n", beam_tmp, pdm_sat_table->fast_training_beam_num)); + } + } + } + } + } else + #endif + 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 || pDM_FatTable->use_ctrl_frame_antdiv)) + { + 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,RSSI_METHOD); + + #ifdef ODM_EVM_ENHANCE_ANTDIV + if(!isCCKrate) + { + odm_AntselStatistics(pDM_Odm, pDM_FatTable->antsel_rx_keep_0, pPktinfo->StationID,RxEVM_Ant0,EVM_METHOD); + } + #endif + } + 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,RSSI_METHOD); + } + 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,RSSI_METHOD); + } + } + } + } + //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 PVOID pDM_VOID, + IN pu1Byte pDesc, + IN u1Byte macId + + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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 + } +} +#elif(DM_ODM_SUPPORT_TYPE == ODM_AP) + +VOID +ODM_SetTxAntByTxInfo( + struct rtl8192cd_priv *priv, + struct tx_desc *pdesc, + 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_RTL8188E) { + /*panic_printk("[%s] [%d] ******ODM_SetTxAntByTxInfo_8188E******\n",__FUNCTION__,__LINE__);*/ + pdesc->Dword2 &= set_desc(~BIT(24)); + pdesc->Dword2 &= set_desc(~BIT(25)); + pdesc->Dword7 &= set_desc(~BIT(29)); + + pdesc->Dword2 |= set_desc(pDM_FatTable->antsel_a[aid]<<24); + pdesc->Dword2 |= set_desc(pDM_FatTable->antsel_b[aid]<<25); + pdesc->Dword7 |= set_desc(pDM_FatTable->antsel_c[aid]<<29); + + + } else if (SupportICType == ODM_RTL8812) { + /*[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)); + + 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 PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + 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)||defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + 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) || defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A)) + 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 PVOID pDM_VOID, + IN u1Byte state + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(state==INIT_ANTDIV_TIMMER) + { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + ODM_InitializeTimer(pDM_Odm, &(pDM_Odm->DM_SWAT_Table.phydm_SwAntennaSwitchTimer), + (RT_TIMER_CALL_BACK)ODM_SW_AntDiv_Callback, NULL, "phydm_SwAntennaSwitchTimer"); + #elif ( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + ODM_InitializeTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer, + (RT_TIMER_CALL_BACK)odm_FastAntTrainingCallback, NULL, "FastAntTrainingTimer"); + #endif + + #ifdef ODM_EVM_ENHANCE_ANTDIV + ODM_InitializeTimer(pDM_Odm,&pDM_Odm->EVM_FastAntTrainingTimer, + (RT_TIMER_CALL_BACK)odm_EVM_FastAntTrainingCallback, NULL, "EVM_FastAntTrainingTimer"); + #endif + } + else if(state==CANCEL_ANTDIV_TIMMER) + { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + ODM_CancelTimer(pDM_Odm, &(pDM_Odm->DM_SWAT_Table.phydm_SwAntennaSwitchTimer)); + #elif ( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + ODM_CancelTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer); + #endif + + #ifdef ODM_EVM_ENHANCE_ANTDIV + ODM_CancelTimer(pDM_Odm,&pDM_Odm->EVM_FastAntTrainingTimer); + #endif + } + else if(state==RELEASE_ANTDIV_TIMMER) + { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + ODM_ReleaseTimer(pDM_Odm, &(pDM_Odm->DM_SWAT_Table.phydm_SwAntennaSwitchTimer)); + #elif ( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) + ODM_ReleaseTimer(pDM_Odm,&pDM_Odm->FastAntTrainingTimer); + #endif + + #ifdef ODM_EVM_ENHANCE_ANTDIV + ODM_ReleaseTimer(pDM_Odm,&pDM_Odm->EVM_FastAntTrainingTimer); + #endif + } + +} + +#endif /*#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))*/ + +VOID +ODM_AntDivReset( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->AntDivType == S0S1_SW_ANTDIV) + { + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + odm_S0S1_SWAntDiv_Reset(pDM_Odm); + #endif + } + +} + +VOID +odm_AntennaDiversityInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(pDM_Odm->mp_mode == TRUE) + return; + + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + ODM_AntDiv_Config(pDM_Odm); + ODM_AntDivInit(pDM_Odm); + #endif +} + +VOID +odm_AntennaDiversity( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + if(pDM_Odm->mp_mode == TRUE) + return; + + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + ODM_AntDiv(pDM_Odm); + #endif +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.h new file mode 100644 index 00000000..8d72d289 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_antdiv.h @@ -0,0 +1,567 @@ +/****************************************************************************** + * + * 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 "2.0" //2014.11.04*/ +/*#define ANTDIV_VERSION "2.1" //2015.01.13 Dino*/ +/*#define ANTDIV_VERSION "2.2" 2015.01.16 Dino*/ +/*#define ANTDIV_VERSION "3.1" 2015.07.29 YuChen, remove 92c 92d 8723a*/ +/*#define ANTDIV_VERSION "3.2" 2015.08.11 Stanley, disable antenna diversity when BT is enable for 8723B*/ +/*#define ANTDIV_VERSION "3.3" 2015.08.12 Stanley. 8723B does not need to check the antenna is control by BT, + because antenna diversity only works when BT is disable or radio off*/ +#define ANTDIV_VERSION "3.4" /*2015.08.28 Dino 1.Add 8821A Smart Antenna 2. Add 8188F SW S0S1 Antenna Diversity*/ + +//1 ============================================================ +//1 Definition +//1 ============================================================ + +#define MAIN_ANT 1 +#define AUX_ANT 2 + +#define ANT1_2G 0 // = ANT2_5G +#define ANT2_2G 1 // = ANT1_5G +/*smart antenna*/ +#define SUPPORT_RF_PATH_NUM 4 +#define SUPPORT_BEAM_PATTERN_NUM 4 + + +//Antenna Diversty Control Type +#define ODM_AUTO_ANT 0 +#define ODM_FIX_MAIN_ANT 1 +#define ODM_FIX_AUX_ANT 2 + +#define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8188F) +#define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_ANTDIV_SUPPORT (ODM_N_ANTDIV_SUPPORT|ODM_AC_ANTDIV_SUPPORT) +#define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E|ODM_RTL8192E) +#define ODM_HL_SMART_ANT_TYPE1_SUPPORT (ODM_RTL8821) + +#define ODM_ANTDIV_2G_SUPPORT_IC (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8881A|ODM_RTL8188F) +#define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) + +#define ODM_EVM_ENHANCE_ANTDIV_SUPPORT_IC (ODM_RTL8192E) + +#define ODM_ANTDIV_2G BIT0 +#define ODM_ANTDIV_5G BIT1 + +#define ANTDIV_ON 1 +#define ANTDIV_OFF 0 + +#define FAT_ON 1 +#define FAT_OFF 0 + +#define TX_BY_DESC 1 +#define TX_BY_REG 0 + +#define RSSI_METHOD 0 +#define EVM_METHOD 1 +#define CRC32_METHOD 2 + +#define INIT_ANTDIV_TIMMER 0 +#define CANCEL_ANTDIV_TIMMER 1 +#define RELEASE_ANTDIV_TIMMER 2 + +#define CRC32_FAIL 1 +#define CRC32_OK 0 + +#define Evm_RSSI_TH_High 25 +#define Evm_RSSI_TH_Low 20 + +#define NORMAL_STATE_MIAN 1 +#define NORMAL_STATE_AUX 2 +#define TRAINING_STATE 3 + +#define FORCE_RSSI_DIFF 10 + +#define CSI_ON 1 +#define CSI_OFF 0 + +#define DIVON_CSIOFF 1 +#define DIVOFF_CSION 2 + +#define BDC_DIV_TRAIN_STATE 0 +#define BDC_BFer_TRAIN_STATE 1 +#define BDC_DECISION_STATE 2 +#define BDC_BF_HOLD_STATE 3 +#define BDC_DIV_HOLD_STATE 4 + +#define BDC_MODE_1 1 +#define BDC_MODE_2 2 +#define BDC_MODE_3 3 +#define BDC_MODE_4 4 +#define BDC_MODE_NULL 0xff + +/*SW S0S1 antenna diversity*/ +#define SWAW_STEP_INIT 0xff +#define SWAW_STEP_PEEK 0 +#define SWAW_STEP_DETERMINE 1 + +#define RSSI_CHECK_RESET_PERIOD 10 +#define RSSI_CHECK_THRESHOLD 50 + +/*Hong Lin Smart antenna*/ +#define HL_SMTANT_2WIRE_DATA_LEN 24 + +//1 ============================================================ +//1 structure +//1 ============================================================ + + +typedef struct _SW_Antenna_Switch_ +{ + u1Byte Double_chk_flag; /*If current antenna RSSI > "RSSI_CHECK_THRESHOLD", than check this antenna again*/ + u1Byte try_flag; + s4Byte PreRSSI; + u1Byte CurAntenna; + u1Byte PreAntenna; + u1Byte RSSI_Trying; + u1Byte reset_idx; + u1Byte Train_time; + u1Byte Train_time_flag; /*base on RSSI difference between two antennas*/ + RT_TIMER phydm_SwAntennaSwitchTimer; + u4Byte PktCnt_SWAntDivByCtrlFrame; + BOOLEAN bSWAntDivByCtrlFrame; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM phydm_SwAntennaSwitchWorkitem; + #endif + #endif + + /* AntDect (Before link Antenna Switch check) need to be moved*/ + u2Byte Single_Ant_Counter; + u2Byte Dual_Ant_Counter; + u2Byte Aux_FailDetec_Counter; + u2Byte Retry_Counter; + u1Byte SWAS_NoLink_State; + 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; + + +}SWAT_T, *pSWAT_T; + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) +typedef struct _BF_DIV_COEX_ +{ + BOOLEAN w_BFer_Client[ODM_ASSOCIATE_ENTRY_NUM]; + BOOLEAN w_BFee_Client[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MA_rx_TP[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MA_rx_TP_DIV[ODM_ASSOCIATE_ENTRY_NUM]; + + u1Byte BDCcoexType_wBfer; + u1Byte num_Txbfee_Client; + u1Byte num_Txbfer_Client; + u1Byte BDC_Try_counter; + u1Byte BDC_Hold_counter; + u1Byte BDC_Mode; + u1Byte BDC_active_Mode; + u1Byte BDC_state; + u1Byte BDC_RxIdleUpdate_counter; + u1Byte num_Client; + u1Byte pre_num_Client; + u1Byte num_BfTar; + u1Byte num_DivTar; + + BOOLEAN bAll_DivSta_Idle; + BOOLEAN bAll_BFSta_Idle; + BOOLEAN BDC_Try_flag; + BOOLEAN BF_pass; + BOOLEAN DIV_pass; +}BDC_T,*pBDC_T; +#endif +#endif + +#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 +typedef struct _SMART_ANTENNA_TRAINNING_ { + u4Byte latch_time; + BOOLEAN pkt_skip_statistic_en; + u4Byte fix_beam_pattern_en; + u4Byte fix_training_num_en; + u4Byte fix_beam_pattern_codeword; + u4Byte update_beam_codeword; + u4Byte ant_num; /*number of smart beam antenna*/ + u4Byte beam_patten_num_each_ant;/*number of beam can be switched in each antenna*/ + u4Byte data_codeword_bit_num; + u4Byte per_beam_training_pkt_num; + u1Byte decision_holding_period; + u4Byte pkt_counter; + u4Byte fast_training_beam_num; + u4Byte pre_fast_training_beam_num; + u4Byte pkt_rssi_pre[SUPPORT_RF_PATH_NUM][SUPPORT_BEAM_PATTERN_NUM]; + u4Byte pkt_rssi_sum[8][SUPPORT_BEAM_PATTERN_NUM]; + u4Byte pkt_rssi_cnt[8][SUPPORT_BEAM_PATTERN_NUM]; + u4Byte rx_idle_beam[SUPPORT_RF_PATH_NUM]; + u4Byte pre_codeword; + BOOLEAN force_update_beam_en; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_WORK_ITEM hl_smart_antenna_workitem; + RT_WORK_ITEM hl_smart_antenna_decision_workitem; + #endif + +} SAT_T, *pSAT_T; +#endif + +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; + u1Byte AntDiv_OnOff; + BOOLEAN bBecomeLinked; + u4Byte MinMaxRSSI; + u1Byte idx_AntDiv_counter_2G; + u1Byte idx_AntDiv_counter_5G; + u1Byte AntDiv_2G_5G; + u4Byte CCK_counter_main; + u4Byte CCK_counter_aux; + u4Byte OFDM_counter_main; + u4Byte OFDM_counter_aux; + + #ifdef ODM_EVM_ENHANCE_ANTDIV + u4Byte MainAntEVM_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAntEVM_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MainAntEVM_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAntEVM_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + BOOLEAN EVM_method_enable; + u1Byte TargetAnt_EVM; + u1Byte TargetAnt_CRC32; + u1Byte TargetAnt_enhance; + u1Byte pre_TargetAnt_enhance; + u2Byte Main_MPDU_OK_cnt; + u2Byte Aux_MPDU_OK_cnt; + + u4Byte CRC32_Ok_Cnt; + u4Byte CRC32_Fail_Cnt; + u4Byte MainCRC32_Ok_Cnt; + u4Byte AuxCRC32_Ok_Cnt; + u4Byte MainCRC32_Fail_Cnt; + u4Byte AuxCRC32_Fail_Cnt; + #endif + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + 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; + #endif + BOOLEAN fix_ant_bfee; + BOOLEAN enable_ctrl_frame_antdiv; + BOOLEAN use_ctrl_frame_antdiv; + u1Byte hw_antsw_occur; +}FAT_T,*pFAT_T; + + +//1 ============================================================ +//1 enumeration +//1 ============================================================ + + + +typedef enum _FAT_STATE /*Fast antenna training*/ +{ + FAT_BEFORE_LINK_STATE = 0, + FAT_PREPARE_STATE = 1, + FAT_TRAINING_STATE = 2, + FAT_DECISION_STATE = 3 +}FAT_STATE_E, *PFAT_STATE_E; + +typedef enum _ANT_DIV_TYPE +{ + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + CG_TRX_SMART_ANTDIV = 0x03, + S0S1_SW_ANTDIV = 0x04, /*8723B intrnal switch S0 S1*/ + HL_SW_SMART_ANT_TYPE1 = 0x10 /*Hong-Lin Smart antenna use for 8821AE which is a 2 Ant. entitys, and each Ant. is equipped with 4 antenna patterns*/ +}ANT_DIV_TYPE_E, *PANT_DIV_TYPE_E; + + +//1 ============================================================ +//1 function prototype +//1 ============================================================ + + +VOID +ODM_StopAntennaSwitchDm( + IN PVOID pDM_VOID + ); +VOID +ODM_SetAntConfig( + IN PVOID pDM_VOID, + IN u1Byte antSetting // 0=A, 1=B, 2=C, .... + ); + + +#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink + +VOID ODM_SwAntDivRestAfterLink( + IN PVOID pDM_VOID + ); + +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + +VOID +ODM_UpdateRxIdleAnt( + IN PVOID pDM_VOID, + IN u1Byte Ant +); + +#if (RTL8723B_SUPPORT == 1) +VOID +ODM_UpdateRxIdleAnt_8723B( + IN PVOID pDM_VOID, + IN u1Byte Ant, + IN u4Byte DefaultAnt, + IN u4Byte OptionalAnt +); +#endif + +#if (RTL8188F_SUPPORT == 1) +VOID +phydm_update_rx_idle_antenna_8188F( + IN PVOID pDM_VOID, + IN u4Byte default_ant +); +#endif + + +#ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + +#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_WorkitemCallback( + IN PVOID pContext +); + +VOID +ODM_SW_AntDiv_Callback( + void *FunctionContext + ); + +#endif + +VOID +odm_S0S1_SwAntDivByCtrlFrame( + IN PVOID pDM_VOID, + IN u1Byte Step +); + +VOID +odm_AntselStatisticsOfCtrlFrame( + IN PVOID pDM_VOID, + IN u1Byte antsel_tr_mux, + IN u4Byte RxPWDBAll +); + +VOID +odm_S0S1_SwAntDivByCtrlFrame_ProcessRSSI( + IN PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void +); + +#endif + +#ifdef ODM_EVM_ENHANCE_ANTDIV +VOID +odm_EVM_FastAntTrainingCallback( + IN PVOID pDM_VOID +); +#endif + +VOID +odm_HW_AntDiv( + IN PVOID pDM_VOID +); + +#if( defined(CONFIG_5G_CG_SMART_ANT_DIVERSITY) ) ||( defined(CONFIG_2G_CG_SMART_ANT_DIVERSITY) ) +VOID +odm_FastAntTraining( + IN PVOID pDM_VOID +); + +VOID +odm_FastAntTrainingCallback( + IN PVOID pDM_VOID +); + +VOID +odm_FastAntTrainingWorkItemCallback( + IN PVOID pDM_VOID +); +#endif + + +#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +phydm_beam_switch_workitem_callback( + IN PVOID pContext + ); + +VOID +phydm_beam_decision_workitem_callback( + IN PVOID pContext + ); + +#endif + +VOID +phydm_update_beam_pattern( + IN PVOID pDM_VOID, + IN u4Byte codeword, + IN u4Byte codeword_length + ); + +void +phydm_set_all_ant_same_beam_num( + IN PVOID pDM_VOID + ); + +VOID +phydm_hl_smart_ant_cmd( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +); + +#endif/*#ifdef CONFIG_HL_SMART_ANTENNA_TYPE1*/ + +VOID +ODM_AntDivInit( + IN PVOID pDM_VOID +); + +VOID +ODM_AntDiv( + IN PVOID pDM_VOID +); + +VOID +odm_AntselStatistics( + IN PVOID pDM_VOID, + IN u1Byte antsel_tr_mux, + IN u4Byte MacId, + IN u4Byte utility, + IN u1Byte method +); + +VOID +ODM_Process_RSSIForAntDiv( + IN OUT PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void +); + + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_SetTxAntByTxInfo( + IN PVOID pDM_VOID, + IN pu1Byte pDesc, + IN u1Byte macId +); + +#elif(DM_ODM_SUPPORT_TYPE == ODM_AP) + +VOID +ODM_SetTxAntByTxInfo( + struct rtl8192cd_priv *priv, + struct tx_desc *pdesc, + unsigned short aid +); + +#endif + + +VOID +ODM_AntDiv_Config( + IN PVOID pDM_VOID +); + +VOID +ODM_AntDivTimers( + IN PVOID pDM_VOID, + IN u1Byte state +); + +#endif /*#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY))*/ + +VOID +ODM_AntDivReset( + IN PVOID pDM_VOID +); + +VOID +odm_AntennaDiversityInit( + IN PVOID pDM_VOID +); + +VOID +odm_AntennaDiversity( + IN PVOID pDM_VOID +); + + +#endif /*#ifndef __ODMANTDIV_H__*/ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.c new file mode 100644 index 00000000..6410a03b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.c @@ -0,0 +1,1939 @@ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#if WPP_SOFTWARE_TRACE +#include "phydm_beamforming.tmh" +#endif +#endif + +#if (BEAMFORMING_SUPPORT == 1) + +PRT_BEAMFORM_STAINFO +phydm_staInfoInit( + IN PDM_ODM_T pDM_Odm, + IN u2Byte staIdx + ) +{ + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORM_STAINFO pEntry = &(pBeamInfo->BeamformSTAinfo); + PSTA_INFO_T pSTA = pDM_Odm->pODM_StaInfo[staIdx]; + PADAPTER Adapter = pDM_Odm->Adapter; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + PRT_VERY_HIGH_THROUGHPUT pVHTInfo = GET_VHT_INFO(pMgntInfo); + + ODM_MoveMemory(pDM_Odm, pEntry->MyMacAddr, Adapter->CurrentAddress, 6); + + pEntry->HtBeamformCap = pHTInfo->HtBeamformCap; + pEntry->VhtBeamformCap = pVHTInfo->VhtBeamformCap; + + /*IBSS, AP mode*/ + if (staIdx != 0) { + pEntry->AID = pSTA->AID; + pEntry->RA = pSTA->MacAddr; + pEntry->MacID = pSTA->AssociatedMacId; + pEntry->WirelessMode = pSTA->WirelessMode; + pEntry->BW = pSTA->BandWidth; + pEntry->CurBeamform = pSTA->HTInfo.HtCurBeamform; + } else {/*client mode*/ + pEntry->AID = pMgntInfo->mAId; + pEntry->RA = pMgntInfo->Bssid; + pEntry->MacID = pMgntInfo->mMacId; + pEntry->WirelessMode = pMgntInfo->dot11CurrentWirelessMode; + pEntry->BW = pMgntInfo->dot11CurrentChannelBandWidth; + pEntry->CurBeamform = pHTInfo->HtCurBeamform; + } + + if ((pEntry->WirelessMode & WIRELESS_MODE_AC_5G) || (pEntry->WirelessMode & WIRELESS_MODE_AC_24G)) { + if (staIdx != 0) + pEntry->CurBeamformVHT = pSTA->VHTInfo.VhtCurBeamform; + else + pEntry->CurBeamformVHT = pVHTInfo->VhtCurBeamform; + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("pSTA->wireless_mode = 0x%x, staidx = %d\n", pSTA->WirelessMode, staIdx)); +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + + if (!IS_STA_VALID(pSTA)) { + rtw_warn_on(1); + DBG_871X("%s => sta_info(mac_id:%d) failed\n", __func__, staIdx); + return pEntry; + } + + ODM_MoveMemory(pDM_Odm, pEntry->MyMacAddr, adapter_mac_addr(pSTA->padapter), 6); + pEntry->HtBeamformCap = pSTA->htpriv.beamform_cap; + + pEntry->AID = pSTA->aid; + pEntry->RA = pSTA->hwaddr; + pEntry->MacID = pSTA->mac_id; + pEntry->WirelessMode = pSTA->wireless_mode; + pEntry->BW = pSTA->bw_mode; + + pEntry->CurBeamform = pSTA->htpriv.beamform_cap; +#if ODM_IC_11AC_SERIES_SUPPORT + if ((pEntry->WirelessMode & WIRELESS_MODE_AC_5G) || (pEntry->WirelessMode & WIRELESS_MODE_AC_24G)) { + pEntry->CurBeamformVHT = pSTA->vhtpriv.beamform_cap; + pEntry->VhtBeamformCap = pSTA->vhtpriv.beamform_cap; + } +#endif + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("pSTA->wireless_mode = 0x%x, staidx = %d\n", pSTA->wireless_mode, staIdx)); +#endif + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("pEntry->CurBeamform = 0x%x, pEntry->CurBeamformVHT = 0x%x\n", pEntry->CurBeamform, pEntry->CurBeamformVHT)); + return pEntry; + +} +void phydm_staInfoUpdate( + IN PDM_ODM_T pDM_Odm, + IN u2Byte staIdx, + PRT_BEAMFORMEE_ENTRY pBeamformEntry + ) +{ + PSTA_INFO_T pSTA = pDM_Odm->pODM_StaInfo[staIdx]; + + if (!IS_STA_VALID(pSTA)) + return; + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + pSTA->txbf_paid = pBeamformEntry->P_AID; + pSTA->txbf_gid = pBeamformEntry->G_ID; +#endif +} + + +u1Byte +Beamforming_GetHTNDPTxRate( + IN PVOID pDM_VOID, + u1Byte CompSteeringNumofBFer +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Nr_index = 0; + u1Byte NDPTxRate; + /*Find Nr*/ + + if (pDM_Odm->SupportICType & ODM_RTL8814A) + Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), CompSteeringNumofBFer); + else + Nr_index = TxBF_Nr(1, CompSteeringNumofBFer); + + switch (Nr_index) { + case 1: + NDPTxRate = MGN_MCS8; + break; + + case 2: + NDPTxRate = MGN_MCS16; + break; + + case 3: + NDPTxRate = MGN_MCS24; + break; + + default: + NDPTxRate = MGN_MCS8; + break; + } + +return NDPTxRate; + +} + +u1Byte +Beamforming_GetVHTNDPTxRate( + IN PVOID pDM_VOID, + u1Byte CompSteeringNumofBFer +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Nr_index = 0; + u1Byte NDPTxRate; + /*Find Nr*/ + if (pDM_Odm->SupportICType & ODM_RTL8814A) + Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), CompSteeringNumofBFer); + else + Nr_index = TxBF_Nr(1, CompSteeringNumofBFer); + + switch (Nr_index) { + case 1: + NDPTxRate = MGN_VHT2SS_MCS0; + break; + + case 2: + NDPTxRate = MGN_VHT3SS_MCS0; + break; + + case 3: + NDPTxRate = MGN_VHT4SS_MCS0; + break; + + default: + NDPTxRate = MGN_VHT2SS_MCS0; + break; + } + +return NDPTxRate; + +} + + +PRT_BEAMFORMEE_ENTRY +phydm_Beamforming_GetBFeeEntryByAddr( + IN PVOID pDM_VOID, + IN pu1Byte RA, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformeeEntry[i].bUsed && (eqMacAddr(RA, pBeamInfo->BeamformeeEntry[i].MacAddr))) { + *Idx = i; + return &(pBeamInfo->BeamformeeEntry[i]); + } + } + + return NULL; +} + +PRT_BEAMFORMER_ENTRY +phydm_Beamforming_GetBFerEntryByAddr( + IN PVOID pDM_VOID, + IN pu1Byte TA, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (i = 0; i < BEAMFORMER_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformerEntry[i].bUsed && (eqMacAddr(TA, pBeamInfo->BeamformerEntry[i].MacAddr))) { + *Idx = i; + return &(pBeamInfo->BeamformerEntry[i]); + } + } + + return NULL; +} + + +PRT_BEAMFORMEE_ENTRY +phydm_Beamforming_GetEntryByMacId( + IN PVOID pDM_VOID, + IN u1Byte MacId, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformeeEntry[i].bUsed && (MacId == pBeamInfo->BeamformeeEntry[i].MacId)) { + *Idx = i; + return &(pBeamInfo->BeamformeeEntry[i]); + } + } + + return NULL; +} + + +BEAMFORMING_CAP +phydm_Beamforming_GetEntryBeamCapByMacId( + IN PVOID pDM_VOID, + IN u1Byte MacId + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + BEAMFORMING_CAP BeamformEntryCap = BEAMFORMING_CAP_NONE; + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformeeEntry[i].bUsed && (MacId == pBeamInfo->BeamformeeEntry[i].MacId)) { + BeamformEntryCap = pBeamInfo->BeamformeeEntry[i].BeamformEntryCap; + i = BEAMFORMEE_ENTRY_NUM; + } + } + + return BeamformEntryCap; +} + + +PRT_BEAMFORMEE_ENTRY +phydm_Beamforming_GetFreeBFeeEntry( + IN PVOID pDM_VOID, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformeeEntry[i].bUsed == FALSE) { + *Idx = i; + return &(pBeamInfo->BeamformeeEntry[i]); + } + } + return NULL; +} + +PRT_BEAMFORMER_ENTRY +phydm_Beamforming_GetFreeBFerEntry( + IN PVOID pDM_VOID, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s ===>\n", __func__)); + + for (i = 0; i < BEAMFORMER_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformerEntry[i].bUsed == FALSE) { + *Idx = i; + return &(pBeamInfo->BeamformerEntry[i]); + } + } + return NULL; +} + +/* +// Description: Get the first entry index of MU Beamformee. +// +// Return Value: Index of the first MU sta. +// +// 2015.05.25. Created by tynli. +// +*/ +u1Byte +phydm_Beamforming_GetFirstMUBFeeEntryIdx( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte idx = 0xFF; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + BOOLEAN bFound = FALSE; + + for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) { + if (pBeamInfo->BeamformeeEntry[idx].bUsed && pBeamInfo->BeamformeeEntry[idx].is_mu_sta) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] idx=%d!\n", __func__, idx)); + bFound = TRUE; + break; + } + } + + if (!bFound) + idx = 0xFF; + + return idx; +} + + +/*Add SU BFee and MU BFee*/ +PRT_BEAMFORMEE_ENTRY +Beamforming_AddBFeeEntry( + IN PVOID pDM_VOID, + IN PRT_BEAMFORM_STAINFO pSTA, + IN BEAMFORMING_CAP BeamformCap, + IN u1Byte NumofSoundingDim, + IN u1Byte CompSteeringNumofBFer, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMEE_ENTRY pEntry = phydm_Beamforming_GetFreeBFeeEntry(pDM_Odm, Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pEntry != NULL) { + pEntry->bUsed = TRUE; + pEntry->AID = pSTA->AID; + pEntry->MacId = pSTA->MacID; + pEntry->SoundBW = pSTA->BW; + ODM_MoveMemory(pDM_Odm, pEntry->MyMacAddr, pSTA->MyMacAddr, 6); + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_AP)) { + /*BSSID[44:47] xor BSSID[40:43]*/ + u2Byte BSSID = ((pSTA->MyMacAddr[5] & 0xf0) >> 4) ^ (pSTA->MyMacAddr[5] & 0xf); + /*(dec(A) + dec(B)*32) mod 512*/ + pEntry->P_AID = (pSTA->AID + BSSID * 32) & 0x1ff; + pEntry->G_ID = 63; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BFee P_AID addressed to STA=%d\n", __func__, pEntry->P_AID)); + } else if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) { + /*ad hoc mode*/ + pEntry->P_AID = 0; + pEntry->G_ID = 63; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BFee P_AID as IBSS=%d\n", __func__, pEntry->P_AID)); + } else { + /*client mode*/ + pEntry->P_AID = pSTA->RA[5]; + /*BSSID[39:47]*/ + pEntry->P_AID = (pEntry->P_AID << 1) | (pSTA->RA[4] >> 7); + pEntry->G_ID = 0; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BFee P_AID addressed to AP=0x%X\n", __func__, pEntry->P_AID)); + } + cpMacAddr(pEntry->MacAddr, pSTA->RA); + pEntry->bTxBF = FALSE; + pEntry->bSound = FALSE; + pEntry->SoundPeriod = 400; + pEntry->BeamformEntryCap = BeamformCap; + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + +/* pEntry->LogSeq = 0xff; Move to Beamforming_AddBFerEntry*/ +/* pEntry->LogRetryCnt = 0; Move to Beamforming_AddBFerEntry*/ +/* pEntry->LogSuccessCnt = 0; Move to Beamforming_AddBFerEntry*/ + + pEntry->LogStatusFailCnt = 0; + + pEntry->NumofSoundingDim = NumofSoundingDim; + pEntry->CompSteeringNumofBFer = CompSteeringNumofBFer; + + if (BeamformCap & BEAMFORMER_CAP_VHT_MU) { + pDM_Odm->BeamformingInfo.beamformee_mu_cnt += 1; + pEntry->is_mu_sta = TRUE; + pDM_Odm->BeamformingInfo.FirstMUBFeeIndex = phydm_Beamforming_GetFirstMUBFeeEntryIdx(pDM_Odm); + } else if (BeamformCap & BEAMFORMER_CAP_VHT_SU) { + pDM_Odm->BeamformingInfo.beamformee_su_cnt += 1; + pEntry->is_mu_sta = FALSE; + } + + return pEntry; + } + else + return NULL; +} + +/*Add SU BFee and MU BFer*/ +PRT_BEAMFORMER_ENTRY +Beamforming_AddBFerEntry( + IN PVOID pDM_VOID, + IN PRT_BEAMFORM_STAINFO pSTA, + IN BEAMFORMING_CAP BeamformCap, + IN u1Byte NumofSoundingDim, + OUT pu1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMER_ENTRY pEntry = phydm_Beamforming_GetFreeBFerEntry(pDM_Odm, Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pEntry != NULL) { + pEntry->bUsed = TRUE; + ODM_MoveMemory(pDM_Odm, pEntry->MyMacAddr, pSTA->MyMacAddr, 6); + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_AP)) { + /*BSSID[44:47] xor BSSID[40:43]*/ + u2Byte BSSID = ((pSTA->MyMacAddr[5] & 0xf0) >> 4) ^ (pSTA->MyMacAddr[5] & 0xf); + + pEntry->P_AID = (pSTA->AID + BSSID * 32) & 0x1ff; + pEntry->G_ID = 63; + /*(dec(A) + dec(B)*32) mod 512*/ + } else if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) { + pEntry->P_AID = 0; + pEntry->G_ID = 63; + } else { + pEntry->P_AID = pSTA->RA[5]; + /*BSSID[39:47]*/ + pEntry->P_AID = (pEntry->P_AID << 1) | (pSTA->RA[4] >> 7); + pEntry->G_ID = 0; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: P_AID addressed to AP=0x%X\n", __func__, pEntry->P_AID)); + } + + cpMacAddr(pEntry->MacAddr, pSTA->RA); + pEntry->BeamformEntryCap = BeamformCap; + + pEntry->PreLogSeq = 0; /*Modified by Jeffery @2015-04-13*/ + pEntry->LogSeq = 0; /*Modified by Jeffery @2014-10-29*/ + pEntry->LogRetryCnt = 0; /*Modified by Jeffery @2014-10-29*/ + pEntry->LogSuccess = 0; /*LogSuccess is NOT needed to be accumulated, so LogSuccessCnt->LogSuccess, 2015-04-13, Jeffery*/ + pEntry->ClockResetTimes = 0; /*Modified by Jeffery @2015-04-13*/ + + pEntry->NumofSoundingDim = NumofSoundingDim; + + if (BeamformCap & BEAMFORMEE_CAP_VHT_MU) { + pDM_Odm->BeamformingInfo.beamformer_mu_cnt += 1; + pEntry->is_mu_ap = TRUE; + pEntry->AID = pSTA->AID; + } else if (BeamformCap & BEAMFORMEE_CAP_VHT_SU) { + pDM_Odm->BeamformingInfo.beamformer_su_cnt += 1; + pEntry->is_mu_ap = FALSE; + } + + return pEntry; + } + else + return NULL; +} + +#if 0 +BOOLEAN +Beamforming_RemoveEntry( + IN PADAPTER Adapter, + IN pu1Byte RA, + OUT pu1Byte Idx + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + PRT_BEAMFORMER_ENTRY pBFerEntry = phydm_Beamforming_GetBFerEntryByAddr(pDM_Odm, RA, Idx); + PRT_BEAMFORMEE_ENTRY pEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, Idx); + BOOLEAN ret = FALSE; + + RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s Start!\n", __func__)); + RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s, pBFerEntry=0x%x\n", __func__, pBFerEntry)); + RT_DISP(FBEAM, FBEAM_FUN, ("[Beamforming]@%s, pEntry=0x%x\n", __func__, pEntry)); + + if (pEntry != NULL) { + pEntry->bUsed = FALSE; + pEntry->BeamformEntryCap = BEAMFORMING_CAP_NONE; + /*pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE;*/ + pEntry->bBeamformingInProgress = FALSE; + ret = TRUE; + } + if (pBFerEntry != NULL) { + pBFerEntry->bUsed = FALSE; + pBFerEntry->BeamformEntryCap = BEAMFORMING_CAP_NONE; + ret = TRUE; + } + return ret; + +} +#endif + +/* Used for BeamformingStart_V1 */ +VOID +phydm_Beamforming_NDPARate( + IN PVOID pDM_VOID, + CHANNEL_WIDTH BW, + u1Byte Rate +) +{ + u2Byte NDPARate = Rate; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (NDPARate == 0) { + if(pDM_Odm->RSSI_Min > 30) // link RSSI > 30% + NDPARate = ODM_RATE24M; + else + NDPARate = ODM_RATE6M; + } + + if (NDPARate < ODM_RATEMCS0) + BW = (CHANNEL_WIDTH)ODM_BW20M; + + NDPARate = (NDPARate << 8) | BW; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_RATE, (pu1Byte)&NDPARate); + +} + + +/* Used for BeamformingStart_SW and BeamformingStart_FW */ +VOID +phydm_Beamforming_DymNDPARate( + IN PVOID pDM_VOID +) +{ + u2Byte NDPARate = ODM_RATE6M, BW; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pDM_Odm->RSSI_Min > 30) /*link RSSI > 30%*/ + NDPARate = ODM_RATE24M; + else + NDPARate = ODM_RATE6M; + + BW = ODM_BW20M; + NDPARate = NDPARate << 8 | BW; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_RATE, (pu1Byte)&NDPARate); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s End, NDPA Rate = 0x%X\n", __func__, NDPARate)); +} + +/* +* SW Sounding : SW Timer unit 1ms +* HW Timer unit (1/32000) s 32k is clock. +* FW Sounding : FW Timer unit 10ms +*/ +VOID +Beamforming_DymPeriod( + IN PVOID pDM_VOID, + IN u8 status +) +{ + u1Byte Idx; + BOOLEAN bChangePeriod = FALSE; + u2Byte SoundPeriod_SW, SoundPeriod_FW; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + PRT_BEAMFORMEE_ENTRY pBeamformEntry; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + + PRT_BEAMFORMEE_ENTRY pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + //3 TODO per-client throughput caculation. + + if ((*(pDM_Odm->pCurrentTxTP) + *(pDM_Odm->pCurrentRxTP) > 2) && ((pEntry->LogStatusFailCnt <= 20) || status)) { + SoundPeriod_SW = 40; /* 40ms */ + SoundPeriod_FW = 40; /* From H2C cmd, unit = 10ms */ + } else { + SoundPeriod_SW = 4000;/* 4s */ + SoundPeriod_FW = 400; + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]SoundPeriod_SW=%d, SoundPeriod_FW=%d\n", __func__, SoundPeriod_SW, SoundPeriod_FW)); + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + pBeamformEntry = pBeamInfo->BeamformeeEntry+Idx; + + if (pBeamformEntry->DefaultCSICnt > 20) { + /*Modified by David*/ + SoundPeriod_SW = 4000; + SoundPeriod_FW = 400; + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Period = %d\n", __func__, SoundPeriod_SW)); + if (pBeamformEntry->BeamformEntryCap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) { + if (pSoundInfo->SoundMode == SOUNDING_FW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_FW_HT_TIMER) { + if (pBeamformEntry->SoundPeriod != SoundPeriod_FW) { + pBeamformEntry->SoundPeriod = SoundPeriod_FW; + bChangePeriod = TRUE; /*Only FW sounding need to send H2C packet to change sound period. */ + } + } else if (pBeamformEntry->SoundPeriod != SoundPeriod_SW) { + pBeamformEntry->SoundPeriod = SoundPeriod_SW; + } + } + } + + if (bChangePeriod) + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_FW_NDPA, (pu1Byte)&Idx); +} + + + + +BOOLEAN +Beamforming_SendHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW, + IN u1Byte QIdx + ) +{ + BOOLEAN ret = TRUE; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (QIdx == BEACON_QUEUE) + ret = SendFWHTNDPAPacket(pDM_Odm, RA, BW); + else + ret = SendSWHTNDPAPacket(pDM_Odm, RA, BW); + + return ret; +} + + + +BOOLEAN +Beamforming_SendVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW, + IN u1Byte QIdx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + BOOLEAN ret = TRUE; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + + HalComTxbf_Set(pDM_Odm, TXBF_SET_GET_TX_RATE, NULL); + + if ((pDM_Odm->TxBfDataRate >= ODM_RATEVHTSS3MCS7) && (pDM_Odm->TxBfDataRate <= ODM_RATEVHTSS3MCS9)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s: 3SS VHT 789 don't sounding\n", __func__)); + + } else { + if (QIdx == BEACON_QUEUE) /* Send to reserved page => FW NDPA */ + ret = SendFWVHTNDPAPacket(pDM_Odm, RA, AID, BW); + else { +#ifdef SUPPORT_MU_BF + #if (SUPPORT_MU_BF == 1) + pBeamInfo->is_mu_sounding = TRUE; + ret = SendSWVHTMUNDPAPacket(pDM_Odm, BW); + #else + pBeamInfo->is_mu_sounding = FALSE; + ret = SendSWVHTNDPAPacket(pDM_Odm, RA, AID, BW); + #endif +#else + pBeamInfo->is_mu_sounding = FALSE; + ret = SendSWVHTNDPAPacket(pDM_Odm, RA, AID, BW); +#endif + } + } + return ret; +} + + +BEAMFORMING_NOTIFY_STATE +phydm_beamfomring_bSounding( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo, + pu1Byte Idx + ) +{ + BEAMFORMING_NOTIFY_STATE bSounding = BEAMFORMING_NOTIFY_NONE; + RT_BEAMFORMING_OID_INFO BeamOidInfo = pBeamInfo->BeamformingOidInfo; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + /*if(( Beamforming_GetBeamCap(pBeamInfo) & BEAMFORMER_CAP) == 0)*/ + /*bSounding = BEAMFORMING_NOTIFY_RESET;*/ + if (BeamOidInfo.SoundOidMode == SOUNDING_STOP_All_TIMER) + bSounding = BEAMFORMING_NOTIFY_RESET; + else { + u1Byte i; + + for (i = 0 ; i < BEAMFORMEE_ENTRY_NUM ; i++) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s: BFee Entry %d bUsed=%d, bSound=%d\n", __func__, i, pBeamInfo->BeamformeeEntry[i].bUsed, pBeamInfo->BeamformeeEntry[i].bSound)); + if (pBeamInfo->BeamformeeEntry[i].bUsed && (!pBeamInfo->BeamformeeEntry[i].bSound)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: Add BFee entry %d\n", __func__, i)); + *Idx = i; + if (pBeamInfo->BeamformeeEntry[i].is_mu_sta) + bSounding = BEAMFORMEE_NOTIFY_ADD_MU; + else + bSounding = BEAMFORMEE_NOTIFY_ADD_SU; + } + + if ((!pBeamInfo->BeamformeeEntry[i].bUsed) && pBeamInfo->BeamformeeEntry[i].bSound) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: Delete BFee entry %d\n", __func__, i)); + *Idx = i; + if (pBeamInfo->BeamformeeEntry[i].is_mu_sta) + bSounding = BEAMFORMEE_NOTIFY_DELETE_MU; + else + bSounding = BEAMFORMEE_NOTIFY_DELETE_SU; + } + } + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s End, bSounding = %d\n", __func__, bSounding)); + return bSounding; +} + + +//This function is unused +u1Byte +phydm_beamforming_SoundingIdx( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo + ) +{ + u1Byte Idx = 0; + RT_BEAMFORMEE_ENTRY BeamEntry; + RT_BEAMFORMING_OID_INFO BeamOidInfo = pBeamInfo->BeamformingOidInfo; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (BeamOidInfo.SoundOidMode == SOUNDING_SW_HT_TIMER || BeamOidInfo.SoundOidMode == SOUNDING_SW_VHT_TIMER || + BeamOidInfo.SoundOidMode == SOUNDING_HW_HT_TIMER || BeamOidInfo.SoundOidMode == SOUNDING_HW_VHT_TIMER) + Idx = BeamOidInfo.SoundOidIdx; + else { + u1Byte i; + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + if (pBeamInfo->BeamformeeEntry[i].bUsed && (FALSE == pBeamInfo->BeamformeeEntry[i].bSound)) { + Idx = i; + break; + } + } + } + + return Idx; +} + + +SOUNDING_MODE +phydm_beamforming_SoundingMode( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo, + u1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte SupportInterface = pDM_Odm->SupportInterface; + + RT_BEAMFORMEE_ENTRY BeamEntry = pBeamInfo->BeamformeeEntry[Idx]; + RT_BEAMFORMING_OID_INFO BeamOidInfo = pBeamInfo->BeamformingOidInfo; + SOUNDING_MODE Mode = BeamOidInfo.SoundOidMode; + + if (BeamOidInfo.SoundOidMode == SOUNDING_SW_VHT_TIMER || BeamOidInfo.SoundOidMode == SOUNDING_HW_VHT_TIMER) { + if (BeamEntry.BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + Mode = BeamOidInfo.SoundOidMode; + else + Mode = SOUNDING_STOP_All_TIMER; + } else if (BeamOidInfo.SoundOidMode == SOUNDING_SW_HT_TIMER || BeamOidInfo.SoundOidMode == SOUNDING_HW_HT_TIMER) { + if (BeamEntry.BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT) + Mode = BeamOidInfo.SoundOidMode; + else + Mode = SOUNDING_STOP_All_TIMER; + } else if (BeamEntry.BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) { + if ((SupportInterface == ODM_ITRF_USB) && !(pDM_Odm->SupportICType & (ODM_RTL8814A | ODM_RTL8822B))) + Mode = SOUNDING_FW_VHT_TIMER; + else + Mode = SOUNDING_SW_VHT_TIMER; + } else if (BeamEntry.BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT) { + if ((SupportInterface == ODM_ITRF_USB) && !(pDM_Odm->SupportICType & (ODM_RTL8814A | ODM_RTL8822B))) + Mode = SOUNDING_FW_HT_TIMER; + else + Mode = SOUNDING_SW_HT_TIMER; + } else + Mode = SOUNDING_STOP_All_TIMER; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] SupportInterface=%d, Mode=%d\n", __func__, SupportInterface, Mode)); + + return Mode; +} + + +u2Byte +phydm_beamforming_SoundingTime( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo, + SOUNDING_MODE Mode, + u1Byte Idx + ) +{ + u2Byte SoundingTime = 0xffff; + RT_BEAMFORMEE_ENTRY BeamEntry = pBeamInfo->BeamformeeEntry[Idx]; + RT_BEAMFORMING_OID_INFO BeamOidInfo = pBeamInfo->BeamformingOidInfo; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (Mode == SOUNDING_HW_HT_TIMER || Mode == SOUNDING_HW_VHT_TIMER) + SoundingTime = BeamOidInfo.SoundOidPeriod * 32; + else if (Mode == SOUNDING_SW_HT_TIMER || Mode == SOUNDING_SW_VHT_TIMER) + /*Modified by David*/ + SoundingTime = BeamEntry.SoundPeriod; /*BeamOidInfo.SoundOidPeriod;*/ + else + SoundingTime = BeamEntry.SoundPeriod; + + return SoundingTime; +} + + +CHANNEL_WIDTH +phydm_beamforming_SoundingBW( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo, + SOUNDING_MODE Mode, + u1Byte Idx + ) +{ + CHANNEL_WIDTH SoundingBW = CHANNEL_WIDTH_20; + RT_BEAMFORMEE_ENTRY BeamEntry = pBeamInfo->BeamformeeEntry[Idx]; + RT_BEAMFORMING_OID_INFO BeamOidInfo = pBeamInfo->BeamformingOidInfo; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (Mode == SOUNDING_HW_HT_TIMER || Mode == SOUNDING_HW_VHT_TIMER) + SoundingBW = BeamOidInfo.SoundOidBW; + else if (Mode == SOUNDING_SW_HT_TIMER || Mode == SOUNDING_SW_VHT_TIMER) + /*Modified by David*/ + SoundingBW = BeamEntry.SoundBW; /*BeamOidInfo.SoundOidBW;*/ + else + SoundingBW = BeamEntry.SoundBW; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, SoundingBW=0x%X\n", __func__, SoundingBW)); + + return SoundingBW; +} + + +BOOLEAN +phydm_Beamforming_SelectBeamEntry( + IN PVOID pDM_VOID, + PRT_BEAMFORMING_INFO pBeamInfo + ) +{ + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + /*pEntry.bSound is different between first and latter NDPA, and should not be used as BFee entry selection*/ + /*BTW, latter modification should sync to the selection mechanism of AP/ADSL instead of the fixed SoundIdx.*/ + pSoundInfo->SoundIdx = phydm_beamforming_SoundingIdx(pDM_Odm, pBeamInfo); + /*pSoundInfo->SoundIdx = 0;*/ + + if (pSoundInfo->SoundIdx < BEAMFORMEE_ENTRY_NUM) + pSoundInfo->SoundMode = phydm_beamforming_SoundingMode(pDM_Odm, pBeamInfo, pSoundInfo->SoundIdx); + else + pSoundInfo->SoundMode = SOUNDING_STOP_All_TIMER; + + if (SOUNDING_STOP_All_TIMER == pSoundInfo->SoundMode) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Return because of SOUNDING_STOP_All_TIMER\n", __func__)); + return FALSE; + } else { + pSoundInfo->SoundBW = phydm_beamforming_SoundingBW(pDM_Odm, pBeamInfo, pSoundInfo->SoundMode, pSoundInfo->SoundIdx ); + pSoundInfo->SoundPeriod = phydm_beamforming_SoundingTime(pDM_Odm, pBeamInfo, pSoundInfo->SoundMode, pSoundInfo->SoundIdx ); + return TRUE; + } +} + +/*SU BFee Entry Only*/ +BOOLEAN +phydm_beamforming_StartPeriod( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + BOOLEAN Ret = TRUE; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + + phydm_Beamforming_DymNDPARate(pDM_Odm); + + phydm_Beamforming_SelectBeamEntry(pDM_Odm, pBeamInfo); // Modified + + if (pSoundInfo->SoundMode == SOUNDING_SW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_SW_HT_TIMER) + ODM_SetTimer(pDM_Odm, &pBeamInfo->BeamformingTimer, pSoundInfo->SoundPeriod); + else if (pSoundInfo->SoundMode == SOUNDING_HW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_HW_HT_TIMER || + pSoundInfo->SoundMode == SOUNDING_AUTO_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_AUTO_HT_TIMER) { + HAL_HW_TIMER_TYPE TimerType = HAL_TIMER_TXBF; + u4Byte val = (pSoundInfo->SoundPeriod | (TimerType<<16)); + + //HW timer stop: All IC has the same setting + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_STOP, (pu1Byte)(&TimerType)); + //ODM_Write1Byte(pDM_Odm, 0x15F, 0); + //HW timer init: All IC has the same setting, but 92E & 8812A only write 2 bytes + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_INIT, (pu1Byte)(&val)); + //ODM_Write1Byte(pDM_Odm, 0x164, 1); + //ODM_Write4Byte(pDM_Odm, 0x15C, val); + //HW timer start: All IC has the same setting + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_START, (pu1Byte)(&TimerType)); + //ODM_Write1Byte(pDM_Odm, 0x15F, 0x5); + } else if (pSoundInfo->SoundMode == SOUNDING_FW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_FW_HT_TIMER) + Ret = BeamformingStart_FW(pDM_Odm, pSoundInfo->SoundIdx); + else + Ret = FALSE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] SoundIdx=%d, SoundMode=%d, SoundBW=%d, SoundPeriod=%d\n", __func__, + pSoundInfo->SoundIdx, pSoundInfo->SoundMode, pSoundInfo->SoundBW, pSoundInfo->SoundPeriod)); + + return Ret; +} + +// Used after Beamforming_Leave, and will clear the setting of the "already deleted" entry +/*SU BFee Entry Only*/ +VOID +phydm_beamforming_EndPeriod_SW( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pBeamformEntry; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + + HAL_HW_TIMER_TYPE TimerType = HAL_TIMER_TXBF; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pSoundInfo->SoundMode == SOUNDING_SW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_SW_HT_TIMER) + ODM_CancelTimer(pDM_Odm, &pBeamInfo->BeamformingTimer); + else if (pSoundInfo->SoundMode == SOUNDING_HW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_HW_HT_TIMER || + pSoundInfo->SoundMode == SOUNDING_AUTO_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_AUTO_HT_TIMER) + /*HW timer stop: All IC has the same setting*/ + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_STOP, (pu1Byte)(&TimerType)); + /*ODM_Write1Byte(pDM_Odm, 0x15F, 0);*/ +} + +VOID +phydm_beamforming_EndPeriod_FW( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx = 0; + + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_FW_NDPA, (pu1Byte)&Idx); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]\n", __func__)); +} + + +/*SU BFee Entry Only*/ +VOID +phydm_beamforming_ClearEntry_SW( + IN PVOID pDM_VOID, + BOOLEAN IsDelete, + u1Byte DeleteIdx + ) +{ + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + if (IsDelete) { + if (DeleteIdx < BEAMFORMEE_ENTRY_NUM) { + pBeamformEntry = pBeamInfo->BeamformeeEntry + DeleteIdx; + if (!((!pBeamformEntry->bUsed) && pBeamformEntry->bSound)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] SW DeleteIdx is wrong!!!!!\n", __func__)); + return; + } + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] SW delete BFee entry %d\n", __func__, DeleteIdx)); + if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) { + pBeamformEntry->bBeamformingInProgress = FALSE; + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + } else if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&DeleteIdx); + } + pBeamformEntry->bSound = FALSE; + } else { + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + pBeamformEntry = pBeamInfo->BeamformeeEntry+Idx; + + /*Used after bSounding=RESET, and will clear the setting of "ever sounded" entry, which is not necessarily be deleted.*/ + /*This function is mainly used in case "BeamOidInfo.SoundOidMode == SOUNDING_STOP_All_TIMER".*/ + /*However, setting oid doesn't delete entries (bUsed is still TRUE), new entries may fail to be added in.*/ + + if (pBeamformEntry->bSound) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] SW reset BFee entry %d\n", __func__, Idx)); + /* + * If End procedure is + * 1. Between (Send NDPA, C2H packet return), reset state to initialized. + * After C2H packet return , status bit will be set to zero. + * + * 2. After C2H packet, then reset state to initialized and clear status bit. + */ + + if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + phydm_Beamforming_End_SW(pDM_Odm, 0); + else if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZED; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&Idx); + } + + pBeamformEntry->bSound = FALSE; + } + } + } +} + +VOID +phydm_beamforming_ClearEntry_FW( + IN PVOID pDM_VOID, + BOOLEAN IsDelete, + u1Byte DeleteIdx + ) +{ + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + if (IsDelete) { + if (DeleteIdx < BEAMFORMEE_ENTRY_NUM) { + pBeamformEntry = pBeamInfo->BeamformeeEntry + DeleteIdx; + + if (!((!pBeamformEntry->bUsed) && pBeamformEntry->bSound)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] FW DeleteIdx is wrong!!!!!\n", __func__)); + return; + } + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: FW delete BFee entry %d\n", __func__, DeleteIdx)); + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE; + pBeamformEntry->bSound = FALSE; + } else { + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + pBeamformEntry = pBeamInfo->BeamformeeEntry+Idx; + + /*Used after bSounding=RESET, and will clear the setting of "ever sounded" entry, which is not necessarily be deleted.*/ + /*This function is mainly used in case "BeamOidInfo.SoundOidMode == SOUNDING_STOP_All_TIMER".*/ + /*However, setting oid doesn't delete entries (bUsed is still TRUE), new entries may fail to be added in.*/ + + if (pBeamformEntry->bSound) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]FW reset BFee entry %d\n", __func__, Idx)); + /* + * If End procedure is + * 1. Between (Send NDPA, C2H packet return), reset state to initialized. + * After C2H packet return , status bit will be set to zero. + * + * 2. After C2H packet, then reset state to initialized and clear status bit. + */ + + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZED; + pBeamformEntry->bSound = FALSE; + } + } + } +} + +/* +* Called : +* 1. Add and delete entry : Beamforming_Enter/Beamforming_Leave +* 2. FW trigger : Beamforming_SetTxBFen +* 3. Set OID_RT_BEAMFORMING_PERIOD : BeamformingControl_V2 +*/ +VOID +phydm_Beamforming_Notify( + IN PVOID pDM_VOID + ) +{ + u1Byte Idx=BEAMFORMEE_ENTRY_NUM; + BEAMFORMING_NOTIFY_STATE bSounding = BEAMFORMING_NOTIFY_NONE; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + bSounding = phydm_beamfomring_bSounding(pDM_Odm, pBeamInfo, &Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, Before notify, bSounding=%d, Idx=%d\n", __func__, bSounding, Idx)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: pBeamInfo->beamformee_su_cnt = %d\n", __func__, pBeamInfo->beamformee_su_cnt)); + + + switch (bSounding) { + case BEAMFORMEE_NOTIFY_ADD_SU: + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BEAMFORMEE_NOTIFY_ADD_SU\n", __func__)); + phydm_beamforming_StartPeriod(pDM_Odm); + break; + + case BEAMFORMEE_NOTIFY_DELETE_SU: + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BEAMFORMEE_NOTIFY_DELETE_SU\n", __func__)); + if (pSoundInfo->SoundMode == SOUNDING_FW_HT_TIMER || pSoundInfo->SoundMode == SOUNDING_FW_VHT_TIMER) { + phydm_beamforming_ClearEntry_FW(pDM_Odm, TRUE, Idx); + if (pBeamInfo->beamformee_su_cnt == 0) { /* For 2->1 entry, we should not cancel SW timer */ + phydm_beamforming_EndPeriod_FW(pDM_Odm); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: No BFee left\n", __func__)); + } + } else { + phydm_beamforming_ClearEntry_SW(pDM_Odm, TRUE, Idx); + if (pBeamInfo->beamformee_su_cnt == 0) { /* For 2->1 entry, we should not cancel SW timer */ + phydm_beamforming_EndPeriod_SW(pDM_Odm); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: No BFee left\n", __func__)); + } + } + break; + + case BEAMFORMEE_NOTIFY_ADD_MU: + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BEAMFORMEE_NOTIFY_ADD_MU\n", __func__)); + if (pBeamInfo->beamformee_mu_cnt == 2) { + /*if (pSoundInfo->SoundMode == SOUNDING_SW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_SW_HT_TIMER) + ODM_SetTimer(pDM_Odm, &pBeamInfo->BeamformingTimer, pSoundInfo->SoundPeriod);*/ + ODM_SetTimer(pDM_Odm, &pBeamInfo->BeamformingTimer, 1000); /*Do MU sounding every 1sec*/ + } else + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: Less or larger than 2 MU STAs, not to set timer\n", __func__)); + break; + + case BEAMFORMEE_NOTIFY_DELETE_MU: + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: BEAMFORMEE_NOTIFY_DELETE_MU\n", __func__)); + if (pBeamInfo->beamformee_mu_cnt == 1) { + /*if (pSoundInfo->SoundMode == SOUNDING_SW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_SW_HT_TIMER)*/{ + ODM_CancelTimer(pDM_Odm, &pBeamInfo->BeamformingTimer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: Less than 2 MU STAs, stop sounding\n", __func__)); + } + } + break; + + case BEAMFORMING_NOTIFY_RESET: + if (pSoundInfo->SoundMode == SOUNDING_FW_HT_TIMER || pSoundInfo->SoundMode == SOUNDING_FW_VHT_TIMER) { + phydm_beamforming_ClearEntry_FW(pDM_Odm, FALSE, Idx); + phydm_beamforming_EndPeriod_FW(pDM_Odm); + } else { + phydm_beamforming_ClearEntry_SW(pDM_Odm, FALSE, Idx); + phydm_beamforming_EndPeriod_SW(pDM_Odm); + } + + break; + + default: + break; + } + +} + + + +BOOLEAN +Beamforming_InitEntry( + IN PVOID pDM_VOID, + IN u2Byte staIdx, + pu1Byte BFerBFeeIdx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL; + PRT_BEAMFORMER_ENTRY pBeamformerEntry = NULL; + PRT_BEAMFORM_STAINFO pSTA = NULL; + BEAMFORMING_CAP BeamformCap = BEAMFORMING_CAP_NONE; + u1Byte BFerIdx=0xF, BFeeIdx=0xF; + u1Byte NumofSoundingDim = 0, CompSteeringNumofBFer = 0; + + pSTA = phydm_staInfoInit(pDM_Odm, staIdx); + + /*The current setting does not support Beaforming*/ + if (BEAMFORMING_CAP_NONE == pSTA->HtBeamformCap && BEAMFORMING_CAP_NONE == pSTA->VhtBeamformCap) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("The configuration disabled Beamforming! Skip...\n")); + return FALSE; + } + + if (pSTA->WirelessMode < WIRELESS_MODE_N_24G) + return FALSE; + else { /*HT*/ + /*We are Beamformee because the STA is Beamformer*/ + if (TEST_FLAG(pSTA->CurBeamform, BEAMFORMING_HT_BEAMFORMER_ENABLE)) { + BeamformCap =(BEAMFORMING_CAP)(BeamformCap |BEAMFORMEE_CAP_HT_EXPLICIT); + NumofSoundingDim = (pSTA->CurBeamform&BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP)>>6; + } + /*We are Beamformer because the STA is Beamformee*/ + if (TEST_FLAG(pSTA->CurBeamform, BEAMFORMING_HT_BEAMFORMEE_ENABLE) || + TEST_FLAG(pSTA->HtBeamformCap, BEAMFORMING_HT_BEAMFORMER_TEST)) { + BeamformCap =(BEAMFORMING_CAP)(BeamformCap | BEAMFORMER_CAP_HT_EXPLICIT); + CompSteeringNumofBFer = (pSTA->CurBeamform & BEAMFORMING_HT_BEAMFORMER_STEER_NUM)>>4; + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] HT CurBeamform=0x%X, BeamformCap=0x%X\n", __func__, pSTA->CurBeamform, BeamformCap)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] HT NumofSoundingDim=%d, CompSteeringNumofBFer=%d\n", __func__, NumofSoundingDim, CompSteeringNumofBFer)); +#if (ODM_IC_11AC_SERIES_SUPPORT == 1) + if (pSTA->WirelessMode & WIRELESS_MODE_AC_5G || pSTA->WirelessMode & WIRELESS_MODE_AC_24G) { /*VHT*/ + + /* We are Beamformee because the STA is SU Beamformer*/ + if (TEST_FLAG(pSTA->CurBeamformVHT, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + BeamformCap =(BEAMFORMING_CAP)(BeamformCap |BEAMFORMEE_CAP_VHT_SU); + NumofSoundingDim = (pSTA->CurBeamformVHT & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM)>>12; + } + /* We are Beamformer because the STA is SU Beamformee*/ + if (TEST_FLAG(pSTA->CurBeamformVHT, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) || + TEST_FLAG(pSTA->VhtBeamformCap, BEAMFORMING_VHT_BEAMFORMER_TEST)) { + BeamformCap =(BEAMFORMING_CAP)(BeamformCap |BEAMFORMER_CAP_VHT_SU); + CompSteeringNumofBFer = (pSTA->CurBeamformVHT & BEAMFORMING_VHT_BEAMFORMER_STS_CAP)>>8; + } + /* We are Beamformee because the STA is MU Beamformer*/ + if (TEST_FLAG(pSTA->CurBeamformVHT, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) { + BeamformCap = (BEAMFORMING_CAP)(BeamformCap | BEAMFORMEE_CAP_VHT_MU); + NumofSoundingDim = (pSTA->CurBeamformVHT & BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM)>>12; + } + /* We are Beamformer because the STA is MU Beamformee*/ + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_AP)) { /* Only AP mode supports to act an MU beamformer */ + if (TEST_FLAG(pSTA->CurBeamformVHT, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE) || + TEST_FLAG(pSTA->VhtBeamformCap, BEAMFORMING_VHT_BEAMFORMER_TEST)) { + BeamformCap = (BEAMFORMING_CAP)(BeamformCap | BEAMFORMER_CAP_VHT_MU); + CompSteeringNumofBFer = (pSTA->CurBeamformVHT & BEAMFORMING_VHT_BEAMFORMER_STS_CAP)>>8; + } + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]VHT CurBeamformVHT=0x%X, BeamformCap=0x%X\n", __func__, pSTA->CurBeamformVHT, BeamformCap)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]VHT NumofSoundingDim=0x%X, CompSteeringNumofBFer=0x%X\n", __func__, NumofSoundingDim, CompSteeringNumofBFer)); + + } +#endif + } + + + if(BeamformCap == BEAMFORMING_CAP_NONE) + return FALSE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Self BF Entry Cap = 0x%02X\n", __func__, BeamformCap)); + + /*We are BFee, so the entry is BFer*/ + if (BeamformCap & (BEAMFORMEE_CAP_VHT_MU | BEAMFORMEE_CAP_VHT_SU | BEAMFORMEE_CAP_HT_EXPLICIT)) { + pBeamformerEntry = phydm_Beamforming_GetBFerEntryByAddr(pDM_Odm, pSTA->RA, &BFerIdx); + + if (pBeamformerEntry == NULL) { + pBeamformerEntry = Beamforming_AddBFerEntry(pDM_Odm, pSTA, BeamformCap, NumofSoundingDim , &BFerIdx); + if (pBeamformerEntry == NULL) + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Not enough BFer entry!!!!!\n", __func__)); + } + } + + /*We are BFer, so the entry is BFee*/ + if (BeamformCap & (BEAMFORMER_CAP_VHT_MU | BEAMFORMER_CAP_VHT_SU | BEAMFORMER_CAP_HT_EXPLICIT)) { + pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, pSTA->RA, &BFeeIdx); + + /*¦pªGBFeeIdx = 0xF «h¥Nªí¥Ø«eentry·í¤¤¨S¦³¬Û¦PªºMACID¦b¤º*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Get BFee entry 0x%X by address\n", __func__, BFeeIdx)); + if (pBeamformEntry == NULL) { + pBeamformEntry = Beamforming_AddBFeeEntry(pDM_Odm, pSTA, BeamformCap, NumofSoundingDim, CompSteeringNumofBFer, &BFeeIdx); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]: pSTA->AID=%d, pSTA->MacID=%d\n", __func__, pSTA->AID, pSTA->MacID)); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]: Add BFee entry %d\n", __func__, BFeeIdx)); + + if (pBeamformEntry == NULL) + return FALSE; + else + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZEING; + } else { + /*Entry has been created. If entry is initialing or progressing then errors occur.*/ + if (pBeamformEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_INITIALIZED && + pBeamformEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_PROGRESSED) { + return FALSE; + } else + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZEING; + } + pBeamformEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZED; + phydm_staInfoUpdate(pDM_Odm, staIdx, pBeamformEntry); + } + + *BFerBFeeIdx = (BFerIdx<<4) | BFeeIdx; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End: BFerIdx=0x%X, BFeeIdx=0x%X, BFerBFeeIdx=0x%X\n", __func__, BFerIdx, BFeeIdx, *BFerBFeeIdx)); + + return TRUE; +} + + +VOID +Beamforming_DeInitEntry( + IN PVOID pDM_VOID, + pu1Byte RA + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx = 0; + + PRT_BEAMFORMER_ENTRY pBFerEntry = phydm_Beamforming_GetBFerEntryByAddr(pDM_Odm, RA, &Idx); + PRT_BEAMFORMEE_ENTRY pBFeeEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + BOOLEAN ret = FALSE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pBFeeEntry != NULL) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, pBFeeEntry\n", __func__)); + pBFeeEntry->bUsed = FALSE; + pBFeeEntry->BeamformEntryCap = BEAMFORMING_CAP_NONE; + pBFeeEntry->bBeamformingInProgress = FALSE; + if (pBFeeEntry->is_mu_sta) { + pDM_Odm->BeamformingInfo.beamformee_mu_cnt -= 1; + pDM_Odm->BeamformingInfo.FirstMUBFeeIndex = phydm_Beamforming_GetFirstMUBFeeEntryIdx(pDM_Odm); + } else { + pDM_Odm->BeamformingInfo.beamformee_su_cnt -= 1; + } + ret = TRUE; + } + + if (pBFerEntry != NULL) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, pBFerEntry\n", __func__)); + pBFerEntry->bUsed = FALSE; + pBFerEntry->BeamformEntryCap = BEAMFORMING_CAP_NONE; + if (pBFerEntry->is_mu_ap) + pDM_Odm->BeamformingInfo.beamformer_mu_cnt -= 1; + else + pDM_Odm->BeamformingInfo.beamformer_su_cnt -= 1; + ret = TRUE; + } + + if (ret == TRUE) + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_LEAVE, (pu1Byte)&Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s End, Idx = 0x%X\n", __func__, Idx)); +} + + +VOID +Beamforming_Reset( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx = 0; + PRT_BEAMFORMING_INFO pBeamformingInfo = &(pDM_Odm->BeamformingInfo); + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + if (pBeamformingInfo->BeamformeeEntry[Idx].bUsed == TRUE) { + pBeamformingInfo->BeamformeeEntry[Idx].bUsed = FALSE; + pBeamformingInfo->BeamformeeEntry[Idx].BeamformEntryCap = BEAMFORMING_CAP_NONE; + /*pBeamformingInfo->BeamformeeEntry[Idx].BeamformEntryState = BEAMFORMING_ENTRY_STATE_UNINITIALIZE;*/ + /*Modified by David*/ + pBeamformingInfo->BeamformeeEntry[Idx].bBeamformingInProgress = FALSE; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_LEAVE, (pu1Byte)&Idx); + } + } + + for (Idx = 0; Idx < BEAMFORMER_ENTRY_NUM; Idx++) { + pBeamformingInfo->BeamformerEntry[Idx].bUsed = FALSE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Idx=%d, bUsed=%d\n", __func__, Idx, pBeamformingInfo->BeamformerEntry[Idx].bUsed)); + } + +} + + +BOOLEAN +BeamformingStart_V1( + IN PVOID pDM_VOID, + pu1Byte RA, + BOOLEAN Mode, + CHANNEL_WIDTH BW, + u1Byte Rate + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pEntry; + BOOLEAN ret = TRUE; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + + pEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + if (pEntry->bUsed == FALSE) { + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } else { + if (pEntry->bBeamformingInProgress) + return FALSE; + + pEntry->bBeamformingInProgress = TRUE; + + if (Mode == 1) { + if (!(pEntry->BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT)) { + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } + } else if (Mode == 0) { + if (!(pEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU)) { + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } + } + + if (pEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_INITIALIZED && pEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_PROGRESSED) { + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } else { + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSING; + pEntry->bSound = TRUE; + } + } + + pEntry->SoundBW = BW; + pBeamInfo->BeamformeeCurIdx = Idx; + phydm_Beamforming_NDPARate(pDM_Odm, BW, Rate); + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&Idx); + + if (Mode == 1) + ret = Beamforming_SendHTNDPAPacket(pDM_Odm, RA, BW, NORMAL_QUEUE); + else + ret = Beamforming_SendVHTNDPAPacket(pDM_Odm, RA, pEntry->AID, BW, NORMAL_QUEUE); + + if (ret == FALSE) { + Beamforming_Leave(pDM_Odm, RA); + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Idx %d\n", __func__, Idx)); + return TRUE; +} + + +BOOLEAN +BeamformingStart_SW( + IN PVOID pDM_VOID, + u1Byte Idx, + u1Byte Mode, + CHANNEL_WIDTH BW + ) +{ + pu1Byte RA = NULL; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMEE_ENTRY pEntry; + BOOLEAN ret = TRUE; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + + pEntry = &(pBeamInfo->BeamformeeEntry[Idx]); + + if (pEntry->bUsed == FALSE) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Skip Beamforming, no entry for Idx =%d\n", Idx)); + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } else { + if (pEntry->bBeamformingInProgress) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("bBeamformingInProgress, skip...\n")); + return FALSE; + } + + pEntry->bBeamformingInProgress = TRUE; + RA = pEntry->MacAddr; + + if (Mode == SOUNDING_SW_HT_TIMER || Mode == SOUNDING_HW_HT_TIMER || Mode == SOUNDING_AUTO_HT_TIMER) { + if (!(pEntry->BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT)) { + pEntry->bBeamformingInProgress = FALSE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Return by not support BEAMFORMER_CAP_HT_EXPLICIT <==\n", __func__)); + return FALSE; + } + } else if (Mode == SOUNDING_SW_VHT_TIMER || Mode == SOUNDING_HW_VHT_TIMER || Mode == SOUNDING_AUTO_VHT_TIMER) { + if (!(pEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU)) { + pEntry->bBeamformingInProgress = FALSE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Return by not support BEAMFORMER_CAP_VHT_SU <==\n", __func__)); + return FALSE; + } + } + if (pEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_INITIALIZED && pEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_PROGRESSED) { + pEntry->bBeamformingInProgress = FALSE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Return by incorrect BeamformEntryState(%d) <==\n", __func__, pEntry->BeamformEntryState)); + return FALSE; + } else { + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSING; + pEntry->bSound = TRUE; + } + } + + pBeamInfo->BeamformeeCurIdx = Idx; + /*2014.12.22 Luke: Need to be checked*/ + /*GET_TXBF_INFO(Adapter)->fTxbfSet(Adapter, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&Idx);*/ + + if (Mode == SOUNDING_SW_HT_TIMER || Mode == SOUNDING_HW_HT_TIMER || Mode == SOUNDING_AUTO_HT_TIMER) + ret = Beamforming_SendHTNDPAPacket(pDM_Odm, RA , BW, NORMAL_QUEUE); + else + ret = Beamforming_SendVHTNDPAPacket(pDM_Odm, RA , pEntry->AID, BW, NORMAL_QUEUE); + + if (ret == FALSE) { + Beamforming_Leave(pDM_Odm, RA); + pEntry->bBeamformingInProgress = FALSE; + return FALSE; + } + + + /*-------------------------- + // Send BF Report Poll for MU BF + --------------------------*/ +#ifdef SUPPORT_MU_BF +#if (SUPPORT_MU_BF == 1) +{ + u1Byte idx, PollSTACnt = 0; + BOOLEAN bGetFirstBFee = FALSE; + + if (pBeamInfo->beamformee_mu_cnt > 1) { /* More than 1 MU STA*/ + + for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) { + pEntry = &(pBeamInfo->BeamformeeEntry[idx]); + if (pEntry->is_mu_sta) { + if (bGetFirstBFee) { + PollSTACnt++; + if (PollSTACnt == (pBeamInfo->beamformee_mu_cnt - 1))/* The last STA*/ + SendSWVHTBFReportPoll(pDM_Odm, pEntry->MacAddr, TRUE); + else + SendSWVHTBFReportPoll(pDM_Odm, pEntry->MacAddr, FALSE); + } else { + bGetFirstBFee = TRUE; + } + } + } + } +} +#endif +#endif + return TRUE; +} + + +BOOLEAN +BeamformingStart_FW( + IN PVOID pDM_VOID, + u1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pu1Byte RA = NULL; + PRT_BEAMFORMEE_ENTRY pEntry; + BOOLEAN ret = TRUE; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + + pEntry = &(pBeamInfo->BeamformeeEntry[Idx]); + if (pEntry->bUsed == FALSE) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Skip Beamforming, no entry for Idx =%d\n", Idx)); + return FALSE; + } + + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSING; + pEntry->bSound = TRUE; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_FW_NDPA, (pu1Byte)&Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End, Idx=0x%X\n", __func__, Idx)); + return TRUE; +} + +VOID +Beamforming_CheckSoundingSuccess( + IN PVOID pDM_VOID, + BOOLEAN Status +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[David]@%s Start!\n", __func__)); + + if (Status == 1) { + if (pEntry->LogStatusFailCnt == 21) + Beamforming_DymPeriod(pDM_Odm, Status); + pEntry->LogStatusFailCnt = 0; + } else if (pEntry->LogStatusFailCnt <= 20) { + pEntry->LogStatusFailCnt++; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s LogStatusFailCnt %d\n", __func__, pEntry->LogStatusFailCnt)); + } + if (pEntry->LogStatusFailCnt > 20) { + pEntry->LogStatusFailCnt = 21; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s LogStatusFailCnt > 20, Stop SOUNDING\n", __func__)); + Beamforming_DymPeriod(pDM_Odm, Status); + } +} + +VOID +phydm_Beamforming_End_SW( + IN PVOID pDM_VOID, + BOOLEAN Status + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + + if (pEntry->BeamformEntryState != BEAMFORMING_ENTRY_STATE_PROGRESSING) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BeamformStatus %d\n", __func__, pEntry->BeamformEntryState)); + return; + } + + if ((pDM_Odm->TxBfDataRate >= ODM_RATEVHTSS3MCS7) && (pDM_Odm->TxBfDataRate <= ODM_RATEVHTSS3MCS9)) { + ODM_RT_TRACE(pDM_Odm, BEAMFORMING_DEBUG, ODM_DBG_LOUD, ("[%s] VHT3SS 7,8,9, do not apply V matrix.\n", __func__)); + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZED; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&(pBeamInfo->BeamformeeCurIdx)); + } else if (Status == 1) { + pEntry->LogStatusFailCnt = 0; + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_STATUS, (pu1Byte)&(pBeamInfo->BeamformeeCurIdx)); + } else { + pEntry->LogStatusFailCnt++; + pEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_INITIALIZED; + HalComTxbf_Set(pDM_Odm, TXBF_SET_TX_PATH_RESET, (pu1Byte)&(pBeamInfo->BeamformeeCurIdx)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] LogStatusFailCnt %d\n", __func__, pEntry->LogStatusFailCnt)); + } + + if (pEntry->LogStatusFailCnt > 30) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s LogStatusFailCnt > 50, Stop SOUNDING\n", __func__)); + pEntry->bSound = FALSE; + Beamforming_DeInitEntry(pDM_Odm, pEntry->MacAddr); + + /*Modified by David - Every action of deleting entry should follow by Notify*/ + phydm_Beamforming_Notify(pDM_Odm); + } + pEntry->bBeamformingInProgress = FALSE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: Status=%d\n", __func__, Status)); +} + + +VOID +Beamforming_TimerCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PVOID pDM_VOID +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + IN PVOID pContext +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER Adapter = (PADAPTER)pContext; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif + BOOLEAN ret = FALSE; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + PRT_SOUNDING_INFO pSoundInfo = &(pBeamInfo->SoundingInfo); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + if (pEntry->bBeamformingInProgress) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("bBeamformingInProgress, reset it\n")); + phydm_Beamforming_End_SW(pDM_Odm, 0); + } + + ret = phydm_Beamforming_SelectBeamEntry(pDM_Odm, pBeamInfo); +#if (SUPPORT_MU_BF == 1) + if (ret && pBeamInfo->beamformee_mu_cnt > 1) + ret = 1; + else + ret = 0; +#endif + if (ret) + ret = BeamformingStart_SW(pDM_Odm, pSoundInfo->SoundIdx, pSoundInfo->SoundMode, pSoundInfo->SoundBW); + else + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, Error value return from BeamformingStart_V2\n", __func__)); + + if ((pBeamInfo->beamformee_su_cnt != 0) || (pBeamInfo->beamformee_mu_cnt > 1)) { + if (pSoundInfo->SoundMode == SOUNDING_SW_VHT_TIMER || pSoundInfo->SoundMode == SOUNDING_SW_HT_TIMER) + ODM_SetTimer(pDM_Odm, &pBeamInfo->BeamformingTimer, pSoundInfo->SoundPeriod); + else { + u4Byte val = (pSoundInfo->SoundPeriod << 16) | HAL_TIMER_TXBF; + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_HW_REG_TIMER_RESTART, (pu1Byte)(&val)); + } + } +} + + +VOID +Beamforming_SWTimerCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PRT_TIMER pTimer +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + void *FunctionContext +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + Beamforming_TimerCallback(pDM_Odm); +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)FunctionContext; + PADAPTER Adapter = pDM_Odm->Adapter; + + if (Adapter->net_closed == TRUE) + return; + rtw_run_in_thread_cmd(Adapter, Beamforming_TimerCallback, Adapter); +#endif + +} + + +VOID +phydm_Beamforming_Init( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PHAL_TXBF_INFO pTxbfInfo = &pBeamInfo->TxbfInfo; + PRT_BEAMFORMING_OID_INFO pBeamOidInfo = &(pBeamInfo->BeamformingOidInfo); + + pBeamOidInfo->SoundOidMode = SOUNDING_STOP_OID_TIMER; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Mode (%d)\n", __func__, pBeamOidInfo->SoundOidMode)); + + pBeamInfo->beamformee_su_cnt = 0; + pBeamInfo->beamformer_su_cnt = 0; + pBeamInfo->beamformee_mu_cnt = 0; + pBeamInfo->beamformer_mu_cnt = 0; + pBeamInfo->beamformee_mu_reg_maping = 0; + pBeamInfo->mu_ap_index = 0; + pBeamInfo->is_mu_sounding = FALSE; + pBeamInfo->FirstMUBFeeIndex = 0xFF; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pBeamInfo->SourceAdapter = pDM_Odm->Adapter; +#endif + halComTxbf_beamformInit(pDM_Odm); +} + + +VOID +Beamforming_Enter( + IN PVOID pDM_VOID, + IN u2Byte staIdx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte BFerBFeeIdx = 0xff; + + if (Beamforming_InitEntry(pDM_Odm, staIdx, &BFerBFeeIdx)) + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_ENTER, (pu1Byte)&BFerBFeeIdx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End!\n", __func__)); +} + + +VOID +Beamforming_Leave( + IN PVOID pDM_VOID, + pu1Byte RA + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (RA == NULL) + Beamforming_Reset(pDM_Odm); + else + Beamforming_DeInitEntry(pDM_Odm, RA); + + phydm_Beamforming_Notify(pDM_Odm); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End!!\n", __func__)); +} + +#if 0 +//Nobody calls this function +VOID +phydm_Beamforming_SetTxBFen( + IN PVOID pDM_VOID, + u1Byte MacId, + BOOLEAN bTxBF + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pEntry; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + pEntry = phydm_Beamforming_GetEntryByMacId(pDM_Odm, MacId, &Idx); + + if(pEntry == NULL) + return; + else + pEntry->bTxBF = bTxBF; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s MacId %d TxBF %d\n", __func__, pEntry->MacId, pEntry->bTxBF)); + + phydm_Beamforming_Notify(pDM_Odm); +} +#endif + +BEAMFORMING_CAP +phydm_Beamforming_GetBeamCap( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamInfo + ) +{ + u1Byte i; + BOOLEAN bSelfBeamformer = FALSE; + BOOLEAN bSelfBeamformee = FALSE; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + RT_BEAMFORMER_ENTRY BeamformerEntry; + BEAMFORMING_CAP BeamformCap = BEAMFORMING_CAP_NONE; + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + BeamformeeEntry = pBeamInfo->BeamformeeEntry[i]; + + if (BeamformeeEntry.bUsed) { + bSelfBeamformer = TRUE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BFee entry %d bUsed=TRUE\n", __func__, i)); + break; + } + } + + for (i = 0; i < BEAMFORMER_ENTRY_NUM; i++) { + BeamformerEntry = pBeamInfo->BeamformerEntry[i]; + + if (BeamformerEntry.bUsed) { + bSelfBeamformee = TRUE; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]: BFer entry %d bUsed=TRUE\n", __func__, i)); + break; + } + } + + if (bSelfBeamformer) + BeamformCap = (BEAMFORMING_CAP)(BeamformCap | BEAMFORMER_CAP); + if (bSelfBeamformee) + BeamformCap = (BEAMFORMING_CAP)(BeamformCap | BEAMFORMEE_CAP); + + return BeamformCap; +} + + +BOOLEAN +BeamformingControl_V1( + IN PVOID pDM_VOID, + pu1Byte RA, + u1Byte AID, + u1Byte Mode, + CHANNEL_WIDTH BW, + u1Byte Rate + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + BOOLEAN ret = TRUE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("AID (%d), Mode (%d), BW (%d)\n", AID, Mode, BW)); + + switch (Mode) { + case 0: + ret = BeamformingStart_V1(pDM_Odm, RA, 0, BW, Rate); + break; + case 1: + ret = BeamformingStart_V1(pDM_Odm, RA, 1, BW, Rate); + break; + case 2: + phydm_Beamforming_NDPARate(pDM_Odm, BW, Rate); + ret = Beamforming_SendVHTNDPAPacket(pDM_Odm, RA, AID, BW, NORMAL_QUEUE); + break; + case 3: + phydm_Beamforming_NDPARate(pDM_Odm, BW, Rate); + ret = Beamforming_SendHTNDPAPacket(pDM_Odm, RA, BW, NORMAL_QUEUE); + break; + } + return ret; +} + +/*Only OID uses this function*/ +BOOLEAN +phydm_BeamformingControl_V2( + IN PVOID pDM_VOID, + u1Byte Idx, + u1Byte Mode, + CHANNEL_WIDTH BW, + u2Byte Period + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMING_OID_INFO pBeamOidInfo = &(pBeamInfo->BeamformingOidInfo); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Start!\n", __func__)); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Idx (%d), Mode (%d), BW (%d), Period (%d)\n", Idx, Mode, BW, Period)); + + pBeamOidInfo->SoundOidIdx = Idx; + pBeamOidInfo->SoundOidMode = (SOUNDING_MODE) Mode; + pBeamOidInfo->SoundOidBW = BW; + pBeamOidInfo->SoundOidPeriod = Period; + + phydm_Beamforming_Notify(pDM_Odm); + + return TRUE; +} + + +VOID +phydm_Beamforming_Watchdog( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("%s Start!\n", __func__)); + + if (pBeamInfo->beamformee_su_cnt == 0) + return; + + Beamforming_DymPeriod(pDM_Odm,0); + phydm_Beamforming_DymNDPARate(pDM_Odm); + +} + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.h new file mode 100644 index 00000000..1d4bf83c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_beamforming.h @@ -0,0 +1,365 @@ +#ifndef __INC_BEAMFORMING_H +#define __INC_BEAMFORMING_H + +#ifndef BEAMFORMING_SUPPORT +#define BEAMFORMING_SUPPORT 0 +#endif + +/*Beamforming Related*/ +#include "txbf/halcomtxbf.h" +#include "txbf/haltxbfjaguar.h" +#include "txbf/haltxbf8192e.h" +#include "txbf/haltxbf8814a.h" +#include "txbf/haltxbf8821b.h" +#include "txbf/haltxbf8822b.h" +#include "txbf/haltxbfinterface.h" + +#if (BEAMFORMING_SUPPORT == 1) + +#define MAX_BEAMFORMEE_SU 2 +#define MAX_BEAMFORMER_SU 2 +#if (RTL8822B_SUPPORT == 1) +#define MAX_BEAMFORMEE_MU 6 +#define MAX_BEAMFORMER_MU 1 +#else +#define MAX_BEAMFORMEE_MU 0 +#define MAX_BEAMFORMER_MU 0 +#endif + +#define BEAMFORMEE_ENTRY_NUM (MAX_BEAMFORMEE_SU + MAX_BEAMFORMEE_MU) +#define BEAMFORMER_ENTRY_NUM (MAX_BEAMFORMER_SU + MAX_BEAMFORMER_MU) + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +/*for different naming between WIN and CE*/ +#define BEACON_QUEUE BCN_QUEUE_INX +#define NORMAL_QUEUE MGT_QUEUE_INX +#define RT_DISABLE_FUNC RTW_DISABLE_FUNC +#define RT_ENABLE_FUNC RTW_ENABLE_FUNC +#endif + +typedef enum _BEAMFORMING_ENTRY_STATE { + BEAMFORMING_ENTRY_STATE_UNINITIALIZE, + BEAMFORMING_ENTRY_STATE_INITIALIZEING, + BEAMFORMING_ENTRY_STATE_INITIALIZED, + BEAMFORMING_ENTRY_STATE_PROGRESSING, + BEAMFORMING_ENTRY_STATE_PROGRESSED +} BEAMFORMING_ENTRY_STATE, *PBEAMFORMING_ENTRY_STATE; + + +typedef enum _BEAMFORMING_NOTIFY_STATE { + BEAMFORMING_NOTIFY_NONE, + BEAMFORMING_NOTIFY_ADD, + BEAMFORMING_NOTIFY_DELETE, + BEAMFORMEE_NOTIFY_ADD_SU, + BEAMFORMEE_NOTIFY_DELETE_SU, + BEAMFORMEE_NOTIFY_ADD_MU, + BEAMFORMEE_NOTIFY_DELETE_MU, + BEAMFORMING_NOTIFY_RESET +} BEAMFORMING_NOTIFY_STATE, *PBEAMFORMING_NOTIFY_STATE; + +typedef enum _BEAMFORMING_CAP { + BEAMFORMING_CAP_NONE = 0x0, + BEAMFORMER_CAP_HT_EXPLICIT = BIT1, + BEAMFORMEE_CAP_HT_EXPLICIT = BIT2, + BEAMFORMER_CAP_VHT_SU = BIT5, /* Self has er Cap, because Reg er & peer ee */ + BEAMFORMEE_CAP_VHT_SU = BIT6, /* Self has ee Cap, because Reg ee & peer er */ + BEAMFORMER_CAP_VHT_MU = BIT7, /* Self has er Cap, because Reg er & peer ee */ + BEAMFORMEE_CAP_VHT_MU = BIT8, /* Self has ee Cap, because Reg ee & peer er */ + BEAMFORMER_CAP = BIT9, + BEAMFORMEE_CAP = BIT10, +}BEAMFORMING_CAP, *PBEAMFORMING_CAP; + + +typedef enum _SOUNDING_MODE { + SOUNDING_SW_VHT_TIMER = 0x0, + SOUNDING_SW_HT_TIMER = 0x1, + SOUNDING_STOP_All_TIMER = 0x2, + SOUNDING_HW_VHT_TIMER = 0x3, + SOUNDING_HW_HT_TIMER = 0x4, + SOUNDING_STOP_OID_TIMER = 0x5, + SOUNDING_AUTO_VHT_TIMER = 0x6, + SOUNDING_AUTO_HT_TIMER = 0x7, + SOUNDING_FW_VHT_TIMER = 0x8, + SOUNDING_FW_HT_TIMER = 0x9, +}SOUNDING_MODE, *PSOUNDING_MODE; + +typedef struct _RT_BEAMFORM_STAINFO { + pu1Byte RA; + u2Byte AID; + u2Byte MacID; + u1Byte MyMacAddr[6]; + WIRELESS_MODE WirelessMode; + CHANNEL_WIDTH BW; + BEAMFORMING_CAP BeamformCap; + u1Byte HtBeamformCap; + u2Byte VhtBeamformCap; + u1Byte CurBeamform; + u2Byte CurBeamformVHT; +} RT_BEAMFORM_STAINFO, *PRT_BEAMFORM_STAINFO; + + +typedef struct _RT_BEAMFORMEE_ENTRY { + BOOLEAN bUsed; + BOOLEAN bTxBF; + BOOLEAN bSound; + u2Byte AID; /*Used to construct AID field of NDPA packet.*/ + u2Byte MacId; /*Used to Set Reg42C in IBSS mode. */ + u2Byte P_AID; /*Used to fill Reg42C & Reg714 to compare with P_AID of Tx DESC. */ + u2Byte G_ID; /*Used to fill Tx DESC*/ + u1Byte MyMacAddr[6]; + u1Byte MacAddr[6]; /*Used to fill Reg6E4 to fill Mac address of CSI report frame.*/ + CHANNEL_WIDTH SoundBW; /*Sounding BandWidth*/ + u2Byte SoundPeriod; + BEAMFORMING_CAP BeamformEntryCap; + BEAMFORMING_ENTRY_STATE BeamformEntryState; + BOOLEAN bBeamformingInProgress; + /*u1Byte LogSeq; // Move to _RT_BEAMFORMER_ENTRY*/ + /*u2Byte LogRetryCnt:3; // 0~4 // Move to _RT_BEAMFORMER_ENTRY*/ + /*u2Byte LogSuccessCnt:2; // 0~2 // Move to _RT_BEAMFORMER_ENTRY*/ + u2Byte LogStatusFailCnt:5; // 0~21 + u2Byte DefaultCSICnt:5; // 0~21 + u1Byte CSIMatrix[327]; + u2Byte CSIMatrixLen; + u1Byte NumofSoundingDim; + u1Byte CompSteeringNumofBFer; + u1Byte su_reg_index; + /*For MU-MIMO*/ + BOOLEAN is_mu_sta; + u1Byte mu_reg_index; + u1Byte gid_valid[8]; + u1Byte user_position[16]; +} RT_BEAMFORMEE_ENTRY, *PRT_BEAMFORMEE_ENTRY; + +typedef struct _RT_BEAMFORMER_ENTRY { + BOOLEAN bUsed; + /*P_AID of BFer entry is probably not used*/ + u2Byte P_AID; /*Used to fill Reg42C & Reg714 to compare with P_AID of Tx DESC. */ + u2Byte G_ID; + u1Byte MyMacAddr[6]; + u1Byte MacAddr[6]; + BEAMFORMING_CAP BeamformEntryCap; + u1Byte NumofSoundingDim; + u1Byte ClockResetTimes; /*Modified by Jeffery @2015-04-10*/ + u1Byte PreLogSeq; /*Modified by Jeffery @2015-03-30*/ + u1Byte LogSeq; /*Modified by Jeffery @2014-10-29*/ + u2Byte LogRetryCnt:3; /*Modified by Jeffery @2014-10-29*/ + u2Byte LogSuccess:2; /*Modified by Jeffery @2014-10-29*/ + u1Byte su_reg_index; + /*For MU-MIMO*/ + BOOLEAN is_mu_ap; + u1Byte gid_valid[8]; + u1Byte user_position[16]; + u2Byte AID; +} RT_BEAMFORMER_ENTRY, *PRT_BEAMFORMER_ENTRY; + +typedef struct _RT_SOUNDING_INFO { + u1Byte SoundIdx; + CHANNEL_WIDTH SoundBW; + SOUNDING_MODE SoundMode; + u2Byte SoundPeriod; +} RT_SOUNDING_INFO, *PRT_SOUNDING_INFO; + + + +typedef struct _RT_BEAMFORMING_OID_INFO { + u1Byte SoundOidIdx; + CHANNEL_WIDTH SoundOidBW; + SOUNDING_MODE SoundOidMode; + u2Byte SoundOidPeriod; +} RT_BEAMFORMING_OID_INFO, *PRT_BEAMFORMING_OID_INFO; + + +typedef struct _RT_BEAMFORMING_INFO { + BEAMFORMING_CAP BeamformCap; + RT_BEAMFORMEE_ENTRY BeamformeeEntry[BEAMFORMEE_ENTRY_NUM]; + RT_BEAMFORMER_ENTRY BeamformerEntry[BEAMFORMER_ENTRY_NUM]; + RT_BEAMFORM_STAINFO BeamformSTAinfo; + u1Byte BeamformeeCurIdx; + RT_TIMER BeamformingTimer; + RT_TIMER mu_timer; + RT_SOUNDING_INFO SoundingInfo; + RT_BEAMFORMING_OID_INFO BeamformingOidInfo; + HAL_TXBF_INFO TxbfInfo; + u1Byte SoundingSequence; + u1Byte beamformee_su_cnt; + u1Byte beamformer_su_cnt; + u4Byte beamformee_su_reg_maping; + u4Byte beamformer_su_reg_maping; + /*For MU-MINO*/ + u1Byte beamformee_mu_cnt; + u1Byte beamformer_mu_cnt; + u4Byte beamformee_mu_reg_maping; + u1Byte mu_ap_index; + BOOLEAN is_mu_sounding; + u1Byte FirstMUBFeeIndex; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER SourceAdapter; +#endif + /* Control register */ + u4Byte RegMUTxCtrl; /* For USB/SDIO interfaces aync I/O */ +} RT_BEAMFORMING_INFO, *PRT_BEAMFORMING_INFO; + + +typedef struct _RT_NDPA_STA_INFO { + u2Byte AID:12; + u2Byte FeedbackType:1; + u2Byte NcIndex:3; +} RT_NDPA_STA_INFO, *PRT_NDPA_STA_INFO; + + +BEAMFORMING_CAP +phydm_Beamforming_GetEntryBeamCapByMacId( + IN PVOID pDM_VOID, + IN u1Byte MacId + ); + +PRT_BEAMFORMEE_ENTRY +phydm_Beamforming_GetBFeeEntryByAddr( + IN PVOID pDM_VOID, + IN pu1Byte RA, + OUT pu1Byte Idx + ); + +PRT_BEAMFORMER_ENTRY +phydm_Beamforming_GetBFerEntryByAddr( + IN PVOID pDM_VOID, + IN pu1Byte TA, + OUT pu1Byte Idx + ); + +u1Byte +Beamforming_GetHTNDPTxRate( + IN PVOID pDM_VOID, + u1Byte CompSteeringNumofBFer +); + +u1Byte +Beamforming_GetVHTNDPTxRate( + IN PVOID pDM_VOID, + u1Byte CompSteeringNumofBFer +); + +VOID +phydm_Beamforming_Notify( + IN PVOID pDM_VOID + ); + + +VOID +Beamforming_Enter( + IN PVOID pDM_VOID, + IN u2Byte staIdx + ); + +VOID +Beamforming_Leave( + IN PVOID pDM_VOID, + pu1Byte RA + ); + +BOOLEAN +BeamformingStart_FW( + IN PVOID pDM_VOID, + u1Byte Idx + ); + +VOID +Beamforming_CheckSoundingSuccess( + IN PVOID pDM_VOID, + BOOLEAN Status +); + +VOID +phydm_Beamforming_End_SW( + IN PVOID pDM_VOID, + BOOLEAN Status + ); + +VOID +Beamforming_TimerCallback( + IN PVOID pDM_VOID + ); + +VOID +phydm_Beamforming_Init( + IN PVOID pDM_VOID + ); + + + +BEAMFORMING_CAP +phydm_Beamforming_GetBeamCap( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamInfo + ); + + +BOOLEAN +BeamformingControl_V1( + IN PVOID pDM_VOID, + pu1Byte RA, + u1Byte AID, + u1Byte Mode, + CHANNEL_WIDTH BW, + u1Byte Rate + ); + + +BOOLEAN +phydm_BeamformingControl_V2( + IN PVOID pDM_VOID, + u1Byte Idx, + u1Byte Mode, + CHANNEL_WIDTH BW, + u2Byte Period + ); + +VOID +phydm_Beamforming_Watchdog( + IN PVOID pDM_VOID + ); + +VOID +Beamforming_SWTimerCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PRT_TIMER pTimer +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + void *FunctionContext +#endif + ); + +BOOLEAN +Beamforming_SendHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW, + IN u1Byte QIdx + ); + + +BOOLEAN +Beamforming_SendVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW, + IN u1Byte QIdx + ); + +#else +#define Beamforming_GidPAid(Adapter, pTcb) +#define Beamforming_Enter(pDM_Odm, staIdx) +#define Beamforming_Leave(pDM_Odm, RA) +#define Beamforming_End_FW(pDMOdm) +#define BeamformingControl_V1(pDM_Odm, RA, AID, Mode, BW, Rate) TRUE +#define BeamformingControl_V2(pDM_Odm, Idx, Mode, BW, Period) TRUE +#define phydm_Beamforming_End_SW(pDM_Odm, _Status) +#define Beamforming_TimerCallback(pDM_Odm) +#define phydm_Beamforming_Init(pDM_Odm) +#define phydm_BeamformingControl_V2(pDM_Odm, _Idx, _Mode, _BW, _Period) FALSE +#define Beamforming_Watchdog(pDM_Odm) +#define phydm_Beamforming_Watchdog(pDM_Odm) + + +#endif +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.c new file mode 100644 index 00000000..64e29656 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.c @@ -0,0 +1,347 @@ +/****************************************************************************** + * + * 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 +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + 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_RTL8188E | ODM_RTL8188F)) { + /* 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_RTL8703B|ODM_RTL8723B|ODM_RTL8192E|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 if (pDM_Odm->SupportICType & ODM_RTL8822B) { + /* write 0x24[30:25] = 0x28[6:1] = 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 { + 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)); +#endif +} + +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); + + pCfoTrack->DefXCap = odm_GetDefaultCrytaltalCap(pDM_Odm); + pCfoTrack->bAdjust = TRUE; + + if(pCfoTrack->CrystalCap > pCfoTrack->DefXCap) + { + odm_SetCrystalCap(pDM_Odm, pCfoTrack->CrystalCap - 1); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, + ("ODM_CfoTrackingReset(): approch default value (0x%x)\n", pCfoTrack->CrystalCap)); + } else if (pCfoTrack->CrystalCap < pCfoTrack->DefXCap) + { + odm_SetCrystalCap(pDM_Odm, pCfoTrack->CrystalCap + 1); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CFO_TRACKING, ODM_DBG_LOUD, + ("ODM_CfoTrackingReset(): approch default value (0x%x)\n", pCfoTrack->CrystalCap)); + } + + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + odm_SetATCStatus(pDM_Odm, TRUE); + #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) / 10)>>7; /* CFO_tail[1:0] is S(8,7), (num_subcarrier>>7) x 312.5K = CFO value(K Hz) */ + CFO_kHz_B = (int)((pCfoTrack->CFO_tail[1] * 3125) / 10)>>7; + + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_cfotracking.h new file mode 100644 index 00000000..b1cc4877 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/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.2" /*2015.06.17*/ + +#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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.c new file mode 100644 index 00000000..acbb01cb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.c @@ -0,0 +1,2005 @@ +/****************************************************************************** + * + * 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 | +// PHYDM_COMP_RA_DBG | +/* PHYDM_COMP_TXBF |*/ +//MAC Functions +// ODM_COMP_EDCA_TURBO | +// ODM_COMP_EARLY_MODE | +/* ODM_FW_DEBUG_TRACE |*/ +//RF Functions +// ODM_COMP_TX_PWR_TRACK | +// ODM_COMP_RX_GAIN_TRACK | +// ODM_COMP_CALIBRATION | +//Common +/* ODM_PHY_CONFIG |*/ +// ODM_COMP_COMMON | +// ODM_COMP_INIT | +// ODM_COMP_PSD | +/* ODM_COMP_NOISY_DETECT |*/ +#endif + 0; + + pDM_Odm->fw_buff_is_enpty = TRUE; + pDM_Odm->pre_c2h_seq = 0; +} + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +static u1Byte BbDbgBuf[BB_TMP_BUF_SIZE]; + +VOID +phydm_BB_RxHang_Info(IN PDM_ODM_T pDM_Odm) +{ + u4Byte value32 = 0; + + + if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) + return; + + value32 = ODM_GetBBReg(pDM_Odm, 0xF80 , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rptreg of sc/bw/ht/...", value32); + DCMD_Printf(BbDbgBuf); + + /* dbg_port = state machine */ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x007); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "state machine", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = CCA-related*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x204); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "CCA-related", (value32)); + DCMD_Printf(BbDbgBuf); + } + + + /* dbg_port = edcca/rxd*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x278); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "edcca/rxd", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = rx_state/mux_state/ADC_MASK_OFDM*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x290); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rx_state/mux_state/ADC_MASK_OFDM", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = bf-related*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x2B2); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "bf-related", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = bf-related*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0x2B8); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "bf-related", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = txon/rxd*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xA03); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "txon/rxd", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = l_rate/l_length*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xA0B); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "l_rate/l_length", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = rxd/rxd_hit*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xA0D); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rxd/rxd_hit", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = dis_cca*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAA0); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "dis_cca", (value32)); + DCMD_Printf(BbDbgBuf); + } + + + /* dbg_port = tx*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAB0); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "tx", (value32)); + DCMD_Printf(BbDbgBuf); + } + + /* dbg_port = rx plcp*/ + { + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAD0); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rx plcp", (value32)); + DCMD_Printf(BbDbgBuf); + + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAD1); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rx plcp", (value32)); + DCMD_Printf(BbDbgBuf); + + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAD2); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rx plcp", (value32)); + DCMD_Printf(BbDbgBuf); + + ODM_SetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord, 0xAD3); + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_DBG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x8fc", value32); + DCMD_Printf(BbDbgBuf); + + value32 = ODM_GetBBReg(pDM_Odm, ODM_REG_RPT_11AC , bMaskDWord); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "rx plcp", (value32)); + DCMD_Printf(BbDbgBuf); + } + +} + +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[3] = {"legacy", "HT", "VHT"}; + const char *BW_table[3] = {"20M", "40M", "80M"}; + const char *RXSC_table[7] = {"duplicate/full bw", "usc20-1", "lsc20-1", "usc20-2", "lsc20-2", "usc40", "lsc40"}; + + const char *L_rate[8] = {"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((char *)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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "F80", value32_2); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_HT_BW", RX_HT_BW); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_VHT_BW", RX_VHT_BW); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_SC", RXSC); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "RX_HT", RX_HT); + DCMD_Printf(BbDbgBuf); + */ + + /*rsprintf((char *)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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: VHT Mode"); + DCMD_Printf(BbDbgBuf); + if (RX_VHT_BW == 0) { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW=20M"); + DCMD_Printf(BbDbgBuf); + } else if (RX_VHT_BW == 1) { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW=40M"); + DCMD_Printf(BbDbgBuf); + } else { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW=80M"); + DCMD_Printf(BbDbgBuf); + } + RX_BW = RX_VHT_BW; + } else if (RX_HT == 1) { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: HT Mode"); + DCMD_Printf(BbDbgBuf); + if (RX_HT_BW == 0) { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW=20M"); + DCMD_Printf(BbDbgBuf); + } else if (RX_HT_BW == 1) { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW=40M"); + DCMD_Printf(BbDbgBuf); + } + RX_BW = RX_HT_BW; + } else { + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Mode: Legeacy Mode"); + DCMD_Printf(BbDbgBuf); + } + + if (RX_HT != 0) { + if (RXSC == 0) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n duplicate/full bw"); + else if (RXSC == 1) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc20-1"); + else if (RXSC == 2) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc20-1"); + else if (RXSC == 3) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc20-2"); + else if (RXSC == 4) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc20-2"); + else if (RXSC == 9) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n usc40"); + else if (RXSC == 10) + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n lsc40"); + DCMD_Printf(BbDbgBuf); + } + /* + if(RX_HT == 2){ + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW:%s", BW_table[RX_VHT_BW]); + RX_BW = RX_VHT_BW; + } + else if(RX_HT == 1){ + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " BW:%s", BW_table[RX_HT_BW]); + RX_BW = RX_HT_BW; + } + else + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, ""); + + DCMD_Printf(BbDbgBuf); + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, " RXSC:%s", RXSC_table[RXSC]); + DCMD_Printf(BbDbgBuf); + */ + + +/* rsprintf((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "CFO Report Info"); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)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((char *)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((char *)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((char *)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((char *)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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "L-SIG"); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n Rate:%s", L_rate[idx]); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x/ %x /%x", " Rsv/Length/Parity", rsv, RX_BW, Length); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x / %x/ %x", " MCS/BW/Length", HMCSS, HRX_BW, HLength); + DCMD_Printf(BbDbgBuf); + + rsprintf((char *)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((char *)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((char *)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((char *)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);*/ + 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((char *)BbDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %x", "F2C", value32);*/ + /*DCMD_Printf(BbDbgBuf);*/ + + rsprintf((char *)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((char *)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((char *)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((char *)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((char *)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_sbd_check( + IN PDM_ODM_T pDM_Odm +) +{ + static u4Byte pkt_cnt = 0; + static BOOLEAN sbd_state = 0; + u4Byte sym_count, count, value32; + + if (sbd_state == 0) { + pkt_cnt++; + if (pkt_cnt % 5 == 0) { /*read SBD conter once every 5 packets*/ + ODM_SetTimer(pDM_Odm, &pDM_Odm->sbdcnt_timer, 0); /*ms*/ + sbd_state = 1; + } + } else { /*read counter*/ + value32 = ODM_GetBBReg(pDM_Odm, 0xF98, bMaskDWord); + sym_count = (value32 & 0x7C000000) >> 26; + count = (value32 & 0x3F00000) >> 20; + DbgPrint("#SBD# sym_count %d count %d\n", sym_count, count); + sbd_state = 0; + } +} + +void phydm_sbd_callback( + 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 USE_WORKITEM + ODM_ScheduleWorkItem(&pDM_Odm->sbdcnt_workitem); +#else + phydm_sbd_check(pDM_Odm); +#endif +} + +void phydm_sbd_workitem_callback( + IN PVOID pContext +) +{ + PADAPTER pAdapter = (PADAPTER)pContext; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + phydm_sbd_check(pDM_Odm); +} +#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; + u1Byte legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; + u1Byte vht_en = ((pDM_Odm->RxRate) >= ODM_RATEVHTSS1MCS0) ? 1 : 0; + + if (pDM_Odm->RxRate <= ODM_RATE11M) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[CCK AGC Report] LNA_idx = 0x%x, VGA_idx = 0x%x\n", + pDM_Odm->cck_lna_idx, pDM_Odm->cck_vga_idx)); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[OFDM AGC Report] { 0x%x, 0x%x, 0x%x, 0x%x }\n", + pDM_Odm->ofdm_agc_idx[0], pDM_Odm->ofdm_agc_idx[1], pDM_Odm->ofdm_agc_idx[2], pDM_Odm->ofdm_agc_idx[3])); + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI: { %d, %d, %d, %d }, RxRate: { %s%s%s%s%d%s}\n", + (pDM_Odm->RSSI_A == 0xff) ? 0 : pDM_Odm->RSSI_A , + (pDM_Odm->RSSI_B == 0xff) ? 0 : pDM_Odm->RSSI_B , + (pDM_Odm->RSSI_C == 0xff) ? 0 : pDM_Odm->RSSI_C, + (pDM_Odm->RSSI_D == 0xff) ? 0 : pDM_Odm->RSSI_D, + ((pDM_Odm->RxRate >= ODM_RATEVHTSS1MCS0) && (pDM_Odm->RxRate <= ODM_RATEVHTSS1MCS9)) ? "VHT 1ss " : "", + ((pDM_Odm->RxRate >= ODM_RATEVHTSS2MCS0) && (pDM_Odm->RxRate <= ODM_RATEVHTSS2MCS9)) ? "VHT 2ss " : "", + ((pDM_Odm->RxRate >= ODM_RATEVHTSS3MCS0) && (pDM_Odm->RxRate <= ODM_RATEVHTSS3MCS9)) ? "VHT 3ss " : "", + (pDM_Odm->RxRate >= ODM_RATEMCS0) ? "MCS " : "", + (vht_en) ? ((pDM_Odm->RxRate - ODM_RATEVHTSS1MCS0)%10) : ((pDM_Odm->RxRate >= ODM_RATEMCS0) ? (pDM_Odm->RxRate - ODM_RATEMCS0) : ((pDM_Odm->RxRate <= ODM_RATE54M)?legacy_table[pDM_Odm->RxRate]:0)), + (pDM_Odm->RxRate >= ODM_RATEMCS0) ? "" : "M")); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + FalseAlmCnt->Cnt_CCK_CCA, FalseAlmCnt->Cnt_OFDM_CCA, FalseAlmCnt->Cnt_CCA_all)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n", + 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)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked = %d, RSSI_Min = %d, CurrentIGI = 0x%x, bNoisy=%d\n\n", + pDM_Odm->bLinked, pDM_Odm->RSSI_Min, pDM_DigTable->CurIGValue, pDM_Odm->NoisyDecision)); +/* + temp_reg = ODM_GetBBReg(pDM_Odm, 0xDD0, bMaskByte0); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("0xDD0 = 0x%x\n",temp_reg)); + + temp_reg = ODM_GetBBReg(pDM_Odm, 0xDDc, bMaskByte1); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("0xDDD = 0x%x\n",temp_reg)); + + temp_reg = ODM_GetBBReg(pDM_Odm, 0xc50, bMaskByte0); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("0xC50 = 0x%x\n",temp_reg)); + + temp_reg = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x0, 0x3fe0); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, ("RF 0x0[13:5] = 0x%x\n\n",temp_reg)); +*/ + +#endif +} + + +VOID phydm_BasicProfile( + IN PVOID pDM_VOID, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + char *Cut = NULL; + char *ICType = NULL; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + u4Byte commit_ver = 0; + u4Byte date = 0; + char *commit_by = NULL; + u4Byte release_ver = 0; + + PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "% Basic Profile %")); + + 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"; +#if (RTL8703B_SUPPORT == 1) + else if (pDM_Odm->SupportICType == ODM_RTL8703B) { + ICType = "RTL8703B"; + date = RELEASE_DATE_8703B; + commit_by = COMMIT_BY_8703B; + release_ver = RELEASE_VERSION_8703B; + } +#endif + else if (pDM_Odm->SupportICType == ODM_RTL8195A) + ICType = "RTL8195A"; + else if (pDM_Odm->SupportICType == ODM_RTL8188F) + ICType = "RTL8188F"; + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s (MP Chip: %s)\n", "IC Type", ICType, pDM_Odm->bIsMPChip ? "Yes" : "No")); + + 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"; + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Cut Version", Cut)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter Version", ODM_GetHWImgVersion(pDM_Odm))); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter Commit date", date)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "PHY Parameter Commit by", commit_by)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d\n", "PHY Parameter Release Version", release_ver)); + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + { + PADAPTER Adapter = pDM_Odm->Adapter; + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d (Subversion: %d)\n", "FW Version", Adapter->MgntInfo.FirmwareVersion, Adapter->MgntInfo.FirmwareSubVersion)); + } +#elif (DM_ODM_SUPPORT_TYPE & ODM_AP) + { + struct rtl8192cd_priv *priv = pDM_Odm->priv; + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d (Subversion: %d)\n", "FW Version", priv->pshare->fw_version, priv->pshare->fw_sub_version)); + } +#else + { + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %d (Subversion: %d)\n", "FW Version", pHalData->FirmwareVersion, pHalData->FirmwareSubVersion)); + } +#endif + //1 PHY DM Version List + PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "% PHYDM Version %")); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Adaptivity", ADAPTIVITY_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "DIG", DIG_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "CFO Tracking", CFO_TRACKING_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Antenna Diversity", ANTDIV_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Power Tracking", POWRTRACKING_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Dynamic TxPower", DYNAMIC_TXPWR_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "RA Info", RAINFO_VERSION)); +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Antenna Detection", ANTDECT_VERSION)); +#endif + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Auto Channel Selection", ACS_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "EDCA Turbo", EDCATURBO_VERSION)); + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "Path Diversity", PATHDIV_VERSION)); +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "RxHP", RXHP_VERSION)); +#endif +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8822B) + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s: %s\n", "PHY config 8822B", PHY_CONFIG_VERSION_8822B)); + +#endif + *_used = used; + *_out_len = out_len; + +} + +VOID +phydm_fw_trace_en_h2c( + IN PVOID pDM_VOID, + IN BOOLEAN enable, + IN u4Byte monitor_mode, + IN u4Byte macid +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte H2C_Parameter[3] = {0}; + + H2C_Parameter[0] = enable; + H2C_Parameter[1] = (u1Byte)monitor_mode; + H2C_Parameter[2] = (u1Byte)macid; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("---->\n")); + if (monitor_mode == 0){ + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[H2C] FW_debug_en: (( %d ))\n", enable)); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[H2C] FW_debug_en: (( %d )), mode: (( %d )), macid: (( %d ))\n", enable, monitor_mode, macid)); + } + ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_FW_TRACE_EN, 3, H2C_Parameter); +} + +VOID +phydm_get_per_path_txagc( + IN PVOID pDM_VOID, + IN u1Byte path, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte rate_idx; + u1Byte txagc; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + +#if (RTL8822B_SUPPORT == 1) + if ((pDM_Odm->SupportICType & ODM_RTL8822B) && (path <= ODM_RF_PATH_B)) { + for (rate_idx = 0; rate_idx <= 0x53; rate_idx++) { + if (rate_idx == ODM_RATE1M) + PHYDM_SNPRINTF((output + used, out_len - used, " %-35s\n", "CCK====>")); + else if (rate_idx == ODM_RATE6M) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "OFDM====>")); + else if (rate_idx == ODM_RATEMCS0) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "HT 1ss====>")); + else if (rate_idx == ODM_RATEMCS8) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "HT 2ss====>")); + else if (rate_idx == ODM_RATEMCS16) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "HT 3ss====>")); + else if (rate_idx == ODM_RATEMCS24) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "HT 4ss====>")); + else if (rate_idx == ODM_RATEVHTSS1MCS0) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "VHT 1ss====>")); + else if (rate_idx == ODM_RATEVHTSS2MCS0) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "VHT 2ss====>")); + else if (rate_idx == ODM_RATEVHTSS3MCS0) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "VHT 3ss====>")); + else if (rate_idx == ODM_RATEVHTSS4MCS0) + PHYDM_SNPRINTF((output + used, out_len - used, "\n %-35s\n", "VHT 4ss====>")); + + txagc = config_phydm_read_txagc_8822b(pDM_Odm, path, rate_idx); + if (config_phydm_read_txagc_check_8822b(txagc)) + PHYDM_SNPRINTF((output + used, out_len - used, " 0x%02x ", txagc)); + else + PHYDM_SNPRINTF((output + used, out_len - used, " 0x%s ", "xx")); + } + } +#endif +} + + +VOID +phydm_get_txagc( + IN PVOID pDM_VOID, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + + /* Path-A */ + PHYDM_SNPRINTF((output + used, out_len - used, "%-35s\n", "Path-A====================")); + phydm_get_per_path_txagc(pDM_Odm, ODM_RF_PATH_A, _used, output, _out_len); + + /* Path-B */ + PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "Path-B====================")); + phydm_get_per_path_txagc(pDM_Odm, ODM_RF_PATH_B, _used, output, _out_len); + + /* Path-C */ + PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "Path-C====================")); + phydm_get_per_path_txagc(pDM_Odm, ODM_RF_PATH_C, _used, output, _out_len); + + /* Path-D */ + PHYDM_SNPRINTF((output + used, out_len - used, "\n%-35s\n", "Path-D====================")); + phydm_get_per_path_txagc(pDM_Odm, ODM_RF_PATH_D, _used, output, _out_len); + +} + +VOID +phydm_set_txagc( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8822B) { + if (dm_value[0] <= 1) { + if (phydm_write_txagc_1byte_8822b(pDM_Odm, dm_value[2], dm_value[0], (u1Byte)dm_value[1])) + PHYDM_SNPRINTF((output + used, out_len - used, " %s%d %s%x%s%x\n", "Write path-", dm_value[0], "rate index-0x", dm_value[1], " = 0x", dm_value[2])); + else + PHYDM_SNPRINTF((output + used, out_len - used, " %s%d %s%x%s\n", "Write path-", (dm_value[0] & 0x1), "rate index-0x", (dm_value[1] & 0x7f), " fail")); + } else { + PHYDM_SNPRINTF((output + used, out_len - used, " %s%d %s%x%s\n", "Write path-", (dm_value[0] & 0x1), "rate index-0x", (dm_value[1] & 0x7f), " fail")); + } + } +#endif +} + +VOID +odm_debug_trace( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u8Byte pre_debug_components, one = 1; + u4Byte used = *_used; + u4Byte out_len = *_out_len; + + pre_debug_components = pDM_Odm->DebugComponents; + + PHYDM_SNPRINTF((output + used, out_len - used, "\n%s\n", "================================")); + if (dm_value[0] == 100) { + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Debug Message] PhyDM Selection")); + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================")); + PHYDM_SNPRINTF((output + used, out_len - used, "00. (( %s ))DIG\n", ((pDM_Odm->DebugComponents & ODM_COMP_DIG) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "01. (( %s ))RA_MASK\n", ((pDM_Odm->DebugComponents & ODM_COMP_RA_MASK) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "02. (( %s ))DYNAMIC_TXPWR\n", ((pDM_Odm->DebugComponents & ODM_COMP_DYNAMIC_TXPWR) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "03. (( %s ))FA_CNT\n", ((pDM_Odm->DebugComponents & ODM_COMP_FA_CNT) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "04. (( %s ))RSSI_MONITOR\n", ((pDM_Odm->DebugComponents & ODM_COMP_RSSI_MONITOR) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "05. (( %s ))CCK_PD\n", ((pDM_Odm->DebugComponents & ODM_COMP_CCK_PD) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "06. (( %s ))ANT_DIV\n", ((pDM_Odm->DebugComponents & ODM_COMP_ANT_DIV) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "07. (( %s ))PWR_SAVE\n", ((pDM_Odm->DebugComponents & ODM_COMP_PWR_SAVE) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "08. (( %s ))PWR_TRAIN\n", ((pDM_Odm->DebugComponents & ODM_COMP_PWR_TRAIN) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "09. (( %s ))RATE_ADAPTIVE\n", ((pDM_Odm->DebugComponents & ODM_COMP_RATE_ADAPTIVE) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "10. (( %s ))PATH_DIV\n", ((pDM_Odm->DebugComponents & ODM_COMP_PATH_DIV) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "11. (( %s ))PSD\n", ((pDM_Odm->DebugComponents & ODM_COMP_PSD) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "12. (( %s ))DYNAMIC_PRICCA\n", ((pDM_Odm->DebugComponents & ODM_COMP_DYNAMIC_PRICCA) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "13. (( %s ))RXHP\n", ((pDM_Odm->DebugComponents & ODM_COMP_RXHP) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "14. (( %s ))MP\n", ((pDM_Odm->DebugComponents & ODM_COMP_MP) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "15. (( %s ))CFO_TRACKING\n", ((pDM_Odm->DebugComponents & ODM_COMP_CFO_TRACKING) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "16. (( %s ))ACS\n", ((pDM_Odm->DebugComponents & ODM_COMP_ACS) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "17. (( %s ))ADAPTIVITY\n", ((pDM_Odm->DebugComponents & PHYDM_COMP_ADAPTIVITY) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "18. (( %s ))RA_DBG\n", ((pDM_Odm->DebugComponents & PHYDM_COMP_RA_DBG) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "20. (( %s ))EDCA_TURBO\n", ((pDM_Odm->DebugComponents & ODM_COMP_EDCA_TURBO) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "21. (( %s ))EARLY_MODE\n", ((pDM_Odm->DebugComponents & ODM_COMP_EARLY_MODE) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "22. (( %s ))FW_DEBUG_TRACE\n", ((pDM_Odm->DebugComponents & ODM_FW_DEBUG_TRACE) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "24. (( %s ))TX_PWR_TRACK\n", ((pDM_Odm->DebugComponents & ODM_COMP_TX_PWR_TRACK) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "25. (( %s ))RX_GAIN_TRACK\n", ((pDM_Odm->DebugComponents & ODM_COMP_RX_GAIN_TRACK) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "26. (( %s ))CALIBRATION\n", ((pDM_Odm->DebugComponents & ODM_COMP_CALIBRATION) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "28. (( %s ))PHY_CONFIG\n", ((pDM_Odm->DebugComponents & ODM_PHY_CONFIG) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "29. (( %s ))BEAMFORMING_DEBUG\n", ((pDM_Odm->DebugComponents & BEAMFORMING_DEBUG) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "30. (( %s ))COMMON\n", ((pDM_Odm->DebugComponents & ODM_COMP_COMMON) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "31. (( %s ))INIT\n", ((pDM_Odm->DebugComponents & ODM_COMP_INIT) ? ("V") : (".")))); + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================")); + + } else if (dm_value[0] == 101) { + pDM_Odm->DebugComponents = 0; + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Disable all debug components")); + } else { + if (dm_value[1] == 1) { /*enable*/ + pDM_Odm->DebugComponents |= (one << dm_value[0]); + + if (dm_value[0] == 22) { /*FW trace function*/ + phydm_fw_trace_en_h2c(pDM_Odm, 1, dm_value[2], dm_value[3]); /*H2C to enable C2H Msg*/ + } + } else if (dm_value[1] == 2) { /*disable*/ + pDM_Odm->DebugComponents &= ~(one << dm_value[0]); + + if (dm_value[0] == 22) { /*FW trace function*/ + phydm_fw_trace_en_h2c(pDM_Odm, 0, dm_value[2], dm_value[3]); /*H2C to disable C2H Msg*/ + } + } else + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "[Warning!!!] 1:enable, 2:disable")); + } + PHYDM_SNPRINTF((output + used, out_len - used, "pre-DbgComponents = 0x%x\n", (u4Byte)pre_debug_components)); + PHYDM_SNPRINTF((output + used, out_len - used, "Curr-DbgComponents = 0x%x\n", ((u4Byte)pDM_Odm->DebugComponents))); + PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "================================")); +} + +VOID +phydm_DumpBbReg( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte Addr = 0; + + /* BB Reg */ + for (Addr = 0x800; Addr < 0xfff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + + if (pDM_Odm->SupportICType & (ODM_RTL8822B|ODM_RTL8814A)) { + + if (pDM_Odm->RFType > ODM_2T2R) { + for (Addr = 0x1800; Addr < 0x18ff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + } + + if (pDM_Odm->RFType > ODM_3T3R) { + for (Addr = 0x1a00; Addr < 0x1aff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + } + + for (Addr = 0x1900; Addr < 0x19ff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + + for (Addr = 0x1c00; Addr < 0x1cff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + + for (Addr = 0x1f00; Addr < 0x1fff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + } +} + +VOID +phydm_DumpAllReg( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte Addr = 0; + + /* dump MAC register */ + DbgPrint("MAC==========\n"); + for (Addr = 0; Addr < 0x7ff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + + for (Addr = 1000; Addr < 0x17ff; Addr += 4) + DbgPrint("%04x %08x\n", Addr, ODM_GetBBReg(pDM_Odm, Addr, bMaskDWord)); + + /* dump BB register */ + DbgPrint("BB==========\n"); + phydm_DumpBbReg(pDM_Odm); + + /* dump RF register */ + DbgPrint("RF-A==========\n"); + for (Addr = 0; Addr < 0xFF; Addr++) + DbgPrint("%02x %05x\n", Addr, ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, Addr, bRFRegOffsetMask)); + + if (pDM_Odm->RFType > ODM_1T1R) { + DbgPrint("RF-B==========\n"); + for (Addr = 0; Addr < 0xFF; Addr++) + DbgPrint("%02x %05x\n", Addr, ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, Addr, bRFRegOffsetMask)); + } + + if (pDM_Odm->RFType > ODM_2T2R) { + DbgPrint("RF-C==========\n"); + for (Addr = 0; Addr < 0xFF; Addr++) + DbgPrint("%02x %05x\n", Addr, ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_C, Addr, bRFRegOffsetMask)); + } + + if (pDM_Odm->RFType > ODM_3T3R) { + DbgPrint("RF-D==========\n"); + for (Addr = 0; Addr < 0xFF; Addr++) + DbgPrint("%02x %05x\n", Addr, ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_D, Addr, bRFRegOffsetMask)); + } +} + +struct _PHYDM_COMMAND { + char name[16]; + u1Byte id; +}; + +enum PHYDM_CMD_ID { + PHYDM_DEMO, + PHYDM_RA, + PHYDM_PROFILE, + PHYDM_PATHDIV, + PHYDM_DEBUG, + PHYDM_SUPPORT_ABILITY, + PHYDM_GET_TXAGC, + PHYDM_SET_TXAGC, + PHYDM_SMART_ANT, + PHYDM_API, + PHYDM_TRX_PATH, + PHYDM_LA_MODE, + PHYDM_DUMP_REG +}; + +struct _PHYDM_COMMAND phy_dm_ary[] = { + {"demo", PHYDM_DEMO}, + {"ra", PHYDM_RA}, + {"profile", PHYDM_PROFILE}, + {"pathdiv", PHYDM_PATHDIV}, + {"dbg", PHYDM_DEBUG}, + {"ability", PHYDM_SUPPORT_ABILITY}, + {"get_txagc", PHYDM_GET_TXAGC}, + {"set_txagc", PHYDM_SET_TXAGC}, + {"smtant", PHYDM_SMART_ANT}, + {"api", PHYDM_API}, + {"trxpath", PHYDM_TRX_PATH}, + {"lamode", PHYDM_LA_MODE}, + {"dumpreg", PHYDM_DUMP_REG} +}; + +VOID +phydm_cmd_parser( + IN PDM_ODM_T pDM_Odm, + IN char input[][MAX_ARGV], + IN u4Byte input_num, + IN u1Byte flag, + OUT char *output, + IN u4Byte out_len +) +{ + u4Byte used = 0; + u1Byte id = 0; + int var1[5] = {0}; + int i, input_idx = 0; + + if (flag == 0) { + PHYDM_SNPRINTF((output + used, out_len - used, "GET, nothing to print\n")); + return; + } + + PHYDM_SNPRINTF((output + used, out_len - used, "\n")); + + //Parsing Cmd ID + if (input_num) { + 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, input[0]) == 0) { + id = phy_dm_ary[i].id; + break; + } + } + if (i == n) { + PHYDM_SNPRINTF((output + used, out_len - used, "SET, command not found!\n")); + return; + } + } + + switch (id) { + case PHYDM_DEMO: /*echo demo 10 0x3a z abcde >cmd*/ + { + u4Byte directory = 0; +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP)) + char char_temp; +#else + u4Byte char_temp = ' '; +#endif + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &directory); + PHYDM_SNPRINTF((output + used, out_len - used, "Decimal Value = %d\n", directory)); + PHYDM_SSCANF(input[2], DCMD_HEX, &directory); + PHYDM_SNPRINTF((output + used, out_len - used, "Hex Value = 0x%x\n", directory)); + PHYDM_SSCANF(input[3], DCMD_CHAR, &char_temp); + PHYDM_SNPRINTF((output + used, out_len - used, "Char = %c\n", char_temp)); + PHYDM_SNPRINTF((output + used, out_len - used, "String = %s\n", input[4])); + } + break; + + case PHYDM_RA: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + PHYDM_SNPRINTF((output + used, out_len - used, "new SET, RA_var[%d]= (( %d ))\n", i , var1[i])); + input_idx++; + } + } + + if (input_idx >= 1) { + /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_RA_debug\n"));*/ +#if (defined(CONFIG_RA_DBG_CMD)) + odm_RA_debug((PVOID)pDM_Odm, var1); +#endif + } + + + break; + + case PHYDM_PATHDIV: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + + /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, PATHDIV_var[%d]= (( %d ))\n", i , var1[i]));*/ + input_idx++; + } + } + + if (input_idx >= 1) { + /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_PATHDIV_debug\n"));*/ +#if (defined(CONFIG_PATH_DIVERSITY)) + odm_pathdiv_debug(pDM_Odm, (u4Byte *)var1, &used, output, &out_len); +#endif + } + + break; + + case PHYDM_DEBUG: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, Debug_var[%d]= (( %d ))\n", i , var1[i]));*/ + input_idx++; + } + } + + if (input_idx >= 1) { + /*PHYDM_SNPRINTF((output+used, out_len-used, "odm_debug_comp\n"));*/ + odm_debug_trace(pDM_Odm, (u4Byte *)var1, &used, output, &out_len); + } + + + break; + + case PHYDM_SUPPORT_ABILITY: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, support ablity_var[%d]= (( %d ))\n", i , var1[i]));*/ + input_idx++; + } + } + + if (input_idx >= 1) { + /*PHYDM_SNPRINTF((output+used, out_len-used, "support ablity\n"));*/ + phydm_support_ablity_debug(pDM_Odm, (u4Byte *)var1, &used, output, &out_len); + } + + break; + + case PHYDM_SMART_ANT: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + #ifdef CONFIG_HL_SMART_ANTENNA_TYPE1 + phydm_hl_smart_ant_cmd(pDM_Odm, (u4Byte *)var1, &used, output, &out_len); + #endif + #endif + } + + break; + + case PHYDM_API: +#if (RTL8822B_SUPPORT == 1) + { + if (pDM_Odm->SupportICType & ODM_RTL8822B) { + BOOLEAN bEnableDbgMode; + u1Byte central_ch, primary_ch_idx, bandwidth; + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + } + + bEnableDbgMode = (BOOLEAN)var1[0]; + central_ch = (u1Byte) var1[1]; + primary_ch_idx = (u1Byte) var1[2]; + bandwidth = (ODM_BW_E) var1[3]; + + if (bEnableDbgMode) { + pDM_Odm->bDisablePhyApi = FALSE; + config_phydm_switch_channel_bw_8822b(pDM_Odm, central_ch, primary_ch_idx, bandwidth); + pDM_Odm->bDisablePhyApi = TRUE; + PHYDM_SNPRINTF((output+used, out_len-used, "central_ch = %d, primary_ch_idx = %d, bandwidth = %d\n", central_ch, primary_ch_idx, bandwidth)); + } else { + pDM_Odm->bDisablePhyApi = FALSE; + PHYDM_SNPRINTF((output+used, out_len-used, "Disable API debug mode\n")); + } + } else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support PHYDM API function\n")); + } +#else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support PHYDM API function\n")); +#endif + break; + + case PHYDM_PROFILE: /*echo profile, >cmd*/ + phydm_BasicProfile(pDM_Odm, &used, output, &out_len); + break; + + case PHYDM_GET_TXAGC: + phydm_get_txagc(pDM_Odm, &used, output, &out_len); + break; + + case PHYDM_SET_TXAGC: + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + + /*PHYDM_SNPRINTF((output+used, out_len-used, "new SET, support ablity_var[%d]= (( %d ))\n", i , var1[i]));*/ + input_idx++; + } + } + + phydm_set_txagc(pDM_Odm, (u4Byte *)var1, &used, output, &out_len); + break; + + case PHYDM_TRX_PATH: +#if (RTL8822B_SUPPORT == 1) + { + if (pDM_Odm->SupportICType & ODM_RTL8822B) { + u1Byte TxPath, RxPath; + BOOLEAN bEnableDbgMode, bTx2Path; + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + } + + bEnableDbgMode = (BOOLEAN)var1[0]; + TxPath = (u1Byte) var1[1]; + RxPath = (u1Byte) var1[2]; + bTx2Path = (BOOLEAN) var1[3]; + + if (bEnableDbgMode) { + pDM_Odm->bDisablePhyApi = FALSE; + config_phydm_trx_mode_8822b(pDM_Odm, TxPath, RxPath, bTx2Path); + pDM_Odm->bDisablePhyApi = TRUE; + PHYDM_SNPRINTF((output+used, out_len-used, "TxPath = 0x%x, RxPath = 0x%x, bTx2Path = %d\n", TxPath, RxPath, bTx2Path)); + } else { + pDM_Odm->bDisablePhyApi = FALSE; + PHYDM_SNPRINTF((output+used, out_len-used, "Disable API debug mode\n")); + } + } else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support PHYDM API function\n")); + } +#else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support PHYDM API function\n")); +#endif + break; + + case PHYDM_LA_MODE: +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if ((RTL8822B_SUPPORT == 1) || (RTL8814A_SUPPORT == 1)) + { + if (pDM_Odm->SupportICType & (ODM_RTL8814A | ODM_RTL8822B)) { + u2Byte PollingTime; + u1Byte TrigSel, TrigSigSel, DmaDataSigSel, TriggerTime; + BOOLEAN bEnableLaMode; + + for (i = 0; i < 6; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &var1[i]); + } + + bEnableLaMode = (BOOLEAN)var1[0]; + if (bEnableLaMode) { + TrigSel = (u1Byte)var1[1]; + TrigSigSel = (u1Byte)var1[2]; + DmaDataSigSel = (u1Byte)var1[3]; + TriggerTime = (u1Byte)var1[4]; + PollingTime = (((u1Byte)var1[5]) << 6); + + ADCSmp_Set(pDM_Odm->Adapter, TrigSel, TrigSigSel, DmaDataSigSel, TriggerTime, PollingTime); + PHYDM_SNPRINTF((output+used, out_len-used, "TrigSel = %d, TrigSigSel = %d, DmaDataSigSel = %d\n", TrigSel, TrigSigSel, DmaDataSigSel)); + PHYDM_SNPRINTF((output+used, out_len-used, "TriggerTime = %d, PollingTime = %d\n", TriggerTime, PollingTime)); + } else { + ADCSmp_Stop(pDM_Odm->Adapter); + PHYDM_SNPRINTF((output+used, out_len-used, "Disable LA mode\n")); + } + } else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support LA mode\n")); + } +#else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support LA mode\n")); +#endif +#else + PHYDM_SNPRINTF((output+used, out_len-used, "This IC doesn't support LA mode\n")); +#endif + break; + + case PHYDM_DUMP_REG: + { + u1Byte type = 0; + + if (input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + type = (u1Byte)var1[0]; + } + + if (type == 0) + phydm_DumpBbReg(pDM_Odm); + else if (type == 1) + phydm_DumpAllReg(pDM_Odm); + } + break; + default: + PHYDM_SNPRINTF((output + used, out_len - used, "SET, unknown command!\n")); + break; + + } +} + +#ifdef __ECOS +char *strsep(char **s, const char *ct) +{ + char *sbegin = *s; + char *end; + + if (sbegin == NULL) + return NULL; + + end = strpbrk(sbegin, ct); + if (end) + *end++ = '\0'; + *s = end; + return sbegin; +} +#endif + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP)) +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 +) +{ + char *token; + u4Byte Argc = 0; + char Argv[MAX_ARGC][MAX_ARGV]; + + do { + token = strsep(&input, ", "); + if (token) { + strcpy(Argv[Argc], token); + Argc++; + } else + break; + } while (Argc < MAX_ARGC); + + if (Argc == 1) + Argv[0][strlen(Argv[0]) - 1] = '\0'; + + phydm_cmd_parser(pDM_Odm, Argv, Argc, flag, output, out_len); + + return 0; +} +#endif + + +VOID +phydm_fw_trace_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + /*u1Byte debug_trace_11byte[60];*/ + u1Byte freg_num, c2h_seq, buf_0 = 0; + + if (CmdLen > 12) + return; + + buf_0 = CmdBuf[0]; + freg_num = (buf_0 & 0xf); + c2h_seq = (buf_0 & 0xf0) >> 4; + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] freg_num = (( %d )), c2h_seq = (( %d ))\n", freg_num,c2h_seq ));*/ + + /*strncpy(debug_trace_11byte,&CmdBuf[1],(CmdLen-1));*/ + /*debug_trace_11byte[CmdLen-1] = '\0';*/ + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] %s\n", debug_trace_11byte));*/ + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] CmdLen = (( %d ))\n", CmdLen));*/ + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW debug message] c2h_cmd_start = (( %d ))\n", pDM_Odm->c2h_cmd_start));*/ + + + + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("pre_seq = (( %d )), current_seq = (( %d ))\n", pDM_Odm->pre_c2h_seq, c2h_seq));*/ + /*ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("fw_buff_is_enpty = (( %d ))\n", pDM_Odm->fw_buff_is_enpty));*/ + + if ((c2h_seq != pDM_Odm->pre_c2h_seq) && pDM_Odm->fw_buff_is_enpty == FALSE) { + pDM_Odm->fw_debug_trace[pDM_Odm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW Dbg Queue Overflow] %s\n", pDM_Odm->fw_debug_trace)); + pDM_Odm->c2h_cmd_start = 0; + } + + if ((CmdLen - 1) > (60 - pDM_Odm->c2h_cmd_start)) { + pDM_Odm->fw_debug_trace[pDM_Odm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW Dbg Queue error: wrong C2H length] %s\n", pDM_Odm->fw_debug_trace)); + pDM_Odm->c2h_cmd_start = 0; + return; + } + + strncpy((char *)&(pDM_Odm->fw_debug_trace[pDM_Odm->c2h_cmd_start]), (char *)&CmdBuf[1], (CmdLen-1)); + pDM_Odm->c2h_cmd_start += (CmdLen - 1); + pDM_Odm->fw_buff_is_enpty = FALSE; + + if (freg_num == 0 || pDM_Odm->c2h_cmd_start >= 60) { + if (pDM_Odm->c2h_cmd_start < 60) + pDM_Odm->fw_debug_trace[pDM_Odm->c2h_cmd_start] = '\0'; + else + pDM_Odm->fw_debug_trace[59] = '\0'; + + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s\n", pDM_Odm->fw_debug_trace)); + /*DbgPrint("[FW DBG Msg] %s\n", pDM_Odm->fw_debug_trace);*/ + pDM_Odm->c2h_cmd_start = 0; + pDM_Odm->fw_buff_is_enpty = TRUE; + } + + pDM_Odm->pre_c2h_seq = c2h_seq; +} + +VOID +phydm_fw_trace_handler_code( + IN PVOID pDM_VOID, + IN pu1Byte Buffer, + IN u1Byte CmdLen +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte function = Buffer[0]; + u1Byte dbg_num = Buffer[1]; + u2Byte content_0 = (((u2Byte)Buffer[3])<<8)|((u2Byte)Buffer[2]); + u2Byte content_1 = (((u2Byte)Buffer[5])<<8)|((u2Byte)Buffer[4]); + u2Byte content_2 = (((u2Byte)Buffer[7])<<8)|((u2Byte)Buffer[6]); + u2Byte content_3 = (((u2Byte)Buffer[9])<<8)|((u2Byte)Buffer[8]); + u2Byte content_4 = (((u2Byte)Buffer[11])<<8)|((u2Byte)Buffer[10]); + + if(CmdLen >12) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW Msg] Invalid cmd length (( %d )) >12 \n", CmdLen)); + } + + //ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW Msg] Func=((%d)), num=((%d)), ct_0=((%d)), ct_1=((%d)), ct_2=((%d)), ct_3=((%d)), ct_4=((%d))\n", + // function, dbg_num, content_0, content_1, content_2, content_3, content_4)); + + /*--------------------------------------------*/ + if(function == RATE_DECISION) { + if(dbg_num == 0) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] RA_CNT=((%d)) Max_device=((%d))--------------------------->\n", content_1, content_2)); + } else if(content_0 == 2) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] Check RA macid= ((%d)), MediaStatus=((%d)), Dis_RA=((%d)), try_bit=((0x%x))\n", content_1, content_2, content_3, content_4)); + } else if(content_0 == 3) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Check RA total=((%d)), drop=((0x%x)), TXRPT_TRY_bit=((%x)), bNoisy=((%x))\n", content_1, content_2, content_3, content_4)); + } + } else if(dbg_num == 1) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] RTY[0,1,2,3]=[ %d, %d, %d, %d ] \n", content_1, content_2, content_3, content_4)); + } else if(content_0 == 2) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] RTY[4]=[ %d ], drop=((%d)), total=((%d)), current_rate=((0x%x))\n", content_1, content_2, content_3, content_4)); + } else if(content_0 == 3) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] penality_idx=((%d ))\n", content_1)); + } + } + + else if(dbg_num == 3) { + if (content_0 == 1) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Fast_RA (( DOWN )) total=((%d)), total>>1=((%d)), R4+R3+R2 = ((%d)), RateDownHold = ((%d))\n", content_1, content_2, content_3, content_4)); + else if (content_0 == 2) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Fast_RA (( UP )) total_acc=((%d)), total_acc>>1=((%d)), R4+R3+R2 = ((%d)), RateDownHold = ((%d))\n", content_1, content_2, content_3, content_4)); + else if (content_0 == 3) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Fast_RA (( UP )) ((Rate Down Hold)) RA_CNT=((%d))\n", content_1)); + else if (content_0 == 4) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Fast_RA (( UP )) ((tota_accl<5 skip)) RA_CNT=((%d))\n", content_1)); + else if (content_0 == 8) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDecisoin] Fast_RA (( Reset Tx Rpt )) RA_CNT=((%d))\n", content_1)); + } + + else if(dbg_num == 5) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] (( UP)) Nsc=((%d)), N_High=((%d))\n", content_1, content_2)); + } else if(content_0 == 2) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] ((DOWN)) Nsc=((%d)), N_Low=((%d))\n", content_1, content_2)); + } else if(content_0 == 3) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] ((HOLD)) Nsc=((%d)), N_High=((%d)), N_Low=((%d)), Reset_CNT=((%d))\n", content_1, content_2, content_3, content_4)); + } + } + else if(dbg_num == 0x60) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] ((AP RPT)) macid=((%d)), BUPDATE[macid]=((%d))\n", content_1, content_2)); + } else if(content_0 == 4) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] ((AP RPT)) pass=((%d)), rty_num=((%d)), drop=((%d)), total=((%d))\n", content_1, content_2, content_3, content_4)); + } else if(content_0 == 5) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("[FW][RateDecisoin] ((AP RPT)) PASS=((%d)), RTY_NUM=((%d)), DROP=((%d)), TOTAL=((%d))\n", content_1, content_2, content_3, content_4)); + } + } + else if(dbg_num == 0xff) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE,ODM_DBG_LOUD,("\n\n")); + } + } + + } + /*--------------------------------------------*/ + else if (function == INIT_RA_TABLE){ + if(dbg_num == 3) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][INIT_RA_INFO] Ra_init, RA_SKIP_CNT = (( %d ))\n", content_0)); + } + + } + /*--------------------------------------------*/ + else if (function == RATE_UP) { + if(dbg_num == 2) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((Highest rate -> return)), macid=((%d)) Nsc=((%d))\n", content_1, content_2)); + } + } else if(dbg_num == 5) { + if (content_0 == 0) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((Rate UP)), up_rate_tmp=((0x%x)), rate_idx=((0x%x)), SGI_en=((%d)), SGI=((%d))\n", content_1, content_2, content_3, content_4)); + else if (content_0 == 1) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateUp] ((Rate UP)), rate_1=((0x%x)), rate_2=((0x%x)), BW=((%d)), Try_Bit=((%d))\n", content_1, content_2, content_3, content_4)); + } + + } + /*--------------------------------------------*/ + else if (function == RATE_DOWN) { + if(dbg_num == 5) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][RateDownStep] ((Rate Down)), macid=((%d)), rate=((0x%x)), BW=((%d))\n", content_1, content_2, content_3)); + } + } + } else if (function == TRY_DONE) { + if (dbg_num == 1) { + if (content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][Try Done] ((try succsess )) macid=((%d)), Try_Done_cnt=((%d))\n", content_1, content_2)); + /**/ + } + } else if (dbg_num == 2) { + if (content_0 == 1) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][Try Done] ((try fail )) macid=((%d)), Try_Done_cnt=((%d)), multi_try_rate=((%d))\n", content_1, content_2, content_3)); + } + } + /*--------------------------------------------*/ + else if (function == F_RATE_AP_RPT) { + if(dbg_num == 1) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] ((1)), SPE_STATIS=((0x%x))---------->\n", content_3)); + } + } else if(dbg_num == 2) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] RTY_all=((%d))\n", content_1)); + } + } else if(dbg_num == 3) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID1[%d], TOTAL=((%d)), RTY=((%d))\n", content_3, content_1, content_2)); + } + } else if(dbg_num == 4) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID2[%d], TOTAL=((%d)), RTY=((%d))\n", content_3, content_1, content_2)); + } + } else if(dbg_num == 5) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID1[%d], PASS=((%d)), DROP=((%d))\n", content_3, content_1, content_2)); + } + } else if(dbg_num == 6) { + if(content_0 == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW][AP RPT] MACID2[%d],, PASS=((%d)), DROP=((%d))\n", content_3, content_1, content_2)); + } + } + } + /*--------------------------------------------*/ + + +} + +VOID +phydm_fw_trace_handler_8051( + IN PVOID pDM_VOID, + IN pu1Byte Buffer, + IN u1Byte CmdLen +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if 0 + if (CmdLen >= 3) + CmdBuf[CmdLen - 1] = '\0'; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s\n", &(CmdBuf[3]))); +#else + + int i = 0; + u1Byte Extend_c2hSubID = 0, Extend_c2hDbgLen = 0, Extend_c2hDbgSeq = 0; + u1Byte fw_debug_trace[128]; + pu1Byte Extend_c2hDbgContent = 0; + + if (CmdLen > 127) + return; + + Extend_c2hSubID = Buffer[0]; + Extend_c2hDbgLen = Buffer[1]; + Extend_c2hDbgContent = Buffer + 2; /*DbgSeq+DbgContent for show HEX*/ + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_DISP(FC2H, C2H_Summary, ("[Extend C2H packet], Extend_c2hSubId=0x%x, Extend_c2hDbgLen=%d\n", + Extend_c2hSubID, Extend_c2hDbgLen)); + + RT_DISP_DATA(FC2H, C2H_Summary, "[Extend C2H packet], Content Hex:", Extend_c2hDbgContent, CmdLen-2); + #endif + +GoBackforAggreDbgPkt: + i = 0; + Extend_c2hDbgSeq = Buffer[2]; + Extend_c2hDbgContent = Buffer + 3; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_DISP(FC2H, C2H_Summary, ("[RTKFW, SEQ= %d] :", Extend_c2hDbgSeq)); + #endif + + for (; ; i++) { + fw_debug_trace[i] = Extend_c2hDbgContent[i]; + if (Extend_c2hDbgContent[i + 1] == '\0') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s", &(fw_debug_trace[0]))); + break; + } else if (Extend_c2hDbgContent[i] == '\n') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("[FW DBG Msg] %s", &(fw_debug_trace[0]))); + Buffer = Extend_c2hDbgContent + i + 3; + goto GoBackforAggreDbgPkt; + } + } + + +#endif +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.h new file mode 100644 index 00000000..2f5859b5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_debug.h @@ -0,0 +1,330 @@ +/****************************************************************************** + * + * 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 DEBUG_VERSION "1.0" /*2015.01.13 Dino*/ +//----------------------------------------------------------------------------- +// 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 + +/*FW DBG MSG*/ +#define RATE_DECISION BIT0 +#define INIT_RA_TABLE BIT1 +#define RATE_UP BIT2 +#define RATE_DOWN BIT3 +#define TRY_DONE BIT4 +#define F_RATE_AP_RPT BIT7 + +//----------------------------------------------------------------------------- +// 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 +#define PHYDM_COMP_RA_DBG BIT18 +#define PHYDM_COMP_TXBF BIT19 +//MAC Functions +#define ODM_COMP_EDCA_TURBO BIT20 +#define ODM_COMP_EARLY_MODE BIT21 +#define ODM_FW_DEBUG_TRACE BIT22 +//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_PHY_CONFIG BIT28 +#define BEAMFORMING_DEBUG BIT29 +#define ODM_COMP_COMMON BIT30 +#define ODM_COMP_INIT BIT31 +#define ODM_COMP_NOISY_DETECT BIT32 + +/*------------------------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) \ + do { \ + 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] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8703B) \ + DbgPrint("[ODM-8703B] "); \ + else if(pDM_Odm->SupportICType == ODM_RTL8822B) \ + DbgPrint("[ODM-8822] "); \ + else if (pDM_Odm->SupportICType == ODM_RTL8188F) \ + DbgPrint("[ODM-8188F] "); \ + RT_PRINTK fmt; \ + } \ + } while (0) + +#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); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID phydm_BB_RxHang_Info(IN PDM_ODM_T pDM_Odm); +#endif + +#define BB_TMP_BUF_SIZE 100 +VOID phydm_BB_Debug_Info(IN PDM_ODM_T pDM_Odm); +VOID phydm_BasicDbgMessage( IN PVOID pDM_VOID); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define PHYDM_DBGPRINT 0 +#define PHYDM_SSCANF(x, y, z) DCMD_Scanf(x, y, z) +#if (PHYDM_DBGPRINT == 1) +#define PHYDM_SNPRINTF(msg) \ + do {\ + rsprintf msg;\ + DbgPrint(output);\ + } while (0) +#else +#define PHYDM_SNPRINTF(msg) \ + do {\ + rsprintf msg;\ + DCMD_Printf(output);\ + } while (0) +#endif +#else +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#define PHYDM_DBGPRINT 0 +#else +#define PHYDM_DBGPRINT 1 +#endif +#define MAX_ARGC 20 +#define MAX_ARGV 16 +#define DCMD_DECIMAL "%d" +#define DCMD_CHAR "%c" +#define DCMD_HEX "%x" + +#define PHYDM_SSCANF(x, y, z) sscanf(x, y, z) +#if (PHYDM_DBGPRINT == 1) +#define PHYDM_SNPRINTF(msg)\ + do {\ + snprintf msg;\ + DbgPrint(output);\ + } while (0) +#else +#define PHYDM_SNPRINTF(msg)\ + do {\ + if(out_len > used)\ + used+=snprintf msg;\ + } while (0) +#endif +#endif + + +VOID phydm_BasicProfile( + IN PVOID pDM_VOID, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ); +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP)) +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 +VOID +phydm_cmd_parser( + IN PDM_ODM_T pDM_Odm, + IN char input[][16], + IN u4Byte input_num, + IN u1Byte flag, + OUT char *output, + IN u4Byte out_len +); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +void phydm_sbd_check( + IN PDM_ODM_T pDM_Odm + ); + +void phydm_sbd_callback( + PRT_TIMER pTimer + ); + +void phydm_sbd_workitem_callback( + IN PVOID pContext + ); +#endif + +VOID +phydm_fw_trace_en_h2c( + IN PVOID pDM_VOID, + IN BOOLEAN enable, + IN u4Byte monitor_mode, + IN u4Byte macid +); + +VOID +phydm_fw_trace_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +); + +VOID +phydm_fw_trace_handler_code( + IN PVOID pDM_VOID, + IN pu1Byte Buffer, + IN u1Byte CmdLen +); + +VOID +phydm_fw_trace_handler_8051( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +); + +#endif // __ODM_DBG_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.c new file mode 100644 index 00000000..468281fb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.c @@ -0,0 +1,2086 @@ +/****************************************************************************** + * + * 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, ("ODM_Write_DIG(): Stop Writing IGI\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_Write_DIG(): 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))); + + //1 Check initial gain by upper bound + if ((!pDM_DigTable->bPSDInProgress) && pDM_Odm->bLinked) + { + if (CurrentIGI > pDM_DigTable->rx_gain_range_max) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("ODM_Write_DIG(): CurrentIGI(0x%02x) is larger than upper bound !!\n", CurrentIGI)); + CurrentIGI = pDM_DigTable->rx_gain_range_max; + } + if (pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY && pDM_Odm->adaptivity_flag == TRUE) + { + if(CurrentIGI > pDM_Odm->Adaptivity_IGI_upper) + CurrentIGI = pDM_Odm->Adaptivity_IGI_upper; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ODM_Write_DIG(): Adaptivity case: Force upper bound to 0x%x !!!!!!\n", CurrentIGI)); + } + } + + if(pDM_DigTable->CurIGValue != CurrentIGI) + { + + /*Add by YuChen for USB IO too slow issue*/ + if ((pDM_Odm->SupportAbility & ODM_BB_ADAPTIVITY) && (CurrentIGI > pDM_DigTable->CurIGValue)) + Phydm_Adaptivity(pDM_Odm, CurrentIGI); + + //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, ("ODM_Write_DIG(): CurrentIGI(0x%02x).\n", CurrentIGI)); + +} + +VOID +odm_PauseDIG( + IN PVOID pDM_VOID, + IN PHYDM_PAUSE_TYPE PauseType, + IN PHYDM_PAUSE_LEVEL pause_level, + 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()=========> level = %d\n", pause_level)); + + if ((pDM_DigTable->pause_dig_level == 0) && (!(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 DIG or FA is disabled !!\n")); + return; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, + ("odm_PauseDIG(): Return: Wrong pause level !!\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_dig_level, IGIValue)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pDM_DigTable->pause_dig_value[7], pDM_DigTable->pause_dig_value[6], pDM_DigTable->pause_dig_value[5], pDM_DigTable->pause_dig_value[4], + pDM_DigTable->pause_dig_value[3], pDM_DigTable->pause_dig_value[2], pDM_DigTable->pause_dig_value[1], pDM_DigTable->pause_dig_value[0])); + + switch (PauseType) { + /* Pause DIG */ + case PHYDM_PAUSE: + { + /* 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")); + + /* Backup IGI value */ + if (pDM_DigTable->pause_dig_level == 0) { + pDM_DigTable->IGIBackup = pDM_DigTable->CurIGValue; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Backup IGI = 0x%x, new IGI = 0x%x\n", pDM_DigTable->IGIBackup, IGIValue)); + } + + /* Record IGI value */ + pDM_DigTable->pause_dig_value[pause_level] = IGIValue; + + /* Update pause level */ + pDM_DigTable->pause_dig_level = (pDM_DigTable->pause_dig_level | BIT(pause_level)); + + /* Write new IGI value */ + if (BIT(pause_level + 1) > pDM_DigTable->pause_dig_level) { + ODM_Write_DIG(pDM_Odm, IGIValue); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): IGI of higher level = 0x%x\n", IGIValue)); + } + break; + } + /* Resume DIG */ + case PHYDM_RESUME: + { + /* check if the level is illegal or not */ + if ((pDM_DigTable->pause_dig_level & (BIT(pause_level))) != 0) { + pDM_DigTable->pause_dig_level = pDM_DigTable->pause_dig_level & (~(BIT(pause_level))); + pDM_DigTable->pause_dig_value[pause_level] = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Resume DIG !!\n")); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong resume level !!\n")); + break; + } + + /* Resume DIG */ + if (pDM_DigTable->pause_dig_level == 0) { + /* Write backup IGI value */ + ODM_Write_DIG(pDM_Odm, pDM_DigTable->IGIBackup); + 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)); + + /* Enable DIG */ + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_DIG); + break; + } + + if (BIT(pause_level) > pDM_DigTable->pause_dig_level) { + u1Byte max_level; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; max_level--) { + if ((pDM_DigTable->pause_dig_level & BIT(max_level)) > 0) + break; + } + + /* write IGI of lower level */ + ODM_Write_DIG(pDM_Odm, pDM_DigTable->pause_dig_value[max_level]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Write IGI (0x%x) of level (%d)\n", + pDM_DigTable->pause_dig_value[max_level], max_level)); + break; + } + break; + } + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): Wrong type !!\n")); + break; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_dig_level, IGIValue)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_PauseDIG(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pDM_DigTable->pause_dig_value[7], pDM_DigTable->pause_dig_value[6], pDM_DigTable->pause_dig_value[5], pDM_DigTable->pause_dig_value[4], + pDM_DigTable->pause_dig_value[3], pDM_DigTable->pause_dig_value[2], pDM_DigTable->pause_dig_value[1], pDM_DigTable->pause_dig_value[0])); + +} + +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)) + PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( pDM_Odm, PHYDM_FALSEALMCNT); +#endif + + pDM_DigTable->bStopDIG = 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)) + 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; + + ODM_Memory_Set(pDM_Odm, pDM_DigTable->pause_dig_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1)); + pDM_DigTable->pause_dig_level = 0; + ODM_Memory_Set(pDM_Odm, pDM_DigTable->pause_cckpd_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1)); + pDM_DigTable->pause_cckpd_level = 0; +#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]; + 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")); + + + //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; + if (*pDM_Odm->pBandWidth == ODM_BW20M){ + dm_dig_min = DM_DIG_MIN_AP_DFS+2; + } + else{ + 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) { + 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_DIG, 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_DIG, 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) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Beacon Num (%d)\n", pDM_Odm->PhyDbgInfo.NumQryBeaconPkt)); + 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 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); + + 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(!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) + return; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics()======>\n")); + +#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, ("odm_FalseAlarmCounterStatistics(): 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, ("odm_FalseAlarmCounterStatistics(): 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, ("odm_FalseAlarmCounterStatistics(): 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); + + + /* Read CCK FA counter */ + 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, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail_pre)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): 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, ("odm_FalseAlarmCounterStatistics(): 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, ("odm_FalseAlarmCounterStatistics(): Cnt_OFDM_CCA=%d\n", FalseAlmCnt->Cnt_OFDM_CCA)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_CCK_CCA=%d\n", FalseAlmCnt->Cnt_CCK_CCA)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_CCA_all=%d\n", FalseAlmCnt->Cnt_CCA_all)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Cck_fail=%d\n", FalseAlmCnt->Cnt_Cck_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Cnt_Ofdm_fail=%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_FalseAlarmCounterStatistics(): Total False Alarm=%d\n\n", FalseAlmCnt->Cnt_all)); +} + +//3============================================================ +//3 CCK Packet Detect Threshold +//3============================================================ + +VOID +odm_PauseCCKPacketDetection( + IN PVOID pDM_VOID, + IN PHYDM_PAUSE_TYPE PauseType, + IN PHYDM_PAUSE_LEVEL pause_level, + IN u1Byte CCKPDThreshold +) +{ + 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_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection()=========> level = %d\n", pause_level)); + + if ((pDM_DigTable->pause_cckpd_level == 0) && (!(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; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, + ("odm_PauseCCKPacketDetection(): Return: Wrong pause level !!\n")); + return; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_cckpd_level, CCKPDThreshold)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pDM_DigTable->pause_cckpd_value[7], pDM_DigTable->pause_cckpd_value[6], pDM_DigTable->pause_cckpd_value[5], pDM_DigTable->pause_cckpd_value[4], + pDM_DigTable->pause_cckpd_value[3], pDM_DigTable->pause_cckpd_value[2], pDM_DigTable->pause_cckpd_value[1], pDM_DigTable->pause_cckpd_value[0])); + + switch (PauseType) { + /* Pause CCK Packet Detection Threshold */ + case PHYDM_PAUSE: + { + /* Disable CCK PD */ + 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, ("odm_PauseCCKPacketDetection(): Pause CCK packet detection threshold !!\n")); + + /* Backup original CCK PD threshold decided by CCK PD mechanism */ + if (pDM_DigTable->pause_cckpd_level == 0) { + pDM_DigTable->CCKPDBackup = pDM_DigTable->CurCCK_CCAThres; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, + ("odm_PauseCCKPacketDetection(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", pDM_DigTable->CCKPDBackup, CCKPDThreshold)); + } + + /* Update pause level */ + pDM_DigTable->pause_cckpd_level = (pDM_DigTable->pause_cckpd_level | BIT(pause_level)); + + /* Record CCK PD threshold */ + pDM_DigTable->pause_cckpd_value[pause_level] = CCKPDThreshold; + + /* Write new CCK PD threshold */ + if (BIT(pause_level + 1) > pDM_DigTable->pause_cckpd_level) { + ODM_Write_CCK_CCA_Thres(pDM_Odm, CCKPDThreshold); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): CCKPD of higher level = 0x%x\n", CCKPDThreshold)); + } + break; + } + /* Resume CCK Packet Detection Threshold */ + case PHYDM_RESUME: + { + /* check if the level is illegal or not */ + if ((pDM_DigTable->pause_cckpd_level & (BIT(pause_level))) != 0) { + pDM_DigTable->pause_cckpd_level = pDM_DigTable->pause_cckpd_level & (~(BIT(pause_level))); + pDM_DigTable->pause_cckpd_value[pause_level] = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Resume CCK PD !!\n")); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Wrong resume level !!\n")); + break; + } + + /* Resume DIG */ + if (pDM_DigTable->pause_cckpd_level == 0) { + /* Write backup IGI value */ + ODM_Write_CCK_CCA_Thres(pDM_Odm, pDM_DigTable->CCKPDBackup); + /* pDM_DigTable->bIgnoreDIG = TRUE; */ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Write original CCKPD = 0x%x\n", pDM_DigTable->CCKPDBackup)); + + /* Enable DIG */ + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, pDM_Odm->SupportAbility | ODM_BB_CCK_PD); + break; + } + + if (BIT(pause_level) > pDM_DigTable->pause_cckpd_level) { + u1Byte max_level; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; max_level--) { + if ((pDM_DigTable->pause_cckpd_level & BIT(max_level)) > 0) + break; + } + + /* write CCKPD of lower level */ + ODM_Write_CCK_CCA_Thres(pDM_Odm, pDM_DigTable->pause_cckpd_value[max_level]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Write CCKPD (0x%x) of level (%d)\n", + pDM_DigTable->pause_cckpd_value[max_level], max_level)); + break; + } + break; + } + default: + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): Wrong type !!\n")); + break; + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause level = 0x%x, Current value = 0x%x\n", pDM_DigTable->pause_cckpd_level, CCKPDThreshold)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CCK_PD, ODM_DBG_LOUD, ("odm_PauseCCKPacketDetection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + pDM_DigTable->pause_cckpd_value[7], pDM_DigTable->pause_cckpd_value[6], pDM_DigTable->pause_cckpd_value[5], pDM_DigTable->pause_cckpd_value[4], + pDM_DigTable->pause_cckpd_value[3], pDM_DigTable->pause_cckpd_value[2], pDM_DigTable->pause_cckpd_value[1], pDM_DigTable->pause_cckpd_value[0])); +} + + +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, RSSI_thd = 55; + + +#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")); +#ifdef MCR_WIRELESS_EXTEND + ODM_Write_CCK_CCA_Thres(pDM_Odm, 0x43); +#endif + 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 > RSSI_thd) + CurCCK_CCAThres = 0xcd; + else if ((pDM_Odm->RSSI_Min <= RSSI_thd) && (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)) + if (*pDM_Odm->pBandType == ODM_BAND_5G || (pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B))) // 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_RTL8822B))) + { + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.h new file mode 100644 index 00000000..7e2b13bb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dig.h @@ -0,0 +1,327 @@ +/****************************************************************************** + * + * 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.8" /*2015.07.01*/ + +/* Pause DIG & CCKPD */ +#define DM_DIG_MAX_PAUSE_TYPE 0x7 + +typedef struct _Dynamic_Initial_Gain_Threshold_ +{ + BOOLEAN bStopDIG; // for debug + 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 pause_cckpd_level; + u1Byte pause_cckpd_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + + 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 *bP2PInProcess; + + u1Byte pause_dig_level; + u1Byte pause_dig_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + +#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_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) +*/ + +typedef enum tag_PHYDM_Pause_Type { + PHYDM_PAUSE = BIT0, + PHYDM_RESUME = BIT1 +} PHYDM_PAUSE_TYPE; + +typedef enum tag_PHYDM_Pause_Level { +/* number of pause level can't exceed DM_DIG_MAX_PAUSE_TYPE */ + PHYDM_PAUSE_LEVEL_0 = 0, + PHYDM_PAUSE_LEVEL_1 = 1, + PHYDM_PAUSE_LEVEL_2 = 2, + PHYDM_PAUSE_LEVEL_3 = 3, + PHYDM_PAUSE_LEVEL_4 = 4, + PHYDM_PAUSE_LEVEL_5 = 5, + PHYDM_PAUSE_LEVEL_6 = 6, + PHYDM_PAUSE_LEVEL_7 = DM_DIG_MAX_PAUSE_TYPE /* maximum level */ +} PHYDM_PAUSE_LEVEL; + + +#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 PHYDM_PAUSE_TYPE PauseType, + IN PHYDM_PAUSE_LEVEL pause_level, + 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 PHYDM_PAUSE_TYPE PauseType, + IN PHYDM_PAUSE_LEVEL pause_level, + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.c new file mode 100644 index 00000000..23fc0022 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.c @@ -0,0 +1,219 @@ +/****************************************************************************** + * + * 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 +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamicbbpowersaving.h new file mode 100644 index 00000000..0556e3f5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/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 diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.c new file mode 100644 index 00000000..afb3be92 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.c @@ -0,0 +1,633 @@ +/****************************************************************************** + * + * 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; + + +#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]); + + +#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]); + + +#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) || (RTL8814A_SUPPORT==1)) + if (pDM_Odm->SupportICType & (ODM_RTL8812 | ODM_RTL8881A | ODM_RTL8814A)) + 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 + +#ifdef CONFIG_WLAN_HAL_8814AE + if (GET_CHIP_VER(priv) == VERSION_8814A) { + if (!disable_pwr_ctrl && (pDM_Odm->RSSI_Min != 0xff)) { + if (pDM_Odm->RSSI_Min > pwr_thd) + RRSR_power_control_14(priv, 1); + else if (pDM_Odm->RSSI_Min < (pwr_thd-8)) + RRSR_power_control_14(priv, 0); + } else { + RRSR_power_control_14(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; + + + + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +} + + +VOID +odm_DynamicTxPower_92D( + IN PVOID pDM_VOID + ) +{ +#if (RTL8192D_SUPPORT==1) + 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; + + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#endif +} + +VOID +odm_DynamicTxPower_8821( + IN PVOID pDM_VOID, + IN pu1Byte pDesc, + IN u1Byte macId + ) +{ +#if (RTL8821A_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PSTA_INFO_T pEntry; + u1Byte reg0xc56_byte; + u1Byte reg0xe56_byte; + u1Byte txpwr_offset = 0; + + pEntry = pDM_Odm->pODM_StaInfo[macId]; + + reg0xc56_byte = ODM_Read1Byte(pDM_Odm, 0xc56); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("reg0xc56_byte=%d\n", reg0xc56_byte)); + + if (pEntry[macId].rssi_stat.UndecoratedSmoothedPWDB > 85) { + + /* Avoid TXAGC error after TX power offset is applied. + For example: Reg0xc56=0x6, if txpwr_offset=3( reduce 11dB ) + Total power = 6-11= -5( overflow!! ), PA may be burned ! + so txpwr_offset should be adjusted by Reg0xc56*/ + + if (reg0xc56_byte < 7) + txpwr_offset = 1; + else if (reg0xc56_byte < 11) + txpwr_offset = 2; + else + txpwr_offset = 3; + + SET_TX_DESC_TX_POWER_OFFSET_8812(pDesc, txpwr_offset); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("odm_DynamicTxPower_8821: RSSI=%d, txpwr_offset=%d\n", pEntry[macId].rssi_stat.UndecoratedSmoothedPWDB, txpwr_offset)); + + } else{ + SET_TX_DESC_TX_POWER_OFFSET_8812(pDesc, txpwr_offset); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_DYNAMIC_TXPWR, DBG_LOUD, ("odm_DynamicTxPower_8821: RSSI=%d, txpwr_offset=%d\n", pEntry[macId].rssi_stat.UndecoratedSmoothedPWDB, txpwr_offset)); + + } +#endif /*#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)*/ +#endif /*#if (RTL8821A_SUPPORT==1)*/ +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.h new file mode 100644 index 00000000..69e1849d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_dynamictxpower.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * 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 DYNAMIC_TXPWR_VERSION "1.1" /*2015.01.13*/ + +#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 + ); + +VOID +odm_DynamicTxPower_8821( + IN PVOID pDM_VOID, + IN pu1Byte pDesc, + IN u1Byte macId + ); + +#endif + +VOID +odm_DynamicTxPower( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerAP( + IN PVOID pDM_VOID + ); + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.c new file mode 100644 index 00000000..255d9855 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.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" + +VOID +ODM_EdcaTurboInit( + IN PVOID pDM_VOID) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + +#if (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; + } + 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("pRFCalibrateInfo->ThermalValue = 0x%X\n", pRFCalibrateInfo->ThermalValue);*/ + /*if(pRFCalibrateInfo->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("pRFCalibrateInfo->ThermalValue = 0x%X\n", pRFCalibrateInfo->ThermalValue);*/ + /*if(pRFCalibrateInfo->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 && IOTPeerSubType != HT_IOT_PEER_TPLINK_AC1750) + { + // 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\n",(*EDCA_BE_UL),(*EDCA_BE_DL))); + } + + if((ICType==ODM_RTL8814A) && (IOTPeer == HT_IOT_PEER_REALTEK)) /*8814AU and 8814AR*/ + { + (*EDCA_BE_UL) = 0x5ea42b; + (*EDCA_BE_DL) = 0xa42b; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_EDCA_TURBO,ODM_DBG_LOUD,("8814A: EDCA_BE_UL=0x%lx EDCA_BE_DL =0x%lx\n",(*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, IOTPeer = %d\n",(*EDCA_BE_UL),(*EDCA_BE_DL), IOTPeer)); + +} + + +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 + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.h new file mode 100644 index 00000000..982df924 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_edcaturbocheck.h @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * 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 "2.1"*/ +#define EDCATURBO_VERSION "2.2" /*2015.01.13*/ + +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}; + +#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 + ); +#endif + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_features.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_features.h new file mode 100644 index 00000000..78b56beb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_features.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * 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 __PHYDM_FEATURES_H__ +#define __PHYDM_FEATURES + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + /*Antenna Diversity*/ + #define CONFIG_PHYDM_ANTENNA_DIVERSITY + #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY + + #if (RTL8723B_SUPPORT == 1) || (RTL8821A_SUPPORT == 1) || (RTL8188F_SUPPORT == 1) + #define CONFIG_S0S1_SW_ANTENNA_DIVERSITY + #endif + + #if (RTL8821A_SUPPORT == 1) + /*#define CONFIG_HL_SMART_ANTENNA_TYPE1*/ + #endif + #endif + + /*#define CONFIG_PATH_DIVERSITY*/ + /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ + #define CONFIG_ANT_DETECTION + #define CONFIG_RA_DBG_CMD + +#elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + + /* [ Configure RA Debug H2C CMD ]*/ + #define CONFIG_RA_DBG_CMD + + /*#define CONFIG_PATH_DIVERSITY*/ + /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ + #define CONFIG_RA_DYNAMIC_RATE_ID + + /* [ Configure Antenna Diversity ] */ + #if defined(CONFIG_RTL_8881A_ANT_SWITCH) || defined(CONFIG_SLOT_0_ANT_SWITCH) || defined(CONFIG_SLOT_1_ANT_SWITCH) + #define CONFIG_PHYDM_ANTENNA_DIVERSITY + #define ODM_EVM_ENHANCE_ANTDIV + + /*----------*/ + + #if (!defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A) && !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 + #elif defined(CONFIG_2G5G_CG_TRX_DIVERSITY_8881A) + #define CONFIG_2G5G_CG_TRX_DIVERSITY + #endif + #if (!defined(CONFIG_NO_5G_DIVERSITY) && !defined(CONFIG_5G_CGCS_RX_DIVERSITY) && !defined(CONFIG_5G_CG_TRX_DIVERSITY) && !defined(CONFIG_2G5G_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)) || defined(CONFIG_2G5G_CG_TRX_DIVERSITY)) + #define CONFIG_2G5G_SUPPORT_ANTDIV + #endif + /*----------*/ + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + + /*Antenna Diversity*/ + #ifdef CONFIG_ANTENNA_DIVERSITY + #define CONFIG_PHYDM_ANTENNA_DIVERSITY + + #ifdef CONFIG_PHYDM_ANTENNA_DIVERSITY + + #if (RTL8723B_SUPPORT == 1) || (RTL8821A_SUPPORT == 1) || (RTL8188F_SUPPORT == 1) + #define CONFIG_S0S1_SW_ANTENNA_DIVERSITY + #endif + + #if (RTL8821A_SUPPORT == 1) + /*#define CONFIG_HL_SMART_ANTENNA_TYPE1*/ + #endif + #endif + #endif + + /*#define CONFIG_RA_DBG_CMD*/ + /*#define CONFIG_ANT_DETECTION*/ + /*#define CONFIG_PATH_DIVERSITY*/ + /*#define CONFIG_RA_DYNAMIC_RTY_LIMIT*/ + +#endif + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.c new file mode 100644 index 00000000..1d576598 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.c @@ -0,0 +1,3331 @@ +/****************************************************************************** + * + * 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 (PHYDM_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 (PHYDM_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); + } + +} + + +// +// 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 (DM_ODM_SUPPORT_TYPE == ODM_WIN) + 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 +#endif + { + return odm_SignalScaleMapping_92CSeries(pDM_Odm,CurrSig); + } + +} + + + +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));*/ +#ifdef ODM_EVM_ENHANCE_ANTDIV + if (ret_val >= 0) + ret_val = 0; + + if (ret_val <= -40) + ret_val = -40; + + ret_val = 0 - ret_val; + ret_val *= 3; +#else + 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; +#endif + + return (u1Byte)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 (u1Byte)ret_val; +} + +static s2Byte +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) + +s1Byte +odm_CCKRSSI_8703B( + IN u2Byte LNA_idx, + IN u1Byte VGA_idx + ) +{ + s1Byte rx_pwr_all = 0x00; + + switch (LNA_idx) { + case 0xf: + rx_pwr_all = -48 - (2 * VGA_idx); + break; + case 0xb: + rx_pwr_all = -42 - (2 * VGA_idx); /*TBD*/ + break; + case 0xa: + rx_pwr_all = -36 - (2 * VGA_idx); + break; + case 8: + rx_pwr_all = -32 - (2 * VGA_idx); + break; + case 7: + rx_pwr_all = -28 - (2 * VGA_idx); /*TBD*/ + break; + case 4: + rx_pwr_all = -16 - (2 * VGA_idx); + break; + case 0: + rx_pwr_all = -2 - (2 * VGA_idx); + break; + default: + /*rx_pwr_all = -53+(2*(31-VGA_idx));*/ + /*DbgPrint("wrong LNA index\n");*/ + break; + + } + return rx_pwr_all; +} + +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 = 0; + u1Byte VGA_idx = 0; + PPHY_STATUS_RPT_8192CD_T pPhyStaRpt = (PPHY_STATUS_RPT_8192CD_T)pPhyStatus; + + isCCKrate = (pPktinfo->DataRate <= ODM_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_RTL8703B)) { + + #if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->cck_agc_report_type == 1) { /*4 bit LNA*/ + + u1Byte cck_agc_rpt_b = (pPhyStaRpt->cck_rpt_b_ofdm_cfosho_b & BIT7) ? 1 : 0; + + LNA_idx = (cck_agc_rpt_b << 3) | ((cck_agc_rpt & 0xE0) >> 5); + VGA_idx = (cck_agc_rpt & 0x1F); + + rx_pwr_all = odm_CCKRSSI_8703B(LNA_idx, VGA_idx); + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + if (PWDB_ALL > 100) + PWDB_ALL = 100; + + } + #endif + } else if (pDM_Odm->SupportICType & (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8188F)) /*3 bit LNA*/ + { + LNA_idx = ((cck_agc_rpt & 0xE0) >>5); + VGA_idx = (cck_agc_rpt & 0x1F); + if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8192E)) + { + if(pDM_Odm->cck_agc_report_type == 0 && (pDM_Odm->SupportICType & ODM_RTL8192E) ) + { + switch(LNA_idx) + { + case 7: + rx_pwr_all = -45 - 2*(VGA_idx); + break; + case 6: + rx_pwr_all = -43 -2*(VGA_idx); + break; + case 5: + rx_pwr_all = -27 - 2*(VGA_idx); + break; + case 4: + rx_pwr_all = -21 - 2*(VGA_idx); + break; + case 3: + rx_pwr_all = -18 - 2*(VGA_idx); + break; + case 2: + rx_pwr_all = -6 - 2*(VGA_idx); + break; + case 1: + rx_pwr_all = 9 -2*(VGA_idx); + break; + case 0: + rx_pwr_all = 15 -2*(VGA_idx); + break; + default: + + break; + } + + if(pDM_Odm->BoardType & ODM_BOARD_EXT_LNA) + { + rx_pwr_all -= pDM_Odm->ExtLNAGain; + } + + PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); + } + else + { + 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 += 8; + + //2012.10.08 LukeLee: Modify for 92E CCK RSSI + if(pDM_Odm->SupportICType == ODM_RTL8192E) + rx_pwr_all += 8; + + 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 (pDM_Odm->SupportICType & (ODM_RTL8188F)) { +#if (RTL8188F_SUPPORT == 1) + rx_pwr_all = odm_CCKRSSI_8188F(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; + } + } + + pDM_Odm->cck_lna_idx = LNA_idx; + pDM_Odm->cck_vga_idx = VGA_idx; + 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 (DM_ODM_SUPPORT_TYPE == ODM_WIN) + 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 +#endif + 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; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) { + if (i == 0) + pPhyInfo->RxMIMOSignalStrength[0] = PWDB_ALL; + else + pPhyInfo->RxMIMOSignalStrength[1] = 0; + } + } + else //2 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; + pDM_Odm->ofdm_agc_idx[i] = (pPhyStaRpt->path_agc[i].gain & 0x3F); + + #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)); + + + if(pDM_Odm->SupportICType&ODM_RTL8192C) + { + //Modification for ext-LNA board + 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)) + //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 (DM_ODM_SUPPORT_TYPE == ODM_WIN) + 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); + } +#endif + } + } + + + // + // (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); + + + 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 >=ODM_RATEMCS8 && pPktinfo->DataRate <=ODM_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 + + //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 = SignalScaleProc(pDM_Odm->Adapter, PWDB_ALL, TRUE, TRUE); +#else + #ifdef CONFIG_SIGNAL_SCALE_MAPPING + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));/*PWDB_ALL;*/ + #else + pPhyInfo->SignalStrength = (u1Byte)PWDB_ALL; + #endif +#endif /*#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)*/ + } + 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 = SignalScaleProc(pDM_Odm->Adapter, (total_rssi /= rf_rx_num), TRUE, FALSE); + #else + #ifdef CONFIG_SIGNAL_SCALE_MAPPING + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, total_rssi /= rf_rx_num)); + #else + total_rssi/=rf_rx_num; + pPhyInfo->SignalStrength = (u1Byte)total_rssi; + #endif + #endif + } + } +#endif /*#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE))*/ + + //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_PHYDM_ANTENNA_DIVERSITY)) + //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_RxPhyBWJaguarSeries_Parsing( + OUT PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo, + IN PPHY_STATUS_RPT_8812_T pPhyStaRpt +) +{ + + if(pPktinfo->DataRate <= ODM_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; + } + } + +} + +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, EVMdbm, PWDB_ALL = 0, PWDB_ALL_BT; + u1Byte RSSI, avg_rssi = 0, best_rssi = 0, second_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; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + + odm_RxPhyBWJaguarSeries_Parsing(pPhyInfo, pPktinfo, pPhyStaRpt); + + if (pPktinfo->DataRate <= ODM_RATE11M) + isCCKrate = TRUE; + else + isCCKrate = FALSE; + + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_A] = -1; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_B] = -1; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_C] = -1; + pPhyInfo->RxMIMOSignalQuality[ODM_RF_PATH_D] = -1; + + if (isCCKrate) { + u1Byte cck_agc_rpt; + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++; + + /*(1)Hardware does not provide RSSI for CCK*/ + /*(2)PWDB, Average PWDB calculated 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 | ODM_RTL8881A)) { + 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); + } else if (pDM_Odm->SupportICType == ODM_RTL8814A || pDM_Odm->SupportICType == ODM_RTL8822B) { + s1Byte Pout = -6; + + switch (LNA_idx) { + /*CCK only use LNA: 2, 3, 5, 7*/ + case 7: + rx_pwr_all = Pout - 32 - (2 * VGA_idx); + break; + case 5: + rx_pwr_all = Pout - 22 - (2 * VGA_idx); + break; + case 3: + rx_pwr_all = Pout - 2 - (2 * VGA_idx); + break; + case 2: + rx_pwr_all = Pout + 5 - (2 * VGA_idx); + break; + /*case 6:*/ + /*rx_pwr_all = Pout -26 - (2*VGA_idx);*/ + /*break;*/ + /*case 4:*/ + /*rx_pwr_all = Pout - 8 - (2*VGA_idx);*/ + /*break;*/ + /*case 1:*/ + /*rx_pwr_all = Pout + 21 - (2*VGA_idx);*/ + /*break;*/ + /*case 0:*/ + /*rx_pwr_all = Pout + 10 - (2*VGA_idx);*/ +/* // break;*/ + default: +/* //DbgPrint("CCK Exception default\n");*/ + 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; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (i == 0) + pPhyInfo->RxMIMOSignalStrength[0] = PWDB_ALL; + else + pPhyInfo->RxMIMOSignalStrength[i] = 0; + } + } else { + /*is OFDM rate*/ + pDM_FatTable->hw_antsw_occur = pPhyStaRpt->hw_antsw_occur; + + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; + + /*(1)Get RSSI for OFDM rate*/ + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; 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))*/ + if (i < ODM_RF_PATH_C) + rx_pwr[i] = (pPhyStaRpt->gain_trsw[i] & 0x7F) - 110; + else + rx_pwr[i] = (pPhyStaRpt->gain_trsw_cd[i - 2] & 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;*/ + /*Get the best two RSSI*/ + if (RSSI > best_rssi && RSSI > second_rssi) { + second_rssi = best_rssi; + best_rssi = RSSI; + } else if (RSSI > second_rssi && RSSI <= best_rssi) + second_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; + + + /*Get Rx snr value in DB*/ + if (i < ODM_RF_PATH_C) + pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = pPhyStaRpt->rxsnr[i] / 2; + else if (pDM_Odm->SupportICType & (ODM_RTL8814A | ODM_RTL8822B)) + pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = pPhyStaRpt->csi_current[i - 2] / 2; + +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + /*(2) CFO_short & CFO_tail*/ + if (i < ODM_RF_PATH_C) { + pPhyInfo->Cfo_short[i] = odm_Cfo((pPhyStaRpt->cfosho[i])); + pPhyInfo->Cfo_tail[i] = odm_Cfo((pPhyStaRpt->cfotail[i])); + } +#endif + /* Record Signal Strength for next packet */ + if (pPktinfo->bPacketMatchBSSID) { +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + 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); + + } +#endif + } + } + + /*(3)PWDB, Average PWDB calculated 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 | ODM_RTL8881A)) && (!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 + + 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 >= ODM_RATEMCS8) && + (pPktinfo->DataRate <= ODM_RATEMCS15)) + Max_spatial_stream = 2; + else if ((pPktinfo->DataRate >= ODM_RATEVHTSS2MCS0) && + (pPktinfo->DataRate <= ODM_RATEVHTSS2MCS9)) + Max_spatial_stream = 2; + else if ((pPktinfo->DataRate >= ODM_RATEMCS16) && + (pPktinfo->DataRate <= ODM_RATEMCS23)) + Max_spatial_stream = 3; + else if ((pPktinfo->DataRate >= ODM_RATEVHTSS3MCS0) && + (pPktinfo->DataRate <= ODM_RATEVHTSS3MCS9)) + Max_spatial_stream = 3; + else + Max_spatial_stream = 1; + + if (pPktinfo->bPacketMatchBSSID) { + /*DbgPrint("pPktinfo->DataRate = %d\n", pPktinfo->DataRate);*/ + + for (i = 0; i < Max_spatial_stream; i++) { + /*Do not use shift operation like "rx_evmX >>= 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.*/ + + if (pPktinfo->DataRate >= ODM_RATE6M && pPktinfo->DataRate <= ODM_RATE54M) { + if (i == ODM_RF_PATH_A) { + EVM = odm_EVMdbToPercentage((pPhyStaRpt->sigevm)); /*dbm*/ + EVM += 20; + if (EVM > 100) + EVM = 100; + } + } else { + if (i < ODM_RF_PATH_C) { + if (pPhyStaRpt->rxevm[i] == -128) + pPhyStaRpt->rxevm[i] = -25; + EVM = odm_EVMdbToPercentage((pPhyStaRpt->rxevm[i])); /*dbm*/ + } else { + if (pPhyStaRpt->rxevm_cd[i - 2] == -128){ + pPhyStaRpt->rxevm_cd[i - 2] = -25; + } + EVM = odm_EVMdbToPercentage((pPhyStaRpt->rxevm_cd[i - 2])); /*dbm*/ + } + } + + if (i < ODM_RF_PATH_C) + EVMdbm = odm_EVMdbm_JaguarSeries(pPhyStaRpt->rxevm[i]); + else + EVMdbm = odm_EVMdbm_JaguarSeries(pPhyStaRpt->rxevm_cd[i - 2]); + /*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; +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + pPhyInfo->RxMIMOEVMdbm[i] = EVMdbm; +#endif + } + } + } + } + + 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 = SignalScaleProc(pDM_Odm->Adapter, PWDB_ALL, FALSE, TRUE); +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));/*PWDB_ALL;*/ +#endif + } else { + if (rf_rx_num != 0) { + /* 2015/01 Sean, use the best two RSSI only, suggested by Ynlin and ChenYu.*/ + if (rf_rx_num == 1) + avg_rssi = best_rssi; + else + avg_rssi = (best_rssi + second_rssi)/2; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + /* 2012/01/12 MH Use customeris signal strength from HalComRxdDesc.c/*/ + pPhyInfo->SignalStrength = SignalScaleProc(pDM_Odm->Adapter, avg_rssi, FALSE, FALSE); +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pDM_Odm, avg_rssi)); +#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; + pDM_Odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antidx_antc; + pDM_Odm->DM_FatTable.antsel_rx_keep_3 = pPhyStaRpt->antidx_antd; + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("StaID[%d]: antidx_anta = ((%d)), MatchBSSID = ((%d))\n", pPktinfo->StationID, pPhyStaRpt->antidx_anta, pPktinfo->bPacketMatchBSSID));*/ + + +/* DbgPrint("pPhyStaRpt->antidx_anta = %d, pPhyStaRpt->antidx_antb = %d\n",*/ +/* pPhyStaRpt->antidx_anta, pPhyStaRpt->antidx_antb);*/ +/* DbgPrint("----------------------------\n");*/ +/* DbgPrint("pPktinfo->StationID=%d, pPktinfo->DataRate=0x%x\n",pPktinfo->StationID, pPktinfo->DataRate);*/ +/* DbgPrint("pPhyStaRpt->r_RFMOD = %d\n", pPhyStaRpt->r_RFMOD);*/ +/* DbgPrint("pPhyStaRpt->gain_trsw[0]=0x%x, pPhyStaRpt->gain_trsw[1]=0x%x\n",*/ +/* pPhyStaRpt->gain_trsw[0],pPhyStaRpt->gain_trsw[1]);*/ +/* DbgPrint("pPhyStaRpt->gain_trsw[2]=0x%x, pPhyStaRpt->gain_trsw[3]=0x%x\n",*/ +/* pPhyStaRpt->gain_trsw_cd[0],pPhyStaRpt->gain_trsw_cd[1]);*/ +/* DbgPrint("pPhyStaRpt->pwdb_all = 0x%x, pPhyInfo->RxPWDBAll = %d\n", pPhyStaRpt->pwdb_all, pPhyInfo->RxPWDBAll);*/ +/* DbgPrint("pPhyStaRpt->cfotail[i] = 0x%x, pPhyStaRpt->CFO_tail[i] = 0x%x\n", pPhyStaRpt->cfotail[0], pPhyStaRpt->cfotail[1]);*/ +/* DbgPrint("pPhyStaRpt->rxevm[0] = %d, pPhyStaRpt->rxevm[1] = %d\n", pPhyStaRpt->rxevm[0], pPhyStaRpt->rxevm[1]);*/ +/* DbgPrint("pPhyStaRpt->rxevm[2] = %d, pPhyStaRpt->rxevm[3] = %d\n", pPhyStaRpt->rxevm_cd[0], pPhyStaRpt->rxevm_cd[1]);*/ +/* DbgPrint("pPhyInfo->RxMIMOSignalStrength[0]=%d, pPhyInfo->RxMIMOSignalStrength[1]=%d, RxPWDBAll=%d\n",*/ +/* pPhyInfo->RxMIMOSignalStrength[0], pPhyInfo->RxMIMOSignalStrength[1], pPhyInfo->RxPWDBAll);*/ +/* DbgPrint("pPhyInfo->RxMIMOSignalStrength[2]=%d, pPhyInfo->RxMIMOSignalStrength[3]=%d\n",*/ +/* pPhyInfo->RxMIMOSignalStrength[2], pPhyInfo->RxMIMOSignalStrength[3]);*/ +/* DbgPrint("ppPhyInfo->RxMIMOSignalQuality[0]=%d, pPhyInfo->RxMIMOSignalQuality[1]=%d\n",*/ +/* pPhyInfo->RxMIMOSignalQuality[0], pPhyInfo->RxMIMOSignalQuality[1]);*/ +/* DbgPrint("ppPhyInfo->RxMIMOSignalQuality[2]=%d, pPhyInfo->RxMIMOSignalQuality[3]=%d\n",*/ +/* pPhyInfo->RxMIMOSignalQuality[2], pPhyInfo->RxMIMOSignalQuality[3]);*/ + +} + +#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 (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + #endif + + if (pPktinfo->StationID >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + #ifdef CONFIG_S0S1_SW_ANTENNA_DIVERSITY + odm_S0S1_SwAntDivByCtrlFrame_ProcessRSSI(pDM_Odm, pPhyInfo, pPktinfo); + #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 (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + if ((pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) && + (pDM_FatTable->enable_ctrl_frame_antdiv) + ) + { + if (pPktinfo->bPacketMatchBSSID) + pDM_Odm->data_frame_num++; + + if ((pDM_FatTable->use_ctrl_frame_antdiv)) { + if (!pPktinfo->bToSelf)/*data frame + CTRL frame*/ + return; + } else { + if ((!pPktinfo->bPacketMatchBSSID))/*data frame only*/ + return; + } + } else +#endif + { + if ((!pPktinfo->bPacketMatchBSSID))/*data frame only*/ + return; + } + + if(pPktinfo->bPacketBeacon) + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt++; + + isCCKrate = (pPktinfo->DataRate <= ODM_RATE11M )?TRUE :FALSE; + pDM_Odm->RxRate = pPktinfo->DataRate; + + //--------------Statistic for antenna/path diversity------------------ + if(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV) + { + #if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + ODM_Process_RSSIForAntDiv(pDM_Odm,pPhyInfo,pPktinfo); + #endif + } + #if(defined(CONFIG_PATH_DIVERSITY)) + else if(pDM_Odm->SupportAbility & ODM_BB_PATH_DIV) + { + phydm_process_rssi_for_path_div(pDM_Odm,pPhyInfo,pPktinfo); + } + #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 (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B)) { + u1Byte RX_count = 0; + u4Byte RSSI_linear = 0; + + if (pDM_Odm->RXAntStatus & ODM_RF_A) { + pDM_Odm->RSSI_A = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + RX_count++; + RSSI_linear += odm_ConvertTo_linear(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]); + } else + pDM_Odm->RSSI_A = 0; + + if (pDM_Odm->RXAntStatus & ODM_RF_B) { + pDM_Odm->RSSI_B = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]; + RX_count++; + RSSI_linear += odm_ConvertTo_linear(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]); + } else + pDM_Odm->RSSI_B = 0; + + if (pDM_Odm->RXAntStatus & ODM_RF_C) { + pDM_Odm->RSSI_C = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_C]; + RX_count++; + RSSI_linear += odm_ConvertTo_linear(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_C]); + } else + pDM_Odm->RSSI_C = 0; + + if (pDM_Odm->RXAntStatus & ODM_RF_D) { + pDM_Odm->RSSI_D = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_D]; + RX_count++; + RSSI_linear += odm_ConvertTo_linear(pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_D]); + } else + pDM_Odm->RSSI_D = 0; + + /* Calculate average RSSI */ + switch (RX_count) { + case 2: + RSSI_linear = (RSSI_linear >> 1); + break; + case 3: + RSSI_linear = ((RSSI_linear) + (RSSI_linear << 1) + (RSSI_linear << 3)) >> 5; /* RSSI_linear/3 ~ RSSI_linear*11/32 */ + break; + case 4: + RSSI_linear = (RSSI_linear >> 2); + break; + } + RSSI_Ave = odm_ConvertTo_dB(RSSI_linear); + } else +#endif + { + 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); + } + } + if (pEntry->rssi_stat.OFDM_pkt != 64) { + i = 63; + pEntry->rssi_stat.OFDM_pkt -= (u4Byte)(((pEntry->rssi_stat.PacketMap>>i)&BIT0)-1); + } + 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 = 0xFF; + pDM_Odm->RSSI_C = 0xFF; + pDM_Odm->RSSI_D = 0xFF; + + //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); + } + } + i = 63; + pEntry->rssi_stat.OFDM_pkt -= (u4Byte)((pEntry->rssi_stat.PacketMap>>i)&BIT0); + 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.OFDM_pkt == 64) { /* speed up when all packets are OFDM*/ + UndecoratedSmoothedPWDB = UndecoratedSmoothedOFDM; + } else { + if (pEntry->rssi_stat.ValidBit < 64) + pEntry->rssi_stat.ValidBit++; + + if (pEntry->rssi_stat.ValidBit == 64) { + Weighting = ((pEntry->rssi_stat.OFDM_pkt<<4) > 64)?64:(pEntry->rssi_stat.OFDM_pkt<<4); + UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6; + } else { + if (pEntry->rssi_stat.ValidBit != 0) + UndecoratedSmoothedPWDB = (pEntry->rssi_stat.OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-pEntry->rssi_stat.OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit; + else + UndecoratedSmoothedPWDB = 0; + } + } + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB == -1) + phydm_ra_rssi_rpt_wk(pDM_Odm); + #endif + 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); + odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo); +} +#endif + + +// +// Endianness before calling this API +// +#if ODM_IC_11AC_SERIES_SUPPORT + +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); +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + //phydm_sbd_check(pDM_Odm); +#endif +} +#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 (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType & ODM_RTL8822B) { + phydm_RxPhyStatusJaguarSeries2(pDM_Odm, pPhyStatus, pPktinfo, pPhyInfo); + return; + } +#endif + +#if ODM_IC_11AC_SERIES_SUPPORT + if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) + ODM_PhyStatusQuery_JaguarSeries(pDM_Odm, pPhyInfo, pPhyStatus, pPktinfo); +#endif + +#if ODM_IC_11N_SERIES_SUPPORT + 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 + ) +{ +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); +#endif + + 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)); + +//1 AP doesn't use PHYDM power tracking table in these ICs +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#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 (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) { + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) && (DEV_BUS_TYPE == RT_PCI_INTERFACE) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + if ((pHalData->EEPROMSVID == 0x17AA && pHalData->EEPROMSMID == 0xA811) || + (pHalData->EEPROMSVID == 0x10EC && pHalData->EEPROMSMID == 0xA812) || + (pHalData->EEPROMSVID == 0x10EC && pHalData->EEPROMSMID == 0x8812)) + READ_AND_CONFIG_MP(8812A,_TXPWR_LMT_HM812A03); + else + #endif + 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 { + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if (pMgntInfo->CustomerID == RT_CID_8821AE_ASUS_MB) + READ_AND_CONFIG_MP(8821A,_TXPWR_LMT_8821A_SAR_8mm); + else if (pMgntInfo->CustomerID == RT_CID_ASUS_NB) + READ_AND_CONFIG_MP(8821A,_TXPWR_LMT_8821A_SAR_5mm); + else + #endif + 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) { +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) && (DEV_BUS_TYPE == RT_PCI_INTERFACE) /*Refine by Vincent Lan for 5mm SAR pwr limit*/ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + if ((pHalData->EEPROMSVID == 0x11AD && pHalData->EEPROMSMID == 0x8192) || + (pHalData->EEPROMSVID == 0x11AD && pHalData->EEPROMSMID == 0x8193)) + READ_AND_CONFIG_MP(8192E, _TXPWR_LMT_8192E_SAR_5mm); + else +#endif + READ_AND_CONFIG_MP(8192E,_TXPWR_LMT); + } + } +#endif +#endif//(DM_ODM_SUPPORT_TYPE != ODM_AP) + +//1 All platforms support +#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 (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8814A,_RadioA); + else if(eRFPath == ODM_RF_PATH_B) + READ_AND_CONFIG_MP(8814A,_RadioB); + else if(eRFPath == ODM_RF_PATH_C) + READ_AND_CONFIG_MP(8814A,_RadioC); + else if(eRFPath == ODM_RF_PATH_D) + READ_AND_CONFIG_MP(8814A,_RadioD); + } + else if(ConfigType == CONFIG_RF_TXPWR_LMT) + READ_AND_CONFIG_MP(8814A,_TXPWR_LMT); + } +#endif +#if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8703B) { + if (ConfigType == CONFIG_RF_RADIO) { + if (eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8703B, _RadioA); + } + } +#endif + +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) { + if (ConfigType == CONFIG_RF_RADIO) { + if (eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8188F, _RadioA); + } else if (ConfigType == CONFIG_RF_TXPWR_LMT) + READ_AND_CONFIG_MP(8188F, _TXPWR_LMT); + } +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (RTL8821B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821B) + { + if (ConfigType == CONFIG_RF_RADIO) { + if (eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG(8821B, _RadioA); + } else if (ConfigType == CONFIG_RF_TXPWR_LMT) + READ_AND_CONFIG(8821B, _TXPWR_LMT); + } +#endif +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8822B) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8822B, _RadioA); + else if(eRFPath == ODM_RF_PATH_B) + READ_AND_CONFIG_MP(8822B, _RadioB); + } + } +#endif +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + { + if(ConfigType == CONFIG_RF_RADIO) { + if(eRFPath == ODM_RF_PATH_A) + READ_AND_CONFIG_TC(8188F,_RadioA); + } + } +#endif +#endif +#endif//(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + 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)); + + +//1 AP doesn't use PHYDM power tracking table in these ICs +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#if RTL8821A_SUPPORT + 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 if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8821A,_TxPowerTrack_SDIO); + } +#endif +#if RTL8812A_SUPPORT + 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 + 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); + else if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8192E,_TxPowerTrack_SDIO); + } +#endif +#if RTL8723B_SUPPORT + 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 + 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 if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8188E,_TxPowerTrack_SDIO); + } +#endif +#endif//(DM_ODM_SUPPORT_TYPE != ODM_AP) + +//1 All platforms support +#if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType == ODM_RTL8814A) + { + if(pDM_Odm->RFEType == 0) + READ_AND_CONFIG_MP(8814A,_TxPowerTrack_Type0); + else if(pDM_Odm->RFEType == 2) + READ_AND_CONFIG_MP(8814A,_TxPowerTrack_Type2); + else if (pDM_Odm->RFEType == 5) + READ_AND_CONFIG_MP(8814A, _TxPowerTrack_Type5); + else + READ_AND_CONFIG_MP(8814A,_TxPowerTrack); + } +#endif +#if RTL8703B_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8703B) { + if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8703B, _TxPowerTrack_USB); + else if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8703B, _TxPowerTrack_SDIO); + } +#endif + +#if RTL8188F_SUPPORT + if (pDM_Odm->SupportICType == ODM_RTL8188F) { + if (pDM_Odm->SupportInterface == ODM_ITRF_USB) + READ_AND_CONFIG_MP(8188F, _TxPowerTrack_USB); + else if (pDM_Odm->SupportInterface == ODM_ITRF_SDIO) + READ_AND_CONFIG_MP(8188F, _TxPowerTrack_SDIO); + } +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if RTL8821B_SUPPORT + if(pDM_Odm->SupportICType == ODM_RTL8821B) + READ_AND_CONFIG(8821B,_TxPowerTrack); +#endif +#if RTL8822B_SUPPORT +/* if(pDM_Odm->SupportICType == ODM_RTL8822B) + READ_AND_CONFIG_MP(8822B, _TxPowerTrack); */ +#endif + +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if RTL8188F_SUPPORT + if(pDM_Odm->SupportICType == ODM_RTL8188F) + READ_AND_CONFIG_TC(8188F,_TxPowerTrack_PCIE); +#endif +#endif +#endif//(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + + 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_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); +#endif + +//1 AP doesn't use PHYDM initialization in these ICs +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#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 (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); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> phy_ConfigBBWithHeaderFile() phy:Rtl8812AGCTABArray\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> phy_ConfigBBWithHeaderFile() agc:Rtl8812PHY_REGArray\n")); + } +#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); + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> phy_ConfigBBWithHeaderFile() phy:Rtl8821AGCTABArray\n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> phy_ConfigBBWithHeaderFile() agc:Rtl8821PHY_REGArray\n")); + } +#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 +#endif//(DM_ODM_SUPPORT_TYPE != ODM_AP) + + +//1 All platforms support +#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 (RTL8814A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8814A) + { + if(ConfigType == CONFIG_BB_PHY_REG){ + READ_AND_CONFIG_MP(8814A,_PHY_REG); + }else if(ConfigType == CONFIG_BB_AGC_TAB){ + READ_AND_CONFIG_MP(8814A,_AGC_TAB); + }else if(ConfigType == CONFIG_BB_PHY_REG_PG){ + READ_AND_CONFIG_MP(8814A,_PHY_REG_PG); + }else if(ConfigType == CONFIG_BB_PHY_REG_MP){ + READ_AND_CONFIG_MP(8814A,_PHY_REG_MP); + } + } +#endif +#if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8703B) { + if (ConfigType == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8703B, _PHY_REG); + else if (ConfigType == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8703B, _AGC_TAB); + else if (ConfigType == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_MP(8703B, _PHY_REG_PG); + } +#endif + +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) { + if (ConfigType == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8188F, _PHY_REG); + else if (ConfigType == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8188F, _AGC_TAB); + else if (ConfigType == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_MP(8188F, _PHY_REG_PG); + } +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (RTL8821B_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8821B) + { + if (ConfigType == CONFIG_BB_PHY_REG) { + READ_AND_CONFIG(8821B,_PHY_REG); + } else if (ConfigType == CONFIG_BB_AGC_TAB) { + READ_AND_CONFIG(8821B,_AGC_TAB); + } else if (ConfigType == CONFIG_BB_PHY_REG_PG) { + READ_AND_CONFIG(8821B,_PHY_REG_PG); + } + } +#endif +#if (RTL8822B_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8822B) + { + if(ConfigType == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8822B, _PHY_REG); + else if(ConfigType == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8822B, _AGC_TAB); +/* else if(ConfigType == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_MP(8822B, _PHY_REG_PG); + else if(ConfigType == CONFIG_BB_PHY_REG_MP) + READ_AND_CONFIG_MP(8822B, _PHY_REG_MP); */ + } +#endif +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if (RTL8188F_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8188F) + { + if(ConfigType == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_TC(8188F,_PHY_REG); + else if(ConfigType == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_TC(8188F,_AGC_TAB); + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_TC(8188F,_PHY_REG_PG); + } +#endif +#endif +#if (RTL8195A_SUPPORT == 1) + if(pDM_Odm->SupportICType == ODM_RTL8195A) + { + if(ConfigType == CONFIG_BB_PHY_REG) + READ_AND_CONFIG(8195A,_PHY_REG); + else if(ConfigType == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG(8195A,_AGC_TAB); + else if(ConfigType == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG(8195A,_PHY_REG_PG); + } +#endif +#endif//(DM_ODM_SUPPORT_TYPE & ODM_WIN) + + return HAL_STATUS_SUCCESS; +} + +HAL_STATUS +ODM_ConfigMACWithHeaderFile( + IN PDM_ODM_T pDM_Odm + ) +{ +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); +#endif + + 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)); + +//1 AP doesn't use PHYDM initialization in these ICs +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#if (RTL8723A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8723A){ + READ_AND_CONFIG_MP(8723A,_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 +#endif//(DM_ODM_SUPPORT_TYPE != ODM_AP) + +//1 All platforms support +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E){ + READ_AND_CONFIG_MP(8188E,_MAC_REG); + } +#endif +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A){ + READ_AND_CONFIG_MP(8814A,_MAC_REG); + } +#endif +#if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8703B) + READ_AND_CONFIG_MP(8703B, _MAC_REG); +#endif + +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + READ_AND_CONFIG_MP(8188F, _MAC_REG); +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (RTL8821B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821B){ + READ_AND_CONFIG(8821B,_MAC_REG); + } +#endif +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8822B) + READ_AND_CONFIG_MP(8822B, _MAC_REG); +#endif + +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + READ_AND_CONFIG_TC(8188F,_MAC_REG); +#endif +#endif +#if (RTL8195A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8195A) + READ_AND_CONFIG_MP(8195A,_MAC_REG); +#endif +#endif /*#if (DM_ODM_SUPPORT_TYPE & ODM_WIN)*/ + + return HAL_STATUS_SUCCESS; +} + +HAL_STATUS +ODM_ConfigFWWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_FW_Config_Type ConfigType, + OUT u1Byte *pFirmware, + OUT u4Byte *pSize + ) +{ +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + { + #ifdef CONFIG_SFW_SUPPORTED + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8188E_T,_FW_NIC); + else if (ConfigType == CONFIG_FW_WoWLAN) + READ_FIRMWARE_MP(8188E_T,_FW_WoWLAN); + else if(ConfigType == CONFIG_FW_NIC_2) + READ_FIRMWARE_MP(8188E_S,_FW_NIC); + else if (ConfigType == CONFIG_FW_WoWLAN_2) + READ_FIRMWARE_MP(8188E_S,_FW_WoWLAN); + #ifdef CONFIG_AP_WOWLAN + if (ConfigType == CONFIG_FW_AP) + READ_FIRMWARE_MP(8188E_T,_FW_AP); + else if (ConfigType == CONFIG_FW_AP_2) + READ_FIRMWARE_MP(8188E_S,_FW_AP); + #endif //CONFIG_AP_WOWLAN + #else + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8188E_T,_FW_NIC); + else if (ConfigType == CONFIG_FW_WoWLAN) + READ_FIRMWARE_MP(8188E_T,_FW_WoWLAN); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP) + READ_FIRMWARE_MP(8188E_T,_FW_AP); + #endif //CONFIG_AP_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 + + } +#endif //#if (RTL8723B_SUPPORT == 1) +#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); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + READ_FIRMWARE(8812A,_FW_AP); + #endif + } +#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); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + READ_FIRMWARE_MP(8821A , _FW_AP); + #endif /*CONFIG_AP_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); + #endif + } +#endif +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A) + { + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8814A,_FW_NIC); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + READ_FIRMWARE_MP(8814A,_FW_AP); + #endif + } +#endif +#if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8703B) { + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8703B, _FW_NIC); + else if (ConfigType == CONFIG_FW_WoWLAN) + READ_FIRMWARE_MP(8703B, _FW_WoWLAN); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + READ_FIRMWARE(8703B, _FW_AP_WoWLAN); + #endif + } +#endif + +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) { + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8188F, _FW_NIC); + else if (ConfigType == CONFIG_FW_WoWLAN) + READ_FIRMWARE_MP(8188F, _FW_WoWLAN); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP) + READ_FIRMWARE_MP(8188F,_FW_AP); + #endif + } +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#if (RTL8821B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821B) + { + } +#endif +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8822B) + { + /* + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8822B,_FW_NIC); + #ifdef CONFIG_AP_WOWLAN + else if (ConfigType == CONFIG_FW_AP_WoWLAN) + READ_FIRMWARE(8822B,_FW_AP); + #endif */ + } +#endif +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + { + if (ConfigType == CONFIG_FW_NIC) + READ_FIRMWARE_MP(8188F,_FW_NIC); + } +#endif +#endif +#endif//(DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#endif//(DM_ODM_SUPPORT_TYPE != ODM_AP) + return HAL_STATUS_SUCCESS; +} + +u4Byte +ODM_GetHWImgVersion( + IN PDM_ODM_T pDM_Odm + ) +{ + u4Byte Version=0; + +//1 AP doesn't use PHYDM initialization in these ICs +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#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 (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 +#endif //(DM_ODM_SUPPORT_TYPE != ODM_AP) + +/*1 All platforms support*/ +#if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + Version = GET_VERSION_MP(8188E,_MAC_REG); +#endif +#if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A) + Version = GET_VERSION_MP(8814A,_MAC_REG); +#endif +#if (RTL8703B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8703B) + Version = GET_VERSION_MP(8703B, _MAC_REG); +#endif +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + Version = GET_VERSION_MP(8188F, _MAC_REG); +#endif + +//1 New ICs (WIN only) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#if (RTL8821B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8821B) + Version = GET_VERSION(8821B,_MAC_REG); +#endif +#if (RTL8822B_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8822B) + Version = GET_VERSION(8822B, _MAC_REG); +#endif +#if ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) +#if (RTL8188F_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188F) + Version = GET_VERSION_TC(8188F, _MAC_REG); +#endif +#endif +#endif //(DM_ODM_SUPPORT_TYPE == ODM_WIN) + + return Version; +} + +#if (RTL8822B_SUPPORT == 1) +/* For 8822B only!! need to move to FW finally */ +/*==============================================*/ + +VOID +phydm_ResetPhyInfo( + IN PDM_ODM_T pPhydm, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + pPhyInfo->RxPWDBAll = 0; + pPhyInfo->SignalQuality = 0; + pPhyInfo->BandWidth = 0; +#if (RTL8822B_SUPPORT == 1) + pPhyInfo->RxCount = 0; +#endif + ODM_Memory_Set(pPhydm, pPhyInfo->RxMIMOSignalQuality, 0 , 4); + ODM_Memory_Set(pPhydm, pPhyInfo->RxMIMOSignalStrength, 0, 4); + ODM_Memory_Set(pPhydm, pPhyInfo->RxSNR, 0, 4); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->RxPower = -110; + pPhyInfo->RecvSignalPower = -110; + pPhyInfo->BTRxRSSIPercentage = 0; + pPhyInfo->SignalStrength = 0; + pPhyInfo->btCoexPwrAdjust = 0; +#if (RTL8822B_SUPPORT == 1) + pPhyInfo->channel = 0; + pPhyInfo->bMuPacket = 0; + pPhyInfo->bBeamformed = 0; + pPhyInfo->rxsc = 0; +#endif + ODM_Memory_Set(pPhydm, pPhyInfo->RxPwr, -110, 4); + ODM_Memory_Set(pPhydm, pPhyInfo->RxMIMOEVMdbm, 0, 4); + ODM_Memory_Set(pPhydm, pPhyInfo->Cfo_short, 0, 8); + ODM_Memory_Set(pPhydm, pPhyInfo->Cfo_tail, 0, 8); +#endif +} + +VOID +phydm_SetPerPathPhyInfo( + IN u1Byte RxPath, + IN s1Byte RxPwr, + IN s1Byte RxEVM, + IN s1Byte Cfo_tail, + IN s1Byte RxSNR, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + u1Byte EVMdBm = 0; + u1Byte EVMPercentage = 0; + + /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */ + + if (RxEVM < 0) { + /* Calculate EVM in dBm */ + EVMdBm = ((u1Byte)(0 - RxEVM) >> 1); + + /* Calculate EVM in percentage */ + if (EVMdBm >= 33) + EVMPercentage = 100; + else + EVMPercentage = (EVMdBm << 1) + (EVMdBm); + } + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->RxPwr[RxPath] = RxPwr; + pPhyInfo->RxMIMOEVMdbm[RxPath] = EVMdBm; + + /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/ + pPhyInfo->Cfo_tail[RxPath] = Cfo_tail; + pPhyInfo->Cfo_tail[RxPath] = ((pPhyInfo->Cfo_tail[RxPath] << 5) + (pPhyInfo->Cfo_tail[RxPath] << 2) + + (pPhyInfo->Cfo_tail[RxPath] << 1) + (pPhyInfo->Cfo_tail[RxPath])) >> 9; +#endif + + pPhyInfo->RxMIMOSignalStrength[RxPath] = odm_QueryRxPwrPercentage(RxPwr); + pPhyInfo->RxMIMOSignalQuality[RxPath] = EVMPercentage; + pPhyInfo->RxSNR[RxPath] = RxSNR >> 1; + +/* + //if (pPktinfo->bPacketMatchBSSID) + { + DbgPrint("Path (%d)--------\n", RxPath); + DbgPrint("RxPwr = %d, Signal strength = %d\n", pPhyInfo->RxPwr[RxPath], pPhyInfo->RxMIMOSignalStrength[RxPath]); + DbgPrint("EVMdBm = %d, Signal quality = %d\n", pPhyInfo->RxMIMOEVMdbm[RxPath], pPhyInfo->RxMIMOSignalQuality[RxPath]); + DbgPrint("CFO = %d, SNR = %d\n", pPhyInfo->Cfo_tail[RxPath], pPhyInfo->RxSNR[RxPath]); + } +*/ +} + +VOID +phydm_SetCommonPhyInfo( + IN s1Byte RxPower, + IN u1Byte channel, + IN BOOLEAN bBeamformed, + IN BOOLEAN bMuPacket, + IN u1Byte bandwidth, + IN u1Byte signalQuality, + IN u1Byte rxsc, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + pPhyInfo->RxPower = RxPower; /* RSSI in dB */ + pPhyInfo->RecvSignalPower = RxPower; /* RSSI in dB */ + pPhyInfo->channel = channel; /* channel number */ + pPhyInfo->bBeamformed = bBeamformed; /* apply BF */ + pPhyInfo->bMuPacket = bMuPacket; /* MU packet */ + pPhyInfo->rxsc = rxsc; +#endif + pPhyInfo->RxPWDBAll = odm_QueryRxPwrPercentage(RxPower); /* RSSI in percentage */ + pPhyInfo->SignalQuality = signalQuality; /* signal quality */ + pPhyInfo->BandWidth = bandwidth; /* bandwidth */ + +/* + //if (pPktinfo->bPacketMatchBSSID) + { + DbgPrint("RxPWDBAll = %d, RxPower = %d, RecvSignalPower = %d\n", pPhyInfo->RxPWDBAll, pPhyInfo->RxPower, pPhyInfo->RecvSignalPower); + DbgPrint("SignalQuality = %d\n", pPhyInfo->SignalQuality); + DbgPrint("bBeamformed = %d, bMuPacket = %d, RxCount = %d\n", pPhyInfo->bBeamformed, pPhyInfo->bMuPacket, pPhyInfo->RxCount + 1); + DbgPrint("channel = %d, rxsc = %d, BandWidth = %d\n", channel, rxsc, bandwidth); + } +*/ +} + +VOID +phydm_GetRxPhyStatusType0( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + /* Type 0 is used for cck packet */ + + PPHY_STATUS_RPT_JAGUAR2_TYPE0 pPhyStaRpt = (PPHY_STATUS_RPT_JAGUAR2_TYPE0)pPhyStatus; + u1Byte i, SQ = 0; + + /* Calculate Signal Quality*/ + if (pPktinfo->bPacketMatchBSSID) { + if (pPhyStaRpt->signal_quality >= 64) + SQ = 0; + else if (pPhyStaRpt->signal_quality <= 20) + SQ = 100; + else { + /* mapping to 2~99% */ + SQ = 64 - pPhyStaRpt->signal_quality; + SQ = ((SQ << 3) + SQ) >> 2; + } + } + + /* Update CCK packet counter */ + pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++; + + /* Update Common information */ + phydm_SetCommonPhyInfo((pPhyStaRpt->pwdb - 110), pPhyStaRpt->channel, FALSE, + FALSE, ODM_BW20M, SQ, pPhyStaRpt->rxsc, pPhyInfo); + + /* Update CCK pwdb */ + phydm_SetPerPathPhyInfo(ODM_RF_PATH_A, (pPhyStaRpt->pwdb - 110), 0, 0, 0, pPhyInfo); /* Update per-path information */ + +/* + //if (pPktinfo->bPacketMatchBSSID) + { + DbgPrint("pwdb = 0x%x, MP gain index = 0x%x, TRSW = 0x%x\n", pPhyStaRpt->pwdb, pPhyStaRpt->gain, pPhyStaRpt->trsw); + DbgPrint("channel = %d, band = %d, rxsc = %d\n", pPhyStaRpt->channel, pPhyStaRpt->band, pPhyStaRpt->rxsc); + DbgPrint("agc_table = 0x%x, agc_rpt 0x%x, bb_power = 0x%x\n", pPhyStaRpt->agc_table, pPhyStaRpt->agc_rpt, pPhyStaRpt->bb_power); + DbgPrint("length = %d, SQ = %d\n", pPhyStaRpt->length, pPhyStaRpt->signal_quality); + DbgPrint("antidx a = 0x%x, b = 0x%x, c = 0x%x, d = 0x%x\n", pPhyStaRpt->antidx_a, pPhyStaRpt->antidx_b, pPhyStaRpt->antidx_c, pPhyStaRpt->antidx_d); + DbgPrint("rsvd_0 = 0x%x, rsvd_1 = 0x%x, rsvd_2 = 0x%x\n", pPhyStaRpt->rsvd_0, pPhyStaRpt->rsvd_1, pPhyStaRpt->rsvd_2); + DbgPrint("rsvd_3 = 0x%x, rsvd_4 = 0x%x, rsvd_5 = 0x%x\n", pPhyStaRpt->rsvd_3, pPhyStaRpt->rsvd_4, pPhyStaRpt->rsvd_5); + DbgPrint("rsvd_6 = 0x%x, rsvd_7 = 0x%x, rsvd_8 = 0x%x\n", pPhyStaRpt->rsvd_6, pPhyStaRpt->rsvd_7, pPhyStaRpt->rsvd_8); + } +*/ +} + +VOID +phydm_GetRxPhyStatusType1( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + /* Type 1 is used for ofdm packet */ + + PPHY_STATUS_RPT_JAGUAR2_TYPE1 pPhyStaRpt = (PPHY_STATUS_RPT_JAGUAR2_TYPE1)pPhyStatus; + s1Byte rx_pwr_db = -120; + u1Byte i, rxsc, bw, RxCount = 0; + BOOLEAN bMU; + + /* Update OFDM packet counter */ + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (pDM_Odm->RXAntStatus & BIT(i)) { + s1Byte rx_path_pwr_db; + + /* RX path counter */ + RxCount++; + + /* Update per-path information (RSSI_dB RSSI_percentage EVM SNR CFO SQ) */ + /* EVM report is reported by stream, not path */ + rx_path_pwr_db = pPhyStaRpt->pwdb[i] - 110; /* per-path pwdb in dB domain */ + phydm_SetPerPathPhyInfo(i, rx_path_pwr_db, pPhyStaRpt->rxevm[RxCount - 1], + pPhyStaRpt->cfo_tail[i], pPhyStaRpt->rxsnr[i], pPhyInfo); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (RxCount > 0) + pPhyInfo->RxCount = RxCount - 1; + + /* Check if MU packet or not */ + if ((pPhyStaRpt->gid != 0) && (pPhyStaRpt->gid != 63)) { + bMU = TRUE; + pDM_Odm->PhyDbgInfo.NumQryMuPkt++; + } else + bMU = FALSE; + + /* Count BF packet */ + pDM_Odm->PhyDbgInfo.NumQryBfPkt = pDM_Odm->PhyDbgInfo.NumQryBfPkt + pPhyStaRpt->beamformed; + + /* Check sub-channel */ + if ((pPktinfo->DataRate > ODM_RATE11M) && (pPktinfo->DataRate < ODM_RATEMCS0)) + rxsc = pPhyStaRpt->l_rxsc; + else + rxsc = pPhyStaRpt->ht_rxsc; + + /* Check RX bandwidth */ + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = pPhyStaRpt->rf_mode; + + /* Update packet information */ + phydm_SetCommonPhyInfo(rx_pwr_db, pPhyStaRpt->channel, (BOOLEAN)pPhyStaRpt->beamformed, + bMU, bw, odm_EVMdbToPercentage(pPhyStaRpt->rxevm[0]), rxsc, pPhyInfo); + +/* + //if (pPktinfo->bPacketMatchBSSID) + { + DbgPrint("channel = %d, band = %d, l_rxsc = %d, ht_rxsc = %d, rf_mode = %d\n", pPhyStaRpt->channel, pPhyStaRpt->band, pPhyStaRpt->l_rxsc, pPhyStaRpt->ht_rxsc, pPhyStaRpt->rf_mode); + DbgPrint("Antidx A = %d, B = %d, C = %d, D = %d\n", pPhyStaRpt->antidx_a, pPhyStaRpt->antidx_b, pPhyStaRpt->antidx_c, pPhyStaRpt->antidx_d); + DbgPrint("pwdb A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->pwdb[0], pPhyStaRpt->pwdb[1], pPhyStaRpt->pwdb[2], pPhyStaRpt->pwdb[3]); + DbgPrint("EVM A: %d, B: %d, C: %d, D: %d\n", pPhyStaRpt->rxevm[0], pPhyStaRpt->rxevm[1], pPhyStaRpt->rxevm[2], pPhyStaRpt->rxevm[3]); + DbgPrint("SNR A: %d, B: %d, C: %d, D: %d\n", pPhyStaRpt->rxsnr[0], pPhyStaRpt->rxsnr[1], pPhyStaRpt->rxsnr[2], pPhyStaRpt->rxsnr[3]); + DbgPrint("CFO A: %d, B: %d, C: %d, D: %d\n", pPhyStaRpt->cfo_tail[0], pPhyStaRpt->cfo_tail[1], pPhyStaRpt->cfo_tail[2], pPhyStaRpt->cfo_tail[3]); + DbgPrint("paid = %d, gid = %d, length = %d\n", (pPhyStaRpt->paid + (pPhyStaRpt->paid_msb<<8)), pPhyStaRpt->gid, pPhyStaRpt->lsig_length); + DbgPrint("ldpc: %d, stbc: %d, bf: %d, gnt_bt: %d, antsw: %d\n", pPhyStaRpt->ldpc, pPhyStaRpt->stbc, pPhyStaRpt->beamformed, pPhyStaRpt->gnt_bt, pPhyStaRpt->hw_antsw_occu); + DbgPrint("NBI: %d, pos: %d\n", pPhyStaRpt->nb_intf_flag, (pPhyStaRpt->intf_pos + (pPhyStaRpt->intf_pos_msb<<8))); + DbgPrint("rsvd_0 = %d, rsvd_1 = %d, rsvd_2 = %d, rsvd_3 = %d, rsvd_4 = %d, rsvd_5 = %d\n", pPhyStaRpt->rsvd_0, pPhyStaRpt->rsvd_1, pPhyStaRpt->rsvd_2, pPhyStaRpt->rsvd_3, pPhyStaRpt->rsvd_4, pPhyStaRpt->rsvd_5); + } + DbgPrint("phydm_GetRxPhyStatusType1 pPktinfo->bPacketMatchBSSID = %d\n", pPktinfo->bPacketMatchBSSID); + DbgPrint("pPktinfo->DataRate = 0x%x\n", pPktinfo->DataRate); +*/ +} + +VOID +phydm_GetRxPhyStatusType2( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + PPHY_STATUS_RPT_JAGUAR2_TYPE2 pPhyStaRpt = (PPHY_STATUS_RPT_JAGUAR2_TYPE2)pPhyStatus; + s1Byte rx_pwr_db = -120; + u1Byte i, rxsc, bw, RxCount = 0; + + /* Update OFDM packet counter */ + pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (pDM_Odm->RXAntStatus & BIT(i)) { + s1Byte rx_path_pwr_db; + + /* RX path counter */ + RxCount++; + + /* Update per-path information (RSSI_dB RSSI_percentage EVM SNR CFO SQ) */ + rx_path_pwr_db = pPhyStaRpt->pwdb[i] - 110; /* per-path pwdb in dB domain */ + phydm_SetPerPathPhyInfo(i, rx_path_pwr_db, 0, 0, 0, pPhyInfo); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (RxCount > 0) + pPhyInfo->RxCount = RxCount - 1; + + /* Check RX sub-channel */ + if ((pPktinfo->DataRate > ODM_RATE11M) && (pPktinfo->DataRate < ODM_RATEMCS0)) + rxsc = pPhyStaRpt->l_rxsc; + else + rxsc = pPhyStaRpt->ht_rxsc; + + /* Check RX bandwidth */ + /* the BW information of sc=0 is useless, because there is no information of RF mode*/ + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = ODM_BW20M; + + /* Update packet information */ + phydm_SetCommonPhyInfo(rx_pwr_db, pPhyStaRpt->channel, (BOOLEAN)pPhyStaRpt->beamformed, + FALSE, bw, 0, rxsc, pPhyInfo); + +/* + //if (pPktinfo->bPacketMatchBSSID) + { + DbgPrint("channel = %d, band = %d, l_rxsc = %d, ht_rxsc = %d\n", pPhyStaRpt->channel, pPhyStaRpt->band, pPhyStaRpt->l_rxsc, pPhyStaRpt->ht_rxsc); + DbgPrint("pwdb A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->pwdb[0], pPhyStaRpt->pwdb[1], pPhyStaRpt->pwdb[2], pPhyStaRpt->pwdb[3]); + DbgPrint("Agc table A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->agc_table_a, pPhyStaRpt->agc_table_b, pPhyStaRpt->agc_table_c, pPhyStaRpt->agc_table_d); + DbgPrint("Gain A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->gain_a, pPhyStaRpt->gain_b, pPhyStaRpt->gain_c, pPhyStaRpt->gain_d); + DbgPrint("TRSW A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->trsw_a, pPhyStaRpt->trsw_b, pPhyStaRpt->trsw_c, pPhyStaRpt->trsw_d); + DbgPrint("AAGC step A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->aagc_step_a, pPhyStaRpt->aagc_step_b, pPhyStaRpt->aagc_step_c, pPhyStaRpt->aagc_step_d); + DbgPrint("HT AAGC gain A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->ht_aagc_gain[0], pPhyStaRpt->ht_aagc_gain[1], pPhyStaRpt->ht_aagc_gain[2], pPhyStaRpt->ht_aagc_gain[3]); + DbgPrint("DAGC gain A: 0x%x, B: 0x%x, C: 0x%x, D: 0x%x\n", pPhyStaRpt->dagc_gain[0], pPhyStaRpt->dagc_gain[1], pPhyStaRpt->dagc_gain[2], pPhyStaRpt->dagc_gain[3]); + DbgPrint("ldpc: %d, stbc: %d, bf: %d, gnt_bt: %d, antsw: %d\n", pPhyStaRpt->ldpc, pPhyStaRpt->stbc, pPhyStaRpt->beamformed, pPhyStaRpt->gnt_bt, pPhyStaRpt->hw_antsw_occu); + DbgPrint("counter: %d, syn_count: %d\n", pPhyStaRpt->counter, pPhyStaRpt->syn_count); + DbgPrint("cnt_cca2agc_rdy: %d, cnt_pw2cca: %d, shift_l_map\n", pPhyStaRpt->cnt_cca2agc_rdy, pPhyStaRpt->cnt_pw2cca, pPhyStaRpt->shift_l_map); + DbgPrint("rsvd_0 = %d, rsvd_1 = %d, rsvd_2 = %d, rsvd_3 = %d, rsvd_4 = %d, rsvd_5 = %d\n", pPhyStaRpt->rsvd_0, pPhyStaRpt->rsvd_1, pPhyStaRpt->rsvd_2, pPhyStaRpt->rsvd_3, pPhyStaRpt->rsvd_4); + DbgPrint("rsvd_5 = %d, rsvd_6 = %d, rsvd_6 = %d\n", pPhyStaRpt->rsvd_5, pPhyStaRpt->rsvd_6, pPhyStaRpt->rsvd_7); + } +*/ +} + +VOID +phydm_GetRxPhyStatusType5( + IN pu1Byte pPhyStatus +) +{ +/* + DbgPrint("DW0: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 3), *(pPhyStatus + 2), *(pPhyStatus + 1), *(pPhyStatus + 0)); + DbgPrint("DW1: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 7), *(pPhyStatus + 6), *(pPhyStatus + 5), *(pPhyStatus + 4)); + DbgPrint("DW2: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 11), *(pPhyStatus + 10), *(pPhyStatus + 9), *(pPhyStatus + 8)); + DbgPrint("DW3: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 15), *(pPhyStatus + 14), *(pPhyStatus + 13), *(pPhyStatus + 12)); + DbgPrint("DW4: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 19), *(pPhyStatus + 18), *(pPhyStatus + 17), *(pPhyStatus + 16)); + DbgPrint("DW5: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 23), *(pPhyStatus + 22), *(pPhyStatus + 21), *(pPhyStatus + 20)); + DbgPrint("DW6: 0x%02x%02x%02x%02x\n", *(pPhyStatus + 27), *(pPhyStatus + 26), *(pPhyStatus + 25), *(pPhyStatus + 24)); +*/ +} + +VOID +phydm_Process_RSSIForDM_Jaguar2( + IN OUT PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo + ) +{ + u4Byte UndecoratedSmoothedPWDB, RSSI_Ave; + u1Byte i; + PSTA_INFO_T pEntry; + + if (pPktinfo->StationID >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID]; + + if (!IS_STA_VALID(pEntry)) + return; + + if ((!pPktinfo->bPacketMatchBSSID))/*data frame only*/ + return; + + if (pPktinfo->bPacketBeacon) + pDM_Odm->PhyDbgInfo.NumQryBeaconPkt++; + + if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { + u4Byte RSSI_linear = 0; + + UndecoratedSmoothedPWDB = (u4Byte)pEntry->rssi_stat.UndecoratedSmoothedPWDB; + pDM_Odm->RSSI_A = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_A]; + pDM_Odm->RSSI_B = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_B]; + pDM_Odm->RSSI_C = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_C]; + pDM_Odm->RSSI_D = pPhyInfo->RxMIMOSignalStrength[ODM_RF_PATH_D]; + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (pPhyInfo->RxMIMOSignalStrength[i] != 0) + RSSI_linear += odm_ConvertTo_linear(pPhyInfo->RxMIMOSignalStrength[i]); + } + + switch (pPhyInfo->RxCount + 1) { + case 2: + RSSI_linear = (RSSI_linear >> 1); + break; + case 3: + RSSI_linear = ((RSSI_linear) + (RSSI_linear << 1) + (RSSI_linear << 3)) >> 5; /* RSSI_linear/3 ~ RSSI_linear*11/32 */ + break; + case 4: + RSSI_linear = (RSSI_linear >> 2); + break; + } + RSSI_Ave = odm_ConvertTo_dB(RSSI_linear); + + if (UndecoratedSmoothedPWDB <= 0) + UndecoratedSmoothedPWDB = pPhyInfo->RxPWDBAll; + else + UndecoratedSmoothedPWDB = (RSSI_Ave + ((UndecoratedSmoothedPWDB<<4) - UndecoratedSmoothedPWDB))>>4; + + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB == -1) + phydm_ra_rssi_rpt_wk(pDM_Odm); + #endif + + pEntry->rssi_stat.UndecoratedSmoothedPWDB = (s4Byte)UndecoratedSmoothedPWDB; + } +} + +VOID +phydm_RxPhyStatusJaguarSeries2( + IN PDM_ODM_T pPhydm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +) +{ + u1Byte phy_status_type = (*pPhyStatus & 0xf); + + /*DbgPrint("phydm_RxPhyStatusJaguarSeries2================> (page: %d)\n", phy_status_type);*/ + + /* Memory reset */ + phydm_ResetPhyInfo(pPhydm, pPhyInfo); + + /* Phy status parsing */ + switch (phy_status_type) { + case 0: + { + phydm_GetRxPhyStatusType0(pPhydm, pPhyStatus, pPktinfo, pPhyInfo); + break; + } + case 1: + { + phydm_GetRxPhyStatusType1(pPhydm, pPhyStatus, pPktinfo, pPhyInfo); + break; + } + case 2: + { + phydm_GetRxPhyStatusType2(pPhydm, pPhyStatus, pPktinfo, pPhyInfo); + break; + } + case 5: + { + phydm_GetRxPhyStatusType5(pPhyStatus); + return; + } + default: + return; + } + + /* Update signal strength to UI, and pPhyInfo->RxPWDBAll is the maximum RSSI of all path */ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pPhyInfo->SignalStrength = SignalScaleProc(pPhydm->Adapter, pPhyInfo->RxPWDBAll, FALSE, FALSE); +#else + pPhyInfo->SignalStrength = (u1Byte)(odm_SignalScaleMapping(pPhydm, pPhyInfo->RxPWDBAll)); +#endif + + /* Calculate average RSSI and smoothed RSSI */ + phydm_Process_RSSIForDM_Jaguar2(pPhydm, pPhyInfo, pPktinfo); + +} +/*==============================================*/ +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.h new file mode 100644 index 00000000..e56f1c20 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_hwconfig.h @@ -0,0 +1,506 @@ +/****************************************************************************** + * + * 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 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 +//============================================================ + +__PACK 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 +} __WLAN_ATTRIB_PACK__ PHY_RX_AGC_INFO_T, *pPHY_RX_AGC_INFO_T; + +__PACK 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 +} __WLAN_ATTRIB_PACK__ PHY_STATUS_RPT_8192CD_T, *PPHY_STATUS_RPT_8192CD_T; + + +typedef struct _Phy_Status_Rpt_8812 { +/* DWORD 0*/ + u1Byte gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/ + u1Byte chl_num_LSB; /*channel number[7:0]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte chl_num_MSB: 2; /*channel number[9:8]*/ + u1Byte sub_chnl: 4; /*sub-channel location[3:0]*/ + u1Byte r_RFMOD: 2; /*RF mode[1:0]*/ +#else /*_BIG_ENDIAN_ */ + u1Byte r_RFMOD: 2; + u1Byte sub_chnl: 4; + u1Byte chl_num_MSB: 2; +#endif + +/* DWORD 1*/ + u1Byte pwdb_all; /*CCK signal quality / OFDM pwdb all*/ + s1Byte cfosho[2]; /*DW1 byte 1 DW1 byte2 CCK AGC report and CCK_BB_Power / OFDM Path-A and Path-B short CFO*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + /*this should be checked again because the definition of 8812 and 8814 is different*/ +/* u1Byte r_cck_rx_enable_pathc:2; cck rx enable pathc[1:0]*/ +/* u1Byte cck_rx_path:4; cck rx path[3:0]*/ + u1Byte resvd_0: 6; + u1Byte bt_RF_ch_MSB: 2; /*8812A:2'b0 8814A: bt rf channel keep[7:6]*/ +#else /*_BIG_ENDIAN_*/ + u1Byte bt_RF_ch_MSB: 2; + u1Byte resvd_0: 6; +#endif + +/* DWORD 2*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte ant_div_sw_a: 1; /*8812A: ant_div_sw_a 8814A: 1'b0*/ + u1Byte ant_div_sw_b: 1; /*8812A: ant_div_sw_b 8814A: 1'b0*/ + u1Byte bt_RF_ch_LSB: 6; /*8812A: 6'b0 8814A: bt rf channel keep[5:0]*/ +#else /*_BIG_ENDIAN_ */ + u1Byte bt_RF_ch_LSB: 6; + u1Byte ant_div_sw_b: 1; + u1Byte ant_div_sw_a: 1; +#endif + s1Byte cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/ + u1Byte PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/ + u1Byte PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/ + +/* DWORD 3*/ + s1Byte rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/ + s1Byte rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/ + +/* DWORD 4*/ + u1Byte PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte PCTS_MSK_RPT_3: 6; /*PCTS mask report[29:24]*/ + u1Byte pcts_rpt_valid: 1; /*pcts_rpt_valid*/ + u1Byte resvd_1: 1; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u1Byte resvd_1: 1; + u1Byte pcts_rpt_valid: 1; + u1Byte PCTS_MSK_RPT_3: 6; +#endif + s1Byte rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 8812A: 16'b0 8814A: stream 3 and stream 4 RX EVM*/ + +/* DWORD 5*/ + u1Byte csi_current[2]; /*DW5 byte 1 DW5 byte 2 8812A: stream 1 and 2 CSI 8814A: path-C and path-D RX SNR*/ + u1Byte gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 path-C and path-D {TRSW, gain[6:0] }*/ + +/* DWORD 6*/ + s1Byte sigevm; /*signal field EVM*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_antc: 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/ + u1Byte antidx_antd: 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/ + u1Byte dpdt_ctrl_keep: 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/ + u1Byte GNT_BT_keep: 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/ +#else /*_BIG_ENDIAN_*/ + u1Byte GNT_BT_keep: 1; + u1Byte dpdt_ctrl_keep: 1; + u1Byte antidx_antd: 3; + u1Byte antidx_antc: 3; +#endif +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_anta: 3; /*antidx_anta[2:0]*/ + u1Byte antidx_antb: 3; /*antidx_antb[2:0]*/ + u1Byte hw_antsw_occur: 2; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u1Byte hw_antsw_occur: 2; + u1Byte antidx_antb: 3; + u1Byte antidx_anta: 3; +#endif +} 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 + ); + +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 + ); + +#if (RTL8822B_SUPPORT == 1) +/*For 8822B only!! need to move to FW finally */ +/*==============================================*/ +VOID +phydm_RxPhyStatusJaguarSeries2( + IN PDM_ODM_T pPhydm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +); + +typedef struct _Phy_Status_Rpt_Jaguar2_Type0 { + /* DW0 */ + u1Byte page_num; + u1Byte pwdb; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain: 6; + u1Byte rsvd_0: 1; + u1Byte trsw: 1; +#else + u1Byte trsw: 1; + u1Byte rsvd_0: 1; + u1Byte gain: 6; +#endif + u1Byte rsvd_1; + + /* DW1 */ + u1Byte rsvd_2; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte rxsc: 4; + u1Byte agc_table: 4; +#else + u1Byte agc_table: 4; + u1Byte rxsc: 4; +#endif + u1Byte channel; + u1Byte band; + + /* DW2 */ + u2Byte length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_a: 3; + u1Byte antidx_b: 3; + u1Byte rsvd_3: 2; + u1Byte antidx_c: 3; + u1Byte antidx_d: 3; + u1Byte rsvd_4:2; +#else + u1Byte rsvd_3: 2; + u1Byte antidx_b: 3; + u1Byte antidx_a: 3; + u1Byte rsvd_4:2; + u1Byte antidx_d: 3; + u1Byte antidx_c: 3; +#endif + + /* DW3 */ + u1Byte signal_quality; + u1Byte agc_rpt; + u1Byte bb_power; + u1Byte rsvd_5; + + /* DW4 */ + u4Byte rsvd_6; + + /* DW5 */ + u4Byte rsvd_7; + + /* DW6 */ + u4Byte rsvd_8; +} PHY_STATUS_RPT_JAGUAR2_TYPE0, *PPHY_STATUS_RPT_JAGUAR2_TYPE0; + +typedef struct _Phy_Status_Rpt_Jaguar2_Type1 { + /* DW0 and DW1 */ + u1Byte page_num; + u1Byte pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte l_rxsc: 4; + u1Byte ht_rxsc: 4; +#else + u1Byte ht_rxsc: 4; + u1Byte l_rxsc: 4; +#endif + u1Byte channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte band: 2; + u1Byte rsvd_0: 1; + u1Byte hw_antsw_occu: 1; + u1Byte gnt_bt: 1; + u1Byte ldpc: 1; + u1Byte stbc: 1; + u1Byte beamformed: 1; +#else + u1Byte beamformed: 1; + u1Byte stbc: 1; + u1Byte ldpc: 1; + u1Byte gnt_bt: 1; + u1Byte hw_antsw_occu: 1; + u1Byte rsvd_0: 1; + u1Byte band: 2; +#endif + + /* DW2 */ + u2Byte lsig_length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_a: 3; + u1Byte antidx_b: 3; + u1Byte rsvd_1: 2; + u1Byte antidx_c: 3; + u1Byte antidx_d: 3; + u1Byte rsvd_2: 2; +#else + u1Byte rsvd_1: 2; + u1Byte antidx_b: 3; + u1Byte antidx_a: 3; + u1Byte rsvd_2: 2; + u1Byte antidx_d: 3; + u1Byte antidx_c: 3; +#endif + + /* DW3 */ + u1Byte paid; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte paid_msb: 1; + u1Byte gid: 6; + u1Byte rsvd_3: 1; +#else + u1Byte rsvd_3: 1; + u1Byte gid: 6; + u1Byte paid_msb: 1; +#endif + u1Byte intf_pos; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte intf_pos_msb: 1; + u1Byte rsvd_4: 2; + u1Byte nb_intf_flag: 1; + u1Byte rf_mode: 2; + u1Byte rsvd_5: 2; +#else + u1Byte rsvd_5: 2; + u1Byte rf_mode: 2; + u1Byte nb_intf_flag: 1; + u1Byte rsvd_4: 2; + u1Byte intf_pos_msb: 1; +#endif + + /* DW4 */ + s1Byte rxevm[4]; /* s(8,1) */ + + /* DW5 */ + s1Byte cfo_tail[4]; /* s(8,7) */ + + /* DW6 */ + s1Byte rxsnr[4]; /* s(8,1) */ +} PHY_STATUS_RPT_JAGUAR2_TYPE1, *PPHY_STATUS_RPT_JAGUAR2_TYPE1; + +typedef struct _Phy_Status_Rpt_Jaguar2_Type2 { + /* DW0 ane DW1 */ + u1Byte page_num; + u1Byte pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte l_rxsc: 4; + u1Byte ht_rxsc: 4; +#else + u1Byte ht_rxsc: 4; + u1Byte l_rxsc: 4; +#endif + u1Byte channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte band: 2; + u1Byte rsvd_0: 1; + u1Byte hw_antsw_occu: 1; + u1Byte gnt_bt: 1; + u1Byte ldpc: 1; + u1Byte stbc: 1; + u1Byte beamformed: 1; +#else + u1Byte beamformed: 1; + u1Byte stbc: 1; + u1Byte ldpc: 1; + u1Byte gnt_bt: 1; + u1Byte hw_antsw_occu: 1; + u1Byte rsvd_0: 1; + u1Byte band: 2; +#endif + + /* DW2 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte shift_l_map: 6; + u1Byte rsvd_1: 2; +#else + u1Byte rsvd_1: 2; + u1Byte shift_l_map: 6; +#endif + u1Byte cnt_pw2cca; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte agc_table_a: 4; + u1Byte agc_table_b: 4; + u1Byte agc_table_c: 4; + u1Byte agc_table_d: 4; +#else + u1Byte agc_table_b: 4; + u1Byte agc_table_a: 4; + u1Byte agc_table_d: 4; + u1Byte agc_table_c: 4; +#endif + + /* DW3 ~ DW6*/ + u1Byte cnt_cca2agc_rdy; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain_a: 6; + u1Byte rsvd_2: 1; + u1Byte trsw_a: 1; + u1Byte gain_b: 6; + u1Byte rsvd_3: 1; + u1Byte trsw_b: 1; + u1Byte gain_c: 6; + u1Byte rsvd_4: 1; + u1Byte trsw_c: 1; + u1Byte gain_d: 6; + u1Byte rsvd_5: 1; + u1Byte trsw_d: 1; + u1Byte aagc_step_a: 2; + u1Byte aagc_step_b: 2; + u1Byte aagc_step_c: 2; + u1Byte aagc_step_d: 2; +#else + u1Byte trsw_a: 1; + u1Byte rsvd_2: 1; + u1Byte gain_a: 6; + u1Byte trsw_b: 1; + u1Byte rsvd_3: 1; + u1Byte gain_b: 6; + u1Byte trsw_c: 1; + u1Byte rsvd_4: 1; + u1Byte gain_c: 6; + u1Byte trsw_d: 1; + u1Byte rsvd_5: 1; + u1Byte gain_d: 6; + u1Byte aagc_step_d: 2; + u1Byte aagc_step_c: 2; + u1Byte aagc_step_b: 2; + u1Byte aagc_step_a: 2; +#endif + u1Byte ht_aagc_gain[4]; + u1Byte dagc_gain[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte counter: 6; + u1Byte rsvd_6: 2; + u1Byte syn_count: 5; + u1Byte rsvd_7:3; +#else + u1Byte rsvd_6: 2; + u1Byte counter: 6; + u1Byte rsvd_7:3; + u1Byte syn_count: 5; +#endif +} PHY_STATUS_RPT_JAGUAR2_TYPE2, *PPHY_STATUS_RPT_JAGUAR2_TYPE2; +/*==============================================*/ +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.c new file mode 100644 index 00000000..6b97b03e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.c @@ -0,0 +1,1014 @@ +/****************************************************************************** + * + * 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) + PHY_SetRFReg(pDM_Odm->priv, eRFPath, RegAddr, BitMask, Data); +#elif (DM_ODM_SUPPORT_TYPE & ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data); + ODM_delay_us(2); + +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE) + PHY_SetRFReg(pDM_Odm->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) + 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) + memset(pbuf, value, length); +#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) + 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) + 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) + del_timer(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 +} + +BOOLEAN +phydm_actingDetermine( + IN PDM_ODM_T pDM_Odm, + IN PHYDM_ACTING_TYPE type + ) +{ + BOOLEAN ret = FALSE; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->BeamformingInfo.SourceAdapter; +#else + PADAPTER Adapter = pDM_Odm->Adapter; +#endif + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if (type == PhyDM_ACTING_AS_AP) + ret = ACTING_AS_AP(Adapter); + else if (type == PhyDM_ACTING_AS_IBSS) + ret = ACTING_AS_IBSS(Adapter); +#elif (DM_ODM_SUPPORT_TYPE & ODM_CE) + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + if (type == PhyDM_ACTING_AS_AP) + ret = check_fwstate(pmlmepriv, WIFI_AP_STATE); + else if (type == PhyDM_ACTING_AS_IBSS) + ret = check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); +#endif + + return ret; + +} + + +u1Byte +phydm_trans_h2c_id( + IN PDM_ODM_T pDM_Odm, + IN u1Byte phydm_h2c_id +) +{ + u1Byte platform_h2c_id=0xff; + + + switch(phydm_h2c_id) + { + //1 [0] + case ODM_H2C_RSSI_REPORT: + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + if(pDM_Odm->SupportICType == ODM_RTL8188E) + { + platform_h2c_id = H2C_88E_RSSI_REPORT; + } + else if(pDM_Odm->SupportICType == ODM_RTL8814A) + { + platform_h2c_id =H2C_8814A_RSSI_REPORT; + } + else + { + platform_h2c_id = H2C_RSSI_REPORT; + } + + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + platform_h2c_id = H2C_RSSI_SETTING; + + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1)) + if (pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8814A || (pDM_Odm->SupportICType == ODM_RTL8822B)) + { + platform_h2c_id =H2C_88XX_RSSI_REPORT; + /*ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] H2C_88XX_RSSI_REPORT CMD_ID = (( %d ))\n", platform_h2c_id));*/ + } else + #endif + #if(RTL8812A_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + platform_h2c_id = H2C_8812_RSSI_REPORT; + } else + #endif + {} + #endif + + break; + + //1 [3] + case ODM_H2C_WIFI_CALIBRATION: + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + platform_h2c_id =H2C_WIFI_CALIBRATION; + + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + #if(RTL8723B_SUPPORT==1) + platform_h2c_id = H2C_8723B_BT_WLAN_CALIBRATION; + #endif + + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + + + #endif + + break; + + + //1 [4] + case ODM_H2C_IQ_CALIBRATION: + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + platform_h2c_id =H2C_IQ_CALIBRATION; + + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + #if((RTL8812A_SUPPORT==1) ||(RTL8821A_SUPPORT==1)) + platform_h2c_id = H2C_8812_IQ_CALIBRATION; + #endif + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + + + #endif + + break; + //1 [5] + case ODM_H2C_RA_PARA_ADJUST: + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + if (pDM_Odm->SupportICType & (ODM_RTL8814A | ODM_RTL8822B)) + platform_h2c_id = H2C_8814A_RA_PARA_ADJUST; + else + platform_h2c_id = H2C_RA_PARA_ADJUST; + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + #if((RTL8812A_SUPPORT==1) ||(RTL8821A_SUPPORT==1)) + platform_h2c_id = H2C_8812_RA_PARA_ADJUST; + #elif ((RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1)) + platform_h2c_id = H2C_RA_PARA_ADJUST; + #elif(RTL8192E_SUPPORT==1) + platform_h2c_id =H2C_8192E_RA_PARA_ADJUST; + #elif(RTL8723B_SUPPORT==1) + platform_h2c_id =H2C_8723B_RA_PARA_ADJUST; + #endif + + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1)) + if (pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8814A || (pDM_Odm->SupportICType == ODM_RTL8822B)) { + platform_h2c_id =H2C_88XX_RA_PARA_ADJUST; + /*ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] H2C_88XX_RA_PARA_ADJUST CMD_ID = (( %d ))\n", platform_h2c_id));*/ + } else + #endif + #if(RTL8812A_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + platform_h2c_id = H2C_8812_RA_PARA_ADJUST; + } else + #endif + {} + #endif + + break; + + + //1 [6] + case PHYDM_H2C_DYNAMIC_TX_PATH: + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + if(pDM_Odm->SupportICType == ODM_RTL8814A) + { + platform_h2c_id =H2C_8814A_DYNAMIC_TX_PATH; + } + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + #if (RTL8814A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8814A) + platform_h2c_id = H2C_DYNAMIC_TX_PATH; + #endif + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + #if(RTL8814A_SUPPORT==1) + if( pDM_Odm->SupportICType == ODM_RTL8814A) + { + platform_h2c_id = H2C_88XX_DYNAMIC_TX_PATH; + } + #endif + + #endif + + break; + + /* [7]*/ + case PHYDM_H2C_FW_TRACE_EN: + + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + if (pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B)) + platform_h2c_id = H2C_8814A_FW_TRACE_EN; + else + platform_h2c_id = H2C_FW_TRACE_EN; + + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + + + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + #if ((RTL8881A_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8814A_SUPPORT == 1) || (RTL8822B_SUPPORT == 1)) + if (pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E || pDM_Odm->SupportICType == ODM_RTL8814A || (pDM_Odm->SupportICType == ODM_RTL8822B)) + platform_h2c_id = H2C_88XX_FW_TRACE_EN; + else + #endif + #if (RTL8812A_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8812) { + platform_h2c_id = H2C_8812_FW_TRACE_EN; + } else + #endif + {} + + #endif + + break; + + case PHYDM_H2C_TXBF: +#if ((RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1)) + platform_h2c_id = 0x41; /*H2C_TxBF*/ +#endif + break; + + default: + platform_h2c_id=0xff; + break; + } + + return platform_h2c_id; + +} + +// +// ODM FW relative API. +// + +VOID +ODM_FillH2CCmd( + IN PDM_ODM_T pDM_Odm, + IN u1Byte phydm_h2c_id, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + u1Byte platform_h2c_id; + + platform_h2c_id=phydm_trans_h2c_id(pDM_Odm, phydm_h2c_id); + + if(platform_h2c_id==0xff) + { + ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] Wrong H2C CMD-ID !! platform_h2c_id==0xff , PHYDM_ElementID=((%d )) \n",phydm_h2c_id)); + return; + } + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + if (!pDM_Odm->RaSupport88E) + FillH2CCmd88E(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); + else if (pDM_Odm->SupportICType == ODM_RTL8192C) + FillH2CCmd92C(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); + else if (pDM_Odm->SupportICType == ODM_RTL8814A) + FillH2CCmd8814A(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); + else if (pDM_Odm->SupportICType == ODM_RTL8822B) +#if (RTL8822B_SUPPORT == 1) + FillH2CCmd8822B(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); +#endif + else + FillH2CCmd(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); + + #elif(DM_ODM_SUPPORT_TYPE & ODM_CE) + rtw_hal_fill_h2c_cmd(Adapter, platform_h2c_id, CmdLen, pCmdBuffer); + + #elif(DM_ODM_SUPPORT_TYPE & ODM_AP) + #if((RTL8881A_SUPPORT==1)||(RTL8192E_SUPPORT==1)||(RTL8814A_SUPPORT==1)) + if(pDM_Odm->SupportICType == ODM_RTL8881A || pDM_Odm->SupportICType == ODM_RTL8192E|| pDM_Odm->SupportICType == ODM_RTL8814A) + { + GET_HAL_INTERFACE(pDM_Odm->priv)->FillH2CCmdHandler(pDM_Odm->priv, platform_h2c_id, CmdLen, pCmdBuffer); + //FillH2CCmd88XX(pDM_Odm->priv, platform_h2c_id, CmdLen, pCmdBuffer); + } else + #endif + #if(RTL8812A_SUPPORT==1) + if(pDM_Odm->SupportICType == ODM_RTL8812) + { + FillH2CCmd8812(pDM_Odm->priv, platform_h2c_id, CmdLen, pCmdBuffer); + } else + #endif + {} + #endif +} + +u1Byte +phydm_c2H_content_parsing( + IN PVOID pDM_VOID, + IN u1Byte c2hCmdId, + IN u1Byte c2hCmdLen, + IN pu1Byte tmpBuf +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + #endif + u1Byte Extend_c2hSubID = 0; + u1Byte find_c2h_cmd = TRUE; + + switch (c2hCmdId) { + case PHYDM_C2H_DBG: + if (pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_RTL8822B)) + phydm_fw_trace_handler(pDM_Odm, tmpBuf, c2hCmdLen); + + break; + + case PHYDM_C2H_RA_RPT: + phydm_c2h_ra_report_handler(pDM_Odm, tmpBuf, c2hCmdLen); + break; + + case PHYDM_C2H_RA_PARA_RPT: + ODM_C2HRaParaReportHandler(pDM_Odm, tmpBuf, c2hCmdLen); + break; + + case PHYDM_C2H_DYNAMIC_TX_PATH_RPT: + if (pDM_Odm->SupportICType & (ODM_RTL8814A)) + phydm_c2h_dtp_handler(pDM_Odm, tmpBuf, c2hCmdLen); + + break; + + case PHYDM_C2H_IQK_FINISH: + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + if (pDM_Odm->SupportICType & (ODM_RTL8812 | ODM_RTL8821)) { + + RT_TRACE(COMP_MP, DBG_LOUD, ("== FW IQK Finish ==\n")); + PlatformAcquireSpinLock(Adapter, RT_IQK_SPINLOCK); + pDM_Odm->RFCalibrateInfo.bIQKInProgress = FALSE; + PlatformReleaseSpinLock(Adapter, RT_IQK_SPINLOCK); + pDM_Odm->RFCalibrateInfo.IQK_ProgressingTime = 0; + pDM_Odm->RFCalibrateInfo.IQK_ProgressingTime = ODM_GetProgressingTime(pDM_Odm, pDM_Odm->RFCalibrateInfo.IQK_StartTime); + } + + #endif + break; + + case PHYDM_C2H_DBG_CODE: + phydm_fw_trace_handler_code(pDM_Odm, tmpBuf, c2hCmdLen); + break; + + case PHYDM_C2H_EXTEND: + Extend_c2hSubID = tmpBuf[0]; + if (Extend_c2hSubID == PHYDM_EXTEND_C2H_DBG_PRINT) + phydm_fw_trace_handler_8051(pDM_Odm, tmpBuf, c2hCmdLen); + + break; + + default: + find_c2h_cmd = FALSE; + break; + } + + return find_c2h_cmd; + +} + +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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.h new file mode 100644 index 00000000..3288849d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_interface.h @@ -0,0 +1,442 @@ +/****************************************************************************** + * + * 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__ + +#define INTERFACE_VERSION "1.0" /*2015.01.13 Dino*/ + +// +// =========== 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 _PHYDM_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_H2C_RA_PARA_ADJUST = 5, + PHYDM_H2C_DYNAMIC_TX_PATH = 6, + PHYDM_H2C_FW_TRACE_EN = 7, + PHYDM_H2C_TXBF = 8, + ODM_MAX_H2CCMD +} PHYDM_H2C_CMD; + +typedef enum _PHYDM_C2H_EVT { + PHYDM_C2H_DBG = 0, + PHYDM_C2H_LB = 1, + PHYDM_C2H_XBF = 2, + PHYDM_C2H_TX_REPORT = 3, + PHYDM_C2H_INFO = 9, + PHYDM_C2H_BT_MP = 11, + PHYDM_C2H_RA_RPT = 12, + PHYDM_C2H_RA_PARA_RPT = 14, + PHYDM_C2H_DYNAMIC_TX_PATH_RPT = 15, + PHYDM_C2H_IQK_FINISH = 17, /*0x11*/ + PHYDM_C2H_DBG_CODE = 0xFE, + PHYDM_C2H_EXTEND = 0xFF, +} PHYDM_C2H_EVT; + +typedef enum _PHYDM_EXTEND_C2H_EVT { + PHYDM_EXTEND_C2H_DBG_PRINT = 0 + +} PHYDM_EXTEND_C2H_EVT; + +typedef enum _PHYDM_ACTING_TYPE { + PhyDM_ACTING_AS_IBSS = 0, + PhyDM_ACTING_AS_AP = 1 +} PHYDM_ACTING_TYPE; + + +// +// 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 + ); + +BOOLEAN +phydm_actingDetermine( + IN PDM_ODM_T pDM_Odm, + IN PHYDM_ACTING_TYPE type + ); + +// +// ODM FW relative API. +// +VOID +ODM_FillH2CCmd( + IN PDM_ODM_T pDM_Odm, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +); + +u1Byte +phydm_c2H_content_parsing( + IN PVOID pDM_VOID, + IN u1Byte c2hCmdId, + IN u1Byte c2hCmdLen, + IN pu1Byte tmpBuf +); + +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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.c new file mode 100644 index 00000000..22c50dbc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.c @@ -0,0 +1,299 @@ +/****************************************************************************** + * + * 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" +#include "phydm_noisemonitor.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 + +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + +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, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, 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, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, IGIValue); + } + func_end = ODM_GetProgressingTime(pDM_Odm,func_start) ; + + 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_ACSeries(PDM_ODM_T pDM_Odm, u8 bPauseDIG, u8 IGIValue, u32 max_time + ) +{ + s4Byte rxi_buf_anta, rxq_buf_anta; /*rxi_buf_antb, rxq_buf_antb;*/ + s4Byte value32, pwdb_A = 0, sval, noise, sum; + BOOLEAN pd_flag; + u1Byte i, valid_cnt; + u32 start = 0, func_start = 0, func_end = 0; + + + if (!(pDM_Odm->SupportICType & (ODM_RTL8812 | ODM_RTL8821))) + return 0; + + func_start = ODM_GetCurrentTime(pDM_Odm); + pDM_Odm->noise_level.noise_all = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_InbandNoise_Monitor_ACSeries() ==>\n")); + + /* Step 1. Disable DIG && Set initial gain. */ + if (bPauseDIG) + odm_PauseDIG(pDM_Odm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, 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); + + /* reset counters */ + sum = 0; + valid_cnt = 0; + + /* Step 3. Get noise power level */ + while (1) { + /*Set IGI=0x1C */ + ODM_Write_DIG(pDM_Odm, 0x1C); + /*stop CK320&CK88 */ + ODM_SetBBReg(pDM_Odm, 0x8B4, BIT6, 1); + /*Read Path-A */ + ODM_SetBBReg(pDM_Odm, 0x8FC, bMaskDWord, 0x200); /*set debug port*/ + value32 = ODM_GetBBReg(pDM_Odm, 0xFA0, bMaskDWord); /*read debug port*/ + + rxi_buf_anta = (value32 & 0xFFC00) >> 10; /*rxi_buf_anta=RegFA0[19:10]*/ + rxq_buf_anta = value32 & 0x3FF; /*rxq_buf_anta=RegFA0[19:10]*/ + + pd_flag = (BOOLEAN) ((value32 & BIT31) >> 31); + + /*Not in packet detection period or Tx state */ + if ((!pd_flag) || (rxi_buf_anta != 0x200)) { + /*sign conversion*/ + rxi_buf_anta = ODM_SignConversion(rxi_buf_anta, 10); + rxq_buf_anta = ODM_SignConversion(rxq_buf_anta, 10); + + pwdb_A = ODM_PWdB_Conversion(rxi_buf_anta * rxi_buf_anta + rxq_buf_anta * rxq_buf_anta, 20, 18); /*S(10,9)*S(10,9)=S(20,18)*/ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pwdb_A= %d dB, rxi_buf_anta= 0x%x, rxq_buf_anta= 0x%x\n", pwdb_A, rxi_buf_anta & 0x3FF, rxq_buf_anta & 0x3FF)); + } + + /*BB Reset*/ + ODM_Write1Byte(pDM_Odm, 0x02, ODM_Read1Byte(pDM_Odm, 0x02) & (~BIT0)); + ODM_Write1Byte(pDM_Odm, 0x02, ODM_Read1Byte(pDM_Odm, 0x02) | BIT0); + + /*Start CK320&CK88*/ + ODM_SetBBReg(pDM_Odm, 0x8B4, BIT6, 0); + + sval = pwdb_A; + + if (sval < 0 && sval >= -27) { + if (valid_cnt < ValidCnt) { + valid_cnt++; + sum += sval; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Valid sval = %d\n", sval)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("Sum of sval = %d,\n", sum)); + if ((valid_cnt >= ValidCnt) || (ODM_GetProgressingTime(pDM_Odm, start) > max_time)) { + sum /= valid_cnt; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("After divided, sum = %d\n", sum)); + break; + } + } + } + } + + /*ADC backoff is 12dB,*/ + /*Ptarget=0x1C-110=-82dBm*/ + noise = sum + 12 + 0x1C - 110; + + /*Offset*/ + noise = noise - 3; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("noise = %d\n", noise)); + pDM_Odm->noise_level.noise_all = (s2Byte)noise; + + /* Step 4. Recover the Dig*/ + if (bPauseDIG) + odm_PauseDIG(pDM_Odm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, IGIValue); + + func_end = ODM_GetProgressingTime(pDM_Odm, func_start); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_InbandNoise_Monitor_ACSeries() <==\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) + return odm_InbandNoise_Monitor_ACSeries(pDM_Odm, bPauseDIG, IGIValue, max_time); + else + return odm_InbandNoise_Monitor_NSeries(pDM_Odm, bPauseDIG, IGIValue, max_time); +} + +#endif + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_noisemonitor.h new file mode 100644 index 00000000..6625be61 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.c new file mode 100644 index 00000000..433d091e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.c @@ -0,0 +1,2311 @@ +/****************************************************************************** + * + * 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(defined(CONFIG_PATH_DIVERSITY)) +#if RTL8814A_SUPPORT + +VOID +phydm_dtp_fix_tx_path( + IN PVOID pDM_VOID, + IN u1Byte path + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &pDM_Odm->DM_PathDiv; + u1Byte i,num_enable_path=0; + + if(path==pDM_PathDiv->pre_tx_path) + { + return; + } + else + { + pDM_PathDiv->pre_tx_path=path; + } + + ODM_SetBBReg( pDM_Odm, 0x93c, BIT18|BIT19, 3); + + for(i=0; i<4; i++) + { + if(path&BIT(i)) + num_enable_path++; + } + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Number of trun-on path : (( %d ))\n", num_enable_path)); + + if(num_enable_path == 1) + { + ODM_SetBBReg( pDM_Odm, 0x93c, 0xf00000, path); + + if(path==PHYDM_A)//1-1 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A ))\n")); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + } + else if(path==PHYDM_B)//1-2 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B ))\n")); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 0); + } + else if(path==PHYDM_C)//1-3 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( C ))\n")); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 0); + + } + else if(path==PHYDM_D)//1-4 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( D ))\n")); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 0); + } + + } + else if(num_enable_path == 2) + { + ODM_SetBBReg( pDM_Odm, 0x93c, 0xf00000, path); + ODM_SetBBReg( pDM_Odm, 0x940, 0xf0, path); + + if(path==PHYDM_AB)//2-1 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 1); + } + else if(path==PHYDM_AC)//2-2 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A C ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 1); + } + else if(path==PHYDM_AD)//2-3 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A D ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 1); + } + else if(path==PHYDM_BC)//2-4 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B C ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 1); + } + else if(path==PHYDM_BD)//2-5 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B D ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 1); + } + else if(path==PHYDM_CD)//2-6 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( C D ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 1); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 1); + } + + } + else if(num_enable_path == 3) + { + ODM_SetBBReg( pDM_Odm, 0x93c, 0xf00000, path); + ODM_SetBBReg( pDM_Odm, 0x940, 0xf0, path); + ODM_SetBBReg( pDM_Odm, 0x940, 0xf0000, path); + + if(path==PHYDM_ABC)//3-1 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B C))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 1); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 2); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 2); + //set for 3ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT21|BIT20, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT23|BIT22, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT25|BIT24, 2); + } + else if(path==PHYDM_ABD)//3-2 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B D ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 1); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 2); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 2); + //set for 3ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT21|BIT20, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT23|BIT22, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT27|BIT26, 2); + + } + else if(path==PHYDM_ACD)//3-3 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A C D ))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT25|BIT24, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 1); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 2); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT9|BIT8, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 2); + //set for 3ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT21|BIT20, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT25|BIT24, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT27|BIT26, 2); + } + else if(path==PHYDM_BCD)//3-4 + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B C D))\n")); + //set for 1ss + ODM_SetBBReg( pDM_Odm, 0x93c, BIT27|BIT26, 0); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT29|BIT28, 1); + ODM_SetBBReg( pDM_Odm, 0x93c, BIT31|BIT30, 2); + //set for 2ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT11|BIT10, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT13|BIT12, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT15|BIT14, 2); + //set for 3ss + ODM_SetBBReg( pDM_Odm, 0x940, BIT23|BIT22, 0); + ODM_SetBBReg( pDM_Odm, 0x940, BIT25|BIT24, 1); + ODM_SetBBReg( pDM_Odm, 0x940, BIT27|BIT26, 2); + } + } + else if(num_enable_path == 4) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path ((A B C D))\n")); + } + +} + +VOID +phydm_find_default_path( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &pDM_Odm->DM_PathDiv; + u4Byte rssi_avg_a=0, rssi_avg_b=0, rssi_avg_c=0, rssi_avg_d=0, rssi_avg_bcd=0; + u4Byte rssi_total_a=0, rssi_total_b=0, rssi_total_c=0, rssi_total_d=0; + + //2 Default Path Selection By RSSI + + rssi_avg_a = (pDM_PathDiv->path_a_cnt_all > 0)? (pDM_PathDiv->path_a_sum_all / pDM_PathDiv->path_a_cnt_all) :0 ; + rssi_avg_b = (pDM_PathDiv->path_b_cnt_all > 0)? (pDM_PathDiv->path_b_sum_all / pDM_PathDiv->path_b_cnt_all) :0 ; + rssi_avg_c = (pDM_PathDiv->path_c_cnt_all > 0)? (pDM_PathDiv->path_c_sum_all / pDM_PathDiv->path_c_cnt_all) :0 ; + rssi_avg_d = (pDM_PathDiv->path_d_cnt_all > 0)? (pDM_PathDiv->path_d_sum_all / pDM_PathDiv->path_d_cnt_all) :0 ; + + + pDM_PathDiv->path_a_sum_all = 0; + pDM_PathDiv->path_a_cnt_all = 0; + pDM_PathDiv->path_b_sum_all = 0; + pDM_PathDiv->path_b_cnt_all = 0; + pDM_PathDiv->path_c_sum_all = 0; + pDM_PathDiv->path_c_cnt_all = 0; + pDM_PathDiv->path_d_sum_all = 0; + pDM_PathDiv->path_d_cnt_all = 0; + + if(pDM_PathDiv->use_path_a_as_default_ant == 1) + { + rssi_avg_bcd=(rssi_avg_b+rssi_avg_c+rssi_avg_d)/3; + + if( (rssi_avg_a + ANT_DECT_RSSI_TH) > rssi_avg_bcd ) + { + pDM_PathDiv->is_pathA_exist=TRUE; + pDM_PathDiv->default_path=PATH_A; + } + else + { + pDM_PathDiv->is_pathA_exist=FALSE; + } + } + else + { + if( (rssi_avg_a >=rssi_avg_b) && (rssi_avg_a >=rssi_avg_c)&&(rssi_avg_a >=rssi_avg_d)) + pDM_PathDiv->default_path=PATH_A; + else if( (rssi_avg_b >=rssi_avg_c)&&(rssi_avg_b >=rssi_avg_d)) + pDM_PathDiv->default_path=PATH_B; + else if( rssi_avg_c >=rssi_avg_d) + pDM_PathDiv->default_path=PATH_C; + else + pDM_PathDiv->default_path=PATH_D; + } + + +} + + +VOID +phydm_candidate_dtp_update( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &pDM_Odm->DM_PathDiv; + + pDM_PathDiv->num_candidate=3; + + if(pDM_PathDiv->use_path_a_as_default_ant == 1) + { + if(pDM_PathDiv->num_tx_path==3) + { + if(pDM_PathDiv->is_pathA_exist) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_ABC; + pDM_PathDiv->ant_candidate_2 = PHYDM_ABD; + pDM_PathDiv->ant_candidate_3 = PHYDM_ACD; + } + else // use path BCD + { + pDM_PathDiv->num_candidate=1; + phydm_dtp_fix_tx_path(pDM_Odm, PHYDM_BCD); + return; + } + } + else if(pDM_PathDiv->num_tx_path==2) + { + if(pDM_PathDiv->is_pathA_exist) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_AB; + pDM_PathDiv->ant_candidate_2 = PHYDM_AC; + pDM_PathDiv->ant_candidate_3 = PHYDM_AD; + } + else + { + pDM_PathDiv->ant_candidate_1 = PHYDM_BC; + pDM_PathDiv->ant_candidate_2 = PHYDM_BD; + pDM_PathDiv->ant_candidate_3 = PHYDM_CD; + } + } + } + else + { + //2 3 TX Mode + if(pDM_PathDiv->num_tx_path==3)//choose 3 ant form 4 + { + if(pDM_PathDiv->default_path == PATH_A) //choose 2 ant form 3 + { + pDM_PathDiv->ant_candidate_1 = PHYDM_ABC; + pDM_PathDiv->ant_candidate_2 = PHYDM_ABD; + pDM_PathDiv->ant_candidate_3 = PHYDM_ACD; + } + else if(pDM_PathDiv->default_path==PATH_B) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_ABC; + pDM_PathDiv->ant_candidate_2 = PHYDM_ABD; + pDM_PathDiv->ant_candidate_3 = PHYDM_BCD; + } + else if(pDM_PathDiv->default_path == PATH_C) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_ABC; + pDM_PathDiv->ant_candidate_2 = PHYDM_ACD; + pDM_PathDiv->ant_candidate_3 = PHYDM_BCD; + } + else if(pDM_PathDiv->default_path == PATH_D) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_ABD; + pDM_PathDiv->ant_candidate_2 = PHYDM_ACD; + pDM_PathDiv->ant_candidate_3 = PHYDM_BCD; + } + } + + //2 2 TX Mode + else if(pDM_PathDiv->num_tx_path==2)//choose 2 ant form 4 + { + if(pDM_PathDiv->default_path == PATH_A) //choose 2 ant form 3 + { + pDM_PathDiv->ant_candidate_1 = PHYDM_AB; + pDM_PathDiv->ant_candidate_2 = PHYDM_AC; + pDM_PathDiv->ant_candidate_3 = PHYDM_AD; + } + else if(pDM_PathDiv->default_path==PATH_B) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_AB; + pDM_PathDiv->ant_candidate_2 = PHYDM_BC; + pDM_PathDiv->ant_candidate_3 = PHYDM_BD; + } + else if(pDM_PathDiv->default_path == PATH_C) + { + pDM_PathDiv->ant_candidate_1 = PHYDM_AC; + pDM_PathDiv->ant_candidate_2 = PHYDM_BC; + pDM_PathDiv->ant_candidate_3 = PHYDM_CD; + } + else if(pDM_PathDiv->default_path == PATH_D) + { + pDM_PathDiv->ant_candidate_1= PHYDM_AD; + pDM_PathDiv->ant_candidate_2 = PHYDM_BD; + pDM_PathDiv->ant_candidate_3= PHYDM_CD; + } + } + } +} + + +VOID +phydm_dynamic_tx_path( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &pDM_Odm->DM_PathDiv; + + PSTA_INFO_T pEntry; + u4Byte i; + u1Byte num_client=0; + u1Byte H2C_Parameter[6] ={0}; + + + if(!pDM_Odm->bLinked) //bLinked==False + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("DTP_8814 [No Link!!!]\n")); + + if(pDM_PathDiv->bBecomeLinked == TRUE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" [Be disconnected]----->\n")); + pDM_PathDiv->bBecomeLinked = pDM_Odm->bLinked; + } + return; + } + else + { + if(pDM_PathDiv->bBecomeLinked ==FALSE) + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" [Be Linked !!!]----->\n")); + pDM_PathDiv->bBecomeLinked = pDM_Odm->bLinked; + } + } + + //2 [Period CTRL] + if(pDM_PathDiv->dtp_period >=2) + { + pDM_PathDiv->dtp_period=0; + } + else + { + //ODM_RT_TRACE(pDM_Odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Phydm_Dynamic_Tx_Path_8814A() Stay = (( %d ))\n",pDM_PathDiv->dtp_period)); + pDM_PathDiv->dtp_period++; + return; + } + + + //2 [Fix Path] + if (pDM_Odm->path_select != PHYDM_AUTO_PATH) + { + return; + } + + //2 [Check Bfer] + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if (BEAMFORMING_SUPPORT == 1) + { + BEAMFORMING_CAP BeamformCap = (pDM_Odm->BeamformingInfo.BeamformCap); + + if( BeamformCap & BEAMFORMER_CAP ) // BFmer On && Div On -> Div Off + { + if( pDM_PathDiv->fix_path_bfer == 0) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV,ODM_DBG_LOUD,("[ PathDiv : OFF ] BFmer ==1 \n")); + pDM_PathDiv->fix_path_bfer = 1 ; + } + return; + } + else // BFmer Off && Div Off -> Div On + { + if( pDM_PathDiv->fix_path_bfer == 1 ) + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV,ODM_DBG_LOUD,("[ PathDiv : ON ] BFmer ==0 \n")); + pDM_PathDiv->fix_path_bfer = 0; + } + } + } + #endif + #endif + + if(pDM_PathDiv->use_path_a_as_default_ant ==1) + { + phydm_find_default_path(pDM_Odm); + phydm_candidate_dtp_update(pDM_Odm); + } + else + { + if( pDM_PathDiv->dtp_state == PHYDM_DTP_INIT) + { + phydm_find_default_path(pDM_Odm); + phydm_candidate_dtp_update(pDM_Odm); + pDM_PathDiv->dtp_state = PHYDM_DTP_RUNNING_1; + } + + else if( pDM_PathDiv->dtp_state == PHYDM_DTP_RUNNING_1) + { + pDM_PathDiv->dtp_check_patha_counter++; + + if(pDM_PathDiv->dtp_check_patha_counter>=NUM_RESET_DTP_PERIOD) + { + pDM_PathDiv->dtp_check_patha_counter=0; + pDM_PathDiv->dtp_state = PHYDM_DTP_INIT; + } + //2 Search space update + else + { + // 1. find the worst candidate + + + // 2. repalce the worst candidate + } + } + } + + //2 Dynamic Path Selection H2C + + if(pDM_PathDiv->num_candidate == 1) + { + return; + } + else + { + H2C_Parameter[0] = pDM_PathDiv->num_candidate; + H2C_Parameter[1] = pDM_PathDiv->num_tx_path; + H2C_Parameter[2] = pDM_PathDiv->ant_candidate_1; + H2C_Parameter[3] = pDM_PathDiv->ant_candidate_2; + H2C_Parameter[4] = pDM_PathDiv->ant_candidate_3; + + ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_DYNAMIC_TX_PATH, 6, H2C_Parameter); + } + +} + + + +VOID +phydm_dynamic_tx_path_init( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &(pDM_Odm->DM_PathDiv); + PADAPTER pAdapter = pDM_Odm->Adapter; + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + USB_MODE_MECH *pUsbModeMech = &pAdapter->UsbModeMechanism; + #endif + u1Byte search_space_2[NUM_CHOOSE2_FROM4]= {PHYDM_AB, PHYDM_AC, PHYDM_AD, PHYDM_BC, PHYDM_BD, PHYDM_CD }; + u1Byte search_space_3[NUM_CHOOSE3_FROM4]= {PHYDM_BCD, PHYDM_ACD, PHYDM_ABD, PHYDM_ABC}; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pDM_PathDiv->is_u3_mode = (pUsbModeMech->CurUsbMode==USB_MODE_U3)? 1 : 0 ; + #else + pDM_PathDiv->is_u3_mode = 1; + #endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Dynamic TX Path Init 8814\n")); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("is_u3_mode = (( %d ))\n", pDM_PathDiv->is_u3_mode)); + + memcpy(&(pDM_PathDiv->search_space_2[0]), &(search_space_2[0]), NUM_CHOOSE2_FROM4); + memcpy(&(pDM_PathDiv->search_space_3[0]), &(search_space_3[0]), NUM_CHOOSE3_FROM4); + + pDM_PathDiv->use_path_a_as_default_ant= 1; + pDM_PathDiv->dtp_state = PHYDM_DTP_INIT; + pDM_Odm->path_select = PHYDM_AUTO_PATH; + pDM_PathDiv->path_div_type = PHYDM_4R_PATH_DIV; + + + if(pDM_PathDiv->is_u3_mode ) + { + pDM_PathDiv->num_tx_path=3; + phydm_dtp_fix_tx_path(pDM_Odm, PHYDM_BCD);/* 3TX Set Init TX Path*/ + + } + else + { + pDM_PathDiv->num_tx_path=2; + phydm_dtp_fix_tx_path(pDM_Odm, PHYDM_BC);/* 2TX // Set Init TX Path*/ + } + +} + + +VOID +phydm_process_rssi_for_path_div( + IN OUT PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_PHY_INFO_T pPhyInfo=(PODM_PHY_INFO_T)p_phy_info_void; + PODM_PACKET_INFO_T pPktinfo=(PODM_PACKET_INFO_T)p_pkt_info_void; + pPATHDIV_T pDM_PathDiv = &(pDM_Odm->DM_PathDiv); + + if(pPktinfo->bPacketToSelf || pPktinfo->bPacketMatchBSSID) + { + if(pPktinfo->DataRate > ODM_RATE11M) + { + if(pDM_PathDiv->path_div_type == PHYDM_4R_PATH_DIV) + { + #if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType & ODM_RTL8814A) + { + pDM_PathDiv->path_a_sum_all+=pPhyInfo->RxMIMOSignalStrength[0]; + pDM_PathDiv->path_a_cnt_all++; + + pDM_PathDiv->path_b_sum_all+=pPhyInfo->RxMIMOSignalStrength[1]; + pDM_PathDiv->path_b_cnt_all++; + + pDM_PathDiv->path_c_sum_all+=pPhyInfo->RxMIMOSignalStrength[2]; + pDM_PathDiv->path_c_cnt_all++; + + pDM_PathDiv->path_d_sum_all+=pPhyInfo->RxMIMOSignalStrength[3]; + pDM_PathDiv->path_d_cnt_all++; + } + #endif + } + else + { + pDM_PathDiv->PathA_Sum[pPktinfo->StationID]+=pPhyInfo->RxMIMOSignalStrength[0]; + pDM_PathDiv->PathA_Cnt[pPktinfo->StationID]++; + + pDM_PathDiv->PathB_Sum[pPktinfo->StationID]+=pPhyInfo->RxMIMOSignalStrength[1]; + pDM_PathDiv->PathB_Cnt[pPktinfo->StationID]++; + } + } + } + + +} + +#endif //#if RTL8814A_SUPPORT + +VOID +odm_pathdiv_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &(pDM_Odm->DM_PathDiv); + u4Byte used = *_used; + u4Byte out_len = *_out_len; + + pDM_Odm->path_select = (dm_value[0] & 0xf); + PHYDM_SNPRINTF((output+used, out_len-used,"Path_select = (( 0x%x ))\n",pDM_Odm->path_select )); + + //2 [Fix Path] + if (pDM_Odm->path_select != PHYDM_AUTO_PATH) + { + PHYDM_SNPRINTF((output+used, out_len-used,"Trun on path [%s%s%s%s]\n", + ((pDM_Odm->path_select) & 0x1)?"A":"", + ((pDM_Odm->path_select) & 0x2)?"B":"", + ((pDM_Odm->path_select) & 0x4)?"C":"", + ((pDM_Odm->path_select) & 0x8)?"D":"" )); + + phydm_dtp_fix_tx_path( pDM_Odm, pDM_Odm->path_select ); + } + else + { + PHYDM_SNPRINTF((output+used, out_len-used,"%s\n","Auto Path")); + } +} + +#endif // #if(defined(CONFIG_PATH_DIVERSITY)) + +VOID +phydm_c2h_dtp_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +) +{ +#if(defined(CONFIG_PATH_DIVERSITY)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pPATHDIV_T pDM_PathDiv = &(pDM_Odm->DM_PathDiv); + + u1Byte macid = CmdBuf[0]; + u1Byte target = CmdBuf[1]; + u1Byte nsc_1 = CmdBuf[2]; + u1Byte nsc_2 = CmdBuf[3]; + u1Byte nsc_3 = CmdBuf[4]; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_PATH_DIV,ODM_DBG_LOUD,("Target_candidate = (( %d ))\n", target)); + /* + if( (nsc_1 >= nsc_2) && (nsc_1 >= nsc_3)) + { + phydm_dtp_fix_tx_path(pDM_Odm, pDM_PathDiv->ant_candidate_1); + } + else if( nsc_2 >= nsc_3) + { + phydm_dtp_fix_tx_path(pDM_Odm, pDM_PathDiv->ant_candidate_2); + } + else + { + phydm_dtp_fix_tx_path(pDM_Odm, pDM_PathDiv->ant_candidate_3); + } + */ +#endif +} + +VOID +odm_PathDiversity( + IN PVOID pDM_VOID +) +{ +#if(defined(CONFIG_PATH_DIVERSITY)) + 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); + else + #endif + + #if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType & ODM_RTL8814A) + phydm_dynamic_tx_path(pDM_Odm); + else + #endif + {} +#endif +} + +VOID +odm_PathDiversityInit( + IN PVOID pDM_VOID +) +{ +#if(defined(CONFIG_PATH_DIVERSITY)) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + /*pDM_Odm->SupportAbility |= ODM_BB_PATH_DIV;*/ + + 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); + else + #endif + + #if RTL8814A_SUPPORT + if(pDM_Odm->SupportICType & ODM_RTL8814A) + phydm_dynamic_tx_path_init(pDM_Odm); + else + #endif + {} +#endif +} + + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +// +// 2011/12/02 MH Copy from MP oursrc for temporarily test. +// +#if RTL8192C_SUPPORT +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; + 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; + + 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_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; + 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)) + 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; + 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); + } + +} +#else + +VOID +odm_PathDivChkAntSwitchCallback( + PRT_TIMER pTimer +) +{ +} + +VOID +odm_PathDivChkAntSwitchWorkitemCallback( + IN PVOID pContext + ) +{ +} + +VOID +odm_CCKTXPathDiversityCallback( + PRT_TIMER pTimer +) +{ +} + +VOID +odm_CCKTXPathDiversityWorkItemCallback( + IN PVOID pContext + ) +{ +} +u1Byte +odm_SwAntDivSelectScanChnl( + IN PADAPTER Adapter + ) +{ + return 0; +} +VOID +odm_SwAntDivConstructScanChnl( + IN PADAPTER Adapter, + IN u1Byte ScanChnl + ) +{ +} + + +#endif + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.h new file mode 100644 index 00000000..ca2116f4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pathdiv.h @@ -0,0 +1,324 @@ +/****************************************************************************** + * + * 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 "2.0" //2014.11.04*/ +#define PATHDIV_VERSION "3.0" /*2015.01.13 Dino*/ + +#if(defined(CONFIG_PATH_DIVERSITY)) +#define USE_PATH_A_AS_DEFAULT_ANT //for 8814 dynamic TX path selection + +#define NUM_RESET_DTP_PERIOD 5 +#define ANT_DECT_RSSI_TH 3 + +#define PATH_A 1 +#define PATH_B 2 +#define PATH_C 3 +#define PATH_D 4 + +#define PHYDM_AUTO_PATH 0 +#define PHYDM_FIX_PATH 1 + +#define NUM_CHOOSE2_FROM4 6 +#define NUM_CHOOSE3_FROM4 4 + + +#define PHYDM_A BIT0 +#define PHYDM_B BIT1 +#define PHYDM_C BIT2 +#define PHYDM_D BIT3 +#define PHYDM_AB (BIT0 | BIT1) // 0 +#define PHYDM_AC (BIT0 | BIT2) // 1 +#define PHYDM_AD (BIT0 | BIT3) // 2 +#define PHYDM_BC (BIT1 | BIT2) // 3 +#define PHYDM_BD (BIT1 | BIT3) // 4 +#define PHYDM_CD (BIT2 | BIT3) // 5 + +#define PHYDM_ABC (BIT0 | BIT1 | BIT2) /* 0*/ +#define PHYDM_ABD (BIT0 | BIT1 | BIT3) /* 1*/ +#define PHYDM_ACD (BIT0 | BIT2 | BIT3) /* 2*/ +#define PHYDM_BCD (BIT1 | BIT2 | BIT3) /* 3*/ + +#define PHYDM_ABCD (BIT0 | BIT1 | BIT2 | BIT3) + + +typedef enum dtp_state +{ + PHYDM_DTP_INIT=1, + PHYDM_DTP_RUNNING_1 + +}PHYDM_DTP_STATE; + +typedef enum path_div_type +{ + PHYDM_2R_PATH_DIV = 1, + PHYDM_4R_PATH_DIV = 2 +}PHYDM_PATH_DIV_TYPE; + +VOID +phydm_process_rssi_for_path_div( + IN OUT PVOID pDM_VOID, + IN PVOID p_phy_info_void, + IN PVOID p_pkt_info_void + ); + +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]; + u2Byte PathA_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u2Byte PathB_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte path_div_type; + #if RTL8814A_SUPPORT + + u4Byte path_a_sum_all; + u4Byte path_b_sum_all; + u4Byte path_c_sum_all; + u4Byte path_d_sum_all; + + u4Byte path_a_cnt_all; + u4Byte path_b_cnt_all; + u4Byte path_c_cnt_all; + u4Byte path_d_cnt_all; + + u1Byte dtp_period; + BOOLEAN bBecomeLinked; + BOOLEAN is_u3_mode; + u1Byte num_tx_path; + u1Byte default_path; + u1Byte num_candidate; + u1Byte ant_candidate_1; + u1Byte ant_candidate_2; + u1Byte ant_candidate_3; + u1Byte dtp_state; + u1Byte dtp_check_patha_counter; + BOOLEAN fix_path_bfer; + u1Byte search_space_2[NUM_CHOOSE2_FROM4]; + u1Byte search_space_3[NUM_CHOOSE3_FROM4]; + + u1Byte pre_tx_path; + u1Byte use_path_a_as_default_ant; + BOOLEAN is_pathA_exist; + + #endif +}PATHDIV_T, *pPATHDIV_T; + + +#endif //#if(defined(CONFIG_PATH_DIVERSITY)) + +VOID +phydm_c2h_dtp_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen + ); + +VOID +odm_PathDiversityInit( + IN PVOID pDM_VOID + ); + +VOID +odm_PathDiversity( + IN PVOID pDM_VOID + ); + +VOID +odm_pathdiv_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value, + IN u4Byte *_used, + OUT char *output, + IN u4Byte *_out_len + ); + + + +//1 [OLD IC]-------------------------------------------------------------------------------- + + + + + + +#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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.c new file mode 100644 index 00000000..fce05cb6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.c @@ -0,0 +1,1050 @@ +/****************************************************************************** + * + * 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 !defined(_OUTSRC_COEXIST) +//============================================================ +// Global var +//============================================================ + + +u4Byte OFDMSwingTable_New[OFDM_TABLE_SIZE_92D] = { + 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 + {0x1c, 0x1a, 0x18, 0x12, 0x0e, 0x08, 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 + {0x1c, 0x1a, 0x18, 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 OFDMSwingTable[OFDM_TABLE_SIZE_92D] = { + 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[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 + {0x1c, 0x1a, 0x18, 0x12, 0x0e, 0x08, 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 [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 + {0x1c, 0x1a, 0x18, 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 +}; + +u1Byte CCKSwingTable_Ch1_Ch14_88F[CCK_TABLE_SIZE_88F][16] = { +{0x16, 0x15, 0x13, 0x10, 0xD, 0x9, 0x6, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0 -16dB */ +{0x18, 0x17, 0x15, 0x12, 0xE, 0xA, 0x7, 0x4, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 1 -15.5dB */ +{0x1B, 0x1A, 0x18, 0x14, 0x10, 0xB, 0x7, 0x4, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 2 -15dB */ +{0x1F, 0x1E, 0x1B, 0x17, 0x12, 0xD, 0x8, 0x5, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 3 -14.5dB */ +{0x22, 0x21, 0x1E, 0x19, 0x14, 0xE, 0x9, 0x5, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 4 -14dB */ +{0x26, 0x25, 0x22, 0x1C, 0x16, 0x10, 0xA, 0x6, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 5 -13.5dB */ +{0x2B, 0x2A, 0x26, 0x20, 0x19, 0x12, 0xC, 0x7, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 6 -13dB */ +{0x30, 0x2F, 0x2A, 0x24, 0x1C, 0x14, 0xD, 0x8, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 7 -12.5dB */ +{0x36, 0x34, 0x2F, 0x28, 0x1F, 0x17, 0xF, 0x9, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 8 -12dB */ +{0x3D, 0x3B, 0x35, 0x2D, 0x23, 0x19, 0x11, 0xA, 0x5, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 9 -11.5dB */ +{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0xB, 0x5, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 10 -11dB */ +{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0xC, 0x6, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 11 -10.5dB */ +{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0xE, 0x6, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 12 -10dB */ +{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0xF, 0x7, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 13 -9.5dB */ +{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x8, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 14 -9dB */ +{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x9, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 15 -8.5dB */ +{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0xA, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 16 -8dB */ +{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0xB, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 17 -7.5dB */ +{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0xD, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 18 -7dB */ +{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0xE, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 19 -6.5dB */ +{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} /* 20 -6dB */ +}; + + +#if 0 +u4Byte OFDMSwingTable_92E[OFDM_TABLE_SIZE_92E] = { + /* Index0 6 dB */ 0x7fc001ff, + /* Index1 5.7dB */ 0x7b4001ed, + /* Index2 5.4dB */ 0x774001dd, + /* Index3 5.1dB */ 0x734001cd, + /* Index4 4.8dB */ 0x6f4001bd, + /* Index5 4.5dB */ 0x6b8001ae, + /* Index6 4.2dB */ 0x67c0019f, + /* Index7 3.9dB */ 0x64400191, + /* Index8 3.6dB */ 0x60c00183, + /* Index9 3.3dB */ 0x5d800176, + /* Index10 3 dB */ 0x5a80016a, + /* Index11 2.7dB */ 0x5740015d, + /* Index12 2.4dB */ 0x54400151, + /* Index13 2.1dB */ 0x51800146, + /* Index14 1.8dB */ 0x4ec0013b, + /* Index15 1.5dB */ 0x4c000130, + /* Index16 1.2dB */ 0x49800126, + /* Index17 0.9dB */ 0x4700011c, + /* Index18 0.6dB */ 0x44800112, + /* Index19 0.3dB */ 0x42000108, + /* Index20 0 dB */ 0x40000100, // 20 This is OFDM base index + /* Index21 -0.3dB */ 0x3dc000f7, + /* Index22 -0.6dB */ 0x3bc000ef, + /* Index23 -0.9dB */ 0x39c000e7, + /* Index24 -1.2dB */ 0x37c000df, + /* Index25 -1.5dB */ 0x35c000d7, + /* Index26 -1.8dB */ 0x340000d0, + /* Index27 -2.1dB */ 0x324000c9, + /* Index28 -2.4dB */ 0x308000c2, + /* Index29 -2.7dB */ 0x2f0000bc, + /* Index30 -3 dB */ 0x2d4000b5, + /* Index31 -3.3dB */ 0x2bc000af, + /* Index32 -3.6dB */ 0x2a4000a9, + /* Index33 -3.9dB */ 0x28c000a3, + /* Index34 -4.2dB */ 0x2780009e, + /* Index35 -4.5dB */ 0x26000098, + /* Index36 -4.8dB */ 0x24c00093, + /* Index37 -5.1dB */ 0x2380008e, + /* Index38 -5.4dB */ 0x22400089, + /* Index39 -5.7dB */ 0x21400085, + /* Index40 -6 dB */ 0x20000080, + /* Index41 -6.3dB */ 0x1f00007c, + /* Index42 -6.6dB */ 0x1e000078, + /* Index43 -6.9dB */ 0x1d000074, + /* Index44 -7.2dB */ 0x1c000070, + /* Index45 -7.5dB */ 0x1b00006c, + /* Index46 -7.8dB */ 0x1a000068, + /* Index47 -8.1dB */ 0x19400065, + /* Index48 -8.4dB */ 0x18400061, + /* Index49 -8.7dB */ 0x1780005e, + /* Index50 -9 dB */ 0x16c0005b, + /* Index51 -9.3dB */ 0x16000058, + /* Index52 -9.6dB */ 0x15400055, + /* Index53 -9.9dB */ 0x14800052 +}; +u1Byte CCKSwingTable_Ch1_Ch13_92E[CCK_TABLE_SIZE_92E][8] = { + /* Index0 0 dB */ {0x36, 0x34 , 0x2E , 0x26 , 0x1C , 0x12 , 0x08 , 0x04}, + /* Index1 -0.3dB */ {0x34, 0x32 , 0x2C , 0x25 , 0x1B , 0x11 , 0x08 , 0x04}, + /* Index2 -0.6dB */ {0x32, 0x30 , 0x2B , 0x23 , 0x1A , 0x11 , 0x07 , 0x04}, + /* Index3 -0.9dB */ {0x31, 0x2F , 0x29 , 0x22 , 0x19 , 0x10 , 0x07 , 0x04}, + /* Index4 -1.2dB */ {0x2F, 0x2D , 0x28 , 0x21 , 0x18 , 0x10 , 0x07 , 0x03}, + /* Index5 -1.5dB */ {0x2D, 0x2C , 0x27 , 0x20 , 0x18 , 0x0F , 0x07 , 0x03}, + /* Index6 -1.8dB */ {0x2C, 0x2A , 0x25 , 0x1F , 0x17 , 0x0F , 0x06 , 0x03}, + /* Index7 -2.1dB */ {0x2A, 0x29 , 0x24 , 0x1E , 0x16 , 0x0E , 0x06 , 0x03}, + /* Index8 -2.4dB */ {0x29, 0x27 , 0x23 , 0x1D , 0x15 , 0x0E , 0x06 , 0x03}, + /* Index9 -2.7dB */ {0x27, 0x26 , 0x22 , 0x1C , 0x14 , 0x0D , 0x06 , 0x03}, + /* Index10 -3 dB */ {0x26, 0x25 , 0x20 , 0x1B , 0x14 , 0x0D , 0x06 , 0x03}, + /* Index11 -3.3dB */ {0x25, 0x23 , 0x1F , 0x1A , 0x13 , 0x0C , 0x05 , 0x03}, + /* Index12 -3.6dB */ {0x24, 0x22 , 0x1E , 0x19 , 0x12 , 0x0C , 0x05 , 0x03}, + /* Index13 -3.9dB */ {0x22, 0x21 , 0x1D , 0x18 , 0x12 , 0x0B , 0x05 , 0x03}, + /* Index14 -4.2dB */ {0x21, 0x20 , 0x1C , 0x17 , 0x11 , 0x0B , 0x05 , 0x02}, + /* Index15 -4.5dB */ {0x20, 0x1F , 0x1B , 0x17 , 0x11 , 0x0B , 0x05 , 0x02}, + /* Index16 -4.8dB */ {0x1F, 0x1E , 0x1A , 0x16 , 0x10 , 0x0A , 0x05 , 0x02}, + /* Index17 -5.1dB */ {0x1E, 0x1D , 0x1A , 0x15 , 0x10 , 0x0A , 0x04 , 0x02}, + /* Index18 -5.4dB */ {0x1D, 0x1C , 0x19 , 0x14 , 0x0F , 0x0A , 0x04 , 0x02}, + /* Index19 -5.7dB */ {0x1C, 0x1B , 0x18 , 0x14 , 0x0E , 0x09 , 0x04 , 0x02}, + /* Index20 -6.0dB */ {0x1B, 0x1A , 0x17 , 0x13 , 0x0E , 0x09 , 0x04 , 0x02}, // 20 This is CCK base index + /* Index21 -6.3dB */ {0x1A, 0x19 , 0x16 , 0x12 , 0x0E , 0x09 , 0x04 , 0x02}, + /* Index22 -6.6dB */ {0x19, 0x18 , 0x15 , 0x12 , 0x0D , 0x08 , 0x04 , 0x02}, + /* Index23 -6.9dB */ {0x18, 0x17 , 0x15 , 0x11 , 0x0D , 0x08 , 0x04 , 0x02}, + /* Index24 -7.2dB */ {0x18, 0x17 , 0x14 , 0x11 , 0x0C , 0x08 , 0x03 , 0x02}, + /* Index25 -7.5dB */ {0x17, 0x16 , 0x13 , 0x10 , 0x0C , 0x08 , 0x03 , 0x02}, + /* Index26 -7.8dB */ {0x16, 0x15 , 0x13 , 0x0F , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index27 -8.1dB */ {0x15, 0x14 , 0x12 , 0x0F , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index28 -8.4dB */ {0x14, 0x14 , 0x11 , 0x0E , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index29 -8.7dB */ {0x14, 0x13 , 0x11 , 0x0E , 0x0A , 0x07 , 0x03 , 0x01}, + /* Index30 -9.0dB */ {0x13, 0x12 , 0x10 , 0x0D , 0x0A , 0x06 , 0x03 , 0x01}, // 30 This is hp CCK base index + /* Index31 -9.3dB */ {0x12, 0x12 , 0x0F , 0x0D , 0x0A , 0x06 , 0x03 , 0x01}, + /* Index32 -9.6dB */ {0x12, 0x11 , 0x0F , 0x0D , 0x09 , 0x06 , 0x03 , 0x01}, + /* Index33 -9.9dB */ {0x11, 0x11 , 0x0F , 0x0C , 0x09 , 0x06 , 0x03 , 0x01}, + /* Index34 -10.2dB */ {0x11, 0x11 , 0x0E , 0x0C , 0x09 , 0x06 , 0x02 , 0x01}, + /* Index35 -10.5dB */ {0x10, 0x0F , 0x0E , 0x0B , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index36 -10.8dB */ {0x10, 0x0F , 0x0D , 0x0B , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index37 -11.1dB */ {0x0F, 0x0E , 0x0D , 0x0A , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index38 -11.4dB */ {0x0E, 0x0E , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index39 -11.7dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index40 -12 dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index41 -12.3dB */ {0x0D, 0x0D , 0x0B , 0x09 , 0x07 , 0x04 , 0x02 , 0x01}, + /* Index42 -12.6dB */ {0x0D, 0x0C , 0x0B , 0x09 , 0x07 , 0x04 , 0x02 , 0x01}, + /* Index43 -12.9dB */ {0x0C, 0x0C , 0x0A , 0x09 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index44 -13.2dB */ {0x0C, 0x0B , 0x0A , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index45 -13.5dB */ {0x0B, 0x0B , 0x0A , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index46 -13.8dB */ {0x0B, 0x0B , 0x09 , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index47 -14.1dB */ {0x0B, 0x0A , 0x09 , 0x07 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index48 -14.4dB */ {0x0A, 0x0A , 0x09 , 0x07 , 0x05 , 0x03 , 0x02 , 0x01}, + /* Index49 -14.7dB */ {0x0A, 0x0A , 0x08 , 0x07 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index50 -15 dB */ {0x0A, 0x09 , 0x08 , 0x07 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index51 -15.3dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index52 -15.6dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index53 -15.9dB */ {0x09, 0x08 , 0x07 , 0x06 , 0x04 , 0x03 , 0x01 , 0x01} +}; +u1Byte CCKSwingTable_Ch14_92E[CCK_TABLE_SIZE_92E][8] = { + /* Index0 0 dB */ {0x36, 0x34 , 0x2E , 0x26 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index1 -0.3dB */ {0x34, 0x32 , 0x2C , 0x25 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index2 -0.6dB */ {0x32, 0x30 , 0x2B , 0x23 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index3 -0.9dB */ {0x31, 0x2F , 0x29 , 0x22 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index4 -1.2dB */ {0x2F, 0x2D , 0x28 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index5 -1.5dB */ {0x2D, 0x2C , 0x27 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index6 -1.8dB */ {0x2C, 0x2A , 0x25 , 0x1F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index7 -2.1dB */ {0x2A, 0x29 , 0x24 , 0x1E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index8 -2.4dB */ {0x29, 0x27 , 0x23 , 0x1D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index9 -2.7dB */ {0x27, 0x26 , 0x22 , 0x1C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index10 -3 dB */ {0x26, 0x25 , 0x20 , 0x1B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index11 -3.3dB */ {0x25, 0x23 , 0x1F , 0x1A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index12 -3.6dB */ {0x24, 0x22 , 0x1E , 0x19 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index13 -3.9dB */ {0x22, 0x21 , 0x1D , 0x18 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index14 -4.2dB */ {0x21, 0x20 , 0x1C , 0x17 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index15 -4.5dB */ {0x20, 0x1F , 0x1B , 0x17 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index16 -4.8dB */ {0x1F, 0x1E , 0x1A , 0x16 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index17 -5.1dB */ {0x1E, 0x1D , 0x1A , 0x15 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index18 -5.4dB */ {0x1D, 0x1C , 0x19 , 0x14 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index19 -5.7dB */ {0x1C, 0x1B , 0x18 , 0x14 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index20 -6 dB */ {0x1B, 0x1A , 0x17 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index21 -6.3dB */ {0x1A, 0x19 , 0x16 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index22 -6.6dB */ {0x19, 0x18 , 0x15 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index23 -6.9dB */ {0x18, 0x17 , 0x15 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index24 -7.2dB */ {0x18, 0x17 , 0x14 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index25 -7.5dB */ {0x17, 0x16 , 0x13 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index26 -7.8dB */ {0x16, 0x15 , 0x13 , 0x0F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index27 -8.1dB */ {0x15, 0x14 , 0x12 , 0x0F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index28 -8.4dB */ {0x14, 0x14 , 0x11 , 0x0E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index29 -8.7dB */ {0x14, 0x13 , 0x11 , 0x0E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index30 -9 dB */ {0x13, 0x12 , 0x10 , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index31 -9.3dB */ {0x12, 0x12 , 0x0F , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index32 -9.6dB */ {0x12, 0x11 , 0x0F , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index33 -9.9dB */ {0x11, 0x11 , 0x0F , 0x0C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index34 -10.2dB */ {0x11, 0x11 , 0x0E , 0x0C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index35 -10.5dB */ {0x10, 0x0F , 0x0E , 0x0B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index36 -10.8dB */ {0x10, 0x0F , 0x0D , 0x0B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index37 -11.1dB */ {0x0F, 0x0E , 0x0D , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index38 -11.4dB */ {0x0E, 0x0E , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index39 -11.7dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index40 -12 dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index41 -12.3dB */ {0x0D, 0x0D , 0x0B , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index42 -12.6dB */ {0x0D, 0x0C , 0x0B , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index43 -12.9dB */ {0x0C, 0x0C , 0x0A , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index44 -13.2dB */ {0x0C, 0x0B , 0x0A , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index45 -13.5dB */ {0x0B, 0x0B , 0x0A , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index46 -13.8dB */ {0x0B, 0x0B , 0x09 , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index47 -14.1dB */ {0x0B, 0x0A , 0x09 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index48 -14.4dB */ {0x0A, 0x0A , 0x09 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index49 -14.7dB */ {0x0A, 0x0A , 0x08 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index50 -15 dB */ {0x0A, 0x09 , 0x08 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index51 -15.3dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index52 -15.6dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index53 -15.9dB */ {0x09, 0x08 , 0x07 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00} +}; +#endif + +#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 + +#endif + + +u1Byte DeltaSwingTableIdx_2GA_P_DEFAULT[DELTA_SWINGIDX_SIZE] = {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}; +u1Byte DeltaSwingTableIdx_2GA_N_DEFAULT[DELTA_SWINGIDX_SIZE] = {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}; + + +#ifdef CONFIG_WLAN_HAL_8192EE +u4Byte OFDMSwingTable_92E[OFDM_TABLE_SIZE_92E] = { + /* Index0 6 dB */ 0x7fc001ff, + /* Index1 5.7dB */ 0x7b4001ed, + /* Index2 5.4dB */ 0x774001dd, + /* Index3 5.1dB */ 0x734001cd, + /* Index4 4.8dB */ 0x6f4001bd, + /* Index5 4.5dB */ 0x6b8001ae, + /* Index6 4.2dB */ 0x67c0019f, + /* Index7 3.9dB */ 0x64400191, + /* Index8 3.6dB */ 0x60c00183, + /* Index9 3.3dB */ 0x5d800176, + /* Index10 3 dB */ 0x5a80016a, + /* Index11 2.7dB */ 0x5740015d, + /* Index12 2.4dB */ 0x54400151, + /* Index13 2.1dB */ 0x51800146, + /* Index14 1.8dB */ 0x4ec0013b, + /* Index15 1.5dB */ 0x4c000130, + /* Index16 1.2dB */ 0x49800126, + /* Index17 0.9dB */ 0x4700011c, + /* Index18 0.6dB */ 0x44800112, + /* Index19 0.3dB */ 0x42000108, + /* Index20 0 dB */ 0x40000100, // 20 This is OFDM base index + /* Index21 -0.3dB */ 0x3dc000f7, + /* Index22 -0.6dB */ 0x3bc000ef, + /* Index23 -0.9dB */ 0x39c000e7, + /* Index24 -1.2dB */ 0x37c000df, + /* Index25 -1.5dB */ 0x35c000d7, + /* Index26 -1.8dB */ 0x340000d0, + /* Index27 -2.1dB */ 0x324000c9, + /* Index28 -2.4dB */ 0x308000c2, + /* Index29 -2.7dB */ 0x2f0000bc, + /* Index30 -3 dB */ 0x2d4000b5, + /* Index31 -3.3dB */ 0x2bc000af, + /* Index32 -3.6dB */ 0x2a4000a9, + /* Index33 -3.9dB */ 0x28c000a3, + /* Index34 -4.2dB */ 0x2780009e, + /* Index35 -4.5dB */ 0x26000098, + /* Index36 -4.8dB */ 0x24c00093, + /* Index37 -5.1dB */ 0x2380008e, + /* Index38 -5.4dB */ 0x22400089, + /* Index39 -5.7dB */ 0x21400085, + /* Index40 -6 dB */ 0x20000080, + /* Index41 -6.3dB */ 0x1f00007c, + /* Index42 -6.6dB */ 0x1e000078, + /* Index43 -6.9dB */ 0x1d000074, + /* Index44 -7.2dB */ 0x1c000070, + /* Index45 -7.5dB */ 0x1b00006c, + /* Index46 -7.8dB */ 0x1a000068, + /* Index47 -8.1dB */ 0x19400065, + /* Index48 -8.4dB */ 0x18400061, + /* Index49 -8.7dB */ 0x1780005e, + /* Index50 -9 dB */ 0x16c0005b, + /* Index51 -9.3dB */ 0x16000058, + /* Index52 -9.6dB */ 0x15400055, + /* Index53 -9.9dB */ 0x14800052 +}; +u1Byte CCKSwingTable_Ch1_Ch13_92E[CCK_TABLE_SIZE_92E][8] = { + /* Index0 0 dB */ {0x36, 0x34 , 0x2E , 0x26 , 0x1C , 0x12 , 0x08 , 0x04}, + /* Index1 -0.3dB */ {0x34, 0x32 , 0x2C , 0x25 , 0x1B , 0x11 , 0x08 , 0x04}, + /* Index2 -0.6dB */ {0x32, 0x30 , 0x2B , 0x23 , 0x1A , 0x11 , 0x07 , 0x04}, + /* Index3 -0.9dB */ {0x31, 0x2F , 0x29 , 0x22 , 0x19 , 0x10 , 0x07 , 0x04}, + /* Index4 -1.2dB */ {0x2F, 0x2D , 0x28 , 0x21 , 0x18 , 0x10 , 0x07 , 0x03}, + /* Index5 -1.5dB */ {0x2D, 0x2C , 0x27 , 0x20 , 0x18 , 0x0F , 0x07 , 0x03}, + /* Index6 -1.8dB */ {0x2C, 0x2A , 0x25 , 0x1F , 0x17 , 0x0F , 0x06 , 0x03}, + /* Index7 -2.1dB */ {0x2A, 0x29 , 0x24 , 0x1E , 0x16 , 0x0E , 0x06 , 0x03}, + /* Index8 -2.4dB */ {0x29, 0x27 , 0x23 , 0x1D , 0x15 , 0x0E , 0x06 , 0x03}, + /* Index9 -2.7dB */ {0x27, 0x26 , 0x22 , 0x1C , 0x14 , 0x0D , 0x06 , 0x03}, + /* Index10 -3 dB */ {0x26, 0x25 , 0x20 , 0x1B , 0x14 , 0x0D , 0x06 , 0x03}, + /* Index11 -3.3dB */ {0x25, 0x23 , 0x1F , 0x1A , 0x13 , 0x0C , 0x05 , 0x03}, + /* Index12 -3.6dB */ {0x24, 0x22 , 0x1E , 0x19 , 0x12 , 0x0C , 0x05 , 0x03}, + /* Index13 -3.9dB */ {0x22, 0x21 , 0x1D , 0x18 , 0x12 , 0x0B , 0x05 , 0x03}, + /* Index14 -4.2dB */ {0x21, 0x20 , 0x1C , 0x17 , 0x11 , 0x0B , 0x05 , 0x02}, + /* Index15 -4.5dB */ {0x20, 0x1F , 0x1B , 0x17 , 0x11 , 0x0B , 0x05 , 0x02}, + /* Index16 -4.8dB */ {0x1F, 0x1E , 0x1A , 0x16 , 0x10 , 0x0A , 0x05 , 0x02}, + /* Index17 -5.1dB */ {0x1E, 0x1D , 0x1A , 0x15 , 0x10 , 0x0A , 0x04 , 0x02}, + /* Index18 -5.4dB */ {0x1D, 0x1C , 0x19 , 0x14 , 0x0F , 0x0A , 0x04 , 0x02}, + /* Index19 -5.7dB */ {0x1C, 0x1B , 0x18 , 0x14 , 0x0E , 0x09 , 0x04 , 0x02}, + /* Index20 -6.0dB */ {0x1B, 0x1A , 0x17 , 0x13 , 0x0E , 0x09 , 0x04 , 0x02}, // 20 This is CCK base index + /* Index21 -6.3dB */ {0x1A, 0x19 , 0x16 , 0x12 , 0x0E , 0x09 , 0x04 , 0x02}, + /* Index22 -6.6dB */ {0x19, 0x18 , 0x15 , 0x12 , 0x0D , 0x08 , 0x04 , 0x02}, + /* Index23 -6.9dB */ {0x18, 0x17 , 0x15 , 0x11 , 0x0D , 0x08 , 0x04 , 0x02}, + /* Index24 -7.2dB */ {0x18, 0x17 , 0x14 , 0x11 , 0x0C , 0x08 , 0x03 , 0x02}, + /* Index25 -7.5dB */ {0x17, 0x16 , 0x13 , 0x10 , 0x0C , 0x08 , 0x03 , 0x02}, + /* Index26 -7.8dB */ {0x16, 0x15 , 0x13 , 0x0F , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index27 -8.1dB */ {0x15, 0x14 , 0x12 , 0x0F , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index28 -8.4dB */ {0x14, 0x14 , 0x11 , 0x0E , 0x0B , 0x07 , 0x03 , 0x02}, + /* Index29 -8.7dB */ {0x14, 0x13 , 0x11 , 0x0E , 0x0A , 0x07 , 0x03 , 0x01}, + /* Index30 -9.0dB */ {0x13, 0x12 , 0x10 , 0x0D , 0x0A , 0x06 , 0x03 , 0x01}, // 30 This is hp CCK base index + /* Index31 -9.3dB */ {0x12, 0x12 , 0x0F , 0x0D , 0x0A , 0x06 , 0x03 , 0x01}, + /* Index32 -9.6dB */ {0x12, 0x11 , 0x0F , 0x0D , 0x09 , 0x06 , 0x03 , 0x01}, + /* Index33 -9.9dB */ {0x11, 0x11 , 0x0F , 0x0C , 0x09 , 0x06 , 0x03 , 0x01}, + /* Index34 -10.2dB */ {0x11, 0x11 , 0x0E , 0x0C , 0x09 , 0x06 , 0x02 , 0x01}, + /* Index35 -10.5dB */ {0x10, 0x0F , 0x0E , 0x0B , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index36 -10.8dB */ {0x10, 0x0F , 0x0D , 0x0B , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index37 -11.1dB */ {0x0F, 0x0E , 0x0D , 0x0A , 0x08 , 0x05 , 0x02 , 0x01}, + /* Index38 -11.4dB */ {0x0E, 0x0E , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index39 -11.7dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index40 -12 dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x07 , 0x05 , 0x02 , 0x01}, + /* Index41 -12.3dB */ {0x0D, 0x0D , 0x0B , 0x09 , 0x07 , 0x04 , 0x02 , 0x01}, + /* Index42 -12.6dB */ {0x0D, 0x0C , 0x0B , 0x09 , 0x07 , 0x04 , 0x02 , 0x01}, + /* Index43 -12.9dB */ {0x0C, 0x0C , 0x0A , 0x09 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index44 -13.2dB */ {0x0C, 0x0B , 0x0A , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index45 -13.5dB */ {0x0B, 0x0B , 0x0A , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index46 -13.8dB */ {0x0B, 0x0B , 0x09 , 0x08 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index47 -14.1dB */ {0x0B, 0x0A , 0x09 , 0x07 , 0x06 , 0x04 , 0x02 , 0x01}, + /* Index48 -14.4dB */ {0x0A, 0x0A , 0x09 , 0x07 , 0x05 , 0x03 , 0x02 , 0x01}, + /* Index49 -14.7dB */ {0x0A, 0x0A , 0x08 , 0x07 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index50 -15 dB */ {0x0A, 0x09 , 0x08 , 0x07 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index51 -15.3dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index52 -15.6dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x05 , 0x03 , 0x01 , 0x01}, + /* Index53 -15.9dB */ {0x09, 0x08 , 0x07 , 0x06 , 0x04 , 0x03 , 0x01 , 0x01} +}; +u1Byte CCKSwingTable_Ch14_92E[CCK_TABLE_SIZE_92E][8] = { + /* Index0 0 dB */ {0x36, 0x34 , 0x2E , 0x26 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index1 -0.3dB */ {0x34, 0x32 , 0x2C , 0x25 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index2 -0.6dB */ {0x32, 0x30 , 0x2B , 0x23 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index3 -0.9dB */ {0x31, 0x2F , 0x29 , 0x22 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index4 -1.2dB */ {0x2F, 0x2D , 0x28 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index5 -1.5dB */ {0x2D, 0x2C , 0x27 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index6 -1.8dB */ {0x2C, 0x2A , 0x25 , 0x1F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index7 -2.1dB */ {0x2A, 0x29 , 0x24 , 0x1E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index8 -2.4dB */ {0x29, 0x27 , 0x23 , 0x1D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index9 -2.7dB */ {0x27, 0x26 , 0x22 , 0x1C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index10 -3 dB */ {0x26, 0x25 , 0x20 , 0x1B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index11 -3.3dB */ {0x25, 0x23 , 0x1F , 0x1A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index12 -3.6dB */ {0x24, 0x22 , 0x1E , 0x19 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index13 -3.9dB */ {0x22, 0x21 , 0x1D , 0x18 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index14 -4.2dB */ {0x21, 0x20 , 0x1C , 0x17 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index15 -4.5dB */ {0x20, 0x1F , 0x1B , 0x17 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index16 -4.8dB */ {0x1F, 0x1E , 0x1A , 0x16 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index17 -5.1dB */ {0x1E, 0x1D , 0x1A , 0x15 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index18 -5.4dB */ {0x1D, 0x1C , 0x19 , 0x14 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index19 -5.7dB */ {0x1C, 0x1B , 0x18 , 0x14 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index20 -6 dB */ {0x1B, 0x1A , 0x17 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index21 -6.3dB */ {0x1A, 0x19 , 0x16 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index22 -6.6dB */ {0x19, 0x18 , 0x15 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index23 -6.9dB */ {0x18, 0x17 , 0x15 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index24 -7.2dB */ {0x18, 0x17 , 0x14 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index25 -7.5dB */ {0x17, 0x16 , 0x13 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index26 -7.8dB */ {0x16, 0x15 , 0x13 , 0x0F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index27 -8.1dB */ {0x15, 0x14 , 0x12 , 0x0F , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index28 -8.4dB */ {0x14, 0x14 , 0x11 , 0x0E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index29 -8.7dB */ {0x14, 0x13 , 0x11 , 0x0E , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index30 -9 dB */ {0x13, 0x12 , 0x10 , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index31 -9.3dB */ {0x12, 0x12 , 0x0F , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index32 -9.6dB */ {0x12, 0x11 , 0x0F , 0x0D , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index33 -9.9dB */ {0x11, 0x11 , 0x0F , 0x0C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index34 -10.2dB */ {0x11, 0x11 , 0x0E , 0x0C , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index35 -10.5dB */ {0x10, 0x0F , 0x0E , 0x0B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index36 -10.8dB */ {0x10, 0x0F , 0x0D , 0x0B , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index37 -11.1dB */ {0x0F, 0x0E , 0x0D , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index38 -11.4dB */ {0x0E, 0x0E , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index39 -11.7dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index40 -12 dB */ {0x0E, 0x0D , 0x0C , 0x0A , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index41 -12.3dB */ {0x0D, 0x0D , 0x0B , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index42 -12.6dB */ {0x0D, 0x0C , 0x0B , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index43 -12.9dB */ {0x0C, 0x0C , 0x0A , 0x09 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index44 -13.2dB */ {0x0C, 0x0B , 0x0A , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index45 -13.5dB */ {0x0B, 0x0B , 0x0A , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index46 -13.8dB */ {0x0B, 0x0B , 0x09 , 0x08 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index47 -14.1dB */ {0x0B, 0x0A , 0x09 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index48 -14.4dB */ {0x0A, 0x0A , 0x09 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index49 -14.7dB */ {0x0A, 0x0A , 0x08 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index50 -15 dB */ {0x0A, 0x09 , 0x08 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index51 -15.3dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index52 -15.6dB */ {0x09, 0x09 , 0x08 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00}, + /* Index53 -15.9dB */ {0x09, 0x08 , 0x07 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00} +}; +#endif + +#if(RTL8814A_SUPPORT == 1) +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 +}; +#elif(ODM_IC_11AC_SERIES_SUPPORT) +u4Byte OFDMSwingTable_8812[OFDM_TABLE_SIZE_8812] = { + 0x3FE, // 0, (6dB) + 0x3C4, // 1, (5.5dB) + 0x38E, // 2, (5dB) + 0x35C, // 3, (4.5dB) + 0x32B, // 4, (4dB) + 0x2FE, // 5, (3.5dB) + 0x2D3, // 6, (3dB) + 0x2AB, // 7, (2.5dB) + 0x285, // 8, (2dB) + 0x261, // 9, (1.5dB + 0x23E, // 10, (1dB) + 0x21E, // 11, (0.5dB) + 0x200, // 12, (0dB) 8814 int PA 2G default + 0x1E3, // 13, (-0.5dB) + 0x1C8, // 14, (-1dB) + 0x1AF, // 15, (-1.5dB) + 0x197, // 16, (-2dB) + 0x180, // 17, (-2.5dB) + 0x16A, // 18, (-3dB) 8812 / 8814 int PA 5G / 8814 ext PA 2G5G default + 0x156, // 19, (-3.5dB) + 0x143, // 20, (-4dB) 8812 HP default + 0x131, // 21, (-4.5dB) + 0x120, // 22, (-5dB) + 0x110, // 23, (-5.5dB) + 0x101, // 24, (-6dB) + 0x0F2, // 25, (-6.5dB) + 0x0E5, // 26, (-7dB) + 0x0D8, // 27, (-7.5dB) + 0x0CC, // 28, (-8dB) + 0x0C0, // 29, (-8.5dB) + 0x0B6, // 30, (-9dB) + 0x0AC, // 31, (-9.5dB) + 0x0A2, // 32, (-10dB) + 0x099, // 33, (-10.5dB) + 0x090, // 34, (-11dB) + 0x088, // 35, (-11.5dB) + 0x081, // 36, (-12dB) + 0x079, // 37, (-12.5dB) + 0x072, // 38, (-13dB) + 0x06c, // 39, (-13.5dB) + 0x066, // 40, (-14dB) + 0x060, // 41, (-14.5dB) + 0x05B // 42, (-15dB) +}; +#endif + +//#endif +//3============================================================ +//3 Tx Power Tracking +//3============================================================ + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + if(!(pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_IC_11N_SERIES))) + return; +#endif + + odm_TXPowerTrackingThermalMeterInit(pDM_Odm); +} + + +VOID +odm_TXPowerTrackingThermalMeterInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + u1Byte p; +#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); + + pMgntInfo->bTXPowerTracking = TRUE; + pHalData->TXPowercount = 0; + pHalData->bTXPowerTrackingInit = FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pHalData->TxPowerTrackControl = TRUE; + ODM_RT_TRACE(pDM_Odm,COMP_POWER_TRACKING, DBG_LOUD, ("pMgntInfo->bTXPowerTracking = %d\n", pMgntInfo->bTXPowerTracking)); +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #ifdef CONFIG_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; + + MSG_8192C("pDM_Odm TxPowerTrackControl = %d\n", pDM_Odm->RFCalibrateInfo.TxPowerTrackControl); + } + #else + { + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + //if(IS_HARDWARE_TYPE_8192C(pHalData)) + { + pdmpriv->bTXPowerTracking = _TRUE; + pdmpriv->TXPowercount = 0; + pdmpriv->bTXPowerTrackingInit = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) //for mp driver, turn off txpwrtracking as default + pdmpriv->TxPowerTrackControl = _TRUE; + + } + MSG_8192C("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); + + } + #endif//endif (CONFIG_RTL8188E==1) +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + + #ifdef RTL8188E_SUPPORT + { + pDM_Odm->RFCalibrateInfo.bTXPowerTracking = _TRUE; + pDM_Odm->RFCalibrateInfo.TXPowercount = 0; + pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = _FALSE; + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE; + pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; + } + #endif +#endif + + pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = TRUE; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndex = 0; + pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast = 0; + pDM_Odm->RFCalibrateInfo.PowerIndexOffset = 0; + pDM_Odm->RFCalibrateInfo.ThermalValue = 0; + pRFCalibrateInfo->DefaultOfdmIndex = 28; + + +#if RTL8188E_SUPPORT + pRFCalibrateInfo->DefaultCckIndex = 20; // -6 dB +#elif RTL8192E_SUPPORT + pRFCalibrateInfo->DefaultCckIndex = 8; // -12 dB +#endif + pRFCalibrateInfo->BbSwingIdxOfdmBase = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex; + pDM_Odm->RFCalibrateInfo.CCK_index = pRFCalibrateInfo->DefaultCckIndex; + for(p = 0; p < MAX_RF_PATH; p++) + { + pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->BbSwingIdxOfdm[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->KfreeOffset[p] = 0; // for 8814 kfree + } + pRFCalibrateInfo->BbSwingIdxCck = pRFCalibrateInfo->DefaultCckIndex; + +} + + +VOID +ODM_TXPowerTrackingCheck( + 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_RF_TX_PWR_TRACK)) + 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_TXPowerTrackingCheckMP(pDM_Odm); + break; + + case ODM_CE: + odm_TXPowerTrackingCheckCE(pDM_Odm); + break; + + case ODM_AP: + odm_TXPowerTrackingCheckAP(pDM_Odm); + break; + default: + break; + } + +} + +VOID +odm_TXPowerTrackingCheckCE( + 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; + + #if(RTL8188E_SUPPORT==1) + + //if(!pMgntInfo->bTXPowerTracking /*|| (!pdmpriv->TxPowerTrackControl && pdmpriv->bAPKdone)*/) + 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 + ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); + //DBG_8192C("Trigger 92C Thermal Meter!!\n"); + + pDM_Odm->RFCalibrateInfo.TM_Trigger = 1; + return; + + } + else + { + //DBG_8192C("Schedule TxPowerTracking direct call!!\n"); + odm_TXPowerTrackingCallback_ThermalMeter_8188E(Adapter); + pDM_Odm->RFCalibrateInfo.TM_Trigger = 0; + } + #endif + +#endif +} + +VOID +odm_TXPowerTrackingCheckMP( + 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; + + if (ODM_CheckPowerStatus(Adapter) == FALSE) + return; + + if(!Adapter->bSlaveOfDMSP || Adapter->DualMacSmartConcurrent == FALSE) + odm_TXPowerTrackingThermalMeterCheck(Adapter); +#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 ((RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1) || (RTL8812A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) || (RTL8814A_SUPPORT == 1)) + if (pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8812|ODM_RTL8881A|ODM_RTL8814A)) + ODM_TXPowerTrackingCallback_ThermalMeter(pDM_Odm); + else +#endif + { + } +#endif + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +odm_TXPowerTrackingThermalMeterCheck( + IN PADAPTER Adapter + ) +{ +#ifndef AP_BUILD_WORKAROUND +#if (HAL_CODE_BASE==RTL8192_C) + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + static u1Byte TM_Trigger = 0; + //u1Byte TxPowerCheckCnt = 5; //10 sec + + if(!pMgntInfo->bTXPowerTracking /*|| (!pHalData->TxPowerTrackControl && pHalData->bAPKdone)*/) + { + return; + } + + if(!TM_Trigger) //at least delay 1 sec + { + if (IS_HARDWARE_TYPE_8188E(Adapter) || IS_HARDWARE_TYPE_8812(Adapter)) + PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER_88E, BIT17 | BIT16, 0x03); + else + PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD,("Trigger 92C 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 +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.h new file mode 100644 index 00000000..264b529a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ap.h @@ -0,0 +1,314 @@ +/****************************************************************************** + * + * 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.1" + +#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 +#else +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#endif + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define DELTA_SWINGIDX_SIZE 30 +#define BAND_NUM 3 +#define MAX_RF_PATH 4 +#define TXSCALE_TABLE_SIZE 37 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_MAX 10 + +#define IQK_BB_REG_NUM 9 + +#define HP_THERMAL_NUM 8 + +#define AVG_THERMAL_NUM 8 +#define IQK_Matrix_REG_NUM 8 +//#define IQK_Matrix_Settings_NUM 1+24+21 +#define IQK_Matrix_Settings_NUM (14+24+21) // Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G + +#if !defined(_OUTSRC_COEXIST) +#define OFDM_TABLE_SIZE_92D 43 +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 +#define CCK_TABLE_SIZE_88F 21 + + + +//#define OFDM_TABLE_SIZE_92E 54 +//#define CCK_TABLE_SIZE_92E 54 +extern u4Byte OFDMSwingTable[OFDM_TABLE_SIZE_92D]; +extern u1Byte CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; +extern u1Byte CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; + + +extern u4Byte OFDMSwingTable_New[OFDM_TABLE_SIZE_92D]; +extern u1Byte CCKSwingTable_Ch1_Ch13_New[CCK_TABLE_SIZE][8]; +extern u1Byte CCKSwingTable_Ch14_New [CCK_TABLE_SIZE][8]; +extern u1Byte CCKSwingTable_Ch1_Ch14_88F[CCK_TABLE_SIZE_88F][16]; + +#endif + +#define ODM_OFDM_TABLE_SIZE 37 +#define ODM_CCK_TABLE_SIZE 33 +// <20140613, YuChen> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. +extern u1Byte DeltaSwingTableIdx_2GA_P_DEFAULT[DELTA_SWINGIDX_SIZE]; +extern u1Byte DeltaSwingTableIdx_2GA_N_DEFAULT[DELTA_SWINGIDX_SIZE]; + + +//extern u4Byte OFDMSwingTable_92E[OFDM_TABLE_SIZE_92E]; +//extern u1Byte CCKSwingTable_Ch1_Ch13_92E[CCK_TABLE_SIZE_92E][8]; +//extern u1Byte CCKSwingTable_Ch14_92E[CCK_TABLE_SIZE_92E][8]; + +#ifdef CONFIG_WLAN_HAL_8192EE +#define OFDM_TABLE_SIZE_92E 54 +#define CCK_TABLE_SIZE_92E 54 +extern u4Byte OFDMSwingTable_92E[OFDM_TABLE_SIZE_92E]; +extern u1Byte CCKSwingTable_Ch1_Ch13_92E[CCK_TABLE_SIZE_92E][8]; +extern u1Byte CCKSwingTable_Ch14_92E[CCK_TABLE_SIZE_92E][8]; +#endif + +#define OFDM_TABLE_SIZE_8812 43 +#define AVG_THERMAL_NUM_8812 4 + +#if(RTL8814A_SUPPORT == 1) +extern u4Byte TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE]; +#elif(ODM_IC_11AC_SERIES_SUPPORT) +extern unsigned int OFDMSwingTable_8812[OFDM_TABLE_SIZE_8812]; +#endif + +#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck + +typedef struct _IQK_MATRIX_REGS_SETTING{ + BOOLEAN bIQKDone; + s4Byte Value[1][IQK_Matrix_REG_NUM]; +}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 bTXPowerTracking; + 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 bDPKenable; + + BOOLEAN bReloadtxpowerindex; + u1Byte bRfPiEnable; + u4Byte TXPowerTrackingCallbackCnt; //cosa add for debug + + u1Byte bCCKinCH14; + u1Byte CCK_index; + u1Byte OFDM_index[MAX_RF_PATH]; + s1Byte PowerIndexOffset; + s1Byte DeltaPowerIndex; + s1Byte DeltaPowerIndexLast; + BOOLEAN bTxPowerChanged; + + u1Byte ThermalValue_HP[HP_THERMAL_NUM]; + u1Byte ThermalValue_HP_index; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; + BOOLEAN bNeedIQK; + u1Byte Delta_IQK; + u1Byte Delta_LCK; + 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_2GCCKC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_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_2GC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_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_5GC_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GC_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_P_8188E[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_N_8188E[DELTA_SWINGIDX_SIZE]; + + u1Byte BbSwingIdxOfdm[MAX_RF_PATH]; + u1Byte BbSwingIdxOfdmCurrent; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + u1Byte BbSwingIdxOfdmBase[MAX_RF_PATH]; +#else + u1Byte BbSwingIdxOfdmBase; +#endif + 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]; + + //--------------------------------------------------------------------// + + //for IQK + u4Byte RegC04; + u4Byte Reg874; + u4Byte RegC08; + u4Byte RegB68; + u4Byte RegB6C; + u4Byte Reg870; + u4Byte Reg860; + u4Byte Reg864; + + BOOLEAN bIQKInitialized; + BOOLEAN bLCKInProgress; + BOOLEAN bAntennaDetected; + 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]; + + //for APK + u4Byte APKoutput[2][2]; //path A/B; output1_1a/output1_2a + u1Byte bAPKdone; + u1Byte bAPKThermalMeterIgnore; + u1Byte bDPdone; + u1Byte bDPPathAOK; + u1Byte bDPPathBOK; + + /*Add by Yuchen for Kfree Phydm*/ + u1Byte RegRfKFreeEnable; /*for registry*/ + u1Byte RfKFreeEnable; /*for efuse enable check*/ + +}ODM_RF_CAL_T,*PODM_RF_CAL_T; + +VOID +odm_TXPowerTrackingCheckAP( + IN PVOID pDM_VOID + ); + +VOID +ODM_TXPowerTrackingCheck( + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.c new file mode 100644 index 00000000..b97d6643 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.c @@ -0,0 +1,670 @@ +/****************************************************************************** + * + * 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_Ch14_88F[CCK_TABLE_SIZE_88F][16] = { +{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ +{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ +{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ +{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ +{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ +{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ +{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ +{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ +{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ +{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ +{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ +{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ +{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ +{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ +{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ +{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ +{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ +{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ +{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ +{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ +{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + + +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)) + 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 || pDM_Odm->SupportICType == ODM_RTL8188F || pDM_Odm->SupportICType == ODM_RTL8703B + ) { + 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; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); +#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); + + pRFCalibrateInfo->bTXPowerTracking = _TRUE; + pRFCalibrateInfo->TXPowercount = 0; + pRFCalibrateInfo->bTXPowerTrackingInit = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pRFCalibrateInfo->TxPowerTrackControl = _TRUE; + else + pRFCalibrateInfo->TxPowerTrackControl = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pRFCalibrateInfo->TxPowerTrackControl = _TRUE; + + + MSG_8192C("pDM_Odm TxPowerTrackControl = %d\n", pRFCalibrateInfo->TxPowerTrackControl); + +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + #ifdef RTL8188E_SUPPORT + { + pRFCalibrateInfo->bTXPowerTracking = _TRUE; + pRFCalibrateInfo->TXPowercount = 0; + pRFCalibrateInfo->bTXPowerTrackingInit = _FALSE; + pRFCalibrateInfo->TxPowerTrackControl = _TRUE; + } + #endif +#endif + + //pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = TRUE; + pRFCalibrateInfo->ThermalValue = pHalData->EEPROMThermalMeter; + pRFCalibrateInfo->ThermalValue_IQK = pHalData->EEPROMThermalMeter; + pRFCalibrateInfo->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->SupportICType == ODM_RTL8703B) { + pRFCalibrateInfo->DefaultOfdmIndex = (defaultSwingIndex >= OFDM_TABLE_SIZE) ? 30 : defaultSwingIndex; + pRFCalibrateInfo->DefaultCckIndex = 20; + } + else if(pDM_Odm->SupportICType == ODM_RTL8188F) //add by Mingzhi.Guo 2015-03-23 + { + pRFCalibrateInfo->DefaultOfdmIndex =28; //OFDM: -1dB + pRFCalibrateInfo->DefaultCckIndex =20; //CCK:-6dB + } + else + { + pRFCalibrateInfo->DefaultOfdmIndex = (defaultSwingIndex >= TXSCALE_TABLE_SIZE) ? 24 : defaultSwingIndex; + pRFCalibrateInfo->DefaultCckIndex = 24; + } + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex; + pRFCalibrateInfo->CCK_index = pRFCalibrateInfo->DefaultCckIndex; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) + { + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->DeltaPowerIndex[p] = 0; + pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0; + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + } + pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0; //add by Mingzhi.Guo + pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0; //add by Mingzhi.Guo + +} + + +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; + + default: + 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 (!(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_8188F(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter) + || IS_HARDWARE_TYPE_8723B(Adapter) + || IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter) + || IS_HARDWARE_TYPE_8703B(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 +} + +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(!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; + + return; + +#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_8188E(Adapter) || IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter) || + IS_HARDWARE_TYPE_8723B(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter) || IS_HARDWARE_TYPE_8188F(Adapter) + || IS_HARDWARE_TYPE_8703B(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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.h new file mode 100644 index 00000000..337fd1f6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_ce.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 __PHYDMPOWERTRACKING_H__ +#define __PHYDMPOWERTRACKING_H__ + +#define POWRTRACKING_VERSION "1.1" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define CCK_TABLE_SIZE_88F 21 +#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 + +#define IQK_BB_REG_NUM 9 + + + +#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 u1Byte CCKSwingTable_Ch1_Ch14_88F[CCK_TABLE_SIZE_88F][16]; + + +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_2GCCKC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_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_2GC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_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_5GC_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GC_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_P_8188E[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_N_8188E[DELTA_SWINGIDX_SIZE]; + + u1Byte BbSwingIdxOfdm[MAX_RF_PATH]; + u1Byte BbSwingIdxOfdmCurrent; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + u1Byte BbSwingIdxOfdmBase[MAX_RF_PATH]; +#else + u1Byte BbSwingIdxOfdmBase; +#endif + 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]; + + //--------------------------------------------------------------------// + + //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}} + u4Byte TxIQC_8703B[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u4Byte RxIQC_8703B[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + + + + // IQK time measurement + u8Byte IQK_StartTime; + u8Byte IQK_ProgressingTime; + u4Byte LOK_Result; + + //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]; + u4Byte DpkTxAGC; + s4Byte DpkGain; + u4Byte DpkThermal[4]; + s1Byte Modify_TxAGC_Value_OFDM; + s1Byte Modify_TxAGC_Value_CCK; +}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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.c new file mode 100644 index 00000000..2cf4c76c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.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_Ch14_88F[CCK_TABLE_SIZE_88F][16] = { +{0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ +{0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ +{0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ +{0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ +{0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ +{0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ +{0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ +{0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ +{0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ +{0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ +{0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ +{0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ +{0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ +{0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ +{0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ +{0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ +{0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ +{0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ +{0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ +{0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ +{0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + + +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)) + if(!(pDM_Odm->SupportICType & (ODM_RTL8814A|ODM_IC_11N_SERIES|ODM_RTL8822B))) + 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 || pDM_Odm->SupportICType == ODM_RTL8188F || pDM_Odm->SupportICType == ODM_RTL8703B) + { + bbSwing = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, 0xFFC00000); + + pSwingTable = OFDMSwingTable_New; + swingTableSize = OFDM_TABLE_SIZE; + } else { + bbSwing = PHY_GetTxBBSwing_8812A(Adapter, pHalData->CurrentBandType, ODM_RF_PATH_A); + pSwingTable = TxScalingTable_Jaguar; + swingTableSize = TXSCALE_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); + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u1Byte p = 0; + + if(pDM_Odm->mp_mode == FALSE) + pRFCalibrateInfo->TxPowerTrackControl = TRUE; +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #ifdef CONFIG_RTL8188E + { + pRFCalibrateInfo->bTXPowerTracking = _TRUE; + pRFCalibrateInfo->TXPowercount = 0; + pRFCalibrateInfo->bTXPowerTrackingInit = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pRFCalibrateInfo->TxPowerTrackControl = _TRUE; + + MSG_8192C("pDM_Odm TxPowerTrackControl = %d\n", pRFCalibrateInfo->TxPowerTrackControl); + } + #else + { + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct dm_priv *pdmpriv = &pHalData->dmpriv; + + pdmpriv->bTXPowerTracking = _TRUE; + pdmpriv->TXPowercount = 0; + pdmpriv->bTXPowerTrackingInit = _FALSE; + + if(pDM_Odm->mp_mode == FALSE) + pdmpriv->TxPowerTrackControl = _TRUE; + + MSG_8192C("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); + + } + #endif//endif (CONFIG_RTL8188E==1) +#elif (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + #ifdef RTL8188E_SUPPORT + { + pRFCalibrateInfo->bTXPowerTracking = _TRUE; + pRFCalibrateInfo->TXPowercount = 0; + pRFCalibrateInfo->bTXPowerTrackingInit = _FALSE; + pRFCalibrateInfo->TxPowerTrackControl = _TRUE; + } + #endif +#endif + + pRFCalibrateInfo->TxPowerTrackControl = TRUE; + pRFCalibrateInfo->ThermalValue = pHalData->EEPROMThermalMeter; + pRFCalibrateInfo->ThermalValue_IQK = pHalData->EEPROMThermalMeter; + pRFCalibrateInfo->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->SupportICType == ODM_RTL8703B) + { + pRFCalibrateInfo->DefaultOfdmIndex = (defaultSwingIndex >= OFDM_TABLE_SIZE) ? 30 : defaultSwingIndex; + pRFCalibrateInfo->DefaultCckIndex = 20; + } + else if(pDM_Odm->SupportICType == ODM_RTL8188F) //add by Mingzhi.Guo 2015-03-23 + { + pRFCalibrateInfo->DefaultOfdmIndex =28; //OFDM: -1dB + pRFCalibrateInfo->DefaultCckIndex =20; //CCK:-6dB + } + else + { + pRFCalibrateInfo->DefaultOfdmIndex = (defaultSwingIndex >= TXSCALE_TABLE_SIZE) ? 24 : defaultSwingIndex; + pRFCalibrateInfo->DefaultCckIndex = 24; + } + + pRFCalibrateInfo->BbSwingIdxCckBase = pRFCalibrateInfo->DefaultCckIndex; + pRFCalibrateInfo->CCK_index = pRFCalibrateInfo->DefaultCckIndex; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) + { + pRFCalibrateInfo->BbSwingIdxOfdmBase[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->OFDM_index[p] = pRFCalibrateInfo->DefaultOfdmIndex; + pRFCalibrateInfo->DeltaPowerIndex[p] = 0; + pRFCalibrateInfo->DeltaPowerIndexLast[p] = 0; + pRFCalibrateInfo->PowerIndexOffset[p] = 0; + pRFCalibrateInfo->KfreeOffset[p] = 0; + } + pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=0; //add by Mingzhi.Guo + pRFCalibrateInfo->Modify_TxAGC_Value_CCK=0; //add by Mingzhi.Guo + +} + + +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; + + default: + 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 ((RTL8188F_SUPPORT == 1)) + rtl8192c_odm_CheckTXPowerTracking(Adapter); + #endif + + #if(RTL8188E_SUPPORT==1) + + if(!(pDM_Odm->SupportAbility & ODM_RF_TX_PWR_TRACK)) + { + return; + } + + if(!pRFCalibrateInfo->TM_Trigger) //at least delay 1 sec + { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); + //DBG_8192C("Trigger 92C Thermal Meter!!\n"); + + pRFCalibrateInfo->TM_Trigger = 1; + return; + + } + else + { + //DBG_8192C("Schedule TxPowerTracking direct call!!\n"); + odm_TXPowerTrackingCallback_ThermalMeter_8188E(Adapter); + pRFCalibrateInfo->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(*pDM_Odm->pIsFcsModeEnable) + return; + + if (ODM_CheckPowerStatus(Adapter) == FALSE) + { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("===>ODM_CheckPowerStatus() return FALSE\n")); + return; + } + + if(IS_HARDWARE_TYPE_8821B(Adapter)) // TODO: Don't Do PowerTracking + return; + +// #if(RTL8192D_SUPPORT==1) +// if(!Adapter->bSlaveOfDMSP || Adapter->DualMacSmartConcurrent == FALSE) + if (IS_HARDWARE_TYPE_8814A(Adapter) || IS_HARDWARE_TYPE_8188F(Adapter)) + odm_TXPowerTrackingThermalMeterCheck(Adapter); + else { + RT_TRACE(COMP_POWER_TRACKING, DBG_LOUD, ("!Adapter->bSlaveOfDMSP || Adapter->DualMacSmartConcurrent == FALSE\n")); + } +// #endif +#endif + +} + + +VOID +odm_TXPowerTrackingCheckAP( + IN PVOID pDM_VOID + ) +{ +return; + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +odm_TXPowerTrackingDirectCall( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + ODM_TXPowerTrackingCallback_ThermalMeter(Adapter); +} + +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_8188E(Adapter) || IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter) || + IS_HARDWARE_TYPE_8723B(Adapter) || IS_HARDWARE_TYPE_8814A(Adapter) || IS_HARDWARE_TYPE_8188F(Adapter) || IS_HARDWARE_TYPE_8703B(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 //end #ifMP + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.h new file mode 100644 index 00000000..be43875f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_powertracking_win.h @@ -0,0 +1,265 @@ +/****************************************************************************** + * + * 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.1" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define TXSCALE_TABLE_SIZE 37 +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define BAND_NUM 3 +#define MAX_RF_PATH 4 +#define CCK_TABLE_SIZE_88F 21 + + +#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck + +#define IQK_Matrix_Settings_NUM 14+24+21 // Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G +#define AVG_THERMAL_NUM 8 +#define HP_THERMAL_NUM 8 +#define IQK_Matrix_REG_NUM 8 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 + +#define IQK_BB_REG_NUM 9 + + +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 u1Byte CCKSwingTable_Ch1_Ch14_88F[CCK_TABLE_SIZE_88F][16]; + +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}; + +VOID +ODM_TXPowerTrackingCheck( + 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_TXPowerTrackingThermalMeterCheck( + IN PADAPTER Adapter + ); + +#endif + +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 bTXPowerTracking; + 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_AVG[AVG_THERMAL_NUM]; + u1Byte ThermalValue_AVG_index; + u1Byte ThermalValue_RxGain; + + 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_2GCCKC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GCCKD_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_2GC_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GC_N[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_P[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GD_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_5GC_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GC_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_5GD_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_P_8188E[DELTA_SWINGIDX_SIZE]; + u1Byte DeltaSwingTableIdx_2GA_N_8188E[DELTA_SWINGIDX_SIZE]; + + u1Byte BbSwingIdxOfdm[MAX_RF_PATH]; + u1Byte BbSwingIdxOfdmCurrent; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + u1Byte BbSwingIdxOfdmBase[MAX_RF_PATH]; +#else + u1Byte BbSwingIdxOfdmBase; +#endif + 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]; + + //--------------------------------------------------------------------// + + //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}} */ + u4Byte TxIQC_8703B[3][2]; /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u4Byte RxIQC_8703B[2][2]; /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + + + + // IQK time measurement + u8Byte IQK_StartTime; + u8Byte IQK_ProgressingTime; + u4Byte LOK_Result; + + //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]; + u4Byte DpkTxAGC; + s4Byte DpkGain; + u4Byte DpkThermal[4]; + + s1Byte Modify_TxAGC_Value_OFDM; + s1Byte Modify_TxAGC_Value_CCK; +}ODM_RF_CAL_T,*PODM_RF_CAL_T; + + + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pre_define.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pre_define.h new file mode 100644 index 00000000..ea89aa04 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_pre_define.h @@ -0,0 +1,615 @@ +/****************************************************************************** + * + * 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 __PHYDMPREDEFINE_H__ +#define __PHYDMPREDEFINE_H__ + +//1 ============================================================ +//1 Definition +//1 ============================================================ + +//Max path of IC +#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 MAX_PATH_NUM_8821B 2 +#define MAX_PATH_NUM_8703B 1 +#define MAX_PATH_NUM_8188F 1 + +//Max RF path +#define ODM_RF_PATH_MAX 2 +#define ODM_RF_PATH_MAX_JAGUAR 4 + +//number of entry +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE)) + #define ASSOCIATE_ENTRY_NUM MACID_NUM_SW_LIMIT /* 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 + #define ODM_ASSOCIATE_ENTRY_NUM ((ASSOCIATE_ENTRY_NUM*3)+1) +#endif + +/* -----MGN rate--------------------------------- */ + +#define ODM_MGN_1M 0x02 +#define ODM_MGN_2M 0x04 +#define ODM_MGN_5_5M 0x0b +#define ODM_MGN_11M 0x16 + +#define ODM_MGN_6M 0x0c +#define ODM_MGN_9M 0x12 +#define ODM_MGN_12M 0x18 +#define ODM_MGN_18M 0x24 +#define ODM_MGN_24M 0x30 +#define ODM_MGN_36M 0x48 +#define ODM_MGN_48M 0x60 +#define ODM_MGN_54M 0x6c + +/*TxHT = 1*/ +#define ODM_MGN_MCS0 0x80 +#define ODM_MGN_MCS1 0x81 +#define ODM_MGN_MCS2 0x82 +#define ODM_MGN_MCS3 0x83 +#define ODM_MGN_MCS4 0x84 +#define ODM_MGN_MCS5 0x85 +#define ODM_MGN_MCS6 0x86 +#define ODM_MGN_MCS7 0x87 +#define ODM_MGN_MCS8 0x88 +#define ODM_MGN_MCS9 0x89 +#define ODM_MGN_MCS10 0x8a +#define ODM_MGN_MCS11 0x8b +#define ODM_MGN_MCS12 0x8c +#define ODM_MGN_MCS13 0x8d +#define ODM_MGN_MCS14 0x8e +#define ODM_MGN_MCS15 0x8f +#define ODM_MGN_VHT1SS_MCS0 0x90 +#define ODM_MGN_VHT1SS_MCS1 0x91 +#define ODM_MGN_VHT1SS_MCS2 0x92 +#define ODM_MGN_VHT1SS_MCS3 0x93 +#define ODM_MGN_VHT1SS_MCS4 0x94 +#define ODM_MGN_VHT1SS_MCS5 0x95 +#define ODM_MGN_VHT1SS_MCS6 0x96 +#define ODM_MGN_VHT1SS_MCS7 0x97 +#define ODM_MGN_VHT1SS_MCS8 0x98 +#define ODM_MGN_VHT1SS_MCS9 0x99 +#define ODM_MGN_VHT2SS_MCS0 0x9a +#define ODM_MGN_VHT2SS_MCS1 0x9b +#define ODM_MGN_VHT2SS_MCS2 0x9c +#define ODM_MGN_VHT2SS_MCS3 0x9d +#define ODM_MGN_VHT2SS_MCS4 0x9e +#define ODM_MGN_VHT2SS_MCS5 0x9f +#define ODM_MGN_VHT2SS_MCS6 0xa0 +#define ODM_MGN_VHT2SS_MCS7 0xa1 +#define ODM_MGN_VHT2SS_MCS8 0xa2 +#define ODM_MGN_VHT2SS_MCS9 0xa3 + +#define ODM_MGN_MCS0_SG 0xc0 +#define ODM_MGN_MCS1_SG 0xc1 +#define ODM_MGN_MCS2_SG 0xc2 +#define ODM_MGN_MCS3_SG 0xc3 +#define ODM_MGN_MCS4_SG 0xc4 +#define ODM_MGN_MCS5_SG 0xc5 +#define ODM_MGN_MCS6_SG 0xc6 +#define ODM_MGN_MCS7_SG 0xc7 +#define ODM_MGN_MCS8_SG 0xc8 +#define ODM_MGN_MCS9_SG 0xc9 +#define ODM_MGN_MCS10_SG 0xca +#define ODM_MGN_MCS11_SG 0xcb +#define ODM_MGN_MCS12_SG 0xcc +#define ODM_MGN_MCS13_SG 0xcd +#define ODM_MGN_MCS14_SG 0xce +#define ODM_MGN_MCS15_SG 0xcf + +/* -----DESC rate--------------------------------- */ + +#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 + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9+1) +#else + #if (RTL8192E_SUPPORT == 1) + #define ODM_NUM_RATE_IDX (ODM_RATEMCS15+1) + #elif (RTL8723B_SUPPORT == 1) || (RTL8188E_SUPPORT == 1) || (RTL8188F_SUPPORT == 1) + #define ODM_NUM_RATE_IDX (ODM_RATEMCS7+1) + #elif (RTL8821A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) + #define ODM_NUM_RATE_IDX (ODM_RATEVHTSS1MCS9+1) + #elif (RTL8812A_SUPPORT == 1) + #define ODM_NUM_RATE_IDX (ODM_RATEVHTSS2MCS9+1) + #elif(RTL8814A_SUPPORT == 1) + #define ODM_NUM_RATE_IDX (ODM_RATEVHTSS3MCS9+1) + #else + #define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9+1) + #endif +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define CONFIG_SFW_SUPPORTED +#endif + +//1 ============================================================ +//1 enumeration +//1 ============================================================ + + +// 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_RTL8195A = BIT14, + ODM_RTL8188F = BIT15 +}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|ODM_RTL8188F) +#define ODM_IC_11AC_SERIES (ODM_RTL8812|ODM_RTL8821|ODM_RTL8814A|ODM_RTL8881A|ODM_RTL8821B|ODM_RTL8822B) +#define ODM_IC_TXBF_SUPPORT (ODM_RTL8192E|ODM_RTL8812|ODM_RTL8821|ODM_RTL8814A|ODM_RTL8881A|ODM_RTL8822B) +#define ODM_IC_11N_GAIN_IDX_EDCCA (ODM_RTL8195A|ODM_RTL8703B|ODM_RTL8188F) +#define ODM_IC_11AC_GAIN_IDX_EDCCA (ODM_RTL8814A|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) || (RTL8703B_SUPPORT == 1) || \ +(RTL8188F_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_A = BIT0, + ODM_RF_B = BIT1, + ODM_RF_C = BIT2, + ODM_RF_D = BIT3, +}ODM_RF_PATH_E; + +typedef enum tag_PHYDM_RF_TX_NUM { + ODM_1T = 1, + ODM_2T = 2, + ODM_3T = 3, + ODM_4T = 4, +} ODM_RF_TX_NUM_E; + +typedef enum tag_ODM_RF_Type_Definition { + ODM_1T1R, + ODM_1T2R, + ODM_2T2R, + ODM_2T2R_GREEN, + ODM_2T3R, + ODM_2T4R, + ODM_3T3R, + ODM_3T4R, + ODM_4T4R, + ODM_XTXR +}ODM_RF_TYPE_E; + + +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_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,/*0x0*/ + ODM_WM_A = BIT0, /* 0x1*/ + ODM_WM_B = BIT1, /* 0x2*/ + ODM_WM_G = BIT2,/* 0x4*/ + ODM_WM_AUTO = BIT3,/* 0x8*/ + ODM_WM_N24G = BIT4,/* 0x10*/ + ODM_WM_N5G = BIT5,/* 0x20*/ + ODM_WM_AC_5G = BIT6,/* 0x40*/ + ODM_WM_AC_24G = BIT7,/* 0x80*/ + ODM_WM_AC_ONLY = BIT8,/* 0x100*/ + ODM_WM_MAX = BIT11/* 0x800*/ + +}ODM_WIRELESS_MODE_E; +#endif + +// ODM_CMNINFO_BAND +typedef enum tag_Band_Type_Definition +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + ODM_BAND_2_4G = BIT0, + ODM_BAND_5G = BIT1, +#else + ODM_BAND_2_4G = 0, + ODM_BAND_5G, + ODM_BAND_ON_BOTH, + ODM_BANDMAX +#endif +}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_BW5M = 4, + ODM_BW10M = 5, + ODM_BW_MAX = 6 +}ODM_BW_E; + +// ODM_CMNINFO_CHNL + +// ODM_CMNINFO_BOARD_TYPE +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 = 0x0000, + TYPE_GPA1 = 0x0055, + TYPE_GPA2 = 0x00AA, + TYPE_GPA3 = 0x00FF, + TYPE_GPA4 = 0x5500, + TYPE_GPA5 = 0x5555, + TYPE_GPA6 = 0x55AA, + TYPE_GPA7 = 0x55FF, + TYPE_GPA8 = 0xAA00, + TYPE_GPA9 = 0xAA55, + TYPE_GPA10 = 0xAAAA, + TYPE_GPA11 = 0xAAFF, + TYPE_GPA12 = 0xFF00, + TYPE_GPA13 = 0xFF55, + TYPE_GPA14 = 0xFFAA, + TYPE_GPA15 = 0xFFFF, +}ODM_TYPE_GPA_E; + +typedef enum tag_ODM_TYPE_APA_Definition { + TYPE_APA0 = 0x0000, + TYPE_APA1 = 0x0055, + TYPE_APA2 = 0x00AA, + TYPE_APA3 = 0x00FF, + TYPE_APA4 = 0x5500, + TYPE_APA5 = 0x5555, + TYPE_APA6 = 0x55AA, + TYPE_APA7 = 0x55FF, + TYPE_APA8 = 0xAA00, + TYPE_APA9 = 0xAA55, + TYPE_APA10 = 0xAAAA, + TYPE_APA11 = 0xAAFF, + TYPE_APA12 = 0xFF00, + TYPE_APA13 = 0xFF55, + TYPE_APA14 = 0xFFAA, + TYPE_APA15 = 0xFFFF, +}ODM_TYPE_APA_E; + +typedef enum tag_ODM_TYPE_GLNA_Definition { + TYPE_GLNA0 = 0x0000, + TYPE_GLNA1 = 0x0055, + TYPE_GLNA2 = 0x00AA, + TYPE_GLNA3 = 0x00FF, + TYPE_GLNA4 = 0x5500, + TYPE_GLNA5 = 0x5555, + TYPE_GLNA6 = 0x55AA, + TYPE_GLNA7 = 0x55FF, + TYPE_GLNA8 = 0xAA00, + TYPE_GLNA9 = 0xAA55, + TYPE_GLNA10 = 0xAAAA, + TYPE_GLNA11 = 0xAAFF, + TYPE_GLNA12 = 0xFF00, + TYPE_GLNA13 = 0xFF55, + TYPE_GLNA14 = 0xFFAA, + TYPE_GLNA15 = 0xFFFF, +}ODM_TYPE_GLNA_E; + +typedef enum tag_ODM_TYPE_ALNA_Definition { + TYPE_ALNA0 = 0x0000, + TYPE_ALNA1 = 0x0055, + TYPE_ALNA2 = 0x00AA, + TYPE_ALNA3 = 0x00FF, + TYPE_ALNA4 = 0x5500, + TYPE_ALNA5 = 0x5555, + TYPE_ALNA6 = 0x55AA, + TYPE_ALNA7 = 0x55FF, + TYPE_ALNA8 = 0xAA00, + TYPE_ALNA9 = 0xAA55, + TYPE_ALNA10 = 0xAAAA, + TYPE_ALNA11 = 0xAAFF, + TYPE_ALNA12 = 0xFF00, + TYPE_ALNA13 = 0xFF55, + TYPE_ALNA14 = 0xFFAA, + TYPE_ALNA15 = 0xFFFF, +}ODM_TYPE_ALNA_E; + + +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_PARAMETER_INIT { + ODM_PRE_SETTING = 0, + ODM_POST_SETTING = 1, +} ODM_PARAMETER_INIT_E; + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_precomp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_precomp.h new file mode 100644 index 00000000..5669c158 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_precomp.h @@ -0,0 +1,320 @@ +/****************************************************************************** + * + * 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" +#include "phydm_features.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 + +#if (DM_ODM_SUPPORT_TYPE ==ODM_CE) +#define RTL8192CE_SUPPORT 0 +#define RTL8192CU_SUPPORT 0 +#define RTL8192C_SUPPORT 0 + +#define RTL8192DE_SUPPORT 0 +#define RTL8192DU_SUPPORT 0 +#define RTL8192D_SUPPORT 0 + +#define RTL8723AU_SUPPORT 0 +#define RTL8723AS_SUPPORT 0 +#define RTL8723AE_SUPPORT 0 +#define RTL8723A_SUPPORT 0 +#define RTL8723_FPGA_VERIFICATION 0 +#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_CE) + #define __PACK + #define __WLAN_ATTRIB_PACK__ +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "mp_precomp.h" + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #define __PACK + #define __WLAN_ATTRIB_PACK__ +#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_interface.h" +#include "phydm_reg.h" + + +#if (DM_ODM_SUPPORT_TYPE & ODM_CE) +#define RTL8821B_SUPPORT 0 +#define RTL8822B_SUPPORT 0 + +VOID +PHY_SetTxPowerLimit( + IN PDM_ODM_T pDM_Odm, + IN u8 *Regulation, + IN u8 *Band, + IN u8 *Bandwidth, + IN u8 *RateSection, + IN u8 *RfPath, + IN u8 *Channel, + IN u8 *PowerLimit +); + +#endif + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) +#define RTL8821B_SUPPORT 0 +#define RTL8822B_SUPPORT 0 +#define RTL8703B_SUPPORT 0 +#define RTL8188F_SUPPORT 0 +#endif + +#if RTL8188E_SUPPORT == 1 +#define RTL8188E_T_SUPPORT 1 +#ifdef CONFIG_SFW_SUPPORTED +#define RTL8188E_S_SUPPORT 1 +#else +#define RTL8188E_S_SUPPORT 0 +#endif +#endif + +#if (RTL8188E_SUPPORT==1) +#include "rtl8188e/hal8188erateadaptive.h"//for RA,Power training +#include "rtl8188e/halhwimg8188e_mac.h" +#include "rtl8188e/halhwimg8188e_rf.h" +#include "rtl8188e/halhwimg8188e_bb.h" +#include "rtl8188e/halhwimg8188e_t_fw.h" +#include "rtl8188e/halhwimg8188e_s_fw.h" +#include "rtl8188e/phydm_regconfig8188e.h" +#include "rtl8188e/phydm_rtl8188e.h" +#include "rtl8188e/hal8188ereg.h" +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8188e_hal.h" + #include "rtl8188e/halphyrf_8188e_ce.h" +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8188e/halphyrf_8188e_win.h" +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "rtl8188e/halphyrf_8188e_ap.h" +#endif +#endif //88E END + +#if (RTL8192E_SUPPORT==1) + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8192e/halphyrf_8192e_win.h" /*FOR_8192E_IQK*/ + #elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "rtl8192e/halphyrf_8192e_ap.h" /*FOR_8192E_IQK*/ + #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8192e/halphyrf_8192e_ce.h" /*FOR_8192E_IQK*/ + #endif + +#include "rtl8192e/phydm_rtl8192e.h" //FOR_8192E_IQK +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + #include "rtl8192e/halhwimg8192e_bb.h" + #include "rtl8192e/halhwimg8192e_mac.h" + #include "rtl8192e/halhwimg8192e_rf.h" + #include "rtl8192e/phydm_regconfig8192e.h" + #include "rtl8192e/halhwimg8192e_fw.h" + #include "rtl8192e/hal8192ereg.h" +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8192e_hal.h" +#endif +#endif //92E END + +#if (RTL8812A_SUPPORT==1) + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8812a/halphyrf_8812a_win.h" + #elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "rtl8812a/halphyrf_8812a_ap.h" + #elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8812a/halphyrf_8812a_ce.h" + #endif + + //#include "rtl8812a/HalPhyRf_8812A.h" //FOR_8812_IQK + #if (DM_ODM_SUPPORT_TYPE != ODM_AP) + #include "rtl8812a/halhwimg8812a_bb.h" + #include "rtl8812a/halhwimg8812a_mac.h" + #include "rtl8812a/halhwimg8812a_rf.h" + #include "rtl8812a/phydm_regconfig8812a.h" + #include "rtl8812a/halhwimg8812a_fw.h" + #include "rtl8812a/phydm_rtl8812a.h" + #endif + + #if (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8812a_hal.h" + #endif + +#endif //8812 END + +#if (RTL8814A_SUPPORT==1) + +#include "rtl8814a/halhwimg8814a_mac.h" +#include "rtl8814a/halhwimg8814a_rf.h" +#include "rtl8814a/halhwimg8814a_bb.h" +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) + #include "rtl8814a/halhwimg8814a_fw.h" + #include "rtl8814a/phydm_rtl8814a.h" +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8814a/halphyrf_8814a_win.h" +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8814a/halphyrf_8814a_ce.h" +#elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "rtl8814a/halphyrf_8814a_ap.h" +#endif + #include "rtl8814a/phydm_regconfig8814a.h" +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8814a_hal.h" + #include "rtl8814a/phydm_iqk_8814a.h" +#endif +#endif //8814 END + +#if (RTL8881A_SUPPORT==1)//FOR_8881_IQK +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#include "rtl8821a/phydm_iqk_8821a_win.h" +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) +#include "rtl8821a/phydm_iqk_8821a_ce.h" +#else +#include "rtl8821a/phydm_iqk_8821a_ap.h" +#endif +//#include "rtl8881a/HalHWImg8881A_BB.h" +//#include "rtl8881a/HalHWImg8881A_MAC.h" +//#include "rtl8881a/HalHWImg8881A_RF.h" +//#include "rtl8881a/odm_RegConfig8881A.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/phydm_regconfig8723b.h" +#include "rtl8723b/phydm_rtl8723b.h" +#include "rtl8723b/hal8723breg.h" +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8723b/halphyrf_8723b_win.h" +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8723b/halphyrf_8723b_ce.h" + #include "rtl8723b/halhwimg8723b_mp.h" + #include "rtl8723b_hal.h" +#endif +#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" +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "rtl8821a/halphyrf_8821a_win.h" +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include "rtl8821a/halphyrf_8821a_ce.h" + #include "rtl8821a/phydm_iqk_8821a_ce.h"/*for IQK*/ + #include "rtl8812a/halphyrf_8812a_ce.h"/*for IQK,LCK,Power-tracking*/ + #include "rtl8812a_hal.h" +#else +#endif +#endif + +#if (RTL8821B_SUPPORT==1) +#include "rtl8821b/halhwimg8821b_mac.h" +#include "rtl8821b/halhwimg8821b_rf.h" +#include "rtl8821b/halhwimg8821b_bb.h" +#include "rtl8821b/halhwimg8821b_fw.h" +#include "rtl8821b/phydm_regconfig8821b.h" +#include "rtl8821b/halhwimg8821b_testchip_mac.h" +#include "rtl8821b/halhwimg8821b_testchip_rf.h" +#include "rtl8821b/halhwimg8821b_testchip_bb.h" +#include "rtl8821b/halhwimg8821b_testchip_fw.h" +#include "rtl8821b/halphyrf_8821b.h" +#endif + +#if (RTL8822B_SUPPORT==1) +#include "rtl8822b/halhwimg8822b_mac.h" +#include "rtl8822b/halhwimg8822b_rf.h" +#include "rtl8822b/halhwimg8822b_bb.h" +/*#include "rtl8822b/halhwimg8822b_fw.h"*/ +#include "rtl8822b/phydm_regconfig8822b.h" +#include "rtl8822b/halphyrf_8822b.h" +#include "rtl8822b/phydm_rtl8822b.h" +#include "rtl8822b/phydm_hal_api8822b.h" +#include "rtl8822b/version_rtl8822b.h" +#endif + +#if (RTL8703B_SUPPORT==1) +#include "rtl8703b/phydm_regconfig8703b.h" +#include "rtl8703b/halhwimg8703b_mac.h" +#include "rtl8703b/halhwimg8703b_rf.h" +#include "rtl8703b/halhwimg8703b_bb.h" +#include "rtl8703b/halhwimg8703b_fw.h" +#include "rtl8703b/halphyrf_8703b.h" +#include "rtl8703b/version_rtl8703b.h" +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#include "rtl8703b_hal.h" +#endif +#endif + +#if (RTL8188F_SUPPORT == 1) +#include "rtl8188f/halhwimg8188f_mac.h" +#include "rtl8188f/halhwimg8188f_rf.h" +#include "rtl8188f/halhwimg8188f_bb.h" +#include "rtl8188f/halhwimg8188f_fw.h" +#include "rtl8188f/hal8188freg.h" +#include "rtl8188f/phydm_rtl8188f.h" +#include "rtl8188f/phydm_regconfig8188f.h" +#include "rtl8188f/halphyrf_8188f.h" /* for IQK,LCK,Power-tracking */ +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#include "rtl8188f_hal.h" +#endif +#endif + +#endif // __ODM_PRECOMP_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.c new file mode 100644 index 00000000..f1f21c09 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.c @@ -0,0 +1,2574 @@ +/****************************************************************************** + * + * 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 (defined(CONFIG_RA_DBG_CMD)) +VOID +ODM_C2HRaParaReportHandler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + u1Byte para_idx = CmdBuf[0]; //Retry Penalty, NH, NL + u1Byte RateTypeStart = CmdBuf[1]; + u1Byte RateTypeLength = CmdLen - 2; + u1Byte i; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[ From FW C2H RA Para ] CmdBuf[0]= (( %d ))\n", CmdBuf[0])); + + if (para_idx == RADBG_RTY_PENALTY) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate Index| |RTY Penality Index| \n")); + + for (i = 0 ; i < (RateTypeLength) ; i++) { + if (pRA_Table->is_ra_dbg_init) + pRA_Table->RTY_P_default[RateTypeStart + i] = CmdBuf[2 + i]; + + pRA_Table->RTY_P[RateTypeStart + i] = CmdBuf[2 + i]; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d \n", (RateTypeStart + i), pRA_Table->RTY_P[RateTypeStart + i])); + } + + } else if (para_idx == RADBG_N_HIGH) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate Index| |N-High| \n")); + + + } else if (para_idx == RADBG_N_LOW){ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate Index| |N-Low| \n")); + + } + else if (para_idx == RADBG_RATE_UP_RTY_RATIO) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate Index| |Rate Up RTY Ratio| \n")); + + for (i = 0 ; i < (RateTypeLength) ; i++) { + if (pRA_Table->is_ra_dbg_init) + pRA_Table->RATE_UP_RTY_RATIO_default[RateTypeStart + i] = CmdBuf[2 + i]; + + pRA_Table->RATE_UP_RTY_RATIO[RateTypeStart + i] = CmdBuf[2 + i]; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d \n", (RateTypeStart + i), pRA_Table->RATE_UP_RTY_RATIO[RateTypeStart + i])); + } + } else if (para_idx == RADBG_RATE_DOWN_RTY_RATIO) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate Index| |Rate Down RTY Ratio| \n")); + + for (i = 0 ; i < (RateTypeLength) ; i++) { + if (pRA_Table->is_ra_dbg_init) + pRA_Table->RATE_DOWN_RTY_RATIO_default[RateTypeStart + i] = CmdBuf[2 + i]; + + pRA_Table->RATE_DOWN_RTY_RATIO[RateTypeStart + i] = CmdBuf[2 + i]; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("%8d %15d \n", (RateTypeStart + i), pRA_Table->RATE_DOWN_RTY_RATIO[RateTypeStart + i])); + } + } else if (para_idx == RADBG_DEBUG_MONITOR1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n")); + if (pDM_Odm->SupportICType & PHYDM_IC_3081_SERIES) { + + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "RSSI =", CmdBuf[1])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "Rate =", CmdBuf[2] & 0x7f)); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "SGI =", (CmdBuf[2] & 0x80) >> 7)); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "BW =", CmdBuf[3])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "BW_max =", CmdBuf[4])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "multi_rate0 =", CmdBuf[5])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "multi_rate1 =", CmdBuf[6])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "DISRA =", CmdBuf[7])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "VHT_EN =", CmdBuf[8])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "SGI_support =", CmdBuf[9])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "try_ness =", CmdBuf[10])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "pre_rate =", CmdBuf[11])); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "RSSI =", CmdBuf[1])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %x \n", "BW =", CmdBuf[2])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "DISRA =", CmdBuf[3])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "VHT_EN =", CmdBuf[4])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "Hightest Rate =", CmdBuf[5])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "Lowest Rate =", CmdBuf[6])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "SGI_support =", CmdBuf[7])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "Rate_ID =", CmdBuf[8]));; + } + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n")); + } else if (para_idx == RADBG_DEBUG_MONITOR2) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n")); + if (pDM_Odm->SupportICType & PHYDM_IC_3081_SERIES) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %d \n", "RateID =", CmdBuf[1])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "highest_rate =", CmdBuf[2])); + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s 0x%x \n", "lowest_rate =", CmdBuf[3])); + + for (i = 4 ; i <= 11 ; i++) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("RAMASK = 0x%x \n", CmdBuf[i])); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s %x%x %x%x %x%x %x%x \n", "RA Mask:", + CmdBuf[8], CmdBuf[7], CmdBuf[6], CmdBuf[5], CmdBuf[4], CmdBuf[3], CmdBuf[2], CmdBuf[1])); + } + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("-------------------------------\n")); + } else if (para_idx == RADBG_DEBUG_MONITOR3) { + + for (i = 0 ; i < (CmdLen - 1) ; i++) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("content[%d] = %d \n", i, CmdBuf[1 + i])); + } else if (para_idx == RADBG_DEBUG_MONITOR4) + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("%5s {%d.%d} \n", "RA Version =", CmdBuf[1], CmdBuf[2])); + +} + +VOID +odm_RA_ParaAdjust_Send_H2C( + IN PVOID pDM_VOID +) +{ + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte H2C_Parameter[6] = {0}; + + H2C_Parameter[0] = RA_FIRST_MACID; + + //ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("RA_Para_feedback_req= (( %d )) \n",pRA_Table->RA_Para_feedback_req )); + if (pRA_Table->RA_Para_feedback_req) { //H2C_Parameter[5]=1 ; ask FW for all RA parameters + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] Ask FW for RA parameter \n")); + H2C_Parameter[5] |= BIT1; //ask FW to report RA parameters + H2C_Parameter[1] = pRA_Table->para_idx; //pRA_Table->para_idx; + pRA_Table->RA_Para_feedback_req = 0; + } else { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[H2C] Send H2C to FW for modifying RA parameter \n")); + + H2C_Parameter[1] = pRA_Table->para_idx; + H2C_Parameter[2] = pRA_Table->rate_idx; + //1 [8 bit] + if (pRA_Table->para_idx == RADBG_RTY_PENALTY || pRA_Table->para_idx == RADBG_RATE_UP_RTY_RATIO || pRA_Table->para_idx == RADBG_RATE_DOWN_RTY_RATIO) { + H2C_Parameter[3] = pRA_Table->value; + H2C_Parameter[4] = 0; + } + //1 [16 bit] + else { //if ((pRA_Table->rate_idx==RADBG_N_HIGH)||(pRA_Table->rate_idx==RADBG_N_LOW)) + H2C_Parameter[3] = (u1Byte)(((pRA_Table->value_16) & 0xf0) >> 4); //byte1 + H2C_Parameter[4] = (u1Byte)((pRA_Table->value_16) & 0x0f); //byte0 + } + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" H2C_Parameter[1] = 0x%x \n", H2C_Parameter[1])); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" H2C_Parameter[2] = 0x%x \n", H2C_Parameter[2])); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" H2C_Parameter[3] = 0x%x \n", H2C_Parameter[3])); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" H2C_Parameter[4] = 0x%x \n", H2C_Parameter[4])); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" H2C_Parameter[5] = 0x%x \n", H2C_Parameter[5])); + + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RA_PARA_ADJUST, 6, H2C_Parameter); + +} + + +VOID +odm_RA_ParaAdjust( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte para_idx = pRA_Table->para_idx; + u1Byte rate_idx = pRA_Table->rate_idx; + u1Byte value = pRA_Table->value; + u1Byte Pre_value = 0xff; + + BOOLEAN sign = 0; + + if (pRA_Table->para_idx == RADBG_RTY_PENALTY) { + Pre_value = pRA_Table->RTY_P[rate_idx]; + pRA_Table->RTY_P[rate_idx] = value; + pRA_Table->RTY_P_modify_note[rate_idx] = 1; + } else if (pRA_Table->para_idx == RADBG_N_HIGH) { + + } else if (pRA_Table->para_idx == RADBG_N_LOW) { + + } else if (pRA_Table->para_idx == RADBG_RATE_UP_RTY_RATIO) { + Pre_value = pRA_Table->RATE_UP_RTY_RATIO[rate_idx]; + pRA_Table->RATE_UP_RTY_RATIO[rate_idx] = value; + pRA_Table->RATE_UP_RTY_RATIO_modify_note[rate_idx] = 1; + } else if (pRA_Table->para_idx == RADBG_RATE_DOWN_RTY_RATIO) { + Pre_value = pRA_Table->RATE_DOWN_RTY_RATIO[rate_idx]; + pRA_Table->RATE_DOWN_RTY_RATIO[rate_idx] = value; + pRA_Table->RATE_DOWN_RTY_RATIO_modify_note[rate_idx] = 1; + } + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" Change RA Papa[%d], Rate[ %d ], ((%d)) -> ((%d)) \n", pRA_Table->para_idx, rate_idx, Pre_value, value)); + odm_RA_ParaAdjust_Send_H2C(pDM_Odm); +} + + +VOID +phydm_ra_print_msg( + IN PVOID pDM_VOID, + IN u1Byte *value, + IN u1Byte *value_default, + IN u1Byte *modify_note +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u4Byte i; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" |Rate index| |Current-value| |Default-value| |Modify?| \n")); + for (i = 0 ; i <= (pRA_Table->rate_length); i++) { +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [ %d ] %20d %25d %20s \n", i, value[i], value_default[i], ((modify_note[i] == 1) ? "V" : " . "))); +#else + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [ %d ] %10d %14d %14s \n", i, value[i], value_default[i], ((modify_note[i] == 1) ? "V" : " . "))); +#endif + } + +} + +VOID +odm_RA_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + pRA_Table->is_ra_dbg_init = FALSE; + + if (dm_value[0] == 100) { /*1 Print RA Parameters*/ + u1Byte default_pointer_value; + u1Byte *pvalue; + u1Byte *pvalue_default; + u1Byte *pmodify_note; + + pvalue = pvalue_default = pmodify_note = &default_pointer_value; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("\n------------------------------------------------------------------------------------\n")); + + if (dm_value[1] == RADBG_RTY_PENALTY) { /* [1]*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [1] RTY_PENALTY\n")); + pvalue = &(pRA_Table->RTY_P[0]); + pvalue_default = &(pRA_Table->RTY_P_default[0]); + pmodify_note = (u1Byte *)&(pRA_Table->RTY_P_modify_note[0]); + } else if (dm_value[1] == RADBG_N_HIGH) { /* [2]*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [2] N_HIGH\n")); + + } else if (dm_value[1] == RADBG_N_LOW) { /*[3]*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [3] N_LOW\n")); + + } else if (dm_value[1] == RADBG_RATE_UP_RTY_RATIO) { /* [8]*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [8] RATE_UP_RTY_RATIO\n")); + pvalue = &(pRA_Table->RATE_UP_RTY_RATIO[0]); + pvalue_default = &(pRA_Table->RATE_UP_RTY_RATIO_default[0]); + pmodify_note = (u1Byte *)&(pRA_Table->RATE_UP_RTY_RATIO_modify_note[0]); + } else if (dm_value[1] == RADBG_RATE_DOWN_RTY_RATIO) { /* [9]*/ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" [9] RATE_DOWN_RTY_RATIO\n")); + pvalue = &(pRA_Table->RATE_DOWN_RTY_RATIO[0]); + pvalue_default = &(pRA_Table->RATE_DOWN_RTY_RATIO_default[0]); + pmodify_note = (u1Byte *)&(pRA_Table->RATE_DOWN_RTY_RATIO_modify_note[0]); + } + + phydm_ra_print_msg(pDM_Odm, pvalue, pvalue_default, pmodify_note); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("\n------------------------------------------------------------------------------------\n\n")); + + } else if (dm_value[0] == 101) { + pRA_Table->para_idx = (u1Byte)dm_value[1]; + + pRA_Table->RA_Para_feedback_req = 1; + odm_RA_ParaAdjust_Send_H2C(pDM_Odm); + } else { + pRA_Table->para_idx = (u1Byte)dm_value[0]; + pRA_Table->rate_idx = (u1Byte)dm_value[1]; + pRA_Table->value = (u1Byte)dm_value[2]; + + odm_RA_ParaAdjust(pDM_Odm); + } + +} + +VOID +odm_RA_ParaAdjust_init( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte i; + u1Byte ra_para_pool_u8[3] = { RADBG_RTY_PENALTY, RADBG_RATE_UP_RTY_RATIO, RADBG_RATE_DOWN_RTY_RATIO}; + /* + RTY_PENALTY = 1, //u8 + N_HIGH = 2, + N_LOW = 3, + RATE_UP_TABLE = 4, + RATE_DOWN_TABLE = 5, + TRYING_NECESSARY = 6, + DROPING_NECESSARY = 7, + RATE_UP_RTY_RATIO = 8, //u8 + RATE_DOWN_RTY_RATIO= 9, //u8 + ALL_PARA = 0xff + + */ + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("odm_RA_ParaAdjust_init \n")); + + pRA_Table->is_ra_dbg_init = TRUE; + for (i = 0; i < 3; i++) { + pRA_Table->RA_Para_feedback_req = 1; + pRA_Table->para_idx = ra_para_pool_u8[i]; + odm_RA_ParaAdjust_Send_H2C(pDM_Odm); + } + + if (pDM_Odm->SupportICType == ODM_RTL8192E) + pRA_Table->rate_length = ODM_RATEMCS15; + else if ((pDM_Odm->SupportICType == ODM_RTL8723B) || (pDM_Odm->SupportICType == ODM_RTL8188E)) + pRA_Table->rate_length = ODM_RATEMCS7; + else if ((pDM_Odm->SupportICType == ODM_RTL8821) || (pDM_Odm->SupportICType == ODM_RTL8881A)) + pRA_Table->rate_length = ODM_RATEVHTSS1MCS9; + else if (pDM_Odm->SupportICType == ODM_RTL8812) + pRA_Table->rate_length = ODM_RATEVHTSS2MCS9; + else if (pDM_Odm->SupportICType == ODM_RTL8814A) + pRA_Table->rate_length = ODM_RATEVHTSS3MCS9; + else + pRA_Table->rate_length = ODM_RATEVHTSS4MCS9; + +} + +#else + +VOID +ODM_C2HRaParaReportHandler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +) +{ +} + +VOID +odm_RA_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value +) +{ +} + +VOID +odm_RA_ParaAdjust_init( + IN PVOID pDM_VOID +) + +{ +} + +#endif //#if (defined(CONFIG_RA_DBG_CMD)) + +VOID +phydm_ra_dynamic_retry_count( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + PSTA_INFO_T pEntry; + u1Byte i, retry_offset; + u4Byte ma_rx_tp; + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("pDM_Odm->pre_b_noisy = %d\n", pDM_Odm->pre_b_noisy ));*/ + if (pDM_Odm->pre_b_noisy != pDM_Odm->NoisyDecision) { + + if (pDM_Odm->NoisyDecision) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("->Noisy Env. RA fallback value\n")); + ODM_SetMACReg(pDM_Odm, 0x430, bMaskDWord, 0x0); + ODM_SetMACReg(pDM_Odm, 0x434, bMaskDWord, 0x04030201); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("->Clean Env. RA fallback value\n")); + ODM_SetMACReg(pDM_Odm, 0x430, bMaskDWord, 0x02010000); + ODM_SetMACReg(pDM_Odm, 0x434, bMaskDWord, 0x06050403); + } + pDM_Odm->pre_b_noisy = pDM_Odm->NoisyDecision; + } +} + +#if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT)) + +VOID +phydm_retry_limit_table_bound( + IN PVOID pDM_VOID, + IN u1Byte *retry_limit, + IN u1Byte offset +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + if (*retry_limit > offset) { + + *retry_limit -= offset; + + if (*retry_limit < pRA_Table->retrylimit_low) + *retry_limit = pRA_Table->retrylimit_low; + else if (*retry_limit > pRA_Table->retrylimit_high) + *retry_limit = pRA_Table->retrylimit_high; + } else + *retry_limit = pRA_Table->retrylimit_low; +} + +VOID +phydm_reset_retry_limit_table( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte i; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) /*support all IC platform*/ + + #else + #if ((RTL8192E_SUPPORT == 1) || (RTL8723B_SUPPORT == 1) || (RTL8188E_SUPPORT == 1)) + u1Byte per_rate_retrylimit_table_20M[ODM_RATEMCS15+1] = { + 1, 1, 2, 4, /*CCK*/ + 2, 2, 4, 6, 8, 12, 16, 18, /*OFDM*/ + 2, 4, 6, 8, 12, 18, 20, 22, /*20M HT-1SS*/ + 2, 4, 6, 8, 12, 18, 20, 22 /*20M HT-2SS*/ + }; + u1Byte per_rate_retrylimit_table_40M[ODM_RATEMCS15+1] = { + 1, 1, 2, 4, /*CCK*/ + 2, 2, 4, 6, 8, 12, 16, 18, /*OFDM*/ + 4, 8, 12, 16, 24, 32, 32, 32, /*40M HT-1SS*/ + 4, 8, 12, 16, 24, 32, 32, 32 /*40M HT-2SS*/ + }; + + #elif (RTL8821A_SUPPORT == 1) || (RTL8881A_SUPPORT == 1) + + #elif (RTL8812A_SUPPORT == 1) + + #elif(RTL8814A_SUPPORT == 1) + + #else + + #endif + #endif + + memcpy(&(pRA_Table->per_rate_retrylimit_20M[0]), &(per_rate_retrylimit_table_20M[0]), ODM_NUM_RATE_IDX); + memcpy(&(pRA_Table->per_rate_retrylimit_40M[0]), &(per_rate_retrylimit_table_40M[0]), ODM_NUM_RATE_IDX); + + for (i = 0; i < ODM_NUM_RATE_IDX; i++) { + phydm_retry_limit_table_bound(pDM_Odm, &(pRA_Table->per_rate_retrylimit_20M[i]), 0); + phydm_retry_limit_table_bound(pDM_Odm, &(pRA_Table->per_rate_retrylimit_40M[i]), 0); + } +} + +VOID +phydm_ra_dynamic_retry_limit( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + PSTA_INFO_T pEntry; + u1Byte i, retry_offset; + u4Byte ma_rx_tp; + + + if (pDM_Odm->pre_number_active_client == pDM_Odm->number_active_client) { + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, (" pre_number_active_client == number_active_client\n")); + return; + + } else { + if (pDM_Odm->number_active_client == 1) { + phydm_reset_retry_limit_table(pDM_Odm); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("one client only->reset to default value\n")); + } else { + + retry_offset = pDM_Odm->number_active_client * pRA_Table->retry_descend_num; + + for (i = 0; i < ODM_NUM_RATE_IDX; i++) { + + phydm_retry_limit_table_bound(pDM_Odm, &(pRA_Table->per_rate_retrylimit_20M[i]), retry_offset); + phydm_retry_limit_table_bound(pDM_Odm, &(pRA_Table->per_rate_retrylimit_40M[i]), retry_offset); + } + } + } +} + +VOID +phydm_ra_dynamic_retry_limit_init( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + + pRA_Table->retry_descend_num = RA_RETRY_DESCEND_NUM; + pRA_Table->retrylimit_low = RA_RETRY_LIMIT_LOW; + pRA_Table->retrylimit_high = RA_RETRY_LIMIT_HIGH; + + phydm_reset_retry_limit_table(pDM_Odm); + +} +#else +VOID +phydm_ra_dynamic_retry_limit( + IN PVOID pDM_VOID +) +{ +} +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +VOID +phydm_ra_dynamic_rate_id_on_assoc( + IN PVOID pDM_VOID, + IN u1Byte wireless_mode, + IN u1Byte init_rate_id +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] rf_mode = ((0x%x)), wireless_mode = ((0x%x)), init_rate_id = ((0x%x))\n", pDM_Odm->RFType, wireless_mode, init_rate_id)); + + if ((pDM_Odm->RFType == ODM_2T2R) | (pDM_Odm->RFType == ODM_2T2R_GREEN) | (pDM_Odm->RFType == ODM_2T3R) | (pDM_Odm->RFType == ODM_2T4R)) { + + if ((pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8192E)) && + (wireless_mode & (ODM_WM_N24G | ODM_WM_N5G)) + ){ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] set N-2SS ARFR5 table\n")); + ODM_SetMACReg(pDM_Odm, 0x4a4, bMaskDWord, 0xfc1ffff); /*N-2SS, ARFR5, rate_id = 0xe*/ + ODM_SetMACReg(pDM_Odm, 0x4a8, bMaskDWord, 0x0); /*N-2SS, ARFR5, rate_id = 0xe*/ + } else if ((pDM_Odm->SupportICType & (ODM_RTL8812)) && + (wireless_mode & (ODM_WM_AC_5G | ODM_WM_AC_24G | ODM_WM_AC_ONLY)) + ){ + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[ON ASSOC] set AC-2SS ARFR0 table\n")); + ODM_SetMACReg(pDM_Odm, 0x444, bMaskDWord, 0x0fff); /*AC-2SS, ARFR0, rate_id = 0x9*/ + ODM_SetMACReg(pDM_Odm, 0x448, bMaskDWord, 0xff01f000); /*AC-2SS, ARFR0, rate_id = 0x9*/ + } + } + +} + +VOID +phydm_ra_dynamic_rate_id_init( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8192E)) { + + ODM_SetMACReg(pDM_Odm, 0x4a4, bMaskDWord, 0xfc1ffff); /*N-2SS, ARFR5, rate_id = 0xe*/ + ODM_SetMACReg(pDM_Odm, 0x4a8, bMaskDWord, 0x0); /*N-2SS, ARFR5, rate_id = 0xe*/ + + ODM_SetMACReg(pDM_Odm, 0x444, bMaskDWord, 0x0fff); /*AC-2SS, ARFR0, rate_id = 0x9*/ + ODM_SetMACReg(pDM_Odm, 0x448, bMaskDWord, 0xff01f000); /*AC-2SS, ARFR0, rate_id = 0x9*/ + } +} + +VOID +phydm_update_rate_id( + IN PVOID pDM_VOID, + IN u1Byte rate, + IN u1Byte platform_macid +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte current_tx_ss; + u1Byte rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u1Byte wireless_mode; + u1Byte phydm_macid; + PSTA_INFO_T pEntry; + + if (rate_idx >= ODM_RATEVHTSS2MCS0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate[%d]: (( VHT2SS-MCS%d ))\n", platform_macid, (rate_idx-ODM_RATEVHTSS2MCS0))); + /*dummy for SD4 check patch*/ + } else if (rate_idx >= ODM_RATEVHTSS1MCS0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate[%d]: (( VHT1SS-MCS%d ))\n", platform_macid, (rate_idx-ODM_RATEVHTSS1MCS0))); + /*dummy for SD4 check patch*/ + } else if (rate_idx >= ODM_RATEMCS0) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate[%d]: (( HT-MCS%d ))\n", platform_macid, (rate_idx-ODM_RATEMCS0))); + /*dummy for SD4 check patch*/ + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate[%d]: (( HT-MCS%d ))\n", platform_macid, rate_idx)); + /*dummy for SD4 check patch*/ + } + + phydm_macid = pDM_Odm->platform2phydm_macid_table[platform_macid]; + pEntry = pDM_Odm->pODM_StaInfo[phydm_macid]; + + if (IS_STA_VALID(pEntry)) { + wireless_mode = pEntry->WirelessMode; + + if ((pDM_Odm->RFType == ODM_2T2R) | (pDM_Odm->RFType == ODM_2T2R_GREEN) | (pDM_Odm->RFType == ODM_2T3R) | (pDM_Odm->RFType == ODM_2T4R)) { + + pEntry->ratr_idx = pEntry->ratr_idx_init; + if (wireless_mode & (ODM_WM_N24G | ODM_WM_N5G)) { /*N mode*/ + if (rate_idx >= ODM_RATEMCS8 && rate_idx <= ODM_RATEMCS15) { /*2SS mode*/ + + pEntry->ratr_idx = ARFR_5_RATE_ID; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("ARFR_5\n")); + } + } else if (wireless_mode & (ODM_WM_AC_5G | ODM_WM_AC_24G | ODM_WM_AC_ONLY)) {/*AC mode*/ + if (rate_idx >= ODM_RATEVHTSS2MCS0 && rate_idx <= ODM_RATEVHTSS2MCS9) {/*2SS mode*/ + + pEntry->ratr_idx = ARFR_0_RATE_ID; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("ARFR_0\n")); + } + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("UPdate_RateID[%d]: (( 0x%x ))\n", platform_macid, pEntry->ratr_idx)); + } + } + +} +#endif + +VOID +phydm_c2h_ra_report_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + pRA_T pRA_Table = &pDM_Odm->DM_RA_Table; + u1Byte legacy_table[12] = {1,2,5,11,6,9,12,18,24,36,48,54}; + u1Byte macid = CmdBuf[1]; + + u1Byte rate = CmdBuf[0]; + u1Byte rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u1Byte vht_en=(rate_idx >= ODM_RATEVHTSS1MCS0)? 1 :0; + u1Byte b_sgi = (rate & 0x80)>>7; + + u1Byte pre_rate = pRA_Table->link_tx_rate[macid]; + u1Byte pre_rate_idx = pre_rate & 0x7f; /*remove bit7 SGI*/ + u1Byte pre_vht_en=(pre_rate_idx >= ODM_RATEVHTSS1MCS0)? 1 :0; + u1Byte pre_b_sgi = (pre_rate & 0x80)>>7; + + #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + + GET_HAL_DATA(Adapter)->CurrentRARate = HwRateToMRate(rate_idx); + #endif + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + ODM_UpdateInitRate(pDM_Odm, rate_idx); + #endif + + /*ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,("RA: rate_idx=0x%x , sgi = %d\n", rate_idx, b_sgi));*/ + /*if (pDM_Odm->SupportICType & (ODM_RTL8703B))*/ + { + if (CmdLen >= 4) { + if (CmdBuf[3] == 0) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("Init-Rate Update\n")); + /**/ + } else if (CmdBuf[3] == 0xff) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("FW Level: Fix rate\n")); + /**/ + } else if (CmdBuf[3] == 1) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("Try Success\n")); + /**/ + } else if (CmdBuf[3] == 2) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("Try Fail & Try Again\n")); + /**/ + } else if (CmdBuf[3] == 3) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("Rate Back\n")); + /**/ + } else if (CmdBuf[3] == 4) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("start rate by RSSI\n")); + /**/ + } else if (CmdBuf[3] == 5) { + ODM_RT_TRACE(pDM_Odm, ODM_FW_DEBUG_TRACE, ODM_DBG_LOUD, ("Try rate\n")); + /**/ + } + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Tx Rate Update, MACID[%d] ( %s%s%s%s%d%s%s ) -> ( %s%s%s%s%d%s%s)\n", + macid, + ((pre_rate_idx >= ODM_RATEVHTSS1MCS0) && (pre_rate_idx <= ODM_RATEVHTSS1MCS9)) ? "VHT 1ss " : "", + ((pre_rate_idx >= ODM_RATEVHTSS2MCS0) && (pre_rate_idx <= ODM_RATEVHTSS2MCS9)) ? "VHT 2ss " : "", + ((pre_rate_idx >= ODM_RATEVHTSS3MCS0) && (pre_rate_idx <= ODM_RATEVHTSS3MCS9)) ? "VHT 3ss " : "", + (pre_rate_idx >= ODM_RATEMCS0) ? "MCS " : "", + (pre_vht_en) ? ((pre_rate_idx - ODM_RATEVHTSS1MCS0)%10) : ((pre_rate_idx >= ODM_RATEMCS0)? (pre_rate_idx - ODM_RATEMCS0) : ((pre_rate_idx <= ODM_RATE54M)?legacy_table[pre_rate_idx]:0)), + (pre_b_sgi) ? "-S" : " ", + (pre_rate_idx >= ODM_RATEMCS0) ? "" : "M", + ((rate_idx >= ODM_RATEVHTSS1MCS0) && (rate_idx <= ODM_RATEVHTSS1MCS9)) ? "VHT 1ss " : "", + ((rate_idx >= ODM_RATEVHTSS2MCS0) && (rate_idx <= ODM_RATEVHTSS2MCS9)) ? "VHT 2ss " : "", + ((rate_idx >= ODM_RATEVHTSS3MCS0) && (rate_idx <= ODM_RATEVHTSS3MCS9)) ? "VHT 3ss " : "", + (rate_idx >= ODM_RATEMCS0) ? "MCS " : "", + (vht_en) ? ((rate_idx - ODM_RATEVHTSS1MCS0)%10) : ((rate_idx >= ODM_RATEMCS0)? (rate_idx - ODM_RATEMCS0) : ((rate_idx <= ODM_RATE54M)?legacy_table[rate_idx]:0)), + (b_sgi) ? "-S" : " ", + (rate_idx >= ODM_RATEMCS0) ? "" : "M" )); + + pRA_Table->link_tx_rate[macid] = rate; + + + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8192E)) + phydm_update_rate_id(pDM_Odm, rate, macid); + #endif + +} + +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_RAPostActionOnAssoc( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + pDM_Odm->H2C_RARpt_connect = 1; + odm_RSSIMonitorCheck(pDM_Odm); + pDM_Odm->H2C_RARpt_connect = 0; +} + +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) +s4Byte +phydm_FindMinimumRSSI( +IN PDM_ODM_T pDM_Odm, +IN PADAPTER pAdapter, +IN OUT BOOLEAN *pbLink_temp + + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo); + BOOLEAN act_as_ap = ACTING_AS_AP(pAdapter); + + /*DbgPrint("bMediaConnect = %d, ACTING_AS_AP = %d , EntryMinUndecoratedSmoothedPWDB = %d\n", + pMgntInfo->bMediaConnect,act_as_ap,pHalData->EntryMinUndecoratedSmoothedPWDB);*/ + + + /* 1.Determine the minimum RSSI */ + if ((!pMgntInfo->bMediaConnect) || + (act_as_ap && (pHalData->EntryMinUndecoratedSmoothedPWDB == 0))) {/* We should check AP mode and Entry info.into consideration, revised by Roger, 2013.10.18*/ + + pHalData->MinUndecoratedPWDBForDM = 0; + *pbLink_temp = FALSE; + + } else + *pbLink_temp = TRUE; + + + if (pMgntInfo->bMediaConnect) { /* Default port*/ + + if (act_as_ap || pMgntInfo->mIbss) { + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + /**/ + } else { + pHalData->MinUndecoratedPWDBForDM = pHalData->UndecoratedSmoothedPWDB; + /**/ + } + } else { /* associated entry pwdb*/ + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + /**/ + } + + return pHalData->MinUndecoratedPWDBForDM; +} + +#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; + u1Byte H2C_Parameter[4] = {0}; + u4Byte i; + BOOLEAN bExtRAInfo = FALSE; + u1Byte cmdlen = 3; + u1Byte TxBF_EN = 0, stbc_en = 0; + + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PRT_WLAN_STA pEntry = NULL; + s4Byte tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PMGNT_INFO pDefaultMgntInfo = &Adapter->MgntInfo; + u8Byte curTxOkCnt = 0, curRxOkCnt = 0; + //BOOLEAN FirstConnect = 0; + 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; +#endif + + PADAPTER pLoopAdapter = GetDefaultAdapter(Adapter); + + if (pDM_Odm->SupportICType & EXT_RA_INFO_SUPPORT_IC) { + bExtRAInfo = TRUE; + cmdlen = 4; + } + + //FirstConnect = (pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0 == FALSE); + //pRA_Table->firstconnect = pHalData->bLinked; + + + /* + 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 || + pDM_Odm->SupportICType == ODM_RTL8814A|| pDM_Odm->SupportICType == ODM_RTL8822B) + { + if(curRxOkCnt >(curTxOkCnt*6)) + H2C_Parameter[3]|=RAINFO_BE_RX_STATE; + } + */ + + 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)); + + //2 BF_en +#if (BEAMFORMING_SUPPORT) + Beamform_cap = phydm_Beamforming_GetEntryBeamCapByMacId(pDM_Odm, pEntry->AssociatedMacId); + if (Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; +#endif + //2 STBC_en + if ((IS_WIRELESS_MODE_AC(Adapter) && TEST_FLAG(pEntry->VHTInfo.STBC, STBC_VHT_ENABLE_TX)) || + TEST_FLAG(pEntry->HTInfo.STBC, STBC_HT_ENABLE_TX)) + stbc_en = 1; + + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) + tmpEntryMinPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) + tmpEntryMaxPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + + if (bExtRAInfo) { + if (curRxOkCnt > (curTxOkCnt * 6)) + H2C_Parameter[3] |= RAINFO_BE_RX_STATE; + + if (TxBF_EN) + H2C_Parameter[3] |= RAINFO_BF_STATE; + else { + if (stbc_en) + H2C_Parameter[3] |= RAINFO_STBC_STATE; + } + + if ( pDM_Odm->NoisyDecision ) + { + H2C_Parameter[3] |= RAINFO_NOISY_STATE; // BIT2 + } + else + H2C_Parameter[3] &= (~RAINFO_NOISY_STATE); + + if (pDM_Odm->H2C_RARpt_connect) + H2C_Parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + } + + 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); + + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, cmdlen, 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) { + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pDefaultMgntInfo); + PRT_VERY_HIGH_THROUGHPUT pVHTInfo = GET_VHT_INFO(pDefaultMgntInfo); + + //2 BF_en +#if (BEAMFORMING_SUPPORT == 1) + Beamform_cap = phydm_Beamforming_GetEntryBeamCapByMacId(pDM_Odm, pDefaultMgntInfo->mMacId); + + if (Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; +#endif + + //2 STBC_en + if ((IS_WIRELESS_MODE_AC(Adapter) && TEST_FLAG(pVHTInfo->VhtCurStbc, STBC_VHT_ENABLE_TX)) || + TEST_FLAG(pHTInfo->HtCurStbc, STBC_HT_ENABLE_TX)) + stbc_en = 1; + + if (bExtRAInfo) { + if (TxBF_EN) + H2C_Parameter[3] |= RAINFO_BF_STATE; + else { + if (stbc_en) + H2C_Parameter[3] |= RAINFO_STBC_STATE; + } + + if (pDM_Odm->H2C_RARpt_connect) + H2C_Parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + + if ( pDM_Odm->NoisyDecision==1 ) + { + H2C_Parameter[3] |= RAINFO_NOISY_STATE; // BIT2 + ODM_RT_TRACE(pDM_Odm, ODM_COMP_NOISY_DETECT, ODM_DBG_LOUD, ("[RSSIMonitorCheckMP] Send H2C to FW\n")); + } + else + H2C_Parameter[3] &= (~RAINFO_NOISY_STATE); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_NOISY_DETECT, ODM_DBG_LOUD, ("[RSSIMonitorCheckMP] H2C_Parameter=%x\n", H2C_Parameter[3])); + } + + 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 + + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, cmdlen, 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; + + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, cmdlen, 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); + BOOLEAN default_pointer_value, *pbLink_temp = &default_pointer_value; + s4Byte GlobalRSSI_min = 0xFF, LocalRSSI_Min; + BOOLEAN bLink = FALSE; + + while (pLoopAdapter) { + LocalRSSI_Min = phydm_FindMinimumRSSI(pDM_Odm, pLoopAdapter, pbLink_temp); + //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 (*pbLink_temp) + bLink = TRUE; + + pLoopAdapter = GetNextExtAdapter(pLoopAdapter); + } + + pHalData->bLinked = bLink; + ODM_CmnInfoUpdate(&pHalData->DM_OutSrc , ODM_CMNINFO_LINK, (u8Byte)bLink); + + if (bLink) + ODM_CmnInfoUpdate(&pHalData->DM_OutSrc, ODM_CMNINFO_RSSI_MIN, (u8Byte)GlobalRSSI_min); + else + ODM_CmnInfoUpdate(&pHalData->DM_OutSrc, ODM_CMNINFO_RSSI_MIN, 0); + + } + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +/*H2C_RSSI_REPORT*/ +s8 phydm_rssi_report(PDM_ODM_T pDM_Odm, u8 mac_id) +{ + PADAPTER Adapter = pDM_Odm->Adapter; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 H2C_Parameter[4] = {0}; + u8 UL_DL_STATE = 0, STBC_TX = 0, TxBF_EN = 0; + u8 cmdlen = 4, first_connect = _FALSE; + u64 curTxOkCnt = 0, curRxOkCnt = 0; + PSTA_INFO_T pEntry = pDM_Odm->pODM_StaInfo[mac_id]; + + if (!IS_STA_VALID(pEntry)) + return _FAIL; + + if (mac_id != pEntry->mac_id) { + DBG_871X("%s mac_id:%u:%u invalid\n", __func__, mac_id, pEntry->mac_id); + rtw_warn_on(1); + return _FAIL; + } + + if (IS_MCAST(pEntry->hwaddr)) /*if(psta->mac_id ==1)*/ + return _FAIL; + + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB == (-1)) { + DBG_871X("%s mac_id:%u, mac:"MAC_FMT", rssi == -1\n", __func__, pEntry->mac_id, MAC_ARG(pEntry->hwaddr)); + return _FAIL; + } + + curTxOkCnt = pdvobjpriv->traffic_stat.cur_tx_bytes; + curRxOkCnt = pdvobjpriv->traffic_stat.cur_rx_bytes; + if (curRxOkCnt > (curTxOkCnt * 6)) + UL_DL_STATE = 1; + else + UL_DL_STATE = 0; + + #ifdef CONFIG_BEAMFORMING + { + #if (BEAMFORMING_SUPPORT == 1) + BEAMFORMING_CAP Beamform_cap = phydm_Beamforming_GetEntryBeamCapByMacId(pDM_Odm, pEntry->mac_id); + #else/*for drv beamforming*/ + BEAMFORMING_CAP Beamform_cap = beamforming_get_entry_beam_cap_by_mac_id(&Adapter->mlmepriv, pEntry->mac_id); + #endif + + if (Beamform_cap & (BEAMFORMER_CAP_HT_EXPLICIT | BEAMFORMER_CAP_VHT_SU)) + TxBF_EN = 1; + else + TxBF_EN = 0; + } + #endif /*#ifdef CONFIG_BEAMFORMING*/ + + if (TxBF_EN) + STBC_TX = 0; + else { + #ifdef CONFIG_80211AC_VHT + if (IsSupportedVHT(pEntry->wireless_mode)) + STBC_TX = TEST_FLAG(pEntry->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX); + else + #endif + STBC_TX = TEST_FLAG(pEntry->htpriv.stbc_cap, STBC_HT_ENABLE_TX); + } + + H2C_Parameter[0] = (u8)(pEntry->mac_id & 0xFF); + H2C_Parameter[2] = pEntry->rssi_stat.UndecoratedSmoothedPWDB & 0x7F; + + if (UL_DL_STATE) + H2C_Parameter[3] |= RAINFO_BE_RX_STATE; + + if (TxBF_EN) + H2C_Parameter[3] |= RAINFO_BF_STATE; + if (STBC_TX) + H2C_Parameter[3] |= RAINFO_STBC_STATE; + if (pDM_Odm->NoisyDecision) + H2C_Parameter[3] |= RAINFO_NOISY_STATE; + + if (pEntry->ra_rpt_linked == _FALSE) { + H2C_Parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + pEntry->ra_rpt_linked = _TRUE; + first_connect = _TRUE; + } + + #if 1 + if (first_connect) { + DBG_871X("%s mac_id:%u, mac:"MAC_FMT", rssi:%d\n", __func__, + pEntry->mac_id, MAC_ARG(pEntry->hwaddr), pEntry->rssi_stat.UndecoratedSmoothedPWDB); + + DBG_871X("%s RAINFO - TP:%s, TxBF:%s, STBC:%s, Noisy:%s, Firstcont:%s\n", __func__, + (UL_DL_STATE) ? "DL" : "UL", (TxBF_EN) ? "EN" : "DIS", (STBC_TX) ? "EN" : "DIS", + (pDM_Odm->NoisyDecision) ? "True" : "False", (first_connect) ? "True" : "False"); + } + #endif + + if (pHalData->fw_ractrl == _TRUE) { + #if (RTL8188E_SUPPORT == 1) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + cmdlen = 3; + #endif + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, cmdlen, H2C_Parameter); + } else { + #if ((RTL8188E_SUPPORT == 1) && (RATE_ADAPTIVE_SUPPORT == 1)) + if (pDM_Odm->SupportICType == ODM_RTL8188E) + ODM_RA_SetRSSI_8188E(pDM_Odm, (u8)(pEntry->mac_id & 0xFF), pEntry->rssi_stat.UndecoratedSmoothedPWDB & 0x7F); + #endif + } + return _SUCCESS; +} + +void phydm_ra_rssi_rpt_wk_hdl(PVOID pContext) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pContext; + int i; + u8 mac_id = 0xFF; + PSTA_INFO_T pEntry = NULL; + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + pEntry = pDM_Odm->pODM_StaInfo[i]; + if (IS_STA_VALID(pEntry)) { + if (IS_MCAST(pEntry->hwaddr)) /*if(psta->mac_id ==1)*/ + continue; + if (pEntry->ra_rpt_linked == _FALSE) { + mac_id = i; + break; + } + } + } + if (mac_id != 0xFF) + phydm_rssi_report(pDM_Odm, mac_id); +} +void phydm_ra_rssi_rpt_wk(PVOID pContext) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pContext; + + rtw_run_in_thread_cmd(pDM_Odm->Adapter, phydm_ra_rssi_rpt_wk_hdl, pDM_Odm); +} +#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); + PSTA_INFO_T pEntry; + int i; + int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; + u8 sta_cnt = 0; + + if (pDM_Odm->bLinked != _TRUE) + return; + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + pEntry = pDM_Odm->pODM_StaInfo[i]; + if (IS_STA_VALID(pEntry)) { + if (IS_MCAST(pEntry->hwaddr)) /*if(psta->mac_id ==1)*/ + continue; + + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB == (-1)) + continue; + + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) + tmpEntryMinPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + + if (pEntry->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) + tmpEntryMaxPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; + + if (phydm_rssi_report(pDM_Odm, i)) + sta_cnt++; + } + } + /*DBG_871X("%s==> sta_cnt(%d)\n", __func__, sta_cnt);*/ + + if (tmpEntryMaxPWDB != 0) // If associated entry is found + pHalData->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; + else + pHalData->EntryMaxUndecoratedSmoothedPWDB = 0; + + if (tmpEntryMinPWDB != 0xff) // If associated entry is found + pHalData->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; + else + pHalData->EntryMinUndecoratedSmoothedPWDB = 0; + + FindMinimumRSSI(Adapter);//get pdmpriv->MinUndecoratedPWDBForDM + + pDM_Odm->RSSI_Min = pHalData->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 (RTL8812A_SUPPORT||RTL8881A_SUPPORT||RTL8192E_SUPPORT||RTL8814A_SUPPORT) + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte H2C_Parameter[4] = {0}; + u4Byte i; + BOOLEAN bExtRAInfo = FALSE; + u1Byte cmdlen = 3 ; + u1Byte TxBF_EN = 0, stbc_en = 0; + + prtl8192cd_priv priv = pDM_Odm->priv; + PSTA_INFO_T pstat; + BOOLEAN act_bfer = FALSE; + +#ifdef BEAMFORMING_SUPPORT +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) + pBDC_T pDM_BdcTable = &pDM_Odm->DM_BdcTable; + pDM_BdcTable->num_Txbfee_Client = 0; + pDM_BdcTable->num_Txbfer_Client = 0; +#endif +#endif + + if (pDM_Odm->H2C_RARpt_connect) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[RA Init] First Connected\n")); + /**/ + } else if (priv->up_time % 2) + return; + + if (pDM_Odm->SupportICType & EXT_RA_INFO_SUPPORT_IC) { + bExtRAInfo = TRUE; + cmdlen = 4; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + pstat = pDM_Odm->pODM_StaInfo[i]; + + if (IS_STA_VALID(pstat)) { + if (pstat->sta_in_firmware != 1) + continue; + + //2 BF_en +#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; + act_bfer = TRUE; + } + +#if (defined(CONFIG_PHYDM_ANTENNA_DIVERSITY)) /*BDC*/ + + if (act_bfer == TRUE) { + 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 + } +#endif +#endif + + //2 STBC_en + 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 + )) + stbc_en = 1; + + //2 RAINFO + + if (bExtRAInfo) { + if ((pstat->rx_avarage) > ((pstat->tx_avarage) * 6)) + H2C_Parameter[3] |= RAINFO_BE_RX_STATE; + + if (TxBF_EN) + H2C_Parameter[3] |= RAINFO_BF_STATE; + else { + if (stbc_en) + H2C_Parameter[3] |= RAINFO_STBC_STATE; + } + + if ( pDM_Odm->NoisyDecision ) + { + H2C_Parameter[3] |= RAINFO_NOISY_STATE; // BIT2 + } + else + H2C_Parameter[3] &= (~RAINFO_NOISY_STATE); + + if (pDM_Odm->H2C_RARpt_connect) { + H2C_Parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("[RA Init] set Init rate by RSSI\n")); + } + + /*ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[RAINFO] H2C_Para[3] = %x\n",H2C_Parameter[3]));*/ + } + + H2C_Parameter[2] = (u1Byte)(pstat->rssi & 0xFF); + H2C_Parameter[0] = REMAP_AID(pstat); + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_COMMON, ODM_DBG_LOUD, + ("H2C_Parameter[3]=%d\n", H2C_Parameter[3])); + + //ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[RSSI] H2C_Para[2] = %x, \n",H2C_Parameter[2])); + //ODM_RT_TRACE(pDM_Odm,PHYDM_COMP_RA_DBG, ODM_DBG_LOUD, ("[MACID] H2C_Para[0] = %x, \n",H2C_Parameter[0])); + + ODM_FillH2CCmd(pDM_Odm, ODM_H2C_RSSI_REPORT, cmdlen, H2C_Parameter); + + } + } + +#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; +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) && \ + ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) + pOdmRA->LowRSSIThresh = 23; +#else + pOdmRA->LowRSSIThresh = 20; +#endif +} +/*----------------------------------------------------------------------------- + * 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; + } + +} + +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 (RTW_CANNOT_RUN(pAdapter)) { + 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; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + PSTA_INFO_T pstat = pDM_Odm->pODM_StaInfo[i]; + if (IS_STA_VALID(pstat)) { + if (IS_MCAST(pstat->hwaddr)) //if(psta->mac_id ==1) + 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) + 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; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + pstat = pDM_Odm->pODM_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)); + +#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 + } + } + } + } +#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; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("RSSI= (( %d )), Current_RSSI_level = (( %d ))\n", RSSI, *pRATRState)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("[Ori RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", HighRSSIThreshForRA, LowRSSIThreshForRA)); + // 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 + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, ("[Mod RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", HighRSSIThreshForRA, LowRSSIThreshForRA)); + /*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 Update] %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 +} + + +VOID +phydm_ra_info_init( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + #if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT)) + phydm_ra_dynamic_retry_limit_init(pDM_Odm); + #endif + #if (DM_ODM_SUPPORT_TYPE == ODM_AP) + phydm_ra_dynamic_rate_id_init(pDM_Odm); + #endif + + /*phydm_fw_trace_en_h2c(pDM_Odm, 1, 0, 0);*/ +} + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) +u1Byte +odm_Find_RTS_Rate( + IN PVOID pDM_VOID, + IN u1Byte Tx_Rate, + IN BOOLEAN bErpProtect +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte RTS_Ini_Rate = ODM_RATE6M; + + if (bErpProtect) /* use CCK rate as RTS*/ + RTS_Ini_Rate = ODM_RATE1M; + else { + switch (Tx_Rate) { + case ODM_RATEVHTSS3MCS9: + case ODM_RATEVHTSS3MCS8: + case ODM_RATEVHTSS3MCS7: + case ODM_RATEVHTSS3MCS6: + case ODM_RATEVHTSS3MCS5: + case ODM_RATEVHTSS3MCS4: + case ODM_RATEVHTSS3MCS3: + case ODM_RATEVHTSS2MCS9: + case ODM_RATEVHTSS2MCS8: + case ODM_RATEVHTSS2MCS7: + case ODM_RATEVHTSS2MCS6: + case ODM_RATEVHTSS2MCS5: + case ODM_RATEVHTSS2MCS4: + case ODM_RATEVHTSS2MCS3: + case ODM_RATEVHTSS1MCS9: + case ODM_RATEVHTSS1MCS8: + case ODM_RATEVHTSS1MCS7: + case ODM_RATEVHTSS1MCS6: + case ODM_RATEVHTSS1MCS5: + case ODM_RATEVHTSS1MCS4: + case ODM_RATEVHTSS1MCS3: + case ODM_RATEMCS15: + case ODM_RATEMCS14: + case ODM_RATEMCS13: + case ODM_RATEMCS12: + case ODM_RATEMCS11: + case ODM_RATEMCS7: + case ODM_RATEMCS6: + case ODM_RATEMCS5: + case ODM_RATEMCS4: + case ODM_RATEMCS3: + case ODM_RATE54M: + case ODM_RATE48M: + case ODM_RATE36M: + case ODM_RATE24M: + RTS_Ini_Rate = ODM_RATE24M; + break; + case ODM_RATEVHTSS3MCS2: + case ODM_RATEVHTSS3MCS1: + case ODM_RATEVHTSS2MCS2: + case ODM_RATEVHTSS2MCS1: + case ODM_RATEVHTSS1MCS2: + case ODM_RATEVHTSS1MCS1: + case ODM_RATEMCS10: + case ODM_RATEMCS9: + case ODM_RATEMCS2: + case ODM_RATEMCS1: + case ODM_RATE18M: + case ODM_RATE12M: + RTS_Ini_Rate = ODM_RATE12M; + break; + case ODM_RATEVHTSS3MCS0: + case ODM_RATEVHTSS2MCS0: + case ODM_RATEVHTSS1MCS0: + case ODM_RATEMCS8: + case ODM_RATEMCS0: + case ODM_RATE9M: + case ODM_RATE6M: + RTS_Ini_Rate = ODM_RATE6M; + break; + case ODM_RATE11M: + case ODM_RATE5_5M: + case ODM_RATE2M: + case ODM_RATE1M: + RTS_Ini_Rate = ODM_RATE1M; + break; + default: + RTS_Ini_Rate = ODM_RATE6M; + break; + } + } + + if (*pDM_Odm->pBandType == 1) { + if (RTS_Ini_Rate < ODM_RATE6M) + RTS_Ini_Rate = ODM_RATE6M; + } + return RTS_Ini_Rate; + +} + +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 PVOID pDM_VOID, + IN BOOLEAN bNoisyStateFromC2H +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + /*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 PVOID pDM_VOID, + IN WIRELESS_MODE WirelessMode, + IN u4Byte ratr_bitmap, + IN u1Byte rssi_level +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte ret_bitmap = ratr_bitmap; + + return ret_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 &= 0xfc3e0c08; // Reserve MCS 5-9 + else if (rssi_level == 2) + ret_bitmap &= 0xfe3f8e08; // Reserve MCS 3-9 + else if (rssi_level == 3) + ret_bitmap &= 0xffffffff; + else + ret_bitmap &= 0xffffffff; + } else { /* in SNR State*/ + if (rssi_level == 1) + ret_bitmap &= 0xfe3f0e08; // Reserve MCS 4-9 + else if (rssi_level == 2) + ret_bitmap &= 0xff3fcf8c; // Reserve MCS 2-9 + else if (rssi_level == 3) + ret_bitmap &= 0xffffffff; + else + ret_bitmap &= 0xffffffff; + } + 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; // Reserve MCS 4-7; MCS12-15 + else if (rssi_level == 2) + ret_bitmap &= 0x0fcfce0c; // Reserve MCS 2-7; MCS10-15 + else if (rssi_level == 3) + ret_bitmap &= 0xffffffff; + else + ret_bitmap &= 0xffffffff; + } else { + if (rssi_level == 1) + ret_bitmap &= 0x0f8f8e08; // Reserve MCS 3-7; MCS11-15 + else if (rssi_level == 2) + ret_bitmap &= 0x0fefef8c; // Reserve MCS 1-7; MCS9-15 + else if (rssi_level == 3) + ret_bitmap &= 0xffffffff; + else + ret_bitmap &= 0xffffffff; + } + break; + default: + break; + } + /*DbgPrint("DM_RAMask ====> rssi_LV = %d, BITMAP = %x\n", rssi_level, ret_bitmap);*/ + return ret_bitmap; + +} + +VOID +ODM_UpdateInitRate( + IN PVOID pDM_VOID, + IN u1Byte Rate +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte p = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Get C2H Command! Rate=0x%x\n", Rate)); + + 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) { +#if (RTL8821A_SUPPORT == 1) + ODM_TxPwrTrackSetPwr8821A(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); +#endif + } else if (pDM_Odm->SupportICType == ODM_RTL8812) { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8812A; p++) { +#if (RTL8812A_SUPPORT == 1) + ODM_TxPwrTrackSetPwr8812A(pDM_Odm, MIX_MODE, p, 0); +#endif + } + } else if (pDM_Odm->SupportICType == ODM_RTL8723B) { +#if (RTL8723B_SUPPORT == 1) + ODM_TxPwrTrackSetPwr_8723B(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); +#endif + } else if (pDM_Odm->SupportICType == ODM_RTL8192E) { + for (p = ODM_RF_PATH_A; p < MAX_PATH_NUM_8192E; p++) { +#if (RTL8192E_SUPPORT == 1) + ODM_TxPwrTrackSetPwr92E(pDM_Odm, MIX_MODE, p, 0); +#endif + } + } else if (pDM_Odm->SupportICType == ODM_RTL8188E) { +#if (RTL8188E_SUPPORT == 1) + ODM_TxPwrTrackSetPwr88E(pDM_Odm, MIX_MODE, ODM_RF_PATH_A, 0); +#endif + } +#endif +#else + PlatformScheduleWorkItem(&pDM_Odm->RaRptWorkitem); +#endif +#endif + +} + +#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]); + } +} + +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; +} + +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; +} +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) /*#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)*/ + +static void +FindMinimumRSSI( + IN PADAPTER pAdapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + /*Determine the minimum RSSI*/ + + if ((pDM_Odm->bLinked != _TRUE) && + (pHalData->EntryMinUndecoratedSmoothedPWDB == 0)) { + pHalData->MinUndecoratedPWDBForDM = 0; + /*ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any\n"));*/ + } else + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + + /*DBG_8192C("%s=>MinUndecoratedPWDBForDM(%d)\n",__FUNCTION__,pdmpriv->MinUndecoratedPWDBForDM);*/ + /*ODM_RT_TRACE(pDM_Odm,COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",pHalData->MinUndecoratedPWDBForDM));*/ +} + +u8Byte +PhyDM_Get_Rate_Bitmap_Ex( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u8Byte ra_mask, + IN u1Byte rssi_level, + OUT u8Byte *dm_RA_Mask, + OUT u1Byte *dm_RteID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PSTA_INFO_T pEntry; + u8Byte rate_bitmap = 0; + u1Byte WirelessMode; + + 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 & 0x000000000000000c) /* 11M or 5.5M enable */ + rate_bitmap = 0x000000000000000d; + else + rate_bitmap = 0x000000000000000f; + break; + + case (ODM_WM_G): + case (ODM_WM_A): + if (rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x0000000000000f00; + else + rate_bitmap = 0x0000000000000ff0; + break; + + case (ODM_WM_B|ODM_WM_G): + if (rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x0000000000000f00; + else if (rssi_level == DM_RATR_STA_MIDDLE) + rate_bitmap = 0x0000000000000ff0; + else + rate_bitmap = 0x0000000000000ff5; + 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 = 0x00000000000f0000; + else if (rssi_level == DM_RATR_STA_MIDDLE) + rate_bitmap = 0x00000000000ff000; + else { + if (*(pDM_Odm->pBandWidth) == ODM_BW40M) + rate_bitmap = 0x00000000000ff015; + else + rate_bitmap = 0x00000000000ff005; + } + } else if (pDM_Odm->RFType == ODM_2T2R || pDM_Odm->RFType == ODM_2T3R || pDM_Odm->RFType == ODM_2T4R) { + if (rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x000000000f8f0000; + else if (rssi_level == DM_RATR_STA_MIDDLE) + rate_bitmap = 0x000000000f8ff000; + else { + if (*(pDM_Odm->pBandWidth) == ODM_BW40M) + rate_bitmap = 0x000000000f8ff015; + else + rate_bitmap = 0x000000000f8ff005; + } + } else { + if (rssi_level == DM_RATR_STA_HIGH) + rate_bitmap = 0x0000000f0f0f0000; + else if (rssi_level == DM_RATR_STA_MIDDLE) + rate_bitmap = 0x0000000fcfcfe000; + else { + if (*(pDM_Odm->pBandWidth) == ODM_BW40M) + rate_bitmap = 0x0000000ffffff015; + else + rate_bitmap = 0x0000000ffffff005; + } + } + } + break; + + case (ODM_WM_AC|ODM_WM_G): + if (rssi_level == 1) + rate_bitmap = 0x00000000fc3f0000; + else if (rssi_level == 2) + rate_bitmap = 0x00000000fffff000; + else + rate_bitmap = 0x00000000ffffffff; + break; + + case (ODM_WM_AC|ODM_WM_A): + + if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) { + if (rssi_level == 1) /* add by Gary for ac-series */ + rate_bitmap = 0x00000000003f8000; + else if (rssi_level == 2) + rate_bitmap = 0x00000000003fe000; + else + rate_bitmap = 0x00000000003ff010; + } else if (pDM_Odm->RFType == ODM_2T2R || pDM_Odm->RFType == ODM_2T3R || pDM_Odm->RFType == ODM_2T4R) { + if (rssi_level == 1) /* add by Gary for ac-series */ + rate_bitmap = 0x00000000fe3f8000; /* VHT 2SS MCS3~9 */ + else if (rssi_level == 2) + rate_bitmap = 0x00000000fffff000; /* VHT 2SS MCS0~9 */ + else + rate_bitmap = 0x00000000fffff010; /* All */ + } else { + if (rssi_level == 1) /* add by Gary for ac-series */ + rate_bitmap = 0x000003f8fe3f8000ULL; /* VHT 3SS MCS3~9 */ + else if (rssi_level == 2) + rate_bitmap = 0x000003fffffff000ULL; /* VHT3SS MCS0~9 */ + else + rate_bitmap = 0x000003fffffff010ULL; /* All */ + } + break; + + default: + if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) + rate_bitmap = 0x00000000000fffff; + else if (pDM_Odm->RFType == ODM_2T2R || pDM_Odm->RFType == ODM_2T3R || pDM_Odm->RFType == ODM_2T4R) + rate_bitmap = 0x000000000fffffff; + else + rate_bitmap = 0x0000003fffffffffULL; + break; + + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%016llx\n", rssi_level, WirelessMode, rate_bitmap)); + + return (ra_mask & rate_bitmap); +} + + +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; + + } + + DBG_871X("%s ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x\n", __func__, 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) + +#endif /*#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN| ODM_CE))*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.h new file mode 100644 index 00000000..35f26c3e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rainfo.h @@ -0,0 +1,445 @@ +/****************************************************************************** + * + * 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 "2.0" //2014.11.04*/ +/*#define RAINFO_VERSION "3.0" //2015.01.13 Dino*/ +/*#define RAINFO_VERSION "3.1" //2015.01.14 Dino*/ +#define RAINFO_VERSION "3.2" /*2015.01.14 Dino*/ + +#define HIGH_RSSI_THRESH 50 +#define LOW_RSSI_THRESH 20 + +#define ACTIVE_TP_THRESHOLD 150 +#define RA_RETRY_DESCEND_NUM 2 +#define RA_RETRY_LIMIT_LOW 4 +#define RA_RETRY_LIMIT_HIGH 32 + +#define PHYDM_IC_8051_SERIES (ODM_RTL8881A|ODM_RTL8812|ODM_RTL8821|ODM_RTL8192S|ODM_RTL8192C|ODM_RTL8192D|ODM_RTL8723A|ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8703B|ODM_RTL8188F) +#define PHYDM_IC_3081_SERIES (ODM_RTL8814A|ODM_RTL8821B|ODM_RTL8822B) + +#define RAINFO_BE_RX_STATE BIT0 // 1:RX //ULDL +#define RAINFO_STBC_STATE BIT1 +//#define RAINFO_LDPC_STATE BIT2 +#define RAINFO_NOISY_STATE BIT2 // set by Noisy_Detection +#define RAINFO_SHURTCUT_STATE BIT3 +#define RAINFO_SHURTCUT_FLAG BIT4 +#define RAINFO_INIT_RSSI_RATE_STATE BIT5 +#define RAINFO_BF_STATE BIT6 +#define RAINFO_BE_TX_STATE BIT7 // 1:TX + +#define RA_MASK_CCK 0xf +#define RA_MASK_OFDM 0xff0 +#define RA_MASK_HT1SS 0xff000 +#define RA_MASK_HT2SS 0xff00000 +/*#define RA_MASK_MCS3SS */ +#define RA_MASK_HT4SS 0xff0 +#define RA_MASK_VHT1SS 0x3ff000 +#define RA_MASK_VHT2SS 0xffc00000 + +#if(DM_ODM_SUPPORT_TYPE == ODM_AP) +#define EXT_RA_INFO_SUPPORT_IC (ODM_RTL8881A |ODM_RTL8192E |ODM_RTL8812 |ODM_RTL8814A|ODM_RTL8822B) +#define RA_FIRST_MACID 1 +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define EXT_RA_INFO_SUPPORT_IC (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8723B | ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8703B) +#define RA_FIRST_MACID 0 +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) +/*#define EXT_RA_INFO_SUPPORT_IC (ODM_RTL8192E|ODM_RTL8812|ODM_RTL8821|ODM_RTL8723B|ODM_RTL8814A|ODM_RTL8822B|ODM_RTL8703B) */ +#define RA_FIRST_MACID 0 +#endif + + +#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) +#define DM_RATR_STA_ULTRA_LOW 4 +#endif + +#define DM_RA_RATE_UP 1 +#define DM_RA_RATE_DOWN 2 + +typedef enum _phydm_arfr_num { + ARFR_0_RATE_ID = 0x9, + ARFR_1_RATE_ID = 0xa, + ARFR_2_RATE_ID = 0xb, + ARFR_3_RATE_ID = 0xc, + ARFR_4_RATE_ID = 0xd, + ARFR_5_RATE_ID = 0xe +} PHYDM_RA_ARFR_NUM_E; + +typedef enum _Phydm_ra_dbg_para { + RADBG_RTY_PENALTY = 1, //u8 + RADBG_N_HIGH = 2, + RADBG_N_LOW = 3, + RADBG_TRATE_UP_TABLE = 4, + RADBG_TRATE_DOWN_TABLE = 5, + RADBG_TRYING_NECESSARY = 6, + RADBG_TDROPING_NECESSARY = 7, + RADBG_RATE_UP_RTY_RATIO = 8, //u8 + RADBG_RATE_DOWN_RTY_RATIO = 9, //u8 + + RADBG_DEBUG_MONITOR1 = 0xc, + RADBG_DEBUG_MONITOR2 = 0xd, + RADBG_DEBUG_MONITOR3 = 0xe, + RADBG_DEBUG_MONITOR4 = 0xf, + NUM_RA_PARA +} PHYDM_RA_DBG_PARA_E; + + +#if (RATE_ADAPTIVE_SUPPORT == 1)//88E RA +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 +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) && ((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) + u1Byte RateDownCounter; + u1Byte RateUpCounter; + u1Byte RateDirection; + u1Byte BoundingType; + u1Byte BoundingCounter; + u1Byte BoundingLearningTime; + u1Byte RateDownStartTime; +#endif +} ODM_RA_INFO_T, *PODM_RA_INFO_T; +#endif + + +typedef struct _Rate_Adaptive_Table_ { + u1Byte firstconnect; +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) + BOOLEAN PT_collision_pre; +#endif + +#if (defined(CONFIG_RA_DBG_CMD)) + BOOLEAN is_ra_dbg_init; + + u1Byte RTY_P[ODM_NUM_RATE_IDX]; + u1Byte RTY_P_default[ODM_NUM_RATE_IDX]; + BOOLEAN RTY_P_modify_note[ODM_NUM_RATE_IDX]; + + u1Byte RATE_UP_RTY_RATIO[ODM_NUM_RATE_IDX]; + u1Byte RATE_UP_RTY_RATIO_default[ODM_NUM_RATE_IDX]; + BOOLEAN RATE_UP_RTY_RATIO_modify_note[ODM_NUM_RATE_IDX]; + + u1Byte RATE_DOWN_RTY_RATIO[ODM_NUM_RATE_IDX]; + u1Byte RATE_DOWN_RTY_RATIO_default[ODM_NUM_RATE_IDX]; + BOOLEAN RATE_DOWN_RTY_RATIO_modify_note[ODM_NUM_RATE_IDX]; + + BOOLEAN RA_Para_feedback_req; + + u1Byte para_idx; + u1Byte rate_idx; + u1Byte value; + u2Byte value_16; + u1Byte rate_length; +#endif + u1Byte link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM]; + + #if (defined(CONFIG_RA_DYNAMIC_RTY_LIMIT)) + u1Byte per_rate_retrylimit_20M[ODM_NUM_RATE_IDX]; + u1Byte per_rate_retrylimit_40M[ODM_NUM_RATE_IDX]; + u1Byte retry_descend_num; + u1Byte retrylimit_low; + u1Byte retrylimit_high; + #endif + + +} RA_T, *pRA_T; + +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_C2HRaParaReportHandler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +); + +VOID +odm_RA_ParaAdjust_Send_H2C( + IN PVOID pDM_VOID +); + +VOID +odm_RA_debug( + IN PVOID pDM_VOID, + IN u4Byte *const dm_value +); + +VOID +odm_RA_ParaAdjust_init( + IN PVOID pDM_VOID +); + +VOID +odm_RA_ParaAdjust( + IN PVOID pDM_VOID +); + +VOID +phydm_ra_dynamic_retry_count( + IN PVOID pDM_VOID +); + +VOID +phydm_ra_dynamic_retry_limit( + IN PVOID pDM_VOID +); + +VOID +phydm_ra_dynamic_rate_id_on_assoc( + IN PVOID pDM_VOID, + IN u1Byte wireless_mode, + IN u1Byte init_rate_id +); + +VOID +phydm_c2h_ra_report_handler( + IN PVOID pDM_VOID, + IN pu1Byte CmdBuf, + IN u1Byte CmdLen +); + +VOID +phydm_ra_info_init( + IN PVOID pDM_VOID +); + +VOID +odm_RSSIMonitorInit( + IN PVOID pDM_VOID +); + +VOID +odm_RSSIMonitorCheck( + IN PVOID pDM_VOID +); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +s4Byte +phydm_FindMinimumRSSI( +IN PDM_ODM_T pDM_Odm, +IN PADAPTER pAdapter, +IN OUT BOOLEAN *pbLink_temp + + ); +#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 +); +VOID +ODM_RAPostActionOnAssoc( + IN PVOID pDM_Odm +); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + +u1Byte +odm_Find_RTS_Rate( + IN PVOID pDM_VOID, + IN u1Byte Tx_Rate, + IN BOOLEAN bErpProtect +); + +VOID +ODM_UpdateNoisyState( + IN PVOID pDM_VOID, + IN BOOLEAN bNoisyStateFromC2H +); + +u4Byte +Set_RA_DM_Ratrbitmap_by_Noisy( + IN PVOID pDM_VOID, + IN WIRELESS_MODE WirelessMode, + IN u4Byte ratr_bitmap, + IN u1Byte rssi_level +); + +VOID +ODM_UpdateInitRate( + IN PVOID pDM_VOID, + IN u1Byte Rate +); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +odm_RSSIDumpToRegister( + IN PVOID pDM_VOID +); + +VOID +odm_RefreshLdpcRtsMP( + IN PADAPTER pAdapter, + IN PDM_ODM_T pDM_Odm, + IN u1Byte mMacId, + IN u1Byte IOTPeer, + IN s4Byte UndecoratedSmoothedPWDB +); + +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 +); +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + +static void +FindMinimumRSSI( + IN PADAPTER pAdapter +); + +u8Byte +PhyDM_Get_Rate_Bitmap_Ex( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u8Byte ra_mask, + IN u1Byte rssi_level, + OUT u8Byte *dm_RA_Mask, + OUT u1Byte *dm_RteID +); +u4Byte +ODM_Get_Rate_Bitmap( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u4Byte ra_mask, + IN u1Byte rssi_level +); +void phydm_ra_rssi_rpt_wk(PVOID pContext); + +#endif/*#elif (DM_ODM_SUPPORT_TYPE == ODM_CE)*/ + +#endif/*#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN| ODM_CE))*/ + +#endif /*#ifndef __ODMRAINFO_H__*/ + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_reg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_reg.h new file mode 100644 index 00000000..8deff913 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11ac.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11ac.h new file mode 100644 index 00000000..3dfaf1f9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11ac.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * + * 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_TX_PATH_11AC 0x80c +#define ODM_REG_BB_ATC_11AC 0x860 +#define ODM_REG_EDCCA_POWER_CAL 0x8dc +#define ODM_REG_DBG_RPT_11AC 0x8fc +//PAGE 9 +#define ODM_REG_EDCCA_DOWN_OPT 0x900 +#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944 +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +#define ODM_REG_NHM_TIMER_11AC 0x990 +#define ODM_REG_CLM_TIME_PERIOD_11AC 0x990 +#define ODM_REG_NHM_TH9_TH10_11AC 0x994 +#define ODM_REG_CLM_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 +#define ODM_REG_CSI_CONTENT_VALUE 0x9b4 +//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_CLM_RESULT_11AC 0xfa4 +#define ODM_REG_NHM_CNT_11AC 0xfa8 +#define ODM_REG_NHM_DUR_READY_11AC 0xfb4 + +#define ODM_REG_NHM_CNT7_TO_CNT4_11AC 0xfac +#define ODM_REG_NHM_CNT11_TO_CNT8_11AC 0xfb0 +#define ODM_REG_OFDM_FA_TYPE2_11AC 0xFD0 +//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_TX_PATH_11AC 0xF +#define ODM_BIT_BB_ATC_11AC BIT14 + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11n.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11n.h new file mode 100644 index 00000000..2f09dc7f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_regdefine11n.h @@ -0,0 +1,199 @@ +/****************************************************************************** + * + * 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_CLM_TIME_PERIOD_11N 0x894 +#define ODM_REG_NHM_TH9_TH10_11N 0x890 +#define ODM_REG_CLM_11N 0x890 +#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898 +#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c +#define ODM_REG_NHM_TH8_11N 0xe28 +#define ODM_REG_CLM_READY_11N 0x8b4 +#define ODM_REG_CLM_RESULT_11N 0x8d0 +#define ODM_REG_NHM_CNT_11N 0x8d8 + +// For ACS, Jeffery, 2014-12-26 +#define ODM_REG_NHM_CNT7_TO_CNT4_11N 0x8dc +#define ODM_REG_NHM_CNT9_TO_CNT8_11N 0x8d0 +#define ODM_REG_NHM_CNT10_11N 0x8d4 + + + +//PAGE 9 +#define ODM_REG_DBG_RPT_11N 0x908 +#define ODM_REG_BB_TX_PATH_11N 0x90c +#define ODM_REG_ANT_MAPPING1_11N 0x914 +#define ODM_REG_ANT_MAPPING2_11N 0x918 +#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948 + +//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_EDCCA_DCNF_11N 0xE24 +#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_TX_PATH_11N 0xF +#define ODM_BIT_BB_ATC_11N BIT11 + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.c new file mode 100644 index 00000000..8a4a273e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.c @@ -0,0 +1,1692 @@ +/****************************************************************************** + * + * 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]) + { + FillH2CCmd92C(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; + + /* check illegal channel and bandwidth */ + if (Is40MHz && ((cur_channel < 3) || (cur_channel > 12))) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_RXHP, ODM_DBG_LOUD, ("illegal channel setting, 40MHz channel = %d\n", cur_channel)); + return; + } + + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_rxhp.h new file mode 100644 index 00000000..a1fe97f1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_types.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_types.h new file mode 100644 index 00000000..459ca0b1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/phydm_types.h @@ -0,0 +1,259 @@ +/****************************************************************************** + * + * 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 Different SW team support*/ +#define ODM_AP 0x01 /*BIT0*/ +#define ODM_ADSL 0x02 +#define ODM_CE 0x04 /*BIT2*/ +#define ODM_WIN 0x08 /*BIT3*/ + +/*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_SYNC_IO_CNT_SPINLOCK = 43, + 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 + #define __func__ __FUNCTION__ + #define PHYDM_TESTCHIP_SUPPORT TESTCHIP_SUPPORT + #define bMaskH3Bytes 0xffffff00 + #define SUCCESS 0 + #define FAIL (-1) + +#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 + + #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 + + #if (defined(TESTCHIP_SUPPORT)) + #define PHYDM_TESTCHIP_SUPPORT 1 + #else + #define PHYDM_TESTCHIP_SUPPORT 0 + #endif + +#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 BT_30_SUPPORT 0*/ + #define FPGA_TWO_MAC_VERIFICATION 0 + #define RTL8881A_SUPPORT 0 + + #if (defined(TESTCHIP_SUPPORT)) + #define PHYDM_TESTCHIP_SUPPORT 1 + #else + #define PHYDM_TESTCHIP_SUPPORT 0 + #endif +#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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.c new file mode 100644 index 00000000..5f81e052 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.c @@ -0,0 +1,480 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ + +/****************************************************************************** + + History: + Data Who Remark (Internal History) + + 05/14/2012 MH Collect RTK inernal infromation and generate channel plan draft. + +******************************************************************************/ + +//============================================================ +// include files +//============================================================ +#include "mp_precomp.h" +#include "rtchnlplan.h" + + + +// +// Channel Plan Domain Code +// + +/* + Channel Plan Contents + Domain Code EEPROM Countries in Specific Domain + 2G RD 5G RD Bit[6:0] 2G 5G + Case Old Define 00h~1Fh Old Define Old Define + 1 2G_WORLD 5G_NULL 20h Worldwird 13 NA + 2 2G_ETSI1 5G_NULL 21h Europe 2G NA + 3 2G_FCC1 5G_NULL 22h US 2G NA + 4 2G_MKK1 5G_NULL 23h Japan 2G NA + 5 2G_ETSI2 5G_NULL 24h France 2G NA + 6 2G_FCC1 5G_FCC1 25h US 2G US 5G ¤K¤j°ê»{ÃÒ + 7 2G_WORLD 5G_ETSI1 26h Worldwird 13 Europe ¤K¤j°ê»{ÃÒ + 8 2G_MKK1 5G_MKK1 27h Japan 2G Japan 5G ¤K¤j°ê»{ÃÒ + 9 2G_WORLD 5G_KCC1 28h Worldwird 13 Korea ¤K¤j°ê»{ÃÒ + 10 2G_WORLD 5G_FCC2 29h Worldwird 13 US o/w DFS Channels + 11 2G_WORLD 5G_FCC3 30h Worldwird 13 India, Mexico + 12 2G_WORLD 5G_FCC4 31h Worldwird 13 Venezuela + 13 2G_WORLD 5G_FCC5 32h Worldwird 13 China + 14 2G_WORLD 5G_FCC6 33h Worldwird 13 Israel + 15 2G_FCC1 5G_FCC7 34h US 2G US/Canada ¤K¤j°ê»{ÃÒ + 16 2G_WORLD 5G_ETSI2 35h Worldwird 13 Australia, New Zealand ¤K¤j°ê»{ÃÒ + 17 2G_WORLD 5G_ETSI3 36h Worldwird 13 Russia + 18 2G_MKK1 5G_MKK2 37h Japan 2G Japan (W52, W53) + 19 2G_MKK1 5G_MKK3 38h Japan 2G Japan (W56) + 20 2G_FCC1 5G_NCC1 39h US 2G Taiwan ¤K¤j°ê»{ÃÒ + + NA 2G_WORLD 5G_FCC1 7F FCC FCC DFS Channels Realtek Define + + + + + + 2.4G Regulatory Domains + Case 2G RD Regulation Channels Frequencyes Note Countries in Specific Domain + 1 2G_WORLD ETSI 1~13 2412~2472 Passive scan CH 12, 13 Worldwird 13 + 2 2G_ETSI1 ETSI 1~13 2412~2472 Europe + 3 2G_FCC1 FCC 1~11 2412~2462 US + 4 2G_MKK1 MKK 1~13, 14 2412~2472, 2484 Japan + 5 2G_ETSI2 ETSI 10~13 2457~2472 France + + + + + 5G Regulatory Domains + Case 5G RD Regulation Channels Frequencyes Note Countries in Specific Domain + 1 5G_NULL NA NA NA Do not support 5GHz + 2 5G_ETSI1 ETSI "36~48, 52~64, + 100~140" "5180~5240, 5260~5230 + 5500~5700" Band1, Ban2, Band3 Europe + 3 5G_ETSI2 ETSI "36~48, 52~64, + 100~140, 149~165" "5180~5240, 5260~5230 + 5500~5700, 5745~5825" Band1, Ban2, Band3, Band4 Australia, New Zealand + 4 5G_ETSI3 ETSI "36~48, 52~64, + 100~132, 149~165" + "5180~5240, 5260~5230 + 5500~5660, 5745~5825" Band1, Ban2, Band3(except CH 136, 140), Band4" Russia + 5 5G_FCC1 FCC "36~48, 52~64, + 100~140, 149~165" + "5180~5240, 5260~5230 + 5500~5700, 5745~5825" Band1(5150~5250MHz), + Band2(5250~5350MHz), + Band3(5470~5725MHz), + Band4(5725~5850MHz)" US + 6 5G_FCC2 FCC 36~48, 149~165 5180~5240, 5745~5825 Band1, Band4 FCC o/w DFS Channels + 7 5G_FCC3 FCC "36~48, 52~64, + 149~165" "5180~5240, 5260~5230 + 5745~5825" Band1, Ban2, Band4 India, Mexico + 8 5G_FCC4 FCC "36~48, 52~64, + 149~161" "5180~5240, 5260~5230 + 5745~5805" Band1, Ban2, + Band4(except CH 165)" Venezuela + 9 5G_FCC5 FCC 149~165 5745~5825 Band4 China + 10 5G_FCC6 FCC 36~48, 52~64 5180~5240, 5260~5230 Band1, Band2 Israel + 11 5G_FCC7 + 5G_IC1 FCC + IC" "36~48, 52~64, + 100~116, 136, 140, + 149~165" "5180~5240, 5260~5230 + 5500~5580, 5680, 5700, + 5745~5825" "Band1, Band2, + Band3(except 5600~5650MHz), + Band4" "US + Canada" + 12 5G_KCC1 KCC "36~48, 52~64, + 100~124, 149~165" "5180~5240, 5260~5230 + 5500~5620, 5745~5825" "Band1, Ban2, + Band3(5470~5650MHz), + Band4" Korea + 13 5G_MKK1 MKK "36~48, 52~64, + 100~140" "5180~5240, 5260~5230 + 5500~5700" W52, W53, W56 Japan + 14 5G_MKK2 MKK 36~48, 52~64 5180~5240, 5260~5230 W52, W53 Japan (W52, W53) + 15 5G_MKK3 MKK 100~140 5500~5700 W56 Japan (W56) + 16 5G_NCC1 NCC "56~64, + 100~116, 136, 140, + 149~165" "5260~5320 + 5500~5580, 5680, 5700, + 5745~5825" "Band2(except CH 52), + Band3(except 5600~5650MHz), + Band4" Taiwan + + +*/ + +// +// 2.4G CHannel +// +/* + + 2.4G Band Regulatory Domains RTL8192D + Channel Number Channel Frequency US Canada Europe Spain France Japan Japan 20M 40M + (MHz) (FCC) (IC) (ETSI) (MPHPT) + 1 2412 v v v v v + 2 2417 v v v v v + 3 2422 v v v v v v + 4 2427 v v v v v v + 5 2432 v v v v v v + 6 2437 v v v v v v + 7 2442 v v v v v v + 8 2447 v v v v v v + 9 2452 v v v v v v + 10 2457 v v v v v v v v + 11 2462 v v v v v v v v + 12 2467 v v v v v + 13 2472 v v v v + 14 2484 v v + + +*/ + + +// +// 5G Operating Channel +// +/* + + 5G Band RTL8192D RTL8195 (Jaguar) Jaguar 2 Regulatory Domains + Channel Number Channel Frequency Global Global Global "US +(FCC 15.407)" "Canada +(FCC, except 5.6~5.65GHz)" Argentina, Australia, New Zealand, Brazil, S. Africa (FCC/ETSI) "Europe +(CE 301 893)" China India, Mexico, Singapore Israel, Turkey "Japan +(MIC Item 19-3, 19-3-2)" Korea Russia, Ukraine "Taiwan +(NCC)" Venezuela + (MHz) (20MHz) (20MHz) (40MHz) (80MHz) (160MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) (20MHz) +"Band 1 +5.15GHz +~ +5.25GHz" 36 5180 v v v v v Indoor Indoor v Indoor v Indoor Indoor v v v + 40 5200 v v v Indoor Indoor v Indoor v Indoor Indoor v v v + 44 5220 v v v v Indoor Indoor v Indoor v Indoor Indoor v v v + 48 5240 v v v Indoor Indoor v Indoor v Indoor Indoor v v v +"Band 2 +5.25GHz +~ +5.35GHz +(DFS)" 52 5260 v v v v v v v v Indoor v Indoor Indoor v v v + 56 5280 v v v v v v Indoor v Indoor Indoor v v Indoor v + 60 5300 v v v v v v v Indoor v Indoor Indoor v v Indoor v + 64 5320 v v v v v v Indoor v Indoor Indoor v v Indoor v + +"Band 3 +5.47GHz +~ +5.725GHz +(DFS)" 100 5500 v v v v v v v v v v v v v + 104 5520 v v v v v v v v v v v + 108 5540 v v v v v v v v v v v v + 112 5560 v v v v v v v v v v v + 116 5580 v v v v v v v v v v v v v + 120 5600 v v v Indoor v Indoor v v v + 124 5620 v v v v Indoor v Indoor v v v + 128 5640 v v v Indoor v Indoor v v + 132 5660 v v v E v Indoor v Indoor v v + 136 5680 v v v v v v v v v + 140 5700 v v E v v v v v v v + 144 5720 E E E +"Band 4 +5.725GHz +~ +5.85GHz +(~5.9GHz)" 149 5745 v v v v v v v v v v v v v v + 153 5765 v v v v v v v v v v v v + 157 5785 v v v v v v v v v v v v v + 161 5805 v v v v v v v v v v v v + 165 5825 v v P P v v v v v v v v v + 169 5845 P P P + 173 5865 P P P P + 177 5885 P P P +Channel Count 28 28 14 7 0 28 24 20 24 19 5 13 8 19 20 22 15 12 + E: FCC accepted the ask for CH144 from Accord. PS: 160MHz ¥Î 80MHz+80MHz¹ê²{¡H Argentina Belgium (¤ñ§Q®É) India Israel Russia + P: Customer's requirement from James. Australia The Netherlands (²üÄõ) Mexico Turkey Ukraine + New Zealand UK (­^°ê) Singapore + Brazil Switzerland (·ç¤h) + + +*/ + +/*---------------------------Define Local Constant---------------------------*/ + + +// define Maximum Power v.s each band for each region +// ISRAEL +// Format: +// RT_CHANNEL_DOMAIN_Region ={{{Chnl_Start, Chnl_end, Pwr_dB_Max}, {Chn2_Start, Chn2_end, Pwr_dB_Max}, {Chn3_Start, Chn3_end, Pwr_dB_Max}, {Chn4_Start, Chn4_end, Pwr_dB_Max}, {Chn5_Start, Chn5_end, Pwr_dB_Max}}, Limit_Num} */ +// RT_CHANNEL_DOMAIN_FCC ={{{01,11,30}, {36,48,17}, {52,64,24}, {100,140,24}, {149,165,30}}, 5} +// "NR" is non-release channle. +// Issue--- Israel--Russia--New Zealand +// DOMAIN_01= (2G_WORLD, 5G_NULL) +// DOMAIN_02= (2G_ETSI1, 5G_NULL) +// DOMAIN_03= (2G_FCC1, 5G_NULL) +// DOMAIN_04= (2G_MKK1, 5G_NULL) +// DOMAIN_05= (2G_ETSI2, 5G_NULL) +// DOMAIN_06= (2G_FCC1, 5G_FCC1) +// DOMAIN_07= (2G_WORLD, 5G_ETSI1) +// DOMAIN_08= (2G_MKK1, 5G_MKK1) +// DOMAIN_09= (2G_WORLD, 5G_KCC1) +// DOMAIN_10= (2G_WORLD, 5G_FCC2) +// DOMAIN_11= (2G_WORLD, 5G_FCC3)----india +// DOMAIN_12= (2G_WORLD, 5G_FCC4)----Venezuela +// DOMAIN_13= (2G_WORLD, 5G_FCC5)----China +// DOMAIN_14= (2G_WORLD, 5G_FCC6)----Israel +// DOMAIN_15= (2G_FCC1, 5G_FCC7)-----Canada +// DOMAIN_16= (2G_WORLD, 5G_ETSI2)---Australia +// DOMAIN_17= (2G_WORLD, 5G_ETSI3)---Russia +// DOMAIN_18= (2G_MKK1, 5G_MKK2)-----Japan +// DOMAIN_19= (2G_MKK1, 5G_MKK3)-----Japan +// DOMAIN_20= (2G_FCC1, 5G_NCC1)-----Taiwan +// DOMAIN_21= (2G_FCC1, 5G_NCC1)-----Taiwan + + +static RT_CHANNEL_PLAN_MAXPWR ChnlPlanPwrMax_2G[] = { + + // 2G_WORLD, + {{1, 13, 20}, 1}, + + // 2G_ETSI1 + {{1, 13, 20}, 1}, + + /* RT_CHANNEL_DOMAIN_ETSI */ + {{{1, 11, 17}, {40, 56, 17}, {60, 128, 17}, {0, 0, 0}, {149, 165, 17}}, 4}, + + // RT_CHANNEL_DOMAIN_MKK + {{{1, 11, 17}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 1}, + + // Add new channel plan mex power table. + // ...... + }; + + +/* +//===========================================1:(2G_WORLD, 5G_NULL) + +RT_CHANNEL_PLAN_MAXPWR RT_DOMAIN_01 ={{{01,13,20}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}}, 1} + +//===========================================2:(2G_ETSI1, 5G_NULL) + +RT_DOMAIN_02 ={{{01,13,20}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}}, 1} + +//===========================================3:(2G_FCC1, 5G_NULL) + +RT_DOMAIN_03 ={{{01,11,30}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}}, 1} + +//===========================================4:(2G_MKK1, 5G_NULL) + +RT_DOMAIN_04 ={{{01,14,23}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}}, 1} + +//===========================================5:(2G_ETSI2, 5G_NULL) + +RT_DOMAIN_05 ={{{10,13,20}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}}, 1} + +//===========================================6:(2G_FCC1, 5G_FCC1) + +RT_DOMAIN_06 ={{{01,13,30}, {36,48,17}, {52,64,24}, {100,140,24}, {149,165,30}}, 5} + +//===========================================7:(2G_WORLD, 5G_ETSI1) + +RT_DOMAIN_07 ={{{01,13,20}, {36,48,23}, {52,64,23}, {100,140,30}, {NR,NR,0}}, 4} + +//===========================================8:(2G_MKK1, 5G_MKK1) + +RT_DOMAIN_08 ={{{01,14,23}, {36,48,23}, {52,64,23}, {100,140,23}, {NR,NR,0}}, 4} + +//===========================================9:(2G_WORLD, 5G_KCC1) + +RT_DOMAIN_09 ={{{01,13,20}, {36,48,17}, {52,64,23}, {100,124,23}, {149,165,23}}, 5} + +//===========================================10:(2G_WORLD, 5G_FCC2) + +RT_DOMAIN_10 ={{{01,13,20}, {36,48,17}, {NR,NR,0}, {NR,NR,0}, {149,165,30}}, 3} + +//===========================================11:(2G_WORLD, 5G_FCC3) +RT_DOMAIN_11 ={{{01,13,20}, {36,48,23}, {52,64,23}, {NR,NR,0}, {149,165,23}}, 4} + +//===========================================12:(2G_WORLD, 5G_FCC4) +RT_DOMAIN_12 ={{{01,13,20}, {36,48,24}, {52,64,24}, {NR,NR,0}, {149,161,27}}, 4} + +//===========================================13:(2G_WORLD, 5G_FCC5) +RT_DOMAIN_13 ={{{01,13,20}, {NR,NR,0}, {NR,NR,0}, {NR,NR,0}, {149,165,27}}, 2} + +//===========================================14:(2G_WORLD, 5G_FCC6) +RT_DOMAIN_14 ={{{01,13,20}, {36,48,17}, {52,64,17}, {NR,NR,0}, {NR,NR,0}}, 3} + +//===========================================15:(2G_FCC1, 5G_FCC7) +RT_DOMAIN_15 ={{{01,11,30}, {36,48,23}, {52,64,24}, {100,140,24}, {149,165,30}}, 5} + +//===========================================16:(2G_WORLD, 5G_ETSI2) +RT_DOMAIN_16 ={{{01,13,20}, {36,48,23}, {52,64,23}, {100,140,30}, {149,165,30}}, 5} + +//===========================================17:(2G_WORLD, 5G_ETSI3) +RT_DOMAIN_17 ={{{01,13,20}, {36,48,23}, {52,64,23}, {100,132,30}, {149,165,20}}, 5} + +//===========================================18:(2G_MKK1, 5G_MKK2) +RT_DOMAIN_18 ={{{01,14,23}, {36,48,23}, {52,64,23}, {NR,NR,0}, {NR,NR,0}}, 3} + +//===========================================19:(2G_MKK1, 5G_MKK3) +RT_DOMAIN_19 ={{{01,14,23}, {NR,NR,0}, {NR,NR,0}, {100,140,23}, {NR,NR,0}}, 2} + +//===========================================20:(2G_FCC1, 5G_NCC1) +RT_DOMAIN_20 ={{{01,11,30}, {NR,NR,0}, {56,64,23}, {100,140,24}, {149,165,30}}, 4} + +//===========================================21:(2G_FCC1, 5G_NCC2) +RT_DOMAIN_21 ={{{01,11,30}, {NR,NR,0}, {56,64,23}, {NR,NR,0}, {149,165,30}}, 3} + +//===========================================22:(2G_WORLD, 5G_FCC3) +RT_DOMAIN_22 ={{{01,13,24}, {36,48,20}, {52,64,24}, {NR,NR,0}, {149,165,30}}, 4} + +//===========================================23:(2G_WORLD, 5G_ETSI2) +RT_DOMAIN_23 ={{{01,13,20}, {36,48,23}, {52,64,23}, {100,140,30}, {149,165,30}}, 5} + +*/ + +// +// Counter & Realtek Channel plan transfer table. +// +RT_CHNL_CTRY_TBL RtCtryChnlTbl[] = +{ + + { + RT_CTRY_AL, // "Albaniaªüº¸¤Ú¥§¨È" + "AL", + RT_2G_WORLD, + RT_5G_WORLD, + RT_CHANNEL_DOMAIN_UNDEFINED // 2G/5G world. + }, +#if 0 + { + RT_CTRY_BB, // "Barbados¤Ú¤Ú¦h´µ" + "BB", + RT_2G_WORLD, + RT_5G_NULL, + RT_CHANNEL_DOMAIN_EFUSE_0x20 // 2G world. 5G_NULL + }, + + { + RT_CTRY_DE, // "Germany¼w°ê" + "DE", + RT_2G_WORLD, + RT_5G_ETSI1, + RT_CHANNEL_DOMAIN_EFUSE_0x26 + }, + + { + RT_CTRY_US, // "Germany¼w°ê" + "US", + RT_2G_FCC1, + RT_5G_FCC7, + RT_CHANNEL_DOMAIN_EFUSE_0x34 + }, + + { + RT_CTRY_JP, // "Germany¼w°ê" + "JP", + RT_2G_MKK1, + RT_5G_MKK1, + RT_CHANNEL_DOMAIN_EFUSE_0x34 + }, + + { + RT_CTRY_TW, // "Germany¼w°ê" + "TW", + RT_2G_FCC1, + RT_5G_NCC1, + RT_CHANNEL_DOMAIN_EFUSE_0x39 + }, +#endif + +}; // RtCtryChnlTbl + +// +// Realtek Defined Channel plan. +// +#if 0 + +static RT_CHANNEL_PLAN_NEW RtChnlPlan[] = +{ + // Channel Plan 0x20. + { + &RtCtryChnlTbl[1], // RT_CHNL_CTRY_TBL Country & channel plan transfer table. + RT_CHANNEL_DOMAIN_EFUSE_0x20, // RT_CHANNEL_DOMAIN RT Channel Plan Define + RT_2G_WORLD, // RT_REGULATION_2G + RT_5G_NULL, // RT_REGULATION_5G + RT_WORLD, // RT_REGULATION_CMN RT Regulatory domain definition. + RT_SREQ_NA, // RT Channel plan special & customerize requirement. + + CHNL_RT_2G_WORLD, + CHNL_RT_2G_WORLD_SCAN_TYPE, + &ChnlPlanPwrMax_2G[0], + + CHNL_RT_5G_NULL, + CHNL_RT_5G_NULL_SCAN_TYPE, + + + }, + + // Channel Plan 0x26. + { + &RtCtryChnlTbl[1], // RT_CHNL_CTRY_TBL Country & channel plan transfer table. + RT_CHANNEL_DOMAIN_EFUSE_0x26, // RT_CHANNEL_DOMAIN RT Channel Plan Define + RT_2G_WORLD, // RT_REGULATION_2G + RT_5G_ETSI1, // RT_REGULATION_5G + RT_WORLD, // RT_REGULATION_CMN RT Regulatory domain definition. + RT_SREQ_NA, // RT Channel plan special & customerize requirement. + + CHNL_RT_2G_WORLD, // 2G workd cannel + CHNL_RT_2G_WORLD_SCAN_TYPE, + &ChnlPlanPwrMax_2G[1], + + CHNL_RT_5G_ETSI1, + CHNL_RT_5G_ETSI1_SCAN_TYPE, + + } + + +}; +#endif + + + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.h new file mode 100644 index 00000000..37786cf8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtchnlplan.h @@ -0,0 +1,699 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RT_CHANNELPLAN_H__ +#define __RT_CHANNELPLAN_H__ + +typedef enum _RT_CHANNEL_DOMAIN_NEW +{ + + //===== Add new channel plan above this line ===============// + + // For new architecture we define different 2G/5G CH area for all country. + // 2.4 G only + RT_CHANNEL_DOMAIN_2G_WORLD_5G_NULL = 0x20, + RT_CHANNEL_DOMAIN_2G_ETSI1_5G_NULL = 0x21, + RT_CHANNEL_DOMAIN_2G_FCC1_5G_NULL = 0x22, + RT_CHANNEL_DOMAIN_2G_MKK1_5G_NULL = 0x23, + RT_CHANNEL_DOMAIN_2G_ETSI2_5G_NULL = 0x24, + // 2.4 G + 5G type 1 + RT_CHANNEL_DOMAIN_2G_FCC1_5G_FCC1 = 0x25, + RT_CHANNEL_DOMAIN_2G_WORLD_5G_ETSI1 = 0x26, + //RT_CHANNEL_DOMAIN_2G_WORLD_5G_ETSI1 = 0x27, + // ..... + + RT_CHANNEL_DOMAIN_MAX_NEW, + +}RT_CHANNEL_DOMAIN_NEW, *PRT_CHANNEL_DOMAIN_NEW; + + +#if 0 +#define DOMAIN_CODE_2G_WORLD \ + {1,2,3,4,5,6,7,8,9,10,11,12,13}, 13 +#define DOMAIN_CODE_2G_ETSI1 \ + {1,2,3,4,5,6,7,8,9,10,11,12,13}, 13 +#define DOMAIN_CODE_2G_ETSI2 \ + {1,2,3,4,5,6,7,8,9,10,11}, 11 +#define DOMAIN_CODE_2G_FCC1 \ + {1,2,3,4,5,6,7,8,9,10,11,12,13,14}, 14 +#define DOMAIN_CODE_2G_MKK1 \ + {10,11,12,13}, 4 + +#define DOMAIN_CODE_5G_ETSI1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}, 19 +#define DOMAIN_CODE_5G_ETSI2 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165}, 24 +#define DOMAIN_CODE_5G_ETSI3 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165}, 22 +#define DOMAIN_CODE_5G_FCC1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165}, 24 +#define DOMAIN_CODE_5G_FCC2 \ + {36,40,44,48,149,153,157,161,165}, 9 +#define DOMAIN_CODE_5G_FCC3 \ + {36,40,44,48,52,56,60,64,149,153,157,161,165}, 13 +#define DOMAIN_CODE_5G_FCC4 \ + {36,40,44,48,52,56,60,64,149,153,157,161}, 12 +#define DOMAIN_CODE_5G_FCC5 \ + {149,153,157,161,165}, 5 +#define DOMAIN_CODE_5G_FCC6 \ + {36,40,44,48,52,56,60,64}, 8 +#define DOMAIN_CODE_5G_FCC7 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define DOMAIN_CODE_5G_IC1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define DOMAIN_CODE_5G_KCC1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165}, 20 +#define DOMAIN_CODE_5G_MKK1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}, 19 +#define DOMAIN_CODE_5G_MKK2 \ + {36,40,44,48,52,56,60,64}, 8 +#define DOMAIN_CODE_5G_MKK3 \ + {100,104,108,112,116,120,124,128,132,136,140}, 11 +#define DOMAIN_CODE_5G_NCC1 \ + {56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 24 +#define DOMAIN_CODE_5G_NCC2 \ + {56,60,64,149,153,157,161,165}, 8 +#define UNDEFINED \ + {0}, 0 +#endif + +// +// +// +/* + +Countries "Country Abbreviation" Domain Code SKU's Ch# of 20MHz + 2G 5G Ch# of 40MHz +"Albaniaªüº¸¤Ú¥§¨È" AL Local Test + +"Algeriaªüº¸¤Î§Q¨È" DZ CE TCF + +"Antigua & Barbuda¦w´£¥Ê®q&¤Ú¥¬¹F" AG 2G_WORLD FCC TCF + +"Argentinaªü®Ú§Ê" AR 2G_WORLD Local Test + +"Armenia¨È¬ü¥§¨È" AM 2G_WORLD ETSI + +"Arubaªü¾|¤Ú®q" AW 2G_WORLD FCC TCF + +"Australia¿D¬w" AU 2G_WORLD 5G_ETSI2 + +"Austria¶ø¦a§Q" AT 2G_WORLD 5G_ETSI1 CE + +"Azerbaijanªü¶ë«ô¾Ê" AZ 2G_WORLD CE TCF + +"Bahamas¤Ú«¢°¨" BS 2G_WORLD + +"Barbados¤Ú¤Ú¦h´µ" BB 2G_WORLD FCC TCF + +"Belgium¤ñ§Q®É" BE 2G_WORLD 5G_ETSI1 CE + +"Bermuda¦Ê¼}¹F" BM 2G_WORLD FCC TCF + +"Brazil¤Ú¦è" BR 2G_WORLD Local Test + +"Bulgaria«O¥[§Q¨È" BG 2G_WORLD 5G_ETSI1 CE + +"Canada¥[®³¤j" CA 2G_FCC1 5G_FCC7 IC / FCC IC / FCC + +"Cayman Islands¶}°Ò¸s®q" KY 2G_WORLD 5G_ETSI1 CE + +"Chile´¼§Q" CL 2G_WORLD FCC TCF + +"China¤¤°ê" CN 2G_WORLD 5G_FCC5 «H³¡?¡i2002¡j353? + +"Columbia­ô­Û¤ñ¨È" CO 2G_WORLD Voluntary + +"Costa Rica­ô´µ¹F¾¤¥[" CR 2G_WORLD FCC TCF + +"Cyprus¶ë®ú¸ô´µ" CY 2G_WORLD 5G_ETSI1 CE + +"Czech ±¶§J" CZ 2G_WORLD 5G_ETSI1 CE + +"Denmark¤¦³Á" DK 2G_WORLD 5G_ETSI1 CE + +"Dominican Republic¦h©ú¥§¥[¦@©M°ê" DO 2G_WORLD FCC TCF + +"Egypt®J¤Î" EG 2G_WORLD CE T CF + +"El SalvadorÂĺ¸¥Ë¦h" SV 2G_WORLD Voluntary + +"Estonia·R¨F¥§¨È" EE 2G_WORLD 5G_ETSI1 CE + +"FinlandªâÄõ" FI 2G_WORLD 5G_ETSI1 CE + +"Franceªk°ê" FR 5G_E TSI1 CE + +"Germany¼w°ê" DE 2G_WORLD 5G_ETSI1 CE + +"Greece §Æþ" GR 2G_WORLD 5G_ETSI1 CE + +"GuamÃö®q" GU 2G_WORLD + +"Guatemala¥Ê¦a°¨©Ô" GT 2G_WORLD + +"Haiti®ü¦a" HT 2G_WORLD FCC TCF + +"Honduras§»³£©Ô´µ" HN 2G_WORLD FCC TCF + +"Hungary¦I¤ú§Q" HU 2G_WORLD 5G_ETSI1 CE + +"Iceland¦B®q" IS 2G_WORLD 5G_ETSI1 CE + +"India¦L«×" IN 2G_WORLD 5G_FCC3 FCC/CE TCF + +"Ireland·Rº¸Äõ" IE 2G_WORLD 5G_ETSI1 CE + +"Israel¥H¦â¦C" IL 5G_F CC6 CE TCF + +"Italy¸q¤j§Q" IT 2G_WORLD 5G_ETSI1 CE + +"Japan¤é¥»" JP 2G_MKK1 5G_MKK1 MKK MKK + +"KoreaÁú°ê" KR 2G_WORLD 5G_KCC1 KCC KCC + +"Latvia©Ô²æºû¨È" LV 2G_WORLD 5G_ETSI1 CE + +"Lithuania¥ß³³©{" LT 2G_WORLD 5G_ETSI1 CE + +"Luxembourg¿c´Ë³ù" LU 2G_WORLD 5G_ETSI1 CE + +"Malaysia°¨¨Ó¦è¨È" MY 2G_WORLD Local Test + +"Malta°¨º¸¥L" MT 2G_WORLD 5G_ETSI1 CE + +"Mexico¾¥¦è­ô" MX 2G_WORLD 5G_FCC3 Local Test + +"Morocco¼¯¬¥­ô" MA CE TCF + +"Netherlands²üÄõ" NL 2G_WORLD 5G_ETSI1 CE + +"New Zealand¯Ã¦èÄõ" NZ 2G_WORLD 5G_ETSI2 + +"Norway®¿«Â" NO 2G_WORLD 5G_ETSI1 CE + +"Panama¤Ú®³°¨ " PA 2G_FCC1 Voluntary + +"Philippinesµá«ß»«" PH 2G_WORLD FCC TCF + +"PolandªiÄõ" PL 2G_WORLD 5G_ETSI1 CE + +"Portugal¸²µå¤ú" PT 2G_WORLD 5G_ETSI1 CE + +"Romaniaù°¨¥§¨È" RO 2G_WORLD 5G_ETSI1 CE + +"Russia«Xù´µ" RU 2G_WORLD 5G_ETSI3 CE TCF + +"Saudi Arabia¨F¦aªü©Ô§B" SA 2G_WORLD CE TCF + +"Singapore·s¥[©Y" SG 2G_WORLD + +"Slovakia´µ¬¥¥ï§J" SK 2G_WORLD 5G_ETSI1 CE + +"Slovenia´µ¬¥ºû¥§¨È" SI 2G_WORLD 5G_ETSI1 CE + +"South Africa«n«D" ZA 2G_WORLD CE TCF + +"Spain¦è¯Z¤ú" ES 5G_ETSI1 CE + +"Sweden·ç¨å" SE 2G_WORLD 5G_ETSI1 CE + +"Switzerland·ç¤h" CH 2G_WORLD 5G_ETSI1 CE + +"Taiwan»OÆW" TW 2G_FCC1 5G_NCC1 NCC + +"Thailand®õ°ê" TH 2G_WORLD FCC/CE TCF + +"Turkey¤g¦Õ¨ä" TR 2G_WORLD + +"Ukraine¯Q§JÄõ" UA 2G_WORLD Local Test + +"United Kingdom­^°ê" GB 2G_WORLD 5G_ETSI1 CE ETSI + +"United States¬ü°ê" US 2G_FCC1 5G_FCC7 FCC FCC + +"Venezuela©e¤º·ç©Ô" VE 2G_WORLD 5G_FCC4 FCC TCF + +"Vietnam¶V«n" VN 2G_WORLD FCC/CE TCF + + + +*/ + +// Counter abbervation. +typedef enum _RT_COUNTRY_DEFINE_NUM +{ + RT_CTRY_AL, // "Albaniaªüº¸¤Ú¥§¨È" + RT_CTRY_DZ, // "Algeriaªüº¸¤Î§Q¨È" + RT_CTRY_AG, // "Antigua & Barbuda¦w´£¥Ê®q&¤Ú¥¬¹F" + RT_CTRY_AR, // "Argentinaªü®Ú§Ê" + RT_CTRY_AM, // "Armenia¨È¬ü¥§¨È" + RT_CTRY_AW, // "Arubaªü¾|¤Ú®q" + RT_CTRY_AU, // "Australia¿D¬w" + RT_CTRY_AT, // "Austria¶ø¦a§Q" + RT_CTRY_AZ, // "Azerbaijanªü¶ë«ô¾Ê" + RT_CTRY_BS, // "Bahamas¤Ú«¢°¨" + RT_CTRY_BB, // "Barbados¤Ú¤Ú¦h´µ" + RT_CTRY_BE, // "Belgium¤ñ§Q®É" + RT_CTRY_BM, // "Bermuda¦Ê¼}¹F" + RT_CTRY_BR, // "Brazil¤Ú¦è" + RT_CTRY_BG, // "Bulgaria«O¥[§Q¨È" + RT_CTRY_CA, // "Canada¥[®³¤j" + RT_CTRY_KY, // "Cayman Islands¶}°Ò¸s®q" + RT_CTRY_CL, // "Chile´¼§Q" + RT_CTRY_CN, // "China¤¤°ê" + RT_CTRY_CO, // "Columbia­ô­Û¤ñ¨È" + RT_CTRY_CR, // "Costa Rica­ô´µ¹F¾¤¥[" + RT_CTRY_CY, // "Cyprus¶ë®ú¸ô´µ" + RT_CTRY_CZ, // "Czech ±¶§J" + RT_CTRY_DK, // "Denmark¤¦³Á" + RT_CTRY_DO, // "Dominican Republic¦h©ú¥§¥[¦@©M°ê" + RT_CTRY_CE, // "Egypt®J¤Î" EG 2G_WORLD + RT_CTRY_SV, // "El SalvadorÂĺ¸¥Ë¦h" + RT_CTRY_EE, // "Estonia·R¨F¥§¨È" + RT_CTRY_FI, // "FinlandªâÄõ" + RT_CTRY_FR, // "Franceªk°ê" + RT_CTRY_DE, // "Germany¼w°ê" + RT_CTRY_GR, // "Greece §Æþ" + RT_CTRY_GU, // "GuamÃö®q" + RT_CTRY_GT, // "Guatemala¥Ê¦a°¨©Ô" + RT_CTRY_HT, // "Haiti®ü¦a" + RT_CTRY_HN, // "Honduras§»³£©Ô´µ" + RT_CTRY_HU, // "Hungary¦I¤ú§Q" + RT_CTRY_IS, // "Iceland¦B®q" + RT_CTRY_IN, // "India¦L«×" + RT_CTRY_IE, // "Ireland·Rº¸Äõ" + RT_CTRY_IL, // "Israel¥H¦â¦C" + RT_CTRY_IT, // "Italy¸q¤j§Q" + RT_CTRY_JP, // "Japan¤é¥»" + RT_CTRY_KR, // "KoreaÁú°ê" + RT_CTRY_LV, // "Latvia©Ô²æºû¨È" + RT_CTRY_LT, // "Lithuania¥ß³³©{" + RT_CTRY_LU, // "Luxembourg¿c´Ë³ù" + RT_CTRY_MY, // "Malaysia°¨¨Ó¦è¨È" + RT_CTRY_MT, // "Malta°¨º¸¥L" + RT_CTRY_MX, // "Mexico¾¥¦è­ô" + RT_CTRY_MA, // "Morocco¼¯¬¥­ô" + RT_CTRY_NL, // "Netherlands²üÄõ" + RT_CTRY_NZ, // "New Zealand¯Ã¦èÄõ" + RT_CTRY_NO, // "Norway®¿«Â" + RT_CTRY_PA, // "Panama¤Ú®³°¨ " + RT_CTRY_PH, // "Philippinesµá«ß»«" + RT_CTRY_PL, // "PolandªiÄõ" + RT_CTRY_PT, // "Portugal¸²µå¤ú" + RT_CTRY_RO, // "Romaniaù°¨¥§¨È" + RT_CTRY_RU, // "Russia«Xù´µ" + RT_CTRY_SA, // "Saudi Arabia¨F¦aªü©Ô§B" + RT_CTRY_SG, // "Singapore·s¥[©Y" + RT_CTRY_SK, // "Slovakia´µ¬¥¥ï§J" + RT_CTRY_SI, // "Slovenia´µ¬¥ºû¥§¨È" + RT_CTRY_ZA, // "South Africa«n«D" + RT_CTRY_ES, // "Spain¦è¯Z¤ú" + RT_CTRY_SE, // "Sweden·ç¨å" + RT_CTRY_CH, // "Switzerland·ç¤h" + RT_CTRY_TW, // "Taiwan»OÆW" + RT_CTRY_TH, // "Thailand®õ°ê" + RT_CTRY_TR, // "Turkey¤g¦Õ¨ä" + RT_CTRY_UA, // "Ukraine¯Q§JÄõ" + RT_CTRY_GB, // "United Kingdom­^°ê" + RT_CTRY_US, // "United States¬ü°ê" + RT_CTRY_VE, // "Venezuela©e¤º·ç©Ô" + RT_CTRY_VN, // "Vietnam¶V«n" + RT_CTRY_MAX, // + +}RT_COUNTRY_NAME, *PRT_COUNTRY_NAME; + +// Scan type including active and passive scan. +typedef enum _RT_SCAN_TYPE_NEW +{ + SCAN_NULL, + SCAN_ACT, + SCAN_PAS, + SCAN_BOTH, +}RT_SCAN_TYPE_NEW, *PRT_SCAN_TYPE_NEW; + + +// Power table sample. + +typedef struct _RT_CHNL_PLAN_LIMIT +{ + u2Byte Chnl_Start; + u2Byte Chnl_end; + + u2Byte Freq_Start; + u2Byte Freq_end; +}RT_CHNL_PLAN_LIMIT, *PRT_CHNL_PLAN_LIMIT; + + +// +// 2.4G Regulatory Domains +// +typedef enum _RT_REGULATION_DOMAIN_2G +{ + RT_2G_NULL, + RT_2G_WORLD, + RT_2G_ETSI1, + RT_2G_FCC1, + RT_2G_MKK1, + RT_2G_ETSI2 + +}RT_REGULATION_2G, *PRT_REGULATION_2G; + + +//typedef struct _RT_CHANNEL_BEHAVIOR +//{ +// u1Byte Chnl; +// RT_SCAN_TYPE_NEW +// +//}RT_CHANNEL_BEHAVIOR, *PRT_CHANNEL_BEHAVIOR; + +//typedef struct _RT_CHANNEL_PLAN_TYPE +//{ +// RT_CHANNEL_BEHAVIOR +// u1Byte Chnl_num; +//}RT_CHNL_PLAN_TYPE, *PRT_CHNL_PLAN_TYPE; + +// +// 2.4G Channel Number +// Channel definition & number +// +#define CHNL_RT_2G_NULL \ + {0}, 0 +#define CHNL_RT_2G_WORLD \ + {1,2,3,4,5,6,7,8,9,10,11,12,13}, 13 +#define CHNL_RT_2G_WORLD_TEST \ + {1,2,3,4,5,6,7,8,9,10,11,12,13}, 13 + +#define CHNL_RT_2G_EFSI1 \ + {1,2,3,4,5,6,7,8,9,10,11,12,13}, 13 +#define CHNL_RT_2G_FCC1 \ + {1,2,3,4,5,6,7,8,9,10,11}, 11 +#define CHNL_RT_2G_MKK1 \ + {1,2,3,4,5,6,7,8,9,10,11,12,13,14}, 14 +#define CHNL_RT_2G_ETSI2 \ + {10,11,12,13}, 4 + +// +// 2.4G Channel Active or passive scan. +// +#define CHNL_RT_2G_NULL_SCAN_TYPE \ + {SCAN_NULL} +#define CHNL_RT_2G_WORLD_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1,0,0} +#define CHNL_RT_2G_EFSI1_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1,1,1} +#define CHNL_RT_2G_FCC1_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1} +#define CHNL_RT_2G_MKK1_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1,1,1,1} +#define CHNL_RT_2G_ETSI2_SCAN_TYPE \ + {1,1,1,1} + + +// +// 2.4G Band & Frequency Section +// Freqency start & end / band number +// +#define FREQ_RT_2G_NULL \ + {0}, 0 + // Passive scan CH 12, 13 +#define FREQ_RT_2G_WORLD \ + {2412, 2472}, 1 +#define FREQ_RT_2G_EFSI1 \ + {2412, 2472}, 1 +#define FREQ_RT_2G_FCC1 \ + {2412, 2462}, 1 +#define FREQ_RT_2G_MKK1 \ + {2412, 2484}, 1 +#define FREQ_RT_2G_ETSI2 \ + {2457, 2472}, 1 + + +// +// 5G Regulatory Domains +// +typedef enum _RT_REGULATION_DOMAIN_5G +{ + RT_5G_NULL, + RT_5G_WORLD, + RT_5G_ETSI1, + RT_5G_ETSI2, + RT_5G_ETSI3, + RT_5G_FCC1, + RT_5G_FCC2, + RT_5G_FCC3, + RT_5G_FCC4, + RT_5G_FCC5, + RT_5G_FCC6, + RT_5G_FCC7, + RT_5G_IC1, + RT_5G_KCC1, + RT_5G_MKK1, + RT_5G_MKK2, + RT_5G_MKK3, + RT_5G_NCC1, + +}RT_REGULATION_5G, *PRT_REGULATION_5G; + +// +// 5G Channel Number +// +#define CHNL_RT_5G_NULL \ + {0}, 0 +#define CHNL_RT_5G_WORLD \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}, 19 +#define CHNL_RT_5G_ETSI1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165}, 24 +#define CHNL_RT_5G_ETSI2 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165}, 22 +#define CHNL_RT_5G_ETSI3 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165}, 24 +#define CHNL_RT_5G_FCC1 \ + {36,40,44,48,149,153,157,161,165}, 9 +#define CHNL_RT_5G_FCC2 \ + {36,40,44,48,52,56,60,64,149,153,157,161,165}, 13 +#define CHNL_RT_5G_FCC3 \ + {36,40,44,48,52,56,60,64,149,153,157,161}, 12 +#define CHNL_RT_5G_FCC4 \ + {149,153,157,161,165}, 5 +#define CHNL_RT_5G_FCC5 \ + {36,40,44,48,52,56,60,64}, 8 +#define CHNL_RT_5G_FCC6 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define CHNL_RT_5G_FCC7 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define CHNL_RT_5G_IC1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165}, 20 +#define CHNL_RT_5G_KCC1 \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}, 19 +#define CHNL_RT_5G_MKK1 \ + {36,40,44,48,52,56,60,64}, 8 +#define CHNL_RT_5G_MKK2 \ + {100,104,108,112,116,120,124,128,132,136,140}, 11 +#define CHNL_RT_5G_MKK3 \ + {56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 24 +#define CHNL_RT_5G_NCC1 \ + {56,60,64,149,153,157,161,165}, 8 + +// +// 5G Channel Active or passive scan. +// +#define CHNL_RT_5G_NULL_SCAN_TYPE \ + {SCAN_NULL} +#define CHNL_RT_5G_WORLD_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} +#define CHNL_RT_5G_ETSI1_SCAN_TYPE \ + {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} +#define CHNL_RT_5G_ETSI2_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165}, 22 +#define CHNL_RT_5G_ETSI3_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165}, 24 +#define CHNL_RT_5G_FCC1_SCAN_TYPE \ + {36,40,44,48,149,153,157,161,165}, 9 +#define CHNL_RT_5G_FCC2_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,149,153,157,161,165}, 13 +#define CHNL_RT_5G_FCC3_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,149,153,157,161}, 12 +#define CHNL_RT_5G_FCC4_SCAN_TYPE \ + {149,153,157,161,165}, 5 +#define CHNL_RT_5G_FCC5_SCAN_TYPE \ + {36,40,44,48,52,56,60,64}, 8 +#define CHNL_RT_5G_FCC6_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define CHNL_RT_5G_FCC7_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 20 +#define CHNL_RT_5G_IC1_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165}, 20 +#define CHNL_RT_5G_KCC1_SCAN_TYPE \ + {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140}, 19 +#define CHNL_RT_5G_MKK1_SCAN_TYPE \ + {36,40,44,48,52,56,60,64}, 8 +#define CHNL_RT_5G_MKK2_SCAN_TYPE \ + {100,104,108,112,116,120,124,128,132,136,140}, 11 +#define CHNL_RT_5G_MKK3_SCAN_TYPE \ + {56,60,64,100,104,108,112,116,136,140,149,153,157,161,165}, 24 +#define CHNL_RT_5G_NCC1_SCAN_TYPE \ + {56,60,64,149,153,157,161,165}, 8 + +// +// Global Regulation +// +typedef enum _RT_REGULATION_COMMON +{ + RT_WORLD, + RT_FCC, + RT_MKK, + RT_ETSI, + RT_IC, + RT_CE, + RT_NCC, + +}RT_REGULATION_CMN, *PRT_REGULATION_CMN; + + + +// +// Special requirement for different regulation domain. +// For internal test or customerize special request. +// +typedef enum _RT_CHNLPLAN_SREQ +{ + RT_SREQ_NA = 0x0, + RT_SREQ_2G_ADHOC_11N = 0x00000001, + RT_SREQ_2G_ADHOC_11B = 0x00000002, + RT_SREQ_2G_ALL_PASS = 0x00000004, + RT_SREQ_2G_ALL_ACT = 0x00000008, + RT_SREQ_5G_ADHOC_11N = 0x00000010, + RT_SREQ_5G_ADHOC_11AC = 0x00000020, + RT_SREQ_5G_ALL_PASS = 0x00000040, + RT_SREQ_5G_ALL_ACT = 0x00000080, + RT_SREQ_C1_PLAN = 0x00000100, + RT_SREQ_C2_PLAN = 0x00000200, + RT_SREQ_C3_PLAN = 0x00000400, + RT_SREQ_C4_PLAN = 0x00000800, + RT_SREQ_NFC_ON = 0x00001000, + RT_SREQ_MASK = 0x0000FFFF, /* Requirements bit mask */ + +}RT_CHNLPLAN_SREQ, *PRT_CHNLPLAN_SREQ; + + +// +// RT_COUNTRY_NAME & RT_REGULATION_2G & RT_REGULATION_5G transfer table +// +// +typedef struct _RT_CHANNEL_PLAN_COUNTRY_TRANSFER_TABLE +{ + // + // Define countery domain and corresponding + // + RT_COUNTRY_NAME Country_Enum; + char Country_Name[3]; + + //char Domain_Name[12]; + RT_REGULATION_2G Domain_2G; + + RT_REGULATION_5G Domain_5G; + + RT_CHANNEL_DOMAIN RtChDomain; + //u1Byte Country_Area; + +}RT_CHNL_CTRY_TBL, *PRT_CHNL_CTRY_TBL; + + +#define RT_MAX_CHNL_NUM_2G 13 +#define RT_MAX_CHNL_NUM_5G 44 + +// Power table sample. + +typedef struct _RT_CHNL_PLAN_PWR_LIMIT +{ + u2Byte Chnl_Start; + u2Byte Chnl_end; + u1Byte dB_Max; + u2Byte mW_Max; +}RT_CHNL_PWR_LIMIT, *PRT_CHNL_PWR_LIMIT; + + +#define RT_MAX_BAND_NUM 5 + +typedef struct _RT_CHANNEL_PLAN_MAXPWR +{ +// STRING_T + RT_CHNL_PWR_LIMIT Chnl[RT_MAX_BAND_NUM]; + u1Byte Band_Useful_Num; + + +}RT_CHANNEL_PLAN_MAXPWR, *PRT_CHANNEL_PLAN_MAXPWR; + + +// +// Power By Rate Table. +// + + + +typedef struct _RT_CHANNEL_PLAN_NEW +{ + // + // Define countery domain and corresponding + // + //char Country_Name[36]; + //u1Byte Country_Enum; + + //char Domain_Name[12]; + + + PRT_CHNL_CTRY_TBL pCtryTransfer; + + RT_CHANNEL_DOMAIN RtChDomain; + + RT_REGULATION_2G Domain_2G; + + RT_REGULATION_5G Domain_5G; + + RT_REGULATION_CMN Regulator; + + RT_CHNLPLAN_SREQ ChnlSreq; + + //RT_CHNL_PLAN_LIMIT RtChnl; + + u1Byte Chnl2G[MAX_CHANNEL_NUM]; // CHNL_RT_2G_WORLD + u1Byte Len2G; + u1Byte Chnl2GScanTp[MAX_CHANNEL_NUM]; // CHNL_RT_2G_WORLD_SCAN_TYPE + //u1Byte Freq2G[2]; // FREQ_RT_2G_WORLD + + u1Byte Chnl5G[MAX_CHANNEL_NUM]; + u1Byte Len5G; + u1Byte Chnl5GScanTp[MAX_CHANNEL_NUM]; + //u1Byte Freq2G[2]; // FREQ_RT_2G_WORLD + + RT_CHANNEL_PLAN_MAXPWR ChnlMaxPwr; + + +}RT_CHANNEL_PLAN_NEW, *PRT_CHANNEL_PLAN_NEW; + + +#endif // __RT_CHANNELPLAN_H__ + + + + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/hal8188freg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/hal8188freg.h new file mode 100644 index 00000000..40b1a0a4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/hal8188freg.h @@ -0,0 +1,862 @@ +/***************************************************************************** + * Copyright(c) 2009, RealTEK Technology Inc. All Right Reserved. + * + * Module: __INC_HAL8188FREG_H + * + * + * Note: 1. Define Mac register address and corresponding bit mask map + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * + *****************************************************************************/ +#ifndef __INC_HAL8188FREG_H +#define __INC_HAL8188FREG_H + + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL_8188F 0x0000 // 2 Byte +#define REG_SYS_FUNC_EN_8188F 0x0002 // 2 Byte +#define REG_APS_FSMCO_8188F 0x0004 // 4 Byte +#define REG_SYS_CLKR_8188F 0x0008 // 2 Byte +#define REG_9346CR_8188F 0x000A // 2 Byte +#define REG_EE_VPD_8188F 0x000C // 2 Byte +#define REG_AFE_MISC_8188F 0x0010 // 1 Byte +#define REG_SPS0_CTRL_8188F 0x0011 // 7 Byte +#define REG_SPS_OCP_CFG_8188F 0x0018 // 4 Byte +#define REG_RSV_CTRL_8188F 0x001C // 3 Byte +#define REG_RF_CTRL_8188F 0x001F // 1 Byte +#define REG_LPLDO_CTRL_8188F 0x0023 // 1 Byte +#define REG_AFE_XTAL_CTRL_8188F 0x0024 // 4 Byte +#define REG_AFE_PLL_CTRL_8188F 0x0028 // 4 Byte +#define REG_MAC_PLL_CTRL_EXT_8188F 0x002c // 4 Byte +#define REG_EFUSE_CTRL_8188F 0x0030 +#define REG_EFUSE_TEST_8188F 0x0034 +#define REG_PWR_DATA_8188F 0x0038 +#define REG_CAL_TIMER_8188F 0x003C +#define REG_ACLK_MON_8188F 0x003E +#define REG_GPIO_MUXCFG_8188F 0x0040 +#define REG_GPIO_IO_SEL_8188F 0x0042 +#define REG_MAC_PINMUX_CFG_8188F 0x0043 +#define REG_GPIO_PIN_CTRL_8188F 0x0044 +#define REG_GPIO_INTM_8188F 0x0048 +#define REG_LEDCFG0_8188F 0x004C +#define REG_LEDCFG1_8188F 0x004D +#define REG_LEDCFG2_8188F 0x004E +#define REG_LEDCFG3_8188F 0x004F +#define REG_FSIMR_8188F 0x0050 +#define REG_FSISR_8188F 0x0054 +#define REG_HSIMR_8188F 0x0058 +#define REG_HSISR_8188F 0x005c +#define REG_GPIO_EXT_CTRL 0x0060 +#define REG_MULTI_FUNC_CTRL_8188F 0x0068 +#define REG_GPIO_STATUS_8188F 0x006C +#define REG_SDIO_CTRL_8188F 0x0070 +#define REG_OPT_CTRL_8188F 0x0074 +#define REG_AFE_XTAL_CTRL_EXT_8188F 0x0078 +#define REG_MCUFWDL_8188F 0x0080 +#define REG_FW_DBG_STATUS_8188F 0x0088 +#define REG_FW_DBG_CTRL_8188F 0x008F +#define REG_WLLPS_CTRL_8188F 0x0090 +#define REG_HIMR0_8188F 0x00B0 +#define REG_HISR0_8188F 0x00B4 +#define REG_HIMR1_8188F 0x00B8 +#define REG_HISR1_8188F 0x00BC +#define REG_PMC_DBG_CTRL2_8188F 0x00CC +#define REG_EFUSE_BURN_GNT_8188F 0x00CF +#define REG_HPON_FSM_8188F 0x00EC +#define REG_SYS_CFG_8188F 0x00F0 +#define REG_SYS_CFG1_8188F 0x00FC +#define REG_ROM_VERSION 0x00FD + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR_8188F 0x0100 +#define REG_PBP_8188F 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL_8188F 0x0106 +#define REG_TRXDMA_CTRL_8188F 0x010C +#define REG_TRXFF_BNDY_8188F 0x0114 +#define REG_TRXFF_STATUS_8188F 0x0118 +#define REG_RXFF_PTR_8188F 0x011C +#define REG_CPWM_8188F 0x012F +#define REG_FWIMR_8188F 0x0130 +#define REG_FWISR_8188F 0x0134 +#define REG_FTIMR_8188F 0x0138 +#define REG_PKTBUF_DBG_CTRL_8188F 0x0140 +#define REG_RXPKTBUF_CTRL_8188F 0x0142 +#define REG_PKTBUF_DBG_DATA_L_8188F 0x0144 +#define REG_PKTBUF_DBG_DATA_H_8188F 0x0148 + +#define REG_TC0_CTRL_8188F 0x0150 +#define REG_TC1_CTRL_8188F 0x0154 +#define REG_TC2_CTRL_8188F 0x0158 +#define REG_TC3_CTRL_8188F 0x015C +#define REG_TC4_CTRL_8188F 0x0160 +#define REG_TCUNIT_BASE_8188F 0x0164 +#define REG_RSVD3_8188F 0x0168 +#define REG_32K_CAL_REG1_8188F 0x0198 +#define REG_C2HEVT_MSG_NORMAL_8188F 0x01A0 +#define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 +#define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 +#define REG_C2HEVT_CMD_LEN_88XX 0x01AE +#define REG_C2HEVT_CLEAR_8188F 0x01AF +#define REG_MCUTST_1_8188F 0x01C0 +#define REG_MCUTST_WOWLAN_8188F 0x01C7 +#define REG_FMETHR_8188F 0x01C8 +#define REG_HMETFR_8188F 0x01CC +#define REG_HMEBOX_0_8188F 0x01D0 +#define REG_HMEBOX_1_8188F 0x01D4 +#define REG_HMEBOX_2_8188F 0x01D8 +#define REG_HMEBOX_3_8188F 0x01DC +#define REG_LLT_INIT_8188F 0x01E0 +#define REG_HMEBOX_EXT0_8188F 0x01F0 +#define REG_HMEBOX_EXT1_8188F 0x01F4 +#define REG_HMEBOX_EXT2_8188F 0x01F8 +#define REG_HMEBOX_EXT3_8188F 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN_8188F 0x0200 +#define REG_FIFOPAGE_8188F 0x0204 +#define REG_TDECTRL_8188F 0x0208 +#define REG_DWBCN0_CTRL_8188F REG_TDECTRL +#define REG_TXDMA_OFFSET_CHK_8188F 0x020C +#define REG_TXDMA_STATUS_8188F 0x0210 +#define REG_RQPN_NPQ_8188F 0x0214 +#define REG_AUTO_LLT_8188F 0x0224 +#define REG_TDECTRL1_8188F 0x0228 +#define REG_DWBCN1_CTRL_8188F 0x0228 + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH_8188F 0x0280 +#define REG_FW_UPD_RDPTR_8188F 0x0284 // FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 +#define REG_RXDMA_CONTROL_8188F 0x0286 // Control the RX DMA. +#define REG_RXPKT_NUM_8188F 0x0287 // The number of packets in RXPKTBUF. +#define REG_RXDMA_STATUS_8188F 0x0288 +#define REG_RXDMA_PRO_8188F 0x0290 +#define REG_EARLY_MODE_CONTROL_8188F 0x02BC +#define REG_RSVD5_8188F 0x02F0 +#define REG_RSVD6_8188F 0x02F4 + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8188F 0x0300 +#define REG_INT_MIG_8188F 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA_8188F 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA_8188F 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA_8188F 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA_8188F 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA_8188F 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA_8188F 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA_8188F 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA_8188F 0x0340 // RX Queue Descriptor Address +#define REG_DBI_WDATA_8188F 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8188F 0x034C // DBI Read Data +#define REG_DBI_ADDR_8188F 0x0350 // DBI Address +#define REG_DBI_FLAG_8188F 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8188F 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8188F 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8188F 0x0358 // MDIO for Control +#define REG_DBG_SEL_8188F 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM_8188F 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM_8188F 0x0363 //PCIe CPWM +#define REG_PCIE_MULTIFET_CTRL_8188F 0x036A //PCIE Multi-Fethc Control + +#define REG_MGQ_TXBD_NUM_8188F 0x0380 + +// spec version 11 +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_VOQ_INFORMATION_8188F 0x0400 +#define REG_VIQ_INFORMATION_8188F 0x0404 +#define REG_BEQ_INFORMATION_8188F 0x0408 +#define REG_BKQ_INFORMATION_8188F 0x040C +#define REG_MGQ_INFORMATION_8188F 0x0410 +#define REG_HGQ_INFORMATION_8188F 0x0414 +#define REG_BCNQ_INFORMATION_8188F 0x0418 +#define REG_TXPKT_EMPTY_8188F 0x041A + +#define REG_FWHW_TXQ_CTRL_8188F 0x0420 +#define REG_HWSEQ_CTRL_8188F 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY_8188F 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8188F 0x0425 +#define REG_LIFECTRL_CTRL_8188F 0x0426 +#define REG_MULTI_BCNQ_OFFSET_8188F 0x0427 +#define REG_SPEC_SIFS_8188F 0x0428 +#define REG_RL_8188F 0x042A +#define REG_TXBF_CTRL_8188F 0x042C +#define REG_DARFRC_8188F 0x0430 +#define REG_RARFRC_8188F 0x0438 +#define REG_RRSR_8188F 0x0440 +#define REG_ARFR0_8188F 0x0444 +#define REG_ARFR1_8188F 0x044C +#define REG_CCK_CHECK_8188F 0x0454 +#define REG_AMPDU_MAX_TIME_8188F 0x0456 +#define REG_TXPKTBUF_BCNQ_BDNY1_8188F 0x0457 + +#define REG_AMPDU_MAX_LENGTH_8188F 0x0458 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8188F 0x045D +#define REG_NDPA_OPT_CTRL_8188F 0x045F +#define REG_FAST_EDCA_CTRL_8188F 0x0460 +#define REG_RD_RESP_PKT_TH_8188F 0x0463 +#define REG_DATA_SC_8188F 0x0483 +#define REG_TXRPT_START_OFFSET 0x04AC +#define REG_POWER_STAGE1_8188F 0x04B4 +#define REG_POWER_STAGE2_8188F 0x04B8 +#define REG_AMPDU_BURST_MODE_8188F 0x04BC +#define REG_PKT_VO_VI_LIFE_TIME_8188F 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME_8188F 0x04C2 +#define REG_STBC_SETTING_8188F 0x04C4 +#define REG_HT_SINGLE_AMPDU_8188F 0x04C7 +#define REG_PROT_MODE_CTRL_8188F 0x04C8 +#define REG_MAX_AGGR_NUM_8188F 0x04CA +#define REG_RTS_MAX_AGGR_NUM_8188F 0x04CB +#define REG_BAR_MODE_CTRL_8188F 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT_8188F 0x04CF +#define REG_MACID_PKT_DROP0_8188F 0x04D0 +#define REG_MACID_PKT_SLEEP_8188F 0x04D4 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM_8188F 0x0500 +#define REG_EDCA_VI_PARAM_8188F 0x0504 +#define REG_EDCA_BE_PARAM_8188F 0x0508 +#define REG_EDCA_BK_PARAM_8188F 0x050C +#define REG_BCNTCFG_8188F 0x0510 +#define REG_PIFS_8188F 0x0512 +#define REG_RDG_PIFS_8188F 0x0513 +#define REG_SIFS_CTX_8188F 0x0514 +#define REG_SIFS_TRX_8188F 0x0516 +#define REG_AGGR_BREAK_TIME_8188F 0x051A +#define REG_SLOT_8188F 0x051B +#define REG_TX_PTCL_CTRL_8188F 0x0520 +#define REG_TXPAUSE_8188F 0x0522 +#define REG_DIS_TXREQ_CLR_8188F 0x0523 +#define REG_RD_CTRL_8188F 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT_8188F 0x0540 +#define REG_RD_NAV_NXT_8188F 0x0544 +#define REG_NAV_PROT_LEN_8188F 0x0546 +#define REG_BCN_CTRL_8188F 0x0550 +#define REG_BCN_CTRL_1_8188F 0x0551 +#define REG_MBID_NUM_8188F 0x0552 +#define REG_DUAL_TSF_RST_8188F 0x0553 +#define REG_BCN_INTERVAL_8188F 0x0554 +#define REG_DRVERLYINT_8188F 0x0558 +#define REG_BCNDMATIM_8188F 0x0559 +#define REG_ATIMWND_8188F 0x055A +#define REG_USTIME_TSF_8188F 0x055C +#define REG_BCN_MAX_ERR_8188F 0x055D +#define REG_RXTSF_OFFSET_CCK_8188F 0x055E +#define REG_RXTSF_OFFSET_OFDM_8188F 0x055F +#define REG_TSFTR_8188F 0x0560 +#define REG_CTWND_8188F 0x0572 +#define REG_SECONDARY_CCA_CTRL_8188F 0x0577 +#define REG_PSTIMER_8188F 0x0580 +#define REG_TIMER0_8188F 0x0584 +#define REG_TIMER1_8188F 0x0588 +#define REG_ACMHWCTRL_8188F 0x05C0 +#define REG_SCH_TXCMD_8188F 0x05F8 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8188F 0x0600 +#define REG_TCR_8188F 0x0604 +#define REG_RCR_8188F 0x0608 +#define REG_RX_PKT_LIMIT_8188F 0x060C +#define REG_RX_DLK_TIME_8188F 0x060D +#define REG_RX_DRVINFO_SZ_8188F 0x060F + +#define REG_MACID_8188F 0x0610 +#define REG_BSSID_8188F 0x0618 +#define REG_MAR_8188F 0x0620 +#define REG_MBIDCAMCFG_8188F 0x0628 + +#define REG_USTIME_EDCA_8188F 0x0638 +#define REG_MAC_SPEC_SIFS_8188F 0x063A +#define REG_RESP_SIFP_CCK_8188F 0x063C +#define REG_RESP_SIFS_OFDM_8188F 0x063E +#define REG_ACKTO_8188F 0x0640 +#define REG_CTS2TO_8188F 0x0641 +#define REG_EIFS_8188F 0x0642 + +#define REG_NAV_UPPER_8188F 0x0652 // unit of 128 +#define REG_TRXPTCL_CTL_8188F 0x0668 + +// Security +#define REG_CAMCMD_8188F 0x0670 +#define REG_CAMWRITE_8188F 0x0674 +#define REG_CAMREAD_8188F 0x0678 +#define REG_CAMDBG_8188F 0x067C +#define REG_SECCFG_8188F 0x0680 + +// Power +#define REG_WOW_CTRL_8188F 0x0690 +#define REG_PS_RX_INFO_8188F 0x0692 +#define REG_UAPSD_TID_8188F 0x0693 +#define REG_WKFMCAM_CMD_8188F 0x0698 +#define REG_WKFMCAM_NUM_8188F 0x0698 +#define REG_WKFMCAM_RWD_8188F 0x069C +#define REG_RXFLTMAP0_8188F 0x06A0 +#define REG_RXFLTMAP1_8188F 0x06A2 +#define REG_RXFLTMAP2_8188F 0x06A4 +#define REG_BCN_PSR_RPT_8188F 0x06A8 +#define REG_BT_COEX_TABLE_8188F 0x06C0 +#define REG_BFMER0_INFO_8188F 0x06E4 +#define REG_BFMER1_INFO_8188F 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8188F 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8188F 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8188F 0x06FC + +// Hardware Port 2 +#define REG_MACID1_8188F 0x0700 +#define REG_BSSID1_8188F 0x0708 +#define REG_BFMEE_SEL_8188F 0x0714 +#define REG_SND_PTCL_CTRL_8188F 0x0718 + +// LTE_COEX +#define REG_LTECOEX_CTRL 0x07C0 +#define REG_LTECOEX_WRITE_DATA 0x07C4 + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define EFUSE_CTRL_8188F REG_EFUSE_CTRL_8188F // E-Fuse Control. +#define EFUSE_TEST_8188F REG_EFUSE_TEST_8188F // E-Fuse Test. +#define MSR_8188F (REG_CR_8188F + 2) // Media Status register +#define ISR_8188F REG_HISR0_8188F +#define TSFR_8188F REG_TSFTR_8188F // Timing Sync Function Timer Register. + +#define PBP_8188F REG_PBP_8188F + +// Redifine MACID register, to compatible prior ICs. +#define IDR0_8188F REG_MACID_8188F // MAC ID Register, Offset 0x0050-0x0053 +#define IDR4_8188F (REG_MACID_8188F + 4) // MAC ID Register, Offset 0x0054-0x0055 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM_8188F REG_CAMCMD_8188F //IN 8190 Data Sheet is called CAMcmd +#define WCAMI_8188F REG_CAMWRITE_8188F // Software write CAM input content +#define RCAMO_8188F REG_CAMREAD_8188F // Software read/write CAM config +#define CAMDBG_8188F REG_CAMDBG_8188F +#define SECR_8188F REG_SECCFG_8188F //Security Configuration Register + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8188F 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8188F BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8188F BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8188F BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8188F BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8188F BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8188F BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8188F BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8188F BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8188F BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8188F BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8188F BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8188F BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8188F BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8188F BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8188F BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8188F BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8188F BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8188F BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8188F BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8188F BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8188F BIT3 // AC_VI DMA OK +#define IMR_VODOK_8188F BIT2 // AC_VO DMA OK +#define IMR_RDU_8188F BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8188F BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8188F BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8188F BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8188F BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8188F BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8188F BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8188F BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8188F BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8188F BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8188F BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8188F BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8188F BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8188F BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8188F BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8188F BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8188F BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8188F BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8188F BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8188F BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8188F BIT8 // Receive FIFO Overflow + + + + + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ +//---------------------------------------------------------------------------- +// 8195 (TXPAUSE) transmission pause (Offset 0x522, 8 bits) +//---------------------------------------------------------------------------- +/* +#define StopBecon BIT6 +#define StopHigh BIT5 +#define StopMgt BIT4 +#define StopVO BIT3 +#define StopVI BIT2 +#define StopBE BIT1 +#define StopBK BIT0 +*/ + + +//============================================================================ +// 8192C Regsiter Bit and Content definition +//============================================================================ +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +/* +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) + + +//2 9346CR + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +//2 EFUSE_TEST (For RTL8188 partially) +#define EF_TRPT BIT(7) +#define EF_CELL_SEL (BIT(8)|BIT(9)) // 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 +#define LDOE25_EN BIT(31) +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +#define EFUSE_BT_SEL_0 0x1 +#define EFUSE_BT_SEL_1 0x2 +#define EFUSE_BT_SEL_2 0x3 + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define RAM_DL_SEL BIT(7) +#define ROM_DLEN BIT(19) +#define CPRST BIT(23) + + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) // RTL ID +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 + +*/ +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +/* + +//2 Function Enable Registers +//2 CR 0x0100-0x0103 + + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) +#define CALTMR_EN BIT(10) // 32k CAL TMR enable + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + + +//2 PBP - Page Size Register 0x0104 +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA 0x010C +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + +//2 REG_C2HEVT_CLEAR 0x01AF +#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message +#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver. + + + +//2 LLT_INIT 0x01E0 +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +*/ +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +/* +//2 TDECTL 0x0208 +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK 0x020C +#define DROP_DATA_EN BIT(9) +*/ +//----------------------------------------------------- +// +// 0x0280h ~ 0x028Bh RX DMA Configuration +// +//----------------------------------------------------- +/* +//2 REG_RXDMA_CONTROL, 0x0286h + +// Write only. When this bit is set, RXDMA will decrease RX PKT counter by one. Before +// this bit is polled, FW shall update RXFF_RD_PTR first. This register is write pulse and auto clear. +#define RXPKT_RELEASE_POLL BIT(0) +// Read only. When RXMA finishes on-going DMA operation, RXMDA will report idle state in +// this bit. FW can start releasing packets after RXDMA entering idle mode. +#define RXDMA_IDLE BIT(1) +// When this bit is set, RXDMA will enter this mode after on-going RXDMA packet to host +// completed, and stop DMA packet to host. RXDMA will then report Default: 0; +#define RW_RELEASE_EN BIT(2) +*/ +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +/* +//2 FWHW_TXQ_CTRL 0x0420 +#define EN_AMPDU_RTY_NEW BIT(7) + + +//2 REG_LIFECTRL_CTRL 0x0426 +#define HAL92C_EN_PKT_LIFE_TIME_BK BIT3 +#define HAL92C_EN_PKT_LIFE_TIME_BE BIT2 +#define HAL92C_EN_PKT_LIFE_TIME_VI BIT1 +#define HAL92C_EN_PKT_LIFE_TIME_VO BIT0 + +#define HAL92C_MSDU_LIFE_TIME_UNIT 128 // in us, said by Tim. + + +//2 SPEC SIFS 0x0428 +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +//2 RL 0x042A +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) +*/ + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +/* +//2 EDCA setting 0x050C +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +//2 BCN_CTRL 0x0550 +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +//2 TxPause 0x0522 +#define STOP_BCNQ BIT(6) +*/ + + +//2 ACMHWCTRL 0x05C0 +#define AcmHw_HwEn_8188F BIT(0) +#define AcmHw_VoqEn_8188F BIT(1) +#define AcmHw_ViqEn_8188F BIT(2) +#define AcmHw_BeqEn_8188F BIT(3) +#define AcmHw_VoqStatus_8188F BIT(5) +#define AcmHw_ViqStatus_8188F BIT(6) +#define AcmHw_BeqStatus_8188F BIT(7) + + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +/* + +//2 TCR 0x0604 +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) +*/ + +//---------------------------------------------------------------------------- +// 8195 (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +/* +#define RCR_APPFCS BIT31 // WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // MACRX will retain the MIC at the bottom of the packet. +#define RCR_APP_ICV BIT29 // MACRX will retain the ICV at the bottom of the packet. +#define RCR_APP_PHYST_RXFF BIT28 // HY Status is appended before RX packet in RXFF +#define RCR_APP_BA_SSN BIT27 // SSN of previous TXBA is appended as after original RXDESC as the 4-th DW of RXDESC. +#define RCR_RSVD_BIT26 BIT26 // Reserved +*/ +#define RCR_TCPOFLD_EN BIT25 // Enable TCP checksum offload + +#endif // #ifndef __INC_HAL8188FREG_H diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.c new file mode 100644 index 00000000..58a5d3e6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.c @@ -0,0 +1,590 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8188F_SUPPORT == 1) +static BOOLEAN +CheckPositive( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2, + IN const u4Byte Condition3, + IN const u4Byte Condition4 +) +{ + u1Byte _BoardType = ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA*/ + ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA*/ + ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA*/ + ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ + ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT*/ + + u4Byte cond1 = Condition1, cond2 = Condition2, cond3 = Condition3, cond4 = Condition4; + u4Byte driver1 = pDM_Odm->CutVersion << 24 | + (pDM_Odm->SupportInterface & 0xF0) << 16 | + pDM_Odm->SupportPlatform << 16 | + pDM_Odm->PackageType << 12 | + (pDM_Odm->SupportInterface & 0x0F) << 8 | + _BoardType; + + u4Byte driver2 = (pDM_Odm->TypeGLNA & 0xFF) << 0 | + (pDM_Odm->TypeGPA & 0xFF) << 8 | + (pDM_Odm->TypeALNA & 0xFF) << 16 | + (pDM_Odm->TypeAPA & 0xFF) << 24; + +u4Byte driver3 = 0; + + u4Byte driver4 = (pDM_Odm->TypeGLNA & 0xFF00) >> 8 | + (pDM_Odm->TypeGPA & 0xFF00) | + (pDM_Odm->TypeALNA & 0xFF00) << 8 | + (pDM_Odm->TypeAPA & 0xFF00) << 16; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Platform, Interface) = (0x%X, 0x%X)\n", pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Board, Package) = (0x%X, 0x%X)\n", pDM_Odm->BoardType, pDM_Odm->PackageType)); + + + /*============== Value Defined Check ===============*/ + /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return FALSE; + if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return FALSE; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u4Byte bitMask = 0; + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ + return TRUE; + + if ((cond1 & BIT0) != 0) /*GLNA*/ + bitMask |= 0x000000FF; + if ((cond1 & BIT1) != 0) /*GPA*/ + bitMask |= 0x0000FF00; + if ((cond1 & BIT2) != 0) /*ALNA*/ + bitMask |= 0x00FF0000; + if ((cond1 & BIT3) != 0) /*APA*/ + bitMask |= 0xFF000000; + + if (((cond2 & bitMask) == (driver2 & bitMask)) && ((cond4 & bitMask) == (driver4 & bitMask))) /* BoardType of each RF path is matched*/ + return TRUE; + else + return FALSE; + } else + return FALSE; +} +static BOOLEAN +CheckNegative( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2 +) +{ + return TRUE; +} + +/****************************************************************************** +* AGC_TAB.TXT +******************************************************************************/ + +u4Byte Array_MP_8188F_AGC_TAB[] = { + 0xC78, 0xFC000001, + 0xC78, 0xFB010001, + 0xC78, 0xFA020001, + 0xC78, 0xF9030001, + 0xC78, 0xF8040001, + 0xC78, 0xF7050001, + 0xC78, 0xF6060001, + 0xC78, 0xF5070001, + 0xC78, 0xF4080001, + 0xC78, 0xF3090001, + 0xC78, 0xF20A0001, + 0xC78, 0xF10B0001, + 0xC78, 0xF00C0001, + 0xC78, 0xEF0D0001, + 0xC78, 0xEE0E0001, + 0xC78, 0xED0F0001, + 0xC78, 0xEC100001, + 0xC78, 0xEB110001, + 0xC78, 0xEA120001, + 0xC78, 0xE9130001, + 0xC78, 0xE8140001, + 0xC78, 0xE7150001, + 0xC78, 0xE6160001, + 0xC78, 0xE5170001, + 0xC78, 0xE4180001, + 0xC78, 0xE3190001, + 0xC78, 0xE21A0001, + 0xC78, 0xE11B0001, + 0xC78, 0xE01C0001, + 0xC78, 0xC21D0001, + 0xC78, 0xC11E0001, + 0xC78, 0xC01F0001, + 0xC78, 0xA5200001, + 0xC78, 0xA4210001, + 0xC78, 0xA3220001, + 0xC78, 0xA2230001, + 0xC78, 0xA1240001, + 0xC78, 0xA0250001, + 0xC78, 0x65260001, + 0xC78, 0x64270001, + 0xC78, 0x63280001, + 0xC78, 0x62290001, + 0xC78, 0x612A0001, + 0xC78, 0x442B0001, + 0xC78, 0x432C0001, + 0xC78, 0x422D0001, + 0xC78, 0x412E0001, + 0xC78, 0x402F0001, + 0xC78, 0x21300001, + 0xC78, 0x20310001, + 0xC78, 0x05320001, + 0xC78, 0x04330001, + 0xC78, 0x03340001, + 0xC78, 0x02350001, + 0xC78, 0x01360001, + 0xC78, 0x00370001, + 0xC78, 0x00380001, + 0xC78, 0x00390001, + 0xC78, 0x003A0001, + 0xC78, 0x003B0001, + 0xC78, 0x003C0001, + 0xC78, 0x003D0001, + 0xC78, 0x003E0001, + 0xC78, 0x003F0001, + 0xC50, 0x69553422, + 0xC50, 0x69553420, + +}; + +void +ODM_ReadAndConfig_MP_8188F_AGC_TAB( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; + u4Byte ArrayLen = sizeof(Array_MP_8188F_AGC_TAB)/sizeof(u4Byte); + pu4Byte Array = Array_MP_8188F_AGC_TAB; + + u4Byte v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_AGC_TAB\n")); + + while ((i + 1) < ArrayLen) { + v1 = Array[i]; + 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; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n")); + } else if (cCond == COND_ELSE) { /*else*/ + bMatched = bSkipped?FALSE:TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n")); + } else {/*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n")); + } + } else if (v1 & BIT30) { /*negative condition*/ + if (bSkipped == FALSE) { + if (CheckPositive(pDM_Odm, pre_v1, pre_v2, v1, v2)) { + bMatched = TRUE; + bSkipped = TRUE; + } else { + bMatched = FALSE; + bSkipped = FALSE; + } + } else + bMatched = FALSE; + } + } else { + if (bMatched) + odm_ConfigBB_AGC_8188F(pDM_Odm, v1, bMaskDWord, v2); + } + i = i + 2; + } +} + +u4Byte +ODM_GetVersion_MP_8188F_AGC_TAB(void) +{ + return 25; +} + +/****************************************************************************** +* PHY_REG.TXT +******************************************************************************/ + +u4Byte Array_MP_8188F_PHY_REG[] = { + 0x800, 0x83045700, + 0x804, 0x00000001, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x00200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00030000, + 0x854, 0x00000000, + 0x858, 0x569A569A, + 0x85C, 0x569A569A, + 0x860, 0x00000130, + 0x864, 0x00000000, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x00000000, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x004F0201, + 0x880, 0xB0000B1E, + 0x884, 0x00000007, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000002, + 0x914, 0x00000201, + 0x948, 0x99000000, + 0x94C, 0x00000010, + 0x950, 0x20003000, + 0x954, 0x4A880000, + 0x958, 0x4BC5D87A, + 0x95C, 0x04EB9B79, + 0x96C, 0x00000003, + 0xA00, 0x00D047C8, + 0xA04, 0x80FF800C, + 0x80000400, 0x00000000, 0x40000000, 0x00000000, + 0xA08, 0x8C038300, + 0xA0000000, 0x00000000, + 0xA08, 0x8CCD8300, + 0xB0000000, 0x00000000, + 0xA0C, 0x2E7F120F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xD1D80000, + 0xA24, 0x5A7DA0BD, + 0xA28, 0x0000223B, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B1, + 0xA84, 0x00120000, + 0xA88, 0x040C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x05100000, + 0xA9C, 0x3F000000, + 0xAA0, 0x00000000, + 0xB2C, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x18800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9CC4A, + 0xC34, 0x31000040, + 0xC38, 0x21688080, + 0xC3C, 0x00001714, + 0xC40, 0x1F78403F, + 0xC44, 0x00010036, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00013169, + 0xC5C, 0x00250492, + 0xC60, 0x00000000, + 0xC64, 0x7112848B, + 0xC68, 0x47C07BFF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020600DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0x80000400, 0x00000000, 0x40000000, 0x00000000, + 0xC84, 0x21F60000, + 0xA0000000, 0x00000000, + 0xC84, 0x71F60000, + 0xB0000000, 0x00000000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00091521, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00000000, + 0xCA4, 0x000300A0, + 0xCA8, 0x00000000, + 0xCAC, 0x00000000, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x00000000, + 0xCC4, 0x00000000, + 0xCC8, 0x00000000, + 0xCCC, 0x00000000, + 0xCD0, 0x00000000, + 0xCD4, 0x00000000, + 0xCD8, 0x64B22427, + 0xCDC, 0x00766932, + 0xCE0, 0x00222222, + 0xCE4, 0x10000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x04030740, + 0xD04, 0x40020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC53, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCB979975, + 0xD30, 0x00000000, + 0xD34, 0x80608000, + 0xD38, 0x98000000, + 0xD3C, 0x40127353, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x6437140A, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xD6C, 0x2A201C16, + 0xD70, 0x1812362E, + 0xD74, 0x322C2220, + 0xD78, 0x000E3C24, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE60, 0x021400A0, + 0xE64, 0x281600A0, + 0xE6C, 0x01C00010, + 0xE70, 0x01C00010, + 0xE74, 0x02000010, + 0xE78, 0x02000010, + 0xE7C, 0x02000010, + 0xE80, 0x02000010, + 0xE84, 0x01C00010, + 0xE88, 0x02000010, + 0xE8C, 0x01C00010, + 0xED0, 0x01C00010, + 0xED4, 0x01C00010, + 0xED8, 0x01C00010, + 0xEDC, 0x00000010, + 0xEE0, 0x00000010, + 0xEEC, 0x03C00010, + 0xF14, 0x00000003, + 0xF4C, 0x00000000, + 0xF00, 0x00000300, + +}; + +void +ODM_ReadAndConfig_MP_8188F_PHY_REG( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; + u4Byte ArrayLen = sizeof(Array_MP_8188F_PHY_REG)/sizeof(u4Byte); + pu4Byte Array = Array_MP_8188F_PHY_REG; + + u4Byte v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_PHY_REG\n")); + + while ((i + 1) < ArrayLen) { + v1 = Array[i]; + 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; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n")); + } else if (cCond == COND_ELSE) { /*else*/ + bMatched = bSkipped?FALSE:TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n")); + } else {/*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n")); + } + } else if (v1 & BIT30) { /*negative condition*/ + if (bSkipped == FALSE) { + if (CheckPositive(pDM_Odm, pre_v1, pre_v2, v1, v2)) { + bMatched = TRUE; + bSkipped = TRUE; + } else { + bMatched = FALSE; + bSkipped = FALSE; + } + } else + bMatched = FALSE; + } + } else { + if (bMatched) + odm_ConfigBB_PHY_8188F(pDM_Odm, v1, bMaskDWord, v2); + } + i = i + 2; + } +} + +u4Byte +ODM_GetVersion_MP_8188F_PHY_REG(void) +{ + return 25; +} + +/****************************************************************************** +* PHY_REG_PG.TXT +******************************************************************************/ + +u4Byte Array_MP_8188F_PHY_REG_PG[] = { + 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, + 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, + 0, 0, 0, 0x00000e00, 0xffffffff, 0x34363636, + 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303234, + 0, 0, 0, 0x00000e10, 0xffffffff, 0x30343434, + 0, 0, 0, 0x00000e14, 0xffffffff, 0x26262830 +}; + +void +ODM_ReadAndConfig_MP_8188F_PHY_REG_PG( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u4Byte ArrayLen = sizeof(Array_MP_8188F_PHY_REG_PG)/sizeof(u4Byte); + pu4Byte Array = Array_MP_8188F_PHY_REG_PG; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PlatformZeroMemory(pHalData->BufOfLinesPwrByRate, MAX_LINES_HWCONFIG_TXT*MAX_BYTES_LINE_HWCONFIG_TXT); + pHalData->nLinesReadPwrByRate = ArrayLen/6; +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_PHY_REG_PG\n")); + + pDM_Odm->PhyRegPgVersion = 1; + pDM_Odm->PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE; + + for (i = 0; i < ArrayLen; i += 6) { + u4Byte v1 = Array[i]; + u4Byte v2 = Array[i+1]; + u4Byte v3 = Array[i+2]; + u4Byte v4 = Array[i+3]; + u4Byte v5 = Array[i+4]; + u4Byte v6 = Array[i+5]; + + odm_ConfigBB_PHY_REG_PG_8188F(pDM_Odm, v1, v2, v3, v4, v5, v6); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + rsprintf((char *)pHalData->BufOfLinesPwrByRate[i/6], 100, "%s, %s, %s, 0x%X, 0x%08X, 0x%08X,", + (v1 == 0?"2.4G":" 5G"), (v2 == 0?"A":"B"), (v3 == 0?"1Tx":"2Tx"), v4, v5, v6); +#endif + } +} + + + +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.h new file mode 100644 index 00000000..71d15e50 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_bb.h @@ -0,0 +1,59 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#if (RTL8188F_SUPPORT == 1) +#ifndef __INC_MP_BB_HW_IMG_8188F_H +#define __INC_MP_BB_HW_IMG_8188F_H + + +/****************************************************************************** +* AGC_TAB.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_AGC_TAB(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_AGC_TAB(void); + +/****************************************************************************** +* PHY_REG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_PHY_REG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_PHY_REG(void); + +/****************************************************************************** +* PHY_REG_PG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_PHY_REG_PG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_PHY_REG_PG(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.c new file mode 100644 index 00000000..5753255f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.c @@ -0,0 +1,3547 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.16*/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8188F_SUPPORT == 1) +#if (defined(CONFIG_AP_WOWLAN) || (DM_ODM_SUPPORT_TYPE & (ODM_AP))) + + +u1Byte Array_MP_8188F_FW_AP[] = { +0xF1, 0x88, 0x20, 0x00, 0x01, 0x00, 0x07, 0x00, 0x10, 0x22, 0x17, 0x28, 0x36, 0x44, 0x02, 0x00, +0xE7, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x87, 0x32, 0x02, 0xB7, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xAC, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xB8, 0x06, 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, 0xB7, 0xB5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA9, 0xD2, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xB8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x87, 0xDA, 0x02, 0x96, 0x30, 0x02, 0x80, 0x86, 0x02, 0x80, 0x89, 0x02, 0x80, 0x8C, 0x02, +0x8D, 0x4D, 0x02, 0x97, 0xD8, 0x02, 0x80, 0x95, 0x02, 0x80, 0x98, 0x02, 0x80, 0x9B, 0x02, 0x80, +0x9E, 0x02, 0x80, 0xA1, 0x02, 0x80, 0xA4, 0x02, 0x80, 0xA7, 0x02, 0x80, 0xAA, 0x02, 0x80, 0xAD, +0x02, 0x80, 0xB0, 0x02, 0x89, 0x19, 0x02, 0x80, 0xB6, 0x02, 0x80, 0xB9, 0x02, 0xB2, 0x58, 0x02, +0xA0, 0x9E, 0x02, 0xA0, 0x27, 0x02, 0xA7, 0x15, 0x02, 0xAE, 0x1F, 0x02, 0xB1, 0xEF, 0x02, 0x80, +0xCE, 0x02, 0x80, 0xD1, 0x02, 0x80, 0xD4, 0x02, 0x80, 0xD7, 0x00, 0x00, 0x00, 0x02, 0x80, 0xDD, +0x02, 0x80, 0xE0, 0x02, 0x80, 0xE3, 0x02, 0x80, 0xE6, 0x02, 0xC3, 0x1D, 0x02, 0x80, 0xEC, 0x02, +0x80, 0xEF, 0x02, 0x80, 0xF2, 0x02, 0x80, 0xF5, 0x02, 0x80, 0xF8, 0x02, 0x80, 0xFB, 0x02, 0x80, +0xFE, 0x02, 0x81, 0x01, 0x02, 0x81, 0x04, 0x02, 0x81, 0x07, 0x02, 0x81, 0x0A, 0x02, 0x81, 0x0D, +0x02, 0x81, 0x10, 0x02, 0x81, 0x13, 0x02, 0x81, 0x16, 0x02, 0x81, 0x19, 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, 0x93, 0x32, 0x02, 0xB8, 0xB7, 0x02, 0x90, 0xF4, 0x02, 0x90, 0xE9, +0x02, 0x81, 0x40, 0x02, 0x8E, 0xAC, 0x02, 0xBF, 0x1A, 0x02, 0x81, 0x49, 0x02, 0x81, 0x4C, 0x02, +0x81, 0x4F, 0x02, 0x81, 0x52, 0x02, 0x81, 0x55, 0x02, 0x81, 0x58, 0x02, 0x81, 0x5B, 0x02, 0x91, +0x57, 0x02, 0x81, 0x61, 0x02, 0x81, 0x64, 0x02, 0xBF, 0xE3, 0x02, 0xC2, 0x57, 0x02, 0xC2, 0x8A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, +0x08, 0x03, 0x03, 0x00, 0x04, 0x09, 0x07, 0x03, 0x03, 0x00, 0x04, 0x08, 0x06, 0x03, 0x02, 0x00, +0x04, 0x08, 0x05, 0x03, 0x01, 0x00, 0x04, 0x0D, 0x0A, 0x07, 0x05, 0x00, 0x08, 0x0C, 0x0A, 0x07, +0x04, 0x00, 0x08, 0x0B, 0x0A, 0x06, 0x05, 0x00, 0x08, 0x0B, 0x0A, 0x05, 0x03, 0x00, 0x08, 0x0B, +0x0A, 0x03, 0x02, 0x00, 0x08, 0x14, 0x12, 0x0C, 0x04, 0x00, 0x10, 0x14, 0x12, 0x09, 0x04, 0x00, +0x10, 0x24, 0x22, 0x1C, 0x12, 0x00, 0x20, 0x24, 0x22, 0x18, 0x0C, 0x00, 0x20, 0x24, 0x22, 0x14, +0x06, 0x00, 0x20, 0x24, 0x22, 0x0F, 0x04, 0x00, 0x20, 0x24, 0x21, 0x0A, 0x04, 0x00, 0x20, 0x23, +0x21, 0x0C, 0x04, 0x00, 0x20, 0x23, 0x1F, 0x0A, 0x04, 0x00, 0x20, 0x22, 0x1F, 0x0F, 0x04, 0x00, +0x20, 0x21, 0x1F, 0x16, 0x0C, 0x00, 0x20, 0x31, 0x2F, 0x20, 0x14, 0x00, 0x30, 0x31, 0x2F, 0x18, +0x10, 0x00, 0x30, 0x31, 0x2C, 0x18, 0x0C, 0x00, 0x30, 0x31, 0x2A, 0x14, 0x0C, 0x00, 0x30, 0x31, +0x28, 0x14, 0x00, 0x00, 0x30, 0x31, 0x24, 0x14, 0x00, 0x00, 0x30, 0x31, 0x1E, 0x14, 0x00, 0x00, +0x30, 0x02, 0x02, 0x03, 0x04, 0x04, 0x08, 0x09, 0x09, 0x0C, 0x0E, 0x10, 0x12, 0x02, 0x09, 0x0B, +0x0E, 0x0D, 0x0F, 0x10, 0x12, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x23, 0x00, +0x2D, 0x00, 0x50, 0x00, 0x91, 0x00, 0xC3, 0x01, 0x27, 0x01, 0x31, 0x01, 0x5E, 0x00, 0x8C, 0x00, +0xC8, 0x00, 0xDC, 0x01, 0x5E, 0x01, 0x68, 0x01, 0x9A, 0x01, 0xCC, 0x01, 0xEA, 0x02, 0x02, 0x04, +0x08, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x14, 0x28, 0x32, 0x50, 0x78, 0xA0, 0xC8, +0xE6, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x02, 0x04, 0x06, +0x07, 0x07, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x03, 0x03, 0x04, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x03, 0x03, 0x03, +0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x19, 0x06, 0x04, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x84, 0x04, 0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0, +0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A, 0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C, +0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02, 0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00, +0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6, 0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1, +0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9, 0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF, +0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF, 0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30, +0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50, 0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8, +0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8, +0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80, 0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5, +0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD, +0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0, 0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86, +0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C, 0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF, +0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F, 0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F, +0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6, +0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76, 0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80, +0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81, 0x76, 0x30, 0x90, 0x87, 0xD4, 0x74, 0x01, 0x93, +0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89, 0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2, +0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81, +0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2, 0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE, +0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74, 0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18, +0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09, +0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE, 0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81, +0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E, 0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02, +0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09, +0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF, 0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F, +0x04, 0x90, 0x87, 0xD4, 0x93, 0xF6, 0x08, 0xEF, 0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3, +0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF, 0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4, +0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF, 0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F, +0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x84, 0x4D, 0x50, 0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02, +0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74, 0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C, +0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19, 0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5, +0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01, +0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08, 0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC, +0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8, 0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5, +0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, +0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6, 0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4, +0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30, 0xE2, 0x01, 0x0F, 0x02, 0x84, 0x4C, 0x8F, 0xF0, +0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80, 0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08, +0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x32, 0x50, 0x30, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6, +0x60, 0x27, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x25, 0x0E, 0x30, +0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x14, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x15, 0x54, 0xEC, +0x4E, 0xF6, 0xD2, 0xAF, 0xD2, 0xA9, 0x02, 0x84, 0x4D, 0x7F, 0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, +0xC2, 0xAF, 0x56, 0xC6, 0xD2, 0xAF, 0xD2, 0xA9, 0x54, 0x80, 0x4F, 0xFF, 0x22, 0xEF, 0x2B, 0xFF, +0xEE, 0x3A, 0xFE, 0xED, 0x39, 0xFD, 0xEC, 0x38, 0xFC, 0x22, 0xC3, 0xEF, 0x9B, 0xFF, 0xEE, 0x9A, +0xFE, 0xED, 0x99, 0xFD, 0xEC, 0x98, 0xFC, 0x22, 0xEF, 0x5B, 0xFF, 0xEE, 0x5A, 0xFE, 0xED, 0x59, +0xFD, 0xEC, 0x58, 0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48, +0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xE0, 0xF8, +0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, +0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, +0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, +0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, +0x80, 0xDF, 0x02, 0x87, 0x70, 0x02, 0x84, 0xDD, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, +0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, +0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, +0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, +0x90, 0x87, 0xB5, 0xE4, 0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, 0x93, 0x9F, 0x00, 0x41, 0x93, 0xA0, 0x00, 0x41, 0x93, 0xA5, +0x00, 0x44, 0x93, 0x8B, 0x41, 0x4E, 0x59, 0x00, 0x44, 0x93, 0x87, 0x61, 0x6E, 0x79, 0x00, 0x41, +0x93, 0xA7, 0x00, 0x00, 0xB2, 0xC6, 0xB6, 0xD6, 0xA7, 0x66, 0x90, 0x93, 0xA3, 0xEF, 0xF0, 0x7F, +0x02, 0xD1, 0x27, 0x90, 0x84, 0xC1, 0xE0, 0xFF, 0x90, 0x93, 0xA3, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, +0x84, 0xC1, 0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x5B, 0x12, 0x02, 0xF6, 0x25, 0x5B, 0x90, +0x84, 0xC6, 0xF0, 0xF1, 0x11, 0x25, 0x5B, 0x90, 0x84, 0xC7, 0x71, 0xEE, 0x25, 0x5B, 0x90, 0x84, +0xC8, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x03, 0x0F, 0x25, 0x5B, 0x90, 0x84, 0xC9, 0xF0, 0x90, 0x00, +0x04, 0x12, 0x03, 0x0F, 0x25, 0x5B, 0x90, 0x84, 0xCA, 0xF0, 0x90, 0x00, 0x05, 0x12, 0x03, 0x0F, +0x25, 0x5B, 0x90, 0x84, 0xCB, 0xF0, 0x11, 0x3F, 0x25, 0x5B, 0x90, 0x84, 0xCC, 0xF0, 0x22, 0x90, +0x00, 0x06, 0x02, 0x03, 0x0F, 0xF1, 0xD6, 0x12, 0x02, 0xF6, 0xFF, 0x54, 0x7F, 0x90, 0x85, 0xC5, +0xF0, 0xEF, 0x71, 0xF9, 0xA3, 0xF0, 0xF1, 0x11, 0xFD, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x90, +0x85, 0xC3, 0xE0, 0x54, 0xF0, 0x4F, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x03, 0x0F, 0xFC, 0x54, 0x01, +0x25, 0xE0, 0xFF, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0xEC, 0x54, 0x02, 0x25, 0xE0, +0xFF, 0x90, 0x93, 0x1F, 0xE0, 0x54, 0xFB, 0x4F, 0xF0, 0xED, 0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, +0xF1, 0xE4, 0x71, 0xED, 0x90, 0x85, 0xC4, 0xF0, 0x11, 0x3F, 0x30, 0xE0, 0x52, 0xC3, 0x13, 0x54, +0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x85, 0xD8, 0x50, 0x04, 0xEF, 0xF0, 0x80, 0x2A, 0x74, 0x03, +0xF0, 0x31, 0x13, 0xE9, 0x24, 0x06, 0xF9, 0xE4, 0x3A, 0xFA, 0x12, 0x02, 0xF6, 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, 0x03, 0x3C, 0x31, 0x13, 0x11, 0x3F, 0xC4, 0x54, 0x0F, 0xFF, +0xC3, 0x94, 0x04, 0x90, 0x85, 0xCD, 0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, 0xEF, 0xF0, 0x31, +0x13, 0x90, 0x00, 0x04, 0x12, 0x03, 0x0F, 0xFD, 0x7F, 0x02, 0x12, 0x57, 0x82, 0x31, 0x13, 0x12, +0x71, 0xCB, 0x12, 0xAA, 0x60, 0xF0, 0x90, 0x85, 0xC5, 0x12, 0xC3, 0xF5, 0xF1, 0xE3, 0x90, 0x01, +0xBE, 0xF0, 0x22, 0x90, 0x92, 0x07, 0x02, 0x86, 0xFA, 0xF1, 0xD6, 0x31, 0x13, 0x12, 0x02, 0xF6, +0x54, 0x7F, 0xFD, 0xF1, 0x11, 0xFE, 0x54, 0x1F, 0x90, 0x92, 0x0B, 0x71, 0xF5, 0x90, 0x92, 0x0A, +0x71, 0xEE, 0xFE, 0x54, 0x03, 0xFC, 0xEE, 0x54, 0x30, 0xC4, 0x54, 0x0F, 0x90, 0x92, 0x0D, 0x71, +0xEE, 0xFE, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x92, 0x0C, 0x71, 0xF5, 0xFF, 0x71, +0xEF, 0xFB, 0x54, 0x08, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x90, 0x92, 0x0F, 0xF0, 0xFA, 0xEB, 0x54, +0x04, 0x13, 0x13, 0x54, 0x3F, 0xA3, 0xF0, 0xEF, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, +0x51, 0x81, 0x54, 0x7F, 0x4F, 0xF0, 0x90, 0x92, 0x0C, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x54, +0xC0, 0x51, 0x81, 0x54, 0xBF, 0x4F, 0xF0, 0xEA, 0x60, 0x02, 0x41, 0x80, 0x90, 0x92, 0x0B, 0xE0, +0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0x91, 0x05, 0x54, 0xE0, 0x4F, 0xF0, 0xEC, 0x54, 0x03, +0x51, 0x81, 0x54, 0xFC, 0x4F, 0xF0, 0xEC, 0x54, 0x03, 0x25, 0xE0, 0x25, 0xE0, 0x51, 0x81, 0x54, +0xF3, 0x4F, 0xF0, 0x90, 0x92, 0x0A, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x54, 0xE0, 0xFF, 0x75, 0xF0, +0x12, 0xED, 0x91, 0x05, 0x54, 0xDF, 0x4F, 0xF0, 0x90, 0x92, 0x0D, 0xE0, 0x54, 0x03, 0xC4, 0x54, +0xF0, 0x51, 0x81, 0x54, 0xCF, 0x4F, 0xF1, 0xEB, 0xF5, 0x83, 0xE0, 0x54, 0xFB, 0xF1, 0xEB, 0xF5, +0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x92, 0x10, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFE, +0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x90, 0x93, 0x19, 0xE0, 0x60, 0x3A, 0x31, 0x13, 0xE9, +0x24, 0x03, 0xF9, 0xE4, 0x3A, 0xFA, 0x12, 0x02, 0xF6, 0x54, 0x1F, 0x12, 0x03, 0x3C, 0x90, 0x92, +0x0E, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x0E, 0xE0, 0xFF, 0xC3, 0x94, 0x04, 0x50, 0x19, 0xEF, 0x24, +0x03, 0xFF, 0xE4, 0x33, 0xFE, 0x31, 0x13, 0x8F, 0x82, 0x8E, 0x83, 0xE4, 0x12, 0x03, 0x4E, 0x90, +0x92, 0x0E, 0xE0, 0x04, 0xF0, 0x80, 0xDD, 0x90, 0x93, 0x17, 0xE0, 0x54, 0x07, 0xFF, 0xBF, 0x05, +0x0A, 0xEC, 0xB4, 0x01, 0x06, 0x90, 0x93, 0x1C, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x92, 0x0E, 0xF0, +0x90, 0x92, 0x0E, 0xE0, 0xFC, 0x24, 0x03, 0xFF, 0xE4, 0x33, 0xFE, 0x31, 0x13, 0x8F, 0x82, 0x8E, +0x83, 0x12, 0x03, 0x0F, 0xFF, 0xED, 0x12, 0xBC, 0x87, 0xE5, 0x82, 0x2C, 0x12, 0xAE, 0x17, 0xEF, +0xF0, 0x90, 0x92, 0x0E, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x04, 0xD5, 0xAF, 0x05, 0x12, 0x17, 0x8E, +0x22, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0x90, 0x89, 0x3F, 0x12, 0x05, 0x28, 0xE0, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0xDC, 0x20, 0xE6, 0x02, 0x61, 0xB4, 0x90, 0x00, 0x8C, 0xE0, +0x90, 0x93, 0x96, 0xF0, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0x90, 0x93, 0x97, 0xEF, 0xF0, 0x90, 0x00, +0x8E, 0xE0, 0x90, 0x93, 0x98, 0xF0, 0x90, 0x93, 0x97, 0xE0, 0x24, 0xFC, 0x60, 0x10, 0x24, 0x03, +0x60, 0x02, 0x61, 0xA8, 0x90, 0x93, 0x96, 0xE0, 0xFF, 0x12, 0xBC, 0x95, 0x61, 0xA8, 0x90, 0x93, +0x96, 0xE0, 0x24, 0xDC, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFD, 0xFF, +0x71, 0xE6, 0x75, 0xF0, 0x12, 0x51, 0x86, 0x13, 0x13, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x71, +0xE6, 0x75, 0xF0, 0x12, 0x51, 0x86, 0x71, 0xF9, 0xFB, 0x0D, 0xE4, 0xFF, 0x71, 0xE6, 0x75, 0xF0, +0x12, 0x51, 0x86, 0xC4, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x71, 0xE6, 0xF1, 0xF7, 0xFB, 0xE4, +0xFD, 0x0F, 0x71, 0xE6, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x3D, 0x12, 0x05, 0x28, 0x71, 0xE3, 0x75, +0xF0, 0x12, 0x91, 0x05, 0xC4, 0x13, 0x54, 0x01, 0xFB, 0x0D, 0x7F, 0x01, 0x71, 0xE6, 0x75, 0xF0, +0x12, 0x91, 0x05, 0x54, 0x1F, 0x71, 0xE4, 0x12, 0xBC, 0x87, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x71, +0xE6, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x71, 0xE1, 0x75, 0xF0, +0x08, 0xA4, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x71, 0xE1, 0x75, 0xF0, 0x08, 0xA4, 0x24, +0x03, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x71, 0xE1, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x04, 0xF5, 0x82, +0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x71, 0xE6, 0x75, 0xF0, 0x08, 0xA4, +0x24, 0x05, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x71, 0xE1, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x06, 0xF5, +0x82, 0xE4, 0x34, 0x82, 0x71, 0xE1, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x07, 0xF5, 0x82, 0xE4, 0x34, +0x82, 0xF5, 0x83, 0xE0, 0xFB, 0x0D, 0x71, 0xB9, 0xF1, 0xDC, 0x30, 0xE0, 0x07, 0xE4, 0xFD, 0x7F, +0x8D, 0x12, 0x7B, 0x3E, 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, 0x0C, 0x74, 0xFC, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, 0xEB, 0xF0, +0x22, 0xF5, 0x83, 0xE0, 0xFB, 0x0D, 0x71, 0xB9, 0x90, 0x93, 0x96, 0xE0, 0x22, 0x4F, 0xF0, 0x90, +0x00, 0x02, 0x02, 0x03, 0x0F, 0xF0, 0xEE, 0x54, 0x80, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x22, +0x75, 0xF0, 0x12, 0xE5, 0x6E, 0x90, 0x89, 0x3E, 0x12, 0x05, 0x28, 0xE0, 0x22, 0x8F, 0x6E, 0x8D, +0x6F, 0xEF, 0xF1, 0xA4, 0xE0, 0xF5, 0x70, 0x54, 0x7F, 0xF5, 0x71, 0xE5, 0x70, 0x54, 0x80, 0xF5, +0x73, 0x75, 0xF0, 0x12, 0xEF, 0xF1, 0xFA, 0xF5, 0x75, 0x75, 0xF0, 0x12, 0xEF, 0x51, 0x86, 0xC4, +0x54, 0x03, 0xF5, 0x76, 0xF1, 0x17, 0x74, 0xFF, 0xF0, 0x12, 0xBA, 0xF9, 0xE5, 0x70, 0x45, 0x73, +0xFF, 0x12, 0xBC, 0x09, 0xEF, 0xF0, 0xE5, 0x6E, 0xF1, 0xBC, 0xE0, 0x54, 0x03, 0xF5, 0x74, 0x74, +0x4C, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE5, 0x74, 0xF0, 0xE5, 0x71, 0x65, +0x75, 0x70, 0x42, 0x91, 0x00, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x0C, 0xE5, 0x73, 0x70, 0x08, +0xE5, 0x71, 0x44, 0x80, 0xF5, 0x70, 0xA1, 0x13, 0x12, 0xBA, 0xF9, 0xE5, 0x6E, 0x12, 0xBB, 0x20, +0xE0, 0xFF, 0xA3, 0xE0, 0x12, 0xC3, 0x6B, 0xE4, 0xF0, 0xA3, 0xE5, 0x6E, 0xF0, 0xE4, 0x90, 0x92, +0x49, 0x12, 0x99, 0x30, 0x7B, 0x01, 0xFA, 0x7D, 0x02, 0x7F, 0x04, 0x12, 0x9F, 0x21, 0x7D, 0x07, +0xAF, 0x6E, 0x02, 0xB9, 0x96, 0xE5, 0x71, 0xC3, 0x95, 0x75, 0x50, 0x5F, 0xAB, 0x6E, 0xAD, 0x75, +0xAF, 0x71, 0x12, 0x72, 0xEA, 0x8F, 0x72, 0x85, 0x72, 0x70, 0x91, 0x00, 0xC4, 0x13, 0x54, 0x01, +0xFF, 0x90, 0x92, 0x49, 0xE4, 0x12, 0xC3, 0x6F, 0xE4, 0xF0, 0xA3, 0xE5, 0x72, 0xF0, 0xA3, 0xE4, +0xF0, 0xA3, 0xE5, 0x71, 0xF0, 0xE5, 0x73, 0x71, 0xF9, 0x12, 0xC3, 0xB5, 0xE4, 0xFB, 0xFA, 0x7D, +0x05, 0x7F, 0x04, 0x12, 0x9F, 0x21, 0xE5, 0x71, 0xC3, 0x94, 0x0C, 0x40, 0x26, 0x91, 0x00, 0xC4, +0x13, 0x54, 0x07, 0x30, 0xE0, 0x1D, 0xE5, 0x6F, 0x60, 0x19, 0xE5, 0x73, 0x70, 0x15, 0xE5, 0x71, +0x44, 0x80, 0xF5, 0x70, 0xF1, 0x17, 0xE5, 0x72, 0xF0, 0x80, 0x08, 0x12, 0xBC, 0x09, 0xE5, 0x75, +0xF0, 0xF5, 0x70, 0x90, 0x92, 0x45, 0xE4, 0xF0, 0xA3, 0xE5, 0x70, 0xF0, 0xF1, 0x17, 0xE0, 0xFF, +0x12, 0xC4, 0x0F, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x74, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, +0xE5, 0x6F, 0xF0, 0x7B, 0x01, 0x7A, 0x00, 0x7D, 0x05, 0x7F, 0x04, 0x12, 0x9F, 0x21, 0x90, 0x91, +0x0B, 0xE5, 0x74, 0xF0, 0xAB, 0x6F, 0xAD, 0x70, 0xAF, 0x6E, 0x02, 0x27, 0x3D, 0xD3, 0x10, 0xAF, +0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0xA6, 0xED, 0xF0, 0x90, 0x85, 0xC1, 0xE0, 0xFE, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0xC1, 0xA7, 0xEE, 0x71, 0xF9, 0x30, 0xE0, 0x02, 0xC1, 0xA7, +0x90, 0x85, 0xC8, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0xC1, 0xA7, 0xEF, 0x70, 0x02, 0xC1, 0x12, 0x24, +0xFE, 0x70, 0x02, 0xC1, 0x4F, 0x24, 0xFE, 0x60, 0x4D, 0x24, 0xFC, 0x70, 0x02, 0xC1, 0x8E, 0x24, +0xFC, 0x60, 0x02, 0xC1, 0xA0, 0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, +0x70, 0x05, 0x7F, 0x01, 0x12, 0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, +0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x0F, 0x90, 0x93, 0xA6, 0xE0, 0xFF, 0x60, 0x05, 0x12, +0x6D, 0x4C, 0x80, 0x03, 0x12, 0x79, 0x61, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x08, 0x60, 0x02, 0xC1, +0xA0, 0x12, 0x7A, 0xB9, 0xC1, 0xA0, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x79, +0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, +0x0E, 0x08, 0xD1, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x0C, +0x60, 0x02, 0xC1, 0xA0, 0xD1, 0xAC, 0xEF, 0x64, 0x01, 0x60, 0x02, 0xC1, 0xA0, 0x12, 0x70, 0x9E, +0xC1, 0xA0, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0xD1, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, +0x93, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, +0x0C, 0x08, 0xD1, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x04, +0x70, 0x5E, 0x12, 0xBF, 0x1A, 0xEF, 0x64, 0x01, 0x70, 0x56, 0x12, 0x77, 0xFE, 0x80, 0x51, 0x90, +0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0xD1, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, +0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0C, 0x08, 0xD1, +0xAC, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, +0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x17, 0x12, 0x79, 0xF3, 0x80, 0x12, 0x90, 0x85, +0xC8, 0xE0, 0xB4, 0x0C, 0x0B, 0x12, 0xAB, 0x19, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x12, 0x7A, 0x8A, +0x90, 0x85, 0xC8, 0x12, 0xC3, 0xF5, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x0E, 0x01, 0x80, 0x3B, +0x90, 0x85, 0xC1, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x05, 0x75, 0x0E, 0x02, 0x80, +0x2A, 0x90, 0x85, 0xC7, 0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75, 0x0E, 0x08, 0x80, 0x1C, 0x90, +0x93, 0x09, 0xE0, 0x30, 0xE0, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x05, 0x75, 0x0E, 0x11, +0x80, 0x09, 0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02, +0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x0E, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x86, +0xFA, 0x90, 0x00, 0x01, 0x02, 0x03, 0x0F, 0x74, 0x60, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x93, +0xF5, 0x83, 0x22, 0x8D, 0x78, 0xEF, 0x30, 0xE6, 0x1A, 0xF1, 0xA2, 0xF1, 0xB8, 0xE0, 0x54, 0x03, +0x90, 0x91, 0x0B, 0xF0, 0xE4, 0xFB, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0xF1, 0x95, 0xF1, 0xB1, 0x74, +0x01, 0x80, 0x49, 0xF1, 0xC9, 0x04, 0xF0, 0xF1, 0xC9, 0x64, 0x02, 0x70, 0x1E, 0x74, 0x60, 0x25, +0x78, 0xF1, 0x1B, 0xE0, 0xFD, 0xF4, 0x60, 0x02, 0x80, 0x04, 0xF1, 0xA2, 0xE0, 0xFD, 0xF1, 0xBA, +0x12, 0xC3, 0xD9, 0xF1, 0xA2, 0xF1, 0xB1, 0x74, 0x02, 0x80, 0x21, 0xF1, 0xC9, 0xD3, 0x94, 0x03, +0x40, 0x0D, 0xAF, 0x78, 0x12, 0x6D, 0x94, 0xF1, 0x95, 0xF1, 0xB1, 0x74, 0x03, 0x80, 0x0D, 0xF1, +0xA2, 0xF1, 0xB8, 0x12, 0xC3, 0xD9, 0xF1, 0xA2, 0xF1, 0xB1, 0x74, 0x02, 0xF0, 0xAB, 0x78, 0xE4, +0xFD, 0xFF, 0x02, 0x52, 0xC3, 0x74, 0xBC, 0x25, 0x78, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, +0xE4, 0xF0, 0xE5, 0x78, 0xC4, 0x54, 0xF0, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, +0x22, 0xE0, 0x90, 0x8A, 0x71, 0xF0, 0xA3, 0x22, 0xE0, 0xFD, 0xE5, 0x78, 0xC4, 0x54, 0xF0, 0x24, +0x05, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0x74, 0xBC, 0x25, 0x78, 0xF5, 0x82, 0xE4, +0x34, 0x90, 0xF5, 0x83, 0xE0, 0x22, 0x90, 0x92, 0x07, 0x02, 0x87, 0x03, 0x7F, 0x8F, 0x12, 0x7B, +0x51, 0xEF, 0x22, 0xF0, 0x90, 0x85, 0xC3, 0xE0, 0x54, 0x0F, 0x22, 0xF0, 0x74, 0xCC, 0x2D, 0xF5, +0x82, 0xE4, 0x34, 0x8F, 0x22, 0x41, 0x8E, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x3C, 0x12, 0x05, 0x28, +0xE0, 0x22, 0x8B, 0x5B, 0x8A, 0x5C, 0x89, 0x5D, 0x90, 0x93, 0x13, 0xE0, 0x70, 0x10, 0x12, 0x02, +0xF6, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x06, 0x90, 0x93, 0x19, 0x74, 0x01, 0xF0, 0x90, 0x93, +0x15, 0xE0, 0x70, 0x0F, 0x11, 0xDD, 0xC4, 0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x06, 0x90, 0x93, 0x1A, +0x74, 0x01, 0xF0, 0xAB, 0x5B, 0xAA, 0x5C, 0xA9, 0x5D, 0x12, 0x8F, 0x11, 0xFF, 0xF5, 0x5F, 0x12, +0x02, 0xF6, 0xFE, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0x12, 0x8B, 0xEF, 0xF5, 0x60, 0x80, 0x02, 0x8F, +0x60, 0x85, 0x5F, 0x5E, 0xE5, 0x5E, 0xD3, 0x95, 0x60, 0x50, 0x28, 0x11, 0xDD, 0x54, 0x01, 0xFD, +0xAF, 0x5E, 0x12, 0x6E, 0x5F, 0xAF, 0x5E, 0x12, 0x77, 0x39, 0xEF, 0xAF, 0x5E, 0x70, 0x04, 0x11, +0xA1, 0x80, 0x02, 0xF1, 0x2E, 0x90, 0x93, 0x1A, 0xE0, 0x60, 0x04, 0xAF, 0x5E, 0x11, 0xA1, 0x05, +0x5E, 0x80, 0xD1, 0xE5, 0x5F, 0x70, 0x19, 0xFF, 0x12, 0x77, 0x39, 0xEF, 0x70, 0x12, 0x71, 0x32, +0x12, 0x79, 0x61, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xF7, 0xF0, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, +0x22, 0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x07, 0xEF, 0xF0, 0xA3, +0xED, 0xF0, 0x7D, 0x44, 0x7F, 0x6F, 0x11, 0xE9, 0x11, 0xF4, 0x90, 0x92, 0x08, 0xE0, 0x90, 0x92, +0x07, 0xB4, 0x01, 0x0A, 0xE0, 0x12, 0x8F, 0xBC, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x08, 0xE0, 0x12, +0x8F, 0xBC, 0xE0, 0x54, 0xFB, 0xF0, 0x11, 0xE6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAB, 0x5B, 0xAA, +0x5C, 0xA9, 0x5D, 0x02, 0x02, 0xF6, 0xE4, 0xFD, 0xFF, 0x90, 0x05, 0x22, 0xEF, 0xF0, 0x90, 0x92, +0xE1, 0xED, 0xF0, 0x22, 0xE4, 0x90, 0x93, 0x93, 0xF0, 0xA3, 0xF0, 0x90, 0x05, 0x22, 0xE0, 0x90, +0x93, 0x95, 0xF0, 0x7D, 0x47, 0x7F, 0xFF, 0x11, 0xE9, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x18, 0xA3, +0xE0, 0x70, 0x14, 0xA3, 0xE0, 0x70, 0x10, 0xA3, 0xE0, 0x70, 0x0C, 0x90, 0x93, 0x95, 0xE0, 0xFF, +0x7D, 0x48, 0x11, 0xE9, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x93, 0x94, 0xE0, 0x94, 0xE8, 0x90, 0x93, +0x93, 0xE0, 0x94, 0x03, 0x40, 0x13, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0x93, 0x95, +0xE0, 0xFF, 0x7D, 0x48, 0x11, 0xE9, 0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x7C, 0x9F, +0x90, 0x93, 0x93, 0xF1, 0xE7, 0x80, 0xB2, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, +0xDB, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x84, 0xC3, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, +0x60, 0x32, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x92, 0xDF, 0xF0, 0x7D, 0x26, 0x7F, 0xFF, 0x11, 0xE9, +0x11, 0xF4, 0xEF, 0x64, 0x01, 0x70, 0x0A, 0x31, 0xD9, 0xFB, 0x7D, 0x01, 0x12, 0x3A, 0xC2, 0x31, +0xE3, 0x90, 0x92, 0xDF, 0xE0, 0xFF, 0x7D, 0x27, 0x11, 0xE9, 0x90, 0x92, 0xDB, 0xE0, 0xFF, 0x12, +0x5C, 0xA3, 0x80, 0x18, 0x90, 0x92, 0xDB, 0xE0, 0xFF, 0x12, 0x5C, 0xA3, 0x31, 0xD9, 0xFB, 0x90, +0x93, 0x92, 0x74, 0x0A, 0xF0, 0x7D, 0x01, 0x12, 0xBD, 0x28, 0x31, 0xE3, 0x90, 0x04, 0x1F, 0x74, +0x20, 0xF0, 0x90, 0x84, 0xBF, 0xA3, 0xE0, 0x24, 0x7F, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, +0x74, 0x01, 0xF0, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x84, 0xC8, 0xE0, 0xFF, 0x90, 0x92, +0xDC, 0xE0, 0x22, 0x90, 0x92, 0xDD, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x92, 0xDB, +0xE0, 0xFF, 0x12, 0x65, 0x61, 0x90, 0x92, 0xDD, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x02, 0x50, 0xD7, +0x90, 0x93, 0x09, 0xE0, 0x30, 0xE0, 0x4D, 0x13, 0x13, 0x54, 0x3F, 0x20, 0xE0, 0x14, 0xE4, 0x90, +0x91, 0x6E, 0xF0, 0x90, 0x93, 0x0B, 0x51, 0x6B, 0xE4, 0x51, 0x55, 0x30, 0xE0, 0x02, 0x91, 0x3E, +0x81, 0x45, 0x90, 0x93, 0x09, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x27, 0xE4, 0x90, 0x91, +0x6E, 0xF0, 0x90, 0x93, 0x0C, 0x51, 0x6B, 0x90, 0x93, 0x09, 0xE0, 0x54, 0xFB, 0xF0, 0xE0, 0xC3, +0x13, 0x30, 0xE0, 0x07, 0x7D, 0x04, 0x7F, 0x01, 0x02, 0x57, 0x82, 0x7D, 0x31, 0x7F, 0xFF, 0x11, +0xE9, 0x12, 0xB8, 0xB7, 0x22, 0xFD, 0xFF, 0x11, 0xE9, 0x71, 0x32, 0x90, 0x93, 0x09, 0xE0, 0xC3, +0x13, 0x22, 0xF0, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x86, 0x6E, 0xE0, 0x90, 0x91, 0x6F, 0xF0, +0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x02, 0x61, 0x41, 0xE4, 0xF5, 0x77, 0x90, 0x85, 0xC5, +0xE0, 0x70, 0x02, 0x61, 0x09, 0xF1, 0x4D, 0x60, 0x02, 0x61, 0x09, 0xF1, 0xF5, 0x90, 0x85, 0xC3, +0xE0, 0xC4, 0x54, 0x0F, 0x60, 0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, 0x70, 0x1E, 0x90, 0x85, 0xCC, +0xE0, 0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x85, 0xCE, 0xE0, 0x60, 0x0E, 0xEF, 0x70, 0x08, +0x90, 0x85, 0xCB, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, 0x77, 0x01, 0xE5, 0x77, 0x60, 0x4A, 0x90, +0x85, 0xC8, 0xE0, 0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x8D, 0x4D, 0x90, 0x85, 0xC9, +0xE0, 0x44, 0x10, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0x60, 0x04, 0x64, 0x01, 0x70, 0x13, 0xE4, 0x90, +0x91, 0x6E, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0x71, 0x15, 0x51, 0x6C, 0x90, 0x85, 0xCE, 0xE0, 0x80, +0x12, 0xE4, 0x90, 0x91, 0x6E, 0x71, 0x0A, 0x51, 0x6C, 0x90, 0x85, 0xCE, 0xE0, 0x75, 0xF0, 0x03, +0xA4, 0x24, 0xFE, 0x71, 0x15, 0x90, 0x85, 0xDE, 0xF0, 0x22, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0x75, +0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x85, 0xCD, 0xE0, 0x2F, 0x22, 0x90, 0x93, 0x09, 0xE0, +0x30, 0xE0, 0x0E, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x51, 0x55, 0x30, 0xE0, 0x02, 0x91, 0x3E, 0x91, +0x45, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x02, 0x12, 0x7B, 0x51, 0xEF, 0x44, +0x01, 0xFD, 0x7F, 0x02, 0x12, 0x7B, 0x3E, 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, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x8F, 0xD6, 0x12, 0x02, 0xF6, 0xFF, 0x54, 0x01, 0xFE, 0x90, +0x93, 0x09, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, +0xFF, 0xF0, 0x12, 0x02, 0xF6, 0xFE, 0x54, 0x04, 0x25, 0xE0, 0xFD, 0xEF, 0x54, 0xF7, 0x4D, 0xFF, +0x90, 0x93, 0x09, 0xF0, 0xEE, 0x54, 0x08, 0x25, 0xE0, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xF0, 0x90, +0x05, 0x52, 0xE0, 0x54, 0x07, 0xFF, 0x90, 0x92, 0x07, 0x60, 0x13, 0x12, 0x8F, 0x0E, 0xFD, 0x90, +0x05, 0x56, 0xE0, 0xC3, 0x9D, 0x90, 0x93, 0x0B, 0xF0, 0xA3, 0xED, 0xF0, 0x80, 0x23, 0x12, 0x8F, +0x0E, 0xFB, 0xFF, 0x90, 0x05, 0x54, 0xE0, 0xC3, 0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7C, 0x00, +0x7D, 0x05, 0x12, 0x03, 0x82, 0x90, 0x93, 0x0B, 0xEF, 0xF0, 0xEB, 0x75, 0xF0, 0x05, 0x84, 0xA3, +0xF0, 0x12, 0x89, 0x13, 0x12, 0x02, 0xF6, 0x20, 0xE0, 0x0B, 0x71, 0x32, 0x11, 0xE6, 0x90, 0x01, +0x57, 0xE4, 0xF0, 0x80, 0x04, 0x91, 0x3E, 0x91, 0x45, 0x90, 0x93, 0x09, 0xE0, 0xFF, 0xC4, 0x54, +0x0F, 0x20, 0xE0, 0x04, 0xEF, 0x54, 0xDF, 0xF0, 0x51, 0x5B, 0x30, 0xE0, 0x19, 0x90, 0x85, 0xC5, +0x74, 0x01, 0xF0, 0xE4, 0x90, 0x85, 0xC7, 0xF0, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x04, 0xF0, 0x90, +0x05, 0x58, 0x74, 0x05, 0xF0, 0x22, 0xE4, 0x90, 0x85, 0xC5, 0xF0, 0x90, 0x85, 0xC7, 0x74, 0x0C, +0xF0, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xFE, 0xF0, 0xA3, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x7D, 0x0C, +0x7F, 0x01, 0x02, 0x57, 0x82, 0x90, 0x93, 0x09, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x51, 0x7A, 0xE4, +0xFF, 0xF1, 0xA8, 0x90, 0x92, 0xE3, 0xE0, 0x30, 0xE0, 0x03, 0x12, 0xBE, 0x9E, 0x61, 0x1C, 0x90, +0x93, 0x09, 0xE0, 0x30, 0xE0, 0x0C, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x93, 0x0B, 0x51, 0x6B, +0x91, 0x45, 0x90, 0x84, 0xC5, 0xE0, 0xB4, 0x01, 0x16, 0x90, 0x93, 0x09, 0xE0, 0xFF, 0xC4, 0x54, +0x0F, 0x20, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x54, 0x07, 0x20, 0xE0, 0x03, 0x12, 0xC2, 0xE1, 0x22, +0x7E, 0x00, 0x7F, 0xAC, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x85, 0x79, 0xC1, 0x12, 0x06, 0xDE, 0x90, +0x85, 0xC4, 0x74, 0x02, 0xF0, 0x90, 0x85, 0xCB, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, +0x90, 0x85, 0xD1, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xB1, 0x3F, 0x12, 0xC0, 0xAB, 0xE4, 0xFD, 0xFF, +0x12, 0x57, 0x82, 0x7D, 0x0C, 0x7F, 0x02, 0x12, 0x57, 0x82, 0x91, 0x3E, 0x90, 0x84, 0xC5, 0xE0, +0xFF, 0xB4, 0x01, 0x08, 0x90, 0x85, 0xD0, 0x74, 0xDD, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x85, 0xD0, +0xB4, 0x03, 0x05, 0x74, 0xD4, 0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x2C, 0x12, 0x7B, 0x51, +0xEF, 0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x85, 0xFB, 0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, +0x90, 0x85, 0xFB, 0xF0, 0x90, 0x86, 0x6D, 0x74, 0x03, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, +0x54, 0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0xB1, 0x3F, 0xE4, 0x90, 0x85, 0xD7, 0xF0, 0xA3, +0xF0, 0x7F, 0x01, 0x12, 0x69, 0x33, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x0A, +0xE0, 0x54, 0xF8, 0xF0, 0xE4, 0xFD, 0xFF, 0x11, 0xE9, 0xE4, 0x90, 0x86, 0x71, 0xF0, 0x22, 0xF0, +0x90, 0x85, 0xFB, 0xE0, 0x24, 0x04, 0x90, 0x85, 0xDD, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x22, 0x90, +0x85, 0xC5, 0xE0, 0x70, 0x02, 0xC1, 0x09, 0x90, 0x85, 0xDC, 0xE0, 0x04, 0xF0, 0x90, 0x05, 0x61, +0xD1, 0x29, 0x78, 0x08, 0x12, 0x04, 0xD8, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, +0x05, 0x60, 0xD1, 0x29, 0x12, 0x86, 0xD5, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, +0x05, 0x62, 0xD1, 0x29, 0x78, 0x10, 0x12, 0x04, 0xD8, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, +0x00, 0x12, 0x86, 0xD5, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xA3, 0xD1, 0x29, 0x78, +0x18, 0x12, 0x04, 0xD8, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x86, 0xD5, 0x90, +0x85, 0xFC, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0x1F, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0xC3, +0x13, 0x30, 0xE0, 0x0D, 0x12, 0xAF, 0xB5, 0x12, 0x51, 0x7D, 0x90, 0x93, 0x1F, 0xE0, 0x54, 0xFD, +0xF0, 0x90, 0x85, 0xC2, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x15, 0x90, 0x01, 0x3B, +0xE0, 0x30, 0xE4, 0x0E, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x7C, 0x41, 0x7D, 0x01, 0x7F, 0x02, 0x12, +0x7C, 0x41, 0x90, 0x93, 0xA4, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, +0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0xF1, 0xEE, 0xFF, 0xBF, 0x03, 0x14, 0x90, +0x93, 0x11, 0xE0, 0xB4, 0x01, 0x0D, 0x90, 0x01, 0xB8, 0xE0, 0x04, 0xF0, 0x90, 0x05, 0x21, 0xE0, +0x44, 0x80, 0xF0, 0x7F, 0x01, 0xF1, 0xD8, 0x81, 0x5F, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x22, +0x90, 0x92, 0x04, 0x12, 0x87, 0x03, 0x90, 0x92, 0x03, 0xEF, 0xF0, 0x12, 0x87, 0x0C, 0x96, 0x7E, +0x00, 0x96, 0x87, 0x01, 0x96, 0x8F, 0x08, 0x96, 0x98, 0x09, 0x96, 0xA1, 0x0A, 0x96, 0xAA, 0x12, +0x96, 0xB3, 0x13, 0x96, 0xBC, 0x14, 0x96, 0xC5, 0x20, 0x96, 0xCE, 0x25, 0x96, 0xD7, 0x26, 0x96, +0xDF, 0x40, 0x96, 0xE8, 0x42, 0x96, 0xF1, 0x43, 0x96, 0xFA, 0x44, 0x97, 0x2D, 0x47, 0x97, 0x2D, +0x49, 0x97, 0x03, 0xC2, 0x97, 0x0C, 0xC3, 0x97, 0x15, 0xC4, 0x00, 0x00, 0x97, 0x1E, 0x90, 0x92, +0x04, 0x12, 0x86, 0xFA, 0x02, 0x87, 0xF4, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x01, 0x02, 0x90, +0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x98, 0x1D, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x9F, +0xF7, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0xA0, 0x13, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, +0x02, 0xA7, 0xE4, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0xA7, 0xF8, 0x90, 0x92, 0x04, 0x12, +0x86, 0xFA, 0x02, 0xAF, 0xF6, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x88, 0x45, 0x90, 0x92, +0x04, 0x12, 0x86, 0xFA, 0x02, 0xB0, 0x05, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x61, 0x65, 0x90, +0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x89, 0x19, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x4E, +0x29, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0x28, 0xE6, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, +0x02, 0x62, 0xFC, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0xB0, 0x0D, 0x90, 0x92, 0x04, 0x12, +0x86, 0xFA, 0x02, 0xB0, 0x15, 0x90, 0x92, 0x04, 0x12, 0x86, 0xFA, 0x02, 0xB1, 0xDA, 0x90, 0x01, +0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x92, 0x03, 0xE0, 0x90, 0x01, 0xC2, 0xF0, 0x22, 0xE4, 0xFD, +0x01, 0xA3, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x03, 0x12, 0xAA, 0x9D, 0x41, 0x00, 0xF1, 0x4D, 0x70, +0x0B, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x05, 0x12, 0xAC, 0x3C, 0x51, 0x62, 0x22, 0xE4, 0xFF, 0x12, +0x77, 0x39, 0xEF, 0x64, 0x01, 0x22, 0xE4, 0x90, 0x92, 0xCC, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x60, +0x3B, 0xF1, 0x4D, 0x70, 0x37, 0x90, 0x85, 0xCB, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0xF1, 0xF5, 0x90, +0x92, 0xCC, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x85, 0xCC, 0xF0, 0x04, 0x60, 0x1F, 0x90, 0x85, 0xC8, +0xE0, 0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x8D, 0x4D, 0x90, 0x85, 0xC9, 0xE0, 0x44, +0x10, 0xF0, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x85, 0xCD, 0x51, 0x6B, 0x22, 0xF1, 0x56, 0x7D, +0x02, 0x7F, 0x02, 0x12, 0x7C, 0xA9, 0x7F, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x93, 0x1F, 0xE0, 0xFE, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x18, 0x90, 0x92, 0xCC, 0x74, 0x1E, +0xF0, 0x90, 0x92, 0xDA, 0x74, 0x01, 0xF0, 0x90, 0x92, 0xCE, 0xEF, 0xF0, 0x7B, 0x01, 0x12, 0xAF, +0x7F, 0xF1, 0xD8, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x8F, 0x0D, 0x7F, 0x02, 0x12, 0x86, 0x27, 0x90, +0x84, 0xC1, 0xE0, 0x45, 0x0D, 0xF0, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x07, 0x0A, 0x90, 0x01, +0x02, 0xE0, 0x54, 0x03, 0x22, 0x90, 0x05, 0x63, 0xE0, 0x90, 0x93, 0x28, 0xF0, 0x90, 0x05, 0x62, +0xE0, 0x90, 0x93, 0x29, 0xF0, 0x90, 0x05, 0x61, 0xE0, 0x90, 0x93, 0x2A, 0xF0, 0x90, 0x05, 0x60, +0xE0, 0x90, 0x93, 0x2B, 0xF0, 0x90, 0x93, 0x1F, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x12, 0x8F, 0xD6, +0x12, 0x02, 0xF6, 0x30, 0xE0, 0x13, 0x11, 0xCD, 0x90, 0x84, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x28, +0x90, 0xFE, 0x10, 0xE0, 0x44, 0x04, 0xF0, 0x80, 0x1F, 0x90, 0x93, 0x05, 0xE0, 0x60, 0x16, 0x7D, +0x10, 0xE4, 0xFF, 0x12, 0x7B, 0xBF, 0x90, 0x01, 0x3C, 0xE0, 0x30, 0xE4, 0x03, 0x74, 0x10, 0xF0, +0x90, 0x01, 0x63, 0xE4, 0xF0, 0x12, 0xA7, 0xCA, 0x90, 0x92, 0x07, 0x12, 0x8F, 0x0E, 0x90, 0x92, +0xE4, 0x12, 0x8B, 0xEE, 0x90, 0x92, 0xE5, 0xF0, 0x90, 0x92, 0xE4, 0xE0, 0x54, 0x01, 0x90, 0x92, +0xF1, 0xF0, 0x90, 0x92, 0xE4, 0xE0, 0x54, 0x02, 0x90, 0x92, 0xF2, 0xF0, 0x90, 0x92, 0xE4, 0xE0, +0x54, 0x04, 0x90, 0x92, 0xF3, 0xF0, 0x90, 0x92, 0xE4, 0xE0, 0x54, 0x08, 0x90, 0x92, 0xF4, 0xF0, +0x90, 0x92, 0xE4, 0xE0, 0x54, 0x10, 0x90, 0x92, 0xF5, 0xF0, 0x90, 0x92, 0xE5, 0xE0, 0x54, 0x01, +0x90, 0x92, 0xF6, 0xF0, 0x90, 0x92, 0xE5, 0xE0, 0x54, 0x02, 0x90, 0x92, 0xF7, 0xF0, 0x90, 0x92, +0xE5, 0xE0, 0x54, 0x04, 0x90, 0x92, 0xF8, 0xF0, 0x90, 0x92, 0xE5, 0xE0, 0x54, 0x08, 0x90, 0x92, +0xF9, 0xF0, 0x90, 0x92, 0xE5, 0xE0, 0x54, 0x10, 0x90, 0x92, 0xFA, 0xF0, 0x22, 0x12, 0xA0, 0xFF, +0x90, 0x85, 0xB7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x86, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x92, +0xE3, 0xE0, 0x44, 0x01, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x7C, 0xA9, 0x90, 0x05, 0x52, 0xE0, +0x54, 0x07, 0x04, 0x90, 0x92, 0xEE, 0x31, 0x00, 0x90, 0x04, 0x22, 0xE0, 0x54, 0xEF, 0xF0, 0x22, +0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x92, 0xE3, 0xE0, 0x54, 0xFE, 0x31, 0x00, 0x90, +0x92, 0xEA, 0x31, 0x30, 0x90, 0x93, 0x05, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x93, 0x5F, +0xE0, 0xFF, 0x90, 0x92, 0x45, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, +0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x04, 0x85, 0xE0, 0xF5, 0x6B, 0x90, 0x93, +0x5F, 0xE0, 0x04, 0xF0, 0xE4, 0xF5, 0x62, 0x90, 0x85, 0xBB, 0xE0, 0xFF, 0xE5, 0x62, 0xC3, 0x9F, +0x40, 0x02, 0xE1, 0x1A, 0xE5, 0x62, 0x12, 0x8F, 0xA4, 0xE0, 0xF5, 0x6D, 0x12, 0xC4, 0x29, 0xF5, +0x83, 0xE0, 0x65, 0x6D, 0x60, 0x18, 0x90, 0x8A, 0x71, 0xE5, 0x6D, 0xF0, 0xE4, 0xA3, 0xF0, 0xAB, +0x62, 0xFD, 0xFF, 0x12, 0x52, 0xC3, 0x12, 0xC4, 0x29, 0xF5, 0x83, 0xE5, 0x6D, 0xF0, 0x90, 0x04, +0xA0, 0xE0, 0x64, 0x01, 0x70, 0x50, 0xA3, 0xE0, 0x65, 0x62, 0x70, 0x4A, 0xA3, 0xE0, 0xF5, 0x63, +0xA3, 0xE0, 0x90, 0x92, 0x3E, 0xF0, 0xE5, 0x62, 0x12, 0x8F, 0xA4, 0xE0, 0x65, 0x63, 0x70, 0x02, +0xE1, 0x16, 0xE5, 0x62, 0x12, 0x8F, 0xA4, 0xE5, 0x63, 0xF0, 0xE5, 0x62, 0x12, 0x8F, 0xBC, 0xE0, +0x54, 0xFC, 0xFF, 0x90, 0x92, 0x3E, 0xE0, 0x54, 0x03, 0x4F, 0xFF, 0xE5, 0x62, 0x12, 0x8F, 0xBC, +0xEF, 0xF0, 0x90, 0x8A, 0x71, 0xE5, 0x63, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0xAB, 0x62, 0xE4, 0xFD, +0xFF, 0x12, 0x52, 0xC3, 0xE1, 0x16, 0xAF, 0x62, 0x12, 0x77, 0x39, 0x75, 0xF0, 0x12, 0xE5, 0x62, +0x12, 0x8A, 0x86, 0x12, 0x8B, 0xF9, 0xFD, 0x12, 0xC4, 0x08, 0xED, 0xF0, 0x90, 0x92, 0x47, 0xE4, +0x12, 0xC3, 0x6F, 0xE4, 0xF0, 0xA3, 0xE5, 0x62, 0xF0, 0x12, 0xAF, 0x4C, 0x80, 0x05, 0xC3, 0x33, +0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0xFF, 0x90, 0x92, 0x4B, 0xEE, +0xF0, 0xA3, 0xEF, 0xF0, 0x7B, 0x02, 0x7A, 0x00, 0xE4, 0xFD, 0x7F, 0x01, 0xF1, 0x21, 0x12, 0xBA, +0x0B, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0xBA, 0x00, 0xE0, 0xFD, 0xE5, 0x62, 0x12, 0xAF, 0xC3, +0x54, 0x80, 0xFB, 0x12, 0xC4, 0x08, 0xEB, 0xF0, 0x12, 0xC4, 0x0F, 0xED, 0xF0, 0x90, 0x92, 0x45, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x4B, 0xF0, 0xA3, 0xF0, 0x7B, 0x03, 0xFA, 0xFD, +0x7F, 0x01, 0xF1, 0x21, 0xAF, 0x62, 0x12, 0x77, 0x39, 0xEF, 0x70, 0x02, 0xE1, 0x16, 0x75, 0xF0, +0x12, 0xE5, 0x62, 0x12, 0x8A, 0x86, 0x12, 0x8B, 0xF9, 0x30, 0xE0, 0x02, 0xE1, 0x16, 0xE5, 0x62, +0x12, 0xAF, 0x4C, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, +0xEF, 0x5D, 0x4E, 0x60, 0x02, 0xE1, 0x16, 0x12, 0xBA, 0x0B, 0xE0, 0xFE, 0xA3, 0xE0, 0x4E, 0x70, +0x08, 0x12, 0xBA, 0x00, 0xE0, 0x70, 0x02, 0xE1, 0x16, 0xE5, 0x62, 0x75, 0xF0, 0x12, 0xA4, 0x24, +0x44, 0xF9, 0x74, 0x89, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90, 0x92, 0x33, 0x12, 0x87, 0x03, 0x12, +0xC3, 0xCB, 0x12, 0x03, 0xED, 0x2F, 0xFF, 0xF1, 0xD2, 0x2F, 0xFF, 0x12, 0xC4, 0x02, 0x2F, 0xFF, +0x12, 0xC3, 0x9F, 0x2F, 0xF5, 0x6C, 0x12, 0xBA, 0x0B, 0xE0, 0xF5, 0x68, 0xA3, 0xE0, 0xF5, 0x69, +0x12, 0xBA, 0x00, 0xE0, 0xFF, 0x90, 0x92, 0x36, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x62, 0x12, +0x8F, 0xA4, 0xE0, 0xF5, 0x63, 0x54, 0x80, 0xF5, 0x65, 0xE5, 0x63, 0x54, 0x7F, 0xF5, 0x64, 0x12, +0xC4, 0x20, 0xF1, 0xD8, 0x12, 0xC3, 0xD1, 0x90, 0x92, 0x47, 0xF1, 0xDC, 0xF1, 0xD2, 0xFF, 0x90, +0x92, 0x49, 0xF1, 0xDC, 0x12, 0xC4, 0x02, 0xFF, 0x90, 0x92, 0x4B, 0xF1, 0xDC, 0x7B, 0x01, 0xF1, +0xE3, 0x12, 0xC3, 0x99, 0xF1, 0xD8, 0x90, 0x92, 0x36, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, 0x47, +0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xE5, 0x68, 0xF0, 0xA3, 0xE5, 0x69, 0xF0, 0xA3, 0xE4, 0xF0, +0xA3, 0xE5, 0x63, 0xF0, 0x7B, 0x02, 0xF1, 0xE3, 0x74, 0x7C, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, +0x90, 0xF5, 0x83, 0xE0, 0xC3, 0x94, 0x05, 0x40, 0x02, 0xA1, 0x7A, 0x75, 0xF0, 0x12, 0xE5, 0x62, +0x12, 0x8F, 0xFA, 0xFF, 0xE5, 0x64, 0xD3, 0x9F, 0x40, 0x08, 0x8F, 0x64, 0xE5, 0x64, 0x45, 0x65, +0xF5, 0x63, 0xE5, 0x64, 0x90, 0x82, 0xE1, 0x93, 0xF5, 0x6A, 0xE5, 0x65, 0x60, 0x04, 0x05, 0x6A, +0x05, 0x6A, 0x90, 0x04, 0x8C, 0xE0, 0x64, 0x01, 0x70, 0x28, 0xE5, 0x64, 0xC3, 0x94, 0x0C, 0x40, +0x21, 0x74, 0x84, 0x25, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFF, 0x54, 0x7F, +0xFE, 0xEF, 0x30, 0xE7, 0x06, 0xE5, 0x6A, 0x2E, 0xFF, 0x80, 0x05, 0xC3, 0xE5, 0x6A, 0x9E, 0xFF, +0x8F, 0x6A, 0xE5, 0x6A, 0xD3, 0x94, 0x1A, 0xAF, 0x6A, 0x40, 0x02, 0x7F, 0x1A, 0x8F, 0x6A, 0x31, +0x22, 0x7B, 0x03, 0xFA, 0xF1, 0xE5, 0xE5, 0x63, 0x90, 0x83, 0x59, 0x93, 0xFF, 0xD3, 0x90, 0x92, +0x37, 0xE0, 0x9F, 0x90, 0x92, 0x36, 0xE0, 0x94, 0x00, 0x40, 0x02, 0x80, 0x6B, 0xC3, 0xE5, 0x69, +0x94, 0x0A, 0xE5, 0x68, 0x94, 0x00, 0x40, 0x02, 0x81, 0xB1, 0xF1, 0xB9, 0xE0, 0xC3, 0x94, 0x01, +0x40, 0x05, 0xF1, 0xB9, 0xE0, 0x14, 0xF0, 0x12, 0xC3, 0x99, 0xFF, 0x90, 0x92, 0x37, 0xE0, 0x2F, +0xFF, 0x90, 0x92, 0x36, 0xE0, 0x12, 0xC3, 0x8A, 0xF1, 0xD1, 0x2F, 0xFD, 0xEE, 0x35, 0xF0, 0xFC, +0xE5, 0x68, 0xC3, 0x13, 0xFE, 0xE5, 0x69, 0x13, 0xFF, 0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, 0x31, +0xE5, 0x62, 0x94, 0x05, 0x50, 0x05, 0xF1, 0xB9, 0x74, 0x03, 0xF0, 0x90, 0x92, 0x45, 0xE5, 0x68, +0xF0, 0xA3, 0xE5, 0x69, 0xF0, 0xE5, 0x68, 0xC3, 0x13, 0xA3, 0xF0, 0xE5, 0x69, 0x13, 0xA3, 0xF1, +0x8B, 0x12, 0xC3, 0xB4, 0x7B, 0x01, 0xF1, 0x1B, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0xBB, 0x2C, 0xA1, +0x7A, 0x12, 0xC4, 0x20, 0x65, 0x6C, 0x70, 0x02, 0xE5, 0xF0, 0x70, 0x55, 0x90, 0x92, 0x45, 0xF0, +0xA3, 0xE5, 0x6C, 0xF0, 0xC3, 0x13, 0xFF, 0xA3, 0xE4, 0xF0, 0xA3, 0xEF, 0xF1, 0x8B, 0x12, 0xC3, +0xB4, 0x7B, 0x02, 0xF1, 0x1B, 0xE5, 0x62, 0xC3, 0x94, 0x05, 0x50, 0x0E, 0xF1, 0xB9, 0xE0, 0xD3, +0x94, 0x00, 0x40, 0x06, 0x31, 0x1D, 0x7B, 0x03, 0x80, 0x0B, 0xE5, 0x6C, 0xC3, 0x94, 0x03, 0x50, +0x10, 0x31, 0x1D, 0x7B, 0x04, 0xFA, 0xF1, 0x1D, 0x7D, 0x06, 0xAF, 0x62, 0x12, 0xB9, 0x96, 0xE1, +0x16, 0xE4, 0xFD, 0xAF, 0x62, 0x12, 0x8C, 0x0D, 0x7D, 0x07, 0xAF, 0x62, 0x12, 0xB9, 0x96, 0xA1, +0x7A, 0x31, 0x1D, 0x7B, 0x08, 0xFA, 0xF1, 0x1D, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0x65, 0xC2, 0xA1, +0x7A, 0xF1, 0xB9, 0xE4, 0xF0, 0x90, 0x92, 0x43, 0x74, 0x02, 0xF0, 0xAB, 0x6A, 0xAD, 0x62, 0xAF, +0x69, 0xAE, 0x68, 0x12, 0xBA, 0x16, 0x8E, 0x66, 0x8F, 0x67, 0x12, 0xC3, 0xE7, 0xC3, 0x74, 0x01, +0x93, 0x95, 0x67, 0xE4, 0x93, 0x95, 0x66, 0x50, 0x1F, 0xF1, 0xC5, 0xE4, 0xF0, 0x7D, 0x01, 0xAF, +0x62, 0x12, 0x8C, 0x0D, 0x12, 0xC3, 0x58, 0xE5, 0x66, 0xF0, 0xA3, 0xE5, 0x67, 0xF0, 0xE4, 0x90, +0x92, 0x49, 0x31, 0x30, 0x7B, 0x01, 0x80, 0x28, 0x12, 0xC3, 0xAC, 0xC3, 0xE5, 0x67, 0x9F, 0xE5, +0x66, 0x94, 0x00, 0x50, 0x24, 0xF1, 0xC5, 0xE4, 0xF0, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0xBB, 0x2C, +0x90, 0x92, 0x45, 0x12, 0xC3, 0xA5, 0x12, 0xC4, 0x0F, 0xEF, 0xF0, 0xE4, 0x31, 0x2F, 0x7B, 0x02, +0xFA, 0x7D, 0x05, 0x7F, 0x01, 0xF1, 0x21, 0x80, 0x51, 0x7D, 0x07, 0xAF, 0x62, 0x12, 0xB9, 0x96, +0x12, 0xC3, 0x58, 0x12, 0xC3, 0xA5, 0x12, 0xC4, 0x08, 0xEF, 0xF0, 0xF1, 0xC5, 0x12, 0xC3, 0xB4, +0x7B, 0x03, 0x7A, 0x00, 0x7D, 0x05, 0x7F, 0x01, 0xF1, 0x21, 0xF1, 0xC5, 0xE0, 0x04, 0xF0, 0xE5, +0x64, 0x90, 0x83, 0x6D, 0x93, 0xFF, 0xF1, 0xC5, 0xE0, 0xC3, 0x9F, 0x40, 0x1D, 0xF1, 0xC5, 0xE4, +0x12, 0xC3, 0xAB, 0x12, 0xC3, 0xE7, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x34, 0x00, 0xC3, +0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xE5, 0x62, 0x12, 0xBB, 0x0F, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x90, +0x89, 0x43, 0x12, 0x05, 0x28, 0xE0, 0x64, 0x01, 0x60, 0x02, 0xC1, 0xFB, 0x12, 0xC3, 0xCB, 0xAE, +0xF0, 0x12, 0x03, 0xED, 0x2F, 0xFF, 0xE5, 0xF0, 0x3E, 0xF1, 0xD1, 0x2F, 0xFF, 0xEE, 0x12, 0xC3, +0x8A, 0xFE, 0x90, 0x00, 0x08, 0x12, 0xC3, 0x90, 0x90, 0x92, 0x38, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, +0x03, 0xED, 0xFF, 0xC3, 0x90, 0x92, 0x39, 0xE0, 0x9F, 0xFE, 0x90, 0x92, 0x38, 0xE0, 0x95, 0xF0, +0x90, 0x92, 0x3A, 0xF0, 0xA3, 0xCE, 0xF0, 0x12, 0xC4, 0x02, 0xFD, 0xAC, 0xF0, 0x25, 0xE0, 0xFF, +0xEC, 0x33, 0xFE, 0xEF, 0x2D, 0xFD, 0xEE, 0x3C, 0xFC, 0xF1, 0xD2, 0x25, 0xE0, 0xFF, 0xE5, 0xF0, +0x33, 0xFE, 0x90, 0x00, 0x02, 0x12, 0xC3, 0x90, 0xCF, 0x2D, 0xFD, 0xEF, 0x3C, 0xFC, 0x12, 0xC3, +0x99, 0xAE, 0xF0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xFF, 0xEC, 0x3E, +0x90, 0x92, 0x3C, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x36, 0x12, 0xC3, 0x77, 0x24, 0x0C, 0xF5, +0x82, 0xE4, 0x34, 0x90, 0xF1, 0xEB, 0x50, 0x08, 0x90, 0x92, 0x36, 0x12, 0xC3, 0xBF, 0x80, 0x04, +0x7E, 0xFF, 0x7F, 0xFF, 0xE5, 0x62, 0x25, 0xE0, 0x24, 0x0C, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0x12, +0xBB, 0x18, 0x90, 0x92, 0x38, 0x12, 0xC3, 0x77, 0x24, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF1, +0xEB, 0x50, 0x08, 0x90, 0x92, 0x38, 0x12, 0xC3, 0xBF, 0x80, 0x04, 0x7E, 0xFF, 0x7F, 0xFF, 0xE5, +0x62, 0x25, 0xE0, 0x24, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0x12, 0xBB, 0x18, 0x90, 0x92, 0x3C, +0x12, 0xC3, 0x77, 0x24, 0x5C, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF1, 0xEB, 0x50, 0x08, 0x90, 0x92, +0x3C, 0x12, 0xC3, 0xBF, 0x80, 0x04, 0x7E, 0xFF, 0x7F, 0xFF, 0xE5, 0x62, 0x25, 0xE0, 0x24, 0x5C, +0xF5, 0x82, 0xE4, 0x34, 0x90, 0x12, 0xBB, 0x18, 0xC3, 0x74, 0xFF, 0x95, 0x69, 0xFF, 0x74, 0xFF, +0x95, 0x68, 0xFE, 0x12, 0xC4, 0x16, 0x34, 0x90, 0xF1, 0xEB, 0x50, 0x0A, 0xE5, 0x69, 0x2D, 0xFF, +0xE5, 0x68, 0x3C, 0xFE, 0x80, 0x04, 0x7E, 0xFF, 0x7F, 0xFF, 0x12, 0xC4, 0x16, 0x34, 0x90, 0x12, +0xBB, 0x18, 0x90, 0x92, 0x3A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFB, 0xC3, 0x74, 0xFF, 0x9B, 0xFF, 0x74, +0xFF, 0x9E, 0xFE, 0x74, 0xFF, 0x94, 0x00, 0xFD, 0x74, 0xFF, 0x94, 0x00, 0xFC, 0x90, 0x8F, 0x77, +0x12, 0x86, 0xEE, 0xD3, 0x12, 0x04, 0xB4, 0x50, 0x16, 0x90, 0x92, 0x3A, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0xE4, 0xFC, 0xFD, 0x90, 0x8F, 0x77, 0x12, 0x86, 0xEE, 0x12, 0x86, 0xAD, 0x80, 0x06, 0x74, +0xFF, 0xFF, 0xFE, 0xFD, 0xFC, 0x90, 0x8F, 0x77, 0x12, 0x04, 0xEB, 0xE4, 0xF5, 0x6C, 0xFD, 0xAF, +0x62, 0x12, 0x65, 0xC2, 0xE4, 0x90, 0x92, 0x45, 0xF0, 0x31, 0x2B, 0xA3, 0xF0, 0x7B, 0x01, 0xFA, +0x7D, 0xFF, 0x7F, 0x01, 0xF1, 0x21, 0x05, 0x62, 0x21, 0x47, 0x22, 0x7A, 0x00, 0x7D, 0x03, 0x7F, +0x01, 0x90, 0x01, 0xC6, 0xE0, 0xFE, 0x64, 0x80, 0x70, 0x60, 0x90, 0x92, 0x4F, 0xEF, 0xF0, 0xA3, +0xED, 0xF0, 0xEB, 0xA3, 0xF0, 0xEA, 0xA3, 0xF0, 0x90, 0x92, 0x45, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, +0x92, 0x53, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x47, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x55, +0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x49, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x57, 0xF0, 0xEC, +0xA3, 0xF0, 0x90, 0x92, 0x4B, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x59, 0xF0, 0xEC, 0xA3, 0xF0, +0x90, 0x92, 0x4D, 0x74, 0xFE, 0xF0, 0x90, 0x92, 0x5B, 0x74, 0x0C, 0xF0, 0x7B, 0x01, 0x7A, 0x92, +0x79, 0x4D, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x12, 0x87, 0xDA, 0x22, 0xF0, 0x90, 0x92, 0x33, 0x12, +0x86, 0xFA, 0x90, 0x00, 0x06, 0x12, 0x04, 0x18, 0xFF, 0xAE, 0xF0, 0x90, 0x00, 0x08, 0x12, 0x04, +0x18, 0x2F, 0xFF, 0xE5, 0xF0, 0x3E, 0xFE, 0x90, 0x00, 0x04, 0x12, 0x04, 0x18, 0x2F, 0xFF, 0xEE, +0x35, 0xF0, 0x90, 0x92, 0x49, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x70, 0x25, 0x62, 0xF5, 0x82, 0xE4, +0x34, 0x93, 0xF5, 0x83, 0x22, 0x74, 0xAC, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, +0x22, 0xFE, 0x90, 0x00, 0x04, 0x02, 0x04, 0x18, 0xFF, 0x90, 0x92, 0x45, 0xE5, 0xF0, 0xF0, 0xA3, +0xEF, 0xF0, 0x22, 0x7A, 0x00, 0x7D, 0x01, 0x7F, 0x01, 0xE1, 0x21, 0xF5, 0x83, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0xD3, 0x9F, 0xEC, 0x9E, 0x22, 0x12, 0x8F, 0xD6, 0x12, 0x89, 0x13, 0x12, 0xA0, 0x0C, +0x75, 0x1E, 0x05, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0xFB, 0x02, 0x6A, 0x21, 0x8B, 0x1B, 0x8A, 0x1C, +0x89, 0x1D, 0x22, 0x12, 0x8F, 0xD6, 0x12, 0x89, 0x13, 0x11, 0x0C, 0x75, 0x1E, 0x05, 0x7B, 0x01, +0x7A, 0x93, 0x79, 0x00, 0x02, 0x6A, 0x21, 0x90, 0x92, 0x21, 0xEF, 0xF0, 0xA3, 0x12, 0x87, 0x03, +0x90, 0x93, 0xA0, 0xE0, 0xFE, 0x04, 0xF0, 0x90, 0x00, 0x01, 0xEE, 0x12, 0x03, 0x4E, 0x74, 0x00, +0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x92, +0x22, 0x12, 0x86, 0xFA, 0x11, 0x0C, 0x75, 0x1E, 0x02, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, +0x6A, 0x21, 0x90, 0x92, 0x21, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, +0x03, 0xC0, 0x02, 0xC0, 0x01, 0xA3, 0x12, 0x86, 0xFA, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, +0x1B, 0xF5, 0x1C, 0x89, 0x1D, 0x90, 0x92, 0x22, 0x11, 0x95, 0xF5, 0x1E, 0xD0, 0x01, 0xD0, 0x02, +0xD0, 0x03, 0x02, 0x6A, 0x21, 0x12, 0x86, 0xFA, 0x90, 0x00, 0x0E, 0x02, 0x03, 0x0F, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x25, 0x12, 0x87, 0x03, 0x7F, 0x96, 0x7E, 0x02, 0x12, +0x66, 0x80, 0xEF, 0x60, 0x45, 0x11, 0xFF, 0xFE, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, +0x92, 0x28, 0xEF, 0xF0, 0xEE, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x92, 0x28, 0xE0, 0xFD, 0x90, +0x02, 0x94, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x25, 0x11, 0x95, 0x24, 0x02, 0xFF, 0xE4, 0x33, +0xFE, 0x12, 0x5A, 0xA5, 0x90, 0x92, 0x28, 0xE0, 0x24, 0x18, 0xFF, 0x90, 0x92, 0x25, 0x12, 0x86, +0xFA, 0x12, 0x56, 0xF4, 0x90, 0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, +0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x22, +0x90, 0x93, 0x00, 0xE0, 0x90, 0x92, 0x96, 0xF0, 0x90, 0x93, 0x01, 0xE0, 0x90, 0x92, 0x97, 0xF0, +0x90, 0x93, 0x02, 0xE0, 0x90, 0x92, 0x98, 0xF0, 0x90, 0x93, 0x03, 0xE0, 0x90, 0x92, 0x99, 0xF0, +0x90, 0x93, 0x04, 0xE0, 0x90, 0x92, 0x9A, 0xF0, 0x90, 0x92, 0xF1, 0xE0, 0x90, 0x92, 0x9B, 0xF0, +0x90, 0x92, 0xF2, 0xE0, 0x90, 0x92, 0x9C, 0xF0, 0x90, 0x92, 0xF3, 0xE0, 0x90, 0x92, 0x9D, 0xF0, +0x90, 0x92, 0xF4, 0xE0, 0x90, 0x92, 0x9E, 0xF0, 0x90, 0x92, 0xF5, 0xE0, 0x90, 0x92, 0x9F, 0xF0, +0x90, 0x92, 0xF6, 0xE0, 0x90, 0x92, 0xA0, 0xF0, 0x90, 0x92, 0xF7, 0xE0, 0x90, 0x92, 0xA1, 0xF0, +0x90, 0x92, 0xF8, 0xE0, 0x90, 0x92, 0xA2, 0xF0, 0x90, 0x92, 0xF9, 0xE0, 0x90, 0x92, 0xA3, 0xF0, +0x90, 0x92, 0xFA, 0xE0, 0x90, 0x92, 0xA4, 0xF0, 0xE4, 0x90, 0x92, 0x3F, 0xF0, 0x90, 0x92, 0xAA, +0x12, 0x99, 0x2E, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x50, 0x04, 0xD1, 0x4D, 0x80, 0xF8, 0x90, +0x01, 0x1F, 0xE0, 0xFE, 0x90, 0x01, 0x1E, 0x31, 0x07, 0x90, 0x92, 0x33, 0xF0, 0xA3, 0xEF, 0xF0, +0xE4, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x50, 0x4A, 0xD1, 0x6F, 0x90, 0x92, 0x3E, 0xE0, 0xFE, +0x24, 0xA5, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xD1, 0xD7, 0xE0, 0x24, 0x4D, 0xF5, 0x82, 0xE4, 0x34, +0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x40, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xD1, 0xD7, 0xE0, +0x24, 0x4E, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xEE, 0xF1, 0x07, 0x12, 0x87, 0x03, 0xD1, +0xDB, 0xE0, 0x24, 0x38, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0xEE, 0xD1, 0xC9, 0x12, 0x87, 0x03, 0xD1, +0x5A, 0x80, 0xB2, 0x90, 0x02, 0x87, 0xE0, 0x70, 0x02, 0xC1, 0x32, 0x90, 0x92, 0xE3, 0xE0, 0x20, +0xE0, 0x02, 0xC1, 0x32, 0xE4, 0x90, 0x92, 0xAF, 0x12, 0x99, 0x2E, 0x90, 0x92, 0x33, 0xE0, 0xFF, +0xA3, 0xE0, 0xA3, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x35, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, +0xEC, 0x90, 0xFD, 0x11, 0xF0, 0x74, 0x01, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, +0xFE, 0xD1, 0xF0, 0xE0, 0x7A, 0x00, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x54, 0x3F, 0x90, 0x92, 0x37, +0xF0, 0xA3, 0xF1, 0x58, 0x54, 0x0F, 0x33, 0x33, 0x33, 0x54, 0xF8, 0x90, 0x92, 0x3A, 0xF0, 0xFC, +0x74, 0x07, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0x90, 0x92, 0x3C, +0xF0, 0xEC, 0x24, 0x18, 0x90, 0x92, 0x39, 0xF0, 0xFD, 0x90, 0x92, 0x35, 0xE0, 0xFE, 0xA3, 0xE0, +0xFF, 0x12, 0x55, 0x36, 0xEF, 0x54, 0xFC, 0x90, 0x92, 0x3B, 0xF0, 0x90, 0x92, 0x3A, 0xE0, 0x24, +0x18, 0xFF, 0xE4, 0x33, 0x90, 0x92, 0x37, 0x8F, 0xF0, 0x12, 0x07, 0x0A, 0x90, 0x92, 0x37, 0xE0, +0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x7A, 0xD0, 0x90, 0x92, 0x33, 0xEE, 0x8F, 0xF0, 0x12, 0x07, 0x0A, +0x90, 0x85, 0xB7, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x33, 0x12, 0x9F, 0xED, 0x40, 0x1B, +0x90, 0x85, 0xB8, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x85, 0xB7, 0xE0, 0x34, 0x00, 0xFE, 0xC3, 0xED, +0x9F, 0xFF, 0xEC, 0x9E, 0x90, 0x92, 0x33, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x93, 0x09, 0xE0, 0x30, +0xE0, 0x09, 0x13, 0x13, 0x54, 0x3F, 0x20, 0xE0, 0x02, 0xC1, 0x25, 0x90, 0x92, 0x3B, 0xE0, 0x24, +0xC0, 0x60, 0x02, 0x81, 0xFB, 0xD1, 0x33, 0x24, 0x18, 0xFD, 0x12, 0x55, 0x36, 0xEF, 0x60, 0x02, +0x81, 0xE8, 0xD1, 0x33, 0x24, 0x19, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x92, 0x54, 0xEF, 0xF0, 0xE4, +0x90, 0x92, 0x3D, 0xF0, 0x90, 0x92, 0x54, 0xE0, 0xFF, 0x90, 0x92, 0x3D, 0xE0, 0xFD, 0xC3, 0x9F, +0x50, 0x1A, 0xD1, 0x33, 0x24, 0x1A, 0xFC, 0xED, 0x2C, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x92, 0x3D, +0xE0, 0x24, 0x55, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xD1, 0xB2, 0x80, 0xD8, 0x90, 0x92, 0x54, 0xE0, +0x70, 0x02, 0x81, 0x12, 0xE4, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x40, 0x02, 0x61, 0xFA, 0xD1, +0x6F, 0x90, 0x92, 0x3E, 0xE0, 0xFF, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0xE0, +0xFE, 0x90, 0x92, 0x54, 0xE0, 0xFD, 0xEE, 0x6D, 0x70, 0x20, 0xEF, 0xF1, 0x07, 0x12, 0x86, 0xFA, +0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0xD1, 0xBD, 0x90, 0x92, 0xBA, 0xED, 0xF0, 0xD0, 0x01, 0xD0, +0x02, 0xD0, 0x03, 0xD1, 0x89, 0xEF, 0x60, 0x02, 0x80, 0x53, 0x90, 0x92, 0x54, 0xE0, 0x64, 0x03, +0x70, 0x5A, 0xD1, 0xBD, 0x90, 0x92, 0xBA, 0x74, 0x03, 0xF0, 0x7A, 0x93, 0x79, 0x8B, 0xD1, 0x89, +0xEF, 0x70, 0x11, 0xD1, 0xBD, 0x90, 0x92, 0xBA, 0x74, 0x03, 0xF0, 0x7A, 0x93, 0x79, 0x87, 0xD1, +0x89, 0xEF, 0x60, 0x30, 0x90, 0x92, 0x3E, 0xE0, 0xFF, 0x24, 0xA0, 0xF5, 0x82, 0xE4, 0x34, 0x92, +0xF5, 0x83, 0xE0, 0x60, 0x02, 0x80, 0x11, 0x90, 0x92, 0x3E, 0xE0, 0xFF, 0x24, 0x9B, 0xF5, 0x82, +0xE4, 0x34, 0x92, 0xF5, 0x83, 0xE0, 0x60, 0x05, 0x74, 0xAF, 0x2F, 0x80, 0x15, 0xD1, 0x61, 0x74, +0x01, 0xF0, 0x80, 0x12, 0x90, 0x92, 0x3E, 0xE0, 0x24, 0xAF, 0x80, 0x06, 0x90, 0x92, 0x3E, 0xE0, +0x24, 0xAF, 0xD1, 0x67, 0xE4, 0xF0, 0xD1, 0x5A, 0x61, 0x49, 0x90, 0x92, 0xAF, 0xE0, 0x70, 0x55, +0xA3, 0xE0, 0x70, 0x51, 0xA3, 0xE0, 0x70, 0x4D, 0xA3, 0xE0, 0x70, 0x49, 0xA3, 0xE0, 0x70, 0x45, +0x81, 0xE8, 0xE4, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x50, 0x22, 0x74, 0x9B, 0x2E, 0xF5, 0x82, +0xE4, 0x34, 0x92, 0xF5, 0x83, 0xE0, 0x60, 0x09, 0x74, 0xAF, 0x2E, 0xD1, 0x67, 0xE4, 0xF0, 0x80, +0x08, 0x74, 0xAF, 0x2E, 0xD1, 0x67, 0x74, 0x01, 0xF0, 0xD1, 0x5A, 0x80, 0xDA, 0x90, 0x92, 0xAF, +0xE0, 0x70, 0x12, 0xA3, 0xE0, 0x70, 0x0E, 0xA3, 0xE0, 0x70, 0x0A, 0xA3, 0xE0, 0x70, 0x06, 0xA3, +0xE0, 0x70, 0x02, 0x81, 0xE8, 0xE4, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x40, 0x02, 0x81, 0xE8, +0xD1, 0x6F, 0xD1, 0x61, 0xE0, 0x60, 0x7D, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x10, +0xD3, 0xEF, 0x94, 0xE8, 0xEE, 0x94, 0x03, 0x50, 0x07, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0x80, 0xEA, +0x90, 0x04, 0x1D, 0xE0, 0x70, 0x5E, 0x90, 0x92, 0x3E, 0xE0, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, +0x92, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x93, 0x92, 0x74, 0x06, 0xF0, 0x7B, 0x08, 0x7D, 0x01, 0x12, +0xBD, 0x28, 0x90, 0x92, 0x37, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x3D, 0xF0, 0x90, +0x92, 0x3D, 0xE0, 0xFD, 0xC3, 0x94, 0x06, 0x50, 0x21, 0xD1, 0x33, 0x24, 0x0A, 0xFC, 0xED, 0x2C, +0xFD, 0x12, 0x55, 0x36, 0x90, 0x92, 0x37, 0xA3, 0xE0, 0xFE, 0x90, 0x92, 0x3D, 0xE0, 0x2E, 0x24, +0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xD1, 0xB2, 0x80, 0xD5, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, +0x90, 0x06, 0x35, 0xF0, 0xD1, 0x5A, 0x81, 0x5A, 0x90, 0x92, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x12, 0x7C, 0x0B, 0x90, 0x06, 0x36, 0x74, 0xDD, 0xF0, 0x41, 0x03, 0x90, 0x92, 0x3C, 0xE0, 0x60, +0x02, 0xC1, 0x25, 0xD1, 0x33, 0x24, 0x16, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x06, 0x34, 0xEF, 0xF0, +0xD1, 0x33, 0x24, 0x17, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x06, 0x37, 0xEF, 0xF0, 0xE4, 0x90, 0x92, +0x3E, 0xF0, 0xD1, 0x40, 0x50, 0x67, 0xD1, 0x6F, 0xE4, 0x90, 0x92, 0x3D, 0xF0, 0x90, 0x92, 0x3D, +0xE0, 0xFF, 0xC3, 0x94, 0x06, 0x50, 0x52, 0xEF, 0x60, 0x04, 0x64, 0x01, 0x70, 0x20, 0xD1, 0x33, +0xD1, 0xFB, 0x90, 0x92, 0x3D, 0xE0, 0xFE, 0x24, 0xA0, 0xD1, 0xE6, 0x90, 0x92, 0x3E, 0xE0, 0xD1, +0xC9, 0x12, 0x86, 0xFA, 0x8E, 0x82, 0xD1, 0x83, 0xFF, 0x74, 0xA2, 0x2E, 0xD1, 0xE6, 0xD1, 0x33, +0xD1, 0xFB, 0x90, 0x92, 0x3E, 0xE0, 0xFE, 0xD1, 0xC9, 0x12, 0x86, 0xFA, 0x90, 0x92, 0x3D, 0xE0, +0xF5, 0x82, 0xD1, 0x83, 0x6F, 0x60, 0x0E, 0x74, 0xAA, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, +0x83, 0xE4, 0xF0, 0x80, 0x04, 0xD1, 0xB6, 0x80, 0xA4, 0xD1, 0x5A, 0x80, 0x95, 0x90, 0x92, 0xAA, +0xE0, 0x64, 0x01, 0x60, 0x17, 0xA3, 0xE0, 0x64, 0x01, 0x60, 0x11, 0xA3, 0xE0, 0x64, 0x01, 0x60, +0x0B, 0xA3, 0xE0, 0x64, 0x01, 0x60, 0x05, 0xA3, 0xE0, 0xB4, 0x01, 0x06, 0x90, 0x92, 0x3F, 0x74, +0x01, 0xF0, 0x90, 0x92, 0x3F, 0xE0, 0x64, 0x01, 0x70, 0x54, 0xF1, 0xCA, 0x90, 0x01, 0xC7, 0x74, +0x66, 0xF0, 0xE4, 0xFF, 0x12, 0x5F, 0xE9, 0x90, 0x93, 0x05, 0xE0, 0x70, 0x02, 0x41, 0x03, 0x90, +0x01, 0x3C, 0xE0, 0x30, 0xE4, 0x03, 0x74, 0x10, 0xF0, 0x7D, 0x10, 0xE4, 0xFF, 0x12, 0x7B, 0xFD, +0x90, 0x93, 0x06, 0xE0, 0x60, 0x08, 0xF5, 0x25, 0xE4, 0xF5, 0x26, 0xFB, 0x80, 0x15, 0x90, 0x93, +0x07, 0xE0, 0x60, 0x08, 0xFB, 0xE4, 0xF5, 0x25, 0xF5, 0x26, 0x80, 0x07, 0x75, 0x25, 0x20, 0xE4, +0xF5, 0x26, 0xFB, 0x7D, 0x01, 0x7F, 0x60, 0x7E, 0x01, 0x12, 0x76, 0x3D, 0x41, 0x03, 0xE4, 0x90, +0x92, 0x3F, 0xF0, 0x90, 0x92, 0xAA, 0x12, 0x99, 0x2E, 0x90, 0x92, 0x3E, 0xF0, 0xD1, 0x40, 0x50, +0x04, 0xD1, 0x4D, 0x80, 0xF8, 0x90, 0x92, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x7C, 0x0B, +0x41, 0x03, 0x22, 0x90, 0x92, 0x35, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x39, 0xE0, 0x22, +0x90, 0x92, 0xEE, 0xE0, 0xFF, 0x90, 0x92, 0x3E, 0xE0, 0xFE, 0xC3, 0x9F, 0x22, 0x74, 0xAA, 0x2E, +0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x3E, 0xE0, 0x04, 0xF0, +0x22, 0x90, 0x92, 0x3E, 0xE0, 0x24, 0xAF, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0x74, +0x96, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0xE0, 0xFF, 0x02, 0x7B, 0x2A, 0x12, 0x86, +0xFA, 0x8F, 0x82, 0x75, 0x83, 0x00, 0x02, 0x03, 0x0F, 0x90, 0x92, 0xB4, 0x12, 0x87, 0x03, 0xE4, +0xFF, 0x90, 0x92, 0xBA, 0xE0, 0xFE, 0xEF, 0xC3, 0x9E, 0x50, 0x14, 0x90, 0x92, 0xB7, 0xD1, 0x7E, +0xFE, 0x90, 0x92, 0xB4, 0xD1, 0x7E, 0x6E, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x0F, 0x80, 0xE2, 0x7F, +0x01, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x92, 0x3D, 0xE0, 0x04, 0xF0, 0x22, 0x7B, 0x01, 0x7A, +0x92, 0x79, 0x55, 0x90, 0x92, 0xB7, 0x02, 0x87, 0x03, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x87, 0xF5, +0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0xA5, 0x2E, 0xF5, 0x82, +0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEF, 0xF0, 0x22, +0x74, 0x00, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0x24, 0x04, 0xFD, 0x90, 0x92, +0x3D, 0xE0, 0x2D, 0xFD, 0x02, 0x55, 0x36, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x45, 0xF5, 0x82, 0xE4, +0x34, 0x92, 0xF5, 0x83, 0x22, 0xE4, 0xFC, 0xED, 0x2C, 0x24, 0x00, 0xD1, 0xF3, 0xE4, 0xF0, 0x0C, +0xEC, 0xB4, 0x18, 0xF3, 0xD1, 0xF0, 0xEF, 0xF0, 0xEE, 0x54, 0x3F, 0xFF, 0x74, 0x01, 0x2D, 0xF5, +0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xF1, 0x58, 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, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, +0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x86, 0x4E, 0x90, +0x92, 0x32, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x84, 0xC1, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60, +0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE0, 0x0F, 0x90, 0x84, 0xC1, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, +0x12, 0x2D, 0xBD, 0x12, 0x99, 0x38, 0xF1, 0xC0, 0x30, 0xE1, 0x06, 0x54, 0xFD, 0xF0, 0x12, 0x60, +0x5D, 0xF1, 0xC0, 0x30, 0xE2, 0x06, 0x54, 0xFB, 0xF0, 0x12, 0x6A, 0x6D, 0xF1, 0xC0, 0x30, 0xE5, +0x0B, 0x54, 0xDF, 0xF0, 0x12, 0x6F, 0x22, 0xBF, 0x01, 0x02, 0x31, 0x10, 0xD2, 0xAF, 0x80, 0xB6, +0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x84, 0xC1, 0xE0, 0xFF, 0x22, 0xC2, 0xAF, 0x90, 0x92, 0xE3, 0xE0, +0x54, 0xFE, 0xF0, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x7C, 0x41, 0xE4, 0x90, 0x92, 0xEF, 0xF0, 0xA3, +0xF0, 0xD2, 0xAF, 0x22, 0x12, 0x02, 0xF6, 0xFF, 0x90, 0x93, 0x08, 0xF0, 0xBF, 0x01, 0x08, 0x12, +0xB1, 0x2A, 0xE4, 0x90, 0x93, 0x08, 0xF0, 0x22, 0x12, 0x02, 0xF6, 0xFF, 0x54, 0x80, 0xFE, 0x90, +0x89, 0x16, 0xE0, 0x54, 0x7F, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x40, 0xFF, 0xEE, 0x54, 0xBF, 0x4F, +0xFF, 0xF0, 0x12, 0x02, 0xF6, 0xFE, 0x54, 0x20, 0xFD, 0xEF, 0x54, 0xDF, 0x4D, 0xFF, 0x90, 0x89, +0x16, 0xF0, 0xEE, 0x54, 0x10, 0xFE, 0xEF, 0x54, 0xEF, 0x4E, 0xFF, 0xF0, 0x12, 0x02, 0xF6, 0x54, +0x0F, 0xFE, 0xEF, 0x54, 0xF0, 0x4E, 0x90, 0x89, 0x16, 0xF0, 0x12, 0x8F, 0x11, 0xFF, 0x54, 0x7F, +0x90, 0x89, 0x18, 0xF0, 0xEF, 0x12, 0x8B, 0xF7, 0xFF, 0x90, 0x89, 0x17, 0xE0, 0x54, 0xFE, 0x12, +0x8B, 0xED, 0x90, 0x89, 0x19, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x03, 0x0F, 0x54, 0x01, 0x25, 0xE0, +0xFF, 0x90, 0x89, 0x17, 0xE0, 0x54, 0xFD, 0x4F, 0xF0, 0x11, 0x73, 0x20, 0xE0, 0x02, 0x7D, 0x01, +0x02, 0x54, 0x9F, 0x90, 0x89, 0x16, 0xE0, 0xFE, 0x54, 0x0F, 0xFF, 0xEE, 0xC4, 0x13, 0x13, 0x54, +0x03, 0x7D, 0x00, 0x22, 0x90, 0x89, 0x16, 0xE0, 0xFF, 0x12, 0x8B, 0xF9, 0x30, 0xE0, 0x1A, 0xEF, +0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x02, 0x11, 0xAA, 0x90, 0x89, 0x17, 0xE0, 0x30, 0xE0, 0x0A, 0x11, +0x73, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x12, 0x54, 0x9F, 0x22, 0xE4, 0x90, 0x92, 0xCE, 0xF0, 0x90, +0x92, 0xCC, 0x74, 0x14, 0xF0, 0x90, 0x92, 0xDA, 0x74, 0x01, 0xF0, 0xFB, 0xF1, 0x7F, 0x02, 0x87, +0xDA, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x15, 0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x05, 0x12, 0x6B, +0x98, 0x80, 0x09, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xF7, 0xF0, 0x11, 0xDE, 0x80, 0xA6, 0x90, 0x85, +0xC7, 0xE0, 0xFF, 0x7D, 0x01, 0x02, 0x8D, 0x4D, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, 0x01, 0x0F, +0x90, 0x85, 0xC5, 0xE0, 0x60, 0x09, 0x31, 0x00, 0xF0, 0x54, 0x07, 0x70, 0x02, 0x11, 0xDE, 0x22, +0x90, 0x85, 0xC9, 0xE0, 0x54, 0xFE, 0x22, 0xE4, 0xF5, 0x77, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x77, +0x54, 0xC0, 0x70, 0x08, 0x31, 0x00, 0xF0, 0x54, 0xFD, 0xF0, 0x80, 0xC2, 0xE5, 0x77, 0x30, 0xE6, +0x1F, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x1A, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x01, 0x12, +0x8F, 0xE3, 0x64, 0x02, 0x60, 0x05, 0x12, 0x77, 0x61, 0x80, 0x08, 0x12, 0x79, 0x41, 0x80, 0x03, +0x31, 0x00, 0xF0, 0xE5, 0x77, 0x90, 0x85, 0xC9, 0x30, 0xE7, 0x0E, 0xE0, 0x44, 0x02, 0x12, 0x92, +0x62, 0x90, 0x85, 0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x12, 0x97, +0x4D, 0x70, 0x13, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0D, 0x91, 0x3C, 0xF0, 0x90, 0x85, 0xC1, 0xE0, +0x91, 0x47, 0x70, 0x02, 0x11, 0xDE, 0x22, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, +0x03, 0x30, 0xE0, 0x1E, 0xEF, 0x54, 0xBF, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x85, 0xC2, 0x30, +0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x08, 0xE0, 0x54, 0xFE, 0x51, 0x5F, 0x74, 0x04, 0xF0, +0x11, 0xDE, 0x22, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x12, 0x8B, 0xF9, 0x30, 0xE0, 0x23, 0xEF, 0x54, +0x7F, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x85, 0xC2, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, +0x80, 0x07, 0xE0, 0x54, 0xFD, 0x51, 0x5F, 0x04, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x02, 0x11, +0xDE, 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, 0xD2, 0xF0, 0x74, 0xA9, 0xA3, 0xF0, 0x12, 0x75, 0x28, 0xE5, 0x56, 0x30, 0xE1, +0x03, 0x12, 0x97, 0x32, 0xE5, 0x56, 0x30, 0xE2, 0x02, 0x11, 0xC1, 0xE5, 0x56, 0x30, 0xE4, 0x02, +0xF1, 0x9D, 0xE5, 0x57, 0x30, 0xE0, 0x02, 0x51, 0x6A, 0xE5, 0x59, 0x30, 0xE1, 0x05, 0x7F, 0x04, +0x12, 0x97, 0xD8, 0xE5, 0x59, 0x30, 0xE4, 0x03, 0x12, 0x97, 0x9D, 0xE5, 0x59, 0x30, 0xE5, 0x02, +0x31, 0x77, 0xE5, 0x59, 0x30, 0xE6, 0x02, 0x31, 0xA3, 0x74, 0xD2, 0x04, 0x90, 0x01, 0xC4, 0xF0, +0x74, 0xA9, 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, 0xF0, +0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x22, 0x12, 0xBE, 0x4F, 0x90, 0x92, 0xCC, +0xEF, 0xF0, 0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x57, 0x82, +0x90, 0x92, 0xCC, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, +0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0xF1, 0xB5, 0x02, 0x51, 0x7D, 0x71, 0x19, 0x13, +0x54, 0x1F, 0x30, 0xE0, 0x10, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x07, 0x7D, 0x02, +0x7F, 0x02, 0x12, 0x7C, 0x41, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, +0x07, 0xEF, 0x91, 0x47, 0x70, 0x52, 0x80, 0x4E, 0x90, 0x85, 0xCE, 0xE0, 0x04, 0xF0, 0x90, 0x85, +0xC9, 0xE0, 0x54, 0xEF, 0xF0, 0xF1, 0x89, 0xD3, 0x9F, 0x40, 0x3B, 0x12, 0x97, 0x4D, 0x70, 0x38, +0x12, 0x8F, 0xE4, 0x70, 0x0B, 0x12, 0x70, 0xDB, 0x90, 0x85, 0xC2, 0xE0, 0x54, 0xFB, 0xF0, 0x22, +0x12, 0x70, 0xDB, 0x90, 0x85, 0xCF, 0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0x02, 0x40, 0x0E, 0x90, +0x85, 0xC2, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0x90, 0x85, 0xCF, 0xF0, 0x80, 0x03, 0x12, 0x79, 0x41, +0xE4, 0x90, 0x85, 0xCE, 0xF0, 0x22, 0x11, 0xDE, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0xFF, 0x13, 0x13, +0x22, 0x12, 0x97, 0x4D, 0x60, 0x02, 0x81, 0x3B, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0x81, 0x3B, +0x90, 0x05, 0x63, 0xE0, 0x90, 0x93, 0x24, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0x90, 0x93, 0x25, 0xF0, +0x90, 0x05, 0x61, 0xE0, 0x90, 0x93, 0x26, 0xF0, 0x90, 0x05, 0x60, 0xE0, 0x90, 0x93, 0x27, 0xF0, +0x91, 0x3C, 0xF0, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xEC, 0xF0, 0x90, 0x85, 0xC3, 0xE0, 0xFF, 0xC4, +0x54, 0x0F, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x02, 0x31, 0x07, 0x90, 0x85, 0xC3, 0xE0, 0xFF, 0xC4, +0x54, 0x0F, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x85, 0xCC, 0xF0, 0x90, 0x06, +0xAA, 0xE0, 0x90, 0x85, 0xCB, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x85, 0xCB, 0xE0, 0xFE, +0xFF, 0x80, 0x00, 0x90, 0x85, 0xCC, 0xEF, 0xF0, 0x12, 0xC0, 0xC3, 0xE4, 0x90, 0x85, 0xCE, 0xF0, +0xF1, 0x93, 0x71, 0x19, 0x13, 0x54, 0x1F, 0x20, 0xE0, 0x02, 0x81, 0x34, 0xEF, 0xC4, 0x13, 0x13, +0x54, 0x03, 0x20, 0xE0, 0x3B, 0x90, 0x85, 0xCB, 0xE0, 0xFF, 0xA3, 0xE0, 0x6F, 0x70, 0x75, 0x90, +0x85, 0xC2, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x85, 0xCB, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x90, 0x01, +0x3F, 0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x12, 0x7B, 0xFD, 0x7D, 0x01, 0x7F, 0x02, 0x12, 0x7C, +0x41, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x7C, 0x41, 0x90, 0x85, 0xCC, 0xE0, 0x14, 0xF0, 0x80, 0x44, +0x90, 0x85, 0xC3, 0xE0, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x39, 0x90, 0x85, 0xCB, 0xE0, 0xFF, +0xA3, 0xE0, 0xFE, 0x6F, 0x60, 0x2E, 0x90, 0x05, 0x73, 0xE0, 0xFF, 0xEE, 0x6F, 0x60, 0x25, 0x71, +0x19, 0x54, 0x3F, 0x30, 0xE0, 0x1E, 0xEF, 0x54, 0xBF, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10, 0xF0, +0xFD, 0x7F, 0x03, 0x12, 0x7B, 0xBF, 0x7D, 0x01, 0x7F, 0x02, 0x12, 0x7C, 0xA9, 0x7D, 0x02, 0x7F, +0x02, 0x12, 0x7C, 0xA9, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x01, 0x57, 0xE4, +0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0x22, 0x54, 0xFB, 0xF0, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xFD, +0xF0, 0x54, 0x07, 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, 0x54, 0xF0, 0x74, 0xAC, 0xA3, 0xF0, 0x12, 0x71, 0x90, 0xE5, 0x4C, +0x30, 0xE1, 0x02, 0xB1, 0x89, 0xE5, 0x4C, 0x30, 0xE3, 0x02, 0xF1, 0xA8, 0xE5, 0x4C, 0x30, 0xE4, +0x02, 0xF1, 0x77, 0xE5, 0x4C, 0x30, 0xE5, 0x03, 0x12, 0xBC, 0xEC, 0xE5, 0x4E, 0x30, 0xE0, 0x03, +0x12, 0x94, 0x4D, 0xE5, 0x4E, 0x30, 0xE1, 0x03, 0x12, 0x95, 0x4F, 0xE5, 0x4E, 0x30, 0xE2, 0x02, +0xF1, 0x3B, 0xE5, 0x4E, 0x30, 0xE3, 0x03, 0x12, 0x97, 0x3D, 0xE5, 0x4E, 0x30, 0xE4, 0x02, 0x31, +0x5E, 0xE5, 0x4E, 0x30, 0xE5, 0x03, 0x12, 0xB8, 0x37, 0xE5, 0x4E, 0x30, 0xE6, 0x02, 0x11, 0xE8, +0xE5, 0x4E, 0x30, 0xE7, 0x02, 0xF1, 0xE0, 0xE5, 0x4F, 0x30, 0xE0, 0x02, 0xF1, 0xD1, 0xE5, 0x4F, +0x30, 0xE1, 0x02, 0xD1, 0x07, 0xE5, 0x4F, 0x30, 0xE4, 0x02, 0xF1, 0x6B, 0xE5, 0x4F, 0x30, 0xE5, +0x02, 0xB1, 0x19, 0x74, 0x54, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xAC, 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, 0x77, 0x90, 0x85, 0xBB, 0xE0, +0xFF, 0xE5, 0x77, 0xC3, 0x9F, 0x50, 0x61, 0xAF, 0x77, 0x12, 0x77, 0x39, 0xEF, 0x60, 0x55, 0xE5, +0x77, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE5, 0x77, 0x54, 0x07, 0xFE, 0x74, 0x75, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFD, 0xAF, 0x06, 0xF1, 0x63, 0x80, 0x05, 0xC3, 0x33, +0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x60, 0x2A, 0xE5, 0x77, 0xF1, 0xC3, 0x20, 0xE7, +0x02, 0x80, 0x13, 0xE5, 0x77, 0xC4, 0x54, 0xF0, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, +0x83, 0xE0, 0xFF, 0x20, 0xE7, 0x09, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x20, 0xF0, 0x80, 0x05, 0xAD, +0x77, 0x12, 0x8F, 0x23, 0x05, 0x77, 0x80, 0x94, 0x22, 0xE4, 0xFF, 0x90, 0x92, 0xBB, 0xEF, 0xF0, +0x90, 0x04, 0x7E, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, 0xCB, 0xF0, 0xE0, 0xFE, 0x6F, 0x60, 0x66, +0x90, 0x92, 0xBC, 0x74, 0x03, 0xF0, 0x90, 0x92, 0xCA, 0x74, 0x08, 0xF0, 0xEE, 0x04, 0x54, 0x0F, +0xFF, 0xE4, 0xFE, 0xEF, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, +0x83, 0xE5, 0x82, 0x2E, 0xD1, 0x17, 0xE0, 0xFD, 0x74, 0xBE, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, +0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x08, 0xDA, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0xBC, 0x12, +0x5E, 0x10, 0x90, 0x92, 0xCB, 0xE0, 0x04, 0x54, 0x0F, 0xFF, 0xF0, 0xBF, 0x0F, 0x02, 0xE4, 0xF0, +0x90, 0x92, 0xCB, 0xE0, 0x90, 0x04, 0x7F, 0xF0, 0x90, 0x92, 0xBB, 0xE0, 0x7F, 0x04, 0x70, 0x03, +0x02, 0x97, 0xD8, 0x12, 0x87, 0xDA, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x03, 0x12, 0xC2, 0xB6, +0x22, 0x12, 0x05, 0x28, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0x22, 0x90, +0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x92, 0x01, 0xF0, 0x90, 0x92, 0x01, 0xE0, 0xFD, 0x70, 0x02, +0xE1, 0x1F, 0x90, 0x85, 0x1D, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, +0x14, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, +0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x93, 0x9F, 0xE0, 0xF1, 0x62, +0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xE1, 0x02, +0xE4, 0x90, 0x92, 0x02, 0xF0, 0x90, 0x92, 0x02, 0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x34, 0xF1, +0x21, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0xF1, +0x29, 0x90, 0x84, 0xCD, 0xD1, 0x11, 0xEF, 0xF1, 0x20, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, +0x74, 0xF0, 0xF1, 0x29, 0x90, 0x84, 0xD1, 0xD1, 0x11, 0xEF, 0xF0, 0x90, 0x92, 0x02, 0xE0, 0x04, +0xF0, 0x80, 0xC2, 0x90, 0x92, 0x01, 0xE0, 0xFF, 0x90, 0x93, 0x9F, 0xE0, 0xFE, 0x74, 0x01, 0xA8, +0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, 0x90, 0x92, 0x01, 0xF0, 0x90, 0x93, +0x9F, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, +0xCC, 0xF0, 0x90, 0x93, 0x9F, 0xE0, 0x04, 0xF0, 0xE0, 0x54, 0x03, 0xF0, 0x90, 0x85, 0x1E, 0xF1, +0x70, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, 0x02, 0xC1, 0x29, 0xE4, 0x90, 0x85, 0x1E, 0xF0, +0xC1, 0x29, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, 0xF0, 0x90, 0x93, 0x9F, 0xE0, 0x44, 0x80, 0x90, +0x00, 0x8A, 0xF1, 0x20, 0x90, 0x01, 0xD0, 0x12, 0x05, 0x28, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, +0xF0, 0x90, 0x93, 0x9F, 0xE0, 0x75, 0xF0, 0x04, 0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, +0x83, 0xE0, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0x75, 0xF0, 0x08, 0x22, 0x90, 0x85, 0xC8, 0xE0, 0x64, +0x02, 0x60, 0x08, 0x71, 0x21, 0x90, 0x01, 0xE6, 0xE0, 0x04, 0xF0, 0x22, 0x13, 0x13, 0x13, 0x54, +0x1F, 0x24, 0x75, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFD, 0x7C, 0x00, 0xE5, 0x62, +0x54, 0x07, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x22, 0xE4, 0xFF, 0x02, 0x2D, 0xBD, +0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22, 0x12, 0x40, 0xB9, 0x7F, 0x02, 0x02, 0x97, 0xD8, 0x7A, +0x92, 0x79, 0xCC, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x22, 0x90, 0x86, 0x6D, 0xE0, 0xFF, 0x90, 0x85, +0xCE, 0xE0, 0x22, 0x90, 0x85, 0xD1, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0x90, 0x01, 0xC7, +0x74, 0x66, 0xF0, 0xE4, 0xFF, 0x02, 0x5F, 0xE9, 0x90, 0x92, 0xE3, 0xE0, 0x30, 0xE0, 0x05, 0x7F, +0x20, 0x12, 0x97, 0xD8, 0x22, 0x90, 0x85, 0xD7, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x85, 0xDE, +0xE0, 0xFB, 0x22, 0xC4, 0x54, 0xF0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, +0x22, 0x12, 0x97, 0xEE, 0xFF, 0xBF, 0x03, 0x07, 0x90, 0x05, 0x21, 0xE0, 0x54, 0x7F, 0xF0, 0x22, +0xE4, 0xF5, 0x77, 0xF5, 0x78, 0xF5, 0x79, 0x12, 0x97, 0xEE, 0xFF, 0xBF, 0x03, 0x07, 0x90, 0x05, +0x21, 0xE0, 0x54, 0x7F, 0xF0, 0x22, 0x12, 0x02, 0xF6, 0x54, 0x01, 0xFF, 0x90, 0x93, 0x1E, 0xE0, +0x54, 0xFE, 0x4F, 0xF0, 0x22, 0x12, 0x02, 0xF6, 0x90, 0x86, 0x71, 0xF0, 0x22, 0x12, 0x02, 0xF6, +0x90, 0x93, 0x11, 0xF0, 0x22, 0x12, 0x02, 0xF6, 0xFF, 0x90, 0x93, 0x12, 0xF0, 0xBF, 0x01, 0x07, +0x11, 0x28, 0xE4, 0x90, 0x93, 0x12, 0xF0, 0x22, 0x31, 0x1C, 0x7F, 0xF4, 0x7E, 0x00, 0x12, 0x64, +0x37, 0xBF, 0x01, 0x06, 0x90, 0x92, 0x16, 0xE0, 0xA3, 0xF0, 0x31, 0x1C, 0x7F, 0xF5, 0x7E, 0x00, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x18, 0xF0, 0x31, 0x1C, +0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, +0x19, 0xF0, 0x31, 0x1C, 0x7F, 0xF7, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, +0x16, 0xE0, 0x90, 0x92, 0x1A, 0xF0, 0x31, 0x1C, 0x7F, 0xF8, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, +0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1B, 0xF0, 0x31, 0x1C, 0x7F, 0xF9, 0x7E, 0x00, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1C, 0xF0, 0x31, 0x1C, +0x7F, 0xFB, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, +0x1D, 0xF0, 0x31, 0x1C, 0x7F, 0xFD, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, +0x16, 0xE0, 0x90, 0x92, 0x1E, 0xF0, 0x90, 0x92, 0x07, 0x74, 0x19, 0xF0, 0x90, 0x92, 0x15, 0x74, +0x08, 0xF0, 0x90, 0x92, 0x17, 0xE0, 0x90, 0x92, 0x09, 0xF0, 0x90, 0x92, 0x18, 0xE0, 0x90, 0x92, +0x0A, 0xF0, 0x90, 0x92, 0x19, 0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x90, 0x92, 0x1A, 0xE0, 0x90, 0x92, +0x0C, 0xF0, 0x90, 0x92, 0x1B, 0xE0, 0x90, 0x92, 0x0D, 0xF0, 0x90, 0x92, 0x1C, 0xE0, 0x90, 0x92, +0x0E, 0xF0, 0x90, 0x92, 0x1D, 0xE0, 0x90, 0x92, 0x0F, 0xF0, 0x90, 0x92, 0x1E, 0xE0, 0x90, 0x92, +0x10, 0xF0, 0x31, 0x23, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x02, 0x87, 0xDA, 0x7B, 0x01, 0x7A, 0x92, +0x79, 0x16, 0x22, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x07, 0x22, 0x31, 0x23, 0x7F, 0xF5, 0x7E, 0x01, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x06, 0x90, 0x92, 0x07, 0xE0, 0xA3, 0xF0, 0x31, 0x23, 0x7F, 0xF6, +0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x09, 0xF0, +0x31, 0x23, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, +0x90, 0x92, 0x0A, 0xF0, 0x31, 0x23, 0x7F, 0xF3, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, +0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x31, 0x23, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x64, +0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x0C, 0xF0, 0x90, 0x92, 0x08, 0xE0, +0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x92, 0x10, 0xF0, 0x90, 0x92, 0x0C, +0xE0, 0x90, 0x92, 0x11, 0xF0, 0x90, 0x92, 0x12, 0x74, 0x12, 0xF0, 0x90, 0x92, 0x20, 0x74, 0x05, +0xF0, 0x90, 0x92, 0x14, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x92, 0x10, 0xE0, +0x90, 0x92, 0x17, 0xF0, 0x90, 0x92, 0x11, 0xE0, 0x90, 0x92, 0x18, 0xF0, 0x7B, 0x01, 0x7A, 0x92, +0x79, 0x12, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x02, 0x87, 0xDA, 0x12, 0x02, 0xF6, 0x90, 0x93, 0x05, +0xF0, 0x12, 0x8F, 0x11, 0x90, 0x93, 0x06, 0x12, 0x8B, 0xEE, 0x90, 0x93, 0x07, 0xF0, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x85, 0x1E, 0xE0, 0xFF, 0x90, 0x85, 0x1D, 0xE0, 0xB5, +0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x48, 0x90, 0x85, 0x1D, 0xE0, 0xFE, +0x75, 0xF0, 0x08, 0x90, 0x84, 0xCD, 0x12, 0x05, 0x28, 0xE0, 0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, +0x24, 0xCE, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF, 0x05, 0x12, 0x96, 0x30, 0x90, +0x85, 0x1D, 0x12, 0xAF, 0x70, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x85, +0x1D, 0xF0, 0x7D, 0x68, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x12, 0x40, 0xB9, 0x90, 0x84, 0xC1, 0xE0, +0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x85, 0xB5, 0xE0, 0xFF, 0x70, 0x06, 0xA3, +0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x85, 0xB6, 0xE0, 0xB5, 0x07, 0x04, 0x7F, +0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x02, 0xF0, 0x22, +0xC0, 0x01, 0x90, 0x85, 0xB6, 0xE0, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x1F, 0xF9, 0x74, 0x85, 0x35, +0xF0, 0xA8, 0x01, 0xFC, 0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F, 0x0F, 0x12, 0x02, 0xD0, 0x7D, +0xCC, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xB6, 0x12, 0xAF, 0x70, 0xB4, 0x0A, 0x02, 0x7F, +0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x85, 0xB6, 0xF0, 0x22, 0xE4, 0x90, 0x84, 0xC1, 0x12, 0x99, +0x30, 0x90, 0x92, 0xE1, 0xF0, 0x22, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0x80, 0x12, +0x7B, 0x3E, 0xB1, 0x6A, 0xB1, 0x5D, 0x12, 0x7B, 0x9C, 0xB1, 0xD9, 0x51, 0xBA, 0x7F, 0x01, 0x12, +0x85, 0x15, 0x90, 0x93, 0x10, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x85, 0x15, 0x90, 0x93, 0x10, 0xE0, +0x04, 0xF0, 0x91, 0x92, 0x71, 0xC9, 0x90, 0x01, 0xCC, 0x74, 0x0F, 0xF0, 0x90, 0x00, 0x80, 0xE0, +0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x7B, 0x3E, 0x75, 0x20, 0xFF, 0x12, 0x7C, 0xCD, 0x91, 0xF6, +0x90, 0x00, 0x81, 0xE0, 0x44, 0x04, 0xFD, 0x7F, 0x81, 0x12, 0x7B, 0x3E, 0xB1, 0x52, 0x71, 0x4E, +0x90, 0x00, 0x00, 0xE0, 0x54, 0xFB, 0xFD, 0xE4, 0xFF, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x01, 0xE0, +0x44, 0x04, 0xFD, 0x7F, 0x01, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x98, 0x74, 0x80, 0xF0, 0xA3, 0x74, +0x88, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xE4, 0xFF, 0x02, 0x85, 0x9E, 0x7E, 0x00, +0x7F, 0x0B, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x93, 0x79, 0x13, 0x12, 0x06, 0xDE, 0x71, 0xC2, 0x7F, +0xF9, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x1C, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x01, +0x90, 0x93, 0x13, 0xF0, 0xEE, 0x54, 0x04, 0x90, 0x93, 0x15, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0x54, +0x08, 0x90, 0x93, 0x14, 0xF0, 0x71, 0xC2, 0x7F, 0xFB, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, +0x16, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x07, 0x90, 0x93, 0x17, 0xF0, 0xEE, 0x54, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x90, 0x93, 0x16, 0xF0, 0x71, 0xC2, 0x7F, 0xFD, 0x7E, 0x00, 0x12, 0x64, 0x37, +0xBF, 0x01, 0x0E, 0x90, 0x92, 0x29, 0xE0, 0x54, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x93, 0x18, +0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x29, 0x22, 0xB1, 0x4C, 0x12, 0x7B, 0xEF, 0x12, 0x3C, +0x03, 0xD1, 0x23, 0x12, 0x94, 0x90, 0x71, 0xE4, 0x12, 0x99, 0x07, 0xB1, 0x7F, 0x90, 0x93, 0x11, +0x74, 0x01, 0xF0, 0x22, 0x90, 0x93, 0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xFB, +0xF0, 0x44, 0x10, 0xF0, 0x90, 0x84, 0xC5, 0xE0, 0xFF, 0x64, 0x02, 0x70, 0x2D, 0x90, 0xFD, 0x80, +0xE0, 0x7E, 0x00, 0x30, 0xE0, 0x02, 0x7E, 0x01, 0x90, 0x93, 0x0F, 0x91, 0x8B, 0x7E, 0x00, 0x30, +0xE1, 0x02, 0x7E, 0x01, 0x90, 0x93, 0x0D, 0x91, 0x8B, 0x7E, 0x00, 0x30, 0xE2, 0x02, 0x7E, 0x01, +0x90, 0x93, 0x0E, 0x91, 0x8B, 0x90, 0x02, 0xFB, 0xF0, 0x22, 0xEF, 0x64, 0x01, 0x70, 0x21, 0x91, +0x84, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x0F, 0xEF, 0xF0, 0x91, 0x84, 0x30, 0xE1, 0x02, +0x7F, 0x01, 0x90, 0x93, 0x0D, 0xEF, 0xF0, 0x91, 0x84, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x80, 0x27, +0x90, 0x84, 0xC5, 0xE0, 0x64, 0x03, 0x70, 0x24, 0x91, 0x7D, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, +0x93, 0x0F, 0xEF, 0xF0, 0x91, 0x7D, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x0D, 0xEF, 0xF0, +0x91, 0x7D, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x0E, 0xEF, 0xF0, 0x22, 0x90, 0xFD, 0x78, +0xE0, 0x7F, 0x00, 0x22, 0x90, 0xFD, 0x70, 0xE0, 0x7F, 0x00, 0x22, 0xEE, 0xF0, 0x90, 0xFD, 0x80, +0xE0, 0x22, 0x12, 0x7C, 0x4E, 0x90, 0x84, 0xC5, 0xEF, 0xF0, 0x91, 0xC6, 0x90, 0x01, 0x64, 0x74, +0x01, 0xF0, 0x90, 0x04, 0x23, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x00, 0x17, 0xE0, 0x54, 0xFC, 0x44, +0x04, 0xFD, 0x7F, 0x17, 0x12, 0x7B, 0x3E, 0x90, 0x00, 0x38, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x38, +0x12, 0x7B, 0x3E, 0x02, 0x68, 0xE2, 0x12, 0x75, 0xB6, 0x12, 0x75, 0x58, 0xB1, 0xFC, 0xB1, 0xBA, +0xE4, 0xF5, 0x40, 0xF5, 0x41, 0xF5, 0x42, 0x75, 0x43, 0x80, 0xAD, 0x40, 0x7F, 0x50, 0x12, 0x7B, +0x3E, 0xAD, 0x41, 0x7F, 0x51, 0x12, 0x7B, 0x3E, 0xAD, 0x42, 0x7F, 0x52, 0x12, 0x7B, 0x3E, 0xAD, +0x43, 0x7F, 0x53, 0x02, 0x7B, 0x3E, 0xE4, 0x90, 0x92, 0x29, 0xF0, 0xA3, 0xF0, 0xB1, 0x9C, 0xEF, +0x64, 0x01, 0x60, 0x41, 0xC3, 0x90, 0x92, 0x2A, 0xE0, 0x94, 0x88, 0x90, 0x92, 0x29, 0xE0, 0x94, +0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, +0x80, 0x23, 0x90, 0x92, 0x29, 0x12, 0x97, 0xE7, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0xD3, +0x90, 0x92, 0x2A, 0xE0, 0x94, 0x32, 0x90, 0x92, 0x29, 0xE0, 0x94, 0x00, 0x40, 0xBF, 0x90, 0x01, +0xC6, 0xE0, 0x30, 0xE3, 0xB8, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0x02, +0x6E, 0x5F, 0x90, 0x01, 0xE4, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x01, 0x94, +0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x84, 0xA1, 0x74, 0x02, 0xF0, +0xA3, 0x74, 0x10, 0xF0, 0x90, 0x84, 0xA7, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0x90, +0x89, 0x16, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, +0x90, 0x89, 0x18, 0xF0, 0x90, 0x89, 0x16, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x01, 0x9A, 0xE0, +0x54, 0xC0, 0x44, 0x0B, 0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x01, 0x98, 0xE0, +0x54, 0xC0, 0x7F, 0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0x75, 0x52, 0x06, 0x75, 0x53, 0x01, +0x75, 0x54, 0x03, 0x75, 0x55, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x52, 0xF0, 0xA3, 0xE5, 0x53, 0xF0, +0xA3, 0xE5, 0x54, 0xF0, 0xA3, 0xE5, 0x55, 0xF0, 0x22, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x04, 0xF0, +0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x01, +0x99, 0xE0, 0x44, 0xC0, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x80, 0xF0, 0x22, 0x75, 0x48, 0x12, 0xE4, +0xF5, 0x49, 0x75, 0x4A, 0x87, 0x75, 0x4B, 0x33, 0xF5, 0x50, 0x90, 0x01, 0x30, 0xE5, 0x48, 0xF0, +0xA3, 0xE5, 0x49, 0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0x90, 0x01, 0x20, 0xE5, +0x50, 0xF0, 0x22, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x90, 0x89, 0x1B, 0x12, 0x87, 0x03, 0x7B, +0xFF, 0x7A, 0x82, 0x79, 0x00, 0x90, 0x89, 0x1E, 0x12, 0x87, 0x03, 0x7A, 0x82, 0x79, 0x3F, 0x90, +0x89, 0x21, 0x12, 0x87, 0x03, 0x7A, 0x82, 0x79, 0xE1, 0x90, 0x89, 0x27, 0x12, 0x87, 0x03, 0x7A, +0x82, 0x79, 0xF5, 0x90, 0x89, 0x2A, 0x12, 0x87, 0x03, 0x7A, 0x83, 0x79, 0x1D, 0x90, 0x89, 0x2D, +0x12, 0x87, 0x03, 0x7A, 0x83, 0x79, 0x31, 0x90, 0x89, 0x33, 0x12, 0x87, 0x03, 0x7A, 0x83, 0x79, +0x59, 0x90, 0x89, 0x36, 0x12, 0x87, 0x03, 0x7A, 0x83, 0x79, 0x81, 0x90, 0x89, 0x39, 0x12, 0x87, +0x03, 0xE4, 0x90, 0x93, 0x5F, 0xF0, 0x90, 0x92, 0x29, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0xFF, 0xC3, +0x94, 0x05, 0x50, 0x10, 0x74, 0x70, 0x2F, 0x12, 0x9F, 0xBD, 0xE4, 0xF0, 0x90, 0x92, 0x29, 0xE0, +0x04, 0xF0, 0x80, 0xE6, 0x22, 0x7D, 0x02, 0x90, 0x01, 0xC4, 0x74, 0xA5, 0xF0, 0x74, 0xB6, 0xA3, +0xF0, 0x90, 0x93, 0x10, 0xE0, 0xFF, 0xED, 0xC3, 0x9F, 0x50, 0x18, 0xED, 0x25, 0xE0, 0x24, 0x81, +0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22, +0x0D, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0xE4, 0x90, 0x92, 0x2B, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, +0x92, 0x2B, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0xD6, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xB6, 0xA3, 0xF0, +0x12, 0x7C, 0x66, 0xBF, 0x01, 0x03, 0x12, 0x5B, 0x25, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0F, 0x90, +0x85, 0xC8, 0xE0, 0xFF, 0x90, 0x85, 0xC7, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0xA8, 0xDE, 0xC2, 0xAF, +0xD1, 0xA5, 0xBF, 0x01, 0x02, 0xF1, 0x3D, 0xD2, 0xAF, 0x12, 0xB8, 0x53, 0x90, 0x92, 0x2C, 0x12, +0x97, 0xE7, 0x54, 0x7F, 0x45, 0xF0, 0x70, 0x0D, 0x7F, 0xFF, 0x12, 0x7B, 0x51, 0xEF, 0x04, 0xFD, +0x7F, 0xFF, 0x12, 0x7B, 0x3E, 0x12, 0x8F, 0xF5, 0x12, 0x84, 0x4D, 0x80, 0xA2, 0x90, 0x85, 0xC1, +0xE0, 0x30, 0xE0, 0x02, 0xF1, 0x47, 0x22, 0x90, 0x85, 0xC8, 0xE0, 0xFF, 0x60, 0x03, 0xB4, 0x08, +0x0E, 0x12, 0xBF, 0x97, 0xBF, 0x01, 0x08, 0xF1, 0x60, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0, 0x22, +0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xB8, 0xEB, 0xF1, 0x71, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xF1, 0x95, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x7B, +0x3E, 0xE4, 0xFF, 0x12, 0xB9, 0x42, 0x7D, 0x35, 0x7F, 0x27, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xC2, +0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x01, 0xC4, 0x74, 0x95, 0xF0, 0x74, 0xB7, 0xA3, 0xF0, 0x7F, +0x90, 0x12, 0x7B, 0x51, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0x95, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, +0xB7, 0xA3, 0xF0, 0x22, 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, 0xB5, 0xF0, 0x74, 0xB7, 0xA3, 0xF0, 0x12, 0x6C, 0xBC, 0x74, +0xB5, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xB7, 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, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, +0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0x06, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0xB8, 0xFF, 0xA3, +0xF0, 0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, +0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, 0x01, 0x13, 0x90, +0x85, 0xC5, 0xE0, 0x60, 0x0D, 0x12, 0x8F, 0xE4, 0x64, 0x02, 0x60, 0x03, 0x02, 0x77, 0x61, 0x12, +0x79, 0x41, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x19, 0xE0, 0x60, 0x25, +0x7F, 0x54, 0x7E, 0x09, 0x12, 0x70, 0x61, 0x11, 0xAB, 0xEF, 0x44, 0xFE, 0xFF, 0xEE, 0x44, 0x03, +0xFE, 0xED, 0x44, 0x04, 0xFD, 0xEC, 0x11, 0xAB, 0x90, 0x91, 0x66, 0x12, 0x04, 0xEB, 0x7F, 0x54, +0x7E, 0x09, 0x12, 0x71, 0x18, 0x90, 0x93, 0x14, 0xE0, 0x70, 0x04, 0x90, 0x07, 0xCC, 0xF0, 0x90, +0x93, 0x1C, 0xE0, 0x70, 0x0A, 0x90, 0x93, 0x19, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0x07, 0x90, +0x00, 0x1F, 0xE0, 0x54, 0xF0, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x92, 0x2E, 0x12, 0x04, +0xEB, 0x90, 0x92, 0x2E, 0x02, 0x86, 0xE2, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x02, +0x12, 0x7B, 0x51, 0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x00, 0x74, +0x3F, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0x90, 0x01, 0x01, 0xE0, 0x54, 0xFD, 0xF0, 0x90, +0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0x44, +0x10, 0xF0, 0x90, 0x85, 0xD0, 0xE0, 0xFD, 0x7F, 0x93, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xC6, 0xE0, +0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, +0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, 0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, +0x7B, 0x3E, 0x7F, 0x01, 0x31, 0x42, 0x7D, 0x34, 0x7F, 0x27, 0x12, 0x7B, 0x3E, 0x7F, 0x90, 0x12, +0x7B, 0x51, 0xEF, 0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x7B, 0x3E, 0x7F, 0x14, 0x7E, 0x00, 0x02, +0x7C, 0x9F, 0x90, 0x93, 0x99, 0xEF, 0x12, 0x99, 0x00, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00, 0x30, +0xE7, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x99, 0xE0, 0x6F, 0x60, 0x3A, 0xC3, 0x90, 0x93, 0x9B, 0xE0, +0x94, 0x88, 0x90, 0x93, 0x9A, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10, +0xF0, 0x22, 0x90, 0x93, 0x9A, 0x12, 0x97, 0xE7, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0xD3, +0x90, 0x93, 0x9B, 0xE0, 0x94, 0x32, 0x90, 0x93, 0x9A, 0xE0, 0x94, 0x00, 0x40, 0xBB, 0x90, 0x01, +0xC6, 0xE0, 0x30, 0xE0, 0xB4, 0x22, 0xED, 0x30, 0xE0, 0x26, 0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, +0x44, 0x31, 0xE7, 0xEF, 0x90, 0x89, 0x46, 0x31, 0xE7, 0xEF, 0x90, 0x89, 0x48, 0x31, 0xE7, 0xEF, +0x90, 0x89, 0x4A, 0x31, 0xE7, 0xEF, 0x90, 0x89, 0x4C, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xA3, 0xF0, +0xED, 0x30, 0xE1, 0x0A, 0x75, 0xF0, 0x12, 0xEF, 0x51, 0x10, 0xE4, 0xF0, 0xA3, 0xF0, 0xED, 0x30, +0xE2, 0x08, 0x75, 0xF0, 0x12, 0xEF, 0x51, 0x05, 0xE4, 0xF0, 0x31, 0xF2, 0xE0, 0x54, 0xBF, 0x44, +0x80, 0xFE, 0x31, 0xF2, 0xEE, 0xF0, 0x22, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, +0x12, 0x22, 0xEF, 0xC4, 0x54, 0xF0, 0x24, 0x03, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, +0x75, 0xF0, 0x12, 0xE5, 0x62, 0x90, 0x89, 0x42, 0x02, 0x05, 0x28, 0x75, 0xF0, 0x12, 0xE5, 0x62, +0x90, 0x89, 0x40, 0x02, 0x05, 0x28, 0x90, 0x92, 0x3F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, +0xF0, 0xEB, 0x75, 0xF0, 0x06, 0xA4, 0xFF, 0x90, 0x89, 0x21, 0x12, 0x86, 0xFA, 0xE9, 0x2F, 0xF9, +0xEA, 0x35, 0xF0, 0xFA, 0x90, 0x92, 0x47, 0x12, 0x87, 0x03, 0x90, 0x92, 0x41, 0xE0, 0x71, 0x20, +0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, 0x44, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, +0x92, 0x47, 0x12, 0x86, 0xFA, 0x90, 0x92, 0x46, 0xE0, 0xFF, 0xF5, 0x82, 0x12, 0xA6, 0x83, 0xFD, +0x7C, 0x00, 0x90, 0x92, 0x41, 0xE0, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x44, 0x12, 0x05, 0x28, 0x75, +0xF0, 0x02, 0xEF, 0x12, 0x05, 0x28, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x43, 0xE0, 0xFB, +0xEF, 0xA8, 0x03, 0x08, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, 0x03, +0x70, 0x90, 0x92, 0x44, 0xEE, 0x8F, 0xF0, 0x12, 0x07, 0x0A, 0x90, 0x92, 0x46, 0xE0, 0x04, 0xF0, +0xE0, 0xB4, 0x05, 0xAB, 0x90, 0x92, 0x47, 0x12, 0x86, 0xFA, 0x90, 0x00, 0x05, 0x12, 0x03, 0x0F, +0xFD, 0x7C, 0x00, 0x90, 0x92, 0x43, 0xE0, 0xFF, 0x90, 0x92, 0x3F, 0xE0, 0xFE, 0xA3, 0xE0, 0xA8, +0x07, 0x08, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0xFF, 0x12, 0x03, 0x70, 0x90, +0x92, 0x44, 0x12, 0x9F, 0xED, 0x40, 0x08, 0xED, 0x9F, 0xFF, 0xEC, 0x9E, 0xFE, 0x80, 0x04, 0x7E, +0x00, 0x7F, 0x00, 0x90, 0x92, 0x44, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x44, 0xE0, 0xFE, +0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x41, 0xE0, 0x80, 0x16, 0xE5, 0x71, 0x25, 0xE0, 0x24, 0xF5, 0xF5, +0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, 0x93, 0xFF, 0xE5, 0x6E, 0x25, +0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, +0x25, 0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, 0xAC, 0x05, 0x90, 0x92, +0x3F, 0xEF, 0xF0, 0xFD, 0xE0, 0xFF, 0x12, 0x8F, 0xA4, 0xE0, 0xF5, 0x6E, 0x54, 0x7F, 0xF5, 0x70, +0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, 0x3D, 0x12, 0x05, 0x28, 0xE0, 0xF9, 0x90, 0x92, 0x3F, 0xE0, +0x12, 0x8F, 0xF7, 0xFE, 0xEF, 0x12, 0x8F, 0xBC, 0xE0, 0x54, 0x03, 0xF5, 0x6F, 0xE5, 0x70, 0x90, +0x83, 0x1D, 0x93, 0xFB, 0xED, 0x71, 0x20, 0xE4, 0xF0, 0xA3, 0xEB, 0xF0, 0x12, 0x8A, 0x82, 0xC4, +0x54, 0x03, 0x90, 0x92, 0x40, 0xF0, 0x74, 0xCC, 0x2D, 0x91, 0x0D, 0xE5, 0x70, 0xF0, 0x74, 0x4C, +0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE5, 0x6F, 0xF0, 0xE5, 0x70, 0xD3, 0x9E, 0x40, +0x06, 0x8E, 0x70, 0xAF, 0x06, 0x8F, 0x6E, 0x8C, 0x71, 0xE4, 0xFF, 0xEF, 0xC3, 0x95, 0x71, 0x50, +0x2F, 0xE5, 0x6E, 0x30, 0xE7, 0x09, 0x85, 0x70, 0x6E, 0x1C, 0xEC, 0x70, 0x20, 0x80, 0x21, 0xE5, +0x70, 0xD3, 0x99, 0x40, 0x14, 0xAD, 0x01, 0x90, 0x92, 0x3F, 0xE0, 0xFB, 0x90, 0x92, 0x44, 0xEC, +0xF0, 0xAF, 0x70, 0x91, 0x15, 0x8F, 0x6E, 0x80, 0x07, 0x89, 0x6E, 0x80, 0x03, 0x0F, 0x80, 0xCB, +0x90, 0x92, 0x3F, 0xE0, 0xFF, 0x90, 0x92, 0x45, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, +0xA3, 0xE5, 0x6E, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x6F, 0x12, 0x99, 0x00, 0x7B, 0x01, 0xFA, +0x7D, 0x05, 0x7F, 0x08, 0x12, 0x9F, 0x21, 0x90, 0x92, 0x3F, 0xE0, 0xFF, 0x90, 0x91, 0x0B, 0xE5, +0x6F, 0xF0, 0xE4, 0xFB, 0xAD, 0x6E, 0x02, 0x27, 0x3D, 0x74, 0xCC, 0x25, 0x6E, 0xF5, 0x82, 0xE4, +0x34, 0x90, 0xF5, 0x83, 0x22, 0xE4, 0xF5, 0x73, 0xEF, 0x14, 0xF5, 0x72, 0xED, 0xFF, 0xE5, 0x72, +0xF5, 0x82, 0x33, 0x95, 0xE0, 0xF5, 0x83, 0xC3, 0xE5, 0x82, 0x9F, 0x74, 0x80, 0xF8, 0x65, 0x83, +0x98, 0x40, 0x51, 0xE5, 0x72, 0x78, 0x03, 0xA2, 0xE7, 0x13, 0xD8, 0xFB, 0xFF, 0x33, 0x95, 0xE0, +0xFE, 0xEB, 0x91, 0x87, 0xE5, 0x82, 0x2F, 0xF5, 0x82, 0xE5, 0x83, 0x3E, 0xF5, 0x83, 0xE0, 0xF5, +0x82, 0x75, 0x83, 0x00, 0xE5, 0x72, 0x12, 0xAF, 0x60, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, +0xD8, 0xF9, 0xFF, 0xEE, 0x55, 0x83, 0xFE, 0xEF, 0x55, 0x82, 0x4E, 0x60, 0x13, 0x85, 0x72, 0x74, +0x05, 0x73, 0x90, 0x92, 0x44, 0xE0, 0x65, 0x73, 0x60, 0x0A, 0xE5, 0x74, 0xD3, 0x9D, 0x40, 0x04, +0x15, 0x72, 0x80, 0x98, 0xAF, 0x74, 0x22, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, +0x34, 0x82, 0xF5, 0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0xA1, 0xEF, +0xF0, 0x12, 0x8F, 0xDC, 0x30, 0xE6, 0x40, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0xEF, 0x64, 0x01, 0x70, +0x36, 0x90, 0x93, 0xA2, 0xF0, 0x90, 0x93, 0xA2, 0xE0, 0xFD, 0x90, 0x93, 0xA1, 0xE0, 0x12, 0x8F, +0xA4, 0xE5, 0x82, 0x2D, 0x12, 0xAE, 0x17, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x8B, 0xB9, 0x90, 0x93, +0xA2, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x10, 0x40, 0xDB, 0x12, 0x8F, 0xDC, 0x30, 0xE0, 0x07, +0xE4, 0xFD, 0x7F, 0x8D, 0x12, 0x7B, 0x3E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xCF, 0xE0, +0x90, 0x92, 0xBB, 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, 0x75, 0xB6, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, +0x7F, 0x03, 0x12, 0x7B, 0x3E, 0x80, 0xFE, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x93, 0x90, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x93, 0x8F, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, +0x7B, 0x2A, 0x7C, 0x00, 0xAD, 0x07, 0x90, 0x93, 0x8F, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x93, +0x90, 0xE0, 0x60, 0x0E, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, +0x80, 0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, +0xC0, 0xF0, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0xF0, +0x90, 0x93, 0x92, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x18, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0xEF, 0xF0, 0x74, 0x12, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0x01, +0xFF, 0x90, 0x93, 0x91, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x44, 0x02, 0x4E, 0xFF, 0xAE, +0x05, 0x74, 0x12, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x74, 0x11, 0x2E, +0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x74, 0xFF, 0xF0, 0x74, 0x29, 0x2E, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x75, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, +0x12, 0x70, 0x61, 0x90, 0x93, 0x7F, 0x12, 0x04, 0xEB, 0x90, 0x93, 0x77, 0x12, 0x86, 0xE2, 0x12, +0x04, 0xA7, 0x90, 0x93, 0x7F, 0x12, 0x86, 0xEE, 0x12, 0x86, 0xC8, 0xC0, 0x04, 0xC0, 0x05, 0xC0, +0x06, 0xC0, 0x07, 0x90, 0x93, 0x77, 0x12, 0x86, 0xE2, 0x90, 0x93, 0x7B, 0x12, 0x86, 0xEE, 0x12, +0x86, 0xC8, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x86, 0xD5, 0x90, 0x93, 0x83, +0x12, 0x04, 0xEB, 0x90, 0x93, 0x83, 0x12, 0x86, 0xE2, 0x90, 0x91, 0x66, 0x12, 0x04, 0xEB, 0x90, +0x93, 0x75, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x71, 0x18, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, +0x90, 0x92, 0xCE, 0xF0, 0xA3, 0xF0, 0x7F, 0x83, 0x12, 0x7B, 0x51, 0x90, 0x92, 0xCD, 0xEF, 0xF0, +0x7F, 0x83, 0x12, 0x7B, 0x51, 0xAE, 0x07, 0x90, 0x92, 0xCD, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, +0xC3, 0x90, 0x92, 0xCF, 0xE0, 0x94, 0x64, 0x90, 0x92, 0xCE, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, +0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x92, 0xCD, 0xE0, 0xFF, 0x22, 0x90, 0x92, 0xCE, 0x12, +0x97, 0xE7, 0x80, 0xC2, 0x90, 0x04, 0x24, 0xEF, 0xF0, 0x90, 0x04, 0x57, 0xF0, 0x22, 0x90, 0x92, +0xEE, 0xE0, 0xFD, 0x7C, 0x00, 0xA3, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x03, 0x82, 0xED, 0x4C, +0x70, 0x05, 0x90, 0x92, 0xFB, 0x80, 0x2A, 0xED, 0x64, 0x01, 0x4C, 0x70, 0x05, 0x90, 0x92, 0xFC, +0x80, 0x1F, 0xED, 0x64, 0x02, 0x4C, 0x70, 0x05, 0x90, 0x92, 0xFD, 0x80, 0x14, 0xED, 0x64, 0x03, +0x4C, 0x70, 0x05, 0x90, 0x92, 0xFE, 0x80, 0x09, 0xED, 0x64, 0x04, 0x4C, 0x70, 0x0D, 0x90, 0x92, +0xFF, 0xE0, 0xFF, 0xD1, 0x94, 0x90, 0x92, 0xEF, 0x12, 0x97, 0xE7, 0x22, 0x90, 0x93, 0x9C, 0x12, +0x87, 0x03, 0x12, 0x71, 0x54, 0x90, 0x85, 0xC5, 0xE0, 0xFF, 0x12, 0x60, 0xD0, 0x90, 0x85, 0xC5, +0xE0, 0x60, 0x16, 0x90, 0x93, 0x9C, 0x12, 0x8F, 0x0E, 0x54, 0x0F, 0xFF, 0x12, 0x8B, 0xEF, 0xFD, +0x12, 0x6A, 0xB8, 0x12, 0xAF, 0xB5, 0x12, 0x51, 0x7D, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x0F, 0x01, 0x80, 0x56, 0x90, 0x85, +0xC9, 0xE0, 0xFF, 0x54, 0x03, 0x60, 0x05, 0x75, 0x0F, 0x02, 0x80, 0x48, 0x90, 0x85, 0xC7, 0xE0, +0xFE, 0xE4, 0xC3, 0x9E, 0x50, 0x05, 0x75, 0x0F, 0x04, 0x80, 0x39, 0xEF, 0x30, 0xE2, 0x05, 0x75, +0x0F, 0x08, 0x80, 0x30, 0x90, 0x85, 0xC9, 0xE0, 0x30, 0xE4, 0x05, 0x75, 0x0F, 0x10, 0x80, 0x24, +0x90, 0x85, 0xC2, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x20, 0xE0, 0x05, 0x75, 0x0F, 0x20, 0x80, 0x14, +0x90, 0x86, 0x71, 0xE0, 0x60, 0x05, 0x75, 0x0F, 0x80, 0x80, 0x09, 0x90, 0x01, 0xB8, 0xE4, 0xF0, +0x7F, 0x01, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x0F, 0xF0, +0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80, 0x08, 0x90, +0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60, 0x05, 0x75, 0x61, 0x01, 0x80, 0x28, 0x90, 0x02, 0x96, 0xE0, +0x60, 0x05, 0x75, 0x61, 0x10, 0x80, 0x1D, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02, 0x80, 0x07, +0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3, 0x05, 0x75, 0x61, 0x04, 0x80, 0x08, 0x90, 0x01, 0xB8, 0xE4, +0xF0, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x61, 0xF0, +0x7F, 0x00, 0x22, 0xAC, 0x07, 0x90, 0x93, 0x1F, 0xE0, 0xF9, 0x30, 0xE0, 0x03, 0x02, 0xC0, 0x99, +0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x04, 0x90, 0x85, 0xDA, +0xF0, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x03, 0x90, 0x85, 0xD9, 0xF0, 0x80, 0x0D, 0x90, 0x85, 0xDA, +0x74, 0x02, 0xF0, 0x90, 0x85, 0xD9, 0x14, 0xF0, 0x0B, 0x0B, 0x90, 0x85, 0xD9, 0xE0, 0xFA, 0x90, +0x85, 0xD8, 0xE0, 0xD3, 0x9A, 0x50, 0x0E, 0x90, 0x85, 0xCD, 0xEB, 0xF0, 0x90, 0x85, 0xDA, 0xE0, +0xC3, 0x9D, 0x2C, 0x80, 0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x85, 0xCD, 0xF0, 0x90, 0x85, 0xD9, +0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x85, 0xDD, 0xF0, 0x90, 0x85, 0xDA, 0xE0, 0xFF, 0x24, +0x0A, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x85, 0xDD, 0x11, 0xA1, 0x98, 0x40, 0x04, 0xEF, 0x24, 0x0A, +0xF0, 0x90, 0x85, 0xDD, 0xE0, 0xFF, 0x24, 0x23, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x85, 0xCD, 0x11, +0xA1, 0x98, 0x40, 0x04, 0xEF, 0x24, 0x23, 0xF0, 0x90, 0x85, 0xDD, 0xE0, 0xFF, 0x7E, 0x00, 0x90, +0x85, 0xD1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01, 0xE4, 0x60, +0x03, 0x12, 0xAF, 0x93, 0xE9, 0x54, 0xFD, 0x80, 0x03, 0xE9, 0x44, 0x02, 0x90, 0x93, 0x1F, 0xF0, +0x22, 0xE0, 0xD3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x22, 0x90, 0x93, 0x59, 0x74, 0x04, +0xF0, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74, 0x05, 0xF0, +0xA3, 0xF0, 0x22, 0xE4, 0x90, 0x92, 0xBB, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x93, 0x28, 0x12, +0x86, 0xE2, 0x90, 0x93, 0x24, 0x12, 0x86, 0xEE, 0xC3, 0x12, 0x04, 0xB4, 0x40, 0x4B, 0x90, 0x85, +0xC1, 0xE0, 0x90, 0x93, 0x28, 0x30, 0xE0, 0x0F, 0x51, 0x3A, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x04, +0x2F, 0xFF, 0x90, 0x93, 0x59, 0x80, 0x05, 0x51, 0x3A, 0x90, 0x93, 0x5A, 0xE0, 0xFE, 0xC3, 0xEF, +0x9E, 0x90, 0x92, 0xBC, 0xF0, 0x90, 0x92, 0xBC, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x50, 0x1A, 0x74, +0x2C, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xE0, 0x04, 0xF0, 0x90, 0x85, 0xDB, 0xE0, +0x04, 0xF0, 0xE0, 0xFD, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xDB, 0xE0, 0xFF, 0xD3, 0x90, +0x93, 0x5C, 0xE0, 0x9F, 0x90, 0x93, 0x5B, 0xE0, 0x94, 0x00, 0x40, 0x02, 0x41, 0x17, 0x51, 0x18, +0x90, 0x92, 0xBB, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x50, 0x1C, 0x51, 0x22, 0x90, 0x92, 0xBD, 0xE0, +0xD3, 0x9F, 0x40, 0x0A, 0x90, 0x92, 0xBB, 0xE0, 0x90, 0x92, 0xBE, 0xF0, 0x80, 0x08, 0x90, 0x92, +0xBB, 0xE0, 0x04, 0xF0, 0x80, 0xDA, 0x51, 0x18, 0x90, 0x92, 0xBB, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, +0x50, 0x2C, 0x51, 0x22, 0xC3, 0x90, 0x93, 0x5C, 0xE0, 0x9F, 0xFF, 0x90, 0x93, 0x5B, 0xE0, 0x94, +0x00, 0xFE, 0x90, 0x92, 0xBD, 0xE0, 0xD3, 0x9F, 0xE4, 0x9E, 0x40, 0x0A, 0x90, 0x92, 0xBB, 0xE0, +0x90, 0x92, 0xBF, 0xF0, 0x80, 0x08, 0x90, 0x92, 0xBB, 0xE0, 0x04, 0xF0, 0x80, 0xCA, 0x90, 0x92, +0xBE, 0xE0, 0x90, 0x85, 0xE0, 0xF0, 0x90, 0x92, 0xBF, 0xE0, 0x90, 0x85, 0xE1, 0xF0, 0x90, 0x85, +0xE0, 0xE0, 0xFF, 0xC3, 0x94, 0x0A, 0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x85, 0xD8, 0xF0, 0xE4, +0x80, 0x0E, 0xE4, 0x90, 0x85, 0xD8, 0xF0, 0x90, 0x85, 0xE0, 0xE0, 0xFF, 0xC3, 0x74, 0x0A, 0x9F, +0x90, 0x85, 0xD7, 0xF0, 0x90, 0x85, 0xE0, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x85, 0xDE, +0xF0, 0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x05, 0x90, 0x93, 0x59, 0x80, 0x03, 0x90, 0x93, 0x5A, +0xE0, 0xFF, 0x90, 0x85, 0xDE, 0xE0, 0x2F, 0x04, 0xF0, 0x90, 0x85, 0xDE, 0xE0, 0xC3, 0x94, 0x0A, +0x50, 0x03, 0x74, 0x0A, 0xF0, 0x90, 0x85, 0xDE, 0xE0, 0x24, 0x02, 0xF0, 0x12, 0xAF, 0xB5, 0x12, +0x51, 0x7D, 0xE4, 0xFF, 0x12, 0x69, 0x33, 0x22, 0xE4, 0x90, 0x92, 0xBD, 0xF0, 0x90, 0x92, 0xBB, +0xF0, 0x22, 0x74, 0x2C, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x92, +0xBD, 0xE0, 0x2F, 0xF0, 0x90, 0x93, 0x5D, 0xE0, 0xFF, 0x22, 0x12, 0x86, 0xEE, 0x90, 0x93, 0x24, +0x12, 0x86, 0xE2, 0x12, 0x86, 0xBA, 0x78, 0x0A, 0x12, 0x04, 0xC5, 0x90, 0x85, 0xDD, 0xE0, 0xFE, +0xC3, 0x74, 0x0A, 0x9E, 0x2F, 0xFF, 0x22, 0x12, 0xAF, 0x89, 0xD3, 0x9F, 0x40, 0x2B, 0x90, 0x85, +0xDF, 0xE0, 0x04, 0xF0, 0x90, 0x93, 0x5E, 0xE0, 0xFF, 0x90, 0x85, 0xDF, 0xE0, 0xD3, 0x9F, 0x50, +0x18, 0x90, 0x85, 0xD7, 0xE0, 0x04, 0x12, 0x93, 0x0A, 0x90, 0x85, 0xDE, 0xF0, 0xFB, 0x90, 0x85, +0xD7, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x12, 0x51, 0x7D, 0x22, 0xE4, 0xFE, 0x74, 0x2C, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0x93, 0xF5, 0x83, 0xE4, 0xF0, 0x0E, 0xEE, 0xB4, 0x2D, 0xEF, 0xE4, 0x90, 0x85, +0xDC, 0xF0, 0x90, 0x85, 0xDB, 0xF0, 0x90, 0x85, 0xDF, 0xF0, 0xEF, 0xB4, 0x01, 0x07, 0xA3, 0x74, +0x2D, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x22, 0x12, 0x8F, +0xE4, 0x60, 0x10, 0xE4, 0xFD, 0x7F, 0x0C, 0x12, 0x8D, 0x4D, 0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xE9, +0x02, 0x6B, 0x98, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12, 0x8D, 0x4D, +0x22, 0x90, 0x93, 0x09, 0xE0, 0x30, 0xE0, 0x34, 0xC4, 0x13, 0x54, 0x07, 0x20, 0xE0, 0x2D, 0x90, +0x93, 0xA7, 0xE0, 0x04, 0xF0, 0xE0, 0xD3, 0x94, 0xC8, 0x40, 0x21, 0x90, 0x93, 0x09, 0xE0, 0x44, +0x20, 0xF0, 0xE4, 0x90, 0x93, 0xA7, 0xF0, 0x90, 0x93, 0x09, 0xE0, 0x13, 0x30, 0xE0, 0x0D, 0x90, +0x85, 0xC1, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x85, 0xD0, 0x74, 0xD0, 0xF0, 0x22, 0x90, 0x92, 0xE0, +0xEF, 0xF0, 0x90, 0x84, 0xC5, 0xE0, 0xB4, 0x02, 0x12, 0x90, 0x92, 0xE0, 0xE0, 0xFF, 0x64, 0x01, +0x60, 0x25, 0x90, 0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0, 0x80, 0x19, 0x90, 0x01, 0x00, 0x74, 0xFF, +0xF0, 0x7F, 0x64, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, +0x92, 0xE0, 0xE0, 0xFF, 0x12, 0x2A, 0x87, 0x22, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, +0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x74, 0x01, 0x93, 0x90, 0x92, 0x47, 0xCF, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x45, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x74, 0xFF, 0x9F, +0xFF, 0x74, 0xFF, 0x9E, 0xFE, 0xE5, 0x62, 0x25, 0xE0, 0x22, 0x35, 0xF0, 0xFE, 0x90, 0x00, 0x06, +0x12, 0x04, 0x18, 0x2F, 0xFF, 0xEE, 0x35, 0xF0, 0x22, 0x90, 0x92, 0x33, 0x12, 0x86, 0xFA, 0x90, +0x00, 0x08, 0x02, 0x04, 0x18, 0xE5, 0x66, 0xF0, 0xA3, 0xE5, 0x67, 0xF0, 0xE5, 0x64, 0x90, 0x83, +0x1D, 0x93, 0xFF, 0x22, 0xE0, 0xFF, 0x90, 0x92, 0x4B, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xE0, +0xFE, 0xA3, 0xE0, 0xFF, 0xED, 0x2F, 0xFF, 0xEC, 0x3E, 0xFE, 0x22, 0x90, 0x92, 0x33, 0x12, 0x86, +0xFA, 0x90, 0x00, 0x02, 0x12, 0x04, 0x18, 0xFF, 0x22, 0xE0, 0x54, 0x03, 0x90, 0x91, 0x0B, 0xF0, +0x7B, 0x01, 0xAF, 0x78, 0x02, 0x27, 0x3D, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, 0xE4, +0x34, 0x82, 0xF5, 0x83, 0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x85, 0xC7, 0xE0, 0x90, 0x01, +0xBB, 0x22, 0x90, 0x00, 0x06, 0x02, 0x04, 0x18, 0x90, 0x92, 0x49, 0xE4, 0xF0, 0xA3, 0x22, 0x90, +0x92, 0x47, 0xE4, 0xF0, 0xA3, 0x22, 0xE5, 0x62, 0x25, 0xE0, 0x24, 0x8C, 0xF5, 0x82, 0xE4, 0x22, +0x90, 0x92, 0x33, 0x12, 0x86, 0xFA, 0x02, 0x03, 0xED, 0x74, 0xBC, 0x25, 0x62, 0xF5, 0x82, 0xE4, +0x34, 0x8F, 0x22, 0x00, 0x31, 0x70, +}; +u4Byte ArrayLength_MP_8188F_FW_AP = 17494; + + +void +ODM_ReadFirmware_MP_8188F_FW_AP( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + *((SIZE_PTR *)pFirmware) = (SIZE_PTR)Array_MP_8188F_FW_AP; +#else + ODM_MoveMemory(pDM_Odm, pFirmware, Array_MP_8188F_FW_AP, ArrayLength_MP_8188F_FW_AP); +#endif + *pFirmwareSize = ArrayLength_MP_8188F_FW_AP; +} + + +#endif /* #if (defined(CONFIG_AP_WOWLAN)||(DM_ODM_SUPPORT_TYPE & (ODM_AP)) */ + + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) || (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + + +u1Byte Array_MP_8188F_FW_NIC[] = { +0xF1, 0x88, 0x10, 0x00, 0x01, 0x00, 0x07, 0x00, 0x10, 0x22, 0x17, 0x28, 0x52, 0x49, 0x02, 0x00, +0xE7, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x86, 0xAD, 0x02, 0xBC, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xA5, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xBC, 0xB5, 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, 0xBC, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA4, 0x3F, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xBC, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x87, 0xBB, 0x02, 0x89, 0x07, 0x02, 0x80, 0x86, 0x02, 0x80, 0x89, 0x02, 0x80, 0x8C, 0x02, +0x9A, 0x4C, 0x02, 0xA3, 0x4F, 0x02, 0x80, 0x95, 0x02, 0x80, 0x98, 0x02, 0x80, 0x9B, 0x02, 0x80, +0x9E, 0x02, 0x80, 0xA1, 0x02, 0x80, 0xA4, 0x02, 0x80, 0xA7, 0x02, 0x80, 0xAA, 0x02, 0x80, 0xAD, +0x02, 0x80, 0xB0, 0x02, 0x89, 0xDD, 0x02, 0x80, 0xB6, 0x02, 0x80, 0xB9, 0x02, 0xB8, 0x4E, 0x02, +0xB9, 0x2B, 0x02, 0xB8, 0xB0, 0x02, 0xB6, 0xEC, 0x02, 0xAF, 0xE5, 0x02, 0xB7, 0xE5, 0x02, 0x80, +0xCE, 0x02, 0x80, 0xD1, 0x02, 0xC6, 0x3E, 0x02, 0x80, 0xD7, 0x00, 0x00, 0x00, 0x02, 0x80, 0xDD, +0x02, 0x80, 0xE0, 0x02, 0x80, 0xE3, 0x02, 0x80, 0xE6, 0x02, 0xC5, 0xEC, 0x02, 0x80, 0xEC, 0x02, +0x80, 0xEF, 0x02, 0x80, 0xF2, 0x02, 0x80, 0xF5, 0x02, 0x80, 0xF8, 0x02, 0x80, 0xFB, 0x02, 0x80, +0xFE, 0x02, 0x81, 0x01, 0x02, 0x81, 0x04, 0x02, 0x81, 0x07, 0x02, 0x81, 0x0A, 0x02, 0x81, 0x0D, +0x02, 0x81, 0x10, 0x02, 0x81, 0x13, 0x02, 0x81, 0x16, 0x02, 0x81, 0x19, 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, 0xAE, 0x52, 0x02, 0xC0, 0x1A, 0x02, 0x90, 0xE6, 0x02, 0x90, 0xDB, +0x02, 0x81, 0x40, 0x02, 0x9B, 0xAC, 0x02, 0xBB, 0x71, 0x02, 0x81, 0x49, 0x02, 0x81, 0x4C, 0x02, +0x81, 0x4F, 0x02, 0x81, 0x52, 0x02, 0x81, 0x55, 0x02, 0x81, 0x58, 0x02, 0x81, 0x5B, 0x02, 0x91, +0x44, 0x02, 0x81, 0x61, 0x02, 0x81, 0x64, 0x02, 0xC4, 0xD3, 0x02, 0xC5, 0xBB, 0x02, 0xBF, 0x30, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, +0x08, 0x03, 0x03, 0x00, 0x04, 0x09, 0x07, 0x03, 0x03, 0x00, 0x04, 0x08, 0x06, 0x03, 0x02, 0x00, +0x04, 0x08, 0x05, 0x03, 0x01, 0x00, 0x04, 0x0D, 0x0A, 0x07, 0x05, 0x00, 0x08, 0x0C, 0x0A, 0x07, +0x04, 0x00, 0x08, 0x0B, 0x0A, 0x06, 0x05, 0x00, 0x08, 0x0B, 0x0A, 0x05, 0x03, 0x00, 0x08, 0x0B, +0x0A, 0x03, 0x02, 0x00, 0x08, 0x14, 0x12, 0x0C, 0x04, 0x00, 0x10, 0x14, 0x12, 0x09, 0x04, 0x00, +0x10, 0x24, 0x22, 0x1C, 0x12, 0x00, 0x20, 0x24, 0x22, 0x18, 0x0C, 0x00, 0x20, 0x24, 0x22, 0x14, +0x06, 0x00, 0x20, 0x24, 0x22, 0x0F, 0x04, 0x00, 0x20, 0x24, 0x21, 0x0A, 0x04, 0x00, 0x20, 0x23, +0x21, 0x0C, 0x04, 0x00, 0x20, 0x23, 0x1F, 0x0A, 0x04, 0x00, 0x20, 0x22, 0x1F, 0x0F, 0x04, 0x00, +0x20, 0x21, 0x1F, 0x16, 0x0C, 0x00, 0x20, 0x31, 0x2F, 0x20, 0x14, 0x00, 0x30, 0x31, 0x2F, 0x18, +0x10, 0x00, 0x30, 0x31, 0x2C, 0x18, 0x0C, 0x00, 0x30, 0x31, 0x2A, 0x14, 0x0C, 0x00, 0x30, 0x31, +0x28, 0x14, 0x00, 0x00, 0x30, 0x31, 0x24, 0x14, 0x00, 0x00, 0x30, 0x31, 0x1E, 0x14, 0x00, 0x00, +0x30, 0x02, 0x02, 0x03, 0x04, 0x04, 0x08, 0x09, 0x09, 0x0C, 0x0E, 0x10, 0x12, 0x02, 0x09, 0x0B, +0x0E, 0x0D, 0x0F, 0x10, 0x12, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x23, 0x00, +0x2D, 0x00, 0x50, 0x00, 0x91, 0x00, 0xC3, 0x01, 0x27, 0x01, 0x31, 0x01, 0x5E, 0x00, 0x8C, 0x00, +0xC8, 0x00, 0xDC, 0x01, 0x5E, 0x01, 0x68, 0x01, 0x9A, 0x01, 0xCC, 0x01, 0xEA, 0x02, 0x02, 0x04, +0x08, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x14, 0x28, 0x32, 0x50, 0x78, 0xA0, 0xC8, +0xE6, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x02, 0x04, 0x06, +0x07, 0x07, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x03, 0x03, 0x04, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x03, 0x03, 0x03, +0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x19, 0x06, 0x04, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x84, 0x04, 0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0, +0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A, 0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C, +0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02, 0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00, +0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6, 0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1, +0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9, 0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF, +0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF, 0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30, +0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50, 0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8, +0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8, +0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80, 0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5, +0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD, +0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0, 0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86, +0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C, 0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF, +0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F, 0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F, +0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6, +0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76, 0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80, +0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81, 0x76, 0x30, 0x90, 0x87, 0xB5, 0x74, 0x01, 0x93, +0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89, 0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2, +0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81, +0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2, 0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE, +0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74, 0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18, +0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09, +0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE, 0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81, +0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E, 0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02, +0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09, +0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF, 0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F, +0x04, 0x90, 0x87, 0xB5, 0x93, 0xF6, 0x08, 0xEF, 0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3, +0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF, 0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4, +0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF, 0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F, +0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x84, 0x4D, 0x50, 0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02, +0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74, 0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C, +0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19, 0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5, +0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01, +0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08, 0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC, +0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8, 0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5, +0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, +0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6, 0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4, +0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30, 0xE2, 0x01, 0x0F, 0x02, 0x84, 0x4C, 0x8F, 0xF0, +0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80, 0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08, +0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x32, 0x50, 0x30, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6, +0x60, 0x27, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x25, 0x0E, 0x30, +0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x14, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x15, 0x54, 0xEC, +0x4E, 0xF6, 0xD2, 0xAF, 0xD2, 0xA9, 0x02, 0x84, 0x4D, 0x7F, 0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, +0xC2, 0xAF, 0x56, 0xC6, 0xD2, 0xAF, 0xD2, 0xA9, 0x54, 0x80, 0x4F, 0xFF, 0x22, 0x02, 0x86, 0xEB, +0x02, 0x84, 0xDD, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, +0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, +0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, +0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x87, 0xA8, 0xE4, 0x7E, +0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, +0xC3, 0xEF, 0x9B, 0xFF, 0xEE, 0x9A, 0xFE, 0xED, 0x99, 0xFD, 0xEC, 0x98, 0xFC, 0x22, 0xEF, 0x5B, +0xFF, 0xEE, 0x5A, 0xFE, 0xED, 0x59, 0xFD, 0xEC, 0x58, 0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, +0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, +0xA3, 0xE0, 0xFF, 0x22, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x22, +0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, +0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, +0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, +0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0x41, 0x93, 0x22, 0x00, 0x41, 0x93, 0x23, 0x00, +0x41, 0x93, 0x28, 0x00, 0x00, 0xA9, 0x6A, 0xBA, 0x06, 0xBB, 0xFE, 0x90, 0x93, 0x26, 0xEF, 0xF0, +0x7F, 0x02, 0xD1, 0x27, 0x90, 0x84, 0xC1, 0xE0, 0xFF, 0x90, 0x93, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, +0x90, 0x84, 0xC1, 0xF0, 0x22, 0x90, 0x92, 0x07, 0x74, 0x10, 0xF0, 0x90, 0x92, 0x15, 0x74, 0x07, +0xF0, 0x12, 0x02, 0xF6, 0x90, 0x92, 0x09, 0xF1, 0xEB, 0x80, 0xD0, 0xF0, 0x7B, 0x01, 0x7A, 0x92, +0x79, 0x07, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x5B, 0x12, 0x02, +0xF6, 0x25, 0x5B, 0x90, 0x84, 0xC6, 0xB1, 0x90, 0x25, 0x5B, 0x90, 0x84, 0xC7, 0x91, 0xA7, 0x25, +0x5B, 0x90, 0x84, 0xC8, 0xF1, 0xE1, 0x25, 0x5B, 0x90, 0x84, 0xC9, 0xF0, 0x90, 0x00, 0x04, 0x12, +0x03, 0x0F, 0x25, 0x5B, 0x90, 0x84, 0xCA, 0xF0, 0x90, 0x00, 0x05, 0x12, 0x03, 0x0F, 0x25, 0x5B, +0x90, 0x84, 0xCB, 0xF0, 0x11, 0x3D, 0x25, 0x5B, 0x90, 0x84, 0xCC, 0xF0, 0x22, 0x90, 0x00, 0x06, +0x02, 0x03, 0x0F, 0x12, 0xC8, 0xEE, 0xFF, 0x54, 0x7F, 0x90, 0x85, 0xC5, 0xF0, 0xEF, 0xB1, 0x9B, +0xA3, 0xB1, 0x90, 0xFD, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x90, 0x85, 0xC3, 0xE0, 0x54, 0xF0, +0x4F, 0xF1, 0xE1, 0xFC, 0x54, 0x01, 0x25, 0xE0, 0xFF, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xFD, 0x4F, +0xF0, 0xEC, 0x54, 0x02, 0x25, 0xE0, 0xFF, 0x90, 0x92, 0x96, 0xE0, 0x54, 0xFB, 0x4F, 0xF0, 0xED, +0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x12, 0x9F, 0x13, 0x91, 0xA6, 0x90, 0x85, 0xC4, 0xF0, 0x11, +0x3D, 0x30, 0xE0, 0x4E, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x85, 0xD8, 0x50, +0x04, 0xEF, 0xF0, 0x80, 0x26, 0x74, 0x03, 0xF0, 0x31, 0xD7, 0xE9, 0x24, 0x06, 0x12, 0xC9, 0x31, +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, 0x03, 0x3C, 0x31, 0xD7, 0x11, 0x3D, 0xC4, +0x54, 0x0F, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x85, 0xCD, 0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, +0xEF, 0xF0, 0x31, 0xD7, 0x90, 0x00, 0x04, 0x12, 0x03, 0x0F, 0xFD, 0x7F, 0x02, 0x12, 0x57, 0x82, +0x31, 0xD7, 0x12, 0x71, 0xCB, 0x12, 0xA5, 0x40, 0xF0, 0x90, 0x85, 0xC5, 0x12, 0xC8, 0xC2, 0x12, +0x9F, 0x12, 0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x92, 0x04, 0x12, 0x87, 0x79, 0x90, 0x92, 0x03, +0xEF, 0xF0, 0x12, 0x87, 0x82, 0x89, 0x5B, 0x00, 0x89, 0x60, 0x01, 0x89, 0x65, 0x03, 0x89, 0x6A, +0x04, 0x89, 0x6F, 0x12, 0x89, 0x74, 0x14, 0x89, 0x79, 0x1C, 0x89, 0x7E, 0x20, 0x89, 0x82, 0x24, +0x89, 0x87, 0x25, 0x89, 0x8C, 0x27, 0x89, 0x91, 0x40, 0x89, 0x95, 0x42, 0x89, 0xCA, 0x47, 0x89, +0xCA, 0x49, 0x89, 0x9E, 0x80, 0x89, 0x9A, 0x81, 0x89, 0xA2, 0x82, 0x89, 0xA7, 0x83, 0x89, 0xAC, +0x84, 0x89, 0xB1, 0x88, 0x89, 0xB6, 0xC3, 0x00, 0x00, 0x89, 0xBB, 0x31, 0xCB, 0x02, 0x87, 0xF8, +0x31, 0xCB, 0x02, 0x90, 0x00, 0x31, 0xCB, 0x02, 0x78, 0x94, 0x31, 0xCB, 0x02, 0x6B, 0x03, 0x31, +0xCB, 0x02, 0x97, 0xFD, 0x31, 0xCB, 0x02, 0x98, 0xD4, 0x31, 0xCB, 0x02, 0x87, 0xD5, 0x31, 0xCB, +0x01, 0x43, 0x31, 0xCB, 0x02, 0x98, 0xE3, 0x31, 0xCB, 0x02, 0x9F, 0xFB, 0x31, 0xCB, 0x02, 0xA0, +0x03, 0x31, 0xCB, 0x80, 0x48, 0x31, 0xCB, 0x02, 0x4E, 0x29, 0x31, 0xCB, 0xA1, 0xAF, 0x31, 0xCB, +0x81, 0xAE, 0x31, 0xCB, 0x02, 0x7A, 0xFE, 0x31, 0xCB, 0x02, 0x6F, 0x63, 0x31, 0xCB, 0x02, 0x6F, +0xA4, 0x31, 0xCB, 0x02, 0x7B, 0xD0, 0x31, 0xCB, 0x02, 0xA7, 0xEE, 0x90, 0x01, 0xC0, 0xE0, 0x44, +0x01, 0xF0, 0x90, 0x92, 0x03, 0xE0, 0x90, 0x01, 0xC2, 0xF0, 0x22, 0x90, 0x92, 0x04, 0x02, 0x87, +0x70, 0x24, 0x03, 0xFF, 0xE4, 0x33, 0xFE, 0x90, 0x92, 0x07, 0x02, 0x87, 0x70, 0x90, 0x92, 0x07, +0x12, 0x87, 0x79, 0x31, 0xD7, 0x12, 0x02, 0xF6, 0x54, 0x7F, 0xFD, 0xB1, 0x91, 0xFE, 0x54, 0x1F, +0x90, 0x92, 0x0B, 0xF0, 0xEE, 0x54, 0x80, 0xB1, 0x9B, 0x90, 0x92, 0x0A, 0x91, 0xA7, 0xFE, 0x54, +0x03, 0xFC, 0xEE, 0x54, 0x30, 0xC4, 0x54, 0x0F, 0x90, 0x92, 0x0D, 0x91, 0xA7, 0xFE, 0x54, 0x40, +0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x92, 0x0C, 0xF0, 0xEE, 0x54, 0x80, 0xB1, 0x9B, 0xFF, 0x91, +0xA8, 0xFB, 0x54, 0x08, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x90, 0x92, 0x0F, 0xF0, 0xFA, 0xEB, 0x54, +0x04, 0x13, 0x13, 0x54, 0x3F, 0xA3, 0xF0, 0xEF, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, +0x71, 0x3F, 0x54, 0x7F, 0x4F, 0xF0, 0x90, 0x92, 0x0C, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x54, +0xC0, 0x71, 0x3F, 0x54, 0xBF, 0x4F, 0xF0, 0xEA, 0x60, 0x02, 0x61, 0x3E, 0x90, 0x92, 0x0B, 0xE0, +0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0xB1, 0xA7, 0x54, 0xE0, 0x4F, 0xF0, 0xEC, 0x54, 0x03, +0x71, 0x3F, 0x54, 0xFC, 0x4F, 0xF0, 0xEC, 0x54, 0x03, 0x25, 0xE0, 0x25, 0xE0, 0x71, 0x3F, 0x54, +0xF3, 0x4F, 0xF0, 0x90, 0x92, 0x0A, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x54, 0xE0, 0xFF, 0x75, 0xF0, +0x12, 0xED, 0xB1, 0xA7, 0x54, 0xDF, 0x4F, 0xF0, 0x90, 0x92, 0x0D, 0xE0, 0x54, 0x03, 0xC4, 0x54, +0xF0, 0x71, 0x3F, 0x54, 0xCF, 0x4F, 0x12, 0xC8, 0xCF, 0xE0, 0x54, 0xFB, 0x12, 0xC8, 0xCF, 0xC0, +0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x92, 0x10, 0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x4E, +0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x90, 0x92, 0x90, 0xE0, 0x60, 0x30, 0x31, 0xD7, 0xE9, 0x24, 0x03, +0x12, 0xC9, 0x31, 0x54, 0x1F, 0x12, 0x03, 0x3C, 0x90, 0x92, 0x0E, 0x74, 0x01, 0xF0, 0x90, 0x92, +0x0E, 0xE0, 0xFF, 0xC3, 0x94, 0x04, 0x50, 0x13, 0xEF, 0x31, 0xD1, 0x8F, 0x82, 0x8E, 0x83, 0xE4, +0x12, 0x03, 0x4E, 0x90, 0x92, 0x0E, 0xE0, 0x04, 0xF0, 0x80, 0xE3, 0x90, 0x92, 0x8E, 0xE0, 0x54, +0x07, 0xFF, 0xBF, 0x05, 0x0A, 0xEC, 0xB4, 0x01, 0x06, 0x90, 0x92, 0x93, 0x74, 0x01, 0xF0, 0xE4, +0x90, 0x92, 0x0E, 0xF0, 0x90, 0x92, 0x0E, 0xE0, 0xFC, 0x31, 0xD1, 0x8F, 0x82, 0x8E, 0x83, 0x12, +0x03, 0x0F, 0xFF, 0xED, 0x12, 0xC8, 0x73, 0xE5, 0x82, 0x2C, 0x12, 0xA7, 0x33, 0xEF, 0xF0, 0x90, +0x92, 0x0E, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x04, 0xDB, 0xAF, 0x05, 0x12, 0x17, 0x8E, 0x22, 0xFF, +0x75, 0xF0, 0x12, 0xED, 0x90, 0x89, 0x3F, 0x12, 0x05, 0x28, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0xF1, 0x8B, 0x20, 0xE6, 0x02, 0x81, 0x6D, 0x90, 0x00, 0x8C, 0xE0, 0x90, 0x93, +0x19, 0xF0, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0x90, 0x93, 0x1A, 0xEF, 0xF0, 0x90, 0x00, 0x8E, 0xE0, +0x90, 0x93, 0x1B, 0xF0, 0x90, 0x93, 0x1A, 0xE0, 0x24, 0xFC, 0x60, 0x0F, 0x24, 0x03, 0x60, 0x02, +0x81, 0x66, 0x90, 0x93, 0x19, 0xE0, 0xFF, 0xF1, 0x92, 0x81, 0x66, 0x90, 0x93, 0x19, 0xE0, 0x24, +0xDC, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFD, 0xFF, 0x91, 0x9F, 0x75, +0xF0, 0x12, 0x71, 0x44, 0x13, 0x13, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x91, 0x9F, 0x75, 0xF0, +0x12, 0x71, 0x44, 0xB1, 0x9B, 0xFB, 0x0D, 0xE4, 0xFF, 0x91, 0x9F, 0x75, 0xF0, 0x12, 0x71, 0x44, +0xC4, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x91, 0x9F, 0x12, 0xC8, 0x8D, 0xFB, 0xE4, 0xFD, 0x0F, +0x91, 0x9F, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x3D, 0x12, 0x05, 0x28, 0x91, 0x9C, 0x75, 0xF0, 0x12, +0xB1, 0xA7, 0xC4, 0x13, 0x54, 0x01, 0xFB, 0x0D, 0x7F, 0x01, 0x91, 0x9F, 0x75, 0xF0, 0x12, 0xB1, +0xA7, 0x54, 0x1F, 0x91, 0x9D, 0x12, 0xC8, 0x73, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x91, 0x9F, 0x75, +0xF0, 0x08, 0xA4, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x9A, 0x75, 0xF0, 0x08, 0xA4, +0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x9A, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x03, 0xF5, +0x82, 0xE4, 0x34, 0x82, 0x91, 0x9A, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x04, 0xF5, 0x82, 0xE4, 0x34, +0x82, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x91, 0x9F, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x05, +0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x9A, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x06, 0xF5, 0x82, 0xE4, +0x34, 0x82, 0x91, 0x9A, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x07, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, +0x83, 0xE0, 0xFB, 0x0D, 0x91, 0x72, 0xF1, 0x8B, 0x30, 0xE0, 0x02, 0xF1, 0xF9, 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, 0x0C, 0x74, 0xFC, 0x2D, +0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, 0xEB, 0xF0, 0x22, 0xF5, 0x83, 0xE0, 0xFB, 0x0D, 0x91, +0x72, 0x90, 0x93, 0x19, 0xE0, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x02, 0x02, 0x03, 0x0F, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xC8, 0xEE, 0x20, 0xE0, 0x05, 0x12, 0xAD, 0xE9, 0xA1, 0x8A, +0x31, 0xD7, 0x12, 0xA7, 0xCD, 0x90, 0x86, 0x75, 0xD1, 0x3B, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, +0xF1, 0xE8, 0x12, 0xC9, 0x09, 0xD1, 0x49, 0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0xF1, 0xE8, 0x12, +0xC9, 0x11, 0xD1, 0x49, 0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0xF1, 0xE8, 0x12, 0xC9, 0x19, 0xB1, +0x90, 0x54, 0x80, 0xFF, 0x90, 0x86, 0x76, 0xE0, 0x54, 0x7F, 0x4F, 0xF0, 0x12, 0xC9, 0x21, 0x30, +0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x04, 0xF0, 0x31, 0xD7, 0x12, 0x02, 0xF6, 0x13, 0x13, +0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x84, 0xC5, +0xE0, 0xB4, 0x02, 0x05, 0xB1, 0x97, 0x20, 0xE0, 0x3E, 0xB1, 0x91, 0x54, 0x7F, 0xFF, 0x90, 0x86, +0x76, 0xE0, 0x54, 0x80, 0x91, 0xA6, 0x90, 0x86, 0x77, 0xF1, 0xE1, 0xFF, 0x54, 0x01, 0xFE, 0x90, +0x86, 0x78, 0x12, 0xA7, 0xC5, 0x54, 0xFE, 0xFF, 0xEE, 0x54, 0x01, 0x4F, 0xF0, 0x90, 0x86, 0x76, +0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x86, 0x75, 0xE0, 0xFE, 0xC4, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, +0xE0, 0x02, 0x7D, 0x01, 0x12, 0x54, 0x9F, 0x90, 0x84, 0xC5, 0xE0, 0xB4, 0x01, 0x07, 0x90, 0xFE, +0x10, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x87, 0x4A, 0x74, 0x05, 0xF0, 0x7E, 0x00, 0x7F, 0x08, 0x7D, +0x00, 0x7B, 0x01, 0x7A, 0x87, 0x79, 0x95, 0x12, 0x06, 0xDE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x4F, +0xF0, 0x90, 0x00, 0x01, 0x02, 0x03, 0x0F, 0x90, 0x86, 0x76, 0xE0, 0xC4, 0x13, 0x13, 0x13, 0x54, +0x01, 0x22, 0x75, 0xF0, 0x12, 0xE5, 0x6E, 0x90, 0x89, 0x3E, 0x12, 0x05, 0x28, 0xE0, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xA7, 0xCD, 0x90, 0x86, 0x72, 0xD1, 0x3B, 0x54, 0x04, +0xFD, 0xEF, 0x54, 0xFB, 0xF1, 0x83, 0x12, 0xC9, 0x09, 0xD1, 0x49, 0x54, 0x10, 0xFD, 0xEF, 0x54, +0xEF, 0xF1, 0x83, 0x12, 0xC9, 0x11, 0xD1, 0x49, 0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0xF1, 0x83, +0x12, 0xC9, 0x19, 0x91, 0xA7, 0x54, 0x01, 0xFF, 0x90, 0x86, 0x74, 0xE0, 0x54, 0xFE, 0xB1, 0x8F, +0xFF, 0x54, 0x01, 0xFE, 0x90, 0x86, 0x73, 0x12, 0xA7, 0xC5, 0x54, 0x04, 0xFF, 0xEE, 0x54, 0xFB, +0x4F, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0xC3, 0x13, 0x54, 0x01, 0xFF, 0x12, 0x7C, 0x72, 0xF1, 0xF0, +0x54, 0x01, 0xFF, 0x12, 0x7C, 0x7E, 0xF1, 0xF0, 0x13, 0x54, 0x01, 0xFF, 0x12, 0x66, 0xDA, 0x90, +0x86, 0x72, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x01, 0xFF, 0x12, 0xAD, 0x29, 0x90, 0x86, 0x72, 0xE0, +0x54, 0x01, 0xFF, 0x12, 0xAB, 0xEF, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, +0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F, 0xFF, 0xF0, 0x12, 0x02, 0xF6, 0xFE, 0x22, +0x8F, 0x6E, 0x8D, 0x6F, 0xEF, 0x12, 0x92, 0x71, 0xE0, 0xF5, 0x70, 0x54, 0x7F, 0xF5, 0x71, 0xE5, +0x70, 0x54, 0x80, 0xF5, 0x73, 0x75, 0xF0, 0x12, 0xEF, 0x12, 0xC8, 0x90, 0xF5, 0x75, 0x75, 0xF0, +0x12, 0xEF, 0x71, 0x44, 0xC4, 0x54, 0x03, 0xF5, 0x76, 0x12, 0xC8, 0x81, 0x74, 0xFF, 0xF0, 0x12, +0xB2, 0x8E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x70, 0x45, 0x73, 0xFF, 0x12, 0xB2, 0x82, 0xEF, +0xF0, 0xE5, 0x6E, 0x12, 0x91, 0xD8, 0xE0, 0x54, 0x03, 0xF5, 0x74, 0x74, 0x4C, 0x25, 0x6E, 0x12, +0xB7, 0xD3, 0xE5, 0x74, 0xF0, 0xE5, 0x71, 0x65, 0x75, 0x70, 0x41, 0xB1, 0xA2, 0xC4, 0x13, 0x54, +0x07, 0x30, 0xE0, 0x0C, 0xE5, 0x73, 0x70, 0x08, 0xE5, 0x71, 0x44, 0x80, 0xF5, 0x70, 0xE1, 0x53, +0x12, 0xB2, 0x8E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0xB2, 0xA2, 0x12, 0xC9, 0x00, 0x12, 0xB2, +0x77, 0xE5, 0x6E, 0xF0, 0xE4, 0x90, 0x92, 0x43, 0x12, 0x96, 0xD2, 0x7B, 0x01, 0xFA, 0x7D, 0x02, +0x7F, 0x04, 0x12, 0x97, 0x1A, 0x7D, 0x07, 0xAF, 0x6E, 0x02, 0xC0, 0xC9, 0xE5, 0x71, 0xC3, 0x95, +0x75, 0x50, 0x58, 0xAB, 0x6E, 0xAD, 0x75, 0xAF, 0x71, 0x12, 0x72, 0xEA, 0x8F, 0x72, 0x85, 0x72, +0x70, 0xB1, 0xA2, 0xC4, 0x13, 0x54, 0x01, 0xFF, 0x90, 0x92, 0x43, 0x12, 0xB2, 0x76, 0xE5, 0x72, +0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x71, 0xF0, 0xE5, 0x73, 0xB1, 0x9B, 0x12, 0x97, 0xE3, 0xE4, +0xFB, 0xFA, 0x12, 0xC9, 0x48, 0xE5, 0x71, 0xC3, 0x94, 0x0C, 0x40, 0x27, 0xB1, 0xA2, 0xC4, 0x13, +0x54, 0x07, 0x30, 0xE0, 0x1E, 0xE5, 0x6F, 0x60, 0x1A, 0xE5, 0x73, 0x70, 0x16, 0xE5, 0x71, 0x44, +0x80, 0xF5, 0x70, 0x12, 0xC8, 0x81, 0xE5, 0x72, 0xF0, 0x80, 0x08, 0x12, 0xB2, 0x82, 0xE5, 0x75, +0xF0, 0xF5, 0x70, 0x12, 0xB2, 0x7B, 0xE5, 0x70, 0xF0, 0x12, 0xC8, 0x81, 0xE0, 0xFF, 0x12, 0xC8, +0xE7, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x74, 0x12, 0xB7, 0xCB, 0xF0, 0x7B, 0x01, 0x7A, +0x00, 0x12, 0xC9, 0x48, 0x90, 0x91, 0x0B, 0xE5, 0x74, 0xF0, 0xAB, 0x6F, 0xAD, 0x70, 0xAF, 0x6E, +0x02, 0x27, 0x3D, 0x4D, 0xFF, 0x90, 0x86, 0x72, 0xF0, 0xEE, 0x22, 0x7F, 0x8F, 0x12, 0x7B, 0x51, +0xEF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x24, 0xEF, 0xF0, 0xF1, 0x8B, +0x30, 0xE6, 0x39, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0xEF, 0x64, 0x01, 0x70, 0x2F, 0x90, 0x93, 0x25, +0xF0, 0x90, 0x93, 0x25, 0xE0, 0xFD, 0x90, 0x93, 0x24, 0xE0, 0x12, 0x92, 0x71, 0xE5, 0x82, 0x2D, +0x12, 0xA7, 0x33, 0xE0, 0xFB, 0xE4, 0xFF, 0x91, 0x72, 0x90, 0x93, 0x25, 0xE0, 0x04, 0xF0, 0xE0, +0xC3, 0x94, 0x10, 0x40, 0xDC, 0xF1, 0x8B, 0x30, 0xE0, 0x02, 0xF1, 0xF9, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0xF0, 0x90, 0x00, 0x03, 0x02, 0x03, 0x0F, 0x4D, 0xFF, 0x90, 0x86, 0x75, 0xF0, 0xEE, 0x22, +0x90, 0x86, 0x72, 0xE0, 0x13, 0x13, 0x22, 0x61, 0x4C, 0xE4, 0xFD, 0x7F, 0x8D, 0x02, 0x7B, 0x3E, +0x8B, 0x5B, 0x8A, 0x5C, 0x89, 0x5D, 0x90, 0x92, 0x8A, 0xE0, 0x70, 0x0C, 0x12, 0xC9, 0x21, 0x30, +0xE0, 0x06, 0x90, 0x92, 0x90, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x8C, 0xE0, 0x70, 0x0F, 0x31, 0xC1, +0xC4, 0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x06, 0x90, 0x92, 0x91, 0x74, 0x01, 0xF0, 0xAB, 0x5B, 0xAA, +0x5C, 0xA9, 0x5D, 0x12, 0x8D, 0x91, 0xFF, 0xF5, 0x5F, 0x12, 0x02, 0xF6, 0xFE, 0xC3, 0x13, 0x30, +0xE0, 0x07, 0x12, 0x8C, 0xA8, 0xF5, 0x60, 0x80, 0x02, 0x8F, 0x60, 0x85, 0x5F, 0x5E, 0xE5, 0x5E, +0xD3, 0x95, 0x60, 0x50, 0x28, 0x31, 0xC1, 0x54, 0x01, 0xFD, 0xAF, 0x5E, 0x12, 0x6E, 0x5F, 0xAF, +0x5E, 0x12, 0x77, 0x39, 0xEF, 0xAF, 0x5E, 0x70, 0x04, 0x11, 0x98, 0x80, 0x02, 0xF1, 0xF9, 0x90, +0x92, 0x91, 0xE0, 0x60, 0x04, 0xAF, 0x5E, 0x11, 0x98, 0x05, 0x5E, 0x80, 0xD1, 0xE5, 0x5F, 0x70, +0x16, 0xFF, 0x12, 0x77, 0x39, 0xEF, 0x70, 0x0F, 0x12, 0xAE, 0x52, 0x12, 0x79, 0x61, 0x12, 0xA7, +0xDD, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22, 0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x92, 0x07, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x7D, 0x44, 0x7F, 0x6F, 0x11, 0xDB, 0x11, +0xE6, 0x90, 0x92, 0x08, 0xE0, 0x90, 0x92, 0x07, 0xB4, 0x01, 0x09, 0xE0, 0x31, 0xD8, 0xE0, 0x44, +0x04, 0xF0, 0x80, 0x07, 0xE0, 0x31, 0xD8, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0xFD, 0xFF, 0x11, 0xDB, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0xAE, 0x52, 0xE4, 0xFD, 0xFF, 0x90, 0x05, 0x22, 0xEF, 0xF0, +0x90, 0x92, 0x81, 0xED, 0xF0, 0x22, 0xE4, 0x90, 0x93, 0x16, 0xF0, 0xA3, 0xF0, 0x90, 0x05, 0x22, +0xE0, 0x90, 0x93, 0x18, 0xF0, 0x7D, 0x47, 0x7F, 0xFF, 0x11, 0xDB, 0x90, 0x05, 0xF8, 0xE0, 0x70, +0x13, 0xA3, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0x31, 0xB9, 0x11, +0xDB, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x93, 0x17, 0xE0, 0x94, 0xE8, 0x90, 0x93, 0x16, 0xE0, 0x94, +0x03, 0x40, 0x0E, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x31, 0xB9, 0x11, 0xDB, 0x7F, 0x00, +0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x93, 0x16, 0xE4, 0x75, 0xF0, 0x01, 0x12, +0x07, 0x0A, 0x80, 0xB7, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x76, 0xEF, 0xF0, +0xA3, 0xED, 0xF0, 0x90, 0x84, 0xC3, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x2D, 0x90, +0x05, 0x22, 0xE0, 0x90, 0x92, 0x7A, 0xF0, 0x7D, 0x26, 0x7F, 0xFF, 0x11, 0xDB, 0x11, 0xE6, 0xEF, +0x64, 0x01, 0x70, 0x0B, 0x31, 0xCA, 0xFB, 0x7D, 0x01, 0x12, 0x3A, 0xC2, 0x12, 0xC8, 0x56, 0x90, +0x92, 0x7A, 0xE0, 0xFF, 0x7D, 0x27, 0x11, 0xDB, 0x31, 0xB1, 0x80, 0x13, 0x31, 0xB1, 0x31, 0xCA, +0xFB, 0x90, 0x93, 0x15, 0x74, 0x0A, 0xF0, 0x7D, 0x01, 0x12, 0xC2, 0x43, 0x12, 0xC8, 0x56, 0x90, +0x04, 0x1F, 0x74, 0x20, 0xF0, 0x12, 0xC6, 0xDC, 0x74, 0x01, 0xF0, 0xFF, 0xD0, 0xD0, 0x92, 0xAF, +0x22, 0x90, 0x92, 0x76, 0xE0, 0xFF, 0x02, 0x5C, 0xA3, 0x90, 0x93, 0x18, 0xE0, 0xFF, 0x7D, 0x48, +0x22, 0xAB, 0x5B, 0xAA, 0x5C, 0xA9, 0x5D, 0x02, 0x02, 0xF6, 0x90, 0x84, 0xC8, 0xE0, 0xFF, 0x90, +0x92, 0x77, 0xE0, 0x22, 0xE0, 0xFD, 0xE5, 0x78, 0xC4, 0x54, 0xF0, 0x24, 0x05, 0xF5, 0x82, 0xE4, +0x34, 0x81, 0xF5, 0x83, 0x22, 0x8D, 0x78, 0xEF, 0x30, 0xE6, 0x15, 0x51, 0x6F, 0x31, 0xD4, 0xF1, +0xD1, 0xE4, 0xFB, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0x51, 0x62, 0xF1, 0x9B, 0x74, 0x01, 0x80, 0x59, +0xF1, 0xED, 0xE0, 0x04, 0xF0, 0xF1, 0xED, 0xE0, 0x64, 0x02, 0x70, 0x25, 0x74, 0xD7, 0x25, 0x78, +0x12, 0xC8, 0x85, 0xE0, 0xFD, 0xF4, 0x60, 0x02, 0x80, 0x04, 0x51, 0x6F, 0xE0, 0xFD, 0x31, 0xD6, +0xF1, 0xD1, 0x7B, 0x01, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0x51, 0x6F, 0xF1, 0x9B, 0x74, 0x02, 0x80, +0x28, 0xF1, 0xED, 0xE0, 0xD3, 0x94, 0x03, 0x40, 0x0D, 0xAF, 0x78, 0x12, 0x6D, 0x94, 0x51, 0x62, +0xF1, 0x9B, 0x74, 0x03, 0x80, 0x13, 0x51, 0x6F, 0x31, 0xD4, 0xF1, 0xD1, 0x7B, 0x01, 0xAF, 0x78, +0x12, 0x27, 0x3D, 0x51, 0x6F, 0xF1, 0x9B, 0x74, 0x02, 0xF0, 0xAB, 0x78, 0xE4, 0xFD, 0xFF, 0x02, +0x52, 0xC3, 0x74, 0xBC, 0x25, 0x78, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE4, 0xF0, 0xE5, +0x78, 0xC4, 0x54, 0xF0, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0x90, 0x04, +0x85, 0xE0, 0xF5, 0x6B, 0x90, 0x92, 0xD6, 0xE0, 0x04, 0xF0, 0xE4, 0xF5, 0x62, 0x90, 0x85, 0xBB, +0xE0, 0xFF, 0xE5, 0x62, 0xC3, 0x9F, 0x40, 0x02, 0xC1, 0xBE, 0xE5, 0x62, 0x51, 0x71, 0xE0, 0xF5, +0x6D, 0x12, 0xC8, 0xDB, 0xE0, 0x65, 0x6D, 0x60, 0x16, 0x90, 0x8A, 0x71, 0xE5, 0x6D, 0xF0, 0xE4, +0xA3, 0xF0, 0xAB, 0x62, 0xFD, 0xFF, 0x12, 0x52, 0xC3, 0x12, 0xC8, 0xDB, 0xE5, 0x6D, 0xF0, 0x90, +0x04, 0xA0, 0xE0, 0x64, 0x01, 0x70, 0x4C, 0xA3, 0xE0, 0x65, 0x62, 0x70, 0x46, 0xA3, 0xE0, 0xF5, +0x63, 0xA3, 0xE0, 0x90, 0x92, 0x38, 0xF0, 0xE5, 0x62, 0x51, 0x71, 0xE0, 0x65, 0x63, 0x70, 0x02, +0xC1, 0xBA, 0xE5, 0x62, 0x51, 0x71, 0xE5, 0x63, 0xF0, 0xE5, 0x62, 0x31, 0xD8, 0xE0, 0x54, 0xFC, +0xFF, 0x90, 0x92, 0x38, 0xE0, 0x54, 0x03, 0x4F, 0xFF, 0xE5, 0x62, 0x31, 0xD8, 0xEF, 0xF0, 0x90, +0x8A, 0x71, 0xE5, 0x63, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0xAB, 0x62, 0xE4, 0xFD, 0xFF, 0x12, 0x52, +0xC3, 0xC1, 0xBA, 0xAF, 0x62, 0x12, 0x77, 0x39, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0x8B, 0x44, +0x12, 0x8D, 0x9B, 0xFD, 0xF1, 0xC4, 0xED, 0xF0, 0x90, 0x92, 0x41, 0x12, 0xB2, 0x76, 0xE5, 0x62, +0xF0, 0x12, 0xB1, 0x13, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, +0x5C, 0xFE, 0xEF, 0x5D, 0xFF, 0x90, 0x92, 0x45, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x7B, 0x02, 0x7A, +0x00, 0xE4, 0xFD, 0x7F, 0x01, 0xF1, 0x1A, 0x12, 0xB3, 0x9B, 0xFF, 0xF1, 0xD9, 0x12, 0x05, 0x28, +0xE0, 0xFD, 0xE5, 0x62, 0x12, 0xC8, 0xB4, 0x54, 0x80, 0xFB, 0xF1, 0xC4, 0xEB, 0xF0, 0x12, 0xC8, +0xE7, 0xED, 0xF0, 0x90, 0x92, 0x3F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x45, 0xF0, +0xA3, 0xF0, 0x7B, 0x03, 0xFA, 0xFD, 0x7F, 0x01, 0xF1, 0x1A, 0xAF, 0x62, 0x12, 0x77, 0x39, 0xEF, +0x70, 0x02, 0xC1, 0xBA, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0x8B, 0x44, 0x12, 0x8D, 0x9B, 0x30, +0xE0, 0x02, 0xC1, 0xBA, 0xE5, 0x62, 0x12, 0xB1, 0x13, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, 0x60, 0x02, 0xC1, 0xBA, 0x12, 0xB3, +0x9B, 0x4E, 0x70, 0x0A, 0xF1, 0xD9, 0x12, 0x05, 0x28, 0xE0, 0x70, 0x02, 0xC1, 0xBA, 0xE5, 0x62, +0x75, 0xF0, 0x12, 0xA4, 0x24, 0x44, 0xF9, 0x74, 0x89, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90, 0x92, +0x33, 0x12, 0x87, 0x79, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0x12, 0xC9, 0x40, 0x12, 0x03, 0xED, +0x2F, 0xFF, 0xF1, 0xB2, 0x2F, 0xFF, 0xF1, 0xB8, 0x2F, 0xFF, 0xF1, 0xBE, 0x2F, 0xF5, 0x6C, 0x75, +0xF0, 0x12, 0xE5, 0x62, 0x90, 0x89, 0x40, 0x12, 0x05, 0x28, 0xE0, 0xF5, 0x68, 0xA3, 0xE0, 0xF5, +0x69, 0xF1, 0xD9, 0x12, 0x05, 0x28, 0xE0, 0xFF, 0x90, 0x92, 0x36, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, +0xE5, 0x62, 0x51, 0x71, 0xE0, 0xF5, 0x63, 0x54, 0x80, 0xF5, 0x65, 0xE5, 0x63, 0x54, 0x7F, 0xF5, +0x64, 0x12, 0xC8, 0xF7, 0xF1, 0x90, 0x12, 0xC9, 0x40, 0x90, 0x92, 0x41, 0xF1, 0x94, 0xF1, 0xB2, +0xFF, 0x90, 0x92, 0x43, 0xF1, 0x94, 0xF1, 0xB8, 0xFF, 0x90, 0x92, 0x45, 0xF1, 0x94, 0x7B, 0x01, +0xF1, 0xAA, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0xF1, 0xBE, 0xF1, 0x90, 0x90, 0x92, 0x36, 0x12, +0xC9, 0x00, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0x12, 0xC9, 0x38, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x63, +0xF0, 0x7B, 0x02, 0xF1, 0xAA, 0x74, 0x7C, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, +0xE0, 0xC3, 0x94, 0x05, 0x40, 0x02, 0xC1, 0x9F, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0xC8, 0x90, +0xFF, 0xE5, 0x64, 0xD3, 0x9F, 0x40, 0x08, 0x8F, 0x64, 0xE5, 0x64, 0x45, 0x65, 0xF5, 0x63, 0xE5, +0x64, 0x90, 0x82, 0xE1, 0x93, 0xF5, 0x6A, 0xE5, 0x65, 0x60, 0x04, 0x05, 0x6A, 0x05, 0x6A, 0x90, +0x04, 0x8C, 0xE0, 0x64, 0x01, 0x70, 0x28, 0xE5, 0x64, 0xC3, 0x94, 0x0C, 0x40, 0x21, 0x74, 0x84, +0x25, 0x64, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFF, 0x54, 0x7F, 0xFE, 0xEF, 0x30, +0xE7, 0x06, 0xE5, 0x6A, 0x2E, 0xFF, 0x80, 0x05, 0xC3, 0xE5, 0x6A, 0x9E, 0xFF, 0x8F, 0x6A, 0xE5, +0x6A, 0xD3, 0x94, 0x1A, 0xAF, 0x6A, 0x40, 0x02, 0x7F, 0x1A, 0x8F, 0x6A, 0xD1, 0xC4, 0x7B, 0x03, +0xFA, 0xF1, 0xAC, 0xE5, 0x63, 0x90, 0x83, 0x59, 0x93, 0xFF, 0xD3, 0x90, 0x92, 0x37, 0xE0, 0x9F, +0x90, 0x92, 0x36, 0xE0, 0x94, 0x00, 0x40, 0x02, 0x80, 0x73, 0xC3, 0xE5, 0x69, 0x94, 0x0A, 0xE5, +0x68, 0x94, 0x00, 0x40, 0x02, 0xA1, 0xED, 0xF1, 0x08, 0xE0, 0xC3, 0x94, 0x01, 0x40, 0x05, 0xF1, +0x08, 0xE0, 0x14, 0xF0, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0xF1, 0xBE, 0xFF, 0x90, 0x92, 0x37, +0xE0, 0x2F, 0xFF, 0x90, 0x92, 0x36, 0xE0, 0x35, 0xF0, 0xFE, 0xF1, 0xB8, 0x2F, 0xFF, 0xEE, 0x35, +0xF0, 0xFE, 0xF1, 0xB2, 0x2F, 0xFD, 0xEE, 0x35, 0xF0, 0xFC, 0xE5, 0x68, 0xC3, 0x13, 0xFE, 0xE5, +0x69, 0x13, 0xFF, 0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, 0x28, 0xE5, 0x62, 0x94, 0x05, 0x50, 0x05, +0xF1, 0x08, 0x74, 0x03, 0xF0, 0x90, 0x92, 0x3F, 0x12, 0xC9, 0x38, 0xE5, 0x68, 0xC3, 0x13, 0xA3, +0xF0, 0xE5, 0x69, 0x13, 0xA3, 0xD1, 0xDA, 0xF1, 0xE2, 0x7B, 0x01, 0xF1, 0x14, 0x12, 0xB1, 0xA4, +0xC1, 0x9F, 0x12, 0xC8, 0xF7, 0x65, 0x6C, 0x70, 0x02, 0xE5, 0xF0, 0x70, 0x50, 0x90, 0x92, 0x3F, +0xF0, 0xA3, 0xE5, 0x6C, 0xF0, 0xC3, 0x13, 0xFF, 0xA3, 0xE4, 0xF0, 0xA3, 0xEF, 0xD1, 0xDA, 0xF1, +0xE2, 0x7B, 0x02, 0xF1, 0x14, 0xE5, 0x62, 0xC3, 0x94, 0x05, 0x50, 0x0E, 0xF1, 0x08, 0xE0, 0xD3, +0x94, 0x00, 0x40, 0x06, 0xD1, 0xBF, 0x7B, 0x03, 0x80, 0x0B, 0xE5, 0x6C, 0xC3, 0x94, 0x03, 0x50, +0x10, 0xD1, 0xBF, 0x7B, 0x04, 0xFA, 0xF1, 0x16, 0x7D, 0x06, 0xAF, 0x62, 0x12, 0xC0, 0xC9, 0xC1, +0xBA, 0xE4, 0xFD, 0xAF, 0x62, 0x12, 0x8E, 0x50, 0x12, 0xC0, 0xC5, 0xC1, 0x9F, 0xD1, 0xBF, 0x7B, +0x08, 0xFA, 0xF1, 0x16, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0x65, 0xC2, 0xC1, 0x9F, 0xF1, 0x08, 0xE4, +0xF0, 0x90, 0x92, 0x3D, 0x74, 0x02, 0xF0, 0xAB, 0x6A, 0xAD, 0x62, 0xAF, 0x69, 0xAE, 0x68, 0x12, +0xB2, 0xB0, 0x8E, 0x66, 0x8F, 0x67, 0x12, 0xC8, 0xA6, 0xC3, 0x74, 0x01, 0x93, 0x95, 0x67, 0xE4, +0x93, 0x95, 0x66, 0x50, 0x18, 0xF1, 0x84, 0xE4, 0xF0, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0x8E, 0x50, +0x12, 0xC8, 0x08, 0xE4, 0x90, 0x92, 0x43, 0xD1, 0xD2, 0x7B, 0x01, 0x80, 0x22, 0xF1, 0xA2, 0xC3, +0xE5, 0x67, 0x9F, 0xE5, 0x66, 0x94, 0x00, 0x50, 0x1B, 0xF1, 0x84, 0xE4, 0xF0, 0x12, 0xB1, 0xA4, +0x12, 0xC8, 0x23, 0xF1, 0xA2, 0x12, 0xC8, 0xE7, 0xEF, 0xF0, 0xE4, 0xD1, 0xD1, 0x7B, 0x02, 0xFA, +0xF1, 0xCB, 0x80, 0x4B, 0x12, 0xC0, 0xC5, 0x12, 0xC8, 0x08, 0xF1, 0xA2, 0xF1, 0xC4, 0xEF, 0xF0, +0xF1, 0x84, 0xF1, 0xE2, 0x7B, 0x03, 0x7A, 0x00, 0xF1, 0xCB, 0xF1, 0x84, 0xE0, 0x04, 0xF0, 0xE5, +0x64, 0x90, 0x83, 0x6D, 0x93, 0xFF, 0xF1, 0x84, 0xE0, 0xC3, 0x9F, 0x40, 0x22, 0xF1, 0x84, 0xE4, +0xF0, 0xF1, 0xA2, 0x12, 0xC8, 0xA6, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x34, 0x00, 0xC3, +0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xE5, 0x62, 0x12, 0xB2, 0xA4, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, +0xF5, 0x6C, 0xFD, 0xAF, 0x62, 0x12, 0x65, 0xC2, 0xE4, 0x90, 0x92, 0x3F, 0xF0, 0xD1, 0xCD, 0xA3, +0xF0, 0x7B, 0x01, 0xFA, 0x7D, 0xFF, 0x7F, 0x01, 0xF1, 0x1A, 0x05, 0x62, 0x41, 0x8D, 0x22, 0x90, +0x92, 0xD6, 0xE0, 0xFF, 0x90, 0x92, 0x3F, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, +0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xF0, 0x90, 0x92, 0x33, 0x12, 0x87, +0x70, 0x90, 0x00, 0x06, 0x12, 0x04, 0x18, 0xFF, 0xAE, 0xF0, 0x90, 0x00, 0x08, 0x12, 0x04, 0x18, +0x2F, 0xFF, 0xE5, 0xF0, 0x3E, 0xFE, 0x90, 0x00, 0x04, 0x12, 0x04, 0x18, 0x2F, 0xFF, 0xEE, 0x35, +0xF0, 0x90, 0x92, 0x43, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0xE7, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, +0x92, 0xF5, 0x83, 0x22, 0x7A, 0x00, 0x7D, 0x03, 0x7F, 0x01, 0x90, 0x01, 0xC6, 0xE0, 0xFE, 0x64, +0x80, 0x70, 0x60, 0x90, 0x92, 0x49, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xEB, 0xA3, 0xF0, 0xEA, 0xA3, +0xF0, 0x90, 0x92, 0x3F, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x4D, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, +0x92, 0x41, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x4F, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x43, +0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x51, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x45, 0xE0, 0xFC, +0xA3, 0xE0, 0x90, 0x92, 0x53, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x47, 0x74, 0xFE, 0xF0, 0x90, +0x92, 0x55, 0x74, 0x0C, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x47, 0x12, 0x5E, 0x10, 0x7F, 0x04, +0x12, 0x87, 0xBB, 0x22, 0x74, 0xAC, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, +0xFF, 0x90, 0x92, 0x3F, 0xE5, 0xF0, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xE0, 0x90, 0x8A, 0x71, 0xF0, +0xA3, 0x22, 0xE5, 0x64, 0x90, 0x83, 0x1D, 0x93, 0xFF, 0x22, 0x7A, 0x00, 0x7D, 0x01, 0x7F, 0x01, +0xE1, 0x1A, 0x90, 0x00, 0x04, 0x02, 0x04, 0x18, 0x90, 0x00, 0x06, 0x02, 0x04, 0x18, 0x90, 0x00, +0x08, 0x02, 0x04, 0x18, 0x90, 0x92, 0x43, 0xE4, 0xF0, 0xA3, 0x22, 0x7D, 0x05, 0x7F, 0x01, 0xE1, +0x1A, 0xE0, 0x54, 0x03, 0x90, 0x91, 0x0B, 0xF0, 0x22, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x90, 0x89, +0x42, 0x22, 0xE0, 0xFF, 0x90, 0x92, 0x45, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x74, 0xBC, 0x25, +0x78, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0x22, 0xE4, 0xFD, 0x01, 0x9A, 0x12, 0x02, 0xF6, +0xFF, 0x90, 0x92, 0x83, 0xF0, 0xBF, 0x01, 0x07, 0x11, 0x10, 0xE4, 0x90, 0x92, 0x83, 0xF0, 0x22, +0x7B, 0x01, 0x7A, 0x92, 0x79, 0x07, 0x7F, 0xF5, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x06, +0x90, 0x92, 0x07, 0xE0, 0xA3, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x07, 0x7F, 0xF6, 0x7E, 0x01, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x09, 0xF0, 0x7B, 0x01, +0x7A, 0x92, 0x79, 0x07, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, +0x07, 0xE0, 0x90, 0x92, 0x0A, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x07, 0x7F, 0xF3, 0x7E, 0x01, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x7B, 0x01, +0x7A, 0x92, 0x79, 0x07, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, +0x07, 0xE0, 0x90, 0x92, 0x0C, 0xF0, 0x90, 0x92, 0x08, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, +0xFB, 0xA3, 0xE0, 0x90, 0x92, 0x10, 0xF0, 0x90, 0x92, 0x0C, 0xE0, 0x90, 0x92, 0x11, 0xF0, 0x90, +0x92, 0x12, 0x74, 0x12, 0xF0, 0x90, 0x92, 0x20, 0x74, 0x05, 0xF0, 0x90, 0x92, 0x14, 0xEF, 0xF0, +0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x92, 0x10, 0xE0, 0x90, 0x92, 0x17, 0xF0, 0x90, 0x92, +0x11, 0xE0, 0x90, 0x92, 0x18, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x12, 0x12, 0x5E, 0x10, 0x7F, +0x04, 0x02, 0x87, 0xBB, 0x12, 0x02, 0xF6, 0x54, 0x01, 0xFF, 0x90, 0x92, 0x95, 0xE0, 0x54, 0xFE, +0x4F, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x5B, 0x8A, 0x5C, 0x89, 0x5D, +0x90, 0x05, 0x27, 0xE0, 0xF5, 0x5E, 0x8B, 0x1B, 0x8A, 0x1C, 0x89, 0x1D, 0x75, 0x1E, 0x01, 0x7B, +0x01, 0x7A, 0x85, 0x79, 0xBC, 0x12, 0x6A, 0x21, 0x12, 0x91, 0xC1, 0xFF, 0xC3, 0x13, 0x20, 0xE0, +0x02, 0x21, 0x9B, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x70, 0xB1, 0x13, 0x75, 0x5E, 0x21, 0xB1, +0x2B, 0x30, 0xE0, 0x04, 0xB1, 0xF0, 0x80, 0x0D, 0xE4, 0x90, 0x85, 0xBD, 0xF0, 0xA3, 0xF0, 0x7D, +0x40, 0xFF, 0x12, 0x7C, 0x41, 0xB1, 0x22, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x12, 0xEF, +0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x14, 0x90, 0x85, 0xBC, 0xE0, 0xC4, 0x13, 0x54, +0x07, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x80, 0x90, 0x85, 0xBC, 0x12, 0xB7, 0xDE, 0x20, 0xE0, 0x03, +0x43, 0x5E, 0x40, 0x51, 0x41, 0x90, 0x85, 0xBF, 0xE0, 0x70, 0x04, 0x7F, 0x01, 0x71, 0xF7, 0x90, +0x85, 0xBC, 0xB1, 0x1A, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80, 0x0B, 0xB1, 0x34, 0xEF, 0x60, 0x04, +0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x71, 0xF7, 0x80, 0x7F, 0x51, 0x3E, 0x90, 0x85, 0xBF, 0xE0, +0x64, 0x04, 0x60, 0x02, 0x41, 0x39, 0xFF, 0x71, 0xF7, 0x41, 0x39, 0x90, 0x85, 0xBC, 0xE0, 0x30, +0xE0, 0x6F, 0xB1, 0x13, 0x43, 0x5E, 0x31, 0xB1, 0x2B, 0x30, 0xE0, 0x04, 0xB1, 0xF0, 0x80, 0x07, +0x7D, 0x40, 0xE4, 0xFF, 0x12, 0x7C, 0x41, 0xB1, 0x22, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43, 0x5E, +0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x04, 0x51, 0x41, 0x90, 0x85, 0xBC, +0xB1, 0x1A, 0x30, 0xE0, 0x0A, 0xD1, 0xAB, 0x60, 0x30, 0xE4, 0xFD, 0x7F, 0x02, 0x80, 0x1E, 0x12, +0xC0, 0x69, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x18, 0x12, 0x7A, 0xA2, 0xB1, 0x34, 0xBF, 0x01, +0x09, 0x90, 0x85, 0xC7, 0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD, 0xFF, 0x51, 0x4C, 0x80, +0x08, 0x90, 0x85, 0xC8, 0xE0, 0x90, 0x85, 0xC0, 0xF0, 0x90, 0x05, 0x40, 0x74, 0x22, 0xF0, 0x80, +0x28, 0x51, 0x3E, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x06, 0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B, +0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x08, 0x06, 0x7D, 0x01, 0x7F, 0x0C, 0x51, 0x4C, 0x12, 0xC4, 0xC9, +0x90, 0x85, 0xC7, 0x12, 0xA3, 0xBB, 0x12, 0xC4, 0x63, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, 0x5E, +0x01, 0x90, 0x05, 0x27, 0xE5, 0x5E, 0xF0, 0x22, 0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x2A, 0xED, 0xF0, 0x90, 0x85, 0xC1, 0xE0, 0xFE, 0xC4, 0x13, 0x13, +0x54, 0x03, 0x30, 0xE0, 0x02, 0x61, 0xA7, 0xEE, 0x12, 0x8D, 0x9B, 0x30, 0xE0, 0x02, 0x61, 0xA7, +0x90, 0x85, 0xC8, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0x61, 0xA7, 0xEF, 0x70, 0x02, 0x61, 0x12, 0x24, +0xFE, 0x70, 0x02, 0x61, 0x4F, 0x24, 0xFE, 0x60, 0x4D, 0x24, 0xFC, 0x70, 0x02, 0x61, 0x8E, 0x24, +0xFC, 0x60, 0x02, 0x61, 0xA0, 0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, +0x70, 0x05, 0x7F, 0x01, 0x12, 0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, +0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x0F, 0x90, 0x93, 0x2A, 0xE0, 0xFF, 0x60, 0x05, 0x12, +0x6D, 0x4C, 0x80, 0x03, 0x12, 0x79, 0x61, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x08, 0x60, 0x02, 0x61, +0xA0, 0x12, 0x7A, 0xB9, 0x61, 0xA0, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x79, +0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, +0x0E, 0x08, 0x71, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x0C, +0x60, 0x02, 0x61, 0xA0, 0x71, 0xAC, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61, 0xA0, 0x12, 0x70, 0x9E, +0x61, 0xA0, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0x71, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, +0x93, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, +0x0C, 0x08, 0x71, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x04, +0x70, 0x5E, 0x12, 0xBB, 0x71, 0xEF, 0x64, 0x01, 0x70, 0x56, 0x12, 0x77, 0xFE, 0x80, 0x51, 0x90, +0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0x71, 0xAC, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, +0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0C, 0x08, 0x71, +0xAC, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, +0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x17, 0x12, 0x79, 0xF3, 0x80, 0x12, 0x90, 0x85, +0xC8, 0xE0, 0xB4, 0x0C, 0x0B, 0x12, 0xA1, 0x6B, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x12, 0x7A, 0x8A, +0x90, 0x85, 0xC8, 0x12, 0xC8, 0xC2, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x0E, 0x01, 0x80, 0x24, +0x90, 0x85, 0xC1, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x05, 0x75, 0x0E, 0x02, 0x80, +0x13, 0x90, 0x85, 0xC7, 0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75, 0x0E, 0x08, 0x80, 0x05, 0x12, +0xBB, 0x5C, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x0E, 0xF0, +0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x85, +0xBF, 0xE0, 0x90, 0x93, 0x29, 0xF0, 0x6F, 0x70, 0x02, 0xA1, 0x0E, 0xEF, 0x14, 0x60, 0x46, 0x14, +0x60, 0x72, 0x14, 0x70, 0x02, 0x81, 0xB2, 0x14, 0x70, 0x02, 0x81, 0xE1, 0x24, 0x04, 0x60, 0x02, +0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xC4, 0xA7, 0xA1, 0x0E, 0x90, 0x93, +0x29, 0xE0, 0xB4, 0x02, 0x05, 0x12, 0xC4, 0xAC, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, +0x05, 0x12, 0xC4, 0xA3, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0x64, 0x01, 0x60, 0x02, 0xA1, 0x0E, +0x12, 0xC4, 0x96, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xAF, 0xDA, 0xA1, +0x0E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x02, 0x04, 0xF1, 0xEC, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, +0xB4, 0x03, 0x05, 0x12, 0xC4, 0xB1, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0x60, 0x02, 0xA1, 0x0E, +0xF1, 0xE5, 0xA1, 0x0E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xC0, 0x5E, 0x80, 0x7E, +0x90, 0x93, 0x29, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0xC0, 0x4E, 0x80, 0x72, 0x90, 0x93, 0x29, 0xE0, +0xB4, 0x03, 0x04, 0xF1, 0xF1, 0x80, 0x67, 0x90, 0x93, 0x29, 0xE0, 0x70, 0x61, 0x12, 0xC0, 0x64, +0x80, 0x5C, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x05, 0x12, 0xAE, 0x8C, 0x80, 0x50, 0x90, 0x93, +0x29, 0xE0, 0xB4, 0x01, 0x05, 0x12, 0xAF, 0xB5, 0x80, 0x44, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x02, +0x05, 0x12, 0xAE, 0x7B, 0x80, 0x38, 0x90, 0x93, 0x29, 0xE0, 0x70, 0x32, 0x12, 0xAF, 0xBE, 0x80, +0x2D, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, 0x05, 0x12, 0xC4, 0xBA, 0x80, 0x21, 0x90, 0x93, 0x29, +0xE0, 0xB4, 0x01, 0x05, 0x12, 0xC4, 0x82, 0x80, 0x15, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x02, 0x05, +0x12, 0xAE, 0x97, 0x80, 0x09, 0x90, 0x93, 0x29, 0xE0, 0x70, 0x03, 0x12, 0xC4, 0x91, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x7D, 0x03, 0x7F, 0x02, 0x02, 0x7B, 0xFD, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x54, +0x03, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x22, 0x90, 0x05, 0x43, 0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, +0xE4, 0xF5, 0x77, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0xA1, 0xDD, 0xF1, 0xF4, 0x64, 0x01, 0x60, +0x02, 0xA1, 0xDD, 0x12, 0xC8, 0x2E, 0x12, 0xA1, 0x83, 0x60, 0x22, 0x24, 0xFE, 0x60, 0x03, 0x04, +0x70, 0x1E, 0x90, 0x85, 0xCC, 0xE0, 0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x85, 0xCE, 0xE0, +0x60, 0x0E, 0xEF, 0x70, 0x08, 0x90, 0x85, 0xCB, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, 0x77, 0x01, +0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x11, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x03, 0xE4, 0xF5, +0x77, 0xB1, 0x34, 0xEF, 0x70, 0x02, 0xF5, 0x77, 0xE5, 0x77, 0x60, 0x41, 0x90, 0x85, 0xC8, 0xE0, +0x20, 0xE2, 0x02, 0x51, 0x48, 0x12, 0xC9, 0x29, 0x90, 0x85, 0xCE, 0xE0, 0x60, 0x04, 0x64, 0x01, +0x70, 0x13, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0xB1, 0xE9, 0xD1, 0x0D, 0x90, +0x85, 0xCE, 0xE0, 0x80, 0x12, 0xE4, 0x90, 0x91, 0x6E, 0xB1, 0xDE, 0xD1, 0x0D, 0x90, 0x85, 0xCE, +0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xB1, 0xE9, 0x90, 0x85, 0xDE, 0xF0, 0x22, 0xF0, 0x90, +0x85, 0xCE, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x85, 0xCD, 0xE0, 0x2F, 0x22, +0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x12, 0x7C, 0xA9, 0x43, 0x5E, 0x08, 0x22, +0xE0, 0x44, 0x02, 0xF0, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x86, 0x6E, 0xE0, 0x90, 0x91, 0x6F, +0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x02, 0x61, 0x41, 0xE4, 0x90, 0x92, 0x67, 0xF0, +0x90, 0x85, 0xC5, 0xE0, 0x60, 0x4F, 0xF1, 0xF4, 0x64, 0x01, 0x70, 0x49, 0x12, 0xA7, 0xE5, 0x12, +0xC8, 0x2E, 0x90, 0x92, 0x67, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x85, 0xCC, 0xF0, 0x90, 0x85, 0xBC, +0xE0, 0x30, 0xE0, 0x15, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x05, 0xE4, 0x90, 0x92, 0x67, 0xF0, +0xB1, 0x34, 0xEF, 0x70, 0x04, 0x90, 0x92, 0x67, 0xF0, 0x90, 0x92, 0x67, 0xE0, 0x60, 0x16, 0x90, +0x85, 0xC8, 0xE0, 0x20, 0xE2, 0x02, 0x51, 0x48, 0x12, 0xC9, 0x29, 0xE4, 0x90, 0x91, 0x6E, 0xF0, +0x90, 0x85, 0xCD, 0xD1, 0x0C, 0x22, 0xAE, 0x07, 0xB1, 0x34, 0xBF, 0x01, 0x12, 0x90, 0x85, 0xBC, +0x12, 0xB7, 0xDE, 0x20, 0xE0, 0x09, 0xAF, 0x06, 0x7D, 0x01, 0x51, 0x4C, 0x7F, 0x01, 0x22, 0x7F, +0x00, 0x22, 0x90, 0x85, 0xBC, 0xB1, 0x1A, 0x30, 0xE0, 0x0A, 0xD1, 0xAB, 0x60, 0x06, 0x7D, 0x01, +0x7F, 0x02, 0x51, 0x4C, 0xD1, 0xAB, 0x60, 0x02, 0xD1, 0xB2, 0x22, 0x90, 0x85, 0xC0, 0xE0, 0x64, +0x02, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x02, 0x60, 0x0F, 0xF1, 0x13, 0x60, 0x0B, 0x12, 0x7A, +0x29, 0xEF, 0x70, 0x05, 0xFD, 0x7F, 0x0C, 0x51, 0x4C, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x07, +0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x10, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x07, 0xB1, 0x34, +0xBF, 0x01, 0x04, 0x80, 0xCD, 0xD1, 0xE8, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x1B, +0xF1, 0x13, 0x60, 0x0F, 0xE4, 0xFD, 0x7F, 0x0C, 0x51, 0x4C, 0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xDB, +0x02, 0x6B, 0x98, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x02, 0x51, 0x48, 0x22, 0x90, 0x85, 0xC9, 0xE0, +0x44, 0x01, 0xF0, 0x90, 0x85, 0xC3, 0xE0, 0x54, 0x0F, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, +0xE0, 0x3C, 0x90, 0x85, 0xC0, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x85, 0xBF, +0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x22, 0xEF, 0xC3, 0x13, 0x30, +0xE0, 0x02, 0x80, 0x1B, 0xD1, 0x92, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x08, 0x06, 0xE4, 0xFD, 0x7F, +0x0C, 0x80, 0x09, 0x90, 0x85, 0xC0, 0xE0, 0x70, 0x05, 0xFD, 0x7F, 0x04, 0x51, 0x4C, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1, 0x34, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, +0x02, 0x71, 0xF7, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x92, 0x56, 0xF0, +0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x05, 0x12, 0xA3, 0xA4, 0x80, 0x56, 0xED, 0x30, 0xE6, 0x3F, 0x90, +0x85, 0xC5, 0xE0, 0x64, 0x02, 0x70, 0x27, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, +0x09, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x1A, 0xF1, 0x13, 0x64, 0x01, 0x70, 0x21, +0x90, 0x85, 0xC9, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x01, 0x12, 0x62, 0x8E, 0x80, 0x13, 0xF1, 0x0C, +0x64, 0x02, 0x60, 0x05, 0x12, 0x77, 0x61, 0x80, 0x08, 0x12, 0x79, 0x41, 0x80, 0x03, 0x12, 0xA3, +0xA4, 0x90, 0x92, 0x56, 0xE0, 0x90, 0x85, 0xC9, 0x30, 0xE7, 0x05, 0xD1, 0x00, 0x02, 0xA7, 0xD5, +0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x85, 0xBF, 0x74, 0x01, 0xF0, 0x22, 0x12, 0x90, 0xD5, 0x80, +0xF4, 0x02, 0xC0, 0x55, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xEF, 0x22, 0x12, 0x02, 0xF6, 0x90, 0x86, +0x71, 0xF0, 0x22, 0xF1, 0xCD, 0x90, 0x92, 0x84, 0xF1, 0xC5, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, +0x12, 0x8D, 0x8F, 0x90, 0x92, 0x85, 0x12, 0x8C, 0xA7, 0x90, 0x92, 0x86, 0xF0, 0x51, 0xFE, 0x90, +0x92, 0x84, 0xE0, 0x54, 0x01, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0x64, 0x01, +0x70, 0x19, 0x11, 0x6E, 0x60, 0x09, 0x11, 0x67, 0x12, 0x7B, 0xFD, 0x51, 0xF5, 0x80, 0x07, 0x11, +0x67, 0x12, 0x7B, 0xBF, 0x51, 0xB5, 0x12, 0x7A, 0x8A, 0x80, 0x17, 0x11, 0x6E, 0x60, 0x07, 0x11, +0x67, 0x12, 0x7B, 0xFD, 0x80, 0x05, 0x11, 0x67, 0x12, 0x7B, 0xBF, 0x51, 0xC3, 0x51, 0xCA, 0x12, +0x7A, 0xB9, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x22, 0x90, 0x92, +0x86, 0xE0, 0x90, 0x01, 0x3F, 0x22, 0x12, 0x9F, 0xF4, 0x64, 0x01, 0x60, 0x02, 0x21, 0x5F, 0x90, +0x85, 0xC5, 0xE0, 0x70, 0x02, 0x21, 0x5F, 0x90, 0x05, 0x63, 0xE0, 0x90, 0x92, 0x9B, 0xF0, 0x90, +0x05, 0x62, 0xE0, 0x90, 0x92, 0x9C, 0xF0, 0x90, 0x05, 0x61, 0xE0, 0x90, 0x92, 0x9D, 0xF0, 0x90, +0x05, 0x60, 0xE0, 0x90, 0x92, 0x9E, 0xF0, 0xF1, 0x65, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xEC, 0xF0, +0x31, 0x83, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x0E, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x05, 0x12, +0x9F, 0x78, 0x80, 0x02, 0x71, 0x5E, 0x31, 0x83, 0x64, 0x01, 0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, +0x90, 0x85, 0xCC, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, 0x85, 0xCB, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, +0x08, 0x90, 0x85, 0xCB, 0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x85, 0xCC, 0xEF, 0xF0, 0x12, 0xBD, +0x99, 0xE4, 0x90, 0x85, 0xCE, 0xF0, 0x12, 0xC5, 0x99, 0x31, 0x6B, 0x13, 0x54, 0x1F, 0x30, 0xE0, +0x5C, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, 0x22, 0x31, 0x7B, 0x6F, 0x70, 0x4E, 0x90, +0x85, 0xC2, 0xE0, 0x44, 0x40, 0xF0, 0xF1, 0xE5, 0x90, 0x01, 0x3F, 0x11, 0x67, 0x12, 0x7B, 0xFD, +0x51, 0xBC, 0x91, 0x23, 0x90, 0x85, 0xCC, 0xE0, 0x14, 0xF0, 0x80, 0x31, 0x90, 0x85, 0xC3, 0xE0, +0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x26, 0x31, 0x7B, 0xFE, 0x6F, 0x60, 0x20, 0x90, 0x05, 0x73, +0xE0, 0xFF, 0xEE, 0x6F, 0x60, 0x17, 0x31, 0x6B, 0x54, 0x3F, 0x30, 0xE0, 0x10, 0xEF, 0x54, 0xBF, +0xF0, 0x90, 0x01, 0x3F, 0x11, 0x67, 0x12, 0x7B, 0xBF, 0x51, 0xCA, 0x51, 0xC3, 0x31, 0x73, 0x90, +0x85, 0xBC, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x02, 0x31, 0x73, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0xFF, +0x13, 0x13, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x85, 0xCB, 0xE0, 0xFF, +0xA3, 0xE0, 0x22, 0x90, 0x85, 0xC3, 0xE0, 0xFF, 0xC4, 0x54, 0x0F, 0x22, 0x90, 0x85, 0xBC, 0xE0, +0x30, 0xE0, 0x06, 0x90, 0x85, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0x41, +0x44, 0x90, 0x85, 0xDC, 0xE0, 0x04, 0xF0, 0x90, 0x05, 0x61, 0x51, 0xAE, 0x78, 0x08, 0x12, 0x04, +0xD8, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x05, 0x60, 0x51, 0xAE, 0x12, 0x87, +0x4B, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05, 0x62, 0x51, 0xAE, 0x78, 0x10, +0x12, 0x04, 0xD8, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x87, 0x4B, 0xC0, 0x04, +0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0xA3, 0x51, 0xAE, 0x78, 0x18, 0x12, 0x04, 0xD8, 0xD0, 0x03, +0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x87, 0x4B, 0x90, 0x85, 0xFC, 0xEE, 0xF0, 0xA3, 0xEF, +0xF0, 0x90, 0x92, 0x96, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x12, 0xBD, +0x8C, 0xFB, 0x12, 0x51, 0x7D, 0x90, 0x92, 0x96, 0xE0, 0x54, 0xFD, 0xF0, 0x31, 0x6B, 0x13, 0x54, +0x1F, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x02, 0x51, 0xB5, 0x90, 0x93, 0x27, +0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, +0xE0, 0x44, 0x01, 0xF0, 0x12, 0x5D, 0x1F, 0x12, 0x6E, 0x1D, 0xE4, 0x90, 0x88, 0xE0, 0xF0, 0x7F, +0x01, 0x71, 0x4F, 0x71, 0x08, 0x12, 0xB7, 0xDB, 0x30, 0xE0, 0x52, 0x90, 0x88, 0x76, 0xE0, 0xFE, +0xA3, 0xE0, 0xFF, 0x7C, 0x00, 0x7D, 0x64, 0x12, 0x03, 0x82, 0x90, 0x88, 0xCA, 0xE0, 0x6E, 0x70, +0x03, 0xA3, 0xE0, 0x6F, 0x60, 0x0A, 0x90, 0x88, 0xCA, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x07, 0x0A, +0x90, 0x88, 0x7A, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x88, 0x88, 0xE0, 0xB5, 0x06, 0x14, 0xA3, +0xE0, 0xB5, 0x07, 0x0F, 0xEF, 0x4E, 0x60, 0x0B, 0x90, 0x01, 0xC7, 0x74, 0x31, 0xF0, 0x7F, 0x01, +0x02, 0x5F, 0xE9, 0x12, 0xC3, 0x08, 0xE4, 0x90, 0x88, 0xCA, 0xF0, 0xA3, 0xF0, 0x22, 0xE0, 0xFF, +0xE4, 0xFC, 0xFD, 0xFE, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x7C, 0x41, 0x7D, 0x01, 0x7F, 0x02, +0x02, 0x7C, 0x41, 0x7D, 0x02, 0x7F, 0x02, 0x02, 0x7C, 0xA9, 0x7D, 0x01, 0x7F, 0x02, 0x02, 0x7C, +0xA9, 0x12, 0x9E, 0x1B, 0x51, 0xC3, 0x7F, 0x01, 0x71, 0x19, 0x90, 0x92, 0x84, 0xE0, 0x30, 0xE0, +0x13, 0x51, 0xF5, 0x90, 0x92, 0x87, 0xE0, 0x60, 0x05, 0x14, 0xF0, 0x02, 0x7A, 0x8A, 0x51, 0xFE, +0xE4, 0xFF, 0x11, 0x26, 0x22, 0x90, 0x92, 0x86, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x90, 0x92, +0x85, 0xE0, 0x14, 0x90, 0x92, 0x87, 0xF0, 0x22, 0x90, 0x92, 0x84, 0xE0, 0x30, 0xE0, 0x09, 0x90, +0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x02, 0x51, 0xB5, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, +0x90, 0x92, 0x96, 0xE0, 0xFE, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x1E, 0x90, 0x92, 0x67, 0x74, +0x1E, 0xF0, 0x90, 0x92, 0x75, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x69, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, +0x92, 0x79, 0x67, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x71, 0x4F, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x8F, +0x0D, 0x7F, 0x02, 0x12, 0x86, 0x27, 0x90, 0x84, 0xC1, 0xE0, 0x45, 0x0D, 0xF0, 0x22, 0xE4, 0xF5, +0x77, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x77, 0x54, 0xC0, 0x70, 0x07, 0x71, 0xA4, 0x54, 0xFD, 0xF0, +0x80, 0x3A, 0xE5, 0x77, 0x30, 0xE6, 0x19, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x13, 0x12, +0x9F, 0x0C, 0x64, 0x02, 0x60, 0x05, 0x12, 0x77, 0x61, 0x80, 0x07, 0x12, 0x79, 0x41, 0x80, 0x02, +0x71, 0xA4, 0xE5, 0x77, 0x90, 0x85, 0xC9, 0x30, 0xE7, 0x05, 0x12, 0x9E, 0x00, 0xE1, 0xD5, 0xE0, +0x54, 0xFD, 0xF0, 0x22, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x85, 0xBC, 0xE0, +0x90, 0x85, 0xC7, 0x30, 0xE0, 0x05, 0xE0, 0xFF, 0x02, 0x9E, 0x76, 0xE0, 0xFF, 0x7D, 0x01, 0x02, +0x9A, 0x4C, 0x31, 0x6B, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, +0x30, 0xE0, 0x02, 0x91, 0x23, 0xF1, 0x71, 0x30, 0xE0, 0x08, 0xF1, 0x3B, 0x54, 0x07, 0x70, 0x3A, +0x80, 0x36, 0xF1, 0x87, 0x40, 0x32, 0x12, 0x9F, 0xF4, 0x64, 0x01, 0x70, 0x2D, 0x12, 0x9F, 0x13, +0x70, 0x05, 0x12, 0x70, 0xDB, 0x80, 0x24, 0x12, 0x70, 0xDB, 0x90, 0x85, 0xCF, 0xE0, 0x04, 0xF0, +0xE0, 0xD3, 0x94, 0x02, 0x40, 0x09, 0x91, 0x1B, 0xE4, 0x90, 0x85, 0xCF, 0xF0, 0x80, 0x03, 0x12, +0x79, 0x41, 0xE4, 0x90, 0x85, 0xCE, 0xF0, 0x22, 0x71, 0xAC, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0x54, +0xFB, 0xF0, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0x02, 0x7C, 0x41, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0E, +0x90, 0x06, 0x92, 0xE0, 0x30, 0xE1, 0x03, 0x02, 0x6B, 0x98, 0xF1, 0xDD, 0x71, 0xAC, 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, +0x3F, 0xF0, 0x74, 0xA4, 0xA3, 0xF0, 0x12, 0x75, 0x28, 0xE5, 0x56, 0x30, 0xE1, 0x02, 0xB1, 0x36, +0xE5, 0x56, 0x30, 0xE2, 0x02, 0x91, 0x2A, 0xE5, 0x57, 0x30, 0xE0, 0x03, 0x12, 0xBD, 0x59, 0xE5, +0x58, 0x30, 0xE1, 0x03, 0x12, 0xBF, 0xD1, 0xE5, 0x58, 0x30, 0xE0, 0x03, 0x12, 0x9F, 0x1A, 0xE5, +0x58, 0x30, 0xE4, 0x02, 0xF1, 0xBF, 0xE5, 0x59, 0x30, 0xE1, 0x04, 0x7F, 0x04, 0x71, 0x4F, 0xE5, +0x59, 0x30, 0xE4, 0x02, 0x51, 0xD1, 0xE5, 0x59, 0x30, 0xE5, 0x02, 0x91, 0xDA, 0xE5, 0x59, 0x30, +0xE6, 0x02, 0xB1, 0x00, 0x74, 0x3F, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xA4, 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, 0x85, 0xC1, 0x12, 0x9D, 0x1A, +0x30, 0xE0, 0x18, 0xEF, 0x54, 0xBF, 0xB1, 0x2D, 0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80, +0x08, 0xE0, 0x54, 0xFE, 0xB1, 0x3F, 0x74, 0x04, 0xF0, 0x71, 0xAC, 0xE4, 0xFF, 0x02, 0x68, 0x8F, +0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x12, 0x8D, 0x9B, 0x30, 0xE0, 0x1D, 0xEF, 0x54, 0x7F, 0xB1, 0x2D, +0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0xE0, 0x54, 0xFD, 0xB1, 0x3F, 0x04, 0xF0, +0x90, 0x85, 0xC5, 0xE0, 0x60, 0x02, 0x71, 0xAC, 0x7F, 0x01, 0x02, 0x68, 0x8F, 0xF0, 0x90, 0x04, +0xE0, 0xE0, 0x90, 0x85, 0xC2, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x02, 0x71, 0xC2, 0x22, 0xF0, +0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x22, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, +0x01, 0x0E, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x08, 0x71, 0xA4, 0x54, 0x07, 0x70, 0x02, 0x71, 0xAC, +0x22, 0x12, 0x9F, 0xF4, 0x64, 0x01, 0x70, 0x14, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0E, 0xF1, 0x65, +0x90, 0x85, 0xC1, 0xE0, 0xF1, 0x3C, 0x54, 0x07, 0x70, 0x02, 0x71, 0xAC, 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, 0x7D, 0xF0, +0x74, 0xA5, 0xA3, 0xF0, 0x12, 0x71, 0x90, 0xE5, 0x4C, 0x30, 0xE1, 0x02, 0xD1, 0xAF, 0xE5, 0x4C, +0x30, 0xE3, 0x02, 0xF1, 0x7B, 0xE5, 0x4C, 0x30, 0xE4, 0x02, 0xF1, 0x2C, 0xE5, 0x4C, 0x30, 0xE5, +0x03, 0x12, 0xC1, 0xC8, 0xE5, 0x4C, 0x30, 0xE6, 0x03, 0x12, 0xBC, 0xE6, 0xE5, 0x4E, 0x30, 0xE0, +0x02, 0xF1, 0xA0, 0xE5, 0x4E, 0x30, 0xE1, 0x02, 0x31, 0x8C, 0xE5, 0x4E, 0x30, 0xE2, 0x03, 0x12, +0xBC, 0xF3, 0xE5, 0x4E, 0x30, 0xE3, 0x03, 0x12, 0xBD, 0x22, 0xE5, 0x4E, 0x30, 0xE4, 0x02, 0xB1, +0x61, 0xE5, 0x4E, 0x30, 0xE5, 0x03, 0x12, 0xBD, 0x3D, 0xE5, 0x4E, 0x30, 0xE6, 0x02, 0xB1, 0x4A, +0xE5, 0x4F, 0x30, 0xE1, 0x03, 0x12, 0x9E, 0xCA, 0xE5, 0x4F, 0x30, 0xE4, 0x02, 0xF1, 0xC0, 0xE5, +0x4F, 0x30, 0xE5, 0x02, 0xD1, 0x3C, 0x74, 0x7D, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xA5, 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, 0x77, 0x90, +0x85, 0xBB, 0xE0, 0xFF, 0xE5, 0x77, 0xC3, 0x9F, 0x50, 0x64, 0xAF, 0x77, 0x12, 0x77, 0x39, 0xEF, +0x60, 0x58, 0xE5, 0x77, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE5, 0x77, 0x54, 0x07, 0xFE, 0x74, +0x75, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFD, 0xAF, 0x06, 0x12, 0xB1, 0x2A, +0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x60, 0x2B, 0xE5, +0x77, 0x12, 0xC8, 0xB4, 0x20, 0xE7, 0x02, 0x80, 0x13, 0xE5, 0x77, 0xC4, 0x54, 0xF0, 0x24, 0x02, +0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFF, 0x20, 0xE7, 0x09, 0x90, 0x01, 0xC1, 0xE0, +0x44, 0x20, 0xF0, 0x80, 0x05, 0xAD, 0x77, 0x12, 0x91, 0xE5, 0x05, 0x77, 0x80, 0x91, 0x22, 0xE4, +0xFF, 0x90, 0x92, 0x56, 0xEF, 0xF0, 0x90, 0x04, 0x7E, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, 0x66, +0xF0, 0xE0, 0xFE, 0x6F, 0x60, 0x65, 0x90, 0x92, 0x57, 0x74, 0x03, 0xF0, 0x90, 0x92, 0x65, 0x74, +0x08, 0xF0, 0xEE, 0x04, 0x54, 0x0F, 0xFF, 0xE4, 0xFE, 0xEF, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x00, +0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE5, 0x82, 0x2E, 0xF1, 0x33, 0xE0, 0xFD, 0x74, 0x59, +0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, 0x08, 0xDA, 0x7B, +0x01, 0x7A, 0x92, 0x79, 0x57, 0x12, 0x5E, 0x10, 0x90, 0x92, 0x66, 0xE0, 0x04, 0x54, 0x0F, 0xFF, +0xF0, 0xBF, 0x0F, 0x02, 0xE4, 0xF0, 0x90, 0x92, 0x66, 0xE0, 0x90, 0x04, 0x7F, 0xF0, 0x90, 0x92, +0x56, 0xE0, 0x7F, 0x04, 0x70, 0x02, 0x61, 0x4F, 0x12, 0x87, 0xBB, 0x22, 0x12, 0x40, 0xB9, 0x7F, +0x02, 0x61, 0x4F, 0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xEF, 0x54, 0xFB, 0xF0, 0x90, +0x85, 0xC9, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x01, 0x57, 0xE0, 0x60, 0x17, 0xF1, 0x68, 0xF1, +0x71, 0x30, 0xE0, 0x02, 0x80, 0xE5, 0xF1, 0x87, 0x40, 0x0A, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, +0x01, 0x02, 0x91, 0x1B, 0x22, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, +0x22, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x86, 0x72, 0xE0, 0x30, +0xE0, 0x04, 0x7F, 0x10, 0x71, 0x4F, 0x22, 0x90, 0x85, 0xCE, 0xE0, 0x04, 0xF0, 0x90, 0x85, 0xC9, +0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x86, 0x6D, 0xE0, 0xFF, 0x90, 0x85, 0xCE, 0xE0, 0xD3, 0x9F, 0x22, +0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x11, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x85, 0xBC, 0xE0, 0xFF, +0xC3, 0x13, 0x30, 0xE0, 0x03, 0x12, 0x9F, 0x5F, 0x12, 0x9D, 0x40, 0xE4, 0xFF, 0x61, 0x19, 0x22, +0xE4, 0xFF, 0x02, 0x2D, 0xBD, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x22, 0x12, 0x02, 0xF6, +0xFF, 0x54, 0x01, 0xFE, 0x22, 0x90, 0x85, 0xC1, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0x90, 0x85, 0xC1, +0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90, 0x85, 0xCB, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x12, 0x02, +0xF6, 0xFF, 0x90, 0x92, 0x89, 0xF0, 0xBF, 0x01, 0x08, 0x12, 0xA8, 0x02, 0xE4, 0x90, 0x92, 0x89, +0xF0, 0x22, 0x11, 0xE2, 0x7F, 0xF4, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x06, 0x90, 0x92, +0x16, 0xE0, 0xA3, 0xF0, 0x11, 0xE2, 0x7F, 0xF5, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, +0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x18, 0xF0, 0x11, 0xE2, 0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x64, +0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x19, 0xF0, 0x11, 0xE2, 0x7F, 0xF7, +0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1A, 0xF0, +0x11, 0xE2, 0x7F, 0xF8, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, +0x90, 0x92, 0x1B, 0xF0, 0x11, 0xE2, 0x31, 0x63, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, +0x92, 0x1C, 0xF0, 0x11, 0xE2, 0x31, 0x5C, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, +0x1D, 0xF0, 0x11, 0xE2, 0x11, 0xE9, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1E, +0xF0, 0x90, 0x92, 0x07, 0x74, 0x19, 0xF0, 0x90, 0x92, 0x15, 0x74, 0x08, 0xF0, 0x90, 0x92, 0x17, +0xE0, 0x90, 0x92, 0x09, 0xF0, 0x90, 0x92, 0x18, 0xE0, 0x90, 0x92, 0x0A, 0xF0, 0x90, 0x92, 0x19, +0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x90, 0x92, 0x1A, 0xE0, 0x90, 0x92, 0x0C, 0xF0, 0x90, 0x92, 0x1B, +0xE0, 0x90, 0x92, 0x0D, 0xF0, 0x90, 0x92, 0x1C, 0xE0, 0x90, 0x92, 0x0E, 0xF0, 0x90, 0x92, 0x1D, +0xE0, 0x90, 0x92, 0x0F, 0xF0, 0x90, 0x92, 0x1E, 0xE0, 0x90, 0x92, 0x10, 0x12, 0x87, 0xEB, 0x02, +0x87, 0xBB, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x16, 0x22, 0x7F, 0xFD, 0x7E, 0x00, 0x02, 0x64, 0x37, +0x7E, 0x00, 0x7F, 0x0B, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x8A, 0x12, 0x06, 0xDE, 0x31, +0x55, 0x31, 0x63, 0xBF, 0x01, 0x1C, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x01, 0x90, 0x92, 0x8A, +0xF0, 0xEE, 0x54, 0x04, 0x90, 0x92, 0x8C, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0x54, 0x08, 0x90, 0x92, +0x8B, 0xF0, 0x31, 0x55, 0x31, 0x5C, 0xBF, 0x01, 0x16, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x07, +0x90, 0x92, 0x8E, 0xF0, 0xEE, 0x54, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x90, 0x92, 0x8D, 0xF0, 0x31, +0x55, 0x11, 0xE9, 0xBF, 0x01, 0x0E, 0x90, 0x92, 0x29, 0xE0, 0x54, 0x0C, 0x13, 0x13, 0x54, 0x3F, +0x90, 0x92, 0x8F, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x29, 0x22, 0x7F, 0xFB, 0x7E, 0x00, +0x02, 0x64, 0x37, 0x7F, 0xF9, 0x7E, 0x00, 0x02, 0x64, 0x37, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, +0xFD, 0x7F, 0x80, 0x12, 0x7B, 0x3E, 0x12, 0xBB, 0xE9, 0x12, 0xC1, 0xBB, 0x12, 0x7B, 0x9C, 0x31, +0xEF, 0xF1, 0xCE, 0x7F, 0x01, 0x12, 0x85, 0x15, 0x90, 0x92, 0x88, 0x74, 0x02, 0xF0, 0xFF, 0x12, +0x85, 0x15, 0x90, 0x92, 0x88, 0xE0, 0x04, 0xF0, 0x71, 0x1A, 0x51, 0x0C, 0x90, 0x01, 0xCC, 0x74, +0x0F, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x7B, 0x3E, 0x75, 0x20, +0xFF, 0x12, 0x7C, 0xCD, 0x71, 0x80, 0x90, 0x00, 0x81, 0xE0, 0x44, 0x04, 0xFD, 0x7F, 0x81, 0x12, +0x7B, 0x3E, 0xF1, 0xC3, 0x11, 0xF0, 0x90, 0x00, 0x00, 0xE0, 0x54, 0xFB, 0xFD, 0xE4, 0xFF, 0xD1, +0x84, 0x44, 0x04, 0xFD, 0x7F, 0x01, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x98, 0x74, 0x80, 0xF0, 0xA3, +0x74, 0x88, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xE4, 0xFF, 0x02, 0x85, 0x9E, 0x90, +0x01, 0x01, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x71, 0xE7, 0x90, 0x01, +0x99, 0xE0, 0x44, 0xC0, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x80, 0xF0, 0x22, 0xF1, 0x8E, 0x12, 0x7B, +0xEF, 0x12, 0x3C, 0x03, 0x12, 0xC1, 0x39, 0x12, 0xC4, 0x63, 0xD1, 0xB1, 0x51, 0xF5, 0x51, 0x43, +0x12, 0x7B, 0x64, 0x12, 0x78, 0xB9, 0x90, 0x89, 0x16, 0xE0, 0x54, 0x7F, 0xF0, 0x54, 0xBF, 0xF0, +0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, 0x90, 0x89, 0x18, 0xF0, 0x90, 0x89, 0x16, 0xE0, 0x54, +0xEF, 0xF0, 0x22, 0x7E, 0x00, 0x7F, 0x24, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x86, 0x79, 0x72, 0x12, +0x06, 0xDE, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x20, 0xF0, 0xD1, 0x0F, 0x51, 0xFA, 0x90, 0x84, 0xC5, +0xE0, 0xFF, 0x64, 0x02, 0x70, 0x29, 0x51, 0xEE, 0x30, 0xE0, 0x02, 0x7E, 0x01, 0x90, 0x86, 0x90, +0x51, 0xEC, 0x30, 0xE1, 0x02, 0x7E, 0x01, 0x90, 0x86, 0x8E, 0x51, 0xEC, 0x30, 0xE2, 0x02, 0x7E, +0x01, 0x90, 0x86, 0x8F, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x90, 0x02, 0xFB, 0xF0, 0x22, 0xEF, +0x64, 0x01, 0x70, 0x1D, 0x51, 0xE5, 0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x90, 0x51, 0xE3, +0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x8E, 0x51, 0xE3, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x80, +0x23, 0x90, 0x84, 0xC5, 0xE0, 0x64, 0x03, 0x70, 0x20, 0x51, 0xDC, 0x30, 0xE0, 0x02, 0x7F, 0x01, +0x90, 0x86, 0x90, 0x51, 0xDA, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x8E, 0x51, 0xDA, 0x30, +0xE2, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x8F, 0xEF, 0xF0, 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, 0x71, 0x02, 0x06, 0xDE, 0xF1, 0x9C, 0xE4, 0x90, 0x88, 0xD8, +0x12, 0x96, 0xD2, 0x90, 0x88, 0x76, 0xF0, 0x12, 0x96, 0xCD, 0x12, 0x96, 0xD3, 0x90, 0x88, 0x88, +0xF0, 0xA3, 0xF0, 0x90, 0x88, 0xCA, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x7C, 0x4E, 0x90, 0x84, 0xC5, +0xEF, 0xF0, 0x71, 0x4E, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, 0x04, 0x23, 0xE0, 0x44, 0x80, +0xF0, 0x90, 0x00, 0x17, 0xE0, 0x54, 0xFC, 0x44, 0x04, 0xFD, 0x7F, 0x17, 0x12, 0x7B, 0x3E, 0x90, +0x00, 0x38, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x38, 0x12, 0x7B, 0x3E, 0x02, 0x68, 0xE2, 0x12, 0x75, +0xB6, 0x12, 0x75, 0x58, 0x12, 0xB9, 0x8F, 0x12, 0xB9, 0xB6, 0xE4, 0xF5, 0x40, 0xF5, 0x41, 0xF5, +0x42, 0x75, 0x43, 0x80, 0xAD, 0x40, 0x7F, 0x50, 0x12, 0x7B, 0x3E, 0xAD, 0x41, 0x7F, 0x51, 0x12, +0x7B, 0x3E, 0xAD, 0x42, 0x7F, 0x52, 0x12, 0x7B, 0x3E, 0xAD, 0x43, 0x7F, 0x53, 0x02, 0x7B, 0x3E, +0xE4, 0x90, 0x92, 0x29, 0xF0, 0xA3, 0xF0, 0x71, 0xCF, 0xEF, 0x64, 0x01, 0x60, 0x3A, 0xC3, 0x90, +0x92, 0x2A, 0xE0, 0x94, 0x88, 0x90, 0x92, 0x29, 0xE0, 0x94, 0x13, 0x40, 0x0F, 0x90, 0x01, 0xC1, +0xE0, 0x44, 0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, 0x80, 0x1C, 0x90, 0x92, 0x29, 0x12, +0xC8, 0x98, 0xD3, 0x90, 0x92, 0x2A, 0xE0, 0x94, 0x32, 0x90, 0x92, 0x29, 0xE0, 0x94, 0x00, 0x40, +0xC6, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xBF, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, 0x22, 0x90, +0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x44, 0x0B, 0x71, 0xE7, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xC0, 0x7F, +0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x7C, 0x9F, 0xEF, +0x60, 0x49, 0x90, 0x88, 0xCE, 0xE0, 0xFF, 0x60, 0x03, 0x12, 0x7B, 0x8A, 0x90, 0x01, 0xC7, 0xE4, +0xF0, 0x91, 0x63, 0xEC, 0x3E, 0x90, 0x85, 0xB7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x06, 0x09, 0xE0, +0x54, 0xFE, 0xF0, 0x7D, 0x35, 0x7F, 0xFF, 0x12, 0x90, 0xDB, 0x12, 0xC0, 0x1A, 0x90, 0x02, 0x86, +0xE0, 0x44, 0x04, 0xF0, 0x12, 0x72, 0x79, 0x91, 0x56, 0x12, 0x90, 0xD5, 0x12, 0x76, 0xE6, 0x90, +0x01, 0x34, 0x74, 0x08, 0xF0, 0xFD, 0xE4, 0xFF, 0x02, 0x7C, 0xA9, 0x7D, 0x08, 0xE4, 0xFF, 0x12, +0x7C, 0x41, 0x90, 0x06, 0x90, 0xE0, 0x54, 0xF0, 0xF0, 0x90, 0x02, 0x86, 0xE0, 0x54, 0xFB, 0xF0, +0xB1, 0xE9, 0x91, 0x57, 0x41, 0x43, 0x22, 0x90, 0x86, 0x72, 0x12, 0x9D, 0x1A, 0x30, 0xE0, 0x02, +0x51, 0xFA, 0x22, 0x90, 0x01, 0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, 0x00, +0xFF, 0x22, 0x90, 0x88, 0xD9, 0xB1, 0x10, 0x12, 0xC3, 0xB1, 0xFD, 0x90, 0x92, 0x07, 0xE0, 0x24, +0x2C, 0x12, 0xC3, 0xCA, 0x90, 0x92, 0x07, 0xE0, 0x2F, 0x24, 0x30, 0xA3, 0xF0, 0xE0, 0xFD, 0x24, +0x04, 0xD1, 0x4A, 0xE0, 0xFE, 0x74, 0x05, 0x2D, 0xB1, 0xCD, 0x91, 0x6B, 0xEC, 0x3E, 0x90, 0x88, +0x80, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x08, 0xE0, 0x24, 0x0C, 0xF9, 0xE4, 0x34, 0xFC, 0xB1, +0x21, 0x75, 0x1E, 0x04, 0x7B, 0x01, 0x7A, 0x88, 0x79, 0x82, 0x12, 0x6A, 0x21, 0x90, 0x92, 0x08, +0xE0, 0x24, 0x14, 0xF0, 0xE0, 0xFD, 0x24, 0x01, 0xB1, 0xDD, 0x2D, 0xB1, 0xD5, 0x91, 0x6B, 0xEC, +0x3E, 0x90, 0x88, 0x86, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x88, 0xDA, 0xB1, 0x10, 0x90, 0x88, 0x7C, +0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x4E, 0x60, 0x11, 0x90, 0x92, 0x07, 0xE0, 0xB1, 0x1B, 0x8F, 0x1E, +0x7B, 0x01, 0x7A, 0x88, 0x79, 0x8A, 0x12, 0x6A, 0x21, 0x90, 0x88, 0xDB, 0xB1, 0x10, 0xB1, 0x1B, +0x90, 0x88, 0x7E, 0xA3, 0xE0, 0xF5, 0x1E, 0x7B, 0x01, 0x7A, 0x88, 0x79, 0xAA, 0x02, 0x6A, 0x21, +0xE0, 0xFF, 0x12, 0x7B, 0x2A, 0x90, 0x92, 0x07, 0xEF, 0xF0, 0x22, 0x24, 0x00, 0xF9, 0xE4, 0x34, +0xFC, 0x75, 0x1B, 0x01, 0xF5, 0x1C, 0x89, 0x1D, 0x22, 0xEF, 0x60, 0x04, 0xB1, 0x31, 0x91, 0x72, +0x22, 0xE4, 0xFD, 0xFC, 0x90, 0x88, 0xD8, 0xE0, 0xFF, 0xF1, 0x94, 0xAB, 0x05, 0x74, 0x01, 0x2B, +0xB1, 0xDD, 0x2B, 0xB1, 0xD5, 0xF1, 0xAC, 0x90, 0x88, 0x76, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x03, +0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x02, 0x2B, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0xB1, 0xC4, 0x90, 0x88, 0x78, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x05, 0x2B, 0xB1, 0xCD, +0xE0, 0xFE, 0x74, 0x04, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xB1, 0xC4, 0x90, 0x88, 0x7A, 0xF0, +0xA3, 0xEF, 0xF0, 0x74, 0x07, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, +0x06, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xB1, 0xC4, 0x90, 0x88, 0x7C, 0xF0, 0xA3, 0xEF, 0xF0, +0x74, 0x09, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x08, 0x2B, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x90, 0x88, 0x7E, 0xF0, +0xA3, 0xEF, 0xF0, 0x22, 0xF5, 0x83, 0xE0, 0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x22, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x00, 0x22, 0xD1, 0x0F, 0x12, 0x77, 0x89, 0x90, 0x01, +0x3F, 0x74, 0x04, 0xF0, 0x90, 0x84, 0xC5, 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, 0x7B, 0x3E, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0xAD, 0x07, 0x90, 0x88, 0x80, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x90, 0x88, +0x80, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x04, 0x2E, 0xD1, 0x4A, 0xEF, 0xF0, 0x90, 0x88, 0x80, 0xA3, +0xE0, 0xFF, 0x74, 0x05, 0x2E, 0xB1, 0xCD, 0xEF, 0xF0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x02, 0xF1, 0xA4, 0x7F, 0x02, 0xD1, +0x84, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, +0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD1, 0x52, 0x90, 0x85, 0xBF, +0x74, 0x03, 0xF0, 0x22, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x01, 0xE0, 0x22, 0x7D, 0x22, 0x7F, 0xFF, +0xD1, 0xA9, 0x44, 0x40, 0xF0, 0x80, 0xE6, 0xD1, 0x52, 0x7D, 0x24, 0xD1, 0xA7, 0x54, 0xBF, 0xF0, +0x90, 0x85, 0xBF, 0x74, 0x04, 0xF0, 0x22, 0x7F, 0x6F, 0x12, 0x90, 0xDB, 0x90, 0x05, 0x27, 0xE0, +0x22, 0x7E, 0x00, 0x7F, 0xAC, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x85, 0x79, 0xC1, 0x12, 0x06, 0xDE, +0xF1, 0x71, 0x12, 0x06, 0xDE, 0x90, 0x85, 0xC4, 0x74, 0x02, 0xF0, 0x90, 0x85, 0xCB, 0x14, 0xF0, +0xA3, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x90, 0x85, 0xD1, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xF1, 0x7E, +0x12, 0xC5, 0xA3, 0xE4, 0xFD, 0xFF, 0x12, 0x57, 0x82, 0x7D, 0x0C, 0x7F, 0x02, 0x12, 0x57, 0x82, +0x7D, 0x0C, 0x7F, 0x01, 0x12, 0x57, 0x82, 0x90, 0x84, 0xC5, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90, +0x85, 0xD0, 0x74, 0xDD, 0xF0, 0x80, 0x0F, 0xEF, 0x90, 0x85, 0xD0, 0xB4, 0x03, 0x05, 0x74, 0xD4, +0xF0, 0x80, 0x03, 0x74, 0x40, 0xF0, 0x7F, 0x2C, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0x0F, 0xFF, 0xBF, +0x05, 0x08, 0x90, 0x85, 0xFB, 0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x85, 0xFB, 0xF0, 0x90, +0x86, 0x6D, 0x74, 0x03, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28, 0xF0, +0xA3, 0x74, 0x07, 0xF1, 0x7E, 0xE4, 0x90, 0x85, 0xD7, 0xF0, 0xA3, 0xF0, 0x7F, 0x01, 0x12, 0x69, +0x33, 0x90, 0x05, 0x58, 0x74, 0x02, 0xF0, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, +0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xDB, 0xE4, 0x90, 0x86, 0x71, 0xF0, +0x22, 0x7E, 0x00, 0x7F, 0x04, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x84, 0x22, 0xF0, 0x90, +0x85, 0xFB, 0xE0, 0x24, 0x04, 0x90, 0x85, 0xDD, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x22, 0xE4, 0xFD, +0xFF, 0x02, 0x6E, 0x5F, 0x12, 0x7B, 0x2A, 0x7C, 0x00, 0xAD, 0x07, 0x22, 0x90, 0x86, 0x72, 0xE0, +0x54, 0xBF, 0xF0, 0x22, 0x12, 0x7B, 0x51, 0xEF, 0x44, 0x01, 0xFD, 0x22, 0xE0, 0x7A, 0x00, 0x24, +0x00, 0xFF, 0xEA, 0x3E, 0x22, 0x7D, 0x21, 0x7F, 0xFF, 0x12, 0x90, 0xDB, 0xC1, 0x7D, 0x12, 0x9F, +0xE5, 0x80, 0xF2, 0x90, 0x01, 0xE4, 0x74, 0x01, 0xF0, 0xA3, 0x74, 0x07, 0xF0, 0x22, 0xE4, 0x90, +0x84, 0xC1, 0x12, 0x96, 0xD2, 0x90, 0x92, 0x81, 0xF0, 0x22, 0xE4, 0xFD, 0xFF, 0xD1, 0xA9, 0x44, +0x40, 0xF0, 0x02, 0x9F, 0xE5, 0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x92, 0x01, 0xF0, 0x90, +0x92, 0x01, 0xE0, 0xFD, 0x70, 0x03, 0x02, 0xB0, 0xF7, 0x90, 0x85, 0x1D, 0xE0, 0xFF, 0x70, 0x06, +0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0xB5, 0x07, 0x04, +0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, 0x01, 0xF0, +0x22, 0x90, 0x93, 0x22, 0xE0, 0x31, 0x29, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, +0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0x01, 0xDA, 0xE4, 0x90, 0x92, 0x02, 0xF0, 0x90, 0x92, 0x02, +0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x42, 0x11, 0xF9, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, 0x00, 0x2F, +0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0x31, 0x01, 0x90, 0x84, 0xCD, 0x12, 0x05, 0x28, 0xE5, +0x82, 0x29, 0x12, 0xA7, 0x33, 0xEF, 0x11, 0xF8, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, +0xF0, 0x31, 0x01, 0x90, 0x84, 0xD1, 0x12, 0x05, 0x28, 0xE5, 0x82, 0x29, 0x12, 0xA7, 0x33, 0xEF, +0xF0, 0x90, 0x92, 0x02, 0xE0, 0x04, 0xF0, 0x80, 0xB4, 0x90, 0x92, 0x01, 0xE0, 0xFF, 0x90, 0x93, +0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, +0x90, 0x92, 0x01, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, +0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x54, +0x03, 0xF0, 0x90, 0x85, 0x1E, 0xF1, 0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, 0x03, 0x02, +0xAF, 0xEF, 0xE4, 0x90, 0x85, 0x1E, 0xF0, 0x02, 0xAF, 0xEF, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, +0xF0, 0x90, 0x93, 0x22, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0x11, 0xF8, 0x90, 0x01, 0xD0, 0x12, +0x05, 0x28, 0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0x75, 0xF0, 0x04, +0x22, 0x2F, 0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0x75, +0xF0, 0x08, 0x22, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x24, 0x75, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, +0x83, 0xE0, 0xFD, 0x7C, 0x00, 0xE5, 0x62, 0x54, 0x07, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, +0x22, 0xE4, 0xF5, 0x73, 0xEF, 0x14, 0xF5, 0x72, 0xED, 0xFF, 0xE5, 0x72, 0xF5, 0x82, 0x33, 0x95, +0xE0, 0xF5, 0x83, 0xC3, 0xE5, 0x82, 0x9F, 0x74, 0x80, 0xF8, 0x65, 0x83, 0x98, 0x40, 0x52, 0xE5, +0x72, 0x78, 0x03, 0xA2, 0xE7, 0x13, 0xD8, 0xFB, 0xFF, 0x33, 0x95, 0xE0, 0xFE, 0xEB, 0x12, 0xC8, +0x73, 0xE5, 0x82, 0x2F, 0xF5, 0x82, 0xE5, 0x83, 0x3E, 0xF5, 0x83, 0xE0, 0xF5, 0x82, 0x75, 0x83, +0x00, 0xE5, 0x72, 0x31, 0x27, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, +0xEE, 0x55, 0x83, 0xFE, 0xEF, 0x55, 0x82, 0x4E, 0x60, 0x13, 0x85, 0x72, 0x74, 0x05, 0x73, 0x90, +0x92, 0x3E, 0xE0, 0x65, 0x73, 0x60, 0x0A, 0xE5, 0x74, 0xD3, 0x9D, 0x40, 0x04, 0x15, 0x72, 0x80, +0x97, 0xAF, 0x74, 0x22, 0x7D, 0x01, 0xAF, 0x62, 0xAC, 0x05, 0x90, 0x92, 0x39, 0xEF, 0xF0, 0xFD, +0xE0, 0xFF, 0x12, 0x92, 0x71, 0xE0, 0xF5, 0x6E, 0x54, 0x7F, 0xF5, 0x70, 0x75, 0xF0, 0x12, 0xEF, +0x90, 0x89, 0x3D, 0x12, 0x05, 0x28, 0xE0, 0xF9, 0x90, 0x92, 0x39, 0xE0, 0x12, 0xC8, 0x8D, 0xFE, +0xEF, 0x12, 0x91, 0xD8, 0xE0, 0x54, 0x03, 0xF5, 0x6F, 0xE5, 0x70, 0x90, 0x83, 0x1D, 0x93, 0xFB, +0xED, 0x51, 0xA4, 0xE4, 0xF0, 0xA3, 0xEB, 0xF0, 0x12, 0x8B, 0x40, 0xC4, 0x54, 0x03, 0x90, 0x92, +0x3A, 0xF0, 0x74, 0xCC, 0x2D, 0x51, 0x86, 0xE5, 0x70, 0xF0, 0x74, 0x4C, 0x2D, 0xF1, 0xD3, 0xE5, +0x6F, 0xF0, 0xE5, 0x70, 0xD3, 0x9E, 0x40, 0x06, 0x8E, 0x70, 0xAF, 0x06, 0x8F, 0x6E, 0x8C, 0x71, +0xE4, 0xFF, 0xEF, 0xC3, 0x95, 0x71, 0x50, 0x2F, 0xE5, 0x6E, 0x30, 0xE7, 0x09, 0x85, 0x70, 0x6E, +0x1C, 0xEC, 0x70, 0x20, 0x80, 0x21, 0xE5, 0x70, 0xD3, 0x99, 0x40, 0x14, 0xAD, 0x01, 0x90, 0x92, +0x39, 0xE0, 0xFB, 0x90, 0x92, 0x3E, 0xEC, 0xF0, 0xAF, 0x70, 0x31, 0x31, 0x8F, 0x6E, 0x80, 0x07, +0x89, 0x6E, 0x80, 0x03, 0x0F, 0x80, 0xCB, 0x90, 0x92, 0x39, 0xE0, 0xFF, 0x51, 0x7B, 0xEF, 0xF0, +0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x6E, 0xF1, 0xCB, 0x71, 0xAB, 0x7B, 0x01, 0xFA, 0x7D, 0x05, 0x7F, +0x08, 0x12, 0x97, 0x1A, 0x90, 0x92, 0x39, 0xE0, 0xFF, 0x90, 0x91, 0x0B, 0xE5, 0x6F, 0xF0, 0xE4, +0xFB, 0xAD, 0x6E, 0x02, 0x27, 0x3D, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x3F, 0xE4, 0xF0, +0xA3, 0x22, 0x74, 0xCC, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0x22, 0xE5, 0x71, +0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4, 0x93, 0xFE, 0x74, 0x01, +0x93, 0xFF, 0xE5, 0x6E, 0x25, 0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, +0x90, 0x92, 0x39, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xEB, 0x75, 0xF0, 0x06, 0xA4, +0xFF, 0x90, 0x89, 0x21, 0x12, 0x87, 0x70, 0xE9, 0x2F, 0xF9, 0xEA, 0x35, 0xF0, 0xFA, 0x90, 0x92, +0x41, 0x12, 0x87, 0x79, 0x90, 0x92, 0x3B, 0xE0, 0x51, 0xA4, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, +0x3E, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x92, 0x41, 0x12, 0x87, 0x70, 0x90, +0x92, 0x40, 0xE0, 0xFF, 0xF5, 0x82, 0x75, 0x83, 0x00, 0x12, 0x03, 0x0F, 0xFD, 0x7C, 0x00, 0x90, +0x92, 0x3B, 0xE0, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x44, 0x12, 0x05, 0x28, 0x75, 0xF0, 0x02, 0xEF, +0x71, 0xA3, 0xFF, 0x90, 0x92, 0x3D, 0xE0, 0xFB, 0xEF, 0xA8, 0x03, 0x08, 0x80, 0x05, 0xCE, 0xC3, +0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x71, 0x93, 0xEE, 0x8F, 0xF0, 0x12, 0x07, 0x0A, 0x90, 0x92, 0x40, +0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x05, 0xB2, 0x90, 0x92, 0x41, 0x12, 0x87, 0x70, 0x90, 0x00, 0x05, +0x12, 0x03, 0x0F, 0xFD, 0x7C, 0x00, 0x90, 0x92, 0x3D, 0xE0, 0xFF, 0x90, 0x92, 0x39, 0xE0, 0xFE, +0xA3, 0xE0, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x71, 0x93, +0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x9F, 0xEC, 0x9E, 0x40, 0x08, 0xED, 0x9F, 0xFF, 0xEC, 0x9E, +0xFE, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x00, 0x90, 0x92, 0x3E, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x92, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x3B, 0xE0, 0x51, 0xA4, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0x22, 0xFF, 0x12, 0x03, 0x70, 0x90, 0x92, 0x3E, 0x22, 0x75, 0xF0, 0x12, 0xE5, 0x62, +0x90, 0x89, 0x40, 0x12, 0x05, 0x28, 0xE0, 0xFE, 0xA3, 0xE0, 0x22, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, +0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x92, 0xF5, 0xF0, 0xA3, 0xF0, +0xA3, 0x74, 0x08, 0xF0, 0xA3, 0x71, 0xAB, 0x90, 0x92, 0xFD, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, +0x01, 0xC4, 0x74, 0xB2, 0xF0, 0x74, 0xB3, 0xA3, 0xF0, 0x90, 0x01, 0x1F, 0xE0, 0xFE, 0x90, 0x01, +0x1E, 0x12, 0xAC, 0x6B, 0xEC, 0x3E, 0x90, 0x92, 0xEC, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x02, 0x87, +0xE0, 0x90, 0x92, 0xF4, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0x20, 0xE0, 0x02, 0xC1, 0x9A, 0xE4, 0x90, +0x92, 0xF3, 0xF0, 0x90, 0x92, 0xF4, 0xE0, 0xFF, 0x90, 0x92, 0xF3, 0xE0, 0xC3, 0x9F, 0x40, 0x02, +0xC1, 0x9A, 0x90, 0x92, 0xEC, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFF, 0x90, 0xFD, 0x11, 0xF0, +0x90, 0x92, 0xFD, 0xEF, 0xF0, 0xF1, 0x20, 0xF5, 0x83, 0xE0, 0xFE, 0xD1, 0xE1, 0x12, 0xAF, 0xAC, +0x54, 0x3F, 0xFE, 0x90, 0x92, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0xF9, 0xEE, 0xF0, 0xA3, +0xF1, 0x35, 0x54, 0x0F, 0x33, 0x33, 0x33, 0x54, 0xF8, 0xFF, 0xF1, 0x29, 0x54, 0x03, 0xFE, 0xEF, +0x24, 0x18, 0x2E, 0xFF, 0x90, 0x92, 0xFE, 0xF0, 0x90, 0x92, 0xED, 0xE0, 0x2F, 0xFF, 0x90, 0x92, +0xEC, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x92, 0xF0, 0xD1, 0xC6, 0xC0, 0x07, 0xD1, 0xAB, 0x7D, 0x01, +0x12, 0x55, 0x36, 0xC0, 0x07, 0xD1, 0xAB, 0x7D, 0x04, 0x12, 0x55, 0x36, 0xAB, 0x07, 0xD0, 0x05, +0xD0, 0x07, 0x12, 0x5D, 0x98, 0x90, 0x92, 0xF5, 0xEF, 0xD1, 0xAA, 0xE4, 0xFD, 0x12, 0x55, 0x36, +0xEF, 0x54, 0xFC, 0x90, 0x92, 0xF2, 0xF0, 0x90, 0x92, 0xFE, 0xE0, 0xFF, 0x90, 0x92, 0xEE, 0xE4, +0x8F, 0xF0, 0x12, 0x07, 0x0A, 0x90, 0x92, 0xEE, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x7A, 0xD0, +0x90, 0x92, 0xEE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xD1, 0xD8, 0x7D, 0x0F, 0x12, 0x55, 0x36, 0x90, +0x92, 0xEE, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x90, 0x92, 0xEC, 0xEC, 0x8D, 0xF0, 0x12, 0x07, 0x0A, +0x90, 0x85, 0xB7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x90, 0x92, 0xED, 0xE0, 0x9D, 0x90, 0x92, +0xEC, 0xE0, 0x9C, 0x40, 0x1B, 0x90, 0x85, 0xB8, 0xE0, 0x24, 0x01, 0xFD, 0x90, 0x85, 0xB7, 0xE0, +0x34, 0x00, 0xFC, 0xC3, 0x90, 0x92, 0xED, 0xE0, 0x9D, 0xF0, 0x90, 0x92, 0xEC, 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, 0x92, +0xF2, 0xE0, 0x24, 0x40, 0x60, 0x04, 0x24, 0x20, 0x70, 0x2C, 0x90, 0x86, 0x75, 0xE0, 0xFF, 0x12, +0x8D, 0x9B, 0x20, 0xE0, 0x02, 0xC1, 0x1E, 0x90, 0x86, 0x87, 0xE0, 0x04, 0xD1, 0xAA, 0x12, 0x59, +0x20, 0xEF, 0x70, 0x02, 0xC1, 0x1E, 0x90, 0x92, 0xF2, 0xE0, 0xFF, 0x12, 0x7B, 0x77, 0x90, 0x86, +0x88, 0xE0, 0x04, 0xF0, 0xC1, 0x1E, 0xF1, 0xDB, 0x30, 0xE0, 0x5A, 0x90, 0x92, 0xF5, 0xE0, 0xFF, +0x90, 0x92, 0xF1, 0xE0, 0x2F, 0xFF, 0x90, 0x92, 0xF0, 0xE0, 0x34, 0x00, 0xCF, 0x24, 0x08, 0xCF, +0x34, 0x00, 0xFE, 0x90, 0x92, 0xFB, 0xD1, 0xC6, 0xEF, 0x64, 0x45, 0x70, 0x38, 0xD1, 0xB5, 0x12, +0xC7, 0xCF, 0xEF, 0x64, 0x01, 0x70, 0x2E, 0xD1, 0xB5, 0x12, 0xC7, 0x92, 0xEF, 0x64, 0x01, 0x70, +0x24, 0x90, 0x92, 0xFF, 0x04, 0xD1, 0xB4, 0xA3, 0xE0, 0xFD, 0x12, 0xC6, 0xEB, 0xEF, 0x70, 0x0D, +0x90, 0x92, 0xFD, 0xE0, 0xFD, 0x90, 0xFD, 0x11, 0xD1, 0xB4, 0x12, 0xC7, 0x43, 0x90, 0x92, 0xFD, +0xE0, 0x90, 0xFD, 0x11, 0xF0, 0xD1, 0xAB, 0x12, 0x59, 0x20, 0xEF, 0x60, 0x18, 0xD1, 0xAB, 0x90, +0x92, 0xF5, 0xE0, 0xFD, 0x90, 0x92, 0xF8, 0xE0, 0xFB, 0x12, 0x54, 0x02, 0xEF, 0x60, 0x06, 0x90, +0x92, 0xFF, 0x74, 0x01, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x13, 0xD1, 0xAB, +0x90, 0x92, 0xF5, 0xE0, 0xFD, 0x12, 0x38, 0x10, 0xEF, 0x60, 0x06, 0x90, 0x92, 0xFF, 0x74, 0x01, +0xF0, 0x12, 0x8F, 0xF0, 0x54, 0x3F, 0x30, 0xE0, 0x0A, 0xD1, 0xAB, 0x90, 0x92, 0xF5, 0xE0, 0xFD, +0x12, 0x21, 0xB6, 0x90, 0x86, 0x72, 0xE0, 0xFF, 0x12, 0x8D, 0x9B, 0x30, 0xE0, 0x10, 0x90, 0x92, +0xFF, 0xE0, 0x70, 0x0A, 0xD1, 0xAB, 0x90, 0x92, 0xF5, 0xE0, 0xFD, 0x12, 0x4A, 0x3F, 0x12, 0x79, +0x00, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x10, 0xD1, 0xCF, 0x30, +0xE0, 0x06, 0x90, 0x01, 0x3F, 0x74, 0x04, 0xF0, 0x7F, 0x01, 0x12, 0x5F, 0xE9, 0x90, 0x01, 0x3F, +0xE0, 0x30, 0xE2, 0x02, 0xD1, 0xBE, 0x12, 0x7A, 0xE7, 0xEF, 0x64, 0x01, 0x70, 0x36, 0x90, 0x86, +0x89, 0xE0, 0x04, 0xF0, 0x12, 0x6F, 0xE5, 0xAD, 0x07, 0xEF, 0x64, 0x01, 0x60, 0x1F, 0xD1, 0xBE, +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, 0x5F, 0xE9, 0x80, 0x1D, 0xD1, 0xD8, 0x12, +0x7C, 0x0B, 0x80, 0x0E, 0xD1, 0xCF, 0x20, 0xE0, 0x11, 0x90, 0x86, 0x72, 0xE0, 0x54, 0xFE, 0xF0, +0x80, 0x08, 0x90, 0x92, 0xF3, 0xE0, 0x04, 0xF0, 0x81, 0x03, 0x74, 0xB2, 0x04, 0x90, 0x01, 0xC4, +0xF0, 0x74, 0xB3, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x92, 0xF0, 0xE0, 0xFE, +0xA3, 0xE0, 0xFF, 0x22, 0xF0, 0x90, 0x92, 0xFB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x86, +0x7A, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xFD, 0x02, 0x55, 0x36, 0x90, +0x86, 0x74, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x90, 0x92, 0xEC, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x22, 0x74, 0x00, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0xE4, 0xFC, 0xED, 0x2C, +0x24, 0x00, 0xD1, 0xE4, 0xE4, 0xF0, 0x0C, 0xEC, 0xB4, 0x18, 0xF3, 0xD1, 0xE1, 0xEF, 0xF0, 0xEE, +0x54, 0x3F, 0xFF, 0xF1, 0x20, 0xF5, 0x83, 0xF1, 0x35, 0x54, 0xF0, 0xF0, 0xF1, 0x29, 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, 0x22, 0x74, 0x03, 0x2D, 0xF5, 0x82, 0xE4, 0x34, +0xFB, 0xF5, 0x83, 0xE0, 0x22, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, +0x83, 0xE0, 0x22, 0x90, 0x93, 0x1C, 0xEF, 0x71, 0xAB, 0x90, 0x01, 0x09, 0xE0, 0x7F, 0x00, 0x30, +0xE7, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x1C, 0xE0, 0x6F, 0x60, 0x33, 0xC3, 0x90, 0x93, 0x1E, 0xE0, +0x94, 0x88, 0x90, 0x93, 0x1D, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10, +0xF0, 0x22, 0x90, 0x93, 0x1D, 0x12, 0xC8, 0x98, 0xD3, 0x90, 0x93, 0x1E, 0xE0, 0x94, 0x32, 0x90, +0x93, 0x1D, 0xE0, 0x94, 0x00, 0x40, 0xC2, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xBB, 0x22, 0x12, +0xC4, 0x44, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x7B, 0x3E, +0xE4, 0xFF, 0xF1, 0x43, 0x7D, 0x35, 0x7F, 0x27, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xC2, 0xE0, 0x54, +0xEF, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xC0, 0x71, 0xF1, 0x8F, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, +0xE5, 0x6F, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0x22, 0x90, 0x86, 0x72, 0xE0, 0xC4, +0x13, 0x13, 0x54, 0x03, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x85, 0x1E, 0xE0, +0xFF, 0x90, 0x85, 0x1D, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, +0x48, 0x90, 0x85, 0x1D, 0xE0, 0xFE, 0x75, 0xF0, 0x08, 0x90, 0x84, 0xCD, 0x12, 0x05, 0x28, 0xE0, +0xFD, 0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0xCE, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0xFA, 0x7B, 0x01, +0xAF, 0x05, 0x12, 0x89, 0x07, 0x90, 0x85, 0x1D, 0x12, 0xB7, 0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, +0xEF, 0x60, 0x05, 0xE4, 0x90, 0x85, 0x1D, 0xF0, 0x7D, 0x68, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x12, +0x40, 0xB9, 0x90, 0x84, 0xC1, 0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x85, +0xB5, 0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x85, +0xB6, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, +0xC1, 0xE0, 0x44, 0x02, 0xF0, 0x22, 0xC0, 0x01, 0x90, 0x85, 0xB6, 0xE0, 0x75, 0xF0, 0x0F, 0xA4, +0x24, 0x1F, 0xF9, 0x74, 0x85, 0x35, 0xF0, 0xA8, 0x01, 0xFC, 0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, +0x7F, 0x0F, 0x12, 0x02, 0xD0, 0x7D, 0xCC, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xB6, 0x12, +0xB7, 0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x85, 0xB6, 0xF0, 0x22, +0x90, 0x92, 0x21, 0xEF, 0xF0, 0xA3, 0x12, 0x87, 0x79, 0x90, 0x93, 0x23, 0xE0, 0xFE, 0x04, 0xF0, +0x90, 0x00, 0x01, 0xEE, 0x12, 0x03, 0x4E, 0x74, 0x00, 0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, +0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x92, 0x22, 0x12, 0x87, 0x70, 0x8B, 0x1B, 0x8A, +0x1C, 0x89, 0x1D, 0x75, 0x1E, 0x02, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x6A, 0x21, 0x90, +0x92, 0x21, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, +0xC0, 0x01, 0xA3, 0x12, 0x87, 0x70, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, 0x1B, 0xF5, 0x1C, +0x89, 0x1D, 0x90, 0x92, 0x22, 0x31, 0x22, 0xF5, 0x1E, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x02, +0x6A, 0x21, 0x12, 0x87, 0x70, 0x90, 0x00, 0x0E, 0x02, 0x03, 0x0F, 0xD3, 0x10, 0xAF, 0x01, 0xC3, +0xC0, 0xD0, 0x90, 0x92, 0x25, 0x12, 0x87, 0x79, 0x7F, 0x96, 0x7E, 0x02, 0x12, 0x66, 0x80, 0xEF, +0x60, 0x48, 0x12, 0xAC, 0x63, 0xEC, 0x3E, 0xFE, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, +0x92, 0x28, 0xEF, 0xF0, 0xEE, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x92, 0x28, 0xE0, 0xFD, 0x90, +0x02, 0x94, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x25, 0x31, 0x22, 0x24, 0x02, 0xFF, 0xE4, 0x33, +0xFE, 0x12, 0x5A, 0xA5, 0x90, 0x92, 0x28, 0xE0, 0x24, 0x18, 0xFF, 0x90, 0x92, 0x25, 0x12, 0x87, +0x70, 0x12, 0x56, 0xF4, 0x90, 0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x75, +0x48, 0x12, 0xE4, 0xF5, 0x49, 0x75, 0x4A, 0x07, 0x75, 0x4B, 0x32, 0xF5, 0x50, 0x90, 0x01, 0x30, +0xE5, 0x48, 0xF0, 0xA3, 0xE5, 0x49, 0xF0, 0xA3, 0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0x90, +0x01, 0x20, 0xE5, 0x50, 0xF0, 0x22, 0x75, 0x52, 0x06, 0x75, 0x53, 0x01, 0x75, 0x54, 0x03, 0x75, +0x55, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x52, 0xF0, 0xA3, 0xE5, 0x53, 0xF0, 0xA3, 0xE5, 0x54, 0xF0, +0xA3, 0xE5, 0x55, 0xF0, 0x22, 0x7D, 0x02, 0x90, 0x01, 0xC4, 0x74, 0xD5, 0xF0, 0x74, 0xB9, 0xA3, +0xF0, 0x90, 0x92, 0x88, 0xE0, 0xFF, 0xED, 0xC3, 0x9F, 0x50, 0x18, 0xED, 0x25, 0xE0, 0x24, 0x81, +0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22, +0x0D, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0xE4, 0x90, 0x92, 0x2B, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, +0x92, 0x2B, 0xE0, 0x64, 0x01, 0xF0, 0x24, 0x06, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xBA, 0xA3, 0xF0, +0x12, 0x7C, 0x66, 0xBF, 0x01, 0x03, 0x12, 0x5B, 0x25, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0F, 0x90, +0x85, 0xC8, 0xE0, 0xFF, 0x90, 0x85, 0xC7, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0xA3, 0xAC, 0xC2, 0xAF, +0x31, 0xD5, 0xBF, 0x01, 0x02, 0x51, 0x70, 0xD2, 0xAF, 0x51, 0xF8, 0x90, 0x92, 0x2C, 0xE4, 0x75, +0xF0, 0x01, 0x12, 0x07, 0x0A, 0x54, 0x7F, 0x45, 0xF0, 0x70, 0x0D, 0x7F, 0xFF, 0x12, 0x7B, 0x51, +0xEF, 0x04, 0xFD, 0x7F, 0xFF, 0x12, 0x7B, 0x3E, 0x12, 0x8F, 0xF7, 0x12, 0x84, 0x4D, 0x80, 0x9F, +0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x18, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, 0xE0, 0x0E, 0xC3, +0x13, 0x30, 0xE0, 0x07, 0x71, 0x64, 0xBF, 0x01, 0x06, 0x80, 0x02, 0x80, 0x00, 0x51, 0x90, 0x22, +0x90, 0x85, 0xC8, 0xE0, 0xFF, 0x60, 0x03, 0xB4, 0x08, 0x0E, 0x51, 0xA9, 0xBF, 0x01, 0x09, 0x12, +0xB7, 0xB3, 0x90, 0x01, 0xE5, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x92, 0x84, 0xE0, 0xC3, 0x13, 0x20, +0xE0, 0x2A, 0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80, 0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, +0x60, 0x05, 0x75, 0x61, 0x01, 0x80, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02, 0x80, 0x07, +0x90, 0x02, 0x86, 0xE0, 0x30, 0xE3, 0x05, 0x75, 0x61, 0x04, 0x80, 0x0D, 0x90, 0x04, 0x1D, 0xE0, +0x60, 0x05, 0x75, 0x61, 0x40, 0x80, 0x02, 0x80, 0x73, 0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, +0x01, 0xB8, 0xE5, 0x61, 0xF0, 0x7F, 0x00, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x92, 0x90, 0xE0, 0x60, 0x25, 0x7F, 0x54, 0x7E, 0x09, 0x12, 0x70, 0x61, 0x71, 0x50, 0xEF, 0x44, +0xFE, 0xFF, 0xEE, 0x44, 0x03, 0xFE, 0xED, 0x44, 0x04, 0xFD, 0xEC, 0x71, 0x50, 0x90, 0x91, 0x66, +0x12, 0x04, 0xEB, 0x7F, 0x54, 0x7E, 0x09, 0x12, 0x71, 0x18, 0x90, 0x92, 0x8B, 0xE0, 0x70, 0x04, +0x90, 0x07, 0xCC, 0xF0, 0x90, 0x92, 0x93, 0xE0, 0x70, 0x0A, 0x90, 0x92, 0x90, 0xE0, 0x70, 0x04, +0xA3, 0xE0, 0x60, 0x07, 0x90, 0x00, 0x1F, 0xE0, 0x54, 0xF0, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x90, 0x92, 0x2E, 0x12, 0x04, 0xEB, 0x90, 0x92, 0x2E, 0x02, 0x87, 0x58, 0x90, 0x01, 0xB8, 0xE4, +0xF0, 0x7F, 0x01, 0x22, 0x90, 0x85, 0xBF, 0xE0, 0x64, 0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, +0x75, 0x0F, 0x01, 0x80, 0x51, 0x90, 0x85, 0xC9, 0xE0, 0xFF, 0x54, 0x03, 0x60, 0x05, 0x75, 0x0F, +0x02, 0x80, 0x43, 0x90, 0x85, 0xC7, 0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x50, 0x05, 0x75, 0x0F, 0x04, +0x80, 0x34, 0xEF, 0x30, 0xE2, 0x05, 0x75, 0x0F, 0x08, 0x80, 0x2B, 0x90, 0x85, 0xC9, 0xE0, 0x30, +0xE4, 0x05, 0x75, 0x0F, 0x10, 0x80, 0x1F, 0x90, 0x85, 0xC2, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x20, +0xE0, 0x05, 0x75, 0x0F, 0x20, 0x80, 0x0F, 0x90, 0x86, 0x71, 0xE0, 0x60, 0x05, 0x75, 0x0F, 0x80, +0x80, 0x04, 0x71, 0x5C, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01, 0xB8, 0xE5, +0x0F, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x84, 0xA1, 0x74, 0x02, 0xF0, 0xA3, +0x74, 0x10, 0xF0, 0x90, 0x84, 0xA7, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0xE4, 0xFB, +0xFA, 0xFD, 0x7F, 0x01, 0x12, 0x86, 0x4E, 0x90, 0x92, 0x32, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x84, +0xC1, 0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE0, 0x0F, 0x90, +0x84, 0xC1, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0x12, 0x2D, 0xBD, 0x12, 0x92, 0x7E, 0x91, 0x59, +0x30, 0xE1, 0x06, 0x54, 0xFD, 0xF0, 0x12, 0x60, 0x5D, 0x91, 0x59, 0x30, 0xE2, 0x06, 0x54, 0xFB, +0xF0, 0x12, 0x6A, 0x6D, 0x91, 0x59, 0x30, 0xE4, 0x0C, 0x54, 0xEF, 0xF0, 0x12, 0x6F, 0x22, 0xBF, +0x01, 0x03, 0x12, 0xB3, 0xB2, 0xD2, 0xAF, 0x80, 0xB5, 0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x84, 0xC1, +0xE0, 0xFF, 0x22, 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, 0x64, 0xF0, 0x74, 0xBC, 0xA3, 0xF0, 0x12, 0x6C, 0xBC, 0x74, 0x64, +0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xBC, 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, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, +0xC0, 0x05, 0xC0, 0x07, 0x7D, 0xB5, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0xBC, 0xFF, 0xA3, 0xF0, +0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, 0xD0, +0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, +0xA3, 0xF0, 0x22, 0x90, 0x88, 0xE7, 0xE0, 0x04, 0xF0, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, 0xE0, +0x05, 0x12, 0x9E, 0xAB, 0x60, 0x1B, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x04, 0xEF, 0x30, 0xE0, 0x0B, +0x90, 0x85, 0xC8, 0xE0, 0x64, 0x02, 0x60, 0x09, 0x12, 0xA0, 0x76, 0x90, 0x01, 0xE6, 0xE0, 0x04, +0xF0, 0x22, 0x12, 0x9F, 0xF4, 0x64, 0x01, 0x70, 0x13, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0D, 0x90, +0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0x12, 0x9E, 0x03, 0x22, 0xE4, 0xFF, 0x12, +0x77, 0x39, 0xBF, 0x01, 0x13, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0D, 0x12, 0x9F, 0x13, 0x64, 0x02, +0x60, 0x03, 0x02, 0x77, 0x61, 0x12, 0x79, 0x41, 0x22, 0xF1, 0x88, 0x90, 0x92, 0x67, 0xEF, 0xF0, +0x30, 0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x57, 0x82, 0x90, 0x92, +0x67, 0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06, +0x90, 0x01, 0x2F, 0x74, 0x80, 0xF0, 0xB1, 0x8C, 0xFB, 0x02, 0x51, 0x7D, 0x90, 0x85, 0xD7, 0xE0, +0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x85, 0xDE, 0xE0, 0x22, 0xE4, 0x90, 0x92, 0x56, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0x90, 0x92, 0x9F, 0x12, 0x87, 0x58, 0x90, 0x92, 0x9B, 0x12, 0x87, 0x64, 0xC3, 0x12, +0x04, 0xB4, 0x40, 0x50, 0x90, 0x85, 0xC1, 0xE0, 0x90, 0x92, 0x9F, 0x30, 0xE0, 0x14, 0xF1, 0x10, +0x74, 0x0A, 0x9E, 0x2F, 0xFF, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x04, 0x2F, 0xFF, 0x90, 0x92, 0xD0, +0x80, 0x0A, 0xF1, 0x10, 0x74, 0x0A, 0x9E, 0x2F, 0xFF, 0x90, 0x92, 0xD1, 0xE0, 0xFE, 0xC3, 0xEF, +0x9E, 0x90, 0x92, 0x57, 0xF0, 0x90, 0x92, 0x57, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x50, 0x15, 0x74, +0xA3, 0x2F, 0xF1, 0x28, 0xE0, 0x04, 0xF0, 0x90, 0x85, 0xDB, 0xE0, 0x04, 0xF0, 0xE0, 0xFD, 0x7F, +0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xDB, 0xE0, 0xFF, 0xD3, 0x90, 0x92, 0xD3, 0xE0, 0x9F, 0x90, +0x92, 0xD2, 0xE0, 0x94, 0x00, 0x40, 0x02, 0xC1, 0xDC, 0xD1, 0xEE, 0xD1, 0xE5, 0x50, 0x1C, 0xD1, +0xF8, 0x90, 0x92, 0x58, 0xE0, 0xD3, 0x9F, 0x40, 0x0A, 0x90, 0x92, 0x56, 0xE0, 0x90, 0x92, 0x59, +0xF0, 0x80, 0x08, 0x90, 0x92, 0x56, 0xE0, 0x04, 0xF0, 0x80, 0xE0, 0xD1, 0xEE, 0xD1, 0xE5, 0x50, +0x2C, 0xD1, 0xF8, 0xC3, 0x90, 0x92, 0xD3, 0xE0, 0x9F, 0xFF, 0x90, 0x92, 0xD2, 0xE0, 0x94, 0x00, +0xFE, 0x90, 0x92, 0x58, 0xE0, 0xD3, 0x9F, 0xE4, 0x9E, 0x40, 0x0A, 0x90, 0x92, 0x56, 0xE0, 0x90, +0x92, 0x5A, 0xF0, 0x80, 0x08, 0x90, 0x92, 0x56, 0xE0, 0x04, 0xF0, 0x80, 0xD0, 0x90, 0x92, 0x59, +0xE0, 0x90, 0x85, 0xE0, 0xF0, 0x90, 0x92, 0x5A, 0xE0, 0x90, 0x85, 0xE1, 0xD1, 0xDD, 0x94, 0x0A, +0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, 0x85, 0xD8, 0xF0, 0xE4, 0x80, 0x09, 0xE4, 0x90, 0x85, 0xD8, +0xD1, 0xDD, 0x74, 0x0A, 0x9F, 0x90, 0x85, 0xD7, 0xF0, 0x90, 0x85, 0xE0, 0xE0, 0xFF, 0xA3, 0xE0, +0xC3, 0x9F, 0x90, 0x85, 0xDE, 0xF0, 0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x05, 0x90, 0x92, 0xD0, +0x80, 0x03, 0x90, 0x92, 0xD1, 0xE0, 0xFF, 0x90, 0x85, 0xDE, 0xE0, 0x2F, 0x04, 0xF0, 0x90, 0x85, +0xDE, 0xE0, 0xC3, 0x94, 0x0A, 0x50, 0x03, 0x74, 0x0A, 0xF0, 0x90, 0x85, 0xDE, 0xE0, 0x24, 0x02, +0xF0, 0xB1, 0x8C, 0xFB, 0x12, 0x51, 0x7D, 0xE4, 0xFF, 0x12, 0x69, 0x33, 0x22, 0xF0, 0x90, 0x85, +0xE0, 0xE0, 0xFF, 0xC3, 0x22, 0x90, 0x92, 0x56, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x22, 0xE4, 0x90, +0x92, 0x58, 0xF0, 0x90, 0x92, 0x56, 0xF0, 0x22, 0x74, 0xA3, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x92, +0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x92, 0x58, 0xE0, 0x2F, 0xF0, 0x90, 0x92, 0xD4, 0xE0, 0xFF, 0x22, +0x12, 0x87, 0x64, 0x90, 0x92, 0x9B, 0x12, 0x87, 0x58, 0x12, 0x87, 0x30, 0x78, 0x0A, 0x12, 0x04, +0xC5, 0x90, 0x85, 0xDD, 0xE0, 0xFE, 0xC3, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, +0xE4, 0xFE, 0x74, 0xA3, 0x2E, 0xF1, 0x28, 0xE4, 0xF0, 0x0E, 0xEE, 0xB4, 0x2D, 0xF4, 0xE4, 0x90, +0x85, 0xDC, 0xF0, 0x90, 0x85, 0xDB, 0xF0, 0x90, 0x85, 0xDF, 0xF0, 0xEF, 0xB4, 0x01, 0x07, 0xA3, +0x74, 0x2D, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, 0x93, 0x1F, 0x12, 0x87, 0x79, 0x12, 0x71, 0x54, +0x90, 0x85, 0xC5, 0xE0, 0xFF, 0x12, 0x60, 0xD0, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x19, 0x90, 0x93, +0x1F, 0x12, 0x87, 0x70, 0x12, 0x8D, 0x91, 0x54, 0x0F, 0xFF, 0x12, 0x8C, 0xA8, 0xFD, 0x12, 0x6A, +0xB8, 0xB1, 0x8C, 0xFB, 0x12, 0x51, 0x7D, 0x22, 0xE4, 0x90, 0x92, 0x69, 0xF0, 0xA3, 0xF0, 0x7F, +0x83, 0x12, 0x7B, 0x51, 0x90, 0x92, 0x68, 0xEF, 0xF0, 0x7F, 0x83, 0x12, 0x7B, 0x51, 0xAE, 0x07, +0x90, 0x92, 0x68, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0x92, 0x6A, 0xE0, 0x94, 0x64, +0x90, 0x92, 0x69, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, +0x92, 0x68, 0xE0, 0xFF, 0x22, 0x90, 0x92, 0x69, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x80, +0xBE, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, 0xE0, 0x40, 0x90, 0x85, 0xC0, 0xE0, 0x7E, 0x00, 0xB4, +0x02, 0x02, 0x7E, 0x01, 0x90, 0x85, 0xBF, 0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, +0x4E, 0x70, 0x26, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x03, 0x02, 0x9F, 0x5F, 0x12, 0xA7, 0x47, 0x90, +0x85, 0xC0, 0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08, 0x80, 0x0A, 0x90, 0x85, 0xC0, 0xE0, +0xB4, 0x04, 0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x9A, 0x4C, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x7F, 0x02, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x7B, 0x3E, 0x90, +0x01, 0x00, 0x74, 0x3F, 0xF0, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0x90, 0x01, 0x01, 0xE0, 0x54, +0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7D, 0x20, +0x7F, 0xFF, 0x12, 0x90, 0xDB, 0x11, 0x1A, 0x90, 0x85, 0xBF, 0x74, 0x02, 0xF0, 0x22, 0x11, 0x69, +0x7D, 0x23, 0x80, 0xEC, 0x12, 0x9F, 0xE5, 0x80, 0xE5, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, +0x22, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x85, 0xD0, 0xE0, 0xFD, 0x7F, 0x93, 0x12, +0x7B, 0x3E, 0x90, 0x85, 0xC6, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, +0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, +0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x7B, 0x3E, 0x7F, 0x01, 0x12, 0xB7, 0x43, 0x7D, 0x34, 0x7F, +0x27, 0x12, 0x7B, 0x3E, 0x7F, 0x90, 0x12, 0xAF, 0xA4, 0x7F, 0x90, 0x12, 0x7B, 0x3E, 0x7F, 0x14, +0x7E, 0x00, 0x02, 0x7C, 0x9F, 0x7D, 0x07, 0xAF, 0x62, 0xED, 0x30, 0xE0, 0x21, 0x75, 0xF0, 0x12, +0xEF, 0x90, 0x89, 0x44, 0x31, 0x18, 0xEF, 0x90, 0x89, 0x46, 0x31, 0x18, 0xEF, 0x90, 0x89, 0x48, +0x31, 0x18, 0xEF, 0x90, 0x89, 0x4A, 0x31, 0x18, 0xEF, 0x90, 0x89, 0x4C, 0x31, 0x23, 0xED, 0x30, +0xE1, 0x09, 0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, 0x40, 0x31, 0x23, 0xED, 0x30, 0xE2, 0x0C, 0x75, +0xF0, 0x12, 0xEF, 0x90, 0x89, 0x42, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0x31, 0x2B, 0xE0, 0x54, 0xBF, +0x44, 0x80, 0xFE, 0x31, 0x2B, 0xEE, 0xF0, 0x22, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, +0xF0, 0x12, 0x22, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xA3, 0xF0, 0x22, 0xEF, 0xC4, 0x54, 0xF0, 0x24, +0x03, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x90, +0x89, 0x1B, 0x12, 0x87, 0x79, 0x7B, 0xFF, 0x7A, 0x82, 0x79, 0x00, 0x90, 0x89, 0x1E, 0x12, 0x87, +0x79, 0x7A, 0x82, 0x79, 0x3F, 0x90, 0x89, 0x21, 0x12, 0x87, 0x79, 0x7A, 0x82, 0x79, 0xE1, 0x90, +0x89, 0x27, 0x12, 0x87, 0x79, 0x7A, 0x82, 0x79, 0xF5, 0x90, 0x89, 0x2A, 0x12, 0x87, 0x79, 0x7A, +0x83, 0x79, 0x1D, 0x90, 0x89, 0x2D, 0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, 0x31, 0x90, 0x89, 0x33, +0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, 0x59, 0x90, 0x89, 0x36, 0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, +0x81, 0x90, 0x89, 0x39, 0x12, 0x87, 0x79, 0xE4, 0x90, 0x92, 0xD6, 0xF0, 0x90, 0x92, 0x29, 0xF0, +0x90, 0x92, 0x29, 0xE0, 0xFF, 0xC3, 0x94, 0x05, 0x50, 0x10, 0x74, 0xE7, 0x2F, 0x12, 0x97, 0x0C, +0xE4, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0x04, 0xF0, 0x80, 0xE6, 0x22, 0x90, 0x01, 0x94, 0xE0, 0x44, +0x01, 0xF0, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0x92, 0x56, 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, 0x75, 0xB6, 0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x7B, +0x3E, 0x80, 0xFE, 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, 0xC3, 0xEE, 0x94, 0x01, 0x40, 0x0A, 0x0D, 0xED, 0x13, 0x90, 0xFD, 0x10, 0xF0, 0xE4, +0x2F, 0xFF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x13, 0xED, 0xF0, 0xA3, +0xEB, 0xF0, 0x90, 0x93, 0x12, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0xAF, 0x94, 0x90, 0x93, 0x12, +0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x93, 0x13, 0xE0, 0x60, 0x05, 0x51, 0xFC, 0x44, 0x80, 0xF0, +0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, 0xF0, +0x51, 0xFC, 0x54, 0xC0, 0xF0, 0x90, 0x93, 0x15, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x18, 0x2E, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x00, 0x8B, 0xE0, 0xD3, 0x94, 0x03, 0x74, +0x10, 0x40, 0x07, 0x51, 0xF3, 0x74, 0x04, 0xF0, 0x80, 0x04, 0x51, 0xF3, 0xE4, 0xF0, 0xAF, 0x05, +0x51, 0xEA, 0xF5, 0x83, 0xE0, 0x54, 0x01, 0xFE, 0x90, 0x93, 0x14, 0xE0, 0x25, 0xE0, 0x25, 0xE0, +0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0x51, 0xEA, 0xF5, 0x83, 0xEE, 0xF0, 0x74, 0x11, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x74, 0xFF, 0xF0, 0x74, 0x29, 0x2F, 0x71, 0xC1, 0x54, 0xF7, +0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, 0x12, 0x2F, 0xF5, 0x82, 0xE4, +0x34, 0xFC, 0x22, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0x74, 0x21, 0x2F, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xE4, 0x90, 0x92, 0x59, 0xF0, 0xA3, 0xF0, 0x90, +0x06, 0x32, 0xE0, 0x44, 0x20, 0xF0, 0x12, 0x75, 0xE4, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x61, 0xA7, +0x90, 0x88, 0xD9, 0xE0, 0xFF, 0x90, 0x93, 0x15, 0x74, 0x0A, 0xF0, 0x7B, 0x08, 0x7D, 0x01, 0x51, +0x43, 0x90, 0x92, 0x56, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x56, 0xA3, 0x71, 0xB1, 0xFD, +0x74, 0x2C, 0x2E, 0x71, 0xCA, 0x90, 0x92, 0x58, 0xEF, 0xF0, 0x90, 0x92, 0x56, 0xA3, 0xE0, 0x24, +0x28, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xE4, 0xFD, 0x12, 0x52, 0x21, 0x90, 0x92, 0x58, +0xE0, 0xFF, 0x90, 0x92, 0x57, 0xE0, 0x2F, 0xFF, 0x90, 0x92, 0x56, 0xE0, 0x34, 0x00, 0xCF, 0x24, +0x30, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x92, 0x59, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0xAE, 0x22, 0x71, +0xA8, 0x90, 0x88, 0xD9, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x15, 0x44, 0x71, 0xA8, 0x90, 0x88, 0xD5, +0xE0, 0xFB, 0x7F, 0x11, 0x12, 0x15, 0x44, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x90, 0x88, 0x88, +0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x22, 0x90, 0x92, 0x59, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, +0x22, 0xE0, 0xFE, 0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x29, +0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0xE0, 0xFB, 0x02, 0x5D, 0x98, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x00, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x70, 0x61, 0x90, 0x93, 0x0A, 0x12, 0x04, 0xEB, 0x90, 0x93, +0x02, 0x12, 0x87, 0x58, 0x12, 0x04, 0xA7, 0x90, 0x93, 0x0A, 0x12, 0x87, 0x64, 0x12, 0x87, 0x3E, +0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x93, 0x02, 0x12, 0x87, 0x58, 0x90, 0x93, +0x06, 0x12, 0x87, 0x64, 0x12, 0x87, 0x3E, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, +0x87, 0x4B, 0x90, 0x93, 0x0E, 0x12, 0x04, 0xEB, 0x90, 0x93, 0x0E, 0x12, 0x87, 0x58, 0x90, 0x91, +0x66, 0x12, 0x04, 0xEB, 0x90, 0x93, 0x00, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x71, 0x18, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, 0xC4, 0x74, 0x44, 0xF0, 0x74, 0xC4, 0xA3, 0xF0, 0x7F, 0x90, +0x12, 0x7B, 0x51, 0xEF, 0x20, 0xE0, 0xF7, 0x74, 0x44, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xC4, +0xA3, 0xF0, 0x22, 0x7E, 0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x85, 0x79, 0xBC, 0x12, +0x06, 0xDE, 0x90, 0x85, 0xBC, 0xE0, 0x54, 0xFD, 0xF0, 0xE4, 0x12, 0x96, 0xD3, 0xA3, 0x74, 0x0C, +0xF0, 0x22, 0x7D, 0x1F, 0x12, 0xAE, 0xA7, 0x54, 0xBF, 0xF0, 0x90, 0x85, 0xBF, 0x74, 0x04, 0xF0, +0x22, 0x12, 0x9F, 0xE5, 0x80, 0xEC, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, 0xE4, 0x90, 0x85, +0xBF, 0xF0, 0x22, 0x91, 0xB1, 0x80, 0xEF, 0x12, 0xAF, 0xDA, 0x80, 0xEA, 0x12, 0x9F, 0xEC, 0x80, +0xE5, 0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xDB, 0x02, 0x9F, 0xE5, 0x7D, 0x25, 0x12, 0xAE, 0xA7, 0x54, +0xBF, 0xF0, 0x90, 0x85, 0xBF, 0x74, 0x04, 0xF0, 0x22, 0x12, 0x7A, 0x29, 0xEF, 0x70, 0x03, 0x12, +0x9E, 0xE8, 0x22, 0xAC, 0x07, 0x90, 0x92, 0x96, 0xE0, 0xF9, 0x30, 0xE0, 0x02, 0xA1, 0x87, 0x90, +0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x04, 0x90, 0x85, 0xDA, 0xF0, +0x90, 0x85, 0xFB, 0xE0, 0x24, 0x03, 0x90, 0x85, 0xD9, 0xF0, 0x80, 0x0D, 0x90, 0x85, 0xDA, 0x74, +0x02, 0xF0, 0x90, 0x85, 0xD9, 0x14, 0xF0, 0x0B, 0x0B, 0x90, 0x85, 0xD9, 0xE0, 0xFA, 0x90, 0x85, +0xD8, 0xE0, 0xD3, 0x9A, 0x50, 0x0E, 0x90, 0x85, 0xCD, 0xEB, 0xF0, 0x90, 0x85, 0xDA, 0xE0, 0xC3, +0x9D, 0x2C, 0x80, 0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90, 0x85, 0xCD, 0xF0, 0x90, 0x85, 0xD9, 0xE0, +0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x85, 0xDD, 0xF0, 0x90, 0x85, 0xDA, 0xE0, 0xFF, 0x24, 0x0A, +0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x85, 0xDD, 0xB1, 0x8F, 0x98, 0x40, 0x04, 0xEF, 0x24, 0x0A, 0xF0, +0x90, 0x85, 0xDD, 0xE0, 0xFF, 0x24, 0x23, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x85, 0xCD, 0xB1, 0x8F, +0x98, 0x40, 0x04, 0xEF, 0x24, 0x23, 0xF0, 0x90, 0x85, 0xDD, 0xE0, 0xFF, 0x7E, 0x00, 0x90, 0x85, +0xD1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58, 0xE0, 0x6F, 0x70, 0x01, 0xE4, 0x60, 0x02, +0xB1, 0x99, 0xE9, 0x54, 0xFD, 0x80, 0x03, 0xE9, 0x44, 0x02, 0x90, 0x92, 0x96, 0xF0, 0x22, 0xE0, +0xD3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x22, 0x90, 0x85, 0xD1, 0xA3, 0xE0, 0x90, 0x05, +0x58, 0xF0, 0x22, 0x90, 0x92, 0xD0, 0x74, 0x04, 0xF0, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0xE4, 0xF0, +0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0xA7, 0x94, 0x40, 0x2B, +0x90, 0x85, 0xDF, 0xE0, 0x04, 0xF0, 0x90, 0x92, 0xD5, 0xE0, 0xFF, 0x90, 0x85, 0xDF, 0xE0, 0xD3, +0x9F, 0x50, 0x18, 0x90, 0x85, 0xD7, 0xE0, 0x04, 0x12, 0x9D, 0xDE, 0x90, 0x85, 0xDE, 0xF0, 0xFB, +0x90, 0x85, 0xD7, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x12, 0x51, 0x7D, 0x22, 0x90, 0x92, 0x7B, 0xEF, +0xF0, 0x90, 0x84, 0xC5, 0xE0, 0x64, 0x02, 0x70, 0x1F, 0x90, 0x92, 0x7B, 0xE0, 0xFD, 0x64, 0x01, +0x70, 0x32, 0x12, 0xB6, 0xBE, 0x12, 0x8D, 0x97, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x4D, 0xE0, 0x64, +0x80, 0xF0, 0x80, 0x20, 0xAF, 0x05, 0x80, 0x19, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x7F, 0x64, +0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x92, 0x7B, 0xE0, +0xFF, 0x12, 0x2A, 0x87, 0x90, 0x88, 0xE1, 0xE0, 0x54, 0xFE, 0xF0, 0x02, 0xAF, 0x9C, 0x90, 0x92, +0x7C, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x80, 0xF0, 0x7D, 0x09, 0x12, 0x55, 0x36, +0xEF, 0x64, 0x06, 0x70, 0x2A, 0xD1, 0xD3, 0x7D, 0x14, 0x12, 0x55, 0x36, 0xEF, 0x70, 0x20, 0xD1, +0xD3, 0x7D, 0x15, 0x12, 0x55, 0x36, 0xEF, 0x64, 0x50, 0x70, 0x14, 0xD1, 0xD3, 0x7D, 0x21, 0x12, +0x55, 0x36, 0xEF, 0x20, 0xE0, 0x03, 0x30, 0xE2, 0x06, 0x90, 0x92, 0x80, 0x74, 0x01, 0xF0, 0x90, +0x86, 0x73, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x3F, 0xD1, 0xD3, 0x7D, 0x09, 0x12, 0x55, +0x36, 0xEF, 0x64, 0x11, 0x70, 0x33, 0x90, 0x92, 0x7D, 0xE0, 0x24, 0x14, 0xFF, 0x90, 0x92, 0x7C, +0xE0, 0x34, 0x00, 0xFE, 0x90, 0x92, 0x7E, 0xF0, 0xA3, 0xEF, 0xF0, 0x7D, 0x02, 0x12, 0x55, 0x36, +0xEF, 0x70, 0x16, 0x90, 0x92, 0x7E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7D, 0x03, 0x12, 0x55, 0x36, +0xBF, 0x89, 0x06, 0x90, 0x92, 0x80, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x80, 0xE0, 0xFF, 0xD1, 0xDC, +0xEF, 0xF0, 0x22, 0x90, 0x92, 0x7C, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x84, 0xBF, 0xA3, +0xE0, 0x24, 0x7F, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22, 0xF1, 0x31, 0xA3, 0xED, 0xF0, +0x90, 0x88, 0x7C, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x60, 0x23, 0xE4, 0x90, 0x92, 0x36, 0xF0, 0xF1, +0x3A, 0x50, 0x1D, 0xF1, 0x7E, 0x24, 0x8A, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0x6F, +0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x92, 0x36, 0xE0, 0x04, 0xF0, 0x80, 0xE2, 0x7F, 0x00, 0x22, +0x90, 0x06, 0x32, 0xE0, 0x44, 0x40, 0xF0, 0xE4, 0x90, 0x88, 0x88, 0xF0, 0xA3, 0xF0, 0x7F, 0x01, +0x22, 0x90, 0x92, 0x33, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x92, 0x36, 0xE0, 0xFD, 0xC3, +0x94, 0x02, 0x22, 0xF1, 0x31, 0xA3, 0xED, 0xF0, 0xE4, 0xA3, 0xF0, 0xF1, 0x3A, 0x50, 0x17, 0xF1, +0x7E, 0x24, 0xAA, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0xB5, 0x07, 0x1D, 0x90, 0x92, +0x36, 0xE0, 0x04, 0xF0, 0x80, 0xE5, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x01, 0xC7, +0x74, 0x30, 0xF0, 0x7F, 0x01, 0x12, 0x5F, 0xE9, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x92, +0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xED, 0x24, 0x1C, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x92, 0x36, +0xE0, 0x22, 0xF1, 0x31, 0x24, 0x16, 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, 0xFD, 0x12, 0x55, 0x36, 0x90, +0x88, 0x86, 0xA3, 0xE0, 0xB5, 0x07, 0x19, 0x90, 0x92, 0x34, 0xE0, 0x24, 0x16, 0xF1, 0xC6, 0x7D, +0x01, 0x12, 0x55, 0x36, 0xEF, 0xFD, 0x90, 0x88, 0x86, 0xE0, 0x6D, 0x70, 0x01, 0xE4, 0x60, 0x03, +0x7F, 0x00, 0x22, 0x7F, 0x01, 0x22, 0xFF, 0x90, 0x92, 0x33, 0xE0, 0x34, 0x00, 0xFE, 0x22, 0xF1, +0x31, 0xE4, 0xA3, 0xF0, 0x90, 0x92, 0x35, 0xE0, 0xFD, 0xC3, 0x94, 0x04, 0x50, 0x27, 0x90, 0x92, +0x34, 0xE0, 0x24, 0x10, 0xF1, 0xC6, 0x12, 0x55, 0x36, 0x90, 0x92, 0x35, 0xE0, 0x24, 0x82, 0xF5, +0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x92, 0x35, +0xE0, 0x04, 0xF0, 0x80, 0xCF, 0x7F, 0x01, 0x22, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, +0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x74, 0x01, 0x93, 0x90, 0x92, 0x41, 0xCF, 0xF0, +0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x3F, 0xE5, 0x66, 0xF0, 0xA3, 0xE5, 0x67, 0xF0, 0x22, 0x90, 0x05, +0x63, 0xE0, 0x90, 0x92, 0x9F, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0x90, 0x92, 0xA0, 0xF0, 0x90, 0x05, +0x61, 0xE0, 0x90, 0x92, 0xA1, 0xF0, 0x90, 0x05, 0x60, 0xE0, 0x90, 0x92, 0xA2, 0xF0, 0x90, 0x92, +0x96, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x92, 0x78, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, +0x90, 0x92, 0x76, 0xE0, 0xFF, 0x12, 0x65, 0x61, 0x90, 0x92, 0x78, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, +0x02, 0x50, 0xD7, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, +0x22, 0x74, 0xD7, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x12, +0x90, 0x89, 0x3C, 0x12, 0x05, 0x28, 0xE0, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x7F, +0x14, 0x7E, 0x00, 0x02, 0x7C, 0x9F, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, 0xE4, 0x34, +0x82, 0xF5, 0x83, 0x22, 0xC4, 0x54, 0xF0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, +0xE0, 0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x85, 0xC7, 0xE0, 0x90, 0x01, 0xBB, 0x22, 0xF0, +0x74, 0xCC, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, 0x74, 0xBC, 0x25, 0x62, 0xF5, +0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, 0x90, 0x92, 0x41, 0xE4, 0xF0, 0xA3, 0x22, 0x90, 0x92, +0x07, 0x12, 0x87, 0x79, 0x02, 0x02, 0xF6, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0x02, 0x03, 0xED, +0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x92, 0x41, 0xCF, 0x22, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x4E, +0x22, 0x54, 0x20, 0xFE, 0xEF, 0x54, 0xDF, 0x4E, 0x22, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, +0x22, 0x12, 0x02, 0xF6, 0x13, 0x13, 0x54, 0x3F, 0x22, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x10, 0xF0, +0x22, 0xF9, 0xE4, 0x3A, 0xFA, 0x02, 0x02, 0xF6, 0xE5, 0x68, 0xF0, 0xA3, 0xE5, 0x69, 0xF0, 0x22, +0x90, 0x00, 0x02, 0x12, 0x04, 0x18, 0xFF, 0x22, 0x7D, 0x05, 0x7F, 0x04, 0x02, 0x97, 0x1A, 0x00, +0x18, 0x19, +}; +u4Byte ArrayLength_MP_8188F_FW_NIC = 18802; + + +void +ODM_ReadFirmware_MP_8188F_FW_NIC( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + *((SIZE_PTR *)pFirmware) = (SIZE_PTR)Array_MP_8188F_FW_NIC; +#else + ODM_MoveMemory(pDM_Odm, pFirmware, Array_MP_8188F_FW_NIC, ArrayLength_MP_8188F_FW_NIC); +#endif + *pFirmwareSize = ArrayLength_MP_8188F_FW_NIC; +} + + +u1Byte Array_MP_8188F_FW_WoWLAN[] = { +0xF1, 0x88, 0x30, 0x00, 0x01, 0x00, 0x07, 0x00, 0x10, 0x22, 0x17, 0x28, 0x30, 0x49, 0x02, 0x00, +0xE7, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x86, 0xAD, 0x02, 0xBD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xA6, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xBD, 0x56, 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, 0xBD, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB9, 0x34, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0xBD, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x87, 0xBB, 0x02, 0x88, 0xE7, 0x02, 0x80, 0x86, 0x02, 0x80, 0x89, 0x02, 0x80, 0x8C, 0x02, +0x9D, 0x7E, 0x02, 0xB9, 0x12, 0x02, 0x80, 0x95, 0x02, 0x80, 0x98, 0x02, 0x80, 0x9B, 0x02, 0x80, +0x9E, 0x02, 0x80, 0xA1, 0x02, 0x80, 0xA4, 0x02, 0x80, 0xA7, 0x02, 0x80, 0xAA, 0x02, 0x80, 0xAD, +0x02, 0x80, 0xB0, 0x02, 0x89, 0xB5, 0x02, 0x80, 0xB6, 0x02, 0x80, 0xB9, 0x02, 0xB0, 0x4D, 0x02, +0xB1, 0x2A, 0x02, 0xB0, 0xAF, 0x02, 0xAF, 0x6D, 0x02, 0xA8, 0x68, 0x02, 0xAF, 0xE4, 0x02, 0x80, +0xCE, 0x02, 0x80, 0xD1, 0x02, 0xC6, 0x0A, 0x02, 0x80, 0xD7, 0x00, 0x00, 0x00, 0x02, 0x80, 0xDD, +0x02, 0x80, 0xE0, 0x02, 0x80, 0xE3, 0x02, 0x80, 0xE6, 0x02, 0xC5, 0xB3, 0x02, 0x80, 0xEC, 0x02, +0x80, 0xEF, 0x02, 0x80, 0xF2, 0x02, 0x80, 0xF5, 0x02, 0x80, 0xF8, 0x02, 0x80, 0xFB, 0x02, 0x80, +0xFE, 0x02, 0x81, 0x01, 0x02, 0x81, 0x04, 0x02, 0x81, 0x07, 0x02, 0x81, 0x0A, 0x02, 0x81, 0x0D, +0x02, 0x81, 0x10, 0x02, 0x81, 0x13, 0x02, 0x81, 0x16, 0x02, 0x81, 0x19, 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, 0xB3, 0xE4, 0x02, 0xB5, 0xB4, 0x02, 0x90, 0xE8, 0x02, 0x90, 0xDD, +0x02, 0x81, 0x40, 0x02, 0x9E, 0xDE, 0x02, 0xC4, 0x21, 0x02, 0x81, 0x49, 0x02, 0x81, 0x4C, 0x02, +0x81, 0x4F, 0x02, 0x81, 0x52, 0x02, 0x81, 0x55, 0x02, 0x81, 0x58, 0x02, 0x81, 0x5B, 0x02, 0x91, +0x46, 0x02, 0x81, 0x61, 0x02, 0x81, 0x64, 0x02, 0xC4, 0x9A, 0x02, 0xC5, 0x6A, 0x02, 0xBC, 0x1A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, +0x08, 0x03, 0x03, 0x00, 0x04, 0x09, 0x07, 0x03, 0x03, 0x00, 0x04, 0x08, 0x06, 0x03, 0x02, 0x00, +0x04, 0x08, 0x05, 0x03, 0x01, 0x00, 0x04, 0x0D, 0x0A, 0x07, 0x05, 0x00, 0x08, 0x0C, 0x0A, 0x07, +0x04, 0x00, 0x08, 0x0B, 0x0A, 0x06, 0x05, 0x00, 0x08, 0x0B, 0x0A, 0x05, 0x03, 0x00, 0x08, 0x0B, +0x0A, 0x03, 0x02, 0x00, 0x08, 0x14, 0x12, 0x0C, 0x04, 0x00, 0x10, 0x14, 0x12, 0x09, 0x04, 0x00, +0x10, 0x24, 0x22, 0x1C, 0x12, 0x00, 0x20, 0x24, 0x22, 0x18, 0x0C, 0x00, 0x20, 0x24, 0x22, 0x14, +0x06, 0x00, 0x20, 0x24, 0x22, 0x0F, 0x04, 0x00, 0x20, 0x24, 0x21, 0x0A, 0x04, 0x00, 0x20, 0x23, +0x21, 0x0C, 0x04, 0x00, 0x20, 0x23, 0x1F, 0x0A, 0x04, 0x00, 0x20, 0x22, 0x1F, 0x0F, 0x04, 0x00, +0x20, 0x21, 0x1F, 0x16, 0x0C, 0x00, 0x20, 0x31, 0x2F, 0x20, 0x14, 0x00, 0x30, 0x31, 0x2F, 0x18, +0x10, 0x00, 0x30, 0x31, 0x2C, 0x18, 0x0C, 0x00, 0x30, 0x31, 0x2A, 0x14, 0x0C, 0x00, 0x30, 0x31, +0x28, 0x14, 0x00, 0x00, 0x30, 0x31, 0x24, 0x14, 0x00, 0x00, 0x30, 0x31, 0x1E, 0x14, 0x00, 0x00, +0x30, 0x02, 0x02, 0x03, 0x04, 0x04, 0x08, 0x09, 0x09, 0x0C, 0x0E, 0x10, 0x12, 0x02, 0x09, 0x0B, +0x0E, 0x0D, 0x0F, 0x10, 0x12, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x23, 0x00, +0x2D, 0x00, 0x50, 0x00, 0x91, 0x00, 0xC3, 0x01, 0x27, 0x01, 0x31, 0x01, 0x5E, 0x00, 0x8C, 0x00, +0xC8, 0x00, 0xDC, 0x01, 0x5E, 0x01, 0x68, 0x01, 0x9A, 0x01, 0xCC, 0x01, 0xEA, 0x02, 0x02, 0x04, +0x08, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x14, 0x28, 0x32, 0x50, 0x78, 0xA0, 0xC8, +0xE6, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x02, 0x04, 0x06, +0x07, 0x07, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, +0x02, 0x03, 0x03, 0x04, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x03, 0x03, 0x03, +0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x19, 0x06, 0x04, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x84, 0x04, 0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0, +0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A, 0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C, +0xEC, 0x24, 0x87, 0xF8, 0xE6, 0xBC, 0x02, 0x02, 0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00, +0x40, 0xCE, 0x79, 0x03, 0x78, 0x80, 0x16, 0xE6, 0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1, +0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9, 0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF, +0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF, 0x03, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30, +0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50, 0x20, 0x05, 0x0C, 0x74, 0x86, 0x25, 0x0C, 0xF8, +0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8, +0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80, 0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5, +0x0C, 0x24, 0x87, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD, +0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0, 0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x86, +0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C, 0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF, +0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F, 0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F, +0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x86, 0xA6, +0x81, 0x74, 0x02, 0x60, 0x06, 0xFF, 0x08, 0x76, 0xFF, 0xDF, 0xFB, 0x7F, 0x03, 0xE4, 0x78, 0x80, +0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81, 0x76, 0x30, 0x90, 0x87, 0xB5, 0x74, 0x01, 0x93, +0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89, 0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2, +0x8C, 0xD2, 0xAF, 0x22, 0x02, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81, +0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2, 0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE, +0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74, 0x86, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18, +0xBE, 0x02, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09, +0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE, 0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81, +0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x86, 0x2E, 0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02, +0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED, 0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09, +0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF, 0x24, 0x86, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F, +0x04, 0x90, 0x87, 0xB5, 0x93, 0xF6, 0x08, 0xEF, 0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3, +0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF, 0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4, +0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF, 0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x86, 0x2F, +0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x84, 0x4D, 0x50, 0x2E, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xBF, 0x02, +0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74, 0x86, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C, +0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19, 0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5, +0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74, 0x87, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01, +0x0F, 0x74, 0x86, 0x2F, 0xF8, 0xA6, 0x01, 0x08, 0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC, +0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8, 0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5, +0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF, 0xD3, 0x94, 0x02, 0x40, 0x03, 0x7F, 0xFF, 0x22, +0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6, 0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4, +0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30, 0xE2, 0x01, 0x0F, 0x02, 0x84, 0x4C, 0x8F, 0xF0, +0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80, 0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08, +0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x32, 0x50, 0x30, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6, +0x60, 0x27, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x25, 0x0E, 0x30, +0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x14, 0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x15, 0x54, 0xEC, +0x4E, 0xF6, 0xD2, 0xAF, 0xD2, 0xA9, 0x02, 0x84, 0x4D, 0x7F, 0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, +0xC2, 0xAF, 0x56, 0xC6, 0xD2, 0xAF, 0xD2, 0xA9, 0x54, 0x80, 0x4F, 0xFF, 0x22, 0x02, 0x86, 0xEB, +0x02, 0x84, 0xDD, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, +0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, +0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, +0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x87, 0xA8, 0xE4, 0x7E, +0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 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, +0xC3, 0xEF, 0x9B, 0xFF, 0xEE, 0x9A, 0xFE, 0xED, 0x99, 0xFD, 0xEC, 0x98, 0xFC, 0x22, 0xEF, 0x5B, +0xFF, 0xEE, 0x5A, 0xFE, 0xED, 0x59, 0xFD, 0xEC, 0x58, 0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE, 0x4A, +0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC, 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, +0xA3, 0xE0, 0xFF, 0x22, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0x22, +0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, +0xF0, 0x22, 0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, +0xA3, 0xA3, 0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, +0x68, 0x60, 0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0x41, 0x93, 0x22, 0x00, 0x41, 0x93, 0x23, 0x00, +0x41, 0x93, 0x28, 0x00, 0x00, 0x9A, 0x48, 0xB1, 0x91, 0xB8, 0xAD, 0x90, 0x93, 0x26, 0xEF, 0xF0, +0x7F, 0x02, 0xD1, 0x27, 0x90, 0x84, 0xC1, 0xE0, 0xFF, 0x90, 0x93, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, +0x90, 0x84, 0xC1, 0xF0, 0x22, 0x90, 0x02, 0x09, 0xE0, 0xF5, 0x5B, 0x12, 0x02, 0xF6, 0x25, 0x5B, +0x90, 0x84, 0xC6, 0x12, 0x8D, 0x73, 0x25, 0x5B, 0x90, 0x84, 0xC7, 0x12, 0x8C, 0x7F, 0x25, 0x5B, +0x90, 0x84, 0xC8, 0x12, 0x8F, 0xED, 0x25, 0x5B, 0x90, 0x84, 0xC9, 0xF0, 0x90, 0x00, 0x04, 0x12, +0x03, 0x0F, 0x25, 0x5B, 0x90, 0x84, 0xCA, 0xF0, 0x90, 0x00, 0x05, 0x12, 0x03, 0x0F, 0x25, 0x5B, +0x90, 0x84, 0xCB, 0xF0, 0x11, 0x1D, 0x25, 0x5B, 0x90, 0x84, 0xCC, 0xF0, 0x22, 0x90, 0x00, 0x06, +0x02, 0x03, 0x0F, 0x12, 0xC8, 0xCC, 0xFF, 0x54, 0x7F, 0x90, 0x85, 0xC5, 0xF0, 0xEF, 0xB1, 0x6B, +0xA3, 0xB1, 0x73, 0xFD, 0x54, 0xF0, 0xC4, 0x54, 0x0F, 0xFF, 0x90, 0x85, 0xC3, 0xE0, 0x54, 0xF0, +0x4F, 0xF1, 0xED, 0xFC, 0x54, 0x01, 0x25, 0xE0, 0xFF, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xFD, 0x4F, +0xF0, 0xEC, 0x54, 0x02, 0x25, 0xE0, 0xFF, 0x90, 0x92, 0x96, 0xE0, 0x54, 0xFB, 0x4F, 0xF0, 0xED, +0x54, 0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x12, 0x9F, 0xE5, 0x91, 0x7E, 0x90, 0x85, 0xC4, 0xF0, 0x11, +0x1D, 0x30, 0xE0, 0x4E, 0xC3, 0x13, 0x54, 0x07, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x85, 0xD8, 0x50, +0x04, 0xEF, 0xF0, 0x80, 0x26, 0x74, 0x03, 0xF0, 0x31, 0xAF, 0xE9, 0x24, 0x06, 0x12, 0xC9, 0x07, +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, 0x03, 0x3C, 0x31, 0xAF, 0x11, 0x1D, 0xC4, +0x54, 0x0F, 0xFF, 0xC3, 0x94, 0x04, 0x90, 0x85, 0xCD, 0x50, 0x05, 0x74, 0x04, 0xF0, 0x80, 0x02, +0xEF, 0xF0, 0x31, 0xAF, 0x90, 0x00, 0x04, 0x12, 0x03, 0x0F, 0xFD, 0x7F, 0x02, 0x12, 0x57, 0x82, +0x31, 0xAF, 0x12, 0x71, 0xCB, 0x12, 0xBA, 0x2E, 0xF0, 0x90, 0x85, 0xC5, 0x12, 0xC8, 0x84, 0x12, +0x9F, 0xE4, 0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x92, 0x04, 0x12, 0x87, 0x79, 0x90, 0x92, 0x03, +0xEF, 0xF0, 0x12, 0x87, 0x82, 0x89, 0x38, 0x00, 0x89, 0x3D, 0x01, 0x89, 0x42, 0x03, 0x89, 0x47, +0x04, 0x89, 0x4C, 0x12, 0x89, 0x51, 0x14, 0x89, 0x56, 0x20, 0x89, 0x5A, 0x24, 0x89, 0x5F, 0x25, +0x89, 0x64, 0x27, 0x89, 0x69, 0x40, 0x89, 0x6D, 0x42, 0x89, 0xA2, 0x47, 0x89, 0xA2, 0x49, 0x89, +0x76, 0x80, 0x89, 0x72, 0x81, 0x89, 0x7A, 0x82, 0x89, 0x7F, 0x83, 0x89, 0x84, 0x84, 0x89, 0x89, +0x88, 0x89, 0x8E, 0xC3, 0x00, 0x00, 0x89, 0x93, 0x31, 0xA3, 0x02, 0x87, 0xD5, 0x31, 0xA3, 0x02, +0x90, 0x02, 0x31, 0xA3, 0x02, 0x78, 0x94, 0x31, 0xA3, 0x02, 0x6B, 0x03, 0x31, 0xA3, 0x02, 0x97, +0xFE, 0x31, 0xA3, 0x02, 0xA0, 0x13, 0x31, 0xA3, 0x01, 0x23, 0x31, 0xA3, 0x02, 0x9C, 0x14, 0x31, +0xA3, 0x02, 0xA0, 0x22, 0x31, 0xA3, 0x02, 0xA0, 0x2A, 0x31, 0xA3, 0x80, 0x48, 0x31, 0xA3, 0x02, +0x4E, 0x29, 0x31, 0xA3, 0xA1, 0x87, 0x31, 0xA3, 0x81, 0x86, 0x31, 0xA3, 0x02, 0x7A, 0xFE, 0x31, +0xA3, 0x02, 0x6F, 0x63, 0x31, 0xA3, 0x02, 0x6F, 0xA4, 0x31, 0xA3, 0x02, 0x7B, 0xD0, 0x31, 0xA3, +0x02, 0x9A, 0x35, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x92, 0x03, 0xE0, 0x90, 0x01, +0xC2, 0xF0, 0x22, 0x90, 0x92, 0x04, 0x02, 0x87, 0x70, 0x24, 0x03, 0xFF, 0xE4, 0x33, 0xFE, 0x90, +0x92, 0x07, 0x02, 0x87, 0x70, 0x90, 0x92, 0x07, 0x12, 0x87, 0x79, 0x31, 0xAF, 0x12, 0x02, 0xF6, +0x54, 0x7F, 0xFD, 0xB1, 0x74, 0xFE, 0x54, 0x1F, 0x90, 0x92, 0x0B, 0xF0, 0xEE, 0x54, 0x80, 0xB1, +0x6B, 0x90, 0x92, 0x0A, 0x91, 0x7F, 0xFE, 0x54, 0x03, 0xFC, 0xEE, 0x54, 0x30, 0xC4, 0x54, 0x0F, +0x90, 0x92, 0x0D, 0x91, 0x7F, 0xFE, 0x54, 0x40, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x90, 0x92, 0x0C, +0xF0, 0xEE, 0x54, 0x80, 0xB1, 0x6B, 0xFF, 0x91, 0x80, 0xFB, 0x54, 0x08, 0x13, 0x13, 0x13, 0x54, +0x1F, 0x90, 0x92, 0x0F, 0xF0, 0xFA, 0xEB, 0x54, 0x04, 0x13, 0x13, 0x54, 0x3F, 0xA3, 0xF0, 0xEF, +0x54, 0x01, 0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0x71, 0x17, 0x54, 0x7F, 0x4F, 0xF0, 0x90, 0x92, +0x0C, 0xE0, 0x54, 0x01, 0xC4, 0x33, 0x33, 0x54, 0xC0, 0x71, 0x17, 0x54, 0xBF, 0x4F, 0xF0, 0xEA, +0x60, 0x02, 0x61, 0x16, 0x90, 0x92, 0x0B, 0xE0, 0x54, 0x1F, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0xB1, +0x7F, 0x54, 0xE0, 0x4F, 0xF0, 0xEC, 0x54, 0x03, 0x71, 0x17, 0x54, 0xFC, 0x4F, 0xF0, 0xEC, 0x54, +0x03, 0x25, 0xE0, 0x25, 0xE0, 0x71, 0x17, 0x54, 0xF3, 0x4F, 0xF0, 0x90, 0x92, 0x0A, 0xE0, 0x54, +0x01, 0xC4, 0x33, 0x54, 0xE0, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0xB1, 0x7F, 0x54, 0xDF, 0x4F, 0xF0, +0x90, 0x92, 0x0D, 0xE0, 0x54, 0x03, 0xC4, 0x54, 0xF0, 0x71, 0x17, 0x54, 0xCF, 0x4F, 0x12, 0xC8, +0xAD, 0xE0, 0x54, 0xFB, 0x12, 0xC8, 0xAD, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x92, 0x10, +0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x90, 0x92, 0x90, +0xE0, 0x60, 0x30, 0x31, 0xAF, 0xE9, 0x24, 0x03, 0x12, 0xC9, 0x07, 0x54, 0x1F, 0x12, 0x03, 0x3C, +0x90, 0x92, 0x0E, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x0E, 0xE0, 0xFF, 0xC3, 0x94, 0x04, 0x50, 0x13, +0xEF, 0x31, 0xA9, 0x8F, 0x82, 0x8E, 0x83, 0xE4, 0x12, 0x03, 0x4E, 0x90, 0x92, 0x0E, 0xE0, 0x04, +0xF0, 0x80, 0xE3, 0x90, 0x92, 0x8E, 0xE0, 0x54, 0x07, 0xFF, 0xBF, 0x05, 0x0A, 0xEC, 0xB4, 0x01, +0x06, 0x90, 0x92, 0x93, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x92, 0x0E, 0xF0, 0x90, 0x92, 0x0E, 0xE0, +0xFC, 0x31, 0xA9, 0x8F, 0x82, 0x8E, 0x83, 0x12, 0x03, 0x0F, 0xFF, 0xED, 0x12, 0xC8, 0x3F, 0xE5, +0x82, 0x2C, 0x12, 0xA8, 0x60, 0xEF, 0xF0, 0x90, 0x92, 0x0E, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x04, +0xDB, 0xAF, 0x05, 0x12, 0x17, 0x8E, 0x22, 0xFF, 0x75, 0xF0, 0x12, 0xED, 0x90, 0x89, 0x3F, 0x12, +0x05, 0x28, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xF1, 0x80, 0x20, 0xE6, 0x02, +0x81, 0x45, 0x90, 0x00, 0x8C, 0xE0, 0x90, 0x93, 0x19, 0xF0, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0x90, +0x93, 0x1A, 0xEF, 0xF0, 0x90, 0x00, 0x8E, 0xE0, 0x90, 0x93, 0x1B, 0xF0, 0x90, 0x93, 0x1A, 0xE0, +0x24, 0xFC, 0x60, 0x0F, 0x24, 0x03, 0x60, 0x02, 0x81, 0x3E, 0x90, 0x93, 0x19, 0xE0, 0xFF, 0xF1, +0x87, 0x81, 0x3E, 0x90, 0x93, 0x19, 0xE0, 0x24, 0xDC, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, +0xE0, 0xFB, 0xE4, 0xFD, 0xFF, 0x91, 0x77, 0x75, 0xF0, 0x12, 0x71, 0x1C, 0x13, 0x13, 0x54, 0x03, +0xFB, 0x0D, 0xE4, 0xFF, 0x91, 0x77, 0x75, 0xF0, 0x12, 0x71, 0x1C, 0xB1, 0x6B, 0xFB, 0x0D, 0xE4, +0xFF, 0x91, 0x77, 0x75, 0xF0, 0x12, 0x71, 0x1C, 0xC4, 0x54, 0x03, 0xFB, 0x0D, 0xE4, 0xFF, 0x91, +0x77, 0x12, 0xC8, 0x4D, 0xFB, 0xE4, 0xFD, 0x0F, 0x91, 0x77, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x3D, +0x12, 0x05, 0x28, 0x91, 0x74, 0x75, 0xF0, 0x12, 0xB1, 0x7F, 0xC4, 0x13, 0x54, 0x01, 0xFB, 0x0D, +0x7F, 0x01, 0x91, 0x77, 0x75, 0xF0, 0x12, 0xB1, 0x7F, 0x54, 0x1F, 0x91, 0x75, 0x12, 0xC8, 0x3F, +0xE0, 0xFB, 0xE4, 0xFD, 0x0F, 0x91, 0x77, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x01, 0xF5, 0x82, 0xE4, +0x34, 0x82, 0x91, 0x72, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, +0x72, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x03, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x72, 0x75, 0xF0, +0x08, 0xA4, 0x24, 0x04, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFB, 0xE4, 0xFD, 0x0F, +0x91, 0x77, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0x05, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x72, 0x75, +0xF0, 0x08, 0xA4, 0x24, 0x06, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0x91, 0x72, 0x75, 0xF0, 0x08, 0xA4, +0x24, 0x07, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE0, 0xFB, 0x0D, 0x91, 0x4A, 0xF1, 0x80, +0x30, 0xE0, 0x02, 0xF1, 0xFB, 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, 0x0C, 0x74, 0xFC, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, 0xEB, +0xF0, 0x22, 0xF5, 0x83, 0xE0, 0xFB, 0x0D, 0x91, 0x4A, 0x90, 0x93, 0x19, 0xE0, 0x22, 0x4F, 0xF0, +0x90, 0x00, 0x02, 0x02, 0x03, 0x0F, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xC8, 0xCC, +0x20, 0xE0, 0x05, 0x12, 0xB6, 0x52, 0xA1, 0x62, 0x31, 0xAF, 0x12, 0xC8, 0x99, 0x90, 0x86, 0x75, +0xD1, 0x13, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0xF1, 0x5C, 0x12, 0xC8, 0xE7, 0xD1, 0x21, 0x54, +0x10, 0xFD, 0xEF, 0x54, 0xEF, 0xF1, 0x5C, 0x12, 0xC8, 0xEF, 0xD1, 0x21, 0x54, 0x40, 0xFD, 0xEF, +0x54, 0xBF, 0xF1, 0x5C, 0x12, 0xC8, 0xF7, 0xB1, 0x73, 0x54, 0x80, 0xFF, 0x90, 0x86, 0x76, 0xE0, +0x54, 0x7F, 0x4F, 0xF0, 0x12, 0xC8, 0xFF, 0x30, 0xE0, 0x07, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x04, +0xF0, 0x31, 0xAF, 0x12, 0x02, 0xF6, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x07, 0x90, 0x06, +0x90, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0x84, 0xC5, 0xE0, 0xB4, 0x02, 0x05, 0xB1, 0x67, 0x20, 0xE0, +0x3E, 0xB1, 0x74, 0x54, 0x7F, 0xFF, 0x90, 0x86, 0x76, 0xE0, 0x54, 0x80, 0x91, 0x7E, 0x90, 0x86, +0x77, 0xF1, 0xED, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x86, 0x78, 0x12, 0xC8, 0x91, 0x54, 0xFE, 0xFF, +0xEE, 0x54, 0x01, 0x4F, 0xF0, 0x90, 0x86, 0x76, 0xE0, 0x54, 0x7F, 0xFF, 0x90, 0x86, 0x75, 0xE0, +0xFE, 0xC4, 0x13, 0x54, 0x07, 0x7D, 0x00, 0x20, 0xE0, 0x02, 0x7D, 0x01, 0x12, 0x54, 0x9F, 0x90, +0x84, 0xC5, 0xE0, 0xB4, 0x01, 0x07, 0x90, 0xFE, 0x10, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x87, 0x4A, +0x74, 0x05, 0xF0, 0x7E, 0x00, 0x7F, 0x08, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x87, 0x79, 0x95, 0x12, +0x06, 0xDE, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x86, 0x76, 0xE0, 0xC4, 0x13, 0x13, 0x13, 0x54, +0x01, 0x22, 0x4F, 0xF0, 0x90, 0x00, 0x01, 0x02, 0x03, 0x0F, 0x75, 0xF0, 0x12, 0xE5, 0x6E, 0x90, +0x89, 0x3E, 0x12, 0x05, 0x28, 0xE0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0xC8, +0x99, 0x90, 0x86, 0x72, 0xD1, 0x13, 0x54, 0x04, 0xFD, 0xEF, 0x54, 0xFB, 0xF1, 0x54, 0x12, 0xC8, +0xE7, 0xD1, 0x21, 0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0xF1, 0x54, 0x12, 0xC8, 0xEF, 0xD1, 0x21, +0x54, 0x40, 0xFD, 0xEF, 0x54, 0xBF, 0xF1, 0x54, 0x12, 0xC8, 0xF7, 0x91, 0x7F, 0x54, 0x01, 0xFF, +0x90, 0x86, 0x74, 0xE0, 0x54, 0xFE, 0xB1, 0x72, 0xFF, 0x54, 0x01, 0xFE, 0x90, 0x86, 0x73, 0x12, +0xC8, 0x91, 0x54, 0x04, 0xFF, 0xEE, 0x54, 0xFB, 0x4F, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0xC3, 0x13, +0x54, 0x01, 0xFF, 0x12, 0x7C, 0x72, 0xF1, 0xF4, 0x54, 0x01, 0xFF, 0x12, 0x7C, 0x7E, 0xF1, 0xF4, +0x13, 0x54, 0x01, 0xFF, 0x12, 0x66, 0xDA, 0x90, 0x86, 0x72, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x01, +0xFF, 0x12, 0xC1, 0x11, 0x90, 0x86, 0x72, 0xE0, 0x54, 0x01, 0xFF, 0x12, 0xB5, 0xE8, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, +0x4F, 0xFF, 0xF0, 0x12, 0x02, 0xF6, 0xFE, 0x22, 0x8F, 0x6E, 0x8D, 0x6F, 0xEF, 0xF1, 0x73, 0xE0, +0xF5, 0x70, 0x54, 0x7F, 0xF5, 0x71, 0xE5, 0x70, 0x54, 0x80, 0xF5, 0x73, 0x75, 0xF0, 0x12, 0xEF, +0x12, 0xC8, 0x50, 0xF5, 0x75, 0x75, 0xF0, 0x12, 0xEF, 0x71, 0x1C, 0xC4, 0x54, 0x03, 0xF5, 0x76, +0xF1, 0xE1, 0x74, 0xFF, 0xF0, 0x12, 0xAB, 0x01, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x70, 0x45, +0x73, 0xFF, 0x12, 0xAA, 0xF5, 0xEF, 0xF0, 0xE5, 0x6E, 0x12, 0x91, 0xDA, 0xE0, 0x54, 0x03, 0xF5, +0x74, 0x74, 0x4C, 0x25, 0x6E, 0x12, 0xAF, 0xD3, 0xE5, 0x74, 0xF0, 0xE5, 0x71, 0x65, 0x75, 0x70, +0x40, 0xB1, 0x7A, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x0C, 0xE5, 0x73, 0x70, 0x08, 0xE5, 0x71, +0x44, 0x80, 0xF5, 0x70, 0xE1, 0x26, 0x12, 0xAB, 0x01, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0xAB, +0x15, 0x12, 0xC8, 0xDE, 0xF1, 0xD6, 0xE5, 0x6E, 0xF0, 0xE4, 0x90, 0x92, 0x43, 0x12, 0x96, 0x3F, +0x7B, 0x01, 0xFA, 0x7D, 0x02, 0x7F, 0x04, 0x12, 0x96, 0x87, 0x7D, 0x07, 0xAF, 0x6E, 0x02, 0xBE, +0x04, 0xE5, 0x71, 0xC3, 0x95, 0x75, 0x50, 0x56, 0xAB, 0x6E, 0xAD, 0x75, 0xAF, 0x71, 0x12, 0x72, +0xEA, 0x8F, 0x72, 0x85, 0x72, 0x70, 0xB1, 0x7A, 0xC4, 0x13, 0x54, 0x01, 0xFF, 0x90, 0x92, 0x43, +0xF1, 0xD5, 0xE5, 0x72, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x71, 0xF0, 0xE5, 0x73, 0xB1, 0x6B, +0x12, 0x97, 0xD4, 0xE4, 0xFB, 0xFA, 0x12, 0xC9, 0x1E, 0xE5, 0x71, 0xC3, 0x94, 0x0C, 0x40, 0x26, +0xB1, 0x7A, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0, 0x1D, 0xE5, 0x6F, 0x60, 0x19, 0xE5, 0x73, 0x70, +0x15, 0xE5, 0x71, 0x44, 0x80, 0xF5, 0x70, 0xF1, 0xE1, 0xE5, 0x72, 0xF0, 0x80, 0x08, 0x12, 0xAA, +0xF5, 0xE5, 0x75, 0xF0, 0xF5, 0x70, 0xF1, 0xDA, 0xE5, 0x70, 0xF0, 0xF1, 0xE1, 0xE0, 0xFF, 0x12, +0xC8, 0xC5, 0xEF, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x74, 0x12, 0xAF, 0xCB, 0xF0, 0x7B, 0x01, +0x7A, 0x00, 0x12, 0xC9, 0x1E, 0x90, 0x91, 0x0B, 0xE5, 0x74, 0xF0, 0xAB, 0x6F, 0xAD, 0x70, 0xAF, +0x6E, 0x02, 0x27, 0x3D, 0x4D, 0xFF, 0x90, 0x86, 0x72, 0xF0, 0xEE, 0x22, 0x4D, 0xFF, 0x90, 0x86, +0x75, 0xF0, 0xEE, 0x22, 0x74, 0xBC, 0x25, 0x78, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE4, +0xF0, 0xE5, 0x78, 0xC4, 0x54, 0xF0, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, +0x7F, 0x8F, 0x12, 0x7B, 0x51, 0xEF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, +0x24, 0xEF, 0xF0, 0xF1, 0x80, 0x30, 0xE6, 0x38, 0x7F, 0x8D, 0x12, 0x7B, 0x51, 0xEF, 0x64, 0x01, +0x70, 0x2E, 0x90, 0x93, 0x25, 0xF0, 0x90, 0x93, 0x25, 0xE0, 0xFD, 0x90, 0x93, 0x24, 0xE0, 0xF1, +0x73, 0xE5, 0x82, 0x2D, 0x12, 0xA8, 0x60, 0xE0, 0xFB, 0xE4, 0xFF, 0x91, 0x4A, 0x90, 0x93, 0x25, +0xE0, 0x04, 0xF0, 0xE0, 0xC3, 0x94, 0x10, 0x40, 0xDD, 0xF1, 0x80, 0x30, 0xE0, 0x02, 0xF1, 0xFB, +0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x3F, 0xE4, 0xF0, 0xA3, +0x22, 0x74, 0xD7, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0xF0, 0x90, 0x00, +0x03, 0x02, 0x03, 0x0F, 0x90, 0x86, 0x72, 0xE0, 0x13, 0x13, 0x22, 0xE4, 0xFD, 0x7F, 0x8D, 0x02, +0x7B, 0x3E, 0x8B, 0x5B, 0x8A, 0x5C, 0x89, 0x5D, 0x90, 0x92, 0x8A, 0xE0, 0x70, 0x0C, 0x12, 0xC8, +0xFF, 0x30, 0xE0, 0x06, 0x90, 0x92, 0x90, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x8C, 0xE0, 0x70, 0x0F, +0x31, 0xC3, 0xC4, 0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x06, 0x90, 0x92, 0x91, 0x74, 0x01, 0xF0, 0xAB, +0x5B, 0xAA, 0x5C, 0xA9, 0x5D, 0x12, 0x8D, 0x74, 0xFF, 0xF5, 0x5F, 0x12, 0x02, 0xF6, 0xFE, 0xC3, +0x13, 0x30, 0xE0, 0x07, 0x12, 0x8C, 0x80, 0xF5, 0x60, 0x80, 0x02, 0x8F, 0x60, 0x85, 0x5F, 0x5E, +0xE5, 0x5E, 0xD3, 0x95, 0x60, 0x50, 0x28, 0x31, 0xC3, 0x54, 0x01, 0xFD, 0xAF, 0x5E, 0x12, 0x6E, +0x5F, 0xAF, 0x5E, 0x12, 0x77, 0x39, 0xEF, 0xAF, 0x5E, 0x70, 0x04, 0x11, 0x9A, 0x80, 0x02, 0xF1, +0xEA, 0x90, 0x92, 0x91, 0xE0, 0x60, 0x04, 0xAF, 0x5E, 0x11, 0x9A, 0x05, 0x5E, 0x80, 0xD1, 0xE5, +0x5F, 0x70, 0x16, 0xFF, 0x12, 0x77, 0x39, 0xEF, 0x70, 0x0F, 0x12, 0xB3, 0xE4, 0x12, 0x79, 0x61, +0x12, 0xC9, 0x25, 0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0x22, 0x7D, 0x01, 0xD3, 0x10, 0xAF, 0x01, +0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x07, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x7D, 0x44, 0x7F, 0x6F, 0x11, +0xDD, 0x11, 0xE8, 0x90, 0x92, 0x08, 0xE0, 0x90, 0x92, 0x07, 0xB4, 0x01, 0x09, 0xE0, 0x31, 0xDA, +0xE0, 0x44, 0x04, 0xF0, 0x80, 0x07, 0xE0, 0x31, 0xDA, 0xE0, 0x54, 0xFB, 0xF0, 0xE4, 0xFD, 0xFF, +0x11, 0xDD, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0xB3, 0xE4, 0xE4, 0xFD, 0xFF, 0x90, 0x05, 0x22, +0xEF, 0xF0, 0x90, 0x92, 0x81, 0xED, 0xF0, 0x22, 0xE4, 0x90, 0x93, 0x16, 0xF0, 0xA3, 0xF0, 0x90, +0x05, 0x22, 0xE0, 0x90, 0x93, 0x18, 0xF0, 0x7D, 0x47, 0x7F, 0xFF, 0x11, 0xDD, 0x90, 0x05, 0xF8, +0xE0, 0x70, 0x13, 0xA3, 0xE0, 0x70, 0x0F, 0xA3, 0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0x31, +0xBB, 0x11, 0xDD, 0x7F, 0x01, 0x22, 0xD3, 0x90, 0x93, 0x17, 0xE0, 0x94, 0xE8, 0x90, 0x93, 0x16, +0xE0, 0x94, 0x03, 0x40, 0x0E, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x20, 0xF0, 0x31, 0xBB, 0x11, 0xDD, +0x7F, 0x00, 0x22, 0x7F, 0x32, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x93, 0x16, 0xE4, 0x75, 0xF0, +0x01, 0x12, 0x07, 0x0A, 0x80, 0xB7, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x76, +0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x84, 0xC3, 0xE0, 0x04, 0xF0, 0x90, 0x04, 0x1D, 0xE0, 0x60, +0x2D, 0x90, 0x05, 0x22, 0xE0, 0x90, 0x92, 0x7A, 0xF0, 0x7D, 0x26, 0x7F, 0xFF, 0x11, 0xDD, 0x11, +0xE8, 0xEF, 0x64, 0x01, 0x70, 0x0B, 0x31, 0xCC, 0xFB, 0x7D, 0x01, 0x12, 0x3A, 0xC2, 0x12, 0xC8, +0x22, 0x90, 0x92, 0x7A, 0xE0, 0xFF, 0x7D, 0x27, 0x11, 0xDD, 0x31, 0xB3, 0x80, 0x13, 0x31, 0xB3, +0x31, 0xCC, 0xFB, 0x90, 0x93, 0x15, 0x74, 0x0A, 0xF0, 0x7D, 0x01, 0x12, 0xBF, 0x83, 0x12, 0xC8, +0x22, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x12, 0xC6, 0xA8, 0x74, 0x01, 0xF0, 0xFF, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x90, 0x92, 0x76, 0xE0, 0xFF, 0x02, 0x5C, 0xA3, 0x90, 0x93, 0x18, 0xE0, 0xFF, +0x7D, 0x48, 0x22, 0xAB, 0x5B, 0xAA, 0x5C, 0xA9, 0x5D, 0x02, 0x02, 0xF6, 0x90, 0x84, 0xC8, 0xE0, +0xFF, 0x90, 0x92, 0x77, 0xE0, 0x22, 0xE0, 0xFD, 0xE5, 0x78, 0xC4, 0x54, 0xF0, 0x24, 0x05, 0xF5, +0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0x22, 0x90, 0x04, 0x85, 0xE0, 0xF5, 0x6B, 0x90, 0x92, 0xD6, +0xE0, 0x04, 0xF0, 0xE4, 0xF5, 0x62, 0x90, 0x85, 0xBB, 0xE0, 0xFF, 0xE5, 0x62, 0xC3, 0x9F, 0x40, +0x02, 0xC1, 0x2B, 0xE5, 0x62, 0x12, 0x8F, 0x73, 0xE0, 0xF5, 0x6D, 0x12, 0xC8, 0xB9, 0xE0, 0x65, +0x6D, 0x60, 0x16, 0x90, 0x8A, 0x71, 0xE5, 0x6D, 0xF0, 0xE4, 0xA3, 0xF0, 0xAB, 0x62, 0xFD, 0xFF, +0x12, 0x52, 0xC3, 0x12, 0xC8, 0xB9, 0xE5, 0x6D, 0xF0, 0x90, 0x04, 0xA0, 0xE0, 0x64, 0x01, 0x70, +0x4E, 0xA3, 0xE0, 0x65, 0x62, 0x70, 0x48, 0xA3, 0xE0, 0xF5, 0x63, 0xA3, 0xE0, 0x90, 0x92, 0x38, +0xF0, 0xE5, 0x62, 0x12, 0x8F, 0x73, 0xE0, 0x65, 0x63, 0x70, 0x02, 0xC1, 0x27, 0xE5, 0x62, 0x12, +0x8F, 0x73, 0xE5, 0x63, 0xF0, 0xE5, 0x62, 0x31, 0xDA, 0xE0, 0x54, 0xFC, 0xFF, 0x90, 0x92, 0x38, +0xE0, 0x54, 0x03, 0x4F, 0xFF, 0xE5, 0x62, 0x31, 0xDA, 0xEF, 0xF0, 0x90, 0x8A, 0x71, 0xE5, 0x63, +0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0xAB, 0x62, 0xE4, 0xFD, 0xFF, 0x12, 0x52, 0xC3, 0xC1, 0x27, 0xAF, +0x62, 0x12, 0x77, 0x39, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0x8B, 0x1C, 0x12, 0x8D, 0x6B, 0xFD, +0xF1, 0xB5, 0xED, 0xF0, 0x90, 0x92, 0x41, 0x12, 0x8F, 0xD5, 0xE5, 0x62, 0xF0, 0x12, 0xA9, 0x91, +0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x5C, 0xFE, 0xEF, 0x5D, +0xFF, 0x90, 0x92, 0x45, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x7B, 0x02, 0x7A, 0x00, 0xE4, 0xFD, 0x7F, +0x01, 0xD1, 0x87, 0x12, 0xAC, 0x0E, 0xFF, 0xF1, 0xCA, 0x12, 0x05, 0x28, 0xE0, 0xFD, 0xE5, 0x62, +0x12, 0xC8, 0x76, 0x54, 0x80, 0xFB, 0xF1, 0xB5, 0xEB, 0xF0, 0x12, 0xC8, 0xC5, 0xED, 0xF0, 0x90, +0x92, 0x3F, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x45, 0xF0, 0xA3, 0xF0, 0x7B, 0x03, +0xFA, 0xFD, 0x7F, 0x01, 0xD1, 0x87, 0xAF, 0x62, 0x12, 0x77, 0x39, 0xEF, 0x70, 0x02, 0xC1, 0x27, +0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0x8B, 0x1C, 0x12, 0x8D, 0x6B, 0x30, 0xE0, 0x02, 0xC1, 0x27, +0xE5, 0x62, 0x12, 0xA9, 0x91, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, +0xEE, 0x5C, 0xFE, 0xEF, 0x5D, 0x4E, 0x60, 0x02, 0xC1, 0x27, 0x12, 0xAC, 0x0E, 0x4E, 0x70, 0x0A, +0xF1, 0xCA, 0x12, 0x05, 0x28, 0xE0, 0x70, 0x02, 0xC1, 0x27, 0xE5, 0x62, 0x75, 0xF0, 0x12, 0xA4, +0x24, 0x44, 0xF9, 0x74, 0x89, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x90, 0x92, 0x33, 0x12, 0x87, 0x79, +0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0x12, 0xC9, 0x16, 0x12, 0x03, 0xED, 0x2F, 0xFF, 0xF1, 0xA3, +0x2F, 0xFF, 0xF1, 0xA9, 0x2F, 0xFF, 0xF1, 0xAF, 0x2F, 0xF5, 0x6C, 0x75, 0xF0, 0x12, 0xE5, 0x62, +0x90, 0x89, 0x40, 0x12, 0x05, 0x28, 0xE0, 0xF5, 0x68, 0xA3, 0xE0, 0xF5, 0x69, 0xF1, 0xCA, 0x12, +0x05, 0x28, 0xE0, 0xFF, 0x90, 0x92, 0x36, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xE5, 0x62, 0x12, 0x8F, +0x73, 0xE0, 0xF5, 0x63, 0x54, 0x80, 0xF5, 0x65, 0xE5, 0x63, 0x54, 0x7F, 0xF5, 0x64, 0x12, 0xC8, +0xD5, 0xD1, 0xFD, 0x12, 0xC9, 0x16, 0x90, 0x92, 0x41, 0xF1, 0x01, 0xF1, 0xA3, 0xFF, 0x90, 0x92, +0x43, 0xF1, 0x01, 0xF1, 0xA9, 0xFF, 0x90, 0x92, 0x45, 0xF1, 0x01, 0x7B, 0x01, 0xF1, 0x9B, 0x90, +0x92, 0x33, 0x12, 0x87, 0x70, 0xF1, 0xAF, 0xD1, 0xFD, 0x90, 0x92, 0x36, 0x12, 0xC8, 0xDE, 0xF0, +0xA3, 0xEF, 0xF0, 0xA3, 0x12, 0xC9, 0x0E, 0xA3, 0xE4, 0xF0, 0xA3, 0xE5, 0x63, 0xF0, 0x7B, 0x02, +0xF1, 0x9B, 0x74, 0x7C, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0xE0, 0xC3, 0x94, +0x05, 0x40, 0x02, 0xC1, 0x0C, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x12, 0xC8, 0x50, 0xFF, 0xE5, 0x64, +0xD3, 0x9F, 0x40, 0x08, 0x8F, 0x64, 0xE5, 0x64, 0x45, 0x65, 0xF5, 0x63, 0xE5, 0x64, 0x90, 0x82, +0xE1, 0x93, 0xF5, 0x6A, 0xE5, 0x65, 0x60, 0x04, 0x05, 0x6A, 0x05, 0x6A, 0x90, 0x04, 0x8C, 0xE0, +0x64, 0x01, 0x70, 0x28, 0xE5, 0x64, 0xC3, 0x94, 0x0C, 0x40, 0x21, 0x74, 0x84, 0x25, 0x64, 0xF5, +0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFF, 0x54, 0x7F, 0xFE, 0xEF, 0x30, 0xE7, 0x06, 0xE5, +0x6A, 0x2E, 0xFF, 0x80, 0x05, 0xC3, 0xE5, 0x6A, 0x9E, 0xFF, 0x8F, 0x6A, 0xE5, 0x6A, 0xD3, 0x94, +0x1A, 0xAF, 0x6A, 0x40, 0x02, 0x7F, 0x1A, 0x8F, 0x6A, 0xD1, 0x31, 0x7B, 0x03, 0xFA, 0xF1, 0x9D, +0xE5, 0x63, 0x90, 0x83, 0x59, 0x93, 0xFF, 0xD3, 0x90, 0x92, 0x37, 0xE0, 0x9F, 0x90, 0x92, 0x36, +0xE0, 0x94, 0x00, 0x40, 0x02, 0x80, 0x73, 0xC3, 0xE5, 0x69, 0x94, 0x0A, 0xE5, 0x68, 0x94, 0x00, +0x40, 0x02, 0xA1, 0x5A, 0xD1, 0x75, 0xE0, 0xC3, 0x94, 0x01, 0x40, 0x05, 0xD1, 0x75, 0xE0, 0x14, +0xF0, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0xF1, 0xAF, 0xFF, 0x90, 0x92, 0x37, 0xE0, 0x2F, 0xFF, +0x90, 0x92, 0x36, 0xE0, 0x35, 0xF0, 0xFE, 0xF1, 0xA9, 0x2F, 0xFF, 0xEE, 0x35, 0xF0, 0xFE, 0xF1, +0xA3, 0x2F, 0xFD, 0xEE, 0x35, 0xF0, 0xFC, 0xE5, 0x68, 0xC3, 0x13, 0xFE, 0xE5, 0x69, 0x13, 0xFF, +0xD3, 0xED, 0x9F, 0xEC, 0x9E, 0x40, 0x28, 0xE5, 0x62, 0x94, 0x05, 0x50, 0x05, 0xD1, 0x75, 0x74, +0x03, 0xF0, 0x90, 0x92, 0x3F, 0x12, 0xC9, 0x0E, 0xE5, 0x68, 0xC3, 0x13, 0xA3, 0xF0, 0xE5, 0x69, +0x13, 0xA3, 0xD1, 0x47, 0xF1, 0xD3, 0x7B, 0x01, 0xD1, 0x81, 0x12, 0xAA, 0x22, 0xC1, 0x0C, 0x12, +0xC8, 0xD5, 0x65, 0x6C, 0x70, 0x02, 0xE5, 0xF0, 0x70, 0x50, 0x90, 0x92, 0x3F, 0xF0, 0xA3, 0xE5, +0x6C, 0xF0, 0xC3, 0x13, 0xFF, 0xA3, 0xE4, 0xF0, 0xA3, 0xEF, 0xD1, 0x47, 0xF1, 0xD3, 0x7B, 0x02, +0xD1, 0x81, 0xE5, 0x62, 0xC3, 0x94, 0x05, 0x50, 0x0E, 0xD1, 0x75, 0xE0, 0xD3, 0x94, 0x00, 0x40, +0x06, 0xD1, 0x2C, 0x7B, 0x03, 0x80, 0x0B, 0xE5, 0x6C, 0xC3, 0x94, 0x03, 0x50, 0x10, 0xD1, 0x2C, +0x7B, 0x04, 0xFA, 0xD1, 0x83, 0x7D, 0x06, 0xAF, 0x62, 0x12, 0xBE, 0x04, 0xC1, 0x27, 0xE4, 0xFD, +0xAF, 0x62, 0x12, 0x8E, 0x28, 0x12, 0xBE, 0x00, 0xC1, 0x0C, 0xD1, 0x2C, 0x7B, 0x08, 0xFA, 0xD1, +0x83, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0x65, 0xC2, 0xC1, 0x0C, 0xD1, 0x75, 0xE4, 0xF0, 0x90, 0x92, +0x3D, 0x74, 0x02, 0xF0, 0xAB, 0x6A, 0xAD, 0x62, 0xAF, 0x69, 0xAE, 0x68, 0x12, 0xAB, 0x23, 0x8E, +0x66, 0x8F, 0x67, 0x12, 0xC8, 0x68, 0xC3, 0x74, 0x01, 0x93, 0x95, 0x67, 0xE4, 0x93, 0x95, 0x66, +0x50, 0x18, 0xD1, 0xF1, 0xE4, 0xF0, 0x7D, 0x01, 0xAF, 0x62, 0x12, 0x8E, 0x28, 0x12, 0xC7, 0xD4, +0xE4, 0x90, 0x92, 0x43, 0xD1, 0x3F, 0x7B, 0x01, 0x80, 0x22, 0xF1, 0x93, 0xC3, 0xE5, 0x67, 0x9F, +0xE5, 0x66, 0x94, 0x00, 0x50, 0x1B, 0xD1, 0xF1, 0xE4, 0xF0, 0x12, 0xAA, 0x22, 0x12, 0xC7, 0xEF, +0xF1, 0x93, 0x12, 0xC8, 0xC5, 0xEF, 0xF0, 0xE4, 0xD1, 0x3E, 0x7B, 0x02, 0xFA, 0xF1, 0xBC, 0x80, +0x4B, 0x12, 0xBE, 0x00, 0x12, 0xC7, 0xD4, 0xF1, 0x93, 0xF1, 0xB5, 0xEF, 0xF0, 0xD1, 0xF1, 0xF1, +0xD3, 0x7B, 0x03, 0x7A, 0x00, 0xF1, 0xBC, 0xD1, 0xF1, 0xE0, 0x04, 0xF0, 0xE5, 0x64, 0x90, 0x83, +0x6D, 0x93, 0xFF, 0xD1, 0xF1, 0xE0, 0xC3, 0x9F, 0x40, 0x22, 0xD1, 0xF1, 0xE4, 0xF0, 0xF1, 0x93, +0x12, 0xC8, 0x68, 0x74, 0x01, 0x93, 0x2F, 0xFF, 0xE4, 0x93, 0x34, 0x00, 0xC3, 0x13, 0xFE, 0xEF, +0x13, 0xFF, 0xE5, 0x62, 0x12, 0xAB, 0x17, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xF5, 0x6C, 0xFD, +0xAF, 0x62, 0x12, 0x65, 0xC2, 0xE4, 0x90, 0x92, 0x3F, 0xF0, 0xD1, 0x3A, 0xA3, 0xF0, 0x7B, 0x01, +0xFA, 0x7D, 0xFF, 0x7F, 0x01, 0xD1, 0x87, 0x05, 0x62, 0x21, 0xF6, 0x22, 0x90, 0x92, 0xD6, 0xE0, +0xFF, 0x90, 0x92, 0x3F, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xF0, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0x90, 0x00, +0x06, 0x12, 0x04, 0x18, 0xFF, 0xAE, 0xF0, 0x90, 0x00, 0x08, 0x12, 0x04, 0x18, 0x2F, 0xFF, 0xE5, +0xF0, 0x3E, 0xFE, 0x90, 0x00, 0x04, 0x12, 0x04, 0x18, 0x2F, 0xFF, 0xEE, 0x35, 0xF0, 0x90, 0x92, +0x43, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0xE7, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, +0x22, 0x7A, 0x00, 0x7D, 0x03, 0x7F, 0x01, 0x90, 0x01, 0xC6, 0xE0, 0xFE, 0x64, 0x80, 0x70, 0x60, +0x90, 0x92, 0x49, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xEB, 0xA3, 0xF0, 0xEA, 0xA3, 0xF0, 0x90, 0x92, +0x3F, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x4D, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x41, 0xE0, +0xFC, 0xA3, 0xE0, 0x90, 0x92, 0x4F, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x43, 0xE0, 0xFC, 0xA3, +0xE0, 0x90, 0x92, 0x51, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x45, 0xE0, 0xFC, 0xA3, 0xE0, 0x90, +0x92, 0x53, 0xF0, 0xEC, 0xA3, 0xF0, 0x90, 0x92, 0x47, 0x74, 0xFE, 0xF0, 0x90, 0x92, 0x55, 0x74, +0x0C, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x47, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x12, 0x87, 0xBB, +0x22, 0x74, 0xAC, 0x25, 0x62, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, 0xFF, 0x90, 0x92, +0x3F, 0xE5, 0xF0, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x8D, 0x78, 0xEF, 0x30, 0xE6, 0x17, 0x12, 0x8F, +0x71, 0x31, 0xD6, 0xF1, 0xC2, 0xE4, 0xFB, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0x12, 0x8F, 0x64, 0xF1, +0x8C, 0x74, 0x01, 0x80, 0x5E, 0xF1, 0xDE, 0xE0, 0x04, 0xF0, 0xF1, 0xDE, 0xE0, 0x64, 0x02, 0x70, +0x27, 0x74, 0xD7, 0x25, 0x78, 0x12, 0x8F, 0xE5, 0xE0, 0xFD, 0xF4, 0x60, 0x02, 0x80, 0x05, 0x12, +0x8F, 0x71, 0xE0, 0xFD, 0x31, 0xD8, 0xF1, 0xC2, 0x7B, 0x01, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0x12, +0x8F, 0x71, 0xF1, 0x8C, 0x74, 0x02, 0x80, 0x2B, 0xF1, 0xDE, 0xE0, 0xD3, 0x94, 0x03, 0x40, 0x0E, +0xAF, 0x78, 0x12, 0x6D, 0x94, 0x12, 0x8F, 0x64, 0xF1, 0x8C, 0x74, 0x03, 0x80, 0x15, 0x12, 0x8F, +0x71, 0x31, 0xD6, 0xF1, 0xC2, 0x7B, 0x01, 0xAF, 0x78, 0x12, 0x27, 0x3D, 0x12, 0x8F, 0x71, 0xF1, +0x8C, 0x74, 0x02, 0xF0, 0xAB, 0x78, 0xE4, 0xFD, 0xFF, 0x02, 0x52, 0xC3, 0xE0, 0x90, 0x8A, 0x71, +0xF0, 0xA3, 0x22, 0xE5, 0x64, 0x90, 0x83, 0x1D, 0x93, 0xFF, 0x22, 0x7A, 0x00, 0x7D, 0x01, 0x7F, +0x01, 0xC1, 0x87, 0x90, 0x00, 0x04, 0x02, 0x04, 0x18, 0x90, 0x00, 0x06, 0x02, 0x04, 0x18, 0x90, +0x00, 0x08, 0x02, 0x04, 0x18, 0x90, 0x92, 0x43, 0xE4, 0xF0, 0xA3, 0x22, 0x7D, 0x05, 0x7F, 0x01, +0xC1, 0x87, 0xE0, 0x54, 0x03, 0x90, 0x91, 0x0B, 0xF0, 0x22, 0x75, 0xF0, 0x12, 0xE5, 0x62, 0x90, +0x89, 0x42, 0x22, 0xE0, 0xFF, 0x90, 0x92, 0x45, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x74, 0xBC, +0x25, 0x78, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0x22, 0xE4, 0xFD, 0x01, 0x9C, 0x7D, 0x20, +0x7F, 0xFF, 0x11, 0xDD, 0x12, 0xB5, 0xB4, 0x90, 0x85, 0xBF, 0x74, 0x02, 0xF0, 0x22, 0x12, 0x02, +0xF6, 0xFF, 0x90, 0x92, 0x83, 0xF0, 0xBF, 0x01, 0x07, 0x11, 0x11, 0xE4, 0x90, 0x92, 0x83, 0xF0, +0x22, 0x11, 0xC1, 0x7F, 0xF5, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x06, 0x90, 0x92, 0x07, +0xE0, 0xA3, 0xF0, 0x11, 0xC1, 0x7F, 0xF6, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, +0x92, 0x07, 0xE0, 0x90, 0x92, 0x09, 0xF0, 0x11, 0xC1, 0x7F, 0xF4, 0x7E, 0x01, 0x12, 0x64, 0x37, +0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x0A, 0xF0, 0x11, 0xC1, 0x7F, 0xF3, 0x7E, +0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x11, +0xC1, 0x7F, 0xF2, 0x7E, 0x01, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x07, 0xE0, 0x90, +0x92, 0x0C, 0xF0, 0x90, 0x92, 0x08, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, +0x90, 0x92, 0x10, 0xF0, 0x90, 0x92, 0x0C, 0xE0, 0x90, 0x92, 0x11, 0xF0, 0x90, 0x92, 0x12, 0x74, +0x12, 0xF0, 0x90, 0x92, 0x20, 0x74, 0x05, 0xF0, 0x90, 0x92, 0x14, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, +0xA3, 0xEB, 0xF0, 0x90, 0x92, 0x10, 0xE0, 0x90, 0x92, 0x17, 0xF0, 0x90, 0x92, 0x11, 0xE0, 0x90, +0x92, 0x18, 0xF0, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x12, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x02, 0x87, +0xBB, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x07, 0x22, 0x31, 0xAD, 0x7F, 0xF4, 0x7E, 0x00, 0x12, 0x64, +0x37, 0xBF, 0x01, 0x06, 0x90, 0x92, 0x16, 0xE0, 0xA3, 0xF0, 0x31, 0xAD, 0x7F, 0xF5, 0x7E, 0x00, +0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x18, 0xF0, 0x31, 0xAD, +0x7F, 0xF6, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, +0x19, 0xF0, 0x31, 0xAD, 0x7F, 0xF7, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, 0x01, 0x08, 0x90, 0x92, +0x16, 0xE0, 0x90, 0x92, 0x1A, 0xF0, 0x31, 0xAD, 0x7F, 0xF8, 0x7E, 0x00, 0x12, 0x64, 0x37, 0xBF, +0x01, 0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1B, 0xF0, 0x31, 0xAD, 0x51, 0x2E, 0xBF, 0x01, +0x08, 0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1C, 0xF0, 0x31, 0xAD, 0x51, 0x27, 0xBF, 0x01, 0x08, +0x90, 0x92, 0x16, 0xE0, 0x90, 0x92, 0x1D, 0xF0, 0x31, 0xAD, 0x31, 0xB4, 0xBF, 0x01, 0x08, 0x90, +0x92, 0x16, 0xE0, 0x90, 0x92, 0x1E, 0xF0, 0x90, 0x92, 0x07, 0x74, 0x19, 0xF0, 0x90, 0x92, 0x15, +0x74, 0x08, 0xF0, 0x90, 0x92, 0x17, 0xE0, 0x90, 0x92, 0x09, 0xF0, 0x90, 0x92, 0x18, 0xE0, 0x90, +0x92, 0x0A, 0xF0, 0x90, 0x92, 0x19, 0xE0, 0x90, 0x92, 0x0B, 0xF0, 0x90, 0x92, 0x1A, 0xE0, 0x90, +0x92, 0x0C, 0xF0, 0x90, 0x92, 0x1B, 0xE0, 0x90, 0x92, 0x0D, 0xF0, 0x90, 0x92, 0x1C, 0xE0, 0x90, +0x92, 0x0E, 0xF0, 0x90, 0x92, 0x1D, 0xE0, 0x90, 0x92, 0x0F, 0xF0, 0x90, 0x92, 0x1E, 0xE0, 0x90, +0x92, 0x10, 0xF0, 0x11, 0xC1, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x02, 0x87, 0xBB, 0x7B, 0x01, 0x7A, +0x92, 0x79, 0x16, 0x22, 0x7F, 0xFD, 0x7E, 0x00, 0x02, 0x64, 0x37, 0x7E, 0x00, 0x7F, 0x0B, 0x7D, +0x00, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x8A, 0x12, 0x06, 0xDE, 0x51, 0x20, 0x51, 0x2E, 0xBF, 0x01, +0x1C, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x01, 0x90, 0x92, 0x8A, 0xF0, 0xEE, 0x54, 0x04, 0x90, +0x92, 0x8C, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0x54, 0x08, 0x90, 0x92, 0x8B, 0xF0, 0x51, 0x20, 0x51, +0x27, 0xBF, 0x01, 0x16, 0x90, 0x92, 0x29, 0xE0, 0xFE, 0x54, 0x07, 0x90, 0x92, 0x8E, 0xF0, 0xEE, +0x54, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x90, 0x92, 0x8D, 0xF0, 0x51, 0x20, 0x31, 0xB4, 0xBF, 0x01, +0x0E, 0x90, 0x92, 0x29, 0xE0, 0x54, 0x0C, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x92, 0x8F, 0xF0, 0x22, +0x7B, 0x01, 0x7A, 0x92, 0x79, 0x29, 0x22, 0x7F, 0xFB, 0x7E, 0x00, 0x02, 0x64, 0x37, 0x7F, 0xF9, +0x7E, 0x00, 0x02, 0x64, 0x37, 0x12, 0x02, 0xF6, 0xFF, 0x90, 0x92, 0x89, 0xF0, 0xBF, 0x01, 0x07, +0x11, 0xC8, 0xE4, 0x90, 0x92, 0x89, 0xF0, 0x22, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80, 0xFD, 0x7F, +0x80, 0x12, 0x7B, 0x3E, 0x12, 0xB8, 0x98, 0x12, 0xBE, 0xF6, 0x12, 0x7B, 0x9C, 0x51, 0xD2, 0x12, +0xB7, 0xD5, 0x7F, 0x01, 0x12, 0x85, 0x15, 0x90, 0x92, 0x88, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x85, +0x15, 0x90, 0x92, 0x88, 0xE0, 0x04, 0xF0, 0x12, 0xB8, 0x59, 0x51, 0xF0, 0x90, 0x01, 0xCC, 0x74, +0x0F, 0xF0, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x7B, 0x3E, 0x75, 0x20, +0xFF, 0x12, 0x7C, 0xCD, 0x12, 0xB6, 0xA3, 0x90, 0x00, 0x81, 0xE0, 0x44, 0x04, 0xFD, 0x7F, 0x81, +0x12, 0x7B, 0x3E, 0x12, 0xB8, 0x8D, 0x31, 0xBB, 0x90, 0x00, 0x00, 0xE0, 0x54, 0xFB, 0xFD, 0xE4, +0xFF, 0x12, 0xB6, 0x80, 0x44, 0x04, 0xFD, 0x7F, 0x01, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x98, 0x74, +0x80, 0xF0, 0xA3, 0x74, 0x88, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x80, 0xF0, 0xE4, 0xFF, 0x02, +0x85, 0x9E, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x12, +0xB7, 0x09, 0x90, 0x01, 0x99, 0xE0, 0x44, 0xC0, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x80, 0xF0, 0x22, +0xF1, 0xEE, 0x12, 0x7B, 0xEF, 0x12, 0x3C, 0x03, 0x12, 0xBE, 0x74, 0xF1, 0xF4, 0x12, 0xC3, 0x2D, +0x71, 0xDA, 0x71, 0x27, 0x12, 0x7B, 0x64, 0x12, 0x78, 0xB9, 0x90, 0x89, 0x16, 0xE0, 0x54, 0x7F, +0xF0, 0x54, 0xBF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xF0, 0xF0, 0xE4, 0x90, 0x89, 0x18, 0xF0, 0x90, +0x89, 0x16, 0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x7E, 0x00, 0x7F, 0x24, 0x7D, 0x00, 0x7B, 0x01, 0x7A, +0x86, 0x79, 0x72, 0x12, 0x06, 0xDE, 0x90, 0x06, 0x90, 0xE0, 0x44, 0x20, 0xF0, 0x12, 0xB7, 0x11, +0x71, 0xE0, 0x90, 0x84, 0xC5, 0xE0, 0xFF, 0x64, 0x02, 0x70, 0x29, 0x71, 0xD3, 0x30, 0xE0, 0x02, +0x7E, 0x01, 0x90, 0x86, 0x90, 0x71, 0xD1, 0x30, 0xE1, 0x02, 0x7E, 0x01, 0x90, 0x86, 0x8E, 0x71, +0xD1, 0x30, 0xE2, 0x02, 0x7E, 0x01, 0x90, 0x86, 0x8F, 0xEE, 0xF0, 0x90, 0xFD, 0x80, 0xE0, 0x90, +0x02, 0xFB, 0xF0, 0x22, 0xEF, 0x64, 0x01, 0x70, 0x1D, 0x71, 0xCA, 0x30, 0xE0, 0x02, 0x7F, 0x01, +0x90, 0x86, 0x90, 0x71, 0xC8, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x8E, 0x71, 0xC8, 0x30, +0xE2, 0x02, 0x7F, 0x01, 0x80, 0x23, 0x90, 0x84, 0xC5, 0xE0, 0x64, 0x03, 0x70, 0x20, 0x71, 0xC1, +0x30, 0xE0, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x90, 0x71, 0xBF, 0x30, 0xE1, 0x02, 0x7F, 0x01, 0x90, +0x86, 0x8E, 0x71, 0xBF, 0x30, 0xE2, 0x02, 0x7F, 0x01, 0x90, 0x86, 0x8F, 0xEF, 0xF0, 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, 0x12, 0xC3, 0xFC, 0x02, 0x06, 0xDE, +0x12, 0xC6, 0x02, 0xE4, 0x90, 0x88, 0xD8, 0x12, 0x96, 0x3F, 0x90, 0x88, 0x76, 0xF0, 0x12, 0x96, +0x3A, 0x12, 0x96, 0x40, 0x90, 0x88, 0x88, 0xF0, 0xA3, 0xF0, 0x90, 0x88, 0xCA, 0xF0, 0xA3, 0xF0, +0x22, 0x90, 0x86, 0x72, 0x91, 0x0C, 0x30, 0xE0, 0x02, 0x71, 0xE0, 0x22, 0xE0, 0xFF, 0xC4, 0x13, +0x13, 0x54, 0x03, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x8B, 0x5B, 0x8A, 0x5C, 0x89, +0x5D, 0x90, 0x05, 0x27, 0xE0, 0xF5, 0x5E, 0x8B, 0x1B, 0x8A, 0x1C, 0x89, 0x1D, 0x75, 0x1E, 0x01, +0x7B, 0x01, 0x7A, 0x85, 0x79, 0xBC, 0x12, 0x6A, 0x21, 0x12, 0x91, 0xC3, 0xFF, 0xC3, 0x13, 0x20, +0xE0, 0x02, 0x81, 0xCF, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x72, 0xF1, 0x29, 0x75, 0x5E, 0x21, +0xF1, 0x9B, 0x30, 0xE0, 0x05, 0x12, 0xC8, 0x58, 0x80, 0x0D, 0xE4, 0x90, 0x85, 0xBD, 0xF0, 0xA3, +0xF0, 0x7D, 0x40, 0xFF, 0x12, 0x7C, 0x41, 0xF1, 0x92, 0x54, 0x1F, 0x30, 0xE0, 0x03, 0x43, 0x5E, +0x12, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x14, 0x90, 0x85, 0xBC, 0xE0, 0xC4, +0x13, 0x54, 0x07, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x80, 0x90, 0x85, 0xBC, 0xF1, 0xD7, 0x20, 0xE0, +0x03, 0x43, 0x5E, 0x40, 0xB1, 0x73, 0x90, 0x85, 0xBF, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0xB4, +0x17, 0x90, 0x85, 0xBC, 0x91, 0x0C, 0x30, 0xE0, 0x04, 0x7F, 0x04, 0x80, 0x0B, 0xF1, 0xAD, 0xEF, +0x60, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x12, 0xB4, 0x17, 0xA1, 0x3E, 0xB1, 0x70, 0x90, +0x85, 0xBF, 0xE0, 0x64, 0x04, 0x60, 0x02, 0xA1, 0x6B, 0xFF, 0x12, 0xB4, 0x17, 0xA1, 0x6B, 0x90, +0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x70, 0xF1, 0x29, 0x43, 0x5E, 0x31, 0xF1, 0x9B, 0x30, 0xE0, 0x05, +0x12, 0xC8, 0x58, 0x80, 0x07, 0x7D, 0x40, 0xE4, 0xFF, 0x12, 0x7C, 0x41, 0xF1, 0x92, 0x54, 0x1F, +0x30, 0xE0, 0x03, 0x43, 0x5E, 0x02, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x03, 0x43, 0x5E, 0x04, +0xB1, 0x73, 0x90, 0x85, 0xBC, 0x91, 0x0C, 0x30, 0xE0, 0x0A, 0xF1, 0x49, 0x60, 0x30, 0xE4, 0xFD, +0x7F, 0x02, 0x80, 0x1E, 0x12, 0xB6, 0x78, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x18, 0x12, 0x7A, +0xA2, 0xF1, 0xAD, 0xBF, 0x01, 0x09, 0x90, 0x85, 0xC7, 0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, +0xFD, 0xFF, 0xB1, 0x7E, 0x80, 0x08, 0x90, 0x85, 0xC8, 0xE0, 0x90, 0x85, 0xC0, 0xF0, 0x90, 0x05, +0x40, 0x74, 0x22, 0xF0, 0x80, 0x25, 0xB1, 0x70, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x06, 0x7D, +0x01, 0x7F, 0x04, 0x80, 0x0B, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x08, 0x06, 0x7D, 0x01, 0x7F, 0x0C, +0xB1, 0x7E, 0xF1, 0xA4, 0x90, 0x85, 0xC7, 0xF1, 0x8C, 0xF1, 0xF4, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x75, 0x5E, 0x01, 0x90, 0x05, 0x27, 0xE5, 0x5E, 0xF0, 0x22, 0x7D, 0x01, 0x7F, 0x04, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x2A, 0xED, 0xF0, 0x90, 0x85, 0xC1, 0xE0, 0xFE, 0xC4, +0x13, 0x13, 0x54, 0x03, 0x30, 0xE0, 0x02, 0xC1, 0xD9, 0xEE, 0x12, 0x8D, 0x6B, 0x30, 0xE0, 0x02, +0xC1, 0xD9, 0x90, 0x85, 0xC8, 0xE0, 0xFE, 0x6F, 0x70, 0x02, 0xC1, 0xD9, 0xEF, 0x70, 0x02, 0xC1, +0x44, 0x24, 0xFE, 0x70, 0x02, 0xC1, 0x81, 0x24, 0xFE, 0x60, 0x4D, 0x24, 0xFC, 0x70, 0x02, 0xC1, +0xC0, 0x24, 0xFC, 0x60, 0x02, 0xC1, 0xD2, 0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, +0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12, 0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, +0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x0F, 0x90, 0x93, 0x2A, 0xE0, 0xFF, 0x60, +0x05, 0x12, 0x6D, 0x4C, 0x80, 0x03, 0x12, 0x79, 0x61, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x08, 0x60, +0x02, 0xC1, 0xD2, 0x12, 0x7A, 0xB9, 0xC1, 0xD2, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, 0x01, +0x12, 0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, +0xE0, 0xB4, 0x0E, 0x08, 0xD1, 0xDE, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, +0x64, 0x0C, 0x60, 0x02, 0xC1, 0xD2, 0xD1, 0xDE, 0xEF, 0x64, 0x01, 0x60, 0x02, 0xC1, 0xD2, 0x12, +0x70, 0x9E, 0xC1, 0xD2, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0xD1, 0xDE, 0xBF, 0x01, 0x03, +0x12, 0x74, 0x93, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, +0xE0, 0xB4, 0x0C, 0x08, 0xD1, 0xDE, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, +0x64, 0x04, 0x70, 0x5E, 0x12, 0xC4, 0x21, 0xEF, 0x64, 0x01, 0x70, 0x56, 0x12, 0x77, 0xFE, 0x80, +0x51, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0E, 0x08, 0xD1, 0xDE, 0xBF, 0x01, 0x03, 0x12, 0x74, 0x93, +0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x73, 0x8E, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0C, +0x08, 0xD1, 0xDE, 0xBF, 0x01, 0x03, 0x12, 0x70, 0x9E, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x05, 0x7F, +0x01, 0x12, 0x79, 0x80, 0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x04, 0x17, 0x12, 0x79, 0xF3, 0x80, 0x12, +0x90, 0x85, 0xC8, 0xE0, 0xB4, 0x0C, 0x0B, 0x12, 0xA1, 0x92, 0x54, 0x3F, 0x30, 0xE0, 0x03, 0x12, +0x7A, 0x8A, 0x90, 0x85, 0xC8, 0x12, 0xC8, 0x84, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, +0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, 0x75, 0x0E, 0x01, +0x80, 0x24, 0x90, 0x85, 0xC1, 0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x05, 0x75, 0x0E, +0x02, 0x80, 0x13, 0x90, 0x85, 0xC7, 0xE0, 0xD3, 0x94, 0x04, 0x40, 0x05, 0x75, 0x0E, 0x08, 0x80, +0x05, 0x12, 0xB3, 0xD4, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0, 0x90, 0x01, 0xB8, 0xE5, +0x0E, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7D, 0x03, 0x7F, 0x02, 0x02, 0x7B, 0xFD, +0x90, 0x85, 0xBC, 0x91, 0x0C, 0x30, 0xE0, 0x0A, 0xF1, 0x49, 0x60, 0x06, 0x7D, 0x01, 0x7F, 0x02, +0xB1, 0x7E, 0xF1, 0x49, 0x60, 0x02, 0xF1, 0x50, 0x22, 0x90, 0x85, 0xC0, 0xE0, 0x64, 0x02, 0x22, +0x90, 0x85, 0xC5, 0xE0, 0x64, 0x02, 0x60, 0x0F, 0xF1, 0xE5, 0x60, 0x0B, 0x12, 0x7A, 0x29, 0xEF, +0x70, 0x05, 0xFD, 0x7F, 0x0C, 0xB1, 0x7E, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x1B, +0xF1, 0xE5, 0x60, 0x0F, 0xE4, 0xFD, 0x7F, 0x0C, 0xB1, 0x7E, 0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xDD, +0x02, 0x6B, 0x98, 0x90, 0x85, 0xC8, 0xE0, 0x70, 0x02, 0xB1, 0x7A, 0x22, 0xE0, 0xFF, 0x7D, 0x01, +0xA1, 0x7E, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x22, 0x12, 0x7A, 0x29, 0xEF, 0x70, 0x02, 0xF1, 0x68, 0x22, 0x90, 0x05, 0x43, +0xE0, 0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, 0xAE, 0x07, 0xF1, 0xAD, 0xBF, 0x01, 0x11, +0x90, 0x85, 0xBC, 0xF1, 0xD7, 0x20, 0xE0, 0x09, 0xAF, 0x06, 0x7D, 0x01, 0xB1, 0x7E, 0x7F, 0x01, +0x22, 0x7F, 0x00, 0x22, 0x90, 0x86, 0x72, 0xE0, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x22, 0x90, 0x85, +0xC9, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x85, 0xC3, 0xE0, 0x54, 0x0F, 0x22, 0x81, 0x01, 0xE4, 0xFD, +0xFF, 0x02, 0x6E, 0x5F, 0x7E, 0x00, 0x7F, 0x01, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x85, 0x79, 0xBC, +0x12, 0x06, 0xDE, 0x90, 0x85, 0xBC, 0xE0, 0x54, 0xFD, 0xF0, 0xE4, 0x12, 0x96, 0x40, 0xA3, 0x74, +0x0C, 0xF0, 0x22, 0x12, 0x02, 0xF6, 0x54, 0x01, 0xFF, 0x90, 0x92, 0x95, 0xE0, 0x54, 0xFE, 0x4F, +0xF0, 0x22, 0x12, 0x02, 0xF6, 0x90, 0x86, 0x71, 0xF0, 0x22, 0x12, 0xC8, 0x99, 0x90, 0x92, 0x84, +0x12, 0xC8, 0x91, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x12, 0x8D, 0x72, 0x90, 0x92, 0x85, 0x12, +0x8C, 0x7F, 0x90, 0x92, 0x86, 0xF0, 0xB1, 0x8C, 0x90, 0x92, 0x84, 0xE0, 0x54, 0x01, 0xFF, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xEF, 0x64, 0x01, 0x70, 0x19, 0x11, 0x97, 0x60, 0x09, 0x11, +0x90, 0x12, 0x7B, 0xFD, 0xB1, 0x7A, 0x80, 0x07, 0x11, 0x90, 0x12, 0x7B, 0xBF, 0x91, 0x61, 0x12, +0x7A, 0x8A, 0x80, 0x17, 0x11, 0x97, 0x60, 0x07, 0x11, 0x90, 0x12, 0x7B, 0xFD, 0x80, 0x05, 0x11, +0x90, 0x12, 0x7B, 0xBF, 0xB1, 0x32, 0xB1, 0x63, 0x12, 0x7A, 0xB9, 0xD0, 0xD0, 0x92, 0xAF, 0x22, +0x74, 0x10, 0xF0, 0xFD, 0x7F, 0x03, 0x22, 0x90, 0x92, 0x86, 0xE0, 0x90, 0x01, 0x3F, 0x22, 0x91, +0x6F, 0x64, 0x01, 0x60, 0x02, 0x21, 0x86, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0x21, 0x86, 0x90, +0x05, 0x63, 0xE0, 0x90, 0x92, 0x9B, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0x90, 0x92, 0x9C, 0xF0, 0x90, +0x05, 0x61, 0xE0, 0x90, 0x92, 0x9D, 0xF0, 0x90, 0x05, 0x60, 0xE0, 0x90, 0x92, 0x9E, 0xF0, 0xB1, +0xEE, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xEC, 0xF0, 0x31, 0xAA, 0x24, 0xFD, 0x50, 0x02, 0x80, 0x0D, +0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x04, 0x51, 0xCB, 0x80, 0x02, 0x51, 0x7E, 0x31, 0xAA, 0x64, +0x01, 0x70, 0x22, 0x90, 0x06, 0xAB, 0xE0, 0x90, 0x85, 0xCC, 0xF0, 0x90, 0x06, 0xAA, 0xE0, 0x90, +0x85, 0xCB, 0xF0, 0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x85, 0xCB, 0xE0, 0xFE, 0xFF, 0x80, 0x00, +0x90, 0x85, 0xCC, 0xEF, 0xF0, 0x12, 0xBA, 0x83, 0xE4, 0x90, 0x85, 0xCE, 0xF0, 0x12, 0xC5, 0x60, +0x31, 0x92, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x5C, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x20, 0xE0, +0x22, 0x31, 0xA2, 0x6F, 0x70, 0x4E, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x40, 0xF0, 0xB1, 0x83, 0x90, +0x01, 0x3F, 0x11, 0x90, 0x12, 0x7B, 0xFD, 0x91, 0x68, 0xB1, 0x5C, 0x90, 0x85, 0xCC, 0xE0, 0x14, +0xF0, 0x80, 0x31, 0x90, 0x85, 0xC3, 0xE0, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x26, 0x31, 0xA2, +0xFE, 0x6F, 0x60, 0x20, 0x90, 0x05, 0x73, 0xE0, 0xFF, 0xEE, 0x6F, 0x60, 0x17, 0x31, 0x92, 0x54, +0x3F, 0x30, 0xE0, 0x10, 0xEF, 0x54, 0xBF, 0xF0, 0x90, 0x01, 0x3F, 0x11, 0x90, 0x12, 0x7B, 0xBF, +0xB1, 0x63, 0xB1, 0x32, 0x31, 0x9A, 0x90, 0x85, 0xBC, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x02, 0x31, +0x9A, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0xFF, 0x13, 0x13, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x04, +0xF0, 0x22, 0x90, 0x85, 0xCB, 0xE0, 0xFF, 0xA3, 0xE0, 0x22, 0x90, 0x85, 0xC3, 0xE0, 0xFF, 0xC4, +0x54, 0x0F, 0x22, 0xE4, 0xF5, 0x77, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0x41, 0x50, 0x91, 0x6F, +0x64, 0x01, 0x60, 0x02, 0x41, 0x50, 0x12, 0xC7, 0xFA, 0x31, 0xAA, 0x60, 0x22, 0x24, 0xFE, 0x60, +0x03, 0x04, 0x70, 0x1E, 0x90, 0x85, 0xCC, 0xE0, 0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x85, +0xCE, 0xE0, 0x60, 0x0E, 0xEF, 0x70, 0x08, 0x90, 0x85, 0xCB, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x75, +0x77, 0x01, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x12, 0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x02, 0x03, +0xE4, 0xF5, 0x77, 0x12, 0x9F, 0xAD, 0xEF, 0x70, 0x02, 0xF5, 0x77, 0xE5, 0x77, 0x60, 0x41, 0x90, +0x85, 0xC8, 0xE0, 0x20, 0xE2, 0x03, 0x12, 0x9D, 0x7A, 0xB1, 0x72, 0x90, 0x85, 0xCE, 0xE0, 0x60, +0x04, 0x64, 0x01, 0x70, 0x13, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0x51, 0x5C, +0x51, 0x70, 0x90, 0x85, 0xCE, 0xE0, 0x80, 0x12, 0xE4, 0x90, 0x91, 0x6E, 0x51, 0x51, 0x51, 0x70, +0x90, 0x85, 0xCE, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0x51, 0x5C, 0x90, 0x85, 0xDE, 0xF0, +0x22, 0xF0, 0x90, 0x85, 0xCE, 0xE0, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x85, 0xCD, +0xE0, 0x2F, 0x22, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x86, 0x6E, 0xE0, +0x90, 0x91, 0x6F, 0xF0, 0xE4, 0xFB, 0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x02, 0x61, 0x41, 0xE4, 0xF5, +0x77, 0x90, 0x06, 0xA9, 0xE0, 0xF5, 0x77, 0x54, 0xC0, 0x70, 0x07, 0x51, 0xC3, 0x54, 0xFD, 0xF0, +0xA1, 0x96, 0xE5, 0x77, 0x30, 0xE6, 0x19, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x01, 0x70, 0x13, 0x12, +0x9F, 0xDE, 0x64, 0x02, 0x60, 0x05, 0x12, 0x77, 0x61, 0x80, 0x07, 0x12, 0x79, 0x41, 0x80, 0x02, +0x51, 0xC3, 0xE5, 0x77, 0x90, 0x85, 0xC9, 0x30, 0xE7, 0x04, 0x51, 0x63, 0xA1, 0x6A, 0xE0, 0x54, +0xFD, 0xF0, 0x22, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xFE, 0xF0, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, +0x92, 0x56, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x04, 0x51, 0xC3, 0x80, 0x56, 0xED, 0x30, 0xE6, +0x41, 0x90, 0x85, 0xC5, 0xE0, 0x64, 0x02, 0x70, 0x28, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0xC3, 0x13, +0x20, 0xE0, 0x09, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x1C, 0x12, 0x9F, 0xE5, 0x64, +0x01, 0x70, 0x21, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x04, 0xF0, 0x7F, 0x01, 0x12, 0x62, 0x8E, 0x80, +0x13, 0x12, 0x9F, 0xDE, 0x64, 0x02, 0x60, 0x05, 0x12, 0x77, 0x61, 0x80, 0x07, 0x12, 0x79, 0x41, +0x80, 0x02, 0x51, 0xC3, 0x90, 0x92, 0x56, 0xE0, 0x90, 0x85, 0xC9, 0x30, 0xE7, 0x04, 0x51, 0x63, +0xA1, 0x6A, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x06, 0x90, 0x85, +0xBE, 0x74, 0x01, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x02, 0x61, 0xEF, 0x90, 0x85, 0xDC, 0xE0, +0x04, 0xF0, 0x90, 0x05, 0x61, 0x91, 0x5A, 0x78, 0x08, 0x12, 0x04, 0xD8, 0xA8, 0x04, 0xA9, 0x05, +0xAA, 0x06, 0xAB, 0x07, 0x90, 0x05, 0x60, 0x91, 0x5A, 0x12, 0x87, 0x4B, 0xC0, 0x04, 0xC0, 0x05, +0xC0, 0x06, 0xC0, 0x07, 0x90, 0x05, 0x62, 0x91, 0x5A, 0x78, 0x10, 0x12, 0x04, 0xD8, 0xD0, 0x03, +0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x87, 0x4B, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, +0x07, 0xA3, 0x91, 0x5A, 0x78, 0x18, 0x12, 0x04, 0xD8, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, +0x00, 0x12, 0x87, 0x4B, 0x90, 0x85, 0xFC, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x96, 0xE0, +0x54, 0xFE, 0xF0, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x0E, 0x12, 0xBA, 0x76, 0xFB, 0x12, 0x51, 0x7D, +0x90, 0x92, 0x96, 0xE0, 0x54, 0xFD, 0xF0, 0x31, 0x92, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x09, 0x90, +0x01, 0x3B, 0xE0, 0x30, 0xE4, 0x02, 0x91, 0x61, 0x90, 0x93, 0x27, 0xE0, 0x04, 0xF0, 0xE0, 0xC3, +0x94, 0x80, 0x40, 0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0, 0xE0, 0x44, 0x01, 0xF0, 0x12, +0x5D, 0x1F, 0x12, 0x6E, 0x1D, 0xE4, 0x90, 0x88, 0xE0, 0xF0, 0x7F, 0x01, 0x12, 0xB9, 0x12, 0xD1, +0x04, 0x12, 0x9F, 0xD4, 0x30, 0xE0, 0x52, 0x90, 0x88, 0x76, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7C, +0x00, 0x7D, 0x64, 0x12, 0x03, 0x82, 0x90, 0x88, 0xCA, 0xE0, 0x6E, 0x70, 0x03, 0xA3, 0xE0, 0x6F, +0x60, 0x0A, 0x90, 0x88, 0xCA, 0xE4, 0x75, 0xF0, 0x01, 0x02, 0x07, 0x0A, 0x90, 0x88, 0x7A, 0xE0, +0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x88, 0x88, 0xE0, 0xB5, 0x06, 0x14, 0xA3, 0xE0, 0xB5, 0x07, 0x0F, +0xEF, 0x4E, 0x60, 0x0B, 0x90, 0x01, 0xC7, 0x74, 0x31, 0xF0, 0x7F, 0x01, 0x02, 0x5F, 0xE9, 0x12, +0xC1, 0xFA, 0xE4, 0x90, 0x88, 0xCA, 0xF0, 0xA3, 0xF0, 0x22, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, +0x22, 0x7D, 0x02, 0x7F, 0x02, 0x12, 0x7C, 0x41, 0x7D, 0x01, 0x7F, 0x02, 0x02, 0x7C, 0x41, 0xE4, +0xFF, 0x12, 0x77, 0x39, 0xEF, 0x22, 0xE4, 0x90, 0x92, 0x67, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x60, +0x4F, 0x91, 0x6F, 0x64, 0x01, 0x70, 0x49, 0xB1, 0x83, 0x12, 0xC7, 0xFA, 0x90, 0x92, 0x67, 0x74, +0x01, 0xF0, 0xE4, 0x90, 0x85, 0xCC, 0xF0, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x85, +0xC0, 0xE0, 0xB4, 0x02, 0x05, 0xE4, 0x90, 0x92, 0x67, 0xF0, 0x12, 0x9F, 0xAD, 0xEF, 0x70, 0x04, +0x90, 0x92, 0x67, 0xF0, 0x90, 0x92, 0x67, 0xE0, 0x60, 0x16, 0x90, 0x85, 0xC8, 0xE0, 0x20, 0xE2, +0x03, 0x12, 0x9D, 0x7A, 0xB1, 0x72, 0xE4, 0x90, 0x91, 0x6E, 0xF0, 0x90, 0x85, 0xCD, 0x51, 0x6F, +0x22, 0x31, 0x92, 0x13, 0x54, 0x1F, 0x30, 0xE0, 0x0B, 0xEF, 0xC4, 0x13, 0x13, 0x54, 0x03, 0x30, +0xE0, 0x02, 0xB1, 0x5C, 0xB1, 0xFA, 0x30, 0xE0, 0x08, 0xB1, 0xC3, 0x54, 0x07, 0x70, 0x3A, 0x80, +0x36, 0x12, 0xC5, 0x9A, 0x40, 0x31, 0x91, 0x6F, 0x64, 0x01, 0x70, 0x2D, 0x12, 0x9F, 0xE5, 0x70, +0x05, 0x12, 0x70, 0xDB, 0x80, 0x24, 0x12, 0x70, 0xDB, 0x90, 0x85, 0xCF, 0xE0, 0x04, 0xF0, 0xE0, +0xD3, 0x94, 0x02, 0x40, 0x09, 0xB1, 0x2A, 0xE4, 0x90, 0x85, 0xCF, 0xF0, 0x80, 0x03, 0x12, 0x79, +0x41, 0xE4, 0x90, 0x85, 0xCE, 0xF0, 0x22, 0xB1, 0x96, 0x22, 0x90, 0x85, 0xC2, 0xE0, 0x54, 0xFB, +0xF0, 0x22, 0x7D, 0x02, 0x7F, 0x02, 0x02, 0x7C, 0xA9, 0x91, 0x76, 0xB1, 0x32, 0x7F, 0x01, 0xF1, +0x38, 0x90, 0x92, 0x84, 0xE0, 0x30, 0xE0, 0x13, 0xB1, 0x7A, 0x90, 0x92, 0x87, 0xE0, 0x60, 0x05, +0x14, 0xF0, 0x02, 0x7A, 0x8A, 0xB1, 0x8C, 0xE4, 0xFF, 0x11, 0x4F, 0x22, 0x7D, 0x02, 0x7F, 0x02, +0x02, 0x7C, 0x41, 0x7D, 0x01, 0x7F, 0x02, 0x02, 0x7C, 0xA9, 0x90, 0x85, 0xC1, 0xE0, 0x44, 0x04, +0xF0, 0x22, 0x90, 0x85, 0xC9, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x92, 0x86, 0xE0, 0x90, 0x05, +0x73, 0xF0, 0x22, 0x90, 0x85, 0xCB, 0xE0, 0x90, 0x05, 0x73, 0xF0, 0x22, 0x90, 0x92, 0x85, 0xE0, +0x14, 0x90, 0x92, 0x87, 0xF0, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0x90, 0x85, 0xC7, 0x30, 0xE0, 0x05, +0xE0, 0xFF, 0x02, 0x9F, 0xB9, 0x02, 0x9F, 0x8C, 0x91, 0x6F, 0x64, 0x01, 0x70, 0x14, 0x90, 0x85, +0xC5, 0xE0, 0x60, 0x0E, 0xB1, 0xEE, 0x90, 0x85, 0xC1, 0xE0, 0xB1, 0xC4, 0x54, 0x07, 0x70, 0x02, +0xB1, 0x96, 0x22, 0xEF, 0x54, 0xFB, 0xF0, 0x90, 0x85, 0xC9, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, +0x01, 0x57, 0xE0, 0x60, 0x18, 0xB1, 0xF1, 0xB1, 0xFA, 0x30, 0xE0, 0x02, 0x80, 0xE5, 0x12, 0xC5, +0x9A, 0x40, 0x0A, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, 0x01, 0x02, 0xB1, 0x2A, 0x22, 0x90, 0x01, +0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x13, +0x13, 0x54, 0x3F, 0x22, 0x90, 0x92, 0x84, 0xE0, 0x30, 0xE0, 0x09, 0x90, 0x01, 0x3B, 0xE0, 0x30, +0xE4, 0x02, 0x91, 0x61, 0x22, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0F, 0x90, 0x06, 0x92, 0xE0, 0x30, +0xE1, 0x03, 0x02, 0x6B, 0x98, 0x12, 0xC9, 0x25, 0xB1, 0x96, 0x22, 0xE4, 0xFF, 0x12, 0x77, 0x39, +0xBF, 0x01, 0x0E, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x08, 0x51, 0xC3, 0x54, 0x07, 0x70, 0x02, 0xB1, +0x96, 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, 0x42, 0xF0, 0x74, 0xA6, 0xA3, 0xF0, 0x12, 0x71, 0x90, 0xE5, 0x4C, 0x30, 0xE1, +0x02, 0xF1, 0xE2, 0xE5, 0x4C, 0x30, 0xE3, 0x03, 0x12, 0xB9, 0x28, 0xE5, 0x4C, 0x30, 0xE4, 0x03, +0x12, 0xB9, 0x21, 0xE5, 0x4C, 0x30, 0xE5, 0x03, 0x12, 0xBF, 0x03, 0xE5, 0x4C, 0x30, 0xE6, 0x03, +0x12, 0xBD, 0x87, 0xE5, 0x4E, 0x30, 0xE0, 0x02, 0xF1, 0x1C, 0xE5, 0x4E, 0x30, 0xE1, 0x02, 0x71, +0x37, 0xE5, 0x4E, 0x30, 0xE2, 0x03, 0x12, 0xBD, 0x94, 0xE5, 0x4E, 0x30, 0xE3, 0x02, 0xF1, 0x03, +0xE5, 0x4E, 0x30, 0xE4, 0x02, 0xB1, 0xA8, 0xE5, 0x4E, 0x30, 0xE5, 0x03, 0x12, 0xBD, 0xC3, 0xE5, +0x4E, 0x30, 0xE6, 0x02, 0xD1, 0x2B, 0xE5, 0x4F, 0x30, 0xE1, 0x03, 0x12, 0xBD, 0xDF, 0xE5, 0x4F, +0x30, 0xE4, 0x03, 0x12, 0xBF, 0x3F, 0xE5, 0x4F, 0x30, 0xE5, 0x02, 0xF1, 0x6F, 0x74, 0x42, 0x04, +0x90, 0x01, 0xC4, 0xF0, 0x74, 0xA6, 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, 0x91, 0x6F, 0x64, 0x01, 0x70, 0x12, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0C, 0x90, +0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0x51, 0x66, 0x22, 0x90, 0x85, 0xBC, 0xE0, +0x30, 0xE0, 0x11, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0xC3, 0x13, 0x30, 0xE0, +0x03, 0x12, 0xB7, 0x24, 0x31, 0xB3, 0xE4, 0xFF, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, +0x92, 0x96, 0xE0, 0xFE, 0x13, 0x13, 0x54, 0x3F, 0x30, 0xE0, 0x1F, 0x90, 0x92, 0x67, 0x74, 0x1E, +0xF0, 0x90, 0x92, 0x75, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x69, 0xEF, 0xF0, 0x7B, 0x01, 0x7A, 0x92, +0x79, 0x67, 0x12, 0x5E, 0x10, 0x7F, 0x04, 0x12, 0xB9, 0x12, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xE4, +0xF5, 0x77, 0x90, 0x85, 0xBB, 0xE0, 0xFF, 0xE5, 0x77, 0xC3, 0x9F, 0x50, 0x64, 0xAF, 0x77, 0x12, +0x77, 0x39, 0xEF, 0x60, 0x58, 0xE5, 0x77, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE5, 0x77, 0x54, +0x07, 0xFE, 0x74, 0x75, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, 0xFD, 0xAF, 0x06, +0x12, 0xA9, 0xA8, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, +0x60, 0x2B, 0xE5, 0x77, 0x12, 0xC8, 0x76, 0x20, 0xE7, 0x02, 0x80, 0x13, 0xE5, 0x77, 0xC4, 0x54, +0xF0, 0x24, 0x02, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFF, 0x20, 0xE7, 0x09, 0x90, +0x01, 0xC1, 0xE0, 0x44, 0x20, 0xF0, 0x80, 0x05, 0xAD, 0x77, 0x12, 0x97, 0x08, 0x05, 0x77, 0x80, +0x91, 0x22, 0xE4, 0xFF, 0x90, 0x92, 0x56, 0xEF, 0xF0, 0x90, 0x04, 0x7E, 0xE0, 0xFF, 0xA3, 0xE0, +0x90, 0x92, 0x66, 0xF0, 0xE0, 0xFE, 0x6F, 0x60, 0x66, 0x90, 0x92, 0x57, 0x74, 0x03, 0xF0, 0x90, +0x92, 0x65, 0x74, 0x08, 0xF0, 0xEE, 0x04, 0x54, 0x0F, 0xFF, 0xE4, 0xFE, 0xEF, 0x75, 0xF0, 0x08, +0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83, 0xE5, 0x82, 0x2E, 0x11, 0x60, 0xE0, +0xFD, 0x74, 0x59, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0xED, 0xF0, 0x0E, 0xEE, 0xB4, +0x08, 0xDA, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x57, 0x12, 0x5E, 0x10, 0x90, 0x92, 0x66, 0xE0, 0x04, +0x54, 0x0F, 0xFF, 0xF0, 0xBF, 0x0F, 0x02, 0xE4, 0xF0, 0x90, 0x92, 0x66, 0xE0, 0x90, 0x04, 0x7F, +0xF0, 0x90, 0x92, 0x56, 0xE0, 0x7F, 0x04, 0x70, 0x03, 0x02, 0xB9, 0x12, 0x12, 0x87, 0xBB, 0x22, +0xF5, 0x82, 0xE4, 0x35, 0x83, 0xF5, 0x83, 0x22, 0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x92, +0x01, 0xF0, 0x90, 0x92, 0x01, 0xE0, 0xFD, 0x70, 0x02, 0x21, 0x75, 0x90, 0x85, 0x1D, 0xE0, 0xFF, +0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0xB5, +0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, 0xE0, 0x44, +0x01, 0xF0, 0x22, 0x90, 0x93, 0x22, 0xE0, 0x31, 0xA7, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, +0xCE, 0xD8, 0xF9, 0xFF, 0xEF, 0x5D, 0x70, 0x02, 0x21, 0x58, 0xE4, 0x90, 0x92, 0x02, 0xF0, 0x90, +0x92, 0x02, 0xE0, 0xF9, 0xC3, 0x94, 0x04, 0x50, 0x40, 0x31, 0x77, 0xA4, 0xFF, 0xE9, 0xFD, 0x7C, +0x00, 0x2F, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, 0x74, 0xD0, 0x31, 0x7F, 0x90, 0x84, 0xCD, 0x12, 0x05, +0x28, 0xE5, 0x82, 0x29, 0x11, 0x60, 0xEF, 0x31, 0x76, 0xA4, 0x2D, 0xFF, 0xEC, 0x35, 0xF0, 0xFE, +0x74, 0xF0, 0x31, 0x7F, 0x90, 0x84, 0xD1, 0x12, 0x05, 0x28, 0xE5, 0x82, 0x29, 0x11, 0x60, 0xEF, +0xF0, 0x90, 0x92, 0x02, 0xE0, 0x04, 0xF0, 0x80, 0xB6, 0x90, 0x92, 0x01, 0xE0, 0xFF, 0x90, 0x93, +0x22, 0xE0, 0xFE, 0x74, 0x01, 0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xF4, 0x5F, +0x90, 0x92, 0x01, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, +0xC3, 0x33, 0xD8, 0xFC, 0x90, 0x01, 0xCC, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x54, +0x03, 0xF0, 0x90, 0x85, 0x1E, 0xF1, 0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x70, 0x02, 0x01, +0x72, 0xE4, 0x90, 0x85, 0x1E, 0xF0, 0x01, 0x72, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x02, 0xF0, 0x90, +0x93, 0x22, 0xE0, 0x44, 0x80, 0x90, 0x00, 0x8A, 0x31, 0x76, 0x90, 0x01, 0xD0, 0x12, 0x05, 0x28, +0xE0, 0x90, 0x01, 0xC3, 0xF0, 0x22, 0xF0, 0x90, 0x93, 0x22, 0xE0, 0x75, 0xF0, 0x04, 0x22, 0x2F, +0xF5, 0x82, 0x74, 0x01, 0x3E, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x85, 0x1E, 0xE0, 0x75, 0xF0, 0x08, +0x22, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x24, 0x75, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0xE0, +0xFD, 0x7C, 0x00, 0xE5, 0x62, 0x54, 0x07, 0xFF, 0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x22, 0xE4, +0xF5, 0x73, 0xEF, 0x14, 0xF5, 0x72, 0xED, 0xFF, 0xE5, 0x72, 0xF5, 0x82, 0x33, 0x95, 0xE0, 0xF5, +0x83, 0xC3, 0xE5, 0x82, 0x9F, 0x74, 0x80, 0xF8, 0x65, 0x83, 0x98, 0x40, 0x52, 0xE5, 0x72, 0x78, +0x03, 0xA2, 0xE7, 0x13, 0xD8, 0xFB, 0xFF, 0x33, 0x95, 0xE0, 0xFE, 0xEB, 0x12, 0xC8, 0x3F, 0xE5, +0x82, 0x2F, 0xF5, 0x82, 0xE5, 0x83, 0x3E, 0xF5, 0x83, 0xE0, 0xF5, 0x82, 0x75, 0x83, 0x00, 0xE5, +0x72, 0x31, 0xA5, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0xEE, 0x55, +0x83, 0xFE, 0xEF, 0x55, 0x82, 0x4E, 0x60, 0x13, 0x85, 0x72, 0x74, 0x05, 0x73, 0x90, 0x92, 0x3E, +0xE0, 0x65, 0x73, 0x60, 0x0A, 0xE5, 0x74, 0xD3, 0x9D, 0x40, 0x04, 0x15, 0x72, 0x80, 0x97, 0xAF, +0x74, 0x22, 0x7D, 0x01, 0xAF, 0x62, 0xAC, 0x05, 0x90, 0x92, 0x39, 0xEF, 0xF0, 0xFD, 0xE0, 0xFF, +0x12, 0x8F, 0x73, 0xE0, 0xF5, 0x6E, 0x54, 0x7F, 0xF5, 0x70, 0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, +0x3D, 0x12, 0x05, 0x28, 0xE0, 0xF9, 0x90, 0x92, 0x39, 0xE0, 0x12, 0xC8, 0x4D, 0xFE, 0xEF, 0x12, +0x91, 0xDA, 0xE0, 0x54, 0x03, 0xF5, 0x6F, 0xE5, 0x70, 0x90, 0x83, 0x1D, 0x93, 0xFB, 0xED, 0x71, +0x17, 0xE4, 0xF0, 0xA3, 0xEB, 0xF0, 0x12, 0x8B, 0x18, 0xC4, 0x54, 0x03, 0x90, 0x92, 0x3A, 0xF0, +0x74, 0xCC, 0x2D, 0x51, 0xF9, 0xE5, 0x70, 0xF0, 0x74, 0x4C, 0x2D, 0xF1, 0xD3, 0xE5, 0x6F, 0xF0, +0xE5, 0x70, 0xD3, 0x9E, 0x40, 0x06, 0x8E, 0x70, 0xAF, 0x06, 0x8F, 0x6E, 0x8C, 0x71, 0xE4, 0xFF, +0xEF, 0xC3, 0x95, 0x71, 0x50, 0x2F, 0xE5, 0x6E, 0x30, 0xE7, 0x09, 0x85, 0x70, 0x6E, 0x1C, 0xEC, +0x70, 0x20, 0x80, 0x21, 0xE5, 0x70, 0xD3, 0x99, 0x40, 0x14, 0xAD, 0x01, 0x90, 0x92, 0x39, 0xE0, +0xFB, 0x90, 0x92, 0x3E, 0xEC, 0xF0, 0xAF, 0x70, 0x31, 0xAF, 0x8F, 0x6E, 0x80, 0x07, 0x89, 0x6E, +0x80, 0x03, 0x0F, 0x80, 0xCB, 0x90, 0x92, 0x39, 0xE0, 0xFF, 0x12, 0x8F, 0xDA, 0xEF, 0xF0, 0xA3, +0xE4, 0xF0, 0xA3, 0xE5, 0x6E, 0xF1, 0xCB, 0x91, 0x1E, 0x7B, 0x01, 0xFA, 0x7D, 0x05, 0x7F, 0x08, +0x12, 0x96, 0x87, 0x90, 0x92, 0x39, 0xE0, 0xFF, 0x90, 0x91, 0x0B, 0xE5, 0x6F, 0xF0, 0xE4, 0xFB, +0xAD, 0x6E, 0x02, 0x27, 0x3D, 0x74, 0xCC, 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, +0x22, 0xE5, 0x71, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0xE4, 0x93, +0xFE, 0x74, 0x01, 0x93, 0xFF, 0xE5, 0x6E, 0x25, 0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x8F, +0xF5, 0x83, 0x22, 0x90, 0x92, 0x39, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xEB, 0x75, +0xF0, 0x06, 0xA4, 0xFF, 0x90, 0x89, 0x21, 0x12, 0x87, 0x70, 0xE9, 0x2F, 0xF9, 0xEA, 0x35, 0xF0, +0xFA, 0x90, 0x92, 0x41, 0x12, 0x87, 0x79, 0x90, 0x92, 0x3B, 0xE0, 0x71, 0x17, 0xE0, 0xFF, 0xA3, +0xE0, 0x90, 0x92, 0x3E, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x92, 0x41, 0x12, +0x87, 0x70, 0x90, 0x92, 0x40, 0xE0, 0xFF, 0xF5, 0x82, 0x75, 0x83, 0x00, 0x12, 0x03, 0x0F, 0xFD, +0x7C, 0x00, 0x90, 0x92, 0x3B, 0xE0, 0x75, 0xF0, 0x12, 0x90, 0x89, 0x44, 0x12, 0x05, 0x28, 0x75, +0xF0, 0x02, 0xEF, 0x91, 0x16, 0xFF, 0x90, 0x92, 0x3D, 0xE0, 0xFB, 0xEF, 0xA8, 0x03, 0x08, 0x80, +0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, 0xF9, 0x91, 0x06, 0xEE, 0x8F, 0xF0, 0x12, 0x07, 0x0A, +0x90, 0x92, 0x40, 0xE0, 0x04, 0xF0, 0xE0, 0xB4, 0x05, 0xB2, 0x90, 0x92, 0x41, 0x12, 0x87, 0x70, +0x90, 0x00, 0x05, 0x12, 0x03, 0x0F, 0xFD, 0x7C, 0x00, 0x90, 0x92, 0x3D, 0xE0, 0xFF, 0x90, 0x92, +0x39, 0xE0, 0xFE, 0xA3, 0xE0, 0xA8, 0x07, 0x08, 0x80, 0x05, 0xCE, 0xC3, 0x13, 0xCE, 0x13, 0xD8, +0xF9, 0x91, 0x06, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x9F, 0xEC, 0x9E, 0x40, 0x08, 0xED, 0x9F, +0xFF, 0xEC, 0x9E, 0xFE, 0x80, 0x04, 0x7E, 0x00, 0x7F, 0x00, 0x90, 0x92, 0x3E, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0x90, 0x92, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x92, 0x3B, 0xE0, 0x71, 0x17, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xFF, 0x12, 0x03, 0x70, 0x90, 0x92, 0x3E, 0x22, 0x75, 0xF0, +0x12, 0xE5, 0x62, 0x90, 0x89, 0x40, 0x12, 0x05, 0x28, 0xE0, 0xFE, 0xA3, 0xE0, 0x22, 0xF0, 0xE4, +0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x92, 0xF5, +0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0x91, 0x1E, 0x90, 0x92, 0xFD, 0xF0, 0xA3, 0xF0, +0xA3, 0xF0, 0x90, 0x01, 0xC4, 0x74, 0x25, 0xF0, 0x74, 0xAC, 0xA3, 0xF0, 0x90, 0x01, 0x1F, 0xE0, +0xFE, 0x90, 0x01, 0x1E, 0xF1, 0x66, 0xEC, 0x3E, 0x90, 0x92, 0xEC, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x02, 0x87, 0xE0, 0x90, 0x92, 0xF4, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0x20, 0xE0, 0x02, 0xE1, 0x0C, +0xE4, 0x90, 0x92, 0xF3, 0xF0, 0x90, 0x92, 0xF4, 0xE0, 0xFF, 0x90, 0x92, 0xF3, 0xE0, 0xC3, 0x9F, +0x40, 0x02, 0xE1, 0x0C, 0x90, 0x92, 0xEC, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xFF, 0x90, 0xFD, +0x11, 0xF0, 0x90, 0x92, 0xFD, 0xEF, 0xF0, 0xF1, 0xA1, 0xF5, 0x83, 0xE0, 0xFE, 0xF1, 0x53, 0xF1, +0xDB, 0x54, 0x3F, 0xFE, 0x90, 0x92, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0xF9, 0xEE, 0xF0, +0xA3, 0xF1, 0xB6, 0x54, 0x0F, 0x33, 0x33, 0x33, 0x54, 0xF8, 0xFF, 0xF1, 0xAA, 0x54, 0x03, 0xFE, +0xEF, 0x24, 0x18, 0x2E, 0xFF, 0x90, 0x92, 0xFE, 0xF0, 0x90, 0x92, 0xED, 0xE0, 0x2F, 0xFF, 0x90, +0x92, 0xEC, 0xE0, 0x34, 0x00, 0xFE, 0x90, 0x92, 0xF0, 0xF1, 0x38, 0xC0, 0x07, 0xF1, 0x1D, 0x7D, +0x01, 0x12, 0x55, 0x36, 0xC0, 0x07, 0xF1, 0x1D, 0x7D, 0x04, 0x12, 0x55, 0x36, 0xAB, 0x07, 0xD0, +0x05, 0xD0, 0x07, 0x12, 0x5D, 0x98, 0x90, 0x92, 0xF5, 0xEF, 0xF1, 0x1C, 0xE4, 0xFD, 0x12, 0x55, +0x36, 0xEF, 0x54, 0xFC, 0x90, 0x92, 0xF2, 0xF0, 0x90, 0x92, 0xFE, 0xE0, 0xFF, 0x90, 0x92, 0xEE, +0xE4, 0x8F, 0xF0, 0x12, 0x07, 0x0A, 0x90, 0x92, 0xEE, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x7A, +0xD0, 0x90, 0x92, 0xEE, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xF1, 0x4A, 0x7D, 0x0F, 0x12, 0x55, 0x36, +0x90, 0x92, 0xEE, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0x90, 0x92, 0xEC, 0xEC, 0x8D, 0xF0, 0x12, 0x07, +0x0A, 0x90, 0x85, 0xB7, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xD3, 0x90, 0x92, 0xED, 0xE0, 0x9D, 0x90, +0x92, 0xEC, 0xE0, 0x9C, 0x40, 0x1B, 0x90, 0x85, 0xB8, 0xE0, 0x24, 0x01, 0xFD, 0x90, 0x85, 0xB7, +0xE0, 0x34, 0x00, 0xFC, 0xC3, 0x90, 0x92, 0xED, 0xE0, 0x9D, 0xF0, 0x90, 0x92, 0xEC, 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, +0x92, 0xF2, 0xE0, 0x24, 0x40, 0x60, 0x04, 0x24, 0x20, 0x70, 0x2C, 0x90, 0x86, 0x75, 0xE0, 0xFF, +0x12, 0x8D, 0x6B, 0x20, 0xE0, 0x02, 0xC1, 0x90, 0x90, 0x86, 0x87, 0xE0, 0x04, 0xF1, 0x1C, 0x12, +0x59, 0x20, 0xEF, 0x70, 0x02, 0xC1, 0x90, 0x90, 0x92, 0xF2, 0xE0, 0xFF, 0x12, 0x7B, 0x77, 0x90, +0x86, 0x88, 0xE0, 0x04, 0xF0, 0xC1, 0x90, 0x12, 0x9F, 0xD4, 0x30, 0xE0, 0x5A, 0x90, 0x92, 0xF5, +0xE0, 0xFF, 0x90, 0x92, 0xF1, 0xE0, 0x2F, 0xFF, 0x90, 0x92, 0xF0, 0xE0, 0x34, 0x00, 0xCF, 0x24, +0x08, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x92, 0xFB, 0xF1, 0x38, 0xEF, 0x64, 0x45, 0x70, 0x38, 0xF1, +0x27, 0x12, 0xC7, 0x9B, 0xEF, 0x64, 0x01, 0x70, 0x2E, 0xF1, 0x27, 0x12, 0xC7, 0x5E, 0xEF, 0x64, +0x01, 0x70, 0x24, 0x90, 0x92, 0xFF, 0x04, 0xF1, 0x26, 0xA3, 0xE0, 0xFD, 0x12, 0xC6, 0xB7, 0xEF, +0x70, 0x0D, 0x90, 0x92, 0xFD, 0xE0, 0xFD, 0x90, 0xFD, 0x11, 0xF1, 0x26, 0x12, 0xC7, 0x0F, 0x90, +0x92, 0xFD, 0xE0, 0x90, 0xFD, 0x11, 0xF0, 0xF1, 0x1D, 0x12, 0x59, 0x20, 0xEF, 0x60, 0x18, 0xF1, +0x1D, 0x90, 0x92, 0xF5, 0xE0, 0xFD, 0x90, 0x92, 0xF8, 0xE0, 0xFB, 0x12, 0x54, 0x02, 0xEF, 0x60, +0x06, 0x90, 0x92, 0xFF, 0x74, 0x01, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0xC3, 0x13, 0x30, 0xE0, 0x13, +0xF1, 0x1D, 0x90, 0x92, 0xF5, 0xE0, 0xFD, 0x12, 0x38, 0x10, 0xEF, 0x60, 0x06, 0x90, 0x92, 0xFF, +0x74, 0x01, 0xF0, 0x12, 0x8F, 0xF4, 0x54, 0x3F, 0x30, 0xE0, 0x0A, 0xF1, 0x1D, 0x90, 0x92, 0xF5, +0xE0, 0xFD, 0x12, 0x21, 0xB6, 0x90, 0x86, 0x72, 0xE0, 0xFF, 0x12, 0x8D, 0x6B, 0x30, 0xE0, 0x10, +0x90, 0x92, 0xFF, 0xE0, 0x70, 0x0A, 0xF1, 0x1D, 0x90, 0x92, 0xF5, 0xE0, 0xFD, 0x12, 0x4A, 0x3F, +0x12, 0x79, 0x00, 0xEF, 0x64, 0x01, 0x60, 0x07, 0x90, 0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x10, 0xF1, +0x41, 0x30, 0xE0, 0x06, 0x90, 0x01, 0x3F, 0x74, 0x04, 0xF0, 0x7F, 0x01, 0x12, 0x5F, 0xE9, 0x90, +0x01, 0x3F, 0xE0, 0x30, 0xE2, 0x02, 0xF1, 0x30, 0x12, 0x7A, 0xE7, 0xEF, 0x64, 0x01, 0x70, 0x36, +0x90, 0x86, 0x89, 0xE0, 0x04, 0xF0, 0x12, 0x6F, 0xE5, 0xAD, 0x07, 0xEF, 0x64, 0x01, 0x60, 0x1F, +0xF1, 0x30, 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, 0x5F, 0xE9, 0x80, 0x1D, 0xF1, +0x4A, 0x12, 0x7C, 0x0B, 0x80, 0x0E, 0xF1, 0x41, 0x20, 0xE0, 0x11, 0x90, 0x86, 0x72, 0xE0, 0x54, +0xFE, 0xF0, 0x80, 0x08, 0x90, 0x92, 0xF3, 0xE0, 0x04, 0xF0, 0x81, 0x75, 0x74, 0x25, 0x04, 0x90, +0x01, 0xC4, 0xF0, 0x74, 0xAC, 0xA3, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xF0, 0x90, 0x92, 0xF0, +0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xF0, 0x90, 0x92, 0xFB, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, +0x90, 0x86, 0x7A, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4, 0xFD, 0x02, 0x55, +0x36, 0x90, 0x86, 0x74, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x22, 0x90, 0x92, 0xEC, 0xE0, 0xFE, 0xA3, +0xE0, 0xFF, 0x22, 0x74, 0x00, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, 0xF5, 0x83, 0x22, 0x90, 0x01, +0x17, 0xE0, 0xFE, 0x90, 0x01, 0x16, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, 0x22, 0xE4, 0xFC, 0xED, +0x2C, 0x24, 0x00, 0xF1, 0x56, 0xE4, 0xF0, 0x0C, 0xEC, 0xB4, 0x18, 0xF3, 0xF1, 0x53, 0xEF, 0xF0, +0xEE, 0x54, 0x3F, 0xFF, 0xF1, 0xA1, 0xF5, 0x83, 0xF1, 0xB6, 0x54, 0xF0, 0xF0, 0xF1, 0xAA, 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, 0x22, 0x74, 0x03, 0x2D, 0xF5, 0x82, 0xE4, +0x34, 0xFB, 0xF5, 0x83, 0xE0, 0x22, 0xEF, 0xF0, 0x74, 0x02, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFB, +0xF5, 0x83, 0xE0, 0x22, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0x22, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, +0xE5, 0x6F, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x90, 0xF5, 0x83, 0x22, 0xE0, 0x7A, 0x00, 0x24, 0x00, +0xFF, 0xEA, 0x3E, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x85, 0x1E, 0xE0, 0xFF, +0x90, 0x85, 0x1D, 0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x70, 0x48, +0x90, 0x85, 0x1D, 0xE0, 0xFE, 0x75, 0xF0, 0x08, 0x90, 0x84, 0xCD, 0x12, 0x05, 0x28, 0xE0, 0xFD, +0xEE, 0x75, 0xF0, 0x08, 0xA4, 0x24, 0xCE, 0xF9, 0x74, 0x84, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0xAF, +0x05, 0x12, 0x88, 0xE7, 0x90, 0x85, 0x1D, 0x12, 0xAF, 0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, +0x60, 0x05, 0xE4, 0x90, 0x85, 0x1D, 0xF0, 0x7D, 0x68, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x12, 0x40, +0xB9, 0x90, 0x84, 0xC1, 0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x85, 0xB5, +0xE0, 0xFF, 0x70, 0x06, 0xA3, 0xE0, 0x64, 0x09, 0x60, 0x0A, 0xEF, 0x14, 0xFF, 0x90, 0x85, 0xB6, +0xE0, 0xB5, 0x07, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x60, 0x08, 0x90, 0x01, 0xC1, +0xE0, 0x44, 0x02, 0xF0, 0x22, 0xC0, 0x01, 0x90, 0x85, 0xB6, 0xE0, 0x75, 0xF0, 0x0F, 0xA4, 0x24, +0x1F, 0xF9, 0x74, 0x85, 0x35, 0xF0, 0xA8, 0x01, 0xFC, 0x7D, 0x01, 0xD0, 0x01, 0x7E, 0x00, 0x7F, +0x0F, 0x12, 0x02, 0xD0, 0x7D, 0xCC, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xB6, 0x12, 0xAF, +0xC4, 0xB4, 0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4, 0x90, 0x85, 0xB6, 0xF0, 0x22, 0x90, +0x92, 0x21, 0xEF, 0xF0, 0xA3, 0x12, 0x87, 0x79, 0x90, 0x93, 0x23, 0xE0, 0xFE, 0x04, 0xF0, 0x90, +0x00, 0x01, 0xEE, 0x12, 0x03, 0x4E, 0x74, 0x00, 0x2F, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, +0xC0, 0x03, 0xC0, 0x02, 0xC0, 0x01, 0x90, 0x92, 0x22, 0x12, 0x87, 0x70, 0x8B, 0x1B, 0x8A, 0x1C, +0x89, 0x1D, 0x75, 0x1E, 0x02, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x12, 0x6A, 0x21, 0x90, 0x92, +0x21, 0xE0, 0x24, 0x02, 0xF9, 0xE4, 0x34, 0xFB, 0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x02, 0xC0, +0x01, 0xA3, 0x12, 0x87, 0x70, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0x8B, 0x1B, 0xF5, 0x1C, 0x89, +0x1D, 0x90, 0x92, 0x22, 0x31, 0x21, 0xF5, 0x1E, 0xD0, 0x01, 0xD0, 0x02, 0xD0, 0x03, 0x02, 0x6A, +0x21, 0x12, 0x87, 0x70, 0x90, 0x00, 0x0E, 0x02, 0x03, 0x0F, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, +0xD0, 0x90, 0x92, 0x25, 0x12, 0x87, 0x79, 0x7F, 0x96, 0x7E, 0x02, 0x12, 0x66, 0x80, 0xEF, 0x60, +0x48, 0x12, 0xAF, 0x5E, 0xEC, 0x3E, 0xFE, 0xEF, 0x24, 0x01, 0xFF, 0xE4, 0x3E, 0xFE, 0x90, 0x92, +0x28, 0xEF, 0xF0, 0xEE, 0xFF, 0x90, 0xFD, 0x11, 0xF0, 0x90, 0x92, 0x28, 0xE0, 0xFD, 0x90, 0x02, +0x94, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x25, 0x31, 0x21, 0x24, 0x02, 0xFF, 0xE4, 0x33, 0xFE, +0x12, 0x5A, 0xA5, 0x90, 0x92, 0x28, 0xE0, 0x24, 0x18, 0xFF, 0x90, 0x92, 0x25, 0x12, 0x87, 0x70, +0x12, 0x56, 0xF4, 0x90, 0x02, 0x96, 0x74, 0x01, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x02, 0x8B, +0x24, 0xE4, 0x90, 0x92, 0x2B, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x92, 0x2B, 0xE0, 0x64, 0x01, +0xF0, 0x24, 0x91, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xB1, 0xA3, 0xF0, 0x12, 0x7C, 0x66, 0xBF, 0x01, +0x03, 0x12, 0x5B, 0x25, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x0F, 0x90, 0x85, 0xC8, 0xE0, 0xFF, 0x90, +0x85, 0xC7, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0xA5, 0x96, 0xC2, 0xAF, 0xF1, 0x5D, 0xBF, 0x01, 0x02, +0x31, 0xFA, 0xD2, 0xAF, 0x71, 0x03, 0x90, 0x92, 0x2C, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, +0x54, 0x7F, 0x45, 0xF0, 0x70, 0x0D, 0x7F, 0xFF, 0x12, 0x7B, 0x51, 0xEF, 0x04, 0xFD, 0x7F, 0xFF, +0x12, 0x7B, 0x3E, 0x31, 0x8E, 0x12, 0x84, 0x4D, 0x80, 0xA0, 0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, +0x18, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, 0xE0, 0x0E, 0xC3, 0x13, 0x30, 0xE0, 0x07, 0xD1, 0x88, +0xBF, 0x01, 0x06, 0x80, 0x02, 0x80, 0x00, 0x51, 0x1A, 0x22, 0x90, 0x85, 0xC8, 0xE0, 0xFF, 0x60, +0x03, 0xB4, 0x08, 0x0D, 0x71, 0x67, 0xBF, 0x01, 0x08, 0x51, 0x32, 0x90, 0x01, 0xE5, 0xE0, 0x04, +0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x51, 0xB1, 0x51, 0x42, 0xD0, 0xD0, 0x92, +0xAF, 0x22, 0xF1, 0x3E, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, +0x7B, 0x3E, 0xE4, 0xFF, 0x51, 0x65, 0x7D, 0x35, 0x7F, 0x27, 0x12, 0x7B, 0x3E, 0x90, 0x85, 0xC2, +0xE0, 0x54, 0xEF, 0xF0, 0x22, 0x90, 0x93, 0x1C, 0xEF, 0x12, 0xAC, 0x1E, 0x90, 0x01, 0x09, 0xE0, +0x7F, 0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x90, 0x93, 0x1C, 0xE0, 0x6F, 0x60, 0x32, 0xC3, 0x90, +0x93, 0x1E, 0xE0, 0x94, 0x88, 0x90, 0x93, 0x1D, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90, 0x01, 0xC0, +0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90, 0x93, 0x1D, 0xD1, 0x95, 0xD3, 0x90, 0x93, 0x1E, 0xE0, 0x94, +0x32, 0x90, 0x93, 0x1D, 0xE0, 0x94, 0x00, 0x40, 0xC3, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0, 0xBC, +0x22, 0x90, 0x85, 0xC2, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x85, 0xD0, 0xE0, 0xFD, 0x7F, 0x93, 0x12, +0x7B, 0x3E, 0x90, 0x85, 0xC6, 0xE0, 0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x05, 0x74, +0x10, 0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x90, 0xF0, 0x7F, 0x08, 0x12, 0x7B, 0x51, 0xEF, +0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x7B, 0x3E, 0x7F, 0x01, 0x51, 0x65, 0x7D, 0x34, 0x7F, 0x27, +0x12, 0x7B, 0x3E, 0x7F, 0x90, 0x71, 0xDC, 0x7F, 0x90, 0x12, 0x7B, 0x3E, 0x7F, 0x14, 0x7E, 0x00, +0x02, 0x7C, 0x9F, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x92, 0x90, 0xE0, 0x60, 0x25, +0x7F, 0x54, 0x7E, 0x09, 0x12, 0x70, 0x61, 0x71, 0x5B, 0xEF, 0x44, 0xFE, 0xFF, 0xEE, 0x44, 0x03, +0xFE, 0xED, 0x44, 0x04, 0xFD, 0xEC, 0x71, 0x5B, 0x90, 0x91, 0x66, 0x12, 0x04, 0xEB, 0x7F, 0x54, +0x7E, 0x09, 0x12, 0x71, 0x18, 0x90, 0x92, 0x8B, 0xE0, 0x70, 0x04, 0x90, 0x07, 0xCC, 0xF0, 0x90, +0x92, 0x93, 0xE0, 0x70, 0x0A, 0x90, 0x92, 0x90, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0x07, 0x90, +0x00, 0x1F, 0xE0, 0x54, 0xF0, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x92, 0x2E, 0x12, 0x04, +0xEB, 0x90, 0x92, 0x2E, 0x02, 0x87, 0x58, 0x90, 0x92, 0x84, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x48, +0x90, 0x02, 0x87, 0xE0, 0x60, 0x02, 0x80, 0x08, 0x90, 0x01, 0x00, 0xE0, 0x64, 0x3F, 0x60, 0x05, +0x75, 0x61, 0x01, 0x80, 0x40, 0x90, 0x86, 0x72, 0xE0, 0x30, 0xE0, 0x0B, 0x90, 0x02, 0x82, 0xE0, +0x60, 0x05, 0x75, 0x61, 0x02, 0x80, 0x2E, 0x90, 0x86, 0x7A, 0xE0, 0x30, 0xE0, 0x05, 0x75, 0x61, +0x08, 0x80, 0x22, 0x90, 0x02, 0x86, 0xE0, 0x20, 0xE1, 0x02, 0x80, 0x07, 0x90, 0x02, 0x86, 0xE0, +0x30, 0xE3, 0x05, 0x75, 0x61, 0x04, 0x80, 0x0D, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x05, 0x75, 0x61, +0x40, 0x80, 0x02, 0x80, 0x0F, 0x90, 0x01, 0xB9, 0x74, 0x08, 0xF0, 0x90, 0x01, 0xB8, 0xE5, 0x61, +0xF0, 0x7F, 0x00, 0x22, 0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01, 0x22, 0x12, 0x7B, 0x51, 0xEF, +0x44, 0x01, 0xFD, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x02, 0x71, 0xDC, 0x7F, +0x02, 0xD1, 0x80, 0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF, 0xF0, 0x90, 0x06, 0xB7, 0x74, +0x09, 0xF0, 0x90, 0x06, 0xB4, 0x74, 0x86, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x12, 0x90, 0xD7, +0x90, 0x85, 0xBF, 0x74, 0x01, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x85, +0xBF, 0xE0, 0x90, 0x93, 0x29, 0xF0, 0x6F, 0x70, 0x02, 0xA1, 0x1E, 0xEF, 0x14, 0x60, 0x42, 0x14, +0x60, 0x6C, 0x14, 0x70, 0x02, 0x81, 0xCA, 0x14, 0x70, 0x02, 0x81, 0xF5, 0x24, 0x04, 0x60, 0x02, +0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x04, 0xB1, 0x32, 0xA1, 0x1E, 0x90, 0x93, 0x29, +0xE0, 0xB4, 0x02, 0x04, 0xB1, 0x23, 0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, 0x04, 0xB1, +0x49, 0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, 0x64, 0x01, 0x60, 0x02, 0xA1, 0x1E, 0xB1, 0x25, 0xA1, +0x1E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, 0x04, 0xB1, 0x36, 0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, +0xB4, 0x02, 0x04, 0x91, 0x0D, 0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, 0x04, 0xB1, 0x4D, +0xA1, 0x1E, 0x90, 0x93, 0x29, 0xE0, 0x60, 0x02, 0xA1, 0x1E, 0xB1, 0x7A, 0xA1, 0x1E, 0x90, 0x93, +0x29, 0xE0, 0xB4, 0x04, 0x04, 0xB1, 0x9F, 0x80, 0x75, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x01, 0x05, +0x12, 0x97, 0xEE, 0x80, 0x69, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, 0x04, 0xB1, 0x97, 0x80, 0x5E, +0x90, 0x93, 0x29, 0xE0, 0x70, 0x58, 0xB1, 0x9A, 0x80, 0x54, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x04, +0x04, 0xB1, 0x55, 0x80, 0x49, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x01, 0x04, 0xB1, 0x8E, 0x80, 0x3E, +0x90, 0x93, 0x29, 0xE0, 0xB4, 0x02, 0x04, 0xB1, 0x40, 0x80, 0x33, 0x90, 0x93, 0x29, 0xE0, 0x70, +0x2D, 0xB1, 0x8C, 0x80, 0x29, 0x90, 0x93, 0x29, 0xE0, 0xB4, 0x03, 0x04, 0xB1, 0xA6, 0x80, 0x1E, +0x90, 0x93, 0x29, 0xE0, 0xB4, 0x01, 0x04, 0xB1, 0x7E, 0x80, 0x13, 0x90, 0x93, 0x29, 0xE0, 0xB4, +0x02, 0x04, 0xB1, 0x60, 0x80, 0x08, 0x90, 0x93, 0x29, 0xE0, 0x70, 0x02, 0xB1, 0x7C, 0xD0, 0xD0, +0x92, 0xAF, 0x22, 0x91, 0x0D, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0, 0xE4, 0x90, 0x85, 0xBF, +0xF0, 0x22, 0xB1, 0x36, 0x80, 0xEF, 0xE4, 0xFD, 0xFF, 0xB1, 0x72, 0x44, 0x40, 0xF0, 0x81, 0x10, +0x71, 0xE4, 0x90, 0x85, 0xBF, 0x74, 0x03, 0xF0, 0x22, 0xB1, 0x4D, 0x80, 0xD8, 0xE4, 0xFD, 0xFF, +0x12, 0x90, 0xDD, 0x81, 0x10, 0x7D, 0x22, 0x7F, 0xFF, 0xB1, 0x72, 0x44, 0x40, 0xF0, 0x80, 0xE2, +0x71, 0xE4, 0x7D, 0x24, 0xB1, 0x70, 0x54, 0xBF, 0xF0, 0x90, 0x85, 0xBF, 0x74, 0x04, 0xF0, 0x22, +0x7F, 0x6F, 0x12, 0x90, 0xDD, 0x90, 0x05, 0x27, 0xE0, 0x22, 0x81, 0x10, 0xB1, 0x7A, 0x7D, 0x1F, +0xB1, 0x70, 0x54, 0xBF, 0xF0, 0x90, 0x85, 0xBF, 0x74, 0x04, 0xF0, 0x22, 0xB1, 0x7A, 0x7D, 0x21, +0x7F, 0xFF, 0x12, 0x90, 0xDD, 0x80, 0xAB, 0x02, 0x97, 0xF4, 0xB1, 0x7A, 0x02, 0x97, 0xEE, 0xD1, +0x78, 0x7D, 0x23, 0x02, 0x97, 0xF0, 0x7D, 0x25, 0xB1, 0x70, 0x54, 0xBF, 0xF0, 0x90, 0x85, 0xBF, +0x74, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x7F, 0x02, 0x12, 0x7B, 0x51, +0xEF, 0x54, 0xFE, 0xFD, 0x7F, 0x02, 0x12, 0x7B, 0x3E, 0x90, 0x01, 0x00, 0x74, 0x3F, 0xF0, 0x90, +0x01, 0x34, 0x74, 0x08, 0xF0, 0x90, 0x01, 0x01, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05, 0x53, 0xE0, +0x44, 0x20, 0xF0, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xEF, 0x60, 0x49, 0x90, 0x88, 0xCE, 0xE0, 0xFF, +0x60, 0x03, 0x12, 0x7B, 0x8A, 0x90, 0x01, 0xC7, 0xE4, 0xF0, 0x12, 0xAF, 0x5E, 0xEC, 0x3E, 0x90, +0x85, 0xB7, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x06, 0x09, 0xE0, 0x54, 0xFE, 0xF0, 0x7D, 0x35, 0x7F, +0xFF, 0x12, 0x90, 0xDD, 0xB1, 0xB4, 0x90, 0x02, 0x86, 0xE0, 0x44, 0x04, 0xF0, 0x12, 0x72, 0x79, +0xD1, 0x51, 0x12, 0x90, 0xD7, 0x12, 0x76, 0xE6, 0x90, 0x01, 0x34, 0x74, 0x08, 0xF0, 0xFD, 0xE4, +0xFF, 0x02, 0x7C, 0xA9, 0x7D, 0x08, 0xE4, 0xFF, 0x12, 0x7C, 0x41, 0x90, 0x06, 0x90, 0xE0, 0x54, +0xF0, 0xF0, 0x90, 0x02, 0x86, 0xE0, 0x54, 0xFB, 0xF0, 0xD1, 0x52, 0x12, 0x9F, 0xEC, 0x02, 0x9B, +0x27, 0x22, 0xF1, 0x11, 0x12, 0x77, 0x89, 0x90, 0x01, 0x3F, 0x74, 0x04, 0xF0, 0x90, 0x84, 0xC5, +0xE0, 0xFF, 0xB4, 0x01, 0x07, 0x90, 0xFD, 0x00, 0xE0, 0x54, 0xEF, 0xF0, 0xEF, 0xB4, 0x01, 0x07, +0x90, 0xFE, 0x10, 0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x22, +0x12, 0x7B, 0x3E, 0x90, 0x01, 0x01, 0xE0, 0x22, 0x90, 0x85, 0xBF, 0xE0, 0x64, 0x02, 0x7F, 0x01, +0x60, 0x02, 0x7F, 0x00, 0x22, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x7F, 0x14, 0x7E, 0x00, +0x02, 0x7C, 0x9F, 0xE4, 0x90, 0x92, 0x29, 0xF0, 0xA3, 0xF0, 0xD1, 0xF1, 0xEF, 0x64, 0x01, 0x60, +0x39, 0xC3, 0x90, 0x92, 0x2A, 0xE0, 0x94, 0x88, 0x90, 0x92, 0x29, 0xE0, 0x94, 0x13, 0x40, 0x0F, +0x90, 0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0xFD, 0xF0, 0x80, 0x1B, 0x90, +0x92, 0x29, 0xD1, 0x95, 0xD3, 0x90, 0x92, 0x2A, 0xE0, 0x94, 0x32, 0x90, 0x92, 0x29, 0xE0, 0x94, +0x00, 0x40, 0xC7, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xC0, 0x90, 0x01, 0xC7, 0x74, 0xFE, 0xF0, +0x22, 0x90, 0x01, 0x9A, 0xE0, 0x54, 0xC0, 0x44, 0x0B, 0xF1, 0x09, 0x90, 0x01, 0x98, 0xE0, 0x54, +0xC0, 0x7F, 0x00, 0xB4, 0x40, 0x02, 0x7F, 0x01, 0x22, 0xF0, 0x7F, 0x0A, 0x7E, 0x00, 0x02, 0x7C, +0x9F, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xE4, 0xFD, 0x7F, 0x8F, 0x12, 0x7B, 0x3E, 0xD0, +0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x9F, 0xAD, 0xBF, 0x01, +0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x02, 0x91, 0x17, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x01, +0xC4, 0x74, 0x3E, 0xF0, 0x74, 0xB7, 0xA3, 0xF0, 0x7F, 0x90, 0x12, 0x7B, 0x51, 0xEF, 0x20, 0xE0, +0xF7, 0x74, 0x3E, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xB7, 0xA3, 0xF0, 0x22, 0x7D, 0x02, 0x90, +0x01, 0xC4, 0x74, 0x5D, 0xF0, 0x74, 0xB7, 0xA3, 0xF0, 0x90, 0x92, 0x88, 0xE0, 0xFF, 0xED, 0xC3, +0x9F, 0x50, 0x18, 0xED, 0x25, 0xE0, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01, 0xB8, +0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00, 0x22, 0x0D, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0x90, 0x85, +0xBC, 0xE0, 0xFF, 0x30, 0xE0, 0x3E, 0x90, 0x85, 0xC0, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02, 0x7E, +0x01, 0x90, 0x85, 0xBF, 0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70, 0x24, +0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0xE1, 0x24, 0x12, 0x9F, 0x30, 0x90, 0x85, 0xC0, 0xE0, 0xB4, +0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C, 0x80, 0x09, 0x90, 0x85, 0xC0, 0xE0, 0x70, 0x06, 0xFD, 0x7F, +0x04, 0x12, 0x9D, 0x7E, 0x22, 0xE4, 0x90, 0x84, 0xC1, 0x12, 0x96, 0x3F, 0x90, 0x92, 0x81, 0xF0, +0x22, 0xE4, 0xF5, 0x40, 0xF5, 0x41, 0xF5, 0x42, 0x75, 0x43, 0x80, 0xAD, 0x40, 0x7F, 0x50, 0x12, +0x7B, 0x3E, 0xAD, 0x41, 0x7F, 0x51, 0x12, 0x7B, 0x3E, 0xAD, 0x42, 0x7F, 0x52, 0x12, 0x7B, 0x3E, +0xAD, 0x43, 0x7F, 0x53, 0x02, 0x7B, 0x3E, 0x75, 0x48, 0x12, 0xE4, 0xF5, 0x49, 0x75, 0x4A, 0x07, +0x75, 0x4B, 0x32, 0xF5, 0x50, 0x90, 0x01, 0x30, 0xE5, 0x48, 0xF0, 0xA3, 0xE5, 0x49, 0xF0, 0xA3, +0xE5, 0x4A, 0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0x90, 0x01, 0x20, 0xE5, 0x50, 0xF0, 0x22, 0x12, 0x75, +0xB6, 0x12, 0x75, 0x58, 0x11, 0x07, 0x11, 0x3A, 0x80, 0xA7, 0x75, 0x52, 0x06, 0x75, 0x53, 0x01, +0x75, 0x54, 0x03, 0x75, 0x55, 0x62, 0x90, 0x01, 0x38, 0xE5, 0x52, 0xF0, 0xA3, 0xE5, 0x53, 0xF0, +0xA3, 0xE5, 0x54, 0xF0, 0xA3, 0xE5, 0x55, 0xF0, 0x22, 0x12, 0x7C, 0x4E, 0x90, 0x84, 0xC5, 0xEF, +0xF0, 0x11, 0x2E, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0, 0x90, 0x04, 0x23, 0xE0, 0x44, 0x80, 0xF0, +0x90, 0x00, 0x17, 0xE0, 0x54, 0xFC, 0x44, 0x04, 0xFD, 0x7F, 0x17, 0x12, 0x7B, 0x3E, 0x90, 0x00, +0x38, 0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x38, 0x12, 0x7B, 0x3E, 0x02, 0x68, 0xE2, 0x90, 0x01, 0xE4, +0x74, 0x01, 0xF0, 0xA3, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x84, 0xA1, 0x74, 0x02, 0xF0, 0xA3, 0x74, +0x10, 0xF0, 0x90, 0x84, 0xA7, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0x22, 0xE4, 0xFB, 0xFA, +0xFD, 0x7F, 0x01, 0x12, 0x86, 0x4E, 0x90, 0x92, 0x32, 0xEF, 0xF0, 0x60, 0xF0, 0x90, 0x84, 0xC1, +0xE0, 0xFF, 0x70, 0x04, 0xA3, 0xE0, 0x60, 0xE5, 0xC2, 0xAF, 0xEF, 0x30, 0xE0, 0x0F, 0x90, 0x84, +0xC1, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0x12, 0x2D, 0xBD, 0x12, 0x91, 0xE7, 0x31, 0x08, 0x30, +0xE1, 0x06, 0x54, 0xFD, 0xF0, 0x12, 0x60, 0x5D, 0x31, 0x08, 0x30, 0xE2, 0x06, 0x54, 0xFB, 0xF0, +0x12, 0x6A, 0x6D, 0x31, 0x08, 0x30, 0xE4, 0x0C, 0x54, 0xEF, 0xF0, 0x12, 0x6F, 0x22, 0xBF, 0x01, +0x03, 0x12, 0xAC, 0x25, 0xD2, 0xAF, 0x80, 0xB5, 0xD2, 0xAF, 0xC2, 0xAF, 0x90, 0x84, 0xC1, 0xE0, +0xFF, 0x22, 0x8F, 0x0D, 0x7F, 0x02, 0x12, 0x86, 0x27, 0x90, 0x84, 0xC1, 0xE0, 0x45, 0x0D, 0xF0, +0x22, 0x12, 0x40, 0xB9, 0x7F, 0x02, 0x80, 0xEA, 0x90, 0x86, 0x72, 0xE0, 0x30, 0xE0, 0x04, 0x7F, +0x10, 0x31, 0x12, 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, 0x34, 0xF0, 0x74, 0xB9, 0xA3, 0xF0, 0x12, 0x75, 0x28, 0xE5, 0x56, +0x30, 0xE1, 0x02, 0x51, 0x6C, 0xE5, 0x56, 0x30, 0xE2, 0x03, 0x12, 0xA6, 0x15, 0xE5, 0x57, 0x30, +0xE0, 0x02, 0x51, 0x38, 0xE5, 0x58, 0x30, 0xE1, 0x02, 0x91, 0x72, 0xE5, 0x58, 0x30, 0xE0, 0x03, +0x12, 0xB7, 0x8E, 0xE5, 0x58, 0x30, 0xE4, 0x02, 0x51, 0x6B, 0xE5, 0x59, 0x30, 0xE1, 0x04, 0x7F, +0x04, 0x31, 0x12, 0xE5, 0x59, 0x30, 0xE4, 0x03, 0x12, 0xA5, 0x39, 0xE5, 0x59, 0x30, 0xE5, 0x02, +0x31, 0xCF, 0xE5, 0x59, 0x30, 0xE6, 0x02, 0x31, 0xF6, 0x74, 0x34, 0x04, 0x90, 0x01, 0xC4, 0xF0, +0x74, 0xB9, 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, +0x85, 0xC1, 0x12, 0x9C, 0x0C, 0x30, 0xE0, 0x19, 0xEF, 0x54, 0xBF, 0x51, 0x24, 0x30, 0xE0, 0x06, +0xE0, 0x44, 0x01, 0xF0, 0x80, 0x08, 0xE0, 0x54, 0xFE, 0x51, 0x2D, 0x74, 0x04, 0xF0, 0x12, 0xA5, +0x96, 0xE4, 0xFF, 0x02, 0x68, 0x8F, 0x90, 0x85, 0xC1, 0xE0, 0xFF, 0x12, 0x8D, 0x6B, 0x30, 0xE0, +0x1E, 0xEF, 0x54, 0x7F, 0x51, 0x24, 0x30, 0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x07, 0xE0, +0x54, 0xFD, 0x51, 0x2D, 0x04, 0xF0, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x03, 0x12, 0xA5, 0x96, 0x7F, +0x01, 0x02, 0x68, 0x8F, 0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x85, 0xC2, 0x22, 0xF0, 0x90, 0x01, +0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x22, 0x91, 0xBB, 0x90, 0x92, 0x67, 0xEF, 0xF0, 0x30, +0xE0, 0x05, 0x7D, 0x01, 0xE4, 0x80, 0x02, 0xE4, 0xFD, 0xFF, 0x12, 0x57, 0x82, 0x90, 0x92, 0x67, +0xE0, 0x30, 0xE6, 0x11, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4, 0xF0, 0x80, 0x06, 0x90, +0x01, 0x2F, 0x74, 0x80, 0xF0, 0x51, 0x76, 0xFB, 0x02, 0x51, 0x7D, 0x22, 0x90, 0x85, 0xC5, 0xE0, +0x60, 0x03, 0x12, 0xA4, 0xD1, 0x22, 0x90, 0x85, 0xD7, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x90, 0x85, +0xDE, 0xE0, 0x22, 0xE4, 0x90, 0x92, 0x56, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x92, 0x9F, 0x12, +0x87, 0x58, 0x90, 0x92, 0x9B, 0x12, 0x87, 0x64, 0xC3, 0x12, 0x04, 0xB4, 0x40, 0x50, 0x90, 0x85, +0xC1, 0xE0, 0x90, 0x92, 0x9F, 0x30, 0xE0, 0x14, 0x71, 0xFA, 0x74, 0x0A, 0x9E, 0x2F, 0xFF, 0x90, +0x85, 0xFB, 0xE0, 0x24, 0x04, 0x2F, 0xFF, 0x90, 0x92, 0xD0, 0x80, 0x0A, 0x71, 0xFA, 0x74, 0x0A, +0x9E, 0x2F, 0xFF, 0x90, 0x92, 0xD1, 0xE0, 0xFE, 0xC3, 0xEF, 0x9E, 0x90, 0x92, 0x57, 0xF0, 0x90, +0x92, 0x57, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x50, 0x15, 0x74, 0xA3, 0x2F, 0x91, 0x12, 0xE0, 0x04, +0xF0, 0x90, 0x85, 0xDB, 0xE0, 0x04, 0xF0, 0xE0, 0xFD, 0x7F, 0xFE, 0x12, 0x7B, 0x3E, 0x90, 0x85, +0xDB, 0xE0, 0xFF, 0xD3, 0x90, 0x92, 0xD3, 0xE0, 0x9F, 0x90, 0x92, 0xD2, 0xE0, 0x94, 0x00, 0x40, +0x02, 0x61, 0xC6, 0x71, 0xD8, 0x71, 0xCF, 0x50, 0x1C, 0x71, 0xE2, 0x90, 0x92, 0x58, 0xE0, 0xD3, +0x9F, 0x40, 0x0A, 0x90, 0x92, 0x56, 0xE0, 0x90, 0x92, 0x59, 0xF0, 0x80, 0x08, 0x90, 0x92, 0x56, +0xE0, 0x04, 0xF0, 0x80, 0xE0, 0x71, 0xD8, 0x71, 0xCF, 0x50, 0x2C, 0x71, 0xE2, 0xC3, 0x90, 0x92, +0xD3, 0xE0, 0x9F, 0xFF, 0x90, 0x92, 0xD2, 0xE0, 0x94, 0x00, 0xFE, 0x90, 0x92, 0x58, 0xE0, 0xD3, +0x9F, 0xE4, 0x9E, 0x40, 0x0A, 0x90, 0x92, 0x56, 0xE0, 0x90, 0x92, 0x5A, 0xF0, 0x80, 0x08, 0x90, +0x92, 0x56, 0xE0, 0x04, 0xF0, 0x80, 0xD0, 0x90, 0x92, 0x59, 0xE0, 0x90, 0x85, 0xE0, 0xF0, 0x90, +0x92, 0x5A, 0xE0, 0x90, 0x85, 0xE1, 0x71, 0xC7, 0x94, 0x0A, 0x40, 0x0A, 0xEF, 0x24, 0xF6, 0x90, +0x85, 0xD8, 0xF0, 0xE4, 0x80, 0x09, 0xE4, 0x90, 0x85, 0xD8, 0x71, 0xC7, 0x74, 0x0A, 0x9F, 0x90, +0x85, 0xD7, 0xF0, 0x90, 0x85, 0xE0, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x85, 0xDE, 0xF0, +0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x05, 0x90, 0x92, 0xD0, 0x80, 0x03, 0x90, 0x92, 0xD1, 0xE0, +0xFF, 0x90, 0x85, 0xDE, 0xE0, 0x2F, 0x04, 0xF0, 0x90, 0x85, 0xDE, 0xE0, 0xC3, 0x94, 0x0A, 0x50, +0x03, 0x74, 0x0A, 0xF0, 0x90, 0x85, 0xDE, 0xE0, 0x24, 0x02, 0xF0, 0x51, 0x76, 0xFB, 0x12, 0x51, +0x7D, 0xE4, 0xFF, 0x12, 0x69, 0x33, 0x22, 0xF0, 0x90, 0x85, 0xE0, 0xE0, 0xFF, 0xC3, 0x22, 0x90, +0x92, 0x56, 0xE0, 0xFF, 0xC3, 0x94, 0x2D, 0x22, 0xE4, 0x90, 0x92, 0x58, 0xF0, 0x90, 0x92, 0x56, +0xF0, 0x22, 0x74, 0xA3, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x92, +0x58, 0xE0, 0x2F, 0xF0, 0x90, 0x92, 0xD4, 0xE0, 0xFF, 0x22, 0x12, 0x87, 0x64, 0x90, 0x92, 0x9B, +0x12, 0x87, 0x58, 0x12, 0x87, 0x30, 0x78, 0x0A, 0x12, 0x04, 0xC5, 0x90, 0x85, 0xDD, 0xE0, 0xFE, +0xC3, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0x92, 0xF5, 0x83, 0x22, 0xE4, 0xFE, 0x74, 0xA3, 0x2E, 0x91, +0x12, 0xE4, 0xF0, 0x0E, 0xEE, 0xB4, 0x2D, 0xF4, 0xE4, 0x90, 0x85, 0xDC, 0xF0, 0x90, 0x85, 0xDB, +0xF0, 0x90, 0x85, 0xDF, 0xF0, 0xEF, 0xB4, 0x01, 0x07, 0xA3, 0x74, 0x2D, 0xF0, 0xE4, 0xA3, 0xF0, +0x22, 0x90, 0x93, 0x1F, 0x12, 0x87, 0x79, 0x12, 0x71, 0x54, 0x90, 0x85, 0xC5, 0xE0, 0xFF, 0x12, +0x60, 0xD0, 0x90, 0x85, 0xC5, 0xE0, 0x60, 0x19, 0x90, 0x93, 0x1F, 0x12, 0x87, 0x70, 0x12, 0x8D, +0x74, 0x54, 0x0F, 0xFF, 0x12, 0x8C, 0x80, 0xFD, 0x12, 0x6A, 0xB8, 0x51, 0x76, 0xFB, 0x12, 0x51, +0x7D, 0x22, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, 0xE0, 0x40, 0x90, 0x85, 0xC0, 0xE0, 0x7E, 0x00, +0xB4, 0x02, 0x02, 0x7E, 0x01, 0x90, 0x85, 0xBF, 0xE0, 0x7D, 0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, +0xED, 0x4E, 0x70, 0x26, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x03, 0x02, 0xB7, 0x24, 0x12, 0xA5, 0xCF, +0x90, 0x85, 0xC0, 0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08, 0x80, 0x0A, 0x90, 0x85, 0xC0, +0xE0, 0xB4, 0x04, 0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x9D, 0x7E, 0x22, 0xE4, 0x90, 0x92, 0x69, 0xF0, +0xA3, 0xF0, 0x7F, 0x83, 0x12, 0x7B, 0x51, 0x90, 0x92, 0x68, 0xEF, 0xF0, 0x7F, 0x83, 0x12, 0x7B, +0x51, 0xAE, 0x07, 0x90, 0x92, 0x68, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3, 0x90, 0x92, 0x6A, +0xE0, 0x94, 0x64, 0x90, 0x92, 0x69, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01, 0xC0, 0xE0, 0x44, +0x40, 0xF0, 0x90, 0x92, 0x68, 0xE0, 0xFF, 0x22, 0x90, 0x92, 0x69, 0xE4, 0x75, 0xF0, 0x01, 0x12, +0x07, 0x0A, 0x80, 0xBE, 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, 0x05, 0xF0, 0x74, 0xBD, 0xA3, 0xF0, 0x12, 0x6C, 0xBC, 0x74, +0x05, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0xBD, 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, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, +0x00, 0xC0, 0x05, 0xC0, 0x07, 0x7D, 0x56, 0x90, 0x01, 0xC4, 0xED, 0xF0, 0x74, 0xBD, 0xFF, 0xA3, +0xF0, 0xED, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0xA3, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0x05, 0xD0, 0xD0, +0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, +0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x88, 0xE7, 0xE0, 0x04, 0xF0, 0x90, 0x85, 0xBC, 0xE0, 0xFF, 0x30, +0xE0, 0x05, 0x12, 0x9F, 0x49, 0x60, 0x1B, 0x90, 0x85, 0xC5, 0xE0, 0x70, 0x04, 0xEF, 0x30, 0xE0, +0x0B, 0x90, 0x85, 0xC8, 0xE0, 0x64, 0x02, 0x60, 0x09, 0x12, 0xA0, 0x9F, 0x90, 0x01, 0xE6, 0xE0, +0x04, 0xF0, 0x22, 0xE4, 0xFF, 0x12, 0x77, 0x39, 0xBF, 0x01, 0x13, 0x90, 0x85, 0xC5, 0xE0, 0x60, +0x0D, 0x12, 0x9F, 0xE5, 0x64, 0x02, 0x60, 0x03, 0x02, 0x77, 0x61, 0x12, 0x79, 0x41, 0x22, 0x90, +0x85, 0xC5, 0xE0, 0x70, 0x07, 0x90, 0x85, 0xBC, 0xE0, 0x30, 0xE0, 0x13, 0x90, 0x85, 0xBC, 0xE0, +0x30, 0xE0, 0x09, 0x12, 0x9F, 0xAD, 0xBF, 0x01, 0x06, 0x02, 0x9F, 0x50, 0x12, 0x9F, 0x68, 0x22, +0x7D, 0x07, 0xAF, 0x62, 0xED, 0x30, 0xE0, 0x21, 0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, 0x44, 0xD1, +0x53, 0xEF, 0x90, 0x89, 0x46, 0xD1, 0x53, 0xEF, 0x90, 0x89, 0x48, 0xD1, 0x53, 0xEF, 0x90, 0x89, +0x4A, 0xD1, 0x53, 0xEF, 0x90, 0x89, 0x4C, 0xD1, 0x5E, 0xED, 0x30, 0xE1, 0x09, 0x75, 0xF0, 0x12, +0xEF, 0x90, 0x89, 0x40, 0xD1, 0x5E, 0xED, 0x30, 0xE2, 0x0C, 0x75, 0xF0, 0x12, 0xEF, 0x90, 0x89, +0x42, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xD1, 0x66, 0xE0, 0x54, 0xBF, 0x44, 0x80, 0xFE, 0xD1, 0x66, +0xEE, 0xF0, 0x22, 0x12, 0x05, 0x28, 0xE4, 0xF0, 0xA3, 0xF0, 0x75, 0xF0, 0x12, 0x22, 0x12, 0x05, +0x28, 0xE4, 0xF0, 0xA3, 0xF0, 0x22, 0xEF, 0xC4, 0x54, 0xF0, 0x24, 0x03, 0xF5, 0x82, 0xE4, 0x34, +0x81, 0xF5, 0x83, 0x22, 0x7B, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x90, 0x89, 0x1B, 0x12, 0x87, 0x79, +0x7B, 0xFF, 0x7A, 0x82, 0x79, 0x00, 0x90, 0x89, 0x1E, 0x12, 0x87, 0x79, 0x7A, 0x82, 0x79, 0x3F, +0x90, 0x89, 0x21, 0x12, 0x87, 0x79, 0x7A, 0x82, 0x79, 0xE1, 0x90, 0x89, 0x27, 0x12, 0x87, 0x79, +0x7A, 0x82, 0x79, 0xF5, 0x90, 0x89, 0x2A, 0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, 0x1D, 0x90, 0x89, +0x2D, 0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, 0x31, 0x90, 0x89, 0x33, 0x12, 0x87, 0x79, 0x7A, 0x83, +0x79, 0x59, 0x90, 0x89, 0x36, 0x12, 0x87, 0x79, 0x7A, 0x83, 0x79, 0x81, 0x90, 0x89, 0x39, 0x12, +0x87, 0x79, 0xE4, 0x90, 0x92, 0xD6, 0xF0, 0x90, 0x92, 0x29, 0xF0, 0x90, 0x92, 0x29, 0xE0, 0xFF, +0xC3, 0x94, 0x05, 0x50, 0x10, 0x74, 0xE7, 0x2F, 0x12, 0x96, 0x79, 0xE4, 0xF0, 0x90, 0x92, 0x29, +0xE0, 0x04, 0xF0, 0x80, 0xE6, 0x22, 0x90, 0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x01, 0xC7, +0xE4, 0xF0, 0x22, 0x90, 0x01, 0xCF, 0xE0, 0x90, 0x92, 0x56, 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, 0x75, 0xB6, +0x90, 0x00, 0x03, 0xE0, 0x54, 0xFB, 0xFD, 0x7F, 0x03, 0x12, 0x7B, 0x3E, 0x80, 0xFE, 0x22, 0xE4, +0xFF, 0x02, 0x2D, 0xBD, 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, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x13, 0xED, 0xF0, 0xA3, +0xEB, 0xF0, 0x90, 0x93, 0x12, 0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0x12, 0xC2, 0xB7, 0x90, 0x93, 0x12, +0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, 0x93, 0x13, 0xE0, 0x60, 0x06, 0x12, 0xC8, 0xA1, 0x44, 0x80, +0xF0, 0xAF, 0x05, 0x74, 0x20, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xC0, +0xF0, 0x12, 0xC8, 0xA1, 0x54, 0xC0, 0xF0, 0x90, 0x93, 0x15, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x18, +0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x00, 0x8B, 0xE0, 0xD3, 0x94, +0x03, 0x74, 0x10, 0x40, 0x08, 0x12, 0xC0, 0x38, 0x74, 0x04, 0xF0, 0x80, 0x05, 0x12, 0xC0, 0x38, +0xE4, 0xF0, 0xAF, 0x05, 0x12, 0xC0, 0x2F, 0xF5, 0x83, 0xE0, 0x54, 0x01, 0xFE, 0x90, 0x93, 0x14, +0xE0, 0x25, 0xE0, 0x25, 0xE0, 0xFB, 0xEE, 0x44, 0x02, 0x4B, 0xFE, 0x11, 0x2F, 0xF5, 0x83, 0xEE, +0xF0, 0x74, 0x11, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x74, 0xFF, 0xF0, 0x74, 0x29, +0x2F, 0x11, 0x51, 0x54, 0xF7, 0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x74, +0x12, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0x22, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, +0x22, 0xE0, 0xFE, 0x24, 0x28, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFF, 0x74, 0x29, +0x2E, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0x90, 0x88, 0xD9, 0x11, 0xF8, 0x11, +0x41, 0xFD, 0x90, 0x92, 0x07, 0xE0, 0x24, 0x2C, 0x51, 0xAB, 0x90, 0x92, 0x07, 0xE0, 0x2F, 0x24, +0x30, 0xA3, 0xF0, 0xE0, 0xFD, 0x24, 0x04, 0x51, 0xA3, 0xE0, 0xFE, 0x74, 0x05, 0x2D, 0x31, 0xB6, +0x12, 0xAF, 0x66, 0xEC, 0x3E, 0x90, 0x88, 0x80, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x08, 0xE0, +0x24, 0x0C, 0xF9, 0xE4, 0x34, 0xFC, 0x31, 0x09, 0x75, 0x1E, 0x04, 0x7B, 0x01, 0x7A, 0x88, 0x79, +0x82, 0x12, 0x6A, 0x21, 0x90, 0x92, 0x08, 0xE0, 0x24, 0x14, 0xF0, 0xE0, 0xFD, 0x24, 0x01, 0x31, +0xC6, 0x2D, 0x31, 0xBE, 0x12, 0xAF, 0x66, 0xEC, 0x3E, 0x90, 0x88, 0x86, 0xF0, 0xA3, 0xEF, 0xF0, +0x90, 0x88, 0xDA, 0x11, 0xF8, 0x90, 0x88, 0x7C, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x4E, 0x60, 0x11, +0x90, 0x92, 0x07, 0xE0, 0x31, 0x03, 0x8F, 0x1E, 0x7B, 0x01, 0x7A, 0x88, 0x79, 0x8A, 0x12, 0x6A, +0x21, 0x90, 0x88, 0xDB, 0x11, 0xF8, 0x31, 0x03, 0x90, 0x88, 0x7E, 0xA3, 0xE0, 0xF5, 0x1E, 0x7B, +0x01, 0x7A, 0x88, 0x79, 0xAA, 0x02, 0x6A, 0x21, 0xE0, 0xFF, 0x12, 0x7B, 0x2A, 0x90, 0x92, 0x07, +0xEF, 0xF0, 0x22, 0x24, 0x00, 0xF9, 0xE4, 0x34, 0xFC, 0x75, 0x1B, 0x01, 0xF5, 0x1C, 0x89, 0x1D, +0x22, 0xEF, 0x60, 0x04, 0x31, 0x19, 0x11, 0x5A, 0x22, 0xE4, 0xFD, 0xFC, 0x90, 0x88, 0xD8, 0xE0, +0xFF, 0x51, 0xB7, 0xAB, 0x05, 0x74, 0x01, 0x2B, 0x31, 0xC6, 0x2B, 0x31, 0xBE, 0x12, 0xAF, 0xDB, +0x90, 0x88, 0x76, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x03, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, +0x83, 0xE0, 0xFE, 0x74, 0x02, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0x31, 0xAD, 0x90, 0x88, 0x78, +0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x05, 0x2B, 0x31, 0xB6, 0xE0, 0xFE, 0x74, 0x04, 0x2B, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0x31, 0xAD, 0x90, 0x88, 0x7A, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x07, 0x2B, 0xF5, +0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x06, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0x31, 0xAD, 0x90, 0x88, 0x7C, 0xF0, 0xA3, 0xEF, 0xF0, 0x74, 0x09, 0x2B, 0xF5, 0x82, 0xE4, 0x34, +0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x08, 0x2B, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, +0x24, 0x00, 0xFF, 0xEC, 0x3E, 0x90, 0x88, 0x7E, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0xF5, 0x83, 0xE0, +0x24, 0x00, 0xFF, 0xEA, 0x3E, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, +0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, +0x00, 0x22, 0xAD, 0x07, 0x90, 0x88, 0x80, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x90, 0x88, +0x80, 0xE0, 0xFF, 0xAE, 0x05, 0x74, 0x04, 0x2E, 0x51, 0xA3, 0xEF, 0xF0, 0x90, 0x88, 0x80, 0xA3, +0xE0, 0xFF, 0x74, 0x05, 0x2E, 0x31, 0xB6, 0xEF, 0xF0, 0x22, 0xE4, 0x90, 0x92, 0x59, 0xF0, 0xA3, +0xF0, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x20, 0xF0, 0x12, 0x75, 0xE4, 0xEF, 0x64, 0x01, 0x60, 0x02, +0x41, 0x99, 0x90, 0x88, 0xD9, 0xE0, 0xFF, 0x90, 0x93, 0x15, 0x74, 0x0A, 0xF0, 0x7B, 0x08, 0x7D, +0x01, 0x12, 0xBF, 0x83, 0x90, 0x92, 0x56, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x92, 0x56, 0xA3, +0x11, 0x41, 0xFD, 0x74, 0x2C, 0x2E, 0x51, 0xAB, 0x90, 0x92, 0x58, 0xEF, 0xF0, 0x90, 0x92, 0x56, +0xA3, 0xE0, 0x24, 0x28, 0xF9, 0xE4, 0x34, 0xFC, 0xFA, 0x7B, 0x01, 0xE4, 0xFD, 0x12, 0x52, 0x21, +0x90, 0x92, 0x58, 0xE0, 0xFF, 0x90, 0x92, 0x57, 0xE0, 0x2F, 0xFF, 0x90, 0x92, 0x56, 0xE0, 0x34, +0x00, 0xCF, 0x24, 0x30, 0xCF, 0x34, 0x00, 0xFE, 0x90, 0x92, 0x59, 0xF0, 0xA3, 0xEF, 0xF0, 0x31, +0xD2, 0x51, 0x9A, 0x90, 0x88, 0xD9, 0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x15, 0x44, 0x51, 0x9A, 0x90, +0x88, 0xD5, 0xE0, 0xFB, 0x7F, 0x11, 0x12, 0x15, 0x44, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x90, +0x88, 0x88, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x07, 0x0A, 0x22, 0x90, 0x92, 0x59, 0xE0, 0xFC, 0xA3, +0xE0, 0xFD, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0x22, 0xF5, 0x82, 0xE4, 0x34, 0xFC, +0xF5, 0x83, 0xE0, 0xFB, 0x02, 0x5D, 0x98, 0x12, 0x7B, 0x2A, 0x7C, 0x00, 0xAD, 0x07, 0x22, 0xD3, +0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x93, 0x00, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x12, 0x70, +0x61, 0x90, 0x93, 0x0A, 0x12, 0x04, 0xEB, 0x90, 0x93, 0x02, 0x12, 0x87, 0x58, 0x12, 0x04, 0xA7, +0x90, 0x93, 0x0A, 0x12, 0x87, 0x64, 0x12, 0x87, 0x3E, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, +0x07, 0x90, 0x93, 0x02, 0x12, 0x87, 0x58, 0x90, 0x93, 0x06, 0x12, 0x87, 0x64, 0x12, 0x87, 0x3E, +0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x87, 0x4B, 0x90, 0x93, 0x0E, 0x12, 0x04, +0xEB, 0x90, 0x93, 0x0E, 0x12, 0x87, 0x58, 0x90, 0x91, 0x66, 0x12, 0x04, 0xEB, 0x90, 0x93, 0x00, +0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x12, 0x71, 0x18, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x7E, 0x00, 0x7F, +0xAC, 0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x85, 0x79, 0xC1, 0x12, 0x06, 0xDE, 0x71, 0xFC, 0x12, 0x06, +0xDE, 0x90, 0x85, 0xC4, 0x74, 0x02, 0xF0, 0x90, 0x85, 0xCB, 0x14, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, +0x0A, 0xF0, 0x90, 0x85, 0xD1, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0x71, 0xEC, 0x91, 0x09, 0xE4, 0xFD, +0xFF, 0x12, 0x57, 0x82, 0x7D, 0x0C, 0x7F, 0x02, 0x12, 0x57, 0x82, 0x7D, 0x0C, 0x7F, 0x01, 0x12, +0x57, 0x82, 0x90, 0x84, 0xC5, 0xE0, 0xFF, 0xB4, 0x01, 0x08, 0x90, 0x85, 0xD0, 0x74, 0xDD, 0xF0, +0x80, 0x0F, 0xEF, 0x90, 0x85, 0xD0, 0xB4, 0x03, 0x05, 0x74, 0xD4, 0xF0, 0x80, 0x03, 0x74, 0x40, +0xF0, 0x7F, 0x2C, 0x12, 0x7B, 0x51, 0xEF, 0x54, 0x0F, 0xFF, 0xBF, 0x05, 0x08, 0x90, 0x85, 0xFB, +0x74, 0x02, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x85, 0xFB, 0xF0, 0x90, 0x86, 0x6D, 0x74, 0x03, 0xF0, +0xA3, 0x74, 0x0F, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x07, 0x71, 0xEC, +0xE4, 0x90, 0x85, 0xD7, 0xF0, 0xA3, 0xF0, 0x7F, 0x01, 0x12, 0x69, 0x33, 0x90, 0x05, 0x58, 0x74, +0x02, 0xF0, 0x90, 0x06, 0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, +0xE4, 0xFD, 0xFF, 0x12, 0x90, 0xDD, 0xE4, 0x90, 0x86, 0x71, 0xF0, 0x22, 0xF0, 0x90, 0x85, 0xFB, +0xE0, 0x24, 0x04, 0x90, 0x85, 0xDD, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x22, 0x7E, 0x00, 0x7F, 0x04, +0x7D, 0x00, 0x7B, 0x01, 0x7A, 0x92, 0x79, 0x84, 0x22, 0x90, 0x92, 0xD0, 0x74, 0x04, 0xF0, 0x14, +0xF0, 0xA3, 0xF0, 0xA3, 0xE4, 0xF0, 0xA3, 0x74, 0x64, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xF0, +0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x7A, 0x29, 0xEF, 0x64, 0x01, 0x60, 0x05, +0x75, 0x0F, 0x01, 0x80, 0x52, 0x90, 0x85, 0xC9, 0xE0, 0xFF, 0x54, 0x03, 0x60, 0x05, 0x75, 0x0F, +0x02, 0x80, 0x44, 0x90, 0x85, 0xC7, 0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x50, 0x05, 0x75, 0x0F, 0x04, +0x80, 0x35, 0xEF, 0x30, 0xE2, 0x05, 0x75, 0x0F, 0x08, 0x80, 0x2C, 0x90, 0x85, 0xC9, 0xE0, 0x30, +0xE4, 0x05, 0x75, 0x0F, 0x10, 0x80, 0x20, 0x90, 0x85, 0xC2, 0xE0, 0x13, 0x13, 0x54, 0x3F, 0x20, +0xE0, 0x05, 0x75, 0x0F, 0x20, 0x80, 0x10, 0x90, 0x86, 0x71, 0xE0, 0x60, 0x05, 0x75, 0x0F, 0x80, +0x80, 0x05, 0x12, 0xB3, 0xD4, 0x80, 0x0E, 0x90, 0x01, 0xB9, 0x74, 0x04, 0xF0, 0x90, 0x01, 0xB8, +0xE5, 0x0F, 0xF0, 0x7F, 0x00, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xAC, 0x07, 0x90, 0x92, 0x96, 0xE0, +0xF9, 0x30, 0xE0, 0x02, 0xA1, 0x4E, 0x90, 0x85, 0xC1, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x85, 0xFB, +0xE0, 0x24, 0x04, 0x90, 0x85, 0xDA, 0xF0, 0x90, 0x85, 0xFB, 0xE0, 0x24, 0x03, 0x90, 0x85, 0xD9, +0xF0, 0x80, 0x0D, 0x90, 0x85, 0xDA, 0x74, 0x02, 0xF0, 0x90, 0x85, 0xD9, 0x14, 0xF0, 0x0B, 0x0B, +0x90, 0x85, 0xD9, 0xE0, 0xFA, 0x90, 0x85, 0xD8, 0xE0, 0xD3, 0x9A, 0x50, 0x0E, 0x90, 0x85, 0xCD, +0xEB, 0xF0, 0x90, 0x85, 0xDA, 0xE0, 0xC3, 0x9D, 0x2C, 0x80, 0x11, 0xC3, 0xED, 0x9A, 0x2B, 0x90, +0x85, 0xCD, 0xF0, 0x90, 0x85, 0xD9, 0xE0, 0xFF, 0xA3, 0xE0, 0xC3, 0x9F, 0x90, 0x85, 0xDD, 0xF0, +0x90, 0x85, 0xDA, 0xE0, 0xFF, 0x24, 0x0A, 0xFD, 0xE4, 0x33, 0xFC, 0x90, 0x85, 0xDD, 0xB1, 0x56, +0x98, 0x40, 0x04, 0xEF, 0x24, 0x0A, 0xF0, 0x90, 0x85, 0xDD, 0xE0, 0xFF, 0x24, 0x23, 0xFD, 0xE4, +0x33, 0xFC, 0x90, 0x85, 0xCD, 0xB1, 0x56, 0x98, 0x40, 0x04, 0xEF, 0x24, 0x23, 0xF0, 0x90, 0x85, +0xDD, 0xE0, 0xFF, 0x7E, 0x00, 0x90, 0x85, 0xD1, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x05, 0x58, +0xE0, 0x6F, 0x70, 0x01, 0xE4, 0x60, 0x02, 0xB1, 0x60, 0xE9, 0x54, 0xFD, 0x80, 0x03, 0xE9, 0x44, +0x02, 0x90, 0x92, 0x96, 0xF0, 0x22, 0xE0, 0xD3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, 0x22, +0x90, 0x85, 0xD1, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x22, 0xB1, 0xA7, 0x40, 0x2B, 0x90, 0x85, +0xDF, 0xE0, 0x04, 0xF0, 0x90, 0x92, 0xD5, 0xE0, 0xFF, 0x90, 0x85, 0xDF, 0xE0, 0xD3, 0x9F, 0x50, +0x18, 0x90, 0x85, 0xD7, 0xE0, 0x04, 0x12, 0xA2, 0x51, 0x90, 0x85, 0xDE, 0xF0, 0xFB, 0x90, 0x85, +0xD7, 0xE0, 0xFF, 0xA3, 0xE0, 0xFD, 0x12, 0x51, 0x7D, 0x22, 0x90, 0x85, 0xCE, 0xE0, 0x04, 0xF0, +0x90, 0x85, 0xC9, 0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x86, 0x6D, 0xE0, 0xFF, 0x90, 0x85, 0xCE, 0xE0, +0xD3, 0x9F, 0x22, 0x90, 0x92, 0x7B, 0xEF, 0xF0, 0x90, 0x84, 0xC5, 0xE0, 0x64, 0x02, 0x70, 0x1F, +0x90, 0x92, 0x7B, 0xE0, 0xFD, 0x64, 0x01, 0x70, 0x32, 0x12, 0xAF, 0x30, 0x12, 0x8D, 0x67, 0x30, +0xE0, 0x09, 0x90, 0x01, 0x4D, 0xE0, 0x64, 0x80, 0xF0, 0x80, 0x20, 0xAF, 0x05, 0x80, 0x19, 0x90, +0x01, 0x00, 0x74, 0xFF, 0xF0, 0x7F, 0x64, 0x7E, 0x00, 0x12, 0x7C, 0x9F, 0x90, 0x06, 0x90, 0xE0, +0x44, 0x01, 0xF0, 0x90, 0x92, 0x7B, 0xE0, 0xFF, 0x12, 0x2A, 0x87, 0x90, 0x88, 0xE1, 0xE0, 0x54, +0xFE, 0xF0, 0x90, 0x86, 0x72, 0xE0, 0x54, 0xBF, 0xF0, 0x22, 0x90, 0x92, 0x7C, 0xEE, 0xF0, 0xA3, +0xEF, 0xF0, 0xE4, 0x90, 0x92, 0x80, 0xF0, 0x7D, 0x09, 0x12, 0x55, 0x36, 0xEF, 0x64, 0x06, 0x70, +0x2A, 0xD1, 0x9F, 0x7D, 0x14, 0x12, 0x55, 0x36, 0xEF, 0x70, 0x20, 0xD1, 0x9F, 0x7D, 0x15, 0x12, +0x55, 0x36, 0xEF, 0x64, 0x50, 0x70, 0x14, 0xD1, 0x9F, 0x7D, 0x21, 0x12, 0x55, 0x36, 0xEF, 0x20, +0xE0, 0x03, 0x30, 0xE2, 0x06, 0x90, 0x92, 0x80, 0x74, 0x01, 0xF0, 0x90, 0x86, 0x73, 0xE0, 0x13, +0x13, 0x54, 0x3F, 0x30, 0xE0, 0x3F, 0xD1, 0x9F, 0x7D, 0x09, 0x12, 0x55, 0x36, 0xEF, 0x64, 0x11, +0x70, 0x33, 0x90, 0x92, 0x7D, 0xE0, 0x24, 0x14, 0xFF, 0x90, 0x92, 0x7C, 0xE0, 0x34, 0x00, 0xFE, +0x90, 0x92, 0x7E, 0xF0, 0xA3, 0xEF, 0xF0, 0x7D, 0x02, 0x12, 0x55, 0x36, 0xEF, 0x70, 0x16, 0x90, +0x92, 0x7E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x7D, 0x03, 0x12, 0x55, 0x36, 0xBF, 0x89, 0x06, 0x90, +0x92, 0x80, 0x74, 0x01, 0xF0, 0x90, 0x92, 0x80, 0xE0, 0xFF, 0xD1, 0xA8, 0xEF, 0xF0, 0x22, 0x90, +0x92, 0x7C, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0x90, 0x84, 0xBF, 0xA3, 0xE0, 0x24, 0x7F, 0xF5, +0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22, 0xD1, 0xFD, 0xA3, 0xED, 0xF0, 0x90, 0x88, 0x7C, 0xE0, +0x70, 0x02, 0xA3, 0xE0, 0x60, 0x23, 0xE4, 0x90, 0x92, 0x36, 0xF0, 0xF1, 0x06, 0x50, 0x1D, 0xF1, +0x4A, 0x24, 0x8A, 0xF5, 0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, 0x7F, 0x00, +0x22, 0x90, 0x92, 0x36, 0xE0, 0x04, 0xF0, 0x80, 0xE2, 0x7F, 0x00, 0x22, 0x90, 0x06, 0x32, 0xE0, +0x44, 0x40, 0xF0, 0xE4, 0x90, 0x88, 0x88, 0xF0, 0xA3, 0xF0, 0x7F, 0x01, 0x22, 0x90, 0x92, 0x33, +0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x90, 0x92, 0x36, 0xE0, 0xFD, 0xC3, 0x94, 0x02, 0x22, 0xD1, +0xFD, 0xA3, 0xED, 0xF0, 0xE4, 0xA3, 0xF0, 0xF1, 0x06, 0x50, 0x17, 0xF1, 0x4A, 0x24, 0xAA, 0xF5, +0x82, 0xE4, 0x34, 0x88, 0xF5, 0x83, 0xE0, 0xB5, 0x07, 0x1D, 0x90, 0x92, 0x36, 0xE0, 0x04, 0xF0, +0x80, 0xE5, 0x90, 0x06, 0x32, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x01, 0xC7, 0x74, 0x30, 0xF0, 0x7F, +0x01, 0x12, 0x5F, 0xE9, 0x7F, 0x01, 0x22, 0x7F, 0x00, 0x22, 0x90, 0x92, 0x33, 0xE0, 0xFE, 0xA3, +0xE0, 0xFF, 0xED, 0x24, 0x1C, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x92, 0x36, 0xE0, 0x22, 0xD1, 0xFD, +0x24, 0x16, 0xFF, 0xE4, 0x3E, 0xFE, 0xE4, 0xFD, 0x12, 0x55, 0x36, 0x90, 0x88, 0x86, 0xA3, 0xE0, +0xB5, 0x07, 0x19, 0x90, 0x92, 0x34, 0xE0, 0x24, 0x16, 0xF1, 0x92, 0x7D, 0x01, 0x12, 0x55, 0x36, +0xEF, 0xFD, 0x90, 0x88, 0x86, 0xE0, 0x6D, 0x70, 0x01, 0xE4, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x7F, +0x01, 0x22, 0xFF, 0x90, 0x92, 0x33, 0xE0, 0x34, 0x00, 0xFE, 0x22, 0xD1, 0xFD, 0xE4, 0xA3, 0xF0, +0x90, 0x92, 0x35, 0xE0, 0xFD, 0xC3, 0x94, 0x04, 0x50, 0x27, 0x90, 0x92, 0x34, 0xE0, 0x24, 0x10, +0xF1, 0x92, 0x12, 0x55, 0x36, 0x90, 0x92, 0x35, 0xE0, 0x24, 0x82, 0xF5, 0x82, 0xE4, 0x34, 0x88, +0xF5, 0x83, 0xE0, 0x6F, 0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x92, 0x35, 0xE0, 0x04, 0xF0, 0x80, +0xCF, 0x7F, 0x01, 0x22, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, +0x83, 0xE4, 0x93, 0xFF, 0x74, 0x01, 0x93, 0x90, 0x92, 0x41, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, +0x92, 0x3F, 0xE5, 0x66, 0xF0, 0xA3, 0xE5, 0x67, 0xF0, 0x22, 0x90, 0x05, 0x63, 0xE0, 0x90, 0x92, +0x9F, 0xF0, 0x90, 0x05, 0x62, 0xE0, 0x90, 0x92, 0xA0, 0xF0, 0x90, 0x05, 0x61, 0xE0, 0x90, 0x92, +0xA1, 0xF0, 0x90, 0x05, 0x60, 0xE0, 0x90, 0x92, 0xA2, 0xF0, 0x90, 0x92, 0x96, 0xE0, 0x44, 0x01, +0xF0, 0x22, 0x90, 0x92, 0x78, 0xEE, 0xF0, 0xFC, 0xA3, 0xEF, 0xF0, 0xFD, 0x90, 0x92, 0x76, 0xE0, +0xFF, 0x12, 0x65, 0x61, 0x90, 0x92, 0x78, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x02, 0x50, 0xD7, 0x75, +0xF0, 0x08, 0xA4, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22, 0x75, 0xF0, 0x12, +0x90, 0x89, 0x3C, 0x12, 0x05, 0x28, 0xE0, 0x22, 0x90, 0x01, 0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, +0xFF, 0x12, 0x7C, 0xA9, 0x43, 0x5E, 0x08, 0x22, 0xE5, 0x64, 0x25, 0xE0, 0x24, 0xF5, 0xF5, 0x82, +0xE4, 0x34, 0x82, 0xF5, 0x83, 0x22, 0xC4, 0x54, 0xF0, 0x24, 0x01, 0xF5, 0x82, 0xE4, 0x34, 0x81, +0xF5, 0x83, 0xE0, 0x22, 0xE0, 0x90, 0x01, 0xBA, 0xF0, 0x90, 0x85, 0xC7, 0xE0, 0x90, 0x01, 0xBB, +0x22, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0, 0xEF, 0x22, 0x12, 0x02, 0xF6, 0xFF, 0x54, 0x01, 0xFE, +0x22, 0x74, 0x21, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x22, 0xF0, 0x74, 0xCC, +0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x8F, 0xF5, 0x83, 0x22, 0x74, 0xBC, 0x25, 0x62, 0xF5, 0x82, 0xE4, +0x34, 0x8F, 0xF5, 0x83, 0x22, 0x90, 0x92, 0x41, 0xE4, 0xF0, 0xA3, 0x22, 0x90, 0x92, 0x07, 0x12, +0x87, 0x79, 0x02, 0x02, 0xF6, 0x90, 0x92, 0x33, 0x12, 0x87, 0x70, 0x02, 0x03, 0xED, 0xE0, 0xFF, +0xA3, 0xE0, 0x90, 0x92, 0x41, 0xCF, 0x22, 0x54, 0x08, 0xFE, 0xEF, 0x54, 0xF7, 0x4E, 0x22, 0x54, +0x20, 0xFE, 0xEF, 0x54, 0xDF, 0x4E, 0x22, 0x54, 0x80, 0xFE, 0xEF, 0x54, 0x7F, 0x4E, 0x22, 0x12, +0x02, 0xF6, 0x13, 0x13, 0x54, 0x3F, 0x22, 0xF9, 0xE4, 0x3A, 0xFA, 0x02, 0x02, 0xF6, 0xE5, 0x68, +0xF0, 0xA3, 0xE5, 0x69, 0xF0, 0x22, 0x90, 0x00, 0x02, 0x12, 0x04, 0x18, 0xFF, 0x22, 0x7D, 0x05, +0x7F, 0x04, 0x02, 0x96, 0x87, 0x90, 0x85, 0xC1, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x00, 0x55, 0x69, + +}; +u4Byte ArrayLength_MP_8188F_FW_WoWLAN = 18768; + + +void +ODM_ReadFirmware_MP_8188F_FW_WoWLAN( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE)) + *((SIZE_PTR *)pFirmware) = (SIZE_PTR)Array_MP_8188F_FW_WoWLAN; +#else + ODM_MoveMemory(pDM_Odm, pFirmware, Array_MP_8188F_FW_WoWLAN, ArrayLength_MP_8188F_FW_WoWLAN); +#endif + *pFirmwareSize = ArrayLength_MP_8188F_FW_WoWLAN; +} + + + +#endif /* end of (defined(CONFIG_AP_WOWLAN) || (DM_ODM_SUPPORT_TYPE & (ODM_AP)))*/ + + +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.h new file mode 100644 index 00000000..2778653e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_fw.h @@ -0,0 +1,62 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.16*/ +#if (RTL8188F_SUPPORT == 1) +#ifndef __INC_MP_FW_HW_IMG_8188F_H +#define __INC_MP_FW_HW_IMG_8188F_H + + +/****************************************************************************** +* FW_AP.TXT +******************************************************************************/ + +void +ODM_ReadFirmware_MP_8188F_FW_AP( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +); + +/****************************************************************************** +* FW_NIC.TXT +******************************************************************************/ + +void +ODM_ReadFirmware_MP_8188F_FW_NIC( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +); + +/****************************************************************************** +* FW_WoWLAN.TXT +******************************************************************************/ + +void +ODM_ReadFirmware_MP_8188F_FW_WoWLAN( + IN PDM_ODM_T pDM_Odm, + OUT u1Byte *pFirmware, + OUT u4Byte *pFirmwareSize +); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.c new file mode 100644 index 00000000..a0b09636 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.c @@ -0,0 +1,288 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8188F_SUPPORT == 1) +static BOOLEAN +CheckPositive( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2, + IN const u4Byte Condition3, + IN const u4Byte Condition4 +) +{ + u1Byte _BoardType = ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA*/ + ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA*/ + ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA*/ + ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ + ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT*/ + + u4Byte cond1 = Condition1, cond2 = Condition2, cond3 = Condition3, cond4 = Condition4; + u4Byte driver1 = pDM_Odm->CutVersion << 24 | + (pDM_Odm->SupportInterface & 0xF0) << 16 | + pDM_Odm->SupportPlatform << 16 | + pDM_Odm->PackageType << 12 | + (pDM_Odm->SupportInterface & 0x0F) << 8 | + _BoardType; + + u4Byte driver2 = (pDM_Odm->TypeGLNA & 0xFF) << 0 | + (pDM_Odm->TypeGPA & 0xFF) << 8 | + (pDM_Odm->TypeALNA & 0xFF) << 16 | + (pDM_Odm->TypeAPA & 0xFF) << 24; + +u4Byte driver3 = 0; + + u4Byte driver4 = (pDM_Odm->TypeGLNA & 0xFF00) >> 8 | + (pDM_Odm->TypeGPA & 0xFF00) | + (pDM_Odm->TypeALNA & 0xFF00) << 8 | + (pDM_Odm->TypeAPA & 0xFF00) << 16; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Platform, Interface) = (0x%X, 0x%X)\n", pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Board, Package) = (0x%X, 0x%X)\n", pDM_Odm->BoardType, pDM_Odm->PackageType)); + + + /*============== Value Defined Check ===============*/ + /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return FALSE; + if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return FALSE; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u4Byte bitMask = 0; + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ + return TRUE; + + if ((cond1 & BIT0) != 0) /*GLNA*/ + bitMask |= 0x000000FF; + if ((cond1 & BIT1) != 0) /*GPA*/ + bitMask |= 0x0000FF00; + if ((cond1 & BIT2) != 0) /*ALNA*/ + bitMask |= 0x00FF0000; + if ((cond1 & BIT3) != 0) /*APA*/ + bitMask |= 0xFF000000; + + if (((cond2 & bitMask) == (driver2 & bitMask)) && ((cond4 & bitMask) == (driver4 & bitMask))) /* BoardType of each RF path is matched*/ + return TRUE; + else + return FALSE; + } else + return FALSE; +} +static BOOLEAN +CheckNegative( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2 +) +{ + return TRUE; +} + +/****************************************************************************** +* MAC_REG.TXT +******************************************************************************/ + +u4Byte Array_MP_8188F_MAC_REG[] = { + 0x024, 0x000000DF, + 0x025, 0x00000007, + 0x02B, 0x0000001C, + 0x283, 0x00000020, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000044, + 0x461, 0x00000044, + 0x4BC, 0x000000C0, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000028, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000028, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + +}; + +void +ODM_ReadAndConfig_MP_8188F_MAC_REG( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; + u4Byte ArrayLen = sizeof(Array_MP_8188F_MAC_REG)/sizeof(u4Byte); + pu4Byte Array = Array_MP_8188F_MAC_REG; + + u4Byte v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_MAC_REG\n")); + + while ((i + 1) < ArrayLen) { + v1 = Array[i]; + 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; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n")); + } else if (cCond == COND_ELSE) { /*else*/ + bMatched = bSkipped?FALSE:TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n")); + } else {/*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n")); + } + } else if (v1 & BIT30) { /*negative condition*/ + if (bSkipped == FALSE) { + if (CheckPositive(pDM_Odm, pre_v1, pre_v2, v1, v2)) { + bMatched = TRUE; + bSkipped = TRUE; + } else { + bMatched = FALSE; + bSkipped = FALSE; + } + } else + bMatched = FALSE; + } + } else { + if (bMatched) + odm_ConfigMAC_8188F(pDM_Odm, v1, (u1Byte)v2); + } + i = i + 2; + } +} + +u4Byte +ODM_GetVersion_MP_8188F_MAC_REG(void) +{ + return 25; +} + +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.h new file mode 100644 index 00000000..6d61aa5d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_mac.h @@ -0,0 +1,39 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#if (RTL8188F_SUPPORT == 1) +#ifndef __INC_MP_MAC_HW_IMG_8188F_H +#define __INC_MP_MAC_HW_IMG_8188F_H + + +/****************************************************************************** +* MAC_REG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_MAC_REG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_MAC_REG(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.c new file mode 100644 index 00000000..bced1eec --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.c @@ -0,0 +1,1130 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (RTL8188F_SUPPORT == 1) +static BOOLEAN +CheckPositive( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2, + IN const u4Byte Condition3, + IN const u4Byte Condition4 +) +{ + u1Byte _BoardType = ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA*/ + ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA*/ + ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA*/ + ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ + ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT*/ + + u4Byte cond1 = Condition1, cond2 = Condition2, cond3 = Condition3, cond4 = Condition4; + u4Byte driver1 = pDM_Odm->CutVersion << 24 | + (pDM_Odm->SupportInterface & 0xF0) << 16 | + pDM_Odm->SupportPlatform << 16 | + pDM_Odm->PackageType << 12 | + (pDM_Odm->SupportInterface & 0x0F) << 8 | + _BoardType; + + u4Byte driver2 = (pDM_Odm->TypeGLNA & 0xFF) << 0 | + (pDM_Odm->TypeGPA & 0xFF) << 8 | + (pDM_Odm->TypeALNA & 0xFF) << 16 | + (pDM_Odm->TypeAPA & 0xFF) << 24; + +u4Byte driver3 = 0; + + u4Byte driver4 = (pDM_Odm->TypeGLNA & 0xFF00) >> 8 | + (pDM_Odm->TypeGPA & 0xFF00) | + (pDM_Odm->TypeALNA & 0xFF00) << 8 | + (pDM_Odm->TypeAPA & 0xFF00) << 16; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", cond1, cond2, cond3, cond4)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + ("===> CheckPositive (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", driver1, driver2, driver3, driver4)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Platform, Interface) = (0x%X, 0x%X)\n", pDM_Odm->SupportPlatform, pDM_Odm->SupportInterface)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, + (" (Board, Package) = (0x%X, 0x%X)\n", pDM_Odm->BoardType, pDM_Odm->PackageType)); + + + /*============== Value Defined Check ===============*/ + /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return FALSE; + if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return FALSE; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u4Byte bitMask = 0; + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ + return TRUE; + + if ((cond1 & BIT0) != 0) /*GLNA*/ + bitMask |= 0x000000FF; + if ((cond1 & BIT1) != 0) /*GPA*/ + bitMask |= 0x0000FF00; + if ((cond1 & BIT2) != 0) /*ALNA*/ + bitMask |= 0x00FF0000; + if ((cond1 & BIT3) != 0) /*APA*/ + bitMask |= 0xFF000000; + + if (((cond2 & bitMask) == (driver2 & bitMask)) && ((cond4 & bitMask) == (driver4 & bitMask))) /* BoardType of each RF path is matched*/ + return TRUE; + else + return FALSE; + } else + return FALSE; +} +static BOOLEAN +CheckNegative( + IN PDM_ODM_T pDM_Odm, + IN const u4Byte Condition1, + IN const u4Byte Condition2 +) +{ + return TRUE; +} + +/****************************************************************************** +* RadioA.TXT +******************************************************************************/ + +u4Byte Array_MP_8188F_RadioA[] = { + 0x000, 0x00030000, + 0x008, 0x00008400, + 0x018, 0x00000407, + 0x019, 0x00000012, + 0x01E, 0x00080009, + 0x01F, 0x00000880, + 0x02F, 0x0001A060, + 0x03F, 0x00028000, + 0x042, 0x000060C0, + 0x057, 0x000D0000, + 0x058, 0x000C0160, + 0x067, 0x00001552, + 0x083, 0x00000000, + 0x0B0, 0x000FF9F0, + 0x0B1, 0x00022218, + 0x0B2, 0x00034C00, + 0x0B4, 0x0004484B, + 0x0B5, 0x0000112A, + 0x0B6, 0x0000053E, + 0x0B7, 0x00010408, + 0x0B8, 0x00010200, + 0x0B9, 0x00080001, + 0x0BA, 0x00040001, + 0x0BB, 0x00000400, + 0x0BF, 0x000C0000, + 0x0C2, 0x00002400, + 0x0C3, 0x00000009, + 0x0C4, 0x00040C91, + 0x0C5, 0x00099999, + 0x0C6, 0x000000A3, + 0x0C7, 0x0008F820, + 0x0C8, 0x00076C06, + 0x0C9, 0x00000000, + 0x0CA, 0x00080000, + 0x0DF, 0x00000180, + 0x0EF, 0x000001A0, + 0x81000000, 0x00000000, 0x40000000, 0x00000000, + 0x051, 0x000E8231, + 0x052, 0x000FAC88, + 0x053, 0x00000141, + 0xA0000000, 0x00000000, + 0x051, 0x000E8333, + 0x052, 0x000FAC88, + 0x053, 0x00000103, + 0xB0000000, 0x00000000, + 0x056, 0x000517F0, + 0x81000000, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000090, + 0x035, 0x00000190, + 0x035, 0x00000290, + 0x036, 0x00001064, + 0x036, 0x00009064, + 0x036, 0x00011064, + 0x036, 0x00019064, + 0xA0000000, 0x00000000, + 0x035, 0x00000099, + 0x035, 0x00000199, + 0x035, 0x00000299, + 0x036, 0x00000064, + 0x036, 0x00008064, + 0x036, 0x00010064, + 0x036, 0x00018064, + 0xB0000000, 0x00000000, + 0x018, 0x00000C07, + 0x05A, 0x00048000, + 0x019, 0x000739D0, + 0x80000400, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000ADD2, + 0x034, 0x00009DCF, + 0x034, 0x00008CF2, + 0x034, 0x00007CEF, + 0x034, 0x00006CEC, + 0x034, 0x00005CE9, + 0x034, 0x00004CCE, + 0x034, 0x00003CCB, + 0x034, 0x00002CC8, + 0x034, 0x00001C4B, + 0x034, 0x00000C48, + 0x91000000, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000ADD3, + 0x034, 0x00009DD1, + 0x034, 0x00008CF4, + 0x034, 0x00007CF1, + 0x034, 0x00006CEE, + 0x034, 0x00005CD3, + 0x034, 0x00004CD0, + 0x034, 0x00003CCD, + 0x034, 0x00002CCA, + 0x034, 0x00001C4D, + 0x034, 0x00000C4A, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADD6, + 0x034, 0x00009DD3, + 0x034, 0x00008CF4, + 0x034, 0x00007CF1, + 0x034, 0x00006CEE, + 0x034, 0x00005CEB, + 0x034, 0x00004CCE, + 0x034, 0x00003CCB, + 0x034, 0x00002CC8, + 0x034, 0x00001C4B, + 0x034, 0x00000C48, + 0xB0000000, 0x00000000, + 0x000, 0x00030159, + 0x084, 0x00048000, + 0x086, 0x0000002A, + 0x087, 0x00000025, + 0x08E, 0x00065540, + 0x08F, 0x00088000, + 0x0EF, 0x000020A0, + 0x03B, 0x000F0F00, + 0x03B, 0x000E0B00, + 0x03B, 0x000D0900, + 0x03B, 0x000C0700, + 0x03B, 0x000B0600, + 0x03B, 0x000A0400, + 0x03B, 0x00090200, + 0x03B, 0x00080000, + 0x03B, 0x0007BF00, + 0x03B, 0x00060B00, + 0x03B, 0x0005C900, + 0x03B, 0x00040700, + 0x03B, 0x00030600, + 0x03B, 0x0002D500, + 0x03B, 0x00010200, + 0x03B, 0x0000E000, + 0x0EF, 0x000000A0, + 0x0EF, 0x00000010, + 0x03B, 0x0000C0A8, + 0x03B, 0x00010400, + 0x0EF, 0x00000000, + 0x0EF, 0x00080000, + 0x030, 0x00010000, + 0x031, 0x0000000F, + 0x032, 0x00007EFE, + 0x0EF, 0x00000000, + 0x000, 0x00010159, + 0x018, 0x0000FC07, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x01F, 0x00080003, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x01E, 0x00000001, + 0x01F, 0x00080000, + 0x000, 0x00033D95, + +}; + +void +ODM_ReadAndConfig_MP_8188F_RadioA( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u1Byte cCond; + BOOLEAN bMatched = TRUE, bSkipped = FALSE; + u4Byte ArrayLen = sizeof(Array_MP_8188F_RadioA)/sizeof(u4Byte); + pu4Byte Array = Array_MP_8188F_RadioA; + + u4Byte v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_RadioA\n")); + + while ((i + 1) < ArrayLen) { + v1 = Array[i]; + 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; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ENDIF\n")); + } else if (cCond == COND_ELSE) { /*else*/ + bMatched = bSkipped?FALSE:TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("ELSE\n")); + } else {/*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("IF or ELSE IF\n")); + } + } else if (v1 & BIT30) { /*negative condition*/ + if (bSkipped == FALSE) { + if (CheckPositive(pDM_Odm, pre_v1, pre_v2, v1, v2)) { + bMatched = TRUE; + bSkipped = TRUE; + } else { + bMatched = FALSE; + bSkipped = FALSE; + } + } else + bMatched = FALSE; + } + } else { + if (bMatched) + odm_ConfigRF_RadioA_8188F(pDM_Odm, v1, v2); + } + i = i + 2; + } +} + +u4Byte +ODM_GetVersion_MP_8188F_RadioA(void) +{ + return 25; +} + +/****************************************************************************** +* TxPowerTrack_AP.TXT +******************************************************************************/ + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +u1Byte gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_AP_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_AP_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_AP_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_AP_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_AP_8188F[] = {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; +u1Byte gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_AP_8188F[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_AP_8188F[] = {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; +u1Byte gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_AP_8188F[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_AP_8188F[] = {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_AP_8188F[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_AP_8188F[] = {0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_AP_8188F[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9}; +#endif + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_AP( + IN PDM_ODM_T pDM_Odm +) +{ +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188F\n")); + + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P, gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N, gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P, gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N, gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_AP_8188F, DELTA_SWINGIDX_SIZE*3); +#endif +} + +/****************************************************************************** +* TxPowerTrack_SDIO.TXT +******************************************************************************/ + +#if DEV_BUS_TYPE == RT_SDIO_INTERFACE +u1Byte gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_SDIO_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_SDIO_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_SDIO_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_SDIO_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_SDIO_8188F[] = {0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_SDIO_8188F[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 8}; +u1Byte gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_SDIO_8188F[] = {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; +u1Byte gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_SDIO_8188F[] = {0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_SDIO_8188F[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_SDIO_8188F[] = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 7}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_SDIO_8188F[] = {0, 1, 2, 3, 4, 6, 7, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_SDIO_8188F[] = {0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}; +#endif + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_SDIO( + IN PDM_ODM_T pDM_Odm +) +{ +#if DEV_BUS_TYPE == RT_SDIO_INTERFACE + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188F\n")); + + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P, gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N, gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P, gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N, gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_SDIO_8188F, DELTA_SWINGIDX_SIZE*3); +#endif +} + +/****************************************************************************** +* TxPowerTrack_USB.TXT +******************************************************************************/ + +#if DEV_BUS_TYPE == RT_USB_INTERFACE +u1Byte gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_USB_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_USB_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_USB_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18}, +}; +u1Byte gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_USB_8188F[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; +u1Byte gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_USB_8188F[] = {0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_USB_8188F[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7, 8, 8, 8, 8}; +u1Byte gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_USB_8188F[] = {0, 1, 1, 2, 3, 4, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}; +u1Byte gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_USB_8188F[] = {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_USB_8188F[] = {0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_USB_8188F[] = {0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 7}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_USB_8188F[] = {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; +u1Byte gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_USB_8188F[] = {0, 0, 1, 2, 2, 3, 3, 4, 6, 6, 7, 8, 8, 10, 10, 11, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}; +#endif + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_USB( + IN PDM_ODM_T pDM_Odm +) +{ +#if DEV_BUS_TYPE == RT_USB_INTERFACE + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_MP_8188F\n")); + + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P, gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N, gDeltaSwingTableIdx_MP_2GA_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P, gDeltaSwingTableIdx_MP_2GB_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N, gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P, gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N, gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P, gDeltaSwingTableIdx_MP_2GCCKB_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N, gDeltaSwingTableIdx_MP_2GCCKB_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE); + + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_P, gDeltaSwingTableIdx_MP_5GA_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GA_N, gDeltaSwingTableIdx_MP_5GA_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_P, gDeltaSwingTableIdx_MP_5GB_P_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE*3); + ODM_MoveMemory(pDM_Odm, pRFCalibrateInfo->DeltaSwingTableIdx_5GB_N, gDeltaSwingTableIdx_MP_5GB_N_TxPowerTrack_USB_8188F, DELTA_SWINGIDX_SIZE*3); +#endif +} + +/****************************************************************************** +* TXPWR_LMT.TXT +******************************************************************************/ + +const char *Array_MP_8188F_TXPWR_LMT[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "01", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "02", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "02", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "02", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "03", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "03", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "03", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "04", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "04", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "05", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "05", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "05", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "06", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "06", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "06", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "07", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "07", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "08", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "08", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "08", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "09", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "09", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "09", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "10", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "10", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "11", "32", + "ETSI", "2.4G", "20M", "CCK", "1T", "11", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "11", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "12", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "12", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "12", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "13", "26", + "MKK", "2.4G", "20M", "CCK", "1T", "13", "32", + "FCC", "2.4G", "20M", "CCK", "1T", "14", "63", + "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", + "MKK", "2.4G", "20M", "CCK", "1T", "14", "32", + "FCC", "2.4G", "20M", "OFDM", "1T", "01", "28", + "ETSI", "2.4G", "20M", "OFDM", "1T", "01", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "01", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "28", + "ETSI", "2.4G", "20M", "OFDM", "1T", "02", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "02", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "03", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "03", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "04", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "04", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "04", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "05", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "05", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "06", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "06", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "07", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "07", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "07", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "30", + "ETSI", "2.4G", "20M", "OFDM", "1T", "08", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "08", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "09", "28", + "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "09", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "10", "28", + "ETSI", "2.4G", "20M", "OFDM", "1T", "10", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "10", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", + "ETSI", "2.4G", "20M", "OFDM", "1T", "11", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "11", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "12", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "12", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "13", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "13", "30", + "MKK", "2.4G", "20M", "OFDM", "1T", "13", "30", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", + "ETSI", "2.4G", "20M", "OFDM", "1T", "14", "63", + "MKK", "2.4G", "20M", "OFDM", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "1T", "01", "28", + "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", + "MKK", "2.4G", "20M", "HT", "1T", "01", "30", + "FCC", "2.4G", "20M", "HT", "1T", "02", "28", + "ETSI", "2.4G", "20M", "HT", "1T", "02", "30", + "MKK", "2.4G", "20M", "HT", "1T", "02", "30", + "FCC", "2.4G", "20M", "HT", "1T", "03", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "03", "30", + "MKK", "2.4G", "20M", "HT", "1T", "03", "30", + "FCC", "2.4G", "20M", "HT", "1T", "04", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", + "MKK", "2.4G", "20M", "HT", "1T", "04", "30", + "FCC", "2.4G", "20M", "HT", "1T", "05", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "05", "30", + "MKK", "2.4G", "20M", "HT", "1T", "05", "30", + "FCC", "2.4G", "20M", "HT", "1T", "06", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "06", "30", + "MKK", "2.4G", "20M", "HT", "1T", "06", "30", + "FCC", "2.4G", "20M", "HT", "1T", "07", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", + "MKK", "2.4G", "20M", "HT", "1T", "07", "30", + "FCC", "2.4G", "20M", "HT", "1T", "08", "30", + "ETSI", "2.4G", "20M", "HT", "1T", "08", "30", + "MKK", "2.4G", "20M", "HT", "1T", "08", "30", + "FCC", "2.4G", "20M", "HT", "1T", "09", "28", + "ETSI", "2.4G", "20M", "HT", "1T", "09", "30", + "MKK", "2.4G", "20M", "HT", "1T", "09", "30", + "FCC", "2.4G", "20M", "HT", "1T", "10", "28", + "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", + "MKK", "2.4G", "20M", "HT", "1T", "10", "30", + "FCC", "2.4G", "20M", "HT", "1T", "11", "28", + "ETSI", "2.4G", "20M", "HT", "1T", "11", "30", + "MKK", "2.4G", "20M", "HT", "1T", "11", "30", + "FCC", "2.4G", "20M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "12", "30", + "MKK", "2.4G", "20M", "HT", "1T", "12", "30", + "FCC", "2.4G", "20M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", + "MKK", "2.4G", "20M", "HT", "1T", "13", "30", + "FCC", "2.4G", "20M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "1T", "14", "63", + "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "28", + "ETSI", "2.4G", "20M", "HT", "2T", "01", "30", + "MKK", "2.4G", "20M", "HT", "2T", "01", "30", + "FCC", "2.4G", "20M", "HT", "2T", "02", "28", + "ETSI", "2.4G", "20M", "HT", "2T", "02", "30", + "MKK", "2.4G", "20M", "HT", "2T", "02", "30", + "FCC", "2.4G", "20M", "HT", "2T", "03", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "03", "30", + "MKK", "2.4G", "20M", "HT", "2T", "03", "30", + "FCC", "2.4G", "20M", "HT", "2T", "04", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "04", "30", + "MKK", "2.4G", "20M", "HT", "2T", "04", "30", + "FCC", "2.4G", "20M", "HT", "2T", "05", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "05", "30", + "MKK", "2.4G", "20M", "HT", "2T", "05", "30", + "FCC", "2.4G", "20M", "HT", "2T", "06", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "06", "30", + "MKK", "2.4G", "20M", "HT", "2T", "06", "30", + "FCC", "2.4G", "20M", "HT", "2T", "07", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "07", "30", + "MKK", "2.4G", "20M", "HT", "2T", "07", "30", + "FCC", "2.4G", "20M", "HT", "2T", "08", "30", + "ETSI", "2.4G", "20M", "HT", "2T", "08", "30", + "MKK", "2.4G", "20M", "HT", "2T", "08", "30", + "FCC", "2.4G", "20M", "HT", "2T", "09", "28", + "ETSI", "2.4G", "20M", "HT", "2T", "09", "30", + "MKK", "2.4G", "20M", "HT", "2T", "09", "30", + "FCC", "2.4G", "20M", "HT", "2T", "10", "28", + "ETSI", "2.4G", "20M", "HT", "2T", "10", "30", + "MKK", "2.4G", "20M", "HT", "2T", "10", "30", + "FCC", "2.4G", "20M", "HT", "2T", "11", "28", + "ETSI", "2.4G", "20M", "HT", "2T", "11", "30", + "MKK", "2.4G", "20M", "HT", "2T", "11", "30", + "FCC", "2.4G", "20M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "12", "30", + "MKK", "2.4G", "20M", "HT", "2T", "12", "30", + "FCC", "2.4G", "20M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "13", "30", + "MKK", "2.4G", "20M", "HT", "2T", "13", "30", + "FCC", "2.4G", "20M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", + "MKK", "2.4G", "20M", "HT", "2T", "14", "63", + "FCC", "2.4G", "40M", "HT", "1T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "01", "63", + "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "02", "63", + "MKK", "2.4G", "40M", "HT", "1T", "02", "63", + "FCC", "2.4G", "40M", "HT", "1T", "03", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "03", "26", + "MKK", "2.4G", "40M", "HT", "1T", "03", "26", + "FCC", "2.4G", "40M", "HT", "1T", "04", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "04", "26", + "MKK", "2.4G", "40M", "HT", "1T", "04", "26", + "FCC", "2.4G", "40M", "HT", "1T", "05", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "05", "26", + "MKK", "2.4G", "40M", "HT", "1T", "05", "26", + "FCC", "2.4G", "40M", "HT", "1T", "06", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "06", "26", + "MKK", "2.4G", "40M", "HT", "1T", "06", "26", + "FCC", "2.4G", "40M", "HT", "1T", "07", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "07", "26", + "MKK", "2.4G", "40M", "HT", "1T", "07", "26", + "FCC", "2.4G", "40M", "HT", "1T", "08", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "08", "26", + "MKK", "2.4G", "40M", "HT", "1T", "08", "26", + "FCC", "2.4G", "40M", "HT", "1T", "09", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "09", "26", + "MKK", "2.4G", "40M", "HT", "1T", "09", "26", + "FCC", "2.4G", "40M", "HT", "1T", "10", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "10", "26", + "MKK", "2.4G", "40M", "HT", "1T", "10", "26", + "FCC", "2.4G", "40M", "HT", "1T", "11", "26", + "ETSI", "2.4G", "40M", "HT", "1T", "11", "26", + "MKK", "2.4G", "40M", "HT", "1T", "11", "26", + "FCC", "2.4G", "40M", "HT", "1T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "12", "26", + "MKK", "2.4G", "40M", "HT", "1T", "12", "26", + "FCC", "2.4G", "40M", "HT", "1T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "13", "26", + "MKK", "2.4G", "40M", "HT", "1T", "13", "26", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "1T", "14", "63", + "MKK", "2.4G", "40M", "HT", "1T", "14", "63", + "FCC", "2.4G", "40M", "HT", "2T", "01", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", + "MKK", "2.4G", "40M", "HT", "2T", "01", "63", + "FCC", "2.4G", "40M", "HT", "2T", "02", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "02", "63", + "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "03", "26", + "MKK", "2.4G", "40M", "HT", "2T", "03", "26", + "FCC", "2.4G", "40M", "HT", "2T", "04", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "04", "26", + "MKK", "2.4G", "40M", "HT", "2T", "04", "26", + "FCC", "2.4G", "40M", "HT", "2T", "05", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "05", "26", + "MKK", "2.4G", "40M", "HT", "2T", "05", "26", + "FCC", "2.4G", "40M", "HT", "2T", "06", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "06", "26", + "MKK", "2.4G", "40M", "HT", "2T", "06", "26", + "FCC", "2.4G", "40M", "HT", "2T", "07", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "07", "26", + "MKK", "2.4G", "40M", "HT", "2T", "07", "26", + "FCC", "2.4G", "40M", "HT", "2T", "08", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "08", "26", + "MKK", "2.4G", "40M", "HT", "2T", "08", "26", + "FCC", "2.4G", "40M", "HT", "2T", "09", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "09", "26", + "MKK", "2.4G", "40M", "HT", "2T", "09", "26", + "FCC", "2.4G", "40M", "HT", "2T", "10", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "10", "26", + "MKK", "2.4G", "40M", "HT", "2T", "10", "26", + "FCC", "2.4G", "40M", "HT", "2T", "11", "26", + "ETSI", "2.4G", "40M", "HT", "2T", "11", "26", + "MKK", "2.4G", "40M", "HT", "2T", "11", "26", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "12", "26", + "MKK", "2.4G", "40M", "HT", "2T", "12", "26", + "FCC", "2.4G", "40M", "HT", "2T", "13", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "13", "26", + "MKK", "2.4G", "40M", "HT", "2T", "13", "26", + "FCC", "2.4G", "40M", "HT", "2T", "14", "63", + "ETSI", "2.4G", "40M", "HT", "2T", "14", "63", + "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "36", "32", + "MKK", "5G", "20M", "OFDM", "1T", "36", "32", + "FCC", "5G", "20M", "OFDM", "1T", "40", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", + "MKK", "5G", "20M", "OFDM", "1T", "40", "32", + "FCC", "5G", "20M", "OFDM", "1T", "44", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "44", "32", + "MKK", "5G", "20M", "OFDM", "1T", "44", "32", + "FCC", "5G", "20M", "OFDM", "1T", "48", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "48", "32", + "MKK", "5G", "20M", "OFDM", "1T", "48", "32", + "FCC", "5G", "20M", "OFDM", "1T", "52", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", + "MKK", "5G", "20M", "OFDM", "1T", "52", "32", + "FCC", "5G", "20M", "OFDM", "1T", "56", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "56", "32", + "MKK", "5G", "20M", "OFDM", "1T", "56", "32", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "60", "32", + "MKK", "5G", "20M", "OFDM", "1T", "60", "32", + "FCC", "5G", "20M", "OFDM", "1T", "64", "28", + "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", + "MKK", "5G", "20M", "OFDM", "1T", "64", "32", + "FCC", "5G", "20M", "OFDM", "1T", "100", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "100", "32", + "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "114", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "114", "32", + "MKK", "5G", "20M", "OFDM", "1T", "114", "32", + "FCC", "5G", "20M", "OFDM", "1T", "108", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", + "MKK", "5G", "20M", "OFDM", "1T", "108", "32", + "FCC", "5G", "20M", "OFDM", "1T", "112", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "112", "32", + "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "116", "32", + "MKK", "5G", "20M", "OFDM", "1T", "116", "32", + "FCC", "5G", "20M", "OFDM", "1T", "120", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", + "MKK", "5G", "20M", "OFDM", "1T", "120", "32", + "FCC", "5G", "20M", "OFDM", "1T", "124", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "124", "32", + "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", + "ETSI", "5G", "20M", "OFDM", "1T", "128", "32", + "MKK", "5G", "20M", "OFDM", "1T", "128", "32", + "FCC", "5G", "20M", "OFDM", "1T", "132", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", + "MKK", "5G", "20M", "OFDM", "1T", "132", "32", + "FCC", "5G", "20M", "OFDM", "1T", "136", "30", + "ETSI", "5G", "20M", "OFDM", "1T", "136", "32", + "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", + "ETSI", "5G", "20M", "OFDM", "1T", "140", "32", + "MKK", "5G", "20M", "OFDM", "1T", "140", "32", + "FCC", "5G", "20M", "OFDM", "1T", "149", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "149", "32", + "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "153", "32", + "MKK", "5G", "20M", "OFDM", "1T", "153", "63", + "FCC", "5G", "20M", "OFDM", "1T", "157", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "157", "32", + "MKK", "5G", "20M", "OFDM", "1T", "157", "63", + "FCC", "5G", "20M", "OFDM", "1T", "161", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "161", "32", + "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "34", + "ETSI", "5G", "20M", "OFDM", "1T", "165", "32", + "MKK", "5G", "20M", "OFDM", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "1T", "36", "30", + "ETSI", "5G", "20M", "HT", "1T", "36", "32", + "MKK", "5G", "20M", "HT", "1T", "36", "32", + "FCC", "5G", "20M", "HT", "1T", "40", "30", + "ETSI", "5G", "20M", "HT", "1T", "40", "32", + "MKK", "5G", "20M", "HT", "1T", "40", "32", + "FCC", "5G", "20M", "HT", "1T", "44", "30", + "ETSI", "5G", "20M", "HT", "1T", "44", "32", + "MKK", "5G", "20M", "HT", "1T", "44", "32", + "FCC", "5G", "20M", "HT", "1T", "48", "30", + "ETSI", "5G", "20M", "HT", "1T", "48", "32", + "MKK", "5G", "20M", "HT", "1T", "48", "32", + "FCC", "5G", "20M", "HT", "1T", "52", "34", + "ETSI", "5G", "20M", "HT", "1T", "52", "32", + "MKK", "5G", "20M", "HT", "1T", "52", "32", + "FCC", "5G", "20M", "HT", "1T", "56", "34", + "ETSI", "5G", "20M", "HT", "1T", "56", "32", + "MKK", "5G", "20M", "HT", "1T", "56", "32", + "FCC", "5G", "20M", "HT", "1T", "60", "32", + "ETSI", "5G", "20M", "HT", "1T", "60", "32", + "MKK", "5G", "20M", "HT", "1T", "60", "32", + "FCC", "5G", "20M", "HT", "1T", "64", "28", + "ETSI", "5G", "20M", "HT", "1T", "64", "32", + "MKK", "5G", "20M", "HT", "1T", "64", "32", + "FCC", "5G", "20M", "HT", "1T", "100", "30", + "ETSI", "5G", "20M", "HT", "1T", "100", "32", + "MKK", "5G", "20M", "HT", "1T", "100", "32", + "FCC", "5G", "20M", "HT", "1T", "114", "30", + "ETSI", "5G", "20M", "HT", "1T", "114", "32", + "MKK", "5G", "20M", "HT", "1T", "114", "32", + "FCC", "5G", "20M", "HT", "1T", "108", "32", + "ETSI", "5G", "20M", "HT", "1T", "108", "32", + "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "34", + "ETSI", "5G", "20M", "HT", "1T", "112", "32", + "MKK", "5G", "20M", "HT", "1T", "112", "32", + "FCC", "5G", "20M", "HT", "1T", "116", "34", + "ETSI", "5G", "20M", "HT", "1T", "116", "32", + "MKK", "5G", "20M", "HT", "1T", "116", "32", + "FCC", "5G", "20M", "HT", "1T", "120", "34", + "ETSI", "5G", "20M", "HT", "1T", "120", "32", + "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "34", + "ETSI", "5G", "20M", "HT", "1T", "124", "32", + "MKK", "5G", "20M", "HT", "1T", "124", "32", + "FCC", "5G", "20M", "HT", "1T", "128", "32", + "ETSI", "5G", "20M", "HT", "1T", "128", "32", + "MKK", "5G", "20M", "HT", "1T", "128", "32", + "FCC", "5G", "20M", "HT", "1T", "132", "30", + "ETSI", "5G", "20M", "HT", "1T", "132", "32", + "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "30", + "ETSI", "5G", "20M", "HT", "1T", "136", "32", + "MKK", "5G", "20M", "HT", "1T", "136", "32", + "FCC", "5G", "20M", "HT", "1T", "140", "28", + "ETSI", "5G", "20M", "HT", "1T", "140", "32", + "MKK", "5G", "20M", "HT", "1T", "140", "32", + "FCC", "5G", "20M", "HT", "1T", "149", "34", + "ETSI", "5G", "20M", "HT", "1T", "149", "32", + "MKK", "5G", "20M", "HT", "1T", "149", "63", + "FCC", "5G", "20M", "HT", "1T", "153", "34", + "ETSI", "5G", "20M", "HT", "1T", "153", "32", + "MKK", "5G", "20M", "HT", "1T", "153", "63", + "FCC", "5G", "20M", "HT", "1T", "157", "34", + "ETSI", "5G", "20M", "HT", "1T", "157", "32", + "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "34", + "ETSI", "5G", "20M", "HT", "1T", "161", "32", + "MKK", "5G", "20M", "HT", "1T", "161", "63", + "FCC", "5G", "20M", "HT", "1T", "165", "34", + "ETSI", "5G", "20M", "HT", "1T", "165", "32", + "MKK", "5G", "20M", "HT", "1T", "165", "63", + "FCC", "5G", "20M", "HT", "2T", "36", "28", + "ETSI", "5G", "20M", "HT", "2T", "36", "30", + "MKK", "5G", "20M", "HT", "2T", "36", "30", + "FCC", "5G", "20M", "HT", "2T", "40", "28", + "ETSI", "5G", "20M", "HT", "2T", "40", "30", + "MKK", "5G", "20M", "HT", "2T", "40", "30", + "FCC", "5G", "20M", "HT", "2T", "44", "28", + "ETSI", "5G", "20M", "HT", "2T", "44", "30", + "MKK", "5G", "20M", "HT", "2T", "44", "30", + "FCC", "5G", "20M", "HT", "2T", "48", "28", + "ETSI", "5G", "20M", "HT", "2T", "48", "30", + "MKK", "5G", "20M", "HT", "2T", "48", "30", + "FCC", "5G", "20M", "HT", "2T", "52", "34", + "ETSI", "5G", "20M", "HT", "2T", "52", "30", + "MKK", "5G", "20M", "HT", "2T", "52", "30", + "FCC", "5G", "20M", "HT", "2T", "56", "32", + "ETSI", "5G", "20M", "HT", "2T", "56", "30", + "MKK", "5G", "20M", "HT", "2T", "56", "30", + "FCC", "5G", "20M", "HT", "2T", "60", "30", + "ETSI", "5G", "20M", "HT", "2T", "60", "30", + "MKK", "5G", "20M", "HT", "2T", "60", "30", + "FCC", "5G", "20M", "HT", "2T", "64", "26", + "ETSI", "5G", "20M", "HT", "2T", "64", "30", + "MKK", "5G", "20M", "HT", "2T", "64", "30", + "FCC", "5G", "20M", "HT", "2T", "100", "28", + "ETSI", "5G", "20M", "HT", "2T", "100", "30", + "MKK", "5G", "20M", "HT", "2T", "100", "30", + "FCC", "5G", "20M", "HT", "2T", "114", "28", + "ETSI", "5G", "20M", "HT", "2T", "114", "30", + "MKK", "5G", "20M", "HT", "2T", "114", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "30", + "ETSI", "5G", "20M", "HT", "2T", "108", "30", + "MKK", "5G", "20M", "HT", "2T", "108", "30", + "FCC", "5G", "20M", "HT", "2T", "112", "32", + "ETSI", "5G", "20M", "HT", "2T", "112", "30", + "MKK", "5G", "20M", "HT", "2T", "112", "30", + "FCC", "5G", "20M", "HT", "2T", "116", "32", + "ETSI", "5G", "20M", "HT", "2T", "116", "30", + "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "34", + "ETSI", "5G", "20M", "HT", "2T", "120", "30", + "MKK", "5G", "20M", "HT", "2T", "120", "30", + "FCC", "5G", "20M", "HT", "2T", "124", "32", + "ETSI", "5G", "20M", "HT", "2T", "124", "30", + "MKK", "5G", "20M", "HT", "2T", "124", "30", + "FCC", "5G", "20M", "HT", "2T", "128", "30", + "ETSI", "5G", "20M", "HT", "2T", "128", "30", + "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "28", + "ETSI", "5G", "20M", "HT", "2T", "132", "30", + "MKK", "5G", "20M", "HT", "2T", "132", "30", + "FCC", "5G", "20M", "HT", "2T", "136", "28", + "ETSI", "5G", "20M", "HT", "2T", "136", "30", + "MKK", "5G", "20M", "HT", "2T", "136", "30", + "FCC", "5G", "20M", "HT", "2T", "140", "26", + "ETSI", "5G", "20M", "HT", "2T", "140", "30", + "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "149", "34", + "ETSI", "5G", "20M", "HT", "2T", "149", "30", + "MKK", "5G", "20M", "HT", "2T", "149", "63", + "FCC", "5G", "20M", "HT", "2T", "153", "34", + "ETSI", "5G", "20M", "HT", "2T", "153", "30", + "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "34", + "ETSI", "5G", "20M", "HT", "2T", "157", "30", + "MKK", "5G", "20M", "HT", "2T", "157", "63", + "FCC", "5G", "20M", "HT", "2T", "161", "34", + "ETSI", "5G", "20M", "HT", "2T", "161", "30", + "MKK", "5G", "20M", "HT", "2T", "161", "63", + "FCC", "5G", "20M", "HT", "2T", "165", "34", + "ETSI", "5G", "20M", "HT", "2T", "165", "30", + "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "30", + "ETSI", "5G", "40M", "HT", "1T", "38", "32", + "MKK", "5G", "40M", "HT", "1T", "38", "32", + "FCC", "5G", "40M", "HT", "1T", "46", "30", + "ETSI", "5G", "40M", "HT", "1T", "46", "32", + "MKK", "5G", "40M", "HT", "1T", "46", "32", + "FCC", "5G", "40M", "HT", "1T", "54", "32", + "ETSI", "5G", "40M", "HT", "1T", "54", "32", + "MKK", "5G", "40M", "HT", "1T", "54", "32", + "FCC", "5G", "40M", "HT", "1T", "62", "32", + "ETSI", "5G", "40M", "HT", "1T", "62", "32", + "MKK", "5G", "40M", "HT", "1T", "62", "32", + "FCC", "5G", "40M", "HT", "1T", "102", "28", + "ETSI", "5G", "40M", "HT", "1T", "102", "32", + "MKK", "5G", "40M", "HT", "1T", "102", "32", + "FCC", "5G", "40M", "HT", "1T", "110", "32", + "ETSI", "5G", "40M", "HT", "1T", "110", "32", + "MKK", "5G", "40M", "HT", "1T", "110", "32", + "FCC", "5G", "40M", "HT", "1T", "118", "34", + "ETSI", "5G", "40M", "HT", "1T", "118", "32", + "MKK", "5G", "40M", "HT", "1T", "118", "32", + "FCC", "5G", "40M", "HT", "1T", "126", "34", + "ETSI", "5G", "40M", "HT", "1T", "126", "32", + "MKK", "5G", "40M", "HT", "1T", "126", "32", + "FCC", "5G", "40M", "HT", "1T", "134", "32", + "ETSI", "5G", "40M", "HT", "1T", "134", "32", + "MKK", "5G", "40M", "HT", "1T", "134", "32", + "FCC", "5G", "40M", "HT", "1T", "151", "34", + "ETSI", "5G", "40M", "HT", "1T", "151", "32", + "MKK", "5G", "40M", "HT", "1T", "151", "63", + "FCC", "5G", "40M", "HT", "1T", "159", "34", + "ETSI", "5G", "40M", "HT", "1T", "159", "32", + "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "28", + "ETSI", "5G", "40M", "HT", "2T", "38", "30", + "MKK", "5G", "40M", "HT", "2T", "38", "30", + "FCC", "5G", "40M", "HT", "2T", "46", "28", + "ETSI", "5G", "40M", "HT", "2T", "46", "30", + "MKK", "5G", "40M", "HT", "2T", "46", "30", + "FCC", "5G", "40M", "HT", "2T", "54", "30", + "ETSI", "5G", "40M", "HT", "2T", "54", "30", + "MKK", "5G", "40M", "HT", "2T", "54", "30", + "FCC", "5G", "40M", "HT", "2T", "62", "30", + "ETSI", "5G", "40M", "HT", "2T", "62", "30", + "MKK", "5G", "40M", "HT", "2T", "62", "30", + "FCC", "5G", "40M", "HT", "2T", "102", "26", + "ETSI", "5G", "40M", "HT", "2T", "102", "30", + "MKK", "5G", "40M", "HT", "2T", "102", "30", + "FCC", "5G", "40M", "HT", "2T", "110", "30", + "ETSI", "5G", "40M", "HT", "2T", "110", "30", + "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "34", + "ETSI", "5G", "40M", "HT", "2T", "118", "30", + "MKK", "5G", "40M", "HT", "2T", "118", "30", + "FCC", "5G", "40M", "HT", "2T", "126", "32", + "ETSI", "5G", "40M", "HT", "2T", "126", "30", + "MKK", "5G", "40M", "HT", "2T", "126", "30", + "FCC", "5G", "40M", "HT", "2T", "134", "30", + "ETSI", "5G", "40M", "HT", "2T", "134", "30", + "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "151", "34", + "ETSI", "5G", "40M", "HT", "2T", "151", "30", + "MKK", "5G", "40M", "HT", "2T", "151", "63", + "FCC", "5G", "40M", "HT", "2T", "159", "34", + "ETSI", "5G", "40M", "HT", "2T", "159", "30", + "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "30", + "ETSI", "5G", "80M", "VHT", "1T", "42", "32", + "MKK", "5G", "80M", "VHT", "1T", "42", "32", + "FCC", "5G", "80M", "VHT", "1T", "58", "28", + "ETSI", "5G", "80M", "VHT", "1T", "58", "32", + "MKK", "5G", "80M", "VHT", "1T", "58", "32", + "FCC", "5G", "80M", "VHT", "1T", "106", "30", + "ETSI", "5G", "80M", "VHT", "1T", "106", "32", + "MKK", "5G", "80M", "VHT", "1T", "106", "32", + "FCC", "5G", "80M", "VHT", "1T", "122", "34", + "ETSI", "5G", "80M", "VHT", "1T", "122", "32", + "MKK", "5G", "80M", "VHT", "1T", "122", "32", + "FCC", "5G", "80M", "VHT", "1T", "155", "34", + "ETSI", "5G", "80M", "VHT", "1T", "155", "32", + "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "28", + "ETSI", "5G", "80M", "VHT", "2T", "42", "30", + "MKK", "5G", "80M", "VHT", "2T", "42", "30", + "FCC", "5G", "80M", "VHT", "2T", "58", "26", + "ETSI", "5G", "80M", "VHT", "2T", "58", "30", + "MKK", "5G", "80M", "VHT", "2T", "58", "30", + "FCC", "5G", "80M", "VHT", "2T", "106", "28", + "ETSI", "5G", "80M", "VHT", "2T", "106", "30", + "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "32", + "ETSI", "5G", "80M", "VHT", "2T", "122", "30", + "MKK", "5G", "80M", "VHT", "2T", "122", "30", + "FCC", "5G", "80M", "VHT", "2T", "155", "34", + "ETSI", "5G", "80M", "VHT", "2T", "155", "30", + "MKK", "5G", "80M", "VHT", "2T", "155", "63" +}; + +void +ODM_ReadAndConfig_MP_8188F_TXPWR_LMT( + IN PDM_ODM_T pDM_Odm +) +{ + u4Byte i = 0; + u4Byte ArrayLen = sizeof(Array_MP_8188F_TXPWR_LMT)/sizeof(pu1Byte); + pu1Byte *Array = (pu1Byte *)Array_MP_8188F_TXPWR_LMT; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PADAPTER Adapter = pDM_Odm->Adapter; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + PlatformZeroMemory(pHalData->BufOfLinesPwrLmt, MAX_LINES_HWCONFIG_TXT*MAX_BYTES_LINE_HWCONFIG_TXT); + pHalData->nLinesReadPwrLmt = ArrayLen/7; +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===> ODM_ReadAndConfig_MP_8188F_TXPWR_LMT\n")); + + for (i = 0; i < ArrayLen; i += 7) { + pu1Byte regulation = Array[i]; + pu1Byte band = Array[i+1]; + pu1Byte bandwidth = Array[i+2]; + pu1Byte rate = Array[i+3]; + pu1Byte rfPath = Array[i+4]; + pu1Byte chnl = Array[i+5]; + pu1Byte val = Array[i+6]; + + odm_ConfigBB_TXPWR_LMT_8188F(pDM_Odm, regulation, band, bandwidth, rate, rfPath, chnl, val); +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + rsprintf((char *)pHalData->BufOfLinesPwrLmt[i/7], 100, "\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\",", + regulation, band, bandwidth, rate, rfPath, chnl, val); +#endif + } + +} + +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.h new file mode 100644 index 00000000..7bf5f488 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halhwimg8188f_rf.h @@ -0,0 +1,79 @@ +/****************************************************************************** +* +* 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 +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.18*/ +#if (RTL8188F_SUPPORT == 1) +#ifndef __INC_MP_RF_HW_IMG_8188F_H +#define __INC_MP_RF_HW_IMG_8188F_H + + +/****************************************************************************** +* RadioA.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_RadioA(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_RadioA(void); + +/****************************************************************************** +* TxPowerTrack_AP.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_AP(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_TxPowerTrack_AP(void); + +/****************************************************************************** +* TxPowerTrack_SDIO.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_SDIO(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_TxPowerTrack_SDIO(void); + +/****************************************************************************** +* TxPowerTrack_USB.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_TxPowerTrack_USB(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_TxPowerTrack_USB(void); + +/****************************************************************************** +* TXPWR_LMT.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8188F_TXPWR_LMT(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8188F_TXPWR_LMT(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.c new file mode 100644 index 00000000..3f9290a3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.c @@ -0,0 +1,3609 @@ +/****************************************************************************** + * + * 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" + +#define bMaskH3Bytes 0xffffff00 + +//#define SUCCESS 0 +//#define FAIL -1 + + +/*---------------------------Define Local Constant---------------------------*/ +// 2010/04/25 MH Define the max tx power tracking tx agc power. +#define ODM_TXPWRTRACK_MAX_IDX8188F 6 + +// MACRO definition for pRFCalibrateInfo->TxIQC_8188F[0] +#define PATH_S0 1 // RF_PATH_B +#define IDX_0xC94 0 +#define IDX_0xC80 1 +#define IDX_0xC4C 2 +#define IDX_0xC14 0 +#define IDX_0xCA0 1 +#define KEY 0 +#define VAL 1 + +// MACRO definition for pRFCalibrateInfo->TxIQC_8188F[1] +#define PATH_S1 0 // RF_PATH_A +#define IDX_0xC9C 0 +#define IDX_0xC88 1 +#define IDX_0xC4C 2 +#define IDX_0xC1C 0 +#define IDX_0xC78 1 + + + +/*---------------------------Define Local Constant---------------------------*/ + + +//3============================================================ +//3 Tx Power Tracking +//3============================================================ + + +void setIqkMatrix_8188F( + PDM_ODM_T pDM_Odm, + s1Byte OFDM_index, + u1Byte RFPath, + s4Byte IqkResult_X, + s4Byte IqkResult_Y +) +{ + s4Byte ele_A = 0, ele_D, ele_C = 0, value32; + + 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; + + //new element A = element D x X + if ((IqkResult_X != 0) && (*(pDM_Odm->pBandType) == ODM_BAND_2_4G)) { + if ((IqkResult_X & 0x00000200) != 0) //consider minus + IqkResult_X = IqkResult_X | 0xFFFFFC00; + ele_A = ((IqkResult_X * ele_D) >> 8) & 0x000003FF; + + //new element C = element D x Y + if ((IqkResult_Y & 0x00000200) != 0) + IqkResult_Y = IqkResult_Y | 0xFFFFFC00; + ele_C = ((IqkResult_Y * ele_D) >> 8) & 0x000003FF; + + if (RFPath == ODM_RF_PATH_A) + switch (RFPath) { + case ODM_RF_PATH_A: + //wirte new elements A, C, D to regC80 and regC94, element B is always 0 + value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; + ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C & 0x000003C0) >> 6; + ODM_SetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskH4Bits, value32); + + value32 = ((IqkResult_X * ele_D) >> 7) & 0x01; + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT24, value32); + break; + case ODM_RF_PATH_B: + //wirte new elements A, C, D to regC88 and regC9C, element B is always 0 + value32 = (ele_D << 22) | ((ele_C & 0x3F) << 16) | ele_A; + ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); + + value32 = (ele_C & 0x000003C0) >> 6; + ODM_SetBBReg(pDM_Odm, rOFDM0_XDTxAFE, bMaskH4Bits, value32); + + value32 = ((IqkResult_X * ele_D) >> 7) & 0x01; + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT28, value32); + + break; + default: + break; + } + } else { + switch (RFPath) { + case ODM_RF_PATH_A: + ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]); + ODM_SetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00); + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT24, 0x00); + break; + + case ODM_RF_PATH_B: + ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable_New[OFDM_index]); + ODM_SetBBReg(pDM_Odm, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT28, 0x00); + break; + + default: + break; + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("TxPwrTracking path B: X = 0x%x, Y = 0x%x ele_A = 0x%x ele_C = 0x%x ele_D = 0x%x 0xeb4 = 0x%x 0xebc = 0x%x\n", + (u4Byte)IqkResult_X, (u4Byte)IqkResult_Y, (u4Byte)ele_A, (u4Byte)ele_C, (u4Byte)ele_D, (u4Byte)IqkResult_X, (u4Byte)IqkResult_Y)); +} + +void DoIQK_8188F( + PVOID pDM_VOID, + u1Byte DeltaThermalIndex, + u1Byte ThermalValue, + u1Byte Threshold +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +#endif +#if(DM_ODM_SUPPORT_TYPE & ODM_CE) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); +#endif +#endif + + ODM_ResetIQKResult(pDM_Odm); + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) +#if USE_WORKITEM + PlatformAcquireMutex(&pHalData->mxChnlBwControl); +#else + PlatformAcquireSpinLock(Adapter, RT_CHANNEL_AND_BANDWIDTH_SPINLOCK); +#endif +#elif((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) + PlatformAcquireMutex(&pHalData->mxChnlBwControl); +#endif +#endif + + + pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue; +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + PHY_IQCalibrate_8188F(pDM_Odm, FALSE, FALSE); +#else + PHY_IQCalibrate_8188F(Adapter, FALSE, FALSE); +#endif + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) +#if USE_WORKITEM + PlatformReleaseMutex(&pHalData->mxChnlBwControl); +#else + PlatformReleaseSpinLock(Adapter, RT_CHANNEL_AND_BANDWIDTH_SPINLOCK); +#endif +#elif((DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)) + PlatformReleaseMutex(&pHalData->mxChnlBwControl); +#endif +#endif +} + +/*----------------------------------------------------------------------------- + * Function: odm_TxPwrTrackSetPwr88E() + * + * Overview: 88E change all channel tx power accordign to flag. + * OFDM & CCK are all different. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 04/23/2012 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +VOID +ODM_TxPwrTrackSetPwr_8188F( + IN PVOID pDM_VOID, + PWRTRACK_METHOD Method, + u1Byte RFPath, + u1Byte ChannelMappedIndex +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + u1Byte PwrTrackingLimit_OFDM = 34; //+0dB + u1Byte PwrTrackingLimit_CCK = CCK_TABLE_SIZE_88F-1; //-2dB + u1Byte TxRate = 0xFF; + s1Byte Final_OFDM_Swing_Index = 0; + s1Byte Final_CCK_Swing_Index = 0; +// u1Byte i = 0; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + +#if 0 +#if (MP_DRIVER==1) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PMPT_CONTEXT pMptCtx = &(Adapter->MptCtx); + TxRate = MptToMgntRate(pMptCtx->MptRateIndex); +#else + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + if (!pMgntInfo->ForcedDataRate) { //auto rate + if (pDM_Odm->TxRate != 0xFF) + TxRate = HwRateToMRate8812(pDM_Odm->TxRate); + } else //force rate + TxRate = (u1Byte) pMgntInfo->ForcedDataRate; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("===>ODM_TxPwrTrackSetPwr8188F\n")); + + if (TxRate != 0xFF) { + //2 CCK + if ((TxRate >= MGN_1M) && (TxRate <= MGN_11M)) + PwrTrackingLimit_CCK = CCK_TABLE_SIZE_88F-1; //-2dB + //2 OFDM + else if ((TxRate >= MGN_6M) && (TxRate <= MGN_48M)) + PwrTrackingLimit_OFDM = 36; //+3dB + else if (TxRate == MGN_54M) + PwrTrackingLimit_OFDM = 34; //+2dB + + //2 HT + else if ((TxRate >= MGN_MCS0) && (TxRate <= MGN_MCS2)) //QPSK/BPSK + PwrTrackingLimit_OFDM = 38; //+4dB + else if ((TxRate >= MGN_MCS3) && (TxRate <= MGN_MCS4)) //16QAM + PwrTrackingLimit_OFDM = 36; //+3dB + else if ((TxRate >= MGN_MCS5) && (TxRate <= MGN_MCS7)) //64QAM + PwrTrackingLimit_OFDM = 34; //+2dB + + else + PwrTrackingLimit_OFDM = pRFCalibrateInfo->DefaultOfdmIndex; //Default OFDM index = 30 + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("TxRate=0x%x, PwrTrackingLimit=%d\n", TxRate, PwrTrackingLimit_OFDM)); + + RT_TRACE(COMP_CMD, DBG_LOUD, ("Method=%d\n", Method)); + + if (Method == TXAGC) + { + //u1Byte rf = 0; +#if (MP_DRIVER == 1) + u4Byte pwr = 0, TxAGC = 0; +#endif + PADAPTER Adapter = pDM_Odm->Adapter; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("odm_TxPwrTrackSetPwr8188F CH=%d\n", *(pDM_Odm->pChannel))); + + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + + #if (MP_DRIVER == 1) + if ( (pDM_Odm->mp_mode) == 1) { + pwr = PHY_QueryBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1); + pwr += pDM_Odm->RFCalibrateInfo.PowerIndexOffset[ODM_RF_PATH_A]; + PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pwr); //CCK 1M + + if (pwr>0x3F) + pwr=0x3F; //add by Mingzhi.Guo 2015-04-10 + else if(pwr <= 0) + pwr=0; + + TxAGC = (pwr<<16)|(pwr<<8)|(pwr); + + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC); //CCK 2~11M + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ODM_TxPwrTrackSetPwr8188F: CCK Tx-rf(A) Power = 0x%x\n", TxAGC)); + + pwr = PHY_QueryBBReg(Adapter, rTxAGC_A_Rate18_06, 0xFF); + pwr += (pRFCalibrateInfo->BbSwingIdxOfdm[ODM_RF_PATH_A] - pRFCalibrateInfo->BbSwingIdxOfdmBase[ODM_RF_PATH_A]); + TxAGC |= ((pwr << 24) | (pwr << 16) | (pwr << 8) | pwr); + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); + // PHY_SetBBReg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); + // PHY_SetBBReg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ODM_TxPwrTrackSetPwr8188F: OFDM Tx-rf(A) Power = 0x%x\n", TxAGC)); + } else +#endif + { + //PHY_SetTxPowerLevelByPath8188F(Adapter, pHalData->CurrentChannel, ODM_RF_PATH_A); + //PHY_SetTxPowerLevel8188F(pDM_Odm->Adapter, *pDM_Odm->pChannel); + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE; + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE; + + if (RFPath == ODM_RF_PATH_A) { + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, CCK); + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, OFDM); + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, HT_MCS0_MCS7); + } + } + +#endif +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + //PHY_RF6052SetCCKTxPower(pDM_Odm->priv, *(pDM_Odm->pChannel)); + //PHY_RF6052SetOFDMTxPower(pDM_Odm->priv, *(pDM_Odm->pChannel)); +#endif + + } else if (Method == BBSWING) { + Final_OFDM_Swing_Index = pRFCalibrateInfo->DefaultOfdmIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]; + Final_CCK_Swing_Index = pRFCalibrateInfo->DefaultCckIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]; + + // Adjust BB swing by OFDM IQ matrix + if (Final_OFDM_Swing_Index >= PwrTrackingLimit_OFDM) + Final_OFDM_Swing_Index = PwrTrackingLimit_OFDM; + else if (Final_OFDM_Swing_Index <= 0) + Final_OFDM_Swing_Index = 0; + + if (Final_CCK_Swing_Index >= CCK_TABLE_SIZE_88F) + Final_CCK_Swing_Index = CCK_TABLE_SIZE_88F - 1; + else if ((s1Byte)pRFCalibrateInfo->BbSwingIdxCck < 0) + Final_CCK_Swing_Index = 0; + + if (RFPath == ODM_RF_PATH_A) + { + + setIqkMatrix_8188F(pDM_Odm, Final_OFDM_Swing_Index, ODM_RF_PATH_A, + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + + ODM_Write1Byte(pDM_Odm, 0xa22, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][0]); + ODM_Write1Byte(pDM_Odm, 0xa23, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][1]); + ODM_Write1Byte(pDM_Odm, 0xa24, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][2]); + ODM_Write1Byte(pDM_Odm, 0xa25, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][3]); + ODM_Write1Byte(pDM_Odm, 0xa26, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][4]); + ODM_Write1Byte(pDM_Odm, 0xa27, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][5]); + ODM_Write1Byte(pDM_Odm, 0xa28, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][6]); + ODM_Write1Byte(pDM_Odm, 0xa29, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][7]); + ODM_Write1Byte(pDM_Odm, 0xa9a, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][8]); + ODM_Write1Byte(pDM_Odm, 0xa9b, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][9]); + ODM_Write1Byte(pDM_Odm, 0xa9c, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][10]); + ODM_Write1Byte(pDM_Odm, 0xa9d, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][11]); + ODM_Write1Byte(pDM_Odm, 0xaa0, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][12]); + ODM_Write1Byte(pDM_Odm, 0xaa1, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][13]); + ODM_Write1Byte(pDM_Odm, 0xaa2, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][14]); + ODM_Write1Byte(pDM_Odm, 0xaa3, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][15]); + } + + } + else if (Method == MIX_MODE) + { + #if (MP_DRIVER == 1) + //u4Byte pwr = 0, TxAGC = 0; + u4Byte TxAGC=0; //add by Mingzhi.Guo 2015-04-10 + s4Byte pwr=0; + #endif + RT_TRACE(COMP_CMD, DBG_LOUD, ("Method is MIX_MODE ====> \n")); + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("pRFCalibrateInfo->DefaultOfdmIndex=%d, pRFCalibrateInfo->DefaultCCKIndex=%d, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", + pRFCalibrateInfo->DefaultOfdmIndex, pRFCalibrateInfo->DefaultCckIndex, pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath],RFPath )); + + Final_OFDM_Swing_Index = pRFCalibrateInfo->DefaultOfdmIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]; + Final_CCK_Swing_Index = pRFCalibrateInfo->DefaultCckIndex + pRFCalibrateInfo->Absolute_OFDMSwingIdx[RFPath]; + if (RFPath == ODM_RF_PATH_A) { + if (Final_OFDM_Swing_Index > PwrTrackingLimit_OFDM) { //BBSwing higher then Limit + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - PwrTrackingLimit_OFDM; + + setIqkMatrix_8188F(pDM_Odm, PwrTrackingLimit_OFDM, RFPath, + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE; + + //Set TxAGC Page C{}; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", + PwrTrackingLimit_OFDM, pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath])); + } else if (Final_OFDM_Swing_Index < pRFCalibrateInfo->DefaultOfdmIndex) { + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index - pRFCalibrateInfo->DefaultOfdmIndex; + setIqkMatrix_8188F(pDM_Odm, pRFCalibrateInfo->DefaultOfdmIndex, ODM_RF_PATH_A, + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA = TRUE; + /* Set TxAGC Page C{}; */ + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Path_A Lower then BBSwing lower bound 28 , Remnant TxAGC Value = %d\n", + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath])); + } + + /* + else if (Final_OFDM_Swing_Index < 0) + { + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = Final_OFDM_Swing_Index ; + setIqkMatrix_8188F(pDM_Odm, 0, ODM_RF_PATH_A, + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA=TRUE; + //Set TxAGC Page C{}; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath])); + } + */ + else { + setIqkMatrix_8188F(pDM_Odm, Final_OFDM_Swing_Index, ODM_RF_PATH_A, + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][0], + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[ChannelMappedIndex].Value[0][1]); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, + ("******Path_A Compensate with BBSwing , Final_OFDM_Swing_Index = %d\n", Final_OFDM_Swing_Index)); + + if (pRFCalibrateInfo->Modify_TxAGC_Flag_PathA) { //If TxAGC has changed, reset TxAGC again + pRFCalibrateInfo->Remnant_OFDMSwingIdx[RFPath] = 0; + } + } + #if (MP_DRIVER == 1) && (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + if ( (pDM_Odm->mp_mode) == 1) { + pwr = PHY_QueryBBReg(Adapter, rTxAGC_A_Rate18_06, 0xFF); + pwr += (pRFCalibrateInfo->Remnant_OFDMSwingIdx[ODM_RF_PATH_A] - pRFCalibrateInfo->Modify_TxAGC_Value_OFDM); + + if (pwr>0x3F) pwr=0x3F; //add by Mingzhi.Guo 2015-04-10 + else if(pwr<0) pwr=0; + + TxAGC |= ((pwr<<24)|(pwr<<16)|(pwr<<8)|pwr); + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC); + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC); + //PHY_SetBBReg(Adapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC); + //PHY_SetBBReg(Adapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ODM_TxPwrTrackSetPwr8188F: OFDM Tx-rf(A) Power = 0x%x\n", TxAGC)); + + + } + else + #endif + { + //Set TxAGC Page C{}; + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, OFDM ); + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, HT_MCS0_MCS7 ); + } + pRFCalibrateInfo->Modify_TxAGC_Value_OFDM=pRFCalibrateInfo->Remnant_OFDMSwingIdx[ODM_RF_PATH_A] ; //add by Mingzhi.Guo + + + //MIX mode: CCK + if(Final_CCK_Swing_Index > PwrTrackingLimit_CCK) + { + pRFCalibrateInfo->Remnant_CCKSwingIdx = Final_CCK_Swing_Index - PwrTrackingLimit_CCK; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Path_A CCK Over Limit , PwrTrackingLimit_CCK = %d , pRFCalibrateInfo->Remnant_CCKSwingIdx = %d \n", PwrTrackingLimit_CCK, pRFCalibrateInfo->Remnant_CCKSwingIdx)); + ODM_Write1Byte(pDM_Odm, 0xa22, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][0]); + ODM_Write1Byte(pDM_Odm, 0xa23, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][1]); + ODM_Write1Byte(pDM_Odm, 0xa24, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][2]); + ODM_Write1Byte(pDM_Odm, 0xa25, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][3]); + ODM_Write1Byte(pDM_Odm, 0xa26, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][4]); + ODM_Write1Byte(pDM_Odm, 0xa27, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][5]); + ODM_Write1Byte(pDM_Odm, 0xa28, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][6]); + ODM_Write1Byte(pDM_Odm, 0xa29, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][7]); + ODM_Write1Byte(pDM_Odm, 0xa9a, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][8]); + ODM_Write1Byte(pDM_Odm, 0xa9b, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][9]); + ODM_Write1Byte(pDM_Odm, 0xa9c, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][10]); + ODM_Write1Byte(pDM_Odm, 0xa9d, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][11]); + ODM_Write1Byte(pDM_Odm, 0xaa0, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][12]); + ODM_Write1Byte(pDM_Odm, 0xaa1, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][13]); + ODM_Write1Byte(pDM_Odm, 0xaa2, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][14]); + ODM_Write1Byte(pDM_Odm, 0xaa3, CCKSwingTable_Ch1_Ch14_88F[PwrTrackingLimit_CCK][15]); + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE; + + } + else if(Final_CCK_Swing_Index < 0) // Lowest CCK Index = 0 + { + pRFCalibrateInfo->Remnant_CCKSwingIdx = Final_CCK_Swing_Index; + + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Path_A CCK Under Limit , PwrTrackingLimit_CCK = %d , pRFCalibrateInfo->Remnant_CCKSwingIdx = %d \n", 0, pRFCalibrateInfo->Remnant_CCKSwingIdx)); + ODM_Write1Byte(pDM_Odm, 0xa22, CCKSwingTable_Ch1_Ch14_88F[0][0]); + ODM_Write1Byte(pDM_Odm, 0xa23, CCKSwingTable_Ch1_Ch14_88F[0][1]); + ODM_Write1Byte(pDM_Odm, 0xa24, CCKSwingTable_Ch1_Ch14_88F[0][2]); + ODM_Write1Byte(pDM_Odm, 0xa25, CCKSwingTable_Ch1_Ch14_88F[0][3]); + ODM_Write1Byte(pDM_Odm, 0xa26, CCKSwingTable_Ch1_Ch14_88F[0][4]); + ODM_Write1Byte(pDM_Odm, 0xa27, CCKSwingTable_Ch1_Ch14_88F[0][5]); + ODM_Write1Byte(pDM_Odm, 0xa28, CCKSwingTable_Ch1_Ch14_88F[0][6]); + ODM_Write1Byte(pDM_Odm, 0xa29, CCKSwingTable_Ch1_Ch14_88F[0][7]); + ODM_Write1Byte(pDM_Odm, 0xa9a, CCKSwingTable_Ch1_Ch14_88F[0][8]); + ODM_Write1Byte(pDM_Odm, 0xa9b, CCKSwingTable_Ch1_Ch14_88F[0][9]); + ODM_Write1Byte(pDM_Odm, 0xa9c, CCKSwingTable_Ch1_Ch14_88F[0][10]); + ODM_Write1Byte(pDM_Odm, 0xa9d, CCKSwingTable_Ch1_Ch14_88F[0][11]); + ODM_Write1Byte(pDM_Odm, 0xaa0, CCKSwingTable_Ch1_Ch14_88F[0][12]); + ODM_Write1Byte(pDM_Odm, 0xaa1, CCKSwingTable_Ch1_Ch14_88F[0][13]); + ODM_Write1Byte(pDM_Odm, 0xaa2, CCKSwingTable_Ch1_Ch14_88F[0][14]); + ODM_Write1Byte(pDM_Odm, 0xaa3, CCKSwingTable_Ch1_Ch14_88F[0][15]); + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK = TRUE; + + } + + else + { + ODM_RT_TRACE(pDM_Odm,ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,("******Path_A CCK Compensate with BBSwing , Final_CCK_Swing_Index = %d \n", Final_CCK_Swing_Index)); + ODM_Write1Byte(pDM_Odm, 0xa22, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][0]); + ODM_Write1Byte(pDM_Odm, 0xa23, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][1]); + ODM_Write1Byte(pDM_Odm, 0xa24, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][2]); + ODM_Write1Byte(pDM_Odm, 0xa25, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][3]); + ODM_Write1Byte(pDM_Odm, 0xa26, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][4]); + ODM_Write1Byte(pDM_Odm, 0xa27, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][5]); + ODM_Write1Byte(pDM_Odm, 0xa28, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][6]); + ODM_Write1Byte(pDM_Odm, 0xa29, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][7]); + ODM_Write1Byte(pDM_Odm, 0xa9a, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][8]); + ODM_Write1Byte(pDM_Odm, 0xa9b, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][9]); + ODM_Write1Byte(pDM_Odm, 0xa9c, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][10]); + ODM_Write1Byte(pDM_Odm, 0xa9d, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][11]); + ODM_Write1Byte(pDM_Odm, 0xaa0, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][12]); + ODM_Write1Byte(pDM_Odm, 0xaa1, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][13]); + ODM_Write1Byte(pDM_Odm, 0xaa2, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][14]); + ODM_Write1Byte(pDM_Odm, 0xaa3, CCKSwingTable_Ch1_Ch14_88F[Final_CCK_Swing_Index][15]); + + pRFCalibrateInfo->Modify_TxAGC_Flag_PathA_CCK=FALSE; + pRFCalibrateInfo->Remnant_CCKSwingIdx = 0; + + } + #if (MP_DRIVER == 1) && (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + if ( (pDM_Odm->mp_mode) == 1) { + pwr = PHY_QueryBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1); + pwr +=pRFCalibrateInfo->Remnant_CCKSwingIdx-pRFCalibrateInfo->Modify_TxAGC_Value_CCK; + + if (pwr>0x3F) pwr=0x3F; //add by Mingzhi.Guo 2015-04-10 + else if(pwr<0) pwr=0; + + PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, pwr); //CCK 1M + TxAGC = (pwr<<16)|(pwr<<8)|(pwr); + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, TxAGC); //CCK 2~11M + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("ODM_TxPwrTrackSetPwr8188F: CCK Tx-rf(A) Power = 0x%x\n", TxAGC)); + } + else + #endif + { + //Set TxAGC Page C{}; + PHY_SetTxPowerIndexByRateSection(Adapter, ODM_RF_PATH_A, pHalData->CurrentChannel, CCK ); + } + pRFCalibrateInfo->Modify_TxAGC_Value_CCK = pRFCalibrateInfo->Remnant_CCKSwingIdx; + + } + } + else + return; +} // odm_TxPwrTrackSetPwr8188F + + +VOID +GetDeltaSwingTable_8188F( + IN PVOID pDM_VOID, + OUT pu1Byte *TemperatureUP_A, + OUT pu1Byte *TemperatureDOWN_A, + OUT pu1Byte *TemperatureUP_B, + OUT pu1Byte *TemperatureDOWN_B +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + u1Byte TxRate = 0xFF; + u1Byte channel = pHalData->CurrentChannel; + + if (pDM_Odm->mp_mode == TRUE) { + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE)) + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + #if (MP_DRIVER == 1) + PMPT_CONTEXT pMptCtx = &(Adapter->MptCtx); + + TxRate = MptToMgntRate(pMptCtx->MptRateIndex); + #endif + #elif (DM_ODM_SUPPORT_TYPE & ODM_CE) + PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.MptCtx); + + TxRate = MptToMgntRate(pMptCtx->MptRateIndex); + #endif + #endif + } else { + u2Byte rate = *(pDM_Odm->pForcedDataRate); + + if (!rate) { /*auto rate*/ + if (rate != 0xFF) { + #if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + TxRate = Adapter->HalFunc.GetHwRateFromMRateHandler(pDM_Odm->TxRate); + #elif (DM_ODM_SUPPORT_TYPE & ODM_CE) + TxRate = HwRateToMRate(pDM_Odm->TxRate); + #endif + } + } else { /*force rate*/ + TxRate = (u1Byte)rate; + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD, ("Power Tracking TxRate=0x%X\n", TxRate)); + + + RT_TRACE(COMP_CMD, DBG_LOUD, ("GetDeltaSwingTable_8188F ====> channel is %d\n", channel)); + + if ( 1 <= channel && channel <= 14) { + if (IS_CCK_RATE(TxRate)) { + *TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_P; + *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKA_N; + *TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_P; + *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GCCKB_N; + } else { + *TemperatureUP_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_P; + *TemperatureDOWN_A = pRFCalibrateInfo->DeltaSwingTableIdx_2GA_N; + *TemperatureUP_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_P; + *TemperatureDOWN_B = pRFCalibrateInfo->DeltaSwingTableIdx_2GB_N; + } + } else { + *TemperatureUP_A = (pu1Byte)DeltaSwingTableIdx_2GA_P_8188E; + *TemperatureDOWN_A = (pu1Byte)DeltaSwingTableIdx_2GA_N_8188E; + *TemperatureUP_B = (pu1Byte)DeltaSwingTableIdx_2GA_P_8188E; + *TemperatureDOWN_B = (pu1Byte)DeltaSwingTableIdx_2GA_N_8188E; + } + + return; +} + + +void ConfigureTxpowerTrack_8188F( + PTXPWRTRACK_CFG pConfig +) +{ + RT_TRACE(COMP_CMD, DBG_LOUD, ("ConfigureTxpowerTrack_8188F ====> \n")); + pConfig->SwingTableSize_CCK = CCK_TABLE_SIZE_88F; + pConfig->SwingTableSize_OFDM = OFDM_TABLE_SIZE; + pConfig->Threshold_IQK = IQK_THRESHOLD; + pConfig->AverageThermalNum = AVG_THERMAL_NUM_8188F; + pConfig->RfPathCount = MAX_PATH_NUM_8188F; + pConfig->ThermalRegAddr = RF_T_METER_8188F; + + pConfig->ODM_TxPwrTrackSetPwr = ODM_TxPwrTrackSetPwr_8188F; + pConfig->DoIQK = DoIQK_8188F; + pConfig->PHY_LCCalibrate = PHY_LCCalibrate_8188F; + pConfig->GetDeltaSwingTable = GetDeltaSwingTable_8188F; +} + +//1 7. IQK +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathA_IQK_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN configPathB +) +{ + u4Byte regEAC, regE94, regE9C/*, regEA4*/; + u1Byte result = 0x00; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A IQK!\n")); + + // enable path A PA in TXIQK mode + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x20000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0x07ff7); //0x07f77 + //PA,PAD gain adjust + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x56, bRFRegOffsetMask, 0x5102a); //0x5111e0 + + + //enter IQK mode + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + + //1 Tx IQK + //path-A IQK setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A IQK setting!\n")); + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x821403ff); //0x821403e0 + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); + + //LO calibration setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); + + //One shot, path A LOK & IQK +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_8188F)); +//PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + //reload RF 0xdf + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); + + //save LOK result + pDM_Odm->RFCalibrateInfo.LOK_Result = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x8, bRFRegOffsetMask); + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regE94 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord); + regE9C = ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x, 0xe9c = 0x%x\n", regE94, regE9C)); + //monitor image power before & after IQK + 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))); + + if (!(regEAC & BIT28) && + (((regE94 & 0x03FF0000) >> 16) != 0x142) && + (((regE9C & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + + return result; + + +} + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathA_RxIQK8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN configPathB +) +{ + u4Byte regEAC, regE94, regE9C, regEA4, u4tmp; + u1Byte result = 0x00; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK!\n")); + + //1 Get TXIMR setting + //modify RXIQK mode table +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table!\n")); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf1173); //0xf117b + + //PA,PAD gain adjust + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x56, bRFRegOffsetMask, 0x5102a); //0x510f0 + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + //IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + + //path-A IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82160fff); //0x821603e0 + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); + + //LO calibration setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); + + //One shot, path A LOK & IQK +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_8188F)); +//PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + + //reload RF 0xdf + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); + + + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regE94 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord); + regE9C = ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x, 0xe9c = 0x%x\n", regE94, regE9C)); + //monitor image power before & after IQK + 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))); + + if (!(regEAC & BIT28) && + (((regE94 & 0x03FF0000) >> 16) != 0x142) && + (((regE9C & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else //if Tx not OK, ignore Rx + return result; + + u4tmp = 0x80007C00 | (regE94 & 0x3FF0000) | ((regE9C & 0x3FF0000) >> 16); + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, u4tmp); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe40 = 0x%x u4tmp = 0x%x\n", ODM_GetBBReg(pDM_Odm, rTx_IQK, bMaskDWord), u4tmp)); + + + //1 RX IQK + //modify RXIQK mode table +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table 2!\n")); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); // 0xEF[19] = 0x1 + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000); // 0x30[19:0] = 0x18000 + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); // 0x31[19:0] = 0x0000f + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ff2); // 0x32[19:0] = 0xf7ffa + + //PA,PAD gain adjust + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000); //0x51000 + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + //IQK setting + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + + //path-A IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x30008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82160000); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x281613ff); //0x281603e0 + + + //LO calibration setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); + + //One shot, path A LOK & IQK +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path A LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_8188F)); +//PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + //reload RF 0xdf + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180); + + //reload LOK value + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x8, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.LOK_Result); + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regEA4 = ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_A_2, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea4 = 0x%x, 0xeac = 0x%x\n", regEA4, regEAC)); + //monitor image power before & after IQK + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n", + ODM_GetBBReg(pDM_Odm, 0xea0, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xea8, bMaskDWord))); + + + if (!(regEAC & BIT27) && //if Tx is OK, check whether Rx is OK + (((regEA4 & 0x03FF0000) >> 16) != 0x132) && + (((regEAC & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK fail!!\n")); + + return result; + + +} + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathB_IQK_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER pAdapter +#endif +) +{ + u4Byte regEAC, regE94, regE9C/*, regEC4, regECC*/; + u1Byte result = 0x00; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B IQK!\n")); + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + //switch to path B + ODM_SetBBReg(pDM_Odm, 0x948, bMaskDWord, 0x00000080); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xb0, bRFRegOffsetMask, 0xefff0); + // in TXIQK mode +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0 ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x20000 ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0003f ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xc7f87 ); +// enable path B PA in TXIQK mode +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xed, bRFRegOffsetMask, 0x00020 ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x43, bRFRegOffsetMask, 0x40fc1 ); + + + //1 Tx IQK + //path-A IQK setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-B IQK setting!\n")); + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x18008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x38008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82140102); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28160000); + + //LO calibration setting +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); + + + //enter IQK mode + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + //One shot, path B LOK & IQK +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path B LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); + + // delay x ms +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path B LOK & IQK.\n", IQK_DELAY_TIME_8188F)); +//PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0x948 = 0x%x\n", ODM_GetBBReg(pDM_Odm, 0x948, bMaskDWord))); + + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regE94 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord); + regE9C = ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe94 = 0x%x, 0xe9c = 0x%x\n", regE94, regE9C)); + //monitor image power before & after IQK + 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))); + + + if (!(regEAC & BIT28) && + (((regE94 & 0x03FF0000) >> 16) != 0x142) && + (((regE9C & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; +#if 0 + if (!(regEAC & BIT30) && + (((regEC4 & 0x03FF0000) >> 16) != 0x132) && + (((regECC & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n")); + +#endif + return result; +} + + + +u1Byte //bit0 = 1 => Tx OK, bit1 = 1 => Rx OK +phy_PathB_RxIQK8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN configPathB +) +{ + u4Byte regEAC, regEB4, regEBC, regECC, regEC4, u4tmp; + u1Byte result = 0x00; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK!\n")); + + //1 Get TXIMR setting + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Get RXIQK TXIMR!\n")); + //modify RXIQK mode table +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table!\n")); +// ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0 ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000 ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f ); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B ); +// ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + //IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x81004800); + + //path-B IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x10008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x30008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_B, bMaskDWord, 0x82130804); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_B, bMaskDWord, 0x68130000); + + //LO calibration setting + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); + + //One shot, path B LOK & IQK + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path B LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000); + + // delay x ms + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_8188F)); + //PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regEB4 = ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_B, bMaskDWord); + regEBC = ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_B, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeb4 = 0x%x, 0xebc = 0x%x\n", regEB4, regEBC)); + //monitor image power before & after IQK + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeb0(before IQK)= 0x%x, 0xeb8(afer IQK) = 0x%x\n", + ODM_GetBBReg(pDM_Odm, 0xeb0, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xeb8, bMaskDWord))); + + + if (!(regEAC & BIT31) && + (((regEB4 & 0x03FF0000) >> 16) != 0x142) && + (((regEBC & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else //if Tx not OK, ignore Rx + return result; + + u4tmp = 0x80007C00 | (regEB4 & 0x3FF0000) | ((regEBC & 0x3FF0000) >> 16); + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, u4tmp); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xe40 = 0x%x u4tmp = 0x%x\n", ODM_GetBBReg(pDM_Odm, rTx_IQK, bMaskDWord), u4tmp)); + + + //1 RX IQK + //modify RXIQK mode table +// ODM_RT_TRACE(pDM_Odm,ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A Rx IQK modify RXIQK mode table 2!\n")); +// ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0 ); + + //<20121009, Kordan> RF Mode = 3 +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); // 0xEF[19] = 0x1 +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x18000 ); // 0x30[19:0] = 0x18000 +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f ); // 0x31[19:0] = 0x0000f +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa ); // 0x32[19:0] = 0xf7ffa +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); // 0xEF[19] = 0x0 +// ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + + //IQK setting + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + + //path-B IQK setting + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x30008c1c); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x10008c1c); + ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_B, bMaskDWord, 0x82130c05); + ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_B, bMaskDWord, 0x68130c05); + + //LO calibration setting + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LO calibration setting!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); + + //One shot, path B LOK & IQK + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("One shot, path B LOK & IQK!\n")); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Cont, bMaskDWord, 0x00000002); + ODM_SetBBReg(pDM_Odm, rIQK_AGC_Cont, bMaskDWord, 0x00000000); + + // delay x ms + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Delay %d ms for One shot, path A LOK & IQK.\n", IQK_DELAY_TIME_8188F)); + //PlatformStallExecution(IQK_DELAY_TIME_8188F*1000); + ODM_delay_ms(IQK_DELAY_TIME_8188F); + + // Check failed + regEAC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord); + regEC4 = ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_B_2, bMaskDWord);; + regECC = ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_B_2, bMaskDWord); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xec4 = 0x%x, 0xecc = 0x%x\n", regEC4, regECC)); + //monitor image power before & after IQK + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xec0(before IQK)= 0x%x, 0xec8(afer IQK) = 0x%x\n", + ODM_GetBBReg(pDM_Odm, 0xec0, bMaskDWord), ODM_GetBBReg(pDM_Odm, 0xec8, bMaskDWord))); + + // PA/PAD controlled by 0x0 + //leave IQK mode +// ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); +// ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0xdf, bRFRegOffsetMask, 0x180 ); + + + +#if 0 + if (!(regEAC & BIT31) && + (((regEB4 & 0x03FF0000) >> 16) != 0x142) && + (((regEBC & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else //if Tx not OK, ignore Rx + return result; +#endif + + if (!(regEAC & BIT30) && //if Tx is OK, check whether Rx is OK + (((regEC4 & 0x03FF0000) >> 16) != 0x132) && + (((regECC & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n")); + + return result; + + +} + + +VOID +_PHY_PathAFillIQKMatrix8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN bIQKOK, + IN s4Byte result[][8], + IN u1Byte final_candidate, + IN BOOLEAN bTxOnly +) +{ + u4Byte Oldval_0, X, TX0_A, reg; + s4Byte Y, TX0_C; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A IQ Calibration %s !\n", (bIQKOK) ? "Success" : "Failed")); + + if (final_candidate == 0xFF) + return; + + else if (bIQKOK) { + Oldval_0 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][0]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX0_A = (X * Oldval_0) >> 8; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("X = 0x%x, TX0_A = 0x%x, Oldval_0 0x%x\n", X, TX0_A, Oldval_0)); + ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); + + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0 >> 7) & 0x1)); + + Y = result[final_candidate][1]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + + //2 Tx IQC + TX0_C = (Y * Oldval_0) >> 8; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Y = 0x%x, TX = 0x%x\n", Y, TX0_C)); + ODM_SetBBReg(pDM_Odm, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY] = rOFDM0_XCTxAFE; + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XCTxAFE, bMaskDWord); + + ODM_SetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY] = rOFDM0_XATxIQImbalance; + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XATxIQImbalance, bMaskDWord); + + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold; + pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord); + + if (bTxOnly) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_PHY_PathAFillIQKMatrix8188F only Tx OK\n")); + + // <20130226, Kordan> Saving RxIQC, otherwise not initialized. + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta; + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, bMaskDWord); + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance; + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XARxIQImbalance, bMaskDWord); + return; + } + + reg = result[final_candidate][2]; +#if (DM_ODM_SUPPORT_TYPE==ODM_AP) + if (RTL_ABS(reg, 0x100) >= 16) + reg = 0x100; +#endif + + //2 Rx IQC + ODM_SetBBReg(pDM_Odm, rOFDM0_XARxIQImbalance, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + ODM_SetBBReg(pDM_Odm, rOFDM0_XARxIQImbalance, 0xFC00, reg); + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY] = rOFDM0_XARxIQImbalance; + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XARxIQImbalance, bMaskDWord); + + reg = (result[final_candidate][3] >> 6) & 0xF; + ODM_SetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, 0xF0000000, reg); + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY] = rOFDM0_RxIQExtAnta; + pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_RxIQExtAnta, bMaskDWord); + + } +} + +VOID +_PHY_PathBFillIQKMatrix8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN bIQKOK, + IN s4Byte result[][8], + IN u1Byte final_candidate, + IN BOOLEAN bTxOnly //do Tx only +) +{ + u4Byte Oldval_1, X, TX1_A, reg; + s4Byte Y, TX1_C; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B IQ Calibration %s !\n", (bIQKOK) ? "Success" : "Failed")); + + if (final_candidate == 0xFF) + return; + + else if (bIQKOK) { + Oldval_1 = (ODM_GetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; + + X = result[final_candidate][4]; + if ((X & 0x00000200) != 0) + X = X | 0xFFFFFC00; + TX1_A = (X * Oldval_1) >> 8; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("X = 0x%x, TX1_A = 0x%x\n", X, TX1_A)); + + ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); + + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1 >> 7) & 0x1)); + + Y = result[final_candidate][5]; + if ((Y & 0x00000200) != 0) + Y = Y | 0xFFFFFC00; + + TX1_C = (Y * Oldval_1) >> 8; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Y = 0x%x, TX1_C = 0x%x\n", Y, TX1_C)); + + //2 Tx IQC + ODM_SetBBReg(pDM_Odm, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C & 0x3C0) >> 6)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][KEY] = rOFDM0_XDTxAFE; + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC9C][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XDTxAFE, bMaskDWord); + + ODM_SetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C & 0x3F)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC88][KEY] = rOFDM0_XBTxIQImbalance; + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC88][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XBTxIQImbalance, bMaskDWord); + + ODM_SetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1 >> 7) & 0x1)); + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY] = rOFDM0_ECCAThreshold; + pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_ECCAThreshold, bMaskDWord); + + if (bTxOnly) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("_PHY_PathBFillIQKMatrix8188F only Tx OK\n")); + + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC1C][KEY] = rOFDM0_XBRxIQImbalance; + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC1C][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XBRxIQImbalance, bMaskDWord); + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC78][KEY] = rOFDM0_AGCRSSITable; + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC78][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_AGCRSSITable, bMaskDWord); + return; + } + + //2 Rx IQC + reg = result[final_candidate][6]; + ODM_SetBBReg(pDM_Odm, rOFDM0_XBRxIQImbalance, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + ODM_SetBBReg(pDM_Odm, rOFDM0_XBRxIQImbalance, 0xFC00, reg); + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC1C][KEY] = rOFDM0_XBRxIQImbalance; + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC1C][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_XBRxIQImbalance, bMaskDWord); + + reg = (result[final_candidate][7] >> 6) & 0xF; + ODM_SetBBReg(pDM_Odm, rOFDM0_AGCRSSITable, 0x0000F000, reg); + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC78][KEY] = rOFDM0_AGCRSSITable; + pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC78][VAL] = ODM_GetBBReg(pDM_Odm, rOFDM0_AGCRSSITable, bMaskDWord); + } +} + +// +// 2011/07/26 MH Add an API for testing IQK fail case. +// +// MP Already declare in odm.c +#if !(DM_ODM_SUPPORT_TYPE & ODM_WIN) +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,COMP_INIT, 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,COMP_INIT, DBG_LOUD, ("ODM_CheckPowerStatus Return FALSE, due to %d/%d/%d\n", + Adapter->bDriverStopped, Adapter->bDriverIsGoingToPnpSetPowerSleep, rtState)); + return FALSE; + } + */ + return TRUE; +} +#endif + +VOID +_PHY_SaveADDARegisters8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN pu4Byte ADDABackup, + IN u4Byte RegisterNum +) +{ + u4Byte i; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif + + if (ODM_CheckPowerStatus(pAdapter) == FALSE) + return; +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save ADDA parameters.\n")); + for (i = 0; i < RegisterNum; i++) + ADDABackup[i] = ODM_GetBBReg(pDM_Odm, ADDAReg[i], bMaskDWord); +} + + +VOID +_PHY_SaveMACRegisters8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte MACReg, + IN pu4Byte MACBackup +) +{ + u4Byte i; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save MAC parameters.\n")); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + MACBackup[i] = ODM_Read1Byte(pDM_Odm, MACReg[i]); + MACBackup[i] = ODM_Read4Byte(pDM_Odm, MACReg[i]); + +} + + +VOID +_PHY_ReloadADDARegisters8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN pu4Byte ADDABackup, + IN u4Byte RegiesterNum +) +{ + u4Byte i; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload ADDA power saving parameters !\n")); + for (i = 0; i < RegiesterNum; i++) + ODM_SetBBReg(pDM_Odm, ADDAReg[i], bMaskDWord, ADDABackup[i]); +} + +VOID +_PHY_ReloadMACRegisters8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte MACReg, + IN pu4Byte MACBackup +) +{ + u4Byte i; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload MAC parameters !\n")); + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)MACBackup[i]); + ODM_Write4Byte(pDM_Odm, MACReg[i], MACBackup[i]); +} + + +VOID +_PHY_PathADDAOn8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN BOOLEAN isPathAOn, + IN BOOLEAN is2T +) +{ + u4Byte pathOn; + u4Byte i; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("ADDA ON.\n")); + + pathOn = isPathAOn ? 0x03c00014 : 0x03c00014; + if (FALSE == is2T) { + pathOn = 0x03c00014; + ODM_SetBBReg(pDM_Odm, ADDAReg[0], bMaskDWord, 0x03c00014); + } else + ODM_SetBBReg(pDM_Odm, ADDAReg[0], bMaskDWord, pathOn); + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + ODM_SetBBReg(pDM_Odm, ADDAReg[i], bMaskDWord, pathOn); + +} + +VOID +_PHY_MACSettingCalibration8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte MACReg, + IN pu4Byte MACBackup +) +{ + u4Byte i = 0; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("MAC settings for Calibration.\n")); + + ODM_Write1Byte(pDM_Odm, MACReg[i], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)(MACBackup[i] & (~BIT3))); + ODM_Write1Byte(pDM_Odm, MACReg[i], (u1Byte)(MACBackup[i] & (~BIT5))); + +} + +VOID +_PHY_PathAStandBy8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER pAdapter +#endif +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path-A standby mode!\n")); + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); +//Allen + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMaskDWord, 0x10000); + //ODM_SetBBReg(pDM_Odm, 0x840, bMaskDWord, 0x00010000); +// + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); +} + +VOID +_PHY_PIModeSwitch8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN PIMode +) +{ + u4Byte mode; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("BB Switch to %s mode!\n", (PIMode ? "PI" : "SI"))); + + mode = PIMode ? 0x01000100 : 0x01000000; + ODM_SetBBReg(pDM_Odm, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode); + ODM_SetBBReg(pDM_Odm, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode); +} + +BOOLEAN +phy_SimularityCompare_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN s4Byte result[][8], + IN u1Byte c1, + IN u1Byte c2 +) +{ + u4Byte i, j, diff, SimularityBitMap, bound = 0; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +#if DBG + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif +#endif + u1Byte final_candidate[2] = { 0xFF, 0xFF }; //for path A and path B + BOOLEAN bResult = TRUE; +//#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +// BOOLEAN is2T = IS_92C_SERIAL( pHalData->VersionID); +//#else + BOOLEAN is2T = TRUE; +//#endif + + s4Byte tmp1 = 0, tmp2 = 0; + + if (is2T) + bound = 8; + else + bound = 4; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("===> IQK:phy_SimularityCompare_8192E c1 %d c2 %d!!!\n", c1, c2)); + + + SimularityBitMap = 0; + + for (i = 0; i < bound; i++) { + + if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { + if ((result[c1][i] & 0x00000200) != 0) + tmp1 = result[c1][i] | 0xFFFFFC00; + else + tmp1 = result[c1][i]; + + if ((result[c2][i] & 0x00000200) != 0) + tmp2 = result[c2][i] | 0xFFFFFC00; + else + tmp2 = result[c2][i]; + } else { + tmp1 = result[c1][i]; + tmp2 = result[c2][i]; + } + + diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); + + if (diff > MAX_TOLERANCE) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:differnece overflow %d index %d compare1 0x%x compare2 0x%x!!!\n", diff, i, result[c1][i], result[c2][i])); + + if ((i == 2 || i == 6) && !SimularityBitMap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + SimularityBitMap = SimularityBitMap | (1 << i); + } else + SimularityBitMap = SimularityBitMap | (1 << i); + } + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:phy_SimularityCompare_8192E SimularityBitMap %x !!!\n", SimularityBitMap)); + + if (SimularityBitMap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) result[3][j] = result[final_candidate[i]][j]; + bResult = FALSE; + } + } + return bResult; + } else { + + if (!(SimularityBitMap & 0x03)) { //path A TX OK + for (i = 0; i < 2; i++) result[3][i] = result[c1][i]; + } + + if (!(SimularityBitMap & 0x0c)) { //path A RX OK + for (i = 2; i < 4; i++) result[3][i] = result[c1][i]; + } + + if (!(SimularityBitMap & 0x30)) { //path B TX OK + for (i = 4; i < 6; i++) result[3][i] = result[c1][i]; + + } + + if (!(SimularityBitMap & 0xc0)) { //path B RX OK + for (i = 6; i < 8; i++) result[3][i] = result[c1][i]; + } + return FALSE; + } +} + + + +VOID +phy_IQCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN s4Byte result[][8], + IN u1Byte t, + IN BOOLEAN is2T +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + u4Byte i; + u1Byte PathAOK, PathBOK; + u1Byte tmp0xc50 = (u1Byte)ODM_GetBBReg(pDM_Odm, 0xC50, bMaskByte0); + u1Byte tmp0xc58 = (u1Byte)ODM_GetBBReg(pDM_Odm, 0xC58, bMaskByte0); + u4Byte ADDA_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 + }; + u4Byte IQK_MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG + }; + + //since 92C & 92D have the different define in IQK_BB_REG + u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, + rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, + rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD + }; + + u4Byte Path_SEL_BB, Path_SEL_RF; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) + u4Byte retryCount = 2; +#else +#if MP_DRIVER + const u4Byte retryCount = 9; +#else + const u4Byte retryCount = 2; +#endif +#endif + + // Note: IQ calibration must be performed after loading + // PHY_REG.txt , and radio_a, radio_b.txt + + //u4Byte bbvalue; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP)) +#ifdef MP_TEST + if (pDM_Odm->priv->pshare->rf_ft_var.mp_specific) + retryCount = 9; +#endif +#endif + + + if (t == 0) { +// bbvalue = ODM_GetBBReg(pDM_Odm, rFPGA0_RFMOD, bMaskDWord); +// RT_DISP(FINIT, INIT_IQK, ("phy_IQCalibrate_8188F()==>0x%08x\n",bbvalue)); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2T ? "2T2R" : "1T1R"), t)); + + // Save ADDA parameters, turn Path A ADDA on +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_SaveADDARegisters8188F(pAdapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); + _PHY_SaveMACRegisters8188F(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); + _PHY_SaveADDARegisters8188F(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); +#else + _PHY_SaveADDARegisters8188F(pDM_Odm, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); + _PHY_SaveMACRegisters8188F(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); + _PHY_SaveADDARegisters8188F(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); +#endif + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQ Calibration for %s for %d times\n", (is2T ? "2T2R" : "1T1R"), t)); + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + _PHY_PathADDAOn8188F(pAdapter, ADDA_REG, TRUE, is2T); +#else + _PHY_PathADDAOn8188F(pDM_Odm, ADDA_REG, TRUE, is2T); +#endif + + + if (t == 0) + pDM_Odm->RFCalibrateInfo.bRfPiEnable = (u1Byte)ODM_GetBBReg(pDM_Odm, rFPGA0_XA_HSSIParameter1, BIT(8)); + + if (!pDM_Odm->RFCalibrateInfo.bRfPiEnable) { + // Switch BB to PI mode to do IQ Calibration. +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_PIModeSwitch8188F(pAdapter, TRUE); +#else + _PHY_PIModeSwitch8188F(pDM_Odm, TRUE); +#endif + } + + //save RF path + Path_SEL_BB = ODM_GetBBReg(pDM_Odm, 0x948, bMaskDWord); + Path_SEL_RF = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xb0, 0xfffff); + + + //BB setting + ODM_SetBBReg(pDM_Odm, rFPGA0_RFMOD, BIT24, 0x00); + ODM_SetBBReg(pDM_Odm, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); + ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); + ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x25204000); + + //external switch control +// ODM_SetBBReg(pDM_Odm, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); +// ODM_SetBBReg(pDM_Odm, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); +// ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); +// ODM_SetBBReg(pDM_Odm, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); + + + if (is2T) { + //Allen + // ODM_SetBBReg(pDM_Odm, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); + // ODM_SetBBReg(pDM_Odm, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMaskDWord, 0x10000); + } + + //MAC settings +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_MACSettingCalibration8188F(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); +#else + _PHY_MACSettingCalibration8188F(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); +#endif + + + //Page B init + //AP or IQK +// ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); + + if (is2T) { +// ODM_SetBBReg(pDM_Odm, rConfig_AntB, bMaskDWord, 0x0f600000); + } + + // IQ calibration setting + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK setting!\n")); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x808000); + ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); + + for (i = 0; i < retryCount; i++) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PathAOK = phy_PathA_IQK_8188F(pAdapter, is2T); +#else + PathAOK = phy_PathA_IQK_8188F(pDM_Odm, is2T); +#endif +// if(PathAOK == 0x03){ + if (PathAOK == 0x01) { //Path A Tx IQK Success + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A] = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x8, bRFRegOffsetMask); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Tx IQK Success!!\n")); + result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + break; + } +#if 0 + else if (i == (retryCount - 1) && PathAOK == 0x01) { //Tx IQK OK + RT_DISP(FINIT, INIT_IQK, ("Path A IQK Only Tx Success!!\n")); + + result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + } +#endif + } + +//bypass RXQIK +#if 1 + + for (i = 0; i < retryCount; i++) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PathAOK = phy_PathA_RxIQK8188F(pAdapter, is2T); +#else + PathAOK = phy_PathA_RxIQK8188F(pDM_Odm, is2T); +#endif + if (PathAOK == 0x03) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK Success!!\n")); +// result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; +// result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][2] = (ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; + result[t][3] = (ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; + break; + } else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A Rx IQK Fail!!\n")); + } +#endif + + + if (0x00 == PathAOK) + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path A IQK failed!!\n")); + + if (is2T) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_PathAStandBy8188F(pAdapter); + + // Turn Path B ADDA on + _PHY_PathADDAOn8188F(pAdapter, ADDA_REG, FALSE, is2T); +#else + _PHY_PathAStandBy8188F(pDM_Odm); + + // Turn Path B ADDA on + _PHY_PathADDAOn8188F(pDM_Odm, ADDA_REG, FALSE, is2T); +#endif +//Allen + for (i = 0; i < retryCount; i++) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PathBOK = phy_PathB_IQK_8188F(pAdapter); +#else + PathBOK = phy_PathB_IQK_8188F(pDM_Odm); +#endif +// if(PathBOK == 0x03){ + if (PathBOK == 0x01) { //Path B Tx IQK Success + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_B] = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x8, bRFRegOffsetMask); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Tx IQK Success!!\n")); + result[t][4] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + result[t][5] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; + break; + } +#if 0 + else if (i == (retryCount - 1) && PathAOK == 0x01) { //Tx IQK OK + RT_DISP(FINIT, INIT_IQK, ("Path B IQK Only Tx Success!!\n")); + + result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; + result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_B, bMaskDWord) & 0x3FF0000) >> 16; + } +#endif + } + +//bypass RXQIK +#if 0 + + for (i = 0; i < retryCount; i++) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PathBOK = phy_PathB_RxIQK8188F(pAdapter, is2T); +#else + PathBOK = phy_PathB_RxIQK8188F(pDM_Odm, is2T); +#endif + if (PathBOK == 0x03) { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK Success!!\n")); +// result[t][0] = (ODM_GetBBReg(pDM_Odm, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; +// result[t][1] = (ODM_GetBBReg(pDM_Odm, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; + result[t][6] = (ODM_GetBBReg(pDM_Odm, rRx_Power_Before_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; + result[t][7] = (ODM_GetBBReg(pDM_Odm, rRx_Power_After_IQK_B_2, bMaskDWord) & 0x3FF0000) >> 16; + break; + } else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B Rx IQK Fail!!\n")); + } + +#endif + +////////Allen end ///////// + if (0x00 == PathBOK) + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Path B IQK failed!!\n")); + } + + //Back to BB mode, load original value + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Back to BB mode, load original value!\n")); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0); + + if (t != 0) { + if (!pDM_Odm->RFCalibrateInfo.bRfPiEnable) { + // Switch back BB to SI mode after finish IQ Calibration. +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_PIModeSwitch8188F(pAdapter, FALSE); +#else + _PHY_PIModeSwitch8188F(pDM_Odm, FALSE); +#endif + } +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + // Reload ADDA power saving parameters + _PHY_ReloadADDARegisters8188F(pAdapter, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); + + // Reload MAC parameters + _PHY_ReloadMACRegisters8188F(pAdapter, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); + + _PHY_ReloadADDARegisters8188F(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); +#else + // Reload ADDA power saving parameters + _PHY_ReloadADDARegisters8188F(pDM_Odm, ADDA_REG, pDM_Odm->RFCalibrateInfo.ADDA_backup, IQK_ADDA_REG_NUM); + + // Reload MAC parameters + _PHY_ReloadMACRegisters8188F(pDM_Odm, IQK_MAC_REG, pDM_Odm->RFCalibrateInfo.IQK_MAC_backup); + + _PHY_ReloadADDARegisters8188F(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM); +#endif + + + //Reload RF path + ODM_SetBBReg(pDM_Odm, 0x948, bMaskDWord, Path_SEL_BB); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); + + //Allen initial gain 0xc50 + // Restore RX initial gain + ODM_SetBBReg(pDM_Odm, 0xc50, bMaskByte0, 0x50); + ODM_SetBBReg(pDM_Odm, 0xc50, bMaskByte0, tmp0xc50); + if (is2T) { + ODM_SetBBReg(pDM_Odm, 0xc58, bMaskByte0, 0x50); + ODM_SetBBReg(pDM_Odm, 0xc58, bMaskByte0, tmp0xc58); + } + + //load 0xe30 IQC default value + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_IQCalibrate_8188F() <==\n")); + +} + + +VOID +phy_LCCalibrate_8188F( + IN PDM_ODM_T pDM_Odm, + IN BOOLEAN is2T +) +{ + u1Byte tmpReg; + u4Byte RF_Amode = 0, RF_Bmode = 0, LC_Cal; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PADAPTER pAdapter = pDM_Odm->Adapter; +#endif + + //Check continuous TX and Packet TX + tmpReg = ODM_Read1Byte(pDM_Odm, 0xd03); + + if ((tmpReg & 0x70) != 0) //Deal with contisuous TX case + ODM_Write1Byte(pDM_Odm, 0xd03, tmpReg & 0x8F); //disable all continuous TX + else // Deal with Packet TX case + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0xFF); // block all queues + + if ((tmpReg & 0x70) != 0) { + //1. Read original RF mode + //Path-A +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + RF_Amode = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_AC, bMask12Bits); + + //Path-B + if (is2T) + RF_Bmode = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_B, RF_AC, bMask12Bits); +#else + RF_Amode = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits); + + //Path-B + if (is2T) + RF_Bmode = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits); +#endif + + //2. Set RF mode = standby mode + //Path-A + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000); + + //Path-B + if (is2T) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode & 0x8FFFF) | 0x10000); + } + + //3. Read RF reg18 +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + LC_Cal = PHY_QueryRFReg(pAdapter, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits); +#else + LC_Cal = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits); +#endif + + //4. Set LC calibration begin bit15 + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBF0); // LDO ON + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000); + + ODM_delay_ms(100); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFF0); // LDO OFF + + //Restore original situation + if ((tmpReg & 0x70) != 0) { //Deal with contisuous TX case + //Path-A + ODM_Write1Byte(pDM_Odm, 0xd03, tmpReg); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); + + //Path-B + if (is2T) + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); + } else // Deal with Packet TX case + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE, 0x00); +} + +//Analog Pre-distortion calibration +#define APK_BB_REG_NUM 8 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +VOID +phy_APCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PADAPTER pAdapter, +#else + IN PDM_ODM_T pDM_Odm, + IN PADAPTER pAdapter, +#endif + IN s1Byte delta, + IN BOOLEAN is2T +) +{ +#if 0 +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) && (DBG != 0) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + +#if MP_DRIVER == 1 +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + u4Byte regD[PATH_NUM]; +#endif + u4Byte tmpReg, index, offset, apkbound; + u1Byte path, i; + u1Byte pathbound = PATH_NUM; + u4Byte BB_backup[APK_BB_REG_NUM]; + u4Byte BB_REG[APK_BB_REG_NUM] = { + rFPGA1_TxBlock, rOFDM0_TRxPathEnable, + rFPGA0_RFMOD, rOFDM0_TRMuxPar, + rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW, + rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE + }; + u4Byte BB_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 + }; + u4Byte BB_normal_AP_MODE[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 + }; + + u4Byte AFE_backup[IQK_ADDA_REG_NUM]; + u4Byte AFE_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 + }; + + u4Byte MAC_backup[IQK_MAC_REG_NUM]; + u4Byte MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG + }; + + u4Byte APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u4Byte APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, //path settings equal to path b settings + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u4Byte APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u4Byte APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, //path settings equal to path b settings + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; + + u4Byte AFE_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4 + }; //path A on path B off / path A off path B on + + u4Byte APK_offset[PATH_NUM] = { + rConfig_AntA, rConfig_AntB + }; + + u4Byte APK_normal_offset[PATH_NUM] = { + rConfig_Pmpd_AntA, rConfig_Pmpd_AntB + }; + + u4Byte APK_value[PATH_NUM] = { + 0x92fc0000, 0x12fc0000 + }; + + u4Byte APK_normal_value[PATH_NUM] = { + 0x92680000, 0x12680000 + }; + + s1Byte APK_delta_mapping[APK_BB_REG_NUM][13] = { + { -4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + { -4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + { -6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + { -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + { -11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + u4Byte APK_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + u4Byte APK_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + u4Byte APK_result[PATH_NUM][APK_BB_REG_NUM]; //val_1_1a, val_1_2a, val_2a, val_3a, val_4a +// u4Byte AP_curve[PATH_NUM][APK_CURVE_REG_NUM]; + + s4Byte BB_offset, delta_V, delta_offset; + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); +#else + PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx); +#endif + pMptCtx->APK_bound[0] = 45; + pMptCtx->APK_bound[1] = 52; + +#endif + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>phy_APCalibrate_8188F() delta %d\n", delta)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("AP Calibration for %s\n", (is2T ? "2T2R" : "1T1R"))); +#if MP_DRIVER == 1 + if (!is2T) + pathbound = 1; +#endif + //2 FOR NORMAL CHIP SETTINGS + +// Temporarily do not allow normal driver to do the following settings because these offset +// and value will cause RF internal PA to be unpredictably disabled by HW, such that RF Tx signal +// will disappear after disable/enable card many times on 88CU. RF SD and DD have not find the +// root cause, so we remove these actions temporarily. Added by tynli and SD3 Allen. 2010.05.31. +#if MP_DRIVER != 1 + return; +//#endif +#else + //settings adjust for normal chip + for (index = 0; index < PATH_NUM; index ++) { + APK_offset[index] = APK_normal_offset[index]; + APK_value[index] = APK_normal_value[index]; + AFE_on_off[index] = 0x6fdb25a4; + } + + for (index = 0; index < APK_BB_REG_NUM; index ++) { + for (path = 0; path < pathbound; path++) { + APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index]; + APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index]; + } + BB_AP_MODE[index] = BB_normal_AP_MODE[index]; + } + + apkbound = 6; + + //save BB default value + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) //skip + continue; + BB_backup[index] = ODM_GetBBReg(pDM_Odm, BB_REG[index], bMaskDWord); + } + + //save MAC default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_SaveMACRegisters8188F(pAdapter, MAC_REG, MAC_backup); + + //save AFE default value + _PHY_SaveADDARegisters8188F(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#else + _PHY_SaveMACRegisters8188F(pDM_Odm, MAC_REG, MAC_backup); + + //save AFE default value + _PHY_SaveADDARegisters8188F(pDM_Odm, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#endif + + for (path = 0; path < pathbound; path++) { + + + if (path == ODM_RF_PATH_A) { + //path A APK + //load APK setting + //path-A + offset = rPdp_AntA; + for (index = 0; index < 11; index ++) { + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_1[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); + + offset = rConfig_AntA; + for (; index < 13; index ++) { + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_1[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + + //path A + offset = rPdp_AntA; + for (index = 0; index < 16; index++) { + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_2[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + } else if (path == ODM_RF_PATH_B) { + //path B APK + //load APK setting + //path-B + offset = rPdp_AntB; + for (index = 0; index < 10; index ++) { + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_1[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000); +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + PHY_SetBBReg(pAdapter, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); +#else + PHY_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000); +#endif + + offset = rConfig_AntA; + index = 11; + for (; index < 13; index ++) { //offset 0xb68, 0xb6c + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_1[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + + //page-B1 + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + + //path B + offset = 0xb60; + for (index = 0; index < 16; index++) { + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, APK_normal_setting_value_2[index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", offset, ODM_GetBBReg(pDM_Odm, offset, bMaskDWord))); + + offset += 0x04; + } + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0); + } + + //save RF default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + regD[path] = PHY_QueryRFReg(pAdapter, path, RF_TXBIAS_A, bMaskDWord); +#else + regD[path] = ODM_GetRFReg(pDM_Odm, path, RF_TXBIAS_A, bMaskDWord); +#endif + + //Path A AFE all on, path B AFE All off or vise versa + for (index = 0; index < IQK_ADDA_REG_NUM; index++) + ODM_SetBBReg(pDM_Odm, AFE_REG[index], bMaskDWord, AFE_on_off[path]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xe70 %x\n", ODM_GetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord))); + + //BB to AP mode + if (path == 0) { + for (index = 0; index < APK_BB_REG_NUM; index++) { + + if (index == 0) //skip + continue; + else if (index < 5) + ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_AP_MODE[index]); + else if (BB_REG[index] == 0x870) + ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_backup[index] | BIT10 | BIT26); + else + ODM_SetBBReg(pDM_Odm, BB_REG[index], BIT10, 0x0); + } + + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + } else { //path B + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00); + + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x800 %x\n", ODM_GetBBReg(pDM_Odm, 0x800, bMaskDWord))); + + //MAC settings +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_MACSettingCalibration8188F(pAdapter, MAC_REG, MAC_backup); +#else + _PHY_MACSettingCalibration8188F(pDM_Odm, MAC_REG, MAC_backup); +#endif + + if (path == ODM_RF_PATH_A) //Path B to standby mode + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMaskDWord, 0x10000); + else { //Path A to standby mode + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMaskDWord, 0x10000); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE2, bMaskDWord, 0x20103); + } + + delta_offset = ((delta + 14) / 2); + if (delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + //AP calibration + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index != 1) //only DO PA11+PAD01001, AP RF setting + continue; + + tmpReg = APK_RF_init_value[path][index]; +#if 1 + if (!pDM_Odm->RFCalibrateInfo.bAPKThermalMeterIgnore) { + BB_offset = (tmpReg & 0xF0000) >> 16; + + if (!(tmpReg & BIT15)) //sign bit 0 + BB_offset = -BB_offset; + + delta_V = APK_delta_mapping[index][delta_offset]; + + BB_offset += delta_V; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() APK index %d tmpReg 0x%x delta_V %d delta_offset %d\n", index, tmpReg, delta_V, delta_offset)); + + if (BB_offset < 0) { + tmpReg = tmpReg & (~BIT15); + BB_offset = -BB_offset; + } else + tmpReg = tmpReg | BIT15; + tmpReg = (tmpReg & 0xFFF0FFFF) | (BB_offset << 16); + } +#endif + + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, RF_IPA_A, bMaskDWord, 0x8992e); +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xc %x\n", PHY_QueryRFReg(pAdapter, path, RF_IPA_A, bMaskDWord))); + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, RF_AC, bMaskDWord, APK_RF_value_0[path][index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x0 %x\n", PHY_QueryRFReg(pAdapter, path, RF_AC, bMaskDWord))); + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, RF_TXBIAS_A, bMaskDWord, tmpReg); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xd %x\n", PHY_QueryRFReg(pAdapter, path, RF_TXBIAS_A, bMaskDWord))); +#else + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xc %x\n", ODM_GetRFReg(pDM_Odm, path, RF_IPA_A, bMaskDWord))); + ODM_SetRFReg(pDM_Odm, path, RF_AC, bMaskDWord, APK_RF_value_0[path][index]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x0 %x\n", ODM_GetRFReg(pDM_Odm, path, RF_AC, bMaskDWord))); + ODM_SetRFReg(pDM_Odm, path, RF_TXBIAS_A, bMaskDWord, tmpReg); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xd %x\n", ODM_GetRFReg(pDM_Odm, path, RF_TXBIAS_A, bMaskDWord))); +#endif + + // PA11+PAD01111, one shot + i = 0; + do { + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x800000); + { + ODM_SetBBReg(pDM_Odm, APK_offset[path], bMaskDWord, APK_value[0]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(pDM_Odm, APK_offset[path], bMaskDWord))); + ODM_delay_ms(3); + ODM_SetBBReg(pDM_Odm, APK_offset[path], bMaskDWord, APK_value[1]); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(pDM_Odm, APK_offset[path], bMaskDWord))); + + ODM_delay_ms(20); + } + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + + if (path == ODM_RF_PATH_A) + tmpReg = ODM_GetBBReg(pDM_Odm, rAPK, 0x03E00000); + else + tmpReg = ODM_GetBBReg(pDM_Odm, rAPK, 0xF8000000); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188F() offset 0xbd8[25:21] %x\n", tmpReg)); + + + i++; + } while (tmpReg > apkbound && i < 4); + + APK_result[path][index] = tmpReg; + } + } + + //reload MAC default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_ReloadMACRegisters8188F(pAdapter, MAC_REG, MAC_backup); +#else + _PHY_ReloadMACRegisters8188F(pDM_Odm, MAC_REG, MAC_backup); +#endif + + //reload BB default value + for (index = 0; index < APK_BB_REG_NUM; index++) { + + if (index == 0) //skip + continue; + ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_backup[index]); + } + + //reload AFE default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_ReloadADDARegisters8188F(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#else + _PHY_ReloadADDARegisters8188F(pDM_Odm, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#endif + + //reload RF path default value + for (path = 0; path < pathbound; path++) { + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, 0xd, bMaskDWord, regD[path]); + if (path == ODM_RF_PATH_B) { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE2, bMaskDWord, 0x20101); + } + + //note no index == 0 + if (APK_result[path][1] > 6) + APK_result[path][1] = 6; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1])); + } + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("\n")); + + + for (path = 0; path < pathbound; path++) { + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, 0x3, bMaskDWord, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1])); + if (path == ODM_RF_PATH_A) + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, 0x4, bMaskDWord, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05)); + else + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, 0x4, bMaskDWord, + ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05)); +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if (!IS_HARDWARE_TYPE_8723A(pAdapter)) + ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)path, RF_BS_PA_APSET_G9_G11, bMaskDWord, + ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08)); +#endif + } + + pDM_Odm->RFCalibrateInfo.bAPKdone = TRUE; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==phy_APCalibrate_8188F()\n")); +#endif //MP_DRIVER != 1 +#endif +} + + + +#define DP_BB_REG_NUM 7 +#define DP_RF_REG_NUM 1 +#define DP_RETRY_LIMIT 10 +#define DP_PATH_NUM 2 +#define DP_DPK_NUM 3 +#define DP_DPK_VALUE_NUM 2 + + + + +VOID +PHY_IQCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN bReCovery, + IN BOOLEAN bRestore +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else // (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif + +#if (MP_DRIVER == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx); +#else// (DM_ODM_SUPPORT_TYPE == ODM_CE) + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); +#endif +#endif//(MP_DRIVER == 1) +#endif + + s4Byte result[4][8]; //last is final result + u1Byte i, final_candidate, Indexforchannel; + BOOLEAN bPathAOK, bPathBOK; +#if DBG + s4Byte RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC, RegTmp = 0; +#else + s4Byte RegE94, RegEA4, RegEB4, RegEC4, RegTmp = 0; +#endif + BOOLEAN is12simular, is13simular, is23simular; +#if MP_DRIVER == 1 + BOOLEAN bStartContTx = FALSE; +#endif + BOOLEAN bSingleTone = FALSE, bCarrierSuppression = FALSE; + u4Byte IQK_BB_REG_92C[IQK_BB_REG_NUM] = { + rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, + rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, + rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, + rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, + rOFDM0_RxIQExtAnta + }; + u4Byte Path_SEL_BB = 0, Path_SEL_RF = 0; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE) ) + if (ODM_CheckPowerStatus(pAdapter) == FALSE) + return; +#else + prtl8192cd_priv priv = pDM_Odm->priv; + +#ifdef MP_TEST + if (priv->pshare->rf_ft_var.mp_specific) { + if ((OPMODE & WIFI_MP_CTX_PACKET) || (OPMODE & WIFI_MP_CTX_ST)) + return; + } +#endif + + if (priv->pshare->IQK_88E_done) + bReCovery = 1; + priv->pshare->IQK_88E_done = 1; + +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION)) + return; +#endif + +#if MP_DRIVER == 1 + bStartContTx = pMptCtx->bStartContTx; + bSingleTone = pMptCtx->bSingleTone; + bCarrierSuppression = pMptCtx->bCarrierSuppression; +#endif + + // 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) + if (bSingleTone || bCarrierSuppression) + return; + +#if DISABLE_BB_RF + return; +#endif + + if (bRestore) { + u4Byte offset, data; + u1Byte path, bResult = SUCCESS; + PODM_RF_CAL_T pRFCalibrateInfo = &(pDM_Odm->RFCalibrateInfo); + + //#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; + //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)) { + //DBG_871X("%s =>path:%s Restore TX IQK result failed\n",__FUNCTION__,(path==ODM_RF_PATH_A)?"A":"B"); + bResult = FAIL; + break; + } + RT_TRACE(COMP_MP, DBG_TRACE, ("Switch to S1 TxIQC(offset, data) = (0x%X, 0x%X)\n", offset, data)); + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, data); + } + //Restore RX IQK + 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)) { + //DBG_871X("%s =>path:%s Restore RX IQK result failed\n",__FUNCTION__,(path==ODM_RF_PATH_A)?"A":"B"); + bResult = FAIL; + break; + } + RT_TRACE(COMP_MP, DBG_TRACE, ("Switch to S1 RxIQC (offset, data) = (0x%X, 0x%X)\n", offset, data)); + ODM_SetBBReg(pDM_Odm, offset, bMaskDWord, data); + } + + if (pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A] == 0) { + //DBG_871X("%s => Restore Path-A TxLOK result failed\n",__FUNCTION__); + bResult = FAIL; + } else { + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_A]); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_TXM_IDAC, bRFRegOffsetMask, pDM_Odm->RFCalibrateInfo.TxLOK[ODM_RF_PATH_B]); + } + + if (bResult == SUCCESS) + return; + + } + +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_AP)) + if (bReCovery) +#else//for ODM_WIN + if (bReCovery && (!pAdapter->bInHctTest)) //YJ,add for PowerTest,120405 +#endif + { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("PHY_IQCalibrate_8188F: Return due to bReCovery!\n")); +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_ReloadADDARegisters8188F(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); +#else + _PHY_ReloadADDARegisters8188F(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); +#endif + return; + } + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK:Start!!!\n")); + + + // Save RF Path + Path_SEL_BB = ODM_GetBBReg(pDM_Odm, 0x948, bMaskDWord); + Path_SEL_RF = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xb0, 0xfffff); + + + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + bPathAOK = FALSE; + bPathBOK = FALSE; + is12simular = FALSE; + is23simular = FALSE; + is13simular = FALSE; + + + for (i = 0; i < 3; i++) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + + phy_IQCalibrate_8188F(pAdapter, result, i, FALSE); + +#else + phy_IQCalibrate_8188F(pDM_Odm, result, i, FALSE); +#endif + + + if (i == 1) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + is12simular = phy_SimularityCompare_8188F(pAdapter, result, 0, 1); +#else + is12simular = phy_SimularityCompare_8188F(pDM_Odm, result, 0, 1); +#endif + if (is12simular) { + final_candidate = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is12simular final_candidate is %x\n", final_candidate)); + break; + } + } + + if (i == 2) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + is13simular = phy_SimularityCompare_8188F(pAdapter, result, 0, 2); +#else + is13simular = phy_SimularityCompare_8188F(pDM_Odm, result, 0, 2); +#endif + if (is13simular) { + final_candidate = 0; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is13simular final_candidate is %x\n", final_candidate)); + + break; + } +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + is23simular = phy_SimularityCompare_8188F(pAdapter, result, 1, 2); +#else + is23simular = phy_SimularityCompare_8188F(pDM_Odm, result, 1, 2); +#endif + if (is23simular) { + final_candidate = 1; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: is23simular final_candidate is %x\n", final_candidate)); + } else { + for (i = 0; i < 8; i++) RegTmp += result[3][i]; + + if (RegTmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } +// RT_TRACE(COMP_INIT,DBG_LOUD,("Release Mutex in IQCalibrate\n")); + + for (i = 0; i < 4; i++) { + RegE94 = result[i][0]; + RegEA4 = result[i][2]; + RegEB4 = result[i][4]; + RegEC4 = result[i][6]; +#if DBG + RegE9C = result[i][1]; + RegEAC = result[i][3]; + RegEBC = result[i][5]; + RegECC = result[i][7]; +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: RegE94=%04x RegE9C=%04x RegEA4=%04x RegEAC=%04x RegEB4=%04x RegEBC=%04x RegEC4=%04x RegECC=%04x\n", + RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC)); + } + + if (final_candidate != 0xff) { + pDM_Odm->RFCalibrateInfo.RegE94 = result[final_candidate][0]; + pDM_Odm->RFCalibrateInfo.RegE9C = result[final_candidate][1]; + pDM_Odm->RFCalibrateInfo.RegEB4 = result[final_candidate][4]; + pDM_Odm->RFCalibrateInfo.RegEBC = result[final_candidate][5]; + + RegE94 = result[final_candidate][0]; + RegEA4 = result[final_candidate][2]; + RegEB4 = result[final_candidate][4]; + RegEC4 = result[final_candidate][6]; +#if DBG + RegE9C = result[final_candidate][1]; + RegEAC = result[final_candidate][3]; + RegEBC = result[final_candidate][5]; + RegECC = result[final_candidate][7]; +#endif + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: final_candidate is %x\n", final_candidate)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: RegE94=%04x RegE9C=%04x RegEA4=%04x RegEAC=%04x RegEB4=%04x RegEBC=%04x RegEC4=%04x RegECC=%04x\n", + RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC)); + bPathAOK = bPathBOK = TRUE; + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK: FAIL use default value\n")); + + pDM_Odm->RFCalibrateInfo.RegE94 = pDM_Odm->RFCalibrateInfo.RegEB4 = 0x100; //X default value + pDM_Odm->RFCalibrateInfo.RegE9C = pDM_Odm->RFCalibrateInfo.RegEBC = 0x0; //Y default value + } + +#if MP_DRIVER == 1 + if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || ((pDM_Odm->mp_mode) == 0)) +#endif + { + if (RegE94 != 0) { +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_PathAFillIQKMatrix8188F(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); +#else + _PHY_PathAFillIQKMatrix8188F(pDM_Odm, bPathAOK, result, final_candidate, (RegEA4 == 0)); +#endif + } + } + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +#if MP_DRIVER == 1 + if ((pMptCtx->MptRfPath == ODM_RF_PATH_A) || ((pDM_Odm->mp_mode) == 0)) +#endif + { + if (RegEB4 != 0) + _PHY_PathBFillIQKMatrix8188F(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); + } +#endif + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + Indexforchannel = ODM_GetRightChnlPlaceforIQK(pHalData->CurrentChannel); +#else + Indexforchannel = 0; +#endif + +//To Fix BSOD when final_candidate is 0xff +//by sherry 20120321 + if (final_candidate < 4) { + for (i = 0; i < IQK_Matrix_REG_NUM; i++) pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].Value[0][i] = result[final_candidate][i]; + pDM_Odm->RFCalibrateInfo.IQKMatrixRegSetting[Indexforchannel].bIQKDone = TRUE; + } + //RT_DISP(FINIT, INIT_IQK, ("\nIQK OK Indexforchannel %d.\n", Indexforchannel)); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("\nIQK OK Indexforchannel %d.\n", Indexforchannel)); +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + _PHY_SaveADDARegisters8188F(pAdapter, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); +#else + _PHY_SaveADDARegisters8188F(pDM_Odm, IQK_BB_REG_92C, pDM_Odm->RFCalibrateInfo.IQK_BB_backup_recover, IQK_BB_REG_NUM); +#endif + + // Restore RF Path + ODM_SetBBReg(pDM_Odm, 0x948, bMaskDWord, Path_SEL_BB); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0xb0, 0xfffff, Path_SEL_RF); + + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("IQK finished 8188F\n")); + + +} + + +VOID +PHY_LCCalibrate_8188F( + PVOID pDM_VOID +) +{ +#if MP_DRIVER == 1 + BOOLEAN bStartContTx = FALSE; +#endif + BOOLEAN bSingleTone = FALSE, bCarrierSuppression = FALSE; + u4Byte timeout = 2000, timecount = 0; + + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +#if MP_DRIVER == 1 + PADAPTER pAdapter = pDM_Odm->Adapter; + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PMPT_CONTEXT pMptCtx = &(pAdapter->MptCtx); +#else// (DM_ODM_SUPPORT_TYPE == ODM_CE) + PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.MptCtx); +#endif +#endif +#endif + +#if MP_DRIVER == 1 + bStartContTx = pMptCtx->bStartContTx; + bSingleTone = pMptCtx->bSingleTone; + bCarrierSuppression = pMptCtx->bCarrierSuppression; +#endif + + +#if DISABLE_BB_RF + return; +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION)) + return; +#endif + // 20120213 Turn on when continuous Tx to pass lab testing. (required by Edlu) + if (bSingleTone || bCarrierSuppression) + return; + + while (*(pDM_Odm->pbScanInProcess) && timecount < timeout) { + ODM_delay_ms(50); + timecount += 50; + } + + pDM_Odm->RFCalibrateInfo.bLCKInProgress = TRUE; + + + phy_LCCalibrate_8188F(pDM_Odm, FALSE); + + + pDM_Odm->RFCalibrateInfo.bLCKInProgress = FALSE; + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("LCK:Finish!!!interface %d 8188F\n", pDM_Odm->InterfaceIndex)); + +} + +VOID +PHY_APCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN s1Byte delta +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) +#if DBG + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif +#endif +#if DISABLE_BB_RF + return; +#endif + + return; +#if 0 +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (!(pDM_Odm->SupportAbility & ODM_RF_CALIBRATION)) + return; +#endif + +#if FOR_BRAZIL_PRETEST != 1 + if (pDM_Odm->RFCalibrateInfo.bAPKdone) +#endif + return; + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + if (IS_2T2R(pHalData->VersionID)) + phy_APCalibrate_8188F(pAdapter, delta, TRUE); + else +#endif + { + // For 88C 1T1R +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + phy_APCalibrate_8188F(pAdapter, delta, FALSE); +#else + phy_APCalibrate_8188F(pDM_Odm, delta, FALSE); +#endif + } +#endif +} + +VOID phy_SetRFPathSwitch_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN bMain, + IN BOOLEAN is2T +) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif + + if (bMain) // Left antenna + ODM_SetBBReg(pDM_Odm, 0x92C, bMaskDWord, 0x1); + else + ODM_SetBBReg(pDM_Odm, 0x92C, bMaskDWord, 0x2); +} + +VOID PHY_SetRFPathSwitch_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN bMain +) +{ + +#if DISABLE_BB_RF + return; +#endif + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + phy_SetRFPathSwitch_8188F(pAdapter, bMain, TRUE); +#endif + +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +//digital predistortion +VOID +phy_DigitalPredistortion8188F( +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PADAPTER pAdapter, +#else + IN PDM_ODM_T pDM_Odm, +#endif + IN BOOLEAN is2T +) +{ +#if (RT_PLATFORM == PLATFORM_WINDOWS) +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + + u4Byte tmpReg, tmpReg2, index, i; + u1Byte path, pathbound = PATH_NUM; + u4Byte AFE_backup[IQK_ADDA_REG_NUM]; + u4Byte AFE_REG[IQK_ADDA_REG_NUM] = { + rFPGA0_XCD_SwitchControl, rBlue_Tooth, + 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 + }; + + u4Byte BB_backup[DP_BB_REG_NUM]; + u4Byte BB_REG[DP_BB_REG_NUM] = { + rOFDM0_TRxPathEnable, rFPGA0_RFMOD, + rOFDM0_TRMuxPar, rFPGA0_XCD_RFInterfaceSW, + rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, + rFPGA0_XB_RFInterfaceOE + }; + u4Byte BB_settings[DP_BB_REG_NUM] = { + 0x00a05430, 0x02040000, 0x000800e4, 0x22208000, + 0x0, 0x0, 0x0 + }; + + u4Byte RF_backup[DP_PATH_NUM][DP_RF_REG_NUM]; + u4Byte RF_REG[DP_RF_REG_NUM] = { + RF_TXBIAS_A + }; + + u4Byte MAC_backup[IQK_MAC_REG_NUM]; + u4Byte MAC_REG[IQK_MAC_REG_NUM] = { + REG_TXPAUSE, REG_BCN_CTRL, + REG_BCN_CTRL_1, REG_GPIO_MUXCFG + }; + + u4Byte Tx_AGC[DP_DPK_NUM][DP_DPK_VALUE_NUM] = { + { 0x1e1e1e1e, 0x03901e1e }, + { 0x18181818, 0x03901818 }, + { 0x0e0e0e0e, 0x03900e0e } + }; + + u4Byte AFE_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4 + }; //path A on path B off / path A off path B on + + u1Byte RetryCount = 0; + + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>phy_DigitalPredistortion8188F()\n")); + + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_DigitalPredistortion8188F for %s\n", (is2T ? "2T2R" : "1T1R"))); + + //save BB default value + for (index = 0; index < DP_BB_REG_NUM; index++) BB_backup[index] = ODM_GetBBReg(pDM_Odm, BB_REG[index], bMaskDWord); + + //save MAC default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_SaveMACRegisters8188F(pAdapter, BB_REG, MAC_backup); +#else + _PHY_SaveMACRegisters8188F(pDM_Odm, BB_REG, MAC_backup); +#endif + + //save RF default value + for (path = 0; path < DP_PATH_NUM; path++) { + for (index = 0; index < DP_RF_REG_NUM; index++) +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + RF_backup[path][index] = PHY_QueryRFReg(pAdapter, path, RF_REG[index], bMaskDWord); +#else + RF_backup[path][index] = ODM_GetRFReg(pAdapter, path, RF_REG[index], bMaskDWord); +#endif + } + + //save AFE default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_SaveADDARegisters8188F(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#else + _PHY_SaveADDARegisters8188F(pDM_Odm, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); +#endif + + //Path A/B AFE all on + for (index = 0; index < IQK_ADDA_REG_NUM; index++) ODM_SetBBReg(pDM_Odm, AFE_REG[index], bMaskDWord, 0x6fdb25a4); + + //BB register setting + for (index = 0; index < DP_BB_REG_NUM; index++) { + if (index < 4) + ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_settings[index]); + else if (index == 4) + ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_backup[index] | BIT10 | BIT26); + else + ODM_SetBBReg(pDM_Odm, BB_REG[index], BIT10, 0x00); + } + + //MAC register setting +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_MACSettingCalibration8188F(pAdapter, MAC_REG, MAC_backup); +#else + _PHY_MACSettingCalibration8188F(pDM_Odm, MAC_REG, MAC_backup); +#endif + + //PAGE-E IQC setting + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00); + ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00); + + //path_A DPK + //Path B to standby mode + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMaskDWord, 0x10000); + + // PA gain = 11 & PAD1 => tx_agc 1f ~11 + // PA gain = 11 & PAD2 => tx_agc 10~0e + // PA gain = 01 => tx_agc 0b~0d + // PA gain = 00 => tx_agc 0a~00 + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + ODM_SetBBReg(pDM_Odm, 0xbc0, bMaskDWord, 0x0005361f); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + + //do inner loopback DPK 3 times + for (i = 0; i < 3; i++) { + //PA gain = 11 & PAD2 => tx_agc = 0x0f/0x0c/0x07 + for (index = 0; index < 3; index++) ODM_SetBBReg(pDM_Odm, 0xe00 + index * 4, bMaskDWord, Tx_AGC[i][0]); + ODM_SetBBReg(pDM_Odm, 0xe00 + index * 4, bMaskDWord, Tx_AGC[i][1]); + for (index = 0; index < 4; index++) ODM_SetBBReg(pDM_Odm, 0xe10 + index * 4, bMaskDWord, Tx_AGC[i][0]); + + // PAGE_B for Path-A inner loopback DPK setting + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x02097098); + ODM_SetBBReg(pDM_Odm, rPdp_AntA_4, bMaskDWord, 0xf76d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00880000); + + //----send one shot signal----// + // Path A + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x80047788); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x00047788); + ODM_delay_ms(50); + } + + //PA gain = 11 => tx_agc = 1a + for (index = 0; index < 3; index++) ODM_SetBBReg(pDM_Odm, 0xe00 + index * 4, bMaskDWord, 0x34343434); + ODM_SetBBReg(pDM_Odm, 0xe08 + index * 4, bMaskDWord, 0x03903434); + for (index = 0; index < 4; index++) ODM_SetBBReg(pDM_Odm, 0xe10 + index * 4, bMaskDWord, 0x34343434); + + //==================================== + // PAGE_B for Path-A DPK setting + //==================================== + // open inner loopback @ b00[19]:10 od 0xb00 0x01097018 + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x02017098); + ODM_SetBBReg(pDM_Odm, rPdp_AntA_4, bMaskDWord, 0xf76d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00880000); + + //rf_lpbk_setup + //1.rf 00:5205a, rf 0d:0e52c + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x0c, bMaskDWord, 0x8992b); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x0d, bMaskDWord, 0x0e52c); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, 0x00, bMaskDWord, 0x5205a); + + //----send one shot signal----// + // Path A + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x800477c0); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x000477c0); + ODM_delay_ms(50); + + while (RetryCount < DP_RETRY_LIMIT && !pDM_Odm->RFCalibrateInfo.bDPPathAOK) { + //----read back measurement results----// + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x0c297018); + tmpReg = ODM_GetBBReg(pDM_Odm, 0xbe0, bMaskDWord); + ODM_delay_ms(10); + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x0c29701f); + tmpReg2 = ODM_GetBBReg(pDM_Odm, 0xbe8, bMaskDWord); + ODM_delay_ms(10); + + tmpReg = (tmpReg & bMaskHWord) >> 16; + tmpReg2 = (tmpReg2 & bMaskHWord) >> 16; + if (tmpReg < 0xf0 || tmpReg > 0x105 || tmpReg2 > 0xff) { + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x02017098); + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x800000); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x800477c0); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x000477c0); + ODM_delay_ms(50); + RetryCount++; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A DPK RetryCount %d 0xbe0[31:16] %x 0xbe8[31:16] %x\n", RetryCount, tmpReg, tmpReg2)); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A DPK Sucess\n")); + pDM_Odm->RFCalibrateInfo.bDPPathAOK = TRUE; + break; + } + } + RetryCount = 0; + + //DPP path A + if (pDM_Odm->RFCalibrateInfo.bDPPathAOK) { + // DP settings + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x01017098); + ODM_SetBBReg(pDM_Odm, rPdp_AntA_4, bMaskDWord, 0x776d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntA, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00880000); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + + for (i = rPdp_AntA; i <= 0xb3c; i += 4) { + ODM_SetBBReg(pDM_Odm, i, bMaskDWord, 0x40004000); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path A ofsset = 0x%x\n", i)); + } + + //pwsf + ODM_SetBBReg(pDM_Odm, 0xb40, bMaskDWord, 0x40404040); + ODM_SetBBReg(pDM_Odm, 0xb44, bMaskDWord, 0x28324040); + ODM_SetBBReg(pDM_Odm, 0xb48, bMaskDWord, 0x10141920); + + for (i = 0xb4c; i <= 0xb5c; i += 4) + ODM_SetBBReg(pDM_Odm, i, bMaskDWord, 0x0c0c0c0c); + + //TX_AGC boundary + ODM_SetBBReg(pDM_Odm, 0xbc0, bMaskDWord, 0x0005361f); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + } else { + ODM_SetBBReg(pDM_Odm, rPdp_AntA, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, rPdp_AntA_4, bMaskDWord, 0x00000000); + } + + //DPK path B + if (is2T) { + //Path A to standby mode + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_AC, bMaskDWord, 0x10000); + + // LUTs => tx_agc + // PA gain = 11 & PAD1, => tx_agc 1f ~11 + // PA gain = 11 & PAD2, => tx_agc 10 ~0e + // PA gain = 01 => tx_agc 0b ~0d + // PA gain = 00 => tx_agc 0a ~00 + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + ODM_SetBBReg(pDM_Odm, 0xbc4, bMaskDWord, 0x0005361f); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + + //do inner loopback DPK 3 times + for (i = 0; i < 3; i++) { + //PA gain = 11 & PAD2 => tx_agc = 0x0f/0x0c/0x07 + for (index = 0; index < 4; index++) ODM_SetBBReg(pDM_Odm, 0x830 + index * 4, bMaskDWord, Tx_AGC[i][0]); + for (index = 0; index < 2; index++) ODM_SetBBReg(pDM_Odm, 0x848 + index * 4, bMaskDWord, Tx_AGC[i][0]); + for (index = 0; index < 2; index++) ODM_SetBBReg(pDM_Odm, 0x868 + index * 4, bMaskDWord, Tx_AGC[i][0]); + + // PAGE_B for Path-A inner loopback DPK setting + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x02097098); + ODM_SetBBReg(pDM_Odm, rPdp_AntB_4, bMaskDWord, 0xf76d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntB, bMaskDWord, 0x00880000); + + //----send one shot signal----// + // Path B + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x80047788); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x00047788); + ODM_delay_ms(50); + } + + // PA gain = 11 => tx_agc = 1a + for (index = 0; index < 4; index++) ODM_SetBBReg(pDM_Odm, 0x830 + index * 4, bMaskDWord, 0x34343434); + for (index = 0; index < 2; index++) ODM_SetBBReg(pDM_Odm, 0x848 + index * 4, bMaskDWord, 0x34343434); + for (index = 0; index < 2; index++) ODM_SetBBReg(pDM_Odm, 0x868 + index * 4, bMaskDWord, 0x34343434); + + // PAGE_B for Path-B DPK setting + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x02017098); + ODM_SetBBReg(pDM_Odm, rPdp_AntB_4, bMaskDWord, 0xf76d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntB, bMaskDWord, 0x00880000); + + // RF lpbk switches on + ODM_SetBBReg(pDM_Odm, 0x840, bMaskDWord, 0x0101000f); + ODM_SetBBReg(pDM_Odm, 0x840, bMaskDWord, 0x01120103); + + //Path-B RF lpbk + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x0c, bMaskDWord, 0x8992b); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, 0x0d, bMaskDWord, 0x0e52c); + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_AC, bMaskDWord, 0x5205a); + + //----send one shot signal----// + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x800477c0); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x000477c0); + ODM_delay_ms(50); + + while (RetryCount < DP_RETRY_LIMIT && !pDM_Odm->RFCalibrateInfo.bDPPathBOK) { + //----read back measurement results----// + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x0c297018); + tmpReg = ODM_GetBBReg(pDM_Odm, 0xbf0, bMaskDWord); + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x0c29701f); + tmpReg2 = ODM_GetBBReg(pDM_Odm, 0xbf8, bMaskDWord); + + tmpReg = (tmpReg & bMaskHWord) >> 16; + tmpReg2 = (tmpReg2 & bMaskHWord) >> 16; + + if (tmpReg < 0xf0 || tmpReg > 0x105 || tmpReg2 > 0xff) { + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x02017098); + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x800000); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x800477c0); + ODM_delay_ms(1); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x000477c0); + ODM_delay_ms(50); + RetryCount++; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B DPK RetryCount %d 0xbf0[31:16] %x, 0xbf8[31:16] %x\n", RetryCount , tmpReg, tmpReg2)); + } else { + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B DPK Success\n")); + pDM_Odm->RFCalibrateInfo.bDPPathBOK = TRUE; + break; + } + } + + //DPP path B + if (pDM_Odm->RFCalibrateInfo.bDPPathBOK) { + // DP setting + // LUT by SRAM + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x01017098); + ODM_SetBBReg(pDM_Odm, rPdp_AntB_4, bMaskDWord, 0x776d9f84); + ODM_SetBBReg(pDM_Odm, rConfig_Pmpd_AntB, bMaskDWord, 0x0004ab87); + ODM_SetBBReg(pDM_Odm, rConfig_AntB, bMaskDWord, 0x00880000); + + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x400000); + for (i = 0xb60; i <= 0xb9c; i += 4) { + ODM_SetBBReg(pDM_Odm, i, bMaskDWord, 0x40004000); + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("path B ofsset = 0x%x\n", i)); + } + + // PWSF + ODM_SetBBReg(pDM_Odm, 0xba0, bMaskDWord, 0x40404040); + ODM_SetBBReg(pDM_Odm, 0xba4, bMaskDWord, 0x28324050); + ODM_SetBBReg(pDM_Odm, 0xba8, bMaskDWord, 0x0c141920); + + for (i = 0xbac; i <= 0xbbc; i += 4) + ODM_SetBBReg(pDM_Odm, i, bMaskDWord, 0x0c0c0c0c); + + // tx_agc boundary + ODM_SetBBReg(pDM_Odm, 0xbc4, bMaskDWord, 0x0005361f); + ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskH3Bytes, 0x000000); + + } else { + ODM_SetBBReg(pDM_Odm, rPdp_AntB, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, rPdp_AntB_4, bMaskDWord, 0x00000000); + } + } + + //reload BB default value + for (index = 0; index < DP_BB_REG_NUM; index++) ODM_SetBBReg(pDM_Odm, BB_REG[index], bMaskDWord, BB_backup[index]); + + //reload RF default value + for (path = 0; path < DP_PATH_NUM; path++) { + for (i = 0; i < DP_RF_REG_NUM; i++) + ODM_SetRFReg(pDM_Odm, path, RF_REG[i], bMaskDWord, RF_backup[path][i]); + } + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f); //standby mode + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_MODE2, bMaskDWord, 0x20101); //RF lpbk switches off + + //reload AFE default value +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + _PHY_ReloadADDARegisters8188F(pAdapter, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + //reload MAC default value + _PHY_ReloadMACRegisters8188F(pAdapter, MAC_REG, MAC_backup); +#else + _PHY_ReloadADDARegisters8188F(pDM_Odm, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM); + + //reload MAC default value + _PHY_ReloadMACRegisters8188F(pDM_Odm, MAC_REG, MAC_backup); +#endif + + pDM_Odm->RFCalibrateInfo.bDPdone = TRUE; + ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==phy_DigitalPredistortion8188F()\n")); +#endif +} + +VOID +PHY_DigitalPredistortion_8188F( +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PADAPTER pAdapter +#else + IN PDM_ODM_T pDM_Odm +#endif +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif +#if DISABLE_BB_RF + return; +#endif + + return; + + if (pDM_Odm->RFCalibrateInfo.bDPdone) + return; +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + + if (IS_92C_SERIAL(pHalData->VersionID)) + phy_DigitalPredistortion8188F(pAdapter, TRUE); + else +#endif + { + // For 88C 1T1R + phy_DigitalPredistortion8188F(pAdapter, FALSE); + } +} + + + +//return value TRUE => Main; FALSE => Aux + +BOOLEAN phy_QueryRFPathSwitch_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN BOOLEAN is2T +) +{ +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#endif +#endif + + + if (ODM_GetBBReg(pDM_Odm, 0x92C, bMaskDWord) == 0x01) + return TRUE; + else + return FALSE; + +} + + + +//return value TRUE => Main; FALSE => Aux +BOOLEAN PHY_QueryRFPathSwitch_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER pAdapter +#endif +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + +#if DISABLE_BB_RF + return TRUE; +#endif + +#if !(DM_ODM_SUPPORT_TYPE & ODM_AP) + return phy_QueryRFPathSwitch_8188F(pAdapter, FALSE); +#else + return phy_QueryRFPathSwitch_8188F(pDM_Odm, FALSE); +#endif + +} +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.h new file mode 100644 index 00000000..9d384b9c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/halphyrf_8188f.h @@ -0,0 +1,135 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_RF_8188F_H__ +#define __HAL_PHY_RF_8188F_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define IQK_DELAY_TIME_8188F 25 /* ms */ +#define IQK_DEFERRED_TIME_8188F 4 +#define index_mapping_NUM_8188F 15 +#define AVG_THERMAL_NUM_8188F 4 +#define RF_T_METER_8188F 0x42 + + +void ConfigureTxpowerTrack_8188F( + PTXPWRTRACK_CFG pConfig + ); + +void DoIQK_8188F( + PVOID pDM_VOID, + u1Byte DeltaThermalIndex, + u1Byte ThermalValue, + u1Byte Threshold + ); + +VOID +ODM_TxPwrTrackSetPwr_8188F( + IN PVOID pDM_VOID, + PWRTRACK_METHOD Method, + u1Byte RFPath, + u1Byte ChannelMappedIndex + ); + +//1 7. IQK + +void +PHY_IQCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER Adapter, +#endif + IN BOOLEAN bReCovery, + IN BOOLEAN bRestore); + + +// +// LC calibrate +// +void +PHY_LCCalibrate_8188F( + IN PVOID pDM_VOID +); + +// +// AP calibrate +// +void +PHY_APCalibrate_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN s1Byte delta); +void +PHY_DigitalPredistortion_8188F( IN PADAPTER pAdapter); + + +VOID +_PHY_SaveADDARegisters_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN pu4Byte ADDABackup, + IN u4Byte RegisterNum + ); + +VOID +_PHY_PathADDAOn_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN BOOLEAN isPathAOn, + IN BOOLEAN is2T + ); + +VOID +_PHY_MACSettingCalibration_8188F( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte MACReg, + IN pu4Byte MACBackup + ); + + +VOID +_PHY_PathAStandBy( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER pAdapter +#endif + ); + + +#endif // #ifndef __HAL_PHY_RF_8188E_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/mp_precomp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/mp_precomp.h new file mode 100644 index 00000000..4e376e79 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.c new file mode 100644 index 00000000..e7c8716c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.c @@ -0,0 +1,233 @@ +/****************************************************************************** + * + * 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 (RTL8188F_SUPPORT == 1) + +void +odm_ConfigRFReg_8188F( + 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_8188F( + 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_8188F(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_8188F( + 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_8188F(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_8188F( + 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_8188F( + 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_8188F( + 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_8188F( + 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_8188F( + 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 | ODM_CE)) + PHY_SetTxPowerLimit(pDM_Odm, Regulation, Band, + Bandwidth, RateSection, RfPath, Channel, PowerLimit); +#endif +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.h new file mode 100644 index 00000000..106e6ab9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_regconfig8188f.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_8188F +#define __INC_ODM_REGCONFIG_H_8188F + +#if (RTL8188F_SUPPORT == 1) + +void +odm_ConfigRFReg_8188F( + 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_8188F( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ); + +void +odm_ConfigRF_RadioB_8188F( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ); + +void +odm_ConfigMAC_8188F( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u1Byte Data + ); + +void +odm_ConfigBB_AGC_8188F( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_PHY_REG_PG_8188F( + 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_8188F( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_TXPWR_LMT_8188F( + 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/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.c new file mode 100644 index 00000000..2fcbab4e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.c @@ -0,0 +1,72 @@ +/****************************************************************************** + * + * 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 (RTL8188F_SUPPORT == 1) + + s1Byte +odm_CCKRSSI_8188F( + IN u1Byte LNA_idx, + IN u1Byte VGA_idx + ) +{ + s1Byte rx_pwr_all=0x00; + switch(LNA_idx) + { + case 7: + if (VGA_idx <= 27) + rx_pwr_all = -100 + 2 * (27 - VGA_idx); + else + rx_pwr_all = -100; + break; + + case 5: + rx_pwr_all = -74 + 2 * (21 - VGA_idx); + break; + + case 3: + rx_pwr_all = -60 + 2 * (20 - VGA_idx); + break; + + case 1: + rx_pwr_all = -44 + 2 * (19 - VGA_idx); + break; + + default: + break; + } + return rx_pwr_all; +} + +#endif // end if RTL8188F + + + + + + + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.h new file mode 100644 index 00000000..714b78a0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/phydm_rtl8188f.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_RTL8188F_H__ +#define __ODM_RTL8188F_H__ + +s1Byte +odm_CCKRSSI_8188F( + IN u1Byte LNA_idx, + IN u1Byte VGA_idx + ); + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/version_rtl8188f.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/version_rtl8188f.h new file mode 100644 index 00000000..2c2217a3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/rtl8188f/version_rtl8188f.h @@ -0,0 +1,10 @@ +/*RTL8188F PHY Parameters*/ +/* +[Caution] + Since 01/Aug/2015, the commit rules will be simplified. + You do not need to fill up the version.h anymore, + only the maintenance supervisor fills it before formal release. +*/ +#define RELEASE_DATE_8188F 20151008 +#define COMMIT_BY_8188F "BB_DAVID" +#define RELEASE_VERSION_8188F 25 diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.c new file mode 100644 index 00000000..426a1933 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.c @@ -0,0 +1,551 @@ +//============================================================ +// Description: +// +// This file is for TXBF mechanism +// +//============================================================ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +/*Beamforming halcomtxbf API create by YuChen 2015/05*/ + +VOID +halComTxbf_beamformInit( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_Init(pDM_Odm); +} + +/*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/ +VOID +halComTxbf_ConfigGtab( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_ConfigGtab(pDM_Odm); +} + +VOID +phydm_beamformSetSoundingEnter( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_EnterWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_EnterWorkItem)); +#else + halComTxbf_EnterWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetSoundingLeave( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_LeaveWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_LeaveWorkItem)); +#else + halComTxbf_LeaveWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetSoundingRate( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_RateWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_RateWorkItem)); +#else + halComTxbf_RateWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetSoundingStatus( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_StatusWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_StatusWorkItem)); +#else + halComTxbf_StatusWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetSoundingFwNdpa( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (*pDM_Odm->pbFwDwRsvdPageInProgress) + ODM_SetTimer(pDM_Odm, &(pTxbfInfo->Txbf_FwNdpaTimer), 5); + else + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_FwNdpaWorkItem)); +#else + halComTxbf_FwNdpaWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetSoundingClk( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_ClkWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_ClkWorkItem)); +#elif(DM_ODM_SUPPORT_TYPE == ODM_CE) + PADAPTER padapter = pDM_Odm->Adapter; + + rtw_run_in_thread_cmd(padapter, halComTxbf_ClkWorkItemCallback, padapter); +#else + halComTxbf_ClkWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetResetTxPath( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_ResetTxPathWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_ResetTxPathWorkItem)); +#else + halComTxbf_ResetTxPathWorkItemCallback(pDM_Odm); +#endif +} + +VOID +phydm_beamformSetGetTxRate( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + if (PlatformIsWorkItemScheduled(&(pTxbfInfo->Txbf_GetTxRateWorkItem)) == FALSE) + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_GetTxRateWorkItem)); +#else + halComTxbf_GetTxRateWorkItemCallback(pDM_Odm); +#endif +} + +VOID +halComTxbf_EnterWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + u1Byte Idx = pTxbfInfo->TXBFIdx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) + HalTxbfJaguar_Enter(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8192E) + HalTxbf8192E_Enter(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_Enter(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8821B) + HalTxbf8821B_Enter(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_Enter(pDM_Odm, Idx); +} + +VOID +halComTxbf_LeaveWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + u1Byte Idx = pTxbfInfo->TXBFIdx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) + HalTxbfJaguar_Leave(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8192E) + HalTxbf8192E_Leave(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_Leave(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8821B) + HalTxbf8821B_Leave(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_Leave(pDM_Odm, Idx); +} + + +VOID +halComTxbf_FwNdpaWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + u1Byte Idx = pTxbfInfo->NdpaIdx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) + HalTxbfJaguar_FwTxBF(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8192E) + HalTxbf8192E_FwTxBF(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_FwTxBF(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8821B) + HalTxbf8821B_FwTxBF(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_FwTxBF(pDM_Odm, Idx); +} + +VOID +halComTxbf_ClkWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & ODM_RTL8812) + HalTxbfJaguar_Clk_8812A(pDM_Odm); +} + + + +VOID +halComTxbf_RateWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + u1Byte BW = pTxbfInfo->BW; + u1Byte Rate = pTxbfInfo->Rate; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & ODM_RTL8812) + HalTxbf8812A_setNDPArate(pDM_Odm, BW, Rate); + else if (pDM_Odm->SupportICType & ODM_RTL8192E) + HalTxbf8192E_setNDPArate(pDM_Odm, BW, Rate); + else if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_setNDPArate(pDM_Odm, BW, Rate); + +} + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +halComTxbf_FwNdpaTimerCallback( + IN PRT_TIMER pTimer + ) +{ + + PADAPTER Adapter = (PADAPTER)pTimer->Adapter; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (*pDM_Odm->pbFwDwRsvdPageInProgress) + ODM_SetTimer(pDM_Odm, &(pTxbfInfo->Txbf_FwNdpaTimer), 5); + else + PlatformScheduleWorkItem(&(pTxbfInfo->Txbf_FwNdpaWorkItem)); +} +#endif + + +VOID +halComTxbf_StatusWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + u1Byte Idx = pTxbfInfo->TXBFIdx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->SupportICType & (ODM_RTL8812|ODM_RTL8821)) + HalTxbfJaguar_Status(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8192E) + HalTxbf8192E_Status(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_Status(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8821B) + HalTxbf8821B_Status(pDM_Odm, Idx); + else if (pDM_Odm->SupportICType & ODM_RTL8822B) + HalTxbf8822B_Status(pDM_Odm, Idx); +} + +VOID +halComTxbf_ResetTxPathWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + u1Byte Idx = pTxbfInfo->TXBFIdx; + + if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_ResetTxPath(pDM_Odm, Idx); + +} + +VOID +halComTxbf_GetTxRateWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ) +{ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#endif + + if (pDM_Odm->SupportICType & ODM_RTL8814A) + HalTxbf8814A_GetTxRate(pDM_Odm); +} + + +BOOLEAN +HalComTxbf_Set( + IN PVOID pDM_VOID, + IN u1Byte setType, + IN PVOID pInBuf + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PBOOLEAN pBoolean=(PBOOLEAN)pInBuf; + pu1Byte pU1Tmp=(pu1Byte)pInBuf; + pu4Byte pU4Tmp=(pu4Byte)pInBuf; + PHAL_TXBF_INFO pTxbfInfo = &pDM_Odm->BeamformingInfo.TxbfInfo; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] setType = 0x%X\n", __func__, setType)); + + switch(setType){ + case TXBF_SET_SOUNDING_ENTER: + pTxbfInfo->TXBFIdx = *pU1Tmp; + phydm_beamformSetSoundingEnter(pDM_Odm); + break; + + case TXBF_SET_SOUNDING_LEAVE: + pTxbfInfo->TXBFIdx = *pU1Tmp; + phydm_beamformSetSoundingLeave(pDM_Odm); + break; + + case TXBF_SET_SOUNDING_RATE: + pTxbfInfo->BW = pU1Tmp[0]; + pTxbfInfo->Rate = pU1Tmp[1]; + phydm_beamformSetSoundingRate(pDM_Odm); + break; + + case TXBF_SET_SOUNDING_STATUS: + pTxbfInfo->TXBFIdx = *pU1Tmp; + phydm_beamformSetSoundingStatus(pDM_Odm); + break; + + case TXBF_SET_SOUNDING_FW_NDPA: + pTxbfInfo->NdpaIdx = *pU1Tmp; + phydm_beamformSetSoundingFwNdpa(pDM_Odm); + break; + + case TXBF_SET_SOUNDING_CLK: + phydm_beamformSetSoundingClk(pDM_Odm); + break; + + case TXBF_SET_TX_PATH_RESET: + pTxbfInfo->TXBFIdx = *pU1Tmp; + phydm_beamformSetResetTxPath(pDM_Odm); + break; + + case TXBF_SET_GET_TX_RATE: + phydm_beamformSetGetTxRate(pDM_Odm); + break; + + } + + return TRUE; +} + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +BOOLEAN +HalComTxbf_Get( + IN PADAPTER Adapter, + IN u1Byte getType, + OUT PVOID pOutBuf + ) +{ + PHAL_DATA_TYPE pHalData=GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PBOOLEAN pBoolean=(PBOOLEAN)pOutBuf; + ps4Byte pS4Tmp=(ps4Byte)pOutBuf; + pu4Byte pU4Tmp=(pu4Byte)pOutBuf; + pu1Byte pU1Tmp=(pu1Byte)pOutBuf; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (getType == TXBF_GET_EXPLICIT_BEAMFORMEE) { + if (IS_HARDWARE_TYPE_OLDER_THAN_8812A(Adapter)) + *pBoolean = FALSE; + else if (/*IS_HARDWARE_TYPE_8822B(Adapter) ||*/ + IS_HARDWARE_TYPE_8821B(Adapter) || + IS_HARDWARE_TYPE_8192E(Adapter) || + IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) + *pBoolean = TRUE; + else + *pBoolean = FALSE; + } else if (getType == TXBF_GET_EXPLICIT_BEAMFORMER) { + if (IS_HARDWARE_TYPE_OLDER_THAN_8812A(Adapter)) + *pBoolean = FALSE; + else if (/*IS_HARDWARE_TYPE_8822B(Adapter) ||*/ + IS_HARDWARE_TYPE_8821B(Adapter) || + IS_HARDWARE_TYPE_8192E(Adapter) || + IS_HARDWARE_TYPE_JAGUAR(Adapter) || IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(Adapter)) { + if(pHalData->RF_Type == RF_2T2R || pHalData->RF_Type == RF_3T3R) + *pBoolean = TRUE; + else + *pBoolean = FALSE; + } else + *pBoolean = FALSE; + } else if (getType == TXBF_GET_MU_MIMO_STA) { +#if (RTL8822B_SUPPORT == 1) + if (/*pDM_Odm->SupportICType & (ODM_RTL8822B)*/ + IS_HARDWARE_TYPE_8822B(Adapter)) + *pBoolean = TRUE; + else +#endif + *pBoolean = FALSE; + + + } else if (getType == TXBF_GET_MU_MIMO_AP) { +#if (RTL8822B_SUPPORT == 1) + if (/*pDM_Odm->SupportICType & (ODM_RTL8822B)*/ + IS_HARDWARE_TYPE_8822B(Adapter)) + *pBoolean = TRUE; + else +#endif + *pBoolean = FALSE; + } + + return TRUE; +} +#endif + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.h new file mode 100644 index 00000000..abb9d594 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/halcomtxbf.h @@ -0,0 +1,181 @@ +#ifndef __HAL_COM_TXBF_H__ +#define __HAL_COM_TXBF_H__ + +/* +typedef BOOLEAN +(*TXBF_GET)( + IN PVOID pAdapter, + IN u1Byte getType, + OUT PVOID pOutBuf + ); + +typedef BOOLEAN +(*TXBF_SET)( + IN PVOID pAdapter, + IN u1Byte setType, + OUT PVOID pInBuf + ); +*/ +#define TxBF_Nr(a, b) ((a > b) ? (b) : (a)) + +typedef enum _TXBF_SET_TYPE{ + TXBF_SET_SOUNDING_ENTER, + TXBF_SET_SOUNDING_LEAVE, + TXBF_SET_SOUNDING_RATE, + TXBF_SET_SOUNDING_STATUS, + TXBF_SET_SOUNDING_FW_NDPA, + TXBF_SET_SOUNDING_CLK, + TXBF_SET_TX_PATH_RESET, + TXBF_SET_GET_TX_RATE +}TXBF_SET_TYPE,*PTXBF_SET_TYPE; + + +typedef enum _TXBF_GET_TYPE{ + TXBF_GET_EXPLICIT_BEAMFORMEE, + TXBF_GET_EXPLICIT_BEAMFORMER, + TXBF_GET_MU_MIMO_STA, + TXBF_GET_MU_MIMO_AP +}TXBF_GET_TYPE,*PTXBF_GET_TYPE; + + + +//2 HAL TXBF related +typedef struct _HAL_TXBF_INFO { + u1Byte TXBFIdx; + u1Byte NdpaIdx; + u1Byte BW; + u1Byte Rate; + + RT_TIMER Txbf_FwNdpaTimer; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_WORK_ITEM Txbf_EnterWorkItem; + RT_WORK_ITEM Txbf_LeaveWorkItem; + RT_WORK_ITEM Txbf_FwNdpaWorkItem; + RT_WORK_ITEM Txbf_ClkWorkItem; + RT_WORK_ITEM Txbf_StatusWorkItem; + RT_WORK_ITEM Txbf_RateWorkItem; + RT_WORK_ITEM Txbf_ResetTxPathWorkItem; + RT_WORK_ITEM Txbf_GetTxRateWorkItem; +#endif + +} HAL_TXBF_INFO, *PHAL_TXBF_INFO; + +#if (BEAMFORMING_SUPPORT == 1) + +VOID +halComTxbf_beamformInit( + IN PVOID pDM_VOID + ); + +VOID +halComTxbf_ConfigGtab( + IN PVOID pDM_VOID + ); + +VOID +halComTxbf_EnterWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_LeaveWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_FwNdpaWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_ClkWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_ResetTxPathWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_GetTxRateWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_RateWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +VOID +halComTxbf_FwNdpaTimerCallback( + IN PRT_TIMER pTimer + ); + +VOID +halComTxbf_StatusWorkItemCallback( +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN PADAPTER Adapter +#else + IN PVOID pDM_VOID +#endif + ); + +BOOLEAN +HalComTxbf_Set( + IN PVOID pDM_VOID, + IN u1Byte setType, + IN PVOID pInBuf + ); + +BOOLEAN +HalComTxbf_Get( + IN PADAPTER Adapter, + IN u1Byte getType, + OUT PVOID pOutBuf + ); + +#else +#define halComTxbf_beamformInit(pDM_VOID) NULL +#define halComTxbf_ConfigGtab(pDM_VOID) NULL +#define halComTxbf_EnterWorkItemCallback(_Adapter) NULL +#define halComTxbf_LeaveWorkItemCallback(_Adapter) NULL +#define halComTxbf_FwNdpaWorkItemCallback(_Adapter) NULL +#define halComTxbf_ClkWorkItemCallback(_Adapter) NULL +#define halComTxbf_RateWorkItemCallback(_Adapter) NULL +#define halComTxbf_FwNdpaTimerCallback(_Adapter) NULL +#define halComTxbf_StatusWorkItemCallback(_Adapter) NULL +#define HalComTxbf_Get(_Adapter, _getType, _pOutBuf) + +#endif + +#endif // #ifndef __HAL_COM_TXBF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.c new file mode 100644 index 00000000..754686bf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.c @@ -0,0 +1,392 @@ +//============================================================ +// Description: +// +// This file is for 8192E TXBF mechanism +// +//============================================================ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8192E_SUPPORT == 1) + +VOID +HalTxbf8192E_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8192E, (Rate << 2 | BW)); + +} + +VOID +halTxbf8192E_RfMode( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamInfo +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + BOOLEAN bSelfBeamformer = FALSE; + BOOLEAN bSelfBeamformee = FALSE; + BEAMFORMING_CAP BeamformCap = BEAMFORMING_CAP_NONE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pDM_Odm->RFType == ODM_1T1R) + return; + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x1); /*RF Mode table write enable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WE_LUT, 0x80000, 0x1); /*RF Mode table write enable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) { + /*Path_A*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0xfffff, 0x18000); /*Select RX mode 0x30=0x18000*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x0000f); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0x77fc2); /*Enable TXIQGEN in RX mode*/ + /*Path_B*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0xfffff, 0x18000); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x0000f); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0x77fc2); /*Enable TXIQGEN in RX mode*/ + } else { + /*Path_A*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0xfffff, 0x18000); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x0000f); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0x77f82); /*Disable TXIQGEN in RX mode*/ + /*Path_B*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0xfffff, 0x18000); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x0000f); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0x77f82); /*Disable TXIQGEN in RX mode*/ + } + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WE_LUT, 0x80000, 0x0); /*RF Mode table write disable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WE_LUT, 0x80000, 0x0); /*RF Mode table write disable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) { + ODM_SetBBReg(pDM_Odm, rFPGA1_TxInfo, bMaskDWord, 0x83321333); + ODM_SetBBReg(pDM_Odm, rCCK0_AFESetting, bMaskByte3, 0xc1); + } else + ODM_SetBBReg(pDM_Odm, rFPGA1_TxInfo, bMaskDWord, 0x81121313); +} + + + +VOID +halTxbf8192E_FwTxBFCmd( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx, Period0 = 0, Period1 = 0; + u1Byte PageNum0 = 0xFF, PageNum1 = 0xFF; + u1Byte u1TxBFParm[3] = {0}; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + if (pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (Idx == 0) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum0 = 0xFE; + else + PageNum0 = 0xFF; //stop sounding + Period0 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } else if (Idx == 1) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum1 = 0xFE; + else + PageNum1 = 0xFF; //stop sounding + Period1 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } + } + } + + u1TxBFParm[0] = PageNum0; + u1TxBFParm[1] = PageNum1; + u1TxBFParm[2] = (Period1 << 4) | Period0; + ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_TXBF, 3, u1TxBFParm); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, + ("[%s] PageNum0 = %d Period0 = %d, PageNum1 = %d Period1 %d\n", __func__, PageNum0, Period0, PageNum1, Period1)); +} + + +VOID +halTxbf8192E_DownloadNDPA( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte u1bTmp = 0, tmpReg422 = 0, Head_Page; + u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; + BOOLEAN bSendBeacon = FALSE; + PADAPTER Adapter = pDM_Odm->Adapter; + u1Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812; + /*default reseved 1 page for the IC type which is undefined.*/ + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + *pDM_Odm->pbFwDwRsvdPageInProgress = TRUE; +#endif + if (Idx == 0) + Head_Page = 0xFE; + else + Head_Page = 0xFE; + + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu1Byte)&TxPageBndy); + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8192E+1); + ODM_Write1Byte(pDM_Odm, REG_CR_8192E+1, (u1bTmp | BIT0)); + + /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ + tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8192E+2); + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8192E+2, tmpReg422 & (~BIT6)); + + if (tmpReg422 & BIT6) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_WARNING, ("%s There is an Adapter is sending beacon.\n", __func__)); + bSendBeacon = TRUE; + } + + /*TDECTRL[15:8] 0x209[7:0] = 0xFE/0xFD NDPA Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+1, Head_Page); + + do { + /*Clear beacon valid check bit.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+2); + ODM_Write1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+2, (BcnValidReg | BIT0)); + + // download NDPA rsvd page. + Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); + +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_MGQ_TXBD_NUM_8192E+3); + count = 0; + while ((count < 20) && (u1bTmp & BIT4)) { + count++; + ODM_delay_us(10); + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_MGQ_TXBD_NUM_8192E+3); + } + ODM_Write1Byte(pDM_Odm, REG_MGQ_TXBD_NUM_8192E+3, u1bTmp | BIT4); +#endif + + /*check rsvd page download OK.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+2); + count = 0; + while (!(BcnValidReg & BIT0) && count < 20) { + count++; + ODM_delay_us(10); + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+2); + } + DLBcnCount++; + } while (!(BcnValidReg & BIT0) && DLBcnCount < 5); + + if (!(BcnValidReg & BIT0)) + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_WARNING, ("%s Download RSVD page failed!\n", __func__)); + + /*TDECTRL[15:8] 0x209[7:0] = 0xF9 Beacon Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_DWBCN0_CTRL_8192E+1, TxPageBndy); + + /*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 (bSendBeacon) + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8192E+2, tmpReg422); + + /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ + /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8192E+1); + ODM_Write1Byte(pDM_Odm, REG_CR_8192E+1, (u1bTmp & (~BIT0))); + + pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + *pDM_Odm->pbFwDwRsvdPageInProgress = FALSE; +#endif +} + + +VOID +HalTxbf8192E_Enter( + IN PVOID pDM_VOID, + IN u1Byte BFerBFeeIdx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; + u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); + u4Byte CSI_Param; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + RT_BEAMFORMER_ENTRY BeamformerEntry; + u2Byte STAid = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + halTxbf8192E_RfMode(pDM_Odm, pBeamformingInfo); + + if (pDM_Odm->RFType == ODM_2T2R) + ODM_Write4Byte(pDM_Odm, 0xd80, 0x00000000); /*Nc =2*/ + + if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; + + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E, 0xCB); + + /*MAC address/Partial AID of Beamformer*/ + if (BFerIdx == 0) { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8192E+i), BeamformerEntry.MacAddr[i]); + } else { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8192E+i), BeamformerEntry.MacAddr[i]); + } + + /*CSI report parameters of Beamformer Default use Nc = 2*/ + CSI_Param = 0x03090309; + + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8192E, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8192E, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8192E, CSI_Param); + + /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E+3, 0x50); + + } + + if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + STAid = BeamformeeEntry.MacId; + else + STAid = BeamformeeEntry.P_AID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s], STAid=0x%X\n", __func__, STAid)); + + /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ + if (BFeeIdx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E, STAid); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+3) | BIT4 | BIT6 | BIT7); + } else + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2, STAid | BIT12 | BIT14 | BIT15); + + /*CSI report parameters of Beamformee*/ + if (BFeeIdx == 0) { + /*Get BIT24 & BIT25*/ + u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+3) & 0x3; + + ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+3, tmp | 0x60); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E, STAid | BIT9); + } else { + /*Set BIT25*/ + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2, STAid | 0xE200); + } + phydm_Beamforming_Notify(pDM_Odm); + + } +} + + +VOID +HalTxbf8192E_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + halTxbf8192E_RfMode(pDM_Odm, pBeamInfo); + + /* Clear P_AID of Beamformee + * Clear MAC addresss of Beamformer + * Clear Associated Bfmee Sel + */ + if (pBeamInfo->BeamformCap == BEAMFORMING_CAP_NONE) + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E, 0xC8); + + if (Idx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E, 0); + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8192E, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8192E+4, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E, 0); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2) & 0xF000); + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8192E, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8192E+4, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2, ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2) & 0x60); + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Idx %d\n", __func__, Idx)); +} + + +VOID +HalTxbf8192E_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte BeamCtrlVal; + u4Byte BeamCtrlReg; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformEntry = pBeamInfo->BeamformeeEntry[Idx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + BeamCtrlVal = BeamformEntry.MacId; + else + BeamCtrlVal = BeamformEntry.P_AID; + + if (Idx == 0) + BeamCtrlReg = REG_TXBF_CTRL_8192E; + else { + BeamCtrlReg = REG_TXBF_CTRL_8192E+2; + BeamCtrlVal |= BIT12 | BIT14 | BIT15; + } + + if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) + BeamCtrlVal |= BIT9; + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) + BeamCtrlVal |= BIT10; + } else + BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); + + ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Idx %d BeamCtrlReg %x BeamCtrlVal %x\n", __func__, Idx, BeamCtrlReg, BeamCtrlVal)); +} + + +VOID +HalTxbf8192E_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + halTxbf8192E_DownloadNDPA(pDM_Odm, Idx); + + halTxbf8192E_FwTxBFCmd(pDM_Odm); +} + +#endif /* #if (RTL8192E_SUPPORT == 1)*/ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.h new file mode 100644 index 00000000..406c2d6e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8192e.h @@ -0,0 +1,52 @@ +#ifndef __HAL_TXBF_8192E_H__ +#define __HAL_TXBF_8192E_H__ + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8192E_SUPPORT == 1) +VOID +HalTxbf8192E_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +); + +VOID +HalTxbf8192E_Enter( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8192E_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8192E_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8192E_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); +#else + +#define HalTxbf8192E_setNDPArate(pDM_VOID, BW, Rate) +#define HalTxbf8192E_Enter(pDM_VOID, Idx) +#define HalTxbf8192E_Leave(pDM_VOID, Idx) +#define HalTxbf8192E_Status(pDM_VOID, Idx) +#define HalTxbf8192E_FwTxBF(pDM_VOID, Idx) + +#endif + +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.c new file mode 100644 index 00000000..d7e25451 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.c @@ -0,0 +1,653 @@ +//============================================================ +// Description: +// +// This file is for 8814A TXBF mechanism +// +//============================================================ + +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8814A_SUPPORT == 1) + +VOID +HalTxbf8814A_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8814A, BW); + ODM_Write1Byte(pDM_Odm, REG_NDPA_RATE_8814A, (u1Byte) Rate); + +} + +#define PHYDM_MEMORY_MAP_BUF_READ 0x8000 +#define PHYDM_CTRL_INFO_PAGE 0x660 + +VOID +phydm_DataRate_8814A( + IN PDM_ODM_T pDM_Odm, + IN u1Byte macId, + OUT pu4Byte data, + IN u1Byte dataLen + ) +{ + u1Byte i = 0; + u2Byte XReadDataAddr = 0; + + ODM_Write2Byte(pDM_Odm, REG_PKTBUF_DBG_CTRL_8814A, PHYDM_CTRL_INFO_PAGE); + XReadDataAddr = PHYDM_MEMORY_MAP_BUF_READ + macId*32; /*Ctrl Info: 32Bytes for each macid(n)*/ + + if ((XReadDataAddr < PHYDM_MEMORY_MAP_BUF_READ) || (XReadDataAddr > 0x8FFF)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("XReadDataAddr(0x%x) is not correct!\n", XReadDataAddr)); + return; + } + + /* Read data */ + for (i = 0; i < dataLen; i++) + *(data+i) = ODM_Read2Byte(pDM_Odm, XReadDataAddr+i); + +} + +VOID +HalTxbf8814A_GetTxRate( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pEntry; + u4Byte TxRptData = 0; + u1Byte DataRate = 0xFF; + + pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + + phydm_DataRate_8814A(pDM_Odm, (u1Byte)pEntry->MacId, &TxRptData, 1); + DataRate = (u1Byte)TxRptData; + DataRate &= bMask7bits; /*Bit7 indicates SGI*/ + + pDM_Odm->TxBfDataRate = DataRate; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] pDM_Odm->TxBfDataRate = 0x%x\n", __func__, pDM_Odm->TxBfDataRate)); +} + +VOID +HalTxbf8814A_ResetTxPath( + IN PVOID pDM_VOID, + IN u1Byte idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; +#if DEV_BUS_TYPE == RT_USB_INTERFACE + + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + u1Byte Nr_index = 0; + + if (idx < BEAMFORMEE_ENTRY_NUM) + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx]; + else + return; + + if ((pDM_Odm->LastUSBHub) != (*pDM_Odm->HubUsbMode)) { + Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), BeamformeeEntry.CompSteeringNumofBFer); + + if (idx == 0) { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366); /*tx2path, BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x936); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x9360); + break; + + case 2: /*Nsts = 3 BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee); /*tx3path, BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93e); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93e93e0); + break; + + default: /*Nr>3, same as Case 3*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff); /*tx4path, ABCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93f); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskDWord, 0x93f93f0); + break; + } + } else { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366); /*tx2path, BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x936); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x9360); + break; + + case 2: /*Nsts = 3 BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee); /*tx3path, BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93e); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93e93e0); + break; + + default: /*Nr>3, same as Case 3*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff); /*tx4path, ABCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93f); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93f93f0); + break; + } + } + + pDM_Odm->LastUSBHub = *pDM_Odm->HubUsbMode; + } else + return; +#endif +} + + +u1Byte +halTxbf8814A_GetNtx( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Ntx = 0; + +#if DEV_BUS_TYPE == RT_USB_INTERFACE + if (pDM_Odm->SupportInterface == ODM_ITRF_USB) { + if (*pDM_Odm->HubUsbMode == 2) {/*USB3.0*/ + if (pDM_Odm->RFType == ODM_4T4R) + Ntx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Ntx = 2; + else + Ntx = 1; + } else if (*pDM_Odm->HubUsbMode == 1) /*USB 2.0 always 2Tx*/ + Ntx = 1; + else + Ntx = 1; + } else +#endif + { + if (pDM_Odm->RFType == ODM_4T4R) + Ntx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Ntx = 2; + else + Ntx = 1; + } + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Ntx = %d\n", __func__, Ntx)); + return Ntx; +} + +u1Byte +halTxbf8814A_GetNrx( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Nrx = 0; + + if (pDM_Odm->RFType == ODM_4T4R) + Nrx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Nrx = 2; + else if (pDM_Odm->RFType == ODM_2T2R) + Nrx = 1; + else if (pDM_Odm->RFType == ODM_2T3R) + Nrx = 2; + else if (pDM_Odm->RFType == ODM_2T4R) + Nrx = 3; + else if (pDM_Odm->RFType == ODM_1T1R) + Nrx = 0; + else if (pDM_Odm->RFType == ODM_1T2R) + Nrx = 1; + else + Nrx = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Nrx = %d\n", __func__, Nrx)); + return Nrx; +} + +VOID +halTxbf8814A_RfMode( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamformingInfo, + IN u1Byte idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i, Nr_index = 0; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + + if (idx < BEAMFORMEE_ENTRY_NUM) + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx]; + else + return; + + Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), BeamformeeEntry.CompSteeringNumofBFer); + + if (pDM_Odm->RFType == ODM_1T1R) + return; + + for (i = ODM_RF_PATH_A; i < MAX_RF_PATH; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_WeLut_Jaguar, 0x80000, 0x1); + /*RF Mode table write enable*/ + } + + if (pBeamformingInfo->beamformee_su_cnt > 0) { + for (i = ODM_RF_PATH_A; i < MAX_RF_PATH; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableAddr, 0xfffff, 0x18000); + /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableData0, 0xfffff, 0xBE77F); + /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableData1, 0xfffff, 0x226BF); + /*Enable TXIQGEN in RX mode*/ + } + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF); + /*Enable TXIQGEN in RX mode*/ + } + + for (i = ODM_RF_PATH_A; i < MAX_RF_PATH; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_WeLut_Jaguar, 0x80000, 0x0); + /*RF Mode table write disable*/ + } + + if (pBeamformingInfo->beamformee_su_cnt > 0) { +#if DEV_BUS_TYPE == RT_USB_INTERFACE + pDM_Odm->LastUSBHub = *pDM_Odm->HubUsbMode; +#endif + + /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, BIT28 | BIT29, 0x2); /*enable BB TxBF ant mapping register*/ + + if (idx == 0) { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366); /*tx2path, BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x936); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x9360); + break; + + case 2: /*Nsts = 3 BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee); /*tx3path, BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93e); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93e93e0); + break; + + default: /*Nr>3, same as Case 3*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff); /*tx4path, ABCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93f); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskDWord, 0x93f93f0); + break; + } + } else { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366); /*tx2path, BC*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x936); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x9360); + break; + + case 2: /*Nsts = 3 BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee); /*tx3path, BCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93e); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93e93e0); + break; + + default: /*Nr>3, same as Case 3*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff); /*tx4path, ABCD*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x93f); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93f93f0); + break; + } + } + } + + if ((pBeamformingInfo->beamformee_su_cnt == 0) && (pBeamformingInfo->beamformer_su_cnt == 0)) { + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, bMaskByte3 | bMaskByte2HighNibble, 0x932); /*set TxPath selection for 8814a BFer bug refine*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93e9360); + } +} +#if 0 +VOID +halTxbf8814A_DownloadNDPA( + IN PADAPTER Adapter, + IN u1Byte Idx +) +{ + u1Byte u1bTmp = 0, tmpReg422 = 0; + u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; + u2Byte Head_Page = 0x7FE; + BOOLEAN bSendBeacon = FALSE; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u2Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/ + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + pHalData->bFwDwRsvdPageInProgress = TRUE; + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu2Byte)&TxPageBndy); + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A + 1); + PlatformEFIOWrite1Byte(Adapter, REG_CR_8814A + 1, (u1bTmp | BIT0)); + + + /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ + tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2); + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422 & (~BIT6)); + + if (tmpReg422 & BIT6) { + RT_TRACE(COMP_INIT, DBG_LOUD, ("SetBeamformDownloadNDPA_8814A(): There is an Adapter is sending beacon.\n")); + bSendBeacon = TRUE; + } + + /*0x204[11:0] Beacon Head for TXDMA*/ + PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, Head_Page); + + do { + /*Clear beacon valid check bit.*/ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1); + PlatformEFIOWrite1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1, (BcnValidReg | BIT7)); + + /*download NDPA rsvd page.*/ + if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE); + else + Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); + + /*check rsvd page download OK.*/ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1); + count = 0; + while (!(BcnValidReg & BIT7) && count < 20) { + count++; + delay_us(10); + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 2); + } + DLBcnCount++; + } while (!(BcnValidReg & BIT7) && DLBcnCount < 5); + + if (!(BcnValidReg & BIT0)) + RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__)); + + /*0x204[11:0] Beacon Head for TXDMA*/ + PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, TxPageBndy); + + /*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 (bSendBeacon) + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422); + + /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ + /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A + 1); + PlatformEFIOWrite1Byte(Adapter, REG_CR_8814A + 1, (u1bTmp & (~BIT0))); + + pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; + + pHalData->bFwDwRsvdPageInProgress = FALSE; +} + +VOID +halTxbf8814A_FwTxBFCmd( + IN PADAPTER Adapter +) +{ + u1Byte Idx, Period = 0; + u1Byte PageNum0 = 0xFF, PageNum1 = 0xFF; + u1Byte u1TxBFParm[3] = {0}; + + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) { + PageNum0 = 0xFE; + PageNum1 = 0x07; + Period = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } else if (PageNum0 == 0xFF) { + PageNum0 = 0xFF; /*stop sounding*/ + PageNum1 = 0x0F; + } + } + } + + u1TxBFParm[0] = PageNum0; + u1TxBFParm[1] = PageNum1; + u1TxBFParm[2] = Period; + FillH2CCmd(Adapter, PHYDM_H2C_TXBF, 3, u1TxBFParm); + + RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x Period = %d", __func__, PageNum0, PageNum1, Period)); +} +#endif +VOID +HalTxbf8814A_Enter( + IN PVOID pDM_VOID, + IN u1Byte BFerBFeeIdx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; + u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + RT_BEAMFORMER_ENTRY BeamformerEntry; + u2Byte STAid = 0, CSI_Param = 0; + u1Byte Nc_index = 0, Nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BFerIdx=%d, BFeeIdx=%d\n", __func__, BFerIdx, BFeeIdx)); + ODM_SetMACReg(pDM_Odm, REG_SND_PTCL_CTRL_8814A, bMaskByte1 | bMaskByte2, 0x0202); + + if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xDB); + + /*MAC address/Partial AID of Beamformer*/ + if (BFerIdx == 0) { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8814A + i), BeamformerEntry.MacAddr[i]); + } else { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8814A + i), BeamformerEntry.MacAddr[i]); + } + + /*CSI report parameters of Beamformer*/ + Nc_index = halTxbf8814A_GetNrx(pDM_Odm); /*for 8814A Nrx = 3(4 Ant), min=0(1 Ant)*/ + Nr_index = BeamformerEntry.NumofSoundingDim; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/ + + grouping = 0; + + /*for ac = 1, for n = 3*/ + if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) + codebookinfo = 1; + else if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_HT_EXPLICIT) + codebookinfo = 3; + + coefficientsize = 3; + + CSI_Param = (u2Byte)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (Nr_index << 3) | (Nc_index)); + + if (BFerIdx == 0) + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, CSI_Param); + else + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, CSI_Param); + /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A + 3, 0x40); + + } + + if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + + halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx); + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + STAid = BeamformeeEntry.MacId; + else + STAid = BeamformeeEntry.P_AID; + + /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ + if (BFeeIdx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, STAid); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7); + } else + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, STAid | BIT14 | BIT15 | BIT12); + + /*CSI report parameters of Beamformee*/ + if (BFeeIdx == 0) { + /*Get BIT24 & BIT25*/ + u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3) & 0x3; + + ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3, tmp | 0x60); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, STAid | BIT9); + } else + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, STAid | 0xE200); /*Set BIT25*/ + + phydm_Beamforming_Notify(pDM_Odm); + } + +} + + +VOID +HalTxbf8814A_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMER_ENTRY BeamformerEntry; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + + if (Idx < BEAMFORMER_ENTRY_NUM) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx]; + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx]; + } else + return; + + /*Clear P_AID of Beamformee*/ + /*Clear MAC address of Beamformer*/ + /*Clear Associated Bfmee Sel*/ + + if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xD8); + if (Idx == 0) { + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, 0); + } else { + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, 0); + } + } + + if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, Idx); + if (Idx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, 0x0); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, 0); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, 0x0 | BIT14 | BIT15 | BIT12); + + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2) & 0x60); + } + } +} + +VOID +HalTxbf8814A_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte BeamCtrlVal, tmpVal; + u4Byte BeamCtrlReg; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformEntry; + + if (Idx < BEAMFORMEE_ENTRY_NUM) + BeamformEntry = pBeamformingInfo->BeamformeeEntry[Idx]; + else + return; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + BeamCtrlVal = BeamformEntry.MacId; + else + BeamCtrlVal = BeamformEntry.P_AID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BeamformEntry.BeamformEntryState = %d", __func__, BeamformEntry.BeamformEntryState)); + + if (Idx == 0) + BeamCtrlReg = REG_TXBF_CTRL_8814A; + else { + BeamCtrlReg = REG_TXBF_CTRL_8814A + 2; + BeamCtrlVal |= BIT12 | BIT14 | BIT15; + } + + if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) + BeamCtrlVal |= BIT9; + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) + BeamCtrlVal |= (BIT9 | BIT10); + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80) + BeamCtrlVal |= (BIT9 | BIT10 | BIT11); + } else { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix", __func__)); + BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); + } + + ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); + /*disable NDP packet use beamforming */ + tmpVal = ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8814A); + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, tmpVal | BIT15); + +} + + + + + +VOID +HalTxbf8814A_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ +#if 0 + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + halTxbf8814A_DownloadNDPA(Adapter, Idx); + + halTxbf8814A_FwTxBFCmd(Adapter); +#endif +} + +#endif /* (RTL8814A_SUPPORT == 1)*/ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.h new file mode 100644 index 00000000..7efdc025 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8814a.h @@ -0,0 +1,70 @@ +#ifndef __HAL_TXBF_8814A_H__ +#define __HAL_TXBF_8814A_H__ + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8814A_SUPPORT == 1) +VOID +HalTxbf8814A_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +); + +u1Byte +halTxbf8814A_GetNtx( + IN PVOID pDM_VOID + ); + +VOID +HalTxbf8814A_Enter( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8814A_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8814A_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + +VOID +HalTxbf8814A_ResetTxPath( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8814A_GetTxRate( + IN PVOID pDM_VOID + ); + +VOID +HalTxbf8814A_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); +#else + +#define HalTxbf8814A_setNDPArate(pDM_VOID, BW, Rate) +#define halTxbf8814A_GetNtx(pDM_VOID) 0 +#define HalTxbf8814A_Enter(pDM_VOID, Idx) +#define HalTxbf8814A_Leave(pDM_VOID, Idx) +#define HalTxbf8814A_Status(pDM_VOID, Idx) +#define HalTxbf8814A_ResetTxPath(pDM_VOID, Idx) +#define HalTxbf8814A_GetTxRate(pDM_VOID) +#define HalTxbf8814A_FwTxBF(pDM_VOID, Idx) +#endif + +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.c new file mode 100644 index 00000000..eff8e984 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.c @@ -0,0 +1,400 @@ +/*============================================================*/ +/*Description:*/ +/*This file is for 8812/8821/8811 TXBF mechanism*/ +/*============================================================*/ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8821B_SUPPORT == 1) + +VOID +halTxbf8821B_RfMode( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamInfo +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->RFType == ODM_1T1R) + return; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] set TxIQGen\n", __func__)); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x1); /*RF Mode table write enable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x1); /*RF Mode table write enable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) { + /*Path_A*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/ + /*Path_B*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/ + } else { + /*Path_A*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/ + /*Path_B*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/ + } + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x0); /*RF Mode table write disable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x0); /*RF Mode table write disable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) + ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x33); + else + ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x11); +} + +#if 0 +VOID +halTxbf8821B_DownloadNDPA( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Idx +) +{ + u1Byte u1bTmp = 0, tmpReg422 = 0, Head_Page; + u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; + BOOLEAN bSendBeacon = FALSE; + u1Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812; /*default reseved 1 page for the IC type which is undefined.*/ + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pDM_Odm->Adapter); + PADAPTER Adapter = pDM_Odm->Adapter; + + pHalData->bFwDwRsvdPageInProgress = TRUE; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (Idx == 0) + Head_Page = 0xFE; + else + Head_Page = 0xFE; + + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu1Byte)&TxPageBndy); + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8821B + 1); + ODM_Write1Byte(pDM_Odm, REG_CR_8821B + 1, (u1bTmp | BIT0)); + + + /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ + tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8821B + 2); + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8821B + 2, tmpReg422 & (~BIT6)); + + if (tmpReg422 & BIT6) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("SetBeamformDownloadNDPA_8812(): There is an Adapter is sending beacon.\n")); + bSendBeacon = TRUE; + } + + /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, Head_Page); + + do { + /*Clear beacon valid check bit.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 2, (BcnValidReg | BIT0)); + + /*download NDPA rsvd page.*/ + if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE); + else + Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); + + /*check rsvd page download OK.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + count = 0; + while (!(BcnValidReg & BIT0) && count < 20) { + count++; + ODM_delay_ms(10); + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + } + DLBcnCount++; + } while (!(BcnValidReg & BIT0) && DLBcnCount < 5); + + if (!(BcnValidReg & BIT0)) + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__)); + + /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, TxPageBndy); + + /*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 (bSendBeacon) + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8821B + 2, tmpReg422); + + /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ + /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8821B + 1); + ODM_Write1Byte(pDM_Odm, REG_CR_8821B + 1, (u1bTmp & (~BIT0))); + + pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; + + pHalData->bFwDwRsvdPageInProgress = FALSE; +} + + +VOID +halTxbf8821B_FwTxBFCmd( + IN PDM_ODM_T pDM_Odm +) +{ + u1Byte Idx, Period0 = 0, Period1 = 0; + u1Byte PageNum0 = 0xFF, PageNum1 = 0xFF; + u1Byte u1TxBFParm[3] = {0}; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + /*Modified by David*/ + if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (Idx == 0) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum0 = 0xFE; + else + PageNum0 = 0xFF; /*stop sounding*/ + Period0 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } else if (Idx == 1) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum1 = 0xFE; + else + PageNum1 = 0xFF; /*stop sounding*/ + Period1 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } + } + } + + u1TxBFParm[0] = PageNum0; + u1TxBFParm[1] = PageNum1; + u1TxBFParm[2] = (Period1 << 4) | Period0; + FillH2CCmd(Adapter, PHYDM_H2C_TXBF, 3, u1TxBFParm); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, + ("[%s] PageNum0 = %d Period0 = %d, PageNum1 = %d Period1 %d\n", __func__, PageNum0, Period0, PageNum1, Period1)); +} + +#endif +VOID +HalTxbf8821B_Enter( + IN PVOID pDM_VOID, + IN u1Byte BFerBFeeIdx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; + u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); + u4Byte CSI_Param; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + RT_BEAMFORMER_ENTRY BeamformerEntry; + u2Byte STAid = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__)); + + halTxbf8821B_RfMode(pDM_Odm, pBeamformingInfo); + + if (pDM_Odm->RFType == ODM_2T2R) + ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x00000000); /*Nc =2*/ + else + ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x01081008); /*Nc =1*/ + + if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; + + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B, 0xCB); + + /*MAC address/Partial AID of Beamformer*/ + if (BFerIdx == 0) { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_BFMER0_INFO_8812A + i), BeamformerEntry.MacAddr[i]); + /*CSI report use legacy ofdm so don't need to fill P_AID. */ + /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER0_INFO_8821B+6, BeamformEntry.P_AID); */ + } else { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_BFMER1_INFO_8812A + i), BeamformerEntry.MacAddr[i]); + /*CSI report use legacy ofdm so don't need to fill P_AID.*/ + /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER1_INFO_8821B+6, BeamformEntry.P_AID);*/ + } + + /*CSI report parameters of Beamformee*/ + if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) { + if (pDM_Odm->RFType == ODM_2T2R) + CSI_Param = 0x01090109; + else + CSI_Param = 0x01080108; + } else { + if (pDM_Odm->RFType == ODM_2T2R) + CSI_Param = 0x03090309; + else + CSI_Param = 0x03080308; + } + + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, CSI_Param); + + /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B + 3, 0x50); + } + + + if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + STAid = BeamformeeEntry.MacId; + else + STAid = BeamformeeEntry.P_AID; + + /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ + if (BFeeIdx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B, STAid); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 3) | BIT4 | BIT6 | BIT7); + } else + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2, STAid | BIT12 | BIT14 | BIT15); + + /*CSI report parameters of Beamformee*/ + if (BFeeIdx == 0) { + /*Get BIT24 & BIT25*/ + u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3) & 0x3; + + ODM_Write1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, STAid | BIT9); + } else { + /*Set BIT25*/ + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, STAid | 0xE200); + } + phydm_Beamforming_Notify(pDM_Odm); + } +} + + +VOID +HalTxbf8821B_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMER_ENTRY BeamformerEntry; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + + if (Idx < BEAMFORMER_ENTRY_NUM) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx]; + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx]; + } else + return; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, Idx)); + + /*Clear P_AID of Beamformee*/ + /*Clear MAC address of Beamformer*/ + /*Clear Associated Bfmee Sel*/ + + if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B, 0xC8); + if (Idx == 0) { + ODM_Write4Byte(pDM_Odm, REG_BFMER0_INFO_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_BFMER0_INFO_8812A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, 0); + } else { + ODM_Write4Byte(pDM_Odm, REG_BFMER1_INFO_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_BFMER1_INFO_8812A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, 0); + } + } + + if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + halTxbf8821B_RfMode(pDM_Odm, pBeamformingInfo); + if (Idx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B, 0x0); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, 0); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2, ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2) & 0xF000); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2) & 0x60); + } + } + +} + + +VOID +HalTxbf8821B_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte BeamCtrlVal; + u4Byte BeamCtrlReg; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformEntry = pBeamInfo->BeamformeeEntry[Idx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + BeamCtrlVal = BeamformEntry.MacId; + else + BeamCtrlVal = BeamformEntry.P_AID; + + if (Idx == 0) + BeamCtrlReg = REG_TXBF_CTRL_8821B; + else { + BeamCtrlReg = REG_TXBF_CTRL_8821B + 2; + BeamCtrlVal |= BIT12 | BIT14 | BIT15; + } + + if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) + BeamCtrlVal |= BIT9; + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) + BeamCtrlVal |= BIT10; + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80) + BeamCtrlVal |= BIT11; + } else + BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BeamCtrlVal = 0x%x!\n", __func__, BeamCtrlVal)); + + ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); +} + + + +VOID +HalTxbf8821B_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); +#if 0 + if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + halTxbf8821B_DownloadNDPA(pDM_Odm, Idx); + + halTxbf8821B_FwTxBFCmd(pDM_Odm); +#endif +} + +#endif + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.h new file mode 100644 index 00000000..c92d79a3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8821b.h @@ -0,0 +1,43 @@ +#ifndef __HAL_TXBF_8821B_H__ +#define __HAL_TXBF_8821B_H__ +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8821B_SUPPORT == 1) +VOID +HalTxbf8821B_Enter( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8821B_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8821B_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8821B_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + +#else +#define HalTxbf8821B_Enter(pDM_VOID, Idx) +#define HalTxbf8821B_Leave(pDM_VOID, Idx) +#define HalTxbf8821B_Status(pDM_VOID, Idx) +#define HalTxbf8821B_FwTxBF(pDM_VOID, Idx) +#endif + + +#endif + +#endif // #ifndef __HAL_TXBF_8821B_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.c new file mode 100644 index 00000000..caa18a9c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.c @@ -0,0 +1,1099 @@ +/*============================================================*/ +/* Description: */ +/* */ +/* This file is for 8814A TXBF mechanism */ +/* */ +/*============================================================*/ + +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8822B_SUPPORT == 1) + +#if 0 +VOID +HalTxbf8814A_GetBeamformcap( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PRT_BEAMFORMING_INFO pBeamformingInfo = GET_BEAMFORM_INFO(Adapter); + BEAMFORMING_CAP BeamformCap = BEAMFORMING_CAP_NONE; + + BeamformCap = phydm_Beamforming_GetBeamCap(pDM_Odm, pBeamformingInfo); + + if (BeamformCap == pBeamformingInfo->BeamformCap) + return; + else + pBeamformingInfo->BeamformCap = BeamformCap; + +} + +VOID +HalTxbf8814A_GetTxRate( + IN PADAPTER Adapter +) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + PRT_BEAMFORMEE_ENTRY pEntry; + u4Byte TxRptData = 0; + u1Byte DataRate = 0xFF; + + pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]); + + ReadSdramData_8814A(Adapter, (u1Byte)pEntry->MacId, LOC_8814A_CTRL_INFO, &TxRptData, 1); + DataRate = (u1Byte)TxRptData; + DataRate &= bMask7bits; /*Bit7 indicates SGI*/ + + pDM_Odm->TxBfDataRate = DataRate; + +} + +VOID +HalTxbf8814A_ResetTxPath( + IN PADAPTER Adapter, + IN u1Byte idx +) +{ +#if DEV_BUS_TYPE == RT_USB_INTERFACE + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PRT_BEAMFORMING_INFO pBeamformingInfo = GET_BEAMFORM_INFO(Adapter); + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + u1Byte Nr_index = 0; + + if (idx < BEAMFORMEE_ENTRY_NUM) + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx]; + else + return; + + if ((pDM_Odm->LastUSBHub) != (RT_GetHubUSBMode(Adapter))) { + Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(Adapter), BeamformeeEntry.CompSteeringNumofBFer); + + if (idx == 0) { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT3|BIT2|BIT1|BIT0, 0x6); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT7|BIT6|BIT5|BIT4, 0x6); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, 0x0000ff00, 0x10); /*BC*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0x6); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x10); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x1060); + break; + + case 2: /*Nsts = 3 BCD*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT3|BIT2|BIT1|BIT0, 0xe); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT7|BIT6|BIT5|BIT4, 0xe); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, 0x0000ff00, 0x90); /*BCD*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT19|BIT18|BIT17|BIT16, 0xe); /*3ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, 0xff00000, 0x90); /*bcd*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0xe); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x90); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x90e90e0); + break; + + default: /*Nr>3, same as Case 3*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT3|BIT2|BIT1|BIT0, 0xf); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT7|BIT6|BIT5|BIT4, 0xf); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, 0x0000ff00, 0x93); /*BC*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, BIT19|BIT18|BIT17|BIT16, 0xf); /*3ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF0, 0xff00000, 0x93); /*bcd*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0xf); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x93); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93f93f0); + break; + } + } else { + switch (Nr_index) { + case 0: + break; + + case 1: /*Nsts = 2 BC*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT3|BIT2|BIT1|BIT0, 0x6); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT7|BIT6|BIT5|BIT4, 0x6); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, 0x0000ff00, 0x10); /*BC*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0x6); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x10); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x1060); + break; + + case 2: /*Nsts = 3 BCD*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT3|BIT2|BIT1|BIT0, 0xe); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT7|BIT6|BIT5|BIT4, 0xe); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, 0x0000ff00, 0x90); /*BC*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT19|BIT18|BIT17|BIT16, 0xe); /*3ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, 0xff00000, 0x90); /*bcd*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0xe); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x90); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x90e90e0); + break; + + default: /*Nr>3, same as Case 3*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT3|BIT2|BIT1|BIT0, 0xf); /*1ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT7|BIT6|BIT5|BIT4, 0xf); /*2ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, 0x0000ff00, 0x93); /*BC*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, BIT19|BIT18|BIT17|BIT16, 0xf); /*3ss*/ + PHY_SetBBReg(Adapter, REG_BB_TXBF_ANT_SET_BF1, 0xff00000, 0x93); /*bcd*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, BIT23|BIT22|BIT21|BIT20, 0xf); /*set TxPath selection for 8814a BFer bug refine*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_1, bMaskByte3, 0x93); /*if Bfer enable, always use 3Tx for all Spatial stream*/ + PHY_SetBBReg(Adapter, REG_BB_TX_PATH_SEL_2, bMaskDWord, 0x93f93f0); + break; + + } + } + + pDM_Odm->LastUSBHub = RT_GetHubUSBMode(Adapter); + } + else + return; +#endif +} +#endif + +u1Byte +halTxbf8822B_GetNtx( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Ntx = 0; + +#if DEV_BUS_TYPE == RT_USB_INTERFACE + if (pDM_Odm->SupportInterface == ODM_ITRF_USB) { + if (*pDM_Odm->HubUsbMode == 2) {/*USB3.0*/ + if (pDM_Odm->RFType == ODM_4T4R) + Ntx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Ntx = 2; + else + Ntx = 1; + } else if (*pDM_Odm->HubUsbMode == 1) /*USB 2.0 always 2Tx*/ + Ntx = 1; + else + Ntx = 1; + } else +#endif + { + if (pDM_Odm->RFType == ODM_4T4R) + Ntx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Ntx = 2; + else + Ntx = 1; + } + + return Ntx; + +} + +u1Byte +halTxbf8822B_GetNrx( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Nrx = 0; + + if (pDM_Odm->RFType == ODM_4T4R) + Nrx = 3; + else if (pDM_Odm->RFType == ODM_3T3R) + Nrx = 2; + else if (pDM_Odm->RFType == ODM_2T2R) + Nrx = 1; + else if (pDM_Odm->RFType == ODM_2T3R) + Nrx = 2; + else if (pDM_Odm->RFType == ODM_2T4R) + Nrx = 3; + else if (pDM_Odm->RFType == ODM_1T1R) + Nrx = 0; + else if (pDM_Odm->RFType == ODM_1T2R) + Nrx = 1; + else + Nrx = 0; + + return Nrx; + +} + +/***************SU & MU BFee Entry********************/ +VOID +halTxbf8822B_RfMode( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamformingInfo, + IN u1Byte idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i, Nr_index = 0; + BOOLEAN bSelfBeamformer = FALSE; + BOOLEAN bSelfBeamformee = FALSE; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + + if (idx < BEAMFORMEE_ENTRY_NUM) + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx]; + else + return; + + if (pDM_Odm->RFType == ODM_1T1R) + return; + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_WeLut_Jaguar, 0x80000, 0x1); + /*RF Mode table write enable*/ + } + + if ((pBeamformingInfo->beamformee_su_cnt > 0) || (pBeamformingInfo->beamformee_mu_cnt > 0)) { + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableAddr, 0xfffff, 0x18000); + /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableData0, 0xfffff, 0xBE77F); + /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, i, RF_ModeTableData1, 0xfffff, 0x226BF); + /*Enable TXIQGEN in RX mode*/ + } + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF); + /*Enable TXIQGEN in RX mode*/ + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) { + ODM_SetRFReg(pDM_Odm, i, RF_WeLut_Jaguar, 0x80000, 0x0); + /*RF Mode table write disable*/ + } + + if (pBeamformingInfo->beamformee_su_cnt > 0) { + + /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, BIT28|BIT29, 0x2); /*enable BB TxBF ant mapping register*/ + + if (idx == 0) { + /*Nsts = 2 AB*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0, 0xffff, 0x0433); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, 0xfff00000, 0x043); + /*ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x430);*/ + + } else {/*IDX =1*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, 0xffff, 0x0433); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, 0xfff00000, 0x043); + /*ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x430;*/ + } + } else { + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, 0xfff00000, 0x1); /*1SS by path-A*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x430); /*2SS by path-A,B*/ + } + + if (pBeamformingInfo->beamformee_mu_cnt > 0) { + /*MU STAs share the common setting*/ + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, BIT31, 1); + ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1, 0xffff, 0x0433); + ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1, 0xfff00000, 0x043); + } + +} +#if 0 +VOID +halTxbf8822B_DownloadNDPA( + IN PADAPTER Adapter, + IN u1Byte Idx + ) +{ + u1Byte u1bTmp = 0, tmpReg422 = 0; + u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; + u2Byte Head_Page = 0x7FE; + BOOLEAN bSendBeacon = FALSE; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u2Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/ + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry+Idx; + + pHalData->bFwDwRsvdPageInProgress = TRUE; + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu2Byte)&TxPageBndy); + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A+1); + PlatformEFIOWrite1Byte(Adapter, REG_CR_8814A+1, (u1bTmp|BIT0)); + + + /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ + tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2); + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2, tmpReg422&(~BIT6)); + + if (tmpReg422 & BIT6) { + RT_TRACE(COMP_INIT, DBG_LOUD, ("SetBeamformDownloadNDPA_8814A(): There is an Adapter is sending beacon.\n")); + bSendBeacon = TRUE; + } + + /*0x204[11:0] Beacon Head for TXDMA*/ + PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, Head_Page); + + do { + /*Clear beacon valid check bit.*/ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+1); + PlatformEFIOWrite1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+1, (BcnValidReg|BIT7)); + + /*download NDPA rsvd page.*/ + if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE); + else + Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); + + /*check rsvd page download OK.*/ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1); + count = 0; + while (!(BcnValidReg & BIT7) && count < 20) { + count++; + delay_us(10); + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+2); + } + DLBcnCount++; + } while (!(BcnValidReg & BIT7) && DLBcnCount < 5); + + if (!(BcnValidReg & BIT0)) + RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__)); + + /*0x204[11:0] Beacon Head for TXDMA*/ + PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, TxPageBndy); + + /*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 (bSendBeacon) + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2, tmpReg422); + + /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ + /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A+1); + PlatformEFIOWrite1Byte(Adapter, REG_CR_8814A+1, (u1bTmp&(~BIT0))); + + pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; + + pHalData->bFwDwRsvdPageInProgress = FALSE; +} + +VOID +halTxbf8822B_FwTxBFCmd( + IN PADAPTER Adapter + ) +{ + u1Byte Idx, Period = 0; + u1Byte PageNum0 = 0xFF, PageNum1 = 0xFF; + u1Byte u1TxBFParm[3] = {0}; + + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) { + PageNum0 = 0xFE; + PageNum1 = 0x07; + Period = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } else if (PageNum0 == 0xFF) { + PageNum0 = 0xFF; /*stop sounding*/ + PageNum1 = 0x0F; + } + } + } + + u1TxBFParm[0] = PageNum0; + u1TxBFParm[1] = PageNum1; + u1TxBFParm[2] = Period; + FillH2CCmd(Adapter, PHYDM_H2C_TXBF, 3, u1TxBFParm); + + RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x Period = %d", __func__, PageNum0, PageNum1, Period)); +} +#endif + +VOID +HalTxbf8822B_Init( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte u1bTmp; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + + ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT16, 1); /*Enable P1 aggr new packet according to P0 transfer time*/ + ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT15|BIT14|BIT13|BIT12, 1); /*MU Retry Limit*/ + ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT7, 0); /*Disable Tx MU-MIMO until sounding done*/ + ODM_SetBBReg(pDM_Odm, 0x14c0 , 0x3F, 0); /* Clear validity of MU STAs */ + ODM_Write1Byte(pDM_Odm, 0x167c , 0x70); /*MU-MIMO Option as default value*/ + ODM_Write2Byte(pDM_Odm, 0x1680 , 0); /*MU-MIMO Control as default value*/ + + /* Set MU NDPA rate & BW source */ + /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */ + u1bTmp = ODM_Read1Byte(pDM_Odm, 0x42C); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B, (u1bTmp|BIT6)); + /* 0x45F[7:0] = 0x10 (Rate=OFDM_6M, BW20) */ + ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B, 0x10); + + /* Init HW variable */ + pBeamformingInfo->RegMUTxCtrl = ODM_Read4Byte(pDM_Odm, 0x14c0); +} + +VOID +HalTxbf8822B_Enter( + IN PVOID pDM_VOID, + IN u1Byte BFerBFeeIdx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + u1Byte BFerIdx = (BFerBFeeIdx & 0xF0)>>4; + u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); + u2Byte CSI_Param = 0; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamformeeEntry; + PRT_BEAMFORMER_ENTRY pBeamformerEntry; + u2Byte value16, STAid = 0; + u1Byte Nc_index = 0, Nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0; + u4Byte gid_valid, user_position_l, user_position_h; + u4Byte mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e}; + u1Byte u1bTmp; + u4Byte u4bTmp; + + RT_DISP(FBEAM, FBEAM_FUN, ("%s: BFerBFeeIdx=%d, BFerIdx=%d, BFeeIdx=%d\n", __func__, BFerBFeeIdx, BFerIdx, BFeeIdx)); + + /*************SU BFer Entry Init*************/ + if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[BFerIdx]; + pBeamformerEntry->is_mu_ap = FALSE; + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); + + + for (i = 0; i < MAX_BEAMFORMER_SU; i++) { + if ((pBeamformingInfo->beamformer_su_reg_maping & BIT(i)) == 0) { + pBeamformingInfo->beamformer_su_reg_maping |= BIT(i); + pBeamformerEntry->su_reg_index = i; + break; + } + } + + /*MAC address/Partial AID of Beamformer*/ + if (pBeamformerEntry->su_reg_index == 0) { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+i), pBeamformerEntry->MacAddr[i]); + } else { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8822B+i), pBeamformerEntry->MacAddr[i]); + } + + /*CSI report parameters of Beamformer*/ + Nc_index = halTxbf8822B_GetNrx(pDM_Odm); /*for 8814A Nrx = 3(4 Ant), min=0(1 Ant)*/ + Nr_index = pBeamformerEntry->NumofSoundingDim; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/ + + grouping = 0; + + /*for ac = 1, for n = 3*/ + if (pBeamformerEntry->BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) + codebookinfo = 1; + else if (pBeamformerEntry->BeamformEntryCap & BEAMFORMEE_CAP_HT_EXPLICIT) + codebookinfo = 3; + + coefficientsize = 3; + + CSI_Param = (u2Byte)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(Nr_index<<3)|(Nc_index)); + + if (BFerIdx == 0) + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8822B, CSI_Param); + else + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8822B+2, CSI_Param); + /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A+3, 0x70); + + } + + /*************SU BFee Entry Init*************/ + if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + pBeamformeeEntry->is_mu_sta = FALSE; + halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx); + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + STAid = pBeamformeeEntry->MacId; + else + STAid = pBeamformeeEntry->P_AID; + + for (i = 0; i < MAX_BEAMFORMEE_SU; i++) { + if ((pBeamformingInfo->beamformee_su_reg_maping & BIT(i)) == 0) { + pBeamformingInfo->beamformee_su_reg_maping |= BIT(i); + pBeamformeeEntry->su_reg_index = i; + break; + } + } + + /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ + if (pBeamformeeEntry->su_reg_index == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, STAid); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3)|BIT4|BIT6|BIT7); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B+2, STAid | BIT14 | BIT15 | BIT12); + } + + /*CSI report parameters of Beamformee*/ + if (pBeamformeeEntry->su_reg_index == 0) { + /*Get BIT24 & BIT25*/ + u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+3) & 0x3; + + ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3, tmp | 0x60); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B, STAid | BIT9); + } else + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2, STAid | 0xE200); /*Set BIT25*/ + + phydm_Beamforming_Notify(pDM_Odm); + } + + /*************MU BFer Entry Init*************/ + if ((pBeamformingInfo->beamformer_mu_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[BFerIdx]; + pBeamformingInfo->mu_ap_index = BFerIdx; + pBeamformerEntry->is_mu_ap = TRUE; + for (i = 0; i < 8; i++) + pBeamformerEntry->gid_valid[i] = 0; + for (i = 0; i < 16; i++) + pBeamformerEntry->user_position[i] = 0; + + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); + + /* MAC address */ + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+i), pBeamformerEntry->MacAddr[i]); + + /* Set partial AID */ + ODM_Write2Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+6), pBeamformerEntry->P_AID); + + /* Fill our AID to 0x1680[11:0] and [13:12] = 2b'00, BF report segment select to 3895 bytes*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, 0x1680); + u1bTmp = (pBeamformerEntry->AID)&0xFFF; + ODM_Write1Byte(pDM_Odm, 0x1680, u1bTmp); + + /* Set 80us for leaving ndp_rx_standby_state */ + ODM_Write1Byte(pDM_Odm, 0x71B, 0x50); + + /* Set 0x6A0[14] = 1 to accept action_no_ack */ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1); + u1bTmp |= 0x40; + ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1, u1bTmp); + /* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP1_8822B); + u1bTmp |= 0x30; + ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP1_8822B, u1bTmp); + + /*CSI report parameters of Beamformer*/ + Nc_index = halTxbf8822B_GetNrx(pDM_Odm); /* Depend on RF type */ + Nr_index = 1; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/ + grouping = 0; /*no grouping*/ + codebookinfo = 1; /*7 bit for psi, 9 bit for phi*/ + coefficientsize = 0; /*This is nothing really matter*/ + CSI_Param = (u2Byte)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(Nr_index<<3)|(Nc_index)); + ODM_Write2Byte(pDM_Odm, 0x6F4, CSI_Param); + + } + + /*************MU BFee Entry Init*************/ + if ((pBeamformingInfo->beamformee_mu_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + pBeamformeeEntry->is_mu_sta = TRUE; + for (i = 0; i < MAX_BEAMFORMEE_MU; i++) { + if ((pBeamformingInfo->beamformee_mu_reg_maping & BIT(i)) == 0) { + pBeamformingInfo->beamformee_mu_reg_maping |= BIT(i); + pBeamformeeEntry->mu_reg_index = i; + break; + } + } + + if (pBeamformeeEntry->mu_reg_index == 0xFF) { + /* There is no valid bit in beamformee_mu_reg_maping */ + RT_DISP(FBEAM, FBEAM_FUN, ("%s: ERROR! There is no valid bit in beamformee_mu_reg_maping!\n", __func__)); + return; + } + + /*User position table*/ + switch (pBeamformeeEntry->mu_reg_index) { + case 0: + gid_valid = 0x7fe; + user_position_l = 0x111110; + user_position_h = 0x0; + break; + case 1: + gid_valid = 0x7f806; + user_position_l = 0x11000004; + user_position_h = 0x11; + break; + case 2: + gid_valid = 0x1f81818; + user_position_l = 0x400040; + user_position_h = 0x11100; + break; + case 3: + gid_valid = 0x1e186060; + user_position_l = 0x4000400; + user_position_h = 0x1100040; + break; + case 4: + gid_valid = 0x66618180; + user_position_l = 0x40004000; + user_position_h = 0x10040400; + break; + case 5: + gid_valid = 0x79860600; + user_position_l = 0x40000; + user_position_h = 0x4404004; + break; + } + + for (i = 0; i < 8; i++) { + if (i < 4) { + pBeamformeeEntry->gid_valid[i] = (u1Byte)(gid_valid & 0xFF); + gid_valid = (gid_valid >> 8); + } else + pBeamformeeEntry->gid_valid[i] = 0; + } + for (i = 0; i < 16; i++) { + if (i < 4) { + pBeamformeeEntry->user_position[i] = (u1Byte)(user_position_l & 0xFF); + user_position_l = user_position_l >> 8; + } else if (i < 8) { + pBeamformeeEntry->user_position[i] = (u1Byte)(user_position_h & 0xFF); + user_position_h = user_position_h >> 8; + } else + pBeamformeeEntry->user_position[i] = 0; + } + + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); + + /*select MU STA table*/ + pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10); + pBeamformingInfo->RegMUTxCtrl |= (pBeamformeeEntry->mu_reg_index << 8)&(BIT8|BIT9|BIT10); + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + + ODM_SetBBReg(pDM_Odm, 0x14c4 , bMaskDWord, 0); /*Reset gid_valid table*/ + ODM_SetBBReg(pDM_Odm, 0x14c8 , bMaskDWord, user_position_l); + ODM_SetBBReg(pDM_Odm, 0x14cc , bMaskDWord, user_position_h); + + /*set validity of MU STAs*/ + pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0; + pBeamformingInfo->RegMUTxCtrl |= pBeamformingInfo->beamformee_mu_reg_maping&0x3F; + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + + value16 = ODM_Read2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index]); + value16 &= 0xFE00; /*Clear PAID*/ + value16 |= BIT9; /*Enable MU BFee*/ + value16 |= pBeamformeeEntry->P_AID; + ODM_Write2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index] , value16); + + /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3); + u1bTmp |= 0xD0; /* Set bit 28, 30, 31 to 3b'111*/ + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, u1bTmp); + /* Set NDPA to 6M*/ + ODM_Write1Byte(pDM_Odm, REG_NDPA_RATE_8822B, 0x4); /* 6M */ + + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B); + u1bTmp &= 0xFC; /* Clear bit 0, 1*/ + ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B, u1bTmp); + + u4bTmp = ODM_Read4Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B); + u4bTmp = ((u4bTmp & 0xFF0000FF) | 0x020200); /* Set [23:8] to 0x0202 */ + ODM_Write4Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, u4bTmp); + + /* Set 0x6A0[14] = 1 to accept action_no_ack */ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1); + u1bTmp |= 0x40; + ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1, u1bTmp); + /* End of MAC registers setting */ + + halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx); +#if (SUPPORT_MU_BF == 1) + /*Special for plugfest*/ + delay_ms(50); /* wait for 4-way handshake ending*/ + SendSWVHTGIDMgntFrame(pDM_Odm, pBeamformeeEntry->MacAddr, BFeeIdx); +#endif + + phydm_Beamforming_Notify(pDM_Odm); + + } + +} + + +VOID +HalTxbf8822B_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMER_ENTRY pBeamformerEntry; + PRT_BEAMFORMEE_ENTRY pBeamformeeEntry; + u4Byte mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e}; + + if (Idx < BEAMFORMER_ENTRY_NUM) { + pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[Idx]; + pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[Idx]; + } else + return; + + /*Clear P_AID of Beamformee*/ + /*Clear MAC address of Beamformer*/ + /*Clear Associated Bfmee Sel*/ + + if (pBeamformerEntry->BeamformEntryCap == BEAMFORMING_CAP_NONE) { + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xD8); + if (pBeamformerEntry->is_mu_ap == 0) { /*SU BFer */ + if (pBeamformerEntry->su_reg_index == 0) { + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8822B, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8822B+4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8822B, 0); + } else { + ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8822B, 0); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8822B+4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8822B+2, 0); + } + pBeamformingInfo->beamformer_su_reg_maping &= ~(BIT(pBeamformerEntry->su_reg_index)); + pBeamformerEntry->su_reg_index = 0xFF; + } else { /*MU BFer */ + /*set validity of MU STA0 and MU STA1*/ + pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0; + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + + ODM_Memory_Set(pDM_Odm, pBeamformerEntry->gid_valid, 0, 8); + ODM_Memory_Set(pDM_Odm, pBeamformerEntry->user_position, 0, 16); + pBeamformerEntry->is_mu_ap = FALSE; + } + } + + if (pBeamformeeEntry->BeamformEntryCap == BEAMFORMING_CAP_NONE) { + halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, Idx); + if (pBeamformeeEntry->is_mu_sta == 0) { /*SU BFee*/ + if (pBeamformeeEntry->su_reg_index == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, 0x0); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3)|BIT4|BIT6|BIT7); + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B, 0); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B+2, 0x0 | BIT14 | BIT15 | BIT12); + + ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2, + ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2) & 0x60); + } + pBeamformingInfo->beamformee_su_reg_maping &= ~(BIT(pBeamformeeEntry->su_reg_index)); + pBeamformeeEntry->su_reg_index = 0xFF; + } else { /*MU BFee */ + /*Disable sending NDPA & BF-rpt-poll to this BFee*/ + ODM_Write2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index] , 0); + /*set validity of MU STA*/ + pBeamformingInfo->RegMUTxCtrl &= ~(BIT(pBeamformeeEntry->mu_reg_index)); + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + + + pBeamformeeEntry->is_mu_sta = FALSE; + pBeamformingInfo->beamformee_mu_reg_maping &= ~(BIT(pBeamformeeEntry->mu_reg_index)); + pBeamformeeEntry->mu_reg_index = 0xFF; + } + } +} + + +/***********SU & MU BFee Entry Only when souding done****************/ +VOID +HalTxbf8822B_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte BeamCtrlVal, tmpVal; + u4Byte BeamCtrlReg; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamformEntry; + BOOLEAN is_mu_sounding = pBeamformingInfo->is_mu_sounding, is_bitmap_ready = FALSE; + u16 bitmap; + u8 idx, gid, i; + u8 id1, id0; + u32 gid_valid[6] = {0}; + u32 user_position_lsb[6] = {0}; + u32 user_position_msb[6] = {0}; + u32 value32; + + if (Idx < BEAMFORMEE_ENTRY_NUM) + pBeamformEntry = &pBeamformingInfo->BeamformeeEntry[Idx]; + else + return; + + /*SU sounding done */ + if (is_mu_sounding == FALSE) { + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + BeamCtrlVal = pBeamformEntry->MacId; + else + BeamCtrlVal = pBeamformEntry->P_AID; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BeamformEntry.BeamformEntryState = %d", __func__, pBeamformEntry->BeamformEntryState)); + + if (pBeamformEntry->su_reg_index == 0) { + BeamCtrlReg = REG_TXBF_CTRL_8822B; + } else { + BeamCtrlReg = REG_TXBF_CTRL_8822B+2; + BeamCtrlVal |= BIT12|BIT14|BIT15; + } + + if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_20) + BeamCtrlVal |= BIT9; + else if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_40) + BeamCtrlVal |= (BIT9|BIT10); + else if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_80) + BeamCtrlVal |= (BIT9|BIT10|BIT11); + } else { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix", __func__)); + BeamCtrlVal &= ~(BIT9|BIT10|BIT11); + } + + ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); + /*disable NDP packet use beamforming */ + tmpVal = ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8822B); + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, tmpVal|BIT15); + } else { + /*MU sounding done */ + if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + /*value32 = ODM_GetBBReg(pDM_Odm, 0xF4C, 0xFFFF0000);*/ + value32 = 1; + + is_bitmap_ready = (BOOLEAN)((value32 & BIT15) >> 15); + bitmap = (u16)(value32 & 0x3FFF); + + for (idx = 0; idx < 15; idx++) { + if (idx < 5) {/*bit0~4*/ + id0 = 0; + id1 = (u8)(idx + 1); + } else if (idx < 9) { /*bit5~8*/ + id0 = 1; + id1 = (u8)(idx - 3); + } else if (idx < 12) { /*bit9~11*/ + id0 = 2; + id1 = (u8)(idx - 6); + } else if (idx < 14) { /*bit12~13*/ + id0 = 3; + id1 = (u8)(idx - 8); + } else { /*bit14*/ + id0 = 4; + id1 = (u8)(idx - 9); + } + if (bitmap & BIT(idx)) { + /*Pair 1*/ + gid = (idx << 1) + 1; + gid_valid[id0] |= (BIT(gid)); + gid_valid[id1] |= (BIT(gid)); + /*Pair 2*/ + gid += 1; + gid_valid[id0] |= (BIT(gid)); + gid_valid[id1] |= (BIT(gid)); + } else { + /*Pair 1*/ + gid = (idx << 1) + 1; + gid_valid[id0] &= ~(BIT(gid)); + gid_valid[id1] &= ~(BIT(gid)); + /*Pair 2*/ + gid += 1; + gid_valid[id0] &= ~(BIT(gid)); + gid_valid[id1] &= ~(BIT(gid)); + } + } + + for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) { + pBeamformEntry = &pBeamformingInfo->BeamformeeEntry[i]; + if ((pBeamformEntry->is_mu_sta) && (pBeamformEntry->mu_reg_index < 6)) { + value32 = gid_valid[pBeamformEntry->mu_reg_index]; + for (idx = 0; idx < 4; idx++) { + pBeamformEntry->gid_valid[idx] = (u8)(value32 & 0xFF); + value32 = (value32 >> 8); + } + } + } + + for (idx = 0; idx < 6; idx++) { + pBeamformingInfo->RegMUTxCtrl |= ~(BIT8|BIT9|BIT10); + pBeamformingInfo->RegMUTxCtrl |= ((idx<<8)&(BIT8|BIT9|BIT10)); + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + ODM_SetMACReg(pDM_Odm, 0x14C4, bMaskDWord, gid_valid[idx]); /*set MU STA gid valid table*/ + } + + /*Enable TxMU PPDU*/ + pBeamformingInfo->RegMUTxCtrl |= BIT7; + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + } + } +} + +/*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/ +VOID +HalTxbf8822B_ConfigGtab( + IN PVOID pDM_VOID + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMER_ENTRY pBeamformerEntry = NULL; + u4Byte gid_valid = 0, user_position_l = 0, user_position_h = 0, i; + + if (pBeamformingInfo->mu_ap_index < BEAMFORMER_ENTRY_NUM) + pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[pBeamformingInfo->mu_ap_index]; + else + return; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s==>\n", __func__)); + + /*For GID 0~31*/ + for (i = 0; i < 4; i++) + gid_valid |= (pBeamformerEntry->gid_valid[i] << (i<<3)); + for (i = 0; i < 8; i++) { + if (i < 4) + user_position_l |= (pBeamformerEntry->user_position[i] << (i << 3)); + else + user_position_h |= (pBeamformerEntry->user_position[i] << ((i - 4)<<3)); + } + /*select MU STA0 table*/ + pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10); + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + ODM_SetBBReg(pDM_Odm, 0x14c4, bMaskDWord, gid_valid); + ODM_SetBBReg(pDM_Odm, 0x14c8, bMaskDWord, user_position_l); + ODM_SetBBReg(pDM_Odm, 0x14cc, bMaskDWord, user_position_h); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA0: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n", + __func__, gid_valid, user_position_l, user_position_h)); + + gid_valid = 0; + user_position_l = 0; + user_position_h = 0; + + /*For GID 32~64*/ + for (i = 4; i < 8; i++) + gid_valid |= (pBeamformerEntry->gid_valid[i] << ((i - 4)<<3)); + for (i = 8; i < 16; i++) { + if (i < 4) + user_position_l |= (pBeamformerEntry->user_position[i] << ((i - 8) << 3)); + else + user_position_h |= (pBeamformerEntry->user_position[i] << ((i - 12) << 3)); + } + /*select MU STA1 table*/ + pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10); + pBeamformingInfo->RegMUTxCtrl |= BIT8; + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + ODM_SetBBReg(pDM_Odm, 0x14c4, bMaskDWord, gid_valid); + ODM_SetBBReg(pDM_Odm, 0x14c8, bMaskDWord, user_position_l); + ODM_SetBBReg(pDM_Odm, 0x14cc, bMaskDWord, user_position_h); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA1: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n", + __func__, gid_valid, user_position_l, user_position_h)); + + /* Set validity of MU STA0 and MU STA1*/ + pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0; + pBeamformingInfo->RegMUTxCtrl |= 0x3; /* STA0, STA1*/ + ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); + +} + + + +#if 0 +/*This function translate the bitmap to GTAB*/ +VOID +haltxbf8822b_gtab_translation( + IN PDM_ODM_T pDM_Odm +) +{ + u8 idx, gid; + u8 id1, id0; + u32 gid_valid[6] = {0}; + u32 user_position_lsb[6] = {0}; + u32 user_position_msb[6] = {0}; + + for (idx = 0; idx < 15; idx++) { + if (idx < 5) {/*bit0~4*/ + id0 = 0; + id1 = (u8)(idx + 1); + } else if (idx < 9) { /*bit5~8*/ + id0 = 1; + id1 = (u8)(idx - 3); + } else if (idx < 12) { /*bit9~11*/ + id0 = 2; + id1 = (u8)(idx - 6); + } else if (idx < 14) { /*bit12~13*/ + id0 = 3; + id1 = (u8)(idx - 8); + } else { /*bit14*/ + id0 = 4; + id1 = (u8)(idx - 9); + } + + /*Pair 1*/ + gid = (idx << 1) + 1; + gid_valid[id0] |= (1 << gid); + gid_valid[id1] |= (1 << gid); + if (gid < 16) { + /*user_position_lsb[id0] |= (0 << (gid << 1));*/ + user_position_lsb[id1] |= (1 << (gid << 1)); + } else { + /*user_position_msb[id0] |= (0 << ((gid - 16) << 1));*/ + user_position_msb[id1] |= (1 << ((gid - 16) << 1)); + } + + /*Pair 2*/ + gid += 1; + gid_valid[id0] |= (1 << gid); + gid_valid[id1] |= (1 << gid); + if (gid < 16) { + user_position_lsb[id0] |= (1 << (gid << 1)); + /*user_position_lsb[id1] |= (0 << (gid << 1));*/ + } else { + user_position_msb[id0] |= (1 << ((gid - 16) << 1)); + /*user_position_msb[id1] |= (0 << ((gid - 16) << 1));*/ + } + + } + + + for (idx = 0; idx < 6; idx++) { + /*DbgPrint("gid_valid[%d] = 0x%x\n", idx, gid_valid[idx]); + DbgPrint("user_position[%d] = 0x%x %x\n", idx, user_position_msb[idx], user_position_lsb[idx]);*/ + } +} +#endif + +VOID +HalTxbf8822B_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ) +{ +#if 0 + PRT_BEAMFORMING_INFO pBeamInfo = GET_BEAMFORM_INFO(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry+Idx; + + if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + halTxbf8822B_DownloadNDPA(Adapter, Idx); + + halTxbf8822B_FwTxBFCmd(Adapter); +#endif +} + +#else /* (RTL8822B_SUPPORT == 1)*/ + +#endif /* (RTL8822B_SUPPORT == 1)*/ + +#endif /*(BEAMFORMING_SUPPORT == 1)*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.h new file mode 100644 index 00000000..bc22bcef --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbf8822b.h @@ -0,0 +1,53 @@ +#ifndef __HAL_TXBF_8822B_H__ +#define __HAL_TXBF_8822B_H__ +#if (BEAMFORMING_SUPPORT == 1) +#if (RTL8822B_SUPPORT == 1) + +VOID +HalTxbf8822B_Init( + IN PVOID pDM_VOID + ); + +VOID +HalTxbf8822B_Enter( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8822B_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbf8822B_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + +VOID +HalTxbf8822B_ConfigGtab( + IN PVOID pDM_VOID + ); + +VOID +HalTxbf8822B_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); +#else +#define HalTxbf8822B_Init(pDM_VOID) +#define HalTxbf8822B_Enter(pDM_VOID, Idx) +#define HalTxbf8822B_Leave(pDM_VOID, Idx) +#define HalTxbf8822B_Status(pDM_VOID, Idx) +#define HalTxbf8822B_FwTxBF(pDM_VOID, Idx) +#define HalTxbf8822B_ConfigGtab(pDM_VOID) +#endif + + +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.c new file mode 100644 index 00000000..badd23b4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.c @@ -0,0 +1,1384 @@ +//============================================================ +// Description: +// +// This file is for TXBF interface mechanism +// +//============================================================ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +Beamforming_GidPAid( + PADAPTER Adapter, + PRT_TCB pTcb +) +{ + u1Byte Idx = 0; + u1Byte RA[6] ={0}; + pu1Byte pHeader = GET_FRAME_OF_FIRST_FRAG(Adapter, pTcb); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + + if (Adapter->HardwareType < HARDWARE_TYPE_RTL8192EE) + return; + else if (IS_WIRELESS_MODE_N(Adapter) == FALSE) + return; + +#if (SUPPORT_MU_BF == 1) + if (pTcb->TxBFPktType == RT_BF_PKT_TYPE_BROADCAST_NDPA) { /* MU NDPA */ +#else + if (0) { +#endif + /* Fill G_ID and P_AID */ + pTcb->G_ID = 63; + if (pBeamInfo->FirstMUBFeeIndex < BEAMFORMEE_ENTRY_NUM) { + pTcb->P_AID = pBeamInfo->BeamformeeEntry[pBeamInfo->FirstMUBFeeIndex].P_AID; + RT_DISP(FBEAM, FBEAM_FUN, ("[David]@%s End, G_ID=0x%X, P_AID=0x%X\n", __func__, pTcb->G_ID, pTcb->P_AID)); + } + } else { + GET_80211_HDR_ADDRESS1(pHeader, &RA); + + // VHT SU PPDU carrying one or more group addressed MPDUs or + // Transmitting a VHT NDP intended for multiple recipients + if (MacAddr_isBcst(RA) || MacAddr_isMulticast(RA) || pTcb->macId == MAC_ID_STATIC_FOR_BROADCAST_MULTICAST) { + pTcb->G_ID = 63; + pTcb->P_AID = 0; + } else if (ACTING_AS_AP(Adapter)) { + u2Byte AID = (u2Byte) (MacIdGetOwnerAssociatedClientAID(Adapter, pTcb->macId) & 0x1ff); /*AID[0:8]*/ + + /*RT_DISP(FBEAM, FBEAM_FUN, ("@%s pTcb->macId=0x%X, AID=0x%X\n", __func__, pTcb->macId, AID));*/ + pTcb->G_ID = 63; + + if (AID == 0) /*A PPDU sent by an AP to a non associated STA*/ + pTcb->P_AID = 0; + else { /*Sent by an AP and addressed to a STA associated with that AP*/ + u2Byte BSSID = 0; + GET_80211_HDR_ADDRESS2(pHeader, &RA); + BSSID = ((RA[5] & 0xf0) >> 4) ^ (RA[5] & 0xf); /*BSSID[44:47] xor BSSID[40:43]*/ + pTcb->P_AID = (AID + BSSID *32) & 0x1ff; /*(dec(A) + dec(B)*32) mod 512*/ + } + } else if (ACTING_AS_IBSS(Adapter)) { + pTcb->G_ID = 63; + /*P_AID for infrasturcture mode; MACID for ad-hoc mode. */ + pTcb->P_AID = pTcb->macId; + } else if (MgntLinkStatusQuery(Adapter)) { /*Addressed to AP*/ + pTcb->G_ID = 0; + GET_80211_HDR_ADDRESS1(pHeader, &RA); + pTcb->P_AID = RA[5]; /*RA[39:47]*/ + pTcb->P_AID = (pTcb->P_AID << 1) | (RA[4] >> 7 ); + } else { + pTcb->G_ID = 63; + pTcb->P_AID = 0; + } + /*RT_DISP(FBEAM, FBEAM_FUN, ("[David]@%s End, G_ID=0x%X, P_AID=0x%X\n", __func__, pTcb->G_ID, pTcb->P_AID));*/ + } +} + + +RT_STATUS +Beamforming_GetReportFrame( + IN PADAPTER Adapter, + IN PRT_RFD pRfd, + IN POCTET_STRING pPduOS + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL; + pu1Byte pMIMOCtrlField, pCSIReport, pCSIMatrix; + u1Byte Idx, Nc, Nr, CH_W; + u2Byte CSIMatrixLen = 0; + + ACT_PKT_TYPE pktType = ACT_PKT_TYPE_UNKNOWN; + + //Memory comparison to see if CSI report is the same with previous one + pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, Frame_Addr2(*pPduOS), &Idx); + + if (pBeamformEntry == NULL) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Beamforming_GetReportFrame: Cannot find entry by addr\n")); + return RT_STATUS_FAILURE; + } + + pktType = PacketGetActionFrameType(pPduOS); + + //-@ Modified by David + if (pktType == ACT_PKT_VHT_COMPRESSED_BEAMFORMING) { + pMIMOCtrlField = pPduOS->Octet + 26; + Nc = ((*pMIMOCtrlField) & 0x7) + 1; + Nr = (((*pMIMOCtrlField) & 0x38) >> 3) + 1; + CH_W = (((*pMIMOCtrlField) & 0xC0) >> 6); + pCSIMatrix = pMIMOCtrlField + 3 + Nc; //24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField) +SNR(Nc=2) + CSIMatrixLen = pPduOS->Length - 26 -3 -Nc; + } else if (pktType == ACT_PKT_HT_COMPRESSED_BEAMFORMING) { + pMIMOCtrlField = pPduOS->Octet + 26; + Nc = ((*pMIMOCtrlField) & 0x3) + 1; + Nr = (((*pMIMOCtrlField) & 0xC) >> 2) + 1; + CH_W = (((*pMIMOCtrlField) & 0x10) >> 4); + pCSIMatrix = pMIMOCtrlField + 6 + Nr; //24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField) +SNR(Nc=2) + CSIMatrixLen = pPduOS->Length - 26 -6 -Nr; + } else + return RT_STATUS_SUCCESS; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] idx=%d, pkt type=%d, Nc=%d, Nr=%d, CH_W=%d\n", __func__, Idx, pktType, Nc, Nr, CH_W)); + + return RT_STATUS_SUCCESS; +} + + +VOID +ConstructHTNDPAPacket( + PADAPTER Adapter, + pu1Byte RA, + pu1Byte Buffer, + pu4Byte pLength, + CHANNEL_WIDTH BW + ) +{ + u2Byte Duration= 0; + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + OCTET_STRING pNDPAFrame,ActionContent; + u1Byte ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c}; + + PlatformZeroMemory(Buffer, 32); + + SET_80211_HDR_FRAME_CONTROL(Buffer,0); + + SET_80211_HDR_ORDER(Buffer, 1); + SET_80211_HDR_TYPE_AND_SUBTYPE(Buffer,Type_Action_No_Ack); + + SET_80211_HDR_ADDRESS1(Buffer, RA); + SET_80211_HDR_ADDRESS2(Buffer, Adapter->CurrentAddress); + SET_80211_HDR_ADDRESS3(Buffer, pMgntInfo->Bssid); + + Duration = 2*aSifsTime + 40; + + if (BW == CHANNEL_WIDTH_40) + Duration+= 87; + else + Duration+= 180; + + SET_80211_HDR_DURATION(Buffer, Duration); + + //HT control field + SET_HT_CTRL_CSI_STEERING(Buffer+sMacHdrLng, 3); + SET_HT_CTRL_NDP_ANNOUNCEMENT(Buffer+sMacHdrLng, 1); + + FillOctetString(pNDPAFrame, Buffer, sMacHdrLng+sHTCLng); + + FillOctetString(ActionContent, ActionHdr, 4); + PacketAppendData(&pNDPAFrame, ActionContent); + + *pLength = 32; +} + + + + +BOOLEAN +SendFWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u4Byte BufLen; + pu1Byte BufAddr; + u1Byte DescLen = 0, Idx = 0, NDPTxRate; + PADAPTER pDefAdapter = GetDefaultAdapter(Adapter); + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pBeamformEntry == NULL) + return FALSE; + + NDPTxRate = Beamforming_GetHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetFWBuffer(pDefAdapter, &pTcb, &pBuf)) { +#if(DEV_BUS_TYPE != RT_PCI_INTERFACE) + DescLen = Adapter->HWDescHeadLength - pHalData->USBALLDummyLength; +#endif + BufAddr = pBuf->Buffer.VirtualAddress + DescLen; + + ConstructHTNDPAPacket( + Adapter, + RA, + BufAddr, + &BufLen, + BW + ); + + pTcb->PacketLength = BufLen + DescLen; + + pTcb->bTxEnableSwCalcDur = TRUE; + + pTcb->BWOfPacket = BW; + + if(ACTING_AS_IBSS(Adapter) || ACTING_AS_AP(Adapter)) + pTcb->G_ID = 63; + + pTcb->P_AID = pBeamformEntry->P_AID; + pTcb->DataRate = NDPTxRate; /*rate of NDP decide by Nr*/ + + Adapter->HalFunc.CmdSendPacketHandler(Adapter, pTcb, pBuf, pTcb->PacketLength, DESC_PACKET_TYPE_NORMAL, FALSE); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + + +BOOLEAN +SendSWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u1Byte Idx = 0, NDPTxRate = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + NDPTxRate = Beamforming_GetHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetBuffer(Adapter, &pTcb, &pBuf)) { + ConstructHTNDPAPacket( + Adapter, + RA, + pBuf->Buffer.VirtualAddress, + &pTcb->PacketLength, + BW + ); + + pTcb->bTxEnableSwCalcDur = TRUE; + + pTcb->BWOfPacket = BW; + + MgntSendPacket(Adapter, pTcb, pBuf, pTcb->PacketLength, NORMAL_QUEUE, NDPTxRate); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + + + +VOID +ConstructVHTNDPAPacket( + IN PDM_ODM_T pDM_Odm, + pu1Byte RA, + u2Byte AID, + pu1Byte Buffer, + pu4Byte pLength, + CHANNEL_WIDTH BW + ) +{ + u2Byte Duration= 0; + u1Byte Sequence = 0; + pu1Byte pNDPAFrame = Buffer; + RT_NDPA_STA_INFO STAInfo; + PADAPTER Adapter = pDM_Odm->Adapter; + u1Byte Idx = 0; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + // Frame control. + SET_80211_HDR_FRAME_CONTROL(pNDPAFrame, 0); + SET_80211_HDR_TYPE_AND_SUBTYPE(pNDPAFrame, Type_NDPA); + + SET_80211_HDR_ADDRESS1(pNDPAFrame, RA); + SET_80211_HDR_ADDRESS2(pNDPAFrame, pBeamformEntry->MyMacAddr); + + Duration = 2*aSifsTime + 44; + + if (BW == CHANNEL_WIDTH_80) + Duration += 40; + else if(BW == CHANNEL_WIDTH_40) + Duration+= 87; + else + Duration+= 180; + + SET_80211_HDR_DURATION(pNDPAFrame, Duration); + + Sequence = *(pDM_Odm->pSoundingSeq) << 2; + ODM_MoveMemory(pDM_Odm, pNDPAFrame+16, &Sequence, 1); + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS) || phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_AP) == FALSE) + AID = 0; + + STAInfo.AID = AID; + STAInfo.FeedbackType = 0; + STAInfo.NcIndex = 0; + + ODM_MoveMemory(pDM_Odm, pNDPAFrame+17, (pu1Byte)&STAInfo, 2); + + *pLength = 19; +} + + +BOOLEAN +SendFWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u4Byte BufLen; + pu1Byte BufAddr; + u1Byte DescLen = 0, Idx = 0, NDPTxRate = 0; + PADAPTER pDefAdapter = GetDefaultAdapter(Adapter); + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PRT_BEAMFORMEE_ENTRY pBeamformEntry =phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pBeamformEntry == NULL) + return FALSE; + + NDPTxRate = Beamforming_GetVHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetFWBuffer(pDefAdapter, &pTcb, &pBuf)) { +#if(DEV_BUS_TYPE != RT_PCI_INTERFACE) + DescLen = Adapter->HWDescHeadLength - pHalData->USBALLDummyLength; +#endif + BufAddr = pBuf->Buffer.VirtualAddress + DescLen; + + ConstructVHTNDPAPacket( + pDM_Odm, + RA, + AID, + BufAddr, + &BufLen, + BW + ); + + pTcb->PacketLength = BufLen + DescLen; + + pTcb->bTxEnableSwCalcDur = TRUE; + + pTcb->BWOfPacket = BW; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS) || phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_AP)) + pTcb->G_ID = 63; + + pTcb->P_AID = pBeamformEntry->P_AID; + pTcb->DataRate = NDPTxRate; /*decide by Nr*/ + + Adapter->HalFunc.CmdSendPacketHandler(Adapter, pTcb, pBuf, pTcb->PacketLength, DESC_PACKET_TYPE_NORMAL, FALSE); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End, ret=%d\n", __func__, ret)); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + + + +BOOLEAN +SendSWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u1Byte Idx = 0, NDPTxRate = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + NDPTxRate = Beamforming_GetVHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetBuffer(Adapter, &pTcb, &pBuf)) { + ConstructVHTNDPAPacket( + pDM_Odm, + RA, + AID, + pBuf->Buffer.VirtualAddress, + &pTcb->PacketLength, + BW + ); + + pTcb->bTxEnableSwCalcDur = TRUE; + pTcb->BWOfPacket = BW; + + /*rate of NDP decide by Nr*/ + MgntSendPacket(Adapter, pTcb, pBuf, pTcb->PacketLength, NORMAL_QUEUE, NDPTxRate); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + +#ifdef SUPPORT_MU_BF +#if (SUPPORT_MU_BF == 1) +/* +// Description: On VHT GID management frame by an MU beamformee. +// +// 2015.05.20. Created by tynli. +*/ +RT_STATUS +Beamforming_GetVHTGIDMgntFrame( + IN PADAPTER Adapter, + IN PRT_RFD pRfd, + IN POCTET_STRING pPduOS + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + pu1Byte pBuffer = NULL; + pu1Byte pRaddr = NULL; + u1Byte MemStatus[8] = {0}, UserPos[16] = {0}; + u1Byte idx; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMER_ENTRY pBeamformEntry = &pBeamInfo->BeamformerEntry[pBeamInfo->mu_ap_index]; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] On VHT GID mgnt frame!\n", __func__)); + + /* Check length*/ + if (pPduOS->Length < (FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY+16)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Beamforming_GetVHTGIDMgntFrame(): Invalid length (%d)\n", pPduOS->Length)); + return RT_STATUS_INVALID_LENGTH; + } + + /* Check RA*/ + pRaddr = (pu1Byte)(pPduOS->Octet)+4; + if (!eqMacAddr(pRaddr, Adapter->CurrentAddress)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Beamforming_GetVHTGIDMgntFrame(): Drop because of RA error.\n")); + return RT_STATUS_PKT_DROP; + } + + RT_DISP_DATA(FBEAM, FBEAM_DATA, "On VHT GID Mgnt Frame ==>:\n", pPduOS->Octet, pPduOS->Length); + + /*Parsing Membership Status Array*/ + pBuffer = pPduOS->Octet + FRAME_OFFSET_VHT_GID_MGNT_MEMBERSHIP_STATUS_ARRAY; + for (idx = 0; idx < 8; idx++) { + MemStatus[idx] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS(pBuffer+idx); + pBeamformEntry->gid_valid[idx] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS(pBuffer+idx); + } + + RT_DISP_DATA(FBEAM, FBEAM_DATA, "MemStatus: ", MemStatus, 8); + + /* Parsing User Position Array*/ + pBuffer = pPduOS->Octet + FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY; + for (idx = 0; idx < 16; idx++) { + UserPos[idx] = GET_VHT_GID_MGNT_INFO_USER_POSITION(pBuffer+idx); + pBeamformEntry->user_position[idx] = GET_VHT_GID_MGNT_INFO_USER_POSITION(pBuffer+idx); + } + + RT_DISP_DATA(FBEAM, FBEAM_DATA, "UserPos: ", UserPos, 16); + + /* Group ID detail printed*/ + { + u1Byte i, j; + u1Byte tmpVal; + u2Byte tmpVal2; + + for (i = 0; i < 8; i++) { + tmpVal = MemStatus[i]; + tmpVal2 = ((UserPos[i*2 + 1] << 8) & 0xFF00) + (UserPos[i * 2] & 0xFF); + for (j = 0; j < 8; j++) { + if ((tmpVal >> j) & BIT0) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Use Group ID (%d), User Position (%d)\n", + (i*8+j), (tmpVal2 >> 2 * j)&0x3)); + } + } + } + } + + /* Indicate GID frame to IHV service. */ + { + u1Byte Indibuffer[24] = {0}; + u1Byte Indioffset = 0; + + PlatformMoveMemory(Indibuffer + Indioffset, pBeamformEntry->gid_valid, 8); + Indioffset += 8; + PlatformMoveMemory(Indibuffer + Indioffset, pBeamformEntry->user_position, 16); + Indioffset += 16; + + PlatformIndicateCustomStatus( + Adapter, + RT_CUSTOM_EVENT_VHT_RECV_GID_MGNT_FRAME, + RT_CUSTOM_INDI_TARGET_IHV, + Indibuffer, + Indioffset); + } + + /* Config HW GID table */ + halComTxbf_ConfigGtab(pDM_Odm); + + return rtStatus; +} + +/* +// Description: Construct VHT Group ID (GID) management frame. +// +// 2015.05.20. Created by tynli. +*/ +VOID +ConstructVHTGIDMgntFrame( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte RA, + IN PRT_BEAMFORMEE_ENTRY pBeamformEntry, + OUT pu1Byte Buffer, + OUT pu4Byte pLength + +) +{ + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PADAPTER Adapter = pBeamInfo->SourceAdapter; + OCTET_STRING osFTMFrame, tmp; + + FillOctetString(osFTMFrame, Buffer, 0); + *pLength = 0; + + ConstructMaFrameHdr( + Adapter, + RA, + ACT_CAT_VHT, + ACT_VHT_GROUPID_MANAGEMENT, + &osFTMFrame); + + /* Membership Status Array*/ + FillOctetString(tmp, pBeamformEntry->gid_valid, 8); + PacketAppendData(&osFTMFrame, tmp); + + /* User Position Array*/ + FillOctetString(tmp, pBeamformEntry->user_position, 16); + PacketAppendData(&osFTMFrame, tmp); + + *pLength = osFTMFrame.Length; + + RT_DISP_DATA(FBEAM, FBEAM_DATA, "ConstructVHTGIDMgntFrame():\n", Buffer, *pLength); +} + +BOOLEAN +SendSWVHTGIDMgntFrame( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u1Byte Idx + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u1Byte DataRate = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = &pBeamInfo->BeamformeeEntry[Idx]; + PADAPTER Adapter = pBeamInfo->SourceAdapter; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetBuffer(Adapter, &pTcb, &pBuf)) { + ConstructVHTGIDMgntFrame( + pDM_Odm, + RA, + pBeamformEntry, + pBuf->Buffer.VirtualAddress, + &pTcb->PacketLength + ); + + pTcb->BWOfPacket = CHANNEL_WIDTH_20; + DataRate = MGN_6M; + MgntSendPacket(Adapter, pTcb, pBuf, pTcb->PacketLength, NORMAL_QUEUE, DataRate); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + + +/* +// Description: Construct VHT beamforming report poll. +// +// 2015.05.20. Created by tynli. +*/ +VOID +ConstructVHTBFReportPoll( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte RA, + OUT pu1Byte Buffer, + OUT pu4Byte pLength +) +{ + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PADAPTER Adapter = pBeamInfo->SourceAdapter; + pu1Byte pBFRptPoll = Buffer; + + /* Frame control*/ + SET_80211_HDR_FRAME_CONTROL(pBFRptPoll, 0); + SET_80211_HDR_TYPE_AND_SUBTYPE(pBFRptPoll, Type_Beamforming_Report_Poll); + + /* Duration*/ + SET_80211_HDR_DURATION(pBFRptPoll, 100); + + /* RA*/ + SET_VHT_BF_REPORT_POLL_RA(pBFRptPoll, RA); + + /* TA*/ + SET_VHT_BF_REPORT_POLL_TA(pBFRptPoll, Adapter->CurrentAddress); + + /* Feedback Segment Retransmission Bitmap*/ + SET_VHT_BF_REPORT_POLL_FEEDBACK_SEG_RETRAN_BITMAP(pBFRptPoll, 0xFF); + + *pLength = 17; + + RT_DISP_DATA(FBEAM, FBEAM_DATA, "ConstructVHTBFReportPoll():\n", Buffer, *pLength); + +} + +BOOLEAN +SendSWVHTBFReportPoll( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN BOOLEAN bFinalPoll + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u1Byte Idx = 0, DataRate = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + PADAPTER Adapter = pBeamInfo->SourceAdapter; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetBuffer(Adapter, &pTcb, &pBuf)) { + ConstructVHTBFReportPoll( + pDM_Odm, + RA, + pBuf->Buffer.VirtualAddress, + &pTcb->PacketLength + ); + + pTcb->bTxEnableSwCalcDur = TRUE; /* need?*/ + pTcb->BWOfPacket = CHANNEL_WIDTH_20; + + if (bFinalPoll) + pTcb->TxBFPktType = RT_BF_PKT_TYPE_FINAL_BF_REPORT_POLL; + else + pTcb->TxBFPktType = RT_BF_PKT_TYPE_BF_REPORT_POLL; + + DataRate = MGN_6M; /* Legacy OFDM rate*/ + MgntSendPacket(Adapter, pTcb, pBuf, pTcb->PacketLength, NORMAL_QUEUE, DataRate); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "SendSWVHTBFReportPoll():\n", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; + +} + + +/* +// Description: Construct VHT MU NDPA packet. +// We should combine this function with ConstructVHTNDPAPacket() in the future. +// +// 2015.05.21. Created by tynli. +*/ +VOID +ConstructVHTMUNDPAPacket( + IN PDM_ODM_T pDM_Odm, + IN CHANNEL_WIDTH BW, + OUT pu1Byte Buffer, + OUT pu4Byte pLength + ) +{ + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PADAPTER Adapter = pBeamInfo->SourceAdapter; + u2Byte Duration = 0; + u1Byte Sequence = 0; + pu1Byte pNDPAFrame = Buffer; + RT_NDPA_STA_INFO STAInfo; + u1Byte idx; + u1Byte DestAddr[6] = {0}; + PRT_BEAMFORMEE_ENTRY pEntry = NULL; + + /* Fill the first MU BFee entry (STA1) MAC addr to destination address then + HW will change A1 to broadcast addr. 2015.05.28. Suggested by SD1 Chunchu. */ + for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) { + pEntry = &(pBeamInfo->BeamformeeEntry[idx]); + if (pEntry->is_mu_sta) { + cpMacAddr(DestAddr, pEntry->MacAddr); + break; + } + } + if (pEntry == NULL) + return; + + /* Frame control.*/ + SET_80211_HDR_FRAME_CONTROL(pNDPAFrame, 0); + SET_80211_HDR_TYPE_AND_SUBTYPE(pNDPAFrame, Type_NDPA); + + SET_80211_HDR_ADDRESS1(pNDPAFrame, DestAddr); + SET_80211_HDR_ADDRESS2(pNDPAFrame, pEntry->MyMacAddr); + + /*--------------------------------------------*/ + /* Need to modify "Duration" to MU consideration. */ + Duration = 2*aSifsTime + 44; + + if (BW == CHANNEL_WIDTH_80) + Duration += 40; + else if(BW == CHANNEL_WIDTH_40) + Duration+= 87; + else + Duration+= 180; + /*--------------------------------------------*/ + + SET_80211_HDR_DURATION(pNDPAFrame, Duration); + + Sequence = *(pDM_Odm->pSoundingSeq) << 2; + ODM_MoveMemory(pDM_Odm, pNDPAFrame + 16, &Sequence, 1); + + *pLength = 17; + + /* Construct STA info. for multiple STAs*/ + for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) { + pEntry = &(pBeamInfo->BeamformeeEntry[idx]); + if (pEntry->is_mu_sta) { + STAInfo.AID = pEntry->AID; + STAInfo.FeedbackType = 1; /* 1'b1: MU*/ + STAInfo.NcIndex = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Get BeamformeeEntry idx(%d), AID =%d\n", __func__, idx, pEntry->AID)); + + ODM_MoveMemory(pDM_Odm, pNDPAFrame+(*pLength), (pu1Byte)&STAInfo, 2); + *pLength += 2; + } + } + +} + +BOOLEAN +SendSWVHTMUNDPAPacket( + IN PVOID pDM_VOID, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_TCB pTcb; + PRT_TX_LOCAL_BUFFER pBuf; + BOOLEAN ret = TRUE; + u1Byte NDPTxRate = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PADAPTER Adapter = pBeamInfo->SourceAdapter; + + NDPTxRate = MGN_VHT2SS_MCS0; + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + + if (MgntGetBuffer(Adapter, &pTcb, &pBuf)) { + ConstructVHTMUNDPAPacket( + pDM_Odm, + BW, + pBuf->Buffer.VirtualAddress, + &pTcb->PacketLength + ); + + pTcb->bTxEnableSwCalcDur = TRUE; + pTcb->BWOfPacket = BW; + pTcb->TxBFPktType = RT_BF_PKT_TYPE_BROADCAST_NDPA; + + /*rate of NDP decide by Nr*/ + MgntSendPacket(Adapter, pTcb, pBuf, pTcb->PacketLength, NORMAL_QUEUE, NDPTxRate); + } else + ret = FALSE; + + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); + + if (ret) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "", pBuf->Buffer.VirtualAddress, pTcb->PacketLength); + + return ret; +} + +#endif /*#if (SUPPORT_MU_BF == 1)*/ +#endif /*#ifdef SUPPORT_MU_BF*/ + + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + +u4Byte +Beamforming_GetReportFrame( + IN PVOID pDM_VOID, + union recv_frame *precv_frame + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u4Byte ret = _SUCCESS; + PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL; + pu1Byte pframe = precv_frame->u.hdr.rx_data; + u4Byte frame_len = precv_frame->u.hdr.len; + pu1Byte TA; + u1Byte Idx, offset; + + /*DBG_871X("beamforming_get_report_frame\n");*/ + + /*Memory comparison to see if CSI report is the same with previous one*/ + TA = GetAddr2Ptr(pframe); + pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, TA, &Idx); + if(pBeamformEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + offset = 31; /*24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/ + else if(pBeamformEntry->BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT) + offset = 34; /*24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/ + else + return ret; + + /*DBG_871X("%s MacId %d offset=%d\n", __FUNCTION__, pBeamformEntry->mac_id, offset);*/ + + return ret; +} + + +BOOLEAN +SendFWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u1Byte ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c}; + u1Byte *pframe; + u2Byte *fctrl; + u2Byte duration = 0; + u1Byte aSifsTime = 0, NDPTxRate = 0, Idx = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X("%s, alloc mgnt frame fail\n", __func__); + return _FALSE; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + + pattrib->qsel = QSLT_BEACON; + NDPTxRate = Beamforming_GetHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + pattrib->rate = NDPTxRate; + pattrib->bwmode = BW; + pattrib->order = 1; + pattrib->subtype = WIFI_ACTION_NOACK; + + _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; + + SetOrderBit(pframe); + SetFrameSubType(pframe, WIFI_ACTION_NOACK); + + _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pBeamformEntry->MyMacAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + if( pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + duration = 2*aSifsTime + 40; + + if(BW == CHANNEL_WIDTH_40) + duration+= 87; + else + duration+= 180; + + SetDuration(pframe, duration); + + //HT control field + SET_HT_CTRL_CSI_STEERING(pframe+24, 3); + SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1); + + _rtw_memcpy(pframe+28, ActionHdr, 4); + + pattrib->pktlen = 32; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; +} + + +BOOLEAN +SendSWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u1Byte ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c}; + pu1Byte pframe; + pu2Byte fctrl; + u2Byte duration = 0; + u1Byte aSifsTime = 0, NDPTxRate = 0, Idx = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + NDPTxRate = Beamforming_GetHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X("%s, alloc mgnt frame fail\n", __func__); + return _FALSE; + } + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + pattrib->qsel = QSLT_MGNT; + pattrib->rate = NDPTxRate; + pattrib->bwmode = BW; + pattrib->order = 1; + pattrib->subtype = WIFI_ACTION_NOACK; + + _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; + + SetOrderBit(pframe); + SetFrameSubType(pframe, WIFI_ACTION_NOACK); + + _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pBeamformEntry->MyMacAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + if (pmlmeext->cur_wireless_mode == WIRELESS_11B) + aSifsTime = 10; + else + aSifsTime = 16; + + duration = 2*aSifsTime + 40; + + if (BW == CHANNEL_WIDTH_40) + duration += 87; + else + duration += 180; + + SetDuration(pframe, duration); + + /*HT control field*/ + SET_HT_CTRL_CSI_STEERING(pframe+24, 3); + SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1); + + _rtw_memcpy(pframe+28, ActionHdr, 4); + + pattrib->pktlen = 32; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; +} + + +BOOLEAN +SendFWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + pu1Byte pframe; + pu2Byte fctrl; + u2Byte duration = 0; + u1Byte sequence = 0, aSifsTime = 0, NDPTxRate= 0, Idx = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + RT_NDPA_STA_INFO sta_info; + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X("%s, alloc mgnt frame fail\n", __func__); + return _FALSE; + } + + //update attribute + pattrib = &pmgntframe->attrib; + _rtw_memcpy(pattrib->ra, RA, ETH_ALEN); + update_mgntframe_attrib(Adapter, pattrib); + + pattrib->qsel = QSLT_BEACON; + NDPTxRate = Beamforming_GetVHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + pattrib->rate = NDPTxRate; + pattrib->bwmode = BW; + pattrib->subtype = WIFI_NDPA; + + _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; + + SetFrameSubType(pframe, WIFI_NDPA); + + _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pBeamformEntry->MyMacAddr, ETH_ALEN); + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode)) + aSifsTime = 16; + else + aSifsTime = 10; + + duration = 2*aSifsTime + 44; + + if(BW == CHANNEL_WIDTH_80) + duration += 40; + else if(BW == CHANNEL_WIDTH_40) + duration+= 87; + else + duration+= 180; + + SetDuration(pframe, duration); + + sequence = pBeamInfo->SoundingSequence<< 2; + if (pBeamInfo->SoundingSequence >= 0x3f) + pBeamInfo->SoundingSequence = 0; + else + pBeamInfo->SoundingSequence++; + + _rtw_memcpy(pframe+16, &sequence,1); + + if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + AID = 0; + + sta_info.AID = AID; + sta_info.FeedbackType = 0; + sta_info.NcIndex= 0; + + _rtw_memcpy(pframe+17, (u8 *)&sta_info, 2); + + pattrib->pktlen = 19; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + + return _TRUE; +} + + + +BOOLEAN +SendSWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + RT_NDPA_STA_INFO ndpa_sta_info; + u1Byte NDPTxRate = 0, sequence = 0, aSifsTime = 0, Idx = 0; + pu1Byte pframe; + pu2Byte fctrl; + u2Byte duration = 0; + PRT_BEAMFORMING_INFO pBeamInfo = &(pDM_Odm->BeamformingInfo); + PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr(pDM_Odm, RA, &Idx); + + NDPTxRate = Beamforming_GetVHTNDPTxRate(pDM_Odm, pBeamformEntry->CompSteeringNumofBFer); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] NDPTxRate =%d\n", __func__, NDPTxRate)); + + pmgntframe = alloc_mgtxmitframe(pxmitpriv); + + if (pmgntframe == NULL) { + DBG_871X("%s, alloc mgnt frame fail\n", __func__); + return _FALSE; + } + + /*update attribute*/ + pattrib = &pmgntframe->attrib; + _rtw_memcpy(pattrib->ra, RA, ETH_ALEN); + update_mgntframe_attrib(Adapter, pattrib); + pattrib->qsel = QSLT_MGNT; + pattrib->rate = NDPTxRate; + pattrib->bwmode = BW; + pattrib->subtype = WIFI_NDPA; + + _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; + + SetFrameSubType(pframe, WIFI_NDPA); + + _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, pBeamformEntry->MyMacAddr, ETH_ALEN); + + if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode)) + aSifsTime = 16; + else + aSifsTime = 10; + + duration = 2*aSifsTime + 44; + + if (BW == CHANNEL_WIDTH_80) + duration += 40; + else if (BW == CHANNEL_WIDTH_40) + duration += 87; + else + duration += 180; + + SetDuration(pframe, duration); + + sequence = pBeamInfo->SoundingSequence << 2; + if (pBeamInfo->SoundingSequence >= 0x3f) + pBeamInfo->SoundingSequence = 0; + else + pBeamInfo->SoundingSequence++; + + _rtw_memcpy(pframe+16, &sequence, 1); + if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) + AID = 0; + + ndpa_sta_info.AID = AID; + ndpa_sta_info.FeedbackType = 0; + ndpa_sta_info.NcIndex = 0; + + _rtw_memcpy(pframe+17, (u8 *)&ndpa_sta_info, 2); + + pattrib->pktlen = 19; + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(Adapter, pmgntframe); + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] [%d]\n", __func__, __LINE__)); + + return _TRUE; +} + + +#endif + + +VOID +Beamforming_GetNDPAFrame( + IN PVOID pDM_VOID, +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN OCTET_STRING pduOS +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + union recv_frame *precv_frame +#endif +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PADAPTER Adapter = pDM_Odm->Adapter; + pu1Byte TA ; + u1Byte Idx, Sequence; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + pu1Byte pNDPAFrame = pduOS.Octet; +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + pu1Byte pNDPAFrame = precv_frame->u.hdr.rx_data; +#endif + PRT_BEAMFORMER_ENTRY pBeamformerEntry = NULL; /*Modified By Jeffery @2014-10-29*/ + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_DISP_DATA(FBEAM, FBEAM_DATA, "Beamforming_GetNDPAFrame\n", pduOS.Octet, pduOS.Length); + if (IsCtrlNDPA(pNDPAFrame) == FALSE) +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + if (GetFrameSubType(pNDPAFrame) != WIFI_NDPA) +#endif + return; + else if (!(pDM_Odm->SupportICType & (ODM_RTL8812 | ODM_RTL8821))) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] not 8812 or 8821A, return\n", __func__)); + return; + } +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + TA = Frame_Addr2(pduOS); +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + TA = GetAddr2Ptr(pNDPAFrame); +#endif + /*Remove signaling TA. */ + TA[0] = TA[0] & 0xFE; + + pBeamformerEntry = phydm_Beamforming_GetBFerEntryByAddr(pDM_Odm, TA, &Idx); // Modified By Jeffery @2014-10-29 + + /*Break options for Clock Reset*/ + if (pBeamformerEntry == NULL) + return; + else if (!(pBeamformerEntry->BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU)) + return; + /*LogSuccess: As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is NO LONGER needed !2015-04-10, Jeffery*/ + /*ClockResetTimes: While BFer entry always doesn't receive our CSI, clock will reset again and again.So ClockResetTimes is limited to 5 times.2015-04-13, Jeffery*/ + else if ((pBeamformerEntry->LogSuccess == 1) || (pBeamformerEntry->ClockResetTimes == 5)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, LogSuccess=%d, ClockResetTimes=%d, clock reset is no longer needed.\n", + __func__, pBeamformerEntry->LogSeq, pBeamformerEntry->PreLogSeq, pBeamformerEntry->LogRetryCnt, pBeamformerEntry->LogSuccess, pBeamformerEntry->ClockResetTimes)); + + return; + } + + Sequence = (pNDPAFrame[16]) >> 2; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start, Sequence=%d, LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, ClockResetTimes=%d, LogSuccess=%d\n", + __func__, Sequence, pBeamformerEntry->LogSeq, pBeamformerEntry->PreLogSeq, pBeamformerEntry->LogRetryCnt, pBeamformerEntry->ClockResetTimes, pBeamformerEntry->LogSuccess)); + + if ((pBeamformerEntry->LogSeq != 0) && (pBeamformerEntry->PreLogSeq != 0)) { + /*Success condition*/ + if ((pBeamformerEntry->LogSeq != Sequence) && (pBeamformerEntry->PreLogSeq != pBeamformerEntry->LogSeq)) { + /* break option for clcok reset, 2015-03-30, Jeffery */ + pBeamformerEntry->LogRetryCnt = 0; + /*As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is no longer needed.*/ + /*That is, LogSuccess is NOT needed to be reset to zero, 2015-04-13, Jeffery*/ + pBeamformerEntry->LogSuccess = 1; + + } else {/*Fail condition*/ + + if (pBeamformerEntry->LogRetryCnt == 5) { + pBeamformerEntry->ClockResetTimes++; + pBeamformerEntry->LogRetryCnt = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Clock Reset!!! ClockResetTimes=%d\n", + __func__, pBeamformerEntry->ClockResetTimes)); + HalComTxbf_Set(pDM_Odm, TXBF_SET_SOUNDING_CLK, NULL); + + } else + pBeamformerEntry->LogRetryCnt++; + } + } + + /*Update LogSeq & PreLogSeq*/ + pBeamformerEntry->PreLogSeq = pBeamformerEntry->LogSeq; + pBeamformerEntry->LogSeq = Sequence; + +} + + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.h new file mode 100644 index 00000000..0318ad36 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfinterface.h @@ -0,0 +1,158 @@ +#ifndef __HAL_TXBF_INTERFACE_H__ +#define __HAL_TXBF_INTERFACE_H__ + +#if (BEAMFORMING_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +Beamforming_GidPAid( + PADAPTER Adapter, + PRT_TCB pTcb + ); + +RT_STATUS +Beamforming_GetReportFrame( + IN PADAPTER Adapter, + IN PRT_RFD pRfd, + IN POCTET_STRING pPduOS + ); + +VOID +Beamforming_GetNDPAFrame( + IN PVOID pDM_VOID, + IN OCTET_STRING pduOS + ); + +BOOLEAN +SendFWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendFWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendSWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendSWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ); + +#ifdef SUPPORT_MU_BF +#if (SUPPORT_MU_BF == 1) +RT_STATUS +Beamforming_GetVHTGIDMgntFrame( + IN PADAPTER Adapter, + IN PRT_RFD pRfd, + IN POCTET_STRING pPduOS + ); + +BOOLEAN +SendSWVHTGIDMgntFrame( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u1Byte Idx + ); + +BOOLEAN +SendSWVHTBFReportPoll( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN BOOLEAN bFinalPoll + ); + +BOOLEAN +SendSWVHTMUNDPAPacket( + IN PVOID pDM_VOID, + IN CHANNEL_WIDTH BW + ); +#else +#define Beamforming_GetVHTGIDMgntFrame(Adapter, pRfd, pPduOS) RT_STATUS_FAILURE +#define SendSWVHTGIDMgntFrame(pDM_VOID, RA) +#define SendSWVHTBFReportPoll(pDM_VOID, RA, bFinalPoll) +#define SendSWVHTMUNDPAPacket(pDM_VOID, BW) +#endif +#endif + + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + +u4Byte +Beamforming_GetReportFrame( + IN PVOID pDM_VOID, + union recv_frame *precv_frame + ); + +BOOLEAN +SendFWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendSWHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendFWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ); + +BOOLEAN +SendSWVHTNDPAPacket( + IN PVOID pDM_VOID, + IN pu1Byte RA, + IN u2Byte AID, + IN CHANNEL_WIDTH BW + ); +#endif + +VOID +Beamforming_GetNDPAFrame( + IN PVOID pDM_VOID, +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + IN OCTET_STRING pduOS +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + union recv_frame *precv_frame +#endif +); + +#else +#define Beamforming_GetNDPAFrame(pDM_Odm, _PduOS) +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#define Beamforming_GetReportFrame(Adapter, precv_frame) RT_STATUS_FAILURE +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define Beamforming_GetReportFrame(Adapter, pRfd, pPduOS) RT_STATUS_FAILURE +#define Beamforming_GetVHTGIDMgntFrame(Adapter, pRfd, pPduOS) RT_STATUS_FAILURE +#endif +#define SendFWHTNDPAPacket(pDM_VOID, RA, BW) +#define SendSWHTNDPAPacket(pDM_VOID, RA, BW) +#define SendFWVHTNDPAPacket(pDM_VOID, RA, AID, BW) +#define SendSWVHTNDPAPacket(pDM_VOID, RA, AID, BW) +#define SendSWVHTGIDMgntFrame(pDM_VOID, RA, idx) +#define SendSWVHTBFReportPoll(pDM_VOID, RA, bFinalPoll) +#define SendSWVHTMUNDPAPacket(pDM_VOID, BW) +#endif + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.c new file mode 100644 index 00000000..2f18aa9b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.c @@ -0,0 +1,527 @@ +//============================================================ +// Description: +// +// This file is for 8812/8821/8811 TXBF mechanism +// +//============================================================ +#include "mp_precomp.h" +#include "../phydm_precomp.h" + +#if (BEAMFORMING_SUPPORT == 1) +#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1)) +VOID +HalTxbf8812A_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8812A, (Rate << 2 | BW)); + +} + +VOID +halTxbfJaguar_RfMode( + IN PVOID pDM_VOID, + IN PRT_BEAMFORMING_INFO pBeamInfo +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + + if (pDM_Odm->RFType == ODM_1T1R) + return; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] set TxIQGen\n", __func__)); + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x1); /*RF Mode table write enable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x1); /*RF Mode table write enable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) { + // Paath_A + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/ + // Path_B + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/ + } else { + // Paath_A + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/ + // Path_B + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3); /*Select RX mode*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF); /*Set Table data*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/ + } + + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x0); /*RF Mode table write disable*/ + ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x0); /*RF Mode table write disable*/ + + if (pBeamInfo->beamformee_su_cnt > 0) + ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x33); + else + ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x11); +} + + +VOID +halTxbfJaguar_DownloadNDPA( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte u1bTmp = 0, tmpReg422 = 0, Head_Page; + u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; + BOOLEAN bSendBeacon = FALSE; + u1Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812; /*default reseved 1 page for the IC type which is undefined.*/ + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + PADAPTER Adapter = pDM_Odm->Adapter; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + *pDM_Odm->pbFwDwRsvdPageInProgress = TRUE; +#endif + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (Idx == 0) + Head_Page = 0xFE; + else + Head_Page = 0xFE; + + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu1Byte)&TxPageBndy); + + /*Set REG_CR bit 8. DMA beacon by SW.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8812A + 1); + ODM_Write1Byte(pDM_Odm, REG_CR_8812A + 1, (u1bTmp | BIT0)); + + + /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ + tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2); + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmpReg422 & (~BIT6)); + + if (tmpReg422 & BIT6) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("SetBeamformDownloadNDPA_8812(): There is an Adapter is sending beacon.\n")); + bSendBeacon = TRUE; + } + + /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, Head_Page); + + do { + /*Clear beacon valid check bit.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 2, (BcnValidReg | BIT0)); + + /*download NDPA rsvd page.*/ + if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) + Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE); + else + Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); + + /*check rsvd page download OK.*/ + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + count = 0; + while (!(BcnValidReg & BIT0) && count < 20) { + count++; + ODM_delay_ms(10); + BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2); + } + DLBcnCount++; + } while (!(BcnValidReg & BIT0) && DLBcnCount < 5); + + if (!(BcnValidReg & BIT0)) + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__)); + + /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/ + ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, TxPageBndy); + + /*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 (bSendBeacon) + ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmpReg422); + + /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ + /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ + u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8812A + 1); + ODM_Write1Byte(pDM_Odm, REG_CR_8812A + 1, (u1bTmp & (~BIT0))); + + pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + *pDM_Odm->pbFwDwRsvdPageInProgress = FALSE; +#endif +} + + +VOID +halTxbfJaguar_FwTxBFCmd( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte Idx, Period0 = 0, Period1 = 0; + u1Byte PageNum0 = 0xFF, PageNum1 = 0xFF; + u1Byte u1TxBFParm[3] = {0}; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) { + /*Modified by David*/ + if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (Idx == 0) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum0 = 0xFE; + else + PageNum0 = 0xFF; /*stop sounding*/ + Period0 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } else if (Idx == 1) { + if (pBeamInfo->BeamformeeEntry[Idx].bSound) + PageNum1 = 0xFE; + else + PageNum1 = 0xFF; /*stop sounding*/ + Period1 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod); + } + } + } + + u1TxBFParm[0] = PageNum0; + u1TxBFParm[1] = PageNum1; + u1TxBFParm[2] = (Period1 << 4) | Period0; + ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_TXBF, 3, u1TxBFParm); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, + ("[%s] PageNum0 = %d Period0 = %d, PageNum1 = %d Period1 %d\n", __func__, PageNum0, Period0, PageNum1, Period1)); +} + + +VOID +HalTxbfJaguar_Enter( + IN PVOID pDM_VOID, + IN u1Byte BFerBFeeIdx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u1Byte i = 0; + u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; + u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); + u4Byte CSI_Param; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + RT_BEAMFORMER_ENTRY BeamformerEntry; + u2Byte STAid = 0; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__)); + + halTxbfJaguar_RfMode(pDM_Odm, pBeamformingInfo); + + if (pDM_Odm->RFType == ODM_2T2R) + ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x00000000); /*Nc =2*/ + else + ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x01081008); /*Nc =1*/ + + if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; + + /*Sounding protocol control*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xCB); + + /*MAC address/Partial AID of Beamformer*/ + if (BFerIdx == 0) { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_BFMER0_INFO_8812A + i), BeamformerEntry.MacAddr[i]); + /*CSI report use legacy ofdm so don't need to fill P_AID. */ + /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER0_INFO_8812A+6, BeamformEntry.P_AID); */ + } else { + for (i = 0; i < 6 ; i++) + ODM_Write1Byte(pDM_Odm, (REG_BFMER1_INFO_8812A + i), BeamformerEntry.MacAddr[i]); + /*CSI report use legacy ofdm so don't need to fill P_AID.*/ + /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER1_INFO_8812A+6, BeamformEntry.P_AID);*/ + } + + /*CSI report parameters of Beamformee*/ + if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) { + if (pDM_Odm->RFType == ODM_2T2R) + CSI_Param = 0x01090109; + else + CSI_Param = 0x01080108; + } else { + if (pDM_Odm->RFType == ODM_2T2R) + CSI_Param = 0x03090309; + else + CSI_Param = 0x03080308; + } + + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, CSI_Param); + ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, CSI_Param); + + /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/ + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A + 3, 0x50); + } + + + if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + STAid = BeamformeeEntry.MacId; + else + STAid = BeamformeeEntry.P_AID; + + /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ + if (BFeeIdx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A, STAid); + ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 3) | BIT4 | BIT6 | BIT7); + } else + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2, STAid | BIT12 | BIT14 | BIT15); + + /*CSI report parameters of Beamformee*/ + if (BFeeIdx == 0) { + /*Get BIT24 & BIT25*/ + u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3) & 0x3; + + ODM_Write1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, STAid | BIT9); + } else { + /*Set BIT25*/ + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, STAid | 0xE200); + } + phydm_Beamforming_Notify(pDM_Odm); + } +} + + +VOID +HalTxbfJaguar_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMER_ENTRY BeamformerEntry; + RT_BEAMFORMEE_ENTRY BeamformeeEntry; + + if (Idx < BEAMFORMER_ENTRY_NUM) { + BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx]; + BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx]; + } else + return; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, Idx)); + + /*Clear P_AID of Beamformee*/ + /*Clear MAC address of Beamformer*/ + /*Clear Associated Bfmee Sel*/ + + if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xC8); + if (Idx == 0) { + ODM_Write4Byte(pDM_Odm, REG_BFMER0_INFO_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_BFMER0_INFO_8812A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, 0); + } else { + ODM_Write4Byte(pDM_Odm, REG_BFMER1_INFO_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_BFMER1_INFO_8812A + 4, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, 0); + ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, 0); + } + } + + if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { + halTxbfJaguar_RfMode(pDM_Odm, pBeamformingInfo); + if (Idx == 0) { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A, 0x0); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, 0); + } else { + ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2) & 0xF000); + ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2) & 0x60); + } + } + +} + + +VOID +HalTxbfJaguar_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte BeamCtrlVal; + u4Byte BeamCtrlReg; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + RT_BEAMFORMEE_ENTRY BeamformEntry = pBeamInfo->BeamformeeEntry[Idx]; + + if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) + BeamCtrlVal = BeamformEntry.MacId; + else + BeamCtrlVal = BeamformEntry.P_AID; + + if (Idx == 0) + BeamCtrlReg = REG_TXBF_CTRL_8812A; + else { + BeamCtrlReg = REG_TXBF_CTRL_8812A + 2; + BeamCtrlVal |= BIT12 | BIT14 | BIT15; + } + + if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { + if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) + BeamCtrlVal |= BIT9; + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) + BeamCtrlVal |= (BIT9 | BIT10); + else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80) + BeamCtrlVal |= (BIT9 | BIT10 | BIT11); + } else + BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BeamCtrlVal = 0x%x!\n", __func__, BeamCtrlVal)); + + ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); +} + + + +VOID +HalTxbfJaguar_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING) + halTxbfJaguar_DownloadNDPA(pDM_Odm, Idx); + + halTxbfJaguar_FwTxBFCmd(pDM_Odm); +} + + +VOID +HalTxbfJaguar_Patch( + IN PVOID pDM_VOID, + IN u1Byte Operation +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (pBeamInfo->BeamformCap == BEAMFORMING_CAP_NONE) + return; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + if (Operation == SCAN_OPT_BACKUP_BAND0) + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xC8); + else if (Operation == SCAN_OPT_RESTORE) + ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xCB); +#endif +} + +VOID +HalTxbfJaguar_Clk_8812A( + IN PVOID pDM_VOID +) +{ + PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; + u2Byte u2btmp; + u1Byte Count = 0, u1btmp; + PADAPTER Adapter = pDM_Odm->Adapter; + + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); + + if (*(pDM_Odm->pbScanInProcess)) { + ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] return by Scan\n", __func__)); + return; + } +#if DEV_BUS_TYPE == RT_PCI_INTERFACE + /*Stop PCIe TxDMA*/ + ODM_Write1Byte(pDM_Odm, REG_PCIE_CTRL_REG_8812A + 1, 0xFE); +#endif + + /*Stop Usb TxDMA*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + RT_DISABLE_FUNC(Adapter, DF_TX_BIT); + PlatformReturnAllPendingTxPackets(Adapter); +#else + rtw_write_port_cancel(Adapter); +#endif + + /*Wait TXFF empty*/ + for (Count = 0; Count < 100; Count++) { + u2btmp = ODM_Read2Byte(pDM_Odm, REG_TXPKT_EMPTY_8812A); + u2btmp = u2btmp & 0xfff; + if (u2btmp != 0xfff) { + ODM_delay_ms(10); + continue; + } else + break; + } + + /*TX pause*/ + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE_8812A, 0xFF); + + /*Wait TX State Machine OK*/ + for (Count = 0; Count < 100; Count++) { + if (ODM_Read4Byte(pDM_Odm, REG_SCH_TXCMD_8812A) != 0) + continue; + else + break; + } + + + /*Stop RX DMA path*/ + u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A); + ODM_Write1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A, u1btmp | BIT2); + + for (Count = 0; Count < 100; Count++) { + u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A); + if (u1btmp & BIT1) + break; + else + ODM_delay_ms(10); + } + + /*Disable clock*/ + ODM_Write1Byte(pDM_Odm, REG_SYS_CLKR_8812A + 1, 0xf0); + /*Disable 320M*/ + ODM_Write1Byte(pDM_Odm, REG_AFE_PLL_CTRL_8812A + 3, 0x8); + /*Enable 320M*/ + ODM_Write1Byte(pDM_Odm, REG_AFE_PLL_CTRL_8812A + 3, 0xa); + /*Enable clock*/ + ODM_Write1Byte(pDM_Odm, REG_SYS_CLKR_8812A + 1, 0xfc); + + + /*Release Tx pause*/ + ODM_Write1Byte(pDM_Odm, REG_TXPAUSE_8812A, 0); + + /*Enable RX DMA path*/ + u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A); + ODM_Write1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A, u1btmp & (~BIT2)); +#if DEV_BUS_TYPE == RT_PCI_INTERFACE + /*Enable PCIe TxDMA*/ + ODM_Write1Byte(pDM_Odm, REG_PCIE_CTRL_REG_8812A + 1, 0); +#endif + /*Start Usb TxDMA*/ + RT_ENABLE_FUNC(Adapter, DF_TX_BIT); +} + +#endif + + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.h b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.h new file mode 100644 index 00000000..49a5fdff --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/phydm/txbf/haltxbfjaguar.h @@ -0,0 +1,67 @@ +#ifndef __HAL_TXBF_JAGUAR_H__ +#define __HAL_TXBF_JAGUAR_H__ + +#if (BEAMFORMING_SUPPORT == 1) +#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1)) +VOID +HalTxbf8812A_setNDPArate( + IN PVOID pDM_VOID, + IN u1Byte BW, + IN u1Byte Rate +); + + +VOID +HalTxbfJaguar_Enter( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbfJaguar_Leave( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbfJaguar_Status( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbfJaguar_FwTxBF( + IN PVOID pDM_VOID, + IN u1Byte Idx + ); + + +VOID +HalTxbfJaguar_Patch( + IN PVOID pDM_VOID, + IN u1Byte Operation + ); + + +VOID +HalTxbfJaguar_Clk_8812A( + IN PVOID pDM_VOID + ); + +#else + +#define HalTxbf8812A_setNDPArate(pDM_VOID, BW, Rate) +#define HalTxbfJaguar_Enter(pDM_VOID, Idx) +#define HalTxbfJaguar_Leave(pDM_VOID, Idx) +#define HalTxbfJaguar_Status(pDM_VOID, Idx) +#define HalTxbfJaguar_FwTxBF(pDM_VOID, Idx) +#define HalTxbfJaguar_Patch(pDM_VOID, Operation) +#define HalTxbfJaguar_Clk_8812A(pDM_VOID) +#endif + +#endif +#endif // #ifndef __HAL_TXBF_JAGUAR_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/Hal8188FPwrSeq.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/Hal8188FPwrSeq.c new file mode 100644 index 00000000..277f85b2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/Hal8188FPwrSeq.c @@ -0,0 +1,99 @@ + +/*++ +Copyright (c) Realtek Semiconductor Corp. All rights reserved. + +Module Name: + Hal8188FPwrSeq.c + +Abstract: + This file includes all kinds of Power Action event for RTL8188F and corresponding hardware configurtions which are released from HW SD. + +Major Change History: + When What + ------------------- --------------- + 2014-08-18 Create. + +--*/ + +#include "Hal8188FPwrSeq.h" + + +/* + drivers should parse below arrays and do the corresponding actions +*/ +/*3 Power on Array */ +WLAN_PWR_CFG rtl8188F_power_on_flow[RTL8188F_TRANS_CARDEMU_TO_ACT_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_CARDEMU_TO_ACT + RTL8188F_TRANS_END +}; + +/*3Radio off GPIO Array */ +WLAN_PWR_CFG rtl8188F_radio_off_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_ACT_TO_CARDEMU + RTL8188F_TRANS_END +}; + +/*3Card Disable Array */ +WLAN_PWR_CFG rtl8188F_card_disable_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_ACT_TO_CARDEMU + RTL8188F_TRANS_CARDEMU_TO_CARDDIS + RTL8188F_TRANS_END +}; + +/*3 Card Enable Array */ +WLAN_PWR_CFG rtl8188F_card_enable_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_CARDDIS_TO_CARDEMU + RTL8188F_TRANS_CARDEMU_TO_ACT + RTL8188F_TRANS_END +}; + +/*3Suspend Array */ +WLAN_PWR_CFG rtl8188F_suspend_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_ACT_TO_CARDEMU + RTL8188F_TRANS_CARDEMU_TO_SUS + RTL8188F_TRANS_END +}; + +/*3 Resume Array */ +WLAN_PWR_CFG rtl8188F_resume_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_CARDEMU_TO_SUS_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_SUS_TO_CARDEMU + RTL8188F_TRANS_CARDEMU_TO_ACT + RTL8188F_TRANS_END +}; + + + +/*3HWPDN Array */ +WLAN_PWR_CFG rtl8188F_hwpdn_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS + RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS + RTL8188F_TRANS_END_STEPS] = { + RTL8188F_TRANS_ACT_TO_CARDEMU + RTL8188F_TRANS_CARDEMU_TO_PDN + RTL8188F_TRANS_END +}; + +/*3 Enter LPS */ +WLAN_PWR_CFG rtl8188F_enter_lps_flow[RTL8188F_TRANS_ACT_TO_LPS_STEPS + RTL8188F_TRANS_END_STEPS] = { + /*FW behavior */ + RTL8188F_TRANS_ACT_TO_LPS + RTL8188F_TRANS_END +}; + +/*3 Leave LPS */ +WLAN_PWR_CFG rtl8188F_leave_lps_flow[RTL8188F_TRANS_LPS_TO_ACT_STEPS + RTL8188F_TRANS_END_STEPS] = { + /*FW behavior */ + RTL8188F_TRANS_LPS_TO_ACT + RTL8188F_TRANS_END +}; + +/*3 Enter SW LPS */ +WLAN_PWR_CFG rtl8188F_enter_swlps_flow[RTL8188F_TRANS_ACT_TO_SWLPS_STEPS + RTL8188F_TRANS_END_STEPS] = { + /*SW behavior */ + RTL8188F_TRANS_ACT_TO_SWLPS + RTL8188F_TRANS_END +}; + +/*3 Leave SW LPS */ +WLAN_PWR_CFG rtl8188F_leave_swlps_flow[RTL8188F_TRANS_SWLPS_TO_ACT_STEPS + RTL8188F_TRANS_END_STEPS] = { + /*SW behavior */ + RTL8188F_TRANS_SWLPS_TO_ACT + RTL8188F_TRANS_END +}; diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_cmd.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_cmd.c new file mode 100644 index 00000000..d7b77606 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_cmd.c @@ -0,0 +1,1313 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8188F_CMD_C_ + +#include +#include "hal_com_h2c.h" + +#define MAX_H2C_BOX_NUMS 4 +#define MESSAGE_BOX_SIZE 4 + +#define RTL8188F_MAX_CMD_LEN 7 +#define RTL8188F_EX_MESSAGE_BOX_SIZE 4 + +static u8 _is_fw_read_cmd_down(_adapter *padapter, u8 msgbox_num) +{ + u8 read_down = _FALSE; + int retry_cnts = 100; + + u8 valid; + + /*DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num); */ + + do { + valid = rtw_read8(padapter, REG_HMETFR) & BIT(msgbox_num); + if (0 == valid) + read_down = _TRUE; + else + rtw_msleep_os(1); + } while ((!read_down) && (retry_cnts--)); + + return read_down; + +} + + +/***************************************** +* H2C Msg format : +*| 31 - 8 |7-5 | 4 - 0 | +*| h2c_msg |Class |CMD_ID | +*| 31-0 | +*| Ext msg | +* +******************************************/ +s32 FillH2CCmd8188F(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) +{ + u8 h2c_box_num; + u32 msgbox_addr; + u32 msgbox_ex_addr = 0; + PHAL_DATA_TYPE pHalData; + u32 h2c_cmd = 0; + u32 h2c_cmd_ex = 0; + s32 ret = _FAIL; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + _func_enter_; + + padapter = GET_PRIMARY_ADAPTER(padapter); + pHalData = GET_HAL_DATA(padapter); +#ifdef DBG_CHECK_FW_PS_STATE +#ifdef DBG_CHECK_FW_PS_STATE_H2C + if (rtw_fw_ps_state(padapter) == _FAIL) { + DBG_871X("%s: h2c doesn't leave 32k ElementID=%02x\n", __func__, ElementID); + pdbgpriv->dbg_h2c_leave32k_fail_cnt++; + } + + /*DBG_871X("H2C ElementID=%02x , pHalData->LastHMEBoxNum=%02x\n", ElementID, pHalData->LastHMEBoxNum); */ +#endif /*DBG_CHECK_FW_PS_STATE_H2C */ +#endif /*DBG_CHECK_FW_PS_STATE */ + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); + + if (!pCmdBuffer) + goto exit; + if (CmdLen > RTL8188F_MAX_CMD_LEN) + goto exit; + if (rtw_is_surprise_removed(padapter)) + goto exit; + + /*pay attention to if race condition happened in H2C cmd setting. */ + do { + h2c_box_num = pHalData->LastHMEBoxNum; + + if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) { + DBG_8192C(" fw read cmd failed...\n"); +#ifdef DBG_CHECK_FW_PS_STATE + 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 */ + /*DBG_8192C(" 0x1c0: 0x%8x\n", rtw_read32(padapter, 0x1c0)); */ + /*DBG_8192C(" 0x1c4: 0x%8x\n", rtw_read32(padapter, 0x1c4)); */ + goto exit; + } + + if (CmdLen <= 3) + _rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen); + else { + _rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3); + _rtw_memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, CmdLen - 3); + /**(u8*)(&h2c_cmd) |= BIT(7); */ + } + + *(u8 *)(&h2c_cmd) |= ElementID; + + if (CmdLen > 3) { + msgbox_ex_addr = REG_HMEBOX_EXT0_8188F + (h2c_box_num * RTL8188F_EX_MESSAGE_BOX_SIZE); + h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex); + rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex); + } + msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * MESSAGE_BOX_SIZE); + h2c_cmd = le32_to_cpu(h2c_cmd); + rtw_write32(padapter, msgbox_addr, h2c_cmd); + + /*DBG_8192C("MSG_BOX:%d, CmdLen(%d), CmdID(0x%x), reg:0x%x =>h2c_cmd:0x%.8x, reg:0x%x =>h2c_cmd_ex:0x%.8x\n" */ + /* ,pHalData->LastHMEBoxNum , CmdLen, ElementID, msgbox_addr, h2c_cmd, msgbox_ex_addr, h2c_cmd_ex); */ + + pHalData->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS; + + } while (0); + + ret = _SUCCESS; + +exit: + + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); + + _func_exit_; + + return ret; +} + +static void ConstructBeacon(_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", __func__); */ + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), 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", __func__, pktlen); */ + +} + +static void ConstructPSPoll(_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", __func__); */ + + 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, adapter_mac_addr(padapter), ETH_ALEN); + + *pLength = 16; +} + +static void ConstructNullFunctionData( + 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", __func__, 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, adapter_mac_addr(padapter), 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, adapter_mac_addr(padapter), ETH_ALEN); + break; + case Ndis802_11IBSS: + default: + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), 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; +} + +/* To check if reserved page content is destroyed by beacon because beacon is too large. */ +/* 2010.06.23. Added by tynli. */ +VOID +CheckFwRsvdPageContent( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 MaxBcnPageNum; + + if (pHalData->FwRsvdPageStartOffset != 0) { + /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize); + RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset), + ("CheckFwRsvdPageContent(): The reserved page content has been"\ + "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!", + MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/ + } +} + +/* */ +/* Description: Get the reserved page number in Tx packet buffer. */ +/* Retrun value: the page number. */ +/* 2012.08.09, by tynli. */ +/* */ +u8 GetTxBufferRsvdPageNum8188F(_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_8188F; + + rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy); + + RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8188F - TxPageBndy + 1; + + return RsvdPageNum; +} + +static void rtl8188f_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) +{ + u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0}; + + DBG_871X("8188FRsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n", + rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll, + rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull, + rsvdpageloc->LocBTQosNull); + + SET_8188F_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp); + SET_8188F_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll); + SET_8188F_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData); + SET_8188F_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull); + SET_8188F_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN); + FillH2CCmd8188F(padapter, H2C_8188F_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm); +} + +static void rtl8188f_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 res = 0, count = 0; +#ifdef CONFIG_WOWLAN + u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0}; + + DBG_871X("8188FAOACRsvdPageLoc: 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 */ + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN); + FillH2CCmd8188F(padapter, H2C_8188F_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm); + } else { +#ifdef CONFIG_PNO_SUPPORT + 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); + FillH2CCmd8188F(padapter, H2C_AOAC_RSVDPAGE3, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm); + rtw_msleep_os(10); + } +#endif + } + +#endif /* CONFIG_WOWLAN */ +} + +static void rtl8188f_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type) +{ + u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0}; + 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_8188F_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable); + SET_8188F_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt); + SET_8188F_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type); + SET_8188F_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CKeepAliveParm:", u1H2CKeepAliveParm, H2C_KEEP_ALIVE_CTRL_LEN); + + FillH2CCmd8188F(padapter, H2C_8188F_KEEP_ALIVE, H2C_KEEP_ALIVE_CTRL_LEN, u1H2CKeepAliveParm); +} + +static void rtl8188f_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable) +{ + u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0}; + u8 adopt = 1, check_period = 10, trypkt_num = 0; + + DBG_871X("%s(): benable = %d\n", __func__, benable); + SET_8188F_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, benable); + SET_8188F_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt); + SET_8188F_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period); + SET_8188F_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CDisconDecisionParm:", u1H2CDisconDecisionParm, H2C_DISCON_DECISION_LEN); + + FillH2CCmd8188F(padapter, H2C_8188F_DISCON_DECISION, H2C_DISCON_DECISION_LEN, u1H2CDisconDecisionParm); +} + +void rtl8188f_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); + + _func_enter_; + + SET_8188F_H2CCMD_MACID_CFG_MACID(u1H2CMacIdConfigParm, mac_id); + SET_8188F_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid); + SET_8188F_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi) ? 1 : 0); + SET_8188F_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw); + + /*DisableTXPowerTraining */ + if (pHalData->bDisableTXPowerTraining) { + SET_8188F_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm, 1); + DBG_871X("%s,Disable PWT by driver\n", __func__); + } else { + PDM_ODM_T pDM_OutSrc = &pHalData->odmpriv; + + if (pDM_OutSrc->bDisablePowerTraining) { + SET_8188F_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm, 1); + DBG_871X("%s,Disable PWT by DM\n", __func__); + } + } + + SET_8188F_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff)); + SET_8188F_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >> 8)); + SET_8188F_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16)); + SET_8188F_H2CCMD_MACID_CFG_RATE_MASK3(u1H2CMacIdConfigParm, (u8)((mask & 0xff000000) >> 24)); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMacIdConfigParm:", u1H2CMacIdConfigParm, H2C_MACID_CFG_LEN); + FillH2CCmd8188F(padapter, H2C_8188F_MACID_CFG, H2C_MACID_CFG_LEN, u1H2CMacIdConfigParm); + + _func_exit_; +} + +void rtl8188f_set_FwRssiSetting_cmd(_adapter *padapter, u8 *param) +{ + u8 u1H2CRssiSettingParm[H2C_RSSI_SETTING_LEN] = {0}; + u8 mac_id = *param; + u8 rssi = *(param + 2); + u8 uldl_state = 0; + + _func_enter_; + /*DBG_871X("%s(): param=%.2x-%.2x-%.2x\n", __func__, *param, *(param+1), *(param+2)); */ + /*DBG_871X("%s(): mac_id=%d rssi=%d\n", __func__, mac_id, rssi); */ + + SET_8188F_H2CCMD_RSSI_SETTING_MACID(u1H2CRssiSettingParm, mac_id); + SET_8188F_H2CCMD_RSSI_SETTING_RSSI(u1H2CRssiSettingParm, rssi); + SET_8188F_H2CCMD_RSSI_SETTING_ULDL_STATE(u1H2CRssiSettingParm, uldl_state); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "u1H2CRssiSettingParm:", u1H2CRssiSettingParm, H2C_RSSI_SETTING_LEN); + FillH2CCmd8188F(padapter, H2C_8188F_RSSI_SETTING, H2C_RSSI_SETTING_LEN, u1H2CRssiSettingParm); + + _func_exit_; +} + +void rtl8188f_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack) +{ + u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN] = {0}; + u8 macid1 = 1, macid2 = 0; + + DBG_871X("%s(): need_ack = %d\n", __func__, need_ack); + + SET_8188F_H2CCMD_APREQRPT_PARM_MACID1(u1H2CApReqRptParm, macid1); + SET_8188F_H2CCMD_APREQRPT_PARM_MACID2(u1H2CApReqRptParm, macid2); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CApReqRptParm:", u1H2CApReqRptParm, H2C_AP_REQ_TXRPT_LEN); + FillH2CCmd8188F(padapter, H2C_8188F_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm); +} + +void rtl8188f_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); + + if (psmode == PS_MODE_MIN) { + rlbm = 0; + awake_intvl = 2; + smart_ps = pwrpriv->smart_ps; + } 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 + awake_intvl = 4;/*DTIM=3 */ + + + 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 = 1; + } +#endif /* CONFIG_P2P */ + + if (padapter->registrypriv.wifi_spec == 1) { + awake_intvl = 2; + rlbm = 1; + } + + if (psmode > 0) { +#ifdef CONFIG_BT_COEXIST + if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE) { + PowerState = rtw_btcoex_RpwmVal(padapter); + byte5 = rtw_btcoex_LpsVal(padapter); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from */ + /* decreasing coex performance */ + awake_intvl = 2; + rlbm = 2; + } + } else +#endif /* CONFIG_BT_COEXIST */ + { + PowerState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + byte5 = 0x40; + } + } else { + PowerState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */ + byte5 = 0x40; + } + + SET_8188F_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode > 0) ? 1 : 0); + SET_8188F_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, smart_ps); + SET_8188F_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm); + SET_8188F_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl); + SET_8188F_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable); + SET_8188F_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CPwrModeParm, PowerState); + SET_8188F_H2CCMD_PWRMODE_PARM_BYTE5(u1H2CPwrModeParm, byte5); +#ifdef CONFIG_LPS_LCLK + if (psmode != PS_MODE_ACTIVE) { + if (pmlmeext->adaptive_tsf_done == _FALSE && pmlmeext->bcn_cnt > 0) { + u8 ratio_20_delay, ratio_80_delay; + + /*byte 6 for adaptive_early_32k */ + /*[0:3] = DrvBcnEarly (ms) , [4:7] = DrvBcnTimeOut (ms) */ + /* 20% for DrvBcnEarly, 80% for DrvBcnTimeOut */ + ratio_20_delay = 0; + ratio_80_delay = 0; + pmlmeext->DrvBcnEarly = 0xff; + pmlmeext->DrvBcnTimeOut = 0xff; + + /*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]); */ + + ratio_20_delay += pmlmeext->bcn_delay_ratio[i]; + ratio_80_delay += pmlmeext->bcn_delay_ratio[i]; + + if (ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff) { + pmlmeext->DrvBcnEarly = i; + /*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); */ + } + + /*reset adaptive_early_32k cnt */ + pmlmeext->bcn_delay_cnt[i] = 0; + pmlmeext->bcn_delay_ratio[i] = 0; + + } + + pmlmeext->bcn_cnt = 0; + pmlmeext ->adaptive_tsf_done = _TRUE; + + } else { + /*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 + pmlmeext->DrvBcnEarly=0; + pmlmeext->DrvBcnTimeOut=7; + + if((pmlmeext->DrvBcnEarly!=0Xff) && (pmlmeext->DrvBcnTimeOut!=0xff)) + u1H2CPwrModeParm[H2C_PWRMODE_LEN-1] = BIT(0) | ((pmlmeext->DrvBcnEarly<<1)&0x0E) |((pmlmeext->DrvBcnTimeOut<<4)&0xf0); + */ + + } +#endif + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_RecordPwrMode(padapter, u1H2CPwrModeParm, H2C_PWRMODE_LEN); +#endif /* CONFIG_BT_COEXIST */ + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPwrModeParm:", u1H2CPwrModeParm, H2C_PWRMODE_LEN); + + FillH2CCmd8188F(padapter, H2C_8188F_SET_PWR_MODE, H2C_PWRMODE_LEN, u1H2CPwrModeParm); + _func_exit_; +} + +void rtl8188f_set_FwPsTuneParam_cmd(PADAPTER padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 u1H2CPsTuneParm[H2C_PSTUNEPARAM_LEN] = {0}; + u8 bcn_to_limit = 10; /*10 * 100 * awakeinterval (ms) */ + u8 dtim_timeout = 5; /*ms //wait broadcast data timer */ + u8 ps_timeout = 20; /*ms //Keep awake when tx */ + u8 dtim_period = 3; + + _func_enter_; + /*DBG_871X("%s(): FW LPS mode = %d\n", __func__, psmode); */ + + SET_8188F_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(u1H2CPsTuneParm, bcn_to_limit); + SET_8188F_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(u1H2CPsTuneParm, dtim_timeout); + SET_8188F_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(u1H2CPsTuneParm, ps_timeout); + SET_8188F_H2CCMD_PSTUNE_PARM_ADOPT(u1H2CPsTuneParm, 1); + SET_8188F_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(u1H2CPsTuneParm, dtim_period); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPsTuneParm:", u1H2CPsTuneParm, H2C_PSTUNEPARAM_LEN); + + FillH2CCmd8188F(padapter, H2C_8188F_PS_TUNING_PARA, H2C_PSTUNEPARAM_LEN, u1H2CPsTuneParm); + _func_exit_; +} + +void rtl8188f_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param) +{ + u8 u1H2CBtMpOperParm[H2C_BTMP_OPER_LEN] = {0}; + + _func_enter_; + + DBG_8192C("%s: idx=%d ver=%d reqnum=%d param1=0x%02x param2=0x%02x\n", __func__, idx, ver, reqnum, param[0], param[1]); + + SET_8188F_H2CCMD_BT_MPOPER_VER(u1H2CBtMpOperParm, ver); + SET_8188F_H2CCMD_BT_MPOPER_REQNUM(u1H2CBtMpOperParm, reqnum); + SET_8188F_H2CCMD_BT_MPOPER_IDX(u1H2CBtMpOperParm, idx); + SET_8188F_H2CCMD_BT_MPOPER_PARAM1(u1H2CBtMpOperParm, param[0]); + SET_8188F_H2CCMD_BT_MPOPER_PARAM2(u1H2CBtMpOperParm, param[1]); + SET_8188F_H2CCMD_BT_MPOPER_PARAM3(u1H2CBtMpOperParm, param[2]); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CBtMpOperParm:", u1H2CBtMpOperParm, H2C_BTMP_OPER_LEN); + + FillH2CCmd8188F(padapter, H2C_8188F_BT_MP_OPER, H2C_BTMP_OPER_LEN, u1H2CBtMpOperParm); + _func_exit_; +} + +void rtl8188f_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param) +{ + /*u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k */ + + DBG_871X("%s()\n", __func__); + + cmd_param = cmd_param; + + FillH2CCmd8188F(padapter, H2C_8188F_FWLPS_IN_IPS_, 1, &cmd_param); + +} + + +static s32 rtl8188f_set_FwLowPwrLps_cmd(PADAPTER padapter, u8 enable) +{ + /*TODO */ + return _FALSE; +} + + +void rtl8188f_download_rsvd_page(PADAPTER padapter, u8 mstatus) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + BOOLEAN bcn_valid = _FALSE; + u8 DLBcnCount = 0; + u32 poll = 0; + u8 val8; + + _func_enter_; + + DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n", + FUNC_ADPT_ARG(padapter), get_iface_type(padapter), 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(padapter, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid)); + + /* set REG_CR bit 8 */ + v8 = rtw_read8(padapter, REG_CR + 1); + v8 |= BIT(0); /* ENSWBCN */ + rtw_write8(padapter, 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(padapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, 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(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl & ~BIT(6)); + pHalData->RegFwHwTxQCtrl &= ~BIT(6); + + /* Clear beacon valid check bit. */ + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + + DLBcnCount = 0; + poll = 0; + do { + rtw_hal_set_fw_rsvd_page(padapter, 0); + + DLBcnCount++; + do { + rtw_yield_os(); + /*rtw_mdelay_os(10); */ + /* check rsvd page download OK. */ + rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid)); + poll++; + } while (!bcn_valid && (poll%10) != 0 && !RTW_CANNOT_RUN(padapter)); + + } while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter)); + + if (RTW_CANNOT_RUN(padapter)) + ; + else if (!bcn_valid) + DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n", + ADPT_ARG(padapter) , DLBcnCount, poll); + else { + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + pwrctl->fw_psmode_iface_id = padapter->iface_id; + DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n", + ADPT_ARG(padapter), DLBcnCount, poll); + } + + /* 2010.05.11. Added by tynli. */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= EN_BCN_FUNCTION; + val8 &= ~DIS_TSF_UDT; + rtw_write8(padapter, 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(padapter, 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(padapter, REG_CR + 1); + v8 &= ~BIT(0); /* ~ENSWBCN */ + rtw_write8(padapter, REG_CR + 1, v8); + } + + _func_exit_; +} + +void rtl8188f_set_rssi_cmd(_adapter *padapter, u8 *param) +{ + rtl8188f_set_FwRssiSetting_cmd(padapter, param); +} + +void rtl8188f_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus) +{ + struct sta_info *psta = NULL; + struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if (mstatus == 1) + rtl8188f_download_rsvd_page(padapter, RT_MEDIA_CONNECT); +} + +/*arg[0] = macid */ +/*arg[1] = raid */ +/*arg[2] = shortGIrate */ +/*arg[3] = init_rate */ +void rtl8188f_Add_RateATid(PADAPTER pAdapter, u64 rate_bitmap, u8 *arg, u8 rssi_level) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct macid_ctl_t *macid_ctl = &pAdapter->dvobj->macid_ctl; + struct sta_info *psta = NULL; + u8 mac_id = arg[0]; + u8 raid = arg[1]; + u8 shortGI = arg[2]; + u8 bw; + u32 bitmap = (u32) rate_bitmap; + u32 mask = bitmap & 0x0FFFFFFF; + + if (mac_id < macid_ctl->num) + psta = macid_ctl->sta[mac_id]; + if (psta == NULL) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u, sta is NULL\n" + , FUNC_ADPT_ARG(pAdapter), mac_id); + return; + } + + bw = psta->bw_mode; + + if (rssi_level != DM_RATR_STA_INIT) + mask = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level); + + DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask); + rtl8188f_set_FwMacIdConfig_cmd(pAdapter, mac_id, raid, bw, shortGI, mask); +} + +#if 0 +void rtl8188f_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack) +{ + rtl8188f_set_FwAPReqRPT_cmd(padapter, need_ack); +} +#endif + +#ifdef CONFIG_BT_COEXIST +static void ConstructBtNullFunctionData( + 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_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + u8 bssid[ETH_ALEN]; + + + DBG_871X("+" FUNC_ADPT_FMT ": qos=%d eosp=%d ps=%d\n", + FUNC_ADPT_ARG(padapter), bQoS, bEosp, bForcePowerSave); + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + if (NULL == StaAddr) { + _rtw_memcpy(bssid, myid(&padapter->eeprompriv), ETH_ALEN); + StaAddr = bssid; + } + + fctrl = &pwlanhdr->frame_ctl; + *fctrl = 0; + if (bForcePowerSave) + SetPwrMgt(fctrl); + + SetFrDs(fctrl); + _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN); + + SetDuration(pwlanhdr, 0); + 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; +} + +static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter) +{ + 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; + u32 BeaconLength = 0; + u32 BTQosNullLength = 0; + u8 *ReservedPagePacket; + u8 TxDescLen, TxDescOffset; + u8 TotalPageNum = 0, CurtPktPageNum = 0, RsvdPageNum = 0; + u16 BufIndex, PageSize; + u32 TotalPacketLen, MaxRsvdPageBufSize = 0; + RSVDPAGE_LOC RsvdPageLoc; + + + /*DBG_8192C("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter)); */ + + pHalData = GET_HAL_DATA(padapter); + pxmitpriv = &padapter->xmitpriv; + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + TxDescLen = TXDESC_SIZE; + TxDescOffset = TXDESC_OFFSET; + PageSize = PAGE_SIZE_TX_8188F; + + RsvdPageNum = BCNQ_PAGE_NUM_8188F; + MaxRsvdPageBufSize = RsvdPageNum * PageSize; + + pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv); + if (pcmdframe == NULL) { + DBG_8192C("%s: alloc ReservedPagePacket fail!\n", __func__); + return; + } + + ReservedPagePacket = pcmdframe->buf_addr; + _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC)); + + /*3 (1) beacon */ + BufIndex = TxDescOffset; + ConstructBeacon(padapter, &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); + + /* Jump to lastest page */ + if (BufIndex < (MaxRsvdPageBufSize - PageSize)) { + BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize); + TotalPageNum = BCNQ_PAGE_NUM_8188F - 1; + } + + /*3 (6) BT Qos null data */ + RsvdPageLoc.LocBTQosNull = TotalPageNum; + ConstructBtNullFunctionData( + padapter, + &ReservedPagePacket[BufIndex], + &BTQosNullLength, + NULL, + _TRUE, 0, 0, _FALSE); + rtl8188f_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex - TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE); + + CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength); + + TotalPageNum += CurtPktPageNum; + + TotalPacketLen = BufIndex + BTQosNullLength; + if (TotalPacketLen > MaxRsvdPageBufSize) { + DBG_8192C(FUNC_ADPT_FMT ": ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n", + FUNC_ADPT_ARG(padapter), TotalPacketLen, MaxRsvdPageBufSize); + goto error; + } + + /* update attribute */ + pattrib = &pcmdframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->qsel = QSLT_BEACON; + pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset; +#ifdef CONFIG_PCI_HCI + dump_mgntframe(padapter, pcmdframe); +#else + dump_mgntframe_and_wait(padapter, pcmdframe, 100); +#endif + + /*DBG_8192C(FUNC_ADPT_FMT ": Set RSVD page location to Fw, TotalPacketLen(%d), TotalPageNum(%d)\n", */ + /* FUNC_ADPT_ARG(padapter), TotalPacketLen, TotalPageNum); */ + rtl8188f_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc); + rtl8188f_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc); + + return; + +error: + rtw_free_xmitframe(pxmitpriv, pcmdframe); +} + +void rtl8188f_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + u8 bRecover = _FALSE; + u8 bcn_valid = _FALSE; + u8 DLBcnCount = 0; + u32 poll = 0; + u8 val8; + + + DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d fw_state=0x%08X\n", + FUNC_ADPT_ARG(padapter), get_iface_type(padapter), get_fwstate(&padapter->mlmepriv)); + +#ifdef CONFIG_DEBUG + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _FALSE) { + DBG_8192C(FUNC_ADPT_FMT ": [WARNING] not in AP mode!!\n", + FUNC_ADPT_ARG(padapter)); + } +#endif /* CONFIG_DEBUG */ + + pHalData = GET_HAL_DATA(padapter); + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + /* 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(padapter, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid)); + + /* set REG_CR bit 8 */ + val8 = rtw_read8(padapter, REG_CR + 1); + val8 |= BIT(0); /* ENSWBCN */ + rtw_write8(padapter, REG_CR + 1, val8); + + /* 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(padapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, 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. */ + pHalData->RegFwHwTxQCtrl &= ~BIT(6); + rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); + + /* Clear beacon valid check bit. */ + rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + + DLBcnCount = 0; + poll = 0; + do { + SetFwRsvdPagePkt_BTCoex(padapter); + DLBcnCount++; + do { + rtw_yield_os(); + /*rtw_mdelay_os(10); */ + /* check rsvd page download OK. */ + rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, &bcn_valid); + poll++; + } while (!bcn_valid && (poll % 10) != 0 && !RTW_CANNOT_RUN(padapter)); + } while (!bcn_valid && (DLBcnCount <= 100) && !RTW_CANNOT_RUN(padapter)); + + if (_TRUE == bcn_valid) { + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + pwrctl->fw_psmode_iface_id = padapter->iface_id; + DBG_8192C(ADPT_FMT": DL RSVD page success! DLBcnCount:%d, poll:%d\n", + ADPT_ARG(padapter), DLBcnCount, poll); + } else { + DBG_871X(ADPT_FMT": DL RSVD page fail! DLBcnCount:%d, poll:%d\n", + ADPT_ARG(padapter), DLBcnCount, poll); + DBG_871X(ADPT_FMT": DL RSVD page fail! bSurpriseRemoved=%s\n", + ADPT_ARG(padapter), rtw_is_surprise_removed(padapter)?"True":"False"); + DBG_871X(ADPT_FMT": DL RSVD page fail! bDriverStopped=%s\n", + ADPT_ARG(padapter), rtw_is_drv_stopped(padapter)?"True":"False"); + } + + /* 2010.05.11. Added by tynli. */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= EN_BCN_FUNCTION; + val8 &= ~DIS_TSF_UDT; + rtw_write8(padapter, 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) { + pHalData->RegFwHwTxQCtrl |= BIT(6); + rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); + } + + /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */ + val8 = rtw_read8(padapter, REG_CR + 1); + val8 &= ~BIT(0); /* ~ENSWBCN */ + rtw_write8(padapter, REG_CR + 1, val8); +} +#endif /* CONFIG_BT_COEXIST */ + +#ifdef CONFIG_P2P +void rtl8188f_set_p2p_ps_offload_cmd(_adapter *padapter, u8 p2p_ps_state) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload); + u8 i; + + _func_enter_; + +#if 1 + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + DBG_8192C("P2P_PS_DISABLE\n"); + _rtw_memset(p2p_ps_offload, 0 , 1); + break; + case P2P_PS_ENABLE: + DBG_8192C("P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (pwdinfo->ctwindow > 0) { + p2p_ps_offload->CTWindow_En = 1; + rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow); + } + + /* hw only support 2 set of NoA */ + for (i = 0; i < pwdinfo->noa_num; i++) { + /* To control the register setting for which NOA */ + rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4)); + if (i == 0) + p2p_ps_offload->NoA0_En = 1; + else + p2p_ps_offload->NoA1_En = 1; + + /* config P2P NoA Descriptor Register */ + /*DBG_8192C("%s(): noa_duration = %x\n",__func__,pwdinfo->noa_duration[i]); */ + rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]); + + /*DBG_8192C("%s(): noa_interval = %x\n",__func__,pwdinfo->noa_interval[i]); */ + rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]); + + /*DBG_8192C("%s(): start_time = %x\n",__func__,pwdinfo->noa_start_time[i]); */ + rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]); + + /*DBG_8192C("%s(): noa_count = %x\n",__func__,pwdinfo->noa_count[i]); */ + rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]); + } + + if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4)); + + p2p_ps_offload->Offload_En = 1; + + if (pwdinfo->role == P2P_ROLE_GO) { + p2p_ps_offload->role = 1; + p2p_ps_offload->AllStaSleep = 0; + } else + p2p_ps_offload->role = 0; + + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + DBG_8192C("P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + DBG_8192C("P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + pwdinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + FillH2CCmd8188F(padapter, H2C_8188F_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); +#endif + + _func_exit_; + +} +#endif /*CONFIG_P2P */ + + +#ifdef CONFIG_TSF_RESET_OFFLOAD +/* + ask FW to Reset sync register at Beacon early interrupt +*/ +u8 rtl8188f_reset_tsf(_adapter *padapter, u8 reset_port) +{ + u8 buf[2]; + u8 res = _SUCCESS; + + _func_enter_; + if (IFACE_PORT0 == reset_port) { + buf[0] = 0x1; + buf[1] = 0; + + } else { + buf[0] = 0x0; + buf[1] = 0x1; + } + FillH2CCmd8188F(padapter, H2C_8188F_RESET_TSF, 2, buf); + _func_exit_; + + return res; +} +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_dm.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_dm.c new file mode 100644 index 00000000..748bb1b8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_dm.c @@ -0,0 +1,623 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +/*============================================================ */ +/* Description: */ +/* */ +/* This file is for 92CE/92CU dynamic mechanism only */ +/* */ +/* */ +/*============================================================ */ +#define _RTL8188F_DM_C_ + +/*============================================================ */ +/* include files */ +/*============================================================ */ +#include + +/*============================================================ */ +/* Global var */ +/*============================================================ */ + + +static VOID +dm_CheckProtection( + IN PADAPTER Adapter +) +{ +#if 0 + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + u1Byte CurRate, RateThreshold; + + if (pMgntInfo->pHTInfo->bCurBW40MHz) + RateThreshold = MGN_MCS1; + else + RateThreshold = MGN_MCS3; + + if (Adapter->TxStats.CurrentInitTxRate <= RateThreshold) { + pMgntInfo->bDmDisableProtect = TRUE; + DbgPrint("Forced disable protect: %x\n", Adapter->TxStats.CurrentInitTxRate); + } else { + pMgntInfo->bDmDisableProtect = FALSE; + DbgPrint("Enable protect: %x\n", Adapter->TxStats.CurrentInitTxRate); + } +#endif +} + +static VOID +dm_CheckStatistics( + IN PADAPTER Adapter +) +{ +#if 0 + if (!Adapter->MgntInfo.bMediaConnect) + return; + + /*2008.12.10 tynli Add for getting Current_Tx_Rate_Reg flexibly. */ + rtw_hal_get_hwreg(Adapter, HW_VAR_INIT_TX_RATE, (pu1Byte)(&Adapter->TxStats.CurrentInitTxRate)); + + /* Calculate current Tx Rate(Successful transmited!!) */ + + /* Calculate current Rx Rate(Successful received!!) */ + + /*for tx tx retry count */ + rtw_hal_get_hwreg(Adapter, HW_VAR_RETRY_COUNT, (pu1Byte)(&Adapter->TxStats.NumTxRetryCount)); +#endif +} +#ifdef CONFIG_SUPPORT_HW_WPS_PBC +static void dm_CheckPbcGPIO(_adapter *padapter) +{ + u8 tmp1byte; + u8 bPbcPressed = _FALSE; + + if (!padapter->registrypriv.hw_wps_pbc) + return; + +#ifdef CONFIG_USB_HCI + tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); + tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /*enable GPIO[2] as output mode */ + + tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IN, tmp1byte); /*reset the floating voltage level */ + + tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); + tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); + rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /*enable GPIO[2] as input mode */ + + tmp1byte = rtw_read8(padapter, GPIO_IN); + + if (tmp1byte == 0xff) + return; + + if (tmp1byte & HAL_8192C_HW_GPIO_WPS_BIT) + bPbcPressed = _TRUE; +#else + tmp1byte = rtw_read8(padapter, GPIO_IN); + /*RT_TRACE(COMP_IO, DBG_TRACE, ("dm_CheckPbcGPIO - %x\n", tmp1byte)); */ + + if (tmp1byte == 0xff || padapter->init_adpt_in_progress) + return; + + if ((tmp1byte & HAL_8192C_HW_GPIO_WPS_BIT) == 0) + bPbcPressed = _TRUE; +#endif + + if (_TRUE == bPbcPressed) { + /* Here we only set bPbcPressed to true */ + /* After trigger PBC, the variable will be set to false */ + DBG_8192C("CheckPbcGPIO - PBC is pressed\n"); + rtw_request_wps_pbc_event(padapter); + } +} +#endif /*#ifdef CONFIG_SUPPORT_HW_WPS_PBC */ + + +#ifdef CONFIG_PCI_HCI +/* */ +/* Description: */ +/* Perform interrupt migration dynamically to reduce CPU utilization. */ +/* */ +/* Assumption: */ +/* 1. Do not enable migration under WIFI test. */ +/* */ +/* Created by Roger, 2010.03.05. */ +/* */ +VOID +dm_InterruptMigration( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + BOOLEAN bCurrentIntMt, bCurrentACIntDisable; + BOOLEAN IntMtToSet = _FALSE; + BOOLEAN ACIntToSet = _FALSE; + + + /* Retrieve current interrupt migration and Tx four ACs IMR settings first. */ + bCurrentIntMt = pHalData->bInterruptMigration; + bCurrentACIntDisable = pHalData->bDisableTxInt; + + /* */ + /* Currently we use busy traffic for reference instead of RxIntOK counts to prevent non-linear Rx statistics */ + /* when interrupt migration is set before. 2010.03.05. */ + /* */ + if (!Adapter->registrypriv.wifi_spec && + (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) && + pmlmepriv->LinkDetectInfo.bHigherBusyTraffic) { + IntMtToSet = _TRUE; + + /* To check whether we should disable Tx interrupt or not. */ + if (pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic) + ACIntToSet = _TRUE; + } + + /*Update current settings. */ + if (bCurrentIntMt != IntMtToSet) { + DBG_8192C("%s(): Update interrupt migration(%d)\n", __func__, IntMtToSet); + if (IntMtToSet) { + /* */ + /* Set interrupt migration timer and corresponging Tx/Rx counter. */ + /* timer 25ns*0xfa0=100us for 0xf packets. */ + /* 2010.03.05. */ + /* */ + rtw_write32(Adapter, REG_INT_MIG, 0xff000fa0);/* 0x306:Rx, 0x307:Tx */ + pHalData->bInterruptMigration = IntMtToSet; + } else { + /* Reset all interrupt migration settings. */ + rtw_write32(Adapter, REG_INT_MIG, 0); + pHalData->bInterruptMigration = IntMtToSet; + } + } + +#if 0 /* mask */ + if (bCurrentACIntDisable != ACIntToSet) { + DBG_8192C("%s(): Update AC interrupt(%d)\n", __func__, ACIntToSet); + if (ACIntToSet) { /* Disable four ACs interrupts. */ + /* */ + /* Disable VO, VI, BE and BK four AC interrupts to gain more efficient CPU utilization. */ + /* When extremely highly Rx OK occurs, we will disable Tx interrupts. */ + /* 2010.03.05. */ + /* */ + UpdateInterruptMask8192CE(Adapter, 0, RT_AC_INT_MASKS); + pHalData->bDisableTxInt = ACIntToSet; + } else { /* Enable four ACs interrupts. */ + UpdateInterruptMask8192CE(Adapter, RT_AC_INT_MASKS, 0); + pHalData->bDisableTxInt = ACIntToSet; + } + } +#endif + +} + +#endif + +/* */ +/* Initialize GPIO setting registers */ +/* */ +static void +dm_InitGPIOSetting( + IN PADAPTER Adapter +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + u8 tmp1byte; + + tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG); + tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT); + + rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte); +} +/*============================================================ */ +/* functions */ +/*============================================================ */ +static void Init_ODM_ComInfo_8188f(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + u32 SupportAbility = 0; + u8 cut_ver, fab_ver; + + Init_ODM_ComInfo(Adapter); + + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_PACKAGE_TYPE, pHalData->PackageType); + ODM_CmnInfoInit(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8188F); + + fab_ver = ODM_TSMC; + cut_ver = GET_CVID_CUT_VERSION(pHalData->VersionID); + + 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); + +#ifdef CONFIG_DISABLE_ODM + SupportAbility = 0; +#else + SupportAbility = ODM_RF_CALIBRATION | + ODM_RF_TX_PWR_TRACK /*| */ + ; + /*if(pHalData->AntDivCfg) */ + /* pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV; */ +#endif + + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, SupportAbility); +} + +static void Update_ODM_ComInfo_8188f(PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + u32 SupportAbility = 0; + + SupportAbility = 0 + | ODM_BB_DIG + | ODM_BB_RA_MASK + | ODM_BB_DYNAMIC_TXPWR + | ODM_BB_FA_CNT + | ODM_BB_RSSI_MONITOR + /*| ODM_BB_CCK_PD + | ODM_BB_PWR_SAVE */ + | ODM_BB_CFO_TRACKING + | 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) { + rtw_odm_adaptivity_config_msg(RTW_DBGDUMP, Adapter); + SupportAbility |= ODM_BB_ADAPTIVITY; + } + +#ifdef CONFIG_ANTENNA_DIVERSITY + if (pHalData->AntDivCfg) + SupportAbility |= ODM_BB_ANT_DIV; +#endif + +#if (MP_DRIVER==1) + if (Adapter->registrypriv.mp_mode == 1) { + SupportAbility = 0 + | ODM_RF_CALIBRATION + | ODM_RF_TX_PWR_TRACK + ; + } +#endif/*(MP_DRIVER==1) */ + +#ifdef CONFIG_DISABLE_ODM + SupportAbility = 0; +#endif/*CONFIG_DISABLE_ODM */ + + ODM_CmnInfoUpdate(pDM_Odm, ODM_CMNINFO_ABILITY, SupportAbility); +} + +void +rtl8188f_InitHalDm( + IN PADAPTER Adapter +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + u8 i; + +#ifdef CONFIG_USB_HCI + dm_InitGPIOSetting(Adapter); +#endif + + pHalData->DM_Type = DM_Type_ByDriver; + + Update_ODM_ComInfo_8188f(Adapter); + + if (Adapter->registrypriv.mp_mode == 0) + ODM_DMInit(pDM_Odm); + +} + +#if 0 /* function never used */ +static void +FindMinimumRSSI_8188f( + IN PADAPTER pAdapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; + + /*1 1.Determine the minimum RSSI */ + + +#ifdef CONFIG_CONCURRENT_MODE + /* FindMinimumRSSI() per-adapter */ + { + PADAPTER pbuddy_adapter = pAdapter->pbuddy_adapter; + PHAL_DATA_TYPE pbuddy_HalData = GET_HAL_DATA(pbuddy_adapter); + struct dm_priv *pbuddy_dmpriv = &pbuddy_HalData->dmpriv; + + if ((pHalData->EntryMinUndecoratedSmoothedPWDB != 0) && + (pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB != 0)) { + + if (pHalData->EntryMinUndecoratedSmoothedPWDB > pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB) + pHalData->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB; + } else { + if (pHalData->EntryMinUndecoratedSmoothedPWDB == 0) + pHalData->EntryMinUndecoratedSmoothedPWDB = pbuddy_dmpriv->EntryMinUndecoratedSmoothedPWDB; + + } +#if 0 + if ((pHalData->UndecoratedSmoothedPWDB != (-1)) && + (pbuddy_dmpriv->UndecoratedSmoothedPWDB != (-1))) { + + if ((pHalData->UndecoratedSmoothedPWDB > pbuddy_dmpriv->UndecoratedSmoothedPWDB) && + (pbuddy_dmpriv->UndecoratedSmoothedPWDB != 0)) + pHalData->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; + } else { + if ((pHalData->UndecoratedSmoothedPWDB == (-1)) && (pbuddy_dmpriv->UndecoratedSmoothedPWDB != 0)) + pHalData->UndecoratedSmoothedPWDB = pbuddy_dmpriv->UndecoratedSmoothedPWDB; + } +#endif + } +#endif + + if ((check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) && + (pHalData->EntryMinUndecoratedSmoothedPWDB == 0)) { + pHalData->MinUndecoratedPWDBForDM = 0; + /*ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("Not connected to any\n")); */ + } + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { /* Default port */ +#if 0 + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) { + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + /*ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("AP Client PWDB = 0x%x\n", pHalData->MinUndecoratedPWDBForDM)); */ + } else { /*for STA mode */ + pHalData->MinUndecoratedPWDBForDM = pHalData->UndecoratedSmoothedPWDB; + /*ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("STA Default Port PWDB = 0x%x\n", pHalData->MinUndecoratedPWDBForDM)); */ + } +#else + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; +#endif + } else { /* associated entry pwdb */ + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + /*ODM_RT_TRACE(pDM_Odm,COMP_BB_POWERSAVING, DBG_LOUD, ("AP Ext Port or disconnect PWDB = 0x%x\n", pHalData->MinUndecoratedPWDBForDM)); */ + } + + /*odm_FindMinimumRSSI_Dmsp(pAdapter); */ + /*DBG_8192C("%s=>MinUndecoratedPWDBForDM(%d)\n",__func__,pHalData->MinUndecoratedPWDBForDM); */ + /*ODM_RT_TRACE(pDM_Odm,COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",pHalData->MinUndecoratedPWDBForDM)); */ +} +#endif + +VOID +rtl8188f_HalDmWatchDog( + IN PADAPTER Adapter +) +{ + BOOLEAN bFwCurrentInPSMode = _FALSE; + BOOLEAN bFwPSAwake = _TRUE; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; +#endif /*CONFIG_CONCURRENT_MODE */ + + if (Adapter->registrypriv.mp_mode == 1 && Adapter->mppriv.mp_dm == 0) /* for MP power tracking */ + return; + + + if (!rtw_is_hw_init_completed(Adapter)) + goto skip_dm; + +#ifdef CONFIG_LPS + bFwCurrentInPSMode = adapter_to_pwrctl(Adapter)->bFwCurrentInPSMode; + rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); +#endif + +#ifdef CONFIG_P2P + /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */ + /* modifed by thomas. 2011.06.11. */ + if (Adapter->wdinfo.p2p_ps_mode) + bFwPSAwake = _FALSE; +#endif /*CONFIG_P2P */ + + if ((rtw_is_hw_init_completed(Adapter)) + && ((!bFwCurrentInPSMode) && bFwPSAwake)) { + /* */ + /* Calculate Tx/Rx statistics. */ + /* */ + dm_CheckStatistics(Adapter); + rtw_hal_check_rxfifo_full(Adapter); + /* */ + /* Dynamically switch RTS/CTS protection. */ + /* */ + /*dm_CheckProtection(Adapter); */ + +#ifdef CONFIG_PCI_HCI + /* 20100630 Joseph: Disable Interrupt Migration mechanism temporarily because it degrades Rx throughput. */ + /* Tx Migration settings. */ + /*dm_InterruptMigration(Adapter); */ + + /*if(Adapter->HalFunc.TxCheckStuckHandler(Adapter)) */ + /* PlatformScheduleWorkItem(&(GET_HAL_DATA(Adapter)->HalResetWorkItem)); */ +#endif + } + + /*ODM */ + if (rtw_is_hw_init_completed(Adapter)) { + u8 bLinked = _FALSE; + u8 bsta_state = _FALSE; + u8 bBtDisabled = _TRUE; + + if (rtw_linked_check(Adapter)) { + bLinked = _TRUE; + if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) + bsta_state = _TRUE; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter)) { + bLinked = _TRUE; + if (pbuddy_adapter && check_fwstate(&pbuddy_adapter->mlmepriv, WIFI_STATION_STATE)) + bsta_state = _TRUE; + } +#endif /*CONFIG_CONCURRENT_MODE */ + + ODM_CmnInfoUpdate(&pHalData->odmpriv , ODM_CMNINFO_LINK, bLinked); + ODM_CmnInfoUpdate(&pHalData->odmpriv , ODM_CMNINFO_STATION_STATE, bsta_state); + + /*FindMinimumRSSI_8188f(Adapter); */ + /*ODM_CmnInfoUpdate(&pHalData->odmpriv ,ODM_CMNINFO_RSSI_MIN, pHalData->MinUndecoratedPWDBForDM); */ + +#ifdef CONFIG_BT_COEXIST + bBtDisabled = rtw_btcoex_IsBtDisabled(Adapter); +#endif /* CONFIG_BT_COEXIST */ + ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_BT_ENABLED, ((bBtDisabled == _TRUE) ? _FALSE : _TRUE)); + + ODM_DMWatchdog(&pHalData->odmpriv); + } + +skip_dm: + + /* Check GPIO to determine current RF on/off and Pbc status. */ + /* Check Hardware Radio ON/OFF or not */ + /*if(Adapter->MgntInfo.PowerSaveControl.bGpioRfSw) */ + /*{ */ + /*RTPRINT(FPWR, PWRHW, ("dm_CheckRfCtrlGPIO\n")); */ + /* dm_CheckRfCtrlGPIO(Adapter); */ + /*} */ +#ifdef CONFIG_SUPPORT_HW_WPS_PBC + dm_CheckPbcGPIO(Adapter); +#endif + return; +} + +void rtl8188f_hal_dm_in_lps(PADAPTER padapter) +{ + u32 PWDB_rssi = 0; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta = NULL; + + DBG_871X("%s, RSSI_Min=%d\n", __func__, pDM_Odm->RSSI_Min); + + /*update IGI */ + ODM_Write_DIG(pDM_Odm, pDM_Odm->RSSI_Min); + + + /*set rssi to fw */ + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta && (psta->rssi_stat.UndecoratedSmoothedPWDB > 0)) { + PWDB_rssi = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB << 16)); + + rtl8188f_set_rssi_cmd(padapter, (u8 *)&PWDB_rssi); + } + +} + +void rtl8188f_HalDmWatchDog_in_LPS(IN PADAPTER Adapter) +{ + u8 bLinked = _FALSE; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + pDIG_T pDM_DigTable = &pDM_Odm->DM_DigTable; + struct sta_priv *pstapriv = &Adapter->stapriv; + struct sta_info *psta = NULL; +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = Adapter->pbuddy_adapter; +#endif /*CONFIG_CONCURRENT_MODE */ + + if (!rtw_is_hw_init_completed(Adapter)) + goto skip_lps_dm; + + + if (rtw_linked_check(Adapter)) + bLinked = _TRUE; + +#ifdef CONFIG_CONCURRENT_MODE + if (pbuddy_adapter && rtw_linked_check(pbuddy_adapter)) + bLinked = _TRUE; +#endif /*CONFIG_CONCURRENT_MODE */ + + ODM_CmnInfoUpdate(&pHalData->odmpriv , ODM_CMNINFO_LINK, bLinked); + + if (bLinked == _FALSE) + goto skip_lps_dm; + + if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) + goto skip_lps_dm; + + + /*ODM_DMWatchdog(&pHalData->odmpriv); */ + /*Do DIG by RSSI In LPS-32K */ + + /*.1 Find MIN-RSSI */ + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) + goto skip_lps_dm; + + pHalData->EntryMinUndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; + + DBG_871X("CurIGValue=%d, EntryMinUndecoratedSmoothedPWDB = %d\n", pDM_DigTable->CurIGValue, pHalData->EntryMinUndecoratedSmoothedPWDB); + + if (pHalData->EntryMinUndecoratedSmoothedPWDB <= 0) + goto skip_lps_dm; + + pHalData->MinUndecoratedPWDBForDM = pHalData->EntryMinUndecoratedSmoothedPWDB; + + pDM_Odm->RSSI_Min = pHalData->MinUndecoratedPWDBForDM; + + /*if(pDM_DigTable->CurIGValue != pDM_Odm->RSSI_Min) */ + if ((pDM_DigTable->CurIGValue > pDM_Odm->RSSI_Min + 5) || + (pDM_DigTable->CurIGValue < pDM_Odm->RSSI_Min - 5)) + + { +#ifdef CONFIG_LPS + rtw_dm_in_lps_wk_cmd(Adapter); +#endif + } + + +skip_lps_dm: + + return; + +} + +void rtl8188f_init_dm_priv(IN PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T podmpriv = &pHalData->odmpriv; + Init_ODM_ComInfo_8188f(Adapter); + ODM_InitAllTimers(podmpriv); +} + +void rtl8188f_deinit_dm_priv(IN PADAPTER Adapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T podmpriv = &pHalData->odmpriv; + ODM_CancelAllTimers(podmpriv); + +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_hal_init.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_hal_init.c new file mode 100644 index 00000000..33cfd16f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_hal_init.c @@ -0,0 +1,7165 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 + * + * + ******************************************************************************/ +#define _HAL_INIT_C_ + +#include +#include "hal_com_h2c.h" + +#if 0 /* FW tx packet write */ +#define FW_DOWNLOAD_SIZE_8188F 8192 +#endif + +static VOID +_FWDownloadEnable( + IN PADAPTER padapter, + IN BOOLEAN enable +) +{ + u8 tmp, count = 0; + + if (enable) { + /* 8051 enable */ + tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04); + + tmp = rtw_read8(padapter, REG_MCUFWDL); + rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); + + do { + tmp = rtw_read8(padapter, REG_MCUFWDL); + if (tmp & 0x01) + break; + rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); + rtw_msleep_os(1); + } while (count++ < 100); + if (count > 0) + DBG_871X("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count); + + /* 8051 reset */ + tmp = rtw_read8(padapter, REG_MCUFWDL + 2); + rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + /* MCU firmware download disable. */ + tmp = rtw_read8(padapter, REG_MCUFWDL); + rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe); + } +} + +static int +_BlockWrite( + IN PADAPTER padapter, + IN PVOID buffer, + IN u32 buffSize +) +{ + int ret = _SUCCESS; + + u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ + u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ + u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */ + u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; + u32 remainSize_p1 = 0, remainSize_p2 = 0; + u8 *bufferPtr = (u8 *)buffer; + u32 i = 0, offset = 0; +#ifdef CONFIG_PCI_HCI + u8 remainFW[4] = {0, 0, 0, 0}; + u8 *p = NULL; +#endif + +#ifdef CONFIG_USB_HCI + blockSize_p1 = 254; +#endif + + /*printk("====>%s %d\n", __func__, __LINE__); */ + + /*3 Phase #1 */ + blockCount_p1 = buffSize / blockSize_p1; + remainSize_p1 = buffSize % blockSize_p1; + + if (blockCount_p1) { + RT_TRACE(_module_hal_init_c_, _drv_notice_, + ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n", + buffSize, blockSize_p1, blockCount_p1, remainSize_p1)); + } + + for (i = 0; i < blockCount_p1; i++) { +#ifdef CONFIG_USB_HCI + ret = rtw_writeN(padapter, (FW_8188F_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1)); +#else + ret = rtw_write32(padapter, (FW_8188F_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32 *)(bufferPtr + i * blockSize_p1)))); +#endif + if (ret == _FAIL) { + printk("====>%s %d i:%d\n", __func__, __LINE__, i); + goto exit; + } + } + +#ifdef CONFIG_PCI_HCI + p = (u8 *)((u32 *)(bufferPtr + blockCount_p1 * blockSize_p1)); + if (remainSize_p1) { + switch (remainSize_p1) { + case 0: + break; + case 3: + remainFW[2] = *(p + 2); + case 2: + remainFW[1] = *(p + 1); + case 1: + remainFW[0] = *(p); + ret = rtw_write32(padapter, (FW_8188F_START_ADDRESS + blockCount_p1 * blockSize_p1), + le32_to_cpu(*(u32 *)remainFW)); + } + return ret; + } +#endif + + /*3 Phase #2 */ + if (remainSize_p1) { + offset = blockCount_p1 * blockSize_p1; + + blockCount_p2 = remainSize_p1 / blockSize_p2; + remainSize_p2 = remainSize_p1 % blockSize_p2; + + if (blockCount_p2) { + RT_TRACE(_module_hal_init_c_, _drv_notice_, + ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n", + (buffSize - offset), blockSize_p2 , blockCount_p2, remainSize_p2)); + } + +#ifdef CONFIG_USB_HCI + for (i = 0; i < blockCount_p2; i++) { + ret = rtw_writeN(padapter, (FW_8188F_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2)); + + if (ret == _FAIL) + goto exit; + } +#endif + } + + /*3 Phase #3 */ + if (remainSize_p2) { + offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2); + + blockCount_p3 = remainSize_p2 / blockSize_p3; + + RT_TRACE(_module_hal_init_c_, _drv_notice_, + ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n", + (buffSize - offset), blockSize_p3, blockCount_p3)); + + for (i = 0; i < blockCount_p3; i++) { + ret = rtw_write8(padapter, (FW_8188F_START_ADDRESS + offset + i), *(bufferPtr + offset + i)); + + if (ret == _FAIL) { + printk("====>%s %d i:%d\n", __func__, __LINE__, i); + goto exit; + } + } + } +exit: + return ret; +} + +static int +_PageWrite( + IN PADAPTER padapter, + IN u32 page, + IN PVOID buffer, + IN u32 size +) +{ + u8 value8; + u8 u8Page = (u8)(page & 0x07); + + value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page; + rtw_write8(padapter, REG_MCUFWDL + 2, value8); + + return _BlockWrite(padapter, buffer, size); +} + +static VOID +_FillDummy( + u8 *pFwBuf, + u32 *pFwLen +) +{ + u32 FwLen = *pFwLen; + u8 remain = (u8)(FwLen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pFwBuf[FwLen] = 0; + FwLen++; + remain--; + } + + *pFwLen = FwLen; +} + +static int +_WriteFW( + IN PADAPTER padapter, + IN PVOID buffer, + IN u32 size +) +{ + /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */ + int ret = _SUCCESS; + u32 pageNums, remainSize; + u32 page, offset; + u8 *bufferPtr = (u8 *)buffer; + +#ifdef CONFIG_PCI_HCI + /* 20100120 Joseph: Add for 88CE normal chip. */ + /* Fill in zero to make firmware image to dword alignment. */ + _FillDummy(bufferPtr, &size); +#endif + + pageNums = size / MAX_DLFW_PAGE_SIZE; + /*RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */ + remainSize = size % MAX_DLFW_PAGE_SIZE; + + for (page = 0; page < pageNums; page++) { + offset = page * MAX_DLFW_PAGE_SIZE; + ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE); + + if (ret == _FAIL) { + printk("====>%s %d\n", __func__, __LINE__); + goto exit; + } + } + if (remainSize) { + offset = pageNums * MAX_DLFW_PAGE_SIZE; + page = pageNums; + ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize); + + if (ret == _FAIL) { + printk("====>%s %d\n", __func__, __LINE__); + goto exit; + } + } + RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n")); + +exit: + return ret; +} + +void _8051Reset8188(PADAPTER padapter) +{ + u8 cpu_rst; + u8 io_rst; + +#if 0 + io_rst = rtw_read8(padapter, REG_RSV_CTRL); + rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT1)); +#endif + + /* Reset 8051(WLMCU) IO wrapper */ + /* 0x1c[8] = 0 */ + /* Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 */ + io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1); + io_rst &= ~BIT(0); + rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst); + + cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + cpu_rst &= ~BIT(2); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst); + +#if 0 + io_rst = rtw_read8(padapter, REG_RSV_CTRL); + rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT1)); +#endif + + /* Enable 8051 IO wrapper */ + /* 0x1c[8] = 1 */ + io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1); + io_rst |= BIT(0); + rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst); + + cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + cpu_rst |= BIT(2); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst); + + DBG_8192C("%s: Finish\n", __func__); +} + +static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms) +{ + s32 ret = _FAIL; + u32 value32; + u32 start = rtw_get_current_time(); + u32 cnt = 0; + + /* polling CheckSum report */ + do { + cnt++; + value32 = rtw_read32(adapter, REG_MCUFWDL); + if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_RUN(adapter)) + break; + rtw_yield_os(); + } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt); + + if (!(value32 & FWDL_ChkSum_rpt)) + goto exit; + + if (rtw_fwdl_test_trigger_chksum_fail()) + goto exit; + + ret = _SUCCESS; + +exit: + DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __func__ + , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32); + + return ret; +} + +static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms) +{ + s32 ret = _FAIL; + u32 value32; + u32 start = rtw_get_current_time(); + u32 cnt = 0; + u32 value_to_check = 0; + u32 value_expected = (MCUFWDL_RDY | FWDL_ChkSum_rpt | WINTINI_RDY | RAM_DL_SEL); + + value32 = rtw_read32(adapter, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtw_write32(adapter, REG_MCUFWDL, value32); + + _8051Reset8188(adapter); + + /* polling for FW ready */ + do { + cnt++; + value32 = rtw_read32(adapter, REG_MCUFWDL); + value_to_check = value32 & value_expected; + if ((value_to_check == value_expected) || RTW_CANNOT_RUN(adapter)) + break; + rtw_yield_os(); + } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt); + + if (value_to_check != value_expected) + goto exit; + + if (rtw_fwdl_test_trigger_wintint_rdy_fail()) + goto exit; + + ret = _SUCCESS; + +exit: + DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __func__ + , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32); + + return ret; +} + +#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) + +void rtl8188f_FirmwareSelfReset(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 u1bTmp; + u8 Delay = 100; + + if (!(IS_FW_81xxC(padapter) && + ((pHalData->FirmwareVersion < 0x21) || + (pHalData->FirmwareVersion == 0x21 && + pHalData->FirmwareSubVersion < 0x01)))) { /* after 88C Fw v33.1 */ + /*0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test */ + rtw_write8(padapter, REG_HMETFR + 3, 0x20); + + u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + while (u1bTmp & BIT2) { + Delay--; + if (Delay == 0) + break; + rtw_udelay_os(50); + u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + } + RT_TRACE(_module_hal_init_c_, _drv_notice_, ("-%s: 8051 reset success (%d)\n", __func__, Delay)); + + if (Delay == 0) { + RT_TRACE(_module_hal_init_c_, _drv_notice_, ("%s: Force 8051 reset!!!\n", __func__)); + /*force firmware reset */ + u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT2)); + } + } +} + +#ifdef CONFIG_FILE_FWIMG +extern char *rtw_fw_file_path; +extern char *rtw_fw_wow_file_path; +#ifdef CONFIG_MP_INCLUDED +extern char *rtw_fw_mp_bt_file_path; +#endif /* CONFIG_MP_INCLUDED */ +u8 FwBuffer[FW_8188F_SIZE]; +#endif /* CONFIG_FILE_FWIMG */ + +#ifdef CONFIG_MP_INCLUDED +int _WriteBTFWtoTxPktBuf8188F( + IN PADAPTER Adapter, + IN PVOID buffer, + IN u4Byte FwBufLen, + IN u1Byte times +) +{ + int rtStatus = _SUCCESS; + /*u4Byte value32; */ + /*u1Byte numHQ, numLQ, numPubQ;//, txpktbuf_bndy; */ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + /*PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); */ + u1Byte BcnValidReg; + u1Byte count = 0, DLBcnCount = 0; + pu1Byte FwbufferPtr = (pu1Byte)buffer; + /*PRT_TCB pTcb, ptempTcb; */ + /*PRT_TX_LOCAL_BUFFER pBuf; */ + BOOLEAN bRecover = _FALSE; + pu1Byte ReservedPagePacket = NULL; + pu1Byte pGenBufReservedPagePacket = NULL; + u4Byte TotalPktLen, txpktbuf_bndy; + /*u1Byte tmpReg422; */ + /*u1Byte u1bTmp; */ + u8 *pframe; + struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); + struct xmit_frame *pmgntframe; + 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; +#else + TotalPktLen = FwBufLen + pHalData->HWDescHeadLength; +#endif + + if ((TotalPktLen + TXDESC_OFFSET) > MAX_CMDBUF_SZ) { + DBG_871X(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d\n" + , __func__, (TotalPktLen + TXDESC_OFFSET), MAX_CMDBUF_SZ); + return _FAIL; + } + + pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);/*GetGenTempBuffer (Adapter, TotalPktLen); */ + if (!pGenBufReservedPagePacket) + return _FAIL; + + ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket; + + _rtw_memset(ReservedPagePacket, 0, TotalPktLen); + +#if 1/*(DEV_BUS_TYPE == RT_PCI_INTERFACE) */ + _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen); + +#else + PlatformMoveMemory(ReservedPagePacket + Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen); +#endif + + /*--------------------------------------------------------- */ + /* 1. Pause BCN */ + /*--------------------------------------------------------- */ + /*Set REG_CR bit 8. DMA beacon by SW. */ +#if (DEV_BUS_TYPE == RT_PCI_INTERFACE) + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR + 1); + PlatformEFIOWrite1Byte(Adapter, REG_CR + 1, (u1bTmp | BIT0)); +#else + /* Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO. */ + /* De not remove this part on MERGE_TEMP. by tynli. */ + /*pHalData->RegCR_1 |= (BIT0); */ + /*PlatformEFIOWrite1Byte(Adapter, REG_CR+1, pHalData->RegCR_1); */ +#endif + + /* 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); + +#if 0/*(DEV_BUS_TYPE == RT_PCI_INTERFACE) */ + tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2); + if (tmpReg422 & BIT6) + bRecover = TRUE; + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, tmpReg422 & (~BIT6)); +#else + /* 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; + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl & (~BIT(6)))); + pHalData->RegFwHwTxQCtrl &= (~ BIT(6)); +#endif + + /*--------------------------------------------------------- */ + /* 2. Adjust LLT table to an even boundary. */ + /*--------------------------------------------------------- */ +#if 0/*(DEV_BUS_TYPE == RT_SDIO_INTERFACE) */ + txpktbuf_bndy = 10; /* rsvd page start address should be an even value. */ + rtStatus = InitLLTTable8188FS(Adapter, txpktbuf_bndy); + if (RT_STATUS_SUCCESS != rtStatus) { + DBG_8192C("_CheckWLANFwPatchBTFwReady_8188F(): Failed to init LLT!\n"); + return RT_STATUS_FAILURE; + } + + /* Init Tx boundary. */ + PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8188F + 1, (u1Byte)txpktbuf_bndy); +#endif + + + /*--------------------------------------------------------- */ + /* 3. Write Fw to Tx packet buffer by reseverd page. */ + /*--------------------------------------------------------- */ + do { + /* download rsvd page. */ + /* Clear beacon valid check bit. */ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2); + PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg & (~BIT(0))); + + /*BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy */ + RT_TRACE(_module_mp_, _drv_info_, ("0x209:%x\n", + PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 1))); /*209 < 0x40 */ + + PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 1, (0x90 - 0x20 * (times - 1))); + DBG_871X("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 1)); + RT_TRACE(_module_mp_, _drv_info_, ("0x209:%x\n", + PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 1))); + +#if 0 + /* Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock. */ + /* Advertised by Roger. Added by tynli. 2010.02.22. */ + PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + if (MgntGetFWBuffer(Adapter, &pTcb, &pBuf)) { + PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen); + CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE); + } else + dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n"); + PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); +#else + /*--------------------------------------------------------- + tx reserved_page_packet + ----------------------------------------------------------*/ + pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv); + if (pmgntframe == NULL) { + rtStatus = _FAIL; + goto exit; + } + /*update attribute */ + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(Adapter, pattrib); + + pattrib->qsel = QSLT_BEACON; + pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen; + + /*_rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size); */ + /*pmgntframe->buf_addr = ReservedPagePacket; */ + + _rtw_memcpy((u8 *)(pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen); + DBG_871X("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d\n", DLBcnCount, (FwBufLen + txdesc_offset)); + +#ifdef CONFIG_PCI_HCI + dump_mgntframe(Adapter, pmgntframe); +#else + dump_mgntframe_and_wait(Adapter, pmgntframe, 100); +#endif + +#endif +#if 1 + /* check rsvd page download OK. */ + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2); + while (!(BcnValidReg & BIT(0)) && count < 200) { + count++; + /*PlatformSleepUs(10); */ + rtw_msleep_os(1); + BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2); + RT_TRACE(_module_mp_, _drv_notice_, ("Poll 0x20A = %x\n", BcnValidReg)); + } + DLBcnCount++; + /*DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210)); */ + + PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg); + + } while ((!(BcnValidReg & BIT(0))) && DLBcnCount < 5); + + +#endif + if (DLBcnCount >= 5) { + DBG_871X(" check rsvd page download OK DLBcnCount =%d\n", DLBcnCount); + rtStatus = _FAIL; + goto exit; + } + + if (!(BcnValidReg & BIT(0))) { + DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n"); + rtStatus = _FAIL; + goto exit; + } + + /*--------------------------------------------------------- */ + /* 4. Set Tx boundary to the initial value */ + /*--------------------------------------------------------- */ + + + /*--------------------------------------------------------- */ + /* 5. Reset beacon setting to the initial value. */ + /* After _CheckWLANFwPatchBTFwReady(). */ + /*--------------------------------------------------------- */ + +exit: + + if (pGenBufReservedPagePacket) { + DBG_871X("_WriteBTFWtoTxPktBuf8188F => rtw_mfree pGenBufReservedPagePacket!\n"); + rtw_mfree((u8 *)pGenBufReservedPagePacket, TotalPktLen); + } + return rtStatus; +} + + + +/* */ +/* Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW. */ +/* 2011.10.20 by tynli */ +/* */ +void +SetFwBTFwPatchCmd( + IN PADAPTER Adapter, + IN u16 FwSize +) +{ + u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN] = {0}; + u8 addr0 = 0; + u8 addr1 = 0xa0; + u8 addr2 = 0x10; + u8 addr3 = 0x80; + + RT_TRACE(_module_mp_, _drv_notice_, ("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize)); + + SET_8188F_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize); + SET_8188F_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0); + SET_8188F_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1); + SET_8188F_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2); + SET_8188F_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3); + + FillH2CCmd8188F(Adapter, H2C_8188F_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm); + + RT_TRACE(_module_mp_, _drv_notice_, ("<----SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize)); +} + +void +SetFwBTPwrCmd( + IN PADAPTER Adapter, + IN u1Byte PwrIdx +) +{ + u1Byte u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN] = {0}; + + RT_TRACE(_module_mp_, _drv_info_, ("SetFwBTPwrCmd(): idx = %d\n", PwrIdx)); + SET_8188F_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx); + + RT_TRACE(_module_mp_, _drv_info_, ("SetFwBTPwrCmd(): %x %x %x\n", + u1BTPwrIdxParm[0], u1BTPwrIdxParm[1], u1BTPwrIdxParm[2])); + + FillH2CCmd8188F(Adapter, H2C_8188F_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm); +} + +/* */ +/* Description: WLAN Fw will write BT Fw to BT XRAM and signal driver. */ +/* */ +/* 2011.10.20. by tynli. */ +/* */ +int +_CheckWLANFwPatchBTFwReady( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u4Byte count = 0; + u1Byte u1bTmp; + int ret = _FAIL; + + /*--------------------------------------------------------- */ + /* Check if BT FW patch procedure is ready. */ + /*--------------------------------------------------------- */ + do { + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8188F); + if ((u1bTmp & BIT6) || (u1bTmp & BIT7)) { + ret = _SUCCESS; + break; + } + + count++; + RT_TRACE(_module_mp_, _drv_info_, ("0x88=%x, wait for 50 ms (%d) times.\n", + u1bTmp, count)); + rtw_msleep_os(50); /* 50ms */ + } while (!((u1bTmp & BIT6) || (u1bTmp & BIT7)) && count < 50); + + RT_TRACE(_module_mp_, _drv_notice_, + ("_CheckWLANFwPatchBTFwReady(): Polling ready bit 0x88[7] for %d times.\n", count)); + + if (count >= 50) { + RT_TRACE(_module_mp_, _drv_notice_, + ("_CheckWLANFwPatchBTFwReady(): Polling ready bit 0x88[7] FAIL!!\n")); + } + + /*--------------------------------------------------------- */ + /* Reset beacon setting to the initial value. */ + /*--------------------------------------------------------- */ +#if 0/*(DEV_BUS_TYPE == RT_PCI_INTERFACE) */ + if (LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE) { + dbgdump("Init self define for BT Fw patch LLT table fail.\n"); + /*return RT_STATUS_FAILURE; */ + } +#endif + u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL); + u1bTmp |= EN_BCN_FUNCTION; + u1bTmp &= ~DIS_TSF_UDT; + rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp); + + /* 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 0/*(DEV_BUS_TYPE == RT_PCI_INTERFACE) */ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2); + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (u1bTmp | BIT6)); +#else + PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl | BIT(6))); + pHalData->RegFwHwTxQCtrl |= BIT(6); +#endif + + /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */ + u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8188F + 1); + PlatformEFIOWrite1Byte(Adapter, REG_CR_8188F + 1, (u1bTmp & (~BIT0))); + + return ret; +} + +int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize) +{ + u8 temp, ret, lastBTsz; + u32 u1bTmp = 0, address_start = 0, count = 0, i = 0; + u8 *myBTFwBuffer = NULL; + + myBTFwBuffer = rtw_zmalloc(BTPatchSize); + if (myBTFwBuffer == NULL) { + DBG_871X("%s can't be executed due to the failed malloc.\n", __func__); + Adapter->mppriv.bTxBufCkFail = _TRUE; + return _FALSE; + } + + temp = rtw_read8(Adapter, 0x209); + + address_start = (temp * 128) / 8; + + rtw_write32(Adapter, 0x140, 0x00000000); + rtw_write32(Adapter, 0x144, 0x00000000); + rtw_write32(Adapter, 0x148, 0x00000000); + + rtw_write8(Adapter, 0x106, 0x69); + + for (i = 0; i < (BTPatchSize / 8); i++) { + rtw_write32(Adapter, 0x140, address_start + 5 + i); + + /*polling until reg 0x140[23]=1; */ + do { + u1bTmp = rtw_read32(Adapter, 0x140); + if (u1bTmp & BIT(23)) { + ret = _SUCCESS; + break; + } + count++; + DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count); + rtw_msleep_os(10); /* 10ms */ + } while (!(u1bTmp & BIT(23)) && count < 50); + + myBTFwBuffer[i * 8 + 0] = rtw_read8(Adapter, 0x144); + myBTFwBuffer[i * 8 + 1] = rtw_read8(Adapter, 0x145); + myBTFwBuffer[i * 8 + 2] = rtw_read8(Adapter, 0x146); + myBTFwBuffer[i * 8 + 3] = rtw_read8(Adapter, 0x147); + myBTFwBuffer[i * 8 + 4] = rtw_read8(Adapter, 0x148); + myBTFwBuffer[i * 8 + 5] = rtw_read8(Adapter, 0x149); + myBTFwBuffer[i * 8 + 6] = rtw_read8(Adapter, 0x14a); + myBTFwBuffer[i * 8 + 7] = rtw_read8(Adapter, 0x14b); + } + + rtw_write32(Adapter, 0x140, address_start + 5 + BTPatchSize / 8); + + lastBTsz = BTPatchSize % 8; + + /*polling until reg 0x140[23]=1; */ + u1bTmp = 0; + count = 0; + do { + u1bTmp = rtw_read32(Adapter, 0x140); + if (u1bTmp & BIT(23)) { + ret = _SUCCESS; + break; + } + count++; + DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count); + rtw_msleep_os(10); /* 10ms */ + } while (!(u1bTmp & BIT(23)) && count < 50); + + for (i = 0; i < lastBTsz; i++) + myBTFwBuffer[(BTPatchSize / 8) * 8 + i] = rtw_read8(Adapter, (0x144 + i)); + + + for (i = 0; i < BTPatchSize; i++) { + if (myBTFwBuffer[i] != pFirmware->szFwBuffer[i]) { + DBG_871X(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n", i, myBTFwBuffer[i], pFirmware->szFwBuffer[i]); + Adapter->mppriv.bTxBufCkFail = _TRUE; + break; + } + } + + if (myBTFwBuffer != NULL) + rtw_mfree(myBTFwBuffer, BTPatchSize); + + return _TRUE; +} + +#ifdef CONFIG_BT_COEXIST +/* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it + * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8188F is used to indicate + * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096 + * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part + * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part + * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the + * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location + * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the + * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only + * has 32 bytes descrption at the head of part 1. +*/ +s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware) +{ + s32 rtStatus; + u8 *pBTFirmwareBuf; + u32 BTFirmwareLen; + u8 download_time; + s8 i; + + + rtStatus = _SUCCESS; + pBTFirmwareBuf = NULL; + BTFirmwareLen = 0; + + /* */ + /* Patch BT Fw. Download BT RAM code to Tx packet buffer. */ + /* */ + if (padapter->bBTFWReady) { + DBG_8192C("%s: BT Firmware is ready!!\n", __func__); + return _FAIL; + } + +#ifdef CONFIG_FILE_FWIMG + if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE) { + DBG_8192C("%s: acquire MP BT FW from file:%s\n", __func__, rtw_fw_mp_bt_file_path); + + rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8188F_SIZE); + BTFirmwareLen = rtStatus >= 0 ? rtStatus : 0; + pBTFirmwareBuf = FwBuffer; + } else +#endif /* CONFIG_FILE_FWIMG */ + { +#ifdef CONFIG_EMBEDDED_FWIMG + DBG_8192C("%s: Download MP BT FW from header\n", __func__); + + pBTFirmwareBuf = (u8 *)Rtl8188FFwBTImgArray; + BTFirmwareLen = Rtl8188FFwBTImgArrayLength; + pFirmware->szFwBuffer = pBTFirmwareBuf; + pFirmware->ulFwLength = BTFirmwareLen; +#endif /* CONFIG_EMBEDDED_FWIMG */ + } + + DBG_8192C("%s: MP BT Firmware size=%d\n", __func__, BTFirmwareLen); + + /* for h2c cam here should be set to true */ + padapter->bFWReady = _TRUE; + + download_time = (BTFirmwareLen + 4095) / 4096; + DBG_8192C("%s: download_time is %d\n", __func__, download_time); + + /* Download BT patch Fw. */ + for (i = (download_time - 1); i >= 0; i--) { + if (i == (download_time - 1)) { + rtStatus = _WriteBTFWtoTxPktBuf8188F(padapter, pBTFirmwareBuf + (4096 * i), (BTFirmwareLen - (4096 * i)), 1); + DBG_8192C("%s: start %d, len %d, time 1\n", __func__, 4096 * i, BTFirmwareLen - (4096 * i)); + } else { + rtStatus = _WriteBTFWtoTxPktBuf8188F(padapter, pBTFirmwareBuf + (4096 * i), 4096, (download_time - i)); + DBG_8192C("%s: start %d, len 4096, time %d\n", __func__, 4096 * i, download_time - i); + } + + if (rtStatus != _SUCCESS) { + DBG_8192C("%s: BT Firmware download to Tx packet buffer fail!\n", __func__); + padapter->bBTFWReady = _FALSE; + return rtStatus; + } + } + + ReservedPage_Compare(padapter, pFirmware, BTFirmwareLen); + + padapter->bBTFWReady = _TRUE; + SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen); + rtStatus = _CheckWLANFwPatchBTFwReady(padapter); + + DBG_8192C("<===%s: return %s!\n", __func__, rtStatus == _SUCCESS ? "SUCCESS" : "FAIL"); + + return rtStatus; +} +#endif /* CONFIG_BT_COEXIST */ +#endif /* CONFIG_MP_INCLUDED */ + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +void rtl8188f_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 + +#if 0 /* FW tx packet write */ +u8 send_fw_packet(PADAPTER padapter, u8 *pRam_code, u32 length) +{ + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct xmit_buf xmit_buf_tmp; + struct submit_ctx sctx_tmp; + u8 *pTx_data_buffer = NULL; + u8 *pTmp_buffer = NULL; + u32 modify_ram_size; + u32 tmp_size, tmp_value; + u8 value8; + u32 i, counter; + u8 bRet; + u32 dwDataLength, writeLength; + + /* Due to SDIO can not send 32K packet */ + if (FW_DOWNLOAD_SIZE_8188F == length) + length--; + + modify_ram_size = length << 2; + pTx_data_buffer = rtw_zmalloc(modify_ram_size); + + if (NULL == pTx_data_buffer) { + DBG_871X("Allocate buffer fail!!\n"); + return _FALSE; + } + + _rtw_memset(pTx_data_buffer, 0, modify_ram_size); + + /* Transfer to new format */ + tmp_size = length >> 1; + for (i = 0; i <= tmp_size; i++) { + *(pTx_data_buffer + i * 8) = *(pRam_code + i * 2); + *(pTx_data_buffer + i * 8 + 1) = *(pRam_code + i * 2 + 1); + } + + /* Gen TX_DESC */ + _rtw_memset(pTx_data_buffer, 0, TXDESC_SIZE); + pTmp_buffer = pTx_data_buffer; +#if 0 + pTmp_buffer->qsel = BcnQsel; + pTmp_buffer->txpktsize = modify_ram_size - TXDESC_SIZE; + pTmp_buffer->offset = TXDESC_SIZE; +#else + SET_TX_DESC_QUEUE_SEL_8188F(pTmp_buffer, QSLT_BEACON); + SET_TX_DESC_PKT_SIZE_8188F(pTmp_buffer, modify_ram_size - TXDESC_SIZE); + SET_TX_DESC_OFFSET_8188F(pTmp_buffer, TXDESC_SIZE); +#endif + rtl8188f_cal_txdesc_chksum((struct tx_desc *)pTmp_buffer); + + + /* Send packet */ +#if 0 + dwDataLength = modify_ram_size; + overlap.Offset = 0; + overlap.OffsetHigh = 0; + overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + bRet = WriteFile(HalVari.hFile_Queue[TX_BCNQ]->handle, pTx_data_buffer, dwDataLength, &writeLength, &overlap); + if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) { + + GetOverlappedResult(HalVari.hFile_Queue[TX_BCNQ]->handle, &overlap, &writeLength, FALSE); + if (writeLength != dwDataLength) { + TCHAR editbuf[100]; + + sprintf(editbuf, "DL FW Length Err: Write length error:bRet %d writeLength %ld dwDataLength %ld, Error Code:%ld", bRet, writeLength, dwDataLength, GetLastError()); + AfxMessageBox(editbuf, MB_OK | MB_ICONERROR); + return FALSE; + } + } + CloseHandle(overlap.hEvent); +#else + xmit_buf_tmp.pdata = pTx_data_buffer; + xmit_buf_tmp.len = modify_ram_size; + rtw_sctx_init(&sctx_tmp, 10); + xmit_buf_tmp.sctx = &sctx_tmp; + if (rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[BCN_QUEUE_INX], xmit_buf_tmp.len, (u8 *)&xmit_buf_tmp) == _FAIL) { + DBG_871X("rtw_write_port fail\n"); + return _FAIL; + } +#endif + + /* check if DMA is OK */ + counter = 100; + do { + if (0 == counter) { + DBG_871X("DMA time out!!\n"); + return _FALSE; + } + value8 = rtw_read8(padapter, REG_DWBCN0_CTRL_8188F + 2); + counter--; + } while (0 == (value8 & BIT(0))); + + rtw_write8(padapter, REG_DWBCN0_CTRL_8188F + 2, value8); + + /* Modify ram code by IO method */ + tmp_value = rtw_read8(padapter, REG_MCUFWDL + 1); + /* Disable DMA */ + rtw_write8(padapter, REG_MCUFWDL + 1, (u8)tmp_value & ~(BIT(5))); + tmp_value = (tmp_value >> 6) << 1; + /* Set page start address */ + rtw_write8(padapter, REG_MCUFWDL + 2, (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | tmp_value); + tmp_size = TXDESC_SIZE >> 2; /* 10bytes */ +#if 0 + IO_Func.WriteRegister(0x1000, (u2Byte)tmp_size, pRam_code); +#else + _BlockWrite(padapter, pRam_code, tmp_size); +#endif + + if (pTmp_buffer != NULL) + rtw_mfree((u8 *)pTmp_buffer, modify_ram_size); + + return _TRUE; +} +#endif + +/* */ +/* Description: */ +/* Download 8192C firmware code. */ +/* */ +/* */ +s32 rtl8188f_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw) +{ + s32 rtStatus = _SUCCESS; + u8 write_fw = 0; + u32 fwdl_start_time; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + s8 R8188FFwImageFileName[] = {RTL8188F_FW_IMG}; + u8 *FwImage; + u32 FwImageLen; + u8 *pFwImageFileName; +#ifdef CONFIG_WOWLAN + u8 *FwImageWoWLAN; + u32 FwImageWoWLANLen; +#endif + u8 *pucMappedFile = NULL; + PRT_FIRMWARE_8188F pFirmware = NULL; + PRT_8188F_FIRMWARE_HDR pFwHdr = NULL; + u8 *pFirmwareBuf; + u32 FirmwareLen; +#ifdef CONFIG_FILE_FWIMG + u8 *fwfilepath; +#endif /* CONFIG_FILE_FWIMG */ + u8 value8; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__)); +#ifdef CONFIG_WOWLAN + RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __func__, bUsedWoWLANFw)); +#endif + pFirmware = (PRT_FIRMWARE_8188F)rtw_zmalloc(sizeof(RT_FIRMWARE_8188F)); + + if (!pFirmware) { + rtStatus = _FAIL; + goto exit; + } + + { + u8 tmp_ps = 0, tmp_rf = 0; + + tmp_ps = rtw_read8(padapter, 0xa3); + tmp_ps &= 0xf8; + tmp_ps |= 0x02; + /*1. write 0xA3[:2:0] = 3b'010 */ + rtw_write8(padapter, 0xa3, tmp_ps); + /*2. read power_state = 0xA0[1:0] */ + tmp_ps = rtw_read8(padapter, 0xa0); + tmp_ps &= 0x03; + if (tmp_ps != 0x01) { + DBG_871X(FUNC_ADPT_FMT" tmp_ps=%x\n", FUNC_ADPT_ARG(padapter), tmp_ps); + pdbgpriv->dbg_downloadfw_pwr_state_cnt++; + } + } + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_PreLoadFirmware(padapter); +#endif + +#ifdef CONFIG_FILE_FWIMG +#ifdef CONFIG_WOWLAN + if (bUsedWoWLANFw) + fwfilepath = rtw_fw_wow_file_path; + else +#endif /* CONFIG_WOWLAN */ + { + fwfilepath = rtw_fw_file_path; + } +#endif /* CONFIG_FILE_FWIMG */ + +#ifdef CONFIG_FILE_FWIMG + if (rtw_is_file_readable(fwfilepath) == _TRUE) { + DBG_8192C("%s acquire FW from file:%s\n", __func__, fwfilepath); + pFirmware->eFWSource = FW_SOURCE_IMG_FILE; + } else +#endif /* CONFIG_FILE_FWIMG */ + { +#ifdef CONFIG_EMBEDDED_FWIMG + pFirmware->eFWSource = FW_SOURCE_HEADER_FILE; +#else /* !CONFIG_EMBEDDED_FWIMG */ + pFirmware->eFWSource = FW_SOURCE_IMG_FILE; /* We should decided by Reg. */ +#endif /* !CONFIG_EMBEDDED_FWIMG */ + } + + switch (pFirmware->eFWSource) { + case FW_SOURCE_IMG_FILE: +#ifdef CONFIG_FILE_FWIMG + rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer, FW_8188F_SIZE); + pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0; + pFirmware->szFwBuffer = FwBuffer; +#endif /* CONFIG_FILE_FWIMG */ + break; + + case FW_SOURCE_HEADER_FILE: +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + if (bUsedWoWLANFw) { + if (!pwrpriv->wowlan_ap_mode) { + ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, + CONFIG_FW_WoWLAN, + (u8 *)&pFirmware->szFwBuffer, + &pFirmware->ulFwLength); + + DBG_8192C(" ===> %s fw: %s, size: %d\n", + __func__, "WoWLAN", + pFirmware->ulFwLength); + } else { + ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, + CONFIG_FW_AP, + (u8 *)&pFirmware->szFwBuffer, + &pFirmware->ulFwLength); + + DBG_8192C(" ===> %s fw: %s, size: %d\n", + __func__, "AP_WoWLAN", + pFirmware->ulFwLength); + } + } else +#endif /* CONFIG_WOWLAN */ + { + ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv + , CONFIG_FW_WoWLAN /* functions of CONFIG_FW_NIC is included in CONFIG_FW_WoWLAN */ + , (u8 *)&pFirmware->szFwBuffer + , &pFirmware->ulFwLength + ); + DBG_8192C("%s fw: %s, size: %d\n", __func__, "FW_WoWLAN", pFirmware->ulFwLength); + } + break; + } + + if (pFirmware->ulFwLength > FW_8188F_SIZE) { + rtStatus = _FAIL; + DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8188F_SIZE); + goto exit; + } + + pFirmwareBuf = pFirmware->szFwBuffer; + FirmwareLen = pFirmware->ulFwLength; + + /* To Check Fw header. Added by tynli. 2009.12.04. */ + pFwHdr = (PRT_8188F_FIRMWARE_HDR)pFirmwareBuf; + + pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); + pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion); + pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature); + + DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n", + __func__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature + , pFwHdr->Month, pFwHdr->Date, pFwHdr->Hour, pFwHdr->Minute); + + if (IS_FW_HEADER_EXIST_8188F(pFwHdr)) { + DBG_871X("%s(): Shift for fw header!\n", __func__); + /* Shift 32 bytes for FW header */ + pFirmwareBuf = pFirmwareBuf + 32; + FirmwareLen = FirmwareLen - 32; + } + + fwdl_start_time = rtw_get_current_time(); + +#if 1 + DBG_871X("%s by IO write!\n", __func__); + + /* + * Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, + * or it will cause download Fw fail. 2010.02.01. by tynli. + */ + if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { + rtw_write8(padapter, REG_MCUFWDL, 0x00); + _8051Reset8188(padapter); + } + + _FWDownloadEnable(padapter, _TRUE); + + while (!RTW_CANNOT_RUN(padapter) + && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500)) { + /* reset FWDL chksum */ + rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt); + + rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen); + if (rtStatus != _SUCCESS) + continue; + + rtStatus = polling_fwdl_chksum(padapter, 5, 50); + if (rtStatus == _SUCCESS) + break; + } +#else + DBG_871X("%s by Tx pkt write!\n", __func__); + + if ((rtw_read8(padapter, REG_MCUFWDL) & MCUFWDL_RDY) == 0) { + /* DLFW use HIQ only */ + value32 = 0xFF | BIT(31); + rtw_write32(padapter, REG_RQPN, value32); + + /* Set beacon boundary to TXFIFO header */ + rtw_write8(padapter, REG_BCNQ_BDNY, 0); + rtw_write16(padapter, REG_DWBCN0_CTRL_8188F + 1, BIT(8)); + + /* SDIO need read this register before send packet */ + rtw_read32(padapter, 0x10250020); + + _FWDownloadEnable(padapter, _TRUE); + + /* Get original check sum */ + new_chk_sum = *(pFirmwareBuf + FirmwareLen - 2) | ((u16) *(pFirmwareBuf + FirmwareLen - 1) << 8); + + /* Send ram code flow */ + dma_iram_sel = 0; + mem_offset = 0; + pkt_size_tmp = FirmwareLen; + while (0 != pkt_size_tmp) { + if (pkt_size_tmp >= FW_DOWNLOAD_SIZE_8188F) { + send_pkt_size = FW_DOWNLOAD_SIZE_8188F; + /* Modify check sum value */ + new_chk_sum = (u16)(new_chk_sum ^ (((send_pkt_size - 1) << 2) - TXDESC_SIZE)); + } else { + send_pkt_size = pkt_size_tmp; + new_chk_sum = (u16)(new_chk_sum ^ ((send_pkt_size << 2) - TXDESC_SIZE)); + + } + + if (send_pkt_size == pkt_size_tmp) { + /* last partition packet, write new check sum to ram code file */ + *(pFirmwareBuf + FirmwareLen - 2) = new_chk_sum & 0xFF; + *(pFirmwareBuf + FirmwareLen - 1) = (new_chk_sum & 0xFF00) >> 8; + } + + /* IRAM select */ + rtw_write8(padapter, REG_MCUFWDL + 1, (rtw_read8(padapter, REG_MCUFWDL + 1) & 0x3F) | (dma_iram_sel << 6)); + /* Enable DMA */ + rtw_write8(padapter, REG_MCUFWDL + 1, rtw_read8(padapter, REG_MCUFWDL + 1) | BIT(5)); + + if (_FALSE == send_fw_packet(padapter, pFirmwareBuf + mem_offset, send_pkt_size)) { + DBG_871X("%s: Send FW fail !\n", __func__); + rtStatus = _FAIL; + goto DLFW_FAIL; + } + + dma_iram_sel++; + mem_offset += send_pkt_size; + pkt_size_tmp -= send_pkt_size; + } + } else { + DBG_871X("%s: Download FW fail since MCUFWDL_RDY is not set!\n", __func__); + rtStatus = _FAIL; + goto DLFW_FAIL; + } +#endif + + _FWDownloadEnable(padapter, _FALSE); + + rtStatus = _FWFreeToGo(padapter, 10, 200); + if (_SUCCESS != rtStatus) + goto DLFW_FAIL; + + DBG_871X("%s: DLFW OK !\n", __func__); + +DLFW_FAIL: + if (rtStatus == _FAIL) { + /* Disable FWDL_EN */ + value8 = rtw_read8(padapter, REG_MCUFWDL); + value8 = (value8 & ~(BIT(0)) & ~(BIT(1))); + rtw_write8(padapter, REG_MCUFWDL, value8); + } + + DBG_871X("%s %s. write_fw:%u, %dms\n" + , __func__, (rtStatus == _SUCCESS) ? "success" : "fail" + , write_fw + , rtw_get_passing_time_ms(fwdl_start_time) + ); + +exit: + if (pFirmware) + rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8188F)); + + DBG_871X(" <=== %s()\n", __func__); + + return rtStatus; +} + +void rtl8188f_InitializeFirmwareVars(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + /* Init Fw LPS related. */ + adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE; + + /*Init H2C cmd. */ + rtw_write8(padapter, REG_HMETFR, 0x0f); + + /* Init H2C counter. by tynli. 2009.12.09. */ + pHalData->LastHMEBoxNum = 0; + /*pHalData->H2CQueueHead = 0; */ + /*pHalData->H2CQueueTail = 0; */ + /*pHalData->H2CStopInsertQueue = _FALSE; */ +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +/*=========================================== */ + +/* */ +/* Description: Prepare some information to Fw for WoWLAN. */ +/* (1) Download wowlan Fw. */ +/* (2) Download RSVD page packets. */ +/* (3) Enable AP offload if needed. */ +/* */ +/* 2011.04.12 by tynli. */ +/* */ +VOID +SetFwRelatedForWoWLAN8188f( + IN PADAPTER padapter, + IN u8 bHostIsGoingtoSleep +) +{ + int status = _FAIL; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 bRecover = _FALSE; + /* */ + /* 1. Before WoWLAN we need to re-download WoWLAN Fw. */ + /* */ + status = rtl8188f_FirmwareDownload(padapter, bHostIsGoingtoSleep); + if (status != _SUCCESS) { + DBG_871X("SetFwRelatedForWoWLAN8188f(): Re-Download Firmware failed!!\n"); + return; + } else + DBG_871X("SetFwRelatedForWoWLAN8188f(): Re-Download Firmware Success !!\n"); + /* */ + /* 2. Re-Init the variables about Fw related setting. */ + /* */ + rtl8188f_InitializeFirmwareVars(padapter); +} +#endif /*CONFIG_WOWLAN */ + +/*=========================================================== */ +/* Efuse related code */ +/*=========================================================== */ +static u8 +hal_EfuseSwitchToBank( + PADAPTER padapter, + u8 bank, + u8 bPseudoTest) +{ + u8 bRet = _FALSE; + u32 value32 = 0; +#ifdef HAL_EFUSE_MEMORY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; +#endif + + + DBG_8192C("%s: Efuse switch bank to %d\n", __func__, bank); + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + pEfuseHal->fakeEfuseBank = bank; +#else + fakeEfuseBank = bank; +#endif + bRet = _TRUE; + } else { + value32 = rtw_read32(padapter, EFUSE_TEST); + bRet = _TRUE; + switch (bank) { + case 0: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + break; + case 1: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0); + break; + case 2: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1); + break; + case 3: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2); + break; + default: + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + bRet = _FALSE; + break; + } + rtw_write32(padapter, EFUSE_TEST, value32); + } + + return bRet; +} + +static void +Hal_GetEfuseDefinition( + PADAPTER padapter, + u8 efuseType, + u8 type, + void *pOut, + u8 bPseudoTest) +{ + switch (type) { + case TYPE_EFUSE_MAX_SECTION: { + u8 *pMax_section; + + pMax_section = (u8 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pMax_section = EFUSE_MAX_SECTION_8188F; + else + *pMax_section = EFUSE_BT_MAX_SECTION; + } + break; + + case TYPE_EFUSE_REAL_CONTENT_LEN: { + u16 *pu2Tmp; + + pu2Tmp = (u16 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8188F; + else + *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN; + } + break; + + case TYPE_AVAILABLE_EFUSE_BYTES_BANK: { + u16 *pu2Tmp; + + pu2Tmp = (u16 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8188F - EFUSE_OOB_PROTECT_BYTES); + else + *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK); + } + break; + + case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: { + u16 *pu2Tmp; + + pu2Tmp = (u16 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8188F - EFUSE_OOB_PROTECT_BYTES); + else + *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN - (EFUSE_PROTECT_BYTES_BANK * 3)); + } + break; + + case TYPE_EFUSE_MAP_LEN: { + u16 *pu2Tmp; + + pu2Tmp = (u16 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu2Tmp = EFUSE_MAX_MAP_LEN; + else + *pu2Tmp = EFUSE_BT_MAP_LEN; + } + break; + + case TYPE_EFUSE_PROTECT_BYTES_BANK: { + u8 *pu1Tmp; + + pu1Tmp = (u8 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; + else + *pu1Tmp = EFUSE_PROTECT_BYTES_BANK; + } + break; + + case TYPE_EFUSE_CONTENT_LEN_BANK: { + u16 *pu2Tmp; + + pu2Tmp = (u16 *)pOut; + + if (efuseType == EFUSE_WIFI) + *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8188F; + else + *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN; + } + break; + + default: { + u8 *pu1Tmp; + + pu1Tmp = (u8 *)pOut; + *pu1Tmp = 0; + } + break; + } +} + +#define VOLTAGE_V25 0x03 +#define LDOE25_SHIFT 28 + +/*================================================================= */ +/* The following is for compile ok */ +/* That should be merged with the original in the future */ +/*================================================================= */ +#define EFUSE_ACCESS_ON_8188 0x69 /* For RTL8188 only. */ +#define EFUSE_ACCESS_OFF_8188 0x00 /* For RTL8188 only. */ +#define REG_EFUSE_ACCESS_8188 0x00CF /* Efuse access protection for RTL8188 */ + +/*================================================================= */ +static void Hal_BT_EfusePowerSwitch( + PADAPTER padapter, + u8 bWrite, + u8 PwrState) +{ + u8 tempval; + if (PwrState == _TRUE) { + /* enable BT power cut */ + /* 0x6A[14] = 1 */ + tempval = rtw_read8(padapter, 0x6B); + tempval |= BIT(6); + rtw_write8(padapter, 0x6B, tempval); + + /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */ + /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together! */ + rtw_usleep_os(100); + /* disable BT output isolation */ + /* 0x6A[15] = 0 */ + tempval = rtw_read8(padapter, 0x6B); + tempval &= ~BIT(7); + rtw_write8(padapter, 0x6B, tempval); + } else { + /* enable BT output isolation */ + /* 0x6A[15] = 1 */ + tempval = rtw_read8(padapter, 0x6B); + tempval |= BIT(7); + rtw_write8(padapter, 0x6B, tempval); + + /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */ + /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together! */ + + /* disable BT power cut */ + /* 0x6A[14] = 1 */ + tempval = rtw_read8(padapter, 0x6B); + tempval &= ~BIT(6); + rtw_write8(padapter, 0x6B, tempval); + } + +} +static void +Hal_EfusePowerSwitch( + PADAPTER padapter, + u8 bWrite, + u8 PwrState) +{ + u8 tempval; + u16 tmpV16; + + + if (PwrState == _TRUE) { +#ifdef CONFIG_SDIO_HCI + /* To avoid cannot access efuse regsiters after disable/enable several times during DTM test. */ + /* Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. */ + tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL); + if (tempval & BIT(0)) { /* SDIO local register is suspend */ + u8 count = 0; + + + tempval &= ~BIT(0); + rtw_write8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL, tempval); + + /* check 0x86[1:0]=10'2h, wait power state to leave suspend */ + do { + tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL); + tempval &= 0x3; + if (tempval == 0x02) + break; + + count++; + if (count >= 100) + break; + + rtw_mdelay_os(10); + } while (1); + + if (count >= 100) { + DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n", + FUNC_ADPT_ARG(padapter), tempval); + } else { + DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n", + FUNC_ADPT_ARG(padapter), tempval); + } + } +#endif /* CONFIG_SDIO_HCI */ + + rtw_write8(padapter, REG_EFUSE_ACCESS_8188, EFUSE_ACCESS_ON_8188); + + /* Reset: 0x0000h[28], default valid */ + tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN); + if (!(tmpV16 & FEN_ELDR)) { + tmpV16 |= FEN_ELDR; + rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16); + } + + /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */ + tmpV16 = rtw_read16(padapter, REG_SYS_CLKR); + if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { + tmpV16 |= (LOADER_CLK_EN | ANA8M); + rtw_write16(padapter, REG_SYS_CLKR, tmpV16); + } + + if (bWrite == _TRUE) { + /* Enable LDO 2.5V before read/write action */ + tempval = rtw_read8(padapter, EFUSE_TEST + 3); + tempval &= 0x0F; + tempval |= (VOLTAGE_V25 << 4); + rtw_write8(padapter, EFUSE_TEST + 3, (tempval | 0x80)); + + /*rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); */ + } + } else { + rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + + if (bWrite == _TRUE) { + /* Disable LDO 2.5V after read/write action */ + tempval = rtw_read8(padapter, EFUSE_TEST + 3); + rtw_write8(padapter, EFUSE_TEST + 3, (tempval & 0x7F)); + } + + } +} + +static void +hal_ReadEFuse_WiFi( + PADAPTER padapter, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + u8 bPseudoTest) +{ +#ifdef HAL_EFUSE_MEMORY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; +#endif + u8 *efuseTbl = NULL; + u16 eFuse_Addr = 0; + u8 offset, wden; + u8 efuseHeader, efuseExtHdr, efuseData; + u16 i, total, used; + u8 efuse_usage = 0; + + /*DBG_871X("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest); */ + /* */ + /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */ + /* */ + if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN) { + DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __func__, _offset, _size_byte); + return; + } + + efuseTbl = (u8 *)rtw_malloc(EFUSE_MAX_MAP_LEN); + if (efuseTbl == NULL) { + DBG_8192C("%s: alloc efuseTbl fail!\n", __func__); + return; + } + /* 0xff will be efuse default value instead of 0x00. */ + _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN); + + +#ifdef CONFIG_DEBUG + if (0) { + for (i = 0; i < 256; i++) + /*ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE); */ + efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE); + DBG_871X("Efuse Content:\n"); + for (i = 0; i < 256; i++) + printk("%02X%s", efuseTbl[i], (((i + 1) % 16) == 0)?"\n":" "); + } +#endif + + + /* switch bank back to bank 0 for later BT and wifi use. */ + hal_EfuseSwitchToBank(padapter, 0, bPseudoTest); + + while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) { + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); + if (efuseHeader == 0xFF) { + DBG_8192C("%s: data end at address=%#x\n", __func__, eFuse_Addr - 1); + break; + } + /*DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __func__, eFuse_Addr-1, efuseHeader); */ + + /* Check PG header for section num. */ + if (EXT_HEADER(efuseHeader)) { /*extended header */ + offset = GET_HDR_OFFSET_2_0(efuseHeader); + /*DBG_8192C("%s: extended header offset=0x%X\n", __func__, offset); */ + + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); + /*DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __func__, eFuse_Addr-1, efuseExtHdr); */ + if (ALL_WORDS_DISABLED(efuseExtHdr)) + continue; + + offset |= ((efuseExtHdr & 0xF0) >> 1); + wden = (efuseExtHdr & 0x0F); + } else { + offset = ((efuseHeader >> 4) & 0x0f); + wden = (efuseHeader & 0x0f); + } + /*DBG_8192C("%s: Offset=%d Worden=0x%X\n", __func__, offset, wden); */ + + if (offset < EFUSE_MAX_SECTION_8188F) { + u16 addr; + /* Get word enable value from PG header */ + /*DBG_8192C("%s: Offset=%d Worden=0x%X\n", __func__, offset, wden); */ + + addr = offset * PGPKT_DATA_SIZE; + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (!(wden & (0x01 << i))) { + efuseData = 0; + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest); + /*DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, eFuse_Addr-1, efuseData); */ + efuseTbl[addr] = efuseData; + + efuseData = 0; + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest); + /*DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, eFuse_Addr-1, efuseData); */ + efuseTbl[addr + 1] = efuseData; + } + addr += 2; + } + } else { + DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __func__, offset); + eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2; + } + } + + /* Copy from Efuse map to output pointer memory!!! */ + for (i = 0; i < _size_byte; i++) + pbuf[i] = efuseTbl[_offset + i]; + +#ifdef CONFIG_DEBUG + if (1) { + DBG_871X("Efuse Realmap:\n"); + for (i = 0; i < _size_byte; i++) + printk("%02X%s", pbuf[i], (((i + 1) % 16) == 0)?"\n":" "); + } +#endif + /* Calculate Efuse utilization */ + total = 0; + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest); + used = eFuse_Addr - 1; + if (total) + efuse_usage = (u8)((used * 100) / total); + else + efuse_usage = 100; + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + pEfuseHal->fakeEfuseUsedBytes = used; +#else + fakeEfuseUsedBytes = used; +#endif + } else { + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used); + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8 *)&efuse_usage); + } + + if (efuseTbl) + rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN); +} + +static VOID +hal_ReadEFuse_BT( + PADAPTER padapter, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + u8 bPseudoTest +) +{ +#ifdef HAL_EFUSE_MEMORY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; +#endif + u8 *efuseTbl; + u8 bank; + u16 eFuse_Addr; + u8 efuseHeader, efuseExtHdr, efuseData; + u8 offset, wden; + u16 i, total, used; + u8 efuse_usage; + + + /* */ + /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */ + /* */ + if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) { + DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __func__, _offset, _size_byte); + return; + } + + efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN); + if (efuseTbl == NULL) { + DBG_8192C("%s: efuseTbl malloc fail!\n", __func__); + return; + } + /* 0xff will be efuse default value instead of 0x00. */ + _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN); + + total = 0; + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest); + + for (bank = 1; bank < 3; bank++) { /* 8188F Max bake 0~2 */ + if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) { + DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __func__); + goto exit; + } + + eFuse_Addr = 0; + + while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) { + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); + if (efuseHeader == 0xFF) break; + DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __func__, (((bank - 1)*EFUSE_REAL_CONTENT_LEN_8188F) + eFuse_Addr - 1), efuseHeader); + + /* Check PG header for section num. */ + if (EXT_HEADER(efuseHeader)) { /*extended header */ + offset = GET_HDR_OFFSET_2_0(efuseHeader); + DBG_8192C("%s: extended header offset_2_0=0x%X\n", __func__, offset); + + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); + DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __func__, (((bank - 1)*EFUSE_REAL_CONTENT_LEN_8188F) + eFuse_Addr - 1), efuseExtHdr); + if (ALL_WORDS_DISABLED(efuseExtHdr)) + continue; + + offset |= ((efuseExtHdr & 0xF0) >> 1); + wden = (efuseExtHdr & 0x0F); + } else { + offset = ((efuseHeader >> 4) & 0x0f); + wden = (efuseHeader & 0x0f); + } + + if (offset < EFUSE_BT_MAX_SECTION) { + u16 addr; + + /* Get word enable value from PG header */ + DBG_8192C("%s: Offset=%d Worden=%#X\n", __func__, offset, wden); + + addr = offset * PGPKT_DATA_SIZE; + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (!(wden & (0x01 << i))) { + efuseData = 0; + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest); + DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, eFuse_Addr - 1, efuseData); + efuseTbl[addr] = efuseData; + + efuseData = 0; + /*ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */ + efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest); + DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, eFuse_Addr - 1, efuseData); + efuseTbl[addr + 1] = efuseData; + } + addr += 2; + } + } else { + DBG_8192C("%s: offset(%d) is illegal!!\n", __func__, offset); + eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2; + } + } + + if ((eFuse_Addr - 1) < total) { + DBG_8192C("%s: bank(%d) data end at %#x\n", __func__, bank, eFuse_Addr - 1); + break; + } + } + + /* switch bank back to bank 0 for later BT and wifi use. */ + hal_EfuseSwitchToBank(padapter, 0, bPseudoTest); + + /* Copy from Efuse map to output pointer memory!!! */ + for (i = 0; i < _size_byte; i++) + pbuf[i] = efuseTbl[_offset + i]; + + /* */ + /* Calculate Efuse utilization. */ + /* */ + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest); + used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1; + DBG_8192C("%s: bank(%d) data end at %#x ,used =%d\n", __func__, bank, eFuse_Addr - 1, used); + efuse_usage = (u8)((used * 100) / total); + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + pEfuseHal->fakeBTEfuseUsedBytes = used; +#else + fakeBTEfuseUsedBytes = used; +#endif + } else { + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&used); + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8 *)&efuse_usage); + } + +exit: + if (efuseTbl) + rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN); +} + +static void +Hal_ReadEFuse( + PADAPTER padapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, + u8 bPseudoTest) +{ + if (efuseType == EFUSE_WIFI) + hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest); + else + hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest); +} + +static u16 +hal_EfuseGetCurrentSize_WiFi( + PADAPTER padapter, + u8 bPseudoTest) +{ +#ifdef HAL_EFUSE_MEMORY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; +#endif + u16 efuse_addr = 0; + u16 start_addr = 0; /* for debug */ + u8 hoffset = 0, hworden = 0; + u8 efuse_data, word_cnts = 0; + u32 count = 0; /* for debug */ + + + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes; +#else + efuse_addr = (u16)fakeEfuseUsedBytes; +#endif + } else + rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); + start_addr = efuse_addr; + DBG_8192C("%s: start_efuse_addr=0x%X\n", __func__, efuse_addr); + + /* switch bank back to bank 0 for later BT and wifi use. */ + hal_EfuseSwitchToBank(padapter, 0, bPseudoTest); + +#if 0 /* for debug test */ + efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest); + DBG_8192C(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n", + FUNC_ADPT_ARG(padapter), efuse_data); + efuse_data = 0xFF; +#endif /* for debug test */ + + count = 0; + while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { +#if 1 + if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) { + DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __func__, efuse_addr); + goto error; + } +#else + ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest); +#endif + + if (efuse_data == 0xFF) break; + + if ((start_addr != 0) && (efuse_addr == start_addr)) { + count++; + DBG_8192C(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n", + FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count); + + efuse_data = 0xFF; + if (count < 4) { + /* try again! */ + + if (count > 2) { + /* try again form address 0 */ + efuse_addr = 0; + start_addr = 0; + } + + continue; + } + + goto error; + } + + if (EXT_HEADER(efuse_data)) { + hoffset = GET_HDR_OFFSET_2_0(efuse_data); + efuse_addr++; + efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest); + if (ALL_WORDS_DISABLED(efuse_data)) + continue; + + hoffset |= ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } else { + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + } + + word_cnts = Efuse_CalculateWordCnts(hworden); + efuse_addr += (word_cnts * 2) + 1; + } + + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + pEfuseHal->fakeEfuseUsedBytes = efuse_addr; +#else + fakeEfuseUsedBytes = efuse_addr; +#endif + } else + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr); + + goto exit; + +error: + /* report max size to prevent write efuse */ + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest); + +exit: + DBG_8192C("%s: CurrentSize=%d\n", __func__, efuse_addr); + + return efuse_addr; +} + +static u16 +hal_EfuseGetCurrentSize_BT( + PADAPTER padapter, + u8 bPseudoTest) +{ +#ifdef HAL_EFUSE_MEMORY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; +#endif + u16 btusedbytes; + u16 efuse_addr; + u8 bank, startBank; + u8 hoffset = 0, hworden = 0; + u8 efuse_data, word_cnts = 0; + u16 retU2 = 0; + u8 bContinual = _TRUE; + + + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes; +#else + btusedbytes = fakeBTEfuseUsedBytes; +#endif + } else { + btusedbytes = 0; + rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&btusedbytes); + } + efuse_addr = (u16)((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN)); + startBank = (u8)(1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN)); + + DBG_8192C("%s: start from bank=%d addr=0x%X\n", __func__, startBank, efuse_addr); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest); + + for (bank = startBank; bank < 3; bank++) { + if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) { + DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __func__, bank); + /*bank = EFUSE_MAX_BANK; */ + break; + } + + /* only when bank is switched we have to reset the efuse_addr. */ + if (bank != startBank) + efuse_addr = 0; +#if 1 + + while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { + if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) { + DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __func__, efuse_addr); + /*bank = EFUSE_MAX_BANK; */ + break; + } + DBG_8192C("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __func__, efuse_addr, efuse_data, bank); + + if (efuse_data == 0xFF) break; + + if (EXT_HEADER(efuse_data)) { + hoffset = GET_HDR_OFFSET_2_0(efuse_data); + efuse_addr++; + efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest); + DBG_8192C("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __func__, efuse_addr, efuse_data, bank); + + if (ALL_WORDS_DISABLED(efuse_data)) { + efuse_addr++; + continue; + } + + /*hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */ + hoffset |= ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } else { + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + } + + DBG_8192C(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n", + FUNC_ADPT_ARG(padapter), hoffset, hworden); + + word_cnts = Efuse_CalculateWordCnts(hworden); + /*read next header */ + efuse_addr += (word_cnts * 2) + 1; + } +#else + while (bContinual && + efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest) && + AVAILABLE_EFUSE_ADDR(efuse_addr)) { + if (efuse_data != 0xFF) { + if ((efuse_data & 0x1F) == 0x0F) { /*extended header */ + hoffset = efuse_data; + efuse_addr++; + efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest); + if ((efuse_data & 0x0F) == 0x0F) { + efuse_addr++; + continue; + } else { + hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } + } else { + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + } + word_cnts = Efuse_CalculateWordCnts(hworden); + /*read next header */ + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + } else + bContinual = _FALSE; + } +#endif + + + /* Check if we need to check next bank efuse */ + if (efuse_addr < retU2) { + /* don't need to check next bank. */ + break; + } + } +#if 0 + retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr; + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + pEfuseHal->fakeBTEfuseUsedBytes = retU2; +#else + fakeBTEfuseUsedBytes = retU2; +#endif + } else + rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2); +#else + retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr; + if (bPseudoTest) { + pEfuseHal->fakeBTEfuseUsedBytes = retU2; + /*RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes)); */ + } else { + pEfuseHal->BTEfuseUsedBytes = retU2; + /*RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes)); */ + } +#endif + + DBG_8192C("%s: CurrentSize=%d\n", __func__, retU2); + return retU2; +} + +static u16 +Hal_EfuseGetCurrentSize( + PADAPTER pAdapter, + u8 efuseType, + u8 bPseudoTest) +{ + u16 ret = 0; + + if (efuseType == EFUSE_WIFI) + ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest); + else + ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest); + + return ret; +} + +static u8 +Hal_EfuseWordEnableDataWrite( + PADAPTER padapter, + u16 efuse_addr, + u8 word_en, + u8 *data, + u8 bPseudoTest) +{ + u16 tmpaddr = 0; + u16 start_addr = efuse_addr; + u8 badworden = 0x0F; + u8 tmpdata[PGPKT_DATA_SIZE]; + + + /*DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __func__, efuse_addr, word_en); */ + _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE); + + if (!(word_en & BIT(0))) { + tmpaddr = start_addr; + efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest); + efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest); + + efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest); + efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[1], bPseudoTest); + if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) + badworden &= (~BIT(0)); + } + if (!(word_en & BIT(1))) { + tmpaddr = start_addr; + efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest); + efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest); + + efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest); + efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[3], bPseudoTest); + if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) + badworden &= (~BIT(1)); + } + if (!(word_en & BIT(2))) { + tmpaddr = start_addr; + efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest); + efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest); + + efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest); + efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[5], bPseudoTest); + if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) + badworden &= (~BIT(2)); + } + if (!(word_en & BIT(3))) { + tmpaddr = start_addr; + efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest); + efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest); + + efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest); + efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[7], bPseudoTest); + if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) + badworden &= (~BIT(3)); + } + + return badworden; +} + +static s32 +Hal_EfusePgPacketRead( + PADAPTER padapter, + u8 offset, + u8 *data, + u8 bPseudoTest) +{ + u8 bDataEmpty = _TRUE; + u8 efuse_data, word_cnts = 0; + u16 efuse_addr = 0; + u8 hoffset = 0, hworden = 0; + u8 i; + u8 max_section = 0; + s32 ret; + + + if (data == NULL) + return _FALSE; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest); + if (offset > max_section) { + DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __func__, offset, max_section); + return _FALSE; + } + + _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE); + ret = _TRUE; + + /* */ + /* Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */ + /* Skip dummy parts to prevent unexpected data read from Efuse. */ + /* By pass right now. 2009.02.19. */ + /* */ + while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { + if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE) { + ret = _FALSE; + break; + } + + if (efuse_data == 0xFF) break; + + if (EXT_HEADER(efuse_data)) { + hoffset = GET_HDR_OFFSET_2_0(efuse_data); + efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest); + if (ALL_WORDS_DISABLED(efuse_data)) { + DBG_8192C("%s: Error!! All words disabled!\n", __func__); + continue; + } + + hoffset |= ((efuse_data & 0xF0) >> 1); + hworden = efuse_data & 0x0F; + } else { + hoffset = (efuse_data >> 4) & 0x0F; + hworden = efuse_data & 0x0F; + } + + if (hoffset == offset) { + for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { + /* Check word enable condition in the section */ + if (!(hworden & (0x01 << i))) { + /*ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */ + efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest); + /*DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, efuse_addr+tmpidx, efuse_data); */ + data[i * 2] = efuse_data; + + /*ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */ + efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest); + /*DBG_8192C("%s: efuse[%#X]=0x%02X\n", __func__, efuse_addr+tmpidx, efuse_data); */ + data[(i * 2) + 1] = efuse_data; + } + } + } else { + word_cnts = Efuse_CalculateWordCnts(hworden); + efuse_addr += word_cnts * 2; + } + } + + return ret; +} + +static u8 +hal_EfusePgCheckAvailableAddr( + PADAPTER pAdapter, + u8 efuseType, + u8 bPseudoTest) +{ + u16 max_available = 0; + u16 current_size; + + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest); + /*DBG_8192C("%s: max_available=%d\n", __func__, max_available); */ + + current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest); + if (current_size >= max_available) { + DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __func__, current_size, max_available); + return _FALSE; + } + return _TRUE; +} + +static void +hal_EfuseConstructPGPkt( + u8 offset, + u8 word_en, + u8 *pData, + PPGPKT_STRUCT pTargetPkt) +{ + _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE); + pTargetPkt->offset = offset; + pTargetPkt->word_en = word_en; + efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data); + pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); +} + +#if 0 +static u8 +wordEnMatched( + PPGPKT_STRUCT pTargetPkt, + PPGPKT_STRUCT pCurPkt, + u8 *pWden) +{ + u8 match_word_en = 0x0F; /* default all words are disabled */ + u8 i; + + /* check if the same words are enabled both target and current PG packet */ + if (((pTargetPkt->word_en & BIT(0)) == 0) && + ((pCurPkt->word_en & BIT(0)) == 0)) { + match_word_en &= ~BIT(0); /* enable word 0 */ + } + if (((pTargetPkt->word_en & BIT(1)) == 0) && + ((pCurPkt->word_en & BIT(1)) == 0)) { + match_word_en &= ~BIT(1); /* enable word 1 */ + } + if (((pTargetPkt->word_en & BIT(2)) == 0) && + ((pCurPkt->word_en & BIT(2)) == 0)) { + match_word_en &= ~BIT(2); /* enable word 2 */ + } + if (((pTargetPkt->word_en & BIT(3)) == 0) && + ((pCurPkt->word_en & BIT(3)) == 0)) { + match_word_en &= ~BIT(3); /* enable word 3 */ + } + + *pWden = match_word_en; + + if (match_word_en != 0xf) + return _TRUE; + else + return _FALSE; +} + +static u8 +hal_EfuseCheckIfDatafollowed( + PADAPTER pAdapter, + u8 word_cnts, + u16 startAddr, + u8 bPseudoTest) +{ + u8 bRet = _FALSE; + u8 i, efuse_data; + + for (i = 0; i < (word_cnts * 2); i++) { + if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) == _FALSE) { + DBG_8192C("%s: efuse_OneByteRead FAIL!!\n", __func__); + bRet = _TRUE; + break; + } + + if (efuse_data != 0xFF) { + bRet = _TRUE; + break; + } + } + + return bRet; +} +#endif + +static u8 +hal_EfusePartialWriteCheck( + PADAPTER padapter, + u8 efuseType, + u16 *pAddr, + PPGPKT_STRUCT pTargetPkt, + u8 bPseudoTest) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal; + u8 bRet = _FALSE; + u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0; + u8 efuse_data = 0; +#if 0 + u8 i, cur_header = 0; + u8 new_wden = 0, matched_wden = 0, badworden = 0; + PGPKT_STRUCT curPkt; +#endif + + + EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest); + EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest); + + if (efuseType == EFUSE_WIFI) { + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes; +#else + startAddr = (u16)fakeEfuseUsedBytes; +#endif + } else + rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr); + } else { + if (bPseudoTest) { +#ifdef HAL_EFUSE_MEMORY + startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes; +#else + startAddr = (u16)fakeBTEfuseUsedBytes; +#endif + } else + rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr); + } + startAddr %= efuse_max; + DBG_8192C("%s: startAddr=%#X\n", __func__, startAddr); + + while (1) { + if (startAddr >= efuse_max_available_len) { + bRet = _FALSE; + DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n", + __func__, startAddr, efuse_max_available_len); + break; + } + + if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) { +#if 1 + bRet = _FALSE; + DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n", + __func__, startAddr, efuse_data); + break; +#else + if (EXT_HEADER(efuse_data)) { + cur_header = efuse_data; + startAddr++; + efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest); + if (ALL_WORDS_DISABLED(efuse_data)) { + DBG_8192C("%s: Error condition, all words disabled!", __func__); + bRet = _FALSE; + break; + } else { + curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); + curPkt.word_en = efuse_data & 0x0F; + } + } else { + cur_header = efuse_data; + curPkt.offset = (cur_header >> 4) & 0x0F; + curPkt.word_en = cur_header & 0x0F; + } + + curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en); + /* if same header is found but no data followed */ + /* write some part of data followed by the header. */ + if ((curPkt.offset == pTargetPkt->offset) && + (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr + 1, bPseudoTest) == _FALSE) && + wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE) { + DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __func__); + /* Here to write partial data */ + badworden = Efuse_WordEnableDataWrite(padapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest); + if (badworden != 0x0F) { + u32 PgWriteSuccess = 0; + /* if write fail on some words, write these bad words again */ + if (efuseType == EFUSE_WIFI) + PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + else + PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest); + + if (!PgWriteSuccess) { + bRet = _FALSE; /* write fail, return */ + break; + } + } + /* partial write ok, update the target packet for later use */ + for (i = 0; i < 4; i++) { + if ((matched_wden & (0x1 << i)) == 0) { /* this word has been written */ + pTargetPkt->word_en |= (0x1 << i); /* disable the word */ + } + } + pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en); + } + /* read from next header */ + startAddr = startAddr + (curPkt.word_cnts * 2) + 1; +#endif + } else { + /* not used header, 0xff */ + *pAddr = startAddr; + /*DBG_8192C("%s: Started from unused header offset=%d\n", __func__, startAddr)); */ + bRet = _TRUE; + break; + } + } + + return bRet; +} + +static u8 +hal_EfusePgPacketWrite1ByteHeader( + PADAPTER pAdapter, + u8 efuseType, + u16 *pAddr, + PPGPKT_STRUCT pTargetPkt, + u8 bPseudoTest) +{ + u8 bRet = _FALSE; + u8 pg_header = 0, tmp_header = 0; + u16 efuse_addr = *pAddr; + u8 repeatcnt = 0; + + + /*DBG_8192C("%s\n", __func__); */ + pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en; + + do { + efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest); + if (tmp_header != 0xFF) break; + if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { + DBG_8192C("%s: Repeat over limit for pg_header!!\n", __func__); + return _FALSE; + } + } while (1); + + if (tmp_header != pg_header) { + DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __func__, pg_header, tmp_header); + return _FALSE; + } + + *pAddr = efuse_addr; + + return _TRUE; +} + +static u8 +hal_EfusePgPacketWrite2ByteHeader( + PADAPTER padapter, + u8 efuseType, + u16 *pAddr, + PPGPKT_STRUCT pTargetPkt, + u8 bPseudoTest) +{ + u16 efuse_addr, efuse_max_available_len = 0; + u8 pg_header = 0, tmp_header = 0; + u8 repeatcnt = 0; + + + /*DBG_8192C("%s\n", __func__); */ + EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest); + + efuse_addr = *pAddr; + if (efuse_addr >= efuse_max_available_len) { + DBG_8192C("%s: addr(%d) over available(%d)!!\n", __func__, efuse_addr, efuse_max_available_len); + return _FALSE; + } + + pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; + /*DBG_8192C("%s: pg_header=0x%x\n", __func__, pg_header); */ + + do { + efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest); + if (tmp_header != 0xFF) break; + if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { + DBG_8192C("%s: Repeat over limit for pg_header!!\n", __func__); + return _FALSE; + } + } while (1); + + if (tmp_header != pg_header) { + DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __func__, pg_header, tmp_header); + return _FALSE; + } + + /* to write ext_header */ + efuse_addr++; + pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; + + do { + efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest); + efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest); + if (tmp_header != 0xFF) break; + if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { + DBG_8192C("%s: Repeat over limit for ext_header!!\n", __func__); + return _FALSE; + } + } while (1); + + if (tmp_header != pg_header) { /*offset PG fail */ + DBG_8192C(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __func__, pg_header, tmp_header); + return _FALSE; + } + + *pAddr = efuse_addr; + + return _TRUE; +} + +static u8 +hal_EfusePgPacketWriteHeader( + PADAPTER padapter, + u8 efuseType, + u16 *pAddr, + PPGPKT_STRUCT pTargetPkt, + u8 bPseudoTest) +{ + u8 bRet = _FALSE; + + if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) + bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest); + else + bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest); + + return bRet; +} + +static u8 +hal_EfusePgPacketWriteData( + PADAPTER pAdapter, + u8 efuseType, + u16 *pAddr, + PPGPKT_STRUCT pTargetPkt, + u8 bPseudoTest) +{ + u16 efuse_addr; + u8 badworden; + + + efuse_addr = *pAddr; + badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest); + if (badworden != 0x0F) { + DBG_8192C("%s: Fail!!\n", __func__); + return _FALSE; + } + + /*DBG_8192C("%s: ok\n", __func__); */ + return _TRUE; +} + +static s32 +Hal_EfusePgPacketWrite( + PADAPTER padapter, + u8 offset, + u8 word_en, + u8 *pData, + u8 bPseudoTest) +{ + PGPKT_STRUCT targetPkt; + u16 startAddr = 0; + u8 efuseType = EFUSE_WIFI; + + if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest)) + return _FALSE; + + hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); + + if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + return _TRUE; +} + +static u8 +Hal_EfusePgPacketWrite_BT( + PADAPTER pAdapter, + u8 offset, + u8 word_en, + u8 *pData, + u8 bPseudoTest) +{ + PGPKT_STRUCT targetPkt; + u16 startAddr = 0; + u8 efuseType = EFUSE_BT; + + if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest)) + return _FALSE; + + hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); + + if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) + return _FALSE; + + return _TRUE; +} + + +static void rtl8188f_read_chip_version(PADAPTER padapter) +{ + u32 value32; + HAL_DATA_TYPE *pHalData; + u8 tmpvdr; + pHalData = GET_HAL_DATA(padapter); + + value32 = rtw_read32(padapter, REG_SYS_CFG); + pHalData->VersionID.ICType = CHIP_8188F; + pHalData->VersionID.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); + pHalData->VersionID.RFType = RF_TYPE_1T1R; + + tmpvdr = (value32 & EXT_VENDOR_ID) >> EXT_VENDOR_ID_SHIFT; + if (tmpvdr == 0x00) + pHalData->VersionID.VendorType = CHIP_VENDOR_TSMC; + else if (tmpvdr == 0x01) + pHalData->VersionID.VendorType = CHIP_VENDOR_SMIC; + else if (tmpvdr == 0x02) + pHalData->VersionID.VendorType = CHIP_VENDOR_UMC; + + pHalData->VersionID.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */ + + #if 0 + /* For regulator mode. by tynli. 2011.01.14 */ + pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR); + #endif + + #if 0 + value32 = rtw_read32(padapter, REG_GPIO_OUTSTS); + pHalData->VersionID.ROMVer = ((value32 & RF_RL_ID) >> 20); /* ROM code version. */ + #endif + + #if 0 + /* For multi-function consideration. Added by Roger, 2010.10.06. */ + pHalData->MultiFunc = RT_MULTI_FUNC_NONE; + value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL); + pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0); + pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0); + pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0); + pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT); + #endif + + rtw_hal_config_rftype(padapter); + +#if 0 /* mark for chage to use efuse */ + if (IS_B_CUT(pHalData->VersionID) || IS_C_CUT(pHalData->VersionID)) { + MSG_8192C(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n"); + PHY_SetMacReg(padapter, 0x14, BIT23 | BIT22 | BIT21 | BIT20, 0x5); /* MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V) */ + } else if (IS_D_CUT(pHalData->VersionID)) + MSG_8192C(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n"); +#endif /* mark for chage to use efuse */ + +#if 1 + dump_chip_info(pHalData->VersionID); +#endif + +} + + +void rtl8188f_InitBeaconParameters(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u16 val16; + u8 val8; + + + val8 = DIS_TSF_UDT; + val16 = val8 | (val8 << 8); /* port0 and port1 */ +#ifdef CONFIG_BT_COEXIST + /* Enable prot0 beacon function for PSTDMA */ + val16 |= EN_BCN_FUNCTION; +#endif + rtw_write16(padapter, REG_BCN_CTRL, val16); + + /* TODO: Remove these magic number */ + rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */ + /* Firmware will control REG_DRVERLYINT when power saving is enable, */ + /* so don't set this register on STA mode. */ + if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE) + rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8188F); /* 5ms */ + rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8188F); /* 2ms */ + + /* Suggested by designer timchen. Change beacon AIFS to the largest number */ + /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */ + rtw_write16(padapter, REG_BCNTCFG, 0x660F); + + pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL); + pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE); + pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2); + pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT + 2); + pHalData->RegCR_1 = rtw_read8(padapter, REG_CR + 1); +} + +void rtl8188f_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode) +{ +#ifdef CONFIG_ADHOC_WORKAROUND_SETTING + rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); +#else + /*rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10)); */ +#endif +} + +void _InitBurstPktLen_8188FS(PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + rtw_write8(Adapter, 0x4c7, rtw_read8(Adapter, 0x4c7) | BIT(7)); /*enable single pkt ampdu */ + rtw_write8(Adapter, REG_RX_PKT_LIMIT_8188F, 0x18); /*for VHT packet length 11K */ + rtw_write8(Adapter, REG_MAX_AGGR_NUM_8188F, 0x1F); + rtw_write8(Adapter, REG_PIFS_8188F, 0x00); + rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8188F, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL) & (~BIT(7))); + if (pHalData->AMPDUBurstMode) + rtw_write8(Adapter, REG_AMPDU_BURST_MODE_8188F, 0x5F); + rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8188F, 0x70); + + /* ARFB table 9 for 11ac 5G 2SS */ + rtw_write32(Adapter, REG_ARFR0_8188F, 0x00000010); + if (IS_NORMAL_CHIP(pHalData->VersionID)) + rtw_write32(Adapter, REG_ARFR0_8188F + 4, 0xfffff000); + else + rtw_write32(Adapter, REG_ARFR0_8188F + 4, 0x3e0ff000); + + /* ARFB table 10 for 11ac 5G 1SS */ + rtw_write32(Adapter, REG_ARFR1_8188F, 0x00000010); + rtw_write32(Adapter, REG_ARFR1_8188F + 4, 0x003ff000); +} + +static void ResumeTxBeacon(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + + /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ + /* which should be read from register to a global variable. */ + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n")); + + pHalData->RegFwHwTxQCtrl |= BIT(6); + rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); + rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff); + pHalData->RegReg542 |= BIT(0); + rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542); +} + +static void StopTxBeacon(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + + /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */ + /* which should be read from register to a global variable. */ + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n")); + + pHalData->RegFwHwTxQCtrl &= ~BIT(6); + rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); + rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64); + pHalData->RegReg542 &= ~BIT(0); + rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542); + + CheckFwRsvdPageContent(padapter); /* 2010.06.23. Added by tynli. */ +} + +static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked) +{ + rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB); + rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F); +} + +static void rtl8188f_SetBeaconRelatedRegisters(PADAPTER padapter) +{ + u8 val8; + u32 value32; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + u32 bcn_ctrl_reg; + + /*reset TSF, enable update TSF, correcting TSF On Beacon */ + + /*REG_BCN_INTERVAL */ + /*REG_BCNDMATIM */ + /*REG_ATIMWND */ + /*REG_TBTT_PROHIBIT */ + /*REG_DRVERLYINT */ + /*REG_BCN_MAX_ERR */ + /*REG_BCNTCFG //(0x510) */ + /*REG_DUAL_TSF_RST */ + /*REG_BCN_CTRL //(0x550) */ + + + bcn_ctrl_reg = REG_BCN_CTRL; +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) + bcn_ctrl_reg = REG_BCN_CTRL_1; +#endif + + /* */ + /* ATIM window */ + /* */ + rtw_write16(padapter, REG_ATIMWND, 2); + + /* */ + /* Beacon interval (in unit of TU). */ + /* */ + rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); + + rtl8188f_InitBeaconParameters(padapter); + + rtw_write8(padapter, REG_SLOT, 0x09); + + /* */ + /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */ + /* */ + value32 = rtw_read32(padapter, REG_TCR); + value32 &= ~TSFRST; + rtw_write32(padapter, REG_TCR, value32); + + value32 |= TSFRST; + rtw_write32(padapter, REG_TCR, value32); + + /* NOTE: Fix test chip's bug (about contention windows's randomness) */ + if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == _TRUE) { + rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50); + rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50); + } + + _BeaconFunctionEnable(padapter, _TRUE, _TRUE); + + ResumeTxBeacon(padapter); + val8 = rtw_read8(padapter, bcn_ctrl_reg); + val8 |= DIS_BCNQ_SUB; + rtw_write8(padapter, bcn_ctrl_reg, val8); +} + +void hal_notch_filter_8188f(_adapter *adapter, bool enable) +{ + if (enable) { + DBG_871X("Enable notch filter\n"); + rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1); + } else { + DBG_871X("Disable notch filter\n"); + rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1); + } +} + +u8 rtl8188f_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx) +{ + u8 ret = 0; + RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter); + switch (rate_idx) { + + case RATR_INX_WIRELESS_NGB: + if (rftype == RF_1T1R) + ret = 1; + else + ret = 0; + break; + + case RATR_INX_WIRELESS_N: + case RATR_INX_WIRELESS_NG: + if (rftype == RF_1T1R) + ret = 5; + else + ret = 4; + break; + + case RATR_INX_WIRELESS_NB: + if (rftype == RF_1T1R) + ret = 3; + else + ret = 2; + break; + + case RATR_INX_WIRELESS_GB: + ret = 6; + break; + + case RATR_INX_WIRELESS_G: + ret = 7; + break; + + case RATR_INX_WIRELESS_B: + ret = 8; + break; + + case RATR_INX_WIRELESS_MC: + if (padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N) + ret = 6; + else + ret = 7; + break; + case RATR_INX_WIRELESS_AC_N: + if (rftype == RF_1T1R) /* || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9) */ + ret = 10; + else + ret = 9; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +void UpdateHalRAMask8188F(PADAPTER padapter, u32 mac_id, u8 rssi_level) +{ + u32 mask, rate_bitmap; + u8 shortGIrate = _FALSE; + struct sta_info *psta = NULL; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl; + + if (mac_id < macid_ctl->num) + psta = macid_ctl->sta[mac_id]; + if (psta == NULL) { + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u, sta is NULL\n" + , FUNC_ADPT_ARG(padapter), mac_id); + return; + } + + shortGIrate = query_ra_short_GI(psta); + + mask = psta->ra_mask; + + rate_bitmap = 0xffffffff; + rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level); + DBG_871X("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n", + __func__, mac_id, psta->wireless_mode, mask, rssi_level, rate_bitmap); + + mask &= rate_bitmap; + +#ifdef CONFIG_BT_COEXIST + rate_bitmap = rtw_btcoex_GetRaMask(padapter); + mask &= ~rate_bitmap; +#endif /* CONFIG_BT_COEXIST */ + +#ifdef CONFIG_CMCC_TEST +#ifdef CONFIG_BT_COEXIST + if (pmlmeext->cur_wireless_mode & WIRELESS_11G) { + if (mac_id == 0) { + DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask); + /*mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC */ + mask &= 0xffffff00; /*disable CCK & <24M OFDM rate for 11G mode for CMCC */ + DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask); + } + } +#endif +#endif + + if (pHalData->fw_ractrl == _TRUE) + rtl8188f_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask); + + /*set correct initial date rate for each mac_id */ + pHalData->INIDATA_RATE[mac_id] = psta->init_rate; + 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); +} + +/* */ +/* Description: In normal chip, we should send some packet to Hw which will be used by Fw */ +/* in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */ +/* Fw can tell Hw to send these packet derectly. */ +/* Added by tynli. 2009.10.15. */ +/* */ +/*type1:pspoll, type2:null */ +void rtl8188f_fill_fake_txdesc( + PADAPTER padapter, + u8 *pDesc, + u32 BufferLen, + u8 IsPsPoll, + u8 IsBTQosNull, + u8 bDataFrame) +{ + /* Clear all status */ + _rtw_memset(pDesc, 0, TXDESC_SIZE); + + SET_TX_DESC_FIRST_SEG_8188F(pDesc, 1); /*bFirstSeg; */ + SET_TX_DESC_LAST_SEG_8188F(pDesc, 1); /*bLastSeg; */ + + SET_TX_DESC_OFFSET_8188F(pDesc, 0x28); /* Offset = 32 */ + + SET_TX_DESC_PKT_SIZE_8188F(pDesc, BufferLen); /* Buffer size + command header */ + SET_TX_DESC_QUEUE_SEL_8188F(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) { + /* Nothing */ + SET_TX_DESC_NAV_USE_HDR_8188F(pDesc, 1); + } else { + SET_TX_DESC_HWSEQ_EN_8188F(pDesc, 1); /* Hw set sequence number */ + SET_TX_DESC_HWSEQ_SEL_8188F(pDesc, 0); + } + + if (_TRUE == IsBTQosNull) + SET_TX_DESC_BT_INT_8188F(pDesc, 1); + + SET_TX_DESC_USE_RATE_8188F(pDesc, 1); /* use data rate which is set by Sw */ + SET_TX_DESC_OWN_8188F((pu1Byte)pDesc, 1); + + SET_TX_DESC_TX_RATE_8188F(pDesc, DESC8188F_RATE1M); + + /* */ + /* 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_8188F(pDesc, 0x0); + break; + case _WEP40_: + case _WEP104_: + case _TKIP_: + SET_TX_DESC_SEC_TYPE_8188F(pDesc, 0x1); + break; + case _SMS4_: + SET_TX_DESC_SEC_TYPE_8188F(pDesc, 0x2); + break; + case _AES_: + SET_TX_DESC_SEC_TYPE_8188F(pDesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE_8188F(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.). */ + rtl8188f_cal_txdesc_chksum((struct tx_desc *)pDesc); +#endif +} + +void rtl8188f_set_hal_ops(struct hal_ops *pHalFunc) +{ + pHalFunc->dm_init = &rtl8188f_init_dm_priv; + pHalFunc->dm_deinit = &rtl8188f_deinit_dm_priv; + + pHalFunc->read_chip_version = &rtl8188f_read_chip_version; + + pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8188F; + pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188F; + pHalFunc->set_channel_handler = &PHY_SwChnl8188F; + pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8188F; + + pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8188F; + pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8188F; + + pHalFunc->hal_dm_watchdog = &rtl8188f_HalDmWatchDog; +#ifdef CONFIG_LPS_LCLK_WD_TIMER + pHalFunc->hal_dm_watchdog_in_lps = &rtl8188f_HalDmWatchDog_in_LPS; +#endif /* CONFIG_LPS_LCLK_WD_TIMER */ + +#ifdef CONFIG_C2H_PACKET_EN + pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8188F; +#endif /* CONFIG_C2H_PACKET_EN */ + + pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8188f_SetBeaconRelatedRegisters; + + pHalFunc->Add_RateATid = &rtl8188f_Add_RateATid; + + pHalFunc->run_thread = &rtl8188f_start_thread; + pHalFunc->cancel_thread = &rtl8188f_stop_thread; + + pHalFunc->read_bbreg = &PHY_QueryBBReg_8188F; + pHalFunc->write_bbreg = &PHY_SetBBReg_8188F; + pHalFunc->read_rfreg = &PHY_QueryRFReg_8188F; + pHalFunc->write_rfreg = &PHY_SetRFReg_8188F; + + /* Efuse related function */ + pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch; + pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch; + pHalFunc->ReadEFuse = &Hal_ReadEFuse; + pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition; + pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize; + pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead; + pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite; + pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite; + pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT; + +#ifdef DBG_CONFIG_ERROR_DETECT + pHalFunc->sreset_init_value = &sreset_init_value; + pHalFunc->sreset_reset_value = &sreset_reset_value; + pHalFunc->silentreset = &sreset_reset; + pHalFunc->sreset_xmit_status_check = &rtl8188f_sreset_xmit_status_check; + pHalFunc->sreset_linked_status_check = &rtl8188f_sreset_linked_status_check; + pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status; + pHalFunc->sreset_inprogress = &sreset_inprogress; +#endif + pHalFunc->GetHalODMVarHandler = GetHalODMVar; + pHalFunc->SetHalODMVarHandler = SetHalODMVar; + +#ifdef CONFIG_XMIT_THREAD_MODE + pHalFunc->xmit_thread_handler = &hal_xmit_handler; +#endif + pHalFunc->hal_notch_filter = &hal_notch_filter_8188f; + + pHalFunc->c2h_handler = c2h_handler_8188f; + pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8188f; + + pHalFunc->fill_h2c_cmd = &FillH2CCmd8188F; + pHalFunc->fill_fake_txdesc = &rtl8188f_fill_fake_txdesc; +#ifdef CONFIG_WOWLAN + pHalFunc->hal_set_wowlan_fw = &SetFwRelatedForWoWLAN8188f; +#endif + pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8188F; +} + +void rtl8188f_InitAntenna_Selection(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 val; + + + pHalData = GET_HAL_DATA(padapter); +#if 0 + val = rtw_read8(padapter, REG_LEDCFG2); + /* Let 8051 take control antenna setting */ + val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */ + rtw_write8(padapter, REG_LEDCFG2, val); +#else + /* TODO: <20130114, Kordan> The following setting is only for DPDT and Fixed board type. */ + /* TODO: A better solution is configure it according EFUSE during the run-time. */ + PHY_SetMacReg(padapter, 0x64, BIT20, 0x0); /*0x66[4]=0 */ + PHY_SetMacReg(padapter, 0x64, BIT24, 0x0); /*0x66[8]=0 */ + PHY_SetMacReg(padapter, 0x40, BIT4, 0x0); /*0x40[4]=0 */ + PHY_SetMacReg(padapter, 0x40, BIT3, 0x1); /*0x40[3]=1 */ + PHY_SetMacReg(padapter, 0x4C, BIT24, 0x1); /*0x4C[24:23]=10 */ + PHY_SetMacReg(padapter, 0x4C, BIT23, 0x0); /*0x4C[24:23]=10 */ + PHY_SetBBReg(padapter, 0x944, BIT1 | BIT0, 0x3); /*0x944[1:0]=11 */ + PHY_SetBBReg(padapter, 0x930, bMaskByte0, 0x77); /*0x930[7:0]=77 */ + PHY_SetMacReg(padapter, 0x38, BIT11, 0x1); /*0x38[11]=1 */ +#endif +} + +void rtl8188f_CheckAntenna_Selection(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 val; + + + pHalData = GET_HAL_DATA(padapter); + + val = rtw_read8(padapter, REG_LEDCFG2); + /* Let 8051 take control antenna stetting */ + if (!(val & BIT(7))) { + val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */ + rtw_write8(padapter, REG_LEDCFG2, val); + } +} +void rtl8188f_DeinitAntenna_Selection(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 val; + + + pHalData = GET_HAL_DATA(padapter); + val = rtw_read8(padapter, REG_LEDCFG2); + /* Let 8051 take control antenna stetting */ + val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */ + rtw_write8(padapter, REG_LEDCFG2, val); + +} + +void init_hal_spec_8188f(_adapter *adapter) +{ + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + + hal_spec->macid_num = MACID_NUM_8188F; + hal_spec->sec_cam_ent_num = SEC_CAM_ENT_NUM_8188F; + hal_spec->sec_cap = 0; + hal_spec->nss_num = NSS_NUM_8188F; + hal_spec->band_cap = BAND_CAP_8188F; + hal_spec->bw_cap = BW_CAP_8188F; + + hal_spec->wl_func = 0 + | WL_FUNC_P2P + | WL_FUNC_MIRACAST + | WL_FUNC_TDLS + ; +} + +void rtl8188f_init_default_value(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 i; + pHalData = GET_HAL_DATA(padapter); + + /* init default value */ + pHalData->fw_ractrl = _FALSE; + if (!adapter_to_pwrctl(padapter)->bkeepfwalive) + pHalData->LastHMEBoxNum = 0; + + padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N; + + /*init phydm default value */ + pHalData->bIQKInitialized = _FALSE; + pHalData->odmpriv.RFCalibrateInfo.TM_Trigger = 0;/*for IQK */ + pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP_index = 0; + for (i = 0; i < HP_THERMAL_NUM; i++) + pHalData->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0; + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI) + pHalData->IntrMask[0] = (u32)( + /* IMR_ROK | */ + /* IMR_RDU | */ + /* IMR_VODOK | */ + /* IMR_VIDOK | */ + /* IMR_BEDOK | */ + /* IMR_BKDOK | */ + /* IMR_MGNTDOK | */ + /* IMR_HIGHDOK | */ + /* IMR_CPWM | */ + /* IMR_CPWM2 | */ + /* IMR_C2HCMD | */ + /* IMR_HISR1_IND_INT | */ + /* IMR_ATIMEND | */ + /* IMR_BCNDMAINT_E | */ + /* IMR_HSISR_IND_ON_INT | */ + /* IMR_BCNDOK0 | */ + /* IMR_BCNDMAINT0 | */ + /* IMR_TSF_BIT32_TOGGLE | */ + /* IMR_TXBCN0OK | */ + /* IMR_TXBCN0ERR | */ + /* IMR_GTINT3 | */ + /* IMR_GTINT4 | */ + /* IMR_TXCCK | */ + 0); + + pHalData->IntrMask[1] = (u32)( + /* IMR_RXFOVW | */ + /* IMR_TXFOVW | */ + /* IMR_RXERR | */ + /* IMR_TXERR | */ + /* IMR_ATIMEND_E | */ + /* IMR_BCNDOK1 | */ + /* IMR_BCNDOK2 | */ + /* IMR_BCNDOK3 | */ + /* IMR_BCNDOK4 | */ + /* IMR_BCNDOK5 | */ + /* IMR_BCNDOK6 | */ + /* IMR_BCNDOK7 | */ + /* IMR_BCNDMAINT1 | */ + /* IMR_BCNDMAINT2 | */ + /* IMR_BCNDMAINT3 | */ + /* IMR_BCNDMAINT4 | */ + /* IMR_BCNDMAINT5 | */ + /* IMR_BCNDMAINT6 | */ + /* IMR_BCNDMAINT7 | */ + 0); +#endif + + /* init Efuse variables */ + pHalData->EfuseUsedBytes = 0; + pHalData->EfuseUsedPercentage = 0; +#ifdef HAL_EFUSE_MEMORY + pHalData->EfuseHal.fakeEfuseBank = 0; + pHalData->EfuseHal.fakeEfuseUsedBytes = 0; + _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE); + _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN); + _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN); + pHalData->EfuseHal.BTEfuseUsedBytes = 0; + pHalData->EfuseHal.BTEfuseUsedPercentage = 0; + _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE); + _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN); + _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN); + pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0; + _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE); + _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN); + _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN); +#endif +} + +u8 GetEEPROMSize8188F(PADAPTER padapter) +{ + u8 size = 0; + u32 cr; + + cr = rtw_read16(padapter, REG_9346CR); + /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */ + size = (cr & BOOT_FROM_EEPROM) ? 6 : 4; + + MSG_8192C("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46"); + + return size; +} + +/*------------------------------------------------------------------------- */ +/* */ +/* LLT R/W/Init function */ +/* */ +/*------------------------------------------------------------------------- */ +s32 rtl8188f_InitLLTTable(PADAPTER padapter) +{ + u32 start, passing_time; + u32 val32; + s32 ret; + + + ret = _FAIL; + + val32 = rtw_read32(padapter, REG_AUTO_LLT); + val32 |= BIT_AUTO_INIT_LLT; + rtw_write32(padapter, REG_AUTO_LLT, val32); + + start = rtw_get_current_time(); + + do { + val32 = rtw_read32(padapter, REG_AUTO_LLT); + if (!(val32 & BIT_AUTO_INIT_LLT)) { + ret = _SUCCESS; + break; + } + + passing_time = rtw_get_passing_time_ms(start); + if (passing_time > 1000) { + DBG_8192C("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n", + __func__, REG_AUTO_LLT, val32); + break; + } + + rtw_usleep_os(2); + } while (1); + + return ret; +} + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +void _DisableGPIO(PADAPTER padapter) +{ + /* + * j. GPIO_PIN_CTRL 0x44[31:0]=0x000 + * k.Value = GPIO_PIN_CTRL[7:0] + * l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level + * m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 + * n. LEDCFG 0x4C[15:0] = 0x8080 + */ + u8 value8; + u16 value16; + u32 value32; + u32 u4bTmp; + + + /*1. Disable GPIO[7:0] */ + rtw_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000); + value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; + u4bTmp = value32 & 0x000000FF; + value32 |= ((u4bTmp << 8) | 0x00FF0000); + rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32); + + + /*2. Disable GPIO[10:8] */ + rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00); + value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F; + value8 = (u8)(value16 & 0x000F); + value16 |= ((value8 << 4) | 0x0780); + rtw_write16(padapter, REG_GPIO_IO_SEL, value16); + + + /*3. Disable LED0 & 1 */ + rtw_write16(padapter, REG_LEDCFG0, 0x8080); + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n")); */ +} /*end of _DisableGPIO() */ + +void _DisableRFAFEAndResetBB8188F(PADAPTER padapter) +{ + /* + * a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue + * b. RF path 0 offset 0x00 = 0x00 disable RF + * c. APSD_CTRL 0x600[7:0] = 0x40 + * d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine + * e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine + */ + u8 eRFPath = 0, value8 = 0; + + rtw_write8(padapter, REG_TXPAUSE, 0xFF); + + PHY_SetRFReg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0); + + value8 |= APSDOFF; + rtw_write8(padapter, REG_APSD_CTRL, value8);/*0x40 */ + + /* Set BB reset at first */ + value8 = 0; + value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); + rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /*0x16 */ + + /* Set global reset. */ + value8 &= ~FEN_BB_GLB_RSTn; + rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /*0x14 */ + + /* 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode. */ + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); */ +} + +void _DisableRFAFEAndResetBB(PADAPTER padapter) +{ + _DisableRFAFEAndResetBB8188F(padapter); +} + +void _ResetDigitalProcedure1_8188F(PADAPTER padapter, BOOLEAN bWithoutHWSM) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) { +#if 0 + /* + * f. SYS_FUNC_EN 0x03[7:0]=0x54 reset MAC register, DCORE + * g. MCUFWDL 0x80[7:0]=0 reset MCU ready status + */ + u32 value32 = 0; + + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54); + rtw_write8(padapter, REG_MCUFWDL, 0); +#else + /* + * f. MCUFWDL 0x80[7:0]=0 reset MCU ready status + * g. SYS_FUNC_EN 0x02[10]= 0 reset MCU register, (8051 reset) + * h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC register, DCORE + * i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register, (8051 enable) + */ + u16 valu16 = 0; + + rtw_write8(padapter, REG_MCUFWDL, 0); + + valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN); + rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));/*reset MCU ,8051 */ + + valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF; + rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | (FEN_HWPDN | FEN_ELDR))); /*reset MAC */ + + valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN); + rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));/*enable MCU ,8051 */ +#endif + } else { + u8 retry_cnts = 0; + + /* 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to */ + /* enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because */ + /* we will init FW when power on again. */ + /*if(!pDevice->RegUsbSS) */ + { + /* If we want to SS mode, we can not reset 8051. */ + if (rtw_read8(padapter, REG_MCUFWDL) & BIT1) { + /*IF fw in RAM code, do reset */ + + + if (padapter->bFWReady) { + /* 2010/08/25 MH According to RD alfred's suggestion, we need to disable other */ + /* HRCV INT to influence 8051 reset. */ + rtw_write8(padapter, REG_FWIMR, 0x20); + /* 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation. */ + rtw_write8(padapter, REG_FTIMR, 0x00); + rtw_write8(padapter, REG_FSIMR, 0x00); + + rtw_write8(padapter, REG_HMETFR + 3, 0x20); /*8051 reset by self */ + + while ((retry_cnts++ < 100) && (FEN_CPUEN & rtw_read16(padapter, REG_SYS_FUNC_EN))) { + rtw_udelay_os(50);/*us */ + /* 2010/08/25 For test only We keep on reset 5051 to prevent fail. */ + /*rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self */ + } + /*RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n")); */ + + if (retry_cnts >= 100) { + /* if 8051 reset fail we trigger GPIO 0 for LA */ + /*rtw_write32( padapter, */ + /* REG_GPIO_PIN_CTRL, */ + /* 0x00010100); */ + /* 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly. */ + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x50); /*Reset MAC and Enable 8051 */ + rtw_mdelay_os(10); + } + /*else */ + /* RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts)); */ + } + } + /*else */ + /*{ */ + /* RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n")); */ + /*} */ + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54); /*Reset MAC and Enable 8051 */ + rtw_write8(padapter, REG_MCUFWDL, 0); + } + } + + /*if(pDevice->RegUsbSS) */ + /*bWithoutHWSM = TRUE; // Sugest by Filen and Issau. */ + + if (bWithoutHWSM) { + /*HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */ + /* + * Without HW auto state machine + * SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock + * h. AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL + * i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK + * j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 isolated digital to PON + */ + /*rtw_write16(padapter, REG_SYS_CLKR, 0x30A3); */ + /*if(!pDevice->RegUsbSS) */ + /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */ + rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); /*modify to 0x70A3 by Scott. */ + rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80); + rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F); + /*if(!pDevice->RegUsbSS) */ + rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9); + } else { + /* Disable all RF/BB power */ + rtw_write8(padapter, REG_RF_CTRL, 0x00); + } + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n")); */ + +} + +void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM) +{ + _ResetDigitalProcedure1_8188F(padapter, bWithoutHWSM); +} + +void _ResetDigitalProcedure2(PADAPTER padapter) +{ + /*HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */ + /* + * k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction + * l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock + * m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON + */ + /*rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott. */ + /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */ + rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); /*modify to 0x70a3 by Scott. */ + rtw_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82); /*modify to 0x82 by Scott. */ +} + +void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u16 value16 = 0; + u8 value8 = 0; + + + if (bWithoutHWSM) { + /* + * n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power + * o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power + * r. When driver call disable, the ASIC will turn off remaining clock automatically + */ + + rtw_write8(padapter, REG_LDOA15_CTRL, 0x04); + /*rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54); */ + + value8 = rtw_read8(padapter, REG_LDOV12D_CTRL); + value8 &= (~LDV12_EN); + rtw_write8(padapter, REG_LDOV12D_CTRL, value8); + /*RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8)); */ + } + + /* + * h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode + * i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend + */ + value8 = 0x23; + + rtw_write8(padapter, REG_SPS0_CTRL, value8); + + if (bWithoutHWSM) { + /*value16 |= (APDM_HOST | PFM_ALDN); */ + /* 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically. */ + /* Because suspend operation need the asistance of 8051 to wait for 3ms. */ + value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + } else + value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + + rtw_write16(padapter, REG_APS_FSMCO, value16);/*0x4802 */ + + rtw_write8(padapter, REG_RSV_CTRL, 0x0e); + +#if 0 + /*tynli_test for suspend mode. */ + if (!bWithoutHWSM) + rtw_write8(padapter, 0xfe10, 0x19); +#endif + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16)); */ +} + +/* HW Auto state machine */ +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU) +{ + int rtStatus = _SUCCESS; + + + if (RTW_CANNOT_RUN(padapter)) + return rtStatus; + /*==== RF Off Sequence ==== */ + _DisableRFAFEAndResetBB(padapter); + + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure1(padapter, _FALSE); + + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _DisableGPIO(padapter); + + /* ==== Disable analog sequence === */ + _DisableAnalog(padapter, _FALSE); + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n")); + + return rtStatus; +} + +/* without HW Auto state machine */ +s32 CardDisableWithoutHWSM(PADAPTER padapter) +{ + s32 rtStatus = _SUCCESS; + + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n")); */ + if (RTW_CANNOT_RUN(padapter)) + return rtStatus; + + /*==== RF Off Sequence ==== */ + _DisableRFAFEAndResetBB(padapter); + + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure1(padapter, _TRUE); + + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _DisableGPIO(padapter); + + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure2(padapter); + + /* ==== Disable analog sequence === */ + _DisableAnalog(padapter, _TRUE); + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n")); */ + return rtStatus; +} +#endif /* CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */ + +BOOLEAN +Hal_GetChnlGroup8188F( + IN u8 Channel, + OUT u8 *pGroup +) +{ + BOOLEAN bIn24G = TRUE; + + if (Channel <= 14) { + bIn24G = TRUE; + + if (1 <= Channel && Channel <= 2) + *pGroup = 0; + else if (3 <= Channel && Channel <= 5) + *pGroup = 1; + else if (6 <= Channel && Channel <= 8) + *pGroup = 2; + else if (9 <= Channel && Channel <= 11) + *pGroup = 3; + else if (12 <= Channel && Channel <= 14) + *pGroup = 4; + else + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("==>Hal_GetChnlGroup8188F in 2.4 G, but Channel %d in Group not found\n", Channel)); + } else { + bIn24G = FALSE; + + if (36 <= Channel && Channel <= 42) + *pGroup = 0; + else if (44 <= Channel && Channel <= 48) *pGroup = 1; + else if (50 <= Channel && Channel <= 58) *pGroup = 2; + else if (60 <= Channel && Channel <= 64) *pGroup = 3; + else if (100 <= Channel && Channel <= 106) *pGroup = 4; + else if (108 <= Channel && Channel <= 114) *pGroup = 5; + else if (116 <= Channel && Channel <= 122) *pGroup = 6; + else if (124 <= Channel && Channel <= 130) *pGroup = 7; + else if (132 <= Channel && Channel <= 138) *pGroup = 8; + else if (140 <= Channel && Channel <= 144) *pGroup = 9; + else if (149 <= Channel && Channel <= 155) *pGroup = 10; + else if (157 <= Channel && Channel <= 161) *pGroup = 11; + else if (165 <= Channel && Channel <= 171) *pGroup = 12; + else if (173 <= Channel && Channel <= 177) *pGroup = 13; + else + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("==>Hal_GetChnlGroup8188F in 5G, but Channel %d in Group not found\n", Channel)); + + } + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==Hal_GetChnlGroup8188F, (%s) Channel = %d, Group =%d,\n", + (bIn24G) ? "2.4G" : "5G", Channel, *pGroup)); + return bIn24G; +} + +void +Hal_InitPGData( + PADAPTER padapter, + u8 *PROMContent) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u32 i; + u16 value16; + + if (_FALSE == pHalData->bautoload_fail_flag) { + /* autoload OK. */ + /*if (IS_BOOT_FROM_EEPROM(padapter)) */ + if (_TRUE == pHalData->EepromOrEfuse) { + /* Read all Content from EEPROM or EFUSE. */ + for (i = 0; i < HWSET_MAX_SIZE_8188F; i += 2) { + /*value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1))); */ + /**((u16*)(&PROMContent[i])) = value16; */ + } + } else { + /* Read EFUSE real map to shadow. */ + EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE); + _rtw_memcpy((void *)PROMContent, (void *)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8188F); + } + } else { + /*autoload fail */ + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n")); + /*pHalData->AutoloadFailFlag = _TRUE; */ + /*update to default value 0xFF */ + if (_FALSE == pHalData->EepromOrEfuse) + EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE); + _rtw_memcpy((void *)PROMContent, (void *)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8188F); + } + +#ifdef CONFIG_EFUSE_CONFIG_FILE + if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) { + if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS) + DBG_871X_LEVEL(_drv_err_, "invalid phy efuse and read from file fail, will use driver default!!\n"); + } +#endif +} + +void +Hal_EfuseParseIDCode( + IN PADAPTER padapter, + IN u8 *hwinfo +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u16 EEPROMId; + + + /* Checl 0x8129 again for making sure autoload status!! */ + EEPROMId = le16_to_cpu(*((u16 *)hwinfo)); + if (EEPROMId != RTL_EEPROM_ID) { + DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId); + pHalData->bautoload_fail_flag = _TRUE; + } else + pHalData->bautoload_fail_flag = _FALSE; + + RT_TRACE(_module_hal_init_c_, _drv_notice_, ("EEPROM ID=0x%04x\n", EEPROMId)); +} + +static void +Hal_EEValueCheck( + IN u8 EEType, + IN PVOID pInValue, + OUT PVOID pOutValue +) +{ + switch (EEType) { + case EETYPE_TX_PWR: { + u8 *pIn, *pOut; + + pIn = (u8 *)pInValue; + pOut = (u8 *)pOutValue; + + if (*pIn <= 63) + *pOut = *pIn; + else { + RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n", + *pIn, EEPROM_Default_TxPowerLevel)); + *pOut = EEPROM_Default_TxPowerLevel; + } + } + break; + default: + break; + } +} + +static u8 +Hal_GetChnlGroup( + IN u8 chnl +) +{ + u8 group = 0; + + if (chnl < 3) /* Cjanel 1-3 */ + group = 0; + else if (chnl < 9) /* Channel 4-9 */ + group = 1; + else /* Channel 10-14 */ + group = 2; + + return group; +} + +void +Hal_ReadPowerValueFromPROM_8188F( + IN PADAPTER Adapter, + IN PTxPowerInfo24G pwrInfo24G, + IN u8 *PROMContent, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u4Byte rfPath, eeAddr = EEPROM_TX_PWR_INX_8188F, group, TxCount = 0; + + _rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G)); + + if (0xFF == PROMContent[eeAddr + 1]) + AutoLoadFail = TRUE; + + if (AutoLoadFail) { + DBG_871X("%s(): Use Default value!\n", __func__); + for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) { + /*2.4G default value */ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; + pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; + } + for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { + if (TxCount == 0) { + pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF; + pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF; + } else { + pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; + pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; + pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; + pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF; + } + } + } + + return; + } + + pHalData->bTXPowerDataReadFromEEPORM = TRUE; /*YJ,move,120316 */ + + for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) { + /*2 2.4G default value */ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++]; + if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF) + pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; + } + for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { + pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++]; + if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF) + pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX; + } + for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { + if (TxCount == 0) { + pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0; + pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; + if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; + + pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); + if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; + + pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0; + eeAddr++; + } else { + pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; + if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0; + + pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); + if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0; + + eeAddr++; + + pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4; + if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0; + + + pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f); + if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3) /*4bit sign number to 8 bit sign number*/ + pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0; + + eeAddr++; + } + } + + /* Ignore the unnecessary 5G parameters parsing, but still consider the efuse address offset */ +#define TX_PWR_DIFF_OFFSET_5G 10 + eeAddr += (MAX_CHNL_GROUP_5G + TX_PWR_DIFF_OFFSET_5G); + } +} + + +void +Hal_EfuseParseTxPowerInfo_8188F( + IN PADAPTER padapter, + IN u8 *PROMContent, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + TxPowerInfo24G pwrInfo24G; + u8 rfPath, ch, group, TxCount = 1; + + /*RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail)); */ + Hal_ReadPowerValueFromPROM_8188F(padapter, &pwrInfo24G, PROMContent, AutoLoadFail); + for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) { + for (ch = 0; ch < CENTER_CH_2G_NUM; ch++) { + Hal_GetChnlGroup8188F(ch + 1, &group); + + if (ch == 14 - 1) { + pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5]; + pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group]; + } else { + pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group]; + pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group]; + } +#ifdef CONFIG_DEBUG + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======= Path %d, ChannelIndex %d, Group %d=======\n", rfPath, ch, group)); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_CCK_Base[%d][%d] = 0x%x\n", rfPath, ch , pHalData->Index24G_CCK_Base[rfPath][ch])); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_BW40_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_BW40_Base[rfPath][ch])); +#endif + } + + for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { + pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount]; + pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount]; + pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount]; + pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount]; + +#ifdef CONFIG_DEBUG + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("--------------------------------------- 2.4G ---------------------------------------\n")); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CCK_24G_Diff[%d][%d]= %d\n", rfPath, TxCount, pHalData->CCK_24G_Diff[rfPath][TxCount])); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("OFDM_24G_Diff[%d][%d]= %d\n", rfPath, TxCount, pHalData->OFDM_24G_Diff[rfPath][TxCount])); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW20_24G_Diff[%d][%d]= %d\n", rfPath, TxCount, pHalData->BW20_24G_Diff[rfPath][TxCount])); + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW40_24G_Diff[%d][%d]= %d\n", rfPath, TxCount, pHalData->BW40_24G_Diff[rfPath][TxCount])); +#endif + } + } + + /* 2010/10/19 MH Add Regulator recognize for CU. */ + if (!AutoLoadFail) { + pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8188F] & 0x7); /*bit0~2 */ + if (PROMContent[EEPROM_RF_BOARD_OPTION_8188F] == 0xFF) + pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /*bit0~2 */ + } else + pHalData->EEPROMRegulatory = 0; + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory)); +} + +VOID +Hal_EfuseParseEEPROMVer_8188F( + IN PADAPTER padapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + /*RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail)); */ + if (!AutoLoadFail) + pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8188F]; + else + pHalData->EEPROMVersion = 1; + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n", + pHalData->EEPROMVersion)); +} + +#ifndef DBG_PPG_MAC_HIDDEN_HANDLE + #define DBG_PPG_MAC_HIDDEN_HANDLE 0 +#endif + +#define PPG_MAC_HIDDEN_START_8188F 0xF8 +#define PPG_MAC_HIDDEN_END_8188F 0xFD + +#define IS_PPG_RANGE_UUID_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xF4) && (PPG_MAC_HIDDEN_END_8188F >= 0xF7)) +#define GET_PMH_UUID_X_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF4 - PPG_MAC_HIDDEN_START_8188F, 0, 8) +#define GET_PMH_UUID_Y_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF5 - PPG_MAC_HIDDEN_START_8188F, 0, 8) +#define GET_PMH_UUID_Z_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF6 - PPG_MAC_HIDDEN_START_8188F, 0, 5) +#define GET_PMH_UUID_CRC_8188F(_pmh_m) LE_BITS_TO_2BYTE(((u8 *)(_pmh_m)) + 0xF6 - PPG_MAC_HIDDEN_START_8188F, 5, 11) + +#define IS_PPG_RANGE_HCI_TYPE_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xF8) && (PPG_MAC_HIDDEN_END_8188F >= 0xF8)) +#define IS_PPG_RANGE_PACKAGE_TYPE_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xF8) && (PPG_MAC_HIDDEN_END_8188F >= 0xF8)) +#define GET_PMH_HCI_TYPE_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF8 - PPG_MAC_HIDDEN_START_8188F, 0, 4) +#define GET_PMH_PACKAGE_TYPE_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF8 - PPG_MAC_HIDDEN_START_8188F, 4, 4) + +#define IS_PPG_RANGE_WL_FUNC_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xF9) && (PPG_MAC_HIDDEN_END_8188F >= 0xF9)) +#define IS_PPG_RANGE_HW_SPECIAL_TYPE_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xF9) && (PPG_MAC_HIDDEN_END_8188F >= 0xF9)) +#define GET_PMH_WL_FUNC_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF9 - PPG_MAC_HIDDEN_START_8188F, 0, 4) +#define GET_PMH_HW_SPECIAL_TYPE_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xF9 - PPG_MAC_HIDDEN_START_8188F, 4, 4) + +#define IS_PPG_RANGE_BW_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xFB) && (PPG_MAC_HIDDEN_END_8188F >= 0xFB)) +#define IS_PPG_RANGE_ANT_NUM_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xFB) && (PPG_MAC_HIDDEN_END_8188F >= 0xFB)) +#define GET_PMH_BW_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xFB - PPG_MAC_HIDDEN_START_8188F, 0, 3) +#define GET_PMH_ANT_NUM_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xFB - PPG_MAC_HIDDEN_START_8188F, 5, 3) + +#define IS_PPG_RANGE_80211_PROTOCOL_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xFD) && (PPG_MAC_HIDDEN_END_8188F >= 0xFD)) +#define IS_PPG_RANGE_NIC_8188F ((PPG_MAC_HIDDEN_START_8188F <= 0xFD) && (PPG_MAC_HIDDEN_END_8188F >= 0xFD)) +#define GET_PMH_80211_PROTOCOL_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xFD - PPG_MAC_HIDDEN_START_8188F, 2, 2) +#define GET_PMH_NIC_8188F(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + 0xFD - PPG_MAC_HIDDEN_START_8188F, 6, 2) + +VOID +Hal_EfuseParseMacHidden_8188F( + IN PADAPTER adapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter); + + u8 pmh_map[PPG_MAC_HIDDEN_END_8188F - PPG_MAC_HIDDEN_START_8188F + 1]; + u16 start = PPG_MAC_HIDDEN_START_8188F; + u16 end = PPG_MAC_HIDDEN_END_8188F; + int i; + + u8 uuid_x = 0; + u8 uuid_y = 0; + u8 uuid_z = 0; + u16 uuid_crc = 0; + u8 hci_type = 0x0F; /* no used */ + u8 package_type = 0x0F; /* QFN24 */ + u8 wl_func = 0xF; /* all support */ + u8 hw_stype = 0x0F; /* no used */ + u8 bw = 0x6; /* 40MHz */ + u8 ant_num = 0x01 /* 1 ANT */; + u8 protocol = 0x02; /* 11n only */ + u8 nic = 0x03; /* NIC */ + + Efuse_PowerSwitch(adapter, _FALSE, _TRUE); + for (i = 0; i <= end - start; i++) + efuse_OneByteRead(adapter, start + i, pmh_map + i, FALSE); + Efuse_PowerSwitch(adapter, _FALSE, _FALSE); + +#if IS_PPG_RANGE_UUID_8188F + uuid_x = GET_PMH_UUID_X_8188F(pmh_map); + uuid_y = GET_PMH_UUID_Y_8188F(pmh_map); + uuid_z = GET_PMH_UUID_Z_8188F(pmh_map); + uuid_crc = GET_PMH_UUID_CRC_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_HCI_TYPE_8188F + hci_type = GET_PMH_HCI_TYPE_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_PACKAGE_TYPE_8188F + package_type = GET_PMH_PACKAGE_TYPE_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_WL_FUNC_8188F + wl_func = GET_PMH_WL_FUNC_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_HW_SPECIAL_TYPE_8188F + hw_stype = GET_PMH_HW_SPECIAL_TYPE_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_BW_8188F + bw = GET_PMH_BW_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_ANT_NUM_8188F + ant_num = GET_PMH_ANT_NUM_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_80211_PROTOCOL_8188F + protocol = GET_PMH_80211_PROTOCOL_8188F(pmh_map); +#endif +#if IS_PPG_RANGE_NIC_8188F + nic = GET_PMH_NIC_8188F(pmh_map); +#endif + + if (DBG_PPG_MAC_HIDDEN_HANDLE) { + if (IS_PPG_RANGE_UUID_8188F) + DBG_871X("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc); + DBG_871X("hci_type:0x%x\n", hci_type); + DBG_871X("package_type:0x%x\n", package_type); + DBG_871X("wl_func:0x%x\n", wl_func); + DBG_871X("hw_stype:0x%x\n", hw_stype); + DBG_871X("bw:0x%x\n", bw); + DBG_871X("ant_num:0x%x\n", ant_num); + DBG_871X("protocol:0x%x\n", protocol); + DBG_871X("nic:0x%x\n", nic); + } + + hal_data->PackageType = package_type; + hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func); + hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw); + hal_spec->nss_num = rtw_min(hal_spec->nss_num, ant_num); +} + +#if 0 /* Do not need for rtl8188f */ +VOID +Hal_EfuseParseVoltage_8188F( + IN PADAPTER pAdapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + /*_rtw_memcpy(pEEPROM->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8188F], 1); */ + DBG_871X("%s hwinfo[EEPROM_Voltage_ADDR_8188F] =%02x\n", __func__, hwinfo[EEPROM_Voltage_ADDR_8188F]); + pHalData->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8188F] & 0xf0) >> 4; + DBG_871X("%s pHalData->adjuseVoltageVal =%x\n", __func__, pHalData->adjuseVoltageVal); +} +#endif + +VOID +Hal_EfuseParseChnlPlan_8188F( + IN PADAPTER padapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan( + padapter + , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_8188F] : NULL + , hwinfo ? hwinfo[EEPROM_ChannelPlan_8188F] : 0xFF + , padapter->registrypriv.alpha2 + , padapter->registrypriv.channel_plan + , RTW_CHPLAN_WORLD_NULL + , AutoLoadFail + ); +} + +VOID +Hal_EfuseParseCustomerID_8188F( + IN PADAPTER padapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + /*RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail)); */ + if (!AutoLoadFail) + pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8188F]; + else + pHalData->EEPROMCustomerID = 0; + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID)); +} + +VOID +Hal_EfuseParsePowerSavingMode_8188F( + IN PADAPTER padapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + u8 tmpvalue; + + if (AutoLoadFail) { + pwrctl->bHWPowerdown = _FALSE; + pwrctl->bSupportRemoteWakeup = _FALSE; + } else { + + /* hw power down mode selection , 0:rf-off ; 1:power down */ + + if (padapter->registrypriv.hwpdn_mode == 2) + pwrctl->bHWPowerdown = (hwinfo[EEPROM_FEATURE_OPTION_8188F] & BIT4); + else + pwrctl->bHWPowerdown = padapter->registrypriv.hwpdn_mode; + + /* decide hw if support remote wakeup function */ + /* if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume */ +#ifdef CONFIG_USB_HCI + pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0_8188FU] & BIT1) ? _TRUE : _FALSE; +#endif /* CONFIG_USB_HCI */ + + DBG_871X("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) ,bSupportRemoteWakeup(%x)\n" + , __FUNCTION__, pwrctl->bHWPwrPindetect, pwrctl->bHWPowerdown, pwrctl->bSupportRemoteWakeup); + + DBG_871X("### PS params=> power_mgnt(%x),usbss_enable(%x) ###\n" + , padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable); + + } +} + +VOID +Hal_EfuseParseAntennaDiversity_8188F( + IN PADAPTER pAdapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ +#ifdef CONFIG_ANTENNA_DIVERSITY + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + struct registry_priv *registry_par = &pAdapter->registrypriv; + + if (pHalData->EEPROMBluetoothAntNum == Ant_x1) + pHalData->AntDivCfg = 0; + else { + if (registry_par->antdiv_cfg == 2) /* 0:OFF , 1:ON, 2:By EFUSE */ + pHalData->AntDivCfg = 1; + else + pHalData->AntDivCfg = registry_par->antdiv_cfg; + } + + /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */ + if (registry_par->antdiv_type == 0) { + pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8188F]; + 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) + pHalData->TRxAntDivType = S0S1_SW_ANTDIV; /*intrnal switch S0S1 */ + else + DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n", + __func__, EEPROM_RFE_OPTION_8188F, pHalData->TRxAntDivType); + } else { + pHalData->TRxAntDivType = registry_par->antdiv_type;/*GetRegAntDivType(pAdapter); */ + } + + DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n", + __func__, pHalData->AntDivCfg, pHalData->TRxAntDivType); +#endif +} + +VOID +Hal_EfuseParseXtal_8188F( + IN PADAPTER pAdapter, + IN u8 *hwinfo, + IN BOOLEAN AutoLoadFail +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + + /*RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail)); */ + if (!AutoLoadFail) { + pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8188F]; + if (pHalData->CrystalCap == 0xFF) + pHalData->CrystalCap = EEPROM_Default_CrystalCap_8188F; /*what value should 8812 set? */ + } else + pHalData->CrystalCap = EEPROM_Default_CrystalCap_8188F; + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM CrystalCap: 0x%2x\n", pHalData->CrystalCap)); +} + + +void +Hal_EfuseParseThermalMeter_8188F( + PADAPTER padapter, + u8 *PROMContent, + u8 AutoLoadFail +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + /*RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail)); */ + /* */ + /* ThermalMeter from EEPROM */ + /* */ + if (_FALSE == AutoLoadFail) + pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8188F]; + else + pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8188F; + + if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoLoadFail)) { + pHalData->odmpriv.RFCalibrateInfo.bAPKThermalMeterIgnore = _TRUE; + pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8188F; + } + + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ThermalMeter=0x%x\n", pHalData->EEPROMThermalMeter)); +} + + +void Hal_EfuseParseKFreeData_8188F( + IN PADAPTER Adapter, + IN u8 *PROMContent, + IN BOOLEAN AutoloadFail) +{ +#ifdef CONFIG_RF_GAIN_OFFSET + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct kfree_data_t *kfree_data = &pHalData->kfree_data; + + if ((Adapter->registrypriv.RegRfKFreeEnable == 1) || !AutoloadFail) { + kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A] + = KFREE_BB_GAIN_2G_TX_OFFSET(EFUSE_Read1Byte(Adapter, PPG_BB_GAIN_2G_TXA_OFFSET_8188F) & PPG_BB_GAIN_2G_TX_OFFSET_MASK); + kfree_data->thermal + = KFREE_THERMAL_OFFSET(EFUSE_Read1Byte(Adapter, PPG_THERMAL_OFFSET_8188F) & PPG_THERMAL_OFFSET_MASK); + + if (GET_PG_KFREE_ON_8188F(PROMContent) && PROMContent[0xc1] != 0xff) + kfree_data->flag |= KFREE_FLAG_ON; + if (GET_PG_KFREE_THERMAL_K_ON_8188F(PROMContent) && PROMContent[0xc8] != 0xff) + kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON; + + } + + if (Adapter->registrypriv.RegRfKFreeEnable == 1) { + kfree_data->flag |= KFREE_FLAG_ON; + kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON; + } + + if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON) + pHalData->EEPROMThermalMeter += kfree_data->thermal; + + DBG_871X("kfree flag:%u\n", kfree_data->flag); + if (Adapter->registrypriv.RegRfKFreeEnable == 1 || kfree_data->flag & KFREE_FLAG_ON) + DBG_871X("bb_gain:%d\n", kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A]); + if (Adapter->registrypriv.RegRfKFreeEnable == 1 || kfree_data->flag & KFREE_FLAG_THERMAL_K_ON) + DBG_871X("thermal:%d\n", kfree_data->thermal); + +#endif /*CONFIG_RF_GAIN_OFFSET */ +} + +u8 +BWMapping_8188F( + IN PADAPTER Adapter, + IN struct pkt_attrib *pattrib +) +{ + u8 BWSettingOfDesc = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + /*DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d\n",pHalData->CurrentChannelBW,pattrib->bwmode); */ + + if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_80) { + if (pattrib->bwmode == CHANNEL_WIDTH_80) + BWSettingOfDesc = 2; + else if (pattrib->bwmode == CHANNEL_WIDTH_40) + BWSettingOfDesc = 1; + else + BWSettingOfDesc = 0; + } else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) { + if ((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80)) + BWSettingOfDesc = 1; + else + BWSettingOfDesc = 0; + } else + BWSettingOfDesc = 0; + + /*if(pTcb->bBTTxPacket) */ + /* BWSettingOfDesc = 0; */ + + return BWSettingOfDesc; +} + +u8 SCMapping_8188F(PADAPTER Adapter, struct pkt_attrib *pattrib) +{ + u8 SCSettingOfDesc = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + /*DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC); */ + + if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_80) { + if (pattrib->bwmode == CHANNEL_WIDTH_80) + SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE; + else if (pattrib->bwmode == CHANNEL_WIDTH_40) { + if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) + SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) + SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + DBG_871X("SCMapping: DONOT CARE Mode Setting\n"); + } else { + if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)) + SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)) + SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)) + SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)) + SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + DBG_871X("SCMapping: DONOT CARE Mode Setting\n"); + } + } else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) { + /*DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC); */ + + if (pattrib->bwmode == CHANNEL_WIDTH_40) + SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE; + else if (pattrib->bwmode == CHANNEL_WIDTH_20) { + if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) + SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) + SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else + SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE; + } + } else + SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE; + + return SCSettingOfDesc; +} + + +static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib) +{ + u8 sectype = 0; + if ((pattrib->encrypt > 0) && !pattrib->bswenc) { + switch (pattrib->encrypt) { + /* SEC_TYPE */ + case _WEP40_: + case _WEP104_: + case _TKIP_: + case _TKIP_WTMIC_: + sectype = 1; + break; + +#ifdef CONFIG_WAPI_SUPPORT + case _SMS4_: + sectype = 2; + break; +#endif + case _AES_: + sectype = 3; + break; + + case _NO_PRIVACY_: + default: + break; + } + } + return sectype; +} + +static void fill_txdesc_vcs_8188f(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc) +{ + /*DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode); */ + + SET_TX_DESC_HW_RTS_ENABLE_8188F(ptxdesc, 0); + + switch (pattrib->vcs_mode) { + case RTS_CTS: + SET_TX_DESC_RTS_ENABLE_8188F(ptxdesc, 1); + break; + case CTS_TO_SELF: + SET_TX_DESC_CTS2SELF_8188F(ptxdesc, 1); + break; + case NONE_VCS: + default: + break; + } + +#if 1 /* TODO: */ + /* Protection mode related */ + if (pattrib->vcs_mode) { + /* SET_TX_DESC_CCA_RTS_8188F(ptxdesc, pTcb->RTSCCA); */ + SET_TX_DESC_RTS_RATE_8188F(ptxdesc, 8); /*TODO: Hardcode?, RTS Rate=24M (8) */ + SET_TX_DESC_RTS_RATE_FB_LIMIT_8188F(ptxdesc, 0xF); /* TODO: PROTECTION_MODE ?? */ + + if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT) + SET_TX_DESC_RTS_SHORT_8188F(ptxdesc, 1); + + /* Set RTS BW */ + if (pattrib->ht_en) + SET_TX_DESC_RTS_SC_8188F(ptxdesc, SCMapping_8188F(padapter, pattrib)); + } +#endif +} + +static void fill_txdesc_phy_8188f(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc) +{ + /*DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */ + + if (pattrib->ht_en) { + SET_TX_DESC_DATA_BW_8188F(ptxdesc, BWMapping_8188F(padapter, pattrib)); + SET_TX_DESC_DATA_SC_8188F(ptxdesc, SCMapping_8188F(padapter, pattrib)); + } +} + +static void rtl8188f_fill_default_txdesc( + struct xmit_frame *pxmitframe, + u8 *pbuf) +{ + PADAPTER padapter; + HAL_DATA_TYPE *pHalData; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + struct pkt_attrib *pattrib; + s32 bmcst; + + _rtw_memset(pbuf, 0, TXDESC_SIZE); + + padapter = pxmitframe->padapter; + pHalData = GET_HAL_DATA(padapter); + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &(pmlmeext->mlmext_info); + + pattrib = &pxmitframe->attrib; + bmcst = IS_MCAST(pattrib->ra); + + if (pxmitframe->frame_tag == DATA_FRAMETAG) { + u8 drv_userate = 0; + + SET_TX_DESC_MACID_8188F(pbuf, pattrib->mac_id); + SET_TX_DESC_RATE_ID_8188F(pbuf, pattrib->raid); + SET_TX_DESC_QUEUE_SEL_8188F(pbuf, pattrib->qsel); + SET_TX_DESC_SEQ_8188F(pbuf, pattrib->seqnum); + + SET_TX_DESC_SEC_TYPE_8188F(pbuf, fill_txdesc_sectype(pattrib)); + fill_txdesc_vcs_8188f(padapter, pattrib, pbuf); + + if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1) + drv_userate = 1; + + if ((pattrib->ether_type != 0x888e) && + (pattrib->ether_type != 0x0806) && + (pattrib->ether_type != 0x88B4) && + (pattrib->dhcp_pkt != 1) && + (drv_userate != 1) +#ifdef CONFIG_AUTO_AP_MODE + && (pattrib->pctrl != _TRUE) +#endif + ) { + /* Non EAP & ARP & DHCP type data packet */ + + if (pattrib->ampdu_en == _TRUE) { + SET_TX_DESC_AGG_ENABLE_8188F(pbuf, 1); + SET_TX_DESC_MAX_AGG_NUM_8188F(pbuf, 0x1F); + SET_TX_DESC_AMPDU_DENSITY_8188F(pbuf, pattrib->ampdu_spacing); + } else + SET_TX_DESC_AGG_BREAK_8188F(pbuf, 1); + + fill_txdesc_phy_8188f(padapter, pattrib, pbuf); + + SET_TX_DESC_DATA_RATE_FB_LIMIT_8188F(pbuf, 0x1F); + + if (pHalData->fw_ractrl == _FALSE) { + SET_TX_DESC_USE_RATE_8188F(pbuf, 1); + + if (pHalData->INIDATA_RATE[pattrib->mac_id] & BIT(7)) + SET_TX_DESC_DATA_SHORT_8188F(pbuf, 1); + + SET_TX_DESC_TX_RATE_8188F(pbuf, pHalData->INIDATA_RATE[pattrib->mac_id] & 0x7F); + } + + /* modify data rate by iwpriv */ + if (padapter->fix_rate != 0xFF) { + SET_TX_DESC_USE_RATE_8188F(pbuf, 1); + if (padapter->fix_rate & BIT(7)) + SET_TX_DESC_DATA_SHORT_8188F(pbuf, 1); + SET_TX_DESC_TX_RATE_8188F(pbuf, padapter->fix_rate & 0x7F); + if (!padapter->data_fb) + SET_TX_DESC_DISABLE_FB_8188F(pbuf, 1); + } + + if (pattrib->ldpc) + SET_TX_DESC_DATA_LDPC_8188F(pbuf, 1); + + if (pattrib->stbc) + SET_TX_DESC_DATA_STBC_8188F(pbuf, 1); + +#ifdef CONFIG_CMCC_TEST + SET_TX_DESC_DATA_SHORT_8188F(pbuf, 1); /* use cck short premble */ +#endif + } else { + /* EAP data packet and ARP packet. */ + /* Use the 1M data rate to send the EAP/ARP packet. */ + /* This will maybe make the handshake smooth. */ + + SET_TX_DESC_AGG_BREAK_8188F(pbuf, 1); + SET_TX_DESC_USE_RATE_8188F(pbuf, 1); + if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) + SET_TX_DESC_DATA_SHORT_8188F(pbuf, 1); + SET_TX_DESC_TX_RATE_8188F(pbuf, MRateToHwRate(pmlmeext->tx_rate)); + + DBG_8192C(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n", + FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate)); + } + +#if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + SET_TX_DESC_USB_TXAGG_NUM_8188F(pbuf, pxmitframe->agg_num); +#endif + +#ifdef CONFIG_TDLS +#ifdef CONFIG_XMIT_ACK + /* CCX-TXRPT ack for xmit mgmt frames. */ + if (pxmitframe->ack_report) { +#ifdef DBG_CCX + DBG_8192C("%s set spe_rpt\n", __func__); +#endif + SET_TX_DESC_SPE_RPT_8188F(pbuf, 1); + SET_TX_DESC_SW_DEFINE_8188F(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no)); + } +#endif /* CONFIG_XMIT_ACK */ +#endif + } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { + /* RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __func__)); */ + + SET_TX_DESC_MACID_8188F(pbuf, pattrib->mac_id); + SET_TX_DESC_QUEUE_SEL_8188F(pbuf, pattrib->qsel); + SET_TX_DESC_RATE_ID_8188F(pbuf, pattrib->raid); + SET_TX_DESC_SEQ_8188F(pbuf, pattrib->seqnum); + SET_TX_DESC_USE_RATE_8188F(pbuf, 1); + + SET_TX_DESC_MBSSID_8188F(pbuf, pattrib->mbssid & 0xF); + + SET_TX_DESC_RETRY_LIMIT_ENABLE_8188F(pbuf, 1); + if (pattrib->retry_ctrl == _TRUE) { + /* Nothing */ + SET_TX_DESC_DATA_RETRY_LIMIT_8188F(pbuf, 6); + } else { + /* Nothing */ + SET_TX_DESC_DATA_RETRY_LIMIT_8188F(pbuf, 12); + } + +#ifdef CONFIG_INTEL_PROXIM + if ((padapter->proximity.proxim_on == _TRUE) && (pattrib->intel_proxim == _TRUE)) { + DBG_871X("\n %s pattrib->rate=%d\n", __func__, pattrib->rate); + SET_TX_DESC_TX_RATE_8188F(pbuf, pattrib->rate); + } else +#endif + { + SET_TX_DESC_TX_RATE_8188F(pbuf, MRateToHwRate(pmlmeext->tx_rate)); + } + +#ifdef CONFIG_XMIT_ACK + /* CCX-TXRPT ack for xmit mgmt frames. */ + if (pxmitframe->ack_report) { +#ifdef DBG_CCX + DBG_8192C("%s set spe_rpt\n", __func__); +#endif + SET_TX_DESC_SPE_RPT_8188F(pbuf, 1); + SET_TX_DESC_SW_DEFINE_8188F(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no)); + } +#endif /* CONFIG_XMIT_ACK */ + } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) + RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __func__)); +#ifdef CONFIG_MP_INCLUDED + else if (pxmitframe->frame_tag == MP_FRAMETAG) { + RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __func__)); + fill_txdesc_for_mp(padapter, pbuf); + } +#endif + else { + RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __func__, pxmitframe->frame_tag)); + + SET_TX_DESC_MACID_8188F(pbuf, pattrib->mac_id); + SET_TX_DESC_RATE_ID_8188F(pbuf, pattrib->raid); + SET_TX_DESC_QUEUE_SEL_8188F(pbuf, pattrib->qsel); + SET_TX_DESC_SEQ_8188F(pbuf, pattrib->seqnum); + SET_TX_DESC_USE_RATE_8188F(pbuf, 1); + SET_TX_DESC_TX_RATE_8188F(pbuf, MRateToHwRate(pmlmeext->tx_rate)); + } + + SET_TX_DESC_PKT_SIZE_8188F(pbuf, pattrib->last_txcmdsz); + + { + u8 pkt_offset, offset; + + pkt_offset = 0; + offset = TXDESC_SIZE; +#ifdef CONFIG_USB_HCI + pkt_offset = pxmitframe->pkt_offset; + offset += (pxmitframe->pkt_offset >> 3); +#endif /* CONFIG_USB_HCI */ + +#ifdef CONFIG_TX_EARLY_MODE + if (pxmitframe->frame_tag == DATA_FRAMETAG) { + pkt_offset = 1; + offset += EARLY_MODE_INFO_SIZE; + } +#endif /* CONFIG_TX_EARLY_MODE */ + + SET_TX_DESC_PKT_OFFSET_8188F(pbuf, pkt_offset); + SET_TX_DESC_OFFSET_8188F(pbuf, offset); + } + + if (bmcst) + SET_TX_DESC_BMC_8188F(pbuf, 1); + + /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ + /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */ + /* mgnt frame should be controlled by Hw because Fw will also send null data */ + /* which we cannot control when Fw LPS enable. */ + /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */ + /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */ + /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */ + /* 2010.06.23. Added by tynli. */ + if (!pattrib->qos_en) + SET_TX_DESC_HWSEQ_EN_8188F(pbuf, 1); +} + +/* + * Description: + * + * Parameters: + * pxmitframe xmitframe + * pbuf where to fill tx desc + */ +void rtl8188f_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf) +{ + PADAPTER padapter = pxmitframe->padapter; + rtl8188f_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) + rtl8188f_cal_txdesc_chksum((struct tx_desc *)pbuf); +#endif +} + +#ifdef CONFIG_TSF_RESET_OFFLOAD +int reset_tsf(PADAPTER Adapter, u8 reset_port) +{ + u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0; + u32 reg_reset_tsf_cnt = (IFACE_PORT0 == reset_port) ? + REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1; + + rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */ + reset_cnt_after = reset_cnt_before = rtw_read8(Adapter, reg_reset_tsf_cnt); + rtl8188f_reset_tsf(Adapter, reset_port); + + while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) { + rtw_msleep_os(100); + loop_cnt++; + reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt); + } + + return (loop_cnt >= 10) ? _FAIL : _TRUE; +} +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + +static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val) +{ + u32 value_rcr, rcr_bits; + u16 value_rxfltmap2; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv); + + if (*((u8 *)val) == _HW_STATE_MONITOR_) { + + /* Leave IPS */ + rtw_pm_set_ips(Adapter, IPS_NONE); + LeaveAllPowerSaveMode(Adapter); + + /* Receive all type */ + rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF; + + /* Append FCS */ + rcr_bits |= RCR_APPFCS; + +#if 0 + /* + CRC and ICV packet will drop in recvbuf2recvframe() + We no turn on it. + */ + rcr_bits |= (RCR_ACRC32 | RCR_AICV); +#endif + + /* Receive all data frames */ + value_rxfltmap2 = 0xFFFF; + + value_rcr = rcr_bits; + rtw_write32(Adapter, REG_RCR, value_rcr); + + rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2); + +#if 0 + /* tx pause */ + rtw_write8(padapter, REG_TXPAUSE, 0xFF); +#endif + } else { + /* do nothing */ + } + +} + +static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 val8; + u8 mode = *((u8 *)val); + static u8 isMonitor = _FALSE; + + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + if (isMonitor == _TRUE) { + /* reset RCR */ + rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig); + isMonitor = _FALSE; + } + + if (mode == _HW_STATE_MONITOR_) { + isMonitor = _TRUE; + /* set net_type */ + Set_MSR(padapter, _HW_STATE_NOLINK_); + + hw_var_set_monitor(padapter, variable, val); + return; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + /* disable Port1 TSF update */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + + Set_MSR(padapter, mode); + + DBG_871X("#### %s()-%d iface_type(%d) mode=%d ####\n", + __func__, __LINE__, padapter->iface_type, mode); + + if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { + if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { + StopTxBeacon(padapter); +#ifdef CONFIG_PCI_HCI + UpdateInterruptMask8188FE(padapter, 0, 0, RT_BCN_INT_MASKS, 0); +#else /* !CONFIG_PCI_HCI */ +#ifdef CONFIG_INTERRUPT_BASED_TXBCN + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + rtw_write8(padapter, REG_DRVERLYINT, 0x05);/*restore early int time to 5ms */ + UpdateInterruptMask8188FU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8188F); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */ + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + UpdateInterruptMask8188FU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8188F | IMR_TXBCN0OK_8188F)); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */ + +#endif /* CONFIG_INTERRUPT_BASED_TXBCN */ +#endif /* !CONFIG_PCI_HCI */ + } + + /* disable atim wnd and disable beacon function */ + rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_ATIM); + } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) { + ResumeTxBeacon(padapter); + rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB); + } else if (mode == _HW_STATE_AP_) { +#ifdef CONFIG_PCI_HCI + UpdateInterruptMask8188FE(padapter, RT_BCN_INT_MASKS, 0, 0, 0); +#else /* !CONFIG_PCI_HCI */ +#ifdef CONFIG_INTERRUPT_BASED_TXBCN + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + UpdateInterruptMask8188FU(padapter, _TRUE, IMR_BCNDMAINT0_8188F, 0); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */ + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + UpdateInterruptMask8188FU(padapter, _TRUE, (IMR_TXBCN0ERR_8188F | IMR_TXBCN0OK_8188F), 0); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */ + +#endif /* CONFIG_INTERRUPT_BASED_TXBCN */ +#endif /* !CONFIG_PCI_HCI */ + + ResumeTxBeacon(padapter); + + rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_BCNQ_SUB); + + /* Set RCR */ + /*rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0 */ + /*rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0 */ + rtw_write32(padapter, REG_RCR, 0x7000208e);/*CBSSID_DATA must set to 0,reject ICV_ERR packet */ + /* enable to rx data frame */ + rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); + /* enable to rx ps-poll */ + rtw_write16(padapter, REG_RXFLTMAP1, 0x0400); + + /* Beacon Control related register for first time */ + rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */ + + /*rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */ + rtw_write8(padapter, REG_ATIMWND_1, 0x0a); /* 10ms for port1 */ + rtw_write16(padapter, REG_BCNTCFG, 0x00); + rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04); + rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */ + + /* reset TSF2 */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)); + + /* enable BCN1 Function for if2 */ + /* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */ + rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB)); + + /*SW_BCN_SEL - Port1 */ + /*rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4); */ + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + + /* select BCN on port 1 */ + rtw_write8(padapter, REG_CCK_CHECK_8188F, + (rtw_read8(padapter, REG_CCK_CHECK_8188F) | BIT_BCN_PORT_SEL)); + + if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE)) { + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, val8); + } + + /*BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */ + /*rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5)); */ + /*rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3)); */ + + /*dis BCN0 ATIM WND if if1 is station */ + rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | DIS_ATIM); + +#ifdef CONFIG_TSF_RESET_OFFLOAD + /* Reset TSF for STA+AP concurrent mode */ + if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) { + if (reset_tsf(padapter, IFACE_PORT1) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n", + __func__, __LINE__); + } +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + } + } else /*else for port0 */ +#endif /* CONFIG_CONCURRENT_MODE */ + { + /* disable Port0 TSF update */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL, val8); + + /* set net_type */ + Set_MSR(padapter, mode); + DBG_871X("#### %s() -%d iface_type(0) mode = %d ####\n", __func__, __LINE__, mode); + + if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { +#ifdef CONFIG_CONCURRENT_MODE + if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { + /* suspect code indent for conditional statements */ +#else + { +#endif /* CONFIG_CONCURRENT_MODE */ + StopTxBeacon(padapter); +#ifdef CONFIG_PCI_HCI + UpdateInterruptMask8188FE(padapter, 0, 0, RT_BCN_INT_MASKS, 0); +#else /* !CONFIG_PCI_HCI */ +#ifdef CONFIG_INTERRUPT_BASED_TXBCN +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + rtw_write8(padapter, REG_DRVERLYINT, 0x05); /* restore early int time to 5ms */ + UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8188F); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */ + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + UpdateInterruptMask8812AU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8188F | IMR_TXBCN0OK_8188F)); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */ + +#endif /* CONFIG_INTERRUPT_BASED_TXBCN */ +#endif /* !CONFIG_PCI_HCI */ + } + + /* disable atim wnd */ + rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM); + /*rtw_write8(padapter,REG_BCN_CTRL, 0x18); */ + } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) { + ResumeTxBeacon(padapter); + rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB); + } else if (mode == _HW_STATE_AP_) { +#ifdef CONFIG_PCI_HCI + UpdateInterruptMask8188FE(padapter, RT_BCN_INT_MASKS, 0, 0, 0); +#else /* !CONFIG_PCI_HCI */ +#ifdef CONFIG_INTERRUPT_BASED_TXBCN +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + UpdateInterruptMask8188FU(padapter, _TRUE , IMR_BCNDMAINT0_8188F, 0); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */ + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + UpdateInterruptMask8188FU(padapter, _TRUE , (IMR_TXBCN0ERR_8188F | IMR_TXBCN0OK_8188F), 0); +#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */ + +#endif /* CONFIG_INTERRUPT_BASED_TXBCN */ +#endif + + ResumeTxBeacon(padapter); + + rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB); + + /*Set RCR */ + /*rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0 */ + /*rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0 */ + rtw_write32(padapter, REG_RCR, 0x7000208e);/*CBSSID_DATA must set to 0,reject ICV_ERR packet */ + /*enable to rx data frame */ + rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); + /*enable to rx ps-poll */ + rtw_write16(padapter, REG_RXFLTMAP1, 0x0400); + + /*Beacon Control related register for first time */ + rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */ + + /*rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */ + rtw_write8(padapter, REG_ATIMWND, 0x0a); /* 10ms */ + rtw_write16(padapter, REG_BCNTCFG, 0x00); + rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04); + rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */ + + /*reset TSF */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0)); + + /*enable BCN0 Function for if1 */ + /*don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */ + rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB)); + + /*SW_BCN_SEL - Port0 */ + /*rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4); */ + rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); + + /* select BCN on port 0 */ + rtw_write8(padapter, REG_CCK_CHECK_8188F, + (rtw_read8(padapter, REG_CCK_CHECK_8188F) & ~BIT_BCN_PORT_SEL)); + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE)) { + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + } +#endif /* CONFIG_CONCURRENT_MODE */ + + /* dis BCN1 ATIM WND if if2 is station */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 |= DIS_ATIM; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); +#ifdef CONFIG_TSF_RESET_OFFLOAD + /* Reset TSF for STA+AP concurrent mode */ + if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) { + if (reset_tsf(padapter, IFACE_PORT0) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n", + __func__, __LINE__); + } +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + } + } +} + +static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 idx = 0; + u32 reg_macid; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) + reg_macid = REG_MACID1; + else +#endif + { + reg_macid = REG_MACID; + } + + for (idx = 0; idx < 6; idx++) + rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid + idx), val[idx]); +} + +static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 idx = 0; + u32 reg_bssid; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) + reg_bssid = REG_BSSID1; + else +#endif + { + reg_bssid = REG_BSSID; + } + + for (idx = 0; idx < 6; idx++) + rtw_write8(padapter, (reg_bssid + idx), val[idx]); +} + +static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val) +{ + u32 bcn_ctrl_reg; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) + bcn_ctrl_reg = REG_BCN_CTRL_1; + else +#endif + { + bcn_ctrl_reg = REG_BCN_CTRL; + } + + if (*(u8 *)val) + rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT)); + else { + u8 val8; + val8 = rtw_read8(padapter, bcn_ctrl_reg); + val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT); +#ifdef CONFIG_BT_COEXIST + /* Always enable port0 beacon function for PSTDMA */ + if (REG_BCN_CTRL == bcn_ctrl_reg) + val8 |= EN_BCN_FUNCTION; +#endif + rtw_write8(padapter, bcn_ctrl_reg, val8); + } +} + +static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 val8; + u64 tsf; + struct mlme_ext_priv *pmlmeext; + struct mlme_ext_info *pmlmeinfo; + + + pmlmeext = &padapter->mlmeextpriv; + pmlmeinfo = &pmlmeext->mlmext_info; + + tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval * 1024)) - 1024; /*us */ + + if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || + ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) + StopTxBeacon(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + /* disable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + + rtw_write32(padapter, REG_TSFTR1, tsf); + rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32); + + + /* enable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 |= EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + + /* Update buddy port's TSF if it is SoftAP for beacon TX issue! */ + if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) + ) { + /* disable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, val8); + + rtw_write32(padapter, REG_TSFTR, tsf); + rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32); + + /* enable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, val8); +#ifdef CONFIG_TSF_RESET_OFFLOAD + /* Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue! */ + if (reset_tsf(padapter, IFACE_PORT0) == _FALSE) + DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n", + __func__, __LINE__); + +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + } + } else +#endif /* CONFIG_CONCURRENT_MODE */ + { + /* disable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, val8); + + rtw_write32(padapter, REG_TSFTR, tsf); + rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32); + + /* enable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL, val8); + +#ifdef CONFIG_CONCURRENT_MODE + /* Update buddy port's TSF if it is SoftAP for beacon TX issue! */ + if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE + && check_buddy_fwstate(padapter, WIFI_AP_STATE)) { + /* disable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + + rtw_write32(padapter, REG_TSFTR1, tsf); + rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32); + + /* enable related TSF function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 |= EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + +#ifdef CONFIG_TSF_RESET_OFFLOAD + /* Update buddy port's TSF if it is SoftAP for beacon TX issue! */ + if (reset_tsf(padapter, IFACE_PORT1) == _FALSE) { + DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n", + __func__, __LINE__); + } +#endif /* CONFIG_TSF_RESET_OFFLOAD */ + } +#endif /* CONFIG_CONCURRENT_MODE */ + } + + if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) + || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) + ResumeTxBeacon(padapter); +} + +static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 val8; + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_)) +#endif + { + /* Set RCR to not to receive data frame when NO LINK state */ + /*rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF); */ + /* reject all data frames */ + rtw_write16(padapter, REG_RXFLTMAP2, 0); + } + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + /* reset TSF1 */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)); + + /* disable update TSF1 */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + + /* disable Port1's beacon function */ + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 &= ~EN_BCN_FUNCTION; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + } else +#endif + { + /* reset TSF */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0)); + + /* disable update TSF */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 |= DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL, val8); + } +} + +static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8 *val) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + u32 value_rcr, rcr_clear_bit, reg_bcn_ctl; + u16 value_rxfltmap2; + u8 val8; + PHAL_DATA_TYPE pHalData; + struct mlme_priv *pmlmepriv; + u8 ap_num; + +#ifdef CONFIG_CONCURRENT_MODE + u32 buddy_reg_bcn_ctl; +#endif + + pHalData = GET_HAL_DATA(padapter); + pmlmepriv = &padapter->mlmepriv; + +#ifdef CONFIG_CONCURRENT_MODE + + if (padapter->iface_type == IFACE_PORT1) { + reg_bcn_ctl = REG_BCN_CTRL_1; + buddy_reg_bcn_ctl = REG_BCN_CTRL; + } else { + reg_bcn_ctl = REG_BCN_CTRL; + buddy_reg_bcn_ctl = REG_BCN_CTRL_1; + } +#else + reg_bcn_ctl = REG_BCN_CTRL; +#endif + + rtw_dev_iface_status(padapter, NULL, NULL, NULL, &ap_num, NULL); + +#ifdef CONFIG_FIND_BEST_CHANNEL + rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA); + + /* Receive all data frames */ + value_rxfltmap2 = 0xFFFF; +#else /* CONFIG_FIND_BEST_CHANNEL */ + + rcr_clear_bit = RCR_CBSSID_BCN; + + /* config RCR to receive different BSSID & not to receive data frame */ + value_rxfltmap2 = 0; + +#endif /* CONFIG_FIND_BEST_CHANNEL */ + + if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) +#ifdef CONFIG_CONCURRENT_MODE + || (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) +#endif + ) + rcr_clear_bit = RCR_CBSSID_BCN; +#ifdef CONFIG_TDLS + /* TDLS will clear RCR_CBSSID_DATA bit for connection. */ + else if (padapter->tdlsinfo.link_established == _TRUE) + rcr_clear_bit = RCR_CBSSID_BCN; +#endif /* CONFIG_TDLS */ + + value_rcr = rtw_read32(padapter, REG_RCR); + + if (*((u8 *)val)) { + /* under sitesurvey */ + /* + * 1. configure REG_RXFLTMAP2 + * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN + * 3. config RCR to receive different BSSID BCN or probe rsp + */ + + rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2); + + if (rtw_linked_check(padapter) && + check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) { + /* disable update TSF */ + rtw_write8(padapter, reg_bcn_ctl, rtw_read8(padapter, reg_bcn_ctl)|DIS_TSF_UDT); + padapter->mlmeextpriv.en_hw_update_tsf = _FALSE; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_linked_check(padapter->pbuddy_adapter) && + check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE) { + /* disable update buddy TSF to avoid updating wrong TSF due to clear RCR_CBSSID_BCN */ + rtw_write8(padapter->pbuddy_adapter, buddy_reg_bcn_ctl, + rtw_read8(padapter->pbuddy_adapter, buddy_reg_bcn_ctl)|DIS_TSF_UDT); + padapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _FALSE; + } +#endif + value_rcr &= ~(rcr_clear_bit); + rtw_write32(padapter, REG_RCR, value_rcr); + + /* Save orignal RRSR setting. */ + pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR); + + if (ap_num) + StopTxBeacon(padapter); + } else { + /* + * 1. enable rx data frame + * 2. config RCR not to receive different BSSID BCN or probe rsp + * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict + * so, we enable TSF update when rx first BCN after sitesurvey done + */ + + /* sitesurvey done */ + if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) +#ifdef CONFIG_CONCURRENT_MODE + || check_buddy_fwstate(padapter, (_FW_LINKED | WIFI_AP_STATE)) +#endif + ) { + /* enable to rx data frame */ + rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); + } + + value_rcr |= rcr_clear_bit; + rtw_write32(padapter, REG_RCR, value_rcr); + + if (rtw_linked_check(padapter) && + check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + padapter->mlmeextpriv.en_hw_update_tsf = _TRUE; + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_linked_check(padapter->pbuddy_adapter) && + check_fwstate(&padapter->pbuddy_adapter->mlmepriv, WIFI_AP_STATE) != _TRUE) + /* disable update buddy TSF to avoid updating wrong TSF due to clear RCR_CBSSID_BCN */ + padapter->pbuddy_adapter->mlmeextpriv.en_hw_update_tsf = _TRUE; +#endif + + /* Restore orignal RRSR setting. */ + rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR); + + if (ap_num) { + int i; + _adapter *iface; + + ResumeTxBeacon(padapter); + for (i = 0; i < dvobj->iface_nums; i++) { + iface = dvobj->padapters[i]; + if (!iface) + continue; + + if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE + && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE + ) { + iface->mlmepriv.update_bcn = _TRUE; + #ifndef CONFIG_INTERRUPT_BASED_TXBCN + #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + tx_beacon_hdl(iface, NULL); + #endif + #endif + + } + } + } + } +} + +static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val) +{ + u8 val8; + u16 val16; + u32 val32; + u8 RetryLimit; + u8 type; + PHAL_DATA_TYPE pHalData; + struct mlme_priv *pmlmepriv; + + RetryLimit = 0x30; + type = *(u8 *)val; + pHalData = GET_HAL_DATA(padapter); + pmlmepriv = &padapter->mlmepriv; + +#ifdef CONFIG_CONCURRENT_MODE + if (type == 0) { + /* prepare to join */ + if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_LINKED)) + StopTxBeacon(padapter); + + /* enable to rx data frame.Accept all data frame */ + rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); + + if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) { + val32 = rtw_read32(padapter, REG_RCR); + val32 |= RCR_CBSSID_BCN; + rtw_write32(padapter, REG_RCR, val32); + } else { + val32 = rtw_read32(padapter, REG_RCR); + val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; + rtw_write32(padapter, REG_RCR, val32); + } + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48; + else /* Ad-hoc Mode */ + RetryLimit = 0x7; + } else if (type == 1) { + /* joinbss_event call back when join res < 0 */ + if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_)) + rtw_write16(padapter, REG_RXFLTMAP2, 0x00); + + if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_LINKED)) { + ResumeTxBeacon(padapter); + + /* reset TSF 1/2 after ResumeTxBeacon */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0)); + } + } else if (type == 2) { + /* sta add event call back */ + + /* enable update TSF */ + if (padapter->iface_type == IFACE_PORT1) { + val8 = rtw_read8(padapter, REG_BCN_CTRL_1); + val8 &= ~DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL_1, val8); + } else { + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 &= ~DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL, val8); + } + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { + rtw_write8(padapter, 0x542 , 0x02); + RetryLimit = 0x7; + } + + if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && + check_buddy_fwstate(padapter, _FW_LINKED)) { + ResumeTxBeacon(padapter); + + /* reset TSF 1/2 after ResumeTxBeacon */ + rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0)); + } + } + + val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT); + rtw_write16(padapter, REG_RL, val16); +#else /* !CONFIG_CONCURRENT_MODE */ + if (type == 0) { /* prepare to join */ + /*enable to rx data frame.Accept all data frame */ + /*rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); */ + rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); + + val32 = rtw_read32(padapter, REG_RCR); + if (padapter->in_cta_test) + val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*| RCR_ADF */ + else + val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; + rtw_write32(padapter, REG_RCR, val32); + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48; + else /* Ad-hoc Mode */ + RetryLimit = 0x7; + } else if (type == 1) /*joinbss_event call back when join res < 0 */ + rtw_write16(padapter, REG_RXFLTMAP2, 0x00); + else if (type == 2) { /*sta add event call back */ + /*enable update TSF */ + val8 = rtw_read8(padapter, REG_BCN_CTRL); + val8 &= ~DIS_TSF_UDT; + rtw_write8(padapter, REG_BCN_CTRL, val8); + + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) + RetryLimit = 0x7; + } + + val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT); + rtw_write16(padapter, REG_RL, val16); +#endif /* !CONFIG_CONCURRENT_MODE */ +} + +static void hw_var_set_hw_update_tsf(PADAPTER padapter) +{ + + u16 reg_bcn_ctl; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) + reg_bcn_ctl = REG_BCN_CTRL_1; + else + reg_bcn_ctl = REG_BCN_CTRL; +#else + reg_bcn_ctl = REG_BCN_CTRL; +#endif + + if (!pmlmeext->en_hw_update_tsf) + return; + + /* check REG_RCR bit is set */ + if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN)) { + pmlmeext->en_hw_update_tsf = _FALSE; + return; + } + + + /* enable hw update tsf function for non-AP */ + if (rtw_linked_check(padapter) && + check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + /* enable update buddy TSF */ + rtw_write8(padapter, reg_bcn_ctl, rtw_read8(padapter, reg_bcn_ctl)&(~DIS_TSF_UDT)); + + pmlmeext->en_hw_update_tsf = _FALSE; +} + +void CCX_FwC2HTxRpt_8188f(PADAPTER padapter, u8 *pdata, u8 len) +{ + u8 seq_no; + +#define GET_8188F_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1) +#define GET_8188F_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1) + + /*DBG_871X("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, */ + /* *pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7)); */ + + seq_no = *(pdata + 6); + +#ifdef CONFIG_XMIT_ACK + if (GET_8188F_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8188F_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); + /* + else if(seq_no != padapter->xmitpriv.seq_no) { + DBG_871X("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no); + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); + } + */ + else + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS); +#endif +} + +#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_8188f(PADAPTER padapter, u8 *pdata, u8 len) +{ + int i = 0; + int cnt = 0, total_length = 0; + u8 buf[128] = {0}; + u8 more_data = _FALSE; + u8 *nextdata = NULL; + u8 test = 0; + + 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 - 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; + } + + 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 */ + +s32 c2h_id_filter_ccx_8188f(u8 *buf) +{ + struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf; + s32 ret = _FALSE; + if (c2h_evt->id == C2H_CCX_TX_RPT) + ret = _TRUE; + + return ret; +} + + +s32 c2h_handler_8188f(PADAPTER padapter, u8 *buf) +{ + struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + s32 ret = _SUCCESS; + u8 index = 0; + + if (pC2hEvent == NULL) { + DBG_8192C("%s(): pC2hEventis NULL\n", __func__); + ret = _FAIL; + goto exit; + } + + switch (pC2hEvent->id) { + case C2H_DBG: { + RT_TRACE(_module_hal_init_c_, _drv_info_, ("c2h_handler_8188f: %s\n", pC2hEvent->payload)); + } + break; + + case C2H_CCX_TX_RPT: + /*CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload); */ + break; + +#ifdef CONFIG_BT_COEXIST + case C2H_BT_INFO: + rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload); + break; +#endif + +/* +#ifdef CONFIG_MP_INCLUDED + case C2H_BT_MP_INFO: + DBG_8192C(" %s, C2H_BT_MP_INFO pC2hEvent->plen=%d\n", __func__, pC2hEvent->plen); + MPTBT_FwC2hBtMpCtrl(padapter, pC2hEvent->payload, pC2hEvent->plen); + break; +#endif +*/ + default: + break; + } + + /* Clear event to notify FW we have read the command. */ + /* Note: */ + /* If this field isn't clear, the FW won't update the next command message. */ + /*rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); */ +exit: + return ret; +} + +static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2hBuf) +{ + u8 index = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + + if (c2hBuf == NULL) { + DBG_8192C("%s c2hbuff is NULL\n", __func__); + return; + } + + switch (pC2hEvent->CmdID) { + case C2H_CCX_TX_RPT: + CCX_FwC2HTxRpt_8188f(padapter, c2hBuf, pC2hEvent->CmdLen); + break; + +#ifdef CONFIG_BT_COEXIST + case C2H_BT_INFO: + rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf); + break; +#endif + +/* +#ifdef CONFIG_MP_INCLUDED + case C2H_BT_MP_INFO: + MPTBT_FwC2hBtMpCtrl(padapter, c2hBuf, pC2hEvent->CmdLen); + break; +#endif +*/ +#ifdef CONFIG_FW_C2H_DEBUG + case C2H_EXTEND: + Debug_FwC2H_8188f(padapter, c2hBuf, pC2hEvent->CmdLen); + break; +#endif /* CONFIG_FW_C2H_DEBUG */ + + default: + if (!(phydm_c2H_content_parsing(pDM_Odm, pC2hEvent->CmdID, pC2hEvent->CmdLen, c2hBuf))) + RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: [WARNING] unknown C2H(0x%02x)\n", __func__, c2hCmdId)); + + break; + + } + +#ifndef CONFIG_C2H_PACKET_EN + /* Clear event to notify FW we have read the command. */ + /* Note: */ + /* If this field isn't clear, the FW won't update the next command message. */ + rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); +#endif +} + +#ifdef CONFIG_C2H_PACKET_EN + +static void C2HPacketHandler_8188F(PADAPTER padapter, u8 *pbuffer, u16 length) +{ + C2H_EVT_HDR C2hEvent; + u8 *tmpBuf = NULL; +#ifdef CONFIG_WOWLAN + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + if (pwrpriv->wowlan_mode == _TRUE) { + DBG_871X("%s(): return because wowolan_mode==TRUE! CMDID=%d\n", __func__, pbuffer[0]); + return; + } +#endif + C2hEvent.CmdID = pbuffer[0]; + C2hEvent.CmdSeq = pbuffer[1]; + 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_8188F(): Command Content:\n", tmpBuf, C2hEvent.CmdLen); + + process_c2h_event(padapter, &C2hEvent, tmpBuf); + /*c2h_handler_8188f(padapter,&C2hEvent); */ + return; +} + +void rtl8188f_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", + __func__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen); + + switch (C2hEvent.CmdID) { + case C2H_CCX_TX_RPT: +#ifdef CONFIG_FW_C2H_DEBUG + case C2H_EXTEND: +#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 */ +/* BITS [127:120] [119:16] [15:8] [7:4] [3:0] */ +/*2009.10.08. by tynli. */ +static void C2HCommandHandler(PADAPTER padapter) +{ + C2H_EVT_HDR C2hEvent; +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + + u8 *tmpBuf = NULL; + u8 index = 0; + u8 bCmdMsgReady = _FALSE; + u8 U1bTmp = 0; + /*u8 QueueID = 0; */ + + _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR)); + + C2hEvent.CmdID = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8188F); + C2hEvent.CmdLen = rtw_read8(padapter, REG_C2HEVT_CMD_LEN_8188F); + C2hEvent.CmdSeq = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8188F + 1); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "C2HCommandHandler(): ", + &C2hEvent , sizeof(C2hEvent)); + + U1bTmp = rtw_read8(padapter, REG_C2HEVT_CLEAR); + DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n", + __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq); + + if (U1bTmp == C2H_EVT_HOST_CLOSE) { + /* Not ready. */ + return; + } else if (U1bTmp == C2H_EVT_FW_CLOSE) + bCmdMsgReady = _TRUE; + else { + /* Not a valid value, reset the clear event. */ + goto exit; + } + + if (C2hEvent.CmdLen == 0) + goto exit; + tmpBuf = rtw_zmalloc(C2hEvent.CmdLen); + if (tmpBuf == NULL) + goto exit; + + /* Read the content */ + for (index = 0; index < C2hEvent.CmdLen; index++) + tmpBuf[index] = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8188F + 2 + index); + + RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HCommandHandler(): Command Content:\n", tmpBuf, C2hEvent.CmdLen); + + /*process_c2h_event(padapter,&C2hEvent, tmpBuf); */ + c2h_handler_8188f(padapter, &C2hEvent); + if (tmpBuf) + rtw_mfree(tmpBuf, C2hEvent.CmdLen); +#endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */ + +#ifdef CONFIG_USB_HCI + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR)); + C2hEvent.CmdID = pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF; + C2hEvent.CmdLen = (pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF0) >> 4; + C2hEvent.CmdSeq = pHalData->C2hArray[USB_C2H_SEQ_OFFSET]; + c2h_handler_8188f(padapter, (u8 *)&C2hEvent); + /*process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]); */ +#endif /* CONFIG_USB_HCI */ + + /*REG_C2HEVT_CLEAR have done in process_c2h_event */ + return; +exit: + rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); + return; +} + +#endif /* !CONFIG_C2H_PACKET_EN */ + +void rtl8188f_set_pll_ref_clk_sel(_adapter *adapter, u8 sel) +{ + u8 value8; + + value8 = rtw_read8(adapter, REG_MAC_PLL_CTRL_EXT_8188F); + if ((value8 & 0x0F) != (sel & 0x0F)) { + u16 value16; + u8 ori_bit_wlock_2c; + + value16 = rtw_read16(adapter, REG_RSV_CTRL_8188F); + ori_bit_wlock_2c = (value16 & BIT8) ? 1 : 0; + if (ori_bit_wlock_2c) { + value16 &= ~BIT8; + rtw_write16(adapter, REG_RSV_CTRL_8188F, value16); + } + + DBG_871X_LEVEL(_drv_always_, "switch pll_ref_clk_sel from 0x%x to 0x%x\n" + , (value8 & 0x0F), (sel & 0x0F)); + value8 = (value8 & 0xF0) | (sel & 0x0F); + rtw_write8(adapter, REG_MAC_PLL_CTRL_EXT_8188F, value8); + + if (ori_bit_wlock_2c) { + value16 |= BIT8; + rtw_write16(adapter, REG_RSV_CTRL_8188F, value16); + } + } +} + +void SetHwReg8188F(PADAPTER padapter, u8 variable, u8 *val) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8 val8; + u16 val16; + u32 val32; + + _func_enter_; + + switch (variable) { + case HW_VAR_MEDIA_STATUS: + val8 = rtw_read8(padapter, MSR) & 0x0c; + val8 |= *val; + rtw_write8(padapter, MSR, val8); + break; + + case HW_VAR_MEDIA_STATUS1: + val8 = rtw_read8(padapter, MSR) & 0x03; + val8 |= *val << 2; + rtw_write8(padapter, MSR, val8); + break; + + case HW_VAR_SET_OPMODE: + hw_var_set_opmode(padapter, variable, val); + break; + + case HW_VAR_MAC_ADDR: + hw_var_set_macaddr(padapter, variable, val); + break; + + case HW_VAR_BSSID: + hw_var_set_bssid(padapter, variable, val); + break; + + case HW_VAR_BASIC_RATE: { + struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info; + u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0; + u16 rrsr_2g_force_mask = RRSR_CCK_RATES; + u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES); + + HalSetBrateCfg(padapter, val, &BrateCfg); + input_b = BrateCfg; + + /* apply force and allow mask */ + BrateCfg |= rrsr_2g_force_mask; + BrateCfg &= rrsr_2g_allow_mask; + masked = BrateCfg; + +#ifdef CONFIG_CMCC_TEST + BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */ + BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */ +#endif + + /* IOT consideration */ + if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) { + /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */ + if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0) + BrateCfg |= RRSR_6M; + } + ioted = BrateCfg; + + pHalData->BasicRateSet = BrateCfg; + + DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted); + + /* Set RRSR rate table. */ + rtw_write16(padapter, REG_RRSR, BrateCfg); + rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0); + } + break; + + case HW_VAR_TXPAUSE: + rtw_write8(padapter, REG_TXPAUSE, *val); + break; + + case HW_VAR_BCN_FUNC: + hw_var_set_bcn_func(padapter, variable, val); + break; + + case HW_VAR_CORRECT_TSF: + hw_var_set_correct_tsf(padapter, variable, val); + break; + + case HW_VAR_CHECK_BSSID: { + u32 val32; + + val32 = rtw_read32(padapter, REG_RCR); + if (*val) + val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; + else + val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtw_write32(padapter, REG_RCR, val32); + } + break; + + case HW_VAR_MLME_DISCONNECT: + hw_var_set_mlme_disconnect(padapter, variable, val); + break; + + case HW_VAR_MLME_SITESURVEY: + hw_var_set_mlme_sitesurvey(padapter, variable, val); + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_ScanNotify(padapter, *val ? _TRUE : _FALSE); +#endif /* CONFIG_BT_COEXIST */ + break; + + case HW_VAR_MLME_JOIN: + hw_var_set_mlme_join(padapter, variable, val); + +#ifdef CONFIG_BT_COEXIST + switch (*val) { + case 0: + /* prepare to join */ + rtw_btcoex_ConnectNotify(padapter, _TRUE); + break; + case 1: + /* joinbss_event callback when join res < 0 */ + rtw_btcoex_ConnectNotify(padapter, _FALSE); + break; + case 2: + /* sta add event callback */ + /*rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT); */ + break; + } +#endif /* CONFIG_BT_COEXIST */ + break; + + case HW_VAR_ON_RCR_AM: + val32 = rtw_read32(padapter, REG_RCR); + val32 |= RCR_AM; + rtw_write32(padapter, REG_RCR, val32); + DBG_8192C("%s, %d, RCR= %x\n", __func__, __LINE__, rtw_read32(padapter, REG_RCR)); + break; + + case HW_VAR_OFF_RCR_AM: + val32 = rtw_read32(padapter, REG_RCR); + val32 &= ~RCR_AM; + rtw_write32(padapter, REG_RCR, val32); + DBG_8192C("%s, %d, RCR= %x\n", __func__, __LINE__, rtw_read32(padapter, REG_RCR)); + break; + + case HW_VAR_BEACON_INTERVAL: + rtw_write16(padapter, REG_BCN_INTERVAL, *((u16 *)val)); + break; + + case HW_VAR_SLOT_TIME: + rtw_write8(padapter, REG_SLOT, *val); + break; + + case HW_VAR_RESP_SIFS: +#if 0 + /* SIFS for OFDM Data ACK */ + rtw_write8(padapter, REG_SIFS_CTX + 1, val[0]); + /* SIFS for OFDM consecutive tx like CTS data! */ + rtw_write8(padapter, REG_SIFS_TRX + 1, val[1]); + + rtw_write8(padapter, REG_SPEC_SIFS + 1, val[0]); + rtw_write8(padapter, REG_MAC_SPEC_SIFS + 1, val[0]); + + /* 20100719 Joseph: Revise SIFS setting due to Hardware register definition change. */ + rtw_write8(padapter, REG_R2T_SIFS + 1, val[0]); + rtw_write8(padapter, REG_T2T_SIFS + 1, val[0]); + +#else + /*SIFS_Timer = 0x0a0a0808; */ + /*RESP_SIFS for CCK */ + rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); /* SIFS_T2T_CCK (0x08) */ + rtw_write8(padapter, REG_RESP_SIFS_CCK + 1, val[1]); /*SIFS_R2T_CCK(0x08) */ + /*RESP_SIFS for OFDM */ + rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); /*SIFS_T2T_OFDM (0x0a) */ + rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, val[3]); /*SIFS_R2T_OFDM(0x0a) */ +#endif + break; + + case HW_VAR_ACK_PREAMBLE: { + u8 regTmp; + u8 bShortPreamble = *val; + + /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ + /*regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */ + regTmp = 0; + if (bShortPreamble) + regTmp |= 0x80; + rtw_write8(padapter, REG_RRSR + 2, regTmp); + } + break; + + case HW_VAR_CAM_EMPTY_ENTRY: { + u8 ucIndex = *val; + u8 i; + u32 ulCommand = 0; + u32 ulContent = 0; + u32 ulEncAlgo = CAM_AES; + + for (i = 0; i < CAM_CONTENT_COUNT; i++) { + /* filled id in CAM config 2 byte */ + if (i == 0) { + ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2); + /*ulContent |= CAM_VALID; */ + } else + ulContent = 0; + /* polling bit, and No Write enable, and address */ + ulCommand = CAM_CONTENT_COUNT * ucIndex + i; + ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE; + /* write content 0 is equall to mark invalid */ + rtw_write32(padapter, WCAMI, ulContent); /*delay_ms(40); */ + /*RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx\n",ulContent)); */ + rtw_write32(padapter, RWCAM, ulCommand); /*delay_ms(40); */ + /*RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx\n",ulCommand)); */ + } + } + break; + + case HW_VAR_CAM_INVALID_ALL: + rtw_write32(padapter, RWCAM, BIT(31) | BIT(30)); + break; + + case HW_VAR_AC_PARAM_VO: + rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32 *)val)); + break; + + case HW_VAR_AC_PARAM_VI: + rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32 *)val)); + break; + + case HW_VAR_AC_PARAM_BE: + pHalData->AcParam_BE = ((u32 *)(val))[0]; + rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32 *)val)); + break; + + case HW_VAR_AC_PARAM_BK: + rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32 *)val)); + break; + + case HW_VAR_ACM_CTRL: { + u8 ctrl = *((u8 *)val); + u8 hwctrl = 0; + + if (ctrl != 0) { + hwctrl |= AcmHw_HwEn; + + if (ctrl & BIT(1)) /* BE */ + hwctrl |= AcmHw_BeqEn; + + if (ctrl & BIT(2)) /* VI */ + hwctrl |= AcmHw_ViqEn; + + if (ctrl & BIT(3)) /* VO */ + hwctrl |= AcmHw_VoqEn; + } + + DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl); + rtw_write8(padapter, REG_ACMHWCTRL, hwctrl); + } + break; + + case HW_VAR_AMPDU_FACTOR: { + u32 AMPDULen = (*((u8 *)val)); + + if (AMPDULen < HT_AGG_SIZE_32K) + AMPDULen = (0x2000 << (*((u8 *)val))) - 1; + else + AMPDULen = 0x7fff; + + rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8188F, AMPDULen); + } + break; + +#if 0 + case HW_VAR_RXDMA_AGG_PG_TH: + rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val); + break; +#endif + + case HW_VAR_H2C_FW_PWRMODE: { + u8 psmode = *val; + + /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */ + /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */ + if (psmode != PS_MODE_ACTIVE) + ODM_RF_Saving(&pHalData->odmpriv, _TRUE); + + /*if (psmode != PS_MODE_ACTIVE) { */ + /* rtl8188f_set_lowpwr_lps_cmd(padapter, _TRUE); */ + /*} else { */ + /* rtl8188f_set_lowpwr_lps_cmd(padapter, _FALSE); */ + /*} */ + rtl8188f_set_FwPwrMode_cmd(padapter, psmode); + } + break; + case HW_VAR_H2C_PS_TUNE_PARAM: + rtl8188f_set_FwPsTuneParam_cmd(padapter); + break; + + case HW_VAR_H2C_FW_JOINBSSRPT: + rtl8188f_set_FwJoinBssRpt_cmd(padapter, *val); + break; + +#ifdef CONFIG_P2P + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl8188f_set_p2p_ps_offload_cmd(padapter, *val); + break; +#endif /*CONFIG_P2P */ +#ifdef CONFIG_TDLS + case HW_VAR_TDLS_WRCR: + rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & (~RCR_CBSSID_DATA)); + break; + case HW_VAR_TDLS_RS_RCR: + rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) | (RCR_CBSSID_DATA)); + break; +#endif /*CONFIG_TDLS */ + +#ifdef CONFIG_ANTENNA_DIVERSITY + case HW_VAR_ANTENNA_DIVERSITY_SELECT: + { + u8 Optimum_antenna = (*(u8 *)val); + u8 Ant; + /*switch antenna to Optimum_antenna*/ + /*DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");*/ + if (pHalData->CurAntenna != Optimum_antenna) { + Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT; + ODM_UpdateRxIdleAnt(&pHalData->odmpriv, Ant); + + pHalData->CurAntenna = Optimum_antenna; + /*DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");*/ + } + } + break; +#endif + + case HW_VAR_EFUSE_USAGE: + pHalData->EfuseUsedPercentage = *val; + break; + + case HW_VAR_EFUSE_BYTES: + pHalData->EfuseUsedBytes = *((u16 *)val); + break; + + case HW_VAR_EFUSE_BT_USAGE: +#ifdef HAL_EFUSE_MEMORY + pHalData->EfuseHal.BTEfuseUsedPercentage = *val; +#endif + break; + + case HW_VAR_EFUSE_BT_BYTES: +#ifdef HAL_EFUSE_MEMORY + pHalData->EfuseHal.BTEfuseUsedBytes = *((u16 *)val); +#else + BTEfuseUsedBytes = *((u16 *)val); +#endif + break; + + case HW_VAR_FIFO_CLEARN_UP: { +#define RW_RELEASE_EN BIT(18) +#define RXDMA_IDLE BIT(17) + + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + u8 trycnt = 100; + + /* pause tx */ + rtw_write8(padapter, REG_TXPAUSE, 0xff); + + /* keep sn */ + padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ); + + if (pwrpriv->bkeepfwalive != _TRUE) { + /* RX DMA stop */ + val32 = rtw_read32(padapter, REG_RXPKT_NUM); + val32 |= RW_RELEASE_EN; + rtw_write32(padapter, REG_RXPKT_NUM, val32); + do { + val32 = rtw_read32(padapter, REG_RXPKT_NUM); + val32 &= RXDMA_IDLE; + if (val32) + break; + + DBG_871X("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __func__, val32, trycnt); + } while (--trycnt); + if (trycnt == 0) + DBG_8192C("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n"); + + /* RQPN Load 0 */ + rtw_write16(padapter, REG_RQPN_NPQ, 0); + rtw_write32(padapter, REG_RQPN, 0x80000000); + rtw_mdelay_os(2); + } + } + break; + + case HW_VAR_RESTORE_HW_SEQ: + /* restore Sequence No. */ + rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn); + break; + +#ifdef CONFIG_CONCURRENT_MODE + case HW_VAR_CHECK_TXBUF: { + u32 i; + u8 RetryLimit = 0x01; + u32 reg_200, reg_204; + + val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT; + rtw_write16(padapter, REG_RL, val16); + + for (i = 0; i < 200; i++) { /* polling 200x10=2000 msec */ + reg_200 = rtw_read32(padapter, 0x200); + reg_204 = rtw_read32(padapter, 0x204); + if (reg_200 != reg_204) { + /*DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i); */ + rtw_msleep_os(10); + } else { + DBG_871X("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i); + break; + } + } + + if (reg_200 != reg_204) + DBG_871X("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200); + + RetryLimit = 0x30; + val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT; + rtw_write16(padapter, REG_RL, val16); + } + break; +#endif /* CONFIG_CONCURRENT_MODE */ + + case HW_VAR_APFM_ON_MAC: + pHalData->bMacPwrCtrlOn = *val; + DBG_871X("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn); + break; + + case HW_VAR_HCI_SUS_STATE: + pHalData->hci_sus_state = *val; + DBG_871X("%s: hci_sus_state=%u\n", __func__, pHalData->hci_sus_state); + break; + + case HW_VAR_NAV_UPPER: { + u32 usNavUpper = *((u32 *)val); + + if (usNavUpper > HAL_NAV_UPPER_UNIT_8188F * 0xFF) { + RT_TRACE(_module_hal_init_c_, _drv_notice_, ("The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", usNavUpper, HAL_NAV_UPPER_UNIT_8188F)); + break; + } + + /* The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8188F - 1) / HAL_NAV_UPPER_UNIT_8188F) */ + /* is getting the upper integer. */ + usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8188F - 1) / HAL_NAV_UPPER_UNIT_8188F; + rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper); + } + break; + +#ifndef CONFIG_C2H_PACKET_EN + case HW_VAR_C2H_HANDLE: + C2HCommandHandler(padapter); + break; +#endif + + case HW_VAR_BCN_VALID: +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8188F + 2); + val8 |= BIT(0); + rtw_write8(padapter, REG_DWBCN1_CTRL_8188F + 2, val8); + } else +#endif /* CONFIG_CONCURRENT_MODE */ + { + /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */ + val8 = rtw_read8(padapter, REG_TDECTRL + 2); + val8 |= BIT(0); + rtw_write8(padapter, REG_TDECTRL + 2, val8); + } + break; + + case HW_VAR_DL_BCN_SEL: +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + /* SW_BCN_SEL - Port1 */ + val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8188F + 2); + val8 |= BIT(4); + rtw_write8(padapter, REG_DWBCN1_CTRL_8188F + 2, val8); + } else +#endif /* CONFIG_CONCURRENT_MODE */ + { + /* SW_BCN_SEL - Port0 */ + val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8188F + 2); + val8 &= ~BIT(4); + rtw_write8(padapter, REG_DWBCN1_CTRL_8188F + 2, val8); + } + break; + + case HW_VAR_DO_IQK: + if (*val) + pHalData->bNeedIQK = _TRUE; + else + pHalData->bNeedIQK = _FALSE; + break; + + case HW_VAR_DL_RSVD_PAGE: +#ifdef CONFIG_BT_COEXIST + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) + rtl8188f_download_BTCoex_AP_mode_rsvd_page(padapter); + else +#endif /* CONFIG_BT_COEXIST */ + { + rtl8188f_download_rsvd_page(padapter, RT_MEDIA_CONNECT); + } + break; + + case HW_VAR_MACID_SLEEP: { + /* TODO: 16 MACID? */ + 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; + } + + 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(bit_shift); + rtw_write32(padapter, reg_macid_sleep, val32); + } + break; + + case HW_VAR_MACID_WAKEUP: { + /* TODO: 16 MACID? */ + 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; + } + + 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(bit_shift); + rtw_write32(padapter, reg_macid_sleep, val32); + } + break; +#ifdef CONFIG_GPIO_WAKEUP + case HW_SET_GPIO_WL_CTRL: { + u8 enable = *val; + u8 value = rtw_read8(padapter, 0x4e); + + if (enable && (value & BIT(6))) { + value &= ~BIT(6); + rtw_write8(padapter, 0x4e, value); + } else if (enable == _FALSE) { + value |= BIT(6); + rtw_write8(padapter, 0x4e, value); + } + DBG_871X("%s: set WL control, 0x4E=0x%02X\n", + __func__, rtw_read8(padapter, 0x4e)); + } + break; +#endif + case HW_VAR_EN_HW_UPDATE_TSF: + hw_var_set_hw_update_tsf(padapter); + break; + default: + SetHwReg(padapter, variable, val); + break; + } + + _func_exit_; +} + +struct qinfo_8188f { + u32 head: 8; + u32 pkt_num: 7; + u32 tail: 8; + u32 ac: 2; + u32 macid: 7; +}; + +struct bcn_qinfo_8188f { + u16 head: 8; + u16 pkt_num: 8; +}; + +void dump_qinfo_8188f(void *sel, struct qinfo_8188f *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_8188f(void *sel, struct bcn_qinfo_8188f *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_8188f(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_8188f(sel, (struct qinfo_8188f *)&q0_info, "Q0 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q1_info, "Q1 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q2_info, "Q2 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q3_info, "Q3 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q4_info, "Q4 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q5_info, "Q5 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q6_info, "Q6 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&q7_info, "Q7 "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&mg_q_info, "MG "); + dump_qinfo_8188f(sel, (struct qinfo_8188f *)&hi_q_info, "HI "); + dump_bcn_qinfo_8188f(sel, (struct bcn_qinfo_8188f *)&bcn_q_info, "BCN "); +} + +void GetHwReg8188F(PADAPTER padapter, u8 variable, u8 *val) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8 val8; + u16 val16; + u32 val32; + + + switch (variable) { + case HW_VAR_TXPAUSE: + *val = rtw_read8(padapter, REG_TXPAUSE); + break; + + case HW_VAR_BCN_VALID: +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->iface_type == IFACE_PORT1) { + val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8188F + 2); + *val = (BIT(0) & val8) ? _TRUE : _FALSE; + } else +#endif + { + /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */ + val8 = rtw_read8(padapter, REG_TDECTRL + 2); + *val = (BIT(0) & val8) ? _TRUE : _FALSE; + } + break; + + case HW_VAR_FWLPS_RF_ON: { + /* When we halt NIC, we should check if FW LPS is leave. */ + u32 valRCR; + + if ((rtw_is_surprise_removed(padapter)) || + (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)) { + /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */ + /* because Fw is unload. */ + *val = _TRUE; + } else { + valRCR = rtw_read32(padapter, REG_RCR); + valRCR &= 0x00070000; + if (valRCR) + *val = _FALSE; + else + *val = _TRUE; + } + } + break; + +#ifdef CONFIG_ANTENNA_DIVERSITY + case HW_VAR_CURRENT_ANTENNA: + *val = pHalData->CurAntenna; + break; +#endif + + case HW_VAR_EFUSE_USAGE: + *val = pHalData->EfuseUsedPercentage; + break; + + case HW_VAR_EFUSE_BYTES: + *((u16 *)val) = pHalData->EfuseUsedBytes; + break; + + case HW_VAR_EFUSE_BT_USAGE: +#ifdef HAL_EFUSE_MEMORY + *val = pHalData->EfuseHal.BTEfuseUsedPercentage; +#endif + break; + + case HW_VAR_EFUSE_BT_BYTES: +#ifdef HAL_EFUSE_MEMORY + *((u16 *)val) = pHalData->EfuseHal.BTEfuseUsedBytes; +#else + *((u16 *)val) = BTEfuseUsedBytes; +#endif + break; + + case HW_VAR_APFM_ON_MAC: + *val = pHalData->bMacPwrCtrlOn; + break; + case HW_VAR_HCI_SUS_STATE: + *val = pHalData->hci_sus_state; + break; + case HW_VAR_CHK_HI_QUEUE_EMPTY: + val16 = rtw_read16(padapter, REG_TXPKT_EMPTY); + *val = (val16 & BIT(10)) ? _TRUE : _FALSE; + break; +#ifdef CONFIG_WOWLAN + case HW_VAR_RPWM_TOG: + *val = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HRPWM1) & BIT7; + break; + case HW_VAR_WAKEUP_REASON: + *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON); + if (*val == 0xEA) + *val = 0; + break; + case HW_VAR_SYS_CLKR: + *val = rtw_read8(padapter, REG_SYS_CLKR); + break; +#endif + case HW_VAR_DUMP_MAC_QUEUE_INFO: + dump_mac_qinfo_8188f(val, padapter); + break; + default: + GetHwReg(padapter, variable, val); + break; + } +} + +/* + * Description: + * Change default setting of specified variable. + */ +u8 SetHalDefVar8188F(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval) +{ + PHAL_DATA_TYPE pHalData; + u8 bResult; + + + pHalData = GET_HAL_DATA(padapter); + bResult = _SUCCESS; + + switch (variable) { + default: + bResult = SetHalDefVar(padapter, variable, pval); + break; + } + + return bResult; +} + +#ifdef CONFIG_C2H_PACKET_EN +void SetHwRegWithBuf8188F(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_8188F(padapter, pbuf, len); + break; + + default: + break; + } + _func_exit_; +} +#endif /* CONFIG_C2H_PACKET_EN */ + +/* + * Description: + * Query setting of specified variable. + */ +u8 GetHalDefVar8188F(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval) +{ + PHAL_DATA_TYPE pHalData; + u8 bResult; + + + pHalData = GET_HAL_DATA(padapter); + bResult = _SUCCESS; + + switch (variable) { + case HAL_DEF_MAX_RECVBUF_SZ: + *((u32 *)pval) = MAX_RECVBUF_SZ; + break; + + case HAL_DEF_RX_PACKET_OFFSET: + *((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ * 8; + break; + + case HW_VAR_MAX_RX_AMPDU_FACTOR: + /* Stanley@BB.SD3 suggests 16K can get stable performance */ + /* The experiment was done on SDIO interface */ + /* coding by Lucas@20130730 */ + *(HT_CAP_AMPDU_FACTOR *)pval = MAX_AMPDU_FACTOR_16K; + break; + case HW_VAR_BEST_AMPDU_DENSITY: + *((u32 *)pval) = AMPDU_DENSITY_VALUE_7; + break; + case HAL_DEF_TX_LDPC: + case HAL_DEF_RX_LDPC: + *((u8 *)pval) = _FALSE; + break; + case HAL_DEF_TX_STBC: + *((u8 *)pval) = 0; + break; + case HAL_DEF_RX_STBC: + *((u8 *)pval) = 1; + break; + case HAL_DEF_EXPLICIT_BEAMFORMER: + case HAL_DEF_EXPLICIT_BEAMFORMEE: + *((u8 *)pval) = _FALSE; + break; + + case HW_DEF_RA_INFO_DUMP: { + u8 mac_id = *(u8 *)pval; + u32 cmd; + u32 ra_info1, ra_info2; + u32 rate_mask1, rate_mask2; + u8 curr_tx_rate, curr_tx_sgi, hight_rate, lowest_rate; + + DBG_8192C("============ RA status check Mac_id:%d ===================\n", mac_id); + + cmd = 0x40000100 | mac_id; + rtw_write32(padapter, REG_HMEBOX_DBG_2_8188F, cmd); + rtw_msleep_os(10); + ra_info1 = rtw_read32(padapter, 0x2F0); + curr_tx_rate = ra_info1 & 0x7F; + curr_tx_sgi = (ra_info1 >> 7) & 0x01; + DBG_8192C("[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d, PWRSTS = 0x%02x\n", + ra_info1, + HDATA_RATE(curr_tx_rate), + curr_tx_sgi, + (ra_info1 >> 8) & 0x07); + + cmd = 0x40000400 | mac_id; + rtw_write32(padapter, REG_HMEBOX_DBG_2_8188F, cmd); + rtw_msleep_os(10); + ra_info1 = rtw_read32(padapter, 0x2F0); + ra_info2 = rtw_read32(padapter, 0x2F4); + rate_mask1 = rtw_read32(padapter, 0x2F8); + rate_mask2 = rtw_read32(padapter, 0x2FC); + hight_rate = ra_info2 & 0xFF; + lowest_rate = (ra_info2 >> 8) & 0xFF; + + DBG_8192C("[ ra_info1:0x%08x ] =>RSSI=%d, BW_setting=0x%02x, DISRA=0x%02x, VHT_EN=0x%02x\n", + ra_info1, + ra_info1 & 0xFF, + (ra_info1 >> 8) & 0xFF, + (ra_info1 >> 16) & 0xFF, + (ra_info1 >> 24) & 0xFF); + + DBG_8192C("[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n", + ra_info2, + HDATA_RATE(hight_rate), + HDATA_RATE(lowest_rate), + (ra_info2 >> 16) & 0xFF, + (ra_info2 >> 24) & 0xFF); + + DBG_8192C("rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1); + + } + break; + + case HAL_DEF_TX_PAGE_BOUNDARY: + if (!padapter->registrypriv.wifi_spec) + *(u8 *)pval = TX_PAGE_BOUNDARY_8188F; + else + *(u8 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8188F; + break; + + case HAL_DEF_MACID_SLEEP: + *(u8 *)pval = _TRUE; /* support macid sleep */ + break; + case HAL_DEF_TX_PAGE_SIZE: + *((u32 *)pval) = PAGE_SIZE_128; + break; + case HAL_DEF_RX_DMA_SZ_WOW: + *(u32 *)pval = RX_DMA_SIZE_8188F - RESV_FMWF; + break; + case HAL_DEF_RX_DMA_SZ: + *(u32 *)pval = RX_DMA_BOUNDARY_8188F + 1; + break; + case HAL_DEF_RX_PAGE_SIZE: + *((u32 *)pval) = 8; + break; + default: + bResult = GetHalDefVar(padapter, variable, pval); + break; + } + + return bResult; +} + +#ifdef CONFIG_WOWLAN +void Hal_DetectWoWMode(PADAPTER pAdapter) +{ + adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE; + DBG_871X("%s\n", __func__); +} +#endif /*CONFIG_WOWLAN */ + +void rtl8188f_start_thread(_adapter *padapter) +{ +#if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI) +#ifndef CONFIG_SDIO_TX_TASKLET + struct xmit_priv *xmitpriv = &padapter->xmitpriv; + + xmitpriv->SdioXmitThread = kthread_run(rtl8188fs_xmit_thread, padapter, "RTWHALXT"); + if (IS_ERR(xmitpriv->SdioXmitThread)) + RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8188fs_xmit_thread FAIL!!\n", __func__)); +#endif +#endif +} + +void rtl8188f_stop_thread(_adapter *padapter) +{ +#if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI) +#ifndef CONFIG_SDIO_TX_TASKLET + struct xmit_priv *xmitpriv = &padapter->xmitpriv; + + /* stop xmit_buf_thread */ + if (xmitpriv->SdioXmitThread) { + _rtw_up_sema(&xmitpriv->SdioXmitSema); + _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema); + xmitpriv->SdioXmitThread = 0; + } +#endif +#endif +} + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +extern void check_bt_status_work(void *data); +void rtl8188fs_init_checkbthang_workqueue(_adapter *adapter) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0); +#else + adapter->priv_checkbt_wq = create_workqueue("sdio_wq"); +#endif + INIT_DELAYED_WORK(&adapter->checkbt_work, (void *)check_bt_status_work); +} + +void rtl8188fs_free_checkbthang_workqueue(_adapter *adapter) +{ + if (adapter->priv_checkbt_wq) { + cancel_delayed_work_sync(&adapter->checkbt_work); + flush_workqueue(adapter->priv_checkbt_wq); + destroy_workqueue(adapter->priv_checkbt_wq); + adapter->priv_checkbt_wq = NULL; + } +} + +void rtl8188fs_cancle_checkbthang_workqueue(_adapter *adapter) +{ + if (adapter->priv_checkbt_wq) + cancel_delayed_work_sync(&adapter->checkbt_work); +} + +void rtl8188fs_hal_check_bt_hang(_adapter *adapter) +{ + if (adapter->priv_checkbt_wq) + queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0); +} +#endif + + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_phycfg.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_phycfg.c new file mode 100644 index 00000000..4cce7547 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_phycfg.c @@ -0,0 +1,1567 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8188F_PHYCFG_C_ + +#include + + +/*---------------------------Define Local Constant---------------------------*/ +/* Channel switch:The size of command tables for switch channel*/ +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ + +/*------------------------Define local variable------------------------------*/ + + +/*--------------------Define export function prototype-----------------------*/ +/* Please refer to header file */ +/*--------------------Define export function prototype-----------------------*/ + +/*----------------------------Function Body----------------------------------*/ +/* */ +/* 1. BB register R/W API */ +/* */ + +/** +* Function: phy_CalculateBitShift +* +* OverView: Get shifted position of the BitMask +* +* Input: +* u4Byte BitMask, +* +* Output: none +* Return: u4Byte Return the shift bit bit position of the mask +*/ +static u32 +phy_CalculateBitShift( + u32 BitMask +) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((BitMask >> i) & 0x1) == 1) + break; + } + + return (i); +} + + +/** +* Function: PHY_QueryBBReg +* +* OverView: Read "sepcific bits" from BB register +* +* Input: +* PADAPTER Adapter, +* u4Byte RegAddr, The target address to be readback +* u4Byte BitMask The target bit position in the target address +* to be readback +* Output: None +* Return: u4Byte Data The readback register value +* Note: This function is equal to "GetRegSetting" in PHY programming guide +*/ +u32 +PHY_QueryBBReg_8188F( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask +) +{ + u32 ReturnValue = 0, OriginalValue, BitShift; + u16 BBWaitCounter = 0; + +#if (DISABLE_BB_RF == 1) + return 0; +#endif + + /*RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_QueryBBReg(): RegAddr(%#lx), BitMask(%#lx)\n", RegAddr, BitMask)); */ + + OriginalValue = rtw_read32(Adapter, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + ReturnValue = (OriginalValue & BitMask) >> BitShift; + + return (ReturnValue); + +} + + +/** + * Function: PHY_SetBBReg + * + * OverView: Write "Specific bits" to BB register (page 8~) + * + * Input: + * PADAPTER Adapter, + * u4Byte RegAddr, The target address to be modified + * u4Byte BitMask The target bit position in the target address + * to be modified + * u4Byte Data The new register value in the target bit position + * of the target address + * + * Output: None + * Return: None + * Note: This function is equal to "PutRegSetting" in PHY programming guide + */ + +VOID +PHY_SetBBReg_8188F( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + /*u16 BBWaitCounter = 0; */ + u32 OriginalValue, BitShift; + +#if (DISABLE_BB_RF == 1) + return; +#endif + + /*RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */ + + if (BitMask != bMaskDWord) { /*if not "double word" write */ + OriginalValue = rtw_read32(Adapter, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + Data = ((OriginalValue & (~BitMask)) | ((Data << BitShift) & BitMask)); + } + + rtw_write32(Adapter, RegAddr, Data); +} + + +/* */ +/* 2. RF register R/W API */ +/* */ + +/*----------------------------------------------------------------------------- + * Function: phy_FwRFSerialRead() + * + * Overview: We support firmware to execute RF-R/W. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/21/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static u32 +phy_FwRFSerialRead( + IN PADAPTER Adapter, + IN RF_PATH eRFPath, + IN u32 Offset) +{ + u32 retValue = 0; + /*RT_ASSERT(FALSE,("deprecate!\n")); */ + return (retValue); + +} /* phy_FwRFSerialRead */ + + +/*----------------------------------------------------------------------------- + * Function: phy_FwRFSerialWrite() + * + * Overview: We support firmware to execute RF-R/W. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 01/21/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static VOID +phy_FwRFSerialWrite( + IN PADAPTER Adapter, + IN RF_PATH eRFPath, + IN u32 Offset, + IN u32 Data) +{ + /*RT_ASSERT(FALSE,("deprecate!\n")); */ +} + +static u32 +phy_RFSerialRead_8188F( + IN PADAPTER Adapter, + IN RF_PATH eRFPath, + IN u32 Offset +) +{ + u32 retValue = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath]; + u32 NewOffset; + u32 tmplong, tmplong2; + u8 RfPiEnable = 0; + u4Byte MaskforPhySet = 0; + int i = 0; + + /* */ + /* Make sure RF register offset is correct */ + /* */ + Offset &= 0xff; + + NewOffset = Offset; + + if (eRFPath == RF_PATH_A) { + tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2 | MaskforPhySet, bMaskDWord); + tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /*T65 RF */ + PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2 | MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge)); + } else { + tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter2 | MaskforPhySet, bMaskDWord); + tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /*T65 RF */ + PHY_SetBBReg(Adapter, rFPGA0_XB_HSSIParameter2 | MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge)); + } + + tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2 | MaskforPhySet, bMaskDWord); + PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2 | MaskforPhySet, bMaskDWord, tmplong2 & (~bLSSIReadEdge)); + PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2 | MaskforPhySet, bMaskDWord, tmplong2 | bLSSIReadEdge); + + rtw_udelay_os(10); + + for (i = 0; i < 2; i++) + rtw_udelay_os(MAX_STALL_TIME); + rtw_udelay_os(10); + + if (eRFPath == RF_PATH_A) + RfPiEnable = (u1Byte)PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1 | MaskforPhySet, BIT8); + else if (eRFPath == RF_PATH_B) + RfPiEnable = (u1Byte)PHY_QueryBBReg(Adapter, rFPGA0_XB_HSSIParameter1 | MaskforPhySet, BIT8); + + if (RfPiEnable) { + /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ + retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi | MaskforPhySet, bLSSIReadBackData); + + /*RT_DISP(FINIT, INIT_RF, ("Readback from RF-PI : 0x%x\n", retValue)); */ + } else { + /*Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ + retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack | MaskforPhySet, bLSSIReadBackData); + + /*RT_DISP(FINIT, INIT_RF,("Readback from RF-SI : 0x%x\n", retValue)); */ + } + return retValue; + +} + +/** + * Function: phy_RFSerialWrite_8188F + * + * OverView: Write data to RF register (page 8~) + * + * Input: + * PADAPTER Adapter, + * RF_PATH RFPath, Radio path of A/B/C/D + * u4Byte Offset, The target address to be read + * u4Byte Data The new register Data in the target bit position + * of the target to be read + * + * Output: None + * Return: None + * Note: Threre are three types of serial operations: + * 1. Software serial write + * 2. Hardware LSSI-Low Speed Serial Interface + * 3. Hardware HSSI-High speed + * serial write. Driver need to implement (1) and (2). + * This function is equal to the combination of RF_ReadReg() and RFLSSIRead() + * + * Note: For RF8256 only + * The total count of RTL8256(Zebra4) register is around 36 bit it only employs + * 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10]) + * to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration + * programming guide" for more details. + * Thus, we define a sub-finction for RTL8526 register address conversion + * =========================================================== + * Register Mode RegCTL[1] RegCTL[0] Note + * (Reg00[12]) (Reg00[10]) + * =========================================================== + * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) + * ------------------------------------------------------------------ + * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) + * ------------------------------------------------------------------ + * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) + * ------------------------------------------------------------------ + * + * 2008/09/02 MH Add 92S RF definition + * + * + * +*/ +static VOID +phy_RFSerialWrite_8188F( + IN PADAPTER Adapter, + IN RF_PATH eRFPath, + IN u32 Offset, + IN u32 Data +) +{ + u32 DataAndAddr = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + BB_REGISTER_DEFINITION_T *pPhyReg = &pHalData->PHYRegDef[eRFPath]; + u32 NewOffset; + + Offset &= 0xff; + + /* */ + /* Shadow Update */ + /* */ + /*PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */ + + /* */ + /* Switch page for 8256 RF IC */ + /* */ + NewOffset = Offset; + + /* */ + /* Put write addr in [5:0] and write data in [31:16] */ + /* */ + /*DataAndAddr = (Data<<16) | (NewOffset&0x3f); */ + DataAndAddr = ((NewOffset << 20) | (Data & 0x000fffff)) & 0x0fffffff; /* T65 RF */ + + /* */ + /* Write Operation */ + /* */ + PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); + /*RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]=0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); */ + +} + + +/** + * Function: PHY_QueryRFReg + * + * OverView: Query "Specific bits" to RF register (page 8~) + * + * Input: + * PADAPTER Adapter, + * RF_PATH eRFPath, Radio path of A/B/C/D + * u4Byte RegAddr, The target address to be read + * u4Byte BitMask The target bit position in the target address + * to be read + * + * Output: None + * Return: u4Byte Readback value + * Note: This function is equal to "GetRFRegSetting" in PHY programming guide + */ +u32 +PHY_QueryRFReg_8188F( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask +) +{ + u32 Original_Value, Readback_Value, BitShift; + +#if (DISABLE_BB_RF == 1) + return 0; +#endif + + Original_Value = phy_RFSerialRead_8188F(Adapter, eRFPath, RegAddr); + + BitShift = phy_CalculateBitShift(BitMask); + Readback_Value = (Original_Value & BitMask) >> BitShift; + + return (Readback_Value); +} + +/** +* Function: PHY_SetRFReg +* +* OverView: Write "Specific bits" to RF register (page 8~) +* +* Input: +* PADAPTER Adapter, +* RF_PATH eRFPath, Radio path of A/B/C/D +* u4Byte RegAddr, The target address to be modified +* u4Byte BitMask The target bit position in the target address +* to be modified +* u4Byte Data The new register Data in the target bit position +* of the target address +* +* Output: None +* Return: None +* Note: This function is equal to "PutRFRegSetting" in PHY programming guide +*/ +VOID +PHY_SetRFReg_8188F( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data +) +{ + u32 Original_Value, BitShift; + +#if (DISABLE_BB_RF == 1) + return; +#endif + + /* RF data is 12 bits only */ + if (BitMask != bRFRegOffsetMask) { + Original_Value = phy_RFSerialRead_8188F(Adapter, eRFPath, RegAddr); + BitShift = phy_CalculateBitShift(BitMask); + Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); + } + + phy_RFSerialWrite_8188F(Adapter, eRFPath, RegAddr, Data); +} + + +/* */ +/* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ +/* */ + + +/*----------------------------------------------------------------------------- + * Function: PHY_MACConfig8192C + * + * Overview: Condig MAC by header file or parameter file. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 08/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +s32 PHY_MACConfig8188F(PADAPTER Adapter) +{ + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s8 *pszMACRegFile; + s8 sz8188MACRegFile[] = RTL8188F_PHY_MACREG; + + + pszMACRegFile = sz8188MACRegFile; + + /* */ + /* Config MAC */ + /* */ +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + rtStatus = phy_ConfigMACWithParaFile(Adapter, pszMACRegFile); + if (rtStatus == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv); + rtStatus = _SUCCESS; +#endif/*CONFIG_EMBEDDED_FWIMG */ + } + + return rtStatus; +} + +/** +* Function: phy_InitBBRFRegisterDefinition +* +* OverView: Initialize Register definition offset for Radio Path A/B/C/D +* +* Input: +* PADAPTER Adapter, +* +* Output: None +* Return: None +* Note: The initialization value is constant and it should never be changes +*/ +static VOID +phy_InitBBRFRegisterDefinition( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + /* RF Interface Sowrtware Control */ + pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */ + pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ + + /* RF Interface Output (and Enable) */ + pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */ + pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */ + + /* RF Interface (Output and) Enable */ + pHalData->PHYRegDef[ODM_RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ + pHalData->PHYRegDef[ODM_RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ + + pHalData->PHYRegDef[ODM_RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /*LSSI Parameter */ + pHalData->PHYRegDef[ODM_RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; + + pHalData->PHYRegDef[ODM_RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /*wire control parameter2 */ + pHalData->PHYRegDef[ODM_RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /*wire control parameter2 */ + + /* Tranceiver Readback LSSI/HSPI mode */ + pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; + pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; + pHalData->PHYRegDef[ODM_RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; + pHalData->PHYRegDef[ODM_RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; + +} + +#if 0 /* (MP_DRIVER == 1) */ + +/*----------------------------------------------------------------------------- + * Function: phy_ConfigBBWithMpHeaderFile + * + * Overview: Config PHY_REG_MP array + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 02/04/2010 chiyokolin Modify to new files. + *---------------------------------------------------------------------------*/ +static int +phy_ConfigBBWithMpHeaderFile( + IN PADAPTER Adapter, + IN u1Byte ConfigType) +{ + int i; + u32 *Rtl8192CPHY_REGArray_Table_MP; + u16 PHY_REGArrayMPLen; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + + PHY_REGArrayMPLen = Rtl8188F_PHY_REG_Array_MPLength; + Rtl8192CPHY_REGArray_Table_MP = (u32 *)Rtl8188F_PHY_REG_Array_MP; + + if (ConfigType == BaseBand_Config_PHY_REG) { + for (i = 0; i < PHY_REGArrayMPLen; i = i + 2) { + if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xfe) { +#ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(50); +#else + rtw_mdelay_os(50); +#endif + } else if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xfd) + rtw_mdelay_os(5); + else if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xfc) + rtw_mdelay_os(1); + else if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xfb) { +#ifdef CONFIG_LONG_DELAY_ISSUE + rtw_msleep_os(50); +#else + rtw_mdelay_os(50); +#endif + } else if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xfa) + rtw_mdelay_os(5); + else if (Rtl8192CPHY_REGArray_Table_MP[i] == 0xf9) + rtw_mdelay_os(1); + PHY_SetBBReg(Adapter, Rtl8192CPHY_REGArray_Table_MP[i], bMaskDWord, Rtl8192CPHY_REGArray_Table_MP[i + 1]); + + /* Add 1us delay between BB/RF register setting. */ + rtw_mdelay_os(1); + + /*RT_TRACE(COMP_INIT, DBG_TRACE, ("The Rtl8192CPHY_REGArray_Table_MP[%d] is %lx Rtl8192CPHY_REGArray_Table_MP[%d] is %lx\n", i, i+1, Rtl8192CPHY_REGArray_Table_MP[i], Rtl8192CPHY_REGArray_Table_MP[i+1])); */ + } + } else { + /*RT_TRACE(COMP_SEND, DBG_LOUD, ("phy_ConfigBBWithMpHeaderFile(): ConfigType != BaseBand_Config_PHY_REG\n")); */ + } + + return _SUCCESS; +} /* phy_ConfigBBWithMpHeaderFile */ + +#endif /* #if (MP_DRIVER == 1) */ + + +static int +phy_BB8188f_Config_ParaFile( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rtStatus = _SUCCESS; + u8 sz8188FBRegFile[] = RTL8188F_PHY_REG; + u8 sz8188AGCTableFile[] = RTL8188F_AGC_TAB; + u8 sz8188FBRegMpFile[] = RTL8188F_PHY_REG_MP; + u8 *pszBBRegFile = NULL, *pszAGCTableFile = NULL, *pszBBRegMpFile = NULL; + + pszBBRegFile = sz8188FBRegFile; + pszAGCTableFile = sz8188AGCTableFile; + pszBBRegMpFile = sz8188FBRegMpFile; + + /* */ + /* 1. Read PHY_REG.TXT BB INIT!! */ + /* */ +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (phy_ConfigBBWithParaFile(Adapter, pszBBRegFile, CONFIG_BB_PHY_REG) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG)) + rtStatus = _FAIL; +#endif + } + + if (rtStatus != _SUCCESS) { + DBG_8192C("%s():Write BB Reg Fail!!", __func__); + goto phy_BB8190_Config_ParaFile_Fail; + } + +#if MP_DRIVER == 1 + if (Adapter->registrypriv.mp_mode == 1) { + /* */ + /* 1.1 Read PHY_REG_MP.TXT BB INIT!! */ + /* */ +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (phy_ConfigBBWithMpParaFile(Adapter, pszBBRegMpFile) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_MP)) + rtStatus = _FAIL; +#endif + } + + if (rtStatus != _SUCCESS) { + DBG_8192C("%s():Write BB Reg MP Fail!!", __func__); + goto phy_BB8190_Config_ParaFile_Fail; + } + } +#endif /* #if (MP_DRIVER == 1) */ + + /* */ + /* 2. Read BB AGC table Initialization */ + /* */ +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (phy_ConfigBBWithParaFile(Adapter, pszAGCTableFile, CONFIG_BB_AGC_TAB) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_SUCCESS != ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB)) + rtStatus = _FAIL; +#endif + } + + if (rtStatus != _SUCCESS) { + DBG_8192C("%s():AGC Table Fail\n", __func__); + goto phy_BB8190_Config_ParaFile_Fail; + } + +phy_BB8190_Config_ParaFile_Fail: + + return rtStatus; +} + + +int +PHY_BBConfig8188F( + IN PADAPTER Adapter +) +{ + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u32 RegVal; + u8 TmpU1B = 0; + u8 value8; + + phy_InitBBRFRegisterDefinition(Adapter); + + /* Enable BB and RF */ + RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN); + rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT13 | BIT0 | BIT1)); + +#if 0 /* TODO: [BB]. reg 948 is only use for bt_coex */ +#ifdef CONFIG_USB_HCI + rtw_write32(Adapter, 0x948, 0x0); /* USB use Antenna S0 */ +#else + if (pHalData->ant_path == ODM_RF_PATH_A) + rtw_write32(Adapter, 0x948, 0x280); + else + rtw_write32(Adapter, 0x948, 0x0); +#endif + +#endif + rtw_write8(Adapter, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + + rtw_usleep_os(10); + + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1, 0xfffff, 0x780); + +#if 0 + /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */ + rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x83); + rtw_write8(Adapter, REG_AFE_PLL_CTRL + 1, 0xdb); +#endif + + /* rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_PPLL|FEN_PCIEA|FEN_DIO_PCIE|FEN_BB_GLB_RSTn|FEN_BBRSTB); */ + rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn | FEN_BBRSTB); + + /* Config BB and AGC */ + rtStatus = phy_BB8188f_Config_ParaFile(Adapter); + + hal_set_crystal_cap(Adapter, pHalData->CrystalCap); + + return rtStatus; +} + +void phy_LCK_8188F( + IN PADAPTER Adapter +) +{ + PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFBE0); + PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, 0x8C01); + rtw_mdelay_os(200); + PHY_SetRFReg(Adapter, RF_PATH_A, 0xB0, bRFRegOffsetMask, 0xDFFE0); +} + +#if 0 +/* Block & Path enable */ +#define rOFDMCCKEN_Jaguar 0x808 /* OFDM/CCK block enable */ +#define bOFDMEN_Jaguar 0x20000000 +#define bCCKEN_Jaguar 0x10000000 +#define rRxPath_Jaguar 0x808 /* Rx antenna */ +#define bRxPath_Jaguar 0xff +#define rTxPath_Jaguar 0x80c /* Tx antenna */ +#define bTxPath_Jaguar 0x0fffffff +#define rCCK_RX_Jaguar 0xa04 /* for cck rx path selection */ +#define bCCK_RX_Jaguar 0x0c000000 +#define rVhtlen_Use_Lsig_Jaguar 0x8c3 /* Use LSIG for VHT length */ +VOID +PHY_BB8188F_Config_1T( + IN PADAPTER Adapter +) +{ + /* BB OFDM RX Path_A */ + PHY_SetBBReg(Adapter, rRxPath_Jaguar, bRxPath_Jaguar, 0x11); + /* BB OFDM TX Path_A */ + PHY_SetBBReg(Adapter, rTxPath_Jaguar, bMaskLWord, 0x1111); + /* BB CCK R/Rx Path_A */ + PHY_SetBBReg(Adapter, rCCK_RX_Jaguar, bCCK_RX_Jaguar, 0x0); + /* MCS support */ + PHY_SetBBReg(Adapter, 0x8bc, 0xc0000060, 0x4); + /* RF Path_B HSSI OFF */ + PHY_SetBBReg(Adapter, 0xe00, 0xf, 0x4); + /* RF Path_B Power Down */ + PHY_SetBBReg(Adapter, 0xe90, bMaskDWord, 0); + /* ADDA Path_B OFF */ + PHY_SetBBReg(Adapter, 0xe60, bMaskDWord, 0); + PHY_SetBBReg(Adapter, 0xe64, bMaskDWord, 0); +} +#endif + +int +PHY_RFConfig8188F( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rtStatus = _SUCCESS; + + /* */ + /* RF config */ + /* */ + rtStatus = PHY_RF6052_Config8188F(Adapter); + + phy_LCK_8188F(Adapter); + /*PHY_BB8188F_Config_1T(Adapter); */ + + return rtStatus; +} + +/*----------------------------------------------------------------------------- + * Function: PHY_ConfigRFWithParaFile() + * + * Overview: This function read RF parameters from general file format, and do RF 3-wire + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * RF_PATH eRFPath + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + * Note: Delay may be required for RF configuration + *---------------------------------------------------------------------------*/ +int +PHY_ConfigRFWithParaFile_8188F( + IN PADAPTER Adapter, + IN u8 *pFileName, + RF_PATH eRFPath +) +{ + return _SUCCESS; +} + +/***************************************** */ +/*----------------------------------------------------------------------------- + * Function: PHY_ConfigRFWithHeaderFile() + * + * Overview: This function read RF parameters from general file format, and do RF 3-wire + * + * Input: PADAPTER Adapter + * ps1Byte pFileName + * RF_PATH eRFPath + * + * Output: NONE + * + * Return: RT_STATUS_SUCCESS: configuration file exist + * + * Note: Delay may be required for RF configuration + *---------------------------------------------------------------------------*/ +void phy_PowerIndexCheck8188F( + IN PADAPTER Adapter, + IN u8 channel, + IN OUT u8 *cckPowerLevel, + IN OUT u8 *ofdmPowerLevel, + IN OUT u8 *BW20PowerLevel, + IN OUT u8 *BW40PowerLevel +) +{ + + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + pHalData->CurrentCckTxPwrIdx = cckPowerLevel[0]; + pHalData->CurrentOfdm24GTxPwrIdx = ofdmPowerLevel[0]; + pHalData->CurrentBW2024GTxPwrIdx = BW20PowerLevel[0]; + pHalData->CurrentBW4024GTxPwrIdx = BW40PowerLevel[0]; + + RT_TRACE(_module_hal_init_c_, _drv_info_, + ("PHY_SetTxPowerLevel8188F(): CurrentCckTxPwrIdx : 0x%x,CurrentOfdm24GTxPwrIdx: 0x%x\n", + pHalData->CurrentCckTxPwrIdx, pHalData->CurrentOfdm24GTxPwrIdx)); +} + +/************************************************************************************************************** + * Description: + * The low-level interface to set TxAGC , called by both MP and Normal Driver. + * + * <20120830, Kordan> + **************************************************************************************************************/ + +VOID +PHY_SetTxPowerIndex_8188F( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate +) +{ + if (RFPath == ODM_RF_PATH_A || RFPath == ODM_RF_PATH_B) { + switch (Rate) { + case MGN_1M: + PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, PowerIndex); + break; + case MGN_2M: + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte1, PowerIndex); + break; + case MGN_5_5M: + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte2, PowerIndex); + break; + case MGN_11M: + PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte3, PowerIndex); + break; + + case MGN_6M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte0, PowerIndex); + break; + case MGN_9M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte1, PowerIndex); + break; + case MGN_12M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte2, PowerIndex); + break; + case MGN_18M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate18_06, bMaskByte3, PowerIndex); + break; + + case MGN_24M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte0, PowerIndex); + break; + case MGN_36M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte1, PowerIndex); + break; + case MGN_48M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte2, PowerIndex); + break; + case MGN_54M: + PHY_SetBBReg(Adapter, rTxAGC_A_Rate54_24, bMaskByte3, PowerIndex); + break; + + case MGN_MCS0: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte0, PowerIndex); + break; + case MGN_MCS1: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte1, PowerIndex); + break; + case MGN_MCS2: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte2, PowerIndex); + break; + case MGN_MCS3: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs03_Mcs00, bMaskByte3, PowerIndex); + break; + + case MGN_MCS4: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte0, PowerIndex); + break; + case MGN_MCS5: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte1, PowerIndex); + break; + case MGN_MCS6: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte2, PowerIndex); + break; + case MGN_MCS7: + PHY_SetBBReg(Adapter, rTxAGC_A_Mcs07_Mcs04, bMaskByte3, PowerIndex); + break; + + default: + DBG_871X("Invalid Rate!!\n"); + break; + } + } else + RT_TRACE(_module_hal_init_c_, _drv_err_, ("Invalid RFPath!!\n")); +} + +u8 +phy_GetCurrentTxNum_8188F( + IN PADAPTER pAdapter +) +{ + return RF_TX_NUM_NONIMPLEMENT; +} + +u8 +PHY_GetTxPowerIndex_8188F( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter); + s8 txPower = 0, powerDiffByRate = 0, limit = 0; + BOOLEAN bIn24G = _FALSE; + + /*DBG_871X("===>%s\n", __func__ ); */ + + txPower = (s8) PHY_GetTxPowerIndexBase(pAdapter, RFPath, Rate, BandWidth, Channel, &bIn24G); + powerDiffByRate = PHY_GetTxPowerByRate(pAdapter, BAND_ON_2_4G, ODM_RF_PATH_A, RF_1TX, Rate); + + limit = PHY_GetTxPowerLimit(pAdapter, pAdapter->registrypriv.RegPwrTblSel, (u8)(!bIn24G), pHalData->CurrentChannelBW, RFPath, Rate, pHalData->CurrentChannel); + + powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate; + txPower += powerDiffByRate; + + txPower += PHY_GetTxPowerTrackingOffset(pAdapter, RFPath, Rate); + + if (txPower > MAX_POWER_INDEX) + txPower = MAX_POWER_INDEX; + + /*DBG_871X("Final Tx Power(RF-%c, Channel: %d) = %d(0x%X)\n", ((RFPath==0)?'A':'B'), Channel, txPower, txPower)); */ + return (u8) txPower; +} + +VOID +PHY_SetTxPowerLevel8188F( + IN PADAPTER Adapter, + IN u8 Channel +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + pFAT_T pDM_FatTable = &pDM_Odm->DM_FatTable; + u8 RFPath = ODM_RF_PATH_A; + + if (pHalData->AntDivCfg) /* antenna diversity Enable */ + RFPath = ((pDM_FatTable->RxIdleAnt == MAIN_ANT) ? ODM_RF_PATH_A : ODM_RF_PATH_B); + else /* antenna diversity disable */ + RFPath = pHalData->ant_path; + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("==>PHY_SetTxPowerLevel8188F()\n")); + + PHY_SetTxPowerLevelByPath(Adapter, Channel, RFPath); + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("<==PHY_SetTxPowerLevel8188F()\n")); +} + +VOID +PHY_GetTxPowerLevel8188F( + IN PADAPTER Adapter, + OUT s32 *powerlevel +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + s32 TxPwrDbm = 13; +#if 0 + RT_TRACE(COMP_TXAGC, DBG_LOUD, ("PHY_GetTxPowerLevel8188F(): TxPowerLevel: %#x\n", TxPwrDbm)); + + if (pMgntInfo->ClientConfigPwrInDbm != UNSPECIFIED_PWR_DBM) + *powerlevel = pMgntInfo->ClientConfigPwrInDbm; + else + *powerlevel = TxPwrDbm; +#endif +} + + +/* A workaround to eliminate the 2400MHz, 2440MHz, 2480MHz spur of 8188F. (Asked by David.) */ +VOID +phy_SpurCalibration_8188F( + IN PADAPTER pAdapter, + IN u1Byte ToChannel, + IN u1Byte threshold +) +{ + u4Byte freq[6] = {0xFCCD, 0xFC4D, 0xFFCD, 0xFF4D, 0xFCCD, 0xFF9A}; /* {chnl 5, 6, 7, 8, 13, 14} */ + u1Byte idx = 0; + u1Byte b_doNotch = FALSE; + u1Byte initial_gain; + BOOLEAN bHW_Ctrl = FALSE, bSW_Ctrl = FALSE, bHW_Ctrl_S1 = FALSE, bSW_Ctrl_S1 = FALSE; + u4Byte reg948; + + /* add for notch */ + u4Byte wlan_channel, CurrentChannel, Is40MHz; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + PDM_ODM_T pDM_Odm = &(pHalData->odmpriv); + + /* check threshold */ + if (threshold <= 0x0) + threshold = 0x16; + + /* DBG_8192C("===> phy_SpurCalibration_8188F: Channel = %d\n", ToChannel); */ + + if (ToChannel == 5) + idx = 0; + else if (ToChannel == 6) + idx = 1; + else if (ToChannel == 7) + idx = 2; + else if (ToChannel == 8) + idx = 3; + else if (ToChannel == 13) + idx = 4; + else if (ToChannel == 14) + idx = 5; + else + idx = 10; + + reg948 = PHY_QueryBBReg(pAdapter, rS0S1_PathSwitch, bMaskDWord); + if ((reg948 & BIT6) == 0x0) + bSW_Ctrl = TRUE; + else + bHW_Ctrl = TRUE; + + if (bHW_Ctrl) + bHW_Ctrl_S1 = (PHY_QueryBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT5 | BIT4 | BIT3) == 0x1) ? TRUE : FALSE; + else if (bSW_Ctrl) + bSW_Ctrl_S1 = ((reg948 & BIT9) == 0x0) ? TRUE : FALSE; + + /* If wlan at S1 (both HW control & SW control) and current channel=5,6,7,8,13,14 */ + if ((bHW_Ctrl_S1 || bSW_Ctrl_S1) && (idx <= 5)) { + initial_gain = (u1Byte)(ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskByte0) & 0x7f); + ODM_Write_DIG(pDM_Odm, 0x30); + PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, bMaskDWord, 0xccf000c0); /* disable 3-wire */ + + PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, freq[idx]); /* Setup PSD */ + PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, 0x400000 | freq[idx]); /* Start PSD */ + + rtw_msleep_os(30); + + if (PHY_QueryBBReg(pAdapter, rFPGA0_PSDReport, bMaskDWord) >= threshold) + b_doNotch = TRUE; + + PHY_SetBBReg(pAdapter, rFPGA0_PSDFunction, bMaskDWord, freq[idx]); /* turn off PSD */ + PHY_SetBBReg(pAdapter, rFPGA0_AnalogParameter4, bMaskDWord, 0xccc000c0); /* enable 3-wire */ + ODM_Write_DIG(pDM_Odm, initial_gain); + } + + /* --- Notch Filter --- Asked by Rock */ + if (b_doNotch) { + CurrentChannel = ODM_GetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask); + wlan_channel = CurrentChannel & 0x0f; /*Get center frequency */ + + switch (wlan_channel) { /*Set notch filter */ + case 5: + case 13: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT28 | BIT27 | BIT26 | BIT25 | BIT24, 0xB); + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1); /*enable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x06000000); + ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1); /*enable CSI mask */ + break; + case 6: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT28 | BIT27 | BIT26 | BIT25 | BIT24, 0x4); + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1); /*enable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000600); + ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1); /*enable CSI mask */ + break; + case 7: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT28 | BIT27 | BIT26 | BIT25 | BIT24, 0x3); + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1); /*enable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x06000000); + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1); /*enable CSI mask */ + break; + case 8: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT28 | BIT27 | BIT26 | BIT25 | BIT24, 0xA); + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1); /*enable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00000380); + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1); /*enable CSI mask */ + break; + case 14: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT28 | BIT27 | BIT26 | BIT25 | BIT24, 0x5); + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x1); /*enable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD40, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD44, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD48, bMaskDWord, 0x00000000); + ODM_SetBBReg(pDM_Odm, 0xD4C, bMaskDWord, 0x00180000); + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x1); /*enable CSI mask */ + break; + default: + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x0); /*disable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x0); /*disable CSI mask function */ + break; + } /*switch(wlan_channel) */ + return; + } + + ODM_SetBBReg(pDM_Odm, 0xC40, BIT9, 0x0); /*disable notch filter */ + ODM_SetBBReg(pDM_Odm, 0xD2C, BIT28, 0x0); /*disable CSI mask */ + +} + +VOID +phy_SetRegBW_8188F( + IN PADAPTER Adapter, + CHANNEL_WIDTH CurrentBW +) +{ + u16 RegRfMod_BW, u2tmp = 0; + RegRfMod_BW = rtw_read16(Adapter, REG_TRXPTCL_CTL_8188F); + + switch (CurrentBW) { + case CHANNEL_WIDTH_20: + rtw_write16(Adapter, REG_TRXPTCL_CTL_8188F, (RegRfMod_BW & 0xFE7F)); /* BIT 7 = 0, BIT 8 = 0 */ + break; + + case CHANNEL_WIDTH_40: + u2tmp = RegRfMod_BW | BIT7; + rtw_write16(Adapter, REG_TRXPTCL_CTL_8188F, (u2tmp & 0xFEFF)); /* BIT 7 = 1, BIT 8 = 0 */ + break; + + case CHANNEL_WIDTH_80: + u2tmp = RegRfMod_BW | BIT8; + rtw_write16(Adapter, REG_TRXPTCL_CTL_8188F, (u2tmp & 0xFF7F)); /* BIT 7 = 0, BIT 8 = 1 */ + break; + + default: + DBG_871X("phy_PostSetBWMode8188F(): unknown Bandwidth: %#X\n", CurrentBW); + break; + } +} + +u8 +phy_GetSecondaryChnl_8188F( + IN PADAPTER Adapter +) +{ + u8 SCSettingOf40 = 0, SCSettingOf20 = 0; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d\n", pHalData->CurrentChannelBW, + pHalData->nCur80MhzPrimeSC, pHalData->nCur40MhzPrimeSC)); + if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_80) { + if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) + SCSettingOf40 = VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) + SCSettingOf40 = VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n")); + + if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)) + SCSettingOf20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)) + SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)) + SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)) + SCSettingOf20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n")); + } else if (pHalData->CurrentChannelBW == CHANNEL_WIDTH_40) { + RT_TRACE(_module_hal_init_c_, _drv_info_, ("SCMapping: VHT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d\n", pHalData->CurrentChannelBW, pHalData->nCur40MhzPrimeSC)); + + if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) + SCSettingOf20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) + SCSettingOf20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else + RT_TRACE(_module_hal_init_c_, _drv_err_, ("SCMapping: Not Correct Primary40MHz Setting\n")); + } + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("SCMapping: SC Value %x\n", ((SCSettingOf40 << 4) | SCSettingOf20))); + return ((SCSettingOf40 << 4) | SCSettingOf20); +} + +VOID +phy_PostSetBwMode8188F( + IN PADAPTER Adapter +) +{ + u1Byte SubChnlNum = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + /* DBG_8192C("===>%s: CurrentChannelBW = %s Mhz\n", __func__, pHalData->CurrentChannelBW?"40":"20"); */ + + switch (pHalData->CurrentChannelBW) { + case CHANNEL_WIDTH_20: + /* + 0x800[0]=1'b0 + 0x900[0]=1'b0 + 0x800[10:8]=3'b111(80M) + 0x800[14:12]=3'b101(80M) + 0xCE4[31:30]=2'b00 + 0xCE4[29:28]=2'b01 + 0xc10[29:28]=1 + 0x954[19]=1'b0 + 0x954[23:20]=3 + */ + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT0, 0x0); + PHY_SetBBReg(Adapter, rFPGA1_RFMOD, BIT0, 0x0); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT10 | BIT9 | BIT8, 0x7); /* RXADC CLK */ + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT14 | BIT13 | BIT12, 0x5); /* TXDAC CLK */ + PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, BIT31 | BIT30, 0x0); /* small BW */ + PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, BIT29 | BIT28, 0x1); /* adc buffer clk(TBD) */ + PHY_SetBBReg(Adapter, rOFDM0_XARxAFE, BIT29 | BIT28, 0x1); /* adc buffer clk(TBD) */ + PHY_SetBBReg(Adapter, BBrx_DFIR, BIT19, 0x0); /* OFDM RX DFIR */ + PHY_SetBBReg(Adapter, BBrx_DFIR, BIT23 | BIT22 | BIT21 | BIT20, 0x3); /* OFDM RX DFIR */ + break; + + case CHANNEL_WIDTH_40: + /* + 0x800[0]=1'b1 + 0x900[0]=1'b1 + 0x800[10:8]=3'b111(80M) + 0x800[14:12]=3'b101(80M) + 0xCE4[31:30]=2'b00 + 0xCE4[29:28]=2'b01 + 0xc10[29:28]: 1 + 0x954[19]=1'b0 + 0x954[23:20]=0x6(For ACPR) + + 0xa00[4]=1/0 + + 0x483[3:0]=1/2 + 0x440[22:21]=2'b00 + + 0xc84[31:28]=0x2 (SDIO) + 0xc84[31:28]=0x7 (USB) + */ + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT0, 0x1); + PHY_SetBBReg(Adapter, rFPGA1_RFMOD, BIT0, 0x1); + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT10 | BIT9 | BIT8, 0x7); /* RXADC CLK */ + PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT14 | BIT13 | BIT12, 0x5); /* TXDAC CLK */ + PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, BIT31 | BIT30, 0x0); /* small BW */ + PHY_SetBBReg(Adapter, rOFDM0_TxPseudoNoiseWgt, BIT29 | BIT28, 0x1); /* adc buffer clk(TBD) */ + PHY_SetBBReg(Adapter, rOFDM0_XARxAFE, BIT29 | BIT28, 0x1); /* adc buffer clk(TBD) */ + PHY_SetBBReg(Adapter, BBrx_DFIR, BIT19, 0x0); /* OFDM RX DFIR */ + PHY_SetBBReg(Adapter, BBrx_DFIR, BIT23 | BIT22 | BIT21 | BIT20, 0x6); /* OFDM RX DFIR */ + + PHY_SetBBReg(Adapter, rCCK0_System, BIT4, (pHalData->nCur40MhzPrimeSC >> 1)); /* primary channel (CCK RXSC) */ + + SubChnlNum = phy_GetSecondaryChnl_8188F(Adapter); + PHY_SetMacReg(Adapter, REG_DATA_SC_8188F, BIT3 | BIT2 | BIT1 | BIT0, SubChnlNum); /* txsc_20 */ + PHY_SetMacReg(Adapter, REG_RRSR_8188F, BIT22 | BIT21, 0x0); /* RRSR_RSC */ + +#ifdef CONFIG_SDIO_HCI + PHY_SetBBReg(Adapter, rOFDM0_XATxAFE, BIT31 | BIT30 | BIT29 | BIT28, 0x2); /* PDTH_BW40/ACPR */ +#endif /* CONFIG_SDIO_HCI */ +#ifdef CONFIG_USB_HCI + PHY_SetBBReg(Adapter, rOFDM0_XATxAFE, BIT31 | BIT30 | BIT29 | BIT28, 0x7); /* PDTH_BW40/ACPR */ +#endif /* CONFIG_USB_HCI */ + + if (0) + DBG_871X("%s: REG_DATA_SC_8188F(%d) nCur40MhzPrimeSC(%d)\n", __func__, SubChnlNum, pHalData->nCur40MhzPrimeSC); + break; + + default: + RT_TRACE(COMP_DBG, DBG_LOUD, ("phy_SetBWMode8188F(): unknown Bandwidth: %#X\n"\ + , pHalData->CurrentChannelBW)); + break; + } + + /*3<3>Set RF related register */ + PHY_RF6052SetBandwidth8188F(Adapter, pHalData->CurrentChannelBW); +} + +VOID +phy_SwChnl8188F( + IN PADAPTER pAdapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); + u8 channelToSW = pHalData->CurrentChannel; +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + PDM_ODM_T pDM_Odm = &pHalData->DM_OutSrc; +#else /* (DM_ODM_SUPPORT_TYPE == ODM_CE) */ + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; +#endif + + if (pHalData->rf_chip == RF_PSEUDO_11N) { + /*RT_TRACE(COMP_MLME,DBG_LOUD,("phy_SwChnl8188F: return for PSEUDO\n")); */ + return; + } + + pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff00) | channelToSW); + PHY_SetRFReg(pAdapter, ODM_RF_PATH_A, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0]); + /* PHY_SetRFReg(pAdapter, ODM_RF_PATH_B, RF_CHNLBW, 0x3FF, pHalData->RfRegChnlVal[0] ); */ + + /* DBG_8192C("===>phy_SwChnl8188F: Channel = %d\n", channelToSW); */ + + phy_SpurCalibration_8188F(pAdapter, channelToSW, 0x16); +} + +VOID +phy_SwChnlAndSetBwMode8188F( + IN PADAPTER Adapter +) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + /*RT_TRACE(COMP_SCAN, DBG_LOUD, ("phy_SwChnlAndSetBwMode8188F(): bSwChnl %d, bSetChnlBW %d\n", pHalData->bSwChnl, pHalData->bSetChnlBW)); */ + if (Adapter->bNotifyChannelChange) { + DBG_871X("[%s] bSwChnl=%d, ch=%d, bSetChnlBW=%d, bw=%d\n", + __func__, + pHalData->bSwChnl, + pHalData->CurrentChannel, + pHalData->bSetChnlBW, + pHalData->CurrentChannelBW); + } + + if (RTW_CANNOT_RUN(Adapter)) + return; + + if (pHalData->bSwChnl) { + phy_SwChnl8188F(Adapter); + pHalData->bSwChnl = _FALSE; + } + + if (pHalData->bSetChnlBW) { + phy_PostSetBwMode8188F(Adapter); + pHalData->bSetChnlBW = _FALSE; + } + + PHY_SetTxPowerLevel8188F(Adapter, pHalData->CurrentChannel); +} + +VOID +PHY_HandleSwChnlAndSetBW8188F( + IN PADAPTER Adapter, + IN BOOLEAN bSwitchChannel, + IN BOOLEAN bSetBandWidth, + IN u8 ChannelNum, + IN CHANNEL_WIDTH ChnlWidth, + IN EXTCHNL_OFFSET ExtChnlOffsetOf40MHz, + IN EXTCHNL_OFFSET ExtChnlOffsetOf80MHz, + IN u8 CenterFrequencyIndex1 +) +{ + /*static BOOLEAN bInitialzed = _FALSE; */ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + u8 tmpChannel = pHalData->CurrentChannel; + CHANNEL_WIDTH tmpBW = pHalData->CurrentChannelBW; + u8 tmpnCur40MhzPrimeSC = pHalData->nCur40MhzPrimeSC; + u8 tmpnCur80MhzPrimeSC = pHalData->nCur80MhzPrimeSC; + u8 tmpCenterFrequencyIndex1 = pHalData->CurrentCenterFrequencyIndex1; + struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; + + /* DBG_871X("=> PHY_HandleSwChnlAndSetBW8188F: bSwitchChannel %d, bSetBandWidth %d\n", bSwitchChannel, bSetBandWidth); */ + /* DBG_871X("=> %s: ChnlWidth %d\n", __func__, ChnlWidth); */ + + /*check is swchnl or setbw */ + if (!bSwitchChannel && !bSetBandWidth) { + DBG_871X("PHY_HandleSwChnlAndSetBW8188F: not switch channel and not set bandwidth\n"); + return; + } + + /*skip change for channel or bandwidth is the same */ + if (bSwitchChannel) { + /*if(pHalData->CurrentChannel != ChannelNum) */ + { + if (HAL_IsLegalChannel(Adapter, ChannelNum)) + pHalData->bSwChnl = _TRUE; + } + } + + if (bSetBandWidth) { +#if 0 + if (bInitialzed == _FALSE) { + bInitialzed = _TRUE; + pHalData->bSetChnlBW = _TRUE; + } else if ((pHalData->CurrentChannelBW != ChnlWidth) || (pHalData->nCur40MhzPrimeSC != ExtChnlOffsetOf40MHz) || (pHalData->CurrentCenterFrequencyIndex1 != CenterFrequencyIndex1)) + pHalData->bSetChnlBW = _TRUE; +#else + pHalData->bSetChnlBW = _TRUE; +#endif + } + + if (!pHalData->bSetChnlBW && !pHalData->bSwChnl) { + /* DBG_871X("<= PHY_HandleSwChnlAndSetBW8188F: bSwChnl %d, bSetChnlBW %d\n", pHalData->bSwChnl, pHalData->bSetChnlBW); */ + return; + } + + + if (pHalData->bSwChnl) { + pHalData->CurrentChannel = ChannelNum; + pHalData->CurrentCenterFrequencyIndex1 = ChannelNum; + } + + + if (pHalData->bSetChnlBW) { + pHalData->CurrentChannelBW = ChnlWidth; +#if 0 + if (ExtChnlOffsetOf40MHz == EXTCHNL_OFFSET_LOWER) + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; + else if (ExtChnlOffsetOf40MHz == EXTCHNL_OFFSET_UPPER) + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; + else + pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (ExtChnlOffsetOf80MHz == EXTCHNL_OFFSET_LOWER) + pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; + else if (ExtChnlOffsetOf80MHz == EXTCHNL_OFFSET_UPPER) + pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; + else + pHalData->nCur80MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; +#else + pHalData->nCur40MhzPrimeSC = ExtChnlOffsetOf40MHz; + pHalData->nCur80MhzPrimeSC = ExtChnlOffsetOf80MHz; +#endif + + pHalData->CurrentCenterFrequencyIndex1 = CenterFrequencyIndex1; + } + + /*Switch workitem or set timer to do switch channel or setbandwidth operation */ + if (!RTW_CANNOT_RUN(Adapter)) + phy_SwChnlAndSetBwMode8188F(Adapter); + else { + if (pHalData->bSwChnl) { + pHalData->CurrentChannel = tmpChannel; + pHalData->CurrentCenterFrequencyIndex1 = tmpChannel; + } + if (pHalData->bSetChnlBW) { + pHalData->CurrentChannelBW = tmpBW; + pHalData->nCur40MhzPrimeSC = tmpnCur40MhzPrimeSC; + pHalData->nCur80MhzPrimeSC = tmpnCur80MhzPrimeSC; + pHalData->CurrentCenterFrequencyIndex1 = tmpCenterFrequencyIndex1; + } + } + + /*DBG_871X("Channel %d ChannelBW %d ",pHalData->CurrentChannel, pHalData->CurrentChannelBW); */ + /*DBG_871X("40MhzPrimeSC %d 80MhzPrimeSC %d ",pHalData->nCur40MhzPrimeSC, pHalData->nCur80MhzPrimeSC); */ + /*DBG_871X("CenterFrequencyIndex1 %d\n",pHalData->CurrentCenterFrequencyIndex1); */ + + /*DBG_871X("<= PHY_HandleSwChnlAndSetBW8188F: bSwChnl %d, bSetChnlBW %d\n",pHalData->bSwChnl,pHalData->bSetChnlBW); */ + +} + +VOID +PHY_SetBWMode8188F( + IN PADAPTER Adapter, + /* 20M or 40M */ + IN CHANNEL_WIDTH Bandwidth, + /* Upper, Lower, or Don't care */ + IN u8 Offset +) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + + PHY_HandleSwChnlAndSetBW8188F(Adapter, _FALSE, _TRUE, pHalData->CurrentChannel, Bandwidth, Offset, Offset, pHalData->CurrentChannel); +} + +VOID +PHY_SwChnl8188F( + /* Call after initialization */ + IN PADAPTER Adapter, + IN u8 channel +) +{ + PHY_HandleSwChnlAndSetBW8188F(Adapter, _TRUE, _FALSE, channel, 0, 0, 0, channel); +} + +VOID +PHY_SetSwChnlBWMode8188F( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +) +{ + /*DBG_871X("%s()===>\n",__func__); */ + + PHY_HandleSwChnlAndSetBW8188F(Adapter, _TRUE, _TRUE, channel, Bandwidth, Offset40, Offset80, channel); + + /*DBG_871X("<==%s()\n",__func__); */ +} + +static VOID +_PHY_DumpRFReg_8188F(IN PADAPTER pAdapter) +{ + u32 rfRegValue, rfRegOffset; + + RT_TRACE(_module_hal_init_c_, _drv_info_, ("_PHY_DumpRFReg_8188F()====>\n")); + + for (rfRegOffset = 0x00; rfRegOffset <= 0x30; rfRegOffset++) { + rfRegValue = PHY_QueryRFReg_8188F(pAdapter, RF_PATH_A, rfRegOffset, bMaskDWord); + RT_TRACE(_module_hal_init_c_, _drv_info_, (" 0x%02x = 0x%08x\n", rfRegOffset, rfRegValue)); + } + RT_TRACE(_module_hal_init_c_, _drv_info_, ("<===== _PHY_DumpRFReg_8188F()\n")); +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rf6052.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rf6052.c new file mode 100644 index 00000000..940b3199 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rf6052.c @@ -0,0 +1,297 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/****************************************************************************** + * + * + * Module: rtl8192c_rf6052.c ( Source C File) + * + * Note: Provide RF 6052 series relative API. + * + * Function: + * + * Export: + * + * Abbrev: + * + * History: + * Data Who Remark + * + * 09/25/2008 MHC Create initial version. + * 11/05/2008 MHC Add API for tw power setting. + * + * +******************************************************************************/ + +#include + +/*---------------------------Define Local Constant---------------------------*/ +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ +/*------------------------Define global variable-----------------------------*/ + + +/*------------------------Define local variable------------------------------*/ +/* 2008/11/20 MH For Debug only, RF */ +/*static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG] = {0}; */ +static RF_SHADOW_T RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG]; +/*------------------------Define local variable------------------------------*/ + +/*----------------------------------------------------------------------------- + * Function: PHY_RF6052SetBandwidth() + * + * Overview: This function is called by SetBWModeCallback8190Pci() only + * + * Input: PADAPTER Adapter + * WIRELESS_BANDWIDTH_E Bandwidth 20M or 40M + * + * Output: NONE + * + * Return: NONE + * + * Note: For RF type 0222D + *---------------------------------------------------------------------------*/ +VOID +PHY_RF6052SetBandwidth8188F( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth) /*20M or 40M */ +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + switch (Bandwidth) { + case CHANNEL_WIDTH_20: + /* + RF_A_reg 0x18[11:10]=2'b11 + RF_A_reg 0x87=0x00065 + RF_A_reg 0x1c=0x00000 + RF_A_reg 0x52=0xFAC2C (for USB) + RF_A_reg 0xDF=0x00140 + RF_A_reg 0x1b=0x00c6c + */ + pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT10 | BIT11); + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x18, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); /* RF TRX_BW */ + + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x87, bRFRegOffsetMask, 0x00065); /* FILTER BW&RC Corner (ACPR) */ + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1C, bRFRegOffsetMask, 0x00000); /* FILTER BW&RC Corner (ACPR) */ +#ifdef CONFIG_USB_HCI + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x52, bRFRegOffsetMask, 0xFAC2C); /* FILTER BW&RC Corner (ACPR) */ +#endif /* CONFIG_USB_HCI */ + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0xDF, bRFRegOffsetMask, 0x00140); /* FILTER BW&RC Corner (ACPR) */ + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1B, bRFRegOffsetMask, 0x00C6C); /* FILTER BW&RC Corner (ACPR) */ + break; + + case CHANNEL_WIDTH_40: + /* + RF_A_reg 0x18[11:10]=2'b01 + RF_A_reg 0x87=0x00025 + RF_A_reg 0x1c=0x00800 (for SDIO) + RF_A_reg 0x1c=0x01000 (for USB) + RF_A_reg 0x52=0xFAC2C (for USB) + RF_A_reg 0xDF=0x00140 + RF_A_reg 0x1b=0x00c6c + */ + pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | BIT10); + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x18, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); /* RF TRX_BW */ + + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x87, bRFRegOffsetMask, 0x00025); /* FILTER BW&RC Corner (ACPR) */ +#ifdef CONFIG_SDIO_HCI + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1C, bRFRegOffsetMask, 0x00800); /* FILTER BW&RC Corner (ACPR) */ +#endif /* CONFIG_SDIO_HCI */ +#ifdef CONFIG_USB_HCI + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1C, bRFRegOffsetMask, 0x01000); /* FILTER BW&RC Corner (ACPR) */ + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x52, bRFRegOffsetMask, 0xFAC2C); /* FILTER BW&RC Corner (ACPR) */ +#endif + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0xDF, bRFRegOffsetMask, 0x00140); /* FILTER BW&RC Corner (ACPR) */ + PHY_SetRFReg(Adapter, ODM_RF_PATH_A, 0x1B, bRFRegOffsetMask, 0x00C6C); /* FILTER BW&RC Corner (ACPR) */ + break; + + default: + /*RT_TRACE(COMP_DBG, DBG_LOUD, ("PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth )); */ + break; + } + +} + +static VOID +phy_RF6052_Config_HardCode( + IN PADAPTER Adapter +) +{ + + /* Set Default Bandwidth to 20M */ + /*Adapter->HalFunc .SetBWModeHandler(Adapter, CHANNEL_WIDTH_20); */ + + /* TODO: Set Default Channel to channel one for RTL8225 */ + +} + +static int +phy_RF6052_Config_ParaFile( + IN PADAPTER Adapter +) +{ + u32 u4RegValue = 0; + u8 eRFPath; + BB_REGISTER_DEFINITION_T *pPhyReg; + + int rtStatus = _SUCCESS; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + static char sz8188RadioAFile[] = RTL8188F_PHY_RADIO_A; + static char sz8188RadioBFile[] = RTL8188F_PHY_RADIO_B; + static s1Byte sz8188FTxPwrTrackFile[] = RTL8188F_TXPWR_TRACK; + char *pszRadioAFile, *pszRadioBFile, *pszTxPwrTrackFile; + + pszRadioAFile = sz8188RadioAFile; + pszRadioBFile = sz8188RadioBFile; + pszTxPwrTrackFile = sz8188FTxPwrTrackFile; + + /*3//----------------------------------------------------------------- */ + /*3// <2> Initialize RF */ + /*3//----------------------------------------------------------------- */ + /*for(eRFPath = RF_PATH_A; eRFPath NumTotalRFPath; eRFPath++) */ + for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { + + pPhyReg = &pHalData->PHYRegDef[eRFPath]; + + /*----Store original RFENV control type----*/ + switch (eRFPath) { + case RF_PATH_A: + case RF_PATH_C: + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); + break; + case RF_PATH_B : + case RF_PATH_D: + u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16); + break; + } + + /*----Set RF_ENV enable----*/ + PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1); + rtw_udelay_os(1);/*PlatformStallExecution(1); */ + + /*----Set RF_ENV output high----*/ + PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); + rtw_udelay_os(1);/*PlatformStallExecution(1); */ + + /* Set bit number of Address and Data for RF register */ + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ + rtw_udelay_os(1);/*PlatformStallExecution(1); */ + + PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ + rtw_udelay_os(1);/*PlatformStallExecution(1); */ + + /*----Initialize RF fom connfiguration file----*/ + switch (eRFPath) { + case RF_PATH_A: +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (PHY_ConfigRFWithParaFile(Adapter, pszRadioAFile, eRFPath) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, CONFIG_RF_RADIO, (ODM_RF_RADIO_PATH_E)eRFPath)) + rtStatus = _FAIL; +#endif + } + break; + case RF_PATH_B: +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (PHY_ConfigRFWithParaFile(Adapter, pszRadioBFile, eRFPath) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, CONFIG_RF_RADIO, (ODM_RF_RADIO_PATH_E)eRFPath)) + rtStatus = _FAIL; +#endif + } + break; + case RF_PATH_C: + break; + case RF_PATH_D: + break; + } + + /*----Restore RFENV control type----*/; + switch (eRFPath) { + case RF_PATH_A: + case RF_PATH_C: + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); + break; + case RF_PATH_B : + case RF_PATH_D: + PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV << 16, u4RegValue); + break; + } + + if (rtStatus != _SUCCESS) { + /*RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath)); */ + goto phy_RF6052_Config_ParaFile_Fail; + } + + } + + /*3 ----------------------------------------------------------------- */ + /*3 Configuration of Tx Power Tracking */ + /*3 ----------------------------------------------------------------- */ + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + if (PHY_ConfigRFWithTxPwrTrackParaFile(Adapter, pszTxPwrTrackFile) == _FAIL) +#endif + { +#ifdef CONFIG_EMBEDDED_FWIMG + ODM_ConfigRFWithTxPwrTrackHeaderFile(&pHalData->odmpriv); +#endif + } + + /*RT_TRACE(COMP_INIT, DBG_LOUD, ("<---phy_RF6052_Config_ParaFile()\n")); */ + return rtStatus; + +phy_RF6052_Config_ParaFile_Fail: + return rtStatus; +} + + +int +PHY_RF6052_Config8188F( + IN PADAPTER Adapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + int rtStatus = _SUCCESS; + + /* */ + /* Initialize general global value */ + /* */ + /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */ + if (pHalData->rf_type == RF_1T1R) + pHalData->NumTotalRFPath = 1; + else + pHalData->NumTotalRFPath = 2; + + /* */ + /* Config BB and RF */ + /* */ + rtStatus = phy_RF6052_Config_ParaFile(Adapter); + return rtStatus; + +} + +/* End of HalRf6052.c */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rxdesc.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rxdesc.c new file mode 100644 index 00000000..de910607 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_rxdesc.c @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RTL8188F_REDESC_C_ + +#include + +void rtl8188f_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_8188F(pdesc); + pattrib->pkt_rpt_type = GET_RX_STATUS_DESC_RPT_SEL_8188F(pdesc) ? C2H_PACKET : NORMAL_RX; + + if (pattrib->pkt_rpt_type == NORMAL_RX) { + /* Offset 0 */ + pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8188F(pdesc); + pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8188F(pdesc); + pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8188F(pdesc) << 3; + pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8188F(pdesc); + pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8188F(pdesc); + pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8188F(pdesc); + pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8188F(pdesc); + pattrib->bdecrypted = (u8)GET_RX_STATUS_DESC_SWDEC_8188F(pdesc) ? 0 : 1; + + /* Offset 4 */ + pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8188F(pdesc); + pattrib->amsdu = (u8)GET_RX_STATUS_DESC_AMSDU_8188F(pdesc); + pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8188F(pdesc); + pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8188F(pdesc); + + /* Offset 8 */ + pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8188F(pdesc); + pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8188F(pdesc); + + /* Offset 12 */ + pattrib->data_rate = (u8)GET_RX_STATUS_DESC_RX_RATE_8188F(pdesc); + + /* Offset 16 */ + pattrib->sgi = (u8)GET_RX_STATUS_DESC_SPLCP_8188F(pdesc); + pattrib->ldpc = (u8)GET_RX_STATUS_DESC_LDPC_8188F(pdesc); + pattrib->stbc = (u8)GET_RX_STATUS_DESC_STBC_8188F(pdesc); + pattrib->bw = (u8)GET_RX_STATUS_DESC_BW_8188F(pdesc); + + /* Offset 20 */ + /* pattrib->tsfl=(u8)GET_RX_STATUS_DESC_TSFL_8188F(pdesc); */ + } +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_sreset.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_sreset.c new file mode 100644 index 00000000..e7f7e3bf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/rtl8188f_sreset.c @@ -0,0 +1,109 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8188F_SRESET_C_ + +#include + + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtl8188f_sreset_xmit_status_check(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + + unsigned long current_time; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + unsigned int diff_time; + u32 txdma_status; + + txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS); + if (txdma_status != 0x00 && txdma_status != 0xeaeaeaea) { + DBG_871X("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status); + rtw_hal_sreset_reset(padapter); + } + +#ifdef CONFIG_USB_HCI + /*total xmit irp = 4 */ + /*DBG_8192C("==>%s free_xmitbuf_cnt(%d),txirp_cnt(%d)\n",__func__,pxmitpriv->free_xmitbuf_cnt,pxmitpriv->txirp_cnt); */ + /*if(pxmitpriv->txirp_cnt == NR_XMITBUFF+1) */ + current_time = rtw_get_current_time(); + + if (0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) { + + diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_time); + + if (diff_time > 2000) { + if (psrtpriv->last_tx_complete_time == 0) + psrtpriv->last_tx_complete_time = current_time; + else { + diff_time = rtw_get_passing_time_ms(psrtpriv->last_tx_complete_time); + if (diff_time > 4000) { + u32 ability = 0; + + /*padapter->Wifi_Error_Status = WIFI_TX_HANG; */ + ability = rtw_phydm_ability_get(padapter); + DBG_871X("%s tx hang %s\n", __func__, + (ability & ODM_BB_ADAPTIVITY) ? "ODM_BB_ADAPTIVITY" : ""); + + if (!(ability & ODM_BB_ADAPTIVITY)) + rtw_hal_sreset_reset(padapter); + } + } + } + } +#endif /* #ifdef CONFIG_USB_HCI */ + + if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) { + psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; + rtw_hal_sreset_reset(padapter); + return; + } +} + +void rtl8188f_sreset_linked_status_check(_adapter *padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; +#if 0 + u32 regc50, regc58, reg824, reg800; + + regc50 = rtw_read32(padapter, 0xc50); + regc58 = rtw_read32(padapter, 0xc58); + reg824 = rtw_read32(padapter, 0x824); + reg800 = rtw_read32(padapter, 0x800); + if (((regc50 & 0xFFFFFF00) != 0x69543400) || + ((regc58 & 0xFFFFFF00) != 0x69543400) || + (((reg824 & 0xFFFFFF00) != 0x00390000) && (((reg824 & 0xFFFFFF00) != 0x80390000))) || + (((reg800 & 0xFFFFFF00) != 0x03040000) && ((reg800 & 0xFFFFFF00) != 0x83040000))) { + DBG_8192C("%s regc50:0x%08x, regc58:0x%08x, reg824:0x%08x, reg800:0x%08x,\n", __func__, + regc50, regc58, reg824, reg800); + rtw_hal_sreset_reset(padapter); + } +#endif + + if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) { + psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; + rtw_hal_sreset_reset(padapter); + return; + } +} + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_led.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_led.c new file mode 100644 index 00000000..1bf9f81e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_led.c @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8188FS_LED_C_ + +#include "rtl8188f_hal.h" + +//================================================================================ +// LED object. +//================================================================================ + + +//================================================================================ +// Prototype of protected function. +//================================================================================ + +//================================================================================ +// LED_819xUsb routines. +//================================================================================ + +// +// Description: +// Turn on LED according to LedPin specified. +// +void +SwLedOn_8188FS( + _adapter *padapter, + PLED_SDIO pLed +) +{ + u8 LedCfg; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (RTW_CANNOT_RUN(padapter)) + return; + + pLed->bLedOn = _TRUE; + +} + + +// +// Description: +// Turn off LED according to LedPin specified. +// +void +SwLedOff_8188FS( + _adapter *padapter, + PLED_SDIO pLed +) +{ + u8 LedCfg; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (RTW_CANNOT_RUN(padapter)) + goto exit; + +exit: + pLed->bLedOn = _FALSE; + +} + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ + +//================================================================================ +// Default LED behavior. +//================================================================================ + +// +// Description: +// Initialize all LED_871x objects. +// +void +rtl8188fs_InitSwLeds( + _adapter *padapter + ) +{ +#if 0 + struct led_priv *pledpriv = &(padapter->ledpriv); + + pledpriv->LedControlHandler = LedControlSDIO; + + pledpriv->SwLedOn = SwLedOn_8188FS; + pledpriv->SwLedOff = SwLedOff_8188FS; + + InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0); + + InitLed871x(padapter,&(pledpriv->SwLed1), LED_PIN_LED1); +#endif +} + + +// +// Description: +// DeInitialize all LED_819xUsb objects. +// +void +rtl8188fs_DeInitSwLeds( + _adapter *padapter + ) +{ +#if 0 + struct led_priv *ledpriv = &(padapter->ledpriv); + + DeInitLed871x( &(ledpriv->SwLed0) ); + DeInitLed871x( &(ledpriv->SwLed1) ); +#endif +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_recv.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_recv.c new file mode 100644 index 00000000..5a4061e6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_recv.c @@ -0,0 +1,711 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8188FS_RECV_C_ + +#include + + +static s32 initrecvbuf(struct recv_buf *precvbuf, PADAPTER padapter) +{ + _rtw_init_listhead(&precvbuf->list); + _rtw_spinlock_init(&precvbuf->recvbuf_lock); + + precvbuf->adapter = padapter; + + return _SUCCESS; +} + +static void freerecvbuf(struct recv_buf *precvbuf) +{ + _rtw_spinlock_free(&precvbuf->recvbuf_lock); +} + +static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf *precvbuf, u8 *pphy_status) +{ + s32 ret=_SUCCESS; +#ifdef CONFIG_CONCURRENT_MODE + u8 *secondary_myid, *paddr1; + union recv_frame *precvframe_if2 = NULL; + _adapter *primary_padapter = precvframe->u.hdr.adapter; + _adapter *secondary_padapter = primary_padapter->pbuddy_adapter; + struct recv_priv *precvpriv = &primary_padapter->recvpriv; + _queue *pfree_recv_queue = &precvpriv->free_recv_queue; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(primary_padapter); + + if(!secondary_padapter) + return ret; + + paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data); + + if(IS_MCAST(paddr1) == _FALSE)//unicast packets + { + secondary_myid = adapter_mac_addr(secondary_padapter); + + if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN)) + { + //change to secondary interface + precvframe->u.hdr.adapter = secondary_padapter; + } + + //ret = recv_entry(precvframe); + + } + else // Handle BC/MC Packets + { + //clone/copy to if2 + _pkt *pkt_copy = NULL; + struct rx_pkt_attrib *pattrib = NULL; + + precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue); + + if(!precvframe_if2) + return _FAIL; + + precvframe_if2->u.hdr.adapter = secondary_padapter; + _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)); + pattrib = &precvframe_if2->u.hdr.attrib; + + //driver need to set skb len for skb_copy(). + //If skb->len is zero, skb_copy() will not copy data from original skb. + skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len); + + pkt_copy = rtw_skb_copy( precvframe->u.hdr.pkt); + if (pkt_copy == NULL) + { + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) + { + DBG_8192C("pre_recv_entry(): rtw_skb_copy fail , drop frag frame \n"); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + return ret; + } + + pkt_copy = rtw_skb_clone( precvframe->u.hdr.pkt); + if(pkt_copy == NULL) + { + DBG_8192C("pre_recv_entry(): rtw_skb_clone fail , drop frame\n"); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + return ret; + } + } + + pkt_copy->dev = secondary_padapter->pnetdev; + + precvframe_if2->u.hdr.pkt = pkt_copy; + precvframe_if2->u.hdr.rx_head = pkt_copy->head; + precvframe_if2->u.hdr.rx_data = pkt_copy->data; + precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy); + precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy); + precvframe_if2->u.hdr.len = pkt_copy->len; + + //recvframe_put(precvframe_if2, pattrib->pkt_len); + + if ( pHalData->ReceiveConfig & RCR_APPFCS) + recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN); + + if (pattrib->physt) + rx_query_phy_status(precvframe_if2, pphy_status); + + if(rtw_recv_entry(precvframe_if2) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, + ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } + } + + if (precvframe->u.hdr.attrib.physt) + rx_query_phy_status(precvframe, pphy_status); + + ret = rtw_recv_entry(precvframe); +#endif + + return ret; + +} + +#ifdef CONFIG_SDIO_RX_COPY +static void rtl8188fs_recv_tasklet(void *priv) +{ + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + union recv_frame *precvframe; + struct recv_frame_hdr *phdr; + struct rx_pkt_attrib *pattrib; + _irqL irql; + u8 *ptr; + u32 pkt_len, pkt_offset, skb_len, alloc_sz; + _pkt *pkt_copy = NULL; + u8 shift_sz = 0, rx_report_sz = 0; + + + padapter = (PADAPTER)priv; + pHalData = GET_HAL_DATA(padapter); + precvpriv = &padapter->recvpriv; + + do { + precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue); + if (NULL == precvbuf) break; + + ptr = precvbuf->pdata; + + while (ptr < precvbuf->ptail) + { + precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue); + if (precvframe == NULL) + { + DBG_8192C("%s: no enough recv frame!\n", __FUNCTION__); + rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue); + + // The case of can't allocte recvframe should be temporary, + // schedule again and hope recvframe is available next time. +#ifdef PLATFORM_LINUX + tasklet_schedule(&precvpriv->recv_tasklet); +#endif + return; + } + + //rx desc parsing + rtl8188f_query_rx_desc_status(precvframe, ptr); + + pattrib = &precvframe->u.hdr.attrib; + + // fix Hardware RX data error, drop whole recv_buffer + if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err) + { +#if !(MP_DRIVER==1) + DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__); +#endif + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + + rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz; + pkt_offset = rx_report_sz + pattrib->shift_sz + pattrib->pkt_len; + + if ((ptr + pkt_offset) > precvbuf->ptail) { + DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + + if ((pattrib->crc_err) || (pattrib->icv_err)) + { +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + { + if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) + { + if (pattrib->crc_err == 1) + padapter->mppriv.rx_crcerrpktcount++; + } + } + else +#endif + { + DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err); + } + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + } + else + { + // Modified by Albert 20101213 + // For 8 bytes IP header alignment. + if (pattrib->qos) // Qos data, wireless lan header length is 26 + { + shift_sz = 6; + } + else + { + shift_sz = 0; + } + + skb_len = pattrib->pkt_len; + + // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. + // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){ + //alloc_sz = 1664; //1664 is 128 alignment. + if(skb_len <= 1650) + alloc_sz = 1664; + else + alloc_sz = skb_len + 14; + } + else { + alloc_sz = skb_len; + // 6 is for IP header 8 bytes alignment in QoS packet case. + // 8 is for skb->data 4 bytes alignment. + alloc_sz += 14; + } + + pkt_copy = rtw_skb_alloc(alloc_sz); + + if (pkt_copy) + { + pkt_copy->dev = padapter->pnetdev; + precvframe->u.hdr.pkt = pkt_copy; + skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address + skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz. + _rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz + pattrib->shift_sz), skb_len); + precvframe->u.hdr.rx_head = pkt_copy->head; + precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; + precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy); + } + else + { + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) + { + DBG_8192C("%s: alloc_skb fail, drop frag frame\n", __FUNCTION__); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + + precvframe->u.hdr.pkt = rtw_skb_clone(precvbuf->pskb); + if(precvframe->u.hdr.pkt) + { + _pkt *pkt_clone = precvframe->u.hdr.pkt; + + pkt_clone->data = ptr + rx_report_sz + pattrib->shift_sz; + skb_reset_tail_pointer(pkt_clone); + precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail + = pkt_clone->data; + precvframe->u.hdr.rx_end = pkt_clone->data + skb_len; + } + else + { + DBG_8192C("%s: rtw_skb_clone fail\n", __FUNCTION__); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + } + + recvframe_put(precvframe, skb_len); + //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); + + if (pHalData->ReceiveConfig & RCR_APPFCS) + recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN); + + // move to drv info position + ptr += RXDESC_SIZE; + + // update drv info + if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) { + //rtl8188s_update_bassn(padapter, pdrvinfo); + ptr += 4; + } + + if (pattrib->pkt_rpt_type == NORMAL_RX) { + // skip the rx packet with abnormal length + if (pattrib->pkt_len < 14 || pattrib->pkt_len > 8192) { + DBG_8192C("skip abnormal rx packet(%d)\n", pattrib->pkt_len); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + { + if (pre_recv_entry(precvframe, precvbuf, ptr) != _SUCCESS) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, + ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); + } + } + else +#endif + { + if (pattrib->physt) + rx_query_phy_status(precvframe, ptr); + + if (rtw_recv_entry(precvframe) != _SUCCESS) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_dump_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__)); + } + } + } + else { +#ifdef CONFIG_C2H_PACKET_EN + if (pattrib->pkt_rpt_type == C2H_PACKET) { + rtl8188f_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 + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + } + } + + pkt_offset = _RND8(pkt_offset); + precvbuf->pdata += pkt_offset; + ptr = precvbuf->pdata; + precvframe = NULL; + pkt_copy = NULL; + } + + rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue); + } while (1); + +} +#else +static void rtl8188fs_recv_tasklet(void *priv) +{ + PADAPTER padapter; + PHAL_DATA_TYPE pHalData; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + union recv_frame *precvframe; + struct recv_frame_hdr *phdr; + struct rx_pkt_attrib *pattrib; + u8 *ptr; + _pkt *ppkt; + u32 pkt_offset; + _irqL irql; + + + padapter = (PADAPTER)priv; + pHalData = GET_HAL_DATA(padapter); + precvpriv = &padapter->recvpriv; + + do { + precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue); + if (NULL == precvbuf) break; + + ptr = precvbuf->pdata; + + while (ptr < precvbuf->ptail) + { + precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue); + if (precvframe == NULL) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("rtl8188fs_recv_tasklet: no enough recv frame!\n")); + rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue); + + // The case of can't allocte recvframe should be temporary, + // schedule again and hope recvframe is available next time. +#ifdef PLATFORM_LINUX + tasklet_schedule(&precvpriv->recv_tasklet); +#endif + return; + } + + phdr = &precvframe->u.hdr; + pattrib = &phdr->attrib; + + rtl8188f_query_rx_desc_status(precvframe, ptr); + +#if 0 + { + int i, len = 64; + u8 *pptr = ptr; + + if((*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x80) && (*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x40)) + { + DBG_871X("##############RxDESC############### \n"); + for(i=0; i<32;i=i+16) + DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i), + *(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10), + *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15)); + + if(pattrib->pkt_len < 100) + len = pattrib->pkt_len; + pptr = ptr + RXDESC_SIZE + pattrib->drvinfo_sz; + DBG_871X("##############Len=%d############### \n", pattrib->pkt_len); + for(i=0; iReceiveConfig & RCR_ACRC32)) && pattrib->crc_err) + { + DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } + + pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->pkt_len; +#if 0 // reduce check to speed up + if ((ptr + pkt_offset) > precvbuf->ptail) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, + ("%s: next pkt len(%p,%d) exceed ptail(%p)!\n", + __FUNCTION__, ptr, pkt_offset, precvbuf->ptail)); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + break; + } +#endif + + if ((pattrib->crc_err) || (pattrib->icv_err)) + { +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + { + if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0)) + { + if (pattrib->crc_err == 1) + padapter->mppriv.rx_crcerrpktcount++; + } + } + else +#endif + { + DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err); + } + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + } + else + { + ppkt = rtw_skb_clone(precvbuf->pskb); + if (ppkt == NULL) { + DBG_8192C("%s: no enough memory to allocate SKB!\n", __FUNCTION__); + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue); + + // The case of can't allocte skb is serious and may never be recovered, + // once bDriverStopped is enable, this task should be stopped. + if (padapter->bDriverStopped == _FALSE) { +#ifdef PLATFORM_LINUX + tasklet_schedule(&precvpriv->recv_tasklet); +#endif + } + + return; + } + + phdr->pkt = ppkt; + phdr->len = 0; + phdr->rx_head = precvbuf->phead; + phdr->rx_data = phdr->rx_tail = precvbuf->pdata; + phdr->rx_end = precvbuf->pend; + recvframe_put(precvframe, pkt_offset); + recvframe_pull(precvframe, RXDESC_SIZE + pattrib->drvinfo_sz); + if (pHalData->ReceiveConfig & RCR_APPFCS) + recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN); + + // move to drv info position + ptr += RXDESC_SIZE; + + // update drv info + if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) { + //rtl8188s_update_bassn(padapter, pdrvinfo); + ptr += 4; + } + + if (pattrib->pkt_rpt_type == NORMAL_RX) { +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + { + if (pre_recv_entry(precvframe, precvbuf, ptr) != _SUCCESS) { + RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, + ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); + } + } + else +#endif + { + if (pattrib->physt) + rx_query_phy_status(precvframe, ptr); + + if (rtw_recv_entry(precvframe) != _SUCCESS) + { + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtl8188fs_recv_tasklet: rtw_recv_entry(precvframe) != _SUCCESS\n")); + } + } + } + else { +#ifdef CONFIG_C2H_PACKET_EN + if (pattrib->pkt_rpt_type == C2H_PACKET) { + rtl8188f_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 + rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); + } + } + + pkt_offset = _RND8(pkt_offset); + precvbuf->pdata += pkt_offset; + ptr = precvbuf->pdata; + } + + rtw_skb_free(precvbuf->pskb); + precvbuf->pskb = NULL; + rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue); + } while (1); +} +#endif + +/* + * Initialize recv private variable for hardware dependent + * 1. recv buf + * 2. recv tasklet + * + */ +s32 rtl8188fs_init_recv_priv(PADAPTER padapter) +{ + s32 res; + u32 i, n; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + + + res = _SUCCESS; + precvpriv = &padapter->recvpriv; + + //3 1. init recv buffer + _rtw_init_queue(&precvpriv->free_recv_buf_queue); + _rtw_init_queue(&precvpriv->recv_buf_pending_queue); + + n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + precvpriv->pallocated_recv_buf = rtw_zmalloc(n); + if (precvpriv->pallocated_recv_buf == NULL) { + res = _FAIL; + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n")); + goto exit; + } + + precvpriv->precv_buf = (u8*)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4); + + // init each recv buffer + precvbuf = (struct recv_buf*)precvpriv->precv_buf; + for (i = 0; i < NR_RECVBUFF; i++) + { + res = initrecvbuf(precvbuf, padapter); + if (res == _FAIL) + break; + + res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); + if (res == _FAIL) { + freerecvbuf(precvbuf); + break; + } + +#ifdef CONFIG_SDIO_RX_COPY + if (precvbuf->pskb == NULL) { + SIZE_PTR tmpaddr=0; + SIZE_PTR alignment=0; + + precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); + + if(precvbuf->pskb) + { + precvbuf->pskb->dev = padapter->pnetdev; + + tmpaddr = (SIZE_PTR)precvbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); + skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + } + + if (precvbuf->pskb == NULL) { + DBG_871X("%s: alloc_skb fail!\n", __FUNCTION__); + } + } +#endif + + rtw_list_insert_tail(&precvbuf->list, &precvpriv->free_recv_buf_queue.queue); + + precvbuf++; + } + precvpriv->free_recv_buf_queue_cnt = i; + + if (res == _FAIL) + goto initbuferror; + + //3 2. init tasklet +#ifdef PLATFORM_LINUX + tasklet_init(&precvpriv->recv_tasklet, + (void(*)(unsigned long))rtl8188fs_recv_tasklet, + (unsigned long)padapter); +#endif + + goto exit; + +initbuferror: + precvbuf = (struct recv_buf*)precvpriv->precv_buf; + if (precvbuf) { + n = precvpriv->free_recv_buf_queue_cnt; + precvpriv->free_recv_buf_queue_cnt = 0; + for (i = 0; i < n ; i++) + { + rtw_list_delete(&precvbuf->list); + rtw_os_recvbuf_resource_free(padapter, precvbuf); + freerecvbuf(precvbuf); + precvbuf++; + } + precvpriv->precv_buf = NULL; + } + + if (precvpriv->pallocated_recv_buf) { + n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + rtw_mfree(precvpriv->pallocated_recv_buf, n); + precvpriv->pallocated_recv_buf = NULL; + } + +exit: + return res; +} + +/* + * Free recv private variable of hardware dependent + * 1. recv buf + * 2. recv tasklet + * + */ +void rtl8188fs_free_recv_priv(PADAPTER padapter) +{ + u32 i, n; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + + + precvpriv = &padapter->recvpriv; + + //3 1. kill tasklet +#ifdef PLATFORM_LINUX + tasklet_kill(&precvpriv->recv_tasklet); +#endif + + //3 2. free all recv buffers + precvbuf = (struct recv_buf*)precvpriv->precv_buf; + if (precvbuf) { + n = NR_RECVBUFF; + precvpriv->free_recv_buf_queue_cnt = 0; + for (i = 0; i < n ; i++) + { + rtw_list_delete(&precvbuf->list); + rtw_os_recvbuf_resource_free(padapter, precvbuf); + freerecvbuf(precvbuf); + precvbuf++; + } + precvpriv->precv_buf = NULL; + } + + if (precvpriv->pallocated_recv_buf) { + n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; + rtw_mfree(precvpriv->pallocated_recv_buf, n); + precvpriv->pallocated_recv_buf = NULL; + } +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_xmit.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_xmit.c new file mode 100644 index 00000000..45b92fbc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/rtl8189fs_xmit.c @@ -0,0 +1,769 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _RTL8188FS_XMIT_C_ + +#include + +static u8 rtw_sdio_wait_enough_TxOQT_space(PADAPTER padapter, u8 agg_num) +{ + u32 n = 0; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + while (pHalData->SdioTxOQTFreeSpace < agg_num) + { + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s: bSurpriseRemoved or bDriverStopped (wait TxOQT)\n", __func__); + return _FALSE; + } + + HalQueryTxOQTBufferStatus8188FSdio(padapter); + + if ((++n % 60) == 0) { + if ((n % 300) == 0) { + DBG_871X("%s(%d): QOT free space(%d), agg_num: %d\n", + __func__, n, pHalData->SdioTxOQTFreeSpace, agg_num); + } + rtw_msleep_os(1); + //yield(); + } + } + + pHalData->SdioTxOQTFreeSpace -= agg_num; + + //if (n > 1) + // ++priv->pshare->nr_out_of_txoqt_space; + + return _TRUE; +} + +static s32 rtl8188fs_dequeue_writeport(PADAPTER padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct xmit_buf *pxmitbuf; + u8 PageIdx = 0; + u32 deviceId; +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + u8 bUpdatePageNum = _FALSE; +#else + u32 polling_num = 0; +#endif + + if (rtw_xmit_ac_blocked(padapter) == _TRUE) + pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv); + else + pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv); + + if (pxmitbuf == NULL) + return _TRUE; + + deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr); + + // translate fifo addr to queue index + switch (deviceId) { + case WLAN_TX_HIQ_DEVICE_ID: + PageIdx = HI_QUEUE_IDX; + break; + + case WLAN_TX_MIQ_DEVICE_ID: + PageIdx = MID_QUEUE_IDX; + break; + + case WLAN_TX_LOQ_DEVICE_ID: + PageIdx = LOW_QUEUE_IDX; + break; + } + +query_free_page: + /* check if hardware tx fifo page is enough */ + if (_FALSE == rtw_hal_sdio_query_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num)) { +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + if (!bUpdatePageNum) { + // Total number of page is NOT available, so update current FIFO status + HalQueryTxBufferStatus8188FSdio(padapter); + bUpdatePageNum = _TRUE; + goto query_free_page; + } else { + bUpdatePageNum = _FALSE; + enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf); + return _TRUE; + } +#else //CONFIG_SDIO_TX_ENABLE_AVAL_INT + polling_num++; + if ((polling_num % 0x7F) == 0) {//or 80 + //DBG_871X("%s: FIFO starvation!(%d) len=%d agg=%d page=(R)%d(A)%d\n", + // __func__, polling_num, pxmitbuf->len, pxmitbuf->agg_num, pframe->pg_num, freePage[PageIdx] + freePage[PUBLIC_QUEUE_IDX]); + rtw_msleep_os(1); + } + + // Total number of page is NOT available, so update current FIFO status + HalQueryTxBufferStatus8188FSdio(padapter); + goto query_free_page; +#endif //CONFIG_SDIO_TX_ENABLE_AVAL_INT + } + + if (RTW_CANNOT_RUN(padapter)) { + RT_TRACE(_module_hal_xmit_c_, _drv_notice_, + ("%s: bSurpriseRemoved(wirte port)\n", __FUNCTION__)); + goto free_xmitbuf; + } + + if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == _FALSE) + { + goto free_xmitbuf; + } + +#ifdef CONFIG_CHECK_LEAVE_LPS + traffic_check_for_leave_lps(padapter, _TRUE, pxmitbuf->agg_num); +#endif + + rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf); + + rtw_hal_sdio_update_tx_freepage(padapter, PageIdx, pxmitbuf->pg_num); + +free_xmitbuf: + //rtw_free_xmitframe(pxmitpriv, pframe); + //pxmitbuf->priv_data = NULL; + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + +#if 0 // improve TX/RX throughput balance +{ + PSDIO_DATA psdio; + struct sdio_func *func; + static u8 i = 0; + u32 sdio_hisr; + u8 j; + + psdio = &adapter_to_dvobj(padapter)->intf_data; + func = psdio->func; + + if (i == 2) + { + j = 0; + while (j < 10) + { + sdio_hisr = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR); + sdio_hisr &= GET_HAL_DATA(padapter)->sdio_himr; + if (sdio_hisr & SDIO_HISR_RX_REQUEST) + { + sdio_claim_host(func); + sd_int_hdl(GET_PRIMARY_ADAPTER(padapter)); + sdio_release_host(func); + } + else + { + break; + } + j++; + } + i = 0; + } + else + { + i++; + } +} +#endif + +#ifdef CONFIG_SDIO_TX_TASKLET + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#endif + + return _FAIL; +} + +/* + * Description + * Transmit xmitbuf to hardware tx fifo + * + * Return + * _SUCCESS ok + * _FAIL something error + */ +s32 rtl8188fs_xmit_buf_handler(PADAPTER padapter) +{ + struct xmit_priv *pxmitpriv; + u8 queue_empty, queue_pending; + s32 ret; + + pxmitpriv = &padapter->xmitpriv; + + ret = _rtw_down_sema(&pxmitpriv->xmit_sema); + if (_FAIL == ret) { + DBG_871X_LEVEL(_drv_emerg_, "%s: down SdioXmitBufSema fail!\n", __FUNCTION__); + return _FAIL; + } + + if (RTW_CANNOT_RUN(padapter)) { + RT_TRACE(_module_hal_xmit_c_, _drv_err_ + , ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)!\n" + , __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + return _FAIL; + } + + queue_pending = check_pending_xmitbuf(pxmitpriv); + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + queue_pending |= check_pending_xmitbuf(&padapter->pbuddy_adapter->xmitpriv); +#endif + + if(queue_pending == _FALSE) + return _SUCCESS; + +#ifdef CONFIG_LPS_LCLK + ret = rtw_register_tx_alive(padapter); + if (ret != _SUCCESS) { + return _SUCCESS; + } +#endif + + do { + queue_empty = rtl8188fs_dequeue_writeport(padapter); +// dump secondary adapter xmitbuf +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + queue_empty &= rtl8188fs_dequeue_writeport(padapter->pbuddy_adapter); +#endif + } while ( !queue_empty); + +#ifdef CONFIG_LPS_LCLK + rtw_unregister_tx_alive(padapter); +#endif + + return _SUCCESS; +} + +/* + * Description: + * Aggregation packets and send to hardware + * + * Return: + * 0 Success + * -1 Hardware resource(TX FIFO) not ready + * -2 Software resource(xmitbuf) not ready + */ +static s32 xmit_xmitframes(PADAPTER padapter, struct xmit_priv *pxmitpriv) +{ + s32 err, ret; + u32 k=0; + struct hw_xmit *hwxmits, *phwxmit; + u8 no_res, idx, hwentry; + _irqL irql; + struct tx_servq *ptxservq; + _list *sta_plist, *sta_phead, *frame_plist, *frame_phead; + struct xmit_frame *pxmitframe; + _queue *pframe_queue; + struct xmit_buf *pxmitbuf; + u32 txlen, max_xmit_len; + u8 txdesc_size = TXDESC_SIZE; + int inx[4]; + u8 pre_qsel=0xFF,next_qsel=0xFF; + u8 single_sta_in_queue = _FALSE; + + err = 0; + no_res = _FALSE; + hwxmits = pxmitpriv->hwxmits; + hwentry = pxmitpriv->hwxmit_entry; + ptxservq = NULL; + pxmitframe = NULL; + pframe_queue = NULL; + pxmitbuf = NULL; + + if (padapter->registrypriv.wifi_spec == 1) { + for(idx=0; idx<4; idx++) + inx[idx] = pxmitpriv->wmm_para_seq[idx]; + } else { + inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; + } + + // 0(VO), 1(VI), 2(BE), 3(BK) + for (idx = 0; idx < hwentry; idx++) + { + phwxmit = hwxmits + inx[idx]; + + if((check_pending_xmitbuf(pxmitpriv) == _TRUE) && (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic == _TRUE)) { + if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) { + err = -2; + break; + } + } + + max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]); + + _enter_critical_bh(&pxmitpriv->lock, &irql); + + sta_phead = get_list_head(phwxmit->sta_queue); + sta_plist = get_next(sta_phead); + //because stop_sta_xmit may delete sta_plist at any time + //so we should add lock here, or while loop can not exit + + single_sta_in_queue = rtw_end_of_queue_search(sta_phead, get_next(sta_plist)); + + while (rtw_end_of_queue_search(sta_phead, sta_plist) == _FALSE) + { + ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq, tx_pending); + sta_plist = get_next(sta_plist); + +#ifdef DBG_XMIT_BUF + DBG_871X("%s idx:%d hwxmit_pkt_num:%d ptxservq_pkt_num:%d\n", __func__, idx, phwxmit->accnt, ptxservq->qcnt); + DBG_871X("%s free_xmit_extbuf_cnt=%d free_xmitbuf_cnt=%d free_xmitframe_cnt=%d \n", + __func__, pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xmitbuf_cnt, + pxmitpriv->free_xmitframe_cnt); +#endif + pframe_queue = &ptxservq->sta_pending; + + frame_phead = get_list_head(pframe_queue); + + while (rtw_is_list_empty(frame_phead) == _FALSE) + { + frame_plist = get_next(frame_phead); + pxmitframe = LIST_CONTAINOR(frame_plist, struct xmit_frame, list); + + // check xmit_buf size enough or not + txlen = txdesc_size + rtw_wlan_pkt_size(pxmitframe); + next_qsel = pxmitframe->attrib.qsel; + if ((NULL == pxmitbuf) || + ((_RND(pxmitbuf->len, 8) + txlen) > max_xmit_len) + || (k >= (rtw_hal_sdio_max_txoqt_free_space(padapter)-1)) + || ((k!=0) && (_FAIL == rtw_hal_busagg_qsel_check(padapter,pre_qsel,next_qsel))) + ) + { + if (pxmitbuf) + { + //pxmitbuf->priv_data will be NULL, and will crash here + if (pxmitbuf->len > 0 && pxmitbuf->priv_data) + { + struct xmit_frame *pframe; + pframe = (struct xmit_frame*)pxmitbuf->priv_data; + pframe->agg_num = k; + pxmitbuf->agg_num = k; + rtl8188f_update_txdesc(pframe, pframe->buf_addr); + rtw_free_xmitframe(pxmitpriv, pframe); + pxmitbuf->priv_data = NULL; + enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); + + //can not yield under lock + //rtw_yield_os(); + if (single_sta_in_queue == _FALSE) { + /* break the loop in case there is more than one sta in this ac queue */ + pxmitbuf = NULL; + err = -3; + break; + } + + } else { + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + } + } + + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + if (pxmitbuf == NULL) { +#ifdef DBG_XMIT_BUF + DBG_871X_LEVEL(_drv_err_, "%s: xmit_buf is not enough!\n", __FUNCTION__); +#endif + err = -2; +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + #ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type > PRIMARY_ADAPTER) + _rtw_up_sema(&(padapter->pbuddy_adapter->xmitpriv.xmit_sema)); + else + #endif + _rtw_up_sema(&(pxmitpriv->xmit_sema)); +#endif + break; + } + k = 0; + } + + // ok to send, remove frame from queue +#ifdef CONFIG_AP_MODE + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) { + if ((pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) && + (pxmitframe->attrib.triggered == 0)) { + DBG_871X("%s: one not triggered pkt in queue when this STA sleep," + " break and goto next sta\n", __func__); + break; + } + } +#endif + rtw_list_delete(&pxmitframe->list); + ptxservq->qcnt--; + phwxmit->accnt--; + + if (k == 0) { + pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); + pxmitbuf->priv_data = (u8*)pxmitframe; + } + + // coalesce the xmitframe to xmitbuf + pxmitframe->pxmitbuf = pxmitbuf; + pxmitframe->buf_addr = pxmitbuf->ptail; + + ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); + if (ret == _FAIL) { + DBG_871X_LEVEL(_drv_err_, "%s: coalesce FAIL!", __FUNCTION__); + // Todo: error handler + } else { + k++; + if (k != 1) + rtl8188f_update_txdesc(pxmitframe, pxmitframe->buf_addr); + rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz); + pre_qsel = pxmitframe->attrib.qsel; + txlen = txdesc_size + pxmitframe->attrib.last_txcmdsz; + pxmitframe->pg_num = (txlen + 127)/128; + pxmitbuf->pg_num += (txlen + 127)/128; + //if (k != 1) + // ((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num; + pxmitbuf->ptail += _RND(txlen, 8); // round to 8 bytes alignment + pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen; + } + + if (k != 1) + rtw_free_xmitframe(pxmitpriv, pxmitframe); + pxmitframe = NULL; + } + + if (_rtw_queue_empty(pframe_queue) == _TRUE) + rtw_list_delete(&ptxservq->tx_pending); + else if (err == -3) { + /* Re-arrange the order of stations in this ac queue to balance the service for these stations */ + rtw_list_delete(&ptxservq->tx_pending); + rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmit->sta_queue)); + } + + if (err) break; + } + _exit_critical_bh(&pxmitpriv->lock, &irql); + + // dump xmit_buf to hw tx fifo + if (pxmitbuf) + { + RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("pxmitbuf->len=%d enqueue\n",pxmitbuf->len)); + + if (pxmitbuf->len > 0) { + struct xmit_frame *pframe; + pframe = (struct xmit_frame*)pxmitbuf->priv_data; + pframe->agg_num = k; + pxmitbuf->agg_num = k; + rtl8188f_update_txdesc(pframe, pframe->buf_addr); + rtw_free_xmitframe(pxmitpriv, pframe); + pxmitbuf->priv_data = NULL; + enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); + rtw_yield_os(); + } + else + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + pxmitbuf = NULL; + } + + if (err == -2) + break; + } + + return err; +} + +/* + * Description + * Transmit xmitframe from queue + * + * Return + * _SUCCESS ok + * _FAIL something error + */ +s32 rtl8188fs_xmit_handler(PADAPTER padapter) +{ + struct xmit_priv *pxmitpriv; + s32 ret; + _irqL irql; + + + pxmitpriv = &padapter->xmitpriv; + +wait: + ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema); + if (_FAIL == ret) { + DBG_871X_LEVEL(_drv_emerg_, "%s: down sema fail!\n", __FUNCTION__); + return _FAIL; + } + +next: + if (RTW_CANNOT_RUN(padapter)) { + RT_TRACE(_module_hal_xmit_c_, _drv_notice_ + , ("%s: bDriverStopped(%s) bSurpriseRemoved(%s)\n" + , __func__ + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False")); + return _FAIL; + } + + _enter_critical_bh(&pxmitpriv->lock, &irql); + ret = rtw_txframes_pending(padapter); + _exit_critical_bh(&pxmitpriv->lock, &irql); + if (ret == 0) { + return _SUCCESS; + } + + // dequeue frame and write to hardware + + ret = xmit_xmitframes(padapter, pxmitpriv); + if (ret == -2) { + //here sleep 1ms will cause big TP loss of TX + //from 50+ to 40+ + if(padapter->registrypriv.wifi_spec) + rtw_msleep_os(1); + else +#ifdef CONFIG_REDUCE_TX_CPU_LOADING + rtw_msleep_os(1); +#else + rtw_yield_os(); +#endif + goto next; + } + + _enter_critical_bh(&pxmitpriv->lock, &irql); + ret = rtw_txframes_pending(padapter); + _exit_critical_bh(&pxmitpriv->lock, &irql); + if (ret == 1) { +#ifdef CONFIG_REDUCE_TX_CPU_LOADING + rtw_msleep_os(1); +#endif + goto next; + } + + return _SUCCESS; +} + +thread_return rtl8188fs_xmit_thread(thread_context context) +{ + s32 ret; + PADAPTER padapter; + struct xmit_priv *pxmitpriv; + u8 thread_name[20] = "RTWHALXT"; + + + ret = _SUCCESS; + padapter = (PADAPTER)context; + pxmitpriv = &padapter->xmitpriv; + + rtw_sprintf(thread_name, 20, "%s-"ADPT_FMT, thread_name, ADPT_ARG(padapter)); + thread_enter(thread_name); + + DBG_871X("start "FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + // For now, no one would down sema to check thread is running, + // so mark this temporary, Lucas@20130820 +// _rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema); + + do { + ret = rtl8188fs_xmit_handler(padapter); + if (signal_pending(current)) { + flush_signals(current); + } + } while (_SUCCESS == ret); + + _rtw_up_sema(&pxmitpriv->SdioXmitTerminateSema); + + RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("-%s\n", __FUNCTION__)); + + thread_exit(); +} + +s32 rtl8188fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe) +{ + s32 ret = _SUCCESS; + struct pkt_attrib *pattrib; + struct xmit_buf *pxmitbuf; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + u8 txdesc_size = TXDESC_SIZE; + + RT_TRACE(_module_hal_xmit_c_, _drv_info_, ("+%s\n", __FUNCTION__)); + + pattrib = &pmgntframe->attrib; + pxmitbuf = pmgntframe->pxmitbuf; + + rtl8188f_update_txdesc(pmgntframe, pmgntframe->buf_addr); + + pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz; + //pmgntframe->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size + pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size + pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len; + pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe); + + rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz); + + rtw_free_xmitframe(pxmitpriv, pmgntframe); + + pxmitbuf->priv_data = NULL; + + if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly + { + ret = rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr], pxmitbuf->len, (u8 *)pxmitbuf); + if (ret != _SUCCESS) + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); + + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + } + else + { + enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); + } + + return ret; +} + +/* + * Description: + * Handle xmitframe(packet) come from rtw_xmit() + * + * Return: + * _TRUE dump packet directly ok + * _FALSE enqueue, temporary can't transmit packets to hardware + */ +s32 rtl8188fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv; + _irqL irql; + s32 err; + + + pxmitframe->attrib.qsel = pxmitframe->attrib.priority; + pxmitpriv = &padapter->xmitpriv; + +#ifdef CONFIG_80211N_HT + if ((pxmitframe->frame_tag == DATA_FRAMETAG) && + (pxmitframe->attrib.ether_type != 0x0806) && + (pxmitframe->attrib.ether_type != 0x888e) && + (pxmitframe->attrib.dhcp_pkt != 1)) + { + if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) + rtw_issue_addbareq_cmd(padapter, pxmitframe); + } +#endif + + _enter_critical_bh(&pxmitpriv->lock, &irql); + err = rtw_xmitframe_enqueue(padapter, pxmitframe); + _exit_critical_bh(&pxmitpriv->lock, &irql); + if (err != _SUCCESS) { + RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("rtl8188fs_hal_xmit: enqueue xmitframe fail\n")); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + pxmitpriv->tx_drop++; + return _TRUE; + } + + _rtw_up_sema(&pxmitpriv->SdioXmitSema); + + return _FALSE; +} + +s32 rtl8188fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + s32 err; + + if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) + { + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + pxmitpriv->tx_drop++; + } + else + { +#ifdef CONFIG_SDIO_TX_TASKLET + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); +#else + _rtw_up_sema(&pxmitpriv->SdioXmitSema); +#endif + } + + return err; + +} + +/* + * Return + * _SUCCESS start thread ok + * _FAIL start thread fail + * + */ +s32 rtl8188fs_init_xmit_priv(PADAPTER padapter) +{ + struct xmit_priv *xmitpriv = &padapter->xmitpriv; + PHAL_DATA_TYPE phal; + + + phal = GET_HAL_DATA(padapter); + + _rtw_spinlock_init(&phal->SdioTxFIFOFreePageLock); + _rtw_init_sema(&xmitpriv->SdioXmitSema, 0); + _rtw_init_sema(&xmitpriv->SdioXmitTerminateSema, 0); + + return _SUCCESS; +} + +void rtl8188fs_free_xmit_priv(PADAPTER padapter) +{ + PHAL_DATA_TYPE phal; + struct xmit_priv *pxmitpriv; + struct xmit_buf *pxmitbuf; + _queue *pqueue; + _list *plist, *phead; + _list tmplist; + _irqL irql; + + + phal = GET_HAL_DATA(padapter); + pxmitpriv = &padapter->xmitpriv; + pqueue = &pxmitpriv->pending_xmitbuf_queue; + phead = get_list_head(pqueue); + _rtw_init_listhead(&tmplist); + + _enter_critical_bh(&pqueue->lock, &irql); + if (_rtw_queue_empty(pqueue) == _FALSE) + { + // Insert tmplist to end of queue, and delete phead + // then tmplist become head of queue. + rtw_list_insert_tail(&tmplist, phead); + rtw_list_delete(phead); + } + _exit_critical_bh(&pqueue->lock, &irql); + + phead = &tmplist; + while (rtw_is_list_empty(phead) == _FALSE) + { + plist = get_next(phead); + rtw_list_delete(plist); + + pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list); + rtw_free_xmitframe(pxmitpriv, (struct xmit_frame*)pxmitbuf->priv_data); + pxmitbuf->priv_data = NULL; + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + } + + _rtw_spinlock_free(&phal->SdioTxFIFOFreePageLock); +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_halinit.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_halinit.c new file mode 100644 index 00000000..b6004857 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_halinit.c @@ -0,0 +1,1886 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _SDIO_HALINIT_C_ + +#include +#include "hal_com_h2c.h" + +/* + * Description: + * Call power on sequence to enable card + * + * Return: + * _SUCCESS enable success + * _FAIL enable fail + */ +static u8 CardEnable(PADAPTER padapter) +{ + u8 bMacPwrCtrlOn; + u8 ret = _FAIL; + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if (bMacPwrCtrlOn == _FALSE) { + u8 hci_sus_state; + + // RSV_CTRL 0x1C[7:0] = 0x00 + // unlock ISO/CLK/Power control register + rtw_write8(padapter, REG_RSV_CTRL, 0x0); + + hci_sus_state = HCI_SUS_LEAVING; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8188F_card_enable_flow); + if (ret == _SUCCESS) { + bMacPwrCtrlOn = _TRUE; + rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + hci_sus_state = HCI_SUS_LEAVE; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + } else { + hci_sus_state = HCI_SUS_ERR; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + } + } else + ret = _SUCCESS; + + return ret; +} + +/* + * Description: + * Call this function to make sure power on successfully + * + * Return: + * _SUCCESS enable success + * _FAIL enable fail + */ +static int PowerOnCheck(PADAPTER padapter) +{ + u32 val_offset0, val_offset1, val_offset2, val_offset3; + u32 val_mix = 0; + u32 res = 0; + u8 ret = _FAIL; + int index = 0; + + val_offset0 = rtw_read8(padapter, REG_CR); + val_offset1 = rtw_read8(padapter, REG_CR+1); + val_offset2 = rtw_read8(padapter, REG_CR+2); + val_offset3 = rtw_read8(padapter, REG_CR+3); + + if (val_offset0 == 0xEA || val_offset1 == 0xEA || + val_offset2 == 0xEA || val_offset3 ==0xEA) { + DBG_871X("%s: power on fail, do Power on again\n", __func__); + return ret; + } + + val_mix = val_offset3 << 24 | val_mix; + val_mix = val_offset2 << 16 | val_mix; + val_mix = val_offset1 << 8 | val_mix; + val_mix = val_offset0 | val_mix; + + res = rtw_read32(padapter, REG_CR); + + DBG_871X("%s: val_mix:0x%08x, res:0x%08x\n", __func__, val_mix, res); + + while(index < 100) { + if (res == val_mix) { + DBG_871X("%s: 0x100 the result of cmd52 and cmd53 is the same.\n", __func__); + ret = _SUCCESS; + break; + } else { + DBG_871X("%s: 0x100 cmd52 and cmd53 is not the same(index:%d).\n", __func__, index); + res = rtw_read32(padapter, REG_CR); + index ++; + ret = _FAIL; + } + } + + if (ret) { + index = 0; + while(index < 100) { + rtw_write32(padapter, 0x1B8, 0x12345678); + res = rtw_read32(padapter, 0x1B8); + if (res == 0x12345678) { + DBG_871X("%s: 0x1B8 test Pass.\n", __func__); + ret = _SUCCESS; + break; + } else { + index ++; + DBG_871X("%s: 0x1B8 test Fail(index: %d).\n", __func__, index); + ret = _FAIL; + } + } + } else { + DBG_871X("%s: fail at cmd52, cmd53.\n", __func__); + } + + if (ret == _FAIL) { + DBG_871X_LEVEL(_drv_err_, "Dump MAC Page0 register:\n"); + /* Dump Page0 for check cystal*/ + for (index = 0 ; index < 0xff ; index++) { + if(index%16==0) + printk("0x%02x ",index); + + printk("%02x ", rtw_read8(padapter, index)); + + if(index%16==15) + printk("\n"); + else if(index%8==7) + printk("\t"); + } + printk("\n"); + } + + return ret; +} + +static u32 _InitPowerOn_8188FS(PADAPTER padapter) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + u8 value8; + u16 value16; + u32 value32; + u8 ret; + u8 pwron_chk_cnt=0; +// u8 bMacPwrCtrlOn; + +_init_power_on: + + /* check to apply user defined pll_ref_clk_sel */ + if ((regsty->pll_ref_clk_sel & 0x0F) != 0x0F) + rtl8188f_set_pll_ref_clk_sel(padapter, regsty->pll_ref_clk_sel); + +#ifdef CONFIG_EXT_CLK + // Use external crystal(XTAL) + value8 = rtw_read8(padapter, REG_PAD_CTRL1_8188F+2); + value8 |= BIT(7); + rtw_write8(padapter, REG_PAD_CTRL1_8188F+2, value8); + + // CLK_REQ High active or Low Active + // Request GPIO polarity: + // 0: low active + // 1: high active + value8 = rtw_read8(padapter, REG_MULTI_FUNC_CTRL+1); + value8 |= BIT(5); + rtw_write8(padapter, REG_MULTI_FUNC_CTRL+1, value8); +#endif // CONFIG_EXT_CLK + + // only cmd52 can be used before power on(card enable) + ret = CardEnable(padapter); + if (ret == _FALSE) { + RT_TRACE(_module_hci_hal_init_c_, _drv_emerg_, + ("%s: run power on flow fail\n", __FUNCTION__)); + return _FAIL; + } + + rtw_write8(padapter, REG_CR, 0x00); + // Enable MAC DMA/WMAC/SCHEDULE/SEC block + value16 = rtw_read16(padapter, REG_CR); + value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN + | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN); + rtw_write16(padapter, REG_CR, value16); + + + //PowerOnCheck() + ret = PowerOnCheck(padapter); + pwron_chk_cnt++; + if (_FAIL == ret ) { + if (pwron_chk_cnt > 1) { + DBG_871X("Failed to init Power On!\n"); + return _FAIL; + } + DBG_871X("Power on Fail! do it again\n"); + goto _init_power_on; + } + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_PowerOnSetting(padapter); + + // external switch to S1 + // 0x38[11] = 0x1 + // 0x4c[23] = 0x1 + // 0x64[0] = 0 + value16 = rtw_read16(padapter, REG_PWR_DATA); + // Switch the control of EESK, EECS to RFC for DPDT or Antenna switch + value16 |= BIT(11); // BIT_EEPRPAD_RFE_CTRL_EN + rtw_write16(padapter, REG_PWR_DATA, value16); +// DBG_8192C("%s: REG_PWR_DATA(0x%x)=0x%04X\n", __FUNCTION__, REG_PWR_DATA, rtw_read16(padapter, REG_PWR_DATA)); + + value32 = rtw_read32(padapter, REG_LEDCFG0); + value32 |= BIT(23); // DPDT_SEL_EN, 1 for SW control + rtw_write32(padapter, REG_LEDCFG0, value32); +// DBG_8192C("%s: REG_LEDCFG0(0x%x)=0x%08X\n", __FUNCTION__, REG_LEDCFG0, rtw_read32(padapter, REG_LEDCFG0)); + + value8 = rtw_read8(padapter, REG_PAD_CTRL1_8188F); + value8 &= ~BIT(0); // BIT_SW_DPDT_SEL_DATA, DPDT_SEL default configuration + rtw_write8(padapter, REG_PAD_CTRL1_8188F, value8); +// DBG_8192C("%s: REG_PAD_CTRL1(0x%x)=0x%02X\n", __FUNCTION__, REG_PAD_CTRL1_8188F, rtw_read8(padapter, REG_PAD_CTRL1_8188F)); +#endif // CONFIG_BT_COEXIST + + return _SUCCESS; +} + +//Tx Page FIFO threshold +static void _init_available_page_threshold(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ) +{ + u16 HQ_threshold, NQ_threshold, LQ_threshold; + + HQ_threshold = (numPubQ + numHQ + 1) >> 1; + HQ_threshold |= (HQ_threshold<<8); + + NQ_threshold = (numPubQ + numNQ + 1) >> 1; + NQ_threshold |= (NQ_threshold<<8); + + LQ_threshold = (numPubQ + numLQ + 1) >> 1; + LQ_threshold |= (LQ_threshold<<8); + + rtw_write16(padapter, 0x218, HQ_threshold); + rtw_write16(padapter, 0x21A, NQ_threshold); + rtw_write16(padapter, 0x21C, LQ_threshold); + DBG_8192C("%s(): Enable Tx FIFO Page Threshold H:0x%x,N:0x%x,L:0x%x\n", __FUNCTION__, HQ_threshold, NQ_threshold, LQ_threshold); +} + +static void _InitQueueReservedPage(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + u32 outEPNum = (u32)pHalData->OutEpNumber; + u32 numHQ = 0; + u32 numLQ = 0; + u32 numNQ = 0; + u32 numPubQ; + u32 value32; + u8 value8; + BOOLEAN bWiFiConfig = pregistrypriv->wifi_spec; + + if (pHalData->OutEpQueueSel & TX_SELE_HQ) + { + numHQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_HPQ_8188F : NORMAL_PAGE_NUM_HPQ_8188F; + } + + if (pHalData->OutEpQueueSel & TX_SELE_LQ) + { + numLQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_LPQ_8188F : NORMAL_PAGE_NUM_LPQ_8188F; + } + + // NOTE: This step shall be proceed before writting REG_RQPN. + if (pHalData->OutEpQueueSel & TX_SELE_NQ) { + numNQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_NPQ_8188F : NORMAL_PAGE_NUM_NPQ_8188F; + } + + numPubQ = TX_TOTAL_PAGE_NUMBER_8188F - numHQ - numLQ - numNQ; + + value8 = (u8)_NPQ(numNQ); + rtw_write8(padapter, REG_RQPN_NPQ, value8); + + // TX DMA + value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; + rtw_write32(padapter, REG_RQPN, value32); + + rtw_hal_set_sdio_tx_max_length(padapter, numHQ, numNQ, numLQ, numPubQ); + +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + _init_available_page_threshold(padapter, numHQ, numNQ, numLQ, numPubQ); +#endif +} + +static void _InitTxBufferBoundary(PADAPTER padapter) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; +#ifdef CONFIG_CONCURRENT_MODE + u8 val8; +#endif // CONFIG_CONCURRENT_MODE + + //u16 txdmactrl; + u8 txpktbuf_bndy; + + if (!pregistrypriv->wifi_spec) { + txpktbuf_bndy = TX_PAGE_BOUNDARY_8188F; + } else { + //for WMM + txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_8188F; + } + + rtw_write8(padapter, REG_TXPKTBUF_BCNQ_BDNY_8188F, txpktbuf_bndy); + rtw_write8(padapter, REG_TXPKTBUF_MGQ_BDNY_8188F, txpktbuf_bndy); + rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD_8188F, txpktbuf_bndy); + rtw_write8(padapter, REG_TRXFF_BNDY, txpktbuf_bndy); + rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy); + +#ifdef CONFIG_CONCURRENT_MODE + val8 = txpktbuf_bndy + BCNQ_PAGE_NUM_8188F + WOWLAN_PAGE_NUM_8188F; + rtw_write8(padapter, REG_BCNQ1_BDNY, val8); + rtw_write8(padapter, REG_DWBCN1_CTRL_8188F+1, val8); // BCN1_HEAD + + val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8188F+2); + val8 |= BIT(1); // BIT1- BIT_SW_BCN_SEL_EN + rtw_write8(padapter, REG_DWBCN1_CTRL_8188F+2, val8); +#endif // CONFIG_CONCURRENT_MODE +} + +static VOID +_InitNormalChipRegPriority( + IN PADAPTER Adapter, + IN u16 beQ, + IN u16 bkQ, + IN u16 viQ, + IN u16 voQ, + IN u16 mgtQ, + IN u16 hiQ + ) +{ + u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7); + + value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | + _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | + _TXDMA_MGQ_MAP(mgtQ)| _TXDMA_HIQ_MAP(hiQ); + + rtw_write16(Adapter, REG_TRXDMA_CTRL, value16); +} + +static VOID +_InitNormalChipOneOutEpPriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + u16 value = 0; + switch(pHalData->OutEpQueueSel) + { + case TX_SELE_HQ: + value = QUEUE_HIGH; + break; + case TX_SELE_LQ: + value = QUEUE_LOW; + break; + case TX_SELE_NQ: + value = QUEUE_NORMAL; + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + _InitNormalChipRegPriority(Adapter, + value, + value, + value, + value, + value, + value + ); + +} + +static VOID +_InitNormalChipTwoOutEpPriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct registry_priv *pregistrypriv = &Adapter->registrypriv; + u16 beQ,bkQ,viQ,voQ,mgtQ,hiQ; + + + u16 valueHi = 0; + u16 valueLow = 0; + + switch(pHalData->OutEpQueueSel) + { + case (TX_SELE_HQ | TX_SELE_LQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_NQ | TX_SELE_LQ): + valueHi = QUEUE_NORMAL; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_HQ | TX_SELE_NQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_NORMAL; + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + if(!pregistrypriv->wifi_spec ){ + beQ = valueLow; + bkQ = valueLow; + viQ = valueHi; + voQ = valueHi; + mgtQ = valueHi; + hiQ = valueHi; + } + else{//for WMM ,CONFIG_OUT_EP_WIFI_MODE + beQ = valueLow; + bkQ = valueHi; + viQ = valueHi; + voQ = valueLow; + mgtQ = valueHi; + hiQ = valueHi; + } + + _InitNormalChipRegPriority(Adapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ); + +} + +static VOID +_InitNormalChipThreeOutEpPriority( + IN PADAPTER padapter + ) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; + + if (!pregistrypriv->wifi_spec){// typical setting + beQ = QUEUE_LOW; + bkQ = QUEUE_LOW; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } + else {// for WMM + beQ = QUEUE_LOW; + bkQ = QUEUE_NORMAL; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } + _InitNormalChipRegPriority(padapter,beQ,bkQ,viQ,voQ,mgtQ,hiQ); +} + +static VOID +_InitNormalChipQueuePriority( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + + switch(pHalData->OutEpNumber) + { + case 1: + _InitNormalChipOneOutEpPriority(Adapter); + break; + case 2: + _InitNormalChipTwoOutEpPriority(Adapter); + break; + case 3: + _InitNormalChipThreeOutEpPriority(Adapter); + break; + default: + //RT_ASSERT(FALSE,("Shall not reach here!\n")); + break; + } + + +} + +static void _InitQueuePriority(PADAPTER padapter) +{ + _InitNormalChipQueuePriority(padapter); +} + +static void _InitPageBoundary(PADAPTER padapter) +{ + // RX Page Boundary + u16 rxff_bndy = RX_DMA_BOUNDARY_8188F; + + rtw_write16(padapter, (REG_TRXFF_BNDY + 2), rxff_bndy); +} + +static void _InitTransferPageSize(PADAPTER padapter) +{ + // Tx page size is always 128. + + u8 value8; + value8 = _PSRX(PBP_128) | _PSTX(PBP_128); + rtw_write8(padapter, REG_PBP, value8); +} + +void _InitDriverInfoSize(PADAPTER padapter, u8 drvInfoSize) +{ + rtw_write8(padapter, REG_RX_DRVINFO_SZ, drvInfoSize); +} + +void _InitNetworkType(PADAPTER padapter) +{ + u32 value32; + + value32 = rtw_read32(padapter, REG_CR); + + // TODO: use the other function to set network type +// value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AD_HOC); + value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP); + + rtw_write32(padapter, REG_CR, value32); +} + +void _InitWMACSetting(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u16 value16; + + + pHalData = GET_HAL_DATA(padapter); + + pHalData->ReceiveConfig = 0; + pHalData->ReceiveConfig |= RCR_APM | RCR_AM | RCR_AB; + pHalData->ReceiveConfig |= RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_AMF; + pHalData->ReceiveConfig |= RCR_HTC_LOC_CTRL; + pHalData->ReceiveConfig |= RCR_APP_PHYST_RXFF | RCR_APP_ICV | RCR_APP_MIC; +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + pHalData->ReceiveConfig |= RCR_AAP; + pHalData->ReceiveConfig |= RCR_ADD3 | RCR_APWRMGT | RCR_ACRC32 | RCR_ADF; +#endif + rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig); + + // Accept all multicast address + rtw_write32(padapter, REG_MAR, 0xFFFFFFFF); + rtw_write32(padapter, REG_MAR + 4, 0xFFFFFFFF); + + // Accept all data frames + value16 = 0xFFFF; + rtw_write16(padapter, REG_RXFLTMAP2, value16); + + // 2010.09.08 hpfan + // Since ADF is removed from RCR, ps-poll will not be indicate to driver, + // RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll. + value16 = 0x400; + rtw_write16(padapter, REG_RXFLTMAP1, value16); + + // Accept all management frames + value16 = 0xFFFF; + rtw_write16(padapter, REG_RXFLTMAP0, value16); +} + +void _InitAdaptiveCtrl(PADAPTER padapter) +{ + u16 value16; + u32 value32; + + // Response Rate Set + value32 = rtw_read32(padapter, REG_RRSR); + value32 &= ~RATE_BITMAP_ALL; + value32 |= RATE_RRSR_CCK_ONLY_1M; + rtw_write32(padapter, REG_RRSR, value32); + + // CF-END Threshold + //m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1); + + // SIFS (used in NAV) + value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); + rtw_write16(padapter, REG_SPEC_SIFS, value16); + + // Retry Limit + value16 = _LRL(0x30) | _SRL(0x30); + rtw_write16(padapter, REG_RL, value16); +} + +void _InitEDCA(PADAPTER padapter) +{ + // Set Spec SIFS (used in NAV) + rtw_write16(padapter, REG_SPEC_SIFS, 0x100a); + rtw_write16(padapter, REG_MAC_SPEC_SIFS, 0x100a); + + // Set SIFS for CCK + rtw_write16(padapter, REG_SIFS_CTX, 0x100a); + + // Set SIFS for OFDM + rtw_write16(padapter, REG_SIFS_TRX, 0x100a); + + // TXOP + rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002FA226); + + rtw_write8(padapter, REG_USTIME_EDCA_8188F, 0x28); + rtw_write8(padapter, REG_USTIME_TSF_8188F, 0x28); +} + +void _InitRateFallback(PADAPTER padapter) +{ + // Set Data Auto Rate Fallback Retry Count register. + rtw_write32(padapter, REG_DARFRC, 0x00000000); + rtw_write32(padapter, REG_DARFRC+4, 0x10080404); + rtw_write32(padapter, REG_RARFRC, 0x04030201); + rtw_write32(padapter, REG_RARFRC+4, 0x08070605); + +} + +void _InitRetryFunction(PADAPTER padapter) +{ + u8 value8; + + value8 = rtw_read8(padapter, REG_FWHW_TXQ_CTRL); + value8 |= EN_AMPDU_RTY_NEW; + rtw_write8(padapter, REG_FWHW_TXQ_CTRL, value8); + + // Set ACK timeout + rtw_write8(padapter, REG_ACKTO, 0x40); +} + +static void HalRxAggr8188FSdio(PADAPTER padapter) +{ + u8 dma_time_th; + u8 dma_len_th; + + dma_time_th = 0x01; + dma_len_th = 0x0f; + + if (dma_len_th * 1024 > MAX_RECVBUF_SZ) { + DBG_871X_LEVEL(_drv_always_, "Reduce RXDMA_AGG_LEN_TH from %u to %u\n" + , dma_len_th, MAX_RECVBUF_SZ / 1024); + dma_len_th = MAX_RECVBUF_SZ / 1024; + } + + rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, (dma_time_th << 8) | dma_len_th); +} + +void sdio_AggSettingRxUpdate(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData; + u8 valueDMA; + u8 valueRxAggCtrl = 0; + u8 aggBurstNum = 3; //0:1, 1:2, 2:3, 3:4 + u8 aggBurstSize = 0; //0:1K, 1:512Byte, 2:256Byte... + + pHalData = GET_HAL_DATA(padapter); + + valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL); + valueDMA |= RXDMA_AGG_EN; + rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA); + + valueRxAggCtrl |= RXDMA_AGG_MODE_EN; + valueRxAggCtrl |= ((aggBurstNum<<2) & 0x0C); + valueRxAggCtrl |= ((aggBurstSize<<4) & 0x30); + rtw_write8(padapter, REG_RXDMA_MODE_CTRL_8188F, valueRxAggCtrl);//RxAggLowThresh = 4*1K +} + +void _initSdioAggregationSetting(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + // Tx aggregation setting +// sdio_AggSettingTxUpdate(padapter); + + // Rx aggregation setting + HalRxAggr8188FSdio(padapter); + + sdio_AggSettingRxUpdate(padapter); +} + +static void _RXAggrSwitch(PADAPTER padapter, u8 enable) +{ + PHAL_DATA_TYPE pHalData; + u8 valueDMA; + u8 valueRxAggCtrl; + + + pHalData = GET_HAL_DATA(padapter); + + valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL); + valueRxAggCtrl = rtw_read8(padapter, REG_RXDMA_MODE_CTRL_8188F); + + if (_TRUE == enable) + { + valueDMA |= RXDMA_AGG_EN; + valueRxAggCtrl |= RXDMA_AGG_MODE_EN; + } + else + { + valueDMA &= ~RXDMA_AGG_EN; + valueRxAggCtrl &= ~RXDMA_AGG_MODE_EN; + } + + rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA); + rtw_write8(padapter, REG_RXDMA_MODE_CTRL_8188F, valueRxAggCtrl); +} + +void _InitOperationMode(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + struct mlme_ext_priv *pmlmeext; + u8 regBwOpMode = 0; + u32 regRATR = 0, regRRSR = 0; + u8 MinSpaceCfg = 0; + + + pHalData = GET_HAL_DATA(padapter); + pmlmeext = &padapter->mlmeextpriv; + + //1 This part need to modified according to the rate set we filtered!! + // + // Set RRSR, RATR, and REG_BWOPMODE registers + // + switch(pmlmeext->cur_wireless_mode) + { + case WIRELESS_MODE_B: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK; + regRRSR = RATE_ALL_CCK; + break; + case WIRELESS_MODE_A: +// RT_ASSERT(FALSE,("Error wireless a mode\n")); +#if 0 + regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ; + regRATR = RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_OFDM_AG; +#endif + break; + case WIRELESS_MODE_G: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_AUTO: +#if 0 + if (padapter->bInHctTest) + { + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + } + else +#endif + { + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + } + break; + case WIRELESS_MODE_N_24G: + // It support CCK rate by default. + // CCK rate will be filtered out only when associated AP does not support it. + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_N_5G: +// RT_ASSERT(FALSE,("Error wireless mode")); +#if 0 + regBwOpMode = BW_OPMODE_5G; + regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_OFDM_AG; +#endif + break; + + default: //for MacOSX compiler warning. + break; + } + + rtw_write8(padapter, REG_BWOPMODE, regBwOpMode); + +} + +void _InitInterrupt(PADAPTER padapter) +{ + // + // Initialize and enable SDIO Host Interrupt. + // + InitInterrupt8188FSdio(padapter); + + // + // Initialize system Host Interrupt. + // + InitSysInterrupt8188FSdio(padapter); +} + +void _InitRDGSetting(PADAPTER padapter) +{ + rtw_write8(padapter, REG_RD_CTRL, 0xFF); + rtw_write16(padapter, REG_RD_NAV_NXT, 0x200); + rtw_write8(padapter, REG_RD_RESP_PKT_TH, 0x05); +} + +static void _InitRFType(PADAPTER padapter) +{ + struct registry_priv *pregpriv = &padapter->registrypriv; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + +#if DISABLE_BB_RF + pHalData->rf_chip = RF_PSEUDO_11N; + return; +#endif + pHalData->rf_chip = RF_6052; + + MSG_8192C("Set RF Chip ID to RF_6052 and RF type to %d.\n", pHalData->rf_type); +} + +// Set CCK and OFDM Block "ON" +static void _BBTurnOnBlock(PADAPTER padapter) +{ +#if (DISABLE_BB_RF) + return; +#endif + + PHY_SetBBReg(padapter, rFPGA0_RFMOD, bCCKEn, 0x1); + PHY_SetBBReg(padapter, rFPGA0_RFMOD, bOFDMEn, 0x1); +} + +static void _RfPowerSave(PADAPTER padapter) +{ +//YJ,TODO +} + +static void _InitAntenna_Selection(PADAPTER padapter) +{ + rtw_write8(padapter, REG_LEDCFG2, 0x82); +} + +static void _InitPABias(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 pa_setting; + + //FIXED PA current issue + //efuse_one_byte_read(padapter, 0x1FA, &pa_setting); + pa_setting = EFUSE_Read1Byte(padapter, 0x1FA); + + //RT_TRACE(COMP_INIT, DBG_LOUD, ("_InitPABias 0x1FA 0x%x \n",pa_setting)); + + if(!(pa_setting & BIT0)) + { + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x0F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x4F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0x8F406); + PHY_SetRFReg(padapter, RF_PATH_A, 0x15, 0x0FFFFF, 0xCF406); + //RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path A\n")); + } + + if(!(pa_setting & BIT4)) + { + pa_setting = rtw_read8(padapter, 0x16); + pa_setting &= 0x0F; + rtw_write8(padapter, 0x16, pa_setting | 0x80); + rtw_write8(padapter, 0x16, pa_setting | 0x90); + } +} + +// +// 2010/08/09 MH Add for power down check. +// +static BOOLEAN HalDetectPwrDownMode(PADAPTER Adapter) +{ + u8 tmpvalue; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter); + + + EFUSE_ShadowRead(Adapter, 1, 0x7B/*EEPROM_RF_OPT3_92C*/, (u32 *)&tmpvalue); + + // 2010/08/25 MH INF priority > PDN Efuse value. + if(tmpvalue & BIT4 && pwrctrlpriv->reg_pdnmode) + { + pHalData->pwrdown = _TRUE; + } + else + { + pHalData->pwrdown = _FALSE; + } + + DBG_8192C("HalDetectPwrDownMode(): PDN=%d\n", pHalData->pwrdown); + + return pHalData->pwrdown; +} // HalDetectPwrDownMode + +static u32 rtl8188fs_hal_init(PADAPTER padapter) +{ + s32 ret; + PHAL_DATA_TYPE pHalData; + struct pwrctrl_priv *pwrctrlpriv; + struct registry_priv *pregistrypriv; + struct sreset_priv *psrtpriv; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + rt_rf_power_state eRfPowerStateToSet; + u32 NavUpper = WiFiNavUpperUs; + u8 u1bTmp; + u16 value16; + u8 typeid; + u32 u4Tmp; + + pHalData = GET_HAL_DATA(padapter); + psrtpriv = &pHalData->srestpriv; + pwrctrlpriv = adapter_to_pwrctl(padapter); + pregistrypriv = &padapter->registrypriv; + +#ifdef CONFIG_SWLPS_IN_IPS + if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE) + { + u8 val8, bMacPwrCtrlOn = _TRUE; + + DBG_871X("%s: run LPS flow in IPS\n", __FUNCTION__); + + //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); + + adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80; + + rtw_mdelay_os(5); //wait set rpwm already + + ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8188F_leave_swlps_flow); + if (ret == _FALSE) { + DBG_8192C("%s: run LPS flow in IPS fail!\n", __FUNCTION__); + return _FAIL; + } + + rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + + pHalData->LastHMEBoxNum = 0; + + + return _SUCCESS; + } +#elif defined(CONFIG_FWLPS_IN_IPS) + if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE + && adapter_to_pwrctl(padapter)->pre_ips_type == 0) + { + u32 start_time; + u8 cpwm_orig, cpwm_now; + u8 val8, bMacPwrCtrlOn = _TRUE; + + DBG_871X("%s: Leaving IPS in FWLPS state\n", __FUNCTION__); + + //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); + + rtl8188f_set_FwPwrModeInIPS_cmd(padapter, 0); + + rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + + +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("after hal init, fw ps state in 32k\n"); + pdbgpriv->dbg_ips_drvopen_fail_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + return _SUCCESS; + } +#endif //CONFIG_SWLPS_IN_IPS + + // Disable Interrupt first. +// rtw_hal_disable_interrupt(padapter); + + if(rtw_read8(padapter, REG_MCUFWDL) == 0xc6) { + DBG_871X("FW exist before power on!!\n"); + } else { + DBG_871X("FW does not exist before power on!!\n"); + } + + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("check fw_ps_state fail before PowerOn!\n"); + pdbgpriv->dbg_ips_drvopen_fail_cnt++; + } + + ret = rtw_hal_power_on(padapter); + if (_FAIL == ret) { + RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init Power On!\n")); + return _FAIL; + } + DBG_871X("Power on ok!\n"); + + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("check fw_ps_state fail after PowerOn!\n"); + pdbgpriv->dbg_ips_drvopen_fail_cnt++; + } + + + rtw_write8(padapter, REG_EARLY_MODE_CONTROL, 0); + + if (padapter->registrypriv.mp_mode == 0) { + ret = rtl8188f_FirmwareDownload(padapter, _FALSE); + if (ret != _SUCCESS) { + RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: Download Firmware failed!!\n", __FUNCTION__)); + padapter->bFWReady = _FALSE; + pHalData->fw_ractrl = _FALSE; + return ret; + } else { + RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("rtl8188fs_hal_init(): Download Firmware Success!!\n")); + padapter->bFWReady = _TRUE; + pHalData->fw_ractrl = _TRUE; + } + } + + rtl8188f_InitializeFirmwareVars(padapter); + +// SIC_Init(padapter); + + if (pwrctrlpriv->reg_rfoff == _TRUE) { + pwrctrlpriv->rf_pwrstate = rf_off; + } + + // 2010/08/09 MH We need to check if we need to turnon or off RF after detecting + // HW GPIO pin. Before PHY_RFConfig8192C. + HalDetectPwrDownMode(padapter); + + // Set RF type for BB/RF configuration + _InitRFType(padapter); + + // Save target channel + // Current Channel will be updated again later. + pHalData->CurrentChannel = 6; + +#if (HAL_MAC_ENABLE == 1) + ret = PHY_MACConfig8188F(padapter); + if(ret != _SUCCESS){ + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure MAC!!\n")); + return ret; + } +#endif + // + //d. Initialize BB related configurations. + // +#if (HAL_BB_ENABLE == 1) + ret = PHY_BBConfig8188F(padapter); + if(ret != _SUCCESS){ + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure BB!!\n")); + return ret; + } +#endif + + // If RF is on, we need to init RF. Otherwise, skip the procedure. + // We need to follow SU method to change the RF cfg.txt. Default disable RF TX/RX mode. + //if(pHalData->eRFPowerState == eRfOn) + { +#if (HAL_RF_ENABLE == 1) + ret = PHY_RFConfig8188F(padapter); + if(ret != _SUCCESS){ + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure RF!!\n")); + return ret; + } +#endif + } + + // + // Joseph Note: Keep RfRegChnlVal for later use. + // + pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(padapter, (RF_PATH)0, RF_CHNLBW, bRFRegOffsetMask); + pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(padapter, (RF_PATH)1, RF_CHNLBW, bRFRegOffsetMask); + + + //if (!pHalData->bMACFuncEnable) { + _InitQueueReservedPage(padapter); + _InitTxBufferBoundary(padapter); + + // init LLT after tx buffer boundary is defined + ret = rtl8188f_InitLLTTable(padapter); + if (_SUCCESS != ret) + { + DBG_8192C("%s: Failed to init LLT Table!\n", __FUNCTION__); + return _FAIL; + } + //} + _InitQueuePriority(padapter); + _InitPageBoundary(padapter); + _InitTransferPageSize(padapter); + + // Get Rx PHY status in order to report RSSI and others. + _InitDriverInfoSize(padapter, DRVINFO_SZ); + hal_init_macaddr(padapter); + _InitNetworkType(padapter); + _InitWMACSetting(padapter); + _InitAdaptiveCtrl(padapter); + _InitEDCA(padapter); + //_InitRateFallback(padapter); + _InitRetryFunction(padapter); + _initSdioAggregationSetting(padapter); + _InitOperationMode(padapter); + rtl8188f_InitBeaconParameters(padapter); + rtl8188f_InitBeaconMaxError(padapter, _TRUE); + _InitInterrupt(padapter); + _InitBurstPktLen_8188FS(padapter); + + //YJ,TODO + rtw_write8(padapter, REG_SECONDARY_CCA_CTRL_8188F, 0x3); // CCA + rtw_write8(padapter, 0x976, 0); // hpfan_todo: 2nd CCA related + +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_TX_MCAST2UNI) + +#ifdef CONFIG_CHECK_AC_LIFETIME + // Enable lifetime check for the four ACs + rtw_write8(padapter, REG_LIFETIME_EN, 0x0F); +#endif // CONFIG_CHECK_AC_LIFETIME + +#ifdef CONFIG_TX_MCAST2UNI + rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); // unit: 256us. 256ms + rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); // unit: 256us. 256ms +#else // CONFIG_TX_MCAST2UNI + rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x3000); // unit: 256us. 3s + rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x3000); // unit: 256us. 3s +#endif // CONFIG_TX_MCAST2UNI +#endif // CONFIG_CONCURRENT_MODE || CONFIG_TX_MCAST2UNI + + + invalidate_cam_all(padapter); + + rtw_hal_set_chnl_bw(padapter, padapter->registrypriv.channel, + CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HAL_PRIME_CHNL_OFFSET_DONT_CARE); + + // Record original value for template. This is arough data, we can only use the data + // for power adjust. The value can not be adjustde according to different power!!! +// pHalData->OriginalCckTxPwrIdx = pHalData->CurrentCckTxPwrIdx; +// pHalData->OriginalOfdm24GTxPwrIdx = pHalData->CurrentOfdm24GTxPwrIdx; + + rtl8188f_InitAntenna_Selection(padapter); + + // + // Disable BAR, suggested by Scott + // 2010.04.09 add by hpfan + // + rtw_write32(padapter, REG_BAR_MODE_CTRL, 0x0201ffff); + + // HW SEQ CTRL + // set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. + rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); + + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN); + u1bTmp &= ~(FEN_BBRSTB|FEN_BB_GLB_RSTn); + rtw_write8(padapter, REG_SYS_FUNC_EN,u1bTmp); + + rtw_write8(padapter, REG_RD_CTRL, 0x0F); + rtw_write8(padapter, REG_RD_CTRL+1, 0xCF); + rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD_8188F, 0x80); + rtw_write32(padapter, REG_CR, 0x0b0202ff); +#endif + + /* + * onfigure SDIO TxRx Control to enable Rx DMA timer masking. + * 2010.02.24. + * Only clear necessary bits 0x0[2:0] and 0x2[15:0] and keep 0x0[15:3] + * 2015.03.19. + */ + u4Tmp = rtw_read32(padapter, SDIO_LOCAL_BASE|SDIO_REG_TX_CTRL); + u4Tmp &= 0x0000FFF8; + rtw_write32(padapter, SDIO_LOCAL_BASE|SDIO_REG_TX_CTRL, u4Tmp); + + _RfPowerSave(padapter); + + rtl8188f_InitHalDm(padapter); + + //DbgPrint("pHalData->DefaultTxPwrDbm = %d\n", pHalData->DefaultTxPwrDbm); + +// if(pHalData->SwBeaconType < HAL92CSDIO_DEFAULT_BEACON_TYPE) // The lowest Beacon Type that HW can support +// pHalData->SwBeaconType = HAL92CSDIO_DEFAULT_BEACON_TYPE; + + // + // Update current Tx FIFO page status. + // + HalQueryTxBufferStatus8188FSdio(padapter); + HalQueryTxOQTBufferStatus8188FSdio(padapter); + pHalData->SdioTxOQTMaxFreeSpace = pHalData->SdioTxOQTFreeSpace; + + // Enable MACTXEN/MACRXEN block + u1bTmp = rtw_read8(padapter, REG_CR); + u1bTmp |= (MACTXEN | MACRXEN); + rtw_write8(padapter, REG_CR, u1bTmp); + + rtw_hal_set_hwreg(padapter, HW_VAR_NAV_UPPER, (u8*)&NavUpper); + +#ifdef CONFIG_XMIT_ACK + //ack for xmit mgmt frames. + rtw_write32(padapter, REG_FWHW_TXQ_CTRL, rtw_read32(padapter, REG_FWHW_TXQ_CTRL)|BIT(12)); +#endif //CONFIG_XMIT_ACK + +// pHalData->PreRpwmVal = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HRPWM1) & 0x80; + +#if (MP_DRIVER == 1) + if (padapter->registrypriv.mp_mode == 1) + { + padapter->mppriv.channel = pHalData->CurrentChannel; + MPT_InitializeAdapter(padapter, padapter->mppriv.channel); + } + else +#endif //#if (MP_DRIVER == 1) + { + pwrctrlpriv->rf_pwrstate = rf_on; + + if(pwrctrlpriv->rf_pwrstate == rf_on) + { + struct pwrctrl_priv *pwrpriv; + u32 start_time; + u8 restore_iqk_rst; + u8 b2Ant; + u8 h2cCmdBuf; + + pwrpriv = adapter_to_pwrctl(padapter); + + PHY_LCCalibrate_8188F(&pHalData->odmpriv); + + /* Inform WiFi FW that it is the beginning of IQK */ + h2cCmdBuf = 1; + FillH2CCmd8188F(padapter, H2C_8188F_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf); + + start_time = rtw_get_current_time(); + do { + if (rtw_read8(padapter, 0x1e7) & 0x01) + break; + + rtw_msleep_os(50); + } while (rtw_get_passing_time_ms(start_time) <= 400); + + restore_iqk_rst = (pwrpriv->bips_processing==_TRUE)?_TRUE:_FALSE; + PHY_IQCalibrate_8188F(padapter, _FALSE, restore_iqk_rst); + pHalData->bIQKInitialized = _TRUE; + + /* Inform WiFi FW that it is the finish of IQK */ + h2cCmdBuf = 0; + FillH2CCmd8188F(padapter, H2C_8188F_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf); + + ODM_TXPowerTrackingCheck(&pHalData->odmpriv); + } + } + + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("-%s\n", __FUNCTION__)); + + return _SUCCESS; +} + +// +// Description: +// RTL8188e card disable power sequence v003 which suggested by Scott. +// +// First created by tynli. 2011.01.28. +// +static void CardDisableRTL8188FSdio(PADAPTER padapter) +{ + u8 u1bTmp; + u16 u2bTmp; + u32 u4bTmp; + u8 bMacPwrCtrlOn; + u8 hci_sus_state; + u8 ret = _FAIL; + + // Run LPS WL RFOFF flow + ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8188F_enter_lps_flow); + if (ret == _FAIL) { + DBG_8192C(KERN_ERR "%s: run RF OFF flow fail!\n", __func__); + } + + // ==== Reset digital sequence ====== + + u1bTmp = rtw_read8(padapter, REG_MCUFWDL); + if ((u1bTmp & RAM_DL_SEL) && padapter->bFWReady) //8051 RAM code + rtl8188f_FirmwareSelfReset(padapter); + + // Reset MCU 0x2[10]=0. Suggested by Filen. 2011.01.26. by tynli. + u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1); + u1bTmp &= ~BIT(2); // 0x2[10], FEN_CPUEN + rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp); + + // MCUFWDL 0x80[1:0]=0 + // reset MCU ready status + rtw_write8(padapter, REG_MCUFWDL, 0); + + // Reset MCU IO Wrapper, added by Roger, 2011.08.30 + +//derek mod for reg 0x1d +// u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1); +// u1bTmp &= ~BIT(0); +// rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp); +// u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1); +// u1bTmp |= BIT(0); +// rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp); + + // ==== Reset digital sequence end ====== + + bMacPwrCtrlOn = _FALSE; // Disable CMD53 R/W + ret = _FALSE; + rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + hci_sus_state = HCI_SUS_ENTERING; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8188F_card_disable_flow); + if (ret == _FALSE) { + hci_sus_state = HCI_SUS_ERR; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + DBG_8192C(KERN_ERR "%s: run CARD DISABLE flow fail!\n", __func__); + } else { + hci_sus_state = HCI_SUS_ENTER; + rtw_hal_set_hwreg(padapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + } + + padapter->bFWReady = _FALSE; +} + +static u32 rtl8188fs_hal_deinit(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + MPT_DeInitAdapter(padapter); +#endif + + if (rtw_is_hw_init_completed(padapter)) { +#ifdef CONFIG_SWLPS_IN_IPS + if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE) + { + u8 bMacPwrCtrlOn; + u8 ret = _TRUE; + + DBG_871X("%s: run LPS flow in IPS\n", __FUNCTION__); + + rtw_write32(padapter, 0x130, 0x0); + rtw_write32(padapter, 0x138, 0x100); + rtw_write8(padapter, 0x13d, 0x1); + + + bMacPwrCtrlOn = _FALSE; // Disable CMD53 R/W + rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + + ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8188F_enter_swlps_flow); + if (ret == _FALSE) { + DBG_8192C("%s: run LPS flow in IPS fail!\n", __FUNCTION__); + return _FAIL; + } + } + else +#elif defined(CONFIG_FWLPS_IN_IPS) + if (adapter_to_pwrctl(padapter)->bips_processing == _TRUE && psrtpriv->silent_reset_inprogress == _FALSE) + { + if(padapter->netif_up == _TRUE) + { + int cnt=0; + u8 val8 = 0; + + DBG_871X("%s: issue H2C to FW when entering IPS\n", __FUNCTION__); + + rtl8188f_set_FwPwrModeInIPS_cmd(padapter, 0x3); + //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", __FUNCTION__, 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); + 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", __FUNCTION__, val8, cnt); + rtw_mdelay_os(10); + }while(cnt<100 && (val8!=0xEA)); +#ifdef DBG_CHECK_FW_PS_STATE + if(val8 != 0xEA) + 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)); + } + + DBG_871X("polling done when entering IPS, check result : 0x100=0x%x, cnt=%d, MAC_1cc=0x%02x\n" + , rtw_read8(padapter, REG_CR), cnt, rtw_read8(padapter, REG_HMETFR)); + + adapter_to_pwrctl(padapter)->pre_ips_type = 0; + + } + else + { + pdbgpriv->dbg_carddisable_cnt++; +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("card disable should leave 32k\n"); + pdbgpriv->dbg_carddisable_error_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + rtw_hal_power_off(padapter); + + adapter_to_pwrctl(padapter)->pre_ips_type = 1; + } + + } + else +#endif //CONFIG_SWLPS_IN_IPS + { + pdbgpriv->dbg_carddisable_cnt++; +#ifdef DBG_CHECK_FW_PS_STATE + if(rtw_fw_ps_state(padapter) == _FAIL) + { + DBG_871X("card disable should leave 32k\n"); + pdbgpriv->dbg_carddisable_error_cnt++; + } +#endif //DBG_CHECK_FW_PS_STATE + rtw_hal_power_off(padapter); + } + } + else + { + pdbgpriv->dbg_deinit_fail_cnt++; + } + + return _SUCCESS; +} +static void rtl8188fs_init_default_value(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + + rtl8188f_init_default_value(padapter); + + // interface related variable + pHalData->SdioRxFIFOCnt = 0; +} + +static void rtl8188fs_interface_configure(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + BOOLEAN bWiFiConfig = pregistrypriv->wifi_spec; + + + pdvobjpriv->RtOutPipe[0] = WLAN_TX_HIQ_DEVICE_ID; + pdvobjpriv->RtOutPipe[1] = WLAN_TX_MIQ_DEVICE_ID; + pdvobjpriv->RtOutPipe[2] = WLAN_TX_LOQ_DEVICE_ID; + + if (bWiFiConfig) + pHalData->OutEpNumber = 2; + else + pHalData->OutEpNumber = SDIO_MAX_TX_QUEUE; + + switch(pHalData->OutEpNumber){ + case 3: + pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_LQ|TX_SELE_NQ; + break; + case 2: + pHalData->OutEpQueueSel=TX_SELE_HQ| TX_SELE_NQ; + break; + case 1: + pHalData->OutEpQueueSel=TX_SELE_HQ; + break; + default: + break; + } + + Hal_MappingOutPipe(padapter, pHalData->OutEpNumber); +} + +// +// Description: +// We should set Efuse cell selection to WiFi cell in default. +// +// Assumption: +// PASSIVE_LEVEL +// +// Added by Roger, 2010.11.23. +// +static void +_EfuseCellSel( + IN PADAPTER padapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + u32 value32; + + //if(INCLUDE_MULTI_FUNC_BT(padapter)) + { + value32 = rtw_read32(padapter, EFUSE_TEST); + value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); + rtw_write32(padapter, EFUSE_TEST, value32); + } +} + +static VOID +_ReadRFType( + IN PADAPTER Adapter + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + +#if DISABLE_BB_RF + pHalData->rf_chip = RF_PSEUDO_11N; +#else + pHalData->rf_chip = RF_6052; +#endif +} + +static VOID +_ReadEfuseInfo8188FS( + IN PADAPTER padapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8* hwinfo = NULL; + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("====>_ReadEfuseInfo8188FS()\n")); + + // + // This part read and parse the eeprom/efuse content + // + + if (sizeof(pHalData->efuse_eeprom_data) < HWSET_MAX_SIZE_8188F) + DBG_871X("[WARNING] size of efuse_eeprom_data is less than HWSET_MAX_SIZE_8188F!\n"); + + hwinfo = pHalData->efuse_eeprom_data; + + Hal_InitPGData(padapter, hwinfo); + + Hal_EfuseParseIDCode(padapter, hwinfo); + Hal_EfuseParseEEPROMVer_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + hal_config_macaddr(padapter, pHalData->bautoload_fail_flag); + Hal_EfuseParseTxPowerInfo_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + //Hal_EfuseParseBoardType_8188FS(padapter, hwinfo, pHalData->bautoload_fail_flag); + + // + // Read Bluetooth co-exist and initialize + // + //Hal_EfuseParseBTCoexistInfo_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseChnlPlan_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseXtal_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseThermalMeter_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseAntennaDiversity_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseCustomerID_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + + //Hal_EfuseParseVoltage_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + Hal_DetectWoWMode(padapter); +#endif + + Hal_EfuseParseKFreeData_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + Hal_EfuseParseMacHidden_8188F(padapter, hwinfo, pHalData->bautoload_fail_flag); + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==== _ReadEfuseInfo8188FS()\n")); +} + +static void _ReadPROMContent( + IN PADAPTER padapter + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + u8 eeValue; + + eeValue = rtw_read8(padapter, REG_9346CR); + // To check system boot selection. + pHalData->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? _TRUE : _FALSE; + pHalData->bautoload_fail_flag = (eeValue & EEPROM_EN) ? _FALSE : _TRUE; + + RT_TRACE(_module_hci_hal_init_c_, _drv_info_, + ("%s: 9346CR=0x%02X, Boot from %s, Autoload %s\n", + __FUNCTION__, eeValue, + (pHalData->EepromOrEfuse ? "EEPROM" : "EFUSE"), + (pHalData->bautoload_fail_flag ? "Fail" : "OK"))); + +// pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; + + _ReadEfuseInfo8188FS(padapter); +} + +// +// Description: +// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported. +// +// Assumption: +// PASSIVE_LEVEL (SDIO interface) +// +// +static void ReadAdapterInfo8188FS(PADAPTER padapter) +{ + /* Read EEPROM size before call any EEPROM function */ + padapter->EepromAddressSize = GetEEPROMSize8188F(padapter); + + _EfuseCellSel(padapter); + _ReadRFType(padapter); + _ReadPROMContent(padapter); +} + +/* + * If variable not handled here, + * some variables will be processed in SetHwReg8188F() + */ +void SetHwReg8188FS(PADAPTER padapter, u8 variable, u8 *val) +{ + PHAL_DATA_TYPE pHalData; + u8 val8; + +_func_enter_; + + pHalData = GET_HAL_DATA(padapter); + + switch (variable) + { + case HW_VAR_SET_RPWM: + // rpwm value only use BIT0(clock bit) ,BIT6(Ack bit), and BIT7(Toggle bit) + // BIT0 value - 1: 32k, 0:40MHz. + // BIT6 value - 1: report cpwm value after success set, 0:do not report. + // BIT7 value - Toggle bit change. + { + val8 = *val; + val8 &= 0xC1; + rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8); + } + break; + case HW_VAR_SET_REQ_FW_PS: + //1. driver write 0x8f[4]=1 //request fw ps state (only can write bit4) + { + u8 req_fw_ps=0; + req_fw_ps = rtw_read8(padapter, 0x8f); + req_fw_ps |= 0x10; + rtw_write8(padapter, 0x8f, req_fw_ps); + } + break; + case HW_VAR_RXDMA_AGG_PG_TH: + val8 = *val; + + // TH=1 => invalidate RX DMA aggregation + // TH=0 => validate RX DMA aggregation, use init value. + if (val8 == 0) + { + // enable RXDMA aggregation + //_RXAggrSwitch(padapter, _TRUE); + } + else + { + // disable RXDMA aggregation + //_RXAggrSwitch(padapter, _FALSE); + } + break; + case HW_VAR_DM_IN_LPS: + rtl8188f_hal_dm_in_lps(padapter); + break; + default: + SetHwReg8188F(padapter, variable, val); + break; + } + +_func_exit_; +} + +/* + * If variable not handled here, + * some variables will be processed in GetHwReg8188F() + */ +void GetHwReg8188FS(PADAPTER padapter, u8 variable, u8 *val) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + +_func_enter_; + + switch (variable) + { + case HW_VAR_CPWM: + *val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HCPWM1_8188F); + break; + + case HW_VAR_FW_PS_STATE: + { + //3. read dword 0x88 //driver read fw ps state + *((u16*)val) = rtw_read16(padapter, 0x88); + } + break; + default: + GetHwReg8188F(padapter, variable, val); + break; + } + +_func_exit_; +} + +// +// Description: +// Query setting of specified variable. +// +u8 +GetHalDefVar8188FSDIO( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + u8 bResult = _SUCCESS; + + switch(eVariable) + { + case HAL_DEF_IS_SUPPORT_ANT_DIV: +#ifdef CONFIG_ANTENNA_DIVERSITY + *((u8 *)pValue) = _FALSE; +#endif + break; + case HAL_DEF_CURRENT_ANTENNA: +#ifdef CONFIG_ANTENNA_DIVERSITY + *(( u8*)pValue) = pHalData->CurAntenna; +#endif + break; + case HW_VAR_MAX_RX_AMPDU_FACTOR: + // Stanley@BB.SD3 suggests 16K can get stable performance + // coding by Lucas@20130730 + *(HT_CAP_AMPDU_FACTOR*)pValue = MAX_AMPDU_FACTOR_16K; + break; + default: + bResult = GetHalDefVar8188F(Adapter, eVariable, pValue); + break; + } + + return bResult; +} + +// +// Description: +// Change default setting of specified variable. +// +u8 +SetHalDefVar8188FSDIO( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ) +{ + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter); + u8 bResult = _SUCCESS; + + switch(eVariable) + { + default: + bResult = SetHalDefVar8188F(Adapter, eVariable, pValue); + break; + } + + return bResult; +} + +void rtl8188fs_set_hal_ops(PADAPTER padapter) +{ + struct hal_ops *pHalFunc = &padapter->HalFunc; + +_func_enter_; + + rtl8188f_set_hal_ops(pHalFunc); + + pHalFunc->hal_power_on = &_InitPowerOn_8188FS; + pHalFunc->hal_power_off = &CardDisableRTL8188FSdio; + + pHalFunc->hal_init = &rtl8188fs_hal_init; + pHalFunc->hal_deinit = &rtl8188fs_hal_deinit; + + pHalFunc->init_xmit_priv = &rtl8188fs_init_xmit_priv; + pHalFunc->free_xmit_priv = &rtl8188fs_free_xmit_priv; + + pHalFunc->init_recv_priv = &rtl8188fs_init_recv_priv; + pHalFunc->free_recv_priv = &rtl8188fs_free_recv_priv; + + pHalFunc->InitSwLeds = &rtl8188fs_InitSwLeds; + pHalFunc->DeInitSwLeds = &rtl8188fs_DeInitSwLeds; + + pHalFunc->init_default_value = &rtl8188fs_init_default_value; + pHalFunc->intf_chip_configure = &rtl8188fs_interface_configure; + pHalFunc->read_adapter_info = &ReadAdapterInfo8188FS; + + pHalFunc->enable_interrupt = &EnableInterrupt8188FSdio; + pHalFunc->disable_interrupt = &DisableInterrupt8188FSdio; + pHalFunc->check_ips_status = &CheckIPSStatus; + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + pHalFunc->clear_interrupt = &ClearInterrupt8188FSdio; +#endif + pHalFunc->SetHwRegHandler = &SetHwReg8188FS; + pHalFunc->GetHwRegHandler = &GetHwReg8188FS; + pHalFunc->GetHalDefVarHandler = &GetHalDefVar8188FSDIO; + pHalFunc->SetHalDefVarHandler = &SetHalDefVar8188FSDIO; + + pHalFunc->hal_xmit = &rtl8188fs_hal_xmit; + pHalFunc->mgnt_xmit = &rtl8188fs_mgnt_xmit; + pHalFunc->hal_xmitframe_enqueue = &rtl8188fs_hal_xmitframe_enqueue; + +#ifdef CONFIG_HOSTAPD_MLME + pHalFunc->hostap_mgnt_xmit_entry = NULL; +#endif + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) + pHalFunc->hal_init_checkbthang_workqueue = &rtl8188fs_init_checkbthang_workqueue; + pHalFunc->hal_free_checkbthang_workqueue = &rtl8188fs_free_checkbthang_workqueue; + pHalFunc->hal_cancle_checkbthang_workqueue = &rtl8188fs_cancle_checkbthang_workqueue; + pHalFunc->hal_checke_bt_hang = &rtl8188fs_hal_check_bt_hang; +#endif + +_func_exit_; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c new file mode 100644 index 00000000..316f0276 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/hal/rtl8188f/sdio/sdio_ops.c @@ -0,0 +1,2350 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + *******************************************************************************/ +#define _SDIO_OPS_C_ + +#include + +//#define SDIO_DEBUG_IO 1 + +#define SDIO_LOCAL_CMD_ADDR(addr) ((SDIO_LOCAL_DEVICE_ID << 13) | ((addr) & SDIO_LOCAL_MSK)) +#define WLAN_IOREG_CMD_ADDR(addr) ((WLAN_IOREG_DEVICE_ID << 13) | ((addr) & WLAN_IOREG_MSK)) +#define WLAN_TXHIQ_CMD_ADDR(r4_cnt) ((WLAN_TX_HIQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK)) +#define WLAN_TXMIQ_CMD_ADDR(r4_cnt) ((WLAN_TX_MIQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK)) +#define WLAN_TXLOQ_CMD_ADDR(r4_cnt) ((WLAN_TX_LOQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK)) +#define WLAN_TXEXQ_CMD_ADDR(r4_cnt) ((WLAN_TX_EXQ_DEVICE_ID << 13) | ((r4_cnt) & WLAN_FIFO_MSK)) +#define WLAN_RX0FF_CMD_ADDR(seq) ((WLAN_RX0FF_DEVICE_ID << 13) | ((seq) & WLAN_RX0FF_MSK)) + +// +// Description: +// The following mapping is for SDIO host local register space. +// +// Creadted by Roger, 2011.01.31. +// +static void HalSdioGetCmdAddr8188FSdio( + IN PADAPTER padapter, + IN u8 DeviceID, + IN u32 Addr, + OUT u32* pCmdAddr + ) +{ + switch (DeviceID) + { + case SDIO_LOCAL_DEVICE_ID: + *pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK)); + break; + + case WLAN_IOREG_DEVICE_ID: + *pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK)); + break; + + case WLAN_TX_HIQ_DEVICE_ID: + *pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + break; + + case WLAN_TX_MIQ_DEVICE_ID: + *pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + break; + + case WLAN_TX_LOQ_DEVICE_ID: + *pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + break; + + case WLAN_RX0FF_DEVICE_ID: + *pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK)); + break; + + default: + break; + } +} + +static u8 get_deviceid(u32 addr) +{ + u8 devideId; + u16 pseudoId; + + + pseudoId = (u16)(addr >> 16); + switch (pseudoId) + { + case 0x1025: + devideId = SDIO_LOCAL_DEVICE_ID; + break; + + case 0x1026: + devideId = WLAN_IOREG_DEVICE_ID; + break; + +// case 0x1027: +// devideId = SDIO_FIRMWARE_FIFO; +// break; + + case 0x1031: + devideId = WLAN_TX_HIQ_DEVICE_ID; + break; + + case 0x1032: + devideId = WLAN_TX_MIQ_DEVICE_ID; + break; + + case 0x1033: + devideId = WLAN_TX_LOQ_DEVICE_ID; + break; + + case 0x1034: + devideId = WLAN_RX0FF_DEVICE_ID; + break; + + default: +// devideId = (u8)((addr >> 13) & 0xF); + devideId = WLAN_IOREG_DEVICE_ID; + break; + } + + return devideId; +} + +/* + * Ref: + * HalSdioGetCmdAddr8188FSdio() + */ +static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset) +{ + u8 deviceId; + u16 offset; + u32 ftaddr; + + + deviceId = get_deviceid(addr); + offset = 0; + + switch (deviceId) + { + case SDIO_LOCAL_DEVICE_ID: + offset = addr & SDIO_LOCAL_MSK; + break; + + case WLAN_TX_HIQ_DEVICE_ID: + case WLAN_TX_MIQ_DEVICE_ID: + case WLAN_TX_LOQ_DEVICE_ID: + offset = addr & WLAN_FIFO_MSK; + break; + + case WLAN_RX0FF_DEVICE_ID: + offset = addr & WLAN_RX0FF_MSK; + break; + + case WLAN_IOREG_DEVICE_ID: + default: + deviceId = WLAN_IOREG_DEVICE_ID; + offset = addr & WLAN_IOREG_MSK; + break; + } + ftaddr = (deviceId << 13) | offset; + + if (pdeviceId) *pdeviceId = deviceId; + if (poffset) *poffset = offset; + + return ftaddr; +} + +#ifdef CONFIG_SDIO_CHK_HCI_RESUME + +#ifndef SDIO_HCI_RESUME_PWR_RDY_TIMEOUT_MS + #define SDIO_HCI_RESUME_PWR_RDY_TIMEOUT_MS 200 +#endif +#ifndef DBG_SDIO_CHK_HCI_RESUME + #define DBG_SDIO_CHK_HCI_RESUME 0 +#endif + +static bool sdio_chk_hci_resume(struct intf_hdl *pintfhdl) +{ + _adapter *adapter = pintfhdl->padapter; + u8 hci_sus_state; + u8 sus_ctl, sus_ctl_ori = 0xEA; + u8 do_leave = 0; + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + s32 err = 0; + + rtw_hal_get_hwreg(adapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + if (hci_sus_state == HCI_SUS_LEAVE || hci_sus_state == HCI_SUS_ERR) + goto no_hdl; + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + if (err) + goto exit; + sus_ctl_ori = sus_ctl; + + if (sus_ctl & HCI_RESUME_PWR_RDY) + goto exit; + + sus_ctl &= ~(HCI_SUS_CTRL); + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + if (err) + goto exit; + + do_leave = 1; + + /* polling for HCI_RESUME_PWR_RDY */ + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(adapter)) { + sr = 1; + break; + } + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + + if (!err && (sus_ctl & HCI_RESUME_PWR_RDY)) + break; + + if (rtw_get_passing_time_ms(start) > SDIO_HCI_RESUME_PWR_RDY_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + +exit: + + if (DBG_SDIO_CHK_HCI_RESUME) { + DBG_871X(FUNC_ADPT_FMT" hci_sus_state:%u, sus_ctl:0x%02x(0x%02x), do_leave:%u, to:%u, err:%u\n" + , FUNC_ADPT_ARG(adapter), hci_sus_state, sus_ctl, sus_ctl_ori, do_leave, timeout, err); + if (start != 0 || end != 0) { + DBG_871X(FUNC_ADPT_FMT" polling %d ms\n" + , FUNC_ADPT_ARG(adapter), rtw_get_time_interval_ms(start, end)); + } + } + + if (timeout) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" timeout(err:%d) sus_ctl:0x%02x\n" + , FUNC_ADPT_ARG(adapter), err, sus_ctl); + } else if (err) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" err:%d\n" + , FUNC_ADPT_ARG(adapter), err); + } + +no_hdl: + return do_leave ? _TRUE : _FALSE; +} + +void sdio_chk_hci_suspend(struct intf_hdl *pintfhdl) +{ +#define SDIO_CHK_HCI_SUSPEND_POLLING 0 + + _adapter *adapter = pintfhdl->padapter; + u8 hci_sus_state; + u8 sus_ctl, sus_ctl_ori = 0xEA; + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + s32 err = 0; + u8 device_id; + u16 offset; + + rtw_hal_get_hwreg(adapter, HW_VAR_HCI_SUS_STATE, &hci_sus_state); + if (hci_sus_state == HCI_SUS_LEAVE || hci_sus_state == HCI_SUS_LEAVING || hci_sus_state == HCI_SUS_ERR) + goto no_hdl; + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + if (err) + goto exit; + sus_ctl_ori = sus_ctl; + + if (!(sus_ctl & HCI_RESUME_PWR_RDY)) + goto exit; + + sus_ctl |= HCI_SUS_CTRL; + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + if (err) + goto exit; + + #if SDIO_CHK_HCI_SUSPEND_POLLING + /* polling for HCI_RESUME_PWR_RDY cleared */ + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(adapter)) { + sr = 1; + break; + } + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_HSUS_CTRL), 1, &sus_ctl); + + if (!err && !(sus_ctl & HCI_RESUME_PWR_RDY)) + break; + + if (rtw_get_passing_time_ms(start) > SDIO_HCI_RESUME_PWR_RDY_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + #endif /* SDIO_CHK_HCI_SUSPEND_POLLING */ + +exit: + + if (DBG_SDIO_CHK_HCI_RESUME) { + DBG_871X(FUNC_ADPT_FMT" hci_sus_state:%u, sus_ctl:0x%02x(0x%02x), to:%u, err:%u\n" + , FUNC_ADPT_ARG(adapter), hci_sus_state, sus_ctl, sus_ctl_ori, timeout, err); + if (start != 0 || end != 0) { + DBG_871X(FUNC_ADPT_FMT" polling %d ms\n" + , FUNC_ADPT_ARG(adapter), rtw_get_time_interval_ms(start, end)); + } + } + + #if SDIO_CHK_HCI_SUSPEND_POLLING + if (timeout) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" timeout(err:%d) sus_ctl:0x%02x\n" + , FUNC_ADPT_ARG(adapter), err, sus_ctl); + } else + #endif + if (err) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" err:%d\n" + , FUNC_ADPT_ARG(adapter), err); + } + +no_hdl: + return; +} + +#else +#define sdio_chk_hci_resume(pintfhdl) _FALSE +#define sdio_chk_hci_suspend(pintfhdl) do {} while (0) +#endif /* CONFIG_SDIO_CHK_HCI_RESUME */ + +u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr) +{ + u32 ftaddr; + u8 device_id; + u16 offset; + u8 val; + u8 sus_leave = _FALSE; + + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); + + if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + val = sd_read8(pintfhdl, ftaddr, NULL); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return val; +} + +u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr) +{ + u32 ftaddr; + u8 device_id; + u16 offset; + u16 val; + u8 sus_leave = _FALSE; + + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); + + if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + val = 0; + sd_cmd52_read(pintfhdl, ftaddr, 2, (u8*)&val); + val = le16_to_cpu(val); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return val; +} + +u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr) +{ + PADAPTER padapter; + u8 bMacPwrCtrlOn; + u8 deviceId; + u16 offset; + u32 ftaddr; + u8 shift; + u32 val; + s32 err; + +_func_enter_; + + padapter = pintfhdl->padapter; + ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + + if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) + || (_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + u8 sus_leave = _FALSE; + + if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + val = 0; + err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + +#ifdef SDIO_DEBUG_IO + if (!err) { +#endif + val = le32_to_cpu(val); + return val; +#ifdef SDIO_DEBUG_IO + } + + DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr); + return SDIO_ERR_VAL32; +#endif + } + + // 4 bytes alignment + shift = ftaddr & 0x3; + if (shift == 0) { + val = sd_read32(pintfhdl, ftaddr, NULL); + } else { + u8 *ptmpbuf; + + ptmpbuf = (u8*)rtw_malloc(8); + if (NULL == ptmpbuf) { + DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr); + return SDIO_ERR_VAL32; + } + + ftaddr &= ~(u16)0x3; + err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf); + if (err) + return SDIO_ERR_VAL32; + _rtw_memcpy(&val, ptmpbuf+shift, 4); + val = le32_to_cpu(val); + + rtw_mfree(ptmpbuf, 8); + } + +_func_exit_; + + return val; +} + +s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf) +{ + PADAPTER padapter; + u8 bMacPwrCtrlOn; + u8 deviceId; + u16 offset; + u32 ftaddr; + u8 shift; + s32 err; + +_func_enter_; + + padapter = pintfhdl->padapter; + err = 0; + + ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) + || (_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + u8 sus_leave = _FALSE; + + if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return err; + } + + // 4 bytes alignment + shift = ftaddr & 0x3; + if (shift == 0) { + err = sd_read(pintfhdl, ftaddr, cnt, pbuf); + } else { + u8 *ptmpbuf; + u32 n; + + ftaddr &= ~(u16)0x3; + n = cnt + shift; + ptmpbuf = rtw_malloc(n); + if (NULL == ptmpbuf) return -1; + err = sd_read(pintfhdl, ftaddr, n, ptmpbuf); + if (!err) + _rtw_memcpy(pbuf, ptmpbuf+shift, cnt); + rtw_mfree(ptmpbuf, n); + } + +_func_exit_; + + return err; +} + +s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +{ + u32 ftaddr; + u8 device_id; + u16 offset; + s32 err; + u8 sus_leave = _FALSE; + + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); + + if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + err = 0; + sd_write8(pintfhdl, ftaddr, val, &err); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return err; +} + +s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +{ + u32 ftaddr; + u8 device_id; + u16 offset; + s32 err; + u8 sus_leave = _FALSE; + + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); + + if (device_id == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + val = cpu_to_le16(val); + err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8*)&val); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return err; +} + +s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +{ + PADAPTER padapter; + u8 bMacPwrCtrlOn; + u8 deviceId; + u16 offset; + u32 ftaddr; + u8 shift; + s32 err; + +_func_enter_; + + padapter = pintfhdl->padapter; + err = 0; + + ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + + if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) + || (_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + u8 sus_leave = _FALSE; + + if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + val = cpu_to_le32(val); + err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return err; + } + + // 4 bytes alignment + shift = ftaddr & 0x3; +#if 1 + if (shift == 0) + { + sd_write32(pintfhdl, ftaddr, val, &err); + } + else + { + val = cpu_to_le32(val); + err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val); + } +#else + if (shift == 0) { + sd_write32(pintfhdl, ftaddr, val, &err); + } else { + u8 *ptmpbuf; + + ptmpbuf = (u8*)rtw_malloc(8); + if (NULL == ptmpbuf) return (-1); + + ftaddr &= ~(u16)0x3; + err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf); + if (err) { + rtw_mfree(ptmpbuf, 8); + return err; + } + val = cpu_to_le32(val); + _rtw_memcpy(ptmpbuf+shift, &val, 4); + err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf); + + rtw_mfree(ptmpbuf, 8); + } +#endif + +_func_exit_; + + return err; +} + +s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8* pbuf) +{ + PADAPTER padapter; + u8 bMacPwrCtrlOn; + u8 deviceId; + u16 offset; + u32 ftaddr; + u8 shift; + s32 err; + +_func_enter_; + + padapter = pintfhdl->padapter; + err = 0; + + ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) + || (_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + u8 sus_leave = _FALSE; + + if (deviceId == WLAN_IOREG_DEVICE_ID && offset < 0x100) + sus_leave = sdio_chk_hci_resume(pintfhdl); + + err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf); + + if (sus_leave == _TRUE) + sdio_chk_hci_suspend(pintfhdl); + + return err; + } + + shift = ftaddr & 0x3; + if (shift == 0) { + err = sd_write(pintfhdl, ftaddr, cnt, pbuf); + } else { + u8 *ptmpbuf; + u32 n; + + ftaddr &= ~(u16)0x3; + n = cnt + shift; + ptmpbuf = rtw_malloc(n); + if (NULL == ptmpbuf) return -1; + err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf); + if (err) { + rtw_mfree(ptmpbuf, n); + return err; + } + _rtw_memcpy(ptmpbuf+shift, pbuf, cnt); + err = sd_write(pintfhdl, ftaddr, n, ptmpbuf); + rtw_mfree(ptmpbuf, n); + } + +_func_exit_; + + return err; +} + +u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr) +{ + u32 ftaddr; + u8 val; + +_func_enter_; + val = sd_f0_read8(pintfhdl, addr, NULL); + +_func_exit_; + + return val; +} + +void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) +{ + s32 err; + +_func_enter_; + + err = sdio_readN(pintfhdl, addr, cnt, rmem); + +_func_exit_; +} + +void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) +{ +_func_enter_; + + sdio_writeN(pintfhdl, addr, cnt, wmem); + +_func_exit_; +} + +/* + * Description: + * Read from RX FIFO + * Round read size to block size, + * and make sure data transfer will be done in one command. + * + * Parameters: + * pintfhdl a pointer of intf_hdl + * addr port ID + * cnt size to read + * rmem address to put data + * + * Return: + * _SUCCESS(1) Success + * _FAIL(0) Fail + */ +static u32 sdio_read_port( + struct intf_hdl *pintfhdl, + u32 addr, + u32 cnt, + u8 *mem) +{ + PADAPTER padapter; + PSDIO_DATA psdio; + PHAL_DATA_TYPE phal; + u32 oldcnt; +#ifdef SDIO_DYNAMIC_ALLOC_MEM + u8 *oldmem; +#endif + s32 err; + + + padapter = pintfhdl->padapter; + psdio = &adapter_to_dvobj(padapter)->intf_data; + phal = GET_HAL_DATA(padapter); + + HalSdioGetCmdAddr8188FSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr); + + oldcnt = cnt; + if (cnt > psdio->block_transfer_len) + cnt = _RND(cnt, psdio->block_transfer_len); +// cnt = sdio_align_size(cnt); + + if (oldcnt != cnt) { +#ifdef SDIO_DYNAMIC_ALLOC_MEM + oldmem = mem; + mem = rtw_malloc(cnt); + if (mem == NULL) { + DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt); + mem = oldmem; + oldmem == NULL; + } +#else + // in this case, caller should gurante the buffer is big enough + // to receive data after alignment +#endif + } + + err = _sd_read(pintfhdl, addr, cnt, mem); + +#ifdef SDIO_DYNAMIC_ALLOC_MEM + if ((oldcnt != cnt) && (oldmem)) { + _rtw_memcpy(oldmem, mem, oldcnt); + rtw_mfree(mem, cnt); + } +#endif + + if (err) return _FAIL; + return _SUCCESS; +} + +/* + * Description: + * Write to TX FIFO + * Align write size block size, + * and make sure data could be written in one command. + * + * Parameters: + * pintfhdl a pointer of intf_hdl + * addr port ID + * cnt size to write + * wmem data pointer to write + * + * Return: + * _SUCCESS(1) Success + * _FAIL(0) Fail + */ +static u32 sdio_write_port( + struct intf_hdl *pintfhdl, + u32 addr, + u32 cnt, + u8 *mem) +{ + PADAPTER padapter; + PSDIO_DATA psdio; + s32 err; + struct xmit_buf *xmitbuf = (struct xmit_buf *)mem; + + padapter = pintfhdl->padapter; + psdio = &adapter_to_dvobj(padapter)->intf_data; + + if (!rtw_is_hw_init_completed(padapter)) { + DBG_871X("%s [addr=0x%x cnt=%d] padapter->hw_init_completed == _FALSE\n",__func__,addr,cnt); + return _FAIL; + } + + cnt = _RND4(cnt); + HalSdioGetCmdAddr8188FSdio(padapter, addr, cnt >> 2, &addr); + + if (cnt > psdio->block_transfer_len) + cnt = _RND(cnt, psdio->block_transfer_len); +// cnt = sdio_align_size(cnt); + + err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata); + + rtw_sctx_done_err(&xmitbuf->sctx, + err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS); + + if (err) return _FAIL; + return _SUCCESS; +} + +/* + * Todo: align address to 4 bytes. + */ +s32 _sdio_local_read( + PADAPTER padapter, + u32 addr, + u32 cnt, + u8 *pbuf) +{ + struct intf_hdl * pintfhdl; + u8 bMacPwrCtrlOn; + s32 err; + u8 *ptmpbuf; + u32 n; + + + pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if (_FALSE == bMacPwrCtrlOn) + { + err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf); + return err; + } + + n = RND4(cnt); + ptmpbuf = (u8*)rtw_malloc(n); + if (!ptmpbuf) + return (-1); + + err = _sd_read(pintfhdl, addr, n, ptmpbuf); + if (!err) + _rtw_memcpy(pbuf, ptmpbuf, cnt); + + if (ptmpbuf) + rtw_mfree(ptmpbuf, n); + + return err; +} + +/* + * Todo: align address to 4 bytes. + */ +s32 sdio_local_read( + PADAPTER padapter, + u32 addr, + u32 cnt, + u8 *pbuf) +{ + struct intf_hdl * pintfhdl; + u8 bMacPwrCtrlOn; + s32 err; + u8 *ptmpbuf; + u32 n; + + pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if ((_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf); + return err; + } + + n = RND4(cnt); + ptmpbuf = (u8*)rtw_malloc(n); + if (!ptmpbuf) + return (-1); + + err = sd_read(pintfhdl, addr, n, ptmpbuf); + if (!err) + _rtw_memcpy(pbuf, ptmpbuf, cnt); + + if (ptmpbuf) + rtw_mfree(ptmpbuf, n); + + return err; +} + +/* + * Todo: align address to 4 bytes. + */ +s32 _sdio_local_write( + PADAPTER padapter, + u32 addr, + u32 cnt, + u8 *pbuf) +{ + struct intf_hdl * pintfhdl; + u8 bMacPwrCtrlOn; + s32 err; + u8 *ptmpbuf; + + if(addr & 0x3) + DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__); + + if(cnt & 0x3) + DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__); + + pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if ((_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + err = _sd_cmd52_write(pintfhdl, addr, cnt, pbuf); + return err; + } + + ptmpbuf = (u8*)rtw_malloc(cnt); + if (!ptmpbuf) + return (-1); + + _rtw_memcpy(ptmpbuf, pbuf, cnt); + + err = _sd_write(pintfhdl, addr, cnt, ptmpbuf); + + if (ptmpbuf) + rtw_mfree(ptmpbuf, cnt); + + return err; +} + +/* + * Todo: align address to 4 bytes. + */ +s32 sdio_local_write( + PADAPTER padapter, + u32 addr, + u32 cnt, + u8 *pbuf) +{ + struct intf_hdl * pintfhdl; + u8 bMacPwrCtrlOn; + s32 err; + u8 *ptmpbuf; + + if(addr & 0x3) + DBG_8192C("%s, address must be 4 bytes alignment\n", __FUNCTION__); + + if(cnt & 0x3) + DBG_8192C("%s, size must be the multiple of 4 \n", __FUNCTION__); + + pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if ((_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf); + return err; + } + + ptmpbuf = (u8*)rtw_malloc(cnt); + if (!ptmpbuf) + return (-1); + + _rtw_memcpy(ptmpbuf, pbuf, cnt); + + err = sd_write(pintfhdl, addr, cnt, ptmpbuf); + + if (ptmpbuf) + rtw_mfree(ptmpbuf, cnt); + + return err; +} + +u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr) +{ + u8 val = 0; + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_read(pintfhdl, addr, 1, &val); + + return val; +} + +u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr) +{ + u16 val = 0; + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_read(pintfhdl, addr, 2, (u8*)&val); + + val = le16_to_cpu(val); + + return val; +} + +u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr) +{ + u32 val = 0; + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val); + + val = le32_to_cpu(val); + + return val; +} + +u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr) +{ + + u8 bMacPwrCtrlOn; + u32 val = 0; + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if ((_FALSE == bMacPwrCtrlOn) +#ifdef CONFIG_LPS_LCLK + || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) +#endif + ) + { + sd_cmd52_read(pintfhdl, addr, 4, (u8*)&val); + val = le32_to_cpu(val); + } + else + val = sd_read32(pintfhdl, addr, NULL); + + return val; +} + +void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v) +{ + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_write(pintfhdl, addr, 1, &v); +} + +void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v) +{ + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + v = cpu_to_le16(v); + sd_cmd52_write(pintfhdl, addr, 2, (u8*)&v); +} + +void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v) +{ + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + HalSdioGetCmdAddr8188FSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + v = cpu_to_le32(v); + sd_cmd52_write(pintfhdl, addr, 4, (u8*)&v); +} + +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +/* program indirect access register in sdio local to read/write page0 registers */ +#ifndef INDIRECT_ACCESS_TIMEOUT_MS + #define INDIRECT_ACCESS_TIMEOUT_MS 200 +#endif +#ifndef DBG_SDIO_INDIRECT_ACCESS + #define DBG_SDIO_INDIRECT_ACCESS 0 +#endif + +static s32 sdio_iread(PADAPTER padapter, u32 addr, u8 size, u8 *v) +{ + struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + _mutex *mutex = &adapter_to_dvobj(padapter)->sd_indirect_access_mutex; + + u8 val[4] = {0}; + u8 cmd[4] = {0}; /* mapping to indirect access register, little endien */ + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + s32 err = 0; + + if (size == 1) + SET_INDIRECT_REG_SIZE_1BYTE(cmd); + else if (size == 2) + SET_INDIRECT_REG_SIZE_2BYTE(cmd); + else if (size == 4) + SET_INDIRECT_REG_SIZE_4BYTE(cmd); + + SET_INDIRECT_REG_ADDR(cmd, addr); + + /* acquire indirect access lock */ + _enter_critical_mutex(mutex, NULL); + + if (DBG_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" cmd:%02x %02x %02x %02x\n", FUNC_ADPT_ARG(padapter), cmd[0], cmd[1], cmd[2], cmd[3]); + + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F), 3, cmd); + if (err) + goto exit; + + /* trigger */ + SET_INDIRECT_REG_READ(cmd); + + if (DBG_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" cmd:%02x %02x %02x %02x\n", FUNC_ADPT_ARG(padapter), cmd[0], cmd[1], cmd[2], cmd[3]); + + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F + 2), 1, cmd + 2); + if (err) + goto exit; + + /* polling for indirect access done */ + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(padapter)) { + sr = 1; + break; + } + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F + 2), 1, cmd + 2); + + if (!err && GET_INDIRECT_REG_RDY(cmd)) + break; + + if (rtw_get_passing_time_ms(start) > INDIRECT_ACCESS_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + + if (timeout || sr) + goto exit; + + /* read result */ + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_DATA_8188F), size, val); + if (size == 2) + *((u16 *)(val)) = le16_to_cpu(*((u16 *)(val))); + else if (size == 4) + *((u32 *)(val)) = le32_to_cpu(*((u32 *)(val))); + + if (DBG_SDIO_INDIRECT_ACCESS) { + if (size == 1) + DBG_871X(FUNC_ADPT_FMT" val:0x%02x\n", FUNC_ADPT_ARG(padapter), *((u8 *)(val))); + else if (size == 2) + DBG_871X(FUNC_ADPT_FMT" val:0x%04x\n", FUNC_ADPT_ARG(padapter), *((u16 *)(val))); + else if (size == 4) + DBG_871X(FUNC_ADPT_FMT" val:0x%08x\n", FUNC_ADPT_ARG(padapter), *((u32 *)(val))); + } + +exit: + /* release indirect access lock */ + _exit_critical_mutex(mutex, NULL); + + if (DBG_SDIO_INDIRECT_ACCESS) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%0x size:%u, cmd:%02x %02x %02x %02x, to:%u, err:%u\n" + , FUNC_ADPT_ARG(padapter), addr, size, cmd[0], cmd[1], cmd[2], cmd[3], timeout, err); + if (start != 0 || end != 0) { + DBG_871X(FUNC_ADPT_FMT" polling %d ms\n" + , FUNC_ADPT_ARG(padapter), rtw_get_time_interval_ms(start, end)); + } + } + + if (timeout) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" addr:0x%0x timeout(err:%d), cmd\n" + , FUNC_ADPT_ARG(padapter), addr, err); + if (!err) + err = -1; /* just for return value */ + } else if (err) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" addr:0x%0x err:%d\n" + , FUNC_ADPT_ARG(padapter), addr, err); + } else if (sr) { + /* just for return value */ + err = -1; + } + + if (!err && !timeout && !sr) + _rtw_memcpy(v, val, size); + + return err; +} + +static s32 sdio_iwrite(PADAPTER padapter, u32 addr, u8 size, u8 *v) +{ + struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + _mutex *mutex = &adapter_to_dvobj(padapter)->sd_indirect_access_mutex; + + u8 val[4] = {0}; + u8 cmd[4] = {0}; /* mapping to indirect access register, little endien */ + u32 start = 0, end = 0; + u8 timeout = 0; + u8 sr = 0; + s32 err = 0; + + if (size == 1) + SET_INDIRECT_REG_SIZE_1BYTE(cmd); + else if (size == 2) + SET_INDIRECT_REG_SIZE_2BYTE(cmd); + else if (size == 4) + SET_INDIRECT_REG_SIZE_4BYTE(cmd); + + SET_INDIRECT_REG_ADDR(cmd, addr); + + /* acquire indirect access lock */ + _enter_critical_mutex(mutex, NULL); + + if (DBG_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" cmd:%02x %02x %02x %02x\n", FUNC_ADPT_ARG(padapter), cmd[0], cmd[1], cmd[2], cmd[3]); + + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F), 3, cmd); + if (err) + goto exit; + + /* data to write */ + _rtw_memcpy(val, v, size); + + if (DBG_SDIO_INDIRECT_ACCESS) { + if (size == 1) + DBG_871X(FUNC_ADPT_FMT" val:0x%02x\n", FUNC_ADPT_ARG(padapter), *((u8 *)(val))); + else if (size == 2) + DBG_871X(FUNC_ADPT_FMT" val:0x%04x\n", FUNC_ADPT_ARG(padapter), *((u16 *)(val))); + else if (size == 4) + DBG_871X(FUNC_ADPT_FMT" val:0x%08x\n", FUNC_ADPT_ARG(padapter), *((u32 *)(val))); + } + + if (size == 2) + *((u16 *)(val)) = cpu_to_le16(*((u16 *)(val))); + else if (size == 4) + *((u32 *)(val)) = cpu_to_le32(*((u32 *)(val))); + + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_DATA_8188F), size, val); + if (err) + goto exit; + + /* trigger */ + SET_INDIRECT_REG_WRITE(cmd); + + if (DBG_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" cmd:%02x %02x %02x %02x\n", FUNC_ADPT_ARG(padapter), cmd[0], cmd[1], cmd[2], cmd[3]); + + err = sd_cmd52_write(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F + 2), 1, cmd + 2); + if (err) + goto exit; + + /* polling for indirect access done */ + start = rtw_get_current_time(); + while (1) { + if (rtw_is_surprise_removed(padapter)) { + sr = 1; + break; + } + + err = sd_cmd52_read(pintfhdl, SDIO_LOCAL_CMD_ADDR(SDIO_REG_INDIRECT_REG_CFG_8188F + 2), 1, cmd + 2); + + if (!err && GET_INDIRECT_REG_RDY(cmd)) + break; + + if (rtw_get_passing_time_ms(start) > INDIRECT_ACCESS_TIMEOUT_MS) { + timeout = 1; + break; + } + } + end = rtw_get_current_time(); + + if (timeout || sr) + goto exit; + +exit: + /* release indirect access lock */ + _exit_critical_mutex(mutex, NULL); + + if (DBG_SDIO_INDIRECT_ACCESS) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%0x size:%u, cmd:%02x %02x %02x %02x, to:%u, err:%u\n" + , FUNC_ADPT_ARG(padapter), addr, size, cmd[0], cmd[1], cmd[2], cmd[3], timeout, err); + if (start != 0 || end != 0) { + DBG_871X(FUNC_ADPT_FMT" polling %d ms\n" + , FUNC_ADPT_ARG(padapter), rtw_get_time_interval_ms(start, end)); + } + } + + if (timeout) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" addr:0x%0x timeout(err:%d), cmd\n" + , FUNC_ADPT_ARG(padapter), addr, err); + if (!err) + err = -1; /* just for return value */ + } else if (err) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" addr:0x%0x err:%d\n" + , FUNC_ADPT_ARG(padapter), addr, err); + } else if (sr) { + /* just for return value */ + err = -1; + } + + return err; +} + +u8 sdio_iread8(struct intf_hdl *pintfhdl, u32 addr) +{ + u8 val; + + if (sdio_iread(pintfhdl->padapter, addr, 1, (u8 *)&val) != 0) + val = SDIO_ERR_VAL8; + + return val; +} + +u16 sdio_iread16(struct intf_hdl *pintfhdl, u32 addr) +{ + u16 val; + + if (sdio_iread(pintfhdl->padapter, addr, 2, (u8 *)&val) != 0) + val = SDIO_ERR_VAL16; + + return val; +} + +u32 sdio_iread32(struct intf_hdl *pintfhdl, u32 addr) +{ + u32 val; + + if (sdio_iread(pintfhdl->padapter, addr, 4, (u8 *)&val) != 0) + val = SDIO_ERR_VAL32; + + return val; +} + +s32 sdio_iwrite8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +{ + return sdio_iwrite(pintfhdl->padapter, addr, 1, (u8 *)&val); +} + +s32 sdio_iwrite16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +{ + return sdio_iwrite(pintfhdl->padapter, addr, 2, (u8 *)&val); +} + +s32 sdio_iwrite32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +{ + return sdio_iwrite(pintfhdl->padapter, addr, 4, (u8 *)&val); +} + +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ + +void sdio_set_intf_ops(_adapter *padapter, struct _io_ops *pops) +{ +_func_enter_; + + pops->_read8 = &sdio_read8; + pops->_read16 = &sdio_read16; + pops->_read32 = &sdio_read32; + pops->_read_mem = &sdio_read_mem; + pops->_read_port = &sdio_read_port; + + pops->_write8 = &sdio_write8; + pops->_write16 = &sdio_write16; + pops->_write32 = &sdio_write32; + pops->_writeN = &sdio_writeN; + pops->_write_mem = &sdio_write_mem; + pops->_write_port = &sdio_write_port; + + pops->_sd_f0_read8 = sdio_f0_read8; + +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + pops->_sd_iread8 = sdio_iread8; + pops->_sd_iread16 = sdio_iread16; + pops->_sd_iread32 = sdio_iread32; + pops->_sd_iwrite8 = sdio_iwrite8; + pops->_sd_iwrite16 = sdio_iwrite16; + pops->_sd_iwrite32 = sdio_iwrite32; +#endif + +_func_exit_; +} + +#if 0 +void +DumpLoggedInterruptHistory8188Sdio( + PADAPTER padapter +) +{ + HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter); + u4Byte DebugLevel = DBG_LOUD; + + if (DBG_Var.DbgPrintIsr == 0) + return; + + DBG_ChkDrvResource(padapter); + + + if(pHalData->InterruptLog.nISR_RX_REQUEST) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RX_REQUEST[%ld]\t\n", pHalData->InterruptLog.nISR_RX_REQUEST)); + + if(pHalData->InterruptLog.nISR_AVAL) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# AVAL[%ld]\t\n", pHalData->InterruptLog.nISR_AVAL)); + + if(pHalData->InterruptLog.nISR_TXERR) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXERR)); + + if(pHalData->InterruptLog.nISR_RXERR) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXERR[%ld]\t\n", pHalData->InterruptLog.nISR_RXERR)); + + if(pHalData->InterruptLog.nISR_TXFOVW) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_TXFOVW)); + + if(pHalData->InterruptLog.nISR_RXFOVW) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# RXFOVW[%ld]\t\n", pHalData->InterruptLog.nISR_RXFOVW)); + + if(pHalData->InterruptLog.nISR_TXBCNOK) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNOK[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNOK)); + + if(pHalData->InterruptLog.nISR_TXBCNERR) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# TXBCNERR[%ld]\t\n", pHalData->InterruptLog.nISR_TXBCNERR)); + + if(pHalData->InterruptLog.nISR_BCNERLY_INT) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# BCNERLY_INT[%ld]\t\n", pHalData->InterruptLog.nISR_BCNERLY_INT)); + + if(pHalData->InterruptLog.nISR_C2HCMD) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# C2HCMD[%ld]\t\n", pHalData->InterruptLog.nISR_C2HCMD)); + + if(pHalData->InterruptLog.nISR_CPWM1) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM1L[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM1)); + + if(pHalData->InterruptLog.nISR_CPWM2) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CPWM2[%ld]\t\n", pHalData->InterruptLog.nISR_CPWM2)); + + if(pHalData->InterruptLog.nISR_HSISR_IND) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# HSISR_IND[%ld]\t\n", pHalData->InterruptLog.nISR_HSISR_IND)); + + if(pHalData->InterruptLog.nISR_GTINT3_IND) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT3_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT3_IND)); + + if(pHalData->InterruptLog.nISR_GTINT4_IND) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# GTINT4_IND[%ld]\t\n", pHalData->InterruptLog.nISR_GTINT4_IND)); + + if(pHalData->InterruptLog.nISR_PSTIMEOUT) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# PSTIMEOUT[%ld]\t\n", pHalData->InterruptLog.nISR_PSTIMEOUT)); + + if(pHalData->InterruptLog.nISR_OCPINT) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# OCPINT[%ld]\t\n", pHalData->InterruptLog.nISR_OCPINT)); + + if(pHalData->InterruptLog.nISR_ATIMEND) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND)); + + if(pHalData->InterruptLog.nISR_ATIMEND_E) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# ATIMEND_E[%ld]\t\n", pHalData->InterruptLog.nISR_ATIMEND_E)); + + if(pHalData->InterruptLog.nISR_CTWEND) + RT_TRACE(COMP_SEND|COMP_RECV, DebugLevel, ("# CTWEND[%ld]\t\n", pHalData->InterruptLog.nISR_CTWEND)); +} + +void +LogInterruptHistory8188Sdio( + PADAPTER padapter, + PRT_ISR_CONTENT pIsrContent +) +{ + HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter); + + if((pHalData->IntrMask[0] & SDIO_HIMR_RX_REQUEST_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_RX_REQUEST)) + pHalData->InterruptLog.nISR_RX_REQUEST ++; + if((pHalData->IntrMask[0] & SDIO_HIMR_AVAL_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_AVAL)) + pHalData->InterruptLog.nISR_AVAL++; + if((pHalData->IntrMask[0] & SDIO_HIMR_TXERR_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_TXERR)) + pHalData->InterruptLog.nISR_TXERR++; + if((pHalData->IntrMask[0] & SDIO_HIMR_RXERR_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_RXERR)) + pHalData->InterruptLog.nISR_RXERR++; + if((pHalData->IntrMask[0] & SDIO_HIMR_TXFOVW_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_TXFOVW)) + pHalData->InterruptLog.nISR_TXFOVW++; + if((pHalData->IntrMask[0] & SDIO_HIMR_RXFOVW_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_RXFOVW)) + pHalData->InterruptLog.nISR_RXFOVW++; + if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNOK_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNOK)) + pHalData->InterruptLog.nISR_TXBCNOK++; + if((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNERR_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNERR)) + pHalData->InterruptLog.nISR_TXBCNERR++; + if((pHalData->IntrMask[0] & SDIO_HIMR_BCNERLY_INT_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_BCNERLY_INT)) + pHalData->InterruptLog.nISR_BCNERLY_INT ++; + if((pHalData->IntrMask[0] & SDIO_HIMR_C2HCMD_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_C2HCMD)) + pHalData->InterruptLog.nISR_C2HCMD++; + if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM1_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_CPWM1)) + pHalData->InterruptLog.nISR_CPWM1++; + if((pHalData->IntrMask[0] & SDIO_HIMR_CPWM2_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_CPWM2)) + pHalData->InterruptLog.nISR_CPWM2++; + if((pHalData->IntrMask[0] & SDIO_HIMR_HSISR_IND_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_HSISR_IND)) + pHalData->InterruptLog.nISR_HSISR_IND++; + if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT3_IND_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_GTINT3_IND)) + pHalData->InterruptLog.nISR_GTINT3_IND++; + if((pHalData->IntrMask[0] & SDIO_HIMR_GTINT4_IND_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_GTINT4_IND)) + pHalData->InterruptLog.nISR_GTINT4_IND++; + if((pHalData->IntrMask[0] & SDIO_HIMR_PSTIMEOUT_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_PSTIMEOUT)) + pHalData->InterruptLog.nISR_PSTIMEOUT++; + if((pHalData->IntrMask[0] & SDIO_HIMR_OCPINT_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_OCPINT)) + pHalData->InterruptLog.nISR_OCPINT++; + if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND)) + pHalData->InterruptLog.nISR_ATIMEND++; + if((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_E_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND_E)) + pHalData->InterruptLog.nISR_ATIMEND_E++; + if((pHalData->IntrMask[0] & SDIO_HIMR_CTWEND_MSK) && + (pIsrContent->IntArray[0] & SDIO_HISR_CTWEND)) + pHalData->InterruptLog.nISR_CTWEND++; + +} + +void +DumpHardwareProfile8188Sdio( + IN PADAPTER padapter +) +{ + DumpLoggedInterruptHistory8188Sdio(padapter); +} +#endif + +static s32 ReadInterrupt8188FSdio(PADAPTER padapter, u32 *phisr) +{ + u32 hisr, himr; + u8 val8, hisr_len; + int i; + + if (phisr == NULL) + return _FALSE; + + himr = GET_HAL_DATA(padapter)->sdio_himr; + + // decide how many bytes need to be read + hisr_len = 0; + while (himr) + { + hisr_len++; + himr >>= 8; + } + + hisr = 0; + for (i = 0; i < hisr_len; i++) { + val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR + i); + hisr |= (val8 << (8 * i)); + } + + *phisr = hisr; + + return _TRUE; +} + +// +// Description: +// Initialize SDIO Host Interrupt Mask configuration variables for future use. +// +// Assumption: +// Using SDIO Local register ONLY for configuration. +// +// Created by Roger, 2011.02.11. +// +void InitInterrupt8188FSdio(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + pHalData->sdio_himr = (u32)( \ + SDIO_HIMR_RX_REQUEST_MSK | +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + SDIO_HIMR_AVAL_MSK | +#endif +// SDIO_HIMR_TXERR_MSK | +// SDIO_HIMR_RXERR_MSK | +// SDIO_HIMR_TXFOVW_MSK | +// SDIO_HIMR_RXFOVW_MSK | +// SDIO_HIMR_TXBCNOK_MSK | +// SDIO_HIMR_TXBCNERR_MSK | +// SDIO_HIMR_BCNERLY_INT_MSK | +// SDIO_HIMR_C2HCMD_MSK | +#if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_DETECT_CPWM_BY_POLLING) + SDIO_HIMR_CPWM1_MSK | +// SDIO_HIMR_CPWM2_MSK | +#endif // CONFIG_LPS_LCLK && !CONFIG_DETECT_CPWM_BY_POLLING +// SDIO_HIMR_HSISR_IND_MSK | +// SDIO_HIMR_GTINT3_IND_MSK | +// SDIO_HIMR_GTINT4_IND_MSK | +// SDIO_HIMR_PSTIMEOUT_MSK | +// SDIO_HIMR_OCPINT_MSK | +// SDIO_HIMR_ATIMEND_MSK | +// SDIO_HIMR_ATIMEND_E_MSK | +// SDIO_HIMR_CTWEND_MSK | + 0); +} + +// +// Description: +// Initialize System Host Interrupt Mask configuration variables for future use. +// +// Created by Roger, 2011.08.03. +// +void InitSysInterrupt8188FSdio(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + + + pHalData = GET_HAL_DATA(padapter); + + pHalData->SysIntrMask = ( \ +// HSIMR_GPIO12_0_INT_EN | +// HSIMR_SPS_OCP_INT_EN | +// HSIMR_RON_INT_EN | +// HSIMR_PDNINT_EN | +// HSIMR_GPIO9_INT_EN | + 0); +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +// +// Description: +// Clear corresponding SDIO Host ISR interrupt service. +// +// Assumption: +// Using SDIO Local register ONLY for configuration. +// +// Created by Roger, 2011.02.11. +// +void ClearInterrupt8188FSdio(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u8 *clear; + + + if (rtw_is_surprise_removed(padapter)) + return; + + pHalData = GET_HAL_DATA(padapter); + clear = rtw_zmalloc(4); + + // Clear corresponding HISR Content if needed + *(u32*)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR); + if (*(u32*)clear) + { + // Perform write one clear operation + sdio_local_write(padapter, SDIO_REG_HISR, 4, clear); + } + + rtw_mfree(clear, 4); +} +#endif + +// +// Description: +// Clear corresponding system Host ISR interrupt service. +// +// +// Created by Roger, 2011.02.11. +// +void ClearSysInterrupt8188FSdio(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u32 clear; + + + if (rtw_is_surprise_removed(padapter)) + return; + + pHalData = GET_HAL_DATA(padapter); + + // Clear corresponding HISR Content if needed + clear = pHalData->SysIntrStatus & MASK_HSISR_CLEAR; + if (clear) + { + // Perform write one clear operation + rtw_write32(padapter, REG_HSISR, clear); + } +} + +// +// Description: +// Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain. +// +// Assumption: +// 1. Using SDIO Local register ONLY for configuration. +// 2. PASSIVE LEVEL +// +// Created by Roger, 2011.02.11. +// +void EnableInterrupt8188FSdio(PADAPTER padapter) +{ + PHAL_DATA_TYPE pHalData; + u32 himr; + + pHalData = GET_HAL_DATA(padapter); + + himr = cpu_to_le32(pHalData->sdio_himr); + sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr); + + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: enable SDIO HIMR=0x%08X\n", __FUNCTION__, pHalData->sdio_himr)); + + // Update current system IMR settings + himr = rtw_read32(padapter, REG_HSIMR); + rtw_write32(padapter, REG_HSIMR, himr|pHalData->SysIntrMask); + + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: enable HSIMR=0x%08X\n", __FUNCTION__, pHalData->SysIntrMask)); + + // + // There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. + // So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. + // 2011.10.19. + // + rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); +} + +// +// Description: +// Disable SDIO Host IMR configuration to mask unnecessary interrupt service. +// +// Assumption: +// Using SDIO Local register ONLY for configuration. +// +// Created by Roger, 2011.02.11. +// +void DisableInterrupt8188FSdio(PADAPTER padapter) +{ + u32 himr; + + himr = cpu_to_le32(SDIO_HIMR_DISABLED); + sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr); + +} + +// +// Description: +// Using 0x100 to check the power status of FW. +// +// Assumption: +// Using SDIO Local register ONLY for configuration. +// +// Created by Isaac, 2013.09.10. +// +u8 CheckIPSStatus(PADAPTER padapter) +{ + DBG_871X("%s(): Read 0x100=0x%02x 0x86=0x%02x\n", __func__, + rtw_read8(padapter, 0x100),rtw_read8(padapter, 0x86)); + + if (rtw_read8(padapter, 0x100) == 0xEA) + return _TRUE; + else + return _FALSE; +} + +#ifdef CONFIG_WOWLAN +void DisableInterruptButCpwm28188FSdio(PADAPTER padapter) +{ + u32 himr, tmp; + + sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp); + DBG_871X("DisableInterruptButCpwm28188FSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp); + + himr = cpu_to_le32(SDIO_HIMR_DISABLED)|SDIO_HIMR_CPWM2_MSK; + sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8*)&himr); + + sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8*)&tmp); + DBG_871X("DisableInterruptButCpwm28188FSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp); +} +#endif //CONFIG_WOWLAN +// +// Description: +// Update SDIO Host Interrupt Mask configuration on SDIO local domain. +// +// Assumption: +// 1. Using SDIO Local register ONLY for configuration. +// 2. PASSIVE LEVEL +// +// Created by Roger, 2011.02.11. +// +void UpdateInterruptMask8188FSdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR) +{ + HAL_DATA_TYPE *pHalData; + + pHalData = GET_HAL_DATA(padapter); + + if (AddMSR) + pHalData->sdio_himr |= AddMSR; + + if (RemoveMSR) + pHalData->sdio_himr &= (~RemoveMSR); + + DisableInterrupt8188FSdio(padapter); + EnableInterrupt8188FSdio(padapter); +} + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER +static void sd_recv_loopback(PADAPTER padapter, u32 size) +{ + PLOOPBACKDATA ploopback; + u32 readsize, allocsize; + u8 *preadbuf; + + + readsize = size; + DBG_8192C("%s: read size=%d\n", __func__, readsize); + allocsize = _RND(readsize, adapter_to_dvobj(padapter)->intf_data.block_transfer_len); + + ploopback = padapter->ploopback; + if (ploopback) { + ploopback->rxsize = readsize; + preadbuf = ploopback->rxbuf; + } + else { + preadbuf = rtw_malloc(allocsize); + if (preadbuf == NULL) { + DBG_8192C("%s: malloc fail size=%d\n", __func__, allocsize); + return; + } + } + +// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + + if (ploopback) + _rtw_up_sema(&ploopback->sema); + else { + u32 i; + + DBG_8192C("%s: drop pkt\n", __func__); + for (i = 0; i < readsize; i+=4) { + DBG_8192C("%08X", *(u32*)(preadbuf + i)); + if ((i+4) & 0x1F) printk(" "); + else printk("\n"); + } + printk("\n"); + rtw_mfree(preadbuf, allocsize); + } +} +#endif // CONFIG_MAC_LOOPBACK_DRIVER + +#ifdef CONFIG_SDIO_RX_COPY +static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size) +{ + u32 readsize, ret; + u8 *preadbuf; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + + +#if 0 + readsize = size; +#else + // Patch for some SDIO Host 4 bytes issue + // ex. RK3188 + readsize = RND4(size); +#endif + + if (readsize > MAX_RECVBUF_SZ) { + DBG_871X(FUNC_ADPT_FMT" %u\n", FUNC_ADPT_ARG(padapter), readsize); + rtw_warn_on(readsize > MAX_RECVBUF_SZ); + } + + //3 1. alloc recvbuf + precvpriv = &padapter->recvpriv; + precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue); + if (precvbuf == NULL) { + DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __FUNCTION__); + return NULL; + } + + //3 2. alloc skb + if (precvbuf->pskb == NULL) { + SIZE_PTR tmpaddr=0; + SIZE_PTR alignment=0; + + precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); + if (precvbuf->pskb == NULL) { + DBG_871X("%s: alloc_skb fail! read=%d\n", __FUNCTION__, readsize); + rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue); + return NULL; + } + + precvbuf->pskb->dev = padapter->pnetdev; + + tmpaddr = (SIZE_PTR)precvbuf->pskb->data; + alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); + skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + } + + //3 3. read data from rxfifo + preadbuf = precvbuf->pskb->data; +// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + if (ret == _FAIL) { + RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__)); + rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue); + return NULL; + } + + //3 4. init recvbuf + precvbuf->len = size; + precvbuf->phead = precvbuf->pskb->head; + precvbuf->pdata = precvbuf->pskb->data; + skb_set_tail_pointer(precvbuf->pskb, size); + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + + return precvbuf; +} +#else // !CONFIG_SDIO_RX_COPY +static struct recv_buf* sd_recv_rxfifo(PADAPTER padapter, u32 size) +{ + u32 sdioblksize, readsize, allocsize, ret; + u8 *preadbuf; + _pkt *ppkt; + struct recv_priv *precvpriv; + struct recv_buf *precvbuf; + + + sdioblksize = adapter_to_dvobj(padapter)->intf_data.block_transfer_len; +#if 0 + readsize = size; +#else + // Patch for some SDIO Host 4 bytes issue + // ex. RK3188 + readsize = RND4(size); +#endif + + //3 1. alloc skb + // align to block size + if (readsize > sdioblksize) + allocsize = _RND(readsize, sdioblksize); + else + allocsize = readsize; + + ppkt = rtw_skb_alloc(allocsize); + + if (ppkt == NULL) { + RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: alloc_skb fail! alloc=%d read=%d\n", __FUNCTION__, allocsize, readsize)); + return NULL; + } + + //3 2. read data from rxfifo + preadbuf = skb_put(ppkt, size); +// rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + if (ret == _FAIL) { + rtw_skb_free(ppkt); + RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __FUNCTION__)); + return NULL; + } + + //3 3. alloc recvbuf + precvpriv = &padapter->recvpriv; + precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue); + if (precvbuf == NULL) { + rtw_skb_free(ppkt); + DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __FUNCTION__); + return NULL; + } + + //3 4. init recvbuf + precvbuf->pskb = ppkt; + + precvbuf->len = ppkt->len; + + precvbuf->phead = ppkt->head; + precvbuf->pdata = ppkt->data; + precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); + precvbuf->pend = skb_end_pointer(precvbuf->pskb); + + return precvbuf; +} +#endif // !CONFIG_SDIO_RX_COPY + +static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf) +{ + struct recv_priv *precvpriv; + _queue *ppending_queue; + + + precvpriv = &padapter->recvpriv; + ppending_queue = &precvpriv->recv_buf_pending_queue; + + //3 1. enqueue recvbuf + rtw_enqueue_recvbuf(precvbuf, ppending_queue); + + //3 2. schedule tasklet +#ifdef PLATFORM_LINUX + tasklet_schedule(&precvpriv->recv_tasklet); +#endif +} + +void sd_int_dpc(PADAPTER padapter) +{ + PHAL_DATA_TYPE phal; + struct dvobj_priv *dvobj; + struct intf_hdl * pintfhdl=&padapter->iopriv.intf; + struct pwrctrl_priv *pwrctl; + + + phal = GET_HAL_DATA(padapter); + dvobj = adapter_to_dvobj(padapter); + pwrctl = dvobj_to_pwrctl(dvobj); + +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT + if (phal->sdio_hisr & SDIO_HISR_AVAL) + { + //_irqL irql; + u8 freepage[4]; + + _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage); + //_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + //_rtw_memcpy(phal->SdioTxFIFOFreePage, freepage, 4); + //_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + //DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n", + // freepage[0], + // freepage[1], + // freepage[2], + // freepage[3]); + _rtw_up_sema(&(padapter->xmitpriv.xmit_sema)); + } +#endif + if (phal->sdio_hisr & SDIO_HISR_CPWM1) + { + struct reportpwrstate_parm report; + +#ifdef CONFIG_LPS_RPWM_TIMER + u8 bcancelled; + _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled); +#endif // CONFIG_LPS_RPWM_TIMER + + report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8188F); + +#ifdef CONFIG_LPS_LCLK + //cpwm_int_hdl(padapter, &report); + _set_workitem(&(pwrctl->cpwm_event)); +#endif + } + + if (phal->sdio_hisr & SDIO_HISR_TXERR) + { + u8 *status; + u32 addr; + + status = rtw_malloc(4); + if (status) + { + addr = REG_TXDMA_STATUS; + HalSdioGetCmdAddr8188FSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr); + _sd_read(pintfhdl, addr, 4, status); + _sd_write(pintfhdl, addr, 4, status); + DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status)); + rtw_mfree(status, 4); + } else { + DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); + } + } + + if (phal->sdio_hisr & SDIO_HISR_TXBCNOK) + { + DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); + } + + if (phal->sdio_hisr & SDIO_HISR_TXBCNERR) + { + DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); + } +#ifndef CONFIG_C2H_PACKET_EN + if (phal->sdio_hisr & SDIO_HISR_C2HCMD) + { + struct c2h_evt_hdr_88xx *c2h_evt; + + DBG_8192C("%s: C2H Command\n", __func__); + if ((c2h_evt = (struct c2h_evt_hdr_88xx*)rtw_zmalloc(16)) != NULL) { + if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) { + if (c2h_id_filter_ccx_8188f((u8 *)c2h_evt)) { + /* Handle CCX report here */ + rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt); + rtw_mfree((u8*)c2h_evt, 16); + } else { + rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt); + } + } + } else { + /* Error handling for malloc fail */ + if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS) + DBG_871X("%s rtw_cbuf_push fail\n", __func__); + _set_workitem(&padapter->evtpriv.c2h_wk); + } + } +#endif + + if (phal->sdio_hisr & SDIO_HISR_RXFOVW) + { + DBG_8192C("%s: Rx Overflow\n", __func__); + } + if (phal->sdio_hisr & SDIO_HISR_RXERR) + { + DBG_8192C("%s: Rx Error\n", __func__); + } + + if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) + { + struct recv_buf *precvbuf; + int alloc_fail_time=0; + u32 hisr; + +// DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); + phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; + do { + phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN); + if (phal->SdioRxFIFOSize != 0) + { +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + sd_recv_loopback(padapter, phal->SdioRxFIFOSize); +#else + precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize); + if (precvbuf) + sd_rxhandler(padapter, precvbuf); + else + { + alloc_fail_time++; + DBG_871X("%s: recv fail!(time=%d)\n", __func__, alloc_fail_time); + if (alloc_fail_time >= 10) + break; + } + phal->SdioRxFIFOSize = 0; +#endif + } + else + break; + + hisr = 0; + ReadInterrupt8188FSdio(padapter, &hisr); + hisr &= SDIO_HISR_RX_REQUEST; + if (!hisr) + break; + } while (1); + + if (alloc_fail_time == 10) + DBG_871X("%s: exit because recv failed more than 10 times!\n", __func__); + } +} + +void sd_int_hdl(PADAPTER padapter) +{ + PHAL_DATA_TYPE phal; + + + if (RTW_CANNOT_RUN(padapter)) + return; + + phal = GET_HAL_DATA(padapter); + + phal->sdio_hisr = 0; + ReadInterrupt8188FSdio(padapter, &phal->sdio_hisr); + + if (phal->sdio_hisr & phal->sdio_himr) + { + u32 v32; + + phal->sdio_hisr &= phal->sdio_himr; + + // clear HISR + v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR; + if (v32) { + SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32); + } + + sd_int_dpc(padapter); + } else { + RT_TRACE(_module_hci_ops_c_, _drv_err_, + ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n", + __FUNCTION__, phal->sdio_hisr, phal->sdio_himr)); + } +} + +// +// Description: +// Query SDIO Local register to query current the number of Free TxPacketBuffer page. +// +// Assumption: +// 1. Running at PASSIVE_LEVEL +// 2. RT_TX_SPINLOCK is NOT acquired. +// +// Created by Roger, 2011.01.28. +// +u8 HalQueryTxBufferStatus8188FSdio(PADAPTER padapter) +{ + /* TODO: EXQ */ + PHAL_DATA_TYPE phal; + u1Byte NumOfFreePage[8]; + //_irqL irql; + + phal = GET_HAL_DATA(padapter); + + sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 8, NumOfFreePage); + + //_enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + phal->SdioTxFIFOFreePage[HI_QUEUE_IDX] = NumOfFreePage[0]; + phal->SdioTxFIFOFreePage[MID_QUEUE_IDX] = NumOfFreePage[2]; + phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = NumOfFreePage[4]; + phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = NumOfFreePage[6]; + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: Free page for HIQ(%#x),MIDQ(%#x),LOWQ(%#x),PUBQ(%#x)\n", + __FUNCTION__, + phal->SdioTxFIFOFreePage[HI_QUEUE_IDX], + phal->SdioTxFIFOFreePage[MID_QUEUE_IDX], + phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); + //_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + + return _TRUE; +} + +// +// Description: +// Query SDIO Local register to get the current number of TX OQT Free Space. +// +u8 HalQueryTxOQTBufferStatus8188FSdio(PADAPTER padapter) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_AC_OQT_FREEPG_8188F); + return _TRUE; +} + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +u8 RecvOnePkt(PADAPTER padapter, u32 size) +{ + struct recv_buf *precvbuf; + struct dvobj_priv *psddev; + PSDIO_DATA psdio_data; + struct sdio_func *func; + + u8 res = _FALSE; + + DBG_871X("+%s: size: %d+\n", __func__, size); + + if (padapter == NULL) { + DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__); + return _FALSE; + } + + psddev = adapter_to_dvobj(padapter); + psdio_data = &psddev->intf_data; + func = psdio_data->func; + + if(size) { + sdio_claim_host(func); + precvbuf = sd_recv_rxfifo(padapter, size); + + if (precvbuf) { + //printk("Completed Recv One Pkt.\n"); + sd_rxhandler(padapter, precvbuf); + res = _TRUE; + }else{ + res = _FALSE; + } + sdio_release_host(func); + } + DBG_871X("-%s-\n", __func__); + return res; +} +#endif //CONFIG_WOWLAN + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/ifcfg-wlan0 b/linux-3.4/drivers/net/wireless/rtl8189fs/ifcfg-wlan0 new file mode 100644 index 00000000..20dcbec2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/ifcfg-wlan0 @@ -0,0 +1,4 @@ +#DHCP client +DEVICE=wlan0 +BOOTPROTO=dhcp +ONBOOT=yes \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyCfg.h new file mode 100644 index 00000000..cbe8dcb6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyCfg.h @@ -0,0 +1,274 @@ +/****************************************************************************** + * + * 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_HAL8188EPHYCFG_H__ +#define __INC_HAL8188EPHYCFG_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +#define MAX_TX_COUNT_8188E 1 + +/* BB/RF related */ + + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +// +// BB and RF register read/write +// +u32 PHY_QueryBBReg8188E( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetBBReg8188E( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 PHY_QueryRFReg8188E( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetRFReg8188E( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +int PHY_MACConfig8188E(IN PADAPTER Adapter ); +int PHY_BBConfig8188E(IN PADAPTER Adapter ); +int PHY_RFConfig8188E(IN PADAPTER Adapter ); + +/* RF config */ +int rtl8188e_PHY_ConfigRFWithParaFile(IN PADAPTER Adapter, IN u8 * pFileName, u8 eRFPath); + +// +// RF Power setting +// +//extern BOOLEAN PHY_SetRFPowerState(IN PADAPTER Adapter, +// IN RT_RF_POWER_STATE eRFPowerState); + +// +// BB TX Power R/W +// +void PHY_GetTxPowerLevel8188E( IN PADAPTER Adapter, + OUT s32* powerlevel ); +void PHY_SetTxPowerLevel8188E( IN PADAPTER Adapter, + IN u8 channel ); +BOOLEAN PHY_UpdateTxPowerDbm8188E( IN PADAPTER Adapter, + IN int powerInDbm ); + +VOID +PHY_SetTxPowerIndex_8188E( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +u8 +PHY_GetTxPowerIndex_8188E( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +// +// Switch bandwidth for 8192S +// +//extern void PHY_SetBWModeCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SetBWMode8188E( IN PADAPTER pAdapter, + IN CHANNEL_WIDTH ChnlWidth, + IN unsigned char Offset ); + +// +// Set FW CMD IO for 8192S. +// +//extern BOOLEAN HalSetIO8192C( IN PADAPTER Adapter, +// IN IO_TYPE IOType); + +// +// Set A2 entry to fw for 8192S +// +extern void FillA2Entry8192C( IN PADAPTER Adapter, + IN u8 index, + IN u8* val); + + +// +// channel switch related funciton +// +//extern void PHY_SwChnlCallback8192C( IN PRT_TIMER pTimer ); +void PHY_SwChnl8188E( IN PADAPTER pAdapter, + IN u8 channel ); + +VOID +PHY_SetSwChnlBWMode8188E( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +// +// BB/MAC/RF other monitor API +// +void PHY_SetMonitorMode8192C(IN PADAPTER pAdapter, + IN BOOLEAN bEnableMonitorMode ); + +BOOLEAN PHY_CheckIsLegalRfPath8192C(IN PADAPTER pAdapter, + IN u32 eRFPath ); + +VOID PHY_SetRFPathSwitch_8188E(IN PADAPTER pAdapter, IN BOOLEAN bMain); + +extern VOID +PHY_SwitchEphyParameter( + IN PADAPTER Adapter + ); + +extern VOID +PHY_EnableHostClkReq( + IN PADAPTER Adapter + ); + +BOOLEAN +SetAntennaConfig92C( + IN PADAPTER Adapter, + IN u8 DefaultAnt + ); + +VOID +storePwrIndexDiffRateOffset( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); +/*--------------------------Exported Function prototype---------------------*/ + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +//extern s32 PHY_MACConfig8723(PADAPTER padapter); +//s32 PHY_BBConfig8723(PADAPTER padapter); +//s32 PHY_RFConfig8723(PADAPTER padapter); + + + +//================================================================== +// Note: If SIC_ENABLE under PCIE, because of the slow operation +// you should +// 2) "#define RTL8723_FPGA_VERIFICATION 1" in Precomp.h.WlanE.Windows +// 3) "#define RTL8190_Download_Firmware_From_Header 0" in Precomp.h.WlanE.Windows if needed. +// +#if (RTL8188E_SUPPORT == 1) && (RTL8188E_FPGA_TRUE_PHY_VERIFICATION == 1) +#define SIC_ENABLE 1 +#define SIC_HW_SUPPORT 1 +#else +#define SIC_ENABLE 0 +#define SIC_HW_SUPPORT 0 +#endif +//================================================================== + + +#define SIC_MAX_POLL_CNT 5 + +#if(SIC_HW_SUPPORT == 1) +#define SIC_CMD_READY 0 +#define SIC_CMD_PREWRITE 0x1 +#if(RTL8188E_SUPPORT == 1) +#define SIC_CMD_WRITE 0x40 +#define SIC_CMD_PREREAD 0x2 +#define SIC_CMD_READ 0x80 +#define SIC_CMD_INIT 0xf0 +#define SIC_INIT_VAL 0xff + +#define SIC_INIT_REG 0x1b7 +#define SIC_CMD_REG 0x1EB // 1byte +#define SIC_ADDR_REG 0x1E8 // 1b4~1b5, 2 bytes +#define SIC_DATA_REG 0x1EC // 1b0~1b3 +#else +#define SIC_CMD_WRITE 0x11 +#define SIC_CMD_PREREAD 0x2 +#define SIC_CMD_READ 0x12 +#define SIC_CMD_INIT 0x1f +#define SIC_INIT_VAL 0xff + +#define SIC_INIT_REG 0x1b7 +#define SIC_CMD_REG 0x1b6 // 1byte +#define SIC_ADDR_REG 0x1b4 // 1b4~1b5, 2 bytes +#define SIC_DATA_REG 0x1b0 // 1b0~1b3 +#endif +#else +#define SIC_CMD_READY 0 +#define SIC_CMD_WRITE 1 +#define SIC_CMD_READ 2 + +#if(RTL8188E_SUPPORT == 1) +#define SIC_CMD_REG 0x1EB // 1byte +#define SIC_ADDR_REG 0x1E8 // 1b9~1ba, 2 bytes +#define SIC_DATA_REG 0x1EC // 1bc~1bf +#else +#define SIC_CMD_REG 0x1b8 // 1byte +#define SIC_ADDR_REG 0x1b9 // 1b9~1ba, 2 bytes +#define SIC_DATA_REG 0x1bc // 1bc~1bf +#endif +#endif + +#if(SIC_ENABLE == 1) +VOID SIC_Init(IN PADAPTER Adapter); +#endif + + +#endif // __INC_HAL8192CPHYCFG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyReg.h new file mode 100644 index 00000000..2113a260 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPhyReg.h @@ -0,0 +1,1106 @@ +/****************************************************************************** + * + * 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_HAL8188EPHYREG_H__ +#define __INC_HAL8188EPHYREG_H__ +/*--------------------------Define Parameters-------------------------------*/ +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + + + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_csi_fix_mask1 0xd40 +#define rOFDM1_csi_fix_mask2 0xd44 +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // + +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 +#define RF_POW_ABILITY 0x17 // +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER_88E 0x42 // +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B +#define RF_0x52 0x52 +#define RF_WE_LUT 0xEF + + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + + + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPwrSeq.h new file mode 100644 index 00000000..41f852f2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188EPwrSeq.h @@ -0,0 +1,176 @@ + +/****************************************************************************** + * + * 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 __HAL8188EPWRSEQ_H__ +#define __HAL8188EPWRSEQ_H__ + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END + + PWR SEQ Version: rtl8188E_PwrSeq_V09.h +*/ +#define RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS 10 +#define RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS 10 +#define RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS 10 +#define RTL8188E_TRANS_SUS_TO_CARDEMU_STEPS 10 +#define RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS 10 +#define RTL8188E_TRANS_PDN_TO_CARDEMU_STEPS 10 +#define RTL8188E_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8188E_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8188E_TRANS_END_STEPS 1 + + +#define RTL8188E_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0|BIT1, 0}, /* 0x02[1:0] = 0 reset BB*/ \ + {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7}, /*0x24[23] = 2b'01 schmit trigger */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0}, /* 0x04[15] = 0 disable HWPDN (control by DRV)*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, 0}, /*0x04[12:11] = 2b'00 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x04[8] = 1 polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0}, /*wait till 0x04[8] = 0*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*LDO normal mode*/ \ + +#define RTL8188E_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*LDO Sleep mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + +#define RTL8188E_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11enable WL suspend for PCIe*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, BIT7}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ + {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8188E_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8188E_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0026, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7}, /*0x24[23] = 2b'01 schmit trigger */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /* 0x04[31:30] = 2b'10 enable enable bandgap mbias in suspend */ \ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*Clear SIC_EN register 0x40[12] = 1'b0 */ \ + {0xfe10, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*Set USB suspend enable local register 0xfe10[4]=1 */ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8188E_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8188E_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8188E_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +//This is used by driver for LPSRadioOff Procedure, not for FW LPS Step +#define RTL8188E_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8188E_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8188E_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_radio_off_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_card_disable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_card_enable_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_suspend_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_resume_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_hwpdn_flow[RTL8188E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_enter_lps_flow[RTL8188E_TRANS_ACT_TO_LPS_STEPS+RTL8188E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188E_leave_lps_flow[RTL8188E_TRANS_LPS_TO_ACT_STEPS+RTL8188E_TRANS_END_STEPS]; + +#endif //__HAL8188EPWRSEQ_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyCfg.h new file mode 100644 index 00000000..9d729ff9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyCfg.h @@ -0,0 +1,149 @@ +/****************************************************************************** + * + * 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_HAL8188FPHYCFG_H__ +#define __INC_HAL8188FPHYCFG_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters End-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure End----------------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ +u32 +PHY_QueryBBReg_8188F( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetBBReg_8188F( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +u32 +PHY_QueryRFReg_8188F( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetRFReg_8188F( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +/* MAC/BB/RF HAL config */ +int PHY_BBConfig8188F(PADAPTER Adapter ); + +int PHY_RFConfig8188F(PADAPTER Adapter ); + +s32 PHY_MACConfig8188F(PADAPTER padapter); + +int +PHY_ConfigRFWithParaFile_8188F( + IN PADAPTER Adapter, + IN u8* pFileName, + RF_PATH eRFPath +); + +VOID +PHY_SetTxPowerIndex_8188F( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +u8 +PHY_GetTxPowerIndex_8188F( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_GetTxPowerLevel8188F( + IN PADAPTER Adapter, + OUT s32* powerlevel + ); + +VOID +PHY_SetTxPowerLevel8188F( + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetBWMode8188F( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN unsigned char Offset // Upper, Lower, or Don't care +); + +VOID +PHY_SwChnl8188F( // Call after initialization + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetSwChnlBWMode8188F( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +VOID PHY_SetRFPathSwitch_8188F( + IN PADAPTER pAdapter, + IN BOOLEAN bMain + ); +/*--------------------------Exported Function prototype End---------------------*/ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyReg.h new file mode 100644 index 00000000..817ff8e8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPhyReg.h @@ -0,0 +1,1171 @@ +/****************************************************************************** + * + * 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_HAL8188FPHYREG_H__ +#define __INC_HAL8188FPHYREG_H__ + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c + +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? +#define rS0S1_PathSwitch 0x948 + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B +#define RF_0x52 0x52 +#define RF_RXG_MIX_SWBW 0x87 +#define RF_DBG_LP_RX2 0xDF +#define RF_WE_LUT 0xEF +#define RF_S0S1 0xB0 + +#define RF_TX_GAIN_OFFSET_8188F(_val) (abs((_val)) | (((_val) > 0) ? BIT5 : 0)) + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +/*--------------------------Define Parameters-------------------------------*/ + + +// BB Register Definition +// +// 4. Page9(0x900) +// +#define rDPDT_control 0x92c +#define rfe_ctrl_anta_src 0x930 +#define rS0S1_PathSwitch 0x948 +#define BBrx_DFIR 0x954 +#define AGC_table_select 0xb2c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rPdp_AntA_8 0xb08 +#define rPdp_AntA_C 0xb0c +#define rPdp_AntA_10 0xb10 +#define rPdp_AntA_14 0xb14 +#define rPdp_AntA_18 0xb18 +#define rPdp_AntA_1C 0xb1c +#define rPdp_AntA_20 0xb20 +#define rPdp_AntA_24 0xb24 + +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rBndA 0xb30 +#define rHssiPar 0xb34 + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c + +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rPdp_AntB_8 0xb78 +#define rPdp_AntB_C 0xb7c +#define rPdp_AntB_10 0xb80 +#define rPdp_AntB_14 0xb84 +#define rPdp_AntB_18 0xb88 +#define rPdp_AntB_1C 0xb8c +#define rPdp_AntB_20 0xb90 +#define rPdp_AntB_24 0xb94 + +#define rConfig_Pmpd_AntB 0xb98 + +#define rBndB 0xba0 + +#define rAPK 0xbd8 +#define rPm_Rx0_AntA 0xbdc +#define rPm_Rx1_AntA 0xbe0 +#define rPm_Rx2_AntA 0xbe4 +#define rPm_Rx3_AntA 0xbe8 +#define rPm_Rx0_AntB 0xbec +#define rPm_Rx1_AntB 0xbf0 +#define rPm_Rx2_AntB 0xbf4 +#define rPm_Rx3_AntB 0xbf8 + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPwrSeq.h new file mode 100644 index 00000000..b6d0c59a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8188FPwrSeq.h @@ -0,0 +1,199 @@ +#ifndef REALTEK_POWER_SEQUENCE_8188F +#define REALTEK_POWER_SEQUENCE_8188F + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20130815-JackieLau-RTL8188F_Power_Architecture v08.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8188F_TRANS_CARDEMU_TO_ACT_STEPS 13 +#define RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8188F_TRANS_CARDEMU_TO_SUS_STEPS 14 +#define RTL8188F_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8188F_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8188F_TRANS_ACT_TO_LPS_STEPS 11 +#define RTL8188F_TRANS_LPS_TO_ACT_STEPS 13 +#define RTL8188F_TRANS_ACT_TO_SWLPS_STEPS 21 +#define RTL8188F_TRANS_SWLPS_TO_ACT_STEPS 14 +#define RTL8188F_TRANS_END_STEPS 1 + + +#define RTL8188F_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT3), 0},/* 0x4[11]=1'b0 disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* 0x4[8]=1 polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x0027, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0x35}, /*0x27<=35 to reduce RF noise*/ + +#define RTL8188F_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x0027, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0x34}, /*0x27 <= 34, xtal_qsel=0 to xtal bring up*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + +#define RTL8188F_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00}, /*0x07=0x00 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, BIT4},/* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode*/ + +#define RTL8188F_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0},/* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode*/ + +#define RTL8188F_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00}, /*0x07=0x00 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, BIT4},/* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode*/ + +#define RTL8188F_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT4, 0},/* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode*/ + + +#define RTL8188F_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8188F_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8188F_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0139, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*set RPWM IMR*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ + + +#define RTL8188F_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0027, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xff,0x35},/*xtal_qsel=1 for low noise*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x002B, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x1c, 0x1c}, /*. 0x2b[4:2] = 3b'111 to enable BB,AFE clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + + #define RTL8188F_TRANS_ACT_TO_SWLPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0139, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0},/*set RPWM IMR*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + {0x002b, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0x1C, 0x00},/*0x2b[4:2]<=0 to gated BB,AFE clock*/ \ + {0x0027, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0x34},/*xtal_qsel=0 for bring up*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0x00},/* sdio LPS option*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0x83},/* usb LPS option, open bandgap, xtal*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT5, 0}, /* 0xC4[5]<=0, digital LDO no standby mode*/ \ + {0x00C4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT7, BIT7}, /* 0xC4[7]<=1, on domain voltage adjust*/ \ + {0x00a7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0xe0}, /* low power LPS enable for sdio*/ \ + {0x00a7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xff, 0xe4}, /* low power LPS enable for usb*/ \ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT0, BIT0}, /* enable WL_LPS_EN*/ + + +#define RTL8188F_TRANS_SWLPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*polling TSF stable*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1, enable security engine*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x06B7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x09}, /*. reset MAC rx state machine*/\ + {0x06B4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x86}, /*. reset MAC rx state machine*/\ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/* set CPU RAM code ready*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* Enable CPU*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2},/* Enable CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, BIT7},/*polling FW init ready */ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT6, BIT6},/*polling FW init ready */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8188F_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8188F_power_on_flow[RTL8188F_TRANS_CARDEMU_TO_ACT_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_radio_off_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_card_disable_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_card_enable_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_suspend_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_resume_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_CARDEMU_TO_SUS_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_hwpdn_flow[RTL8188F_TRANS_ACT_TO_CARDEMU_STEPS+RTL8188F_TRANS_CARDEMU_TO_PDN_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_enter_lps_flow[RTL8188F_TRANS_ACT_TO_LPS_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_leave_lps_flow[RTL8188F_TRANS_LPS_TO_ACT_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_enter_swlps_flow[RTL8188F_TRANS_ACT_TO_SWLPS_STEPS+RTL8188F_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8188F_leave_swlps_flow[RTL8188F_TRANS_SWLPS_TO_ACT_STEPS+RTL8188F_TRANS_END_STEPS]; +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyCfg.h new file mode 100644 index 00000000..99563fe0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyCfg.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * 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_HAL8192EPHYCFG_H__ +#define __INC_HAL8192EPHYCFG_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters-------------------------------*/ + +/*------------------------------Define structure----------------------------*/ + +/* BB/RF related */ + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +// +// BB and RF register read/write +// +u32 PHY_QueryBBReg8192E( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetBBReg8192E( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 PHY_QueryRFReg8192E( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetRFReg8192E( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +int PHY_MACConfig8192E(IN PADAPTER Adapter ); +int PHY_BBConfig8192E(IN PADAPTER Adapter ); +int PHY_RFConfig8192E(IN PADAPTER Adapter ); + +/* RF config */ + + +// +// BB TX Power R/W +// +void PHY_GetTxPowerLevel8192E( IN PADAPTER Adapter, OUT s32* powerlevel ); +void PHY_SetTxPowerLevel8192E( IN PADAPTER Adapter, IN u8 channel ); +BOOLEAN PHY_UpdateTxPowerDbm8192E( IN PADAPTER Adapter, IN int powerInDbm ); + +VOID +PHY_SetTxPowerIndex_8192E( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +u8 +PHY_GetTxPowerIndex_8192E( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +// +// Switch bandwidth for 8192S +// +VOID +PHY_SetBWMode8192E( + IN PADAPTER pAdapter, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset +); + +// +// channel switch related funciton +// +VOID +PHY_SwChnl8192E( + IN PADAPTER Adapter, + IN u8 channel +); + + +VOID +PHY_SetSwChnlBWMode8192E( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +VOID +PHY_SetRFEReg_8192E( + IN PADAPTER Adapter +); + +void +phy_SpurCalibration_8192E( + IN PADAPTER Adapter, + IN SPUR_CAL_METHOD Method +); +void PHY_SpurCalibration_8192E(IN PADAPTER Adapter); + +#ifdef CONFIG_SPUR_CAL_NBI +void +phy_SpurCalibration_8192E_NBI( + IN PADAPTER Adapter +); +#endif +// +// BB/MAC/RF other monitor API +// + +VOID +PHY_SetRFPathSwitch_8192E( + IN PADAPTER pAdapter, + IN BOOLEAN bMain +); + +VOID +storePwrIndexDiffRateOffset( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +/*--------------------------Exported Function prototype---------------------*/ +#endif // __INC_HAL8192CPHYCFG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyReg.h new file mode 100644 index 00000000..20627341 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPhyReg.h @@ -0,0 +1,1133 @@ +/***************************************************************************** + * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved. + * + * Module: __INC_HAL8192SPHYREG_H + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __INC_HAL8192EPHYREG_H +#define __INC_HAL8192EPHYREG_H + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + + + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // + +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 +#define RF_POW_ABILITY 0x17 // +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER_8192E 0x42 // +#define RF_T_METER_88E 0x42 // +#define RF_T_METER 0x24 // + +//#endif + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B +#define RF_0x52 0x52 +#define RF_LDO 0xB1 +#define RF_WE_LUT 0xEF + + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) +#define RF_TX_GAIN_OFFSET_8192E(_val) ((abs((_val)) << 1) | (((_val) > 0) ? BIT0 : 0)) + + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + + +// RSSI Dump Message +#define rA_RSSIDump_92E 0xcb0 +#define rB_RSSIDump_92E 0xcb1 +#define rS1_RXevmDump_92E 0xcb2 +#define rS2_RXevmDump_92E 0xcb3 +#define rA_RXsnrDump_92E 0xcb4 +#define rB_RXsnrDump_92E 0xcb5 +#define rA_CfoShortDump_92E 0xcb6 +#define rB_CfoShortDump_92E 0xcb8 +#define rA_CfoLongDump_92E 0xcba +#define rB_CfoLongDump_92E 0xcbc + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8188EPHYREG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPwrSeq.h new file mode 100644 index 00000000..7acc0d18 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8192EPwrSeq.h @@ -0,0 +1,155 @@ +#ifndef REALTEK_POWER_SEQUENCE_8192E +#define REALTEK_POWER_SEQUENCE_8192E + +#include "HalPwrSeqCmd.h" +/* + Check document WM-20110607-Paul-RTL8192E_Power_Architecture-R02.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8192E_TRANS_CARDEMU_TO_ACT_STEPS 18 +#define RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS 18 +#define RTL8192E_TRANS_SUS_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS 18 +#define RTL8192E_TRANS_PDN_TO_CARDEMU_STEPS 18 +#define RTL8192E_TRANS_ACT_TO_LPS_STEPS 23 +#define RTL8192E_TRANS_LPS_TO_ACT_STEPS 23 +#define RTL8192E_TRANS_END_STEPS 1 + + +#define RTL8192E_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + + +#define RTL8192E_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + + +#define RTL8192E_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8192E_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8192E_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*Unlock small LDO Register*/ \ + {0x0011, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*Disable small LDO*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8192E_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0011, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*Enable small LDO*/ \ + {0x00CC, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*Lock small LDO Register*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + + +#define RTL8192E_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8192E_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8192E_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8192E_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM, For Repeatly In and out, Taggle bit should be changed*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/\ + {0x013D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*Clear ISR*/ + +#define RTL8192E_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8192E_power_on_flow[RTL8192E_TRANS_CARDEMU_TO_ACT_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_radio_off_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_card_disable_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_card_enable_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_suspend_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_resume_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_CARDEMU_TO_SUS_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_hwpdn_flow[RTL8192E_TRANS_ACT_TO_CARDEMU_STEPS+RTL8192E_TRANS_CARDEMU_TO_PDN_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_enter_lps_flow[RTL8192E_TRANS_ACT_TO_LPS_STEPS+RTL8192E_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8192E_leave_lps_flow[RTL8192E_TRANS_LPS_TO_ACT_STEPS+RTL8192E_TRANS_END_STEPS]; + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyCfg.h new file mode 100644 index 00000000..9df208ee --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyCfg.h @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * 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_HAL8703BPHYCFG_H__ +#define __INC_HAL8703BPHYCFG_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters End-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure End----------------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ +u32 +PHY_QueryBBReg_8703B( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetBBReg_8703B( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +u32 +PHY_QueryRFReg_8703B( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetRFReg_8703B( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +/* MAC/BB/RF HAL config */ +int PHY_BBConfig8703B(PADAPTER Adapter ); + +int PHY_RFConfig8703B(PADAPTER Adapter ); + +s32 PHY_MACConfig8703B(PADAPTER padapter); + +int +PHY_ConfigRFWithParaFile_8703B( + IN PADAPTER Adapter, + IN u8* pFileName, + RF_PATH eRFPath +); + +VOID +PHY_SetTxPowerIndex_8703B( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +u8 +PHY_GetTxPowerIndex_8703B( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_GetTxPowerLevel8703B( + IN PADAPTER Adapter, + OUT s32* powerlevel + ); + +VOID +PHY_SetTxPowerLevel8703B( + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetBWMode8703B( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN unsigned char Offset // Upper, Lower, or Don't care +); + +VOID +PHY_SwChnl8703B( // Call after initialization + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetSwChnlBWMode8703B( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); +/*--------------------------Exported Function prototype End---------------------*/ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyReg.h new file mode 100644 index 00000000..5f0f23f9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPhyReg.h @@ -0,0 +1,1139 @@ +/****************************************************************************** + * + * 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_HAL8703BPHYREG_H__ +#define __INC_HAL8703BPHYREG_H__ + +#define rSYM_WLBT_PAPE_SEL 0x64 +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c + +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? +#define rDPDT_control 0x92c +#define rfe_ctrl_anta_src 0x930 +#define rS0S1_PathSwitch 0x948 +#define rBBrx_DFIR 0x954 + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rPdp_AntA_8 0xb08 +#define rPdp_AntA_C 0xb0c +#define rPdp_AntA_10 0xb10 +#define rPdp_AntA_14 0xb14 +#define rPdp_AntA_18 0xb18 +#define rPdp_AntA_1C 0xb1c +#define rPdp_AntA_20 0xb20 +#define rPdp_AntA_24 0xb24 + +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rBndA 0xb30 +#define rHssiPar 0xb34 + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c + +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rPdp_AntB_8 0xb78 +#define rPdp_AntB_C 0xb7c +#define rPdp_AntB_10 0xb80 +#define rPdp_AntB_14 0xb84 +#define rPdp_AntB_18 0xb88 +#define rPdp_AntB_1C 0xb8c +#define rPdp_AntB_20 0xb90 +#define rPdp_AntB_24 0xb94 + +#define rConfig_Pmpd_AntB 0xb98 + +#define rBndB 0xba0 + +#define rAPK 0xbd8 +#define rPm_Rx0_AntA 0xbdc +#define rPm_Rx1_AntA 0xbe0 +#define rPm_Rx2_AntA 0xbe4 +#define rPm_Rx3_AntA 0xbe8 +#define rPm_Rx0_AntB 0xbec +#define rPm_Rx1_AntB 0xbf0 +#define rPm_Rx2_AntB 0xbf4 +#define rPm_Rx3_AntB 0xbf8 +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B +#define RF_0x52 0x52 +#define RF_WE_LUT 0xEF +#define RF_S0S1 0xB0 + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) +#define RF_TX_GAIN_OFFSET_8703B(_val) (abs((_val)) | (((_val) > 0) ? BIT5 : 0)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPwrSeq.h new file mode 100644 index 00000000..c61519aa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8703BPwrSeq.h @@ -0,0 +1,184 @@ +#ifndef REALTEK_POWER_SEQUENCE_8703B +#define REALTEK_POWER_SEQUENCE_8703B + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20140402-JackieLau-RTL8703B_Power_Architecture v09.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8703B_TRANS_CARDEMU_TO_ACT_STEPS 23 +#define RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8703B_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8703B_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8703B_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8703B_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8703B_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8703B_TRANS_END_STEPS 1 + + +#define RTL8703B_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3|BIT2), 0},/* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[11]=0*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , BIT0},/* Disable USB suspend */ \ + {0x0004, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 , BIT3},/* enabled usb resume */ \ + {0x0004, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 , 0},/* disable usb resume */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , 0},/* Enable USB suspend */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* Enable WL control XTAL setting*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable falling edge triggering interrupt*/\ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable GPIO9 interrupt mode*/\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable GPIO9 input mode*/\ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Enable HSISR GPIO[C:0] interrupt*/\ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable HSISR GPIO9 interrupt*/\ + {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3},/*For GPIO9 internal pull high setting by test chip*/\ + {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/*For GPIO9 internal pull high setting*/\ + + +#define RTL8703B_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable rising edge triggering interrupt*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/* Enable BT control XTAL setting*/\ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/\ + + +#define RTL8703B_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8703B_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8703B_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8703B_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8703B_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8703B_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8703B_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8703B_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8703B_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8703B_power_on_flow[RTL8703B_TRANS_CARDEMU_TO_ACT_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_radio_off_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_card_disable_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_card_enable_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_suspend_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_resume_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_hwpdn_flow[RTL8703B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8703B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_enter_lps_flow[RTL8703B_TRANS_ACT_TO_LPS_STEPS+RTL8703B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8703B_leave_lps_flow[RTL8703B_TRANS_LPS_TO_ACT_STEPS+RTL8703B_TRANS_END_STEPS]; + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyCfg.h new file mode 100644 index 00000000..534e1be3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyCfg.h @@ -0,0 +1,149 @@ +/****************************************************************************** + * + * 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_HAL8723BPHYCFG_H__ +#define __INC_HAL8723BPHYCFG_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters End-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure End----------------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ +u32 +PHY_QueryBBReg_8723B( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetBBReg_8723B( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +u32 +PHY_QueryRFReg_8723B( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetRFReg_8723B( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +/* MAC/BB/RF HAL config */ +int PHY_BBConfig8723B(PADAPTER Adapter ); + +int PHY_RFConfig8723B(PADAPTER Adapter ); + +s32 PHY_MACConfig8723B(PADAPTER padapter); + +int +PHY_ConfigRFWithParaFile_8723B( + IN PADAPTER Adapter, + IN u8* pFileName, + RF_PATH eRFPath +); + +VOID +PHY_SetTxPowerIndex_8723B( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +u8 +PHY_GetTxPowerIndex_8723B( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_GetTxPowerLevel8723B( + IN PADAPTER Adapter, + OUT s32* powerlevel + ); + +VOID +PHY_SetTxPowerLevel8723B( + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetBWMode8723B( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN unsigned char Offset // Upper, Lower, or Don't care +); + +VOID +PHY_SwChnl8723B( // Call after initialization + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetSwChnlBWMode8723B( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +VOID PHY_SetRFPathSwitch_8723B( + IN PADAPTER pAdapter, + IN BOOLEAN bMain + ); +/*--------------------------Exported Function prototype End---------------------*/ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyReg.h new file mode 100644 index 00000000..ff444b27 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPhyReg.h @@ -0,0 +1,1137 @@ +/****************************************************************************** + * + * 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_HAL8723BPHYREG_H__ +#define __INC_HAL8723BPHYREG_H__ + +#define rSYM_WLBT_PAPE_SEL 0x64 +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c + +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? +#define rDPDT_control 0x92c +#define rfe_ctrl_anta_src 0x930 +#define rS0S1_PathSwitch 0x948 + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rPdp_AntA_8 0xb08 +#define rPdp_AntA_C 0xb0c +#define rPdp_AntA_10 0xb10 +#define rPdp_AntA_14 0xb14 +#define rPdp_AntA_18 0xb18 +#define rPdp_AntA_1C 0xb1c +#define rPdp_AntA_20 0xb20 +#define rPdp_AntA_24 0xb24 + +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rBndA 0xb30 +#define rHssiPar 0xb34 + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c + +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rPdp_AntB_8 0xb78 +#define rPdp_AntB_C 0xb7c +#define rPdp_AntB_10 0xb80 +#define rPdp_AntB_14 0xb84 +#define rPdp_AntB_18 0xb88 +#define rPdp_AntB_1C 0xb8c +#define rPdp_AntB_20 0xb90 +#define rPdp_AntB_24 0xb94 + +#define rConfig_Pmpd_AntB 0xb98 + +#define rBndB 0xba0 + +#define rAPK 0xbd8 +#define rPm_Rx0_AntA 0xbdc +#define rPm_Rx1_AntA 0xbe0 +#define rPm_Rx2_AntA 0xbe4 +#define rPm_Rx3_AntA 0xbe8 +#define rPm_Rx0_AntB 0xbec +#define rPm_Rx1_AntB 0xbf0 +#define rPm_Rx2_AntB 0xbf4 +#define rPm_Rx3_AntB 0xbf8 +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C // +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B +#define RF_0x52 0x52 +#define RF_WE_LUT 0xEF +#define RF_S0S1 0xB0 + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPwrSeq.h new file mode 100644 index 00000000..d2124454 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723BPwrSeq.h @@ -0,0 +1,233 @@ +#ifndef REALTEK_POWER_SEQUENCE_8723B +#define REALTEK_POWER_SEQUENCE_8723B + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20130815-JackieLau-RTL8723B_Power_Architecture v08.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS 26 +#define RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8723B_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8723B_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8723B_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8723B_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8723B_TRANS_ACT_TO_SWLPS_STEPS 22 +#define RTL8723B_TRANS_SWLPS_TO_ACT_STEPS 15 +#define RTL8723B_TRANS_END_STEPS 1 + + +#define RTL8723B_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3|BIT2), 0},/* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[11]=0*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , BIT0},/* Disable USB suspend */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , 0},/* Enable USB suspend */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* Enable WL control XTAL setting*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable falling edge triggering interrupt*/\ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable GPIO9 interrupt mode*/\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable GPIO9 input mode*/\ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Enable HSISR GPIO[C:0] interrupt*/\ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable HSISR GPIO9 interrupt*/\ + {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3},/*For GPIO9 internal pull high setting by test chip*/\ + {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/*For GPIO9 internal pull high setting*/\ + + +#define RTL8723B_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable rising edge triggering interrupt*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/* Enable BT control XTAL setting*/\ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/\ + + +#define RTL8723B_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723B_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8723B_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8723B_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8723B_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8723B_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + + #define RTL8723B_TRANS_ACT_TO_SWLPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable 32 K source*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*disable security engine*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x40},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*reset dual TSF*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/*Reset CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*Reset MCUFWDL register*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*Reset CPU IO Wrapper*/ \ + {0x0287, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*polling RXFF packet number = 0 */ \ + {0x0286, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/*polling RXDMA idle */ \ + {0x013D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Clear FW RPWM interrupt */\ + {0x0139, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW RPWM interrupt source*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/*polling TSF stable*/\ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW LPS*/ \ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/*polling FW LPS ready */ + + +#define RTL8723B_TRANS_SWLPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*polling TSF stable*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1, enable security engine*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x06B7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x09}, /*. reset MAC rx state machine*/\ + {0x06B4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x86}, /*. reset MAC rx state machine*/\ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/* set CPU RAM code ready*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* Enable CPU*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2},/* Enable CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, BIT7},/*polling FW init ready */ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT6, BIT6},/*polling FW init ready */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8723B_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_radio_off_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_card_disable_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_card_enable_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_suspend_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_resume_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_hwpdn_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_enter_lps_flow[RTL8723B_TRANS_ACT_TO_LPS_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_leave_lps_flow[RTL8723B_TRANS_LPS_TO_ACT_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_enter_swlps_flow[RTL8723B_TRANS_ACT_TO_SWLPS_STEPS+RTL8723B_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723B_leave_swlps_flow[RTL8723B_TRANS_SWLPS_TO_ACT_STEPS+RTL8723B_TRANS_END_STEPS]; +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723PwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723PwrSeq.h new file mode 100644 index 00000000..307ac90d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8723PwrSeq.h @@ -0,0 +1,170 @@ +#ifndef __HAL8723PWRSEQ_H__ +#define __HAL8723PWRSEQ_H__ +/* + Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#include "HalPwrSeqCmd.h" + +#define RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS 15 +#define RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8723A_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8723A_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8723A_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8723A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8723A_TRANS_END_STEPS 1 + + +#define RTL8723A_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 1},/*0x4C[23] = 0x4E[7] = 1, switch DPDT_SEL_P output from WL BB */\ + +#define RTL8723A_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \ + + +#define RTL8723A_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723A_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8723A_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8723A_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8723A_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8723A_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8723A_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STEPS+RTL8723A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS]; + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyCfg.h new file mode 100644 index 00000000..f8c83e15 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyCfg.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * 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_HAL8812PHYCFG_H__ +#define __INC_HAL8812PHYCFG_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters-------------------------------*/ + +/*------------------------------Define structure----------------------------*/ + + +/* BB/RF related */ + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +// +// BB and RF register read/write +// +u32 PHY_QueryBBReg8812( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetBBReg8812( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); +u32 PHY_QueryRFReg8812( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); +void PHY_SetRFReg8812( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +// +// Initialization related function +// +/* MAC/BB/RF HAL config */ +int PHY_MACConfig8812(IN PADAPTER Adapter ); +int PHY_BBConfig8812(IN PADAPTER Adapter ); +void PHY_BB8812_Config_1T(IN PADAPTER Adapter ); +int PHY_RFConfig8812(IN PADAPTER Adapter ); + +/* RF config */ + +s32 +PHY_SwitchWirelessBand8812( + IN PADAPTER Adapter, + IN u8 Band +); + +// +// BB TX Power R/W +// +void PHY_GetTxPowerLevel8812( IN PADAPTER Adapter, OUT s32* powerlevel ); +void PHY_SetTxPowerLevel8812( IN PADAPTER Adapter, IN u8 Channel ); + +BOOLEAN PHY_UpdateTxPowerDbm8812( IN PADAPTER Adapter, IN int powerInDbm ); +u8 PHY_GetTxPowerIndex_8812A( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +u32 PHY_GetTxBBSwing_8812A( + IN PADAPTER Adapter, + IN BAND_TYPE Band, + IN u8 RFPath + ); + +VOID +PHY_SetTxPowerIndex_8812A( + IN PADAPTER Adapter, + IN u4Byte PowerIndex, + IN u1Byte RFPath, + IN u1Byte Rate + ); + +// +// Switch bandwidth for 8192S +// +VOID +PHY_SetBWMode8812( + IN PADAPTER pAdapter, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset +); + +// +// channel switch related funciton +// +VOID +PHY_SwChnl8812( + IN PADAPTER Adapter, + IN u8 channel +); + + +VOID +PHY_SetSwChnlBWMode8812( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +// +// BB/MAC/RF other monitor API +// + +VOID +PHY_SetRFPathSwitch_8812A( + IN PADAPTER pAdapter, + IN BOOLEAN bMain +); + +/*--------------------------Exported Function prototype---------------------*/ +#endif // __INC_HAL8192CPHYCFG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyReg.h new file mode 100644 index 00000000..0fe2b589 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PhyReg.h @@ -0,0 +1,739 @@ +/****************************************************************************** + * + * 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_HAL8812PHYREG_H__ +#define __INC_HAL8812PHYREG_H__ +/*--------------------------Define Parameters-------------------------------*/ +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// BB Register Definition + +#define rCCAonSec_Jaguar 0x838 +#define rPwed_TH_Jaguar 0x830 + +// BW and sideband setting +#define rBWIndication_Jaguar 0x834 +#define rL1PeakTH_Jaguar 0x848 +#define rFPGA0_XA_LSSIReadBack 0x8a0 /*Tranceiver LSSI Readback*/ +#define rRFMOD_Jaguar 0x8ac //RF mode +#define rADC_Buf_Clk_Jaguar 0x8c4 +#define rRFECTRL_Jaguar 0x900 +#define bRFMOD_Jaguar 0xc3 +#define rCCK_System_Jaguar 0xa00 // for cck sideband +#define bCCK_System_Jaguar 0x10 + +// Block & Path enable +#define rOFDMCCKEN_Jaguar 0x808 // OFDM/CCK block enable +#define bOFDMEN_Jaguar 0x20000000 +#define bCCKEN_Jaguar 0x10000000 +#define rRxPath_Jaguar 0x808 // Rx antenna +#define bRxPath_Jaguar 0xff +#define rTxPath_Jaguar 0x80c // Tx antenna +#define bTxPath_Jaguar 0x0fffffff +#define rCCK_RX_Jaguar 0xa04 // for cck rx path selection +#define bCCK_RX_Jaguar 0x0c000000 +#define rVhtlen_Use_Lsig_Jaguar 0x8c3 // Use LSIG for VHT length + +// RF read/write-related +#define rHSSIRead_Jaguar 0x8b0 // RF read addr +#define bHSSIRead_addr_Jaguar 0xff +#define bHSSIRead_trigger_Jaguar 0x100 +#define rA_PIRead_Jaguar 0xd04 // RF readback with PI +#define rB_PIRead_Jaguar 0xd44 // RF readback with PI +#define rA_SIRead_Jaguar 0xd08 // RF readback with SI +#define rB_SIRead_Jaguar 0xd48 // RF readback with SI +#define rRead_data_Jaguar 0xfffff +#define rA_LSSIWrite_Jaguar 0xc90 // RF write addr +#define rB_LSSIWrite_Jaguar 0xe90 // RF write addr +#define bLSSIWrite_data_Jaguar 0x000fffff +#define bLSSIWrite_addr_Jaguar 0x0ff00000 + + + +// YN: mask the following register definition temporarily +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +//#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +//#define rFPGA0_XCD_RFParameter 0x87c + +//#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +//#define rFPGA0_AnalogParameter2 0x884 +//#define rFPGA0_AnalogParameter3 0x888 +//#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +//#define rFPGA0_AnalogParameter4 0x88c + + +// CCK TX scaling +#define rCCK_TxFilter1_Jaguar 0xa20 +#define bCCK_TxFilter1_C0_Jaguar 0x00ff0000 +#define bCCK_TxFilter1_C1_Jaguar 0xff000000 +#define rCCK_TxFilter2_Jaguar 0xa24 +#define bCCK_TxFilter2_C2_Jaguar 0x000000ff +#define bCCK_TxFilter2_C3_Jaguar 0x0000ff00 +#define bCCK_TxFilter2_C4_Jaguar 0x00ff0000 +#define bCCK_TxFilter2_C5_Jaguar 0xff000000 +#define rCCK_TxFilter3_Jaguar 0xa28 +#define bCCK_TxFilter3_C6_Jaguar 0x000000ff +#define bCCK_TxFilter3_C7_Jaguar 0x0000ff00 + + +// YN: mask the following register definition temporarily +//#define rPdp_AntA 0xb00 +//#define rPdp_AntA_4 0xb04 +//#define rConfig_Pmpd_AntA 0xb28 +//#define rConfig_AntA 0xb68 +//#define rConfig_AntB 0xb6c +//#define rPdp_AntB 0xb70 +//#define rPdp_AntB_4 0xb74 +//#define rConfig_Pmpd_AntB 0xb98 +//#define rAPK 0xbd8 + +// RXIQC +#define rA_RxIQC_AB_Jaguar 0xc10 //RxIQ imblance matrix coeff. A & B +#define rA_RxIQC_CD_Jaguar 0xc14 //RxIQ imblance matrix coeff. C & D +#define rA_TxScale_Jaguar 0xc1c // Pah_A TX scaling factor +#define rB_TxScale_Jaguar 0xe1c // Path_B TX scaling factor +#define rB_RxIQC_AB_Jaguar 0xe10 //RxIQ imblance matrix coeff. A & B +#define rB_RxIQC_CD_Jaguar 0xe14 //RxIQ imblance matrix coeff. C & D +#define b_RxIQC_AC_Jaguar 0x02ff // bit mask for IQC matrix element A & C +#define b_RxIQC_BD_Jaguar 0x02ff0000 // bit mask for IQC matrix element A & C + + +// DIG-related +#define rA_IGI_Jaguar 0xc50 // Initial Gain for path-A +#define rB_IGI_Jaguar 0xe50 // Initial Gain for path-B +#define rOFDM_FalseAlarm1_Jaguar 0xf48 // counter for break +#define rOFDM_FalseAlarm2_Jaguar 0xf4c // counter for spoofing +#define rCCK_FalseAlarm_Jaguar 0xa5c // counter for cck false alarm +#define b_FalseAlarm_Jaguar 0xffff +#define rCCK_CCA_Jaguar 0xa08 // cca threshold +#define bCCK_CCA_Jaguar 0x00ff0000 + +// Tx Power Ttraining-related +#define rA_TxPwrTraing_Jaguar 0xc54 +#define rB_TxPwrTraing_Jaguar 0xe54 + +// Report-related +#define rOFDM_ShortCFOAB_Jaguar 0xf60 +#define rOFDM_LongCFOAB_Jaguar 0xf64 +#define rOFDM_EndCFOAB_Jaguar 0xf70 +#define rOFDM_AGCReport_Jaguar 0xf84 +#define rOFDM_RxSNR_Jaguar 0xf88 +#define rOFDM_RxEVMCSI_Jaguar 0xf8c +#define rOFDM_SIGReport_Jaguar 0xf90 + +// Misc functions +#define rEDCCA_Jaguar 0x8a4 // EDCCA +#define bEDCCA_Jaguar 0xffff +#define rAGC_table_Jaguar 0x82c // AGC tabel select +#define bAGC_table_Jaguar 0x3 +#define b_sel5g_Jaguar 0x1000 // sel5g +#define b_LNA_sw_Jaguar 0x8000 // HW/WS control for LNA +#define rFc_area_Jaguar 0x860 // fc_area +#define bFc_area_Jaguar 0x1ffe000 +#define rSingleTone_ContTx_Jaguar 0x914 + +// RFE +#define rA_RFE_Pinmux_Jaguar 0xcb0 // Path_A RFE cotrol pinmux +#define rB_RFE_Pinmux_Jaguar 0xeb0 // Path_B RFE control pinmux +#define rA_RFE_Inv_Jaguar 0xcb4 // Path_A RFE cotrol +#define rB_RFE_Inv_Jaguar 0xeb4 // Path_B RFE control +#define rA_RFE_Jaguar 0xcb8 // Path_A RFE cotrol +#define rB_RFE_Jaguar 0xeb8 // Path_B RFE control +#define r_ANTSEL_SW_Jaguar 0x900 // ANTSEL SW Control +#define bMask_RFEInv_Jaguar 0x3ff00000 +#define bMask_AntselPathFollow_Jaguar 0x00030000 + +// 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 +#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 +#define bTxAGC_byte0_Jaguar 0xff +#define bTxAGC_byte1_Jaguar 0xff00 +#define bTxAGC_byte2_Jaguar 0xff0000 +#define bTxAGC_byte3_Jaguar 0xff000000 + +// IQK YN: temporaily mask this part +//#define rFPGA0_IQK 0xe28 +//#define rTx_IQK_Tone_A 0xe30 +//#define rRx_IQK_Tone_A 0xe34 +//#define rTx_IQK_PI_A 0xe38 +//#define rRx_IQK_PI_A 0xe3c + +//#define rTx_IQK 0xe40 +//#define rRx_IQK 0xe44 +//#define rIQK_AGC_Pts 0xe48 +//#define rIQK_AGC_Rsp 0xe4c +//#define rTx_IQK_Tone_B 0xe50 +//#define rRx_IQK_Tone_B 0xe54 +//#define rTx_IQK_PI_B 0xe58 +//#define rRx_IQK_PI_B 0xe5c +//#define rIQK_AGC_Cont 0xe60 + + +// AFE-related +#define rA_AFEPwr1_Jaguar 0xc60 // dynamic AFE power control +#define rA_AFEPwr2_Jaguar 0xc64 // dynamic AFE power control +#define rA_Rx_WaitCCA_Tx_CCKRFON_Jaguar 0xc68 +#define rA_Tx_CCKBBON_OFDMRFON_Jaguar 0xc6c +#define rA_Tx_OFDMBBON_Tx2Rx_Jaguar 0xc70 +#define rA_Tx2Tx_RXCCK_Jaguar 0xc74 +#define rA_Rx_OFDM_WaitRIFS_Jaguar 0xc78 +#define rA_Rx2Rx_BT_Jaguar 0xc7c +#define rA_sleep_nav_Jaguar 0xc80 +#define rA_pmpd_Jaguar 0xc84 +#define rB_AFEPwr1_Jaguar 0xe60 // dynamic AFE power control +#define rB_AFEPwr2_Jaguar 0xe64 // dynamic AFE power control +#define rB_Rx_WaitCCA_Tx_CCKRFON_Jaguar 0xe68 +#define rB_Tx_CCKBBON_OFDMRFON_Jaguar 0xe6c +#define rB_Tx_OFDMBBON_Tx2Rx_Jaguar 0xe70 +#define rB_Tx2Tx_RXCCK_Jaguar 0xe74 +#define rB_Rx_OFDM_WaitRIFS_Jaguar 0xe78 +#define rB_Rx2Rx_BT_Jaguar 0xe7c +#define rB_sleep_nav_Jaguar 0xe80 +#define rB_pmpd_Jaguar 0xe84 + + +// YN: mask these registers temporaily +//#define rTx_Power_Before_IQK_A 0xe94 +//#define rTx_Power_After_IQK_A 0xe9c + +//#define rRx_Power_Before_IQK_A 0xea0 +//#define rRx_Power_Before_IQK_A_2 0xea4 +//#define rRx_Power_After_IQK_A 0xea8 +//#define rRx_Power_After_IQK_A_2 0xeac + +//#define rTx_Power_Before_IQK_B 0xeb4 +//#define rTx_Power_After_IQK_B 0xebc + +//#define rRx_Power_Before_IQK_B 0xec0 +//#define rRx_Power_Before_IQK_B_2 0xec4 +//#define rRx_Power_After_IQK_B 0xec8 +//#define rRx_Power_After_IQK_B_2 0xecc + + +// RSSI Dump +#define rA_RSSIDump_Jaguar 0xBF0 +#define rB_RSSIDump_Jaguar 0xBF1 +#define rS1_RXevmDump_Jaguar 0xBF4 +#define rS2_RXevmDump_Jaguar 0xBF5 +#define rA_RXsnrDump_Jaguar 0xBF6 +#define rB_RXsnrDump_Jaguar 0xBF7 +#define rA_CfoShortDump_Jaguar 0xBF8 +#define rB_CfoShortDump_Jaguar 0xBFA +#define rA_CfoLongDump_Jaguar 0xBEC +#define rB_CfoLongDump_Jaguar 0xBEE + + +// RF Register +// +#define RF_AC_Jaguar 0x00 // +#define RF_RF_Top_Jaguar 0x07 // +#define RF_TXLOK_Jaguar 0x08 // +#define RF_TXAPK_Jaguar 0x0B +#define RF_CHNLBW_Jaguar 0x18 // RF channel and BW switch +#define RF_RCK1_Jaguar 0x1c // +#define RF_RCK2_Jaguar 0x1d +#define RF_RCK3_Jaguar 0x1e +#define RF_ModeTableAddr 0x30 +#define RF_ModeTableData0 0x31 +#define RF_ModeTableData1 0x32 +#define RF_TxLCTank_Jaguar 0x54 +#define RF_APK_Jaguar 0x63 +#define RF_LCK 0xB4 +#define RF_WeLut_Jaguar 0xEF + +#define bRF_CHNLBW_MOD_AG_Jaguar 0x70300 +#define bRF_CHNLBW_BW 0xc00 + + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_RCK_OS 0x30 // RF TX PA control +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_0x52 0x52 +#define RF_WE_LUT 0xEF + +#define RF_TX_GAIN_OFFSET_8812A(_val) ((abs((_val)) << 1) | (((_val) > 0) ? BIT0 : 0)) +#define RF_TX_GAIN_OFFSET_8821A(_val) ((abs((_val)) << 1) | (((_val) > 0) ? BIT0 : 0)) + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +#define rFPGA0_AnalogParameter4 0x88c +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XCD_RFPara 0x8b4 + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// PageA(0xA00) +// +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_DSPParameter2 0xa1c //SQ threshold +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 + + +// +// Other Definition +// + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +//byte endable for srwrite +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PwrSeq.h new file mode 100644 index 00000000..5d6a7ad2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8812PwrSeq.h @@ -0,0 +1,210 @@ + +/****************************************************************************** + * + * 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 __HAL8812PWRSEQ_H__ +#define __HAL8812PWRSEQ_H__ + +#include "HalPwrSeqCmd.h" + +/* + Check document WB-110628-DZ-RTL8195 (Jaguar) Power Architecture-R04.pdf + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8812_TRANS_CARDEMU_TO_ACT_STEPS 15 +#define RTL8812_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8812_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8812_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8812_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8812_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8812_TRANS_END_STEPS 1 + + +#define RTL8812_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + /*{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0}, disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ + +#define RTL8812_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /* 0x2[0] = 0 RESET BB, CLOSE RF */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + /*{0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},//0x1F[7:0] = 0 turn off RF*/ \ + /*{0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},//0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x2A}, /* 0x07[7:0] = 0x28 sps pwm mode 0x2a for BT coex*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */ \ + /*{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0|BIT1, 0}, // 0x02[1:0] = 0 reset BB */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ + +#define RTL8812_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xcc},\ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xEC},\ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */ \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* suspend option all off */ \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'11 enable WL suspend for PCIe*/ + +#define RTL8812_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO sleep mode leave */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */ \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ + +#define RTL8812_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + /**{0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, //0x194[0]=0 , disable 32K clock*/ \ + /**{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x94}, //0x93=0x94 , 90[30] =0 enable 500k ANA clock .switch clock from 12M to 500K , 90 [26] =0 disable EEprom loader clock*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x03[2] = 0, reset 8051*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x05}, /*0x80=05h if reload fw, fill the default value of host_CPU handshake field*/ \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xcc},\ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xEC},\ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x07},/* gpio11 input mode, gpio10~8 output mode */ \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, BIT7},/*0x14[7] = 1 turn on ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, BIT0},/* 0x15[0] =1 trun on ZCD */ \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/*0x12[0] = 0 force PFM mode */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0},/*0x8[1] = 0 ANA clk =500k */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x001f, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /*0x01f[1]=0 , disable RFC_0 control REG_RF_CTRL_8812 */ \ + {0x0076, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /*0x076[1]=0 , disable RFC_1 control REG_OPT_CTRL_8812 +2 */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 2b'01 enable WL suspend*/ + +#define RTL8812_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*0x12[0] = 1 force PWM mode */ \ + {0x0014, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x80, 0},/*0x14[7] = 0 turn off ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x01, 0},/* 0x15[0] =0 trun off ZCD */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO leave sleep mode */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ + {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x04[10] = 0, enable SW LPS PCIE only*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 2b'01enable WL suspend*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x03[2] = 1, enable 8051*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8812_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8812_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8812_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated,and RF closed*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ + + +#define RTL8812_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/ \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/ \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/ \ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8812_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8812_power_on_flow[RTL8812_TRANS_CARDEMU_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_radio_off_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_card_disable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_card_enable_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_suspend_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_resume_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_SUS_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_hwpdn_flow[RTL8812_TRANS_ACT_TO_CARDEMU_STEPS+RTL8812_TRANS_CARDEMU_TO_PDN_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_enter_lps_flow[RTL8812_TRANS_ACT_TO_LPS_STEPS+RTL8812_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8812_leave_lps_flow[RTL8812_TRANS_LPS_TO_ACT_STEPS+RTL8812_TRANS_END_STEPS]; + +#endif //__HAL8812PWRSEQ_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyCfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyCfg.h new file mode 100644 index 00000000..d6be7976 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyCfg.h @@ -0,0 +1,282 @@ +/****************************************************************************** + * + * 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_HAL8814PHYCFG_H__ +#define __INC_HAL8814PHYCFG_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + + +#ifdef CONFIG_PCI_HCI +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters-------------------------------*/ + +/*------------------------------Define structure----------------------------*/ + + +/* BB/RF related */ + +#define SIC_ENABLE 0 + +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +//1. BB register R/W API + +extern u32 +PHY_QueryBBReg8814A( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask ); + + +VOID +PHY_SetBBReg8814A( IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + + +extern u32 +PHY_QueryRFReg8814A( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask ); + + +void +PHY_SetRFReg8814A( IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data ); + +//1 3. Initial BB/RF config by reading MAC/BB/RF txt. +s32 +phy_BB8814A_Config_ParaFile( + IN PADAPTER Adapter + ); + + +RT_STATUS +PHY_BBConfigMP_8814A( + IN PADAPTER Adapter + ); + +VOID +PHY_ConfigBB_8814A( + IN PADAPTER Adapter + ); + + +VOID +phy_ADC_CLK_8814A( + IN PADAPTER Adapter + ); + +s32 +PHY_RFConfig8814A( + IN PADAPTER Adapter + ); + +// +// RF Power setting +// +//BOOLEAN PHY_SetRFPowerState8814A(PADAPTER Adapter, rt_rf_power_state eRFPowerState); + +//1 5. Tx Power setting API + +VOID +PHY_GetTxPowerLevel8814( + IN PADAPTER Adapter, + OUT ps4Byte powerlevel + ); + +VOID +PHY_SetTxPowerLevel8814( + IN PADAPTER Adapter, + IN u8 Channel + ); + +u8 +PHY_GetTxPowerIndex_8814A( + IN PADAPTER Adapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_SetTxPowerIndex_8814A( + IN PADAPTER Adapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + + +BOOLEAN +PHY_UpdateTxPowerDbm8814A( + IN PADAPTER Adapter, + IN s4Byte powerInDbm + ); + + +u32 +PHY_GetTxBBSwing_8814A( + IN PADAPTER Adapter, + IN BAND_TYPE Band, + IN u8 RFPath + ); + + + +//1 6. Channel setting API + +VOID +PHY_SwChnlTimerCallback8814A( + IN PRT_TIMER pTimer + ); + +VOID +PHY_SwChnlWorkItemCallback8814A( + IN PVOID pContext + ); + + +VOID +HAL_HandleSwChnl8814A( + IN PADAPTER pAdapter, + IN u8 channel + ); + +VOID +PHY_SwChnlSynchronously8814A( IN PADAPTER pAdapter, + IN u8 channel ); + +VOID +PHY_SwChnlAndSetBWModeCallback8814A(IN PVOID pContext); + + +VOID +PHY_HandleSwChnlAndSetBW8814A( + IN PADAPTER Adapter, + IN BOOLEAN bSwitchChannel, + IN BOOLEAN bSetBandWidth, + IN u8 ChannelNum, + IN CHANNEL_WIDTH ChnlWidth, + IN u8 ChnlOffsetOf40MHz, + IN u8 ChnlOffsetOf80MHz, + IN u8 CenterFrequencyIndex1 +); + + +BOOLEAN +PHY_QueryRFPathSwitch_8814A( IN PADAPTER pAdapter); + + + +//VOID PHY_SetMonitorMode8814A(PADAPTER pAdapter, BOOLEAN bEnableMonitorMode); + + +#if (USE_WORKITEM) +VOID +RtCheckForHangWorkItemCallback8814A( + IN PVOID pContext +); +#endif + +BOOLEAN +SetAntennaConfig8814A( + IN PADAPTER Adapter, + IN u8 DefaultAnt + ); + +VOID +PHY_SetRFEReg8814A( + IN PADAPTER Adapter, + IN BOOLEAN bInit, + IN u8 Band + ); + + +s32 +PHY_SwitchWirelessBand8814A( + IN PADAPTER Adapter, + IN u8 Band +); + +VOID +PHY_SetIO_8814A( + PADAPTER pAdapter + ); + +VOID +PHY_SetBWMode8814( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN u8 Offset // Upper, Lower, or Don't care +); + +VOID +PHY_SwChnl8814( + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetSwChnlBWMode8814( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +s32 PHY_MACConfig8814(PADAPTER Adapter); +int PHY_BBConfig8814(PADAPTER Adapter); +VOID PHY_Set_SecCCATH_by_RXANT_8814A(PADAPTER pAdapter, u4Byte ulAntennaRx); + + + +/*--------------------------Exported Function prototype---------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ +#endif // __INC_HAL8192CPHYCFG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyReg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyReg.h new file mode 100644 index 00000000..56c74baf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PhyReg.h @@ -0,0 +1,866 @@ +/****************************************************************************** + * + * 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_HAL8814PHYREG_H__ +#define __INC_HAL8814PHYREG_H__ +/*--------------------------Define Parameters-------------------------------*/ +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +/* BB Register Definition */ + +#define rCCAonSec_Jaguar 0x838 +#define rPwed_TH_Jaguar 0x830 +#define rL1_Weight_Jaguar 0x840 + +// BW and sideband setting +#define rBWIndication_Jaguar 0x834 +#define rL1PeakTH_Jaguar 0x848 +#define rRFMOD_Jaguar 0x8ac //RF mode +#define rADC_Buf_Clk_Jaguar 0x8c4 +#define rADC_Buf_40_Clk_Jaguar2 0x8c8 +#define rRFECTRL_Jaguar 0x900 +#define bRFMOD_Jaguar 0xc3 +#define rCCK_System_Jaguar 0xa00 // for cck sideband +#define bCCK_System_Jaguar 0x10 + +// Block & Path enable +#define rOFDMCCKEN_Jaguar 0x808 // OFDM/CCK block enable +#define bOFDMEN_Jaguar 0x20000000 +#define bCCKEN_Jaguar 0x10000000 +#define rRxPath_Jaguar 0x808 // Rx antenna +#define bRxPath_Jaguar 0xff +#define rTxPath_Jaguar 0x80c // Tx antenna +#define bTxPath_Jaguar 0x0fffffff +#define rCCK_RX_Jaguar 0xa04 // for cck rx path selection +#define bCCK_RX_Jaguar 0x0c000000 +#define rVhtlen_Use_Lsig_Jaguar 0x8c3 // Use LSIG for VHT length + +#define rRxPath_Jaguar2 0xa04 // Rx antenna +#define rTxAnt_1Nsts_Jaguar2 0x93c // Tx antenna for 1Nsts +#define rTxAnt_23Nsts_Jaguar2 0x940 // Tx antenna for 2Nsts and 3Nsts + + +// RF read/write-related +#define rHSSIRead_Jaguar 0x8b0 // RF read addr +#define bHSSIRead_addr_Jaguar 0xff +#define bHSSIRead_trigger_Jaguar 0x100 +#define rA_PIRead_Jaguar 0xd04 // RF readback with PI +#define rB_PIRead_Jaguar 0xd44 // RF readback with PI +#define rA_SIRead_Jaguar 0xd08 // RF readback with SI +#define rB_SIRead_Jaguar 0xd48 // RF readback with SI +#define rRead_data_Jaguar 0xfffff +#define rA_LSSIWrite_Jaguar 0xc90 // RF write addr +#define rB_LSSIWrite_Jaguar 0xe90 // RF write addr +#define bLSSIWrite_data_Jaguar 0x000fffff +#define bLSSIWrite_addr_Jaguar 0x0ff00000 + +#define rC_PIRead_Jaguar2 0xd84 // RF readback with PI +#define rD_PIRead_Jaguar2 0xdC4 // RF readback with PI +#define rC_SIRead_Jaguar2 0xd88 // RF readback with SI +#define rD_SIRead_Jaguar2 0xdC8 // RF readback with SI +#define rC_LSSIWrite_Jaguar2 0x1890 // RF write addr +#define rD_LSSIWrite_Jaguar2 0x1A90 // RF write addr + + +// YN: mask the following register definition temporarily +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +//#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +//#define rFPGA0_XCD_RFParameter 0x87c + +//#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +//#define rFPGA0_AnalogParameter2 0x884 +//#define rFPGA0_AnalogParameter3 0x888 +//#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +//#define rFPGA0_AnalogParameter4 0x88c + + +// CCK TX scaling +#define rCCK_TxFilter1_Jaguar 0xa20 +#define bCCK_TxFilter1_C0_Jaguar 0x00ff0000 +#define bCCK_TxFilter1_C1_Jaguar 0xff000000 +#define rCCK_TxFilter2_Jaguar 0xa24 +#define bCCK_TxFilter2_C2_Jaguar 0x000000ff +#define bCCK_TxFilter2_C3_Jaguar 0x0000ff00 +#define bCCK_TxFilter2_C4_Jaguar 0x00ff0000 +#define bCCK_TxFilter2_C5_Jaguar 0xff000000 +#define rCCK_TxFilter3_Jaguar 0xa28 +#define bCCK_TxFilter3_C6_Jaguar 0x000000ff +#define bCCK_TxFilter3_C7_Jaguar 0x0000ff00 +/* NBI & CSI Mask setting */ +#define rCSI_Mask_Setting1_Jaguar 0x874 +#define rCSI_Fix_Mask0_Jaguar 0x880 +#define rCSI_Fix_Mask1_Jaguar 0x884 +#define rCSI_Fix_Mask2_Jaguar 0x888 +#define rCSI_Fix_Mask3_Jaguar 0x88c +#define rCSI_Fix_Mask4_Jaguar 0x890 +#define rCSI_Fix_Mask5_Jaguar 0x894 +#define rCSI_Fix_Mask6_Jaguar 0x898 +#define rCSI_Fix_Mask7_Jaguar 0x89c +#define rNBI_Setting_Jaguar 0x87c + + +// YN: mask the following register definition temporarily +//#define rPdp_AntA 0xb00 +//#define rPdp_AntA_4 0xb04 +//#define rConfig_Pmpd_AntA 0xb28 +//#define rConfig_AntA 0xb68 +//#define rConfig_AntB 0xb6c +//#define rPdp_AntB 0xb70 +//#define rPdp_AntB_4 0xb74 +//#define rConfig_Pmpd_AntB 0xb98 +//#define rAPK 0xbd8 + +// RXIQC +#define rA_RxIQC_AB_Jaguar 0xc10 //RxIQ imblance matrix coeff. A & B +#define rA_RxIQC_CD_Jaguar 0xc14 //RxIQ imblance matrix coeff. C & D +#define rA_TxScale_Jaguar 0xc1c // Pah_A TX scaling factor +#define rB_TxScale_Jaguar 0xe1c // Path_B TX scaling factor +#define rB_RxIQC_AB_Jaguar 0xe10 //RxIQ imblance matrix coeff. A & B +#define rB_RxIQC_CD_Jaguar 0xe14 //RxIQ imblance matrix coeff. C & D +#define b_RxIQC_AC_Jaguar 0x02ff // bit mask for IQC matrix element A & C +#define b_RxIQC_BD_Jaguar 0x02ff0000 // bit mask for IQC matrix element A & C + +#define rC_TxScale_Jaguar2 0x181c // Pah_C TX scaling factor +#define rD_TxScale_Jaguar2 0x1A1c // Path_D TX scaling factor +#define rRF_TxGainOffset 0x55 + +// DIG-related +#define rA_IGI_Jaguar 0xc50 // Initial Gain for path-A +#define rB_IGI_Jaguar 0xe50 // Initial Gain for path-B +#define rC_IGI_Jaguar2 0x1850 // Initial Gain for path-C +#define rD_IGI_Jaguar2 0x1A50 // Initial Gain for path-D + +#define rOFDM_FalseAlarm1_Jaguar 0xf48 // counter for break +#define rOFDM_FalseAlarm2_Jaguar 0xf4c // counter for spoofing +#define rCCK_FalseAlarm_Jaguar 0xa5c // counter for cck false alarm +#define b_FalseAlarm_Jaguar 0xffff +#define rCCK_CCA_Jaguar 0xa08 // cca threshold +#define bCCK_CCA_Jaguar 0x00ff0000 + +// Tx Power Ttraining-related +#define rA_TxPwrTraing_Jaguar 0xc54 +#define rB_TxPwrTraing_Jaguar 0xe54 + +// Report-related +#define rOFDM_ShortCFOAB_Jaguar 0xf60 +#define rOFDM_LongCFOAB_Jaguar 0xf64 +#define rOFDM_EndCFOAB_Jaguar 0xf70 +#define rOFDM_AGCReport_Jaguar 0xf84 +#define rOFDM_RxSNR_Jaguar 0xf88 +#define rOFDM_RxEVMCSI_Jaguar 0xf8c +#define rOFDM_SIGReport_Jaguar 0xf90 + +// Misc functions +#define rEDCCA_Jaguar 0x8a4 // EDCCA +#define bEDCCA_Jaguar 0xffff +#define rAGC_table_Jaguar 0x82c // AGC tabel select +#define bAGC_table_Jaguar 0x3 +#define b_sel5g_Jaguar 0x1000 // sel5g +#define b_LNA_sw_Jaguar 0x8000 // HW/WS control for LNA +#define rFc_area_Jaguar 0x860 // fc_area +#define bFc_area_Jaguar 0x1ffe000 +#define rSingleTone_ContTx_Jaguar 0x914 + +#define rAGC_table_Jaguar2 0x958 // AGC tabel select +#define rDMA_trigger_Jaguar2 0x95C // ADC sample mode + + +// RFE +#define rA_RFE_Pinmux_Jaguar 0xcb0 // Path_A RFE cotrol pinmux +#define rB_RFE_Pinmux_Jaguar 0xeb0 // Path_B RFE control pinmux +#define rA_RFE_Inv_Jaguar 0xcb4 // Path_A RFE cotrol +#define rB_RFE_Inv_Jaguar 0xeb4 // Path_B RFE control +#define rA_RFE_Jaguar 0xcb8 // Path_A RFE cotrol +#define rB_RFE_Jaguar 0xeb8 // Path_B RFE control +#define r_ANTSEL_SW_Jaguar 0x900 // ANTSEL SW Control +#define bMask_RFEInv_Jaguar 0x3ff00000 +#define bMask_AntselPathFollow_Jaguar 0x00030000 + +#define rC_RFE_Pinmux_Jaguar 0x18B4 // Path_C RFE cotrol pinmux +#define rD_RFE_Pinmux_Jaguar 0x1AB4 // Path_D RFE cotrol pinmux +#define rA_RFE_Sel_Jaguar2 0x1990 + + + +// 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 +#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 +#define bTxAGC_byte0_Jaguar 0xff +#define bTxAGC_byte1_Jaguar 0xff00 +#define bTxAGC_byte2_Jaguar 0xff0000 +#define bTxAGC_byte3_Jaguar 0xff000000 + + +// TX AGC +#define rTxAGC_A_CCK11_CCK1_Jaguar2 0xc20 +#define rTxAGC_A_Ofdm18_Ofdm6_Jaguar2 0xc24 +#define rTxAGC_A_Ofdm54_Ofdm24_Jaguar2 0xc28 +#define rTxAGC_A_MCS3_MCS0_Jaguar2 0xc2c +#define rTxAGC_A_MCS7_MCS4_Jaguar2 0xc30 +#define rTxAGC_A_MCS11_MCS8_Jaguar2 0xc34 +#define rTxAGC_A_MCS15_MCS12_Jaguar2 0xc38 +#define rTxAGC_A_MCS19_MCS16_Jaguar2 0xcd8 +#define rTxAGC_A_MCS23_MCS20_Jaguar2 0xcdc +#define rTxAGC_A_Nss1Index3_Nss1Index0_Jaguar2 0xc3c +#define rTxAGC_A_Nss1Index7_Nss1Index4_Jaguar2 0xc40 +#define rTxAGC_A_Nss2Index1_Nss1Index8_Jaguar2 0xc44 +#define rTxAGC_A_Nss2Index5_Nss2Index2_Jaguar2 0xc48 +#define rTxAGC_A_Nss2Index9_Nss2Index6_Jaguar2 0xc4c +#define rTxAGC_A_Nss3Index3_Nss3Index0_Jaguar2 0xce0 +#define rTxAGC_A_Nss3Index7_Nss3Index4_Jaguar2 0xce4 +#define rTxAGC_A_Nss3Index9_Nss3Index8_Jaguar2 0xce8 +#define rTxAGC_B_CCK11_CCK1_Jaguar2 0xe20 +#define rTxAGC_B_Ofdm18_Ofdm6_Jaguar2 0xe24 +#define rTxAGC_B_Ofdm54_Ofdm24_Jaguar2 0xe28 +#define rTxAGC_B_MCS3_MCS0_Jaguar2 0xe2c +#define rTxAGC_B_MCS7_MCS4_Jaguar2 0xe30 +#define rTxAGC_B_MCS11_MCS8_Jaguar2 0xe34 +#define rTxAGC_B_MCS15_MCS12_Jaguar2 0xe38 +#define rTxAGC_B_MCS19_MCS16_Jaguar2 0xed8 +#define rTxAGC_B_MCS23_MCS20_Jaguar2 0xedc +#define rTxAGC_B_Nss1Index3_Nss1Index0_Jaguar2 0xe3c +#define rTxAGC_B_Nss1Index7_Nss1Index4_Jaguar2 0xe40 +#define rTxAGC_B_Nss2Index1_Nss1Index8_Jaguar2 0xe44 +#define rTxAGC_B_Nss2Index5_Nss2Index2_Jaguar2 0xe48 +#define rTxAGC_B_Nss2Index9_Nss2Index6_Jaguar2 0xe4c +#define rTxAGC_B_Nss3Index3_Nss3Index0_Jaguar2 0xee0 +#define rTxAGC_B_Nss3Index7_Nss3Index4_Jaguar2 0xee4 +#define rTxAGC_B_Nss3Index9_Nss3Index8_Jaguar2 0xee8 +#define rTxAGC_C_CCK11_CCK1_Jaguar2 0x1820 +#define rTxAGC_C_Ofdm18_Ofdm6_Jaguar2 0x1824 +#define rTxAGC_C_Ofdm54_Ofdm24_Jaguar2 0x1828 +#define rTxAGC_C_MCS3_MCS0_Jaguar2 0x182c +#define rTxAGC_C_MCS7_MCS4_Jaguar2 0x1830 +#define rTxAGC_C_MCS11_MCS8_Jaguar2 0x1834 +#define rTxAGC_C_MCS15_MCS12_Jaguar2 0x1838 +#define rTxAGC_C_MCS19_MCS16_Jaguar2 0x18d8 +#define rTxAGC_C_MCS23_MCS20_Jaguar2 0x18dc +#define rTxAGC_C_Nss1Index3_Nss1Index0_Jaguar2 0x183c +#define rTxAGC_C_Nss1Index7_Nss1Index4_Jaguar2 0x1840 +#define rTxAGC_C_Nss2Index1_Nss1Index8_Jaguar2 0x1844 +#define rTxAGC_C_Nss2Index5_Nss2Index2_Jaguar2 0x1848 +#define rTxAGC_C_Nss2Index9_Nss2Index6_Jaguar2 0x184c +#define rTxAGC_C_Nss3Index3_Nss3Index0_Jaguar2 0x18e0 +#define rTxAGC_C_Nss3Index7_Nss3Index4_Jaguar2 0x18e4 +#define rTxAGC_C_Nss3Index9_Nss3Index8_Jaguar2 0x18e8 +#define rTxAGC_D_CCK11_CCK1_Jaguar2 0x1a20 +#define rTxAGC_D_Ofdm18_Ofdm6_Jaguar2 0x1a24 +#define rTxAGC_D_Ofdm54_Ofdm24_Jaguar2 0x1a28 +#define rTxAGC_D_MCS3_MCS0_Jaguar2 0x1a2c +#define rTxAGC_D_MCS7_MCS4_Jaguar2 0x1a30 +#define rTxAGC_D_MCS11_MCS8_Jaguar2 0x1a34 +#define rTxAGC_D_MCS15_MCS12_Jaguar2 0x1a38 +#define rTxAGC_D_MCS19_MCS16_Jaguar2 0x1ad8 +#define rTxAGC_D_MCS23_MCS20_Jaguar2 0x1adc +#define rTxAGC_D_Nss1Index3_Nss1Index0_Jaguar2 0x1a3c +#define rTxAGC_D_Nss1Index7_Nss1Index4_Jaguar2 0x1a40 +#define rTxAGC_D_Nss2Index1_Nss1Index8_Jaguar2 0x1a44 +#define rTxAGC_D_Nss2Index5_Nss2Index2_Jaguar2 0x1a48 +#define rTxAGC_D_Nss2Index9_Nss2Index6_Jaguar2 0x1a4c +#define rTxAGC_D_Nss3Index3_Nss3Index0_Jaguar2 0x1ae0 +#define rTxAGC_D_Nss3Index7_Nss3Index4_Jaguar2 0x1ae4 +#define rTxAGC_D_Nss3Index9_Nss3Index8_Jaguar2 0x1ae8 +// IQK YN: temporaily mask this part +//#define rFPGA0_IQK 0xe28 +//#define rTx_IQK_Tone_A 0xe30 +//#define rRx_IQK_Tone_A 0xe34 +//#define rTx_IQK_PI_A 0xe38 +//#define rRx_IQK_PI_A 0xe3c + +//#define rTx_IQK 0xe40 +//#define rRx_IQK 0xe44 +//#define rIQK_AGC_Pts 0xe48 +//#define rIQK_AGC_Rsp 0xe4c +//#define rTx_IQK_Tone_B 0xe50 +//#define rRx_IQK_Tone_B 0xe54 +//#define rTx_IQK_PI_B 0xe58 +//#define rRx_IQK_PI_B 0xe5c +//#define rIQK_AGC_Cont 0xe60 + + +// AFE-related +#define rA_AFEPwr1_Jaguar 0xc60 // dynamic AFE power control +#define rA_AFEPwr2_Jaguar 0xc64 // dynamic AFE power control +#define rA_Rx_WaitCCA_Tx_CCKRFON_Jaguar 0xc68 +#define rA_Tx_CCKBBON_OFDMRFON_Jaguar 0xc6c +#define rA_Tx_OFDMBBON_Tx2Rx_Jaguar 0xc70 +#define rA_Tx2Tx_RXCCK_Jaguar 0xc74 +#define rA_Rx_OFDM_WaitRIFS_Jaguar 0xc78 +#define rA_Rx2Rx_BT_Jaguar 0xc7c +#define rA_sleep_nav_Jaguar 0xc80 +#define rA_pmpd_Jaguar 0xc84 +#define rB_AFEPwr1_Jaguar 0xe60 // dynamic AFE power control +#define rB_AFEPwr2_Jaguar 0xe64 // dynamic AFE power control +#define rB_Rx_WaitCCA_Tx_CCKRFON_Jaguar 0xe68 +#define rB_Tx_CCKBBON_OFDMRFON_Jaguar 0xe6c +#define rB_Tx_OFDMBBON_Tx2Rx_Jaguar 0xe70 +#define rB_Tx2Tx_RXCCK_Jaguar 0xe74 +#define rB_Rx_OFDM_WaitRIFS_Jaguar 0xe78 +#define rB_Rx2Rx_BT_Jaguar 0xe7c +#define rB_sleep_nav_Jaguar 0xe80 +#define rB_pmpd_Jaguar 0xe84 + + +// YN: mask these registers temporaily +//#define rTx_Power_Before_IQK_A 0xe94 +//#define rTx_Power_After_IQK_A 0xe9c + +//#define rRx_Power_Before_IQK_A 0xea0 +//#define rRx_Power_Before_IQK_A_2 0xea4 +//#define rRx_Power_After_IQK_A 0xea8 +//#define rRx_Power_After_IQK_A_2 0xeac + +//#define rTx_Power_Before_IQK_B 0xeb4 +//#define rTx_Power_After_IQK_B 0xebc + +//#define rRx_Power_Before_IQK_B 0xec0 +//#define rRx_Power_Before_IQK_B_2 0xec4 +//#define rRx_Power_After_IQK_B 0xec8 +//#define rRx_Power_After_IQK_B_2 0xecc + + +// RSSI Dump +#define rA_RSSIDump_Jaguar 0xBF0 +#define rB_RSSIDump_Jaguar 0xBF1 +#define rS1_RXevmDump_Jaguar 0xBF4 +#define rS2_RXevmDump_Jaguar 0xBF5 +#define rA_RXsnrDump_Jaguar 0xBF6 +#define rB_RXsnrDump_Jaguar 0xBF7 +#define rA_CfoShortDump_Jaguar 0xBF8 +#define rB_CfoShortDump_Jaguar 0xBFA +#define rA_CfoLongDump_Jaguar 0xBEC +#define rB_CfoLongDump_Jaguar 0xBEE + + +// RF Register +// +#define RF_AC_Jaguar 0x00 // +#define RF_RF_Top_Jaguar 0x07 // +#define RF_TXLOK_Jaguar 0x08 // +#define RF_TXAPK_Jaguar 0x0B +#define RF_CHNLBW_Jaguar 0x18 // RF channel and BW switch +#define RF_RCK1_Jaguar 0x1c // +#define RF_RCK2_Jaguar 0x1d +#define RF_RCK3_Jaguar 0x1e +#define RF_ModeTableAddr 0x30 +#define RF_ModeTableData0 0x31 +#define RF_ModeTableData1 0x32 +#define RF_TxLCTank_Jaguar 0x54 +#define RF_APK_Jaguar 0x63 +#define RF_LCK 0xB4 +#define RF_WeLut_Jaguar 0xEF + +#define bRF_CHNLBW_MOD_AG_Jaguar 0x70300 +#define bRF_CHNLBW_BW 0xc00 + + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_RCK_OS 0x30 // RF TX PA control +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control +#define RF_0x52 0x52 +#define RF_WE_LUT 0xEF + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AdDaClockEn 0x888 // enable ad/da clock1 for dual-phy +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_XCD_RFPara 0x8b4 +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? +#define REG_BB_TX_PATH_SEL_1 0x93c +#define REG_BB_TX_PATH_SEL_2 0x940 +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + /*Page 19 for TxBF*/ +#define REG_BB_TXBF_ANT_SET_BF1 0x19ac +#define REG_BB_TXBF_ANT_SET_BF0 0x19b4 +// +// PageA(0xA00) +// +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_DSPParameter2 0xa1c //SQ threshold +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +#define RF_T_METER_88E 0x42 // + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 + + +// +// Other Definition +// + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +//byte endable for srwrite +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH3Bytes 0xffffff00 +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f +#define bMask7bits 0x7f +#define bMaskByte2HighNibble 0x00f00000 +#define bMaskByte3LowNibble 0x0f000000 +#define bMaskL3Bytes 0x00ffffff + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PwrSeq.h new file mode 100644 index 00000000..2ef43c23 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8814PwrSeq.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 __HAL8814PWRSEQ_H__ +#define __HAL8814PWRSEQ_H__ + +#include "HalPwrSeqCmd.h" + +/* + Check document WB-110628-DZ-RTL8195 (Jaguar) Power Architecture-R04.pdf + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8814A_TRANS_CARDEMU_TO_ACT_STEPS 16 +#define RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS 20 +#define RTL8814A_TRANS_CARDEMU_TO_SUS_STEPS 17 +#define RTL8814A_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8814A_TRANS_CARDEMU_TO_PDN_STEPS 17 +#define RTL8814A_TRANS_PDN_TO_CARDEMU_STEPS 16 +#define RTL8814A_TRANS_ACT_TO_LPS_STEPS 20 +#define RTL8814A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8814A_TRANS_END_STEPS 1 + + +#define RTL8814A_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x002B, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /* ??0x28[24]=1, enable pll phase select*/ \ + {0x0015, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT3|BIT2|BIT1), (BIT3|BIT2|BIT1)},/* 0x14[11:9]=3'b111,OCP current threshold=1.5A */ \ + {0x002D, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x0E, 0x08},/* 0x2C[11:9]=3'b100, select lpf R3 */ \ + {0x002D, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x70, 0x50},/* 0x2C[14:12]=3'b101, select lpf Rs*/ \ + {0x007B, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* 0x78[30]=1'b1, SDM order select*/ \ + /*{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0}, */ /* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0},/* disable WL suspend*/ \ + {0x00F0, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* */ \ + {0x0081, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x30, 0x20},/* */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ + +#define RTL8814A_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /* 0x2[0] = 0 RESET BB, CLOSE RF */ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, /*Delay 1us*/ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + {0x1002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /* 0x2[0] = 0 RESET BB, CLOSE RF */ \ + {0x0002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, /*Delay 1us*/ \ + {0x1002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*0x1F[7:0] = 0 turn off RF*/ \ + /*{0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},*/ /*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x28}, /* 0x07[7:0] = 0x28 sps pwm mode 0x2a for BT coex*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x02, 0}, /*0x8[1] = 0 ANA clk =500k */ \ + /*{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0|BIT1, 0},*/ /* 0x02[1:0] = 0 reset BB */ \ + {0x0066, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0}, /*0x66[7]=0, disable ckreq for gpio7 output SUS */ \ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x41[4]=0, disable sic for gpio7 output SUS */ \ + {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /*0x42[1]=0, disable ckout for gpio7 output SUS */ \ + {0x004e, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x4E[5]=1, disable LED2 for gpio7 output SUS */ \ + {0x0041, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x41[0]=0, disable uart for gpio7 output SUS */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ + +#define RTL8814A_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0061, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x0F, 0x0c},\ + {0x0061, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x0F, 0x0E},\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x0F, 0x07},/* gpio11 input mode, gpio10~8 output mode */ \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* suspend option all off */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*0x14[13] = 1 turn on ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* 0x14[14] =1 trun on ZCD */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*0x8[1] = 0 ANA clk =500k */ \ + {0x0091, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xA0, 0xA0}, /* 0x91[7]=1 0x91[5]=1 , disable sps,ldo sleep mode */ \ + {0x0070, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /* 0x70[3]=1 enable mainbias polling */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 1 enable WL suspend */ + +#define RTL8814A_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 0 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0x10, 0},/*0x23[4] = 0 hpon LDO sleep mode leave */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/* 0x14[14] =0 trun off ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0},/*0x14[13] = 0 turn off ZCD */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio11 input mode, gpio10~8 input mode */ + +#define RTL8814A_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + /**{0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, //0x194[0]=0 , disable 32K clock*/ \ + /**{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x94}, //0x93=0x94 , 90[30] =0 enable 500k ANA clock .switch clock from 12M to 500K , 90 [26] =0 disable EEprom loader clock*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x03[2] = 0, reset 3081*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x01}, /*0x80=05h if reload fw, fill the default value of host_CPU handshake field*/ \ + {0x0081, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x30}, /*0x80=05h if reload fw, fill the default value of host_CPU handshake field*/ \ + /*{0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xcc},*/ \ + /*{0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xF0, 0xEC},*/ \ + /*{0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x07},*/ /* gpio11 input mode, gpio10~8 output mode */ \ + {0x0045, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio 0~7 output same value as input ?? */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xff},/* gpio0~7 output mode */ \ + {0x0047, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/* 0x47[7:0] = 00 gpio mode */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* 0x15[6] =1 trun on ZCD output */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*0x15[5] = 1 turn on ZCD */ \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/*0x12[6] = 0 force PFM mode */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4},/*0x23[4] = 1 hpon LDO sleep mode */ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*0x8[1] = 0 ANA clk =500k */ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x001f, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* 0x01f[1]=0 , disable RFC_0 control REG_RF_CTRL_8814A */ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* 0x020[1]=0 , disable RFC_1 control REG_RF_CTRL_8814A */ \ + {0x0021, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* 0x021[1]=0 , disable RFC_2 control REG_RF_CTRL_8814A */ \ + {0x0076, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* 0x076[1]=0 , disable RFC_3 control REG_OPT_CTRL_8814A +2 */ \ + {0x0091, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xA0, 0xA0}, /* 0x91[7]=1 0x91[5]=1 , disable sps,ldo sleep mode */ \ + {0x0070, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /* 0x70[3]=1 enable mainbias polling */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3}, /*0x04[11] = 1 enable WL suspend*/ + +#define RTL8814A_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0012, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/*0x12[6] = 1 force PWM mode */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0},/*0x15[5] = 0 turn off ZCD */ \ + {0x0015, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/* 0x15[6] =0 trun off ZCD output */ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0},/*0x23[4] = 0 hpon LDO leave sleep mode */ \ + {0x0046, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/* gpio0~7 input mode */ \ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00}, /* gpio11 input mode, gpio10~8 input mode */ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0}, /*0x04[10] = 0, enable SW LPS PCIE only*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, 0}, /*0x04[11] = 0, enable WL suspend*/ \ + /*{0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2},*/ /*0x03[2] = 1, enable 3081*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ \ + {0x0071, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/*0x70[10] = 0, CPHY_MBIAS_EN disable*/ + + +#define RTL8814A_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8814A_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8814A_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x7F},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0c00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xc00[7:0] = 4 turn off 3-wire */ \ + {0x0e00, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x04}, /* 0xe00[7:0] = 4 turn off 3-wire */ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated,and RF closed*/ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + {0x1002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated,and RF closed*/ \ + {0x0002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x1002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0}, /* Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x05F1, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Respond TxOK to scheduler*/ + + +#define RTL8814A_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/ \ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/ \ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /* Delay*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/ \ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /* Polling 0x109[7]=0 TSF in 40M*/ \ + /*{0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, */ /*. ??0x29[7:6] = 2b'00 enable BB clock*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/ \ + {0x0002, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/ \ + {0x1002, ~PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x1002[1:0] = 2b'11 enable BB macro*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8814A_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8814A_power_on_flow[RTL8814A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_radio_off_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_card_disable_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_card_enable_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_suspend_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_resume_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_hwpdn_flow[RTL8814A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8814A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_enter_lps_flow[RTL8814A_TRANS_ACT_TO_LPS_STEPS+RTL8814A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8814A_leave_lps_flow[RTL8814A_TRANS_LPS_TO_ACT_STEPS+RTL8814A_TRANS_END_STEPS]; + +#endif //__HAL8814PWRSEQ_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8821APwrSeq.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8821APwrSeq.h new file mode 100644 index 00000000..840dd742 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/Hal8821APwrSeq.h @@ -0,0 +1,186 @@ +#ifndef REALTEK_POWER_SEQUENCE_8821 +#define REALTEK_POWER_SEQUENCE_8821 + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20130516-JackieLau-RTL8821A_Power_Architecture-R10.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS 25 +#define RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS 15 +#define RTL8821A_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8821A_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8821A_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8821A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8821A_TRANS_END_STEPS 1 + + +#define RTL8821A_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3|BIT2), 0},/* disable SW LPS 0x04[10]=0 and WLSUS_EN 0x04[12:11]=0*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , BIT0},/* Disable USB suspend */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0 , 0},/* Enable USB suspend */ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*0x4C[24] = 0x4F[0] = 1, switch DPDT_SEL_P output from WL BB */\ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT5|BIT4), (BIT5|BIT4)},/*0x66[13] = 0x67[5] = 1, switch for PAPE_G/PAPE_A from WL BB ; 0x66[12] = 0x67[4] = 1, switch LNAON from WL BB */\ + {0x0025, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/*anapar_mac<118> , 0x25[6]=0 by wlan single function*/\ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable falling edge triggering interrupt*/\ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable GPIO9 interrupt mode*/\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable GPIO9 input mode*/\ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Enable HSISR GPIO[C:0] interrupt*/\ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable HSISR GPIO9 interrupt*/\ + {0x007A, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3A},/*0x7A = 0x3A start BT*/\ + {0x002E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF , 0x82 },/* 0x2C[23:12]=0x820 ; XTAL trim */ \ + {0x0010, PWR_CUT_A_MSK , PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6 , BIT6 },/* 0x10[6]=1 ; MP·s¼W¹ï©ó0x2Cªº±±¨îÅv¡A¶·§â0x10[6]³]¬°1¤~¯àÅýWLAN±±¨î */ \ + + +#define RTL8821A_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*0x4C[24] = 0x4F[0] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable rising edge triggering interrupt*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \ + + +#define RTL8821A_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8821A_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8821A_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8821A_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8821A_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8821A_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8821A_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ \ + + +#define RTL8821A_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + +#define RTL8821A_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8821A_power_on_flow[RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_radio_off_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_card_disable_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_card_enable_flow[RTL8821A_TRANS_CARDDIS_TO_CARDEMU_STEPS+RTL8821A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_suspend_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_resume_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8821A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_hwpdn_flow[RTL8821A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8821A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_enter_lps_flow[RTL8821A_TRANS_ACT_TO_LPS_STEPS+RTL8821A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8821A_leave_lps_flow[RTL8821A_TRANS_LPS_TO_ACT_STEPS+RTL8821A_TRANS_END_STEPS]; + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalPwrSeqCmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalPwrSeqCmd.h new file mode 100644 index 00000000..5cf122fb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalPwrSeqCmd.h @@ -0,0 +1,138 @@ +/****************************************************************************** + * + * 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 __HALPWRSEQCMD_H__ +#define __HALPWRSEQCMD_H__ + +#include + +/*---------------------------------------------*/ +//3 The value of cmd: 4 bits +/*---------------------------------------------*/ +#define PWR_CMD_READ 0x00 + // offset: the read register offset + // msk: the mask of the read value + // value: N/A, left by 0 + // note: dirver shall implement this function by read & msk + +#define PWR_CMD_WRITE 0x01 + // offset: the read register offset + // msk: the mask of the write bits + // value: write value + // note: driver shall implement this cmd by read & msk after write + +#define PWR_CMD_POLLING 0x02 + // offset: the read register offset + // msk: the mask of the polled value + // value: the value to be polled, masked by the msd field. + // note: driver shall implement this cmd by + // do{ + // if( (Read(offset) & msk) == (value & msk) ) + // break; + // } while(not timeout); + +#define PWR_CMD_DELAY 0x03 + // offset: the value to delay + // msk: N/A + // value: the unit of delay, 0: us, 1: ms + +#define PWR_CMD_END 0x04 + // offset: N/A + // msk: N/A + // value: N/A + +/*---------------------------------------------*/ +//3 The value of base: 4 bits +/*---------------------------------------------*/ + // define the base address of each block +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +/*---------------------------------------------*/ +//3 The value of interface_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of fab_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of cut_msk: 8 bits +/*---------------------------------------------*/ +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + + +typedef enum _PWRSEQ_CMD_DELAY_UNIT_ +{ + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +} PWRSEQ_DELAY_UNIT; + +typedef struct _WL_PWR_CFG_ +{ + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +} WLAN_PWR_CFG, *PWLAN_PWR_CFG; + + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk +#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base +#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd +#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk +#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value + + +//================================================================================ +// Prototype of protected function. +//================================================================================ +u8 HalPwrSeqCmdParsing( + PADAPTER padapter, + u8 CutVersion, + u8 FabVersion, + u8 InterfaceType, + WLAN_PWR_CFG PwrCfgCmd[]); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalVerDef.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalVerDef.h new file mode 100644 index 00000000..d3df5df9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/HalVerDef.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 __HAL_VERSION_DEF_H__ +#define __HAL_VERSION_DEF_H__ + +#define TRUE _TRUE +#define FALSE _FALSE + +// HAL_IC_TYPE_E +typedef enum tag_HAL_IC_Type_Definition +{ + CHIP_8192S = 0, + CHIP_8188C = 1, + CHIP_8192C = 2, + CHIP_8192D = 3, + CHIP_8723A = 4, + CHIP_8188E = 5, + CHIP_8812 = 6, + CHIP_8821 = 7, + CHIP_8723B = 8, + CHIP_8192E = 9, + CHIP_8814A = 10, + CHIP_8703B = 11, + CHIP_8188F = 12, +}HAL_IC_TYPE_E; + +//HAL_CHIP_TYPE_E +typedef enum tag_HAL_CHIP_Type_Definition +{ + TEST_CHIP = 0, + NORMAL_CHIP = 1, + FPGA = 2, +}HAL_CHIP_TYPE_E; + +//HAL_CUT_VERSION_E +typedef enum tag_HAL_Cut_Version_Definition +{ + A_CUT_VERSION = 0, + B_CUT_VERSION = 1, + C_CUT_VERSION = 2, + D_CUT_VERSION = 3, + E_CUT_VERSION = 4, + F_CUT_VERSION = 5, + G_CUT_VERSION = 6, + H_CUT_VERSION = 7, + I_CUT_VERSION = 8, + J_CUT_VERSION = 9, + K_CUT_VERSION = 10, +}HAL_CUT_VERSION_E; + +// HAL_Manufacturer +typedef enum tag_HAL_Manufacturer_Version_Definition +{ + CHIP_VENDOR_TSMC = 0, + CHIP_VENDOR_UMC = 1, + CHIP_VENDOR_SMIC = 2, +}HAL_VENDOR_E; + +typedef enum tag_HAL_RF_Type_Definition +{ + RF_TYPE_1T1R = 0, + RF_TYPE_1T2R = 1, + RF_TYPE_2T2R = 2, + RF_TYPE_2T3R = 3, + RF_TYPE_2T4R = 4, + RF_TYPE_3T3R = 5, + RF_TYPE_3T4R = 6, + RF_TYPE_4T4R = 7, +}HAL_RF_TYPE_E; + +typedef struct tag_HAL_VERSION +{ + HAL_IC_TYPE_E ICType; + HAL_CHIP_TYPE_E ChipType; + HAL_CUT_VERSION_E CUTVersion; + HAL_VENDOR_E VendorType; + HAL_RF_TYPE_E RFType; + u8 ROMVer; +}HAL_VERSION,*PHAL_VERSION; + +//VERSION_8192C VersionID; +//HAL_VERSION VersionID; + +// Get element +#define GET_CVID_IC_TYPE(version) ((HAL_IC_TYPE_E)(((HAL_VERSION)version).ICType) ) +#define GET_CVID_CHIP_TYPE(version) ((HAL_CHIP_TYPE_E)(((HAL_VERSION)version).ChipType) ) +#define GET_CVID_RF_TYPE(version) ((HAL_RF_TYPE_E)(((HAL_VERSION)version).RFType)) +#define GET_CVID_MANUFACTUER(version) ((HAL_VENDOR_E)(((HAL_VERSION)version).VendorType)) +#define GET_CVID_CUT_VERSION(version) ((HAL_CUT_VERSION_E)(((HAL_VERSION)version).CUTVersion)) +#define GET_CVID_ROM_VERSION(version) ((((HAL_VERSION)version).ROMVer) & ROM_VERSION_MASK) + +//---------------------------------------------------------------------------- +//Common Macro. -- +//---------------------------------------------------------------------------- +//HAL_VERSION VersionID + +// HAL_IC_TYPE_E +#if 0 +#define IS_81XXC(version) (((GET_CVID_IC_TYPE(version) == CHIP_8192C)||(GET_CVID_IC_TYPE(version) == CHIP_8188C))? TRUE : FALSE) +#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723A)? TRUE : FALSE) +#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192D)? TRUE : FALSE) +#endif + +#define IS_8188E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188E)? TRUE : FALSE) +#define IS_8188F(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188F) ? TRUE : FALSE) +#define IS_8192E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192E)? TRUE : FALSE) +#define IS_8812_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8812)? TRUE : FALSE) +#define IS_8821_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8821)? TRUE : FALSE) +#define IS_8814A_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8814A) ? TRUE : FALSE) +#define IS_8723B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723B)? TRUE : FALSE) +#define IS_8703B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8703B)? TRUE : FALSE) + +//HAL_CHIP_TYPE_E +#define IS_TEST_CHIP(version) ((GET_CVID_CHIP_TYPE(version)==TEST_CHIP)? TRUE: FALSE) +#define IS_NORMAL_CHIP(version) ((GET_CVID_CHIP_TYPE(version)==NORMAL_CHIP)? TRUE: FALSE) + +//HAL_CUT_VERSION_E +#define IS_A_CUT(version) ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? TRUE : FALSE) +#define IS_B_CUT(version) ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? TRUE : FALSE) +#define IS_C_CUT(version) ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? TRUE : FALSE) +#define IS_D_CUT(version) ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? TRUE : FALSE) +#define IS_E_CUT(version) ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? TRUE : FALSE) +#define IS_F_CUT(version) ((GET_CVID_CUT_VERSION(version) == F_CUT_VERSION) ? TRUE : FALSE) +#define IS_I_CUT(version) ((GET_CVID_CUT_VERSION(version) == I_CUT_VERSION) ? TRUE : FALSE) +#define IS_J_CUT(version) ((GET_CVID_CUT_VERSION(version) == J_CUT_VERSION) ? TRUE : FALSE) +#define IS_K_CUT(version) ((GET_CVID_CUT_VERSION(version) == K_CUT_VERSION) ? TRUE : FALSE) + +//HAL_VENDOR_E +#define IS_CHIP_VENDOR_TSMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC)? TRUE: FALSE) +#define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC)? TRUE: FALSE) +#define IS_CHIP_VENDOR_SMIC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_SMIC)? TRUE: FALSE) + +//HAL_RF_TYPE_E +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R)? TRUE : FALSE ) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)? TRUE : FALSE) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)? TRUE : FALSE) +#define IS_3T3R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_3T3R)? TRUE : FALSE) +#define IS_3T4R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_3T4R)? TRUE : FALSE) +#define IS_4T4R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_4T4R)? TRUE : FALSE) + + + +//---------------------------------------------------------------------------- +//Chip version Macro. -- +//---------------------------------------------------------------------------- +#if 0 +#define IS_81XXC_TEST_CHIP(version) ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version)))? TRUE: FALSE) + +#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ? TRUE : FALSE) +#define IS_81xxC_VENDOR_UMC_A_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_A_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) +#define IS_81xxC_VENDOR_UMC_B_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_B_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) +#define IS_81xxC_VENDOR_UMC_C_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) + +#define IS_NORMAL_CHIP92D(version) (( IS_92D(version))?((GET_CVID_CHIP_TYPE(version)==NORMAL_CHIP)? TRUE: FALSE):FALSE) + +#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? (IS_2T2R(version) ? TRUE: FALSE) : FALSE) +#define IS_92D_C_CUT(version) ((IS_92D(version)) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE) +#define IS_92D_D_CUT(version) ((IS_92D(version)) ? (IS_D_CUT(version) ? TRUE : FALSE) : FALSE) +#define IS_92D_E_CUT(version) ((IS_92D(version)) ? (IS_E_CUT(version) ? TRUE : FALSE) : FALSE) + +#define IS_8723A_A_CUT(version) ((IS_8723_SERIES(version)) ? ( IS_A_CUT(version)?TRUE : FALSE) : FALSE) +#define IS_8723A_B_CUT(version) ((IS_8723_SERIES(version)) ? ( IS_B_CUT(version)?TRUE : FALSE) : FALSE) +#endif + +#define IS_VENDOR_8188E_I_CUT_SERIES(_Adapter) ((IS_8188E(GET_HAL_DATA(_Adapter)->VersionID)) ? ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->VersionID) >= I_CUT_VERSION) ? TRUE : FALSE) : FALSE) + +#define IS_VENDOR_8812A_TEST_CHIP(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? FALSE : TRUE) : FALSE) +#define IS_VENDOR_8812A_MP_CHIP(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? TRUE : FALSE) : FALSE) +#define IS_VENDOR_8812A_C_CUT(_Adapter) ((IS_8812_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->VersionID) == C_CUT_VERSION) ? TRUE : FALSE) : FALSE) + +#define IS_VENDOR_8821A_TEST_CHIP(_Adapter) ((IS_8821_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? FALSE : TRUE) : FALSE) +#define IS_VENDOR_8821A_MP_CHIP(_Adapter) ((IS_8821_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? TRUE : FALSE) : FALSE) + +#define IS_VENDOR_8192E_B_CUT(_Adapter) ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->VersionID) == B_CUT_VERSION) ? TRUE : FALSE) + +#define IS_VENDOR_8723B_TEST_CHIP(_Adapter) ((IS_8723B_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? FALSE : TRUE) : FALSE) +#define IS_VENDOR_8723B_MP_CHIP(_Adapter) ((IS_8723B_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? TRUE : FALSE) : FALSE) + +#define IS_VENDOR_8703B_TEST_CHIP(_Adapter) ((IS_8703B_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? FALSE : TRUE) : FALSE) +#define IS_VENDOR_8703B_MP_CHIP(_Adapter) ((IS_8703B_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? TRUE : FALSE) : FALSE) +#define IS_VENDOR_8814A_TEST_CHIP(_Adapter) ((IS_8814A_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? FALSE : TRUE) : FALSE) +#define IS_VENDOR_8814A_MP_CHIP(_Adapter) ((IS_8814A_SERIES(GET_HAL_DATA(_Adapter)->VersionID)) ? ((IS_NORMAL_CHIP(GET_HAL_DATA(_Adapter)->VersionID)) ? TRUE : FALSE) : FALSE) + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/autoconf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/autoconf.h new file mode 100644 index 00000000..fc951186 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/autoconf.h @@ -0,0 +1,243 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/* + * Public General Config + */ +#define AUTOCONF_INCLUDED + +#define RTL871X_MODULE_NAME "8189FS" +#define DRV_NAME "rtl8189fs" + +#ifndef CONFIG_RTL8188F +#define CONFIG_RTL8188F +#endif +#define CONFIG_SDIO_HCI + +#define PLATFORM_LINUX + + +/* + * 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 */ + #ifndef CONFIG_PLATFORM_INTEL_BYT + #define CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER + #endif //!CONFIG_PLATFORM_INTEL_BYT + //#define CONFIG_DEBUG_CFG80211 + #define CONFIG_SET_SCAN_DENY_TIMER + /*#define SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42*/ /* wpa_supplicant realtek version <= jb42 will be defined this */ +#endif + +#define CONFIG_AP_MODE +#ifdef CONFIG_AP_MODE + #define CONFIG_NATIVEAP_MLME + #ifndef CONFIG_NATIVEAP_MLME + #define CONFIG_HOSTAPD_MLME + #endif + //#define CONFIG_FIND_BEST_CHANNEL + #define CONFIG_TX_MCAST2UNI // Support IP multicast->unicast +#endif + +#define CONFIG_P2P +#ifdef CONFIG_P2P + //Added by Albert 20110812 + //The CONFIG_WFD is for supporting the Wi-Fi display + #define CONFIG_WFD + + #define CONFIG_P2P_REMOVE_GROUP_INFO + + //#define CONFIG_DBG_P2P + #define CONFIG_P2P_PS + #define CONFIG_P2P_OP_CHK_SOCIAL_CH + #define CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT //replace CONFIG_P2P_CHK_INVITE_CH_LIST flag + #define CONFIG_P2P_INVITE_IOT +#endif + +// Added by Kurt 20110511 +#ifdef CONFIG_TDLS + #define CONFIG_TDLS_DRIVER_SETUP +// #ifndef CONFIG_WFD +// #define CONFIG_WFD +// #endif +// #define CONFIG_TDLS_AUTOSETUP + #define CONFIG_TDLS_AUTOCHECKALIVE + #define CONFIG_TDLS_CH_SW /* Enable "CONFIG_TDLS_CH_SW" by default, however limit it to only work in wifi logo test mode but not in normal mode currently */ +#endif + +//#define CONFIG_CONCURRENT_MODE // Set from Makefile +#ifdef CONFIG_CONCURRENT_MODE + //#define CONFIG_HWPORT_SWAP // Port0->Sec , Port1 -> Pri + #define CONFIG_RUNTIME_PORT_SWITCH + #ifndef CONFIG_RUNTIME_PORT_SWITCH + #define CONFIG_TSF_RESET_OFFLOAD // For 2 PORT TSF SYNC. + #endif + //#define DBG_RUNTIME_PORT_SWITCH + #define CONFIG_SCAN_BACKOP +#endif // CONFIG_CONCURRENT_MODE + +#define CONFIG_LAYER2_ROAMING +#define CONFIG_LAYER2_ROAMING_RESUME + +//#define CONFIG_80211D + + +/* + * Hareware/Firmware Related Config + */ +//#define CONFIG_BT_COEXIST // Set from Makefile +//#define CONFIG_ANTENNA_DIVERSITY // Set from Makefile +//#define SUPPORT_HW_RFOFF_DETECTED + +//#define CONFIG_SW_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, */ + +/* + * Interface Related Config + */ +#define CONFIG_SDIO_CHK_HCI_RESUME +#define CONFIG_TX_AGGREGATION +#define CONFIG_SDIO_RX_COPY +#define CONFIG_XMIT_THREAD_MODE +//#define CONFIG_SDIO_TX_ENABLE_AVAL_INT + + +/* + * Others + */ +//#define CONFIG_MAC_LOOPBACK_DRIVER + +#define CONFIG_SKB_COPY //for amsdu + +#define CONFIG_NEW_SIGNAL_STAT_PROCESS + +#define CONFIG_EMBEDDED_FWIMG +//#define CONFIG_FILE_FWIMG + +#define CONFIG_LONG_DELAY_ISSUE +//#define CONFIG_PATCH_JOIN_WRONG_CHANNEL +#define CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR + + +/* + * Auto Config Section + */ +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + #undef CONFIG_IOCTL_CFG80211 + #undef CONFIG_AP_MODE + #undef CONFIG_NATIVEAP_MLME + #undef CONFIG_POWER_SAVING + #undef CONFIG_BT_COEXIST + #undef CONFIG_ANTENNA_DIVERSITY + #undef SUPPORT_HW_RFOFF_DETECTED +#endif + +#ifdef CONFIG_MP_INCLUDED + #define MP_DRIVER 1 + #define CONFIG_MP_IWPRIV_SUPPORT +#else // !CONFIG_MP_INCLUDED + #define MP_DRIVER 0 +#endif // !CONFIG_MP_INCLUDED + +#ifdef CONFIG_POWER_SAVING + #define CONFIG_IPS + #define CONFIG_LPS + + #if defined(CONFIG_LPS) && (defined(CONFIG_GSPI_HCI) || defined(CONFIG_SDIO_HCI)) + #define CONFIG_LPS_LCLK + #endif + + #ifdef CONFIG_LPS + #define CONFIG_CHECK_LEAVE_LPS + //#define CONFIG_LPS_SLOW_TRANSITION + #endif + + #ifdef CONFIG_LPS_LCLK + #define CONFIG_DETECT_CPWM_BY_POLLING + #define CONFIG_LPS_RPWM_TIMER + #if defined(CONFIG_LPS_RPWM_TIMER) || defined(CONFIG_DETECT_CPWM_BY_POLLING) + #define LPS_RPWM_WAIT_MS 300 + #endif + #define CONFIG_LPS_LCLK_WD_TIMER /* Watch Dog timer in LPS LCLK */ + #endif + + #ifdef CONFIG_IPS + #define CONFIG_IPS_CHECK_IN_WD /* Do IPS Check in WatchDog */ + //#define CONFIG_SWLPS_IN_IPS /* Do SW LPS flow when entering and leaving IPS */ + //#define CONFIG_FWLPS_IN_IPS /* issue H2C command to let FW do LPS when entering IPS */ + #endif +#endif /* CONFIG_POWER_SAVING */ + +#define BT_30_SUPPORT 0 + +#ifdef CONFIG_WOWLAN + //#define CONFIG_GTK_OL + #define CONFIG_ARP_KEEP_ALIVE +#endif // CONFIG_WOWLAN + +#ifdef CONFIG_GPIO_WAKEUP + #ifndef WAKEUP_GPIO_IDX + #define WAKEUP_GPIO_IDX 0 + #endif +#endif + +/* + * Debug Related Config + */ +#define CONFIG_DEBUG /* DBG_871X, etc... */ + +#ifdef CONFIG_DEBUG +#define DBG 1 // for ODM & BTCOEX debug +//#define CONFIG_DEBUG_RTL871X /* RT_TRACE, RT_PRINT_DATA, _func_enter_, _func_exit_ */ +#else // !CONFIG_DEBUG +#define DBG 0 // for ODM & BTCOEX debug +#endif // !CONFIG_DEBUG + +#define CONFIG_PROC_DEBUG + +#define DBG_CONFIG_ERROR_DETECT +//#define DBG_XMIT_BUF +//#define DBG_XMIT_BUF_EXT +//#define DBG_CHECK_FW_PS_STATE +//#define DBG_CHECK_FW_PS_STATE_H2C +//#define CONFIG_FW_C2H_DEBUG + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/basic_types.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/basic_types.h new file mode 100644 index 00000000..0b75813e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/basic_types.h @@ -0,0 +1,385 @@ +/****************************************************************************** + * + * 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 __BASIC_TYPES_H__ +#define __BASIC_TYPES_H__ + + +#define SUCCESS 0 +#define FAIL (-1) + +#ifndef TRUE + #define _TRUE 1 +#else + #define _TRUE TRUE +#endif + +#ifndef FALSE + #define _FALSE 0 +#else + #define _FALSE FALSE +#endif + +#ifdef PLATFORM_WINDOWS + + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed long s32; + typedef unsigned long u32; + + typedef unsigned int uint; + typedef signed int sint; + + + typedef signed long long s64; + typedef unsigned long long u64; + + #ifdef NDIS50_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 0 + + #endif + + #ifdef NDIS51_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 1 + + #endif + + typedef NDIS_PROC proc_t; + + typedef LONG atomic_t; + +#endif + + +#ifdef PLATFORM_LINUX + #include + #include + #include + #include + #include + #include + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + typedef signed int sint; + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + + #define UCHAR u8 + #define USHORT u16 + #define UINT u32 + #define ULONG u32 + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) + typedef _Bool bool; + #endif + + typedef void (*proc_t)(void*); + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + + +#ifdef PLATFORM_FREEBSD + + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed int s32; + typedef unsigned int u32; + + typedef unsigned int uint; + typedef signed int sint; + typedef long atomic_t; + + typedef signed long long s64; + typedef unsigned long long u64; + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + typedef u32 dma_addr_t; + #define UCHAR u8 + #define USHORT u16 + #define UINT u32 + #define ULONG u32 + + typedef void (*proc_t)(void*); + + typedef unsigned int __kernel_size_t; + typedef int __kernel_ssize_t; + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + +#define MEM_ALIGNMENT_OFFSET (sizeof (SIZE_T)) +#define MEM_ALIGNMENT_PADDING (sizeof(SIZE_T) - 1) + +#define SIZE_PTR SIZE_T +#define SSIZE_PTR SSIZE_T + +/* +* Continuous bits starting from least significant bit +* Example: +* BIT_LEN_MASK_32(0) => 0x00000000 +* BIT_LEN_MASK_32(1) => 0x00000001 +* BIT_LEN_MASK_32(2) => 0x00000003 +* BIT_LEN_MASK_32(32) => 0xFFFFFFFF +*/ +#define BIT_LEN_MASK_32(__BitLen) ((u32)(0xFFFFFFFF >> (32 - (__BitLen)))) +#define BIT_LEN_MASK_16(__BitLen) ((u16)(0xFFFF >> (16 - (__BitLen)))) +#define BIT_LEN_MASK_8(__BitLen) ((u8)(0xFF >> (8 - (__BitLen)))) + +/* +* Continuous bits starting from least significant bit +* Example: +* BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +* BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 +*/ +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ((u32)(BIT_LEN_MASK_32(__BitLen) << (__BitOffset))) +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ((u16)(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))) +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ((u8)(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))) + +/* +* Convert LE data to host byte order +*/ +#define EF1Byte (u8) +#define EF2Byte le16_to_cpu +#define EF4Byte le32_to_cpu + +/* +* Read LE data from memory to host byte order +*/ +#define ReadLE4Byte(_ptr) le32_to_cpu(*((u32 *)(_ptr))) +#define ReadLE2Byte(_ptr) le16_to_cpu(*((u16 *)(_ptr))) +#define ReadLE1Byte(_ptr) (*((u8 *)(_ptr))) + +/* +* Read BE data from memory to host byte order +*/ +#define ReadBEE4Byte(_ptr) be32_to_cpu(*((u32 *)(_ptr))) +#define ReadBE2Byte(_ptr) be16_to_cpu(*((u16 *)(_ptr))) +#define ReadBE1Byte(_ptr) (*((u8 *)(_ptr))) + +/* +* Write host byte order data to memory in LE order +*/ +#define WriteLE4Byte(_ptr, _val) (*((u32 *)(_ptr))) = cpu_to_le32(_val) +#define WriteLE2Byte(_ptr, _val) (*((u16 *)(_ptr))) = cpu_to_le16(_val) +#define WriteLE1Byte(_ptr, _val) (*((u8 *)(_ptr))) = ((u8)(_val)) + +/* +* Write host byte order data to memory in BE order +*/ +#define WriteBE4Byte(_ptr, _val) (*((u32 *)(_ptr))) = cpu_to_be32(_val) +#define WriteBE2Byte(_ptr, _val) (*((u16 *)(_ptr))) = cpu_to_be16(_val) +#define WriteBE1Byte(_ptr, _val) (*((u8 *)(_ptr))) = ((u8)(_val)) + +/* +* Return 4-byte value in host byte ordering from 4-byte pointer in litten-endian system. +*/ +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (le32_to_cpu(*((u32 *)(__pStart)))) +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) (le16_to_cpu(*((u16 *)(__pStart)))) +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) ((*((u8 *)(__pStart)))) + +/* +* Return 4-byte value in host byte ordering from 4-byte pointer in big-endian system. +*/ +#define BE_P4BYTE_TO_HOST_4BYTE(__pStart) (be32_to_cpu(*((u32 *)(__pStart)))) +#define BE_P2BYTE_TO_HOST_2BYTE(__pStart) (be16_to_cpu(*((u16 *)(__pStart)))) +#define BE_P1BYTE_TO_HOST_1BYTE(__pStart) ((*((u8 *)(__pStart)))) + +/* +* Translate subfield (continuous bits in little-endian) of 4-byte value in LE byte to +* 4-byte value in host byte ordering. +*/ +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ((LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_32(__BitLen)) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ((LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_16(__BitLen)) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ((LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_8(__BitLen)) + +/* +* Translate subfield (continuous bits in big-endian) of 4-byte value in BE byte to +* 4-byte value in host byte ordering. +*/ +#define BE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ((BE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_32(__BitLen)) + +#define BE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ((BE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_16(__BitLen)) + +#define BE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ((BE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset)) & BIT_LEN_MASK_8(__BitLen)) + +/* +* Mask subfield (continuous bits in little-endian) of 4-byte value in LE byte oredering +* and return the result in 4-byte value in host byte ordering. +*/ +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + (LE_P4BYTE_TO_HOST_4BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen))) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + (LE_P2BYTE_TO_HOST_2BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen))) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + (LE_P1BYTE_TO_HOST_1BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen))) + +/* +* Mask subfield (continuous bits in big-endian) of 4-byte value in BE byte oredering +* and return the result in 4-byte value in host byte ordering. +*/ +#define BE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + (BE_P4BYTE_TO_HOST_4BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen))) + +#define BE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + (BE_P2BYTE_TO_HOST_2BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen))) + +#define BE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + (BE_P1BYTE_TO_HOST_1BYTE(__pStart) & (~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen))) + +/* +* Set subfield of little-endian 4-byte value to specified value. +*/ +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 32) \ + WriteLE4Byte(__pStart, __Value); \ + else { \ + WriteLE4Byte(__pStart, \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 16) \ + WriteLE2Byte(__pStart, __Value); \ + else { \ + WriteLE2Byte(__pStart, \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 8) \ + WriteLE1Byte(__pStart, __Value); \ + else { \ + WriteLE1Byte(__pStart, \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +/* +* Set subfield of big-endian 4-byte value to specified value. +*/ +#define SET_BITS_TO_BE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 32) \ + WriteBE4Byte(__pStart, __Value); \ + else { \ + WriteBE4Byte(__pStart, \ + BE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +#define SET_BITS_TO_BE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 16) \ + WriteBE2Byte(__pStart, __Value); \ + else { \ + WriteBE2Byte(__pStart, \ + BE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +#define SET_BITS_TO_BE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + do { \ + if (__BitOffset == 0 && __BitLen == 8) \ + WriteBE1Byte(__pStart, __Value); \ + else { \ + WriteBE1Byte(__pStart, \ + BE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset)) \ + ); \ + } \ + } while (0) + +// Get the N-bytes aligment offset from the current length +#define N_BYTE_ALIGMENT(__Value, __Aligment) ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / __Aligment) * __Aligment)) + +typedef unsigned char BOOLEAN,*PBOOLEAN; + +#define TEST_FLAG(__Flag,__testFlag) (((__Flag) & (__testFlag)) != 0) +#define SET_FLAG(__Flag, __setFlag) ((__Flag) |= __setFlag) +#define CLEAR_FLAG(__Flag, __clearFlag) ((__Flag) &= ~(__clearFlag)) +#define CLEAR_FLAGS(__Flag) ((__Flag) = 0) +#define TEST_FLAGS(__Flag, __testFlags) (((__Flag) & (__testFlags)) == (__testFlags)) + +#endif //__BASIC_TYPES_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/big_endian.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/big_endian.h new file mode 100644 index 00000000..ccb31328 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/big_endian.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_BIG_ENDIAN_H +#define _LINUX_BYTEORDER_BIG_ENDIAN_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#include + +#define __constant_htonl(x) ((__u32)(x)) +#define __constant_ntohl(x) ((__u32)(x)) +#define __constant_htons(x) ((__u16)(x)) +#define __constant_ntohs(x) ((__u16)(x)) +#define __constant_cpu_to_le64(x) ___constant_swab64((x)) +#define __constant_le64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_le32(x) ___constant_swab32((x)) +#define __constant_le32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_le16(x) ___constant_swab16((x)) +#define __constant_le16_to_cpu(x) ___constant_swab16((x)) +#define __constant_cpu_to_be64(x) ((__u64)(x)) +#define __constant_be64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_be32(x) ((__u32)(x)) +#define __constant_be32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_be16(x) ((__u16)(x)) +#define __constant_be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64(x) __swab64((x)) +#define __le64_to_cpu(x) __swab64((x)) +#define __cpu_to_le32(x) __swab32((x)) +#define __le32_to_cpu(x) __swab32((x)) +#define __cpu_to_le16(x) __swab16((x)) +#define __le16_to_cpu(x) __swab16((x)) +#define __cpu_to_be64(x) ((__u64)(x)) +#define __be64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_be32(x) ((__u32)(x)) +#define __be32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_be16(x) ((__u16)(x)) +#define __be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64p(x) __swab64p((x)) +#define __le64_to_cpup(x) __swab64p((x)) +#define __cpu_to_le32p(x) __swab32p((x)) +#define __le32_to_cpup(x) __swab32p((x)) +#define __cpu_to_le16p(x) __swab16p((x)) +#define __le16_to_cpup(x) __swab16p((x)) +#define __cpu_to_be64p(x) (*(__u64*)(x)) +#define __be64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_be32p(x) (*(__u32*)(x)) +#define __be32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_be16p(x) (*(__u16*)(x)) +#define __be16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_le64s(x) __swab64s((x)) +#define __le64_to_cpus(x) __swab64s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) +#define __le32_to_cpus(x) __swab32s((x)) +#define __cpu_to_le16s(x) __swab16s((x)) +#define __le16_to_cpus(x) __swab16s((x)) +#define __cpu_to_be64s(x) do {} while (0) +#define __be64_to_cpus(x) do {} while (0) +#define __cpu_to_be32s(x) do {} while (0) +#define __be32_to_cpus(x) do {} while (0) +#define __cpu_to_be16s(x) do {} while (0) +#define __be16_to_cpus(x) do {} while (0) + +#include + +#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/generic.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/generic.h new file mode 100644 index 00000000..759b0c47 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/generic.h @@ -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 + * + * + ******************************************************************************/ +#ifndef _LINUX_BYTEORDER_GENERIC_H +#define _LINUX_BYTEORDER_GENERIC_H + +/* + * linux/byteorder_generic.h + * Generic Byte-reordering support + * + * Francois-Rene Rideau 19970707 + * gathered all the good ideas from all asm-foo/byteorder.h into one file, + * cleaned them up. + * I hope it is compliant with non-GCC compilers. + * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, + * because I wasn't sure it would be ok to put it in types.h + * Upgraded it to 2.1.43 + * Francois-Rene Rideau 19971012 + * Upgraded it to 2.1.57 + * to please Linus T., replaced huge #ifdef's between little/big endian + * by nestedly #include'd files. + * Francois-Rene Rideau 19971205 + * Made it to 2.1.71; now a facelift: + * Put files under include/linux/byteorder/ + * Split swab from generic support. + * + * TODO: + * = Regular kernel maintainers could also replace all these manual + * byteswap macros that remain, disseminated among drivers, + * after some grep or the sources... + * = Linus might want to rename all these macros and files to fit his taste, + * to fit his personal naming scheme. + * = it seems that a few drivers would also appreciate + * nybble swapping support... + * = every architecture could add their byteswap macro in asm/byteorder.h + * see how some architectures already do (i386, alpha, ppc, etc) + * = cpu_to_beXX and beXX_to_cpu might some day need to be well + * distinguished throughout the kernel. This is not the case currently, + * since little endian, big endian, and pdp endian machines needn't it. + * But this might be the case for, say, a port of Linux to 20/21 bit + * architectures (and F21 Linux addict around?). + */ + +/* + * The following macros are to be defined by : + * + * Conversion of long and short int between network and host format + * ntohl(__u32 x) + * ntohs(__u16 x) + * htonl(__u32 x) + * htons(__u16 x) + * It seems that some programs (which? where? or perhaps a standard? POSIX?) + * might like the above to be functions, not macros (why?). + * if that's true, then detect them, and take measures. + * Anyway, the measure is: define only ___ntohl as a macro instead, + * and in a separate file, have + * unsigned long inline ntohl(x){return ___ntohl(x);} + * + * The same for constant arguments + * __constant_ntohl(__u32 x) + * __constant_ntohs(__u16 x) + * __constant_htonl(__u32 x) + * __constant_htons(__u16 x) + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + * + */ + + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) || defined(PLATFORM_MPIXEL) || defined(PLATFORM_FREEBSD) +/* + * inside the kernel, we can use nicknames; + * outside of it, we must avoid POSIX namespace pollution... + */ +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus +#endif + + +/* + * Handle ntohl and suches. These have various compatibility + * issues - like we want to give the prototype even though we + * also have a macro for them in case some strange program + * wants to take the address of the thing or something.. + * + * Note that these used to return a "long" in libc5, even though + * long is often 64-bit these days.. Thus the casts. + * + * They have to be macros in order to do the constant folding + * correctly - if the argument passed into a inline function + * it is no longer constant according to gcc.. + */ + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +/* + * Do the prototypes. Somebody might want to take the + * address or some such sick thing.. + */ +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +extern __u32 ntohl(__u32); +extern __u32 htonl(__u32); +#else //defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#ifndef PLATFORM_FREEBSD +extern unsigned long int ntohl(unsigned long int); +extern unsigned long int htonl(unsigned long int); +#endif +#endif +#ifndef PLATFORM_FREEBSD +extern unsigned short int ntohs(unsigned short int); +extern unsigned short int htons(unsigned short int); +#endif + +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) || defined(PLATFORM_MPIXEL) + +#define ___htonl(x) __cpu_to_be32(x) +#define ___htons(x) __cpu_to_be16(x) +#define ___ntohl(x) __be32_to_cpu(x) +#define ___ntohs(x) __be16_to_cpu(x) + +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#else +#define htonl(x) ((unsigned long)___htonl(x)) +#define ntohl(x) ((unsigned long)___ntohl(x)) +#endif +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#endif /* OPTIMIZE */ + + +#if defined (PLATFORM_WINDOWS) + +#define htonl(x) __cpu_to_be32(x) +#define ntohl(x) __be32_to_cpu(x) +#define htons(x) __cpu_to_be16(x) +#define ntohs(x) __be16_to_cpu(x) + + +#endif + +#endif /* _LINUX_BYTEORDER_GENERIC_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/little_endian.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/little_endian.h new file mode 100644 index 00000000..5a3c8ab4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/little_endian.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_LITTLE_ENDIAN_H +#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +#include + +#ifndef __constant_htonl +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) +#define __constant_cpu_to_le64(x) ((__u64)(x)) +#define __constant_le64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_le32(x) ((__u32)(x)) +#define __constant_le32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le16(x) ((__u16)(x)) +#define __constant_le16_to_cpu(x) ((__u16)(x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) +#define __cpu_to_le64(x) ((__u64)(x)) +#define __le64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_le32(x) ((__u32)(x)) +#define __le32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le16(x) ((__u16)(x)) +#define __le16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_be64(x) __swab64((x)) +#define __be64_to_cpu(x) __swab64((x)) +#define __cpu_to_be32(x) __swab32((x)) +#define __be32_to_cpu(x) __swab32((x)) +#define __cpu_to_be16(x) __swab16((x)) +#define __be16_to_cpu(x) __swab16((x)) +#define __cpu_to_le64p(x) (*(__u64*)(x)) +#define __le64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_le32p(x) (*(__u32*)(x)) +#define __le32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le16p(x) (*(__u16*)(x)) +#define __le16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_be64p(x) __swab64p((x)) +#define __be64_to_cpup(x) __swab64p((x)) +#define __cpu_to_be32p(x) __swab32p((x)) +#define __be32_to_cpup(x) __swab32p((x)) +#define __cpu_to_be16p(x) __swab16p((x)) +#define __be16_to_cpup(x) __swab16p((x)) +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) +#endif // __constant_htonl + +#include + +#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swab.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swab.h new file mode 100644 index 00000000..067c8e43 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swab.h @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_SWAB_H +#define _LINUX_BYTEORDER_SWAB_H + +#if !defined(CONFIG_PLATFORM_MSTAR) +#ifndef __u16 +typedef unsigned short __u16; +#endif + +#ifndef __u32 +typedef unsigned int __u32; +#endif + +#ifndef __u8 +typedef unsigned char __u8; +#endif + +#ifndef __u64 +typedef unsigned long long __u64; +#endif + + +__inline static __u16 ___swab16(__u16 x) +{ + __u16 __x = x; + return + ((__u16)( + (((__u16)(__x) & (__u16)0x00ffU) << 8) | + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); + +} + +__inline static __u32 ___swab32(__u32 x) +{ + __u32 __x = (x); + return ((__u32)( + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); +} + +__inline static __u64 ___swab64(__u64 x) +{ + __u64 __x = (x); + + return + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +} +#endif // CONFIG_PLATFORM_MSTAR + +#ifndef __arch__swab16 +__inline static __u16 __arch__swab16(__u16 x) +{ + return ___swab16(x); +} + +#endif + +#ifndef __arch__swab32 +__inline static __u32 __arch__swab32(__u32 x) +{ + __u32 __tmp = (x) ; + return ___swab32(__tmp); +} +#endif + +#ifndef __arch__swab64 + +__inline static __u64 __arch__swab64(__u64 x) +{ + __u64 __tmp = (x) ; + return ___swab64(__tmp); +} + + +#endif + +#ifndef __swab16 +#define __swab16(x) __fswab16(x) +#define __swab32(x) __fswab32(x) +#define __swab64(x) __fswab64(x) +#endif // __swab16 + +#ifdef PLATFORM_FREEBSD +__inline static __u16 __fswab16(__u16 x) +#else +__inline static const __u16 __fswab16(__u16 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab16(x); +} +#ifdef PLATFORM_FREEBSD +__inline static __u32 __fswab32(__u32 x) +#else +__inline static const __u32 __fswab32(__u32 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab32(x); +} + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) +#define swab16 __swab16 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab32s __swab32s +#define swab64s __swab64s +#endif + +#endif /* _LINUX_BYTEORDER_SWAB_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swabb.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swabb.h new file mode 100644 index 00000000..dbbd50f8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/byteorder/swabb.h @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * 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 _LINUX_BYTEORDER_SWABB_H +#define _LINUX_BYTEORDER_SWABB_H + +/* + * linux/byteorder/swabb.h + * SWAp Bytes Bizarrely + * swaHHXX[ps]?(foo) + * + * Support for obNUXIous pdp-endian and other bizarre architectures. + * Will Linux ever run on such ancient beasts? if not, this file + * will be but a programming pearl. Still, it's a reminder that we + * shouldn't be making too many assumptions when trying to be portable. + * + */ + +/* + * Meaning of the names I chose (vaxlinux people feel free to correct them): + * swahw32 swap 16-bit half-words in a 32-bit word + * swahb32 swap 8-bit halves of each 16-bit half-word in a 32-bit word + * + * No 64-bit support yet. I don't know NUXI conventions for long longs. + * I guarantee it will be a mess when it's there, though :-> + * It will be even worse if there are conflicting 64-bit conventions. + * Hopefully, no one ever used 64-bit objects on NUXI machines. + * + */ + +#define ___swahw32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x0000ffffUL) << 16) | \ + (((__u32)(__x) & (__u32)0xffff0000UL) >> 16) )); \ +}) +#define ___swahb32(x) \ +({ \ + __u32 __x = (x); \ + ((__u32)( \ + (((__u32)(__x) & (__u32)0x00ff00ffUL) << 8) | \ + (((__u32)(__x) & (__u32)0xff00ff00UL) >> 8) )); \ +}) + +#define ___constant_swahw32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \ + (((__u32)(x) & (__u32)0xffff0000UL) >> 16) )) +#define ___constant_swahb32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \ + (((__u32)(x) & (__u32)0xff00ff00UL) >> 8) )) + +/* + * provide defaults when no architecture-specific optimization is detected + */ +#ifndef __arch__swahw32 +# define __arch__swahw32(x) ___swahw32(x) +#endif +#ifndef __arch__swahb32 +# define __arch__swahb32(x) ___swahb32(x) +#endif + +#ifndef __arch__swahw32p +# define __arch__swahw32p(x) __swahw32(*(x)) +#endif +#ifndef __arch__swahb32p +# define __arch__swahb32p(x) __swahb32(*(x)) +#endif + +#ifndef __arch__swahw32s +# define __arch__swahw32s(x) do { *(x) = __swahw32p((x)); } while (0) +#endif +#ifndef __arch__swahb32s +# define __arch__swahb32s(x) do { *(x) = __swahb32p((x)); } while (0) +#endif + + +/* + * Allow constant folding + */ +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) +# define __swahw32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swahw32((x)) : \ + __fswahw32((x))) +# define __swahb32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swahb32((x)) : \ + __fswahb32((x))) +#else +# define __swahw32(x) __fswahw32(x) +# define __swahb32(x) __fswahb32(x) +#endif /* OPTIMIZE */ + + +__inline static__ __const__ __u32 __fswahw32(__u32 x) +{ + return __arch__swahw32(x); +} +__inline static__ __u32 __swahw32p(__u32 *x) +{ + return __arch__swahw32p(x); +} +__inline static__ void __swahw32s(__u32 *addr) +{ + __arch__swahw32s(addr); +} + + +__inline static__ __const__ __u32 __fswahb32(__u32 x) +{ + return __arch__swahb32(x); +} +__inline static__ __u32 __swahb32p(__u32 *x) +{ + return __arch__swahb32p(x); +} +__inline static__ void __swahb32s(__u32 *addr) +{ + __arch__swahb32s(addr); +} + +#ifdef __BYTEORDER_HAS_U64__ +/* + * Not supported yet + */ +#endif /* __BYTEORDER_HAS_U64__ */ + +#if defined(PLATFORM_LINUX) +#define swahw32 __swahw32 +#define swahb32 __swahb32 +#define swahw32p __swahw32p +#define swahb32p __swahb32p +#define swahw32s __swahw32s +#define swahb32s __swahb32s +#endif + +#endif /* _LINUX_BYTEORDER_SWABB_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/circ_buf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/circ_buf.h new file mode 100644 index 00000000..23523164 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/circ_buf.h @@ -0,0 +1,28 @@ +/****************************************************************************** + * + * 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 __CIRC_BUF_H_ +#define __CIRC_BUF_H_ 1 + +#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1)) + +#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size)) + +#endif //_CIRC_BUF_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/cmd_osdep.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/cmd_osdep.h new file mode 100644 index 00000000..65a7253b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/cmd_osdep.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 __CMD_OSDEP_H_ +#define __CMD_OSDEP_H_ + + +extern sint _rtw_init_cmd_priv (struct cmd_priv *pcmdpriv); +extern sint _rtw_init_evt_priv(struct evt_priv *pevtpriv); +extern void _rtw_free_evt_priv (struct evt_priv *pevtpriv); +extern void _rtw_free_cmd_priv (struct cmd_priv *pcmdpriv); +extern sint _rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj, bool to_head); +extern struct cmd_obj *_rtw_dequeue_cmd(_queue *queue); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/custom_gpio.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/custom_gpio.h new file mode 100644 index 00000000..c76b340f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/custom_gpio.h @@ -0,0 +1,32 @@ +#ifndef __CUSTOM_GPIO_H__ +#define __CUSTOM_GPIO_H___ + +#include +#include + +#ifdef PLATFORM_OS_XP +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#ifdef PLATFORM_LINUX +#include +#endif + +typedef enum cust_gpio_modes { + WLAN_PWDN_ON, + WLAN_PWDN_OFF, + WLAN_POWER_ON, + WLAN_POWER_OFF, + WLAN_BT_PWDN_ON, + WLAN_BT_PWDN_OFF +} cust_gpio_modes_t; + +extern int rtw_wifi_gpio_init(void); +extern int rtw_wifi_gpio_deinit(void); +extern void rtw_wifi_gpio_wlan_ctrl(int onoff); + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_conf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_conf.h new file mode 100644 index 00000000..467862ef --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_conf.h @@ -0,0 +1,201 @@ +/****************************************************************************** + * + * 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 __DRV_CONF_H__ +#define __DRV_CONF_H__ +#include "autoconf.h" +#include "hal_ic_cfg.h" + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +//Older Android kernel doesn't has CONFIG_ANDROID defined, +//add this to force CONFIG_ANDROID defined +#ifdef CONFIG_PLATFORM_ANDROID +#ifndef CONFIG_ANDROID +#define CONFIG_ANDROID +#endif +#endif + +#ifdef CONFIG_ANDROID +//Some Android build will restart the UI while non-printable ascii is passed +//between java and c/c++ layer (JNI). We force CONFIG_VALIDATE_SSID +//for Android here. If you are sure there is no risk on your system about this, +//mask this macro define to support non-printable ascii ssid. +//#define CONFIG_VALIDATE_SSID + +//Android expect dbm as the rx signal strength unit +#define CONFIG_SIGNAL_DISPLAY_DBM +#endif + +/* +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_HAS_EARLYSUSPEND enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif + +#if defined(CONFIG_ANDROID_POWER) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_ANDROID_POWER enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif +*/ + +#ifdef CONFIG_RESUME_IN_WORKQUEUE //this can be removed, because there is no case for this... + #if !defined( CONFIG_WAKELOCK) && !defined(CONFIG_ANDROID_POWER) + #error "enable CONFIG_RESUME_IN_WORKQUEUE without CONFIG_WAKELOCK or CONFIG_ANDROID_POWER will suffer from the danger of wifi's unfunctionality..." + #error "If you still want to enable CONFIG_RESUME_IN_WORKQUEUE in this case, mask this preprossor checking and GOOD LUCK..." + #endif +#endif + +//About USB VENDOR REQ +#if defined(CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif +#if defined(CONFIG_VENDOR_REQ_RETRY) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_VENDOR_REQ_RETRY automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif + +#if !defined(CONFIG_AP_MODE) && defined(CONFIG_DFS_MASTER) + #warning "undef CONFIG_DFS_MASTER because CONFIG_AP_MODE is not defined" + #undef CONFIG_DFS_MASTER +#endif + +#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 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_MODE + #define CONFIG_RTW_ADAPTIVITY_MODE 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_DML + #define CONFIG_RTW_ADAPTIVITY_DML 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_DC_BACKOFF + #define CONFIG_RTW_ADAPTIVITY_DC_BACKOFF 2 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_TH_L2H_INI + #define CONFIG_RTW_ADAPTIVITY_TH_L2H_INI 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_TH_EDCCA_HL_DIFF + #define CONFIG_RTW_ADAPTIVITY_TH_EDCCA_HL_DIFF 0 +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_2G_A + #define CONFIG_RTW_TARGET_TX_PWR_2G_A {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_2G_B + #define CONFIG_RTW_TARGET_TX_PWR_2G_B {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_2G_C + #define CONFIG_RTW_TARGET_TX_PWR_2G_C {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_2G_D + #define CONFIG_RTW_TARGET_TX_PWR_2G_D {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_5G_A + #define CONFIG_RTW_TARGET_TX_PWR_5G_A {-1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_5G_B + #define CONFIG_RTW_TARGET_TX_PWR_5G_B {-1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_5G_C + #define CONFIG_RTW_TARGET_TX_PWR_5G_C {-1, -1, -1, -1, -1, -1, -1, -1, -1} +#endif + +#ifndef CONFIG_RTW_TARGET_TX_PWR_5G_D + #define CONFIG_RTW_TARGET_TX_PWR_5G_D {-1, -1, -1, -1, -1, -1, -1, -1, -1} +#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 + +#ifndef CONFIG_RTW_RFE_TYPE + #define CONFIG_RTW_RFE_TYPE 64 +#endif + +#ifndef CONFIG_RTW_GLNA_TYPE + #define CONFIG_RTW_GLNA_TYPE 0 +#endif + +#ifndef CONFIG_RTW_PLL_REF_CLK_SEL + #define CONFIG_RTW_PLL_REF_CLK_SEL 0x0F +#endif + +#define MACID_NUM_SW_LIMIT 32 +#define SEC_CAM_ENT_NUM_SW_LIMIT 32 + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) + #define CONFIG_IEEE80211_BAND_5GHZ +#endif + +#ifndef RTW_DEF_MODULE_REGULATORY_CERT + #define RTW_DEF_MODULE_REGULATORY_CERT 0 +#endif + +#if RTW_DEF_MODULE_REGULATORY_CERT + /* force enable TX power by rate and TX power limit */ + #ifndef CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY + #define CONFIG_CALIBRATE_TX_POWER_BY_REGULATORY + #endif +#endif + +/* + Mark CONFIG_DEAUTH_BEFORE_CONNECT by Arvin 2015/07/20 + If the failure of Wi-Fi connection is due to some irregular disconnection behavior (like unplug dongle, + power down etc.) in last time, we can unmark this flag to avoid some unpredictable response from AP. +*/ +/*#define CONFIG_DEAUTH_BEFORE_CONNECT */ + +/*#define CONFIG_WEXT_DONT_JOIN_BYSSID */ +//#include + + +/*#define CONFIG_DOSCAN_IN_BUSYTRAFFIC */ + +#endif // __DRV_CONF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types.h new file mode 100644 index 00000000..701eecf4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types.h @@ -0,0 +1,1304 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +/*------------------------------------------------------------------------------- + + For type defines and data structure defines + +--------------------------------------------------------------------------------*/ + + +#ifndef __DRV_TYPES_H__ +#define __DRV_TYPES_H__ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ARP_KEEP_ALIVE +#include +#include +#endif + +#ifdef PLATFORM_OS_XP +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#ifdef PLATFORM_LINUX +#include +#endif + +enum _NIC_VERSION { + + RTL8711_NIC, + RTL8712_NIC, + RTL8713_NIC, + RTL8716_NIC + +}; + +typedef struct _ADAPTER _adapter, ADAPTER,*PADAPTER; + +#include +#include + +#ifdef CONFIG_80211N_HT +#include +#endif + +#ifdef CONFIG_80211AC_VHT +#include +#endif + +#ifdef CONFIG_INTEL_WIDI +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_BEAMFORMING +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "../hal/hal_dm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER +#include +#endif + +#include + +#ifdef CONFIG_TDLS +#include +#endif // CONFIG_TDLS + +#ifdef CONFIG_WAPI_SUPPORT +#include +#endif // CONFIG_WAPI_SUPPORT + +#ifdef CONFIG_DRVEXT_MODULE +#include +#endif // CONFIG_DRVEXT_MODULE + +#ifdef CONFIG_MP_INCLUDED +#include +#endif // CONFIG_MP_INCLUDED + +#ifdef CONFIG_BR_EXT +#include +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_IOL +#include +#endif // CONFIG_IOL + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_BT_COEXIST +#include +#endif // CONFIG_BT_COEXIST + +#define SPEC_DEV_ID_NONE BIT(0) +#define SPEC_DEV_ID_DISABLE_HT BIT(1) +#define SPEC_DEV_ID_ENABLE_PS BIT(2) +#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3) +#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4) +#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5) + +struct specific_device_id{ + + u32 flags; + + u16 idVendor; + u16 idProduct; + +}; + +struct registry_priv +{ + u8 chip_version; + u8 rfintfs; + u8 lbkmode; + u8 hci; + NDIS_802_11_SSID ssid; + u8 network_mode; //infra, ad-hoc, auto + u8 channel;//ad-hoc support requirement + u8 wireless_mode;//A, B, G, auto + u8 scan_mode;//active, passive + u8 radio_enable; + u8 preamble;//long, short, auto + u8 vrtl_carrier_sense;//Enable, Disable, Auto + u8 vcs_type;//RTS/CTS, CTS-to-self + u16 rts_thresh; + u16 frag_thresh; + u8 adhoc_tx_pwr; + u8 soft_ap; + u8 power_mgnt; + u8 ips_mode; + u8 smart_ps; + u8 usb_rxagg_mode; + u8 long_retry_lmt; + u8 short_retry_lmt; + u16 busy_thresh; + u8 ack_policy; + u8 mp_mode; + u8 mp_dm; + u8 software_encrypt; + u8 software_decrypt; + #ifdef CONFIG_TX_EARLY_MODE + u8 early_mode; + #endif + u8 acm_method; + //UAPSD + u8 wmm_enable; + u8 uapsd_enable; + u8 uapsd_max_sp; + u8 uapsd_acbk_en; + u8 uapsd_acbe_en; + u8 uapsd_acvi_en; + u8 uapsd_acvo_en; + + WLAN_BSSID_EX dev_network; + +#ifdef CONFIG_80211N_HT + u8 ht_enable; + // 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz + // 2.4G use bit 0 ~ 3, 5G use bit 4 ~ 7 + // 0x21 means enable 2.4G 40MHz & 5G 80MHz + u8 bw_mode; + u8 ampdu_enable;//for tx + u8 rx_stbc; + u8 ampdu_amsdu;//A-MPDU Supports A-MSDU is permitted + // Short GI support Bit Map + // BIT0 - 20MHz, 1: support, 0: non-support + // BIT1 - 40MHz, 1: support, 0: non-support + // BIT2 - 80MHz, 1: support, 0: non-support + // BIT3 - 160MHz, 1: support, 0: non-support + u8 short_gi; + // BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx + u8 ldpc_cap; + // BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx + u8 stbc_cap; + // BIT0: Enable VHT Beamformer, BIT1: Enable VHT Beamformee, BIT4: Enable HT Beamformer, BIT5: Enable HT Beamformee + u8 beamform_cap; + u8 beamformer_rf_num; + u8 beamformee_rf_num; +#endif //CONFIG_80211N_HT + +#ifdef CONFIG_80211AC_VHT + u8 vht_enable; //0:disable, 1:enable, 2:auto + u8 ampdu_factor; + u8 vht_rate_sel; +#endif //CONFIG_80211AC_VHT + + u8 lowrate_two_xmit; + + u8 rf_config ; + u8 low_power ; + + u8 wifi_spec;// !turbo_mode + u8 special_rf_path; // 0: 2T2R ,1: only turn on path A 1T1R + char alpha2[2]; + u8 channel_plan; + u8 full_ch_in_p2p_handshake; /* 0: reply only softap channel, 1: reply full channel list*/ +#ifdef CONFIG_BT_COEXIST + u8 btcoex; + u8 bt_iso; + u8 bt_sco; + u8 bt_ampdu; + s8 ant_num; +#endif + BOOLEAN bAcceptAddbaReq; + + u8 antdiv_cfg; + u8 antdiv_type; + + u8 switch_usb3; + + u8 usbss_enable;//0:disable,1:enable + u8 hwpdn_mode;//0:disable,1:enable,2:decide by EFUSE config + u8 hwpwrp_detect;//0:disable,1:enable + + u8 hw_wps_pbc;//0:disable,1:enable + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + char adaptor_info_caching_file_path[PATH_LENGTH_MAX]; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + u8 max_roaming_times; // the max number driver will try to roaming +#endif + +#ifdef CONFIG_IOL + u8 fw_iol; //enable iol without other concern +#endif + +#ifdef CONFIG_80211D + u8 enable80211d; +#endif + + u8 ifname[16]; + u8 if2name[16]; + + u8 notch_filter; + +#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + u8 force_ant;//0 normal,1 main,2 aux + u8 force_igi;//0 normal +#endif + + /* for pll reference clock selction */ + u8 pll_ref_clk_sel; + + //define for tx power adjust + u8 RegEnableTxPowerLimit; + u8 RegEnableTxPowerByRate; + u8 RegPowerBase; + u8 RegPwrTblSel; + + u8 target_tx_pwr_valid; + s8 target_tx_pwr_2g[RF_PATH_MAX][RATE_SECTION_NUM]; +#ifdef CONFIG_IEEE80211_BAND_5GHZ + s8 target_tx_pwr_5g[RF_PATH_MAX][RATE_SECTION_NUM - 1]; +#endif + + s8 TxBBSwing_2G; + s8 TxBBSwing_5G; + u8 AmplifierType_2G; + u8 AmplifierType_5G; + u8 bEn_RFE; + u8 RFE_Type; + u8 GLNA_Type; + u8 check_fw_ps; + u8 RegRfKFreeEnable; + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + u8 load_phy_file; + u8 RegDecryptCustomFile; +#endif + +#ifdef CONFIG_MULTI_VIR_IFACES + u8 ext_iface_num;//primary/secondary iface is excluded +#endif + u8 qos_opt_enable; + + u8 hiq_filter; + u8 adaptivity_en; + u8 adaptivity_mode; + u8 adaptivity_dml; + u8 adaptivity_dc_backoff; + s8 adaptivity_th_l2h_ini; + s8 adaptivity_th_edcca_hl_diff; + + u8 boffefusemask; + BOOLEAN bFileMaskEfuse; +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + u8 acs_mode; + u8 acs_auto_scan; +#endif + u32 reg_rxgain_offset_2g; + u32 reg_rxgain_offset_5gl; + u32 reg_rxgain_offset_5gm; + u32 reg_rxgain_offset_5gh; +}; + +//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 GetRegGLNAType(_Adapter) (_Adapter->registrypriv.GLNA_Type) + +#define BSSID_OFT(field) ((ULONG)FIELD_OFFSET(WLAN_BSSID_EX,field)) +#define BSSID_SZ(field) sizeof(((PWLAN_BSSID_EX) 0)->field) + +#define REGSTY_BW_2G(regsty) ((regsty)->bw_mode & 0x0F) +#define REGSTY_BW_5G(regsty) (((regsty)->bw_mode) >> 4) +#define REGSTY_IS_BW_2G_SUPPORT(regsty, bw) (REGSTY_BW_2G((regsty)) >= (bw)) +#define REGSTY_IS_BW_5G_SUPPORT(regsty, bw) (REGSTY_BW_5G((regsty)) >= (bw)) + +#ifdef CONFIG_SDIO_HCI +#include +#define INTF_DATA SDIO_DATA +#elif defined(CONFIG_GSPI_HCI) +#include +#define INTF_DATA GSPI_DATA +#elif defined(CONFIG_PCI_HCI) +#include +#endif + +#ifdef CONFIG_CONCURRENT_MODE +#define is_primary_adapter(adapter) (adapter->adapter_type == PRIMARY_ADAPTER) +#define is_vir_adapter(adapter) (adapter->adapter_type == MAX_ADAPTER) +#define get_iface_type(adapter) (adapter->iface_type) +#else +#define is_primary_adapter(adapter) (1) +#define is_vir_adapter(adapter) (0) +#define get_iface_type(adapter) (IFACE_PORT0) +#endif +#define GET_PRIMARY_ADAPTER(padapter) (((_adapter *)padapter)->dvobj->padapters[IFACE_ID0]) +#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 + IFACE_ID2, + IFACE_ID3, + IFACE_ID_MAX, +}; + +#ifdef CONFIG_DBG_COUNTER + +struct rx_logs { + u32 intf_rx; + u32 intf_rx_err_recvframe; + u32 intf_rx_err_skb; + u32 intf_rx_report; + u32 core_rx; + u32 core_rx_pre; + u32 core_rx_pre_ver_err; + u32 core_rx_pre_mgmt; + u32 core_rx_pre_mgmt_err_80211w; + u32 core_rx_pre_mgmt_err; + u32 core_rx_pre_ctrl; + u32 core_rx_pre_ctrl_err; + u32 core_rx_pre_data; + u32 core_rx_pre_data_wapi_seq_err; + u32 core_rx_pre_data_wapi_key_err; + u32 core_rx_pre_data_handled; + u32 core_rx_pre_data_err; + u32 core_rx_pre_data_unknown; + u32 core_rx_pre_unknown; + u32 core_rx_enqueue; + u32 core_rx_dequeue; + u32 core_rx_post; + u32 core_rx_post_decrypt; + u32 core_rx_post_decrypt_wep; + u32 core_rx_post_decrypt_tkip; + u32 core_rx_post_decrypt_aes; + u32 core_rx_post_decrypt_wapi; + u32 core_rx_post_decrypt_hw; + u32 core_rx_post_decrypt_unknown; + u32 core_rx_post_decrypt_err; + u32 core_rx_post_defrag_err; + u32 core_rx_post_portctrl_err; + u32 core_rx_post_indicate; + u32 core_rx_post_indicate_in_oder; + u32 core_rx_post_indicate_reoder; + u32 core_rx_post_indicate_err; + u32 os_indicate; + u32 os_indicate_ap_mcast; + u32 os_indicate_ap_forward; + u32 os_indicate_ap_self; + u32 os_indicate_err; + u32 os_netif_ok; + u32 os_netif_err; +}; + +struct tx_logs { + u32 os_tx; + u32 os_tx_err_up; + u32 os_tx_err_xmit; + u32 os_tx_m2u; + u32 os_tx_m2u_ignore_fw_linked; + u32 os_tx_m2u_ignore_self; + u32 os_tx_m2u_entry; + u32 os_tx_m2u_entry_err_xmit; + u32 os_tx_m2u_entry_err_skb; + u32 os_tx_m2u_stop; + u32 core_tx; + u32 core_tx_err_pxmitframe; + u32 core_tx_err_brtx; + u32 core_tx_upd_attrib; + u32 core_tx_upd_attrib_adhoc; + u32 core_tx_upd_attrib_sta; + u32 core_tx_upd_attrib_ap; + u32 core_tx_upd_attrib_unknown; + u32 core_tx_upd_attrib_dhcp; + u32 core_tx_upd_attrib_icmp; + u32 core_tx_upd_attrib_active; + u32 core_tx_upd_attrib_err_ucast_sta; + u32 core_tx_upd_attrib_err_ucast_ap_link; + u32 core_tx_upd_attrib_err_sta; + u32 core_tx_upd_attrib_err_link; + u32 core_tx_upd_attrib_err_sec; + u32 core_tx_ap_enqueue_warn_fwstate; + u32 core_tx_ap_enqueue_warn_sta; + u32 core_tx_ap_enqueue_warn_nosta; + u32 core_tx_ap_enqueue_warn_link; + u32 core_tx_ap_enqueue_warn_trigger; + u32 core_tx_ap_enqueue_mcast; + u32 core_tx_ap_enqueue_ucast; + u32 core_tx_ap_enqueue; + u32 intf_tx; + u32 intf_tx_pending_ac; + u32 intf_tx_pending_fw_under_survey; + u32 intf_tx_pending_fw_under_linking; + u32 intf_tx_pending_xmitbuf; + u32 intf_tx_enqueue; + u32 core_tx_enqueue; + u32 core_tx_enqueue_class; + u32 core_tx_enqueue_class_err_sta; + u32 core_tx_enqueue_class_err_nosta; + u32 core_tx_enqueue_class_err_fwlink; + u32 intf_tx_direct; + u32 intf_tx_direct_err_coalesce; + u32 intf_tx_dequeue; + u32 intf_tx_dequeue_err_coalesce; + u32 intf_tx_dump_xframe; + u32 intf_tx_dump_xframe_err_txdesc; + u32 intf_tx_dump_xframe_err_port; +}; + +struct int_logs { + u32 all; + u32 err; + u32 tbdok; + u32 tbder; + u32 bcnderr; + u32 bcndma; + u32 bcndma_e; + u32 rx; + u32 rx_rdu; + u32 rx_fovw; + u32 txfovw; + u32 mgntok; + u32 highdok; + u32 bkdok; + u32 bedok; + u32 vidok; + u32 vodok; +}; + +#endif // CONFIG_DBG_COUNTER + +struct debug_priv { + u32 dbg_sdio_free_irq_error_cnt; + u32 dbg_sdio_alloc_irq_error_cnt; + u32 dbg_sdio_free_irq_cnt; + u32 dbg_sdio_alloc_irq_cnt; + u32 dbg_sdio_deinit_error_cnt; + u32 dbg_sdio_init_error_cnt; + u32 dbg_suspend_error_cnt; + u32 dbg_suspend_cnt; + u32 dbg_resume_cnt; + u32 dbg_resume_error_cnt; + u32 dbg_deinit_fail_cnt; + u32 dbg_carddisable_cnt; + u32 dbg_carddisable_error_cnt; + u32 dbg_ps_insuspend_cnt; + u32 dbg_dev_unload_inIPS_cnt; + u32 dbg_wow_leave_ps_fail_cnt; + u32 dbg_scan_pwr_state_cnt; + u32 dbg_downloadfw_pwr_state_cnt; + u32 dbg_fw_read_ps_state_fail_cnt; + u32 dbg_leave_ips_fail_cnt; + u32 dbg_leave_lps_fail_cnt; + u32 dbg_h2c_leave32k_fail_cnt; + u32 dbg_diswow_dload_fw_fail_cnt; + u32 dbg_enwow_dload_fw_fail_cnt; + u32 dbg_ips_drvopen_fail_cnt; + u32 dbg_poll_fail_cnt; + u32 dbg_rpwm_toogle_cnt; + u32 dbg_rpwm_timeout_fail_cnt; + u32 dbg_sreset_cnt; + u64 dbg_rx_fifo_last_overflow; + u64 dbg_rx_fifo_curr_overflow; + u64 dbg_rx_fifo_diff_overflow; + u64 dbg_rx_ampdu_drop_count; + u64 dbg_rx_ampdu_forced_indicate_count; + u64 dbg_rx_ampdu_loss_count; + u64 dbg_rx_dup_mgt_frame_drop_count; + u64 dbg_rx_ampdu_window_shift_cnt; + u64 dbg_rx_conflic_mac_addr_cnt; +}; + +struct rtw_traffic_statistics { + // tx statistics + u64 tx_bytes; + u64 tx_pkts; + u64 tx_drop; + u64 cur_tx_bytes; + u64 last_tx_bytes; + u32 cur_tx_tp; // Tx throughput in MBps. + + // rx statistics + u64 rx_bytes; + u64 rx_pkts; + u64 rx_drop; + u64 cur_rx_bytes; + u64 last_rx_bytes; + u32 cur_rx_tp; // Rx throughput in MBps. +}; + +#define SEC_CAP_CHK_BMC BIT0 + +#define SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH BIT0 + +struct sec_cam_bmp { + u32 m0; +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 32) + u32 m1; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 64) + u32 m2; +#endif +#if (SEC_CAM_ENT_NUM_SW_LIMIT > 96) + u32 m3; +#endif +}; + +struct cam_ctl_t { + _lock lock; + + u8 sec_cap; + u32 flags; + + u8 num; + struct sec_cam_bmp used; + + _mutex sec_cam_access_mutex; +}; + +struct sec_cam_ent { + u16 ctrl; + u8 mac[ETH_ALEN]; + u8 key[16]; +}; + +#define KEY_FMT "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" +#define KEY_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] + +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 */ + u8 h2c_msr[MACID_NUM_SW_LIMIT]; + struct sta_info *sta[MACID_NUM_SW_LIMIT]; +}; + +struct rf_ctl_t { + #ifdef CONFIG_DFS_MASTER + bool radar_detect_by_sta_link; + bool pre_radar_detect_by_sta_link; + bool dfs_master_enabled; + + u8 radar_detect_ch; + u8 radar_detect_bw; + u8 radar_detect_offset; + u8 pre_radar_detect_ch; + u8 pre_radar_detect_bw; + u8 pre_radar_detect_offset; + + u32 cac_end_time; + + u8 dbg_dfs_master_fake_radar_detect_cnt; + u8 dbg_dfs_master_radar_detect_trigger_non; + u8 dbg_dfs_master_choose_dfs_ch_first; + #endif +}; + +#define RTW_CAC_STOPPED 0 +#define IS_UNDER_CAC(rfctl) ((rfctl)->cac_end_time > rtw_get_current_time()) +#define IS_CAC_STOPPED(rfctl) ((rfctl)->cac_end_time == RTW_CAC_STOPPED) + +struct dvobj_priv +{ + /*-------- below is common data --------*/ + u8 chip_type; + u8 HardwareType; + u8 interface_type;/*USB,SDIO,SPI,PCI*/ + + ATOMIC_T bSurpriseRemoved; + ATOMIC_T bDriverStopped; + + s32 processing_dev_remove; + + struct debug_priv drv_dbg; + + _mutex hw_init_mutex; + _mutex h2c_fwcmd_mutex; + _mutex setch_mutex; + _mutex setbw_mutex; +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + _mutex sd_indirect_access_mutex; +#endif + + unsigned char oper_channel; //saved channel info when call set_channel_bw + unsigned char oper_bwmode; + unsigned char oper_ch_offset;//PRIME_CHNL_OFFSET + u32 on_oper_ch_time; + + //extend to support mulitu interface + /*padapters[IFACE_ID0] == if1 - PRIMARY_ADAPTER*/ + /*padapters[IFACE_ID1] == if2 - SECONDARY_ADAPTER*/ + _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 sec_cam_ent cam_cache[SEC_CAM_ENT_NUM_SW_LIMIT]; + + struct rf_ctl_t rf_ctl; + + //For 92D, DMDP have 2 interface. + u8 InterfaceNumber; + u8 NumInterfaces; + + //In /Out Pipe information + int RtInPipe[2]; + int RtOutPipe[4]; + u8 Queue2Pipe[HW_QUEUE_ENTRY];//for out pipe mapping + + u8 irq_alloc; + ATOMIC_T continual_io_error; + + ATOMIC_T disable_func; + + struct pwrctrl_priv pwrctl_priv; + + struct rtw_traffic_statistics traffic_stat; + +#if defined(CONFIG_IOCTL_CFG80211) && defined(RTW_SINGLE_WIPHY) + struct wiphy *wiphy; +#endif + +/*-------- below is for SDIO INTERFACE --------*/ + +#ifdef INTF_DATA + INTF_DATA intf_data; +#endif + +/*-------- below is for USB INTERFACE --------*/ + +#ifdef CONFIG_USB_HCI + + u8 usb_speed; // 1.1, 2.0 or 3.0 + u8 nr_endpoint; + u8 RtNumInPipes; + u8 RtNumOutPipes; + int ep_num[6]; //endpoint number + + int RegUsbSS; + + _sema usb_suspend_sema; + +#ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _mutex usb_vendor_req_mutex; +#endif + +#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + u8 * usb_alloc_vendor_req_buf; + u8 * usb_vendor_req_buf; +#endif + +#ifdef PLATFORM_WINDOWS + //related device objects + PDEVICE_OBJECT pphysdevobj;//pPhysDevObj; + PDEVICE_OBJECT pfuncdevobj;//pFuncDevObj; + PDEVICE_OBJECT pnextdevobj;//pNextDevObj; + + u8 nextdevstacksz;//unsigned char NextDeviceStackSize; //= (CHAR)CEdevice->pUsbDevObj->StackSize + 1; + + //urb for control diescriptor request + +#ifdef PLATFORM_OS_XP + struct _URB_CONTROL_DESCRIPTOR_REQUEST descriptor_urb; + PUSB_CONFIGURATION_DESCRIPTOR pconfig_descriptor;//UsbConfigurationDescriptor; +#endif + +#ifdef PLATFORM_OS_CE + WCHAR active_path[MAX_ACTIVE_REG_PATH]; // adapter regpath + USB_EXTENSION usb_extension; + + _nic_hdl pipehdls_r8192c[0x10]; +#endif + + u32 config_descriptor_len;//ULONG UsbConfigurationDescriptorLength; +#endif//PLATFORM_WINDOWS + +#ifdef PLATFORM_LINUX + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_FREEBSD + +#endif//CONFIG_USB_HCI + +/*-------- below is for PCIE INTERFACE --------*/ + +#ifdef CONFIG_PCI_HCI + +#ifdef PLATFORM_LINUX + struct pci_dev *ppcidev; + + //PCI MEM map + unsigned long pci_mem_end; /* shared mem end */ + unsigned long pci_mem_start; /* shared mem start */ + + //PCI IO map + unsigned long pci_base_addr; /* device I/O address */ + + //PciBridge + struct pci_priv pcipriv; + + unsigned int irq; /* get from pci_dev.irq, store to net_device.irq */ + u16 irqline; + u8 irq_enabled; + RT_ISR_CONTENT isr_content; + _lock irq_th_lock; + + //ASPM + u8 const_pci_aspm; + u8 const_amdpci_aspm; + u8 const_hwsw_rfoff_d3; + u8 const_support_pciaspm; + // pci-e bridge */ + u8 const_hostpci_aspm_setting; + // pci-e device */ + u8 const_devicepci_aspm_setting; + u8 b_support_aspm; // If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. + u8 b_support_backdoor; + u8 bdma64; +#endif//PLATFORM_LINUX + +#endif//CONFIG_PCI_HCI +}; + +#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->padapters[IFACE_ID0]->registrypriv)) +#if defined(CONFIG_IOCTL_CFG80211) && defined(RTW_SINGLE_WIPHY) +#define dvobj_to_wiphy(dvobj) ((dvobj)->wiphy) +#endif +#define dvobj_to_rfctl(dvobj) (&(dvobj->rf_ctl)) +#define rfctl_to_dvobj(rfctl) container_of((rfctl), struct dvobj_priv, rf_ctl) + +#ifdef PLATFORM_LINUX +static struct device *dvobj_to_dev(struct dvobj_priv *dvobj) +{ + /* todo: get interface type from dvobj and the return the dev accordingly */ +#ifdef RTW_DVOBJ_CHIP_HW_TYPE +#endif + +#ifdef CONFIG_USB_HCI + return &dvobj->pusbintf->dev; +#endif +#ifdef CONFIG_SDIO_HCI + return &dvobj->intf_data.func->dev; +#endif +#ifdef CONFIG_GSPI_HCI + return &dvobj->intf_data.func->dev; +#endif +#ifdef CONFIG_PCI_HCI + return &dvobj->ppcidev->dev; +#endif +} +#endif + +_adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj); + +enum _IFACE_TYPE { + IFACE_PORT0, //mapping to port0 for C/D series chips + IFACE_PORT1, //mapping to port1 for C/D series chip + MAX_IFACE_PORT, +}; + +enum _ADAPTER_TYPE { + PRIMARY_ADAPTER, + SECONDARY_ADAPTER, + MAX_ADAPTER = 0xFF, +}; + +typedef enum _DRIVER_STATE{ + DRIVER_NORMAL = 0, + DRIVER_DISAPPEAR = 1, + DRIVER_REPLACE_DONGLE = 2, +}DRIVER_STATE; + +#ifdef CONFIG_INTEL_PROXIM +struct proxim { + bool proxim_support; + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(_adapter *padapter, + union recv_frame *precv_frame); + u8 (*proxim_get_var)(_adapter* padapter, u8 type); +}; +#endif //CONFIG_INTEL_PROXIM + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER +typedef struct loopbackdata +{ + _sema sema; + _thread_hdl_ lbkthread; + u8 bstop; + u32 cnt; + u16 size; + u16 txsize; + u8 txbuf[0x8000]; + u16 rxsize; + u8 rxbuf[0x8000]; + u8 msg[100]; + +}LOOPBACKDATA, *PLOOPBACKDATA; +#endif + +struct _ADAPTER{ + int DriverState;// for disable driver using module, use dongle to replace module. + int pid[3];//process id from UI, 0:wps, 1:hostapd, 2:dhcpcd + int bDongle;//build-in module or external dongle + + struct dvobj_priv *dvobj; + struct mlme_priv mlmepriv; + struct mlme_ext_priv mlmeextpriv; + struct cmd_priv cmdpriv; + struct evt_priv evtpriv; + //struct io_queue *pio_queue; + struct io_priv iopriv; + struct xmit_priv xmitpriv; + struct recv_priv recvpriv; + struct sta_priv stapriv; + struct security_priv securitypriv; + _lock security_key_mutex; // add for CONFIG_IEEE80211W, none 11w also can use + struct registry_priv registrypriv; + + struct led_priv ledpriv; + +#ifdef CONFIG_MP_INCLUDED + struct mp_priv mppriv; +#endif + +#ifdef CONFIG_DRVEXT_MODULE + struct drvext_priv drvextpriv; +#endif + +#ifdef CONFIG_AP_MODE + struct hostapd_priv *phostapdpriv; +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P + struct cfg80211_wifidirect_info cfg80211_wdinfo; +#endif //CONFIG_P2P +#endif //CONFIG_IOCTL_CFG80211 + u32 setband; +#ifdef CONFIG_P2P + struct wifidirect_info wdinfo; +#endif //CONFIG_P2P + +#ifdef CONFIG_TDLS + struct tdls_info tdlsinfo; +#endif //CONFIG_TDLS + +#ifdef CONFIG_WAPI_SUPPORT + u8 WapiSupport; + RT_WAPI_T wapiInfo; +#endif + + +#ifdef CONFIG_WFD + struct wifi_display_info wfd_info; +#endif //CONFIG_WFD + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + struct bt_coex_info coex_info; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + ERROR_CODE LastError; /* <20130613, Kordan> Only the functions associated with MP records the error code by now. */ + + PVOID HalData; + u32 hal_data_sz; + struct hal_ops HalFunc; + + u32 IsrContent; + u32 ImrContent; + + u8 EepromAddressSize; + u8 bDriverIsGoingToUnload; + u8 init_adpt_in_progress; + u8 bHaltInProgress; +#ifdef CONFIG_GPIO_API + u8 pre_gpio_pin; + struct gpio_int_priv { + u8 interrupt_mode; + u8 interrupt_enable_mask; + void (*callback[8])(u8 level); + }gpiointpriv; +#endif + _thread_hdl_ cmdThread; + _thread_hdl_ evtThread; + _thread_hdl_ xmitThread; + _thread_hdl_ recvThread; + +#ifndef PLATFORM_LINUX + NDIS_STATUS (*dvobj_init)(struct dvobj_priv *dvobj); + void (*dvobj_deinit)(struct dvobj_priv *dvobj); +#endif + + u32 (*intf_init)(struct dvobj_priv *dvobj); + void (*intf_deinit)(struct dvobj_priv *dvobj); + int (*intf_alloc_irq)(struct dvobj_priv *dvobj); + void (*intf_free_irq)(struct dvobj_priv *dvobj); + + + void (*intf_start)(_adapter * adapter); + void (*intf_stop)(_adapter * adapter); + +#ifdef PLATFORM_WINDOWS + _nic_hdl hndis_adapter;//hNdisAdapter(NDISMiniportAdapterHandle); + _nic_hdl hndis_config;//hNdisConfiguration; + NDIS_STRING fw_img; + + u32 NdisPacketFilter; + u8 MCList[MAX_MCAST_LIST_NUM][6]; + u32 MCAddrCount; +#endif //end of PLATFORM_WINDOWS + + +#ifdef PLATFORM_LINUX + _nic_hdl pnetdev; + char old_ifname[IFNAMSIZ]; + + // used by rtw_rereg_nd_name related function + struct rereg_nd_name_data { + _nic_hdl old_pnetdev; + char old_ifname[IFNAMSIZ]; + u8 old_ips_mode; + u8 old_bRegUseLed; + } rereg_nd_name_priv; + + u8 ndev_unregistering; + int bup; + struct net_device_stats stats; + struct iw_statistics iwstats; + struct proc_dir_entry *dir_dev;// for proc directory + struct proc_dir_entry *dir_odm; + +#ifdef CONFIG_IOCTL_CFG80211 + struct wireless_dev *rtw_wdev; + struct rtw_wdev_priv wdev_data; + + #if !defined(RTW_SINGLE_WIPHY) + struct wiphy *wiphy; + #endif + +#endif /* CONFIG_IOCTL_CFG80211 */ + +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + _nic_hdl pifp; + int bup; + _lock glock; +#endif //PLATFORM_FREEBSD + u8 mac_addr[ETH_ALEN]; + int net_closed; + + u8 netif_up; + + u8 bFWReady; + u8 bBTFWReady; + u8 bLinkInfoDump; + u8 bRxRSSIDisplay; + // Added by Albert 2012/10/26 + // The driver will show up the desired channel number when this flag is 1. + u8 bNotifyChannelChange; +#ifdef CONFIG_P2P + // Added by Albert 2012/12/06 + // The driver will show the current P2P status when the upper application reads it. + u8 bShowGetP2PState; +#endif +#ifdef CONFIG_AUTOSUSPEND + u8 bDisableAutosuspend; +#endif + + //pbuddy_adapter is used only in two inteface case, (iface_nums=2 in struct dvobj_priv) + //PRIMARY_ADAPTER's buddy is SECONDARY_ADAPTER + //SECONDARY_ADAPTER's buddy is PRIMARY_ADAPTER + //for iface_id > SECONDARY_ADAPTER(IFACE_ID1), refer to padapters[iface_id] in struct dvobj_priv + //and their pbuddy_adapter is PRIMARY_ADAPTER. + //for PRIMARY_ADAPTER(IFACE_ID0) can directly refer to if1 in struct dvobj_priv + _adapter *pbuddy_adapter; + +#if defined(CONFIG_CONCURRENT_MODE) + u8 isprimary; //is primary adapter or not + //notes: + // if isprimary is true, the adapter_type value is 0, iface_id is IFACE_ID0 for PRIMARY_ADAPTER + // if isprimary is false, the adapter_type value is 1, iface_id is IFACE_ID1 for SECONDARY_ADAPTER + // refer to iface_id if iface_nums>2 and isprimary is false and the adapter_type value is 0xff. + u8 adapter_type;//used only in two inteface case(PRIMARY_ADAPTER and SECONDARY_ADAPTER) . + u8 iface_type; //interface port type, it depends on HW port +#endif //CONFIG_CONCURRENT_MODE + + //extend to support multi interface + //IFACE_ID0 is equals to PRIMARY_ADAPTER + //IFACE_ID1 is equals to SECONDARY_ADAPTER + u8 iface_id; + +#ifdef CONFIG_BR_EXT + _lock br_ext_lock; + //unsigned int macclone_completed; + struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; + int pppoe_connection_in_progress; + unsigned char pppoe_addr[MACADDRLEN]; + unsigned char scdb_mac[MACADDRLEN]; + unsigned char scdb_ip[4]; + struct nat25_network_db_entry *scdb_entry; + unsigned char br_mac[MACADDRLEN]; + unsigned char br_ip[4]; + + struct br_ext_info ethBrExtInfo; +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_INTEL_PROXIM + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode */ + struct proxim proximity; +#endif //CONFIG_INTEL_PROXIM + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + PLOOPBACKDATA ploopback; +#endif + + //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 driver_rx_ampdu_spacing; //driver control Rx AMPDU Density + u8 fix_rx_ampdu_accept; + u8 fix_rx_ampdu_size; /* 0~127, TODO:consider each sta and each TID */ + unsigned char in_cta_test; +#ifdef DBG_RX_COUNTER_DUMP + u8 dump_rx_cnt_mode;/*BIT0:drv,BIT1:mac,BIT2:phy*/ + u32 drv_rx_cnt_ok; + u32 drv_rx_cnt_crcerror; + u32 drv_rx_cnt_drop; +#endif + +#ifdef CONFIG_DBG_COUNTER + struct rx_logs rx_logs; + struct tx_logs tx_logs; + struct int_logs int_logs; +#endif +}; + +#define adapter_to_dvobj(adapter) ((adapter)->dvobj) +#define adapter_to_regsty(adapter) dvobj_to_regsty(adapter_to_dvobj((adapter))) +#define adapter_to_pwrctl(adapter) dvobj_to_pwrctl(adapter_to_dvobj((adapter))) +#define adapter_wdev_data(adapter) (&((adapter)->wdev_data)) +#if defined(RTW_SINGLE_WIPHY) +#define adapter_to_wiphy(adapter) dvobj_to_wiphy(adapter_to_dvobj(adapter)) +#else +#define adapter_to_wiphy(adapter) ((adapter)->wiphy) +#endif + +#define adapter_to_rfctl(adapter) dvobj_to_rfctl(adapter_to_dvobj((adapter))) + +#define adapter_mac_addr(adapter) (adapter->mac_addr) + +#define mlme_to_adapter(mlme) container_of((mlme), struct _ADAPTER, mlmepriv) +#define tdls_info_to_adapter(tdls) container_of((tdls), struct _ADAPTER, tdlsinfo) + +#define rtw_get_chip_type(adapter) (((PADAPTER)adapter)->dvobj->chip_type) +#define rtw_get_hw_type(adapter) (((PADAPTER)adapter)->dvobj->HardwareType) +#define rtw_get_intf_type(adapter) (((PADAPTER)adapter)->dvobj->interface_type) + +static inline void rtw_set_surprise_removed(_adapter *padapter) +{ + ATOMIC_SET(&adapter_to_dvobj(padapter)->bSurpriseRemoved, _TRUE); +} +static inline void rtw_clr_surprise_removed(_adapter *padapter) +{ + ATOMIC_SET(&adapter_to_dvobj(padapter)->bSurpriseRemoved, _FALSE); +} +static inline void rtw_set_drv_stopped(_adapter *padapter) +{ + ATOMIC_SET(&adapter_to_dvobj(padapter)->bDriverStopped, _TRUE); +} +static inline void rtw_clr_drv_stopped(_adapter *padapter) +{ + ATOMIC_SET(&adapter_to_dvobj(padapter)->bDriverStopped, _FALSE); +} +#define rtw_is_surprise_removed(padapter) (ATOMIC_READ(&adapter_to_dvobj(padapter)->bSurpriseRemoved) == _TRUE) +#define rtw_is_drv_stopped(padapter) (ATOMIC_READ(&adapter_to_dvobj(padapter)->bDriverStopped) == _TRUE) + +// +// Function disabled. +// +#define DF_TX_BIT BIT0 /*write_port_cancel*/ +#define DF_RX_BIT BIT1 /*read_port_cancel*/ +#define DF_IO_BIT BIT2 + +//#define RTW_DISABLE_FUNC(padapter, func) (ATOMIC_ADD(&adapter_to_dvobj(padapter)->disable_func, (func))) +//#define RTW_ENABLE_FUNC(padapter, func) (ATOMIC_SUB(&adapter_to_dvobj(padapter)->disable_func, (func))) +__inline static void RTW_DISABLE_FUNC(_adapter*padapter, int func_bit) +{ + int df = ATOMIC_READ(&adapter_to_dvobj(padapter)->disable_func); + df |= func_bit; + ATOMIC_SET(&adapter_to_dvobj(padapter)->disable_func, df); +} + +__inline static void RTW_ENABLE_FUNC(_adapter*padapter, int func_bit) +{ + int df = ATOMIC_READ(&adapter_to_dvobj(padapter)->disable_func); + df &= ~(func_bit); + ATOMIC_SET(&adapter_to_dvobj(padapter)->disable_func, df); +} + +#define RTW_CANNOT_RUN(padapter) \ + (rtw_is_surprise_removed(padapter) || \ + rtw_is_drv_stopped(padapter)) + +#define RTW_IS_FUNC_DISABLED(padapter, func_bit) (ATOMIC_READ(&adapter_to_dvobj(padapter)->disable_func) & (func_bit)) + +#define RTW_CANNOT_IO(padapter) \ + (rtw_is_surprise_removed(padapter) || \ + RTW_IS_FUNC_DISABLED((padapter), DF_IO_BIT)) + +#define RTW_CANNOT_RX(padapter) \ + (RTW_CANNOT_RUN(padapter) || \ + RTW_IS_FUNC_DISABLED((padapter), DF_RX_BIT)) + +#define RTW_CANNOT_TX(padapter) \ + (RTW_CANNOT_RUN(padapter) || \ + RTW_IS_FUNC_DISABLED((padapter), DF_TX_BIT)) + +#ifdef CONFIG_PNO_SUPPORT +int rtw_parse_ssid_list_tlv(char** list_str, pno_ssid_t* ssid, int max, int *bytes_left); +int rtw_dev_pno_set(struct net_device *net, pno_ssid_t* ssid, int num, + int pno_time, int pno_repeat, int pno_freq_expo_max); +#ifdef CONFIG_PNO_SET_DEBUG +void rtw_dev_pno_debug(struct net_device *net); +#endif //CONFIG_PNO_SET_DEBUG +#endif //CONFIG_PNO_SUPPORT + +#ifdef CONFIG_WOWLAN +int rtw_suspend_wow(_adapter *padapter); +int rtw_resume_process_wow(_adapter *padapter); +#endif + +// HCI Related header file +#ifdef CONFIG_USB_HCI +#include +#include +#include +#endif + +#ifdef CONFIG_SDIO_HCI +#include +#include +#include +#endif + +#ifdef CONFIG_GSPI_HCI +#include +#include +#include +#endif + +#ifdef CONFIG_PCI_HCI +#include +#include +#include +#endif + +#endif //__DRV_TYPES_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_ce.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_ce.h new file mode 100644 index 00000000..b3d35235 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_ce.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_CE_H__ +#define __DRV_TYPES_CE_H__ + +#include +#include + +#include + +#define MAX_ACTIVE_REG_PATH 256 + +#define MAX_MCAST_LIST_NUM 32 + + + +//for ioctl +#define MAKE_DRIVER_VERSION(_MainVer,_MinorVer) ((((u32)(_MainVer))<<16)+_MinorVer) + +#define NIC_HEADER_SIZE 14 //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h +#define NIC_MAX_SEND_PACKETS 10 // max number of send packets the MiniportSendPackets function can accept, can be moved to typedef.h +#define NIC_VENDOR_DRIVER_VERSION MAKE_DRIVER_VERSION(0,001) //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h + +typedef struct _MP_REG_ENTRY +{ + + NDIS_STRING RegName; // variable name text + BOOLEAN bRequired; // 1 -> required, 0 -> optional + + u8 Type; // NdisParameterInteger/NdisParameterHexInteger/NdisParameterStringle/NdisParameterMultiString + uint FieldOffset; // offset to MP_ADAPTER field + uint FieldSize; // size (in bytes) of the field + +#ifdef UNDER_AMD64 + u64 Default; +#else + u32 Default; // default value to use +#endif + + u32 Min; // minimum value allowed + u32 Max; // maximum value allowed +} MP_REG_ENTRY, *PMP_REG_ENTRY; + +#ifdef CONFIG_USB_HCI +typedef struct _USB_EXTENSION { + LPCUSB_FUNCS _lpUsbFuncs; + USB_HANDLE _hDevice; + PVOID pAdapter; + +#if 0 + USB_ENDPOINT_DESCRIPTOR _endpACLIn; + USB_ENDPOINT_DESCRIPTOR _endpACLOutHigh; + USB_ENDPOINT_DESCRIPTOR _endpACLOutNormal; + + USB_PIPE pPipeIn; + USB_PIPE pPipeOutNormal; + USB_PIPE pPipeOutHigh; +#endif + +} USB_EXTENSION, *PUSB_EXTENSION; +#endif + + +typedef struct _OCTET_STRING{ + u8 *Octet; + u16 Length; +} OCTET_STRING, *POCTET_STRING; + + + + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_gspi.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_gspi.h new file mode 100644 index 00000000..27b3cb07 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_gspi.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __DRV_TYPES_GSPI_H__ +#define __DRV_TYPES_GSPI_H__ + +// SPI Header Files +#ifdef PLATFORM_LINUX + #include + #include + #include + //#include + #include + #include + #include + #include + #include + #include + #include +#endif + + +typedef struct gspi_data +{ + u8 func_number; + + u8 tx_block_mode; + u8 rx_block_mode; + u32 block_transfer_len; + +#ifdef PLATFORM_LINUX + struct spi_device *func; + + struct workqueue_struct *priv_wq; + struct delayed_work irq_work; +#endif +} GSPI_DATA, *PGSPI_DATA; + +#endif // #ifndef __DRV_TYPES_GSPI_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_linux.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_linux.h new file mode 100644 index 00000000..db1c5856 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_linux.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_LINUX_H__ +#define __DRV_TYPES_LINUX_H__ + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_pci.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_pci.h new file mode 100644 index 00000000..a5b52ac7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_pci.h @@ -0,0 +1,273 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_PCI_H__ +#define __DRV_TYPES_PCI_H__ + + +#ifdef PLATFORM_LINUX +#include +#endif + + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define PCI_MAX_BRIDGE_NUMBER 255 +#define PCI_MAX_DEVICES 32 +#define PCI_MAX_FUNCTION 8 + +#define PCI_CONF_ADDRESS 0x0CF8 // PCI Configuration Space Address +#define PCI_CONF_DATA 0x0CFC // PCI Configuration Space Data + +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 + +#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define PCI_VENDER_ID_REALTEK 0x10ec + +#define HAL_HW_PCI_8180_DEVICE_ID 0x8180 +#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 //8185 or 8185b +#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 //8185b +#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 //8185b +#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 //8190 +#define HAL_HW_PCI_8723E_DEVICE_ID 0x8723 //8723E +#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 //8192 PCI-E +#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 //8192 SE +#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 //8192 SE +#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 //8191 SE Crab +#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 //8191 SE RE +#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 //8191 SE Unicron +#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 //8190 PCI for Ceraga +#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 //8190 Cardbus for Ceraga +#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 //8192e PCIE for Ceraga +#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 //8192e Express Card for Ceraga +#define HAL_HW_PCI_700F_DEVICE_ID 0x700F +#define HAL_HW_PCI_701F_DEVICE_ID 0x701F +#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304 +#define HAL_HW_PCI_8188EE_DEVICE_ID 0x8179 + +#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 //8190 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192SE 0x10 +#define HAL_HW_PCI_REVISION_ID_8192CE 0x1 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192DE 0x0 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 //8192 support 16 pages of IO registers + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0,//0b'0000,0001 + PCI_BRIDGE_VENDOR_ATI, //= 0x02,//0b'0000,0010 + PCI_BRIDGE_VENDOR_AMD, //= 0x04,//0b'0000,0100 + PCI_BRIDGE_VENDOR_SIS ,//= 0x08,//0b'0000,1000 + PCI_BRIDGE_VENDOR_UNKNOWN, //= 0x40,//0b'0100,0000 + PCI_BRIDGE_VENDOR_MAX ,//= 0x80 +} ; + +// copy this data structor defination from MSDN SDK +typedef struct _PCI_COMMON_CONFIG { + u16 VendorID; + u16 DeviceID; + u16 Command; + u16 Status; + u8 RevisionID; + u8 ProgIf; + u8 SubClass; + u8 BaseClass; + u8 CacheLineSize; + u8 LatencyTimer; + u8 HeaderType; + u8 BIST; + + union { + struct _PCI_HEADER_TYPE_0 { + u32 BaseAddresses[6]; + u32 CIS; + u16 SubVendorID; + u16 SubSystemID; + u32 ROMBaseAddress; + u8 CapabilitiesPtr; + u8 Reserved1[3]; + u32 Reserved2; + + u8 InterruptLine; + u8 InterruptPin; + u8 MinimumGrant; + u8 MaximumLatency; + } type0; +#if 0 + struct _PCI_HEADER_TYPE_1 { + ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; + UCHAR PrimaryBusNumber; + UCHAR SecondaryBusNumber; + UCHAR SubordinateBusNumber; + UCHAR SecondaryLatencyTimer; + UCHAR IOBase; + UCHAR IOLimit; + USHORT SecondaryStatus; + USHORT MemoryBase; + USHORT MemoryLimit; + USHORT PrefetchableMemoryBase; + USHORT PrefetchableMemoryLimit; + ULONG PrefetchableMemoryBaseUpper32; + ULONG PrefetchableMemoryLimitUpper32; + USHORT IOBaseUpper; + USHORT IOLimitUpper; + ULONG Reserved2; + ULONG ExpansionROMBase; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + } type1; + + struct _PCI_HEADER_TYPE_2 { + ULONG BaseAddress; + UCHAR CapabilitiesPtr; + UCHAR Reserved2; + USHORT SecondaryStatus; + UCHAR PrimaryBusNumber; + UCHAR CardbusBusNumber; + UCHAR SubordinateBusNumber; + UCHAR CardbusLatencyTimer; + ULONG MemoryBase0; + ULONG MemoryLimit0; + ULONG MemoryBase1; + ULONG MemoryLimit1; + USHORT IOBase0_LO; + USHORT IOBase0_HI; + USHORT IOLimit0_LO; + USHORT IOLimit0_HI; + USHORT IOBase1_LO; + USHORT IOBase1_HI; + USHORT IOLimit1_LO; + USHORT IOLimit1_HI; + UCHAR InterruptLine; + UCHAR InterruptPin; + USHORT BridgeControl; + USHORT SubVendorID; + USHORT SubSystemID; + ULONG LegacyBaseAddress; + UCHAR Reserved3[56]; + ULONG SystemControl; + UCHAR MultiMediaControl; + UCHAR GeneralStatus; + UCHAR Reserved4[2]; + UCHAR GPIO0Control; + UCHAR GPIO1Control; + UCHAR GPIO2Control; + UCHAR GPIO3Control; + ULONG IRQMuxRouting; + UCHAR RetryStatus; + UCHAR CardControl; + UCHAR DeviceControl; + UCHAR Diagnostic; + } type2; +#endif + } u; + + u8 DeviceSpecific[108]; +} PCI_COMMON_CONFIG , *PPCI_COMMON_CONFIG; + +typedef struct _RT_PCI_CAPABILITIES_HEADER { + u8 CapabilityID; + u8 Next; +} RT_PCI_CAPABILITIES_HEADER, *PRT_PCI_CAPABILITIES_HEADER; + +struct pci_priv{ + BOOLEAN pci_clk_req; + + u8 pciehdr_offset; + // PCIeCap is only differece between B-cut and C-cut. + // Configuration Space offset 72[7:4] + // 0: A/B cut + // 1: C cut and later. + u8 pcie_cap; + u8 linkctrl_reg; + + u8 busnumber; + u8 devnumber; + u8 funcnumber; + + u8 pcibridge_busnum; + u8 pcibridge_devnum; + u8 pcibridge_funcnum; + u8 pcibridge_vendor; + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + u8 pcibridge_pciehdr_offset; + u8 pcibridge_linkctrlreg; + + u8 amd_l1_patch; +}; + +typedef struct _RT_ISR_CONTENT +{ + union{ + u32 IntArray[2]; + u32 IntReg4Byte; + u16 IntReg2Byte; + }; +}RT_ISR_CONTENT, *PRT_ISR_CONTENT; + +//#define RegAddr(addr) (addr + 0xB2000000UL) +//some platform macros will def here +static inline void NdisRawWritePortUlong(u32 port, u32 val) +{ + outl(val, port); + //writel(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawWritePortUchar(u32 port, u8 val) +{ + outb(val, port); + //writeb(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUchar(u32 port, u8 *pval) +{ + *pval = inb(port); + //*pval = readb((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUshort(u32 port, u16 *pval) +{ + *pval = inw(port); + //*pval = readw((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUlong(u32 port, u32 *pval) +{ + *pval = inl(port); + //*pval = readl((u8 *)RegAddr(port)); +} + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_sdio.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_sdio.h new file mode 100644 index 00000000..044ef512 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_sdio.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_SDIO_H__ +#define __DRV_TYPES_SDIO_H__ + +// SDIO Header Files +#ifdef PLATFORM_LINUX + #include + #include + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) || defined(CONFIG_PLATFORM_SPRD) + #include + #include +#endif + +#ifdef CONFIG_PLATFORM_SPRD + #include + #include +#endif // CONFIG_PLATFORM_SPRD +#endif + +#ifdef PLATFORM_OS_XP +#include +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + + +typedef struct sdio_data +{ + u8 func_number; + + u8 tx_block_mode; + u8 rx_block_mode; + u32 block_transfer_len; + +#ifdef PLATFORM_LINUX + struct sdio_func *func; + _thread_hdl_ sys_sdio_irq_thd; +#endif + +#ifdef PLATFORM_OS_XP + PDEVICE_OBJECT pphysdevobj; + PDEVICE_OBJECT pfuncdevobj; + PDEVICE_OBJECT pnextdevobj; + SDBUS_INTERFACE_STANDARD sdbusinft; + u8 nextdevstacksz; +#endif + +#ifdef PLATFORM_OS_CE + SD_DEVICE_HANDLE hDevice; + SD_CARD_RCA sd_rca; + SD_CARD_INTERFACE card_intf; + BOOLEAN enableIsarWithStatus; + WCHAR active_path[MAX_ACTIVE_REG_PATH]; + SD_HOST_BLOCK_CAPABILITY sd_host_blk_cap; +#endif +} SDIO_DATA, *PSDIO_DATA; + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_xp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_xp.h new file mode 100644 index 00000000..2d51b1db --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/drv_types_xp.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * 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 __DRV_TYPES_XP_H__ +#define __DRV_TYPES_XP_H__ + +#include +#include + + + +#define MAX_MCAST_LIST_NUM 32 + + + +//for ioctl +#define MAKE_DRIVER_VERSION(_MainVer,_MinorVer) ((((u32)(_MainVer))<<16)+_MinorVer) + +#define NIC_HEADER_SIZE 14 //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h +#define NIC_MAX_SEND_PACKETS 10 // max number of send packets the MiniportSendPackets function can accept, can be moved to typedef.h +#define NIC_VENDOR_DRIVER_VERSION MAKE_DRIVER_VERSION(0,001) //!< can be moved to typedef.h +#define NIC_MAX_PACKET_SIZE 1514 //!< can be moved to typedef.h + + +#undef ON_VISTA +//added by Jackson +#ifndef ON_VISTA +// +// Bus driver versions +// + +#define SDBUS_DRIVER_VERSION_1 0x100 +#define SDBUS_DRIVER_VERSION_2 0x200 + +#define SDP_FUNCTION_TYPE 4 +#define SDP_BUS_DRIVER_VERSION 5 +#define SDP_BUS_WIDTH 6 +#define SDP_BUS_CLOCK 7 +#define SDP_BUS_INTERFACE_CONTROL 8 +#define SDP_HOST_BLOCK_LENGTH 9 +#define SDP_FUNCTION_BLOCK_LENGTH 10 +#define SDP_FN0_BLOCK_LENGTH 11 +#define SDP_FUNCTION_INT_ENABLE 12 +#endif + + +typedef struct _MP_REG_ENTRY +{ + + NDIS_STRING RegName; // variable name text + BOOLEAN bRequired; // 1 -> required, 0 -> optional + + u8 Type; // NdisParameterInteger/NdisParameterHexInteger/NdisParameterStringle/NdisParameterMultiString + uint FieldOffset; // offset to MP_ADAPTER field + uint FieldSize; // size (in bytes) of the field + +#ifdef UNDER_AMD64 + u64 Default; +#else + u32 Default; // default value to use +#endif + + u32 Min; // minimum value allowed + u32 Max; // maximum value allowed +} MP_REG_ENTRY, *PMP_REG_ENTRY; + + +typedef struct _OCTET_STRING{ + u8 *Octet; + u16 Length; +} OCTET_STRING, *POCTET_STRING; + + + + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/ethernet.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ethernet.h new file mode 100644 index 00000000..cadc8c1d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ethernet.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * 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 */ +#ifndef __INC_ETHERNET_H +#define __INC_ETHERNET_H + +#define ETHERNET_ADDRESS_LENGTH 6 //!< Ethernet Address Length +#define ETHERNET_HEADER_SIZE 14 //!< Ethernet Header Length +#define LLC_HEADER_SIZE 6 //!< LLC Header Length +#define TYPE_LENGTH_FIELD_SIZE 2 //!< Type/Length Size +#define MINIMUM_ETHERNET_PACKET_SIZE 60 //!< Minimum Ethernet Packet Size +#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 //!< Maximum Ethernet Packet Size + +#define RT_ETH_IS_MULTICAST(_pAddr) ((((UCHAR *)(_pAddr))[0]&0x01)!=0) //!< Is Multicast Address? +#define RT_ETH_IS_BROADCAST(_pAddr) ( \ + ((UCHAR *)(_pAddr))[0]==0xff && \ + ((UCHAR *)(_pAddr))[1]==0xff && \ + ((UCHAR *)(_pAddr))[2]==0xff && \ + ((UCHAR *)(_pAddr))[3]==0xff && \ + ((UCHAR *)(_pAddr))[4]==0xff && \ + ((UCHAR *)(_pAddr))[5]==0xff ) //!< Is Broadcast Address? + + +#endif // #ifndef __INC_ETHERNET_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_hal.h new file mode 100644 index 00000000..75815125 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_hal.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __GSPI_HAL_H__ +#define __GSPI_HAL_H__ + + +void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr); +u8 rtw_set_hal_ops(_adapter *padapter); + +#ifdef CONFIG_RTL8188E +void rtl8188es_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8723B +void rtl8723bs_set_hal_ops(PADAPTER padapter); +#endif + +#endif //__GSPI_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops.h new file mode 100644 index 00000000..e04c28a9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops.h @@ -0,0 +1,185 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __GSPI_OPS_H__ +#define __GSPI_OPS_H__ + +/* follwing defination is based on + * GSPI spec of RTL8723, we temp + * suppose that it will be the same + * for diff chips of GSPI, if not + * we should move it to HAL folder */ +#define SPI_LOCAL_DOMAIN 0x0 +#define WLAN_IOREG_DOMAIN 0x8 +#define FW_FIFO_DOMAIN 0x4 +#define TX_HIQ_DOMAIN 0xc +#define TX_MIQ_DOMAIN 0xd +#define TX_LOQ_DOMAIN 0xe +#define RX_RXFIFO_DOMAIN 0x1f + +//IO Bus domain address mapping +#define DEFUALT_OFFSET 0x0 +#define SPI_LOCAL_OFFSET 0x10250000 +#define WLAN_IOREG_OFFSET 0x10260000 +#define FW_FIFO_OFFSET 0x10270000 +#define TX_HIQ_OFFSET 0x10310000 +#define TX_MIQ_OFFSET 0x1032000 +#define TX_LOQ_OFFSET 0x10330000 +#define RX_RXOFF_OFFSET 0x10340000 + +//SPI Local registers +#define SPI_REG_TX_CTRL 0x0000 // SPI Tx Control +#define SPI_REG_STATUS_RECOVERY 0x0004 +#define SPI_REG_INT_TIMEOUT 0x0006 +#define SPI_REG_HIMR 0x0014 // SPI Host Interrupt Mask +#define SPI_REG_HISR 0x0018 // SPI Host Interrupt Service Routine +#define SPI_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length +#define SPI_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page +#define SPI_REG_HCPWM1 0x0024 // HCI Current Power Mode 1 +#define SPI_REG_HCPWM2 0x0026 // HCI Current Power Mode 2 +#define SPI_REG_HTSFR_INFO 0x0030 // HTSF Informaion +#define SPI_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 +#define SPI_REG_HRPWM2 0x0082 // HCI Request Power Mode 2 +#define SPI_REG_HPS_CLKR 0x0084 // HCI Power Save Clock +#define SPI_REG_HSUS_CTRL 0x0086 // SPI HCI Suspend Control +#define SPI_REG_HIMR_ON 0x0090 //SPI Host Extension Interrupt Mask Always +#define SPI_REG_HISR_ON 0x0091 //SPI Host Extension Interrupt Status Always +#define SPI_REG_CFG 0x00F0 //SPI Configuration Register + +#define SPI_TX_CTRL (SPI_REG_TX_CTRL |SPI_LOCAL_OFFSET) +#define SPI_STATUS_RECOVERY (SPI_REG_STATUS_RECOVERY |SPI_LOCAL_OFFSET) +#define SPI_INT_TIMEOUT (SPI_REG_INT_TIMEOUT |SPI_LOCAL_OFFSET) +#define SPI_HIMR (SPI_REG_HIMR |SPI_LOCAL_OFFSET) +#define SPI_HISR (SPI_REG_HISR |SPI_LOCAL_OFFSET) +#define SPI_RX0_REQ_LEN_1_BYTE (SPI_REG_RX0_REQ_LEN |SPI_LOCAL_OFFSET) +#define SPI_FREE_TXPG (SPI_REG_FREE_TXPG |SPI_LOCAL_OFFSET) + +#define SPI_HIMR_DISABLED 0 + +//SPI HIMR MASK diff with SDIO +#define SPI_HISR_RX_REQUEST BIT(0) +#define SPI_HISR_AVAL BIT(1) +#define SPI_HISR_TXERR BIT(2) +#define SPI_HISR_RXERR BIT(3) +#define SPI_HISR_TXFOVW BIT(4) +#define SPI_HISR_RXFOVW BIT(5) +#define SPI_HISR_TXBCNOK BIT(6) +#define SPI_HISR_TXBCNERR BIT(7) +#define SPI_HISR_BCNERLY_INT BIT(16) +#define SPI_HISR_ATIMEND BIT(17) +#define SPI_HISR_ATIMEND_E BIT(18) +#define SPI_HISR_CTWEND BIT(19) +#define SPI_HISR_C2HCMD BIT(20) +#define SPI_HISR_CPWM1 BIT(21) +#define SPI_HISR_CPWM2 BIT(22) +#define SPI_HISR_HSISR_IND BIT(23) +#define SPI_HISR_GTINT3_IND BIT(24) +#define SPI_HISR_GTINT4_IND BIT(25) +#define SPI_HISR_PSTIMEOUT BIT(26) +#define SPI_HISR_OCPINT BIT(27) +#define SPI_HISR_TSF_BIT32_TOGGLE BIT(29) + +#define MASK_SPI_HISR_CLEAR (SPI_HISR_TXERR |\ + SPI_HISR_RXERR |\ + SPI_HISR_TXFOVW |\ + SPI_HISR_RXFOVW |\ + SPI_HISR_TXBCNOK |\ + SPI_HISR_TXBCNERR |\ + SPI_HISR_C2HCMD |\ + SPI_HISR_CPWM1 |\ + SPI_HISR_CPWM2 |\ + SPI_HISR_HSISR_IND |\ + SPI_HISR_GTINT3_IND |\ + SPI_HISR_GTINT4_IND |\ + SPI_HISR_PSTIMEOUT |\ + SPI_HISR_OCPINT) + +#define REG_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 8, x)//(x<<(unsigned int)24) +#define REG_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define REG_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define REG_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define REG_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + +#define FIFO_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 16, x)//(x<<(unsigned int)24) +//#define FIFO_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define FIFO_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define FIFO_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define FIFO_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + + +//get status dword0 +#define GET_STATUS_PUB_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 24, 8) +#define GET_STATUS_HI_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 18, 6) +#define GET_STATUS_MID_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 12, 6) +#define GET_STATUS_LOW_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 6, 6) +#define GET_STATUS_HISR_HI6BIT(status) LE_BITS_TO_4BYTE(status, 0, 6) + +//get status dword1 +#define GET_STATUS_HISR_MID8BIT(status) LE_BITS_TO_4BYTE(status + 4, 24, 8) +#define GET_STATUS_HISR_LOW8BIT(status) LE_BITS_TO_4BYTE(status + 4, 16, 8) +#define GET_STATUS_ERROR(status) LE_BITS_TO_4BYTE(status + 4, 17, 1) +#define GET_STATUS_INT(status) LE_BITS_TO_4BYTE(status + 4, 16, 1) +#define GET_STATUS_RX_LENGTH(status) LE_BITS_TO_4BYTE(status + 4, 0, 16) + + +#define RXDESC_SIZE 24 + + +struct spi_more_data { + unsigned long more_data; + unsigned long len; +}; + +#ifdef CONFIG_RTL8188E +void rtl8188es_set_hal_ops(PADAPTER padapter); +#define set_hal_ops rtl8188es_set_hal_ops +#endif +extern void spi_set_chip_endian(PADAPTER padapter); +extern unsigned int spi_write8_endian(ADAPTER *Adapter, unsigned int addr, unsigned int buf, u32 big); +extern void spi_set_intf_ops(_adapter *padapter,struct _io_ops *pops); +extern void spi_set_chip_endian(PADAPTER padapter); +extern void InitInterrupt8723ASdio(PADAPTER padapter); +extern void InitSysInterrupt8723ASdio(PADAPTER padapter); +extern void EnableInterrupt8723ASdio(PADAPTER padapter); +extern void DisableInterrupt8723ASdio(PADAPTER padapter); +extern void spi_int_hdl(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8723ASdio(PADAPTER padapter); +#ifdef CONFIG_RTL8723B +extern void InitInterrupt8723BSdio(PADAPTER padapter); +extern void InitSysInterrupt8723BSdio(PADAPTER padapter); +extern void EnableInterrupt8723BSdio(PADAPTER padapter); +extern void DisableInterrupt8723BSdio(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8723BSdio(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8188E +extern void InitInterrupt8188EGspi(PADAPTER padapter); +extern void EnableInterrupt8188EGspi(PADAPTER padapter); +extern void DisableInterrupt8188EGspi(PADAPTER padapter); +extern void UpdateInterruptMask8188EGspi(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR); +extern u8 HalQueryTxBufferStatus8189EGspi(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8189EGspi(PADAPTER padapter); +extern void ClearInterrupt8188EGspi(PADAPTER padapter); +extern u8 CheckIPSStatus(PADAPTER padapter); +#endif // CONFIG_RTL8188E +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +extern u8 RecvOnePkt(PADAPTER padapter, u32 size); +#endif // CONFIG_WOWLAN + +#endif //__GSPI_OPS_H__ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops_linux.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops_linux.h new file mode 100644 index 00000000..6358a0fa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_ops_linux.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 + * + * + ******************************************************************************/ +#ifndef __SDIO_OPS_LINUX_H__ +#define __SDIO_OPS_LINUX_H__ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_osintf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_osintf.h new file mode 100644 index 00000000..5b57bdb6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/gspi_osintf.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * 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 __SDIO_OSINTF_H__ +#define __SDIO_OSINTF_H__ + + +#ifdef PLATFORM_OS_CE +extern NDIS_STATUS ce_sd_get_dev_hdl(PADAPTER padapter); +SD_API_STATUS ce_sd_int_callback(SD_DEVICE_HANDLE hDevice, PADAPTER padapter); +extern void sd_setup_irs(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/h2clbk.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/h2clbk.h new file mode 100644 index 00000000..4fa863c2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/h2clbk.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + + +#define _H2CLBK_H_ + + +void _lbk_cmd(PADAPTER Adapter); + +void _lbk_rsp(PADAPTER Adapter); + +void _lbk_evt(IN PADAPTER Adapter); + +void h2c_event_callback(unsigned char *dev, unsigned char *pbuf); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_btcoex.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_btcoex.h new file mode 100644 index 00000000..dd2eb84f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_btcoex.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 __HAL_BTCOEX_H__ +#define __HAL_BTCOEX_H__ + +#include + +// Some variables can't get from outsrc BT-Coex, +// so we need to save here +typedef struct _BT_COEXIST +{ + u8 bBtExist; + u8 btTotalAntNum; + u8 btChipType; + u8 bInitlized; + u8 btAntisolation; +} BT_COEXIST, *PBT_COEXIST; + +void DBG_BT_INFO(u8 *dbgmsg); + +void hal_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist); +u8 hal_btcoex_IsBtExist(PADAPTER padapter); +u8 hal_btcoex_IsBtDisabled(PADAPTER); +void hal_btcoex_SetChipType(PADAPTER padapter, u8 chipType); +u8 hal_btcoex_GetChipType(PADAPTER padapter); +void hal_btcoex_SetPgAntNum(PADAPTER padapter, u8 antNum); +u8 hal_btcoex_GetPgAntNum(PADAPTER padapter); +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); +void hal_btcoex_LpsNotify(PADAPTER padapter, u8 type); +void hal_btcoex_ScanNotify(PADAPTER padapter, u8 type); +void hal_btcoex_ConnectNotify(PADAPTER padapter, u8 action); +void hal_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus); +void hal_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType); +void hal_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void hal_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); +void hal_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); +void hal_btcoex_SuspendNotify(PADAPTER padapter, u8 state); +void hal_btcoex_HaltNotify(PADAPTER padapter); +void hal_btcoex_ScoreBoardStatusNotify(PADAPTER padapter, u8 length, u8 *tmpBuf); +void hal_btcoex_SwitchBtTRxMask(PADAPTER padapter); + +void hal_btcoex_Hanlder(PADAPTER padapter); + +s32 hal_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); +s32 hal_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter); +u32 hal_btcoex_GetAMPDUSize(PADAPTER padapter); +void hal_btcoex_SetManualControl(PADAPTER padapter, u8 bmanual); +u8 hal_btcoex_1Ant(PADAPTER padapter); +u8 hal_btcoex_IsBtControlLps(PADAPTER); +u8 hal_btcoex_IsLpsOn(PADAPTER); +u8 hal_btcoex_RpwmVal(PADAPTER); +u8 hal_btcoex_LpsVal(PADAPTER); +u32 hal_btcoex_GetRaMask(PADAPTER); +void hal_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen); +void hal_btcoex_DisplayBtCoexInfo(PADAPTER, u8 *pbuf, u32 bufsize); +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_SetBtPatchVersion(PADAPTER,u16 btHciVer,u16 btPatchVer); +void hal_btcoex_SetHciVersion(PADAPTER, u16 hciVersion); +void hal_btcoex_SendScanNotify(PADAPTER, u8 type); +void hal_btcoex_StackUpdateProfileInfo(void); +void hal_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON); +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 +u16 hal_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data); +u16 hal_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val); +#endif // !__HAL_BTCOEX_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com.h new file mode 100644 index 00000000..9cee4a85 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com.h @@ -0,0 +1,533 @@ +/****************************************************************************** + * + * 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 __HAL_COMMON_H__ +#define __HAL_COMMON_H__ + +#include "HalVerDef.h" +#include "hal_pg.h" +#include "hal_phy.h" +#include "hal_phy_reg.h" +#include "hal_com_reg.h" +#include "hal_com_phycfg.h" +#include "../hal/hal_com_c2h.h" + +/*------------------------------ Tx Desc definition Macro ------------------------*/ +//#pragma mark -- Tx Desc related definition. -- +//---------------------------------------------------------------------------- +//----------------------------------------------------------- +// Rate +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC_RATE1M 0x00 +#define DESC_RATE2M 0x01 +#define DESC_RATE5_5M 0x02 +#define DESC_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC_RATE6M 0x04 +#define DESC_RATE9M 0x05 +#define DESC_RATE12M 0x06 +#define DESC_RATE18M 0x07 +#define DESC_RATE24M 0x08 +#define DESC_RATE36M 0x09 +#define DESC_RATE48M 0x0a +#define DESC_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC_RATEMCS0 0x0c +#define DESC_RATEMCS1 0x0d +#define DESC_RATEMCS2 0x0e +#define DESC_RATEMCS3 0x0f +#define DESC_RATEMCS4 0x10 +#define DESC_RATEMCS5 0x11 +#define DESC_RATEMCS6 0x12 +#define DESC_RATEMCS7 0x13 +#define DESC_RATEMCS8 0x14 +#define DESC_RATEMCS9 0x15 +#define DESC_RATEMCS10 0x16 +#define DESC_RATEMCS11 0x17 +#define DESC_RATEMCS12 0x18 +#define DESC_RATEMCS13 0x19 +#define DESC_RATEMCS14 0x1a +#define DESC_RATEMCS15 0x1b +#define DESC_RATEMCS16 0x1C +#define DESC_RATEMCS17 0x1D +#define DESC_RATEMCS18 0x1E +#define DESC_RATEMCS19 0x1F +#define DESC_RATEMCS20 0x20 +#define DESC_RATEMCS21 0x21 +#define DESC_RATEMCS22 0x22 +#define DESC_RATEMCS23 0x23 +#define DESC_RATEMCS24 0x24 +#define DESC_RATEMCS25 0x25 +#define DESC_RATEMCS26 0x26 +#define DESC_RATEMCS27 0x27 +#define DESC_RATEMCS28 0x28 +#define DESC_RATEMCS29 0x29 +#define DESC_RATEMCS30 0x2A +#define DESC_RATEMCS31 0x2B +#define DESC_RATEVHTSS1MCS0 0x2C +#define DESC_RATEVHTSS1MCS1 0x2D +#define DESC_RATEVHTSS1MCS2 0x2E +#define DESC_RATEVHTSS1MCS3 0x2F +#define DESC_RATEVHTSS1MCS4 0x30 +#define DESC_RATEVHTSS1MCS5 0x31 +#define DESC_RATEVHTSS1MCS6 0x32 +#define DESC_RATEVHTSS1MCS7 0x33 +#define DESC_RATEVHTSS1MCS8 0x34 +#define DESC_RATEVHTSS1MCS9 0x35 +#define DESC_RATEVHTSS2MCS0 0x36 +#define DESC_RATEVHTSS2MCS1 0x37 +#define DESC_RATEVHTSS2MCS2 0x38 +#define DESC_RATEVHTSS2MCS3 0x39 +#define DESC_RATEVHTSS2MCS4 0x3A +#define DESC_RATEVHTSS2MCS5 0x3B +#define DESC_RATEVHTSS2MCS6 0x3C +#define DESC_RATEVHTSS2MCS7 0x3D +#define DESC_RATEVHTSS2MCS8 0x3E +#define DESC_RATEVHTSS2MCS9 0x3F +#define DESC_RATEVHTSS3MCS0 0x40 +#define DESC_RATEVHTSS3MCS1 0x41 +#define DESC_RATEVHTSS3MCS2 0x42 +#define DESC_RATEVHTSS3MCS3 0x43 +#define DESC_RATEVHTSS3MCS4 0x44 +#define DESC_RATEVHTSS3MCS5 0x45 +#define DESC_RATEVHTSS3MCS6 0x46 +#define DESC_RATEVHTSS3MCS7 0x47 +#define DESC_RATEVHTSS3MCS8 0x48 +#define DESC_RATEVHTSS3MCS9 0x49 +#define DESC_RATEVHTSS4MCS0 0x4A +#define DESC_RATEVHTSS4MCS1 0x4B +#define DESC_RATEVHTSS4MCS2 0x4C +#define DESC_RATEVHTSS4MCS3 0x4D +#define DESC_RATEVHTSS4MCS4 0x4E +#define DESC_RATEVHTSS4MCS5 0x4F +#define DESC_RATEVHTSS4MCS6 0x50 +#define DESC_RATEVHTSS4MCS7 0x51 +#define DESC_RATEVHTSS4MCS8 0x52 +#define DESC_RATEVHTSS4MCS9 0x53 + +#define HDATA_RATE(rate)\ +(rate == DESC_RATE1M)?"CCK_1M" :\ +(rate == DESC_RATE2M)?"CCK_2M" :\ +(rate == DESC_RATE5_5M)?"CCK5_5M" :\ +(rate == DESC_RATE11M)?"CCK_11M" :\ +(rate == DESC_RATE6M)?"OFDM_6M" :\ +(rate == DESC_RATE9M)?"OFDM_9M" :\ +(rate == DESC_RATE12M)?"OFDM_12M" :\ +(rate == DESC_RATE18M)?"OFDM_18M" :\ +(rate == DESC_RATE24M)?"OFDM_24M" :\ +(rate == DESC_RATE36M)?"OFDM_36M" :\ +(rate == DESC_RATE48M)?"OFDM_48M" :\ +(rate == DESC_RATE54M)?"OFDM_54M" :\ +(rate == DESC_RATEMCS0)?"MCS0" :\ +(rate == DESC_RATEMCS1)?"MCS1" :\ +(rate == DESC_RATEMCS2)?"MCS2" :\ +(rate == DESC_RATEMCS3)?"MCS3" :\ +(rate == DESC_RATEMCS4)?"MCS4" :\ +(rate == DESC_RATEMCS5)?"MCS5" :\ +(rate == DESC_RATEMCS6)?"MCS6" :\ +(rate == DESC_RATEMCS7)?"MCS7" :\ +(rate == DESC_RATEMCS8)?"MCS8" :\ +(rate == DESC_RATEMCS9)?"MCS9" :\ +(rate == DESC_RATEMCS10)?"MCS10" :\ +(rate == DESC_RATEMCS11)?"MCS11" :\ +(rate == DESC_RATEMCS12)?"MCS12" :\ +(rate == DESC_RATEMCS13)?"MCS13" :\ +(rate == DESC_RATEMCS14)?"MCS14" :\ +(rate == DESC_RATEMCS15)?"MCS15" :\ +(rate == DESC_RATEMCS16)?"MCS16" :\ +(rate == DESC_RATEMCS17)?"MCS17" :\ +(rate == DESC_RATEMCS18)?"MCS18" :\ +(rate == DESC_RATEMCS19)?"MCS19" :\ +(rate == DESC_RATEMCS20)?"MCS20" :\ +(rate == DESC_RATEMCS21)?"MCS21" :\ +(rate == DESC_RATEMCS22)?"MCS22" :\ +(rate == DESC_RATEMCS23)?"MCS23" :\ +(rate == DESC_RATEVHTSS1MCS0)?"VHTSS1MCS0" :\ +(rate == DESC_RATEVHTSS1MCS1)?"VHTSS1MCS1" :\ +(rate == DESC_RATEVHTSS1MCS2)?"VHTSS1MCS2" :\ +(rate == DESC_RATEVHTSS1MCS3)?"VHTSS1MCS3" :\ +(rate == DESC_RATEVHTSS1MCS4)?"VHTSS1MCS4" :\ +(rate == DESC_RATEVHTSS1MCS5)?"VHTSS1MCS5" :\ +(rate == DESC_RATEVHTSS1MCS6)?"VHTSS1MCS6" :\ +(rate == DESC_RATEVHTSS1MCS7)?"VHTSS1MCS7" :\ +(rate == DESC_RATEVHTSS1MCS8)?"VHTSS1MCS8" :\ +(rate == DESC_RATEVHTSS1MCS9)?"VHTSS1MCS9" :\ +(rate == DESC_RATEVHTSS2MCS0)?"VHTSS2MCS0" :\ +(rate == DESC_RATEVHTSS2MCS1)?"VHTSS2MCS1" :\ +(rate == DESC_RATEVHTSS2MCS2)?"VHTSS2MCS2" :\ +(rate == DESC_RATEVHTSS2MCS3)?"VHTSS2MCS3" :\ +(rate == DESC_RATEVHTSS2MCS4)?"VHTSS2MCS4" :\ +(rate == DESC_RATEVHTSS2MCS5)?"VHTSS2MCS5" :\ +(rate == DESC_RATEVHTSS2MCS6)?"VHTSS2MCS6" :\ +(rate == DESC_RATEVHTSS2MCS7)?"VHTSS2MCS7" :\ +(rate == DESC_RATEVHTSS2MCS8)?"VHTSS2MCS8" :\ +(rate == DESC_RATEVHTSS2MCS9)?"VHTSS2MCS9" :\ +(rate == DESC_RATEVHTSS3MCS0)?"VHTSS3MCS0" :\ +(rate == DESC_RATEVHTSS3MCS1)?"VHTSS3MCS1" :\ +(rate == DESC_RATEVHTSS3MCS2)?"VHTSS3MCS2" :\ +(rate == DESC_RATEVHTSS3MCS3)?"VHTSS3MCS3" :\ +(rate == DESC_RATEVHTSS3MCS4)?"VHTSS3MCS4" :\ +(rate == DESC_RATEVHTSS3MCS5)?"VHTSS3MCS5" :\ +(rate == DESC_RATEVHTSS3MCS6)?"VHTSS3MCS6" :\ +(rate == DESC_RATEVHTSS3MCS7)?"VHTSS3MCS7" :\ +(rate == DESC_RATEVHTSS3MCS8)?"VHTSS3MCS8" :\ +(rate == DESC_RATEVHTSS3MCS9)?"VHTSS3MCS9" : "UNKNOWN" + + +enum{ + UP_LINK, + DOWN_LINK, +}; +typedef enum _RT_MEDIA_STATUS { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +} RT_MEDIA_STATUS; + +#define MAX_DLFW_PAGE_SIZE 4096 // @ page : 4k bytes +typedef enum _FIRMWARE_SOURCE { + FW_SOURCE_IMG_FILE = 0, + 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 + +#define TX_SELE_HQ BIT(0) // High Queue +#define TX_SELE_LQ BIT(1) // Low Queue +#define TX_SELE_NQ BIT(2) // Normal Queue +#define TX_SELE_EQ BIT(3) // Extern Queue + +#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len)&0x7F ? 1:0)) +#define PageNum_256(_Len) (u32)(((_Len)>>8) + ((_Len)&0xFF ? 1:0)) +#define PageNum_512(_Len) (u32)(((_Len)>>9) + ((_Len)&0x1FF ? 1:0)) +#define PageNum(_Len, _Size) (u32)(((_Len)/(_Size)) + ((_Len)&((_Size) - 1) ? 1:0)) + +struct dbg_rx_counter +{ + u32 rx_pkt_ok; + u32 rx_pkt_crc_error; + u32 rx_pkt_drop; + u32 rx_ofdm_fa; + u32 rx_cck_fa; + u32 rx_ht_fa; +}; +void rtw_dump_mac_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter); +void rtw_dump_phy_rx_counters(_adapter* padapter,struct dbg_rx_counter *rx_counter); +void rtw_reset_mac_rx_counters(_adapter* padapter); +void rtw_reset_phy_rx_counters(_adapter* padapter); + +#ifdef DBG_RX_COUNTER_DUMP +#define DUMP_DRV_RX_COUNTER BIT0 +#define DUMP_MAC_RX_COUNTER BIT1 +#define DUMP_PHY_RX_COUNTER BIT2 +#define DUMP_DRV_TRX_COUNTER_DATA BIT3 + +void rtw_dump_phy_rxcnts_preprocess(_adapter* padapter,u8 rx_cnt_mode); +void rtw_dump_rx_counters(_adapter* padapter); +#endif + +void dump_chip_info(HAL_VERSION ChipVersion); +void rtw_hal_config_rftype(PADAPTER padapter); + +#define BAND_CAP_2G BIT0 +#define BAND_CAP_5G BIT1 +#define BAND_CAP_BIT_NUM 2 + +#define BW_CAP_5M BIT0 +#define BW_CAP_10M BIT1 +#define BW_CAP_20M BIT2 +#define BW_CAP_40M BIT3 +#define BW_CAP_80M BIT4 +#define BW_CAP_160M BIT5 +#define BW_CAP_80_80M BIT6 +#define BW_CAP_BIT_NUM 7 + +#define WL_FUNC_P2P BIT0 +#define WL_FUNC_MIRACAST BIT1 +#define WL_FUNC_TDLS BIT2 +#define WL_FUNC_FTM BIT3 +#define WL_FUNC_BIT_NUM 4 + +int hal_spec_init(_adapter *adapter); +void dump_hal_spec(void *sel, _adapter *adapter); + +bool hal_chk_band_cap(_adapter *adapter, u8 cap); +bool hal_chk_bw_cap(_adapter *adapter, u8 cap); +bool hal_is_band_support(_adapter *adapter, u8 band); +bool hal_is_bw_support(_adapter *adapter, u8 bw); +u8 hal_largest_bw(_adapter *adapter, u8 in_bw); + +bool hal_chk_wl_func(_adapter *adapter, u8 func); + +u8 hal_com_config_channel_plan( + IN PADAPTER padapter, + IN char *hw_alpha2, + IN u8 hw_chplan, + IN char *sw_alpha2, + IN u8 sw_chplan, + IN u8 def_chplan, + IN BOOLEAN AutoLoadFail + ); + +int hal_config_macaddr(_adapter *adapter, bool autoload_fail); + +BOOLEAN +HAL_IsLegalChannel( + IN PADAPTER Adapter, + IN u32 Channel + ); + +u8 MRateToHwRate(u8 rate); + +u8 HwRateToMRate(u8 rate); + +void HalSetBrateCfg( + IN PADAPTER Adapter, + IN u8 *mBratesOS, + OUT u16 *pBrateCfg); + +BOOLEAN +Hal_MappingOutPipe( + IN PADAPTER pAdapter, + IN u8 NumOutPipe + ); + +void hal_init_macaddr(_adapter *adapter); + +void rtw_init_hal_com_default_value(PADAPTER Adapter); + +void c2h_evt_clear(_adapter *adapter); +s32 c2h_evt_read(_adapter *adapter, u8 *buf); +s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf); + +u8 rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta); +u8 rtw_get_mgntframe_raid(_adapter *adapter,unsigned char network_type); +void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta); + +/* access HW only */ +u32 rtw_sec_read_cam(_adapter *adapter, u8 addr); +void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata); +void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key); +void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key); +bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id); + +void hw_var_port_switch(_adapter *adapter); + +void SetHwReg(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg(PADAPTER padapter, u8 variable, u8 *val); +void rtw_hal_check_rxfifo_full(_adapter *adapter); + +u8 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); +u8 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); + +BOOLEAN +eqNByte( + u8* str1, + u8* str2, + u32 num + ); + +u32 +MapCharToHexDigit( + IN char chTmp +); + +BOOLEAN +GetHexValueFromString( + IN char* szStr, + IN OUT u32* pu4bVal, + IN OUT u32* pu4bMove + ); + +BOOLEAN +GetFractionValueFromString( + IN char* szStr, + IN OUT u8* pInteger, + IN OUT u8* pFraction, + IN OUT u32* pu4bMove + ); + +BOOLEAN +IsCommentString( + IN char* szStr + ); + +BOOLEAN +ParseQualifiedString( + IN char* In, + IN OUT u32* Start, + OUT char* Out, + IN char LeftQualifier, + IN char RightQualifier + ); + +BOOLEAN +GetU1ByteIntegerFromStringInDecimal( + IN char* Str, + IN OUT u8* pInt + ); + +BOOLEAN +isAllSpaceOrTab( + u8* data, + u8 size + ); + +void linked_info_dump(_adapter *padapter,u8 benable); +#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA +void rtw_get_raw_rssi_info(void *sel, _adapter *padapter); +void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe); +void rtw_dump_raw_rssi_info(_adapter *padapter); +#endif + +#define HWSET_MAX_SIZE 512 +#ifdef CONFIG_EFUSE_CONFIG_FILE +#define EFUSE_FILE_COLUMN_NUM 16 +u32 Hal_readPGDataFromConfigFile(PADAPTER padapter); +u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr); +#endif /* CONFIG_EFUSE_CONFIG_FILE */ + +int check_phy_efuse_tx_power_info_valid(PADAPTER padapter); +int hal_efuse_macaddr_offset(_adapter *adapter); +int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr); + +#ifdef CONFIG_RF_GAIN_OFFSET +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, + PVOID pValue1, + PVOID pValue2); +void SetHalODMVar( + PADAPTER Adapter, + HAL_ODM_VARIABLE eVariable, + PVOID pValue1, + BOOLEAN bSet); + +#ifdef CONFIG_BACKGROUND_NOISE_MONITOR +struct noise_info +{ + u8 bPauseDIG; + u8 IGIValue; + u32 max_time;//ms + u8 chan; +}; +#endif + +void rtw_get_noise(_adapter* padapter); +u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid); +void rtw_hal_set_fw_rsvd_page(_adapter* adapter, bool finished); + +#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, bool isHigh); +int rtw_hal_config_gpio(_adapter* adapter, u8 gpio_num, bool isOutput); +int rtw_hal_register_gpio_interrupt(_adapter* adapter, int gpio_num, void(*callback)(u8 level)); +int rtw_hal_disable_gpio_interrupt(_adapter* adapter, int gpio_num); +#endif + +#ifdef CONFIG_GPIO_WAKEUP +void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable); +void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval); +#endif + +typedef enum _HAL_PHYDM_OPS { + HAL_PHYDM_DIS_ALL_FUNC, + HAL_PHYDM_FUNC_SET, + HAL_PHYDM_FUNC_CLR, + HAL_PHYDM_ABILITY_BK, + HAL_PHYDM_ABILITY_RESTORE, + HAL_PHYDM_ABILITY_SET, + HAL_PHYDM_ABILITY_GET, +} HAL_PHYDM_OPS; + + +#define DYNAMIC_FUNC_DISABLE (0x0) +u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability); + +#define rtw_phydm_func_disable_all(adapter) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_DIS_ALL_FUNC, 0) + +#define rtw_phydm_func_for_offchannel(adapter) \ + do { \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_DIS_ALL_FUNC, 0); \ + if (rtw_odm_adaptivity_needed(adapter)) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_FUNC_SET, ODM_BB_ADAPTIVITY); \ + } while (0) + +#define rtw_phydm_func_set(adapter, ability) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_FUNC_SET, ability) + +#define rtw_phydm_func_clr(adapter, ability) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_FUNC_CLR, ability) + +#define rtw_phydm_ability_backup(adapter) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_ABILITY_BK, 0) + +#define rtw_phydm_ability_restore(adapter) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_ABILITY_RESTORE, 0) + +#define rtw_phydm_ability_set(adapter, ability) \ + rtw_phydm_ability_ops(adapter, HAL_PHYDM_ABILITY_SET, ability) + +static inline u32 rtw_phydm_ability_get(_adapter *adapter) +{ + return rtw_phydm_ability_ops(adapter, HAL_PHYDM_ABILITY_GET, 0); +} + +#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, "\r\n") +#endif + +#ifdef CONFIG_FW_C2H_DEBUG +void Debug_FwC2H(PADAPTER padapter, u8 *pdata, u8 len); +#endif +/*CONFIG_FW_C2H_DEBUG*/ + +void update_IOT_info(_adapter *padapter); + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +void rtw_acs_start(_adapter *padapter, bool bStart); +#endif + +void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap); + +#endif //__HAL_COMMON_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_h2c.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_h2c.h new file mode 100644 index 00000000..ad583d27 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_h2c.h @@ -0,0 +1,364 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __COMMON_H2C_H__ +#define __COMMON_H2C_H__ + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD DEFINITION ------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +// 88e, 8723b, 8812, 8821, 92e use the same FW code base +enum h2c_cmd{ + //Common Class: 000 + H2C_RSVD_PAGE = 0x00, + H2C_MEDIA_STATUS_RPT = 0x01, + H2C_SCAN_ENABLE = 0x02, + H2C_KEEP_ALIVE = 0x03, + H2C_DISCON_DECISION = 0x04, + H2C_PSD_OFFLOAD = 0x05, + H2C_AP_OFFLOAD = 0x08, + H2C_BCN_RSVDPAGE = 0x09, + H2C_PROBERSP_RSVDPAGE = 0x0A, + H2C_FCS_RSVDPAGE = 0x10, + H2C_FCS_INFO = 0x11, + H2C_AP_WOW_GPIO_CTRL = 0x13, + + //PoweSave Class: 001 + H2C_SET_PWR_MODE = 0x20, + H2C_PS_TUNING_PARA = 0x21, + H2C_PS_TUNING_PARA2 = 0x22, + H2C_P2P_LPS_PARAM = 0x23, + H2C_P2P_PS_OFFLOAD = 0x24, + H2C_PS_SCAN_ENABLE = 0x25, + H2C_SAP_PS_ = 0x26, + H2C_INACTIVE_PS_ = 0x27, //Inactive_PS + H2C_FWLPS_IN_IPS_ = 0x28, + + //Dynamic Mechanism Class: 010 + H2C_MACID_CFG = 0x40, + H2C_TXBF = 0x41, + H2C_RSSI_SETTING = 0x42, + H2C_AP_REQ_TXRPT = 0x43, + H2C_INIT_RATE_COLLECT = 0x44, + H2C_IQ_CALIBRATION = 0x45, + + H2C_RA_MASK_3SS = 0x46,/* for 8814A */ + H2C_RA_PARA_ADJUST = 0x47,/* CONFIG_RA_DBG_CMD */ + H2C_DYNAMIC_TX_PATH = 0x48,/* for 8814A */ + + H2C_FW_TRACE_EN = 0x49, + + //BT Class: 011 + H2C_B_TYPE_TDMA = 0x60, + H2C_BT_INFO = 0x61, + H2C_FORCE_BT_TXPWR = 0x62, + H2C_BT_IGNORE_WLANACT = 0x63, + H2C_DAC_SWING_VALUE = 0x64, + H2C_ANT_SEL_RSV = 0x65, + H2C_WL_OPMODE = 0x66, + H2C_BT_MP_OPER = 0x67, + H2C_BT_CONTROL = 0x68, + H2C_BT_WIFI_CTRL = 0x69, + H2C_BT_FW_PATCH = 0x6A, + + //WOWLAN Class: 100 + H2C_WOWLAN = 0x80, + H2C_REMOTE_WAKE_CTRL = 0x81, + H2C_AOAC_GLOBAL_INFO = 0x82, + H2C_AOAC_RSVD_PAGE = 0x83, + H2C_AOAC_RSVD_PAGE2 = 0x84, + H2C_D0_SCAN_OFFLOAD_CTRL = 0x85, + 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_BCNHWSEQ = 0xC5, + 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 +#define H2C_DISCON_DECISION_LEN 3 +#define H2C_AP_OFFLOAD_LEN 3 +#define H2C_AP_WOW_GPIO_CTRL_LEN 4 +#define H2C_AP_PS_LEN 2 +#define H2C_PWRMODE_LEN 7 +#define H2C_PSTUNEPARAM_LEN 4 +#define H2C_MACID_CFG_LEN 7 +#define H2C_BTMP_OPER_LEN 5 +#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 +#define H2C_SCAN_OFFLOAD_CTRL_LEN 4 +#define H2C_BT_FW_PATCH_LEN 6 +#define H2C_RSSI_SETTING_LEN 4 +#define H2C_AP_REQ_TXRPT_LEN 2 +#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 + +#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 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define cpIpAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3]) +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +// +// ARP packet +// +// LLC Header +#define GET_ARP_PKT_LLC_TYPE(__pHeader) ReadLE2Byte(((u8 *)(__pHeader)) + 6) + +//ARP element +#define GET_ARP_PKT_OPERATION(__pHeader) ReadLE2Byte(((u8 *)(__pHeader)) + 6) +#define GET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+8) +#define GET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+14) +#define GET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+18) +#define GET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+24) + +#define SET_ARP_PKT_HW(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 0, __Value) +#define SET_ARP_PKT_PROTOCOL(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 2, __Value) +#define SET_ARP_PKT_HW_ADDR_LEN(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 4, __Value) +#define SET_ARP_PKT_PROTOCOL_ADDR_LEN(__pHeader, __Value) WriteLE1Byte(((u8 *)(__pHeader)) + 5, __Value) +#define SET_ARP_PKT_OPERATION(__pHeader, __Value) WriteLE2Byte(((u8 *)(__pHeader)) + 6, __Value) +#define SET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+8, (u8*)(_val)) +#define SET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+14, (u8*)(_val)) +#define SET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+18, (u8*)(_val)) +#define SET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+24, (u8*)(_val)) + +#define FW_WOWLAN_FUN_EN BIT(0) +#define FW_WOWLAN_PATTERN_MATCH BIT(1) +#define FW_WOWLAN_MAGIC_PKT BIT(2) +#define FW_WOWLAN_UNICAST BIT(3) +#define FW_WOWLAN_ALL_PKT_DROP BIT(4) +#define FW_WOWLAN_GPIO_ACTIVE BIT(5) +#define FW_WOWLAN_REKEY_WAKEUP BIT(6) +#define FW_WOWLAN_DEAUTH_WAKEUP BIT(7) + +#define FW_WOWLAN_GPIO_WAKEUP_EN BIT(0) +#define FW_FW_PARSE_MAGIC_PKT BIT(1) + +#define FW_REMOTE_WAKE_CTRL_EN BIT(0) +#define FW_REALWOWLAN_EN BIT(5) + +#define FW_WOWLAN_KEEP_ALIVE_EN BIT(0) +#define FW_ADOPT_USER BIT(1) +#define FW_WOWLAN_KEEP_ALIVE_PKT_TYPE BIT(2) + +#define FW_REMOTE_WAKE_CTRL_EN BIT(0) +#define FW_ARP_EN BIT(1) +#define FW_REALWOWLAN_EN BIT(5) +#define FW_WOW_FW_UNICAST_EN BIT(7) + +#endif //CONFIG_WOWLAN + +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value)SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_MEDIA_STATUS_RPT_PARM_CMD_0x01 +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)), 0, 1, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)), 1, 1, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_MIRACAST(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)), 2, 1, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)), 3, 1, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_ROLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)), 4, 4, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)) + 1, 0, 8, (__Value)) +#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(((u8 *)(__pH2CCmd)) + 2, 0, 8, (__Value)) + +#define GET_H2CCMD_MSRRPT_PARM_OPMODE(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 0, 1) +#define GET_H2CCMD_MSRRPT_PARM_MIRACAST(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 2, 1) +#define GET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 3, 1) +#define GET_H2CCMD_MSRRPT_PARM_ROLE(__pH2CCmd) LE_BITS_TO_1BYTE(((u8 *)(__pH2CCmd)), 4, 4) + +#define H2C_MSR_ROLE_RSVD 0 +#define H2C_MSR_ROLE_STA 1 +#define H2C_MSR_ROLE_AP 2 +#define H2C_MSR_ROLE_GC 3 +#define H2C_MSR_ROLE_GO 4 +#define H2C_MSR_ROLE_TDLS 5 +#define H2C_MSR_ROLE_ADHOC 6 +#define H2C_MSR_ROLE_MAX 7 + +extern const char * const _h2c_msr_role_str[]; +#define h2c_msr_role_str(role) (((role) >= H2C_MSR_ROLE_MAX) ? _h2c_msr_role_str[H2C_MSR_ROLE_MAX] : _h2c_msr_role_str[(role)]) + +#define H2C_MSR_FMT "%s %s%s" +#define H2C_MSR_ARG(h2c_msr) \ + GET_H2CCMD_MSRRPT_PARM_OPMODE((h2c_msr)) ? " C" : "", \ + h2c_msr_role_str(GET_H2CCMD_MSRRPT_PARM_ROLE((h2c_msr))), \ + GET_H2CCMD_MSRRPT_PARM_MIRACAST((h2c_msr)) ? (GET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK((h2c_msr)) ? " MSINK" : " MSRC") : "" + +s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end); +s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid); +s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end); + +//_KEEP_ALIVE_CMD_0x03 +#define SET_H2CCMD_KEEPALIVE_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_KEEPALIVE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +//_DISCONNECT_DECISION_CMD_0x04 +#define SET_H2CCMD_DISCONDECISION_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_DISCONDECISION_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +//_AP_Offload 0x08 +#define SET_H2CCMD_AP_WOWLAN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +//_BCN_RsvdPage 0x09 +#define SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +//_Probersp_RsvdPage 0x0a +#define SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +//_Probersp_RsvdPage 0x13 +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_C2H_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_AP_WOW_GPIO_CTRL_C2H_DURATION(__pH2CCmd, __Value)SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +//_AP_PS 0x26 +#define SET_H2CCMD_AP_WOW_PS_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#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((__pH2CCmd)+1, 0, 8, __Value) + +// _WoWLAN PARAM_CMD_0x80 +#define SET_H2CCMD_WOWLAN_FUNC_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_H2CCMD_WOWLAN_ALL_PKT_DROP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_H2CCMD_WOWLAN_GPIO_ACTIVE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) +#define SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#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((__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((__pH2CCmd)+3, 1, 7, __Value) +#define SET_H2CCMD_WOWLAN_LOWPR_RX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 1, __Value) +#define SET_H2CCMD_WOWLAN_CHANGE_UNIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 2, 1, __Value) +// _REMOTE_WAKEUP_CMD_0x81 +#define SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#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_NBNS_FILTER_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 2, 1, __Value) +#define SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 1, __Value) +#define SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 4, 1, __Value) + +// AOAC_GLOBAL_INFO_0x82 +#define SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) + +// AOAC_RSVDPAGE_LOC_0x83 +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#ifdef CONFIG_GTK_OL +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) +#endif //CONFIG_GTK_OL +#ifdef CONFIG_PNO_SUPPORT +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#endif + +#ifdef CONFIG_PNO_SUPPORT +// D0_Scan_Offload_Info_0x86 +#define SET_H2CCMD_AOAC_NLO_FUN_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 3, 1, __Value) +#define SET_H2CCMD_AOAC_NLO_IPS_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 4, 1, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__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(__pH2CCmd, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#endif //CONFIG_P2P_WOWLAN + +//---------------------------------------------------------------------------------------------------------// +//------------------------------------------- Structure --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +typedef struct _RSVDPAGE_LOC { + u8 LocProbeRsp; + u8 LocPsPoll; + u8 LocNullData; + u8 LocQosNull; + u8 LocBTQosNull; +#ifdef CONFIG_WOWLAN + u8 LocRemoteCtrlInfo; + u8 LocArpRsp; + u8 LocNbrAdv; + u8 LocGTKRsp; + u8 LocGTKInfo; + u8 LocProbeReq; + u8 LocNetList; +#ifdef CONFIG_GTK_OL + u8 LocGTKEXTMEM; +#endif //CONFIG_GTK_OL +#ifdef CONFIG_PNO_SUPPORT + u8 LocPNOInfo; + u8 LocScanInfo; + u8 LocSSIDInfo; + u8 LocProbePacket; +#endif //CONFIG_PNO_SUPPORT +#endif //CONFIG_WOWLAN + u8 LocApOffloadBCN; +#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_hal_set_fw_media_status_cmd(_adapter* adapter, u8 mstatus, u8 macid); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +//WOW command function +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/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_led.h new file mode 100644 index 00000000..79e62c6e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_led.h @@ -0,0 +1,398 @@ +/****************************************************************************** + * + * 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 __HAL_COMMON_LED_H_ +#define __HAL_COMMON_LED_H_ + + +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) + +//================================================================================ +// LED Behavior Constant. +//================================================================================ +// Default LED behavior. +// +#define LED_BLINK_NORMAL_INTERVAL 100 +#define LED_BLINK_SLOWLY_INTERVAL 200 +#define LED_BLINK_LONG_INTERVAL 400 +#define LED_INITIAL_INTERVAL 1800 + +// LED Customerization + +//NETTRONIX +#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100 +#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000 + +//PORNET +#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000 +#define LED_BLINK_NORMAL_INTERVAL_PORNET 100 +#define LED_BLINK_FAST_INTERVAL_BITLAND 30 + +//AzWave. +#define LED_CM2_BLINK_ON_INTERVAL 250 +#define LED_CM2_BLINK_OFF_INTERVAL 4750 +#define LED_CM8_BLINK_OFF_INTERVAL 3750 //for QMI + +//RunTop +#define LED_RunTop_BLINK_INTERVAL 300 + +//ALPHA +#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 +#define LED_BLINK_NO_LINK_INTERVAL_ALPHA_500MS 500 //add by ylb 20121012 for customer led for alpha +#define LED_BLINK_LINK_INTERVAL_ALPHA 500 //500 +#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 //150 +#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 +#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 + +// 111122 by hpfan: Customized for Xavi +#define LED_CM11_BLINK_INTERVAL 300 +#define LED_CM11_LINK_ON_INTERVEL 3000 + +//Netgear +#define LED_BLINK_LINK_INTERVAL_NETGEAR 500 +#define LED_BLINK_LINK_SLOWLY_INTERVAL_NETGEAR 1000 + +#define LED_WPS_BLINK_OFF_INTERVAL_NETGEAR 100 +#define LED_WPS_BLINK_ON_INTERVAL_NETGEAR 500 + +//Belkin AC950 +#define LED_BLINK_LINK_INTERVAL_ON_BELKIN 200 +#define LED_BLINK_LINK_INTERVAL_OFF_BELKIN 100 +#define LED_BLINK_ERROR_INTERVAL_BELKIN 100 + +//by chiyokolin for Azurewave +#define LED_CM12_BLINK_INTERVAL_5Mbps 160 +#define LED_CM12_BLINK_INTERVAL_10Mbps 80 +#define LED_CM12_BLINK_INTERVAL_20Mbps 50 +#define LED_CM12_BLINK_INTERVAL_40Mbps 40 +#define LED_CM12_BLINK_INTERVAL_80Mbps 30 +#define LED_CM12_BLINK_INTERVAL_MAXMbps 25 + +//Dlink +#define LED_BLINK_NO_LINK_INTERVAL 1000 +#define LED_BLINK_LINK_IDEL_INTERVAL 100 + +#define LED_BLINK_SCAN_ON_INTERVAL 30 +#define LED_BLINK_SCAN_OFF_INTERVAL 300 + +#define LED_WPS_BLINK_ON_INTERVAL_DLINK 30 +#define LED_WPS_BLINK_OFF_INTERVAL_DLINK 300 +#define LED_WPS_BLINK_LINKED_ON_INTERVAL_DLINK 5000 + +//================================================================================ +// LED object. +//================================================================================ + +typedef enum _LED_CTL_MODE{ + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, + LED_CTL_START_WPS_BOTTON = 11, //added for runtop + LED_CTL_STOP_WPS_FAIL = 12, //added for ALPHA + LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, //added for BELKIN + LED_CTL_CONNECTION_NO_TRANSFER = 14, +}LED_CTL_MODE; + +typedef enum _LED_STATE{ + LED_UNKNOWN = 0, + RTW_LED_ON = 1, + RTW_LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_BLINK_POWER_ON = 5, + LED_BLINK_SCAN = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning. + LED_BLINK_NO_LINK = 7, // LED is blinking during no link state. + LED_BLINK_StartToBlink = 8, // Customzied for Sercomm Printer Server case + LED_BLINK_TXRX = 9, + LED_BLINK_WPS = 10, // LED is blinkg during WPS communication + LED_BLINK_WPS_STOP = 11, //for ALPHA + LED_BLINK_WPS_STOP_OVERLAP = 12, //for BELKIN + LED_BLINK_RUNTOP = 13, // Customized for RunTop + LED_BLINK_CAMEO = 14, + LED_BLINK_XAVI = 15, + LED_BLINK_ALWAYS_ON = 16, + LED_BLINK_LINK_IN_PROCESS = 17, //Customized for Belkin AC950 + LED_BLINK_AUTH_ERROR = 18, //Customized for Belkin AC950 + LED_BLINK_Azurewave_5Mbps = 19, + LED_BLINK_Azurewave_10Mbps = 20, + LED_BLINK_Azurewave_20Mbps = 21, + LED_BLINK_Azurewave_40Mbps = 22, + LED_BLINK_Azurewave_80Mbps = 23, + LED_BLINK_Azurewave_MAXMbps = 24, + LED_BLINK_LINK_IDEL = 25, + LED_BLINK_WPS_LINKED = 26, +}LED_STATE; + +typedef enum _LED_PIN{ + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}LED_PIN; + + +//================================================================================ +// PCIE LED Definition. +//================================================================================ +#ifdef CONFIG_PCI_HCI +typedef enum _LED_STRATEGY_PCIE{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // SW control for PCI Express + SW_LED_MODE2, // SW control for Cameo. + SW_LED_MODE3, // SW contorl for RunTop. + SW_LED_MODE4, // SW control for Netcore + SW_LED_MODE5, //added by vivi, for led new mode, DLINK + SW_LED_MODE6, //added by vivi, for led new mode, PRONET + SW_LED_MODE7, //added by chiyokolin, for Lenovo, PCI Express Minicard Spec Rev.1.2 spec + SW_LED_MODE8, //added by chiyokolin, for QMI + SW_LED_MODE9, //added by chiyokolin, for BITLAND-LENOVO, PCI Express Minicard Spec Rev.1.1 + SW_LED_MODE10, //added by chiyokolin, for Edimax-ASUS + SW_LED_MODE11, //added by hpfan, for Xavi + SW_LED_MODE12, //added by chiyokolin, for Azurewave + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) +}LED_STRATEGY_PCIE, *PLED_STRATEGY_PCIE; + +typedef struct _LED_PCIE{ + PADAPTER padapter; + + LED_PIN LedPin; // Identify how to implement this SW led. + + LED_STATE CurrLedState; // Current LED state. + BOOLEAN bLedOn; // TRUE if LED is ON, FALSE if LED is OFF. + + BOOLEAN bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + BOOLEAN bLedWPSBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + + BOOLEAN bLedSlowBlinkInProgress;//added by vivi, for led new mode + u32 BlinkTimes; // Number of times to toggle led state for blinking. + LED_STATE BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are. + + _timer BlinkTimer; // Timer object for led blinking. +} LED_PCIE, *PLED_PCIE; + +typedef struct _LED_PCIE LED_DATA, *PLED_DATA; +typedef enum _LED_STRATEGY_PCIE LED_STRATEGY, *PLED_STRATEGY; + +VOID +LedControlPCIE( + IN PADAPTER Adapter, + IN LED_CTL_MODE LedAction + ); + +VOID +gen_RefreshLedState( + IN PADAPTER Adapter); + +//================================================================================ +// USB LED Definition. +//================================================================================ +#elif defined(CONFIG_USB_HCI) + +#define IS_LED_WPS_BLINKING(_LED_USB) (((PLED_USB)_LED_USB)->CurrLedState==LED_BLINK_WPS \ + || ((PLED_USB)_LED_USB)->CurrLedState==LED_BLINK_WPS_STOP \ + || ((PLED_USB)_LED_USB)->bLedWPSBlinkInProgress) + +#define IS_LED_BLINKING(_LED_USB) (((PLED_USB)_LED_USB)->bLedWPSBlinkInProgress \ + ||((PLED_USB)_LED_USB)->bLedScanBlinkInProgress) + + +typedef enum _LED_STRATEGY_USB{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. + SW_LED_MODE4, //for Edimax / Belkin + SW_LED_MODE5, //for Sercomm / Belkin + SW_LED_MODE6, //for 88CU minicard, porting from ce SW_LED_MODE7 + SW_LED_MODE7, //for Netgear special requirement + SW_LED_MODE8, //for LC + SW_LED_MODE9, //for Belkin AC950 + SW_LED_MODE10, //for Netgear A6200V2 + SW_LED_MODE11, //for Edimax / ASUS + SW_LED_MODE12, //for WNC/NEC + SW_LED_MODE13, //for Netgear A6100, 8811Au + SW_LED_MODE14, //for Buffalo, DNI, 8811Au + SW_LED_MODE15, //for DLINK, 8811Au/8812AU + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) +}LED_STRATEGY_USB, *PLED_STRATEGY_USB; + + +typedef struct _LED_USB{ + PADAPTER padapter; + + LED_PIN LedPin; // Identify how to implement this SW led. + + LED_STATE CurrLedState; // Current LED state. + BOOLEAN bLedOn; // TRUE if LED is ON, FALSE if LED is OFF. + + BOOLEAN bSWLedCtrl; + + BOOLEAN bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + // ALPHA, added by chiyoko, 20090106 + BOOLEAN bLedNoLinkBlinkInProgress; + BOOLEAN bLedLinkBlinkInProgress; + BOOLEAN bLedStartToLinkBlinkInProgress; + BOOLEAN bLedScanBlinkInProgress; + BOOLEAN bLedWPSBlinkInProgress; + + u32 BlinkTimes; // Number of times to toggle led state for blinking. + u8 BlinkCounter; //Added for turn off overlap led after blinking a while, by page, 20120821 + LED_STATE BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are. + + _timer BlinkTimer; // Timer object for led blinking. + + _workitem BlinkWorkItem; // Workitem used by BlinkTimer to manipulate H/W to blink LED.' + ATOMIC_T bCancelWorkItem; //check if WorkItem is cancelled +} LED_USB, *PLED_USB; + +typedef struct _LED_USB LED_DATA, *PLED_DATA; +typedef enum _LED_STRATEGY_USB LED_STRATEGY, *PLED_STRATEGY; + +VOID +LedControlUSB( + IN PADAPTER Adapter, + IN LED_CTL_MODE LedAction + ); + + +//================================================================================ +// SDIO LED Definition. +//================================================================================ +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#define IS_LED_WPS_BLINKING(_LED_SDIO) (((PLED_SDIO)_LED_SDIO)->CurrLedState==LED_BLINK_WPS \ + || ((PLED_SDIO)_LED_SDIO)->CurrLedState==LED_BLINK_WPS_STOP \ + || ((PLED_SDIO)_LED_SDIO)->bLedWPSBlinkInProgress) + +#define IS_LED_BLINKING(_LED_SDIO) (((PLED_SDIO)_LED_SDIO)->bLedWPSBlinkInProgress \ + ||((PLED_SDIO)_LED_SDIO)->bLedScanBlinkInProgress) + + +typedef enum _LED_STRATEGY_SDIO{ + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. + SW_LED_MODE4, //for Edimax / Belkin + SW_LED_MODE5, //for Sercomm / Belkin + SW_LED_MODE6, //for 88CU minicard, porting from ce SW_LED_MODE7 + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) +}LED_STRATEGY_SDIO, *PLED_STRATEGY_SDIO; + +typedef struct _LED_SDIO{ + PADAPTER padapter; + + LED_PIN LedPin; // Identify how to implement this SW led. + + LED_STATE CurrLedState; // Current LED state. + BOOLEAN bLedOn; // TRUE if LED is ON, FALSE if LED is OFF. + + BOOLEAN bSWLedCtrl; + + BOOLEAN bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w.. + // ALPHA, added by chiyoko, 20090106 + BOOLEAN bLedNoLinkBlinkInProgress; + BOOLEAN bLedLinkBlinkInProgress; + BOOLEAN bLedStartToLinkBlinkInProgress; + BOOLEAN bLedScanBlinkInProgress; + BOOLEAN bLedWPSBlinkInProgress; + + u32 BlinkTimes; // Number of times to toggle led state for blinking. + LED_STATE BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are. + + _timer BlinkTimer; // Timer object for led blinking. + + _workitem BlinkWorkItem; // Workitem used by BlinkTimer to manipulate H/W to blink LED. +} LED_SDIO, *PLED_SDIO; + +typedef struct _LED_SDIO LED_DATA, *PLED_DATA; +typedef enum _LED_STRATEGY_SDIO LED_STRATEGY, *PLED_STRATEGY; + +VOID +LedControlSDIO( + IN PADAPTER Adapter, + IN LED_CTL_MODE LedAction + ); + +#endif + +struct led_priv{ + /* add for led controll */ + LED_DATA SwLed0; + LED_DATA SwLed1; + LED_DATA SwLed2; + LED_STRATEGY LedStrategy; + u8 bRegUseLed; + void (*LedControlHandler)(_adapter *padapter, LED_CTL_MODE LedAction); + void (*SwLedOn)(_adapter *padapter, PLED_DATA pLed); + void (*SwLedOff)(_adapter *padapter, PLED_DATA pLed); + /* add for led controll */ +}; + +#ifdef CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) \ + do { \ + if((adapter)->ledpriv.LedControlHandler) \ + (adapter)->ledpriv.LedControlHandler((adapter), (LedAction)); \ + } while(0) +#else //CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) +#endif //CONFIG_SW_LED + +#define SwLedOn(adapter, pLed) \ + do { \ + if((adapter)->ledpriv.SwLedOn) \ + (adapter)->ledpriv.SwLedOn((adapter), (pLed)); \ + } while(0) + +#define SwLedOff(adapter, pLed) \ + do { \ + if((adapter)->ledpriv.SwLedOff) \ + (adapter)->ledpriv.SwLedOff((adapter), (pLed)); \ + } while(0) + +void BlinkTimerCallback(void *data); +void BlinkWorkItemCallback(_workitem *work); + +void ResetLedStatus(PLED_DATA pLed); + +void +InitLed( + _adapter *padapter, + PLED_DATA pLed, + LED_PIN LedPin + ); + +void +DeInitLed( + PLED_DATA pLed + ); + +//hal... +extern void BlinkHandler(PLED_DATA pLed); + +#endif //__RTW_LED_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_phycfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_phycfg.h new file mode 100644 index 00000000..a765d6c5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_phycfg.h @@ -0,0 +1,285 @@ +/****************************************************************************** + * + * 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 __HAL_COM_PHYCFG_H__ +#define __HAL_COM_PHYCFG_H__ + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +typedef enum _RF_TX_NUM { + RF_1TX = 0, + RF_2TX, + RF_3TX, + RF_4TX, + RF_MAX_TX_NUM, + RF_TX_NUM_NONIMPLEMENT, +} RF_TX_NUM; + +#define MAX_POWER_INDEX 0x3F + +typedef enum _REGULATION_TXPWR_LMT { + TXPWR_LMT_FCC = 0, + TXPWR_LMT_MKK = 1, + TXPWR_LMT_ETSI = 2, + TXPWR_LMT_WW = 3, + + TXPWR_LMT_MAX_REGULATION_NUM = 4 +} REGULATION_TXPWR_LMT; + +#define TX_PWR_LMT_REF_VHT_FROM_HT BIT0 +#define TX_PWR_LMT_REF_HT_FROM_VHT BIT1 + +/*------------------------------Define structure----------------------------*/ +typedef struct _BB_REGISTER_DEFINITION{ + u32 rfintfs; // set software control: + // 0x870~0x877[8 bytes] + + u32 rfintfo; // output data: + // 0x860~0x86f [16 bytes] + + u32 rfintfe; // output enable: + // 0x860~0x86f [16 bytes] + + u32 rf3wireOffset; // LSSI data: + // 0x840~0x84f [16 bytes] + + u32 rfHSSIPara2; // wire parameter control2 : + // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] + + u32 rfLSSIReadBack; //LSSI RF readback data SI mode + // 0x8a0~0x8af [16 bytes] + + u32 rfLSSIReadBackPi; //LSSI RF readback data PI mode 0x8b8-8bc for Path A and B + +}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; + + +//---------------------------------------------------------------------- +u8 +PHY_GetTxPowerByRateBase( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN u8 TxNum, + IN RATE_SECTION RateSection + ); + +#ifdef TX_POWER_BY_RATE_OLD +u8 +PHY_GetRateSectionIndexOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask + ); +#endif /* TX_POWER_BY_RATE_OLD */ + +VOID +PHY_GetRateValuesOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Value, + OUT u8 *Rate, + OUT s8 *PwrByRateVal, + OUT u8 *RateNum + ); + +u8 +PHY_GetRateIndexOfTxPowerByRate( + IN u8 Rate + ); + +VOID +PHY_SetTxPowerIndexByRateSection( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Channel, + IN u8 RateSection + ); + +s8 +_PHY_GetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 RateIndex + ); + +s8 +PHY_GetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 RateIndex + ); + +VOID +PHY_SetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 Rate, + IN s8 Value + ); + +VOID +PHY_SetTxPowerLevelByPath( + IN PADAPTER Adapter, + IN u8 channel, + IN u8 path + ); + +VOID +PHY_SetTxPowerIndexByRateArray( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + IN u8* Rates, + IN u8 RateArraySize + ); + +VOID +PHY_InitTxPowerByRate( + IN PADAPTER pAdapter + ); + +VOID +PHY_StoreTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 Band, + IN u32 RfPath, + IN u32 TxNum, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +VOID +PHY_TxPowerByRateConfiguration( + IN PADAPTER pAdapter + ); + +u8 +PHY_GetTxPowerIndexBase( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + OUT PBOOLEAN bIn24G + ); + +s8 +PHY_GetTxPowerLimit( + IN PADAPTER Adapter, + IN u32 RegPwrTblSel, + IN BAND_TYPE Band, + IN CHANNEL_WIDTH Bandwidth, + IN u8 RfPath, + IN u8 DataRate, + IN u8 Channel + ); + +VOID +PHY_ConvertTxPowerLimitToPowerIndex( + IN PADAPTER Adapter + ); + +VOID +PHY_InitTxPowerLimit( + IN PADAPTER Adapter + ); + +s8 +PHY_GetTxPowerTrackingOffset( + PADAPTER pAdapter, + u8 Rate, + u8 RFPath + ); + +u8 +PHY_GetTxPowerIndex( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_SetTxPowerIndex( + IN PADAPTER pAdapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +bool phy_is_tx_power_limit_needed(_adapter *adapter); +bool phy_is_tx_power_by_rate_needed(_adapter *adapter); +int phy_load_tx_power_by_rate(_adapter *adapter, const char *hal_file_name, u8 force); +int phy_load_tx_power_limit(_adapter *adapter, const char *hal_file_name, u8 force); +void phy_load_tx_power_ext_info(_adapter *adapter, u8 chk_file, u8 force); +void phy_reload_tx_power_ext_info(_adapter *adapter); +void phy_reload_default_tx_power_ext_info(_adapter *adapter); + +void dump_tx_power_ext_info(void *sel, _adapter *adapter); +void dump_target_tx_power(void *sel, _adapter *adapter); +void dump_tx_power_by_rate(void *sel, _adapter *adapter); +void dump_tx_power_limit(void *sel, _adapter *adapter); + +int rtw_is_phy_file_readable(const char *hal_file_name); + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +#define MAX_PARA_FILE_BUF_LEN 25600 + +#define LOAD_MAC_PARA_FILE BIT0 +#define LOAD_BB_PARA_FILE BIT1 +#define LOAD_BB_PG_PARA_FILE BIT2 +#define LOAD_BB_MP_PARA_FILE BIT3 +#define LOAD_RF_PARA_FILE BIT4 +#define LOAD_RF_TXPWR_TRACK_PARA_FILE BIT5 +#define LOAD_RF_TXPWR_LMT_PARA_FILE BIT6 + +int phy_ConfigMACWithParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int phy_ConfigBBWithParaFile(IN PADAPTER Adapter, IN char* pFileName, IN u32 ConfigType); + +int phy_ConfigBBWithPgParaFile(IN PADAPTER Adapter, IN const char *pFileName); + +int phy_ConfigBBWithMpParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int PHY_ConfigRFWithParaFile(IN PADAPTER Adapter, IN char* pFileName, IN u8 eRFPath); + +int PHY_ConfigRFWithTxPwrTrackParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int PHY_ConfigRFWithPowerLimitTableParaFile(IN PADAPTER Adapter, IN const char *pFileName); + +void phy_free_filebuf_mask(_adapter *padapter, u8 mask); +void phy_free_filebuf(_adapter *padapter); +#endif /* CONFIG_LOAD_PHY_PARA_FROM_FILE */ + +#endif /* __HAL_COMMON_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_reg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_reg.h new file mode 100644 index 00000000..0548729d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_com_reg.h @@ -0,0 +1,1780 @@ +/****************************************************************************** + * + * 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 __HAL_COMMON_REG_H__ +#define __HAL_COMMON_REG_H__ + + +#define MAC_ADDR_LEN 6 + +#define HAL_NAV_UPPER_UNIT 128 // micro-second + +// 8188E PKT_BUFF_ACCESS_CTRL value +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_SYS_CLK_CTRL REG_SYS_CLKR +#define REG_9346CR 0x000A +#define REG_SYS_EEPROM_CTRL 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS0_CTRL_6 0x0016 +#define REG_POWER_OFF_IN_PROCESS 0x0017 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_LDO_CTRL 0x0027 // 1.5v for 8188EE test chip, 1.4v for MP chip +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002c //for 92d, DMDP,SMSP,DMSP contrl +#define REG_APE_PLL_CTRL_EXT 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. +#define REG_GPIO_IO_SEL_2 0x0062 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. +#define REG_MULTI_FUNC_CTRL 0x0068 // RTL8723 WIFI/BT/GPS Multi-Function control source. +#define REG_GSSR 0x006c +#define REG_AFE_XTAL_CTRL_EXT 0x0078 //RTL8188E +#define REG_XCK_OUT_CTRL 0x007c //RTL8188E +#define REG_MCUFWDL 0x0080 +#define REG_WOL_EVENT 0x0081 //RTL8188E +#define REG_MCUTSTCFG 0x0084 +#define REG_FDHM0 0x0088 +#define REG_HOST_SUSP_CNT 0x00BC // RTL8192C Host suspend counter on FPGA platform +#define REG_SYSTEM_ON_CTRL 0x00CC // For 8723AE Reset after S3 +#define REG_EFUSE_ACCESS 0x00CF // Efuse access protection for RTL8723 +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 // For RTL8723 only. +#define REG_TYPE_ID 0x00FC + +// +// 2010/12/29 MH Add for 92D +// +#define REG_MAC_PHY_CTRL_NORMAL 0x00f8 + + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTIMR 0x0138 +#define REG_FTISR 0x013C //RTL8192C +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_32K_CTRL 0x0194 //RTL8188E +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_MCUTST_1 0x01c0 +#define REG_MCUTST_WOWLAN 0x01C7 // Defined after 8188E series. +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC +#define REG_LLT_INIT 0x01E0 +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 +#define REG_AUTO_LLT 0x0224 + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 /* Interrupt Migration */ +#define REG_BCNQ_DESA 0x0308 /* TX Beacon Descriptor Address */ +#define REG_HQ_DESA 0x0310 /* TX High Queue Descriptor Address */ +#define REG_MGQ_DESA 0x0318 /* TX Manage Queue Descriptor Address */ +#define REG_VOQ_DESA 0x0320 /* TX VO Queue Descriptor Address */ +#define REG_VIQ_DESA 0x0328 /* TX VI Queue Descriptor Address */ +#define REG_BEQ_DESA 0x0330 /* TX BE Queue Descriptor Address */ +#define REG_BKQ_DESA 0x0338 /* TX BK Queue Descriptor Address */ +#define REG_RX_DESA 0x0340 /* RX Queue Descriptor Address */ +//sherry added for DBI Read/Write 20091126 +#define REG_DBI_WDATA 0x0348 /* Backdoor REG for Access Configuration */ +#define REG_DBI_RDATA 0x034C /* Backdoor REG for Access Configuration */ +#define REG_DBI_CTRL 0x0350 /* Backdoor REG for Access Configuration */ +#define REG_DBI_FLAG 0x0352 /* Backdoor REG for Access Configuration */ +#define REG_MDIO 0x0354 /* MDIO for Access PCIE PHY */ +#define REG_DBG_SEL 0x0360 /* Debug Selection Register */ +#define REG_PCIE_HRPWM 0x0361 /* PCIe RPWM */ +#define REG_PCIE_HCPWM 0x0363 /* PCIe CPWM */ +#define REG_WATCH_DOG 0x0368 +#define REG_RX_RXBD_NUM 0x0382 + +// RTL8723 series ------------------------------- +#define REG_PCIE_HISR_EN 0x0394 /* PCIE Local Interrupt Enable Register */ +#define REG_PCIE_HISR 0x03A0 +#define REG_PCIE_HISRE 0x03A4 +#define REG_PCIE_HIMR 0x03A8 +#define REG_PCIE_HIMRE 0x03AC + +#define REG_USB_HIMR 0xFE38 +#define REG_USB_HIMRE 0xFE3C +#define REG_USB_HISR 0xFE78 +#define REG_USB_HISRE 0xFE7C + + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- + +/* 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 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_BCNQ_BDNY 0x0424 +#define REG_MGQ_BDNY 0x0425 +#define REG_LIFETIME_CTRL 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_BCNQ1_BDNY 0x0457 + +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_WMAC_LBK_BF_HD 0x045D +#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 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_QUEUE_CTRL 0x04C6 +#define REG_SINGLE_AMPDU_CTRL 0x04c7 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF + +/* 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 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 // 2 byte +#define REG_DUMMY 0x04FC + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_TSFTR_SYN_OFFSET 0x0518 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 // The same as REG_MBSSID_BCN_SPACE +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_TSFTR1 0x0568 // HW Port 1 TSF Register +#define REG_ATIMWND_1 0x0570 +#define REG_P2P_CTWIN 0x0572 // 1 Byte long (in unit of TU) +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_NOA_DESC_SEL 0x05CF +#define REG_NOA_DESC_DURATION 0x05E0 +#define REG_NOA_DESC_INTERVAL 0x05E4 +#define REG_NOA_DESC_START 0x05E8 +#define REG_NOA_DESC_COUNT 0x05EC + +#define REG_DMC 0x05F0 //Dual MAC Co-Existence Register +#define REG_SCH_TX_CMD 0x05F8 + +#define REG_FW_RESET_TSF_CNT_1 0x05FC +#define REG_FW_RESET_TSF_CNT_0 0x05FD +#define REG_FW_BCN_DIS_CNT 0x05FE + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_PNO_STATUS 0x0631 +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +// 20100719 Joseph: Hardware register definition change. (HW datasheet v54) +#define REG_RESP_SIFS_CCK 0x063C // [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK +#define REG_RESP_SIFS_OFDM 0x063E // [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK + +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + + +//RXERR_RPT +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +// +// Note: +// The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. The default value is +// always too small, but the WiFi TestPlan test by 25,000 microseconds of NAV through sending +// CTS in the air. We must update this value greater than 25,000 microseconds to pass the item. +// The offset of NAV_UPPER in 8192C Spec is incorrect, and the offset should be 0x0652. Commented +// by SD1 Scott. +// By Bruce, 2011-07-18. +// +#define REG_NAV_UPPER 0x0652 // unit of 128 + +//WMA, BA, CCX +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +// Security +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +// Power +#define REG_WOW_CTRL 0x0690 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_NUM REG_WKFMCAM_CMD +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_BT_COEX_TABLE 0x06C0 + +// Hardware Port 2 +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +// for 92DU high_Queue low_Queue Normal_Queue select +#define REG_USB_High_NORMAL_Queue_Select_MAC0 0xFE44 +//#define REG_USB_LOW_Queue_Select_MAC0 0xFE45 +#define REG_USB_High_NORMAL_Queue_Select_MAC1 0xFE47 +//#define REG_USB_LOW_Queue_Select_MAC1 0xFE48 + +// For test chip +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_TEST_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 // 0xFE66~0xFE6B +#define REG_TEST_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_TEST_SIE_STRING 0xFE80 // 0xFE80~0xFEB9 + + +// For normal chip +#define REG_NORMAL_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_NORMAL_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 // 0xFE65~0xFE67 +#define REG_NORMAL_SIE_PHY 0xFE68 // 0xFE68~0xFE6B +#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C +#define REG_NORMAL_SIE_GPS_EP 0xFE6D // 0xFE6D, for RTL8723 only. +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_NORMAL_SIE_STRING 0xFE80 // 0xFE80~0xFEDF + + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. + +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +#define EFUSE_TEST REG_EFUSE_TEST // E-Fuse Test. +#define MSR (REG_CR + 2) // Media Status register +//#define ISR REG_HISR + +#define TSFR REG_TSFTR // Timing Sync Function Timer Register. +#define TSFR1 REG_TSFTR1 // HW Port 1 TSF Register + +#define PBP REG_PBP + +// Redifine MACID register, to compatible prior ICs. +#define IDR0 REG_MACID // MAC ID Register, Offset 0x0050-0x0053 +#define IDR4 (REG_MACID + 4) // MAC ID Register, Offset 0x0054-0x0055 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM REG_CAMCMD //IN 8190 Data Sheet is called CAMcmd +#define WCAMI REG_CAMWRITE // Software write CAM input content +#define RCAMO REG_CAMREAD // Software read/write CAM config +#define CAMDBG REG_CAMDBG +#define SECR REG_SECCFG //Security Configuration Register + +// Unused register +#define UnusedRegister 0x1BF +#define DCAM UnusedRegister +#define PSR UnusedRegister +#define BBAddr UnusedRegister +#define PhyDataR UnusedRegister + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +//---------------------------------------------------------------------------- +// 8192C Cmd9346CR bits (Offset 0xA, 16bit) +//---------------------------------------------------------------------------- +#define CmdEEPROM_En BIT5 // EEPROM enable when set 1 +#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 +#define Cmd9346CR_9356SEL BIT4 + +//---------------------------------------------------------------------------- +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +//---------------------------------------------------------------------------- +// 8811A GPIO PIN Control Register (offset 0x60, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN_8811A REG_GPIO_PIN_CTRL_2 // GPIO pins input value +#define GPIO_OUT_8811A (REG_GPIO_PIN_CTRL_2+1) // GPIO pins output value +#define GPIO_IO_SEL_8811A (REG_GPIO_PIN_CTRL_2+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD_8811A (REG_GPIO_PIN_CTRL_2+3) + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) +//---------------------------------------------------------------------------- +#define HSIMR_GPIO12_0_INT_EN BIT0 +#define HSIMR_SPS_OCP_INT_EN BIT5 +#define HSIMR_RON_INT_EN BIT6 +#define HSIMR_PDN_INT_EN BIT7 +#define HSIMR_GPIO9_INT_EN BIT25 + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) +//---------------------------------------------------------------------------- +#define HSISR_GPIO12_0_INT BIT0 +#define HSISR_SPS_OCP_INT BIT5 +#define HSISR_RON_INT BIT6 +#define HSISR_PDNINT BIT7 +#define HSISR_GPIO9_INT BIT25 + +//---------------------------------------------------------------------------- +// 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +/* +Network Type +00: No link +01: Link in ad hoc network +10: Link in infrastructure network +11: AP mode +Default: 00b. +*/ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +//---------------------------------------------------------------------------- +// USB INTR CONTENT +//---------------------------------------------------------------------------- +#define USB_C2H_CMDID_OFFSET 0 +#define USB_C2H_SEQ_OFFSET 1 +#define USB_C2H_EVENT_OFFSET 2 +#define USB_INTR_CPWM_OFFSET 16 +#define USB_INTR_CONTENT_C2H_OFFSET 0 +#define USB_INTR_CONTENT_CPWM1_OFFSET 16 +#define USB_INTR_CONTENT_CPWM2_OFFSET 20 +#define USB_INTR_CONTENT_HISR_OFFSET 48 +#define USB_INTR_CONTENT_HISRE_OFFSET 52 +#define USB_INTR_CONTENT_LENGTH 56 + +//---------------------------------------------------------------------------- +// Response Rate Set Register (offset 0x440, 24bits) +//---------------------------------------------------------------------------- +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 + +#define RRSR_CCK_RATES (RRSR_11M|RRSR_5_5M|RRSR_2M|RRSR_1M) +#define RRSR_OFDM_RATES (RRSR_54M|RRSR_48M|RRSR_36M|RRSR_24M|RRSR_18M|RRSR_12M|RRSR_9M|RRSR_6M) + +// WOL bit information +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT0 +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT1 +#define HAL92C_WOL_DISASSOC_EVENT BIT2 +#define HAL92C_WOL_DEAUTH_EVENT BIT3 +#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT4 + +//---------------------------------------------------------------------------- +// Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +//CCK +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +//OFDM +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +//MCS 1 Spatial Stream +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +//MCS 2 Spatial Stream +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + + +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\ + RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + +#define RATE_BITMAP_ALL 0xFFFFF + +// Only use CCK 1M rate for ACK +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 +#define RATE_RRSR_WITHOUT_CCK 0xFFFF0 + +//---------------------------------------------------------------------------- +// BW_OPMODE bits (Offset 0x603, 8bit) +//---------------------------------------------------------------------------- +#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_5G BIT1 + +//---------------------------------------------------------------------------- +// CAM Config Setting (offset 0x680, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID BIT15 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT5 + +#define CAM_CONTENT_COUNT 8 + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_CONFIG_USEDK _TRUE +#define CAM_CONFIG_NO_USEDK _FALSE + +#define CAM_WRITE BIT16 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT31 + +// +// 10. Power Save Control Registers +// +#define WOW_PMEN BIT0 // Power management Enable. +#define WOW_WOMEN BIT1 // WoW function on or off. +#define WOW_MAGIC BIT2 // Magic packet +#define WOW_UWF BIT3 // Unicast Wakeup frame. + +// +// 12. Host Interrupt Status Registers +// +//---------------------------------------------------------------------------- +// 8190 IMR/ISR bits +//---------------------------------------------------------------------------- +#define IMR8190_DISABLED 0x0 +#define IMR_DISABLED 0x0 +// IMR DW0 Bit 0-31 +#define IMR_BCNDMAINT6 BIT31 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5 BIT30 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4 BIT29 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3 BIT28 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2 BIT27 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1 BIT26 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK8 BIT25 // Beacon Queue DMA OK Interrup 8 +#define IMR_BCNDOK7 BIT24 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6 BIT23 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5 BIT22 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4 BIT21 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3 BIT20 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2 BIT19 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1 BIT18 // Beacon Queue DMA OK Interrup 1 +#define IMR_TIMEOUT2 BIT17 // Timeout interrupt 2 +#define IMR_TIMEOUT1 BIT16 // Timeout interrupt 1 +#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow +#define IMR_PSTIMEOUT BIT14 // Power save time out interrupt +#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 +#define IMR_RXFOVW BIT12 // Receive FIFO Overflow +#define IMR_RDU BIT11 // Receive Descriptor Unavailable +#define IMR_ATIMEND BIT10 // For 92C,ATIM Window End Interrupt. For 8723 and later ICs, it also means P2P CTWin End interrupt. +#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup +#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt +#define IMR_TBDOK BIT7 // Transmit Beacon OK interrup +#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define IMR_TBDER BIT5 // For 92C,Transmit Beacon Error Interrupt +#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt +#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt +#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt +#define IMR_VODOK BIT1 // AC_VO DMA Interrupt +#define IMR_ROK BIT0 // Receive DMA OK Interrupt + +// 13. Host Interrupt Status Extension Register (Offset: 0x012C-012Eh) +#define IMR_TSF_BIT32_TOGGLE BIT15 +#define IMR_BcnInt_E BIT12 +#define IMR_TXERR BIT11 +#define IMR_RXERR BIT10 +#define IMR_C2HCMD BIT9 +#define IMR_CPWM BIT8 +//RSVD [2-7] +#define IMR_OCPINT BIT1 +#define IMR_WLANOFF BIT0 + +//---------------------------------------------------------------------------- +// 8723E series PCIE Host IMR/ISR bit +//---------------------------------------------------------------------------- +// IMR DW0 Bit 0-31 +#define PHIMR_TIMEOUT2 BIT31 +#define PHIMR_TIMEOUT1 BIT30 +#define PHIMR_PSTIMEOUT BIT29 +#define PHIMR_GTINT4 BIT28 +#define PHIMR_GTINT3 BIT27 +#define PHIMR_TXBCNERR BIT26 +#define PHIMR_TXBCNOK BIT25 +#define PHIMR_TSF_BIT32_TOGGLE BIT24 +#define PHIMR_BCNDMAINT3 BIT23 +#define PHIMR_BCNDMAINT2 BIT22 +#define PHIMR_BCNDMAINT1 BIT21 +#define PHIMR_BCNDMAINT0 BIT20 +#define PHIMR_BCNDOK3 BIT19 +#define PHIMR_BCNDOK2 BIT18 +#define PHIMR_BCNDOK1 BIT17 +#define PHIMR_BCNDOK0 BIT16 +#define PHIMR_HSISR_IND_ON BIT15 +#define PHIMR_BCNDMAINT_E BIT14 +#define PHIMR_ATIMEND_E BIT13 +#define PHIMR_ATIM_CTW_END BIT12 +#define PHIMR_HISRE_IND BIT11 // RO. HISRE Indicator (HISRE & HIMRE is true, this bit is set to 1) +#define PHIMR_C2HCMD BIT10 +#define PHIMR_CPWM2 BIT9 +#define PHIMR_CPWM BIT8 +#define PHIMR_HIGHDOK BIT7 // High Queue DMA OK Interrupt +#define PHIMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define PHIMR_BKDOK BIT5 // AC_BK DMA OK Interrupt +#define PHIMR_BEDOK BIT4 // AC_BE DMA OK Interrupt +#define PHIMR_VIDOK BIT3 // AC_VI DMA OK Interrupt +#define PHIMR_VODOK BIT2 // AC_VO DMA Interrupt +#define PHIMR_RDU BIT1 // Receive Descriptor Unavailable +#define PHIMR_ROK BIT0 // Receive DMA OK Interrupt + +// PCIE Host Interrupt Status Extension bit +#define PHIMR_BCNDMAINT7 BIT23 +#define PHIMR_BCNDMAINT6 BIT22 +#define PHIMR_BCNDMAINT5 BIT21 +#define PHIMR_BCNDMAINT4 BIT20 +#define PHIMR_BCNDOK7 BIT19 +#define PHIMR_BCNDOK6 BIT18 +#define PHIMR_BCNDOK5 BIT17 +#define PHIMR_BCNDOK4 BIT16 +// bit12 15: RSVD +#define PHIMR_TXERR BIT11 +#define PHIMR_RXERR BIT10 +#define PHIMR_TXFOVW BIT9 +#define PHIMR_RXFOVW BIT8 +// bit2-7: RSVD +#define PHIMR_OCPINT BIT1 +// bit0: RSVD + +#define UHIMR_TIMEOUT2 BIT31 +#define UHIMR_TIMEOUT1 BIT30 +#define UHIMR_PSTIMEOUT BIT29 +#define UHIMR_GTINT4 BIT28 +#define UHIMR_GTINT3 BIT27 +#define UHIMR_TXBCNERR BIT26 +#define UHIMR_TXBCNOK BIT25 +#define UHIMR_TSF_BIT32_TOGGLE BIT24 +#define UHIMR_BCNDMAINT3 BIT23 +#define UHIMR_BCNDMAINT2 BIT22 +#define UHIMR_BCNDMAINT1 BIT21 +#define UHIMR_BCNDMAINT0 BIT20 +#define UHIMR_BCNDOK3 BIT19 +#define UHIMR_BCNDOK2 BIT18 +#define UHIMR_BCNDOK1 BIT17 +#define UHIMR_BCNDOK0 BIT16 +#define UHIMR_HSISR_IND BIT15 +#define UHIMR_BCNDMAINT_E BIT14 +//RSVD BIT13 +#define UHIMR_CTW_END BIT12 +//RSVD BIT11 +#define UHIMR_C2HCMD BIT10 +#define UHIMR_CPWM2 BIT9 +#define UHIMR_CPWM BIT8 +#define UHIMR_HIGHDOK BIT7 // High Queue DMA OK Interrupt +#define UHIMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define UHIMR_BKDOK BIT5 // AC_BK DMA OK Interrupt +#define UHIMR_BEDOK BIT4 // AC_BE DMA OK Interrupt +#define UHIMR_VIDOK BIT3 // AC_VI DMA OK Interrupt +#define UHIMR_VODOK BIT2 // AC_VO DMA Interrupt +#define UHIMR_RDU BIT1 // Receive Descriptor Unavailable +#define UHIMR_ROK BIT0 // Receive DMA OK Interrupt + +// USB Host Interrupt Status Extension bit +#define UHIMR_BCNDMAINT7 BIT23 +#define UHIMR_BCNDMAINT6 BIT22 +#define UHIMR_BCNDMAINT5 BIT21 +#define UHIMR_BCNDMAINT4 BIT20 +#define UHIMR_BCNDOK7 BIT19 +#define UHIMR_BCNDOK6 BIT18 +#define UHIMR_BCNDOK5 BIT17 +#define UHIMR_BCNDOK4 BIT16 +// bit14-15: RSVD +#define UHIMR_ATIMEND_E BIT13 +#define UHIMR_ATIMEND BIT12 +#define UHIMR_TXERR BIT11 +#define UHIMR_RXERR BIT10 +#define UHIMR_TXFOVW BIT9 +#define UHIMR_RXFOVW BIT8 +// bit2-7: RSVD +#define UHIMR_OCPINT BIT1 +// bit0: RSVD + + +#define HAL_NIC_UNPLUG_ISR 0xFFFFFFFF // The value when the NIC is unplugged for PCI. +#define HAL_NIC_UNPLUG_PCI_ISR 0xEAEAEAEA // The value when the NIC is unplugged for PCI in PCI interrupt (page 3). + +//---------------------------------------------------------------------------- +// 8188 IMR/ISR bits +//---------------------------------------------------------------------------- +#define IMR_DISABLED_88E 0x0 +// IMR DW0(0x0060-0063) Bit 0-31 +#define IMR_TXCCK_88E BIT30 // TXRPT interrupt when CCX bit of the packet is set +#define IMR_PSTIMEOUT_88E BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_88E BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_88E BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TBDER_88E BIT26 // Transmit Beacon0 Error +#define IMR_TBDOK_88E BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_88E BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_88E BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_88E BIT16 // Beacon Queue DMA Error 0 +#define IMR_HSISR_IND_ON_INT_88E BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_88E BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_88E BIT12 // CTWidnow End or ATIM Window End +#define IMR_HISR1_IND_INT_88E BIT11 // HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1) +#define IMR_C2HCMD_88E BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_88E BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_88E BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_88E BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_88E BIT6 // Management Queue DMA OK +#define IMR_BKDOK_88E BIT5 // AC_BK DMA OK +#define IMR_BEDOK_88E BIT4 // AC_BE DMA OK +#define IMR_VIDOK_88E BIT3 // AC_VI DMA OK +#define IMR_VODOK_88E BIT2 // AC_VO DMA OK +#define IMR_RDU_88E BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_88E BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_88E BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_88E BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_88E BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_88E BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_88E BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_88E BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_88E BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_88E BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_88E BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_88E BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_88E BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_88E BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_88E BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_88E BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_88E BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_88E BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_88E BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_88E BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_88E BIT8 // Receive FIFO Overflow + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ + //---------------------------------------------------------------------------- + // 8192C (TXPAUSE) transmission pause (Offset 0x522, 8 bits) + //---------------------------------------------------------------------------- +// Note: +// The the bits of stoping AC(VO/VI/BE/BK) queue in datasheet RTL8192S/RTL8192C are wrong, +// the correct arragement is VO - Bit0, VI - Bit1, BE - Bit2, and BK - Bit3. +// 8723 and 88E may be not correct either in the eralier version. Confirmed with DD Tim. +// By Bruce, 2011-09-22. +#define StopBecon BIT6 +#define StopHigh BIT5 +#define StopMgt BIT4 +#define StopBK BIT3 +#define StopBE BIT2 +#define StopVI BIT1 +#define StopVO BIT0 + +//---------------------------------------------------------------------------- +// 8192C (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +#define RCR_APPFCS BIT31 // WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // MACRX will retain the MIC at the bottom of the packet. +#define RCR_APP_ICV BIT29 // MACRX will retain the ICV at the bottom of the packet. +#define RCR_APP_PHYST_RXFF BIT28 // PHY Status is appended before RX packet in RXFF +#define RCR_APP_BA_SSN BIT27 // SSN of previous TXBA is appended as after original RXDESC as the 4-th DW of RXDESC. +#define RCR_VHT_DACK BIT26 /* This bit to control response type for vht single mpdu data packet. 1. ACK as response 0. BA as response */ +#define RCR_TCPOFLD_EN BIT25 /* Enable TCP checksum offload */ +#define RCR_ENMBID BIT24 // Enable Multiple BssId. Only response ACK to the packets whose DID(A1) matching to the addresses in the MBSSID CAM Entries. +#define RCR_LSIGEN BIT23 // Enable LSIG TXOP Protection function. Search KEYCAM for each rx packet to check if LSIGEN bit is set. +#define RCR_MFBEN BIT22 // Enable immediate MCS Feedback function. When Rx packet with MRQ = 1'b1, then search KEYCAM to find sender's MCS Feedback function and send response. +#define RCR_DISCHKPPDLLEN BIT21 /* Do not check PPDU while the PPDU length is smaller than 14 byte. */ +#define RCR_PKTCTL_DLEN BIT20 /* While rx path dead lock occurs, reset rx path */ +#define RCR_DISGCLK BIT19 /* Disable macrx clock gating control (no used) */ +#define RCR_TIM_PARSER_EN BIT18 // RX Beacon TIM Parser. +#define RCR_BC_MD_EN BIT17 /* Broadcast data packet more data bit check interrupt enable.*/ +#define RCR_UC_MD_EN BIT16 /* Unicast data packet more data bit check interrupt enable. */ +#define RCR_RXSK_PERPKT BIT15 /* Executing key search per MPDU */ +#define RCR_HTC_LOC_CTRL BIT14 // MFC<--HTC=1 MFC-->HTC=0 +#define RCR_AMF BIT13 // Accept management type frame +#define RCR_ACF BIT12 // Accept control type frame. Control frames BA, BAR, and PS-Poll (when in AP mode) are not controlled by this bit. They are controlled by ADF. +#define RCR_ADF BIT11 // Accept data type frame. This bit also regulates BA, BAR, and PS-Poll (AP mode only). +#define RCR_DISDECMYPKT BIT10 /* This bit determines whether hw need to do decryption.1: If A1 match, do decryption.0: Do decryption. */ +#define RCR_AICV BIT9 // Accept ICV error packet +#define RCR_ACRC32 BIT8 // Accept CRC32 error packet +#define RCR_CBSSID_BCN BIT7 // Accept BSSID match packet (Rx beacon, probe rsp) +#define RCR_CBSSID_DATA BIT6 // Accept BSSID match packet (Data) +#define RCR_APWRMGT BIT5 // Accept power management packet +#define RCR_ADD3 BIT4 // Accept address 3 match packet +#define RCR_AB BIT3 // Accept broadcast packet +#define RCR_AM BIT2 // Accept multicast packet +#define RCR_APM BIT1 // Accept physical match packet +#define RCR_AAP BIT0 // Accept all unicast packet + + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- + +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_EN_25_1 BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) + + +//2 9346CR /REG_SYS_EEPROM_CTRL +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROMSEL BIT(4) +#define EEPROM_EN BIT(5) + + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + + +//2 EFUSE_TEST (For RTL8723 partially) +#define EF_TRPT BIT(7) +#define EF_CELL_SEL (BIT(8)|BIT(9)) // 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 +#define LDOE25_EN BIT(31) +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +#define EFUSE_BT_SEL_0 0x1 +#define EFUSE_BT_SEL_1 0x2 +#define EFUSE_BT_SEL_2 0x3 + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define RAM_DL_SEL BIT(7) +#define CPU_DL_READY BIT(15) /* add flag by gw for fw download ready 20130826 */ +#define ROM_DLEN BIT(19) +#define CPRST BIT(23) + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define SW_OFFLOAD_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define EXT_VENDOR_ID (BIT(18)|BIT(19)) //Currently only for RTL8723B +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) // RTL ID +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) +#define RF_TYPE_ID BIT(27) + +#define RTL_ID BIT(23) // TestChip ID, 1:Test(RLE); 0:MP(RL) +#define SPS_SEL BIT(24) // 1:LDO regulator mode; 0:Switching regulator mode + + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 +#define EXT_VENDOR_ID_SHIFT 18 + +//2 REG_GPIO_OUTSTS (For RTL8723 only) +#define EFS_HCI_SEL (BIT(0)|BIT(1)) +#define PAD_HCI_SEL (BIT(2)|BIT(3)) +#define HCI_SEL (BIT(4)|BIT(5)) +#define PKG_SEL_HCI BIT(6) +#define FEN_GPS BIT(7) +#define FEN_BT BIT(8) +#define FEN_WL BIT(9) +#define FEN_PCI BIT(10) +#define FEN_USB BIT(11) +#define BTRF_HWPDN_N BIT(12) +#define WLRF_HWPDN_N BIT(13) +#define PDN_BT_N BIT(14) +#define PDN_GPS_N BIT(15) +#define BT_CTL_HWPDN BIT(16) +#define GPS_CTL_HWPDN BIT(17) +#define PPHY_SUSB BIT(20) +#define UPHY_SUSB BIT(21) +#define PCI_SUSEN BIT(22) +#define USB_SUSEN BIT(23) +#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) + + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + +//2 Function Enable Registers +//2 CR +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) +#define CALTMR_EN BIT(10) // 32k CAL TMR enable + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +//2 PBP - Page Size Register +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_CMQ_MAP(x) (((x)&0x3) << 16) +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_EXTRA 0 +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + +//2 TRXFF_BNDY + + +//2 LLT_INIT +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +//2 RQPN +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) // NOTE: in RQPN_NPQ register +#define _EPQ(x) (((x) & 0xFF) << 16) // NOTE: in RQPN_EPQ register + + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + + +//2 TDECTL +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK +#define DROP_DATA_EN BIT(9) + +//2 AUTO_LLT +#define BIT_SHIFT_TXPKTNUM 24 +#define BIT_MASK_TXPKTNUM 0xff +#define BIT_TXPKTNUM(x) (((x) & BIT_MASK_TXPKTNUM) << BIT_SHIFT_TXPKTNUM) + +#define BIT_TDE_DBG_SEL BIT(23) +#define BIT_AUTO_INIT_LLT BIT(16) + +#define BIT_SHIFT_Tx_OQT_free_space 8 +#define BIT_MASK_Tx_OQT_free_space 0xff +#define BIT_Tx_OQT_free_space(x) (((x) & BIT_MASK_Tx_OQT_free_space) << BIT_SHIFT_Tx_OQT_free_space) + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x028Bh RX DMA Configuration +// +//----------------------------------------------------- + +//2 REG_RXDMA_CONTROL, 0x0286h +// Write only. When this bit is set, RXDMA will decrease RX PKT counter by one. Before +// this bit is polled, FW shall update RXFF_RD_PTR first. This register is write pulse and auto clear. +//#define RXPKT_RELEASE_POLL BIT(0) +// Read only. When RXMA finishes on-going DMA operation, RXMDA will report idle state in +// this bit. FW can start releasing packets after RXDMA entering idle mode. +//#define RXDMA_IDLE BIT(1) +// When this bit is set, RXDMA will enter this mode after on-going RXDMA packet to host +// completed, and stop DMA packet to host. RXDMA will then report Default: 0; +//#define RW_RELEASE_EN BIT(2) + +//2 REG_RXPKT_NUM, 0x0284 +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +//2 FWHW_TXQ_CTRL +#define EN_AMPDU_RTY_NEW BIT(7) + + +//2 SPEC SIFS +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +//2 RL +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//2 EDCA setting +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + + +//2 BCN_CTRL +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) +#define STOP_BCNQ BIT(6) +#define DIS_RX_BSSID_FIT BIT(6) + +#define DIS_ATIM BIT(0) +#define DIS_BCNQ_SUB BIT(1) +#define DIS_TSF_UDT BIT(4) + +// The same function but different bit field. +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + + +//2 ACMHWCTRL +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + +//2 //REG_DUAL_TSF_RST (0x553) +#define DUAL_TSF_RST_P2P BIT(4) + +//2 // REG_NOA_DESC_SEL (0x5CF) +#define NOA_DESC_SEL_0 0 +#define NOA_DESC_SEL_1 BIT(4) + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +//2 APSD_CTRL +#define APSDOFF BIT(6) + +//2 TCR +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + + +//2 RCR +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define FORCEACK BIT(26) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + + +//2 SECCFG +#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key +#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key +#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption +#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption +#define SCR_SKByA2 BIT(4) //Search kEY BY A2 +#define SCR_NoSKMC BIT(5) //No Key Search Multicast +#define SCR_TXBCUSEDK BIT(6) // Force Tx Broadcast packets Use Default Key +#define SCR_RXBCUSEDK BIT(7) // Force Rx Broadcast packets Use Default Key +#define SCR_CHK_KEYID BIT(8) +#define SCR_CHK_BMC BIT(9) /* add option to support a2+keyid+bcm */ + +//----------------------------------------------------- +// +// SDIO Bus Specification +// +//----------------------------------------------------- + +// I/O bus domain address mapping +#define SDIO_LOCAL_BASE 0x10250000 +#define WLAN_IOREG_BASE 0x10260000 +#define FIRMWARE_FIFO_BASE 0x10270000 +#define TX_HIQ_BASE 0x10310000 +#define TX_MIQ_BASE 0x10320000 +#define TX_LOQ_BASE 0x10330000 +#define TX_EPQ_BASE 0x10350000 +#define RX_RX0FF_BASE 0x10340000 + +//SDIO host local register space mapping. +#define SDIO_LOCAL_MSK 0x0FFF +#define WLAN_IOREG_MSK 0x7FFF +#define WLAN_FIFO_MSK 0x1FFF // Aggregation Length[12:0] +#define WLAN_RX0FF_MSK 0x0003 + +#define SDIO_WITHOUT_REF_DEVICE_ID 0 // Without reference to the SDIO Device ID +#define SDIO_LOCAL_DEVICE_ID 0 // 0b[16], 000b[15:13] +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define WLAN_TX_EXQ_DEVICE_ID 3 // 0b[16], 011b[15:13] +#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13] +#define WLAN_IOREG_DEVICE_ID 8 // 1b[16] + +//SDIO Tx Free Page Index +#define HI_QUEUE_IDX 0 +#define MID_QUEUE_IDX 1 +#define LOW_QUEUE_IDX 2 +#define PUBLIC_QUEUE_IDX 3 + +#define SDIO_MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ +#define SDIO_MAX_RX_QUEUE 1 + +#define SDIO_REG_TX_CTRL 0x0000 // SDIO Tx Control +#define SDIO_REG_HIMR 0x0014 // SDIO Host Interrupt Mask +#define SDIO_REG_HISR 0x0018 // SDIO Host Interrupt Service Routine +#define SDIO_REG_HCPWM 0x0019 // HCI Current Power Mode +#define SDIO_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length +#define SDIO_REG_OQT_FREE_PG 0x001E // OQT Free Page +#define SDIO_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page +#define SDIO_REG_HCPWM1 0x0024 // HCI Current Power Mode 1 +#define SDIO_REG_HCPWM2 0x0026 // HCI Current Power Mode 2 +#define SDIO_REG_FREE_TXPG_SEQ 0x0028 // Free Tx Page Sequence +#define SDIO_REG_HTSFR_INFO 0x0030 // HTSF Informaion +#define SDIO_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 +#define SDIO_REG_HRPWM2 0x0082 // HCI Request Power Mode 2 +#define SDIO_REG_HPS_CLKR 0x0084 // HCI Power Save Clock +#define SDIO_REG_HSUS_CTRL 0x0086 // SDIO HCI Suspend Control +#define SDIO_REG_HIMR_ON 0x0090 //SDIO Host Extension Interrupt Mask Always +#define SDIO_REG_HISR_ON 0x0091 //SDIO Host Extension Interrupt Status Always + +#define SDIO_HIMR_DISABLED 0 + +// RTL8723/RTL8188E SDIO Host Interrupt Mask Register +#define SDIO_HIMR_RX_REQUEST_MSK BIT0 +#define SDIO_HIMR_AVAL_MSK BIT1 +#define SDIO_HIMR_TXERR_MSK BIT2 +#define SDIO_HIMR_RXERR_MSK BIT3 +#define SDIO_HIMR_TXFOVW_MSK BIT4 +#define SDIO_HIMR_RXFOVW_MSK BIT5 +#define SDIO_HIMR_TXBCNOK_MSK BIT6 +#define SDIO_HIMR_TXBCNERR_MSK BIT7 +#define SDIO_HIMR_BCNERLY_INT_MSK BIT16 +#define SDIO_HIMR_C2HCMD_MSK BIT17 +#define SDIO_HIMR_CPWM1_MSK BIT18 +#define SDIO_HIMR_CPWM2_MSK BIT19 +#define SDIO_HIMR_HSISR_IND_MSK BIT20 +#define SDIO_HIMR_GTINT3_IND_MSK BIT21 +#define SDIO_HIMR_GTINT4_IND_MSK BIT22 +#define SDIO_HIMR_PSTIMEOUT_MSK BIT23 +#define SDIO_HIMR_OCPINT_MSK BIT24 +#define SDIO_HIMR_ATIMEND_MSK BIT25 +#define SDIO_HIMR_ATIMEND_E_MSK BIT26 +#define SDIO_HIMR_CTWEND_MSK BIT27 + +//RTL8188E SDIO Specific +#define SDIO_HIMR_MCU_ERR_MSK BIT28 +#define SDIO_HIMR_TSF_BIT32_TOGGLE_MSK BIT29 + +// SDIO Host Interrupt Service Routine +#define SDIO_HISR_RX_REQUEST BIT0 +#define SDIO_HISR_AVAL BIT1 +#define SDIO_HISR_TXERR BIT2 +#define SDIO_HISR_RXERR BIT3 +#define SDIO_HISR_TXFOVW BIT4 +#define SDIO_HISR_RXFOVW BIT5 +#define SDIO_HISR_TXBCNOK BIT6 +#define SDIO_HISR_TXBCNERR BIT7 +#define SDIO_HISR_BCNERLY_INT BIT16 +#define SDIO_HISR_C2HCMD BIT17 +#define SDIO_HISR_CPWM1 BIT18 +#define SDIO_HISR_CPWM2 BIT19 +#define SDIO_HISR_HSISR_IND BIT20 +#define SDIO_HISR_GTINT3_IND BIT21 +#define SDIO_HISR_GTINT4_IND BIT22 +#define SDIO_HISR_PSTIMEOUT BIT23 +#define SDIO_HISR_OCPINT BIT24 +#define SDIO_HISR_ATIMEND BIT25 +#define SDIO_HISR_ATIMEND_E BIT26 +#define SDIO_HISR_CTWEND BIT27 + +//RTL8188E SDIO Specific +#define SDIO_HISR_MCU_ERR BIT28 +#define SDIO_HISR_TSF_BIT32_TOGGLE BIT29 + +#define MASK_SDIO_HISR_CLEAR (SDIO_HISR_TXERR |\ + SDIO_HISR_RXERR |\ + SDIO_HISR_TXFOVW |\ + SDIO_HISR_RXFOVW |\ + SDIO_HISR_TXBCNOK |\ + SDIO_HISR_TXBCNERR |\ + SDIO_HISR_C2HCMD |\ + SDIO_HISR_CPWM1 |\ + SDIO_HISR_CPWM2 |\ + SDIO_HISR_HSISR_IND |\ + SDIO_HISR_GTINT3_IND |\ + SDIO_HISR_GTINT4_IND |\ + SDIO_HISR_PSTIMEOUT |\ + SDIO_HISR_OCPINT) + +// SDIO HCI Suspend Control Register +#define HCI_RESUME_PWR_RDY BIT1 +#define HCI_SUS_CTRL BIT0 + +// SDIO Tx FIFO related +#define SDIO_TX_FREE_PG_QUEUE 4 // The number of Tx FIFO free page +#define SDIO_TX_FIFO_PAGE_SZ 128 + +#ifdef CONFIG_SDIO_HCI + #define MAX_TX_AGG_PACKET_NUMBER 0x8 +#else + #define MAX_TX_AGG_PACKET_NUMBER 0xFF + #define MAX_TX_AGG_PACKET_NUMBER_8812 64 +#endif + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- + +//2 USB Information (0xFE17) +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +//2 Special Option +#define USB_AGG_EN BIT(3) + +// 0; Use interrupt endpoint to upload interrupt pkt +// 1; Use bulk endpoint to upload interrupt pkt, +#define INT_BULK_SEL BIT(4) + +//2REG_C2HEVT_CLEAR +#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message +#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver. + + +//2REG_MULTI_FUNC_CTRL(For RTL8723 Only) +#define WL_HWPDN_EN BIT0 // Enable GPIO[9] as WiFi HW PDn source +#define WL_HWPDN_SL BIT1 // WiFi HW PDn polarity control +#define WL_FUNC_EN BIT2 // WiFi function enable +#define WL_HWROF_EN BIT3 // Enable GPIO[9] as WiFi RF HW PDn source +#define BT_HWPDN_EN BIT16 // Enable GPIO[11] as BT HW PDn source +#define BT_HWPDN_SL BIT17 // BT HW PDn polarity control +#define BT_FUNC_EN BIT18 // BT function enable +#define BT_HWROF_EN BIT19 // Enable GPIO[11] as BT/GPS RF HW PDn source +#define GPS_HWPDN_EN BIT20 // Enable GPIO[10] as GPS HW PDn source +#define GPS_HWPDN_SL BIT21 // GPS HW PDn polarity control +#define GPS_FUNC_EN BIT22 // GPS function enable + +//3 REG_LIFECTRL_CTRL +#define HAL92C_EN_PKT_LIFE_TIME_BK BIT3 +#define HAL92C_EN_PKT_LIFE_TIME_BE BIT2 +#define HAL92C_EN_PKT_LIFE_TIME_VI BIT1 +#define HAL92C_EN_PKT_LIFE_TIME_VO BIT0 + +#define HAL92C_MSDU_LIFE_TIME_UNIT 128 // in us, said by Tim. + +//2 8192D PartNo. +#define PARTNO_92D_NIC (BIT7|BIT6) +#define PARTNO_92D_NIC_REMARK (BIT5|BIT4) +#define PARTNO_SINGLE_BAND_VS BIT3 +#define PARTNO_SINGLE_BAND_VS_REMARK BIT1 +#define PARTNO_CONCURRENT_BAND_VC (BIT3|BIT2) +#define PARTNO_CONCURRENT_BAND_VC_REMARK (BIT1|BIT0) + +//======================================================== +// General definitions +//======================================================== + +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(__Adapter) ( IS_VENDOR_8188E_I_CUT_SERIES(__Adapter) ? 255 : 175 ) +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8812 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8723B 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8192C 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8703B 255 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC 127 +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8188F 255 + +#define POLLING_LLT_THRESHOLD 20 +#if defined(CONFIG_RTL8723B) && defined(CONFIG_PCI_HCI) +#define POLLING_READY_TIMEOUT_COUNT 6000 +#else +#define POLLING_READY_TIMEOUT_COUNT 1000 +#endif + + +// GPIO BIT +#define HAL_8812A_HW_GPIO_WPS_BIT BIT2 +#define HAL_8192C_HW_GPIO_WPS_BIT BIT2 +#define HAL_8192EU_HW_GPIO_WPS_BIT BIT7 +#define HAL_8188E_HW_GPIO_WPS_BIT BIT7 + +#endif //__HAL_COMMON_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_data.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_data.h new file mode 100644 index 00000000..249f8b2f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_data.h @@ -0,0 +1,653 @@ +/****************************************************************************** + * + * 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 __HAL_DATA_H__ +#define __HAL_DATA_H__ + +#if 1//def CONFIG_SINGLE_IMG + +#include "../hal/phydm/phydm_precomp.h" +#ifdef CONFIG_BT_COEXIST +#include +#endif + +#ifdef CONFIG_SDIO_HCI +#include +#endif +#ifdef CONFIG_GSPI_HCI +#include +#endif +// +// For RTL8723 WiFi/BT/GPS multi-function configuration. 2010.10.06. +// +typedef enum _RT_MULTI_FUNC{ + RT_MULTI_FUNC_NONE = 0x00, + RT_MULTI_FUNC_WIFI = 0x01, + RT_MULTI_FUNC_BT = 0x02, + RT_MULTI_FUNC_GPS = 0x04, +}RT_MULTI_FUNC,*PRT_MULTI_FUNC; +// +// For RTL8723 WiFi PDn/GPIO polarity control configuration. 2010.10.08. +// +typedef enum _RT_POLARITY_CTL { + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +} RT_POLARITY_CTL, *PRT_POLARITY_CTL; + +// For RTL8723 regulator mode. by tynli. 2011.01.14. +typedef enum _RT_REGULATOR_MODE { + RT_SWITCHING_REGULATOR = 0, + RT_LDO_REGULATOR = 1, +} RT_REGULATOR_MODE, *PRT_REGULATOR_MODE; + +// +// Interface type. +// +typedef enum _INTERFACE_SELECT_PCIE{ + INTF_SEL0_SOLO_MINICARD = 0, // WiFi solo-mCard + INTF_SEL1_BT_COMBO_MINICARD = 1, // WiFi+BT combo-mCard + INTF_SEL2_PCIe = 2, // PCIe Card +} INTERFACE_SELECT_PCIE, *PINTERFACE_SELECT_PCIE; + + +typedef enum _INTERFACE_SELECT_USB{ + INTF_SEL0_USB = 0, // USB + INTF_SEL1_USB_High_Power = 1, // USB with high power PA + INTF_SEL2_MINICARD = 2, // Minicard + INTF_SEL3_USB_Solo = 3, // USB solo-Slim module + INTF_SEL4_USB_Combo = 4, // USB Combo-Slim module + 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; + +typedef enum _RT_AMPDU_BRUST_MODE{ + RT_AMPDU_BRUST_NONE = 0, + RT_AMPDU_BRUST_92D = 1, + RT_AMPDU_BRUST_88E = 2, + RT_AMPDU_BRUST_8812_4 = 3, + RT_AMPDU_BRUST_8812_8 = 4, + RT_AMPDU_BRUST_8812_12 = 5, + RT_AMPDU_BRUST_8812_15 = 6, + RT_AMPDU_BRUST_8723B = 7, +}RT_AMPDU_BRUST,*PRT_AMPDU_BRUST_MODE; + +/* +#define CHANNEL_MAX_NUMBER 14+24+21 // 14 is the max channel number +*/ +#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, ch4~9, ch10~14 total three groups */ +#define MAX_PG_GROUP 13 + +// Tx Power Limit Table Size +#define MAX_REGULATION_NUM 4 +#define MAX_RF_PATH_NUM_IN_POWER_LIMIT_TABLE 4 +#define MAX_2_4G_BANDWIDTH_NUM 2 +#define MAX_RATE_SECTION_NUM 10 +#define MAX_5G_BANDWIDTH_NUM 4 + +#define MAX_BASE_NUM_IN_PHY_REG_PG_2_4G 10 // CCK:1,OFDM:1, HT:4, VHT:4 +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 9 // OFDM:1, HT:4, VHT:4 + + +//###### duplicate code,will move to ODM ######### +//#define IQK_MAC_REG_NUM 4 +//#define IQK_ADDA_REG_NUM 16 + +//#define IQK_BB_REG_NUM 10 +#define IQK_BB_REG_NUM_92C 9 +#define IQK_BB_REG_NUM_92D 10 +#define IQK_BB_REG_NUM_test 6 + +#define IQK_Matrix_Settings_NUM_92D 1+24+21 + +//#define HP_THERMAL_NUM 8 +//###### duplicate code,will move to ODM ######### + +#ifdef CONFIG_USB_RX_AGGREGATION +typedef enum _USB_RX_AGG_MODE{ + USB_RX_AGG_DISABLE, + USB_RX_AGG_DMA, + USB_RX_AGG_USB, + USB_RX_AGG_MIX +}USB_RX_AGG_MODE; + +//#define MAX_RX_DMA_BUFFER_SIZE 10240 // 10K for 8192C RX DMA buffer + +#endif + +/* For store initial value of BB register */ +typedef struct _BB_INIT_REGISTER { + u16 offset; + u32 value; + +} BB_INIT_REGISTER, *PBB_INIT_REGISTER; + +#define PAGE_SIZE_128 128 +#define PAGE_SIZE_256 256 +#define PAGE_SIZE_512 512 + +#define HCI_SUS_ENTER 0 +#define HCI_SUS_LEAVING 1 +#define HCI_SUS_LEAVE 2 +#define HCI_SUS_ENTERING 3 +#define HCI_SUS_ERR 4 + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +typedef enum _ACS_OP { + ACS_INIT, /*ACS - Variable init*/ + ACS_RESET, /*ACS - NHM Counter reset*/ + ACS_SELECT, /*ACS - NHM Counter Statistics */ +} ACS_OP; + +typedef enum _ACS_STATE { + ACS_DISABLE, + ACS_ENABLE, +} ACS_STATE; + +struct auto_chan_sel { + ATOMIC_T state; + u8 ch; /* previous channel*/ +}; +#endif /*CONFIG_AUTO_CHNL_SEL_NHM*/ + +#define EFUSE_FILE_UNUSED 0 +#define EFUSE_FILE_FAILED 1 +#define EFUSE_FILE_LOADED 2 + +#define MACADDR_FILE_UNUSED 0 +#define MACADDR_FILE_FAILED 1 +#define MACADDR_FILE_LOADED 2 + +#define KFREE_FLAG_ON BIT0 +#define KFREE_FLAG_THERMAL_K_ON BIT1 + +struct kfree_data_t { + u8 flag; + s8 bb_gain[BB_GAIN_NUM][RF_PATH_MAX]; + +#ifdef CONFIG_IEEE80211_BAND_5GHZ + s8 pa_bias_5g[RF_PATH_MAX]; + s8 pad_bias_5g[RF_PATH_MAX]; +#endif + s8 thermal; +}; + +bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data); + +struct hal_spec_t { + u8 macid_num; + + u8 sec_cam_ent_num; + u8 sec_cap; + + u8 nss_num; + u8 band_cap; /* value of BAND_CAP_XXX */ + u8 bw_cap; /* value of BW_CAP_XXX */ + + u8 wl_func; /* value of WL_FUNC_XXX */ +}; + +typedef struct hal_com_data +{ + HAL_VERSION VersionID; + RT_MULTI_FUNC MultiFunc; // For multi-function consideration. + RT_POLARITY_CTL PolarityCtl; // For Wifi PDn Polarity control. + RT_REGULATOR_MODE RegulatorMode; // switching regulator or LDO + u8 hw_init_completed; + /****** FW related ******/ + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + u16 FirmwareSignature; + u8 RegFWOffload; + u8 fw_ractrl; + u8 FwRsvdPageStartOffset; /* 2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ.*/ + u8 LastHMEBoxNum; /* H2C - for host message to fw */ + + /****** current WIFI_PHY values ******/ + WIRELESS_MODE CurrentWirelessMode; + CHANNEL_WIDTH CurrentChannelBW; + BAND_TYPE CurrentBandType; /* 0:2.4G, 1:5G */ + BAND_TYPE BandSet; + u8 CurrentChannel; + u8 CurrentCenterFrequencyIndex1; + u8 nCur40MhzPrimeSC; /* Control channel sub-carrier */ + u8 nCur80MhzPrimeSC; /* used for primary 40MHz of 80MHz mode */ + BOOLEAN bSwChnlAndSetBWInProgress; + u8 bDisableSWChannelPlan; /* flag of disable software change channel plan */ + u16 BasicRateSet; + u32 ReceiveConfig; + BOOLEAN bSwChnl; + BOOLEAN bSetChnlBW; + BOOLEAN bChnlBWInitialized; +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + struct auto_chan_sel acs; +#endif + /****** rf_ctrl *****/ + u8 rf_chip; + u8 rf_type; + u8 PackageType; + u8 NumTotalRFPath; + + /****** Debug ******/ + u16 ForcedDataRate; /* Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M. */ + u8 u1ForcedIgiLb; /* forced IGI lower bound */ + u8 bDumpRxPkt; + u8 bDumpTxPkt; + u8 bDisableTXPowerTraining; + + + /****** EEPROM setting.******/ + u8 bautoload_fail_flag; + u8 efuse_file_status; + u8 macaddr_file_status; + u8 EepromOrEfuse; + u8 efuse_eeprom_data[EEPROM_MAX_SIZE]; /*92C:256bytes, 88E:512bytes, we use union set (512bytes)*/ + u8 InterfaceSel; /* board type kept in eFuse */ + u16 CustomerID; + + u16 EEPROMVID; + u16 EEPROMSVID; +#ifdef CONFIG_USB_HCI + u16 EEPROMPID; + u16 EEPROMSDID; +#endif +#ifdef CONFIG_PCI_HCI + u16 EEPROMDID; + u16 EEPROMSMID; +#endif + + u8 EEPROMCustomerID; + u8 EEPROMSubCustomerID; + u8 EEPROMVersion; + u8 EEPROMRegulatory; + u8 EEPROMThermalMeter; + u8 EEPROMBluetoothCoexist; + u8 EEPROMBluetoothType; + u8 EEPROMBluetoothAntNum; + u8 EEPROMBluetoothAntIsolation; + u8 EEPROMBluetoothRadioShared; + u8 bTXPowerDataReadFromEEPORM; + u8 EEPROMMACAddr[ETH_ALEN]; + +#ifdef CONFIG_RF_GAIN_OFFSET + u8 EEPROMRFGainOffset; + u8 EEPROMRFGainVal; + struct kfree_data_t kfree_data; +#endif /*CONFIG_RF_GAIN_OFFSET*/ + +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) + u8 adjuseVoltageVal; +#endif + u8 EfuseUsedPercentage; + u16 EfuseUsedBytes; + /*u8 EfuseMap[2][HWSET_MAX_SIZE_JAGUAR];*/ + EFUSE_HAL EfuseHal; + + /*---------------------------------------------------------------------------------*/ + //3 [2.4G] + u8 Index24G_CCK_Base[MAX_RF_PATH][CENTER_CH_2G_NUM]; + u8 Index24G_BW40_Base[MAX_RF_PATH][CENTER_CH_2G_NUM]; + //If only one tx, only BW20 and OFDM are used. + s8 CCK_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 OFDM_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + //3 [5G] + u8 Index5G_BW40_Base[MAX_RF_PATH][CENTER_CH_5G_ALL_NUM]; + u8 Index5G_BW80_Base[MAX_RF_PATH][CENTER_CH_5G_80M_NUM]; + s8 OFDM_5G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_5G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_5G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW80_5G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + + u8 Regulation2_4G; + u8 Regulation5G; + + u8 TxPwrInPercentage; + + /******************************** + * TX power by rate table at most 4RF path. + * The register is + * + * VHT TX power by rate off setArray = + * Band:-2G&5G = 0 / 1 + * RF: at most 4*4 = ABCD=0/1/2/3 + * CCK=0 OFDM=1/2 HT-MCS 0-15=3/4/56 VHT=7/8/9/10/11 + **********************************/ + u8 TxPwrByRateTable; + u8 TxPwrByRateBand; + s8 TxPwrByRateOffset[TX_PWR_BY_RATE_NUM_BAND] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RATE]; + //---------------------------------------------------------------------------------// + + /* + //2 Power Limit Table + u8 TxPwrLevelCck[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER]; + u8 TxPwrLevelHT40_1S[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + s8 TxPwrHt20Diff[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff + */ + + u8 tx_pwr_lmt_5g_20_40_ref; + + // Power Limit Table for 2.4G + s8 TxPwrLimit_2_4G[MAX_REGULATION_NUM] + [MAX_2_4G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CENTER_CH_2G_NUM] + [MAX_RF_PATH]; + + // Power Limit Table for 5G + s8 TxPwrLimit_5G[MAX_REGULATION_NUM] + [MAX_5G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CENTER_CH_5G_ALL_NUM] + [MAX_RF_PATH]; + + + // Store the original power by rate value of the base of each rate section of rf path A & B + u8 TxPwrByRateBase2_4G[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_2_4G]; + u8 TxPwrByRateBase5G[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_5G]; + + u8 txpwr_by_rate_loaded:1; + u8 txpwr_by_rate_from_file:1; + u8 txpwr_limit_loaded:1; + u8 txpwr_limit_from_file:1; + + // For power group + /* + u8 PwrGroupHT20[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER]; + u8 PwrGroupHT40[RF_PATH_MAX_92C_88E][CHANNEL_MAX_NUMBER]; + */ + u8 PGMaxGroup; + + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + u8 CurrentBW2024GTxPwrIdx; + u8 CurrentBW4024GTxPwrIdx; + + // Read/write are allow for following hardware information variables + u8 pwrGroupCnt; + u32 MCSTxPowerLevelOriginalOffset[MAX_PG_GROUP][16]; + u32 CCKTxPowerLevelOriginalOffset; + + u8 CrystalCap; + + u8 PAType_2G; + u8 PAType_5G; + u8 LNAType_2G; + u8 LNAType_5G; + u8 ExternalPA_2G; + u8 ExternalLNA_2G; + u8 ExternalPA_5G; + u8 ExternalLNA_5G; + u16 TypeGLNA; + u16 TypeGPA; + u16 TypeALNA; + u16 TypeAPA; + u16 RFEType; + + u8 bLedOpenDrain; /* Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. */ + u32 AcParam_BE; /* Original parameter for BE, use for EDCA turbo. */ + + BB_REGISTER_DEFINITION_T PHYRegDef[MAX_RF_PATH]; //Radio A/B/C/D + + u32 RfRegChnlVal[MAX_RF_PATH]; + + //RDG enable + BOOLEAN bRDGEnable; + + u8 RegTxPause; + // Beacon function related global variable. + u8 RegBcnCtrlVal; + u8 RegFwHwTxQCtrl; + u8 RegReg542; + u8 RegCR_1; + u8 Reg837; + u16 RegRRSR; + + /****** antenna diversity ******/ + u8 CurAntenna; + u8 AntDivCfg; + u8 AntDetection; + u8 TRxAntDivType; + u8 ant_path; //for 8723B s0/s1 selection + u32 AntennaTxPath; /* Antenna path Tx */ + u32 AntennaRxPath; /* Antenna path Rx */ + + /******** PHY DM & DM Section **********/ + u8 DM_Type; + _lock IQKSpinLock; + u8 INIDATA_RATE[MACID_NUM_SW_LIMIT]; + /* Upper and Lower Signal threshold for Rate Adaptive*/ + int EntryMinUndecoratedSmoothedPWDB; + int EntryMaxUndecoratedSmoothedPWDB; + int MinUndecoratedPWDBForDM; + DM_ODM_T odmpriv; + u8 bIQKInitialized; + u8 bNeedIQK; + /******** PHY DM & DM Section **********/ + + + + // 2010/08/09 MH Add CU power down mode. + BOOLEAN pwrdown; + + // Add for dual MAC 0--Mac0 1--Mac1 + u32 interfaceIndex; + +#ifdef CONFIG_P2P + u8 p2p_ps_offload; +#endif + /* Auto FSM to Turn On, include clock, isolation, power control for MAC only */ + u8 bMacPwrCtrlOn; + u8 hci_sus_state; + + u8 RegIQKFWOffload; + struct submit_ctx iqk_sctx; + + RT_AMPDU_BRUST AMPDUBurstMode; //92C maybe not use, but for compile successfully + + u8 OutEpQueueSel; + u8 OutEpNumber; + +#if defined (CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + // + // For SDIO Interface HAL related + // + + // + // SDIO ISR Related + // +// u32 IntrMask[1]; +// u32 IntrMaskToSet[1]; +// LOG_INTERRUPT InterruptLog; + u32 sdio_himr; + u32 sdio_hisr; + + // + // SDIO Tx FIFO related. + // + // HIQ, MID, LOW, PUB free pages; padapter->xmitpriv.free_txpg + u8 SdioTxFIFOFreePage[SDIO_TX_FREE_PG_QUEUE]; + _lock SdioTxFIFOFreePageLock; + u8 SdioTxOQTMaxFreeSpace; + u8 SdioTxOQTFreeSpace; + + // + // SDIO Rx FIFO related. + // + u8 SdioRxFIFOCnt; + u16 SdioRxFIFOSize; + + u32 sdio_tx_max_len[SDIO_MAX_TX_QUEUE];// H, N, L, used for sdio tx aggregation max length per queue +#endif //CONFIG_SDIO_HCI + +#ifdef CONFIG_USB_HCI + + // 2010/12/10 MH Add for USB aggreation mode dynamic shceme. + BOOLEAN UsbRxHighSpeedMode; + BOOLEAN UsbTxVeryHighSpeedMode; + u32 UsbBulkOutSize; + BOOLEAN bSupportUSB3; + + // Interrupt relatd register information. + u32 IntArray[3];//HISR0,HISR1,HSISR + u32 IntrMask[3]; + u8 C2hArray[16]; + #ifdef CONFIG_USB_TX_AGGREGATION + u8 UsbTxAggMode; + u8 UsbTxAggDescNum; + #endif // CONFIG_USB_TX_AGGREGATION + + #ifdef CONFIG_USB_RX_AGGREGATION + u16 HwRxPageSize; // Hardware setting + u32 MaxUsbRxAggBlock; + + USB_RX_AGG_MODE UsbRxAggMode; + u8 UsbRxAggBlockCount; /* FOR USB Mode, USB Block count. Block size is 512-byte in hight speed and 64-byte in full speed */ + u8 UsbRxAggBlockTimeout; + u8 UsbRxAggPageCount; /* FOR DMA Mode, 8192C DMA page count*/ + u8 UsbRxAggPageTimeout; + + u8 RegAcUsbDmaSize; + u8 RegAcUsbDmaTime; + #endif//CONFIG_USB_RX_AGGREGATION +#endif //CONFIG_USB_HCI + + +#ifdef CONFIG_PCI_HCI + // + // EEPROM setting. + // + u32 TransmitConfig; + u32 IntrMaskToSet[2]; + u32 IntArray[2]; + u32 IntrMask[2]; + u32 SysIntArray[1]; + u32 SysIntrMask[1]; + u32 IntrMaskReg[2]; + u32 IntrMaskDefault[2]; + + BOOLEAN bL1OffSupport; + BOOLEAN bSupportBackDoor; + + u8 bDefaultAntenna; + + u8 bInterruptMigration; + u8 bDisableTxInt; + + u16 RxTag; +#endif //CONFIG_PCI_HCI + + +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv srestpriv; +#endif //#ifdef DBG_CONFIG_ERROR_DETECT + +#ifdef CONFIG_BT_COEXIST + // For bluetooth co-existance + BT_COEXIST bt_coexist; +#endif // CONFIG_BT_COEXIST + +#if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8188F) + #ifndef CONFIG_PCI_HCI // mutual exclusive with PCI -- so they're SDIO and GSPI + // Interrupt relatd register information. + u32 SysIntrStatus; + u32 SysIntrMask; + #endif +#endif /*endif CONFIG_RTL8723B */ + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + char para_file_buf[MAX_PARA_FILE_BUF_LEN]; + char *mac_reg; + u32 mac_reg_len; + char *bb_phy_reg; + u32 bb_phy_reg_len; + char *bb_agc_tab; + u32 bb_agc_tab_len; + char *bb_phy_reg_pg; + u32 bb_phy_reg_pg_len; + char *bb_phy_reg_mp; + u32 bb_phy_reg_mp_len; + char *rf_radio_a; + u32 rf_radio_a_len; + char *rf_radio_b; + u32 rf_radio_b_len; + char *rf_tx_pwr_track; + u32 rf_tx_pwr_track_len; + char *rf_tx_pwr_lmt; + u32 rf_tx_pwr_lmt_len; +#endif + +#ifdef CONFIG_BACKGROUND_NOISE_MONITOR + s16 noise[ODM_MAX_CHANNEL_NUM]; +#endif + + struct hal_spec_t hal_spec; + + u8 RfKFreeEnable; + u8 RfKFree_ch_group; + BOOLEAN bCCKinCH14; + BB_INIT_REGISTER RegForRecover[5]; + +#if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN) + BOOLEAN bCorrectBCN; +#endif + u32 RxGainOffset[4]; /*{2G, 5G_Low, 5G_Middle, G_High}*/ + u8 BackUp_IG_REG_4_Chnl_Section[4]; /*{A,B,C,D}*/ +} HAL_DATA_COMMON, *PHAL_DATA_COMMON; + + + +typedef struct hal_com_data HAL_DATA_TYPE, *PHAL_DATA_TYPE; +#define GET_HAL_DATA(__pAdapter) ((HAL_DATA_TYPE *)((__pAdapter)->HalData)) +#define GET_HAL_SPEC(__pAdapter) (&(GET_HAL_DATA((__pAdapter))->hal_spec)) + +#define GET_HAL_RFPATH_NUM(__pAdapter) (((HAL_DATA_TYPE *)((__pAdapter)->HalData))->NumTotalRFPath ) +#define RT_GetInterfaceSelection(_Adapter) (GET_HAL_DATA(_Adapter)->InterfaceSel) +#define GET_RF_TYPE(__pAdapter) (GET_HAL_DATA(__pAdapter)->rf_type) +#define GET_KFREE_DATA(_adapter) (&(GET_HAL_DATA((_adapter))->kfree_data)) + +#define SUPPORT_HW_RADIO_DETECT(Adapter) ( RT_GetInterfaceSelection(Adapter) == INTF_SEL2_MINICARD ||\ + RT_GetInterfaceSelection(Adapter) == INTF_SEL3_USB_Solo ||\ + RT_GetInterfaceSelection(Adapter) == INTF_SEL4_USB_Combo) + +#define get_hal_mac_addr(adapter) (GET_HAL_DATA(adapter)->EEPROMMACAddr) +#define is_boot_from_eeprom(adapter) (GET_HAL_DATA(adapter)->EepromOrEfuse) +#define rtw_get_hw_init_completed(adapter) (GET_HAL_DATA(adapter)->hw_init_completed) +#define rtw_is_hw_init_completed(adapter) (GET_HAL_DATA(adapter)->hw_init_completed == _TRUE) +#endif + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +#define GET_ACS_STATE(padapter) (ATOMIC_READ(&GET_HAL_DATA(padapter)->acs.state)) +#define SET_ACS_STATE(padapter, set_state) (ATOMIC_SET(&GET_HAL_DATA(padapter)->acs.state, set_state)) +#define rtw_get_acs_channel(padapter) (GET_HAL_DATA(padapter)->acs.ch) +#define rtw_set_acs_channel(padapter, survey_ch) (GET_HAL_DATA(padapter)->acs.ch = survey_ch) +#endif /*CONFIG_AUTO_CHNL_SEL_NHM*/ + +#endif //__HAL_DATA_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_gspi.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_gspi.h new file mode 100644 index 00000000..f5880e27 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_gspi.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 __HAL_GSPI_H_ +#define __HAL_GSPI_H_ + +#define ffaddr2deviceId(pdvobj, addr) (pdvobj->Queue2Pipe[addr]) + +u8 rtw_hal_gspi_max_txoqt_free_space(_adapter *padapter); +u8 rtw_hal_gspi_query_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum); +void rtw_hal_gspi_update_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum); +void rtw_hal_set_gspi_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ); +u32 rtw_hal_get_gspi_tx_max_length(PADAPTER padapter, u8 queue_idx); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_ic_cfg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_ic_cfg.h new file mode 100644 index 00000000..0c8371eb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_ic_cfg.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * 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 __HAL_IC_CFG_H__ +#define __HAL_IC_CFG_H__ + +#define RTL8188E_SUPPORT 0 +#define RTL8812A_SUPPORT 0 +#define RTL8821A_SUPPORT 0 +#define RTL8723B_SUPPORT 0 +#define RTL8192E_SUPPORT 0 +#define RTL8814A_SUPPORT 0 +#define RTL8195A_SUPPORT 0 +#define RTL8703B_SUPPORT 0 +#define RTL8188F_SUPPORT 0 +#define RTL8822B_SUPPORT 0 +#define RTL8821B_SUPPORT 0 + +/*#if (RTL8188E_SUPPORT==1)*/ +#define RATE_ADAPTIVE_SUPPORT 0 +#define POWER_TRAINING_ACTIVE 0 + +#ifdef CONFIG_MULTIDRV +#endif + +#ifdef CONFIG_RTL8188E +#undef RTL8188E_SUPPORT +#undef RATE_ADAPTIVE_SUPPORT +#undef POWER_TRAINING_ACTIVE + +#define RTL8188E_SUPPORT 1 +#define RATE_ADAPTIVE_SUPPORT 1 +#define POWER_TRAINING_ACTIVE 1 +#endif + +#ifdef CONFIG_RTL8812A +#undef RTL8812A_SUPPORT +#define RTL8812A_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8821A +#undef RTL8821A_SUPPORT +#define RTL8821A_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8192E +#undef RTL8192E_SUPPORT +#define RTL8192E_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8723B +#undef RTL8723B_SUPPORT +#define RTL8723B_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8814A +#undef RTL8814A_SUPPORT +#define RTL8814A_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8703B +#undef RTL8703B_SUPPORT +#define RTL8703B_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8188F +#undef RTL8188F_SUPPORT +#define RTL8188F_SUPPORT 1 +#endif + +#ifdef CONFIG_RTL8822B +#undef RTL8822B_SUPPORT +#define RTL8822B_SUPPORT 1 +#endif + +#endif /*__HAL_IC_CFG_H__*/ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_intf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_intf.h new file mode 100644 index 00000000..04fc0444 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_intf.h @@ -0,0 +1,686 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __HAL_INTF_H__ +#define __HAL_INTF_H__ + + +enum RTL871X_HCI_TYPE { + RTW_PCIE = BIT0, + RTW_USB = BIT1, + RTW_SDIO = BIT2, + RTW_GSPI = BIT3, +}; + +enum _CHIP_TYPE { + + NULL_CHIP_TYPE, + RTL8188E, + RTL8192E, + RTL8812, + RTL8821, //RTL8811 + RTL8723B, + RTL8814A, + RTL8703B, + RTL8188F, + MAX_CHIP_TYPE +}; + +typedef enum _HAL_HW_TIMER_TYPE { + HAL_TIMER_NONE = 0, + HAL_TIMER_TXBF = 1, + HAL_TIMER_EARLYMODE = 2, +} HAL_HW_TIMER_TYPE, *PHAL_HW_TIMER_TYPE; + + +typedef enum _HW_VARIABLES{ + HW_VAR_MEDIA_STATUS, + HW_VAR_MEDIA_STATUS1, + HW_VAR_SET_OPMODE, + HW_VAR_MAC_ADDR, + HW_VAR_BSSID, + HW_VAR_INIT_RTS_RATE, + HW_VAR_BASIC_RATE, + HW_VAR_TXPAUSE, + HW_VAR_BCN_FUNC, + HW_VAR_CORRECT_TSF, + HW_VAR_CHECK_BSSID, + HW_VAR_MLME_DISCONNECT, + HW_VAR_MLME_SITESURVEY, + HW_VAR_MLME_JOIN, + HW_VAR_ON_RCR_AM, + HW_VAR_OFF_RCR_AM, + HW_VAR_BEACON_INTERVAL, + HW_VAR_SLOT_TIME, + HW_VAR_RESP_SIFS, + HW_VAR_ACK_PREAMBLE, + HW_VAR_SEC_CFG, + HW_VAR_SEC_DK_CFG, + HW_VAR_BCN_VALID, + HW_VAR_RF_TYPE, + /* PHYDM odm->SupportAbility */ + HW_VAR_CAM_EMPTY_ENTRY, + HW_VAR_CAM_INVALID_ALL, + HW_VAR_AC_PARAM_VO, + HW_VAR_AC_PARAM_VI, + HW_VAR_AC_PARAM_BE, + HW_VAR_AC_PARAM_BK, + HW_VAR_ACM_CTRL, + HW_VAR_AMPDU_MIN_SPACE, + HW_VAR_AMPDU_FACTOR, + HW_VAR_RXDMA_AGG_PG_TH, + HW_VAR_SET_RPWM, + HW_VAR_CPWM, + HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_PS_TUNE_PARAM, + HW_VAR_H2C_FW_JOINBSSRPT, + HW_VAR_FWLPS_RF_ON, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + HW_VAR_TDLS_WRCR, + HW_VAR_TDLS_RS_RCR, + HW_VAR_TRIGGER_GPIO_0, + HW_VAR_BT_SET_COEXIST, + HW_VAR_BT_ISSUE_DELBA, + HW_VAR_CURRENT_ANTENNA, + HW_VAR_ANTENNA_DIVERSITY_SELECT, + HW_VAR_SWITCH_EPHY_WoWLAN, + HW_VAR_EFUSE_USAGE, + HW_VAR_EFUSE_BYTES, + HW_VAR_EFUSE_BT_USAGE, + HW_VAR_EFUSE_BT_BYTES, + HW_VAR_FIFO_CLEARN_UP, + HW_VAR_RESTORE_HW_SEQ, + HW_VAR_CHECK_TXBUF, + HW_VAR_PCIE_STOP_TX_DMA, + HW_VAR_APFM_ON_MAC, //Auto FSM to Turn On, include clock, isolation, power control for MAC only + HW_VAR_HCI_SUS_STATE, + // The valid upper nav range for the HW updating, if the true value is larger than the upper range, the HW won't update it. + // Unit in microsecond. 0 means disable this function. +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + HW_VAR_WOWLAN, + HW_VAR_WAKEUP_REASON, + HW_VAR_RPWM_TOG, +#endif +#ifdef CONFIG_GPIO_WAKEUP + HW_SET_GPIO_WL_CTRL, +#endif + HW_VAR_SYS_CLKR, + HW_VAR_NAV_UPPER, + HW_VAR_C2H_HANDLE, + HW_VAR_RPT_TIMER_SETTING, + HW_VAR_TX_RPT_MAX_MACID, + HW_VAR_CHK_HI_QUEUE_EMPTY, + HW_VAR_DL_BCN_SEL, + HW_VAR_AMPDU_MAX_TIME, + HW_VAR_WIRELESS_MODE, + HW_VAR_USB_MODE, + HW_VAR_PORT_SWITCH, + HW_VAR_DO_IQK, + HW_VAR_DM_IN_LPS, + HW_VAR_SET_REQ_FW_PS, + HW_VAR_FW_PS_STATE, + HW_VAR_SOUNDING_ENTER, + HW_VAR_SOUNDING_LEAVE, + HW_VAR_SOUNDING_RATE, + HW_VAR_SOUNDING_STATUS, + HW_VAR_SOUNDING_FW_NDPA, + HW_VAR_SOUNDING_CLK, +/*Add by YuChen for TXBF HW timer*/ + HW_VAR_HW_REG_TIMER_INIT, + HW_VAR_HW_REG_TIMER_RESTART, + HW_VAR_HW_REG_TIMER_START, + HW_VAR_HW_REG_TIMER_STOP, +/*Add by YuChen for TXBF HW timer*/ + HW_VAR_DL_RSVD_PAGE, + HW_VAR_MACID_LINK, + HW_VAR_MACID_NOLINK, + HW_VAR_MACID_SLEEP, + HW_VAR_MACID_WAKEUP, + HW_VAR_DUMP_MAC_QUEUE_INFO, + HW_VAR_ASIX_IOT, + HW_VAR_EN_HW_UPDATE_TSF, +}HW_VARIABLES; + +typedef enum _HAL_DEF_VARIABLE{ + HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, + HAL_DEF_IS_SUPPORT_ANT_DIV, + HAL_DEF_CURRENT_ANTENNA, + HAL_DEF_DRVINFO_SZ, + HAL_DEF_MAX_RECVBUF_SZ, + HAL_DEF_RX_PACKET_OFFSET, + HAL_DEF_RX_DMA_SZ_WOW, + HAL_DEF_RX_DMA_SZ, + HAL_DEF_RX_PAGE_SIZE, + HAL_DEF_DBG_DUMP_RXPKT,//for dbg + HAL_DEF_RA_DECISION_RATE, + HAL_DEF_RA_SGI, + HAL_DEF_PT_PWR_STATUS, + HAL_DEF_TX_LDPC, // LDPC support + HAL_DEF_RX_LDPC, // LDPC support + HAL_DEF_TX_STBC, // TX STBC support + HAL_DEF_RX_STBC, // RX STBC support + HAL_DEF_EXPLICIT_BEAMFORMER,// Explicit Compressed Steering Capable + HAL_DEF_EXPLICIT_BEAMFORMEE,// Explicit Compressed Beamforming Feedback Capable + HAL_DEF_BEAMFORMER_CAP, + HAL_DEF_BEAMFORMEE_CAP, + HW_VAR_MAX_RX_AMPDU_FACTOR, + HW_DEF_RA_INFO_DUMP, + HAL_DEF_DBG_DUMP_TXPKT, + + HAL_DEF_TX_PAGE_SIZE, + HAL_DEF_TX_PAGE_BOUNDARY, + HAL_DEF_TX_PAGE_BOUNDARY_WOWLAN, + HAL_DEF_ANT_DETECT,//to do for 8723a + HAL_DEF_PCI_SUUPORT_L1_BACKDOOR, // Determine if the L1 Backdoor setting is turned on. + HAL_DEF_PCI_AMD_L1_SUPPORT, + 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_DIS_PWT, //disable Tx power training or not. + HAL_DEF_EFUSE_USAGE, /* Get current EFUSE utilization. 2008.12.19. Added by Roger. */ + HAL_DEF_EFUSE_BYTES, + HW_VAR_BEST_AMPDU_DENSITY, +}HAL_DEF_VARIABLE; + +typedef enum _HAL_ODM_VARIABLE{ + HAL_ODM_STA_INFO, + HAL_ODM_P2P_STATE, + HAL_ODM_WIFI_DISPLAY_STATE, + HAL_ODM_NOISE_MONITOR, + HAL_ODM_REGULATION, + HAL_ODM_INITIAL_GAIN, + HAL_ODM_FA_CNT_DUMP, + HAL_ODM_DBG_FLAG, + HAL_ODM_DBG_LEVEL, + HAL_ODM_RX_INFO_DUMP, + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + HAL_ODM_AUTO_CHNL_SEL, +#endif +}HAL_ODM_VARIABLE; + +typedef enum _HAL_INTF_PS_FUNC{ + HAL_USB_SELECT_SUSPEND, + HAL_MAX_ID, +}HAL_INTF_PS_FUNC; + +typedef s32 (*c2h_id_filter)(u8 *c2h_evt); + +struct hal_ops { + /*** initialize section ***/ + void (*read_chip_version)(_adapter *padapter); + void (*init_default_value)(_adapter *padapter); + void (*intf_chip_configure)(_adapter *padapter); + void (*read_adapter_info)(_adapter *padapter); + u32 (*hal_power_on)(_adapter *padapter); + void (*hal_power_off)(_adapter *padapter); + u32 (*hal_init)(_adapter *padapter); + u32 (*hal_deinit)(_adapter *padapter); + void (*dm_init)(_adapter *padapter); + void (*dm_deinit)(_adapter *padapter); + + /*** xmit section ***/ + s32 (*init_xmit_priv)(_adapter *padapter); + void (*free_xmit_priv)(_adapter *padapter); + s32 (*hal_xmit)(_adapter *padapter, struct xmit_frame *pxmitframe); + /* + * mgnt_xmit should be implemented to run in interrupt context + */ + s32 (*mgnt_xmit)(_adapter *padapter, struct xmit_frame *pmgntframe); + s32 (*hal_xmitframe_enqueue)(_adapter *padapter, struct xmit_frame *pxmitframe); +#ifdef CONFIG_XMIT_THREAD_MODE + s32 (*xmit_thread_handler)(_adapter *padapter); +#endif + void (*run_thread)(_adapter *padapter); + void (*cancel_thread)(_adapter *padapter); + + /*** recv section ***/ + s32 (*init_recv_priv)(_adapter *padapter); + void (*free_recv_priv)(_adapter *padapter); +#if defined(CONFIG_USB_HCI)||defined(CONFIG_PCI_HCI) + u32 (*inirp_init)(_adapter *padapter); + u32 (*inirp_deinit)(_adapter *padapter); +#endif + /*** interrupt hdl section ***/ + void (*enable_interrupt)(_adapter *padapter); + void (*disable_interrupt)(_adapter *padapter); + u8 (*check_ips_status)(_adapter *padapter); +#if defined(CONFIG_PCI_HCI) + s32 (*interrupt_handler)(_adapter *padapter); +#endif + +#if defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT) + void (*interrupt_handler)(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif + +#if defined(CONFIG_PCI_HCI) + void (*irp_reset)(_adapter *padapter); +#endif + + /*** DM section ***/ + + void (*InitSwLeds)(_adapter *padapter); + void (*DeInitSwLeds)(_adapter *padapter); + + + void (*set_bwmode_handler)(_adapter *padapter, CHANNEL_WIDTH Bandwidth, u8 Offset); + void (*set_channel_handler)(_adapter *padapter, u8 channel); + void (*set_chnl_bw_handler)(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80); + + void (*set_tx_power_level_handler)(_adapter *padapter, u8 channel); + void (*get_tx_power_level_handler)(_adapter *padapter, s32 *powerlevel); + + void (*hal_dm_watchdog)(_adapter *padapter); +#ifdef CONFIG_LPS_LCLK_WD_TIMER + void (*hal_dm_watchdog_in_lps)(_adapter *padapter); +#endif + + void (*SetHwRegHandler)(_adapter *padapter, u8 variable,u8* val); + void (*GetHwRegHandler)(_adapter *padapter, u8 variable,u8* val); + +#ifdef CONFIG_C2H_PACKET_EN + void (*SetHwRegHandlerWithBuf)(_adapter *padapter, u8 variable, u8 * pbuf, int len); +#endif + + u8 (*GetHalDefVarHandler)(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + u8 (*SetHalDefVarHandler)(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + + void (*GetHalODMVarHandler)(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,PVOID pValue2); + void (*SetHalODMVarHandler)(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet); + + void (*UpdateRAMaskHandler)(_adapter *padapter, u32 mac_id, u8 rssi_level); + void (*SetBeaconRelatedRegistersHandler)(_adapter *padapter); + + void (*Add_RateATid)(_adapter *padapter, u64 bitmap, u8 *arg, u8 rssi_level); + + +#ifdef CONFIG_ANTENNA_DIVERSITY + u8 (*AntDivBeforeLinkHandler)(_adapter *padapter); + void (*AntDivCompareHandler)(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +#endif + u8 (*interface_ps_func)(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val); + + + u32 (*read_bbreg)(_adapter *padapter, u32 RegAddr, u32 BitMask); + void (*write_bbreg)(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); + u32 (*read_rfreg)(_adapter *padapter, u8 eRFPath, u32 RegAddr, u32 BitMask); + void (*write_rfreg)(_adapter *padapter, u8 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); + +#ifdef CONFIG_HOSTAPD_MLME + s32 (*hostap_mgnt_xmit_entry)(_adapter *padapter, _pkt *pkt); +#endif + + void (*EfusePowerSwitch)(_adapter *padapter, u8 bWrite, u8 PwrState); + void (*BTEfusePowerSwitch)(_adapter *padapter, u8 bWrite, u8 PwrState); + void (*ReadEFuse)(_adapter *padapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, BOOLEAN bPseudoTest); + void (*EFUSEGetEfuseDefinition)(_adapter *padapter, u8 efuseType, u8 type, void *pOut, BOOLEAN bPseudoTest); + u16 (*EfuseGetCurrentSize)(_adapter *padapter, u8 efuseType, BOOLEAN bPseudoTest); + int (*Efuse_PgPacketRead)(_adapter *padapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); + int (*Efuse_PgPacketWrite)(_adapter *padapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + u8 (*Efuse_WordEnableDataWrite)(_adapter *padapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + BOOLEAN (*Efuse_PgPacketWrite_BT)(_adapter *padapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + +#ifdef DBG_CONFIG_ERROR_DETECT + void (*sreset_init_value)(_adapter *padapter); + void (*sreset_reset_value)(_adapter *padapter); + void (*silentreset)(_adapter *padapter); + void (*sreset_xmit_status_check)(_adapter *padapter); + void (*sreset_linked_status_check) (_adapter *padapter); + u8 (*sreset_get_wifi_status)(_adapter *padapter); + bool (*sreset_inprogress)(_adapter *padapter); +#endif + +#ifdef CONFIG_IOL + int (*IOL_exec_cmds_sync)(_adapter *padapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt); +#endif + + void (*hal_notch_filter)(_adapter * adapter, bool enable); + s32 (*c2h_handler)(_adapter *padapter, u8 *c2h_evt); + c2h_id_filter c2h_id_filter_ccx; + s32 (*fill_h2c_cmd)(PADAPTER, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); + void (*fill_fake_txdesc)(PADAPTER, u8 *pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) + void (*hal_set_wowlan_fw)(_adapter *adapter, u8 sleep); + void (*clear_interrupt)(_adapter *padapter); +#endif + u8 (*hal_get_tx_buff_rsvd_page_num)(_adapter *adapter, bool wowlan); +#ifdef CONFIG_GPIO_API + void (*update_hisr_hsisr_ind)(PADAPTER padapter, u32 flag); +#endif + void (*fw_correct_bcn)(PADAPTER padapter); +}; + +typedef enum _RT_EEPROM_TYPE{ + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}RT_EEPROM_TYPE,*PRT_EEPROM_TYPE; + + + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_SW BIT31 + +typedef enum _HARDWARE_TYPE{ + HARDWARE_TYPE_RTL8188EE, + HARDWARE_TYPE_RTL8188EU, + HARDWARE_TYPE_RTL8188ES, +// NEW_GENERATION_IC + HARDWARE_TYPE_RTL8192EE, + HARDWARE_TYPE_RTL8192EU, + HARDWARE_TYPE_RTL8192ES, + HARDWARE_TYPE_RTL8812E, + HARDWARE_TYPE_RTL8812AU, + HARDWARE_TYPE_RTL8811AU, + HARDWARE_TYPE_RTL8821E, + HARDWARE_TYPE_RTL8821U, + HARDWARE_TYPE_RTL8821S, + HARDWARE_TYPE_RTL8723BE, + HARDWARE_TYPE_RTL8723BU, + HARDWARE_TYPE_RTL8723BS, + HARDWARE_TYPE_RTL8814AE, + HARDWARE_TYPE_RTL8814AU, + HARDWARE_TYPE_RTL8814AS, + HARDWARE_TYPE_RTL8821BE, + HARDWARE_TYPE_RTL8821BU, + HARDWARE_TYPE_RTL8821BS, + HARDWARE_TYPE_RTL8822BE, + HARDWARE_TYPE_RTL8822BU, + HARDWARE_TYPE_RTL8822BS, + HARDWARE_TYPE_RTL8703BE, + HARDWARE_TYPE_RTL8703BU, + HARDWARE_TYPE_RTL8703BS, + HARDWARE_TYPE_RTL8188FE, + HARDWARE_TYPE_RTL8188FU, + HARDWARE_TYPE_RTL8188FS, + HARDWARE_TYPE_MAX, +}HARDWARE_TYPE; + +#define IS_NEW_GENERATION_IC(_Adapter) (rtw_get_hw_type(_Adapter) >= HARDWARE_TYPE_RTL8192EE) +// +// RTL8188E Series +// +#define IS_HARDWARE_TYPE_8188EE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188EE) +#define IS_HARDWARE_TYPE_8188EU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188EU) +#define IS_HARDWARE_TYPE_8188ES(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188ES) +#define IS_HARDWARE_TYPE_8188E(_Adapter) \ +(IS_HARDWARE_TYPE_8188EE(_Adapter) || IS_HARDWARE_TYPE_8188EU(_Adapter) || IS_HARDWARE_TYPE_8188ES(_Adapter)) + +// RTL8812 Series +#define IS_HARDWARE_TYPE_8812E(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8812E) +#define IS_HARDWARE_TYPE_8812AU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8812AU) +#define IS_HARDWARE_TYPE_8812(_Adapter) \ +(IS_HARDWARE_TYPE_8812E(_Adapter) || IS_HARDWARE_TYPE_8812AU(_Adapter)) + +// RTL8821 Series +#define IS_HARDWARE_TYPE_8821E(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821E) +#define IS_HARDWARE_TYPE_8811AU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8811AU) +#define IS_HARDWARE_TYPE_8821U(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821U || \ + rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8811AU) +#define IS_HARDWARE_TYPE_8821S(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821S) +#define IS_HARDWARE_TYPE_8821(_Adapter) \ +(IS_HARDWARE_TYPE_8821E(_Adapter) || IS_HARDWARE_TYPE_8821U(_Adapter)|| IS_HARDWARE_TYPE_8821S(_Adapter)) + +#define IS_HARDWARE_TYPE_JAGUAR(_Adapter) \ +(IS_HARDWARE_TYPE_8812(_Adapter) || IS_HARDWARE_TYPE_8821(_Adapter)) + +//RTL8192E Series +#define IS_HARDWARE_TYPE_8192EE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8192EU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8192EU) +#define IS_HARDWARE_TYPE_8192ES(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8192ES) + +#define IS_HARDWARE_TYPE_8192E(_Adapter) \ +(IS_HARDWARE_TYPE_8192EE(_Adapter) || IS_HARDWARE_TYPE_8192EU(_Adapter) ||IS_HARDWARE_TYPE_8192ES(_Adapter)) + +#define IS_HARDWARE_TYPE_8723BE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723BE) +#define IS_HARDWARE_TYPE_8723BU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723BU) +#define IS_HARDWARE_TYPE_8723BS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8723BS) + +#define IS_HARDWARE_TYPE_8723B(_Adapter) \ + (IS_HARDWARE_TYPE_8723BE(_Adapter) || IS_HARDWARE_TYPE_8723BU(_Adapter) ||IS_HARDWARE_TYPE_8723BS(_Adapter)) + +/* RTL8814A Series */ +#define IS_HARDWARE_TYPE_8814AE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8814AE) +#define IS_HARDWARE_TYPE_8814AU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8814AU) +#define IS_HARDWARE_TYPE_8814AS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8814AS) + +#define IS_HARDWARE_TYPE_8814A(_Adapter) \ +(IS_HARDWARE_TYPE_8814AE(_Adapter) || IS_HARDWARE_TYPE_8814AU(_Adapter) || IS_HARDWARE_TYPE_8814AS(_Adapter)) + +#define IS_HARDWARE_TYPE_JAGUAR2(_Adapter) \ +(IS_HARDWARE_TYPE_8814A(_Adapter) || IS_HARDWARE_TYPE_8821B(_Adapter) || IS_HARDWARE_TYPE_8822B(_Adapter)) + +#define IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(_Adapter) \ +(IS_HARDWARE_TYPE_JAGUAR(_Adapter) || IS_HARDWARE_TYPE_JAGUAR2(_Adapter)) + +/* RTL8703B Series */ +#define IS_HARDWARE_TYPE_8703BE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8703BE) +#define IS_HARDWARE_TYPE_8703BS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8703BS) +#define IS_HARDWARE_TYPE_8703BU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8703BU) +#define IS_HARDWARE_TYPE_8703B(_Adapter) \ +(IS_HARDWARE_TYPE_8703BE(_Adapter) || IS_HARDWARE_TYPE_8703BU(_Adapter) || IS_HARDWARE_TYPE_8703BS(_Adapter)) + +/* RTL8188F Series */ +#define IS_HARDWARE_TYPE_8188FE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188FE) +#define IS_HARDWARE_TYPE_8188FS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188FS) +#define IS_HARDWARE_TYPE_8188FU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8188FU) +#define IS_HARDWARE_TYPE_8188F(_Adapter) \ +(IS_HARDWARE_TYPE_8188FE(_Adapter) || IS_HARDWARE_TYPE_8188FU(_Adapter) || IS_HARDWARE_TYPE_8188FS(_Adapter)) + +#define IS_HARDWARE_TYPE_8821BE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821BE) +#define IS_HARDWARE_TYPE_8821BU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821BU) +#define IS_HARDWARE_TYPE_8821BS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8821BS) + +#define IS_HARDWARE_TYPE_8821B(_Adapter) \ +(IS_HARDWARE_TYPE_8821BE(_Adapter) || IS_HARDWARE_TYPE_8821BU(_Adapter) || IS_HARDWARE_TYPE_8821BS(_Adapter)) + +#define IS_HARDWARE_TYPE_8822BE(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8822BE) +#define IS_HARDWARE_TYPE_8822BU(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8822BU) +#define IS_HARDWARE_TYPE_8822BS(_Adapter) (rtw_get_hw_type(_Adapter) == HARDWARE_TYPE_RTL8822BS) +#define IS_HARDWARE_TYPE_8822B(_Adapter) \ +(IS_HARDWARE_TYPE_8822BE(_Adapter) || IS_HARDWARE_TYPE_8822BU(_Adapter) || IS_HARDWARE_TYPE_8822BS(_Adapter)) + + + +typedef enum _wowlan_subcode { + WOWLAN_ENABLE = 0, + WOWLAN_DISABLE = 1, + WOWLAN_AP_ENABLE = 2, + WOWLAN_AP_DISABLE = 3, + WOWLAN_PATTERN_CLEAN = 4 +} wowlan_subcode; + +struct wowlan_ioctl_param{ + unsigned int subcode; + unsigned int subcode_value; + unsigned int wakeup_reason; +}; + +#define Rx_Pairwisekey 0x01 +#define Rx_GTK 0x02 +#define Rx_DisAssoc 0x04 +#define Rx_DeAuth 0x08 +#define Rx_ARPReq 0x09 +#define FWDecisionDisconnect 0x10 +#define Rx_MagicPkt 0x21 +#define Rx_UnicastPkt 0x22 +#define Rx_PatternPkt 0x23 +#define RX_PNOWakeUp 0x55 +#define AP_WakeUp 0x66 + +u8 rtw_hal_data_init(_adapter *padapter); +void rtw_hal_data_deinit(_adapter *padapter); + +void rtw_hal_def_value_init(_adapter *padapter); + +void rtw_hal_free_data(_adapter *padapter); + +void rtw_hal_dm_init(_adapter *padapter); +void rtw_hal_dm_deinit(_adapter *padapter); +void rtw_hal_sw_led_init(_adapter *padapter); +void rtw_hal_sw_led_deinit(_adapter *padapter); + +u32 rtw_hal_power_on(_adapter *padapter); +void rtw_hal_power_off(_adapter *padapter); + +uint rtw_hal_init(_adapter *padapter); +uint rtw_hal_deinit(_adapter *padapter); +void rtw_hal_stop(_adapter *padapter); +void rtw_hal_set_hwreg(PADAPTER padapter, u8 variable, u8 *val); +void rtw_hal_get_hwreg(PADAPTER padapter, u8 variable, u8 *val); + +#ifdef CONFIG_C2H_PACKET_EN +void rtw_hal_set_hwreg_with_buf(_adapter *padapter, u8 variable, u8 *pbuf, int len); +#endif + +void rtw_hal_chip_configure(_adapter *padapter); +void rtw_hal_read_chip_info(_adapter *padapter); +void rtw_hal_read_chip_version(_adapter *padapter); + +u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); +u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + +void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet); +void rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,PVOID pValue2); + +void rtw_hal_enable_interrupt(_adapter *padapter); +void rtw_hal_disable_interrupt(_adapter *padapter); + +u8 rtw_hal_check_ips_status(_adapter *padapter); + +#if defined(CONFIG_USB_HCI)||defined(CONFIG_PCI_HCI) +u32 rtw_hal_inirp_init(_adapter *padapter); +u32 rtw_hal_inirp_deinit(_adapter *padapter); +#endif + +#if defined(CONFIG_PCI_HCI) +void rtw_hal_irp_reset(_adapter *padapter); +#endif + +u8 rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val); + +s32 rtw_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtw_hal_init_xmit_priv(_adapter *padapter); +void rtw_hal_free_xmit_priv(_adapter *padapter); + +s32 rtw_hal_init_recv_priv(_adapter *padapter); +void rtw_hal_free_recv_priv(_adapter *padapter); + +void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level); +void rtw_hal_add_ra_tid(_adapter *padapter, u64 bitmap, u8 *arg, u8 rssi_level); + +void rtw_hal_start_thread(_adapter *padapter); +void rtw_hal_stop_thread(_adapter *padapter); + +void rtw_hal_bcn_related_reg_setting(_adapter *padapter); + +u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask); +void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); +u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask); +void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); + +#define PHY_QueryBBReg(Adapter, RegAddr, BitMask) rtw_hal_read_bbreg((Adapter), (RegAddr), (BitMask)) +#define PHY_SetBBReg(Adapter, RegAddr, BitMask, Data) rtw_hal_write_bbreg((Adapter), (RegAddr), (BitMask), (Data)) +#define PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask) rtw_hal_read_rfreg((Adapter), (eRFPath), (RegAddr), (BitMask)) +#define PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data) rtw_hal_write_rfreg((Adapter), (eRFPath), (RegAddr), (BitMask), (Data)) + +#define PHY_SetMacReg PHY_SetBBReg +#define PHY_QueryMacReg PHY_QueryBBReg + +#if defined(CONFIG_PCI_HCI) +s32 rtw_hal_interrupt_handler(_adapter *padapter); +#endif +#if defined(CONFIG_USB_HCI) && defined(CONFIG_SUPPORT_USB_INT) +void rtw_hal_interrupt_handler(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif + +void rtw_hal_set_bwmode(_adapter *padapter, CHANNEL_WIDTH Bandwidth, u8 Offset); +void rtw_hal_set_chan(_adapter *padapter, u8 channel); +void rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80); +void rtw_hal_dm_watchdog(_adapter *padapter); +void rtw_hal_dm_watchdog_in_lps(_adapter *padapter); + +void rtw_hal_set_tx_power_level(_adapter *padapter, u8 channel); +void rtw_hal_get_tx_power_level(_adapter *padapter, s32 *powerlevel); + +#ifdef CONFIG_ANTENNA_DIVERSITY +u8 rtw_hal_antdiv_before_linked(_adapter *padapter); +void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +#endif + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtw_hal_sreset_init(_adapter *padapter); +void rtw_hal_sreset_reset(_adapter *padapter); +void rtw_hal_sreset_reset_value(_adapter *padapter); +void rtw_hal_sreset_xmit_status_check(_adapter *padapter); +void rtw_hal_sreset_linked_status_check (_adapter *padapter); +u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter); +bool rtw_hal_sreset_inprogress(_adapter *padapter); +#endif + +#ifdef CONFIG_IOL +int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt); +#endif + +#ifdef CONFIG_XMIT_THREAD_MODE +s32 rtw_hal_xmit_thread_handler(_adapter *padapter); +#endif + +void rtw_hal_notch_filter(_adapter * adapter, bool enable); + +bool rtw_hal_c2h_valid(_adapter *adapter, u8 *buf); +s32 rtw_hal_c2h_evt_read(_adapter *adapter, u8 *buf); +s32 rtw_hal_c2h_handler(_adapter *adapter, u8 *c2h_evt); +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, u8 macid); +s32 rtw_hal_macid_wakeup(PADAPTER padapter, u8 macid); + +s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +void rtw_hal_fill_fake_txdesc(_adapter *padapter, u8 *pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); +u8 rtw_hal_get_txbuff_rsvd_page_num(_adapter *adapter, bool wowlan); + +#ifdef CONFIG_GPIO_API +void rtw_hal_update_hisr_hsisr_ind(_adapter *padapter, u32 flag); +#endif + +void rtw_hal_fw_correct_bcn(_adapter *padapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtw_hal_clear_interrupt(_adapter *padapter); +void rtw_hal_set_wowlan_fw(_adapter *padapter, u8 sleep); +#endif +u8 rtw_hal_ops_check(_adapter *padapter); + +#endif //__HAL_INTF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_pg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_pg.h new file mode 100644 index 00000000..d1b0023e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_pg.h @@ -0,0 +1,659 @@ +/****************************************************************************** + * + * 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 __HAL_PG_H__ +#define __HAL_PG_H__ + +#define PPG_BB_GAIN_2G_TX_OFFSET_MASK 0x0F +#define PPG_BB_GAIN_2G_TXB_OFFSET_MASK 0xF0 + +#define PPG_BB_GAIN_5G_TX_OFFSET_MASK 0x1F +#define PPG_THERMAL_OFFSET_MASK 0x1F +#define KFREE_BB_GAIN_2G_TX_OFFSET(_ppg_v) (((_ppg_v) == PPG_BB_GAIN_2G_TX_OFFSET_MASK) ? 0 : (((_ppg_v) & 0x01) ? ((_ppg_v) >> 1) : (-((_ppg_v) >> 1)))) +#define KFREE_BB_GAIN_5G_TX_OFFSET(_ppg_v) (((_ppg_v) == PPG_BB_GAIN_5G_TX_OFFSET_MASK) ? 0 : (((_ppg_v) & 0x01) ? ((_ppg_v) >> 1) : (-((_ppg_v) >> 1)))) +#define KFREE_THERMAL_OFFSET(_ppg_v) (((_ppg_v) == PPG_THERMAL_OFFSET_MASK) ? 0 : (((_ppg_v) & 0x01) ? ((_ppg_v) >> 1) : (-((_ppg_v) >> 1)))) + +//==================================================== +// EEPROM/Efuse PG Offset for 88EE/88EU/88ES +//==================================================== +#define EEPROM_TX_PWR_INX_88E 0x10 + +#define EEPROM_ChannelPlan_88E 0xB8 +#define EEPROM_XTAL_88E 0xB9 +#define EEPROM_THERMAL_METER_88E 0xBA +#define EEPROM_IQK_LCK_88E 0xBB + +#define EEPROM_RF_BOARD_OPTION_88E 0xC1 +#define EEPROM_RF_FEATURE_OPTION_88E 0xC2 +#define EEPROM_RF_BT_SETTING_88E 0xC3 +#define EEPROM_VERSION_88E 0xC4 +#define EEPROM_CustomID_88E 0xC5 +#define EEPROM_RF_ANTENNA_OPT_88E 0xC9 +#define EEPROM_COUNTRY_CODE_88E 0xCB + +// RTL88EE +#define EEPROM_MAC_ADDR_88EE 0xD0 +#define EEPROM_VID_88EE 0xD6 +#define EEPROM_DID_88EE 0xD8 +#define EEPROM_SVID_88EE 0xDA +#define EEPROM_SMID_88EE 0xDC + +//RTL88EU +#define EEPROM_MAC_ADDR_88EU 0xD7 +#define EEPROM_VID_88EU 0xD0 +#define EEPROM_PID_88EU 0xD2 +#define EEPROM_USB_OPTIONAL_FUNCTION0 0xD4 //8188EU,8192EU, 8812AU is the same +#define EEPROM_USB_OPTIONAL_FUNCTION0_8811AU 0x104 + +// RTL88ES +#define EEPROM_MAC_ADDR_88ES 0x11A +//==================================================== +// EEPROM/Efuse PG Offset for 8192EE/8192EU/8192ES +//==================================================== +#define GET_PG_KFREE_ON_8192E(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC1, 4, 1) +#define GET_PG_KFREE_THERMAL_K_ON_8192E(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 5, 1) + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8192E 0x1F6 +#define PPG_THERMAL_OFFSET_8192E 0x1F5 + +// 0x10 ~ 0x63 = TX power area. +#define EEPROM_TX_PWR_INX_8192E 0x10 + +#define EEPROM_ChannelPlan_8192E 0xB8 +#define EEPROM_XTAL_8192E 0xB9 +#define EEPROM_THERMAL_METER_8192E 0xBA +#define EEPROM_IQK_LCK_8192E 0xBB +#define EEPROM_2G_5G_PA_TYPE_8192E 0xBC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8192E 0xBD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8192E 0xBF + +#define EEPROM_RF_BOARD_OPTION_8192E 0xC1 +#define EEPROM_RF_FEATURE_OPTION_8192E 0xC2 +#define EEPROM_RF_BT_SETTING_8192E 0xC3 +#define EEPROM_VERSION_8192E 0xC4 +#define EEPROM_CustomID_8192E 0xC5 +#define EEPROM_TX_BBSWING_2G_8192E 0xC6 +#define EEPROM_TX_BBSWING_5G_8192E 0xC7 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8192E 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8192E 0xC9 +#define EEPROM_RFE_OPTION_8192E 0xCA +#define EEPROM_COUNTRY_CODE_8192E 0xCB + +// RTL8192EE +#define EEPROM_MAC_ADDR_8192EE 0xD0 +#define EEPROM_VID_8192EE 0xD6 +#define EEPROM_DID_8192EE 0xD8 +#define EEPROM_SVID_8192EE 0xDA +#define EEPROM_SMID_8192EE 0xDC + +//RTL8192EU +#define EEPROM_MAC_ADDR_8192EU 0xD7 +#define EEPROM_VID_8192EU 0xD0 +#define EEPROM_PID_8192EU 0xD2 +#define EEPROM_PA_TYPE_8192EU 0xBC +#define EEPROM_LNA_TYPE_2G_8192EU 0xBD +#define EEPROM_LNA_TYPE_5G_8192EU 0xBF + +// RTL8192ES +#define EEPROM_MAC_ADDR_8192ES 0x11A +//==================================================== +// EEPROM/Efuse PG Offset for 8812AE/8812AU/8812AS +//==================================================== +// 0x10 ~ 0x63 = TX power area. +#define EEPROM_USB_MODE_8812 0x08 +#define EEPROM_TX_PWR_INX_8812 0x10 + +#define EEPROM_ChannelPlan_8812 0xB8 +#define EEPROM_XTAL_8812 0xB9 +#define EEPROM_THERMAL_METER_8812 0xBA +#define EEPROM_IQK_LCK_8812 0xBB +#define EEPROM_2G_5G_PA_TYPE_8812 0xBC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8812 0xBD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8812 0xBF + +#define EEPROM_RF_BOARD_OPTION_8812 0xC1 +#define EEPROM_RF_FEATURE_OPTION_8812 0xC2 +#define EEPROM_RF_BT_SETTING_8812 0xC3 +#define EEPROM_VERSION_8812 0xC4 +#define EEPROM_CustomID_8812 0xC5 +#define EEPROM_TX_BBSWING_2G_8812 0xC6 +#define EEPROM_TX_BBSWING_5G_8812 0xC7 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8812 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8812 0xC9 +#define EEPROM_RFE_OPTION_8812 0xCA +#define EEPROM_COUNTRY_CODE_8812 0xCB + +// RTL8812AE +#define EEPROM_MAC_ADDR_8812AE 0xD0 +#define EEPROM_VID_8812AE 0xD6 +#define EEPROM_DID_8812AE 0xD8 +#define EEPROM_SVID_8812AE 0xDA +#define EEPROM_SMID_8812AE 0xDC + +//RTL8812AU +#define EEPROM_MAC_ADDR_8812AU 0xD7 +#define EEPROM_VID_8812AU 0xD0 +#define EEPROM_PID_8812AU 0xD2 +#define EEPROM_PA_TYPE_8812AU 0xBC +#define EEPROM_LNA_TYPE_2G_8812AU 0xBD +#define EEPROM_LNA_TYPE_5G_8812AU 0xBF + +//RTL8814AU +#define EEPROM_MAC_ADDR_8814AU 0xD8 +#define EEPROM_VID_8814AU 0xD0 +#define EEPROM_PID_8814AU 0xD2 +#define EEPROM_PA_TYPE_8814AU 0xBC +#define EEPROM_LNA_TYPE_2G_8814AU 0xBD +#define EEPROM_LNA_TYPE_5G_8814AU 0xBF + +/* RTL8814AE */ +#define EEPROM_MAC_ADDR_8814AE 0xD0 +#define EEPROM_VID_8814AE 0xD6 +#define EEPROM_DID_8814AE 0xD8 +#define EEPROM_SVID_8814AE 0xDA +#define EEPROM_SMID_8814AE 0xDC + +//==================================================== +// EEPROM/Efuse PG Offset for 8814AU +//==================================================== +#define GET_PG_KFREE_ON_8814A(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 4, 1) +#define GET_PG_KFREE_THERMAL_K_ON_8814A(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 5, 1) +#define GET_PG_TX_POWER_TRACKING_MODE_8814A(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 6, 2) + +#define KFREE_GAIN_DATA_LENGTH_8814A 22 + +#define PPG_BB_GAIN_2G_TXBA_OFFSET_8814A 0x3EE + +#define PPG_THERMAL_OFFSET_8814A 0x3EF + +#define EEPROM_TX_PWR_INX_8814 0x10 +#define EEPROM_ChannelPlan_8814 0xB8 +#define EEPROM_XTAL_8814 0xB9 +#define EEPROM_THERMAL_METER_8814 0xBA +#define EEPROM_IQK_LCK_8814 0xBB + + +#define EEPROM_PA_TYPE_8814 0xBC +#define EEPROM_LNA_TYPE_AB_2G_8814 0xBD +#define EEPROM_LNA_TYPE_CD_2G_8814 0xBE +#define EEPROM_LNA_TYPE_AB_5G_8814 0xBF +#define EEPROM_LNA_TYPE_CD_5G_8814 0xC0 +#define EEPROM_RF_BOARD_OPTION_8814 0xC1 +#define EEPROM_RF_BT_SETTING_8814 0xC3 +#define EEPROM_VERSION_8814 0xC4 +#define EEPROM_CustomID_8814 0xC5 +#define EEPROM_TX_BBSWING_2G_8814 0xC6 +#define EEPROM_TX_BBSWING_5G_8814 0xC7 +#define EEPROM_TRX_ANTENNA_OPTION_8814 0xC9 +#define EEPROM_RFE_OPTION_8814 0xCA +#define EEPROM_COUNTRY_CODE_8814 0xCB + +/*Extra Info for 8814A Initial Gain Fine Tune suggested by Willis, JIRA: MP123*/ +#define EEPROM_IG_OFFSET_4_AB_2G_8814A 0x120 +#define EEPROM_IG_OFFSET_4_CD_2G_8814A 0x121 +#define EEPROM_IG_OFFSET_4_AB_5GL_8814A 0x122 +#define EEPROM_IG_OFFSET_4_CD_5GL_8814A 0x123 +#define EEPROM_IG_OFFSET_4_AB_5GM_8814A 0x124 +#define EEPROM_IG_OFFSET_4_CD_5GM_8814A 0x125 +#define EEPROM_IG_OFFSET_4_AB_5GH_8814A 0x126 +#define EEPROM_IG_OFFSET_4_CD_5GH_8814A 0x127 + +//==================================================== +// EEPROM/Efuse PG Offset for 8821AE/8821AU/8821AS +//==================================================== + +#define GET_PG_KFREE_ON_8821A(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 4, 1) +#define GET_PG_KFREE_THERMAL_K_ON_8821A(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 5, 1) + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8821A 0x1F6 +#define PPG_THERMAL_OFFSET_8821A 0x1F5 +#define PPG_BB_GAIN_5GLB1_TXA_OFFSET_8821A 0x1F4 +#define PPG_BB_GAIN_5GLB2_TXA_OFFSET_8821A 0x1F3 +#define PPG_BB_GAIN_5GMB1_TXA_OFFSET_8821A 0x1F2 +#define PPG_BB_GAIN_5GMB2_TXA_OFFSET_8821A 0x1F1 +#define PPG_BB_GAIN_5GHB_TXA_OFFSET_8821A 0x1F0 + +#define EEPROM_TX_PWR_INX_8821 0x10 + +#define EEPROM_ChannelPlan_8821 0xB8 +#define EEPROM_XTAL_8821 0xB9 +#define EEPROM_THERMAL_METER_8821 0xBA +#define EEPROM_IQK_LCK_8821 0xBB + + +#define EEPROM_RF_BOARD_OPTION_8821 0xC1 +#define EEPROM_RF_FEATURE_OPTION_8821 0xC2 +#define EEPROM_RF_BT_SETTING_8821 0xC3 +#define EEPROM_VERSION_8821 0xC4 +#define EEPROM_CustomID_8821 0xC5 +#define EEPROM_RF_ANTENNA_OPT_8821 0xC9 + +// RTL8821AE +#define EEPROM_MAC_ADDR_8821AE 0xD0 +#define EEPROM_VID_8821AE 0xD6 +#define EEPROM_DID_8821AE 0xD8 +#define EEPROM_SVID_8821AE 0xDA +#define EEPROM_SMID_8821AE 0xDC + +//RTL8821AU +#define EEPROM_PA_TYPE_8821AU 0xBC +#define EEPROM_LNA_TYPE_8821AU 0xBF + +// RTL8821AS +#define EEPROM_MAC_ADDR_8821AS 0x11A + +//RTL8821AU +#define EEPROM_MAC_ADDR_8821AU 0x107 +#define EEPROM_VID_8821AU 0x100 +#define EEPROM_PID_8821AU 0x102 + + +//==================================================== +// EEPROM/Efuse PG Offset for 8192 SE/SU +//==================================================== +#define EEPROM_VID_92SE 0x0A +#define EEPROM_DID_92SE 0x0C +#define EEPROM_SVID_92SE 0x0E +#define EEPROM_SMID_92SE 0x10 + +#define EEPROM_MAC_ADDR_92S 0x12 + +#define EEPROM_TSSI_A_92SE 0x74 +#define EEPROM_TSSI_B_92SE 0x75 + +#define EEPROM_Version_92SE 0x7C + + +#define EEPROM_VID_92SU 0x08 +#define EEPROM_PID_92SU 0x0A + +#define EEPROM_Version_92SU 0x50 +#define EEPROM_TSSI_A_92SU 0x6b +#define EEPROM_TSSI_B_92SU 0x6c + +/* ==================================================== + EEPROM/Efuse PG Offset for 8188FE/8188FU/8188FS + ==================================================== + */ + +#define GET_PG_KFREE_ON_8188F(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC1, 4, 1) +#define GET_PG_KFREE_THERMAL_K_ON_8188F(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 5, 1) + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8188F 0xEE +#define PPG_THERMAL_OFFSET_8188F 0xEF + +/* 0x10 ~ 0x63 = TX power area. */ +#define EEPROM_TX_PWR_INX_8188F 0x10 + +#define EEPROM_ChannelPlan_8188F 0xB8 +#define EEPROM_XTAL_8188F 0xB9 +#define EEPROM_THERMAL_METER_8188F 0xBA +#define EEPROM_IQK_LCK_8188F 0xBB +#define EEPROM_2G_5G_PA_TYPE_8188F 0xBC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8188F 0xBD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8188F 0xBF + +#define EEPROM_RF_BOARD_OPTION_8188F 0xC1 +#define EEPROM_FEATURE_OPTION_8188F 0xC2 +#define EEPROM_RF_BT_SETTING_8188F 0xC3 +#define EEPROM_VERSION_8188F 0xC4 +#define EEPROM_CustomID_8188F 0xC5 +#define EEPROM_TX_BBSWING_2G_8188F 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8188F 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8188F 0xC9 +#define EEPROM_RFE_OPTION_8188F 0xCA +#define EEPROM_COUNTRY_CODE_8188F 0xCB +#define EEPROM_CUSTOMER_ID_8188F 0x7F +#define EEPROM_SUBCUSTOMER_ID_8188F 0x59 + +/* RTL8188FU */ +#define EEPROM_MAC_ADDR_8188FU 0xD7 +#define EEPROM_VID_8188FU 0xD0 +#define EEPROM_PID_8188FU 0xD2 +#define EEPROM_PA_TYPE_8188FU 0xBC +#define EEPROM_LNA_TYPE_2G_8188FU 0xBD +#define EEPROM_USB_OPTIONAL_FUNCTION0_8188FU 0xD4 + +/* RTL8188FS */ +#define EEPROM_MAC_ADDR_8188FS 0x11A +#define EEPROM_Voltage_ADDR_8188F 0x8 + +//==================================================== +// EEPROM/Efuse PG Offset for 8723BE/8723BU/8723BS +//==================================================== +// 0x10 ~ 0x63 = TX power area. +#define EEPROM_TX_PWR_INX_8723B 0x10 + +#define EEPROM_ChannelPlan_8723B 0xB8 +#define EEPROM_XTAL_8723B 0xB9 +#define EEPROM_THERMAL_METER_8723B 0xBA +#define EEPROM_IQK_LCK_8723B 0xBB +#define EEPROM_2G_5G_PA_TYPE_8723B 0xBC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8723B 0xBD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8723B 0xBF + +#define EEPROM_RF_BOARD_OPTION_8723B 0xC1 +#define EEPROM_FEATURE_OPTION_8723B 0xC2 +#define EEPROM_RF_BT_SETTING_8723B 0xC3 +#define EEPROM_VERSION_8723B 0xC4 +#define EEPROM_CustomID_8723B 0xC5 +#define EEPROM_TX_BBSWING_2G_8723B 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8723B 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8723B 0xC9 +#define EEPROM_RFE_OPTION_8723B 0xCA +#define EEPROM_COUNTRY_CODE_8723B 0xCB + +// RTL8723BE +#define EEPROM_MAC_ADDR_8723BE 0xD0 +#define EEPROM_VID_8723BE 0xD6 +#define EEPROM_DID_8723BE 0xD8 +#define EEPROM_SVID_8723BE 0xDA +#define EEPROM_SMID_8723BE 0xDC + +//RTL8723BU +#define EEPROM_MAC_ADDR_8723BU 0x107 +#define EEPROM_VID_8723BU 0x100 +#define EEPROM_PID_8723BU 0x102 +#define EEPROM_PA_TYPE_8723BU 0xBC +#define EEPROM_LNA_TYPE_2G_8723BU 0xBD + + +//RTL8723BS +#define EEPROM_MAC_ADDR_8723BS 0x11A +#define EEPROM_Voltage_ADDR_8723B 0x8 + +//==================================================== +/* EEPROM/Efuse PG Offset for 8703B */ +//==================================================== +#define GET_PG_KFREE_ON_8703B(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC1, 4, 1) +#define GET_PG_KFREE_THERMAL_K_ON_8703B(_pg_m) LE_BITS_TO_1BYTE(((u8 *)(_pg_m)) + 0xC8, 5, 1) + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8703B 0xEE +#define PPG_THERMAL_OFFSET_8703B 0xEF + +#define EEPROM_TX_PWR_INX_8703B 0x10 + +#define EEPROM_ChannelPlan_8703B 0xB8 +#define EEPROM_XTAL_8703B 0xB9 +#define EEPROM_THERMAL_METER_8703B 0xBA +#define EEPROM_IQK_LCK_8703B 0xBB +#define EEPROM_2G_5G_PA_TYPE_8703B 0xBC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8703B 0xBD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8703B 0xBF + +#define EEPROM_RF_BOARD_OPTION_8703B 0xC1 +#define EEPROM_FEATURE_OPTION_8703B 0xC2 +#define EEPROM_RF_BT_SETTING_8703B 0xC3 +#define EEPROM_VERSION_8703B 0xC4 +#define EEPROM_CustomID_8703B 0xC5 +#define EEPROM_TX_BBSWING_2G_8703B 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8703B 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8703B 0xC9 +#define EEPROM_RFE_OPTION_8703B 0xCA +#define EEPROM_COUNTRY_CODE_8703B 0xCB + +/* MAC Hidden */ +#define PPG_MAC_HIDDEN_START_8703B 0xF0 +#define PPG_MAC_HIDDEN_END_8703B 0xFF +#define EEPROM_HCI_AND_PACKAGE_TYPE_8703B 0xF8 +#define EEPROM_WL_FUNC_CAP_8703B 0xF9 +#define EEPROM_BW_AND_ANT_NUM_CAP_8703B 0xFB +#define GET_PMH_HCI_TYPE_8703B(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + EEPROM_HCI_AND_PACKAGE_TYPE_8703B - PPG_MAC_HIDDEN_START_8703B, 0, 4) +#define GET_PMH_PACKAGE_TYPE_8703B(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + EEPROM_HCI_AND_PACKAGE_TYPE_8703B - PPG_MAC_HIDDEN_START_8703B, 4, 4) +#define GET_PMH_WL_FUNC_CAP_8703B(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + EEPROM_WL_FUNC_CAP_8703B - PPG_MAC_HIDDEN_START_8703B, 0, 4) +#define GET_PMH_BW_CAP_8703B(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + EEPROM_BW_AND_ANT_NUM_CAP_8703B - PPG_MAC_HIDDEN_START_8703B, 0, 3) +#define GET_PMH_ANT_NUM_CAP_8703B(_pmh_m) LE_BITS_TO_1BYTE(((u8 *)(_pmh_m)) + EEPROM_BW_AND_ANT_NUM_CAP_8703B - PPG_MAC_HIDDEN_START_8703B, 5, 3) + +/* RTL8703BU */ +#define EEPROM_MAC_ADDR_8703BU 0x107 +#define EEPROM_VID_8703BU 0x100 +#define EEPROM_PID_8703BU 0x102 +#define EEPROM_USB_OPTIONAL_FUNCTION0_8703BU 0x104 +#define EEPROM_PA_TYPE_8703BU 0xBC +#define EEPROM_LNA_TYPE_2G_8703BU 0xBD + +//RTL8703BS +#define EEPROM_MAC_ADDR_8703BS 0x11A +#define EEPROM_Voltage_ADDR_8703B 0x8 + +//==================================================== +// EEPROM/Efuse Value Type +//==================================================== +#define EETYPE_TX_PWR 0x0 +//==================================================== +// EEPROM/Efuse Default Value +//==================================================== +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_DEFAULT_EXT 0xFF // Reserved for Realtek +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC_TAIWAN 0xB +#define EEPROM_CHANNEL_PLAN_CHIAN 0XC +#define EEPROM_CHANNEL_PLAN_SINGAPORE_INDIA_MEXICO 0XD +#define EEPROM_CHANNEL_PLAN_KOREA 0xE +#define EEPROM_CHANNEL_PLAN_TURKEY 0xF +#define EEPROM_CHANNEL_PLAN_JAPAN 0x10 +#define EEPROM_CHANNEL_PLAN_FCC_NO_DFS 0x11 +#define EEPROM_CHANNEL_PLAN_JAPAN_NO_DFS 0x12 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_5G 0x13 +#define EEPROM_CHANNEL_PLAN_TAIWAN_NO_DFS 0x14 + +#define EEPROM_USB_OPTIONAL1 0xE +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define RTL_EEPROM_ID 0x8129 +#define EEPROM_Default_TSSI 0x0 +#define EEPROM_Default_BoardType 0x02 +#define EEPROM_Default_ThermalMeter 0x12 +#define EEPROM_Default_ThermalMeter_92SU 0x7 +#define EEPROM_Default_ThermalMeter_88E 0x18 +#define EEPROM_Default_ThermalMeter_8812 0x18 +#define EEPROM_Default_ThermalMeter_8192E 0x1A +#define EEPROM_Default_ThermalMeter_8723B 0x18 +#define EEPROM_Default_ThermalMeter_8703B 0x18 +#define EEPROM_Default_ThermalMeter_8188F 0x18 +#define EEPROM_Default_ThermalMeter_8814A 0x18 + + +#define EEPROM_Default_CrystalCap 0x0 +#define EEPROM_Default_CrystalCap_8723A 0x20 +#define EEPROM_Default_CrystalCap_88E 0x20 +#define EEPROM_Default_CrystalCap_8812 0x20 +#define EEPROM_Default_CrystalCap_8814 0x20 +#define EEPROM_Default_CrystalCap_8192E 0x20 +#define EEPROM_Default_CrystalCap_8723B 0x20 +#define EEPROM_Default_CrystalCap_8703B 0x20 +#define EEPROM_Default_CrystalCap_8188F 0x20 +#define EEPROM_Default_CrystalFreq 0x0 +#define EEPROM_Default_TxPowerLevel_92C 0x22 +#define EEPROM_Default_TxPowerLevel_2G 0x2C +#define EEPROM_Default_TxPowerLevel_5G 0x22 +#define EEPROM_Default_TxPowerLevel 0x22 +#define EEPROM_Default_HT40_2SDiff 0x0 +#define EEPROM_Default_HT20_Diff 2 +#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 +#define EEPROM_Default_LegacyHTTxPowerDiff_92C 0x3 +#define EEPROM_Default_LegacyHTTxPowerDiff_92D 0x4 +#define EEPROM_Default_HT40_PwrMaxOffset 0 +#define EEPROM_Default_HT20_PwrMaxOffset 0 + +#define EEPROM_Default_PID 0x1234 +#define EEPROM_Default_VID 0x5678 +#define EEPROM_Default_CustomerID 0xAB +#define EEPROM_Default_CustomerID_8188E 0x00 +#define EEPROM_Default_SubCustomerID 0xCD +#define EEPROM_Default_Version 0 + +#define EEPROM_Default_externalPA_C9 0x00 +#define EEPROM_Default_externalPA_CC 0xFF +#define EEPROM_Default_internalPA_SP3T_C9 0xAA +#define EEPROM_Default_internalPA_SP3T_CC 0xAF +#define EEPROM_Default_internalPA_SPDT_C9 0xAA +#ifdef CONFIG_PCI_HCI +#define EEPROM_Default_internalPA_SPDT_CC 0xA0 +#else +#define EEPROM_Default_internalPA_SPDT_CC 0xFA +#endif +#define EEPROM_Default_PAType 0 +#define EEPROM_Default_LNAType 0 + +//New EFUSE deafult value +#define EEPROM_DEFAULT_24G_INDEX 0x2D +#define EEPROM_DEFAULT_24G_HT20_DIFF 0X02 +#define EEPROM_DEFAULT_24G_OFDM_DIFF 0X04 + +#define EEPROM_DEFAULT_5G_INDEX 0X2A +#define EEPROM_DEFAULT_5G_HT20_DIFF 0X00 +#define EEPROM_DEFAULT_5G_OFDM_DIFF 0X04 + +#define EEPROM_DEFAULT_DIFF 0XFE +#define EEPROM_DEFAULT_CHANNEL_PLAN 0x7F +#define EEPROM_DEFAULT_BOARD_OPTION 0x00 +#define EEPROM_DEFAULT_RFE_OPTION_8192E 0xFF +#define EEPROM_DEFAULT_RFE_OPTION 0x04 +#define EEPROM_DEFAULT_FEATURE_OPTION 0x00 +#define EEPROM_DEFAULT_BT_OPTION 0x10 + + +#define EEPROM_DEFAULT_TX_CALIBRATE_RATE 0x00 + +// PCIe related +#define EEPROM_PCIE_DEV_CAP_01 0xE0 // Express device capability in PCIe configuration space, i.e., map to offset 0x74 +#define EEPROM_PCIE_DEV_CAP_02 0xE1 // Express device capability in PCIe configuration space, i.e., map to offset 0x75 + + +// +// For VHT series TX power by rate table. +// VHT TX power by rate off setArray = +// Band:-2G&5G = 0 / 1 +// RF: at most 4*4 = ABCD=0/1/2/3 +// CCK=0 OFDM=1/2 HT-MCS 0-15=3/4/56 VHT=7/8/9/10/11 +// +#define TX_PWR_BY_RATE_NUM_BAND 2 +#define TX_PWR_BY_RATE_NUM_RF 4 +#define TX_PWR_BY_RATE_NUM_RATE 84 + +#define TXPWR_LMT_MAX_RF 4 + +//---------------------------------------------------------------------------- +// EEPROM/EFUSE data structure definition. +//---------------------------------------------------------------------------- + +//For 88E new structure + +/* +2.4G: +{ +{1,2}, +{3,4,5}, +{6,7,8}, +{9,10,11}, +{12,13}, +{14} +} + +5G: +{ +{36,38,40}, +{44,46,48}, +{52,54,56}, +{60,62,64}, +{100,102,104}, +{108,110,112}, +{116,118,120}, +{124,126,128}, +{132,134,136}, +{140,142,144}, +{149,151,153}, +{157,159,161}, +{173,175,177}, +} +*/ +#define MAX_RF_PATH 4 +#define RF_PATH_MAX MAX_RF_PATH +#define MAX_CHNL_GROUP_24G 6 +#define MAX_CHNL_GROUP_5G 14 + +//It must always set to 4, otherwise read efuse table secquence will be wrong. +#define MAX_TX_COUNT 4 + +typedef struct _TxPowerInfo24G{ + u8 IndexCCK_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + //If only one tx, only BW20 and OFDM are used. + s8 CCK_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +}TxPowerInfo24G, *PTxPowerInfo24G; + +typedef struct _TxPowerInfo5G{ + u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_5G]; + //If only one tx, only BW20, OFDM, BW80 and BW160 are used. + s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW80_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW160_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +}TxPowerInfo5G, *PTxPowerInfo5G; + + +typedef enum _BT_Ant_NUM{ + Ant_x2 = 0, + Ant_x1 = 1 +} BT_Ant_NUM, *PBT_Ant_NUM; + +typedef enum _BT_CoType{ + BT_2WIRE = 0, + BT_ISSC_3WIRE = 1, + BT_ACCEL = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, + BT_RTL8723A = 6, + BT_RTL8821 = 7, + BT_RTL8723B = 8, + BT_RTL8192E = 9, + BT_RTL8814A = 10, + BT_RTL8812A = 11, + BT_RTL8703B = 12 +} BT_CoType, *PBT_CoType; + +typedef enum _BT_RadioShared{ + BT_Radio_Shared = 0, + BT_Radio_Individual = 1, +} BT_RadioShared, *PBT_RadioShared; + + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy.h new file mode 100644 index 00000000..56b50c80 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy.h @@ -0,0 +1,247 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_H__ +#define __HAL_PHY_H__ + + +#if DISABLE_BB_RF +#define HAL_FW_ENABLE 0 +#define HAL_MAC_ENABLE 0 +#define HAL_BB_ENABLE 0 +#define HAL_RF_ENABLE 0 +#else // FPGA_PHY and ASIC +#define HAL_FW_ENABLE 1 +#define HAL_MAC_ENABLE 1 +#define HAL_BB_ENABLE 1 +#define HAL_RF_ENABLE 1 +#endif + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG_88E 0xFF +#define RF6052_MAX_REG_92C 0x7F + +#define RF6052_MAX_REG \ + (RF6052_MAX_REG_88E > RF6052_MAX_REG_92C) ? RF6052_MAX_REG_88E: RF6052_MAX_REG_92C + +#define GET_RF6052_REAL_MAX_REG(_Adapter) \ + IS_HARDWARE_TYPE_8188E(_Adapter) ? RF6052_MAX_REG_88E : RF6052_MAX_REG_92C + +#define RF6052_MAX_PATH 2 + +// +// Antenna detection method, i.e., using single tone detection or RSSI reported from each antenna detected. +// Added by Roger, 2013.05.22. +// +#define ANT_DETECT_BY_SINGLE_TONE BIT0 +#define ANT_DETECT_BY_RSSI BIT1 +#define IS_ANT_DETECT_SUPPORT_SINGLE_TONE(__Adapter) ((GET_HAL_DATA(__Adapter)->AntDetection) & ANT_DETECT_BY_SINGLE_TONE) +#define IS_ANT_DETECT_SUPPORT_RSSI(__Adapter) ((GET_HAL_DATA(__Adapter)->AntDetection) & ANT_DETECT_BY_RSSI) + + +/*--------------------------Define Parameters-------------------------------*/ +typedef enum _RF_TYPE{ + RF_TYPE_MIN = 0, // 0 + RF_8225=1, // 1 11b/g RF for verification only + RF_8256=2, // 2 11b/g/n + RF_8258=3, // 3 11a/b/g/n RF + RF_6052=4, // 4 11b/g/n RF + RF_PSEUDO_11N=5, // 5, It is a temporality RF. + RF_TYPE_MAX +}RF_TYPE_E,*PRF_TYPE_E; + +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define RF_PATH_MAX_92C_88E 2 +#define RF_PATH_MAX_90_8812 4 //Max RF number 90 support + +typedef enum _ANTENNA_PATH{ + ANTENNA_NONE = 0, + ANTENNA_D = 1, + ANTENNA_C = 2, + ANTENNA_CD = 3, + ANTENNA_B = 4, + ANTENNA_BD = 5, + ANTENNA_BC = 6, + ANTENNA_BCD = 7, + ANTENNA_A = 8, + ANTENNA_AD = 9, + ANTENNA_AC = 10, + ANTENNA_ACD = 11, + ANTENNA_AB = 12, + ANTENNA_ABD = 13, + ANTENNA_ABC = 14, + ANTENNA_ABCD = 15 +} ANTENNA_PATH; + +typedef enum _RF_CONTENT{ + radioa_txt = 0x1000, + radiob_txt = 0x1001, + radioc_txt = 0x1002, + radiod_txt = 0x1003 +} RF_CONTENT; + +typedef enum _BaseBand_Config_Type{ + BaseBand_Config_PHY_REG = 0, //Radio Path A + BaseBand_Config_AGC_TAB = 1, //Radio Path B + BaseBand_Config_AGC_TAB_2G = 2, + BaseBand_Config_AGC_TAB_5G = 3, + BaseBand_Config_PHY_REG_PG +}BaseBand_Config_Type, *PBaseBand_Config_Type; + +typedef enum _HW_BLOCK{ + HW_BLOCK_MAC = 0, + HW_BLOCK_PHY0 = 1, + HW_BLOCK_PHY1 = 2, + HW_BLOCK_RF = 3, + HW_BLOCK_MAXIMUM = 4, // Never use this +}HW_BLOCK_E, *PHW_BLOCK_E; + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20, + WIRELESS_MODE_AC_5G = 0x40, + WIRELESS_MODE_AC_24G = 0x80, + WIRELESS_MODE_AC_ONLY = 0x100, +} WIRELESS_MODE; + +typedef enum _SwChnlCmdID{ + CmdID_End, + CmdID_SetTxPowerLevel, + CmdID_BBRegWrite10, + CmdID_WritePortUlong, + CmdID_WritePortUshort, + CmdID_WritePortUchar, + CmdID_RF_WriteReg, +}SwChnlCmdID; + +typedef struct _SwChnlCmd{ + SwChnlCmdID CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +}SwChnlCmd; + +typedef struct _R_ANTENNA_SELECT_OFDM{ + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK{ + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; + +typedef struct RF_Shadow_Compare_Map { + // Shadow register value + u32 Value; + // Compare or not flag + u8 Compare; + // Record If it had ever modified unpredicted + u8 ErrorOrNot; + // Recorver Flag + u8 Recorver; + // + u8 Driver_Write; +}RF_SHADOW_T; + +/*--------------------------Exported Function prototype---------------------*/ + +u32 +PHY_CalculateBitShift( + u32 BitMask + ); + +u32 +PHY_RFShadowRead( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset); + +VOID +PHY_RFShadowWrite( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u32 Data); + +BOOLEAN +PHY_RFShadowCompare( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset); + +VOID +PHY_RFShadowRecorver( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset); + +VOID +PHY_RFShadowCompareAll( + IN PADAPTER Adapter); + +VOID +PHY_RFShadowRecorverAll( + IN PADAPTER Adapter); + +VOID +PHY_RFShadowCompareFlagSet( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u8 Type); + +VOID +PHY_RFShadowRecorverFlagSet( + IN PADAPTER Adapter, + IN u8 eRFPath, + IN u32 Offset, + IN u8 Type); + +VOID +PHY_RFShadowCompareFlagSetAll( + IN PADAPTER Adapter); + +VOID +PHY_RFShadowRecorverFlagSetAll( + IN PADAPTER Adapter); + +VOID +PHY_RFShadowRefresh( + IN PADAPTER Adapter); + +#endif //__HAL_COMMON_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy_reg.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy_reg.h new file mode 100644 index 00000000..723eddb6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_phy_reg.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * 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 __HAL_PHY_REG_H__ +#define __HAL_PHY_REG_H__ + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#if (RTL92SE_FPGA_VERIFY == 1) +//#define bRFRegOffsetMask 0xfff +//#else +#define bRFRegOffsetMask 0xfffff +//#endif + +#endif //__HAL_PHY_REG_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_sdio.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_sdio.h new file mode 100644 index 00000000..ccb49e78 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/hal_sdio.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 __HAL_SDIO_H_ +#define __HAL_SDIO_H_ + +#define ffaddr2deviceId(pdvobj, addr) (pdvobj->Queue2Pipe[addr]) + +u8 rtw_hal_sdio_max_txoqt_free_space(_adapter *padapter); +u8 rtw_hal_sdio_query_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum); +void rtw_hal_sdio_update_tx_freepage(_adapter *padapter, u8 PageIdx, u8 RequiredPageNum); +void rtw_hal_set_sdio_tx_max_length(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ); +u32 rtw_hal_get_sdio_tx_max_length(PADAPTER padapter, u8 queue_idx); + +#endif //__RTW_LED_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211.h new file mode 100644 index 00000000..2c3e15ef --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211.h @@ -0,0 +1,1828 @@ +/****************************************************************************** + * + * 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 __IEEE80211_H +#define __IEEE80211_H + + +#ifndef CONFIG_RTL8711FW + + #if defined PLATFORM_OS_XP + #include + #endif +#else + +#endif + +#define MGMT_QUEUE_NUM 5 + +#define ETH_ALEN 6 +#define ETH_TYPE_LEN 2 +#define PAYLOAD_TYPE_LEN 1 + +#ifdef CONFIG_AP_MODE + +#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) + +/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ +enum { + RTL871X_HOSTAPD_FLUSH = 1, + RTL871X_HOSTAPD_ADD_STA = 2, + RTL871X_HOSTAPD_REMOVE_STA = 3, + RTL871X_HOSTAPD_GET_INFO_STA = 4, + /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ + RTL871X_HOSTAPD_GET_WPAIE_STA = 5, + RTL871X_SET_ENCRYPTION = 6, + RTL871X_GET_ENCRYPTION = 7, + RTL871X_HOSTAPD_SET_FLAGS_STA = 8, + RTL871X_HOSTAPD_GET_RID = 9, + RTL871X_HOSTAPD_SET_RID = 10, + RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, + RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, + RTL871X_HOSTAPD_MLME = 13, + RTL871X_HOSTAPD_SCAN_REQ = 14, + RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, + RTL871X_HOSTAPD_SET_BEACON=16, + RTL871X_HOSTAPD_SET_WPS_BEACON = 17, + RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, + RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, + RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, + RTL871X_HOSTAPD_SET_MACADDR_ACL = 21, + RTL871X_HOSTAPD_ACL_ADD_STA = 22, + RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, +}; + +/* STA flags */ +#define WLAN_STA_AUTH BIT(0) +#define WLAN_STA_ASSOC BIT(1) +#define WLAN_STA_PS BIT(2) +#define WLAN_STA_TIM BIT(3) +#define WLAN_STA_PERM BIT(4) +#define WLAN_STA_AUTHORIZED BIT(5) +#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ +#define WLAN_STA_SHORT_PREAMBLE BIT(7) +#define WLAN_STA_PREAUTH BIT(8) +#define WLAN_STA_WME BIT(9) +#define WLAN_STA_MFP BIT(10) +#define WLAN_STA_HT BIT(11) +#define WLAN_STA_WPS BIT(12) +#define WLAN_STA_MAYBE_WPS BIT(13) +#define WLAN_STA_VHT BIT(14) +#define WLAN_STA_NONERP BIT(31) + +#endif + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +#define IEEE_PARAM_WPAX_SELECT 7 + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 +#define AUTH_ALG_LEAP 0x00000004 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define WPA_CIPHER_NONE BIT(0) +#define WPA_CIPHER_WEP40 BIT(1) +#define WPA_CIPHER_WEP104 BIT(2) +#define WPA_CIPHER_TKIP BIT(3) +#define WPA_CIPHER_CCMP BIT(4) + + + +#define WPA_SELECTOR_LEN 4 +extern u8 RTW_WPA_OUI_TYPE[] ; +extern u16 RTW_WPA_VERSION ; +extern u8 WPA_AUTH_KEY_MGMT_NONE[]; +extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +extern u8 WPA_CIPHER_SUITE_NONE[]; +extern u8 WPA_CIPHER_SUITE_WEP40[]; +extern u8 WPA_CIPHER_SUITE_TKIP[]; +extern u8 WPA_CIPHER_SUITE_WRAP[]; +extern u8 WPA_CIPHER_SUITE_CCMP[]; +extern u8 WPA_CIPHER_SUITE_WEP104[]; + + +#define RSN_HEADER_LEN 4 +#define RSN_SELECTOR_LEN 4 + +extern u16 RSN_VERSION_BSD; +extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +extern u8 RSN_CIPHER_SUITE_NONE[]; +extern u8 RSN_CIPHER_SUITE_WEP40[]; +extern u8 RSN_CIPHER_SUITE_TKIP[]; +extern u8 RSN_CIPHER_SUITE_WRAP[]; +extern u8 RSN_CIPHER_SUITE_CCMP[]; +extern u8 RSN_CIPHER_SUITE_WEP104[]; + + +typedef enum _RATEID_IDX_ { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +} RATEID_IDX, *PRATEID_IDX; + +typedef enum _RATR_TABLE_MODE{ + RATR_INX_WIRELESS_NGB = 0, // BGN 40 Mhz 2SS 1SS + RATR_INX_WIRELESS_NG = 1, // GN or N + RATR_INX_WIRELESS_NB = 2, // BGN 20 Mhz 2SS 1SS or BN + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_AC_N = 8, +}RATR_TABLE_MODE, *PRATR_TABLE_MODE; + + +enum NETWORK_TYPE +{ + WIRELESS_INVALID = 0, + //Sub-Element + WIRELESS_11B = BIT(0), // tx: cck only , rx: cck only, hw: cck + WIRELESS_11G = BIT(1), // tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm + WIRELESS_11A = BIT(2), // tx: ofdm only, rx: ofdm only, hw: ofdm only + WIRELESS_11_24N = BIT(3), // tx: MCS only, rx: MCS & cck, hw: MCS & cck + WIRELESS_11_5N = BIT(4), // tx: MCS only, rx: MCS & ofdm, hw: ofdm only + WIRELESS_AUTO = BIT(5), + WIRELESS_11AC = BIT(6), + + //Combination + //Type for current wireless mode + WIRELESS_11BG = (WIRELESS_11B|WIRELESS_11G), // tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm + WIRELESS_11G_24N = (WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm + WIRELESS_11A_5N = (WIRELESS_11A|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11B_24N = (WIRELESS_11B|WIRELESS_11_24N), // tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck + WIRELESS_11BG_24N = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck + WIRELESS_11_24AC = (WIRELESS_11G|WIRELESS_11AC), + WIRELESS_11_5AC = (WIRELESS_11A|WIRELESS_11AC), + + + //Type for registry default wireless mode + WIRELESS_11AGN = (WIRELESS_11A|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11ABGN = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), + WIRELESS_MODE_24G = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), + WIRELESS_MODE_5G = (WIRELESS_11A|WIRELESS_11_5N|WIRELESS_11AC), + WIRELESS_MODE_MAX = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N|WIRELESS_11AC), +}; + +#define SUPPORTED_24G_NETTYPE_MSK WIRELESS_MODE_24G +#define SUPPORTED_5G_NETTYPE_MSK WIRELESS_MODE_5G + +#define IsLegacyOnly(NetType) ((NetType) == ((NetType) & (WIRELESS_11BG|WIRELESS_11A))) + +#define IsSupported24G(NetType) ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? _TRUE : _FALSE) +#define IsSupported5G(NetType) ((NetType) & SUPPORTED_5G_NETTYPE_MSK ? _TRUE : _FALSE) + +#define IsEnableHWCCK(NetType) IsSupported24G(NetType) +#define IsEnableHWOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11_24N|SUPPORTED_5G_NETTYPE_MSK) ? _TRUE : _FALSE) + +#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType) +#define IsSupportedRxOFDM(NetType) IsEnableHWOFDM(NetType) +#define IsSupportedRxHT(NetType) IsEnableHWOFDM(NetType) + +#define IsSupportedTxCCK(NetType) ((NetType) & (WIRELESS_11B) ? _TRUE : _FALSE) +#define IsSupportedTxOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11A) ? _TRUE : _FALSE) +#define IsSupportedHT(NetType) ((NetType) & (WIRELESS_11_24N|WIRELESS_11_5N) ? _TRUE : _FALSE) + +#define IsSupportedVHT(NetType) ((NetType) & (WIRELESS_11AC) ? _TRUE : _FALSE) + + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; +#ifdef CONFIG_AP_MODE + struct { + u16 aid; + u16 capability; + int flags; + u8 tx_supp_rates[16]; + struct rtw_ieee80211_ht_cap ht_cap; + } add_sta; + struct { + u8 reserved[2];//for set max_num_sta + u8 buf[0]; + } bcn_ie; +#endif + + } u; +}ieee_param; + +#ifdef CONFIG_AP_MODE +typedef struct ieee_param_ex { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + u8 data[0]; +}ieee_param_ex; + +struct sta_data{ + u16 aid; + u16 capability; + int flags; + u32 sta_set; + u8 tx_supp_rates[16]; + u32 tx_supp_rates_len; + struct rtw_ieee80211_ht_cap ht_cap; + u64 rx_pkts; + u64 rx_bytes; + u64 rx_drops; + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; +}; +#endif + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + + +#define IEEE80211_HLEN 30 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 + +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + _list list; +}; + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW)||defined(PLATFORM_FREEBSD) + +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +} __attribute__ ((packed)); + +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +} __attribute__ ((packed)); + + +struct rtw_ieee80211_hdr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 qc; +} __attribute__ ((packed)); + +struct rtw_ieee80211_hdr_3addr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u16 qc; +} __attribute__ ((packed)); + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __attribute__ ((packed)); + +#endif + + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +}; + +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +}; + + +struct rtw_ieee80211_hdr_qos { + struct rtw_ieee80211_hdr wlan_hdr; + u16 qc; +}; + +struct rtw_ieee80211_hdr_3addr_qos { + struct rtw_ieee80211_hdr_3addr wlan_hdr; + u16 qc; +}; + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +}; +#pragma pack() + +#endif + + + +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + +/* Frame control field constants */ +#define RTW_IEEE80211_FCTL_VERS 0x0003 +#define RTW_IEEE80211_FCTL_FTYPE 0x000c +#define RTW_IEEE80211_FCTL_STYPE 0x00f0 +#define RTW_IEEE80211_FCTL_TODS 0x0100 +#define RTW_IEEE80211_FCTL_FROMDS 0x0200 +#define RTW_IEEE80211_FCTL_MOREFRAGS 0x0400 +#define RTW_IEEE80211_FCTL_RETRY 0x0800 +#define RTW_IEEE80211_FCTL_PM 0x1000 +#define RTW_IEEE80211_FCTL_MOREDATA 0x2000 +#define RTW_IEEE80211_FCTL_PROTECTED 0x4000 +#define RTW_IEEE80211_FCTL_ORDER 0x8000 +#define RTW_IEEE80211_FCTL_CTL_EXT 0x0f00 + +#define RTW_IEEE80211_FTYPE_MGMT 0x0000 +#define RTW_IEEE80211_FTYPE_CTL 0x0004 +#define RTW_IEEE80211_FTYPE_DATA 0x0008 +#define RTW_IEEE80211_FTYPE_EXT 0x000c + +/* management */ +#define RTW_IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define RTW_IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define RTW_IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define RTW_IEEE80211_STYPE_PROBE_REQ 0x0040 +#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050 +#define RTW_IEEE80211_STYPE_BEACON 0x0080 +#define RTW_IEEE80211_STYPE_ATIM 0x0090 +#define RTW_IEEE80211_STYPE_DISASSOC 0x00A0 +#define RTW_IEEE80211_STYPE_AUTH 0x00B0 +#define RTW_IEEE80211_STYPE_DEAUTH 0x00C0 +#define RTW_IEEE80211_STYPE_ACTION 0x00D0 + +/* control */ +#define RTW_IEEE80211_STYPE_CTL_EXT 0x0060 +#define RTW_IEEE80211_STYPE_BACK_REQ 0x0080 +#define RTW_IEEE80211_STYPE_BACK 0x0090 +#define RTW_IEEE80211_STYPE_PSPOLL 0x00A0 +#define RTW_IEEE80211_STYPE_RTS 0x00B0 +#define RTW_IEEE80211_STYPE_CTS 0x00C0 +#define RTW_IEEE80211_STYPE_ACK 0x00D0 +#define RTW_IEEE80211_STYPE_CFEND 0x00E0 +#define RTW_IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define RTW_IEEE80211_STYPE_DATA 0x0000 +#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010 +#define RTW_IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define RTW_IEEE80211_STYPE_NULLFUNC 0x0040 +#define RTW_IEEE80211_STYPE_CFACK 0x0050 +#define RTW_IEEE80211_STYPE_CFPOLL 0x0060 +#define RTW_IEEE80211_STYPE_CFACKPOLL 0x0070 +#define RTW_IEEE80211_STYPE_QOS_DATA 0x0080 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 +#define RTW_IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 +#define RTW_IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 +#define RTW_IEEE80211_STYPE_QOS_CFACK 0x00D0 +#define RTW_IEEE80211_STYPE_QOS_CFPOLL 0x00E0 +#define RTW_IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 + +/* sequence control field */ +#define RTW_IEEE80211_SCTL_FRAG 0x000F +#define RTW_IEEE80211_SCTL_SEQ 0xFFF0 + + +#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0) +#define RTW_ERP_INFO_USE_PROTECTION BIT(1) +#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + +/* QoS,QOS */ +#define NORMAL_ACK 0 +#define NO_ACK 1 +#define NON_EXPLICIT_ACK 2 +#define BLOCK_ACK 3 + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#define ETH_P_ECONET 0x0018 + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) || defined(PLATFORM_FREEBSD) + +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +}; +#pragma pack() + +#endif + + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE) + +#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f) + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & RTW_IEEE80211_SCTL_SEQ) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) + +/* Status codes */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +/* 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/* Reason codes */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#define WLAN_REASON_ACTIVE_ROAM 65533 +#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 +#define WLAN_REASON_EXPIRATION_CHK 65535 + +/* Information Element IDs */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARAMS 2 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_CHALLENGE 16 +/* EIDs defined by IEEE 802.11h - START */ +#define WLAN_EID_PWR_CONSTRAINT 32 +#define WLAN_EID_PWR_CAPABILITY 33 +#define WLAN_EID_TPC_REQUEST 34 +#define WLAN_EID_TPC_REPORT 35 +#define WLAN_EID_SUPPORTED_CHANNELS 36 +#define WLAN_EID_CHANNEL_SWITCH 37 +#define WLAN_EID_MEASURE_REQUEST 38 +#define WLAN_EID_MEASURE_REPORT 39 +#define WLAN_EID_QUITE 40 +#define WLAN_EID_IBSS_DFS 41 +/* EIDs defined by IEEE 802.11h - END */ +#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_SUPP_RATES 50 +#define WLAN_EID_MOBILITY_DOMAIN 54 +#define WLAN_EID_FAST_BSS_TRANSITION 55 +#define WLAN_EID_TIMEOUT_INTERVAL 56 +#define WLAN_EID_RIC_DATA 57 +#define WLAN_EID_HT_OPERATION 61 +#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 +#define WLAN_EID_20_40_BSS_COEXISTENCE 72 +#define WLAN_EID_20_40_BSS_INTOLERANT 73 +#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 +#define WLAN_EID_MMIE 76 +#define WLAN_EID_VENDOR_SPECIFIC 221 +#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) +#define WLAN_EID_VHT_CAPABILITY 191 +#define WLAN_EID_VHT_OPERATION 192 +#define WLAN_EID_VHT_OP_MODE_NOTIFY 199 + +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_NUM_OFDM_RATESLEN 8 + + +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + +enum MGN_RATE{ + MGN_1M = 0x02, + MGN_2M = 0x04, + MGN_5_5M = 0x0B, + MGN_6M = 0x0C, + MGN_9M = 0x12, + MGN_11M = 0x16, + MGN_12M = 0x18, + MGN_18M = 0x24, + MGN_24M = 0x30, + MGN_36M = 0x48, + MGN_48M = 0x60, + MGN_54M = 0x6C, + MGN_MCS32 = 0x7F, + MGN_MCS0, + MGN_MCS1, + MGN_MCS2, + MGN_MCS3, + MGN_MCS4, + MGN_MCS5, + MGN_MCS6, + MGN_MCS7, + MGN_MCS8, + MGN_MCS9, + MGN_MCS10, + MGN_MCS11, + MGN_MCS12, + MGN_MCS13, + MGN_MCS14, + MGN_MCS15, + MGN_MCS16, + MGN_MCS17, + MGN_MCS18, + MGN_MCS19, + MGN_MCS20, + MGN_MCS21, + MGN_MCS22, + MGN_MCS23, + MGN_MCS24, + MGN_MCS25, + MGN_MCS26, + MGN_MCS27, + MGN_MCS28, + MGN_MCS29, + MGN_MCS30, + MGN_MCS31, + MGN_VHT1SS_MCS0, + MGN_VHT1SS_MCS1, + MGN_VHT1SS_MCS2, + MGN_VHT1SS_MCS3, + MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, + MGN_VHT1SS_MCS6, + MGN_VHT1SS_MCS7, + MGN_VHT1SS_MCS8, + MGN_VHT1SS_MCS9, + MGN_VHT2SS_MCS0, + MGN_VHT2SS_MCS1, + MGN_VHT2SS_MCS2, + MGN_VHT2SS_MCS3, + MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, + MGN_VHT2SS_MCS6, + MGN_VHT2SS_MCS7, + MGN_VHT2SS_MCS8, + MGN_VHT2SS_MCS9, + MGN_VHT3SS_MCS0, + MGN_VHT3SS_MCS1, + MGN_VHT3SS_MCS2, + MGN_VHT3SS_MCS3, + MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, + MGN_VHT3SS_MCS6, + MGN_VHT3SS_MCS7, + MGN_VHT3SS_MCS8, + MGN_VHT3SS_MCS9, + MGN_VHT4SS_MCS0, + MGN_VHT4SS_MCS1, + MGN_VHT4SS_MCS2, + MGN_VHT4SS_MCS3, + MGN_VHT4SS_MCS4, + MGN_VHT4SS_MCS5, + MGN_VHT4SS_MCS6, + MGN_VHT4SS_MCS7, + MGN_VHT4SS_MCS8, + MGN_VHT4SS_MCS9, + MGN_UNKNOWN +}; + +#define IS_HT_RATE(_rate) ((_rate) >= MGN_MCS0 && (_rate) <= MGN_MCS31) +#define IS_VHT_RATE(_rate) ((_rate) >= MGN_VHT1SS_MCS0 && (_rate) <= MGN_VHT4SS_MCS9) +#define IS_CCK_RATE(_rate) ((_rate) == MGN_1M || (_rate) == MGN_2M || (_rate) == MGN_5_5M || (_rate) == MGN_11M) +#define IS_OFDM_RATE(_rate) ((_rate) >= MGN_6M && (_rate) <= MGN_54M && (_rate) != MGN_11M) + +#define IS_HT1SS_RATE(_rate) ((_rate) >= MGN_MCS0 && (_rate) <= MGN_MCS7) +#define IS_HT2SS_RATE(_rate) ((_rate) >= MGN_MCS8 && (_rate) <= MGN_MCS15) +#define IS_HT3SS_RATE(_rate) ((_rate) >= MGN_MCS16 && (_rate) <= MGN_MCS23) +#define IS_HT4SS_RATE(_rate) ((_rate) >= MGN_MCS24 && (_rate) <= MGN_MCS31) + +#define IS_VHT1SS_RATE(_rate) ((_rate) >= MGN_VHT1SS_MCS0 && (_rate) <= MGN_VHT1SS_MCS9) +#define IS_VHT2SS_RATE(_rate) ((_rate) >= MGN_VHT2SS_MCS0 && (_rate) <= MGN_VHT2SS_MCS9) +#define IS_VHT3SS_RATE(_rate) ((_rate) >= MGN_VHT3SS_MCS0 && (_rate) <= MGN_VHT3SS_MCS9) +#define IS_VHT4SS_RATE(_rate) ((_rate) >= MGN_VHT4SS_MCS0 && (_rate) <= MGN_VHT4SS_MCS9) + +#define IS_1T_RATE(_rate) (IS_CCK_RATE((_rate)) || IS_OFDM_RATE((_rate)) || IS_HT1SS_RATE((_rate)) || IS_VHT1SS_RATE((_rate))) +#define IS_2T_RATE(_rate) (IS_HT2SS_RATE((_rate)) || IS_VHT2SS_RATE((_rate))) +#define IS_3T_RATE(_rate) (IS_HT3SS_RATE((_rate)) || IS_VHT3SS_RATE((_rate))) +#define IS_4T_RATE(_rate) (IS_HT4SS_RATE((_rate)) || IS_VHT4SS_RATE((_rate))) + +typedef enum _RATE_SECTION { + CCK = 0, + OFDM = 1, + HT_MCS0_MCS7 = 2, + HT_MCS8_MCS15 = 3, + HT_MCS16_MCS23 = 4, + HT_MCS24_MCS31 = 5, + HT_1SS = HT_MCS0_MCS7, + HT_2SS = HT_MCS8_MCS15, + HT_3SS = HT_MCS16_MCS23, + HT_4SS = HT_MCS24_MCS31, + VHT_1SSMCS0_1SSMCS9 = 6, + VHT_2SSMCS0_2SSMCS9 = 7, + VHT_3SSMCS0_3SSMCS9 = 8, + VHT_4SSMCS0_4SSMCS9 = 9, + VHT_1SS = VHT_1SSMCS0_1SSMCS9, + VHT_2SS = VHT_2SSMCS0_2SSMCS9, + VHT_3SS = VHT_3SSMCS0_3SSMCS9, + VHT_4SS = VHT_4SSMCS0_4SSMCS9, + RATE_SECTION_NUM, +} RATE_SECTION; + +const char *rate_section_str(u8 section); + +#define IS_CCK_RATE_SECTION(section) ((section) == CCK) +#define IS_OFDM_RATE_SECTION(section) ((section) == OFDM) +#define IS_HT_RATE_SECTION(section) ((section) >= HT_1SS && (section) <= HT_4SS) +#define IS_VHT_RATE_SECTION(section) ((section) >= VHT_1SS && (section) <= VHT_4SS) + +#define IS_1T_RATE_SECTION(section) ((section) == CCK || (section) == OFDM || (section) == HT_1SS || (section) == VHT_1SS) +#define IS_2T_RATE_SECTION(section) ((section) == HT_2SS || (section) == VHT_2SS) +#define IS_3T_RATE_SECTION(section) ((section) == HT_3SS || (section) == VHT_3SS) +#define IS_4T_RATE_SECTION(section) ((section) == HT_4SS || (section) == VHT_4SS) + +extern u8 mgn_rates_cck[]; +extern u8 mgn_rates_ofdm[]; +extern u8 mgn_rates_mcs0_7[]; +extern u8 mgn_rates_mcs8_15[]; +extern u8 mgn_rates_mcs16_23[]; +extern u8 mgn_rates_mcs24_31[]; +extern u8 mgn_rates_vht1ss[]; +extern u8 mgn_rates_vht2ss[]; +extern u8 mgn_rates_vht3ss[]; +extern u8 mgn_rates_vht4ss[]; + +struct rate_section_ent { + u8 tx_num; /* value of RF_TX_NUM */ + u8 rate_num; + u8 *rates; +}; + +extern struct rate_section_ent rates_by_sections[]; + +#define rate_section_to_tx_num(section) (rates_by_sections[(section)].tx_num) +#define rate_section_rate_num(section) (rates_by_sections[(section)].rate_num) + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { + //u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 received_channel; + u16 rate; /* in 100 kbps */ + //u8 control; + u8 mask; + u8 freq; + u16 len; +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + u32 first_frag_time; + uint seq; + uint last_frag; + uint qos; //jackson + uint tid; //jackson + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined +struct ieee80211_stats { + uint tx_unicast_frames; + uint tx_multicast_frames; + uint tx_fragments; + uint tx_unicast_octets; + uint tx_multicast_octets; + uint tx_deferred_transmissions; + uint tx_single_retry_frames; + uint tx_multiple_retry_frames; + uint tx_retry_limit_exceeded; + uint tx_discards; + uint rx_unicast_frames; + uint rx_multicast_frames; + uint rx_fragments; + uint rx_unicast_octets; + uint rx_multicast_octets; + uint rx_fcs_errors; + uint rx_discards_no_buffer; + uint tx_discards_wrong_sa; + uint rx_discards_undecryptable; + uint rx_message_in_msg_fragments; + uint rx_message_in_bad_msg_fragments; +}; +#endif //PLATFORM_FREEBSD +struct ieee80211_softmac_stats{ + uint rx_ass_ok; + uint rx_ass_err; + uint rx_probe_rq; + uint tx_probe_rs; + uint tx_beacons; + uint rx_auth_rq; + uint rx_auth_rs_ok; + uint rx_auth_rs_err; + uint tx_auth_rq; + uint no_auth_rs; + uint no_ass_rs; + uint tx_ass_rq; + uint rx_ass_rq; + uint tx_probe_rq; + uint reassoc; + uint swtxstop; + uint swtxawake; +}; + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 + +#ifdef CONFIG_IEEE80211W +#define BIP_MAX_KEYID 5 +#define BIP_AAD_SIZE 20 +#endif //CONFIG_IEEE80211W + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} ; +#pragma pack() + +#endif + +/* + + 802.11 data frame from AP + + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' + +Total: 28-2340 bytes + +*/ + +struct ieee80211_header_data { + u16 frame_ctl; + u16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + u16 seq_ctrl; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +/* Management Frame Information Element Types */ +#define MFIE_TYPE_SSID 0 +#define MFIE_TYPE_RATES 1 +#define MFIE_TYPE_FH_SET 2 +#define MFIE_TYPE_DS_SET 3 +#define MFIE_TYPE_CF_SET 4 +#define MFIE_TYPE_TIM 5 +#define MFIE_TYPE_IBSS_SET 6 +#define MFIE_TYPE_CHALLENGE 16 +#define MFIE_TYPE_ERP 42 +#define MFIE_TYPE_RSN 48 +#define MFIE_TYPE_RATES_EX 50 +#define MFIE_TYPE_GENERIC 221 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} ; + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} ; +#pragma pack() + +#endif + + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 10 + + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} __attribute__ ((packed)); + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +} __attribute__ ((packed)); +#endif + + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} ; + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} ; + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} ; + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} ; + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +}; + +#pragma pack() + +#endif + + + + +struct ieee80211_txb { + u8 nr_frags; + u8 encrypted; + u16 reserved; + u16 frag_size; + u16 payload_size; + struct sk_buff *fragments[0]; +}; + + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 +#define MAX_CHANNEL_NUMBER 161 +#define IEEE80211_SOFTMAC_SCAN_TIME 400 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN (256) +#define MAX_WPS_IE_LEN (512) +#define MAX_P2P_IE_LEN (256) +#define MAX_WFD_IE_LEN (128) + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST +#define IW_ESSID_MAX_SIZE 32 +#if 0 +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + u8 rssi; //relative signal strength + u8 sq; //signal quality + + /* These are network statistics */ + //struct ieee80211_rx_stats stats; + u16 capability; + u16 aid; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + + u8 edca_parmsets[18]; + + u8 mode; + u8 flags; + u8 time_stamp[8]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + u8 country[6]; + u8 dtim_period; + u8 dtim_data; + u8 power_constraint; + u8 qosinfo; + u8 qbssload[5]; + u8 network_type; + int join_res; + unsigned long last_scanned; +}; +#endif +/* +join_res: +-1: authentication fail +-2: association fail +> 0: TID +*/ + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined + +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, + +}; +#endif //PLATFORM_FREEBSD + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] +#define IP_FMT "%d.%d.%d.%d" +#define IP_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3] +#define PORT_FMT "%u" +#define PORT_ARG(x) ntohs(*((u16 *)(x))) + +#ifdef PLATFORM_FREEBSD //Baron change func to macro +#define is_multicast_mac_addr(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff)) +#define is_broadcast_mac_addr(Addr) ((((Addr[0]) & 0xff) == 0xff) && (((Addr[1]) & 0xff) == 0xff) && \ +(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ +(((Addr[5]) & 0xff) == 0xff)) +#else +static __inline int is_multicast_mac_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} + +static __inline int is_broadcast_mac_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} + +static __inline int is_zero_mac_addr(const u8 *addr) +{ + return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ + (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); +} +#endif //PLATFORM_FREEBSD + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) + +typedef struct tx_pending_t{ + int frag; + struct ieee80211_txb *txb; +}tx_pending_t; + + + +#define TID_NUM 16 + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +//Baron move to ieee80211.c +int ieee80211_is_empty_essid(const char *essid, int essid_len); +int ieee80211_get_hdrlen(u16 fc); + +#if 0 +/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_WMM 17 +#endif + + +/* Action category code */ +enum rtw_ieee80211_category { + RTW_WLAN_CATEGORY_SPECTRUM_MGMT = 0, + RTW_WLAN_CATEGORY_QOS = 1, + RTW_WLAN_CATEGORY_DLS = 2, + RTW_WLAN_CATEGORY_BACK = 3, + RTW_WLAN_CATEGORY_PUBLIC = 4, //IEEE 802.11 public action frames + RTW_WLAN_CATEGORY_RADIO_MEASUREMENT = 5, + RTW_WLAN_CATEGORY_FT = 6, + RTW_WLAN_CATEGORY_HT = 7, + RTW_WLAN_CATEGORY_SA_QUERY = 8, + RTW_WLAN_CATEGORY_UNPROTECTED_WNM = 11, // add for CONFIG_IEEE80211W, none 11w also can use + RTW_WLAN_CATEGORY_TDLS = 12, + RTW_WLAN_CATEGORY_SELF_PROTECTED = 15, // add for CONFIG_IEEE80211W, none 11w also can use + RTW_WLAN_CATEGORY_WMM = 17, + RTW_WLAN_CATEGORY_VHT = 21, + RTW_WLAN_CATEGORY_P2P = 0x7f,//P2P action frames +}; + +/* SPECTRUM_MGMT action code */ +enum rtw_ieee80211_spectrum_mgmt_actioncode { + RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, + RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, + RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, + RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, + RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, + RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, +}; + +enum _PUBLIC_ACTION{ + ACT_PUBLIC_BSSCOEXIST = 0, // 20/40 BSS Coexistence + ACT_PUBLIC_DSE_ENABLE = 1, + ACT_PUBLIC_DSE_DEENABLE = 2, + ACT_PUBLIC_DSE_REG_LOCATION = 3, + ACT_PUBLIC_EXT_CHL_SWITCH = 4, + ACT_PUBLIC_DSE_MSR_REQ = 5, + ACT_PUBLIC_DSE_MSR_RPRT = 6, + ACT_PUBLIC_MP = 7, // Measurement Pilot + ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, + ACT_PUBLIC_VENDOR = 9, // for WIFI_DIRECT + ACT_PUBLIC_GAS_INITIAL_REQ = 10, + ACT_PUBLIC_GAS_INITIAL_RSP = 11, + ACT_PUBLIC_GAS_COMEBACK_REQ = 12, + ACT_PUBLIC_GAS_COMEBACK_RSP = 13, + ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, + ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_MAX +}; + +#ifdef CONFIG_TDLS +enum TDLS_ACTION_FIELD{ + TDLS_SETUP_REQUEST = 0, + TDLS_SETUP_RESPONSE = 1, + TDLS_SETUP_CONFIRM = 2, + TDLS_TEARDOWN = 3, + TDLS_PEER_TRAFFIC_INDICATION = 4, + TDLS_CHANNEL_SWITCH_REQUEST = 5, + TDLS_CHANNEL_SWITCH_RESPONSE = 6, + TDLS_PEER_PSM_REQUEST = 7, + TDLS_PEER_PSM_RESPONSE = 8, + TDLS_PEER_TRAFFIC_RESPONSE = 9, + TDLS_DISCOVERY_REQUEST = 10, + TDLS_DISCOVERY_RESPONSE = 14, //it's used in public action frame +}; + +#define TUNNELED_PROBE_REQ 15 +#define TUNNELED_PROBE_RSP 16 +#endif //CONFIG_TDLS + +/* BACK action code */ +enum rtw_ieee80211_back_actioncode { + RTW_WLAN_ACTION_ADDBA_REQ = 0, + RTW_WLAN_ACTION_ADDBA_RESP = 1, + RTW_WLAN_ACTION_DELBA = 2, +}; + +/* HT features action code */ +enum rtw_ieee80211_ht_actioncode { + RTW_WLAN_ACTION_HT_NOTI_CHNL_WIDTH = 0, + RTW_WLAN_ACTION_HT_SM_PS = 1, + RTW_WLAN_ACTION_HT_PSMP = 2, + RTW_WLAN_ACTION_HT_SET_PCO_PHASE = 3, + RTW_WLAN_ACTION_HT_CSI = 4, + RTW_WLAN_ACTION_HT_NON_COMPRESS_BEAMFORMING = 5, + RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING = 6, + RTW_WLAN_ACTION_HT_ASEL_FEEDBACK = 7, +}; + +/* BACK (block-ack) parties */ +enum rtw_ieee80211_back_parties { + RTW_WLAN_BACK_RECIPIENT = 0, + RTW_WLAN_BACK_INITIATOR = 1, + RTW_WLAN_BACK_TIMER = 2, +}; + +/*20/40 BSS Coexistence element */ +#define RTW_WLAN_20_40_BSS_COEX_INFO_REQ BIT(0) +#define RTW_WLAN_20_40_BSS_COEX_40MHZ_INTOL BIT(1) +#define RTW_WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ BIT(2) +#define RTW_WLAN_20_40_BSS_COEX_OBSS_EXEMPT_REQ BIT(3) +#define RTW_WLAN_20_40_BSS_COEX_OBSS_EXEMPT_GRNT BIT(4) + +/* VHT features action code */ +enum rtw_ieee80211_vht_actioncode{ + RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING = 0, + RTW_WLAN_ACTION_VHT_GROUPID_MANAGEMENT = 1, + RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION = 2, +}; + + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ +#ifndef PLATFORM_FREEBSD //Baron BSD has defined +#define WME_OUI_TYPE 2 +#endif //PLATFORM_FREEBSD +#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WME_VERSION 1 + +#define WME_ACTION_CODE_SETUP_REQUEST 0 +#define WME_ACTION_CODE_SETUP_RESPONSE 1 +#define WME_ACTION_CODE_TEARDOWN 2 + +#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 +#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 +#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 + +#define WME_TSPEC_DIRECTION_UPLINK 0 +#define WME_TSPEC_DIRECTION_DOWNLINK 1 +#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + + +#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ + +#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ + +/** + * enum rtw_ieee80211_channel_flags - channel flags + * + * Channel flags set by the regulatory control code. + * + * @RTW_IEEE80211_CHAN_DISABLED: This channel is disabled. + * @RTW_IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted + * on this channel. + * @RTW_IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. + * @RTW_IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @RTW_IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel + * is not permitted. + * @RTW_IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel + * is not permitted. + */ + enum rtw_ieee80211_channel_flags { + RTW_IEEE80211_CHAN_DISABLED = 1<<0, + RTW_IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, + RTW_IEEE80211_CHAN_NO_IBSS = 1<<2, + RTW_IEEE80211_CHAN_RADAR = 1<<3, + RTW_IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + RTW_IEEE80211_CHAN_NO_HT40MINUS = 1<<5, + }; + + #define RTW_IEEE80211_CHAN_NO_HT40 \ + (RTW_IEEE80211_CHAN_NO_HT40PLUS | RTW_IEEE80211_CHAN_NO_HT40MINUS) + +/* Represent channel details, subset of ieee80211_channel */ +struct rtw_ieee80211_channel { + //enum ieee80211_band band; + //u16 center_freq; + u16 hw_value; + u32 flags; + //int max_antenna_gain; + //int max_power; + //int max_reg_power; + //bool beacon_found; + //u32 orig_flags; + //int orig_mag; + //int orig_mpwr; +}; + +#define CHAN_FMT \ + /*"band:%d, "*/ \ + /*"center_freq:%u, "*/ \ + "hw_value:%u, " \ + "flags:0x%08x" \ + /*"max_antenna_gain:%d\n"*/ \ + /*"max_power:%d\n"*/ \ + /*"max_reg_power:%d\n"*/ \ + /*"beacon_found:%u\n"*/ \ + /*"orig_flags:0x%08x\n"*/ \ + /*"orig_mag:%d\n"*/ \ + /*"orig_mpwr:%d\n"*/ + +#define CHAN_ARG(channel) \ + /*(channel)->band*/ \ + /*, (channel)->center_freq*/ \ + (channel)->hw_value \ + , (channel)->flags \ + /*, (channel)->max_antenna_gain*/ \ + /*, (channel)->max_power*/ \ + /*, (channel)->max_reg_power*/ \ + /*, (channel)->beacon_found*/ \ + /*, (channel)->orig_flags*/ \ + /*, (channel)->orig_mag*/ \ + /*, (channel)->orig_mpwr*/ \ + +/* Parsed Information Elements */ +struct rtw_ieee802_11_elems { + u8 *ssid; + u8 ssid_len; + u8 *supp_rates; + u8 supp_rates_len; + u8 *fh_params; + u8 fh_params_len; + u8 *ds_params; + u8 ds_params_len; + u8 *cf_params; + u8 cf_params_len; + u8 *tim; + u8 tim_len; + u8 *ibss_params; + u8 ibss_params_len; + u8 *challenge; + u8 challenge_len; + u8 *erp_info; + u8 erp_info_len; + u8 *ext_supp_rates; + u8 ext_supp_rates_len; + u8 *wpa_ie; + u8 wpa_ie_len; + u8 *rsn_ie; + u8 rsn_ie_len; + u8 *wme; + u8 wme_len; + u8 *wme_tspec; + u8 wme_tspec_len; + u8 *wps_ie; + u8 wps_ie_len; + u8 *power_cap; + u8 power_cap_len; + u8 *supp_channels; + u8 supp_channels_len; + u8 *mdie; + u8 mdie_len; + u8 *ftie; + u8 ftie_len; + u8 *timeout_int; + u8 timeout_int_len; + u8 *ht_capabilities; + u8 ht_capabilities_len; + u8 *ht_operation; + u8 ht_operation_len; + u8 *vendor_ht_cap; + u8 vendor_ht_cap_len; + u8 *vht_capabilities; + u8 vht_capabilities_len; + u8 *vht_operation; + u8 vht_operation_len; + u8 *vht_op_mode_notify; + u8 vht_op_mode_notify_len; +}; + +typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; + +ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, + struct rtw_ieee802_11_elems *elems, + int show_errors); + +u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen); +u8 *rtw_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen); + +enum secondary_ch_offset { + SCN = 0, /* no secondary channel */ + SCA = 1, /* secondary channel above */ + SCB = 3, /* secondary channel below */ +}; +u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset); +u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset); +u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt); +u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset); +u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl, u8 flags, u16 reason, u16 precedence); + +u8 *rtw_get_ie(u8*pbuf, sint index, sint *len, sint limit); +u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen); +int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len); + +void rtw_set_supported_rate(u8* SupportedRates, uint mode) ; + +unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit); +unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit); +int rtw_get_wpa_cipher_suite(u8 *s); +int rtw_get_wpa2_cipher_suite(u8 *s); +int rtw_get_wapi_ie(u8 *in_ie,uint in_len,u8 *wapi_ie,u16 *wapi_len); +int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x); +int rtw_parse_wpa2_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x); + +int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len); + +u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); +u8 *rtw_get_wps_ie_from_scan_queue(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen, u8 frame_type); +u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); +u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content); + +/** + * for_each_ie - iterate over continuous IEs + * @ie: + * @buf: + * @buf_len: + */ +#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(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); + +void rtw_ies_get_chbw(u8 *ies, int ies_len, u8 *ch, u8 *bw, u8 *offset); + +void rtw_bss_get_chbw(WLAN_BSSID_EX *bss, u8 *ch, u8 *bw, u8 *offset); + +bool rtw_is_chbw_grouped(u8 ch_a, u8 bw_a, u8 offset_a + , u8 ch_b, u8 bw_b, u8 offset_b); +void rtw_sync_chbw(u8 *req_ch, u8 *req_bw, u8 *req_offset + , u8 *g_ch, u8 *g_bw, u8 *g_offset); + +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(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_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content); +u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr); +uint rtw_del_p2p_ie(u8 *ies, uint ies_len_ori, const char *msg); +uint rtw_del_p2p_attr(u8 *ie, uint ielen_ori, u8 attr_id); +u8 *rtw_bss_ex_get_p2p_ie(WLAN_BSSID_EX *bss_ex, u8 *p2p_ie, uint *p2p_ielen); +void rtw_bss_ex_del_p2p_ie(WLAN_BSSID_EX *bss_ex); +void rtw_bss_ex_del_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); + +void dump_wfd_ie(void *sel, u8 *ie, u32 ie_len); +u8 *rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); +u8 *rtw_get_wfd_attr(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id, u8 *buf_content, uint *len_content); +uint rtw_del_wfd_ie(u8 *ies, uint ies_len_ori, const char *msg); +uint rtw_del_wfd_attr(u8 *ie, uint ielen_ori, u8 attr_id); +u8 *rtw_bss_ex_get_wfd_ie(WLAN_BSSID_EX *bss_ex, u8 *wfd_ie, uint *wfd_ielen); +void rtw_bss_ex_del_wfd_ie(WLAN_BSSID_EX *bss_ex); +void rtw_bss_ex_del_wfd_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); + +uint rtw_get_rateset_len(u8 *rateset); + +struct registry_priv; +int rtw_generate_ie(struct registry_priv *pregistrypriv); + +int rtw_get_bit_value_from_ieee_value(u8 val); + +uint rtw_is_cckrates_included(u8 *rate); + +uint rtw_is_cckratesonly_included(u8 *rate); + +int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); + +void rtw_get_bcn_info(struct wlan_network *pnetwork); + +u8 rtw_check_invalid_mac_address(u8 *mac_addr, u8 check_local_bit); +void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr); + +u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI, unsigned char * MCS_rate); +u8 rtw_ht_mcsset_to_nss(u8 *supp_mcs_set); + +int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8* category, u8 *action); +const char *action_public_str(u8 action); + +u8 key_2char2num(u8 hch, u8 lch); +u8 str_2char2num(u8 hch, u8 lch); +void macstr2num(u8 *dst, u8 *src); +u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); +int wifirate2_ratetbl_inx(unsigned char rate); + +#endif /* IEEE80211_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211_ext.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211_ext.h new file mode 100644 index 00000000..14f1b239 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ieee80211_ext.h @@ -0,0 +1,477 @@ +/****************************************************************************** + * + * 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 __IEEE80211_EXT_H +#define __IEEE80211_EXT_H + +#include +#include +#include + +#define WMM_OUI_TYPE 2 +#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WMM_VERSION 1 + +#define WPA_PROTO_WPA BIT(0) +#define WPA_PROTO_RSN BIT(1) + +#define WPA_KEY_MGMT_IEEE8021X BIT(0) +#define WPA_KEY_MGMT_PSK BIT(1) +#define WPA_KEY_MGMT_NONE BIT(2) +#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3) +#define WPA_KEY_MGMT_WPA_NONE BIT(4) + + +#define WPA_CAPABILITY_PREAUTH BIT(0) +#define WPA_CAPABILITY_MGMT_FRAME_PROTECTION BIT(6) +#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9) + + +#define PMKID_LEN 16 + + +#ifdef PLATFORM_LINUX +struct wpa_ie_hdr { + u8 elem_id; + u8 len; + u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ + u8 version[2]; /* little endian */ +}__attribute__ ((packed)); + +struct rsn_ie_hdr { + u8 elem_id; /* WLAN_EID_RSN */ + u8 len; + u8 version[2]; /* little endian */ +}__attribute__ ((packed)); + +struct wme_ac_parameter { +#if defined(CONFIG_LITTLE_ENDIAN) + /* byte 1 */ + u8 aifsn:4, + acm:1, + aci:2, + reserved:1; + + /* byte 2 */ + u8 eCWmin:4, + eCWmax:4; +#elif defined(CONFIG_BIG_ENDIAN) + /* byte 1 */ + u8 reserved:1, + aci:2, + acm:1, + aifsn:4; + + /* byte 2 */ + u8 eCWmax:4, + eCWmin:4; +#else +#error "Please fix " +#endif + + /* bytes 3 & 4 */ + u16 txopLimit; +} __attribute__ ((packed)); + +struct wme_parameter_element { + /* required fields for WME version 1 */ + u8 oui[3]; + u8 oui_type; + u8 oui_subtype; + u8 version; + u8 acInfo; + u8 reserved; + struct wme_ac_parameter ac[4]; + +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct wpa_ie_hdr { + u8 elem_id; + u8 len; + u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */ + u8 version[2]; /* little endian */ +}; + +struct rsn_ie_hdr { + u8 elem_id; /* WLAN_EID_RSN */ + u8 len; + u8 version[2]; /* little endian */ +}; + +#pragma pack() + +#endif + +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val)) +//#define RSN_SELECTOR_PUT(a, val) WPA_PUT_LE32((u8 *) (a), (val)) + + + +/* Action category code */ +enum ieee80211_category { + WLAN_CATEGORY_SPECTRUM_MGMT = 0, + WLAN_CATEGORY_QOS = 1, + WLAN_CATEGORY_DLS = 2, + WLAN_CATEGORY_BACK = 3, + WLAN_CATEGORY_HT = 7, + WLAN_CATEGORY_WMM = 17, +}; + +/* SPECTRUM_MGMT action code */ +enum ieee80211_spectrum_mgmt_actioncode { + WLAN_ACTION_SPCT_MSR_REQ = 0, + WLAN_ACTION_SPCT_MSR_RPRT = 1, + WLAN_ACTION_SPCT_TPC_REQ = 2, + WLAN_ACTION_SPCT_TPC_RPRT = 3, + WLAN_ACTION_SPCT_CHL_SWITCH = 4, + WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, +}; + +/* BACK action code */ +enum ieee80211_back_actioncode { + WLAN_ACTION_ADDBA_REQ = 0, + WLAN_ACTION_ADDBA_RESP = 1, + WLAN_ACTION_DELBA = 2, +}; + +/* HT features action code */ +enum ieee80211_ht_actioncode { + WLAN_ACTION_NOTIFY_CH_WIDTH = 0, + WLAN_ACTION_SM_PS = 1, + WLAN_ACTION_PSPM = 2, + WLAN_ACTION_PCO_PHASE = 3, + WLAN_ACTION_MIMO_CSI_MX = 4, + WLAN_ACTION_MIMO_NONCP_BF = 5, + WLAN_ACTION_MIMP_CP_BF = 6, + WLAN_ACTION_ASEL_INDICATES_FB = 7, + WLAN_ACTION_HI_INFO_EXCHG = 8, +}; + +/* BACK (block-ack) parties */ +enum ieee80211_back_parties { + WLAN_BACK_RECIPIENT = 0, + WLAN_BACK_INITIATOR = 1, + WLAN_BACK_TIMER = 2, +}; + +#ifdef PLATFORM_LINUX + +struct ieee80211_mgmt { + u16 frame_control; + u16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + u16 seq_ctrl; + union { + struct { + u16 auth_alg; + u16 auth_transaction; + u16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } __attribute__ ((packed)) auth; + struct { + u16 reason_code; + } __attribute__ ((packed)) deauth; + struct { + u16 capab_info; + u16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) assoc_req; + struct { + u16 capab_info; + u16 status_code; + u16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) assoc_resp, reassoc_resp; + struct { + u16 capab_info; + u16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) reassoc_req; + struct { + u16 reason_code; + } __attribute__ ((packed)) disassoc; + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } __attribute__ ((packed)) beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } __attribute__ ((packed)) probe_req; + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } __attribute__ ((packed)) probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } __attribute__ ((packed)) wme_action; +#if 0 + struct{ + u8 action_code; + u8 element_id; + u8 length; + struct ieee80211_channel_sw_ie sw_elem; + } __attribute__ ((packed)) chan_switch; + struct{ + u8 action_code; + u8 dialog_token; + u8 element_id; + u8 length; + struct ieee80211_msrment_ie msr_elem; + } __attribute__ ((packed)) measurement; +#endif + struct{ + u8 action_code; + u8 dialog_token; + u16 capab; + u16 timeout; + u16 start_seq_num; + } __attribute__ ((packed)) addba_req; + struct{ + u8 action_code; + u8 dialog_token; + u16 status; + u16 capab; + u16 timeout; + } __attribute__ ((packed)) addba_resp; + struct{ + u8 action_code; + u16 params; + u16 reason_code; + } __attribute__ ((packed)) delba; + struct{ + u8 action_code; + /* capab_info for open and confirm, + * reason for close + */ + u16 aux; + /* Followed in plink_confirm by status + * code, AID and supported rates, + * and directly by supported rates in + * plink_open and plink_close + */ + u8 variable[0]; + } __attribute__ ((packed)) plink_action; + struct{ + u8 action_code; + u8 variable[0]; + } __attribute__ ((packed)) mesh_action; + } __attribute__ ((packed)) u; + } __attribute__ ((packed)) action; + } __attribute__ ((packed)) u; +}__attribute__ ((packed)); + +#endif + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct ieee80211_mgmt { + u16 frame_control; + u16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + u16 seq_ctrl; + union { + struct { + u16 auth_alg; + u16 auth_transaction; + u16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } auth; + struct { + u16 reason_code; + } deauth; + struct { + u16 capab_info; + u16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } assoc_req; + struct { + u16 capab_info; + u16 status_code; + u16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } assoc_resp, reassoc_resp; + struct { + u16 capab_info; + u16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } reassoc_req; + struct { + u16 reason_code; + } disassoc; +#if 0 + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } probe_req; + + struct { + __le64 timestamp; + u16 beacon_int; + u16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } probe_resp; +#endif + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } wme_action; +/* + struct{ + u8 action_code; + u8 element_id; + u8 length; + struct ieee80211_channel_sw_ie sw_elem; + } chan_switch; + struct{ + u8 action_code; + u8 dialog_token; + u8 element_id; + u8 length; + struct ieee80211_msrment_ie msr_elem; + } measurement; +*/ + struct{ + u8 action_code; + u8 dialog_token; + u16 capab; + u16 timeout; + u16 start_seq_num; + } addba_req; + struct{ + u8 action_code; + u8 dialog_token; + u16 status; + u16 capab; + u16 timeout; + } addba_resp; + struct{ + u8 action_code; + u16 params; + u16 reason_code; + } delba; + struct{ + u8 action_code; + /* capab_info for open and confirm, + * reason for close + */ + u16 aux; + /* Followed in plink_confirm by status + * code, AID and supported rates, + * and directly by supported rates in + * plink_open and plink_close + */ + u8 variable[0]; + } plink_action; + struct{ + u8 action_code; + u8 variable[0]; + } mesh_action; + } u; + } action; + } u; +} ; + +#pragma pack() + +#endif + +/* mgmt header + 1 byte category code */ +#define IEEE80211_MIN_ACTION_SIZE FIELD_OFFSET(struct ieee80211_mgmt, u.action.u) + + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/if_ether.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/if_ether.h new file mode 100644 index 00000000..93ed096d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/if_ether.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * 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 _LINUX_IF_ETHER_H +#define _LINUX_IF_ETHER_H + +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ + +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ +#define ETH_DATA_LEN 1500 /* Max. octets in payload */ +#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + +/* + * These are the defined Ethernet Protocol ID's. + */ + +#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ +#define ETH_P_PUP 0x0200 /* Xerox PUP packet */ +#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_X25 0x0805 /* CCITT X.25 */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ +#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ +#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ +#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ +#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ +#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ +#define ETH_P_LAT 0x6004 /* DEC LAT */ +#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ +#define ETH_P_CUST 0x6006 /* DEC Customer use */ +#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ +#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ +#define ETH_P_ATALK 0x809B /* Appletalk DDP */ +#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ +#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define ETH_P_IPX 0x8137 /* IPX over DIX */ +#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ +#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ +#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport + * over Ethernet + */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + +#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ +#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ +#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ +#define ETH_P_802_2 0x0004 /* 802.2 frames */ +#define ETH_P_SNAP 0x0005 /* Internal only */ +#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ +#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ +#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ +#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ +#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ +#define ETH_P_CONTROL 0x0016 /* Card specific control frames */ +#define ETH_P_IRDA 0x0017 /* Linux-IrDA */ +#define ETH_P_ECONET 0x0018 /* Acorn Econet */ + +/* + * This is an Ethernet frame header. + */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; + +struct _vlan { + unsigned short h_vlan_TCI; // Encapsulates priority and VLAN ID + unsigned short h_vlan_encapsulated_proto; +}; + + + +#define get_vlan_id(pvlan) ((ntohs((unsigned short )pvlan->h_vlan_TCI)) & 0xfff) +#define get_vlan_priority(pvlan) ((ntohs((unsigned short )pvlan->h_vlan_TCI))>>13) +#define get_vlan_encap_proto(pvlan) (ntohs((unsigned short )pvlan->h_vlan_encapsulated_proto)) + + +#endif /* _LINUX_IF_ETHER_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/ip.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ip.h new file mode 100644 index 00000000..a637d048 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/ip.h @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * 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 _LINUX_IP_H +#define _LINUX_IP_H + +/* SOL_IP socket options */ + +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_MINCOST 0x02 + +#define IPTOS_PREC_MASK 0xE0 +#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* IP options */ +#define IPOPT_COPY 0x80 +#define IPOPT_CLASS_MASK 0x60 +#define IPOPT_NUMBER_MASK 0x1f + +#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) +#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) +#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_MEASUREMENT 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_END (0 |IPOPT_CONTROL) +#define IPOPT_NOOP (1 |IPOPT_CONTROL) +#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) +#define IPOPT_RR (7 |IPOPT_CONTROL) +#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY) + +#define IPVERSION 4 +#define MAXTTL 255 +#define IPDEFTTL 64 + +/* struct timestamp, struct route and MAX_ROUTES are removed. + + REASONS: it is clear that nobody used them because: + - MAX_ROUTES value was wrong. + - "struct route" was wrong. + - "struct timestamp" had fatally misaligned bitfields and was completely unusable. + */ + +#define IPOPT_OPTVAL 0 +#define IPOPT_OLEN 1 +#define IPOPT_OFFSET 2 +#define IPOPT_MINOFF 4 +#define MAX_IPOPTLEN 40 +#define IPOPT_NOP IPOPT_NOOP +#define IPOPT_EOL IPOPT_END +#define IPOPT_TS IPOPT_TIMESTAMP + +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +#ifdef PLATFORM_LINUX + +struct ip_options { + __u32 faddr; /* Saved first hop address */ + unsigned char optlen; + unsigned char srr; + unsigned char rr; + unsigned char ts; + unsigned char is_setbyuser:1, /* Set by setsockopt? */ + is_data:1, /* Options in __data, rather than skb */ + is_strictroute:1, /* Strict source route */ + srr_is_hit:1, /* Packet destination addr was our one */ + is_changed:1, /* IP checksum more not valid */ + rr_needaddr:1, /* Need to record addr of outgoing dev */ + ts_needtime:1, /* Need to record timestamp */ + ts_needaddr:1; /* Need to record addr of outgoing dev */ + unsigned char router_alert; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __data[0]; +}; + +#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) +#endif + +struct iphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +#error "Please fix " +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; + /*The options start here. */ +}; + +#endif /* _LINUX_IP_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/linux/wireless.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/linux/wireless.h new file mode 100644 index 00000000..d79caeb5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/linux/wireless.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * 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 _LINUX_WIRELESS_H +#define _LINUX_WIRELESS_H + +/***************************** INCLUDES *****************************/ + +#if 0 +#include /* for __u* and __s* typedefs */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#else +#define __user +//typedef uint16_t __u16; +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#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 + * pointer to memory allocated in user space. + */ +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + + +/* ------------------------ IOCTL REQUEST ------------------------ */ +/* + * This structure defines the payload of an ioctl, and is used + * below. + * + * Note that this structure should fit on the memory footprint + * of iwreq (which is the same as ifreq), which mean a max size of + * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... + * You should check this when increasing the structures defined + * above in this file... + */ +union iwreq_data +{ + /* Config - generic */ + char name[IFNAMSIZ]; + /* Name : used to verify the presence of wireless extensions. + * Name of the protocol/provider... */ + + struct iw_point data; /* Other large parameters */ +}; + +/* + * The structure to exchange data for ioctl. + * This structure is the same as 'struct ifreq', but (re)defined for + * convenience... + * Do I need to remind you about structure size (32 octets) ? + */ +struct iwreq +{ + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + } ifr_ifrn; + + /* Data part (defined just above) */ + union iwreq_data u; +}; + +#endif /* _LINUX_WIRELESS_H */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/mlme_osdep.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/mlme_osdep.h new file mode 100644 index 00000000..5380cd4d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/mlme_osdep.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * 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 __MLME_OSDEP_H_ +#define __MLME_OSDEP_H_ + + +#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_MPIXEL) +extern int time_after(u32 now, u32 old); +#endif + +extern void rtw_init_mlme_timer(_adapter *padapter); +extern void rtw_os_indicate_disconnect( _adapter *adapter ); +extern void rtw_os_indicate_connect( _adapter *adapter ); +void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted); +extern void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie); + +void rtw_reset_securitypriv( _adapter *adapter ); + +#endif //_MLME_OSDEP_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/mp_custom_oid.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/mp_custom_oid.h new file mode 100644 index 00000000..9cf1c827 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/mp_custom_oid.h @@ -0,0 +1,354 @@ +/****************************************************************************** + * + * 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 __CUSTOM_OID_H +#define __CUSTOM_OID_H + +// by Owen +// 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit +// 0xFF818500 - 0xFF81850F RTL8185 Setup Utility +// 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility + +// + +// by Owen for Production Kit +// For Production Kit with Agilent Equipments +// in order to make our custom oids hopefully somewhat unique +// we will use 0xFF (indicating implementation specific OID) +// 81(first byte of non zero Realtek unique identifier) +// 80 (second byte of non zero Realtek unique identifier) +// XX (the custom OID number - providing 255 possible custom oids) + +#define OID_RT_PRO_RESET_DUT 0xFF818000 +#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 +#define OID_RT_PRO_START_TEST 0xFF818002 +#define OID_RT_PRO_STOP_TEST 0xFF818003 +#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 +#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 +#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 +#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 +#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 +#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 +#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A + +#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D +#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E +#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F +#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 +#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 +#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 +#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 +#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 +#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 +#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 +#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 +#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 +#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 +#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A +#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B +#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C +#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D +#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E +#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F +#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 +#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 +#define OID_RT_PRO_READ_EEPROM 0xFF818022 +#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 +#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 +#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 +#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 +#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 +#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 +#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 +#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A +#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C +// added by Owen on 04/08/03 for Cameo's request +#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D +#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E +#define OID_RT_PRO_SET_MODULATION 0xFF81802F +// + +//Sean +#define OID_RT_DRIVER_OPTION 0xFF818080 +#define OID_RT_RF_OFF 0xFF818081 +#define OID_RT_AUTH_STATUS 0xFF818082 + +//======================================================================== +#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B +#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C +#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B +#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 +//======================================================================== + + +// by Owen for RTL8185 Phy Status Report Utility +#define OID_RT_UTILITY_FALSE_ALARM_COUNTERS 0xFF818580 +#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 +#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 +#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 +#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 +#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS 0xFF818585 +#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 +// + +// by Owen on 03/09/19-03/09/22 for RTL8185 +#define OID_RT_WIRELESS_MODE 0xFF818500 +#define OID_RT_SUPPORTED_RATES 0xFF818501 +#define OID_RT_DESIRED_RATES 0xFF818502 +#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 +// + +#define OID_RT_GET_CONNECT_STATE 0xFF030001 +#define OID_RT_RESCAN 0xFF030002 +#define OID_RT_SET_KEY_LENGTH 0xFF030003 +#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 + +#define OID_RT_SET_CHANNEL 0xFF010182 +#define OID_RT_SET_SNIFFER_MODE 0xFF010183 +#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 +#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 +#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 +#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 +#define OID_RT_GET_TX_RETRY 0xFF010188 +#define OID_RT_GET_RX_RETRY 0xFF010189 +#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A//S +#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B//S + +#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 +#define OID_RT_GET_TX_BEACON_OK 0xFF010191 +#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 +#define OID_RT_GET_RX_ICV_ERR 0xFF010193 +#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 +#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 +#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 +#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 +#define OID_RT_GET_AP_IP 0xFF010198 +#define OID_RT_GET_CHANNELPLAN 0xFF010199 +#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A +#define OID_RT_SET_BCN_INTVL 0xFF01019B +#define OID_RT_GET_RF_VENDER 0xFF01019C +#define OID_RT_DEDICATE_PROBE 0xFF01019D +#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E + +#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F + +#define OID_RT_GET_CCA_ERR 0xFF0101A0 +#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 +#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 + +#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 +#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 + +// by Owen on 03/31/03 for Cameo's request +#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 +// +#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 +#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 +#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 +#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 +#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 +#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA +#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB +#define OID_RT_GET_CHANNEL 0xFF0101AC + +#define OID_RT_SET_CHANNELPLAN 0xFF0101AD +#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE +#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF +#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 +#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 +#define OID_RT_GET_IS_ROAMING 0xFF0101B2 +#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 +#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 +#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 +#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 +#define OID_RT_RESET_LOG 0xFF0101B7 +#define OID_RT_GET_LOG 0xFF0101B8 +#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 +#define OID_RT_GET_HEADER_FAIL 0xFF0101BA +#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB +#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC +#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD +#define OID_RT_GET_TX_INFO 0xFF0101BE +#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF +#define OID_RT_RF_READ_WRITE 0xFF0101C0 + +// For Netgear request. 2005.01.13, by rcnjko. +#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 +#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 +// For Netgear request. 2005.02.17, by rcnjko. +#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 +// For AZ project. 2005.06.27, by rcnjko. +#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 + +// Vincent 8185MP +#define OID_RT_PRO_RX_FILTER 0xFF0111C0 + +//Andy TEST +//#define OID_RT_PRO_WRITE_REGISTRY 0xFF0111C1 +//#define OID_RT_PRO_READ_REGISTRY 0xFF0111C2 +#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 +#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 + + +#define OID_RT_PRO_SET_INITIAL_GAIN 0xFF0111C3 +#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 +#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 +#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 +#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 +#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 +#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 +#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA + +// AP OID +#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 +#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 +#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 +#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 +#define OID_RT_AP_SUPPORTED 0xFF010304 // Determine if driver supports AP mode. 2004.08.27, by rcnjko. +#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 // Set WPA-PSK passphrase into authenticator. 2005.07.08, byrcnjko. + +// 8187MP. 2004.09.06, by rcnjko. +#define OID_RT_PRO8187_WI_POLL 0xFF818780 +#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 +#define OID_RT_PRO_READ_BB_REG 0xFF818782 +#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 +#define OID_RT_PRO_READ_RF_REG 0xFF818784 + +// Meeting House. added by Annie, 2005-07-20. +#define OID_RT_MH_VENDER_ID 0xFFEDC100 + +//8711 MP OID added 20051230. +#define OID_RT_PRO8711_JOIN_BSS 0xFF871100//S + +#define OID_RT_PRO_READ_REGISTER 0xFF871101 //Q +#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 //S + +#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 //Q +#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 //S + +#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 //S + +#define OID_RT_PRO_READ16_EEPROM 0xFF871106 //Q +#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 //S + +#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 //S +#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 //Q + +#define OID_RT_PRO8711_WI_POLL 0xFF87110A //Q +#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B //Q +#define OID_RT_RD_ATTRIB_MEM 0xFF87110C//Q +#define OID_RT_WR_ATTRIB_MEM 0xFF87110D//S + + +//Method 2 for H2C/C2H +#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 //S +#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 //Q +#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 //S +#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 //Q +#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114//Q + +#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 //Q, S + +#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 //S +#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 //Q,S +#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 //Q +#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 //Q + +#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A //S +#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B //Q +#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C //S +#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D //Q +#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E //S +#define OID_RT_POLL_RX_STATUS 0xFF87111F //Q + +#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 //Q,S +#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121//S +#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122//S +#define OID_RT_PRO_READ_TSSI 0xFF871123//S +#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124//S + + +#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 //Q +#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 //S + +//Method 2 , using workitem +#define OID_RT_SET_READ_REG 0xFF871181 //S +#define OID_RT_SET_WRITE_REG 0xFF871182 //S +#define OID_RT_SET_BURST_READ_REG 0xFF871183 //S +#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 //S +#define OID_RT_SET_WRITE_TXCMD 0xFF871185 //S +#define OID_RT_SET_READ16_EEPROM 0xFF871186 //S +#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 //S +#define OID_RT_QRY_POLL_WKITEM 0xFF871188 //Q + +//For SDIO INTERFACE only +#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 //Q, S +#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 + +//For USB INTERFACE only +#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 //Q, S +#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 //S +#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 //S +#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 //Q +#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 //Q + +#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB //S +#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC //S +#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE + +#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 //Q, S +#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 //S +#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 //S +#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 //Q + +#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 //Q, S + +#define OID_RT_PRO_READ_EFUSE 0xFF871205 //Q +#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 //S +#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 //Q, S +#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 //Q + +#define OID_RT_SET_BANDWIDTH 0xFF871209 //S +#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A //S + +#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B //S + +#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C //Q + +#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D //S + +#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E //S + +#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F //S + +#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 //Q + +#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 //S +#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 //Q +#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 //Q + +#define OID_RT_SET_POWER_DOWN 0xFF871214 //S + +#define OID_RT_GET_POWER_MODE 0xFF871215 //Q + +#define OID_RT_PRO_EFUSE 0xFF871216 //Q, S +#define OID_RT_PRO_EFUSE_MAP 0xFF871217 //Q, S + +#endif //#ifndef __CUSTOM_OID_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/nic_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/nic_spec.h new file mode 100644 index 00000000..18e7b2c0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/nic_spec.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * + * 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 __NIC_SPEC_H__ +#define __NIC_SPEC_H__ + +#include + +#define RTL8711_MCTRL_ (0x20000) +#define RTL8711_UART_ (0x30000) +#define RTL8711_TIMER_ (0x40000) +#define RTL8711_FINT_ (0x50000) +#define RTL8711_HINT_ (0x50000) +#define RTL8711_GPIO_ (0x60000) +#define RTL8711_WLANCTRL_ (0x200000) +#define RTL8711_WLANFF_ (0xe00000) +#define RTL8711_HCICTRL_ (0x600000) +#define RTL8711_SYSCFG_ (0x620000) +#define RTL8711_SYSCTRL_ (0x620000) +#define RTL8711_MCCTRL_ (0x020000) + + +#include + +#include + + +#endif // __RTL8711_SPEC_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_intf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_intf.h new file mode 100644 index 00000000..8b8679fa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_intf.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * 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 __OSDEP_INTF_H_ +#define __OSDEP_INTF_H_ + + +struct intf_priv { + + u8 *intf_dev; + u32 max_iosz; //USB2.0: 128, USB1.1: 64, SDIO:64 + u32 max_xmitsz; //USB2.0: unlimited, SDIO:512 + u32 max_recvsz; //USB2.0: unlimited, SDIO:512 + + volatile u8 *io_rwmem; + volatile u8 *allocated_io_rwmem; + u32 io_wsz; //unit: 4bytes + u32 io_rsz;//unit: 4bytes + u8 intf_status; + + void (*_bus_io)(u8 *priv); + +/* +Under Sync. IRP (SDIO/USB) +A protection mechanism is necessary for the io_rwmem(read/write protocol) + +Under Async. IRP (SDIO/USB) +The protection mechanism is through the pending queue. +*/ + + _mutex ioctl_mutex; + + +#ifdef PLATFORM_LINUX + #ifdef CONFIG_USB_HCI + // when in USB, IO is through interrupt in/out endpoints + struct usb_device *udev; + PURB piorw_urb; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + _timer io_timer; + u8 bio_irp_timeout; + u8 bio_timer_cancel; + #endif +#endif + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + // below is for io_rwmem... + PMDL pmdl; + PSDBUS_REQUEST_PACKET sdrp; + PSDBUS_REQUEST_PACKET recv_sdrp; + PSDBUS_REQUEST_PACKET xmit_sdrp; + + PIRP piorw_irp; + + #endif + #ifdef CONFIG_USB_HCI + PURB piorw_urb; + PIRP piorw_irp; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + #endif +#endif + +}; + + +#ifdef CONFIG_R871X_TEST +int rtw_start_pseudo_adhoc(_adapter *padapter); +int rtw_stop_pseudo_adhoc(_adapter *padapter); +#endif + +struct dvobj_priv *devobj_init(void); +void devobj_deinit(struct dvobj_priv *pdvobj); + +u8 rtw_init_drv_sw(_adapter *padapter); +u8 rtw_free_drv_sw(_adapter *padapter); +u8 rtw_reset_drv_sw(_adapter *padapter); +void rtw_dev_unload(PADAPTER padapter); + +u32 rtw_start_drv_threads(_adapter *padapter); +void rtw_stop_drv_threads (_adapter *padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void rtw_cancel_dynamic_chk_timer(_adapter *padapter); +#endif +void rtw_cancel_all_timer(_adapter *padapter); + +uint loadparam(_adapter *adapter); + +#ifdef PLATFORM_LINUX +int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + +int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); +struct net_device *rtw_init_netdev(_adapter *padapter); + +void rtw_os_ndev_free(_adapter *adapter); +int rtw_os_ndev_init(_adapter *adapter, char *name); +void rtw_os_ndev_deinit(_adapter *adapter); +void rtw_os_ndevs_unregister(struct dvobj_priv *dvobj); +int rtw_os_ndevs_init(struct dvobj_priv *dvobj); +void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj); + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) +u16 rtw_recv_select_queue(struct sk_buff *skb); +#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) + +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 + + +#ifdef PLATFORM_FREEBSD +extern int rtw_ioctl(struct ifnet * ifp, u_long cmd, caddr_t data); +#endif + +void rtw_ips_dev_unload(_adapter *padapter); + +#ifdef CONFIG_IPS +int rtw_ips_pwr_up(_adapter *padapter); +void rtw_ips_pwr_down(_adapter *padapter); +#endif + +#ifdef CONFIG_CONCURRENT_MODE +struct _io_ops; +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops)); +void rtw_drv_if2_free(_adapter *if2); +void rtw_drv_if2_stop(_adapter *if2); +#ifdef CONFIG_MULTI_VIR_IFACES +struct dvobj_priv; +_adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops)); +void rtw_drv_stop_vir_ifaces(struct dvobj_priv *dvobj); +void rtw_drv_free_vir_ifaces(struct dvobj_priv *dvobj); +#endif //CONFIG_MULTI_VIR_IFACES +#endif + +void rtw_ndev_destructor(_nic_hdl ndev); + +#ifdef CONFIG_ARP_KEEP_ALIVE +int rtw_gw_addr_query(_adapter *padapter); +#endif + +int rtw_suspend_common(_adapter *padapter); +int rtw_resume_common(_adapter *padapter); + +#endif //_OSDEP_INTF_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service.h new file mode 100644 index 00000000..7562c86f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service.h @@ -0,0 +1,634 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __OSDEP_SERVICE_H_ +#define __OSDEP_SERVICE_H_ + + +#define _FAIL 0 +#define _SUCCESS 1 +#define RTW_RX_HANDLED 2 +//#define RTW_STATUS_TIMEDOUT -110 + +#undef _TRUE +#define _TRUE 1 + +#undef _FALSE +#define _FALSE 0 + + +#ifdef PLATFORM_FREEBSD +#include +#endif + +#ifdef PLATFORM_LINUX +#include +#endif + +#ifdef PLATFORM_OS_XP +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#define RTW_TIMER_HDL_NAME(name) rtw_##name##_timer_hdl +#define RTW_DECLARE_TIMER_HDL(name) void RTW_TIMER_HDL_NAME(name)(RTW_TIMER_HDL_ARGS) + +//#include + +#ifndef BIT + #define BIT(x) ( 1 << (x)) +#endif + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 +#define BIT32 0x0100000000 +#define BIT33 0x0200000000 +#define BIT34 0x0400000000 +#define BIT35 0x0800000000 +#define BIT36 0x1000000000 + +extern int RTW_STATUS_CODE(int error_code); + +#ifndef RTK_DMP_PLATFORM +#define CONFIG_USE_VMALLOC +#endif + +/* flags used for rtw_mstat_update() */ +enum mstat_f { + /* type: 0x00ff */ + MSTAT_TYPE_VIR = 0x00, + MSTAT_TYPE_PHY= 0x01, + MSTAT_TYPE_SKB = 0x02, + MSTAT_TYPE_USB = 0x03, + MSTAT_TYPE_MAX = 0x04, + + /* func: 0xff00 */ + MSTAT_FUNC_UNSPECIFIED = 0x00<<8, + MSTAT_FUNC_IO = 0x01<<8, + MSTAT_FUNC_TX_IO = 0x02<<8, + MSTAT_FUNC_RX_IO = 0x03<<8, + MSTAT_FUNC_TX = 0x04<<8, + MSTAT_FUNC_RX = 0x05<<8, + MSTAT_FUNC_CFG_VENDOR = 0x06<<8, + MSTAT_FUNC_MAX = 0x07<<8, +}; + +#define mstat_tf_idx(flags) ((flags)&0xff) +#define mstat_ff_idx(flags) (((flags)&0xff00) >> 8) + +typedef enum mstat_status{ + MSTAT_ALLOC_SUCCESS = 0, + MSTAT_ALLOC_FAIL, + MSTAT_FREE +} MSTAT_STATUS; + +#ifdef DBG_MEM_ALLOC +void rtw_mstat_update(const enum mstat_f flags, const MSTAT_STATUS status, u32 sz); +void rtw_mstat_dump (void *sel); +u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_vmfree(u8 *pbuf, const enum mstat_f flags, u32 sz, const char *func, const int line); +u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_mfree(u8 *pbuf, const enum mstat_f flags, u32 sz, const char *func, const int line); + +struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line); +int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line); +void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line); +#ifdef CONFIG_USB_HCI +void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, const int line); +void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, const int line); +#endif /* CONFIG_USB_HCI */ + +#ifdef CONFIG_USE_VMALLOC +#define rtw_vmalloc(sz) dbg_rtw_vmalloc((sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_zvmalloc(sz) dbg_rtw_zvmalloc((sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmfree(pbuf, sz) dbg_rtw_vmfree((pbuf), (sz), MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmalloc_f(sz, mstat_f) dbg_rtw_vmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_zvmalloc_f(sz, mstat_f) dbg_rtw_zvmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#define rtw_vmfree_f(pbuf, sz, mstat_f) dbg_rtw_vmfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_VIR, __FUNCTION__, __LINE__) +#else /* CONFIG_USE_VMALLOC */ +#define rtw_vmalloc(sz) dbg_rtw_malloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zvmalloc(sz) dbg_rtw_zmalloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmfree(pbuf, sz) dbg_rtw_mfree((pbuf), (sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmalloc_f(sz, mstat_f) dbg_rtw_malloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zvmalloc_f(sz, mstat_f) dbg_rtw_zmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_vmfree_f(pbuf, sz, mstat_f) dbg_rtw_mfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#endif /* CONFIG_USE_VMALLOC */ +#define rtw_malloc(sz) dbg_rtw_malloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zmalloc(sz) dbg_rtw_zmalloc((sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_mfree(pbuf, sz) dbg_rtw_mfree((pbuf), (sz), MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_malloc_f(sz, mstat_f) dbg_rtw_malloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_zmalloc_f(sz, mstat_f) dbg_rtw_zmalloc((sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) +#define rtw_mfree_f(pbuf, sz, mstat_f) dbg_rtw_mfree((pbuf), (sz), ((mstat_f)&0xff00)|MSTAT_TYPE_PHY, __FUNCTION__, __LINE__) + +#define rtw_skb_alloc(size) dbg_rtw_skb_alloc((size), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_free(skb) dbg_rtw_skb_free((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_alloc_f(size, mstat_f) dbg_rtw_skb_alloc((size), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_free_f(skb, mstat_f) dbg_rtw_skb_free((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_copy(skb) dbg_rtw_skb_copy((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_clone(skb) dbg_rtw_skb_clone((skb), MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_copy_f(skb, mstat_f) dbg_rtw_skb_copy((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_clone_f(skb, mstat_f) dbg_rtw_skb_clone((skb), ((mstat_f)&0xff00)|MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_netif_rx(ndev, skb) dbg_rtw_netif_rx(ndev, skb, MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#define rtw_skb_queue_purge(sk_buff_head) dbg_rtw_skb_queue_purge(sk_buff_head, MSTAT_TYPE_SKB, __FUNCTION__, __LINE__) +#ifdef CONFIG_USB_HCI +#define rtw_usb_buffer_alloc(dev, size, dma) dbg_rtw_usb_buffer_alloc((dev), (size), (dma), MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_free(dev, size, addr, dma) dbg_rtw_usb_buffer_free((dev), (size), (addr), (dma), MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_alloc_f(dev, size, dma, mstat_f) dbg_rtw_usb_buffer_alloc((dev), (size), (dma), ((mstat_f)&0xff00)|MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#define rtw_usb_buffer_free_f(dev, size, addr, dma, mstat_f) dbg_rtw_usb_buffer_free((dev), (size), (addr), (dma), ((mstat_f)&0xff00)|MSTAT_TYPE_USB, __FUNCTION__, __LINE__) +#endif /* CONFIG_USB_HCI */ + +#else /* DBG_MEM_ALLOC */ +#define rtw_mstat_update(flag, status, sz) do {} while(0) +#define rtw_mstat_dump(sel) do {} while(0) +u8* _rtw_vmalloc(u32 sz); +u8* _rtw_zvmalloc(u32 sz); +void _rtw_vmfree(u8 *pbuf, u32 sz); +u8* _rtw_zmalloc(u32 sz); +u8* _rtw_malloc(u32 sz); +void _rtw_mfree(u8 *pbuf, u32 sz); + +struct sk_buff *_rtw_skb_alloc(u32 sz); +void _rtw_skb_free(struct sk_buff *skb); +struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb); +struct sk_buff *_rtw_skb_clone(struct sk_buff *skb); +int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb); +void _rtw_skb_queue_purge(struct sk_buff_head *list); + +#ifdef CONFIG_USB_HCI +void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma); +void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma); +#endif /* CONFIG_USB_HCI */ + +#ifdef CONFIG_USE_VMALLOC +#define rtw_vmalloc(sz) _rtw_vmalloc((sz)) +#define rtw_zvmalloc(sz) _rtw_zvmalloc((sz)) +#define rtw_vmfree(pbuf, sz) _rtw_vmfree((pbuf), (sz)) +#define rtw_vmalloc_f(sz, mstat_f) _rtw_vmalloc((sz)) +#define rtw_zvmalloc_f(sz, mstat_f) _rtw_zvmalloc((sz)) +#define rtw_vmfree_f(pbuf, sz, mstat_f) _rtw_vmfree((pbuf), (sz)) +#else /* CONFIG_USE_VMALLOC */ +#define rtw_vmalloc(sz) _rtw_malloc((sz)) +#define rtw_zvmalloc(sz) _rtw_zmalloc((sz)) +#define rtw_vmfree(pbuf, sz) _rtw_mfree((pbuf), (sz)) +#define rtw_vmalloc_f(sz, mstat_f) _rtw_malloc((sz)) +#define rtw_zvmalloc_f(sz, mstat_f) _rtw_zmalloc((sz)) +#define rtw_vmfree_f(pbuf, sz, mstat_f) _rtw_mfree((pbuf), (sz)) +#endif /* CONFIG_USE_VMALLOC */ +#define rtw_malloc(sz) _rtw_malloc((sz)) +#define rtw_zmalloc(sz) _rtw_zmalloc((sz)) +#define rtw_mfree(pbuf, sz) _rtw_mfree((pbuf), (sz)) +#define rtw_malloc_f(sz, mstat_f) _rtw_malloc((sz)) +#define rtw_zmalloc_f(sz, mstat_f) _rtw_zmalloc((sz)) +#define rtw_mfree_f(pbuf, sz, mstat_f) _rtw_mfree((pbuf), (sz)) + +#define rtw_skb_alloc(size) _rtw_skb_alloc((size)) +#define rtw_skb_free(skb) _rtw_skb_free((skb)) +#define rtw_skb_alloc_f(size, mstat_f) _rtw_skb_alloc((size)) +#define rtw_skb_free_f(skb, mstat_f) _rtw_skb_free((skb)) +#define rtw_skb_copy(skb) _rtw_skb_copy((skb)) +#define rtw_skb_clone(skb) _rtw_skb_clone((skb)) +#define rtw_skb_copy_f(skb, mstat_f) _rtw_skb_copy((skb)) +#define rtw_skb_clone_f(skb, mstat_f) _rtw_skb_clone((skb)) +#define rtw_netif_rx(ndev, skb) _rtw_netif_rx(ndev, skb) +#define rtw_skb_queue_purge(sk_buff_head) _rtw_skb_queue_purge(sk_buff_head) +#ifdef CONFIG_USB_HCI +#define rtw_usb_buffer_alloc(dev, size, dma) _rtw_usb_buffer_alloc((dev), (size), (dma)) +#define rtw_usb_buffer_free(dev, size, addr, dma) _rtw_usb_buffer_free((dev), (size), (addr), (dma)) +#define rtw_usb_buffer_alloc_f(dev, size, dma, mstat_f) _rtw_usb_buffer_alloc((dev), (size), (dma)) +#define rtw_usb_buffer_free_f(dev, size, addr, dma, mstat_f) _rtw_usb_buffer_free((dev), (size), (addr), (dma)) +#endif /* CONFIG_USB_HCI */ +#endif /* DBG_MEM_ALLOC */ + +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, const void *sour, u32 sz); +extern void _rtw_memmove(void *dst, const void *src, u32 sz); +extern int _rtw_memcmp(void *dst, void *src, u32 sz); +extern void _rtw_memset(void *pbuf, int c, u32 sz); + +extern void _rtw_init_listhead(_list *list); +extern u32 rtw_is_list_empty(_list *phead); +extern void rtw_list_insert_head(_list *plist, _list *phead); +extern void rtw_list_insert_tail(_list *plist, _list *phead); +#ifndef PLATFORM_FREEBSD +extern void rtw_list_delete(_list *plist); +#endif //PLATFORM_FREEBSD + +extern void _rtw_init_sema(_sema *sema, int init_val); +extern void _rtw_free_sema(_sema *sema); +extern void _rtw_up_sema(_sema *sema); +extern u32 _rtw_down_sema(_sema *sema); +extern void _rtw_mutex_init(_mutex *pmutex); +extern void _rtw_mutex_free(_mutex *pmutex); +#ifndef PLATFORM_FREEBSD +extern void _rtw_spinlock_init(_lock *plock); +#endif //PLATFORM_FREEBSD +extern void _rtw_spinlock_free(_lock *plock); +extern void _rtw_spinlock(_lock *plock); +extern void _rtw_spinunlock(_lock *plock); +extern void _rtw_spinlock_ex(_lock *plock); +extern void _rtw_spinunlock_ex(_lock *plock); + +extern void _rtw_init_queue(_queue *pqueue); +extern void _rtw_deinit_queue(_queue *pqueue); +extern u32 _rtw_queue_empty(_queue *pqueue); +extern u32 rtw_end_of_queue_search(_list *queue, _list *pelement); + +extern u32 rtw_get_current_time(void); +extern u32 rtw_systime_to_ms(u32 systime); +extern u32 rtw_ms_to_systime(u32 ms); +extern s32 rtw_get_passing_time_ms(u32 start); +extern s32 rtw_get_time_interval_ms(u32 start, u32 end); + +extern void rtw_sleep_schedulable(int ms); + +extern void rtw_msleep_os(int ms); +extern void rtw_usleep_os(int us); + +extern u32 rtw_atoi(u8* s); + +#ifdef DBG_DELAY_OS +#define rtw_mdelay_os(ms) _rtw_mdelay_os((ms), __FUNCTION__, __LINE__) +#define rtw_udelay_os(ms) _rtw_udelay_os((ms), __FUNCTION__, __LINE__) +extern void _rtw_mdelay_os(int ms, const char *func, const int line); +extern void _rtw_udelay_os(int us, const char *func, const int line); +#else +extern void rtw_mdelay_os(int ms); +extern void rtw_udelay_os(int us); +#endif + +extern void rtw_yield_os(void); + + +extern void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc); + + +__inline static unsigned char _cancel_timer_ex(_timer *ptimer) +{ +#ifdef PLATFORM_LINUX + return del_timer_sync(ptimer); +#endif +#ifdef PLATFORM_FREEBSD + _cancel_timer(ptimer,0); + return 0; +#endif +#ifdef PLATFORM_WINDOWS + u8 bcancelled; + + _cancel_timer(ptimer, &bcancelled); + + return bcancelled; +#endif +} + +static __inline void thread_enter(char *name) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) + daemonize("%s", name); + #endif + allow_signal(SIGTERM); +#endif +#ifdef PLATFORM_FREEBSD + printf("%s", "RTKTHREAD_enter"); +#endif +} + +__inline static void flush_signals_thread(void) +{ +#ifdef PLATFORM_LINUX + if (signal_pending (current)) + { + flush_signals(current); + } +#endif +} + +__inline static _OS_STATUS res_to_status(sint res) +{ + +#if defined (PLATFORM_LINUX) || defined (PLATFORM_MPIXEL) || defined (PLATFORM_FREEBSD) + return res; +#endif + +#ifdef PLATFORM_WINDOWS + + if (res == _SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; + +#endif + +} + +__inline static void rtw_dump_stack(void) +{ +#ifdef PLATFORM_LINUX + dump_stack(); +#endif +} + +#ifdef PLATFORM_LINUX +#define rtw_warn_on(condition) WARN_ON(condition) +#else +#define rtw_warn_on(condition) do {} while (0) +#endif + +__inline static int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *parg4) +{ + int ret = _TRUE; + +#ifdef PLATFORM_WINDOWS + if ( ((uint)parg1) <= 0x7fffffff || + ((uint)parg2) <= 0x7fffffff || + ((uint)parg3) <= 0x7fffffff || + ((uint)parg4) <= 0x7fffffff) + { + ret = _FALSE; + KeBugCheckEx(0x87110000, (ULONG_PTR)parg1, (ULONG_PTR)parg2, (ULONG_PTR)parg3, (ULONG_PTR)parg4); + } +#endif + + return ret; + +} + +#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) +#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) + +__inline static u32 _RND4(u32 sz) +{ + + u32 val; + + val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; + + return val; + +} + +__inline static u32 _RND8(u32 sz) +{ + + u32 val; + + val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; + + return val; + +} + +__inline static u32 _RND128(u32 sz) +{ + + u32 val; + + val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; + + return val; + +} + +__inline static u32 _RND256(u32 sz) +{ + + u32 val; + + val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; + + return val; + +} + +__inline static u32 _RND512(u32 sz) +{ + + u32 val; + + val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; + + return val; + +} + +__inline static u32 bitshift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) + if (((bitmask>>i) & 0x1) == 1) break; + + return i; +} + +#define rtw_min(a, b) ((a>b)?b:a) +#define rtw_is_range_a_in_b(hi_a, lo_a, hi_b, lo_b) (((hi_a) <= (hi_b)) && ((lo_a) >= (lo_b))) +#define rtw_is_range_overlap(hi_a, lo_a, hi_b, lo_b) (((hi_a) > (lo_b)) && ((lo_a) < (hi_b))) + +#ifndef MAC_FMT +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#endif +#ifndef MAC_ARG +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] +#endif + + +extern void rtw_suspend_lock_init(void); +extern void rtw_suspend_lock_uninit(void); +extern void rtw_lock_suspend(void); +extern void rtw_unlock_suspend(void); +extern void rtw_lock_suspend_timeout(u32 timeout_ms); +extern void rtw_lock_ext_suspend_timeout(u32 timeout_ms); +extern void rtw_lock_rx_suspend_timeout(u32 timeout_ms); +extern void rtw_lock_traffic_suspend_timeout(u32 timeout_ms); +extern void rtw_lock_resume_scan_timeout(u32 timeout_ms); +extern void rtw_resume_lock_suspend(void); +extern void rtw_resume_unlock_suspend(void); +#ifdef CONFIG_AP_WOWLAN +extern void rtw_softap_lock_suspend(void); +extern void rtw_softap_unlock_suspend(void); +#endif + +extern void ATOMIC_SET(ATOMIC_T *v, int i); +extern int ATOMIC_READ(ATOMIC_T *v); +extern void ATOMIC_ADD(ATOMIC_T *v, int i); +extern void ATOMIC_SUB(ATOMIC_T *v, int i); +extern void ATOMIC_INC(ATOMIC_T *v); +extern void ATOMIC_DEC(ATOMIC_T *v); +extern int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i); +extern int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i); +extern int ATOMIC_INC_RETURN(ATOMIC_T *v); +extern int ATOMIC_DEC_RETURN(ATOMIC_T *v); + +//File operation APIs, just for linux now +extern int rtw_is_file_readable(char *path); +extern int rtw_retrieve_from_file(char *path, u8 *buf, u32 sz); +extern int rtw_store_to_file(char *path, u8* buf, u32 sz); + + +#ifndef PLATFORM_FREEBSD +extern void rtw_free_netdev(struct net_device * netdev); +#endif //PLATFORM_FREEBSD + + +extern u64 rtw_modular64(u64 x, u64 y); +extern u64 rtw_division64(u64 x, u64 y); +extern u32 rtw_random32(void); + +/* Macros for handling unaligned memory accesses */ + +#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) +#define RTW_PUT_BE16(a, val) \ + do { \ + (a)[0] = ((u16) (val)) >> 8; \ + (a)[1] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define RTW_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32) (a)[2])) +#define RTW_PUT_BE24(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[2] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) +#define RTW_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ + (((u32) (a)[1]) << 8) | ((u32) (a)[0])) +#define RTW_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ + (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ + (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ + (((u64) (a)[6]) << 8) | ((u64) (a)[7])) +#define RTW_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ + (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ + (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ + (((u64) (a)[1]) << 8) | ((u64) (a)[0])) + +void rtw_buf_free(u8 **buf, u32 *buf_len); +void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len); + +struct rtw_cbuf { + u32 write; + u32 read; + u32 size; + void *bufs[0]; +}; + +bool rtw_cbuf_full(struct rtw_cbuf *cbuf); +bool rtw_cbuf_empty(struct rtw_cbuf *cbuf); +bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf); +void *rtw_cbuf_pop(struct rtw_cbuf *cbuf); +struct rtw_cbuf *rtw_cbuf_alloc(u32 size); +void rtw_cbuf_free(struct rtw_cbuf *cbuf); + +// String handler + +BOOLEAN IsHexDigit(char chTmp); +BOOLEAN is_alpha(char chTmp); +char alpha_to_upper(char c); + +/* + * Write formatted output to sized buffer + */ +#ifdef PLATFORM_LINUX +#define rtw_sprintf(buf, size, format, arg...) snprintf(buf, size, format, ##arg) +#else // !PLATFORM_LINUX +#error "NOT DEFINE \"rtw_sprintf\"!!" +#endif // !PLATFORM_LINUX + +#endif + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_bsd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_bsd.h new file mode 100644 index 00000000..b56ccbb2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_bsd.h @@ -0,0 +1,749 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __OSDEP_BSD_SERVICE_H_ +#define __OSDEP_BSD_SERVICE_H_ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include "usbdevs.h" + +#define USB_DEBUG_VAR rum_debug +#include + +#if 1 //Baron porting from linux, it's all temp solution, needs to check again +#include +#include /* XXX for PCPU_GET */ +// typedef struct semaphore _sema; + typedef struct sema _sema; +// typedef spinlock_t _lock; + typedef struct mtx _lock; + typedef struct mtx _mutex; + typedef struct timer_list _timer; + struct list_head { + struct list_head *next, *prev; + }; + struct __queue { + struct list_head queue; + _lock lock; + }; + + //typedef struct sk_buff _pkt; + typedef struct mbuf _pkt; + typedef struct mbuf _buffer; + + typedef struct __queue _queue; + typedef struct list_head _list; + typedef int _OS_STATUS; + //typedef u32 _irqL; + typedef unsigned long _irqL; + typedef struct ifnet * _nic_hdl; + + typedef pid_t _thread_hdl_; +// typedef struct thread _thread_hdl_; + typedef void thread_return; + typedef void* thread_context; + + //#define thread_exit() complete_and_exit(NULL, 0) + + #define thread_exit() do{printf("%s", "RTKTHREAD_exit");}while(0) + + typedef void timer_hdl_return; + typedef void* timer_hdl_context; + typedef struct work_struct _workitem; + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +/* emulate a modern version */ +#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 35) + +#define WIRELESS_EXT -1 +#define HZ hz +#define spin_lock_irqsave mtx_lock_irqsave +#define spin_lock_bh mtx_lock_irqsave +#define mtx_lock_irqsave(lock, x) mtx_lock(lock)//{local_irq_save((x)); mtx_lock_spin((lock));} +//#define IFT_RTW 0xf9 //ifnet allocate type for RTW +#define free_netdev if_free +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n)) +/* + * Linux timers are emulated using FreeBSD callout functions + * (and taskqueue functionality). + * + * Currently no timer stats functionality. + * + * See (linux_compat) processes.c + * + */ +struct timer_list { + + /* FreeBSD callout related fields */ + struct callout callout; + + //timeout function + void (*function)(void*); + //argument + void *arg; + +}; +struct workqueue_struct; +struct work_struct; +typedef void (*work_func_t)(struct work_struct *work); +/* Values for the state of an item of work (work_struct) */ +typedef enum work_state { + WORK_STATE_UNSET = 0, + WORK_STATE_CALLOUT_PENDING = 1, + WORK_STATE_TASK_PENDING = 2, + WORK_STATE_WORK_CANCELLED = 3 +} work_state_t; + +struct work_struct { + struct task task; /* FreeBSD task */ + work_state_t state; /* the pending or otherwise state of work. */ + work_func_t func; +}; +#define spin_unlock_irqrestore mtx_unlock_irqrestore +#define spin_unlock_bh mtx_unlock_irqrestore +#define mtx_unlock_irqrestore(lock,x) mtx_unlock(lock); +extern void _rtw_spinlock_init(_lock *plock); + +//modify private structure to match freebsd +#define BITS_PER_LONG 32 +union ktime { + s64 tv64; +#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR) + struct { +#ifdef __BIG_ENDIAN + s32 sec, nsec; +#else + s32 nsec, sec; +#endif + } tv; +#endif +}; +#define kmemcheck_bitfield_begin(name) +#define kmemcheck_bitfield_end(name) +#define CHECKSUM_NONE 0 +typedef unsigned char *sk_buff_data_t; +typedef union ktime ktime_t; /* Kill this */ + +void rtw_mtx_lock(_lock *plock); + +void rtw_mtx_unlock(_lock *plock); + +/** + * struct sk_buff - socket buffer + * @next: Next buffer in list + * @prev: Previous buffer in list + * @sk: Socket we are owned by + * @tstamp: Time we arrived + * @dev: Device we arrived on/are leaving by + * @transport_header: Transport layer header + * @network_header: Network layer header + * @mac_header: Link layer header + * @_skb_refdst: destination entry (with norefcount bit) + * @sp: the security path, used for xfrm + * @cb: Control buffer. Free for use by every layer. Put private vars here + * @len: Length of actual data + * @data_len: Data length + * @mac_len: Length of link layer header + * @hdr_len: writable header length of cloned skb + * @csum: Checksum (must include start/offset pair) + * @csum_start: Offset from skb->head where checksumming should start + * @csum_offset: Offset from csum_start where checksum should be stored + * @local_df: allow local fragmentation + * @cloned: Head may be cloned (check refcnt to be sure) + * @nohdr: Payload reference only, must not modify header + * @pkt_type: Packet class + * @fclone: skbuff clone status + * @ip_summed: Driver fed us an IP checksum + * @priority: Packet queueing priority + * @users: User count - see {datagram,tcp}.c + * @protocol: Packet protocol from driver + * @truesize: Buffer size + * @head: Head of buffer + * @data: Data head pointer + * @tail: Tail pointer + * @end: End pointer + * @destructor: Destruct function + * @mark: Generic packet mark + * @nfct: Associated connection, if any + * @ipvs_property: skbuff is owned by ipvs + * @peeked: this packet has been seen already, so stats have been + * done for it, don't do them again + * @nf_trace: netfilter packet trace flag + * @nfctinfo: Relationship of this skb to the connection + * @nfct_reasm: netfilter conntrack re-assembly pointer + * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c + * @skb_iif: ifindex of device we arrived on + * @rxhash: the packet hash computed on receive + * @queue_mapping: Queue mapping for multiqueue devices + * @tc_index: Traffic control index + * @tc_verd: traffic control verdict + * @ndisc_nodetype: router type (from link layer) + * @dma_cookie: a cookie to one of several possible DMA operations + * done by skb DMA functions + * @secmark: security marking + * @vlan_tci: vlan tag control information + */ + +struct sk_buff { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + ktime_t tstamp; + + struct sock *sk; + //struct net_device *dev; + struct ifnet *dev; + + /* + * This is the control buffer. It is free to use for every + * layer. Please put your private variables there. If you + * want to keep them across layers you have to do a skb_clone() + * first. This is owned by whoever has the skb queued ATM. + */ + char cb[48] __aligned(8); + + unsigned long _skb_refdst; +#ifdef CONFIG_XFRM + struct sec_path *sp; +#endif + unsigned int len, + data_len; + u16 mac_len, + hdr_len; + union { + u32 csum; + struct { + u16 csum_start; + u16 csum_offset; + }smbol2; + }smbol1; + u32 priority; + kmemcheck_bitfield_begin(flags1); + u8 local_df:1, + cloned:1, + ip_summed:2, + nohdr:1, + nfctinfo:3; + u8 pkt_type:3, + fclone:2, + ipvs_property:1, + peeked:1, + nf_trace:1; + kmemcheck_bitfield_end(flags1); + u16 protocol; + + void (*destructor)(struct sk_buff *skb); +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + struct nf_conntrack *nfct; + struct sk_buff *nfct_reasm; +#endif +#ifdef CONFIG_BRIDGE_NETFILTER + struct nf_bridge_info *nf_bridge; +#endif + + int skb_iif; +#ifdef CONFIG_NET_SCHED + u16 tc_index; /* traffic control index */ +#ifdef CONFIG_NET_CLS_ACT + u16 tc_verd; /* traffic control verdict */ +#endif +#endif + + u32 rxhash; + + kmemcheck_bitfield_begin(flags2); + u16 queue_mapping:16; +#ifdef CONFIG_IPV6_NDISC_NODETYPE + u8 ndisc_nodetype:2, + deliver_no_wcard:1; +#else + u8 deliver_no_wcard:1; +#endif + kmemcheck_bitfield_end(flags2); + + /* 0/14 bit hole */ + +#ifdef CONFIG_NET_DMA + dma_cookie_t dma_cookie; +#endif +#ifdef CONFIG_NETWORK_SECMARK + u32 secmark; +#endif + union { + u32 mark; + u32 dropcount; + }symbol3; + + u16 vlan_tci; + + sk_buff_data_t transport_header; + sk_buff_data_t network_header; + sk_buff_data_t mac_header; + /* These elements must be at the end, see alloc_skb() for details. */ + sk_buff_data_t tail; + sk_buff_data_t end; + unsigned char *head, + *data; + unsigned int truesize; + atomic_t users; +}; +struct sk_buff_head { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + u32 qlen; + _lock lock; +}; +#define skb_tail_pointer(skb) skb->tail +static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len) +{ + unsigned char *tmp = skb_tail_pointer(skb); + //SKB_LINEAR_ASSERT(skb); + skb->tail += len; + skb->len += len; + return tmp; +} + +static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) +{ + skb->len -= len; + if(skb->len < skb->data_len) + printf("%s(),%d,error!\n",__FUNCTION__,__LINE__); + return skb->data += len; +} +static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) +{ + #ifdef PLATFORM_FREEBSD + return __skb_pull(skb, len); + #else + return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); + #endif //PLATFORM_FREEBSD +} +static inline u32 skb_queue_len(const struct sk_buff_head *list_) +{ + return list_->qlen; +} +static inline void __skb_insert(struct sk_buff *newsk, + struct sk_buff *prev, struct sk_buff *next, + struct sk_buff_head *list) +{ + newsk->next = next; + newsk->prev = prev; + next->prev = prev->next = newsk; + list->qlen++; +} +static inline void __skb_queue_before(struct sk_buff_head *list, + struct sk_buff *next, + struct sk_buff *newsk) +{ + __skb_insert(newsk, next->prev, next, list); +} +static inline void skb_queue_tail(struct sk_buff_head *list, + struct sk_buff *newsk) +{ + mtx_lock(&list->lock); + __skb_queue_before(list, (struct sk_buff *)list, newsk); + mtx_unlock(&list->lock); +} +static inline struct sk_buff *skb_peek(struct sk_buff_head *list_) +{ + struct sk_buff *list = ((struct sk_buff *)list_)->next; + if (list == (struct sk_buff *)list_) + list = NULL; + return list; +} +static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) +{ + struct sk_buff *next, *prev; + + list->qlen--; + next = skb->next; + prev = skb->prev; + skb->next = skb->prev = NULL; + next->prev = prev; + prev->next = next; +} + +static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list) +{ + mtx_lock(&list->lock); + + struct sk_buff *skb = skb_peek(list); + if (skb) + __skb_unlink(skb, list); + + mtx_unlock(&list->lock); + + return skb; +} +static inline void skb_reserve(struct sk_buff *skb, int len) +{ + skb->data += len; + skb->tail += len; +} +static inline void __skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = list->next = (struct sk_buff *)list; + list->qlen = 0; +} +/* + * This function creates a split out lock class for each invocation; + * this is needed for now since a whole lot of users of the skb-queue + * infrastructure in drivers have different locking usage (in hardirq) + * than the networking core (in softirq only). In the long run either the + * network layer or drivers should need annotation to consolidate the + * main types of usage into 3 classes. + */ +static inline void skb_queue_head_init(struct sk_buff_head *list) +{ + _rtw_spinlock_init(&list->lock); + __skb_queue_head_init(list); +} +unsigned long copy_from_user(void *to, const void *from, unsigned long n); +unsigned long copy_to_user(void *to, const void *from, unsigned long n); +struct sk_buff * dev_alloc_skb(unsigned int size); +struct sk_buff *skb_clone(const struct sk_buff *skb); +void dev_kfree_skb_any(struct sk_buff *skb); +#endif //Baron porting from linux, it's all temp solution, needs to check again + + +#if 1 // kenny add Linux compatibility code for Linux USB driver +#include + +#define __init // __attribute ((constructor)) +#define __exit // __attribute ((destructor)) + +/* + * Definitions for module_init and module_exit macros. + * + * These macros will use the SYSINIT framework to call a specified + * function (with no arguments) on module loading or unloading. + * + */ + +void module_init_exit_wrapper(void *arg); + +#define module_init(initfn) \ + SYSINIT(mod_init_ ## initfn, \ + SI_SUB_KLD, SI_ORDER_FIRST, \ + module_init_exit_wrapper, initfn) + +#define module_exit(exitfn) \ + SYSUNINIT(mod_exit_ ## exitfn, \ + SI_SUB_KLD, SI_ORDER_ANY, \ + module_init_exit_wrapper, exitfn) + +/* + * The usb_register and usb_deregister functions are used to register + * usb drivers with the usb subsystem. + */ +int usb_register(struct usb_driver *driver); +int usb_deregister(struct usb_driver *driver); + +/* + * usb_get_dev and usb_put_dev - increment/decrement the reference count + * of the usb device structure. + * + * Original body of usb_get_dev: + * + * if (dev) + * get_device(&dev->dev); + * return dev; + * + * Reference counts are not currently used in this compatibility + * layer. So these functions will do nothing. + */ +static inline struct usb_device * +usb_get_dev(struct usb_device *dev) +{ + return dev; +} + +static inline void +usb_put_dev(struct usb_device *dev) +{ + return; +} + + +// rtw_usb_compat_linux +int rtw_usb_submit_urb(struct urb *urb, uint16_t mem_flags); +int rtw_usb_unlink_urb(struct urb *urb); +int rtw_usb_clear_halt(struct usb_device *dev, struct usb_host_endpoint *uhe); +int rtw_usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *uhe, + uint8_t request, uint8_t requesttype, + uint16_t value, uint16_t index, void *data, + uint16_t size, usb_timeout_t timeout); +int rtw_usb_set_interface(struct usb_device *dev, uint8_t iface_no, uint8_t alt_index); +int rtw_usb_setup_endpoint(struct usb_device *dev, + struct usb_host_endpoint *uhe, usb_size_t bufsize); +struct urb *rtw_usb_alloc_urb(uint16_t iso_packets, uint16_t mem_flags); +struct usb_host_endpoint *rtw_usb_find_host_endpoint(struct usb_device *dev, uint8_t type, uint8_t ep); +struct usb_host_interface *rtw_usb_altnum_to_altsetting(const struct usb_interface *intf, uint8_t alt_index); +struct usb_interface *rtw_usb_ifnum_to_if(struct usb_device *dev, uint8_t iface_no); +void *rtw_usbd_get_intfdata(struct usb_interface *intf); +void rtw_usb_linux_register(void *arg); +void rtw_usb_linux_deregister(void *arg); +void rtw_usb_linux_free_device(struct usb_device *dev); +void rtw_usb_free_urb(struct urb *urb); +void rtw_usb_init_urb(struct urb *urb); +void rtw_usb_kill_urb(struct urb *urb); +void rtw_usb_set_intfdata(struct usb_interface *intf, void *data); +void rtw_usb_fill_bulk_urb(struct urb *urb, struct usb_device *udev, + struct usb_host_endpoint *uhe, void *buf, + int length, usb_complete_t callback, void *arg); +int rtw_usb_bulk_msg(struct usb_device *udev, struct usb_host_endpoint *uhe, + void *data, int len, uint16_t *pactlen, usb_timeout_t timeout); +void *usb_get_intfdata(struct usb_interface *intf); +int usb_linux_init_endpoints(struct usb_device *udev); + + + +typedef struct urb * PURB; + +typedef unsigned gfp_t; +#define __GFP_WAIT ((gfp_t)0x10u) /* Can wait and reschedule? */ +#define __GFP_HIGH ((gfp_t)0x20u) /* Should access emergency pools? */ +#define __GFP_IO ((gfp_t)0x40u) /* Can start physical IO? */ +#define __GFP_FS ((gfp_t)0x80u) /* Can call down to low-level FS? */ +#define __GFP_COLD ((gfp_t)0x100u) /* Cache-cold page required */ +#define __GFP_NOWARN ((gfp_t)0x200u) /* Suppress page allocation failure warning */ +#define __GFP_REPEAT ((gfp_t)0x400u) /* Retry the allocation. Might fail */ +#define __GFP_NOFAIL ((gfp_t)0x800u) /* Retry for ever. Cannot fail */ +#define __GFP_NORETRY ((gfp_t)0x1000u)/* Do not retry. Might fail */ +#define __GFP_NO_GROW ((gfp_t)0x2000u)/* Slab internal usage */ +#define __GFP_COMP ((gfp_t)0x4000u)/* Add compound page metadata */ +#define __GFP_ZERO ((gfp_t)0x8000u)/* Return zeroed page on success */ +#define __GFP_NOMEMALLOC ((gfp_t)0x10000u) /* Don't use emergency reserves */ +#define __GFP_HARDWALL ((gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ + +/* This equals 0, but use constants in case they ever change */ +#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) +/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */ +#define GFP_ATOMIC (__GFP_HIGH) +#define GFP_NOIO (__GFP_WAIT) +#define GFP_NOFS (__GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL) +#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ + __GFP_HIGHMEM) + + +#endif // kenny add Linux compatibility code for Linux USB + +__inline static _list *get_next(_list *list) +{ + return list->next; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) + + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_lock_bh(plock, *pirqL); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_unlock_bh(plock, *pirqL); +} + +__inline static void _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + + mtx_lock(pmutex); + +} + + +__inline static void _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + + mtx_unlock(pmutex); + +} +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} +__inline static void rtw_list_delete(_list *plist) +{ + __list_del(plist->prev, plist->next); + INIT_LIST_HEAD(plist); +} + +__inline static void _init_timer(_timer *ptimer,_nic_hdl padapter,void *pfunc,void* cntx) +{ + ptimer->function = pfunc; + ptimer->arg = cntx; + callout_init(&ptimer->callout, CALLOUT_MPSAFE); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + // mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); + if(ptimer->function && ptimer->arg){ + rtw_mtx_lock(NULL); + callout_reset(&ptimer->callout, delay_time,ptimer->function, ptimer->arg); + rtw_mtx_unlock(NULL); + } +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + // del_timer_sync(ptimer); + // *bcancelled= _TRUE;//TRUE ==1; FALSE==0 + rtw_mtx_lock(NULL); + callout_drain(&ptimer->callout); + rtw_mtx_unlock(NULL); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + printf("%s Not implement yet! \n",__FUNCTION__); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + printf("%s Not implement yet! \n",__FUNCTION__); +// schedule_work(pwork); +} + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ +} + +#define ATOMIC_INIT(i) { (i) } + +static __inline void thread_enter(char *name); + +//Atomic integer operations +typedef uint32_t ATOMIC_T ; + +#define rtw_netdev_priv(netdev) (((struct ifnet *)netdev)->if_softc) + +#define rtw_free_netdev(netdev) if_free((netdev)) + +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) "" +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) "" +#define FUNC_NDEV_FMT "%s" +#define FUNC_NDEV_ARG(ndev) __func__ +#define FUNC_ADPT_FMT "%s" +#define FUNC_ADPT_ARG(adapter) __func__ + +#define STRUCT_PACKED + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_ce.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_ce.h new file mode 100644 index 00000000..04c5b188 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_ce.h @@ -0,0 +1,192 @@ +/****************************************************************************** + * + * 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 __OSDEP_CE_SERVICE_H_ +#define __OSDEP_CE_SERVICE_H_ + + +#include +#include + +#ifdef CONFIG_SDIO_HCI +#include "SDCardDDK.h" +#endif + +#ifdef CONFIG_USB_HCI +#include +#endif + +typedef HANDLE _sema; +typedef LIST_ENTRY _list; +typedef NDIS_STATUS _OS_STATUS; + +typedef NDIS_SPIN_LOCK _lock; + +typedef HANDLE _rwlock; //Mutex + +typedef u32 _irqL; + +typedef NDIS_HANDLE _nic_hdl; + + +typedef NDIS_MINIPORT_TIMER _timer; + +struct __queue { + LIST_ENTRY queue; + _lock lock; +}; + +typedef NDIS_PACKET _pkt; +typedef NDIS_BUFFER _buffer; +typedef struct __queue _queue; + +typedef HANDLE _thread_hdl_; +typedef DWORD thread_return; +typedef void* thread_context; +typedef NDIS_WORK_ITEM _workitem; + +#define thread_exit() ExitThread(STATUS_SUCCESS); return 0; + + +#define SEMA_UPBND (0x7FFFFFFF) //8192 + +__inline static _list *get_prev(_list *list) +{ + return list->Blink; +} + +__inline static _list *get_next(_list *list) +{ + return list->Flink; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + +#define LIST_CONTAINOR(ptr, type, member) CONTAINING_RECORD(ptr, type, member) + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + NdisAcquireSpinLock(plock); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + NdisReleaseSpinLock(plock); +} + +__inline static _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + + +__inline static void _enter_hwio_critical(_rwlock *prwlock, _irqL *pirqL) +{ + WaitForSingleObject(*prwlock, INFINITE ); + +} + +__inline static void _exit_hwio_critical(_rwlock *prwlock, _irqL *pirqL) +{ + ReleaseMutex(*prwlock); +} + +__inline static void rtw_list_delete(_list *plist) +{ + RemoveEntryList(plist); + InitializeListHead(plist); +} + +#define RTW_TIMER_HDL_ARGS IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3 + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,PVOID cntx) +{ + NdisMInitializeTimer(ptimer, nic_hdl, pfunc, cntx); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + NdisMSetTimer(ptimer,delay_time); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + NdisMCancelTimer(ptimer,bcancelled); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + + NdisInitializeWorkItem(pwork, pfunc, cntx); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + NdisScheduleWorkItem(pwork); +} + +#define ATOMIC_INIT(i) { (i) } + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (NdisInterlockedIncrement((PULONG)&(_MutexCounter)) != 1)\ + { \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ + NdisMSleep(10000); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ +} + +// limitation of path length +#define PATH_LENGTH_MAX MAX_PATH + +//Atomic integer operations +#define ATOMIC_T LONG + +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) "" +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) "" +#define FUNC_NDEV_FMT "%s" +#define FUNC_NDEV_ARG(ndev) __func__ +#define FUNC_ADPT_FMT "%s" +#define FUNC_ADPT_ARG(adapter) __func__ + +#define STRUCT_PACKED + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_linux.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_linux.h new file mode 100644 index 00000000..a4926e60 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_linux.h @@ -0,0 +1,425 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __OSDEP_LINUX_SERVICE_H_ +#define __OSDEP_LINUX_SERVICE_H_ + + #include + #include + #include + #include + #include + #include + #include + #include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5)) + #include +#endif + //#include + #include + #include + #include + #include + #include + #include + #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + #include +#else + #include +#endif + #include + #include + #include + #include + #include + #include + #include + #include + #include // for struct tasklet_struct + #include + #include + #include + #include + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41)) + #include +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) + #include +#else + #include +#endif + +#ifdef RTK_DMP_PLATFORM +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + #include +#endif + #include +#endif + +#ifdef CONFIG_NET_RADIO + #define CONFIG_WIRELESS_EXT +#endif + + /* Monitor mode */ + #include + #include +#ifdef CONFIG_IOCTL_CFG80211 +/* #include */ + #include +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + #include + #include +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND + #include +#endif //CONFIG_HAS_EARLYSUSPEND + +#ifdef CONFIG_EFUSE_CONFIG_FILE + #include +#endif + +#ifdef CONFIG_USB_HCI + #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + #include +#else + #include +#endif +#endif + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + #include + #include + #include + #include + #include +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + +#ifdef CONFIG_USB_HCI + typedef struct urb * PURB; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22)) +#ifdef CONFIG_USB_SUSPEND +#define CONFIG_AUTOSUSPEND 1 +#endif +#endif +#endif + + typedef struct semaphore _sema; + typedef spinlock_t _lock; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + typedef struct mutex _mutex; +#else + typedef struct semaphore _mutex; +#endif + typedef struct timer_list _timer; + + struct __queue { + struct list_head queue; + _lock lock; + }; + + typedef struct sk_buff _pkt; + typedef unsigned char _buffer; + + typedef struct __queue _queue; + typedef struct list_head _list; + typedef int _OS_STATUS; + //typedef u32 _irqL; + typedef unsigned long _irqL; + typedef struct net_device * _nic_hdl; + + typedef void* _thread_hdl_; + typedef int thread_return; + typedef void* thread_context; + + #define thread_exit() complete_and_exit(NULL, 0) + + typedef void timer_hdl_return; + typedef void* timer_hdl_context; + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) + typedef struct work_struct _workitem; +#else + typedef struct tq_struct _workitem; +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) +// Porting from linux kernel, for compatible with old kernel. +static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->tail; +} + +static inline void skb_reset_tail_pointer(struct sk_buff *skb) +{ + skb->tail = skb->data; +} + +static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) +{ + skb->tail = skb->data + offset; +} + +static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) +{ + return skb->end; +} +#endif + +__inline static _list *get_next(_list *list) +{ + return list->next; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) + + +__inline static void _enter_critical(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_lock_irqsave(plock, *pirqL); +} + +__inline static void _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + spin_unlock_irqrestore(plock, *pirqL); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_lock_bh(plock); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + spin_unlock_bh(plock); +} + +__inline static int _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + int ret = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + //mutex_lock(pmutex); + ret = mutex_lock_interruptible(pmutex); +#else + ret = down_interruptible(pmutex); +#endif + return ret; +} + + +__inline static void _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_unlock(pmutex); +#else + up(pmutex); +#endif +} + +__inline static void rtw_list_delete(_list *plist) +{ + list_del_init(plist); +} + +#define RTW_TIMER_HDL_ARGS void *FunctionContext + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,void* cntx) +{ + //setup_timer(ptimer, pfunc,(u32)cntx); + ptimer->function = pfunc; + ptimer->data = (unsigned long)cntx; + init_timer(ptimer); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + mod_timer(ptimer , (jiffies+(delay_time*HZ/1000))); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + del_timer_sync(ptimer); + *bcancelled = 1; +} + + +static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + INIT_WORK(pwork, pfunc); +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) + INIT_WORK(pwork, pfunc,pwork); +#else + INIT_TQUEUE(pwork, pfunc,pwork); +#endif +} + +__inline static void _set_workitem(_workitem *pwork) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) + schedule_work(pwork); +#else + schedule_task(pwork); +#endif +} + +__inline static void _cancel_workitem_sync(_workitem *pwork) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22)) + cancel_work_sync(pwork); +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) + flush_scheduled_work(); +#else + flush_scheduled_tasks(); +#endif +} +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (atomic_inc_return((atomic_t *)&(_MutexCounter)) != 1)\ + { \ + atomic_dec((atomic_t *)&(_MutexCounter)); \ + msleep(10); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + atomic_dec((atomic_t *)&(_MutexCounter)); \ +} + +static inline int rtw_netif_queue_stopped(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + return (netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) && + netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)) ); +#else + return netif_queue_stopped(pnetdev); +#endif +} + +static inline void rtw_netif_wake_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_wake_all_queues(pnetdev); +#else + netif_wake_queue(pnetdev); +#endif +} + +static inline void rtw_netif_start_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_start_all_queues(pnetdev); +#else + netif_start_queue(pnetdev); +#endif +} + +static inline void rtw_netif_stop_queue(struct net_device *pnetdev) +{ +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + netif_tx_stop_all_queues(pnetdev); +#else + netif_stop_queue(pnetdev); +#endif +} + +static inline void rtw_merge_string(char *dst, int dst_len, const char *src1, const char *src2) +{ + int len = 0; + len += snprintf(dst+len, dst_len - len, "%s", src1); + len += snprintf(dst+len, dst_len - len, "%s", src2); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)),(sig), 1) +#else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) +#define rtw_signal_process(pid, sig) kill_proc((pid), (sig), 1) +#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + + +// Suspend lock prevent system from going suspend +#ifdef CONFIG_WAKELOCK +#include +#elif defined(CONFIG_ANDROID_POWER) +#include +#endif + +// limitation of path length +#define PATH_LENGTH_MAX PATH_MAX + +//Atomic integer operations +#define ATOMIC_T atomic_t + +#define rtw_netdev_priv(netdev) ( ((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv ) + +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) ndev->name +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) adapter->pnetdev->name +#define FUNC_NDEV_FMT "%s(%s)" +#define FUNC_NDEV_ARG(ndev) __func__, ndev->name +#define FUNC_ADPT_FMT "%s(%s)" +#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name + +struct rtw_netdev_priv_indicator { + void *priv; + u32 sizeof_priv; +}; +struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); +extern struct net_device * rtw_alloc_etherdev(int sizeof_priv); + +#define STRUCT_PACKED __attribute__ ((packed)) + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_xp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_xp.h new file mode 100644 index 00000000..45d54af1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/osdep_service_xp.h @@ -0,0 +1,202 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __OSDEP_LINUX_SERVICE_H_ +#define __OSDEP_LINUX_SERVICE_H_ + + #include + #include + #include + #include + +#ifdef CONFIG_USB_HCI + #include + #include + #include +#endif + + typedef KSEMAPHORE _sema; + typedef LIST_ENTRY _list; + typedef NDIS_STATUS _OS_STATUS; + + + typedef NDIS_SPIN_LOCK _lock; + + typedef KMUTEX _mutex; + + typedef KIRQL _irqL; + + // USB_PIPE for WINCE , but handle can be use just integer under windows + typedef NDIS_HANDLE _nic_hdl; + + + typedef NDIS_MINIPORT_TIMER _timer; + + struct __queue { + LIST_ENTRY queue; + _lock lock; + }; + + typedef NDIS_PACKET _pkt; + typedef NDIS_BUFFER _buffer; + typedef struct __queue _queue; + + typedef PKTHREAD _thread_hdl_; + typedef void thread_return; + typedef void* thread_context; + + typedef NDIS_WORK_ITEM _workitem; + + #define thread_exit() PsTerminateSystemThread(STATUS_SUCCESS); + + #define HZ 10000000 + #define SEMA_UPBND (0x7FFFFFFF) //8192 + +__inline static _list *get_next(_list *list) +{ + return list->Flink; +} + +__inline static _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + + +#define LIST_CONTAINOR(ptr, type, member) CONTAINING_RECORD(ptr, type, member) + + +__inline static _enter_critical(_lock *plock, _irqL *pirqL) +{ + NdisAcquireSpinLock(plock); +} + +__inline static _exit_critical(_lock *plock, _irqL *pirqL) +{ + NdisReleaseSpinLock(plock); +} + + +__inline static _enter_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static _exit_critical_ex(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + +__inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL) +{ + NdisDprAcquireSpinLock(plock); +} + +__inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL) +{ + NdisDprReleaseSpinLock(plock); +} + +__inline static _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + KeWaitForSingleObject(pmutex, Executive, KernelMode, FALSE, NULL); +} + + +__inline static _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + KeReleaseMutex(pmutex, FALSE); +} + + +__inline static void rtw_list_delete(_list *plist) +{ + RemoveEntryList(plist); + InitializeListHead(plist); +} + +#define RTW_TIMER_HDL_ARGS IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3 + +__inline static void _init_timer(_timer *ptimer,_nic_hdl nic_hdl,void *pfunc,PVOID cntx) +{ + NdisMInitializeTimer(ptimer, nic_hdl, pfunc, cntx); +} + +__inline static void _set_timer(_timer *ptimer,u32 delay_time) +{ + NdisMSetTimer(ptimer,delay_time); +} + +__inline static void _cancel_timer(_timer *ptimer,u8 *bcancelled) +{ + NdisMCancelTimer(ptimer,bcancelled); +} + +__inline static void _init_workitem(_workitem *pwork, void *pfunc, PVOID cntx) +{ + + NdisInitializeWorkItem(pwork, pfunc, cntx); +} + +__inline static void _set_workitem(_workitem *pwork) +{ + NdisScheduleWorkItem(pwork); +} + + +#define ATOMIC_INIT(i) { (i) } + +// +// Global Mutex: can only be used at PASSIVE level. +// + +#define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + while (NdisInterlockedIncrement((PULONG)&(_MutexCounter)) != 1)\ + { \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ + NdisMSleep(10000); \ + } \ +} + +#define RELEASE_GLOBAL_MUTEX(_MutexCounter) \ +{ \ + NdisInterlockedDecrement((PULONG)&(_MutexCounter)); \ +} + +// limitation of path length +#define PATH_LENGTH_MAX MAX_PATH + +//Atomic integer operations +#define ATOMIC_T LONG + + +#define NDEV_FMT "%s" +#define NDEV_ARG(ndev) "" +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) "" +#define FUNC_NDEV_FMT "%s" +#define FUNC_NDEV_ARG(ndev) __func__ +#define FUNC_ADPT_FMT "%s" +#define FUNC_ADPT_ARG(adapter) __func__ + +#define STRUCT_PACKED + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_hal.h new file mode 100644 index 00000000..00157707 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_hal.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * 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 __PCI_HAL_H__ +#define __PCI_HAL_H__ + +#ifdef CONFIG_RTL8188E +void rtl8188ee_set_hal_ops(_adapter *padapter); +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +void rtl8812ae_set_hal_ops(_adapter *padapter); +#endif + +#if defined(CONFIG_RTL8192E) +void rtl8192ee_set_hal_ops(_adapter *padapter); +#endif + +#ifdef CONFIG_RTL8723B +void rtl8723be_set_hal_ops(_adapter *padapter); +#endif + +#ifdef CONFIG_RTL8814A +void rtl8814ae_set_hal_ops(_adapter *padapter); +#endif + +u8 rtw_set_hal_ops(_adapter *padapter); + +#endif //__PCIE_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_ops.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_ops.h new file mode 100644 index 00000000..07add168 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_ops.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * + * 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 __PCI_OPS_H_ +#define __PCI_OPS_H_ + + +#ifdef CONFIG_RTL8188E +u32 rtl8188ee_init_desc_ring(_adapter *padapter); +u32 rtl8188ee_free_desc_ring(_adapter *padapter); +void rtl8188ee_reset_desc_ring(_adapter *padapter); +int rtl8188ee_interrupt(PADAPTER Adapter); +void rtl8188ee_xmit_tasklet(void *priv); +void rtl8188ee_recv_tasklet(void *priv); +void rtl8188ee_prepare_bcn_tasklet(void *priv); +void rtl8188ee_set_intf_ops(struct _io_ops *pops); +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +u32 rtl8812ae_init_desc_ring(_adapter *padapter); +u32 rtl8812ae_free_desc_ring(_adapter *padapter); +void rtl8812ae_reset_desc_ring(_adapter *padapter); +int rtl8812ae_interrupt(PADAPTER Adapter); +void rtl8812ae_xmit_tasklet(void *priv); +void rtl8812ae_recv_tasklet(void *priv); +void rtl8812ae_prepare_bcn_tasklet(void *priv); +void rtl8812ae_set_intf_ops(struct _io_ops *pops); +#endif + +#ifdef CONFIG_RTL8192E +u32 rtl8192ee_init_desc_ring(_adapter *padapter); +u32 rtl8192ee_free_desc_ring(_adapter *padapter); +void rtl8192ee_reset_desc_ring(_adapter *padapter); +void rtl8192ee_recv_tasklet(void *priv); +void rtl8192ee_prepare_bcn_tasklet(void *priv); +int rtl8192ee_interrupt(PADAPTER Adapter); +void rtl8192ee_set_intf_ops(struct _io_ops *pops); +#endif + +#ifdef CONFIG_RTL8723B +u32 rtl8723be_init_desc_ring(_adapter *padapter); +u32 rtl8723be_free_desc_ring(_adapter *padapter); +void rtl8723be_reset_desc_ring(_adapter *padapter); +int rtl8723be_interrupt(PADAPTER Adapter); +void rtl8723be_recv_tasklet(void *priv); +void rtl8723be_prepare_bcn_tasklet(void *priv); +void rtl8723be_set_intf_ops(struct _io_ops *pops); +#endif + +#ifdef CONFIG_RTL8814A +u32 rtl8814ae_init_desc_ring(_adapter *padapter); +u32 rtl8814ae_free_desc_ring(_adapter *padapter); +void rtl8814ae_reset_desc_ring(_adapter *padapter); +int rtl8814ae_interrupt(PADAPTER Adapter); +void rtl8814ae_xmit_tasklet(void *priv); +void rtl8814ae_recv_tasklet(void *priv); +void rtl8814ae_prepare_bcn_tasklet(void *priv); +void rtl8814ae_set_intf_ops(struct _io_ops *pops); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_osintf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_osintf.h new file mode 100644 index 00000000..9df50f73 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/pci_osintf.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 __PCI_OSINTF_H +#define __PCI_OSINTF_H + + +void rtw_pci_disable_aspm(_adapter *padapter); +void rtw_pci_enable_aspm(_adapter *padapter); +void PlatformClearPciPMEStatus(PADAPTER Adapter); +#ifdef CONFIG_64BIT_DMA +u8 PlatformEnableDMA64(PADAPTER Adapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/recv_osdep.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/recv_osdep.h new file mode 100644 index 00000000..0a65313f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/recv_osdep.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * 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 __RECV_OSDEP_H_ +#define __RECV_OSDEP_H_ + + +extern sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +extern void _rtw_free_recv_priv (struct recv_priv *precvpriv); + + +extern s32 rtw_recv_entry(union recv_frame *precv_frame); +extern int rtw_recv_indicatepkt(_adapter *adapter, union recv_frame *precv_frame); +extern void rtw_recv_returnpacket(IN _nic_hdl cnxt, IN _pkt *preturnedpkt); + +extern int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame); + +extern void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame); + +struct sta_info; +extern void rtw_handle_tkip_mic_err(_adapter *padapter, struct sta_info *sta, u8 bgroup); + + +int rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +void rtw_free_recv_priv (struct recv_priv *precvpriv); + + +int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter); +int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe); +void rtw_os_recv_resource_free(struct recv_priv *precvpriv); + + +int rtw_os_alloc_recvframe(_adapter *padapter, union recv_frame *precvframe, u8 *pdata, _pkt *pskb); +void rtw_os_free_recvframe(union recv_frame *precvframe); + + +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); + +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata); +void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib); + +void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf); + +void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); + + +#endif // + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_cmd.h new file mode 100644 index 00000000..76e426d5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_cmd.h @@ -0,0 +1,186 @@ +/****************************************************************************** + * + * 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 __RTL8188E_CMD_H__ +#define __RTL8188E_CMD_H__ + +#if 0 +enum cmd_msg_element_id +{ + NONE_CMDMSG_EID, + AP_OFFLOAD_EID = 0, + SET_PWRMODE_EID = 1, + JOINBSS_RPT_EID = 2, + RSVD_PAGE_EID = 3, + RSSI_4_EID = 4, + RSSI_SETTING_EID = 5, + MACID_CONFIG_EID = 6, + MACID_PS_MODE_EID = 7, + P2P_PS_OFFLOAD_EID = 8, + SELECTIVE_SUSPEND_ROF_CMD = 9, + P2P_PS_CTW_CMD_EID = 32, + MAX_CMDMSG_EID +}; +#else +typedef enum _RTL8188E_H2C_CMD_ID +{ + //Class Common + H2C_COM_RSVD_PAGE =0x00, + H2C_COM_MEDIA_STATUS_RPT =0x01, + H2C_COM_SCAN =0x02, + H2C_COM_KEEP_ALIVE =0x03, + H2C_COM_DISCNT_DECISION =0x04, +#ifndef CONFIG_WOWLAN + H2C_COM_WWLAN =0x05, +#endif + H2C_COM_INIT_OFFLOAD =0x06, + H2C_COM_REMOTE_WAKE_CTL =0x07, + H2C_COM_AP_OFFLOAD =0x08, + H2C_COM_BCN_RSVD_PAGE =0x09, + H2C_COM_PROB_RSP_RSVD_PAGE =0x0A, + + //Class PS + H2C_PS_PWR_MODE =0x20, + H2C_PS_TUNE_PARA =0x21, + H2C_PS_TUNE_PARA_2 =0x22, + H2C_PS_LPS_PARA =0x23, + H2C_PS_P2P_OFFLOAD =0x24, + + //Class DM + H2C_DM_MACID_CFG =0x40, + H2C_DM_TXBF =0x41, + H2C_RSSI_REPORT =0x42, + //Class BT + H2C_BT_COEX_MASK =0x60, + H2C_BT_COEX_GPIO_MODE =0x61, + H2C_BT_DAC_SWING_VAL =0x62, + H2C_BT_PSD_RST =0x63, + + //Class Remote WakeUp +#ifdef CONFIG_WOWLAN + H2C_COM_WWLAN =0x80, + H2C_COM_REMOTE_WAKE_CTRL =0x81, + H2C_COM_AOAC_GLOBAL_INFO =0x82, + H2C_COM_AOAC_RSVD_PAGE =0x83, +#endif + + //Class + //H2C_RESET_TSF =0xc0, +}RTL8188E_H2C_CMD_ID; + +#endif + + +struct cmd_msg_parm { + u8 eid; //element id + u8 sz; // sz + u8 buf[6]; +}; + +enum{ + PWRS +}; + +typedef struct _SETPWRMODE_PARM { + u8 Mode;//0:Active,1:LPS,2:WMMPS + //u8 RLBM:4;//0:Min,1:Max,2: User define + u8 SmartPS_RLBM;//LPS=0:PS_Poll,1:PS_Poll,2:NullData,WMM=0:PS_Poll,1:NullData + u8 AwakeInterval; // unit: beacon interval + u8 bAllQueueUAPSD; + u8 PwrState;//AllON(0x0c),RFON(0x04),RFOFF(0x00) +} SETPWRMODE_PARM, *PSETPWRMODE_PARM; + +struct H2C_SS_RFOFF_PARAM{ + u8 ROFOn; // 1: on, 0:off + u16 gpio_period; // unit: 1024 us +}__attribute__ ((packed)); + + +typedef struct JOINBSSRPT_PARM_88E{ + u8 OpMode; // RT_MEDIA_STATUS +#ifdef CONFIG_WOWLAN + u8 MacID; // MACID +#endif //CONFIG_WOWLAN +}JOINBSSRPT_PARM_88E, *PJOINBSSRPT_PARM_88E; + +/* move to hal_com_h2c.h +typedef struct _RSVDPAGE_LOC_88E { + u8 LocProbeRsp; + u8 LocPsPoll; + u8 LocNullData; + u8 LocQosNull; + u8 LocBTQosNull; +#ifdef CONFIG_WOWLAN + u8 LocRemoteCtrlInfo; + u8 LocArpRsp; + u8 LocNbrAdv; + u8 LocGTKRsp; + u8 LocGTKInfo; + u8 LocProbeReq; + u8 LocNetList; +#endif //CONFIG_WOWLAN +} RSVDPAGE_LOC_88E, *PRSVDPAGE_LOC_88E; +*/ + +// host message to firmware cmd +void rtl8188e_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8188e_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus); +u8 rtl8188e_set_rssi_cmd(PADAPTER padapter, u8 *param); +u8 rtl8188e_set_raid_cmd(_adapter *padapter, u32 bitmap, u8 *arg); +void rtl8188e_Add_RateATid(PADAPTER padapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +s32 FillH2CCmd_88E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +//u8 rtl8192c_set_FwSelectSuspend_cmd(PADAPTER padapter, u8 bfwpoll, u16 period); +u8 GetTxBufferRsvdPageNum8188E(_adapter *padapter, bool wowlan); + + +#ifdef CONFIG_P2P +void rtl8188e_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +//u8 rtl8188e_reset_tsf(_adapter *padapter, u8 reset_port); +int reset_tsf(PADAPTER Adapter, u8 reset_port ); +#endif // CONFIG_TSF_RESET_OFFLOAD + +//#define H2C_8188E_RSVDPAGE_LOC_LEN 5 +//#define H2C_8188E_AOAC_RSVDPAGE_LOC_LEN 7 + +#ifdef CONFIG_WOWLAN +void SetFwRelatedForWoWLAN8188ES(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif//CONFIG_WOWLAN + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD CONTENT --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +// +/* move to hal_com_h2c.h +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_8188E_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188E_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8188E_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8188E_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +// AOAC_RSVDPAGE_LOC_0x83 +#define SET_8188E_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#define SET_8188E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +*/ +#endif//__RTL8188E_CMD_H__ + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_dm.h new file mode 100644 index 00000000..eb97de18 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_dm.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * 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 __RTL8188E_DM_H__ +#define __RTL8188E_DM_H__ + +void rtl8188e_init_dm_priv(IN PADAPTER Adapter); +void rtl8188e_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8188e_InitHalDm(IN PADAPTER Adapter); +void rtl8188e_HalDmWatchDog(IN PADAPTER Adapter); + +//VOID rtl8192c_dm_CheckTXPowerTracking(IN PADAPTER Adapter); + +//void rtl8192c_dm_RF_Saving(IN PADAPTER pAdapter, IN u8 bForceInNormal); + +#ifdef CONFIG_ANTENNA_DIVERSITY +void AntDivCompare8188E(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +u8 AntDivBeforeLink8188E(PADAPTER Adapter ); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_hal.h new file mode 100644 index 00000000..20e7bb4f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_hal.h @@ -0,0 +1,332 @@ +/****************************************************************************** + * + * 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 __RTL8188E_HAL_H__ +#define __RTL8188E_HAL_H__ + +//#include "hal_com.h" +#include "hal_data.h" + +//include HAL Related header after HAL Related compiling flags +#include "rtl8188e_spec.h" +#include "Hal8188EPhyReg.h" +#include "Hal8188EPhyCfg.h" +#include "rtl8188e_rf.h" +#include "rtl8188e_dm.h" +#include "rtl8188e_recv.h" +#include "rtl8188e_xmit.h" +#include "rtl8188e_cmd.h" +#include "rtl8188e_led.h" +#include "Hal8188EPwrSeq.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8188e_sreset.h" +#endif + +#if 0 + // Fw Array + #define Rtl8188E_FwImageArray Rtl8188EFwImgArray + #define Rtl8188E_FWImgArrayLength Rtl8188EFWImgArrayLength +#ifdef CONFIG_WOWLAN + #define Rtl8188E_FwWoWImageArray Array_MP_8188E_FW_WoWLAN + #define Rtl8188E_FwWoWImgArrayLength ArrayLength_MP_8188E_FW_WoWLAN +#endif //CONFIG_WOWLAN +#endif + + + #define RTL8188E_FW_IMG "rtl8188e/FW_NIC.bin" + #define RTL8188E_FW_WW_IMG "rtl8188e/FW_WoWLAN.bin" + #define RTL8188E_PHY_REG "rtl8188e/PHY_REG.txt" + #define RTL8188E_PHY_RADIO_A "rtl8188e/RadioA.txt" + #define RTL8188E_PHY_RADIO_B "rtl8188e/RadioB.txt" + #define RTL8188E_TXPWR_TRACK "rtl8188e/TxPowerTrack.txt" + #define RTL8188E_AGC_TAB "rtl8188e/AGC_TAB.txt" + #define RTL8188E_PHY_MACREG "rtl8188e/MAC_REG.txt" + #define RTL8188E_PHY_REG_PG "rtl8188e/PHY_REG_PG.txt" + #define RTL8188E_PHY_REG_MP "rtl8188e/PHY_REG_MP.txt" + #define RTL8188E_TXPWR_LMT "rtl8188e/TXPWR_LMT.txt" + + //--------------------------------------------------------------------- + // RTL8188E Power Configuration CMDs for USB/SDIO/PCIE interfaces + //--------------------------------------------------------------------- + #define Rtl8188E_NIC_PWR_ON_FLOW rtl8188E_power_on_flow + #define Rtl8188E_NIC_RF_OFF_FLOW rtl8188E_radio_off_flow + #define Rtl8188E_NIC_DISABLE_FLOW rtl8188E_card_disable_flow + #define Rtl8188E_NIC_ENABLE_FLOW rtl8188E_card_enable_flow + #define Rtl8188E_NIC_SUSPEND_FLOW rtl8188E_suspend_flow + #define Rtl8188E_NIC_RESUME_FLOW rtl8188E_resume_flow + #define Rtl8188E_NIC_PDN_FLOW rtl8188E_hwpdn_flow + #define Rtl8188E_NIC_LPS_ENTER_FLOW rtl8188E_enter_lps_flow + #define Rtl8188E_NIC_LPS_LEAVE_FLOW rtl8188E_leave_lps_flow + + +#if 1 // download firmware related data structure +#define MAX_FW_8188E_SIZE 0x8000 //32768,32k / 16384,16k + +#define FW_8188E_SIZE 0x4000 //16384,16k +#define FW_8188E_SIZE_2 0x8000 //32768,32k + +#define FW_8188E_START_ADDRESS 0x1000 +#define FW_8188E_END_ADDRESS 0x1FFF //0x5FFF + + +#define IS_FW_HEADER_EXIST_88E(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88E0) + +typedef struct _RT_FIRMWARE_8188E { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[MAX_FW_8188E_SIZE]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8188E, *PRT_FIRMWARE_8188E; + +// +// This structure must be cared byte-ordering +// + +typedef struct _RT_8188E_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u8 Subversion; // FW Subversion, default 0x00 + u16 Rsvd1; + + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u8 Foundry; + u8 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8188E_FIRMWARE_HDR, *PRT_8188E_FIRMWARE_HDR; +#endif // download firmware related data structure + + +#define DRIVER_EARLY_INT_TIME_8188E 0x05 +#define BCN_DMA_ATIME_INT_TIME_8188E 0x02 + + +//#define MAX_RX_DMA_BUFFER_SIZE_88E 0x2400 //9k for 88E nornal chip , //MaxRxBuff=10k-max(TxReportSize(64*8), WOLPattern(16*24)) +#define RX_DMA_SIZE_88E(__Adapter) ((!IS_VENDOR_8188E_I_CUT_SERIES(__Adapter))?0x2800:0x4000) + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#define RX_DMA_RESERVD_FW_FEATURE 0x200 /* for tx report (64*8) */ + +#define MAX_RX_DMA_BUFFER_SIZE_88E(__Adapter) RX_DMA_SIZE_88E(__Adapter)-RX_DMA_RESERVD_FW_FEATURE + +#define MAX_TX_REPORT_BUFFER_SIZE 0x0400 /* 1k */ + +// Note: We will divide number of page equally for each queue other than public queue! +// 22k = 22528 bytes = 176 pages (@page = 128 bytes) +// must reserved about 7 pages for LPS => 176-7 = 169 (0xA9) +// 2*BCN / 1*ps-poll / 1*null-data /1*prob_rsp /1*QOS null-data /1*BT QOS null-data + +#define BCNQ_PAGE_NUM_88E 0x08 + +//For WoWLan , more reserved page +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_88E 0x00 +#else +#define WOWLAN_PAGE_NUM_88E 0x00 +#endif + +/* Note: +Tx FIFO Size : previous CUT:22K /I_CUT after:32KB +Tx page Size : 128B +Total page numbers : 176(0xB0) / 256(0x100) +*/ +#define TOTAL_PAGE_NUMBER_88E(_Adapter) ((IS_VENDOR_8188E_I_CUT_SERIES(_Adapter)?0x100:0xB0) - 1)/* must reserved 1 page for dma issue */ +#define TX_TOTAL_PAGE_NUMBER_88E(_Adapter) (TOTAL_PAGE_NUMBER_88E(_Adapter) - BCNQ_PAGE_NUM_88E - WOWLAN_PAGE_NUM_88E) +#define TX_PAGE_BOUNDARY_88E(_Adapter) (TX_TOTAL_PAGE_NUMBER_88E(_Adapter) + 1) /* beacon header start address */ + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_88E(_Adapter) TX_TOTAL_PAGE_NUMBER_88E(_Adapter) +#define WMM_NORMAL_TX_PAGE_BOUNDARY_88E(_Adapter) (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_88E(_Adapter) + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8723B +#define NORMAL_PAGE_NUM_HPQ_88E 0x0 +#define NORMAL_PAGE_NUM_LPQ_88E 0x09 +#define NORMAL_PAGE_NUM_NPQ_88E 0x0 + +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_88E 0x29 +#define WMM_NORMAL_PAGE_NUM_LPQ_88E 0x1C +#define WMM_NORMAL_PAGE_NUM_NPQ_88E 0x1C + + +//------------------------------------------------------------------------- +// Chip specific +//------------------------------------------------------------------------- +#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3) +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_88C_USB_MCARD 0x2 +#define CHIP_BONDING_88C_USB_HP 0x1 + +//------------------------------------------------------------------------- +// Channel Plan +//------------------------------------------------------------------------- + + +#define EFUSE_REAL_CONTENT_LEN 512 +#define EFUSE_MAP_LEN 128 +#define EFUSE_MAX_SECTION 16 +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN) +// +// +// To prevent out of boundary programming case, +// leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 1byte|----8bytes----|1byte|--5bytes--| +// | | Reserved(14bytes) | +// +#define EFUSE_OOB_PROTECT_BYTES 15 // PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. + +#define EFUSE_REAL_CONTENT_LEN_88E 256 +#define EFUSE_MAP_LEN_88E 512 +#define EFUSE_MAX_SECTION_88E 64 +#define EFUSE_MAX_WORD_UNIT_88E 4 +#define EFUSE_IC_ID_OFFSET_88E 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR_88E(addr) (addr < EFUSE_REAL_CONTENT_LEN_88E) +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 2byte|----8bytes----|1byte|--7bytes--| //92D +#define EFUSE_OOB_PROTECT_BYTES_88E 18 // PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. +#define EFUSE_PROTECT_BYTES_BANK_88E 16 + + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +//#define IS_MULTI_FUNC_CHIP(_Adapter) (((((PHAL_DATA_TYPE)(_Adapter->HalData))->MultiFunc) & (RT_MULTI_FUNC_BT|RT_MULTI_FUNC_GPS)) ? _TRUE : _FALSE) + +//#define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) + +#ifdef CONFIG_PCI_HCI + /* according to the define in the rtw_xmit.h, rtw_recv.h */ +#define TX_DESC_NUM_8188EE TXDESC_NUM /* 128 */ +#ifdef CONFIG_CONCURRENT_MODE +/*#define BE_QUEUE_TX_DESC_NUM_8188EE (TXDESC_NUM<<1)*/ /* 256 */ +#define BE_QUEUE_TX_DESC_NUM_8188EE ((TXDESC_NUM<<1)+(TXDESC_NUM>>1)) /* 320 */ +/*#define BE_QUEUE_TX_DESC_NUM_8188EE ((TXDESC_NUM<<1)+TXDESC_NUM)*/ /* 384 */ +#else +#define BE_QUEUE_TX_DESC_NUM_8188EE TXDESC_NUM /* 128 */ +/*#define BE_QUEUE_TX_DESC_NUM_8188EE (TXDESC_NUM+(TXDESC_NUM>>1)) *//* 192 */ +#endif + +void InterruptRecognized8188EE(PADAPTER Adapter, PRT_ISR_CONTENT pIsrContent); +void UpdateInterruptMask8188EE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif //CONFIG_PCI_HCI + +// rtl8188e_hal_init.c + +s32 rtl8188e_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void _8051Reset88E(PADAPTER padapter); +void rtl8188e_InitializeFirmwareVars(PADAPTER padapter); + + +s32 InitLLTTable(PADAPTER padapter, u8 txpktbuf_bndy); + +// EFuse +u8 GetEEPROMSize8188E(PADAPTER padapter); +void Hal_InitPGData88E(PADAPTER padapter); +void Hal_EfuseParseIDCode88E(PADAPTER padapter, u8 *hwinfo); +void Hal_ReadTxPowerInfo88E(PADAPTER padapter,u8* hwinfo,BOOLEAN AutoLoadFail); + +void Hal_EfuseParseEEPROMVer88E(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void rtl8188e_EfuseParseChnlPlan(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID88E(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_ReadAntennaDiversity88E (PADAPTER pAdapter,u8*PROMContent,BOOLEAN AutoLoadFail); +void Hal_ReadThermalMeter_88E(PADAPTER Adapter,u8* PROMContent,BOOLEAN AutoloadFail); +void Hal_EfuseParseXtal_8188E(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_EfuseParseBoardType88E(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadPowerSavingMode88E(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); + +BOOLEAN HalDetectPwrDownMode88E(PADAPTER Adapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + + +#ifdef CONFIG_RF_GAIN_OFFSET +void Hal_ReadRFGainOffset(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +#endif //CONFIG_RF_GAIN_OFFSET + +void rtl8188e_init_default_value(_adapter *adapter); + +void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8188e(_adapter *adapter); + +// register +void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits); + +void rtl8188e_start_thread(_adapter *padapter); +void rtl8188e_stop_thread(_adapter *padapter); + +void rtw_IOL_cmd_tx_pkt_buf_dump(ADAPTER *Adapter,int data_len); +#ifdef CONFIG_IOL_EFUSE_PATCH +s32 rtl8188e_iol_efuse_patch(PADAPTER padapter); +#endif//CONFIG_IOL_EFUSE_PATCH +void _InitTransferPageSize(PADAPTER padapter); + +void SetHwReg8188E(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg8188E(PADAPTER padapter, u8 variable, u8 *val); +void ResumeTxBeacon(PADAPTER padapter); +void StopTxBeacon(PADAPTER padapter); +u8 +GetHalDefVar8188E( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ); +#endif //__RTL8188E_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_led.h new file mode 100644 index 00000000..4b05994a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * 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 __RTL8188E_LED_H__ +#define __RTL8188E_LED_H__ + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8188eu_InitSwLeds(PADAPTER padapter); +void rtl8188eu_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8188ee_InitSwLeds(PADAPTER padapter); +void rtl8188ee_DeInitSwLeds(PADAPTER padapter); +#endif +#if defined (CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +void rtl8188es_InitSwLeds(PADAPTER padapter); +void rtl8188es_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_recv.h new file mode 100644 index 00000000..8326afa0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_recv.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * + * 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 __RTL8188E_RECV_H__ +#define __RTL8188E_RECV_H__ + +#define RECV_BLK_SZ 512 +#define RECV_BLK_CNT 16 +#define RECV_BLK_TH RECV_BLK_CNT + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + //#define MAX_RECVBUF_SZ (32768) // 32k + //#define MAX_RECVBUF_SZ (16384) //16K + //#define MAX_RECVBUF_SZ (10240) //10K + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#define MAX_RECVBUF_SZ (10240) + +#endif + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#define TX_RPT1_PKT_LEN 8 + +typedef struct rxreport_8188e +{ + //Offset 0 + u32 pktlen:14; + u32 crc32:1; + u32 icverr:1; + u32 drvinfosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 physt:1; + u32 swdec:1; + u32 ls:1; + u32 fs:1; + u32 eor:1; + u32 own:1; + + //Offset 4 + u32 macid:5; + u32 tid:4; + u32 hwrsvd:4; + u32 amsdu:1; + u32 paggr:1; + u32 faggr:1; + u32 a1fit:4; + u32 a2fit:4; + u32 pam:1; + u32 pwr:1; + u32 md:1; + u32 mf:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + //Offset 8 + u32 seq:12; + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd0831:1; + + //Offset 12 + u32 rxmcs:6; + u32 rxht:1; + u32 gf:1; + u32 splcp:1; + u32 bw:1; + u32 htc:1; + u32 eosp:1; + u32 bssidfit:2; + u32 rpt_sel:2; + u32 rsvd1216:13; + u32 pattern_match:1; + u32 unicastwake:1; + u32 magicwake:1; + + //Offset 16 + /* + u32 pattern0match:1; + u32 pattern1match:1; + u32 pattern2match:1; + u32 pattern3match:1; + u32 pattern4match:1; + u32 pattern5match:1; + u32 pattern6match:1; + u32 pattern7match:1; + u32 pattern8match:1; + u32 pattern9match:1; + u32 patternamatch:1; + u32 patternbmatch:1; + u32 patterncmatch:1; + u32 rsvd1613:19; + */ + u32 rsvd16; + + //Offset 20 + u32 tsfl; + + //Offset 24 + u32 bassn:12; + u32 bavld:1; + u32 rsvd2413:19; +} RXREPORT, *PRXREPORT; + + +#if defined (CONFIG_SDIO_HCI)||defined(CONFIG_GSPI_HCI) +s32 rtl8188es_init_recv_priv(PADAPTER padapter); +void rtl8188es_free_recv_priv(PADAPTER padapter); +void rtl8188es_recv_hdl(PADAPTER padapter, struct recv_buf *precvbuf); +#endif + +#ifdef CONFIG_USB_HCI +void rtl8188eu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +s32 rtl8188eu_init_recv_priv(PADAPTER padapter); +void rtl8188eu_free_recv_priv(PADAPTER padapter); +void rtl8188eu_recv_hdl(PADAPTER padapter, struct recv_buf *precvbuf); +void rtl8188eu_recv_tasklet(void *priv); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8188ee_init_recv_priv(PADAPTER padapter); +void rtl8188ee_free_recv_priv(PADAPTER padapter); +#endif + +void rtl8188e_query_rx_desc_status(union recv_frame *precvframe, struct recv_stat *prxstat); + +#endif /* __RTL8188E_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_rf.h new file mode 100644 index 00000000..28e58f29 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_rf.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * 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 __RTL8188E_RF_H__ +#define __RTL8188E_RF_H__ + + + +int PHY_RF6052_Config8188E( IN PADAPTER Adapter ); +void rtl8188e_RF_ChangeTxPath( IN PADAPTER Adapter, + IN u16 DataRate); +void rtl8188e_PHY_RF6052SetBandwidth( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + +#endif//__RTL8188E_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_spec.h new file mode 100644 index 00000000..a678dd99 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_spec.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * 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 __RTL8188E_SPEC_H__ +#define __RTL8188E_SPEC_H__ + + +//============================================================ +// 8188E Regsiter offset definition +//============================================================ + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_BB_PAD_CTRL 0x0064 +#define REG_HMEBOX_E0 0x0088 +#define REG_HMEBOX_E1 0x008A +#define REG_HMEBOX_E2 0x008C +#define REG_HMEBOX_E3 0x008E +#define REG_HMEBOX_EXT_0 0x01F0 +#define REG_HMEBOX_EXT_1 0x01F4 +#define REG_HMEBOX_EXT_2 0x01F8 +#define REG_HMEBOX_EXT_3 0x01FC +#define REG_HIMR_88E 0x00B0 //RTL8188E +#define REG_HISR_88E 0x00B4 //RTL8188E +#define REG_HIMRE_88E 0x00B8 //RTL8188E +#define REG_HISRE_88E 0x00BC //RTL8188E +#define REG_MACID_NO_LINK_0 0x0484 +#define REG_MACID_NO_LINK_1 0x0488 +#define REG_MACID_PAUSE_0 0x048c +#define REG_MACID_PAUSE_1 0x0490 + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) +#define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) +#define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) +#define REG_WOWLAN_WAKE_REASON REG_MCUTST_WOWLAN + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x01a4 +#define REG_TXPKTBUF_IV_HIGH 0x01a8 +#endif + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#ifdef CONFIG_RF_GAIN_OFFSET +#define EEPROM_RF_GAIN_OFFSET 0xC1 +#define EEPROM_RF_GAIN_VAL 0xF6 +#define EEPROM_THERMAL_OFFSET 0xF5 +#endif //CONFIG_RF_GAIN_OFFSET +//---------------------------------------------------------------------------- +// 88E Driver Initialization Offload REG_FDHM0(Offset 0x88, 8 bits) +//---------------------------------------------------------------------------- +//IOL config for REG_FDHM0(Reg0x88) +#define CMD_INIT_LLT BIT0 +#define CMD_READ_EFUSE_MAP BIT1 +#define CMD_EFUSE_PATCH BIT2 +#define CMD_IOCONFIG BIT3 +#define CMD_INIT_LLT_ERR BIT4 +#define CMD_READ_EFUSE_MAP_ERR BIT5 +#define CMD_EFUSE_PATCH_ERR BIT6 +#define CMD_IOCONFIG_ERR BIT7 + +//----------------------------------------------------- +// +// Redifine register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define ISR_88E REG_HISR_88E + +#ifdef CONFIG_PCI_HCI +//#define IMR_RX_MASK (IMR_ROK_88E|IMR_RDU_88E|IMR_RXFOVW_88E) +#define IMR_TX_MASK (IMR_VODOK_88E|IMR_VIDOK_88E|IMR_BEDOK_88E|IMR_BKDOK_88E|IMR_MGNTDOK_88E|IMR_HIGHDOK_88E|IMR_BCNDERR0_88E) + +#ifdef CONFIG_CONCURRENT_MODE +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_88E | IMR_TBDOK_88E | IMR_TBDER_88E | IMR_BCNDMAINT_E_88E) +#else +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_88E | IMR_TBDOK_88E | IMR_TBDER_88E) +#endif + +#define RT_AC_INT_MASKS (IMR_VIDOK_88E | IMR_VODOK_88E | IMR_BEDOK_88E|IMR_BKDOK_88E) +#endif + + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_88E 64 +#define SEC_CAM_ENT_NUM_88E 32 +#define NSS_NUM_88E 1 +#define BAND_CAP_88E (BAND_CAP_2G) +#define BW_CAP_88E (BW_CAP_20M | BW_CAP_40M) + +//---------------------------------------------------------------------------- +// 8192C EEPROM/EFUSE share register definition. +//---------------------------------------------------------------------------- + +#define EFUSE_ACCESS_ON 0x69 // For RTL8723 only. +#define EFUSE_ACCESS_OFF 0x00 // For RTL8723 only. + +#endif /* __RTL8188E_SPEC_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_sreset.h new file mode 100644 index 00000000..34cb21a0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL8188E_SRESET_H_ +#define _RTL8188E_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8188e_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8188e_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_xmit.h new file mode 100644 index 00000000..793a66bf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188e_xmit.h @@ -0,0 +1,299 @@ +/****************************************************************************** + * + * 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 __RTL8188E_XMIT_H__ +#define __RTL8188E_XMIT_H__ + + + + +//For 88e early mode +#define SET_EARLYMODE_PKTNUM(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 3, __Value) +#define SET_EARLYMODE_LEN0(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 12, __Value) +#define SET_EARLYMODE_LEN1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 16, 12, __Value) +#define SET_EARLYMODE_LEN2_1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 28, 4, __Value) +#define SET_EARLYMODE_LEN2_2(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 8, __Value) +#define SET_EARLYMODE_LEN3(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 8, 12, __Value) +#define SET_EARLYMODE_LEN4(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 20, 12, __Value) + +// +//defined for TX DESC Operation +// + +#define MAX_TID (15) + +//OFFSET 0 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define BMC BIT(24) +#define LSG BIT(26) +#define FSG BIT(27) +#define OWN BIT(31) + + +//OFFSET 4 +#define PKT_OFFSET_SZ 0 +#define QSEL_SHT 8 +#define RATE_ID_SHT 16 +#define NAVUSEHDR BIT(20) +#define SEC_TYPE_SHT 22 +#define PKT_OFFSET_SHT 26 + +//OFFSET 8 +#define AGG_EN BIT(12) +#define AGG_BK BIT(16) +#define AMPDU_DENSITY_SHT 20 +#define ANTSEL_A BIT(24) +#define ANTSEL_B BIT(25) +#define TX_ANT_CCK_SHT 26 +#define TX_ANTL_SHT 28 +#define TX_ANT_HT_SHT 30 + +//OFFSET 12 +#define SEQ_SHT 16 +#define EN_HWSEQ BIT(31) + +//OFFSET 16 +#define QOS BIT(6) +#define HW_SSN BIT(7) +#define USERATE BIT(8) +#define DISDATAFB BIT(10) +#define CTS_2_SELF BIT(11) +#define RTS_EN BIT(12) +#define HW_RTS_EN BIT(13) +#define DATA_SHORT BIT(24) +#define PWR_STATUS_SHT 15 +#define DATA_SC_SHT 20 +#define DATA_BW BIT(25) + +//OFFSET 20 +#define RTY_LMT_EN BIT(17) + + +//OFFSET 20 +#define SGI BIT(6) +#define USB_TXAGG_NUM_SHT 24 + +typedef struct txdesc_88e +{ + //Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 ls:1; + u32 fs:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + //Offset 4 + u32 macid:6; + u32 rsvd0406:2; + u32 qsel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rate_id:4; + u32 navusehdr:1; + u32 en_desc_id:1; + u32 sectype:2; + u32 rsvd0424:2; + u32 pkt_offset:5; // unit: 8 bytes + u32 rsvd0431:1; + + //Offset 8 + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rd_en:1; + u32 bar_rty_th:2; + u32 bk:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdu_density:3; + u32 bt_null:1; + u32 ant_sel_a:1; + u32 ant_sel_b:1; + u32 tx_ant_cck:2; + u32 tx_antl:2; + u32 tx_ant_ht:2; + + //Offset 12 + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + //Offset 16 + u32 rtsrate:5; + u32 ap_dcfe:1; + u32 hwseq_sel:2; + u32 userate:1; + u32 disrtsfb:1; + u32 disdatafb:1; + u32 cts2self:1; + u32 rtsen:1; + u32 hw_rts_en:1; + u32 port_id:1; + u32 pwr_status:3; + u32 wait_dcts:1; + u32 cts2ap_en:1; + u32 data_sc:2; + u32 data_stbc:2; + u32 data_short:1; + u32 data_bw:1; + u32 rts_short:1; + u32 rts_bw:1; + u32 rts_sc:2; + u32 vcs_stbc:2; + + //Offset 20 + u32 datarate:6; + u32 sgi:1; + u32 try_rate:1; + u32 data_ratefb_lmt:5; + u32 rts_ratefb_lmt:4; + u32 rty_lmt_en:1; + u32 data_rt_lmt:6; + u32 usb_txagg_num:8; + + //Offset 24 + u32 txagg_a:5; + u32 txagg_b:5; + u32 use_max_len:1; + u32 max_agg_num:5; + u32 mcsg1_max_len:4; + u32 mcsg2_max_len:4; + u32 mcsg3_max_len:4; + u32 mcs7_sgi_max_len:4; + + //Offset 28 + u32 checksum:16; // TxBuffSize(PCIe)/CheckSum(USB) + u32 sw0:8; /* offset 30 */ + u32 sw1:4; + u32 mcs15_sgi_max_len:4; +}TXDESC_8188E, *PTXDESC_8188E; + +#define txdesc_set_ccx_sw_88e(txdesc, value) \ + do { \ + ((struct txdesc_88e *)(txdesc))->sw1 = (((value)>>8) & 0x0f); \ + ((struct txdesc_88e *)(txdesc))->sw0 = ((value) & 0xff); \ + } while (0) + +struct txrpt_ccx_88e { + /* offset 0 */ + u8 tag1:1; + u8 pkt_num:3; + u8 txdma_underflow:1; + u8 int_bt:1; + u8 int_tri:1; + u8 int_ccx:1; + + /* offset 1 */ + u8 mac_id:6; + u8 pkt_ok:1; + u8 bmc:1; + + /* offset 2 */ + u8 retry_cnt:6; + u8 lifetime_over:1; + u8 retry_over:1; + + /* offset 3 */ + u8 ccx_qtime0; + u8 ccx_qtime1; + + /* offset 5 */ + u8 final_data_rate; + + /* offset 6 */ + u8 sw1:4; + u8 qsel:4; + + /* offset 7 */ + u8 sw0; +}; + +#define txrpt_ccx_sw_88e(txrpt_ccx) ((txrpt_ccx)->sw0 + ((txrpt_ccx)->sw1<<8)) +#define txrpt_ccx_qtime_88e(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8)) + +#define SET_TX_DESC_SEC_TYPE_8188E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) + +void rtl8188e_fill_fake_txdesc(PADAPTER padapter,u8*pDesc,u32 BufferLen, + u8 IsPsPoll,u8 IsBTQosNull, u8 bDataFrame); +void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); + +#if defined(CONFIG_SDIO_HCI)||defined (CONFIG_GSPI_HCI) +s32 rtl8188es_init_xmit_priv(PADAPTER padapter); +void rtl8188es_free_xmit_priv(PADAPTER padapter); +s32 rtl8188es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +thread_return rtl8188es_xmit_thread(thread_context context); +s32 rtl8188es_xmit_buf_handler(PADAPTER padapter); + +#ifdef CONFIG_SDIO_TX_TASKLET +void rtl8188es_xmit_tasklet(void *priv); +#endif +#endif + +#ifdef CONFIG_USB_HCI +s32 rtl8188eu_init_xmit_priv(PADAPTER padapter); +void rtl8188eu_free_xmit_priv(PADAPTER padapter); +s32 rtl8188eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8188eu_xmit_buf_handler(PADAPTER padapter); +void rtl8188eu_xmit_tasklet(void *priv); +s32 rtl8188eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8188ee_init_xmit_priv(PADAPTER padapter); +void rtl8188ee_free_xmit_priv(PADAPTER padapter); +void rtl8188ee_xmitframe_resume(_adapter *padapter); +s32 rtl8188ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188ee_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8188ee_xmit_tasklet(void *priv); +#endif + + + +#ifdef CONFIG_TX_EARLY_MODE +void UpdateEarlyModeInfo8188E(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf ); +#endif + +#ifdef CONFIG_XMIT_ACK +void dump_txrpt_ccx_88e(void *buf); +void handle_txrpt_ccx_88e(_adapter *adapter, u8 *buf); +#else +#define dump_txrpt_ccx_88e(buf) do {} while(0) +#define handle_txrpt_ccx_88e(adapter, buf) do {} while(0) +#endif //CONFIG_XMIT_ACK + +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc); +#endif //__RTL8188E_XMIT_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_cmd.h new file mode 100644 index 00000000..ff8e5261 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_cmd.h @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8188F_CMD_H__ +#define __RTL8188F_CMD_H__ + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD DEFINITION ------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +enum h2c_cmd_8188F{ + //Common Class: 000 + H2C_8188F_RSVD_PAGE = 0x00, + H2C_8188F_MEDIA_STATUS_RPT = 0x01, + H2C_8188F_SCAN_ENABLE = 0x02, + H2C_8188F_KEEP_ALIVE = 0x03, + H2C_8188F_DISCON_DECISION = 0x04, + H2C_8188F_PSD_OFFLOAD = 0x05, + H2C_8188F_AP_OFFLOAD = 0x08, + H2C_8188F_BCN_RSVDPAGE = 0x09, + H2C_8188F_PROBERSP_RSVDPAGE = 0x0A, + H2C_8188F_FCS_RSVDPAGE = 0x10, + H2C_8188F_FCS_INFO = 0x11, + H2C_8188F_AP_WOW_GPIO_CTRL = 0x13, + + //PoweSave Class: 001 + H2C_8188F_SET_PWR_MODE = 0x20, + H2C_8188F_PS_TUNING_PARA = 0x21, + H2C_8188F_PS_TUNING_PARA2 = 0x22, + H2C_8188F_P2P_LPS_PARAM = 0x23, + H2C_8188F_P2P_PS_OFFLOAD = 0x24, + H2C_8188F_PS_SCAN_ENABLE = 0x25, + H2C_8188F_SAP_PS_ = 0x26, + H2C_8188F_INACTIVE_PS_ = 0x27, //Inactive_PS + H2C_8188F_FWLPS_IN_IPS_ = 0x28, + + //Dynamic Mechanism Class: 010 + H2C_8188F_MACID_CFG = 0x40, + H2C_8188F_TXBF = 0x41, + H2C_8188F_RSSI_SETTING = 0x42, + H2C_8188F_AP_REQ_TXRPT = 0x43, + H2C_8188F_INIT_RATE_COLLECT = 0x44, + H2C_8188F_RA_PARA_ADJUST = 0x46, + + //BT Class: 011 + H2C_8188F_B_TYPE_TDMA = 0x60, + H2C_8188F_BT_INFO = 0x61, + H2C_8188F_FORCE_BT_TXPWR = 0x62, + H2C_8188F_BT_IGNORE_WLANACT = 0x63, + H2C_8188F_DAC_SWING_VALUE = 0x64, + H2C_8188F_ANT_SEL_RSV = 0x65, + H2C_8188F_WL_OPMODE = 0x66, + H2C_8188F_BT_MP_OPER = 0x67, + H2C_8188F_BT_CONTROL = 0x68, + H2C_8188F_BT_WIFI_CTRL = 0x69, + H2C_8188F_BT_FW_PATCH = 0x6A, + H2C_8188F_BT_WLAN_CALIBRATION = 0x6D, + + //WOWLAN Class: 100 + H2C_8188F_WOWLAN = 0x80, + H2C_8188F_REMOTE_WAKE_CTRL = 0x81, + H2C_8188F_AOAC_GLOBAL_INFO = 0x82, + H2C_8188F_AOAC_RSVD_PAGE = 0x83, + H2C_8188F_AOAC_RSVD_PAGE2 = 0x84, + H2C_8188F_D0_SCAN_OFFLOAD_CTRL = 0x85, + H2C_8188F_D0_SCAN_OFFLOAD_INFO = 0x86, + H2C_8188F_CHNL_SWITCH_OFFLOAD = 0x87, + H2C_8188F_P2P_OFFLOAD_RSVD_PAGE = 0x8A, + H2C_8188F_P2P_OFFLOAD = 0x8B, + + H2C_8188F_RESET_TSF = 0xC0, + H2C_8188F_MAXID, +}; + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD CONTENT --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_8188F_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8188F_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8188F_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8188F_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_KEEP_ALIVE_CMD_0x03 +#define SET_8188F_H2CCMD_KEEPALIVE_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8188F_H2CCMD_KEEPALIVE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8188F_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8188F_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +//_DISCONNECT_DECISION_CMD_0x04 +#define SET_8188F_H2CCMD_DISCONDECISION_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8188F_H2CCMD_DISCONDECISION_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8188F_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8188F_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +// _PWR_MOD_CMD_0x20 +#define SET_8188F_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8188F_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +#define GET_8188F_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +// _PS_TUNE_PARAM_CMD_0x21 +#define SET_8188F_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8188F_H2CCMD_PSTUNE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 1, __Value) +#define SET_8188F_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 1, 7, __Value) +#define SET_8188F_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +//_MACID_CFG_CMD_0x40 +#define SET_8188F_H2CCMD_MACID_CFG_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_RAID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 5, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_SGI_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 2, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_NO_UPDATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 3, 1, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_VHT_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 4, 2, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_DISPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 6, 1, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_DISRA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_RATE_MASK0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_RATE_MASK1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_RATE_MASK2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value) +#define SET_8188F_H2CCMD_MACID_CFG_RATE_MASK3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value) + +//_RSSI_SETTING_CMD_0x42 +#define SET_8188F_H2CCMD_RSSI_SETTING_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_RSSI_SETTING_RSSI(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value) +#define SET_8188F_H2CCMD_RSSI_SETTING_ULDL_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +// _AP_REQ_TXRPT_CMD_0x43 +#define SET_8188F_H2CCMD_APREQRPT_PARM_MACID1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8188F_H2CCMD_APREQRPT_PARM_MACID2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +// _FORCE_BT_TXPWR_CMD_0x62 +#define SET_8188F_H2CCMD_BT_PWR_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) + +// _FORCE_BT_MP_OPER_CMD_0x67 +#define SET_8188F_H2CCMD_BT_MPOPER_VER(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) +#define SET_8188F_H2CCMD_BT_MPOPER_REQNUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value) +#define SET_8188F_H2CCMD_BT_MPOPER_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_MPOPER_PARAM1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_MPOPER_PARAM2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_MPOPER_PARAM3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) + +// _BT_FW_PATCH_0x6A +#define SET_8188F_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_2BYTE((pu1Byte)(__pH2CCmd), 0, 16, __Value) +#define SET_8188F_H2CCMD_BT_FW_PATCH_ADDR0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_FW_PATCH_ADDR1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_FW_PATCH_ADDR2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8188F_H2CCMD_BT_FW_PATCH_ADDR3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + + +//---------------------------------------------------------------------------------------------------------// +//------------------------------------------- Structure --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- Function Statement --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +// host message to firmware cmd +void rtl8188f_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8188f_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus); +void rtl8188f_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8188f_Add_RateATid(PADAPTER pAdapter, u64 bitmap, u8* arg, u8 rssi_level); +void rtl8188f_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack); +//s32 rtl8188f_set_lowpwr_lps_cmd(PADAPTER padapter, u8 enable); +void rtl8188f_set_FwPsTuneParam_cmd(PADAPTER padapter); +void rtl8188f_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask); +void rtl8188f_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param); +void rtl8188f_download_rsvd_page(PADAPTER padapter, u8 mstatus); +#ifdef CONFIG_BT_COEXIST +void rtl8188f_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); +#endif // CONFIG_BT_COEXIST +#ifdef CONFIG_P2P +void rtl8188f_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void SetFwRelatedForWoWLAN8188f(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif//CONFIG_WOWLAN + +#ifdef CONFIG_P2P_WOWLAN +void rtl8188f_set_p2p_wowlan_offload_cmd(PADAPTER padapter); +#endif + +void rtl8188f_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +u8 rtl8188f_reset_tsf(_adapter *padapter, u8 reset_port); +#endif // CONFIG_TSF_RESET_OFFLOAD +s32 FillH2CCmd8188F(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +u8 GetTxBufferRsvdPageNum8188F(_adapter *padapter, bool wowlan); +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_dm.h new file mode 100644 index 00000000..d703ae52 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_dm.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * 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 __RTL8188F_DM_H__ +#define __RTL8188F_DM_H__ +//============================================================ +// Description: +// +// This file is for 8188F dynamic mechanism only +// +// +//============================================================ + +//============================================================ +// structure and define +//============================================================ + +//============================================================ +// function prototype +//============================================================ + +void rtl8188f_init_dm_priv(PADAPTER padapter); +void rtl8188f_deinit_dm_priv(PADAPTER padapter); + +void rtl8188f_InitHalDm(PADAPTER padapter); +void rtl8188f_HalDmWatchDog(PADAPTER padapter); +void rtl8188f_HalDmWatchDog_in_LPS(PADAPTER padapter); +void rtl8188f_hal_dm_in_lps(PADAPTER padapter); + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_hal.h new file mode 100644 index 00000000..acb5996d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_hal.h @@ -0,0 +1,322 @@ +/****************************************************************************** + * + * 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 __RTL8188F_HAL_H__ +#define __RTL8188F_HAL_H__ + +#include "hal_data.h" + +#include "rtl8188f_spec.h" +#include "rtl8188f_rf.h" +#include "rtl8188f_dm.h" +#include "rtl8188f_recv.h" +#include "rtl8188f_xmit.h" +#include "rtl8188f_cmd.h" +#include "rtl8188f_led.h" +#include "Hal8188FPwrSeq.h" +#include "Hal8188FPhyReg.h" +#include "Hal8188FPhyCfg.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8188f_sreset.h" +#endif + + +//--------------------------------------------------------------------- +// RTL8188F From file +//--------------------------------------------------------------------- + #define RTL8188F_FW_IMG "rtl8188f/FW_NIC.bin" + #define RTL8188F_FW_WW_IMG "rtl8188f/FW_WoWLAN.bin" + #define RTL8188F_PHY_REG "rtl8188f/PHY_REG.txt" + #define RTL8188F_PHY_RADIO_A "rtl8188f/RadioA.txt" + #define RTL8188F_PHY_RADIO_B "rtl8188f/RadioB.txt" + #define RTL8188F_TXPWR_TRACK "rtl8188f/TxPowerTrack.txt" + #define RTL8188F_AGC_TAB "rtl8188f/AGC_TAB.txt" + #define RTL8188F_PHY_MACREG "rtl8188f/MAC_REG.txt" + #define RTL8188F_PHY_REG_PG "rtl8188f/PHY_REG_PG.txt" + #define RTL8188F_PHY_REG_MP "rtl8188f/PHY_REG_MP.txt" + #define RTL8188F_TXPWR_LMT "rtl8188f/TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8188F From header +//--------------------------------------------------------------------- + +#if MP_DRIVER == 1 + #define Rtl8188F_FwBTImgArray Rtl8188FFwBTImgArray + #define Rtl8188F_FwBTImgArrayLength Rtl8188FFwBTImgArrayLength + + #define Rtl8188F_FwMPImageArray Rtl8188FFwMPImgArray + #define Rtl8188F_FwMPImgArrayLength Rtl8188FMPImgArrayLength + + #define Rtl8188F_PHY_REG_Array_MP Rtl8188F_PHYREG_Array_MP + #define Rtl8188F_PHY_REG_Array_MPLength Rtl8188F_PHYREG_Array_MPLength +#endif + + +#define FW_8188F_SIZE 0x8000 +#define FW_8188F_START_ADDRESS 0x1000 +#define FW_8188F_END_ADDRESS 0x1FFF //0x5FFF + +#define IS_FW_HEADER_EXIST_8188F(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88F0) + +typedef struct _RT_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_8188F_SIZE]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8188F, *PRT_FIRMWARE_8188F; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8188F_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u16 Subversion; // FW Subversion, default 0x00 + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8188F_FIRMWARE_HDR, *PRT_8188F_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME_8188F 0x05 +#define BCN_DMA_ATIME_INT_TIME_8188F 0x02 + +// for 8188F +// TX 32K, RX 16K, Page size 128B for TX, 8B for RX +#define PAGE_SIZE_TX_8188F 128 +#define PAGE_SIZE_RX_8188F 8 + +#define RX_DMA_SIZE_8188F 0x4000 // 16K +#ifdef CONFIG_FW_C2H_DEBUG +#define RX_DMA_RESERVED_SIZE_8188F 0x100 // 256B, reserved for c2h debug message +#else +#define RX_DMA_RESERVED_SIZE_8188F 0x80 // 128B, reserved for tx report +#endif + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#define RX_DMA_BOUNDARY_8188F (RX_DMA_SIZE_8188F - RX_DMA_RESERVED_SIZE_8188F - 1) + +// Note: We will divide number of page equally for each queue other than public queue! + +//For General Reserved Page Number(Beacon Queue is reserved page) +//Beacon:2, PS-Poll:1, Null Data:1,Qos Null Data:1,BT Qos Null Data:1 +#define BCNQ_PAGE_NUM_8188F 0x08 +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8188F 0x08 // 0x04 +#else +#define BCNQ1_PAGE_NUM_8188F 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef BCNQ1_PAGE_NUM_8188F +#define BCNQ1_PAGE_NUM_8188F 0x00 // 0x04 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8188F 0x07 +#else +#define WOWLAN_PAGE_NUM_8188F 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef WOWLAN_PAGE_NUM_8188F +#define WOWLAN_PAGE_NUM_8188F 0x15 +#endif + +#ifdef CONFIG_AP_WOWLAN +#define AP_WOWLAN_PAGE_NUM_8188F 0x02 +#endif + +#define TX_TOTAL_PAGE_NUMBER_8188F (0xFF - BCNQ_PAGE_NUM_8188F - BCNQ1_PAGE_NUM_8188F - WOWLAN_PAGE_NUM_8188F) +#define TX_PAGE_BOUNDARY_8188F (TX_TOTAL_PAGE_NUMBER_8188F + 1) + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8188F TX_TOTAL_PAGE_NUMBER_8188F +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8188F (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8188F + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8188F +#define NORMAL_PAGE_NUM_HPQ_8188F 0x0C +#define NORMAL_PAGE_NUM_LPQ_8188F 0x02 +#define NORMAL_PAGE_NUM_NPQ_8188F 0x02 + +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8188F 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8188F 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8188F 0x20 + + +#include "HalVerDef.h" +#include "hal_com.h" + +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define HAL_EFUSE_MEMORY + +#define HWSET_MAX_SIZE_8188F 512 +#define EFUSE_REAL_CONTENT_LEN_8188F 512 +#define EFUSE_MAP_LEN_8188F 512 +#define EFUSE_MAX_SECTION_8188F 64 + +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN_8188F) + +#define EFUSE_ACCESS_ON 0x69 // For RTL8188 only. +#define EFUSE_ACCESS_OFF 0x00 // For RTL8188 only. + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +typedef struct _C2H_EVT_HDR +{ + u8 CmdID; + u8 CmdLen; + u8 CmdSeq; +} __attribute__((__packed__)) C2H_EVT_HDR, *PC2H_EVT_HDR; + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +// rtl8188a_hal_init.c +s32 rtl8188f_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void rtl8188f_FirmwareSelfReset(PADAPTER padapter); +void rtl8188f_InitializeFirmwareVars(PADAPTER padapter); + +void rtl8188f_InitAntenna_Selection(PADAPTER padapter); +void rtl8188f_DeinitAntenna_Selection(PADAPTER padapter); +void rtl8188f_CheckAntenna_Selection(PADAPTER padapter); +void rtl8188f_init_default_value(PADAPTER padapter); + +s32 rtl8188f_InitLLTTable(PADAPTER padapter); + +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU); +s32 CardDisableWithoutHWSM(PADAPTER padapter); + +// EFuse +u8 GetEEPROMSize8188F(PADAPTER padapter); +void Hal_InitPGData(PADAPTER padapter, u8 *PROMContent); +void Hal_EfuseParseIDCode(PADAPTER padapter, u8 *hwinfo); +void Hal_EfuseParseTxPowerInfo_8188F(PADAPTER padapter, u8 *PROMContent, BOOLEAN AutoLoadFail); +/* void Hal_EfuseParseBTCoexistInfo_8188F(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); */ +void Hal_EfuseParseEEPROMVer_8188F(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseChnlPlan_8188F(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID_8188F(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParsePowerSavingMode_8188F(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseAntennaDiversity_8188F(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8188F(PADAPTER pAdapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseThermalMeter_8188F(PADAPTER padapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseKFreeData_8188F(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +VOID Hal_EfuseParseMacHidden_8188F(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); + +#if 0 /* Do not need for rtl8188f */ +VOID Hal_EfuseParseVoltage_8188F(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +#endif + +#ifdef CONFIG_C2H_PACKET_EN +void rtl8188f_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length); +#endif + +void rtl8188f_set_pll_ref_clk_sel(_adapter *adapter, u8 sel); + +void rtl8188f_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8188f(_adapter *adapter); +void SetHwReg8188F(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg8188F(PADAPTER padapter, u8 variable, u8 *val); +#ifdef CONFIG_C2H_PACKET_EN +void SetHwRegWithBuf8188F(PADAPTER padapter, u8 variable, u8 *pbuf, int len); +#endif // CONFIG_C2H_PACKET_EN +u8 SetHalDefVar8188F(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8188F(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); + +// register +void rtl8188f_InitBeaconParameters(PADAPTER padapter); +void rtl8188f_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode); +void _InitBurstPktLen_8188FS(PADAPTER Adapter); +void _8051Reset8188(PADAPTER padapter); +#ifdef CONFIG_WOWLAN +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void rtl8188f_start_thread(_adapter *padapter); +void rtl8188f_stop_thread(_adapter *padapter); + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +void rtl8188fs_init_checkbthang_workqueue(_adapter * adapter); +void rtl8188fs_free_checkbthang_workqueue(_adapter * adapter); +void rtl8188fs_cancle_checkbthang_workqueue(_adapter * adapter); +void rtl8188fs_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_8188f(PADAPTER padapter, u8 *pdata, u8 len); +#ifdef CONFIG_FW_C2H_DEBUG +void Debug_FwC2H_8188f(PADAPTER padapter, u8 *pdata, u8 len); +#endif //CONFIG_FW_C2H_DEBUG +s32 c2h_id_filter_ccx_8188f(u8 *buf); +s32 c2h_handler_8188f(PADAPTER padapter, u8 *pC2hEvent); +u8 MRateToHwRate8188F(u8 rate); +u8 HwRateToMRate8188F(u8 rate); + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8188FE(PADAPTER Adapter); +VOID UpdateInterruptMask8188FE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_led.h new file mode 100644 index 00000000..9b7bf78c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_led.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 __RTL8188F_LED_H__ +#define __RTL8188F_LED_H__ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8188fu_InitSwLeds(PADAPTER padapter); +void rtl8188fu_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_SDIO_HCI +void rtl8188fs_InitSwLeds(PADAPTER padapter); +void rtl8188fs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_GSPI_HCI +void rtl8188fs_InitSwLeds(PADAPTER padapter); +void rtl8188fs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8188fe_InitSwLeds(PADAPTER padapter); +void rtl8188fe_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_recv.h new file mode 100644 index 00000000..8a1228cd --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_recv.h @@ -0,0 +1,73 @@ +/****************************************************************************** + * + * 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 __RTL8188F_RECV_H__ +#define __RTL8188F_RECV_H__ + +#if defined(CONFIG_USB_HCI) + #ifndef MAX_RECVBUF_SZ + #ifdef PLATFORM_OS_CE + #define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #ifdef CONFIG_MINIMAL_MEMORY_USAGE + #define MAX_RECVBUF_SZ (4000) // about 4K + #else + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #elif defined(CONFIG_PLATFORM_HISILICON) + #define MAX_RECVBUF_SZ (16384) /* 16k */ + #else + #define MAX_RECVBUF_SZ (32768) /* 32k */ + #endif + //#define MAX_RECVBUF_SZ (20480) //20K + //#define MAX_RECVBUF_SZ (10240) //10K + //#define MAX_RECVBUF_SZ (16384) // 16k - 92E RX BUF :16K + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #endif + #endif + #endif //!MAX_RECVBUF_SZ +#elif defined(CONFIG_PCI_HCI) + #define MAX_RECVBUF_SZ (4000) // about 4K +#elif defined(CONFIG_SDIO_HCI) + #define MAX_RECVBUF_SZ (RX_DMA_BOUNDARY_8188F + 1) +#endif /* CONFIG_SDIO_HCI */ + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8188fs_init_recv_priv(PADAPTER padapter); +void rtl8188fs_free_recv_priv(PADAPTER padapter); +#endif + +#ifdef CONFIG_USB_HCI +int rtl8188fu_init_recv_priv(_adapter *padapter); +void rtl8188fu_free_recv_priv (_adapter *padapter); +void rtl8188fu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8188fe_init_recv_priv(PADAPTER padapter); +void rtl8188fe_free_recv_priv(PADAPTER padapter); +#endif + +void rtl8188f_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); + +#endif /* __RTL8188F_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_rf.h new file mode 100644 index 00000000..ea71ef13 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_rf.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * 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 __RTL8188F_RF_H__ +#define __RTL8188F_RF_H__ + +int PHY_RF6052_Config8188F( IN PADAPTER Adapter ); + +VOID +PHY_RF6052SetBandwidth8188F( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_spec.h new file mode 100644 index 00000000..52a02b12 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_spec.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * 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 __RTL8188F_SPEC_H__ +#define __RTL8188F_SPEC_H__ + +#include + + +#define HAL_NAV_UPPER_UNIT_8188F 128 // micro-second + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_RSV_CTRL_8188F 0x001C // 3 Byte +#define REG_BT_WIFI_ANTENNA_SWITCH_8188F 0x0038 +#define REG_HSISR_8188F 0x005c +#define REG_PAD_CTRL1_8188F 0x0064 +#define REG_AFE_CTRL_4_8188F 0x0078 +#define REG_HMEBOX_DBG_0_8188F 0x0088 +#define REG_HMEBOX_DBG_1_8188F 0x008A +#define REG_HMEBOX_DBG_2_8188F 0x008C +#define REG_HMEBOX_DBG_3_8188F 0x008E +#define REG_HIMR0_8188F 0x00B0 +#define REG_HISR0_8188F 0x00B4 +#define REG_HIMR1_8188F 0x00B8 +#define REG_HISR1_8188F 0x00BC +#define REG_PMC_DBG_CTRL2_8188F 0x00CC + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_C2HEVT_CMD_ID_8188F 0x01A0 +#define REG_C2HEVT_CMD_LEN_8188F 0x01AE +#define REG_WOWLAN_WAKE_REASON 0x01C7 +#define REG_WOWLAN_GTK_DBG1 0x630 +#define REG_WOWLAN_GTK_DBG2 0x634 + +#define REG_HMEBOX_EXT0_8188F 0x01F0 +#define REG_HMEBOX_EXT1_8188F 0x01F4 +#define REG_HMEBOX_EXT2_8188F 0x01F8 +#define REG_HMEBOX_EXT3_8188F 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_CONTROL_8188F 0x0286 // Control the RX DMA. +#define REG_RXDMA_MODE_CTRL_8188F 0x0290 + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8188F 0x0300 +#define REG_INT_MIG_8188F 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA_8188F 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA_8188F 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA_8188F 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA_8188F 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA_8188F 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA_8188F 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA_8188F 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA_8188F 0x0340 // RX Queue Descriptor Address +#define REG_DBI_WDATA_8188F 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8188F 0x034C // DBI Read Data +#define REG_DBI_ADDR_8188F 0x0350 // DBI Address +#define REG_DBI_FLAG_8188F 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8188F 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8188F 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8188F 0x0358 // MDIO for Control +#define REG_DBG_SEL_8188F 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM_8188F 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM_8188F 0x0363 //PCIe CPWM +#define REG_PCIE_MULTIFET_CTRL_8188F 0x036A //PCIE Multi-Fethc Control + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_TXPKTBUF_BCNQ_BDNY_8188F 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8188F 0x0425 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8188F 0x045D +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif +#define REG_AMPDU_BURST_MODE_8188F 0x04BC + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_SECONDARY_CCA_CTRL_8188F 0x0577 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + + +//============================================================ +// SDIO Bus Specification +//============================================================ + +//----------------------------------------------------- +// SDIO CMD Address Mapping +//----------------------------------------------------- + +//----------------------------------------------------- +// I/O bus domain (Host) +//----------------------------------------------------- + +//----------------------------------------------------- +// SDIO register +//----------------------------------------------------- +#define SDIO_REG_HIQ_FREEPG_8188F 0x0020 +#define SDIO_REG_MID_FREEPG_8188F 0x0022 +#define SDIO_REG_LOW_FREEPG_8188F 0x0024 +#define SDIO_REG_PUB_FREEPG_8188F 0x0026 +#define SDIO_REG_EXQ_FREEPG_8188F 0x0028 +#define SDIO_REG_AC_OQT_FREEPG_8188F 0x002A +#define SDIO_REG_NOAC_OQT_FREEPG_8188F 0x002B + +#define SDIO_REG_HCPWM1_8188F 0x0038 + +/* indirect access */ +#define SDIO_REG_INDIRECT_REG_CFG_8188F 0x40 +#define SET_INDIRECT_REG_ADDR(_cmd, _addr) SET_BITS_TO_LE_2BYTE(((u8 *)(_cmd)) + 0, 0, 16, (_addr)) +#define SET_INDIRECT_REG_SIZE_1BYTE(_cmd) SET_BITS_TO_LE_1BYTE(((u8 *)(_cmd)) + 2, 0, 2, 0) +#define SET_INDIRECT_REG_SIZE_2BYTE(_cmd) SET_BITS_TO_LE_1BYTE(((u8 *)(_cmd)) + 2, 0, 2, 1) +#define SET_INDIRECT_REG_SIZE_4BYTE(_cmd) SET_BITS_TO_LE_1BYTE(((u8 *)(_cmd)) + 2, 0, 2, 2) +#define SET_INDIRECT_REG_WRITE(_cmd) SET_BITS_TO_LE_1BYTE(((u8 *)(_cmd)) + 2, 2, 1, 1) +#define SET_INDIRECT_REG_READ(_cmd) SET_BITS_TO_LE_1BYTE(((u8 *)(_cmd)) + 2, 3, 1, 1) +#define GET_INDIRECT_REG_RDY(_cmd) LE_BITS_TO_1BYTE(((u8 *)(_cmd)) + 2, 4, 1) + +#define SDIO_REG_INDIRECT_REG_DATA_8188F 0x44 + +//============================================================================ +// 8188 Regsiter Bit and Content definition +//============================================================================ + +//2 HSISR +// interrupt mask which needs to clear +#define MASK_HSISR_CLEAR (HSISR_GPIO12_0_INT |\ + HSISR_SPS_OCP_INT |\ + HSISR_RON_INT |\ + HSISR_PDNINT |\ + HSISR_GPIO9_INT) + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define BIT_USB_RXDMA_AGG_EN BIT(31) +#define RXDMA_AGG_MODE_EN BIT(1) + +#ifdef CONFIG_WOWLAN +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) +#endif + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- + +//---------------------------------------------------------------------------- +// 8188F REG_CCK_CHECK (offset 0x454) +//---------------------------------------------------------------------------- +#define BIT_BCN_PORT_SEL BIT5 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8188F 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8188F BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8188F BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8188F BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8188F BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8188F BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8188F BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8188F BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8188F BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8188F BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8188F BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8188F BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8188F BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8188F BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8188F BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8188F BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8188F BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8188F BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8188F BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8188F BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8188F BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8188F BIT3 // AC_VI DMA OK +#define IMR_VODOK_8188F BIT2 // AC_VO DMA OK +#define IMR_RDU_8188F BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8188F BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8188F BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8188F BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8188F BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8188F BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8188F BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8188F BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8188F BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8188F BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8188F BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8188F BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8188F BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8188F BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8188F BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8188F BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8188F BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8188F BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8188F BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8188F BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8188F BIT8 // Receive FIFO Overflow + +#ifdef CONFIG_PCI_HCI +//#define IMR_RX_MASK (IMR_ROK_8188F|IMR_RDU_8188F|IMR_RXFOVW_8188F) +#define IMR_TX_MASK (IMR_VODOK_8188F|IMR_VIDOK_8188F|IMR_BEDOK_8188F|IMR_BKDOK_8188F|IMR_MGNTDOK_8188F|IMR_HIGHDOK_8188F) + +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8188F | IMR_TXBCN0OK_8188F | IMR_TXBCN0ERR_8188F | IMR_BCNDERR0_8188F) + +#define RT_AC_INT_MASKS (IMR_VIDOK_8188F | IMR_VODOK_8188F | IMR_BEDOK_8188F|IMR_BKDOK_8188F) +#endif + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8188F 16 +#define SEC_CAM_ENT_NUM_8188F 16 +#define NSS_NUM_8188F 1 +#define BAND_CAP_8188F (BAND_CAP_2G) +#define BW_CAP_8188F (BW_CAP_20M | BW_CAP_40M) + +#endif /* __RTL8188F_SPEC_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_sreset.h new file mode 100644 index 00000000..8a276241 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL8188F_SRESET_H_ +#define _RTL8188F_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8188f_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8188f_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_xmit.h new file mode 100644 index 00000000..265b8873 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8188f_xmit.h @@ -0,0 +1,336 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8188F_XMIT_H__ +#define __RTL8188F_XMIT_H__ + + +#define MAX_TID (15) + + +#ifndef __INC_HAL8188FDESC_H +#define __INC_HAL8188FDESC_H + +#define RX_STATUS_DESC_SIZE_8188F 24 +#define RX_DRV_INFO_SIZE_UNIT_8188F 8 + + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8188F(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8188F(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8188F(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8188F(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8188F(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8188F(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8188F(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + + +// Dword 0 +#define GET_TX_DESC_OWN_8188F(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +#define SET_TX_DESC_PKT_SIZE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) + + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_MBSSID_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) +#define SET_TX_DESC_ANTSEL_A_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#if(DEV_BUS_TYPE == RT_SDIO_INTERFACE) +#define SET_TX_DESC_SDIO_TXSEQ_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) + +// Dword 9 +#define SET_TX_DESC_SEQ_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) + +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_8188F(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+40, 0, 32) + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8188F(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) + + +#define SET_EARLYMODE_PKTNUM_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8188F(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +#endif +//----------------------------------------------------------- +// +// Rate +// +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC8188F_RATE1M 0x00 +#define DESC8188F_RATE2M 0x01 +#define DESC8188F_RATE5_5M 0x02 +#define DESC8188F_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC8188F_RATE6M 0x04 +#define DESC8188F_RATE9M 0x05 +#define DESC8188F_RATE12M 0x06 +#define DESC8188F_RATE18M 0x07 +#define DESC8188F_RATE24M 0x08 +#define DESC8188F_RATE36M 0x09 +#define DESC8188F_RATE48M 0x0a +#define DESC8188F_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC8188F_RATEMCS0 0x0c +#define DESC8188F_RATEMCS1 0x0d +#define DESC8188F_RATEMCS2 0x0e +#define DESC8188F_RATEMCS3 0x0f +#define DESC8188F_RATEMCS4 0x10 +#define DESC8188F_RATEMCS5 0x11 +#define DESC8188F_RATEMCS6 0x12 +#define DESC8188F_RATEMCS7 0x13 +#define DESC8188F_RATEMCS8 0x14 +#define DESC8188F_RATEMCS9 0x15 +#define DESC8188F_RATEMCS10 0x16 +#define DESC8188F_RATEMCS11 0x17 +#define DESC8188F_RATEMCS12 0x18 +#define DESC8188F_RATEMCS13 0x19 +#define DESC8188F_RATEMCS14 0x1a +#define DESC8188F_RATEMCS15 0x1b +#define DESC8188F_RATEVHTSS1MCS0 0x2c +#define DESC8188F_RATEVHTSS1MCS1 0x2d +#define DESC8188F_RATEVHTSS1MCS2 0x2e +#define DESC8188F_RATEVHTSS1MCS3 0x2f +#define DESC8188F_RATEVHTSS1MCS4 0x30 +#define DESC8188F_RATEVHTSS1MCS5 0x31 +#define DESC8188F_RATEVHTSS1MCS6 0x32 +#define DESC8188F_RATEVHTSS1MCS7 0x33 +#define DESC8188F_RATEVHTSS1MCS8 0x34 +#define DESC8188F_RATEVHTSS1MCS9 0x35 +#define DESC8188F_RATEVHTSS2MCS0 0x36 +#define DESC8188F_RATEVHTSS2MCS1 0x37 +#define DESC8188F_RATEVHTSS2MCS2 0x38 +#define DESC8188F_RATEVHTSS2MCS3 0x39 +#define DESC8188F_RATEVHTSS2MCS4 0x3a +#define DESC8188F_RATEVHTSS2MCS5 0x3b +#define DESC8188F_RATEVHTSS2MCS6 0x3c +#define DESC8188F_RATEVHTSS2MCS7 0x3d +#define DESC8188F_RATEVHTSS2MCS8 0x3e +#define DESC8188F_RATEVHTSS2MCS9 0x3f + + +#define RX_HAL_IS_CCK_RATE_8188F(pDesc)\ + (GET_RX_STATUS_DESC_RX_RATE_8188F(pDesc) == DESC8188F_RATE1M ||\ + GET_RX_STATUS_DESC_RX_RATE_8188F(pDesc) == DESC8188F_RATE2M ||\ + GET_RX_STATUS_DESC_RX_RATE_8188F(pDesc) == DESC8188F_RATE5_5M ||\ + GET_RX_STATUS_DESC_RX_RATE_8188F(pDesc) == DESC8188F_RATE11M) + + +void rtl8188f_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); +void rtl8188f_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8188fs_init_xmit_priv(PADAPTER padapter); +void rtl8188fs_free_xmit_priv(PADAPTER padapter); +s32 rtl8188fs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188fs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188fs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8188fs_xmit_buf_handler(PADAPTER padapter); +thread_return rtl8188fs_xmit_thread(thread_context context); +#define hal_xmit_handler rtl8188fs_xmit_buf_handler +#endif + +#ifdef CONFIG_USB_HCI +s32 rtl8188fu_xmit_buf_handler(PADAPTER padapter); +#define hal_xmit_handler rtl8188fu_xmit_buf_handler + + +s32 rtl8188fu_init_xmit_priv(PADAPTER padapter); +void rtl8188fu_free_xmit_priv(PADAPTER padapter); +s32 rtl8188fu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188fu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188fu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +//s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); +void rtl8188fu_xmit_tasklet(void *priv); +s32 rtl8188fu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8188fe_init_xmit_priv(PADAPTER padapter); +void rtl8188fe_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8188fe_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8188fe_xmitframe_resume(_adapter *padapter); +s32 rtl8188fe_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8188fe_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8188fe_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8188fe_xmit_tasklet(void *priv); +#endif + +u8 BWMapping_8188F(PADAPTER Adapter, struct pkt_attrib *pattrib); +u8 SCMapping_8188F(PADAPTER Adapter, struct pkt_attrib *pattrib); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_cmd.h new file mode 100644 index 00000000..28bebe30 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_cmd.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * + * 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 __RTL8192E_CMD_H__ +#define __RTL8192E_CMD_H__ + +typedef enum _RTL8192E_H2C_CMD +{ + H2C_8192E_RSVDPAGE = 0x00, + H2C_8192E_MSRRPT = 0x01, + H2C_8192E_SCAN = 0x02, + H2C_8192E_KEEP_ALIVE_CTRL = 0x03, + H2C_8192E_DISCONNECT_DECISION = 0x04, + H2C_8192E_INIT_OFFLOAD = 0x06, + H2C_8192E_AP_OFFLOAD = 0x08, + H2C_8192E_BCN_RSVDPAGE = 0x09, + H2C_8192E_PROBERSP_RSVDPAGE = 0x0a, + + H2C_8192E_AP_WOW_GPIO_CTRL = 0x13, + + H2C_8192E_SETPWRMODE = 0x20, + H2C_8192E_PS_TUNING_PARA = 0x21, + H2C_8192E_PS_TUNING_PARA2 = 0x22, + H2C_8192E_PS_LPS_PARA = 0x23, + H2C_8192E_P2P_PS_OFFLOAD = 0x24, + H2C_8192E_SAP_PS = 0x26, + H2C_8192E_RA_MASK = 0x40, + H2C_8192E_RSSI_REPORT = 0x42, + H2C_8192E_RA_PARA_ADJUST = 0x46, + + H2C_8192E_WO_WLAN = 0x80, + H2C_8192E_REMOTE_WAKE_CTRL = 0x81, + H2C_8192E_AOAC_GLOBAL_INFO = 0x82, + H2C_8192E_AOAC_RSVDPAGE = 0x83, + + //Not defined in new 88E H2C CMD Format + H2C_8192E_SELECTIVE_SUSPEND_ROF_CMD, + H2C_8192E_P2P_PS_MODE, + H2C_8192E_PSD_RESULT, + MAX_8192E_H2CCMD +}RTL8192E_H2C_CMD; + +struct cmd_msg_parm { + u8 eid; //element id + u8 sz; // sz + u8 buf[6]; +}; + +enum{ + PWRS +}; + +typedef struct _SETPWRMODE_PARM { + u8 Mode;//0:Active,1:LPS,2:WMMPS + //u8 RLBM:4;//0:Min,1:Max,2: User define + u8 SmartPS_RLBM;//LPS=0:PS_Poll,1:PS_Poll,2:NullData,WMM=0:PS_Poll,1:NullData + u8 AwakeInterval; // unit: beacon interval + u8 bAllQueueUAPSD; + u8 PwrState;//AllON(0x0c),RFON(0x04),RFOFF(0x00) +} SETPWRMODE_PARM, *PSETPWRMODE_PARM; + +struct H2C_SS_RFOFF_PARAM{ + u8 ROFOn; // 1: on, 0:off + u16 gpio_period; // unit: 1024 us +}__attribute__ ((packed)); + + +typedef struct JOINBSSRPT_PARM_92E{ + u8 OpMode; // RT_MEDIA_STATUS +#ifdef CONFIG_WOWLAN + u8 MacID; // MACID +#endif //CONFIG_WOWLAN +}JOINBSSRPT_PARM_92E, *PJOINBSSRPT_PARM_92E; + +/* move to hal_com_h2c.h +typedef struct _RSVDPAGE_LOC_92E { + u8 LocProbeRsp; + u8 LocPsPoll; + u8 LocNullData; + u8 LocQosNull; + u8 LocBTQosNull; +} RSVDPAGE_LOC_92E, *PRSVDPAGE_LOC_92E; +*/ + + +//_SETPWRMODE_PARM +#define SET_8192E_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8192E_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) +#define GET_8192E_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +//_P2P_PS_OFFLOAD +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_ROLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_CTWINDOW_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_NOA0_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_NOA1_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_8192E_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) + + +// host message to firmware cmd +void rtl8192e_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8192e_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus); +u8 rtl8192e_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8192e_set_raid_cmd(PADAPTER padapter, u32 bitmap, u8* arg); +void rtl8192e_Add_RateATid(PADAPTER padapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +s32 FillH2CCmd_8192E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +u8 GetTxBufferRsvdPageNum8192E(_adapter *padapter, bool wowlan); +//u8 rtl8192c_set_FwSelectSuspend_cmd(PADAPTER padapter, u8 bfwpoll, u16 period); +s32 c2h_handler_8192e(PADAPTER padapter, u8 *buf); +#ifdef CONFIG_BT_COEXIST +void rtl8192e_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); +#endif // CONFIG_BT_COEXIST +#ifdef CONFIG_P2P_PS +void rtl8192e_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +int reset_tsf(PADAPTER Adapter, u8 reset_port ); +#endif // CONFIG_TSF_RESET_OFFLOAD + + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void SetFwRelatedForWoWLAN8192E(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif +/// TX Feedback Content +#define USEC_UNIT_FOR_8192E_C2H_TX_RPT_QUEUE_TIME 256 + +#define GET_8192E_C2H_TX_RPT_QUEUE_SELECT(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 5) +#define GET_8192E_C2H_TX_RPT_PKT_BROCAST(_Header) LE_BITS_TO_1BYTE((_Header + 0), 5, 1) +#define GET_8192E_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1) +#define GET_8192E_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1) +#define GET_8192E_C2H_TX_RPT_MAC_ID(_Header) LE_BITS_TO_1BYTE((_Header + 1), 0, 8) +#define GET_8192E_C2H_TX_RPT_DATA_RETRY_CNT(_Header) LE_BITS_TO_1BYTE((_Header + 2), 0, 6) +#define GET_8192E_C2H_TX_RPT_QUEUE_TIME(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) // In unit of 256 microseconds. +#define GET_8192E_C2H_TX_RPT_FINAL_DATA_RATE(_Header) LE_BITS_TO_1BYTE((_Header + 5), 0, 8) + + + +void C2HContentParsing8192E( + IN PADAPTER Adapter, + IN u1Byte c2hCmdId, + IN u1Byte c2hCmdLen, + IN pu1Byte tmpBuf +); +VOID +C2HPacketHandler_8192E( + IN PADAPTER Adapter, + IN pu1Byte Buffer, + IN u1Byte Length +); + +#endif//__RTL8192E_CMD_H__ \ No newline at end of file diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_dm.h new file mode 100644 index 00000000..bb4f7a5e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_dm.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * 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 __RTL8192E_DM_H__ +#define __RTL8192E_DM_H__ + + +void rtl8192e_init_dm_priv(IN PADAPTER Adapter); +void rtl8192e_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8192e_InitHalDm(IN PADAPTER Adapter); +void rtl8192e_HalDmWatchDog(IN PADAPTER Adapter); + +//VOID rtl8192c_dm_CheckTXPowerTracking(IN PADAPTER Adapter); + +//void rtl8192c_dm_RF_Saving(IN PADAPTER pAdapter, IN u8 bForceInNormal); + +#ifdef CONFIG_ANTENNA_DIVERSITY +void AntDivCompare8192e(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +u8 AntDivBeforeLink8192e(PADAPTER Adapter ); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_hal.h new file mode 100644 index 00000000..97b8f193 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_hal.h @@ -0,0 +1,350 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __RTL8192E_HAL_H__ +#define __RTL8192E_HAL_H__ + +//#include "hal_com.h" + +#include "hal_data.h" + +//include HAL Related header after HAL Related compiling flags +#include "rtl8192e_spec.h" +#include "rtl8192e_rf.h" +#include "rtl8192e_dm.h" +#include "rtl8192e_recv.h" +#include "rtl8192e_xmit.h" +#include "rtl8192e_cmd.h" +#include "rtl8192e_led.h" +#include "Hal8192EPwrSeq.h" +#include "Hal8192EPhyReg.h" +#include "Hal8192EPhyCfg.h" + + +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8192e_sreset.h" +#endif + + +//--------------------------------------------------------------------- +// RTL8192E From header +//--------------------------------------------------------------------- + #define RTL8192E_FW_IMG "rtl8192e/FW_NIC.bin" + #define RTL8192E_FW_WW_IMG "rtl8192e/FW_WoWLAN.bin" + #define RTL8192E_PHY_REG "rtl8192e/PHY_REG.txt" + #define RTL8192E_PHY_RADIO_A "rtl8192e/RadioA.txt" + #define RTL8192E_PHY_RADIO_B "rtl8192e/RadioB.txt" + #define RTL8192E_TXPWR_TRACK "rtl8192e/TxPowerTrack.txt" + #define RTL8192E_AGC_TAB "rtl8192e/AGC_TAB.txt" + #define RTL8192E_PHY_MACREG "rtl8192e/MAC_REG.txt" + #define RTL8192E_PHY_REG_PG "rtl8192e/PHY_REG_PG.txt" + #define RTL8192E_PHY_REG_MP "rtl8192e/PHY_REG_MP.txt" + #define RTL8192E_TXPWR_LMT "rtl8192e/TXPWR_LMT.txt" + #define RTL8192E_WIFI_ANT_ISOLATION "rtl8192e/wifi_ant_isolation.txt" + +//--------------------------------------------------------------------- +// RTL8192E Power Configuration CMDs for PCIe interface +//--------------------------------------------------------------------- +#define Rtl8192E_NIC_PWR_ON_FLOW rtl8192E_power_on_flow +#define Rtl8192E_NIC_RF_OFF_FLOW rtl8192E_radio_off_flow +#define Rtl8192E_NIC_DISABLE_FLOW rtl8192E_card_disable_flow +#define Rtl8192E_NIC_ENABLE_FLOW rtl8192E_card_enable_flow +#define Rtl8192E_NIC_SUSPEND_FLOW rtl8192E_suspend_flow +#define Rtl8192E_NIC_RESUME_FLOW rtl8192E_resume_flow +#define Rtl8192E_NIC_PDN_FLOW rtl8192E_hwpdn_flow +#define Rtl8192E_NIC_LPS_ENTER_FLOW rtl8192E_enter_lps_flow +#define Rtl8192E_NIC_LPS_LEAVE_FLOW rtl8192E_leave_lps_flow + + +#if 1 // download firmware related data structure +#define FW_SIZE_8192E 0x8000 // Compatible with RTL8192e Maximal RAM code size 32k +#define FW_START_ADDRESS 0x1000 +#define FW_END_ADDRESS 0x5FFF + + +#define IS_FW_HEADER_EXIST_8192E(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE_8192E(_pFwHdr) &0xFFF0) == 0x92E0) + + + +typedef struct _RT_FIRMWARE_8192E { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_SIZE_8192E]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8192E, *PRT_FIRMWARE_8192E; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. + +//===================================================== +// Firmware Header(8-byte alinment required) +//===================================================== +//--- LONG WORD 0 ---- +#define GET_FIRMWARE_HDR_SIGNATURE_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 0, 16) // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut +#define GET_FIRMWARE_HDR_CATEGORY_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 16, 8) // AP/NIC and USB/PCI +#define GET_FIRMWARE_HDR_FUNCTION_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 24, 8) // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions +#define GET_FIRMWARE_HDR_VERSION_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 0, 16)// FW Version +#define GET_FIRMWARE_HDR_SUB_VER_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 16, 8) // FW Subversion, default 0x00 +#define GET_FIRMWARE_HDR_RSVD1_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 24, 8) + +//--- LONG WORD 1 ---- +#define GET_FIRMWARE_HDR_MONTH_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 0, 8) // Release time Month field +#define GET_FIRMWARE_HDR_DATE_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 8, 8) // Release time Date field +#define GET_FIRMWARE_HDR_HOUR_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 16, 8)// Release time Hour field +#define GET_FIRMWARE_HDR_MINUTE_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 24, 8)// Release time Minute field +#define GET_FIRMWARE_HDR_ROMCODE_SIZE_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 0, 16)// The size of RAM code +#define GET_FIRMWARE_HDR_RSVD2_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 16, 16) + +//--- LONG WORD 2 ---- +#define GET_FIRMWARE_HDR_SVN_IDX_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 0, 32)// The SVN entry index +#define GET_FIRMWARE_HDR_RSVD3_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 0, 32) + +//--- LONG WORD 3 ---- +#define GET_FIRMWARE_HDR_RSVD4_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 0, 32) +#define GET_FIRMWARE_HDR_RSVD5_8192E(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+28, 0, 32) + +#endif // download firmware related data structure + +#define DRIVER_EARLY_INT_TIME_8192E 0x05 +#define BCN_DMA_ATIME_INT_TIME_8192E 0x02 +#define RX_DMA_SIZE_8192E 0x4000 /* 16K*/ + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#ifdef CONFIG_FW_C2H_DEBUG + #define RX_DMA_RESERVED_SIZE_8192E 0x100 /* 256B, reserved for c2h debug message*/ +#else + #define RX_DMA_RESERVED_SIZE_8192E 0x40 /* 64B, reserved for c2h event(16bytes) or ccx(8 Bytes )*/ +#endif +#define MAX_RX_DMA_BUFFER_SIZE_8192E (RX_DMA_SIZE_8192E-RX_DMA_RESERVED_SIZE_8192E) /*RX 16K*/ + +//For General Reserved Page Number(Beacon Queue is reserved page) +//if (CONFIG_2BCN_EN) Beacon:4, PS-Poll:1, Null Data:1,Prob Rsp:1,Qos Null Data:1 +//Beacon:2, PS-Poll:1, Null Data:1,Prob Rsp:1,Qos Null Data:1 +#define RSVD_PAGE_NUM_8192E 0x08 +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8192E 0x07 +#else +#define WOWLAN_PAGE_NUM_8192E 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef WOWLAN_PAGE_NUM_8192E +#define WOWLAN_PAGE_NUM_8192E 0x0d +#endif + +/* Note: +Tx FIFO Size : 64KB +Tx page Size : 256B +Total page numbers : 256(0x100) +*/ + +#define TOTAL_RSVD_PAGE_NUMBER_8192E (RSVD_PAGE_NUM_8192E+WOWLAN_PAGE_NUM_8192E) + +#define TOTAL_PAGE_NUMBER_8192E (0x100) +#define TX_TOTAL_PAGE_NUMBER_8192E (TOTAL_PAGE_NUMBER_8192E - TOTAL_RSVD_PAGE_NUMBER_8192E) + +#define TX_PAGE_BOUNDARY_8192E ( TX_TOTAL_PAGE_NUMBER_8192E ) /* beacon header start address */ + + +#define PAGE_SIZE_TX_92E PAGE_SIZE_256 +#define RSVD_PKT_LEN_92E (TOTAL_RSVD_PAGE_NUMBER_8192E *PAGE_SIZE_TX_92E) + +#define TX_PAGE_LOAD_FW_BOUNDARY_8192E 0x47 //0xA5 +#define TX_PAGE_BOUNDARY_WOWLAN_8192E 0xE0 + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_92C + +#define NORMAL_PAGE_NUM_HPQ_8192E 0x10 +#define NORMAL_PAGE_NUM_LPQ_8192E 0x10 +#define NORMAL_PAGE_NUM_NPQ_8192E 0x10 +#define NORMAL_PAGE_NUM_EPQ_8192E 0x00 + + +//Note: For WMM Normal Chip Setting ,modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8192E NORMAL_PAGE_NUM_HPQ_8192E +#define WMM_NORMAL_PAGE_NUM_LPQ_8192E NORMAL_PAGE_NUM_LPQ_8192E +#define WMM_NORMAL_PAGE_NUM_NPQ_8192E NORMAL_PAGE_NUM_NPQ_8192E + + +//------------------------------------------------------------------------- +// Chip specific +//------------------------------------------------------------------------- + +// pic buffer descriptor +#define RTL8192EE_SEG_NUM TX_BUFFER_SEG_NUM +#define TX_DESC_NUM_92E 128 +#define RX_DESC_NUM_92E 128 + +//------------------------------------------------------------------------- +// Channel Plan +//------------------------------------------------------------------------- + +#define HWSET_MAX_SIZE_8192E 512 + +#define EFUSE_REAL_CONTENT_LEN_8192E 512 + +#define EFUSE_MAP_LEN_8192E 512 +#define EFUSE_MAX_SECTION_8192E 64 +#define EFUSE_MAX_WORD_UNIT_8192E 4 +#define EFUSE_IC_ID_OFFSET_8192E 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR_8192E(addr) (addr < EFUSE_REAL_CONTENT_LEN_8192E) +// +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 1byte|----8bytes----|1byte|--5bytes--| +// | | Reserved(14bytes) | +// +#define EFUSE_OOB_PROTECT_BYTES_8192E 15 // PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. + + + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_BANK_CONTENT_LEN_8192E 512 +#define EFUSE_BT_REAL_CONTENT_LEN_8192E 1024 // 512*2 +#define EFUSE_BT_MAP_LEN_8192E 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION_8192E 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK_8192E 16 +#define EFUSE_MAX_BANK_8192E 3 +//=========================================================== + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +//#define IS_MULTI_FUNC_CHIP(_Adapter) (((((PHAL_DATA_TYPE)(_Adapter->HalData))->MultiFunc) & (RT_MULTI_FUNC_BT|RT_MULTI_FUNC_GPS)) ? _TRUE : _FALSE) + +//#define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) + +// rtl8812_hal_init.c +void _8051Reset8192E(PADAPTER padapter); +s32 FirmwareDownload8192E(PADAPTER Adapter, BOOLEAN bUsedWoWLANFw); +void InitializeFirmwareVars8192E(PADAPTER padapter); + +s32 InitLLTTable8192E(PADAPTER padapter, u8 txpktbuf_bndy); + +// EFuse +u8 GetEEPROMSize8192E(PADAPTER padapter); +void hal_InitPGData_8192E(PADAPTER padapter, u8* PROMContent); +void Hal_EfuseParseIDCode8192E(PADAPTER padapter, u8 *hwinfo); +void Hal_ReadPROMVersion8192E(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_ReadPowerSavingMode8192E(PADAPTER padapter, u8* hwinfo, BOOLEAN AutoLoadFail); +void Hal_ReadTxPowerInfo8192E(PADAPTER padapter,u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadBoardType8192E(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadThermalMeter_8192E(PADAPTER Adapter,u8* PROMContent,BOOLEAN AutoloadFail); +void Hal_ReadChannelPlan8192E(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8192E(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadAntennaDiversity8192E(PADAPTER pAdapter,u8* PROMContent,BOOLEAN AutoLoadFail); +void Hal_ReadPAType_8192E(PADAPTER Adapter,u8* PROMContent, BOOLEAN AutoloadFail); +void Hal_ReadAmplifierType_8192E(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +void Hal_ReadRFEType_8192E(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +void Hal_EfuseParseBTCoexistInfo8192E(PADAPTER Adapter, u8* hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseKFreeData_8192E(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); + +u8 Hal_CrystalAFEAdjust(_adapter * Adapter); + +BOOLEAN HalDetectPwrDownMode8192E(PADAPTER Adapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +/***********************************************************/ +// RTL8192E-MAC Setting +VOID _InitQueueReservedPage_8192E(IN PADAPTER Adapter); +VOID _InitQueuePriority_8192E(IN PADAPTER Adapter); +VOID _InitTxBufferBoundary_8192E(IN PADAPTER Adapter,IN u8 txpktbuf_bndy); +VOID _InitPageBoundary_8192E(IN PADAPTER Adapter); +//VOID _InitTransferPageSize_8192E(IN PADAPTER Adapter); +VOID _InitDriverInfoSize_8192E(IN PADAPTER Adapter,IN u8 drvInfoSize); +VOID _InitRDGSetting_8192E(PADAPTER Adapter); +void _InitID_8192E(IN PADAPTER Adapter); +VOID _InitNetworkType_8192E(IN PADAPTER Adapter); +VOID _InitWMACSetting_8192E(IN PADAPTER Adapter); +VOID _InitAdaptiveCtrl_8192E(IN PADAPTER Adapter); +VOID _InitRateFallback_8192E(IN PADAPTER Adapter); +VOID _InitEDCA_8192E( IN PADAPTER Adapter); +VOID _InitRetryFunction_8192E( IN PADAPTER Adapter); +VOID _BBTurnOnBlock_8192E(IN PADAPTER Adapter); +VOID _InitBeaconParameters_8192E(IN PADAPTER Adapter); +VOID _InitBeaconMaxError_8192E( + IN PADAPTER Adapter, + IN BOOLEAN InfraMode + ); +void SetBeaconRelatedRegisters8192E(PADAPTER padapter); +VOID hal_ReadRFType_8192E(PADAPTER Adapter); +// RTL8192E-MAC Setting +/***********************************************************/ + +void SetHwReg8192E(PADAPTER Adapter, u8 variable, u8* val); +void GetHwReg8192E(PADAPTER Adapter, u8 variable, u8* val); +u8 +SetHalDefVar8192E( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ); +u8 +GetHalDefVar8192E( + IN PADAPTER Adapter, + IN HAL_DEF_VARIABLE eVariable, + IN PVOID pValue + ); + +void rtl8192e_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8192e(_adapter *adapter); +void rtl8192e_init_default_value(_adapter * padapter); +// register +void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits); + +void rtl8192e_start_thread(_adapter *padapter); +void rtl8192e_stop_thread(_adapter *padapter); + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8192EE(PADAPTER Adapter); +u16 get_txdesc_buf_addr(u16 ff_hwaddr); +#endif + +#ifdef CONFIG_SDIO_HCI +#ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT +void _init_available_page_threshold(PADAPTER padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ); +#endif +#endif + +#ifdef CONFIG_BT_COEXIST +void rtl8192e_combo_card_WifiOnlyHwInit(PADAPTER Adapter); +#endif + +#endif //__RTL8192E_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_led.h new file mode 100644 index 00000000..221e0aa2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * 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 __RTL8192E_LED_H__ +#define __RTL8192E_LED_H__ + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8192eu_InitSwLeds(PADAPTER padapter); +void rtl8192eu_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8192ee_InitSwLeds(PADAPTER padapter); +void rtl8192ee_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_SDIO_HCI +void rtl8192es_InitSwLeds(PADAPTER padapter); +void rtl8192es_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_recv.h new file mode 100644 index 00000000..766a677f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_recv.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * 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 __RTL8192E_RECV_H__ +#define __RTL8192E_RECV_H__ + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifdef CONFIG_MINIMAL_MEMORY_USAGE + #define MAX_RECVBUF_SZ (4000) // about 4K + #else + #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + #define MAX_RECVBUF_SZ (rtw_rtkm_get_buff_size()) /*depend rtkm*/ + #elif defined(CONFIG_PLATFORM_HISILICON) + #define MAX_RECVBUF_SZ (16384) /* 16k */ + #else + #define MAX_RECVBUF_SZ (32768) /* 32k */ + #endif + //#define MAX_RECVBUF_SZ (20480) //20K + //#define MAX_RECVBUF_SZ (10240) //10K + //#define MAX_RECVBUF_SZ (16384) // 16k - 92E RX BUF :16K + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) + +#define MAX_RECVBUF_SZ (16384) + +#endif + + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +//============= +// [1] Rx Buffer Descriptor (for PCIE) buffer descriptor architecture +//DWORD 0 +#define SET_RX_BUFFER_DESC_DATA_LENGTH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc,__Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 15, 1, __Value) +#define SET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 16, 1, __Value) +#define SET_RX_BUFFER_DESC_TOTAL_LENGTH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 16, 15, __Value) + +#define GET_RX_BUFFER_DESC_OWN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) +#define GET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 1) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 15) + + +//DWORD 1 +#define SET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+4, 0, 32, __Value) +#define GET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 0, 32) + +//DWORD 2 +#define SET_RX_BUFFER_PHYSICAL_HIGH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+8, 0, 32, __Value) + +//============= +// [2] Rx Descriptor +//DWORD 0 +#define GET_RX_STATUS_DESC_PKT_LEN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICVERR_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_EOR_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + + +#define SET_RX_STATUS_DESC_PKT_LEN_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_MACID_VLD_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 12, 1) +#define GET_RX_STATUS_DESC_AMSDU_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FITS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_CHKERR_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_IPVER_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_IS_TCPUDP_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_CHK_VLD_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) + +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_HWRSVD_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 24, 4) +#define GET_RX_STATUS_DESC_FCS_OK_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 31, 1) +#define GET_RX_STATUS_DESC_RPT_SEL_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#define GET_RX_STATUS_DESC_DMA_AGG_NUM_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) + +#define GET_RX_STATUS_DESC_PATTERN_MATCH_92E(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_92E(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_WAKE_92E(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_92E(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + + +#ifdef CONFIG_SDIO_HCI +s32 rtl8192es_init_recv_priv(PADAPTER padapter); +void rtl8192es_free_recv_priv(PADAPTER padapter); +void rtl8192es_recv_hdl(PADAPTER padapter, struct recv_buf *precvbuf); +#endif + +#ifdef CONFIG_USB_HCI +void rtl8192eu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +s32 rtl8192eu_init_recv_priv(PADAPTER padapter); +void rtl8192eu_free_recv_priv(PADAPTER padapter); +void rtl8192eu_recv_hdl(PADAPTER padapter, struct recv_buf *precvbuf); +void rtl8192eu_recv_tasklet(void *priv); + +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8192ee_init_recv_priv(PADAPTER padapter); +void rtl8192ee_free_recv_priv(PADAPTER padapter); +#endif + +void rtl8192e_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); + +#endif /* __RTL8192E_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_rf.h new file mode 100644 index 00000000..fec92256 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_rf.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __RTL8192E_RF_H__ +#define __RTL8192E_RF_H__ + +VOID +PHY_RF6052SetBandwidth8192E( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + + +int +PHY_RF6052_Config_8192E( + IN PADAPTER Adapter ); + +#endif//__RTL8192E_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_spec.h new file mode 100644 index 00000000..6ecfbeb5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_spec.h @@ -0,0 +1,327 @@ +/****************************************************************************** + * + * 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 __RTL8192E_SPEC_H__ +#define __RTL8192E_SPEC_H__ + +#include + + +//============================================================ +// 8192E Regsiter offset definition +//============================================================ + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_SWR_CTRL1_8192E 0x0010 // 1 Byte +#define REG_SYS_SWR_CTRL2_8192E 0x0014 // 1 Byte +#define REG_AFE_CTRL1_8192E 0x0024 +#define REG_AFE_CTRL2_8192E 0x0028 +#define REG_AFE_CTRL3_8192E 0x002c + +#define REG_PAD_CTRL1_8192E 0x0064 +#define REG_SDIO_CTRL_8192E 0x0070 +#define REG_OPT_CTRL_8192E 0x0074 +#define REG_RF_B_CTRL_8192E 0x0076 +#define REG_AFE_CTRL4_8192E 0x0078 +#define REG_LDO_SWR_CTRL 0x007C +#define REG_FW_DRV_MSG_8192E 0x0088 +#define REG_HMEBOX_E2_E3_8192E 0x008C +#define REG_HIMR0_8192E 0x00B0 +#define REG_HISR0_8192E 0x00B4 +#define REG_HIMR1_8192E 0x00B8 +#define REG_HISR1_8192E 0x00BC + +#define REG_SYS_CFG1_8192E 0x00F0 +#define REG_SYS_CFG2_8192E 0x00FC +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) +#define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) +#define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) +#define REG_WOWLAN_WAKE_REASON REG_MCUTST_WOWLAN + +#define REG_RSVD3_8192E 0x0168 +#define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 +#define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 +#define REG_C2HEVT_CMD_LEN_88XX 0x01AE + +#define REG_HMEBOX_EXT0_8192E 0x01F0 +#define REG_HMEBOX_EXT1_8192E 0x01F4 +#define REG_HMEBOX_EXT2_8192E 0x01F8 +#define REG_HMEBOX_EXT3_8192E 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_DWBCN0_CTRL 0x0208 +#define REG_DWBCN1_CTRL 0x0228 + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_8192E 0x0290 +#define REG_EARLY_MODE_CONTROL_8192E 0x02BC + +#define REG_RSVD5_8192E 0x02F0 +#define REG_RSVD6_8192E 0x02F4 +#define REG_RSVD7_8192E 0x02F8 +#define REG_RSVD8_8192E 0x02FC + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8192E 0x0300 +#define REG_INT_MIG_8192E 0x0304 // Interrupt Migration +#define REG_BCNQ_TXBD_DESA_8192E 0x0308 // TX Beacon Descriptor Address +#define REG_MGQ_TXBD_DESA_8192E 0x0310 // TX Manage Queue Descriptor Address +#define REG_VOQ_TXBD_DESA_8192E 0x0318 // TX VO Queue Descriptor Address +#define REG_VIQ_TXBD_DESA_8192E 0x0320 // TX VI Queue Descriptor Address +#define REG_BEQ_TXBD_DESA_8192E 0x0328 // TX BE Queue Descriptor Address +#define REG_BKQ_TXBD_DESA_8192E 0x0330 // TX BK Queue Descriptor Address +#define REG_RXQ_RXBD_DESA_8192E 0x0338 // RX Queue Descriptor Address +#define REG_HI0Q_TXBD_DESA_8192E 0x0340 +#define REG_HI1Q_TXBD_DESA_8192E 0x0348 +#define REG_HI2Q_TXBD_DESA_8192E 0x0350 +#define REG_HI3Q_TXBD_DESA_8192E 0x0358 +#define REG_HI4Q_TXBD_DESA_8192E 0x0360 +#define REG_HI5Q_TXBD_DESA_8192E 0x0368 +#define REG_HI6Q_TXBD_DESA_8192E 0x0370 +#define REG_HI7Q_TXBD_DESA_8192E 0x0378 +#define REG_MGQ_TXBD_NUM_8192E 0x0380 +#define REG_RX_RXBD_NUM_8192E 0x0382 +#define REG_VOQ_TXBD_NUM_8192E 0x0384 +#define REG_VIQ_TXBD_NUM_8192E 0x0386 +#define REG_BEQ_TXBD_NUM_8192E 0x0388 +#define REG_BKQ_TXBD_NUM_8192E 0x038A +#define REG_HI0Q_TXBD_NUM_8192E 0x038C +#define REG_HI1Q_TXBD_NUM_8192E 0x038E +#define REG_HI2Q_TXBD_NUM_8192E 0x0390 +#define REG_HI3Q_TXBD_NUM_8192E 0x0392 +#define REG_HI4Q_TXBD_NUM_8192E 0x0394 +#define REG_HI5Q_TXBD_NUM_8192E 0x0396 +#define REG_HI6Q_TXBD_NUM_8192E 0x0398 +#define REG_HI7Q_TXBD_NUM_8192E 0x039A +#define REG_TSFTIMER_HCI_8192E 0x039C + +//Read Write Point +#define REG_VOQ_TXBD_IDX_8192E 0x03A0 +#define REG_VIQ_TXBD_IDX_8192E 0x03A4 +#define REG_BEQ_TXBD_IDX_8192E 0x03A8 +#define REG_BKQ_TXBD_IDX_8192E 0x03AC +#define REG_MGQ_TXBD_IDX_8192E 0x03B0 +#define REG_RXQ_TXBD_IDX_8192E 0x03B4 +#define REG_HI0Q_TXBD_IDX_8192E 0x03B8 +#define REG_HI1Q_TXBD_IDX_8192E 0x03BC +#define REG_HI2Q_TXBD_IDX_8192E 0x03C0 +#define REG_HI3Q_TXBD_IDX_8192E 0x03C4 +#define REG_HI4Q_TXBD_IDX_8192E 0x03C8 +#define REG_HI5Q_TXBD_IDX_8192E 0x03CC +#define REG_HI6Q_TXBD_IDX_8192E 0x03D0 +#define REG_HI7Q_TXBD_IDX_8192E 0x03D4 + +#define REG_PCIE_HCPWM_8192EE 0x03D8 // ?????? +#define REG_PCIE_HRPWM_8192EE 0x03DC //PCIe RPWM // ?????? +#define REG_DBI_WDATA_V1_8192E 0x03E8 +#define REG_DBI_RDATA_V1_8192E 0x03EC +#define REG_DBI_FLAG_V1_8192E 0x03F0 +#define REG_MDIO_V1_8192E 0x3F4 +#define REG_PCIE_MIX_CFG_8192E 0x3F8 + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_TXBF_CTRL_8192E 0x042C +#define REG_ARFR0_8192E 0x0444 +#define REG_ARFR1_8192E 0x044C +#define REG_CCK_CHECK_8192E 0x0454 +#define REG_AMPDU_MAX_TIME_8192E 0x0456 +#define REG_BCNQ1_BDNY_8192E 0x0457 + +#define REG_AMPDU_MAX_LENGTH_8192E 0x0458 +#define REG_WMAC_LBK_BUF_HD_8192E 0x045D +#define REG_NDPA_OPT_CTRL_8192E 0x045F +#define REG_DATA_SC_8192E 0x0483 +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif +#define REG_ARFR2_8192E 0x048C +#define REG_ARFR3_8192E 0x0494 +#define REG_TXRPT_START_OFFSET 0x04AC +#define REG_AMPDU_BURST_MODE_8192E 0x04BC +#define REG_HT_SINGLE_AMPDU_8192E 0x04C7 +#define REG_MACID_PKT_DROP0_8192E 0x04D0 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_CTWND_8192E 0x0572 +#define REG_SECONDARY_CCA_CTRL_8192E 0x0577 +#define REG_SCH_TXCMD_8192E 0x05F8 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8192E 0x0600 + +#define REG_MAC_TX_SM_STATE_8192E 0x06B4 + +// Power +#define REG_BFMER0_INFO_8192E 0x06E4 +#define REG_BFMER1_INFO_8192E 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8192E 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8192E 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8192E 0x06FC + +// Hardware Port 2 +#define REG_BFMEE_SEL_8192E 0x0714 +#define REG_SND_PTCL_CTRL_8192E 0x0718 + + +//----------------------------------------------------- +// +// Redifine register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define ISR_8192E REG_HISR0_8192E + +//---------------------------------------------------------------------------- +// 8192E IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8192E 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8192E BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8192E BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8192E BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8192E BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8192E BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8192E BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8192E BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8192E BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8192E BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8192E BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8192E BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8192E BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8192E BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8192E BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8192E BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8192E BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8192E BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8192E BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8192E BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8192E BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8192E BIT3 // AC_VI DMA OK +#define IMR_VODOK_8192E BIT2 // AC_VO DMA OK +#define IMR_RDU_8192E BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8192E BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8192E BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8192E BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8192E BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8192E BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8192E BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8192E BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8192E BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8192E BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8192E BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8192E BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8192E BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8192E BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8192E BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8192E BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8192E BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8192E BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8192E BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8192E BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8192E BIT8 // Receive FIFO Overflow + +//---------------------------------------------------------------------------- +// 8192E Auto LLT bits (offset 0x224, 8bits) +//---------------------------------------------------------------------------- +//224 REG_AUTO_LLT +// move to hal_com_reg.h + +//---------------------------------------------------------------------------- +// 8192E Auto LLT bits (offset 0x290, 32bits) +//---------------------------------------------------------------------------- +#define BIT_DMA_MODE BIT1 +#define BIT_USB_RXDMA_AGG_EN BIT31 + +//---------------------------------------------------------------------------- +// 8192E REG_SYS_CFG1 (offset 0xF0, 32bits) +//---------------------------------------------------------------------------- +#define BIT_SPSLDO_SEL BIT24 + + +//---------------------------------------------------------------------------- +// 8192E REG_CCK_CHECK (offset 0x454, 8bits) +//---------------------------------------------------------------------------- +#define BIT_BCN_PORT_SEL BIT5 + +//============================================================================ +// Regsiter Bit and Content definition +//============================================================================ + +//2 ACMHWCTRL 0x05C0 +#define AcmHw_HwEn_8192E BIT(0) +#define AcmHw_VoqEn_8192E BIT(1) +#define AcmHw_ViqEn_8192E BIT(2) +#define AcmHw_BeqEn_8192E BIT(3) +#define AcmHw_VoqStatus_8192E BIT(5) +#define AcmHw_ViqStatus_8192E BIT(6) +#define AcmHw_BeqStatus_8192E BIT(7) + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8192E 128 +#define SEC_CAM_ENT_NUM_8192E 64 +#define NSS_NUM_8192E 2 +#define BAND_CAP_8192E (BAND_CAP_2G) +#define BW_CAP_8192E (BW_CAP_20M | BW_CAP_40M) + +#endif //__RTL8192E_SPEC_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_sreset.h new file mode 100644 index 00000000..ea2f19f0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL88812A_SRESET_H_ +#define _RTL8812A_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8192e_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8192e_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_xmit.h new file mode 100644 index 00000000..37e00887 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8192e_xmit.h @@ -0,0 +1,451 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 __RTL8192E_XMIT_H__ +#define __RTL8192E_XMIT_H__ + +typedef struct txdescriptor_8192e +{ + //Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 ls:1; + u32 fs:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + //Offset 4 + u32 macid:6; + u32 rsvd0406:2; + u32 qsel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rate_id:4; + u32 navusehdr:1; + u32 en_desc_id:1; + u32 sectype:2; + u32 rsvd0424:2; + u32 pkt_offset:5; // unit: 8 bytes + u32 rsvd0431:1; + + //Offset 8 + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rd_en:1; + u32 bar_rty_th:2; + u32 bk:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdu_density:3; + u32 bt_null:1; + u32 ant_sel_a:1; + u32 ant_sel_b:1; + u32 tx_ant_cck:2; + u32 tx_antl:2; + u32 tx_ant_ht:2; + + //Offset 12 + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + //Offset 16 + u32 rtsrate:5; + u32 ap_dcfe:1; + u32 hwseq_sel:2; + u32 userate:1; + u32 disrtsfb:1; + u32 disdatafb:1; + u32 cts2self:1; + u32 rtsen:1; + u32 hw_rts_en:1; + u32 port_id:1; + u32 pwr_status:3; + u32 wait_dcts:1; + u32 cts2ap_en:1; + u32 data_sc:2; + u32 data_stbc:2; + u32 data_short:1; + u32 data_bw:1; + u32 rts_short:1; + u32 rts_bw:1; + u32 rts_sc:2; + u32 vcs_stbc:2; + + //Offset 20 + u32 datarate:6; + u32 sgi:1; + u32 try_rate:1; + u32 data_ratefb_lmt:5; + u32 rts_ratefb_lmt:4; + u32 rty_lmt_en:1; + u32 data_rt_lmt:6; + u32 usb_txagg_num:8; + + //Offset 24 + u32 txagg_a:5; + u32 txagg_b:5; + u32 use_max_len:1; + u32 max_agg_num:5; + u32 mcsg1_max_len:4; + u32 mcsg2_max_len:4; + u32 mcsg3_max_len:4; + u32 mcs7_sgi_max_len:4; + + //Offset 28 + u32 checksum:16; // TxBuffSize(PCIe)/CheckSum(USB) + u32 mcsg4_max_len:4; + u32 mcsg5_max_len:4; + u32 mcsg6_max_len:4; + u32 mcs15_sgi_max_len:4; +}TXDESC_8192E, *PTXDESC_8192E; + + + +//For 88e early mode +#define SET_EARLYMODE_PKTNUM(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 3, __Value) +#define SET_EARLYMODE_LEN0(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 12, __Value) +#define SET_EARLYMODE_LEN1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 16, 12, __Value) +#define SET_EARLYMODE_LEN2_1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 28, 4, __Value) +#define SET_EARLYMODE_LEN2_2(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 8, __Value) +#define SET_EARLYMODE_LEN3(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 8, 12, __Value) +#define SET_EARLYMODE_LEN4(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 20, 12, __Value) + +// +//defined for TX DESC Operation +// + +#define MAX_TID (15) + +//OFFSET 0 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define BMC BIT(24) +#define LSG BIT(26) +#define FSG BIT(27) +#define OWN BIT(31) + + +//OFFSET 4 +#define PKT_OFFSET_SZ 0 +#define QSEL_SHT 8 +#define RATE_ID_SHT 16 +#define NAVUSEHDR BIT(20) +#define SEC_TYPE_SHT 22 +#define PKT_OFFSET_SHT 26 + +//OFFSET 8 +#define AGG_EN BIT(12) +#define AGG_BK BIT(16) +#define AMPDU_DENSITY_SHT 20 +#define ANTSEL_A BIT(24) +#define ANTSEL_B BIT(25) +#define TX_ANT_CCK_SHT 26 +#define TX_ANTL_SHT 28 +#define TX_ANT_HT_SHT 30 + +//OFFSET 12 +#define SEQ_SHT 16 +#define EN_HWSEQ BIT(31) + +//OFFSET 16 +#define QOS BIT(6) +#define HW_SSN BIT(7) +#define USERATE BIT(8) +#define DISDATAFB BIT(10) +#define CTS_2_SELF BIT(11) +#define RTS_EN BIT(12) +#define HW_RTS_EN BIT(13) +#define DATA_SHORT BIT(24) +#define PWR_STATUS_SHT 15 +#define DATA_SC_SHT 20 +#define DATA_BW BIT(25) + +//OFFSET 20 +#define RTY_LMT_EN BIT(17) + + +//OFFSET 20 +#define SGI BIT(6) +#define USB_TXAGG_NUM_SHT 24 + + +//=====Tx Desc Buffer content + +// config element for each tx buffer +/* +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) +*/ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) + + +// Dword 0 +#define SET_TX_BUFF_DESC_LEN_0_92E(__pTxDesc, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 14, __Valeu) +#define SET_TX_BUFF_DESC_PSB_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 15, __Value) +#define SET_TX_BUFF_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +// Dword 1 +#define SET_TX_BUFF_DESC_ADDR_LOW_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_92E(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+4, 0,32) + + +// Dword 2 +#define SET_TX_BUFF_DESC_ADDR_HIGH_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 32, __Value) +// Dword 3, RESERVED + + +//=====Tx Desc content +// Dword 0 +#define SET_TX_DESC_PKT_SIZE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +#define GET_TX_DESC_OWN_92E(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +// Dword 1 +#define SET_TX_DESC_MACID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) +#define SET_TX_DESC_MORE_DATA_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 29, 1, __Value) +#define SET_TX_DESC_TXOP_PS_CAP_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 30, 1, __Value) +#define SET_TX_DESC_TXOP_PS_MODE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 31, 1, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_NULL_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 14, 1, __Value) +#define SET_TX_DESC_NULL_1_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 15, 1, __Value) +#define SET_TX_DESC_BK_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define GET_TX_DESC_MORE_FRAG_92E(__pTxDesc) LE_BITS_TO_4BYTE( __pTxDesc+8, 17, 1) +#define SET_TX_DESC_SPE_RPT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_NULL_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_HW_PORT_ID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 14, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_TRY_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 7, 1, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) +#define SET_TX_DESC_PCTS_ENABLE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 29, 1, __Value) +#define SET_TX_DESC_PCTS_MASK_IDX_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 30, 2, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_VCS_STBC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) +#define SET_TX_DESC_TX_ANT_92E(__pTxDesc,__Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 24, 4, __Value) +#define SET_TX_DESC_TX_POWER_0_PSET_92E(__pTxDesc,__Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 28, 3, __Value) + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_MBSSID_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) +#define SET_TX_DESC_ANTSEL_A_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) + + +//#define SET_TX_DESC_HWSEQ_EN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) +// Dword 8 + +#define SET_TX_DESC_RTS_RC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 0, 6, __Value) +#define SET_TX_DESC_BAR_RTY_TH_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 6, 2, __Value) +#define SET_TX_DESC_DATA_RC_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 8, 6, __Value) +#define SET_TX_DESC_EN_HWSEQ_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) +#define SET_TX_DESC_NEXT_HEAD_PAGE_92E(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 16, 8, __Value) +#define SET_TX_DESC_TAIL_PAGE_92E(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 24, 8, __Value) + +// Dword 9 +#define SET_TX_DESC_PADDING_LENGTH_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 0, 11, __Value) +#define SET_TX_DESC_TXBF_PATH_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 11, 1, __Value) +#define SET_TX_DESC_SEQ_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) +#define SET_TX_DESC_FINAL_DATA_RATE_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 24, 8, __Value) + + +#define SET_EARLYMODE_PKTNUM_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_92E(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); + +#ifdef CONFIG_USB_HCI +s32 rtl8192eu_init_xmit_priv(PADAPTER padapter); +void rtl8192eu_free_xmit_priv(PADAPTER padapter); +s32 rtl8192eu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8192eu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8192eu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8192eu_xmit_buf_handler(PADAPTER padapter); +#define hal_xmit_handler rtl8192eu_xmit_buf_handler +void rtl8192eu_xmit_tasklet(void *priv); +s32 rtl8192eu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8192ee_init_xmit_priv(PADAPTER padapter); +void rtl8192ee_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8192ee_dequeue_xmitbuf(struct rtw_tx_ring *ring); +s32 rtl8192ee_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8192ee_xmitframe_resume(_adapter *padapter); +s32 rtl8192ee_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8192ee_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +void rtl8192ee_xmit_tasklet(void *priv); +#endif + +#if defined(CONFIG_SDIO_HCI)||defined (CONFIG_GSPI_HCI) +s32 rtl8192es_init_xmit_priv(PADAPTER padapter); +void rtl8192es_free_xmit_priv(PADAPTER padapter); + +s32 rtl8192es_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8192es_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8192es_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +thread_return rtl8192es_xmit_thread(thread_context context); +s32 rtl8192es_xmit_buf_handler(PADAPTER padapter); + +#ifdef CONFIG_SDIO_TX_TASKLET +void rtl8192es_xmit_tasklet(void *priv); +#endif +#endif + +struct txrpt_ccx_92e { + /* offset 0 */ + u8 tag1:1; + u8 pkt_num:3; + u8 txdma_underflow:1; + u8 int_bt:1; + u8 int_tri:1; + u8 int_ccx:1; + + /* offset 1 */ + u8 mac_id:6; + u8 pkt_ok:1; + u8 bmc:1; + + /* offset 2 */ + u8 retry_cnt:6; + u8 lifetime_over:1; + u8 retry_over:1; + + /* offset 3 */ + u8 ccx_qtime0; + u8 ccx_qtime1; + + /* offset 5 */ + u8 final_data_rate; + + /* offset 6 */ + u8 sw1:4; + u8 qsel:4; + + /* offset 7 */ + u8 sw0; +}; + +#ifdef CONFIG_TX_EARLY_MODE +void UpdateEarlyModeInfo8192E(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf ); +#endif + s32 rtl8192e_init_xmit_priv(_adapter *padapter); +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,u8 *ptxdesc); + +void rtl8192e_fill_fake_txdesc(PADAPTER padapter,u8*pDesc,u32 BufferLen, + u8 IsPsPoll,u8 IsBTQosNull, u8 bDataFrame); +void rtl8192e_cal_txdesc_chksum(u8 *ptxdesc); + +u8 BWMapping_92E(PADAPTER Adapter, struct pkt_attrib *pattrib); +u8 SCMapping_92E(PADAPTER Adapter, struct pkt_attrib *pattrib); +void fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); +void fill_txdesc_vcs(struct pkt_attrib *pattrib, u8 *ptxdesc); +void fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); +void rtl8192e_fixed_rate(_adapter *padapter,u8 *ptxdesc); + +#endif //__RTL8192E_XMIT_H__ + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_cmd.h new file mode 100644 index 00000000..972bed5f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_cmd.h @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8703B_CMD_H__ +#define __RTL8703B_CMD_H__ + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD DEFINITION ------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +enum h2c_cmd_8703B{ + //Common Class: 000 + H2C_8703B_RSVD_PAGE = 0x00, + H2C_8703B_MEDIA_STATUS_RPT = 0x01, + H2C_8703B_SCAN_ENABLE = 0x02, + H2C_8703B_KEEP_ALIVE = 0x03, + H2C_8703B_DISCON_DECISION = 0x04, + H2C_8703B_PSD_OFFLOAD = 0x05, + H2C_8703B_AP_OFFLOAD = 0x08, + H2C_8703B_BCN_RSVDPAGE = 0x09, + H2C_8703B_PROBERSP_RSVDPAGE = 0x0A, + H2C_8703B_FCS_RSVDPAGE = 0x10, + H2C_8703B_FCS_INFO = 0x11, + H2C_8703B_AP_WOW_GPIO_CTRL = 0x13, + + //PoweSave Class: 001 + H2C_8703B_SET_PWR_MODE = 0x20, + H2C_8703B_PS_TUNING_PARA = 0x21, + H2C_8703B_PS_TUNING_PARA2 = 0x22, + H2C_8703B_P2P_LPS_PARAM = 0x23, + H2C_8703B_P2P_PS_OFFLOAD = 0x24, + H2C_8703B_PS_SCAN_ENABLE = 0x25, + H2C_8703B_SAP_PS_ = 0x26, + H2C_8703B_INACTIVE_PS_ = 0x27, //Inactive_PS + H2C_8703B_FWLPS_IN_IPS_ = 0x28, + + //Dynamic Mechanism Class: 010 + H2C_8703B_MACID_CFG = 0x40, + H2C_8703B_TXBF = 0x41, + H2C_8703B_RSSI_SETTING = 0x42, + H2C_8703B_AP_REQ_TXRPT = 0x43, + H2C_8703B_INIT_RATE_COLLECT = 0x44, + H2C_8703B_RA_PARA_ADJUST = 0x46, + + //BT Class: 011 + H2C_8703B_B_TYPE_TDMA = 0x60, + H2C_8703B_BT_INFO = 0x61, + H2C_8703B_FORCE_BT_TXPWR = 0x62, + H2C_8703B_BT_IGNORE_WLANACT = 0x63, + H2C_8703B_DAC_SWING_VALUE = 0x64, + H2C_8703B_ANT_SEL_RSV = 0x65, + H2C_8703B_WL_OPMODE = 0x66, + H2C_8703B_BT_MP_OPER = 0x67, + H2C_8703B_BT_CONTROL = 0x68, + H2C_8703B_BT_WIFI_CTRL = 0x69, + H2C_8703B_BT_FW_PATCH = 0x6A, + H2C_8703B_BT_WLAN_CALIBRATION = 0x6D, + + //WOWLAN Class: 100 + H2C_8703B_WOWLAN = 0x80, + H2C_8703B_REMOTE_WAKE_CTRL = 0x81, + H2C_8703B_AOAC_GLOBAL_INFO = 0x82, + H2C_8703B_AOAC_RSVD_PAGE = 0x83, + H2C_8703B_AOAC_RSVD_PAGE2 = 0x84, + H2C_8703B_D0_SCAN_OFFLOAD_CTRL = 0x85, + H2C_8703B_D0_SCAN_OFFLOAD_INFO = 0x86, + H2C_8703B_CHNL_SWITCH_OFFLOAD = 0x87, + H2C_8703B_P2P_OFFLOAD_RSVD_PAGE = 0x8A, + H2C_8703B_P2P_OFFLOAD = 0x8B, + + H2C_8703B_RESET_TSF = 0xC0, + H2C_8703B_MAXID, +}; + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD CONTENT --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_8703B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8703B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8703B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8703B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_KEEP_ALIVE_CMD_0x03 +#define SET_8703B_H2CCMD_KEEPALIVE_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8703B_H2CCMD_KEEPALIVE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8703B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8703B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +//_DISCONNECT_DECISION_CMD_0x04 +#define SET_8703B_H2CCMD_DISCONDECISION_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8703B_H2CCMD_DISCONDECISION_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8703B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8703B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +// _PWR_MOD_CMD_0x20 +#define SET_8703B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8703B_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +#define GET_8703B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +// _PS_TUNE_PARAM_CMD_0x21 +#define SET_8703B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8703B_H2CCMD_PSTUNE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 1, __Value) +#define SET_8703B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 1, 7, __Value) +#define SET_8703B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +//_MACID_CFG_CMD_0x40 +#define SET_8703B_H2CCMD_MACID_CFG_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_RAID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 5, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_SGI_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 2, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_NO_UPDATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 3, 1, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_VHT_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 4, 2, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_DISPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 6, 1, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_DISRA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_RATE_MASK0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_RATE_MASK1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_RATE_MASK2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value) +#define SET_8703B_H2CCMD_MACID_CFG_RATE_MASK3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value) + +//_RSSI_SETTING_CMD_0x42 +#define SET_8703B_H2CCMD_RSSI_SETTING_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_RSSI_SETTING_RSSI(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value) +#define SET_8703B_H2CCMD_RSSI_SETTING_ULDL_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +// _AP_REQ_TXRPT_CMD_0x43 +#define SET_8703B_H2CCMD_APREQRPT_PARM_MACID1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8703B_H2CCMD_APREQRPT_PARM_MACID2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +// _FORCE_BT_TXPWR_CMD_0x62 +#define SET_8703B_H2CCMD_BT_PWR_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) + +// _FORCE_BT_MP_OPER_CMD_0x67 +#define SET_8703B_H2CCMD_BT_MPOPER_VER(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) +#define SET_8703B_H2CCMD_BT_MPOPER_REQNUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value) +#define SET_8703B_H2CCMD_BT_MPOPER_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_MPOPER_PARAM1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_MPOPER_PARAM2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_MPOPER_PARAM3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) + +// _BT_FW_PATCH_0x6A +#define SET_8703B_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_2BYTE((pu1Byte)(__pH2CCmd), 0, 16, __Value) +#define SET_8703B_H2CCMD_BT_FW_PATCH_ADDR0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_FW_PATCH_ADDR1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_FW_PATCH_ADDR2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8703B_H2CCMD_BT_FW_PATCH_ADDR3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +//---------------------------------------------------------------------------------------------------------// +//------------------------------------------- Structure --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- Function Statement --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +// host message to firmware cmd +void rtl8703b_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8703b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus); +void rtl8703b_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8703b_Add_RateATid(PADAPTER pAdapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +void rtl8703b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack); +//s32 rtl8703b_set_lowpwr_lps_cmd(PADAPTER padapter, u8 enable); +void rtl8703b_set_FwPsTuneParam_cmd(PADAPTER padapter); +void rtl8703b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask); +void rtl8703b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param); +void rtl8703b_download_rsvd_page(PADAPTER padapter, u8 mstatus); +#ifdef CONFIG_BT_COEXIST +void rtl8703b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); +#endif // CONFIG_BT_COEXIST +#ifdef CONFIG_P2P +void rtl8703b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void SetFwRelatedForWoWLAN8703b(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif//CONFIG_WOWLAN + +#ifdef CONFIG_P2P_WOWLAN +void rtl8703b_set_p2p_wowlan_offload_cmd(PADAPTER padapter); +#endif + +void rtl8703b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +u8 rtl8703b_reset_tsf(_adapter *padapter, u8 reset_port); +#endif // CONFIG_TSF_RESET_OFFLOAD +s32 FillH2CCmd8703B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +u8 GetTxBufferRsvdPageNum8703B(_adapter *padapter, bool wowlan); +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_dm.h new file mode 100644 index 00000000..094adc85 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_dm.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * 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 __RTL8703B_DM_H__ +#define __RTL8703B_DM_H__ +//============================================================ +// Description: +// +// This file is for 8703B dynamic mechanism only +// +// +//============================================================ + +//============================================================ +// structure and define +//============================================================ + +//============================================================ +// function prototype +//============================================================ + +void rtl8703b_init_dm_priv(PADAPTER padapter); +void rtl8703b_deinit_dm_priv(PADAPTER padapter); + +void rtl8703b_InitHalDm(PADAPTER padapter); +void rtl8703b_HalDmWatchDog(PADAPTER padapter); +void rtl8703b_HalDmWatchDog_in_LPS(PADAPTER padapter); +void rtl8703b_hal_dm_in_lps(PADAPTER padapter); + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_hal.h new file mode 100644 index 00000000..69a6dc5f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_hal.h @@ -0,0 +1,326 @@ +/****************************************************************************** + * + * 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 __RTL8703B_HAL_H__ +#define __RTL8703B_HAL_H__ + +#include "hal_data.h" + +#include "rtl8703b_spec.h" +#include "rtl8703b_rf.h" +#include "rtl8703b_dm.h" +#include "rtl8703b_recv.h" +#include "rtl8703b_xmit.h" +#include "rtl8703b_cmd.h" +#include "rtl8703b_led.h" +#include "Hal8703BPwrSeq.h" +#include "Hal8703BPhyReg.h" +#include "Hal8703BPhyCfg.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8703b_sreset.h" +#endif + + +//--------------------------------------------------------------------- +// RTL8703B From file +//--------------------------------------------------------------------- + #define RTL8703B_FW_IMG "rtl8703b/FW_NIC.bin" + #define RTL8703B_FW_WW_IMG "rtl8703b/FW_WoWLAN.bin" + #define RTL8703B_PHY_REG "rtl8703b/PHY_REG.txt" + #define RTL8703B_PHY_RADIO_A "rtl8703b/RadioA.txt" + #define RTL8703B_PHY_RADIO_B "rtl8703b/RadioB.txt" + #define RTL8703B_TXPWR_TRACK "rtl8703b/TxPowerTrack.txt" + #define RTL8703B_AGC_TAB "rtl8703b/AGC_TAB.txt" + #define RTL8703B_PHY_MACREG "rtl8703b/MAC_REG.txt" + #define RTL8703B_PHY_REG_PG "rtl8703b/PHY_REG_PG.txt" + #define RTL8703B_PHY_REG_MP "rtl8703b/PHY_REG_MP.txt" + #define RTL8703B_TXPWR_LMT "rtl8703b/TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8703B From header +//--------------------------------------------------------------------- + +#if MP_DRIVER == 1 + #define Rtl8703B_FwBTImgArray Rtl8703BFwBTImgArray + #define Rtl8703B_FwBTImgArrayLength Rtl8703BFwBTImgArrayLength + + #define Rtl8703B_PHY_REG_Array_MP Rtl8703B_PHYREG_Array_MP + #define Rtl8703B_PHY_REG_Array_MPLength Rtl8703B_PHYREG_Array_MPLength +#endif + + +#define FW_8703B_SIZE 0x8000 +#define FW_8703B_START_ADDRESS 0x1000 +#define FW_8703B_END_ADDRESS 0x1FFF //0x5FFF + +#define IS_FW_HEADER_EXIST_8703B(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x03B0) + +typedef struct _RT_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_8703B_SIZE]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8703B, *PRT_FIRMWARE_8703B; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8703B_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u16 Subversion; // FW Subversion, default 0x00 + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8703B_FIRMWARE_HDR, *PRT_8703B_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME_8703B 0x05 +#define BCN_DMA_ATIME_INT_TIME_8703B 0x02 + +// for 8703B +// TX 32K, RX 16K, Page size 128B for TX, 8B for RX +#define PAGE_SIZE_TX_8703B 128 +#define PAGE_SIZE_RX_8703B 8 + +#define TX_DMA_SIZE_8703B 0x8000 /* 32K(TX) */ +#define RX_DMA_SIZE_8703B 0x4000 /* 16K(RX) */ + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#ifdef CONFIG_FW_C2H_DEBUG +#define RX_DMA_RESERVED_SIZE_8703B 0x100 // 256B, reserved for c2h debug message +#else +#define RX_DMA_RESERVED_SIZE_8703B 0x80 // 128B, reserved for tx report +#endif +#define RX_DMA_BOUNDARY_8703B (RX_DMA_SIZE_8703B - RX_DMA_RESERVED_SIZE_8703B - 1) + + +// Note: We will divide number of page equally for each queue other than public queue! + +//For General Reserved Page Number(Beacon Queue is reserved page) +//Beacon:2, PS-Poll:1, Null Data:1,Qos Null Data:1,BT Qos Null Data:1 +#define BCNQ_PAGE_NUM_8703B 0x08 +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8703B 0x08 // 0x04 +#else +#define BCNQ1_PAGE_NUM_8703B 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef BCNQ1_PAGE_NUM_8703B +#define BCNQ1_PAGE_NUM_8703B 0x00 // 0x04 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8703B 0x07 +#else +#define WOWLAN_PAGE_NUM_8703B 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef WOWLAN_PAGE_NUM_8703B +#define WOWLAN_PAGE_NUM_8703B 0x15 +#endif + +#ifdef CONFIG_AP_WOWLAN +#define AP_WOWLAN_PAGE_NUM_8703B 0x02 +#endif + +#define TX_TOTAL_PAGE_NUMBER_8703B (0xFF - BCNQ_PAGE_NUM_8703B - BCNQ1_PAGE_NUM_8703B - WOWLAN_PAGE_NUM_8703B) +#define TX_PAGE_BOUNDARY_8703B (TX_TOTAL_PAGE_NUMBER_8703B + 1) + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8703B TX_TOTAL_PAGE_NUMBER_8703B +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8703B (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8703B + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8703B +#define NORMAL_PAGE_NUM_HPQ_8703B 0x0C +#define NORMAL_PAGE_NUM_LPQ_8703B 0x02 +#define NORMAL_PAGE_NUM_NPQ_8703B 0x02 + +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8703B 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8703B 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8703B 0x20 + + +#include "HalVerDef.h" +#include "hal_com.h" + +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define HAL_EFUSE_MEMORY + +#define HWSET_MAX_SIZE_8703B 256 +#define EFUSE_REAL_CONTENT_LEN_8703B 256 +#define EFUSE_MAP_LEN_8703B 512 +#define EFUSE_MAX_SECTION_8703B 64 + +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN_8703B) + +#define EFUSE_ACCESS_ON 0x69 +#define EFUSE_ACCESS_OFF 0x00 + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define BANK_NUM 1 +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 128 +#define EFUSE_BT_REAL_CONTENT_LEN (EFUSE_BT_REAL_BANK_CONTENT_LEN * BANK_NUM) +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION (EFUSE_BT_MAP_LEN / 8) +#define EFUSE_PROTECT_BYTES_BANK 16 + +typedef struct _C2H_EVT_HDR +{ + u8 CmdID; + u8 CmdLen; + u8 CmdSeq; +} __attribute__((__packed__)) C2H_EVT_HDR, *PC2H_EVT_HDR; + +typedef enum tag_Package_Definition +{ + PACKAGE_DEFAULT, + PACKAGE_QFN68, + PACKAGE_TFBGA90, + PACKAGE_TFBGA80, + PACKAGE_TFBGA79 +}PACKAGE_TYPE_E; + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +// rtl8703b_hal_init.c +s32 rtl8703b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void rtl8703b_FirmwareSelfReset(PADAPTER padapter); +void rtl8703b_InitializeFirmwareVars(PADAPTER padapter); + +void rtl8703b_InitAntenna_Selection(PADAPTER padapter); +void rtl8703b_DeinitAntenna_Selection(PADAPTER padapter); +void rtl8703b_CheckAntenna_Selection(PADAPTER padapter); +void rtl8703b_init_default_value(PADAPTER padapter); + +s32 rtl8703b_InitLLTTable(PADAPTER padapter); + +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU); +s32 CardDisableWithoutHWSM(PADAPTER padapter); + +// EFuse +u8 GetEEPROMSize8703B(PADAPTER padapter); +void Hal_InitPGData(PADAPTER padapter, u8 *PROMContent); +void Hal_EfuseParseIDCode(PADAPTER padapter, u8 *hwinfo); +void Hal_EfuseParseTxPowerInfo_8703B(PADAPTER padapter, u8 *PROMContent, BOOLEAN AutoLoadFail); +void Hal_EfuseParseBTCoexistInfo_8703B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseEEPROMVer_8703B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseChnlPlan_8703B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID_8703B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseAntennaDiversity_8703B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8703B(PADAPTER pAdapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseThermalMeter_8703B(PADAPTER padapter, u8 *hwinfo, u8 AutoLoadFail); +VOID Hal_EfuseParseMacHidden_8703B(PADAPTER pAdapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +VOID Hal_EfuseParseVoltage_8703B(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +VOID Hal_EfuseParseBoardType_8703B(PADAPTER Adapter, u8* PROMContent,BOOLEAN AutoloadFail); + +#ifdef CONFIG_C2H_PACKET_EN +void rtl8703b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length); +#endif + + +void rtl8703b_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8703b(_adapter *adapter); +void SetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val); +#ifdef CONFIG_C2H_PACKET_EN +void SetHwRegWithBuf8703B(PADAPTER padapter, u8 variable, u8 *pbuf, int len); +#endif // CONFIG_C2H_PACKET_EN +u8 SetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); + +// register +void rtl8703b_InitBeaconParameters(PADAPTER padapter); +void rtl8703b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode); +void _InitBurstPktLen_8703BS(PADAPTER Adapter); +void _InitLTECoex_8703BS(PADAPTER Adapter); +void _InitMacAPLLSetting_8703B(PADAPTER Adapter); +void _8051Reset8703(PADAPTER padapter); +#ifdef CONFIG_WOWLAN +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void rtl8703b_start_thread(_adapter *padapter); +void rtl8703b_stop_thread(_adapter *padapter); + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +void rtl8703bs_init_checkbthang_workqueue(_adapter * adapter); +void rtl8703bs_free_checkbthang_workqueue(_adapter * adapter); +void rtl8703bs_cancle_checkbthang_workqueue(_adapter * adapter); +void rtl8703bs_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_8703b(PADAPTER padapter, u8 *pdata, u8 len); +s32 c2h_id_filter_ccx_8703b(u8 *buf); +s32 c2h_handler_8703b(PADAPTER padapter, u8 *pC2hEvent); +u8 MRateToHwRate8703B(u8 rate); +u8 HwRateToMRate8703B(u8 rate); + +void Hal_ReadRFGainOffset(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8703BE(PADAPTER Adapter); +VOID UpdateInterruptMask8703BE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_led.h new file mode 100644 index 00000000..1be67548 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_led.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 __RTL8703B_LED_H__ +#define __RTL8703B_LED_H__ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8703bu_InitSwLeds(PADAPTER padapter); +void rtl8703bu_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_SDIO_HCI +void rtl8703bs_InitSwLeds(PADAPTER padapter); +void rtl8703bs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_GSPI_HCI +void rtl8703bs_InitSwLeds(PADAPTER padapter); +void rtl8703bs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8703be_InitSwLeds(PADAPTER padapter); +void rtl8703be_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_recv.h new file mode 100644 index 00000000..024f912a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_recv.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * 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 __RTL8703B_RECV_H__ +#define __RTL8703B_RECV_H__ + +#define RECV_BLK_SZ 512 +#define RECV_BLK_CNT 16 +#define RECV_BLK_TH RECV_BLK_CNT + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + //#define MAX_RECVBUF_SZ (32768) // 32k + //#define MAX_RECVBUF_SZ (16384) //16K + //#define MAX_RECVBUF_SZ (10240) //10K + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#define MAX_RECVBUF_SZ (10240) + +#endif + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#ifdef CONFIG_SDIO_HCI +#ifndef CONFIG_SDIO_RX_COPY +#undef MAX_RECVBUF_SZ +#define MAX_RECVBUF_SZ (RX_DMA_SIZE_8703B - RX_DMA_RESERVED_SIZE_8703B) +#endif // !CONFIG_SDIO_RX_COPY +#endif // CONFIG_SDIO_HCI + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8703bs_init_recv_priv(PADAPTER padapter); +void rtl8703bs_free_recv_priv(PADAPTER padapter); +#endif + +#ifdef CONFIG_USB_HCI +int rtl8703bu_init_recv_priv(_adapter *padapter); +void rtl8703bu_free_recv_priv (_adapter *padapter); +void rtl8703bu_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8703be_init_recv_priv(PADAPTER padapter); +void rtl8703be_free_recv_priv(PADAPTER padapter); +#endif + +void rtl8703b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); + +#endif /* __RTL8703B_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_rf.h new file mode 100644 index 00000000..20e7268a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_rf.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * 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 __RTL8703B_RF_H__ +#define __RTL8703B_RF_H__ + +int PHY_RF6052_Config8703B( IN PADAPTER Adapter ); + +VOID +PHY_RF6052SetBandwidth8703B( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_spec.h new file mode 100644 index 00000000..d83e1e30 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_spec.h @@ -0,0 +1,479 @@ +/****************************************************************************** + * + * 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 __RTL8703B_SPEC_H__ +#define __RTL8703B_SPEC_H__ + +#include + + +#define HAL_NAV_UPPER_UNIT_8703B 128 // micro-second + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL_8703B 0x0000 // 2 Byte +#define REG_SYS_FUNC_EN_8703B 0x0002 // 2 Byte +#define REG_APS_FSMCO_8703B 0x0004 // 4 Byte +#define REG_SYS_CLKR_8703B 0x0008 // 2 Byte +#define REG_9346CR_8703B 0x000A // 2 Byte +#define REG_EE_VPD_8703B 0x000C // 2 Byte +#define REG_AFE_MISC_8703B 0x0010 // 1 Byte +#define REG_SPS0_CTRL_8703B 0x0011 // 7 Byte +#define REG_SPS_OCP_CFG_8703B 0x0018 // 4 Byte +#define REG_RSV_CTRL_8703B 0x001C // 3 Byte +#define REG_RF_CTRL_8703B 0x001F // 1 Byte +#define REG_LPLDO_CTRL_8703B 0x0023 // 1 Byte +#define REG_AFE_XTAL_CTRL_8703B 0x0024 // 4 Byte +#define REG_AFE_PLL_CTRL_8703B 0x0028 // 4 Byte +#define REG_MAC_PLL_CTRL_EXT_8703B 0x002c // 4 Byte +#define REG_EFUSE_CTRL_8703B 0x0030 +#define REG_EFUSE_TEST_8703B 0x0034 +#define REG_PWR_DATA_8703B 0x0038 +#define REG_CAL_TIMER_8703B 0x003C +#define REG_ACLK_MON_8703B 0x003E +#define REG_GPIO_MUXCFG_8703B 0x0040 +#define REG_GPIO_IO_SEL_8703B 0x0042 +#define REG_MAC_PINMUX_CFG_8703B 0x0043 +#define REG_GPIO_PIN_CTRL_8703B 0x0044 +#define REG_GPIO_INTM_8703B 0x0048 +#define REG_LEDCFG0_8703B 0x004C +#define REG_LEDCFG1_8703B 0x004D +#define REG_LEDCFG2_8703B 0x004E +#define REG_LEDCFG3_8703B 0x004F +#define REG_FSIMR_8703B 0x0050 +#define REG_FSISR_8703B 0x0054 +#define REG_HSIMR_8703B 0x0058 +#define REG_HSISR_8703B 0x005c +#define REG_GPIO_EXT_CTRL 0x0060 +#define REG_PAD_CTRL1_8703B 0x0064 +#define REG_MULTI_FUNC_CTRL_8703B 0x0068 +#define REG_GPIO_STATUS_8703B 0x006C +#define REG_SDIO_CTRL_8703B 0x0070 +#define REG_OPT_CTRL_8703B 0x0074 +#define REG_AFE_CTRL_4_8703B 0x0078 +#define REG_MCUFWDL_8703B 0x0080 +#define REG_HMEBOX_DBG_0_8703B 0x0088 +#define REG_HMEBOX_DBG_1_8703B 0x008A +#define REG_HMEBOX_DBG_2_8703B 0x008C +#define REG_HMEBOX_DBG_3_8703B 0x008E +#define REG_HIMR0_8703B 0x00B0 +#define REG_HISR0_8703B 0x00B4 +#define REG_HIMR1_8703B 0x00B8 +#define REG_HISR1_8703B 0x00BC +#define REG_PMC_DBG_CTRL2_8703B 0x00CC +#define REG_EFUSE_BURN_GNT_8703B 0x00CF +#define REG_HPON_FSM_8703B 0x00EC +#define REG_SYS_CFG_8703B 0x00F0 +#define REG_SYS_CFG1_8703B 0x00FC +#define REG_ROM_VERSION 0x00FD + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_C2HEVT_CMD_ID_8703B 0x01A0 +#define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 +#define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 +#define REG_C2HEVT_CMD_LEN_8703B 0x01AE +#define REG_C2HEVT_CMD_LEN_88XX REG_C2HEVT_CMD_LEN_8703B +#define REG_C2HEVT_CLEAR_8703B 0x01AF +#define REG_MCUTST_1_8703B 0x01C0 +#define REG_WOWLAN_WAKE_REASON 0x01C7 +#define REG_FMETHR_8703B 0x01C8 +#define REG_HMETFR_8703B 0x01CC +#define REG_HMEBOX_0_8703B 0x01D0 +#define REG_HMEBOX_1_8703B 0x01D4 +#define REG_HMEBOX_2_8703B 0x01D8 +#define REG_HMEBOX_3_8703B 0x01DC +#define REG_LLT_INIT_8703B 0x01E0 +#define REG_HMEBOX_EXT0_8703B 0x01F0 +#define REG_HMEBOX_EXT1_8703B 0x01F4 +#define REG_HMEBOX_EXT2_8703B 0x01F8 +#define REG_HMEBOX_EXT3_8703B 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN_8703B 0x0200 +#define REG_FIFOPAGE_8703B 0x0204 +#define REG_DWBCN0_CTRL_8703B REG_TDECTRL +#define REG_TXDMA_OFFSET_CHK_8703B 0x020C +#define REG_TXDMA_STATUS_8703B 0x0210 +#define REG_RQPN_NPQ_8703B 0x0214 +#define REG_DWBCN1_CTRL_8703B 0x0228 + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH_8703B 0x0280 +#define REG_FW_UPD_RDPTR_8703B 0x0284 // FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 +#define REG_RXDMA_CONTROL_8703B 0x0286 // Control the RX DMA. +#define REG_RXPKT_NUM_8703B 0x0287 // The number of packets in RXPKTBUF. +#define REG_RXDMA_STATUS_8703B 0x0288 +#define REG_RXDMA_MODE_CTRL_8703B 0x0290 +#define REG_EARLY_MODE_CONTROL_8703B 0x02BC +#define REG_RSVD5_8703B 0x02F0 +#define REG_RSVD6_8703B 0x02F4 + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8703B 0x0300 +#define REG_INT_MIG_8703B 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA_8703B 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA_8703B 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA_8703B 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA_8703B 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA_8703B 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA_8703B 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA_8703B 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA_8703B 0x0340 // RX Queue Descriptor Address +#define REG_DBI_WDATA_8703B 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8703B 0x034C // DBI Read Data +#define REG_DBI_ADDR_8703B 0x0350 // DBI Address +#define REG_DBI_FLAG_8703B 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8703B 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8703B 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8703B 0x0358 // MDIO for Control +#define REG_DBG_SEL_8703B 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM_8703B 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM_8703B 0x0363 //PCIe CPWM +#define REG_PCIE_MULTIFET_CTRL_8703B 0x036A //PCIE Multi-Fethc Control + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_VOQ_INFORMATION_8703B 0x0400 +#define REG_VIQ_INFORMATION_8703B 0x0404 +#define REG_BEQ_INFORMATION_8703B 0x0408 +#define REG_BKQ_INFORMATION_8703B 0x040C +#define REG_MGQ_INFORMATION_8703B 0x0410 +#define REG_HGQ_INFORMATION_8703B 0x0414 +#define REG_BCNQ_INFORMATION_8703B 0x0418 +#define REG_TXPKT_EMPTY_8703B 0x041A + +#define REG_FWHW_TXQ_CTRL_8703B 0x0420 +#define REG_HWSEQ_CTRL_8703B 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY_8703B 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8703B 0x0425 +#define REG_LIFECTRL_CTRL_8703B 0x0426 +#define REG_MULTI_BCNQ_OFFSET_8703B 0x0427 +#define REG_SPEC_SIFS_8703B 0x0428 +#define REG_RL_8703B 0x042A +#define REG_TXBF_CTRL_8703B 0x042C +#define REG_DARFRC_8703B 0x0430 +#define REG_RARFRC_8703B 0x0438 +#define REG_RRSR_8703B 0x0440 +#define REG_ARFR0_8703B 0x0444 +#define REG_ARFR1_8703B 0x044C +#define REG_CCK_CHECK_8703B 0x0454 +#define REG_AMPDU_MAX_TIME_8703B 0x0456 +#define REG_TXPKTBUF_BCNQ_BDNY1_8703B 0x0457 + +#define REG_AMPDU_MAX_LENGTH_8703B 0x0458 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8703B 0x045D +#define REG_NDPA_OPT_CTRL_8703B 0x045F +#define REG_FAST_EDCA_CTRL_8703B 0x0460 +#define REG_RD_RESP_PKT_TH_8703B 0x0463 +#define REG_DATA_SC_8703B 0x0483 +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif +#define REG_TXRPT_START_OFFSET 0x04AC +#define REG_POWER_STAGE1_8703B 0x04B4 +#define REG_POWER_STAGE2_8703B 0x04B8 +#define REG_AMPDU_BURST_MODE_8703B 0x04BC +#define REG_PKT_VO_VI_LIFE_TIME_8703B 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME_8703B 0x04C2 +#define REG_STBC_SETTING_8703B 0x04C4 +#define REG_HT_SINGLE_AMPDU_8703B 0x04C7 +#define REG_PROT_MODE_CTRL_8703B 0x04C8 +#define REG_MAX_AGGR_NUM_8703B 0x04CA +#define REG_RTS_MAX_AGGR_NUM_8703B 0x04CB +#define REG_BAR_MODE_CTRL_8703B 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT_8703B 0x04CF +#define REG_MACID_PKT_DROP0_8703B 0x04D0 +#define REG_MACID_PKT_SLEEP_8703B 0x04D4 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM_8703B 0x0500 +#define REG_EDCA_VI_PARAM_8703B 0x0504 +#define REG_EDCA_BE_PARAM_8703B 0x0508 +#define REG_EDCA_BK_PARAM_8703B 0x050C +#define REG_BCNTCFG_8703B 0x0510 +#define REG_PIFS_8703B 0x0512 +#define REG_RDG_PIFS_8703B 0x0513 +#define REG_SIFS_CTX_8703B 0x0514 +#define REG_SIFS_TRX_8703B 0x0516 +#define REG_AGGR_BREAK_TIME_8703B 0x051A +#define REG_SLOT_8703B 0x051B +#define REG_TX_PTCL_CTRL_8703B 0x0520 +#define REG_TXPAUSE_8703B 0x0522 +#define REG_DIS_TXREQ_CLR_8703B 0x0523 +#define REG_RD_CTRL_8703B 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT_8703B 0x0540 +#define REG_RD_NAV_NXT_8703B 0x0544 +#define REG_NAV_PROT_LEN_8703B 0x0546 +#define REG_BCN_CTRL_8703B 0x0550 +#define REG_BCN_CTRL_1_8703B 0x0551 +#define REG_MBID_NUM_8703B 0x0552 +#define REG_DUAL_TSF_RST_8703B 0x0553 +#define REG_BCN_INTERVAL_8703B 0x0554 +#define REG_DRVERLYINT_8703B 0x0558 +#define REG_BCNDMATIM_8703B 0x0559 +#define REG_ATIMWND_8703B 0x055A +#define REG_USTIME_TSF_8703B 0x055C +#define REG_BCN_MAX_ERR_8703B 0x055D +#define REG_RXTSF_OFFSET_CCK_8703B 0x055E +#define REG_RXTSF_OFFSET_OFDM_8703B 0x055F +#define REG_TSFTR_8703B 0x0560 +#define REG_CTWND_8703B 0x0572 +#define REG_SECONDARY_CCA_CTRL_8703B 0x0577 +#define REG_PSTIMER_8703B 0x0580 +#define REG_TIMER0_8703B 0x0584 +#define REG_TIMER1_8703B 0x0588 +#define REG_ACMHWCTRL_8703B 0x05C0 +#define REG_SCH_TXCMD_8703B 0x05F8 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8703B 0x0600 +#define REG_TCR_8703B 0x0604 +#define REG_RCR_8703B 0x0608 +#define REG_RX_PKT_LIMIT_8703B 0x060C +#define REG_RX_DLK_TIME_8703B 0x060D +#define REG_RX_DRVINFO_SZ_8703B 0x060F + +#define REG_MACID_8703B 0x0610 +#define REG_BSSID_8703B 0x0618 +#define REG_MAR_8703B 0x0620 +#define REG_MBIDCAMCFG_8703B 0x0628 +#define REG_WOWLAN_GTK_DBG1 0x630 +#define REG_WOWLAN_GTK_DBG2 0x634 + +#define REG_USTIME_EDCA_8703B 0x0638 +#define REG_MAC_SPEC_SIFS_8703B 0x063A +#define REG_RESP_SIFP_CCK_8703B 0x063C +#define REG_RESP_SIFS_OFDM_8703B 0x063E +#define REG_ACKTO_8703B 0x0640 +#define REG_CTS2TO_8703B 0x0641 +#define REG_EIFS_8703B 0x0642 + +#define REG_NAV_UPPER_8703B 0x0652 // unit of 128 +#define REG_TRXPTCL_CTL_8703B 0x0668 + +// Security +#define REG_CAMCMD_8703B 0x0670 +#define REG_CAMWRITE_8703B 0x0674 +#define REG_CAMREAD_8703B 0x0678 +#define REG_CAMDBG_8703B 0x067C +#define REG_SECCFG_8703B 0x0680 + +// Power +#define REG_WOW_CTRL_8703B 0x0690 +#define REG_PS_RX_INFO_8703B 0x0692 +#define REG_UAPSD_TID_8703B 0x0693 +#define REG_WKFMCAM_CMD_8703B 0x0698 +#define REG_WKFMCAM_NUM_8703B 0x0698 +#define REG_WKFMCAM_RWD_8703B 0x069C +#define REG_RXFLTMAP0_8703B 0x06A0 +#define REG_RXFLTMAP1_8703B 0x06A2 +#define REG_RXFLTMAP2_8703B 0x06A4 +#define REG_BCN_PSR_RPT_8703B 0x06A8 +#define REG_BT_COEX_TABLE_8703B 0x06C0 +#define REG_BFMER0_INFO_8703B 0x06E4 +#define REG_BFMER1_INFO_8703B 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8703B 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8703B 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8703B 0x06FC + +// Hardware Port 2 +#define REG_MACID1_8703B 0x0700 +#define REG_BSSID1_8703B 0x0708 +#define REG_BFMEE_SEL_8703B 0x0714 +#define REG_SND_PTCL_CTRL_8703B 0x0718 + +// LTE_COEX +#define REG_LTECOEX_CTRL 0x07C0 +#define REG_LTECOEX_WRITE_DATA 0x07C4 +#define REG_LTECOEX_READ_DATA 0x07C8 +#define REG_LTECOEX_PATH_CONTROL 0x70 + +//============================================================ +// SDIO Bus Specification +//============================================================ + +//----------------------------------------------------- +// SDIO CMD Address Mapping +//----------------------------------------------------- + +//----------------------------------------------------- +// I/O bus domain (Host) +//----------------------------------------------------- + +//----------------------------------------------------- +// SDIO register +//----------------------------------------------------- +#define SDIO_REG_HCPWM1_8703B 0x025 // HCI Current Power Mode 1 + + +//============================================================================ +// 8703 Regsiter Bit and Content definition +//============================================================================ + +#define BIT_USB_RXDMA_AGG_EN BIT(31) +#define RXDMA_AGG_MODE_EN BIT(1) + +#ifdef CONFIG_WOWLAN +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) +#endif + +//2 HSISR +// interrupt mask which needs to clear +#define MASK_HSISR_CLEAR (HSISR_GPIO12_0_INT |\ + HSISR_SPS_OCP_INT |\ + HSISR_RON_INT |\ + HSISR_PDNINT |\ + HSISR_GPIO9_INT) + + +//---------------------------------------------------------------------------- +// 8703B REG_CCK_CHECK (offset 0x454) +//---------------------------------------------------------------------------- +#define BIT_BCN_PORT_SEL BIT5 + +#ifdef CONFIG_RF_GAIN_OFFSET + +#ifdef CONFIG_RTL8703B +#define EEPROM_RF_GAIN_OFFSET 0xC1 +#endif + +#define EEPROM_RF_GAIN_VAL 0x1F6 +#endif //CONFIG_RF_GAIN_OFFSET + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8703B 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8703B BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8703B BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8703B BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8703B BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8703B BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8703B BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8703B BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8703B BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8703B BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8703B BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8703B BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8703B BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8703B BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8703B BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8703B BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8703B BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8703B BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8703B BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8703B BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8703B BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8703B BIT3 // AC_VI DMA OK +#define IMR_VODOK_8703B BIT2 // AC_VO DMA OK +#define IMR_RDU_8703B BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8703B BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8703B BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8703B BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8703B BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8703B BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8703B BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8703B BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8703B BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8703B BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8703B BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8703B BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8703B BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8703B BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8703B BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8703B BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8703B BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8703B BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8703B BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8703B BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8703B BIT8 // Receive FIFO Overflow + +#ifdef CONFIG_PCI_HCI +//#define IMR_RX_MASK (IMR_ROK_8703B|IMR_RDU_8703B|IMR_RXFOVW_8703B) +#define IMR_TX_MASK (IMR_VODOK_8703B|IMR_VIDOK_8703B|IMR_BEDOK_8703B|IMR_BKDOK_8703B|IMR_MGNTDOK_8703B|IMR_HIGHDOK_8703B) + +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8703B | IMR_TXBCN0OK_8703B | IMR_TXBCN0ERR_8703B | IMR_BCNDERR0_8703B) + +#define RT_AC_INT_MASKS (IMR_VIDOK_8703B | IMR_VODOK_8703B | IMR_BEDOK_8703B|IMR_BKDOK_8703B) +#endif + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8703B 16 +#define SEC_CAM_ENT_NUM_8703B 16 +#define NSS_NUM_8703B 1 +#define BAND_CAP_8703B (BAND_CAP_2G) +#define BW_CAP_8703B (BW_CAP_20M | BW_CAP_40M) + +#endif /* __RTL8703B_SPEC_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_sreset.h new file mode 100644 index 00000000..4eb70ddb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL8703B_SRESET_H_ +#define _RTL8703B_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8703b_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8703b_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_xmit.h new file mode 100644 index 00000000..2509b2f3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8703b_xmit.h @@ -0,0 +1,336 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8703B_XMIT_H__ +#define __RTL8703B_XMIT_H__ + + +#define MAX_TID (15) + + +#ifndef __INC_HAL8703BDESC_H +#define __INC_HAL8703BDESC_H + +#define RX_STATUS_DESC_SIZE_8703B 24 +#define RX_DRV_INFO_SIZE_UNIT_8703B 8 + + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8703B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8703B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8703B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8703B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8703B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8703B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8703B(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + + +// Dword 0 +#define GET_TX_DESC_OWN_8703B(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +#define SET_TX_DESC_PKT_SIZE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) + + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_MBSSID_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) +#define SET_TX_DESC_ANTSEL_A_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#if(DEV_BUS_TYPE == RT_SDIO_INTERFACE) +#define SET_TX_DESC_SDIO_TXSEQ_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) + +// Dword 9 +#define SET_TX_DESC_SEQ_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) + +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_8703B(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+40, 0, 32) + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8703B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) + + +#define SET_EARLYMODE_PKTNUM_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8703B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +#endif +//----------------------------------------------------------- +// +// Rate +// +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC8703B_RATE1M 0x00 +#define DESC8703B_RATE2M 0x01 +#define DESC8703B_RATE5_5M 0x02 +#define DESC8703B_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC8703B_RATE6M 0x04 +#define DESC8703B_RATE9M 0x05 +#define DESC8703B_RATE12M 0x06 +#define DESC8703B_RATE18M 0x07 +#define DESC8703B_RATE24M 0x08 +#define DESC8703B_RATE36M 0x09 +#define DESC8703B_RATE48M 0x0a +#define DESC8703B_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC8703B_RATEMCS0 0x0c +#define DESC8703B_RATEMCS1 0x0d +#define DESC8703B_RATEMCS2 0x0e +#define DESC8703B_RATEMCS3 0x0f +#define DESC8703B_RATEMCS4 0x10 +#define DESC8703B_RATEMCS5 0x11 +#define DESC8703B_RATEMCS6 0x12 +#define DESC8703B_RATEMCS7 0x13 +#define DESC8703B_RATEMCS8 0x14 +#define DESC8703B_RATEMCS9 0x15 +#define DESC8703B_RATEMCS10 0x16 +#define DESC8703B_RATEMCS11 0x17 +#define DESC8703B_RATEMCS12 0x18 +#define DESC8703B_RATEMCS13 0x19 +#define DESC8703B_RATEMCS14 0x1a +#define DESC8703B_RATEMCS15 0x1b +#define DESC8703B_RATEVHTSS1MCS0 0x2c +#define DESC8703B_RATEVHTSS1MCS1 0x2d +#define DESC8703B_RATEVHTSS1MCS2 0x2e +#define DESC8703B_RATEVHTSS1MCS3 0x2f +#define DESC8703B_RATEVHTSS1MCS4 0x30 +#define DESC8703B_RATEVHTSS1MCS5 0x31 +#define DESC8703B_RATEVHTSS1MCS6 0x32 +#define DESC8703B_RATEVHTSS1MCS7 0x33 +#define DESC8703B_RATEVHTSS1MCS8 0x34 +#define DESC8703B_RATEVHTSS1MCS9 0x35 +#define DESC8703B_RATEVHTSS2MCS0 0x36 +#define DESC8703B_RATEVHTSS2MCS1 0x37 +#define DESC8703B_RATEVHTSS2MCS2 0x38 +#define DESC8703B_RATEVHTSS2MCS3 0x39 +#define DESC8703B_RATEVHTSS2MCS4 0x3a +#define DESC8703B_RATEVHTSS2MCS5 0x3b +#define DESC8703B_RATEVHTSS2MCS6 0x3c +#define DESC8703B_RATEVHTSS2MCS7 0x3d +#define DESC8703B_RATEVHTSS2MCS8 0x3e +#define DESC8703B_RATEVHTSS2MCS9 0x3f + + +#define RX_HAL_IS_CCK_RATE_8703B(pDesc)\ + (GET_RX_STATUS_DESC_RX_RATE_8703B(pDesc) == DESC8703B_RATE1M ||\ + GET_RX_STATUS_DESC_RX_RATE_8703B(pDesc) == DESC8703B_RATE2M ||\ + GET_RX_STATUS_DESC_RX_RATE_8703B(pDesc) == DESC8703B_RATE5_5M ||\ + GET_RX_STATUS_DESC_RX_RATE_8703B(pDesc) == DESC8703B_RATE11M) + + +void rtl8703b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); +void rtl8703b_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8703bs_init_xmit_priv(PADAPTER padapter); +void rtl8703bs_free_xmit_priv(PADAPTER padapter); +s32 rtl8703bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8703bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8703bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8703bs_xmit_buf_handler(PADAPTER padapter); +thread_return rtl8703bs_xmit_thread(thread_context context); +#define hal_xmit_handler rtl8703bs_xmit_buf_handler +#endif + +#ifdef CONFIG_USB_HCI +s32 rtl8703bu_xmit_buf_handler(PADAPTER padapter); +#define hal_xmit_handler rtl8703bu_xmit_buf_handler + + +s32 rtl8703bu_init_xmit_priv(PADAPTER padapter); +void rtl8703bu_free_xmit_priv(PADAPTER padapter); +s32 rtl8703bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8703bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8703bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +//s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); +void rtl8703bu_xmit_tasklet(void *priv); +s32 rtl8703bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8703be_init_xmit_priv(PADAPTER padapter); +void rtl8703be_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8703be_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8703be_xmitframe_resume(_adapter *padapter); +s32 rtl8703be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8703be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8703be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8703be_xmit_tasklet(void *priv); +#endif + +u8 BWMapping_8703B(PADAPTER Adapter, struct pkt_attrib *pattrib); +u8 SCMapping_8703B(PADAPTER Adapter, struct pkt_attrib *pattrib); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_cmd.h new file mode 100644 index 00000000..aa8c6450 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_cmd.h @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8723B_CMD_H__ +#define __RTL8723B_CMD_H__ + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD DEFINITION ------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +enum h2c_cmd_8723B{ + //Common Class: 000 + H2C_8723B_RSVD_PAGE = 0x00, + H2C_8723B_MEDIA_STATUS_RPT = 0x01, + H2C_8723B_SCAN_ENABLE = 0x02, + H2C_8723B_KEEP_ALIVE = 0x03, + H2C_8723B_DISCON_DECISION = 0x04, + H2C_8723B_PSD_OFFLOAD = 0x05, + H2C_8723B_AP_OFFLOAD = 0x08, + H2C_8723B_BCN_RSVDPAGE = 0x09, + H2C_8723B_PROBERSP_RSVDPAGE = 0x0A, + H2C_8723B_FCS_RSVDPAGE = 0x10, + H2C_8723B_FCS_INFO = 0x11, + H2C_8723B_AP_WOW_GPIO_CTRL = 0x13, + + //PoweSave Class: 001 + H2C_8723B_SET_PWR_MODE = 0x20, + H2C_8723B_PS_TUNING_PARA = 0x21, + H2C_8723B_PS_TUNING_PARA2 = 0x22, + H2C_8723B_P2P_LPS_PARAM = 0x23, + H2C_8723B_P2P_PS_OFFLOAD = 0x24, + H2C_8723B_PS_SCAN_ENABLE = 0x25, + H2C_8723B_SAP_PS_ = 0x26, + H2C_8723B_INACTIVE_PS_ = 0x27, //Inactive_PS + H2C_8723B_FWLPS_IN_IPS_ = 0x28, + + //Dynamic Mechanism Class: 010 + H2C_8723B_MACID_CFG = 0x40, + H2C_8723B_TXBF = 0x41, + H2C_8723B_RSSI_SETTING = 0x42, + H2C_8723B_AP_REQ_TXRPT = 0x43, + H2C_8723B_INIT_RATE_COLLECT = 0x44, + H2C_8723B_RA_PARA_ADJUST = 0x46, + + //BT Class: 011 + H2C_8723B_B_TYPE_TDMA = 0x60, + H2C_8723B_BT_INFO = 0x61, + H2C_8723B_FORCE_BT_TXPWR = 0x62, + H2C_8723B_BT_IGNORE_WLANACT = 0x63, + H2C_8723B_DAC_SWING_VALUE = 0x64, + H2C_8723B_ANT_SEL_RSV = 0x65, + H2C_8723B_WL_OPMODE = 0x66, + H2C_8723B_BT_MP_OPER = 0x67, + H2C_8723B_BT_CONTROL = 0x68, + H2C_8723B_BT_WIFI_CTRL = 0x69, + H2C_8723B_BT_FW_PATCH = 0x6A, + H2C_8723B_BT_WLAN_CALIBRATION = 0x6D, + + //WOWLAN Class: 100 + H2C_8723B_WOWLAN = 0x80, + H2C_8723B_REMOTE_WAKE_CTRL = 0x81, + H2C_8723B_AOAC_GLOBAL_INFO = 0x82, + H2C_8723B_AOAC_RSVD_PAGE = 0x83, + H2C_8723B_AOAC_RSVD_PAGE2 = 0x84, + 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, +}; + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD CONTENT --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_KEEP_ALIVE_CMD_0x03 +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +//_DISCONNECT_DECISION_CMD_0x04 +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +// _PWR_MOD_CMD_0x20 +#define SET_8723B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +#define GET_8723B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +// _PS_TUNE_PARAM_CMD_0x21 +#define SET_8723B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 1, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 1, 7, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +//_MACID_CFG_CMD_0x40 +#define SET_8723B_H2CCMD_MACID_CFG_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RAID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 5, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_SGI_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 2, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_NO_UPDATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 3, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_VHT_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 4, 2, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_DISPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 6, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_DISRA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value) + +//_RSSI_SETTING_CMD_0x42 +#define SET_8723B_H2CCMD_RSSI_SETTING_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSSI_SETTING_RSSI(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value) +#define SET_8723B_H2CCMD_RSSI_SETTING_ULDL_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +// _AP_REQ_TXRPT_CMD_0x43 +#define SET_8723B_H2CCMD_APREQRPT_PARM_MACID1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_APREQRPT_PARM_MACID2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +// _FORCE_BT_TXPWR_CMD_0x62 +#define SET_8723B_H2CCMD_BT_PWR_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) + +// _FORCE_BT_MP_OPER_CMD_0x67 +#define SET_8723B_H2CCMD_BT_MPOPER_VER(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_REQNUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_PARAM1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_PARAM2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_PARAM3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) + +// _BT_FW_PATCH_0x6A +#define SET_8723B_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_2BYTE((pu1Byte)(__pH2CCmd), 0, 16, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +//---------------------------------------------------------------------------------------------------------// +//------------------------------------------- Structure --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- Function Statement --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +// host message to firmware cmd +void rtl8723b_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8723b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus); +void rtl8723b_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8723b_Add_RateATid(PADAPTER pAdapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +void rtl8723b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack); +//s32 rtl8723b_set_lowpwr_lps_cmd(PADAPTER padapter, u8 enable); +void rtl8723b_set_FwPsTuneParam_cmd(PADAPTER padapter); +void rtl8723b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask); +void rtl8723b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param); +void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus); +#ifdef CONFIG_BT_COEXIST +void rtl8723b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); +#endif // CONFIG_BT_COEXIST +#ifdef CONFIG_P2P +void rtl8723b_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +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); +u8 GetTxBufferRsvdPageNum8723B(_adapter *padapter, bool wowlan); +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_dm.h new file mode 100644 index 00000000..2108c46d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_dm.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * 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 __RTL8723B_DM_H__ +#define __RTL8723B_DM_H__ +//============================================================ +// Description: +// +// This file is for 8723B dynamic mechanism only +// +// +//============================================================ + +//============================================================ +// structure and define +//============================================================ + +//============================================================ +// function prototype +//============================================================ + +void rtl8723b_init_dm_priv(PADAPTER padapter); +void rtl8723b_deinit_dm_priv(PADAPTER padapter); + +void rtl8723b_InitHalDm(PADAPTER padapter); +void rtl8723b_HalDmWatchDog(PADAPTER padapter); +void rtl8723b_HalDmWatchDog_in_LPS(PADAPTER padapter); +void rtl8723b_hal_dm_in_lps(PADAPTER padapter); + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_hal.h new file mode 100644 index 00000000..84243081 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_hal.h @@ -0,0 +1,326 @@ +/****************************************************************************** + * + * 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 __RTL8723B_HAL_H__ +#define __RTL8723B_HAL_H__ + +#include "hal_data.h" + +#include "rtl8723b_spec.h" +#include "rtl8723b_rf.h" +#include "rtl8723b_dm.h" +#include "rtl8723b_recv.h" +#include "rtl8723b_xmit.h" +#include "rtl8723b_cmd.h" +#include "rtl8723b_led.h" +#include "Hal8723BPwrSeq.h" +#include "Hal8723BPhyReg.h" +#include "Hal8723BPhyCfg.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8723b_sreset.h" +#endif + + +//--------------------------------------------------------------------- +// RTL8723B From file +//--------------------------------------------------------------------- + #define RTL8723B_FW_IMG "rtl8723b/FW_NIC.bin" + #define RTL8723B_FW_WW_IMG "rtl8723b/FW_WoWLAN.bin" + #define RTL8723B_PHY_REG "rtl8723b/PHY_REG.txt" + #define RTL8723B_PHY_RADIO_A "rtl8723b/RadioA.txt" + #define RTL8723B_PHY_RADIO_B "rtl8723b/RadioB.txt" + #define RTL8723B_TXPWR_TRACK "rtl8723b/TxPowerTrack.txt" + #define RTL8723B_AGC_TAB "rtl8723b/AGC_TAB.txt" + #define RTL8723B_PHY_MACREG "rtl8723b/MAC_REG.txt" + #define RTL8723B_PHY_REG_PG "rtl8723b/PHY_REG_PG.txt" + #define RTL8723B_PHY_REG_MP "rtl8723b/PHY_REG_MP.txt" + #define RTL8723B_TXPWR_LMT "rtl8723b/TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8723B From header +//--------------------------------------------------------------------- + +#if MP_DRIVER == 1 + #define Rtl8723B_FwBTImgArray Rtl8723BFwBTImgArray + #define Rtl8723B_FwBTImgArrayLength Rtl8723BFwBTImgArrayLength + + #define Rtl8723B_PHY_REG_Array_MP Rtl8723B_PHYREG_Array_MP + #define Rtl8723B_PHY_REG_Array_MPLength Rtl8723B_PHYREG_Array_MPLength +#endif + + +#define FW_8723B_SIZE 0x8000 +#define FW_8723B_START_ADDRESS 0x1000 +#define FW_8723B_END_ADDRESS 0x1FFF //0x5FFF + +#define IS_FW_HEADER_EXIST_8723B(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x5300) + +typedef struct _RT_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_8723B_SIZE]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8723B, *PRT_FIRMWARE_8723B; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8723B_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u16 Subversion; // FW Subversion, default 0x00 + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8723B_FIRMWARE_HDR, *PRT_8723B_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME_8723B 0x05 +#define BCN_DMA_ATIME_INT_TIME_8723B 0x02 + +// for 8723B +// TX 32K, RX 16K, Page size 128B for TX, 8B for RX +#define PAGE_SIZE_TX_8723B 128 +#define PAGE_SIZE_RX_8723B 8 + +#define TX_DMA_SIZE_8723B 0x8000 /* 32K(TX) */ +#define RX_DMA_SIZE_8723B 0x4000 /* 16K(RX) */ + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#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) + + +// Note: We will divide number of page equally for each queue other than public queue! + +//For General Reserved Page Number(Beacon Queue is reserved page) +//Beacon:2, PS-Poll:1, Null Data:1,Qos Null Data:1,BT Qos Null Data:1 +#define BCNQ_PAGE_NUM_8723B 0x08 +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8723B 0x08 // 0x04 +#else +#define BCNQ1_PAGE_NUM_8723B 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef BCNQ1_PAGE_NUM_8723B +#define BCNQ1_PAGE_NUM_8723B 0x00 // 0x04 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8723B 0x07 +#else +#define WOWLAN_PAGE_NUM_8723B 0x00 +#endif + +#ifdef CONFIG_PNO_SUPPORT +#undef WOWLAN_PAGE_NUM_8723B +#define WOWLAN_PAGE_NUM_8723B 0x15 +#endif + +#ifdef CONFIG_AP_WOWLAN +#define AP_WOWLAN_PAGE_NUM_8723B 0x02 +#endif + +#define TX_TOTAL_PAGE_NUMBER_8723B (0xFF - BCNQ_PAGE_NUM_8723B - BCNQ1_PAGE_NUM_8723B - WOWLAN_PAGE_NUM_8723B) +#define TX_PAGE_BOUNDARY_8723B (TX_TOTAL_PAGE_NUMBER_8723B + 1) + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8723B TX_TOTAL_PAGE_NUMBER_8723B +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8723B (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8723B + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8723B +#define NORMAL_PAGE_NUM_HPQ_8723B 0x0C +#define NORMAL_PAGE_NUM_LPQ_8723B 0x02 +#define NORMAL_PAGE_NUM_NPQ_8723B 0x02 + +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8723B 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8723B 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8723B 0x20 + + +#include "HalVerDef.h" +#include "hal_com.h" + +#define EFUSE_OOB_PROTECT_BYTES 15 + +#define HAL_EFUSE_MEMORY + +#define HWSET_MAX_SIZE_8723B 512 +#define EFUSE_REAL_CONTENT_LEN_8723B 512 +#define EFUSE_MAP_LEN_8723B 512 +#define EFUSE_MAX_SECTION_8723B 64 + +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN_8723B) + +#define EFUSE_ACCESS_ON 0x69 // For RTL8723 only. +#define EFUSE_ACCESS_OFF 0x00 // For RTL8723 only. + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +typedef struct _C2H_EVT_HDR +{ + u8 CmdID; + u8 CmdLen; + u8 CmdSeq; +} __attribute__((__packed__)) C2H_EVT_HDR, *PC2H_EVT_HDR; + +typedef enum tag_Package_Definition +{ + PACKAGE_DEFAULT, + PACKAGE_QFN68, + PACKAGE_TFBGA90, + PACKAGE_TFBGA80, + PACKAGE_TFBGA79 +}PACKAGE_TYPE_E; + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +// rtl8723a_hal_init.c +s32 rtl8723b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void rtl8723b_FirmwareSelfReset(PADAPTER padapter); +void rtl8723b_InitializeFirmwareVars(PADAPTER padapter); + +void rtl8723b_InitAntenna_Selection(PADAPTER padapter); +void rtl8723b_DeinitAntenna_Selection(PADAPTER padapter); +void rtl8723b_CheckAntenna_Selection(PADAPTER padapter); +void rtl8723b_init_default_value(PADAPTER padapter); + +s32 rtl8723b_InitLLTTable(PADAPTER padapter); + +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU); +s32 CardDisableWithoutHWSM(PADAPTER padapter); + +// EFuse +u8 GetEEPROMSize8723B(PADAPTER padapter); +void Hal_InitPGData(PADAPTER padapter, u8 *PROMContent); +void Hal_EfuseParseIDCode(PADAPTER padapter, u8 *hwinfo); +void Hal_EfuseParseTxPowerInfo_8723B(PADAPTER padapter, u8 *PROMContent, BOOLEAN AutoLoadFail); +void Hal_EfuseParseBTCoexistInfo_8723B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseEEPROMVer_8723B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseChnlPlan_8723B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID_8723B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseAntennaDiversity_8723B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8723B(PADAPTER pAdapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseThermalMeter_8723B(PADAPTER padapter, u8 *hwinfo, u8 AutoLoadFail); +VOID Hal_EfuseParsePackageType_8723B(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +VOID Hal_EfuseParseVoltage_8723B(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +VOID Hal_EfuseParseBoardType_8723B(PADAPTER Adapter, u8* PROMContent,BOOLEAN AutoloadFail); + +#ifdef CONFIG_C2H_PACKET_EN +void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length); +#endif + + +void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8723b(_adapter *adapter); +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); + +// register +void rtl8723b_InitBeaconParameters(PADAPTER padapter); +void rtl8723b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode); +void _InitBurstPktLen_8723BS(PADAPTER Adapter); +void _8051Reset8723(PADAPTER padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void rtl8723b_start_thread(_adapter *padapter); +void rtl8723b_stop_thread(_adapter *padapter); + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +void rtl8723bs_init_checkbthang_workqueue(_adapter * adapter); +void rtl8723bs_free_checkbthang_workqueue(_adapter * adapter); +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); +s32 c2h_id_filter_ccx_8723b(u8 *buf); +s32 c2h_handler_8723b(PADAPTER padapter, u8 *pC2hEvent); +u8 MRateToHwRate8723B(u8 rate); +u8 HwRateToMRate8723B(u8 rate); + +#ifdef CONFIG_RF_GAIN_OFFSET +void Hal_ReadRFGainOffset(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +#endif //CONFIG_RF_GAIN_OFFSET + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8723BE(PADAPTER Adapter); +VOID UpdateInterruptMask8723BE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_led.h new file mode 100644 index 00000000..36772c05 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_led.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 __RTL8723B_LED_H__ +#define __RTL8723B_LED_H__ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8723bu_InitSwLeds(PADAPTER padapter); +void rtl8723bu_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_SDIO_HCI +void rtl8723bs_InitSwLeds(PADAPTER padapter); +void rtl8723bs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_GSPI_HCI +void rtl8723bs_InitSwLeds(PADAPTER padapter); +void rtl8723bs_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8723be_InitSwLeds(PADAPTER padapter); +void rtl8723be_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_recv.h new file mode 100644 index 00000000..f4611864 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_recv.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * 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 __RTL8723B_RECV_H__ +#define __RTL8723B_RECV_H__ + +#define RECV_BLK_SZ 512 +#define RECV_BLK_CNT 16 +#define RECV_BLK_TH RECV_BLK_CNT + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + //#define MAX_RECVBUF_SZ (32768) // 32k + //#define MAX_RECVBUF_SZ (16384) //16K + //#define MAX_RECVBUF_SZ (10240) //10K + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#define MAX_RECVBUF_SZ (10240) + +#endif + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#ifdef CONFIG_SDIO_HCI +#ifndef CONFIG_SDIO_RX_COPY +#undef MAX_RECVBUF_SZ +#define MAX_RECVBUF_SZ (RX_DMA_SIZE_8723B - RX_DMA_RESERVED_SIZE_8723B) +#endif // !CONFIG_SDIO_RX_COPY +#endif // CONFIG_SDIO_HCI + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8723bs_init_recv_priv(PADAPTER padapter); +void rtl8723bs_free_recv_priv(PADAPTER padapter); +#endif + +#ifdef CONFIG_USB_HCI +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 + +#ifdef CONFIG_PCI_HCI +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); + +#endif /* __RTL8723B_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_rf.h new file mode 100644 index 00000000..2bb73417 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_rf.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * 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 __RTL8723B_RF_H__ +#define __RTL8723B_RF_H__ + +int PHY_RF6052_Config8723B( IN PADAPTER Adapter ); + +VOID +PHY_RF6052SetBandwidth8723B( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_spec.h new file mode 100644 index 00000000..63f30593 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_spec.h @@ -0,0 +1,295 @@ +/****************************************************************************** + * + * 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 __RTL8723B_SPEC_H__ +#define __RTL8723B_SPEC_H__ + +#include + + +#define HAL_NAV_UPPER_UNIT_8723B 128 // micro-second + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_RSV_CTRL_8723B 0x001C // 3 Byte +#define REG_BT_WIFI_ANTENNA_SWITCH_8723B 0x0038 +#define REG_HSISR_8723B 0x005c +#define REG_PAD_CTRL1_8723B 0x0064 +#define REG_AFE_CTRL_4_8723B 0x0078 +#define REG_HMEBOX_DBG_0_8723B 0x0088 +#define REG_HMEBOX_DBG_1_8723B 0x008A +#define REG_HMEBOX_DBG_2_8723B 0x008C +#define REG_HMEBOX_DBG_3_8723B 0x008E +#define REG_HIMR0_8723B 0x00B0 +#define REG_HISR0_8723B 0x00B4 +#define REG_HIMR1_8723B 0x00B8 +#define REG_HISR1_8723B 0x00BC +#define REG_PMC_DBG_CTRL2_8723B 0x00CC + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_C2HEVT_CMD_ID_8723B 0x01A0 +#define REG_C2HEVT_CMD_LEN_8723B 0x01AE +#define REG_WOWLAN_WAKE_REASON 0x01C7 +#define REG_WOWLAN_GTK_DBG1 0x630 +#define REG_WOWLAN_GTK_DBG2 0x634 + +#define REG_HMEBOX_EXT0_8723B 0x01F0 +#define REG_HMEBOX_EXT1_8723B 0x01F4 +#define REG_HMEBOX_EXT2_8723B 0x01F8 +#define REG_HMEBOX_EXT3_8723B 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_CONTROL_8723B 0x0286 // Control the RX DMA. +#define REG_RXDMA_MODE_CTRL_8723B 0x0290 + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8723B 0x0300 +#define REG_INT_MIG_8723B 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA_8723B 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA_8723B 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA_8723B 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA_8723B 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA_8723B 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA_8723B 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA_8723B 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA_8723B 0x0340 // RX Queue Descriptor Address +#define REG_DBI_WDATA_8723B 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8723B 0x034C // DBI Read Data +#define REG_DBI_ADDR_8723B 0x0350 // DBI Address +#define REG_DBI_FLAG_8723B 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8723B 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8723B 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8723B 0x0358 // MDIO for Control +#define REG_DBG_SEL_8723B 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM_8723B 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM_8723B 0x0363 //PCIe CPWM +#define REG_PCIE_MULTIFET_CTRL_8723B 0x036A //PCIE Multi-Fethc Control + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_TXPKTBUF_BCNQ_BDNY_8723B 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8723B 0x0425 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8723B 0x045D +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif +#define REG_AMPDU_BURST_MODE_8723B 0x04BC + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_SECONDARY_CCA_CTRL_8723B 0x0577 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + + +//============================================================ +// SDIO Bus Specification +//============================================================ + +//----------------------------------------------------- +// SDIO CMD Address Mapping +//----------------------------------------------------- + +//----------------------------------------------------- +// I/O bus domain (Host) +//----------------------------------------------------- + +//----------------------------------------------------- +// SDIO register +//----------------------------------------------------- +#define SDIO_REG_HCPWM1_8723B 0x025 // HCI Current Power Mode 1 + + +//============================================================================ +// 8723 Regsiter Bit and Content definition +//============================================================================ + +//2 HSISR +// interrupt mask which needs to clear +#define MASK_HSISR_CLEAR (HSISR_GPIO12_0_INT |\ + HSISR_SPS_OCP_INT |\ + HSISR_RON_INT |\ + HSISR_PDNINT |\ + HSISR_GPIO9_INT) + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#undef IS_E_CUT +#define IS_E_CUT(version) FALSE +#undef IS_F_CUT +#define IS_F_CUT(version) ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? TRUE : FALSE) + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define BIT_USB_RXDMA_AGG_EN BIT(31) +#define RXDMA_AGG_MODE_EN BIT(1) + +#ifdef CONFIG_WOWLAN +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) +#endif + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- + +//---------------------------------------------------------------------------- +// 8723B REG_CCK_CHECK (offset 0x454) +//---------------------------------------------------------------------------- +#define BIT_BCN_PORT_SEL BIT5 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#ifdef CONFIG_RF_GAIN_OFFSET + +#ifdef CONFIG_RTL8723B +#define EEPROM_RF_GAIN_OFFSET 0xC1 +#endif + +#define EEPROM_RF_GAIN_VAL 0x1F6 +#endif //CONFIG_RF_GAIN_OFFSET + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8723B 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8723B BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8723B BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8723B BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8723B BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8723B BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8723B BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8723B BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8723B BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8723B BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8723B BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8723B BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8723B BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8723B BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8723B BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8723B BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8723B BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8723B BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8723B BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8723B BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8723B BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8723B BIT3 // AC_VI DMA OK +#define IMR_VODOK_8723B BIT2 // AC_VO DMA OK +#define IMR_RDU_8723B BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8723B BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8723B BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8723B BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8723B BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8723B BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8723B BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8723B BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8723B BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8723B BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8723B BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8723B BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8723B BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8723B BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8723B BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8723B BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8723B BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8723B BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8723B BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8723B BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8723B BIT8 // Receive FIFO Overflow + +#ifdef CONFIG_PCI_HCI +//#define IMR_RX_MASK (IMR_ROK_8723B|IMR_RDU_8723B|IMR_RXFOVW_8723B) +#define IMR_TX_MASK (IMR_VODOK_8723B|IMR_VIDOK_8723B|IMR_BEDOK_8723B|IMR_BKDOK_8723B|IMR_MGNTDOK_8723B|IMR_HIGHDOK_8723B) + +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8723B | IMR_TXBCN0OK_8723B | IMR_TXBCN0ERR_8723B | IMR_BCNDERR0_8723B) + +#define RT_AC_INT_MASKS (IMR_VIDOK_8723B | IMR_VODOK_8723B | IMR_BEDOK_8723B|IMR_BKDOK_8723B) +#endif + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8723B 128 +#define SEC_CAM_ENT_NUM_8723B 64 +#define NSS_NUM_8723B 1 +#define BAND_CAP_8723B (BAND_CAP_2G) +#define BW_CAP_8723B (BW_CAP_20M | BW_CAP_40M) + +#endif /* __RTL8723B_SPEC_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_sreset.h new file mode 100644 index 00000000..9ade2dc7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL8723B_SRESET_H_ +#define _RTL8723B_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8723b_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8723b_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_xmit.h new file mode 100644 index 00000000..b9982336 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8723b_xmit.h @@ -0,0 +1,336 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 __RTL8723B_XMIT_H__ +#define __RTL8723B_XMIT_H__ + + +#define MAX_TID (15) + + +#ifndef __INC_HAL8723BDESC_H +#define __INC_HAL8723BDESC_H + +#define RX_STATUS_DESC_SIZE_8723B 24 +#define RX_DRV_INFO_SIZE_UNIT_8723B 8 + + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8723B(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + + +// Dword 0 +#define GET_TX_DESC_OWN_8723B(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +#define SET_TX_DESC_PKT_SIZE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) + + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_MBSSID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) +#define SET_TX_DESC_ANTSEL_A_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#if(DEV_BUS_TYPE == RT_SDIO_INTERFACE) +#define SET_TX_DESC_SDIO_TXSEQ_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) + +// Dword 9 +#define SET_TX_DESC_SEQ_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) + +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_8723B(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+40, 0, 32) + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) + + +#define SET_EARLYMODE_PKTNUM_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +#endif +//----------------------------------------------------------- +// +// Rate +// +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC8723B_RATE1M 0x00 +#define DESC8723B_RATE2M 0x01 +#define DESC8723B_RATE5_5M 0x02 +#define DESC8723B_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC8723B_RATE6M 0x04 +#define DESC8723B_RATE9M 0x05 +#define DESC8723B_RATE12M 0x06 +#define DESC8723B_RATE18M 0x07 +#define DESC8723B_RATE24M 0x08 +#define DESC8723B_RATE36M 0x09 +#define DESC8723B_RATE48M 0x0a +#define DESC8723B_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC8723B_RATEMCS0 0x0c +#define DESC8723B_RATEMCS1 0x0d +#define DESC8723B_RATEMCS2 0x0e +#define DESC8723B_RATEMCS3 0x0f +#define DESC8723B_RATEMCS4 0x10 +#define DESC8723B_RATEMCS5 0x11 +#define DESC8723B_RATEMCS6 0x12 +#define DESC8723B_RATEMCS7 0x13 +#define DESC8723B_RATEMCS8 0x14 +#define DESC8723B_RATEMCS9 0x15 +#define DESC8723B_RATEMCS10 0x16 +#define DESC8723B_RATEMCS11 0x17 +#define DESC8723B_RATEMCS12 0x18 +#define DESC8723B_RATEMCS13 0x19 +#define DESC8723B_RATEMCS14 0x1a +#define DESC8723B_RATEMCS15 0x1b +#define DESC8723B_RATEVHTSS1MCS0 0x2c +#define DESC8723B_RATEVHTSS1MCS1 0x2d +#define DESC8723B_RATEVHTSS1MCS2 0x2e +#define DESC8723B_RATEVHTSS1MCS3 0x2f +#define DESC8723B_RATEVHTSS1MCS4 0x30 +#define DESC8723B_RATEVHTSS1MCS5 0x31 +#define DESC8723B_RATEVHTSS1MCS6 0x32 +#define DESC8723B_RATEVHTSS1MCS7 0x33 +#define DESC8723B_RATEVHTSS1MCS8 0x34 +#define DESC8723B_RATEVHTSS1MCS9 0x35 +#define DESC8723B_RATEVHTSS2MCS0 0x36 +#define DESC8723B_RATEVHTSS2MCS1 0x37 +#define DESC8723B_RATEVHTSS2MCS2 0x38 +#define DESC8723B_RATEVHTSS2MCS3 0x39 +#define DESC8723B_RATEVHTSS2MCS4 0x3a +#define DESC8723B_RATEVHTSS2MCS5 0x3b +#define DESC8723B_RATEVHTSS2MCS6 0x3c +#define DESC8723B_RATEVHTSS2MCS7 0x3d +#define DESC8723B_RATEVHTSS2MCS8 0x3e +#define DESC8723B_RATEVHTSS2MCS9 0x3f + + +#define RX_HAL_IS_CCK_RATE_8723B(pDesc)\ + (GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE1M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE2M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE5_5M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE11M) + + +void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); +void rtl8723b_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +s32 rtl8723bs_init_xmit_priv(PADAPTER padapter); +void rtl8723bs_free_xmit_priv(PADAPTER padapter); +s32 rtl8723bs_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8723bs_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8723bs_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8723bs_xmit_buf_handler(PADAPTER padapter); +thread_return rtl8723bs_xmit_thread(thread_context context); +#define hal_xmit_handler rtl8723bs_xmit_buf_handler +#endif + +#ifdef CONFIG_USB_HCI +s32 rtl8723bu_xmit_buf_handler(PADAPTER padapter); +#define hal_xmit_handler rtl8723bu_xmit_buf_handler + + +s32 rtl8723bu_init_xmit_priv(PADAPTER padapter); +void rtl8723bu_free_xmit_priv(PADAPTER padapter); +s32 rtl8723bu_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8723bu_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +//s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); +void rtl8723bu_xmit_tasklet(void *priv); +s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8723be_init_xmit_priv(PADAPTER padapter); +void rtl8723be_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8723be_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8723be_xmitframe_resume(_adapter *padapter); +s32 rtl8723be_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8723be_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8723be_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8723be_xmit_tasklet(void *priv); +#endif + +u8 BWMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib); +u8 SCMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_cmd.h new file mode 100644 index 00000000..e34683b1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_cmd.h @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * 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 __RTL8812A_CMD_H__ +#define __RTL8812A_CMD_H__ + +typedef enum _RTL8812_H2C_CMD +{ + H2C_8812_RSVDPAGE = 0, + H2C_8812_MSRRPT = 1, + H2C_8812_SCAN = 2, + H2C_8812_KEEP_ALIVE_CTRL = 3, + H2C_8812_DISCONNECT_DECISION = 4, + + H2C_8812_INIT_OFFLOAD = 6, + H2C_8812_AP_OFFLOAD = 8, + H2C_8812_BCN_RSVDPAGE = 9, + H2C_8812_PROBERSP_RSVDPAGE = 10, + + H2C_8812_SETPWRMODE = 0x20, + H2C_8812_PS_TUNING_PARA = 0x21, + H2C_8812_PS_TUNING_PARA2 = 0x22, + H2C_8812_PS_LPS_PARA = 0x23, + H2C_8812_P2P_PS_OFFLOAD = 0x24, + H2C_8812_RA_MASK = 0x40, + H2C_8812_TxBF = 0x41, + H2C_8812_RSSI_REPORT = 0x42, + H2C_8812_IQ_CALIBRATION = 0x45, + H2C_8812_RA_PARA_ADJUST = 0x46, + + H2C_8812_BT_FW_PATCH = 0x6a, + + H2C_8812_WO_WLAN = 0x80, + H2C_8812_REMOTE_WAKE_CTRL = 0x81, + H2C_8812_AOAC_GLOBAL_INFO = 0x82, + H2C_8812_AOAC_RSVDPAGE = 0x83, + H2C_8812_FW_SWCHANNL = 0x87, + + H2C_8812_TSF_RESET = 0xC0, + + MAX_8812_H2CCMD +}RTL8812_H2C_CMD; + +struct cmd_msg_parm { + u8 eid; //element id + u8 sz; // sz + u8 buf[6]; +}; + +enum{ + PWRS +}; + +struct H2C_SS_RFOFF_PARAM{ + u8 ROFOn; // 1: on, 0:off + u16 gpio_period; // unit: 1024 us +}__attribute__ ((packed)); + + + +//_RSVDPAGE_LOC_CMD0 +#define SET_8812_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8812_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8812_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8812_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8812_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_SETPWRMODE_PARM +#define SET_8812_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8812_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +#define GET_8812_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +//_P2P_PS_OFFLOAD +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_ROLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_CTWINDOW_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_NOA0_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_NOA1_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_8812_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) + + +void Set_RA_LDPC_8812(struct sta_info *psta, BOOLEAN bLDPC); + +// host message to firmware cmd +s32 FillH2CCmd_8812(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +void rtl8812_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode); +void rtl8812_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus); +u8 rtl8812_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8812_set_raid_cmd(PADAPTER padapter, u32 bitmap, u8* arg); +void rtl8812_Add_RateATid(PADAPTER padapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +void rtl8812_set_wowlan_cmd(_adapter* padapter, u8 enable); +s32 FillH2CCmd_8812(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +u8 GetTxBufferRsvdPageNum8812(_adapter *padapter, bool wowlan); + +#ifdef CONFIG_BT_COEXIST +void rtl8812a_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter); +#endif // CONFIG_BT_COEXIST +#ifdef CONFIG_P2P_PS +void rtl8812_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +int reset_tsf(PADAPTER Adapter, u8 reset_port ); +#endif // CONFIG_TSF_RESET_OFFLOAD + +#ifdef CONFIG_WOWLAN +void SetFwRelatedForWoWLAN8812(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif//CONFIG_WOWLAN + +//------------------------------------ +// C2H format +//------------------------------------ + +// TX Beamforming +#define GET_8812_C2H_TXBF_ORIGINATE(_Header) LE_BITS_TO_1BYTE(_Header, 0, 8) +#define GET_8812_C2H_TXBF_MACID(_Header) LE_BITS_TO_1BYTE((_Header + 1), 0, 8) + + + +/// TX Feedback Content +#define USEC_UNIT_FOR_8812_C2H_TX_RPT_QUEUE_TIME 256 + +#define GET_8812_C2H_TX_RPT_QUEUE_SELECT(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 5) +#define GET_8812_C2H_TX_RPT_PKT_BROCAST(_Header) LE_BITS_TO_1BYTE((_Header + 0), 5, 1) +#define GET_8812_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1) +#define GET_8812_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1) +#define GET_8812_C2H_TX_RPT_MAC_ID(_Header) LE_BITS_TO_1BYTE((_Header + 1), 0, 8) +#define GET_8812_C2H_TX_RPT_DATA_RETRY_CNT(_Header) LE_BITS_TO_1BYTE((_Header + 2), 0, 6) +#define GET_8812_C2H_TX_RPT_QUEUE_TIME(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) // In unit of 256 microseconds. +#define GET_8812_C2H_TX_RPT_FINAL_DATA_RATE(_Header) LE_BITS_TO_1BYTE((_Header + 5), 0, 8) + +// BT_FW_PATCH +#define SET_8812_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_2BYTE((pu1Byte)(__pH2CCmd), 0, 16, __Value) +#define SET_8812_H2CCMD_BT_FW_PATCH_ADDR0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((pu1Byte)(__pH2CCmd)+2, 0, 8, __Value) +#define SET_8812_H2CCMD_BT_FW_PATCH_ADDR1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((pu1Byte)(__pH2CCmd)+3, 0, 8, __Value) +#define SET_8812_H2CCMD_BT_FW_PATCH_ADDR2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((pu1Byte)(__pH2CCmd)+4, 0, 8, __Value) +#define SET_8812_H2CCMD_BT_FW_PATCH_ADDR3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((pu1Byte)(__pH2CCmd)+5, 0, 8, __Value) + +int rtl8812_iqk_wait(_adapter* padapter, u32 timeout_ms); +void rtl8812_iqk_done(_adapter* padapter); + +s32 +_C2HContentParsing8812( + IN PADAPTER Adapter, + IN u8 c2hCmdId, + IN u8 c2hCmdLen, + IN u8 *tmpBuf +); +void C2HPacketHandler_8812(PADAPTER Adapter, u8 *Buffer, u8 Length); + +#endif//__RTL8812A_CMD_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_dm.h new file mode 100644 index 00000000..3196973d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_dm.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * 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 __RTL8812A_DM_H__ +#define __RTL8812A_DM_H__ + +void rtl8812_init_dm_priv(IN PADAPTER Adapter); +void rtl8812_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8812_InitHalDm(IN PADAPTER Adapter); +void rtl8812_HalDmWatchDog(IN PADAPTER Adapter); + +//VOID rtl8192c_dm_CheckTXPowerTracking(IN PADAPTER Adapter); + +//void rtl8192c_dm_RF_Saving(IN PADAPTER pAdapter, IN u8 bForceInNormal); + +#ifdef CONFIG_ANTENNA_DIVERSITY +void AntDivCompare8812(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +u8 AntDivBeforeLink8812(PADAPTER Adapter ); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_hal.h new file mode 100644 index 00000000..8260256e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_hal.h @@ -0,0 +1,373 @@ +/****************************************************************************** + * + * 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 __RTL8812A_HAL_H__ +#define __RTL8812A_HAL_H__ + +//#include "hal_com.h" +#include "hal_data.h" + +//include HAL Related header after HAL Related compiling flags +#include "rtl8812a_spec.h" +#include "rtl8812a_rf.h" +#include "rtl8812a_dm.h" +#include "rtl8812a_recv.h" +#include "rtl8812a_xmit.h" +#include "rtl8812a_cmd.h" +#include "rtl8812a_led.h" +#include "Hal8812PwrSeq.h" +#include "Hal8821APwrSeq.h" //for 8821A/8811A +#include "Hal8812PhyReg.h" +#include "Hal8812PhyCfg.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8812a_sreset.h" +#endif + + +//--------------------------------------------------------------------- +// RTL8812AU From header +//--------------------------------------------------------------------- + #define RTL8812_FW_IMG "rtl8812a/FW_NIC.bin" + #define RTL8812_FW_WW_IMG "rtl8812a/FW_WoWLAN.bin" + #define RTL8812_PHY_REG "rtl8812a/PHY_REG.txt" + #define RTL8812_PHY_RADIO_A "rtl8812a/RadioA.txt" + #define RTL8812_PHY_RADIO_B "rtl8812a/RadioB.txt" + #define RTL8812_TXPWR_TRACK "rtl8812a/TxPowerTrack.txt" + #define RTL8812_AGC_TAB "rtl8812a/AGC_TAB.txt" + #define RTL8812_PHY_MACREG "rtl8812a/MAC_REG.txt" + #define RTL8812_PHY_REG_PG "rtl8812a/PHY_REG_PG.txt" + #define RTL8812_PHY_REG_MP "rtl8812a/PHY_REG_MP.txt" + #define RTL8812_TXPWR_LMT "rtl8812a/TXPWR_LMT.txt" + #define RTL8812_WIFI_ANT_ISOLATION "rtl8812a/wifi_ant_isolation.txt" + +//--------------------------------------------------------------------- +// RTL8821U From file +//--------------------------------------------------------------------- + #define RTL8821_FW_IMG "rtl8821a/FW_NIC.bin" + #define RTL8821_FW_WW_IMG "rtl8821a/FW_WoWLAN.bin" + #define RTL8821_PHY_REG "rtl8821a/PHY_REG.txt" + #define RTL8821_PHY_RADIO_A "rtl8821a/RadioA.txt" + #define RTL8821_PHY_RADIO_B "rtl8821a/RadioB.txt" + #define RTL8821_TXPWR_TRACK "rtl8821a/TxPowerTrack.txt" + #define RTL8821_AGC_TAB "rtl8821a/AGC_TAB.txt" + #define RTL8821_PHY_MACREG "rtl8821a/MAC_REG.txt" + #define RTL8821_PHY_REG_PG "rtl8821a/PHY_REG_PG.txt" + #define RTL8821_PHY_REG_MP "rtl8821a/PHY_REG_MP.txt" + #define RTL8821_TXPWR_LMT "rtl8821a/TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8812 Power Configuration CMDs for PCIe interface +//--------------------------------------------------------------------- +#define Rtl8812_NIC_PWR_ON_FLOW rtl8812_power_on_flow +#define Rtl8812_NIC_RF_OFF_FLOW rtl8812_radio_off_flow +#define Rtl8812_NIC_DISABLE_FLOW rtl8812_card_disable_flow +#define Rtl8812_NIC_ENABLE_FLOW rtl8812_card_enable_flow +#define Rtl8812_NIC_SUSPEND_FLOW rtl8812_suspend_flow +#define Rtl8812_NIC_RESUME_FLOW rtl8812_resume_flow +#define Rtl8812_NIC_PDN_FLOW rtl8812_hwpdn_flow +#define Rtl8812_NIC_LPS_ENTER_FLOW rtl8812_enter_lps_flow +#define Rtl8812_NIC_LPS_LEAVE_FLOW rtl8812_leave_lps_flow + +//--------------------------------------------------------------------- +// RTL8821 Power Configuration CMDs for PCIe interface +//--------------------------------------------------------------------- +#define Rtl8821A_NIC_PWR_ON_FLOW rtl8821A_power_on_flow +#define Rtl8821A_NIC_RF_OFF_FLOW rtl8821A_radio_off_flow +#define Rtl8821A_NIC_DISABLE_FLOW rtl8821A_card_disable_flow +#define Rtl8821A_NIC_ENABLE_FLOW rtl8821A_card_enable_flow +#define Rtl8821A_NIC_SUSPEND_FLOW rtl8821A_suspend_flow +#define Rtl8821A_NIC_RESUME_FLOW rtl8821A_resume_flow +#define Rtl8821A_NIC_PDN_FLOW rtl8821A_hwpdn_flow +#define Rtl8821A_NIC_LPS_ENTER_FLOW rtl8821A_enter_lps_flow +#define Rtl8821A_NIC_LPS_LEAVE_FLOW rtl8821A_leave_lps_flow + + +#if 1 // download firmware related data structure +#define FW_SIZE_8812 0x8000 // Compatible with RTL8723 Maximal RAM code size 24K. modified to 32k, TO compatible with 92d maximal fw size 32k +#define FW_START_ADDRESS 0x1000 +#define FW_END_ADDRESS 0x5FFF + + + +typedef struct _RT_FIRMWARE_8812 { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_SIZE_8812]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8812, *PRT_FIRMWARE_8812; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +#define IS_FW_HEADER_EXIST_8812(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE_8812(_pFwHdr) &0xFFF0) == 0x9500) + +#define IS_FW_HEADER_EXIST_8821(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE_8812(_pFwHdr) &0xFFF0) == 0x2100) +//===================================================== +// Firmware Header(8-byte alinment required) +//===================================================== +//--- LONG WORD 0 ---- +#define GET_FIRMWARE_HDR_SIGNATURE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 0, 16) // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut +#define GET_FIRMWARE_HDR_CATEGORY_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 16, 8) // AP/NIC and USB/PCI +#define GET_FIRMWARE_HDR_FUNCTION_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 24, 8) // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions +#define GET_FIRMWARE_HDR_VERSION_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 0, 16)// FW Version +#define GET_FIRMWARE_HDR_SUB_VER_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 16, 8) // FW Subversion, default 0x00 +#define GET_FIRMWARE_HDR_RSVD1_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 24, 8) + +//--- LONG WORD 1 ---- +#define GET_FIRMWARE_HDR_MONTH_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 0, 8) // Release time Month field +#define GET_FIRMWARE_HDR_DATE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 8, 8) // Release time Date field +#define GET_FIRMWARE_HDR_HOUR_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 16, 8)// Release time Hour field +#define GET_FIRMWARE_HDR_MINUTE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 24, 8)// Release time Minute field +#define GET_FIRMWARE_HDR_ROMCODE_SIZE_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 0, 16)// The size of RAM code +#define GET_FIRMWARE_HDR_RSVD2_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 16, 16) + +//--- LONG WORD 2 ---- +#define GET_FIRMWARE_HDR_SVN_IDX_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 0, 32)// The SVN entry index +#define GET_FIRMWARE_HDR_RSVD3_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 0, 32) + +//--- LONG WORD 3 ---- +#define GET_FIRMWARE_HDR_RSVD4_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 0, 32) +#define GET_FIRMWARE_HDR_RSVD5_8812(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+28, 0, 32) + +#endif // download firmware related data structure + + +#define DRIVER_EARLY_INT_TIME_8812 0x05 +#define BCN_DMA_ATIME_INT_TIME_8812 0x02 + +//for 8812 +// TX 128K, RX 16K, Page size 512B for TX, 128B for RX +#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80 /* RX 16K */ + +#ifdef CONFIG_WOWLAN +#define RESV_FMWF WKFMCAM_SIZE*MAX_WKFM_NUM /* 16 entries, for each is 24 bytes*/ +#else +#define RESV_FMWF 0 +#endif + +#ifdef CONFIG_FW_C2H_DEBUG +#define RX_DMA_RESERVED_SIZE_8812 0x100 // 256B, reserved for c2h debug message +#else +#define RX_DMA_RESERVED_SIZE_8812 0x0 // 0B +#endif +#define RX_DMA_BOUNDARY_8812 (MAX_RX_DMA_BUFFER_SIZE_8812 - RX_DMA_RESERVED_SIZE_8812 - 1) + +#define BCNQ_PAGE_NUM_8812 0x07 + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:1,GTK EXT MEM:1, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8812 0x05 +#else +#define WOWLAN_PAGE_NUM_8812 0x00 +#endif + + +#ifdef CONFIG_BEAMFORMER_FW_NDPA +#define FW_NDPA_PAGE_NUM 0x02 +#else +#define FW_NDPA_PAGE_NUM 0x00 +#endif + +#define TX_TOTAL_PAGE_NUMBER_8812 (0xFF - BCNQ_PAGE_NUM_8812 - WOWLAN_PAGE_NUM_8812-FW_NDPA_PAGE_NUM) +#define TX_PAGE_BOUNDARY_8812 (TX_TOTAL_PAGE_NUMBER_8812 + 1) + +#define TX_PAGE_BOUNDARY_WOWLAN_8812 (0xFF - BCNQ_PAGE_NUM_8812 - WOWLAN_PAGE_NUM_8812 + 1) + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8812 TX_TOTAL_PAGE_NUMBER_8812 +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8812 (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8812 + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8812 +#define NORMAL_PAGE_NUM_LPQ_8812 0x10 +#define NORMAL_PAGE_NUM_HPQ_8812 0x10 +#define NORMAL_PAGE_NUM_NPQ_8812 0x00 + +#define WMM_NORMAL_PAGE_NUM_HPQ_8812 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8812 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8812 0x20 + + +// for 8821A +// TX 64K, RX 16K, Page size 256B for TX, 128B for RX +#define PAGE_SIZE_TX_8821A 256 +#define PAGE_SIZE_RX_8821A 128 + +#define MAX_RX_DMA_BUFFER_SIZE_8821 0x3E80 /* RX 16K */ + +#ifdef CONFIG_FW_C2H_DEBUG +#define RX_DMA_RESERVED_SIZE_8821 0x100 // 256B, reserved for c2h debug message +#else +#define RX_DMA_RESERVED_SIZE_8821 0x0 // 0B +#endif +#define RX_DMA_BOUNDARY_8821 (MAX_RX_DMA_BUFFER_SIZE_8821 - RX_DMA_RESERVED_SIZE_8821 - 1) + +#define BCNQ_PAGE_NUM_8821 0x08 +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8821 0x04 +#else +#define BCNQ1_PAGE_NUM_8821 0x00 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:1,GTK EXT MEM:1, PNO: 6 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8821 0x06 +#else +#define WOWLAN_PAGE_NUM_8821 0x00 +#endif + +#define TX_TOTAL_PAGE_NUMBER_8821 (0xFF - BCNQ_PAGE_NUM_8821 - BCNQ1_PAGE_NUM_8821 - WOWLAN_PAGE_NUM_8821) +#define TX_PAGE_BOUNDARY_8821 (TX_TOTAL_PAGE_NUMBER_8821 + 1) +//#define TX_PAGE_BOUNDARY_WOWLAN_8821 0xE0 + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8821 TX_TOTAL_PAGE_NUMBER_8821 +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8821 (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8821 + 1) + + +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER +#define NORMAL_PAGE_NUM_LPQ_8821 0x08//0x10 +#define NORMAL_PAGE_NUM_HPQ_8821 0x08//0x10 +#define NORMAL_PAGE_NUM_NPQ_8821 0x00 + +#define WMM_NORMAL_PAGE_NUM_HPQ_8821 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8821 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8821 0x20 + + +#define EFUSE_HIDDEN_812AU 0 +#define EFUSE_HIDDEN_812AU_VS 1 +#define EFUSE_HIDDEN_812AU_VL 2 +#define EFUSE_HIDDEN_812AU_VN 3 + +#if 0 +#define EFUSE_REAL_CONTENT_LEN_JAGUAR 1024 +#define HWSET_MAX_SIZE_JAGUAR 1024 +#else +#define EFUSE_REAL_CONTENT_LEN_JAGUAR 512 +#define HWSET_MAX_SIZE_JAGUAR 512 +#endif + +#define EFUSE_MAX_BANK_8812A 2 +#define EFUSE_MAP_LEN_JAGUAR 512 +#define EFUSE_MAX_SECTION_JAGUAR 64 +#define EFUSE_MAX_WORD_UNIT_JAGUAR 4 +#define EFUSE_IC_ID_OFFSET_JAGUAR 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR_8812(addr) (addr < EFUSE_REAL_CONTENT_LEN_JAGUAR) +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 2byte|----8bytes----|1byte|--7bytes--| //92D +#define EFUSE_OOB_PROTECT_BYTES_JAGUAR 18 // PG data exclude header, dummy 7 bytes frome CP test and reserved 1byte. +#define EFUSE_PROTECT_BYTES_BANK_JAGUAR 16 +// Added for different registry settings to adjust TxPwr index. added by Roger, 2010.03.09. +typedef enum _TX_PWR_PERCENTAGE{ + TX_PWR_PERCENTAGE_0 = 0x01, // 12.5% + TX_PWR_PERCENTAGE_1 = 0x02, // 25% + TX_PWR_PERCENTAGE_2 = 0x04, // 50% + TX_PWR_PERCENTAGE_3 = 0x08, //100%, default target output power. +} TX_PWR_PERCENTAGE; + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +//#define IS_MULTI_FUNC_CHIP(_Adapter) (((((PHAL_DATA_TYPE)(_Adapter->HalData))->MultiFunc) & (RT_MULTI_FUNC_BT|RT_MULTI_FUNC_GPS)) ? _TRUE : _FALSE) + +//#define RT_IS_FUNC_DISABLED(__pAdapter, __FuncBits) ( (__pAdapter)->DisabledFunctions & (__FuncBits) ) + +// rtl8812_hal_init.c +void _8051Reset8812(PADAPTER padapter); +s32 FirmwareDownload8812(PADAPTER Adapter, BOOLEAN bUsedWoWLANFw); +void InitializeFirmwareVars8812(PADAPTER padapter); + +s32 _LLTWrite_8812A(PADAPTER Adapter, u32 address, u32 data); +s32 InitLLTTable8812A(PADAPTER padapter, u8 txpktbuf_bndy); +void InitRDGSetting8812A(PADAPTER padapter); + +void CheckAutoloadState8812A(PADAPTER padapter); + +// EFuse +u8 GetEEPROMSize8812A(PADAPTER padapter); +void InitPGData8812A(PADAPTER padapter); +void Hal_EfuseParseIDCode8812A(PADAPTER padapter, u8 *hwinfo); +void Hal_ReadPROMVersion8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_ReadTxPowerInfo8812A(PADAPTER padapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadBoardType8812A(PADAPTER pAdapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadThermalMeter_8812A(PADAPTER Adapter, u8* PROMContent,BOOLEAN AutoloadFail); +void Hal_ReadChannelPlan8812A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8812A(PADAPTER pAdapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void Hal_ReadAntennaDiversity8812A(PADAPTER pAdapter,u8* PROMContent,BOOLEAN AutoLoadFail); +void Hal_ReadAntennaDiversity8821A(PADAPTER pAdapter, u8* PROMContent, BOOLEAN AutoLoadFail); +void Hal_ReadAmplifierType_8812A(PADAPTER Adapter,u8* PROMContent, BOOLEAN AutoloadFail); +void Hal_ReadPAType_8821A(PADAPTER Adapter,u8* PROMContent, BOOLEAN AutoloadFail); +void Hal_ReadRFEType_8812A(PADAPTER Adapter,u8* PROMContent, BOOLEAN AutoloadFail); +void Hal_EfuseParseBTCoexistInfo8812A(PADAPTER Adapter, u8* hwinfo, BOOLEAN AutoLoadFail); +void hal_ReadUsbType_8812AU(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +int FirmwareDownloadBT(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware); +void Hal_ReadRemoteWakeup_8812A(PADAPTER padapter, u8* hwinfo, BOOLEAN AutoLoadFail); + +BOOLEAN HalDetectPwrDownMode8812(PADAPTER Adapter); +void Hal_EfuseParseKFreeData_8821A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); + +#ifdef CONFIG_WOWLAN +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void _InitBeaconParameters_8812A(PADAPTER padapter); +void SetBeaconRelatedRegisters8812A(PADAPTER padapter); + +void ReadRFType8812A(PADAPTER padapter); +void InitDefaultValue8821A(PADAPTER padapter); + +void SetHwReg8812A(PADAPTER padapter, u8 variable, u8 *pval); +void GetHwReg8812A(PADAPTER padapter, u8 variable, u8 *pval); +u8 SetHalDefVar8812A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8812A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +s32 c2h_id_filter_ccx_8812a(u8 *buf); +void rtl8812_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8812a(_adapter *adapter); +void init_hal_spec_8821a(_adapter *adapter); + +// register +void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits); + +void rtl8812_start_thread(PADAPTER padapter); +void rtl8812_stop_thread(PADAPTER padapter); + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8812AE(PADAPTER Adapter); +VOID UpdateInterruptMask8812AE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +#endif + +#ifdef CONFIG_BT_COEXIST +void rtl8812a_combo_card_WifiOnlyHwInit(PADAPTER Adapter); +#endif + +VOID +Hal_PatchwithJaguar_8812( + IN PADAPTER Adapter, + IN RT_MEDIA_STATUS MediaStatus + ); + +#endif //__RTL8188E_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_led.h new file mode 100644 index 00000000..52eb6e00 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * 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 __RTL8812A_LED_H__ +#define __RTL8812A_LED_H__ + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8812au_InitSwLeds(PADAPTER padapter); +void rtl8812au_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_PCI_HCI +void rtl8812ae_InitSwLeds(PADAPTER padapter); +void rtl8812ae_DeInitSwLeds(PADAPTER padapter); +#endif +#ifdef CONFIG_SDIO_HCI +void rtl8821as_InitSwLeds(PADAPTER padapter); +void rtl8821as_DeInitSwLeds(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_recv.h new file mode 100644 index 00000000..ff5fa76c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_recv.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * + * 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 __RTL8812A_RECV_H__ +#define __RTL8812A_RECV_H__ + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + #define MAX_RECVBUF_SZ (rtw_rtkm_get_buff_size()) /*depend rtkm*/ + #else + #define MAX_RECVBUF_SZ (32768) /*32k*/ + #endif + //#define MAX_RECVBUF_SZ (24576) // 24k + //#define MAX_RECVBUF_SZ (20480) //20K + //#define MAX_RECVBUF_SZ (10240) //10K + //#define MAX_RECVBUF_SZ (15360) // 15k < 16k + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #ifdef CONFIG_PLATFORM_NOVATEK_NT72668 + #undef MAX_RECVBUF_SZ + #define MAX_RECVBUF_SZ (15360) // 15k < 16k + #endif //CONFIG_PLATFORM_NOVATEK_NT72668 + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) + +#define MAX_RECVBUF_SZ (RX_DMA_BOUNDARY_8821 + 1) + +#endif + + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + + +#ifdef CONFIG_SDIO_HCI +s32 InitRecvPriv8821AS(PADAPTER padapter); +void FreeRecvPriv8821AS(PADAPTER padapter); +#endif // CONFIG_SDIO_HCI + +#ifdef CONFIG_USB_HCI +void rtl8812au_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf); +s32 rtl8812au_init_recv_priv(PADAPTER padapter); +void rtl8812au_free_recv_priv(PADAPTER padapter); +void rtl8812au_recv_hdl(PADAPTER padapter, struct recv_buf *precvbuf); +void rtl8812au_recv_tasklet(void *priv); + +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8812ae_init_recv_priv(PADAPTER padapter); +void rtl8812ae_free_recv_priv(PADAPTER padapter); +#endif + +void rtl8812_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); + +#endif /* __RTL8812A_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_rf.h new file mode 100644 index 00000000..e87b8853 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_rf.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * 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 __RTL8812A_RF_H__ +#define __RTL8812A_RF_H__ + +VOID +PHY_RF6052SetBandwidth8812( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + + +int +PHY_RF6052_Config_8812( + IN PADAPTER Adapter ); + +#endif//__RTL8188E_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_spec.h new file mode 100644 index 00000000..eab6d1c5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_spec.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * + * 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 __RTL8812A_SPEC_H__ +#define __RTL8812A_SPEC_H__ + +#include + + +//============================================================ +// 8812 Regsiter offset definition +//============================================================ + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_CLKR_8812A 0x0008 +#define REG_AFE_PLL_CTRL_8812A 0x0028 +#define REG_HSIMR_8812 0x0058 +#define REG_HSISR_8812 0x005c +#define REG_GPIO_EXT_CTRL 0x0060 +#define REG_GPIO_STATUS_8812 0x006C +#define REG_SDIO_CTRL_8812 0x0070 +#define REG_OPT_CTRL_8812 0x0074 +#define REG_RF_B_CTRL_8812 0x0076 +#define REG_FW_DRV_MSG_8812 0x0088 +#define REG_HMEBOX_E2_E3_8812 0x008C +#define REG_HIMR0_8812 0x00B0 +#define REG_HISR0_8812 0x00B4 +#define REG_HIMR1_8812 0x00B8 +#define REG_HISR1_8812 0x00BC +#define REG_EFUSE_BURN_GNT_8812 0x00CF +#define REG_SYS_CFG1_8812 0x00FC + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR_8812A 0x100 +#define REG_PKTBUF_DBG_ADDR (REG_PKTBUF_DBG_CTRL) +#define REG_RXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+2) +#define REG_TXPKTBUF_DBG (REG_PKTBUF_DBG_CTRL+3) +#define REG_WOWLAN_WAKE_REASON REG_MCUTST_WOWLAN + +#define REG_RSVD3_8812 0x0168 +#define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 +#define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 +#define REG_C2HEVT_CMD_LEN_88XX 0x01AE + +#define REG_HMEBOX_EXT0_8812 0x01F0 +#define REG_HMEBOX_EXT1_8812 0x01F4 +#define REG_HMEBOX_EXT2_8812 0x01F8 +#define REG_HMEBOX_EXT3_8812 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_DWBCN0_CTRL_8812 REG_TDECTRL +#define REG_DWBCN1_CTRL_8812 0x0228 + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_TDECTRL_8812A 0x0208 +#define REG_RXDMA_CONTROL_8812A 0x0286 /*Control the RX DMA.*/ +#define REG_RXDMA_PRO_8812 0x0290 +#define REG_EARLY_MODE_CONTROL_8812 0x02BC +#define REG_RSVD5_8812 0x02F0 +#define REG_RSVD6_8812 0x02F4 +#define REG_RSVD7_8812 0x02F8 +#define REG_RSVD8_8812 0x02FC + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8812A 0x0300 +#define REG_DBI_WDATA_8812 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8812 0x034C // DBI Read Data +#define REG_DBI_ADDR_8812 0x0350 // DBI Address +#define REG_DBI_FLAG_8812 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8812 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8812 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8812 0x0358 // MDIO for Control +#define REG_PCIE_MULTIFET_CTRL_8812 0x036A //PCIE Multi-Fethc Control + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_TXPKT_EMPTY_8812A 0x041A +#define REG_FWHW_TXQ_CTRL_8812A 0x0420 +#define REG_TXBF_CTRL_8812A 0x042C +#define REG_ARFR0_8812 0x0444 +#define REG_ARFR1_8812 0x044C +#define REG_CCK_CHECK_8812 0x0454 +#define REG_AMPDU_MAX_TIME_8812 0x0456 +#define REG_TXPKTBUF_BCNQ_BDNY1_8812 0x0457 + +#define REG_AMPDU_MAX_LENGTH_8812 0x0458 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8812 0x045D +#define REG_NDPA_OPT_CTRL_8812A 0x045F +#define REG_DATA_SC_8812 0x0483 +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif +#define REG_ARFR2_8812 0x048C +#define REG_ARFR3_8812 0x0494 +#define REG_TXRPT_START_OFFSET 0x04AC +#define REG_AMPDU_BURST_MODE_8812 0x04BC +#define REG_HT_SINGLE_AMPDU_8812 0x04C7 +#define REG_MACID_PKT_DROP0_8812 0x04D0 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_TXPAUSE_8812A 0x0522 +#define REG_CTWND_8812 0x0572 +#define REG_SECONDARY_CCA_CTRL_8812 0x0577 +#define REG_SCH_TXCMD_8812A 0x05F8 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8812 0x0600 + +#define REG_MAC_TX_SM_STATE_8812 0x06B4 + +// Power +#define REG_BFMER0_INFO_8812A 0x06E4 +#define REG_BFMER1_INFO_8812A 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8812A 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8812A 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8812A 0x06FC + +// Hardware Port 2 +#define REG_BFMEE_SEL_8812A 0x0714 +#define REG_SND_PTCL_CTRL_8812A 0x0718 + + +//----------------------------------------------------- +// +// Redifine register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define ISR_8812 REG_HISR0_8812 + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8812 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8812 BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8812 BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8812 BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8812 BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8812 BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8812 BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8812 BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8812 BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8812 BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8812 BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8812 BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8812 BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8812 BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8812 BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8812 BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8812 BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8812 BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8812 BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8812 BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8812 BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8812 BIT3 // AC_VI DMA OK +#define IMR_VODOK_8812 BIT2 // AC_VO DMA OK +#define IMR_RDU_8812 BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8812 BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_8812 BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8812 BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8812 BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8812 BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8812 BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8812 BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8812 BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8812 BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8812 BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8812 BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8812 BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8812 BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8812 BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8812 BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8812 BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8812 BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8812 BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8812 BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8812 BIT8 // Receive FIFO Overflow + + +#ifdef CONFIG_PCI_HCI +//#define IMR_RX_MASK (IMR_ROK_8812|IMR_RDU_8812|IMR_RXFOVW_8812) +#define IMR_TX_MASK (IMR_VODOK_8812|IMR_VIDOK_8812|IMR_BEDOK_8812|IMR_BKDOK_8812|IMR_MGNTDOK_8812|IMR_HIGHDOK_8812) + +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8812 | IMR_TXBCN0OK_8812 | IMR_TXBCN0ERR_8812 | IMR_BCNDERR0_8812) + +#define RT_AC_INT_MASKS (IMR_VIDOK_8812 | IMR_VODOK_8812 | IMR_BEDOK_8812|IMR_BKDOK_8812) +#endif + + +//============================================================================ +// Regsiter Bit and Content definition +//============================================================================ + +//2 ACMHWCTRL 0x05C0 +#define AcmHw_HwEn_8812 BIT(0) +#define AcmHw_VoqEn_8812 BIT(1) +#define AcmHw_ViqEn_8812 BIT(2) +#define AcmHw_BeqEn_8812 BIT(3) +#define AcmHw_VoqStatus_8812 BIT(5) +#define AcmHw_ViqStatus_8812 BIT(6) +#define AcmHw_BeqStatus_8812 BIT(7) + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8812A 128 +#define SEC_CAM_ENT_NUM_8812A 64 +#define NSS_NUM_8812A 2 +#define BAND_CAP_8812A (BAND_CAP_2G | BAND_CAP_5G) +#define BW_CAP_8812A (BW_CAP_20M | BW_CAP_40M | BW_CAP_80M) + +#endif /* __RTL8812A_SPEC_H__ */ + +#ifdef CONFIG_RTL8821A +#include "rtl8821a_spec.h" +#endif /* CONFIG_RTL8821A */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_sreset.h new file mode 100644 index 00000000..53f39d76 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL88812A_SRESET_H_ +#define _RTL8812A_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8812_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8812_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_xmit.h new file mode 100644 index 00000000..42e1a889 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8812a_xmit.h @@ -0,0 +1,365 @@ +/****************************************************************************** + * + * 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 __RTL8812A_XMIT_H__ +#define __RTL8812A_XMIT_H__ + + +//For 88e early mode +#define SET_EARLYMODE_PKTNUM(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 3, __Value) +#define SET_EARLYMODE_LEN0(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 12, __Value) +#define SET_EARLYMODE_LEN1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 16, 12, __Value) +#define SET_EARLYMODE_LEN2_1(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 28, 4, __Value) +#define SET_EARLYMODE_LEN2_2(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 8, __Value) +#define SET_EARLYMODE_LEN3(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 8, 12, __Value) +#define SET_EARLYMODE_LEN4(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 20, 12, __Value) + +// +//defined for TX DESC Operation +// + +#define MAX_TID (15) + +//OFFSET 0 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define BMC BIT(24) +#define LSG BIT(26) +#define FSG BIT(27) +#define OWN BIT(31) + + +//OFFSET 4 +#define PKT_OFFSET_SZ 0 +#define QSEL_SHT 8 +#define RATE_ID_SHT 16 +#define NAVUSEHDR BIT(20) +#define SEC_TYPE_SHT 22 +#define PKT_OFFSET_SHT 26 + +//OFFSET 8 +#define AGG_EN BIT(12) +#define AGG_BK BIT(16) +#define AMPDU_DENSITY_SHT 20 +#define ANTSEL_A BIT(24) +#define ANTSEL_B BIT(25) +#define TX_ANT_CCK_SHT 26 +#define TX_ANTL_SHT 28 +#define TX_ANT_HT_SHT 30 + +//OFFSET 12 +#define SEQ_SHT 16 +#define EN_HWSEQ BIT(31) + +//OFFSET 16 +#define QOS BIT(6) +#define HW_SSN BIT(7) +#define USERATE BIT(8) +#define DISDATAFB BIT(10) +#define CTS_2_SELF BIT(11) +#define RTS_EN BIT(12) +#define HW_RTS_EN BIT(13) +#define DATA_SHORT BIT(24) +#define PWR_STATUS_SHT 15 +#define DATA_SC_SHT 20 +#define DATA_BW BIT(25) + +//OFFSET 20 +#define RTY_LMT_EN BIT(17) + +//OFFSET 20 +#define SGI BIT(6) +#define USB_TXAGG_NUM_SHT 24 + +typedef struct txdescriptor_8812 +{ + // Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 ls:1; + u32 fs:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 own:1; + + // Offset 4 + u32 macid:6; + u32 rsvd0406:2; + u32 qsel:5; + u32 rd_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rate_id:4; + u32 navusehdr:1; + u32 en_desc_id:1; + u32 sectype:2; + u32 rsvd0424:2; + u32 pkt_offset:5; // unit: 8 bytes + u32 rsvd0431:1; + + // Offset 8 + u32 rts_rc:6; + u32 data_rc:6; + u32 agg_en:1; + u32 rd_en:1; + u32 bar_rty_th:2; + u32 bk:1; + u32 morefrag:1; + u32 raw:1; + u32 ccx:1; + u32 ampdu_density:3; + u32 bt_null:1; + u32 ant_sel_a:1; + u32 ant_sel_b:1; + u32 tx_ant_cck:2; + u32 tx_antl:2; + u32 tx_ant_ht:2; + + // Offset 12 + u32 nextheadpage:8; + u32 tailpage:8; + u32 seq:12; + u32 cpu_handle:1; + u32 tag1:1; + u32 trigger_int:1; + u32 hwseq_en:1; + + // Offset 16 + u32 rtsrate:5; + u32 ap_dcfe:1; + u32 hwseq_sel:2; + u32 userate:1; + u32 disrtsfb:1; + u32 disdatafb:1; + u32 cts2self:1; + u32 rtsen:1; + u32 hw_rts_en:1; + u32 port_id:1; + u32 pwr_status:3; + u32 wait_dcts:1; + u32 cts2ap_en:1; + u32 data_sc:2; + u32 data_stbc:2; + u32 data_short:1; + u32 data_bw:1; + u32 rts_short:1; + u32 rts_bw:1; + u32 rts_sc:2; + u32 vcs_stbc:2; + + // Offset 20 + u32 datarate:6; + u32 sgi:1; + u32 try_rate:1; + u32 data_ratefb_lmt:5; + u32 rts_ratefb_lmt:4; + u32 rty_lmt_en:1; + u32 data_rt_lmt:6; + u32 usb_txagg_num:8; + + // Offset 24 + u32 txagg_a:5; + u32 txagg_b:5; + u32 use_max_len:1; + u32 max_agg_num:5; + u32 mcsg1_max_len:4; + u32 mcsg2_max_len:4; + u32 mcsg3_max_len:4; + u32 mcs7_sgi_max_len:4; + + // Offset 28 + u32 checksum:16; // TxBuffSize(PCIe)/CheckSum(USB) + u32 mcsg4_max_len:4; + u32 mcsg5_max_len:4; + u32 mcsg6_max_len:4; + u32 mcs15_sgi_max_len:4; + + // Offset 32 + u32 rsvd32; + + // Offset 36 + u32 rsvd36; +}TXDESC_8812, *PTXDESC_8812; + + +// Dword 0 +#define GET_TX_DESC_OWN_8812(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) +#define SET_TX_DESC_PKT_SIZE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) + +// Dword 2 +#define SET_TX_DESC_PAID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) +#define SET_TX_DESC_TX_ANT_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 24, 4, __Value) + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_ANTSEL_A_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) +#define SET_TX_DESC_MBSSID_8821(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) + +// Dword 7 +#define SET_TX_DESC_TX_BUFFER_SIZE_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#define SET_TX_DESC_TX_DESC_CHECKSUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#define SET_TX_DESC_USB_TXAGG_NUM_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#ifdef CONFIG_SDIO_HCI +#define SET_TX_DESC_SDIO_TXSEQ_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) + +// Dword 9 +#define SET_TX_DESC_SEQ_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) + +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_8812(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+40, 0, 32) + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8812(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) + + +#define SET_EARLYMODE_PKTNUM_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8812(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +#ifdef CONFIG_TX_EARLY_MODE +#define USB_DUMMY_OFFSET 2 +#else +#define USB_DUMMY_OFFSET 1 +#endif +#define USB_DUMMY_LENGTH (USB_DUMMY_OFFSET * PACKET_OFFSET_SZ) + + +void rtl8812a_cal_txdesc_chksum(u8 *ptxdesc); +void rtl8812a_fill_fake_txdesc(PADAPTER padapter,u8*pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull, u8 bDataFrame); +void rtl8812a_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); +void rtl8812a_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); +void rtl8812a_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); + +#ifdef CONFIG_USB_HCI +s32 rtl8812au_init_xmit_priv(PADAPTER padapter); +void rtl8812au_free_xmit_priv(PADAPTER padapter); +s32 rtl8812au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8812au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8812au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8812au_xmit_buf_handler(PADAPTER padapter); +void rtl8812au_xmit_tasklet(void *priv); +s32 rtl8812au_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8812ae_init_xmit_priv(PADAPTER padapter); +void rtl8812ae_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8812ae_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8812ae_xmitframe_resume(_adapter *padapter); +s32 rtl8812ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8812ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8812ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8812ae_xmit_tasklet(void *priv); +#endif + +#ifdef CONFIG_TX_EARLY_MODE +void UpdateEarlyModeInfo8812(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf ); +#endif + +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,u8 *ptxdesc); + +u8 BWMapping_8812(PADAPTER Adapter, struct pkt_attrib *pattrib); + +u8 SCMapping_8812(PADAPTER Adapter, struct pkt_attrib *pattrib); + +#endif //__RTL8812_XMIT_H__ + +#ifdef CONFIG_RTL8821A +#include "rtl8821a_xmit.h" +#endif // CONFIG_RTL8821A + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_cmd.h new file mode 100644 index 00000000..6f9cdc2e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_cmd.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * 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 __RTL8814A_CMD_H__ +#define __RTL8814A_CMD_H__ +#include "hal_com_h2c.h" + +//_RSVDPAGE_LOC_CMD0 +#define SET_8814A_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8814A_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8814A_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8814A_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8814A_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_SETPWRMODE_PARM +#define SET_8814A_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8814A_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +#define GET_8814A_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + + +// _WoWLAN PARAM_CMD5 +#define SET_8814A_H2CCMD_WOWLAN_FUNC_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_ALL_PKT_DROP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_GPIO_ACTIVE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_REKEY_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#define SET_8814A_H2CCMD_WOWLAN_GPIONUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8814A_H2CCMD_WOWLAN_GPIO_DURATION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) + + +//WLANINFO_PARM +#define SET_8814A_H2CCMD_WLANINFO_PARM_OPMODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8814A_H2CCMD_WLANINFO_PARM_CHANNEL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8814A_H2CCMD_WLANINFO_PARM_BW40MHZ(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) + +// _REMOTE_WAKEUP_CMD7 +#define SET_8814A_H2CCMD_REMOTE_WAKECTRL_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8814A_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8814A_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8814A_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) + + +// _AP_OFFLOAD_CMD8 +#define SET_8814A_H2CCMD_AP_OFFLOAD_ON(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8814A_H2CCMD_AP_OFFLOAD_HIDDEN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8814A_H2CCMD_AP_OFFLOAD_DENYANY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8814A_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) + +// _PWR_MOD_CMD20 +#define SET_88E_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_88E_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_88E_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_88E_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_88E_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_88E_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +/*BCNHWSEQ*/ +#define SET_8814A_H2CCMD_BCNHWSEQ_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 1, __Value) +#define SET_8814A_H2CCMD_BCNHWSEQ_BCN_NUMBER(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 1, 3, __Value) +#define SET_8814A_H2CCMD_BCNHWSEQ_HWSEQ(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 6, 1, __Value) +#define SET_8814A_H2CCMD_BCNHWSEQ_EXHWSEQ(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 7, 1, __Value) +#define SET_8814A_H2CCMD_BCNHWSEQ_PAGE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +void rtl8814_fw_update_beacon_cmd(_adapter *padapter); + +// TX Beamforming +#define GET_8814A_C2H_TXBF_ORIGINATE(_Header) LE_BITS_TO_1BYTE(_Header, 0, 8) +#define GET_8814A_C2H_TXBF_MACID(_Header) LE_BITS_TO_1BYTE((_Header + 1), 0, 8) + + + +/// TX Feedback Content +#define USEC_UNIT_FOR_8814A_C2H_TX_RPT_QUEUE_TIME 256 + +#define GET_8814A_C2H_TX_RPT_QUEUE_SELECT(_Header) LE_BITS_TO_1BYTE((_Header + 0), 0, 5) +#define GET_8814A_C2H_TX_RPT_PKT_BROCAST(_Header) LE_BITS_TO_1BYTE((_Header + 0), 5, 1) +#define GET_8814A_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1) +#define GET_8814A_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1) +#define GET_8814A_C2H_TX_RPT_MAC_ID(_Header) LE_BITS_TO_1BYTE((_Header + 1), 0, 8) +#define GET_8814A_C2H_TX_RPT_DATA_RETRY_CNT(_Header) LE_BITS_TO_1BYTE((_Header + 2), 0, 6) +#define GET_8814A_C2H_TX_RPT_QUEUE_TIME(_Header) LE_BITS_TO_2BYTE((_Header + 3), 0, 16) // In unit of 256 microseconds. +#define GET_8814A_C2H_TX_RPT_FINAL_DATA_RATE(_Header) LE_BITS_TO_1BYTE((_Header + 5), 0, 8) + + +//_P2P_PS_OFFLOAD +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ROLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_CTWINDOW_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA0_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA1_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) + +s32 FillH2CCmd_8814(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); +void rtl8814_set_raid_cmd(PADAPTER padapter, u64 bitmap, u8* arg); +void rtl8814_Add_RateATid(PADAPTER padapter, u64 rate_bitmap, u8 *arg, u8 rssi_level); +void rtl8814_set_wowlan_cmd(_adapter* padapter, u8 enable); +void rtl8814_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus); +void rtl8814_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode); +u8 GetTxBufferRsvdPageNum8814(_adapter *padapter, bool wowlan); +u8 rtl8814_set_rssi_cmd(_adapter*padapter, u8 *param); + +void +Set_RA_LDPC_8814( + struct sta_info *psta, + BOOLEAN bLDPC + ); +int rtl8814_iqk_wait(_adapter* padapter, u32 timeout_ms); +void rtl8814_iqk_done(_adapter* padapter); +VOID +C2HPacketHandler_8814( + IN PADAPTER Adapter, + IN u8 *Buffer, + IN u8 Length + ); +#ifdef CONFIG_P2P_PS +void rtl8814_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +s32 +_C2HContentParsing8814( + IN PADAPTER Adapter, + IN u8 c2hCmdId, + IN u8 c2hCmdLen, + IN u8 *tmpBuf +); + +#endif/* __RTL8814A_CMD_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_dm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_dm.h new file mode 100644 index 00000000..48837700 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_dm.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * 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 __RTL8814A_DM_H__ +#define __RTL8814A_DM_H__ + +void rtl8814_init_dm_priv(IN PADAPTER Adapter); +void rtl8814_deinit_dm_priv(IN PADAPTER Adapter); +void rtl8814_InitHalDm(IN PADAPTER Adapter); +void rtl8814_HalDmWatchDog(IN PADAPTER Adapter); + +#ifdef CONFIG_ANTENNA_DIVERSITY +void AntDivCompare8814(PADAPTER Adapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +u8 AntDivBeforeLink8814(PADAPTER Adapter ); +#endif //CONFIG_ANTENNA_DIVERSITY + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_hal.h new file mode 100644 index 00000000..842ddc69 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_hal.h @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * 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 __RTL8814A_HAL_H__ +#define __RTL8814A_HAL_H__ + +//#include "hal_com.h" +#include "hal_data.h" + +//include HAL Related header after HAL Related compiling flags +#include "rtl8814a_spec.h" +#include "rtl8814a_rf.h" +#include "rtl8814a_dm.h" +#include "rtl8814a_recv.h" +#include "rtl8814a_xmit.h" +#include "rtl8814a_cmd.h" +#include "rtl8814a_led.h" +#include "Hal8814PwrSeq.h" +#include "Hal8814PhyReg.h" +#include "Hal8814PhyCfg.h" +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8814a_sreset.h" +#endif //DBG_CONFIG_ERROR_DETECT + + +typedef enum _TX_PWR_PERCENTAGE{ + TX_PWR_PERCENTAGE_0 = 0x01, // 12.5% + TX_PWR_PERCENTAGE_1 = 0x02, // 25% + TX_PWR_PERCENTAGE_2 = 0x04, // 50% + TX_PWR_PERCENTAGE_3 = 0x08, //100%, default target output power. +} TX_PWR_PERCENTAGE; + + +enum{ + VOLTAGE_V25 = 0x03, + LDOE25_SHIFT = 28 , + }; +/* max. iram is 64k , max dmen is 32k. Total = 96k = 0x18000*/ +#define FW_SIZE 0x18000 +#define FW_START_ADDRESS 0x1000 +typedef struct _RT_FIRMWARE_8814 { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_SIZE]; +#endif + u32 ulFwLength; +} RT_FIRMWARE_8814, *PRT_FIRMWARE_8814; + +#define PAGE_SIZE_TX_8814 PAGE_SIZE_128 +#define BCNQ_PAGE_NUM_8814 0x08 + +//--------------------------------------------------------------------- +// RTL8814AU From header +//--------------------------------------------------------------------- + #define RTL8814A_FW_IMG "rtl8814a/FW_NIC.bin" + #define RTL8814A_FW_WW_IMG "rtl8814a/FW_WoWLAN.bin" + #define RTL8814A_PHY_REG "rtl8814a/PHY_REG.txt" + #define RTL8814A_PHY_RADIO_A "rtl8814a/RadioA.txt" + #define RTL8814A_PHY_RADIO_B "rtl8814a/RadioB.txt" + #define RTL8814A_PHY_RADIO_C "rtl8814a/RadioC.txt" + #define RTL8814A_PHY_RADIO_D "rtl8814a/RadioD.txt" + #define RTL8814A_TXPWR_TRACK "rtl8814a/TxPowerTrack.txt" + #define RTL8814A_AGC_TAB "rtl8814a/AGC_TAB.txt" + #define RTL8814A_PHY_MACREG "rtl8814a/MAC_REG.txt" + #define RTL8814A_PHY_REG_PG "rtl8814a/PHY_REG_PG.txt" + #define RTL8814A_PHY_REG_MP "rtl8814a/PHY_REG_MP.txt" + #define RTL8814A_TXPWR_LMT "rtl8814a/TXPWR_LMT.txt" + #define RTL8814A_WIFI_ANT_ISOLATION "rtl8814a/wifi_ant_isolation.txt" + +#define Rtl8814A_NIC_PWR_ON_FLOW rtl8814A_power_on_flow +#define Rtl8814A_NIC_RF_OFF_FLOW rtl8814A_radio_off_flow +#define Rtl8814A_NIC_DISABLE_FLOW rtl8814A_card_disable_flow +#define Rtl8814A_NIC_ENABLE_FLOW rtl8814A_card_enable_flow +#define Rtl8814A_NIC_SUSPEND_FLOW rtl8814A_suspend_flow +#define Rtl8814A_NIC_RESUME_FLOW rtl8814A_resume_flow +#define Rtl8814A_NIC_PDN_FLOW rtl8814A_hwpdn_flow +#define Rtl8814A_NIC_LPS_ENTER_FLOW rtl8814A_enter_lps_flow +#define Rtl8814A_NIC_LPS_LEAVE_FLOW rtl8814A_leave_lps_flow + +//===================================================== +// New Firmware Header(8-byte alinment required) +//===================================================== +//--- LONG WORD 0 ---- +#define GET_FIRMWARE_HDR_SIGNATURE_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 0, 16) +#define GET_FIRMWARE_HDR_CATEGORY_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 16, 8) // AP/NIC and USB/PCI +#define GET_FIRMWARE_HDR_FUNCTION_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr, 24, 8) // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions +#define GET_FIRMWARE_HDR_VERSION_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 0, 16)// FW Version +#define GET_FIRMWARE_HDR_SUB_VER_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 16, 8) // FW Subversion, default 0x00 +#define GET_FIRMWARE_HDR_SUB_IDX_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+4, 24, 8) // FW Subversion Index + +//--- LONG WORD 1 ---- +#define GET_FIRMWARE_HDR_SVN_IDX_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+8, 0, 32)// The SVN entry index +#define GET_FIRMWARE_HDR_RSVD1_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+12, 0, 32) + +//--- LONG WORD 2 ---- +#define GET_FIRMWARE_HDR_MONTH_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 0, 8) // Release time Month field +#define GET_FIRMWARE_HDR_DATE_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 8, 8) // Release time Date field +#define GET_FIRMWARE_HDR_HOUR_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 16, 8)// Release time Hour field +#define GET_FIRMWARE_HDR_MINUTE_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+16, 24, 8)// Release time Minute field +#define GET_FIRMWARE_HDR_YEAR_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 0, 16)// Release time Year field +#define GET_FIRMWARE_HDR_FOUNDRY_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 16, 8)// Release time Foundry field +#define GET_FIRMWARE_HDR_RSVD2_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+20, 24, 8) + +//--- LONG WORD 3 ---- +#define GET_FIRMWARE_HDR_MEM_UASGE_DL_FROM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 0, 1) +#define GET_FIRMWARE_HDR_MEM_UASGE_BOOT_FROM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 1, 1) +#define GET_FIRMWARE_HDR_MEM_UASGE_BOOT_LOADER_3081(__FwHdr)LE_BITS_TO_4BYTE(__FwHdr+24, 2, 1) +#define GET_FIRMWARE_HDR_MEM_UASGE_IRAM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 3, 1) +#define GET_FIRMWARE_HDR_MEM_UASGE_ERAM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 4, 1) +#define GET_FIRMWARE_HDR_MEM_UASGE_RSVD4_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 5, 3) +#define GET_FIRMWARE_HDR_RSVD3_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 8, 8) +#define GET_FIRMWARE_HDR_BOOT_LOADER_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+24, 16, 16) +#define GET_FIRMWARE_HDR_RSVD5_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+28, 0, 32) + +//--- LONG WORD 4 ---- +#define GET_FIRMWARE_HDR_TOTAL_DMEM_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+36, 0, 32) +#define GET_FIRMWARE_HDR_FW_CFG_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+36, 0, 16) +#define GET_FIRMWARE_HDR_FW_ATTR_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+36, 16, 16) + +//--- LONG WORD 5 ---- +#define GET_FIRMWARE_HDR_IROM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+40, 0, 32) +#define GET_FIRMWARE_HDR_EROM_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+44, 0, 32) + +//--- LONG WORD 6 ---- +#define GET_FIRMWARE_HDR_IRAM_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+48, 0, 32) +#define GET_FIRMWARE_HDR_ERAM_SZ_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+52, 0, 32) + +//--- LONG WORD 7 ---- +#define GET_FIRMWARE_HDR_RSVD6_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+56, 0, 32) +#define GET_FIRMWARE_HDR_RSVD7_3081(__FwHdr) LE_BITS_TO_4BYTE(__FwHdr+60, 0, 32) + + + +// +// 2013/08/16 MH MOve from SDIO.h for common use. +// +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_USB_HCI) +#define TRX_SHARE_MODE_8814A 0 //TRX Buffer Share Index +#define BASIC_RXFF_SIZE_8814A 24576//Basic RXFF Size is 24K = 24*1024 Unit: Byte +#define TRX_SHARE_BUFF_UNIT_8814A 65536//TRX Share Buffer unit Size 64K = 64*1024 Unit: Byte +#define TRX_SHARE_BUFF_UNIT_PAGE_8814A TRX_SHARE_BUFF_UNIT_8814A/PAGE_SIZE_8814A//512 Pages + +//Origin: +#define HPQ_PGNUM_8814A 0x20 //High Queue +#define LPQ_PGNUM_8814A 0x20 //Low Queue +#define NPQ_PGNUM_8814A 0x20 //Normal Queue +#define EPQ_PGNUM_8814A 0x20 //Extra Queue + +#else // #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_USB_HCI) + +#define HPQ_PGNUM_8814A 20 +#define NPQ_PGNUM_8814A 20 +#define LPQ_PGNUM_8814A 20 //1972 +#define EPQ_PGNUM_8814A 20 +#define BCQ_PGNUM_8814A 32 + +#endif //#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_USB_HCI) + +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8814 0x00 +#else +#define WOWLAN_PAGE_NUM_8814 0x00 +#endif + +#define PAGE_SIZE_8814A 128//TXFF Page Size, Unit: Byte +#define MAX_RX_DMA_BUFFER_SIZE_8814A 0x5C00 //BASIC_RXFF_SIZE_8814A+TRX_SHARE_MODE_8814A*TRX_SHARE_BUFF_UNIT_8814A //Basic RXFF Size + ShareBuffer Size +#define TX_PAGE_BOUNDARY_8814A TXPKT_PGNUM_8814A // Need to enlarge boundary, by KaiYuan +#define TX_PAGE_BOUNDARY_WOWLAN_8814A TXPKT_PGNUM_8814A //TODO: 20130415 KaiYuan Check this value later + + +#define TOTAL_PGNUM_8814A 2048 +#define TXPKT_PGNUM_8814A (2048 - BCNQ_PAGE_NUM_8814-WOWLAN_PAGE_NUM_8814) +#define PUB_PGNUM_8814A (TXPKT_PGNUM_8814A-HPQ_PGNUM_8814A-NPQ_PGNUM_8814A-LPQ_PGNUM_8814A-EPQ_PGNUM_8814A) + +//Note: For WMM Normal Chip Setting ,modify later +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8814A TX_PAGE_BOUNDARY_8814A +#define WMM_NORMAL_TX_PAGE_BOUNDARY_8814A (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_8814A + 1) + +#define DRIVER_EARLY_INT_TIME_8814 0x05 +#define BCN_DMA_ATIME_INT_TIME_8814 0x02 + + +#define MAX_PAGE_SIZE 4096 // @ page : 4k bytes + +#define EFUSE_MAX_SECTION_JAGUAR 64 + +#define HWSET_MAX_SIZE_8814A 512 + +#define EFUSE_REAL_CONTENT_LEN_8814A 1024 +#define EFUSE_MAX_BANK_8814A 2 + +#define EFUSE_MAP_LEN_8814A 512 +#define EFUSE_MAX_SECTION_8814A 64 +#define EFUSE_MAX_WORD_UNIT_8814A 4 +#define EFUSE_PROTECT_BYTES_BANK_8814A 16 + +#define EFUSE_IC_ID_OFFSET_8814A 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR_8814A(addr) (addr < EFUSE_REAL_CONTENT_LEN_8814A) + +/*------------------------------------------------------------------------- +Chip specific +-------------------------------------------------------------------------*/ + +/* pic buffer descriptor */ +#if 1 /* according to the define in the rtw_xmit.h, rtw_recv.h */ +#define RTL8814AE_SEG_NUM TX_BUFFER_SEG_NUM /* 0:2 seg, 1: 4 seg, 2: 8 seg */ +#define TX_DESC_NUM_8814A TXDESC_NUM /* 128 */ +#define RX_DESC_NUM_8814A PCI_MAX_RX_COUNT /* 128 */ +#ifdef CONFIG_CONCURRENT_MODE +#define BE_QUEUE_TX_DESC_NUM_8814A (TXDESC_NUM<<1) /* 256 */ +#else +#define BE_QUEUE_TX_DESC_NUM_8814A (TXDESC_NUM+(TXDESC_NUM>>1)) /* 192 */ +#endif +#else +#define RTL8814AE_SEG_NUM TX_BUFFER_SEG_NUM /* 0:2 seg, 1: 4 seg, 2: 8 seg */ +#define TX_DESC_NUM_8814A 128 /* 1024//2048 change by ylb 20130624 */ +#define RX_DESC_NUM_8814A 128 /* 1024 //512 change by ylb 20130624 */ +#endif + +// To prevent out of boundary programming case, leave 1byte and program full section +// 9bytes + 1byt + 5bytes and pre 1byte. +// For worst case: +// | 1byte|----8bytes----|1byte|--5bytes--| +// | | Reserved(14bytes) | +// +#define EFUSE_OOB_PROTECT_BYTES 15 // PG data exclude header, dummy 6 bytes frome CP test and reserved 1byte. + +/* rtl8814_hal_init.c */ +s32 FirmwareDownload8814A( PADAPTER Adapter, BOOLEAN bUsedWoWLANFw); +void InitializeFirmwareVars8814(PADAPTER padapter); + +VOID +Hal_InitEfuseVars_8814A( + IN PADAPTER Adapter + ); + +s32 InitLLTTable8814A( + IN PADAPTER Adapter + ); + + +void InitRDGSetting8814A(PADAPTER padapter); + +//void CheckAutoloadState8812A(PADAPTER padapter); + +// EFuse +u8 GetEEPROMSize8814A(PADAPTER padapter); +void InitPGData8814A(PADAPTER padapter); + +void hal_ReadPROMVersion8814A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void hal_ReadTxPowerInfo8814A(PADAPTER padapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void hal_ReadBoardType8814A(PADAPTER pAdapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void hal_ReadThermalMeter_8814A(PADAPTER Adapter, u8* PROMContent,BOOLEAN AutoloadFail); +void hal_ReadChannelPlan8814A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void hal_EfuseParseXtal_8814A(PADAPTER pAdapter, u8* hwinfo,BOOLEAN AutoLoadFail); +void hal_ReadAntennaDiversity8814A(PADAPTER pAdapter,u8* PROMContent,BOOLEAN AutoLoadFail); +void hal_Read_TRX_antenna_8814A(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +VOID hal_ReadAmplifierType_8814A( + IN PADAPTER Adapter + ); +VOID hal_ReadPAType_8814A( + IN PADAPTER Adapter, + IN u8* PROMContent, + IN BOOLEAN AutoloadFail, + OUT u8* pPAType, + OUT u8* pLNAType + ); +void hal_GetRxGainOffset_8814A( + PADAPTER Adapter, + pu1Byte PROMContent, + BOOLEAN AutoloadFail + ); +void Hal_EfuseParseKFreeData_8814A( + IN PADAPTER Adapter, + IN u8 *PROMContent, + IN BOOLEAN AutoloadFail); +void hal_ReadRFEType_8814A(PADAPTER Adapter,u8* PROMContent, BOOLEAN AutoloadFail); +void hal_EfuseParseBTCoexistInfo8814A(PADAPTER Adapter, u8* hwinfo, BOOLEAN AutoLoadFail); + +//void hal_ReadUsbType_8812AU(PADAPTER Adapter, u8 *PROMContent, BOOLEAN AutoloadFail); +//int FirmwareDownloadBT(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware); +void hal_ReadRemoteWakeup_8814A(PADAPTER padapter, u8* hwinfo, BOOLEAN AutoLoadFail); +u8 MgntQuery_NssTxRate(u16 Rate); + +//BOOLEAN HalDetectPwrDownMode8812(PADAPTER Adapter); + +#ifdef CONFIG_WOWLAN +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void _InitBeaconParameters_8814A(PADAPTER padapter); +void SetBeaconRelatedRegisters8814A(PADAPTER padapter); + +void ReadRFType8814A(PADAPTER padapter); +void InitDefaultValue8814A(PADAPTER padapter); + +void SetHwReg8814A(PADAPTER padapter, u8 variable, u8 *pval); +void GetHwReg8814A(PADAPTER padapter, u8 variable, u8 *pval); +u8 SetHalDefVar8814A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8814A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +s32 c2h_id_filter_ccx_8814a(u8 *buf); +void rtl8814_set_hal_ops(struct hal_ops *pHalFunc); +void init_hal_spec_8814a(_adapter *adapter); + +// register +void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits); +void SetBcnCtrlReg(PADAPTER Adapter, u8 SetBits, u8 ClearBits); +void rtl8814_start_thread(PADAPTER padapter); +void rtl8814_stop_thread(PADAPTER padapter); + + +#ifdef CONFIG_PCI_HCI +BOOLEAN InterruptRecognized8814AE(PADAPTER Adapter); +VOID UpdateInterruptMask8814AE(PADAPTER Adapter, u32 AddMSR, u32 AddMSR1, u32 RemoveMSR, u32 RemoveMSR1); +u16 get_txbd_idx_addr(u16 ff_hwaddr); +#endif + +#ifdef CONFIG_BT_COEXIST +void rtl8812a_combo_card_WifiOnlyHwInit(PADAPTER Adapter); +#endif + +#endif //__RTL8188E_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_led.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_led.h new file mode 100644 index 00000000..17cbd2cd --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_led.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * 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 __RTL8814A_LED_H__ +#define __RTL8814A_LED_H__ + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +#ifdef CONFIG_USB_HCI +void rtl8814au_InitSwLeds(PADAPTER padapter); +void rtl8814au_DeInitSwLeds(PADAPTER padapter); +#endif //CONFIG_USB_HCI +#ifdef CONFIG_PCI_HCI +void rtl8814ae_InitSwLeds(PADAPTER padapter); +void rtl8814ae_DeInitSwLeds(PADAPTER padapter); +#endif //CONFIG_PCI_HCI +#ifdef CONFIG_SDIO_HCI +void rtl8814s_InitSwLeds(PADAPTER padapter); +void rtl8814s_DeInitSwLeds(PADAPTER padapter); +#endif //CONFIG_SDIO_HCI + +#endif //__RTL8814A_LED_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_recv.h new file mode 100644 index 00000000..f2ae1831 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_recv.h @@ -0,0 +1,188 @@ +/****************************************************************************** + * + * 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 __RTL8814A_RECV_H__ +#define __RTL8814A_RECV_H__ + +#if defined(CONFIG_USB_HCI) + +#ifndef MAX_RECVBUF_SZ +#ifdef PLATFORM_OS_CE +#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k +#else + #ifndef CONFIG_MINIMAL_MEMORY_USAGE + #ifdef CONFIG_PLATFORM_MSTAR + #define MAX_RECVBUF_SZ (8192) // 8K + #else + #define MAX_RECVBUF_SZ (32768) // 32k + #endif + //#define MAX_RECVBUF_SZ (24576) // 24k + //#define MAX_RECVBUF_SZ (20480) //20K + //#define MAX_RECVBUF_SZ (10240) //10K + //#define MAX_RECVBUF_SZ (15360) // 15k < 16k + //#define MAX_RECVBUF_SZ (8192+1024) // 8K+1k + #else + #define MAX_RECVBUF_SZ (4000) // about 4K + #endif +#endif +#endif //!MAX_RECVBUF_SZ + +#elif defined(CONFIG_PCI_HCI) +//#ifndef CONFIG_MINIMAL_MEMORY_USAGE +// #define MAX_RECVBUF_SZ (9100) +//#else + #define MAX_RECVBUF_SZ (4000) // about 4K +//#endif + + +#elif defined(CONFIG_SDIO_HCI) +/* temp solution +#ifdef CONFIG_SDIO_RX_COPY +#define MAX_RECVBUF_SZ (10240) +#else // !CONFIG_SDIO_RX_COPY +#define MAX_RECVBUF_SZ MAX_RX_DMA_BUFFER_SIZE_8821 +#endif // !CONFIG_SDIO_RX_COPY +*/ +#endif + + +/* RX buffer descriptor */ +/* DWORD 0 */ +#define SET_RX_BUFFER_DESC_DATA_LENGTH_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 0, 14, __Value) +#define SET_RX_BUFFER_DESC_LS_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 14, 1, __Value) +#define SET_RX_BUFFER_DESC_FS_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 15, 1, __Value) +#define SET_RX_BUFFER_DESC_TOTAL_LENGTH_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc, 16, 16, __Value) + +#define GET_RX_BUFFER_DESC_OWN_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 31, 1) +#define GET_RX_BUFFER_DESC_LS_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 14, 1) +#define GET_RX_BUFFER_DESC_FS_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 15, 1) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc, 16, 15) + +/* DWORD 1 */ +#define SET_RX_BUFFER_PHYSICAL_LOW_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc+4, 0, 32, __Value) +#define GET_RX_BUFFER_PHYSICAL_LOW_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 0, 32) + +/* DWORD 2 */ +#define SET_RX_BUFFER_PHYSICAL_HIGH_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxStatusDesc+8, 0, 32, __Value) + +/* DWORD 3*/ /* RESERVED */ + + +/*============= +//RX Info +==============*/ +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8814A(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8814AE(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8814AE(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_EOR_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_EXT_SECTYPE_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 7, 1)/* 20130415 KaiYuan add for 8814 */ +#define GET_RX_STATUS_DESC_TID_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_MACID_VLD_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 12, 1) +#define GET_RX_STATUS_DESC_AMSDU_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_CHKERR_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_IPVER_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_IS_TCPUDP_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_TCPOFFLOAD_CHK_VLD_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_FIRST_SEG_8814AE(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8814AE(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_MC_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 8) +#else +#define GET_RX_STATUS_DESC_RX_IS_QOS_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#endif +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_HWRSVD_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 24, 4) +#define GET_RX_STATUS_C2H_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) +#define GET_RX_STATUS_DESC_FCS_OK_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 31, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_BSSID_FIT_H_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 7, 3)//20130415 KaiYuan add for 8814 +#define GET_RX_STATUS_DESC_HTC_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_L_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#define GET_RX_STATUS_DESC_DMA_AGG_NUM_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8)//20130415 KaiYuan Check if it exist anymore +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_WAKE_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE(__pRxStatusDesc+12, 31, 1) + +//DWORD 4 +#define GET_RX_STATUS_DESC_PATTERN_IDX_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 0, 8) +#define GET_RX_STATUS_DESC_RX_EOF_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 8, 1) +#define GET_RX_STATUS_DESC_RX_SCRAMBLER_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 9, 7) +#define GET_RX_STATUS_DESC_RX_PRE_NDP_VLD_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 16, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+16, 24, 5) + + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8814A(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#ifdef CONFIG_USB_HCI +s32 rtl8814au_init_recv_priv(PADAPTER padapter); +void rtl8814au_free_recv_priv(PADAPTER padapter); +#endif + +#ifdef CONFIG_PCI_HCI +s32 rtl8814ae_init_recv_priv(PADAPTER padapter); +void rtl8814ae_free_recv_priv(PADAPTER padapter); +#endif + +/* temp solution +#ifdef CONFIG_SDIO_HCI +s32 InitRecvPriv8821AS(PADAPTER padapter); +void FreeRecvPriv8821AS(PADAPTER padapter); +#endif // CONFIG_SDIO_HCI +*/ + +void rtl8814_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); + +#endif /* __RTL8814A_RECV_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_rf.h new file mode 100644 index 00000000..5cd517a8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_rf.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * 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 __RTL8814A_RF_H__ +#define __RTL8814A_RF_H__ + +VOID +PHY_RF6052SetBandwidth8814A( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + + +int +PHY_RF6052_Config_8814A( + IN PADAPTER Adapter ); + +#endif//__RTL8188E_RF_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_spec.h new file mode 100644 index 00000000..4ffa5bc0 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_spec.h @@ -0,0 +1,642 @@ +/****************************************************************************** + * + * 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 __RTL8814A_SPEC_H__ +#define __RTL8814A_SPEC_H__ + +#include + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL_8814A 0x0000 // 2 Byte +#define REG_SYS_FUNC_EN_8814A 0x0002 // 2 Byte +#define REG_SYS_PW_CTRL_8814A 0x0004 // 4 Byte +#define REG_SYS_CLKR_8814A 0x0008 // 2 Byte +#define REG_SYS_EEPROM_CTRL_8814A 0x000A // 2 Byte +#define REG_EE_VPD_8814A 0x000C // 2 Byte +#define REG_SYS_SWR_CTRL1_8814A 0x0010 // 1 Byte +#define REG_SPS0_CTRL_8814A 0x0011 // 7 Byte +#define REG_SYS_SWR_CTRL3_8814A 0x0018 // 4 Byte +#define REG_RSV_CTRL_8814A 0x001C // 3 Byte +#define REG_RF_CTRL0_8814A 0x001F // 1 Byte +#define REG_RF_CTRL1_8814A 0x0020 // 1 Byte +#define REG_RF_CTRL2_8814A 0x0021 // 1 Byte +#define REG_LPLDO_CTRL_8814A 0x0023 // 1 Byte +#define REG_AFE_CTRL1_8814A 0x0024 // 4 Byte +#define REG_AFE_CTRL2_8814A 0x0028 // 4 Byte +#define REG_AFE_CTRL3_8814A 0x002c // 4 Byte +#define REG_EFUSE_CTRL_8814A 0x0030 +#define REG_LDO_EFUSE_CTRL_8814A 0x0034 +#define REG_PWR_DATA_8814A 0x0038 +#define REG_CAL_TIMER_8814A 0x003C +#define REG_ACLK_MON_8814A 0x003E +#define REG_GPIO_MUXCFG_8814A 0x0040 +#define REG_GPIO_IO_SEL_8814A 0x0042 +#define REG_MAC_PINMUX_CFG_8814A 0x0043 +#define REG_GPIO_PIN_CTRL_8814A 0x0044 +#define REG_GPIO_INTM_8814A 0x0048 +#define REG_LEDCFG0_8814A 0x004C +#define REG_LEDCFG1_8814A 0x004D +#define REG_LEDCFG2_8814A 0x004E +#define REG_LEDCFG3_8814A 0x004F +#define REG_FSIMR_8814A 0x0050 +#define REG_FSISR_8814A 0x0054 +#define REG_HSIMR_8814A 0x0058 +#define REG_HSISR_8814A 0x005c +#define REG_GPIO_EXT_CTRL_8814A 0x0060 +#define REG_GPIO_STATUS_8814A 0x006C +#define REG_SDIO_CTRL_8814A 0x0070 +#define REG_HCI_OPT_CTRL_8814A 0x0074 +#define REG_RF_CTRL3_8814A 0x0076 // 1 Byte +#define REG_AFE_CTRL4_8814A 0x0078 +#define REG_8051FW_CTRL_8814A 0x0080 +#define REG_HIMR0_8814A 0x00B0 +#define REG_HISR0_8814A 0x00B4 +#define REG_HIMR1_8814A 0x00B8 +#define REG_HISR1_8814A 0x00BC +#define REG_SYS_CFG1_8814A 0x00F0 +#define REG_SYS_CFG2_8814A 0x00FC +#define REG_SYS_CFG3_8814A 0x1000 + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR_8814A 0x0100 +#define REG_PBP_8814A 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL_8814A 0x0106 +#define REG_TRXDMA_CTRL_8814A 0x010C +#define REG_TRXFF_BNDY_8814A 0x0114 +#define REG_TRXFF_STATUS_8814A 0x0118 +#define REG_RXFF_PTR_8814A 0x011C +#define REG_CPWM_8814A 0x012F +#define REG_FWIMR_8814A 0x0130 +#define REG_FWISR_8814A 0x0134 +#define REG_FTIMR_8814A 0x0138 +#define REG_PKTBUF_DBG_CTRL_8814A 0x0140 +#define REG_RXPKTBUF_CTRL_8814A 0x0142 +#define REG_PKTBUF_DBG_DATA_L_8814A 0x0144 +#define REG_PKTBUF_DBG_DATA_H_8814A 0x0148 + +#define REG_TC0_CTRL_8814A 0x0150 +#define REG_TC1_CTRL_8814A 0x0154 +#define REG_TC2_CTRL_8814A 0x0158 +#define REG_TC3_CTRL_8814A 0x015C +#define REG_TC4_CTRL_8814A 0x0160 +#define REG_TCUNIT_BASE_8814A 0x0164 +#define REG_RSVD3_8814A 0x0168 +#define REG_C2HEVT_MSG_NORMAL_8814A 0x01A0 +#define REG_C2HEVT_CLEAR_8814A 0x01AF +#define REG_MCUTST_1_8814A 0x01C0 +#define REG_MCUTST_WOWLAN_8814A 0x01C7 +#define REG_FMETHR_8814A 0x01C8 +#define REG_HMETFR_8814A 0x01CC +#define REG_HMEBOX_0_8814A 0x01D0 +#define REG_HMEBOX_1_8814A 0x01D4 +#define REG_HMEBOX_2_8814A 0x01D8 +#define REG_HMEBOX_3_8814A 0x01DC +#define REG_LLT_INIT_8814A 0x01E0 +#define REG_LLT_ADDR_8814A 0x01E4 //20130415 KaiYuan add for 8814 +#define REG_HMEBOX_EXT0_8814A 0x01F0 +#define REG_HMEBOX_EXT1_8814A 0x01F4 +#define REG_HMEBOX_EXT2_8814A 0x01F8 +#define REG_HMEBOX_EXT3_8814A 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_FIFOPAGE_CTRL_1_8814A 0x0200 +#define REG_FIFOPAGE_CTRL_2_8814A 0x0204 +#define REG_AUTO_LLT_8814A 0x0208 +#define REG_TXDMA_OFFSET_CHK_8814A 0x020C +#define REG_TXDMA_STATUS_8814A 0x0210 +#define REG_RQPN_NPQ_8814A 0x0214 +#define REG_TQPNT1_8814A 0x0218 +#define REG_TQPNT2_8814A 0x021C +#define REG_TQPNT3_8814A 0x0220 +#define REG_TQPNT4_8814A 0x0224 +#define REG_RQPN_CTRL_1_8814A 0x0228 +#define REG_RQPN_CTRL_2_8814A 0x022C +#define REG_FIFOPAGE_INFO_1_8814A 0x0230 +#define REG_FIFOPAGE_INFO_2_8814A 0x0234 +#define REG_FIFOPAGE_INFO_3_8814A 0x0238 +#define REG_FIFOPAGE_INFO_4_8814A 0x023C +#define REG_FIFOPAGE_INFO_5_8814A 0x0240 + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH_8814A 0x0280 +#define REG_RXPKT_NUM_8814A 0x0284 // The number of packets in RXPKTBUF. +#define REG_RXDMA_CONTROL_8814A 0x0286 // ?????? Control the RX DMA. +#define REG_RXDMA_STATUS_8814A 0x0288 +#define REG_RXDMA_MODE_8814A 0x0290 // ?????? +#define REG_EARLY_MODE_CONTROL_8814A 0x02BC // ?????? +#define REG_RSVD5_8814A 0x02F0 // ?????? + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8814A 0x0300 +#define REG_INT_MIG_8814A 0x0304 // Interrupt Migration +#define REG_BCNQ_TXBD_DESA_8814A 0x0308 // TX Beacon Descriptor Address +#define REG_MGQ_TXBD_DESA_8814A 0x0310 // TX Manage Queue Descriptor Address +#define REG_VOQ_TXBD_DESA_8814A 0x0318 // TX VO Queue Descriptor Address +#define REG_VIQ_TXBD_DESA_8814A 0x0320 // TX VI Queue Descriptor Address +#define REG_BEQ_TXBD_DESA_8814A 0x0328 // TX BE Queue Descriptor Address +#define REG_BKQ_TXBD_DESA_8814A 0x0330 // TX BK Queue Descriptor Address +#define REG_RXQ_RXBD_DESA_8814A 0x0338 // RX Queue Descriptor Address +#define REG_HI0Q_TXBD_DESA_8814A 0x0340 +#define REG_HI1Q_TXBD_DESA_8814A 0x0348 +#define REG_HI2Q_TXBD_DESA_8814A 0x0350 +#define REG_HI3Q_TXBD_DESA_8814A 0x0358 +#define REG_HI4Q_TXBD_DESA_8814A 0x0360 +#define REG_HI5Q_TXBD_DESA_8814A 0x0368 +#define REG_HI6Q_TXBD_DESA_8814A 0x0370 +#define REG_HI7Q_TXBD_DESA_8814A 0x0378 +#define REG_MGQ_TXBD_NUM_8814A 0x0380 +#define REG_RX_RXBD_NUM_8814A 0x0382 +#define REG_VOQ_TXBD_NUM_8814A 0x0384 +#define REG_VIQ_TXBD_NUM_8814A 0x0386 +#define REG_BEQ_TXBD_NUM_8814A 0x0388 +#define REG_BKQ_TXBD_NUM_8814A 0x038A +#define REG_HI0Q_TXBD_NUM_8814A 0x038C +#define REG_HI1Q_TXBD_NUM_8814A 0x038E +#define REG_HI2Q_TXBD_NUM_8814A 0x0390 +#define REG_HI3Q_TXBD_NUM_8814A 0x0392 +#define REG_HI4Q_TXBD_NUM_8814A 0x0394 +#define REG_HI5Q_TXBD_NUM_8814A 0x0396 +#define REG_HI6Q_TXBD_NUM_8814A 0x0398 +#define REG_HI7Q_TXBD_NUM_8814A 0x039A +#define REG_TSFTIMER_HCI_8814A 0x039C + +//Read Write Point +#define REG_VOQ_TXBD_IDX_8814A 0x03A0 +#define REG_VIQ_TXBD_IDX_8814A 0x03A4 +#define REG_BEQ_TXBD_IDX_8814A 0x03A8 +#define REG_BKQ_TXBD_IDX_8814A 0x03AC +#define REG_MGQ_TXBD_IDX_8814A 0x03B0 +#define REG_RXQ_TXBD_IDX_8814A 0x03B4 +#define REG_HI0Q_TXBD_IDX_8814A 0x03B8 +#define REG_HI1Q_TXBD_IDX_8814A 0x03BC +#define REG_HI2Q_TXBD_IDX_8814A 0x03C0 +#define REG_HI3Q_TXBD_IDX_8814A 0x03C4 +#define REG_HI4Q_TXBD_IDX_8814A 0x03C8 +#define REG_HI5Q_TXBD_IDX_8814A 0x03CC +#define REG_HI6Q_TXBD_IDX_8814A 0x03D0 +#define REG_HI7Q_TXBD_IDX_8814A 0x03D4 +#define REG_DBG_SEL_V1_8814A 0x03D8 +#define REG_PCIE_HRPWM1_V1_8814A 0x03D9 +#define REG_PCIE_HCPWM1_V1_8814A 0x03DA +#define REG_PCIE_CTRL2_8814A 0x03DB +#define REG_PCIE_HRPWM2_V1_8814A 0x03DC +#define REG_PCIE_HCPWM2_V1_8814A 0x03DE +#define REG_PCIE_H2C_MSG_V1_8814A 0x03E0 +#define REG_PCIE_C2H_MSG_V1_8814A 0x03E4 +#define REG_DBI_WDATA_V1_8814A 0x03E8 +#define REG_DBI_RDATA_V1_8814A 0x03EC +#define REG_DBI_FLAG_V1_8814A 0x03F0 +#define REG_MDIO_V1_8814A 0x03F4 +#define REG_PCIE_MIX_CFG_8814A 0x03F8 +#define REG_DBG_8814A 0x03FC +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_VOQ_INFORMATION_8814A 0x0400 +#define REG_VIQ_INFORMATION_8814A 0x0404 +#define REG_BEQ_INFORMATION_8814A 0x0408 +#define REG_BKQ_INFORMATION_8814A 0x040C +#define REG_MGQ_INFORMATION_8814A 0x0410 +#define REG_HGQ_INFORMATION_8814A 0x0414 +#define REG_BCNQ_INFORMATION_8814A 0x0418 +#define REG_TXPKT_EMPTY_8814A 0x041A +#define REG_CPU_MGQ_INFORMATION_8814A 0x041C +#define REG_FWHW_TXQ_CTRL_8814A 0x0420 +#define REG_HWSEQ_CTRL_8814A 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY_8814A 0x0424 +//#define REG_MGQ_BDNY_8814A 0x0425 +#define REG_LIFETIME_EN_8814A 0x0426 +//#define REG_FW_FREE_TAIL_8814A 0x0427 +#define REG_SPEC_SIFS_8814A 0x0428 +#define REG_RETRY_LIMIT_8814A 0x042A +#define REG_TXBF_CTRL_8814A 0x042C +#define REG_DARFRC_8814A 0x0430 +#define REG_RARFRC_8814A 0x0438 +#define REG_RRSR_8814A 0x0440 +#define REG_ARFR0_8814A 0x0444 +#define REG_ARFR1_8814A 0x044C +#define REG_CCK_CHECK_8814A 0x0454 +#define REG_AMPDU_MAX_TIME_8814A 0x0455 +#define REG_TXPKTBUF_BCNQ1_BDNY_8814A 0x0456 +#define REG_AMPDU_MAX_LENGTH_8814A 0x0458 +#define REG_ACQ_STOP_8814A 0x045C +#define REG_NDPA_RATE_8814A 0x045D +#define REG_TX_HANG_CTRL_8814A 0x045E +#define REG_NDPA_OPT_CTRL_8814A 0x045F +#define REG_FAST_EDCA_CTRL_8814A 0x0460 +#define REG_RD_RESP_PKT_TH_8814A 0x0463 +#define REG_CMDQ_INFO_8814A 0x0464 +#define REG_Q4_INFO_8814A 0x0468 +#define REG_Q5_INFO_8814A 0x046C +#define REG_Q6_INFO_8814A 0x0470 +#define REG_Q7_INFO_8814A 0x0474 +#define REG_WMAC_LBK_BUF_HD_8814A 0x0478 +#define REG_MGQ_PGBNDY_8814A 0x047A +#define REG_INIRTS_RATE_SEL_8814A 0x0480 +#define REG_BASIC_CFEND_RATE_8814A 0x0481 +#define REG_STBC_CFEND_RATE_8814A 0x0482 +#define REG_DATA_SC_8814A 0x0483 +#define REG_MACID_SLEEP3_8814A 0x0484 +#define REG_MACID_SLEEP1_8814A 0x0488 +#define REG_ARFR2_8814A 0x048C +#define REG_ARFR3_8814A 0x0494 +#define REG_ARFR4_8814A 0x049C +#define REG_ARFR5_8814A 0x04A4 +#define REG_TXRPT_START_OFFSET_8814A 0x04AC +#define REG_TRYING_CNT_TH_8814A 0x04B0 +#define REG_POWER_STAGE1_8814A 0x04B4 +#define REG_POWER_STAGE2_8814A 0x04B8 +#define REG_SW_AMPDU_BURST_MODE_CTRL_8814A 0x04BC +#define REG_PKT_LIFE_TIME_8814A 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME_8814A 0x04C2 // ?????? +#define REG_STBC_SETTING_8814A 0x04C4 +#define REG_STBC_8814A 0x04C5 +#define REG_QUEUE_CTRL_8814A 0x04C6 +#define REG_SINGLE_AMPDU_CTRL_8814A 0x04C7 +#define REG_PROT_MODE_CTRL_8814A 0x04C8 +#define REG_MAX_AGGR_NUM_8814A 0x04CA +#define REG_RTS_MAX_AGGR_NUM_8814A 0x04CB +#define REG_BAR_MODE_CTRL_8814A 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT_8814A 0x04CF +#define REG_MACID_SLEEP2_8814A 0x04D0 +#define REG_MACID_SLEEP0_8814A 0x04D4 +#define REG_HW_SEQ0_8814A 0x04D8 +#define REG_HW_SEQ1_8814A 0x04DA +#define REG_HW_SEQ2_8814A 0x04DC +#define REG_HW_SEQ3_8814A 0x04DE +#define REG_NULL_PKT_STATUS_8814A 0x04E0 +#define REG_PTCL_ERR_STATUS_8814A 0x04E2 +#define REG_DROP_PKT_NUM_8814A 0x04EC +#define REG_PTCL_TX_RPT_8814A 0x04F0 +#define REG_Dummy_8814A 0x04FC + + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM_8814A 0x0500 +#define REG_EDCA_VI_PARAM_8814A 0x0504 +#define REG_EDCA_BE_PARAM_8814A 0x0508 +#define REG_EDCA_BK_PARAM_8814A 0x050C +#define REG_BCNTCFG_8814A 0x0510 +#define REG_PIFS_8814A 0x0512 +#define REG_RDG_PIFS_8814A 0x0513 +#define REG_SIFS_CTX_8814A 0x0514 +#define REG_SIFS_TRX_8814A 0x0516 +#define REG_AGGR_BREAK_TIME_8814A 0x051A +#define REG_SLOT_8814A 0x051B +#define REG_TX_PTCL_CTRL_8814A 0x0520 +#define REG_TXPAUSE_8814A 0x0522 +#define REG_DIS_TXREQ_CLR_8814A 0x0523 +#define REG_RD_CTRL_8814A 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT_8814A 0x0540 +#define REG_RD_NAV_NXT_8814A 0x0544 +#define REG_NAV_PROT_LEN_8814A 0x0546 +#define REG_BCN_CTRL_8814A 0x0550 +#define REG_BCN_CTRL_1_8814A 0x0551 +#define REG_MBID_NUM_8814A 0x0552 +#define REG_DUAL_TSF_RST_8814A 0x0553 +#define REG_MBSSID_BCN_SPACE_8814A 0x0554 +#define REG_DRVERLYINT_8814A 0x0558 +#define REG_BCNDMATIM_8814A 0x0559 +#define REG_ATIMWND_8814A 0x055A +#define REG_USTIME_TSF_8814A 0x055C +#define REG_BCN_MAX_ERR_8814A 0x055D +#define REG_RXTSF_OFFSET_CCK_8814A 0x055E +#define REG_RXTSF_OFFSET_OFDM_8814A 0x055F +#define REG_TSFTR_8814A 0x0560 +#define REG_CTWND_8814A 0x0572 +#define REG_SECONDARY_CCA_CTRL_8814A 0x0577 // ?????? +#define REG_PSTIMER_8814A 0x0580 +#define REG_TIMER0_8814A 0x0584 +#define REG_TIMER1_8814A 0x0588 +#define REG_BCN_PREDL_ITV_8814A 0x058F //Pre download beacon interval +#define REG_ACMHWCTRL_8814A 0x05C0 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8814A 0x0600 +#define REG_TCR_8814A 0x0604 +#define REG_RCR_8814A 0x0608 +#define REG_RX_PKT_LIMIT_8814A 0x060C +#define REG_RX_DLK_TIME_8814A 0x060D +#define REG_RX_DRVINFO_SZ_8814A 0x060F + +#define REG_MACID_8814A 0x0610 +#define REG_BSSID_8814A 0x0618 +#define REG_MAR_8814A 0x0620 +#define REG_MBIDCAMCFG_8814A 0x0628 + +#define REG_USTIME_EDCA_8814A 0x0638 +#define REG_MAC_SPEC_SIFS_8814A 0x063A +#define REG_RESP_SIFP_CCK_8814A 0x063C +#define REG_RESP_SIFS_OFDM_8814A 0x063E +#define REG_ACKTO_8814A 0x0640 +#define REG_CTS2TO_8814A 0x0641 +#define REG_EIFS_8814A 0x0642 + +#define REG_NAV_UPPER_8814A 0x0652 // unit of 128 +#define REG_TRXPTCL_CTL_8814A 0x0668 + +// Security +#define REG_CAMCMD_8814A 0x0670 +#define REG_CAMWRITE_8814A 0x0674 +#define REG_CAMREAD_8814A 0x0678 +#define REG_CAMDBG_8814A 0x067C +#define REG_SECCFG_8814A 0x0680 + +// Power +#define REG_WOW_CTRL_8814A 0x0690 +#define REG_PS_RX_INFO_8814A 0x0692 +#define REG_UAPSD_TID_8814A 0x0693 +#define REG_WKFMCAM_NUM_8814A 0x0698 +#define REG_RXFLTMAP0_8814A 0x06A0 +#define REG_RXFLTMAP1_8814A 0x06A2 +#define REG_RXFLTMAP2_8814A 0x06A4 +#define REG_BCN_PSR_RPT_8814A 0x06A8 +#define REG_BT_COEX_TABLE_8814A 0x06C0 +#define REG_TX_DATA_RSP_RATE_8814A 0x06DE +#define REG_ASSOCIATED_BFMER0_INFO_8814A 0x06E4 +#define REG_ASSOCIATED_BFMER1_INFO_8814A 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8814A 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8814A 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8814A 0x06FC + +// Hardware Port 2 +#define REG_MACID1_8814A 0x0700 +#define REG_BSSID1_8814A 0x0708 +// Hardware Port 3 +#define REG_MACID2_8814A 0x1620 +#define REG_BSSID2_8814A 0x1628 +// Hardware Port 4 +#define REG_MACID3_8814A 0x1630 +#define REG_BSSID3_8814A 0x1638 +// Hardware Port 5 +#define REG_MACID4_8814A 0x1640 +#define REG_BSSID4_8814A 0x1648 + +#define REG_ASSOCIATED_BFMEE_SEL_8814A 0x0714 +#define REG_SND_PTCL_CTRL_8814A 0x0718 +#define REG_IQ_DUMP_8814A 0x07C0 + +/**** page 19 ****/ +//TX BeamForming +#define REG_BB_TXBF_ANT_SET_BF1 0x19ac +#define REG_BB_TXBF_ANT_SET_BF0 0x19b4 + +// 0x1200h ~ 0x12FFh DDMA CTRL +// +//----------------------------------------------------- +#define REG_DDMA_CH0SA 0x1200 +#define REG_DDMA_CH0DA 0x1204 +#define REG_DDMA_CH0CTRL 0x1208 +#define REG_DDMA_CH1SA 0x1210 +#define REG_DDMA_CH1DA 0x1214 +#define REG_DDMA_CH1CTRL 0x1218 +#define REG_DDMA_CH2SA 0x1220 +#define REG_DDMA_CH2DA 0x1224 +#define REG_DDMA_CH2CTRL 0x1228 +#define REG_DDMA_CH3SA 0x1230 +#define REG_DDMA_CH3DA 0x1234 +#define REG_DDMA_CH3CTRL 0x1238 +#define REG_DDMA_CH4SA 0x1240 +#define REG_DDMA_CH4DA 0x1244 +#define REG_DDMA_CH4CTRL 0x1248 +#define REG_DDMA_CH5SA 0x1250 +#define REG_DDMA_CH5DA 0x1254 +#define REG_DDMA_CH5CTRL 0x1258 +#define REG_DDMA_INT_MSK 0x12E0 +#define REG_DDMA_CHSTATUS 0x12E8 +#define REG_DDMA_CHKSUM 0x12F0 +#define REG_DDMA_MONITER 0x12FC + +#define DDMA_LEN_MASK 0x0001FFFF +#define FW_CHKSUM_DUMMY_SZ 8 +#define DDMA_CH_CHKSUM_CNT BIT(24) +#define DDMA_RST_CHKSUM_STS BIT(25) +#define DDMA_MODE_BLOCK_CPU BIT(26) +#define DDMA_CHKSUM_FAIL BIT(27) +#define DDMA_DA_W_DISABLE BIT(28) +#define DDMA_CHKSUM_EN BIT(29) +#define DDMA_CH_OWN BIT(31) + + +//3081 FWDL +#define FWDL_EN BIT0 +#define IMEM_BOOT_DL_RDY BIT1 +#define IMEM_BOOT_CHKSUM_FAIL BIT2 +#define IMEM_DL_RDY BIT3 +#define IMEM_CHKSUM_OK BIT4 +#define DMEM_DL_RDY BIT5 +#define DMEM_CHKSUM_OK BIT6 +#define EMEM_DL_RDY BIT7 +#define EMEM_CHKSUM_FAIL BIT8 +#define EMEM_TXBUF_DL_RDY BIT9 +#define EMEM_TXBUF_CHKSUM_FAIL BIT10 +#define CPU_CLK_SWITCH_BUSY BIT11 +#define CPU_CLK_SEL (BIT12|BIT13) +#define FWDL_OK BIT14 +#define FW_INIT_RDY BIT15 +#define R_EN_BOOT_FLASH BIT20 + +#define OCPBASE_IMEM_3081 0x00000000 +#define OCPBASE_DMEM_3081 0x00200000 +#define OCPBASE_RPTBUF_3081 0x18660000 +#define OCPBASE_RXBUF2_3081 0x18680000 +#define OCPBASE_RXBUF_3081 0x18700000 +#define OCPBASE_TXBUF_3081 0x18780000 + + +#define REG_FAST_EDCA_VOVI_SETTING_8814A 0x1448 +#define REG_FAST_EDCA_BEBK_SETTING_8814A 0x144C + + +//----------------------------------------------------- +// + + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define EFUSE_CTRL_8814A REG_EFUSE_CTRL_8814A // E-Fuse Control. +#define EFUSE_TEST_8814A REG_LDO_EFUSE_CTRL_8814A // E-Fuse Test. +#define MSR_8814A (REG_CR_8814A + 2) // Media Status register +#define ISR_8814A REG_HISR0_8814A +#define TSFR_8814A REG_TSFTR_8814A // Timing Sync Function Timer Register. + +#define PBP_8814A REG_PBP_8814A + +// Redifine MACID register, to compatible prior ICs. +#define IDR0_8814A REG_MACID_8814A // MAC ID Register, Offset 0x0050-0x0053 +#define IDR4_8814A (REG_MACID_8814A + 4) // MAC ID Register, Offset 0x0054-0x0055 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM_8814A REG_CAMCMD_8814A //IN 8190 Data Sheet is called CAMcmd +#define WCAMI_8814A REG_CAMWRITE_8814A // Software write CAM input content +#define RCAMO_8814A REG_CAMREAD_8814A // Software read/write CAM config +#define CAMDBG_8814A REG_CAMDBG_8814A +#define SECR_8814A REG_SECCFG_8814A //Security Configuration Register + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0xB0, 8bits) +//---------------------------------------------------------------------------- +#define IMR_DISABLED_8814A 0 +// IMR DW0(0x00B0-00B3) Bit 0-31 +#define IMR_TIMER2_8814A BIT31 // Timeout interrupt 2 +#define IMR_TIMER1_8814A BIT30 // Timeout interrupt 1 +#define IMR_PSTIMEOUT_8814A BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_8814A BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_8814A BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TXBCN0ERR_8814A BIT26 // Transmit Beacon0 Error +#define IMR_TXBCN0OK_8814A BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_8814A BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_8814A BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_8814A BIT16 // Beacon Queue DMA OK0 +#define IMR_HSISR_IND_ON_INT_8814A BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_8814A BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_8814A BIT12 // CTWidnow End or ATIM Window End +#define IMR_C2HCMD_8814A BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_8814A BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_8814A BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_8814A BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_8814A BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8814A BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8814A BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8814A BIT3 // AC_VI DMA OK +#define IMR_VODOK_8814A BIT2 // AC_VO DMA OK +#define IMR_RDU_8814A BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8814A BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_MCUERR_8814A BIT28 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT7_8814A BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_8814A BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_8814A BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_8814A BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_8814A BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_8814A BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_8814A BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_8814A BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_8814A BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_8814A BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_8814A BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_8814A BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_8814A BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_8814A BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_8814A BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_8814A BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_8814A BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_8814A BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_8814A BIT8 // Receive FIFO Overflow + + +#ifdef CONFIG_PCI_HCI +#define IMR_TX_MASK (IMR_VODOK_8814A | IMR_VIDOK_8814A | IMR_BEDOK_8814A | IMR_BKDOK_8814A | IMR_MGNTDOK_8814A | IMR_HIGHDOK_8814A) + +#define RT_BCN_INT_MASKS (IMR_BCNDMAINT0_8814A | IMR_TXBCN0OK_8814A | IMR_TXBCN0ERR_8814A | IMR_BCNDERR0_8814A) + +#define RT_AC_INT_MASKS (IMR_VIDOK_8814A | IMR_VODOK_8814A | IMR_BEDOK_8814A | IMR_BKDOK_8814A) +#endif + + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- + +//2 Special Option +#define USB_AGG_EN_8814A BIT(7) +#define REG_USB_HRPWM_U3 0xF052 + +#define LAST_ENTRY_OF_TX_PKT_BUFFER_8814A 2048-1 //20130415 KaiYuan add for 8814 + +#define MACID_NUM_8814A 128 +#define SEC_CAM_ENT_NUM_8814A 64 +#define NSS_NUM_8814A 3 +#define BAND_CAP_8814A (BAND_CAP_2G | BAND_CAP_5G) +#define BW_CAP_8814A (BW_CAP_20M | BW_CAP_40M | BW_CAP_80M) + +#endif //__RTL8814A_SPEC_H__ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_sreset.h new file mode 100644 index 00000000..af26460a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * 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 _RTL88814A_SRESET_H_ +#define _RTL8814A_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8814_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8814_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_xmit.h new file mode 100644 index 00000000..c005bc5f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8814a_xmit.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 __RTL8814A_XMIT_H__ +#define __RTL8814A_XMIT_H__ + +typedef struct txdescriptor_8814 +{ + // Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 ls:1; +}TXDESC_8814, *PTXDESC_8814; + + +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 + + + +#ifdef CONFIG_SDIO_HCI +#define SET_TX_DESC_SDIO_TXSEQ_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif //CONFIG_SDIO_HCI + +//----------------------------------------------------------------- +// RTL8814A TX BUFFER DESC +//----------------------------------------------------------------- +/* +- Each TXBD has 4 segment. + -- For 32 bit, each segment is 8 bytes. + -- For 64 bit, each segment is 16 bytes. +*/ +#if 0 +#if 1 /* 32 bit */ +#define SET_TX_EXTBUFF_DESC_LEN_8814A(__pTxDesc, __Value, __Set) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Set*8), 0, 16, __Value) +#define SET_TX_EXTBUFF_DESC_ADDR_LOW_8814A(__pTxDesc, __Value, __Set) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Set*8)+4, 0, 32, __Value) +#else /* 64 bit */ +#define SET_TX_EXTBUFF_DESC_LEN_8814A(__pTxDesc, __Value, __Set) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Set*16), 0, 16, __Value) +#define SET_TX_EXTBUFF_DESC_ADDR_LOW_8814A(__pTxDesc, __Value, __Set) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Set*16)+4, 0, 32, __Value) +#endif +#define SET_TX_EXTBUFF_DESC_ADDR_HIGH_8814A(__pTxDesc, __Value, __Set) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Set*16)+8, 0, 32, __Value) +#endif +/*c2h-DWORD 2*/ +#define GET_RX_STATUS_DESC_RPT_SEL_8814A(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+8, 28, 1) + +//========================================================= +// for Txfilldescroptor8814Ae, fill the desc content. +#if 1 /* 32 bit */ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*8), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*8), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*8)+4, 0, 32, __Valeu) +#else /* 64 bit */ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*16), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*16), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*16)+4, 0, 32, __Valeu) +#endif +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+((__Offset)*16)+8, 0, 32, __Valeu) + +//========================================================= + +//TX buffer +//============= +// Dword 0 +#define SET_TX_BUFF_DESC_LEN_0_8814A(__pTxDesc, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Valeu) +#define SET_TX_BUFF_DESC_PSB_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 15, __Value) +#define SET_TX_BUFF_DESC_OWN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +#define GET_TX_BUFF_DESC_OWN_8814A(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +// Dword 1 +#define SET_TX_BUFF_DESC_ADDR_LOW_0_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 32, __Value) +#define GET_TX_BUFF_DESC_ADDR_LOW_0_8814A(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+4, 0, 32) +// Dword 2 +#define SET_TX_BUFF_DESC_ADDR_HIGH_0_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 32, __Value) +#define GET_TX_BUFF_DESC_ADDR_HIGH_0_8814A(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+8, 0, 32) +// Dword 3 //RESERVED 0 + +#if 0 /* 64 bit */ +// Dword 4 +#define SET_TX_BUFF_DESC_LEN_1_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 16, __Value) +#define SET_TX_BUFF_DESC_AMSDU_1_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 31, 1, __Value) +// Dword 5 +#define SET_TX_BUFF_DESC_ADDR_LOW_1_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 32, __Value) +// Dword 6 +#define SET_TX_BUFF_DESC_ADDR_HIGH_1_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 32, __Value) +// Dword 7 //RESERVED 0 +// Dword 8 +#define SET_TX_BUFF_DESC_LEN_2_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 0, 16, __Value) +#define SET_TX_BUFF_DESC_AMSDU_2_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 31, 1, __Value) +// Dword 9 +#define SET_TX_BUFF_DESC_ADDR_LOW_2_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 0, 32, __Value) +// Dword 10 +#define SET_TX_BUFF_DESC_ADDR_HIGH_2_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) +// Dword 11 //RESERVED 0 +// Dword 12 +#define SET_TX_BUFF_DESC_LEN_3_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 16, __Value) +#define SET_TX_BUFF_DESC_AMSDU_3_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 31, 1, __Value) +// Dword 13 +#define SET_TX_BUFF_DESC_ADDR_LOW_3_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+52, 0, 32, __Value) +// Dword 14 +#define SET_TX_BUFF_DESC_ADDR_HIGH_3_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+56, 0, 32, __Value) +// Dword 15 //RESERVED 0 +#endif + +//=====Desc content +//TX Info +//============= +// Dword 0 +#define SET_TX_DESC_PKT_SIZE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define GET_TX_DESC_PKT_SIZE_8814A(__pTxDesc) LE_BITS_TO_4BYTE( __pTxDesc, 0, 16) +#define SET_TX_DESC_OFFSET_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define GET_TX_DESC_OFFSET_8814A(__pTxDesc) LE_BITS_TO_4BYTE( __pTxDesc, 16, 8) +#define SET_TX_DESC_BMC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_LINIP_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_AMSDU_PAD_EN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_NO_ACM_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_DISQSELSEQ_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) +#define SET_TX_DESC_MORE_DATA_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 29, 1, __Value) +#define SET_TX_DESC_TXOP_PS_CAP_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 30, 1, __Value) +#define SET_TX_DESC_TXOP_PS_MODE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 31, 1, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_NULL_0_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 14, 1, __Value) +#define SET_TX_DESC_NULL_1_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 15, 1, __Value) +#define SET_TX_DESC_BK_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define GET_TX_DESC_MORE_FRAG_8814A(__pTxDesc) LE_BITS_TO_4BYTE( __pTxDesc+8, 17, 1) +#define SET_TX_DESC_RAW_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_NULL_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) +#define SET_TX_DESC_HW_AES_IV_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 31, 1, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 5, __Value) +#define SET_TX_DESC_EARLY_RATE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HW_SSN_SEL_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_CHECK_EN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 14, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_TRY_RATE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 7, 1, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) +#define SET_TX_DESC_PCTS_ENABLE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 29, 1, __Value) +#define SET_TX_DESC_PCTS_MASK_IDX_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 30, 2, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) +#define SET_TX_DESC_SIGNALING_TA_PKT_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 17, 1, __Value) +#define SET_TX_DESC_PORT_ID_8814A(__pTxDesc,__Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 21, 3, __Value)//20130415 KaiYuan add for 8814 +#define SET_TX_DESC_TX_ANT_8814A(__pTxDesc,__Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 24, 4, __Value) +#define SET_TX_DESC_TX_POWER_OFFSET_8814A(__pTxDesc,__Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 28, 3, __Value) + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_MBSSID_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 12, 4, __Value) +#define SET_TX_DESC_ANTSEL_A_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANT_MAPA_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 2, __Value) +#define SET_TX_DESC_ANT_MAPB_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 24, 2, __Value) +#define SET_TX_DESC_ANT_MAPC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 26, 2, __Value) +#define SET_TX_DESC_ANT_MAPD_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 28, 2, __Value) + + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_NTX_MAP_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 20, 4, __Value) +#define SET_TX_DESC_USB_TXAGG_NUM_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) + + +// Dword 8 +#define SET_TX_DESC_RTS_RC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 0, 6, __Value) +#define SET_TX_DESC_BAR_RTY_TH_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 6, 2, __Value) +#define SET_TX_DESC_DATA_RC_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 8, 6, __Value) +#define SET_TX_DESC_EN_HWEXSEQ_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 14, 1, __Value) +#define SET_TX_DESC_HWSEQ_EN_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) +#if(DEV_BUS_TYPE != RT_SDIO_INTERFACE) +#define SET_TX_DESC_NEXT_HEAD_PAGE_L_8814A(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 16, 8, __Value) +#else +#define SET_TX_DESC_SDIO_SEQ_8814A(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 16, 8, __Value) //20130415 KaiYuan add for 8814AS +#endif +#define SET_TX_DESC_TAIL_PAGE_L_8814A(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 24, 8, __Value) + +// Dword 9 +#define SET_TX_DESC_PADDING_LENGTH_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 0, 11, __Value) +#define SET_TX_DESC_TXBF_PATH_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 11, 1, __Value) +#define SET_TX_DESC_SEQ_8814A(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) +#define SET_TX_DESC_NEXT_HEAD_PAGE_H_8814A(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 24, 4, __Value) +#define SET_TX_DESC_TAIL_PAGE_H_8814A(__pTxDesc,__Value)(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 28, 4, __Value) + + + +#define SET_EARLYMODE_PKTNUM_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8814A(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + + +void rtl8814a_cal_txdesc_chksum(u8 *ptxdesc); +void rtl8814a_fill_fake_txdesc(PADAPTER padapter,u8*pDesc,u32 BufferLen,u8 IsPsPoll,u8 IsBTQosNull, u8 bDataFrame); +void rtl8814a_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc); +void rtl8814a_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); +void rtl8814a_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc); + +#ifdef CONFIG_USB_HCI +s32 rtl8814au_init_xmit_priv(PADAPTER padapter); +void rtl8814au_free_xmit_priv(PADAPTER padapter); +s32 rtl8814au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8814au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8814au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8814au_xmit_buf_handler(PADAPTER padapter); +void rtl8814au_xmit_tasklet(void *priv); +s32 rtl8814au_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +#endif //CONFIG_USB_HCI + +#ifdef CONFIG_PCI_HCI +s32 rtl8814ae_init_xmit_priv(PADAPTER padapter); +void rtl8814ae_free_xmit_priv(PADAPTER padapter); +struct xmit_buf *rtl8814ae_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8814ae_xmitframe_resume(_adapter *padapter); +s32 rtl8814ae_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8814ae_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8814ae_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8814ae_xmit_tasklet(void *priv); +#endif + +void _dbg_dump_tx_info(_adapter *padapter,int frame_tag, u8 *ptxdesc); +u8 +SCMapping_8814( + IN PADAPTER Adapter, + IN struct pkt_attrib *pattrib +); + +u8 +BWMapping_8814( + IN PADAPTER Adapter, + IN struct pkt_attrib *pattrib +); + + +#endif /* __RTL8814_XMIT_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_spec.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_spec.h new file mode 100644 index 00000000..10a616b3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_spec.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 __RTL8821A_SPEC_H__ +#define __RTL8821A_SPEC_H__ + +#include +// This file should based on "hal_com_reg.h" +#include +// Because 8812a and 8821a is the same serial, +// most of 8821a register definitions are the same as 8812a. +#include + + +//============================================================ +// 8821A Regsiter offset definition +//============================================================ + +//============================================================ +// MAC register +//============================================================ + +//----------------------------------------------------- +// 0x0000h ~ 0x00FFh System Configuration +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0100h ~ 0x01FFh MACTOP General Configuration +//----------------------------------------------------- +#define REG_WOWLAN_WAKE_REASON REG_MCUTST_WOWLAN + +//----------------------------------------------------- +// 0x0200h ~ 0x027Fh TXDMA Configuration +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0280h ~ 0x02FFh RXDMA Configuration +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0300h ~ 0x03FFh PCIe +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0400h ~ 0x047Fh Protocol Configuration +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0500h ~ 0x05FFh EDCA Configuration +//----------------------------------------------------- + +//----------------------------------------------------- +// 0x0600h ~ 0x07FFh WMAC Configuration +//----------------------------------------------------- + + +//============================================================ +// SDIO Bus Specification +//============================================================ + +//----------------------------------------------------- +// SDIO CMD Address Mapping +//----------------------------------------------------- + +//----------------------------------------------------- +// I/O bus domain (Host) +//----------------------------------------------------- + +//----------------------------------------------------- +// SDIO register +//----------------------------------------------------- +#undef SDIO_REG_HCPWM1 +#define SDIO_REG_FREE_TXPG2 0x024 +#define SDIO_REG_HCPWM1 0x025 + + +//============================================================ +// Regsiter Bit and Content definition +//============================================================ + +//======================================================== +// General definitions +//======================================================== + +#define MACID_NUM_8821A 128 +#define SEC_CAM_ENT_NUM_8821A 64 +#define NSS_NUM_8821A 1 +#define BAND_CAP_8821A (BAND_CAP_2G | BAND_CAP_5G) +#define BW_CAP_8821A (BW_CAP_20M | BW_CAP_40M | BW_CAP_80M) + +#endif /* __RTL8821A_SPEC_H__ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_xmit.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_xmit.h new file mode 100644 index 00000000..2b7320df --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtl8821a_xmit.h @@ -0,0 +1,180 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 __RTL8821A_XMIT_H__ +#define __RTL8821A_XMIT_H__ + +#include + +typedef struct txdescriptor_8821a +{ + // Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 rsvd0026:1; + u32 rsvd0027:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 rsvd0031:1; + + // Offset 4 + u32 macid:7; + u32 rsvd0407:1; + u32 qsel:5; + u32 rdg_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rate_id:5; + u32 en_desc_id:1; + u32 sectype:2; + u32 pkt_offset:5; // unit: 8 bytes + u32 moredata:1; + u32 txop_ps_cap:1; + u32 txop_ps_mode:1; + + // Offset 8 + u32 p_aid:9; + u32 rsvd0809:1; + u32 cca_rts:2; + u32 agg_en:1; + u32 rdg_en:1; + u32 null_0:1; + u32 null_1:1; + u32 bk:1; + u32 morefrag:1; + u32 raw:1; + u32 spe_rpt:1; + u32 ampdu_density:3; + u32 bt_null:1; + u32 g_id:6; + u32 rsvd0830:2; + + // Offset 12 + u32 wheader_len:4; + u32 chk_en:1; + u32 early_rate:1; + u32 hw_ssn_sel:2; + u32 userate:1; + u32 disrtsfb:1; + u32 disdatafb:1; + u32 cts2self:1; + u32 rtsen:1; + u32 hw_rts_en:1; + u32 port_id:1; + u32 navusehdr:1; + u32 use_max_len:1; + u32 max_agg_num:5; + u32 ndpa:2; + u32 ampdu_max_time:8; + + // Offset 16 + u32 datarate:7; + u32 try_rate:1; + u32 data_ratefb_lmt:5; + u32 rts_ratefb_lmt:4; + u32 rty_lmt_en:1; + u32 data_rt_lmt:6; + u32 rtsrate:5; + u32 pcts_en:1; + u32 pcts_mask_idx:2; + + // Offset 20 + u32 data_sc:4; + u32 data_short:1; + u32 data_bw:2; + u32 data_ldpc:1; + u32 data_stbc:2; + u32 vcs_stbc:2; + u32 rts_short:1; + u32 rts_sc:4; + u32 rsvd2016:7; + u32 tx_ant:4; + u32 txpwr_offset:3; + u32 rsvd2031:1; + + // Offset 24 + u32 sw_define:12; + u32 mbssid:4; + u32 antsel_A:3; + u32 antsel_B:3; + u32 antsel_C:3; + u32 antsel_D:3; + u32 rsvd2428:4; + + // Offset 28 + u32 checksum:16; + u32 rsvd2816:8; + u32 usb_txagg_num:8; + + // Offset 32 + u32 rts_rc:6; + u32 bar_rty_th:2; + u32 data_rc:6; + u32 rsvd3214:1; + u32 en_hwseq:1; + u32 nextneadpage:8; + u32 tailpage:8; + + // Offset 36 + u32 padding_len:11; + u32 txbf_path:1; + u32 seq:12; + u32 final_data_rate:8; +}TXDESC_8821A, *PTXDESC_8821A; + +#ifdef CONFIG_SDIO_HCI +s32 InitXmitPriv8821AS(PADAPTER padapter); +void FreeXmitPriv8821AS(PADAPTER padapter); +s32 XmitBufHandler8821AS(PADAPTER padapter); +s32 MgntXmit8821AS(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 HalXmitNoLock8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 HalXmit8821AS(PADAPTER padapter, struct xmit_frame *pxmitframe); +#ifndef CONFIG_SDIO_TX_TASKLET +thread_return XmitThread8821AS(thread_context context); +#endif // !CONFIG_SDIO_TX_TASKLET +#endif // CONFIG_SDIO_HCI + +#if 0 +#ifdef CONFIG_USB_HCI +s32 rtl8821au_init_xmit_priv(PADAPTER padapter); +void rtl8821au_free_xmit_priv(PADAPTER padapter); +s32 rtl8821au_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8821au_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +s32 rtl8821au_hal_xmitframe_enqueue(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8821au_xmit_buf_handler(PADAPTER padapter); +void rtl8821au_xmit_tasklet(void *priv); +s32 rtl8821au_xmitframe_complete(PADAPTER padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +#endif // CONFIG_USB_HCI + +#ifdef CONFIG_PCI_HCI +s32 rtl8821e_init_xmit_priv(PADAPTER padapter); +void rtl8821e_free_xmit_priv(PADAPTER padapter); +struct xmit_buf* rtl8821e_dequeue_xmitbuf(struct rtw_tx_ring *ring); +void rtl8821e_xmitframe_resume(PADAPTER padapter); +s32 rtl8821e_hal_xmit(PADAPTER padapter, struct xmit_frame *pxmitframe); +s32 rtl8821e_mgnt_xmit(PADAPTER padapter, struct xmit_frame *pmgntframe); +void rtl8821e_xmit_tasklet(void *priv); +#endif // CONFIG_PCI_HCI +#endif + +#endif //__RTL8821_XMIT_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_android.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_android.h new file mode 100644 index 00000000..5b52846f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_android.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * 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 __RTW_ANDROID_H__ +#define __RTW_ANDROID_H__ + +enum ANDROID_WIFI_CMD { + ANDROID_WIFI_CMD_START, + ANDROID_WIFI_CMD_STOP, + ANDROID_WIFI_CMD_SCAN_ACTIVE, + ANDROID_WIFI_CMD_SCAN_PASSIVE, + ANDROID_WIFI_CMD_RSSI, + ANDROID_WIFI_CMD_LINKSPEED, + ANDROID_WIFI_CMD_RXFILTER_START, + ANDROID_WIFI_CMD_RXFILTER_STOP, + ANDROID_WIFI_CMD_RXFILTER_ADD, + ANDROID_WIFI_CMD_RXFILTER_REMOVE, + ANDROID_WIFI_CMD_BTCOEXSCAN_START, + ANDROID_WIFI_CMD_BTCOEXSCAN_STOP, + ANDROID_WIFI_CMD_BTCOEXMODE, + ANDROID_WIFI_CMD_SETSUSPENDOPT, + ANDROID_WIFI_CMD_P2P_DEV_ADDR, + ANDROID_WIFI_CMD_SETFWPATH, + ANDROID_WIFI_CMD_SETBAND, + ANDROID_WIFI_CMD_GETBAND, + ANDROID_WIFI_CMD_COUNTRY, + ANDROID_WIFI_CMD_P2P_SET_NOA, + ANDROID_WIFI_CMD_P2P_GET_NOA, + ANDROID_WIFI_CMD_P2P_SET_PS, + ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE, + + ANDROID_WIFI_CMD_MIRACAST, + +#ifdef CONFIG_PNO_SUPPORT + ANDROID_WIFI_CMD_PNOSSIDCLR_SET, + ANDROID_WIFI_CMD_PNOSETUP_SET, + ANDROID_WIFI_CMD_PNOENABLE_SET, + ANDROID_WIFI_CMD_PNODEBUG_SET, +#endif + + ANDROID_WIFI_CMD_MACADDR, + + ANDROID_WIFI_CMD_BLOCK_SCAN, + ANDROID_WIFI_CMD_BLOCK, + + ANDROID_WIFI_CMD_WFD_ENABLE, + ANDROID_WIFI_CMD_WFD_DISABLE, + + ANDROID_WIFI_CMD_WFD_SET_TCPPORT, + ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT, + ANDROID_WIFI_CMD_WFD_SET_DEVTYPE, + ANDROID_WIFI_CMD_CHANGE_DTIM, + ANDROID_WIFI_CMD_HOSTAPD_SET_MACADDR_ACL, + ANDROID_WIFI_CMD_HOSTAPD_ACL_ADD_STA, + ANDROID_WIFI_CMD_HOSTAPD_ACL_REMOVE_STA, +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)) + ANDROID_WIFI_CMD_GTK_REKEY_OFFLOAD, +#endif //CONFIG_GTK_OL + ANDROID_WIFI_CMD_P2P_DISABLE, + ANDROID_WIFI_CMD_DRIVERVERSION, + ANDROID_WIFI_CMD_MAX +}; + +int rtw_android_cmdstr_to_num(char *cmdstr); +int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); + +#if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +int rtw_android_pno_enable(struct net_device *net, int pno_enable); +int rtw_android_cfg80211_pno_setup(struct net_device *net, + struct cfg80211_ssid *ssid, int n_ssids, int interval); +#endif + +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) +int rtw_android_wifictrl_func_add(void); +void rtw_android_wifictrl_func_del(void); +void* wl_android_prealloc(int section, unsigned long size); + +int wifi_get_irq_number(unsigned long *irq_flags_ptr); +int wifi_set_power(int on, unsigned long msec); +int wifi_get_mac_addr(unsigned char *buf); +void *wifi_get_country_code(char *ccode); +#else +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/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ap.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ap.h new file mode 100644 index 00000000..9eaf324c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ap.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_AP_H_ +#define __RTW_AP_H_ + + +#ifdef CONFIG_AP_MODE + +//external function +extern void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta); +extern void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta); + + +void init_mlme_ap_info(_adapter *padapter); +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, 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); +void rtw_start_bss_hdl_after_chbw_decided(_adapter *adapter); +void start_bss_network(_adapter *padapter, struct createbss_parm *parm); +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len); +void rtw_ap_restore_network(_adapter *padapter); +void rtw_set_macaddr_acl(_adapter *padapter, int mode); +int rtw_acl_add_sta(_adapter *padapter, u8 *addr); +int rtw_acl_remove_sta(_adapter *padapter, u8 *addr); + +u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta); +int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid); +int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx); + +#ifdef CONFIG_NATIVEAP_MLME +void associated_clients_update(_adapter *padapter, u8 updated, u32 sta_info_type); +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); +void sta_info_update(_adapter *padapter, struct sta_info *psta); +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason, bool enqueue); +int rtw_sta_flush(_adapter *padapter, bool enqueue); +int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset); +void start_ap_mode(_adapter *padapter); +void stop_ap_mode(_adapter *padapter); +#endif + +void rtw_ap_update_bss_chbw(_adapter *adapter, WLAN_BSSID_EX *bss, u8 ch, u8 bw, u8 offset); +bool rtw_ap_chbw_decision(_adapter *adapter, u8 req_ch, u8 req_bw, u8 req_offset, u8 *ch, u8 *bw, u8 *offset); + +#ifdef CONFIG_AUTO_AP_MODE +extern void rtw_start_auto_ap(_adapter *adapter); +#endif //CONFIG_AUTO_AP_MODE + +#endif //end of CONFIG_AP_MODE + +#endif +void update_bmc_sta(_adapter *padapter); + +void rtw_process_ht_action_smps(_adapter *padapter, u8 *ta, u8 ctrl_field); +void rtw_process_public_act_bsscoex(_adapter *padapter, u8 *pframe, uint frame_len); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_beamforming.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_beamforming.h new file mode 100644 index 00000000..8f71afdd --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_beamforming.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * + * 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 __RTW_BEAMFORMING_H_ +#define __RTW_BEAMFORMING_H_ + +#ifdef CONFIG_BEAMFORMING + +#if (BEAMFORMING_SUPPORT == 0) /*for diver defined beamforming*/ +#define BEAMFORMING_ENTRY_NUM 2 +#define GET_BEAMFORM_INFO(_pmlmepriv) ((struct beamforming_info *)(&(_pmlmepriv)->beamforming_info)) + + +typedef enum _BEAMFORMING_ENTRY_STATE +{ + BEAMFORMING_ENTRY_STATE_UNINITIALIZE, + BEAMFORMING_ENTRY_STATE_INITIALIZEING, + BEAMFORMING_ENTRY_STATE_INITIALIZED, + BEAMFORMING_ENTRY_STATE_PROGRESSING, + BEAMFORMING_ENTRY_STATE_PROGRESSED, +}BEAMFORMING_ENTRY_STATE, *PBEAMFORMING_ENTRY_STATE; + + +typedef enum _BEAMFORMING_STATE +{ + BEAMFORMING_STATE_IDLE, + BEAMFORMING_STATE_START, + BEAMFORMING_STATE_END, +}BEAMFORMING_STATE, *PBEAMFORMING_STATE; + + +typedef enum _BEAMFORMING_CAP +{ + BEAMFORMING_CAP_NONE = 0x0, + BEAMFORMER_CAP_HT_EXPLICIT = 0x1, + BEAMFORMEE_CAP_HT_EXPLICIT = 0x2, + BEAMFORMER_CAP_VHT_SU = 0x4, // Self has er Cap, because Reg er & peer ee + BEAMFORMEE_CAP_VHT_SU = 0x8, // Self has ee Cap, because Reg ee & peer er + BEAMFORMER_CAP = 0x10, + BEAMFORMEE_CAP = 0x20, +}BEAMFORMING_CAP, *PBEAMFORMING_CAP; + + +typedef enum _SOUNDING_MODE +{ + SOUNDING_SW_VHT_TIMER = 0x0, + SOUNDING_SW_HT_TIMER = 0x1, + SOUNDING_STOP_All_TIMER = 0x2, + SOUNDING_HW_VHT_TIMER = 0x3, + SOUNDING_HW_HT_TIMER = 0x4, + SOUNDING_STOP_OID_TIMER = 0x5, + SOUNDING_AUTO_VHT_TIMER = 0x6, + SOUNDING_AUTO_HT_TIMER = 0x7, + SOUNDING_FW_VHT_TIMER = 0x8, + SOUNDING_FW_HT_TIMER = 0x9, +}SOUNDING_MODE, *PSOUNDING_MODE; + +struct beamforming_entry { + BOOLEAN bUsed; + BOOLEAN bSound; + u16 aid; // Used to construct AID field of NDPA packet. + u16 mac_id; // Used to Set Reg42C in IBSS mode. + u16 p_aid; // Used to fill Reg42C & Reg714 to compare with P_AID of Tx DESC. + u16 g_id; + u8 mac_addr[6];// Used to fill Reg6E4 to fill Mac address of CSI report frame. + CHANNEL_WIDTH sound_bw; // Sounding BandWidth + u16 sound_period; + BEAMFORMING_CAP beamforming_entry_cap; + BEAMFORMING_ENTRY_STATE beamforming_entry_state; + u8 ClockResetTimes; /*Modified by Jeffery @2015-04-10*/ + u8 PreLogSeq; /*Modified by Jeffery @2015-03-30*/ + u8 LogSeq; /*Modified by Jeffery @2014-10-29*/ + u16 LogRetryCnt:3; /*Modified by Jeffery @2014-10-29*/ + u16 LogSuccess:2; /*Modified by Jeffery @2014-10-29*/ + + u8 LogStatusFailCnt; + u8 PreCsiReport[327]; + u8 DefaultCsiCnt; + BOOLEAN bDefaultCSI; +}; + +struct sounding_info { + u8 sound_idx; + CHANNEL_WIDTH sound_bw; + SOUNDING_MODE sound_mode; + u16 sound_period; +}; + +struct beamforming_info { + BEAMFORMING_CAP beamforming_cap; + BEAMFORMING_STATE beamforming_state; + struct beamforming_entry beamforming_entry[BEAMFORMING_ENTRY_NUM]; + u8 beamforming_cur_idx; + u8 beamforming_in_progress; + u8 sounding_sequence; + struct sounding_info sounding_info; +}; + +struct rtw_ndpa_sta_info { + u16 aid:12; + u16 feedback_type:1; + u16 nc_index:3; +}; + +BEAMFORMING_CAP beamforming_get_entry_beam_cap_by_mac_id(PVOID pmlmepriv ,u8 mac_id); +void beamforming_notify(PADAPTER adapter); +BEAMFORMING_CAP beamforming_get_beamform_cap(struct beamforming_info *pBeamInfo); + +BOOLEAN beamforming_send_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx); +BOOLEAN beamforming_send_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx); + +void beamforming_check_sounding_success(PADAPTER Adapter,BOOLEAN status); + +void beamforming_watchdog(PADAPTER Adapter); +#endif /*#if (BEAMFORMING_SUPPORT ==0)- for diver defined beamforming*/ + +enum BEAMFORMING_CTRL_TYPE { + BEAMFORMING_CTRL_ENTER = 0, + BEAMFORMING_CTRL_LEAVE = 1, + BEAMFORMING_CTRL_START_PERIOD = 2, + BEAMFORMING_CTRL_END_PERIOD = 3, + BEAMFORMING_CTRL_SOUNDING_FAIL = 4, + BEAMFORMING_CTRL_SOUNDING_CLK = 5, +}; +u32 beamforming_get_report_frame(PADAPTER Adapter, union recv_frame *precv_frame); +void beamforming_get_ndpa_frame(PADAPTER Adapter, union recv_frame *precv_frame); + +void beamforming_wk_hdl(_adapter *padapter, u8 type, u8 *pbuf); +u8 beamforming_wk_cmd(_adapter*padapter, s32 type, u8 *pbuf, s32 size, u8 enqueue); +void update_attrib_txbf_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta); + +#endif /*#ifdef CONFIG_BEAMFORMING */ + +#endif /*__RTW_BEAMFORMING_H_*/ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_br_ext.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_br_ext.h new file mode 100644 index 00000000..dcb51014 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_br_ext.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 _RTW_BR_EXT_H_ +#define _RTW_BR_EXT_H_ + +#if 1 // rtw_wifi_driver +#define CL_IPV6_PASS 1 +#define MACADDRLEN 6 +#define _DEBUG_ERR DBG_8192C +#define _DEBUG_INFO //DBG_8192C +#define DEBUG_WARN DBG_8192C +#define DEBUG_INFO //DBG_8192C +#define DEBUG_ERR DBG_8192C +//#define GET_MY_HWADDR ((GET_MIB(priv))->dot11OperationEntry.hwaddr) +#define GET_MY_HWADDR(padapter) (adapter_mac_addr(padapter)) +#endif // rtw_wifi_driver + +#define NAT25_HASH_BITS 4 +#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS) +#define NAT25_AGEING_TIME 300 + +#ifdef CL_IPV6_PASS +#define MAX_NETWORK_ADDR_LEN 17 +#else +#define MAX_NETWORK_ADDR_LEN 11 +#endif + +struct nat25_network_db_entry +{ + struct nat25_network_db_entry *next_hash; + struct nat25_network_db_entry **pprev_hash; + atomic_t use_count; + unsigned char macAddr[6]; + unsigned long ageing_timer; + unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; +}; + +enum NAT25_METHOD { + NAT25_MIN, + NAT25_CHECK, + NAT25_INSERT, + NAT25_LOOKUP, + NAT25_PARSE, + NAT25_MAX +}; + +struct br_ext_info { + unsigned int nat25_disable; + unsigned int macclone_enable; + unsigned int dhcp_bcst_disable; + int addPPPoETag; // 1: Add PPPoE relay-SID, 0: disable + unsigned char nat25_dmzMac[MACADDRLEN]; + unsigned int nat25sc_disable; +}; + +void nat25_db_cleanup(_adapter *priv); + +#endif // _RTW_BR_EXT_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_bt_mp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_bt_mp.h new file mode 100644 index 00000000..8d26045a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_bt_mp.h @@ -0,0 +1,295 @@ +/****************************************************************************** + * + * 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 __RTW_BT_MP_H +#define __RTW_BT_MP_H + + +#if(MP_DRIVER == 1) + +#pragma pack(1) + +// definition for BT_UP_OP_BT_READY +#define MP_BT_NOT_READY 0 +#define MP_BT_READY 1 + +// definition for BT_UP_OP_BT_SET_MODE +typedef enum _MP_BT_MODE{ + MP_BT_MODE_RF_TXRX_TEST_MODE = 0, + MP_BT_MODE_BT20_DUT_TEST_MODE = 1, + MP_BT_MODE_BT40_DIRECT_TEST_MODE = 2, + MP_BT_MODE_CONNECT_TEST_MODE = 3, + MP_BT_MODE_MAX +}MP_BT_MODE,*PMP_BT_MODE; + + +// definition for BT_UP_OP_BT_SET_TX_RX_PARAMETER +typedef struct _BT_TXRX_PARAMETERS{ + u1Byte txrxChannel; + u4Byte txrxTxPktCnt; + u1Byte txrxTxPktInterval; + u1Byte txrxPayloadType; + u1Byte txrxPktType; + u2Byte txrxPayloadLen; + u4Byte txrxPktHeader; + u1Byte txrxWhitenCoeff; + u1Byte txrxBdaddr[6]; + u1Byte txrxTxGainIndex; +} BT_TXRX_PARAMETERS, *PBT_TXRX_PARAMETERS; + +// txrxPktType +typedef enum _MP_BT_PKT_TYPE{ + MP_BT_PKT_DH1 = 0, + MP_BT_PKT_DH3 = 1, + MP_BT_PKT_DH5 = 2, + MP_BT_PKT_2DH1 = 3, + MP_BT_PKT_2DH3 = 4, + MP_BT_PKT_2DH5 = 5, + MP_BT_PKT_3DH1 = 6, + MP_BT_PKT_3DH3 = 7, + MP_BT_PKT_3DH5 = 8, + MP_BT_PKT_LE = 9, + MP_BT_PKT_MAX +}MP_BT_PKT_TYPE,*PMP_BT_PKT_TYPE; +// txrxPayloadType +typedef enum _MP_BT_PAYLOAD_TYPE{ + MP_BT_PAYLOAD_01010101 = 0, + MP_BT_PAYLOAD_ALL_1 = 1, + MP_BT_PAYLOAD_ALL_0 = 2, + MP_BT_PAYLOAD_11110000 = 3, + MP_BT_PAYLOAD_PRBS9 = 4, + MP_BT_PAYLOAD_MAX = 8, +}MP_BT_PAYLOAD_TYPE,*PMP_BT_PAYLOAD_TYPE; + + +// definition for BT_UP_OP_BT_TEST_CTRL +typedef enum _MP_BT_TEST_CTRL{ + MP_BT_TEST_STOP_ALL_TESTS = 0, + MP_BT_TEST_START_RX_TEST = 1, + MP_BT_TEST_START_PACKET_TX_TEST = 2, + MP_BT_TEST_START_CONTINUOUS_TX_TEST = 3, + MP_BT_TEST_START_INQUIRY_SCAN_TEST = 4, + MP_BT_TEST_START_PAGE_SCAN_TEST = 5, + MP_BT_TEST_START_INQUIRY_PAGE_SCAN_TEST = 6, + MP_BT_TEST_START_LEGACY_CONNECT_TEST = 7, + MP_BT_TEST_START_LE_CONNECT_TEST_INITIATOR = 8, + MP_BT_TEST_START_LE_CONNECT_TEST_ADVERTISER = 9, + MP_BT_TEST_MAX +}MP_BT_TEST_CTRL,*PMP_BT_TEST_CTRL; + + +typedef enum _RTL_EXT_C2H_EVT +{ + EXT_C2H_WIFI_FW_ACTIVE_RSP = 0, + EXT_C2H_TRIG_BY_BT_FW = 1, + MAX_EXT_C2HEVENT +}RTL_EXT_C2H_EVT; + +// OP codes definition between the user layer and driver +typedef enum _BT_CTRL_OPCODE_UPPER{ + BT_UP_OP_BT_READY = 0x00, + BT_UP_OP_BT_SET_MODE = 0x01, + BT_UP_OP_BT_SET_TX_RX_PARAMETER = 0x02, + BT_UP_OP_BT_SET_GENERAL = 0x03, + BT_UP_OP_BT_GET_GENERAL = 0x04, + BT_UP_OP_BT_TEST_CTRL = 0x05, + BT_UP_OP_TEST_BT = 0x06, + BT_UP_OP_MAX +}BT_CTRL_OPCODE_UPPER,*PBT_CTRL_OPCODE_UPPER; + + +typedef enum _BT_SET_GENERAL{ + BT_GSET_REG = 0x00, + BT_GSET_RESET = 0x01, + BT_GSET_TARGET_BD_ADDR = 0x02, + BT_GSET_TX_PWR_FINETUNE = 0x03, + BT_SET_TRACKING_INTERVAL = 0x04, + BT_SET_THERMAL_METER = 0x05, + BT_ENABLE_CFO_TRACKING = 0x06, + BT_GSET_UPDATE_BT_PATCH = 0x07, + BT_GSET_MAX +}BT_SET_GENERAL,*PBT_SET_GENERAL; + +typedef enum _BT_GET_GENERAL{ + BT_GGET_REG = 0x00, + BT_GGET_STATUS = 0x01, + BT_GGET_REPORT = 0x02, + BT_GGET_AFH_MAP = 0x03, + BT_GGET_AFH_STATUS = 0x04, + BT_GGET_MAX +}BT_GET_GENERAL,*PBT_GET_GENERAL; + +// definition for BT_UP_OP_BT_SET_GENERAL +typedef enum _BT_REG_TYPE{ + BT_REG_RF = 0, + BT_REG_MODEM = 1, + BT_REG_BLUEWIZE = 2, + BT_REG_VENDOR = 3, + BT_REG_LE = 4, + BT_REG_MAX +}BT_REG_TYPE,*PBT_REG_TYPE; + +// definition for BT_LO_OP_GET_AFH_MAP +typedef enum _BT_AFH_MAP_TYPE{ + BT_AFH_MAP_RESULT = 0, + BT_AFH_MAP_WIFI_PSD_ONLY = 1, + BT_AFH_MAP_WIFI_CH_BW_ONLY = 2, + BT_AFH_MAP_BT_PSD_ONLY = 3, + BT_AFH_MAP_HOST_CLASSIFICATION_ONLY = 4, + BT_AFH_MAP_MAX +}BT_AFH_MAP_TYPE,*PBT_AFH_MAP_TYPE; + +// definition for BT_UP_OP_BT_GET_GENERAL +typedef enum _BT_REPORT_TYPE{ + BT_REPORT_RX_PACKET_CNT = 0, + BT_REPORT_RX_ERROR_BITS = 1, + BT_REPORT_RSSI = 2, + BT_REPORT_CFO_HDR_QUALITY = 3, + BT_REPORT_CONNECT_TARGET_BD_ADDR = 4, + BT_REPORT_MAX +}BT_REPORT_TYPE,*PBT_REPORT_TYPE; + +VOID +MPTBT_Test( + IN PADAPTER Adapter, + IN u1Byte opCode, + IN u1Byte byte1, + IN u1Byte byte2, + IN u1Byte byte3 + ); + +NDIS_STATUS +MPTBT_SendOidBT( + IN PADAPTER pAdapter, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded + ); + +VOID +MPTBT_FwC2hBtMpCtrl( + PADAPTER Adapter, + pu1Byte tmpBuf, + u1Byte length + ); + +void MPh2c_timeout_handle(void *FunctionContext); + +VOID mptbt_BtControlProcess( + PADAPTER Adapter, + PVOID pInBuf + ); + +#define BT_H2C_MAX_RETRY 1 +#define BT_MAX_C2H_LEN 20 + +typedef struct _BT_REQ_CMD{ + UCHAR opCodeVer; + UCHAR OpCode; + USHORT paraLength; + UCHAR pParamStart[100]; +} BT_REQ_CMD, *PBT_REQ_CMD; + +typedef struct _BT_RSP_CMD{ + USHORT status; + USHORT paraLength; + UCHAR pParamStart[100]; +} BT_RSP_CMD, *PBT_RSP_CMD; + + +typedef struct _BT_H2C{ + u1Byte opCodeVer:4; + u1Byte reqNum:4; + u1Byte opCode; + u1Byte buf[100]; +}BT_H2C, *PBT_H2C; + + + +typedef struct _BT_EXT_C2H{ + u1Byte extendId; + u1Byte statusCode:4; + u1Byte retLen:4; + u1Byte opCodeVer:4; + u1Byte reqNum:4; + u1Byte buf[100]; +}BT_EXT_C2H, *PBT_EXT_C2H; + + +typedef enum _BT_OPCODE_STATUS{ + BT_OP_STATUS_SUCCESS = 0x00, // Success + BT_OP_STATUS_VERSION_MISMATCH = 0x01, + BT_OP_STATUS_UNKNOWN_OPCODE = 0x02, + BT_OP_STATUS_ERROR_PARAMETER = 0x03, + BT_OP_STATUS_MAX +}BT_OPCODE_STATUS,*PBT_OPCODE_STATUS; + + + +//OP codes definition between driver and bt fw +typedef enum _BT_CTRL_OPCODE_LOWER{ + BT_LO_OP_GET_BT_VERSION = 0x00, + BT_LO_OP_RESET = 0x01, + BT_LO_OP_TEST_CTRL = 0x02, + BT_LO_OP_SET_BT_MODE = 0x03, + BT_LO_OP_SET_CHNL_TX_GAIN = 0x04, + BT_LO_OP_SET_PKT_TYPE_LEN = 0x05, + BT_LO_OP_SET_PKT_CNT_L_PL_TYPE = 0x06, + BT_LO_OP_SET_PKT_CNT_H_PKT_INTV = 0x07, + BT_LO_OP_SET_PKT_HEADER = 0x08, + BT_LO_OP_SET_WHITENCOEFF = 0x09, + BT_LO_OP_SET_BD_ADDR_L = 0x0a, + BT_LO_OP_SET_BD_ADDR_H = 0x0b, + BT_LO_OP_WRITE_REG_ADDR = 0x0c, + BT_LO_OP_WRITE_REG_VALUE = 0x0d, + BT_LO_OP_GET_BT_STATUS = 0x0e, + BT_LO_OP_GET_BD_ADDR_L = 0x0f, + BT_LO_OP_GET_BD_ADDR_H = 0x10, + BT_LO_OP_READ_REG = 0x11, + BT_LO_OP_SET_TARGET_BD_ADDR_L = 0x12, + BT_LO_OP_SET_TARGET_BD_ADDR_H = 0x13, + BT_LO_OP_SET_TX_POWER_CALIBRATION = 0x14, + BT_LO_OP_GET_RX_PKT_CNT_L = 0x15, + BT_LO_OP_GET_RX_PKT_CNT_H = 0x16, + BT_LO_OP_GET_RX_ERROR_BITS_L = 0x17, + BT_LO_OP_GET_RX_ERROR_BITS_H = 0x18, + BT_LO_OP_GET_RSSI = 0x19, + BT_LO_OP_GET_CFO_HDR_QUALITY_L = 0x1a, + BT_LO_OP_GET_CFO_HDR_QUALITY_H = 0x1b, + BT_LO_OP_GET_TARGET_BD_ADDR_L = 0x1c, + BT_LO_OP_GET_TARGET_BD_ADDR_H = 0x1d, + BT_LO_OP_GET_AFH_MAP_L = 0x1e, + BT_LO_OP_GET_AFH_MAP_M = 0x1f, + BT_LO_OP_GET_AFH_MAP_H = 0x20, + BT_LO_OP_GET_AFH_STATUS = 0x21, + BT_LO_OP_SET_TRACKING_INTERVAL = 0x22, + BT_LO_OP_SET_THERMAL_METER = 0x23, + BT_LO_OP_ENABLE_CFO_TRACKING = 0x24, + BT_LO_OP_MAX +}BT_CTRL_OPCODE_LOWER,*PBT_CTRL_OPCODE_LOWER; + + + + +#endif /* #if(MP_DRIVER == 1) */ + +#endif // #ifndef __INC_MPT_BT_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_btcoex.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_btcoex.h new file mode 100644 index 00000000..b1489c4b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_btcoex.h @@ -0,0 +1,436 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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_BTCOEX_H__ +#define __RTW_BTCOEX_H__ + +#include + +/* For H2C: H2C_BT_MP_OPER. Return status definition to the user layer */ +typedef enum _BT_CTRL_STATUS { + BT_STATUS_SUCCESS = 0x00, /* Success */ + BT_STATUS_BT_OP_SUCCESS = 0x01, /* bt fw op execution success */ + BT_STATUS_H2C_SUCCESS = 0x02, /* H2c success */ + BT_STATUS_H2C_FAIL = 0x03, /* H2c fail */ + BT_STATUS_H2C_LENGTH_EXCEEDED = 0x04, /* H2c command length exceeded */ + BT_STATUS_H2C_TIMTOUT = 0x05, /* H2c timeout */ + BT_STATUS_H2C_BT_NO_RSP = 0x06, /* H2c sent, bt no rsp */ + BT_STATUS_C2H_SUCCESS = 0x07, /* C2h success */ + BT_STATUS_C2H_REQNUM_MISMATCH = 0x08, /* bt fw wrong rsp */ + BT_STATUS_OPCODE_U_VERSION_MISMATCH = 0x08, /* Upper layer OP code version mismatch. */ + BT_STATUS_OPCODE_L_VERSION_MISMATCH = 0x0a, /* Lower layer OP code version mismatch. */ + BT_STATUS_UNKNOWN_OPCODE_U = 0x0b, /* Unknown Upper layer OP code */ + BT_STATUS_UNKNOWN_OPCODE_L = 0x0c, /* Unknown Lower layer OP code */ + BT_STATUS_PARAMETER_FORMAT_ERROR_U = 0x0d, /* Wrong parameters sent by upper layer. */ + BT_STATUS_PARAMETER_FORMAT_ERROR_L = 0x0e, /* bt fw parameter format is not consistency */ + BT_STATUS_PARAMETER_OUT_OF_RANGE_U = 0x0f, /* uppery layer parameter value is out of range */ + BT_STATUS_PARAMETER_OUT_OF_RANGE_L = 0x10, /* bt fw parameter value is out of range */ + BT_STATUS_UNKNOWN_STATUS_L = 0x11, /* bt returned an defined status code */ + BT_STATUS_UNKNOWN_STATUS_H = 0x12, /* driver need to do error handle or not handle-well. */ + BT_STATUS_WRONG_LEVEL = 0x13, /* should be under passive level */ + BT_STATUS_NOT_IMPLEMENT = 0x14, /* op code not implemented yet */ + BT_STATUS_BT_STACK_OP_SUCCESS = 0x15, /* bt stack op execution success */ + BT_STATUS_BT_STACK_NOT_SUPPORT = 0x16, /* stack version not support this. */ + BT_STATUS_BT_STACK_SEND_HCI_EVENT_FAIL = 0x17, /* send hci event fail */ + BT_STATUS_BT_STACK_NOT_BIND = 0x18, /* stack not bind wifi driver */ + BT_STATUS_BT_STACK_NO_RSP = 0x19, /* stack doesn't have any rsp. */ + BT_STATUS_MAX +} BT_CTRL_STATUS, *PBT_CTRL_STATUS; + +#define SET_BT_MP_OPER_RET(OpCode, StatusCode) ((OpCode << 8) | StatusCode) +#define GET_OP_CODE_FROM_BT_MP_OPER_RET(RetCode) ((RetCode & 0xF0) >> 8) +#define GET_STATUS_CODE_FROM_BT_MP_OPER_RET(RetCode) (RetCode & 0x0F) +#define CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(RetCode, StatusCode) (GET_STATUS_CODE_FROM_BT_MP_OPER_RET(RetCode) == StatusCode) + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + +#define NETLINK_USER 31 +#define CONNECT_PORT 30000 +#define CONNECT_PORT_BT 30001 +#define KERNEL_SOCKET_OK 0x01 +#define NETLINK_SOCKET_OK 0x02 + +#define OTHER 0 +#define RX_ATTEND_ACK 1 +#define RX_LEAVE_ACK 2 +#define RX_BT_LEAVE 3 +#define RX_INVITE_REQ 4 +#define RX_ATTEND_REQ 5 +#define RX_INVITE_RSP 6 + +#define invite_req "INVITE_REQ" +#define invite_rsp "INVITE_RSP" +#define attend_req "ATTEND_REQ" +#define attend_ack "ATTEND_ACK" +#define wifi_leave "WIFI_LEAVE" +#define leave_ack "LEAVE_ACK" +#define bt_leave "BT_LEAVE" + +#define BT_INFO_NOTIFY_CMD 0x0106 +#define BT_INFO_LEN 8 + +typedef struct _HCI_LINK_INFO{ + u2Byte ConnectHandle; + u1Byte IncomingTrafficMode; + u1Byte OutgoingTrafficMode; + u1Byte BTProfile; + u1Byte BTCoreSpec; + s1Byte BT_RSSI; + u1Byte TrafficProfile; + u1Byte linkRole; +}HCI_LINK_INFO, *PHCI_LINK_INFO; + +#define MAX_BT_ACL_LINK_NUM 8 + +typedef struct _HCI_EXT_CONFIG{ + HCI_LINK_INFO aclLink[MAX_BT_ACL_LINK_NUM]; + u1Byte btOperationCode; + u2Byte CurrentConnectHandle; + u1Byte CurrentIncomingTrafficMode; + u1Byte CurrentOutgoingTrafficMode; + + u1Byte NumberOfACL; + u1Byte NumberOfSCO; + u1Byte CurrentBTStatus; + u2Byte HCIExtensionVer; + + BOOLEAN bEnableWifiScanNotify; +}HCI_EXT_CONFIG, *PHCI_EXT_CONFIG; + +typedef struct _HCI_PHY_LINK_BSS_INFO{ + u2Byte bdCap; // capability information + + // Qos related. Added by Annie, 2005-11-01. + //BSS_QOS BssQos; + +}HCI_PHY_LINK_BSS_INFO, *PHCI_PHY_LINK_BSS_INFO; + +typedef enum _BT_CONNECT_TYPE{ + BT_CONNECT_AUTH_REQ =0x00, + BT_CONNECT_AUTH_RSP =0x01, + BT_CONNECT_ASOC_REQ =0x02, + BT_CONNECT_ASOC_RSP =0x03, + BT_DISCONNECT =0x04 +}BT_CONNECT_TYPE,*PBT_CONNECT_TYPE; + + +typedef struct _PACKET_IRP_HCIEVENT_DATA { + u8 EventCode; + u8 Length; //total cmd length = extension event length+1(extension event code length) + u8 Data[1]; // byte1 is extension event code +} rtw_HCI_event; + + +struct btinfo_8761ATV { + u8 cid; + u8 len; + + u8 bConnection:1; + u8 bSCOeSCO:1; + u8 bInQPage:1; + u8 bACLBusy:1; + u8 bSCOBusy:1; + u8 bHID:1; + u8 bA2DP:1; + u8 bFTP:1; + + u8 retry_cnt:4; + u8 rsvd_34:1; + u8 bPage:1; + u8 TRxMask:1; + u8 Sniff_attempt:1; + + u8 rssi; + + u8 A2dp_rate:1; + u8 ReInit:1; + u8 MaxPower:1; + u8 bEnIgnoreWlanAct:1; + u8 TxPowerLow:1; + u8 TxPowerHigh:1; + u8 eSCO_SCO:1; + u8 Master_Slave:1; + + u8 ACL_TRx_TP_low; + u8 ACL_TRx_TP_high; +}; + +#define HCIOPCODE(_OCF, _OGF) ((_OGF)<<10|(_OCF)) +#define HCIOPCODELOW(_OCF, _OGF) (u8)(HCIOPCODE(_OCF, _OGF)&0x00ff) +#define HCIOPCODEHIGHT(_OCF, _OGF) (u8)(HCIOPCODE(_OCF, _OGF)>>8) +#define HCI_OGF(opCode) (unsigned char)((0xFC00 & (opCode)) >> 10) +#define HCI_OCF(opCode) ( 0x3FF & (opCode)) + + +typedef enum _HCI_STATUS{ + HCI_STATUS_SUCCESS =0x00, //Success + HCI_STATUS_UNKNOW_HCI_CMD =0x01, //Unknown HCI Command + HCI_STATUS_UNKNOW_CONNECT_ID =0X02, //Unknown Connection Identifier + HCI_STATUS_HW_FAIL =0X03, //Hardware Failure + HCI_STATUS_PAGE_TIMEOUT =0X04, //Page Timeout + HCI_STATUS_AUTH_FAIL =0X05, //Authentication Failure + HCI_STATUS_PIN_OR_KEY_MISSING =0X06, //PIN or Key Missing + HCI_STATUS_MEM_CAP_EXCEED =0X07, //Memory Capacity Exceeded + HCI_STATUS_CONNECT_TIMEOUT =0X08, //Connection Timeout + HCI_STATUS_CONNECT_LIMIT =0X09, //Connection Limit Exceeded + HCI_STATUS_SYN_CONNECT_LIMIT =0X0a, //Synchronous Connection Limit To A Device Exceeded + HCI_STATUS_ACL_CONNECT_EXISTS =0X0b, //ACL Connection Already Exists + HCI_STATUS_CMD_DISALLOW =0X0c, //Command Disallowed + HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE =0X0d, //Connection Rejected due to Limited Resources + HCI_STATUS_CONNECT_RJT_SEC_REASON =0X0e, //Connection Rejected Due To Security Reasons + HCI_STATUS_CONNECT_RJT_UNACCEPT_BD_ADDR =0X0f, //Connection Rejected due to Unacceptable BD_ADDR + HCI_STATUS_CONNECT_ACCEPT_TIMEOUT =0X10, //Connection Accept Timeout Exceeded + HCI_STATUS_UNSUPPORT_FEATURE_PARA_VALUE =0X11, //Unsupported Feature or Parameter Value + HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE =0X12, //Invalid HCI Command Parameters + HCI_STATUS_REMOTE_USER_TERMINATE_CONNECT =0X13, //Remote User Terminated Connection + HCI_STATUS_REMOTE_DEV_TERMINATE_LOW_RESOURCE =0X14, //Remote Device Terminated Connection due to Low Resources + HCI_STATUS_REMOTE_DEV_TERMINATE_CONNECT_POWER_OFF =0X15, //Remote Device Terminated Connection due to Power Off + HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST =0X16, //Connection Terminated By Local Host + HCI_STATUS_REPEATE_ATTEMPT =0X17, //Repeated Attempts + HCI_STATUS_PAIR_NOT_ALLOW =0X18, //Pairing Not Allowed + HCI_STATUS_UNKNOW_LMP_PDU =0X19, //Unknown LMP PDU + HCI_STATUS_UNSUPPORT_REMOTE_LMP_FEATURE =0X1a, //Unsupported Remote Feature / Unsupported LMP Feature + HCI_STATUS_SOC_OFFSET_REJECT =0X1b, //SCO Offset Rejected + HCI_STATUS_SOC_INTERVAL_REJECT =0X1c, //SCO Interval Rejected + HCI_STATUS_SOC_AIR_MODE_REJECT =0X1d,//SCO Air Mode Rejected + HCI_STATUS_INVALID_LMP_PARA =0X1e, //Invalid LMP Parameters + HCI_STATUS_UNSPECIFIC_ERROR =0X1f, //Unspecified Error + HCI_STATUS_UNSUPPORT_LMP_PARA_VALUE =0X20, //Unsupported LMP Parameter Value + HCI_STATUS_ROLE_CHANGE_NOT_ALLOW =0X21, //Role Change Not Allowed + HCI_STATUS_LMP_RESPONSE_TIMEOUT =0X22, //LMP Response Timeout + HCI_STATUS_LMP_ERROR_TRANSACTION_COLLISION =0X23, //LMP Error Transaction Collision + HCI_STATUS_LMP_PDU_NOT_ALLOW =0X24, //LMP PDU Not Allowed + HCI_STATUS_ENCRYPTION_MODE_NOT_ALLOW =0X25, //Encryption Mode Not Acceptable + HCI_STATUS_LINK_KEY_CAN_NOT_CHANGE =0X26, //Link Key Can Not be Changed + HCI_STATUS_REQUEST_QOS_NOT_SUPPORT =0X27, //Requested QoS Not Supported + HCI_STATUS_INSTANT_PASSED =0X28, //Instant Passed + HCI_STATUS_PAIRING_UNIT_KEY_NOT_SUPPORT =0X29, //Pairing With Unit Key Not Supported + HCI_STATUS_DIFFERENT_TRANSACTION_COLLISION =0X2a, //Different Transaction Collision + HCI_STATUS_RESERVE_1 =0X2b, //Reserved + HCI_STATUS_QOS_UNACCEPT_PARA =0X2c, //QoS Unacceptable Parameter + HCI_STATUS_QOS_REJECT =0X2d, //QoS Rejected + HCI_STATUS_CHNL_CLASSIFICATION_NOT_SUPPORT =0X2e, //Channel Classification Not Supported + HCI_STATUS_INSUFFICIENT_SECURITY =0X2f, //Insufficient Security + HCI_STATUS_PARA_OUT_OF_RANGE =0x30, //Parameter Out Of Mandatory Range + HCI_STATUS_RESERVE_2 =0X31, //Reserved + HCI_STATUS_ROLE_SWITCH_PENDING =0X32, //Role Switch Pending + HCI_STATUS_RESERVE_3 =0X33, //Reserved + HCI_STATUS_RESERVE_SOLT_VIOLATION =0X34, //Reserved Slot Violation + HCI_STATUS_ROLE_SWITCH_FAIL =0X35, //Role Switch Failed + HCI_STATUS_EXTEND_INQUIRY_RSP_TOO_LARGE =0X36, //Extended Inquiry Response Too Large + HCI_STATUS_SEC_SIMPLE_PAIRING_NOT_SUPPORT =0X37, //Secure Simple Pairing Not Supported By Host. + HCI_STATUS_HOST_BUSY_PAIRING =0X38, //Host Busy - Pairing + HCI_STATUS_CONNECT_REJ_NOT_SUIT_CHNL_FOUND =0X39, //Connection Rejected due to No Suitable Channel Found + HCI_STATUS_CONTROLLER_BUSY =0X3a //CONTROLLER BUSY +}RTW_HCI_STATUS; + +#define HCI_EVENT_COMMAND_COMPLETE 0x0e + +#define OGF_EXTENSION 0X3f +typedef enum HCI_EXTENSION_COMMANDS{ + HCI_SET_ACL_LINK_DATA_FLOW_MODE =0x0010, + HCI_SET_ACL_LINK_STATUS =0x0020, + HCI_SET_SCO_LINK_STATUS =0x0030, + HCI_SET_RSSI_VALUE =0x0040, + HCI_SET_CURRENT_BLUETOOTH_STATUS =0x0041, + + //The following is for RTK8723 + HCI_EXTENSION_VERSION_NOTIFY =0x0100, + HCI_LINK_STATUS_NOTIFY =0x0101, + HCI_BT_OPERATION_NOTIFY =0x0102, + HCI_ENABLE_WIFI_SCAN_NOTIFY =0x0103, + HCI_QUERY_RF_STATUS =0x0104, + HCI_BT_ABNORMAL_NOTIFY =0x0105, + HCI_BT_INFO_NOTIFY =0x0106, + HCI_BT_COEX_NOTIFY =0x0107, + HCI_BT_PATCH_VERSION_NOTIFY =0x0108, + HCI_BT_AFH_MAP_NOTIFY =0x0109, + HCI_BT_REGISTER_VALUE_NOTIFY =0x010a, + + //The following is for IVT + HCI_WIFI_CURRENT_CHANNEL =0x0300, + HCI_WIFI_CURRENT_BANDWIDTH =0x0301, + HCI_WIFI_CONNECTION_STATUS =0x0302 +}RTW_HCI_EXT_CMD; + +#define HCI_EVENT_EXTENSION_RTK 0xfe +typedef enum HCI_EXTENSION_EVENT_RTK{ + HCI_EVENT_EXT_WIFI_SCAN_NOTIFY =0x01, + HCI_EVENT_EXT_WIFI_RF_STATUS_NOTIFY =0x02, + HCI_EVENT_EXT_BT_INFO_CONTROL =0x03, + HCI_EVENT_EXT_BT_COEX_CONTROL =0x04 +}RTW_HCI_EXT_EVENT; + +typedef enum _BT_TRAFFIC_MODE{ + BT_MOTOR_EXT_BE = 0x00, //Best Effort. Default. for HCRP, PAN, SDP, RFCOMM-based profiles like FTP,OPP, SPP, DUN, etc. + BT_MOTOR_EXT_GUL = 0x01, //Guaranteed Latency. This type of traffic is used e.g. for HID and AVRCP. + BT_MOTOR_EXT_GUB = 0X02, //Guaranteed Bandwidth. + BT_MOTOR_EXT_GULB = 0X03 //Guaranteed Latency and Bandwidth. for A2DP and VDP. +} BT_TRAFFIC_MODE; + +typedef enum _BT_TRAFFIC_MODE_PROFILE{ + BT_PROFILE_NONE, + BT_PROFILE_A2DP, + BT_PROFILE_PAN , + BT_PROFILE_HID, + BT_PROFILE_SCO +} BT_TRAFFIC_MODE_PROFILE; + +typedef enum _HCI_EXT_BT_OPERATION { + HCI_BT_OP_NONE = 0x0, + HCI_BT_OP_INQUIRY_START = 0x1, + HCI_BT_OP_INQUIRY_FINISH = 0x2, + HCI_BT_OP_PAGING_START = 0x3, + HCI_BT_OP_PAGING_SUCCESS = 0x4, + HCI_BT_OP_PAGING_UNSUCCESS = 0x5, + HCI_BT_OP_PAIRING_START = 0x6, + HCI_BT_OP_PAIRING_FINISH = 0x7, + HCI_BT_OP_BT_DEV_ENABLE = 0x8, + HCI_BT_OP_BT_DEV_DISABLE = 0x9, + HCI_BT_OP_MAX +} HCI_EXT_BT_OPERATION, *PHCI_EXT_BT_OPERATION; + +typedef struct _BT_MGNT{ + BOOLEAN bBTConnectInProgress; + BOOLEAN bLogLinkInProgress; + BOOLEAN bPhyLinkInProgress; + BOOLEAN bPhyLinkInProgressStartLL; + u1Byte BtCurrentPhyLinkhandle; + u2Byte BtCurrentLogLinkhandle; + u1Byte CurrentConnectEntryNum; + u1Byte DisconnectEntryNum; + u1Byte CurrentBTConnectionCnt; + BT_CONNECT_TYPE BTCurrentConnectType; + BT_CONNECT_TYPE BTReceiveConnectPkt; + u1Byte BTAuthCount; + u1Byte BTAsocCount; + BOOLEAN bStartSendSupervisionPkt; + BOOLEAN BtOperationOn; + BOOLEAN BTNeedAMPStatusChg; + BOOLEAN JoinerNeedSendAuth; + HCI_PHY_LINK_BSS_INFO bssDesc; + HCI_EXT_CONFIG ExtConfig; + BOOLEAN bNeedNotifyAMPNoCap; + BOOLEAN bCreateSpportQos; + BOOLEAN bSupportProfile; + u1Byte BTChannel; + BOOLEAN CheckChnlIsSuit; + BOOLEAN bBtScan; + BOOLEAN btLogoTest; + BOOLEAN bRfStatusNotified; + BOOLEAN bBtRsvedPageDownload; +}BT_MGNT, *PBT_MGNT; + +struct bt_coex_info { + /* For Kernel Socket */ + struct socket *udpsock; + struct sockaddr_in wifi_sockaddr; /*wifi socket*/ + struct sockaddr_in bt_sockaddr;/* BT socket */ + struct sock *sk_store;/*back up socket for UDP RX int*/ + + /* store which socket is OK */ + u8 sock_open; + + u8 BT_attend; + u8 is_exist; /* socket exist */ + BT_MGNT BtMgnt; + struct workqueue_struct *btcoex_wq; + struct delayed_work recvmsg_work; +}; +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + +#define PACKET_NORMAL 0 +#define PACKET_DHCP 1 +#define PACKET_ARP 2 +#define PACKET_EAPOL 3 + +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); +void rtw_btcoex_ScanNotify(PADAPTER, u8 type); +void rtw_btcoex_ConnectNotify(PADAPTER, u8 action); +void rtw_btcoex_MediaStatusNotify(PADAPTER, u8 mediaStatus); +void rtw_btcoex_SpecialPacketNotify(PADAPTER, u8 pktType); +void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state); +void rtw_btcoex_BtInfoNotify(PADAPTER, u8 length, u8 *tmpBuf); +void rtw_btcoex_BtMpRptNotify(PADAPTER, u8 length, u8 *tmpBuf); +void rtw_btcoex_SuspendNotify(PADAPTER, u8 state); +void rtw_btcoex_HaltNotify(PADAPTER); +void rtw_btcoex_ScoreBoardStatusNotify(PADAPTER, u8 length, u8 *tmpBuf); +void rtw_btcoex_SwitchBtTRxMask(PADAPTER); +void rtw_btcoex_Switch(PADAPTER, u8 enable); +u8 rtw_btcoex_IsBtDisabled(PADAPTER); +void rtw_btcoex_Handler(PADAPTER); +s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter); +s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER); +u32 rtw_btcoex_GetAMPDUSize(PADAPTER); +void rtw_btcoex_SetManualControl(PADAPTER, u8 bmanual); +u8 rtw_btcoex_1Ant(PADAPTER); +u8 rtw_btcoex_IsBtControlLps(PADAPTER); +u8 rtw_btcoex_IsLpsOn(PADAPTER); +u8 rtw_btcoex_RpwmVal(PADAPTER); +u8 rtw_btcoex_LpsVal(PADAPTER); +void rtw_btcoex_SetBTCoexist(PADAPTER, u8 bBtExist); +void rtw_btcoex_SetChipType(PADAPTER, u8 chipType); +void rtw_btcoex_SetPGAntNum(PADAPTER, u8 antNum); +u8 rtw_btcoex_GetPGAntNum(PADAPTER); +void rtw_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath); +u32 rtw_btcoex_GetRaMask(PADAPTER); +void rtw_btcoex_RecordPwrMode(PADAPTER, u8 *pCmdBuf, u8 cmdLen); +void rtw_btcoex_DisplayBtCoexInfo(PADAPTER, u8 *pbuf, u32 bufsize); +void rtw_btcoex_SetDBG(PADAPTER, u32 *pDbgModule); +u32 rtw_btcoex_GetDBG(PADAPTER, u8 *pStrBuf, u32 bufSize); +u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER); +u8 rtw_btcoex_IsBtLinkExist(PADAPTER); +void rtw_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON); +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX +void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer, u16 btPatchVer); +void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion); +void rtw_btcoex_StackUpdateProfileInfo(void); +void rtw_btcoex_init_socket(_adapter *padapter); +void rtw_btcoex_close_socket(_adapter *padapter); +void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name); +u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force); +u8 rtw_btcoex_create_kernel_socket(_adapter *padapter); +void rtw_btcoex_close_kernel_socket(_adapter *padapter); +void rtw_btcoex_recvmsgbysocket(void *data); +u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size); +u8 rtw_btcoex_btinfo_cmd(PADAPTER padapter, u8 *pbuf, u16 length); +void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *cmd, u16 len); +void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER Adapter, u8 bNeedDbgRsp, u8 dataLen, void *pData); +void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER Adapter, u8 dataLen, void *pData); +void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType); +#define BT_SendEventExtBtCoexControl(Adapter, bNeedDbgRsp, dataLen, pData) rtw_btcoex_SendEventExtBtCoexControl(Adapter, bNeedDbgRsp, dataLen, pData) +#define BT_SendEventExtBtInfoControl(Adapter, dataLen, pData) rtw_btcoex_SendEventExtBtInfoControl(Adapter, dataLen, pData) +#endif //CONFIG_BT_COEXIST_SOCKET_TRX +u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data); +u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val); + +// ================================================== +// Below Functions are called by BT-Coex +// ================================================== +void rtw_btcoex_rx_ampdu_apply(PADAPTER); +void rtw_btcoex_LPS_Enter(PADAPTER); +void rtw_btcoex_LPS_Leave(PADAPTER); + +#endif // __RTW_BTCOEX_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_byteorder.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_byteorder.h new file mode 100644 index 00000000..29c5029c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_byteorder.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * 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 _RTL871X_BYTEORDER_H_ +#define _RTL871X_BYTEORDER_H_ + + +#if defined (CONFIG_LITTLE_ENDIAN) && defined (CONFIG_BIG_ENDIAN) +#error "Shall be CONFIG_LITTLE_ENDIAN or CONFIG_BIG_ENDIAN, but not both!\n" +#endif + +#if defined (CONFIG_LITTLE_ENDIAN) +#ifndef CONFIG_PLATFORM_MSTAR389 +# include +#endif +#elif defined (CONFIG_BIG_ENDIAN) +# include +#else +# error "Must be LITTLE/BIG Endian Host" +#endif + +#endif /* _RTL871X_BYTEORDER_H_ */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_cmd.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_cmd.h new file mode 100644 index 00000000..1f57d56c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_cmd.h @@ -0,0 +1,1320 @@ +/****************************************************************************** + * + * 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 __RTW_CMD_H_ +#define __RTW_CMD_H_ + + +#define C2H_MEM_SZ (16*1024) + +#ifndef CONFIG_RTL8711FW + + #define FREE_CMDOBJ_SZ 128 + + #define MAX_CMDSZ 1024 + #define MAX_RSPSZ 512 + #define MAX_EVTSZ 1024 + +#ifdef PLATFORM_OS_CE + #define CMDBUFF_ALIGN_SZ 4 +#else + #define CMDBUFF_ALIGN_SZ 512 +#endif + + struct cmd_obj { + _adapter *padapter; + u16 cmdcode; + u8 res; + u8 *parmbuf; + u32 cmdsz; + u8 *rsp; + u32 rspsz; + struct submit_ctx *sctx; + u8 no_io; + //_sema cmd_sem; + _list list; + }; + + /* cmd flags */ + enum { + RTW_CMDF_DIRECTLY = BIT0, + RTW_CMDF_WAIT_ACK = BIT1, + }; + + struct cmd_priv { + _sema cmd_queue_sema; + //_sema cmd_done_sema; + _sema terminate_cmdthread_sema; + _queue cmd_queue; + u8 cmd_seq; + u8 *cmd_buf; //shall be non-paged, and 4 bytes aligned + u8 *cmd_allocated_buf; + u8 *rsp_buf; //shall be non-paged, and 4 bytes aligned + u8 *rsp_allocated_buf; + u32 cmd_issued_cnt; + u32 cmd_done_cnt; + u32 rsp_cnt; + ATOMIC_T cmdthd_running; + //u8 cmdthd_running; + u8 stop_req; + _adapter *padapter; + _mutex sctx_mutex; + }; + +#ifdef CONFIG_EVENT_THREAD_MODE + struct evt_obj { + u16 evtcode; + u8 res; + u8 *parmbuf; + u32 evtsz; + _list list; + }; +#endif + + struct evt_priv { +#ifdef CONFIG_EVENT_THREAD_MODE + _sema evt_notify; + _sema terminate_evtthread_sema; + _queue evt_queue; +#endif + +#define CONFIG_C2H_WK +#ifdef CONFIG_C2H_WK + _workitem c2h_wk; + bool c2h_wk_alive; + struct rtw_cbuf *c2h_queue; + #define C2H_QUEUE_MAX_LEN 10 +#endif + +#ifdef CONFIG_H2CLBK + _sema lbkevt_done; + u8 lbkevt_limit; + u8 lbkevt_num; + u8 *cmdevt_parm; +#endif + ATOMIC_T event_seq; + u8 *evt_buf; //shall be non-paged, and 4 bytes aligned + u8 *evt_allocated_buf; + u32 evt_done_cnt; +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 *c2h_mem; + u8 *allocated_c2h_mem; +#ifdef PLATFORM_OS_XP + PMDL pc2h_mdl; +#endif +#endif + + }; + +#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ +do {\ + _rtw_init_listhead(&pcmd->list);\ + pcmd->cmdcode = code;\ + pcmd->parmbuf = (u8 *)(pparm);\ + pcmd->cmdsz = sizeof (*pparm);\ + pcmd->rsp = NULL;\ + pcmd->rspsz = 0;\ +} while(0) + +#define init_h2fwcmd_w_parm_no_parm_rsp(pcmd, code) \ +do {\ + _rtw_init_listhead(&pcmd->list);\ + pcmd->cmdcode = code;\ + pcmd->parmbuf = NULL;\ + pcmd->cmdsz = 0;\ + pcmd->rsp = NULL;\ + pcmd->rspsz = 0;\ +} while(0) + +struct c2h_evt_hdr { + u8 id:4; + u8 plen:4; + u8 seq; + u8 payload[0]; +}; + +struct c2h_evt_hdr_88xx { + u8 id; + u8 seq; + u8 payload[12]; + u8 plen; + u8 trigger; +}; + +#define c2h_evt_valid(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen) + +struct P2P_PS_Offload_t { + u8 Offload_En:1; + u8 role:1; // 1: Owner, 0: Client + u8 CTWindow_En:1; + u8 NoA0_En:1; + u8 NoA1_En:1; + u8 AllStaSleep:1; // Only valid in Owner + u8 discovery:1; + u8 rsvd:1; +}; + +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); + +#ifdef CONFIG_EVENT_THREAD_MODE +extern u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj); +extern struct evt_obj *rtw_dequeue_evt(_queue *queue); +extern void rtw_free_evt_obj(struct evt_obj *pcmd); +#endif + +void rtw_stop_cmd_thread(_adapter *adapter); +thread_return rtw_cmd_thread(thread_context context); + +extern u32 rtw_init_cmd_priv (struct cmd_priv *pcmdpriv); +extern void rtw_free_cmd_priv (struct cmd_priv *pcmdpriv); + +extern u32 rtw_init_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_free_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); +extern void rtw_evt_notify_isr(struct evt_priv *pevtpriv); +#ifdef CONFIG_P2P +u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType ); +#endif //CONFIG_P2P + +#else + //#include +#endif /* CONFIG_RTL8711FW */ + +enum rtw_drvextra_cmd_id +{ + NONE_WK_CID, + STA_MSTATUS_RPT_WK_CID, + DYNAMIC_CHK_WK_CID, + DM_CTRL_WK_CID, + PBC_POLLING_WK_CID, + POWER_SAVING_CTRL_WK_CID,//IPS,AUTOSuspend + LPS_CTRL_WK_CID, + ANT_SELECT_WK_CID, + P2P_PS_WK_CID, + P2P_PROTO_WK_CID, + CHECK_HIQ_WK_CID,//for softap mode, check hi queue if empty + INTEl_WIDI_WK_CID, + C2H_WK_CID, + RTP_TIMER_CFG_WK_CID, + RESET_SECURITYPRIV, // add for CONFIG_IEEE80211W, none 11w also can use + FREE_ASSOC_RESOURCES, // add for CONFIG_IEEE80211W, none 11w also can use + DM_IN_LPS_WK_CID, + DM_RA_MSK_WK_CID, //add for STA update RAMask when bandwith change. + BEAMFORMING_WK_CID, + LPS_CHANGE_DTIM_CID, + BTINFO_WK_CID, + DFS_MASTER_WK_CID, + SESSION_TRACKER_WK_CID, + EN_HW_UPDATE_TSF_WK_CID, + MAX_WK_CID +}; + +enum LPS_CTRL_TYPE +{ + LPS_CTRL_SCAN=0, + LPS_CTRL_JOINBSS=1, + LPS_CTRL_CONNECT=2, + LPS_CTRL_DISCONNECT=3, + 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, + LPS_CTRL_LEAVE_CFG80211_PWRMGMT = 10, +}; + +enum STAKEY_TYPE +{ + GROUP_KEY =0, + UNICAST_KEY =1, + TDLS_KEY =2, +}; + +enum RFINTFS { + SWSI, + HWSI, + HWPI, +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To enter USB suspend mode + +Command Mode + +*/ +struct usb_suspend_parm { + u32 action;// 1: sleep, 0:resume +}; + +/* +Caller Mode: Infra, Ad-HoC + +Notes: To join a known BSS. + +Command-Event Mode + +*/ + +/* +Caller Mode: Infra, Ad-Hoc + +Notes: To join the specified bss + +Command Event Mode + +*/ +struct joinbss_parm { + WLAN_BSSID_EX network; +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To disconnect the current associated BSS + +Command Mode + +*/ +struct disconnect_parm { + u32 deauth_timeout_ms; +}; + +/* +Caller Mode: AP, Ad-HoC(M) + +Notes: To create a BSS + +Command Mode +*/ +struct createbss_parm { + bool adhoc; + + /* used by AP mode now */ + s16 req_ch; + u8 req_bw; + u8 req_offset; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To set the NIC mode of RTL8711 + +Command Mode + +The definition of mode: + +#define IW_MODE_AUTO 0 // Let the driver decides which AP to join +#define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients) +#define IW_MODE_INFRA 2 // Multi cell network, roaming, .. +#define IW_MODE_MASTER 3 // Synchronisation master or Access Point +#define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder) +#define IW_MODE_SECOND 5 // Secondary master/repeater (backup) +#define IW_MODE_MONITOR 6 // Passive monitor (listen only) + +*/ +struct setopmode_parm { + u8 mode; + u8 rsvd[3]; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To ask RTL8711 performing site-survey + +Command-Event Mode + +*/ + +#define RTW_SSID_SCAN_AMOUNT 9 // for WEXT_CSCAN_AMOUNT 9 +#define RTW_CHANNEL_SCAN_AMOUNT (14+37) +struct sitesurvey_parm { + sint scan_mode; //active: 1, passive: 0 + /* sint bsslimit; // 1 ~ 48 */ + u8 ssid_num; + u8 ch_num; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; +}; + +/* +Caller Mode: Any + +Notes: To set the auth type of RTL8711. open/shared/802.1x + +Command Mode + +*/ +struct setauth_parm { + u8 mode; //0: legacy open, 1: legacy shared 2: 802.1x + u8 _1x; //0: PSK, 1: TLS + u8 rsvd[2]; +}; + +/* +Caller Mode: Infra + +a. algorithm: wep40, wep104, tkip & aes +b. keytype: grp key/unicast key +c. key contents + +when shared key ==> keyid is the camid +when 802.1x ==> keyid [0:1] ==> grp key +when 802.1x ==> keyid > 2 ==> unicast key + +*/ +struct setkey_parm { + u8 algorithm; // encryption algorithm, could be none, wep40, TKIP, CCMP, wep104 + u8 keyid; + u8 grpkey; // 1: this is the grpkey for 802.1x. 0: this is the unicast key for 802.1x + u8 set_tx; // 1: main tx key for wep. 0: other key. + u8 key[16]; // this could be 40 or 104 +}; + +/* +When in AP or Ad-Hoc mode, this is used to +allocate an sw/hw entry for a newly associated sta. + +Command + +when shared key ==> algorithm/keyid + +*/ +struct set_stakey_parm { + u8 addr[ETH_ALEN]; + u8 algorithm; + u8 keyid; + u8 key[16]; +}; + +struct set_stakey_rsp { + u8 addr[ETH_ALEN]; + u8 keyid; + u8 rsvd; +}; + +/* +Caller Ad-Hoc/AP + +Command -Rsp(AID == CAMID) mode + +This is to force fw to add an sta_data entry per driver's request. + +FW will write an cam entry associated with it. + +*/ +struct set_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +struct set_assocsta_rsp { + u8 cam_id; + u8 rsvd[3]; +}; + +/* + Caller Ad-Hoc/AP + + Command mode + + This is to force fw to del an sta_data entry per driver's request + + FW will invalidate the cam entry associated with it. + +*/ +struct del_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +/* +Caller Mode: AP/Ad-HoC(M) + +Notes: To notify fw that given staid has changed its power state + +Command Mode + +*/ +struct setstapwrstate_parm { + u8 staid; + u8 status; + u8 hwaddr[6]; +}; + +/* +Caller Mode: Any + +Notes: To setup the basic rate of RTL8711 + +Command Mode + +*/ +struct setbasicrate_parm { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To read the current basic rate + +Command-Rsp Mode + +*/ +struct getbasicrate_parm { + u32 rsvd; +}; + +struct getbasicrate_rsp { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To setup the data rate of RTL8711 + +Command Mode + +*/ +struct setdatarate_parm { +#ifdef MP_FIRMWARE_OFFLOAD + u32 curr_rateidx; +#else + u8 mac_id; + u8 datarates[NumRates]; +#endif +}; + +/* +Caller Mode: Any + +Notes: To read the current data rate + +Command-Rsp Mode + +*/ +struct getdatarate_parm { + u32 rsvd; + +}; +struct getdatarate_rsp { + u8 datarates[NumRates]; +}; + + +/* +Caller Mode: Any +AP: AP can use the info for the contents of beacon frame +Infra: STA can use the info when sitesurveying +Ad-HoC(M): Like AP +Ad-HoC(C): Like STA + + +Notes: To set the phy capability of the NIC + +Command Mode + +*/ + +struct setphyinfo_parm { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +struct getphyinfo_parm { + u32 rsvd; +}; + +struct getphyinfo_rsp { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +/* +Caller Mode: Any + +Notes: To set the channel/modem/band +This command will be used when channel/modem/band is changed. + +Command Mode + +*/ +struct setphy_parm { + u8 rfchannel; + u8 modem; +}; + +/* +Caller Mode: Any + +Notes: To get the current setting of channel/modem/band + +Command-Rsp Mode + +*/ +struct getphy_parm { + u32 rsvd; + +}; +struct getphy_rsp { + u8 rfchannel; + u8 modem; +}; + +struct readBB_parm { + u8 offset; +}; +struct readBB_rsp { + u8 value; +}; + +struct readTSSI_parm { + u8 offset; +}; +struct readTSSI_rsp { + u8 value; +}; + +struct readMAC_parm { + u8 len; + u32 addr; +}; + +struct writeBB_parm { + u8 offset; + u8 value; +}; + +struct readRF_parm { + u8 offset; +}; +struct readRF_rsp { + u32 value; +}; + +struct writeRF_parm { + u32 offset; + u32 value; +}; + +struct getrfintfs_parm { + u8 rfintfs; +}; + + +struct Tx_Beacon_param +{ + WLAN_BSSID_EX network; +}; + +/* + Notes: This command is used for H2C/C2H loopback testing + + mac[0] == 0 + ==> CMD mode, return H2C_SUCCESS. + The following condition must be ture under CMD mode + mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; + s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; + s2 == (b1 << 8 | b0); + + mac[0] == 1 + ==> CMD_RSP mode, return H2C_SUCCESS_RSP + + The rsp layout shall be: + rsp: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = mac[3]; + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = s1; + s1 = swap16(s0); + w0 = swap32(w1); + b0 = b1 + s2 = s0 + s1 + b1 = b0 + w1 = w0 + + mac[0] == 2 + ==> CMD_EVENT mode, return H2C_SUCCESS + The event layout shall be: + event: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = event's sequence number, starting from 1 to parm's marc[3] + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = swap16(s0) - event.mac[2]; + s1 = s1 + event.mac[2]; + w0 = swap32(w0); + b0 = b1 + s2 = s0 + event.mac[2] + b1 = b0 + w1 = swap32(w1) - event.mac[2]; + + parm->mac[3] is the total event counts that host requested. + + + event will be the same with the cmd's param. + +*/ + +#ifdef CONFIG_H2CLBK + +struct seth2clbk_parm { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +struct geth2clbk_parm { + u32 rsv; +}; + +struct geth2clbk_rsp { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +#endif /* CONFIG_H2CLBK */ + +// CMD param Formart for driver extra cmd handler +struct drvextra_cmd_parm { + int ec_id; //extra cmd id + int type; // Can use this field as the type id or command size + int size; //buffer size + unsigned char *pbuf; +}; + +/*------------------- Below are used for RF/BB tunning ---------------------*/ + +struct setantenna_parm { + u8 tx_antset; + u8 rx_antset; + u8 tx_antenna; + u8 rx_antenna; +}; + +struct enrateadaptive_parm { + u32 en; +}; + +struct settxagctbl_parm { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct gettxagctbl_parm { + u32 rsvd; +}; +struct gettxagctbl_rsp { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct setagcctrl_parm { + u32 agcctrl; // 0: pure hw, 1: fw +}; + + +struct setssup_parm { + u32 ss_ForceUp[MAX_RATES_LENGTH]; +}; + +struct getssup_parm { + u32 rsvd; +}; +struct getssup_rsp { + u8 ss_ForceUp[MAX_RATES_LENGTH]; +}; + + +struct setssdlevel_parm { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct getssdlevel_parm { + u32 rsvd; +}; +struct getssdlevel_rsp { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct setssulevel_parm { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + +struct getssulevel_parm { + u32 rsvd; +}; +struct getssulevel_rsp { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + + +struct setcountjudge_parm { + u8 count_judge[MAX_RATES_LENGTH]; +}; + +struct getcountjudge_parm { + u32 rsvd; +}; +struct getcountjudge_rsp { + u8 count_judge[MAX_RATES_LENGTH]; +}; + + +struct setratable_parm { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + +struct getratable_parm { + uint rsvd; +}; +struct getratable_rsp { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + + +//to get TX,RX retry count +struct gettxretrycnt_parm{ + unsigned int rsvd; +}; +struct gettxretrycnt_rsp{ + unsigned long tx_retrycnt; +}; + +struct getrxretrycnt_parm{ + unsigned int rsvd; +}; +struct getrxretrycnt_rsp{ + unsigned long rx_retrycnt; +}; + +//to get BCNOK,BCNERR count +struct getbcnokcnt_parm{ + unsigned int rsvd; +}; +struct getbcnokcnt_rsp{ + unsigned long bcnokcnt; +}; + +struct getbcnerrcnt_parm{ + unsigned int rsvd; +}; +struct getbcnerrcnt_rsp{ + unsigned long bcnerrcnt; +}; + +// to get current TX power level +struct getcurtxpwrlevel_parm{ + unsigned int rsvd; +}; +struct getcurtxpwrlevel_rsp{ + unsigned short tx_power; +}; + +struct setprobereqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocreqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setproberspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocrspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + + +struct addBaReq_parm +{ + unsigned int tid; + u8 addr[ETH_ALEN]; +}; + +/*H2C Handler index: 46 */ +struct set_ch_parm { + u8 ch; + u8 bw; + u8 ch_offset; +}; + +#ifdef MP_FIRMWARE_OFFLOAD +/*H2C Handler index: 47 */ +struct SetTxPower_parm +{ + u8 TxPower; +}; + +/*H2C Handler index: 48 */ +struct SwitchAntenna_parm +{ + u16 antenna_tx; + u16 antenna_rx; +// R_ANTENNA_SELECT_CCK cck_txrx; + u8 cck_txrx; +}; + +/*H2C Handler index: 49 */ +struct SetCrystalCap_parm +{ + u32 curr_crystalcap; +}; + +/*H2C Handler index: 50 */ +struct SetSingleCarrierTx_parm +{ + u8 bStart; +}; + +/*H2C Handler index: 51 */ +struct SetSingleToneTx_parm +{ + u8 bStart; + u8 curr_rfpath; +}; + +/*H2C Handler index: 52 */ +struct SetCarrierSuppressionTx_parm +{ + u8 bStart; + u32 curr_rateidx; +}; + +/*H2C Handler index: 53 */ +struct SetContinuousTx_parm +{ + u8 bStart; + u8 CCK_flag; /*1:CCK 2:OFDM*/ + u32 curr_rateidx; +}; + +/*H2C Handler index: 54 */ +struct SwitchBandwidth_parm +{ + u8 curr_bandwidth; +}; + +#endif /* MP_FIRMWARE_OFFLOAD */ + +/*H2C Handler index: 59 */ +struct SetChannelPlan_param +{ + const struct country_chplan *country_ent; + u8 channel_plan; +}; + +/*H2C Handler index: 60 */ +struct LedBlink_param +{ + PVOID pLed; +}; + +/*H2C Handler index: 61 */ +struct SetChannelSwitch_param +{ + u8 new_ch_no; +}; + +/*H2C Handler index: 62 */ +struct TDLSoption_param +{ + u8 addr[ETH_ALEN]; + u8 option; +}; + +/*H2C Handler index: 64 */ +struct RunInThread_param +{ + void (*func)(void*); + void *context; +}; + + +#define GEN_CMD_CODE(cmd) cmd ## _CMD_ + + +/* + +Result: +0x00: success +0x01: sucess, and check Response. +0x02: cmd ignored due to duplicated sequcne number +0x03: cmd dropped due to invalid cmd code +0x04: reserved. + +*/ + +#define H2C_RSP_OFFSET 512 + +#define H2C_SUCCESS 0x00 +#define H2C_SUCCESS_RSP 0x01 +#define H2C_DUPLICATED 0x02 +#define H2C_DROPPED 0x03 +#define H2C_PARAMETERS_ERROR 0x04 +#define H2C_REJECTED 0x05 +#define H2C_CMD_OVERFLOW 0x06 +#define H2C_RESERVED 0x07 +#define H2C_ENQ_HEAD 0x08 +#define H2C_ENQ_HEAD_FAIL 0x09 + +extern u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr); +extern u8 rtw_setstandby_cmd(_adapter *padapter, uint action); +u8 rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *ssid, int ssid_num, struct rtw_ieee80211_channel *ch, int ch_num); + +u8 rtw_create_ibss_cmd(_adapter *adapter, int flags); +u8 rtw_startbss_cmd(_adapter *adapter, int flags); +u8 rtw_change_bss_chbw_cmd(_adapter *adapter, int flags, u8 req_ch, u8 req_bw, u8 req_offset); + +extern u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch); + +struct sta_info; +extern u8 rtw_setstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 key_type, bool enqueue); +extern u8 rtw_clearstakey_cmd(_adapter *padapter, struct sta_info *sta, u8 enqueue); + +extern u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork); +u8 rtw_disassoc_cmd(_adapter *padapter, u32 deauth_timeout_ms, bool enqueue); +extern u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue); +extern u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_getmacreg_cmd(_adapter *padapter, u8 len, u32 addr); +extern void rtw_usb_catc_trigger_cmd(_adapter *padapter, const char *caller); +extern u8 rtw_setbbreg_cmd(_adapter * padapter, u8 offset, u8 val); +extern u8 rtw_setrfreg_cmd(_adapter * padapter, u8 offset, u32 val); +extern u8 rtw_getbbreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_getrfreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_setrfintfs_cmd(_adapter *padapter, u8 mode); +extern u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table); +extern u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval); + +extern u8 rtw_gettssi_cmd(_adapter *padapter, u8 offset,u8 *pval); +extern u8 rtw_setfwdig_cmd(_adapter*padapter, u8 type); +extern u8 rtw_setfwra_cmd(_adapter*padapter, u8 type); + +extern u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr); +// add for CONFIG_IEEE80211W, none 11w also can use +extern u8 rtw_reset_securitypriv_cmd(_adapter*padapter); +extern u8 rtw_free_assoc_resources_cmd(_adapter *padapter); +extern u8 rtw_dynamic_chk_wk_cmd(_adapter *adapter); + +u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue); +u8 rtw_dm_in_lps_wk_cmd(_adapter*padapter); +u8 rtw_lps_change_dtim_cmd(_adapter*padapter, u8 dtim); + +#if (RATE_ADAPTIVE_SUPPORT==1) +u8 rtw_rpt_timer_cfg_cmd(_adapter*padapter, u16 minRptTime); +#endif + +#ifdef CONFIG_ANTENNA_DIVERSITY +extern u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue); +#endif + +u8 rtw_dm_ra_mask_wk_cmd(_adapter*padapter, u8 *psta); + +extern u8 rtw_ps_cmd(_adapter*padapter); + +#ifdef CONFIG_AP_MODE +u8 rtw_chk_hi_queue_cmd(_adapter*padapter); +#ifdef CONFIG_DFS_MASTER +u8 rtw_dfs_master_cmd(_adapter *adapter, bool enqueue); +void rtw_dfs_master_timer_hdl(RTW_TIMER_HDL_ARGS); +void rtw_dfs_master_enable(_adapter *adapter, u8 ch, u8 bw, u8 offset); +void rtw_dfs_master_disable(_adapter *adapter, bool ld_sta_in_dfs); +enum { + MLME_STA_CONNECTING, + MLME_STA_CONNECTED, + MLME_STA_DISCONNECTED, + MLME_AP_STARTED, + MLME_AP_STOPPED, +}; +void rtw_dfs_master_status_apply(_adapter *adapter, u8 self_action); +#endif /* CONFIG_DFS_MASTER */ +#endif /* CONFIG_AP_MODE */ + +#ifdef CONFIG_BT_COEXIST +u8 rtw_btinfo_cmd(PADAPTER padapter, u8 *pbuf, u16 length); +#endif + +u8 rtw_enable_hw_update_tsf_cmd(_adapter *padapter); + +u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue); + +u8 rtw_set_chplan_cmd(_adapter *adapter, int flags, u8 chplan, u8 swconfig); +u8 rtw_set_country_cmd(_adapter *adapter, int flags, const char *country_code, u8 swconfig); + +extern u8 rtw_led_blink_cmd(_adapter*padapter, PVOID pLed); +extern u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no); +extern u8 rtw_tdls_cmd(_adapter*padapter, u8 *addr, u8 option); + +//#ifdef CONFIG_C2H_PACKET_EN +extern u8 rtw_c2h_packet_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length); +//#else +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 session_tracker_chk_cmd(_adapter *adapter, struct sta_info *sta); +u8 session_tracker_add_cmd(_adapter *adapter, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); +u8 session_tracker_del_cmd(_adapter *adapter, struct sta_info *sta, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); + +u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf); + +extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +void rtw_create_ibss_post_hdl(_adapter *padapter, int status); +extern void rtw_getbbrfreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); + +extern void rtw_setstaKey_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_setassocsta_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getrttbl_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getmacreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); + + +struct _cmd_callback { + u32 cmd_code; + void (*callback)(_adapter *padapter, struct cmd_obj *cmd); +}; + +enum rtw_h2c_cmd +{ + GEN_CMD_CODE(_Read_MACREG) , /*0*/ + GEN_CMD_CODE(_Write_MACREG) , + GEN_CMD_CODE(_Read_BBREG) , + GEN_CMD_CODE(_Write_BBREG) , + GEN_CMD_CODE(_Read_RFREG) , + GEN_CMD_CODE(_Write_RFREG) , /*5*/ + GEN_CMD_CODE(_Read_EEPROM) , + GEN_CMD_CODE(_Write_EEPROM) , + GEN_CMD_CODE(_Read_EFUSE) , + GEN_CMD_CODE(_Write_EFUSE) , + + GEN_CMD_CODE(_Read_CAM) , /*10*/ + GEN_CMD_CODE(_Write_CAM) , + GEN_CMD_CODE(_setBCNITV), + GEN_CMD_CODE(_setMBIDCFG), + GEN_CMD_CODE(_JoinBss), /*14*/ + GEN_CMD_CODE(_DisConnect) , /*15*/ + GEN_CMD_CODE(_CreateBss) , + GEN_CMD_CODE(_SetOpMode) , + GEN_CMD_CODE(_SiteSurvey), /*18*/ + GEN_CMD_CODE(_SetAuth) , + + GEN_CMD_CODE(_SetKey) , /*20*/ + GEN_CMD_CODE(_SetStaKey) , + GEN_CMD_CODE(_SetAssocSta) , + GEN_CMD_CODE(_DelAssocSta) , + GEN_CMD_CODE(_SetStaPwrState) , + GEN_CMD_CODE(_SetBasicRate) , /*25*/ + GEN_CMD_CODE(_GetBasicRate) , + GEN_CMD_CODE(_SetDataRate) , + GEN_CMD_CODE(_GetDataRate) , + GEN_CMD_CODE(_SetPhyInfo) , + + GEN_CMD_CODE(_GetPhyInfo) , /*30*/ + GEN_CMD_CODE(_SetPhy) , + GEN_CMD_CODE(_GetPhy) , + GEN_CMD_CODE(_readRssi) , + GEN_CMD_CODE(_readGain) , + GEN_CMD_CODE(_SetAtim) , /*35*/ + GEN_CMD_CODE(_SetPwrMode) , + GEN_CMD_CODE(_JoinbssRpt), + GEN_CMD_CODE(_SetRaTable) , + GEN_CMD_CODE(_GetRaTable) , + + GEN_CMD_CODE(_GetCCXReport), /*40*/ + GEN_CMD_CODE(_GetDTMReport), + GEN_CMD_CODE(_GetTXRateStatistics), + GEN_CMD_CODE(_SetUsbSuspend), + GEN_CMD_CODE(_SetH2cLbk), + GEN_CMD_CODE(_AddBAReq) , /*45*/ + GEN_CMD_CODE(_SetChannel), /*46*/ + GEN_CMD_CODE(_SetTxPower), + GEN_CMD_CODE(_SwitchAntenna), + GEN_CMD_CODE(_SetCrystalCap), + GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ + + GEN_CMD_CODE(_SetSingleToneTx),/*51*/ + GEN_CMD_CODE(_SetCarrierSuppressionTx), + GEN_CMD_CODE(_SetContinuousTx), + GEN_CMD_CODE(_SwitchBandwidth), /*54*/ + GEN_CMD_CODE(_TX_Beacon), /*55*/ + + GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ + GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ + GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ + + GEN_CMD_CODE(_SetChannelPlan), /*59*/ + GEN_CMD_CODE(_LedBlink), /*60*/ + + GEN_CMD_CODE(_SetChannelSwitch), /*61*/ + GEN_CMD_CODE(_TDLS), /*62*/ + GEN_CMD_CODE(_ChkBMCSleepq), /*63*/ + + GEN_CMD_CODE(_RunInThreadCMD), /*64*/ + + MAX_H2CCMD +}; + +#define _GetMACReg_CMD_ _Read_MACREG_CMD_ +#define _SetMACReg_CMD_ _Write_MACREG_CMD_ +#define _GetBBReg_CMD_ _Read_BBREG_CMD_ +#define _SetBBReg_CMD_ _Write_BBREG_CMD_ +#define _GetRFReg_CMD_ _Read_RFREG_CMD_ +#define _SetRFReg_CMD_ _Write_RFREG_CMD_ + +#ifdef _RTW_CMD_C_ +struct _cmd_callback rtw_cmd_callback[] = +{ + {GEN_CMD_CODE(_Read_MACREG), &rtw_getmacreg_cmdrsp_callback}, /*0*/ + {GEN_CMD_CODE(_Write_MACREG), NULL}, + {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Write_BBREG), NULL}, + {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ + {GEN_CMD_CODE(_Read_EEPROM), NULL}, + {GEN_CMD_CODE(_Write_EEPROM), NULL}, + {GEN_CMD_CODE(_Read_EFUSE), NULL}, + {GEN_CMD_CODE(_Write_EFUSE), NULL}, + + {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ + {GEN_CMD_CODE(_Write_CAM), NULL}, + {GEN_CMD_CODE(_setBCNITV), NULL}, + {GEN_CMD_CODE(_setMBIDCFG), NULL}, + {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ + {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ + {GEN_CMD_CODE(_CreateBss), NULL}, + {GEN_CMD_CODE(_SetOpMode), NULL}, + {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ + {GEN_CMD_CODE(_SetAuth), NULL}, + + {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ + {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, + {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, + {GEN_CMD_CODE(_DelAssocSta), NULL}, + {GEN_CMD_CODE(_SetStaPwrState), NULL}, + {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ + {GEN_CMD_CODE(_GetBasicRate), NULL}, + {GEN_CMD_CODE(_SetDataRate), NULL}, + {GEN_CMD_CODE(_GetDataRate), NULL}, + {GEN_CMD_CODE(_SetPhyInfo), NULL}, + + {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ + {GEN_CMD_CODE(_SetPhy), NULL}, + {GEN_CMD_CODE(_GetPhy), NULL}, + {GEN_CMD_CODE(_readRssi), NULL}, + {GEN_CMD_CODE(_readGain), NULL}, + {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ + {GEN_CMD_CODE(_SetPwrMode), NULL}, + {GEN_CMD_CODE(_JoinbssRpt), NULL}, + {GEN_CMD_CODE(_SetRaTable), NULL}, + {GEN_CMD_CODE(_GetRaTable) , NULL}, + + {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ + {GEN_CMD_CODE(_GetDTMReport), NULL}, + {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, + {GEN_CMD_CODE(_SetUsbSuspend), NULL}, + {GEN_CMD_CODE(_SetH2cLbk), NULL}, + {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ + {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ + {GEN_CMD_CODE(_SetTxPower), NULL}, + {GEN_CMD_CODE(_SwitchAntenna), NULL}, + {GEN_CMD_CODE(_SetCrystalCap), NULL}, + {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ + + {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ + {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, + {GEN_CMD_CODE(_SetContinuousTx), NULL}, + {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ + {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ + + {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ + {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ + {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ + {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ + {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ + + {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 + +#define CMD_FMT "cmd=%d,%d,%d" +#define CMD_ARG(cmd) \ + (cmd)->cmdcode, \ + (cmd)->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->ec_id : ((cmd)->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT) ? ((struct C2HEvent_Header *)(cmd)->parmbuf)->ID : 0), \ + (cmd)->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) ? ((struct drvextra_cmd_parm *)(cmd)->parmbuf)->type : 0 + +#endif // _CMD_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_debug.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_debug.h new file mode 100644 index 00000000..50ce08f7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_debug.h @@ -0,0 +1,538 @@ +/****************************************************************************** + * + * 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 __RTW_DEBUG_H__ +#define __RTW_DEBUG_H__ + + +#define _drv_always_ 1 +#define _drv_emerg_ 2 +#define _drv_alert_ 3 +#define _drv_crit_ 4 +#define _drv_err_ 5 +#define _drv_warning_ 6 +#define _drv_notice_ 7 +#define _drv_info_ 8 +#define _drv_dump_ 9 +#define _drv_debug_ 10 + + +#define _module_rtl871x_xmit_c_ BIT(0) +#define _module_xmit_osdep_c_ BIT(1) +#define _module_rtl871x_recv_c_ BIT(2) +#define _module_recv_osdep_c_ BIT(3) +#define _module_rtl871x_mlme_c_ BIT(4) +#define _module_mlme_osdep_c_ BIT(5) +#define _module_rtl871x_sta_mgt_c_ BIT(6) +#define _module_rtl871x_cmd_c_ BIT(7) +#define _module_cmd_osdep_c_ BIT(8) +#define _module_rtl871x_io_c_ BIT(9) +#define _module_io_osdep_c_ BIT(10) +#define _module_os_intfs_c_ BIT(11) +#define _module_rtl871x_security_c_ BIT(12) +#define _module_rtl871x_eeprom_c_ BIT(13) +#define _module_hal_init_c_ BIT(14) +#define _module_hci_hal_init_c_ BIT(15) +#define _module_rtl871x_ioctl_c_ BIT(16) +#define _module_rtl871x_ioctl_set_c_ BIT(17) +#define _module_rtl871x_ioctl_query_c_ BIT(18) +#define _module_rtl871x_pwrctrl_c_ BIT(19) +#define _module_hci_intfs_c_ BIT(20) +#define _module_hci_ops_c_ BIT(21) +#define _module_osdep_service_c_ BIT(22) +#define _module_mp_ BIT(23) +#define _module_hci_ops_os_c_ BIT(24) +#define _module_rtl871x_ioctl_os_c BIT(25) +#define _module_rtl8712_cmd_c_ BIT(26) +//#define _module_efuse_ BIT(27) +#define _module_rtl8192c_xmit_c_ BIT(28) +#define _module_hal_xmit_c_ BIT(28) +#define _module_efuse_ BIT(29) +#define _module_rtl8712_recv_c_ BIT(30) +#define _module_rtl8712_led_c_ BIT(31) + +#undef _MODULE_DEFINE_ + +#if defined _RTW_XMIT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_ +#elif defined _XMIT_OSDEP_C_ + #define _MODULE_DEFINE_ _module_xmit_osdep_c_ +#elif defined _RTW_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl871x_recv_c_ +#elif defined _RECV_OSDEP_C_ + #define _MODULE_DEFINE_ _module_recv_osdep_c_ +#elif defined _RTW_MLME_C_ + #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_ +#elif defined _MLME_OSDEP_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MLME_EXT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTW_STA_MGT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_ +#elif defined _RTW_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_ +#elif defined _CMD_OSDEP_C_ + #define _MODULE_DEFINE_ _module_cmd_osdep_c_ +#elif defined _RTW_IO_C_ + #define _MODULE_DEFINE_ _module_rtl871x_io_c_ +#elif defined _IO_OSDEP_C_ + #define _MODULE_DEFINE_ _module_io_osdep_c_ +#elif defined _OS_INTFS_C_ + #define _MODULE_DEFINE_ _module_os_intfs_c_ +#elif defined _RTW_SECURITY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_security_c_ +#elif defined _RTW_EEPROM_C_ + #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_ +#elif defined _HAL_INTF_C_ + #define _MODULE_DEFINE_ _module_hal_init_c_ +#elif (defined _HCI_HAL_INIT_C_) || (defined _SDIO_HALINIT_C_) + #define _MODULE_DEFINE_ _module_hci_hal_init_c_ +#elif defined _RTL871X_IOCTL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_ +#elif defined _RTL871X_IOCTL_SET_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_ +#elif defined _RTL871X_IOCTL_QUERY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_query_c_ +#elif defined _RTL871X_PWRCTRL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_ +#elif defined _RTW_PWRCTRL_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _HCI_OPS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_c_ +#elif defined _SDIO_OPS_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _OSDEP_HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _OSDEP_SERVICE_C_ + #define _MODULE_DEFINE_ _module_osdep_service_c_ +#elif defined _HCI_OPS_OS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_os_c_ +#elif defined _RTL871X_IOCTL_LINUX_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c +#elif defined _RTL8712_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_ +#elif defined _RTL8192C_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8723AS_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8712_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL8192CU_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL871X_MLME_EXT_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MP_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_MP_IOCTL_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_EFUSE_C_ + #define _MODULE_DEFINE_ _module_efuse_ +#endif + +#ifdef PLATFORM_OS_CE +extern void rtl871x_cedbg(const char *fmt, ...); +#endif + +#define RT_TRACE(_Comp, _Level, Fmt) do{}while(0) +#define _func_enter_ do{}while(0) +#define _func_exit_ do{}while(0) +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) do{}while(0) + +#ifdef PLATFORM_WINDOWS + #define DBG_871X do {} while(0) + #define MSG_8192C do {} while(0) + #define DBG_8192C do {} while(0) + #define DBG_871X_LEVEL do {} while(0) +#else + #define DBG_871X(x, ...) do {} while(0) + #define MSG_8192C(x, ...) do {} while(0) + #define DBG_8192C(x,...) do {} while(0) + #define DBG_871X_LEVEL(x,...) do {} while(0) +#endif + +#undef _dbgdump +#undef _seqdump + +#ifndef _RTL871X_DEBUG_C_ + extern u32 GlobalDebugLevel; + extern u64 GlobalDebugComponents; +#endif + +#if defined(PLATFORM_WINDOWS) && defined(PLATFORM_OS_XP) + #define _dbgdump DbgPrint + #define _seqdump(sel, fmt, arg...) _dbgdump(fmt, ##arg) +#elif defined(PLATFORM_WINDOWS) && defined(PLATFORM_OS_CE) + #define _dbgdump rtl871x_cedbg + #define _seqdump(sel, fmt, arg...) _dbgdump(fmt, ##arg) +#elif defined PLATFORM_LINUX + #define _dbgdump pr_debug + #define _seqdump seq_printf +#elif defined PLATFORM_FREEBSD + #define _dbgdump printf + #define _seqdump(sel, fmt, arg...) _dbgdump(fmt, ##arg) +#endif + +#define DRIVER_PREFIX "RTL871X: " + +#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...) \ + do {\ + if (level <= GlobalDebugLevel) {\ + if (level <= _drv_err_ && level > _drv_always_) \ + _dbgdump(DRIVER_PREFIX"ERROR " fmt, ##arg);\ + else \ + _dbgdump(DRIVER_PREFIX fmt, ##arg);\ + }\ + }while(0) + +/* without driver-defined prefix */ +#undef _DBG_871X_LEVEL +#define _DBG_871X_LEVEL(level, fmt, arg...) \ + do {\ + if (level <= GlobalDebugLevel) {\ + if (level <= _drv_err_ && level > _drv_always_) \ + _dbgdump("ERROR " fmt, ##arg);\ + else \ + _dbgdump(fmt, ##arg);\ + }\ + }while(0) + +#if defined(_seqdump) +#define RTW_DBGDUMP 0 /* 'stream' for _dbgdump */ + +/* dump message to selected 'stream' */ +#define DBG_871X_SEL(sel, fmt, arg...) \ + do {\ + if (sel == RTW_DBGDUMP)\ + _DBG_871X_LEVEL(_drv_always_, fmt, ##arg); \ + else {\ + if(_seqdump(sel, fmt, ##arg)) /*rtw_warn_on(1)*/; \ + } \ + }while(0) + +/* dump message to selected 'stream' with driver-defined prefix */ +#define DBG_871X_SEL_NL(sel, fmt, arg...) \ + do {\ + if (sel == RTW_DBGDUMP)\ + DBG_871X_LEVEL(_drv_always_, fmt, ##arg); \ + else {\ + if(_seqdump(sel, fmt, ##arg)) /*rtw_warn_on(1)*/; \ + } \ + }while(0) + +#endif /* defined(_seqdump) */ + +#endif /* defined(_dbgdump) */ + +#ifdef CONFIG_DEBUG +#if defined(_dbgdump) + #undef DBG_871X + #define DBG_871X(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) + + #undef MSG_8192C + #define MSG_8192C(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) + + #undef DBG_8192C + #define DBG_8192C(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) +#endif /* defined(_dbgdump) */ +#endif /* CONFIG_DEBUG */ + +#ifdef CONFIG_DEBUG_RTL871X + +#if defined(_dbgdump) && defined(_MODULE_DEFINE_) + + #undef RT_TRACE + #define RT_TRACE(_Comp, _Level, Fmt)\ + do {\ + if((_Comp & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) {\ + _dbgdump("%s [0x%08x,%d]", DRIVER_PREFIX, (unsigned int)_Comp, _Level);\ + _dbgdump Fmt;\ + }\ + }while(0) + +#endif /* defined(_dbgdump) && defined(_MODULE_DEFINE_) */ + + +#if defined(_dbgdump) + #undef _func_enter_ + #define _func_enter_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s enters at %d\n", DRIVER_PREFIX, __FUNCTION__, __LINE__);\ + } \ + } while(0) + + #undef _func_exit_ + #define _func_exit_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s exits at %d\n", DRIVER_PREFIX, __FUNCTION__, __LINE__); \ + } \ + } while(0) + + #undef RT_PRINT_DATA + #define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \ + if(((_Comp) & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) \ + { \ + int __i; \ + u8 *ptr = (u8 *)_HexData; \ + _dbgdump("%s", DRIVER_PREFIX); \ + _dbgdump(_TitleString); \ + for( __i=0; __i<(int)_HexDataLen; __i++ ) \ + { \ + _dbgdump("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \ + if (((__i + 1) % 16) == 0) _dbgdump("\n"); \ + } \ + _dbgdump("\n"); \ + } +#endif /* defined(_dbgdump) */ +#endif /* CONFIG_DEBUG_RTL871X */ + +#ifdef CONFIG_DBG_COUNTER +#define DBG_COUNTER(counter) counter++ +#else +#define DBG_COUNTER(counter) +#endif + +void dump_drv_version(void *sel); +void dump_log_level(void *sel); +void dump_drv_cfg(void *sel); + +#ifdef CONFIG_SDIO_HCI +void sd_f0_reg_dump(void *sel, _adapter *adapter); +void sdio_local_reg_dump(void *sel, _adapter *adapter); +#endif /* CONFIG_SDIO_HCI */ + +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); +bool rtw_del_rx_ampdu_test_trigger_no_tx_fail(void); + +u32 rtw_get_wait_hiq_empty_ms(void); +void rtw_sink_rtp_seq_dbg( _adapter *adapter,_pkt *pkt); + +struct sta_info; +void sta_rx_reorder_ctl_dump(void *sel, struct sta_info *sta); + +struct dvobj_priv; +void dump_adapters_status(void *sel, struct dvobj_priv *dvobj); + +struct sec_cam_ent; +void dump_sec_cam_ent(void *sel, struct sec_cam_ent *ent, int id); +void dump_sec_cam_ent_title(void *sel, u8 has_id); +void dump_sec_cam(void *sel, _adapter *adapter); + +#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); +ssize_t proc_set_read_reg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_fwstate(struct seq_file *m, void *v); +int proc_get_sec_info(struct seq_file *m, void *v); +int proc_get_mlmext_state(struct seq_file *m, void *v); +#ifdef CONFIG_LAYER2_ROAMING +int proc_get_roam_flags(struct seq_file *m, void *v); +ssize_t proc_set_roam_flags(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_roam_param(struct seq_file *m, void *v); +ssize_t proc_set_roam_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +ssize_t proc_set_roam_tgt_addr(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_LAYER2_ROAMING */ +int proc_get_qos_option(struct seq_file *m, void *v); +int proc_get_ht_option(struct seq_file *m, void *v); +int proc_get_rf_info(struct seq_file *m, void *v); +int proc_get_scan_param(struct seq_file *m, void *v); +ssize_t proc_set_scan_param(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_scan_abort(struct seq_file *m, void *v); +#ifdef CONFIG_SCAN_BACKOP +int proc_get_backop_flags_sta(struct seq_file *m, void *v); +ssize_t proc_set_backop_flags_sta(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_backop_flags_ap(struct seq_file *m, void *v); +ssize_t proc_set_backop_flags_ap(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_SCAN_BACKOP */ +int proc_get_survey_info(struct seq_file *m, void *v); +ssize_t proc_set_survey_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_ap_info(struct seq_file *m, void *v); +ssize_t proc_reset_trx_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +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); +#ifdef DBG_RX_COUNTER_DUMP +int proc_get_rx_cnt_dump(struct seq_file *m, void *v); +ssize_t proc_set_rx_cnt_dump(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif +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); +ssize_t proc_set_del_rx_ampdu_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#ifdef CONFIG_DFS_MASTER +int proc_get_dfs_master_test_case(struct seq_file *m, void *v); +ssize_t proc_set_dfs_master_test_case(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_DFS_MASTER */ +ssize_t proc_set_wait_hiq_empty(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +#ifdef CONFIG_AP_MODE +int proc_get_all_sta_info(struct seq_file *m, void *v); +#endif /* CONFIG_AP_MODE */ + +#ifdef DBG_MEMORY_LEAK +int proc_get_malloc_cnt(struct seq_file *m, void *v); +#endif /* DBG_MEMORY_LEAK */ + +#ifdef CONFIG_FIND_BEST_CHANNEL +int proc_get_best_channel(struct seq_file *m, void *v); +ssize_t proc_set_best_channel(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* CONFIG_FIND_BEST_CHANNEL */ + +int proc_get_rx_signal(struct seq_file *m, void *v); +ssize_t proc_set_rx_signal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_hw_status(struct seq_file *m, void *v); + +#ifdef CONFIG_80211N_HT +int proc_get_ht_enable(struct seq_file *m, void *v); +ssize_t proc_set_ht_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_bw_mode(struct seq_file *m, void *v); +ssize_t proc_set_bw_mode(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_ampdu_enable(struct seq_file *m, void *v); +ssize_t proc_set_ampdu_enable(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_mac_rptbuf(struct seq_file *m, void *v); + +int proc_get_rx_ampdu(struct seq_file *m, void *v); +ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +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); + +#ifdef CONFIG_BT_COEXIST +int proc_get_btcoex_dbg(struct seq_file *m, void *v); +ssize_t proc_set_btcoex_dbg(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_btcoex_info(struct seq_file *m, void *v); +#endif /* CONFIG_BT_COEXIST */ + +#if defined(DBG_CONFIG_ERROR_DETECT) +int proc_get_sreset(struct seq_file *m, void *v); +ssize_t proc_set_sreset(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +#endif /* DBG_CONFIG_ERROR_DETECT */ + +int proc_get_odm_dbg_comp(struct seq_file *m, void *v); +ssize_t proc_set_odm_dbg_comp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_odm_dbg_level(struct seq_file *m, void *v); +ssize_t proc_set_odm_dbg_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +int proc_get_odm_adaptivity(struct seq_file *m, void *v); +ssize_t proc_set_odm_adaptivity(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +#ifdef CONFIG_DBG_COUNTER +int proc_get_rx_logs(struct seq_file *m, void *v); +int proc_get_tx_logs(struct seq_file *m, void *v); +int proc_get_int_logs(struct seq_file *m, void *v); +#endif + +#ifdef CONFIG_PCI_HCI +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_GPIO_WAKEUP +int proc_get_wowlan_gpio_info(struct seq_file *m, void *v); +ssize_t proc_set_wowlan_gpio_info(struct file *file, const char __user *buffer, + size_t count, loff_t *pos, void *data); +#endif /*CONFIG_GPIO_WAKEUP*/ + +#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); + +#ifdef CONFIG_POWER_SAVING +int proc_get_ps_info(struct seq_file *m, void *v); +#endif //CONFIG_POWER_SAVING + +#ifdef CONFIG_TDLS +int proc_get_tdls_info(struct seq_file *m, void *v); +#endif + +int proc_get_monitor(struct seq_file *m, void *v); +ssize_t proc_set_monitor(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + + +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER +int proc_get_rtkm_info(struct seq_file *m, void *v); +#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */ + +#ifdef CONFIG_IEEE80211W +ssize_t proc_set_tx_sa_query(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_tx_sa_query(struct seq_file *m, void *v); +ssize_t proc_set_tx_deauth(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_tx_deauth(struct seq_file *m, void *v); +ssize_t proc_set_tx_auth(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +int proc_get_tx_auth(struct seq_file *m, void *v); +#endif /* CONFIG_IEEE80211W */ + +#endif /* CONFIG_PROC_DEBUG */ + +int proc_get_efuse_map(struct seq_file *m, void *v); +ssize_t proc_set_efuse_map(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); + +#endif //__RTW_DEBUG_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_eeprom.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_eeprom.h new file mode 100644 index 00000000..2da2a67b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_eeprom.h @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * 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 __RTW_EEPROM_H__ +#define __RTW_EEPROM_H__ + + +#define RTL8712_EEPROM_ID 0x8712 +//#define EEPROM_MAX_SIZE 256 + +#define HWSET_MAX_SIZE_128 128 +#define HWSET_MAX_SIZE_256 256 +#define HWSET_MAX_SIZE_512 512 +#define HWSET_MAX_SIZE_1024 1024 + +#define EEPROM_MAX_SIZE HWSET_MAX_SIZE_1024 + +#define CLOCK_RATE 50 //100us + +//- EEPROM opcodes +#define EEPROM_READ_OPCODE 06 +#define EEPROM_WRITE_OPCODE 05 +#define EEPROM_ERASE_OPCODE 07 +#define EEPROM_EWEN_OPCODE 19 // Erase/write enable +#define EEPROM_EWDS_OPCODE 16 // Erase/write disable + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +// +// Customer ID, note that: +// This variable is initiailzed through EEPROM or registry, +// however, its definition may be different with that in EEPROM for +// EEPROM size consideration. So, we have to perform proper translation between them. +// Besides, CustomerID of registry has precedence of that of EEPROM. +// defined below. 060703, by rcnjko. +// +typedef enum _RT_CUSTOMER_ID +{ + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31. + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_CHINA_MOBILE = 15, + RT_CID_819x_ALPHA = 16, + RT_CID_819x_Sitecom = 17, + RT_CID_CCX = 18, // It's set under CCX logo test and isn't demanded for CCX functions, but for test behavior like retry limit and tx report. By Bruce, 2009-02-17. + RT_CID_819x_Lenovo = 19, + RT_CID_819x_QMI = 20, + RT_CID_819x_Edimax_Belkin = 21, + RT_CID_819x_Sercomm_Belkin = 22, + RT_CID_819x_CAMEO1 = 23, + RT_CID_819x_MSI = 24, + RT_CID_819x_Acer = 25, + RT_CID_819x_AzWave_ASUS = 26, + RT_CID_819x_AzWave = 27, // For AzWave in PCIe, The ID is AzWave use and not only Asus + RT_CID_819x_HP = 28, + RT_CID_819x_WNC_COREGA = 29, + RT_CID_819x_Arcadyan_Belkin = 30, + RT_CID_819x_SAMSUNG = 31, + RT_CID_819x_CLEVO = 32, + RT_CID_819x_DELL = 33, + RT_CID_819x_PRONETS = 34, + RT_CID_819x_Edimax_ASUS = 35, + RT_CID_NETGEAR = 36, + RT_CID_PLANEX = 37, + RT_CID_CC_C = 38, + RT_CID_819x_Xavi = 39, + RT_CID_LENOVO_CHINA = 40, + RT_CID_INTEL_CHINA = 41, + RT_CID_TPLINK_HPWR = 42, + RT_CID_819x_Sercomm_Netgear = 43, + RT_CID_819x_ALPHA_Dlink = 44,//add by ylb 20121012 for customer led for alpha + RT_CID_WNC_NEC = 45,//add by page for NEC + RT_CID_DNI_BUFFALO = 46,//add by page for NEC +}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; + +extern void eeprom_write16(_adapter *padapter, u16 reg, u16 data); +extern u16 eeprom_read16(_adapter *padapter, u16 reg); +extern void read_eeprom_content(_adapter *padapter); +extern void eeprom_read_sz(_adapter * padapter, u16 reg,u8* data, u32 sz); + +extern void read_eeprom_content_by_attrib(_adapter * padapter ); + +#ifdef PLATFORM_LINUX +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE +extern int isAdaptorInfoFileValid(void); +extern int storeAdaptorInfoFile(char *path, u8 *efuse_data); +extern int retriveAdaptorInfoFile(char *path, u8 *efuse_data); +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE +#endif //PLATFORM_LINUX + +#endif //__RTL871X_EEPROM_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_efuse.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_efuse.h new file mode 100644 index 00000000..828841fc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_efuse.h @@ -0,0 +1,216 @@ +/****************************************************************************** + * + * 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 __RTW_EFUSE_H__ +#define __RTW_EFUSE_H__ + + +#define EFUSE_ERROE_HANDLE 1 + +#define PG_STATE_HEADER 0x01 +#define PG_STATE_WORD_0 0x02 +#define PG_STATE_WORD_1 0x04 +#define PG_STATE_WORD_2 0x08 +#define PG_STATE_WORD_3 0x10 +#define PG_STATE_DATA 0x20 + +#define PG_SWBYTE_H 0x01 +#define PG_SWBYTE_L 0x02 + +#define PGPKT_DATA_SIZE 8 + +#define EFUSE_WIFI 0 +#define EFUSE_BT 1 + +enum _EFUSE_DEF_TYPE { + TYPE_EFUSE_MAX_SECTION = 0, + TYPE_EFUSE_REAL_CONTENT_LEN = 1, + TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, + TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, + TYPE_EFUSE_MAP_LEN = 4, + TYPE_EFUSE_PROTECT_BYTES_BANK = 5, + TYPE_EFUSE_CONTENT_LEN_BANK = 6, +}; + +#define EFUSE_MAX_MAP_LEN 512 + +#define EFUSE_MAX_HW_SIZE 512 +#define EFUSE_MAX_SECTION_BASE 16 + +#define EXT_HEADER(header) ((header & 0x1F ) == 0x0F) +#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) +#define GET_HDR_OFFSET_2_0(header) ( (header & 0xE0) >> 5) + +#define EFUSE_REPEAT_THRESHOLD_ 3 + +#define IS_MASKED_MP(ic, txt, offset) (EFUSE_IsAddressMasked_MP_##ic##txt(offset)) +#define IS_MASKED_TC(ic, txt, offset) (EFUSE_IsAddressMasked_TC_##ic##txt(offset)) +#define GET_MASK_ARRAY_LEN_MP(ic, txt) (EFUSE_GetArrayLen_MP_##ic##txt()) +#define GET_MASK_ARRAY_LEN_TC(ic, txt) (EFUSE_GetArrayLen_TC_##ic##txt()) +#define GET_MASK_ARRAY_MP(ic, txt, offset) (EFUSE_GetMaskArray_MP_##ic##txt(offset)) +#define GET_MASK_ARRAY_TC(ic, txt, offset) (EFUSE_GetMaskArray_TC_##ic##txt(offset)) + + +#define IS_MASKED(ic, txt, offset) ( IS_MASKED_MP(ic,txt, offset) ) +#define GET_MASK_ARRAY_LEN(ic, txt) ( GET_MASK_ARRAY_LEN_MP(ic,txt) ) +#define GET_MASK_ARRAY(ic, txt, out) do { GET_MASK_ARRAY_MP(ic,txt, out);} while(0) + +//============================================= +// The following is for BT Efuse definition +//============================================= +#define EFUSE_BT_MAX_MAP_LEN 1024 +#define EFUSE_MAX_BANK 4 +#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) +//============================================= +/*--------------------------Define Parameters-------------------------------*/ +#define EFUSE_MAX_WORD_UNIT 4 + +/*------------------------------Define structure----------------------------*/ +typedef struct PG_PKT_STRUCT_A{ + u8 offset; + u8 word_en; + u8 data[8]; + u8 word_cnts; +}PGPKT_STRUCT,*PPGPKT_STRUCT; + +typedef enum +{ + ERR_SUCCESS = 0, + ERR_DRIVER_FAILURE, + ERR_IO_FAILURE, + ERR_WI_TIMEOUT, + ERR_WI_BUSY, + ERR_BAD_FORMAT, + ERR_INVALID_DATA, + ERR_NOT_ENOUGH_SPACE, + ERR_WRITE_PROTECT, + ERR_READ_BACK_FAIL, + ERR_OUT_OF_RANGE +} ERROR_CODE; + +/*------------------------------Define structure----------------------------*/ +typedef struct _EFUSE_HAL{ + u8 fakeEfuseBank; + u32 fakeEfuseUsedBytes; + u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]; + u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]; + u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]; + u32 EfuseUsedBytes; + u8 EfuseUsedPercentage; + + u16 BTEfuseUsedBytes; + u8 BTEfuseUsedPercentage; + u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; + u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; + u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; + + u16 fakeBTEfuseUsedBytes; + u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; + u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; + u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; + + // EFUSE Configuration, initialized in HAL_CmnInitPGData(). + const u16 MaxSecNum_WiFi; + const u16 MaxSecNum_BT; + const u16 WordUnit; + const u16 PhysicalLen_WiFi; + const u16 PhysicalLen_BT; + const u16 LogicalLen_WiFi; + const u16 LogicalLen_BT; + const u16 BankSize; + const u16 TotalBankNum; + const u16 BankNum_WiFi; + const u16 BankNum_BT; + const u16 OOBProtectBytes; + const u16 ProtectBytes; + const u16 BankAvailBytes; + const u16 TotalAvailBytes_WiFi; + const u16 TotalAvailBytes_BT; + const u16 HeaderRetry; + const u16 DataRetry; + + ERROR_CODE Status; + +}EFUSE_HAL, *PEFUSE_HAL; + +extern u8 maskfileBuffer[32]; + +/*------------------------Export global variable----------------------------*/ +extern u8 fakeEfuseBank; +extern u32 fakeEfuseUsedBytes; +extern u8 fakeEfuseContent[]; +extern u8 fakeEfuseInitMap[]; +extern u8 fakeEfuseModifiedMap[]; + +extern u32 BTEfuseUsedBytes; +extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 BTEfuseInitMap[]; +extern u8 BTEfuseModifiedMap[]; + +extern u32 fakeBTEfuseUsedBytes; +extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 fakeBTEfuseInitMap[]; +extern u8 fakeBTEfuseModifiedMap[]; +/*------------------------Export global variable----------------------------*/ +u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size); +u16 efuse_bt_GetMaxSize(PADAPTER padapter); + +u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size); +u16 efuse_GetMaxSize(PADAPTER padapter); +u8 rtw_efuse_access(PADAPTER padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data); +u8 rtw_efuse_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); + +u16 Efuse_GetCurrentSize(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +u8 Efuse_CalculateWordCnts(u8 word_en); +void ReadEFuseByte(PADAPTER Adapter, u16 _offset, u8 *pbuf, BOOLEAN bPseudoTest) ; +void EFUSE_GetEfuseDefinition(PADAPTER pAdapter, u8 efuseType, u8 type, void *pOut, BOOLEAN bPseudoTest); +u8 efuse_OneByteRead(PADAPTER pAdapter, u16 addr, u8 *data, BOOLEAN bPseudoTest); +u8 efuse_OneByteWrite(PADAPTER pAdapter, u16 addr, u8 data, BOOLEAN bPseudoTest); + +void BTEfuse_PowerSwitch(PADAPTER pAdapter,u8 bWrite,u8 PwrState); +void Efuse_PowerSwitch(PADAPTER pAdapter,u8 bWrite,u8 PwrState); +int Efuse_PgPacketRead(PADAPTER pAdapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); +int Efuse_PgPacketWrite(PADAPTER pAdapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); +void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); +u8 Efuse_WordEnableDataWrite(PADAPTER pAdapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + +u8 EFUSE_Read1Byte(PADAPTER pAdapter, u16 Address); +void EFUSE_ShadowMapUpdate(PADAPTER pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +void EFUSE_ShadowRead(PADAPTER pAdapter, u8 Type, u16 Offset, u32 *Value); +u8 rtw_efuse_file_read(PADAPTER padapter,u8 *filepatch,u8 *buf, u32 len); + +#define MAC_HIDDEN_MAX_BW_NUM 8 +extern const u8 _mac_hidden_max_bw_to_hal_bw_cap[]; +#define mac_hidden_max_bw_to_hal_bw_cap(max_bw) (((max_bw) >= MAC_HIDDEN_MAX_BW_NUM) ? 0 : _mac_hidden_max_bw_to_hal_bw_cap[(max_bw)]) + +u8 mac_hidden_wl_func_to_hal_wl_func(u8 func); + +#ifdef PLATFORM_LINUX +#ifdef CONFIG_EFUSE_CONFIG_FILE +u32 rtw_read_efuse_from_file(const char *path, u8 *buf); +u32 rtw_read_macaddr_from_file(const char *path, u8 *buf); +#endif /* CONFIG_EFUSE_CONFIG_FILE */ +#endif /* PLATFORM_LINUX */ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_event.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_event.h new file mode 100644 index 00000000..b08b68d8 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_event.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * 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 _RTW_EVENT_H_ +#define _RTW_EVENT_H_ + +#ifdef CONFIG_H2CLBK +#include +#endif + +/* +Used to report a bss has been scanned + +*/ +struct survey_event { + WLAN_BSSID_EX bss; +}; + +/* +Used to report that the requested site survey has been done. + +bss_cnt indicates the number of bss that has been reported. + + +*/ +struct surveydone_event { + unsigned int bss_cnt; + +}; + +/* +Used to report the link result of joinning the given bss + + +join_res: +-1: authentication fail +-2: association fail +> 0: TID + +*/ +struct joinbss_event { + struct wlan_network network; +}; + +/* +Used to report a given STA has joinned the created BSS. +It is used in AP/Ad-HoC(M) mode. + + +*/ +struct stassoc_event { + unsigned char macaddr[6]; +}; + +struct stadel_event { + unsigned char macaddr[6]; + unsigned char rsvd[2]; //for reason + int mac_id; +}; + +struct addba_event +{ + unsigned int tid; +}; + +struct wmm_event +{ + unsigned char wmm; +}; + +#ifdef CONFIG_H2CLBK +struct c2hlbk_event{ + unsigned char mac[6]; + unsigned short s0; + unsigned short s1; + unsigned int w0; + unsigned char b0; + unsigned short s2; + unsigned char b1; + unsigned int w1; +}; +#endif//CONFIG_H2CLBK + +#define GEN_EVT_CODE(event) event ## _EVT_ + + + +struct fwevent { + u32 parmsize; + void (*event_callback)(_adapter *dev, u8 *pbuf); +}; + + +#define C2HEVENT_SZ 32 + +struct event_node{ + unsigned char *node; + unsigned char evt_code; + unsigned short evt_sz; + volatile int *caller_ff_tail; + int caller_ff_sz; +}; + +struct c2hevent_queue { + volatile int head; + volatile int tail; + struct event_node nodes[C2HEVENT_SZ]; + unsigned char seq; +}; + +#define NETWORK_QUEUE_SZ 4 + +struct network_queue { + volatile int head; + volatile int tail; + WLAN_BSSID_EX networks[NETWORK_QUEUE_SZ]; +}; + + +#endif // _WLANEVENT_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ht.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ht.h new file mode 100644 index 00000000..1509dba6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ht.h @@ -0,0 +1,221 @@ +/****************************************************************************** + * + * 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 _RTW_HT_H_ +#define _RTW_HT_H_ + + +struct ht_priv +{ + u8 ht_option; + u8 ampdu_enable;//for enable Tx A-MPDU + u8 tx_amsdu_enable;//for enable Tx A-MSDU + u8 bss_coexist;//for 20/40 Bss coexist + + //u8 baddbareq_issued[16]; + u32 tx_amsdu_maxlen; // 1: 8k, 0:4k ; default:8k, for tx + u32 rx_ampdu_maxlen; //for rx reordering ctrl win_sz, updated when join_callback. + + u8 rx_ampdu_min_spacing; + + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi_20m; + u8 sgi_40m; + + //for processing Tx A-MPDU + u8 agg_enable_bitmap; + //u8 ADDBA_retry_count; + u8 candidate_tid_bitmap; + + u8 ldpc_cap; + u8 stbc_cap; + u8 beamform_cap; + u8 smps_cap; /*spatial multiplexing power save mode. 0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/ + + struct rtw_ieee80211_ht_cap ht_cap; + +}; + +typedef enum AGGRE_SIZE{ + HT_AGG_SIZE_8K = 0, + HT_AGG_SIZE_16K = 1, + HT_AGG_SIZE_32K = 2, + HT_AGG_SIZE_64K = 3, + VHT_AGG_SIZE_128K = 4, + VHT_AGG_SIZE_256K = 5, + VHT_AGG_SIZE_512K = 6, + VHT_AGG_SIZE_1024K = 7, +}AGGRE_SIZE_E, *PAGGRE_SIZE_E; + +typedef enum _RT_HT_INF0_CAP{ + RT_HT_CAP_USE_TURBO_AGGR = 0x01, + RT_HT_CAP_USE_LONG_PREAMBLE = 0x02, + RT_HT_CAP_USE_AMPDU = 0x04, + RT_HT_CAP_USE_WOW = 0x8, + RT_HT_CAP_USE_SOFTAP = 0x10, + RT_HT_CAP_USE_92SE = 0x20, + RT_HT_CAP_USE_88C_92C = 0x40, + RT_HT_CAP_USE_AP_CLIENT_MODE = 0x80, // AP team request to reserve this bit, by Emily +}RT_HT_INF0_CAPBILITY, *PRT_HT_INF0_CAPBILITY; + +typedef enum _RT_HT_INF1_CAP{ + RT_HT_CAP_USE_VIDEO_CLIENT = 0x01, + RT_HT_CAP_USE_JAGUAR_BCUT = 0x02, + RT_HT_CAP_USE_JAGUAR_CCUT = 0x04, +}RT_HT_INF1_CAPBILITY, *PRT_HT_INF1_CAPBILITY; + +#define LDPC_HT_ENABLE_RX BIT0 +#define LDPC_HT_ENABLE_TX BIT1 +#define LDPC_HT_TEST_TX_ENABLE BIT2 +#define LDPC_HT_CAP_TX BIT3 + +#define STBC_HT_ENABLE_RX BIT0 +#define STBC_HT_ENABLE_TX BIT1 +#define STBC_HT_TEST_TX_ENABLE BIT2 +#define STBC_HT_CAP_TX BIT3 + +#define BEAMFORMING_HT_BEAMFORMER_ENABLE BIT0 // Declare our NIC supports beamformer +#define BEAMFORMING_HT_BEAMFORMEE_ENABLE BIT1 // Declare our NIC supports beamformee +#define BEAMFORMING_HT_BEAMFORMER_TEST BIT2 // Transmiting Beamforming no matter the target supports it or not +#define BEAMFORMING_HT_BEAMFORMER_STEER_NUM (BIT4|BIT5) +#define BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP (BIT6|BIT7) + +//------------------------------------------------------------ +// The HT Control field +//------------------------------------------------------------ +#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(((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_LDPC_CAP(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 0, 1, _val) +#define SET_HT_CAP_ELE_CHL_WIDTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 1, 1, _val) +#define SET_HT_CAP_ELE_SM_PS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 2, 2, _val) +#define SET_HT_CAP_ELE_GREENFIELD(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 4, 1, _val) +#define SET_HT_CAP_ELE_SHORT_GI20M(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 5, 1, _val) +#define SET_HT_CAP_ELE_SHORT_GI40M(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 6, 1, _val) +#define SET_HT_CAP_ELE_TX_STBC(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 7, 1, _val) +#define SET_HT_CAP_ELE_RX_STBC(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 0, 2, _val) +#define SET_HT_CAP_ELE_DELAYED_BA(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 2, 1, _val) +#define SET_HT_CAP_ELE_MAX_AMSDU_LENGTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 3, 1, _val) +#define SET_HT_CAP_ELE_DSSS_CCK_40M(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 4, 1, _val) +#define SET_HT_CAP_ELE_FORTY_INTOLERANT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 6, 1, _val) +#define SET_HT_CAP_ELE_LSIG_TXOP_PROTECT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 7, 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_COMP_STEERING_NUM_ANTENNAS(_pEleStart, _val) SET_BITS_TO_LE_4BYTE(((u8 *)(_pEleStart))+21, 23, 2, ((u8)_val)) +#define SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(_pEleStart, _val) SET_BITS_TO_LE_4BYTE(((u8 *)(_pEleStart))+21, 27, 2, ((u8)_val)) + + +#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) +#define GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(_pEleStart) LE_BITS_TO_4BYTE(((u8 *)(_pEleStart))+21, 23, 2) +#define GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(_pEleStart) LE_BITS_TO_4BYTE(((u8 *)(_pEleStart))+21, 27, 2) + +/* HT Operation element */ + +#define GET_HT_OP_ELE_PRI_CHL(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)), 0, 8) +#define SET_HT_OP_ELE_PRI_CHL(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)), 0, 8, _val) + +/* HT Operation Info field */ +#define HT_OP_ELE_OP_INFO(_pEleStart) (((u8 *)(_pEleStart)) + 1) +#define GET_HT_OP_ELE_2ND_CHL_OFFSET(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 1, 0, 2) +#define GET_HT_OP_ELE_STA_CHL_WIDTH(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 1, 2, 1) +#define GET_HT_OP_ELE_RIFS_MODE(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 1, 3, 1) +#define GET_HT_OP_ELE_HT_PROTECT(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 2, 0, 2) +#define GET_HT_OP_ELE_NON_GREEN_PRESENT(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 2, 2, 1) +#define GET_HT_OP_ELE_OBSS_NON_HT_PRESENT(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 2, 4, 1) +#define GET_HT_OP_ELE_DUAL_BEACON(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 4, 6, 1) +#define GET_HT_OP_ELE_DUAL_CTS(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 4, 7, 1) +#define GET_HT_OP_ELE_STBC_BEACON(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 5, 0, 1) +#define GET_HT_OP_ELE_LSIG_TXOP_PROTECT(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 5, 1, 1) +#define GET_HT_OP_ELE_PCO_ACTIVE(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 5, 2, 1) +#define GET_HT_OP_ELE_PCO_PHASE(_pEleStart) LE_BITS_TO_1BYTE(((u8 *)(_pEleStart)) + 5, 3, 1) + +#define SET_HT_OP_ELE_2ND_CHL_OFFSET(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 0, 2, _val) +#define SET_HT_OP_ELE_STA_CHL_WIDTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 2, 1, _val) +#define SET_HT_OP_ELE_RIFS_MODE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 1, 3, 1, _val) +#define SET_HT_OP_ELE_HT_PROTECT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 2, 0, 2, _val) +#define SET_HT_OP_ELE_NON_GREEN_PRESENT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 2, 2, 1, _val) +#define SET_HT_OP_ELE_OBSS_NON_HT_PRESENT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 2, 4, 1, _val) +#define SET_HT_OP_ELE_DUAL_BEACON(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 4, 6, 1, _val) +#define SET_HT_OP_ELE_DUAL_CTS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 4, 7, 1, _val) +#define SET_HT_OP_ELE_STBC_BEACON(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 5, 0, 1, _val) +#define SET_HT_OP_ELE_LSIG_TXOP_PROTECT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 5, 1, 1, _val) +#define SET_HT_OP_ELE_PCO_ACTIVE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 5, 2, 1, _val) +#define SET_HT_OP_ELE_PCO_PHASE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(((u8 *)(_pEleStart)) + 5, 3, 1, _val) + +#endif //_RTL871X_HT_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_io.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_io.h new file mode 100644 index 00000000..1b031f57 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_io.h @@ -0,0 +1,578 @@ +/****************************************************************************** + * + * 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 _RTW_IO_H_ +#define _RTW_IO_H_ + +#define NUM_IOREQ 8 + +#ifdef PLATFORM_WINDOWS +#define MAX_PROT_SZ 64 +#endif +#ifdef PLATFORM_LINUX +#define MAX_PROT_SZ (64-16) +#endif + +#define _IOREADY 0 +#define _IO_WAIT_COMPLETE 1 +#define _IO_WAIT_RSP 2 + +// IO COMMAND TYPE +#define _IOSZ_MASK_ (0x7F) +#define _IO_WRITE_ BIT(7) +#define _IO_FIXED_ BIT(8) +#define _IO_BURST_ BIT(9) +#define _IO_BYTE_ BIT(10) +#define _IO_HW_ BIT(11) +#define _IO_WORD_ BIT(12) +#define _IO_SYNC_ BIT(13) +#define _IO_CMDMASK_ (0x1F80) + + +/* + For prompt mode accessing, caller shall free io_req + Otherwise, io_handler will free io_req +*/ + + + +// IO STATUS TYPE +#define _IO_ERR_ BIT(2) +#define _IO_SUCCESS_ BIT(1) +#define _IO_DONE_ BIT(0) + + +#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) +#define IO_RD16 (_IO_SYNC_ | _IO_HW_) +#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) + +#define IO_RD32_ASYNC (_IO_WORD_) +#define IO_RD16_ASYNC (_IO_HW_) +#define IO_RD8_ASYNC (_IO_BYTE_) + +#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) +#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) +#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) + +#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) +#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) +#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) + +/* + + Only Sync. burst accessing is provided. + +*/ + +#define IO_WR_BURST(x) (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_)) +#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_)) + + + +//below is for the intf_option bit defition... + +#define _INTF_ASYNC_ BIT(0) //support async io + +struct intf_priv; +struct intf_hdl; +struct io_queue; + +struct _io_ops +{ + u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); + u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); + u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); + + int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata); + + int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + + void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + + void (*_sync_irp_protocol_rw)(struct io_queue *pio_q); + + u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr); + + u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); + + u32 (*_write_scsi)(struct intf_hdl *pintfhdl,u32 cnt, u8 *pmem); + + void (*_read_port_cancel)(struct intf_hdl *pintfhdl); + void (*_write_port_cancel)(struct intf_hdl *pintfhdl); + +#ifdef CONFIG_SDIO_HCI + u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr); + #ifdef CONFIG_SDIO_INDIRECT_ACCESS + u8 (*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr); + u16 (*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr); + u32 (*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr); + int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); + int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); + int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); + #endif /* CONFIG_SDIO_INDIRECT_ACCESS */ +#endif + +}; + +struct io_req { + _list list; + u32 addr; + volatile u32 val; + u32 command; + u32 status; + u8 *pbuf; + _sema sema; + +#ifdef PLATFORM_OS_CE +#ifdef CONFIG_USB_HCI + // URB handler for rtw_write_mem + USB_TRANSFER usb_transfer_write_mem; +#endif +#endif + + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt); + u8 *cnxt; + +#ifdef PLATFORM_OS_XP + PMDL pmdl; + PIRP pirp; + +#ifdef CONFIG_SDIO_HCI + PSDBUS_REQUEST_PACKET sdrp; +#endif + +#endif + + +}; + +struct intf_hdl { + +/* + u32 intf_option; + u32 bus_status; + u32 do_flush; + u8 *adapter; + u8 *intf_dev; + struct intf_priv *pintfpriv; + u8 cnt; + void (*intf_hdl_init)(u8 *priv); + void (*intf_hdl_unload)(u8 *priv); + void (*intf_hdl_open)(u8 *priv); + void (*intf_hdl_close)(u8 *priv); + struct _io_ops io_ops; + //u8 intf_status;//moved to struct intf_priv + u16 len; + u16 done_len; +*/ + _adapter *padapter; + struct dvobj_priv *pintf_dev;// pointer to &(padapter->dvobjpriv); + + struct _io_ops io_ops; + +}; + +struct reg_protocol_rd { + +#ifdef CONFIG_LITTLE_ENDIAN + + //DW1 + u32 NumOfTrans:4; + u32 Reserved1:4; + u32 Reserved2:24; + //DW2 + u32 ByteCount:7; + u32 WriteEnable:1; //0:read, 1:write + u32 FixOrContinuous:1; //0:continuous, 1: Fix + u32 BurstMode:1; + u32 Byte1Access:1; + u32 Byte2Access:1; + u32 Byte4Access:1; + u32 Reserved3:3; + u32 Reserved4:16; + //DW3 + u32 BusAddress; + //DW4 + //u32 Value; +#else + + +//DW1 + u32 Reserved1 :4; + u32 NumOfTrans :4; + + u32 Reserved2 :24; + + //DW2 + u32 WriteEnable : 1; + u32 ByteCount :7; + + + u32 Reserved3 : 3; + u32 Byte4Access : 1; + + u32 Byte2Access : 1; + u32 Byte1Access : 1; + u32 BurstMode :1 ; + u32 FixOrContinuous : 1; + + u32 Reserved4 : 16; + + //DW3 + u32 BusAddress; + + //DW4 + //u32 Value; + +#endif + +}; + + +struct reg_protocol_wt { + + +#ifdef CONFIG_LITTLE_ENDIAN + + //DW1 + u32 NumOfTrans:4; + u32 Reserved1:4; + u32 Reserved2:24; + //DW2 + u32 ByteCount:7; + u32 WriteEnable:1; //0:read, 1:write + u32 FixOrContinuous:1; //0:continuous, 1: Fix + u32 BurstMode:1; + u32 Byte1Access:1; + u32 Byte2Access:1; + u32 Byte4Access:1; + u32 Reserved3:3; + u32 Reserved4:16; + //DW3 + u32 BusAddress; + //DW4 + u32 Value; + +#else + //DW1 + u32 Reserved1 :4; + u32 NumOfTrans :4; + + u32 Reserved2 :24; + + //DW2 + u32 WriteEnable : 1; + u32 ByteCount :7; + + u32 Reserved3 : 3; + u32 Byte4Access : 1; + + u32 Byte2Access : 1; + u32 Byte1Access : 1; + u32 BurstMode :1 ; + u32 FixOrContinuous : 1; + + u32 Reserved4 : 16; + + //DW3 + u32 BusAddress; + + //DW4 + u32 Value; + +#endif + +}; +#ifdef CONFIG_PCI_HCI +#define MAX_CONTINUAL_IO_ERR 4 +#endif + +#ifdef CONFIG_USB_HCI +#define MAX_CONTINUAL_IO_ERR 4 +#endif + +#ifdef CONFIG_SDIO_HCI +#define SD_IO_TRY_CNT (8) +#define MAX_CONTINUAL_IO_ERR SD_IO_TRY_CNT +#endif + +#ifdef CONFIG_GSPI_HCI +#define SD_IO_TRY_CNT (8) +#define MAX_CONTINUAL_IO_ERR SD_IO_TRY_CNT +#endif + + +int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj); +void rtw_reset_continual_io_error(struct dvobj_priv *dvobj); + +/* +Below is the data structure used by _io_handler + +*/ + +struct io_queue { + _lock lock; + _list free_ioreqs; + _list pending; //The io_req list that will be served in the single protocol read/write. + _list processing; + u8 *free_ioreqs_buf; // 4-byte aligned + u8 *pallocated_free_ioreqs_buf; + struct intf_hdl intf; +}; + +struct io_priv{ + + _adapter *padapter; + + struct intf_hdl intf; + +}; + +extern uint ioreq_flush(_adapter *adapter, struct io_queue *ioqueue); +extern void sync_ioreq_enqueue(struct io_req *preq,struct io_queue *ioqueue); +extern uint sync_ioreq_flush(_adapter *adapter, struct io_queue *ioqueue); + + +extern uint free_ioreq(struct io_req *preq, struct io_queue *pio_queue); +extern struct io_req *alloc_ioreq(struct io_queue *pio_q); + +extern uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl); +extern void unregister_intf_hdl(struct intf_hdl *pintfhdl); + +extern void _rtw_attrib_read(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_attrib_write(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + +extern u8 _rtw_read8(_adapter *adapter, u32 addr); +extern u16 _rtw_read16(_adapter *adapter, u32 addr); +extern u32 _rtw_read32(_adapter *adapter, u32 addr); +extern void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void _rtw_read_port_cancel(_adapter *adapter); + + +extern int _rtw_write8(_adapter *adapter, u32 addr, u8 val); +extern int _rtw_write16(_adapter *adapter, u32 addr, u16 val); +extern int _rtw_write32(_adapter *adapter, u32 addr, u32 val); +extern int _rtw_writeN(_adapter *adapter, u32 addr, u32 length, u8 *pdata); + +#ifdef CONFIG_SDIO_HCI +u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr); +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +u8 _rtw_sd_iread8(_adapter *adapter, u32 addr); +u16 _rtw_sd_iread16(_adapter *adapter, u32 addr); +u32 _rtw_sd_iread32(_adapter *adapter, u32 addr); +int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val); +int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val); +int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val); +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ +#endif /* CONFIG_SDIO_HCI */ + +extern int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val); +extern int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val); +extern int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val); + +extern void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms); +extern void _rtw_write_port_cancel(_adapter *adapter); + +#ifdef DBG_IO +bool match_read_sniff_ranges(u32 addr, u16 len); +bool match_write_sniff_ranges(u32 addr, u16 len); +bool match_rf_read_sniff_ranges(u8 path, u32 addr, u32 mask); +bool match_rf_write_sniff_ranges(u8 path, u32 addr, u32 mask); + +extern u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line); +extern u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line); +extern u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line); + +extern int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line); +extern int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line); +extern int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line); +extern int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line); + +#ifdef CONFIG_SDIO_HCI +u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line); +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line); +u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line); +u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line); +int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line); +int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line); +int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line); +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ +#endif /* CONFIG_SDIO_HCI */ + +#define rtw_read8(adapter, addr) dbg_rtw_read8((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read16(adapter, addr) dbg_rtw_read16((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read32(adapter, addr) dbg_rtw_read32((adapter), (addr), __FUNCTION__, __LINE__) +#define rtw_read_mem(adapter, addr, cnt, mem) _rtw_read_mem((adapter), (addr), (cnt), (mem)) +#define rtw_read_port(adapter, addr, cnt, mem) _rtw_read_port((adapter), (addr), (cnt), (mem)) +#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) + +#define rtw_write8(adapter, addr, val) dbg_rtw_write8((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_write16(adapter, addr, val) dbg_rtw_write16((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_write32(adapter, addr, val) dbg_rtw_write32((adapter), (addr), (val), __FUNCTION__, __LINE__) +#define rtw_writeN(adapter, addr, length, data) dbg_rtw_writeN((adapter), (addr), (length), (data), __FUNCTION__, __LINE__) + +#define rtw_write8_async(adapter, addr, val) _rtw_write8_async((adapter), (addr), (val)) +#define rtw_write16_async(adapter, addr, val) _rtw_write16_async((adapter), (addr), (val)) +#define rtw_write32_async(adapter, addr, val) _rtw_write32_async((adapter), (addr), (val)) + +#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem((adapter), addr, cnt, mem) +#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port(adapter, addr, cnt, mem) +#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) +#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel(adapter) + +#ifdef CONFIG_SDIO_HCI +#define rtw_sd_f0_read8(adapter, addr) dbg_rtw_sd_f0_read8((adapter), (addr), __func__, __LINE__) +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +#define rtw_sd_iread8(adapter, addr) dbg_rtw_sd_iread8((adapter), (addr), __func__, __LINE__) +#define rtw_sd_iread16(adapter, addr) dbg_rtw_sd_iread16((adapter), (addr), __func__, __LINE__) +#define rtw_sd_iread32(adapter, addr) dbg_rtw_sd_iread32((adapter), (addr), __func__, __LINE__) +#define rtw_sd_iwrite8(adapter, addr, val) dbg_rtw_sd_iwrite8((adapter), (addr), (val), __func__, __LINE__) +#define rtw_sd_iwrite16(adapter, addr, val) dbg_rtw_sd_iwrite16((adapter), (addr), (val), __func__, __LINE__) +#define rtw_sd_iwrite32(adapter, addr, val) dbg_rtw_sd_iwrite32((adapter), (addr), (val), __func__, __LINE__) +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ +#endif /* CONFIG_SDIO_HCI */ + +#else /* DBG_IO */ +#define match_read_sniff_ranges(addr, len) _FALSE +#define match_write_sniff_ranges(addr, len) _FALSE +#define match_rf_read_sniff_ranges(path, addr, mask) _FALSE +#define match_rf_write_sniff_ranges(path, addr, mask) _FALSE +#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr)) +#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr)) +#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr)) +#define rtw_read_mem(adapter, addr, cnt, mem) _rtw_read_mem((adapter), (addr), (cnt), (mem)) +#define rtw_read_port(adapter, addr, cnt, mem) _rtw_read_port((adapter), (addr), (cnt), (mem)) +#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter)) + +#define rtw_write8(adapter, addr, val) _rtw_write8((adapter), (addr), (val)) +#define rtw_write16(adapter, addr, val) _rtw_write16((adapter), (addr), (val)) +#define rtw_write32(adapter, addr, val) _rtw_write32((adapter), (addr), (val)) +#define rtw_writeN(adapter, addr, length, data) _rtw_writeN((adapter), (addr), (length), (data)) + +#define rtw_write8_async(adapter, addr, val) _rtw_write8_async((adapter), (addr), (val)) +#define rtw_write16_async(adapter, addr, val) _rtw_write16_async((adapter), (addr), (val)) +#define rtw_write32_async(adapter, addr, val) _rtw_write32_async((adapter), (addr), (val)) + +#define rtw_write_mem(adapter, addr, cnt, mem) _rtw_write_mem((adapter), (addr), (cnt), (mem)) +#define rtw_write_port(adapter, addr, cnt, mem) _rtw_write_port((adapter), (addr), (cnt), (mem)) +#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms)) +#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel((adapter)) + +#ifdef CONFIG_SDIO_HCI +#define rtw_sd_f0_read8(adapter, addr) _rtw_sd_f0_read8((adapter), (addr)) +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +#define rtw_sd_iread8(adapter, addr) _rtw_sd_iread8((adapter), (addr)) +#define rtw_sd_iread16(adapter, addr) _rtw_sd_iread16((adapter), (addr)) +#define rtw_sd_iread32(adapter, addr) _rtw_sd_iread32((adapter), (addr)) +#define rtw_sd_iwrite8(adapter, addr, val) _rtw_sd_iwrite8((adapter), (addr), (val)) +#define rtw_sd_iwrite16(adapter, addr, val) _rtw_sd_iwrite16((adapter), (addr), (val)) +#define rtw_sd_iwrite32(adapter, addr, val) _rtw_sd_iwrite32((adapter), (addr), (val)) +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ +#endif /* CONFIG_SDIO_HCI */ + +#endif /* DBG_IO */ + +extern void rtw_write_scsi(_adapter *adapter, u32 cnt, u8 *pmem); + +//ioreq +extern void ioreq_read8(_adapter *adapter, u32 addr, u8 *pval); +extern void ioreq_read16(_adapter *adapter, u32 addr, u16 *pval); +extern void ioreq_read32(_adapter *adapter, u32 addr, u32 *pval); +extern void ioreq_write8(_adapter *adapter, u32 addr, u8 val); +extern void ioreq_write16(_adapter *adapter, u32 addr, u16 val); +extern void ioreq_write32(_adapter *adapter, u32 addr, u32 val); + + +extern uint async_read8(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern uint async_read16(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern uint async_read32(_adapter *adapter, u32 addr, u8 *pbuff, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); + +extern void async_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void async_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + +extern void async_write8(_adapter *adapter, u32 addr, u8 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern void async_write16(_adapter *adapter, u32 addr, u16 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); +extern void async_write32(_adapter *adapter, u32 addr, u32 val, + void (*_async_io_callback)(_adapter *padater, struct io_req *pio_req, u8 *cnxt), u8 *cnxt); + +extern void async_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); +extern void async_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem); + + +int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops)); + + +extern uint alloc_io_queue(_adapter *adapter); +extern void free_io_queue(_adapter *adapter); +extern void async_bus_io(struct io_queue *pio_q); +extern void bus_sync_io(struct io_queue *pio_q); +extern u32 _ioreq2rwmem(struct io_queue *pio_q); +extern void dev_power_down(_adapter * Adapter, u8 bpwrup); + +/* +#define RTL_R8(reg) rtw_read8(padapter, reg) +#define RTL_R16(reg) rtw_read16(padapter, reg) +#define RTL_R32(reg) rtw_read32(padapter, reg) +#define RTL_W8(reg, val8) rtw_write8(padapter, reg, val8) +#define RTL_W16(reg, val16) rtw_write16(padapter, reg, val16) +#define RTL_W32(reg, val32) rtw_write32(padapter, reg, val32) +*/ + +/* +#define RTL_W8_ASYNC(reg, val8) rtw_write32_async(padapter, reg, val8) +#define RTL_W16_ASYNC(reg, val16) rtw_write32_async(padapter, reg, val16) +#define RTL_W32_ASYNC(reg, val32) rtw_write32_async(padapter, reg, val32) + +#define RTL_WRITE_BB(reg, val32) phy_SetUsbBBReg(padapter, reg, val32) +#define RTL_READ_BB(reg) phy_QueryUsbBBReg(padapter, reg) +*/ + +#define PlatformEFIOWrite1Byte(_a,_b,_c) \ + rtw_write8(_a,_b,_c) +#define PlatformEFIOWrite2Byte(_a,_b,_c) \ + rtw_write16(_a,_b,_c) +#define PlatformEFIOWrite4Byte(_a,_b,_c) \ + rtw_write32(_a,_b,_c) + +#define PlatformEFIORead1Byte(_a,_b) \ + rtw_read8(_a,_b) +#define PlatformEFIORead2Byte(_a,_b) \ + rtw_read16(_a,_b) +#define PlatformEFIORead4Byte(_a,_b) \ + rtw_read32(_a,_b) + +#endif //_RTL8711_IO_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl.h new file mode 100644 index 00000000..3a82c6d5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl.h @@ -0,0 +1,329 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_H_ +#define _RTW_IOCTL_H_ + +#ifndef PLATFORM_WINDOWS +// 00 - Success +// 11 - Error +#define STATUS_SUCCESS (0x00000000L) +#define STATUS_PENDING (0x00000103L) + +#define STATUS_UNSUCCESSFUL (0xC0000001L) +#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) +#define STATUS_NOT_SUPPORTED (0xC00000BBL) + +#define NDIS_STATUS_SUCCESS ((NDIS_STATUS)STATUS_SUCCESS) +#define NDIS_STATUS_PENDING ((NDIS_STATUS)STATUS_PENDING) +#define NDIS_STATUS_NOT_RECOGNIZED ((NDIS_STATUS)0x00010001L) +#define NDIS_STATUS_NOT_COPIED ((NDIS_STATUS)0x00010002L) +#define NDIS_STATUS_NOT_ACCEPTED ((NDIS_STATUS)0x00010003L) +#define NDIS_STATUS_CALL_ACTIVE ((NDIS_STATUS)0x00010007L) + +#define NDIS_STATUS_FAILURE ((NDIS_STATUS)STATUS_UNSUCCESSFUL) +#define NDIS_STATUS_RESOURCES ((NDIS_STATUS)STATUS_INSUFFICIENT_RESOURCES) +#define NDIS_STATUS_CLOSING ((NDIS_STATUS)0xC0010002L) +#define NDIS_STATUS_BAD_VERSION ((NDIS_STATUS)0xC0010004L) +#define NDIS_STATUS_BAD_CHARACTERISTICS ((NDIS_STATUS)0xC0010005L) +#define NDIS_STATUS_ADAPTER_NOT_FOUND ((NDIS_STATUS)0xC0010006L) +#define NDIS_STATUS_OPEN_FAILED ((NDIS_STATUS)0xC0010007L) +#define NDIS_STATUS_DEVICE_FAILED ((NDIS_STATUS)0xC0010008L) +#define NDIS_STATUS_MULTICAST_FULL ((NDIS_STATUS)0xC0010009L) +#define NDIS_STATUS_MULTICAST_EXISTS ((NDIS_STATUS)0xC001000AL) +#define NDIS_STATUS_MULTICAST_NOT_FOUND ((NDIS_STATUS)0xC001000BL) +#define NDIS_STATUS_REQUEST_ABORTED ((NDIS_STATUS)0xC001000CL) +#define NDIS_STATUS_RESET_IN_PROGRESS ((NDIS_STATUS)0xC001000DL) +#define NDIS_STATUS_CLOSING_INDICATING ((NDIS_STATUS)0xC001000EL) +#define NDIS_STATUS_NOT_SUPPORTED ((NDIS_STATUS)STATUS_NOT_SUPPORTED) +#define NDIS_STATUS_INVALID_PACKET ((NDIS_STATUS)0xC001000FL) +#define NDIS_STATUS_OPEN_LIST_FULL ((NDIS_STATUS)0xC0010010L) +#define NDIS_STATUS_ADAPTER_NOT_READY ((NDIS_STATUS)0xC0010011L) +#define NDIS_STATUS_ADAPTER_NOT_OPEN ((NDIS_STATUS)0xC0010012L) +#define NDIS_STATUS_NOT_INDICATING ((NDIS_STATUS)0xC0010013L) +#define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) +#define NDIS_STATUS_INVALID_DATA ((NDIS_STATUS)0xC0010015L) +#define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) +#define NDIS_STATUS_INVALID_OID ((NDIS_STATUS)0xC0010017L) +#define NDIS_STATUS_ADAPTER_REMOVED ((NDIS_STATUS)0xC0010018L) +#define NDIS_STATUS_UNSUPPORTED_MEDIA ((NDIS_STATUS)0xC0010019L) +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((NDIS_STATUS)0xC001001AL) +#define NDIS_STATUS_FILE_NOT_FOUND ((NDIS_STATUS)0xC001001BL) +#define NDIS_STATUS_ERROR_READING_FILE ((NDIS_STATUS)0xC001001CL) +#define NDIS_STATUS_ALREADY_MAPPED ((NDIS_STATUS)0xC001001DL) +#define NDIS_STATUS_RESOURCE_CONFLICT ((NDIS_STATUS)0xC001001EL) +#define NDIS_STATUS_NO_CABLE ((NDIS_STATUS)0xC001001FL) + +#define NDIS_STATUS_INVALID_SAP ((NDIS_STATUS)0xC0010020L) +#define NDIS_STATUS_SAP_IN_USE ((NDIS_STATUS)0xC0010021L) +#define NDIS_STATUS_INVALID_ADDRESS ((NDIS_STATUS)0xC0010022L) +#define NDIS_STATUS_VC_NOT_ACTIVATED ((NDIS_STATUS)0xC0010023L) +#define NDIS_STATUS_DEST_OUT_OF_ORDER ((NDIS_STATUS)0xC0010024L) // cause 27 +#define NDIS_STATUS_VC_NOT_AVAILABLE ((NDIS_STATUS)0xC0010025L) // cause 35,45 +#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((NDIS_STATUS)0xC0010026L) // cause 37 +#define NDIS_STATUS_INCOMPATABLE_QOS ((NDIS_STATUS)0xC0010027L) // cause 49 +#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((NDIS_STATUS)0xC0010028L) // cause 93 +#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((NDIS_STATUS)0xC0010029L) // cause 3 +#endif /* #ifndef PLATFORM_WINDOWS */ + + +#ifndef OID_802_11_CAPABILITY + #define OID_802_11_CAPABILITY 0x0d010122 +#endif + +#ifndef OID_802_11_PMKID + #define OID_802_11_PMKID 0x0d010123 +#endif + + +// For DDK-defined OIDs +#define OID_NDIS_SEG1 0x00010100 +#define OID_NDIS_SEG2 0x00010200 +#define OID_NDIS_SEG3 0x00020100 +#define OID_NDIS_SEG4 0x01010100 +#define OID_NDIS_SEG5 0x01020100 +#define OID_NDIS_SEG6 0x01020200 +#define OID_NDIS_SEG7 0xFD010100 +#define OID_NDIS_SEG8 0x0D010100 +#define OID_NDIS_SEG9 0x0D010200 +#define OID_NDIS_SEG10 0x0D020200 + +#define SZ_OID_NDIS_SEG1 23 +#define SZ_OID_NDIS_SEG2 3 +#define SZ_OID_NDIS_SEG3 6 +#define SZ_OID_NDIS_SEG4 6 +#define SZ_OID_NDIS_SEG5 4 +#define SZ_OID_NDIS_SEG6 8 +#define SZ_OID_NDIS_SEG7 7 +#define SZ_OID_NDIS_SEG8 36 +#define SZ_OID_NDIS_SEG9 24 +#define SZ_OID_NDIS_SEG10 19 + +// For Realtek-defined OIDs +#define OID_MP_SEG1 0xFF871100 +#define OID_MP_SEG2 0xFF818000 + +#define OID_MP_SEG3 0xFF818700 +#define OID_MP_SEG4 0xFF011100 + +#define DEBUG_OID(dbg, str) \ + if((!dbg)) \ + { \ + RT_TRACE(_module_rtl871x_ioctl_c_,_drv_info_,("%s(%d): %s", __FUNCTION__, __LINE__, str)); \ + } + + +enum oid_type +{ + QUERY_OID, + SET_OID +}; + +struct oid_funs_node { + unsigned int oid_start; //the starting number for OID + unsigned int oid_end; //the ending number for OID + struct oid_obj_priv *node_array; + unsigned int array_sz; //the size of node_array + int query_counter; //count the number of query hits for this segment + int set_counter; //count the number of set hits for this segment +}; + +struct oid_par_priv +{ + void *adapter_context; + NDIS_OID oid; + void *information_buf; + u32 information_buf_len; + u32 *bytes_rw; + u32 *bytes_needed; + enum oid_type type_of_oid; + u32 dbg; +}; + +struct oid_obj_priv { + unsigned char dbg; // 0: without OID debug message 1: with OID debug message + NDIS_STATUS (*oidfuns)(struct oid_par_priv *poid_par_priv); +}; + +#if (defined(CONFIG_MP_INCLUDED) && defined(_RTW_MP_IOCTL_C_)) || \ + (defined(PLATFORM_WINDOWS) && defined(_RTW_IOCTL_RTL_C_)) +static NDIS_STATUS oid_null_function(struct oid_par_priv* poid_par_priv) +{ + _func_enter_; + _func_exit_; + return NDIS_STATUS_SUCCESS; +} +#endif + +#ifdef PLATFORM_WINDOWS + +int TranslateNdisPsToRtPs(IN NDIS_802_11_POWER_MODE ndisPsMode); + +//OID Handler for Segment 1 +NDIS_STATUS oid_gen_supported_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_hardware_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_in_use_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_lookahead_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_frame_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_link_speed_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_transmit_buffer_space_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_receive_buffer_space_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_transmit_block_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_receive_block_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_id_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_description_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_current_packet_filter_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_current_lookahead_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_driver_version_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_total_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_protocol_options_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_mac_options_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_media_connect_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_maximum_send_packets_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_vendor_driver_version_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 2 +NDIS_STATUS oid_gen_physical_medium_hdl(struct oid_par_priv* poid_par_priv); + +//OID Handler for Segment 3 +NDIS_STATUS oid_gen_xmit_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_xmit_error_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_error_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_gen_rcv_no_buffer_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 4 +NDIS_STATUS oid_802_3_permanent_address_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_current_address_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_multicast_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_maximum_list_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_mac_options_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 5 +NDIS_STATUS oid_802_3_rcv_error_alignment_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_one_collision_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_more_collisions_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 6 +NDIS_STATUS oid_802_3_xmit_deferred_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_max_collisions_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_rcv_overrun_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_underrun_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_heartbeat_failure_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_times_crs_lost_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_3_xmit_late_collisions_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 7 +NDIS_STATUS oid_pnp_capabilities_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_set_power_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_query_power_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_add_wake_up_pattern_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_remove_wake_up_pattern_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_wake_up_pattern_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_pnp_enable_wake_up_hdl(struct oid_par_priv* poid_par_priv); + + + +//OID Handler for Segment 8 +NDIS_STATUS oid_802_11_bssid_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_ssid_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_infrastructure_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_add_wep_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_remove_wep_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_disassociate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_authentication_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_privacy_filter_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_bssid_list_scan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_encryption_status_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_reload_defaults_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_add_key_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_remove_key_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_association_information_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_media_stream_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_capability_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_pmkid_hdl(struct oid_par_priv* poid_par_priv); + + + + + +//OID Handler for Segment 9 +NDIS_STATUS oid_802_11_network_types_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_network_type_in_use_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_tx_power_level_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rssi_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rssi_trigger_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_fragmentation_threshold_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rts_threshold_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_number_of_antennas_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_rx_antenna_selected_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_tx_antenna_selected_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_supported_rates_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_desired_rates_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_configuration_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_power_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_802_11_bssid_list_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment 10 +NDIS_STATUS oid_802_11_statistics_hdl(struct oid_par_priv* poid_par_priv); + + +//OID Handler for Segment ED +NDIS_STATUS oid_rt_mh_vender_id_hdl(struct oid_par_priv* poid_par_priv); + +void Set_802_3_MULTICAST_LIST(ADAPTER *pAdapter, UCHAR *MCListbuf, ULONG MCListlen, BOOLEAN bAcceptAllMulticast); + +#endif// end of PLATFORM_WINDOWS + +#if defined(PLATFORM_LINUX) && defined(CONFIG_WIRELESS_EXT) +extern struct iw_handler_def rtw_handlers_def; +#endif + +extern void rtw_request_wps_pbc_event(_adapter *padapter); + +extern NDIS_STATUS drv_query_info( + IN _nic_hdl MiniportAdapterContext, + IN NDIS_OID Oid, + IN void * InformationBuffer, + IN u32 InformationBufferLength, + OUT u32* BytesWritten, + OUT u32* BytesNeeded + ); + +extern NDIS_STATUS drv_set_info( + IN _nic_hdl MiniportAdapterContext, + IN NDIS_OID Oid, + IN void * InformationBuffer, + IN u32 InformationBufferLength, + OUT u32* BytesRead, + OUT u32* BytesNeeded + ); + +#endif // #ifndef __INC_CEINFO_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_query.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_query.h new file mode 100644 index 00000000..d91d35f9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_query.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_QUERY_H_ +#define _RTW_IOCTL_QUERY_H_ + + +#ifdef PLATFORM_WINDOWS + +u8 query_802_11_capability(_adapter* padapter,u8* pucBuf,u32 * pulOutLen); +u8 query_802_11_association_information (_adapter * padapter, PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo); + +#endif + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_rtl.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_rtl.h new file mode 100644 index 00000000..a1b3491f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_rtl.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * 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 _RTW_IOCTL_RTL_H_ +#define _RTW_IOCTL_RTL_H_ + + +//************** oid_rtl_seg_01_01 ************** +NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv* poid_par_priv);//84 +NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv* poid_par_priv); //8a +NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv* poid_par_priv); //8b + +NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv* poid_par_priv);//93 +NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv* poid_par_priv); + +//************** oid_rtl_seg_01_03 section start ************** +NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv* poid_par_priv); + +// oid_rtl_seg_01_11 +NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv* poid_par_priv); + +//************** oid_rtl_seg_03_00 section start ************** +NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv* poid_par_priv); + + + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_set.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_set.h new file mode 100644 index 00000000..1b718468 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_ioctl_set.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 __RTW_IOCTL_SET_H_ +#define __RTW_IOCTL_SET_H_ + + +typedef u8 NDIS_802_11_PMKID_VALUE[16]; + +typedef struct _BSSIDInfo { + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_PMKID_VALUE PMKID; +} BSSIDInfo, *PBSSIDInfo; + + +#ifdef PLATFORM_OS_XP +typedef struct _NDIS_802_11_PMKID { + u32 Length; + u32 BSSIDInfoCount; + BSSIDInfo BSSIDInfo[1]; +} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID; +#endif + + +#ifdef PLATFORM_WINDOWS +u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults); +u8 rtw_set_802_11_test(_adapter * padapter, NDIS_802_11_TEST * test); +u8 rtw_set_802_11_pmkid(_adapter *pdapter, NDIS_802_11_PMKID *pmkid); + +u8 rtw_pnp_set_power_sleep(_adapter* padapter); +u8 rtw_pnp_set_power_wakeup(_adapter* padapter); + +void rtw_pnp_resume_wk(void *context); +void rtw_pnp_sleep_wk(void * context); + +#endif + +u8 rtw_set_802_11_add_key(_adapter * padapter, NDIS_802_11_KEY * key); +u8 rtw_set_802_11_authentication_mode(_adapter *pdapter, NDIS_802_11_AUTHENTICATION_MODE authmode); +u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid); +u8 rtw_set_802_11_add_wep(_adapter * padapter, NDIS_802_11_WEP * wep); +u8 rtw_set_802_11_disassociate(_adapter * padapter); +u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +u8 rtw_set_802_11_infrastructure_mode(_adapter * padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +u8 rtw_set_802_11_remove_wep(_adapter * padapter, u32 keyindex); +u8 rtw_set_802_11_ssid(_adapter * padapter, NDIS_802_11_SSID * ssid); +u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid); +u8 rtw_set_802_11_remove_key(_adapter * padapter, NDIS_802_11_REMOVE_KEY * key); + +u8 rtw_validate_bssid(u8 *bssid); +u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid); + +u16 rtw_get_cur_max_rate(_adapter *adapter); +int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode); +int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan); +int rtw_set_country(_adapter *adapter, const char *country_code); +int rtw_set_band(_adapter *adapter, u8 band); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_iol.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_iol.h new file mode 100644 index 00000000..ddabeacc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_iol.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * + * 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 __RTW_IOL_H_ +#define __RTW_IOL_H_ + + +struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter); +int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len); +int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); +int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt); +bool rtw_IOL_applied(ADAPTER *adapter); +int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); +int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); +int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); + + +#ifdef CONFIG_IOL_NEW_GENERATION +#define IOREG_CMD_END_LEN 4 + +struct ioreg_cfg{ + u8 length; + u8 cmd_id; + u16 address; + u32 data; + u32 mask; +}; +enum ioreg_cmd{ + IOREG_CMD_LLT = 0x01, + IOREG_CMD_REFUSE = 0x02, + IOREG_CMD_EFUSE_PATH = 0x03, + IOREG_CMD_WB_REG = 0x04, + IOREG_CMD_WW_REG = 0x05, + IOREG_CMD_WD_REG = 0x06, + IOREG_CMD_W_RF = 0x07, + IOREG_CMD_DELAY_US = 0x10, + IOREG_CMD_DELAY_MS = 0x11, + IOREG_CMD_END = 0xFF, +}; +void read_efuse_from_txpktbuf(ADAPTER *adapter, int bcnhead, u8 *content, u16 *size); + +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask); +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask); +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask); +int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask); +#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value,mask) _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) ,(mask)) +#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value,mask) _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value),(mask)) +#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value,mask) _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value),(mask)) +#define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value,mask) _rtw_IOL_append_WRF_cmd((xmit_frame),(rf_path), (addr), (value),(mask)) + +u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame); +void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter,int buf_len,u8 *pbuf); + +#ifdef CONFIG_IOL_IOREG_CFG_DBG + struct cmd_cmp{ + u16 addr; + u32 value; + }; +#endif + +#else //CONFIG_IOL_NEW_GENERATION + +typedef struct _io_offload_cmd { + u8 rsvd0; + u8 cmd; + u16 address; + u32 value; +} IO_OFFLOAD_CMD, IOL_CMD; + +#define IOL_CMD_LLT 0x00 +//#define IOL_CMD_R_EFUSE 0x01 +#define IOL_CMD_WB_REG 0x02 +#define IOL_CMD_WW_REG 0x03 +#define IOL_CMD_WD_REG 0x04 +//#define IOL_CMD_W_RF 0x05 +#define IOL_CMD_DELAY_US 0x80 +#define IOL_CMD_DELAY_MS 0x81 +//#define IOL_CMD_DELAY_S 0x82 +#define IOL_CMD_END 0x83 + +/***************************************************** +CMD Address Value +(B1) (B2/B3:H/L addr) (B4:B7 : MSB:LSB) +****************************************************** +IOL_CMD_LLT - B7: PGBNDY +//IOL_CMD_R_EFUSE - - +IOL_CMD_WB_REG 0x0~0xFFFF B7 +IOL_CMD_WW_REG 0x0~0xFFFF B6~B7 +IOL_CMD_WD_REG 0x0~0xFFFF B4~B7 +//IOL_CMD_W_RF RF Reg B5~B7 +IOL_CMD_DELAY_US - B6~B7 +IOL_CMD_DELAY_MS - B6~B7 +//IOL_CMD_DELAY_S - B6~B7 +IOL_CMD_END - - +******************************************************/ +int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value); +int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value); +int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value); + + +int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms); +int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms); + +#ifdef DBG_IO +int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line); +int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line); +int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line); +#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value) dbg_rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), __FUNCTION__, __LINE__) +#else +#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value) _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value)) +#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value) _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value)) +#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value) _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value)) +#endif // DBG_IO +#endif // CONFIG_IOL_NEW_GENERATION + + + +#endif //__RTW_IOL_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mem.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mem.h new file mode 100644 index 00000000..1c11db1b --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mem.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * 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 __RTW_MEM_H__ +#define __RTW_MEM_H__ + +#include +#include +#include + +#ifdef CONFIG_PLATFORM_MSTAR_HIGH +#define MAX_RTKM_RECVBUF_SZ (31744) /* 31k */ +#else +#define MAX_RTKM_RECVBUF_SZ (15360) /* 15k */ +#endif /* CONFIG_PLATFORM_MSTAR_HIGH */ +#define MAX_RTKM_NR_PREALLOC_RECV_SKB 16 + +u16 rtw_rtkm_get_buff_size(void); +u8 rtw_rtkm_get_nr_recv_skb(void); +struct u8* rtw_alloc_revcbuf_premem(void); +struct sk_buff *rtw_alloc_skb_premem(u16 in_size); +int rtw_free_skb_premem(struct sk_buff *pskb); + + +#endif //__RTW_MEM_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme.h new file mode 100644 index 00000000..e592d681 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme.h @@ -0,0 +1,1078 @@ +/****************************************************************************** + * + * 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 __RTW_MLME_H_ +#define __RTW_MLME_H_ + + +#define MAX_BSS_CNT 128 +//#define MAX_JOIN_TIMEOUT 2000 +//#define MAX_JOIN_TIMEOUT 2500 +#define MAX_JOIN_TIMEOUT 6500 + +// Commented by Albert 20101105 +// Increase the scanning timeout because of increasing the SURVEY_TO value. + +#define SCANNING_TIMEOUT 8000 +#ifdef CONFIG_SCAN_BACKOP +#define CONC_SCANNING_TIMEOUT_SINGLE_BAND 10000 +#define CONC_SCANNING_TIMEOUT_DUAL_BAND 15000 +#endif + +#ifdef PALTFORM_OS_WINCE +#define SCANQUEUE_LIFETIME 12000000 // unit:us +#else +#define SCANQUEUE_LIFETIME 20000 // 20sec, unit:msec +#endif + +#define WIFI_NULL_STATE 0x00000000 +#define WIFI_ASOC_STATE 0x00000001 /* Linked */ +#define WIFI_REASOC_STATE 0x00000002 +#define WIFI_SLEEP_STATE 0x00000004 +#define WIFI_STATION_STATE 0x00000008 +#define WIFI_AP_STATE 0x00000010 +#define WIFI_ADHOC_STATE 0x00000020 +#define WIFI_ADHOC_MASTER_STATE 0x00000040 +#define WIFI_UNDER_LINKING 0x00000080 +#define WIFI_UNDER_WPS 0x00000100 +/*#define WIFI_UNDEFINED_STATE 0x00000200*/ +#define WIFI_STA_ALIVE_CHK_STATE 0x00000400 +#define WIFI_SITE_MONITOR 0x00000800 /* under site surveying */ +#define WIFI_WDS 0x00001000 +#define WIFI_WDS_RX_BEACON 0x00002000 /* already rx WDS AP beacon */ +#define WIFI_AUTOCONF 0x00004000 +#define WIFI_AUTOCONF_IND 0x00008000 +#define WIFI_MP_STATE 0x00010000 +#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */ +#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */ +#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */ +#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */ +#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */ +#define WIFI_MP_LPBK_STATE 0x00400000 +#define WIFI_OP_CH_SWITCHING 0x00800000 +/*#define WIFI_UNDEFINED_STATE 0x01000000*/ +/*#define WIFI_UNDEFINED_STATE 0x02000000*/ +/*#define WIFI_UNDEFINED_STATE 0x04000000*/ +/*#define WIFI_UNDEFINED_STATE 0x08000000*/ +/*#define WIFI_UNDEFINED_STATE 0x10000000*/ +/*#define WIFI_UNDEFINED_STATE 0x20000000*/ +/*#define WIFI_UNDEFINED_STATE 0x40000000*/ +#define WIFI_MONITOR_STATE 0x80000000 + +#define MIRACAST_DISABLED 0 +#define MIRACAST_SOURCE BIT0 +#define MIRACAST_SINK BIT1 + +#define MIRACAST_MODE_REVERSE(mode) \ + ((((mode) & MIRACAST_SOURCE) ? MIRACAST_SINK : 0) | (((mode) & MIRACAST_SINK) ? MIRACAST_SOURCE : 0)) + +bool is_miracast_enabled(_adapter *adapter); +bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode); +const char *get_miracast_mode_str(int mode); +void rtw_wfd_st_switch(struct sta_info *sta, bool on); + +#define MLME_STATE(adapter) get_fwstate(&((adapter)->mlmepriv)) + +#define MLME_IS_STA(adapter) (MLME_STATE((adapter)) & WIFI_STATION_STATE) +#define MLME_IS_AP(adapter) (MLME_STATE((adapter)) & WIFI_AP_STATE) +#define MLME_IS_ADHOC(adapter) (MLME_STATE((adapter)) & WIFI_ADHOC_STATE) +#define MLME_IS_ADHOC_MASTER(adapter) (MLME_STATE((adapter)) & WIFI_ADHOC_MASTER_STATE) +#define MLME_IS_MONITOR(adapter) (MLME_STATE((adapter)) & WIFI_MONITOR_STATE) +#define MLME_IS_MP(adapter) (MLME_STATE((adapter)) & WIFI_MP_STATE) +#ifdef CONFIG_P2P +#define MLME_IS_GC(adapter) rtw_p2p_chk_role(&(adapter)->wdinfo, P2P_ROLE_CLIENT) +#define MLME_IS_GO(adapter) rtw_p2p_chk_role(&(adapter)->wdinfo, P2P_ROLE_GO) +#else /* !CONFIG_P2P */ +#define MLME_IS_GC(adapter) 0 +#define MLME_IS_GO(adapter) 0 +#endif /* !CONFIG_P2P */ +#define MLME_IS_MSRC(adapter) rtw_chk_miracast_mode((adapter), MIRACAST_SOURCE) +#define MLME_IS_MSINK(adapter) rtw_chk_miracast_mode((adapter), MIRACAST_SINK) + +#define MLME_STATE_FMT "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" +#define MLME_STATE_ARG(adapter) \ + MLME_IS_STA((adapter)) ? (MLME_IS_GC((adapter)) ? " GC" : " STA") : "", \ + MLME_IS_AP((adapter)) ? (MLME_IS_GO((adapter)) ? " GO" : " AP") : "", \ + MLME_IS_ADHOC((adapter)) ? " ADHOC" : "", \ + MLME_IS_ADHOC_MASTER((adapter)) ? " ADHOC_M" : "", \ + MLME_IS_MONITOR((adapter)) ? " MONITOR" : "", \ + MLME_IS_MP((adapter)) ? " MP" : "", \ + MLME_IS_MSRC((adapter)) ? " MSRC" : "", \ + MLME_IS_MSINK((adapter)) ? " MSINK" : "", \ + (MLME_STATE((adapter)) & WIFI_SITE_MONITOR) ? " SCAN" : "", \ + (MLME_STATE((adapter)) & WIFI_UNDER_LINKING) ? " LINKING" : "", \ + (MLME_STATE((adapter)) & WIFI_ASOC_STATE) ? " ASOC" : "", \ + (MLME_STATE((adapter)) & WIFI_OP_CH_SWITCHING) ? " OP_CH_SW" : "", \ + (MLME_STATE((adapter)) & WIFI_UNDER_WPS) ? " WPS" : "", \ + (MLME_STATE((adapter)) & WIFI_SLEEP_STATE) ? " SLEEP" : "" + +#define _FW_UNDER_LINKING WIFI_UNDER_LINKING +#define _FW_LINKED WIFI_ASOC_STATE +#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR + + +enum dot11AuthAlgrthmNum { + dot11AuthAlgrthm_Open = 0, + dot11AuthAlgrthm_Shared, + dot11AuthAlgrthm_8021X, + dot11AuthAlgrthm_Auto, + dot11AuthAlgrthm_WAPI, + dot11AuthAlgrthm_MaxNum +}; + +// Scan type including active and passive scan. +typedef enum _RT_SCAN_TYPE +{ + SCAN_PASSIVE, + SCAN_ACTIVE, + SCAN_MIX, +}RT_SCAN_TYPE, *PRT_SCAN_TYPE; + +#define WIFI_FREQUENCY_BAND_AUTO 0 +#define WIFI_FREQUENCY_BAND_5GHZ 1 +#define WIFI_FREQUENCY_BAND_2GHZ 2 + +#define rtw_band_valid(band) ((band) <= WIFI_FREQUENCY_BAND_2GHZ) + +enum DriverInterface { + DRIVER_WEXT = 1, + DRIVER_CFG80211 = 2 +}; + +enum SCAN_RESULT_TYPE +{ + SCAN_RESULT_P2P_ONLY = 0, // Will return all the P2P devices. + SCAN_RESULT_ALL = 1, // Will return all the scanned device, include AP. + SCAN_RESULT_WFD_TYPE = 2 // Will just return the correct WFD device. + // If this device is Miracast sink device, it will just return all the Miracast source devices. +}; + +/* + +there are several "locks" in mlme_priv, +since mlme_priv is a shared resource between many threads, +like ISR/Call-Back functions, the OID handlers, and even timer functions. + + +Each _queue has its own locks, already. +Other items are protected by mlme_priv.lock. + +To avoid possible dead lock, any thread trying to modifiying mlme_priv +SHALL not lock up more than one locks at a time! + +*/ + + +#define traffic_threshold 10 +#define traffic_scan_period 500 + +struct sitesurvey_ctrl { + u64 last_tx_pkts; + uint last_rx_pkts; + sint traffic_busy; + _timer sitesurvey_ctrl_timer; +}; + +typedef struct _RT_LINK_DETECT_T{ + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + u32 NumRxUnicastOkInPeriod; + BOOLEAN bBusyTraffic; + BOOLEAN bTxBusyTraffic; + BOOLEAN bRxBusyTraffic; + BOOLEAN bHigherBusyTraffic; // For interrupt migration purpose. + BOOLEAN bHigherBusyRxTraffic; // We may disable Tx interrupt according as Rx traffic. + BOOLEAN bHigherBusyTxTraffic; // We may disable Tx interrupt according as Tx traffic. + //u8 TrafficBusyState; + u8 TrafficTransitionCount; + u32 LowPowerTransitionCount; +}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; + +struct profile_info { + u8 ssidlen; + u8 ssid[ WLAN_SSID_MAXLEN ]; + u8 peermac[ ETH_ALEN ]; +}; + +struct tx_invite_req_info{ + u8 token; + u8 benable; + u8 go_ssid[ WLAN_SSID_MAXLEN ]; + u8 ssidlen; + u8 go_bssid[ ETH_ALEN ]; + u8 peer_macaddr[ ETH_ALEN ]; + u8 operating_ch; // This information will be set by using the p2p_set op_ch=x + u8 peer_ch; // The listen channel for peer P2P device + +}; + +struct tx_invite_resp_info{ + u8 token; // Used to record the dialog token of p2p invitation request frame. +}; + +#ifdef CONFIG_WFD + +struct wifi_display_info{ + u16 wfd_enable; // Eanble/Disable the WFD function. + u16 init_rtsp_ctrlport; /* init value of rtsp_ctrlport when WFD enable */ + u16 rtsp_ctrlport; /* TCP port number at which the this WFD device listens for RTSP messages, 0 when WFD disable */ + u16 tdls_rtsp_ctrlport; /* rtsp_ctrlport used by tdls, will sync when rtsp_ctrlport is changed by user */ + u16 peer_rtsp_ctrlport; // TCP port number at which the peer WFD device listens for RTSP messages + // This filed should be filled when receiving the gropu negotiation request + + u8 peer_session_avail; // WFD session is available or not for the peer wfd device. + // This variable will be set when sending the provisioning discovery request to peer WFD device. + // And this variable will be reset when it is read by using the iwpriv p2p_get wfd_sa command. + u8 ip_address[4]; + u8 peer_ip_address[4]; + u8 wfd_pc; // WFD preferred connection + // 0 -> Prefer to use the P2P for WFD connection on peer side. + // 1 -> Prefer to use the TDLS for WFD connection on peer side. + + u8 wfd_device_type; // WFD Device Type + // 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 op_wfd_mode; + u8 stack_wfd_mode; +}; +#endif //CONFIG_WFD + +struct tx_provdisc_req_info{ + u16 wps_config_method_request; // Used when sending the provisioning request frame + u16 peer_channel_num[2]; // The channel number which the receiver stands. + NDIS_802_11_SSID ssid; + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 peerIFAddr[ ETH_ALEN ]; // Peer interface address + u8 benable; // This provision discovery request frame is trigger to send or not +}; + +struct rx_provdisc_req_info{ //When peer device issue prov_disc_req first, we should store the following informations + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 strconfig_method_desc_of_prov_disc_req[4]; // description for the config method located in the provisioning discovery request frame. + // The UI must know this information to know which config method the remote p2p device is requiring. +}; + +struct tx_nego_req_info{ + u16 peer_channel_num[2]; // The channel number which the receiver stands. + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 benable; // This negoitation request frame is trigger to send or not + u8 peer_ch; /* The listen channel for peer P2P device */ +}; + +struct group_id_info{ + u8 go_device_addr[ ETH_ALEN ]; // The GO's device address of this P2P group + u8 ssid[ WLAN_SSID_MAXLEN ]; // The SSID of this P2P group +}; + +struct scan_limit_info{ + u8 scan_op_ch_only; // When this flag is set, the driver should just scan the operation channel +#ifndef CONFIG_P2P_OP_CHK_SOCIAL_CH + u8 operation_ch[2]; // Store the operation channel of invitation request frame +#else + u8 operation_ch[5]; // Store additional channel 1,6,11 for Android 4.2 IOT & Nexus 4 +#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH +}; + +#ifdef CONFIG_IOCTL_CFG80211 +struct cfg80211_wifidirect_info{ + _timer remain_on_ch_timer; + 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; + _timer restore_p2p_state_timer; + + // Used to do the scanning. After confirming the peer is availalble, the driver transmits the P2P frame to peer. + _timer pre_tx_scan_timer; + _timer reset_ch_sitesurvey; + _timer reset_ch_sitesurvey2; // Just for resetting the scan limit function by using p2p nego +#ifdef CONFIG_CONCURRENT_MODE + // Used to switch the channel between legacy AP and listen state. + _timer ap_p2p_switch_timer; +#endif + struct tx_provdisc_req_info tx_prov_disc_info; + struct rx_provdisc_req_info rx_prov_disc_info; + struct tx_invite_req_info invitereq_info; + struct profile_info profileinfo[ P2P_MAX_PERSISTENT_GROUP_NUM ]; // Store the profile information of persistent group + struct tx_invite_resp_info inviteresp_info; + struct tx_nego_req_info nego_req_info; + struct group_id_info groupid_info; // Store the group id information when doing the group negotiation handshake. + struct scan_limit_info rx_invitereq_info; // Used for get the limit scan channel from the Invitation procedure + struct scan_limit_info p2p_info; // Used for get the limit scan channel from the P2P negotiation handshake +#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; + u8 device_addr[ETH_ALEN]; // The device address should be the mac address of this device. + u8 interface_addr[ETH_ALEN]; + u8 social_chan[4]; + u8 listen_channel; + u8 operating_channel; + u8 listen_dwell; // This value should be between 1 and 3 + u8 support_rate[8]; + u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; + u8 intent; // should only include the intent value. + u8 p2p_peer_interface_addr[ ETH_ALEN ]; + u8 p2p_peer_device_addr[ ETH_ALEN ]; + u8 peer_intent; // Included the intent value and tie breaker value. + u8 device_name[ WPS_MAX_DEVICE_NAME_LEN ]; // Device name for displaying on searching device screen + u8 device_name_len; + u8 profileindex; // Used to point to the index of profileinfo array + u8 peer_operating_ch; + u8 find_phase_state_exchange_cnt; + u16 device_password_id_for_nego; // The device password ID for group negotation + u8 negotiation_dialog_token; + u8 nego_ssid[ WLAN_SSID_MAXLEN ]; // SSID information for group negotitation + u8 nego_ssidlen; + u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; + u8 p2p_group_ssid_len; + u8 persistent_supported; // Flag to know the persistent function should be supported or not. + // In the Sigma test, the Sigma will provide this enable from the sta_set_p2p CAPI. + // 0: disable + // 1: enable + u8 session_available; // Flag to set the WFD session available to enable or disable "by Sigma" + // In the Sigma test, the Sigma will disable the session available by using the sta_preset CAPI. + // 0: disable + // 1: enable + + u8 wfd_tdls_enable; // Flag to enable or disable the TDLS by WFD Sigma + // 0: disable + // 1: enable + u8 wfd_tdls_weaksec; // Flag to enable or disable the weak security function for TDLS by WFD Sigma + // 0: disable + // In this case, the driver can't issue the tdsl setup request frame. + // 1: enable + // In this case, the driver can issue the tdls setup request frame + // even the current security is weak security. + + enum P2P_WPSINFO ui_got_wps_info; // This field will store the WPS value (PIN value or PBC) that UI had got from the user. + u16 supported_wps_cm; // This field describes the WPS config method which this driver supported. + // The value should be the combination of config method defined in page104 of WPS v2.0 spec. + u8 external_uuid; // UUID flag + u8 uuid[16]; // UUID + uint channel_list_attr_len; // This field will contain the length of body of P2P Channel List attribute of group negotitation response frame. + u8 channel_list_attr[100]; // This field will contain the body of P2P Channel List attribute of group negotitation response frame. + // We will use the channel_cnt and channel_list fields when constructing the group negotitation confirm frame. + u8 driver_interface; // Indicate DRIVER_WEXT or DRIVER_CFG80211 + +#ifdef CONFIG_CONCURRENT_MODE + u16 ext_listen_interval; // The interval to be available with legacy AP (ms) + u16 ext_listen_period; // The time period to be available for P2P listen state (ms) +#endif +#ifdef CONFIG_P2P_PS + enum P2P_PS_MODE p2p_ps_mode; // indicate p2p ps mode + enum P2P_PS_STATE p2p_ps_state; // indicate p2p ps state + u8 noa_index; // Identifies and instance of Notice of Absence timing. + u8 ctwindow; // Client traffic window. A period of time in TU after TBTT. + u8 opp_ps; // opportunistic power save. + u8 noa_num; // number of NoA descriptor in P2P IE. + u8 noa_count[P2P_MAX_NOA_NUM]; // Count for owner, Type of client. + u32 noa_duration[P2P_MAX_NOA_NUM]; // Max duration for owner, preferred or min acceptable duration for client. + u32 noa_interval[P2P_MAX_NOA_NUM]; // Length of interval for owner, preferred or max acceptable interval of client. + u32 noa_start_time[P2P_MAX_NOA_NUM]; // schedule expressed in terms of the lower 4 bytes of the TSF timer. +#endif // CONFIG_P2P_PS +}; + +struct tdls_ss_record{ //signal strength record + u8 macaddr[ETH_ALEN]; + u8 RxPWDBAll; + u8 is_tdls_sta; // _TRUE: direct link sta, _FALSE: else +}; + +struct tdls_temp_mgmt{ + u8 initiator; // 0: None, 1: we initiate, 2: peer initiate + u8 peer_addr[ETH_ALEN]; +}; + +#ifdef CONFIG_TDLS_CH_SW +struct tdls_ch_switch{ + u32 ch_sw_state; + ATOMIC_T chsw_on; + u8 addr[ETH_ALEN]; + u8 off_ch_num; + u8 ch_offset; + u32 cur_time; + u8 delay_switch_back; + u8 dump_stack; +}; +#endif + +struct tdls_info{ + u8 ap_prohibited; + u8 ch_switch_prohibited; + u8 link_established; + u8 sta_cnt; + u8 sta_maximum; /* 1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; */ + struct tdls_ss_record ss_record; +#ifdef CONFIG_TDLS_CH_SW + struct tdls_ch_switch chsw_info; +#endif + + u8 ch_sensing; + u8 cur_channel; + u8 collect_pkt_num[MAX_CHANNEL_NUM]; + _lock cmd_lock; + _lock hdl_lock; + u8 watchdog_count; + u8 dev_discovered; /* WFD_TDLS: for sigma test */ + u8 tdls_enable; + + /* Let wpa_supplicant to setup*/ + u8 driver_setup; +#ifdef CONFIG_WFD + struct wifi_display_info *wfd_info; +#endif +}; + +struct tdls_txmgmt { + u8 peer[ETH_ALEN]; + u8 action_code; + u8 dialog_token; + u16 status_code; + u8 *buf; + size_t len; +}; + +/* used for mlme_priv.roam_flags */ +enum { + RTW_ROAM_ON_EXPIRED = BIT0, + RTW_ROAM_ON_RESUME = BIT1, + 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; + sint fw_state; //shall we protect this variable? maybe not necessarily... + u8 bScanInProcess; + u8 to_join; //flag + #ifdef CONFIG_LAYER2_ROAMING + u8 to_roam; /* roaming trying times */ + struct wlan_network *roam_network; /* the target of active roam */ + u8 roam_flags; + u8 roam_rssi_diff_th; /* rssi difference threshold for active scan candidate selection */ + u32 roam_scan_int_ms; /* scan interval for active roam */ + u32 roam_scanr_exp_ms; /* scan result expire time in ms for roam */ + u8 roam_tgt_addr[ETH_ALEN]; /* request to roam to speicific target without other consideration */ + #endif + + u8 *nic_hdl; + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + u8 not_indic_disco; + #endif + _list *pscanned; + _queue free_bss_pool; + _queue scanned_queue; + u8 *free_bss_buf; + u32 num_of_scanned; + + NDIS_802_11_SSID assoc_ssid; + u8 assoc_bssid[6]; + + 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 bGetGateway; + u8 gw_mac_addr[6]; + u8 gw_ip[4]; +#endif + + //uint wireless_mode; no used, remove it + + u32 auto_scan_int_ms; + + _timer assoc_timer; + + uint assoc_by_bssid; + uint assoc_by_rssi; + + _timer scan_to_timer; // driver itself handles scan_timeout status. + u32 scan_start_time; // used to evaluate the time spent in scanning + + #ifdef CONFIG_SET_SCAN_DENY_TIMER + _timer set_scan_deny_timer; + ATOMIC_T set_scan_deny; //0: allowed, 1: deny + #endif + + struct qos_priv qospriv; + +#ifdef CONFIG_80211N_HT + + /* Number of non-HT AP/stations */ + int num_sta_no_ht; + + /* Number of HT AP/stations 20 MHz */ + //int num_sta_ht_20mhz; + + + int num_FortyMHzIntolerant; + + struct ht_priv htpriv; + +#endif + +#ifdef CONFIG_80211AC_VHT + struct vht_priv vhtpriv; +#endif +#ifdef CONFIG_BEAMFORMING +#if (BEAMFORMING_SUPPORT == 0)/*for driver beamforming*/ + struct beamforming_info beamforming_info; +#endif +#endif + +#ifdef CONFIG_DFS + u8 handle_dfs; +#endif +#ifdef CONFIG_DFS_MASTER + /* TODO: move to rfctl */ + _timer dfs_master_timer; +#endif + + RT_LINK_DETECT_T LinkDetectInfo; + _timer dynamic_chk_timer; //dynamic/periodic check timer + + u8 acm_mask; // for wmm acm mask + const struct country_chplan *country_ent; + u8 ChannelPlan; + RT_SCAN_TYPE scan_mode; // active: 1, passive: 0 + + u8 *wps_probe_req_ie; + u32 wps_probe_req_ie_len; + + u8 ext_capab_ie_data[8];/*currently for ap mode only*/ + u8 ext_capab_ie_len; + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + /* Number of associated Non-ERP stations (i.e., stations using 802.11b + * in 802.11g BSS) */ + int num_sta_non_erp; + + /* Number of associated stations that do not support Short Slot Time */ + int num_sta_no_short_slot_time; + + /* Number of associated stations that do not support Short Preamble */ + int num_sta_no_short_preamble; + + int olbc; /* Overlapping Legacy BSS Condition (Legacy b/g)*/ + + /* Number of HT associated stations that do not support greenfield */ + int num_sta_ht_no_gf; + + /* Number of associated non-HT stations */ + //int num_sta_no_ht; + + /* Number of HT associated stations 20 MHz */ + int num_sta_ht_20mhz; + + /* number of associated stations 40MHz intolerant */ + int num_sta_40mhz_intolerant; + + /* Overlapping BSS information */ + int olbc_ht; + +#ifdef CONFIG_80211N_HT + int ht_20mhz_width_req; + int ht_intolerant_ch_reported; + u16 ht_op_mode; + u8 sw_to_20mhz; /*switch to 20Mhz BW*/ +#endif /* CONFIG_80211N_HT */ + + u8 *assoc_req; + u32 assoc_req_len; + u8 *assoc_rsp; + u32 assoc_rsp_len; + + u8 *wps_beacon_ie; + //u8 *wps_probe_req_ie; + u8 *wps_probe_resp_ie; + u8 *wps_assoc_resp_ie; // for CONFIG_IOCTL_CFG80211, this IE could include p2p ie / wfd ie + + u32 wps_beacon_ie_len; + //u32 wps_probe_req_ie_len; + u32 wps_probe_resp_ie_len; + u32 wps_assoc_resp_ie_len; // for CONFIG_IOCTL_CFG80211, this IE len could include p2p ie / wfd ie + + u8 *p2p_beacon_ie; + u8 *p2p_probe_req_ie; + u8 *p2p_probe_resp_ie; + u8 *p2p_go_probe_resp_ie; //for GO + u8 *p2p_assoc_req_ie; + u8 *p2p_assoc_resp_ie; + + u32 p2p_beacon_ie_len; + u32 p2p_probe_req_ie_len; + u32 p2p_probe_resp_ie_len; + u32 p2p_go_probe_resp_ie_len; //for GO + u32 p2p_assoc_req_ie_len; + u32 p2p_assoc_resp_ie_len; + + _lock bcn_update_lock; + u8 update_bcn; + + u8 ori_ch; + u8 ori_bw; + u8 ori_offset; +#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) + + u8 *wfd_beacon_ie; + u8 *wfd_probe_req_ie; + u8 *wfd_probe_resp_ie; + u8 *wfd_go_probe_resp_ie; //for GO + u8 *wfd_assoc_req_ie; + u8 *wfd_assoc_resp_ie; + + u32 wfd_beacon_ie_len; + u32 wfd_probe_req_ie_len; + u32 wfd_probe_resp_ie_len; + u32 wfd_go_probe_resp_ie_len; //for GO + u32 wfd_assoc_req_ie_len; + u32 wfd_assoc_resp_ie_len; + +#endif + +#ifdef RTK_DMP_PLATFORM + // DMP kobject_hotplug function signal need in passive level + _workitem Linkup_workitem; + _workitem Linkdown_workitem; +#endif + +#ifdef CONFIG_INTEL_WIDI + int widi_state; + int listen_state; + _timer listen_timer; + ATOMIC_T rx_probe_rsp; // 1:receive probe respone from RDS source. + u8 *l2sdTaBuffer; + u8 channel_idx; + u8 group_cnt; //In WiDi 3.5, they specified another scan algo. for WFD/RDS co-existed + u8 sa_ext[L2SDTA_SERVICE_VE_LEN]; + + u8 widi_enable; + /** + * For WiDi 4; upper layer would set + * p2p_primary_device_type_category_id + * p2p_primary_device_type_sub_category_id + * p2p_secondary_device_type_category_id + * p2p_secondary_device_type_sub_category_id + */ + u16 p2p_pdt_cid; + u16 p2p_pdt_scid; + u8 num_p2p_sdt; + u16 p2p_sdt_cid[MAX_NUM_P2P_SDT]; + u16 p2p_sdt_scid[MAX_NUM_P2P_SDT]; + u8 p2p_reject_disable; //When starting NL80211 wpa_supplicant/hostapd, it will call netdev_close + //such that it will cause p2p disabled. Use this flag to reject. +#endif // CONFIG_INTEL_WIDI + +#ifdef CONFIG_CONCURRENT_MODE + u8 scanning_via_buddy_intf; +#endif + +// u8 NumOfBcnInfoChkFail; +// u32 timeBcnInfoChkStart; +}; + +#define mlme_set_scan_to_timer(mlme, ms) \ + do { \ + /* DBG_871X("%s set_scan_to_timer(%p, %d)\n", __FUNCTION__, (mlme), (ms)); */ \ + _set_timer(&(mlme)->scan_to_timer, (ms)); \ + } while(0) + +#define rtw_mlme_set_auto_scan_int(adapter, ms) \ + do { \ + adapter->mlmepriv.auto_scan_int_ms = ms; \ + } while (0) + +void rtw_mlme_reset_auto_scan_int(_adapter *adapter); + +#ifdef CONFIG_AP_MODE + +struct hostapd_priv +{ + _adapter *padapter; + +#ifdef CONFIG_HOSTAPD_MLME + struct net_device *pmgnt_netdev; + struct usb_anchor anchored; +#endif + +}; + +extern int hostapd_mode_init(_adapter *padapter); +extern void hostapd_mode_unload(_adapter *padapter); +#endif + + +extern void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf); +extern void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_atimdone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_cpwm_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf); +#ifdef CONFIG_IEEE80211W +void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf); +#endif /* CONFIG_IEEE80211W */ +extern void rtw_join_timeout_handler(RTW_TIMER_HDL_ARGS); +extern void _rtw_scan_timeout_handler(RTW_TIMER_HDL_ARGS); + +thread_return event_thread(thread_context context); + +extern void rtw_free_network_queue(_adapter *adapter,u8 isfreeall); +extern int rtw_init_mlme_priv(_adapter *adapter);// (struct mlme_priv *pmlmepriv); + +extern void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv); + + +extern sint rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); +extern sint rtw_set_key(_adapter *adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx, bool enqueue); +extern sint rtw_set_auth(_adapter *adapter,struct security_priv *psecuritypriv); + +__inline static u8 *get_bssid(struct mlme_priv *pmlmepriv) +{ //if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid + // if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address + return pmlmepriv->cur_network.network.MacAddress; +} + +__inline static sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + if (pmlmepriv->fw_state & state) + return _TRUE; + + return _FALSE; +} + +__inline static sint get_fwstate(struct mlme_priv *pmlmepriv) +{ + return pmlmepriv->fw_state; +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + * + * ### NOTE:#### (!!!!) + * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock + */ +__inline static void set_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state |= state; + //FOR HW integration + if(_FW_UNDER_SURVEY==state){ + pmlmepriv->bScanInProcess = _TRUE; + } +} + +__inline static void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state &= ~state; + //FOR HW integration + if(_FW_UNDER_SURVEY==state){ + pmlmepriv->bScanInProcess = _FALSE; + } +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + */ +__inline static void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + _clr_fwstate_(pmlmepriv, state); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void up_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned++; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +#ifdef CONFIG_CONCURRENT_MODE +sint rtw_buddy_adapter_up(_adapter *padapter); +sint check_buddy_fwstate(_adapter *padapter, sint state); +u8 rtw_get_buddy_bBusyTraffic(_adapter *padapter); +#endif //CONFIG_CONCURRENT_MODE + +__inline static void down_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned--; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void set_scanned_network_val(struct mlme_priv *pmlmepriv, sint val) +{ + _irqL irqL; + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned = val; + _exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +extern u16 rtw_get_capability(WLAN_BSSID_EX *bss); +extern void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target); +extern void rtw_disconnect_hdl_under_linked(_adapter* adapter, struct sta_info *psta, u8 free_assoc); +extern void rtw_generate_random_ibss(u8 *pibss); +extern struct wlan_network* rtw_find_network(_queue *scanned_queue, u8 *addr); +extern struct wlan_network* rtw_get_oldest_wlan_network(_queue *scanned_queue); +struct wlan_network *_rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network); +struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network); + +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); + +void rtw_drv_scan_by_self(_adapter *padapter); +void rtw_scan_wait_completed(_adapter *adapter); +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); +extern int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len); +extern void rtw_init_registrypriv_dev_network(_adapter *adapter); + +extern void rtw_update_registrypriv_dev_network(_adapter *adapter); + +extern void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter); + +extern void _rtw_join_timeout_handler(_adapter *adapter); +extern void rtw_scan_timeout_handler(_adapter *adapter); + +extern void rtw_dynamic_check_timer_handlder(_adapter *adapter); +#ifdef CONFIG_SET_SCAN_DENY_TIMER +bool rtw_is_scan_deny(_adapter *adapter); +void rtw_clear_scan_deny(_adapter *adapter); +void rtw_set_scan_deny_timer_hdl(_adapter *adapter); +void rtw_set_scan_deny(_adapter *adapter, u32 ms); +#else +#define rtw_is_scan_deny(adapter) _FALSE +#define rtw_clear_scan_deny(adapter) do {} while (0) +#define rtw_set_scan_deny_timer_hdl(adapter) do {} while (0) +#define rtw_set_scan_deny(adapter, ms) do {} while (0) +#endif + +void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); + +#define MLME_BEACON_IE 0 +#define MLME_PROBE_REQ_IE 1 +#define MLME_PROBE_RESP_IE 2 +#define MLME_GO_PROBE_RESP_IE 3 +#define MLME_ASSOC_REQ_IE 4 +#define MLME_ASSOC_RESP_IE 5 + +#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) +int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_len); +#endif + +extern int _rtw_init_mlme_priv(_adapter *padapter); +extern void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); + +extern int _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); + +//extern struct wlan_network* _rtw_dequeue_network(_queue *queue); + +extern struct wlan_network* _rtw_alloc_network(struct mlme_priv *pmlmepriv); + + +extern void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall); +extern void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork); + + +extern struct wlan_network* _rtw_find_network(_queue *scanned_queue, u8 *addr); + +extern void _rtw_free_network_queue(_adapter* padapter, u8 isfreeall); + +extern sint rtw_if_up(_adapter *padapter); + +sint rtw_linked_check(_adapter *padapter); + +u8 *rtw_get_capability_from_ie(u8 *ie); +u8 *rtw_get_timestampe_from_ie(u8 *ie); +u8 *rtw_get_beacon_interval_from_ie(u8 *ie); + + +void rtw_joinbss_reset(_adapter *padapter); + +#ifdef CONFIG_80211N_HT +void rtw_ht_use_default_setting(_adapter *padapter); +void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len); +unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel); +void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel); +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len); +#endif + +int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork); +int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature); + +#ifdef CONFIG_LAYER2_ROAMING +#define rtw_roam_flags(adapter) ((adapter)->mlmepriv.roam_flags) +#define rtw_chk_roam_flags(adapter, flags) ((adapter)->mlmepriv.roam_flags & flags) +#define rtw_clr_roam_flags(adapter, flags) \ + do { \ + ((adapter)->mlmepriv.roam_flags &= ~flags); \ + } while (0) + +#define rtw_set_roam_flags(adapter, flags) \ + do { \ + ((adapter)->mlmepriv.roam_flags |= flags); \ + } while (0) + +#define rtw_assign_roam_flags(adapter, flags) \ + do { \ + ((adapter)->mlmepriv.roam_flags = flags); \ + } while (0) + +void _rtw_roaming(_adapter *adapter, struct wlan_network *tgt_network); +void rtw_roaming(_adapter *adapter, struct wlan_network *tgt_network); +void rtw_set_to_roam(_adapter *adapter, u8 to_roam); +u8 rtw_dec_to_roam(_adapter *adapter); +u8 rtw_to_roam(_adapter *adapter); +int rtw_select_roaming_candidate(struct mlme_priv *pmlmepriv); +#else +#define rtw_roam_flags(adapter) 0 +#define rtw_chk_roam_flags(adapter, flags) 0 +#define rtw_clr_roam_flags(adapter, flags) do {} while (0) +#define rtw_set_roam_flags(adapter, flags) do {} while (0) +#define rtw_assign_roam_flags(adapter, flags) do {} while (0) +#define _rtw_roaming(adapter, tgt_network) do {} while(0) +#define rtw_roaming(adapter, tgt_network) do {} while(0) +#define rtw_set_to_roam(adapter, to_roam) do {} while(0) +#define rtw_dec_to_roam(adapter) 0 +#define rtw_to_roam(adapter) 0 +#define rtw_select_roaming_candidate(mlme) _FAIL +#endif /* CONFIG_LAYER2_ROAMING */ + +bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset); + +struct sta_media_status_rpt_cmd_parm { + struct sta_info *sta; + bool connected; +}; + +void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected); +u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected); +void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm); + +#ifdef CONFIG_INTEL_PROXIM +void rtw_proxim_enable(_adapter *padapter); +void rtw_proxim_disable(_adapter *padapter); +void rtw_proxim_send_packet(_adapter *padapter,u8 *pbuf,u16 len,u8 hw_rate); +#endif //CONFIG_INTEL_PROXIM + +#define IPV4_SRC(_iphdr) (((u8 *)(_iphdr)) + 12) +#define IPV4_DST(_iphdr) (((u8 *)(_iphdr)) + 16) +#define GET_IPV4_IHL(_iphdr) BE_BITS_TO_1BYTE(((u8 *)(_iphdr)) + 0, 0, 4) +#define GET_IPV4_PROTOCOL(_iphdr) BE_BITS_TO_1BYTE(((u8 *)(_iphdr)) + 9, 0, 8) +#define GET_IPV4_SRC(_iphdr) BE_BITS_TO_4BYTE(((u8 *)(_iphdr)) + 12, 0, 32) +#define GET_IPV4_DST(_iphdr) BE_BITS_TO_4BYTE(((u8 *)(_iphdr)) + 16, 0, 32) + +#define GET_UDP_SRC(_udphdr) BE_BITS_TO_2BYTE(((u8 *)(_udphdr)) + 0, 0, 16) +#define GET_UDP_DST(_udphdr) BE_BITS_TO_2BYTE(((u8 *)(_udphdr)) + 2, 0, 16) + +#define TCP_SRC(_tcphdr) (((u8 *)(_tcphdr)) + 0) +#define TCP_DST(_tcphdr) (((u8 *)(_tcphdr)) + 2) +#define GET_TCP_SRC(_tcphdr) BE_BITS_TO_2BYTE(((u8 *)(_tcphdr)) + 0, 0, 16) +#define GET_TCP_DST(_tcphdr) BE_BITS_TO_2BYTE(((u8 *)(_tcphdr)) + 2, 0, 16) +#define GET_TCP_SEQ(_tcphdr) BE_BITS_TO_4BYTE(((u8 *)(_tcphdr)) + 4, 0, 32) +#define GET_TCP_ACK_SEQ(_tcphdr) BE_BITS_TO_4BYTE(((u8 *)(_tcphdr)) + 8, 0, 32) +#define GET_TCP_DOFF(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 12, 4, 4) +#define GET_TCP_FIN(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 0, 1) +#define GET_TCP_SYN(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 1, 1) +#define GET_TCP_RST(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 2, 1) +#define GET_TCP_PSH(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 3, 1) +#define GET_TCP_ACK(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 4, 1) +#define GET_TCP_URG(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 5, 1) +#define GET_TCP_ECE(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 6, 1) +#define GET_TCP_CWR(_tcphdr) BE_BITS_TO_1BYTE(((u8 *)(_tcphdr)) + 13, 7, 1) + +#endif //__RTL871X_MLME_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme_ext.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme_ext.h new file mode 100644 index 00000000..85795bc3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mlme_ext.h @@ -0,0 +1,1226 @@ +/****************************************************************************** + * + * 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 __RTW_MLME_EXT_H_ +#define __RTW_MLME_EXT_H_ + + +// Commented by Albert 20101105 +// Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) +// The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. +// So, this driver tried to extend the dwell time for each scanning channel. +// This will increase the chance to receive the probe response from SoftAP. + +#define SURVEY_TO (100) +#define REAUTH_TO (300) //(50) +#define REASSOC_TO (300) //(50) +//#define DISCONNECT_TO (3000) +#define ADDBA_TO (2000) + +#define LINKED_TO (1) //unit:2 sec, 1x2=2 sec + +#define REAUTH_LIMIT (4) +#define REASSOC_LIMIT (4) +#define READDBA_LIMIT (2) + +#ifdef CONFIG_GSPI_HCI + #define ROAMING_LIMIT 5 +#else + #define ROAMING_LIMIT 8 +#endif +//#define IOCMD_REG0 0x10250370 +//#define IOCMD_REG1 0x10250374 +//#define IOCMD_REG2 0x10250378 + +//#define FW_DYNAMIC_FUN_SWITCH 0x10250364 + +//#define WRITE_BB_CMD 0xF0000001 +//#define SET_CHANNEL_CMD 0xF3000000 +//#define UPDATE_RA_CMD 0xFD0000A2 + +#define _HW_STATE_NOLINK_ 0x00 +#define _HW_STATE_ADHOC_ 0x01 +#define _HW_STATE_STATION_ 0x02 +#define _HW_STATE_AP_ 0x03 +#define _HW_STATE_MONITOR_ 0x04 + + +#define _1M_RATE_ 0 +#define _2M_RATE_ 1 +#define _5M_RATE_ 2 +#define _11M_RATE_ 3 +#define _6M_RATE_ 4 +#define _9M_RATE_ 5 +#define _12M_RATE_ 6 +#define _18M_RATE_ 7 +#define _24M_RATE_ 8 +#define _36M_RATE_ 9 +#define _48M_RATE_ 10 +#define _54M_RATE_ 11 + +/******************************************************** +MCS rate definitions +*********************************************************/ +#define MCS_RATE_1R (0x000000ff) +#define MCS_RATE_2R (0x0000ffff) +#define MCS_RATE_3R (0x00ffffff) +#define MCS_RATE_4R (0xffffffff) +#define MCS_RATE_2R_13TO15_OFF (0x00001fff) + + +extern unsigned char RTW_WPA_OUI[]; +extern unsigned char WMM_OUI[]; +extern unsigned char WPS_OUI[]; +extern unsigned char WFD_OUI[]; +extern unsigned char P2P_OUI[]; + +extern unsigned char WMM_INFO_OUI[]; +extern unsigned char WMM_PARA_OUI[]; + +typedef enum _RT_CHANNEL_DOMAIN +{ + /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */ + RTW_CHPLAN_FCC = 0x00, + RTW_CHPLAN_IC = 0x01, + RTW_CHPLAN_ETSI = 0x02, + RTW_CHPLAN_SPAIN = 0x03, + RTW_CHPLAN_FRANCE = 0x04, + RTW_CHPLAN_MKK = 0x05, + RTW_CHPLAN_MKK1 = 0x06, + RTW_CHPLAN_ISRAEL = 0x07, + RTW_CHPLAN_TELEC = 0x08, + RTW_CHPLAN_GLOBAL_DOAMIN = 0x09, + RTW_CHPLAN_WORLD_WIDE_13 = 0x0A, + RTW_CHPLAN_TAIWAN = 0x0B, + RTW_CHPLAN_CHINA = 0x0C, + RTW_CHPLAN_SINGAPORE_INDIA_MEXICO = 0x0D, + RTW_CHPLAN_KOREA = 0x0E, + RTW_CHPLAN_TURKEY = 0x0F, + RTW_CHPLAN_JAPAN = 0x10, + RTW_CHPLAN_FCC_NO_DFS = 0x11, + RTW_CHPLAN_JAPAN_NO_DFS = 0x12, + RTW_CHPLAN_WORLD_WIDE_5G = 0x13, + RTW_CHPLAN_TAIWAN_NO_DFS = 0x14, + + /* ===== 0x20 ~ 0x7F, new channel plan ===== */ + RTW_CHPLAN_WORLD_NULL = 0x20, + RTW_CHPLAN_ETSI1_NULL = 0x21, + RTW_CHPLAN_FCC1_NULL = 0x22, + RTW_CHPLAN_MKK1_NULL = 0x23, + RTW_CHPLAN_ETSI2_NULL = 0x24, + RTW_CHPLAN_FCC1_FCC1 = 0x25, + RTW_CHPLAN_WORLD_ETSI1 = 0x26, + RTW_CHPLAN_MKK1_MKK1 = 0x27, + RTW_CHPLAN_WORLD_KCC1 = 0x28, + RTW_CHPLAN_WORLD_FCC2 = 0x29, + RTW_CHPLAN_WORLD_FCC3 = 0x30, + RTW_CHPLAN_WORLD_FCC4 = 0x31, + RTW_CHPLAN_WORLD_FCC5 = 0x32, + RTW_CHPLAN_WORLD_FCC6 = 0x33, + RTW_CHPLAN_FCC1_FCC7 = 0x34, + RTW_CHPLAN_WORLD_ETSI2 = 0x35, + RTW_CHPLAN_WORLD_ETSI3 = 0x36, + RTW_CHPLAN_MKK1_MKK2 = 0x37, + RTW_CHPLAN_MKK1_MKK3 = 0x38, + RTW_CHPLAN_FCC1_NCC1 = 0x39, + RTW_CHPLAN_FCC1_NCC2 = 0x40, + RTW_CHPLAN_GLOBAL_NULL = 0x41, + RTW_CHPLAN_ETSI1_ETSI4 = 0x42, + RTW_CHPLAN_FCC1_FCC2 = 0x43, + RTW_CHPLAN_FCC1_NCC3 = 0x44, + RTW_CHPLAN_WORLD_ETSI5 = 0x45, + RTW_CHPLAN_FCC1_FCC8 = 0x46, + RTW_CHPLAN_WORLD_ETSI6 = 0x47, + RTW_CHPLAN_WORLD_ETSI7 = 0x48, + RTW_CHPLAN_WORLD_ETSI8 = 0x49, + RTW_CHPLAN_WORLD_ETSI9 = 0x50, + RTW_CHPLAN_WORLD_ETSI10 = 0x51, + RTW_CHPLAN_WORLD_ETSI11 = 0x52, + RTW_CHPLAN_FCC1_NCC4 = 0x53, + RTW_CHPLAN_WORLD_ETSI12 = 0x54, + RTW_CHPLAN_FCC1_FCC9 = 0x55, + RTW_CHPLAN_WORLD_ETSI13 = 0x56, + RTW_CHPLAN_FCC1_FCC10 = 0x57, + RTW_CHPLAN_MKK2_MKK4 = 0x58, + RTW_CHPLAN_WORLD_ETSI14 = 0x59, + + RTW_CHPLAN_MAX, + RTW_CHPLAN_REALTEK_DEFINE = 0x7F, +}RT_CHANNEL_DOMAIN, *PRT_CHANNEL_DOMAIN; + +typedef enum _RT_CHANNEL_DOMAIN_2G +{ + RTW_RD_2G_NULL = 0, + RTW_RD_2G_WORLD = 1, /* Worldwird 13 */ + RTW_RD_2G_ETSI1 = 2, /* Europe */ + RTW_RD_2G_FCC1 = 3, /* US */ + RTW_RD_2G_MKK1 = 4, /* Japan */ + RTW_RD_2G_ETSI2 = 5, /* France */ + RTW_RD_2G_GLOBAL = 6, /* Global domain */ + RTW_RD_2G_MKK2 = 7, /* Japan */ + + RTW_RD_2G_MAX, +}RT_CHANNEL_DOMAIN_2G, *PRT_CHANNEL_DOMAIN_2G; + +typedef enum _RT_CHANNEL_DOMAIN_5G +{ + RTW_RD_5G_NULL = 0, /* */ + RTW_RD_5G_ETSI1 = 1, /* Europe */ + RTW_RD_5G_ETSI2 = 2, /* Australia, New Zealand */ + RTW_RD_5G_ETSI3 = 3, /* Russia */ + RTW_RD_5G_FCC1 = 4, /* US */ + RTW_RD_5G_FCC2 = 5, /* FCC w/o DFS Channels */ + RTW_RD_5G_FCC3 = 6, /* Bolivia, Chile, El Salvador, Venezuela */ + RTW_RD_5G_FCC4 = 7, /* Venezuela */ + RTW_RD_5G_FCC5 = 8, /* China */ + RTW_RD_5G_FCC6 = 9, /* */ + RTW_RD_5G_FCC7 = 10, /* US Canada(w/o Weather radar) */ + RTW_RD_5G_KCC1 = 11, /* Korea */ + RTW_RD_5G_MKK1 = 12, /* Japan */ + RTW_RD_5G_MKK2 = 13, /* Japan (W52, W53) */ + RTW_RD_5G_MKK3 = 14, /* Japan (W56) */ + RTW_RD_5G_NCC1 = 15, /* Taiwan, (w/o Weather radar) */ + RTW_RD_5G_NCC2 = 16, /* Taiwan, Band2, Band4 */ + RTW_RD_5G_NCC3 = 17, /* Taiwan w/o DFS, Band4 only */ + RTW_RD_5G_ETSI4 = 18, /* Europe w/o DFS, Band1 only */ + RTW_RD_5G_ETSI5 = 19, /* Australia, New Zealand(w/o Weather radar) */ + RTW_RD_5G_FCC8 = 20, /* Latin America */ + RTW_RD_5G_ETSI6 = 21, /* Israel, Bahrain, Egypt, India, China, Malaysia */ + RTW_RD_5G_ETSI7 = 22, /* China */ + RTW_RD_5G_ETSI8 = 23, /* Jordan */ + RTW_RD_5G_ETSI9 = 24, /* Lebanon */ + RTW_RD_5G_ETSI10 = 25, /* Qatar */ + RTW_RD_5G_ETSI11 = 26, /* Russia */ + RTW_RD_5G_NCC4 = 27, /* Taiwan, (w/o Weather radar) */ + RTW_RD_5G_ETSI12 = 28, /* Indonesia */ + RTW_RD_5G_FCC9 = 29, /* (w/o Weather radar) */ + RTW_RD_5G_ETSI13 = 30, /* (w/o Weather radar) */ + RTW_RD_5G_FCC10 = 31, /* Argentina(w/o Weather radar) */ + RTW_RD_5G_MKK4 = 32, /* Japan (W52) */ + RTW_RD_5G_ETSI14 = 33, /* Russia */ + + /* === Below are driver defined for legacy channel plan compatible, DON'T assign index ==== */ + RTW_RD_5G_OLD_FCC1, + RTW_RD_5G_OLD_NCC1, + RTW_RD_5G_OLD_KCC1, + + RTW_RD_5G_MAX, +}RT_CHANNEL_DOMAIN_5G, *PRT_CHANNEL_DOMAIN_5G; + +bool rtw_chplan_is_empty(u8 id); +#define rtw_is_channel_plan_valid(chplan) (((chplan) < RTW_CHPLAN_MAX || (chplan) == RTW_CHPLAN_REALTEK_DEFINE) && !rtw_chplan_is_empty(chplan)) +#define rtw_is_legacy_channel_plan(chplan) ((chplan) < 0x20) + +typedef struct _RT_CHANNEL_PLAN +{ + unsigned char Channel[MAX_CHANNEL_NUM]; + unsigned char Len; +}RT_CHANNEL_PLAN, *PRT_CHANNEL_PLAN; + +typedef struct _RT_CHANNEL_PLAN_2G +{ + unsigned char Channel[MAX_CHANNEL_NUM_2G]; + unsigned char Len; +}RT_CHANNEL_PLAN_2G, *PRT_CHANNEL_PLAN_2G; + +typedef struct _RT_CHANNEL_PLAN_5G +{ + unsigned char Channel[MAX_CHANNEL_NUM_5G]; + unsigned char Len; +}RT_CHANNEL_PLAN_5G, *PRT_CHANNEL_PLAN_5G; + +typedef struct _RT_CHANNEL_PLAN_MAP +{ + u8 Index2G; + u8 Index5G; + u8 regd; /* value of REGULATION_TXPWR_LMT */ +}RT_CHANNEL_PLAN_MAP, *PRT_CHANNEL_PLAN_MAP; + +enum Associated_AP +{ + atherosAP = 0, + broadcomAP = 1, + ciscoAP = 2, + marvellAP = 3, + ralinkAP = 4, + realtekAP = 5, + airgocapAP = 6, + unknownAP = 7, + maxAP, +}; + +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_REALTEK_JAGUAR_BCUTAP = 16, + HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP = 17, + HT_IOT_PEER_MAX = 18 +}HT_IOT_PEER_E, *PHTIOT_PEER_E; + +struct mlme_handler { + unsigned int num; + char* str; + unsigned int (*func)(_adapter *padapter, union recv_frame *precv_frame); +}; + +struct action_handler { + unsigned int num; + char* str; + unsigned int (*func)(_adapter *padapter, union recv_frame *precv_frame); +}; + +enum SCAN_STATE +{ + SCAN_DISABLE = 0, + SCAN_START = 1, + SCAN_PS_ANNC_WAIT = 2, + SCAN_ENTER = 3, + SCAN_PROCESS = 4, + + /* backop */ + SCAN_BACKING_OP = 5, + SCAN_BACK_OP = 6, + SCAN_LEAVING_OP = 7, + SCAN_LEAVE_OP = 8, + + /* SW antenna diversity (before linked) */ + SCAN_SW_ANTDIV_BL = 9, + + /* legacy p2p */ + SCAN_TO_P2P_LISTEN = 10, + SCAN_P2P_LISTEN = 11, + + SCAN_COMPLETE = 12, + SCAN_STATE_MAX, +}; + +const char *scan_state_str(u8 state); + +enum ss_backop_flag { + SS_BACKOP_EN = BIT0, /* backop when linked */ + SS_BACKOP_EN_NL = BIT1, /* backop even when no linked */ + + SS_BACKOP_PS_ANNC = BIT4, + SS_BACKOP_TX_RESUME = BIT5, +}; + +struct ss_res { + u8 state; + u8 next_state; /* will set to state on next cmd hdl */ + int bss_cnt; + int channel_idx; + int scan_mode; + u16 scan_ch_ms; + u8 rx_ampdu_accept; + u8 rx_ampdu_size; +#ifdef CONFIG_SCAN_BACKOP + u8 backop_flags_sta; /* policy for station mode*/ + u8 backop_flags_ap; /* policy for ap mode */ + u8 backop_flags; /* per backop runtime decision */ + u8 scan_cnt; + u8 scan_cnt_max; + u32 backop_time; /* the start time of backop */ + u16 backop_ms; +#endif +#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL) + u8 is_sw_antdiv_bl_scan; +#endif + u8 ssid_num; + u8 ch_num; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; +}; + +//#define AP_MODE 0x0C +//#define STATION_MODE 0x08 +//#define AD_HOC_MODE 0x04 +//#define NO_LINK_MODE 0x00 + +#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_ +#define WIFI_FW_STATION_STATE _HW_STATE_STATION_ +#define WIFI_FW_AP_STATE _HW_STATE_AP_ +#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_ + +#define WIFI_FW_AUTH_NULL 0x00000100 +#define WIFI_FW_AUTH_STATE 0x00000200 +#define WIFI_FW_AUTH_SUCCESS 0x00000400 + +#define WIFI_FW_ASSOC_STATE 0x00002000 +#define WIFI_FW_ASSOC_SUCCESS 0x00004000 + +#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE | WIFI_FW_AUTH_SUCCESS |WIFI_FW_ASSOC_STATE) + +#ifdef CONFIG_TDLS +enum TDLS_option +{ + TDLS_ESTABLISHED = 1, + TDLS_ISSUE_PTI = 2, + TDLS_CH_SW_RESP = 3, + TDLS_CH_SW = 4, + TDLS_CH_SW_BACK = 5, + TDLS_RS_RCR = 6, + TDLS_TEAR_STA = 7, + maxTDLS, +}; + +#endif //CONFIG_TDLS + +/* + * Usage: + * When one iface acted as AP mode and the other iface is STA mode and scanning, + * it should switch back to AP's operating channel periodically. + * Parameters info: + * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to AP's operating channel for + * RTW_BACK_OP_CH_MS milliseconds. + * Example: + * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1, + * RTW_SCAN_NUM_OF_CH is 8, RTW_BACK_OP_CH_MS is 300 + * When it's STA mode gets set_scan command, + * it would + * 1. Doing the scan on channel 1.2.3.4.5.6.7.8 + * 2. Back to channel 1 for 300 milliseconds + * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52 + * 4. Back to channel 1 for 300 milliseconds + * 5. ... and so on, till survey done. + */ +#if defined(CONFIG_ATMEL_RC_PATCH) +#define RTW_SCAN_NUM_OF_CH 2 +#define RTW_BACK_OP_CH_MS 200 +#else +#define RTW_SCAN_NUM_OF_CH 3 +#define RTW_BACK_OP_CH_MS 400 +#endif + +struct mlme_ext_info +{ + u32 state; + u32 reauth_count; + u32 reassoc_count; + u32 link_count; + u32 auth_seq; + u32 auth_algo; // 802.11 auth, could be open, shared, auto + u32 authModeToggle; + u32 enc_algo;//encrypt algorithm; + u32 key_index; // this is only valid for legendary wep, 0~3 for key id. + u32 iv; + u8 chg_txt[128]; + u16 aid; + u16 bcn_interval; + u16 capability; + u8 assoc_AP_vendor; + u8 slotTime; + u8 preamble_mode; + u8 WMM_enable; + u8 ERP_enable; + u8 ERP_IE; + u8 HT_enable; + u8 HT_caps_enable; + u8 HT_info_enable; + u8 HT_protection; + u8 turboMode_cts2self; + u8 turboMode_rtsen; + u8 SM_PS; + u8 agg_enable_bitmap; + u8 ADDBA_retry_count; + u8 candidate_tid_bitmap; + u8 dialogToken; + // Accept ADDBA Request + BOOLEAN bAcceptAddbaReq; + u8 bwmode_updated; + u8 hidden_ssid_mode; + u8 VHT_enable; + + struct ADDBA_request ADDBA_req; + struct WMM_para_element WMM_param; + struct HT_caps_element HT_caps; + struct HT_info_element HT_info; + WLAN_BSSID_EX network;//join network or bss_network, if in ap mode, it is the same to cur_network.network +}; + +// The channel information about this channel including joining, scanning, and power constraints. +typedef struct _RT_CHANNEL_INFO +{ + u8 ChannelNum; // The channel number. + RT_SCAN_TYPE ScanType; // Scan type such as passive or active scan. + //u16 ScanPeriod; // Listen time in millisecond in this channel. + //s32 MaxTxPwrDbm; // Max allowed tx power. + //u32 ExInfo; // Extended Information for this channel. +#ifdef CONFIG_FIND_BEST_CHANNEL + u32 rx_count; +#endif +#ifdef CONFIG_DFS_MASTER + u32 non_ocp_end_time; +#endif +}RT_CHANNEL_INFO, *PRT_CHANNEL_INFO; + +#define DFS_MASTER_TIMER_MS 100 +#define CAC_TIME_MS (60*1000) +#define CAC_TIME_CE_MS (10*60*1000) +#define NON_OCP_TIME_MS (30*60*1000) + +#ifdef CONFIG_DFS_MASTER +struct rf_ctl_t; +#define CH_IS_NON_OCP(rt_ch_info) ((rt_ch_info)->non_ocp_end_time > rtw_get_current_time()) +void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl); +bool rtw_is_cac_reset_needed(_adapter *adapter); +bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset); +bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl); +bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl); +bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); +void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset); +void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms); +#else +#define CH_IS_NON_OCP(rt_ch_info) 0 +#define rtw_chset_is_ch_non_ocp(ch_set, ch, bw, offset) _FALSE +#define rtw_rfctl_is_tx_blocked_by_cac(rfctl) _FALSE +#endif + +enum { + RTW_CHF_2G = BIT0, + RTW_CHF_5G = BIT1, + RTW_CHF_DFS = BIT2, + RTW_CHF_LONG_CAC = BIT3, + RTW_CHF_NON_DFS = BIT4, + RTW_CHF_NON_LONG_CAC = BIT5, +}; +bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags); +void dump_country_chplan(void *sel, const struct country_chplan *ent); +void dump_country_chplan_map(void *sel); +void dump_chplan_id_list(void *sel); +void dump_chplan_test(void *sel); +void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set); +void dump_cur_chset(void *sel, _adapter *adapter); + +int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch); +bool rtw_mlme_band_check(_adapter *adapter, const u32 ch); + +// P2P_MAX_REG_CLASSES - Maximum number of regulatory classes +#define P2P_MAX_REG_CLASSES 10 + +// P2P_MAX_REG_CLASS_CHANNELS - Maximum number of channels per regulatory class +#define P2P_MAX_REG_CLASS_CHANNELS 20 + +// struct p2p_channels - List of supported channels +struct p2p_channels { + // struct p2p_reg_class - Supported regulatory class + struct p2p_reg_class { + // reg_class - Regulatory class (IEEE 802.11-2007, Annex J) + u8 reg_class; + + // channel - Supported channels + u8 channel[P2P_MAX_REG_CLASS_CHANNELS]; + + // channels - Number of channel entries in use + size_t channels; + } reg_class[P2P_MAX_REG_CLASSES]; + + // reg_classes - Number of reg_class entries in use + size_t reg_classes; +}; + +struct p2p_oper_class_map { + enum hw_mode {IEEE80211G,IEEE80211A} mode; + u8 op_class; + u8 min_chan; + u8 max_chan; + u8 inc; + enum { BW20, BW40PLUS, BW40MINUS } bw; +}; + +struct mlme_ext_priv +{ + _adapter *padapter; + u8 mlmeext_init; + ATOMIC_T event_seq; + u16 mgnt_seq; +#ifdef CONFIG_IEEE80211W + u16 sa_query_seq; + u64 mgnt_80211w_IPN; + u64 mgnt_80211w_IPN_rx; +#endif //CONFIG_IEEE80211W + //struct fw_priv fwpriv; + + unsigned char cur_channel; + unsigned char cur_bwmode; + unsigned char cur_ch_offset;//PRIME_CHNL_OFFSET + unsigned char cur_wireless_mode; // NETWORK_TYPE + + unsigned char max_chan_nums; + RT_CHANNEL_INFO channel_set[MAX_CHANNEL_NUM]; + struct p2p_channels channel_list; + unsigned char basicrate[NumRates]; + unsigned char datarate[NumRates]; +#ifdef CONFIG_80211N_HT + unsigned char default_supported_mcs_set[16]; +#endif + + struct ss_res sitesurvey_res; + struct mlme_ext_info mlmext_info;//for sta/adhoc mode, including current scanning/connecting/connected related info. + //for ap mode, network includes ap's cap_info + _timer survey_timer; + _timer link_timer; + + //_timer ADDBA_timer; + u32 last_scan_time; + u8 scan_abort; + u8 tx_rate; // TXRATE when USERATE is set. + + u32 retry; //retry for issue probereq + + u64 TSFValue; + + //for LPS-32K to adaptive bcn early and timeout + u8 adaptive_tsf_done; + u32 bcn_delay_cnt[9]; + u32 bcn_delay_ratio[9]; + u32 bcn_cnt; + u8 DrvBcnEarly; + u8 DrvBcnTimeOut; + +#ifdef CONFIG_AP_MODE + unsigned char bstart_bss; +#endif + +#ifdef CONFIG_80211D + u8 update_channel_plan_by_ap_done; +#endif + //recv_decache check for Action_public frame + u8 action_public_dialog_token; + u16 action_public_rxseq; + +//#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK + u8 active_keep_alive_check; +//#endif +#ifdef DBG_FIXED_CHAN + u8 fixed_chan; +#endif + /* set hw sync bcn tsf register or not */ + u8 en_hw_update_tsf; +}; + +#define mlmeext_msr(mlmeext) ((mlmeext)->mlmext_info.state & 0x03) +#define mlmeext_scan_state(mlmeext) ((mlmeext)->sitesurvey_res.state) +#define mlmeext_scan_state_str(mlmeext) scan_state_str((mlmeext)->sitesurvey_res.state) +#define mlmeext_chk_scan_state(mlmeext, _state) ((mlmeext)->sitesurvey_res.state == (_state)) +#define mlmeext_set_scan_state(mlmeext, _state) \ + do { \ + ((mlmeext)->sitesurvey_res.state = (_state)); \ + ((mlmeext)->sitesurvey_res.next_state = (_state)); \ + /* DBG_871X("set_scan_state:%s\n", scan_state_str(_state)); */ \ + } while (0) + +#define mlmeext_scan_next_state(mlmeext) ((mlmeext)->sitesurvey_res.next_state) +#define mlmeext_set_scan_next_state(mlmeext, _state) \ + do { \ + ((mlmeext)->sitesurvey_res.next_state = (_state)); \ + /* DBG_871X("set_scan_next_state:%s\n", scan_state_str(_state)); */ \ + } while (0) + +#ifdef CONFIG_SCAN_BACKOP +#define mlmeext_scan_backop_flags(mlmeext) ((mlmeext)->sitesurvey_res.backop_flags) +#define mlmeext_chk_scan_backop_flags(mlmeext, flags) ((mlmeext)->sitesurvey_res.backop_flags & (flags)) +#define mlmeext_assign_scan_backop_flags(mlmeext, flags) \ + do { \ + ((mlmeext)->sitesurvey_res.backop_flags = (flags)); \ + DBG_871X("assign_scan_backop_flags:0x%02x\n", (mlmeext)->sitesurvey_res.backop_flags); \ + } while (0) + +#define mlmeext_scan_backop_flags_sta(mlmeext) ((mlmeext)->sitesurvey_res.backop_flags_sta) +#define mlmeext_chk_scan_backop_flags_sta(mlmeext, flags) ((mlmeext)->sitesurvey_res.backop_flags_sta & (flags)) +#define mlmeext_assign_scan_backop_flags_sta(mlmeext, flags) \ + do { \ + ((mlmeext)->sitesurvey_res.backop_flags_sta = (flags)); \ + } while (0) + +#define mlmeext_scan_backop_flags_ap(mlmeext) ((mlmeext)->sitesurvey_res.backop_flags_ap) +#define mlmeext_chk_scan_backop_flags_ap(mlmeext, flags) ((mlmeext)->sitesurvey_res.backop_flags_ap & (flags)) +#define mlmeext_assign_scan_backop_flags_ap(mlmeext, flags) \ + do { \ + ((mlmeext)->sitesurvey_res.backop_flags_ap = (flags)); \ + } while (0) +#else +#define mlmeext_scan_backop_flags(mlmeext) (0) +#define mlmeext_chk_scan_backop_flags(mlmeext, flags) (0) +#define mlmeext_assign_scan_backop_flags(mlmeext, flags) do {} while (0) + +#define mlmeext_scan_backop_flags_sta(mlmeext) (0) +#define mlmeext_chk_scan_backop_flags_sta(mlmeext, flags) (0) +#define mlmeext_assign_scan_backop_flags_sta(mlmeext, flags) do {} while (0) + +#define mlmeext_scan_backop_flags_ap(mlmeext) (0) +#define mlmeext_chk_scan_backop_flags_ap(mlmeext, flags) (0) +#define mlmeext_assign_scan_backop_flags_ap(mlmeext, flags) do {} while (0) +#endif + +void init_mlme_default_rate_set(_adapter* padapter); +int init_mlme_ext_priv(_adapter* padapter); +int init_hw_mlme_ext(_adapter *padapter); +void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); +extern void init_mlme_ext_timer(_adapter *padapter); +extern void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta); +extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); +struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv); + +//void fill_fwpriv(_adapter * padapter, struct fw_priv *pfwpriv); + +unsigned char networktype_to_raid(_adapter *adapter,struct sta_info *psta); +unsigned char networktype_to_raid_ex(_adapter *adapter, struct sta_info *psta); + +u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen); +void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len); +void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask); +void UpdateBrateTbl(_adapter *padapter,u8 *mBratesOS); +void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen); +void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch); + +//void Set_NETYPE1_MSR(_adapter *padapter, u8 type); +//void Set_NETYPE0_MSR(_adapter *padapter, u8 type); +void Set_MSR(_adapter *padapter, u8 type); + +u8 rtw_get_oper_ch(_adapter *adapter); +void rtw_set_oper_ch(_adapter *adapter, u8 ch); +u8 rtw_get_oper_bw(_adapter *adapter); +void rtw_set_oper_bw(_adapter *adapter, u8 bw); +u8 rtw_get_oper_choffset(_adapter *adapter); +void rtw_set_oper_choffset(_adapter *adapter, u8 offset); +u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset); +u32 rtw_get_on_oper_ch_time(_adapter *adapter); +u32 rtw_get_on_cur_ch_time(_adapter *adapter); + +u8 rtw_get_offset_by_ch(u8 channel); + +void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode); +void SelectChannel(_adapter *padapter, unsigned char channel); +void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset); + +unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); + +void _clear_cam_entry(_adapter *padapter, u8 entry); +void write_cam_from_cache(_adapter *adapter, u8 id); + +/* modify both HW and cache */ +void write_cam(_adapter *padapter, u8 id, u16 ctrl, u8 *mac, u8 *key); +void clear_cam_entry(_adapter *padapter, u8 id); + +/* modify cache only */ +void write_cam_cache(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key); +void clear_cam_cache(_adapter *adapter, u8 id); + +void invalidate_cam_all(_adapter *padapter); +void CAM_empty_entry(PADAPTER Adapter, u8 ucIndex); + +void flush_all_cam_entry(_adapter *padapter); + +BOOLEAN IsLegal5GChannel(PADAPTER Adapter, u8 channel); + +void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType); +u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid); +void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, _adapter * padapter, bool update_ie); + +int get_bsstype(unsigned short capability); +u8* get_my_bssid(WLAN_BSSID_EX *pnetwork); +u16 get_beacon_interval(WLAN_BSSID_EX *bss); + +int is_client_associated_to_ap(_adapter *padapter); +int is_client_associated_to_ibss(_adapter *padapter); +int is_IBSS_empty(_adapter *padapter); + +unsigned char check_assoc_AP(u8 *pframe, uint len); + +int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +#ifdef CONFIG_WFD +void rtw_process_wfd_ie(_adapter *adapter, u8 *ie, u8 ie_len, const char *tag); +void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag); +#endif +void WMMOnAssocRsp(_adapter *padapter); + +void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void HTOnAssocRsp(_adapter *padapter); + +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); + +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 +void update_capinfo(PADAPTER Adapter, u16 updateCap); +void update_wireless_mode(_adapter * padapter); +void update_tx_basic_rate(_adapter *padapter, u8 modulation); +void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode); +int rtw_ies_get_supported_rate(u8 *ies, uint ies_len, u8 *rate_set, u8 *rate_num); + +//for sta/adhoc mode +void update_sta_info(_adapter *padapter, struct sta_info *psta); +unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz); +unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz); +unsigned int update_MCS_rate(struct HT_caps_element *pHT_caps); +void Update_RA_Entry(_adapter *padapter, struct sta_info *psta); +void set_sta_rate(_adapter *padapter, struct sta_info *psta); + +unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason); + +unsigned char get_highest_rate_idx(u32 mask); +int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode); +unsigned int is_ap_in_tkip(_adapter *padapter); +unsigned int is_ap_in_wep(_adapter *padapter); +unsigned int should_forbid_n_rate(_adapter * padapter); + +s16 rtw_get_camid(_adapter *adapter, struct sta_info* sta, s16 kid); +bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap); +void _rtw_camctl_set_flags(_adapter *adapter, u32 flags); +void rtw_camctl_set_flags(_adapter *adapter, u32 flags); +void _rtw_camctl_clr_flags(_adapter *adapter, u32 flags); +void rtw_camctl_clr_flags(_adapter *adapter, u32 flags); +bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags); + +struct sec_cam_bmp; +void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num); +void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map); + +bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id); +bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id); +s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk); +s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, bool *used); +void rtw_camid_free(_adapter *adapter, u8 cam_id); + +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_set_h2c_msr(struct macid_ctl_t *macid_ctl, u8 id, u8 h2c_msr); +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); +void report_surveydone_event(_adapter *padapter); +void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue); +void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr); +bool rtw_port_switch_chk(_adapter *adapter); +void report_wmm_edca_update(_adapter *padapter); + +void beacon_timing_control(_adapter *padapter); +u8 chk_bmc_sleepq_cmd(_adapter* padapter); +extern u8 set_tx_beacon_cmd(_adapter*padapter); +unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame); +void update_mgnt_tx_rate(_adapter *padapter, u8 rate); +void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe); +void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); +s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms); +s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe); + +#ifdef CONFIG_P2P +void issue_probersp_p2p(_adapter *padapter, unsigned char *da); +void issue_p2p_provision_request( _adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr); +void issue_p2p_GO_request(_adapter *padapter, u8* raddr); +void issue_probereq_p2p(_adapter *padapter, u8 *da); +int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms); +void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 success); +void issue_p2p_invitation_request(_adapter *padapter, u8* raddr ); +#endif //CONFIG_P2P +void issue_beacon(_adapter *padapter, int timeout_ms); +void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq); +void issue_assocreq(_adapter *padapter); +void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type); +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, 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); +void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset); +void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid); +void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size); +void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator); +int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator, int try_cnt, int wait_ms); + +#ifdef CONFIG_IEEE80211W +void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type); +int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type); +extern void init_dot11w_expire_timer(_adapter *padapter, struct sta_info *psta); +#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_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid, u8 force); +unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid, u8 force); + +unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr); +unsigned int send_beacon(_adapter *padapter); + +void start_clnt_assoc(_adapter *padapter); +void start_clnt_auth(_adapter* padapter); +void start_clnt_join(_adapter* padapter); +void start_create_ibss(_adapter* padapter); + +unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame); +unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame); + +unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame); + +#define RX_AMPDU_ACCEPT_INVALID 0xFF +#define RX_AMPDU_SIZE_INVALID 0xFF + +enum rx_ampdu_reason { + RX_AMPDU_DRV_FIXED = 1, + RX_AMPDU_BTCOEX = 2, /* not used, because BTCOEX has its own variable management */ + RX_AMPDU_DRV_SCAN = 3, +}; +u8 rtw_rx_ampdu_size(_adapter *adapter); +bool rtw_rx_ampdu_is_accept(_adapter *adapter); +bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason); +bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason); +u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size); +u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size); +u16 rtw_rx_ampdu_apply(_adapter *adapter); + +unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame); +unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame); +#ifdef CONFIG_IEEE80211W +unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame); +#endif //CONFIG_IEEE80211W +unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame); + + +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, u8 from_timer); + +void _linked_info_dump(_adapter *padapter); + +void survey_timer_hdl (_adapter *padapter); +void link_timer_hdl (_adapter *padapter); +void addba_timer_hdl(struct sta_info *psta); +#ifdef CONFIG_IEEE80211W +void sa_query_timer_hdl(struct sta_info *psta); +#endif //CONFIG_IEEE80211W +//void reauth_timer_hdl(_adapter *padapter); +//void reassoc_timer_hdl(_adapter *padapter); + +#define set_survey_timer(mlmeext, ms) \ + do { \ + /*DBG_871X("%s set_survey_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms));*/ \ + _set_timer(&(mlmeext)->survey_timer, (ms)); \ + } while(0) + +#define set_link_timer(mlmeext, ms) \ + do { \ + /*DBG_871X("%s set_link_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms));*/ \ + _set_timer(&(mlmeext)->link_timer, (ms)); \ + } while(0) + +extern int cckrates_included(unsigned char *rate, int ratelen); +extern int cckratesonly_included(unsigned char *rate, int ratelen); + +extern void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr); + +extern void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); +extern void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext); +extern void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); +extern u8 traffic_status_watchdog(_adapter *padapter, u8 from_timer); + + +#ifdef CONFIG_CONCURRENT_MODE +sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state); +#endif + +void rtw_join_done_chk_ch(_adapter *padapter, int join_res); + +int rtw_chk_start_clnt_join(_adapter *padapter, u8 *ch, u8 *bw, u8 *offset); +int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset); +int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset); + +void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num + , u8 *ap_num, u8 *ld_ap_num); +void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num + , u8 *ap_num, u8 *ld_ap_num); + +struct cmd_hdl { + uint parmsize; + u8 (*h2cfuns)(struct _ADAPTER *padapter, u8 *pbuf); +}; + + +u8 read_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_rfreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_rfreg_hdl(_adapter *padapter, u8 *pbuf); + + +u8 NULL_hdl(_adapter *padapter, u8 *pbuf); +u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 disconnect_hdl(_adapter *padapter, u8 *pbuf); +u8 createbss_hdl(_adapter *padapter, u8 *pbuf); +u8 setopmode_hdl(_adapter *padapter, u8 *pbuf); +u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 setauth_hdl(_adapter *padapter, u8 *pbuf); +u8 setkey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 del_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf); + +u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf); +u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf); +u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf); +u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf); +u8 set_ch_hdl(_adapter *padapter, u8 *pbuf); +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); +u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf); + +#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, +#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, + +#ifdef _RTW_CMD_C_ + +struct cmd_hdl wlancmds[] = +{ + GEN_DRV_CMD_HANDLER(sizeof(struct readMAC_parm), rtw_getmacreg) /*0*/ + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/ + GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/ + GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) + GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ + + GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ + GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ + + GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ + GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ + GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/ + + 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 + +struct C2HEvent_Header +{ + +#ifdef CONFIG_LITTLE_ENDIAN + + unsigned int len:16; + unsigned int ID:8; + unsigned int seq:8; + +#elif defined(CONFIG_BIG_ENDIAN) + + unsigned int seq:8; + unsigned int ID:8; + unsigned int len:16; + +#else + +# error "Must be LITTLE or BIG Endian" + +#endif + + unsigned int rsvd; + +}; + +void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf); +void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf); + +enum rtw_c2h_event +{ + GEN_EVT_CODE(_Read_MACREG)=0, /*0*/ + GEN_EVT_CODE(_Read_BBREG), + GEN_EVT_CODE(_Read_RFREG), + GEN_EVT_CODE(_Read_EEPROM), + GEN_EVT_CODE(_Read_EFUSE), + GEN_EVT_CODE(_Read_CAM), /*5*/ + GEN_EVT_CODE(_Get_BasicRate), + GEN_EVT_CODE(_Get_DataRate), + GEN_EVT_CODE(_Survey), /*8*/ + GEN_EVT_CODE(_SurveyDone), /*9*/ + + GEN_EVT_CODE(_JoinBss) , /*10*/ + GEN_EVT_CODE(_AddSTA), + GEN_EVT_CODE(_DelSTA), + GEN_EVT_CODE(_AtimDone) , + GEN_EVT_CODE(_TX_Report), + GEN_EVT_CODE(_CCX_Report), /*15*/ + GEN_EVT_CODE(_DTM_Report), + GEN_EVT_CODE(_TX_Rate_Statistics), + GEN_EVT_CODE(_C2HLBK), + GEN_EVT_CODE(_FWDBG), + GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ + GEN_EVT_CODE(_ADDBA), + GEN_EVT_CODE(_C2HBCN), + GEN_EVT_CODE(_ReportPwrState), //filen: only for PCIE, USB + GEN_EVT_CODE(_CloseRF), //filen: only for PCIE, work around ASPM + GEN_EVT_CODE(_WMM), /*25*/ +#ifdef CONFIG_IEEE80211W + GEN_EVT_CODE(_TimeoutSTA), +#endif /* CONFIG_IEEE80211W */ + MAX_C2HEVT +}; + + +#ifdef _RTW_MLME_EXT_C_ + +static struct fwevent wlanevents[] = +{ + {0, rtw_dummy_event_callback}, /*0*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, &rtw_survey_event_callback}, /*8*/ + {sizeof (struct surveydone_event), &rtw_surveydone_event_callback}, /*9*/ + + {0, &rtw_joinbss_event_callback}, /*10*/ + {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, + {sizeof(struct stadel_event), &rtw_stadel_event_callback}, + {0, &rtw_atimdone_event_callback}, + {0, rtw_dummy_event_callback}, + {0, NULL}, /*15*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, rtw_fwdbg_event_callback}, + {0, NULL}, /*20*/ + {0, NULL}, + {0, NULL}, + {0, &rtw_cpwm_event_callback}, + {0, NULL}, + {0, &rtw_wmm_event_callback}, /*25*/ +#ifdef CONFIG_IEEE80211W + {sizeof(struct stadel_event), &rtw_sta_timeout_event_callback}, +#endif /* CONFIG_IEEE80211W */ + +}; + +#endif//_RTW_MLME_EXT_C_ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp.h new file mode 100644 index 00000000..ab832d91 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp.h @@ -0,0 +1,979 @@ +/****************************************************************************** + * + * 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 _RTW_MP_H_ +#define _RTW_MP_H_ + +#define RTWPRIV_VER_INFO 1 + +#define MAX_MP_XMITBUF_SZ 2048 +#define NR_MP_XMITFRAME 8 + +struct mp_xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + +#ifdef CONFIG_USB_HCI + + //insert urb, irp, and irpcnt info below... + //max frag_cnt = 8 + + u8 *mem_addr; + u32 sz[8]; + +#if defined(PLATFORM_OS_XP) || defined(PLATFORM_LINUX) + PURB pxmit_urb[8]; +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + + u8 bpending[8]; + sint ac_tag[8]; + sint last[8]; + uint irpcnt; + uint fragcnt; +#endif /* CONFIG_USB_HCI */ + + uint mem[(MAX_MP_XMITBUF_SZ >> 2)]; +}; + +struct mp_wiparam +{ + u32 bcompleted; + u32 act_type; + u32 io_offset; + u32 io_value; +}; + +typedef void(*wi_act_func)(void* padapter); + +#ifdef PLATFORM_WINDOWS +struct mp_wi_cntx +{ + u8 bmpdrv_unload; + + // Work Item + NDIS_WORK_ITEM mp_wi; + NDIS_EVENT mp_wi_evt; + _lock mp_wi_lock; + u8 bmp_wi_progress; + wi_act_func curractfunc; + // Variable needed in each implementation of CurrActFunc. + struct mp_wiparam param; +}; +#endif + +struct mp_tx +{ + u8 stop; + u32 count, sended; + u8 payload; + struct pkt_attrib attrib; + //struct tx_desc desc; + //u8 resvdtx[7]; + u8 desc[TXDESC_SIZE]; + u8 *pallocated_buf; + u8 *buf; + u32 buf_size, write_size; + _thread_hdl_ PktTxThread; +}; + +#define MP_MAX_LINES 1000 +#define MP_MAX_LINES_BYTES 256 +#define u1Byte u8 +#define s1Byte s8 +#define u4Byte u32 +#define s4Byte s32 +#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* + +#define UCHAR u8 +#define USHORT u16 +#define UINT u32 +#define ULONG u32 +#define PULONG u32* + +typedef struct _RT_PMAC_PKT_INFO { + UCHAR MCS; + UCHAR Nss; + UCHAR Nsts; + UINT N_sym; + UCHAR SIGA2B3; +} RT_PMAC_PKT_INFO, *PRT_PMAC_PKT_INFO; + +typedef struct _RT_PMAC_TX_INFO { + u8 bEnPMacTx:1; /* 0: Disable PMac 1: Enable PMac */ + u8 Mode:3; /* 0: Packet TX 3:Continuous TX */ + u8 Ntx:4; /* 0-7 */ + u8 TX_RATE; /* MPT_RATE_E */ + u8 TX_RATE_HEX; + u8 TX_SC; + u8 bSGI:1; + u8 bSPreamble:1; + u8 bSTBC:1; + u8 bLDPC:1; + u8 NDP_sound:1; + u8 BandWidth:3; /* 0: 20 1:40 2:80Mhz */ + u8 m_STBC; /* bSTBC + 1 */ + u8 PacketPeriod; + UINT PacketCount; + UINT PacketLength; + u8 PacketPattern; + u32 SFD; + u8 SignalField; + u8 ServiceField; + u8 LENGTH; + u8 CRC16[2]; + u8 LSIG[3]; + u8 HT_SIG[6]; + u8 VHT_SIG_A[6]; + u8 VHT_SIG_B[4]; + u8 VHT_SIG_B_CRC; + u8 VHT_Delimiter[4]; + u8 MacAddress[6]; +} RT_PMAC_TX_INFO, *PRT_PMAC_TX_INFO; + + +typedef VOID (*MPT_WORK_ITEM_HANDLER)(IN PVOID Adapter); +typedef struct _MPT_CONTEXT +{ + // Indicate if we have started Mass Production Test. + BOOLEAN bMassProdTest; + + // Indicate if the driver is unloading or unloaded. + BOOLEAN bMptDrvUnload; + + _sema MPh2c_Sema; + _timer MPh2c_timeout_timer; +// Event used to sync H2c for BT control + + BOOLEAN MptH2cRspEvent; + BOOLEAN MptBtC2hEvent; + BOOLEAN bMPh2c_timeout; + + /* 8190 PCI does not support NDIS_WORK_ITEM. */ + // Work Item for Mass Production Test. + //NDIS_WORK_ITEM MptWorkItem; +// RT_WORK_ITEM MptWorkItem; + // Event used to sync the case unloading driver and MptWorkItem is still in progress. +// NDIS_EVENT MptWorkItemEvent; + // To protect the following variables. +// NDIS_SPIN_LOCK MptWorkItemSpinLock; + // Indicate a MptWorkItem is scheduled and not yet finished. + BOOLEAN bMptWorkItemInProgress; + // An instance which implements function and context of MptWorkItem. + MPT_WORK_ITEM_HANDLER CurrMptAct; + + // 1=Start, 0=Stop from UI. + ULONG MptTestStart; + // _TEST_MODE, defined in MPT_Req2.h + ULONG MptTestItem; + // Variable needed in each implementation of CurrMptAct. + ULONG MptActType; // Type of action performed in CurrMptAct. + // The Offset of IO operation is depend of MptActType. + ULONG MptIoOffset; + // The Value of IO operation is depend of MptActType. + ULONG MptIoValue; + // The RfPath of IO operation is depend of MptActType. + ULONG MptRfPath; + + WIRELESS_MODE MptWirelessModeToSw; // Wireless mode to switch. + u8 MptChannelToSw; // Channel to switch. + u8 MptInitGainToSet; // Initial gain to set. + //ULONG bMptAntennaA; // TRUE if we want to use antenna A. + ULONG MptBandWidth; // bandwidth to switch. + ULONG MptRateIndex; // rate index. + // Register value kept for Single Carrier Tx test. + u8 btMpCckTxPower; + // Register value kept for Single Carrier Tx test. + u8 btMpOfdmTxPower; + // For MP Tx Power index + u8 TxPwrLevel[4]; /* rf-A, rf-B*/ + u32 RegTxPwrLimit; + // Content of RCR Regsiter for Mass Production Test. + ULONG MptRCR; + // TRUE if we only receive packets with specific pattern. + BOOLEAN bMptFilterPattern; + // Rx OK count, statistics used in Mass Production Test. + ULONG MptRxOkCnt; + // Rx CRC32 error count, statistics used in Mass Production Test. + ULONG MptRxCrcErrCnt; + + BOOLEAN bCckContTx; // TRUE if we are in CCK Continuous Tx test. + BOOLEAN bOfdmContTx; // TRUE if we are in OFDM Continuous Tx test. + BOOLEAN bStartContTx; // TRUE if we have start Continuous Tx test. + // TRUE if we are in Single Carrier Tx test. + BOOLEAN bSingleCarrier; + // TRUE if we are in Carrier Suppression Tx Test. + BOOLEAN bCarrierSuppression; + //TRUE if we are in Single Tone Tx test. + BOOLEAN bSingleTone; + + // ACK counter asked by K.Y.. + BOOLEAN bMptEnableAckCounter; + ULONG MptAckCounter; + + // SD3 Willis For 8192S to save 1T/2T RF table for ACUT Only fro ACUT delete later ~~~! + //s1Byte BufOfLines[2][MAX_LINES_HWCONFIG_TXT][MAX_BYTES_LINE_HWCONFIG_TXT]; + //s1Byte BufOfLines[2][MP_MAX_LINES][MP_MAX_LINES_BYTES]; + //s4Byte RfReadLine[2]; + + u8 APK_bound[2]; //for APK path A/path B + BOOLEAN bMptIndexEven; + + u8 backup0xc50; + u8 backup0xc58; + u8 backup0xc30; + u8 backup0x52_RF_A; + u8 backup0x52_RF_B; + + u4Byte backup0x58_RF_A; + u4Byte backup0x58_RF_B; + + u1Byte h2cReqNum; + u1Byte c2hBuf[32]; + + u1Byte btInBuf[100]; + ULONG mptOutLen; + u1Byte mptOutBuf[100]; + RT_PMAC_TX_INFO PMacTxInfo; + RT_PMAC_PKT_INFO PMacPktInfo; + u8 HWTxmode; + + BOOLEAN bldpc; + BOOLEAN bstbc; +}MPT_CONTEXT, *PMPT_CONTEXT; +//#endif + +/* E-Fuse */ +#ifdef CONFIG_RTL8188E +#define EFUSE_MAP_SIZE 512 +#endif +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) +#define EFUSE_MAP_SIZE 512 +#endif +#ifdef CONFIG_RTL8192E +#define EFUSE_MAP_SIZE 512 +#endif +#ifdef CONFIG_RTL8723B +#define EFUSE_MAP_SIZE 512 +#endif +#ifdef CONFIG_RTL8814A +#define EFUSE_MAP_SIZE 512 +#endif +#ifdef CONFIG_RTL8703B +#define EFUSE_MAP_SIZE 512 +#endif +#ifdef CONFIG_RTL8188F +#define EFUSE_MAP_SIZE 512 +#endif + +#if defined(CONFIG_RTL8814A) +#define EFUSE_MAX_SIZE 1024 +#elif defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8703B) +#define EFUSE_MAX_SIZE 256 +#else +#define EFUSE_MAX_SIZE 512 +#endif +/* end of E-Fuse */ + +//#define RTPRIV_IOCTL_MP ( SIOCIWFIRSTPRIV + 0x17) +enum { + WRITE_REG = 1, + READ_REG, + WRITE_RF, + READ_RF, + MP_START, + MP_STOP, + MP_RATE, + MP_CHANNEL, + MP_BANDWIDTH, + MP_TXPOWER, + MP_ANT_TX, + MP_ANT_RX, + MP_CTX, + MP_QUERY, + MP_ARX, + MP_PSD, + MP_PWRTRK, + MP_THER, + MP_IOCTL, + EFUSE_GET, + EFUSE_SET, + MP_RESET_STATS, + MP_DUMP, + MP_PHYPARA, + MP_SetRFPathSwh, + MP_QueryDrvStats, + MP_SetBT, + CTA_TEST, + MP_DISABLE_BT_COEXIST, + MP_PwrCtlDM, + MP_GETVER, + MP_MON, + EFUSE_MASK, + EFUSE_FILE, + MP_TX, + MP_RX, +#ifdef CONFIG_WOWLAN + MP_WOW_ENABLE, + MP_WOW_SET_PATTERN, +#endif +#ifdef CONFIG_AP_WOWLAN + MP_AP_WOW_ENABLE, +#endif + MP_NULL, + MP_GET_TXPOWER_INX, + + MP_SD_IREAD, + MP_SD_IWRITE, +}; + +struct mp_priv +{ + _adapter *papdater; + + //Testing Flag + u32 mode;//0 for normal type packet, 1 for loopback packet (16bytes TXCMD) + + u32 prev_fw_state; + + //OID cmd handler + struct mp_wiparam workparam; +// u8 act_in_progress; + + //Tx Section + u8 TID; + u32 tx_pktcount; + u32 pktInterval; + u32 pktLength; + struct mp_tx tx; + + //Rx Section + u32 rx_bssidpktcount; + u32 rx_pktcount; + u32 rx_pktcount_filter_out; + u32 rx_crcerrpktcount; + u32 rx_pktloss; + BOOLEAN rx_bindicatePkt; + struct recv_stat rxstat; + + //RF/BB relative + u8 channel; + u8 bandwidth; + u8 prime_channel_offset; + u8 txpoweridx; + u8 rateidx; + u32 preamble; +// u8 modem; + u32 CrystalCap; +// u32 curr_crystalcap; + + u16 antenna_tx; + u16 antenna_rx; +// u8 curr_rfpath; + + u8 check_mp_pkt; + + u8 bSetTxPower; +// uint ForcedDataRate; + u8 mp_dm; + u8 mac_filter[ETH_ALEN]; + u8 bmac_filter; + + struct wlan_network mp_network; + NDIS_802_11_MAC_ADDRESS network_macaddr; + +#ifdef PLATFORM_WINDOWS + u32 rx_testcnt; + u32 rx_testcnt1; + u32 rx_testcnt2; + u32 tx_testcnt; + u32 tx_testcnt1; + + struct mp_wi_cntx wi_cntx; + + u8 h2c_result; + u8 h2c_seqnum; + u16 h2c_cmdcode; + u8 h2c_resp_parambuf[512]; + _lock h2c_lock; + _lock wkitm_lock; + u32 h2c_cmdcnt; + NDIS_EVENT h2c_cmd_evt; + NDIS_EVENT c2h_set; + NDIS_EVENT h2c_clr; + NDIS_EVENT cpwm_int; + + NDIS_EVENT scsir_full_evt; + NDIS_EVENT scsiw_empty_evt; +#endif + + u8 *pallocated_mp_xmitframe_buf; + u8 *pmp_xmtframe_buf; + _queue free_mp_xmitqueue; + u32 free_mp_xmitframe_cnt; + BOOLEAN bSetRxBssid; + BOOLEAN bTxBufCkFail; + BOOLEAN bRTWSmbCfg; + MPT_CONTEXT MptCtx; + + u8 *TXradomBuffer; +}; + +typedef struct _IOCMD_STRUCT_ { + u8 cmdclass; + u16 value; + u8 index; +}IOCMD_STRUCT; + +struct rf_reg_param { + u32 path; + u32 offset; + u32 value; +}; + +struct bb_reg_param { + u32 offset; + u32 value; +}; + +typedef struct _MP_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[0x8000]; +#endif + u32 ulFwLength; +} RT_MP_FIRMWARE, *PRT_MP_FIRMWARE; + + + + +//======================================================================= + +#define LOWER _TRUE +#define RAISE _FALSE + +/* Hardware Registers */ +#if 0 +#if 0 +#define IOCMD_CTRL_REG 0x102502C0 +#define IOCMD_DATA_REG 0x102502C4 +#else +#define IOCMD_CTRL_REG 0x10250370 +#define IOCMD_DATA_REG 0x10250374 +#endif + +#define IOCMD_GET_THERMAL_METER 0xFD000028 + +#define IOCMD_CLASS_BB_RF 0xF0 +#define IOCMD_BB_READ_IDX 0x00 +#define IOCMD_BB_WRITE_IDX 0x01 +#define IOCMD_RF_READ_IDX 0x02 +#define IOCMD_RF_WRIT_IDX 0x03 +#endif +#define BB_REG_BASE_ADDR 0x800 + +/* MP variables */ +#if 0 +#define _2MAC_MODE_ 0 +#define _LOOPBOOK_MODE_ 1 +#endif +typedef enum _MP_MODE_ { + MP_OFF, + MP_ON, + MP_ERR, + MP_CONTINUOUS_TX, + MP_SINGLE_CARRIER_TX, + MP_CARRIER_SUPPRISSION_TX, + MP_SINGLE_TONE_TX, + MP_PACKET_TX, + MP_PACKET_RX +} MP_MODE; + +typedef enum _TEST_MODE { + TEST_NONE , + PACKETS_TX , + PACKETS_RX , + CONTINUOUS_TX , + OFDM_Single_Tone_TX , + CCK_Carrier_Suppression_TX +} TEST_MODE; + + +typedef enum _MPT_BANDWIDTH { + MPT_BW_20MHZ = 0, + MPT_BW_40MHZ_DUPLICATE = 1, + MPT_BW_40MHZ_ABOVE = 2, + MPT_BW_40MHZ_BELOW = 3, + MPT_BW_40MHZ = 4, + MPT_BW_80MHZ = 5, + MPT_BW_80MHZ_20_ABOVE = 6, + MPT_BW_80MHZ_20_BELOW = 7, + MPT_BW_80MHZ_20_BOTTOM = 8, + MPT_BW_80MHZ_20_TOP = 9, + MPT_BW_80MHZ_40_ABOVE = 10, + MPT_BW_80MHZ_40_BELOW = 11, +} MPT_BANDWIDTHE, *PMPT_BANDWIDTH; + +#define MAX_RF_PATH_NUMS RF_PATH_MAX + + +extern u8 mpdatarate[NumRates]; + +/* MP set force data rate base on the definition. */ +typedef enum _MPT_RATE_INDEX +{ + /* CCK rate. */ + MPT_RATE_1M = 1 , /* 0 */ + MPT_RATE_2M, + MPT_RATE_55M, + MPT_RATE_11M, /* 3 */ + + /* OFDM rate. */ + MPT_RATE_6M, /* 4 */ + MPT_RATE_9M, + MPT_RATE_12M, + MPT_RATE_18M, + MPT_RATE_24M, + MPT_RATE_36M, + MPT_RATE_48M, + MPT_RATE_54M, /* 11 */ + + /* HT rate. */ + MPT_RATE_MCS0, /* 12 */ + MPT_RATE_MCS1, + MPT_RATE_MCS2, + MPT_RATE_MCS3, + MPT_RATE_MCS4, + MPT_RATE_MCS5, + MPT_RATE_MCS6, + MPT_RATE_MCS7, /* 19 */ + MPT_RATE_MCS8, + MPT_RATE_MCS9, + MPT_RATE_MCS10, + MPT_RATE_MCS11, + MPT_RATE_MCS12, + 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,/* #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, // # + MPT_RATE_VHT1SS_MCS7, + MPT_RATE_VHT1SS_MCS8, + 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, + MPT_RATE_VHT2SS_MCS7, + MPT_RATE_VHT2SS_MCS8, + 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; + +#define MAX_TX_PWR_INDEX_N_MODE 64 // 0x3F + +#define MPT_IS_CCK_RATE(_value) (MPT_RATE_1M <= _value && _value <= MPT_RATE_11M) +#define MPT_IS_OFDM_RATE(_value) (MPT_RATE_6M <= _value && _value <= MPT_RATE_54M) +#define MPT_IS_HT_RATE(_value) (MPT_RATE_MCS0 <= _value && _value <= MPT_RATE_MCS31) +#define MPT_IS_HT_1S_RATE(_value) (MPT_RATE_MCS0 <= _value && _value <= MPT_RATE_MCS7) +#define MPT_IS_HT_2S_RATE(_value) (MPT_RATE_MCS8 <= _value && _value <= MPT_RATE_MCS15) +#define MPT_IS_HT_3S_RATE(_value) (MPT_RATE_MCS16 <= _value && _value <= MPT_RATE_MCS23) +#define MPT_IS_HT_4S_RATE(_value) (MPT_RATE_MCS24 <= _value && _value <= MPT_RATE_MCS31) + +#define MPT_IS_VHT_RATE(_value) (MPT_RATE_VHT1SS_MCS0 <= _value && _value <= MPT_RATE_VHT4SS_MCS9) +#define MPT_IS_VHT_1S_RATE(_value) (MPT_RATE_VHT1SS_MCS0 <= _value && _value <= MPT_RATE_VHT1SS_MCS9) +#define MPT_IS_VHT_2S_RATE(_value) (MPT_RATE_VHT2SS_MCS0 <= _value && _value <= MPT_RATE_VHT2SS_MCS9) +#define MPT_IS_VHT_3S_RATE(_value) (MPT_RATE_VHT3SS_MCS0 <= _value && _value <= MPT_RATE_VHT3SS_MCS9) +#define MPT_IS_VHT_4S_RATE(_value) (MPT_RATE_VHT4SS_MCS0 <= _value && _value <= MPT_RATE_VHT4SS_MCS9) + +#define MPT_IS_2SS_RATE(_rate) ((MPT_RATE_MCS8 <= _rate && _rate <= MPT_RATE_MCS15) ||\ + (MPT_RATE_VHT2SS_MCS0 <= _rate && _rate <= MPT_RATE_VHT2SS_MCS9)) +#define MPT_IS_3SS_RATE(_rate) ((MPT_RATE_MCS16 <= _rate && _rate <= MPT_RATE_MCS23) ||\ + (MPT_RATE_VHT3SS_MCS0 <= _rate && _rate <= MPT_RATE_VHT3SS_MCS9)) +#define MPT_IS_4SS_RATE(_rate) ((MPT_RATE_MCS24 <= _rate && _rate <= MPT_RATE_MCS31) ||\ + (MPT_RATE_VHT4SS_MCS0 <= _rate && _rate <= MPT_RATE_VHT4SS_MCS9)) + +typedef enum _POWER_MODE_ { + POWER_LOW = 0, + POWER_NORMAL +}POWER_MODE; + +// The following enumeration is used to define the value of Reg0xD00[30:28] or JaguarReg0x914[18:16]. +typedef enum _OFDM_TX_MODE { + OFDM_ALL_OFF = 0, + OFDM_ContinuousTx = 1, + OFDM_SingleCarrier = 2, + OFDM_SingleTone = 4, +} OFDM_TX_MODE; + + +#define RX_PKT_BROADCAST 1 +#define RX_PKT_DEST_ADDR 2 +#define RX_PKT_PHY_MATCH 3 + +#define Mac_OFDM_OK 0x00000000 +#define Mac_OFDM_Fail 0x10000000 +#define Mac_OFDM_FasleAlarm 0x20000000 +#define Mac_CCK_OK 0x30000000 +#define Mac_CCK_Fail 0x40000000 +#define Mac_CCK_FasleAlarm 0x50000000 +#define Mac_HT_OK 0x60000000 +#define Mac_HT_Fail 0x70000000 +#define Mac_HT_FasleAlarm 0x90000000 +#define Mac_DropPacket 0xA0000000 + +typedef enum _ENCRY_CTRL_STATE_ { + HW_CONTROL, //hw encryption& decryption + SW_CONTROL, //sw encryption& decryption + HW_ENCRY_SW_DECRY, //hw encryption & sw decryption + SW_ENCRY_HW_DECRY //sw encryption & hw decryption +}ENCRY_CTRL_STATE; + +typedef enum _MPT_TXPWR_DEF{ + MPT_CCK, + MPT_OFDM, // L and HT OFDM + MPT_OFDM_AND_HT, + MPT_HT, + MPT_VHT +}MPT_TXPWR_DEF; + +#ifdef CONFIG_RF_GAIN_OFFSET + +#if defined(CONFIG_RTL8723B) + #define REG_RF_BB_GAIN_OFFSET 0x7f + #define RF_GAIN_OFFSET_MASK 0xfffff +#elif defined(CONFIG_RTL8188E) + #define REG_RF_BB_GAIN_OFFSET 0x55 + #define RF_GAIN_OFFSET_MASK 0xfffff +#else + #define REG_RF_BB_GAIN_OFFSET 0x55 + #define RF_GAIN_OFFSET_MASK 0xfffff +#endif //CONFIG_RTL8723B + +#endif //CONFIG_RF_GAIN_OFFSET + +#define IS_MPT_HT_RATE(_rate) (_rate >= MPT_RATE_MCS0 && _rate <= MPT_RATE_MCS31) +#define IS_MPT_VHT_RATE(_rate) (_rate >= MPT_RATE_VHT1SS_MCS0 && _rate <= MPT_RATE_VHT4SS_MCS9) +#define IS_MPT_CCK_RATE(_rate) (_rate >= MPT_RATE_1M && _rate <= MPT_RATE_11M) +#define IS_MPT_OFDM_RATE(_rate) (_rate >= MPT_RATE_6M && _rate <= MPT_RATE_54M) +//======================================================================= +//extern struct mp_xmit_frame *alloc_mp_xmitframe(struct mp_priv *pmp_priv); +//extern int free_mp_xmitframe(struct xmit_priv *pxmitpriv, struct mp_xmit_frame *pmp_xmitframe); + +extern s32 init_mp_priv(PADAPTER padapter); +extern void free_mp_priv(struct mp_priv *pmp_priv); +extern s32 MPT_InitializeAdapter(PADAPTER padapter, u8 Channel); +extern void MPT_DeInitAdapter(PADAPTER padapter); +extern s32 mp_start_test(PADAPTER padapter); +extern void mp_stop_test(PADAPTER padapter); + +extern u32 _read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask); +extern void _write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val); + +extern u32 read_macreg(_adapter *padapter, u32 addr, u32 sz); +extern void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz); +extern u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask); +extern void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val); +extern u32 read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr); +extern void write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 val); + +void SetChannel(PADAPTER pAdapter); +void SetBandwidth(PADAPTER pAdapter); +int SetTxPower(PADAPTER pAdapter); +void SetAntenna(PADAPTER pAdapter); +void SetDataRate(PADAPTER pAdapter); +void SetAntenna(PADAPTER pAdapter); +s32 SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +void GetThermalMeter(PADAPTER pAdapter, u8 *value); +void SetContinuousTx(PADAPTER pAdapter, u8 bStart); +void SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart); +void SetSingleToneTx(PADAPTER pAdapter, u8 bStart); +void SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); +void PhySetTxPowerLevel(PADAPTER pAdapter); +void fill_txdesc_for_mp(PADAPTER padapter, u8 *ptxdesc); +void SetPacketTx(PADAPTER padapter); +void SetPacketRx(PADAPTER pAdapter, u8 bStartRx, u8 bAB); +void ResetPhyRxPktCount(PADAPTER pAdapter); +u32 GetPhyRxPktReceived(PADAPTER pAdapter); +u32 GetPhyRxPktCRC32Error(PADAPTER pAdapter); +s32 SetPowerTracking(PADAPTER padapter, u8 enable); +void GetPowerTracking(PADAPTER padapter, u8 *enable); +u32 mp_query_psd(PADAPTER pAdapter, u8 *data); + + + +void hal_mpt_SwitchRfSetting(PADAPTER pAdapter); +s32 hal_mpt_SetPowerTracking(PADAPTER padapter, u8 enable); +void hal_mpt_GetPowerTracking(PADAPTER padapter, u8 *enable); +void hal_mpt_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14); +void hal_mpt_SetChannel(PADAPTER pAdapter); +void hal_mpt_SetBandwidth(PADAPTER pAdapter); +void hal_mpt_SetTxPower(PADAPTER pAdapter); +void hal_mpt_SetDataRate(PADAPTER pAdapter); +void hal_mpt_SetAntenna(PADAPTER pAdapter); +s32 hal_mpt_SetThermalMeter(PADAPTER pAdapter, u8 target_ther); +void hal_mpt_TriggerRFThermalMeter(PADAPTER pAdapter); +u8 hal_mpt_ReadRFThermalMeter(PADAPTER pAdapter); +void hal_mpt_GetThermalMeter(PADAPTER pAdapter, u8 *value); +void hal_mpt_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven); +void hal_mpt_SetContinuousTx(PADAPTER pAdapter, u8 bStart); +void hal_mpt_SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart); +void hal_mpt_SetSingleToneTx(PADAPTER pAdapter, u8 bStart); +void hal_mpt_SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart); +void hal_mpt_SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart); +void hal_mpt_SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart); +VOID mpt_ProSetPMacTx(PADAPTER Adapter); + +void MP_PHY_SetRFPathSwitch(PADAPTER pAdapter , BOOLEAN bMain); +ULONG mpt_ProQueryCalTxPower(PADAPTER pAdapter, u8 RfPath); +void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart); +u8 MptToMgntRate(u32 MptRateIdx); +u8 rtw_mpRateParseFunc(PADAPTER pAdapter, u8 *targetStr); +u32 mp_join(PADAPTER padapter, u8 mode); + +void +PMAC_Get_Pkt_Param( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ); +void +CCK_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ); +void +PMAC_Nsym_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ); +void +L_SIG_generator( + UINT N_SYM, /* Max: 750*/ + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo + ); + +void HT_SIG_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo); + +void VHT_SIG_A_generator( + PRT_PMAC_TX_INFO pPMacTxInfo, + PRT_PMAC_PKT_INFO pPMacPktInfo); + +void VHT_SIG_B_generator( + PRT_PMAC_TX_INFO pPMacTxInfo); + +void VHT_Delimiter_generator( + PRT_PMAC_TX_INFO pPMacTxInfo); + + +int rtw_mp_write_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_read_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_write_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_read_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_start(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_stop(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_channel(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_bandwidth(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_txpower_index(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_txpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_txpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_ant_tx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_ant_rx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_set_ctx_destAddr(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_ctx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_disable_bt_coexist(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_disable_bt_coexist(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_arx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_trx_query(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_pwrtrk(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_psd(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_thermal(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_reset_stats(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_dump(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_phypara(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_SetRFPath(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_QueryDrv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_PwrCtlDM(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra); +int rtw_mp_getver(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_mon(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_efuse_mask_file(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_efuse_file_map(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_SetBT(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra); +int rtw_mp_tx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +int rtw_mp_rx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +u8 HwRateToMPTRate(u8 rate); + +#endif //_RTW_MP_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_ioctl.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_ioctl.h new file mode 100644 index 00000000..cd6303c2 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_ioctl.h @@ -0,0 +1,591 @@ +/****************************************************************************** + * + * 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 _RTW_MP_IOCTL_H_ +#define _RTW_MP_IOCTL_H_ + +#include +#include + +#if 0 +#define TESTFWCMDNUMBER 1000000 +#define TEST_H2CINT_WAIT_TIME 500 +#define TEST_C2HINT_WAIT_TIME 500 +#define HCI_TEST_SYSCFG_HWMASK 1 +#define _BUSCLK_40M (4 << 2) +#endif +//------------------------------------------------------------------------------ +typedef struct CFG_DBG_MSG_STRUCT { + u32 DebugLevel; + u32 DebugComponent_H32; + u32 DebugComponent_L32; +}CFG_DBG_MSG_STRUCT,*PCFG_DBG_MSG_STRUCT; + +typedef struct _RW_REG { + u32 offset; + u32 width; + u32 value; +}mp_rw_reg,RW_Reg, *pRW_Reg; + +//for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM +typedef struct _EEPROM_RW_PARAM { + u32 offset; + u16 value; +}eeprom_rw_param,EEPROM_RWParam, *pEEPROM_RWParam; + +typedef struct _EFUSE_ACCESS_STRUCT_ { + u16 start_addr; + u16 cnts; + u8 data[0]; +}EFUSE_ACCESS_STRUCT, *PEFUSE_ACCESS_STRUCT; + +typedef struct _BURST_RW_REG { + u32 offset; + u32 len; + u8 Data[256]; +}burst_rw_reg,Burst_RW_Reg, *pBurst_RW_Reg; + +typedef struct _USB_VendorReq{ + u8 bRequest; + u16 wValue; + u16 wIndex; + u16 wLength; + u8 u8Dir;//0:OUT, 1:IN + u8 u8InData; +}usb_vendor_req, USB_VendorReq, *pUSB_VendorReq; + +typedef struct _DR_VARIABLE_STRUCT_ { + u8 offset; + u32 variable; +}DR_VARIABLE_STRUCT; + +//int mp_start_joinbss(_adapter *padapter, NDIS_802_11_SSID *pssid); + +//void _irqlevel_changed_(_irqL *irqlevel, /*BOOLEAN*/unsigned char bLower); +#ifdef PLATFORM_OS_XP +static void _irqlevel_changed_(_irqL *irqlevel, u8 bLower) +{ + + if (bLower == LOWER) { + *irqlevel = KeGetCurrentIrql(); + + if (*irqlevel > PASSIVE_LEVEL) { + KeLowerIrql(PASSIVE_LEVEL); + } + } else { + if (KeGetCurrentIrql() == PASSIVE_LEVEL) { + KeRaiseIrql(DISPATCH_LEVEL, irqlevel); + } + } + +} +#else +#define _irqlevel_changed_(a,b) +#endif + +//oid_rtl_seg_81_80_00 +NDIS_STATUS oid_rt_pro_set_data_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_start_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_stop_test_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_81_80_20 +NDIS_STATUS oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_modulation_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_81_87 +NDIS_STATUS oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_81_85 +NDIS_STATUS oid_rt_wireless_mode_hdl(struct oid_par_priv* poid_par_priv); + + +// oid_rtl_seg_87_11_00 +NDIS_STATUS oid_rt_pro8711_join_bss_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_burst_read_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_burst_write_register_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write_txcmd_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_write16_eeprom_hdl (struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_rd_attrib_mem_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_wr_attrib_mem_hdl (struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_poll_rx_status_hdl(struct oid_par_priv* poid_par_priv); +// oid_rtl_seg_87_11_20 +NDIS_STATUS oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_read_tssi_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_87_11_50 +NDIS_STATUS oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv* poid_par_priv); +//oid_rtl_seg_87_11_F0 +NDIS_STATUS oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv* poid_par_priv); + + +//oid_rtl_seg_87_12_00 +NDIS_STATUS oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_add_sta_info_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); +NDIS_STATUS oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); + +NDIS_STATUS oid_rt_set_bandwidth_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_crystal_cap_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_set_rx_packet_type_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_efuse_max_size_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_get_thermal_meter_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv* poid_par_priv); +NDIS_STATUS oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_set_power_down_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_get_power_mode_hdl(struct oid_par_priv* poid_par_priv); + +NDIS_STATUS oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv); + +#ifdef _RTW_MP_IOCTL_C_ + +const struct oid_obj_priv oid_rtl_seg_81_80_00[] = +{ + {1, &oid_null_function}, //0x00 OID_RT_PRO_RESET_DUT + {1, &oid_rt_pro_set_data_rate_hdl}, //0x01 + {1, &oid_rt_pro_start_test_hdl}, //0x02 + {1, &oid_rt_pro_stop_test_hdl}, //0x03 + {1, &oid_null_function}, //0x04 OID_RT_PRO_SET_PREAMBLE + {1, &oid_null_function}, //0x05 OID_RT_PRO_SET_SCRAMBLER + {1, &oid_null_function}, //0x06 OID_RT_PRO_SET_FILTER_BB + {1, &oid_null_function}, //0x07 OID_RT_PRO_SET_MANUAL_DIVERSITY_BB + {1, &oid_rt_pro_set_channel_direct_call_hdl}, //0x08 + {1, &oid_null_function}, //0x09 OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL + {1, &oid_null_function}, //0x0A OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL + {1, &oid_rt_pro_set_continuous_tx_hdl}, //0x0B OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL + {1, &oid_rt_pro_set_single_carrier_tx_hdl}, //0x0C OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS + {1, &oid_null_function}, //0x0D OID_RT_PRO_SET_TX_ANTENNA_BB + {1, &oid_rt_pro_set_antenna_bb_hdl}, //0x0E + {1, &oid_null_function}, //0x0F OID_RT_PRO_SET_CR_SCRAMBLER + {1, &oid_null_function}, //0x10 OID_RT_PRO_SET_CR_NEW_FILTER + {1, &oid_rt_pro_set_tx_power_control_hdl}, //0x11 OID_RT_PRO_SET_TX_POWER_CONTROL + {1, &oid_null_function}, //0x12 OID_RT_PRO_SET_CR_TX_CONFIG + {1, &oid_null_function}, //0x13 OID_RT_PRO_GET_TX_POWER_CONTROL + {1, &oid_null_function}, //0x14 OID_RT_PRO_GET_CR_SIGNAL_QUALITY + {1, &oid_null_function}, //0x15 OID_RT_PRO_SET_CR_SETPOINT + {1, &oid_null_function}, //0x16 OID_RT_PRO_SET_INTEGRATOR + {1, &oid_null_function}, //0x17 OID_RT_PRO_SET_SIGNAL_QUALITY + {1, &oid_null_function}, //0x18 OID_RT_PRO_GET_INTEGRATOR + {1, &oid_null_function}, //0x19 OID_RT_PRO_GET_SIGNAL_QUALITY + {1, &oid_null_function}, //0x1A OID_RT_PRO_QUERY_EEPROM_TYPE + {1, &oid_null_function}, //0x1B OID_RT_PRO_WRITE_MAC_ADDRESS + {1, &oid_null_function}, //0x1C OID_RT_PRO_READ_MAC_ADDRESS + {1, &oid_null_function}, //0x1D OID_RT_PRO_WRITE_CIS_DATA + {1, &oid_null_function}, //0x1E OID_RT_PRO_READ_CIS_DATA + {1, &oid_null_function} //0x1F OID_RT_PRO_WRITE_POWER_CONTROL + +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_20[] = +{ + {1, &oid_null_function}, //0x20 OID_RT_PRO_READ_POWER_CONTROL + {1, &oid_null_function}, //0x21 OID_RT_PRO_WRITE_EEPROM + {1, &oid_null_function}, //0x22 OID_RT_PRO_READ_EEPROM + {1, &oid_rt_pro_reset_tx_packet_sent_hdl}, //0x23 + {1, &oid_rt_pro_query_tx_packet_sent_hdl}, //0x24 + {1, &oid_rt_pro_reset_rx_packet_received_hdl}, //0x25 + {1, &oid_rt_pro_query_rx_packet_received_hdl}, //0x26 + {1, &oid_rt_pro_query_rx_packet_crc32_error_hdl}, //0x27 + {1, &oid_null_function}, //0x28 OID_RT_PRO_QUERY_CURRENT_ADDRESS + {1, &oid_null_function}, //0x29 OID_RT_PRO_QUERY_PERMANENT_ADDRESS + {1, &oid_null_function}, //0x2A OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS + {1, &oid_rt_pro_set_carrier_suppression_tx_hdl},//0x2B OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX + {1, &oid_null_function}, //0x2C OID_RT_PRO_RECEIVE_PACKET + {1, &oid_null_function}, //0x2D OID_RT_PRO_WRITE_EEPROM_BYTE + {1, &oid_null_function}, //0x2E OID_RT_PRO_READ_EEPROM_BYTE + {1, &oid_rt_pro_set_modulation_hdl} //0x2F + +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_40[] = +{ + {1, &oid_null_function}, //0x40 + {1, &oid_null_function}, //0x41 + {1, &oid_null_function}, //0x42 + {1, &oid_rt_pro_set_single_tone_tx_hdl}, //0x43 + {1, &oid_null_function}, //0x44 + {1, &oid_null_function} //0x45 +}; + +const struct oid_obj_priv oid_rtl_seg_81_80_80[] = +{ + {1, &oid_null_function}, //0x80 OID_RT_DRIVER_OPTION + {1, &oid_null_function}, //0x81 OID_RT_RF_OFF + {1, &oid_null_function} //0x82 OID_RT_AUTH_STATUS + +}; + +const struct oid_obj_priv oid_rtl_seg_81_85[] = +{ + {1, &oid_rt_wireless_mode_hdl} //0x00 OID_RT_WIRELESS_MODE +}; + +struct oid_obj_priv oid_rtl_seg_81_87[] = +{ + {1, &oid_null_function}, //0x80 OID_RT_PRO8187_WI_POLL + {1, &oid_rt_pro_write_bb_reg_hdl}, //0x81 + {1, &oid_rt_pro_read_bb_reg_hdl}, //0x82 + {1, &oid_rt_pro_write_rf_reg_hdl}, //0x82 + {1, &oid_rt_pro_read_rf_reg_hdl} //0x83 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_00[] = +{ + {1, &oid_rt_pro8711_join_bss_hdl}, //0x00 //S + {1, &oid_rt_pro_read_register_hdl}, //0x01 + {1, &oid_rt_pro_write_register_hdl}, //0x02 + {1, &oid_rt_pro_burst_read_register_hdl}, //0x03 + {1, &oid_rt_pro_burst_write_register_hdl}, //0x04 + {1, &oid_rt_pro_write_txcmd_hdl}, //0x05 + {1, &oid_rt_pro_read16_eeprom_hdl}, //0x06 + {1, &oid_rt_pro_write16_eeprom_hdl}, //0x07 + {1, &oid_null_function}, //0x08 OID_RT_PRO_H2C_SET_COMMAND + {1, &oid_null_function}, //0x09 OID_RT_PRO_H2C_QUERY_RESULT + {1, &oid_rt_pro8711_wi_poll_hdl}, //0x0A + {1, &oid_rt_pro8711_pkt_loss_hdl}, //0x0B + {1, &oid_rt_rd_attrib_mem_hdl}, //0x0C + {1, &oid_rt_wr_attrib_mem_hdl}, //0x0D + {1, &oid_null_function}, //0x0E + {1, &oid_null_function}, //0x0F + {1, &oid_null_function}, //0x10 OID_RT_PRO_H2C_CMD_MODE + {1, &oid_null_function}, //0x11 OID_RT_PRO_H2C_CMD_RSP_MODE + {1, &oid_null_function}, //0X12 OID_RT_PRO_WAIT_C2H_EVENT + {1, &oid_null_function}, //0X13 OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST + {1, &oid_null_function}, //0X14 OID_RT_PRO_SCSI_ACCESS_TEST + {1, &oid_null_function}, //0X15 OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT + {1, &oid_null_function}, //0X16 OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN + {1, &oid_null_function}, //0X17 OID_RT_RRO_RX_PKT_VIA_IOCTRL + {1, &oid_null_function}, //0X18 OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL + {1, &oid_null_function}, //0X19 OID_RT_RPO_SET_PWRMGT_TEST + {1, &oid_null_function}, //0X1A + {1, &oid_null_function}, //0X1B OID_RT_PRO_QRY_PWRMGT_TEST + {1, &oid_null_function}, //0X1C OID_RT_RPO_ASYNC_RWIO_TEST + {1, &oid_null_function}, //0X1D OID_RT_RPO_ASYNC_RWIO_POLL + {1, &oid_rt_pro_set_rf_intfs_hdl}, //0X1E + {1, &oid_rt_poll_rx_status_hdl} //0X1F +}; + +struct oid_obj_priv oid_rtl_seg_87_11_20[] = +{ + {1, &oid_rt_pro_cfg_debug_message_hdl}, //0x20 + {1, &oid_rt_pro_set_data_rate_ex_hdl}, //0x21 + {1, &oid_rt_pro_set_basic_rate_hdl}, //0x22 + {1, &oid_rt_pro_read_tssi_hdl}, //0x23 + {1, &oid_rt_pro_set_power_tracking_hdl} //0x24 +}; + + +struct oid_obj_priv oid_rtl_seg_87_11_50[] = +{ + {1, &oid_rt_pro_qry_pwrstate_hdl}, //0x50 + {1, &oid_rt_pro_set_pwrstate_hdl} //0x51 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_80[] = +{ + {1, &oid_null_function} //0x80 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_B0[] = +{ + {1, &oid_null_function} //0xB0 +}; + +struct oid_obj_priv oid_rtl_seg_87_11_F0[] = +{ + {1, &oid_null_function}, //0xF0 + {1, &oid_null_function}, //0xF1 + {1, &oid_null_function}, //0xF2 + {1, &oid_null_function}, //0xF3 + {1, &oid_null_function}, //0xF4 + {1, &oid_null_function}, //0xF5 + {1, &oid_null_function}, //0xF6 + {1, &oid_null_function}, //0xF7 + {1, &oid_null_function}, //0xF8 + {1, &oid_null_function}, //0xF9 + {1, &oid_null_function}, //0xFA + {1, &oid_rt_pro_h2c_set_rate_table_hdl}, //0xFB + {1, &oid_rt_pro_h2c_get_rate_table_hdl}, //0xFC + {1, &oid_null_function}, //0xFD + {1, &oid_null_function}, //0xFE OID_RT_PRO_H2C_C2H_LBK_TEST + {1, &oid_null_function} //0xFF + +}; + +struct oid_obj_priv oid_rtl_seg_87_12_00[]= +{ + {1, &oid_rt_pro_encryption_ctrl_hdl}, //0x00 Q&S + {1, &oid_rt_pro_add_sta_info_hdl}, //0x01 S + {1, &oid_rt_pro_dele_sta_info_hdl}, //0x02 S + {1, &oid_rt_pro_query_dr_variable_hdl}, //0x03 Q + {1, &oid_rt_pro_rx_packet_type_hdl}, //0x04 Q,S + {1, &oid_rt_pro_read_efuse_hdl}, //0x05 Q OID_RT_PRO_READ_EFUSE + {1, &oid_rt_pro_write_efuse_hdl}, //0x06 S OID_RT_PRO_WRITE_EFUSE + {1, &oid_rt_pro_rw_efuse_pgpkt_hdl}, //0x07 Q,S + {1, &oid_rt_get_efuse_current_size_hdl}, //0x08 Q + {1, &oid_rt_set_bandwidth_hdl}, //0x09 + {1, &oid_rt_set_crystal_cap_hdl}, //0x0a + {1, &oid_rt_set_rx_packet_type_hdl}, //0x0b S + {1, &oid_rt_get_efuse_max_size_hdl}, //0x0c + {1, &oid_rt_pro_set_tx_agc_offset_hdl}, //0x0d + {1, &oid_rt_pro_set_pkt_test_mode_hdl}, //0x0e + {1, &oid_null_function}, //0x0f OID_RT_PRO_FOR_EVM_TEST_SETTING + {1, &oid_rt_get_thermal_meter_hdl}, //0x10 Q OID_RT_PRO_GET_THERMAL_METER + {1, &oid_rt_reset_phy_rx_packet_count_hdl}, //0x11 S OID_RT_RESET_PHY_RX_PACKET_COUNT + {1, &oid_rt_get_phy_rx_packet_received_hdl}, //0x12 Q OID_RT_GET_PHY_RX_PACKET_RECEIVED + {1, &oid_rt_get_phy_rx_packet_crc32_error_hdl}, //0x13 Q OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR + {1, &oid_rt_set_power_down_hdl}, //0x14 Q OID_RT_SET_POWER_DOWN + {1, &oid_rt_get_power_mode_hdl} //0x15 Q OID_RT_GET_POWER_MODE +}; + +#else /* _RTL871X_MP_IOCTL_C_ */ + +extern struct oid_obj_priv oid_rtl_seg_81_80_00[32]; +extern struct oid_obj_priv oid_rtl_seg_81_80_20[16]; +extern struct oid_obj_priv oid_rtl_seg_81_80_40[6]; +extern struct oid_obj_priv oid_rtl_seg_81_80_80[3]; + +extern struct oid_obj_priv oid_rtl_seg_81_85[1]; +extern struct oid_obj_priv oid_rtl_seg_81_87[5]; + +extern struct oid_obj_priv oid_rtl_seg_87_11_00[32]; +extern struct oid_obj_priv oid_rtl_seg_87_11_20[5]; +extern struct oid_obj_priv oid_rtl_seg_87_11_50[2]; +extern struct oid_obj_priv oid_rtl_seg_87_11_80[1]; +extern struct oid_obj_priv oid_rtl_seg_87_11_B0[1]; +extern struct oid_obj_priv oid_rtl_seg_87_11_F0[16]; + +extern struct oid_obj_priv oid_rtl_seg_87_12_00[32]; + +#endif /* _RTL871X_MP_IOCTL_C_ */ + +struct rwreg_param{ + u32 offset; + u32 width; + u32 value; +}; + +struct bbreg_param{ + u32 offset; + u32 phymask; + u32 value; +}; +/* +struct rfchannel_param{ + u32 ch; + u32 modem; +}; +*/ +struct txpower_param{ + u32 pwr_index; +}; + + +struct datarate_param{ + u32 rate_index; +}; + + +struct rfintfs_parm { + u32 rfintfs; +}; + +typedef struct _mp_xmit_parm_ { + u8 enable; + u32 count; + u16 length; + u8 payload_type; + u8 da[ETH_ALEN]; +}MP_XMIT_PARM, *PMP_XMIT_PARM; + +struct mp_xmit_packet { + u32 len; + u32 mem[MAX_MP_XMITBUF_SZ >> 2]; +}; + +struct psmode_param { + u32 ps_mode; + u32 smart_ps; +}; + +//for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM +struct eeprom_rw_param { + u32 offset; + u16 value; +}; + +struct mp_ioctl_handler { + u32 paramsize; + u32 (*handler)(struct oid_par_priv* poid_par_priv); + u32 oid; +}; + +struct mp_ioctl_param{ + u32 subcode; + u32 len; + u8 data[0]; +}; + +#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ + +enum RTL871X_MP_IOCTL_SUBCODE { + GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ + GEN_MP_IOCTL_SUBCODE(MP_STOP), + GEN_MP_IOCTL_SUBCODE(READ_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_REG), + GEN_MP_IOCTL_SUBCODE(READ_BB_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), /*5*/ + GEN_MP_IOCTL_SUBCODE(READ_RF_REG), + GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), + GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), + GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), + GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*10*/ + GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), + GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), + GEN_MP_IOCTL_SUBCODE(CNTU_TX), + GEN_MP_IOCTL_SUBCODE(SC_TX), + GEN_MP_IOCTL_SUBCODE(CS_TX), /*15*/ + GEN_MP_IOCTL_SUBCODE(ST_TX), + GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), + GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), + GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), + GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*20*/ + GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), + GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), + GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), + GEN_MP_IOCTL_SUBCODE(EFUSE), + GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*25*/ + GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), + GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), + GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), + GEN_MP_IOCTL_SUBCODE(SET_PTM), + GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*30*/ + GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO), + GEN_MP_IOCTL_SUBCODE(SET_DM_BT), /*32*/ + GEN_MP_IOCTL_SUBCODE(DEL_BA), /*33*/ + GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS), /*34*/ + MAX_MP_IOCTL_SUBCODE, +}; + +u32 mp_ioctl_xmit_packet_hdl(struct oid_par_priv* poid_par_priv); + +#ifdef _RTW_MP_IOCTL_C_ + +#define GEN_MP_IOCTL_HANDLER(sz, hdl, oid) {sz, hdl, oid}, + +#define EXT_MP_IOCTL_HANDLER(sz, subcode, oid) {sz, mp_ioctl_ ## subcode ## _hdl, oid}, + + +struct mp_ioctl_handler mp_ioctl_hdl[] = { + +/*0*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST) + + GEN_MP_IOCTL_HANDLER(sizeof(struct rwreg_param), oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER) + GEN_MP_IOCTL_HANDLER(sizeof(struct rwreg_param), oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER) + GEN_MP_IOCTL_HANDLER(sizeof(struct bb_reg_param), oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG) +/*5*/ GEN_MP_IOCTL_HANDLER(sizeof(struct bb_reg_param), oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG) + GEN_MP_IOCTL_HANDLER(sizeof(struct rf_reg_param), oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY) + GEN_MP_IOCTL_HANDLER(sizeof(struct rf_reg_param), oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL) + GEN_MP_IOCTL_HANDLER(sizeof(struct txpower_param), oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL) +/*10*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX) +/*15*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX) + + EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE) + GEN_MP_IOCTL_HANDLER(0, oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT) +/*20*/ GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR) + + GEN_MP_IOCTL_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) + GEN_MP_IOCTL_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0) + GEN_MP_IOCTL_HANDLER(sizeof(EFUSE_ACCESS_STRUCT), oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE) +/*25*/ GEN_MP_IOCTL_HANDLER(0, oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE) + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE) + + GEN_MP_IOCTL_HANDLER(sizeof(u32), oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER) + GEN_MP_IOCTL_HANDLER(sizeof(u8), oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING) +/*30*/ GEN_MP_IOCTL_HANDLER(sizeof(u8), oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN) +/*31*/ GEN_MP_IOCTL_HANDLER(0, oid_rt_pro_trigger_gpio_hdl, 0) + GEN_MP_IOCTL_HANDLER(0, NULL, 0) + GEN_MP_IOCTL_HANDLER(0, NULL, 0) + GEN_MP_IOCTL_HANDLER(0, NULL, 0) +}; + +#else /* _RTW_MP_IOCTL_C_ */ + +extern struct mp_ioctl_handler mp_ioctl_hdl[]; + +#endif /* _RTW_MP_IOCTL_C_ */ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_phy_regdef.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_phy_regdef.h new file mode 100644 index 00000000..340015cd --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_mp_phy_regdef.h @@ -0,0 +1,1100 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __RTW_MP_PHY_REGDEF_H_ + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __RTW_MP_PHY_REGDEF_H_ +#define __RTW_MP_PHY_REGDEF_H_ + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +//#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +//#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 +//#define rFPGA0_XC_RFTiming 0x818 +//#define rFPGA0_XD_RFTiming 0x81c + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rFPGA0_XC_HSSIParameter1 0x830 +#define rFPGA0_XC_HSSIParameter2 0x834 +#define rFPGA0_XD_HSSIParameter1 0x838 +#define rFPGA0_XD_HSSIParameter2 0x83c +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 +#define rFPGA0_XC_LSSIParameter 0x848 +#define rFPGA0_XD_LSSIParameter 0x84c + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rFPGA0_XC_RFInterfaceOE 0x868 +#define rFPGA0_XD_RFInterfaceOE 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? +#define rS0S1_PathSwitch 0x948 + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_RxIQExtAnta 0xca0 + +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 + + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_Rate18_06 0xe00 +#define rTxAGC_Rate54_24 0xe04 +#define rTxAGC_CCK_Mcs32 0xe08 +#define rTxAGC_Mcs03_Mcs00 0xe10 +#define rTxAGC_Mcs07_Mcs04 0xe14 +#define rTxAGC_Mcs11_Mcs08 0xe18 +#define rTxAGC_Mcs15_Mcs12 0xe1c + +// Analog- control in RX_WAIT_CCA : REG: EE0 [Analog- Power & Control Register] +#define rRx_Wait_CCCA 0xe70 +#define rAnapar_Ctrl_BB 0xee0 + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define RTL92SE_FPGA_VERIFY 0 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +//#if (RTL92SE_FPGA_VERIFY == 1) +#define rZebra1_Channel 0x7 // RF channel switch +//#else + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 +#if (RTL92SE_FPGA_VERIFY == 1) +#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address // Reg 0x824 rFPGA0_XA_HSSIParameter2 +#else +#define bLSSIReadAddress 0x7f800000 // T65 RF +#endif +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal +#if (RTL92SE_FPGA_VERIFY == 1) +#define bLSSIReadBackData 0xfff // Reg 0x8a0 rFPGA0_XA_LSSIReadBack +#else +#define bLSSIReadBackData 0xfffff // T65 RF +#endif +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +#define bTxAGCRate18_06 0x7f7f7f7f // Useless +#define bTxAGCRate54_24 0x7f7f7f7f +#define bTxAGCRateMCS32 0x7f +#define bTxAGCRateCCK 0x7f00 +#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f +#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f +#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f +#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMaskH4Bits 0xf0000000 +#define bMaskH3Bytes 0xffffff00 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f +#define bMask12Bits 0xfff + +//for PutRFRegsetting & GetRFRegSetting BitMask +#if (RTL92SE_FPGA_VERIFY == 1) +//#define bMask12Bits 0xfff // RF Reg mask bits +//#define bMask20Bits 0xfff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfff +#else +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff +#endif +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#if 0 +#define ANTENNA_A 0x1 // Useless +#define ANTENNA_B 0x2 +#define ANTENNA_AB 0x3 // ANTENNA_A|ANTENNA_B + +#define ANTENNA_C 0x4 +#define ANTENNA_D 0x8 +#endif + +#define RCR_AAP BIT(0) // accept all physical address +#define RCR_APM BIT(1) // accept physical match +#define RCR_AM BIT(2) // accept multicast +#define RCR_AB BIT(3) // accept broadcast +#define RCR_ACRC32 BIT(5) // accept error packet +#define RCR_9356SEL BIT(6) +#define RCR_AICV BIT(9) // Accept ICV error packet +#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) // Rx FIFO threshold +#define RCR_ADF BIT(18) // Accept Data(frame type) frame +#define RCR_ACF BIT(19) // Accept control frame +#define RCR_AMF BIT(20) // Accept management frame +#define RCR_ADD3 BIT(21) +#define RCR_APWRMGT BIT(22) // Accept power management packet +#define RCR_CBSSID BIT(23) // Accept BSSID match packet +#define RCR_ENMARP BIT(28) // enable mac auto reset phy +#define RCR_EnCS1 BIT(29) // enable carrier sense method 1 +#define RCR_EnCS2 BIT(30) // enable carrier sense method 2 +#define RCR_OnlyErlPkt BIT(31) // Rx Early mode is performed for packet size greater than 1536 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8192SPHYREG_H + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_odm.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_odm.h new file mode 100644 index 00000000..8c0faebb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_odm.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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_ODM_H__ +#define __RTW_ODM_H__ + +#include +#include "../hal/phydm/phydm_types.h" +/* +* This file provides utilities/wrappers for rtw driver to use ODM +*/ + +void rtw_odm_dbg_comp_msg(void *sel,_adapter *adapter); +void rtw_odm_dbg_comp_set(_adapter *adapter, u64 comps); +void rtw_odm_dbg_level_msg(void *sel,_adapter *adapter); +void rtw_odm_dbg_level_set(_adapter *adapter, u32 level); + +void rtw_odm_ability_msg(void *sel, _adapter *adapter); +void rtw_odm_ability_set(_adapter *adapter, u32 ability); + +void rtw_odm_adaptivity_config_msg(void *sel, _adapter *adapter); + +bool rtw_odm_adaptivity_needed(_adapter *adapter); +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 TH_L2H_ini_mode2, s8 TH_EDCCA_HL_diff_mode2, u8 EDCCA_enable); +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); + +#ifdef CONFIG_DFS_MASTER +VOID rtw_odm_radar_detect_reset(_adapter *adapter); +VOID rtw_odm_radar_detect_disable(_adapter *adapter); +VOID rtw_odm_radar_detect_enable(_adapter *adapter); +BOOLEAN rtw_odm_radar_detect(_adapter *adapter); +#endif /* CONFIG_DFS_MASTER */ +#endif // __RTW_ODM_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_p2p.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_p2p.h new file mode 100644 index 00000000..ab3f4c87 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_p2p.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 __RTW_P2P_H_ +#define __RTW_P2P_H_ + + +u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr ); +u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code); +u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +#ifdef CONFIG_WFD +int rtw_init_wifi_display_info(_adapter *padapter); +void rtw_wfd_enable(_adapter *adapter, bool on); +void rtw_wfd_set_ctrl_port(_adapter *adapter, u16 port); +void rtw_tdls_wfd_enable(_adapter *adapter, bool on); + +u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled); +u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); +u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf); + +u32 rtw_append_beacon_wfd_ie(_adapter *adapter, u8 *pbuf); +u32 rtw_append_probe_req_wfd_ie(_adapter *adapter, u8 *pbuf); +u32 rtw_append_probe_resp_wfd_ie(_adapter *adapter, u8 *pbuf); +u32 rtw_append_assoc_req_wfd_ie(_adapter *adapter, u8 *pbuf); +u32 rtw_append_assoc_resp_wfd_ie(_adapter *adapter, u8 *pbuf); +#endif /*CONFIG_WFD */ + +void rtw_xframe_chk_wfd_ie(struct xmit_frame *xframe); + +u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta); +u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe); +u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len ); +u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len); +int process_p2p_cross_connect_ie(PADAPTER padapter, u8 *IEs, u32 IELength); + +void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType); + +#ifdef CONFIG_P2P_PS +void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength); +void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state); +u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue); +#endif // CONFIG_P2P_PS + +#ifdef CONFIG_IOCTL_CFG80211 +void rtw_init_cfg80211_wifidirect_info( _adapter* padapter); +int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx); +#endif /* CONFIG_IOCTL_CFG80211 */ + +void reset_global_wifidirect_info( _adapter* padapter ); +void rtw_init_wifidirect_timers(_adapter* padapter); +void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr); +void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role); +int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role); + +static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + if(wdinfo->p2p_state != state) { + //wdinfo->pre_p2p_state = wdinfo->p2p_state; + wdinfo->p2p_state = state; + } +} +static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + if(wdinfo->pre_p2p_state != state) { + wdinfo->pre_p2p_state = state; + } +} +#if 0 +static inline void _rtw_p2p_restore_state(struct wifidirect_info *wdinfo) +{ + if(wdinfo->pre_p2p_state != -1) { + wdinfo->p2p_state = wdinfo->pre_p2p_state; + wdinfo->pre_p2p_state = -1; + } +} +#endif +static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role) +{ + if(wdinfo->role != role) { + wdinfo->role = role; + } +} +static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo) +{ + return wdinfo->p2p_state; +} +static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo) +{ + return wdinfo->pre_p2p_state; +} +static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo) +{ + return wdinfo->role; +} +static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + return wdinfo->p2p_state == state; +} +static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role) +{ + return wdinfo->role == role; +} + +#ifdef CONFIG_DBG_P2P +void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line); +void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line); +//void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line); +void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line); +#define rtw_p2p_set_state(wdinfo, state) dbg_rtw_p2p_set_state(wdinfo, state, __FUNCTION__, __LINE__) +#define rtw_p2p_set_pre_state(wdinfo, state) dbg_rtw_p2p_set_pre_state(wdinfo, state, __FUNCTION__, __LINE__) +#define rtw_p2p_set_role(wdinfo, role) dbg_rtw_p2p_set_role(wdinfo, role, __FUNCTION__, __LINE__) +//#define rtw_p2p_restore_state(wdinfo) dbg_rtw_p2p_restore_state(wdinfo, __FUNCTION__, __LINE__) +#else //CONFIG_DBG_P2P +#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state) +#define rtw_p2p_set_pre_state(wdinfo, state) _rtw_p2p_set_pre_state(wdinfo, state) +#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role) +//#define rtw_p2p_restore_state(wdinfo) _rtw_p2p_restore_state(wdinfo) +#endif //CONFIG_DBG_P2P + +#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo) +#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo) +#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo) +#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state) +#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role) + +#define rtw_p2p_findphase_ex_set(wdinfo, value) \ + (wdinfo)->find_phase_state_exchange_cnt = (value) + +#ifdef CONFIG_P2P +//is this find phase exchange for social channel scan? +#define rtw_p2p_findphase_ex_is_social(wdinfo) \ + (wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST + +//should we need find phase exchange anymore? +#define rtw_p2p_findphase_ex_is_needed(wdinfo) \ + ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \ + (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE && \ + !(wdinfo)->rx_invitereq_info.scan_op_ch_only && \ + !(wdinfo)->p2p_info.scan_op_ch_only) +#else +#define rtw_p2p_findphase_ex_is_social(wdinfo) 0 +#define rtw_p2p_findphase_ex_is_needed(wdinfo) 0 +#endif /* CONFIG_P2P */ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_pwrctrl.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_pwrctrl.h new file mode 100644 index 00000000..8c4fa6b5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_pwrctrl.h @@ -0,0 +1,514 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_PWRCTRL_H_ +#define __RTW_PWRCTRL_H_ + + +#define FW_PWR0 0 +#define FW_PWR1 1 +#define FW_PWR2 2 +#define FW_PWR3 3 + + +#define HW_PWR0 7 +#define HW_PWR1 6 +#define HW_PWR2 2 +#define HW_PWR3 0 +#define HW_PWR4 8 + +#define FW_PWRMSK 0x7 + + +#define XMIT_ALIVE BIT(0) +#define RECV_ALIVE BIT(1) +#define CMD_ALIVE BIT(2) +#define EVT_ALIVE BIT(3) +#ifdef CONFIG_BT_COEXIST +#define BTCOEX_ALIVE BIT(4) +#endif // CONFIG_BT_COEXIST + +#ifdef CONFIG_WOWLAN +#define MAX_WKFM_NUM 16 /* Frame Mask Cam number for pattern match */ +#define MAX_WKFM_SIZE 16 /* (16 bytes for WKFM bit mask, 16*8 = 128 bits) */ +#define MAX_WKFM_PATTERN_SIZE 128 +#define WKFMCAM_ADDR_NUM 6 +#define WKFMCAM_SIZE 24 /* each entry need 6*4 bytes */ +enum pattern_type { + PATTERN_BROADCAST = 0, + PATTERN_MULTICAST, + PATTERN_UNICAST, + PATTERN_VALID, + PATTERN_INVALID, +}; + +typedef struct rtl_priv_pattern { + int len; + char content[MAX_WKFM_PATTERN_SIZE]; + char mask[MAX_WKFM_SIZE]; +} rtl_priv_pattern_t; + +struct rtl_wow_pattern { + u16 crc; + u8 type; + u32 mask[4]; +}; +#endif /* CONFIG_WOWLAN */ + +enum Power_Mgnt +{ + PS_MODE_ACTIVE = 0 , + PS_MODE_MIN , + PS_MODE_MAX , + PS_MODE_DTIM , //PS_MODE_SELF_DEFINED + PS_MODE_VOIP , + PS_MODE_UAPSD_WMM , + PS_MODE_UAPSD , + PS_MODE_IBSS , + PS_MODE_WWLAN , + PM_Radio_Off , + PM_Card_Disable , + PS_MODE_NUM, +}; + +#ifdef CONFIG_PNO_SUPPORT +#define MAX_PNO_LIST_COUNT 16 +#define MAX_SCAN_LIST_COUNT 14 //2.4G only +#define MAX_HIDDEN_AP 8 //8 hidden AP +#endif + +/* + BIT[2:0] = HW state + BIT[3] = Protocol PS state, 0: register active state , 1: register sleep state + BIT[4] = sub-state +*/ + +#define PS_DPS BIT(0) +#define PS_LCLK (PS_DPS) +#define PS_RF_OFF BIT(1) +#define PS_ALL_ON BIT(2) +#define PS_ST_ACTIVE BIT(3) + +#define PS_ISR_ENABLE BIT(4) +#define PS_IMR_ENABLE BIT(5) +#define PS_ACK BIT(6) +#define PS_TOGGLE BIT(7) + +#define PS_STATE_MASK (0x0F) +#define PS_STATE_HW_MASK (0x07) +#define PS_SEQ_MASK (0xc0) + +#define PS_STATE(x) (PS_STATE_MASK & (x)) +#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) +#define PS_SEQ(x) (PS_SEQ_MASK & (x)) + +#define PS_STATE_S0 (PS_DPS) +#define PS_STATE_S1 (PS_LCLK) +#define PS_STATE_S2 (PS_RF_OFF) +#define PS_STATE_S3 (PS_ALL_ON) +#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) + + +#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) +#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) +#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) + + +struct reportpwrstate_parm { + unsigned char mode; + unsigned char state; //the CPWM value + unsigned short rsvd; +}; + + +typedef _sema _pwrlock; + + +__inline static void _init_pwrlock(_pwrlock *plock) +{ + _rtw_init_sema(plock, 1); +} + +__inline static void _free_pwrlock(_pwrlock *plock) +{ + _rtw_free_sema(plock); +} + + +__inline static void _enter_pwrlock(_pwrlock *plock) +{ + _rtw_down_sema(plock); +} + + +__inline static void _exit_pwrlock(_pwrlock *plock) +{ + _rtw_up_sema(plock); +} + +#define LPS_DELAY_TIME 1*HZ // 1 sec + +#define EXE_PWR_NONE 0x01 +#define EXE_PWR_IPS 0x02 +#define EXE_PWR_LPS 0x04 + +// RF state. +typedef enum _rt_rf_power_state +{ + rf_on, // RF is on after RFSleep or RFOff + rf_sleep, // 802.11 Power Save mode + rf_off, // HW/SW Radio OFF or Inactive Power Save + //=====Add the new RF state above this line=====// + rf_max +}rt_rf_power_state; + +// RF Off Level for IPS or HW/SW radio off +#define RT_RF_OFF_LEVL_ASPM BIT(0) // PCI ASPM +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) // PCI clock request +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) // PCI D3 mode +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) // NIC halt, re-initialize hw parameters +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) // FW free, re-download the FW +#define RT_RF_OFF_LEVL_FW_32K BIT(5) // FW in 32k +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) // Always enable ASPM and Clock Req in initialization. +#define RT_RF_LPS_DISALBE_2R BIT(30) // When LPS is on, disable 2R if no packet is received or transmittd. +#define RT_RF_LPS_LEVEL_ASPM BIT(31) // LPS with ASPM + +#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) ((ppsc->cur_ps_level & _PS_FLAG) ? _TRUE : _FALSE) +#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level |= _PS_FLAG) + +// ASPM OSC Control bit, added by Roger, 2013.03.29. +#define RT_PCI_ASPM_OSC_IGNORE 0 // PCI ASPM ignore OSC control in default +#define RT_PCI_ASPM_OSC_ENABLE BIT0 // PCI ASPM controlled by OS according to ACPI Spec 5.0 +#define RT_PCI_ASPM_OSC_DISABLE BIT1 // PCI ASPM controlled by driver or BIOS, i.e., force enable ASPM + + +enum _PS_BBRegBackup_ { + PSBBREG_RF0 = 0, + PSBBREG_RF1, + PSBBREG_RF2, + PSBBREG_AFE0, + PSBBREG_TOTALCNT +}; + +enum { // for ips_mode + IPS_NONE=0, + IPS_NORMAL, + IPS_LEVEL_2, + IPS_NUM +}; + +// Design for pwrctrl_priv.ips_deny, 32 bits for 32 reasons at most +typedef enum _PS_DENY_REASON +{ + PS_DENY_DRV_INITIAL = 0, + PS_DENY_SCAN, + PS_DENY_JOIN, + PS_DENY_DISCONNECT, + PS_DENY_SUSPEND, + PS_DENY_IOCTL, + PS_DENY_MGNT_TX, + PS_DENY_DRV_REMOVE = 30, + PS_DENY_OTHERS = 31 +} PS_DENY_REASON; + +#ifdef CONFIG_PNO_SUPPORT +typedef struct pno_nlo_info +{ + u32 fast_scan_period; //Fast scan period + 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 + u8 loc_probe_req[MAX_HIDDEN_AP]; //loc_probeReq +}pno_nlo_info_t; + +typedef struct pno_ssid { + u32 SSID_len; + u8 SSID[32]; +} pno_ssid_t; + +typedef struct pno_ssid_list { + pno_ssid_t node[MAX_PNO_LIST_COUNT]; +}pno_ssid_list_t; + +typedef struct pno_scan_channel_info +{ + u8 channel; + u8 tx_power; + u8 timeout; + u8 active; //set 1 means active scan, or pasivite scan. +}pno_scan_channel_info_t; + +typedef struct pno_scan_info +{ + u8 enableRFE; //Enable RFE + u8 period_scan_time; //exclusive with fast_scan_period and slow_scan_period + u8 periodScan; //exclusive with fast_scan_period and slow_scan_period + u8 orig_80_offset; //original channel 80 offset + u8 orig_40_offset; //original channel 40 offset + u8 orig_bw; //original bandwidth + u8 orig_ch; //original channel + u8 channel_num; //number of channel + u64 rfe_type; //rfe_type && 0x00000000000000ff + pno_scan_channel_info_t ssid_channel_info[MAX_SCAN_LIST_COUNT]; +}pno_scan_info_t; +#endif //CONFIG_PNO_SUPPORT + +struct pwrctrl_priv +{ + _pwrlock lock; + _pwrlock check_32k_lock; + volatile u8 rpwm; // requested power state for fw + volatile u8 cpwm; // fw current power state. updated when 1. read from HCPWM 2. driver lowers power level + volatile u8 tog; // toggling + volatile u8 cpwm_tog; // toggling + + u8 pwr_mode; + u8 smart_ps; + u8 bcn_ant_mode; + u8 dtim; + + u32 alives; + _workitem cpwm_event; +#ifdef CONFIG_LPS_RPWM_TIMER + u8 brpwmtimeout; + _workitem rpwmtimeoutwi; + _timer pwr_rpwm_timer; +#endif // CONFIG_LPS_RPWM_TIMER + u8 bpower_saving; //for LPS/IPS + + u8 b_hw_radio_off; + u8 reg_rfoff; + u8 reg_pdnmode; //powerdown mode + u32 rfoff_reason; + + //RF OFF Level + u32 cur_ps_level; + u32 reg_rfps_level; + + uint ips_enter_cnts; + uint ips_leave_cnts; + uint lps_enter_cnts; + uint lps_leave_cnts; + + u8 ips_mode; + u8 ips_org_mode; + u8 ips_mode_req; // used to accept the mode setting request, will update to ipsmode later + uint bips_processing; + u32 ips_deny_time; /* will deny IPS when system time is smaller than this */ + u8 pre_ips_type;// 0: default flow, 1: carddisbale flow + + // ps_deny: if 0, power save is free to go; otherwise deny all kinds of power save. + // Use PS_DENY_REASON to decide reason. + // Don't access this variable directly without control function, + // and this variable should be protected by lock. + u32 ps_deny; + + u8 ps_processing; /* temporarily used to mark whether in rtw_ps_processor */ + + u8 fw_psmode_iface_id; + u8 bLeisurePs; + u8 LpsIdleCount; + u8 power_mgnt; + u8 org_power_mgnt; + u8 bFwCurrentInPSMode; + u32 DelayLPSLastTimeStamp; + s32 pnp_current_pwr_state; + u8 pnp_bstop_trx; + + + u8 bInternalAutoSuspend; + u8 bInSuspend; +#ifdef CONFIG_BT_COEXIST + u8 bAutoResume; + u8 autopm_cnt; +#endif + u8 bSupportRemoteWakeup; + u8 wowlan_wake_reason; + u8 wowlan_ap_mode; + u8 wowlan_mode; + u8 wowlan_p2p_mode; + u8 wowlan_pno_enable; +#ifdef CONFIG_GPIO_WAKEUP + u8 is_high_active; +#endif /* CONFIG_GPIO_WAKEUP */ +#ifdef CONFIG_WOWLAN + u8 wowlan_txpause_status; + u8 wowlan_pattern; + u8 wowlan_pattern_idx; + u64 wowlan_fw_iv; + struct rtl_priv_pattern patterns[MAX_WKFM_NUM]; +#ifdef CONFIG_PNO_SUPPORT + u8 pno_in_resume; + u8 pno_inited; + pno_nlo_info_t *pnlo_info; + pno_scan_info_t *pscan_info; + pno_ssid_list_t *pno_ssid_list; +#endif /* CONFIG_PNO_SUPPORT */ +#endif /* CONFIG_WOWLAN */ + _timer pwr_state_check_timer; + int pwr_state_check_interval; + u8 pwr_state_check_cnts; + + int ps_flag; /* used by autosuspend */ + + rt_rf_power_state rf_pwrstate;//cur power state, only for IPS + //rt_rf_power_state current_rfpwrstate; + rt_rf_power_state change_rfpwrstate; + + u8 bHWPowerdown; /* power down mode selection. 0:radio off, 1:power down */ + u8 bHWPwrPindetect; /* come from registrypriv.hwpwrp_detect. enable power down function. 0:disable, 1:enable */ + u8 bkeepfwalive; + u8 brfoffbyhw; + unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + struct workqueue_struct *rtw_workqueue; + _workitem resume_work; + #endif + + #ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; + u8 do_late_resume; + #endif //CONFIG_HAS_EARLYSUSPEND + + #ifdef CONFIG_ANDROID_POWER + android_early_suspend_t early_suspend; + u8 do_late_resume; + #endif + + #ifdef CONFIG_INTEL_PROXIM + u8 stored_power_mgnt; + #endif +}; + +#define rtw_get_ips_mode_req(pwrctl) \ + (pwrctl)->ips_mode_req + +#define rtw_ips_mode_req(pwrctl, ips_mode) \ + (pwrctl)->ips_mode_req = (ips_mode) + +#define RTW_PWR_STATE_CHK_INTERVAL 2000 + +#define _rtw_set_pwr_state_check_timer(pwrctl, ms) \ + do { \ + /*DBG_871X("%s _rtw_set_pwr_state_check_timer(%p, %d)\n", __FUNCTION__, (pwrctl), (ms));*/ \ + _set_timer(&(pwrctl)->pwr_state_check_timer, (ms)); \ + } while(0) + +#define rtw_set_pwr_state_check_timer(pwrctl) \ + _rtw_set_pwr_state_check_timer((pwrctl), (pwrctl)->pwr_state_check_interval) + +extern void rtw_init_pwrctrl_priv(_adapter *adapter); +extern void rtw_free_pwrctrl_priv(_adapter * adapter); + +#ifdef CONFIG_LPS_LCLK +s32 rtw_register_task_alive(PADAPTER, u32 task); +void rtw_unregister_task_alive(PADAPTER, u32 task); +extern s32 rtw_register_tx_alive(PADAPTER padapter); +extern void rtw_unregister_tx_alive(PADAPTER padapter); +extern s32 rtw_register_rx_alive(PADAPTER padapter); +extern void rtw_unregister_rx_alive(PADAPTER padapter); +extern s32 rtw_register_cmd_alive(PADAPTER padapter); +extern void rtw_unregister_cmd_alive(PADAPTER padapter); +extern s32 rtw_register_evt_alive(PADAPTER padapter); +extern void rtw_unregister_evt_alive(PADAPTER padapter); +extern void cpwm_int_hdl(PADAPTER padapter, struct reportpwrstate_parm *preportpwrstate); +extern void LPS_Leave_check(PADAPTER padapter); +#endif + +extern void LeaveAllPowerSaveMode(PADAPTER Adapter); +extern void LeaveAllPowerSaveModeDirect(PADAPTER Adapter); +#ifdef CONFIG_IPS +void _ips_enter(_adapter * padapter); +void ips_enter(_adapter * padapter); +int _ips_leave(_adapter * padapter); +int ips_leave(_adapter * padapter); +#endif + +void rtw_ps_processor(_adapter*padapter); + +#ifdef CONFIG_AUTOSUSPEND +int autoresume_enter(_adapter* padapter); +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED +rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter ); +#endif + + +int rtw_fw_ps_state(PADAPTER padapter); + +#ifdef CONFIG_LPS +s32 LPS_RF_ON_check(PADAPTER padapter, u32 delay_ms); +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 + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv); +#endif //CONFIG_RESUME_IN_WORKQUEUE + +#if defined(CONFIG_HAS_EARLYSUSPEND ) || defined(CONFIG_ANDROID_POWER) +bool rtw_is_earlysuspend_registered(struct pwrctrl_priv *pwrpriv); +bool rtw_is_do_late_resume(struct pwrctrl_priv *pwrpriv); +void rtw_set_do_late_resume(struct pwrctrl_priv *pwrpriv, bool enable); +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv); +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv); +#else +#define rtw_is_earlysuspend_registered(pwrpriv) _FALSE +#define rtw_is_do_late_resume(pwrpriv) _FALSE +#define rtw_set_do_late_resume(pwrpriv, enable) do {} while (0) +#define rtw_register_early_suspend(pwrpriv) do {} while (0) +#define rtw_unregister_early_suspend(pwrpriv) do {} while (0) +#endif /* CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER */ + +u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val); +void rtw_set_ips_deny(_adapter *padapter, u32 ms); +int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller); +#define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __FUNCTION__) +#define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) _rtw_pwr_wakeup(adapter, ips_deffer_ms, __FUNCTION__) +int rtw_pm_set_ips(_adapter *padapter, u8 mode); +int rtw_pm_set_lps(_adapter *padapter, u8 mode); + +void rtw_ps_deny(PADAPTER padapter, PS_DENY_REASON reason); +void rtw_ps_deny_cancel(PADAPTER padapter, PS_DENY_REASON reason); +u32 rtw_ps_deny_get(PADAPTER padapter); + +#if defined(CONFIG_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); +bool rtw_check_pattern_valid(u8 *input, u8 len); +bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx, + struct rtl_wow_pattern *content); + +bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx); +void rtw_dump_priv_pattern(_adapter *adapter, u8 idx); +void rtw_clean_pattern(_adapter *adapter); +#endif /* CONFIG_WOWLAN */ +#endif //__RTL871X_PWRCTRL_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_qos.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_qos.h new file mode 100644 index 00000000..cc5fcea5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_qos.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * 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 _RTW_QOS_H_ +#define _RTW_QOS_H_ + + + +struct qos_priv { + + unsigned int qos_option; //bit mask option: u-apsd, s-apsd, ts, block ack... + +}; + + +#endif //_RTL871X_QOS_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_recv.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_recv.h new file mode 100644 index 00000000..a2d7f9e3 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_recv.h @@ -0,0 +1,879 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_RECV_H_ +#define _RTW_RECV_H_ + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + #define NR_RECVBUFF 1024//512//128 + #else + #define NR_RECVBUFF (16) + #endif +#elif defined(PLATFORM_OS_CE) + #ifdef CONFIG_SDIO_HCI + #define NR_RECVBUFF (128) + #else + #define NR_RECVBUFF (4) + #endif +#else //PLATFORM_LINUX /PLATFORM_BSD + + #ifdef CONFIG_SINGLE_RECV_BUF + #define NR_RECVBUFF (1) + #else + #if defined(CONFIG_GSPI_HCI) + #define NR_RECVBUFF (32) + #elif defined(CONFIG_SDIO_HCI) + #define NR_RECVBUFF (8) + #else + #define NR_RECVBUFF (8) + #endif + #endif //CONFIG_SINGLE_RECV_BUF + #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + #define NR_PREALLOC_RECV_SKB (rtw_rtkm_get_nr_recv_skb()>>1) + #else /*!CONFIG_PREALLOC_RX_SKB_BUFFER */ + #define NR_PREALLOC_RECV_SKB 8 + #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */ + +#endif + +#define NR_RECVFRAME 256 + +#define RXFRAME_ALIGN 8 +#define RXFRAME_ALIGN_SZ (1<network.PhyInfo.SignalStrength); + #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA + struct rx_raw_rssi raw_rssi_info; + #endif + //s8 rxpwdb; + s16 noise; + //int RxSNRdB[2]; + //s8 RxRssi[2]; + //int FalseAlmCnt_all; + + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + _timer signal_stat_timer; + u32 signal_stat_sampling_interval; + //u32 signal_stat_converging_constant; + struct signal_stat signal_qual_data; + struct signal_stat signal_strength_data; +#else //CONFIG_NEW_SIGNAL_STAT_PROCESS + 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 +#define rtw_set_signal_stat_timer(recvpriv) _set_timer(&(recvpriv)->signal_stat_timer, (recvpriv)->signal_stat_sampling_interval) +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +struct sta_recv_priv { + + _lock lock; + sint option; + + //_queue blk_strms[MAX_RX_NUMBLKS]; + _queue defrag_q; //keeping the fragment frame until defrag + + struct stainfo_rxcache rxcache; + + //uint sta_rx_bytes; + //uint sta_rx_pkts; + //uint sta_rx_fail; + +}; + + +struct recv_buf +{ + _list list; + + _lock recvbuf_lock; + + u32 ref_cnt; + + PADAPTER adapter; + + u8 *pbuf; + u8 *pallocated_buf; + + u32 len; + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + +#ifdef CONFIG_USB_HCI + + #if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX)||defined(PLATFORM_FREEBSD) + PURB purb; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ + u32 alloc_sz; + #endif + + #ifdef PLATFORM_OS_XP + PIRP pirp; + #endif + + #ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_read_port; + #endif + + u8 irp_pending; + int transfer_len; + +#endif + +#ifdef PLATFORM_LINUX + _pkt *pskb; +#endif +#ifdef PLATFORM_FREEBSD //skb solution + struct sk_buff *pskb; +#endif //PLATFORM_FREEBSD //skb solution +}; + + +/* + head -----> + + data -----> + + payload + + tail -----> + + + end -----> + + len = (unsigned int )(tail - data); + +*/ +struct recv_frame_hdr +{ + _list list; +#ifndef CONFIG_BSD_RX_USE_MBUF + struct sk_buff *pkt; + struct sk_buff *pkt_newalloc; +#else // CONFIG_BSD_RX_USE_MBUF + _pkt *pkt; + _pkt *pkt_newalloc; +#endif // CONFIG_BSD_RX_USE_MBUF + + _adapter *adapter; + + u8 fragcnt; + + int frame_tag; + + struct rx_pkt_attrib attrib; + + uint len; + u8 *rx_head; + u8 *rx_data; + u8 *rx_tail; + u8 *rx_end; + + void *precvbuf; + + + // + struct sta_info *psta; + + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl *preorder_ctrl; + +#ifdef CONFIG_WAPI_SUPPORT + u8 UserPriority; + u8 WapiTempPN[16]; + u8 WapiSrcAddr[6]; + u8 bWapiCheckPNInDecrypt; + u8 bIsWaiPacket; +#endif + +}; + + +union recv_frame{ + + union{ + _list list; + struct recv_frame_hdr hdr; + uint mem[RECVFRAME_HDR_ALIGN>>2]; + }u; + + //uint mem[MAX_RXSZ>>2]; + +}; + +bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset); + +typedef enum _RX_PACKET_TYPE{ + NORMAL_RX,//Normal rx packet + TX_REPORT1,//CCX + TX_REPORT2,//TX RPT + HIS_REPORT,// USB HISR RPT + C2H_PACKET +}RX_PACKET_TYPE, *PRX_PACKET_TYPE; + +extern union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +extern union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +extern void rtw_init_recvframe(union recv_frame *precvframe ,struct recv_priv *precvpriv); +extern int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue); + +#define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue) +extern int _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); +extern int rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); + +extern void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue); +u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter); + +sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); +sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); +struct recv_buf *rtw_dequeue_recvbuf (_queue *queue); + +void rtw_reordering_ctrl_timeout_handler(void *pcontext); + +void rx_query_phy_status(union recv_frame *rframe, u8 *phy_stat); +int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index); +void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index); + +__inline static u8 *get_rxmem(union recv_frame *precvframe) +{ + //always return rx_head... + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_head; +} + +__inline static u8 *get_rx_status(union recv_frame *precvframe) +{ + + return get_rxmem(precvframe); + +} + +__inline static u8 *get_recvframe_data(union recv_frame *precvframe) +{ + + //alwasy return rx_data + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_data; + +} + +__inline static u8 *recvframe_push(union recv_frame *precvframe, sint sz) +{ + // append data before rx_data + + /* add data to the start of recv_frame + * + * This function extends the used data area of the recv_frame at the buffer + * start. rx_data must be still larger than rx_head, after pushing. + */ + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data -= sz ; + if( precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head ) + { + precvframe->u.hdr.rx_data += sz ; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_data; + +} + + +__inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz) +{ + // rx_data += sz; move rx_data sz bytes hereafter + + //used for extract sz bytes from rx_data, update rx_data and return the updated rx_data to the caller + + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data += sz; + + if(precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) + { + precvframe->u.hdr.rx_data -= sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_data; + +} + +__inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz) +{ + // rx_tai += sz; move rx_tail sz bytes hereafter + + //used for append sz bytes from ptr to rx_tail, update rx_tail and return the updated rx_tail to the caller + //after putting, rx_tail must be still larger than rx_end. + unsigned char * prev_rx_tail; + + /* DBG_871X("recvframe_put: len=%d\n", sz); */ + + if(precvframe==NULL) + return NULL; + + prev_rx_tail = precvframe->u.hdr.rx_tail; + + precvframe->u.hdr.rx_tail += sz; + + if(precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) + { + precvframe->u.hdr.rx_tail -= sz; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_tail; + +} + + + +__inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) +{ + // rmv data from rx_tail (by yitsen) + + //used for extract sz bytes from rx_end, update rx_end and return the updated rx_end to the caller + //after pulling, rx_end must be still larger than rx_data. + + if(precvframe==NULL) + return NULL; + + precvframe->u.hdr.rx_tail -= sz; + + if(precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) + { + precvframe->u.hdr.rx_tail += sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_tail; + +} + + + +__inline static _buffer * get_rxbuf_desc(union recv_frame *precvframe) +{ + _buffer * buf_desc; + + if(precvframe==NULL) + return NULL; +#ifdef PLATFORM_WINDOWS + NdisQueryPacket(precvframe->u.hdr.pkt, NULL, NULL, &buf_desc, NULL); +#endif + + return buf_desc; +} + + +__inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) +{ + //due to the design of 2048 bytes alignment of recv_frame, we can reference the union recv_frame + //from any given member of recv_frame. + // rxmem indicates the any member/address in recv_frame + + return (union recv_frame*)(((SIZE_PTR)rxmem >> RXFRAME_ALIGN) << RXFRAME_ALIGN); + +} + +__inline static union recv_frame *pkt_to_recvframe(_pkt *pkt) +{ + + u8 * buf_star; + union recv_frame * precv_frame; +#ifdef PLATFORM_WINDOWS + _buffer * buf_desc; + uint len; + + NdisQueryPacket(pkt, NULL, NULL, &buf_desc, &len); + NdisQueryBufferSafe(buf_desc, &buf_star, &len, HighPagePriority); +#endif + precv_frame = rxmem_to_recvframe((unsigned char*)buf_star); + + return precv_frame; +} + +__inline static u8 *pkt_to_recvmem(_pkt *pkt) +{ + // return the rx_head + + union recv_frame * precv_frame = pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_head; + +} + +__inline static u8 *pkt_to_recvdata(_pkt *pkt) +{ + // return the rx_data + + union recv_frame * precv_frame =pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_data; + +} + + +__inline static sint get_recvframe_len(union recv_frame *precvframe) +{ + return precvframe->u.hdr.len; +} + + +__inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex) +{ + s32 SignalPower; // in dBm. + +#ifdef CONFIG_SIGNAL_SCALE_MAPPING + /* Translate to dBm (x=0.5y-95). */ + SignalPower = (s32)((SignalStrengthIndex + 1) >> 1); + SignalPower -= 95; +#else + /* Translate to dBm (x=y-100) */ + SignalPower = SignalStrengthIndex - 100; +#endif + + return SignalPower; +} + + +struct sta_info; + +extern void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); + +extern void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_rf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_rf.h new file mode 100644 index 00000000..d4dd6a29 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_rf.h @@ -0,0 +1,271 @@ +/****************************************************************************** + * + * 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 __RTW_RF_H_ +#define __RTW_RF_H_ + + +#define OFDM_PHY 1 +#define MIXED_PHY 2 +#define CCK_PHY 3 + +#define NumRates (13) + +// slot time for 11g +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + +#define RTL8711_RF_MAX_SENS 6 +#define RTL8711_RF_DEF_SENS 4 + +// +// We now define the following channels as the max channels in each channel plan. +// 2G, total 14 chnls +// {1,2,3,4,5,6,7,8,9,10,11,12,13,14} +// 5G, total 24 chnls +// {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165} +#define MAX_CHANNEL_NUM_2G 14 +#define MAX_CHANNEL_NUM_5G 24 +#define MAX_CHANNEL_NUM 38//14+24 + +#define CENTER_CH_2G_NUM 14 +#define CENTER_CH_5G_20M_NUM 28 /* 20M center channels */ +#define CENTER_CH_5G_40M_NUM 14 /* 40M center channels */ +#define CENTER_CH_5G_80M_NUM 7 /* 80M center channels */ +#define CENTER_CH_5G_ALL_NUM (CENTER_CH_5G_20M_NUM + CENTER_CH_5G_40M_NUM + CENTER_CH_5G_80M_NUM) + +extern u8 center_ch_5g_20m[CENTER_CH_5G_20M_NUM]; +extern u8 center_ch_5g_40m[CENTER_CH_5G_40M_NUM]; +extern u8 center_ch_5g_80m[CENTER_CH_5G_80M_NUM]; +extern u8 center_ch_5g_all[CENTER_CH_5G_ALL_NUM]; + +u8 center_chs_5g_num(u8 bw); +u8 center_chs_5g(u8 bw, u8 id); + +//#define NUM_REGULATORYS 21 +#define NUM_REGULATORYS 1 + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +struct regulatory_class { + u32 starting_freq; //MHz, + u8 channel_set[MAX_CHANNEL_NUM]; + u8 channel_cck_power[MAX_CHANNEL_NUM];//dbm + u8 channel_ofdm_power[MAX_CHANNEL_NUM];//dbm + u8 txpower_limit; //dbm + u8 channel_spacing; //MHz + u8 modem; +}; + +typedef enum _CAPABILITY{ + cESS = 0x0001, + cIBSS = 0x0002, + cPollable = 0x0004, + cPollReq = 0x0008, + cPrivacy = 0x0010, + cShortPreamble = 0x0020, + cPBCC = 0x0040, + cChannelAgility = 0x0080, + cSpectrumMgnt = 0x0100, + cQos = 0x0200, // For HCCA, use with CF-Pollable and CF-PollReq + cShortSlotTime = 0x0400, + cAPSD = 0x0800, + cRM = 0x1000, // RRM (Radio Request Measurement) + cDSSS_OFDM = 0x2000, + cDelayedBA = 0x4000, + cImmediateBA = 0x8000, +}CAPABILITY, *PCAPABILITY; + +enum _REG_PREAMBLE_MODE{ + PREAMBLE_LONG = 1, + PREAMBLE_AUTO = 2, + PREAMBLE_SHORT = 3, +}; + + +enum _RTL8712_RF_MIMO_CONFIG_{ + RTL8712_RFCONFIG_1T=0x10, + RTL8712_RFCONFIG_2T=0x20, + RTL8712_RFCONFIG_1R=0x01, + RTL8712_RFCONFIG_2R=0x02, + RTL8712_RFCONFIG_1T1R=0x11, + RTL8712_RFCONFIG_1T2R=0x12, + RTL8712_RFCONFIG_TURBO=0x92, + RTL8712_RFCONFIG_2T2R=0x22 +}; + +typedef enum _RF_PATH { + RF_PATH_A = 0, + RF_PATH_B = 1, + RF_PATH_C = 2, + RF_PATH_D = 3, +} RF_PATH, *PRF_PATH; + +#define rf_path_char(path) (((path) >= RF_PATH_MAX) ? 'X' : 'A' + (path)) + +// Bandwidth Offset +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +typedef enum _BAND_TYPE { + BAND_ON_2_4G = 0, + BAND_ON_5G = 1, + BAND_ON_BOTH = 2, + BAND_MAX = 3, +} BAND_TYPE, *PBAND_TYPE; + +extern const char * const _band_str[]; +#define band_str(band) (((band) >= BAND_MAX) ? _band_str[BAND_MAX] : _band_str[(band)]) + +extern const u8 _band_to_band_cap[]; +#define band_to_band_cap(band) (((band) >= BAND_MAX) ? _band_to_band_cap[BAND_MAX] : _band_to_band_cap[(band)]) + +// Represent Channel Width in HT Capabilities +// +typedef enum _CHANNEL_WIDTH{ + CHANNEL_WIDTH_20 = 0, + CHANNEL_WIDTH_40 = 1, + CHANNEL_WIDTH_80 = 2, + CHANNEL_WIDTH_160 = 3, + CHANNEL_WIDTH_80_80 = 4, + CHANNEL_WIDTH_MAX = 5, +}CHANNEL_WIDTH, *PCHANNEL_WIDTH; + +extern const char * const _ch_width_str[]; +#define ch_width_str(bw) (((bw) >= CHANNEL_WIDTH_MAX) ? _ch_width_str[CHANNEL_WIDTH_MAX] : _ch_width_str[(bw)]) + +extern const u8 _ch_width_to_bw_cap[]; +#define ch_width_to_bw_cap(bw) (((bw) >= CHANNEL_WIDTH_MAX) ? _ch_width_to_bw_cap[CHANNEL_WIDTH_MAX] : _ch_width_to_bw_cap[(bw)]) + +// +// Represent Extention Channel Offset in HT Capabilities +// This is available only in 40Mhz mode. +// +typedef enum _EXTCHNL_OFFSET{ + EXTCHNL_OFFSET_NO_EXT = 0, + EXTCHNL_OFFSET_UPPER = 1, + EXTCHNL_OFFSET_NO_DEF = 2, + EXTCHNL_OFFSET_LOWER = 3, +}EXTCHNL_OFFSET, *PEXTCHNL_OFFSET; + +typedef enum _VHT_DATA_SC{ + VHT_DATA_SC_DONOT_CARE = 0, + VHT_DATA_SC_20_UPPER_OF_80MHZ = 1, + VHT_DATA_SC_20_LOWER_OF_80MHZ = 2, + VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3, + VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4, + VHT_DATA_SC_20_RECV1 = 5, + VHT_DATA_SC_20_RECV2 = 6, + VHT_DATA_SC_20_RECV3 = 7, + VHT_DATA_SC_20_RECV4 = 8, + VHT_DATA_SC_40_UPPER_OF_80MHZ = 9, + VHT_DATA_SC_40_LOWER_OF_80MHZ = 10, +}VHT_DATA_SC, *PVHT_DATA_SC_E; + +typedef enum _PROTECTION_MODE{ + PROTECTION_MODE_AUTO = 0, + PROTECTION_MODE_FORCE_ENABLE = 1, + PROTECTION_MODE_FORCE_DISABLE = 2, +}PROTECTION_MODE, *PPROTECTION_MODE; + +typedef enum _RT_RF_TYPE_DEFINITION +{ + RF_1T2R = 0, + RF_2T4R = 1, + RF_2T2R = 2, + RF_1T1R = 3, + RF_2T2R_GREEN = 4, + RF_2T3R = 5, + RF_3T3R = 6, + RF_3T4R = 7, + RF_4T4R = 8, + + RF_MAX_TYPE = 0xF, /* u1Byte */ +}RT_RF_TYPE_DEF_E; + +int rtw_ch2freq(int chan); +int rtw_freq2ch(int freq); +bool rtw_chbw_to_freq_range(u8 ch, u8 bw, u8 offset, u32 *hi, u32 *lo); + +#define RTW_MODULE_RTL8821AE_HMC_M2 BIT0 /* RTL8821AE(HMC+M.2) */ +#define RTW_MODULE_RTL8821AU BIT1 /* RTL8821AU */ +#define RTW_MODULE_RTL8812AENF_NGFF BIT2 /* RTL8812AENF(8812AE+8761)_NGFF */ +#define RTW_MODULE_RTL8812AEBT_HMC BIT3 /* RTL8812AEBT(8812AE+8761)_HMC */ +#define RTW_MODULE_RTL8188EE_HMC_M2 BIT4 /* RTL8188EE(HMC+M.2) */ +#define RTW_MODULE_RTL8723BE_HMC_M2 BIT5 /* RTL8723BE(HMC+M.2) */ +#define RTW_MODULE_RTL8723BS_NGFF1216 BIT6 /* RTL8723BS(NGFF1216) */ +#define RTW_MODULE_RTL8192EEBT_HMC_M2 BIT7 /* RTL8192EEBT(8192EE+8761AU)_(HMC+M.2) */ + +#define IS_ALPHA2_NO_SPECIFIED(_alpha2) ((*((u16 *)(_alpha2))) == 0xFFFF) + +struct country_chplan { + char alpha2[2]; + u8 chplan; +#ifdef CONFIG_80211AC_VHT + u8 en_11ac; +#endif +#if RTW_DEF_MODULE_REGULATORY_CERT + u8 def_module_flags; /* RTW_MODULE_RTLXXX */ +#endif +}; + +#ifdef CONFIG_80211AC_VHT +#define COUNTRY_CHPLAN_EN_11AC(_ent) ((_ent)->en_11ac) +#else +#define COUNTRY_CHPLAN_EN_11AC(_ent) 0 +#endif + +#if RTW_DEF_MODULE_REGULATORY_CERT +#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) ((_ent)->def_module_flags) +#else +#define COUNTRY_CHPLAN_DEF_MODULE_FALGS(_ent) 0 +#endif + +const struct country_chplan *rtw_get_chplan_from_country(const char *country_code); + +#define BB_GAIN_2G 0 +#ifdef CONFIG_IEEE80211_BAND_5GHZ +#define BB_GAIN_5GLB1 1 +#define BB_GAIN_5GLB2 2 +#define BB_GAIN_5GMB1 3 +#define BB_GAIN_5GMB2 4 +#define BB_GAIN_5GHB 5 +#endif + +#ifdef CONFIG_IEEE80211_BAND_5GHZ +#define BB_GAIN_NUM 6 +#else +#define BB_GAIN_NUM 1 +#endif + +int rtw_ch_to_bb_gain_sel(int ch); +void rtw_rf_set_tx_gain_offset(_adapter *adapter, u8 path, s8 offset); +void rtw_rf_apply_tx_gain_offset(_adapter *adapter, u8 ch); + +bool rtw_is_dfs_range(u32 hi, u32 lo); +bool rtw_is_dfs_ch(u8 ch, u8 bw, u8 offset); +bool rtw_is_long_cac_range(u32 hi, u32 lo); +bool rtw_is_long_cac_ch(u8 ch, u8 bw, u8 offset); + +#endif //_RTL8711_RF_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_security.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_security.h new file mode 100644 index 00000000..5820a55c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_security.h @@ -0,0 +1,490 @@ +/****************************************************************************** + * + * 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 __RTW_SECURITY_H_ +#define __RTW_SECURITY_H_ + + +#define _NO_PRIVACY_ 0x0 +#define _WEP40_ 0x1 +#define _TKIP_ 0x2 +#define _TKIP_WTMIC_ 0x3 +#define _AES_ 0x4 +#define _WEP104_ 0x5 +#define _WEP_WPA_MIXED_ 0x07 // WEP + WPA +#define _SMS4_ 0x06 +#ifdef CONFIG_IEEE80211W +#define _BIP_ 0x8 +#endif //CONFIG_IEEE80211W +/* 802.11W use wrong key */ +#define IEEE80211W_RIGHT_KEY 0x0 +#define IEEE80211W_WRONG_KEY 0x1 +#define IEEE80211W_NO_KEY 0x2 + +#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) + +const char *security_type_str(u8 value); + +#define _WPA_IE_ID_ 0xdd +#define _WPA2_IE_ID_ 0x30 + +#define SHA256_MAC_LEN 32 +#define AES_BLOCK_SIZE 16 +#define AES_PRIV_SIZE (4 * 44) + +#define RTW_KEK_LEN 16 +#define RTW_KCK_LEN 16 +#define RTW_REPLAY_CTR_LEN 8 + +typedef enum { + ENCRYP_PROTOCOL_OPENSYS, //open system + ENCRYP_PROTOCOL_WEP, //WEP + ENCRYP_PROTOCOL_WPA, //WPA + ENCRYP_PROTOCOL_WPA2, //WPA2 + ENCRYP_PROTOCOL_WAPI, //WAPI: Not support in this version + ENCRYP_PROTOCOL_MAX +}ENCRYP_PROTOCOL_E; + + +#ifndef Ndis802_11AuthModeWPA2 +#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) +#endif + +#ifndef Ndis802_11AuthModeWPA2PSK +#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) +#endif + +union pn48 { + + u64 val; + +#ifdef CONFIG_LITTLE_ENDIAN + +struct { + u8 TSC0; + u8 TSC1; + u8 TSC2; + u8 TSC3; + u8 TSC4; + u8 TSC5; + u8 TSC6; + u8 TSC7; +} _byte_; + +#elif defined(CONFIG_BIG_ENDIAN) + +struct { + u8 TSC7; + u8 TSC6; + u8 TSC5; + u8 TSC4; + u8 TSC3; + u8 TSC2; + u8 TSC1; + u8 TSC0; +} _byte_; + +#endif + +}; + +union Keytype { + u8 skey[16]; + u32 lkey[4]; +}; + + +typedef struct _RT_PMKID_LIST +{ + u8 bUsed; + u8 Bssid[6]; + u8 PMKID[16]; + u8 SsidBuf[33]; + u8* ssid_octet; + u16 ssid_length; +} RT_PMKID_LIST, *PRT_PMKID_LIST; + + +struct security_priv +{ + u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, 8021x and authswitch + u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm. + + /* WEP */ + u32 dot11PrivacyKeyIndex; // this is only valid for legendary wep, 0~3 for key id. (tx key index) + union Keytype dot11DefKey[4]; // this is only valid for def. key + u32 dot11DefKeylen[4]; + u8 key_mask; /* use to restore wep key after hal_init */ + + u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key + u32 dot118021XGrpKeyid; // key id used for Grp Key ( tx key index) + union Keytype dot118021XGrpKey[4]; // 802.1x Group Key, for inx0 and inx1 + union Keytype dot118021XGrptxmickey[4]; + union Keytype dot118021XGrprxmickey[4]; + union pn48 dot11Grptxpn; // PN48 used for Grp Key xmit. + union pn48 dot11Grprxpn; // PN48 used for Grp Key recv. +#ifdef CONFIG_IEEE80211W + u32 dot11wBIPKeyid; // key id used for BIP Key ( tx key index) + union Keytype dot11wBIPKey[6]; // BIP Key, for index4 and index5 + union pn48 dot11wBIPtxpn; // PN48 used for Grp Key xmit. + union pn48 dot11wBIPrxpn; // PN48 used for Grp Key recv. +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_AP_MODE + //extend security capabilities for AP_MODE + unsigned int dot8021xalg;//0:disable, 1:psk, 2:802.1x + unsigned int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + unsigned int wpa_group_cipher; + unsigned int wpa2_group_cipher; + unsigned int wpa_pairwise_cipher; + unsigned int wpa2_pairwise_cipher; +#endif + + u8 wps_ie[MAX_WPS_IE_LEN];//added in assoc req + int wps_ie_len; + + + u8 binstallGrpkey; +#ifdef CONFIG_GTK_OL + u8 binstallKCK_KEK; +#endif //CONFIG_GTK_OL +#ifdef CONFIG_IEEE80211W + u8 binstallBIPkey; +#endif //CONFIG_IEEE80211W + u8 busetkipkey; + //_timer tkip_timer; + u8 bcheck_grpkey; + u8 bgrpkey_handshake; + + //u8 packet_cnt;//unused, removed + + s32 sw_encrypt;//from registry_priv + s32 sw_decrypt;//from registry_priv + + s32 hw_decrypted;//if the rx packets is hw_decrypted==_FALSE, it means the hw has not been ready. + + + //keeps the auth_type & enc_status from upper layer ioctl(wpa_supplicant or wzc) + u32 ndisauthtype; // NDIS_802_11_AUTHENTICATION_MODE + u32 ndisencryptstatus; // NDIS_802_11_ENCRYPTION_STATUS + + NDIS_802_11_WEP ndiswep; +#ifdef PLATFORM_WINDOWS + u8 KeyMaterial[16];// variable length depending on above field. +#endif + + u8 assoc_info[600]; + u8 szofcapability[256]; //for wpa2 usage + u8 oidassociation[512]; //for wpa/wpa2 usage + u8 authenticator_ie[256]; //store ap security information element + u8 supplicant_ie[256]; //store sta security information element + + + //for tkip countermeasure + u32 last_mic_err_time; + u8 btkip_countermeasure; + u8 btkip_wait_report; + u32 btkip_countermeasure_time; + + //--------------------------------------------------------------------------- + // For WPA2 Pre-Authentication. + //--------------------------------------------------------------------------- + //u8 RegEnablePreAuth; // Default value: Pre-Authentication enabled or not, from registry "EnablePreAuth". Added by Annie, 2005-11-01. + //u8 EnablePreAuthentication; // Current Value: Pre-Authentication enabled or not. + RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; // Renamed from PreAuthKey[NUM_PRE_AUTH_KEY]. Annie, 2006-10-13. + u8 PMKIDIndex; + //u32 PMKIDCount; // Added by Annie, 2006-10-13. + //u8 szCapability[256]; // For WPA2-PSK using zero-config, by Annie, 2005-09-20. + + u8 bWepDefaultKeyIdxSet; + +#define DBG_SW_SEC_CNT +#ifdef DBG_SW_SEC_CNT + u64 wep_sw_enc_cnt_bc; + u64 wep_sw_enc_cnt_mc; + u64 wep_sw_enc_cnt_uc; + u64 wep_sw_dec_cnt_bc; + u64 wep_sw_dec_cnt_mc; + u64 wep_sw_dec_cnt_uc; + + u64 tkip_sw_enc_cnt_bc; + u64 tkip_sw_enc_cnt_mc; + u64 tkip_sw_enc_cnt_uc; + u64 tkip_sw_dec_cnt_bc; + u64 tkip_sw_dec_cnt_mc; + u64 tkip_sw_dec_cnt_uc; + + u64 aes_sw_enc_cnt_bc; + u64 aes_sw_enc_cnt_mc; + u64 aes_sw_enc_cnt_uc; + u64 aes_sw_dec_cnt_bc; + u64 aes_sw_dec_cnt_mc; + u64 aes_sw_dec_cnt_uc; +#endif /* DBG_SW_SEC_CNT */ +}; + +struct sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +}; + +#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\ +do{\ + switch(psecuritypriv->dot11AuthAlgrthm)\ + {\ + case dot11AuthAlgrthm_Open:\ + case dot11AuthAlgrthm_Shared:\ + case dot11AuthAlgrthm_Auto:\ + encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;\ + break;\ + case dot11AuthAlgrthm_8021X:\ + if(bmcst)\ + encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\ + else\ + encry_algo =(u8) psta->dot118021XPrivacy;\ + break;\ + case dot11AuthAlgrthm_WAPI:\ + encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;\ + break;\ + }\ +}while(0) + +#define _AES_IV_LEN_ 8 + +#define SET_ICE_IV_LEN( iv_len, icv_len, encrypt)\ +do{\ + switch(encrypt)\ + {\ + case _WEP40_:\ + case _WEP104_:\ + iv_len = 4;\ + icv_len = 4;\ + break;\ + case _TKIP_:\ + iv_len = 8;\ + icv_len = 4;\ + break;\ + case _AES_:\ + iv_len = 8;\ + icv_len = 8;\ + break;\ + case _SMS4_:\ + iv_len = 18;\ + icv_len = 16;\ + break;\ + default:\ + iv_len = 0;\ + icv_len = 0;\ + break;\ + }\ +}while(0) + + +#define GET_TKIP_PN(iv,dot11txpn)\ +do{\ + dot11txpn._byte_.TSC0=iv[2];\ + dot11txpn._byte_.TSC1=iv[0];\ + dot11txpn._byte_.TSC2=iv[4];\ + dot11txpn._byte_.TSC3=iv[5];\ + dot11txpn._byte_.TSC4=iv[6];\ + dot11txpn._byte_.TSC5=iv[7];\ +}while(0) + + +#define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + +struct mic_data +{ + u32 K0, K1; // Key + u32 L, R; // Current state + u32 M; // Message accumulator (single word) + u32 nBytesInM; // # bytes in M +}; + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ + ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) + +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } + +#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) + +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif +#ifdef CONFIG_IEEE80211W +int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac); +#endif //CONFIG_IEEE80211W +void rtw_secmicsetkey(struct mic_data *pmicdata, u8 * key ); +void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b ); +void rtw_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nBytes ); +void rtw_secgetmic(struct mic_data *pmicdata, u8 * dst ); + +void rtw_seccalctkipmic( + u8 * key, + u8 *header, + u8 *data, + u32 data_len, + u8 *Miccode, + u8 priority); + +u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe); +u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe); +void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe); + +u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe); +u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe); +void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe); +#ifdef CONFIG_IEEE80211W +u32 rtw_BIP_verify(_adapter *padapter, u8 *precvframe); +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_TDLS +void wpa_tdls_generate_tpk(_adapter *padapter, PVOID sta); +int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie, + u8 *mic); +int wpa_tdls_teardown_ftie_mic(u8 *kck, u8 *lnkid, u16 reason, + u8 dialog_token, u8 trans_seq, u8 *ftie, u8 *mic); +int tdls_verify_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie); +#endif //CONFIG_TDLS + +void rtw_use_tkipkey_handler(RTW_TIMER_HDL_ARGS); + +void rtw_sec_restore_wep_key(_adapter *adapter); +u8 rtw_handle_tkip_countermeasure(_adapter* adapter, const char *caller); + +#ifdef CONFIG_WOWLAN +u16 rtw_calc_crc(u8 *pdata, int length); +#endif /*CONFIG_WOWLAN*/ + +#endif //__RTL871X_SECURITY_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_sreset.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_sreset.h new file mode 100644 index 00000000..4a225589 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_sreset.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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_SRESET_H_ +#define _RTW_SRESET_H_ + +//#include + +enum { + SRESET_TGP_NULL = 0, + SRESET_TGP_XMIT_STATUS = 1, + SRESET_TGP_LINK_STATUS = 2, +}; + +struct sreset_priv { + _mutex silentreset_mutex; + u8 silent_reset_inprogress; + u8 Wifi_Error_Status; + unsigned long last_tx_time; + unsigned long last_tx_complete_time; + + s32 dbg_trigger_point; +}; + + + +#define WIFI_STATUS_SUCCESS 0 +#define USB_VEN_REQ_CMD_FAIL BIT0 +#define USB_READ_PORT_FAIL BIT1 +#define USB_WRITE_PORT_FAIL BIT2 +#define WIFI_MAC_TXDMA_ERROR BIT3 +#define WIFI_TX_HANG BIT4 +#define WIFI_RX_HANG BIT5 +#define WIFI_IF_NOT_EXIST BIT6 + +void sreset_init_value(_adapter *padapter); +void sreset_reset_value(_adapter *padapter); +u8 sreset_get_wifi_status(_adapter *padapter); +void sreset_set_wifi_error_status(_adapter *padapter, u32 status); +void sreset_set_trigger_point(_adapter *padapter, s32 tgp); +bool sreset_inprogress(_adapter *padapter); +void sreset_reset(_adapter *padapter); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_tdls.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_tdls.h new file mode 100644 index 00000000..ed54a996 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_tdls.h @@ -0,0 +1,149 @@ +/****************************************************************************** + * + * 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 __RTW_TDLS_H_ +#define __RTW_TDLS_H_ + + +#ifdef CONFIG_TDLS +/* TDLS STA state */ + + +/* TDLS Diect Link Establishment */ +#define TDLS_STATE_NONE 0x00000000 /* Default state */ +#define TDLS_INITIATOR_STATE BIT(28) /* 0x10000000 */ +#define TDLS_RESPONDER_STATE BIT(29) /* 0x20000000 */ +#define TDLS_LINKED_STATE BIT(30) /* 0x40000000 */ +/* TDLS PU Buffer STA */ +#define TDLS_WAIT_PTR_STATE BIT(24) /* 0x01000000 */ /* Waiting peer's TDLS_PEER_TRAFFIC_RESPONSE frame */ +/* TDLS Check ALive */ +#define TDLS_ALIVE_STATE BIT(20) /* 0x00100000 */ /* Check if peer sta is alived. */ +/* TDLS Channel Switch */ +#define TDLS_CH_SWITCH_ON_STATE BIT(16) /* 0x00010000 */ +#define TDLS_PEER_AT_OFF_STATE BIT(17) /* 0x00020000 */ /* Could send pkt on target ch */ +#define TDLS_CH_SW_INITIATOR_STATE BIT(18) /* 0x00040000 */ /* Avoid duplicated or unconditional ch. switch rsp. */ +#define TDLS_WAIT_CH_RSP_STATE BIT(19) /* 0x00080000 */ /* Wait Ch. response as we are TDLS channel switch initiator */ + + +#define TPK_RESEND_COUNT 1800 /*Unit: seconds */ +#define CH_SWITCH_TIME 5 +#define CH_SWITCH_TIMEOUT 20 +#define TDLS_SIGNAL_THRESH 0x20 +#define TDLS_WATCHDOG_PERIOD 10 /* Periodically sending tdls discovery request in TDLS_WATCHDOG_PERIOD * 2 sec */ +#define TDLS_HANDSHAKE_TIME 3000 +#define TDLS_PTI_TIME 7000 + +#define TDLS_MIC_LEN 16 +#define WPA_NONCE_LEN 32 +#define TDLS_TIMEOUT_LEN 4 + +struct wpa_tdls_ftie { + u8 ie_type; /* FTIE */ + u8 ie_len; + u8 mic_ctrl[2]; + u8 mic[TDLS_MIC_LEN]; + u8 Anonce[WPA_NONCE_LEN]; /* Responder Nonce in TDLS */ + u8 Snonce[WPA_NONCE_LEN]; /* Initiator Nonce in TDLS */ + /* followed by optional elements */ +} ; + +struct wpa_tdls_lnkid { + u8 ie_type; /* Link Identifier IE */ + u8 ie_len; + u8 bssid[ETH_ALEN]; + u8 init_sta[ETH_ALEN]; + u8 resp_sta[ETH_ALEN]; +} ; + +static u8 TDLS_RSNIE[20]={ 0x01, 0x00, /* Version shall be set to 1 */ + 0x00, 0x0f, 0xac, 0x07, /* Group sipher suite */ + 0x01, 0x00, /* Pairwise cipher suite count */ + 0x00, 0x0f, 0xac, 0x04, /* Pairwise cipher suite list; CCMP only */ + 0x01, 0x00, /* AKM suite count */ + 0x00, 0x0f, 0xac, 0x07, /* TPK Handshake */ + 0x0c, 0x02, + /* PMKID shall not be present */ + }; + +static u8 TDLS_WMMIE[]={0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; /* Qos info all set zero */ + +static u8 TDLS_WMM_PARAM_IE[] = {0x00, 0x00, 0x03, 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00}; + +static u8 TDLS_EXT_CAPIE[] = {0x00, 0x00, 0x00, 0x50, 0x20, 0x00, 0x00, 0x00}; /* bit(28), bit(30), bit(37) */ + +/* SRC: Supported Regulatory Classes */ +static u8 TDLS_SRC[] = { 0x01, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21 }; + +int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len); +int check_ap_tdls_ch_switching_prohibited(u8 *pframe, u8 pkt_len); +void rtw_reset_tdls_info(_adapter* padapter); +int rtw_init_tdls_info(_adapter* padapter); +void rtw_free_tdls_info(struct tdls_info *ptdlsinfo); +int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms); +void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta); +void rtw_free_tdls_timer(struct sta_info *psta); +void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta); +#ifdef CONFIG_WFD +int issue_tunneled_probe_req(_adapter *padapter); +int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame); +#endif /* CONFIG_WFD */ +int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt); +int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack); +int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt); +int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt); +int issue_tdls_dis_rsp(_adapter * padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy); +int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack); +int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *psta, struct tdls_txmgmt *ptxmgmt); +int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *psta); +int issue_tdls_ch_switch_req(_adapter *padapter, struct sta_info *ptdls_sta); +int issue_tdls_ch_switch_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack); +sint On_TDLS_Dis_Rsp(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Setup_Req(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Setup_Rsp(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Setup_Cfm(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Dis_Req(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Teardown(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Peer_Traffic_Indication(_adapter *adapter, union recv_frame *precv_frame); +int On_TDLS_Peer_Traffic_Rsp(_adapter *adapter, union recv_frame *precv_frame); +#ifdef CONFIG_TDLS_CH_SW +sint On_TDLS_Ch_Switch_Req(_adapter *adapter, union recv_frame *precv_frame); +sint On_TDLS_Ch_Switch_Rsp(_adapter *adapter, union recv_frame *precv_frame); +void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +#endif +void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, u8 privacy); +void rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt); +void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); +void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe); + +u8 update_sgi_tdls(_adapter *padapter, struct sta_info *psta); +u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta); +int rtw_tdls_is_driver_setup(_adapter *padapter); +void rtw_tdls_set_key(_adapter *padapter, struct sta_info *ptdls_sta); +const char * rtw_tdls_action_txt(enum TDLS_ACTION_FIELD action); +#endif /* CONFIG_TDLS */ + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_version.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_version.h new file mode 100644 index 00000000..3e3cb7ce --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_version.h @@ -0,0 +1 @@ +#define DRIVERVERSION "v4.3.24_15589.20151023" diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_vht.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_vht.h new file mode 100644 index 00000000..def791ab --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_vht.h @@ -0,0 +1,143 @@ +/****************************************************************************** + * + * 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 _RTW_VHT_H_ +#define _RTW_VHT_H_ + +#define LDPC_VHT_ENABLE_RX BIT0 +#define LDPC_VHT_ENABLE_TX BIT1 +#define LDPC_VHT_TEST_TX_ENABLE BIT2 +#define LDPC_VHT_CAP_TX BIT3 + +#define STBC_VHT_ENABLE_RX BIT0 +#define STBC_VHT_ENABLE_TX BIT1 +#define STBC_VHT_TEST_TX_ENABLE BIT2 +#define STBC_VHT_CAP_TX BIT3 + +#define BEAMFORMING_VHT_BEAMFORMER_ENABLE BIT0 // Declare our NIC supports beamformer +#define BEAMFORMING_VHT_BEAMFORMEE_ENABLE BIT1 // Declare our NIC supports beamformee +#define BEAMFORMING_VHT_MU_MIMO_AP_ENABLE BIT2 /*Declare our NIC support MU-MIMO AP mode*/ +#define BEAMFORMING_VHT_MU_MIMO_STA_ENABLE BIT3 /*Declare our NIC support MU-MIMO STA mode*/ +#define BEAMFORMING_VHT_BEAMFORMER_TEST BIT4 /*Transmiting Beamforming no matter the target supports it or not*/ +#define BEAMFORMING_VHT_BEAMFORMER_STS_CAP (BIT8|BIT9|BIT10) /*Asoc rsp cap*/ +#define BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM (BIT12|BIT13|BIT14) /*Asoc rsp cap*/ + + +//VHT capability info +#define SET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 0, 2, _val) +#define SET_VHT_CAPABILITY_ELE_CHL_WIDTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 2, 2, _val) +#define SET_VHT_CAPABILITY_ELE_RX_LDPC(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 4, 1, _val) +#define SET_VHT_CAPABILITY_ELE_SHORT_GI80M(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 5, 1, _val) +#define SET_VHT_CAPABILITY_ELE_SHORT_GI160M(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 6, 1, _val) +#define SET_VHT_CAPABILITY_ELE_TX_STBC(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 7, 1, _val) +#define SET_VHT_CAPABILITY_ELE_RX_STBC(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+1, 0, 3, _val) +#define SET_VHT_CAPABILITY_ELE_SU_BFER(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+1, 3, 1, _val) +#define SET_VHT_CAPABILITY_ELE_SU_BFEE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+1, 4, 1, _val) +#define SET_VHT_CAPABILITY_ELE_BFER_ANT_SUPP(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+1, 5, 3, _val) +#define SET_VHT_CAPABILITY_ELE_SOUNDING_DIMENSIONS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 0, 3, _val) + +#define SET_VHT_CAPABILITY_ELE_MU_BFER(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 3, 1, _val) +#define SET_VHT_CAPABILITY_ELE_MU_BFEE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 4, 1, _val) +#define SET_VHT_CAPABILITY_ELE_TXOP_PS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 5, 1, _val) +#define SET_VHT_CAPABILITY_ELE_HTC_VHT(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 6, 1, _val) +#define SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+2, 7, 3, _val) //B23~B25 +#define SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+2, 2, 2, _val) +#define SET_VHT_CAPABILITY_ELE_MCS_RX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+4, 0, 16, _val) /* B0~B15 indicate Rx MCS MAP, we write 0 to indicate MCS0~7. by page */ +#define SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+6, 0, 13, _val) +#define SET_VHT_CAPABILITY_ELE_MCS_TX_MAP(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+8, 0, 16, _val) /* B0~B15 indicate Tx MCS MAP, we write 0 to indicate MCS0~7. by page */ +#define SET_VHT_CAPABILITY_ELE_MCS_TX_HIGHEST_RATE(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+10, 0, 13, _val) + + +#define GET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 0, 2) +#define GET_VHT_CAPABILITY_ELE_CHL_WIDTH(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 2, 2) +#define GET_VHT_CAPABILITY_ELE_RX_LDPC(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 4, 1) +#define GET_VHT_CAPABILITY_ELE_SHORT_GI80M(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 5, 1) +#define GET_VHT_CAPABILITY_ELE_SHORT_GI160M(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 6, 1) +#define GET_VHT_CAPABILITY_ELE_TX_STBC(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 7, 1) +#define GET_VHT_CAPABILITY_ELE_RX_STBC(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+1, 0, 3) +#define GET_VHT_CAPABILITY_ELE_SU_BFER(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+1, 3, 1) +#define GET_VHT_CAPABILITY_ELE_SU_BFEE(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+1, 4, 1) +/*phydm-beamforming*/ +#define GET_VHT_CAPABILITY_ELE_SU_BFEE_STS_CAP(_pEleStart) LE_BITS_TO_2BYTE((_pEleStart)+1, 5, 3) +#define GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(_pEleStart) LE_BITS_TO_2BYTE((_pEleStart)+2, 0, 3) +#define GET_VHT_CAPABILITY_ELE_TXOP_PS(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+2, 5, 1) +#define GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(_pEleStart) LE_BITS_TO_2BYTE((_pEleStart)+2, 7, 3) +#define GET_VHT_CAPABILITY_ELE_RX_MCS(_pEleStart) ((_pEleStart)+4) +#define GET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(_pEleStart) LE_BITS_TO_2BYTE((_pEleStart)+6, 0, 13) +#define GET_VHT_CAPABILITY_ELE_TX_MCS(_pEleStart) ((_pEleStart)+8) +#define GET_VHT_CAPABILITY_ELE_MCS_TX_HIGHEST_RATE(_pEleStart) LE_BITS_TO_2BYTE((_pEleStart)+10, 0, 13) + + +//VHT Operation Information Element +#define SET_VHT_OPERATION_ELE_CHL_WIDTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 0, 8, _val) +#define SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart+1, 0, 8, _val) +#define SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart+2, 0, 8, _val) +#define SET_VHT_OPERATION_ELE_BASIC_MCS_SET(_pEleStart, _val) SET_BITS_TO_LE_2BYTE((_pEleStart)+3, 0, 16, _val) + +#define GET_VHT_OPERATION_ELE_CHL_WIDTH(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart,0,8) +#define GET_VHT_OPERATION_ELE_CENTER_FREQ1(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+1,0,8) +#define GET_VHT_OPERATION_ELE_CENTER_FREQ2(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+2,0,8) + +//VHT Operating Mode +#define SET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 0, 2, _val) +#define SET_VHT_OPERATING_MODE_FIELD_RX_NSS(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 4, 3, _val) +#define SET_VHT_OPERATING_MODE_FIELD_RX_NSS_TYPE(_pEleStart, _val) SET_BITS_TO_LE_1BYTE(_pEleStart, 7, 1, _val) +#define GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 0, 2) +#define GET_VHT_OPERATING_MODE_FIELD_RX_NSS(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 4, 3) +#define GET_VHT_OPERATING_MODE_FIELD_RX_NSS_TYPE(_pEleStart) LE_BITS_TO_1BYTE(_pEleStart, 7, 1) + +#define SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(_pEleStart, _val) SET_BITS_TO_LE_1BYTE((_pEleStart)+7, 6, 1, _val) +#define GET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(_pEleStart) LE_BITS_TO_1BYTE((_pEleStart)+7, 6, 1) + +struct vht_priv +{ + u8 vht_option; + + u8 ldpc_cap; + u8 stbc_cap; + u16 beamform_cap; + + u8 sgi_80m;//short GI + u8 ampdu_len; + + u8 vht_op_mode_notify; + u8 vht_highest_rate; + u8 vht_mcs_map[2]; + + u8 vht_cap[32]; +}; + +u8 rtw_get_vht_highest_rate(u8 *pvht_mcs_map); +u16 rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate); +u64 rtw_vht_rate_to_bitmap(u8 *pVHTRate); +void rtw_vht_use_default_setting(_adapter *padapter); +u32 rtw_build_vht_operation_ie(_adapter *padapter, u8 *pbuf, u8 channel); +u32 rtw_build_vht_op_mode_notify_ie(_adapter *padapter, u8 *pbuf, u8 bw); +u32 rtw_build_vht_cap_ie(_adapter *padapter, u8 *pbuf); +void update_sta_vht_info_apmode(_adapter *padapter, PVOID psta); +void update_hw_vht_param(_adapter *padapter); +void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void VHT_operation_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void rtw_process_vht_op_mode_notify(_adapter *padapter, u8 *pframe, PVOID sta); +u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len); +void VHTOnAssocRsp(_adapter *padapter); +u8 rtw_vht_mcsmap_to_nss(u8 *pvht_mcs_map); + +#endif //_RTW_VHT_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_wapi.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_wapi.h new file mode 100644 index 00000000..582410c6 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/rtw_wapi.h @@ -0,0 +1,222 @@ +#ifndef __INC_WAPI_H +#define __INC_WAPI_H + + +#define CONFIG_WAPI_SW_SMS4 +#define WAPI_DEBUG + +#define SMS4_MIC_LEN 16 +#define WAPI_EXT_LEN 18 +#define MAX_WAPI_IE_LEN 256 +#define sMacHdrLng 24 // octets in data header, no WEP + +#ifdef WAPI_DEBUG + +/* WAPI trace debug */ +extern u32 wapi_debug_component; + +static inline void dump_buf(u8 *buf, u32 len) +{ + u32 i; + printk("-----------------Len %d----------------\n", len); + for(i=0; i4096), HW will execute + // memoryR/W CRC error. And then all DMA fetch will fail. We must decrease descriptor + // number or enlarge descriptor size as 64 bytes. + unsigned int txdw12; + unsigned int txdw13; + unsigned int txdw14; + unsigned int txdw15; +#endif +}; +#endif + +union txdesc { + struct tx_desc txdesc; + unsigned int value[TXDESC_SIZE>>2]; +}; + +#ifdef CONFIG_PCI_HCI +#define PCI_MAX_TX_QUEUE_COUNT 8 + +struct rtw_tx_ring { + unsigned char qid; + struct tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + _queue queue; + u32 qlen; +}; +#endif + +struct hw_xmit { + //_lock xmit_lock; + //_list pending; + _queue *sta_queue; + //struct hw_txqueue *phwtxqueue; + //sint txcmdcnt; + int accnt; +}; + +#if 0 +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + int pktlen; //the original 802.3 pkt raw_data len (not include ether_hdr data) + int pkt_hdrlen; //the original 802.3 pkt header len + int hdrlen; //the WLAN Header Len + int nr_frags; + int last_txcmdsz; + int encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv[8]; + int iv_len; + u8 icv[8]; + int icv_len; + int priority; + int ack_policy; + int mac_id; + int vcs_mode; //virtual carrier sense method + + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + + u8 key_idx; + + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 mdata;//more data bit + u8 eosp; + + u8 triggered;//for ap mode handling Power Saving sta + + u32 qsel; + u16 seqnum; + + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif +}; +#else +//reduce size +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + 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) + u32 last_txcmdsz; + u8 nr_frags; + u8 encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv_len; + u8 icv_len; + u8 iv[18]; + u8 icv[16]; + u8 priority; + u8 ack_policy; + u8 mac_id; + u8 vcs_mode; //virtual carrier sense method + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + u8 key_idx; + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 ampdu_spacing; //ampdu_min_spacing for peer sta's rx + u8 mdata;//more data bit + u8 pctrl;//per packet txdesc control enable + u8 triggered;//for ap mode handling Power Saving sta + u8 qsel; + u8 order;//order bit + u8 eosp; + u8 rate; + u8 intel_proxim; + u8 retry_ctrl; + u8 mbssid; + u8 ldpc; + u8 stbc; + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif + + u8 rtsen; + u8 cts2self; + union Keytype dot11tkiptxmickey; + //union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; + +#ifdef CONFIG_TDLS + u8 direct_link; + struct sta_info *ptdls_sta; +#endif //CONFIG_TDLS + u8 key_type; + + u8 icmp_pkt; + +#ifdef CONFIG_BEAMFORMING + u16 txbf_p_aid;/*beamforming Partial_AID*/ + u16 txbf_g_id;/*beamforming Group ID*/ + #endif + +}; +#endif + +#define WLANHDR_OFFSET 64 + +#define NULL_FRAMETAG (0x0) +#define DATA_FRAMETAG 0x01 +#define L2_FRAMETAG 0x02 +#define MGNT_FRAMETAG 0x03 +#define AMSDU_FRAMETAG 0x04 + +#define EII_FRAMETAG 0x05 +#define IEEE8023_FRAMETAG 0x06 + +#define MP_FRAMETAG 0x07 + +#define TXAGG_FRAMETAG 0x08 + +enum { + XMITBUF_DATA = 0, + XMITBUF_MGNT = 1, + XMITBUF_CMD = 2, +}; + +bool rtw_xmit_ac_blocked(_adapter *adapter); + +struct submit_ctx{ + u32 submit_time; /* */ + u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */ + int status; /* status for operation */ +#ifdef PLATFORM_LINUX + struct completion done; +#endif +}; + +enum { + RTW_SCTX_SUBMITTED = -1, + RTW_SCTX_DONE_SUCCESS = 0, + RTW_SCTX_DONE_UNKNOWN, + RTW_SCTX_DONE_TIMEOUT, + RTW_SCTX_DONE_BUF_ALLOC, + RTW_SCTX_DONE_BUF_FREE, + RTW_SCTX_DONE_WRITE_PORT_ERR, + RTW_SCTX_DONE_TX_DESC_NA, + RTW_SCTX_DONE_TX_DENY, + RTW_SCTX_DONE_CCX_PKT_FAIL, + RTW_SCTX_DONE_DRV_STOP, + RTW_SCTX_DONE_DEV_REMOVE, + RTW_SCTX_DONE_CMD_ERROR, +}; + + +void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); +int rtw_sctx_wait(struct submit_ctx *sctx, const char *msg); +void rtw_sctx_done_err(struct submit_ctx **sctx, int status); +void rtw_sctx_done(struct submit_ctx **sctx); + +struct xmit_buf +{ + _list list; + + _adapter *padapter; + + u8 *pallocated_buf; + + u8 *pbuf; + + void *priv_data; + + u16 buf_tag; // 0: Normal xmitbuf, 1: extension xmitbuf, 2:cmd xmitbuf + u16 flags; + u32 alloc_sz; + + u32 len; + + struct submit_ctx *sctx; + +#ifdef CONFIG_USB_HCI + + //u32 sz[8]; + u32 ff_hwaddr; + +#if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) + PURB pxmit_urb[8]; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +#endif + + u8 bpending[8]; + + sint last[8]; + +#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + u32 ff_hwaddr; + u8 pg_num; + u8 agg_num; +#ifdef PLATFORM_OS_XP + PMDL pxmitbuf_mdl; + PIRP pxmitbuf_irp; + PSDBUS_REQUEST_PACKET pxmitbuf_sdrp; +#endif +#endif + +#ifdef CONFIG_PCI_HCI + struct tx_desc *desc; +#endif + +#if defined(DBG_XMIT_BUF )|| defined(DBG_XMIT_BUF_EXT) + u8 no; +#endif + +}; + + +struct xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + + u8 *buf_addr; + + struct xmit_buf *pxmitbuf; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 pg_num; + u8 agg_num; +#endif + +#ifdef CONFIG_USB_HCI +#ifdef CONFIG_USB_TX_AGGREGATION + u8 agg_num; +#endif + s8 pkt_offset; +#endif + +#ifdef CONFIG_XMIT_ACK + u8 ack_report; +#endif + + u8 *alloc_addr; /* the actual address this xmitframe allocated */ + u8 ext_tag; /* 0:data, 1:mgmt */ + +}; + +struct tx_servq { + _list tx_pending; + _queue sta_pending; + int qcnt; +}; + + +struct sta_xmit_priv +{ + _lock lock; + sint option; + sint apsd_setting; //When bit mask is on, the associated edca queue supports APSD. + + + //struct tx_servq blk_q[MAX_NUMBLKS]; + struct tx_servq be_q; //priority == 0,3 + struct tx_servq bk_q; //priority == 1,2 + struct tx_servq vi_q; //priority == 4,5 + struct tx_servq vo_q; //priority == 6,7 + _list legacy_dz; + _list apsd; + + u16 txseq_tid[16]; + + //uint sta_tx_bytes; + //u64 sta_tx_pkts; + //uint sta_tx_fail; + + +}; + + +struct hw_txqueue { + volatile sint head; + volatile sint tail; + volatile sint free_sz; //in units of 64 bytes + volatile sint free_cmdsz; + volatile sint txsz[8]; + uint ff_hwaddr; + uint cmd_hwaddr; + sint ac_tag; +}; + +struct agg_pkt_info{ + u16 offset; + u16 pkt_len; +}; + +enum cmdbuf_type { + CMDBUF_BEACON = 0x00, + CMDBUF_RSVD, + CMDBUF_MAX +}; + +u8 rtw_get_hwseq_no(_adapter *padapter); + +struct xmit_priv { + + _lock lock; + + _sema xmit_sema; + _sema terminate_xmitthread_sema; + + //_queue blk_strms[MAX_NUMBLKS]; + _queue be_pending; + _queue bk_pending; + _queue vi_pending; + _queue vo_pending; + _queue bm_pending; + + //_queue legacy_dz_queue; + //_queue apsd_queue; + + u8 *pallocated_frame_buf; + u8 *pxmit_frame_buf; + uint free_xmitframe_cnt; + _queue free_xmit_queue; + + //uint mapping_addr; + //uint pkt_sz; + + u8 *xframe_ext_alloc_addr; + u8 *xframe_ext; + uint free_xframe_ext_cnt; + _queue free_xframe_ext_queue; + + //struct hw_txqueue be_txqueue; + //struct hw_txqueue bk_txqueue; + //struct hw_txqueue vi_txqueue; + //struct hw_txqueue vo_txqueue; + //struct hw_txqueue bmc_txqueue; + + uint frag_len; + + _adapter *adapter; + + u8 vcs_setting; + u8 vcs; + u8 vcs_type; + //u16 rts_thresh; + + u64 tx_bytes; + u64 tx_pkts; + u64 tx_drop; + u64 last_tx_pkts; + + struct hw_xmit *hwxmits; + u8 hwxmit_entry; + + u8 wmm_para_seq[4];//sequence for wmm ac parameter strength from large to small. it's value is 0->vo, 1->vi, 2->be, 3->bk. + +#ifdef CONFIG_USB_HCI + _sema tx_retevt;//all tx return event; + u8 txirp_cnt;// + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +// USB_TRANSFER usb_transfer_write_mem; +#endif +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#ifdef PLATFORM_FREEBSD + struct task xmit_tasklet; +#endif + //per AC pending irp + int beq_cnt; + int bkq_cnt; + int viq_cnt; + int voq_cnt; + +#endif + +#ifdef CONFIG_PCI_HCI + // Tx + struct rtw_tx_ring tx_ring[PCI_MAX_TX_QUEUE_COUNT]; + int txringcount[PCI_MAX_TX_QUEUE_COUNT]; + u8 beaconDMAing; //flag of indicating beacon is transmiting to HW by DMA +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#endif + +#if defined (CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#ifdef CONFIG_SDIO_TX_TASKLET + #ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; + #endif /* PLATFORM_LINUX */ +#else + _thread_hdl_ SdioXmitThread; + _sema SdioXmitSema; + _sema SdioXmitTerminateSema; +#endif /* CONFIG_SDIO_TX_TASKLET */ +#endif /* CONFIG_SDIO_HCI */ + + _queue free_xmitbuf_queue; + _queue pending_xmitbuf_queue; + u8 *pallocated_xmitbuf; + u8 *pxmitbuf; + uint free_xmitbuf_cnt; + + _queue free_xmit_extbuf_queue; + u8 *pallocated_xmit_extbuf; + u8 *pxmit_extbuf; + 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 + + #ifdef CONFIG_SDIO_HCI + #define MAX_AGG_PKT_NUM 20 + #else + #define MAX_AGG_PKT_NUM 256 //Max tx ampdu coounts + #endif + + struct agg_pkt_info agg_pkt[MAX_AGG_PKT_NUM]; + #endif + +#ifdef CONFIG_XMIT_ACK + int ack_tx; + _mutex ack_tx_mutex; + struct submit_ctx ack_tx_ops; + u8 seq_no; +#endif + _lock lock_sctx; +}; + +extern struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv, + enum cmdbuf_type buf_type); +#define rtw_alloc_cmdxmitframe(p) __rtw_alloc_cmdxmitframe(p, CMDBUF_RSVD) +#if defined(CONFIG_RTL8192E) && defined(CONFIG_PCI_HCI) +extern struct xmit_frame *__rtw_alloc_cmdxmitframe_8192ee(struct xmit_priv *pxmitpriv, + enum cmdbuf_type buf_type); +#define rtw_alloc_bcnxmitframe(p) __rtw_alloc_cmdxmitframe_8192ee(p, CMDBUF_BEACON) +#else +#define rtw_alloc_bcnxmitframe(p) __rtw_alloc_cmdxmitframe(p, CMDBUF_BEACON) +#endif + +extern struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +extern struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +void rtw_count_tx_stats(_adapter *padapter, struct xmit_frame *pxmitframe, int sz); +extern void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len); +static s32 update_attrib_sec_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta); +static void update_attrib_phy_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta); +extern s32 rtw_make_wlanhdr(_adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib); +extern s32 rtw_put_snap(u8 *data, u16 h_proto); + +extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv); +struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); +extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); +struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac); +extern s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +extern struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); + +extern s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); +extern u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); +#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue(&f->attrib) +extern s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +#ifdef CONFIG_IEEE80211W +extern s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_TDLS +extern struct tdls_txmgmt *ptxmgmt; +s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, struct tdls_txmgmt *ptxmgmt); +s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +#endif +s32 _rtw_init_hw_txqueue(struct hw_txqueue* phw_txqueue, u8 ac_tag); +void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); + + +s32 rtw_txframes_pending(_adapter *padapter); +s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib); +void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry); + + +s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter); +void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv); + + +void rtw_alloc_hwxmits(_adapter *padapter); +void rtw_free_hwxmits(_adapter *padapter); + +s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev); + +s32 rtw_xmit(_adapter *padapter, _pkt **pkt); +bool xmitframe_hiq_filter(struct xmit_frame *xmitframe); +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); +void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); +void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta); +#endif + +u8 query_ra_short_GI(struct sta_info *psta); + +u8 qos_acm(u8 acm_mask, u8 priority); + +#ifdef CONFIG_XMIT_THREAD_MODE +void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +void enqueue_pending_xmitbuf_to_head(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +struct xmit_buf* dequeue_pending_xmitbuf(struct xmit_priv *pxmitpriv); +struct xmit_buf* dequeue_pending_xmitbuf_under_survey(struct xmit_priv *pxmitpriv); +sint check_pending_xmitbuf(struct xmit_priv *pxmitpriv); +thread_return rtw_xmit_thread(thread_context context); +#endif + +static void do_queue_select(_adapter * padapter, struct pkt_attrib * pattrib); +u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe); + +#ifdef CONFIG_XMIT_ACK +int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms); +void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status); +#endif //CONFIG_XMIT_ACK + + +//include after declaring struct xmit_buf, in order to avoid warning +#include + +#endif //_RTL871X_XMIT_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_hal.h new file mode 100644 index 00000000..a694cdd4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_hal.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * 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 __SDIO_HAL_H__ +#define __SDIO_HAL_H__ + + +extern u8 sd_hal_bus_init(PADAPTER padapter); +extern u8 sd_hal_bus_deinit(PADAPTER padapter); + +u8 sd_int_isr(PADAPTER padapter); +void sd_int_dpc(PADAPTER padapter); +u8 rtw_set_hal_ops(_adapter *padapter); + +#ifdef CONFIG_RTL8188E +void rtl8188es_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8723B +void rtl8723bs_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8821A +void rtl8821as_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8192E +void rtl8192es_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8703B +void rtl8703bs_set_hal_ops(PADAPTER padapter); +#endif + +#ifdef CONFIG_RTL8188F +void rtl8188fs_set_hal_ops(PADAPTER padapter); +#endif + +#endif //__SDIO_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops.h new file mode 100644 index 00000000..6907814d --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * 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 __SDIO_OPS_H__ +#define __SDIO_OPS_H__ + + +#ifdef PLATFORM_LINUX +#include +#endif + +#ifdef PLATFORM_WINDOWS + +#ifdef PLATFORM_OS_XP +#include +struct async_context +{ + PMDL pmdl; + PSDBUS_REQUEST_PACKET sdrp; + unsigned char* r_buf; + unsigned char* padapter; +}; +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#endif // PLATFORM_WINDOWS + + +extern void sdio_set_intf_ops(_adapter *padapter,struct _io_ops *pops); + +//extern void sdio_func1cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); +//extern void sdio_func1cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); +extern u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr); +extern void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v); +extern s32 _sdio_local_read(PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf); +extern s32 sdio_local_read(PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf); +extern s32 _sdio_local_write(PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf); +extern s32 sdio_local_write(PADAPTER padapter, u32 addr, u32 cnt, u8 *pbuf); + +u32 _sdio_read32(PADAPTER padapter, u32 addr); +s32 _sdio_write32(PADAPTER padapter, u32 addr, u32 val); + +extern void sd_int_hdl(PADAPTER padapter); +extern u8 CheckIPSStatus(PADAPTER padapter); + +#ifdef CONFIG_RTL8188E +extern void InitInterrupt8188ESdio(PADAPTER padapter); +extern void EnableInterrupt8188ESdio(PADAPTER padapter); +extern void DisableInterrupt8188ESdio(PADAPTER padapter); +extern void UpdateInterruptMask8188ESdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR); +extern u8 HalQueryTxBufferStatus8189ESdio(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8189ESdio(PADAPTER padapter); +extern void ClearInterrupt8188ESdio(PADAPTER padapter); +#endif // CONFIG_RTL8188E + +#ifdef CONFIG_RTL8821A +extern void InitInterrupt8821AS(PADAPTER padapter); +extern void EnableInterrupt8821AS(PADAPTER padapter); +extern void DisableInterrupt8821AS(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8821AS(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8821ASdio(PADAPTER padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +void ClearInterrupt8821AS(PADAPTER padapter); +#endif /* defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) */ +#endif /* CONFIG_RTL8821A */ + +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +extern u8 RecvOnePkt(PADAPTER padapter, u32 size); +#endif // CONFIG_WOWLAN +#ifdef CONFIG_RTL8723B +extern void InitInterrupt8723BSdio(PADAPTER padapter); +extern void InitSysInterrupt8723BSdio(PADAPTER padapter); +extern void EnableInterrupt8723BSdio(PADAPTER padapter); +extern void DisableInterrupt8723BSdio(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8723BSdio(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8723BSdio(PADAPTER padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +extern void DisableInterruptButCpwm28723BSdio(PADAPTER padapter); +extern void ClearInterrupt8723BSdio(PADAPTER padapter); +#endif //CONFIG_WOWLAN +#endif + + +#ifdef CONFIG_RTL8192E +extern void InitInterrupt8192ESdio(PADAPTER padapter); +extern void EnableInterrupt8192ESdio(PADAPTER padapter); +extern void DisableInterrupt8192ESdio(PADAPTER padapter); +extern void UpdateInterruptMask8192ESdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR); +extern u8 HalQueryTxBufferStatus8192ESdio(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8192ESdio(PADAPTER padapter); +extern void ClearInterrupt8192ESdio(PADAPTER padapter); +#endif // CONFIG_RTL8192E + +#ifdef CONFIG_RTL8703B +extern void InitInterrupt8703BSdio(PADAPTER padapter); +extern void InitSysInterrupt8703BSdio(PADAPTER padapter); +extern void EnableInterrupt8703BSdio(PADAPTER padapter); +extern void DisableInterrupt8703BSdio(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8703BSdio(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8703BSdio(PADAPTER padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +extern void DisableInterruptButCpwm28703BSdio(PADAPTER padapter); +extern void ClearInterrupt8703BSdio(PADAPTER padapter); +#endif //CONFIG_WOWLAN +#endif + +#ifdef CONFIG_RTL8188F +extern void InitInterrupt8188FSdio(PADAPTER padapter); +extern void InitSysInterrupt8188FSdio(PADAPTER padapter); +extern void EnableInterrupt8188FSdio(PADAPTER padapter); +extern void DisableInterrupt8188FSdio(PADAPTER padapter); +extern u8 HalQueryTxBufferStatus8188FSdio(PADAPTER padapter); +extern u8 HalQueryTxOQTBufferStatus8188FSdio(PADAPTER padapter); +#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) +extern void DisableInterruptButCpwm28188FSdio(PADAPTER padapter); +extern void ClearInterrupt8188FSdio(PADAPTER padapter); +#endif /* defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) */ +#endif + +#endif // !__SDIO_OPS_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_ce.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_ce.h new file mode 100644 index 00000000..d2da2933 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_ce.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * + * 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 _SDIO_OPS_WINCE_H_ +#define _SDIO_OPS_WINCE_H_ + +#include +#include +#include +#include + + +#ifdef PLATFORM_OS_CE + + +extern u8 sdbus_cmd52r_ce(struct intf_priv *pintfpriv, u32 addr); + + +extern void sdbus_cmd52w_ce(struct intf_priv *pintfpriv, u32 addr,u8 val8); + + +uint sdbus_read_blocks_to_membuf_ce(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); + +extern uint sdbus_read_bytes_to_membuf_ce(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); + + +extern uint sdbus_write_blocks_from_membuf_ce(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf,u8 async); + +extern uint sdbus_write_bytes_from_membuf_ce(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); +extern u8 sdbus_func1cmd52r_ce(struct intf_priv *pintfpriv, u32 addr); +extern void sdbus_func1cmd52w_ce(struct intf_priv *pintfpriv, u32 addr, u8 val8); +extern uint sdbus_read_reg(struct intf_priv *pintfpriv, u32 addr, u32 cnt,void *pdata); +extern uint sdbus_write_reg(struct intf_priv *pintfpriv, u32 addr, u32 cnt,void *pdata); +extern void sdio_read_int(_adapter *padapter, u32 addr,u8 sz,void *pdata); + +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_linux.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_linux.h new file mode 100644 index 00000000..38b6a215 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_linux.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * 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 __SDIO_OPS_LINUX_H__ +#define __SDIO_OPS_LINUX_H__ + +#define SDIO_ERR_VAL8 0xEA +#define SDIO_ERR_VAL16 0xEAEA +#define SDIO_ERR_VAL32 0xEAEAEAEA + +u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +void sd_f0_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err); + +s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata); +s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata); +s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata); +s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata); + +u8 _sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +u16 sd_read16(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +u32 _sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err); +s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata); +s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata); +void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err); +void sd_write16(struct intf_hdl *pintfhdl, u32 addr, u16 v, s32 *err); +void _sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err); +void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err); +s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata); +s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata); + + +void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, _thread_hdl_ thd_hdl); +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_xp.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_xp.h new file mode 100644 index 00000000..757b35d4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_ops_xp.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * + * 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 _SDIO_OPS_XP_H_ +#define _SDIO_OPS_XP_H_ + +#include +#include +#include +#include + + +#ifdef PLATFORM_OS_XP + + +extern u8 sdbus_cmd52r_xp(struct intf_priv *pintfpriv, u32 addr); + + +extern void sdbus_cmd52w_xp(struct intf_priv *pintfpriv, u32 addr,u8 val8); + + +uint sdbus_read_blocks_to_membuf_xp(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); + +extern uint sdbus_read_bytes_to_membuf_xp(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); + + +extern uint sdbus_write_blocks_from_membuf_xp(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf,u8 async); + +extern uint sdbus_write_bytes_from_membuf_xp(struct intf_priv *pintfpriv, u32 addr, u32 cnt, u8 *pbuf); +extern u8 sdbus_func1cmd52r_xp(struct intf_priv *pintfpriv, u32 addr); +extern void sdbus_func1cmd52w_xp(struct intf_priv *pintfpriv, u32 addr, u8 val8); +extern uint sdbus_read_reg(struct intf_priv *pintfpriv, u32 addr, u32 cnt,void *pdata); +extern uint sdbus_write_reg(struct intf_priv *pintfpriv, u32 addr, u32 cnt,void *pdata); +extern void sdio_read_int(_adapter *padapter, u32 addr,u8 sz,void *pdata); + +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_osintf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_osintf.h new file mode 100644 index 00000000..1a81d2eb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sdio_osintf.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * 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 __SDIO_OSINTF_H__ +#define __SDIO_OSINTF_H__ + + + +u8 sd_hal_bus_init(PADAPTER padapter); +u8 sd_hal_bus_deinit(PADAPTER padapter); +void sd_c2h_hdl(PADAPTER padapter); + +#ifdef PLATFORM_OS_CE +extern NDIS_STATUS ce_sd_get_dev_hdl(PADAPTER padapter); +SD_API_STATUS ce_sd_int_callback(SD_DEVICE_HANDLE hDevice, PADAPTER padapter); +extern void sd_setup_irs(PADAPTER padapter); +#endif + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/sta_info.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sta_info.h new file mode 100644 index 00000000..bfb63df1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/sta_info.h @@ -0,0 +1,591 @@ +/****************************************************************************** + * + * 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 __STA_INFO_H_ +#define __STA_INFO_H_ + + +#define IBSS_START_MAC_ID 2 +#define NUM_STA MACID_NUM_SW_LIMIT +#define NUM_ACL 16 + +#ifdef CONFIG_TDLS +#define MAX_ALLOWED_TDLS_STA_NUM 4 +#endif + +enum sta_info_update_type { + STA_INFO_UPDATE_NONE = 0, + STA_INFO_UPDATE_BW = BIT(0), + STA_INFO_UPDATE_RATE = BIT(1), + STA_INFO_UPDATE_PROTECTION_MODE = BIT(2), + STA_INFO_UPDATE_CAP = BIT(3), + STA_INFO_UPDATE_HT_CAP = BIT(4), + STA_INFO_UPDATE_VHT_CAP = BIT(5), + STA_INFO_UPDATE_ALL = STA_INFO_UPDATE_BW + |STA_INFO_UPDATE_RATE + |STA_INFO_UPDATE_PROTECTION_MODE + |STA_INFO_UPDATE_CAP + |STA_INFO_UPDATE_HT_CAP + |STA_INFO_UPDATE_VHT_CAP, + STA_INFO_UPDATE_MAX +}; + +//if mode ==0, then the sta is allowed once the addr is hit. +//if mode ==1, then the sta is rejected once the addr is non-hit. +struct rtw_wlan_acl_node { + _list list; + u8 addr[ETH_ALEN]; + u8 valid; +}; + +//mode=0, disable +//mode=1, accept unless in deny list +//mode=2, deny unless in accept list +struct wlan_acl_pool { + int mode; + int num; + struct rtw_wlan_acl_node aclnode[NUM_ACL]; + _queue acl_node_q; +}; + +typedef struct _RSSI_STA{ + s32 UndecoratedSmoothedPWDB; + s32 UndecoratedSmoothedCCK; + s32 UndecoratedSmoothedOFDM; + u32 OFDM_pkt; + u64 PacketMap; + u8 ValidBit; +}RSSI_STA, *PRSSI_STA; + +struct stainfo_stats { + + u64 rx_mgnt_pkts; + u64 rx_beacon_pkts; + u64 rx_probereq_pkts; + u64 rx_probersp_pkts; + u64 rx_probersp_bm_pkts; + u64 rx_probersp_uo_pkts; + u64 rx_ctrl_pkts; + u64 rx_data_pkts; + u64 rx_data_qos_pkts[TID_NUM]; + u64 last_rx_mgnt_pkts; + u64 last_rx_beacon_pkts; + u64 last_rx_probereq_pkts; + u64 last_rx_probersp_pkts; + u64 last_rx_probersp_bm_pkts; + u64 last_rx_probersp_uo_pkts; + u64 last_rx_ctrl_pkts; + u64 last_rx_data_pkts; + u64 last_rx_data_qos_pkts[TID_NUM]; +#ifdef CONFIG_TDLS + u64 rx_tdls_disc_rsp_pkts; + u64 last_rx_tdls_disc_rsp_pkts; +#endif + u64 rx_bytes; + u64 rx_drops; + + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; +}; + +#ifndef DBG_SESSION_TRACKER +#define DBG_SESSION_TRACKER 0 +#endif + +/* session tracker status */ +#define ST_STATUS_NONE 0 +#define ST_STATUS_CHECK BIT0 +#define ST_STATUS_ESTABLISH BIT1 +#define ST_STATUS_EXPIRE BIT2 + +#define ST_EXPIRE_MS (10 * 1000) + +struct session_tracker { + _list list; /* session_tracker_queue */ + u32 local_naddr; + u16 local_port; + u32 remote_naddr; + u16 remote_port; + u32 set_time; + u8 status; +}; + +/* session tracker cmd */ +#define ST_CMD_ADD 0 +#define ST_CMD_DEL 1 +#define ST_CMD_CHK 2 + +struct st_cmd_parm { + u8 cmd; + struct sta_info *sta; + u32 local_naddr; /* TODO: IPV6 */ + u16 local_port; + u32 remote_naddr; /* TODO: IPV6 */ + u16 remote_port; +}; + +typedef bool (*st_match_rule)(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); + +struct st_register { + u8 s_proto; + st_match_rule rule; +}; + +#define SESSION_TRACKER_REG_ID_WFD 0 +#define SESSION_TRACKER_REG_ID_NUM 1 + +struct st_ctl_t { + struct st_register reg[SESSION_TRACKER_REG_ID_NUM]; + _queue tracker_q; +}; + +void rtw_st_ctl_init(struct st_ctl_t *st_ctl); +void rtw_st_ctl_deinit(struct st_ctl_t *st_ctl); +void rtw_st_ctl_register(struct st_ctl_t *st_ctl, u8 st_reg_id, struct st_register *reg); +void rtw_st_ctl_unregister(struct st_ctl_t *st_ctl, u8 st_reg_id); +bool rtw_st_ctl_chk_reg_s_proto(struct st_ctl_t *st_ctl, u8 s_proto); +bool rtw_st_ctl_chk_reg_rule(struct st_ctl_t *st_ctl, _adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port); +void dump_st_ctl(void *sel, struct st_ctl_t *st_ctl); + +#ifdef CONFIG_TDLS +struct TDLS_PeerKey { + u8 kck[16]; /* TPK-KCK */ + u8 tk[16]; /* TPK-TK; only CCMP will be used */ +} ; +#endif //CONFIG_TDLS + +struct sta_info { + + _lock lock; + _list list; //free_sta_queue + _list hash_list; //sta_hash + //_list asoc_list; //20061114 + //_list sleep_list;//sleep_q + //_list wakeup_list;//wakeup_q + _adapter *padapter; + + struct sta_xmit_priv sta_xmitpriv; + struct sta_recv_priv sta_recvpriv; + + _queue sleep_q; + unsigned int sleepq_len; + + uint state; + uint aid; + uint mac_id; + uint qos_option; + u8 hwaddr[ETH_ALEN]; + u16 hwseq; + u8 ra_rpt_linked; + + uint ieee8021x_blocked; //0: allowed, 1:blocked + uint dot118021XPrivacy; //aes, tkip... + union Keytype dot11tkiptxmickey; + union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; + union pn48 dot11txpn; // PN48 used for Unicast xmit +#ifdef CONFIG_GTK_OL + u8 kek[RTW_KEK_LEN]; + u8 kck[RTW_KCK_LEN]; + u8 replay_ctr[RTW_REPLAY_CTR_LEN]; +#endif //CONFIG_GTK_OL +#ifdef CONFIG_IEEE80211W + union pn48 dot11wtxpn; // PN48 used for Unicast mgmt xmit. + _timer dot11w_expire_timer; +#endif //CONFIG_IEEE80211W + union pn48 dot11rxpn; // PN48 used for Unicast recv. + + + u8 bssrateset[16]; + u32 bssratelen; + s32 rssi; + s32 signal_quality; + + u8 cts2self; + u8 rtsen; + + u8 raid; + u8 init_rate; + u64 ra_mask; + u8 wireless_mode; // NETWORK_TYPE + u8 bw_mode; + + u8 ldpc; + u8 stbc; + +#ifdef CONFIG_BEAMFORMING + u16 txbf_paid; + u16 txbf_gid; +#endif + + struct stainfo_stats sta_stats; + +#ifdef CONFIG_TDLS + u32 tdls_sta_state; + u8 SNonce[32]; + u8 ANonce[32]; + u32 TDLS_PeerKey_Lifetime; + u16 TPK_count; + _timer TPK_timer; + struct TDLS_PeerKey tpk; +#ifdef CONFIG_TDLS_CH_SW + u16 ch_switch_time; + u16 ch_switch_timeout; + //u8 option; + _timer ch_sw_timer; + _timer delay_timer; +#endif + _timer handshake_timer; + u8 alive_count; + _timer pti_timer; + u8 TDLS_RSNIE[20]; /* Save peer's RSNIE, used for sending TDLS_SETUP_RSP */ +#endif /* CONFIG_TDLS */ + + //for A-MPDU TX, ADDBA timeout check + _timer addba_retry_timer; + + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl recvreorder_ctrl[TID_NUM]; + ATOMIC_T continual_no_rx_packet[TID_NUM]; + //for A-MPDU Tx + //unsigned char ampdu_txen_bitmap; + u16 BA_starting_seqctrl[16]; + + +#ifdef CONFIG_80211N_HT + struct ht_priv htpriv; +#endif + +#ifdef CONFIG_80211AC_VHT + struct vht_priv vhtpriv; +#endif + + //Notes: + //STA_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) + sta_info: (STA & AP) CAP/INFO + //scan_q: AP CAP/INFO + + //AP_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO + //sta_info: (AP & STA) CAP/INFO + + unsigned int expire_to; + +#ifdef CONFIG_AP_MODE + + _list asoc_list; + _list auth_list; + + unsigned int auth_seq; + unsigned int authalg; + unsigned char chg_txt[128]; + + u16 capability; + int flags; + + int dot8021xalg;//0:disable, 1:psk, 2:802.1x + int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + int wpa_group_cipher; + int wpa2_group_cipher; + int wpa_pairwise_cipher; + int wpa2_pairwise_cipher; + + u8 bpairwise_key_installed; + +#ifdef CONFIG_NATIVEAP_MLME + u8 wpa_ie[32]; + + u8 nonerp_set; + u8 no_short_slot_time_set; + u8 no_short_preamble_set; + u8 no_ht_gf_set; + u8 no_ht_set; + u8 ht_20mhz_set; + u8 ht_40mhz_intolerant; +#endif // CONFIG_NATIVEAP_MLME + +#ifdef CONFIG_ATMEL_RC_PATCH + u8 flag_atmel_rc; +#endif + + u8 qos_info; + + u8 max_sp_len; + u8 uapsd_bk;//BIT(0): Delivery enabled, BIT(1): Trigger enabled + u8 uapsd_be; + u8 uapsd_vi; + u8 uapsd_vo; + + u8 has_legacy_ac; + unsigned int sleepq_ac_len; + +#ifdef CONFIG_P2P + //p2p priv data + u8 is_p2p_device; + u8 p2p_status_code; + + //p2p client info + u8 dev_addr[ETH_ALEN]; + //u8 iface_addr[ETH_ALEN];//= hwaddr[ETH_ALEN] + u8 dev_cap; + u16 config_methods; + u8 primary_dev_type[8]; + u8 num_of_secdev_type; + u8 secdev_types_list[32];// 32/8 == 4; + u16 dev_name_len; + u8 dev_name[32]; +#endif //CONFIG_P2P + +#ifdef CONFIG_WFD + u8 op_wfd_mode; +#endif + +#ifdef CONFIG_TX_MCAST2UNI + u8 under_exist_checking; +#endif // CONFIG_TX_MCAST2UNI + + u8 keep_alive_trycnt; + +#ifdef CONFIG_AUTO_AP_MODE + u8 isrc; //this device is rc + u16 pid; // pairing id +#endif + +#endif // CONFIG_AP_MODE + +#ifdef CONFIG_IOCTL_CFG80211 + u8 *passoc_req; + u32 assoc_req_len; +#endif + + //for DM + RSSI_STA rssi_stat; + + //ODM_STA_INFO_T + // ================ODM Relative Info======================= + // Please be care, dont declare too much structure here. It will cost memory * STA support num. + // + // + // 2011/10/20 MH Add for ODM STA info. + // + // Driver Write + u8 bValid; // record the sta status link or not? + //u8 WirelessMode; // + u8 IOTPeer; // Enum value. HT_IOT_PEER_E + // ODM Write + //1 PHY_STATUS_INFO + u8 RSSI_Path[4]; // + u8 RSSI_Ave; + u8 RXEVM[4]; + u8 RXSNR[4]; + + u8 rssi_level; //for Refresh RA mask + // ODM Write + //1 TX_INFO (may changed by IC) + //TX_INFO_T pTxInfo; // Define in IC folder. Move lower layer. + // + // ================ODM Relative Info======================= + // + + /* To store the sequence number of received management frame */ + u16 RxMgmtFrameSeqNum; + + struct st_ctl_t st_ctl; +}; + +#define sta_rx_pkts(sta) \ + (sta->sta_stats.rx_mgnt_pkts \ + + sta->sta_stats.rx_ctrl_pkts \ + + sta->sta_stats.rx_data_pkts) + +#define sta_last_rx_pkts(sta) \ + (sta->sta_stats.last_rx_mgnt_pkts \ + + sta->sta_stats.last_rx_ctrl_pkts \ + + sta->sta_stats.last_rx_data_pkts) + +#define sta_rx_data_pkts(sta) \ + (sta->sta_stats.rx_data_pkts) + +#define sta_rx_data_qos_pkts(sta, i) \ + (sta->sta_stats.rx_data_qos_pkts[i]) + +#define sta_last_rx_data_pkts(sta) \ + (sta->sta_stats.last_rx_data_pkts) + +#define sta_last_rx_data_qos_pkts(sta, i) \ + (sta->sta_stats.last_rx_data_qos_pkts[i]) + +#define sta_rx_mgnt_pkts(sta) \ + (sta->sta_stats.rx_mgnt_pkts) + +#define sta_last_rx_mgnt_pkts(sta) \ + (sta->sta_stats.last_rx_mgnt_pkts) + +#define sta_rx_beacon_pkts(sta) \ + (sta->sta_stats.rx_beacon_pkts) + +#define sta_last_rx_beacon_pkts(sta) \ + (sta->sta_stats.last_rx_beacon_pkts) + +#define sta_rx_probereq_pkts(sta) \ + (sta->sta_stats.rx_probereq_pkts) + +#define sta_last_rx_probereq_pkts(sta) \ + (sta->sta_stats.last_rx_probereq_pkts) + +#define sta_rx_probersp_pkts(sta) \ + (sta->sta_stats.rx_probersp_pkts) + +#define sta_last_rx_probersp_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_pkts) + +#define sta_rx_probersp_bm_pkts(sta) \ + (sta->sta_stats.rx_probersp_bm_pkts) + +#define sta_last_rx_probersp_bm_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_bm_pkts) + +#define sta_rx_probersp_uo_pkts(sta) \ + (sta->sta_stats.rx_probersp_uo_pkts) + +#define sta_last_rx_probersp_uo_pkts(sta) \ + (sta->sta_stats.last_rx_probersp_uo_pkts) + +#define sta_update_last_rx_pkts(sta) \ + do { \ + sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \ + sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \ + sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \ + sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \ + sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \ + sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \ + sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \ + sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \ + } while(0) + +#define STA_RX_PKTS_ARG(sta) \ + sta->sta_stats.rx_mgnt_pkts \ + , sta->sta_stats.rx_ctrl_pkts \ + , sta->sta_stats.rx_data_pkts + +#define STA_LAST_RX_PKTS_ARG(sta) \ + sta->sta_stats.last_rx_mgnt_pkts \ + , sta->sta_stats.last_rx_ctrl_pkts \ + , sta->sta_stats.last_rx_data_pkts + +#define STA_RX_PKTS_DIFF_ARG(sta) \ + sta->sta_stats.rx_mgnt_pkts - sta->sta_stats.last_rx_mgnt_pkts \ + , sta->sta_stats.rx_ctrl_pkts - sta->sta_stats.last_rx_ctrl_pkts \ + , sta->sta_stats.rx_data_pkts -sta->sta_stats.last_rx_data_pkts + +#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)" + +#ifdef CONFIG_WFD +#define STA_OP_WFD_MODE(sta) (sta)->op_wfd_mode +#define STA_SET_OP_WFD_MODE(sta, mode) (sta)->op_wfd_mode = (mode) +#else +#define STA_OP_WFD_MODE(sta) 0 +#define STA_SET_OP_WFD_MODE(sta, mode) do {} while (0) +#endif + +struct sta_priv { + + u8 *pallocated_stainfo_buf; + u8 *pstainfo_buf; + _queue free_sta_queue; + + _lock sta_hash_lock; + _list sta_hash[NUM_STA]; + int asoc_sta_count; + _queue sleep_q; + _queue wakeup_q; + + _adapter *padapter; + + u32 adhoc_expire_to; + +#ifdef CONFIG_AP_MODE + _list asoc_list; + _list auth_list; + _lock asoc_list_lock; + _lock auth_list_lock; + u8 asoc_list_cnt; + u8 auth_list_cnt; + + unsigned int auth_to; //sec, time to expire in authenticating. + unsigned int assoc_to; //sec, time to expire before associating. + unsigned int expire_to; //sec , time to expire after associated. + + /* pointers to STA info; based on allocated AID or NULL if AID free + * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 + * and so on + */ + struct sta_info *sta_aid[NUM_STA]; + + u16 sta_dz_bitmap;//only support 15 stations, staion aid bitmap for sleeping sta. + u16 tim_bitmap;//only support 15 stations, aid=0~15 mapping bit0~bit15 + + u16 max_num_sta; + + struct wlan_acl_pool acl_list; +#endif + +#ifdef CONFIG_ATMEL_RC_PATCH + u8 atmel_rc_pattern [6]; +#endif + +}; + + +__inline static u32 wifi_mac_hash(u8 *mac) +{ + u32 x; + + x = mac[0]; + x = (x << 2) ^ mac[1]; + x = (x << 2) ^ mac[2]; + x = (x << 2) ^ mac[3]; + x = (x << 2) ^ mac[4]; + x = (x << 2) ^ mac[5]; + + x ^= x >> 8; + x = x & (NUM_STA - 1); + + return x; +} + + +extern u32 _rtw_init_sta_priv(struct sta_priv *pstapriv); +extern u32 _rtw_free_sta_priv(struct sta_priv *pstapriv); + +#define stainfo_offset_valid(offset) (offset < NUM_STA && offset >= 0) +int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta); +struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset); + +extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta); +extern void rtw_free_all_stainfo(_adapter *padapter); +extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_init_bcmc_stainfo(_adapter* padapter); +extern struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter); +extern u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr); + +#endif //_STA_INFO_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_hal.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_hal.h new file mode 100644 index 00000000..8d500eb5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_hal.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 __USB_HAL_H__ +#define __USB_HAL_H__ + +int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz); +void usb_free_recv_priv (_adapter *padapter, u16 ini_in_buf_sz); + +u8 rtw_set_hal_ops(_adapter *padapter); + +#ifdef CONFIG_RTL8188E +void rtl8188eu_set_hal_ops(_adapter * padapter); +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +void rtl8812au_set_hal_ops(_adapter * padapter); +#endif + +#ifdef CONFIG_RTL8192E +void rtl8192eu_set_hal_ops(_adapter * padapter); +#endif + + +#ifdef CONFIG_RTL8723B +void rtl8723bu_set_hal_ops(_adapter * padapter); +#endif + +#ifdef CONFIG_RTL8814A +void rtl8814au_set_hal_ops(_adapter * padapter); +#endif /* CONFIG_RTL8814A */ + +#ifdef CONFIG_RTL8188F +void rtl8188fu_set_hal_ops(_adapter *padapter); +#endif + +#ifdef CONFIG_RTL8703B +void rtl8703bu_set_hal_ops(_adapter *padapter); +#endif + +#ifdef CONFIG_INTEL_PROXIM +extern _adapter *rtw_usb_get_sw_pointer(void); +#endif //CONFIG_INTEL_PROXIM +#endif //__USB_HAL_H__ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops.h new file mode 100644 index 00000000..ee23314a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops.h @@ -0,0 +1,148 @@ +/****************************************************************************** + * + * 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 __USB_OPS_H_ +#define __USB_OPS_H_ + + +#define REALTEK_USB_VENQT_READ 0xC0 +#define REALTEK_USB_VENQT_WRITE 0x40 +#define REALTEK_USB_VENQT_CMD_REQ 0x05 +#define REALTEK_USB_VENQT_CMD_IDX 0x00 +#define REALTEK_USB_IN_INT_EP_IDX 1 + +enum{ + VENDOR_WRITE = 0x00, + VENDOR_READ = 0x01, +}; +#define ALIGNMENT_UNIT 16 +#define MAX_VENDOR_REQ_CMD_SIZE 254 //8188cu SIE Support +#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE +ALIGNMENT_UNIT) + +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) +#define rtw_usb_control_msg(dev, pipe, request, requesttype, value, index, data, size, timeout_ms) \ + usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), (data), (size), (timeout_ms)) +#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout_ms) \ + usb_bulk_msg((usb_dev), (pipe), (data), (len), (actual_length), (timeout_ms)) +#else +#define rtw_usb_control_msg(dev, pipe, request, requesttype, value, index, data, size,timeout_ms) \ + usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), (data), (size), \ + ((timeout_ms) == 0) ||((timeout_ms)*HZ/1000>0)?((timeout_ms)*HZ/1000):1) +#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout_ms) \ + usb_bulk_msg((usb_dev), (pipe), (data), (len), (actual_length), \ + ((timeout_ms) == 0) ||((timeout_ms)*HZ/1000>0)?((timeout_ms)*HZ/1000):1) +#endif +#include +#endif //PLATFORM_LINUX + +#ifdef CONFIG_RTL8188E +void rtl8188eu_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8188eu_set_intf_ops(struct _io_ops *pops); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8188eu(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif +#endif + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) +void rtl8812au_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8812au_set_intf_ops(struct _io_ops *pops); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8812au(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif +#endif + +#ifdef CONFIG_RTL8814A +void rtl8814au_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8814au_set_intf_ops(struct _io_ops *pops); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8814au(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif +#endif /* CONFIG_RTL8814 */ + +#ifdef CONFIG_RTL8192E +void rtl8192eu_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8192eu_set_intf_ops(struct _io_ops *pops); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8192eu(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif + +#endif + +#ifdef CONFIG_RTL8188F +void rtl8188fu_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8188fu_set_intf_ops(struct _io_ops *pops); +void rtl8188fu_recv_tasklet(void *priv); +void rtl8188fu_xmit_tasklet(void *priv); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8188fu(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif +#endif + +#ifdef CONFIG_RTL8723B +void rtl8723bu_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8723bu_set_intf_ops(struct _io_ops *pops); +void rtl8723bu_recv_tasklet(void *priv); +void rtl8723bu_xmit_tasklet(void *priv); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8723bu(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif +#endif + +#ifdef CONFIG_RTL8703B +void rtl8703bu_set_hw_type(struct dvobj_priv *pdvobj); +void rtl8703bu_set_intf_ops(struct _io_ops *pops); +void rtl8703bu_recv_tasklet(void *priv); +void rtl8703bu_xmit_tasklet(void *priv); +#ifdef CONFIG_SUPPORT_USB_INT +void interrupt_handler_8703bu(_adapter *padapter, u16 pkt_len, u8 *pbuf); +#endif /* CONFIG_SUPPORT_USB_INT */ +#endif /* CONFIG_RTL8703B */ + +enum RTW_USB_SPEED { + RTW_USB_SPEED_UNKNOWN = 0, + RTW_USB_SPEED_1_1 = 1, + RTW_USB_SPEED_2 = 2, + RTW_USB_SPEED_3 = 3, +}; + +#define IS_FULL_SPEED_USB(Adapter) (adapter_to_dvobj(Adapter)->usb_speed == RTW_USB_SPEED_1_1) +#define IS_HIGH_SPEED_USB(Adapter) (adapter_to_dvobj(Adapter)->usb_speed == RTW_USB_SPEED_2) +#define IS_SUPER_SPEED_USB(Adapter) (adapter_to_dvobj(Adapter)->usb_speed == RTW_USB_SPEED_3) + +#define USB_SUPER_SPEED_BULK_SIZE 1024 // usb 3.0 +#define USB_HIGH_SPEED_BULK_SIZE 512 // usb 2.0 +#define USB_FULL_SPEED_BULK_SIZE 64 // usb 1.1 + +static inline u8 rtw_usb_bulk_size_boundary(_adapter * padapter,int buf_len) +{ + u8 rst = _TRUE; + + if (IS_SUPER_SPEED_USB(padapter)) + rst = (0 == (buf_len) % USB_SUPER_SPEED_BULK_SIZE)?_TRUE:_FALSE; + if (IS_HIGH_SPEED_USB(padapter)) + rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE)?_TRUE:_FALSE; + else + rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE)?_TRUE:_FALSE; + return rst; +} + + +#endif //__USB_OPS_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops_linux.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops_linux.h new file mode 100644 index 00000000..b0d0f43e --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_ops_linux.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 __USB_OPS_LINUX_H__ +#define __USB_OPS_LINUX_H__ + +#define VENDOR_CMD_MAX_DATA_LEN 254 +#define FW_START_ADDRESS 0x1000 + +#define RTW_USB_CONTROL_MSG_TIMEOUT_TEST 10//ms +#define RTW_USB_CONTROL_MSG_TIMEOUT 500//ms + +#define RECV_BULK_IN_ADDR 0x80//assign by drv,not real address +#define RECV_INT_IN_ADDR 0x81//assign by drv,not real address + +#define INTERRUPT_MSG_FORMAT_LEN 60 + +#if defined(CONFIG_VENDOR_REQ_RETRY) && defined(CONFIG_USB_VENDOR_REQ_MUTEX) +/* vendor req retry should be in the situation when each vendor req is atomically submitted from others */ +#define MAX_USBCTRL_VENDORREQ_TIMES 10 +#else +#define MAX_USBCTRL_VENDORREQ_TIMES 1 +#endif + +#define RTW_USB_BULKOUT_TIMEOUT 5000//ms + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) +#define _usbctrl_vendorreq_async_callback(urb, regs) _usbctrl_vendorreq_async_callback(urb) +#define usb_bulkout_zero_complete(purb, regs) usb_bulkout_zero_complete(purb) +#define usb_write_mem_complete(purb, regs) usb_write_mem_complete(purb) +#define usb_write_port_complete(purb, regs) usb_write_port_complete(purb) +#define usb_read_port_complete(purb, regs) usb_read_port_complete(purb) +#define usb_read_interrupt_complete(purb, regs) usb_read_interrupt_complete(purb) +#endif + +#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ +int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val); +int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val); +int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val); +#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */ + +unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr); + +void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem); +void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem); + +void usb_read_port_cancel(struct intf_hdl *pintfhdl); + +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); + +#ifdef CONFIG_USB_INTERRUPT_IN_PIPE +void usb_read_interrupt_complete(struct urb *purb, struct pt_regs *regs); +u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr); +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_osintf.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_osintf.h new file mode 100644 index 00000000..62dc44aa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_osintf.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * 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 __USB_OSINTF_H +#define __USB_OSINTF_H + +#include + +#define USBD_HALTED(Status) ((ULONG)(Status) >> 30 == 3) + + +u8 usbvendorrequest(struct dvobj_priv *pdvobjpriv, RT_USB_BREQUEST brequest, RT_USB_WVALUE wvalue, u8 windex, void* data, u8 datalen, u8 isdirectionin); + + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_vendor_req.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_vendor_req.h new file mode 100644 index 00000000..b60eefac --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/usb_vendor_req.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * 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 _USB_VENDOR_REQUEST_H_ +#define _USB_VENDOR_REQUEST_H_ + +//4 Set/Get Register related wIndex/Data +#define RT_USB_RESET_MASK_OFF 0 +#define RT_USB_RESET_MASK_ON 1 +#define RT_USB_SLEEP_MASK_OFF 0 +#define RT_USB_SLEEP_MASK_ON 1 +#define RT_USB_LDO_ON 1 +#define RT_USB_LDO_OFF 0 + +//4 Set/Get SYSCLK related wValue or Data +#define RT_USB_SYSCLK_32KHZ 0 +#define RT_USB_SYSCLK_40MHZ 1 +#define RT_USB_SYSCLK_60MHZ 2 + + +typedef enum _RT_USB_BREQUEST { + RT_USB_SET_REGISTER = 1, + RT_USB_SET_SYSCLK = 2, + RT_USB_GET_SYSCLK = 3, + RT_USB_GET_REGISTER = 4 +} RT_USB_BREQUEST; + + +typedef enum _RT_USB_WVALUE { + RT_USB_RESET_MASK = 1, + RT_USB_SLEEP_MASK = 2, + RT_USB_USB_HRCPWM = 3, + RT_USB_LDO = 4, + RT_USB_BOOT_TYPE = 5 +} RT_USB_WVALUE; + + +//BOOLEAN usbvendorrequest(PCE_USB_DEVICE CEdevice, RT_USB_BREQUEST bRequest, RT_USB_WVALUE wValue, UCHAR wIndex, PVOID Data, UCHAR DataLength, BOOLEAN isDirectionIn); +//BOOLEAN CEusbGetStatusRequest(PCE_USB_DEVICE CEdevice, IN USHORT Op, IN USHORT Index, PVOID Data); +//BOOLEAN CEusbFeatureRequest(PCE_USB_DEVICE CEdevice, IN USHORT Op, IN USHORT FeatureSelector, IN USHORT Index); +//BOOLEAN CEusbGetDescriptorRequest(PCE_USB_DEVICE CEdevice, IN short urbLength, IN UCHAR DescriptorType, IN UCHAR Index, IN USHORT LanguageId, IN PVOID TransferBuffer, IN ULONG TransferBufferLength); + +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/wifi.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/wifi.h new file mode 100644 index 00000000..9d21a5af --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/wifi.h @@ -0,0 +1,1397 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 _WIFI_H_ +#define _WIFI_H_ + + +#ifdef BIT +//#error "BIT define occurred earlier elsewhere!\n" +#undef BIT +#endif +#define BIT(x) (1 << (x)) + + +#define WLAN_ETHHDR_LEN 14 +#define WLAN_ETHADDR_LEN 6 +#define WLAN_IEEE_OUI_LEN 3 +#define WLAN_ADDR_LEN 6 +#define WLAN_CRC_LEN 4 +#define WLAN_BSSID_LEN 6 +#define WLAN_BSS_TS_LEN 8 +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +#define WLAN_HDR_A3_QOS_LEN 26 +#define WLAN_HDR_A4_QOS_LEN 32 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_DATA_MAXLEN 2312 + +#define WLAN_A3_PN_OFFSET 24 +#define WLAN_A4_PN_OFFSET 30 + +#define WLAN_MIN_ETHFRM_LEN 60 +#define WLAN_MAX_ETHFRM_LEN 1514 +#define WLAN_ETHHDR_LEN 14 +#define WLAN_WMM_LEN 24 + +#define P80211CAPTURE_VERSION 0x80211001 + +// This value is tested by WiFi 11n Test Plan 5.2.3. +// This test verifies the WLAN NIC can update the NAV through sending the CTS with large duration. +#define WiFiNavUpperUs 30000 // 30 ms + +#ifdef GREEN_HILL +#pragma pack(1) +#endif + +enum WIFI_FRAME_TYPE { + WIFI_MGT_TYPE = (0), + WIFI_CTRL_TYPE = (BIT(2)), + WIFI_DATA_TYPE = (BIT(3)), + WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), //!< QoS Data +}; + +enum WIFI_FRAME_SUBTYPE { + + // below is for mgt frame + WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), + WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE), + WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE), + WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), + WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE), + WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE), + WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE), + WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE), + WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE), + WIFI_ACTION_NOACK = (BIT(7) | BIT(6) | BIT(5) | WIFI_MGT_TYPE), + + // below is for control frame + WIFI_NDPA = (BIT(6) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE), + WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + + // below is for data frame + WIFI_DATA = (0 | WIFI_DATA_TYPE), + WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE), + WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE), + WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE), + WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE), + WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), +}; + +enum WIFI_REASON_CODE { + _RSON_RESERVED_ = 0, + _RSON_UNSPECIFIED_ = 1, + _RSON_AUTH_NO_LONGER_VALID_ = 2, + _RSON_DEAUTH_STA_LEAVING_ = 3, + _RSON_INACTIVITY_ = 4, + _RSON_UNABLE_HANDLE_ = 5, + _RSON_CLS2_ = 6, + _RSON_CLS3_ = 7, + _RSON_DISAOC_STA_LEAVING_ = 8, + _RSON_ASOC_NOT_AUTH_ = 9, + + // WPA reason + _RSON_INVALID_IE_ = 13, + _RSON_MIC_FAILURE_ = 14, + _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, + _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, + _RSON_DIFF_IE_ = 17, + _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, + _RSON_UNICST_CIPHER_NOT_VALID_ = 19, + _RSON_AKMP_NOT_VALID_ = 20, + _RSON_UNSUPPORT_RSNE_VER_ = 21, + _RSON_INVALID_RSNE_CAP_ = 22, + _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, + + //belowing are Realtek definition + _RSON_PMK_NOT_AVAILABLE_ = 24, + _RSON_TDLS_TEAR_TOOFAR_ = 25, + _RSON_TDLS_TEAR_UN_RSN_ = 26, +}; + +/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */ +#if 0 +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#endif +/* IEEE 802.11h */ +#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 +#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 +#if 0 +/* IEEE 802.11i */ +#define WLAN_REASON_INVALID_IE 13 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 +#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 +#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 +#define WLAN_REASON_AKMP_NOT_VALID 20 +#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 +#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 +#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#endif + +enum WIFI_STATUS_CODE { + _STATS_SUCCESSFUL_ = 0, + _STATS_FAILURE_ = 1, + _STATS_SEC_DISABLED_ = 5, + _STATS_NOT_IN_SAME_BSS_ = 7, + _STATS_CAP_FAIL_ = 10, + _STATS_NO_ASOC_ = 11, + _STATS_OTHER_ = 12, + _STATS_NO_SUPP_ALG_ = 13, + _STATS_OUT_OF_AUTH_SEQ_ = 14, + _STATS_CHALLENGE_FAIL_ = 15, + _STATS_AUTH_TIMEOUT_ = 16, + _STATS_UNABLE_HANDLE_STA_ = 17, + _STATS_RATE_FAIL_ = 18, + _STATS_REFUSED_TEMPORARILY_ = 30, + _STATS_DECLINE_REQ_ = 37, + _STATS_INVALID_PARAMETERS_ = 38, + _STATS_INVALID_RSNIE_ = 72, +}; + +/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) */ +#if 0 +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +#endif +//entended +/* IEEE 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 +/* IEEE 802.11h */ +#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 +#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 +#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 +/* IEEE 802.11g */ +#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 +#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 +/* IEEE 802.11w */ +#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 +#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +/* IEEE 802.11i */ +#define WLAN_STATUS_INVALID_IE 40 +#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 +#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 +#define WLAN_STATUS_AKMP_NOT_VALID 43 +#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 +#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 +#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 +/* IEEE 802.11r */ +#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 +#define WLAN_STATUS_INVALID_PMKID 53 +#define WLAN_STATUS_INVALID_MDIE 54 +#define WLAN_STATUS_INVALID_FTIE 55 + + +enum WIFI_REG_DOMAIN { + DOMAIN_FCC = 1, + DOMAIN_IC = 2, + DOMAIN_ETSI = 3, + DOMAIN_SPAIN = 4, + DOMAIN_FRANCE = 5, + DOMAIN_MKK = 6, + DOMAIN_ISRAEL = 7, + DOMAIN_MKK1 = 8, + DOMAIN_MKK2 = 9, + DOMAIN_MKK3 = 10, + DOMAIN_MAX +}; + +#define _TO_DS_ BIT(8) +#define _FROM_DS_ BIT(9) +#define _MORE_FRAG_ BIT(10) +#define _RETRY_ BIT(11) +#define _PWRMGT_ BIT(12) +#define _MORE_DATA_ BIT(13) +#define _PRIVACY_ BIT(14) +#define _ORDER_ BIT(15) + +#define SetToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_TO_DS_); \ + } while(0) + +#define GetToDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_TO_DS_)) != 0) + +#define ClearToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \ + } while(0) + +#define SetFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_FROM_DS_); \ + } while(0) + +#define GetFrDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_FROM_DS_)) != 0) + +#define ClearFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ + } while(0) + +#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) + + +#define SetMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \ + } while(0) + +#define GetMFrag(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_FRAG_)) != 0) + +#define ClearMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \ + } while(0) + +#define SetRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_RETRY_); \ + } while(0) + +#define GetRetry(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_RETRY_)) != 0) + +#define ClearRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \ + } while(0) + +#define SetPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PWRMGT_); \ + } while(0) + +#define GetPwrMgt(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PWRMGT_)) != 0) + +#define ClearPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \ + } while(0) + +#define SetMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \ + } while(0) + +#define GetMData(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_DATA_)) != 0) + +#define ClearMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \ + } while(0) + +#define SetPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PRIVACY_); \ + } while(0) + +#define GetPrivacy(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PRIVACY_)) != 0) + +#define ClearPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)); \ + } while(0) + + +#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + +#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & (BIT(3) | BIT(2))) + +#define SetFrameType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= __constant_cpu_to_le16(~(BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= __constant_cpu_to_le16(type); \ + } while(0) + +#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))) + +#define SetFrameSubType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + } while(0) + +#define GetSequence(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) >> 4) + +#define GetFragNum(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & 0x0f) + +#define GetTupleCache(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22))) + +#define SetFragNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu(~(0x000f))) | \ + cpu_to_le16(0x0f & (num)); \ + } while(0) + +#define SetSeqNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu((unsigned short)~0xfff0)) | \ + le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \ + } while(0) + +#define SetDuration(pbuf, dur) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 2) = cpu_to_le16(0xffff & (dur)); \ + } while(0) + + +#define SetPriority(pbuf, tid) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf); \ + } while(0) + +#define GetPriority(pbuf) ((le16_to_cpu(*(unsigned short *)(pbuf))) & 0xf) + +#define SetEOSP(pbuf, eosp) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (eosp & 1) << 4); \ + } while(0) + +#define SetAckpolicy(pbuf, ack) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (ack & 3) << 5); \ + } while(0) + +#define GetAckpolicy(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 5) & 0x3) + +#define GetAMsdu(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 7) & 0x1) + +#define SetAMsdu(pbuf, amsdu) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (amsdu & 1) << 7); \ + } while(0) + +#define GetAid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 2)) & 0x3fff) + +#define GetTid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + (((GetToDs(pbuf)<<1)|GetFrDs(pbuf))==3?30:24))) & 0x000f) + +#define GetAddr1Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 4)) + +#define GetAddr2Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 10)) + +#define GetAddr3Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 16)) + +#define GetAddr4Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 24)) + +#define MacAddr_isBcst(addr) \ +( \ + ( (addr[0] == 0xff) && (addr[1] == 0xff) && \ + (addr[2] == 0xff) && (addr[3] == 0xff) && \ + (addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \ +) + +__inline static int IS_MCAST(unsigned char *da) +{ + if ((*da) & 0x01) + return _TRUE; + else + return _FALSE; +} + +__inline static unsigned char * get_ra(unsigned char *pframe) +{ + unsigned char *ra; + ra = GetAddr1Ptr(pframe); + return ra; +} +__inline static unsigned char * get_ta(unsigned char *pframe) +{ + unsigned char *ta; + ta = GetAddr2Ptr(pframe); + return ta; +} + +__inline static unsigned char * get_da(unsigned char *pframe) +{ + unsigned char *da; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + da = GetAddr1Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + da = GetAddr1Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + da = GetAddr3Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + da = GetAddr3Ptr(pframe); + break; + } + + return da; +} + + +__inline static unsigned char * get_sa(unsigned char *pframe) +{ + unsigned char *sa; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr3Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + sa = GetAddr4Ptr(pframe); + break; + } + + return sa; +} + +__inline static unsigned char * get_hdr_bssid(unsigned char *pframe) +{ + unsigned char *sa = NULL; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr3Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr2Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr1Ptr(pframe); + break; + case 0x03: // ToDs=1, FromDs=1 + sa = GetAddr1Ptr(pframe); + break; + } + + return sa; +} + + +__inline static int IsFrameTypeCtrl(unsigned char *pframe) +{ + if(WIFI_CTRL_TYPE == GetFrameType(pframe)) + return _TRUE; + else + return _FALSE; +} +/*----------------------------------------------------------------------------- + Below is for the security related definition +------------------------------------------------------------------------------*/ +#define _RESERVED_FRAME_TYPE_ 0 +#define _SKB_FRAME_TYPE_ 2 +#define _PRE_ALLOCMEM_ 1 +#define _PRE_ALLOCHDR_ 3 +#define _PRE_ALLOCLLCHDR_ 4 +#define _PRE_ALLOCICVHDR_ 5 +#define _PRE_ALLOCMICHDR_ 6 + +#define _SIFSTIME_ ((priv->pmib->dot11BssType.net_work_type&WIRELESS_11A)?16:10) +#define _ACKCTSLNG_ 14 //14 bytes long, including crclng +#define _CRCLNG_ 4 + +#define _ASOCREQ_IE_OFFSET_ 4 // excluding wlan_hdr +#define _ASOCRSP_IE_OFFSET_ 6 +#define _REASOCREQ_IE_OFFSET_ 10 +#define _REASOCRSP_IE_OFFSET_ 6 +#define _PROBEREQ_IE_OFFSET_ 0 +#define _PROBERSP_IE_OFFSET_ 12 +#define _AUTH_IE_OFFSET_ 6 +#define _DEAUTH_IE_OFFSET_ 0 +#define _BEACON_IE_OFFSET_ 12 +#define _PUBLIC_ACTION_IE_OFFSET_ 8 + +#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_ + +#define _SSID_IE_ 0 +#define _SUPPORTEDRATES_IE_ 1 +#define _DSSET_IE_ 3 +#define _TIM_IE_ 5 +#define _IBSS_PARA_IE_ 6 +#define _COUNTRY_IE_ 7 +#define _CHLGETXT_IE_ 16 +#define _SUPPORTED_CH_IE_ 36 +#define _CH_SWTICH_ANNOUNCE_ 37 //Secondary Channel Offset +#define _RSN_IE_2_ 48 +#define _SSN_IE_1_ 221 +#define _ERPINFO_IE_ 42 +#define _EXT_SUPPORTEDRATES_IE_ 50 + +#define _HT_CAPABILITY_IE_ 45 +#define _FTIE_ 55 +#define _TIMEOUT_ITVL_IE_ 56 +#define _SRC_IE_ 59 +#define _HT_EXTRA_INFO_IE_ 61 +#define _HT_ADD_INFO_IE_ 61 //_HT_EXTRA_INFO_IE_ +#define _WAPI_IE_ 68 + + +//#define EID_BSSCoexistence 72 // 20/40 BSS Coexistence +//#define EID_BSSIntolerantChlReport 73 +#define _RIC_Descriptor_IE_ 75 +#ifdef CONFIG_IEEE80211W +#define _MME_IE_ 76 //802.11w Management MIC element +#endif //CONFIG_IEEE80211W +#define _LINK_ID_IE_ 101 +#define _CH_SWITCH_TIMING_ 104 +#define _PTI_BUFFER_STATUS_ 106 +#define _EXT_CAP_IE_ 127 +#define _VENDOR_SPECIFIC_IE_ 221 + +#define _RESERVED47_ 47 + +typedef enum _ELEMENT_ID{ + EID_SsId = 0, /* service set identifier (0:32) */ + EID_SupRates = 1, /* supported rates (1:8) */ + EID_FHParms = 2, /* FH parameter set (5) */ + EID_DSParms = 3, /* DS parameter set (1) */ + EID_CFParms = 4, /* CF parameter set (6) */ + EID_Tim = 5, /* Traffic Information Map (4:254) */ + EID_IbssParms = 6, /* IBSS parameter set (2) */ + EID_Country = 7, /* */ + + // Form 7.3.2: Information elements in 802.11E/D13.0, page 46. + EID_QBSSLoad = 11, + EID_EDCAParms = 12, + EID_TSpec = 13, + EID_TClass = 14, + EID_Schedule = 15, + // + + EID_Ctext = 16, /* challenge text*/ + EID_POWER_CONSTRAINT = 32, /* Power Constraint*/ + + //vivi for WIFITest, 802.11h AP, 20100427 + // 2010/12/26 MH The definition we can declare always!! + EID_PowerCap = 33, + EID_SupportedChannels = 36, + EID_ChlSwitchAnnounce = 37, + + EID_MeasureRequest = 38, // Measurement Request + EID_MeasureReport = 39, // Measurement Report + + EID_ERPInfo = 42, + + // Form 7.3.2: Information elements in 802.11E/D13.0, page 46. + EID_TSDelay = 43, + EID_TCLASProc = 44, + EID_HTCapability = 45, + EID_QoSCap = 46, + // + + EID_WPA2 = 48, + EID_ExtSupRates = 50, + + EID_FTIE = 55, // Defined in 802.11r + EID_Timeout = 56, // Defined in 802.11r + + EID_SupRegulatory = 59, // Supported Requlatory Classes 802.11y + EID_HTInfo = 61, + EID_SecondaryChnlOffset = 62, + + EID_BSSCoexistence = 72, // 20/40 BSS Coexistence + EID_BSSIntolerantChlReport = 73, + EID_OBSS = 74, // Overlapping BSS Scan Parameters + + EID_LinkIdentifier = 101, // Defined in 802.11z + EID_WakeupSchedule = 102, // Defined in 802.11z + EID_ChnlSwitchTimeing = 104, // Defined in 802.11z + EID_PTIControl = 105, // Defined in 802.11z + EID_PUBufferStatus = 106, // Defined in 802.11z + + EID_EXTCapability = 127, // Extended Capabilities + // From S19:Aironet IE and S21:AP IP address IE in CCX v1.13, p16 and p18. + EID_Aironet = 133, // 0x85: Aironet Element for Cisco CCX + EID_CiscoIP = 149, // 0x95: IP Address IE for Cisco CCX + + EID_CellPwr = 150, // 0x96: Cell Power Limit IE. Ref. 0x96. + + EID_CCKM = 156, + + EID_Vendor = 221, // 0xDD: Vendor Specific + + EID_WAPI = 68, + EID_VHTCapability = 191, // Based on 802.11ac D2.0 + EID_VHTOperation = 192, // Based on 802.11ac D2.0 + EID_AID = 197, /* Based on 802.11ac D4.0 */ + EID_OpModeNotification = 199, // Based on 802.11ac D3.0 +}ELEMENT_ID, *PELEMENT_ID; + +/* --------------------------------------------------------------------------- + Below is the fixed elements... +-----------------------------------------------------------------------------*/ +#define _AUTH_ALGM_NUM_ 2 +#define _AUTH_SEQ_NUM_ 2 +#define _BEACON_ITERVAL_ 2 +#define _CAPABILITY_ 2 +#define _CURRENT_APADDR_ 6 +#define _LISTEN_INTERVAL_ 2 +#define _RSON_CODE_ 2 +#define _ASOC_ID_ 2 +#define _STATUS_CODE_ 2 +#define _TIMESTAMP_ 8 + +#define AUTH_ODD_TO 0 +#define AUTH_EVEN_TO 1 + +#define WLAN_ETHCONV_ENCAP 1 +#define WLAN_ETHCONV_RFC1042 2 +#define WLAN_ETHCONV_8021h 3 + +#define cap_ESS BIT(0) +#define cap_IBSS BIT(1) +#define cap_CFPollable BIT(2) +#define cap_CFRequest BIT(3) +#define cap_Privacy BIT(4) +#define cap_ShortPremble BIT(5) +#define cap_PBCC BIT(6) +#define cap_ChAgility BIT(7) +#define cap_SpecMgmt BIT(8) +#define cap_QoS BIT(9) +#define cap_ShortSlot BIT(10) + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11i / 802.1x +------------------------------------------------------------------------------*/ +#define _IEEE8021X_MGT_ 1 // WPA +#define _IEEE8021X_PSK_ 2 // WPA with pre-shared key + +/* +#define _NO_PRIVACY_ 0 +#define _WEP_40_PRIVACY_ 1 +#define _TKIP_PRIVACY_ 2 +#define _WRAP_PRIVACY_ 3 +#define _CCMP_PRIVACY_ 4 +#define _WEP_104_PRIVACY_ 5 +#define _WEP_WPA_MIXED_PRIVACY_ 6 // WEP + WPA +*/ + +#ifdef CONFIG_IEEE80211W +#define _MME_IE_LENGTH_ 18 +#endif //CONFIG_IEEE80211W +/*----------------------------------------------------------------------------- + Below is the definition for WMM +------------------------------------------------------------------------------*/ +#define _WMM_IE_Length_ 7 // for WMM STA +#define _WMM_Para_Element_Length_ 24 + + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11n +------------------------------------------------------------------------------*/ + +//#ifdef CONFIG_80211N_HT + +#define SetOrderBit(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ + } while(0) + +#define GetOrderBit(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + +#define ACT_CAT_VENDOR 0x7F/* 127 */ + +/** + * struct rtw_ieee80211_bar - HT Block Ack Request + * + * This structure refers to "HT BlockAckReq" as + * described in 802.11n draft section 7.2.1.7.1 + */ + #if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) +struct rtw_ieee80211_bar { + unsigned short frame_control; + unsigned short duration; + unsigned char ra[6]; + unsigned char ta[6]; + unsigned short control; + unsigned short start_seq_num; +} __attribute__((packed)); + #endif + +/* 802.11 BAR control masks */ +#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 +#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 + + + #if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) || defined(PLATFORM_FREEBSD) + + + + /** + * struct rtw_ieee80211_ht_cap - HT capabilities + * + * This structure refers to "HT capabilities element" as + * described in 802.11n draft section 7.3.2.52 + */ + +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +} __attribute__ ((packed)); + +/** + * struct rtw_ieee80211_ht_cap - HT additional information + * + * This structure refers to "HT information element" as + * described in 802.11n draft section 7.3.2.53 + */ +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +} __attribute__ ((packed)); + + +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } HT_cap_element; + unsigned char HT_cap[26]; + }u; +} __attribute__ ((packed)); + +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +} __attribute__ ((packed)); + +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +} __attribute__ ((packed)); + +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +} __attribute__ ((packed)); + +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +} __attribute__ ((packed)); + + + +#endif + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +}; + + +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +}; + +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } HT_cap_element; + unsigned char HT_cap[26]; + }; +}; + +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +}; + +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +}; + +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +}; + +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +}; + + +#pragma pack() + +#endif + +typedef enum _HT_CAP_AMPDU_FACTOR { + MAX_AMPDU_FACTOR_8K = 0, + MAX_AMPDU_FACTOR_16K = 1, + MAX_AMPDU_FACTOR_32K = 2, + MAX_AMPDU_FACTOR_64K = 3, +}HT_CAP_AMPDU_FACTOR; + + +typedef enum _HT_CAP_AMPDU_DENSITY { + AMPDU_DENSITY_VALUE_0 = 0 , /* For no restriction */ + AMPDU_DENSITY_VALUE_1 = 1 , /* For 1/4 us */ + AMPDU_DENSITY_VALUE_2 = 2 , /* For 1/2 us */ + AMPDU_DENSITY_VALUE_3 = 3 , /* For 1 us */ + AMPDU_DENSITY_VALUE_4 = 4 , /* For 2 us */ + AMPDU_DENSITY_VALUE_5 = 5 , /* For 4 us */ + AMPDU_DENSITY_VALUE_6 = 6 , /* For 8 us */ + AMPDU_DENSITY_VALUE_7 = 7 , /* For 16 us */ +} HT_CAP_AMPDU_DENSITY; + +/* 802.11n HT capabilities masks */ +#define IEEE80211_HT_CAP_LDPC_CODING 0x0001 +#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 +#define IEEE80211_HT_CAP_SM_PS 0x000C +#define IEEE80211_HT_CAP_GRN_FLD 0x0010 +#define IEEE80211_HT_CAP_SGI_20 0x0020 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_TX_STBC 0x0080 +#define IEEE80211_HT_CAP_RX_STBC_1R 0x0100 +#define IEEE80211_HT_CAP_RX_STBC_2R 0x0200 +#define IEEE80211_HT_CAP_RX_STBC_3R 0x0300 +#define IEEE80211_HT_CAP_DELAY_BA 0x0400 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 +#define RTW_IEEE80211_HT_CAP_40MHZ_INTOLERANT ((u16) BIT(14)) +/* 802.11n HT capability AMPDU settings */ +#define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03 +#define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C +/* 802.11n HT capability MSC set */ +#define IEEE80211_SUPP_MCS_SET_UEQM 4 +#define IEEE80211_HT_CAP_MAX_STREAMS 4 +#define IEEE80211_SUPP_MCS_SET_LEN 10 +/* maximum streams the spec allows */ +#define IEEE80211_HT_CAP_MCS_TX_DEFINED 0x01 +#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF 0x02 +#define IEEE80211_HT_CAP_MCS_TX_STREAMS 0x0C +#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 +/* 802.11n HT capability TXBF capability */ +#define IEEE80211_HT_CAP_TXBF_RX_NDP 0x00000008 +#define IEEE80211_HT_CAP_TXBF_TX_NDP 0x00000010 +#define IEEE80211_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP 0x00000400 + +/* 802.11n HT IE masks */ +#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 +#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 +#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 +#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 +#define IEEE80211_HT_IE_CHA_WIDTH 0x04 +#define IEEE80211_HT_IE_HT_PROTECTION 0x0003 +#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 +#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 + +/* block-ack parameters */ +#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C +#define RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0 +#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 +#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 + +/* + * A-PMDU buffer sizes + * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) + */ +#define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_MAX_AMPDU_BUF 0x40 + + +/* Spatial Multiplexing Power Save Modes */ +#define WLAN_HT_CAP_SM_PS_STATIC 0 +#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 +#define WLAN_HT_CAP_SM_PS_INVALID 2 +#define WLAN_HT_CAP_SM_PS_DISABLED 3 + + +#define OP_MODE_PURE 0 +#define OP_MODE_MAY_BE_LEGACY_STAS 1 +#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 +#define OP_MODE_MIXED 3 + +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) + +#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ + ((u16) (0x0001 | 0x0002)) +#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BCN ((u16) BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) + + + +//#endif + +// ===============WPS Section=============== +// For WPSv1.0 +#define WPSOUI 0x0050f204 +// WPS attribute ID +#define WPS_ATTR_VER1 0x104A +#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044 +#define WPS_ATTR_RESP_TYPE 0x103B +#define WPS_ATTR_UUID_E 0x1047 +#define WPS_ATTR_MANUFACTURER 0x1021 +#define WPS_ATTR_MODEL_NAME 0x1023 +#define WPS_ATTR_MODEL_NUMBER 0x1024 +#define WPS_ATTR_SERIAL_NUMBER 0x1042 +#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054 +#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055 +#define WPS_ATTR_DEVICE_NAME 0x1011 +#define WPS_ATTR_CONF_METHOD 0x1008 +#define WPS_ATTR_RF_BANDS 0x103C +#define WPS_ATTR_DEVICE_PWID 0x1012 +#define WPS_ATTR_REQUEST_TYPE 0x103A +#define WPS_ATTR_ASSOCIATION_STATE 0x1002 +#define WPS_ATTR_CONFIG_ERROR 0x1009 +#define WPS_ATTR_VENDOR_EXT 0x1049 +#define WPS_ATTR_SELECTED_REGISTRAR 0x1041 + +// Value of WPS attribute "WPS_ATTR_DEVICE_NAME +#define WPS_MAX_DEVICE_NAME_LEN 32 + +// Value of WPS Request Type Attribute +#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 +#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 +#define WPS_REQ_TYPE_REGISTRAR 0x02 +#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR 0x03 + +// Value of WPS Response Type Attribute +#define WPS_RESPONSE_TYPE_INFO_ONLY 0x00 +#define WPS_RESPONSE_TYPE_8021X 0x01 +#define WPS_RESPONSE_TYPE_REGISTRAR 0x02 +#define WPS_RESPONSE_TYPE_AP 0x03 + +// Value of WPS WiFi Simple Configuration State Attribute +#define WPS_WSC_STATE_NOT_CONFIG 0x01 +#define WPS_WSC_STATE_CONFIG 0x02 + +// Value of WPS Version Attribute +#define WPS_VERSION_1 0x10 + +// Value of WPS Configuration Method Attribute +#define WPS_CONFIG_METHOD_FLASH 0x0001 +#define WPS_CONFIG_METHOD_ETHERNET 0x0002 +#define WPS_CONFIG_METHOD_LABEL 0x0004 +#define WPS_CONFIG_METHOD_DISPLAY 0x0008 +#define WPS_CONFIG_METHOD_E_NFC 0x0010 +#define WPS_CONFIG_METHOD_I_NFC 0x0020 +#define WPS_CONFIG_METHOD_NFC 0x0040 +#define WPS_CONFIG_METHOD_PBC 0x0080 +#define WPS_CONFIG_METHOD_KEYPAD 0x0100 +#define WPS_CONFIG_METHOD_VPBC 0x0280 +#define WPS_CONFIG_METHOD_PPBC 0x0480 +#define WPS_CONFIG_METHOD_VDISPLAY 0x2008 +#define WPS_CONFIG_METHOD_PDISPLAY 0x4008 + +// Value of Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_CID_DISPLAYS 0x0007 +#define WPS_PDT_CID_MULIT_MEDIA 0x0008 +#define WPS_PDT_CID_RTK_WIDI WPS_PDT_CID_MULIT_MEDIA + +// Value of Sub Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_SCID_MEDIA_SERVER 0x0005 +#define WPS_PDT_SCID_RTK_DMP WPS_PDT_SCID_MEDIA_SERVER + +// Value of Device Password ID +#define WPS_DPID_PIN 0x0000 +#define WPS_DPID_USER_SPEC 0x0001 +#define WPS_DPID_MACHINE_SPEC 0x0002 +#define WPS_DPID_REKEY 0x0003 +#define WPS_DPID_PBC 0x0004 +#define WPS_DPID_REGISTRAR_SPEC 0x0005 + +// Value of WPS RF Bands Attribute +#define WPS_RF_BANDS_2_4_GHZ 0x01 +#define WPS_RF_BANDS_5_GHZ 0x02 + +// Value of WPS Association State Attribute +#define WPS_ASSOC_STATE_NOT_ASSOCIATED 0x00 +#define WPS_ASSOC_STATE_CONNECTION_SUCCESS 0x01 +#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE 0x02 +#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03 +#define WPS_ASSOC_STATE_IP_FAILURE 0x04 + +// =====================P2P Section===================== +// For P2P +#define P2POUI 0x506F9A09 + +// P2P Attribute ID +#define P2P_ATTR_STATUS 0x00 +#define P2P_ATTR_MINOR_REASON_CODE 0x01 +#define P2P_ATTR_CAPABILITY 0x02 +#define P2P_ATTR_DEVICE_ID 0x03 +#define P2P_ATTR_GO_INTENT 0x04 +#define P2P_ATTR_CONF_TIMEOUT 0x05 +#define P2P_ATTR_LISTEN_CH 0x06 +#define P2P_ATTR_GROUP_BSSID 0x07 +#define P2P_ATTR_EX_LISTEN_TIMING 0x08 +#define P2P_ATTR_INTENTED_IF_ADDR 0x09 +#define P2P_ATTR_MANAGEABILITY 0x0A +#define P2P_ATTR_CH_LIST 0x0B +#define P2P_ATTR_NOA 0x0C +#define P2P_ATTR_DEVICE_INFO 0x0D +#define P2P_ATTR_GROUP_INFO 0x0E +#define P2P_ATTR_GROUP_ID 0x0F +#define P2P_ATTR_INTERFACE 0x10 +#define P2P_ATTR_OPERATING_CH 0x11 +#define P2P_ATTR_INVITATION_FLAGS 0x12 + +// Value of Status Attribute +#define P2P_STATUS_SUCCESS 0x00 +#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02 +#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03 +#define P2P_STATUS_FAIL_INVALID_PARAM 0x04 +#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05 +#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06 +#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07 +#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08 +#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A +#define P2P_STATUS_FAIL_USER_REJECT 0x0B + +// Value of Inviation Flags Attribute +#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) + +#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ + P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ + P2P_DEVCAP_CONCURRENT_OPERATION | \ + P2P_DEVCAP_INVITATION_PROC) + +#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) + +// Value of Device Capability Bitmap +#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) +#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1) +#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2) +#define P2P_DEVCAP_INFRA_MANAGED BIT(3) +#define P2P_DEVCAP_DEVICE_LIMIT BIT(4) +#define P2P_DEVCAP_INVITATION_PROC BIT(5) + +// Value of Group Capability Bitmap +#define P2P_GRPCAP_GO BIT(0) +#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1) +#define P2P_GRPCAP_GROUP_LIMIT BIT(2) +#define P2P_GRPCAP_INTRABSS BIT(3) +#define P2P_GRPCAP_CROSS_CONN BIT(4) +#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5) +#define P2P_GRPCAP_GROUP_FORMATION BIT(6) + +// P2P Public Action Frame ( Management Frame ) +#define P2P_PUB_ACTION_ACTION 0x09 + +// P2P Public Action Frame Type +#define P2P_GO_NEGO_REQ 0 +#define P2P_GO_NEGO_RESP 1 +#define P2P_GO_NEGO_CONF 2 +#define P2P_INVIT_REQ 3 +#define P2P_INVIT_RESP 4 +#define P2P_DEVDISC_REQ 5 +#define P2P_DEVDISC_RESP 6 +#define P2P_PROVISION_DISC_REQ 7 +#define P2P_PROVISION_DISC_RESP 8 + +// P2P Action Frame Type +#define P2P_NOTICE_OF_ABSENCE 0 +#define P2P_PRESENCE_REQUEST 1 +#define P2P_PRESENCE_RESPONSE 2 +#define P2P_GO_DISC_REQUEST 3 + + +#define P2P_MAX_PERSISTENT_GROUP_NUM 10 + +#define P2P_PROVISIONING_SCAN_CNT 3 + +#define P2P_WILDCARD_SSID_LEN 7 + +#define P2P_FINDPHASE_EX_NONE 0 // default value, used when: (1)p2p disabed or (2)p2p enabled but only do 1 scan phase +#define P2P_FINDPHASE_EX_FULL 1 // used when p2p enabled and want to do 1 scan phase and P2P_FINDPHASE_EX_MAX-1 find phase +#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1) +#define P2P_FINDPHASE_EX_MAX 4 +#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX + +#define P2P_PROVISION_TIMEOUT 5000 // 5 seconds timeout for sending the provision discovery request +#define P2P_CONCURRENT_PROVISION_TIMEOUT 3000 // 3 seconds timeout for sending the provision discovery request under concurrent mode +#define P2P_GO_NEGO_TIMEOUT 5000 // 5 seconds timeout for receiving the group negotation response +#define P2P_CONCURRENT_GO_NEGO_TIMEOUT 3000 // 3 seconds timeout for sending the negotiation request under concurrent mode +#define P2P_TX_PRESCAN_TIMEOUT 100 // 100ms +#define P2P_INVITE_TIMEOUT 5000 // 5 seconds timeout for sending the invitation request +#define P2P_CONCURRENT_INVITE_TIMEOUT 3000 // 3 seconds timeout for sending the invitation request under concurrent mode +#define P2P_RESET_SCAN_CH 25000 // 25 seconds timeout to reset the scan channel ( based on channel plan ) +#define P2P_MAX_INTENT 15 + +#define P2P_MAX_NOA_NUM 2 + +// WPS Configuration Method +#define WPS_CM_NONE 0x0000 +#define WPS_CM_LABEL 0x0004 +#define WPS_CM_DISPLYA 0x0008 +#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010 +#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020 +#define WPS_CM_NFC_INTERFACE 0x0040 +#define WPS_CM_PUSH_BUTTON 0x0080 +#define WPS_CM_KEYPAD 0x0100 +#define WPS_CM_SW_PUHS_BUTTON 0x0280 +#define WPS_CM_HW_PUHS_BUTTON 0x0480 +#define WPS_CM_SW_DISPLAY_PIN 0x2008 +#define WPS_CM_LCD_DISPLAY_PIN 0x4008 + +enum P2P_ROLE { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum P2P_STATE { + P2P_STATE_NONE = 0, // P2P disable + P2P_STATE_IDLE = 1, // P2P had enabled and do nothing + P2P_STATE_LISTEN = 2, // In pure listen state + P2P_STATE_SCAN = 3, // In scan phase + P2P_STATE_FIND_PHASE_LISTEN = 4, // In the listen state of find phase + P2P_STATE_FIND_PHASE_SEARCH = 5, // In the search state of find phase + P2P_STATE_TX_PROVISION_DIS_REQ = 6, // In P2P provisioning discovery + P2P_STATE_RX_PROVISION_DIS_RSP = 7, + P2P_STATE_RX_PROVISION_DIS_REQ = 8, + P2P_STATE_GONEGO_ING = 9, // Doing the group owner negoitation handshake + P2P_STATE_GONEGO_OK = 10, // finish the group negoitation handshake with success + P2P_STATE_GONEGO_FAIL = 11, // finish the group negoitation handshake with failure + P2P_STATE_RECV_INVITE_REQ_MATCH = 12, // receiving the P2P Inviation request and match with the profile. + P2P_STATE_PROVISIONING_ING = 13, // Doing the P2P WPS + P2P_STATE_PROVISIONING_DONE = 14, // Finish the P2P WPS + P2P_STATE_TX_INVITE_REQ = 15, // Transmit the P2P Invitation request + P2P_STATE_RX_INVITE_RESP_OK = 16, // Receiving the P2P Invitation response + P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, // receiving the P2P Inviation request and dismatch with the profile. + P2P_STATE_RECV_INVITE_REQ_GO = 18, // receiving the P2P Inviation request and this wifi is GO. + P2P_STATE_RECV_INVITE_REQ_JOIN = 19, // receiving the P2P Inviation request to join an existing P2P Group. + P2P_STATE_RX_INVITE_RESP_FAIL = 20, // recveing the P2P Inviation response with failure + P2P_STATE_RX_INFOR_NOREADY = 21, // receiving p2p negoitation response with information is not available + P2P_STATE_TX_INFOR_NOREADY = 22, // sending p2p negoitation response with information is not available +}; + +enum P2P_WPSINFO { + P2P_NO_WPSINFO = 0, + P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, + P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, + P2P_GOT_WPSINFO_PBC = 3, +}; + +#define P2P_PRIVATE_IOCTL_SET_LEN 64 + +enum P2P_PROTO_WK_ID +{ + P2P_FIND_PHASE_WK = 0, + P2P_RESTORE_STATE_WK = 1, + P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, + P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, + P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, + P2P_AP_P2P_CH_SWITCH_PROCESS_WK =5, + P2P_RO_CH_WK = 6, +}; + +#ifdef CONFIG_P2P_PS +enum P2P_PS_STATE +{ + P2P_PS_DISABLE = 0, + P2P_PS_ENABLE = 1, + P2P_PS_SCAN = 2, + P2P_PS_SCAN_DONE = 3, + P2P_PS_ALLSTASLEEP = 4, // for P2P GO +}; + +enum P2P_PS_MODE +{ + P2P_PS_NONE = 0, + P2P_PS_CTWINDOW = 1, + P2P_PS_NOA = 2, + P2P_PS_MIX = 3, // CTWindow and NoA +}; +#endif // CONFIG_P2P_PS + +// =====================WFD Section===================== +// For Wi-Fi Display +#define WFD_ATTR_DEVICE_INFO 0x00 +#define WFD_ATTR_ASSOC_BSSID 0x01 +#define WFD_ATTR_COUPLED_SINK_INFO 0x06 +#define WFD_ATTR_LOCAL_IP_ADDR 0x08 +#define WFD_ATTR_SESSION_INFO 0x09 +#define WFD_ATTR_ALTER_MAC 0x0a + +// For WFD Device Information Attribute +#define WFD_DEVINFO_SOURCE 0x0000 +#define WFD_DEVINFO_PSINK 0x0001 +#define WFD_DEVINFO_SSINK 0x0002 +#define WFD_DEVINFO_DUAL 0x0003 + +#define WFD_DEVINFO_SESSION_AVAIL 0x0010 +#define WFD_DEVINFO_WSD 0x0040 +#define WFD_DEVINFO_PC_TDLS 0x0080 +#define WFD_DEVINFO_HDCP_SUPPORT 0x0100 + +#ifdef CONFIG_TX_MCAST2UNI +#define IP_MCAST_MAC(mac) ((mac[0]==0x01)&&(mac[1]==0x00)&&(mac[2]==0x5e)) +#define ICMPV6_MCAST_MAC(mac) ((mac[0]==0x33)&&(mac[1]==0x33)&&(mac[2]!=0xff)) +#endif // CONFIG_TX_MCAST2UNI + +#ifdef CONFIG_IOCTL_CFG80211 +/* Regulatroy Domain */ +struct regd_pair_mapping { + u16 reg_dmnenum; + u16 reg_5ghz_ctl; + u16 reg_2ghz_ctl; +}; + +struct rtw_regulatory { + char alpha2[2]; + u16 country_code; + u16 max_power_level; + u32 tp_scale; + u16 current_rd; + u16 current_rd_ext; + int16_t power_limit; + struct regd_pair_mapping *regpair; +}; +#endif + +#ifdef CONFIG_WAPI_SUPPORT +#ifndef IW_AUTH_WAPI_VERSION_1 +#define IW_AUTH_WAPI_VERSION_1 0x00000008 +#endif +#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK +#define IW_AUTH_KEY_MGMT_WAPI_PSK 0x04 +#endif +#ifndef IW_AUTH_WAPI_ENABLED +#define IW_AUTH_WAPI_ENABLED 0x20 +#endif +#ifndef IW_ENCODE_ALG_SM4 +#define IW_ENCODE_ALG_SM4 0x20 +#endif +#endif + +#endif // _WIFI_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/wlan_bssdef.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/wlan_bssdef.h new file mode 100644 index 00000000..bd5237a7 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/wlan_bssdef.h @@ -0,0 +1,748 @@ +/****************************************************************************** + * + * 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 __WLAN_BSSDEF_H__ +#define __WLAN_BSSDEF_H__ + + +#define MAX_IE_SZ 768 + + +#ifdef PLATFORM_LINUX + +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef ULONG NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + ULONG SsidLength; + UCHAR Ssid[32]; +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + ULONG Length; // Length of structure + ULONG HopPattern; // As defined by 802.11, MSB set + ULONG HopSet; // to one if non-802.11 + ULONG DwellTime; // units are Kusec +} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + ULONG Length; // Length of structure + ULONG BeaconPeriod; // units are Kusec + ULONG ATIMWindow; // units are Kusec + ULONG DSConfig; /* channel number */ + NDIS_802_11_CONFIGURATION_FH FHConfig; +} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode, + Ndis802_11Monitor, +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + UCHAR Timestamp[8]; + USHORT BeaconInterval; + USHORT Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + UCHAR ElementID; + UCHAR Length; + UCHAR data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + ULONG NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeWAPI, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent, + Ndis802_11_EncrypteionWAPI +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + USHORT Capabilities; + USHORT ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + USHORT Capabilities; + USHORT StatusCode; + USHORT AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + ULONG Length; + USHORT AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + ULONG RequestIELength; + ULONG OffsetRequestIEs; + USHORT AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + ULONG ResponseIELength; + ULONG OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + ULONG KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + UCHAR KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; // 0 is the per-client key, 1-N are the global keys + ULONG KeyLength; // length of key in bytes + UCHAR KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + ULONG Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + ULONG Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + ULONG Length; + ULONG Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //end of #ifdef PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef ULONG NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + ULONG SsidLength; + UCHAR Ssid[32]; +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + ULONG Length; // Length of structure + ULONG HopPattern; // As defined by 802.11, MSB set + ULONG HopSet; // to one if non-802.11 + ULONG DwellTime; // units are Kusec +} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + ULONG Length; // Length of structure + ULONG BeaconPeriod; // units are Kusec + ULONG ATIMWindow; // units are Kusec + ULONG DSConfig; /* channel number */ + NDIS_802_11_CONFIGURATION_FH FHConfig; +} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + UCHAR Timestamp[8]; + USHORT BeaconInterval; + USHORT Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + UCHAR ElementID; + UCHAR Length; + UCHAR data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (ULONG) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + ULONG NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + USHORT Capabilities; + USHORT ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + USHORT Capabilities; + USHORT StatusCode; + USHORT AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + ULONG Length; + USHORT AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + ULONG RequestIELength; + ULONG OffsetRequestIEs; + USHORT AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + ULONG ResponseIELength; + ULONG OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + ULONG KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + UCHAR KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + ULONG Length; // Length of this structure + ULONG KeyIndex; // 0 is the per-client key, 1-N are the global keys + ULONG KeyLength; // length of key in bytes + UCHAR KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + ULONG Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + ULONG Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + ULONG Length; + ULONG Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //PLATFORM_FREEBSD +#ifndef Ndis802_11APMode +#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1) +#endif + +typedef struct _WLAN_PHY_INFO +{ + u8 SignalStrength;//(in percentage) + u8 SignalQuality;//(in percentage) + u8 Optimum_antenna; //for Antenna diversity + u8 Reserved_0; +}WLAN_PHY_INFO,*PWLAN_PHY_INFO; + +typedef struct _WLAN_BCN_INFO +{ + /* these infor get from rtw_get_encrypt_info when + * * translate scan to UI */ + u8 encryp_protocol;//ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2/WAPI + int group_cipher; //WPA/WPA2 group cipher + int pairwise_cipher;////WPA/WPA2/WEP pairwise cipher + int is_8021x; + + /* bwmode 20/40 and ch_offset UP/LOW */ + unsigned short ht_cap_info; + unsigned char ht_info_infos_0; +}WLAN_BCN_INFO,*PWLAN_BCN_INFO; + +/* temporally add #pragma pack for structure alignment issue of +* WLAN_BSSID_EX and get_WLAN_BSSID_EX_sz() +*/ +#ifdef PLATFORM_WINDOWS +#pragma pack(push) +#pragma pack(1) +#endif +typedef struct _WLAN_BSSID_EX +{ + ULONG Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + UCHAR Reserved[2];//[0]: IS beacon frame + NDIS_802_11_SSID Ssid; + ULONG Privacy; + NDIS_802_11_RSSI Rssi;//(in dBM,raw data ,get from PHY) + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + WLAN_PHY_INFO PhyInfo; + ULONG IELength; + UCHAR IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} +#ifndef PLATFORM_WINDOWS +__attribute__((packed)) +#endif +WLAN_BSSID_EX, *PWLAN_BSSID_EX; +#ifdef PLATFORM_WINDOWS +#pragma pack(pop) +#endif + +#define BSS_EX_IES(bss_ex) ((bss_ex)->IEs) +#define BSS_EX_IES_LEN(bss_ex) ((bss_ex)->IELength) +#define BSS_EX_FIXED_IE_OFFSET(bss_ex) ((bss_ex)->Reserved[0] == 2 ? 0 : 12) +#define BSS_EX_TLV_IES(bss_ex) (BSS_EX_IES((bss_ex)) + BSS_EX_FIXED_IE_OFFSET((bss_ex))) +#define BSS_EX_TLV_IES_LEN(bss_ex) (BSS_EX_IES_LEN((bss_ex)) - BSS_EX_FIXED_IE_OFFSET((bss_ex))) + +__inline static uint get_WLAN_BSSID_EX_sz(WLAN_BSSID_EX *bss) +{ +#if 0 + uint t_len; + + t_len = sizeof (ULONG) + + sizeof (NDIS_802_11_MAC_ADDRESS) + + 2 + + sizeof (NDIS_802_11_SSID) + + sizeof (ULONG) + + sizeof (NDIS_802_11_RSSI) + + sizeof (NDIS_802_11_NETWORK_TYPE) + + sizeof (NDIS_802_11_CONFIGURATION) + + sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) + + sizeof (NDIS_802_11_RATES_EX) + //all new member add here + + sizeof(WLAN_PHY_INFO) + //all new member add here + + sizeof (ULONG) + + bss->IELength; + return t_len; +#else + return (sizeof(WLAN_BSSID_EX) -MAX_IE_SZ + bss->IELength); +#endif +} + +struct wlan_network { + _list list; + int network_type; //refer to ieee80211.h for WIRELESS_11A/B/G + int fixed; // set to fixed when not to be removed as site-surveying + unsigned long last_scanned; //timestamp for the network + int aid; //will only be valid when a BSS is joinned. + int join_res; + WLAN_BSSID_EX network; //must be the last item + WLAN_BCN_INFO BcnInfo; +#ifdef PLATFORM_WINDOWS + unsigned char iebuf[MAX_IE_SZ]; +#endif + +}; + +enum VRTL_CARRIER_SENSE +{ + DISABLE_VCS, + ENABLE_VCS, + AUTO_VCS +}; + +enum VCS_TYPE +{ + NONE_VCS, + RTS_CTS, + CTS_TO_SELF +}; + + + + +#define PWR_CAM 0 +#define PWR_MINPS 1 +#define PWR_MAXPS 2 +#define PWR_UAPSD 3 +#define PWR_VOIP 4 + + +enum UAPSD_MAX_SP +{ + NO_LIMIT, + TWO_MSDU, + FOUR_MSDU, + SIX_MSDU +}; + + +//john +#define NUM_PRE_AUTH_KEY 16 +#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY + +/* +* WPA2 +*/ + +#ifndef PLATFORM_OS_CE +typedef struct _PMKID_CANDIDATE { + NDIS_802_11_MAC_ADDRESS BSSID; + ULONG Flags; +} PMKID_CANDIDATE, *PPMKID_CANDIDATE; + +typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST +{ + ULONG Version; // Version of the structure + ULONG NumCandidates; // No. of pmkid candidates + PMKID_CANDIDATE CandidateList[1]; +} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST; + + +typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION +{ + NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; + NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; + +} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION; + +typedef struct _NDIS_802_11_CAPABILITY +{ + ULONG Length; + ULONG Version; + ULONG NoOfPMKIDs; + ULONG NoOfAuthEncryptPairsSupported; + NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1]; + +} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY; +#endif + + +#endif //#ifndef WLAN_BSSDEF_H_ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/include/xmit_osdep.h b/linux-3.4/drivers/net/wireless/rtl8189fs/include/xmit_osdep.h new file mode 100644 index 00000000..d489ebfc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/include/xmit_osdep.h @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * 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 __XMIT_OSDEP_H_ +#define __XMIT_OSDEP_H_ + + +struct pkt_file { + _pkt *pkt; + SIZE_T pkt_len; //the remainder length of the open_file + _buffer *cur_buffer; + u8 *buf_start; + u8 *cur_addr; + SIZE_T buf_len; +}; + +#ifdef PLATFORM_WINDOWS + +#ifdef PLATFORM_OS_XP +#ifdef CONFIG_USB_HCI +#include +#include +#include +#endif +#endif + +#ifdef CONFIG_GSPI_HCI +#define NR_XMITFRAME 64 +#else +#define NR_XMITFRAME 128 +#endif + +#define ETH_ALEN 6 + +extern NDIS_STATUS rtw_xmit_entry( +IN _nic_hdl cnxt, +IN NDIS_PACKET *pkt, +IN UINT flags +); + +#endif + +#ifdef PLATFORM_FREEBSD +#define NR_XMITFRAME 256 +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); +extern void rtw_xmit_entry_wrap (struct ifnet * pifp); +#endif //PLATFORM_FREEBSD + +#ifdef PLATFORM_LINUX + +#define NR_XMITFRAME 256 + +struct xmit_priv; +struct pkt_attrib; +struct sta_xmit_priv; +struct xmit_frame; +struct xmit_buf; + +extern int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); + +#endif + +void rtw_os_xmit_schedule(_adapter *padapter); + +int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz, u8 flag); +void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf, u32 free_sz, u8 flag); + +extern void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib); + +extern uint rtw_remainder_len(struct pkt_file *pfile); +extern void _rtw_open_pktfile(_pkt *pkt, struct pkt_file *pfile); +extern uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen); +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/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/custom_gpio_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/custom_gpio_linux.c new file mode 100644 index 00000000..418d7932 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/custom_gpio_linux.c @@ -0,0 +1,356 @@ +/****************************************************************************** + * Customer code to add GPIO control during WLAN start/stop + * + * 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 "drv_types.h" + +#ifdef CONFIG_PLATFORM_SPRD + +//gspi func & GPIO define +#include //0915 +#include + +#if !(defined ANDROID_2X) + +#ifdef CONFIG_RTL8188E +#include +#include +#endif // CONFIG_RTL8188E + +#ifndef GPIO_WIFI_POWER +#define GPIO_WIFI_POWER -1 +#endif // !GPIO_WIFI_POWER + +#ifndef GPIO_WIFI_RESET +#define GPIO_WIFI_RESET -1 +#endif // !GPIO_WIFI_RESET + +#ifndef GPIO_WIFI_PWDN +#define GPIO_WIFI_PWDN -1 +#endif // !GPIO_WIFI_RESET +#ifdef CONFIG_GSPI_HCI +extern unsigned int oob_irq; +#endif // CONFIG_GSPI_HCI + +#ifdef CONFIG_SDIO_HCI +extern int rtw_mp_mode; +#else // !CONFIG_SDIO_HCI +#endif // !CONFIG_SDIO_HCI + +int rtw_wifi_gpio_init(void) +{ +#ifdef CONFIG_GSPI_HCI + if (GPIO_WIFI_IRQ > 0) { + gpio_request(GPIO_WIFI_IRQ, "oob_irq"); + gpio_direction_input(GPIO_WIFI_IRQ); + + oob_irq = gpio_to_irq(GPIO_WIFI_IRQ); + + DBG_8192C("%s oob_irq:%d\n", __func__, oob_irq); + } +#endif + if (GPIO_WIFI_RESET > 0) + gpio_request(GPIO_WIFI_RESET , "wifi_rst"); + if (GPIO_WIFI_POWER > 0) + gpio_request(GPIO_WIFI_POWER, "wifi_power"); + +#ifdef CONFIG_SDIO_HCI +#if (defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1) + if(rtw_mp_mode==1){ + DBG_871X("%s GPIO_BT_RESET pin special for mp_test\n", __func__); + if (GPIO_BT_RESET > 0) + gpio_request(GPIO_BT_RESET , "bt_rst"); + } +#endif +#endif + return 0; +} + +int rtw_wifi_gpio_deinit(void) +{ +#ifdef CONFIG_GSPI_HCI + if (GPIO_WIFI_IRQ > 0) + gpio_free(GPIO_WIFI_IRQ); +#endif + if (GPIO_WIFI_RESET > 0) + gpio_free(GPIO_WIFI_RESET ); + if (GPIO_WIFI_POWER > 0) + gpio_free(GPIO_WIFI_POWER); + +#ifdef CONFIG_SDIO_HCI +#if ( defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1) + if(rtw_mp_mode==1){ + DBG_871X("%s GPIO_BT_RESET pin special for mp_test\n", __func__); + if (GPIO_BT_RESET > 0) + gpio_free(GPIO_BT_RESET); + } +#endif +#endif + return 0; +} + +/* Customer function to control hw specific wlan gpios */ +void rtw_wifi_gpio_wlan_ctrl(int onoff) +{ + switch (onoff) + { + case WLAN_PWDN_OFF: + DBG_8192C("%s: call customer specific GPIO(%d) to set wifi power down pin to 0\n", + __FUNCTION__, GPIO_WIFI_RESET); + +#ifndef CONFIG_DONT_BUS_SCAN + if (GPIO_WIFI_RESET > 0) + gpio_direction_output(GPIO_WIFI_RESET , 0); +#endif + break; + + case WLAN_PWDN_ON: + DBG_8192C("%s: callc customer specific GPIO(%d) to set wifi power down pin to 1\n", + __FUNCTION__, GPIO_WIFI_RESET); + + if (GPIO_WIFI_RESET > 0) + gpio_direction_output(GPIO_WIFI_RESET , 1); + break; + + case WLAN_POWER_OFF: + break; + + case WLAN_POWER_ON: + break; +#ifdef CONFIG_SDIO_HCI +#if ( defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1) + case WLAN_BT_PWDN_OFF: + if(rtw_mp_mode==1) + { + DBG_871X("%s: call customer specific GPIO to set wifi power down pin to 0\n", + __FUNCTION__); + if (GPIO_BT_RESET > 0) + gpio_direction_output(GPIO_BT_RESET , 0); + } + break; + + case WLAN_BT_PWDN_ON: + if(rtw_mp_mode==1) + { + DBG_871X("%s: callc customer specific GPIO to set wifi power down pin to 1 %x\n", + __FUNCTION__, GPIO_BT_RESET); + + if (GPIO_BT_RESET > 0) + gpio_direction_output(GPIO_BT_RESET , 1); + } + break; +#endif +#endif + } +} + +#else //ANDROID_2X + +#include + +#ifdef CONFIG_RTL8188E +extern int sprd_3rdparty_gpio_wifi_power; +#endif +extern int sprd_3rdparty_gpio_wifi_pwd; +#if defined(CONFIG_RTL8723B) +extern int sprd_3rdparty_gpio_bt_reset; +#endif + +int rtw_wifi_gpio_init(void) +{ +#if defined(CONFIG_RTL8723B) + if (sprd_3rdparty_gpio_bt_reset > 0) + gpio_direction_output(sprd_3rdparty_gpio_bt_reset, 1); +#endif + + return 0; +} + +int rtw_wifi_gpio_deinit(void) +{ + return 0; +} + +/* Customer function to control hw specific wlan gpios */ +void rtw_wifi_gpio_wlan_ctrl(int onoff) +{ + switch (onoff) + { + case WLAN_PWDN_OFF: + DBG_8192C("%s: call customer specific GPIO to set wifi power down pin to 0\n", + __FUNCTION__); + if (sprd_3rdparty_gpio_wifi_pwd > 0) + { + gpio_set_value(sprd_3rdparty_gpio_wifi_pwd, 0); + } + + if (sprd_3rdparty_gpio_wifi_pwd == 60) { + DBG_8192C("%s: turn off VSIM2 2.8V\n", __func__); + LDO_TurnOffLDO(LDO_LDO_SIM2); + } + break; + + case WLAN_PWDN_ON: + DBG_8192C("%s: callc customer specific GPIO to set wifi power down pin to 1\n", + __FUNCTION__); + if (sprd_3rdparty_gpio_wifi_pwd == 60) { + DBG_8192C("%s: turn on VSIM2 2.8V\n", __func__); + LDO_SetVoltLevel(LDO_LDO_SIM2, LDO_VOLT_LEVEL0); + LDO_TurnOnLDO(LDO_LDO_SIM2); + } + if (sprd_3rdparty_gpio_wifi_pwd > 0) + { + gpio_set_value(sprd_3rdparty_gpio_wifi_pwd, 1); + } + break; + + case WLAN_POWER_OFF: +#ifdef CONFIG_RTL8188E +#ifdef CONFIG_WIF1_LDO + DBG_8192C("%s: turn off VDD-WIFI0 1.2V\n", __FUNCTION__); + LDO_TurnOffLDO(LDO_LDO_WIF1); +#endif //CONFIG_WIF1_LDO + + DBG_8192C("%s: turn off VDD-WIFI0 3.3V\n", __FUNCTION__); + LDO_TurnOffLDO(LDO_LDO_WIF0); + + DBG_8192C("%s: call customer specific GPIO(%d) to turn off wifi power\n", + __FUNCTION__, sprd_3rdparty_gpio_wifi_power); + if (sprd_3rdparty_gpio_wifi_power != 65535) + gpio_set_value(sprd_3rdparty_gpio_wifi_power, 0); +#endif + break; + + case WLAN_POWER_ON: +#ifdef CONFIG_RTL8188E + DBG_8192C("%s: call customer specific GPIO(%d) to turn on wifi power\n", + __FUNCTION__, sprd_3rdparty_gpio_wifi_power); + if (sprd_3rdparty_gpio_wifi_power != 65535) + gpio_set_value(sprd_3rdparty_gpio_wifi_power, 1); + + DBG_8192C("%s: turn on VDD-WIFI0 3.3V\n", __FUNCTION__); + LDO_TurnOnLDO(LDO_LDO_WIF0); + LDO_SetVoltLevel(LDO_LDO_WIF0,LDO_VOLT_LEVEL1); + +#ifdef CONFIG_WIF1_LDO + DBG_8192C("%s: turn on VDD-WIFI1 1.2V\n", __func__); + LDO_TurnOnLDO(LDO_LDO_WIF1); + LDO_SetVoltLevel(LDO_LDO_WIF1,LDO_VOLT_LEVEL3); +#endif //CONFIG_WIF1_LDO +#endif + break; + + case WLAN_BT_PWDN_OFF: + DBG_8192C("%s: call customer specific GPIO to set bt power down pin to 0\n", + __FUNCTION__); +#if defined(CONFIG_RTL8723B) + if (sprd_3rdparty_gpio_bt_reset > 0) + gpio_set_value(sprd_3rdparty_gpio_bt_reset, 0); +#endif + break; + + case WLAN_BT_PWDN_ON: + DBG_8192C("%s: callc customer specific GPIO to set bt power down pin to 1\n", + __FUNCTION__); +#if defined(CONFIG_RTL8723B) + if (sprd_3rdparty_gpio_bt_reset > 0) + gpio_set_value(sprd_3rdparty_gpio_bt_reset, 1); +#endif + break; + } +} +#endif //ANDROID_2X + +#elif defined(CONFIG_PLATFORM_ARM_RK3066) +#include + +#define GPIO_WIFI_IRQ RK30_PIN2_PC2 +extern unsigned int oob_irq; +int rtw_wifi_gpio_init(void) +{ +#ifdef CONFIG_GSPI_HCI + if (GPIO_WIFI_IRQ > 0) { + rk30_mux_api_set(GPIO2C2_LCDC1DATA18_SMCBLSN1_HSADCDATA5_NAME, GPIO2C_GPIO2C2);//jacky_test + gpio_request(GPIO_WIFI_IRQ, "oob_irq"); + gpio_direction_input(GPIO_WIFI_IRQ); + + oob_irq = gpio_to_irq(GPIO_WIFI_IRQ); + + DBG_8192C("%s oob_irq:%d\n", __func__, oob_irq); + } +#endif + return 0; +} + + +int rtw_wifi_gpio_deinit(void) +{ +#ifdef CONFIG_GSPI_HCI + if (GPIO_WIFI_IRQ > 0) + gpio_free(GPIO_WIFI_IRQ); +#endif + return 0; +} + +void rtw_wifi_gpio_wlan_ctrl(int onoff) +{ +} + +#ifdef CONFIG_GPIO_API +//this is a demo for extending GPIO pin[7] as interrupt mode +struct net_device * rtl_net; +extern int rtw_register_gpio_interrupt(struct net_device *netdev, int gpio_num, void(*callback)(u8 level)); +extern int rtw_disable_gpio_interrupt(struct net_device *netdev, int gpio_num); +void gpio_int(u8 is_high) +{ + DBG_8192C("%s level=%d\n",__func__, is_high); +} +int register_net_gpio_init(void) +{ + rtl_net = dev_get_by_name(&init_net,"wlan0"); + if(!rtl_net) + { + DBG_871X_LEVEL(_drv_always_, "rtl_net init fail!\n"); + return -1; + } + return rtw_register_gpio_interrupt(rtl_net,7, gpio_int); +} +int unregister_net_gpio_init(void) +{ + rtl_net = dev_get_by_name(&init_net,"wlan0"); + if(!rtl_net) + { + DBG_871X_LEVEL(_drv_always_, "rtl_net init fail!\n"); + return -1; + } + return rtw_disable_gpio_interrupt(rtl_net,7); +} +#endif + +#else + +int rtw_wifi_gpio_init(void) +{ + return 0; +} + +void rtw_wifi_gpio_wlan_ctrl(int onoff) +{ +} +#endif //CONFIG_PLATFORM_SPRD diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.c new file mode 100644 index 00000000..48d680c9 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.c @@ -0,0 +1,6871 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _IOCTL_CFG80211_C_ + +#include + +#ifdef CONFIG_IOCTL_CFG80211 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#define STATION_INFO_SIGNAL BIT(NL80211_STA_INFO_SIGNAL) +#define STATION_INFO_TX_BITRATE BIT(NL80211_STA_INFO_TX_BITRATE) +#define STATION_INFO_RX_PACKETS BIT(NL80211_STA_INFO_RX_PACKETS) +#define STATION_INFO_TX_PACKETS BIT(NL80211_STA_INFO_TX_PACKETS) +#define STATION_INFO_ASSOC_REQ_IES 0 +#endif /* Linux kernel >= 4.0.0 */ + +#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 +#define RTW_MAX_NUM_PMKIDS 4 + +#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ + +#ifdef CONFIG_WAPI_SUPPORT + +#ifndef WLAN_CIPHER_SUITE_SMS4 +#define WLAN_CIPHER_SUITE_SMS4 0x00147201 +#endif + +#ifndef WLAN_AKM_SUITE_WAPI_PSK +#define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04 +#endif + +#ifndef WLAN_AKM_SUITE_WAPI_CERT +#define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12 +#endif + +#ifndef NL80211_WAPI_VERSION_1 +#define NL80211_WAPI_VERSION_1 (1 << 2) +#endif + +#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, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +#ifdef CONFIG_WAPI_SUPPORT + WLAN_CIPHER_SUITE_SMS4, +#endif // CONFIG_WAPI_SUPPORT +#ifdef CONFIG_IEEE80211W + WLAN_CIPHER_SUITE_AES_CMAC, +#endif //CONFIG_IEEE80211W +}; + +#define RATETAB_ENT(_rate, _rateid, _flags) \ + { \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ + } + +#define CHAN2G(_channel, _freq, _flags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +#define CHAN5G(_channel, _flags) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = 5000 + (5 * (_channel)), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +/* if wowlan is not supported, kernel generate a disconnect at each suspend + * cf: /net/wireless/sysfs.c, so register a stub wowlan. + * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback. + * (from user space, e.g. iw phy0 wowlan enable) + */ +static const struct wiphy_wowlan_support wowlan_stub = { + .flags = WIPHY_WOWLAN_ANY, + .n_patterns = 0, + .pattern_max_len = 0, + .pattern_min_len = 0, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) + .max_pkt_offset = 0, +#endif +}; +#endif + +static struct ieee80211_rate rtw_rates[] = { + RATETAB_ENT(10, 0x1, 0), + RATETAB_ENT(20, 0x2, 0), + RATETAB_ENT(55, 0x4, 0), + RATETAB_ENT(110, 0x8, 0), + RATETAB_ENT(60, 0x10, 0), + RATETAB_ENT(90, 0x20, 0), + RATETAB_ENT(120, 0x40, 0), + RATETAB_ENT(180, 0x80, 0), + RATETAB_ENT(240, 0x100, 0), + RATETAB_ENT(360, 0x200, 0), + RATETAB_ENT(480, 0x400, 0), + RATETAB_ENT(540, 0x800, 0), +}; + +#define rtw_a_rates (rtw_rates + 4) +#define RTW_A_RATES_NUM 8 +#define rtw_g_rates (rtw_rates + 0) +#define RTW_G_RATES_NUM 12 + +#define RTW_2G_CHANNELS_NUM 14 +#define RTW_5G_CHANNELS_NUM 37 + +static struct ieee80211_channel rtw_2ghz_channels[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0), + CHAN2G(7, 2442, 0), + CHAN2G(8, 2447, 0), + CHAN2G(9, 2452, 0), + CHAN2G(10, 2457, 0), + CHAN2G(11, 2462, 0), + CHAN2G(12, 2467, 0), + CHAN2G(13, 2472, 0), + CHAN2G(14, 2484, 0), +}; + +static struct ieee80211_channel rtw_5ghz_a_channels[] = { + CHAN5G(34, 0), CHAN5G(36, 0), + CHAN5G(38, 0), CHAN5G(40, 0), + CHAN5G(42, 0), CHAN5G(44, 0), + CHAN5G(46, 0), CHAN5G(48, 0), + CHAN5G(52, 0), CHAN5G(56, 0), + CHAN5G(60, 0), CHAN5G(64, 0), + CHAN5G(100, 0), CHAN5G(104, 0), + CHAN5G(108, 0), CHAN5G(112, 0), + CHAN5G(116, 0), CHAN5G(120, 0), + CHAN5G(124, 0), CHAN5G(128, 0), + CHAN5G(132, 0), CHAN5G(136, 0), + CHAN5G(140, 0), CHAN5G(149, 0), + CHAN5G(153, 0), CHAN5G(157, 0), + CHAN5G(161, 0), CHAN5G(165, 0), + CHAN5G(184, 0), CHAN5G(188, 0), + CHAN5G(192, 0), CHAN5G(196, 0), + CHAN5G(200, 0), CHAN5G(204, 0), + CHAN5G(208, 0), CHAN5G(212, 0), + CHAN5G(216, 0), +}; + + +void rtw_2g_channels_init(struct ieee80211_channel *channels) +{ + _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels, + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM + ); +} + +void rtw_5g_channels_init(struct ieee80211_channel *channels) +{ + _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels, + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM + ); +} + +void rtw_2g_rates_init(struct ieee80211_rate *rates) +{ + _rtw_memcpy(rates, rtw_g_rates, + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM + ); +} + +void rtw_5g_rates_init(struct ieee80211_rate *rates) +{ + _rtw_memcpy(rates, rtw_a_rates, + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM + ); +} + +struct ieee80211_supported_band *rtw_spt_band_alloc( + enum ieee80211_band band + ) +{ + struct ieee80211_supported_band *spt_band = NULL; + int n_channels, n_bitrates; + + if(band == IEEE80211_BAND_2GHZ) + { + n_channels = RTW_2G_CHANNELS_NUM; + n_bitrates = RTW_G_RATES_NUM; + } + else if(band == IEEE80211_BAND_5GHZ) + { + n_channels = RTW_5G_CHANNELS_NUM; + n_bitrates = RTW_A_RATES_NUM; + } + else + { + goto exit; + } + + spt_band = (struct ieee80211_supported_band *)rtw_zmalloc( + sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*n_channels + + sizeof(struct ieee80211_rate)*n_bitrates + ); + if(!spt_band) + goto exit; + + spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band)); + spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels); + spt_band->band = band; + spt_band->n_channels = n_channels; + spt_band->n_bitrates = n_bitrates; + + if(band == IEEE80211_BAND_2GHZ) + { + rtw_2g_channels_init(spt_band->channels); + rtw_2g_rates_init(spt_band->bitrates); + } + else if(band == IEEE80211_BAND_5GHZ) + { + rtw_5g_channels_init(spt_band->channels); + rtw_5g_rates_init(spt_band->bitrates); + } + + //spt_band.ht_cap + +exit: + + return spt_band; +} + +void rtw_spt_band_free(struct ieee80211_supported_band *spt_band) +{ + u32 size = 0; + + if(!spt_band) + return; + + if(spt_band->band == IEEE80211_BAND_2GHZ) + { + size = sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM + + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM; + } + else if(spt_band->band == IEEE80211_BAND_5GHZ) + { + size = sizeof(struct ieee80211_supported_band) + + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM + + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM; + } + else + { + + } + rtw_mfree((u8*)spt_band, size); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) +static const struct ieee80211_txrx_stypes +rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4) + }, +}; +#endif + +static u64 rtw_get_systime_us(void) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) + struct timespec ts; + get_monotonic_boottime(&ts); + return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000; +#else + struct timeval tv; + do_gettimeofday(&tv); + return ((u64)tv.tv_sec*1000000) + tv.tv_usec; +#endif +} + +#define MAX_BSSINFO_LEN 1000 +struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork) +{ + struct ieee80211_channel *notify_channel; + struct cfg80211_bss *bss = NULL; + //struct ieee80211_supported_band *band; + u16 channel; + u32 freq; + u64 notify_timestamp; + u16 notify_capability; + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; + s32 notify_signal; + //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; + u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + struct wireless_dev *wdev = padapter->rtw_wdev; + 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 > buf_size){ + DBG_871X("%s IE Length too long > %zu byte \n",__FUNCTION__,buf_size); + goto exit; + } + +#ifndef CONFIG_WAPI_SUPPORT + { + u16 wapi_len = 0; + + if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0) + { + if(wapi_len > 0) + { + DBG_871X("%s, no support wapi!\n",__FUNCTION__); + goto exit; + } + } + } +#endif //!CONFIG_WAPI_SUPPORT + + //To reduce PBC Overlap rate + //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + if(adapter_wdev_data(padapter)->scan_request != NULL) + { + u8 *psr=NULL, sr = 0; + NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid; + struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request; + struct cfg80211_ssid *ssids = request->ssids; + u32 wpsielen=0; + u8 *wpsie=NULL; + + wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen); + + if(wpsie && wpsielen>0) + psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + + if (sr != 0) + { + if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS + { + DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength); + + if (ssids[0].ssid_len == 0) { + } + else if(pssid->SsidLength == ssids[0].ssid_len && + _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len)) + { + DBG_871X("%s, got sr and ssid match!\n", __func__); + } + else + { + if(psr !=NULL) + *psr = 0; //clear sr + +#if 0 + WLAN_BSSID_EX *pselect_network = &pnetwork->network; + struct cfg80211_bss *pselect_bss = NULL; + struct ieee80211_channel *notify_channel = NULL; + u32 freq; + + DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__); + + freq = rtw_ch2freq(pselect_network->Configuration.DSConfig); + notify_channel = ieee80211_get_channel(wiphy, freq); + pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/, + pselect_network->MacAddress, pselect_network->Ssid.Ssid, + pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/, + 0/*WLAN_CAPABILITY_ESS*/); + + if(pselect_bss) + { + DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__); + + cfg80211_unlink_bss(wiphy, pselect_bss); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(wiphy, pselect_bss); +#else + cfg80211_put_bss(pselect_bss); +#endif + + } + + goto exit; +#endif + } + } + } + } + //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + + + channel = pnetwork->network.Configuration.DSConfig; + freq = rtw_ch2freq(channel); + notify_channel = ieee80211_get_channel(wiphy, freq); + + if (0) + notify_timestamp = le64_to_cpu(*(u64*)rtw_get_timestampe_from_ie(pnetwork->network.IEs)); + else + notify_timestamp = rtw_get_systime_us(); + + notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs)); + notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs)); + + notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_; + notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_; + + //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) + if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE && + is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) { + notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm + } else { + notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm + } + + #if 0 + DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress)); + DBG_8192C("Channel: %d(%d)\n", channel, freq); + DBG_8192C("Capability: %X\n", notify_capability); + DBG_8192C("Beacon interval: %d\n", notify_interval); + DBG_8192C("Signal: %d\n", notify_signal); + DBG_8192C("notify_timestamp: %llu\n", notify_timestamp); + #endif + + //pbuf = buf; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf; + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); + //pmlmeext->mgnt_seq++; + + if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON + _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); + SetFrameSubType(pbuf, WIFI_BEACON); + } else { + _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); + SetFrameSubType(pbuf, WIFI_PROBERSP); + } + + _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN); + + + //pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); + len = sizeof (struct rtw_ieee80211_hdr_3addr); + _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)) + //{ + // DBG_8192C("%s, got p2p_ie\n", __func__); + //} + //#endif + +#if 1 + bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf, + len, notify_signal, GFP_ATOMIC); +#else + + bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress, + notify_timestamp, notify_capability, notify_interval, notify_ie, + notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/); +#endif + + if (unlikely(!bss)) { + DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter)); + goto exit; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) +#ifndef COMPAT_KERNEL_RELEASE + //patch for cfg80211, update beacon ies to information_elements + if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON + + if(bss->len_information_elements != bss->len_beacon_ies) + { + bss->information_elements = bss->beacon_ies; + bss->len_information_elements = bss->len_beacon_ies; + } + } +#endif //COMPAT_KERNEL_RELEASE +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) + +/* + { + if( bss->information_elements == bss->proberesp_ies) + { + if( bss->len_information_elements != bss->len_proberesp_ies) + { + DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n"); + } + + } + else if(bss->len_information_elements < bss->len_beacon_ies) + { + bss->information_elements = bss->beacon_ies; + bss->len_information_elements = bss->len_beacon_ies; + } + } +*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(wiphy, bss); +#else + cfg80211_put_bss(bss); +#endif + +exit: + if(pbuf) + rtw_mfree(pbuf, buf_size); + return bss; + +} + +/* + Check the given bss is valid by kernel API cfg80211_get_bss() + @padapter : the given adapter + + return _TRUE if bss is valid, _FALSE for not found. +*/ +int rtw_cfg80211_check_bss(_adapter *padapter) +{ + WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network); + struct cfg80211_bss *bss = NULL; + struct ieee80211_channel *notify_channel = NULL; + u32 freq; + + if (!(pnetwork) || !(padapter->rtw_wdev)) + return _FALSE; + + freq = rtw_ch2freq(pnetwork->Configuration.DSConfig); + notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq); + bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel, + pnetwork->MacAddress, pnetwork->Ssid.Ssid, + pnetwork->Ssid.SsidLength, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss); +#else + cfg80211_put_bss(bss); +#endif + + return (bss!=NULL); +} + +void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + 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 = 2412; + struct ieee80211_channel *notify_channel; +#endif + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig); + + if (0) + DBG_871X("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq); +#endif + + if (pwdev->iftype != NL80211_IFTYPE_ADHOC) + { + return; + } + + if (!rtw_cfg80211_check_bss(padapter)) { + WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network); + struct wlan_network *scanned = pmlmepriv->cur_network_scanned; + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE) + { + + _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX)); + if(cur_network) + { + if (!rtw_cfg80211_inform_bss(padapter,cur_network)) + DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter)); + else + DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); + } + else + { + DBG_871X("cur_network is not exist!!!\n"); + return ; + } + } + else + { + if(scanned == NULL) + rtw_warn_on(1); + + if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE + && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE + ) { + if (!rtw_cfg80211_inform_bss(padapter,scanned)) { + DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter)); + } else { + //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); + } + } else { + DBG_871X("scanned & pnetwork compare fail\n"); + rtw_warn_on(1); + } + } + + if (!rtw_cfg80211_check_bss(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)) + notify_channel = ieee80211_get_channel(wiphy, freq); + cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC); +#else + cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC); +#endif +} + +void rtw_cfg80211_indicate_connect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct wireless_dev *pwdev = padapter->rtw_wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + struct cfg80211_bss *bss = NULL; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + if (pwdev->iftype != NL80211_IFTYPE_STATION + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT + #endif + ) { + return; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return; + +#ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + } +#endif //CONFIG_P2P + + if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) { + WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network); + struct wlan_network *scanned = pmlmepriv->cur_network_scanned; + + //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); + + if(scanned == NULL) { + rtw_warn_on(1); + goto check_bss; + } + + if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE + && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE + ) { + if (!rtw_cfg80211_inform_bss(padapter,scanned)) { + DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter)); + } else { + //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); + } + } else { + DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n", + scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress), + pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress) + ); + rtw_warn_on(1); + } + } + +check_bss: + if (!rtw_cfg80211_check_bss(padapter)) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter)); + + if (rtw_to_roam(padapter) > 0) { + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) + struct wiphy *wiphy = pwdev->wiphy; + struct ieee80211_channel *notify_channel; + u32 freq; + u16 channel = cur_network->network.Configuration.DSConfig; + + freq = rtw_ch2freq(channel); + notify_channel = ieee80211_get_channel(wiphy, freq); + #endif + + DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter)); + cfg80211_roamed(padapter->pnetdev + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) + , notify_channel + #endif + , 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 + , GFP_ATOMIC); + } + else + { + #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 + 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) + DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); + #endif + } +} + +void rtw_cfg80211_indicate_disconnect(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wireless_dev *pwdev = padapter->rtw_wdev; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + + if (pwdev->iftype != NL80211_IFTYPE_STATION + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT + #endif + ) { + return; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + return; + +#ifdef CONFIG_P2P + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + if (pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT) + #endif + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + } +#endif //CONFIG_P2P + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + if (!padapter->mlmepriv.not_indic_disco || padapter->ndev_unregistering) { + #else + { + #endif + #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) + cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/); + else if(pwdev->sme_state==CFG80211_SME_CONNECTED) + cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC); + //else + //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state); + + DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state); + #else + + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + DBG_871X(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter)); + cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC); + } else { + DBG_871X(FUNC_ADPT_FMT" call cfg80211_connect_result\n", FUNC_ADPT_ARG(padapter)); + cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC); + } + #endif + } +} + + +#ifdef CONFIG_AP_MODE +static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + struct sta_info *psta = NULL, *pbcmc_sta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_8192C("%s\n", __FUNCTION__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + //sizeof(struct ieee_param) = 64 bytes; + //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif /* CONFIG_IEEE80211W */ + ) + { + ret = -EINVAL; + goto exit; + } + } + else + { + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(!psta) + { + //ret = -EINVAL; + DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n"); + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL)) + { + //todo:clear default encryption keys + + DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx); + + goto exit; + } + + + if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL)) + { + DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len); + + if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0)) + { + ret = -EINVAL; + goto exit; + } + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + } + + if (psecuritypriv->bWepDefaultKeyIdxSet == 0) + { + //wep default key has not been set, so use this key index as default key. + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + psecuritypriv->dot118021XGrpPrivacy=_WEP40_; + + if(wep_key_len == 13) + { + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + psecuritypriv->dot118021XGrpPrivacy=_WEP104_; + } + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len; + + rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1); + + goto exit; + + } + + + if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key + { + if(param->u.crypt.set_tx == 0) //group key + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__); + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } +#ifdef CONFIG_IEEE80211W + else if (strcmp(param->u.crypt.alg, "BIP") == 0) { + int no; + + DBG_871X("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx); + /* save the IGTK key, length 16 bytes */ + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16:param->u.crypt.key_len)); + /* DBG_871X("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + DBG_871X("\n"); */ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + goto exit; + } +#endif /* CONFIG_IEEE80211W */ + else + { + DBG_8192C("%s, set group_key, none\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + goto exit; + + } + + if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x + { + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + if(param->u.crypt.set_tx ==1) //pairwise key + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psta->dot118021XPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _TKIP_; + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + + DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _AES_; + } + else + { + DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__); + + psta->dot118021XPrivacy = _NO_PRIVACY_; + } + + rtw_ap_set_pairwise_key(padapter, psta); + + psta->ieee8021x_blocked = _FALSE; + + psta->bpairwise_key_installed = _TRUE; + + } + else//group key??? + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + } + + } + +exit: + + return ret; + +} +#endif + +static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + +_func_enter_; + + DBG_8192C("%s\n", __func__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif //CONFIG_IEEE80211W + ) + { + ret = -EINVAL; + goto exit; + } + } else { +#ifdef CONFIG_WAPI_SUPPORT + if (strcmp(param->u.crypt.alg, "SMS4")) +#endif + { + ret = -EINVAL; + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "WEP") == 0) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n")); + DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) + { + ret = -EINVAL; + goto exit; + } + + if (psecuritypriv->bWepDefaultKeyIdxSet == 0) + { + //wep default key has not been set, so use this key index as default key. + + wep_key_len = wep_key_len <= 5 ? 5 : 13; + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + + if(wep_key_len==13) + { + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len; + + rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE); + + goto exit; + } + + if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x + { + struct sta_info * psta,*pbcmc_sta; + struct sta_priv * pstapriv = &padapter->stapriv; + + //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__); + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode + { + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + DBG_8192C("%s, : Obtain Sta_info fail \n", __func__); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + psta->ieee8021x_blocked = _FALSE; + + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + + if(param->u.crypt.set_tx ==1)//pairwise key + { + + DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__); + + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key + { + //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + padapter->securitypriv.busetkipkey=_FALSE; + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + } + psta->bpairwise_key_installed = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:unicastkey\n"); + + rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE); + } + else//group key + { + if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); + _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); + padapter->securitypriv.binstallGrpkey = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:groupkey\n"); + + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE); + } +#ifdef CONFIG_IEEE80211W + else if(strcmp(param->u.crypt.alg, "BIP") == 0) + { + int no; + //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); + //save the IGTK key, length 16 bytes + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + /*DBG_871X("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + DBG_871X("\n");*/ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + } +#endif //CONFIG_IEEE80211W + +#ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); + } + } +#endif //CONFIG_P2P + + } + } + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta==NULL) + { + //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + pbcmc_sta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + } + } + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode + { + } + } + +#ifdef CONFIG_WAPI_SUPPORT + if (strcmp(param->u.crypt.alg, "SMS4") == 0) + { + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + PRT_WAPI_STA_INFO pWapiSta; + u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + + if(param->u.crypt.set_tx == 1) + { + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6)) + { + _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16); + + pWapiSta->wapiUsk.bSet = true; + _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16); + _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16); + pWapiSta->wapiUsk.keyId = param->u.crypt.idx ; + pWapiSta->wapiUsk.bTxEnable = true; + + _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16); + pWapiSta->wapiUskUpdate.bTxEnable = false; + pWapiSta->wapiUskUpdate.bSet = false; + + if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false) + { + //set unicast key for ASUE + rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false); + } + } + } + } + else + { + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6)) + { + pWapiSta->wapiMsk.bSet = true; + _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16); + _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16); + pWapiSta->wapiMsk.keyId = param->u.crypt.idx ; + pWapiSta->wapiMsk.bTxEnable = false; + if(!pWapiSta->bSetkeyOk) + pWapiSta->bSetkeyOk = true; + pWapiSta->bAuthenticateInProgress = false; + + _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16); + + if (psecuritypriv->sw_decrypt == false) + { + //set rx broadcast key for ASUE + rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false); + } + } + + } + } + } +#endif + + +exit: + + DBG_8192C("%s, ret=%d\n", __func__, ret); + + _func_exit_; + + return ret; +} + +static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr, +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr, +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + struct key_params *params) +{ + char *alg_name; + u32 param_len; + struct ieee_param *param = NULL; + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct wireless_dev *rtw_wdev = padapter->rtw_wdev; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_TDLS + struct sta_info *ptdls_sta; +#endif /* CONFIG_TDLS */ + + DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr); + DBG_871X("cipher=0x%x\n", params->cipher); + DBG_871X("key_len=0x%x\n", params->key_len); + DBG_871X("seq_len=0x%x\n", params->seq_len); + DBG_871X("key_index=%d\n", key_index); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + DBG_871X("pairwise=%d\n", pairwise); +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + + param_len = sizeof(struct ieee_param) + params->key_len; + param = (struct ieee_param *)rtw_malloc(param_len); + if (param == NULL) + return -1; + + _rtw_memset(param, 0, param_len); + + param->cmd = IEEE_CMD_SET_ENCRYPTION; + _rtw_memset(param->sta_addr, 0xff, ETH_ALEN); + + switch (params->cipher) { + case IW_AUTH_CIPHER_NONE: + //todo: remove key + //remove = 1; + alg_name = "none"; + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + alg_name = "WEP"; + break; + case WLAN_CIPHER_SUITE_TKIP: + alg_name = "TKIP"; + break; + case WLAN_CIPHER_SUITE_CCMP: + alg_name = "CCMP"; + break; +#ifdef CONFIG_IEEE80211W + case WLAN_CIPHER_SUITE_AES_CMAC: + alg_name = "BIP"; + break; +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_WAPI_SUPPORT + case WLAN_CIPHER_SUITE_SMS4: + alg_name= "SMS4"; + if(pairwise == NL80211_KEYTYPE_PAIRWISE) { + if (key_index != 0 && key_index != 1) { + ret = -ENOTSUPP; + goto addkey_end; + } + _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN); + } else { + DBG_871X("mac_addr is null \n"); + } + DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n"); + break; +#endif + + default: + ret = -ENOTSUPP; + goto addkey_end; + } + + strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); + + + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) + { + param->u.crypt.set_tx = 0; //for wpa/wpa2 group key + } else { + param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key + } + + + //param->u.crypt.idx = key_index - 1; + param->u.crypt.idx = key_index; + + if (params->seq_len && params->seq) + { + _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, (u8 *)params->key, params->key_len); + } + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { +#ifdef CONFIG_TDLS + if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) { + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr); + if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) { + _rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len); + rtw_tdls_set_key(padapter, ptdls_sta); + goto addkey_end; + } + } +#endif /* CONFIG_TDLS */ + + ret = rtw_cfg80211_set_encryption(ndev, param, param_len); + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_AP_MODE + if(mac_addr) + _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN); + + ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len); +#endif + } + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE + || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + //DBG_8192C("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); + ret = rtw_cfg80211_set_encryption(ndev, param, param_len); + } + else + { + DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); + + } + +addkey_end: + if(param) + { + rtw_mfree((u8*)param, param_len); + } + + return ret; + +} + +static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr, +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr, +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + void *cookie, + void (*callback)(void *cookie, + struct key_params*)) +{ +#if 0 + struct iwm_priv *iwm = ndev_to_iwm(ndev); + struct iwm_key *key = &iwm->keys[key_index]; + struct key_params params; + + IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index); + + memset(¶ms, 0, sizeof(params)); + + params.cipher = key->cipher; + params.key_len = key->key_len; + params.seq_len = key->seq_len; + params.seq = key->seq; + params.key = key->key; + + callback(cookie, ¶ms); + + return key->key_len ? 0 : -ENOENT; +#endif + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + u8 key_index, bool pairwise, const u8 *mac_addr) +#else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + u8 key_index, const u8 *mac_addr) +#endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index); + + if (key_index == psecuritypriv->dot11PrivacyKeyIndex) + { + //clear the flag of wep default key set. + psecuritypriv->bWepDefaultKeyIdxSet = 0; + } + + return 0; +} + +static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, u8 key_index + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + , bool unicast, bool multicast + #endif + ) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + +#define SET_DEF_KEY_PARAM_FMT " key_index=%d" +#define SET_DEF_KEY_PARAM_ARG , key_index +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE) + #define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d" + #define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast +#else + #define SET_DEF_KEY_PARAM_FMT_2_6_38 "" + #define SET_DEF_KEY_PARAM_ARG_2_6_38 +#endif + + DBG_871X(FUNC_NDEV_FMT + SET_DEF_KEY_PARAM_FMT + SET_DEF_KEY_PARAM_FMT_2_6_38 + "\n", FUNC_NDEV_ARG(ndev) + SET_DEF_KEY_PARAM_ARG + SET_DEF_KEY_PARAM_ARG_2_6_38 + ); + + if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key + { + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + + psecuritypriv->dot11PrivacyKeyIndex = key_index; + + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if (psecuritypriv->dot11DefKeylen[key_index] == 13) + { + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set + } + + return 0; + +} +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)) +static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_gtk_rekey_data *data) +{ + /*int i;*/ + struct sta_info *psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *psecuritypriv = &(padapter->securitypriv); + + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + DBG_871X("%s, : Obtain Sta_info fail\n", __func__); + return -1; + } + + _rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN); + /*printk("\ncfg80211_rtw_set_rekey_data KEK:"); + for(i=0;ikek[i]);*/ + _rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN); + /*printk("\ncfg80211_rtw_set_rekey_data KCK:"); + for(i=0;ikck[i]);*/ + _rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN); + psecuritypriv->binstallKCK_KEK = _TRUE; + /*printk("\nREPLAY_CTR: "); + for(i=0;ireplay_ctr[i]);*/ + + return 0; +} +#endif /*CONFIG_GTK_OL*/ +static int cfg80211_rtw_get_station(struct wiphy *wiphy, + 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); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + + sinfo->filled = 0; + + if (!mac) { + DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac); + ret = -ENOENT; + goto exit; + } + + psta = rtw_get_stainfo(pstapriv, (u8 *)mac); + if (psta == NULL) { + DBG_8192C("%s, sta_info is null\n", __func__); + ret = -ENOENT; + goto exit; + } + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac)); +#endif + + //for infra./P2PClient mode + if( check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED) + ) + { + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + + 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; + } + + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); + + sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); + + sinfo->filled |= STATION_INFO_RX_PACKETS; + sinfo->rx_packets = sta_rx_data_pkts(psta); + + sinfo->filled |= STATION_INFO_TX_PACKETS; + sinfo->tx_packets = psta->sta_stats.tx_pkts; + + } + + //for Ad-Hoc/AP mode + if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) + ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) + ||check_fwstate(pmlmepriv, WIFI_AP_STATE)) + && check_fwstate(pmlmepriv, _FW_LINKED) + ) + { + //TODO: should acquire station info... + } + +exit: + return ret; +} + +extern int netdev_open(struct net_device *pnetdev); +#ifdef CONFIG_CONCURRENT_MODE +extern int netdev_if2_open(struct net_device *pnetdev); +#endif + +/* +enum nl80211_iftype { + NL80211_IFTYPE_UNSPECIFIED, + NL80211_IFTYPE_ADHOC, //1 + NL80211_IFTYPE_STATION, //2 + NL80211_IFTYPE_AP, //3 + NL80211_IFTYPE_AP_VLAN, + NL80211_IFTYPE_WDS, + NL80211_IFTYPE_MONITOR, //6 + NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, //8 + NL80211_IFTYPE_P2P_GO, //9 + //keep last + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; +*/ +static int cfg80211_rtw_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + enum nl80211_iftype old_type; + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct wireless_dev *rtw_wdev = padapter->rtw_wdev; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif + int ret = 0; + u8 change = _FALSE; + + DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type); + + if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) + { + ret= -EPERM; + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type == SECONDARY_ADAPTER) + { + DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev)); + if(netdev_if2_open(ndev) != 0) { + DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev)); + ret= -EPERM; + goto exit; + } + } + else if(padapter->adapter_type == PRIMARY_ADAPTER) +#endif //CONFIG_CONCURRENT_MODE + { + DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev)); + if(netdev_open(ndev) != 0) { + DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev)); + ret= -EPERM; + goto exit; + } + } + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev)); + ret= -EPERM; + goto exit; + } + + old_type = rtw_wdev->iftype; + DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n", + FUNC_NDEV_ARG(ndev), old_type, type); + + if(old_type != type) + { + change = _TRUE; + pmlmeext->action_public_rxseq = 0xffff; + pmlmeext->action_public_dialog_token = 0xff; + } + + /* initial default type */ + ndev->type = ARPHRD_ETHER; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + networkType = Ndis802_11IBSS; + break; +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_CLIENT: +#endif + case NL80211_IFTYPE_STATION: + networkType = Ndis802_11Infrastructure; + #ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + //it means remove GO and change mode from AP(GO) to station(P2P DEVICE) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); + + DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo)); + } + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + if (type == NL80211_IFTYPE_P2P_CLIENT) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT); + else { + /* NL80211_IFTYPE_STATION */ + if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE); + } + #endif + } + #endif //CONFIG_P2P + break; +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_AP: + networkType = Ndis802_11APMode; + #ifdef CONFIG_P2P + if(pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO) + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + } + } + #endif //CONFIG_P2P + break; + case NL80211_IFTYPE_MONITOR: + networkType = Ndis802_11Monitor; +#if 0 + ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */ +#endif + ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */ + break; + default: + ret = -EOPNOTSUPP; + goto exit; + } + + rtw_wdev->iftype = type; + + if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE) + { + rtw_wdev->iftype = old_type; + ret = -EPERM; + goto exit; + } + + rtw_setopmode_cmd(padapter, networkType, _TRUE); + +exit: + + DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret); + return ret; +} + +void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted) +{ + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + _irqL irqL; + + _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + if (pwdev_priv->scan_request != NULL) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s with scan req\n", __FUNCTION__); + #endif + + /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */ + if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy) + { + DBG_8192C("error wiphy compare\n"); + } + else + { + cfg80211_scan_done(pwdev_priv->scan_request, aborted); + } + + pwdev_priv->scan_request = NULL; + } else { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s without scan req\n", __FUNCTION__); + #endif + } + _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); +} + +u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms) +{ + struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter); + u8 empty = _FALSE; + u32 start; + u32 pass_ms; + + start = rtw_get_current_time(); + + while (rtw_get_passing_time_ms(start) <= timeout_ms) { + + if (RTW_CANNOT_RUN(adapter)) + break; + + if (!wdev_priv->scan_request) { + empty = _TRUE; + break; + } + + rtw_msleep_os(10); + } + + pass_ms = rtw_get_passing_time_ms(start); + + if (empty == _FALSE && pass_ms > timeout_ms) + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pass_ms:%u, timeout\n" + , FUNC_ADPT_ARG(adapter), pass_ms); + + return pass_ms; +} + +void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork) +{ + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct wiphy *wiphy = pwdev->wiphy; + struct cfg80211_bss *bss = NULL; + WLAN_BSSID_EX select_network = pnetwork->network; + + bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/, + select_network.MacAddress, select_network.Ssid.Ssid, + select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/, + 0/*WLAN_CAPABILITY_ESS*/); + + if (bss) { + cfg80211_unlink_bss(wiphy, bss); + DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid ); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss); +#else + cfg80211_put_bss(bss); +#endif + } + return; +} + +void rtw_cfg80211_surveydone_event_callback(_adapter *padapter) +{ + _irqL irqL; + _list *plist, *phead; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u32 cnt=0; + u32 wait_for_surveydone; + sint wait_status; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s\n", __func__); +#endif + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //report network only if the current channel set contains the channel to which this network belongs + if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 + && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE + && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) + ) + { + //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); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); +} + +static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen); + #endif + + if(pmlmepriv->wps_probe_req_ie) + { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_probe_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_req_ie_len = wps_ielen; + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + struct wifidirect_info *wdinfo = &padapter->wdinfo; + u32 attr_contentlen = 0; + u8 listen_ch_attr[5]; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen); + #endif + + if(pmlmepriv->p2p_probe_req_ie) + { + u32 free_len = pmlmepriv->p2p_probe_req_ie_len; + pmlmepriv->p2p_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len); + pmlmepriv->p2p_probe_req_ie = NULL; + } + + pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_probe_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_req_ie_len = p2p_ielen; + + if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen) + && attr_contentlen == 5) + { + if (wdinfo->listen_channel != listen_ch_attr[4]) { + DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n", + FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2], + listen_ch_attr[3], listen_ch_attr[4]); + wdinfo->listen_channel = listen_ch_attr[4]; + } + } + } + #endif //CONFIG_P2P + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + } + #endif /* CONFIG_WFD */ + } + + return ret; + +} + +static int cfg80211_rtw_scan(struct wiphy *wiphy + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) + , struct net_device *ndev + #endif + , struct cfg80211_scan_request *request) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(request->wdev); +#endif + int i; + u8 _status = _FALSE; + int ret = 0; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT]; + _irqL irqL; + u8 *wps_ie=NULL; + uint wps_ielen=0; + u8 *p2p_ie=NULL; + uint p2p_ielen=0; + u8 survey_times=3; + u8 survey_times_for_one_ch=6; + struct cfg80211_ssid *ssids = request->ssids; + int social_channel = 0, j = 0; + bool need_indicate_scan_done = _FALSE; + bool ps_denied = _FALSE; + + _adapter *padapter; + struct rtw_wdev_priv *pwdev_priv; + struct mlme_priv *pmlmepriv; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo; +#endif //CONFIG_P2P +#ifdef CONFIG_CONCURRENT_MODE + PADAPTER pbuddy_adapter = NULL; + struct mlme_priv *pbuddy_mlmepriv = NULL; +#endif //CONFIG_CONCURRENT_MODE + + if (ndev == NULL) { + ret = -EINVAL; + goto exit; + } + + padapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(padapter); + pmlmepriv= &padapter->mlmepriv; +#ifdef CONFIG_P2P + pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + +//#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); +//#endif + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) { + pbuddy_adapter = padapter->pbuddy_adapter; + pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); + } +#endif //CONFIG_CONCURRENT_MODE + +#ifdef CONFIG_MP_INCLUDED +if (padapter->registrypriv.mp_mode == 1) +{ + DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter)); + ret = -EPERM; + goto exit; +} +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) { + if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1) + { + DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter)); + ret = -EPERM; + goto exit; + } + } +#endif //CONFIG_CONCURRENT_MODE +#endif + + _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + pwdev_priv->scan_request = request; + _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + + if (adapter_wdev_data(padapter)->block_scan == _TRUE) { + DBG_871X(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter)); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__); +#endif + + if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + DBG_8192C("AP mode process WPS \n"); + } + + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + } + + rtw_ps_deny(padapter, PS_DENY_SCAN); + ps_denied = _TRUE; + if(_FAIL == rtw_pwr_wakeup(padapter)) { + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + + #ifdef CONFIG_P2P + if( pwdinfo->driver_interface == DRIVER_CFG80211 ) + { + if(ssids->ssid != NULL + && _rtw_memcmp(ssids->ssid, "DIRECT-", 7) + && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL) + ) + { + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + adapter_wdev_data(padapter)->p2p_enabled = _TRUE; + } + else + { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); + #endif + } + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + if(request->n_channels == 3 && + request->channels[0]->hw_value == 1 && + request->channels[1]->hw_value == 6 && + request->channels[2]->hw_value == 11 + ) + { + social_channel = 1; + } + } + } + #endif //CONFIG_P2P + + if(request->ie && request->ie_len>0) + { + rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len ); + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state); + ret = -EBUSY; + goto check_need_indicate_scan_done; + } + + if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) + { +#if 1 // Miracast can't do AP scan + static u32 lastscantime = 0; + u32 passtime; + + passtime = rtw_get_passing_time_ms(lastscantime); + lastscantime = rtw_get_current_time(); + if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) +#endif + { + DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + } + + if (rtw_is_scan_deny(padapter)){ + DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter)); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + +#ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) + { +#if 1 // Miracast can't do AP scan + static u32 buddylastscantime = 0; + u32 passtime; + + passtime = rtw_get_passing_time_ms(buddylastscantime); + buddylastscantime = rtw_get_current_time(); + if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) +//#ifdef CONFIG_P2P +// ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) +//#endif //CONFIG_P2P + ) +#endif + { + DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + } + } + + if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) { + DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state); + need_indicate_scan_done = _TRUE; + goto check_need_indicate_scan_done; + + } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) { + bool scan_via_buddy = _FALSE; + struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter); + + _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + if (buddy_wdev_priv->scan_request) { + DBG_871X("scan via buddy\n"); + pmlmepriv->scanning_via_buddy_intf = _TRUE; + _enter_critical_bh(&pmlmepriv->lock, &irqL); + set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + _exit_critical_bh(&pmlmepriv->lock, &irqL); + scan_via_buddy = _TRUE; + } + _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL); + _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL); + + if (scan_via_buddy == _FALSE) + need_indicate_scan_done = _TRUE; + + goto check_need_indicate_scan_done; + } +#endif /* CONFIG_CONCURRENT_MODE */ + +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_free_network_queue(padapter, _TRUE); + + if(social_channel == 0) + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + else + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST); + } +#endif //CONFIG_P2P + + + _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT); + //parsing request ssids, n_ssids + for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len); + #endif + _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len); + ssid[i].SsidLength = ssids[i].ssid_len; + } + + /* parsing channels, n_channels */ + _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT); + for (i=0;in_channels && ichannels[i])); + #endif + ch[i].hw_value = request->channels[i]->hw_value; + ch[i].flags = request->channels[i]->flags; + } + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + if (request->n_channels == 1) { + for(i=1;in_channels <= 4) { + for(j=request->n_channels-1;j>=0;j--) + for(i=0;in_channels); + } else { + _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0); + } + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + + if(_status == _FALSE) + { + ret = -1; + } + +check_need_indicate_scan_done: + if (_TRUE == need_indicate_scan_done) + { + rtw_cfg80211_surveydone_event_callback(padapter); + rtw_cfg80211_indicate_scan_done(padapter, _FALSE); + } + +cancel_ps_deny: + if (ps_denied == _TRUE) + rtw_ps_deny_cancel(padapter, PS_DENY_SCAN); + +exit: + return ret; + +} + +static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + + if (changed & WIPHY_PARAM_RTS_THRESHOLD && + (iwm->conf.rts_threshold != wiphy->rts_threshold)) { + int ret; + + iwm->conf.rts_threshold = wiphy->rts_threshold; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, + CFG_RTS_THRESHOLD, + iwm->conf.rts_threshold); + if (ret < 0) + return ret; + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD && + (iwm->conf.frag_threshold != wiphy->frag_threshold)) { + int ret; + + iwm->conf.frag_threshold = wiphy->frag_threshold; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX, + CFG_FRAG_THRESHOLD, + iwm->conf.frag_threshold); + if (ret < 0) + return ret; + } +#endif + DBG_8192C("%s\n", __func__); + return 0; +} + + + +static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version) +{ + DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version); + + if (!wpa_version) { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + return 0; + } + + + if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) + { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK; + } + +/* + if (wpa_version & NL80211_WPA_VERSION_2) + { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; + } +*/ + + #ifdef CONFIG_WAPI_SUPPORT + if (wpa_version & NL80211_WAPI_VERSION_1) + { + psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI; + } + #endif + + return 0; + +} + +static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv, + enum nl80211_auth_type sme_auth_type) +{ + DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type); + + + switch (sme_auth_type) { + case NL80211_AUTHTYPE_AUTOMATIC: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + + break; + case NL80211_AUTHTYPE_OPEN_SYSTEM: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; + + if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA) + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + +#ifdef CONFIG_WAPI_SUPPORT + if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI) + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI; +#endif + + break; + case NL80211_AUTHTYPE_SHARED_KEY: + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + + + break; + default: + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; + //return -ENOTSUPP; + } + + return 0; + +} + +static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast) +{ + u32 ndisencryptstatus = Ndis802_11EncryptionDisabled; + + u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm : + &psecuritypriv->dot118021XGrpPrivacy; + + DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher); + + + if (!cipher) { + *profile_cipher = _NO_PRIVACY_; + psecuritypriv->ndisencryptstatus = ndisencryptstatus; + return 0; + } + + switch (cipher) { + case IW_AUTH_CIPHER_NONE: + *profile_cipher = _NO_PRIVACY_; + ndisencryptstatus = Ndis802_11EncryptionDisabled; +#ifdef CONFIG_WAPI_SUPPORT + if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ ) + { + *profile_cipher = _SMS4_; + } +#endif + break; + case WLAN_CIPHER_SUITE_WEP40: + *profile_cipher = _WEP40_; + ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WLAN_CIPHER_SUITE_WEP104: + *profile_cipher = _WEP104_; + ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WLAN_CIPHER_SUITE_TKIP: + *profile_cipher = _TKIP_; + ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WLAN_CIPHER_SUITE_CCMP: + *profile_cipher = _AES_; + ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; +#ifdef CONFIG_WAPI_SUPPORT + case WLAN_CIPHER_SUITE_SMS4: + *profile_cipher = _SMS4_; + ndisencryptstatus = Ndis802_11_EncrypteionWAPI; + break; +#endif + default: + DBG_8192C("Unsupported cipher: 0x%x\n", cipher); + return -ENOTSUPP; + } + + if(ucast) + { + psecuritypriv->ndisencryptstatus = ndisencryptstatus; + + //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_) + // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; + } + + return 0; +} + +static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt) +{ + DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt); + + if (key_mgt == WLAN_AKM_SUITE_8021X) + //*auth_type = UMAC_AUTH_TYPE_8021X; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + else if (key_mgt == WLAN_AKM_SUITE_PSK) { + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; + } +#ifdef CONFIG_WAPI_SUPPORT + else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){ + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI; + } + else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){ + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI; + } +#endif + + + else { + DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt); + //return -EINVAL; + } + + return 0; +} + +static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) +{ + u8 *buf=NULL, *pos=NULL; + u32 left; + int group_cipher = 0, pairwise_cipher = 0; + int ret = 0; + int wpa_ielen=0; + int wpa2_ielen=0; + u8 *pwpa, *pwpa2; + u8 null_addr[]= {0,0,0,0,0,0}; + + if (pie == NULL || !ielen) { + /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */ + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + goto exit; + } + + if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) { + ret = -EINVAL; + goto exit; + } + + buf = rtw_zmalloc(ielen); + if (buf == NULL){ + ret = -ENOMEM; + goto exit; + } + + _rtw_memcpy(buf, pie , ielen); + + //dump + { + int i; + DBG_8192C("set wpa_ie(length:%zu):\n", ielen); + for(i=0;i0) + { + if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2); + + DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen); + } + } + + pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen); + if(pwpa2 && wpa2_ielen>0) + { + if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2); + + DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen); + } + } + + if (group_cipher == 0) + { + group_cipher = WPA_CIPHER_NONE; + } + if (pairwise_cipher == 0) + { + pairwise_cipher = WPA_CIPHER_NONE; + } + + switch(group_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot118021XGrpPrivacy=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot11PrivacyAlgrthm=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + {/* handle wps_ie */ + uint wps_ielen; + u8 *wps_ie; + + wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen); + if (wps_ie && wps_ielen > 0) { + DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen); + padapter->securitypriv.wps_ie_len = wps_ielensecuritypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len); + set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); + } else { + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + } + } + + #ifdef CONFIG_P2P + {//check p2p_ie for assoc req; + uint p2p_ielen=0; + u8 *p2p_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen); + #endif + + if(pmlmepriv->p2p_assoc_req_ie) + { + u32 free_len = pmlmepriv->p2p_assoc_req_ie_len; + pmlmepriv->p2p_assoc_req_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len); + pmlmepriv->p2p_assoc_req_ie = NULL; + } + + pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_assoc_req_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + goto exit; + } + _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen; + } + } + #endif //CONFIG_P2P + + #ifdef CONFIG_WFD + { + uint wfd_ielen=0; + u8 *wfd_ie; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + wfd_ie = rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS) + goto exit; + } + } + #endif /* CONFIG_WFD */ + + //TKIP and AES disallow multicast packets until installing group key + if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) + //WPS open need to enable multicast + //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) + rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n", + pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + +exit: + if (buf) + rtw_mfree(buf, ielen); + if (ret) + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + return ret; +} + +static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ibss_params *params) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + NDIS_802_11_SSID ndis_ssid; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + struct cfg80211_chan_def *pch_def; +#endif + struct ieee80211_channel *pch; + int ret=0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + pch_def = (struct cfg80211_chan_def *)(¶ms->chandef); + pch = (struct ieee80211_channel *) pch_def->chan; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) + pch = (struct ieee80211_channel *)(params->channel); +#endif + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + ret = -EPERM; + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) { + DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__); + ret = -EINVAL; + goto exit; + } + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) { + rtw_scan_abort(padapter->pbuddy_adapter); + } +#endif //CONFIG_CONCURRENT_MODE + + if (!params->ssid || !params->ssid_len) + { + ret = -EINVAL; + goto exit; + } + + if (params->ssid_len > IW_ESSID_MAX_SIZE){ + + ret= -E2BIG; + goto exit; + } + + _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); + ndis_ssid.SsidLength = 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); + + psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + + ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM); + rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype); + + DBG_871X("%s: center_freq = %d\n", __func__, pch->center_freq); + pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq); + + if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) + { + ret = -1; + goto exit; + } + +exit: + return ret; +} + +static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct wireless_dev *rtw_wdev = padapter->rtw_wdev; + enum nl80211_iftype old_type; + int ret = 0; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _TRUE; + #endif + + old_type = rtw_wdev->iftype; + + rtw_set_to_roam(padapter, 0); + + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + rtw_scan_abort(padapter); + LeaveAllPowerSaveMode(padapter); + + rtw_wdev->iftype = NL80211_IFTYPE_STATION; + + if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE) + { + rtw_wdev->iftype = old_type; + ret = -EPERM; + goto leave_ibss; + } + rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE); + } + +leave_ibss: + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _FALSE; + #endif + + return 0; +} + +static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_connect_params *sme) +{ + int ret=0; + _irqL irqL; + _list *phead; + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + NDIS_802_11_SSID ndis_ssid; + u8 *dst_ssid, *src_ssid; + u8 *dst_bssid, *src_bssid; + //u8 matched_by_bssid=_FALSE; + //u8 matched_by_ssid=_FALSE; + u8 matched=_FALSE; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + _queue *queue = &pmlmepriv->scanned_queue; + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _TRUE; + #endif + + DBG_871X("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev)); + DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n", + sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type); + + + if(adapter_wdev_data(padapter)->block == _TRUE) + { + ret = -EBUSY; + DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__); + goto exit; + } + +#ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT + printk("MStar Android!\n"); + if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE) + { +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) +#endif //CONFIG_P2P + { + ret = -EBUSY; + printk("Android hasn't attached yet!\n"); + goto exit; + } + } +#endif + + rtw_ps_deny(padapter, PS_DENY_JOIN); + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + ret = -EPERM; + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) { + DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__); + ret = -EINVAL; + goto exit; + } + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) { + rtw_scan_abort(padapter->pbuddy_adapter); + } +#endif + + if (!sme->ssid || !sme->ssid_len) + { + ret = -EINVAL; + goto exit; + } + + if (sme->ssid_len > IW_ESSID_MAX_SIZE){ + + ret= -E2BIG; + goto exit; + } + + _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); + ndis_ssid.SsidLength = 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); + + + if (sme->bssid) + DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid)); + + + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + ret = -EBUSY; + DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state); + goto exit; + } + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + rtw_scan_abort(padapter); + } + + psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + +#ifdef CONFIG_WAPI_SUPPORT + padapter->wapiInfo.bWapiEnable = false; +#endif + + ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions); + if (ret < 0) + goto exit; + +#ifdef CONFIG_WAPI_SUPPORT + if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) + { + padapter->wapiInfo.bWapiEnable = true; + padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN; + padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN; + } +#endif + + ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type); + +#ifdef CONFIG_WAPI_SUPPORT + if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI) + padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm; +#endif + + + if (ret < 0) + goto exit; + + DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len); + + ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len); + if (ret < 0) + goto exit; + + if (sme->crypto.n_ciphers_pairwise) { + ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE); + if (ret < 0) + goto exit; + } + + //For WEP Shared auth + if (sme->key_len > 0 && sme->key) + { + u32 wep_key_idx, wep_key_len,wep_total_len; + NDIS_802_11_WEP *pwep = NULL; + DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__); + + wep_key_idx = sme->key_idx; + wep_key_len = sme->key_len; + + if (sme->key_idx > WEP_KEYS) { + ret = -EINVAL; + goto exit; + } + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len); + if(pwep == NULL){ + DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n"); + ret = -ENOMEM; + goto exit; + } + + _rtw_memset(pwep, 0, wep_total_len); + + pwep->KeyLength = wep_key_len; + pwep->Length = wep_total_len; + + if(wep_key_len==13) + { + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + } + } + else { + ret = -EINVAL; + goto exit; + } + + pwep->KeyIndex = wep_key_idx; + pwep->KeyIndex |= 0x80000000; + + _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength); + + if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL) + { + ret = -EOPNOTSUPP ; + } + + if (pwep) { + rtw_mfree((u8 *)pwep,wep_total_len); + } + + if(ret < 0) + goto exit; + } + + ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE); + if (ret < 0) + return ret; + + if (sme->crypto.n_akm_suites) { + ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]); + if (ret < 0) + goto exit; + } + +#ifdef CONFIG_WAPI_SUPPORT + if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){ + padapter->wapiInfo.bWapiPSK = true; + } + else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){ + padapter->wapiInfo.bWapiPSK = false; + } +#endif + + authmode = psecuritypriv->ndisauthtype; + rtw_set_802_11_authentication_mode(padapter, authmode); + + //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + + if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) { + ret = -1; + goto exit; + } + + DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy); + +exit: + + rtw_ps_deny_cancel(padapter, PS_DENY_JOIN); + + DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret); + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _FALSE; + #endif + + return ret; +} + +static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, + u16 reason_code) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev)); + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _TRUE; + #endif + + rtw_set_to_roam(padapter, 0); + + //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + rtw_scan_abort(padapter); + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + + DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__); + + rtw_indicate_disconnect(padapter); + + rtw_free_assoc_resources(padapter, 1); + rtw_pwr_wakeup(padapter); + } + + #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42 + padapter->mlmepriv.not_indic_disco = _FALSE; + #endif + + DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + struct wireless_dev *wdev, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE) + enum nl80211_tx_power_setting type, int mbm) +#else + enum tx_power_setting type, int dbm) +#endif +{ +#if 0 + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + int ret; + + switch (type) { + case NL80211_TX_POWER_AUTOMATIC: + return 0; + case NL80211_TX_POWER_FIXED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + + if (!test_bit(IWM_STATUS_READY, &iwm->status)) + return 0; + + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, + CFG_TX_PWR_LIMIT_USR, + MBM_TO_DBM(mbm) * 2); + if (ret < 0) + return ret; + + return iwm_tx_power_trigger(iwm); + default: + IWM_ERR(iwm, "Unsupported power type: %d\n", type); + return -EOPNOTSUPP; + } +#endif + DBG_8192C("%s\n", __func__); + return 0; +} + +static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + struct wireless_dev *wdev, +#endif + int *dbm) +{ + DBG_8192C("%s\n", __func__); + + *dbm = (12); + + return 0; +} + +inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter) +{ + struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter); + return rtw_wdev_priv->power_mgmt; +} + +static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + bool enabled, int timeout) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter); + + DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev), + enabled, timeout); + + rtw_wdev_priv->power_mgmt = enabled; + + #ifdef CONFIG_LPS + if (!enabled) + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 1); + #endif + + return 0; +} + +static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa) +{ + 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" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev) + , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid)); + + 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, (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, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN); + psecuritypriv->PMKIDList[index].bUsed = _TRUE; + psecuritypriv->PMKIDIndex = index+1; + blInserted = _TRUE; + break; + } + } + + if(!blInserted) + { + // Find a new entry + 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, (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++ ; + if(psecuritypriv->PMKIDIndex==16) + { + psecuritypriv->PMKIDIndex =0; + } + } + + return 0; +} + +static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_pmksa *pmksa) +{ + u8 index, bMatched = _FALSE; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + 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, (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 ); + psecuritypriv->PMKIDList[index].bUsed = _FALSE; + bMatched = _TRUE; + DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index); + break; + } + } + + if(_FALSE == bMatched) + { + DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n" + , FUNC_NDEV_ARG(ndev)); + return -EINVAL; + } + + return 0; +} + +static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy, + struct net_device *ndev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct security_priv *psecuritypriv = &padapter->securitypriv; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + psecuritypriv->PMKIDIndex = 0; + + return 0; +} + +#ifdef CONFIG_AP_MODE +void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + s32 freq; + int channel; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct net_device *ndev = padapter->pnetdev; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + { + struct station_info sinfo; + u8 ie_offset; + if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ) + ie_offset = _ASOCREQ_IE_OFFSET_; + else // WIFI_REASSOCREQ + ie_offset = _REASOCREQ_IE_OFFSET_; + + sinfo.filled = 0; + sinfo.filled = STATION_INFO_ASSOC_REQ_IES; + sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; + sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; + cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); + } +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); + #else //COMPAT_KERNEL_RELEASE + { + //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() + #ifndef CONFIG_PLATFORM_MSTAR + pwdev->iftype = NL80211_IFTYPE_STATION; + #endif //CONFIG_PLATFORM_MSTAR + DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype); + rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len); + DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype); + pwdev->iftype = NL80211_IFTYPE_AP; + //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); + } + #endif //COMPAT_KERNEL_RELEASE +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ + +} + +void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason) +{ + s32 freq; + int channel; + u8 *pmgmt_frame; + uint frame_len; + struct rtw_ieee80211_hdr *pwlanhdr; + unsigned short *fctrl; + u8 mgmt_buf[128] = {0}; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct net_device *ndev = padapter->pnetdev; + + DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); + +#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE) + cfg80211_del_sta(ndev, da, GFP_ATOMIC); +#else /* defined(RTW_USE_CFG80211_STA_EVENT) */ + channel = pmlmeext->cur_channel; + freq = rtw_ch2freq(channel); + + pmgmt_frame = mgmt_buf; + pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame; + + fctrl = &(pwlanhdr->frame_ctl); + *(fctrl) = 0; + + _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); + + SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); + pmlmeext->mgnt_seq++; + SetFrameSubType(pmgmt_frame, WIFI_DEAUTH); + + pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr); + frame_len = sizeof(struct rtw_ieee80211_hdr_3addr); + + reason = cpu_to_le16(reason); + pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len); + + #ifdef COMPAT_KERNEL_RELEASE + rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC); + #else //COMPAT_KERNEL_RELEASE + cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); + //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); + #endif //COMPAT_KERNEL_RELEASE +#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */ +} + +static int rtw_cfg80211_monitor_if_open(struct net_device *ndev) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +static int rtw_cfg80211_monitor_if_close(struct net_device *ndev) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev) +{ + int ret = 0; + int rtap_len; + int qos_len = 0; + int dot11_hdr_len = 24; + int snap_len = 6; + unsigned char *pdata; + u16 frame_ctl; + unsigned char src_mac_addr[6]; + unsigned char dst_mac_addr[6]; + struct rtw_ieee80211_hdr *dot11_hdr; + struct ieee80211_radiotap_header *rtap_hdr; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + if (skb) + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize); + + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) + goto fail; + + rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; + if (unlikely(rtap_hdr->it_version)) + goto fail; + + rtap_len = ieee80211_get_radiotap_len(skb->data); + if (unlikely(skb->len < rtap_len)) + goto fail; + + if(rtap_len != 14) + { + DBG_8192C("radiotap len (should be 14): %d\n", rtap_len); + goto fail; + } + + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + + dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data; + frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl); + /* Check if the QoS bit is set */ + if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) { + /* Check if this ia a Wireless Distribution System (WDS) frame + * which has 4 MAC addresses + */ + if (dot11_hdr->frame_ctl & 0x0080) + qos_len = 2; + if ((dot11_hdr->frame_ctl & 0x0300) == 0x0300) + dot11_hdr_len += 6; + + memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); + memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); + + /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for + * for two MAC addresses + */ + skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2); + pdata = (unsigned char*)skb->data; + memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr)); + memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr)); + + DBG_8192C("should be eapol packet\n"); + + /* Use the real net device to transmit the packet */ + ret = _rtw_xmit_entry(skb, padapter->pnetdev); + + return ret; + + } + else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)) + == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION) + ) + { + //only for action frames + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + //u8 category, action, OUI_Subtype, dialogToken=0; + //unsigned char *frame_body; + struct rtw_ieee80211_hdr *pwlanhdr; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 *buf = skb->data; + u32 len = skb->len; + u8 category, action; + int type = -1; + + if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { + DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev), + le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl)); + goto fail; + } + + DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n", + MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev)); + #ifdef CONFIG_P2P + if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) + goto dump; + #endif + if (category == RTW_WLAN_CATEGORY_PUBLIC) + DBG_871X("RTW_Tx:%s\n", action_public_str(action)); + else + DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action); + +dump: + //starting alloc mgmt frame to dump it + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + goto fail; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void*)buf, len); + pattrib->pktlen = len; + +#ifdef CONFIG_P2P + if (type >= 0) + rtw_xframe_chk_wfd_ie(pmgntframe); +#endif /* CONFIG_P2P */ + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //update seq number + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + + + pattrib->last_txcmdsz = pattrib->pktlen; + + dump_mgntframe(padapter, pmgntframe); + + } + else + { + DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE)); + } + + +fail: + + rtw_skb_free(skb); + + return 0; + +} + +static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev) +{ + DBG_8192C("%s\n", __func__); +} + +static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) +{ + int ret = 0; + + DBG_8192C("%s\n", __func__); + + return ret; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_cfg80211_monitor_if_ops = { + .ndo_open = rtw_cfg80211_monitor_if_open, + .ndo_stop = rtw_cfg80211_monitor_if_close, + .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) + .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list, + #endif + .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address, +}; +#endif + +static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev) +{ + int ret = 0; + struct net_device* mon_ndev = NULL; + struct wireless_dev* mon_wdev = NULL; + struct rtw_netdev_priv_indicator *pnpi; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + + if (!name) { + DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter)); + ret = -EINVAL; + goto out; + } + + if (pwdev_priv->pmon_ndev) { + DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n", + FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev)); + ret = -EBUSY; + goto out; + } + + mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); + if (!mon_ndev) { + DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter)); + ret = -ENOMEM; + goto out; + } + + mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; + strncpy(mon_ndev->name, name, IFNAMSIZ); + mon_ndev->name[IFNAMSIZ - 1] = 0; + mon_ndev->destructor = rtw_ndev_destructor; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; +#else + mon_ndev->open = rtw_cfg80211_monitor_if_open; + mon_ndev->stop = rtw_cfg80211_monitor_if_close; + mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry; + mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address; +#endif + + pnpi = netdev_priv(mon_ndev); + pnpi->priv = padapter; + pnpi->sizeof_priv = sizeof(_adapter); + + /* wdev */ + mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev)); + if (!mon_wdev) { + DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter)); + ret = -ENOMEM; + goto out; + } + + mon_wdev->wiphy = padapter->rtw_wdev->wiphy; + mon_wdev->netdev = mon_ndev; + mon_wdev->iftype = NL80211_IFTYPE_MONITOR; + mon_ndev->ieee80211_ptr = mon_wdev; + + ret = register_netdevice(mon_ndev); + if (ret) { + goto out; + } + + *ndev = pwdev_priv->pmon_ndev = mon_ndev; + _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1); + +out: + if (ret && mon_wdev) { + rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev)); + mon_wdev = NULL; + } + + if (ret && mon_ndev) { + free_netdev(mon_ndev); + *ndev = mon_ndev = NULL; + } + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +static struct wireless_dev * +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) +static struct net_device * +#else +static int +#endif + cfg80211_rtw_add_virtual_intf( + struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) + const char *name, + #else + char *name, + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + unsigned char name_assign_type, + #endif + enum nl80211_iftype type, u32 *flags, struct vif_params *params) +{ + int ret = 0; + struct net_device* ndev = NULL; + _adapter *padapter = wiphy_to_adapter(wiphy); + + DBG_871X("%s wiphy:%s, name:%s, type:%d\n", + __func__, wiphy_name(wiphy), name, type); + + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + case NL80211_IFTYPE_MESH_POINT: + ret = -ENODEV; + break; + case NL80211_IFTYPE_MONITOR: + ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); + break; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + case NL80211_IFTYPE_P2P_CLIENT: +#endif + case NL80211_IFTYPE_STATION: + ret = -ENODEV; + break; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + case NL80211_IFTYPE_P2P_GO: +#endif + case NL80211_IFTYPE_AP: + ret = -ENODEV; + break; + default: + ret = -ENODEV; + DBG_871X("Unsupported interface type\n"); + break; + } + + DBG_871X("%s ndev:%p, ret:%d\n", __func__, ndev, ret); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + return ndev ? ndev : ERR_PTR(ret); +#else + return ret; +#endif +} + +static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev +#else + struct net_device *ndev +#endif +) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + int ret = 0; + _adapter *adapter; + struct rtw_wdev_priv *pwdev_priv; + + if (!ndev) { + ret = -EINVAL; + goto exit; + } + + adapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(adapter); + + unregister_netdevice(ndev); + + if (ndev == pwdev_priv->pmon_ndev) { + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev)); + } + +exit: + return ret; +} + +static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len) +{ + int ret=0; + u8 *pbuf = NULL; + uint len, wps_ielen=0; + uint p2p_ielen=0; + u8 *p2p_ie; + u8 got_p2p_ie = _FALSE; + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); + //struct sta_priv *pstapriv = &padapter->stapriv; + + + DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if(head_len<24) + return -EINVAL; + + + pbuf = rtw_zmalloc(head_len+tail_len); + if(!pbuf) + return -ENOMEM; + + + //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); + + //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) + // pstapriv->max_num_sta = NUM_STA; + + + _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len. + _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len); + + len = head_len+tail_len-24; + + //check wps ie if inclued + if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen)) + DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen); + +#ifdef CONFIG_P2P + if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + //check p2p if enable + if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen)) + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct wifidirect_info *pwdinfo= &(adapter->wdinfo); + + DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen); + + got_p2p_ie = _TRUE; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_8192C("Enable P2P function for the first time\n"); + rtw_p2p_enable(adapter, P2P_ROLE_GO); + adapter_wdev_data(adapter)->p2p_enabled = _TRUE; + + adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode + } + else + { + DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen); + + rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK); + pwdinfo->intent = 15; + } + } + } +#endif // CONFIG_P2P + + /* pbss_network->IEs will not include p2p_ie, wfd ie */ + rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4); + rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4); + + if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) + { +#ifdef CONFIG_P2P + //check p2p if enable + if(got_p2p_ie == _TRUE) + { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct wifidirect_info *pwdinfo= &(adapter->wdinfo); + pwdinfo->operating_channel = pmlmeext->cur_channel; + } +#endif //CONFIG_P2P + ret = 0; + } + else + { + ret = -EINVAL; + } + + + rtw_mfree(pbuf, head_len+tail_len); + + return ret; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE) +static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct beacon_parameters *info) +{ + int ret=0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); + + return ret; +} + +static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct beacon_parameters *info) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + pmlmeext->bstart_bss = _TRUE; + + cfg80211_rtw_add_beacon(wiphy, ndev, info); + + return 0; +} + +static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} +#else +static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_ap_settings *settings) +{ + int ret = 0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev), + settings->hidden_ssid, settings->auth_type); + + ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len, + settings->beacon.tail, settings->beacon.tail_len); + + adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid; + + if (settings->ssid && settings->ssid_len) { + WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network; + WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network; + + if(0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter), + settings->ssid, settings->ssid_len, + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength); + + _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len); + pbss_network->Ssid.SsidLength = settings->ssid_len; + _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len); + pbss_network_ext->Ssid.SsidLength = settings->ssid_len; + + if(0) + DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + } + + return ret; +} + +static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_beacon_data *info) +{ + int ret = 0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev); + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); + + return ret; +} + +static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + return 0; +} + +#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + +static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac, +#else + const u8 *mac, +#endif + struct station_parameters *params) +{ + int ret = 0; +#ifdef CONFIG_TDLS + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct sta_priv *pstapriv = &padapter->stapriv; + struct sta_info *psta; +#endif /* CONFIG_TDLS */ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + +#ifdef CONFIG_TDLS + psta = rtw_get_stainfo(pstapriv, mac); + if (psta == NULL) { + psta = rtw_alloc_stainfo(pstapriv, mac); + if (psta ==NULL) { + DBG_871X("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac)); + ret =-EOPNOTSUPP; + goto exit; + } + } +#endif /* CONFIG_TDLS */ + +exit: + return ret; +} + +static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + u8 *mac +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) + const u8 *mac +#else + struct station_del_parameters *params +#endif + ) +{ + int ret=0; + _irqL irqL; + _list *phead, *plist; + u8 updated = _FALSE; + const u8 *target_mac; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) + target_mac = mac; +#else + target_mac = params->mac; +#endif + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__); + return -EINVAL; + } + + + if (!target_mac) + { + DBG_8192C("flush all sta, and cam_entry\n"); + + flush_all_cam_entry(padapter); //clear CAM + + ret = rtw_sta_flush(padapter, _TRUE); + + return ret; + } + + + DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(target_mac)); + + if (target_mac[0] == 0xff && target_mac[1] == 0xff && + target_mac[2] == 0xff && target_mac[3] == 0xff && + target_mac[4] == 0xff && target_mac[5] == 0xff) + { + return -EINVAL; + } + + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + + if (_rtw_memcmp((u8 *)target_mac, psta->hwaddr, ETH_ALEN)) + { + if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE) + { + DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__); + } + else + { + DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid); + + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + + //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE) + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE); + else + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE); + //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + psta = NULL; + + break; + } + + } + + } + + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); + + DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return ret; + +} + +static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev, +#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)); + + return 0; +} + +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; + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) + { + if(idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + i++; + } + return psta; +} + +static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev, + int idx, u8 *mac, struct station_info *sinfo) +{ + + int ret = 0; + _irqL irqL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + psta = rtw_sta_info_get_by_idx(idx, pstapriv); + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(NULL == psta) + { + DBG_871X("Station is not found\n"); + ret = -ENOENT; + goto exit; + } + _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN); + sinfo->filled = 0; + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = psta->rssi; + +exit: + return ret; +} + +static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev, + struct bss_parameters *params) +{ + u8 i; + + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); +/* + DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot); + DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble); + DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time); + DBG_8192C("ap_isolate=%d\n", params->ap_isolate); + + DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len); + for(i=0; ibasic_rates_len; i++) + { + DBG_8192C("basic_rates=%d\n", params->basic_rates[i]); + + } +*/ + return 0; + +} + +static int cfg80211_rtw_set_channel(struct wiphy *wiphy + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + , struct net_device *ndev + #endif + , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) +{ + int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq); + int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + int chan_width = CHANNEL_WIDTH_20; + _adapter *padapter = wiphy_to_adapter(wiphy); + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + #endif + + switch (channel_type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + chan_width = CHANNEL_WIDTH_20; + chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_HT40MINUS: + chan_width = CHANNEL_WIDTH_40; + chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_HT40PLUS: + chan_width = CHANNEL_WIDTH_40; + chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + default: + chan_width = CHANNEL_WIDTH_20; + chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } + + set_channel_bwmode(padapter, chan_target, chan_offset, chan_width); + + return 0; +} + +static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + , struct cfg80211_chan_def *chandef +#else + , struct ieee80211_channel *chan + , enum nl80211_channel_type channel_type +#endif + ) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) + struct ieee80211_channel *chan = chandef->chan; +#endif + + _adapter *padapter = wiphy_to_adapter(wiphy); + int target_channal = chan->hw_value; + int target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + int target_width = CHANNEL_WIDTH_20; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n" + , chan->center_freq + , chan->hw_value + , chandef->width + , chandef->center_freq1 + , chandef->center_freq2); +#endif /* CONFIG_DEBUG_CFG80211 */ + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + target_width = CHANNEL_WIDTH_20; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_WIDTH_40: + target_width = CHANNEL_WIDTH_40; + if (chandef->center_freq1 > chan->center_freq) + target_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + else + target_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_WIDTH_80: + target_width = CHANNEL_WIDTH_80; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_WIDTH_80P80: + target_width = CHANNEL_WIDTH_80_80; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_WIDTH_160: + target_width = CHANNEL_WIDTH_160; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + case NL80211_CHAN_WIDTH_5: + case NL80211_CHAN_WIDTH_10: +#endif + default: + target_width = CHANNEL_WIDTH_20; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } +#else +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("center_freq %u Mhz ch %u channel_type %u\n" + , chan->center_freq + , chan->hw_value + , channel_type); +#endif /* CONFIG_DEBUG_CFG80211 */ + + switch (channel_type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + target_width = CHANNEL_WIDTH_20; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + case NL80211_CHAN_HT40MINUS: + target_width = CHANNEL_WIDTH_40; + target_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; + case NL80211_CHAN_HT40PLUS: + target_width = CHANNEL_WIDTH_40; + target_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; + default: + target_width = CHANNEL_WIDTH_20; + target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; + } +#endif + + set_channel_bwmode(padapter, target_channal, target_offset, target_width); + + return 0; +} + +static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_auth_request *req) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} + +static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_assoc_request *req) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + + return 0; +} +#endif //CONFIG_AP_MODE + +void rtw_cfg80211_rx_probe_request(_adapter *adapter, u8 *frame, uint frame_len) +{ + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + u8 category, action; + + channel = rtw_get_oper_ch(adapter); + freq = rtw_ch2freq(channel); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("RTW_Rx: probe request, cur_ch=%d\n", channel); +#endif /* CONFIG_DEBUG_CFG80211 */ + rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC); +} + +void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + int type; + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 category, action; + + channel = rtw_get_oper_ch(padapter); + + DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); + #ifdef CONFIG_P2P + type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE); + if (type >= 0) + goto indicate; + #endif + rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action); + DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); + +indicate: + freq = rtw_ch2freq(channel); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); +#else + cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); +#endif +} + +void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len) +{ + int type; + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + u8 category, action; + + channel = rtw_get_oper_ch(padapter); + + DBG_8192C("RTW_Rx:cur_ch=%d\n", channel); + #ifdef CONFIG_P2P + type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE); + if (type >= 0) { + switch (type) { + case P2P_GO_NEGO_CONF: + case P2P_PROVISION_DISC_RESP: + case P2P_INVIT_RESP: + rtw_set_scan_deny(padapter, 2000); + rtw_clear_scan_deny(padapter); + } + goto indicate; + } + #endif + rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action); + DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action); + +indicate: + freq = rtw_ch2freq(channel); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC); +#else + cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); +#endif +} + +void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg) +{ + s32 freq; + int channel; + struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv); + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); + u8 category, action; + + channel = rtw_get_oper_ch(adapter); + + rtw_action_frame_parse(frame, frame_len, &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 + } + + freq = rtw_ch2freq(channel); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC); +#else + 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 +void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len) +{ + u16 wps_devicepassword_id = 0x0000; + uint wps_devicepassword_id_len = 0; + u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 }; + uint p2p_ielen = 0; + uint wpsielen = 0; + u32 devinfo_contentlen = 0; + u8 devinfo_content[64] = { 0x00 }; + u16 capability = 0; + uint capability_len = 0; + + unsigned char category = RTW_WLAN_CATEGORY_PUBLIC; + u8 action = P2P_PUB_ACTION_ACTION; + u8 dialogToken = 1; + u32 p2poui = cpu_to_be32(P2POUI); + u8 oui_subtype = P2P_PROVISION_DISC_REQ; + u32 p2pielen = 0; +#ifdef CONFIG_WFD + u32 wfdielen = 0; +#endif + + 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); + u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); + size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr); + + + DBG_871X( "[%s] In\n", __FUNCTION__ ); + + //prepare for building provision_request frame + _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN); + _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN); + + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + + rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen); + rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len); + wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id ); + + switch(wps_devicepassword_id) + { + case WPS_DPID_PIN: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; + break; + case WPS_DPID_USER_SPEC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; + break; + case WPS_DPID_MACHINE_SPEC: + break; + case WPS_DPID_REKEY: + break; + case WPS_DPID_PBC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + break; + case WPS_DPID_REGISTRAR_SPEC: + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; + break; + default: + break; + } + + + if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) ) + { + + rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen); + rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len); + + } + + + //start to build provision_request frame + _rtw_memset(wpsie, 0, sizeof(wpsie)); + _rtw_memset(p2p_ie, 0, sizeof(p2p_ie)); + p2p_ielen = 0; + + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + return; + } + + + //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, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN); + + 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); + + 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, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen)); + pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen)); + + + //build_prov_disc_request_p2p_ie + // P2P OUI + p2pielen = 0; + p2p_ie[ p2pielen++ ] = 0x50; + p2p_ie[ p2pielen++ ] = 0x6F; + p2p_ie[ p2pielen++ ] = 0x9A; + p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0 + + // Commented by Albert 20110301 + // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes + // 1. P2P Capability + // 2. Device Info + // 3. Group ID ( When joining an operating P2P Group ) + + // P2P Capability ATTR + // Type: + p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY; + + // Length: + //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); + RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002); + p2pielen += 2; + + // Value: + // Device Capability Bitmap, 1 byte + // Group Capability Bitmap, 1 byte + _rtw_memcpy(p2p_ie + p2pielen, &capability, 2); + p2pielen += 2; + + + // Device Info ATTR + // Type: + p2p_ie[ 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 ); + RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen); + p2pielen += 2; + + // Value: + _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen); + p2pielen += devinfo_contentlen; + + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen); + //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr); + //pframe += p2pielen; + pattrib->pktlen += p2p_ielen; + + 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 + + // 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->tx_prov_disc_info.wps_config_method_request ); + wpsielen += 2; + + pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen ); + + +#ifdef CONFIG_WFD + wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe); + pframe += wfdielen; + pattrib->pktlen += wfdielen; +#endif + + pattrib->last_txcmdsz = pattrib->pktlen; + + //dump_mgntframe(padapter, pmgntframe); + if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) + DBG_8192C("%s, ack to\n", __func__); + + //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) + //{ + // DBG_8192C("waiting for p2p peer key-in PIN CODE\n"); + // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req. + //} + +} + +static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + struct ieee80211_channel * channel, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + s32 err = 0; + u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq); + u8 ready_on_channel = _FALSE; + _adapter *padapter; + struct rtw_wdev_priv *pwdev_priv; + 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; + } + + padapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(padapter); + 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, cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), remain_ch, duration, *cookie); + +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) { + DBG_871X(FUNC_ADPT_FMT ": MP mode block remain_on_channel request\n", FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) { + if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1) { + DBG_871X(FUNC_ADPT_FMT ": MP mode block remain_on_channel request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter)); + err = -EFAULT; + goto exit; + } + } +#endif +#endif + + 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 + p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK); + } + + pcfg80211_wdinfo->is_ro_ch = _TRUE; + pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time(); + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + err = -EFAULT; + goto exit; + } + + _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel)); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pcfg80211_wdinfo->remain_on_ch_type= channel_type; + #endif + pcfg80211_wdinfo->remain_on_ch_cookie= *cookie; + + rtw_scan_abort(padapter); +#ifdef CONFIG_CONCURRENT_MODE + 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 + + if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) + { + DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv)); + remain_ch = padapter->mlmeextpriv.cur_channel; + } +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) + { + DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv))); + remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel; + } +#endif /* CONFIG_CONCURRENT_MODE */ + + //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_enable(padapter, P2P_ROLE_DEVICE); + adapter_wdev_data(padapter)->p2p_enabled = _TRUE; + padapter->wdinfo.listen_channel = remain_ch; + } else if (rtw_p2p_chk_state(pwdinfo , P2P_STATE_LISTEN)) { + padapter->wdinfo.listen_channel = remain_ch; + } else { + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + } + + + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN); + + #ifdef RTW_ROCH_DURATION_ENLARGE + if (duration < 400) + duration = duration * 3; /* extend from exper */ + #endif + +#ifdef RTW_ROCH_BACK_OP +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_LINKED)) { + 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); + + if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_buddy_fwstate(padapter, _FW_LINKED) ) + { + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) + { + if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 || + (remain_ch != pmlmeext->cur_channel)) + { + if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) { + DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__); + 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); + #endif + } + } + + ready_on_channel = _TRUE; + //pmlmeext->cur_channel = remain_ch; + //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + }else +#endif //CONFIG_CONCURRENT_MODE + if(remain_ch != rtw_get_oper_ch(padapter) ) + { + ready_on_channel = _TRUE; + //pmlmeext->cur_channel = remain_ch; + //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + } else { + DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch); + } + + + //call this after other things have been done +#ifdef CONFIG_CONCURRENT_MODE + if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 || + (remain_ch != rtw_get_oper_ch(padapter))) + { + u8 co_channel = 0xff; + ATOMIC_SET(&pwdev_priv->ro_ch_to, 0); +#endif + + if(ready_on_channel == _TRUE) + { + if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) ) + { + pmlmeext->cur_channel = remain_ch; + +#ifdef CONFIG_CONCURRENT_MODE + co_channel = rtw_get_oper_ch(padapter); + + if(co_channel !=remain_ch) +#endif + { + //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) + set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + } + } + DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration); + _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration); + +#ifdef CONFIG_CONCURRENT_MODE + } +#endif + + rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL); + +exit: + if (err) { + pcfg80211_wdinfo->is_ro_ch = _FALSE; + pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time(); + } + + return err; +} + +static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + u64 cookie) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + s32 err = 0; + _adapter *padapter; + struct rtw_wdev_priv *pwdev_priv; + struct wifidirect_info *pwdinfo; + struct cfg80211_wifidirect_info *pcfg80211_wdinfo; + + if (ndev == NULL) { + err = -EINVAL; + goto exit; + } + + padapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(padapter); + pwdinfo = &padapter->wdinfo; + pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + 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__); + _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); + #ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); + #endif + p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK); + } + + #if 0 + // Disable P2P Listen State + if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info)); + } + } + else + #endif + { + rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo)); +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo)); +#endif + } + + pcfg80211_wdinfo->is_ro_ch = _FALSE; + pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time(); + +exit: + return err; +} + +#endif //CONFIG_P2P + +static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len, int wait_ack) +{ + struct xmit_frame *pmgntframe; + struct pkt_attrib *pattrib; + unsigned char *pframe; + int ret = _FAIL; + bool ack = _TRUE; + struct rtw_ieee80211_hdr *pwlanhdr; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; + + rtw_set_scan_deny(padapter, 1000); + + rtw_scan_abort(padapter); + #ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + rtw_scan_abort(padapter->pbuddy_adapter); + #endif /* CONFIG_CONCURRENT_MODE */ +#ifdef CONFIG_P2P + if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) { + //DBG_8192C("%s, cancel ro ch timer\n", __func__); + //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); + //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE; + #ifdef CONFIG_CONCURRENT_MODE + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + { + DBG_8192C("%s, extend ro ch time\n", __func__); + _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period); + } + #endif //CONFIG_CONCURRENT_MODE + } +#endif //CONFIG_P2P +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_LINKED )) { + u8 co_channel=0xff; + PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; + + co_channel = rtw_get_oper_ch(padapter); + + if (tx_ch != pbuddy_mlmeext->cur_channel) { + + u16 ext_listen_period; + + if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) { + if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) { + DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__); + issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500); + } + + ATOMIC_SET(&pwdev_priv->switch_ch_to, 0); + + //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period); + //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period); + } + + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + { + ext_listen_period = 500;// 500ms + } + else + { + ext_listen_period = pwdinfo->ext_listen_period; + } + + DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period); + _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period); + + } + + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + pmlmeext->cur_channel = tx_ch; + + if (tx_ch != co_channel) + set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + }else +#endif //CONFIG_CONCURRENT_MODE + //if (tx_ch != pmlmeext->cur_channel) { + if(tx_ch != rtw_get_oper_ch(padapter)) { + if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED )) + pmlmeext->cur_channel = tx_ch; + set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + + //starting alloc mgmt frame to dump it + if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) + { + //ret = -ENOMEM; + ret = _FAIL; + goto exit; + } + + //update attribute + pattrib = &pmgntframe->attrib; + update_mgntframe_attrib(padapter, pattrib); + pattrib->retry_ctrl = _FALSE; + + _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); + + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + _rtw_memcpy(pframe, (void*)buf, len); + pattrib->pktlen = len; + + pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; + //update seq number + pmlmeext->mgnt_seq = GetSequence(pwlanhdr); + pattrib->seqnum = pmlmeext->mgnt_seq; + pmlmeext->mgnt_seq++; + +#ifdef CONFIG_P2P + rtw_xframe_chk_wfd_ie(pmgntframe); +#endif /* CONFIG_P2P */ + + pattrib->last_txcmdsz = pattrib->pktlen; + + if (wait_ack) { + if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) { + ack = _FALSE; + ret = _FAIL; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ack == _FAIL\n", __func__); +#endif + } else { + +#ifdef CONFIG_XMIT_ACK + rtw_msleep_os(50); +#endif +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ack=%d, ok!\n", __func__, ack); +#endif + ret = _SUCCESS; + } + } else { + dump_mgntframe(padapter, pmgntframe); + ret = _SUCCESS; + } +exit: + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ret=%d\n", __func__, ret); + #endif + + return ret; + +} + +static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#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) + bool offchan, + #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) + bool channel_type_valid, + #endif + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + unsigned int wait, + #endif + const u8 *buf, size_t len, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + bool no_cck, + #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + bool dont_wait_for_ack, + #endif +#else + struct cfg80211_mgmt_tx_params *params, +#endif + u64 *cookie) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE) + struct ieee80211_channel *chan = params->chan; + bool offchan = params->offchan; + unsigned int wait = params->wait; + const u8 *buf = params->buf; + size_t len = params->len; + bool no_cck = params->no_cck; + bool dont_wait_for_ack = params->dont_wait_for_ack; +#endif + int ret = 0; + int tx_ret; + int wait_ack = 1; + u32 dump_limit = RTW_MAX_MGMT_TX_CNT; + u32 dump_cnt = 0; + bool ack = _TRUE; + u8 tx_ch; + u8 category, action; + u8 frame_styp; + int type = (-1); + u32 start = rtw_get_current_time(); + _adapter *padapter; + struct rtw_wdev_priv *pwdev_priv; + + if ((ndev == NULL) || (chan == NULL)) { + ret = -EINVAL; + goto exit; + } + + tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq); + + padapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(padapter); + + /* cookie generation */ + *cookie = (unsigned long) buf; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d" + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + ", ch_type=%d" + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + ", channel_type_valid=%d" + #endif + #endif + "\n", FUNC_ADPT_ARG(padapter), + len, tx_ch + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + , channel_type + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + , channel_type_valid + #endif + #endif + ); +#endif /* CONFIG_DEBUG_CFG80211 */ + + /* indicate ack before issue frame to avoid racing with rsp frame */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL); +#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) + cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL); +#endif + + frame_styp = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl) & IEEE80211_FCTL_STYPE; + if (IEEE80211_STYPE_PROBE_RESP == frame_styp) { +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("RTW_Tx: probe_resp tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf))); +#endif /* CONFIG_DEBUG_CFG80211 */ + wait_ack = 0; + goto dump; + } + + if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { + DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter), + le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl)); + goto exit; + } + + DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf))); + #ifdef CONFIG_P2P + if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) { + goto dump; + } + #endif + if (category == RTW_WLAN_CATEGORY_PUBLIC) + DBG_871X("RTW_Tx:%s\n", action_public_str(action)); + else + DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action); + +dump: + + rtw_ps_deny(padapter, PS_DENY_MGNT_TX); + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret = -EFAULT; + goto cancel_ps_deny; + } + + while (1) { + u32 sleep_ms = 0; + u32 retry_guarantee_ms = 0; + + dump_cnt++; + tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len, wait_ack); + + 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), + tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start)); + } + + switch (type) { + case P2P_GO_NEGO_CONF: + rtw_clear_scan_deny(padapter); + break; + case P2P_INVIT_RESP: + if (pwdev_priv->invit_info.flags & BIT(0) + && pwdev_priv->invit_info.status == 0) + { + DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n", + FUNC_ADPT_ARG(padapter)); + rtw_set_scan_deny(padapter, 5000); + rtw_pwr_wakeup_ex(padapter, 5000); + rtw_clear_scan_deny(padapter); + } + break; + } + +cancel_ps_deny: + rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX); +exit: + return ret; +} + +static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +#else + struct net_device *ndev, +#endif + u16 frame_type, bool reg) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *ndev = wdev_to_ndev(wdev); +#endif + _adapter *adapter; + + struct rtw_wdev_priv *pwdev_priv; + + if (ndev == NULL) + goto exit; + + adapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(adapter); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter), + frame_type, reg); +#endif + + /* Wait QC Verify */ + return; + + switch (frame_type) { + case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */ + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg); + break; + case IEEE80211_STYPE_ACTION: /* 0x00D0 */ + SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg); + break; + default: + break; + } + +exit: + return; +} + +#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) +static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, + u8 action_code, + u8 dialog_token, + u16 status_code, + const u8 *buf, + size_t len) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; + int ret = 0; + struct tdls_txmgmt txmgmt; + + if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) { + DBG_871X("Discard tdls action:%d, since hal doesn't support tdls\n", action_code); + goto discard; + } + + if (rtw_tdls_is_driver_setup(padapter)) { + DBG_871X("Discard tdls action:%d, let driver to set up direct link\n", action_code); + goto discard; + } + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN); + txmgmt.action_code = action_code; + txmgmt.dialog_token= dialog_token; + txmgmt.status_code = status_code; + txmgmt.len = len; + txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len); + if (txmgmt.buf == NULL) { + ret = -ENOMEM; + goto bad; + } + _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len); + +/* Debug purpose */ +#if 1 + DBG_871X("%s %d\n", __FUNCTION__, __LINE__); + DBG_871X("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n", + MAC_ARG(txmgmt.peer), txmgmt.action_code, + txmgmt.dialog_token, txmgmt.status_code); + if (txmgmt.len > 0) { + int i=0; + for(;i < len; i++) + printk("%02x ", *(txmgmt.buf+i)); + DBG_871X("len:%d\n", txmgmt.len); + } +#endif + + switch (txmgmt.action_code) { + case TDLS_SETUP_REQUEST: + issue_tdls_setup_req(padapter, &txmgmt, _TRUE); + break; + case TDLS_SETUP_RESPONSE: + issue_tdls_setup_rsp(padapter, &txmgmt); + break; + case TDLS_SETUP_CONFIRM: + issue_tdls_setup_cfm(padapter, &txmgmt); + break; + case TDLS_TEARDOWN: + issue_tdls_teardown(padapter, &txmgmt, _TRUE); + break; + case TDLS_DISCOVERY_REQUEST: + issue_tdls_dis_req(padapter, &txmgmt); + break; + case TDLS_DISCOVERY_RESPONSE: + issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo? _TRUE : _FALSE); + break; + } + +bad: + if (txmgmt.buf) + rtw_mfree(txmgmt.buf, txmgmt.len); + +discard: + return ret; +} + +static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy, + struct net_device *ndev, + u8 *peer, + enum nl80211_tdls_operation oper) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct tdls_txmgmt txmgmt; + struct sta_info *ptdls_sta = NULL; + + DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper); + + if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) { + DBG_871X("Discard tdls oper:%d, since hal doesn't support tdls\n", oper); + return 0; + } + +#ifdef CONFIG_LPS + rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1); +#endif //CONFIG_LPS + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + if (peer) + _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN); + + if (rtw_tdls_is_driver_setup(padapter)) { + /* these two cases are done by driver itself */ + if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK) + return 0; + } + + switch (oper) { + case NL80211_TDLS_DISCOVERY_REQ: + issue_tdls_dis_req(padapter, &txmgmt); + break; + case NL80211_TDLS_SETUP: +#ifdef CONFIG_WFD + if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm ) { + if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE) + issue_tdls_setup_req(padapter, &txmgmt, _TRUE); + else + DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ ); + } else +#endif // CONFIG_WFD + { + issue_tdls_setup_req(padapter, &txmgmt, _TRUE); + } + break; + case NL80211_TDLS_TEARDOWN: + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer); + if (ptdls_sta != NULL) { + txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_; + issue_tdls_teardown(padapter, &txmgmt, _TRUE); + }else { + DBG_871X( "TDLS peer not found\n"); + } + break; + case NL80211_TDLS_ENABLE_LINK: + DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer)); + ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer); + if (ptdls_sta != NULL) { + ptdlsinfo->link_established = _TRUE; + ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE; + ptdls_sta->state |= _FW_LINKED; + rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED); + } + break; + case NL80211_TDLS_DISABLE_LINK: + DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer)); + ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer); + if (ptdls_sta != NULL) { + rtw_tdls_cmd(padapter, peer, TDLS_TEAR_STA ); + } + break; + } + return 0; +} +#endif /* CONFIG_TDLS */ + +#if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_sched_scan_request *request) { + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 ret; + + if (padapter->bup == _FALSE) { + DBG_871X("%s: net device is down.\n", __func__); + return -EIO; + } + + if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE || + check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE || + check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { + DBG_871X("%s: device is busy.\n", __func__); + rtw_scan_abort(padapter); + } + + if (request == NULL) { + DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__); + return -EINVAL; + } + + ret = rtw_android_cfg80211_pno_setup(dev, request->ssids, + request->n_ssids, request->interval); + + if (ret < 0) { + DBG_871X("%s ret: %d\n", __func__, ret); + goto exit; + } + + ret = rtw_android_pno_enable(dev, _TRUE); + if (ret < 0) { + DBG_871X("%s ret: %d\n", __func__, ret); + goto exit; + } +exit: + return ret; +} + +static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy, + struct net_device *dev) { + return rtw_android_pno_enable(dev, _FALSE); +} +#endif /* CONFIG_PNO_SUPPORT */ + +static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 wps_oui[8]={0x0,0x50,0xf2,0x04}; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + + DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len); + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen); + #endif + + if(pmlmepriv->wps_beacon_ie) + { + u32 free_len = pmlmepriv->wps_beacon_ie_len; + pmlmepriv->wps_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->wps_beacon_ie, free_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_beacon_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen); + pmlmepriv->wps_beacon_ie_len = wps_ielen; + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE); + + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen); + #endif + + if(pmlmepriv->p2p_beacon_ie) + { + u32 free_len = pmlmepriv->p2p_beacon_ie_len; + pmlmepriv->p2p_beacon_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len); + pmlmepriv->p2p_beacon_ie = NULL; + } + + pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_beacon_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_beacon_ie_len = p2p_ielen; + + } + #endif //CONFIG_P2P + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + } + #endif /* CONFIG_WFD */ + + pmlmeext->bstart_bss = _TRUE; + + } + + return ret; + +} + +static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + uint wps_ielen = 0; + u8 *wps_ie; + u32 p2p_ielen = 0; + u8 *p2p_ie; + u32 wfd_ielen = 0; + u8 *wfd_ie; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if(len>0) + { + if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen))) + { + uint attr_contentlen = 0; + u16 uconfig_method, *puconfig_method = NULL; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen); + #endif + + if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) + { + u8 sr = 0; + rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL); + + if (sr != 0) + { + DBG_871X("%s, got sr\n", __func__); + } + else + { + DBG_8192C("GO mode process WPS under site-survey, sr no set\n"); + return ret; + } + } + + if(pmlmepriv->wps_probe_resp_ie) + { + u32 free_len = pmlmepriv->wps_probe_resp_ie_len; + pmlmepriv->wps_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen); + if ( pmlmepriv->wps_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + + //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode + if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL ) + { + //struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct wireless_dev *wdev = padapter->rtw_wdev; + + #ifdef CONFIG_DEBUG_CFG80211 + //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); + #endif + + //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags + { + uconfig_method = WPS_CM_PUSH_BUTTON; + uconfig_method = cpu_to_be16( uconfig_method ); + + *puconfig_method |= uconfig_method; + } + #endif + } + + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen); + pmlmepriv->wps_probe_resp_ie_len = wps_ielen; + + } + + //buf += wps_ielen; + //len -= wps_ielen; + + #ifdef CONFIG_P2P + if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) + { + u8 is_GO = _FALSE; + u32 attr_contentlen = 0; + u16 cap_attr=0; + + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen); + #endif + + //Check P2P Capability ATTR + if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) ) + { + u8 grp_cap=0; + //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); + cap_attr = le16_to_cpu(cap_attr); + grp_cap = (u8)((cap_attr >> 8)&0xff); + + is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE; + + if(is_GO) + DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap); + } + + + if(is_GO == _FALSE) + { + if(pmlmepriv->p2p_probe_resp_ie) + { + u32 free_len = pmlmepriv->p2p_probe_resp_ie_len; + pmlmepriv->p2p_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len); + pmlmepriv->p2p_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen; + } + else + { + if(pmlmepriv->p2p_go_probe_resp_ie) + { + u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len; + pmlmepriv->p2p_go_probe_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len); + pmlmepriv->p2p_go_probe_resp_ie = NULL; + } + + pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen); + if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + + } + _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen); + pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen; + } + + } + #endif //CONFIG_P2P + + + #ifdef CONFIG_WFD + wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen); + if (wfd_ie) { + #ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen); + #endif + + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS) + return -EINVAL; + } + #endif /* CONFIG_WFD */ + + } + + return ret; + +} + +static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *ie; + u32 ie_len; + + DBG_8192C("%s, ielen=%d\n", __func__, len); + + if (len <= 0) + goto exit; + + ie = rtw_get_wps_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->wps_assoc_resp_ie) { + u32 free_len = pmlmepriv->wps_assoc_resp_ie_len; + + pmlmepriv->wps_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->wps_assoc_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len); + pmlmepriv->wps_assoc_resp_ie_len = ie_len; + } + + ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len); + if (ie && ie_len) { + if (pmlmepriv->p2p_assoc_resp_ie) { + u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len; + + pmlmepriv->p2p_assoc_resp_ie_len = 0; + rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len); + pmlmepriv->p2p_assoc_resp_ie = NULL; + } + + pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len); + if (pmlmepriv->p2p_assoc_resp_ie == NULL) { + DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len); + pmlmepriv->p2p_assoc_resp_ie_len = ie_len; + } + +#ifdef CONFIG_WFD + ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len); + if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS) + return -EINVAL; +#endif + +exit: + return ret; +} + +int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, + int type) +{ + int ret = 0; + uint wps_ielen = 0; + u32 p2p_ielen = 0; + +#ifdef CONFIG_DEBUG_CFG80211 + DBG_8192C("%s, ielen=%d\n", __func__, len); +#endif + + if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0)) + #ifdef CONFIG_P2P + || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0)) + #endif + ) + { + if (net != NULL) + { + switch (type) + { + case 0x1: //BEACON + ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len); + break; + case 0x2: //PROBE_RESP + ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len); + break; + case 0x4: //ASSOC_RESP + ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len); + break; + } + } + } + + return ret; + +} + +static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type) +{ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct ht_priv *phtpriv = &pmlmepriv->htpriv; + u8 stbc_rx_enable = _FALSE; + + rtw_ht_use_default_setting(padapter); + + /* RX LDPC */ + if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) + ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING; + + /* TX STBC */ + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) + ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC; + + /* RX STBC */ + if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) { + /*rtw_rx_stbc 0: disable, bit(0):enable 2.4g, bit(1):enable 5g*/ + if (IEEE80211_BAND_2GHZ == band) + stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(0))?_TRUE:_FALSE; + if (IEEE80211_BAND_5GHZ == band) + stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(1))?_TRUE:_FALSE; + + if (stbc_rx_enable) { + switch (rf_type) { + case RF_1T1R: + ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/*RX STBC One spatial stream*/ + break; + + case RF_2T2R: + case RF_1T2R: + ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */ + break; + case RF_3T3R: + case RF_3T4R: + case RF_4T4R: + ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */ + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + break; + } + } + } +} + +static void rtw_cfg80211_init_ht_capab(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type) +{ +#define MAX_BIT_RATE_40MHZ_MCS23 450 /* Mbps */ +#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ +#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ + + ht_cap->ht_supported = _TRUE; + + ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; + rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type); + + /* + *Maximum length of AMPDU that the STA can receive. + *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + */ + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + + /*Minimum MPDU start spacing , */ + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + + /* + *hw->wiphy->bands[IEEE80211_BAND_2GHZ] + *base on ant_num + *rx_mask: RX mask + *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7 + *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15 + *if rx_ant >=3 rx_mask[2]=0xff; + *if BW_40 rx_mask[4]=0x01; + *highest supported RX rate + */ + if (rf_type == RF_1T1R) { + ht_cap->mcs.rx_mask[0] = 0xFF; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; + } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R) || (rf_type == RF_2T2R_GREEN)) { + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; + } else if ((rf_type == RF_2T3R) || (rf_type == RF_3T3R)) { + ht_cap->mcs.rx_mask[0] = 0xFF; + ht_cap->mcs.rx_mask[1] = 0xFF; + ht_cap->mcs.rx_mask[2] = 0xFF; + + ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS23; + } else { + rtw_warn_on(1); + DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type); + } + +} + +void rtw_cfg80211_init_wiphy(_adapter *padapter) +{ + u8 rf_type; + struct ieee80211_supported_band *bands; + struct wireless_dev *pwdev = padapter->rtw_wdev; + struct wiphy *wiphy = pwdev->wiphy; + + rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type)); + + DBG_8192C("%s:rf_type=%d\n", __func__, rf_type); + + if (IsSupported24G(padapter->registrypriv.wireless_mode)) { + bands = wiphy->bands[IEEE80211_BAND_2GHZ]; + if(bands) + rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type); + } +#ifdef CONFIG_IEEE80211_BAND_5GHZ + if (IsSupported5G(padapter->registrypriv.wireless_mode)) { + bands = wiphy->bands[IEEE80211_BAND_5GHZ]; + if(bands) + rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type); + } +#endif + /* init regulary domain */ + rtw_regd_init(padapter); + + /* copy mac_addr to wiphy */ + _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN); + +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) +struct ieee80211_iface_limit rtw_limits[] = { + { .max = 2, + .types = BIT(NL80211_IFTYPE_STATION) + #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + #endif + }, + #ifdef CONFIG_AP_MODE + { .max = 1, + .types = BIT(NL80211_IFTYPE_AP) + #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) + | BIT(NL80211_IFTYPE_P2P_GO) + #endif + }, + #endif +}; + +struct ieee80211_iface_combination rtw_combinations[] = { + { .limits = rtw_limits, + .n_limits = ARRAY_SIZE(rtw_limits), + .max_interfaces = 2, + .num_different_channels = 1, + }, +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */ + +static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy) +{ + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT; + wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE) + wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION; +#endif + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) +#ifdef CONFIG_AP_MODE + | BIT(NL80211_IFTYPE_AP) + #ifdef CONFIG_WIFI_MONITOR + | BIT(NL80211_IFTYPE_MONITOR) + #endif +#endif +#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) +#endif + ; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) +#ifdef CONFIG_AP_MODE + wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes; +#endif //CONFIG_AP_MODE +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) + #ifdef CONFIG_WIFI_MONITOR + wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); + #endif +#endif + + #if defined(RTW_SINGLE_WIPHY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) + wiphy->iface_combinations = rtw_combinations; + wiphy->n_iface_combinations = ARRAY_SIZE(rtw_combinations); + #endif + + wiphy->cipher_suites = rtw_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites); + + if (IsSupported24G(adapter->registrypriv.wireless_mode)) + wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ); + +#ifdef CONFIG_IEEE80211_BAND_5GHZ + if (IsSupported5G(adapter->registrypriv.wireless_mode)) + wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; + /* remove WIPHY_FLAG_OFFCHAN_TX, because we not support this feature */ + /* wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; */ +#endif + +#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; +#ifdef CONFIG_PNO_SUPPORT + wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT; +#endif +#endif + +#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 + wiphy->wowlan = &wowlan_stub; +#endif +#endif + +#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; +#ifndef CONFIG_TDLS_DRIVER_SETUP + wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; //Driver handles key exchange + wiphy->flags |= NL80211_ATTR_HT_CAPABILITY; +#endif //CONFIG_TDLS_DRIVER_SETUP +#endif /* CONFIG_TDLS */ + + if (regsty->power_mgnt != PS_MODE_ACTIVE) + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; + else + wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; +#endif +} + +static struct cfg80211_ops rtw_cfg80211_ops = { + .change_virtual_intf = cfg80211_rtw_change_iface, + .add_key = cfg80211_rtw_add_key, + .get_key = cfg80211_rtw_get_key, + .del_key = cfg80211_rtw_del_key, + .set_default_key = cfg80211_rtw_set_default_key, +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)) + .set_rekey_data = cfg80211_rtw_set_rekey_data, +#endif /*CONFIG_GTK_OL*/ + .get_station = cfg80211_rtw_get_station, + .scan = cfg80211_rtw_scan, + .set_wiphy_params = cfg80211_rtw_set_wiphy_params, + .connect = cfg80211_rtw_connect, + .disconnect = cfg80211_rtw_disconnect, + .join_ibss = cfg80211_rtw_join_ibss, + .leave_ibss = cfg80211_rtw_leave_ibss, + .set_tx_power = cfg80211_rtw_set_txpower, + .get_tx_power = cfg80211_rtw_get_txpower, + .set_power_mgmt = cfg80211_rtw_set_power_mgmt, + .set_pmksa = cfg80211_rtw_set_pmksa, + .del_pmksa = cfg80211_rtw_del_pmksa, + .flush_pmksa = cfg80211_rtw_flush_pmksa, + +#ifdef CONFIG_AP_MODE + .add_virtual_intf = cfg80211_rtw_add_virtual_intf, + .del_virtual_intf = cfg80211_rtw_del_virtual_intf, + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE) + .add_beacon = cfg80211_rtw_add_beacon, + .set_beacon = cfg80211_rtw_set_beacon, + .del_beacon = cfg80211_rtw_del_beacon, + #else + .start_ap = cfg80211_rtw_start_ap, + .change_beacon = cfg80211_rtw_change_beacon, + .stop_ap = cfg80211_rtw_stop_ap, + #endif + + .add_station = cfg80211_rtw_add_station, + .del_station = cfg80211_rtw_del_station, + .change_station = cfg80211_rtw_change_station, + .dump_station = cfg80211_rtw_dump_station, + .change_bss = cfg80211_rtw_change_bss, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) + .set_channel = cfg80211_rtw_set_channel, + #endif + //.auth = cfg80211_rtw_auth, + //.assoc = cfg80211_rtw_assoc, +#endif //CONFIG_AP_MODE + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + .set_monitor_channel = cfg80211_rtw_set_monitor_channel, +#endif + +#ifdef CONFIG_P2P + .remain_on_channel = cfg80211_rtw_remain_on_channel, + .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel, +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, +#elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) + .action = cfg80211_rtw_mgmt_tx, +#endif + +#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + .tdls_mgmt = cfg80211_rtw_tdls_mgmt, + .tdls_oper = cfg80211_rtw_tdls_oper, +#endif /* CONFIG_TDLS */ + +#if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) + .sched_scan_start = cfg80211_rtw_sched_scan_start, + .sched_scan_stop = cfg80211_rtw_sched_scan_stop, +#endif /* CONFIG_PNO_SUPPORT */ +}; + +struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev) +{ + struct wiphy *wiphy; + struct rtw_wiphy_data *wiphy_data; + + /* wiphy */ + wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*)); + if (!wiphy) { + DBG_8192C("Couldn't allocate wiphy device\n"); + goto exit; + } + set_wiphy_dev(wiphy, dev); + *((_adapter**)wiphy_priv(wiphy)) = padapter; + + rtw_cfg80211_preinit_wiphy(padapter, wiphy); + + DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + +exit: + return wiphy; +} + +void rtw_wiphy_free(struct wiphy *wiphy) +{ + if (!wiphy) + return; + + DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_2GHZ]); + wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; + } + if (wiphy->bands[IEEE80211_BAND_5GHZ]) { + rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_5GHZ]); + wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + } + + wiphy_free(wiphy); +} + +int rtw_wiphy_register(struct wiphy *wiphy) +{ + DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + rtw_cfgvendor_attach(wiphy); +#endif + + return wiphy_register(wiphy); +} + +void rtw_wiphy_unregister(struct wiphy *wiphy) +{ + DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy)); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + rtw_cfgvendor_detach(wiphy); +#endif + + return wiphy_unregister(wiphy); +} + +int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy) +{ + int ret = 0; + struct net_device *pnetdev = padapter->pnetdev; + struct wireless_dev *wdev; + struct rtw_wdev_priv *pwdev_priv; + + DBG_8192C("%s(padapter=%p)\n", __func__, padapter); + + /* wdev */ + wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev)); + if (!wdev) { + DBG_8192C("Couldn't allocate wireless device\n"); + ret = -ENOMEM; + goto exit; + } + wdev->wiphy = wiphy; + wdev->netdev = pnetdev; + + wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init() + // Must sync with _rtw_init_mlme_priv() + // pmlmepriv->fw_state = WIFI_STATION_STATE + //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface() + padapter->rtw_wdev = wdev; + pnetdev->ieee80211_ptr = wdev; + + //init pwdev_priv + pwdev_priv = adapter_wdev_data(padapter); + pwdev_priv->rtw_wdev = wdev; + pwdev_priv->pmon_ndev = NULL; + pwdev_priv->ifname_mon[0] = '\0'; + pwdev_priv->padapter = padapter; + pwdev_priv->scan_request = NULL; + _rtw_spinlock_init(&pwdev_priv->scan_req_lock); + + pwdev_priv->p2p_enabled = _FALSE; + pwdev_priv->provdisc_req_issued = _FALSE; + rtw_wdev_invit_info_init(&pwdev_priv->invit_info); + rtw_wdev_nego_info_init(&pwdev_priv->nego_info); + + pwdev_priv->bandroid_scan = _FALSE; + + if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE) + pwdev_priv->power_mgmt = _TRUE; + else + pwdev_priv->power_mgmt = _FALSE; + +#ifdef CONFIG_CONCURRENT_MODE + ATOMIC_SET(&pwdev_priv->switch_ch_to, 1); + ATOMIC_SET(&pwdev_priv->ro_ch_to, 1); +#endif + +exit: + return ret; +} + +void rtw_wdev_free(struct wireless_dev *wdev) +{ + DBG_8192C("%s(wdev=%p)\n", __func__, wdev); + + if (!wdev) + return; + + rtw_mfree((u8*)wdev, sizeof(struct wireless_dev)); +} + +void rtw_wdev_unregister(struct wireless_dev *wdev) +{ + struct net_device *ndev; + _adapter *adapter; + struct rtw_wdev_priv *pwdev_priv; + + DBG_8192C("%s(wdev=%p)\n", __func__, wdev); + + if (!wdev) + return; + + if(!(ndev = wdev_to_ndev(wdev))) + return; + + adapter = (_adapter *)rtw_netdev_priv(ndev); + pwdev_priv = adapter_wdev_data(adapter); + + rtw_cfg80211_indicate_scan_done(adapter, _TRUE); + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) || defined(COMPAT_KERNEL_RELEASE) + if (wdev->current_bss) { + DBG_871X(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter)); + cfg80211_disconnected(adapter->pnetdev, 0, NULL, 0, GFP_ATOMIC); + } + #endif + + if (pwdev_priv->pmon_ndev) { + DBG_8192C("%s, unregister monitor interface\n", __func__); + unregister_netdev(pwdev_priv->pmon_ndev); + } +} + +int rtw_cfg80211_ndev_res_alloc(_adapter *adapter) +{ + int ret = _FAIL; + +#if !defined(RTW_SINGLE_WIPHY) + struct wiphy *wiphy; + struct device *dev = dvobj_to_dev(adapter_to_dvobj(adapter)); + + wiphy = rtw_wiphy_alloc(adapter, dev); + if (wiphy == NULL) + goto exit; + + adapter->wiphy = wiphy; +#endif + + if (rtw_wdev_alloc(adapter, adapter_to_wiphy(adapter)) == 0) + ret = _SUCCESS; + +#if !defined(RTW_SINGLE_WIPHY) + if (ret != _SUCCESS) { + rtw_wiphy_free(wiphy); + adapter->wiphy = NULL; + } +#endif + +exit: + return ret; +} + +void rtw_cfg80211_ndev_res_free(_adapter *adapter) +{ + rtw_wdev_free(adapter->rtw_wdev); +#if !defined(RTW_SINGLE_WIPHY) + rtw_wiphy_free(adapter_to_wiphy(adapter)); + adapter->wiphy = NULL; +#endif +} + +int rtw_cfg80211_ndev_res_register(_adapter *adapter) +{ + int ret = _FAIL; + +#if !defined(RTW_SINGLE_WIPHY) + if (rtw_wiphy_register(adapter_to_wiphy(adapter)) < 0) { + DBG_871X("%s rtw_wiphy_register fail for if%d\n", __func__, (adapter->iface_id+1)); + goto exit; + } +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +void rtw_cfg80211_ndev_res_unregister(_adapter *adapter) +{ + rtw_wdev_unregister(adapter->rtw_wdev); +} + +int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj) +{ + int ret = _FAIL; + +#if defined(RTW_SINGLE_WIPHY) + struct wiphy *wiphy; + struct device *dev = dvobj_to_dev(dvobj); + + wiphy = rtw_wiphy_alloc(dvobj->padapters[IFACE_ID0], dev); + if (wiphy == NULL) + goto exit; + + dvobj->wiphy = wiphy; +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj) +{ +#if defined(RTW_SINGLE_WIPHY) + rtw_wiphy_free(dvobj_to_wiphy(dvobj)); + dvobj->wiphy = NULL; +#endif +} + +int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj) +{ + int ret = _FAIL; + +#if defined(RTW_SINGLE_WIPHY) + if (rtw_wiphy_register(dvobj_to_wiphy(dvobj)) != 0) + goto exit; +#endif + + ret = _SUCCESS; + +exit: + return ret; +} + +void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj) +{ +#if defined(RTW_SINGLE_WIPHY) + rtw_wiphy_unregister(dvobj_to_wiphy(dvobj)); +#endif +} + +#endif /* CONFIG_IOCTL_CFG80211 */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.h b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.h new file mode 100644 index 00000000..9b483c61 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_cfg80211.h @@ -0,0 +1,212 @@ +/****************************************************************************** + * + * 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 block_scan; + bool power_mgmt; + + /* report mgmt_frame registered */ + u16 report_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) +#define wdev_to_wiphy(w) ((w)->wiphy) +#define ndev_to_wdev(n) ((n)->ieee80211_ptr) + +#define WIPHY_FMT "%s" +#define WIPHY_ARG(wiphy) wiphy_name(wiphy) +#define FUNC_WIPHY_FMT "%s("WIPHY_FMT")" +#define FUNC_WIPHY_ARG(wiphy) __func__, WIPHY_ARG(wiphy) + +#define SET_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt |= (v?BIT(t >> 4):0)) +#define GET_CFG80211_REPORT_MGMT(w, t) ((w->report_mgmt & BIT(t >> 4)) > 0) + +struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev); +void rtw_wiphy_free(struct wiphy *wiphy); +int rtw_wiphy_register(struct wiphy *wiphy); +void rtw_wiphy_unregister(struct wiphy *wiphy); + +int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy); +void rtw_wdev_free(struct wireless_dev *wdev); +void rtw_wdev_unregister(struct wireless_dev *wdev); + +int rtw_cfg80211_ndev_res_alloc(_adapter *adapter); +void rtw_cfg80211_ndev_res_free(_adapter *adapter); +int rtw_cfg80211_ndev_res_register(_adapter *adapter); +void rtw_cfg80211_ndev_res_unregister(_adapter *adapter); + +int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj); +void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj); +int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj); +void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj); + +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); +u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms); + +#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); +void rtw_cfg80211_rx_probe_request(_adapter *padapter, u8 *pmgmt_frame, uint frame_len); + +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) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3 , 18 , 0)) +#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) +#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) +#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/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_linux.c new file mode 100644 index 00000000..be281963 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_linux.c @@ -0,0 +1,13875 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _IOCTL_LINUX_C_ + +#include +#include +#include +#include "../../hal/phydm/phydm_precomp.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) +#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e) +#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e) +#endif + +#ifdef CONFIG_80211N_HT +extern int rtw_ht_enable; +#endif + + +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 + +#define SCAN_ITEM_SIZE 768 +#define MAX_CUSTOM_LEN 64 +#define RATE_COUNT 4 + +#ifdef CONFIG_GLOBAL_UI_PID +extern int ui_pid[3]; +#endif + +// combo scan +#define WEXT_CSCAN_AMOUNT 9 +#define WEXT_CSCAN_BUF_LEN 360 +#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" +#define WEXT_CSCAN_HEADER_SIZE 12 +#define WEXT_CSCAN_SSID_SECTION 'S' +#define WEXT_CSCAN_CHANNEL_SECTION 'C' +#define WEXT_CSCAN_NPROBE_SECTION 'N' +#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' +#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' +#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' +#define WEXT_CSCAN_TYPE_SECTION 'T' + + +extern u8 key_2char2num(u8 hch, u8 lch); +extern u8 str_2char2num(u8 hch, u8 lch); +extern void macstr2num(u8 *dst, u8 *src); +extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch); + +u32 rtw_rates[] = {1000000,2000000,5500000,11000000, + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; + +static const char * const iw_operation_mode[] = +{ + "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor" +}; + +static int hex2num_i(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex2byte_i(const char *hex) +{ + int a, b; + a = hex2num_i(*hex++); + if (a < 0) + return -1; + b = hex2num_i(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +/** + * hwaddr_aton - Convert ASCII string to MAC address + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +static int hwaddr_aton_i(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num_i(*txt++); + if (a < 0) + return -1; + b = hex2num_i(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + +static void indicate_wx_custom_event(_adapter *padapter, char *msg) +{ + u8 *buff, *p; + union iwreq_data wrqu; + + if (strlen(msg) > IW_CUSTOM_MAX) { + DBG_871X("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX); + return; + } + + buff = rtw_zmalloc(IW_CUSTOM_MAX+1); + if(!buff) + return; + + _rtw_memcpy(buff, msg, strlen(msg)); + + _rtw_memset(&wrqu,0,sizeof(wrqu)); + wrqu.data.length = strlen(msg); + + DBG_871X("%s %s\n", __FUNCTION__, buff); +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff); +#endif + + rtw_mfree(buff, IW_CUSTOM_MAX+1); + +} + + +static void request_wps_pbc_event(_adapter *padapter) +{ + u8 *buff, *p; + union iwreq_data wrqu; + + + buff = rtw_malloc(IW_CUSTOM_MAX); + if(!buff) + return; + + _rtw_memset(buff, 0, IW_CUSTOM_MAX); + + p=buff; + + p+=sprintf(p, "WPS_PBC_START.request=TRUE"); + + _rtw_memset(&wrqu,0,sizeof(wrqu)); + + wrqu.data.length = p-buff; + + wrqu.data.length = (wrqu.data.lengthpnetdev, IWEVCUSTOM, &wrqu, buff); +#endif + + if(buff) + { + rtw_mfree(buff, IW_CUSTOM_MAX); + } + +} + +#ifdef CONFIG_SUPPORT_HW_WPS_PBC +void rtw_request_wps_pbc_event(_adapter *padapter) +{ +#ifdef RTK_DMP_PLATFORM +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC); +#endif +#else + + if ( padapter->pid[0] == 0 ) + { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. + return; + } + + rtw_signal_process(padapter->pid[0], SIGUSR1); + +#endif + + rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON); +} +#endif//#ifdef CONFIG_SUPPORT_HW_WPS_PBC + +void indicate_wx_scan_complete_event(_adapter *padapter) +{ + union iwreq_data wrqu; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + //DBG_871X("+rtw_indicate_wx_scan_complete_event\n"); +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL); +#endif +} + + +void rtw_indicate_wx_assoc_event(_adapter *padapter) +{ + union iwreq_data wrqu; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) + _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN); + else + _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN); + + DBG_871X_LEVEL(_drv_always_, "assoc success\n"); +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); +#endif +} + +void rtw_indicate_wx_disassoc_event(_adapter *padapter) +{ + union iwreq_data wrqu; + + _rtw_memset(&wrqu, 0, sizeof(union iwreq_data)); + + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + +#ifndef CONFIG_IOCTL_CFG80211 + DBG_871X_LEVEL(_drv_always_, "indicate disassoc\n"); + wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); +#endif +} + +/* +uint rtw_is_cckrates_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || + (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) ) + return _TRUE; + i++; + } + + return _FALSE; +} + +uint rtw_is_cckratesonly_included(u8 *rate) +{ + u32 i = 0; + + while(rate[i]!=0) + { + if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && + (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) ) + return _FALSE; + i++; + } + + return _TRUE; +} +*/ + +static int search_p2p_wfd_ie(_adapter *padapter, + struct iw_request_info* info, struct wlan_network *pnetwork, + char *start, char *stop) +{ +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo = &padapter->wdinfo; +#ifdef CONFIG_WFD + if ( SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type ) + { + + } + else if ( ( SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type ) || + ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) ) +#endif // CONFIG_WFD + { + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + u32 blnGotP2PIE = _FALSE; + + // User is doing the P2P device discovery + // The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. + // If not, the driver should ignore this AP and go to the next AP. + + // Verifying the SSID + if ( _rtw_memcmp( pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ) ) + { + u32 p2pielen = 0; + + // Verifying the P2P IE + if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen)) + blnGotP2PIE = _TRUE; + } + + if ( blnGotP2PIE == _FALSE ) + { + return _FALSE; + } + + } + } + +#ifdef CONFIG_WFD + if ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) + { + u32 blnGotWFD = _FALSE; + u8 *wfd_ie; + uint wfd_ielen = 0; + + wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen); + if (wfd_ie) { + u8 *wfd_devinfo; + uint wfd_devlen; + + wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen); + if (wfd_devinfo) { + if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK ) + { + // the first two bits will indicate the WFD device type + if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_SOURCE ) + { + // If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. + blnGotWFD = _TRUE; + } + } + else if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE ) + { + // the first two bits will indicate the WFD device type + if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_PSINK ) + { + // If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. + // Todo: How about the SSink?! + blnGotWFD = _TRUE; + } + } + } + } + + if ( blnGotWFD == _FALSE ) + { + 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_SIGNAL_SCALE_MAPPING + iwe->u.qual.level = (u8)ss; /* % */ + #else + { + /* 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); + } + #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; + 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); + + /* 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); + + //parsing HT_CAP_IE + if (pnetwork->network.Reserved[0] == 2) // Probe Request + { + p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength); + } + else + { + p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12); + } + 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 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) + { + if(vht_cap == _TRUE) + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC"); + else 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); + + /* Add mode */ + if (pnetwork->network.Reserved[0] == 2) // Probe Request + { + cap = 0; + } + else + { + iwe.cmd = SIOCGIWMODE; + _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2); + cap = le16_to_cpu(cap); + } + + if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){ + 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); + } + + 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); + + /* 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); + + /*Add basic and extended rates */ + max_rate = 0; + 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++; + } + + if(vht_cap == _TRUE) { + max_rate = vht_data_rate; + } + else 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); + + //parsing WPA/WPA2 IE + if (pnetwork->network.Reserved[0] != 2) // Probe Request + { + u8 buf[MAX_WPA_IE_LEN*2]; + u8 wpa_ie[255],rsn_ie[255]; + u16 wpa_len=0,rsn_len=0; + u8 *p; + sint out_len=0; + 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) + { + p=buf; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2); + 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(buf); + start = iwe_stream_add_point(info, start, stop, &iwe,buf); + + _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) + { + p = buf; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2); + 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(buf); + start = iwe_stream_add_point(info, start, stop, &iwe,buf); + + _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); + } + } + + { //parsing WPS IE + uint cnt = 0,total_ielen; + u8 *wpsie_ptr=NULL; + uint wps_ielen = 0; + + 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 + } + } + +#ifdef CONFIG_WAPI_SUPPORT + 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]; + static u8 wapi_ie[MAX_WAPI_IE_LEN]; + u16 wapi_len=0; + u16 i; + + _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN); + _rtw_memset(wapi_ie, 0, MAX_WAPI_IE_LEN); + + 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 + +{ + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 ss, sq; + + /* 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_SIGNAL_SCALE_MAPPING + iwe.u.qual.level = (u8)ss; /* % */ + #else + { + /* 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); + } + #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); +} + + { + u8 buf[MAX_WPA_IE_LEN]; + u8 * p,*pos; + int len; + p = buf; + pos = pnetwork->network.Reserved; + _rtw_memset(buf, 0, MAX_WPA_IE_LEN); + 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; +} +#endif + +static int wpa_set_auth_algs(struct net_device *dev, u32 value) +{ + _adapter *padapter = (_adapter *) rtw_netdev_priv(dev); + int ret = 0; + + if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM)) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + } + else if (value & AUTH_ALG_SHARED_KEY) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n",value); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared; +#endif + } + else if(value & AUTH_ALG_OPEN_SYSTEM) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n"); + //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) + { +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; +#endif + } + + } + else if(value & AUTH_ALG_LEAP) + { + DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n"); + } + else + { + DBG_871X("wpa_set_auth_algs, error!\n"); + ret = -EINVAL; + } + + return ret; + +} + +static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + +_func_enter_; + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif //CONFIG_IEEE80211W + ) + { + ret = -EINVAL; + goto exit; + } + } + else + { +#ifdef CONFIG_WAPI_SUPPORT + if (strcmp(param->u.crypt.alg, "SMS4")) +#endif + { + ret = -EINVAL; + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "WEP") == 0) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n")); + DBG_871X("wpa_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) + { + ret = -EINVAL; + goto exit; + } + + if (psecuritypriv->bWepDefaultKeyIdxSet == 0) { + /* wep default key has not been set, so use this key index as default key.*/ + + wep_key_len = wep_key_len <= 5 ? 5 : 13; + + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + + if (wep_key_len == 13) + { + psecuritypriv->dot11PrivacyAlgrthm = _WEP104_; + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + } + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len; + + psecuritypriv->key_mask |= BIT(wep_key_idx); + + goto exit; + } + + if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x + { + struct sta_info * psta,*pbcmc_sta; + struct sta_priv * pstapriv = &padapter->stapriv; + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode + { + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + if (psta == NULL) { + //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + psta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + + if(param->u.crypt.set_tx ==1)//pairwise key + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key + { + //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + padapter->securitypriv.busetkipkey=_FALSE; + //_set_timer(&padapter->securitypriv.tkip_timer, 50); + } + + //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:unicastkey\n"); + + rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE); + + psta->bpairwise_key_installed = _TRUE; + + } + else//group key + { + if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + //only TKIP group key need to install this + if(param->u.crypt.key_len > 16) + { + _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8); + _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8); + } + padapter->securitypriv.binstallGrpkey = _TRUE; + //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); + DBG_871X(" ~~~~set sta key:groupkey\n"); + + padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx; + + rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE); + } +#ifdef CONFIG_IEEE80211W + else if(strcmp(param->u.crypt.alg, "BIP") == 0) + { + int no; + //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); + //save the IGTK key, length 16 bytes + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + /*printk("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + printk("\n");*/ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + } +#endif //CONFIG_IEEE80211W + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE); + } +#endif //CONFIG_P2P + + } + } + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta==NULL) + { + //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n")); + } + else + { + //Jeff: don't disable ieee8021x_blocked while clearing key + if (strcmp(param->u.crypt.alg, "none") != 0) + pbcmc_sta->ieee8021x_blocked = _FALSE; + + if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)|| + (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) + { + pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm; + } + } + } + else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode + { + } + } + +#ifdef CONFIG_WAPI_SUPPORT + if (strcmp(param->u.crypt.alg, "SMS4") == 0) + { + PRT_WAPI_T pWapiInfo = &padapter->wapiInfo; + PRT_WAPI_STA_INFO pWapiSta; + u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ; + + if(param->u.crypt.set_tx == 1) + { + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6)) + { + _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16); + + pWapiSta->wapiUsk.bSet = true; + _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16); + _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16); + pWapiSta->wapiUsk.keyId = param->u.crypt.idx ; + pWapiSta->wapiUsk.bTxEnable = true; + + _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16); + _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16); + pWapiSta->wapiUskUpdate.bTxEnable = false; + pWapiSta->wapiUskUpdate.bSet = false; + + if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false) + { + //set unicast key for ASUE + rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false); + } + } + } + } + else + { + list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) { + if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6)) + { + pWapiSta->wapiMsk.bSet = true; + _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16); + _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16); + pWapiSta->wapiMsk.keyId = param->u.crypt.idx ; + pWapiSta->wapiMsk.bTxEnable = false; + if(!pWapiSta->bSetkeyOk) + pWapiSta->bSetkeyOk = true; + pWapiSta->bAuthenticateInProgress = false; + + _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16); + + if (psecuritypriv->sw_decrypt == false) + { + //set rx broadcast key for ASUE + rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false); + } + } + + } + } + } +#endif + +exit: + +_func_exit_; + + return ret; +} + +static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen) +{ + u8 *buf=NULL, *pos=NULL; + u32 left; + int group_cipher = 0, pairwise_cipher = 0; + int ret = 0; + u8 null_addr[]= {0,0,0,0,0,0}; +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + + if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){ + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + if(pie == NULL) + return ret; + else + return -EINVAL; + } + + if(ielen) + { + buf = rtw_zmalloc(ielen); + if (buf == NULL){ + ret = -ENOMEM; + goto exit; + } + + _rtw_memcpy(buf, pie , ielen); + + //dump + { + int i; + DBG_871X("\n wpa_ie(length:%d):\n", ielen); + for(i=0;i= RSN_SELECTOR_LEN){ + pos += RSN_SELECTOR_LEN; + left -= RSN_SELECTOR_LEN; + } + else if (left > 0){ + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie length mismatch, %u too much \n", left)); + ret =-1; + goto exit; + } +#endif + + if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); + } + + if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) + { + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK; + _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen); + } + + if (group_cipher == 0) + { + group_cipher = WPA_CIPHER_NONE; + } + if (pairwise_cipher == 0) + { + pairwise_cipher = WPA_CIPHER_NONE; + } + + switch(group_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot118021XGrpPrivacy=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + switch(pairwise_cipher) + { + case WPA_CIPHER_NONE: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled; + break; + case WPA_CIPHER_WEP40: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + case WPA_CIPHER_TKIP: + padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case WPA_CIPHER_CCMP: + padapter->securitypriv.dot11PrivacyAlgrthm=_AES_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + case WPA_CIPHER_WEP104: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + break; + } + + _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS); + {//set wps_ie + u16 cnt = 0; + u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04}; + + while( cnt < ielen ) + { + eid = buf[cnt]; + + if((eid==_VENDOR_SPECIFIC_IE_)&&(_rtw_memcmp(&buf[cnt+2], wps_oui, 4)==_TRUE)) + { + DBG_871X("SET WPS_IE\n"); + + padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN; + + _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len); + + set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS); + +#ifdef CONFIG_P2P + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK)) + { + rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING); + } +#endif //CONFIG_P2P + cnt += buf[cnt+1]+2; + + break; + } else { + cnt += buf[cnt+1]+2; //goto next + } + } + } + } + + //TKIP and AES disallow multicast packets until installing group key + if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ + || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) + //WPS open need to enable multicast + //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) + rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr); + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n", + pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype)); + +exit: + + if (buf) rtw_mfree(buf, ielen); + + return ret; +} + +static int rtw_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u16 cap; + u32 ht_ielen = 0; + char *p; + u8 ht_cap=_FALSE, vht_cap=_FALSE; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + NDIS_802_11_RATES_EX* prates = NULL; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd)); + + _func_enter_; + + if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) + { + //parsing HT_CAP_IE + p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12); + if(p && ht_ielen>0) + { + ht_cap = _TRUE; + } + +#ifdef CONFIG_80211AC_VHT + if(pmlmepriv->vhtpriv.vht_option == _TRUE) + vht_cap = _TRUE; +#endif + + prates = &pcur_bss->SupportedRates; + + if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b"); + } + else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE) + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg"); + } + else + { + if(pcur_bss->Configuration.DSConfig > 14) + { + #ifdef CONFIG_80211AC_VHT + if(vht_cap == _TRUE){ + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC"); + } + else + #endif + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a"); + } + } + else + { + if(ht_cap == _TRUE) + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn"); + else + snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); + } + } + } + else + { + //prates = &padapter->registrypriv.dev_network.SupportedRates; + //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); + snprintf(wrqu->name, IFNAMSIZ, "unassociated"); + } + + _func_exit_; + + return 0; +} + +static int rtw_wx_set_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + int exp = 1, freq = 0, div = 0; + + _func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n")); + + if (wrqu->freq.m <= 1000) { + if (wrqu->freq.flags == IW_FREQ_AUTO) { + if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, wrqu->freq.m) > 0) { + padapter->mlmeextpriv.cur_channel = wrqu->freq.m; + DBG_871X("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m); + } else { + padapter->mlmeextpriv.cur_channel = 1; + DBG_871X("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__); + } + } else { + padapter->mlmeextpriv.cur_channel = wrqu->freq.m; + DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel); + } + } else { + while (wrqu->freq.e) { + exp *= 10; + wrqu->freq.e--; + } + + freq = wrqu->freq.m; + + while (!(freq%10)) { + freq /= 10; + exp *= 10; + } + + /* freq unit is MHz here */ + div = 1000000/exp; + + if (div) + freq /= div; + else { + div = exp/1000000; + freq *= div; + } + + /* If freq is invalid, rtw_freq2ch() will return channel 1 */ + padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq); + DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel); + } + + set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + + _func_exit_; + + return 0; +} + +static int rtw_wx_get_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) { + + wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000; + wrqu->freq.e = 1; + wrqu->freq.i = pcur_bss->Configuration.DSConfig; + + } else { + wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000; + wrqu->freq.e = 1; + wrqu->freq.i = padapter->mlmeextpriv.cur_channel; + } + + return 0; +} + +static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ; + int ret = 0; + + _func_enter_; + + if(_FAIL == rtw_pwr_wakeup(padapter)) { + ret= -EPERM; + goto exit; + } + + if (!rtw_is_hw_init_completed(padapter)) { + ret = -EPERM; + goto exit; + } + + /* initial default type */ + dev->type = ARPHRD_ETHER; + + switch(wrqu->mode) + { + case IW_MODE_MONITOR: + networkType = Ndis802_11Monitor; +#if 0 + dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */ +#endif + dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */ + DBG_871X("set_mode = IW_MODE_MONITOR\n"); + break; + + case IW_MODE_AUTO: + networkType = Ndis802_11AutoUnknown; + DBG_871X("set_mode = IW_MODE_AUTO\n"); + break; + case IW_MODE_ADHOC: + networkType = Ndis802_11IBSS; + DBG_871X("set_mode = IW_MODE_ADHOC\n"); + break; + case IW_MODE_MASTER: + networkType = Ndis802_11APMode; + DBG_871X("set_mode = IW_MODE_MASTER\n"); + //rtw_setopmode_cmd(padapter, networkType,_TRUE); + break; + case IW_MODE_INFRA: + networkType = Ndis802_11Infrastructure; + DBG_871X("set_mode = IW_MODE_INFRA\n"); + break; + + default : + ret = -EINVAL;; + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode])); + goto exit; + } + +/* + if(Ndis802_11APMode == networkType) + { + rtw_setopmode_cmd(padapter, networkType,_TRUE); + } + else + { + rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE); + } +*/ + + if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){ + + ret = -EPERM; + goto exit; + + } + + rtw_setopmode_cmd(padapter, networkType,_TRUE); + + if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) + rtw_indicate_connect(padapter); + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n")); + + _func_enter_; + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) + { + wrqu->mode = IW_MODE_INFRA; + } + else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) + + { + wrqu->mode = IW_MODE_ADHOC; + } + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + wrqu->mode = IW_MODE_MASTER; + } else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) + wrqu->mode = IW_MODE_MONITOR; + else + wrqu->mode = IW_MODE_AUTO; + + _func_exit_; + + return 0; + +} + + +static int rtw_wx_set_pmkid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 j,blInserted = _FALSE; + int intReturn = _FALSE; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct iw_pmksa* pPMK = ( struct iw_pmksa* ) extra; + u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 }; + u8 strIssueBssid[ ETH_ALEN ] = { 0x00 }; + +/* + struct iw_pmksa + { + __u32 cmd; + struct sockaddr bssid; + __u8 pmkid[IW_PMKID_LEN]; //IW_PMKID_LEN=16 + } + There are the BSSID information in the bssid.sa_data array. + If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information. + If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver. + If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver. + */ + + _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); + if ( pPMK->cmd == IW_PMKSA_ADD ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" ); + if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE ) + { + return( intReturn ); + } + else + { + intReturn = _TRUE; + } + blInserted = _FALSE; + + //overwrite PMKID + for(j=0 ; jPMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE ) + { // BSSID is matched, the same AP => rewrite with new PMKID. + + DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" ); + + _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); + psecuritypriv->PMKIDList[ j ].bUsed = _TRUE; + psecuritypriv->PMKIDIndex = j+1; + blInserted = _TRUE; + break; + } + } + + if(!blInserted) + { + // Find a new entry + DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n", + psecuritypriv->PMKIDIndex ); + + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); + _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); + + psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE; + psecuritypriv->PMKIDIndex++ ; + if(psecuritypriv->PMKIDIndex==16) + { + psecuritypriv->PMKIDIndex =0; + } + } + } + else if ( pPMK->cmd == IW_PMKSA_REMOVE ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" ); + intReturn = _TRUE; + for(j=0 ; jPMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE ) + { // BSSID is matched, the same AP => Remove this PMKID information and reset it. + _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN ); + psecuritypriv->PMKIDList[ j ].bUsed = _FALSE; + break; + } + } + } + else if ( pPMK->cmd == IW_PMKSA_FLUSH ) + { + DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" ); + _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + psecuritypriv->PMKIDIndex = 0; + intReturn = _TRUE; + } + return( intReturn ); +} + +static int rtw_wx_get_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + #ifdef CONFIG_PLATFORM_ROCKCHIPS + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + /* + * 20110311 Commented by Jeff + * For rockchip platform's wpa_driver_wext_get_rssi + */ + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + //wrqu->sens.value=-padapter->recvpriv.signal_strength; + wrqu->sens.value=-padapter->recvpriv.rssi; + //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value); + wrqu->sens.fixed = 0; /* no auto select */ + } else + #endif + { + wrqu->sens.value = 0; + wrqu->sens.fixed = 0; /* no auto select */ + wrqu->sens.disabled = 1; + } + return 0; +} + +static int rtw_wx_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + u16 val; + int i; + + _func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd)); + + wrqu->data.length = sizeof(*range); + _rtw_memset(range, 0, sizeof(*range)); + + /* Let's try to keep this struct in the same order as in + * linux/include/wireless.h + */ + + /* TODO: See what values we can set, and remove the ones we can't + * set, or fill them with some default data. + */ + + /* ~5 Mb/s real (802.11b) */ + range->throughput = 5 * 1000 * 1000; + + // TODO: Not used in 802.11b? +// range->min_nwid; /* Minimal NWID we are able to set */ + // TODO: Not used in 802.11b? +// range->max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ +// range->old_num_channels; +// range->old_num_frequency; +// range->old_freq[6]; /* Filler to keep "version" at the same offset */ + + /* signal level threshold range */ + + /* Quality of link & SNR stuff */ + /* Quality range (link, level, noise) + * If the quality is absolute, it will be in the range [0 ; max_qual], + * if the quality is dBm, it will be in the range [max_qual ; 0]. + * Don't forget that we use 8 bit arithmetics... + * + * If percentage range is 0~100 + * Signal strength dbm range logical is -100 ~ 0 + * but usually value is -90 ~ -20 + * When CONFIG_SIGNAL_SCALE_MAPPING is defined, dbm range is -95 ~ -45 + */ + range->max_qual.qual = 100; +#ifdef CONFIG_SIGNAL_DISPLAY_DBM + range->max_qual.level = (u8)-100; + range->max_qual.noise = (u8)-100; + range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */ + range->max_qual.updated |= IW_QUAL_DBM; +#else /* !CONFIG_SIGNAL_DISPLAY_DBM */ + //percent values between 0 and 100. + range->max_qual.level = 100; + range->max_qual.noise = 100; + range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */ +#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */ + + /* This should contain the average/typical values of the quality + * indicator. This should be the threshold between a "good" and + * a "bad" link (example : monitor going from green to orange). + * Currently, user space apps like quality monitors don't have any + * way to calibrate the measurement. With this, they can split + * the range between 0 and max_qual in different quality level + * (using a geometric subdivision centered on the average). + * I expect that people doing the user space apps will feedback + * us on which value we need to put in each driver... */ + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ +#ifdef CONFIG_SIGNAL_DISPLAY_DBM + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ + range->avg_qual.level = (u8)-70; + range->avg_qual.noise = 0; + range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */ + range->avg_qual.updated |= IW_QUAL_DBM; +#else /* !CONFIG_SIGNAL_DISPLAY_DBM */ + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + range->avg_qual.level = 30; + range->avg_qual.noise = 100; + range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */ +#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */ + + range->num_bitrates = RATE_COUNT; + + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { + range->bitrate[i] = rtw_rates[i]; + } + + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + range->pm_capa = 0; + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 16; + +// range->retry_capa; /* What retry options are supported */ +// range->retry_flags; /* How to decode max/min retry limit */ +// range->r_time_flags; /* How to decode max/min retry life */ +// range->min_retry; /* Minimal number of retries */ +// range->max_retry; /* Maximal number of retries */ +// range->min_r_time; /* Minimal retry lifetime */ +// range->max_r_time; /* Maximal retry lifetime */ + + for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) { + + // Include only legal frequencies for some countries + if(pmlmeext->channel_set[i].ChannelNum != 0) + { + range->freq[val].i = pmlmeext->channel_set[i].ChannelNum; + range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000; + range->freq[val].e = 1; + val++; + } + + if (val == IW_MAX_FREQUENCIES) + break; + } + + range->num_channels = val; + range->num_frequency = val; + +// Commented by Albert 2009/10/13 +// The following code will proivde the security capability to network manager. +// If the driver doesn't provide this capability to network manager, +// the WPA/WPA2 routers can't be choosen in the network manager. + +/* +#define IW_SCAN_CAPA_NONE 0x00 +#define IW_SCAN_CAPA_ESSID 0x01 +#define IW_SCAN_CAPA_BSSID 0x02 +#define IW_SCAN_CAPA_CHANNEL 0x04 +#define IW_SCAN_CAPA_MODE 0x08 +#define IW_SCAN_CAPA_RATE 0x10 +#define IW_SCAN_CAPA_TYPE 0x20 +#define IW_SCAN_CAPA_TIME 0x40 +*/ + +#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| + IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; +#endif + +#ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21 + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID| + IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE; +#endif + + + _func_exit_; + + return 0; + +} + +//set bssid flow +//s1. rtw_set_802_11_infrastructure_mode() +//s2. rtw_set_802_11_authentication_mode() +//s3. set_802_11_encryption_mode() +//s4. rtw_set_802_11_bssid() +static int rtw_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + _irqL irqL; + uint ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sockaddr *temp = (struct sockaddr *)awrq; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _list *phead; + u8 *dst_bssid, *src_bssid; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + + _func_enter_; +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_871X("set bssid, but buddy_intf is under scanning or linking\n"); + + ret = -EINVAL; + + goto exit; + } +#endif + + rtw_ps_deny(padapter, PS_DENY_JOIN); + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret= -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + + + if (temp->sa_family != ARPHRD_ETHER){ + ret = -EINVAL; + goto exit; + } + + authmode = padapter->securitypriv.ndisauthtype; + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + pmlmepriv->pscanned = get_next(phead); + + while (1) + { + + if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) + { +#if 0 + ret = -EINVAL; + goto exit; + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + rtw_set_802_11_bssid(padapter, temp->sa_data); + goto exit; + } + else + { + ret = -EINVAL; + goto exit; + } +#endif + + break; + } + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + dst_bssid = pnetwork->network.MacAddress; + + src_bssid = temp->sa_data; + + if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) + { + if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) + { + ret = -1; + _exit_critical_bh(&queue->lock, &irqL); + goto exit; + } + + break; + } + + } + _exit_critical_bh(&queue->lock, &irqL); + + rtw_set_802_11_authentication_mode(padapter, authmode); + //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) { + ret = -1; + goto exit; + } + +exit: + + rtw_ps_deny_cancel(padapter, PS_DENY_JOIN); + + _func_exit_; + + return ret; +} + +static int rtw_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + + _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n")); + + _func_enter_; + + if ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) || + ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) || + ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) ) + { + + _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN); + } + else + { + _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); + } + + _func_exit_; + + return 0; + +} + +static int rtw_wx_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#if 0 +/* SIOCSIWMLME data */ +struct iw_mlme +{ + __u16 cmd; /* IW_MLME_* */ + __u16 reason_code; + struct sockaddr addr; +}; +#endif + + int ret=0; + u16 reason; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_mlme *mlme = (struct iw_mlme *) extra; + + + if(mlme==NULL) + return -1; + + DBG_871X("%s\n", __FUNCTION__); + + reason = cpu_to_le16(mlme->reason_code); + + + DBG_871X("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason); + + + switch (mlme->cmd) + { + case IW_MLME_DEAUTH: + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + break; + + case IW_MLME_DISASSOC: + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + default: + return -EOPNOTSUPP; + } + + return ret; +} + +static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + u8 _status = _FALSE; + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; + _irqL irqL; +#ifdef CONFIG_P2P + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif //CONFIG_P2P + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n")); + +_func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -1; + goto exit; + } +#endif +*/ +#ifdef CONFIG_MP_INCLUDED + if (padapter->registrypriv.mp_mode == 1) + { + DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter)); + ret = -1; + goto exit; + } +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) { + if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1) + { + DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter)); + ret = -1; + goto exit; + } + } +#endif //CONFIG_CONCURRENT_MODE +#endif + + rtw_ps_deny(padapter, PS_DENY_SCAN); + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret= -1; + goto exit; + } + + if (rtw_is_drv_stopped(padapter)) { + DBG_871X("%s bDriverStopped=_TRUE\n", __func__); + ret= -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + + if (!rtw_is_hw_init_completed(padapter)) { + ret = -1; + goto exit; + } + +#ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC + // When Busy Traffic, driver do not site survey. So driver return success. + // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. + // modify by thomas 2011-02-22. + if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE +#ifdef CONFIG_CONCURRENT_MODE + || rtw_get_buddy_bBusyTraffic(padapter) == _TRUE +#endif //CONFIG_CONCURRENT_MODE + ) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } +#endif + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, + _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) + { + indicate_wx_scan_complete_event(padapter); + goto exit; + } +#endif + +#ifdef CONFIG_P2P + if ( pwdinfo->p2p_state != P2P_STATE_NONE ) + { + rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL); + rtw_free_network_queue(padapter, _TRUE); + } +#endif //CONFIG_P2P + + _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT); + +#if WIRELESS_EXT >= 17 + if (wrqu->data.length == sizeof(struct iw_scan_req)) + { + struct iw_scan_req *req = (struct iw_scan_req *)extra; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) + { + int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE); + + _rtw_memcpy(ssid[0].Ssid, req->essid, len); + ssid[0].SsidLength = len; + + DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + + _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0); + + _exit_critical_bh(&pmlmepriv->lock, &irqL); + + } + else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) + { + DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); + } + + } + else +#endif + + if( wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE + && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE + ) + { + int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE; + char *pos = extra+WEXT_CSCAN_HEADER_SIZE; + char section; + char sec_len; + int ssid_index = 0; + + //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__); + + while(len >= 1) { + section = *(pos++); len-=1; + + switch(section) { + case WEXT_CSCAN_SSID_SECTION: + //DBG_871X("WEXT_CSCAN_SSID_SECTION\n"); + if(len < 1) { + len = 0; + break; + } + + sec_len = *(pos++); len-=1; + + if(sec_len>0 && sec_len<=len) { + ssid[ssid_index].SsidLength = sec_len; + _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); + //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__ + // , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength); + ssid_index++; + } + + pos+=sec_len; len-=sec_len; + break; + + + case WEXT_CSCAN_CHANNEL_SECTION: + //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n"); + pos+=1; len-=1; + break; + case WEXT_CSCAN_ACTV_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_PASV_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_HOME_DWELL_SECTION: + //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n"); + pos+=2; len-=2; + break; + case WEXT_CSCAN_TYPE_SECTION: + //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n"); + pos+=1; len-=1; + break; + #if 0 + case WEXT_CSCAN_NPROBE_SECTION: + DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n"); + break; + #endif + + default: + //DBG_871X("Unknown CSCAN section %c\n", section); + len = 0; // stop parsing + } + //DBG_871X("len:%d\n", len); + + } + + //jeff: it has still some scan paramater to parse, we only do this now... + _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT); + + } else + + { + _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0); + } + + if(_status == _FALSE) + ret = -1; + +exit: + + rtw_ps_deny_cancel(padapter, PS_DENY_SCAN); + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + +_func_exit_; + + return ret; +} + +static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _irqL irqL; + _list *plist, *phead; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + char *ev = extra; + char *stop = ev + wrqu->data.length; + u32 ret = 0; + u32 cnt=0; + u32 wait_for_surveydone; + sint wait_status; +#ifdef CONFIG_CONCURRENT_MODE + //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter; + //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); +#endif +#ifdef CONFIG_P2P + struct wifidirect_info* pwdinfo = &padapter->wdinfo; +#endif //CONFIG_P2P + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n")); + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n")); + + _func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) { + ret = -EINVAL; + goto exit; + } + +#ifdef CONFIG_P2P + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + wait_for_surveydone = 200; + } + else + { + // P2P is disabled + wait_for_surveydone = 100; + } +#else + { + wait_for_surveydone = 100; + } +#endif //CONFIG_P2P + +#if 1 // Wireless Extension use EAGAIN to try + wait_status = _FW_UNDER_SURVEY +#ifndef CONFIG_ANDROID + | _FW_UNDER_LINKING +#endif + ; + + while (check_fwstate(pmlmepriv, wait_status) == _TRUE) + { + return -EAGAIN; + } +#else + wait_status = _FW_UNDER_SURVEY + #ifndef CONFIG_ANDROID + |_FW_UNDER_LINKING + #endif + ; + + while(check_fwstate(pmlmepriv, wait_status) == _TRUE) + { + rtw_msleep_os(30); + cnt++; + if(cnt > wait_for_surveydone ) + break; + } +#endif + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + if((stop - ev) < SCAN_ITEM_SIZE) { + ret = -E2BIG; + break; + } + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //report network only if the current channel set contains the channel to which this network belongs + if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0 + && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE + && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid)) + ) + { + ev=translate_scan(padapter, a, pnetwork, ev, stop); + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + wrqu->data.length = ev-extra; + wrqu->data.flags = 0; + +exit: + + _func_exit_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + + return ret ; + +} + +//set ssid flow +//s1. rtw_set_802_11_infrastructure_mode() +//s2. set_802_11_authenticaion_mode() +//s3. set_802_11_encryption_mode() +//s4. rtw_set_802_11_ssid() +static int rtw_wx_set_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + _irqL irqL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _queue *queue = &pmlmepriv->scanned_queue; + _list *phead; + s8 status = _TRUE; + struct wlan_network *pnetwork = NULL; + NDIS_802_11_AUTHENTICATION_MODE authmode; + NDIS_802_11_SSID ndis_ssid; + u8 *dst_ssid, *src_ssid; + + uint ret = 0, len; + + _func_enter_; + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__); + #endif + #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID + DBG_871X("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__); + return -EPERM; + #endif +/* +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->iface_type > PRIMARY_IFACE) + { + ret = -EINVAL; + goto exit; + } +#endif +*/ + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) + { + DBG_871X("set ssid, but buddy_intf is under scanning or linking\n"); + + ret = -EINVAL; + + goto exit; + } +#endif + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv))); + + rtw_ps_deny(padapter, PS_DENY_JOIN); + if(_FAIL == rtw_pwr_wakeup(padapter)) + { + ret = -1; + goto exit; + } + + if(!padapter->bup){ + ret = -1; + goto exit; + } + +#if WIRELESS_EXT <= 20 + if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){ +#else + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ +#endif + ret= -E2BIG; + goto exit; + } + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + ret = -1; + goto exit; + } + + authmode = padapter->securitypriv.ndisauthtype; + DBG_871X("=>%s\n",__FUNCTION__); + if (wrqu->essid.flags && wrqu->essid.length) + { + // Commented by Albert 20100519 + // We got the codes in "set_info" function of iwconfig source code. + // ========================================= + // wrq.u.essid.length = strlen(essid) + 1; + // if(we_kernel_version > 20) + // wrq.u.essid.length--; + // ========================================= + // That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. +#if WIRELESS_EXT <= 20 + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; +#else + len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE; +#endif + + if( wrqu->essid.length != 33 ) + DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length); + + _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID)); + ndis_ssid.SsidLength = len; + _rtw_memcpy(ndis_ssid.Ssid, extra, len); + src_ssid = ndis_ssid.Ssid; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid)); + _enter_critical_bh(&queue->lock, &irqL); + phead = get_list_head(queue); + pmlmepriv->pscanned = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) + { +#if 0 + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + rtw_set_802_11_ssid(padapter, &ndis_ssid); + + goto exit; + } + else + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n")); + ret = -EINVAL; + goto exit; + } +#endif + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_, + ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n")); + + break; + } + + pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); + + pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); + + dst_ssid = pnetwork->network.Ssid.Ssid; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_wx_set_essid: dst_ssid=%s\n", + pnetwork->network.Ssid.Ssid)); + + if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) && + (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength)) + { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_wx_set_essid: find match, set infra mode\n")); + + if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) + { + if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode) + continue; + } + + if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE) + { + ret = -1; + _exit_critical_bh(&queue->lock, &irqL); + goto exit; + } + + break; + } + } + _exit_critical_bh(&queue->lock, &irqL); + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("set ssid: set_802_11_auth. mode=%d\n", authmode)); + rtw_set_802_11_authentication_mode(padapter, authmode); + //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); + if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) { + ret = -1; + goto exit; + } + } + +exit: + + rtw_ps_deny_cancel(padapter, PS_DENY_JOIN); + + DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret); + + #ifdef DBG_IOCTL + DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret); + #endif + + _func_exit_; + + return ret; +} + +static int rtw_wx_get_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + u32 len,ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n")); + + _func_enter_; + + if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) + { + len = pcur_bss->Ssid.SsidLength; + + wrqu->essid.length = len; + + _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len); + + wrqu->essid.flags = 1; + } + else + { + ret = -1; + goto exit; + } + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_set_rate(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) +{ + int i, ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 datarates[NumRates]; + u32 target_rate = wrqu->bitrate.value; + u32 fixed = wrqu->bitrate.fixed; + u32 ratevalue = 0; + u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; + +_func_enter_; + + RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n")); + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed)); + + if(target_rate == -1){ + ratevalue = 11; + goto set_rate; + } + target_rate = target_rate/100000; + + switch(target_rate){ + case 10: + ratevalue = 0; + break; + case 20: + ratevalue = 1; + break; + case 55: + ratevalue = 2; + break; + case 60: + ratevalue = 3; + break; + case 90: + ratevalue = 4; + break; + case 110: + ratevalue = 5; + break; + case 120: + ratevalue = 6; + break; + case 180: + ratevalue = 7; + break; + case 240: + ratevalue = 8; + break; + case 360: + ratevalue = 9; + break; + case 480: + ratevalue = 10; + break; + case 540: + ratevalue = 11; + break; + default: + ratevalue = 11; + break; + } + +set_rate: + + for(i=0; ibitrate.fixed = 0; /* no auto select */ + wrqu->bitrate.value = max_rate * 100000; + + return 0; +} + +static int rtw_wx_set_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + if (wrqu->rts.disabled) + padapter->registrypriv.rts_thresh = 2347; + else { + if (wrqu->rts.value < 0 || + wrqu->rts.value > 2347) + return -EINVAL; + + padapter->registrypriv.rts_thresh = wrqu->rts.value; + } + + DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh); + + _func_exit_; + + return 0; + +} + +static int rtw_wx_get_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh); + + wrqu->rts.value = padapter->registrypriv.rts_thresh; + wrqu->rts.fixed = 0; /* no auto select */ + //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); + + _func_exit_; + + return 0; +} + +static int rtw_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + if (wrqu->frag.disabled) + padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; + else { + if (wrqu->frag.value < MIN_FRAG_THRESHOLD || + wrqu->frag.value > MAX_FRAG_THRESHOLD) + return -EINVAL; + + padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; + } + + DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len); + + _func_exit_; + + return 0; + +} + +static int rtw_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + _func_enter_; + + DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len); + + wrqu->frag.value = padapter->xmitpriv.frag_len; + wrqu->frag.fixed = 0; /* no auto select */ + //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); + + _func_exit_; + + return 0; +} + +static int rtw_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + + wrqu->retry.value = 7; + wrqu->retry.fixed = 0; /* no auto select */ + wrqu->retry.disabled = 1; + + return 0; + +} + +#if 0 +#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ +#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ +#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ +#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ +#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ +#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ +#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ +/* +iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto +iwconfig wlan0 key off -> flags = 0x8800 +iwconfig wlan0 key open -> flags = 0x2800 +iwconfig wlan0 key open 1234567890 -> flags = 0x2000 +iwconfig wlan0 key restricted -> flags = 0x4800 +iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003 +iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002 +iwconfig wlan0 key open [3] -> flags = 0x2803 +iwconfig wlan0 key restricted [2] -> flags = 0x4802 +*/ +#endif + +static int rtw_wx_set_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + u32 key, ret = 0; + u32 keyindex_provided; + NDIS_802_11_WEP wep; + NDIS_802_11_AUTHENTICATION_MODE authmode; + + struct iw_point *erq = &(wrqu->encoding); + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags); + + _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP)); + + key = erq->flags & IW_ENCODE_INDEX; + + _func_enter_; + + if (erq->flags & IW_ENCODE_DISABLED) + { + DBG_871X("EncryptionDisabled\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + + goto exit; + } + + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + keyindex_provided = 1; + } + else + { + keyindex_provided = 0; + key = padapter->securitypriv.dot11PrivacyKeyIndex; + DBG_871X("rtw_wx_set_enc, key=%d\n", key); + } + + //set authentication mode + if(erq->flags & IW_ENCODE_OPEN) + { + DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; +#endif + + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + } + else if(erq->flags & IW_ENCODE_RESTRICTED) + { + DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n"); + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled; + +#ifdef CONFIG_PLATFORM_MT53XX + padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; +#else + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared; +#endif + + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_; + authmode = Ndis802_11AuthModeShared; + padapter->securitypriv.ndisauthtype=authmode; + } + else + { + DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags); + + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + authmode = Ndis802_11AuthModeOpen; + padapter->securitypriv.ndisauthtype=authmode; + } + + wep.KeyIndex = key; + if (erq->length > 0) + { + wep.KeyLength = erq->length <= 5 ? 5 : 13; + + wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + } + else + { + wep.KeyLength = 0 ; + + if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0). + { + padapter->securitypriv.dot11PrivacyKeyIndex = key; + + DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]); + + switch(padapter->securitypriv.dot11DefKeylen[key]) + { + case 5: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_; + break; + case 13: + padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_; + break; + default: + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + break; + } + + goto exit; + + } + + } + + wep.KeyIndex |= 0x80000000; + + _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); + + if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) { + if(rf_on == pwrpriv->rf_pwrstate ) + ret = -EOPNOTSUPP; + goto exit; + } + +exit: + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + uint key, ret =0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *erq = &(wrqu->encoding); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + _func_enter_; + + if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) + { + if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) + { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + return 0; + } + } + + + key = erq->flags & IW_ENCODE_INDEX; + + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + } else + { + key = padapter->securitypriv.dot11PrivacyKeyIndex; + } + + erq->flags = key + 1; + + //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) + //{ + // erq->flags |= IW_ENCODE_OPEN; + //} + + switch(padapter->securitypriv.ndisencryptstatus) + { + case Ndis802_11EncryptionNotSupported: + case Ndis802_11EncryptionDisabled: + + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + + break; + + case Ndis802_11Encryption1Enabled: + + erq->length = padapter->securitypriv.dot11DefKeylen[key]; + + if(erq->length) + { + _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]); + + erq->flags |= IW_ENCODE_ENABLED; + + if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) + { + erq->flags |= IW_ENCODE_OPEN; + } + else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared) + { + erq->flags |= IW_ENCODE_RESTRICTED; + } + } + else + { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + } + + break; + + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + + erq->length = 16; + erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY); + + break; + + default: + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + + break; + + } + + _func_exit_; + + return ret; + +} + +static int rtw_wx_get_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + wrqu->power.value = 0; + wrqu->power.fixed = 0; /* no auto select */ + wrqu->power.disabled = 1; + + return 0; + +} + +static int rtw_wx_set_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length); + + return ret; +} + +static int rtw_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_param *param = (struct iw_param*)&(wrqu->param); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + u32 value = param->value; + int ret = 0; + + switch (param->flags & IW_AUTH_INDEX) { + + case IW_AUTH_WPA_VERSION: +#ifdef CONFIG_WAPI_SUPPORT +#ifndef CONFIG_IOCTL_CFG80211 + padapter->wapiInfo.bWapiEnable = false; + if(value == IW_AUTH_WAPI_VERSION_1) + { + padapter->wapiInfo.bWapiEnable = true; + psecuritypriv->dot11PrivacyAlgrthm = _SMS4_; + psecuritypriv->dot118021XGrpPrivacy = _SMS4_; + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI; + pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm; + padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN; + padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN; + } +#endif +#endif + break; + case IW_AUTH_CIPHER_PAIRWISE: + + break; + case IW_AUTH_CIPHER_GROUP: + + break; + case IW_AUTH_KEY_MGMT: +#ifdef CONFIG_WAPI_SUPPORT +#ifndef CONFIG_IOCTL_CFG80211 + DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case \n"); + if(value == IW_AUTH_KEY_MGMT_WAPI_PSK) + padapter->wapiInfo.bWapiPSK = true; + else + padapter->wapiInfo.bWapiPSK = false; + DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d \n",padapter->wapiInfo.bWapiPSK); +#endif +#endif + /* + * ??? does not use these parameters + */ + break; + + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if ( param->value ) + { // wpa_supplicant is enabling the tkip countermeasure. + padapter->securitypriv.btkip_countermeasure = _TRUE; + } + else + { // wpa_supplicant is disabling the tkip countermeasure. + padapter->securitypriv.btkip_countermeasure = _FALSE; + } + break; + } + case IW_AUTH_DROP_UNENCRYPTED: + { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + + if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) + { + break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, + // then it needn't reset it; + } + + if(param->value){ + padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; + padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_; + padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_; + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system + padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen; + } + + break; + } + + case IW_AUTH_80211_AUTH_ALG: + + #if defined(CONFIG_ANDROID) || 1 + /* + * It's the starting point of a link layer connection using wpa_supplicant + */ + if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__); + rtw_indicate_disconnect(padapter); + rtw_free_assoc_resources(padapter, 1); + } + #endif + + + ret = wpa_set_auth_algs(dev, (u32)param->value); + + break; + + case IW_AUTH_WPA_ENABLED: + + //if(param->value) + // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x + //else + // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system + + //_disassociate(priv); + + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + //ieee->ieee802_1x = param->value; + break; + + case IW_AUTH_PRIVACY_INVOKED: + //ieee->privacy_invoked = param->value; + break; + +#ifdef CONFIG_WAPI_SUPPORT +#ifndef CONFIG_IOCTL_CFG80211 + case IW_AUTH_WAPI_ENABLED: + break; +#endif +#endif + + default: + return -EOPNOTSUPP; + + } + + return ret; + +} + +static int rtw_wx_set_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + char *alg_name; + u32 param_len; + struct ieee_param *param = NULL; + struct iw_point *pencoding = &wrqu->encoding; + struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; + int ret=0; + + param_len = sizeof(struct ieee_param) + pext->key_len; + param = (struct ieee_param *)rtw_malloc(param_len); + if (param == NULL) + return -1; + + _rtw_memset(param, 0, param_len); + + param->cmd = IEEE_CMD_SET_ENCRYPTION; + _rtw_memset(param->sta_addr, 0xff, ETH_ALEN); + + + switch (pext->alg) { + case IW_ENCODE_ALG_NONE: + //todo: remove key + //remove = 1; + alg_name = "none"; + break; + case IW_ENCODE_ALG_WEP: + alg_name = "WEP"; + break; + case IW_ENCODE_ALG_TKIP: + alg_name = "TKIP"; + break; + case IW_ENCODE_ALG_CCMP: + alg_name = "CCMP"; + break; +#ifdef CONFIG_IEEE80211W + case IW_ENCODE_ALG_AES_CMAC: + alg_name = "BIP"; + break; +#endif //CONFIG_IEEE80211W +#ifdef CONFIG_WAPI_SUPPORT +#ifndef CONFIG_IOCTL_CFG80211 + case IW_ENCODE_ALG_SM4: + alg_name= "SMS4"; + _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN); + DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n"); + break; +#endif +#endif + default: + ret = -1; + goto exit; + } + + strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); + + if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + { + param->u.crypt.set_tx = 1; + } + + /* cliW: WEP does not have group key + * just not checking GROUP key setting + */ + if ((pext->alg != IW_ENCODE_ALG_WEP) && + ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) +#ifdef CONFIG_IEEE80211W + || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC) +#endif //CONFIG_IEEE80211W + )) + { + param->u.crypt.set_tx = 0; + } + + param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ; + + if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) + { +#ifdef CONFIG_WAPI_SUPPORT +#ifndef CONFIG_IOCTL_CFG80211 + if(pext->alg == IW_ENCODE_ALG_SM4) + _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16); + else +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_WAPI_SUPPORT + _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8); + } + + if(pext->key_len) + { + param->u.crypt.key_len = pext->key_len; + //_rtw_memcpy(param + 1, pext + 1, pext->key_len); + _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len); + } + + if (pencoding->flags & IW_ENCODE_DISABLED) + { + //todo: remove key + //remove = 1; + } + + ret = wpa_set_encryption(dev, param, param_len); + +exit: + if(param) + { + rtw_mfree((u8*)param, param_len); + } + + return ret; +} + + +static int rtw_wx_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + //struct security_priv *psecuritypriv = &padapter->securitypriv; + + if(extra) + { + wrqu->data.length = 14; + wrqu->data.flags = 1; + _rtw_memcpy(extra, "", 14); + } + + //rtw_signal_process(pid, SIGUSR1); //for test + + //dump debug info here +/* + u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, and 8021x + u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm. + u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key + u32 ndisauthtype; + u32 ndisencryptstatus; +*/ + + //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + // psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, + // psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); + + //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); + //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype); + //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); + +#if 0 + DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210)); + DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608)); + DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280)); + DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284)); + DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288)); + + DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664)); + + + DBG_871X("\n"); + + DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430)); + DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438)); + + DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440)); + + DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458)); + + DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484)); + DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488)); + + DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444)); + DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448)); + DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c)); + DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450)); +#endif + + return 0; + +} + +static int rtw_wx_read32(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter; + struct iw_point *p; + u16 len; + u32 addr; + u32 data32; + u32 bytes; + u8 *ptmp; + int ret; + + + ret = 0; + padapter = (PADAPTER)rtw_netdev_priv(dev); + p = &wrqu->data; + len = p->length; + if (0 == len) + return -EINVAL; + + ptmp = (u8*)rtw_malloc(len); + if (NULL == ptmp) + return -ENOMEM; + + if (copy_from_user(ptmp, p->pointer, len)) { + ret = -EFAULT; + goto exit; + } + + bytes = 0; + addr = 0; + sscanf(ptmp, "%d,%x", &bytes, &addr); + + switch (bytes) { + case 1: + data32 = rtw_read8(padapter, addr); + sprintf(extra, "0x%02X", data32); + break; + case 2: + data32 = rtw_read16(padapter, addr); + sprintf(extra, "0x%04X", data32); + break; + case 4: + data32 = rtw_read32(padapter, addr); + sprintf(extra, "0x%08X", data32); + break; + default: + DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__); + ret = -EINVAL; + goto exit; + } + DBG_871X(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra); + +exit: + rtw_mfree(ptmp, len); + + return 0; +} + +static int rtw_wx_write32(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + + u32 addr; + u32 data32; + u32 bytes; + + + bytes = 0; + addr = 0; + data32 = 0; + sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); + + switch (bytes) { + case 1: + rtw_write8(padapter, addr, (u8)data32); + DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32); + break; + case 2: + rtw_write16(padapter, addr, (u16)data32); + DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32); + break; + case 4: + rtw_write32(padapter, addr, data32); + DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32); + break; + default: + DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int rtw_wx_read_rf(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u32 path, addr, data32; + + + path = *(u32*)extra; + addr = *((u32*)extra + 1); + data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF); +// DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); + /* + * IMPORTANT!! + * Only when wireless private ioctl is at odd order, + * "extra" would be copied to user space. + */ + sprintf(extra, "0x%05x", data32); + + return 0; +} + +static int rtw_wx_write_rf(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u32 path, addr, data32; + + + path = *(u32*)extra; + addr = *((u32*)extra + 1); + data32 = *((u32*)extra + 2); +// DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); + rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32); + + return 0; +} + +static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + return -1; +} + +static int dummy(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); + + return -1; + +} + +static int rtw_wx_set_channel_plan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 channel_plan_req = (u8) (*((int *)wrqu)); + + if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req)) + return -EPERM; + + return 0; +} + +static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, + ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n", + a->cmd, get_fwstate(pmlmepriv))); +#endif + return 0; +} + +static int rtw_wx_get_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *buf) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + // Modified by Albert 20110914 + // This is in dbm format for MTK platform. + wrqu->qual.level = padapter->recvpriv.rssi; + DBG_871X(" level = %u\n", wrqu->qual.level ); +#endif + return 0; +} + +static int rtw_wx_set_mtk_wps_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#ifdef CONFIG_PLATFORM_MT53XX + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length); +#else + return 0; +#endif +} + +/* +typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +*/ +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + #if 0 +struct iw_point +{ + void __user *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + #endif + +#ifdef CONFIG_DRVEXT_MODULE + u8 res; + struct drvext_handler *phandler; + struct drvext_oidparam *poidparam; + int ret; + u16 len; + u8 *pparmbuf, bset; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *p = &wrqu->data; + + if( (!p->length) || (!p->pointer)){ + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + bset = (u8)(p->flags&0xFFFF); + len = p->length; + pparmbuf = (u8*)rtw_malloc(len); + if (pparmbuf == NULL){ + ret = -ENOMEM; + goto _rtw_drvext_hdl_exit; + } + + if(bset)//set info + { + if (copy_from_user(pparmbuf, p->pointer,len)) { + rtw_mfree(pparmbuf, len); + ret = -EFAULT; + goto _rtw_drvext_hdl_exit; + } + } + else//query info + { + + } + + + // + poidparam = (struct drvext_oidparam *)pparmbuf; + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n", + poidparam->subcode, poidparam->len, len)); + + + //check subcode + if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n")); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n")); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + phandler = drvextoidhandlers + poidparam->subcode; + + if (poidparam->len != phandler->parmsize) + { + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n", + poidparam->len , phandler->parmsize)); + ret = -EINVAL; + goto _rtw_drvext_hdl_exit; + } + + + res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data); + + if(res==0) + { + ret = 0; + + if (bset == 0x00) {//query info + //_rtw_memcpy(p->pointer, pparmbuf, len); + if (copy_to_user(p->pointer, pparmbuf, len)) + ret = -EFAULT; + } + } + else + ret = -EFAULT; + + +_rtw_drvext_hdl_exit: + + return ret; + +#endif + + return 0; + +} + +static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len) +{ + pRW_Reg RegRWStruct; + struct rf_reg_param *prfreg; + u8 path; + u8 offset; + u32 value; + + DBG_871X("%s\n", __FUNCTION__); + + switch(id) + { + case GEN_MP_IOCTL_SUBCODE(MP_START): + DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n"); + break; + case GEN_MP_IOCTL_SUBCODE(READ_REG): + RegRWStruct = (pRW_Reg)pdata; + switch (RegRWStruct->width) + { + case 1: + RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset); + break; + case 2: + RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset); + break; + case 4: + RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset); + break; + default: + break; + } + + break; + case GEN_MP_IOCTL_SUBCODE(WRITE_REG): + RegRWStruct = (pRW_Reg)pdata; + switch (RegRWStruct->width) + { + case 1: + rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value); + break; + case 2: + rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value); + break; + case 4: + rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value); + break; + default: + break; + } + + break; + case GEN_MP_IOCTL_SUBCODE(READ_RF_REG): + + prfreg = (struct rf_reg_param *)pdata; + + path = (u8)prfreg->path; + offset = (u8)prfreg->offset; + + value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff); + + prfreg->value = value; + + break; + case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG): + + prfreg = (struct rf_reg_param *)pdata; + + path = (u8)prfreg->path; + offset = (u8)prfreg->offset; + value = prfreg->value; + + rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value); + + break; + case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO): + DBG_871X("==> trigger gpio 0\n"); + rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0); + break; +#ifdef CONFIG_BT_COEXIST + case GEN_MP_IOCTL_SUBCODE(SET_DM_BT): + DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata); + rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata); + break; + case GEN_MP_IOCTL_SUBCODE(DEL_BA): + DBG_871X("==> delete ba:%x\n",*(u8 *)pdata); + rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata); + break; +#endif +#ifdef DBG_CONFIG_ERROR_DETECT + case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS): + *pdata = rtw_hal_sreset_get_wifi_status(padapter); + break; +#endif + + default: + break; + } + +} + +static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + u32 BytesRead, BytesWritten, BytesNeeded; + struct oid_par_priv oid_par; + struct mp_ioctl_handler *phandler; + struct mp_ioctl_param *poidparam; + uint status=0; + u16 len; + u8 *pparmbuf = NULL, bset; + PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + struct iw_point *p = &wrqu->data; + + //DBG_871X("+rtw_mp_ioctl_hdl\n"); + + //mutex_lock(&ioctl_mutex); + + if ((!p->length) || (!p->pointer)) { + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + pparmbuf = NULL; + bset = (u8)(p->flags & 0xFFFF); + len = p->length; + pparmbuf = (u8*)rtw_malloc(len); + if (pparmbuf == NULL){ + ret = -ENOMEM; + goto _rtw_mp_ioctl_hdl_exit; + } + + if (copy_from_user(pparmbuf, p->pointer, len)) { + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } + + poidparam = (struct mp_ioctl_param *)pparmbuf; + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, + ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n", + poidparam->subcode, poidparam->len, len)); + + if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n")); + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + //DBG_871X("%s: %d\n", __func__, poidparam->subcode); +#ifdef CONFIG_MP_INCLUDED +if (padapter->registrypriv.mp_mode == 1) +{ + phandler = mp_ioctl_hdl + poidparam->subcode; + + if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) + { + RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, + ("no matching drvext param size %d vs %d\r\n", + poidparam->len, phandler->paramsize)); + ret = -EINVAL; + goto _rtw_mp_ioctl_hdl_exit; + } + + if (phandler->handler) + { + oid_par.adapter_context = padapter; + oid_par.oid = phandler->oid; + oid_par.information_buf = poidparam->data; + oid_par.information_buf_len = poidparam->len; + oid_par.dbg = 0; + + BytesWritten = 0; + BytesNeeded = 0; + + if (bset) { + oid_par.bytes_rw = &BytesRead; + oid_par.bytes_needed = &BytesNeeded; + oid_par.type_of_oid = SET_OID; + } else { + oid_par.bytes_rw = &BytesWritten; + oid_par.bytes_needed = &BytesNeeded; + oid_par.type_of_oid = QUERY_OID; + } + + status = phandler->handler(&oid_par); + + //todo:check status, BytesNeeded, etc. + } + else { + DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n", + poidparam->subcode, phandler->oid, phandler->handler); + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } +} +else +#endif +{ + rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len); +} + + if (bset == 0x00) {//query info + if (copy_to_user(p->pointer, pparmbuf, len)) + ret = -EFAULT; + } + + if (status) { + ret = -EFAULT; + goto _rtw_mp_ioctl_hdl_exit; + } + +_rtw_mp_ioctl_hdl_exit: + + if (pparmbuf) + rtw_mfree(pparmbuf, len); + + //mutex_unlock(&ioctl_mutex); + + return ret; +} + +static int rtw_get_ap_info(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int bssid_match, ret = 0; + u32 cnt=0, wpa_ielen; + _irqL irqL; + _list *plist, *phead; + unsigned char *pbuf; + u8 bssid[ETH_ALEN]; + char data[32]; + struct wlan_network *pnetwork = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + _queue *queue = &(pmlmepriv->scanned_queue); + struct iw_point *pdata = &wrqu->data; + + DBG_871X("+rtw_get_aplist_info\n"); + + if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) { + ret= -EINVAL; + goto exit; + } + + while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE) + { + rtw_msleep_os(30); + cnt++; + if(cnt > 100) + break; + } + + + //pdata->length = 0;//? + pdata->flags = 0; + if(pdata->length>=32) + { + if(copy_from_user(data, pdata->pointer, 32)) + { + ret= -EINVAL; + goto exit; + } + } + else + { + ret= -EINVAL; + goto exit; + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + //if(hwaddr_aton_i(pdata->pointer, bssid)) + if(hwaddr_aton_i(data, bssid)) + { + DBG_871X("Invalid BSSID '%s'.\n", (u8*)data); + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + return -EINVAL; + } + + + if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2 + { + DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid)); + + pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + if(pbuf && (wpa_ielen>0)) + { + pdata->flags = 1; + break; + } + + pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12); + if(pbuf && (wpa_ielen>0)) + { + pdata->flags = 2; + break; + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if(pdata->length>=34) + { + if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1)) + { + ret= -EINVAL; + goto exit; + } + } + +exit: + + return ret; + +} + +static int rtw_set_pid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = rtw_netdev_priv(dev); + int *pdata = (int *)wrqu; + int selector; + + if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) { + ret= -EINVAL; + goto exit; + } + + selector = *pdata; + if(selector < 3 && selector >=0) { + padapter->pid[selector] = *(pdata+1); + #ifdef CONFIG_GLOBAL_UI_PID + ui_pid[selector] = *(pdata+1); + #endif + DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]); + } + else + DBG_871X("%s selector %d error\n", __FUNCTION__, selector); + +exit: + + return ret; + +} + +static int rtw_wps_start(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + u32 u32wps_start = 0; + unsigned int uintRet = 0; + + if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) { + ret= -EINVAL; + goto exit; + } + + uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 ); + if ( u32wps_start == 0 ) + { + u32wps_start = *extra; + } + + DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start ); + + if ( u32wps_start == 1 ) // WPS Start + { + rtw_led_control(padapter, LED_CTL_START_WPS); + } + else if ( u32wps_start == 2 ) // WPS Stop because of wps success + { + rtw_led_control(padapter, LED_CTL_STOP_WPS); + } + else if ( u32wps_start == 3 ) // WPS Stop because of wps fail + { + rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL); + } + +#ifdef CONFIG_INTEL_WIDI + process_intel_widi_wps_status(padapter, u32wps_start); +#endif //CONFIG_INTEL_WIDI + +exit: + + return ret; + +} + +#ifdef CONFIG_P2P +static int rtw_wext_p2p_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + enum P2P_ROLE init_role = P2P_ROLE_DISABLE; + + if(*extra == '0' ) + init_role = P2P_ROLE_DISABLE; + else if(*extra == '1') + init_role = P2P_ROLE_DEVICE; + else if(*extra == '2') + init_role = P2P_ROLE_CLIENT; + else if(*extra == '3') + init_role = P2P_ROLE_GO; + + if(_FAIL == rtw_p2p_enable(padapter, init_role)) + { + ret = -EFAULT; + goto exit; + } + + //set channel/bandwidth + if(init_role != P2P_ROLE_DISABLE) + { + u8 channel, ch_offset; + u16 bwmode; + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) + { + // Stay at the listen state and wait for discovery. + channel = pwdinfo->listen_channel; + pwdinfo->operating_channel = pwdinfo->listen_channel; + ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + bwmode = CHANNEL_WIDTH_20; + } +#ifdef CONFIG_CONCURRENT_MODE + else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) + { + _adapter *pbuddy_adapter = padapter->pbuddy_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; + + _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval ); + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel; + // How about the ch_offset and bwmode ?? + } + else + { + pwdinfo->operating_channel = pwdinfo->listen_channel; + } + + channel = pbuddy_mlmeext->cur_channel; + ch_offset = pbuddy_mlmeext->cur_ch_offset; + bwmode = pbuddy_mlmeext->cur_bwmode; + } +#endif + else + { + pwdinfo->operating_channel = pmlmeext->cur_channel; + + channel = pwdinfo->operating_channel; + ch_offset = pmlmeext->cur_ch_offset; + bwmode = pmlmeext->cur_bwmode; + } + + set_channel_bwmode(padapter, channel, ch_offset, bwmode); + } + +exit: + return ret; + +} + +static int rtw_p2p_set_go_nego_ssid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + DBG_871X( "[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen( extra ) ); + _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) ); + pwdinfo->nego_ssidlen = strlen( extra ); + + return ret; + +} + + +static int rtw_p2p_set_intent(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 intent = pwdinfo->intent; + + extra[ wrqu->data.length ] = 0x00; + + intent = rtw_atoi( extra ); + + if ( intent <= 15 ) + { + pwdinfo->intent= intent; + } + else + { + ret = -1; + } + + DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent); + + return ret; + +} + +static int rtw_p2p_set_listen_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 listen_ch = pwdinfo->listen_channel; // Listen channel number + + extra[ wrqu->data.length ] = 0x00; + listen_ch = rtw_atoi( extra ); + + if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) ) + { + pwdinfo->listen_channel = listen_ch; + set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } + else + { + ret = -1; + } + + DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel ); + + return ret; + +} + +static int rtw_p2p_set_op_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Albert 20110524 +// This function is used to set the operating channel if the driver will become the group owner + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + u8 op_ch = pwdinfo->operating_channel; // Operating channel number + + extra[ wrqu->data.length ] = 0x00; + + op_ch = ( u8 ) rtw_atoi( extra ); + if ( op_ch > 0 ) + { + pwdinfo->operating_channel = op_ch; + } + else + { + ret = -1; + } + + DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel ); + + return ret; + +} + + +static int rtw_p2p_profilefound(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + // Comment by Albert 2010/10/13 + // Input data format: + // Ex: 0 + // Ex: 1XX:XX:XX:XX:XX:XXYYSSID + // 0 => Reflush the profile record list. + // 1 => Add the profile list + // XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) + // YY => SSID Length + // SSID => SSID for persistence group + + DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1); + + + // The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + if ( extra[ 0 ] == '0' ) + { + // Remove all the profile information of wifidirect_info structure. + _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM ); + pwdinfo->profileindex = 0; + } + else + { + if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM ) + { + ret = -1; + } + else + { + int jj, kk; + + // Add this profile information into pwdinfo->profileinfo + // Ex: 1XX:XX:XX:XX:XX:XXYYSSID + for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 ) + { + pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]); + } + + //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' ); + //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen ); + pwdinfo->profileindex++; + } + } + } + + return ret; + +} + +static int rtw_p2p_setDN(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN ); + _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 ); + pwdinfo->device_name_len = wrqu->data.length - 1; + + return ret; + +} + + +static int rtw_p2p_get_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_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 + + if ( padapter->bShowGetP2PState ) + { + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + } + + // Commented by Albert 2010/10/12 + // Because of the output size limitation, I had removed the "Role" information. + // About the "Role" information, we will use the new private IOCTL to get the "Role" information. + sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) ); + wrqu->data.length = strlen( extra ); + + return ret; + +} + +// Commented by Albert 20110520 +// This function will return the config method description +// This config method description will show us which config method the remote P2P device is intented to use +// by sending the provisioning discovery request frame. + +static int rtw_p2p_get_req_cm(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req ); + wrqu->data.length = strlen( extra ); + return ret; + +} + + +static int rtw_p2p_get_role(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + + sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) ); + wrqu->data.length = strlen( extra ); + return ret; + +} + + +static int rtw_p2p_get_peer_ifaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + + sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ], + pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_devaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]); + sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X", + pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ], + pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), + pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], + pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ], + pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]); + sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ], + pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ], + pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_groupid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s", + pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ], + pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ], + pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ], + pwdinfo->groupid_info.ssid); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_op_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel); + + sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel ); + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_wps_configmethod(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list * plist,*phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u16 attr_content = 0; + uint attr_contentlen = 0; + u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20110727 + // The input data is the MAC address which the application wants to know its WPS config method. + // After knowing its WPS config method, the application can decide the config method for provisioning discovery. + // Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen); + if (attr_contentlen) + { + attr_content = be16_to_cpu(attr_content); + sprintf(attr_content_str, "\n\nM=%.4d", attr_content); + blnMatch = 1; + } + } + + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(attr_content_str, "\n\nM=0000"); + } + + wrqu->data.length = strlen(attr_content_str); + _rtw_memcpy(extra, attr_content_str, wrqu->data.length); + + return ret; + +} + +#ifdef CONFIG_WFD +static int rtw_p2p_get_peer_wfd_port(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) ); + + sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport ); + DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport ); + + wrqu->data.length = strlen( extra ); + return ret; + +} + +static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc ); + DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc ); + + wrqu->data.length = strlen( extra ); + pwdinfo->wfd_info->wfd_pc = _FALSE; // Reset the WFD preferred connection to P2P + return ret; + +} + +static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail ); + DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail ); + + wrqu->data.length = strlen( extra ); + pwdinfo->wfd_info->peer_session_avail = _TRUE; // Reset the WFD session available + return ret; + +} +#endif /* CONFIG_WFD */ + +static int rtw_p2p_get_go_device_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + u8 attr_content[100] = { 0x00 }; + u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20121209 + // The input data is the GO's interface address which the application wants to know its device address. + // Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen); + if (p2pie) { + while (p2pie) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + _rtw_memset(attr_content, 0x00, 100); + if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) + { + // Handle the P2P Device ID attribute of Beacon first + blnMatch = 1; + break; + + } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) + { + // Handle the P2P Device Info attribute of probe response + blnMatch = 1; + break; + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen); + } + } + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(go_devadd_str, "\n\ndev_add=NULL"); + } else + { + sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); + } + + wrqu->data.length = strlen(go_devadd_str); + _rtw_memcpy(extra, go_devadd_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_device_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 dev_type[8] = { 0x00 }; + uint dev_type_len = 0; + u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; // +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer + + // Commented by Albert 20121209 + // The input data is the MAC address which the application wants to know its device type. + // Such user interface could know the device type. + // Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len); + if (dev_type_len) + { + u16 type = 0; + + _rtw_memcpy(&type, dev_type, 2); + type = be16_to_cpu(type); + sprintf(dev_type_str, "\n\nN=%.2d", type); + blnMatch = 1; + } + } + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(dev_type_str, "\n\nN=00"); + } + + wrqu->data.length = strlen(dev_type_str); + _rtw_memcpy(extra, dev_type_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_device_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 }; + uint dev_len = 0; + u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Albert 20121225 + // The input data is the MAC address which the application wants to know its device name. + // Such user interface could show peer device's device name instead of ssid. + // Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + u8 *wpsie; + uint wpsie_len = 0; + + // The mac address is matched. + + if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) ) + { + rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); + if (dev_len) + { + sprintf(dev_name_str, "\n\nN=%s", dev_name); + blnMatch = 1; + } + } + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(dev_name_str, "\n\nN=0000"); + } + + wrqu->data.length = strlen(dev_name_str); + _rtw_memcpy(extra, dev_name_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_get_invitation_procedure(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, char *subcmd) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 peerMAC[ETH_ALEN] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 blnMatch = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + u8 attr_content[2] = { 0x00 }; + u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; + + // Commented by Ouden 20121226 + // The application wants to know P2P initation procedure is support or not. + // Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 + + DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd); + + macstr2num(peerMAC, subcmd); + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while (1) + { + if (rtw_end_of_queue_search(phead, plist) == _TRUE) break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) + { + // Commented by Albert 20121226 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen); + if (p2pie) { + while (p2pie) + { + //_rtw_memset( attr_content, 0x00, 2); + if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) + { + // Handle the P2P capability attribute + blnMatch = 1; + break; + + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen); + } + } + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if (!blnMatch) + { + sprintf(inv_proc_str, "\nIP=-1"); + } else + { + if ((attr_content[0] & 0x20) == 0x20) + sprintf(inv_proc_str, "\nIP=1"); + else + sprintf(inv_proc_str, "\nIP=0"); + } + + wrqu->data.length = strlen(inv_proc_str); + _rtw_memcpy(extra, inv_proc_str, wrqu->data.length); + + return ret; + +} + +static int rtw_p2p_connect(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _irqL irqL; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Albert 20110304 + // The input data contains two informations. + // 1. First information is the MAC address which wants to formate with + // 2. Second information is the WPS PINCode or "pbc" string for push button method + // Format: 00:E0:4C:00:00:05 + // Format: 00:E0:4C:00:00:05 + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( pwdinfo->p2p_state == P2P_STATE_NONE ) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + +#ifdef CONFIG_INTEL_WIDI + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ ); + return ret; + } +#endif //CONFIG_INTEL_WIDI + + if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO ) + { + return -1; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) ) + { + if (pnetwork->network.Configuration.DSConfig != 0) + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + else if (pwdinfo->nego_req_info.peer_ch != 0) + uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch; + else{ + /* Unexpected case */ + uintPeerChannel = 0; + DBG_871X("%s uintPeerChannel = 0\n", __func__); + } + break; + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if ( uintPeerChannel ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) ); + _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) ); + + pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel; + _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN ); + pwdinfo->nego_req_info.benable = _TRUE; + + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK ) + { + // Restore to the listen state if the current p2p state is not nego OK + rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN ); + } + + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } +#endif // CONFIG_CONCURRENT_MODE + + DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ ); + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + } + else + { + DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ ); +#ifdef CONFIG_INTEL_WIDI + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + rtw_free_network_queue(padapter, _TRUE); + /** + * For WiDi, if we can't find candidate device in scanning queue, + * driver will do scanning itself + */ + _enter_critical_bh(&pmlmepriv->lock, &irqL); + rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +#endif //CONFIG_INTEL_WIDI + ret = -1; + } +exit: + return ret; +} + +static int rtw_p2p_invite_req(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Albert 20120321 + // The input data contains two informations. + // 1. First information is the P2P device address which you want to send to. + // 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. + // Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" + // Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( wrqu->data.length <= 37 ) + { + DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ ); + return ret; + } + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + // Reset the content of struct tx_invite_req_info + pinvite_req_info->benable = _FALSE; + _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN ); + _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN ); + pinvite_req_info->ssidlen = 0x00; + pinvite_req_info->operating_ch = pwdinfo->operating_channel; + _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN ); + pinvite_req_info->token = 3; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen); + if (p2pie) { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + +#ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) { + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + u8 *wfd_ie; + uint wfd_ielen = 0; + + wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen); + if (wfd_ie) { + u8 *wfd_devinfo; + uint wfd_devlen; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen); + if (wfd_devinfo) { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) + { + pwfd_info->peer_session_avail = _TRUE; + } + else + { + pwfd_info->peer_session_avail = _FALSE; + } + } + } + + if ( _FALSE == pwfd_info->peer_session_avail ) + { + DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); + goto exit; + } + } +#endif /* CONFIG_WFD */ + + if ( uintPeerChannel ) + { +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + + // Store the GO's bssid + for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 ) + { + pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + // Store the GO's ssid + pinvite_req_info->ssidlen = wrqu->data.length - 36; + _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen ); + pinvite_req_info->benable = _TRUE; + pinvite_req_info->peer_ch = uintPeerChannel; + + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } + else + { + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } +#else + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); +#endif + + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); + } +exit: + + return ret; + +} + +static int rtw_p2p_set_persistent(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Albert 20120328 + // The input data is 0 or 1 + // 0: disable persistent group functionality + // 1: enable persistent group founctionality + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + if ( extra[ 0 ] == '0' ) // Disable the persistent group function. + { + pwdinfo->persistent_supported = _FALSE; + } + else if ( extra[ 0 ] == '1' ) // Enable the persistent group function. + { + pwdinfo->persistent_supported = _TRUE; + } + else + { + pwdinfo->persistent_supported = _FALSE; + } + } + printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported ); + +exit: + + return ret; + +} + +static int hexstr2bin(const char *hex, u8 *buf, size_t len) +{ + size_t i; + int a; + const char *ipos = hex; + u8 *opos = buf; + + for (i = 0; i < len; i++) { + a = hex2byte_i(ipos); + if (a < 0) + return -1; + *opos++ = a; + ipos += 2; + } + return 0; +} + +static int uuid_str2bin(const char *str, u8 *bin) +{ + const char *pos; + u8 *opos; + + pos = str; + opos = bin; + + if (hexstr2bin(pos, opos, 4)) + return -1; + pos += 8; + opos += 4; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 2)) + return -1; + pos += 4; + opos += 2; + + if (*pos++ != '-' || hexstr2bin(pos, opos, 6)) + return -1; + + return 0; +} + +static int rtw_p2p_set_wps_uuid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &(padapter->wdinfo); + + DBG_871X("[%s] data = %s\n", __FUNCTION__, extra); + + if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0)) + { + pwdinfo->external_uuid = 1; + } else { + pwdinfo->external_uuid = 0; + ret = -EINVAL; + } + + return ret; + +} +#ifdef CONFIG_WFD +static int rtw_p2p_set_pc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + u8 attr_content[50] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; + uint uintPeerChannel = 0; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + struct wifi_display_info* pwfd_info = pwdinfo->wfd_info; + + // Commented by Albert 20120512 + // 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) + // Format: 00:E0:4C:00:00:05 + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen); + if (p2pie) { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + printk( "[%s] Got P2P IE\n", __FUNCTION__ ); + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ ); + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ ); + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + } + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel ); + + if ( uintPeerChannel ) + { + u8 *wfd_ie; + uint wfd_ielen = 0; + + wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen); + if (wfd_ie) { + u8 *wfd_devinfo; + uint wfd_devlen; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen); + if (wfd_devinfo) { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS ) + { + pwfd_info->wfd_pc = _TRUE; + } + else + { + pwfd_info->wfd_pc = _FALSE; + } + } + } + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); + } + +exit: + + return ret; + +} + +static int rtw_p2p_set_wfd_device_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + + // Commented by Albert 20120328 + // The input data is 0 or 1 + // 0: specify to Miracast source device + // 1 or others: specify to Miracast sink device (display device) + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( extra[ 0 ] == '0' ) // Set to Miracast source device. + { + pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE; + } + else // Set to Miracast sink device. + { + pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK; + } + +exit: + + return ret; + +} + +static int rtw_p2p_set_wfd_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set wfd enabled + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if (*extra == '0') + rtw_wfd_enable(padapter, 0); + else if (*extra == '1') + rtw_wfd_enable(padapter, 1); + + DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable ); + + return ret; + +} + +static int rtw_p2p_set_driver_iface(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +// Commented by Kurt 20121206 +// This function is used to set driver iface is WEXT or CFG80211 + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + + if(*extra == '1' ) + { + pwdinfo->driver_interface = DRIVER_WEXT; + DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__); + } + else if(*extra == '2') + { + pwdinfo->driver_interface = DRIVER_CFG80211; + DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__); + } + + return ret; + +} + +// To set the WFD session available to enable or disable +static int rtw_p2p_set_sa(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if( 0 ) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { + if ( extra[ 0 ] == '0' ) // Disable the session available. + { + pwdinfo->session_available = _FALSE; + } + else if ( extra[ 0 ] == '1' ) // Enable the session available. + { + pwdinfo->session_available = _TRUE; + } + else + { + pwdinfo->session_available = _FALSE; + } + } + printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available ); + +exit: + + return ret; + +} +#endif /* CONFIG_WFD */ + +static int rtw_p2p_prov_disc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + u8 peerMAC[ ETH_ALEN ] = { 0x00 }; + int jj,kk; + u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 }; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + _list *plist, *phead; + _queue *queue = &(pmlmepriv->scanned_queue); + struct wlan_network *pnetwork = NULL; + uint uintPeerChannel = 0; + u8 attr_content[100] = { 0x00 }, _status = 0; + u8 *p2pie; + uint p2pielen = 0, attr_contentlen = 0; + _irqL irqL; +#ifdef CONFIG_CONCURRENT_MODE + _adapter *pbuddy_adapter = padapter->pbuddy_adapter; + struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv; + struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv; +#endif // CONFIG_CONCURRENT_MODE + + // Commented by Albert 20110301 + // The input data contains two informations. + // 1. First information is the MAC address which wants to issue the provisioning discovery request frame. + // 2. Second information is the WPS configuration method which wants to discovery + // Format: 00:E0:4C:00:00:05_display + // Format: 00:E0:4C:00:00:05_keypad + // Format: 00:E0:4C:00:00:05_pbc + // Format: 00:E0:4C:00:00:05_label + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + + if ( pwdinfo->p2p_state == P2P_STATE_NONE ) + { + DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ ); + return ret; + } + else + { +#ifdef CONFIG_INTEL_WIDI + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { + DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ ); + return ret; + } +#endif //CONFIG_INTEL_WIDI + + // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. + _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN ); + _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN ); + _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) ); + pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0; + pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0; + pwdinfo->tx_prov_disc_info.benable = _FALSE; + } + + for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 ) + { + peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] ); + } + + if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA; + } + else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD; + } + else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON; + } + else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) ) + { + pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL; + } + else + { + DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ ); + return( ret ); + } + + _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + phead = get_list_head(queue); + plist = get_next(phead); + + while(1) + { + if (rtw_end_of_queue_search(phead,plist)== _TRUE) + break; + + if( uintPeerChannel != 0 ) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); + + // Commented by Albert 2011/05/18 + // Match the device address located in the P2P IE + // This is for the case that the P2P device address is not the same as the P2P interface address. + + p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen); + if (p2pie) { + while ( p2pie ) + { + // The P2P Device ID attribute is included in the Beacon frame. + // The P2P Device Info attribute is included in the probe response frame. + + if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device ID attribute of Beacon first + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) ) + { + // Handle the P2P Device Info attribute of probe response + if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } + + //Get the next P2P IE + p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen); + } + + } + +#ifdef CONFIG_INTEL_WIDI + // Some Intel WiDi source may not provide P2P IE, + // so we could only compare mac addr by 802.11 Source Address + if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION + && uintPeerChannel == 0 ) + { + if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) ) + { + uintPeerChannel = pnetwork->network.Configuration.DSConfig; + break; + } + } +#endif //CONFIG_INTEL_WIDI + + plist = get_next(plist); + + } + + _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); + + if ( uintPeerChannel ) + { + #ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + struct wifi_display_info *pwfd_info = pwdinfo->wfd_info; + u8 *wfd_ie; + uint wfd_ielen = 0; + + wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen); + if (wfd_ie) { + u8 *wfd_devinfo; + uint wfd_devlen; + + DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ ); + wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen); + if (wfd_devinfo) { + u16 wfd_devinfo_field = 0; + + // Commented by Albert 20120319 + // The first two bytes are the WFD device information field of WFD device information subelement. + // In big endian format. + wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo); + if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL ) + { + pwfd_info->peer_session_avail = _TRUE; + } + else + { + pwfd_info->peer_session_avail = _FALSE; + } + } + } + + if ( _FALSE == pwfd_info->peer_session_avail ) + { + DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ ); + goto exit; + } + } + #endif /* CONFIG_WFD */ + + DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel ); +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); + } +#endif // CONFIG_CONCURRENT_MODE + _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN ); + _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN ); + pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel; + pwdinfo->tx_prov_disc_info.benable = _TRUE; + rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo)); + rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ); + + if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) + { + _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) ); + } + else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) + { + _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ); + pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN; + } + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + // Have to enter the power saving with the AP + set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode); + + issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500); + } + else + { + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); + } +#else + set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); +#endif + + _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT ); + +#ifdef CONFIG_CONCURRENT_MODE + if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) ) + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT ); + } + else + { + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); + } +#else + _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT ); +#endif // CONFIG_CONCURRENT_MODE + + } + else + { + DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ ); +#ifdef CONFIG_INTEL_WIDI + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH); + rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE); + rtw_free_network_queue(padapter, _TRUE); + _enter_critical_bh(&pmlmepriv->lock, &irqL); + rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0); + _exit_critical_bh(&pmlmepriv->lock, &irqL); +#endif //CONFIG_INTEL_WIDI + } +exit: + + return ret; + +} + +// Added by Albert 20110328 +// This function is used to inform the driver the user had specified the pin code value or pbc +// to application. + +static int rtw_p2p_got_wpsinfo(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); + + + DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra ); + // Added by Albert 20110328 + // if the input data is P2P_NO_WPSINFO -> reset the wpsinfo + // if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. + // if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. + // if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC + + if ( *extra == '0' ) + { + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; + } + else if ( *extra == '1' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN; + } + else if ( *extra == '2' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN; + } + else if ( *extra == '3' ) + { + pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC; + } + else + { + pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO; + } + + return ret; + +} + +#endif //CONFIG_P2P + +static int rtw_p2p_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; +#ifdef CONFIG_P2P + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra ); + + if ( _rtw_memcmp( extra, "enable=", 7 ) ) + { + rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "setDN=", 6 ) ) + { + wrqu->data.length -= 6; + rtw_p2p_setDN( dev, info, wrqu, &extra[6] ); + } + else if ( _rtw_memcmp( extra, "profilefound=", 13 ) ) + { + wrqu->data.length -= 13; + rtw_p2p_profilefound( dev, info, wrqu, &extra[13] ); + } + else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) ) + { + wrqu->data.length -= 10; + rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] ); + } + else if ( _rtw_memcmp( extra, "nego=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_p2p_connect( dev, info, wrqu, &extra[5] ); + } + else if ( _rtw_memcmp( extra, "intent=", 7 ) ) + { + // Commented by Albert 2011/03/23 + // The wrqu->data.length will include the null character + // So, we will decrease 7 + 1 + wrqu->data.length -= 8; + rtw_p2p_set_intent( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "ssid=", 5 ) ) + { + wrqu->data.length -= 5; + rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] ); + } + else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) ) + { + wrqu->data.length -= 12; + rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] ); + } + else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) ) + { + // Commented by Albert 2011/05/24 + // The wrqu->data.length will include the null character + // So, we will decrease (10 + 1) + wrqu->data.length -= 11; + rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] ); + } + else if ( _rtw_memcmp( extra, "op_ch=", 6 ) ) + { + // Commented by Albert 2011/05/24 + // The wrqu->data.length will include the null character + // So, we will decrease (6 + 1) + wrqu->data.length -= 7; + rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] ); + } + else if ( _rtw_memcmp( extra, "invite=", 7 ) ) + { + wrqu->data.length -= 8; + rtw_p2p_invite_req( dev, info, wrqu, &extra[7] ); + } + else if ( _rtw_memcmp( extra, "persistent=", 11 ) ) + { + wrqu->data.length -= 11; + rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] ); + } + else if ( _rtw_memcmp ( extra, "uuid=", 5) ) + { + wrqu->data.length -= 5; + ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] ); + } + +#ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + if (_rtw_memcmp(extra, "sa=", 3)) { + /* sa: WFD Session Available information */ + wrqu->data.length -= 3; + rtw_p2p_set_sa(dev, info, wrqu, &extra[3]); + } else if (_rtw_memcmp(extra, "pc=", 3)) { + /* pc: WFD Preferred Connection */ + wrqu->data.length -= 3; + rtw_p2p_set_pc(dev, info, wrqu, &extra[3]); + } else if (_rtw_memcmp(extra, "wfd_type=", 9)) { + wrqu->data.length -= 9; + rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]); + } else if (_rtw_memcmp(extra, "wfd_enable=", 11)) { + wrqu->data.length -= 11; + rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]); + } else if (_rtw_memcmp(extra, "driver_iface=", 13)) { + wrqu->data.length -= 13; + rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]); + } + } +#endif /* CONFIG_WFD */ + +#endif //CONFIG_P2P + + return ret; + +} + +static int rtw_p2p_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_P2P + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct iw_point *pdata = &wrqu->data; + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + if ( padapter->bShowGetP2PState ) + { + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer ); + } + + if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) ) + { + rtw_p2p_get_status( dev, info, wrqu, extra ); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) ) + { + rtw_p2p_get_role( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) ) + { + rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) ) + { + rtw_p2p_get_req_cm( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) ) + { + // Get the P2P device address when receiving the provision discovery request frame. + rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) ) + { + rtw_p2p_get_groupid( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) ) + { + // Get the P2P device address when receiving the P2P Invitation request frame. + rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra); + } + else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) ) + { + rtw_p2p_get_op_ch( dev, info, wrqu, extra); + } + +#ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9)) + rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra); + else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6)) + rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra); + else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6)) + rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra); + } +#endif /* CONFIG_WFD */ + +#endif //CONFIG_P2P + + return ret; + +} + +static int rtw_p2p_get2(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_P2P + + int length = wrqu->data.length; + char *buffer = (u8 *)rtw_malloc(length); + + if (buffer == NULL) + { + ret = -ENOMEM; + goto bad; + } + + if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) + { + ret = -EFAULT; + goto bad; + } + + DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer); + + if (_rtw_memcmp(buffer, "wpsCM=", 6)) + { + ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]); + } else if (_rtw_memcmp(buffer, "devN=", 5)) + { + ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]); + } else if (_rtw_memcmp(buffer, "dev_type=", 9)) + { + ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]); + } else if (_rtw_memcmp(buffer, "go_devadd=", 10)) + { + ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]); + } else if (_rtw_memcmp(buffer, "InvProc=", 8)) + { + ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]); + } else + { + snprintf(extra, sizeof("Command not found."), "Command not found."); + wrqu->data.length = strlen(extra); + } + +bad: + if (buffer) + { + rtw_mfree(buffer, length); + } + +#endif //CONFIG_P2P + + return ret; + +} + +static int rtw_cta_test_start(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + DBG_871X("%s %s\n", __func__, extra); + if (!strcmp(extra, "1")) + padapter->in_cta_test = 1; + else + padapter->in_cta_test = 0; + + if(padapter->in_cta_test) + { + u32 v = rtw_read32(padapter, REG_RCR); + v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF + rtw_write32(padapter, REG_RCR, v); + DBG_871X("enable RCR_ADF\n"); + } + else + { + u32 v = rtw_read32(padapter, REG_RCR); + v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF + rtw_write32(padapter, REG_RCR, v); + DBG_871X("disable RCR_ADF\n"); + } + return ret; +} + + +extern int rtw_change_ifname(_adapter *padapter, const char *ifname); +static int rtw_rereg_nd_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = rtw_netdev_priv(dev); + struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv; + char new_ifname[IFNAMSIZ]; + + if(rereg_priv->old_ifname[0] == 0) { + char *reg_ifname; +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->isprimary) + reg_ifname = padapter->registrypriv.ifname; + else +#endif + reg_ifname = padapter->registrypriv.if2name; + + strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ); + rereg_priv->old_ifname[IFNAMSIZ-1] = 0; + } + + //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); + if(wrqu->data.length > IFNAMSIZ) + return -EFAULT; + + if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) { + return -EFAULT; + } + + if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) { + return ret; + } + + DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname); + if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) { + goto exit; + } + + if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) { + padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed; + rtw_hal_sw_led_init(padapter); + //rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); + } + + strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ); + rereg_priv->old_ifname[IFNAMSIZ-1] = 0; + + if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) { + + DBG_871X("%s disable\n", __FUNCTION__); + // free network queue for Android's timming issue + rtw_free_network_queue(padapter, _TRUE); + + // close led + rtw_led_control(padapter, LED_CTL_POWER_OFF); + rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed; + padapter->ledpriv.bRegUseLed= _FALSE; + rtw_hal_sw_led_deinit(padapter); + + // the interface is being "disabled", we can do deeper IPS + //rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); + //rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); + } +exit: + return ret; + +} + +#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) +{ + _irqL irqL; + int ret = 0; + u8 major_cmd, minor_cmd; + u16 arg; + u32 extra_arg, *pdata, val32; + struct sta_info *psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct wlan_network *cur_network = &(pmlmepriv->cur_network); + struct sta_priv *pstapriv = &padapter->stapriv; + + + pdata = (u32*)&wrqu->data; + + val32 = *pdata; + arg = (u16)(val32&0x0000ffff); + major_cmd = (u8)(val32>>24); + minor_cmd = (u8)((val32>>16)&0x00ff); + + extra_arg = *(pdata+1); + + switch(major_cmd) + { + case 0x70://read_reg + switch(minor_cmd) + { + case 1: + DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg)); + break; + case 2: + DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg)); + break; + case 4: + DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg)); + break; + } + break; + case 0x71://write_reg + switch(minor_cmd) + { + case 1: + rtw_write8(padapter, arg, extra_arg); + DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg)); + break; + case 2: + rtw_write16(padapter, arg, extra_arg); + DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg)); + break; + case 4: + rtw_write32(padapter, arg, extra_arg); + DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg)); + break; + } + break; + case 0x72://read_bb + DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); + break; + case 0x73://write_bb + rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg); + DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff)); + break; + case 0x74://read_rf + DBG_871X("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg,rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); + break; + case 0x75://write_rf + rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg); + DBG_871X("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff)); + break; + + case 0x76: + switch(minor_cmd) + { + case 0x00: //normal mode, + padapter->recvpriv.is_signal_dbg = 0; + break; + case 0x01: //dbg mode + padapter->recvpriv.is_signal_dbg = 1; + extra_arg = extra_arg>100?100:extra_arg; + padapter->recvpriv.signal_strength_dbg=extra_arg; + break; + } + break; + case 0x78: //IOL test + switch(minor_cmd) + { + #ifdef CONFIG_IOL + case 0x04: //LLT table initialization test + { + u8 page_boundary = 0xf9; + { + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) { + ret = -ENOMEM; + break; + } + + rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary); + + + if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) ) + ret = -EPERM; + } + } + break; + case 0x05: //blink LED test + { + u16 reg = 0x4c; + u32 blink_num = 50; + u32 blink_delay_ms = 200; + int i; + + { + struct xmit_frame *xmit_frame; + + if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) { + ret = -ENOMEM; + break; + } + + for(i=0;inetwork.MacAddress + , WLAN_REASON_EXPIRATION_CHK); + break; + case 0x7F: + switch(minor_cmd) + { + case 0x0: + DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv)); + break; + case 0x01: + DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", + psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, + psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); + break; + case 0x02: + DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state); + DBG_871X("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly); + DBG_871X("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut); + break; + case 0x03: + DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option); +#ifdef CONFIG_80211N_HT + DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option); +#endif //CONFIG_80211N_HT + break; + case 0x04: + DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel); + DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode); + DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset); + + DBG_871X("oper_ch=%d\n", rtw_get_oper_ch(padapter)); + DBG_871X("oper_bw=%d\n", rtw_get_oper_bw(padapter)); + DBG_871X("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter)); + + break; + case 0x05: + psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress); + if(psta) + { + DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid); + DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset); + DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); +#ifdef CONFIG_80211N_HT + DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); + DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); +#endif //CONFIG_80211N_HT + + sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta); + } + else + { + DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress)); + } + break; + case 0x06: + { + } + break; + case 0x07: + DBG_871X("bSurpriseRemoved=%s, bDriverStopped=%s\n" + , rtw_is_surprise_removed(padapter)?"True":"False" + , rtw_is_drv_stopped(padapter)?"True":"False"); + break; + case 0x08: + { + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct recv_priv *precvpriv = &padapter->recvpriv; + + DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d" + ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d" + ", free_recvframe_cnt=%d\n", + pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, + 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", ATOMIC_READ(&(precvpriv->rx_pending_cnt))); + #endif + } + break; + case 0x09: + { + int i; + _list *plist, *phead; + +#ifdef CONFIG_AP_MODE + DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); +#endif + _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(extra_arg == psta->aid) + { + DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr)); + DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); + DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); +#ifdef CONFIG_80211N_HT + DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); + DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m); + DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable); + DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); +#endif //CONFIG_80211N_HT + +#ifdef CONFIG_AP_MODE + DBG_871X("capability=0x%x\n", psta->capability); + DBG_871X("flags=0x%x\n", psta->flags); + DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk); + DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher); + DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher); + DBG_871X("qos_info=0x%x\n", psta->qos_info); +#endif + DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy); + + sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta); + } + + } + } + + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + } + break; + + case 0x0b: //Enable=1, Disable=0 driver control vrtl_carrier_sense. + { + //u8 driver_vcs_en; //Enable=1, Disable=0 driver control vrtl_carrier_sense. + //u8 driver_vcs_type;//force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. + + if(arg == 0){ + DBG_871X("disable driver ctrl vcs\n"); + padapter->driver_vcs_en = 0; + } + else if(arg == 1){ + DBG_871X("enable driver ctrl vcs = %d\n", extra_arg); + padapter->driver_vcs_en = 1; + + if(extra_arg>2) + padapter->driver_vcs_type = 1; + else + padapter->driver_vcs_type = extra_arg; + } + } + break; + case 0x0c://dump rx/tx packet + { + if(arg == 0){ + DBG_871X("dump rx packet (%d)\n",extra_arg); + //pHalData->bDumpRxPkt =extra_arg; + rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg)); + } + else if(arg==1){ + DBG_871X("dump tx packet (%d)\n",extra_arg); + rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg)); + } + } + break; + case 0x0e: + { + if(arg == 0){ + DBG_871X("disable driver ctrl rx_ampdu_factor\n"); + padapter->driver_rx_ampdu_factor = 0xFF; + } + else if(arg == 1){ + + DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg); + + if(extra_arg > 0x03) + padapter->driver_rx_ampdu_factor = 0xFF; + else + padapter->driver_rx_ampdu_factor = extra_arg; + } + } + break; + #ifdef DBG_CONFIG_ERROR_DETECT + case 0x0f: + { + if(extra_arg == 0){ + DBG_871X("###### silent reset test.......#####\n"); + rtw_hal_sreset_reset(padapter); + } else { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct sreset_priv *psrtpriv = &pHalData->srestpriv; + psrtpriv->dbg_trigger_point = extra_arg; + } + + } + break; + case 0x15: + { + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts); + } + break; + + #endif + + case 0x10:// driver version display + dump_drv_version(RTW_DBGDUMP); + break; + case 0x11://dump linked status + { + 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 + case 0x12: //set rx_stbc + { + struct registry_priv *pregpriv = &padapter->registrypriv; + // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g + //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ + if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3)) + { + pregpriv->rx_stbc= extra_arg; + DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc); + } + else + DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc); + + } + break; + case 0x13: //set ampdu_enable + { + struct registry_priv *pregpriv = &padapter->registrypriv; + // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) + if( pregpriv && extra_arg < 3 ) + { + pregpriv->ampdu_enable= extra_arg; + DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable); + } + else + DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable); + + } + break; +#endif + case 0x14: //get wifi_spec + { + struct registry_priv *pregpriv = &padapter->registrypriv; + DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec); + + } + break; + case 0x16: + { + if(arg == 0xff){ + rtw_odm_dbg_comp_msg(RTW_DBGDUMP,padapter); + } + else{ + u64 dbg_comp = (u64)extra_arg; + rtw_odm_dbg_comp_set(padapter, dbg_comp); + } + } + break; +#ifdef DBG_FIXED_CHAN + case 0x17: + { + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + printk("===> Fixed channel to %d \n",extra_arg); + pmlmeext->fixed_chan = extra_arg; + + } + break; +#endif + case 0x18: + { + printk("===> Switch USB Mode %d \n",extra_arg); + rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg); + } + break; +#ifdef CONFIG_80211N_HT + case 0x19: + { + struct registry_priv *pregistrypriv = &padapter->registrypriv; + // extra_arg : + // BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, + // BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx + if(arg == 0){ + DBG_871X("driver disable LDPC\n"); + pregistrypriv->ldpc_cap = 0x00; + } + else if(arg == 1){ + DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg); + pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33); + } + } + break; + case 0x1a: + { + struct registry_priv *pregistrypriv = &padapter->registrypriv; + // extra_arg : + // BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, + // BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx + if(arg == 0){ + DBG_871X("driver disable STBC\n"); + pregistrypriv->stbc_cap = 0x00; + } + else if(arg == 1){ + DBG_871X("driver set STBC cap = 0x%x\n", extra_arg); + pregistrypriv->stbc_cap = (u8)(extra_arg&0x33); + } + } + break; +#endif //CONFIG_80211N_HT + case 0x1b: + { + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + if(arg == 0){ + DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n"); + init_mlme_default_rate_set(padapter); +#ifdef CONFIG_80211N_HT + pregistrypriv->ht_enable = (u8)rtw_ht_enable; +#endif //CONFIG_80211N_HT + } + else if(arg == 1){ + + int i; + u8 max_rx_rate; + + DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg); + + max_rx_rate = (u8)extra_arg; + + if(max_rx_rate < 0xc) // max_rx_rate < MSC0 -> B or G -> disable HT + { +#ifdef CONFIG_80211N_HT + pregistrypriv->ht_enable = 0; +#endif //CONFIG_80211N_HT + for(i=0; idatarate[i] > max_rx_rate) + pmlmeext->datarate[i] = 0xff; + } + + } +#ifdef CONFIG_80211N_HT + else if(max_rx_rate < 0x1c) // mcs0~mcs15 + { + u32 mcs_bitmap=0x0; + + for(i=0; i<((max_rx_rate+1)-0xc); i++) + mcs_bitmap |= BIT(i); + + set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap); + } +#endif //CONFIG_80211N_HT + } + } + break; + case 0x1c: //enable/disable driver control AMPDU Density for peer sta's rx + { + if(arg == 0){ + DBG_871X("disable driver ctrl ampdu density\n"); + padapter->driver_ampdu_spacing = 0xFF; + } + else if(arg == 1){ + + DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg); + + if(extra_arg > 0x07) + padapter->driver_ampdu_spacing = 0xFF; + else + padapter->driver_ampdu_spacing = extra_arg; + } + } + break; +#ifdef CONFIG_BACKGROUND_NOISE_MONITOR + case 0x1e: + { + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + PDM_ODM_T pDM_Odm = &pHalData->odmpriv; + u8 chan = rtw_get_oper_ch(padapter); + DBG_871X("===========================================\n"); + ODM_InbandNoise_Monitor(pDM_Odm,_TRUE,0x1e,100); + DBG_871X("channel(%d),noise_a = %d, noise_b = %d , noise_all:%d \n", + chan,pDM_Odm->noise_level.noise[ODM_RF_PATH_A], + pDM_Odm->noise_level.noise[ODM_RF_PATH_B], + pDM_Odm->noise_level.noise_all); + DBG_871X("===========================================\n"); + + } + break; +#endif + case 0x23: + { + DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off"); + padapter->bNotifyChannelChange = extra_arg; + break; + } + case 0x24: + { +#ifdef CONFIG_P2P + DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off"); + padapter->bShowGetP2PState = extra_arg; +#endif // CONFIG_P2P + break; + } +#ifdef CONFIG_GPIO_API + case 0x25: //Get GPIO register + { + /* + * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7 + */ + + u8 value; + DBG_871X("Read GPIO Value extra_arg = %d\n",extra_arg); + value = rtw_hal_get_gpio(padapter,extra_arg); + DBG_871X("Read GPIO Value = %d\n",value); + break; + } + case 0x26: //Set GPIO direction + { + + /* dbg 0x7f26000x [y], Set gpio direction, + * x: gpio_num,4~7 y: indicate direction, 0~1 + */ + + int value; + DBG_871X("Set GPIO Direction! arg = %d ,extra_arg=%d\n",arg ,extra_arg); + value = rtw_hal_config_gpio(padapter, arg, extra_arg); + DBG_871X("Set GPIO Direction %s \n",(value==-1)?"Fail!!!":"Success"); + break; + } + case 0x27: //Set GPIO output direction value + { + /* + * dbg 0x7f27000x [y], Set gpio output direction value, + * x: gpio_num,4~7 y: indicate direction, 0~1 + */ + + int value; + DBG_871X("Set GPIO Value! arg = %d ,extra_arg=%d\n",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 +#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; + DBG_871X("chang data rate to :0x%02x\n",extra_arg); + padapter->fix_rate = extra_arg; + } + break; + case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg + { + if(extra_arg==0){ + mac_reg_dump(RTW_DBGDUMP, padapter); + } + else if(extra_arg==1){ + bb_reg_dump(RTW_DBGDUMP, padapter); + } + else if(extra_arg==2){ + rf_reg_dump(RTW_DBGDUMP, padapter); + } + } + break; + + case 0xee: + { + DBG_871X(" === please control /proc to trun on/off PHYDM func === \n"); + } + break; + + case 0xfd: + rtw_write8(padapter, 0xc50, arg); + DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50)); + rtw_write8(padapter, 0xc58, arg); + DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58)); + break; + case 0xfe: + DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50)); + DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58)); + break; + case 0xff: + { + DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210)); + DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608)); + DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280)); + DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284)); + DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288)); + + DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664)); + + + DBG_871X("\n"); + + DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430)); + DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438)); + + DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440)); + + DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458)); + + DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484)); + DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488)); + + DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444)); + DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448)); + DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c)); + DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450)); + } + break; + } + break; + default: + DBG_871X("error dbg cmd!\n"); + break; + } + + + return ret; + +} + +static int wpa_set_param(struct net_device *dev, u8 name, u32 value) +{ + uint ret=0; + u32 flags; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + switch (name){ + case IEEE_PARAM_WPA_ENABLED: + + padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x + + //ret = ieee80211_wpa_enable(ieee, value); + + switch((value)&0xff) + { + case 1 : //WPA + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled; + break; + case 2: //WPA2 + padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK + padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled; + break; + } + + RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype)); + + break; + + case IEEE_PARAM_TKIP_COUNTERMEASURES: + //ieee->tkip_countermeasures=value; + break; + + case IEEE_PARAM_DROP_UNENCRYPTED: + { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + +#if 0 + struct ieee80211_security sec = { + .flags = SEC_ENABLED, + .enabled = value, + }; + ieee->drop_unencrypted = value; + /* We only change SEC_LEVEL for open mode. Others + * are set by ipw_wpa_set_encryption. + */ + if (!value) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_0; + } + else { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); +#endif + break; + + } + case IEEE_PARAM_PRIVACY_INVOKED: + + //ieee->privacy_invoked=value; + + break; + + case IEEE_PARAM_AUTH_ALGS: + + ret = wpa_set_auth_algs(dev, value); + + break; + + case IEEE_PARAM_IEEE_802_1X: + + //ieee->ieee802_1x=value; + + break; + + case IEEE_PARAM_WPAX_SELECT: + + // added for WPA2 mixed mode + //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value); + /* + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); + ieee->wpax_type_set = 1; + ieee->wpax_type_notify = value; + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); + */ + + break; + + default: + + + + ret = -EOPNOTSUPP; + + + break; + + } + + return ret; + +} + +static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + switch (command) + { + case IEEE_MLME_STA_DEAUTH: + + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + case IEEE_MLME_STA_DISASSOC: + + if(!rtw_set_802_11_disassociate(padapter)) + ret = -1; + + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; + +} + +static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) +{ + struct ieee_param *param; + uint ret=0; + + //down(&ieee->wx_sem); + + if (p->length < sizeof(struct ieee_param) || !p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)rtw_malloc(p->length); + if (param == NULL) + { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(param, p->pointer, p->length)) + { + rtw_mfree((u8*)param, p->length); + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + + case IEEE_CMD_SET_WPA_PARAM: + ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); + break; + + case IEEE_CMD_SET_WPA_IE: + //ret = wpa_set_wpa_ie(dev, param, p->length); + ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len); + break; + + case IEEE_CMD_SET_ENCRYPTION: + ret = wpa_set_encryption(dev, param, p->length); + break; + + case IEEE_CMD_MLME: + ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); + break; + + default: + DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd); + ret = -EOPNOTSUPP; + break; + + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + rtw_mfree((u8 *)param, p->length); + +out: + + //up(&ieee->wx_sem); + + return ret; + +} + +#ifdef CONFIG_AP_MODE +static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len) +{ + int ret = 0; + u32 wep_key_idx, wep_key_len,wep_total_len; + NDIS_802_11_WEP *pwep = NULL; + struct sta_info *psta = NULL, *pbcmc_sta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + //sizeof(struct ieee_param) = 64 bytes; + //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) + if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) + { + ret = -EINVAL; + goto exit; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + if (param->u.crypt.idx >= WEP_KEYS +#ifdef CONFIG_IEEE80211W + && param->u.crypt.idx > BIP_MAX_KEYID +#endif /* CONFIG_IEEE80211W */ + ) + { + ret = -EINVAL; + goto exit; + } + } + else + { + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(!psta) + { + //ret = -EINVAL; + DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n"); + goto exit; + } + } + + if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL)) + { + //todo:clear default encryption keys + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; + psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled; + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + + DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx); + + goto exit; + } + + + if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL)) + { + DBG_871X("r871x_set_encryption, crypt.alg = WEP\n"); + + wep_key_idx = param->u.crypt.idx; + wep_key_len = param->u.crypt.key_len; + + DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len); + + if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0)) + { + ret = -EINVAL; + goto exit; + } + + + if (wep_key_len > 0) + { + wep_key_len = wep_key_len <= 5 ? 5 : 13; + wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial); + pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len); + if(pwep == NULL){ + DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n"); + goto exit; + } + + _rtw_memset(pwep, 0, wep_total_len); + + pwep->KeyLength = wep_key_len; + pwep->Length = wep_total_len; + + } + + pwep->KeyIndex = wep_key_idx; + + _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); + + if(param->u.crypt.set_tx) + { + DBG_871X("wep, set_tx=1\n"); + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto; + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->dot11PrivacyAlgrthm=_WEP40_; + psecuritypriv->dot118021XGrpPrivacy=_WEP40_; + + if(pwep->KeyLength==13) + { + psecuritypriv->dot11PrivacyAlgrthm=_WEP104_; + psecuritypriv->dot118021XGrpPrivacy=_WEP104_; + } + + + psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx; + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); + + psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength; + + rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1); + } + else + { + DBG_871X("wep, set_tx=0\n"); + + //don't update "psecuritypriv->dot11PrivacyAlgrthm" and + //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam + + _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength); + + psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength; + + rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0); + } + + goto exit; + + } + + + if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key + { + if(param->u.crypt.set_tx ==1) + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_871X("%s, set group_key, WEP\n", __FUNCTION__); + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } +#ifdef CONFIG_IEEE80211W + else if (strcmp(param->u.crypt.alg, "BIP") == 0) { + int no; + + DBG_871X("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx); + /* save the IGTK key, length 16 bytes */ + _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16:param->u.crypt.key_len)); + /* DBG_871X("IGTK key below:\n"); + for(no=0;no<16;no++) + printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]); + DBG_871X("\n"); */ + padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx; + padapter->securitypriv.binstallBIPkey = _TRUE; + DBG_871X(" ~~~~set sta key:IGKT\n"); + goto exit; + } +#endif /* CONFIG_IEEE80211W */ + else + { + DBG_871X("%s, set group_key, none\n", __FUNCTION__); + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + goto exit; + + } + + if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x + { + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + if(param->u.crypt.set_tx ==1) + { + _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psta->dot118021XPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _TKIP_; + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + + DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__); + + psta->dot118021XPrivacy = _AES_; + } + else + { + DBG_871X("%s, set pairwise key, none\n", __FUNCTION__); + + psta->dot118021XPrivacy = _NO_PRIVACY_; + } + + rtw_ap_set_pairwise_key(padapter, psta); + + psta->ieee8021x_blocked = _FALSE; + + psta->bpairwise_key_installed = _TRUE; + + } + else//group key??? + { + if(strcmp(param->u.crypt.alg, "WEP") == 0) + { + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + psecuritypriv->dot118021XGrpPrivacy = _WEP40_; + if(param->u.crypt.key_len==13) + { + psecuritypriv->dot118021XGrpPrivacy = _WEP104_; + } + } + else if(strcmp(param->u.crypt.alg, "TKIP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _TKIP_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + + //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); + //set mic key + _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8); + _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8); + + psecuritypriv->busetkipkey = _TRUE; + + } + else if(strcmp(param->u.crypt.alg, "CCMP") == 0) + { + psecuritypriv->dot118021XGrpPrivacy = _AES_; + + _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len)); + } + else + { + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + } + + psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx; + + psecuritypriv->binstallGrpkey = _TRUE; + + psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!! + + rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx); + + pbcmc_sta=rtw_get_bcmc_stainfo(padapter); + if(pbcmc_sta) + { + pbcmc_sta->ieee8021x_blocked = _FALSE; + pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy + } + + } + + } + + } + +exit: + + if(pwep) + { + rtw_mfree((u8 *)pwep, wep_total_len); + } + + return ret; + +} + +static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + unsigned char *pbuf = param->u.bcn_ie.buf; + + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); + + if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) + pstapriv->max_num_sta = NUM_STA; + + + if(rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed + ret = 0; + else + ret = -EINVAL; + + + return ret; + +} + +static int rtw_hostapd_sta_flush(struct net_device *dev) +{ + //_irqL irqL; + //_list *phead, *plist; + int ret=0; + //struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + //struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("%s\n", __FUNCTION__); + + flush_all_cam_entry(padapter); //clear CAM + + ret = rtw_sta_flush(padapter, _TRUE); + + return ret; + +} + +static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) +{ + _irqL irqL; + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + +/* + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta); + //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + rtw_free_stainfo(padapter, psta); + //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); + + psta = NULL; + } +*/ + //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + int flags = param->u.add_sta.flags; + + //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta); + + psta->aid = param->u.add_sta.aid;//aid=1~2007 + + _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + + + //check wmm cap. + if(WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if(pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + +#ifdef CONFIG_80211N_HT + //chec 802.11n ht cap. + if(WLAN_STA_HT&flags) + { + psta->htpriv.ht_option = _TRUE; + psta->qos_option = 1; + _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); + } + else + { + psta->htpriv.ht_option = _FALSE; + } + + if(pmlmepriv->htpriv.ht_option == _FALSE) + psta->htpriv.ht_option = _FALSE; +#endif + + + update_sta_info_apmode(padapter, psta); + + + } + else + { + ret = -ENOMEM; + } + + return ret; + +} + +static int rtw_del_sta(struct net_device *dev, struct ieee_param *param) +{ + _irqL irqL; + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + u8 updated=_FALSE; + + //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + if(rtw_is_list_empty(&psta->asoc_list)==_FALSE) + { + rtw_list_delete(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE); + + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL); + + psta = NULL; + + } + else + { + DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n"); + + //ret = -1; + } + + + return ret; + +} + +static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param; + struct sta_data *psta_data = (struct sta_data *)param_ex->data; + + DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff && + param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff && + param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr); + if(psta) + { +#if 0 + struct { + u16 aid; + u16 capability; + int flags; + u32 sta_set; + u8 tx_supp_rates[16]; + u32 tx_supp_rates_len; + struct rtw_ieee80211_ht_cap ht_cap; + u64 rx_pkts; + u64 rx_bytes; + u64 rx_drops; + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; + } get_sta; +#endif + psta_data->aid = (u16)psta->aid; + psta_data->capability = psta->capability; + psta_data->flags = psta->flags; + +/* + nonerp_set : BIT(0) + no_short_slot_time_set : BIT(1) + no_short_preamble_set : BIT(2) + no_ht_gf_set : BIT(3) + no_ht_set : BIT(4) + ht_20mhz_set : BIT(5) +*/ + + psta_data->sta_set =((psta->nonerp_set) | + (psta->no_short_slot_time_set <<1) | + (psta->no_short_preamble_set <<2) | + (psta->no_ht_gf_set <<3) | + (psta->no_ht_set <<4) | + (psta->ht_20mhz_set <<5)); + + psta_data->tx_supp_rates_len = psta->bssratelen; + _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen); +#ifdef CONFIG_80211N_HT + _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap)); +#endif //CONFIG_80211N_HT + psta_data->rx_pkts = psta->sta_stats.rx_data_pkts; + psta_data->rx_bytes = psta->sta_stats.rx_bytes; + psta_data->rx_drops = psta->sta_stats.rx_drops; + + psta_data->tx_pkts = psta->sta_stats.tx_pkts; + psta_data->tx_bytes = psta->sta_stats.tx_bytes; + psta_data->tx_drops = psta->sta_stats.tx_drops; + + + } + else + { + ret = -1; + } + + return ret; + +} + +static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param) +{ + int ret=0; + struct sta_info *psta = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr)); + + if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE) + { + return -EINVAL; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if(psta) + { + if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) + { + int wpa_ie_len; + int copy_len; + + wpa_ie_len = psta->wpa_ie[1]; + + copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2); + + param->u.wpa_ie.len = copy_len; + + _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len); + } + else + { + //ret = -1; + DBG_871X("sta's wpa_ie is NONE\n"); + } + } + else + { + ret = -1; + } + + return ret; + +} + +static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04}; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_beacon_ie) + { + rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len); + pmlmepriv->wps_beacon_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len); + pmlmepriv->wps_beacon_ie_len = ie_len; + if ( pmlmepriv->wps_beacon_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len); + + update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE); + + pmlmeext->bstart_bss = _TRUE; + + } + + + return ret; + +} + +static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_probe_resp_ie) + { + rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len); + pmlmepriv->wps_probe_resp_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len); + pmlmepriv->wps_probe_resp_ie_len = ie_len; + if ( pmlmepriv->wps_probe_resp_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len); + } + + + return ret; + +} + +static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + int ie_len; + + DBG_871X("%s, len=%d\n", __FUNCTION__, len); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + ie_len = len-12-2;// 12 = param header, 2:no packed + + + if(pmlmepriv->wps_assoc_resp_ie) + { + rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); + pmlmepriv->wps_assoc_resp_ie = NULL; + } + + if(ie_len>0) + { + pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len); + pmlmepriv->wps_assoc_resp_ie_len = ie_len; + if ( pmlmepriv->wps_assoc_resp_ie == NULL) { + DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + return -EINVAL; + } + + _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len); + } + + + return ret; + +} + +static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlmepriv = &(adapter->mlmepriv); + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info); + int ie_len; + u8 *ssid_ie; + char ssid[NDIS_802_11_LENGTH_SSID + 1]; + sint ssid_len = 0; + u8 ignore_broadcast_ssid; + + if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE) + return -EPERM; + + if (param->u.bcn_ie.reserved[0] != 0xea) + return -EINVAL; + + mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1]; + + ie_len = len-12-2;// 12 = param header, 2:no packed + ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len); + + if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) { + WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network; + WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network; + + _rtw_memcpy(ssid, ssid_ie+2, ssid_len); + ssid[ssid_len] = 0x0; + + if(0) + DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + ssid, ssid_len, + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + + _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len); + pbss_network->Ssid.SsidLength = ssid_len; + _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len); + pbss_network_ext->Ssid.SsidLength = ssid_len; + + if(0) + DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter), + pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength, + pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength); + } + + DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter), + ignore_broadcast_ssid, ssid, ssid_len); + + return ret; +} + +static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + ret = rtw_acl_remove_sta(padapter, param->sta_addr); + + return ret; + +} + +static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + { + return -EINVAL; + } + + ret = rtw_acl_add_sta(padapter, param->sta_addr); + + return ret; + +} + +static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len) +{ + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + return -EINVAL; + + rtw_set_macaddr_acl(padapter, param->u.mlme.command); + + return ret; +} + +static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p) +{ + struct ieee_param *param; + int ret=0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + //DBG_871X("%s\n", __FUNCTION__); + + /* + * this function is expect to call in master mode, which allows no power saving + * so, we just check hw_init_completed + */ + + if (!rtw_is_hw_init_completed(padapter)) { + ret = -EPERM; + goto out; + } + + + //if (p->length < sizeof(struct ieee_param) || !p->pointer){ + if(!p->pointer){ + ret = -EINVAL; + goto out; + } + + param = (struct ieee_param *)rtw_malloc(p->length); + if (param == NULL) + { + ret = -ENOMEM; + goto out; + } + + if (copy_from_user(param, p->pointer, p->length)) + { + rtw_mfree((u8*)param, p->length); + ret = -EFAULT; + goto out; + } + + //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd); + + switch (param->cmd) + { + case RTL871X_HOSTAPD_FLUSH: + + ret = rtw_hostapd_sta_flush(dev); + + break; + + case RTL871X_HOSTAPD_ADD_STA: + + ret = rtw_add_sta(dev, param); + + break; + + case RTL871X_HOSTAPD_REMOVE_STA: + + ret = rtw_del_sta(dev, param); + + break; + + case RTL871X_HOSTAPD_SET_BEACON: + + ret = rtw_set_beacon(dev, param, p->length); + + break; + + case RTL871X_SET_ENCRYPTION: + + ret = rtw_set_encryption(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_GET_WPAIE_STA: + + ret = rtw_get_sta_wpaie(dev, param); + + break; + + case RTL871X_HOSTAPD_SET_WPS_BEACON: + + ret = rtw_set_wps_beacon(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP: + + ret = rtw_set_wps_probe_resp(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP: + + ret = rtw_set_wps_assoc_resp(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_HIDDEN_SSID: + + ret = rtw_set_hidden_ssid(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_GET_INFO_STA: + + ret = rtw_ioctl_get_sta_data(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_SET_MACADDR_ACL: + + ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_ACL_ADD_STA: + + ret = rtw_ioctl_acl_add_sta(dev, param, p->length); + + break; + + case RTL871X_HOSTAPD_ACL_REMOVE_STA: + + ret = rtw_ioctl_acl_remove_sta(dev, param, p->length); + + break; + + default: + DBG_871X("Unknown hostapd request: %d\n", param->cmd); + ret = -EOPNOTSUPP; + break; + + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + + rtw_mfree((u8 *)param, p->length); + +out: + + return ret; + +} +#endif + +static int rtw_wx_set_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + +#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + char *ext_dbg; +#endif + + int ret = 0; + int len = 0; + char *ext; + int i; + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_point *dwrq = (struct iw_point*)awrq; + + //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n")); + if(dwrq->length == 0) + return -EFAULT; + + len = dwrq->length; + if (!(ext = rtw_vmalloc(len))) + return -ENOMEM; + + if (copy_from_user(ext, dwrq->pointer, len)) { + rtw_vmfree(ext, len); + return -EFAULT; + } + + + //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, + // ("rtw_wx_set_priv: %s req=%s\n", + // dev->name, ext)); + + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + if (!(ext_dbg = rtw_vmalloc(len))) + { + rtw_vmfree(ext, len); + return -ENOMEM; + } + + _rtw_memcpy(ext_dbg, ext, len); + #endif + + //added for wps2.0 @20110524 + if(dwrq->flags == 0x8766 && len > 8) + { + u32 cp_sz; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + u8 *probereq_wpsie = ext; + int probereq_wpsie_len = len; + u8 wps_oui[4]={0x0,0x50,0xf2,0x04}; + + if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) && + (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE)) + { + cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len; + + if(pmlmepriv->wps_probe_req_ie) + { + u32 free_len = pmlmepriv->wps_probe_req_ie_len; + pmlmepriv->wps_probe_req_ie_len = 0; + rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len); + pmlmepriv->wps_probe_req_ie = NULL; + } + + pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz); + if ( pmlmepriv->wps_probe_req_ie == NULL) { + printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__); + ret = -EINVAL; + goto FREE_EXT; + + } + + _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz); + pmlmepriv->wps_probe_req_ie_len = cp_sz; + + } + + goto FREE_EXT; + + } + + if( len >= WEXT_CSCAN_HEADER_SIZE + && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE + ){ + ret = rtw_wx_set_scan(dev, info, awrq, ext); + goto FREE_EXT; + } + +#ifdef CONFIG_ANDROID + //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); + + i = rtw_android_cmdstr_to_num(ext); + + switch(i) { + case ANDROID_WIFI_CMD_START : + indicate_wx_custom_event(padapter, "START"); + break; + case ANDROID_WIFI_CMD_STOP : + indicate_wx_custom_event(padapter, "STOP"); + break; + case ANDROID_WIFI_CMD_RSSI : + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); + } else { + sprintf(ext, "OK"); + } + } + break; + case ANDROID_WIFI_CMD_LINKSPEED : + { + u16 mbps = rtw_get_cur_max_rate(padapter)/10; + sprintf(ext, "LINKSPEED %d", mbps); + } + break; + case ANDROID_WIFI_CMD_MACADDR : + sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr)); + break; + case ANDROID_WIFI_CMD_SCAN_ACTIVE : + { + //rtw_set_scan_mode(padapter, SCAN_ACTIVE); + sprintf(ext, "OK"); + } + break; + case ANDROID_WIFI_CMD_SCAN_PASSIVE : + { + //rtw_set_scan_mode(padapter, SCAN_PASSIVE); + sprintf(ext, "OK"); + } + break; + + case ANDROID_WIFI_CMD_COUNTRY : + { + char country_code[10]; + sscanf(ext, "%*s %s", country_code); + rtw_set_country(padapter, country_code); + sprintf(ext, "OK"); + } + break; + default : + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__, + dev->name, ext_dbg); + #endif + + sprintf(ext, "OK"); + + } + + if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) ) + ret = -EFAULT; + + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__, + dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1)); + #endif +#endif //end of CONFIG_ANDROID + + +FREE_EXT: + + rtw_vmfree(ext, len); + #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV + rtw_vmfree(ext_dbg, len); + #endif + + //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", + // dev->name, ret); + + return ret; + +} +#ifdef CONFIG_WOWLAN +static int rtw_wowlan_ctrl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wowlan_ioctl_param poidparam; + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; +#ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; +#endif + struct sta_info *psta = NULL; + int ret = 0; + u32 start_time = rtw_get_current_time(); + poidparam.subcode = 0; + + DBG_871X("+rtw_wowlan_ctrl: %s\n", extra); + + 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 (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + rtw_scan_abort(padapter); + + if (_rtw_memcmp(extra, "enable", 6)) { + + padapter->registrypriv.mp_mode = 1; + + rtw_suspend_common(padapter); + + } else if (_rtw_memcmp(extra, "disable", 7)) { +#ifdef CONFIG_USB_HCI + RTW_ENABLE_FUNC(padapter, DF_RX_BIT); + RTW_ENABLE_FUNC(padapter, DF_TX_BIT); +#endif + rtw_resume_common(padapter); + +#ifdef CONFIG_PNO_SUPPORT + pwrctrlpriv->wowlan_pno_enable = _FALSE; +#endif //CONFIG_PNO_SUPPORT + + padapter->registrypriv.mp_mode = 0; + } else { + DBG_871X("[%s] Invalid Parameter.\n", __func__); + goto _rtw_wowlan_ctrl_exit_free; + } + //mutex_lock(&ioctl_mutex); +_rtw_wowlan_ctrl_exit_free: + DBG_871X("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode); + DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__, + rtw_get_passing_time_ms(start_time)); +_rtw_wowlan_ctrl_exit: + return ret; +} + +static bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern, + int *pattern_len, char *bit_mask) +{ + char *cp = NULL, *end = NULL; + size_t len = 0; + int pos = 0, mask_pos = 0, res = 0; + u8 member[2] = {0}; + + cp = strchr(input, '='); + if (cp) { + *cp = 0; + cp++; + } + + input = cp; + + while (1) { + cp = strchr(input, ':'); + + if (cp) { + len = strlen(input) - strlen(cp); + *cp = 0; + cp++; + } else { + len = 2; + } + + if (bit_mask && (strcmp(input, "-") == 0 || + strcmp(input, "xx") == 0 || + strcmp(input, "--") == 0)) { + /* skip this byte and leave mask bit unset */ + } else { + u8 hex; + strncpy(member, input, len); + if (!rtw_check_pattern_valid(member, sizeof(member))) { + DBG_871X("%s:[ERROR] pattern is invalid!!\n", + __func__); + goto error; + } + + res = sscanf(member, "%02hhx", &hex); + pattern[pos] = hex; + mask_pos = pos / 8; + if (bit_mask) + bit_mask[mask_pos] |= 1 << (pos % 8); + } + + pos++; + if (!cp) + break; + input = cp; + } + + (*pattern_len) = pos; + + return _TRUE; +error: + return _FALSE; +} + +/* + * IP filter This pattern if for a frame containing a ip packet: + * AA:AA:AA:AA:AA:AA:BB:BB:BB:BB:BB:BB:CC:CC:DD:-:-:-:-:-:-:-:-:EE:-:-:FF:FF:FF:FF:GG:GG:GG:GG:HH:HH:II:II + * + * A: Ethernet destination address + * B: Ethernet source address + * C: Ethernet protocol type + * D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20) + * E: IP protocol + * F: IP source address ( 192.168.0.4: C0:A8:00:2C ) + * G: IP destination address ( 192.168.0.4: C0:A8:00:2C ) + * H: Source port (1024: 04:00) + * I: Destination port (1024: 04:00) + */ + +static int rtw_wowlan_set_pattern(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wowlan_ioctl_param poidparam; + int ret = 0, len = 0, i = 0; + u32 start_time = rtw_get_current_time(); + u8 input[wrqu->data.length]; + u8 index = 0; + + poidparam.subcode = 0; + + if (!check_fwstate(pmlmepriv, _FW_LINKED) && + check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + ret = -EFAULT; + DBG_871X("Please Connect With AP First!!\n"); + goto _rtw_wowlan_set_pattern_exit; + } + + if (wrqu->data.length <= 0) { + ret = -EFAULT; + DBG_871X("ERROR: parameter length <= 0\n"); + goto _rtw_wowlan_set_pattern_exit; + } else { + /* set pattern */ + if (copy_from_user(input, + wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + /* leave PS first */ + rtw_ps_deny(padapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(padapter); + if (strncmp(input, "pattern=", 8) == 0) { + if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_NUM) { + DBG_871X("WARNING: priv-pattern is full(%d)\n", + MAX_WKFM_NUM); + DBG_871X("WARNING: please clean priv-pattern first\n"); + ret = -EINVAL; + goto _rtw_wowlan_set_pattern_exit; + } else { + index = pwrpriv->wowlan_pattern_idx; + + ret = rtw_wowlan_parser_pattern_cmd(input, + pwrpriv->patterns[index].content, + &pwrpriv->patterns[index].len, + pwrpriv->patterns[index].mask); + + if (ret == _TRUE) { + pwrpriv->wowlan_pattern_idx++; + pwrpriv->wowlan_pattern = _TRUE; + } + } + } else if (strncmp(input, "clean", 5) == 0) { + poidparam.subcode = WOWLAN_PATTERN_CLEAN; + rtw_hal_set_hwreg(padapter, + HW_VAR_WOWLAN, (u8 *)&poidparam); + pwrpriv->wowlan_pattern = _FALSE; + } else if (strncmp(input, "show", 4) == 0) { + for (i = 0 ; i < MAX_WKFM_NUM ; i++) { + DBG_871X("=======[%d]=======\n", i); + rtw_read_from_frame_mask(padapter, i); + } + + DBG_871X("********[RTK priv-patterns]*********\n"); + for (i = 0 ; i < MAX_WKFM_NUM ; i++) + rtw_dump_priv_pattern(padapter, i); + } else { + DBG_871X("ERROR: incorrect parameter!\n"); + ret = -EINVAL; + } + rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); + } +_rtw_wowlan_set_pattern_exit: + return ret; +} +#endif //CONFIG_WOWLAN + +#ifdef CONFIG_AP_WOWLAN +static int rtw_ap_wowlan_ctrl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct wowlan_ioctl_param poidparam; + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_info *psta = NULL; + int ret = 0; + u32 start_time = rtw_get_current_time(); + poidparam.subcode = 0; + + DBG_871X("+rtw_ap_wowlan_ctrl: %s\n", extra); + + if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + DBG_871X("[%s] It is not AP mode!!\n", __func__); + goto _rtw_ap_wowlan_ctrl_exit_free; + } + + if (_rtw_memcmp(extra, "enable", 6)) { + + pwrctrlpriv->wowlan_ap_mode = _TRUE; + + rtw_suspend_common(padapter); + } else if (_rtw_memcmp(extra, "disable", 7)) { +#ifdef CONFIG_USB_HCI + RTW_ENABLE_FUNC(padapter, DF_RX_BIT); + RTW_ENABLE_FUNC(padapter, DF_TX_BIT); +#endif + rtw_resume_common(padapter); + } else { + DBG_871X("[%s] Invalid Parameter.\n", __func__); + goto _rtw_ap_wowlan_ctrl_exit_free; + } + //mutex_lock(&ioctl_mutex); +_rtw_ap_wowlan_ctrl_exit_free: + DBG_871X("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode); + DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__, + rtw_get_passing_time_ms(start_time)); +_rtw_ap_wowlan_ctrl_exit: + return ret; +} +#endif //CONFIG_AP_WOWLAN + +static int rtw_pm_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + unsigned mode = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra ); + + if ( _rtw_memcmp( extra, "lps=", 4 ) ) + { + sscanf(extra+4, "%u", &mode); + ret = rtw_pm_set_lps(padapter,mode); + } + else if ( _rtw_memcmp( extra, "ips=", 4 ) ) + { + sscanf(extra+4, "%u", &mode); + ret = rtw_pm_set_ips(padapter,mode); + } + else{ + ret = -EINVAL; + } + + return ret; +} + +static int rtw_mp_efuse_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + PEFUSE_HAL pEfuseHal; + struct iw_point *wrqu; + + u8 *PROMContent = pHalData->efuse_eeprom_data; + u8 ips_mode = IPS_NUM; // init invalid value + u8 lps_mode = PS_MODE_NUM; // init invalid value + struct pwrctrl_priv *pwrctrlpriv ; + u8 *data = NULL; + u8 *rawdata = NULL; + char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00}; + u16 i=0, j=0, mapLen=0, addr=0, cnts=0; + u16 max_available_size=0, raw_cursize=0, raw_maxsize=0; + int err; + #ifdef CONFIG_IOL + u8 org_fw_iol = padapter->registrypriv.fw_iol;// 0:Disable, 1:enable, 2:by usb speed + #endif + + wrqu = (struct iw_point*)wdata; + pwrctrlpriv = adapter_to_pwrctl(padapter); + pEfuseHal = &pHalData->EfuseHal; + + err = 0; + data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); + if (data == NULL) + { + err = -ENOMEM; + goto exit; + } + rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN); + if (rawdata == NULL) + { + err = -ENOMEM; + goto exit; + } + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + { + err = -EFAULT; + goto exit; + } + #ifdef CONFIG_LPS + lps_mode = pwrctrlpriv->power_mgnt;//keep org value + rtw_pm_set_lps(padapter,PS_MODE_ACTIVE); + #endif + + #ifdef CONFIG_IPS + ips_mode = pwrctrlpriv->ips_mode;//keep org value + rtw_pm_set_ips(padapter,IPS_NONE); + #endif + + pch = extra; + DBG_871X("%s: in=%s\n", __FUNCTION__, extra); + + i = 0; + //mac 16 "00e04c871200" rmap,00,2 + while ((token = strsep(&pch, ",")) != NULL) + { + if (i > 2) break; + tmp[i] = token; + i++; + } + #ifdef CONFIG_IOL + padapter->registrypriv.fw_iol = 0;// 0:Disable, 1:enable, 2:by usb speed + #endif + + if(strcmp(tmp[0], "status") == 0){ + sprintf(extra, "Load File efuse=%s,Load File MAC=%s" + , pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK" + , pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK" + ); + goto exit; + } + else if (strcmp(tmp[0], "drvmap") == 0) + { + mapLen = EFUSE_MAP_SIZE; + + sprintf(extra, "\n"); + for (i = 0; i < EFUSE_MAP_SIZE; i += 16) + { +// DBG_871X("0x%02x\t", i); + sprintf(extra, "%s0x%02x\t", extra, i); + for (j=0; j<8; j++) { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, PROMContent[i+j]); + } +// DBG_871X("\t"); + sprintf(extra, "%s\t", extra); + for (; j<16; j++) { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, PROMContent[i+j]); + } +// DBG_871X("\n"); + sprintf(extra,"%s\n",extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0], "realmap") == 0) + { + mapLen = EFUSE_MAP_SIZE; + if (rtw_efuse_mask_map_read(padapter, EFUSE_WIFI , mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) + { + DBG_871X("%s: read realmap Fail!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("OFFSET\tVALUE(hex)\n"); + sprintf(extra, "\n"); + for (i = 0; i < EFUSE_MAP_SIZE; i += 16) + { +// DBG_871X("0x%02x\t", i); + sprintf(extra, "%s0x%02x\t", extra, i); + for (j=0; j<8; j++) { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra, "%s\t", extra); + for (; j<16; j++) { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra,"%s\n",extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0], "rmap") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + + // rmap addr cnts + addr = simple_strtoul(tmp[1], &ptmp, 16); + DBG_871X("%s: addr=%x\n", __FUNCTION__, addr); + + cnts = simple_strtoul(tmp[2], &ptmp, 10); + if (cnts == 0) + { + DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_size, _FALSE); + if ((addr+ cnts) > max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EINVAL; + goto exit; + } + + if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("%s: rtw_efuse_mask_map_read error!\n", __func__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("%s: data={", __FUNCTION__); + *extra = 0; + for (i=0; i= 512) + mapLen = 512; + + _rtw_memset(extra,'\0',strlen(extra)); + + sprintf(extra, "\n0x00\t"); + + for (i = 0; i < mapLen ; i++) { + sprintf(extra, "%s%02X", extra, rawdata[i]); + if ((i & 0xF) == 0xF) { + sprintf(extra, "%s\n", extra); + sprintf(extra, "%s0x%02x\t", extra, i+1); + } else if ((i & 0x7) == 0x7) { + sprintf(extra, "%s \t", extra); + } else { + sprintf(extra, "%s ", extra); + } + } + + } else if (strcmp(tmp[0], "realrawb") == 0) { + addr = 0; + mapLen = EFUSE_MAX_SIZE; + DBG_871X("EFUSE_MAX_SIZE =%d\n", EFUSE_MAX_SIZE); + if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) + { + DBG_871X("%s: rtw_efuse_access Fail!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + _rtw_memset(extra,'\0',strlen(extra)); + // DBG_871X("%s: realraw={\n", __FUNCTION__); + sprintf(extra, "\n0x00\t"); + for (i= 512; i< mapLen; i++) + { + // DBG_871X("%02X", rawdata[i]); + sprintf(extra, "%s%02X", extra, rawdata[i]); + if ((i & 0xF) == 0xF) { + // DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + sprintf(extra, "%s0x%02x\t", extra, i+1); + } + else if ((i & 0x7) == 0x7){ + // DBG_871X("\t"); + sprintf(extra, "%s \t", extra); + } else { + // DBG_871X(" "); + sprintf(extra, "%s ", extra); + } + } + // DBG_871X("}\n"); + } + else if (strcmp(tmp[0], "mac") == 0) + { + if (hal_efuse_macaddr_offset(padapter) == -1) { + err = -EFAULT; + goto exit; + } + + addr = hal_efuse_macaddr_offset(padapter); + cnts = 6; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if ((addr + cnts) > max_available_size) { + DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("%s: rtw_efuse_mask_map_read error!\n", __func__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("%s: MAC address={", __FUNCTION__); + *extra = 0; + for (i=0; i max_available_size) + { + DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("%s: {VID,PID}={", __FUNCTION__); + *extra = 0; + for (i=0; iBTEfuseInitMap) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("OFFSET\tVALUE(hex)\n"); + sprintf(extra, "\n"); + for (i=0; i<512; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF + { +// DBG_871X("0x%03x\t", i); + sprintf(extra, "%s0x%03x\t", extra, i); + for (j=0; j<8; j++) { +// DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra,"%s\t",extra); + for (; j<16; j++) { +// DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0],"btbmap") == 0) + { + BTEfuse_PowerSwitch(padapter,1,_TRUE); + + mapLen = EFUSE_BT_MAX_MAP_LEN; + if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + +// DBG_871X("OFFSET\tVALUE(hex)\n"); + sprintf(extra, "\n"); + for (i=512; i<1024 ; i+=16) + { +// DBG_871X("0x%03x\t", i); + sprintf(extra, "%s0x%03x\t", extra, i); + for (j=0; j<8; j++) + { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra,"%s\t",extra); + for (; j<16; j++) { +// DBG_871X("%02X ", data[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0],"btrmap") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + + BTEfuse_PowerSwitch(padapter,1,_TRUE); + + // rmap addr cnts + addr = simple_strtoul(tmp[1], &ptmp, 16); + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + + cnts = simple_strtoul(tmp[2], &ptmp, 10); + if (cnts == 0) + { + DBG_871X("%s: btrmap Fail!! cnts error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if ((addr + cnts) > max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + + *extra = 0; +// DBG_871X("%s: bt efuse data={", __FUNCTION__); + for (i=0; ifakeBTEfuseModifiedMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra, "%s\t", extra); + for (; j<16; j++) { +// DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0],"btbfake") == 0) + { +// DBG_871X("OFFSET\tVALUE(hex)\n"); + sprintf(extra, "\n"); + for (i=512; i<1024; i+=16) + { +// DBG_871X("0x%03x\t", i); + sprintf(extra, "%s0x%03x\t", extra, i); + for (j=0; j<8; j++) { +// DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra, "%s\t", extra); + for (; j<16; j++) { +// DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + } +// DBG_871X("\n"); + } + else if (strcmp(tmp[0],"wlrfkmap")== 0) + { +// DBG_871X("OFFSET\tVALUE(hex)\n"); + sprintf(extra, "\n"); + for (i=0; ifakeEfuseModifiedMap[i+j]); + sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]); + } +// DBG_871X("\t"); + sprintf(extra, "%s\t", extra); + for (; j<16; j++) { +// DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]); + sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]); + } +// DBG_871X("\n"); + sprintf(extra, "%s\n", extra); + } +// DBG_871X("\n"); + + } + else if (strcmp(tmp[0],"wlrfkrmap")== 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + // rmap addr cnts + addr = simple_strtoul(tmp[1], &ptmp, 16); + DBG_871X("%s: addr=%x\n", __FUNCTION__, addr); + + cnts = simple_strtoul(tmp[2], &ptmp, 10); + if (cnts == 0) + { + DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + + // DBG_871X("%s: data={", __FUNCTION__); + *extra = 0; + for (i=0; ifakeEfuseModifiedMap[addr+i]); + sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr+i]); + } + } + else if (strcmp(tmp[0],"btrfkrmap")== 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + // rmap addr cnts + addr = simple_strtoul(tmp[1], &ptmp, 16); + DBG_871X("%s: addr=%x\n", __FUNCTION__, addr); + + cnts = simple_strtoul(tmp[2], &ptmp, 10); + if (cnts == 0) + { + DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__); + err = -EINVAL; + goto exit; + } + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + + // DBG_871X("%s: data={", __FUNCTION__); + *extra = 0; + for (i=0; ifakeBTEfuseModifiedMap[addr+i]); + sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr+i]); + } + } + else + { + sprintf(extra, "Command not found!"); + } + +exit: + if (data) + rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN); + if (rawdata) + rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN); + if (!err) + wrqu->length = strlen(extra); + + if (padapter->registrypriv.mp_mode == 0) + { + #ifdef CONFIG_IPS + rtw_pm_set_ips(padapter, ips_mode); +#endif // CONFIG_IPS + + #ifdef CONFIG_LPS + rtw_pm_set_lps(padapter, lps_mode); +#endif // CONFIG_LPS + } + + #ifdef CONFIG_IOL + padapter->registrypriv.fw_iol = org_fw_iol;// 0:Disable, 1:enable, 2:by usb speed + #endif + return err; +} + +static int rtw_mp_efuse_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu; + PADAPTER padapter; + struct pwrctrl_priv *pwrctrlpriv ; + PHAL_DATA_TYPE pHalData; + PEFUSE_HAL pEfuseHal; + + u8 ips_mode = IPS_NUM; // init invalid value + u8 lps_mode = PS_MODE_NUM; // init invalid value + u32 i=0,j=0, jj, kk; + u8 *setdata = NULL; + u8 *ShadowMapBT = NULL; + u8 *ShadowMapWiFi = NULL; + u8 *setrawdata = NULL; + char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00}; + u16 addr=0xFF, cnts=0, BTStatus=0 , max_available_size=0; + int err; + + wrqu = (struct iw_point*)wdata; + padapter = rtw_netdev_priv(dev); + pwrctrlpriv = adapter_to_pwrctl(padapter); + pHalData = GET_HAL_DATA(padapter); + pEfuseHal = &pHalData->EfuseHal; + err = 0; + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + setdata = rtw_zmalloc(1024); + if (setdata == NULL) + { + err = -ENOMEM; + goto exit; + } + ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN); + if (ShadowMapBT == NULL) + { + err = -ENOMEM; + goto exit; + } + ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE); + if (ShadowMapWiFi == NULL) + { + err = -ENOMEM; + goto exit; + } + setrawdata = rtw_malloc(EFUSE_MAX_SIZE); + if (setrawdata == NULL) + { + err = -ENOMEM; + goto exit; + } + + #ifdef CONFIG_LPS + lps_mode = pwrctrlpriv->power_mgnt;//keep org value + rtw_pm_set_lps(padapter,PS_MODE_ACTIVE); + #endif + + #ifdef CONFIG_IPS + ips_mode = pwrctrlpriv->ips_mode;//keep org value + rtw_pm_set_ips(padapter,IPS_NONE); + #endif + + pch = extra; + DBG_871X("%s: in=%s\n", __FUNCTION__, extra); + + i = 0; + while ((token = strsep(&pch, ",")) != NULL) + { + if (i > 2) break; + tmp[i] = token; + i++; + } + + // tmp[0],[1],[2] + // wmap,addr,00e04c871200 + if (strcmp(tmp[0], "wmap") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + +#if 1 + // unknown bug workaround, need to fix later + addr=0x1ff; + rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+3, 0x72); + rtw_msleep_os(10); + rtw_read8(padapter, EFUSE_CTRL); +#endif + + addr = simple_strtoul(tmp[1], &ptmp, 16); + addr &= 0xFFF; + + cnts = strlen(tmp[2]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: map data=%s\n", __FUNCTION__, tmp[2]); + + for (jj=0, kk=0; jj max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) + { + DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + *extra = 0; + DBG_871X("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__); + if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) + { + if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts)) + { + DBG_871X("%s: WiFi write map afterf compare success\n", __FUNCTION__); + sprintf(extra, "WiFi write map compare OK\n"); + err = 0; + goto exit; + } + else + { + sprintf(extra, "WiFi write map compare FAIL\n"); + DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__); + err = 0; + goto exit; + } + } + } + else if (strcmp(tmp[0], "wraw") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + + addr = simple_strtoul( tmp[1], &ptmp, 16 ); + addr &= 0xFFF; + + cnts = strlen(tmp[2]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: raw data=%s\n", __FUNCTION__, tmp[2]); + + for (jj=0, kk=0; jj 6) + { + DBG_871X("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]); + err = -EFAULT; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: MAC address=%s\n", __FUNCTION__, tmp[1]); + + for (jj=0, kk=0; jj max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) + { + DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + } + else if (strcmp(tmp[0], "vidpid") == 0) + { + if (tmp[1]==NULL) + { + err = -EINVAL; + goto exit; + } + + // pidvid,da0b7881 + #ifdef CONFIG_RTL8188E + #ifdef CONFIG_USB_HCI + addr = EEPROM_VID_88EU; + #endif + #ifdef CONFIG_PCI_HCI + addr = EEPROM_VID_88EE; + #endif + #endif // CONFIG_RTL8188E + + #ifdef CONFIG_RTL8192E + #ifdef CONFIG_USB_HCI + addr = EEPROM_VID_8192EU; + #endif + #ifdef CONFIG_PCI_HCI + addr = EEPROM_VID_8192EE; + #endif + #endif // CONFIG_RTL8188E + + #ifdef CONFIG_RTL8723B + addr = EEPROM_VID_8723BU; + #endif + + #ifdef CONFIG_RTL8188F + addr = EEPROM_VID_8188FU; + #endif + + #ifdef CONFIG_RTL8703B + #ifdef CONFIG_USB_HCI + addr = EEPROM_VID_8703BU; + #endif /* CONFIG_USB_HCI */ + #endif /* CONFIG_RTL8703B */ + + cnts = strlen(tmp[1]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]); + + for (jj=0, kk=0; jj max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) + { + DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + } + else if (strcmp(tmp[0], "wldumpfake") == 0) + { + if (rtw_efuse_mask_map_read(padapter, 0, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) { + DBG_871X("%s: WiFi hw efuse dump to Fake map success\n", __func__); + } else { + DBG_871X("%s: WiFi hw efuse dump to Fake map Fail\n", __func__); + err = -EFAULT; + } + } + else if (strcmp(tmp[0], "btwmap") == 0) + { + rtw_write8(padapter, 0xa3, 0x05); //For 8723AB ,8821S ? + BTStatus=rtw_read8(padapter, 0xa0); + DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus); + if (BTStatus != 0x04) + { + sprintf(extra, "BT Status not Active Write FAIL\n"); + goto exit; + } + + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + BTEfuse_PowerSwitch(padapter,1,_TRUE); + + addr=0x1ff; + rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+3, 0x72); + rtw_msleep_os(10); + rtw_read8(padapter, EFUSE_CTRL); + + addr = simple_strtoul(tmp[1], &ptmp, 16); + addr &= 0xFFF; + + cnts = strlen(tmp[2]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: BT data=%s\n", __FUNCTION__, tmp[2]); + + for (jj=0, kk=0; jj max_available_size) + { + DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts); + err = -EFAULT; + goto exit; + } + + if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + *extra = 0; + DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__); + if ( (rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT ) == _SUCCESS ) ) + { + if (_rtw_memcmp((void*)ShadowMapBT ,(void*)setdata,cnts)) + { + DBG_871X("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__,BTStatus); + sprintf(extra, "BT write map compare OK"); + err = 0; + goto exit; + } + else + { + sprintf(extra, "BT write map compare FAIL"); + DBG_871X("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__,BTStatus); + err = 0; + goto exit; + } + } + } + else if (strcmp(tmp[0], "btwfake") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + + addr = simple_strtoul(tmp[1], &ptmp, 16); + addr &= 0xFFF; + + cnts = strlen(tmp[2]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]); + + for (jj=0, kk=0; jjfakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]); + } + } + else if (strcmp(tmp[0], "btdumpfake") == 0) + { + if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) { + DBG_871X("%s: BT read all map success\n", __FUNCTION__); + } else { + DBG_871X("%s: BT read all map Fail!\n", __FUNCTION__); + err = -EFAULT; + } + } + else if (strcmp(tmp[0], "btfk2map") == 0) + { + rtw_write8(padapter, 0xa3, 0x05); + BTStatus=rtw_read8(padapter, 0xa0); + DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus); + if (BTStatus != 0x04) + { + sprintf(extra, "BT Status not Active Write FAIL\n"); + goto exit; + } + + BTEfuse_PowerSwitch(padapter,1,_TRUE); + + addr=0x1ff; + rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03)); + rtw_msleep_os(10); + rtw_write8(padapter, EFUSE_CTRL+3, 0x72); + rtw_msleep_os(10); + rtw_read8(padapter, EFUSE_CTRL); + + _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if (max_available_size < 1) + { + err = -EFAULT; + goto exit; + } + + if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + + DBG_871X("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n"); + for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) + { + printk("0x%02x\t", i); + for (j=0; j<8; j++) { + printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } + printk("\t"); + + for (; j<16; j++) { + printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); + } + printk("\n"); + } + printk("\n"); +#if 1 + err = -EFAULT; + DBG_871X("%s: rtw_BT_efuse_map_read _rtw_memcmp \n", __FUNCTION__); + if ( (rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS ) ) + { + if (_rtw_memcmp((void*)pEfuseHal->fakeBTEfuseModifiedMap,(void*)pEfuseHal->fakeBTEfuseInitMap,EFUSE_BT_MAX_MAP_LEN)) + { + sprintf(extra, "BT write map compare OK"); + DBG_871X("%s: BT write map afterf compare success BTStatus=0x%x \n", __FUNCTION__,BTStatus); + err = 0; + goto exit; + } + else + { + sprintf(extra, "BT write map compare FAIL"); + if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) + { + DBG_871X("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__,i); + } + + if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) + { + DBG_871X("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n"); + + for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) + { + printk("0x%02x\t", i); + for (j=0; j<8; j++) { + printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]); + } + printk("\t"); + for (; j<16; j++) { + printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]); + } + printk("\n"); + } + printk("\n"); + } + DBG_871X("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__,BTStatus); + goto exit; + } + } +#endif + + } + else if (strcmp(tmp[0], "wlfk2map") == 0) + { + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if (max_available_size < 1) + { + err = -EFAULT; + goto exit; + } + if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) + { + DBG_871X("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__); + err = -EFAULT; + goto exit; + } + *extra = 0; + DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __func__); + if (rtw_efuse_mask_map_read(padapter, 0x00, EFUSE_MAP_SIZE, ShadowMapWiFi) == _SUCCESS) + { + if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts)) + { + DBG_871X("%s: WiFi write map afterf compare OK\n", __FUNCTION__); + sprintf(extra, "WiFi write map compare OK\n"); + err = 0; + goto exit; + } + else + { + sprintf(extra, "WiFi write map compare FAIL\n"); + DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__); + err = 0; + goto exit; + } + } + } + else if (strcmp(tmp[0], "wlwfake") == 0) + { + if ((tmp[1]==NULL) || (tmp[2]==NULL)) + { + err = -EINVAL; + goto exit; + } + + addr = simple_strtoul(tmp[1], &ptmp, 16); + addr &= 0xFFF; + + cnts = strlen(tmp[2]); + if (cnts%2) + { + err = -EINVAL; + goto exit; + } + cnts /= 2; + if (cnts == 0) + { + err = -EINVAL; + goto exit; + } + + DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr); + DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts); + DBG_871X("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]); + + for (jj=0, kk=0; jjfakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]); + } + _rtw_memset(extra, '\0', strlen(extra)); + sprintf(extra, "wlwfake OK\n"); + } + +exit: + if (setdata) + rtw_mfree(setdata, 1024); + if (ShadowMapBT) + rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN); + if (ShadowMapWiFi) + rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE); + if (setrawdata) + rtw_mfree(setrawdata, EFUSE_MAX_SIZE); + + wrqu->length = strlen(extra); + + if (padapter->registrypriv.mp_mode == 0) + { + #ifdef CONFIG_IPS + rtw_pm_set_ips(padapter, ips_mode); + #endif // CONFIG_IPS + + #ifdef CONFIG_LPS + rtw_pm_set_lps(padapter, lps_mode); + #endif // CONFIG_LPS + } + + return err; +} + + +#ifdef CONFIG_MP_INCLUDED + +#ifdef CONFIG_SDIO_INDIRECT_ACCESS +#define DBG_MP_SDIO_INDIRECT_ACCESS 1 +static int rtw_mp_sd_iread(struct net_device *dev + , struct iw_request_info *info + , struct iw_point *wrqu + , char *extra) +{ + char input[16]; + u8 width; + unsigned long addr; + u32 ret = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (wrqu->length > 16) { + DBG_871X(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length); + ret = -EINVAL; + goto exit; + } + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) { + DBG_871X(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter)); + ret = -EFAULT; + goto exit; + } + + _rtw_memset(extra, 0, wrqu->length); + + if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) { + DBG_871X(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter)); + ret = -EINVAL; + goto exit; + } + + if (addr > 0x3FFF) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr); + ret = -EINVAL; + goto exit; + } + + if (DBG_MP_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr); + + switch (width) { + case 1: + sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr)); + wrqu->length = strlen(extra); + break; + case 2: + sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr)); + wrqu->length = strlen(extra); + break; + case 4: + sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr)); + wrqu->length = strlen(extra); + break; + default: + wrqu->length = 0; + ret = -EINVAL; + break; + } + +exit: + return ret; +} + +static int rtw_mp_sd_iwrite(struct net_device *dev + , struct iw_request_info *info + , struct iw_point *wrqu + , char *extra) +{ + char width; + unsigned long addr, data; + int ret = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + char input[32]; + + if (wrqu->length > 32) { + DBG_871X(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length); + ret = -EINVAL; + goto exit; + } + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) { + DBG_871X(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter)); + ret = -EFAULT; + goto exit; + } + + _rtw_memset(extra, 0, wrqu->length); + + if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) { + DBG_871X(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter)); + ret = -EINVAL; + goto exit; + } + + if (addr > 0x3FFF) { + DBG_871X(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr); + ret = -EINVAL; + goto exit; + } + + if (DBG_MP_SDIO_INDIRECT_ACCESS) + DBG_871X(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data); + + switch (width) { + case 1: + if (data > 0xFF) { + ret = -EINVAL; + break; + } + rtw_sd_iwrite8(padapter, addr, data); + break; + case 2: + if (data > 0xFFFF) { + ret = -EINVAL; + break; + } + rtw_sd_iwrite16(padapter, addr, data); + break; + case 4: + rtw_sd_iwrite32(padapter, addr, data); + break; + default: + wrqu->length = 0; + ret = -EINVAL; + break; + } + +exit: + return ret; +} +#endif /* CONFIG_SDIO_INDIRECT_ACCESS */ + +static int rtw_mp_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + u32 subcmd = wrqu->flags; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (padapter == NULL) + { + return -ENETDOWN; + } + + if((padapter->bup == _FALSE )) + { + DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__); + return -ENETDOWN; + } + + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__); + return -ENETDOWN; + } + + + //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK); + + if (extra == NULL) + { + wrqu->length = 0; + return -EIO; + } + + switch(subcmd) + { + case MP_START: + DBG_871X("set case mp_start \n"); + rtw_mp_start (dev,info,wrqu,extra); + break; + + case MP_STOP: + DBG_871X("set case mp_stop \n"); + rtw_mp_stop (dev,info,wrqu,extra); + break; + + case MP_BANDWIDTH: + DBG_871X("set case mp_bandwidth \n"); + rtw_mp_bandwidth (dev,info,wrqu,extra); + break; + + case MP_RESET_STATS: + DBG_871X("set case MP_RESET_STATS \n"); + rtw_mp_reset_stats (dev,info,wrqu,extra); + break; + case MP_SetRFPathSwh: + DBG_871X("set MP_SetRFPathSwitch \n"); + rtw_mp_SetRFPath (dev,info,wdata,extra); + break; + case CTA_TEST: + DBG_871X("set CTA_TEST\n"); + rtw_cta_test_start (dev, info, wdata, extra); + break; + case MP_DISABLE_BT_COEXIST: + DBG_871X("set case MP_DISABLE_BT_COEXIST \n"); + rtw_mp_disable_bt_coexist(dev, info, wdata, extra); + break; +#ifdef CONFIG_WOWLAN + case MP_WOW_ENABLE: + DBG_871X("set case MP_WOW_ENABLE: %s\n", extra); + + rtw_wowlan_ctrl(dev, info, wdata, extra); + break; + case MP_WOW_SET_PATTERN: + DBG_871X("set case MP_WOW_SET_PATTERN: %s\n", extra); + rtw_wowlan_set_pattern(dev, info, wdata, extra); + break; +#endif +#ifdef CONFIG_AP_WOWLAN + case MP_AP_WOW_ENABLE: + DBG_871X("set case MP_AP_WOW_ENABLE: %s\n", extra); + rtw_ap_wowlan_ctrl(dev, info, wdata, extra); + break; +#endif + } + + + return 0; +} + + +static int rtw_mp_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wdata, char *extra) +{ + struct iw_point *wrqu = (struct iw_point *)wdata; + u32 subcmd = wrqu->flags; + PADAPTER padapter = rtw_netdev_priv(dev); + + //DBG_871X("in mp_get extra= %s \n",extra); + + if (padapter == NULL) + { + return -ENETDOWN; + } + if((padapter->bup == _FALSE )) + { + DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__); + return -ENETDOWN; + } + + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__); + return -ENETDOWN; + } + + if (extra == NULL) { + wrqu->length = 0; + return -EIO; + } + + switch (subcmd) { + case WRITE_REG: + rtw_mp_write_reg(dev, info, wrqu, extra); + break; + + case WRITE_RF: + rtw_mp_write_rf(dev, info, wrqu, extra); + break; + + case MP_PHYPARA: + DBG_871X("mp_get MP_PHYPARA\n"); + rtw_mp_phypara(dev, info, wrqu, extra); + break; + + case MP_CHANNEL: + DBG_871X("set case mp_channel\n"); + rtw_mp_channel(dev , info, wrqu, extra); + break; + + case READ_REG: + DBG_871X("mp_get READ_REG\n"); + rtw_mp_read_reg(dev, info, wrqu, extra); + break; + case READ_RF: + DBG_871X("mp_get READ_RF\n"); + rtw_mp_read_rf(dev, info, wrqu, extra); + break; + + case MP_RATE: + DBG_871X("set case mp_rate\n"); + rtw_mp_rate(dev, info, wrqu, extra); + break; + + case MP_TXPOWER: + DBG_871X("set case MP_TXPOWER\n"); + rtw_mp_txpower(dev, info, wrqu, extra); + break; + + case MP_ANT_TX: + DBG_871X("set case MP_ANT_TX\n"); + rtw_mp_ant_tx(dev, info, wrqu, extra); + break; + + case MP_ANT_RX: + DBG_871X("set case MP_ANT_RX\n"); + rtw_mp_ant_rx(dev, info, wrqu, extra); + break; + + case MP_QUERY: + rtw_mp_trx_query(dev, info, wrqu, extra); + break; + + case MP_CTX: + DBG_871X("set case MP_CTX\n"); + rtw_mp_ctx(dev, info, wrqu, extra); + break; + + case MP_ARX: + DBG_871X("set case MP_ARX\n"); + rtw_mp_arx(dev, info, wrqu, extra); + break; + + case EFUSE_GET: + DBG_871X("efuse get EFUSE_GET\n"); + rtw_mp_efuse_get(dev, info, wdata, extra); + break; + + case MP_DUMP: + DBG_871X("set case MP_DUMP\n"); + rtw_mp_dump(dev, info, wrqu, extra); + break; + case MP_PSD: + DBG_871X("set case MP_PSD\n"); + rtw_mp_psd(dev, info, wrqu, extra); + break; + case MP_THER: + DBG_871X("set case MP_THER\n"); + rtw_mp_thermal(dev, info, wrqu, extra); + break; + case MP_PwrCtlDM: + DBG_871X("set MP_PwrCtlDM\n"); + rtw_mp_PwrCtlDM(dev, info, wrqu, extra); + break; + case MP_QueryDrvStats: + DBG_871X("mp_get MP_QueryDrvStats\n"); + rtw_mp_QueryDrv(dev, info, wdata, extra); + break; + case MP_PWRTRK: + DBG_871X("set case MP_PWRTRK\n"); + rtw_mp_pwrtrk(dev, info, wrqu, extra); + break; + case EFUSE_SET: + DBG_871X("set case efuse set\n"); + rtw_mp_efuse_set(dev, info, wdata, extra); + break; + case MP_GET_TXPOWER_INX: + 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; + case MP_MON: + DBG_871X("mp_get MP_MON\n"); + rtw_mp_mon(dev, info, wdata, extra); + break; + case EFUSE_MASK: + DBG_871X("mp_get EFUSE_MASK\n"); + rtw_efuse_mask_file(dev, info, wdata, extra); + break; + case EFUSE_FILE: + DBG_871X("mp_get EFUSE_FILE\n"); + rtw_efuse_file_map(dev, info, wdata, extra); + break; + case MP_TX: + DBG_871X("mp_get MP_TX\n"); + rtw_mp_tx(dev, info, wdata, extra); + break; + case MP_RX: + DBG_871X("mp_get MP_RX\n"); + rtw_mp_rx(dev, info, wdata, extra); + break; +#if defined(CONFIG_RTL8723B) + case MP_SetBT: + DBG_871X("set MP_SetBT\n"); + rtw_mp_SetBT(dev, info, wdata, extra); + break; +#endif +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + case MP_SD_IREAD: + rtw_mp_sd_iread(dev, info, wrqu, extra); + break; + case MP_SD_IWRITE: + rtw_mp_sd_iwrite(dev, info, wrqu, extra); + break; +#endif + } + + rtw_msleep_os(10); //delay 5ms for sending pkt before exit adb shell operation +return 0; +} + +#endif /*#if defined(CONFIG_MP_INCLUDED)*/ + +static int rtw_wx_tdls_wfd_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if ( extra[ 0 ] == '0' ) + rtw_tdls_wfd_enable(padapter, 0); + else + rtw_tdls_wfd_enable(padapter, 1); + +#endif /* CONFIG_WFD */ +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_weaksec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + u8 i, j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if ( extra[ 0 ] == '0' ) + padapter->wdinfo.wfd_tdls_weaksec = 0; + else + padapter->wdinfo.wfd_tdls_weaksec = 1; + +#endif /* CONFIG_TDLS */ + + return ret; +} + + +static int rtw_tdls_enable(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + _irqL irqL; + _list *plist, *phead; + s32 index; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + u8 tdls_sta[NUM_STA][ETH_ALEN]; + u8 empty_hwaddr[ETH_ALEN] = { 0x00 }; + struct tdls_txmgmt txmgmt; + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta)); + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + + if (extra[ 0 ] == '0') { + ptdlsinfo->tdls_enable = 0; + + if(pstapriv->asoc_sta_count==1) + return ret; + + _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); + for (index=0; index< NUM_STA; index++) { + phead = &(pstapriv->sta_hash[index]); + 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 (psta->tdls_sta_state != TDLS_STATE_NONE) { + _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN); + } + } + } + _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); + + for (index=0; index< NUM_STA; index++) { + if (!_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN)) { + DBG_871X("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index])); + txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_; + _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN); + issue_tdls_teardown(padapter, &txmgmt, _TRUE); + } + } + rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR); + rtw_reset_tdls_info(padapter); + } else if (extra[0] == '1') { + ptdlsinfo->tdls_enable = 1; + } +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_setup(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; +#ifdef CONFIG_TDLS + u8 i, j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_txmgmt txmgmt; +#ifdef CONFIG_WFD + struct wifidirect_info *pwdinfo= &(padapter->wdinfo); +#endif /* CONFIG_WFD */ + + DBG_871X("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1); + + if (wrqu->data.length - 1 != 17) { + DBG_871X("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length -1)); + return ret; + } + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + +#ifdef CONFIG_WFD + if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) { + /* Weak Security situation with AP. */ + if (0 == pwdinfo->wfd_tdls_weaksec) { + /* Can't send the tdls setup request out!! */ + DBG_871X("[%s] Current link is not AES, " + "SKIP sending the tdls setup request!!\n", __FUNCTION__); + } else { + issue_tdls_setup_req(padapter, &txmgmt, _TRUE); + } + } else +#endif /* CONFIG_WFD */ + { + issue_tdls_setup_req(padapter, &txmgmt, _TRUE); + } +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_teardown(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + u8 i,j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct sta_info *ptdls_sta = NULL; + struct tdls_txmgmt txmgmt; + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) { + DBG_871X("[%s] length:%d != 17 or 19\n", + __FUNCTION__, (wrqu->data.length -1)); + return ret; + } + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + for (i=0, j=0; i < ETH_ALEN; i++, j+=3) + txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1)); + + ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer); + + if (ptdls_sta != NULL) { + txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_; + if (wrqu->data.length - 1 == 19) + issue_tdls_teardown(padapter, &txmgmt, _FALSE); + else + issue_tdls_teardown(padapter, &txmgmt, _TRUE); + } else { + DBG_871X( "TDLS peer not found\n"); + } +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_discovery(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_txmgmt txmgmt; + int i = 0, j=0; + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1)); + } + + issue_tdls_dis_req(padapter, &txmgmt); + +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_ch_switch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + u8 i, j; + struct sta_info *ptdls_sta = NULL; + + DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { + DBG_871X("Can't do TDLS channel switch since ch_switch_prohibited = _TRUE\n"); + return ret; + } + + for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){ + pchsw_info->addr[i] = key_2char2num(*(extra+j), *(extra+j+1)); + } + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr); + if( ptdls_sta == NULL ) + return ret; + + pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE; + + if (ptdls_sta != NULL) { + if (pchsw_info->off_ch_num == 0) + pchsw_info->off_ch_num = 11; + }else { + DBG_871X( "TDLS peer not found\n"); + } + + + //issue_tdls_ch_switch_req(padapter, ptdls_sta); + /* DBG_871X("issue tdls ch switch req\n"); */ + +#endif /* CONFIG_TDLS_CH_SW */ +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_ch_switch_off(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info; + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + struct tdls_txmgmt txmgmt; + + _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt)); + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + if (padapter->tdlsinfo.ch_switch_prohibited == _TRUE) + { + DBG_871X("Can't do TDLS channel switch since ch_switch_prohibited = _TRUE\n"); + return ret; + } + + if (wrqu->data.length >= 17) { + for (i=0, j=0 ; i < ETH_ALEN; i++, j+=3) + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + } + + if (padapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(padapter)) { + SelectChannel(padapter, padapter->mlmeextpriv.cur_channel); + } + + pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE | + TDLS_CH_SWITCH_ON_STATE | + TDLS_PEER_AT_OFF_STATE); + ATOMIC_SET(&pchsw_info->chsw_on, _FALSE); + _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN); + + if (ptdls_sta != NULL) { + ptdls_sta->ch_switch_time = 0; + ptdls_sta->ch_switch_timeout = 0; + _cancel_timer_ex(&ptdls_sta->ch_sw_timer); + _cancel_timer_ex(&ptdls_sta->delay_timer); + } + +#endif /* CONFIG_TDLS_CH_SW */ +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_dump_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + DBG_8192C("[%s] dump_stack:%s\n", __FUNCTION__, extra); + + extra[ wrqu->data.length ] = 0x00; + ptdlsinfo->chsw_info.dump_stack = rtw_atoi( extra ); + + return ret; + +#endif +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_off_ch_num(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + DBG_8192C("[%s] off_ch_num:%s\n", __FUNCTION__, extra); + + extra[ wrqu->data.length ] = 0x00; + ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra); + + return ret; + +#endif +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_ch_offset(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_TDLS_CH_SW + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + DBG_8192C("[%s] ch_offset:%s\n", __FUNCTION__, extra); + + extra[ wrqu->data.length ] = 0x00; + ptdlsinfo->chsw_info.ch_offset = rtw_atoi( extra ); + + return ret; + +#endif +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_pson(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for (i=0, j=0; i < ETH_ALEN; i++, j+=3) + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500); + +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_psoff(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 i, j, mac_addr[ETH_ALEN]; + struct sta_info *ptdls_sta = NULL; + + DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 ); + + for (i=0, j=0; i < ETH_ALEN; i++, j+=3) + mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1)); + + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr); + + if(ptdls_sta) + issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500); + +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_setip(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + u8 i=0, j=0, k=0, tag=0; + + DBG_871X("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1); + + while (i < 4) { + for (j=0; j < 4; j++) { + if (*( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0') { + if( j == 1 ) + pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag)); + if( j == 2 ) + pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag)); + if( j == 3 ) + pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag)); + + tag += j + 1; + break; + } + } + i++; + } + + DBG_871X( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__, + ptdlsinfo->wfd_info->ip_address[0], + ptdlsinfo->wfd_info->ip_address[1], + ptdlsinfo->wfd_info->ip_address[2], + ptdlsinfo->wfd_info->ip_address[3]); + +#endif /* CONFIG_WFD */ +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_getip(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + DBG_871X( "[%s]\n", __FUNCTION__); + + sprintf( extra, "\n\n%u.%u.%u.%u\n", + pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], + pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]); + + DBG_871X( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__, + pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1], + pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]); + + wrqu->data.length = strlen( extra ); + +#endif /* CONFIG_WFD */ +#endif /* CONFIG_TDLS */ + + return ret; +} + +static int rtw_tdls_getport(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info; + + DBG_871X( "[%s]\n", __FUNCTION__); + + sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport ); + DBG_871X( "[%s] remote port = %d\n", + __FUNCTION__, pwfd_info->peer_rtsp_ctrlport ); + + wrqu->data.length = strlen( extra ); + +#endif /* CONFIG_WFD */ +#endif /* CONFIG_TDLS */ + + return ret; + +} + +/* WFDTDLS, for sigma test */ +static int rtw_tdls_dis_result(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS +#ifdef CONFIG_WFD + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + DBG_871X( "[%s]\n", __FUNCTION__); + + if (ptdlsinfo->dev_discovered == _TRUE) { + sprintf( extra, "\n\nDis=1\n" ); + ptdlsinfo->dev_discovered = _FALSE; + } + + wrqu->data.length = strlen( extra ); + +#endif /* CONFIG_WFD */ +#endif /* CONFIG_TDLS */ + + return ret; + +} + +/* WFDTDLS, for sigma test */ +static int rtw_wfd_tdls_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct tdls_info *ptdlsinfo = &padapter->tdlsinfo; + + DBG_871X("[%s]\n", __FUNCTION__); + + sprintf( extra, "\nlink_established:%d \n" + "sta_cnt:%d \n" + "sta_maximum:%d \n" + "cur_channel:%d \n" + "tdls_enable:%d" +#ifdef CONFIG_TDLS_CH_SW + "ch_sw_state:%08x\n" + "chsw_on:%d\n" + "off_ch_num:%d\n" + "cur_time:%d\n" + "ch_offset:%d\n" + "delay_swtich_back:%d" +#endif + , + ptdlsinfo->link_established, ptdlsinfo->sta_cnt, + ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel, + ptdlsinfo->tdls_enable +#ifdef CONFIG_TDLS_CH_SW +, + ptdlsinfo->chsw_info.ch_sw_state, + ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on), + ptdlsinfo->chsw_info.off_ch_num, + ptdlsinfo->chsw_info.cur_time, + ptdlsinfo->chsw_info.ch_offset, + ptdlsinfo->chsw_info.delay_switch_back +#endif +); + + wrqu->data.length = strlen( extra ); + +#endif /* CONFIG_TDLS */ + + return ret; + + } + +static int rtw_tdls_getsta(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + { + + int ret = 0; +#ifdef CONFIG_TDLS + u8 i, j; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + u8 addr[ETH_ALEN] = {0}; + char charmac[17]; + struct sta_info *ptdls_sta = NULL; + + DBG_871X("[%s] %s %d\n", __FUNCTION__, + (char *)wrqu->data.pointer, wrqu->data.length -1); + + if(copy_from_user(charmac, wrqu->data.pointer+9, 17)){ + ret = -EFAULT; + goto exit; + } + + DBG_871X("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac); + for (i=0, j=0 ; i < ETH_ALEN; i++, j+=3) + addr[i]=key_2char2num(*(charmac+j), *(charmac+j+1)); + + DBG_871X("[%s] %d, charmac:%s, addr:"MAC_FMT"\n", + __FUNCTION__, __LINE__, charmac, MAC_ARG(addr)); + ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr); + if(ptdls_sta) { + sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state); + DBG_871X("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state); + } else { + sprintf(extra, "\n\nNot found this sta\n"); + DBG_871X("\n\nNot found this sta\n"); + } + wrqu->data.length = strlen( extra ); + +#endif /* CONFIG_TDLS */ +exit: + return ret; + +} + +static int rtw_tdls_get_best_ch(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ +#ifdef CONFIG_FIND_BEST_CHANNEL + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0; + + for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + if (pmlmeext->channel_set[i].ChannelNum == 1) + index_24G = i; + if (pmlmeext->channel_set[i].ChannelNum == 36) + index_5G = i; + } + + for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) { + /* 2.4G */ + if (pmlmeext->channel_set[i].ChannelNum == 6 || pmlmeext->channel_set[i].ChannelNum == 11) { + if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) { + index_24G = i; + best_channel_24G = pmlmeext->channel_set[i].ChannelNum; + } + } + + /* 5G */ + if (pmlmeext->channel_set[i].ChannelNum >= 36 + && pmlmeext->channel_set[i].ChannelNum < 140) { + /* Find primary channel */ + if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } + + if (pmlmeext->channel_set[i].ChannelNum >= 149 + && pmlmeext->channel_set[i].ChannelNum < 165) { + /* Find primary channel */ + if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) + && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) { + index_5G = i; + best_channel_5G = pmlmeext->channel_set[i].ChannelNum; + } + } +#if 1 /* debug */ + DBG_871X("The rx cnt of channel %3d = %d\n", + pmlmeext->channel_set[i].ChannelNum, + pmlmeext->channel_set[i].rx_count); +#endif + } + + sprintf( extra, "\nbest_channel_24G = %d\n", best_channel_24G ); + DBG_871X("best_channel_24G = %d\n", best_channel_24G); + + if (index_5G != 0) { + sprintf(extra, "best_channel_5G = %d\n", best_channel_5G); + DBG_871X("best_channel_5G = %d\n", best_channel_5G); + } + + wrqu->data.length = strlen( extra ); + +#endif + + return 0; + +} + +static int rtw_tdls(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra ); + + if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) { + DBG_871X("Discard tdls oper since hal doesn't support tdls\n"); + return 0; + } + + if (padapter->tdlsinfo.tdls_enable == 0) { + DBG_871X("tdls haven't enabled\n"); + return 0; + } + + /* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */ + + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + if (_rtw_memcmp(extra, "wfdenable=", 10)) { + wrqu->data.length -= 10; + rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]); + return ret; + } + } + + if (_rtw_memcmp(extra, "weaksec=", 8)) { + wrqu->data.length -=8; + rtw_tdls_weaksec( dev, info, wrqu, &extra[8] ); + return ret; + } else if (_rtw_memcmp( extra, "tdlsenable=", 11)) { + wrqu->data.length -=11; + rtw_tdls_enable( dev, info, wrqu, &extra[11] ); + return ret; + } + + if (_rtw_memcmp(extra, "setup=", 6)) { + wrqu->data.length -=6; + rtw_tdls_setup( dev, info, wrqu, &extra[6] ); + } else if (_rtw_memcmp(extra, "tear=", 5)) { + wrqu->data.length -= 5; + rtw_tdls_teardown( dev, info, wrqu, &extra[5] ); + } else if (_rtw_memcmp(extra, "dis=", 4)) { + wrqu->data.length -= 4; + rtw_tdls_discovery( dev, info, wrqu, &extra[4] ); + } else if (_rtw_memcmp(extra, "swoff=", 6)) { + wrqu->data.length -= 6; + rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]); + } else if (_rtw_memcmp(extra, "sw=", 3)) { + wrqu->data.length -= 3; + rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] ); + } else if (_rtw_memcmp(extra, "dumpstack=", 10)) { + wrqu->data.length -= 10; + rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]); + } else if (_rtw_memcmp(extra, "offchnum=", 9)) { + wrqu->data.length -= 9; + rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]); + } else if (_rtw_memcmp(extra, "choffset=", 9)) { + wrqu->data.length -= 9; + rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]); + } else if (_rtw_memcmp(extra, "pson=", 5)) { + wrqu->data.length -= 5; + rtw_tdls_pson( dev, info, wrqu, &extra[5] ); + } else if (_rtw_memcmp(extra, "psoff=", 6)) { + wrqu->data.length -= 6; + rtw_tdls_psoff( dev, info, wrqu, &extra[6] ); + } + +#ifdef CONFIG_WFD + if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + if (_rtw_memcmp(extra, "setip=", 6)) { + wrqu->data.length -= 6; + rtw_tdls_setip(dev, info, wrqu, &extra[6]); + } else if (_rtw_memcmp(extra, "tprobe=", 6)) { + issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev)); + } + } +#endif /* CONFIG_WFD */ + +#endif /* CONFIG_TDLS */ + + return ret; +} + + +static int rtw_tdls_get(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + +#ifdef CONFIG_TDLS + + DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer ); + + if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) ) + rtw_tdls_getip( dev, info, wrqu, extra ); + else if (_rtw_memcmp(wrqu->data.pointer, "port", 4)) + rtw_tdls_getport( dev, info, wrqu, extra ); + /* WFDTDLS, for sigma test */ + else if ( _rtw_memcmp(wrqu->data.pointer, "dis", 3)) + rtw_tdls_dis_result( dev, info, wrqu, extra ); + else if ( _rtw_memcmp(wrqu->data.pointer, "status", 6)) + rtw_wfd_tdls_status( dev, info, wrqu, extra ); + else if ( _rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9)) + rtw_tdls_getsta( dev, info, wrqu, extra ); + else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7)) + rtw_tdls_get_best_ch(dev, info, wrqu, extra); +#endif /* CONFIG_TDLS */ + + return ret; +} + + + + + +#ifdef CONFIG_INTEL_WIDI +static int rtw_widi_set(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + process_intel_widi_cmd(padapter, extra); + + return ret; +} + +static int rtw_widi_set_probe_request(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + u8 *pbuf = NULL; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + pbuf = rtw_malloc(sizeof(l2_msg_t)); + if(pbuf) + { + if ( copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length) ) + ret = -EFAULT; + //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); + + if( wrqu->data.flags == 0 ) + intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t)); + else if( wrqu->data.flags == 1 ) + rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf ); + } + return ret; +} +#endif // CONFIG_INTEL_WIDI + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + +#if defined(CONFIG_RTL8188E) +#include +extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc); +#define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum +#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI) +extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); +#define fill_default_txdesc rtl8188es_fill_default_txdesc +#endif // CONFIG_SDIO_HCI +#endif // CONFIG_RTL8188E +#if defined(CONFIG_RTL8723B) +extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc); +#define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum +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_RTL8703B) +/* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */ +#define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum +/* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */ +#define fill_default_txdesc rtl8703b_fill_default_txdesc +#endif /* CONFIG_RTL8703B */ + +#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) +{ + PLOOPBACKDATA ploopback; + + + if (padapter->ploopback == NULL) { + ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA)); + if (ploopback == NULL) return -ENOMEM; + + _rtw_init_sema(&ploopback->sema, 0); + ploopback->bstop = _TRUE; + ploopback->cnt = 0; + ploopback->size = 300; + _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg)); + + padapter->ploopback = ploopback; + } + + return 0; +} + +static void freeLoopback(PADAPTER padapter) +{ + PLOOPBACKDATA ploopback; + + + ploopback = padapter->ploopback; + if (ploopback) { + rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA)); + padapter->ploopback = NULL; + } +} + +static s32 initpseudoadhoc(PADAPTER padapter) +{ + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; + s32 err; + + networkType = Ndis802_11IBSS; + err = rtw_set_802_11_infrastructure_mode(padapter, networkType); + if (err == _FALSE) return _FAIL; + + err = rtw_setopmode_cmd(padapter, networkType,_TRUE); + if (err == _FAIL) return _FAIL; + + return _SUCCESS; +} + +static s32 createpseudoadhoc(PADAPTER padapter) +{ + NDIS_802_11_AUTHENTICATION_MODE authmode; + struct mlme_priv *pmlmepriv; + NDIS_802_11_SSID *passoc_ssid; + WLAN_BSSID_EX *pdev_network; + u8 *pibss; + u8 ssid[] = "pseduo_ad-hoc"; + s32 err; + _irqL irqL; + + + pmlmepriv = &padapter->mlmepriv; + + authmode = Ndis802_11AuthModeOpen; + err = rtw_set_802_11_authentication_mode(padapter, authmode); + if (err == _FALSE) return _FAIL; + + passoc_ssid = &pmlmepriv->assoc_ssid; + _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID)); + passoc_ssid->SsidLength = sizeof(ssid) - 1; + _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength); + + pdev_network = &padapter->registrypriv.dev_network; + pibss = padapter->registrypriv.dev_network.MacAddress; + _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID)); + + rtw_update_registrypriv_dev_network(padapter); + rtw_generate_random_ibss(pibss); + + _enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + _exit_critical_bh(&pmlmepriv->lock, &irqL); + +#if 0 + err = rtw_create_ibss_cmd(padapter, 0); + if (err == _FAIL) return _FAIL; +#else +{ + struct wlan_network *pcur_network; + struct sta_info *psta; + + //3 create a new psta + pcur_network = &pmlmepriv->cur_network; + + //clear psta in the cur_network, if any + psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress); + if (psta) rtw_free_stainfo(padapter, psta); + + psta = rtw_alloc_stainfo(&padapter->stapriv, pibss); + if (psta == NULL) return _FAIL; + + //3 join psudo AdHoc + pcur_network->join_res = 1; + pcur_network->aid = psta->aid = 1; + _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network)); + + // set msr to WIFI_FW_ADHOC_STATE +#if 0 + Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE); +#else + { + u8 val8; + + val8 = rtw_read8(padapter, MSR); + val8 &= 0xFC; // clear NETYPE0 + val8 |= WIFI_FW_ADHOC_STATE & 0x3; + rtw_write8(padapter, MSR, val8); + } +#endif +} +#endif + + return _SUCCESS; +} + +static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size) +{ + struct xmit_priv *pxmitpriv; + struct xmit_frame *pframe; + struct xmit_buf *pxmitbuf; + struct pkt_attrib *pattrib; + struct tx_desc *desc; + u8 *pkt_start, *pkt_end, *ptr; + struct rtw_ieee80211_hdr *hdr; + s32 bmcast; + _irqL irqL; + + + if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL; + + pxmitpriv = &padapter->xmitpriv; + pframe = NULL; + + //2 1. allocate xmit frame + pframe = rtw_alloc_xmitframe(pxmitpriv); + if (pframe == NULL) return NULL; + pframe->padapter = padapter; + + //2 2. allocate xmit buffer + _enter_critical_bh(&pxmitpriv->lock, &irqL); + pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); + _exit_critical_bh(&pxmitpriv->lock, &irqL); + if (pxmitbuf == NULL) { + rtw_free_xmitframe(pxmitpriv, pframe); + return NULL; + } + + pframe->pxmitbuf = pxmitbuf; + pframe->buf_addr = pxmitbuf->pbuf; + pxmitbuf->priv_data = pframe; + + //2 3. update_attrib() + pattrib = &pframe->attrib; + + // init xmitframe attribute + _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib)); + + pattrib->ether_type = 0x8723; + _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN); + _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN); + _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN); + _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); + +// pattrib->dhcp_pkt = 0; +// pattrib->pktlen = 0; + pattrib->ack_policy = 0; +// pattrib->pkt_hdrlen = ETH_HLEN; + pattrib->hdrlen = WLAN_HDR_A3_LEN; + pattrib->subtype = WIFI_DATA; + pattrib->priority = 0; + pattrib->qsel = pattrib->priority; +// do_queue_select(padapter, pattrib); + pattrib->nr_frags = 1; + pattrib->encrypt = 0; + pattrib->bswenc = _FALSE; + pattrib->qos_en = _FALSE; + + bmcast = IS_MCAST(pattrib->ra); + if (bmcast) { + pattrib->mac_id = 1; + pattrib->psta = rtw_get_bcmc_stainfo(padapter); + } else { + pattrib->mac_id = 0; + pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + } + + pattrib->pktlen = size; + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen; + + //2 4. fill TX descriptor + desc = (struct tx_desc*)pframe->buf_addr; + _rtw_memset(desc, 0, TXDESC_SIZE); + + fill_default_txdesc(pframe, (u8*)desc); + + // Hw set sequence number + ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable +// ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL + + ((PTXDESC)desc)->disdatafb = 1; + + // convert to little endian + desc->txdw0 = cpu_to_le32(desc->txdw0); + desc->txdw1 = cpu_to_le32(desc->txdw1); + desc->txdw2 = cpu_to_le32(desc->txdw2); + desc->txdw3 = cpu_to_le32(desc->txdw3); + desc->txdw4 = cpu_to_le32(desc->txdw4); + desc->txdw5 = cpu_to_le32(desc->txdw5); + desc->txdw6 = cpu_to_le32(desc->txdw6); + desc->txdw7 = cpu_to_le32(desc->txdw7); +#ifdef CONFIG_PCI_HCI + desc->txdw8 = cpu_to_le32(desc->txdw8); + desc->txdw9 = cpu_to_le32(desc->txdw9); + desc->txdw10 = cpu_to_le32(desc->txdw10); + desc->txdw11 = cpu_to_le32(desc->txdw11); + desc->txdw12 = cpu_to_le32(desc->txdw12); + desc->txdw13 = cpu_to_le32(desc->txdw13); + desc->txdw14 = cpu_to_le32(desc->txdw14); + desc->txdw15 = cpu_to_le32(desc->txdw15); +#endif + + cal_txdesc_chksum(desc); + + //2 5. coalesce + pkt_start = pframe->buf_addr + TXDESC_SIZE; + pkt_end = pkt_start + pattrib->last_txcmdsz; + + //3 5.1. make wlan header, make_wlanhdr() + hdr = (struct rtw_ieee80211_hdr *)pkt_start; + SetFrameSubType(&hdr->frame_ctl, pattrib->subtype); + _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA + _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA + _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID + + //3 5.2. make payload + ptr = pkt_start + pattrib->hdrlen; + get_random_bytes(ptr, pkt_end - ptr); + + pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; + pxmitbuf->ptail += pxmitbuf->len; + + return pframe; +} + +static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe) +{ + struct xmit_priv *pxmitpriv; + struct xmit_buf *pxmitbuf; + + + pxmitpriv = &padapter->xmitpriv; + pxmitbuf = pframe->pxmitbuf; + + rtw_free_xmitframe(pxmitpriv, pframe); + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); +} + +static void printdata(u8 *pbuf, u32 len) +{ + u32 i, val; + + + for (i = 0; (i+4) <= len; i+=4) { + printk("%08X", *(u32*)(pbuf + i)); + if ((i+4) & 0x1F) printk(" "); + else printk("\n"); + } + + if (i < len) + { +#ifdef CONFIG_BIG_ENDIAN + for (; i < len, i++) + printk("%02X", pbuf+i); +#else // CONFIG_LITTLE_ENDIAN +#if 0 + val = 0; + _rtw_memcpy(&val, pbuf + i, len - i); + printk("%8X", val); +#else + u8 str[9]; + u8 n; + val = 0; + n = len - i; + _rtw_memcpy(&val, pbuf+i, n); + sprintf(str, "%08X", val); + n = (4 - n) * 2; + printk("%8s", str+n); +#endif +#endif // CONFIG_LITTLE_ENDIAN + } + printk("\n"); +} + +static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz) +{ + PHAL_DATA_TYPE phal; + struct recv_stat *prxstat; + struct recv_stat report; + PRXREPORT prxreport; + u32 drvinfosize; + u32 rxpktsize; + u8 fcssize; + u8 ret = _FALSE; + + prxstat = (struct recv_stat*)rxbuf; + report.rxdw0 = le32_to_cpu(prxstat->rxdw0); + report.rxdw1 = le32_to_cpu(prxstat->rxdw1); + report.rxdw2 = le32_to_cpu(prxstat->rxdw2); + report.rxdw3 = le32_to_cpu(prxstat->rxdw3); + report.rxdw4 = le32_to_cpu(prxstat->rxdw4); + report.rxdw5 = le32_to_cpu(prxstat->rxdw5); + + prxreport = (PRXREPORT)&report; + drvinfosize = prxreport->drvinfosize << 3; + rxpktsize = prxreport->pktlen; + + phal = GET_HAL_DATA(padapter); + if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN; + else fcssize = 0; + + if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) { + DBG_8192C("%s: ERROR! size not match tx/rx=%d/%d !\n", + __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize); + ret = _FALSE; + } else { + ret = _rtw_memcmp(txbuf + TXDESC_SIZE,\ + rxbuf + RXDESC_SIZE + drvinfosize,\ + txsz - TXDESC_SIZE); + if (ret == _FALSE) { + DBG_8192C("%s: ERROR! pkt content mismatch!\n", __func__); + } + } + + if (ret == _FALSE) + { + DBG_8192C("\n%s: TX PKT total=%d, desc=%d, content=%d\n", + __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE); + DBG_8192C("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE); + printdata(txbuf, TXDESC_SIZE); + DBG_8192C("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE); + printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE); + + DBG_8192C("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n", + __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize); + if (rxpktsize != 0) + { + DBG_8192C("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE); + printdata(rxbuf, RXDESC_SIZE); + DBG_8192C("%s: RX drvinfo size=%d\n", __func__, drvinfosize); + printdata(rxbuf + RXDESC_SIZE, drvinfosize); + DBG_8192C("%s: RX content size=%d\n", __func__, rxpktsize); + printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize); + } else { + DBG_8192C("%s: RX data size=%d\n", __func__, rxsz); + printdata(rxbuf, rxsz); + } + } + + return ret; +} + +thread_return lbk_thread(thread_context context) +{ + s32 err; + PADAPTER padapter; + PLOOPBACKDATA ploopback; + struct xmit_frame *pxmitframe; + u32 cnt, ok, fail, headerlen; + u32 pktsize; + u32 ff_hwaddr; + + + padapter = (PADAPTER)context; + ploopback = padapter->ploopback; + if (ploopback == NULL) return -1; + cnt = 0; + ok = 0; + fail = 0; + + daemonize("%s", "RTW_LBK_THREAD"); + allow_signal(SIGTERM); + + do { + if (ploopback->size == 0) { + get_random_bytes(&pktsize, 4); + pktsize = (pktsize % 1535) + 1; // 1~1535 + } else + pktsize = ploopback->size; + + pxmitframe = createloopbackpkt(padapter, pktsize); + if (pxmitframe == NULL) { + sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!"); + break; + } + + ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz; + _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize); + ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); + cnt++; + DBG_8192C("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize); + pxmitframe->pxmitbuf->pdata = ploopback->txbuf; + rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf); + + // wait for rx pkt + _rtw_down_sema(&ploopback->sema); + + err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize); + if (err == _TRUE) + ok++; + else + fail++; + + ploopback->txsize = 0; + _rtw_memset(ploopback->txbuf, 0, 0x8000); + ploopback->rxsize = 0; + _rtw_memset(ploopback->rxbuf, 0, 0x8000); + + freeloopbackpkt(padapter, pxmitframe); + pxmitframe = NULL; + + if (signal_pending(current)) { + flush_signals(current); + } + + if ((ploopback->bstop == _TRUE) || + ((ploopback->cnt != 0) && (ploopback->cnt == cnt))) + { + u32 ok_rate, fail_rate, all; + all = cnt; + ok_rate = (ok*100)/all; + fail_rate = (fail*100)/all; + sprintf(ploopback->msg,\ + "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\ + ok_rate, ok, all, fail_rate, fail, all); + break; + } + } while (1); + + ploopback->bstop = _TRUE; + + thread_exit(); +} + +static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg) +{ + PLOOPBACKDATA ploopback; + u32 len; + s32 err; + + + ploopback = padapter->ploopback; + + if (ploopback) + { + if (ploopback->bstop == _FALSE) { + ploopback->bstop = _TRUE; + _rtw_up_sema(&ploopback->sema); + } + len = 0; + do { + len = strlen(ploopback->msg); + if (len) break; + rtw_msleep_os(1); + } while (1); + _rtw_memcpy(pmsg, ploopback->msg, len+1); + freeLoopback(padapter); + + return; + } + + // disable dynamic algorithm + rtw_phydm_ability_backup(padapter); + rtw_phydm_func_disable_all(padapter); + + // create pseudo ad-hoc connection + err = initpseudoadhoc(padapter); + if (err == _FAIL) { + sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!"); + return; + } + + err = createpseudoadhoc(padapter); + if (err == _FAIL) { + sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!"); + return; + } + + err = initLoopback(padapter); + if (err) { + sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err); + return; + } + + ploopback = padapter->ploopback; + + ploopback->bstop = _FALSE; + ploopback->cnt = cnt; + ploopback->size = size; + ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD"); + if (IS_ERR(padapter->lbkthread)) + { + freeLoopback(padapter); + sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt); + return; + } + + sprintf(pmsg, "loopback start! cnt=%d", cnt); +} +#endif // CONFIG_MAC_LOOPBACK_DRIVER + +static int rtw_test( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + u32 len; + u8 *pbuf, *pch; + char *ptmp; + u8 *delim = ","; + PADAPTER padapter = rtw_netdev_priv(dev); + + + DBG_871X("+%s\n", __func__); + len = wrqu->data.length; + + pbuf = (u8*)rtw_zmalloc(len); + if (pbuf == NULL) { + DBG_871X("%s: no memory!\n", __func__); + return -ENOMEM; + } + + if (copy_from_user(pbuf, wrqu->data.pointer, len)) { + rtw_mfree(pbuf, len); + DBG_871X("%s: copy from user fail!\n", __func__); + return -EFAULT; + } + DBG_871X("%s: string=\"%s\"\n", __func__, pbuf); + + ptmp = (char*)pbuf; + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + DBG_871X("%s: parameter error(level 1)!\n", __func__); + return -EFAULT; + } + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + if (strcmp(pch, "loopback") == 0) + { + s32 cnt = 0; + u32 size = 64; + + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + DBG_871X("%s: parameter error(level 2)!\n", __func__); + return -EFAULT; + } + + sscanf(pch, "%d", &cnt); + DBG_871X("%s: loopback cnt=%d\n", __func__, cnt); + + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) { + rtw_mfree(pbuf, len); + DBG_871X("%s: parameter error(level 2)!\n", __func__); + return -EFAULT; + } + + sscanf(pch, "%d", &size); + DBG_871X("%s: loopback size=%d\n", __func__, size); + + loopbackTest(padapter, cnt, size, extra); + wrqu->data.length = strlen(extra) + 1; + + goto free_buf; + } +#endif + + +#ifdef CONFIG_BT_COEXIST + if (strcmp(pch, "bton") == 0) { + rtw_btcoex_SetManualControl(padapter, _FALSE); + goto free_buf; + } else if (strcmp(pch, "btoff") == 0) { + rtw_btcoex_SetManualControl(padapter, _TRUE); + goto free_buf; + } +#endif + + if (strcmp(pch, "h2c") == 0) { + u8 param[8]; + u8 count = 0; + u32 tmp; + u8 i; + u32 pos; + s32 ret; + + do { + pch = strsep(&ptmp, delim); + if ((pch == NULL) || (strlen(pch) == 0)) + break; + + sscanf(pch, "%x", &tmp); + param[count++] = (u8)tmp; + } while (count < 8); + + if (count == 0) { + rtw_mfree(pbuf, len); + DBG_871X("%s: parameter error(level 2)!\n", __func__); + return -EFAULT; + } + + ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]); + + pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]); + for (i=1; idata.length = strlen(extra) + 1; + + goto free_buf; + } + +free_buf: + rtw_mfree(pbuf, len); + return 0; +} + +static iw_handler rtw_handlers[] = +{ + NULL, /* SIOCSIWCOMMIT */ + rtw_wx_get_name, /* SIOCGIWNAME */ + dummy, /* SIOCSIWNWID */ + dummy, /* SIOCGIWNWID */ + rtw_wx_set_freq, /* SIOCSIWFREQ */ + rtw_wx_get_freq, /* SIOCGIWFREQ */ + rtw_wx_set_mode, /* SIOCSIWMODE */ + rtw_wx_get_mode, /* SIOCGIWMODE */ + dummy, /* SIOCSIWSENS */ + rtw_wx_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + rtw_wx_get_range, /* SIOCGIWRANGE */ + rtw_wx_set_priv, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ + dummy, /* SIOCSIWSPY */ + dummy, /* SIOCGIWSPY */ + NULL, /* SIOCGIWTHRSPY */ + NULL, /* SIOCWIWTHRSPY */ + rtw_wx_set_wap, /* SIOCSIWAP */ + rtw_wx_get_wap, /* SIOCGIWAP */ + rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */ + dummy, /* SIOCGIWAPLIST -- depricated */ + rtw_wx_set_scan, /* SIOCSIWSCAN */ + rtw_wx_get_scan, /* SIOCGIWSCAN */ + rtw_wx_set_essid, /* SIOCSIWESSID */ + rtw_wx_get_essid, /* SIOCGIWESSID */ + dummy, /* SIOCSIWNICKN */ + rtw_wx_get_nick, /* SIOCGIWNICKN */ + NULL, /* -- hole -- */ + NULL, /* -- hole -- */ + rtw_wx_set_rate, /* SIOCSIWRATE */ + rtw_wx_get_rate, /* SIOCGIWRATE */ + rtw_wx_set_rts, /* SIOCSIWRTS */ + rtw_wx_get_rts, /* SIOCGIWRTS */ + rtw_wx_set_frag, /* SIOCSIWFRAG */ + rtw_wx_get_frag, /* SIOCGIWFRAG */ + dummy, /* SIOCSIWTXPOW */ + dummy, /* SIOCGIWTXPOW */ + dummy, /* SIOCSIWRETRY */ + rtw_wx_get_retry, /* SIOCGIWRETRY */ + rtw_wx_set_enc, /* SIOCSIWENCODE */ + rtw_wx_get_enc, /* SIOCGIWENCODE */ + dummy, /* SIOCSIWPOWER */ + rtw_wx_get_power, /* SIOCGIWPOWER */ + NULL, /*---hole---*/ + NULL, /*---hole---*/ + rtw_wx_set_gen_ie, /* SIOCSIWGENIE */ + NULL, /* SIOCGWGENIE */ + rtw_wx_set_auth, /* SIOCSIWAUTH */ + NULL, /* SIOCGIWAUTH */ + rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ + NULL, /* SIOCGIWENCODEEXT */ + rtw_wx_set_pmkid, /* SIOCSIWPMKSA */ + NULL, /*---hole---*/ +}; + + +static const struct iw_priv_args rtw_private_args[] = { + { + SIOCIWFIRSTPRIV + 0x0, + IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write" + }, + { + SIOCIWFIRSTPRIV + 0x1, + IW_PRIV_TYPE_CHAR | 0x7FF, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read" + }, + { + SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" + }, + { + SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" + }, + { + SIOCIWFIRSTPRIV + 0x4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" + }, + { + SIOCIWFIRSTPRIV + 0x5, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid" + }, + { + SIOCIWFIRSTPRIV + 0x6, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" + }, +//for PLATFORM_MT53XX + { + SIOCIWFIRSTPRIV + 0x7, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity" + }, + { + SIOCIWFIRSTPRIV + 0x8, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie" + }, + { + SIOCIWFIRSTPRIV + 0x9, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie" + }, + +//for RTK_DMP_PLATFORM + { + SIOCIWFIRSTPRIV + 0xA, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan" + }, + + { + SIOCIWFIRSTPRIV + 0xB, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg" + }, + { + SIOCIWFIRSTPRIV + 0xC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw" + }, + { + SIOCIWFIRSTPRIV + 0xD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr" + }, +#if 0 + { + SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl" + }, +#endif + { + SIOCIWFIRSTPRIV + 0x10, + IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set" + }, + { + SIOCIWFIRSTPRIV + 0x11, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get" + }, + { + SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL" + }, + { + SIOCIWFIRSTPRIV + 0x13, + IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2" + }, + { + SIOCIWFIRSTPRIV + 0x14, + IW_PRIV_TYPE_CHAR | 64, 0, "tdls" + }, + { + SIOCIWFIRSTPRIV + 0x15, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get" + }, + { + SIOCIWFIRSTPRIV + 0x16, + IW_PRIV_TYPE_CHAR | 64, 0, "pm_set" + }, + + {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"}, +#ifdef CONFIG_MP_INCLUDED + {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"}, + {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"}, +#else + {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"}, + {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"}, +#endif + { + SIOCIWFIRSTPRIV + 0x1D, + IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test" + }, + +#ifdef CONFIG_INTEL_WIDI + { + SIOCIWFIRSTPRIV + 0x1E, + IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set" + }, + { + SIOCIWFIRSTPRIV + 0x1F, + IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req" + }, +#endif // CONFIG_INTEL_WIDI + +#ifdef CONFIG_MP_INCLUDED + { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, //set + { SIOCIWFIRSTPRIV + 0x0F, 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 + { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" }, + { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" }, + { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" }, + { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"}, + { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" }, + { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"}, + { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"}, + { 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, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" }, + { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" }, + { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"}, + { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"}, + { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"}, + { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "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" }, + { 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" }, + { MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" }, + { EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" }, + { EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" }, + { MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" }, + { MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" }, +#if defined(CONFIG_RTL8723B) + { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" }, + { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"}, +#endif + { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"}, +#endif +#ifdef CONFIG_WOWLAN + { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, + { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" }, +#endif +#ifdef CONFIG_AP_WOWLAN + { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, //set +#endif +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + { MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" }, + { MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" }, +#endif +}; + +static iw_handler rtw_private_handler[] = +{ + rtw_wx_write32, //0x00 + rtw_wx_read32, //0x01 + rtw_drvext_hdl, //0x02 + rtw_mp_ioctl_hdl, //0x03 + +// for MM DTV platform + rtw_get_ap_info, //0x04 + + rtw_set_pid, //0x05 + rtw_wps_start, //0x06 + +// for PLATFORM_MT53XX + rtw_wx_get_sensitivity, //0x07 + rtw_wx_set_mtk_wps_probe_ie, //0x08 + rtw_wx_set_mtk_wps_ie, //0x09 + +// for RTK_DMP_PLATFORM +// Set Channel depend on the country code + rtw_wx_set_channel_plan, //0x0A + + rtw_dbg_port, //0x0B + rtw_wx_write_rf, //0x0C + rtw_wx_read_rf, //0x0D +#ifdef CONFIG_MP_INCLUDED + rtw_mp_set, //0x0E + rtw_mp_get, //0x0F +#else + rtw_wx_priv_null, //0x0E + rtw_wx_priv_null, //0x0F +#endif + rtw_p2p_set, //0x10 + rtw_p2p_get, //0x11 + NULL, //0x12 + rtw_p2p_get2, //0x13 + + rtw_tdls, //0x14 + rtw_tdls_get, //0x15 + + rtw_pm_set, //0x16 + rtw_wx_priv_null, //0x17 + rtw_rereg_nd_name, //0x18 + rtw_wx_priv_null, //0x19 +#ifdef CONFIG_MP_INCLUDED + rtw_wx_priv_null, //0x1A + rtw_wx_priv_null, //0x1B +#else + rtw_mp_efuse_set, //0x1A + rtw_mp_efuse_get, //0x1B +#endif + NULL, // 0x1C is reserved for hostapd + rtw_test, // 0x1D +#ifdef CONFIG_INTEL_WIDI + rtw_widi_set, //0x1E + rtw_widi_set_probe_request, //0x1F +#endif // CONFIG_INTEL_WIDI +}; + + +#if WIRELESS_EXT >= 17 +static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct iw_statistics *piwstats=&padapter->iwstats; + int tmp_level = 0; + int tmp_qual = 0; + int tmp_noise = 0; + + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) + { + piwstats->qual.qual = 0; + piwstats->qual.level = 0; + piwstats->qual.noise = 0; + //DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); + } + else{ + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); + #else + #ifdef CONFIG_SIGNAL_SCALE_MAPPING + tmp_level = padapter->recvpriv.signal_strength; + #else + { + /* 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); + + tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength); + } + #endif + #endif + + tmp_qual = padapter->recvpriv.signal_qual; + rtw_get_noise(padapter); + tmp_noise = padapter->recvpriv.noise; + //DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); + + piwstats->qual.level = tmp_level; + piwstats->qual.qual = tmp_qual; + piwstats->qual.noise = tmp_noise; + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) + piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM; +#else +#ifdef RTK_DMP_PLATFORM + //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. + //remove this flag for show percentage 0~100 + piwstats->qual.updated = 0x07; +#else + piwstats->qual.updated = 0x0f; +#endif +#endif + + #ifdef CONFIG_SIGNAL_DISPLAY_DBM + piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM; + #endif + + return &padapter->iwstats; +} +#endif + +#ifdef CONFIG_WIRELESS_EXT +struct iw_handler_def rtw_handlers_def = +{ + .standard = rtw_handlers, + .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler), +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV) + .private = rtw_private_handler, + .private_args = (struct iw_priv_args *)rtw_private_args, + .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args), +#endif +#if WIRELESS_EXT >= 17 + .get_wireless_stats = rtw_get_wireless_stats, +#endif +}; +#endif + +// copy from net/wireless/wext.c start +/* ---------------------------------------------------------------- */ +/* + * Calculate size of private arguments + */ +static const char iw_priv_type_size[] = { + 0, /* IW_PRIV_TYPE_NONE */ + 1, /* IW_PRIV_TYPE_BYTE */ + 1, /* IW_PRIV_TYPE_CHAR */ + 0, /* Not defined */ + sizeof(__u32), /* IW_PRIV_TYPE_INT */ + sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */ + sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */ + 0, /* Not defined */ +}; + +static int get_priv_size(__u16 args) +{ + int num = args & IW_PRIV_SIZE_MASK; + int type = (args & IW_PRIV_TYPE_MASK) >> 12; + + return num * iw_priv_type_size[type]; +} +// copy from net/wireless/wext.c end + + +static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data) +{ + int err = 0; + u8 *input = NULL; + u32 input_len = 0; + const char delim[] = " "; + u8 *output = NULL; + u32 output_len = 0; + u32 count = 0; + u8 *buffer= NULL; + u32 buffer_len = 0; + char *ptr = NULL; + u8 cmdname[17] = {0}; // IFNAMSIZ+1 + u32 cmdlen; + s32 len; + u8 *extra = NULL; + u32 extra_size = 0; + + s32 k; + const iw_handler *priv; /* Private ioctl */ + const struct iw_priv_args *priv_args; /* Private ioctl description */ + u32 num_priv; /* Number of ioctl */ + u32 num_priv_args; /* Number of descriptions */ + iw_handler handler; + int temp; + int subcmd = 0; /* sub-ioctl index */ + int offset = 0; /* Space for sub-ioctl index */ + + union iwreq_data wdata; + + _rtw_memcpy(&wdata, wrq_data, sizeof(wdata)); + + input_len = wdata.data.length; + input = rtw_zmalloc(input_len); + if (NULL == input || input_len == 0) + return -ENOMEM; + if (copy_from_user(input, wdata.data.pointer, input_len)) { + err = -EFAULT; + goto exit; + } + input[input_len - 1] = '\0'; + ptr = input; + len = input_len; + + if (ptr == NULL) { + err = -EOPNOTSUPP; + goto exit; + } + + sscanf(ptr, "%16s", cmdname); + cmdlen = strlen(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_871X("%s: parameters=%s\n", __func__, ptr); + + priv = rtw_private_handler; + priv_args = rtw_private_args; + num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler); + num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args); + + if (num_priv_args == 0) { + err = -EOPNOTSUPP; + goto exit; + } + + /* Search the correct ioctl */ + k = -1; + while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname)); + + /* If not found... */ + if (k == num_priv_args) { + err = -EOPNOTSUPP; + goto exit; + } + + /* Watch out for sub-ioctls ! */ + if (priv_args[k].cmd < SIOCDEVPRIVATE) + { + int j = -1; + + /* Find the matching *real* ioctl */ + while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') || + (priv_args[j].set_args != priv_args[k].set_args) || + (priv_args[j].get_args != priv_args[k].get_args))); + + /* If not found... */ + if (j == num_priv_args) { + err = -EINVAL; + goto exit; + } + + /* Save sub-ioctl number */ + subcmd = priv_args[k].cmd; + /* Reserve one int (simplify alignment issues) */ + offset = sizeof(__u32); + /* Use real ioctl definition from now on */ + k = j; + } + + buffer = rtw_zmalloc(4096); + if (NULL == buffer) { + err = -ENOMEM; + goto exit; + } + + /* If we have to set some data */ + if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) && + (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) + { + u8 *str; + + switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) + { + case IW_PRIV_TYPE_BYTE: + /* Fetch args */ + count = 0; + do { + str = strsep(&ptr, delim); + if (NULL == str) break; + sscanf(str, "%i", &temp); + buffer[count++] = (u8)temp; + } while (1); + buffer_len = count; + + /* Number of args to fetch */ + wdata.data.length = count; + if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) + wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; + + break; + + case IW_PRIV_TYPE_INT: + /* Fetch args */ + count = 0; + do { + str = strsep(&ptr, delim); + if (NULL == str) break; + sscanf(str, "%i", &temp); + ((s32*)buffer)[count++] = (s32)temp; + } while (1); + buffer_len = count * sizeof(s32); + + /* Number of args to fetch */ + wdata.data.length = count; + if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) + wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; + + break; + + case IW_PRIV_TYPE_CHAR: + if (len > 0) + { + /* Size of the string to fetch */ + wdata.data.length = len; + if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) + wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK; + + /* Fetch string */ + _rtw_memcpy(buffer, ptr, wdata.data.length); + } + else + { + wdata.data.length = 1; + buffer[0] = '\0'; + } + buffer_len = wdata.data.length; + break; + + default: + DBG_8192C("%s: Not yet implemented...\n", __func__); + err = -1; + goto exit; + } + + if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && + (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) + { + DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n", + __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK); + err = -EINVAL; + goto exit; + } + } /* if args to set */ + else + { + wdata.data.length = 0L; + } + + /* Those two tests are important. They define how the driver + * will have to handle the data */ + if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && + ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) + { + /* First case : all SET args fit within wrq */ + if (offset) + wdata.mode = subcmd; + _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset); + } + else + { + if ((priv_args[k].set_args == 0) && + (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && + (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) + { + /* Second case : no SET args, GET args fit within wrq */ + if (offset) + wdata.mode = subcmd; + } + else + { + /* Third case : args won't fit in wrq, or variable number of args */ + if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) { + err = -EFAULT; + goto exit; + } + wdata.data.flags = subcmd; + } + } + + rtw_mfree(input, input_len); + input = NULL; + + extra_size = 0; + if (IW_IS_SET(priv_args[k].cmd)) + { + /* Size of set arguments */ + extra_size = get_priv_size(priv_args[k].set_args); + + /* Does it fits in iwr ? */ + if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) && + ((extra_size + offset) <= IFNAMSIZ)) + extra_size = 0; + } else { + /* Size of get arguments */ + extra_size = get_priv_size(priv_args[k].get_args); + + /* Does it fits in iwr ? */ + if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && + (extra_size <= IFNAMSIZ)) + extra_size = 0; + } + + if (extra_size == 0) { + extra = (u8*)&wdata; + rtw_mfree(buffer, 4096); + buffer = NULL; + } else + extra = buffer; + + handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV]; + err = handler(dev, NULL, &wdata, extra); + + /* If we have to get some data */ + if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) && + (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) + { + int j; + int n = 0; /* number of args */ + u8 str[20] = {0}; + + /* Check where is the returned data */ + if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) && + (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) + n = priv_args[k].get_args & IW_PRIV_SIZE_MASK; + else + n = wdata.data.length; + + output = rtw_zmalloc(4096); + if (NULL == output) { + err = -ENOMEM; + goto exit; + } + + switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) + { + case IW_PRIV_TYPE_BYTE: + /* Display args */ + for (j = 0; j < n; j++) + { + sprintf(str, "%d ", extra[j]); + len = strlen(str); + output_len = strlen(output); + if ((output_len + len + 1) > 4096) { + err = -E2BIG; + goto exit; + } + _rtw_memcpy(output+output_len, str, len); + } + break; + + case IW_PRIV_TYPE_INT: + /* Display args */ + for (j = 0; j < n; j++) + { + sprintf(str, "%d ", ((__s32*)extra)[j]); + len = strlen(str); + output_len = strlen(output); + if ((output_len + len + 1) > 4096) { + err = -E2BIG; + goto exit; + } + _rtw_memcpy(output+output_len, str, len); + } + break; + + case IW_PRIV_TYPE_CHAR: + /* Display args */ + _rtw_memcpy(output, extra, n); + break; + + default: + DBG_8192C("%s: Not yet implemented...\n", __func__); + err = -1; + goto exit; + } + + output_len = strlen(output) + 1; + wrq_data->data.length = output_len; + if (copy_to_user(wrq_data->data.pointer, output, output_len)) { + err = -EFAULT; + goto exit; + } + } /* if args to set */ + else + { + wrq_data->data.length = 0; + } + +exit: + if (input) + rtw_mfree(input, input_len); + if (buffer) + rtw_mfree(buffer, 4096); + if (output) + rtw_mfree(output, 4096); + + 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; + int ret=0; + + switch (cmd) + { + case RTL_IOCTL_WPA_SUPPLICANT: + ret = wpa_supplicant_ioctl(dev, &wrq->u.data); + break; +#ifdef CONFIG_AP_MODE + case RTL_IOCTL_HOSTAPD: + ret = rtw_hostapd_ioctl(dev, &wrq->u.data); + break; +#ifdef CONFIG_WIRELESS_EXT + case SIOCSIWMODE: + ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL); + break; +#endif +#endif // CONFIG_AP_MODE + case SIOCDEVPRIVATE: + ret = rtw_ioctl_wext_private(dev, rq); + break; + case (SIOCDEVPRIVATE+1): + ret = rtw_android_priv_cmd(dev, rq, cmd); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_mp.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_mp.c new file mode 100644 index 00000000..58c254c5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/ioctl_mp.c @@ -0,0 +1,2308 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#if defined(CONFIG_MP_INCLUDED) + +#include +#include +#include +#include "../../hal/phydm/phydm_precomp.h" + + +#if defined(CONFIG_RTL8723B) +#include +#endif + +/* + * Input Format: %s,%d,%d + * %s is width, could be + * "b" for 1 byte + * "w" for WORD (2 bytes) + * "dw" for DWORD (4 bytes) + * 1st %d is address(offset) + * 2st %d is data to write + */ +int rtw_mp_write_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char *pch, *pnext, *ptmp; + char *width_str; + char width, buf[5]; + u32 addr, data; + int ret; + PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(extra, 0, wrqu->length); + + pch = input; + + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) + return -EINVAL; + *pnext = 0; + width_str = pch; + + pch = pnext + 1; + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) + return -EINVAL; + *pnext = 0; + /*addr = simple_strtoul(pch, &ptmp, 16); + _rtw_memset(buf, '\0', sizeof(buf)); + _rtw_memcpy(buf, pch, pnext-pch); + ret = kstrtoul(buf, 16, &addr);*/ + ret = sscanf(pch, "%x", &addr); + if (addr > 0x3FFF) + return -EINVAL; + + pch = pnext + 1; + pnext = strpbrk(pch, " ,.-"); + if ((pch - input) >= wrqu->length) + return -EINVAL; + /*data = simple_strtoul(pch, &ptmp, 16);*/ + ret = sscanf(pch, "%x", &data); + DBG_871X("data=%x,addr=%x\n", (u32)data, (u32)addr); + ret = 0; + width = width_str[0]; + switch (width) { + case 'b': + /* 1 byte*/ + if (data > 0xFF) { + ret = -EINVAL; + break; + } + rtw_write8(padapter, addr, data); + break; + case 'w': + /* 2 bytes*/ + if (data > 0xFFFF) { + ret = -EINVAL; + break; + } + rtw_write16(padapter, addr, data); + break; + case 'd': + /* 4 bytes*/ + rtw_write32(padapter, addr, data); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + + +/* + * Input Format: %s,%d + * %s is width, could be + * "b" for 1 byte + * "w" for WORD (2 bytes) + * "dw" for DWORD (4 bytes) + * %d is address(offset) + * + * Return: + * %d for data readed + */ +int rtw_mp_read_reg(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char input[wrqu->length]; + char *pch, *pnext, *ptmp; + char *width_str; + char width; + char data[20], tmp[20], buf[3]; + u32 addr = 0, strtout = 0; + u32 i = 0, j = 0, ret = 0, data32 = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + + + if (wrqu->length > 128) + return -EFAULT; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(extra, 0, wrqu->length); + _rtw_memset(data, '\0', sizeof(data)); + _rtw_memset(tmp, '\0', sizeof(tmp)); + pch = input; + pnext = strpbrk(pch, " ,.-"); + if (pnext == NULL) + return -EINVAL; + *pnext = 0; + width_str = pch; + + pch = pnext + 1; + + ret = sscanf(pch, "%x", &addr); + if (addr > 0x3FFF) + return -EINVAL; + + ret = 0; + width = width_str[0]; + + switch (width) { + case 'b': + data32 = rtw_read8(padapter, addr); + DBG_871X("%x\n", data32); + sprintf(extra, "%d", data32); + wrqu->length = strlen(extra); + break; + case 'w': + /* 2 bytes*/ + sprintf(data, "%04x\n", rtw_read16(padapter, addr)); + + for (i = 0 ; i <= strlen(data) ; i++) { + if (i % 2 == 0) { + tmp[j] = ' '; + j++; + } + if (data[i] != '\0') + tmp[j] = data[i]; + + j++; + } + pch = tmp; + DBG_871X("pch=%s", pch); + + while (*pch != '\0') { + pnext = strpbrk(pch, " "); + if (!pnext || ((pnext - tmp) > 4)) + break; + + pnext++; + if (*pnext != '\0') { + /*strtout = simple_strtoul(pnext , &ptmp, 16);*/ + ret = sscanf(pnext, "%x", &strtout); + sprintf(extra, "%s %d" , extra , strtout); + } else + break; + pch = pnext; + } + wrqu->length = strlen(extra); + break; + case 'd': + /* 4 bytes */ + sprintf(data, "%08x", rtw_read32(padapter, addr)); + /*add read data format blank*/ + for (i = 0 ; i <= strlen(data) ; i++) { + if (i % 2 == 0) { + tmp[j] = ' '; + j++; + } + if (data[i] != '\0') + tmp[j] = data[i]; + + j++; + } + pch = tmp; + DBG_871X("pch=%s", pch); + + while (*pch != '\0') { + pnext = strpbrk(pch, " "); + if (!pnext) + break; + + pnext++; + if (*pnext != '\0') { + ret = sscanf(pnext, "%x", &strtout); + sprintf(extra, "%s %d" , extra , strtout); + } else + break; + pch = pnext; + } + wrqu->length = strlen(extra); + break; + + default: + wrqu->length = 0; + ret = -EINVAL; + break; + } + + return ret; +} + + +/* + * Input Format: %d,%x,%x + * %d is RF path, should be smaller than MAX_RF_PATH_NUMS + * 1st %x is address(offset) + * 2st %x is data to write + */ +int rtw_mp_write_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + + u32 path, addr, data; + int ret; + PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->length]; + + + _rtw_memset(input, 0, wrqu->length); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + + ret = sscanf(input, "%d,%x,%x", &path, &addr, &data); + if (ret < 3) + return -EINVAL; + + if (path >= GET_HAL_RFPATH_NUM(padapter)) + return -EINVAL; + if (addr > 0xFF) + return -EINVAL; + if (data > 0xFFFFF) + return -EINVAL; + + _rtw_memset(extra, 0, wrqu->length); + + write_rfreg(padapter, path, addr, data); + + sprintf(extra, "write_rf completed\n"); + wrqu->length = strlen(extra); + + return 0; +} + + +/* + * Input Format: %d,%x + * %d is RF path, should be smaller than MAX_RF_PATH_NUMS + * %x is address(offset) + * + * Return: + * %d for data readed + */ +int rtw_mp_read_rf(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + char input[wrqu->length]; + char *pch, *pnext, *ptmp; + char data[20], tmp[20], buf[3]; + u32 path, addr, strtou; + u32 ret, i = 0 , j = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (wrqu->length > 128) + return -EFAULT; + _rtw_memset(input, 0, wrqu->length); + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + ret = sscanf(input, "%d,%x", &path, &addr); + if (ret < 2) + return -EINVAL; + + if (path >= GET_HAL_RFPATH_NUM(padapter)) + return -EINVAL; + if (addr > 0xFF) + return -EINVAL; + + _rtw_memset(extra, 0, wrqu->length); + + sprintf(data, "%08x", read_rfreg(padapter, path, addr)); + /*add read data format blank*/ + for (i = 0 ; i <= strlen(data) ; i++) { + if (i % 2 == 0) { + tmp[j] = ' '; + j++; + } + tmp[j] = data[i]; + j++; + } + pch = tmp; + DBG_871X("pch=%s", pch); + + while (*pch != '\0') { + pnext = strpbrk(pch, " "); + if (!pnext) + break; + pnext++; + if (*pnext != '\0') { + /*strtou =simple_strtoul(pnext , &ptmp, 16);*/ + ret = sscanf(pnext, "%x", &strtou); + sprintf(extra, "%s %d" , extra , strtou); + } else + break; + pch = pnext; + } + wrqu->length = strlen(extra); + + return 0; +} + + +int rtw_mp_start(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 val8; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct hal_ops *pHalFunc = &padapter->HalFunc; + + rtw_pm_set_ips(padapter, IPS_NONE); + LeaveAllPowerSaveMode(padapter); + + if (padapter->registrypriv.mp_mode == 0) { + rtw_hal_deinit(padapter); + padapter->registrypriv.mp_mode = 1; + #ifdef CONFIG_RF_GAIN_OFFSET + if (!IS_HARDWARE_TYPE_8814A(padapter)) + padapter->registrypriv.RegRfKFreeEnable = 1; + rtw_hal_read_chip_info(padapter); + #endif /*CONFIG_RF_GAIN_OFFSET*/ + rtw_hal_init(padapter); + } + + if (padapter->registrypriv.mp_mode == 0) + return -EPERM; + + if (padapter->mppriv.mode == MP_OFF) { + if (mp_start_test(padapter) == _FAIL) + return -EPERM; + padapter->mppriv.mode = MP_ON; + MPT_PwrCtlDM(padapter, 0); + } + padapter->mppriv.bmac_filter = _FALSE; +#ifdef CONFIG_RTL8723B +#ifdef CONFIG_USB_HCI + rtw_write32(padapter, 0x765, 0x0000); + rtw_write32(padapter, 0x948, 0x0280); +#else + 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 + rtw_write8(padapter, 0x66, 0x27); /*Open BT uart Log*/ + rtw_write8(padapter, 0xc50, 0x20); /*for RX init Gain*/ +#endif + ODM_Write_DIG(&pHalData->odmpriv, 0x20); + + return 0; +} + + + +int rtw_mp_stop(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + struct hal_ops *pHalFunc = &padapter->HalFunc; + + if (padapter->registrypriv.mp_mode == 1) { + + MPT_DeInitAdapter(padapter); + pHalFunc->hal_deinit(padapter); + padapter->registrypriv.mp_mode = 0; + pHalFunc->hal_init(padapter); + } + + if (padapter->mppriv.mode != MP_OFF) { + mp_stop_test(padapter); + padapter->mppriv.mode = MP_OFF; + } + + return 0; +} + + +int rtw_mp_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 rate = MPT_RATE_1M; + u8 input[wrqu->length]; + PADAPTER padapter = rtw_netdev_priv(dev); + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + rate = rtw_mpRateParseFunc(padapter, input); + padapter->mppriv.rateidx = rate; + + if (rate == 0 && strcmp(input, "1M") != 0) { + rate = rtw_atoi(input); + padapter->mppriv.rateidx = MRateToHwRate(rate); + /*if (rate <= 0x7f) + rate = wifirate2_ratetbl_inx((u8)rate); + else if (rate < 0xC8) + rate = (rate - 0x79 + MPT_RATE_MCS0); + 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); + */ + } + _rtw_memset(extra, 0, wrqu->length); + + sprintf(extra, "Set data rate to %s index %d" , input, padapter->mppriv.rateidx); + DBG_871X("%s: %s rate index=%d\n", __func__, input, padapter->mppriv.rateidx); + + if (padapter->mppriv.rateidx >= DESC_RATEVHTSS4MCS9) + return -EINVAL; + + pMptCtx->MptRateIndex = padapter->mppriv.rateidx; + SetDataRate(padapter); + + wrqu->length = strlen(extra); + return 0; +} + + +int rtw_mp_channel(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 input[wrqu->length]; + u32 channel = 1; + int cur_ch_offset; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + 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; + SetChannel(padapter); + pHalData->CurrentChannel = channel; + + wrqu->length = strlen(extra); + return 0; +} + + +int rtw_mp_bandwidth(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 bandwidth = 0, sg = 0; + int cur_ch_offset; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (sscanf(extra, "40M=%d,shortGI=%d", &bandwidth, &sg) > 0) + DBG_871X("%s: bw=%d sg=%d\n", __func__, bandwidth , sg); + + if (bandwidth == 1) + bandwidth = CHANNEL_WIDTH_40; + else if (bandwidth == 2) + bandwidth = CHANNEL_WIDTH_80; + + padapter->mppriv.bandwidth = (u8)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);*/ + + return 0; +} + + +int rtw_mp_txpower_index(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->length]; + u32 rfpath; + u32 txpower_inx; + + if (wrqu->length > 128) + return -EFAULT; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + rfpath = rtw_atoi(input); + txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath); + sprintf(extra, " %d", txpower_inx); + wrqu->length = strlen(extra); + + return 0; +} + + +int rtw_mp_txpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0, status = 0; + int MsetPower = 1; + u8 input[wrqu->length]; + + PADAPTER padapter = rtw_netdev_priv(dev); + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + MsetPower = strncmp(input, "off", 3); + if (MsetPower == 0) { + padapter->mppriv.bSetTxPower = 0; + sprintf(extra, "MP Set power off"); + } else { + if (sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d) < 3) + DBG_871X("Invalid format on line %s ,patha=%d,pathb=%d,pathc=%d,pathd=%d\n", input , idx_a , idx_b , idx_c , idx_d); + + sprintf(extra, "Set power level path_A:%d path_B:%d path_C:%d path_D:%d", idx_a , idx_b , idx_c , idx_d); + padapter->mppriv.txpoweridx = (u8)idx_a; + + pMptCtx->TxPwrLevel[ODM_RF_PATH_A] = (u8)idx_a; + pMptCtx->TxPwrLevel[ODM_RF_PATH_B] = (u8)idx_b; + pMptCtx->TxPwrLevel[ODM_RF_PATH_C] = (u8)idx_c; + pMptCtx->TxPwrLevel[ODM_RF_PATH_D] = (u8)idx_d; + padapter->mppriv.bSetTxPower = 1; + + SetTxPower(padapter); + } + + wrqu->length = strlen(extra); + return 0; +} + + +int rtw_mp_ant_tx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 i; + u8 input[wrqu->length]; + u16 antenna = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + sprintf(extra, "switch Tx antenna to %s", input); + + for (i = 0; i < strlen(input); i++) { + switch (input[i]) { + case 'a': + antenna |= ANTENNA_A; + break; + case 'b': + antenna |= ANTENNA_B; + break; + case 'c': + antenna |= ANTENNA_C; + break; + case 'd': + antenna |= ANTENNA_D; + break; + } + } + /*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);*/ + pHalData->AntennaTxPath = antenna; + + SetAntenna(padapter); + + wrqu->length = strlen(extra); + return 0; +} + + +int rtw_mp_ant_rx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 i; + u16 antenna = 0; + u8 input[wrqu->length]; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + /*DBG_871X("%s: input=%s\n", __func__, input);*/ + _rtw_memset(extra, 0, wrqu->length); + + sprintf(extra, "switch Rx antenna to %s", input); + + for (i = 0; i < strlen(input); i++) { + switch (input[i]) { + case 'a': + antenna |= ANTENNA_A; + break; + case 'b': + antenna |= ANTENNA_B; + break; + case 'c': + antenna |= ANTENNA_C; + break; + case 'd': + antenna |= ANTENNA_D; + break; + } + } + + DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_tx = antenna; + padapter->mppriv.antenna_rx = antenna; + pHalData->AntennaRxPath = antenna; + /*DBG_871X("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);*/ + SetAntenna(padapter); + wrqu->length = strlen(extra); + + return 0; +} + + +int rtw_set_ctx_destAddr(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + int jj, kk = 0; + + struct pkt_attrib *pattrib; + struct mp_priv *pmp_priv; + PADAPTER padapter = rtw_netdev_priv(dev); + + pmp_priv = &padapter->mppriv; + pattrib = &pmp_priv->tx.attrib; + + if (strlen(extra) < 5) + return _FAIL; + + DBG_871X("%s: in=%s\n", __func__, extra); + for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3) + pattrib->dst[jj] = key_2char2num(extra[kk], extra[kk + 1]); + + DBG_871X("pattrib->dst:%x %x %x %x %x %x\n", pattrib->dst[0], pattrib->dst[1], pattrib->dst[2], pattrib->dst[3], pattrib->dst[4], pattrib->dst[5]); + return 0; +} + + + +int rtw_mp_ctx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 pkTx = 1; + int countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1; + u32 bStartTest = 1; + u32 count = 0, pktinterval = 0, pktlen = 0; + u8 status; + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + pmp_priv = &padapter->mppriv; + pattrib = &pmp_priv->tx.attrib; + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s: in=%s\n", __func__, extra); +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type == SECONDARY_ADAPTER) { + sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n"); + wrqu->length = strlen(extra); + return 0; + } +#endif + countPkTx = strncmp(extra, "count=", 5); /* strncmp TRUE is 0*/ + cotuTx = strncmp(extra, "background", 20); + CarrSprTx = strncmp(extra, "background,cs", 20); + scTx = strncmp(extra, "background,sc", 20); + sgleTx = strncmp(extra, "background,stone", 20); + pkTx = strncmp(extra, "background,pkt", 20); + stop = strncmp(extra, "stop", 4); + if (sscanf(extra, "count=%d,pkt", &count) > 0) + DBG_871X("count= %d\n", count); + if (sscanf(extra, "pktinterval=%d", &pktinterval) > 0) + DBG_871X("pktinterval= %d\n", pktinterval); + + if (sscanf(extra, "pktlen=%d", &pktlen) > 0) + DBG_871X("pktlen= %d\n", pktlen); + + if (_rtw_memcmp(extra, "destmac=", 8)) { + wrqu->length -= 8; + rtw_set_ctx_destAddr(dev, info, wrqu, &extra[8]); + sprintf(extra, "Set dest mac OK !\n"); + return 0; + } + + /*DBG_871X("%s: count=%d countPkTx=%d cotuTx=%d CarrSprTx=%d scTx=%d sgleTx=%d pkTx=%d stop=%d\n", __func__, count, countPkTx, cotuTx, CarrSprTx, pkTx, sgleTx, scTx, stop);*/ + _rtw_memset(extra, '\0', strlen(extra)); + + if (pktinterval != 0) { + sprintf(extra, "Pkt Interval = %d", pktinterval); + padapter->mppriv.pktInterval = pktinterval; + wrqu->length = strlen(extra); + return 0; + } + if (pktlen != 0) { + sprintf(extra, "Pkt len = %d", pktlen); + pattrib->pktlen = pktlen; + wrqu->length = strlen(extra); + return 0; + } + if (stop == 0) { + bStartTest = 0; /* To set Stop*/ + pmp_priv->tx.stop = 1; + sprintf(extra, "Stop continuous Tx"); + ODM_Write_DIG(&pHalData->odmpriv, 0x20); + } else { + bStartTest = 1; + ODM_Write_DIG(&pHalData->odmpriv, 0x7f); + if (pmp_priv->mode != MP_ON) { + if (pmp_priv->tx.stop != 1) { + DBG_871X("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode); + return -EFAULT; + } + } + } + + pmp_priv->tx.count = count; + + if (pkTx == 0 || countPkTx == 0) + pmp_priv->mode = MP_PACKET_TX; + if (sgleTx == 0) + pmp_priv->mode = MP_SINGLE_TONE_TX; + if (cotuTx == 0) + pmp_priv->mode = MP_CONTINUOUS_TX; + if (CarrSprTx == 0) + pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX; + if (scTx == 0) + pmp_priv->mode = MP_SINGLE_CARRIER_TX; + + status = rtw_mp_pretx_proc(padapter, bStartTest, extra); + + wrqu->length = strlen(extra); + return status; +} + + + +int rtw_mp_disable_bt_coexist(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct hal_ops *pHalFunc = &padapter->HalFunc; + + u8 input[wrqu->data.length]; + u32 bt_coexist; + + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + bt_coexist = rtw_atoi(input); + + if (bt_coexist == 0) { + RT_TRACE(_module_mp_, _drv_info_, + ("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n")); + DBG_871X("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n"); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_HaltNotify(padapter); + rtw_btcoex_SetManualControl(padapter, _TRUE); + /* Force to switch Antenna to WiFi*/ + rtw_write16(padapter, 0x870, 0x300); + rtw_write16(padapter, 0x860, 0x110); +#endif + /* CONFIG_BT_COEXIST */ + } else { + RT_TRACE(_module_mp_, _drv_info_, + ("Set OID_RT_SET_DISABLE_BT_COEXIST: enable BT_COEXIST\n")); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_SetManualControl(padapter, _FALSE); +#endif + } + + return 0; +} + + +int rtw_mp_arx(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + int bStartRx = 0, bStopRx = 0, bQueryPhy = 0, bQueryMac = 0, bSetBssid = 0; + int bmac_filter = 0, bfilter_init = 0, bmon = 0, bSmpCfg = 0; + u8 input[wrqu->length]; + char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00}; + u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, ret; + PADAPTER padapter = rtw_netdev_priv(dev); + struct mp_priv *pmppriv = &padapter->mppriv; + struct dbg_rx_counter rx_counter; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s: %s\n", __func__, input); +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type == SECONDARY_ADAPTER) { + sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n"); + wrqu->length = strlen(extra); + return 0; + } +#endif + bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ + bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ + bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ + bQueryMac = (strncmp(input, "mac", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ + bSetBssid = (strncmp(input, "setbssid=", 8) == 0) ? 1 : 0; /* strncmp TRUE is 0*/ + /*bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;*/ + bmac_filter = (strncmp(input, "accept_mac", 10) == 0) ? 1 : 0; + bmon = (strncmp(input, "mon=", 4) == 0) ? 1 : 0; + bSmpCfg = (strncmp(input , "smpcfg=" , 7) == 0) ? 1 : 0; + + if (bSetBssid == 1) { + pch = input; + while ((token = strsep(&pch, "=")) != NULL) { + if (i > 1) + break; + tmp[i] = token; + i++; + } + if ((tmp[0] != NULL) && (tmp[1] != NULL)) { + cnts = strlen(tmp[1]) / 2; + if (cnts < 1) + return -EFAULT; + DBG_871X("%s: cnts=%d\n", __func__, cnts); + DBG_871X("%s: data=%s\n", __func__, tmp[1]); + for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) { + pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); + DBG_871X("network_macaddr[%d]=%x\n", jj, pmppriv->network_macaddr[jj]); + } + } else + return -EFAULT; + + pmppriv->bSetRxBssid = _TRUE; + } + + if (bmac_filter) { + pmppriv->bmac_filter = bmac_filter; + pch = input; + while ((token = strsep(&pch, "=")) != NULL) { + if (i > 1) + break; + tmp[i] = token; + i++; + } + if ((tmp[0] != NULL) && (tmp[1] != NULL)) { + cnts = strlen(tmp[1]) / 2; + if (cnts < 1) + return -EFAULT; + DBG_871X("%s: cnts=%d\n", __func__, cnts); + DBG_871X("%s: data=%s\n", __func__, tmp[1]); + for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) { + pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); + DBG_871X("%s mac_filter[%d]=%x\n", __func__, jj, pmppriv->mac_filter[jj]); + } + } else + return -EFAULT; + + } + + if (bStartRx) { + sprintf(extra, "start"); + SetPacketRx(padapter, bStartRx, _FALSE); + } else if (bStopRx) { + SetPacketRx(padapter, bStartRx, _FALSE); + pmppriv->bmac_filter = _FALSE; + sprintf(extra, "Received packet OK:%d CRC error:%d ,Filter out:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount, padapter->mppriv.rx_pktcount_filter_out); + } else if (bQueryPhy) { + _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter)); + rtw_dump_phy_rx_counters(padapter, &rx_counter); + + DBG_871X("%s: OFDM_FA =%d\n", __func__, rx_counter.rx_ofdm_fa); + DBG_871X("%s: CCK_FA =%d\n", __func__, rx_counter.rx_cck_fa); + sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa); + + + } else if (bQueryMac) { + _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter)); + rtw_dump_mac_rx_counters(padapter, &rx_counter); + sprintf(extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n", + rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop); + + } + + if (bmon == 1) { + ret = sscanf(input, "mon=%d", &bmon); + + if (bmon == 1) { + pmppriv->rx_bindicatePkt = _TRUE; + sprintf(extra, "Indicating Receive Packet to network start\n"); + } else { + pmppriv->rx_bindicatePkt = _FALSE; + sprintf(extra, "Indicating Receive Packet to network Stop\n"); + } + } + if (bSmpCfg == 1) { + ret = sscanf(input, "smpcfg=%d", &bSmpCfg); + + if (bSmpCfg == 1) { + pmppriv->bRTWSmbCfg = _TRUE; + sprintf(extra , "Indicate By Simple Config Format\n"); + SetPacketRx(padapter, _TRUE, _TRUE); + } else { + pmppriv->bRTWSmbCfg = _FALSE; + sprintf(extra , "Indicate By Normal Format\n"); + SetPacketRx(padapter, _TRUE, _FALSE); + } + } + + wrqu->length = strlen(extra) + 1; + + return 0; +} + + +int rtw_mp_trx_query(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u32 txok, txfail, rxok, rxfail, rxfilterout; + PADAPTER padapter = rtw_netdev_priv(dev); + + txok = padapter->mppriv.tx.sended; + txfail = 0; + rxok = padapter->mppriv.rx_pktcount; + rxfail = padapter->mppriv.rx_crcerrpktcount; + rxfilterout = padapter->mppriv.rx_pktcount_filter_out; + + _rtw_memset(extra, '\0', 128); + + sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d\n", txok, txfail, rxok, rxfail, rxfilterout); + + wrqu->length = strlen(extra) + 1; + + return 0; +} + + +int rtw_mp_pwrtrk(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 enable; + u32 thermal; + s32 ret; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + u8 input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + _rtw_memset(extra, 0, wrqu->length); + + enable = 1; + if (wrqu->length > 1) { + /* not empty string*/ + if (strncmp(input, "stop", 4) == 0) { + enable = 0; + sprintf(extra, "mp tx power tracking stop"); + } else if (sscanf(input, "ther=%d", &thermal) == 1) { + ret = SetThermalMeter(padapter, (u8)thermal); + if (ret == _FAIL) + return -EPERM; + sprintf(extra, "mp tx power tracking start,target value=%d ok", thermal); + } else + return -EINVAL; + } + + ret = SetPowerTracking(padapter, enable); + if (ret == _FAIL) + return -EPERM; + + wrqu->length = strlen(extra); + + return 0; +} + + + +int rtw_mp_psd(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + strcpy(extra, input); + + wrqu->length = mp_query_psd(padapter, extra); + + return 0; +} + + +int rtw_mp_thermal(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + u8 val; + int bwrite = 1; + +#ifdef CONFIG_RTL8188E + u16 addr = EEPROM_THERMAL_METER_88E; +#endif +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A) + u16 addr = EEPROM_THERMAL_METER_8812; +#endif +#ifdef CONFIG_RTL8192E + u16 addr = EEPROM_THERMAL_METER_8192E; +#endif +#ifdef CONFIG_RTL8723B + u16 addr = EEPROM_THERMAL_METER_8723B; +#endif +#ifdef CONFIG_RTL8703B + u16 addr = EEPROM_THERMAL_METER_8703B; +#endif +#ifdef CONFIG_RTL8188F + u16 addr = EEPROM_THERMAL_METER_8188F; +#endif + u16 cnt = 1; + u16 max_available_size = 0; + PADAPTER padapter = rtw_netdev_priv(dev); + + if (copy_from_user(extra, wrqu->pointer, wrqu->length)) + return -EFAULT; + + bwrite = strncmp(extra, "write", 6);/* strncmp TRUE is 0*/ + + GetThermalMeter(padapter, &val); + + if (bwrite == 0) { + /*DBG_871X("to write val:%d",val);*/ + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE); + if (2 > max_available_size) { + DBG_871X("no available efuse!\n"); + return -EFAULT; + } + if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) { + DBG_871X("rtw_efuse_map_write error\n"); + return -EFAULT; + } + sprintf(extra, " efuse write ok :%d", val); + } else + sprintf(extra, "%d", val); + wrqu->length = strlen(extra); + + return 0; +} + + + +int rtw_mp_reset_stats(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + PADAPTER padapter = rtw_netdev_priv(dev); + + pmp_priv = &padapter->mppriv; + + pmp_priv->tx.sended = 0; + pmp_priv->tx_pktcount = 0; + pmp_priv->rx_pktcount = 0; + pmp_priv->rx_pktcount_filter_out = 0; + pmp_priv->rx_crcerrpktcount = 0; + + rtw_reset_phy_rx_counters(padapter); + rtw_reset_mac_rx_counters(padapter); + + return 0; +} + + +int rtw_mp_dump(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + struct mp_priv *pmp_priv; + struct pkt_attrib *pattrib; + u32 value; + u8 input[wrqu->length]; + u8 rf_type, path_nums = 0; + u32 i, j = 1, path; + PADAPTER padapter = rtw_netdev_priv(dev); + + pmp_priv = &padapter->mppriv; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + if (strncmp(input, "all", 4) == 0) { + mac_reg_dump(RTW_DBGDUMP, padapter); + bb_reg_dump(RTW_DBGDUMP, padapter); + rf_reg_dump(RTW_DBGDUMP, padapter); + } + return 0; +} + + +int rtw_mp_phypara(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + char input[wrqu->length]; + u32 valxcap, ret; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + DBG_871X("%s:iwpriv in=%s\n", __func__, input); + + ret = sscanf(input, "xcap=%d", &valxcap); + + pHalData->CrystalCap = (u8)valxcap; + hal_set_crystal_cap(padapter , valxcap); + + sprintf(extra, "Set xcap=%d", valxcap); + wrqu->length = strlen(extra) + 1; + + return 0; + +} + + +int rtw_mp_SetRFPath(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->data.length]; + int bMain = 1, bTurnoff = 1; + + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + DBG_871X("%s:iwpriv in=%s\n", __func__, input); + + bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/ + bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/ + + if (bMain == 0) { + MP_PHY_SetRFPathSwitch(padapter, _TRUE); + DBG_871X("%s:PHY_SetRFPathSwitch=TRUE\n", __func__); + } else if (bTurnoff == 0) { + MP_PHY_SetRFPathSwitch(padapter, _FALSE); + DBG_871X("%s:PHY_SetRFPathSwitch=FALSE\n", __func__); + } + + return 0; +} + + +int rtw_mp_QueryDrv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + char input[wrqu->data.length]; + int qAutoLoad = 1; + + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); + + if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + DBG_871X("%s:iwpriv in=%s\n", __func__, input); + + qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/ + + if (qAutoLoad == 0) { + DBG_871X("%s:qAutoLoad\n", __func__); + + if (pHalData->bautoload_fail_flag) + sprintf(extra, "fail"); + else + sprintf(extra, "ok"); + } + wrqu->data.length = strlen(extra) + 1; + return 0; +} + + +int rtw_mp_PwrCtlDM(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + u8 input[wrqu->length]; + int bstart = 1; + + if (copy_from_user(input, wrqu->pointer, wrqu->length)) + return -EFAULT; + + bstart = strncmp(input, "start", 5); /* strncmp TRUE is 0*/ + if (bstart == 0) { + sprintf(extra, "PwrCtlDM start\n"); + MPT_PwrCtlDM(padapter, 1); + } else { + sprintf(extra, "PwrCtlDM stop\n"); + MPT_PwrCtlDM(padapter, 0); + } + wrqu->length = strlen(extra); + + return 0; +} + + +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; +} + + +int rtw_mp_mon(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 = &padapter->mppriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct hal_ops *pHalFunc = &padapter->HalFunc; + NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; + int bstart = 1, bstop = 1; + + networkType = Ndis802_11Infrastructure; + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + rtw_pm_set_ips(padapter, IPS_NONE); + LeaveAllPowerSaveMode(padapter); + +#ifdef CONFIG_MP_INCLUDED + if (init_mp_priv(padapter) == _FAIL) + DBG_871X("%s: initialize MP private data Fail!\n", __func__); + padapter->mppriv.channel = 6; + + bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/ + bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/ + if (bstart == 0) { + mp_join(padapter, WIFI_FW_ADHOC_STATE); + SetPacketRx(padapter, _TRUE, _FALSE); + SetChannel(padapter); + pmp_priv->rx_bindicatePkt = _TRUE; + pmp_priv->bRTWSmbCfg = _TRUE; + sprintf(extra, "monitor mode start\n"); + } else if (bstop == 0) { + SetPacketRx(padapter, _FALSE, _FALSE); + pmp_priv->rx_bindicatePkt = _FALSE; + pmp_priv->bRTWSmbCfg = _FALSE; + padapter->registrypriv.mp_mode = 1; + pHalFunc->hal_deinit(padapter); + padapter->registrypriv.mp_mode = 0; + pHalFunc->hal_init(padapter); + /*rtw_disassoc_cmd(padapter, 0, _TRUE);*/ + if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + rtw_disassoc_cmd(padapter, 500, _TRUE); + rtw_indicate_disconnect(padapter); + /*rtw_free_assoc_resources(padapter, 1);*/ + } + rtw_pm_set_ips(padapter, IPS_NORMAL); + sprintf(extra, "monitor mode Stop\n"); + } +#endif + wrqu->data.length = strlen(extra); + return 0; +} + +int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra) +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mp_priv *pmp_priv = &padapter->mppriv; + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + + switch (pmp_priv->mode) { + + case MP_PACKET_TX: + if (bStartTest == 0) { + pmp_priv->tx.stop = 1; + pmp_priv->mode = MP_ON; + sprintf(extra, "Stop continuous Tx"); + } else if (pmp_priv->tx.stop == 1) { + sprintf(extra, "%s\nStart continuous DA=ffffffffffff len=1500 count=%u\n", extra, pmp_priv->tx.count); + pmp_priv->tx.stop = 0; + SetPacketTx(padapter); + } else { + return -EFAULT; + } + return 0; + case MP_SINGLE_TONE_TX: + if (bStartTest != 0) + sprintf(extra, "%s\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.", extra); + SetSingleToneTx(padapter, (u8)bStartTest); + break; + case MP_CONTINUOUS_TX: + if (bStartTest != 0) + sprintf(extra, "%s\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.", extra); + SetContinuousTx(padapter, (u8)bStartTest); + break; + case MP_CARRIER_SUPPRISSION_TX: + if (bStartTest != 0) { + if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_11M) + sprintf(extra, "%s\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.", extra); + else + sprintf(extra, "%s\nSpecify carrier suppression but not CCK rate", extra); + } + SetCarrierSuppressionTx(padapter, (u8)bStartTest); + break; + case MP_SINGLE_CARRIER_TX: + if (bStartTest != 0) + sprintf(extra, "%s\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.", extra); + SetSingleCarrierTx(padapter, (u8)bStartTest); + break; + + default: + sprintf(extra, "Error! Continuous-Tx is not on-going."); + return -EFAULT; + } + + if (bStartTest == 1 && pmp_priv->mode != MP_ON) { + struct mp_priv *pmp_priv = &padapter->mppriv; + + if (pmp_priv->tx.stop == 0) { + pmp_priv->tx.stop = 1; + rtw_msleep_os(5); + } +#ifdef CONFIG_80211N_HT + pmp_priv->tx.attrib.ht_en = 1; +#endif + pmp_priv->tx.stop = 0; + pmp_priv->tx.count = 1; + SetPacketTx(padapter); + } else + pmp_priv->mode = MP_ON; + +#if defined(CONFIG_RTL8812A) + if (IS_HARDWARE_TYPE_8812AU(padapter)) { + /* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/ + if (pmp_priv->mode == MP_PACKET_TX) + PHY_SetBBReg(padapter, rCCAonSec_Jaguar, BIT3, 1); + else + PHY_SetBBReg(padapter, rCCAonSec_Jaguar, BIT3, 0); + } +#endif + + return 0; +} + + +int rtw_mp_tx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mp_priv *pmp_priv = &padapter->mppriv; + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + struct registry_priv *pregistrypriv = &padapter->registrypriv; + + u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0; + u8 i = 0, j = 0, bStartTest = 1, status = 0, Idx = 0, tmpU1B = 0; + u16 antenna = 0; + + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + DBG_871X("extra = %s\n", extra); +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type == SECONDARY_ADAPTER) { + sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n"); + wrqu->data.length = strlen(extra); + return 0; + } +#endif + + if (strncmp(extra, "stop", 3) == 0) { + bStartTest = 0; /* To set Stop*/ + pmp_priv->tx.stop = 1; + sprintf(extra, "Stop continuous Tx"); + status = rtw_mp_pretx_proc(padapter, bStartTest, extra); + wrqu->data.length = strlen(extra); + return status; + } else if (strncmp(extra, "count", 5) == 0) { + if (sscanf(extra, "count=%d", &count) < 1) + DBG_871X("Got Count=%d]\n", count); + pmp_priv->tx.count = count; + return 0; + } else if (strncmp(extra, "setting", 7) == 0) { + _rtw_memset(extra, 0, wrqu->data.length); + sprintf(extra, "Current Setting :\n Channel:%d", pmp_priv->channel); + sprintf(extra, "%s\n Bandwidth:%d", extra, pmp_priv->bandwidth); + sprintf(extra, "%s\n Rate index:%d", extra, pmp_priv->rateidx); + sprintf(extra, "%s\n TxPower index:%d", extra, pmp_priv->txpoweridx); + sprintf(extra, "%s\n Antenna TxPath:%d", extra, pmp_priv->antenna_tx); + sprintf(extra, "%s\n Antenna RxPath:%d", extra, pmp_priv->antenna_rx); + sprintf(extra, "%s\n MP Mode:%d", extra, pmp_priv->mode); + wrqu->data.length = strlen(extra); + return 0; +#ifdef CONFIG_MP_VHT_HW_TX_MODE + } else if (strncmp(extra, "pmact", 5) == 0) { + if (strncmp(extra, "pmact=start", 11) == 0) { + _rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo)); + pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE; + + if (pMptCtx->bldpc == TRUE) + pMptCtx->PMacTxInfo.bLDPC = _TRUE; + + if (pMptCtx->bstbc == TRUE) + pMptCtx->PMacTxInfo.bSTBC = _TRUE; + + pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble; + pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble; + pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth; + pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx); + + pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode; + + pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/ + + if (padapter->mppriv.pktInterval == 0) + pMptCtx->PMacTxInfo.PacketPeriod = 100; + else + pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval; + + if (padapter->mppriv.pktLength < 1000) + pMptCtx->PMacTxInfo.PacketLength = 1000; + else + pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength; + + pMptCtx->PMacTxInfo.PacketPattern = rtw_random32() % 0xFF; + + if (padapter->mppriv.tx_pktcount != 0) + pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount; + + pMptCtx->PMacTxInfo.Ntx = 0; + for (Idx = 16; Idx < 20; Idx++) { + tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1; + if (tmpU1B) + pMptCtx->PMacTxInfo.Ntx++; + } + + _rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN); + + PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + + if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE)) { + + CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + } else { + PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + /* 24 BIT*/ + L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + } + /* 48BIT*/ + if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) + HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) { + /* 48BIT*/ + VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo); + + /* 26/27/29 BIT & CRC 8 BIT*/ + VHT_SIG_B_generator(&pMptCtx->PMacTxInfo); + + /* 32 BIT*/ + VHT_Delimiter_generator(&pMptCtx->PMacTxInfo); + } + + mpt_ProSetPMacTx(padapter); + sprintf(extra, "Set PMac Tx Mode start\n"); + + } else if (strncmp(extra, "pmact,mode=", 11) == 0) { + int txmode = 0; + + if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) { + if (txmode == 1) { + pMptCtx->HWTxmode = CONTINUOUS_TX; + sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n"); + } else if (txmode == 2) { + pMptCtx->HWTxmode = OFDM_Single_Tone_TX; + sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n"); + } else { + pMptCtx->HWTxmode = PACKETS_TX; + sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n"); + } + } else { + pMptCtx->HWTxmode = PACKETS_TX; + sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX"); + } + } else if (strncmp(extra, "pmact,", 6) == 0) { + int PacketPeriod = 0, PacketLength = 0, PacketCout = 0; + int bldpc = 0, bstbc = 0; + + if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) { + padapter->mppriv.pktInterval = PacketPeriod; + DBG_871X("PacketPeriod=%d\n", padapter->mppriv.pktInterval); + sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval); + + } else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) { + padapter->mppriv.pktLength = PacketLength; + DBG_871X("PacketPeriod=%d\n", padapter->mppriv.pktLength); + sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength); + + } else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) { + padapter->mppriv.tx_pktcount = PacketCout; + DBG_871X("Packet Cout =%d\n", padapter->mppriv.tx_pktcount); + sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount); + + } else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) { + pMptCtx->bldpc = bldpc; + DBG_871X("Set LDPC =%d\n", pMptCtx->bldpc); + sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc); + + } else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) { + pMptCtx->bstbc = bstbc; + DBG_871X("Set STBC =%d\n", pMptCtx->bstbc); + sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc); + } else + sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}"); + + } else { + pMptCtx->PMacTxInfo.bEnPMacTx = FALSE; + sprintf(extra, "Set PMac Tx Mode stop\n"); + + } + + wrqu->data.length = strlen(extra); + return 0; +#endif + } else { + + if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) { + DBG_871X("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode); + _rtw_memset(extra, 0, wrqu->data.length); + sprintf(extra, "\n Please input correct format as bleow:\n"); + sprintf(extra, "%s\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", extra, channel, bandwidth, rate, txpower, ant, txmode); + sprintf(extra, "%s\n [ ch : BGN = <1~14> , A or AC = <36~165> ]", extra); + sprintf(extra, "%s\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]", extra); + sprintf(extra, "%s\n [ rate : CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]", extra); + sprintf(extra, "%s\n [ OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>", extra); + sprintf(extra, "%s\n [ HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >", extra); + sprintf(extra, "%s\n [ HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >", extra); + sprintf(extra, "%s\n [ VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >", extra); + sprintf(extra, "%s\n [ txpower : 1~63 power index", extra); + sprintf(extra, "%s\n [ ant : ,2T ex: AB=3 BC=6 CD=12", extra); + sprintf(extra, "%s\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n", extra); + wrqu->data.length = strlen(extra); + return status; + + } else { + DBG_871X("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode); + _rtw_memset(extra, 0, wrqu->data.length); + sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel); + padapter->mppriv.channel = channel; + SetChannel(padapter); + pHalData->CurrentChannel = channel; + + if (bandwidth == 1) + bandwidth = CHANNEL_WIDTH_40; + else if (bandwidth == 2) + bandwidth = CHANNEL_WIDTH_80; + sprintf(extra, "%s\nChange Current Bandwidth %d to Bandwidth %d", extra, padapter->mppriv.bandwidth , bandwidth); + padapter->mppriv.bandwidth = (u8)bandwidth; + padapter->mppriv.preamble = sg; + SetBandwidth(padapter); + pHalData->CurrentChannelBW = bandwidth; + + sprintf(extra, "%s\nSet power level :%d", extra, txpower); + padapter->mppriv.txpoweridx = (u8)txpower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_A] = (u8)txpower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_B] = (u8)txpower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_C] = (u8)txpower; + pMptCtx->TxPwrLevel[ODM_RF_PATH_D] = (u8)txpower; + + DBG_871X("%s: bw=%d sg=%d\n", __func__, bandwidth, sg); + + if (rate <= 0x7f) + rate = wifirate2_ratetbl_inx((u8)rate); + else if (rate < 0xC8) + rate = (rate - 0x80 + MPT_RATE_MCS0); + /*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); + */ + DBG_871X("%s: rate index=%d\n", __func__, rate); + if (rate >= MPT_RATE_LAST) + return -EINVAL; + sprintf(extra, "%s\nSet data rate to %d index %d", extra, padapter->mppriv.rateidx, rate); + + padapter->mppriv.rateidx = rate; + pMptCtx->MptRateIndex = rate; + SetDataRate(padapter); + + sprintf(extra, "%s\nSet Antenna Path :%d", extra, ant); + switch (ant) { + case 1: + antenna = ANTENNA_A; + break; + case 2: + antenna = ANTENNA_B; + break; + case 4: + antenna = ANTENNA_C; + break; + case 8: + antenna = ANTENNA_D; + break; + case 3: + antenna = ANTENNA_AB; + break; + case 5: + antenna = ANTENNA_AC; + break; + case 9: + antenna = ANTENNA_AD; + break; + case 6: + antenna = ANTENNA_BC; + break; + case 10: + antenna = ANTENNA_BD; + break; + case 12: + antenna = ANTENNA_CD; + break; + case 7: + antenna = ANTENNA_ABC; + break; + case 14: + antenna = ANTENNA_BCD; + break; + case 11: + antenna = ANTENNA_ABD; + break; + case 15: + antenna = ANTENNA_ABCD; + break; + } + DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_tx = antenna; + padapter->mppriv.antenna_rx = antenna; + pHalData->AntennaTxPath = antenna; + SetAntenna(padapter); + + if (txmode == 0) { + pmp_priv->mode = MP_CONTINUOUS_TX; + } else if (txmode == 1) { + pmp_priv->mode = MP_PACKET_TX; + pmp_priv->tx.count = count; + } else if (txmode == 2) { + pmp_priv->mode = MP_SINGLE_TONE_TX; + } else if (txmode == 3) { + pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX; + } else if (txmode == 4) { + pmp_priv->mode = MP_SINGLE_CARRIER_TX; + } + + status = rtw_mp_pretx_proc(padapter, bStartTest, extra); + } + + } + + wrqu->data.length = strlen(extra); + return status; +} + + +int rtw_mp_rx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + struct mp_priv *pmp_priv = &padapter->mppriv; + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + + u32 bandwidth = 0, sg = 0, channel = 6, ant = 0; + u16 antenna = 0; + u8 bStartRx = 0; + + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type == SECONDARY_ADAPTER) { + sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n"); + wrqu->data.length = strlen(extra); + return 0; + } +#endif + + if (strncmp(extra, "stop", 4) == 0) { + _rtw_memset(extra, 0, wrqu->data.length); + SetPacketRx(padapter, bStartRx, _FALSE); + pmp_priv->bmac_filter = _FALSE; + sprintf(extra, "Received packet OK:%d CRC error:%d ,Filter out:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount, padapter->mppriv.rx_pktcount_filter_out); + wrqu->data.length = strlen(extra); + return 0; + + } else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) { + DBG_871X("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant); + _rtw_memset(extra, 0, wrqu->data.length); + sprintf(extra, "\n Please input correct format as bleow:\n"); + sprintf(extra, "%s\t ch=%d,bw=%d,ant=%d\n", extra, channel, bandwidth, ant); + sprintf(extra, "%s\n [ ch : BGN = <1~14> , A or AC = <36~165> ]", extra); + sprintf(extra, "%s\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]", extra); + sprintf(extra, "%s\n [ ant : ,2T ex: AB=3 BC=6 CD=12", extra); + wrqu->data.length = strlen(extra); + return 0; + + } else { + bStartRx = 1; + DBG_871X("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant); + _rtw_memset(extra, 0, wrqu->data.length); + sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel); + padapter->mppriv.channel = channel; + SetChannel(padapter); + pHalData->CurrentChannel = channel; + + if (bandwidth == 1) + bandwidth = CHANNEL_WIDTH_40; + else if (bandwidth == 2) + bandwidth = CHANNEL_WIDTH_80; + sprintf(extra, "%s\nChange Current Bandwidth %d to Bandwidth %d", extra, padapter->mppriv.bandwidth , bandwidth); + padapter->mppriv.bandwidth = (u8)bandwidth; + padapter->mppriv.preamble = sg; + SetBandwidth(padapter); + pHalData->CurrentChannelBW = bandwidth; + + sprintf(extra, "%s\nSet Antenna Path :%d", extra, ant); + switch (ant) { + case 1: + antenna = ANTENNA_A; + break; + case 2: + antenna = ANTENNA_B; + break; + case 4: + antenna = ANTENNA_C; + break; + case 8: + antenna = ANTENNA_D; + break; + case 3: + antenna = ANTENNA_AB; + break; + case 5: + antenna = ANTENNA_AC; + break; + case 9: + antenna = ANTENNA_AD; + break; + case 6: + antenna = ANTENNA_BC; + break; + case 10: + antenna = ANTENNA_BD; + break; + case 12: + antenna = ANTENNA_CD; + break; + case 7: + antenna = ANTENNA_ABC; + break; + case 14: + antenna = ANTENNA_BCD; + break; + case 11: + antenna = ANTENNA_ABD; + break; + case 15: + antenna = ANTENNA_ABCD; + break; + } + DBG_871X("%s: antenna=0x%x\n", __func__, antenna); + padapter->mppriv.antenna_tx = antenna; + padapter->mppriv.antenna_rx = antenna; + pHalData->AntennaTxPath = antenna; + SetAntenna(padapter); + + sprintf(extra, "%s\nstart Rx", extra); + SetPacketRx(padapter, bStartRx, _FALSE); + } + wrqu->data.length = strlen(extra); + return 0; +} + + +int rtw_efuse_mask_file(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + char *rtw_efuse_mask_file_path; + u8 Status; + PADAPTER padapter = rtw_netdev_priv(dev); + + _rtw_memset(maskfileBuffer, 0x00, sizeof(maskfileBuffer)); + + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) { + padapter->registrypriv.boffefusemask = 1; + sprintf(extra, "Turn off Efuse Mask\n"); + wrqu->data.length = strlen(extra); + return 0; + } + if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) { + padapter->registrypriv.boffefusemask = 0; + sprintf(extra, "Turn on Efuse Mask\n"); + wrqu->data.length = strlen(extra); + return 0; + } + rtw_efuse_mask_file_path = extra; + + if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) { + DBG_871X("%s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(maskfileBuffer)); + Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, maskfileBuffer, sizeof(maskfileBuffer)); + if (Status == _TRUE) + padapter->registrypriv.bFileMaskEfuse = _TRUE; + sprintf(extra, "efuse mask file read OK\n"); + } else { + padapter->registrypriv.bFileMaskEfuse = _FALSE; + sprintf(extra, "efuse mask file readable FAIL\n"); + DBG_871X("%s rtw_is_file_readable fail!\n", __func__); + } + wrqu->data.length = strlen(extra); + return 0; +} + + +int rtw_efuse_file_map(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + char *rtw_efuse_file_map_path; + u8 Status; + PEFUSE_HAL pEfuseHal; + PADAPTER padapter = rtw_netdev_priv(dev); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + pEfuseHal = &pHalData->EfuseHal; + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + rtw_efuse_file_map_path = extra; + + if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) { + DBG_871X("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path); + Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, sizeof(pEfuseHal->fakeEfuseModifiedMap)); + if (Status == _TRUE) + sprintf(extra, "efuse file file_read OK\n"); + else + sprintf(extra, "efuse file file_read FAIL\n"); + } else { + sprintf(extra, "efuse file readable FAIL\n"); + DBG_871X("%s rtw_is_file_readable fail!\n", __func__); + } + wrqu->data.length = strlen(extra); + return 0; +} + +#if defined(CONFIG_RTL8723B) +int rtw_mp_SetBT(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + PADAPTER padapter = rtw_netdev_priv(dev); + struct hal_ops *pHalFunc = &padapter->HalFunc; + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + + BT_REQ_CMD BtReq; + PMPT_CONTEXT pMptCtx = &(padapter->mppriv.MptCtx); + PBT_RSP_CMD pBtRsp = (PBT_RSP_CMD)&pMptCtx->mptOutBuf[0]; + char input[128]; + char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00}; + u8 setdata[100]; + u8 resetbt = 0x00; + u8 tempval, BTStatus; + u8 H2cSetbtmac[6]; + u8 u1H2CBtMpOperParm[4] = {0x01}; + int testmode = 1, ready = 1, trxparam = 1, setgen = 1, getgen = 1, testctrl = 1, testbt = 1, readtherm = 1, setbtmac = 1; + u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, status = 0; + PRT_MP_FIRMWARE pBTFirmware = NULL; + + if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + if (strlen(extra) < 1) + return -EFAULT; + + DBG_871X("%s:iwpriv in=%s\n", __func__, extra); + ready = strncmp(extra, "ready", 5); + testmode = strncmp(extra, "testmode", 8); /* strncmp TRUE is 0*/ + trxparam = strncmp(extra, "trxparam", 8); + setgen = strncmp(extra, "setgen", 6); + getgen = strncmp(extra, "getgen", 6); + testctrl = strncmp(extra, "testctrl", 8); + testbt = strncmp(extra, "testbt", 6); + readtherm = strncmp(extra, "readtherm", 9); + setbtmac = strncmp(extra, "setbtmac", 8); + + if (strncmp(extra, "dlbt", 4) == 0) { + pHalData->LastHMEBoxNum = 0; + padapter->bBTFWReady = _FALSE; + rtw_write8(padapter, 0xa3, 0x05); + BTStatus = rtw_read8(padapter, 0xa0); + DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); + if (BTStatus != 0x04) { + sprintf(extra, "BT Status not Active DLFW FAIL\n"); + goto exit; + } + + tempval = rtw_read8(padapter, 0x6B); + tempval |= BIT7; + rtw_write8(padapter, 0x6B, tempval); + + /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/ + /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/ + rtw_usleep_os(100); + /* disable BT power cut*/ + /* 0x6A[14] = 0*/ + tempval = rtw_read8(padapter, 0x6B); + tempval &= ~BIT6; + rtw_write8(padapter, 0x6B, tempval); + rtw_usleep_os(100); + MPT_PwrCtlDM(padapter, 0); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF)); + rtw_msleep_os(600); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010)); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB)); + rtw_msleep_os(1200); + pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE)); + if (pBTFirmware == NULL) + goto exit; + padapter->bBTFWReady = _FALSE; + FirmwareDownloadBT(padapter, pBTFirmware); + if (pBTFirmware) + rtw_mfree((u8 *)pBTFirmware, sizeof(RT_MP_FIRMWARE)); + + DBG_871X("Wait for FirmwareDownloadBT fw boot!\n"); + rtw_msleep_os(2000); + _rtw_memset(extra, '\0', wrqu->data.length); + BtReq.opCodeVer = 1; + BtReq.OpCode = 0; + BtReq.paraLength = 0; + mptbt_BtControlProcess(padapter, &BtReq); + rtw_msleep_os(100); + + DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]); + if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { + + if (padapter->mppriv.bTxBufCkFail == _TRUE) + sprintf(extra, "check TxBuf Fail.\n"); + else + sprintf(extra, "download FW Fail.\n"); + } else { + sprintf(extra, "download FW OK.\n"); + goto exit; + } + goto exit; + } + if (strncmp(extra, "dlfw", 4) == 0) { + pHalData->LastHMEBoxNum = 0; + padapter->bBTFWReady = _FALSE; + rtw_write8(padapter, 0xa3, 0x05); + BTStatus = rtw_read8(padapter, 0xa0); + DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus); + if (BTStatus != 0x04) { + sprintf(extra, "BT Status not Active DLFW FAIL\n"); + goto exit; + } + + tempval = rtw_read8(padapter, 0x6B); + tempval |= BIT7; + rtw_write8(padapter, 0x6B, tempval); + + /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/ + /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/ + rtw_usleep_os(100); + /* disable BT power cut*/ + /* 0x6A[14] = 0*/ + tempval = rtw_read8(padapter, 0x6B); + tempval &= ~BIT6; + rtw_write8(padapter, 0x6B, tempval); + rtw_usleep_os(100); + + MPT_PwrCtlDM(padapter, 0); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF)); + rtw_msleep_os(600); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010)); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB)); + rtw_msleep_os(1200); + +#if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1) + /* Pull up BT reset pin.*/ + DBG_871X("%s: pull up BT reset pin when bt start mp test\n", __func__); + rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON); +#endif + DBG_871X(" FirmwareDownload!\n"); + +#if defined(CONFIG_RTL8723B) + status = rtl8723b_FirmwareDownload(padapter, _FALSE); +#endif + DBG_871X("Wait for FirmwareDownloadBT fw boot!\n"); + rtw_msleep_os(1000); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_HaltNotify(padapter); + DBG_871X("SetBT btcoex HaltNotify !\n"); + /*hal_btcoex1ant_SetAntPath(padapter);*/ + rtw_btcoex_SetManualControl(padapter, _TRUE); +#endif + _rtw_memset(extra, '\0', wrqu->data.length); + BtReq.opCodeVer = 1; + BtReq.OpCode = 0; + BtReq.paraLength = 0; + mptbt_BtControlProcess(padapter, &BtReq); + rtw_msleep_os(200); + + DBG_8192C("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]); + if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) { + if (padapter->mppriv.bTxBufCkFail == _TRUE) + sprintf(extra, "check TxBuf Fail.\n"); + else + sprintf(extra, "download FW Fail.\n"); + } else { +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_SwitchBtTRxMask(padapter); +#endif + rtw_msleep_os(200); + sprintf(extra, "download FW OK.\n"); + goto exit; + } + goto exit; + } + + if (strncmp(extra, "down", 4) == 0) { + DBG_871X("SetBT down for to hal_init !\n"); +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_SetManualControl(padapter, _FALSE); + rtw_btcoex_Initialize(padapter); +#endif + pHalFunc->read_adapter_info(padapter); + pHalFunc->hal_deinit(padapter); + pHalFunc->hal_init(padapter); + rtw_pm_set_ips(padapter, IPS_NONE); + LeaveAllPowerSaveMode(padapter); + MPT_PwrCtlDM(padapter, 0); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004)); + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF)); + rtw_msleep_os(600); + /*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/ + rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010)); + rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB)); + rtw_msleep_os(1200); + goto exit; + } + if (strncmp(extra, "disable", 7) == 0) { + DBG_871X("SetBT disable !\n"); + rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) & 0xFFFFFFFB)); + rtw_msleep_os(500); + goto exit; + } + if (strncmp(extra, "enable", 6) == 0) { + DBG_871X("SetBT enable !\n"); + rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) | 0x00000004)); + rtw_msleep_os(500); + goto exit; + } + if (strncmp(extra, "h2c", 3) == 0) { + DBG_871X("SetBT h2c !\n"); + padapter->bBTFWReady = _TRUE; + rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm); + goto exit; + } + if (strncmp(extra, "2ant", 4) == 0) { + DBG_871X("Set BT 2ant use!\n"); + PHY_SetMacReg(padapter, 0x67, BIT5, 0x1); + rtw_write32(padapter, 0x948, 0000); + + goto exit; + } + + if (ready != 0 && testmode != 0 && trxparam != 0 && setgen != 0 && getgen != 0 && testctrl != 0 && testbt != 0 && readtherm != 0 && setbtmac != 0) + return -EFAULT; + + if (testbt == 0) { + BtReq.opCodeVer = 1; + BtReq.OpCode = 6; + BtReq.paraLength = cnts / 2; + goto todo; + } + if (ready == 0) { + BtReq.opCodeVer = 1; + BtReq.OpCode = 0; + BtReq.paraLength = 0; + goto todo; + } + + pch = extra; + i = 0; + while ((token = strsep(&pch, ",")) != NULL) { + if (i > 1) + break; + tmp[i] = token; + i++; + } + + if ((tmp[0] != NULL) && (tmp[1] != NULL)) { + cnts = strlen(tmp[1]); + if (cnts < 1) + return -EFAULT; + + DBG_871X("%s: cnts=%d\n", __func__, cnts); + DBG_871X("%s: data=%s\n", __func__, tmp[1]); + + for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) { + BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]); + /* DBG_871X("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/ + } + } else + return -EFAULT; + + if (testmode == 0) { + BtReq.opCodeVer = 1; + BtReq.OpCode = 1; + BtReq.paraLength = 1; + } + if (trxparam == 0) { + BtReq.opCodeVer = 1; + BtReq.OpCode = 2; + BtReq.paraLength = cnts / 2; + } + if (setgen == 0) { + DBG_871X("%s: BT_SET_GENERAL\n", __func__); + BtReq.opCodeVer = 1; + BtReq.OpCode = 3;/*BT_SET_GENERAL 3*/ + BtReq.paraLength = cnts / 2; + } + if (getgen == 0) { + DBG_871X("%s: BT_GET_GENERAL\n", __func__); + BtReq.opCodeVer = 1; + BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/ + BtReq.paraLength = cnts / 2; + } + if (readtherm == 0) { + DBG_871X("%s: BT_GET_GENERAL\n", __func__); + BtReq.opCodeVer = 1; + BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/ + BtReq.paraLength = cnts / 2; + } + + if (testctrl == 0) { + DBG_871X("%s: BT_TEST_CTRL\n", __func__); + BtReq.opCodeVer = 1; + BtReq.OpCode = 5;/*BT_TEST_CTRL 5*/ + BtReq.paraLength = cnts / 2; + } + + DBG_871X("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n", + __func__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength); + + if (BtReq.paraLength < 1) + goto todo; + for (i = 0; i < BtReq.paraLength; i++) { + DBG_871X("%s: BtReq.pParamStart[%d] = 0x%02x\n", + __func__, i, BtReq.pParamStart[i]); + } + +todo: + _rtw_memset(extra, '\0', wrqu->data.length); + + if (padapter->bBTFWReady == _FALSE) { + sprintf(extra, "BTFWReady = FALSE.\n"); + goto exit; + } + + mptbt_BtControlProcess(padapter, &BtReq); + + if (readtherm == 0) { + sprintf(extra, "BT thermal="); + for (i = 4; i < pMptCtx->mptOutLen; i++) { + if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00)) + goto exit; + + sprintf(extra, "%s %d ", extra, (pMptCtx->mptOutBuf[i] & 0x1f)); + } + } else { + for (i = 4; i < pMptCtx->mptOutLen; i++) + sprintf(extra, "%s 0x%x ", extra, pMptCtx->mptOutBuf[i]); + } + +exit: + wrqu->data.length = strlen(extra) + 1; + DBG_871X("-%s: output len=%d data=%s\n", __func__, wrqu->data.length, extra); + + return status; +} + +#endif /*#ifdef CONFIG_RTL8723B*/ + +#endif diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/mlme_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/mlme_linux.c new file mode 100644 index 00000000..dd52afaf --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/mlme_linux.c @@ -0,0 +1,618 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + + +#define _MLME_OSDEP_C_ + +#include + + +#ifdef RTK_DMP_PLATFORM +void Linkup_workitem_callback(struct work_struct *work) +{ + struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem); + _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv); + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkup_workitem_callback\n")); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP); +#endif + +_func_exit_; +} + +void Linkdown_workitem_callback(struct work_struct *work) +{ + struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem); + _adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv); + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkdown_workitem_callback\n")); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) + kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN); +#else + kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN); +#endif + +_func_exit_; +} +#endif + + +/* +void sitesurvey_ctrl_handler(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + + _sitesurvey_ctrl_handler(adapter); + + _set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000); +} +*/ + +void rtw_join_timeout_handler (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + _rtw_join_timeout_handler(adapter); +} + + +void _rtw_scan_timeout_handler (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + rtw_scan_timeout_handler(adapter); +} + + +void _dynamic_check_timer_handlder (void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + +#if (MP_DRIVER == 1) + if (adapter->registrypriv.mp_mode == 1 && adapter->mppriv.mp_dm ==0) //for MP ODM dynamic Tx power tracking + { + //DBG_871X("_dynamic_check_timer_handlder mp_dm =0 return \n"); + _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); + return; + } +#endif + +#ifdef CONFIG_CONCURRENT_MODE + if(adapter->pbuddy_adapter) + rtw_dynamic_check_timer_handlder(adapter->pbuddy_adapter); +#endif //CONFIG_CONCURRENT_MODE + + rtw_dynamic_check_timer_handlder(adapter); + + _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); +} + +#ifdef CONFIG_SET_SCAN_DENY_TIMER +void _rtw_set_scan_deny_timer_hdl(void *FunctionContext) +{ + _adapter *adapter = (_adapter *)FunctionContext; + rtw_set_scan_deny_timer_hdl(adapter); +} +#endif + + +void rtw_init_mlme_timer(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter); + //_init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter); + _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter); + + #ifdef CONFIG_DFS_MASTER + _init_timer(&(pmlmepriv->dfs_master_timer), padapter->pnetdev, rtw_dfs_master_timer_hdl, padapter); + #endif + + _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter); + + #ifdef CONFIG_SET_SCAN_DENY_TIMER + _init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter); + #endif + +#ifdef RTK_DMP_PLATFORM + _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter); + _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter); +#endif + +} + +extern void rtw_indicate_wx_assoc_event(_adapter *padapter); +extern void rtw_indicate_wx_disassoc_event(_adapter *padapter); + +void rtw_os_indicate_connect(_adapter *adapter) +{ + struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); +_func_enter_; + +#ifdef CONFIG_IOCTL_CFG80211 + if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) || + (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) ) + { + rtw_cfg80211_ibss_indicate_connect(adapter); + } + else + rtw_cfg80211_indicate_connect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_wx_assoc_event(adapter); + netif_carrier_on(adapter->pnetdev); + + if(adapter->pid[2] !=0) + rtw_signal_process(adapter->pid[2], SIGALRM); + +#ifdef RTK_DMP_PLATFORM + _set_workitem(&adapter->mlmepriv.Linkup_workitem); +#endif + +_func_exit_; + +} + +extern void indicate_wx_scan_complete_event(_adapter *padapter); +void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted) +{ +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_indicate_scan_done(padapter, aborted); +#endif + indicate_wx_scan_complete_event(padapter); +} + +static RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ]; +void rtw_reset_securitypriv( _adapter *adapter ) +{ + u8 backupPMKIDIndex = 0; + u8 backupTKIPCountermeasure = 0x00; + u32 backupTKIPcountermeasure_time = 0; + // add for CONFIG_IEEE80211W, none 11w also can use + _irqL irqL; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + + _enter_critical_bh(&adapter->security_key_mutex, &irqL); + + if(adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)//802.1x + { + // Added by Albert 2009/02/18 + // We have to backup the PMK information for WiFi PMK Caching test item. + // + // Backup the btkip_countermeasure information. + // When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. + + _rtw_memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + + _rtw_memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + backupPMKIDIndex = adapter->securitypriv.PMKIDIndex; + backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure; + backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time; +#ifdef CONFIG_IEEE80211W + //reset RX BIP packet number + pmlmeext->mgnt_80211w_IPN_rx = 0; +#endif //CONFIG_IEEE80211W + _rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv)); + //_init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter); + + // Added by Albert 2009/02/18 + // Restore the PMK information to securitypriv structure for the following connection. + _rtw_memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE ); + adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; + adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure; + adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time; + + adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen; + adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + + } + else //reset values in securitypriv + { + //if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE) + //{ + struct security_priv *psec_priv=&adapter->securitypriv; + + psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open; //open system + psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + psec_priv->dot11PrivacyKeyIndex = 0; + + psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psec_priv->dot118021XGrpKeyid = 1; + + psec_priv->ndisauthtype = Ndis802_11AuthModeOpen; + psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; + //} + } + // add for CONFIG_IEEE80211W, none 11w also can use + _exit_critical_bh(&adapter->security_key_mutex, &irqL); + + DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(adapter)); +} + +void rtw_os_indicate_disconnect( _adapter *adapter ) +{ + //RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ]; + +_func_enter_; + + netif_carrier_off(adapter->pnetdev); // Do it first for tx broadcast pkt after disconnection issue! + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_indicate_disconnect(adapter); +#endif //CONFIG_IOCTL_CFG80211 + + rtw_indicate_wx_disassoc_event(adapter); + +#ifdef RTK_DMP_PLATFORM + _set_workitem(&adapter->mlmepriv.Linkdown_workitem); +#endif + //modify for CONFIG_IEEE80211W, none 11w also can use the same command + rtw_reset_securitypriv_cmd(adapter); + +_func_exit_; + +} + +void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie) +{ + uint len; + u8 *buff,*p,i; + union iwreq_data wrqu; + +_func_enter_; + + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode)); + + buff = NULL; + if(authmode==_WPA_IE_ID_) + { + RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode)); + + buff = rtw_zmalloc(IW_CUSTOM_MAX); + if (NULL == buff) { + DBG_871X(FUNC_ADPT_FMT ": alloc memory FAIL!!\n", + FUNC_ADPT_ARG(adapter)); + return; + } + p = buff; + + p+=sprintf(p,"ASSOCINFO(ReqIEs="); + + len = sec_ie[1]+2; + len = (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX; + + for(i=0;ipnetdev,IWEVCUSTOM,&wrqu,buff); +#endif + + rtw_mfree(buff, IW_CUSTOM_MAX); + } + +exit: + +_func_exit_; + +} + +void _survey_timer_hdl (void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + + survey_timer_hdl(padapter); +} + +void _link_timer_hdl (void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + link_timer_hdl(padapter); +} + +void _addba_timer_hdl(void *FunctionContext) +{ + struct sta_info *psta = (struct sta_info *)FunctionContext; + addba_timer_hdl(psta); +} + +#ifdef CONFIG_IEEE80211W + +void _sa_query_timer_hdl (void *FunctionContext) +{ + struct sta_info *psta = (struct sta_info *)FunctionContext; + + sa_query_timer_hdl(psta); +} + +void init_dot11w_expire_timer(_adapter *padapter, struct sta_info *psta) +{ + _init_timer(&psta->dot11w_expire_timer, padapter->pnetdev, _sa_query_timer_hdl, psta); +} + +#endif //CONFIG_IEEE80211W + +void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta) +{ + + _init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta); +} + +/* +void _reauth_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + reauth_timer_hdl(padapter); +} + +void _reassoc_timer_hdl(void *FunctionContext) +{ + _adapter *padapter = (_adapter *)FunctionContext; + reassoc_timer_hdl(padapter); +} +*/ + +void init_mlme_ext_timer(_adapter *padapter) +{ + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter); + _init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter); + + //_init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter); + + //_init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter); + //_init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter); +} + +#ifdef CONFIG_AP_MODE + +void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta) +{ + union iwreq_data wrqu; + struct sta_priv *pstapriv = &padapter->stapriv; + + if(psta==NULL) + return; + + if(psta->aid > NUM_STA) + return; + + if(pstapriv->sta_aid[psta->aid - 1] != psta) + return; + + + wrqu.addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); + + DBG_871X("+rtw_indicate_sta_assoc_event\n"); + +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL); +#endif + +} + +void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta) +{ + union iwreq_data wrqu; + struct sta_priv *pstapriv = &padapter->stapriv; + + if(psta==NULL) + return; + + if(psta->aid > NUM_STA) + return; + + if(pstapriv->sta_aid[psta->aid - 1] != psta) + return; + + + wrqu.addr.sa_family = ARPHRD_ETHER; + + _rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN); + + DBG_871X("+rtw_indicate_sta_disassoc_event\n"); + +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL); +#endif + +} + + +#ifdef CONFIG_HOSTAPD_MLME + +static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + _adapter *padapter = (_adapter *)phostapdpriv->padapter; + + //DBG_871X("%s\n", __FUNCTION__); + + return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb); +} + +static int mgnt_netdev_open(struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + + DBG_871X("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr)); + + + init_usb_anchor(&phostapdpriv->anchored); + + rtw_netif_wake_queue(pnetdev); + + netif_carrier_on(pnetdev); + + //rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100);//only excluding beacon + + return 0; +} +static int mgnt_netdev_close(struct net_device *pnetdev) +{ + struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev); + + DBG_871X("%s\n", __FUNCTION__); + + usb_kill_anchored_urbs(&phostapdpriv->anchored); + + netif_carrier_off(pnetdev); + + rtw_netif_stop_queue(pnetdev); + + //rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f); + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtl871x_mgnt_netdev_ops = { + .ndo_open = mgnt_netdev_open, + .ndo_stop = mgnt_netdev_close, + .ndo_start_xmit = mgnt_xmit_entry, + //.ndo_set_mac_address = r871x_net_set_mac_address, + //.ndo_get_stats = r871x_net_get_stats, + //.ndo_do_ioctl = r871x_mp_ioctl, +}; +#endif + +int hostapd_mode_init(_adapter *padapter) +{ + unsigned char mac[ETH_ALEN]; + struct hostapd_priv *phostapdpriv; + struct net_device *pnetdev; + + pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv)); + if (!pnetdev) + return -ENOMEM; + + //SET_MODULE_OWNER(pnetdev); + ether_setup(pnetdev); + + //pnetdev->type = ARPHRD_IEEE80211; + + phostapdpriv = rtw_netdev_priv(pnetdev); + phostapdpriv->pmgnt_netdev = pnetdev; + phostapdpriv->padapter= padapter; + padapter->phostapdpriv = phostapdpriv; + + //pnetdev->init = NULL; + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + + DBG_871X("register rtl871x_mgnt_netdev_ops to netdev_ops\n"); + + pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops; + +#else + + pnetdev->open = mgnt_netdev_open; + + pnetdev->stop = mgnt_netdev_close; + + pnetdev->hard_start_xmit = mgnt_xmit_entry; + + //pnetdev->set_mac_address = r871x_net_set_mac_address; + + //pnetdev->get_stats = r871x_net_get_stats; + + //pnetdev->do_ioctl = r871x_mp_ioctl; + +#endif + + pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ + + //pnetdev->wireless_handlers = NULL; + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + pnetdev->features |= NETIF_F_IP_CSUM; +#endif + + + + if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0) + { + DBG_871X("hostapd_mode_init(): dev_alloc_name, fail! \n"); + } + + + //SET_NETDEV_DEV(pnetdev, pintfpriv->udev); + + + mac[0]=0x00; + mac[1]=0xe0; + mac[2]=0x4c; + mac[3]=0x87; + mac[4]=0x11; + mac[5]=0x12; + + _rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN); + + + netif_carrier_off(pnetdev); + + + /* Tell the network stack we exist */ + if (register_netdev(pnetdev) != 0) + { + DBG_871X("hostapd_mode_init(): register_netdev fail!\n"); + + if(pnetdev) + { + rtw_free_netdev(pnetdev); + } + } + + return 0; + +} + +void hostapd_mode_unload(_adapter *padapter) +{ + struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; + struct net_device *pnetdev = phostapdpriv->pmgnt_netdev; + + unregister_netdev(pnetdev); + rtw_free_netdev(pnetdev); + +} + +#endif +#endif + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/os_intfs.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/os_intfs.c new file mode 100644 index 00000000..995b13f1 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/os_intfs.c @@ -0,0 +1,4535 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _OS_INTFS_C_ + +#include +#include + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); +MODULE_AUTHOR("Realtek Semiconductor Corp."); +MODULE_VERSION(DRIVERVERSION); + +/* module param defaults */ +int rtw_chip_version = 0x00; +int rtw_rfintfs = HWPI; +int rtw_lbkmode = 0;//RTL8712_AIR_TRX; + + +int rtw_network_mode = Ndis802_11IBSS;//Ndis802_11Infrastructure;//infra, ad-hoc, auto +//NDIS_802_11_SSID ssid; +int rtw_channel = 1;//ad-hoc support requirement +int rtw_wireless_mode = WIRELESS_MODE_MAX; +int rtw_vrtl_carrier_sense = AUTO_VCS; +int rtw_vcs_type = RTS_CTS;//* +int rtw_rts_thresh = 2347;//* +int rtw_frag_thresh = 2346;//* +int rtw_preamble = PREAMBLE_LONG;//long, short, auto +int rtw_scan_mode = 1;//active, passive +int rtw_adhoc_tx_pwr = 1; +int rtw_soft_ap = 0; +//int smart_ps = 1; +#ifdef CONFIG_POWER_SAVING +int rtw_power_mgnt = PS_MODE_MAX; +#ifdef CONFIG_IPS_LEVEL_2 +int rtw_ips_mode = IPS_LEVEL_2; +#else +int rtw_ips_mode = IPS_NORMAL; +#endif +#else +int rtw_power_mgnt = PS_MODE_ACTIVE; +int rtw_ips_mode = IPS_NONE; +#endif +module_param(rtw_ips_mode, int, 0644); +MODULE_PARM_DESC(rtw_ips_mode,"The default IPS mode"); + +int rtw_smart_ps = 2; + +int rtw_check_fw_ps = 1; + +#ifdef CONFIG_TX_EARLY_MODE +int rtw_early_mode=1; +#endif + +int rtw_usb_rxagg_mode = 2;//USB_RX_AGG_DMA =1,USB_RX_AGG_USB=2 +module_param(rtw_usb_rxagg_mode, int, 0644); + +int rtw_radio_enable = 1; +int rtw_long_retry_lmt = 7; +int rtw_short_retry_lmt = 7; +int rtw_busy_thresh = 40; +//int qos_enable = 0; //* +int rtw_ack_policy = NORMAL_ACK; + +int rtw_mp_mode = 0; + +int rtw_software_encrypt = 0; +int rtw_software_decrypt = 0; + +int rtw_acm_method = 0;// 0:By SW 1:By HW. + +int rtw_wmm_enable = 1;// default is set to enable the wmm. +int rtw_uapsd_enable = 0; +int rtw_uapsd_max_sp = NO_LIMIT; +int rtw_uapsd_acbk_en = 0; +int rtw_uapsd_acbe_en = 0; +int rtw_uapsd_acvi_en = 0; +int rtw_uapsd_acvo_en = 0; +#ifdef CONFIG_RTL8814A +int rtw_rfkfree_enable = 2; /* disable kfree */ +#else +int rtw_rfkfree_enable = 0; /* Default Enalbe kfree by efuse config */ +#endif +#ifdef CONFIG_80211N_HT +int rtw_ht_enable = 1; +// 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160MHz, 4: 80+80MHz +// 2.4G use bit 0 ~ 3, 5G use bit 4 ~ 7 +// 0x21 means enable 2.4G 40MHz & 5G 80MHz +int rtw_bw_mode = 0x21; +int rtw_ampdu_enable = 1;//for enable tx_ampdu ,// 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) +int rtw_rx_stbc = 1;// 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ +int rtw_ampdu_amsdu = 0;// 0: disabled, 1:enabled, 2:auto . There is an IOT issu with DLINK DIR-629 when the flag turn on +// Short GI support Bit Map +// BIT0 - 20MHz, 0: non-support, 1: support +// BIT1 - 40MHz, 0: non-support, 1: support +// BIT2 - 80MHz, 0: non-support, 1: support +// BIT3 - 160MHz, 0: non-support, 1: support +int rtw_short_gi = 0xf; +// BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx +int rtw_ldpc_cap = 0x00; +// BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx +int rtw_stbc_cap = 0x13; +// BIT0: Enable VHT Beamformer, BIT1: Enable VHT Beamformee, BIT4: Enable HT Beamformer, BIT5: Enable HT Beamformee +int rtw_beamform_cap = 0x2; +int rtw_bfer_rf_number = 0; /*BeamformerCapRfNum Rf path number, 0 for auto, others for manual*/ +int rtw_bfee_rf_number = 0; /*BeamformeeCapRfNum Rf path number, 0 for auto, others for manual*/ + +#endif //CONFIG_80211N_HT + +#ifdef CONFIG_80211AC_VHT +int rtw_vht_enable = 1; //0:disable, 1:enable, 2:force auto enable +int rtw_ampdu_factor = 7; +int rtw_vht_rate_sel = 0; +#endif //CONFIG_80211AC_VHT + +int rtw_lowrate_two_xmit = 1;//Use 2 path Tx to transmit MCS0~7 and legacy mode + +//int rf_config = RF_1T2R; // 1T2R +int rtw_rf_config = RF_MAX_TYPE; //auto + +int rtw_low_power = 0; +#ifdef CONFIG_WIFI_TEST +int rtw_wifi_spec = 1;//for wifi test +#else +int rtw_wifi_spec = 0; +#endif + +int rtw_special_rf_path = 0; //0: 2T2R ,1: only turn on path A 1T1R + +char rtw_country_unspecified[] = {0xFF, 0xFF, 0x00}; +char *rtw_country_code = rtw_country_unspecified; +module_param(rtw_country_code, charp, 0644); +MODULE_PARM_DESC(rtw_country_code, "The default country code (in alpha2)"); + +int rtw_channel_plan = RTW_CHPLAN_MAX; +module_param(rtw_channel_plan, int, 0644); +MODULE_PARM_DESC(rtw_channel_plan, "The default chplan ID when rtw_alpha2 is not specified or valid"); + +/*if concurrent softap + p2p(GO) is needed, this param lets p2p response full channel list. +But Softap must be SHUT DOWN once P2P decide to set up connection and become a GO.*/ +#ifdef CONFIG_FULL_CH_IN_P2P_HANDSHAKE +int rtw_full_ch_in_p2p_handshake = 1; /* reply full channel list*/ +#else +int rtw_full_ch_in_p2p_handshake = 0; /* reply only softap channel*/ +#endif + +#ifdef CONFIG_BT_COEXIST +int rtw_btcoex_enable = 1; +module_param(rtw_btcoex_enable, int, 0644); +MODULE_PARM_DESC(rtw_btcoex_enable, "Enable BT co-existence mechanism"); +int rtw_bt_iso = 2;// 0:Low, 1:High, 2:From Efuse +int rtw_bt_sco = 3;// 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy +int rtw_bt_ampdu =1 ;// 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. +int rtw_ant_num = -1; // <0: undefined, >0: Antenna number +module_param(rtw_ant_num, int, 0644); +MODULE_PARM_DESC(rtw_ant_num, "Antenna number setting"); +#endif + +int rtw_AcceptAddbaReq = _TRUE;// 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. + +int rtw_antdiv_cfg = 2; // 0:OFF , 1:ON, 2:decide by Efuse config +int rtw_antdiv_type = 0 ; //0:decide by efuse 1: for 88EE, 1Tx and 1RxCG are diversity.(2 Ant with SPDT), 2: for 88EE, 1Tx and 2Rx are diversity.( 2 Ant, Tx and RxCG are both on aux port, RxCS is on main port ), 3: for 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) + +int rtw_switch_usb3 = _FALSE; /* _FALSE: doesn't switch, _TRUE: switch from usb2.0 to usb 3.0 */ + +#ifdef CONFIG_USB_AUTOSUSPEND +int rtw_enusbss = 1;//0:disable,1:enable +#else +int rtw_enusbss = 0;//0:disable,1:enable +#endif + +int rtw_hwpdn_mode=2;//0:disable,1:enable,2: by EFUSE config + +#ifdef CONFIG_HW_PWRP_DETECTION +int rtw_hwpwrp_detect = 1; +#else +int rtw_hwpwrp_detect = 0; //HW power ping detect 0:disable , 1:enable +#endif + +#ifdef CONFIG_USB_HCI +int rtw_hw_wps_pbc = 1; +#else +int rtw_hw_wps_pbc = 0; +#endif + +#ifdef CONFIG_TX_MCAST2UNI +int rtw_mc2u_disable = 0; +#endif // CONFIG_TX_MCAST2UNI + +#ifdef CONFIG_80211D +int rtw_80211d = 0; +#endif + +#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV +int rtw_force_ant = 2;//0 :normal, 1:Main ant, 2:Aux ant +int rtw_force_igi =0;//0 :normal +module_param(rtw_force_ant, int, 0644); +module_param(rtw_force_igi, int, 0644); +#endif + +#ifdef CONFIG_QOS_OPTIMIZATION +int rtw_qos_opt_enable=1;//0: disable,1:enable +#else +int rtw_qos_opt_enable=0;//0: disable,1:enable +#endif +module_param(rtw_qos_opt_enable,int,0644); + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +int rtw_acs_mode = 1; /*0:disable, 1:enable*/ +module_param(rtw_acs_mode, int, 0644); + +int rtw_acs_auto_scan = 0; /*0:disable, 1:enable*/ +module_param(rtw_acs_auto_scan, int, 0644); + +#endif + +char* ifname = "wlan%d"; +module_param(ifname, charp, 0644); +MODULE_PARM_DESC(ifname, "The default name to allocate for first interface"); + +#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"); + +char* rtw_initmac = 0; // temp mac address if users want to use instead of the mac address in Efuse + +#ifdef CONFIG_MULTI_VIR_IFACES +int rtw_ext_iface_num = 1;//primary/secondary iface is excluded +module_param(rtw_ext_iface_num, int, 0644); +#endif //CONFIG_MULTI_VIR_IFACES + +module_param(rtw_rfkfree_enable, int, 0644); +module_param(rtw_initmac, charp, 0644); +module_param(rtw_special_rf_path, int, 0644); +module_param(rtw_chip_version, int, 0644); +module_param(rtw_rfintfs, int, 0644); +module_param(rtw_lbkmode, int, 0644); +module_param(rtw_network_mode, int, 0644); +module_param(rtw_channel, int, 0644); +module_param(rtw_mp_mode, int, 0644); +module_param(rtw_wmm_enable, int, 0644); +module_param(rtw_vrtl_carrier_sense, int, 0644); +module_param(rtw_vcs_type, int, 0644); +module_param(rtw_busy_thresh, int, 0644); + +#ifdef CONFIG_80211N_HT +module_param(rtw_ht_enable, int, 0644); +module_param(rtw_bw_mode, int, 0644); +module_param(rtw_ampdu_enable, int, 0644); +module_param(rtw_rx_stbc, int, 0644); +module_param(rtw_ampdu_amsdu, int, 0644); +#endif //CONFIG_80211N_HT +#ifdef CONFIG_80211AC_VHT +module_param(rtw_vht_enable, int, 0644); +#endif //CONFIG_80211AC_VHT +#ifdef CONFIG_BEAMFORMING +module_param(rtw_beamform_cap, int, 0644); +#endif +module_param(rtw_lowrate_two_xmit, int, 0644); + +module_param(rtw_rf_config, int, 0644); +module_param(rtw_power_mgnt, int, 0644); +module_param(rtw_smart_ps, int, 0644); +module_param(rtw_low_power, int, 0644); +module_param(rtw_wifi_spec, int, 0644); + +module_param(rtw_full_ch_in_p2p_handshake, int, 0644); +module_param(rtw_antdiv_cfg, int, 0644); +module_param(rtw_antdiv_type, int, 0644); + +module_param(rtw_switch_usb3, int, 0644); + +module_param(rtw_enusbss, int, 0644); +module_param(rtw_hwpdn_mode, int, 0644); +module_param(rtw_hwpwrp_detect, int, 0644); + +module_param(rtw_hw_wps_pbc, int, 0644); + +#ifdef CONFIG_TX_EARLY_MODE +module_param(rtw_early_mode, int, 0644); +#endif +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE +char *rtw_adaptor_info_caching_file_path= "/data/misc/wifi/rtw_cache"; +module_param(rtw_adaptor_info_caching_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_adaptor_info_caching_file_path, "The path of adapter info cache file"); +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE + +#ifdef CONFIG_LAYER2_ROAMING +uint rtw_max_roaming_times=2; +module_param(rtw_max_roaming_times, uint, 0644); +MODULE_PARM_DESC(rtw_max_roaming_times,"The max roaming times to try"); +#endif //CONFIG_LAYER2_ROAMING + +#ifdef CONFIG_IOL +int rtw_fw_iol=1; +module_param(rtw_fw_iol, int, 0644); +MODULE_PARM_DESC(rtw_fw_iol, "FW IOL. 0:Disable, 1:enable, 2:by usb speed"); +#endif //CONFIG_IOL + +#ifdef CONFIG_FILE_FWIMG +char *rtw_fw_file_path = "/system/etc/firmware/rtlwifi/FW_NIC.BIN"; +module_param(rtw_fw_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_fw_file_path, "The path of fw image"); + +char *rtw_fw_wow_file_path = "/system/etc/firmware/rtlwifi/FW_WoWLAN.BIN"; +module_param(rtw_fw_wow_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_fw_wow_file_path, "The path of fw for Wake on Wireless image"); + +#ifdef CONFIG_MP_INCLUDED +char *rtw_fw_mp_bt_file_path = ""; +module_param(rtw_fw_mp_bt_file_path, charp, 0644); +MODULE_PARM_DESC(rtw_fw_mp_bt_file_path, "The path of fw for MP-BT image"); +#endif // CONFIG_MP_INCLUDED +#endif // CONFIG_FILE_FWIMG + +#ifdef CONFIG_TX_MCAST2UNI +module_param(rtw_mc2u_disable, int, 0644); +#endif // CONFIG_TX_MCAST2UNI + +#ifdef CONFIG_80211D +module_param(rtw_80211d, int, 0644); +MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism"); +#endif + +uint rtw_notch_filter = RTW_NOTCH_FILTER; +module_param(rtw_notch_filter, uint, 0644); +MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P"); + +uint rtw_hiq_filter = CONFIG_RTW_HIQ_FILTER; +module_param(rtw_hiq_filter, uint, 0644); +MODULE_PARM_DESC(rtw_hiq_filter, "0:allow all, 1:allow special, 2:deny all"); + +uint rtw_adaptivity_en = CONFIG_RTW_ADAPTIVITY_EN; +module_param(rtw_adaptivity_en, uint, 0644); +MODULE_PARM_DESC(rtw_adaptivity_en, "0:disable, 1:enable"); + +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_adaptivity_dml = CONFIG_RTW_ADAPTIVITY_DML; +module_param(rtw_adaptivity_dml, uint, 0644); +MODULE_PARM_DESC(rtw_adaptivity_dml, "0:disable, 1:enable"); + +uint rtw_adaptivity_dc_backoff = CONFIG_RTW_ADAPTIVITY_DC_BACKOFF; +module_param(rtw_adaptivity_dc_backoff, uint, 0644); +MODULE_PARM_DESC(rtw_adaptivity_dc_backoff, "DC backoff for Adaptivity"); + +int rtw_adaptivity_th_l2h_ini = CONFIG_RTW_ADAPTIVITY_TH_L2H_INI; +module_param(rtw_adaptivity_th_l2h_ini, int, 0644); +MODULE_PARM_DESC(rtw_adaptivity_th_l2h_ini, "TH_L2H_ini for Adaptivity"); + +int rtw_adaptivity_th_edcca_hl_diff = CONFIG_RTW_ADAPTIVITY_TH_EDCCA_HL_DIFF; +module_param(rtw_adaptivity_th_edcca_hl_diff, int, 0644); +MODULE_PARM_DESC(rtw_adaptivity_th_edcca_hl_diff, "TH_EDCCA_HL_diff for Adaptivity"); + +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 = CONFIG_RTW_RFE_TYPE; +module_param(rtw_RFE_type, uint, 0644); +MODULE_PARM_DESC(rtw_RFE_type, "default init value:64"); + +uint rtw_GLNA_type = CONFIG_RTW_GLNA_TYPE; +module_param(rtw_GLNA_type, uint, 0644); +MODULE_PARM_DESC(rtw_GLNA_type, "default init value:0"); + +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"); + +uint rtw_OffEfuseMask = 0; +module_param(rtw_OffEfuseMask, uint, 0644); +MODULE_PARM_DESC(rtw_OffEfuseMask, "default open Efuse Mask value:0"); + +uint rtw_FileMaskEfuse = 0; +module_param(rtw_FileMaskEfuse, uint, 0644); +MODULE_PARM_DESC(rtw_FileMaskEfuse, "default drv Mask Efuse value:0"); + +uint rtw_kfree = 0; +module_param(rtw_kfree, uint, 0644); +MODULE_PARM_DESC(rtw_kfree, "default kfree config value:0"); + +uint rtw_rxgain_offset_2g = 0; +module_param(rtw_rxgain_offset_2g, uint, 0644); +MODULE_PARM_DESC(rtw_rxgain_offset_2g, "default RF Gain 2G Offset value:0"); + +uint rtw_rxgain_offset_5gl = 0; +module_param(rtw_rxgain_offset_5gl, uint, 0644); +MODULE_PARM_DESC(rtw_rxgain_offset_5gl, "default RF Gain 5GL Offset value:0"); + +uint rtw_rxgain_offset_5gm = 0; +module_param(rtw_rxgain_offset_5gm, uint, 0644); +MODULE_PARM_DESC(rtw_rxgain_offset_5gm, "default RF Gain 5GM Offset value:0"); + +uint rtw_rxgain_offset_5gh = 0; +module_param(rtw_rxgain_offset_5gh, uint, 0644); +MODULE_PARM_DESC(rtw_rxgain_offset_5gm, "default RF Gain 5GL Offset value:0"); + + +uint rtw_pll_ref_clk_sel = CONFIG_RTW_PLL_REF_CLK_SEL; +module_param(rtw_pll_ref_clk_sel, uint, 0644); +MODULE_PARM_DESC(rtw_pll_ref_clk_sel, "force pll_ref_clk_sel, 0xF:use autoload value"); + +#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; +#elif defined(CONFIG_CALIBRATE_TX_POWER_TO_MAX)//eFuse: Regulatory selection=0 +int rtw_tx_pwr_lmt_enable = 0; +int rtw_tx_pwr_by_rate = 1; +#else //eFuse: Regulatory selection=2 +#ifdef CONFIG_PCI_HCI +int rtw_tx_pwr_lmt_enable = 2; // 2- Depend on efuse +int rtw_tx_pwr_by_rate = 2;// 2- Depend on efuse +#else // USB & SDIO +int rtw_tx_pwr_lmt_enable = 0; +int rtw_tx_pwr_by_rate = 0; +#endif +#endif + +module_param(rtw_tx_pwr_lmt_enable, int, 0644); +MODULE_PARM_DESC(rtw_tx_pwr_lmt_enable,"0:Disable, 1:Enable, 2: Depend on efuse"); + +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"); + +static int rtw_target_tx_pwr_2g_a[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_A; +static int rtw_target_tx_pwr_2g_a_num = 0; +module_param_array(rtw_target_tx_pwr_2g_a, int, &rtw_target_tx_pwr_2g_a_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_2g_a, "2.4G target tx power (unit:dBm) of RF path A for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_2g_b[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_B; +static int rtw_target_tx_pwr_2g_b_num = 0; +module_param_array(rtw_target_tx_pwr_2g_b, int, &rtw_target_tx_pwr_2g_b_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_2g_b, "2.4G target tx power (unit:dBm) of RF path B for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_2g_c[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_C; +static int rtw_target_tx_pwr_2g_c_num = 0; +module_param_array(rtw_target_tx_pwr_2g_c, int, &rtw_target_tx_pwr_2g_c_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_2g_c, "2.4G target tx power (unit:dBm) of RF path C for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_2g_d[RATE_SECTION_NUM] = CONFIG_RTW_TARGET_TX_PWR_2G_D; +static int rtw_target_tx_pwr_2g_d_num = 0; +module_param_array(rtw_target_tx_pwr_2g_d, int, &rtw_target_tx_pwr_2g_d_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_2g_d, "2.4G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined"); + +#ifdef CONFIG_IEEE80211_BAND_5GHZ +static int rtw_target_tx_pwr_5g_a[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_A; +static int rtw_target_tx_pwr_5g_a_num = 0; +module_param_array(rtw_target_tx_pwr_5g_a, int, &rtw_target_tx_pwr_5g_a_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_5g_a, "5G target tx power (unit:dBm) of RF path A for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_5g_b[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_B; +static int rtw_target_tx_pwr_5g_b_num = 0; +module_param_array(rtw_target_tx_pwr_5g_b, int, &rtw_target_tx_pwr_5g_b_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_5g_b, "5G target tx power (unit:dBm) of RF path B for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_5g_c[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_C; +static int rtw_target_tx_pwr_5g_c_num = 0; +module_param_array(rtw_target_tx_pwr_5g_c, int, &rtw_target_tx_pwr_5g_c_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_5g_c, "5G target tx power (unit:dBm) of RF path C for each rate section, should match the real calibrate power, -1: undefined"); + +static int rtw_target_tx_pwr_5g_d[RATE_SECTION_NUM - 1] = CONFIG_RTW_TARGET_TX_PWR_5G_D; +static int rtw_target_tx_pwr_5g_d_num = 0; +module_param_array(rtw_target_tx_pwr_5g_d, int, &rtw_target_tx_pwr_5g_d_num, 0644); +MODULE_PARM_DESC(rtw_target_tx_pwr_5g_d, "5G target tx power (unit:dBm) of RF path D for each rate section, should match the real calibrate power, -1: undefined"); +#endif /* CONFIG_IEEE80211_BAND_5GHZ */ + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +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 +// BIT0 - MAC, 0: non-support, 1: support +// BIT1 - BB, 0: non-support, 1: support +// BIT2 - BB_PG, 0: non-support, 1: support +// BIT3 - BB_MP, 0: non-support, 1: support +// BIT4 - RF, 0: non-support, 1: support +// BIT5 - RF_TXPWR_TRACK, 0: non-support, 1: support +// BIT6 - RF_TXPWR_LMT, 0: non-support, 1: support +int rtw_load_phy_file = (BIT2|BIT6); +module_param(rtw_load_phy_file, int, 0644); +MODULE_PARM_DESC(rtw_load_phy_file,"PHY File Bit Map"); +int rtw_decrypt_phy_file = 0; +module_param(rtw_decrypt_phy_file, int, 0644); +MODULE_PARM_DESC(rtw_decrypt_phy_file,"Enable Decrypt PHY File"); +#endif + +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 + +void rtw_regsty_load_target_tx_power(struct registry_priv *regsty) +{ + int path, rs; + int *target_tx_pwr; + + for (path = RF_PATH_A; path < RF_PATH_MAX; path++) { + if (path == RF_PATH_A) + target_tx_pwr = rtw_target_tx_pwr_2g_a; + else if (path == RF_PATH_B) + target_tx_pwr = rtw_target_tx_pwr_2g_b; + else if (path == RF_PATH_C) + target_tx_pwr = rtw_target_tx_pwr_2g_c; + else if (path == RF_PATH_D) + target_tx_pwr = rtw_target_tx_pwr_2g_d; + + for (rs = CCK; rs < RATE_SECTION_NUM; rs++) + regsty->target_tx_pwr_2g[path][rs] = target_tx_pwr[rs]; + } + +#ifdef CONFIG_IEEE80211_BAND_5GHZ + for (path = RF_PATH_A; path < RF_PATH_MAX; path++) { + if (path == RF_PATH_A) + target_tx_pwr = rtw_target_tx_pwr_5g_a; + else if (path == RF_PATH_B) + target_tx_pwr = rtw_target_tx_pwr_5g_b; + else if (path == RF_PATH_C) + target_tx_pwr = rtw_target_tx_pwr_5g_c; + else if (path == RF_PATH_D) + target_tx_pwr = rtw_target_tx_pwr_5g_d; + + for (rs = OFDM; rs < RATE_SECTION_NUM; rs++) + regsty->target_tx_pwr_5g[path][rs - 1] = target_tx_pwr[rs - 1]; + } +#endif /* CONFIG_IEEE80211_BAND_5GHZ */ +} + +uint loadparam(_adapter *padapter) +{ + uint status = _SUCCESS; + struct registry_priv *registry_par = &padapter->registrypriv; + +_func_enter_; + + registry_par->chip_version = (u8)rtw_chip_version; + registry_par->rfintfs = (u8)rtw_rfintfs; + registry_par->lbkmode = (u8)rtw_lbkmode; + //registry_par->hci = (u8)hci; + registry_par->network_mode = (u8)rtw_network_mode; + + _rtw_memcpy(registry_par->ssid.Ssid, "ANY", 3); + registry_par->ssid.SsidLength = 3; + + registry_par->channel = (u8)rtw_channel; + registry_par->wireless_mode = (u8)rtw_wireless_mode; + + if (IsSupported24G(registry_par->wireless_mode) && (!IsSupported5G(registry_par->wireless_mode)) + && (registry_par->channel > 14)) { + registry_par->channel = 1; + } + else if (IsSupported5G(registry_par->wireless_mode) && (!IsSupported24G(registry_par->wireless_mode)) + && (registry_par->channel <= 14)) { + registry_par->channel = 36; + } + + registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense ; + registry_par->vcs_type = (u8)rtw_vcs_type; + registry_par->rts_thresh=(u16)rtw_rts_thresh; + registry_par->frag_thresh=(u16)rtw_frag_thresh; + registry_par->preamble = (u8)rtw_preamble; + registry_par->scan_mode = (u8)rtw_scan_mode; + registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr; + registry_par->soft_ap= (u8)rtw_soft_ap; + registry_par->smart_ps = (u8)rtw_smart_ps; + registry_par->check_fw_ps = (u8)rtw_check_fw_ps; + registry_par->power_mgnt = (u8)rtw_power_mgnt; + registry_par->ips_mode = (u8)rtw_ips_mode; + registry_par->radio_enable = (u8)rtw_radio_enable; + registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt; + registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt; + registry_par->busy_thresh = (u16)rtw_busy_thresh; + //registry_par->qos_enable = (u8)rtw_qos_enable; + registry_par->ack_policy = (u8)rtw_ack_policy; + registry_par->mp_mode = (u8)rtw_mp_mode; + registry_par->software_encrypt = (u8)rtw_software_encrypt; + registry_par->software_decrypt = (u8)rtw_software_decrypt; + + registry_par->acm_method = (u8)rtw_acm_method; + registry_par->usb_rxagg_mode = (u8)rtw_usb_rxagg_mode; + + //UAPSD + registry_par->wmm_enable = (u8)rtw_wmm_enable; + registry_par->uapsd_enable = (u8)rtw_uapsd_enable; + registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp; + registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en; + registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en; + registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en; + registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en; + + registry_par->RegRfKFreeEnable = (u8)rtw_rfkfree_enable; + +#ifdef CONFIG_80211N_HT + registry_par->ht_enable = (u8)rtw_ht_enable; + registry_par->bw_mode = (u8)rtw_bw_mode; + registry_par->ampdu_enable = (u8)rtw_ampdu_enable; + registry_par->rx_stbc = (u8)rtw_rx_stbc; + registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu; + registry_par->short_gi = (u8)rtw_short_gi; + registry_par->ldpc_cap = (u8)rtw_ldpc_cap; + registry_par->stbc_cap = (u8)rtw_stbc_cap; + registry_par->beamform_cap = (u8)rtw_beamform_cap; + registry_par->beamformer_rf_num = (u8)rtw_bfer_rf_number; + registry_par->beamformee_rf_num = (u8)rtw_bfee_rf_number; +#endif + +#ifdef CONFIG_80211AC_VHT + registry_par->vht_enable = (u8)rtw_vht_enable; + registry_par->ampdu_factor = (u8)rtw_ampdu_factor; + registry_par->vht_rate_sel = (u8)rtw_vht_rate_sel; +#endif + +#ifdef CONFIG_TX_EARLY_MODE + registry_par->early_mode = (u8)rtw_early_mode; +#endif + registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit; + registry_par->rf_config = (u8)rtw_rf_config; + registry_par->low_power = (u8)rtw_low_power; + + + registry_par->wifi_spec = (u8)rtw_wifi_spec; + + if (strlen(rtw_country_code) != 2 + || is_alpha(rtw_country_code[0]) == _FALSE + || is_alpha(rtw_country_code[1]) == _FALSE + ) { + if (rtw_country_code != rtw_country_unspecified) + DBG_871X_LEVEL(_drv_err_, "%s discard rtw_country_code not in alpha2\n", __func__); + _rtw_memset(registry_par->alpha2, 0xFF, 2); + } else + _rtw_memcpy(registry_par->alpha2, rtw_country_code, 2); + + registry_par->channel_plan = (u8)rtw_channel_plan; + registry_par->special_rf_path = (u8)rtw_special_rf_path; + + registry_par->full_ch_in_p2p_handshake = (u8)rtw_full_ch_in_p2p_handshake; +#ifdef CONFIG_BT_COEXIST + registry_par->btcoex = (u8)rtw_btcoex_enable; + registry_par->bt_iso = (u8)rtw_bt_iso; + registry_par->bt_sco = (u8)rtw_bt_sco; + registry_par->bt_ampdu = (u8)rtw_bt_ampdu; + registry_par->ant_num = (s8)rtw_ant_num; +#endif + + registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq; + + registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg; + registry_par->antdiv_type = (u8)rtw_antdiv_type; + + registry_par->switch_usb3 = (u8)rtw_switch_usb3; + +#ifdef CONFIG_AUTOSUSPEND + registry_par->usbss_enable = (u8)rtw_enusbss;//0:disable,1:enable +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED + registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;//0:disable,1:enable,2:by EFUSE config + registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;//0:disable,1:enable +#endif + + registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc; + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + snprintf(registry_par->adaptor_info_caching_file_path, PATH_LENGTH_MAX, "%s", rtw_adaptor_info_caching_file_path); + registry_par->adaptor_info_caching_file_path[PATH_LENGTH_MAX-1]=0; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + registry_par->max_roaming_times = (u8)rtw_max_roaming_times; +#ifdef CONFIG_INTEL_WIDI + registry_par->max_roaming_times = (u8)rtw_max_roaming_times + 2; +#endif // CONFIG_INTEL_WIDI +#endif + +#ifdef CONFIG_IOL + registry_par->fw_iol = rtw_fw_iol; +#endif + +#ifdef CONFIG_80211D + registry_par->enable80211d = (u8)rtw_80211d; +#endif + + snprintf(registry_par->ifname, 16, "%s", ifname); + snprintf(registry_par->if2name, 16, "%s", if2name); + + registry_par->notch_filter = (u8)rtw_notch_filter; + +#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + registry_par->force_ant = (u8)rtw_force_ant; + registry_par->force_igi = (u8)rtw_force_igi; +#endif + +#ifdef CONFIG_MULTI_VIR_IFACES + registry_par->ext_iface_num = (u8)rtw_ext_iface_num; +#endif //CONFIG_MULTI_VIR_IFACES + + registry_par->pll_ref_clk_sel = (u8)rtw_pll_ref_clk_sel; + + registry_par->RegEnableTxPowerLimit = (u8)rtw_tx_pwr_lmt_enable; + registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate; + + rtw_regsty_load_target_tx_power(registry_par); + + registry_par->RegPowerBase = 14; + 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 = (u8)rtw_RFE_type; + registry_par->AmplifierType_2G = (u8)rtw_amplifier_type_2g; + registry_par->AmplifierType_5G = (u8)rtw_amplifier_type_5g; + registry_par->GLNA_Type = (u8)rtw_GLNA_type; +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE + registry_par->load_phy_file = (u8)rtw_load_phy_file; + registry_par->RegDecryptCustomFile = (u8)rtw_decrypt_phy_file; +#endif + 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->adaptivity_dml = (u8)rtw_adaptivity_dml; + registry_par->adaptivity_dc_backoff = (u8)rtw_adaptivity_dc_backoff; + registry_par->adaptivity_th_l2h_ini = (s8)rtw_adaptivity_th_l2h_ini; + registry_par->adaptivity_th_edcca_hl_diff = (s8)rtw_adaptivity_th_edcca_hl_diff; + + registry_par->boffefusemask = (u8)rtw_OffEfuseMask; + registry_par->bFileMaskEfuse = (u8)rtw_FileMaskEfuse; +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + registry_par->acs_mode = (u8)rtw_acs_mode; + registry_par->acs_auto_scan = (u8)rtw_acs_auto_scan; +#endif + registry_par->reg_rxgain_offset_2g = (u32) rtw_rxgain_offset_2g; + registry_par->reg_rxgain_offset_5gl = (u32) rtw_rxgain_offset_5gl; + registry_par->reg_rxgain_offset_5gm = (u32) rtw_rxgain_offset_5gm; + registry_par->reg_rxgain_offset_5gh = (u32) rtw_rxgain_offset_5gh; +_func_exit_; + + return status; +} + +/** + * rtw_net_set_mac_address + * This callback function is used for the Media Access Control address + * of each net_device needs to be changed. + * + * Arguments: + * @pnetdev: net_device pointer. + * @addr: new MAC address. + * + * Return: + * ret = 0: Permit to change net_device's MAC address. + * ret = -1 (Default): Operation not permitted. + * + * Auther: Arvin Liu + * Date: 2015/05/29 + */ +static int rtw_net_set_mac_address(struct net_device *pnetdev, void *addr) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sockaddr *sa = (struct sockaddr *)addr; + int ret = -1; + + /* only the net_device is in down state to permit modifying mac addr */ + if ((pnetdev->flags & IFF_UP) == _TRUE) { + DBG_871X(FUNC_ADPT_FMT": The net_device's is not in down state\n" + , FUNC_ADPT_ARG(padapter)); + + return ret; + } + + /* if the net_device is linked, it's not permit to modify mac addr */ + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) || + check_fwstate(pmlmepriv, _FW_LINKED) || + check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + DBG_871X(FUNC_ADPT_FMT": The net_device's is not idle currently\n" + , FUNC_ADPT_ARG(padapter)); + + return ret; + } + + /* check whether the input mac address is valid to permit modifying mac addr */ + if (rtw_check_invalid_mac_address(sa->sa_data, _FALSE) == _TRUE) { + DBG_871X(FUNC_ADPT_FMT": Invalid Mac Addr for "MAC_FMT"\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(sa->sa_data)); + + return ret; + } + + _rtw_memcpy(adapter_mac_addr(padapter), sa->sa_data, ETH_ALEN); /* set mac addr to adapter */ + _rtw_memcpy(pnetdev->dev_addr, sa->sa_data, ETH_ALEN); /* set mac addr to net_device */ + + rtw_ps_deny(padapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(padapter); /* leave PS mode for guaranteeing to access hw register successfully */ + rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, sa->sa_data); /* set mac addr to mac register */ + rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL); + + DBG_871X(FUNC_ADPT_FMT": Set Mac Addr to "MAC_FMT" Successfully\n" + , FUNC_ADPT_ARG(padapter), MAC_ARG(sa->sa_data)); + + ret = 0; + + return ret; +} + +static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct recv_priv *precvpriv = &(padapter->recvpriv); + + padapter->stats.tx_packets = pxmitpriv->tx_pkts;//pxmitpriv->tx_pkts++; + padapter->stats.rx_packets = precvpriv->rx_pkts;//precvpriv->rx_pkts++; + padapter->stats.tx_dropped = pxmitpriv->tx_drop; + padapter->stats.rx_dropped = precvpriv->rx_drop; + padapter->stats.tx_bytes = pxmitpriv->tx_bytes; + padapter->stats.rx_bytes = precvpriv->rx_bytes; + + return &padapter->stats; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) +/* + * AC to queue mapping + * + * AC_VO -> queue 0 + * AC_VI -> queue 1 + * AC_BE -> queue 2 + * AC_BK -> queue 3 + */ +static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; + +/* Given a data frame determine the 802.1p/1d tag to use. */ +unsigned int rtw_classify8021d(struct sk_buff *skb) +{ + unsigned int dscp; + + /* skb->priority values from 256->263 are magic values to + * directly indicate a specific 802.1d priority. This is used + * to allow 802.1d priority to be passed directly in from VLAN + * tags, etc. + */ + if (skb->priority >= 256 && skb->priority <= 263) + return skb->priority - 256; + + switch (skb->protocol) { + case htons(ETH_P_IP): + dscp = ip_hdr(skb)->tos & 0xfc; + break; + default: + return 0; + } + + 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 +#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; + + skb->priority = rtw_classify8021d(skb); + + if(pmlmepriv->acm_mask != 0) + { + skb->priority = qos_acm(pmlmepriv->acm_mask, skb->priority); + } + + return rtw_1d_to_queue[skb->priority]; +} + +u16 rtw_recv_select_queue(struct sk_buff *skb) +{ + struct iphdr *piphdr; + unsigned int dscp; + u16 eth_type; + u32 priority; + u8 *pdata = skb->data; + + _rtw_memcpy(ð_type, pdata+(ETH_ALEN<<1), 2); + + switch (eth_type) { + case htons(ETH_P_IP): + + piphdr = (struct iphdr *)(pdata+ETH_HLEN); + + dscp = piphdr->tos & 0xfc; + + priority = dscp >> 5; + + break; + default: + priority = 0; + } + + return rtw_1d_to_queue[priority]; + +} + +#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 + struct net_device *dev = ptr; +#endif + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) + if (dev->netdev_ops->ndo_do_ioctl == NULL) + return NOTIFY_DONE; + + if (dev->netdev_ops->ndo_do_ioctl != rtw_ioctl) +#else + if (dev->do_ioctl == NULL) + return NOTIFY_DONE; + + if (dev->do_ioctl != rtw_ioctl) +#endif + return NOTIFY_DONE; + + DBG_871X_LEVEL(_drv_info_, FUNC_NDEV_FMT" state:%lu\n", FUNC_NDEV_ARG(dev), state); + + switch (state) { + case NETDEV_CHANGENAME: + rtw_adapter_proc_replace(dev); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block rtw_ndev_notifier = { + .notifier_call = rtw_ndev_notifier_call, +}; + +int rtw_ndev_notifier_register(void) +{ + return register_netdevice_notifier(&rtw_ndev_notifier); +} + +void rtw_ndev_notifier_unregister(void) +{ + unregister_netdevice_notifier(&rtw_ndev_notifier); +} + + +int rtw_ndev_init(struct net_device *dev) +{ + _adapter *adapter = rtw_netdev_priv(dev); + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" if%d mac_addr="MAC_FMT"\n" + , FUNC_ADPT_ARG(adapter), (adapter->iface_id+1), MAC_ARG(dev->dev_addr)); + strncpy(adapter->old_ifname, dev->name, IFNAMSIZ); + adapter->old_ifname[IFNAMSIZ-1] = '\0'; + rtw_adapter_proc_init(dev); + + return 0; +} + +void rtw_ndev_uninit(struct net_device *dev) +{ + _adapter *adapter = rtw_netdev_priv(dev); + + DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" if%d\n" + , FUNC_ADPT_ARG(adapter), (adapter->iface_id+1)); + rtw_adapter_proc_deinit(dev); +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_ops = { + .ndo_init = rtw_ndev_init, + .ndo_uninit = rtw_ndev_uninit, + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = rtw_xmit_entry, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +}; +#endif + +int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname) +{ + _adapter *padapter = rtw_netdev_priv(pnetdev); + +#ifdef CONFIG_EASY_REPLACEMENT + struct net_device *TargetNetdev = NULL; + _adapter *TargetAdapter = NULL; + struct net *devnet = NULL; + + if(padapter->bDongle == 1) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + TargetNetdev = dev_get_by_name("wlan0"); +#else + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = pnetdev->nd_net; + #else + devnet = dev_net(pnetdev); + #endif + TargetNetdev = dev_get_by_name(devnet, "wlan0"); +#endif + if(TargetNetdev) { + DBG_871X("Force onboard module driver disappear !!!\n"); + TargetAdapter = rtw_netdev_priv(TargetNetdev); + TargetAdapter->DriverState = DRIVER_DISAPPEAR; + + padapter->pid[0] = TargetAdapter->pid[0]; + padapter->pid[1] = TargetAdapter->pid[1]; + padapter->pid[2] = TargetAdapter->pid[2]; + + dev_put(TargetNetdev); + unregister_netdev(TargetNetdev); + + padapter->DriverState = DRIVER_REPLACE_DONGLE; + } + } +#endif //CONFIG_EASY_REPLACEMENT + + if(dev_alloc_name(pnetdev, ifname) < 0) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("dev_alloc_name, fail! \n")); + } + + netif_carrier_off(pnetdev); + //rtw_netif_stop_queue(pnetdev); + + return 0; +} + +void rtw_hook_if_ops(struct net_device *ndev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) + ndev->netdev_ops = &rtw_netdev_ops; +#else + ndev->init = rtw_ndev_init; + ndev->uninit = rtw_ndev_uninit; + ndev->open = netdev_open; + ndev->stop = netdev_close; + ndev->hard_start_xmit = rtw_xmit_entry; + ndev->set_mac_address = rtw_net_set_mac_address; + ndev->get_stats = rtw_net_get_stats; + ndev->do_ioctl = rtw_ioctl; +#endif +} + +struct net_device *rtw_init_netdev(_adapter *old_padapter) +{ + _adapter *padapter; + struct net_device *pnetdev; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+init_net_dev\n")); + + if(old_padapter != NULL) + pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(_adapter), (void *)old_padapter); + else + pnetdev = rtw_alloc_etherdev(sizeof(_adapter)); + + if (!pnetdev) + return NULL; + + padapter = rtw_netdev_priv(pnetdev); + padapter->pnetdev = pnetdev; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + SET_MODULE_OWNER(pnetdev); +#endif + + rtw_hook_if_ops(pnetdev); + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + pnetdev->features |= NETIF_F_IP_CSUM; +#endif + + //pnetdev->tx_timeout = NULL; + pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */ + +#ifdef CONFIG_WIRELESS_EXT + pnetdev->wireless_handlers = (struct iw_handler_def *)&rtw_handlers_def; +#endif + +#ifdef WIRELESS_SPY + //priv->wireless_data.spy_data = &priv->spy_data; + //pnetdev->wireless_data = &priv->wireless_data; +#endif + + return pnetdev; +} + +int rtw_os_ndev_alloc(_adapter *adapter) +{ + int ret = _FAIL; + struct net_device *ndev = NULL; + + ndev = rtw_init_netdev(adapter); + if (ndev == NULL) { + rtw_warn_on(1); + goto exit; + } + #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) + SET_NETDEV_DEV(ndev, dvobj_to_dev(adapter_to_dvobj(adapter))); + #endif + + #ifdef CONFIG_PCI_HCI + if (adapter_to_dvobj(adapter)->bdma64) + ndev->features |= NETIF_F_HIGHDMA; + ndev->irq = adapter_to_dvobj(adapter)->irq; + #endif + +#if defined(CONFIG_IOCTL_CFG80211) + if (rtw_cfg80211_ndev_res_alloc(adapter) != _SUCCESS) { + rtw_warn_on(1); + goto free_ndev; + } +#endif + + ret = _SUCCESS; + +free_ndev: + if (ret != _SUCCESS && ndev) + rtw_free_netdev(ndev); +exit: + return ret; +} + +void rtw_os_ndev_free(_adapter *adapter) +{ +#if defined(CONFIG_IOCTL_CFG80211) + rtw_cfg80211_ndev_res_free(adapter); +#endif + + if (adapter->pnetdev) { + rtw_free_netdev(adapter->pnetdev); + adapter->pnetdev = NULL; + } +} + +int rtw_os_ndev_register(_adapter *adapter, char *name) +{ + int ret = _SUCCESS; + struct net_device *ndev = adapter->pnetdev; + +#if defined(CONFIG_IOCTL_CFG80211) + if (rtw_cfg80211_ndev_res_register(adapter) != _SUCCESS) { + rtw_warn_on(1); + ret = _FAIL; + goto exit; + } +#endif + + /* alloc netdev name */ + rtw_init_netdev_name(ndev, name); + + _rtw_memcpy(ndev->dev_addr, adapter_mac_addr(adapter), ETH_ALEN); + + /* Tell the network stack we exist */ + if (register_netdev(ndev) != 0) { + DBG_871X(FUNC_NDEV_FMT" if%d Failed!\n", FUNC_NDEV_ARG(ndev), (adapter->iface_id+1)); + ret = _FAIL; + } + +#if defined(CONFIG_IOCTL_CFG80211) + if (ret != _SUCCESS) { + rtw_cfg80211_ndev_res_unregister(adapter); + #if !defined(RTW_SINGLE_WIPHY) + rtw_wiphy_unregister(adapter_to_wiphy(adapter)); + #endif + } +#endif + +exit: + return ret; +} + +void rtw_os_ndev_unregister(_adapter *adapter) +{ + struct net_device *netdev = NULL; + + if (adapter == NULL) + return; + + adapter->ndev_unregistering = 1; + + netdev = adapter->pnetdev; + +#if defined(CONFIG_IOCTL_CFG80211) + rtw_cfg80211_ndev_res_unregister(adapter); +#endif + + if ((adapter->DriverState != DRIVER_DISAPPEAR) && netdev) + unregister_netdev(netdev); /* will call netdev_close() */ + +#if defined(CONFIG_IOCTL_CFG80211) && !defined(RTW_SINGLE_WIPHY) + rtw_wiphy_unregister(adapter_to_wiphy(adapter)); +#endif + + adapter->ndev_unregistering = 0; +} + +/** + * rtw_os_ndev_init - Allocate and register OS layer net device and relating structures for @adapter + * @adapter: the adapter on which this function applies + * @name: the requesting net device name + * + * Returns: + * _SUCCESS or _FAIL + */ +int rtw_os_ndev_init(_adapter *adapter, char *name) +{ + int ret = _FAIL; + + if (rtw_os_ndev_alloc(adapter) != _SUCCESS) + goto exit; + + if (rtw_os_ndev_register(adapter, name) != _SUCCESS) + goto os_ndev_free; + + ret = _SUCCESS; + +os_ndev_free: + if (ret != _SUCCESS) + rtw_os_ndev_free(adapter); +exit: + return ret; +} + +/** + * rtw_os_ndev_deinit - Unregister and free OS layer net device and relating structures for @adapter + * @adapter: the adapter on which this function applies + */ +void rtw_os_ndev_deinit(_adapter *adapter) +{ + rtw_os_ndev_unregister(adapter); + rtw_os_ndev_free(adapter); +} + +int rtw_os_ndevs_alloc(struct dvobj_priv *dvobj) +{ + int i, status = _SUCCESS; + _adapter *adapter; + +#if defined(CONFIG_IOCTL_CFG80211) + if (rtw_cfg80211_dev_res_alloc(dvobj) != _SUCCESS) { + rtw_warn_on(1); + status = _FAIL; + goto exit; + } +#endif + + for (i = 0; i < dvobj->iface_nums; i++) { + + if (i >= IFACE_ID_MAX) { + DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i); + rtw_warn_on(1); + continue; + } + + adapter = dvobj->padapters[i]; + if (adapter && !adapter->pnetdev) { + status = rtw_os_ndev_alloc(adapter); + if (status != _SUCCESS) { + rtw_warn_on(1); + break; + } + } + } + + if (status != _SUCCESS) { + for (; i >= 0; i--) { + adapter = dvobj->padapters[i]; + if (adapter && adapter->pnetdev) + rtw_os_ndev_free(adapter); + } + } + +#if defined(CONFIG_IOCTL_CFG80211) + if (status != _SUCCESS) + rtw_cfg80211_dev_res_free(dvobj); +#endif +exit: + return status; +} + +void rtw_os_ndevs_free(struct dvobj_priv *dvobj) +{ + int i; + _adapter *adapter = NULL; + + for (i = 0; i < dvobj->iface_nums; i++) { + + if (i >= IFACE_ID_MAX) { + DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i); + rtw_warn_on(1); + continue; + } + + adapter = dvobj->padapters[i]; + + if (adapter == NULL) + continue; + + rtw_os_ndev_free(adapter); + } + +#if defined(CONFIG_IOCTL_CFG80211) + rtw_cfg80211_dev_res_free(dvobj); +#endif +} + +u32 rtw_start_drv_threads(_adapter *padapter) +{ + u32 _status = _SUCCESS; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_start_drv_threads\n")); + +#ifdef CONFIG_XMIT_THREAD_MODE +#if defined(CONFIG_SDIO_HCI) + if (is_primary_adapter(padapter)) +#endif + { + padapter->xmitThread = kthread_run(rtw_xmit_thread, padapter, "RTW_XMIT_THREAD"); + if(IS_ERR(padapter->xmitThread)) + _status = _FAIL; + } +#endif //#ifdef CONFIG_XMIT_THREAD_MODE + +#ifdef CONFIG_RECV_THREAD_MODE + padapter->recvThread = kthread_run(rtw_recv_thread, padapter, "RTW_RECV_THREAD"); + if(IS_ERR(padapter->recvThread)) + _status = _FAIL; +#endif + + if (is_primary_adapter(padapter)) { + padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD"); + if(IS_ERR(padapter->cmdThread)) + _status = _FAIL; + else + _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); //wait for cmd_thread to run + } + + +#ifdef CONFIG_EVENT_THREAD_MODE + padapter->evtThread = kthread_run(event_thread, padapter, "RTW_EVENT_THREAD"); + if(IS_ERR(padapter->evtThread)) + _status = _FAIL; +#endif + + rtw_hal_start_thread(padapter); + return _status; + +} + +void rtw_stop_drv_threads (_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_stop_drv_threads\n")); + + if (is_primary_adapter(padapter)) + rtw_stop_cmd_thread(padapter); + +#ifdef CONFIG_EVENT_THREAD_MODE + _rtw_up_sema(&padapter->evtpriv.evt_notify); + if(padapter->evtThread){ + _rtw_down_sema(&padapter->evtpriv.terminate_evtthread_sema); + } +#endif + +#ifdef CONFIG_XMIT_THREAD_MODE + // Below is to termindate tx_thread... +#if defined(CONFIG_SDIO_HCI) + // Only wake-up primary adapter + if (is_primary_adapter(padapter)) +#endif /*SDIO_HCI */ + { + _rtw_up_sema(&padapter->xmitpriv.xmit_sema); + _rtw_down_sema(&padapter->xmitpriv.terminate_xmitthread_sema); + } + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("\n drv_halt: rtw_xmit_thread can be terminated !\n")); +#endif + +#ifdef CONFIG_RECV_THREAD_MODE + // Below is to termindate rx_thread... + _rtw_up_sema(&padapter->recvpriv.recv_sema); + _rtw_down_sema(&padapter->recvpriv.terminate_recvthread_sema); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt:recv_thread can be terminated! \n")); +#endif + + rtw_hal_stop_thread(padapter); +} + +u8 rtw_init_default_value(_adapter *padapter); +u8 rtw_init_default_value(_adapter *padapter) +{ + u8 ret = _SUCCESS; + struct registry_priv* pregistrypriv = &padapter->registrypriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + + //xmit_priv + pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; + pxmitpriv->vcs = pregistrypriv->vcs_type; + pxmitpriv->vcs_type = pregistrypriv->vcs_type; + //pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; + pxmitpriv->frag_len = pregistrypriv->frag_thresh; + + //recv_priv + + //mlme_priv + pmlmepriv->scan_mode = SCAN_ACTIVE; + + //qos_priv + //pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable; + + //ht_priv +#ifdef CONFIG_80211N_HT + pmlmepriv->htpriv.ampdu_enable = _FALSE;//set to disabled +#endif + + //security_priv + //rtw_get_encrypt_decrypt_from_registrypriv(padapter); + psecuritypriv->binstallGrpkey = _FAIL; +#ifdef CONFIG_GTK_OL + psecuritypriv->binstallKCK_KEK = _FAIL; +#endif //CONFIG_GTK_OL + psecuritypriv->sw_encrypt=pregistrypriv->software_encrypt; + psecuritypriv->sw_decrypt=pregistrypriv->software_decrypt; + + psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system + psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_; + + psecuritypriv->dot11PrivacyKeyIndex = 0; + + psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_; + psecuritypriv->dot118021XGrpKeyid = 1; + + psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen; + psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled; + + + //pwrctrl_priv + + + //registry_priv + rtw_init_registrypriv_dev_network(padapter); + rtw_update_registrypriv_dev_network(padapter); + + + //hal_priv + rtw_hal_def_value_init(padapter); + + //misc. + RTW_ENABLE_FUNC(padapter, DF_RX_BIT); + RTW_ENABLE_FUNC(padapter, DF_TX_BIT); + padapter->bLinkInfoDump = 0; + padapter->bNotifyChannelChange = _FALSE; +#ifdef CONFIG_P2P + padapter->bShowGetP2PState = 1; +#endif + + //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_rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID; + padapter->fix_rx_ampdu_size = RX_AMPDU_SIZE_INVALID; +#ifdef DBG_RX_COUNTER_DUMP + padapter->dump_rx_cnt_mode = 0; + padapter->drv_rx_cnt_ok = 0; + padapter->drv_rx_cnt_crcerror = 0; + padapter->drv_rx_cnt_drop = 0; +#endif + return ret; +} + +struct dvobj_priv *devobj_init(void) +{ + struct dvobj_priv *pdvobj = NULL; + + if ((pdvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*pdvobj))) == NULL) + { + return NULL; + } + + _rtw_mutex_init(&pdvobj->hw_init_mutex); + _rtw_mutex_init(&pdvobj->h2c_fwcmd_mutex); + _rtw_mutex_init(&pdvobj->setch_mutex); + _rtw_mutex_init(&pdvobj->setbw_mutex); +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + _rtw_mutex_init(&pdvobj->sd_indirect_access_mutex); +#endif + + 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); + _rtw_mutex_init(&pdvobj->cam_ctl.sec_cam_access_mutex); + + return pdvobj; + +} + +void devobj_deinit(struct dvobj_priv *pdvobj) +{ + if(!pdvobj) + return; + + /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */ +#if defined(CONFIG_IOCTL_CFG80211) + rtw_cfg80211_dev_res_free(pdvobj); +#endif + + _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); +#ifdef CONFIG_SDIO_INDIRECT_ACCESS + _rtw_mutex_free(&pdvobj->sd_indirect_access_mutex); +#endif + + rtw_macid_ctl_deinit(&pdvobj->macid_ctl); + _rtw_spinlock_free(&pdvobj->cam_ctl.lock); + _rtw_mutex_free(&pdvobj->cam_ctl.sec_cam_access_mutex); + + rtw_mfree((u8*)pdvobj, sizeof(*pdvobj)); +} + +u8 rtw_reset_drv_sw(_adapter *padapter) +{ + u8 ret8=_SUCCESS; + struct mlme_priv *pmlmepriv= &padapter->mlmepriv; + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + //hal_priv + if( is_primary_adapter(padapter)) + rtw_hal_def_value_init(padapter); + + RTW_ENABLE_FUNC(padapter, DF_RX_BIT); + RTW_ENABLE_FUNC(padapter, DF_TX_BIT); + padapter->bLinkInfoDump = 0; + + padapter->xmitpriv.tx_pkts = 0; + padapter->recvpriv.rx_pkts = 0; + + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + + //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; + pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; + pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; + + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY |_FW_UNDER_LINKING); + +#ifdef CONFIG_AUTOSUSPEND + #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,22) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,34)) + adapter_to_dvobj(padapter)->pusbdev->autosuspend_disabled = 1;//autosuspend disabled by the user + #endif +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT + if (is_primary_adapter(padapter)) + rtw_hal_sreset_reset_value(padapter); +#endif + pwrctrlpriv->pwr_state_check_cnts = 0; + + //mlmeextpriv + mlmeext_set_scan_state(&padapter->mlmeextpriv, SCAN_DISABLE); + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + rtw_set_signal_stat_timer(&padapter->recvpriv); +#endif + + return ret8; +} + + +u8 rtw_init_drv_sw(_adapter *padapter) +{ + + u8 ret8=_SUCCESS; + +_func_enter_; + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_init_drv_sw\n")); + + ret8 = rtw_init_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")); + ret8=_FAIL; + goto exit; + } + + padapter->cmdpriv.padapter=padapter; + + if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init evt_priv\n")); + ret8=_FAIL; + goto exit; + } + + + if (rtw_init_mlme_priv(padapter) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init mlme_priv\n")); + ret8=_FAIL; + goto exit; + } + +#ifdef CONFIG_P2P + rtw_init_wifidirect_timers(padapter); + init_wifidirect_info(padapter, P2P_ROLE_DISABLE); + reset_global_wifidirect_info(padapter); + #ifdef CONFIG_IOCTL_CFG80211 + rtw_init_cfg80211_wifidirect_info(padapter); + #endif +#ifdef CONFIG_WFD + if(rtw_init_wifi_display_info(padapter) == _FAIL) + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init init_wifi_display_info\n")); +#endif +#endif /* CONFIG_P2P */ + + if(init_mlme_ext_priv(padapter) == _FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("\n Can't init mlme_ext_priv\n")); + ret8=_FAIL; + goto exit; + } + +#ifdef CONFIG_TDLS + if(rtw_init_tdls_info(padapter) == _FAIL) + { + DBG_871X("Can't rtw_init_tdls_info\n"); + ret8=_FAIL; + goto exit; + } +#endif //CONFIG_TDLS + + if(_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) + { + DBG_871X("Can't _rtw_init_xmit_priv\n"); + ret8=_FAIL; + goto exit; + } + + if(_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) + { + DBG_871X("Can't _rtw_init_recv_priv\n"); + ret8=_FAIL; + goto exit; + } + // add for CONFIG_IEEE80211W, none 11w also can use + _rtw_spinlock_init(&padapter->security_key_mutex); + + // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). + //_rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); + + //_init_timer(&(padapter->securitypriv.tkip_timer), padapter->pifp, rtw_use_tkipkey_handler, padapter); + + if(_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) + { + DBG_871X("Can't _rtw_init_sta_priv\n"); + ret8=_FAIL; + goto exit; + } + + padapter->stapriv.padapter = padapter; + padapter->setband = WIFI_FREQUENCY_BAND_AUTO; + padapter->fix_rate = 0xFF; + padapter->data_fb = 0; + padapter->fix_rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID; + padapter->fix_rx_ampdu_size = RX_AMPDU_SIZE_INVALID; +#ifdef DBG_RX_COUNTER_DUMP + padapter->dump_rx_cnt_mode = 0; + padapter->drv_rx_cnt_ok = 0; + padapter->drv_rx_cnt_crcerror = 0; + padapter->drv_rx_cnt_drop = 0; +#endif + rtw_init_bcmc_stainfo(padapter); + + rtw_init_pwrctrl_priv(padapter); + + //_rtw_memset((u8 *)&padapter->qospriv, 0, sizeof (struct qos_priv));//move to mlme_priv + +#ifdef CONFIG_MP_INCLUDED + if (init_mp_priv(padapter) == _FAIL) { + DBG_871X("%s: initialize MP private data Fail!\n", __func__); + } +#endif + + rtw_hal_dm_init(padapter); + rtw_hal_sw_led_init(padapter); + +#ifdef DBG_CONFIG_ERROR_DETECT + rtw_hal_sreset_init(padapter); +#endif + +#ifdef CONFIG_INTEL_WIDI + if(rtw_init_intel_widi(padapter) == _FAIL) + { + DBG_871X("Can't rtw_init_intel_widi\n"); + ret8=_FAIL; + goto exit; + } +#endif //CONFIG_INTEL_WIDI + +#ifdef CONFIG_WAPI_SUPPORT + padapter->WapiSupport = true; //set true temp, will revise according to Efuse or Registry value later. + rtw_wapi_init(padapter); +#endif + +#ifdef CONFIG_BR_EXT + _rtw_spinlock_init(&padapter->br_ext_lock); +#endif // CONFIG_BR_EXT + +exit: + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-rtw_init_drv_sw\n")); + + _func_exit_; + + return ret8; + +} + +#ifdef CONFIG_WOWLAN +void rtw_cancel_dynamic_chk_timer(_adapter *padapter) +{ + _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel dynamic_chk_timer! \n")); +} +#endif + +void rtw_cancel_all_timer(_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_cancel_all_timer\n")); + + _cancel_timer_ex(&padapter->mlmepriv.assoc_timer); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n")); + + #if 0 + _cancel_timer_ex(&padapter->securitypriv.tkip_timer); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel tkip_timer!\n")); + #endif + + _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n")); + + #ifdef CONFIG_DFS_MASTER + _cancel_timer_ex(&padapter->mlmepriv.dfs_master_timer); + #endif + + _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer); + RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n")); + + // cancel sw led timer + rtw_hal_sw_led_deinit(padapter); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel DeInitSwLeds! \n")); + + _cancel_timer_ex(&(adapter_to_pwrctl(padapter)->pwr_state_check_timer)); + +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P + _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer); +#endif //CONFIG_P2P +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_SET_SCAN_DENY_TIMER + _cancel_timer_ex(&padapter->mlmepriv.set_scan_deny_timer); + rtw_clear_scan_deny(padapter); + RT_TRACE(_module_os_intfs_c_,_drv_info_,("rtw_cancel_all_timer:cancel set_scan_deny_timer! \n")); +#endif + +#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS + _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer); +#endif + //cancel dm timer + rtw_hal_dm_deinit(padapter); + +#ifdef CONFIG_PLATFORM_FS_MX61 + msleep(50); +#endif +} + +u8 rtw_free_drv_sw(_adapter *padapter) +{ + RT_TRACE(_module_os_intfs_c_,_drv_info_,("==>rtw_free_drv_sw")); + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_free(padapter); +#endif + + //we can call rtw_p2p_enable here, but: + // 1. rtw_p2p_enable may have IO operation + // 2. rtw_p2p_enable is bundled with wext interface + #ifdef CONFIG_P2P + { + struct wifidirect_info *pwdinfo = &padapter->wdinfo; + if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) + { + _cancel_timer_ex( &pwdinfo->find_phase_timer ); + _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer ); + _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); +#ifdef CONFIG_CONCURRENT_MODE + _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer ); +#endif // CONFIG_CONCURRENT_MODE + rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE); + } + } + #endif + // add for CONFIG_IEEE80211W, none 11w also can use + _rtw_spinlock_free(&padapter->security_key_mutex); + +#ifdef CONFIG_BR_EXT + _rtw_spinlock_free(&padapter->br_ext_lock); +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_INTEL_WIDI + rtw_free_intel_widi(padapter); +#endif //CONFIG_INTEL_WIDI + + free_mlme_ext_priv(&padapter->mlmeextpriv); + +#ifdef CONFIG_TDLS + //rtw_free_tdls_info(&padapter->tdlsinfo); +#endif //CONFIG_TDLS + + rtw_free_cmd_priv(&padapter->cmdpriv); + + rtw_free_evt_priv(&padapter->evtpriv); + + rtw_free_mlme_priv(&padapter->mlmepriv); + + //free_io_queue(padapter); + + _rtw_free_xmit_priv(&padapter->xmitpriv); + + _rtw_free_sta_priv(&padapter->stapriv); //will free bcmc_stainfo here + + _rtw_free_recv_priv(&padapter->recvpriv); + + rtw_free_pwrctrl_priv(padapter); + + //rtw_mfree((void *)padapter, sizeof (padapter)); + +#ifdef CONFIG_DRVEXT_MODULE + free_drvext(&padapter->drvextpriv); +#endif + + rtw_hal_free_data(padapter); + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("<==rtw_free_drv_sw\n")); + + //free the old_pnetdev + if(padapter->rereg_nd_name_priv.old_pnetdev) { + free_netdev(padapter->rereg_nd_name_priv.old_pnetdev); + padapter->rereg_nd_name_priv.old_pnetdev = NULL; + } + + // clear pbuddy_adapter to avoid access wrong pointer. + if(padapter->pbuddy_adapter != NULL) { + padapter->pbuddy_adapter->pbuddy_adapter = NULL; + } + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-rtw_free_drv_sw\n")); + + return _SUCCESS; + +} + +#ifdef CONFIG_CONCURRENT_MODE +#ifdef CONFIG_MULTI_VIR_IFACES +int _netdev_vir_if_open(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + _adapter *primary_padapter = GET_PRIMARY_ADAPTER(padapter); + + DBG_871X(FUNC_NDEV_FMT" enter\n", FUNC_NDEV_ARG(pnetdev)); + + if(!primary_padapter) + goto _netdev_virtual_iface_open_error; + + if (primary_padapter->bup == _FALSE || !rtw_is_hw_init_completed(primary_padapter)) + _netdev_open(primary_padapter->pnetdev); + + if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE && + rtw_is_hw_init_completed(primary_padapter)) + { + padapter->bFWReady = primary_padapter->bFWReady; + + if(rtw_start_drv_threads(padapter) == _FAIL) + { + goto _netdev_virtual_iface_open_error; + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + padapter->bup = _TRUE; + + } + + padapter->net_closed = _FALSE; + + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + + rtw_netif_wake_queue(pnetdev); + + DBG_871X(FUNC_NDEV_FMT" exit\n", FUNC_NDEV_ARG(pnetdev)); + return 0; + +_netdev_virtual_iface_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + return (-1); + +} + +int netdev_vir_if_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_vir_if_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + +#ifdef CONFIG_AUTO_AP_MODE + //if(padapter->iface_id == 2) + // rtw_start_auto_ap(padapter); +#endif + + return ret; +} + +static int netdev_vir_if_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + padapter->net_closed = _TRUE; + + if(pnetdev) + { + rtw_netif_stop_queue(pnetdev); + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + rtw_cfg80211_wait_scan_req_empty(padapter, 200); + adapter_wdev_data(padapter)->bandroid_scan = _FALSE; +#endif + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_vir_if_ops = { + .ndo_open = netdev_vir_if_open, + .ndo_stop = netdev_vir_if_close, + .ndo_start_xmit = rtw_xmit_entry, + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif +}; +#endif + +void rtw_hook_vir_if_ops(struct net_device *ndev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) + ndev->netdev_ops = &rtw_netdev_vir_if_ops; +#else + ndev->open = netdev_vir_if_open; + ndev->stop = netdev_vir_if_close; + ndev->set_mac_address = rtw_net_set_mac_address; +#endif +} + +_adapter *rtw_drv_add_vir_if(_adapter *primary_padapter, + void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops)) +{ + int res = _FAIL; + _adapter *padapter = NULL; + struct dvobj_priv *pdvobjpriv; + u8 mac[ETH_ALEN]; + +/* + if((primary_padapter->bup == _FALSE) || + (rtw_buddy_adapter_up(primary_padapter) == _FALSE)) + goto exit; +*/ + + /****** init adapter ******/ + padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter)); + if (padapter == NULL) + goto exit; + + if (loadparam(padapter) != _SUCCESS) + goto free_adapter; + + _rtw_memcpy(padapter, primary_padapter, sizeof(_adapter)); + + // + padapter->bup = _FALSE; + padapter->net_closed = _TRUE; + padapter->dir_dev = NULL; + padapter->dir_odm = NULL; + + + //set adapter_type/iface type + padapter->isprimary = _FALSE; + padapter->adapter_type = MAX_ADAPTER; + padapter->pbuddy_adapter = primary_padapter; +#if 0 +#ifndef CONFIG_HWPORT_SWAP //Port0 -> Pri , Port1 -> Sec + padapter->iface_type = IFACE_PORT1; +#else + padapter->iface_type = IFACE_PORT0; +#endif //CONFIG_HWPORT_SWAP +#else + //extended virtual interfaces always are set to port0 + padapter->iface_type = IFACE_PORT0; +#endif + + /****** hook vir if into dvobj ******/ + pdvobjpriv = adapter_to_dvobj(padapter); + padapter->iface_id = pdvobjpriv->iface_nums; + pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter; + + padapter->intf_start = NULL; + padapter->intf_stop = NULL; + + //step init_io_priv + if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("\n Can't init io_reqs\n")); + goto free_adapter; + } + + //init drv data + if(rtw_init_drv_sw(padapter)!= _SUCCESS) + goto free_drv_sw; + + + //get mac address from primary_padapter + _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN); + + /* + * If the BIT1 is 0, the address is universally administered. + * If it is 1, the address is locally administered + */ +#if 1 /* needs enable MBSSID CAM */ + mac[0] |= BIT(1); + mac[0] |= (padapter->iface_id-1)<<4; +#endif + + _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN); + + res = _SUCCESS; + +free_drv_sw: + if (res != _SUCCESS && padapter) + rtw_free_drv_sw(padapter); +free_adapter: + if (res != _SUCCESS && padapter) { + rtw_vmfree((u8 *)padapter, sizeof(*padapter)); + padapter = NULL; + } +exit: + return padapter; +} + +void rtw_drv_stop_vir_if(_adapter *padapter) +{ + struct net_device *pnetdev=NULL; + + if (padapter == NULL) + return; + + pnetdev = padapter->pnetdev; + + rtw_cancel_all_timer(padapter); + + if (padapter->bup == _TRUE) + { + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + if (padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + rtw_stop_drv_threads(padapter); + + padapter->bup = _FALSE; + } +} + +void rtw_drv_free_vir_if(_adapter *padapter) +{ + if (padapter == NULL) + return; + + padapter->pbuddy_adapter = NULL; + + rtw_free_drv_sw(padapter); + + /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */ + rtw_os_ndev_free(padapter); + + rtw_vmfree((u8 *)padapter, sizeof(_adapter)); +} + +void rtw_drv_stop_vir_ifaces(struct dvobj_priv *dvobj) +{ + int i; + //struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_stop_vir_if(dvobj->padapters[i]); + } +} + +void rtw_drv_free_vir_ifaces(struct dvobj_priv *dvobj) +{ + int i; + //struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_free_vir_if(dvobj->padapters[i]); + } +} + +void rtw_drv_del_vir_if(_adapter *padapter) +{ + rtw_drv_stop_vir_if(padapter); + rtw_drv_free_vir_if(padapter); +} + +void rtw_drv_del_vir_ifaces(_adapter *primary_padapter) +{ + int i; + struct dvobj_priv *dvobj = primary_padapter->dvobj; + + for(i=2;iiface_nums;i++) + { + rtw_drv_del_vir_if(dvobj->padapters[i]); + } +} +#endif //CONFIG_MULTI_VIR_IFACES + +int _netdev_if2_open(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + _adapter *primary_padapter = padapter->pbuddy_adapter; + + 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(adapter_mac_addr(primary_padapter), get_hal_mac_addr(primary_padapter)); + + _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN); + + /* + * If the BIT1 is 0, the address is universally administered. + * If it is 1, the address is locally administered + */ + mac[0] |= BIT(1); + + _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN); + rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter)); + _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN); + } +#endif //CONFIG_PLATFORM_INTEL_BYT + + if (primary_padapter->bup == _FALSE || !rtw_is_hw_init_completed(primary_padapter)) + _netdev_open(primary_padapter->pnetdev); + + if(padapter->bup == _FALSE && primary_padapter->bup == _TRUE && + rtw_is_hw_init_completed(primary_padapter)) + { + padapter->bFWReady = primary_padapter->bFWReady; + + //if (init_mlme_ext_priv(padapter) == _FAIL) + // goto netdev_if2_open_error; + + + if (rtw_start_drv_threads(padapter) == _FAIL) + { + goto netdev_if2_open_error; + } + + + if (padapter->intf_start) + { + padapter->intf_start(padapter); + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + padapter->bup = _TRUE; + + } + + padapter->net_closed = _FALSE; + + //execute dynamic_chk_timer only on primary interface + // secondary interface shares the timer with primary interface. + //_set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + + rtw_netif_wake_queue(pnetdev); + + DBG_871X("-871x_drv - if2_open, bup=%d\n", padapter->bup); + return 0; + +netdev_if2_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + return (-1); + +} + +int netdev_if2_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + if (pwrctrlpriv->bInSuspend == _TRUE) + { + DBG_871X("+871x_drv - netdev_if2_open, bInSuspend=%d\n", pwrctrlpriv->bInSuspend); + return 0; + } + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_if2_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + +#ifdef CONFIG_AUTO_AP_MODE + //if(padapter->iface_id == 2) + rtw_start_auto_ap(padapter); +#endif + + return ret; +} + +static int netdev_if2_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + padapter->net_closed = _TRUE; + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + + if(pnetdev) + { + rtw_netif_stop_queue(pnetdev); + } + +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_role(&padapter->wdinfo, P2P_ROLE_DISABLE)) + rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); +#endif + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + rtw_cfg80211_wait_scan_req_empty(padapter, 200); + adapter_wdev_data(padapter)->bandroid_scan = _FALSE; +#endif + + return 0; +} + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29)) +static const struct net_device_ops rtw_netdev_if2_ops = { + .ndo_init = rtw_ndev_init, + .ndo_uninit = rtw_ndev_uninit, + .ndo_open = netdev_if2_open, + .ndo_stop = netdev_if2_close, + .ndo_start_xmit = rtw_xmit_entry, + .ndo_set_mac_address = rtw_net_set_mac_address, + .ndo_get_stats = rtw_net_get_stats, + .ndo_do_ioctl = rtw_ioctl, +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + .ndo_select_queue = rtw_select_queue, +#endif +}; +#endif + +void rtw_hook_if2_ops(struct net_device *ndev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) + ndev->netdev_ops = &rtw_netdev_if2_ops; +#else + ndev->init = rtw_ndev_init; + ndev->uninit = rtw_ndev_uninit; + ndev->open = netdev_if2_open; + ndev->stop = netdev_if2_close; + ndev->set_mac_address = rtw_net_set_mac_address; +#endif +} + +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, + void (*set_intf_ops)(_adapter *primary_padapter,struct _io_ops *pops)) +{ + int res = _FAIL; + _adapter *padapter = NULL; + struct dvobj_priv *pdvobjpriv; + u8 mac[ETH_ALEN]; + + /****** init adapter ******/ + padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter)); + if (padapter == NULL) + goto exit; + + if (loadparam(padapter) != _SUCCESS) + goto free_adapter; + + _rtw_memcpy(padapter, primary_padapter, sizeof(*padapter)); + + // + padapter->bup = _FALSE; + padapter->net_closed = _TRUE; + padapter->dir_dev = NULL; + padapter->dir_odm = NULL; + + //set adapter_type/iface type + padapter->isprimary = _FALSE; + padapter->adapter_type = SECONDARY_ADAPTER; + padapter->pbuddy_adapter = primary_padapter; + padapter->iface_id = IFACE_ID1; +#ifndef CONFIG_HWPORT_SWAP //Port0 -> Pri , Port1 -> Sec + padapter->iface_type = IFACE_PORT1; +#else + padapter->iface_type = IFACE_PORT0; +#endif //CONFIG_HWPORT_SWAP + + /****** hook if2 into dvobj ******/ + pdvobjpriv = adapter_to_dvobj(padapter); + pdvobjpriv->padapters[pdvobjpriv->iface_nums++] = padapter; + + // + padapter->intf_start = primary_padapter->intf_start; + padapter->intf_stop = primary_padapter->intf_stop; + + //step init_io_priv + if ((rtw_init_io_priv(padapter, set_intf_ops)) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("\n Can't init io_reqs\n")); + goto free_adapter; + } + + //init drv data + if(rtw_init_drv_sw(padapter)!= _SUCCESS) + goto free_drv_sw; + + + /* get mac address from primary_padapter */ + _rtw_memcpy(mac, adapter_mac_addr(primary_padapter), ETH_ALEN); + + /* + * If the BIT1 is 0, the address is universally administered. + * If it is 1, the address is locally administered + */ + mac[0] |= BIT(1); + + _rtw_memcpy(adapter_mac_addr(padapter), mac, ETH_ALEN); + rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter)); + + primary_padapter->pbuddy_adapter = padapter; + + res = _SUCCESS; + +free_drv_sw: + if (res != _SUCCESS && padapter) + rtw_free_drv_sw(padapter); +free_adapter: + if (res != _SUCCESS && padapter) { + rtw_vmfree((u8 *)padapter, sizeof(*padapter)); + padapter = NULL; + } +exit: + return padapter; +} + +void rtw_drv_if2_free(_adapter *if2) +{ + _adapter *padapter = if2; + + if (padapter == NULL) + return; + + rtw_free_drv_sw(padapter); + + /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */ + rtw_os_ndev_free(padapter); + + rtw_vmfree((u8 *)padapter, sizeof(_adapter)); +} + +void rtw_drv_if2_stop(_adapter *if2) +{ + _adapter *padapter = if2; + struct net_device *pnetdev = NULL; + + if (padapter == NULL) + return; + + rtw_cancel_all_timer(padapter); + + if (padapter->bup == _TRUE) { + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + if (padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + + rtw_stop_drv_threads(padapter); + + padapter->bup = _FALSE; + } +} +#endif //end of CONFIG_CONCURRENT_MODE + +int rtw_os_ndevs_register(struct dvobj_priv *dvobj) +{ + int i, status = _SUCCESS; + struct registry_priv *regsty = dvobj_to_regsty(dvobj); + _adapter *adapter; + +#if defined(CONFIG_IOCTL_CFG80211) + if (rtw_cfg80211_dev_res_register(dvobj) != _SUCCESS) { + rtw_warn_on(1); + status = _FAIL; + goto exit; + } +#endif + + for (i = 0; i < dvobj->iface_nums; i++) { + + if (i >= IFACE_ID_MAX) { + DBG_871X_LEVEL(_drv_err_, "%s %d >= IFACE_ID_MAX\n", __func__, i); + rtw_warn_on(1); + continue; + } + + adapter = dvobj->padapters[i]; + if (adapter) { + char *name; + + if (adapter->iface_id == IFACE_ID0) + name = regsty->ifname; + else if (adapter->iface_id == IFACE_ID1) + name = regsty->if2name; + else + name = "wlan%d"; + + #ifdef CONFIG_CONCURRENT_MODE + switch (adapter->adapter_type) { + case SECONDARY_ADAPTER: + rtw_hook_if2_ops(adapter->pnetdev); + break; + #ifdef CONFIG_MULTI_VIR_IFACES + case MAX_ADAPTER: + rtw_hook_vir_if_ops(adapter->pnetdev); + break; + #endif + } + #endif /* CONFIG_CONCURRENT_MODE */ + + status = rtw_os_ndev_register(adapter, name); + + if (status != _SUCCESS) { + rtw_warn_on(1); + break; + } + } + } + + if (status != _SUCCESS) { + for (; i >= 0; i--) { + adapter = dvobj->padapters[i]; + if (adapter) + rtw_os_ndev_unregister(adapter); + } + } + +#if defined(CONFIG_IOCTL_CFG80211) + if (status != _SUCCESS) + rtw_cfg80211_dev_res_unregister(dvobj); +#endif +exit: + return status; +} + +void rtw_os_ndevs_unregister(struct dvobj_priv *dvobj) +{ + int i; + _adapter *adapter = NULL; + + for (i = 0; i < dvobj->iface_nums; i++) { + adapter = dvobj->padapters[i]; + + if (adapter == NULL) + continue; + + rtw_os_ndev_unregister(adapter); + } + +#if defined(CONFIG_IOCTL_CFG80211) + rtw_cfg80211_dev_res_unregister(dvobj); +#endif +} + +/** + * rtw_os_ndevs_init - Allocate and register OS layer net devices and relating structures for @dvobj + * @dvobj: the dvobj on which this function applies + * + * Returns: + * _SUCCESS or _FAIL + */ +int rtw_os_ndevs_init(struct dvobj_priv *dvobj) +{ + int ret = _FAIL; + + if (rtw_os_ndevs_alloc(dvobj) != _SUCCESS) + goto exit; + + if (rtw_os_ndevs_register(dvobj) != _SUCCESS) + goto os_ndevs_free; + + ret = _SUCCESS; + +os_ndevs_free: + if (ret != _SUCCESS) + rtw_os_ndevs_free(dvobj); +exit: + return ret; +} + +/** + * rtw_os_ndevs_deinit - Unregister and free OS layer net devices and relating structures for @dvobj + * @dvobj: the dvobj on which this function applies + */ +void rtw_os_ndevs_deinit(struct dvobj_priv *dvobj) +{ + rtw_os_ndevs_unregister(dvobj); + rtw_os_ndevs_free(dvobj); +} + +#ifdef CONFIG_BR_EXT +void netdev_br_init(struct net_device *netdev) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + + //if(check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) + { + //struct net_bridge *br = netdev->br_port->br;//->dev->dev_addr; +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if (netdev->br_port) +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + if (rcu_dereference(adapter->pnetdev->rx_handler_data)) +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + { + struct net_device *br_netdev; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + br_netdev = dev_get_by_name(CONFIG_BR_EXT_BRNAME); +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + struct net *devnet = NULL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = netdev->nd_net; +#else // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + devnet = dev_net(netdev); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + + br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME); +#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + + if (br_netdev) { + memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN); + dev_put(br_netdev); + } else + printk("%s()-%d: dev_get_by_name(%s) failed!", __FUNCTION__, __LINE__, CONFIG_BR_EXT_BRNAME); + } + + adapter->ethBrExtInfo.addPPPoETag = 1; + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) +} +#endif //CONFIG_BR_EXT + +int _netdev_open(struct net_device *pnetdev) +{ + uint status; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("+871x_drv - dev_open\n")); + DBG_871X("+871x_drv - drv_open, bup=%d\n", padapter->bup); + + 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; + } + + if(padapter->bup == _FALSE) + { +#ifdef CONFIG_PLATFORM_INTEL_BYT + rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter)); + rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter)); + _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN); +#endif //CONFIG_PLATFORM_INTEL_BYT + + rtw_clr_surprise_removed(padapter); + rtw_clr_drv_stopped(padapter); + + status = rtw_hal_init(padapter); + if (status ==_FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("rtl871x_hal_init(): Can't init h/w!\n")); + goto netdev_open_error; + } + + DBG_871X("MAC Address = "MAC_FMT"\n", MAC_ARG(pnetdev->dev_addr)); + + status=rtw_start_drv_threads(padapter); + if(status ==_FAIL) + { + DBG_871X("Initialize driver software resource Failed!\n"); + goto netdev_open_error; + } + +#ifdef CONFIG_DRVEXT_MODULE + init_drvext(padapter); +#endif + + if (padapter->intf_start) + { + padapter->intf_start(padapter); + } + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_init_wiphy(padapter); +#endif + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + 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; + + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); + +#ifndef CONFIG_IPS_CHECK_IN_WD + rtw_set_pwr_state_check_timer(pwrctrlpriv); +#endif + + //netif_carrier_on(pnetdev);//call this func when rtw_joinbss_event_callback return success + rtw_netif_wake_queue(pnetdev); + +#ifdef CONFIG_BR_EXT + netdev_br_init(pnetdev); +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + if(is_primary_adapter(padapter) && _TRUE == pHalData->EEPROMBluetoothCoexist) + { + rtw_btcoex_init_socket(padapter); + padapter->coex_info.BtMgnt.ExtConfig.HCIExtensionVer = 0x04; + rtw_btcoex_SetHciVersion(padapter,0x04); + } + else + DBG_871X("CONFIG_BT_COEXIST: SECONDARY_ADAPTER\n"); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + +netdev_open_normal_process: + + #ifdef CONFIG_CONCURRENT_MODE + { + _adapter *sec_adapter = padapter->pbuddy_adapter; + if(sec_adapter && (sec_adapter->bup == _FALSE)) + _netdev_if2_open(sec_adapter->pnetdev); + } + #endif + + RT_TRACE(_module_os_intfs_c_,_drv_info_,("-871x_drv - dev_open\n")); + DBG_871X("-871x_drv - drv_open, bup=%d\n", padapter->bup); + + return 0; + +netdev_open_error: + + padapter->bup = _FALSE; + + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + + RT_TRACE(_module_os_intfs_c_,_drv_err_,("-871x_drv - dev_open, fail!\n")); + DBG_871X("-871x_drv - drv_open fail, bup=%d\n", padapter->bup); + + return (-1); + +} + +int netdev_open(struct net_device *pnetdev) +{ + int ret; + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); + + if (pwrctrlpriv->bInSuspend == _TRUE) + { + DBG_871X("+871x_drv - drv_open, bInSuspend=%d\n", pwrctrlpriv->bInSuspend); + return 0; + } + + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + ret = _netdev_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + + return ret; +} + +#ifdef CONFIG_IPS +int ips_netdrv_open(_adapter *padapter) +{ + int status = _SUCCESS; + //struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + + padapter->net_closed = _FALSE; + + DBG_871X("===> %s.........\n",__FUNCTION__); + + + rtw_clr_drv_stopped(padapter); + //padapter->bup = _TRUE; + + status = rtw_hal_init(padapter); + if (status ==_FAIL) + { + RT_TRACE(_module_os_intfs_c_,_drv_err_,("ips_netdrv_open(): Can't init h/w!\n")); + goto netdev_open_error; + } + + if (padapter->intf_start) + { + padapter->intf_start(padapter); + } + +#ifndef CONFIG_IPS_CHECK_IN_WD + rtw_set_pwr_state_check_timer(adapter_to_pwrctl(padapter)); +#endif + _set_timer(&padapter->mlmepriv.dynamic_chk_timer,2000); + + return _SUCCESS; + +netdev_open_error: + //padapter->bup = _FALSE; + DBG_871X("-ips_netdrv_open - drv_open failure, bup=%d\n", padapter->bup); + + return _FAIL; +} + + +int rtw_ips_pwr_up(_adapter *padapter) +{ + int result; + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv *psrtpriv = &pHalData->srestpriv; +#endif//#ifdef DBG_CONFIG_ERROR_DETECT + u32 start_time = rtw_get_current_time(); + DBG_871X("===> rtw_ips_pwr_up..............\n"); + +#if defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_FWLPS_IN_IPS) +#ifdef DBG_CONFIG_ERROR_DETECT + if (psrtpriv->silent_reset_inprogress == _TRUE) +#endif//#ifdef DBG_CONFIG_ERROR_DETECT +#endif //defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_FWLPS_IN_IPS) + rtw_reset_drv_sw(padapter); + + result = ips_netdrv_open(padapter); + + rtw_led_control(padapter, LED_CTL_NO_LINK); + + DBG_871X("<=== rtw_ips_pwr_up.............. in %dms\n", rtw_get_passing_time_ms(start_time)); + return result; + +} + +void rtw_ips_pwr_down(_adapter *padapter) +{ + u32 start_time = rtw_get_current_time(); + DBG_871X("===> rtw_ips_pwr_down...................\n"); + + padapter->net_closed = _TRUE; + + rtw_ips_dev_unload(padapter); + DBG_871X("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time)); +} +#endif +void rtw_ips_dev_unload(_adapter *padapter) +{ + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter); +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv *psrtpriv = &pHalData->srestpriv; +#endif//#ifdef DBG_CONFIG_ERROR_DETECT + DBG_871X("====> %s...\n",__FUNCTION__); + + +#if defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_FWLPS_IN_IPS) +#ifdef DBG_CONFIG_ERROR_DETECT + if (psrtpriv->silent_reset_inprogress == _TRUE) +#endif //#ifdef DBG_CONFIG_ERROR_DETECT +#endif //defined(CONFIG_SWLPS_IN_IPS) || defined(CONFIG_FWLPS_IN_IPS) + { + rtw_hal_set_hwreg(padapter, HW_VAR_FIFO_CLEARN_UP, 0); + + if (padapter->intf_stop) + { + padapter->intf_stop(padapter); + } + } + + if (!rtw_is_surprise_removed(padapter)) + rtw_hal_deinit(padapter); + +} + + +int pm_netdev_open(struct net_device *pnetdev,u8 bnormal) +{ + int status = 0; + + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + + if (_TRUE == bnormal) + { + _enter_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + status = _netdev_open(pnetdev); + _exit_critical_mutex(&(adapter_to_dvobj(padapter)->hw_init_mutex), NULL); + } +#ifdef CONFIG_IPS + else + status = (_SUCCESS == ips_netdrv_open(padapter))?(0):(-1); +#endif + + return status; +} + +static int netdev_close(struct net_device *pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX + + 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); + if(pwrctl->rf_pwrstate == rf_off) + pwrctl->ps_flag = _TRUE; + } + padapter->net_closed = _TRUE; + padapter->netif_up = _FALSE; + pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE; + +/* if (!rtw_is_hw_init_completed(padapter)) { + DBG_871X("(1)871x_drv - drv_close, bup=%d, hw_init_completed=%s\n", padapter->bup, rtw_is_hw_init_completed(padapter)?"_TRUE":"_FALSE"); + + rtw_set_drv_stopped(padapter); + + rtw_dev_unload(padapter); + } + else*/ + if(pwrctl->rf_pwrstate == rf_on){ + DBG_871X("(2)871x_drv - drv_close, bup=%d, hw_init_completed=%s\n", padapter->bup, rtw_is_hw_init_completed(padapter)?"_TRUE":"_FALSE"); + + //s1. + if(pnetdev) + { + rtw_netif_stop_queue(pnetdev); + } + +#ifndef CONFIG_ANDROID + //s2. + LeaveAllPowerSaveMode(padapter); + rtw_disassoc_cmd(padapter, 500, _FALSE); + //s2-2. indicate disconnect to os + rtw_indicate_disconnect(padapter); + //s2-3. + rtw_free_assoc_resources(padapter, 1); + //s2-4. + rtw_free_network_queue(padapter,_TRUE); +#endif + // Close LED + rtw_led_control(padapter, LED_CTL_POWER_OFF); + } + +#ifdef CONFIG_BR_EXT + //if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE)) + { + //void nat25_db_cleanup(_adapter *priv); + nat25_db_cleanup(padapter); + } +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_P2P + if (!rtw_p2p_chk_role(&padapter->wdinfo, P2P_ROLE_DISABLE)) + rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); +#endif //CONFIG_P2P + +#ifdef CONFIG_IOCTL_CFG80211 + rtw_scan_abort(padapter); + rtw_cfg80211_wait_scan_req_empty(padapter, 200); + adapter_wdev_data(padapter)->bandroid_scan = _FALSE; + //padapter->rtw_wdev->iftype = NL80211_IFTYPE_MONITOR; //set this at the end +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_WAPI_SUPPORT + rtw_wapi_disable_tx(padapter); +#endif +#ifdef CONFIG_BT_COEXIST_SOCKET_TRX + if(is_primary_adapter(padapter) && _TRUE == pHalData->EEPROMBluetoothCoexist) + rtw_btcoex_close_socket(padapter); + else + DBG_871X("CONFIG_BT_COEXIST: SECONDARY_ADAPTER\n"); +#endif //CONFIG_BT_COEXIST_SOCKET_TRX +#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 + #ifdef CONFIG_IOCTL_CFG80211 + rtw_cfg80211_wait_scan_req_empty(padapter, 200); + #endif + + 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); + + return 0; + +} + +int pm_netdev_close(struct net_device *pnetdev,u8 bnormal) +{ + int status = 0; + + status = netdev_close(pnetdev); + + return status; +} + +void rtw_ndev_destructor(struct net_device *ndev) +{ + DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); + +#ifdef CONFIG_IOCTL_CFG80211 + if (ndev->ieee80211_ptr) + rtw_mfree((u8 *)ndev->ieee80211_ptr, sizeof(struct wireless_dev)); +#endif + free_netdev(ndev); +} + +#ifdef CONFIG_ARP_KEEP_ALIVE +struct route_info { + struct in_addr dst_addr; + struct in_addr src_addr; + struct in_addr gateway; + unsigned int dev_index; +}; + +static void parse_routes(struct nlmsghdr *nl_hdr, struct route_info *rt_info) +{ + struct rtmsg *rt_msg; + struct rtattr *rt_attr; + int rt_len; + + rt_msg = (struct rtmsg *) NLMSG_DATA(nl_hdr); + if ((rt_msg->rtm_family != AF_INET) || (rt_msg->rtm_table != RT_TABLE_MAIN)) + return; + + rt_attr = (struct rtattr *) RTM_RTA(rt_msg); + rt_len = RTM_PAYLOAD(nl_hdr); + + for (; RTA_OK(rt_attr, rt_len); rt_attr = RTA_NEXT(rt_attr, rt_len)) + { + switch (rt_attr->rta_type) { + case RTA_OIF: + rt_info->dev_index = *(int *) RTA_DATA(rt_attr); + break; + case RTA_GATEWAY: + rt_info->gateway.s_addr = *(u_int *) RTA_DATA(rt_attr); + break; + case RTA_PREFSRC: + rt_info->src_addr.s_addr = *(u_int *) RTA_DATA(rt_attr); + break; + case RTA_DST: + rt_info->dst_addr.s_addr = *(u_int *) RTA_DATA(rt_attr); + break; + } + } +} + +static int route_dump(u32 *gw_addr ,int* gw_index) +{ + int err = 0; + struct socket *sock; + struct { + struct nlmsghdr nlh; + struct rtgenmsg g; + } req; + struct msghdr msg; + struct iovec iov; + struct sockaddr_nl nladdr; + mm_segment_t oldfs; + char *pg; + int size = 0; + + err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock); + if (err) + { + printk( ": Could not create a datagram socket, error = %d\n", -ENXIO); + return err; + } + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + + req.nlh.nlmsg_len = sizeof(req); + req.nlh.nlmsg_type = RTM_GETROUTE; + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + req.nlh.nlmsg_pid = 0; + req.g.rtgen_family = AF_INET; + + iov.iov_base = &req; + iov.iov_len = sizeof(req); + + msg.msg_name = &nladdr; + msg.msg_namelen = sizeof(nladdr); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + /* referece:sock_xmit in kernel code + * WRITE for sock_sendmsg, READ for sock_recvmsg + * third parameter for msg_iovlen + * last parameter for iov_len + */ + iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, sizeof(req)); +#else + msg.msg_iov = &iov; + msg.msg_iovlen = 1; +#endif + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = MSG_DONTWAIT; + + oldfs = get_fs(); set_fs(KERNEL_DS); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + err = sock_sendmsg(sock, &msg); +#else + err = sock_sendmsg(sock, &msg, sizeof(req)); +#endif + set_fs(oldfs); + + if (err < 0) + goto out_sock; + + pg = (char *) __get_free_page(GFP_KERNEL); + if (pg == NULL) { + err = -ENOMEM; + goto out_sock; + } + +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) +restart: +#endif + + for (;;) + { + struct nlmsghdr *h; + + iov.iov_base = pg; + iov.iov_len = PAGE_SIZE; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + iov_iter_init(&msg.msg_iter, READ, &iov, 1, PAGE_SIZE); +#endif + + oldfs = get_fs(); set_fs(KERNEL_DS); + err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT); + set_fs(oldfs); + + if (err < 0) + goto out_sock_pg; + + if (msg.msg_flags & MSG_TRUNC) { + err = -ENOBUFS; + goto out_sock_pg; + } + + h = (struct nlmsghdr*) pg; + + while (NLMSG_OK(h, err)) + { + struct route_info rt_info; + if (h->nlmsg_type == NLMSG_DONE) { + err = 0; + goto done; + } + + if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *errm = (struct nlmsgerr*) NLMSG_DATA(h); + err = errm->error; + printk( "NLMSG error: %d\n", errm->error); + goto done; + } + + if (h->nlmsg_type == RTM_GETROUTE) + { + printk( "RTM_GETROUTE: NLMSG: %d\n", h->nlmsg_type); + } + if (h->nlmsg_type != RTM_NEWROUTE) { + printk( "NLMSG: %d\n", h->nlmsg_type); + err = -EINVAL; + goto done; + } + + memset(&rt_info, 0, sizeof(struct route_info)); + parse_routes(h, &rt_info); + if(!rt_info.dst_addr.s_addr && rt_info.gateway.s_addr && rt_info.dev_index) + { + *gw_addr = rt_info.gateway.s_addr; + *gw_index = rt_info.dev_index; + + } + h = NLMSG_NEXT(h, err); + } + + if (err) + { + printk( "!!!Remnant of size %d %d %d\n", err, h->nlmsg_len, h->nlmsg_type); + err = -EINVAL; + break; + } + } + +done: +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + if (!err && req.g.rtgen_family == AF_INET) { + req.g.rtgen_family = AF_INET6; + + iov.iov_base = &req; + iov.iov_len = sizeof(req); + + msg.msg_name = &nladdr; + msg.msg_namelen = sizeof(nladdr); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, sizeof(req)); +#else + msg.msg_iov = &iov; + msg.msg_iovlen = 1; +#endif + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags=MSG_DONTWAIT; + + oldfs = get_fs(); set_fs(KERNEL_DS); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + err = sock_sendmsg(sock, &msg); +#else + err = sock_sendmsg(sock, &msg, sizeof(req)); +#endif + set_fs(oldfs); + + if (err > 0) + goto restart; + } +#endif + +out_sock_pg: + free_page((unsigned long) pg); + +out_sock: + sock_release(sock); + return err; +} + +static int arp_query(unsigned char *haddr, u32 paddr, + struct net_device *dev) +{ + struct neighbour *neighbor_entry; + int ret = 0; + + neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev); + + if (neighbor_entry != NULL) { + neighbor_entry->used = jiffies; + if (neighbor_entry->nud_state & NUD_VALID) { + _rtw_memcpy(haddr, neighbor_entry->ha, dev->addr_len); + ret = 1; + } + neigh_release(neighbor_entry); + } + return ret; +} + +static int get_defaultgw(u32 *ip_addr ,char mac[]) +{ + int gw_index = 0; // oif device index + struct net_device *gw_dev = NULL; //oif device + + route_dump(ip_addr, &gw_index); + + if( !(*ip_addr) || !gw_index ) + { + //DBG_871X("No default GW \n"); + return -1; + } + + gw_dev = dev_get_by_index(&init_net, gw_index); + + if(gw_dev == NULL) + { + //DBG_871X("get Oif Device Fail \n"); + return -1; + } + + if(!arp_query(mac, *ip_addr, gw_dev)) + { + //DBG_871X( "arp query failed\n"); + dev_put(gw_dev); + return -1; + + } + dev_put(gw_dev); + + return 0; +} + +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; + + res = get_defaultgw(&gw_addr, gw_mac); + if(!res) + { + pmlmepriv->gw_ip[0] = gw_addr&0xff; + pmlmepriv->gw_ip[1] = (gw_addr&0xff00)>>8; + pmlmepriv->gw_ip[2] = (gw_addr&0xff0000)>>16; + pmlmepriv->gw_ip[3] = (gw_addr&0xff000000)>>24; + _rtw_memcpy(pmlmepriv->gw_mac_addr, gw_mac, 6); + DBG_871X("%s Gateway Mac:\t" MAC_FMT "\n", __FUNCTION__, MAC_ARG(pmlmepriv->gw_mac_addr)); + DBG_871X("%s Gateway IP:\t" IP_FMT "\n", __FUNCTION__, IP_ARG(pmlmepriv->gw_ip)); + } + else + { + DBG_871X("Get Gateway IP/MAC fail!\n"); + } + + return res; +} +#endif + +void rtw_dev_unload(PADAPTER padapter) +{ + struct net_device *pnetdev = (struct net_device*)padapter->pnetdev; + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + struct dvobj_priv *pobjpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &pobjpriv->drv_dbg; + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; + u8 cnt = 0; + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+%s\n",__FUNCTION__)); + + if (padapter->bup == _TRUE) + { + DBG_871X("===> %s\n",__FUNCTION__); + + rtw_set_drv_stopped(padapter); + #ifdef CONFIG_XMIT_ACK + if (padapter->xmitpriv.ack_tx) + rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); + #endif + + if (padapter->intf_stop) + padapter->intf_stop(padapter); + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ rtw_dev_unload: stop intf complete!\n")); + + if (!pwrctl->bInternalAutoSuspend) + rtw_stop_drv_threads(padapter); + + while(ATOMIC_READ(&(pcmdpriv->cmdthd_running)) == _TRUE){ + if (cnt > 5) { + DBG_871X("stop cmdthd timeout\n"); + break; + } else { + cnt ++; + DBG_871X("cmdthd is running(%d)\n", cnt); + rtw_msleep_os(10); + } + } + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ %s: stop thread complete!\n",__FUNCTION__)); + + //check the status of IPS + if(rtw_hal_check_ips_status(padapter) == _TRUE || pwrctl->rf_pwrstate == rf_off) { //check HW status and SW state + DBG_871X_LEVEL(_drv_always_, "%s: driver in IPS-FWLPS\n", __func__); + pdbgpriv->dbg_dev_unload_inIPS_cnt++; + } else { + DBG_871X_LEVEL(_drv_always_, "%s: driver not in IPS\n", __func__); + } + + if (!rtw_is_surprise_removed(padapter)) { +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_IpsNotify(padapter, pwrctl->ips_mode_req); +#endif +#ifdef CONFIG_WOWLAN + if (pwrctl->bSupportRemoteWakeup == _TRUE && + pwrctl->wowlan_mode ==_TRUE) { + DBG_871X_LEVEL(_drv_always_, "%s bSupportRemoteWakeup==_TRUE do not run rtw_hal_deinit()\n",__FUNCTION__); + } + else +#endif + { + //amy modify 20120221 for power seq is different between driver open and ips + rtw_hal_deinit(padapter); + } + rtw_set_surprise_removed(padapter); + } + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("@ %s: deinit hal complelt!\n",__FUNCTION__)); + + padapter->bup = _FALSE; + + DBG_871X("<=== %s\n",__FUNCTION__); + } + else { + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: bup==_FALSE\n",__FUNCTION__)); + DBG_871X("%s: bup==_FALSE\n",__FUNCTION__); + } + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-%s\n",__FUNCTION__)); +} + +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) +#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, + MAC_ARG(pmlmepriv->cur_network.network.MacAddress), + pmlmepriv->cur_network.network.Ssid.SsidLength, + pmlmepriv->assoc_ssid.SsidLength); + rtw_set_to_roam(padapter, 1); + } + } + + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)) + { + rtw_disassoc_cmd(padapter, 0, _FALSE); + //s2-2. indicate disconnect to os + rtw_indicate_disconnect(padapter); + } + #ifdef CONFIG_AP_MODE + else if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + rtw_sta_flush(padapter, _TRUE); + } + #endif + + //s2-3. + rtw_free_assoc_resources(padapter, 1); + + //s2-4. +#ifdef CONFIG_AUTOSUSPEND + if(is_primary_adapter(padapter) && (!adapter_to_pwrctl(padapter)->bInternalAutoSuspend )) +#endif + rtw_free_network_queue(padapter, _TRUE); + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { + DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __func__); + rtw_indicate_scan_done(padapter, 1); + clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + } + + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) + { + DBG_871X_LEVEL(_drv_always_, "%s: fw_under_linking\n", __FUNCTION__); + rtw_indicate_disconnect(padapter); + } + + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); + return _SUCCESS; +} + +#ifdef CONFIG_WOWLAN +int rtw_suspend_wow(_adapter *padapter) +{ + u8 ch, bw, offset; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + #endif + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct wowlan_ioctl_param poidparam; + u8 ps_mode; + int ret = _SUCCESS; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(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) + rtw_netif_stop_queue(pnetdev); + #ifdef CONFIG_CONCURRENT_MODE + if(pbuddy_netdev){ + netif_carrier_off(pbuddy_netdev); + rtw_netif_stop_queue(pbuddy_netdev); + } + #endif//CONFIG_CONCURRENT_MODE + // 0. Power off LED + rtw_led_control(padapter, LED_CTL_POWER_OFF); + // 1. stop thread + rtw_set_drv_stopped(padapter); /*for stop thread*/ + rtw_stop_drv_threads(padapter); + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + rtw_stop_drv_threads(padapter->pbuddy_adapter); + #endif /*CONFIG_CONCURRENT_MODE*/ + rtw_clr_drv_stopped(padapter); /*for 32k command*/ + + //#ifdef CONFIG_LPS + //rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN"); + //#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + // 2. disable interrupt + if (padapter->intf_stop) { + padapter->intf_stop(padapter); + } + + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { //free buddy adapter's resource + padapter->pbuddy_adapter->intf_stop(padapter->pbuddy_adapter); + } + #endif + + // 2.1 clean interupt + rtw_hal_clear_interrupt(padapter); +#endif //CONFIG_SDIO_HCI + + // 2.2 free irq + //sdio_free_irq(adapter_to_dvobj(padapter)); + if(padapter->intf_free_irq) + padapter->intf_free_irq(adapter_to_dvobj(padapter)); + + #ifdef CONFIG_RUNTIME_PORT_SWITCH + if (rtw_port_switch_chk(padapter)) { + DBG_871X(" ### PORT SWITCH ### \n"); + rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); + } + #endif + + poidparam.subcode = WOWLAN_ENABLE; + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam); + if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) + && check_fwstate(pmlmepriv, _FW_LINKED)) + { + DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, + pmlmepriv->cur_network.network.Ssid.Ssid, + MAC_ARG(pmlmepriv->cur_network.network.MacAddress), + pmlmepriv->cur_network.network.Ssid.SsidLength, + pmlmepriv->assoc_ssid.SsidLength); + + rtw_set_to_roam(padapter, 0); + } + } + + DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__); + + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) + { + DBG_871X_LEVEL(_drv_always_, "%s: fw_under_survey\n", __func__); + rtw_indicate_scan_done(padapter, 1); + clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + } + + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + set_channel_bwmode(padapter, ch, offset, bw); + } + #ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)){ //free buddy adapter's resource + rtw_suspend_free_assoc_resource(padapter->pbuddy_adapter); + } + #endif + + if(pwrpriv->wowlan_pno_enable) { + DBG_871X_LEVEL(_drv_always_, "%s: pno: %d\n", __func__, + pwrpriv->wowlan_pno_enable); +#ifdef CONFIG_FWLPS_IN_IPS + rtw_set_fw_in_ips_mode(padapter, _TRUE); +#endif + } + #ifdef CONFIG_LPS + else + rtw_set_ps_mode(padapter, PS_MODE_MAX, 0, 0, "WOWLAN"); + #endif //#ifdef CONFIG_LPS + + } + else + { + DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode=%d\n", __FUNCTION__, pwrpriv->wowlan_mode); + } + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); + return ret; +} +#endif //#ifdef CONFIG_WOWLAN + +#ifdef CONFIG_AP_WOWLAN +int rtw_suspend_ap_wow(_adapter *padapter) +{ + u8 ch, bw, offset; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev; + #endif + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct wowlan_ioctl_param poidparam; + u8 ps_mode; + int ret = _SUCCESS; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); + + pwrpriv->wowlan_ap_mode = _TRUE; + + DBG_871X("wowlan_ap_mode: %d\n", pwrpriv->wowlan_ap_mode); + + if(pnetdev) + rtw_netif_stop_queue(pnetdev); + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { + pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + if (pbuddy_netdev) + rtw_netif_stop_queue(pbuddy_netdev); + } + #endif//CONFIG_CONCURRENT_MODE + // 0. Power off LED + rtw_led_control(padapter, LED_CTL_POWER_OFF); + // 1. stop thread + rtw_set_drv_stopped(padapter); /*for stop thread*/ + rtw_stop_drv_threads(padapter); + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + rtw_stop_drv_threads(padapter->pbuddy_adapter); + #endif /* CONFIG_CONCURRENT_MODE */ + rtw_clr_drv_stopped(padapter); /*for 32k command*/ + +#ifdef CONFIG_SDIO_HCI + // 2. disable interrupt + rtw_hal_disable_interrupt(padapter); // It need wait for leaving 32K. + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { //free buddy adapter's resource + padapter->pbuddy_adapter->intf_stop(padapter->pbuddy_adapter); + } + #endif + + // 2.1 clean interupt + rtw_hal_clear_interrupt(padapter); +#endif //CONFIG_SDIO_HCI + + // 2.2 free irq + if(padapter->intf_free_irq) + padapter->intf_free_irq(adapter_to_dvobj(padapter)); + + #ifdef CONFIG_RUNTIME_PORT_SWITCH + if (rtw_port_switch_chk(padapter)) { + DBG_871X(" ### PORT SWITCH ### \n"); + rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL); + } + #endif + + poidparam.subcode = WOWLAN_AP_ENABLE; + rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); + + DBG_871X_LEVEL(_drv_always_, "%s: wowmode suspending\n", __func__); + +#ifdef CONFIG_CONCURRENT_MODE + if (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) { + if (rtw_get_ch_setting_union(padapter->pbuddy_adapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter->pbuddy_adapter), ch, bw, offset); + set_channel_bwmode(padapter->pbuddy_adapter, ch, offset, bw); + } + rtw_suspend_free_assoc_resource(padapter); + } else { + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + set_channel_bwmode(padapter, ch, offset, bw); + } + rtw_suspend_free_assoc_resource(padapter->pbuddy_adapter); + } +#else + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + set_channel_bwmode(padapter, ch, offset, bw); + } +#endif + +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, 0, "AP-WOWLAN"); +#endif + + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); + return ret; +} +#endif //#ifdef CONFIG_AP_WOWLAN + + +int rtw_suspend_normal(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + #endif + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + int ret = _SUCCESS; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); + if(pnetdev){ + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + } +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)){ + pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + netif_carrier_off(pbuddy_netdev); + rtw_netif_stop_queue(pbuddy_netdev); + } +#endif + + rtw_suspend_free_assoc_resource(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)){ + rtw_suspend_free_assoc_resource(padapter->pbuddy_adapter); + } +#endif + rtw_led_control(padapter, LED_CTL_POWER_OFF); + + if ((rtw_hal_check_ips_status(padapter) == _TRUE) + || (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)) + { + DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR #### driver in IPS ####ERROR###!!!\n", __FUNCTION__); + + } + +#ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)){ + rtw_dev_unload(padapter->pbuddy_adapter); + } +#endif + rtw_dev_unload(padapter); + + //sdio_deinit(adapter_to_dvobj(padapter)); + if(padapter->intf_deinit) + padapter->intf_deinit(adapter_to_dvobj(padapter)); + + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); + return ret; +} + +int rtw_suspend_common(_adapter *padapter) +{ + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + int ret = 0; + u32 start_time = rtw_get_current_time(); + + DBG_871X_LEVEL(_drv_always_, " suspend start\n"); + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + pdbgpriv->dbg_suspend_cnt++; + + pwrpriv->bInSuspend = _TRUE; + + while (pwrpriv->bips_processing == _TRUE) + rtw_msleep_os(1); + +#ifdef CONFIG_IOL_READ_EFUSE_MAP + if(!padapter->bup){ + u8 bMacPwrCtrlOn = _FALSE; + rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + if(bMacPwrCtrlOn) + rtw_hal_power_off(padapter); + } +#endif + + if ((!padapter->bup) || RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s bup=%d bDriverStopped=%s bSurpriseRemoved = %s\n", __func__ + , padapter->bup + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False"); + pdbgpriv->dbg_suspend_error_cnt++; + goto exit; + } + rtw_ps_deny(padapter, PS_DENY_SUSPEND); + + rtw_cancel_all_timer(padapter); +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter){ + rtw_cancel_all_timer(padapter->pbuddy_adapter); + } +#endif // CONFIG_CONCURRENT_MODE + + LeaveAllPowerSaveModeDirect(padapter); + + rtw_stop_cmd_thread(padapter); + +#ifdef CONFIG_BT_COEXIST + // wait for the latest FW to remove this condition. + if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { + rtw_btcoex_SuspendNotify(padapter, 0); + DBG_871X("WIFI_AP_STATE\n"); +#ifdef CONFIG_CONCURRENT_MODE + } else if (check_buddy_fwstate(padapter, WIFI_AP_STATE)) { + rtw_btcoex_SuspendNotify(padapter, 0); + DBG_871X("P2P_ROLE_GO\n"); +#endif //CONFIG_CONCURRENT_MODE + } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) { + rtw_btcoex_SuspendNotify(padapter, 1); + DBG_871X("STATION\n"); + } +#endif // CONFIG_BT_COEXIST + + rtw_ps_deny_cancel(padapter, PS_DENY_SUSPEND); + + if (check_fwstate(pmlmepriv,WIFI_STATION_STATE) == _TRUE +#ifdef CONFIG_CONCURRENT_MODE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _FALSE +#endif + ) { + #ifdef CONFIG_WOWLAN + if (check_fwstate(pmlmepriv, _FW_LINKED)) { + pwrpriv->wowlan_mode = _TRUE; + } else if (pwrpriv->wowlan_pno_enable == _TRUE) { + pwrpriv->wowlan_mode |= pwrpriv->wowlan_pno_enable; + } + + #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); + + #else //CONFIG_WOWLAN + rtw_suspend_normal(padapter); + #endif //CONFIG_WOWLAN + } else if (check_fwstate(pmlmepriv,WIFI_AP_STATE) == _TRUE +#ifdef CONFIG_CONCURRENT_MODE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _FALSE +#endif + ) { + #ifdef CONFIG_AP_WOWLAN + rtw_suspend_ap_wow(padapter); + #else + rtw_suspend_normal(padapter); + #endif //CONFIG_AP_WOWLAN +#ifdef CONFIG_CONCURRENT_MODE + } else if (check_fwstate(pmlmepriv,WIFI_STATION_STATE) == _TRUE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) { + #ifdef CONFIG_AP_WOWLAN + rtw_suspend_ap_wow(padapter); + #else + rtw_suspend_normal(padapter); + #endif //CONFIG_AP_WOWLAN +#endif + } else { + rtw_suspend_normal(padapter); + } + + + DBG_871X_LEVEL(_drv_always_, "rtw suspend success in %d ms\n", + rtw_get_passing_time_ms(start_time)); + +exit: + DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ + , ret, rtw_get_passing_time_ms(start_time)); + + return ret; +} + +#ifdef CONFIG_WOWLAN +int rtw_resume_process_wow(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct net_device *pnetdev = padapter->pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev; + #endif + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct wowlan_ioctl_param poidparam; + struct sta_info *psta = NULL; + int ret = _SUCCESS; +_func_enter_; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); + + if (padapter) { + pnetdev = padapter->pnetdev; + pwrpriv = adapter_to_pwrctl(padapter); + } else { + pdbgpriv->dbg_resume_error_cnt++; + ret = -1; + goto exit; + } + + if (RTW_CANNOT_RUN(padapter)) { + DBG_871X("%s pdapter %p bDriverStopped %s bSurpriseRemoved %s\n" + , __func__, padapter + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False"); + goto exit; + } + +#ifdef CONFIG_PNO_SUPPORT + pwrpriv->pno_in_resume = _TRUE; +#ifdef CONFIG_FWLPS_IN_IPS + if(pwrpriv->wowlan_pno_enable) + rtw_set_fw_in_ips_mode(padapter, _FALSE); +#endif //CONFIG_FWLPS_IN_IPS +#endif//CONFIG_PNO_SUPPORT + + if (pwrpriv->wowlan_mode == _TRUE){ +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "WOWLAN"); +#endif //CONFIG_LPS + + pwrpriv->bFwCurrentInPSMode = _FALSE; + +#ifdef CONFIG_SDIO_HCI + if (padapter->intf_stop) { + padapter->intf_stop(padapter); + } + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { //free buddy adapter's resource + padapter->pbuddy_adapter->intf_stop(padapter->pbuddy_adapter); + } + #endif + + rtw_hal_clear_interrupt(padapter); +#endif //CONFIG_SDIO_HCI + + //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) { + if((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)){ + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__)); + goto exit; + } + + //Disable WOW, set H2C command + poidparam.subcode=WOWLAN_DISABLE; + rtw_hal_set_hwreg(padapter,HW_VAR_WOWLAN,(u8 *)&poidparam); + + #ifdef CONFIG_CONCURRENT_MODE + rtw_reset_drv_sw(padapter->pbuddy_adapter); + #endif + + psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv)); + if (psta) { + set_sta_rate(padapter, psta); + } + + + rtw_clr_drv_stopped(padapter); + DBG_871X("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter)?"True":"False"); + rtw_start_drv_threads(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->pbuddy_adapter) + rtw_start_drv_threads(padapter->pbuddy_adapter); +#endif /* CONFIG_CONCURRENT_MODE*/ + + if (padapter->intf_start) { + padapter->intf_start(padapter); + } + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { //free buddy adapter's resource + padapter->pbuddy_adapter->intf_start(padapter->pbuddy_adapter); + } + + if (rtw_buddy_adapter_up(padapter)) { + pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + + if(pbuddy_netdev){ + netif_device_attach(pbuddy_netdev); + netif_carrier_on(pbuddy_netdev); + } + } + #endif + + // start netif queue + if (pnetdev) { + rtw_netif_wake_queue(pnetdev); + } + } + else{ + + DBG_871X_LEVEL(_drv_always_, "%s: ### ERROR ### wowlan_mode=%d\n", __FUNCTION__, pwrpriv->wowlan_mode); + } + + if( padapter->pid[1]!=0) { + DBG_871X("pid[1]:%d\n",padapter->pid[1]); + rtw_signal_process(padapter->pid[1], SIGUSR2); + } + + if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) { + if (pwrpriv->wowlan_wake_reason == FWDecisionDisconnect || + pwrpriv->wowlan_wake_reason == Rx_DisAssoc || + pwrpriv->wowlan_wake_reason == Rx_DeAuth) { + + DBG_871X("%s: disconnect reason: %02x\n", __func__, + pwrpriv->wowlan_wake_reason); + rtw_indicate_disconnect(padapter); + + rtw_sta_media_status_rpt(padapter, + rtw_get_stainfo(&padapter->stapriv, + get_bssid(&padapter->mlmepriv)), 0); + + rtw_free_assoc_resources(padapter, 1); + pmlmeinfo->state = WIFI_FW_NULL_STATE; + + } else { + DBG_871X("%s: do roaming\n", __func__); + rtw_roaming(padapter, NULL); + } + } + + if (pwrpriv->wowlan_wake_reason == FWDecisionDisconnect) { + rtw_lock_ext_suspend_timeout(2000); + } + + if (pwrpriv->wowlan_wake_reason == Rx_GTK || + pwrpriv->wowlan_wake_reason == Rx_DisAssoc || + pwrpriv->wowlan_wake_reason == Rx_DeAuth) { + rtw_lock_ext_suspend_timeout(8000); + } + + if (pwrpriv->wowlan_wake_reason == RX_PNOWakeUp) { +#ifdef CONFIG_IOCTL_CFG80211 + cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, + GFP_ATOMIC); +#endif + rtw_lock_ext_suspend_timeout(10000); + } + + if (pwrpriv->wowlan_mode == _TRUE) { + pwrpriv->bips_processing = _FALSE; + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); +#ifndef CONFIG_IPS_CHECK_IN_WD + rtw_set_pwr_state_check_timer(pwrpriv); +#endif + } else { + DBG_871X_LEVEL(_drv_always_, "do not reset timer\n"); + } + + pwrpriv->wowlan_mode =_FALSE; + + // Power On LED + rtw_hal_sw_led_init(padapter); + if(pwrpriv->wowlan_wake_reason == Rx_DisAssoc || + pwrpriv->wowlan_wake_reason == Rx_DeAuth || + pwrpriv->wowlan_wake_reason == FWDecisionDisconnect) + rtw_led_control(padapter, LED_CTL_NO_LINK); + else + rtw_led_control(padapter, LED_CTL_LINK); + + //clean driver side wake up reason. + pwrpriv->wowlan_wake_reason = 0; + +exit: + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); +_func_exit_; + return ret; +} +#endif //#ifdef CONFIG_WOWLAN + +#ifdef CONFIG_AP_WOWLAN +int rtw_resume_process_ap_wow(_adapter *padapter) +{ + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev; + #endif + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + struct wowlan_ioctl_param poidparam; + struct sta_info *psta = NULL; + int ret = _SUCCESS; + u8 ch, bw, offset; +_func_enter_; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); + + if (padapter) { + pnetdev = padapter->pnetdev; + pwrpriv = adapter_to_pwrctl(padapter); + } else { + pdbgpriv->dbg_resume_error_cnt++; + ret = -1; + goto exit; + } + + +#ifdef CONFIG_LPS + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "AP-WOWLAN"); +#endif //CONFIG_LPS + + pwrpriv->bFwCurrentInPSMode = _FALSE; + + rtw_hal_disable_interrupt(padapter); + + rtw_hal_clear_interrupt(padapter); + + //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) { + if((padapter->intf_alloc_irq) && (padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)){ + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__)); + goto exit; + } + + //Disable WOW, set H2C command + poidparam.subcode = WOWLAN_AP_DISABLE; + rtw_hal_set_hwreg(padapter, HW_VAR_WOWLAN, (u8 *)&poidparam); + pwrpriv->wowlan_ap_mode = _FALSE; + + rtw_clr_drv_stopped(padapter); + DBG_871X("%s: wowmode resuming, DriverStopped:%s\n", __func__, rtw_is_drv_stopped(padapter)?"True":"False"); + rtw_start_drv_threads(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) + rtw_start_drv_threads(padapter->pbuddy_adapter); +#endif /* CONFIG_CONCURRENT_MODE */ + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { + if (rtw_get_ch_setting_union(padapter->pbuddy_adapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter->pbuddy_adapter), ch, bw, offset); + set_channel_bwmode(padapter->pbuddy_adapter, ch, offset, bw); + } + } else { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + set_channel_bwmode(padapter, ch, offset, bw); + rtw_reset_drv_sw(padapter->pbuddy_adapter); + } +#else + if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) { + DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n", + FUNC_ADPT_ARG(padapter), ch, bw, offset); + set_channel_bwmode(padapter, ch, offset, bw); + } +#endif + + if (padapter->intf_start) { + padapter->intf_start(padapter); + } + + #ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { //free buddy adapter's resource + padapter->pbuddy_adapter->intf_start(padapter->pbuddy_adapter); + } + #endif + +#ifdef CONFIG_CONCURRENT_MODE + if (rtw_buddy_adapter_up(padapter)) { + pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + if(pbuddy_netdev){ + rtw_netif_wake_queue(pbuddy_netdev); + } + } +#endif + + // start netif queue + if (pnetdev) { + rtw_netif_wake_queue(pnetdev); + } + + if( padapter->pid[1]!=0) { + DBG_871X("pid[1]:%d\n",padapter->pid[1]); + rtw_signal_process(padapter->pid[1], SIGUSR2); + } + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + //rtw_unlock_suspend(); + #endif //CONFIG_RESUME_IN_WORKQUEUE + + if (pwrpriv->wowlan_wake_reason == AP_WakeUp) + rtw_lock_ext_suspend_timeout(8000); + + pwrpriv->bips_processing = _FALSE; + _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); +#ifndef CONFIG_IPS_CHECK_IN_WD + rtw_set_pwr_state_check_timer(pwrpriv); +#endif + //clean driver side wake up reason. + pwrpriv->wowlan_wake_reason = 0; + + // Power On LED + rtw_hal_sw_led_init(padapter); + rtw_led_control(padapter, LED_CTL_LINK); +exit: + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); +_func_exit_; + return ret; +} +#endif //#ifdef CONFIG_APWOWLAN + +int rtw_resume_process_normal(_adapter *padapter) +{ + struct net_device *pnetdev; + #ifdef CONFIG_CONCURRENT_MODE + struct net_device *pbuddy_netdev; + #endif + struct pwrctrl_priv *pwrpriv; + struct mlme_priv *pmlmepriv; + struct dvobj_priv *psdpriv; + struct debug_priv *pdbgpriv; + + int ret = _SUCCESS; +_func_enter_; + + if (!padapter) { + ret = -1; + goto exit; + } + + pnetdev = padapter->pnetdev; + pwrpriv = adapter_to_pwrctl(padapter); + pmlmepriv = &padapter->mlmepriv; + psdpriv = padapter->dvobj; + pdbgpriv = &psdpriv->drv_dbg; + + DBG_871X("==> "FUNC_ADPT_FMT" entry....\n", FUNC_ADPT_ARG(padapter)); + // interface init + //if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS) + if((padapter->intf_init)&& (padapter->intf_init(adapter_to_dvobj(padapter)) != _SUCCESS)) + { + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__)); + goto exit; + } + rtw_hal_disable_interrupt(padapter); + //if (sdio_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) + if ((padapter->intf_alloc_irq)&&(padapter->intf_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS)) + { + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: sdio_alloc_irq Failed!!\n", __FUNCTION__)); + goto exit; + } + + rtw_reset_drv_sw(padapter); + #ifdef CONFIG_CONCURRENT_MODE + rtw_reset_drv_sw(padapter->pbuddy_adapter); + #endif + + pwrpriv->bkeepfwalive = _FALSE; + + DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive); + if(pm_netdev_open(pnetdev,_TRUE) != 0) { + ret = -1; + pdbgpriv->dbg_resume_error_cnt++; + goto exit; + } + + netif_device_attach(pnetdev); + netif_carrier_on(pnetdev); + + #ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)){ + pbuddy_netdev = padapter->pbuddy_adapter->pnetdev; + + netif_device_attach(pbuddy_netdev); + netif_carrier_on(pbuddy_netdev); + } + #endif + + + if( padapter->pid[1]!=0) { + DBG_871X("pid[1]:%d\n",padapter->pid[1]); + rtw_signal_process(padapter->pid[1], SIGUSR2); + } + + + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + + if (rtw_chk_roam_flags(padapter, RTW_ROAM_ON_RESUME)) + rtw_roaming(padapter, NULL); + + } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + rtw_ap_restore_network(padapter); + } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + } else { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv)); + } + + #ifdef CONFIG_CONCURRENT_MODE + if(rtw_buddy_adapter_up(padapter)) + { + _adapter *buddy = padapter->pbuddy_adapter; + struct mlme_priv *buddy_mlme = &padapter->pbuddy_adapter->mlmepriv; + if (check_fwstate(buddy_mlme, WIFI_STATION_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(buddy), get_fwstate(buddy_mlme)); + + if (rtw_chk_roam_flags(buddy, RTW_ROAM_ON_RESUME)) + rtw_roaming(buddy, NULL); + + } else if (check_fwstate(buddy_mlme, WIFI_AP_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(buddy), get_fwstate(buddy_mlme)); + rtw_ap_restore_network(buddy); + } else if (check_fwstate(buddy_mlme, WIFI_ADHOC_STATE)) { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(buddy), get_fwstate(buddy_mlme)); + } else { + DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(buddy), get_fwstate(buddy_mlme)); + } + } + #endif + +#ifdef CONFIG_RESUME_IN_WORKQUEUE + //rtw_unlock_suspend(); +#endif //CONFIG_RESUME_IN_WORKQUEUE + DBG_871X("<== "FUNC_ADPT_FMT" exit....\n", FUNC_ADPT_ARG(padapter)); + +exit: +_func_exit_; + return ret; +} + +int rtw_resume_common(_adapter *padapter) +{ + int ret = 0; + u32 start_time = rtw_get_current_time(); + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + _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); + + if (check_fwstate(pmlmepriv,WIFI_STATION_STATE) == _TRUE +#ifdef CONFIG_CONCURRENT_MODE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _FALSE +#endif + ) { + #ifdef CONFIG_WOWLAN + if (pwrpriv->wowlan_mode == _TRUE) + rtw_resume_process_wow(padapter); + else + rtw_resume_process_normal(padapter); + #else + rtw_resume_process_normal(padapter); + #endif + + } else if (check_fwstate(pmlmepriv,WIFI_AP_STATE) == _TRUE +#ifdef CONFIG_CONCURRENT_MODE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _FALSE +#endif + ) { + #ifdef CONFIG_AP_WOWLAN + rtw_resume_process_ap_wow(padapter); + #else + rtw_resume_process_normal(padapter); + #endif //CONFIG_AP_WOWLAN +#ifdef CONFIG_CONCURRENT_MODE + } else if (check_fwstate(pmlmepriv,WIFI_STATION_STATE) == _TRUE + && check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) { + #ifdef CONFIG_AP_WOWLAN + rtw_resume_process_ap_wow(padapter); + #else + rtw_resume_process_normal(padapter); + #endif //CONFIG_AP_WOWLAN +#endif + } else { + rtw_resume_process_normal(padapter); + } + + #ifdef CONFIG_BT_COEXIST + rtw_btcoex_SuspendNotify(padapter, 0); + #endif // CONFIG_BT_COEXIST + + if (pwrpriv) { + pwrpriv->bInSuspend = _FALSE; + #ifdef CONFIG_PNO_SUPPORT + pwrpriv->pno_in_resume = _FALSE; + #endif + } + DBG_871X_LEVEL(_drv_always_, "%s:%d in %d ms\n", __FUNCTION__ ,ret, + rtw_get_passing_time_ms(start_time)); + + _func_exit_; + + 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, bool 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, bool isOutput) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_config_gpio(adapter,gpio_num,isOutput); +} +EXPORT_SYMBOL(rtw_config_gpio); +int rtw_register_gpio_interrupt(struct net_device *netdev, int gpio_num, void(*callback)(u8 level)) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_register_gpio_interrupt(adapter,gpio_num,callback); +} +EXPORT_SYMBOL(rtw_register_gpio_interrupt); + +int rtw_disable_gpio_interrupt(struct net_device *netdev, int gpio_num) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(netdev); + return rtw_hal_disable_gpio_interrupt(adapter,gpio_num); +} +EXPORT_SYMBOL(rtw_disable_gpio_interrupt); + +#endif //#ifdef CONFIG_GPIO_API + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/recv_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/recv_linux.c new file mode 100644 index 00000000..e37f0148 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/recv_linux.c @@ -0,0 +1,815 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ +#define _RECV_OSDEP_C_ + +#include + +int rtw_os_alloc_recvframe(_adapter *padapter, union recv_frame *precvframe, u8 *pdata, _pkt *pskb) +{ + int res = _SUCCESS; + u8 shift_sz = 0; + u32 skb_len, alloc_sz; + _pkt *pkt_copy = NULL; + struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; + + + if(pdata == NULL) + { + precvframe->u.hdr.pkt = NULL; + res = _FAIL; + return res; + } + + + // Modified by Albert 20101213 + // For 8 bytes IP header alignment. + shift_sz = pattrib->qos ? 6:0;// Qos data, wireless lan header length is 26 + + skb_len = pattrib->pkt_len; + + // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. + // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) + { + //alloc_sz = 1664; //1664 is 128 alignment. + alloc_sz = (skb_len <= 1650) ? 1664:(skb_len + 14); + } + else + { + alloc_sz = skb_len; + // 6 is for IP header 8 bytes alignment in QoS packet case. + // 8 is for skb->data 4 bytes alignment. + alloc_sz += 14; + } + + pkt_copy = rtw_skb_alloc(alloc_sz); + + if(pkt_copy) + { + pkt_copy->dev = padapter->pnetdev; + precvframe->u.hdr.pkt = pkt_copy; + precvframe->u.hdr.rx_head = pkt_copy->data; + precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; + skb_reserve(pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data) & 7 ));//force pkt_copy->data at 8-byte alignment address + skb_reserve(pkt_copy, shift_sz);//force ip_hdr at 8-byte alignment address according to shift_sz. + _rtw_memcpy(pkt_copy->data, pdata, skb_len); + precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; + } + else + { +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + DBG_871X("%s:can not allocate memory for skb copy\n", __FUNCTION__); + + precvframe->u.hdr.pkt = NULL; + + //rtw_free_recvframe(precvframe, pfree_recv_queue); + //goto _exit_recvbuf2recvframe; + + res = _FAIL; +#else + if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) + { + DBG_871X("%s: alloc_skb fail , drop frag frame \n", __FUNCTION__); + //rtw_free_recvframe(precvframe, pfree_recv_queue); + res = _FAIL; + goto exit_rtw_os_recv_resource_alloc; + } + + if(pskb == NULL) + { + res = _FAIL; + goto exit_rtw_os_recv_resource_alloc; + } + + precvframe->u.hdr.pkt = rtw_skb_clone(pskb); + if(precvframe->u.hdr.pkt) + { + precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pdata; + precvframe->u.hdr.rx_end = pdata + alloc_sz; + } + else + { + DBG_871X("%s: rtw_skb_clone fail\n", __FUNCTION__); + //rtw_free_recvframe(precvframe, pfree_recv_queue); + //goto _exit_recvbuf2recvframe; + res = _FAIL; + } +#endif + } + +exit_rtw_os_recv_resource_alloc: + + return res; + +} + +void rtw_os_free_recvframe(union recv_frame *precvframe) +{ + if(precvframe->u.hdr.pkt) + { + rtw_skb_free(precvframe->u.hdr.pkt);//free skb by driver + + precvframe->u.hdr.pkt = NULL; + } +} + +//init os related resource in struct recv_priv +int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter) +{ + int res=_SUCCESS; + + return res; +} + +//alloc os related resource in union recv_frame +int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe) +{ + int res=_SUCCESS; + + precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL; + + return res; +} + +//free os related resource in union recv_frame +void rtw_os_recv_resource_free(struct recv_priv *precvpriv) +{ + sint i; + union recv_frame *precvframe; + precvframe = (union recv_frame*) precvpriv->precv_frame_buf; + + for(i=0; i < NR_RECVFRAME; i++) + { + if(precvframe->u.hdr.pkt) + { + rtw_skb_free(precvframe->u.hdr.pkt);//free skb by driver + precvframe->u.hdr.pkt = NULL; + } + precvframe++; + } +} + +//alloc os related resource in struct recv_buf +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) +{ + int res=_SUCCESS; + +#ifdef CONFIG_USB_HCI + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + precvbuf->irp_pending = _FALSE; + precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); + if(precvbuf->purb == NULL){ + res = _FAIL; + } + + precvbuf->pskb = NULL; + + precvbuf->pallocated_buf = precvbuf->pbuf = NULL; + + precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL; + + precvbuf->transfer_len = 0; + + precvbuf->len = 0; + + #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr); + precvbuf->pbuf = precvbuf->pallocated_buf; + if(precvbuf->pallocated_buf == NULL) + return _FAIL; + #endif //CONFIG_USE_USB_BUFFER_ALLOC_RX + +#endif //CONFIG_USB_HCI + + return res; +} + +//free os related resource in struct recv_buf +int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf) +{ + int ret = _SUCCESS; + +#ifdef CONFIG_USB_HCI + +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX + + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + rtw_usb_buffer_free(pusbd, (size_t)precvbuf->alloc_sz, precvbuf->pallocated_buf, precvbuf->dma_transfer_addr); + precvbuf->pallocated_buf = NULL; + precvbuf->dma_transfer_addr = 0; + +#endif //CONFIG_USE_USB_BUFFER_ALLOC_RX + + if(precvbuf->purb) + { + //usb_kill_urb(precvbuf->purb); + usb_free_urb(precvbuf->purb); + } + +#endif //CONFIG_USB_HCI + + + if(precvbuf->pskb) + { +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + if(rtw_free_skb_premem(precvbuf->pskb)!=0) +#endif + rtw_skb_free(precvbuf->pskb); + } + return ret; + +} + +_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata) +{ + u16 eth_type; + u8 *data_ptr; + _pkt *sub_skb; + struct rx_pkt_attrib *pattrib; + + pattrib = &prframe->u.hdr.attrib; + +#ifdef CONFIG_SKB_COPY + sub_skb = rtw_skb_alloc(nSubframe_Length + 12); + if(sub_skb) + { + skb_reserve(sub_skb, 12); + data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); + _rtw_memcpy(data_ptr, (pdata + ETH_HLEN), nSubframe_Length); + } + else +#endif // CONFIG_SKB_COPY + { + sub_skb = rtw_skb_clone(prframe->u.hdr.pkt); + if(sub_skb) + { + sub_skb->data = pdata + ETH_HLEN; + sub_skb->len = nSubframe_Length; + skb_set_tail_pointer(sub_skb, nSubframe_Length); + } + else + { + DBG_871X("%s(): rtw_skb_clone() Fail!!!\n",__FUNCTION__); + return NULL; + } + } + + eth_type = RTW_GET_BE16(&sub_skb->data[6]); + + if (sub_skb->len >= 8 && + ((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) && + eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || + _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE) )) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + _rtw_memcpy(skb_push(sub_skb, 2), &len, 2); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN); + _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN); + } + + return sub_skb; +} + +#ifdef DBG_UDP_PKT_LOSE_11AC +#define PAYLOAD_LEN_LOC_OF_IP_HDR 0x10 /*ethernet payload length location of ip header (DA+SA+eth_type+(version&hdr_len)) */ +#endif + +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 + int ret; + + /* Indicat the packets to upper layer */ + if (pkt) { + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) + { + _pkt *pskb2=NULL; + struct sta_info *psta = NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + int bmcast = IS_MCAST(pattrib->dst); + + //DBG_871X("bmcast=%d\n", bmcast); + + if (_rtw_memcmp(pattrib->dst, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE) + { + //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); + + if(bmcast) + { + psta = rtw_get_bcmc_stainfo(padapter); + pskb2 = rtw_skb_clone(pkt); + } else { + psta = rtw_get_stainfo(pstapriv, pattrib->dst); + } + + if(psta) + { + struct net_device *pnetdev= (struct net_device*)padapter->pnetdev; + + //DBG_871X("directly forwarding to the rtw_xmit_entry\n"); + + //skb->ip_summed = CHECKSUM_NONE; + pkt->dev = pnetdev; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt)); +#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) + + _rtw_xmit_entry(pkt, pnetdev); + + if(bmcast && (pskb2 != NULL) ) { + pkt = pskb2; + DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast); + } else { + DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward); + return; + } + } + } + else// to APself + { + //DBG_871X("to APSelf\n"); + DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self); + } + } + +#ifdef CONFIG_BR_EXT + // Insert NAT2.5 RX here! +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + br_port = padapter->pnetdev->br_port; +#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + rcu_read_lock(); + br_port = rcu_dereference(padapter->pnetdev->rx_handler_data); + rcu_read_unlock(); +#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + + + if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) ) + { + int nat25_handle_frame(_adapter *priv, struct sk_buff *skb); + if (nat25_handle_frame(padapter, pkt) == -1) { + //priv->ext_stats.rx_data_drops++; + //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); + //return FAIL; + +#if 1 + // bypass this frame to upper layer!! +#else + rtw_skb_free(sub_skb); + continue; +#endif + } + } +#endif // CONFIG_BR_EXT + if( precvpriv->sink_udpport > 0) + rtw_sink_rtp_seq_dbg(padapter,pkt); +#ifdef DBG_UDP_PKT_LOSE_11AC + /* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header , + * we have to check ethernet type , so this debug must be print before eth_type_trans + */ + if (*((unsigned short *)(pkt->data+ETH_ALEN*2)) == htons(ETH_P_ARP)) { + /* ARP Payload length will be 42bytes or 42+18(tailer)=60bytes*/ + if (pkt->len != 42 && pkt->len != 60) + DBG_871X("Error !!%s,ARP Payload length %u not correct\n" , __func__ , pkt->len); + } else if (*((unsigned short *)(pkt->data+ETH_ALEN*2)) == htons(ETH_P_IP)) { + if (be16_to_cpu(*((u16 *)(pkt->data+PAYLOAD_LEN_LOC_OF_IP_HDR))) != (pkt->len)-ETH_HLEN) { + DBG_871X("Error !!%s,Payload length not correct\n" , __func__); + DBG_871X("%s, IP header describe Total length=%u\n" , __func__ , be16_to_cpu(*((u16 *)(pkt->data+PAYLOAD_LEN_LOC_OF_IP_HDR)))); + DBG_871X("%s, Pkt real length=%u\n" , __func__ , (pkt->len)-ETH_HLEN); + } + } +#endif + /* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header */ + pkt->protocol = eth_type_trans(pkt, padapter->pnetdev); + pkt->dev = padapter->pnetdev; + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX + if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { + pkt->ip_summed = CHECKSUM_UNNECESSARY; + } else { + pkt->ip_summed = CHECKSUM_NONE; + } +#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ + pkt->ip_summed = CHECKSUM_NONE; +#endif //CONFIG_TCP_CSUM_OFFLOAD_RX + + ret = rtw_netif_rx(padapter->pnetdev, pkt); + if (ret == NET_RX_SUCCESS) + DBG_COUNTER(padapter->rx_logs.os_netif_ok); + else + DBG_COUNTER(padapter->rx_logs.os_netif_err); + } +} + +void rtw_handle_tkip_mic_err(_adapter *padapter, struct sta_info *sta, u8 bgroup) +{ +#ifdef CONFIG_IOCTL_CFG80211 + enum nl80211_key_type key_type = 0; +#endif + union iwreq_data wrqu; + struct iw_michaelmicfailure ev; + struct mlme_priv* pmlmepriv = &padapter->mlmepriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + u32 cur_time = 0; + + if( psecuritypriv->last_mic_err_time == 0 ) + { + psecuritypriv->last_mic_err_time = rtw_get_current_time(); + } + else + { + cur_time = rtw_get_current_time(); + + if( cur_time - psecuritypriv->last_mic_err_time < 60*HZ ) + { + psecuritypriv->btkip_countermeasure = _TRUE; + psecuritypriv->last_mic_err_time = 0; + psecuritypriv->btkip_countermeasure_time = cur_time; + } + else + { + psecuritypriv->last_mic_err_time = rtw_get_current_time(); + } + } + +#ifdef CONFIG_IOCTL_CFG80211 + if ( bgroup ) + { + key_type |= NL80211_KEYTYPE_GROUP; + } + else + { + key_type |= NL80211_KEYTYPE_PAIRWISE; + } + + cfg80211_michael_mic_failure(padapter->pnetdev, sta->hwaddr, key_type, -1, NULL, GFP_ATOMIC); +#endif + + _rtw_memset( &ev, 0x00, sizeof( ev ) ); + if ( bgroup ) + { + ev.flags |= IW_MICFAILURE_GROUP; + } + else + { + ev.flags |= IW_MICFAILURE_PAIRWISE; + } + + ev.src_addr.sa_family = ARPHRD_ETHER; + _rtw_memcpy(ev.src_addr.sa_data, sta->hwaddr, ETH_ALEN); + + _rtw_memset( &wrqu, 0x00, sizeof( wrqu ) ); + wrqu.data.length = sizeof( ev ); + +#ifndef CONFIG_IOCTL_CFG80211 + wireless_send_event( padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, (char*) &ev ); +#endif +} + +void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame) +{ +#ifdef CONFIG_HOSTAPD_MLME + _pkt *skb; + struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; + struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev; + + RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("+rtw_hostapd_mlme_rx\n")); + + skb = precv_frame->u.hdr.pkt; + + if (skb == NULL) + return; + + skb->data = precv_frame->u.hdr.rx_data; + skb->tail = precv_frame->u.hdr.rx_tail; + skb->len = precv_frame->u.hdr.len; + + //pskb_copy = rtw_skb_copy(skb); +// if(skb == NULL) goto _exit; + + skb->dev = pmgnt_netdev; + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + //skb->protocol = __constant_htons(0x0019); /*ETH_P_80211_RAW*/ + skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/ + + //DBG_871X("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len); + + //skb->mac.raw = skb->data; + skb_reset_mac_header(skb); + + //skb_pull(skb, 24); + _rtw_memset(skb->cb, 0, sizeof(skb->cb)); + + rtw_netif_rx(pmgnt_netdev, skb); + + precv_frame->u.hdr.pkt = NULL; // set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx() +#endif +} + +#ifdef CONFIG_AUTO_AP_MODE +static void rtw_os_ksocket_send(_adapter *padapter, union recv_frame *precv_frame) +{ + _pkt *skb = precv_frame->u.hdr.pkt; + struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; + struct sta_info *psta = precv_frame->u.hdr.psta; + + DBG_871X("eth rx: got eth_type=0x%x\n", pattrib->eth_type); + + if (psta && psta->isrc && psta->pid>0) + { + u16 rx_pid; + + rx_pid = *(u16*)(skb->data+ETH_HLEN); + + DBG_871X("eth rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n", + rx_pid, MAC_ARG(psta->hwaddr), psta->pid); + + if(rx_pid == psta->pid) + { + int i; + u16 len = *(u16*)(skb->data+ETH_HLEN+2); + //u16 ctrl_type = *(u16*)(skb->data+ETH_HLEN+4); + + //DBG_871X("eth, RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type); + DBG_871X("eth, RC: len=0x%x\n", len); + + for(i=0;idata+ETH_HLEN+4+i)); + //DBG_871X("0x%x\n", *(skb->data+ETH_HLEN+6+i)); + + DBG_871X("eth, RC-end\n"); + +#if 0 + //send_sz = ksocket_send(padapter->ksock_send, &padapter->kaddr_send, (skb->data+ETH_HLEN+2), len); + rtw_recv_ksocket_send_cmd(padapter, (skb->data+ETH_HLEN+2), len); + + //DBG_871X("ksocket_send size=%d\n", send_sz); +#endif + } + + } + +} +#endif //CONFIG_AUTO_AP_MODE + +int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame) +{ + int ret = _FAIL; + struct recv_priv *precvpriv; + _queue *pfree_recv_queue; + _pkt *skb; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct rx_pkt_attrib *pattrib; + + if (NULL == precv_frame) + goto _recv_drop; + + pattrib = &precv_frame->u.hdr.attrib; + precvpriv = &(padapter->recvpriv); + pfree_recv_queue = &(precvpriv->free_recv_queue); + + skb = precv_frame->u.hdr.pkt; + if (skb == NULL) { + DBG_871X("%s :skb==NULL something wrong!!!!\n", __func__); + goto _recv_drop; + } + + skb->data = precv_frame->u.hdr.rx_data; + skb_set_tail_pointer(skb, precv_frame->u.hdr.len); + skb->len = precv_frame->u.hdr.len; + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(0x0019); /* ETH_P_80211_RAW */ + + rtw_netif_rx(padapter->pnetdev, skb); + + /* pointers to NULL before rtw_free_recvframe() */ + precv_frame->u.hdr.pkt = NULL; + + ret = _SUCCESS; + +_recv_drop: + + /* enqueue back to free_recv_queue */ + if (precv_frame) + rtw_free_recvframe(precv_frame, pfree_recv_queue); + + return ret; + +} + +int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame) +{ + struct recv_priv *precvpriv; + _queue *pfree_recv_queue; + _pkt *skb; + struct mlme_priv*pmlmepriv = &padapter->mlmepriv; + 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); + +#ifdef CONFIG_DRVEXT_MODULE + if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS) + { + goto _recv_indicatepkt_drop; + } +#endif + +#ifdef CONFIG_WAPI_SUPPORT + if (rtw_wapi_check_for_drop(padapter,precv_frame)) + { + WAPI_TRACE(WAPI_ERR, "%s(): Rx Reorder Drop case!!\n", __FUNCTION__); + goto _recv_indicatepkt_drop; + } +#endif + + skb = precv_frame->u.hdr.pkt; + if(skb == NULL) + { + RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n")); + goto _recv_indicatepkt_drop; + } + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n")); + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data)); + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len)); + + skb->data = precv_frame->u.hdr.rx_data; + + skb_set_tail_pointer(skb, precv_frame->u.hdr.len); + + skb->len = precv_frame->u.hdr.len; + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len)); + + if (pattrib->eth_type == 0x888e) + DBG_871X_LEVEL(_drv_always_, "recv eapol packet\n"); + +#ifdef CONFIG_AUTO_AP_MODE +#if 1 //for testing +#if 1 + if (0x8899 == pattrib->eth_type) + { + rtw_os_ksocket_send(padapter, precv_frame); + + //goto _recv_indicatepkt_drop; + } +#else + if (0x8899 == pattrib->eth_type) + { + rtw_auto_ap_mode_rx(padapter, precv_frame); + + goto _recv_indicatepkt_end; + } +#endif +#endif +#endif //CONFIG_AUTO_AP_MODE + + /* TODO: move to core */ + { + _pkt *pkt = skb; + struct ethhdr *etherhdr = (struct ethhdr *)pkt->data; + struct sta_info *sta = precv_frame->u.hdr.psta; + + if (!sta) + goto bypass_session_tracker; + + if (ntohs(etherhdr->h_proto) == ETH_P_IP) { + u8 *ip = pkt->data + 14; + + if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */ + && rtw_st_ctl_chk_reg_s_proto(&sta->st_ctl, 0x06) == _TRUE + ) { + u8 *tcp = ip + GET_IPV4_IHL(ip) * 4; + + if (rtw_st_ctl_chk_reg_rule(&sta->st_ctl, padapter, IPV4_DST(ip), TCP_DST(tcp), IPV4_SRC(ip), TCP_SRC(tcp)) == _TRUE) { + if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) { + session_tracker_add_cmd(padapter, sta + , IPV4_DST(ip), TCP_DST(tcp) + , IPV4_SRC(ip), TCP_SRC(tcp)); + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n" + , FUNC_ADPT_ARG(padapter) + , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)) + , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))); + } + if (GET_TCP_FIN(tcp)) { + session_tracker_del_cmd(padapter, sta + , IPV4_DST(ip), TCP_DST(tcp) + , IPV4_SRC(ip), TCP_SRC(tcp)); + if (DBG_SESSION_TRACKER) + DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n" + , FUNC_ADPT_ARG(padapter) + , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)) + , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))); + } + } + + } + } +bypass_session_tracker: + ; + } + + rtw_os_recv_indicate_pkt(padapter, skb, pattrib); + +_recv_indicatepkt_end: + + precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe() + + rtw_free_recvframe(precv_frame, pfree_recv_queue); + + RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n")); + + + return _SUCCESS; + +_recv_indicatepkt_drop: + + //enqueue back to free_recv_queue + if(precv_frame) + rtw_free_recvframe(precv_frame, pfree_recv_queue); + + DBG_COUNTER(padapter->rx_logs.os_indicate_err); + + return _FAIL; + +} + +void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf) +{ + struct recv_priv *precvpriv = &padapter->recvpriv; + +#ifdef CONFIG_USB_HCI + + precvbuf->ref_cnt--; + + //free skb in recv_buf + rtw_skb_free(precvbuf->pskb); + + precvbuf->pskb = NULL; + + if(precvbuf->irp_pending == _FALSE) + { + rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf); + } + + +#endif +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + precvbuf->pskb = NULL; +#endif + +} +void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext); +void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext) +{ + struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)FunctionContext; + rtw_reordering_ctrl_timeout_handler(preorder_ctrl); +} + +void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) +{ + _adapter *padapter = preorder_ctrl->padapter; + + _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl); + +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_android.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_android.c new file mode 100644 index 00000000..8de7ff72 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_android.c @@ -0,0 +1,1293 @@ +/****************************************************************************** + * + * 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 + * + * + ******************************************************************************/ + +#ifdef CONFIG_GPIO_WAKEUP +#include +#endif + +#include + +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) +#include +#else +#include +#endif +#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +#define strnicmp strncasecmp +#endif /* Linux kernel >= 4.0.0 */ + +#ifdef CONFIG_GPIO_WAKEUP +#include +#include +#endif + +#include "rtw_version.h" + +extern void macstr2num(u8 *dst, u8 *src); + +const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = { + "START", + "STOP", + "SCAN-ACTIVE", + "SCAN-PASSIVE", + "RSSI", + "LINKSPEED", + "RXFILTER-START", + "RXFILTER-STOP", + "RXFILTER-ADD", + "RXFILTER-REMOVE", + "BTCOEXSCAN-START", + "BTCOEXSCAN-STOP", + "BTCOEXMODE", + "SETSUSPENDOPT", + "P2P_DEV_ADDR", + "SETFWPATH", + "SETBAND", + "GETBAND", + "COUNTRY", + "P2P_SET_NOA", + "P2P_GET_NOA", + "P2P_SET_PS", + "SET_AP_WPS_P2P_IE", + + "MIRACAST", + +#ifdef CONFIG_PNO_SUPPORT + "PNOSSIDCLR", + "PNOSETUP", + "PNOFORCE", + "PNODEBUG", +#endif + + "MACADDR", + + "BLOCK_SCAN", + "BLOCK", + "WFD-ENABLE", + "WFD-DISABLE", + "WFD-SET-TCPPORT", + "WFD-SET-MAXTPUT", + "WFD-SET-DEVTYPE", + "SET_DTIM", + "HOSTAPD_SET_MACADDR_ACL", + "HOSTAPD_ACL_ADD_STA", + "HOSTAPD_ACL_REMOVE_STA", +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)) + "GTK_REKEY_OFFLOAD", +#endif //CONFIG_GTK_OL +/* Private command for P2P disable*/ + "P2P_DISABLE", + "DRIVER_VERSION" +}; + +#ifdef CONFIG_PNO_SUPPORT +#define PNO_TLV_PREFIX 'S' +#define PNO_TLV_VERSION '1' +#define PNO_TLV_SUBVERSION '2' +#define PNO_TLV_RESERVED '0' +#define PNO_TLV_TYPE_SSID_IE 'S' +#define PNO_TLV_TYPE_TIME 'T' +#define PNO_TLV_FREQ_REPEAT 'R' +#define PNO_TLV_FREQ_EXPO_MAX 'M' + +typedef struct cmd_tlv { + char prefix; + char version; + char subver; + char reserved; +} cmd_tlv_t; + +#ifdef CONFIG_PNO_SET_DEBUG +char pno_in_example[] = { + 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', + 'S', '1', '2', '0', + 'S', //1 + 0x05, + 'd', 'l', 'i', 'n', 'k', + 'S', //2 + 0x06, + 'B', 'U', 'F', 'B', 'U','F', + 'S', //3 + 0x20, + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '@', '#', '$', '%', '^', + 'S', //4 + 0x0a, + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + 'T', + '0', '5', + 'R', + '2', + 'M', + '2', + 0x00 + }; +#endif /* CONFIG_PNO_SET_DEBUG */ +#endif /* PNO_SUPPORT */ + +typedef struct android_wifi_priv_cmd { + char *buf; + int used_len; + int total_len; +} android_wifi_priv_cmd; + +#ifdef CONFIG_COMPAT +typedef struct compat_android_wifi_priv_cmd { + compat_uptr_t buf; + int used_len; + int total_len; +} compat_android_wifi_priv_cmd; +#endif /* CONFIG_COMPAT */ + +/** + * Local (static) functions and variables + */ + +/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first + * time (only) in dhd_open, subsequential wifi on will be handled by + * wl_android_wifi_on + */ +static int g_wifi_on = _TRUE; + +unsigned int oob_irq = 0; +unsigned int oob_gpio = 0; + +#ifdef CONFIG_PNO_SUPPORT +/* + * rtw_android_pno_setup + * Description: + * This is used for private command. + * + * Parameter: + * net: net_device + * command: parameters from private command + * total_len: the length of the command. + * + * */ +static int rtw_android_pno_setup(struct net_device *net, char *command, int total_len) { + pno_ssid_t pno_ssids_local[MAX_PNO_LIST_COUNT]; + int res = -1; + int nssid = 0; + cmd_tlv_t *cmd_tlv_temp; + char *str_ptr; + int tlv_size_left; + int pno_time = 0; + int pno_repeat = 0; + int pno_freq_expo_max = 0; + int cmdlen = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_PNOSETUP_SET]) + 1; + +#ifdef CONFIG_PNO_SET_DEBUG + int i; + char *p; + p = pno_in_example; + + total_len = sizeof(pno_in_example); + str_ptr = p + cmdlen; +#else + str_ptr = command + cmdlen; +#endif + + if (total_len < (cmdlen + sizeof(cmd_tlv_t))) { + DBG_871X("%s argument=%d less min size\n", __func__, total_len); + goto exit_proc; + } + + tlv_size_left = total_len - cmdlen; + + cmd_tlv_temp = (cmd_tlv_t *)str_ptr; + memset(pno_ssids_local, 0, sizeof(pno_ssids_local)); + + if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && + (cmd_tlv_temp->version == PNO_TLV_VERSION) && + (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { + + str_ptr += sizeof(cmd_tlv_t); + tlv_size_left -= sizeof(cmd_tlv_t); + + if ((nssid = rtw_parse_ssid_list_tlv(&str_ptr, pno_ssids_local, + MAX_PNO_LIST_COUNT, &tlv_size_left)) <= 0) { + DBG_871X("SSID is not presented or corrupted ret=%d\n", nssid); + goto exit_proc; + } else { + if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { + DBG_871X("%s scan duration corrupted field size %d\n", + __func__, tlv_size_left); + goto exit_proc; + } + str_ptr++; + pno_time = simple_strtoul(str_ptr, &str_ptr, 16); + DBG_871X("%s: pno_time=%d\n", __func__, pno_time); + + if (str_ptr[0] != 0) { + if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { + DBG_871X("%s pno repeat : corrupted field\n", + __func__); + goto exit_proc; + } + str_ptr++; + pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); + DBG_871X("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat); + if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { + DBG_871X("%s FREQ_EXPO_MAX corrupted field size\n", + __func__); + goto exit_proc; + } + str_ptr++; + pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); + DBG_871X("%s: pno_freq_expo_max=%d\n", + __func__, pno_freq_expo_max); + } + } + } else { + DBG_871X("%s get wrong TLV command\n", __FUNCTION__); + goto exit_proc; + } + + res = rtw_dev_pno_set(net, pno_ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); + +#ifdef CONFIG_PNO_SET_DEBUG + rtw_dev_pno_debug(net); +#endif + +exit_proc: + return res; +} + +/* + * rtw_android_cfg80211_pno_setup + * Description: + * This is used for cfg80211 sched_scan. + * + * Parameter: + * net: net_device + * request: cfg80211_request + * */ + +int rtw_android_cfg80211_pno_setup(struct net_device *net, + struct cfg80211_ssid *ssids, int n_ssids, int interval) { + int res = -1; + int nssid = 0; + int pno_time = 0; + int pno_repeat = 0; + int pno_freq_expo_max = 0; + int index = 0; + pno_ssid_t pno_ssids_local[MAX_PNO_LIST_COUNT]; + + if (n_ssids > MAX_PNO_LIST_COUNT || n_ssids < 0) { + DBG_871X("%s: nssids(%d) is invalid.\n", __func__, n_ssids); + return -EINVAL; + } + + memset(pno_ssids_local, 0, sizeof(pno_ssids_local)); + + nssid = n_ssids; + + for (index = 0 ; index < nssid ; index++) { + pno_ssids_local[index].SSID_len = ssids[index].ssid_len; + memcpy(pno_ssids_local[index].SSID, ssids[index].ssid, + ssids[index].ssid_len); + } + + pno_time = (interval / 1000); + + DBG_871X("%s: nssids: %d, pno_time=%d\n", __func__, nssid, pno_time); + + res = rtw_dev_pno_set(net, pno_ssids_local, nssid, pno_time, + pno_repeat, pno_freq_expo_max); + +exit_proc: + return res; +} + +int rtw_android_pno_enable(struct net_device *net, int pno_enable) { + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); + + if (pwrctl) { + pwrctl->wowlan_pno_enable = pno_enable; + DBG_871X("%s: wowlan_pno_enable: %d\n", __func__, pwrctl->wowlan_pno_enable); + if (pwrctl->wowlan_pno_enable == 0) { + if (pwrctl->pnlo_info != NULL) { + rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t)); + pwrctl->pnlo_info = NULL; + } + if (pwrctl->pno_ssid_list != NULL) { + rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t)); + pwrctl->pno_ssid_list = NULL; + } + if (pwrctl->pscan_info != NULL) { + rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t)); + pwrctl->pscan_info = NULL; + } + } + return 0; + } else { + return -1; + } +} +#endif //CONFIG_PNO_SUPPORT + +int rtw_android_cmdstr_to_num(char *cmdstr) +{ + int cmd_num; + for(cmd_num=0 ; cmd_nummlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + int bytes_written = 0; + + if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) { + bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d", + pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi); + } + + return bytes_written; +} + +int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct wlan_network *pcur_network = &pmlmepriv->cur_network; + int bytes_written = 0; + u16 link_speed = 0; + + link_speed = rtw_get_cur_max_rate(padapter)/10; + bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); + + return bytes_written; +} + +int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + int bytes_written = 0; + + bytes_written = snprintf(command, total_len, "Macaddr = "MAC_FMT, MAC_ARG(net->dev_addr)); + return bytes_written; +} + +int rtw_android_set_country(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1; + int ret = _FAIL; + + ret = rtw_set_country(adapter, country_code); + + return (ret==_SUCCESS)?0:-1; +} + +int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len) +{ + int bytes_written = 0; + + //We use the same address as our HW MAC address + _rtw_memcpy(command, net->dev_addr, ETH_ALEN); + + bytes_written = ETH_ALEN; + return bytes_written; +} + +int rtw_android_set_block_scan(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK_SCAN]) + 1; + + #ifdef CONFIG_IOCTL_CFG80211 + adapter_wdev_data(adapter)->block_scan = (*block_value == '0')?_FALSE:_TRUE; + #endif + + return 0; +} + +int rtw_android_set_block(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK]) + 1; + + #ifdef CONFIG_IOCTL_CFG80211 + adapter_wdev_data(adapter)->block = (*block_value=='0')?_FALSE:_TRUE; + #endif + + return 0; +} + +int rtw_android_setband(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + char *arg = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SETBAND]) + 1; + u32 band = WIFI_FREQUENCY_BAND_AUTO; + int ret = _FAIL; + + if (sscanf(arg, "%u", &band) >= 1) + ret = rtw_set_band(adapter, band); + + return (ret==_SUCCESS)?0:-1; +} + +int rtw_android_getband(struct net_device *net, char *command, int total_len) +{ + _adapter *adapter = (_adapter *)rtw_netdev_priv(net); + int bytes_written = 0; + + bytes_written = snprintf(command, total_len, "%u", adapter->setband); + + return bytes_written; +} + +#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; + int ret = _FAIL; + + num = sscanf(arg, "%hhu", &mode); + + if (num < 1) + goto exit; + + switch (mode) { + case 1: /* soruce */ + mode = MIRACAST_SOURCE; + break; + case 2: /* sink */ + mode = MIRACAST_SINK; + break; + case 0: /* disabled */ + default: + mode = MIRACAST_DISABLED; + break; + } + wfd_info->stack_wfd_mode = mode; + DBG_871X("stack miracast mode: %s\n", get_miracast_mode_str(wfd_info->stack_wfd_mode)); + + ret = _SUCCESS; + +exit: + return (ret == _SUCCESS)?0:-1; +} +#endif /* CONFIG_WFD */ + +int get_int_from_command( char* pcmd ) +{ + int i = 0; + + for( i = 0; i < strlen( pcmd ); i++ ) + { + if ( pcmd[ i ] == '=' ) + { + // Skip the '=' and space characters. + i += 2; + break; + } + } + return ( rtw_atoi( pcmd + i ) ); +} + +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)) +int rtw_gtk_offload(struct net_device *net, u8 *cmd_ptr) +{ + int i; + //u8 *cmd_ptr = priv_cmd.buf; + struct sta_info * psta; + _adapter *padapter = (_adapter *)rtw_netdev_priv(net); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv* psecuritypriv=&(padapter->securitypriv); + psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv)); + + + if (psta == NULL) + { + DBG_8192C("%s, : Obtain Sta_info fail \n", __func__); + } + else + { + //string command length of "GTK_REKEY_OFFLOAD" + cmd_ptr += 18; + + _rtw_memcpy(psta->kek, cmd_ptr, RTW_KEK_LEN); + cmd_ptr += RTW_KEK_LEN; + /* + printk("supplicant KEK: "); + for(i=0;ikek[i]); + printk("\n supplicant KCK: "); + */ + _rtw_memcpy(psta->kck, cmd_ptr, RTW_KCK_LEN); + cmd_ptr += RTW_KCK_LEN; + /* + for(i=0;ikck[i]); + */ + _rtw_memcpy(psta->replay_ctr, cmd_ptr, RTW_REPLAY_CTR_LEN); + psecuritypriv->binstallKCK_KEK = _TRUE; + + //printk("\nREPLAY_CTR: "); + //for(i=0;ireplay_ctr[i]); + } + + return _SUCCESS; +} +#endif //CONFIG_GTK_OL + +int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) +{ + int ret = 0; + char *command = NULL; + int cmd_num; + int bytes_written = 0; +#ifdef CONFIG_PNO_SUPPORT + uint cmdlen = 0; + uint pno_enable = 0; +#endif + android_wifi_priv_cmd priv_cmd; + _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); +#ifdef CONFIG_WFD + struct wifi_display_info *pwfd_info; +#endif + + rtw_lock_suspend(); + + if (!ifr->ifr_data) { + ret = -EINVAL; + goto exit; + } + if (padapter->registrypriv.mp_mode == 1) { + ret = -EINVAL; + goto exit; + } +#ifdef CONFIG_COMPAT + if (is_compat_task()) { + /* User space is 32-bit, use compat ioctl */ + compat_android_wifi_priv_cmd compat_priv_cmd; + + if (copy_from_user(&compat_priv_cmd, ifr->ifr_data, sizeof(compat_android_wifi_priv_cmd))) { + ret = -EFAULT; + goto exit; + } + priv_cmd.buf = compat_ptr(compat_priv_cmd.buf); + priv_cmd.used_len = compat_priv_cmd.used_len; + priv_cmd.total_len = compat_priv_cmd.total_len; + } else +#endif /* CONFIG_COMPAT */ + if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { + ret = -EFAULT; + goto exit; + } + if ( padapter->registrypriv.mp_mode == 1) { + ret = -EFAULT; + goto exit; + } + /*DBG_871X("%s priv_cmd.buf=%p priv_cmd.total_len=%d priv_cmd.used_len=%d\n",__func__,priv_cmd.buf,priv_cmd.total_len,priv_cmd.used_len);*/ + command = rtw_zmalloc(priv_cmd.total_len); + if (!command) + { + DBG_871X("%s: failed to allocate memory\n", __FUNCTION__); + ret = -ENOMEM; + goto exit; + } + + if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ + DBG_871X("%s: failed to access memory\n", __FUNCTION__); + ret = -EFAULT; + goto exit; + } + if (copy_from_user(command, (void *)priv_cmd.buf, priv_cmd.total_len)) { + ret = -EFAULT; + goto exit; + } + + DBG_871X("%s: Android private cmd \"%s\" on %s\n" + , __FUNCTION__, command, ifr->ifr_name); + + cmd_num = rtw_android_cmdstr_to_num(command); + + switch(cmd_num) { + case ANDROID_WIFI_CMD_START: + //bytes_written = wl_android_wifi_on(net); + goto response; + case ANDROID_WIFI_CMD_SETFWPATH: + goto response; + } + + if (!g_wifi_on) { + DBG_871X("%s: Ignore private cmd \"%s\" - iface %s is down\n" + ,__FUNCTION__, command, ifr->ifr_name); + ret = 0; + goto exit; + } + + if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) { + switch (cmd_num) { + case ANDROID_WIFI_CMD_WFD_ENABLE: + case ANDROID_WIFI_CMD_WFD_DISABLE: + case ANDROID_WIFI_CMD_WFD_SET_TCPPORT: + case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT: + case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE: + goto response; + } + } + + switch(cmd_num) { + + case ANDROID_WIFI_CMD_STOP: + //bytes_written = wl_android_wifi_off(net); + break; + + case ANDROID_WIFI_CMD_SCAN_ACTIVE: + //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE); +#ifdef CONFIG_PLATFORM_MSTAR +#ifdef CONFIG_IOCTL_CFG80211 + adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->bandroid_scan = _TRUE; +#endif //CONFIG_IOCTL_CFG80211 +#endif //CONFIG_PLATFORM_MSTAR + break; + case ANDROID_WIFI_CMD_SCAN_PASSIVE: + //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE); + break; + + case ANDROID_WIFI_CMD_RSSI: + bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_LINKSPEED: + bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_MACADDR: + bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_BLOCK_SCAN: + bytes_written = rtw_android_set_block_scan(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_BLOCK: + bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_RXFILTER_START: + //bytes_written = net_os_set_packet_filter(net, 1); + break; + case ANDROID_WIFI_CMD_RXFILTER_STOP: + //bytes_written = net_os_set_packet_filter(net, 0); + break; + case ANDROID_WIFI_CMD_RXFILTER_ADD: + //int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; + //bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); + break; + case ANDROID_WIFI_CMD_RXFILTER_REMOVE: + //int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; + //bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); + break; + + case ANDROID_WIFI_CMD_BTCOEXSCAN_START: + /* TBD: BTCOEXSCAN-START */ + break; + case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP: + /* TBD: BTCOEXSCAN-STOP */ + break; + case ANDROID_WIFI_CMD_BTCOEXMODE: + #if 0 + uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; + if (mode == 1) + net_os_set_packet_filter(net, 0); /* DHCP starts */ + else + net_os_set_packet_filter(net, 1); /* DHCP ends */ +#ifdef WL_CFG80211 + bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); +#endif + #endif + break; + + case ANDROID_WIFI_CMD_SETSUSPENDOPT: + //bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_SETBAND: + bytes_written = rtw_android_setband(net, command, priv_cmd.total_len); + break; + + case ANDROID_WIFI_CMD_GETBAND: + bytes_written = rtw_android_getband(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; + +#ifdef CONFIG_PNO_SUPPORT + case ANDROID_WIFI_CMD_PNOSSIDCLR_SET: + //bytes_written = dhd_dev_pno_reset(net); + break; + case ANDROID_WIFI_CMD_PNOSETUP_SET: + bytes_written = rtw_android_pno_setup(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_PNOENABLE_SET: + cmdlen = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_PNOENABLE_SET]); + pno_enable = *(command + cmdlen + 1) - '0'; + bytes_written = rtw_android_pno_enable(net, pno_enable); + break; +#endif + + case ANDROID_WIFI_CMD_P2P_DEV_ADDR: + bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_P2P_SET_NOA: + //int skip = strlen(CMD_P2P_SET_NOA) + 1; + //bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); + break; + case ANDROID_WIFI_CMD_P2P_GET_NOA: + //bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); + break; + case ANDROID_WIFI_CMD_P2P_SET_PS: + //int skip = strlen(CMD_P2P_SET_PS) + 1; + //bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip); + break; + +#ifdef CONFIG_IOCTL_CFG80211 + case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: + { + int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3; + bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); + break; + } +#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 + // We can enable the WFD function by using the following command: + // wpa_cli driver wfd-enable + + if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) + rtw_wfd_enable(padapter, 1); + break; + } + + case ANDROID_WIFI_CMD_WFD_DISABLE: + { + // Commented by Albert 2012/07/24 + // We can disable the WFD function by using the following command: + // wpa_cli driver wfd-disable + + if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) + rtw_wfd_enable(padapter, 0); + break; + } + case ANDROID_WIFI_CMD_WFD_SET_TCPPORT: + { + // Commented by Albert 2012/07/24 + // We can set the tcp port number by using the following command: + // wpa_cli driver wfd-set-tcpport = 554 + + if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) + rtw_wfd_set_ctrl_port(padapter, (u16)get_int_from_command(priv_cmd.buf)); + break; + } + case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT: + { + break; + } + case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE: + { + // Commented by Albert 2012/08/28 + // Specify the WFD device type ( WFD source/primary sink ) + + pwfd_info = &padapter->wfd_info; + if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) + { + pwfd_info->wfd_device_type = ( u8 ) get_int_from_command( priv_cmd.buf ); + pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL; + } + break; + } +#endif + case ANDROID_WIFI_CMD_CHANGE_DTIM: + { +#ifdef CONFIG_LPS + u8 dtim; + u8 *ptr =(u8 *) &priv_cmd.buf; + + ptr += 9;//string command length of "SET_DTIM"; + + dtim = rtw_atoi(ptr); + + DBG_871X("DTIM=%d\n", dtim); + + rtw_lps_change_dtim_cmd(padapter, dtim); +#endif + } + break; + case ANDROID_WIFI_CMD_HOSTAPD_SET_MACADDR_ACL: + { + padapter->stapriv.acl_list.mode = ( u8 ) get_int_from_command(command); + DBG_871X("%s ANDROID_WIFI_CMD_HOSTAPD_SET_MACADDR_ACL mode:%d\n", __FUNCTION__, padapter->stapriv.acl_list.mode); + break; + } + case ANDROID_WIFI_CMD_HOSTAPD_ACL_ADD_STA: + { + u8 addr[ETH_ALEN] = {0x00}; + macstr2num(addr, command+strlen("HOSTAPD_ACL_ADD_STA")+3); // 3 is space bar + "=" + space bar these 3 chars + rtw_acl_add_sta(padapter, addr); + break; + } + case ANDROID_WIFI_CMD_HOSTAPD_ACL_REMOVE_STA: + { + u8 addr[ETH_ALEN] = {0x00}; + macstr2num(addr, command+strlen("HOSTAPD_ACL_REMOVE_STA")+3); // 3 is space bar + "=" + space bar these 3 chars + rtw_acl_remove_sta(padapter, addr); + break; + } +#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)) + case ANDROID_WIFI_CMD_GTK_REKEY_OFFLOAD: + 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; + u8 channel, ch_offset; + u16 bwmode; + + rtw_p2p_enable(padapter, P2P_ROLE_DISABLE); +#endif // CONFIG_P2P + break; + } + case ANDROID_WIFI_CMD_DRIVERVERSION: + { + bytes_written = strlen(DRIVERVERSION); + snprintf(command, bytes_written+1, DRIVERVERSION); + break; + } + default: + DBG_871X("Unknown PRIVATE command %s - ignored\n", command); + snprintf(command, 3, "OK"); + bytes_written = strlen("OK"); + } + +response: + if (bytes_written >= 0) { + if ((bytes_written == 0) && (priv_cmd.total_len > 0)) + command[0] = '\0'; + if (bytes_written >= priv_cmd.total_len) { + DBG_871X("%s: bytes_written = %d\n", __FUNCTION__, bytes_written); + bytes_written = priv_cmd.total_len; + } else { + bytes_written++; + } + priv_cmd.used_len = bytes_written; + if (copy_to_user((void *)priv_cmd.buf, command, bytes_written)) { + DBG_871X("%s: failed to copy data to user buffer\n", __FUNCTION__); + ret = -EFAULT; + } + } + else { + ret = bytes_written; + } + +exit: + rtw_unlock_suspend(); + if (command) { + rtw_mfree(command, priv_cmd.total_len); + } + + return ret; +} + + +/** + * Functions for Android WiFi card detection + */ +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) + +static int g_wifidev_registered = 0; +static struct semaphore wifi_control_sem; +static struct wifi_platform_data *wifi_control_data = NULL; +static struct resource *wifi_irqres = NULL; + +static int wifi_add_dev(void); +static void wifi_del_dev(void); + +int rtw_android_wifictrl_func_add(void) +{ + int ret = 0; + sema_init(&wifi_control_sem, 0); + + ret = wifi_add_dev(); + if (ret) { + DBG_871X("%s: platform_driver_register failed\n", __FUNCTION__); + return ret; + } + g_wifidev_registered = 1; + + /* Waiting callback after platform_driver_register is done or exit with error */ + if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { + ret = -EINVAL; + DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__); + } + + return ret; +} + +void rtw_android_wifictrl_func_del(void) +{ + if (g_wifidev_registered) + { + wifi_del_dev(); + g_wifidev_registered = 0; + } +} + +void *wl_android_prealloc(int section, unsigned long size) +{ + void *alloc_ptr = NULL; + if (wifi_control_data && wifi_control_data->mem_prealloc) { + alloc_ptr = wifi_control_data->mem_prealloc(section, size); + if (alloc_ptr) { + DBG_871X("success alloc section %d\n", section); + if (size != 0L) + memset(alloc_ptr, 0, size); + return alloc_ptr; + } + } + + DBG_871X("can't alloc section %d\n", section); + return NULL; +} + +int wifi_get_irq_number(unsigned long *irq_flags_ptr) +{ + if (wifi_irqres) { + *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; + return (int)wifi_irqres->start; + } +#ifdef CUSTOM_OOB_GPIO_NUM + return CUSTOM_OOB_GPIO_NUM; +#else + return -1; +#endif +} + +int wifi_set_power(int on, unsigned long msec) +{ + DBG_871X("%s = %d\n", __FUNCTION__, on); + if (wifi_control_data && wifi_control_data->set_power) { + wifi_control_data->set_power(on); + } + if (msec) + msleep(msec); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) +int wifi_get_mac_addr(unsigned char *buf) +{ + DBG_871X("%s\n", __FUNCTION__); + if (!buf) + return -EINVAL; + if (wifi_control_data && wifi_control_data->get_mac_addr) { + return wifi_control_data->get_mac_addr(buf); + } + return -EOPNOTSUPP; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE) +void *wifi_get_country_code(char *ccode) +{ + DBG_871X("%s\n", __FUNCTION__); + if (!ccode) + return NULL; + if (wifi_control_data && wifi_control_data->get_country_code) { + return wifi_control_data->get_country_code(ccode); + } + return NULL; +} +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ + +static int wifi_set_carddetect(int on) +{ + DBG_871X("%s = %d\n", __FUNCTION__, on); + if (wifi_control_data && wifi_control_data->set_carddetect) { + wifi_control_data->set_carddetect(on); + } + return 0; +} + +static int wifi_probe(struct platform_device *pdev) +{ + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + int wifi_wake_gpio = 0; + + DBG_871X("## %s\n", __FUNCTION__); + wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); + + if (wifi_irqres == NULL) + wifi_irqres = platform_get_resource_byname(pdev, + IORESOURCE_IRQ, "bcm4329_wlan_irq"); + else + wifi_wake_gpio = wifi_irqres->start; + +#ifdef CONFIG_GPIO_WAKEUP + printk("%s: gpio:%d wifi_wake_gpio:%d\n", __func__, + 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) + { + oob_irq = wifi_irqres->start; + printk("%s oob_irq:%d\n", __func__, oob_irq); + } +#endif + wifi_control_data = wifi_ctrl; + + wifi_set_power(1, 0); /* Power On */ + wifi_set_carddetect(1); /* CardDetect (0->1) */ + + up(&wifi_control_sem); + return 0; +} + +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN +extern PADAPTER g_test_adapter; + +static void shutdown_card(void) +{ + u32 addr; + u8 tmp8, cnt=0; + + if (NULL == g_test_adapter) + { + DBG_871X("%s: padapter==NULL\n", __FUNCTION__); + return; + } + +#ifdef CONFIG_FWLPS_IN_IPS + LeaveAllPowerSaveMode(g_test_adapter); +#endif // CONFIG_FWLPS_IN_IPS + + // Leave SDIO HCI Suspend + addr = 0x10250086; + rtw_write8(g_test_adapter, addr, 0); + do { + tmp8 = rtw_read8(g_test_adapter, addr); + cnt++; + DBG_871X(FUNC_ADPT_FMT ": polling SDIO_HSUS_CTRL(0x%x)=0x%x, cnt=%d\n", + FUNC_ADPT_ARG(g_test_adapter), addr, tmp8, cnt); + + if (tmp8 & BIT(1)) + break; + + if (cnt >= 100) + { + DBG_871X(FUNC_ADPT_FMT ": polling 0x%x[1]==1 FAIL!!\n", + FUNC_ADPT_ARG(g_test_adapter), addr); + break; + } + + rtw_mdelay_os(10); + } while (1); + + // unlock register I/O + rtw_write8(g_test_adapter, 0x1C, 0); + + // enable power down function + // 0x04[4] = 1 + // 0x05[7] = 1 + addr = 0x04; + tmp8 = rtw_read8(g_test_adapter, addr); + tmp8 |= BIT(4); + rtw_write8(g_test_adapter, addr, tmp8); + DBG_871X(FUNC_ADPT_FMT ": read after write 0x%x=0x%x\n", + FUNC_ADPT_ARG(g_test_adapter), addr, rtw_read8(g_test_adapter, addr)); + + addr = 0x05; + tmp8 = rtw_read8(g_test_adapter, addr); + tmp8 |= BIT(7); + rtw_write8(g_test_adapter, addr, tmp8); + DBG_871X(FUNC_ADPT_FMT ": read after write 0x%x=0x%x\n", + FUNC_ADPT_ARG(g_test_adapter), addr, rtw_read8(g_test_adapter, addr)); + + // lock register page0 0x0~0xB read/write + rtw_write8(g_test_adapter, 0x1C, 0x0E); + + rtw_set_surprise_removed(g_test_adapter); + DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved=%s\n", + FUNC_ADPT_ARG(g_test_adapter), rtw_is_surprise_removed(g_test_adapter)?"True":"False"); +} +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN + +static int wifi_remove(struct platform_device *pdev) +{ + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + + DBG_871X("## %s\n", __FUNCTION__); + wifi_control_data = wifi_ctrl; + + wifi_set_power(0, 0); /* Power Off */ + wifi_set_carddetect(0); /* CardDetect (1->0) */ + + up(&wifi_control_sem); + return 0; +} + +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN +static void wifi_shutdown(struct platform_device *pdev) +{ + struct wifi_platform_data *wifi_ctrl = + (struct wifi_platform_data *)(pdev->dev.platform_data); + + + DBG_871X("## %s\n", __FUNCTION__); + + wifi_control_data = wifi_ctrl; + + shutdown_card(); + wifi_set_power(0, 0); /* Power Off */ + wifi_set_carddetect(0); /* CardDetect (1->0) */ +} +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN + +static int wifi_suspend(struct platform_device *pdev, pm_message_t state) +{ + DBG_871X("##> %s\n", __FUNCTION__); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) + bcmsdh_oob_intr_set(0); +#endif + return 0; +} + +static int wifi_resume(struct platform_device *pdev) +{ + DBG_871X("##> %s\n", __FUNCTION__); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) + if (dhd_os_check_if_up(bcmsdh_get_drvdata())) + bcmsdh_oob_intr_set(1); +#endif + return 0; +} + +/* temporarily use these two */ +static struct platform_driver wifi_device = { + .probe = wifi_probe, + .remove = wifi_remove, + .suspend = wifi_suspend, + .resume = wifi_resume, +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN + .shutdown = wifi_shutdown, +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN + .driver = { + .name = "bcmdhd_wlan", + } +}; + +static struct platform_driver wifi_device_legacy = { + .probe = wifi_probe, + .remove = wifi_remove, + .suspend = wifi_suspend, + .resume = wifi_resume, + .driver = { + .name = "bcm4329_wlan", + } +}; + +static int wifi_add_dev(void) +{ + DBG_871X("## Calling platform_driver_register\n"); + platform_driver_register(&wifi_device); + platform_driver_register(&wifi_device_legacy); + return 0; +} + +static void wifi_del_dev(void) +{ + DBG_871X("## Unregister platform_driver_register\n"); + platform_driver_unregister(&wifi_device); + platform_driver_unregister(&wifi_device_legacy); +} +#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/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.c new file mode 100644 index 00000000..13e07482 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.c @@ -0,0 +1,1340 @@ +/****************************************************************************** + * + * 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 + +#ifdef CONFIG_IOCTL_CFG80211 + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) + +/* +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ + +#include + +#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) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct wireless_dev *wdev = padapter->rtw_wdev; + + struct sk_buff *skb; + unsigned int truesize = 0; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) + skb = cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp); +#else + skb = cfg80211_vendor_event_alloc(wiphy, wdev, len, event_id, gfp); +#endif + + 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 + +struct sk_buff *rtw_cfg80211_vendor_event_alloc( + struct wiphy *wiphy, int len, int event_id, gfp_t gfp) +{ + _adapter *padapter = wiphy_to_adapter(wiphy); + struct wireless_dev *wdev = padapter->rtw_wdev; + struct sk_buff *skb; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) + skb = cfg80211_vendor_event_alloc(wiphy, len, event_id, gfp); +#else + skb = cfg80211_vendor_event_alloc(wiphy, wdev, len, event_id, gfp); +#endif + return skb; +} + +#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_8814A_SERIES(*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/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.h b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_cfgvendor.h new file mode 100644 index 00000000..7c349e79 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/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/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.c new file mode 100644 index 00000000..c81ca694 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.c @@ -0,0 +1,2131 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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 /* tolower() */ +#include +#include +#include "rtw_proc.h" +#ifdef CONFIG_BT_COEXIST +#include +#endif + +#ifdef CONFIG_PROC_DEBUG + +static struct proc_dir_entry *rtw_proc = NULL; + +inline struct proc_dir_entry *get_rtw_drv_proc(void) +{ + return rtw_proc; +} + +#define RTW_PROC_NAME DRV_NAME + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) +#define file_inode(file) ((file)->f_dentry->d_inode) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) +#define PDE_DATA(inode) PDE((inode))->data +#define proc_get_parent_data(inode) PDE((inode))->parent->data +#endif + +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) +#define get_proc_net proc_net +#else +#define get_proc_net init_net.proc_net +#endif + +inline struct proc_dir_entry *rtw_proc_create_dir(const char *name, struct proc_dir_entry *parent, void *data) +{ + struct proc_dir_entry *entry; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) + entry = proc_mkdir_data(name, S_IRUGO|S_IXUGO, parent, data); +#else + //entry = proc_mkdir_mode(name, S_IRUGO|S_IXUGO, parent); + entry = proc_mkdir(name, parent); + if (entry) + entry->data = data; +#endif + + return entry; +} + +inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, + const struct file_operations *fops, void * data) +{ + struct proc_dir_entry *entry; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + entry = proc_create_data(name, S_IFREG|S_IRUGO|S_IWUGO, parent, fops, data); +#else + entry = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUGO, parent); + if (entry) { + entry->data = data; + entry->proc_fops = fops; + } +#endif + + return entry; +} + +static int proc_get_dummy(struct seq_file *m, void *v) +{ + return 0; +} + +static int proc_get_drv_version(struct seq_file *m, void *v) +{ + dump_drv_version(m); + return 0; +} + +static int proc_get_log_level(struct seq_file *m, void *v) +{ + dump_log_level(m); + return 0; +} + +static int proc_get_drv_cfg(struct seq_file *m, void *v) +{ + dump_drv_cfg(m); + return 0; +} + +static ssize_t proc_set_log_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + char tmp[32]; + int log_level; + + if (count < 1) + return -EINVAL; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%d ", &log_level); + + if( log_level >= _drv_always_ && log_level <= _drv_debug_ ) + { + GlobalDebugLevel= log_level; + printk("%d\n", GlobalDebugLevel); + } + } else { + return -EFAULT; + } + + return count; +} + +#ifdef DBG_MEM_ALLOC +static int proc_get_mstat(struct seq_file *m, void *v) +{ + rtw_mstat_dump(m); + return 0; +} +#endif /* DBG_MEM_ALLOC */ + +static int proc_get_country_chplan_map(struct seq_file *m, void *v) +{ + dump_country_chplan_map(m); + return 0; +} + +static int proc_get_chplan_id_list(struct seq_file *m, void *v) +{ + dump_chplan_id_list(m); + return 0; +} + +static int proc_get_chplan_test(struct seq_file *m, void *v) +{ + dump_chplan_test(m); + return 0; +} + +/* +* rtw_drv_proc: +* init/deinit when register/unregister driver +*/ +const struct rtw_proc_hdl drv_proc_hdls [] = { + {"ver_info", proc_get_drv_version, NULL}, + {"log_level", proc_get_log_level, proc_set_log_level}, + {"drv_cfg", proc_get_drv_cfg, NULL}, +#ifdef DBG_MEM_ALLOC + {"mstat", proc_get_mstat, NULL}, +#endif /* DBG_MEM_ALLOC */ + {"country_chplan_map", proc_get_country_chplan_map, NULL}, + {"chplan_id_list", proc_get_chplan_id_list, NULL}, + {"chplan_test", proc_get_chplan_test, NULL}, +}; + +const int drv_proc_hdls_num = sizeof(drv_proc_hdls) / sizeof(struct rtw_proc_hdl); + +static int rtw_drv_proc_open(struct inode *inode, struct file *file) +{ + //struct net_device *dev = proc_get_parent_data(inode); + ssize_t index = (ssize_t)PDE_DATA(inode); + const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; + return single_open(file, hdl->show, NULL); +} + +static ssize_t rtw_drv_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); + const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; + + if (write) + return write(file, buffer, count, pos, NULL); + + return -EROFS; +} + +static const struct file_operations rtw_drv_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_drv_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = rtw_drv_proc_write, +}; + +int rtw_drv_proc_init(void) +{ + int ret = _FAIL; + ssize_t i; + struct proc_dir_entry *entry = NULL; + + if (rtw_proc != NULL) { + rtw_warn_on(1); + goto exit; + } + + rtw_proc = rtw_proc_create_dir(RTW_PROC_NAME, get_proc_net, NULL); + + if (rtw_proc == NULL) { + rtw_warn_on(1); + goto exit; + } + + for (i=0;iprivate; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + sd_f0_reg_dump(m, adapter); + + return 0; +} + +static int proc_get_sdio_local_reg_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + sdio_local_reg_dump(m, adapter); + + return 0; +} +#endif /* CONFIG_SDIO_HCI */ + +static int proc_get_mac_reg_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + mac_reg_dump(m, adapter); + + return 0; +} + +static int proc_get_bb_reg_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + bb_reg_dump(m, adapter); + + return 0; +} + +static int proc_get_rf_reg_dump(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + rf_reg_dump(m, adapter); + + return 0; +} + +static int proc_get_dump_adapters_status(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_adapters_status(m, adapter_to_dvobj(adapter)); + + return 0; +} + +//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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + 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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + 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 (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + 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_current_tx_rate(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; + u8 null_addr[ETH_ALEN] = {0}; + u8 *macaddr; + u8 current_rate_id = 0; + + DBG_871X_SEL_NL(m, "%-5s %-4s %-17s %-7s\n" + , "macid", "if_g", "macaddr", "tx_rate"); + + for (i = 0; i < macid_ctl->num; i++) { + if (rtw_macid_is_used(macid_ctl, i) || macid_ctl->h2c_msr[i]) { + if (macid_ctl->sta[i]) + macaddr = macid_ctl->sta[i]->hwaddr; + else + macaddr = null_addr; + current_rate_id = rtw_get_current_tx_rate(adapter, i); + if (!rtw_macid_is_bmc(macid_ctl, i)) { + DBG_871X_SEL_NL(m, "%5u %4u "MAC_FMT" %s\n" + , i + , rtw_macid_get_if_g(macid_ctl, i) + , MAC_ARG(macaddr) + , HDATA_RATE(current_rate_id) + ); + } + + + } + } + + +return 0; + +} + + +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; +} + + +static ssize_t proc_set_linked_info_dump(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 mode=0,pre_mode=0; + int num=0; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + pre_mode=padapter->bLinkInfoDump; + DBG_871X("pre_mode=%d\n", pre_mode); + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + num =sscanf(tmp, "%d ", &mode); + DBG_871X("num=%d mode=%d\n",num,mode); + + if(num!=1) + { + 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; +} + +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; +} + +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 *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_cur_chset(m, adapter); + + 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); + char tmp[32]; + u8 chan_plan = RTW_CHPLAN_MAX; + + if (!padapter) + return -EFAULT; + + if (count < 1) + { + DBG_871X("argument size is less than 1\n"); + return -EFAULT; + } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = sscanf(tmp, "%hhx", &chan_plan); + if (num != 1) + return count; + } + + rtw_set_channel_plan(padapter, chan_plan); + + return count; +} + +static int proc_get_country_code(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + if (adapter->mlmepriv.country_ent) + dump_country_chplan(m, adapter->mlmepriv.country_ent); + else + DBG_871X_SEL_NL(m, "unspecified\n"); + + return 0; +} + +static ssize_t proc_set_country_code(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]; + char alpha2[2]; + int num; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (!buffer || copy_from_user(tmp, buffer, count)) + goto exit; + + num = sscanf(tmp, "%c%c", &alpha2[0], &alpha2[1]); + if (num != 2) + return count; + + rtw_set_country(padapter, alpha2); + +exit: + return count; +} + +#ifdef CONFIG_DFS_MASTER +ssize_t proc_set_update_non_ocp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &adapter->mlmepriv; + struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv; + char tmp[32]; + u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + int ms = -1; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %hhu %hhu %d", &ch, &bw, &offset, &ms); + + if (num < 1 || (bw != CHANNEL_WIDTH_20 && num < 3)) + goto exit; + + if (bw == CHANNEL_WIDTH_20) + rtw_chset_update_non_ocp_ms(mlmeext->channel_set + , ch, bw, HAL_PRIME_CHNL_OFFSET_DONT_CARE, ms); + else + rtw_chset_update_non_ocp_ms(mlmeext->channel_set + , ch, bw, offset, ms); + } + +exit: + return count; +} + +ssize_t proc_set_radar_detect(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter); + char tmp[32]; + u8 fake_radar_detect_cnt = 0; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu", &fake_radar_detect_cnt); + + if (num < 1) + goto exit; + + rfctl->dbg_dfs_master_fake_radar_detect_cnt = fake_radar_detect_cnt; + } + +exit: + return count; +} +#endif /* CONFIG_DFS_MASTER */ + +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 (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + 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; + u8 null_addr[ETH_ALEN] = {0}; + u8 *macaddr; + + 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 %-17s %s" + "\n" + , "id", "bmc", "if_g", "ch_g", "macaddr", "status" + ); + + for (i=0;inum;i++) { + if (rtw_macid_is_used(macid_ctl, i) + || macid_ctl->h2c_msr[i] + ) { + if (macid_ctl->sta[i]) + macaddr = macid_ctl->sta[i]->hwaddr; + else + macaddr = null_addr; + + DBG_871X_SEL_NL(m, "%3u %3u %4d %4d "MAC_FMT" "H2C_MSR_FMT" %s" + "\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) + , MAC_ARG(macaddr) + , H2C_MSR_ARG(&macid_ctl->h2c_msr[i]) + , rtw_macid_is_used(macid_ctl, i) ? "" : "[unused]" + ); + } + } + + return 0; +} + +static int proc_get_sec_cam(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 cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + + DBG_871X_SEL_NL(m, "sec_cap:0x%02x\n", cam_ctl->sec_cap); + DBG_871X_SEL_NL(m, "flags:0x%08x\n", cam_ctl->flags); + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "max_num:%u\n", cam_ctl->num); + DBG_871X_SEL_NL(m, "used:\n"); + dump_sec_cam_map(m, &cam_ctl->used, cam_ctl->num); + DBG_871X_SEL_NL(m, "\n"); + + DBG_871X_SEL_NL(m, "reg_scr:0x%04x\n", rtw_read16(adapter, 0x680)); + DBG_871X_SEL_NL(m, "\n"); + + dump_sec_cam(m, adapter); + + return 0; +} + +static ssize_t proc_set_sec_cam(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); + struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + char tmp[32] = {0}; + char cmd[4]; + u8 id; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + /* c : clear specific cam entry */ + /* wfc : write specific cam entry from cam cache */ + + int num = sscanf(tmp, "%s %hhu", cmd, &id); + + if (num < 2) + return count; + + if (id >= cam_ctl->num) { + DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" invalid id:%u\n", FUNC_ADPT_ARG(adapter), id); + return count; + } + + if (strcmp("c", cmd) == 0) { + _clear_cam_entry(adapter, id); + adapter->securitypriv.hw_decrypted = _FALSE; /* temporarily set this for TX path to use SW enc */ + } else if (strcmp("wfc", cmd) == 0) { + write_cam_from_cache(adapter, id); + } + } + + return count; +} + +static int proc_get_sec_cam_cache(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 cam_ctl_t *cam_ctl = &dvobj->cam_ctl; + u8 i; + + DBG_871X_SEL_NL(m, "SW sec cam cache:\n"); + dump_sec_cam_ent_title(m, 1); + for (i = 0; i < cam_ctl->num; i++) { + if (dvobj->cam_cache[i].ctrl != 0) + dump_sec_cam_ent(m, &dvobj->cam_cache[i], i); + } + + return 0; +} + +static ssize_t proc_set_change_bss_chbw(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct mlme_priv *mlme = &(adapter->mlmepriv); + struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); + char tmp[32]; + u8 ch, bw = CHANNEL_WIDTH_20, offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu %hhu %hhu", &ch, &bw, &offset); + + if (num < 1 || (bw != CHANNEL_WIDTH_20 && num < 3)) + goto exit; + + if (check_fwstate(mlme, WIFI_AP_STATE) && check_fwstate(mlme, WIFI_ASOC_STATE)) + rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_WAIT_ACK, ch, bw, offset); + } + +exit: + return count; +} + +static int proc_get_target_tx_power(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_target_tx_power(m, adapter); + + return 0; +} + +static int proc_get_tx_power_by_rate(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_tx_power_by_rate(m, adapter); + + return 0; +} + +static int proc_get_tx_power_limit(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_tx_power_limit(m, adapter); + + return 0; +} + +static int proc_get_tx_power_ext_info(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_tx_power_ext_info(m, adapter); + + return 0; +} + +static ssize_t proc_set_tx_power_ext_info(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + char tmp[32] = {0}; + char cmd[16] = {0}; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%s", cmd); + + if (num < 1) + return count; + + phy_free_filebuf_mask(adapter, LOAD_BB_PG_PARA_FILE | LOAD_RF_TXPWR_LMT_PARA_FILE); + + rtw_ps_deny(adapter, PS_DENY_IOCTL); + LeaveAllPowerSaveModeDirect(adapter); + + if (strcmp("default", cmd) == 0) + rtw_run_in_thread_cmd(adapter, ((void *)(phy_reload_default_tx_power_ext_info)), adapter); + else + rtw_run_in_thread_cmd(adapter, ((void *)(phy_reload_tx_power_ext_info)), adapter); + + rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL); + } + + return count; +} + +#ifdef CONFIG_RF_GAIN_OFFSET +static int proc_get_kfree_flag(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + + DBG_871X_SEL_NL(m, "0x%02x\n", kfree_data->flag); + + return 0; +} + +static ssize_t proc_set_kfree_flag(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + char tmp[32] = {0}; + u8 flag; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhx", &flag); + + if (num < 1) + return count; + + kfree_data->flag = flag; + } + + return count; +} + +static int proc_get_kfree_bb_gain(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + u8 i, j; + + for (i = 0; i < BB_GAIN_NUM; i++) { + if (i == 0) + DBG_871X_SEL(m, "2G: "); + else if (i == 1) + DBG_871X_SEL(m, "5GLB1: "); + else if (i == 2) + DBG_871X_SEL(m, "5GLB2: "); + else if (i == 3) + DBG_871X_SEL(m, "5GMB1: "); + else if (i == 4) + DBG_871X_SEL(m, "5GMB2: "); + else if (i == 5) + DBG_871X_SEL(m, "5GHB: "); + + for (j = 0; j < hal_data->NumTotalRFPath; j++) + DBG_871X_SEL(m, "%d ", kfree_data->bb_gain[i][j]); + DBG_871X_SEL(m, "\n"); + } + + return 0; +} + +static ssize_t proc_set_kfree_bb_gain(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + char tmp[BB_GAIN_NUM * RF_PATH_MAX] = {0}; + u8 path, chidx; + s8 bb_gain[BB_GAIN_NUM]; + char ch_band_Group[6]; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + char *c, *next; + int i = 0; + + next = tmp; + c = strsep(&next, " \t"); + + if (sscanf(c, "%s", ch_band_Group) != 1) { + DBG_871X("Error Head Format, channel Group select\n,Please input:\t 2G , 5GLB1 , 5GLB2 , 5GMB1 , 5GMB2 , 5GHB\n"); + return count; + } + if (strcmp("2G", ch_band_Group) == 0) + chidx = BB_GAIN_2G; +#ifdef CONFIG_IEEE80211_BAND_5GHZ + else if (strcmp("5GLB1", ch_band_Group) == 0) + chidx = BB_GAIN_5GLB1; + else if (strcmp("5GLB2", ch_band_Group) == 0) + chidx = BB_GAIN_5GLB2; + else if (strcmp("5GMB1", ch_band_Group) == 0) + chidx = BB_GAIN_5GMB1; + else if (strcmp("5GMB2", ch_band_Group) == 0) + chidx = BB_GAIN_5GMB2; + else if (strcmp("5GHB", ch_band_Group) == 0) + chidx = BB_GAIN_5GHB; +#endif /*CONFIG_IEEE80211_BAND_5GHZ*/ + else { + DBG_871X("Error Head Format, channel Group select\n,Please input:\t 2G , 5GLB1 , 5GLB2 , 5GMB1 , 5GMB2 , 5GHB\n"); + return count; + } + c = strsep(&next, " \t"); + + while (c != NULL) { + if (sscanf(c, "%hhx", &bb_gain[i]) != 1) + break; + + kfree_data->bb_gain[chidx][i] = bb_gain[i]; + DBG_871X("%s,kfree_data->bb_gain[%d][%d]=%x\n", __func__, chidx, i, kfree_data->bb_gain[chidx][i]); + + c = strsep(&next, " \t"); + i++; + } + + } + + return count; + +} + +static int proc_get_kfree_thermal(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + + DBG_871X_SEL(m, "%d\n", kfree_data->thermal); + + return 0; +} + +static ssize_t proc_set_kfree_thermal(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + struct kfree_data_t *kfree_data = GET_KFREE_DATA(adapter); + char tmp[32] = {0}; + s8 thermal; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhd", &thermal); + + if (num < 1) + return count; + + kfree_data->thermal = thermal; + } + + return count; +} + +static ssize_t proc_set_tx_gain_offset(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter; + char tmp[32] = {0}; + u8 rf_path; + s8 offset; + + adapter = (_adapter *)rtw_netdev_priv(dev); + if (!adapter) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + u8 write_value; + int num = sscanf(tmp, "%hhu %hhd", &rf_path, &offset); + + if (num < 2) + return count; + + DBG_871X("write rf_path:%u tx gain offset:%d\n", rf_path, offset); + rtw_rf_set_tx_gain_offset(adapter, rf_path, offset); + } + + return count; +} +#endif /* CONFIG_RF_GAIN_OFFSET */ + +#ifdef CONFIG_BT_COEXIST +ssize_t proc_set_btinfo_evt(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]; + u8 btinfo[8]; + + if (count < 6) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + int num = 0; + + _rtw_memset(btinfo, 0, 8); + + num = sscanf(tmp, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" + , &btinfo[0], &btinfo[1], &btinfo[2], &btinfo[3] + , &btinfo[4], &btinfo[5], &btinfo[6], &btinfo[7]); + + if (num < 6) + return -EINVAL; + + btinfo[1] = num-2; + + rtw_btinfo_cmd(padapter, btinfo, btinfo[1]+2); + } + + return count; +} + +static u8 btreg_read_type = 0; +static u16 btreg_read_addr = 0; +static int btreg_read_error = 0; +static u8 btreg_write_type = 0; +static u16 btreg_write_addr = 0; +static int btreg_write_error = 0; + +static u8 *btreg_type[] = { + "rf", + "modem", + "bluewize", + "vendor", + "le" +}; + +static int btreg_parse_str(char *input, u8 *type, u16 *addr, u16 *val) +{ + u32 num; + u8 str[80] = {0}; + u8 t = 0; + u32 a, v; + u8 i, n; + u8 *p; + + + num = sscanf(input, "%s %x %x", str, &a, &v); + if (num < 2) { + DBG_871X("%s: INVALID input!(%s)\n", __FUNCTION__, input); + return -EINVAL; + } + if ((num < 3) && val) { + DBG_871X("%s: INVALID input!(%s)\n", __FUNCTION__, input); + return -EINVAL; + } + + /* convert to lower case for following type compare */ + p = str; + for ( ; *p; ++p) + *p = tolower(*p); + n = sizeof(btreg_type)/sizeof(btreg_type[0]); + for (i = 0; i < n; i++) { + if (!strcmp(str, btreg_type[i])) { + t = i; + break; + } + } + if (i == n) { + DBG_871X("%s: unknown type(%s)!\n", __FUNCTION__, str); + return -EINVAL; + } + + switch (t) { + case 0: + /* RF */ + if (a & 0xFFFFFF80) { + DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n", + __FUNCTION__, a, btreg_type[t], t); + return -EINVAL; + } + break; + case 1: + /* Modem */ + if (a & 0xFFFFFE00) { + DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n", + __FUNCTION__, a, btreg_type[t], t); + return -EINVAL; + } + break; + default: + /* Others(Bluewize, Vendor, LE) */ + if (a & 0xFFFFF000) { + DBG_871X("%s: INVALID address(0x%X) for type %s(%d)!\n", + __FUNCTION__, a, btreg_type[t], t); + return -EINVAL; + } + break; + } + + if (val) { + if (v & 0xFFFF0000) { + DBG_871X("%s: INVALID value(0x%x)!\n", __FUNCTION__, v); + return -EINVAL; + } + *val = (u16)v; + } + + *type = (u8)t; + *addr = (u16)a; + + return 0; +} + +int proc_get_btreg_read(struct seq_file *m, void *v) +{ + struct net_device *dev; + PADAPTER padapter; + u16 ret; + u32 data; + + + if (btreg_read_error) + return btreg_read_error; + + dev = m->private; + padapter = (PADAPTER)rtw_netdev_priv(dev); + + ret = rtw_btcoex_btreg_read(padapter, btreg_read_type, btreg_read_addr, &data); + if (CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) + DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X = 0x%08x\n", btreg_type[btreg_read_type], btreg_read_addr, data); + else + DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X read fail. error code = 0x%04x.\n", btreg_type[btreg_read_type], btreg_read_addr, ret); + + return 0; +} + +ssize_t proc_set_btreg_read(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + PADAPTER padapter; + u8 tmp[80] = {0}; + u32 num; + int err; + + + padapter = (PADAPTER)rtw_netdev_priv(dev); + + if (NULL == buffer) { + DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + if (count < 1) { + DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + num = count; + if (num > (sizeof(tmp) - 1)) + num = (sizeof(tmp) - 1); + + if (copy_from_user(tmp, buffer, num)) { + DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + err = btreg_parse_str(tmp, &btreg_read_type, &btreg_read_addr, NULL); + if (err) + goto exit; + + DBG_871X(FUNC_ADPT_FMT ": addr=(%s)0x%X\n", + FUNC_ADPT_ARG(padapter), btreg_type[btreg_read_type], btreg_read_addr); + +exit: + btreg_read_error = err; + + return count; +} + +int proc_get_btreg_write(struct seq_file *m, void *v) +{ + struct net_device *dev; + PADAPTER padapter; + u16 ret; + u32 data; + + + if (btreg_write_error < 0) + return btreg_write_error; + else if (btreg_write_error > 0) { + DBG_871X_SEL_NL(m, "BTREG write: (%s)0x%04X write fail. error code = 0x%04x.\n", btreg_type[btreg_write_type], btreg_write_addr, btreg_write_error); + return 0; + } + + dev = m->private; + padapter = (PADAPTER)rtw_netdev_priv(dev); + + ret = rtw_btcoex_btreg_read(padapter, btreg_write_type, btreg_write_addr, &data); + if (CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) + DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X = 0x%08x\n", btreg_type[btreg_write_type], btreg_write_addr, data); + else + DBG_871X_SEL_NL(m, "BTREG read: (%s)0x%04X read fail. error code = 0x%04x.\n", btreg_type[btreg_write_type], btreg_write_addr, ret); + + return 0; +} + +ssize_t proc_set_btreg_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + PADAPTER padapter; + u8 tmp[80] = {0}; + u32 num; + u16 val; + u16 ret; + int err; + + + padapter = (PADAPTER)rtw_netdev_priv(dev); + + if (NULL == buffer) { + DBG_871X(FUNC_ADPT_FMT ": input buffer is NULL!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + if (count < 1) { + DBG_871X(FUNC_ADPT_FMT ": input length is 0!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + num = count; + if (num > (sizeof(tmp) - 1)) + num = (sizeof(tmp) - 1); + + if (copy_from_user(tmp, buffer, num)) { + DBG_871X(FUNC_ADPT_FMT ": copy buffer from user space FAIL!\n", + FUNC_ADPT_ARG(padapter)); + err = -EFAULT; + goto exit; + } + + err = btreg_parse_str(tmp, &btreg_write_type, &btreg_write_addr, &val); + if (err) + goto exit; + + DBG_871X(FUNC_ADPT_FMT ": Set (%s)0x%X = 0x%x\n", + FUNC_ADPT_ARG(padapter), btreg_type[btreg_write_type], btreg_write_addr, val); + + ret = rtw_btcoex_btreg_write(padapter, btreg_write_type, btreg_write_addr, val); + if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) + err = ret; + +exit: + btreg_write_error = err; + + return count; +} +#endif /* CONFIG_BT_COEXIST */ + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM +static int proc_get_best_chan(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + u8 best_24g_ch = 0, best_5g_ch = 0; + + rtw_hal_get_odm_var(adapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch)); + + DBG_871X_SEL_NL(m, "Best 2.4G CH:%u\n", best_24g_ch); + DBG_871X_SEL_NL(m, "Best 5G CH:%u\n", best_5g_ch); + return 0; +} + +static ssize_t proc_set_acs(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]; + u8 acs_satae = 0; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu", &acs_satae); + + if (num < 1) + return -EINVAL; + + if (1 == acs_satae) + rtw_acs_start(padapter, _TRUE); + else + rtw_acs_start(padapter, _FALSE); + + } + return count; +} +#endif + +static int proc_get_hal_spec(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + dump_hal_spec(m, adapter); + return 0; +} + +/* +* rtw_adapter_proc: +* init/deinit when register/unregister net_device +*/ +const struct rtw_proc_hdl adapter_proc_hdls [] = { + {"write_reg", proc_get_dummy, proc_set_write_reg}, + {"read_reg", proc_get_read_reg, proc_set_read_reg}, + {"adapters_status", proc_get_dump_adapters_status, NULL}, + {"fwstate", proc_get_fwstate, NULL}, + {"sec_info", proc_get_sec_info, NULL}, + {"mlmext_state", proc_get_mlmext_state, NULL}, + {"qos_option", proc_get_qos_option, NULL}, + {"ht_option", proc_get_ht_option, NULL}, + {"rf_info", proc_get_rf_info, NULL}, + {"scan_param", proc_get_scan_param, proc_set_scan_param}, + {"scan_abort", proc_get_scan_abort, NULL}, +#ifdef CONFIG_SCAN_BACKOP + {"backop_flags_sta", proc_get_backop_flags_sta, proc_set_backop_flags_sta}, + {"backop_flags_ap", proc_get_backop_flags_ap, proc_set_backop_flags_ap}, +#endif + {"survey_info", proc_get_survey_info, proc_set_survey_info}, + {"ap_info", proc_get_ap_info, NULL}, + {"trx_info", proc_get_trx_info, proc_reset_trx_info}, + {"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}, + {"sec_cam", proc_get_sec_cam, proc_set_sec_cam}, + {"sec_cam_cache", proc_get_sec_cam_cache, NULL}, + {"suspend_info", proc_get_suspend_resume_info, NULL}, + {"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}, + {"roam_tgt_addr", proc_get_dummy, proc_set_roam_tgt_addr}, +#endif /* CONFIG_LAYER2_ROAMING */ + +#ifdef CONFIG_SDIO_HCI + {"sd_f0_reg_dump", proc_get_sd_f0_reg_dump, NULL}, + {"sdio_local_reg_dump", proc_get_sdio_local_reg_dump, NULL}, +#endif /* CONFIG_SDIO_HCI */ + + {"fwdl_test_case", proc_get_dummy, proc_set_fwdl_test_case}, + {"del_rx_ampdu_test_case", proc_get_dummy, proc_set_del_rx_ampdu_test_case}, + {"wait_hiq_empty", proc_get_dummy, proc_set_wait_hiq_empty}, + + {"mac_reg_dump", proc_get_mac_reg_dump, NULL}, + {"bb_reg_dump", proc_get_bb_reg_dump, NULL}, + {"rf_reg_dump", proc_get_rf_reg_dump, NULL}, + +#ifdef CONFIG_AP_MODE + {"all_sta_info", proc_get_all_sta_info, NULL}, +#endif /* CONFIG_AP_MODE */ + +#ifdef DBG_MEMORY_LEAK + {"_malloc_cnt", proc_get_malloc_cnt, NULL}, +#endif /* DBG_MEMORY_LEAK */ + +#ifdef CONFIG_FIND_BEST_CHANNEL + {"best_channel", proc_get_best_channel, proc_set_best_channel}, +#endif + + {"rx_signal", proc_get_rx_signal, proc_set_rx_signal}, + {"hw_info", proc_get_hw_status, NULL}, + +#ifdef CONFIG_80211N_HT + {"ht_enable", proc_get_ht_enable, proc_set_ht_enable}, + {"bw_mode", proc_get_bw_mode, proc_set_bw_mode}, + {"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}, + {"mac_rptbuf", proc_get_mac_rptbuf, NULL}, + + //{"path_rssi", proc_get_two_path_rssi, NULL}, +// {"rssi_disp",proc_get_rssi_disp, proc_set_rssi_disp}, + +#ifdef CONFIG_BT_COEXIST + {"btcoex_dbg", proc_get_btcoex_dbg, proc_set_btcoex_dbg}, + {"btcoex", proc_get_btcoex_info, NULL}, + {"btinfo_evt", proc_get_dummy, proc_set_btinfo_evt}, + {"btreg_read", proc_get_btreg_read, proc_set_btreg_read}, + {"btreg_write", proc_get_btreg_write, proc_set_btreg_write}, +#endif /* CONFIG_BT_COEXIST */ + +#if defined(DBG_CONFIG_ERROR_DETECT) + {"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}, + {"current_tx_rate", proc_get_current_tx_rate, NULL}, +#ifdef CONFIG_GPIO_API + {"gpio_info",proc_get_gpio,proc_set_gpio}, + {"gpio_set_output_value",proc_get_dummy,proc_set_gpio_output_value}, + {"gpio_set_direction",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}, + {"int_logs", proc_get_int_logs, NULL}, +#endif + +#ifdef CONFIG_PCI_HCI + {"rx_ring", proc_get_rx_ring, NULL}, + {"tx_ring", proc_get_tx_ring, NULL}, +#endif +#ifdef CONFIG_GPIO_WAKEUP + {"wowlan_gpio_info", proc_get_wowlan_gpio_info, + proc_set_wowlan_gpio_info}, +#endif +#ifdef CONFIG_P2P_WOWLAN + {"p2p_wowlan_info", proc_get_p2p_wowlan_info, NULL}, +#endif + {"country_code", proc_get_country_code, proc_set_country_code}, + {"chan_plan", proc_get_chan_plan, proc_set_chan_plan}, +#ifdef CONFIG_DFS_MASTER + {"dfs_master_test_case", proc_get_dfs_master_test_case, proc_set_dfs_master_test_case}, + {"update_non_ocp", proc_get_dummy, proc_set_update_non_ocp}, + {"radar_detect", proc_get_dummy, proc_set_radar_detect}, +#endif + {"new_bcn_max", proc_get_new_bcn_max, proc_set_new_bcn_max}, + {"sink_udpport",proc_get_udpport,proc_set_udpport}, +#ifdef DBG_RX_COUNTER_DUMP + {"dump_rx_cnt_mode",proc_get_rx_cnt_dump,proc_set_rx_cnt_dump}, +#endif + {"change_bss_chbw", NULL, proc_set_change_bss_chbw}, + {"target_tx_power", proc_get_target_tx_power, NULL}, + {"tx_power_by_rate", proc_get_tx_power_by_rate, NULL}, + {"tx_power_limit", proc_get_tx_power_limit, NULL}, + {"tx_power_ext_info", proc_get_tx_power_ext_info, proc_set_tx_power_ext_info}, +#ifdef CONFIG_RF_GAIN_OFFSET + {"tx_gain_offset", proc_get_dummy, proc_set_tx_gain_offset}, + {"kfree_flag", proc_get_kfree_flag, proc_set_kfree_flag}, + {"kfree_bb_gain", proc_get_kfree_bb_gain, proc_set_kfree_bb_gain}, + {"kfree_thermal", proc_get_kfree_thermal, proc_set_kfree_thermal}, +#endif +#ifdef CONFIG_POWER_SAVING + {"ps_info",proc_get_ps_info, NULL}, +#endif +#ifdef CONFIG_TDLS + {"tdls_info", proc_get_tdls_info, NULL}, +#endif + {"monitor", proc_get_monitor, proc_set_monitor}, + +#ifdef CONFIG_AUTO_CHNL_SEL_NHM + {"acs", proc_get_best_chan, proc_set_acs}, +#endif +#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER + {"rtkm_info", proc_get_rtkm_info, NULL} +#endif + {"efuse_map", proc_get_efuse_map, NULL}, +#ifdef CONFIG_IEEE80211W + {"11w_tx_sa_query", proc_get_tx_sa_query, proc_set_tx_sa_query}, + {"11w_tx_deauth", proc_get_tx_deauth, proc_set_tx_deauth}, + {"11w_tx_auth", proc_get_tx_auth, proc_set_tx_auth}, +#endif /* CONFIG_IEEE80211W */ + {"hal_spec", proc_get_hal_spec, NULL}, +}; + +const int adapter_proc_hdls_num = sizeof(adapter_proc_hdls) / sizeof(struct rtw_proc_hdl); + +static int rtw_adapter_proc_open(struct inode *inode, struct file *file) +{ + ssize_t index = (ssize_t)PDE_DATA(inode); + const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index; + + return single_open(file, hdl->show, proc_get_parent_data(inode)); +} + +static ssize_t rtw_adapter_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); + const struct rtw_proc_hdl *hdl = adapter_proc_hdls+index; + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; + + if (write) + return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private); + + return -EROFS; +} + +static const struct file_operations rtw_adapter_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_adapter_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = rtw_adapter_proc_write, +}; + +int proc_get_odm_dbg_comp(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + rtw_odm_dbg_comp_msg(m, adapter); + + return 0; +} + +ssize_t proc_set_odm_dbg_comp(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + + u64 dbg_comp; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%llx", &dbg_comp); + + if (num != 1) + return count; + + rtw_odm_dbg_comp_set(adapter, dbg_comp); + } + + return count; +} + +int proc_get_odm_dbg_level(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + rtw_odm_dbg_level_msg(m, adapter); + + return 0; +} + +ssize_t proc_set_odm_dbg_level(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + + u32 dbg_level; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%u", &dbg_level); + + if (num != 1) + return count; + + rtw_odm_dbg_level_set(adapter, dbg_level); + } + + return count; +} + +int proc_get_odm_ability(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + + rtw_odm_ability_msg(m, adapter); + + return 0; +} + +ssize_t proc_set_odm_ability(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *adapter = (_adapter *)rtw_netdev_priv(dev); + char tmp[32]; + + u32 ability; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x", &ability); + + if (num != 1) + return count; + + rtw_odm_ability_set(adapter, ability); + } + + return count; +} + +int proc_get_odm_adaptivity(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + + rtw_odm_adaptivity_parm_msg(m, padapter); + + return 0; +} + +ssize_t proc_set_odm_adaptivity(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 TH_L2H_ini; + u32 TH_L2H_ini_mode2; + s8 TH_EDCCA_HL_diff; + s8 TH_EDCCA_HL_diff_mode2; + u8 EDCCA_enable; + + if (count < 1) + return -EFAULT; + + if (count > sizeof(tmp)) { + rtw_warn_on(1); + return -EFAULT; + } + + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%x %hhd %x %hhd %hhu", &TH_L2H_ini, &TH_EDCCA_HL_diff, &TH_L2H_ini_mode2, &TH_EDCCA_HL_diff_mode2, &EDCCA_enable); + + if (num != 5) + return count; + + rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)TH_L2H_ini_mode2, TH_EDCCA_HL_diff_mode2, EDCCA_enable); + } + + 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 +*/ +const struct rtw_proc_hdl odm_proc_hdls [] = { + {"dbg_comp", proc_get_odm_dbg_comp, proc_set_odm_dbg_comp}, + {"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); + +static int rtw_odm_proc_open(struct inode *inode, struct file *file) +{ + ssize_t index = (ssize_t)PDE_DATA(inode); + const struct rtw_proc_hdl *hdl = odm_proc_hdls+index; + + return single_open(file, hdl->show, proc_get_parent_data(inode)); +} + +static ssize_t rtw_odm_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) +{ + ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); + const struct rtw_proc_hdl *hdl = odm_proc_hdls+index; + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; + + if (write) + return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private); + + return -EROFS; +} + +static const struct file_operations rtw_odm_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_odm_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = rtw_odm_proc_write, +}; + +struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) +{ + struct proc_dir_entry *dir_odm = NULL; + struct proc_dir_entry *entry = NULL; + _adapter *adapter = rtw_netdev_priv(dev); + ssize_t i; + + if (adapter->dir_dev == NULL) { + rtw_warn_on(1); + goto exit; + } + + if (adapter->dir_odm != NULL) { + rtw_warn_on(1); + goto exit; + } + + dir_odm = rtw_proc_create_dir("odm", adapter->dir_dev, dev); + if (dir_odm == NULL) { + rtw_warn_on(1); + goto exit; + } + + adapter->dir_odm = dir_odm; + + for (i=0;idir_odm; + + if (dir_odm == NULL) { + rtw_warn_on(1); + return; + } + + for (i=0;idir_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) +{ + struct proc_dir_entry *drv_proc = get_rtw_drv_proc(); + struct proc_dir_entry *dir_dev = NULL; + struct proc_dir_entry *entry = NULL; + _adapter *adapter = rtw_netdev_priv(dev); + u8 rf_type; + ssize_t i; + + if (drv_proc == NULL) { + rtw_warn_on(1); + goto exit; + } + + if (adapter->dir_dev != NULL) { + rtw_warn_on(1); + goto exit; + } + + dir_dev = rtw_proc_create_dir(dev->name, drv_proc, dev); + if (dir_dev == NULL) { + rtw_warn_on(1); + goto exit; + } + + adapter->dir_dev = dir_dev; + + for (i=0;idir_dev; + + if (dir_dev == NULL) { + rtw_warn_on(1); + return; + } + + for (i=0;iname, drv_proc); + + adapter->dir_dev = NULL; +} + +void rtw_adapter_proc_replace(struct net_device *dev) +{ + struct proc_dir_entry *drv_proc = get_rtw_drv_proc(); + struct proc_dir_entry *dir_dev = NULL; + _adapter *adapter = rtw_netdev_priv(dev); + int i; + + dir_dev = adapter->dir_dev; + + if (dir_dev == NULL) { + rtw_warn_on(1); + return; + } + + for (i=0;iold_ifname, drv_proc); + + adapter->dir_dev = NULL; + + rtw_adapter_proc_init(dev); + +} + +#endif /* CONFIG_PROC_DEBUG */ + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.h b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.h new file mode 100644 index 00000000..9aee7bf5 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/rtw_proc.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 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_PROC_H__ +#define __RTW_PROC_H__ + +#include +#include + +struct rtw_proc_hdl { + char *name; + int (*show)(struct seq_file *, void *); + ssize_t (*write)(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data); +}; + +#ifdef CONFIG_PROC_DEBUG + +struct proc_dir_entry *get_rtw_drv_proc(void); +int rtw_drv_proc_init(void); +void rtw_drv_proc_deinit(void); +struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev); +void rtw_adapter_proc_deinit(struct net_device *dev); +void rtw_adapter_proc_replace(struct net_device *dev); + +#else //!CONFIG_PROC_DEBUG + +#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 + +#endif //__RTW_PROC_H__ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_intf.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_intf.c new file mode 100644 index 00000000..cca2c318 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_intf.c @@ -0,0 +1,1058 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _HCI_INTF_C_ + +#include +#include +#include + +#ifndef CONFIG_SDIO_HCI +#error "CONFIG_SDIO_HCI shall be on!\n" +#endif + +#ifdef CONFIG_PLATFORM_INTEL_BYT +#ifdef CONFIG_ACPI +#include +#include +#include "rtw_android.h" +#endif +static int wlan_en_gpio = -1; +#endif //CONFIG_PLATFORM_INTEL_BYT + +#ifndef dev_to_sdio_func +#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) +#endif + +#ifdef CONFIG_WOWLAN +static struct mmc_host *mmc_host = NULL; +#endif + +static const struct sdio_device_id sdio_ids[] = +{ +#ifdef CONFIG_RTL8723B + { SDIO_DEVICE(0x024c, 0xB723),.driver_data = RTL8723B}, +#endif +#ifdef CONFIG_RTL8188E + { SDIO_DEVICE(0x024c, 0x8179),.driver_data = RTL8188E}, +#endif //CONFIG_RTL8188E + +#ifdef CONFIG_RTL8821A + { SDIO_DEVICE(0x024c, 0x8821),.driver_data = RTL8821}, +#endif //CONFIG_RTL8821A + +#ifdef CONFIG_RTL8192E + { SDIO_DEVICE(0x024c, 0x818B),.driver_data = RTL8192E}, +#endif //CONFIG_RTL8192E + +#ifdef CONFIG_RTL8703B + { SDIO_DEVICE(0x024c, 0xB703), .driver_data = RTL8703B}, +#endif + +#ifdef CONFIG_RTL8188F + {SDIO_DEVICE(0x024c, 0xF179), .driver_data = RTL8188F}, +#endif + +#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) /* temporarily add this to accept all sdio wlan id */ + { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) }, +#endif + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(sdio, sdio_ids); + +static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id); +static void rtw_dev_remove(struct sdio_func *func); +static int rtw_sdio_resume(struct device *dev); +static int rtw_sdio_suspend(struct device *dev); +extern void rtw_dev_unload(PADAPTER padapter); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static const struct dev_pm_ops rtw_sdio_pm_ops = { + .suspend = rtw_sdio_suspend, + .resume = rtw_sdio_resume, +}; +#endif + +struct sdio_drv_priv { + struct sdio_driver r871xs_drv; + int drv_registered; +}; + +static struct sdio_drv_priv sdio_drvpriv = { + .r871xs_drv.probe = rtw_drv_init, + .r871xs_drv.remove = rtw_dev_remove, + .r871xs_drv.name = (char*)DRV_NAME, + .r871xs_drv.id_table = sdio_ids, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + .r871xs_drv.drv = { + .pm = &rtw_sdio_pm_ops, + } + #endif +}; + +static void sd_sync_int_hdl(struct sdio_func *func) +{ + struct dvobj_priv *psdpriv; + + psdpriv = sdio_get_drvdata(func); + + if (!psdpriv->padapters[IFACE_ID0]) { + DBG_871X("%s if1 == NULL\n", __func__); + return; + } + + rtw_sdio_set_irq_thd(psdpriv, current); + sd_int_hdl(psdpriv->padapters[IFACE_ID0]); + rtw_sdio_set_irq_thd(psdpriv, NULL); +} + +int sdio_alloc_irq(struct dvobj_priv *dvobj) +{ + PSDIO_DATA psdio_data; + struct sdio_func *func; + int err; + + psdio_data = &dvobj->intf_data; + func = psdio_data->func; + + sdio_claim_host(func); + + err = sdio_claim_irq(func, &sd_sync_int_hdl); + if (err) + { + dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++; + printk(KERN_CRIT "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); + } + else + { + dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++; + dvobj->irq_alloc = 1; + } + + sdio_release_host(func); + + return err?_FAIL:_SUCCESS; +} + +void sdio_free_irq(struct dvobj_priv *dvobj) +{ + PSDIO_DATA psdio_data; + struct sdio_func *func; + int err; + + if (dvobj->irq_alloc) { + psdio_data = &dvobj->intf_data; + func = psdio_data->func; + + if (func) { + sdio_claim_host(func); + err = sdio_release_irq(func); + if (err) + { + dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; + DBG_871X_LEVEL(_drv_err_,"%s: sdio_release_irq FAIL(%d)!\n", __func__, err); + } + else + dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; + sdio_release_host(func); + } + dvobj->irq_alloc = 0; + } +} + +#ifdef CONFIG_GPIO_WAKEUP +extern unsigned int oob_irq; +extern unsigned int oob_gpio; +static irqreturn_t gpio_hostwakeup_irq_thread(int irq, void *data) +{ + PADAPTER padapter = (PADAPTER)data; + DBG_871X_LEVEL(_drv_always_, "gpio_hostwakeup_irq_thread\n"); + /* Disable interrupt before calling handler */ + //disable_irq_nosync(oob_irq); + rtw_lock_suspend_timeout(HZ/2); +#ifdef CONFIG_PLATFORM_ARM_SUN6I + return 0; +#else + return IRQ_HANDLED; +#endif +} + +static u8 gpio_hostwakeup_alloc_irq(PADAPTER padapter) +{ + int err; + u32 status = 0; + + if (oob_irq == 0) { + DBG_871X("oob_irq ZERO!\n"); + return _FAIL; + } + + DBG_871X("%s : oob_irq = %d\n", __func__, oob_irq); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) + status = IRQF_NO_SUSPEND; +#endif + + if (HIGH_ACTIVE) + status |= IRQF_TRIGGER_RISING; + else + status |= IRQF_TRIGGER_FALLING; + + err = request_threaded_irq(oob_irq, gpio_hostwakeup_irq_thread, NULL, + status, "rtw_wifi_gpio_wakeup", padapter); + + if (err < 0) { + DBG_871X("Oops: can't allocate gpio irq %d err:%d\n", oob_irq, err); + return _FALSE; + } else { + DBG_871X("allocate gpio irq %d ok\n", oob_irq); + } + +#ifndef CONFIG_PLATFORM_ARM_SUN8I + enable_irq_wake(oob_irq); +#endif + return _SUCCESS; +} + +static void gpio_hostwakeup_free_irq(PADAPTER padapter) +{ + wifi_free_gpio(oob_gpio); + + if (oob_irq == 0) + return; + +#ifndef CONFIG_PLATFORM_ARM_SUN8I + disable_irq_wake(oob_irq); +#endif + free_irq(oob_irq, padapter); +} +#endif + +static u32 sdio_init(struct dvobj_priv *dvobj) +{ + PSDIO_DATA psdio_data; + struct sdio_func *func; + int err; + +_func_enter_; + + psdio_data = &dvobj->intf_data; + func = psdio_data->func; + + //3 1. init SDIO bus + sdio_claim_host(func); + + err = sdio_enable_func(func); + if (err) { + dvobj->drv_dbg.dbg_sdio_init_error_cnt++; + DBG_8192C(KERN_CRIT "%s: sdio_enable_func FAIL(%d)!\n", __func__, err); + goto release; + } + + err = sdio_set_block_size(func, 512); + if (err) { + dvobj->drv_dbg.dbg_sdio_init_error_cnt++; + DBG_8192C(KERN_CRIT "%s: sdio_set_block_size FAIL(%d)!\n", __func__, err); + goto release; + } + psdio_data->block_transfer_len = 512; + psdio_data->tx_block_mode = 1; + psdio_data->rx_block_mode = 1; + +release: + sdio_release_host(func); + +exit: +_func_exit_; + + if (err) return _FAIL; + return _SUCCESS; +} + +static void sdio_deinit(struct dvobj_priv *dvobj) +{ + struct sdio_func *func; + int err; + + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+sdio_deinit\n")); + + func = dvobj->intf_data.func; + + if (func) { + sdio_claim_host(func); + err = sdio_disable_func(func); + if (err) + { + dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++; + DBG_8192C(KERN_ERR "%s: sdio_disable_func(%d)\n", __func__, err); + } + + if (dvobj->irq_alloc) { + err = sdio_release_irq(func); + if (err) + { + dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; + DBG_8192C(KERN_ERR "%s: sdio_release_irq(%d)\n", __func__, err); + } + else + dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; + } + + sdio_release_host(func); + } +} + +static void rtw_decide_chip_type_by_device_id(struct dvobj_priv *dvobj, const struct sdio_device_id *pdid) +{ + dvobj->chip_type = pdid->driver_data; + +#if defined(CONFIG_RTL8188E) + if (dvobj->chip_type == RTL8188E) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8188ES; + DBG_871X("CHIP TYPE: RTL8188E\n"); + } +#endif + +#if defined(CONFIG_RTL8723B) + dvobj->chip_type = RTL8723B; + dvobj->HardwareType = HARDWARE_TYPE_RTL8723BS; +#endif + +#if defined(CONFIG_RTL8821A) + if (dvobj->chip_type == RTL8821) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8821S; + DBG_871X("CHIP TYPE: RTL8821A\n"); + } +#endif + +#if defined(CONFIG_RTL8192E) + if (dvobj->chip_type == RTL8192E) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8192ES; + DBG_871X("CHIP TYPE: RTL8192E\n"); + } +#endif + +#if defined(CONFIG_RTL8703B) + if (dvobj->chip_type == RTL8703B) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8703BS; + DBG_871X("CHIP TYPE: RTL8703B\n"); + } +#endif + +#if defined(CONFIG_RTL8188F) + if (dvobj->chip_type == RTL8188F) { + dvobj->HardwareType = HARDWARE_TYPE_RTL8188FS; + DBG_871X("CHIP TYPE: RTL8188F\n"); + } +#endif +} + +static struct dvobj_priv *sdio_dvobj_init(struct sdio_func *func, const struct sdio_device_id *pdid) +{ + int status = _FAIL; + struct dvobj_priv *dvobj = NULL; + PSDIO_DATA psdio; +_func_enter_; + + if((dvobj = devobj_init()) == NULL) { + goto exit; + } + + sdio_set_drvdata(func, dvobj); + + psdio = &dvobj->intf_data; + psdio->func = func; + + if (sdio_init(dvobj) != _SUCCESS) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!\n", __FUNCTION__)); + goto free_dvobj; + } + + dvobj->interface_type = RTW_SDIO; + rtw_decide_chip_type_by_device_id(dvobj, pdid); + + rtw_reset_continual_io_error(dvobj); + status = _SUCCESS; + +free_dvobj: + if (status != _SUCCESS && dvobj) { + sdio_set_drvdata(func, NULL); + + devobj_deinit(dvobj); + + dvobj = NULL; + } +exit: +_func_exit_; + return dvobj; +} + +static void sdio_dvobj_deinit(struct sdio_func *func) +{ + struct dvobj_priv *dvobj = sdio_get_drvdata(func); +_func_enter_; + + sdio_set_drvdata(func, NULL); + if (dvobj) { + sdio_deinit(dvobj); + devobj_deinit(dvobj); + } + +_func_exit_; + return; +} + +u8 rtw_set_hal_ops(PADAPTER padapter) +{ + //alloc memory for HAL DATA + if(rtw_hal_data_init(padapter) == _FAIL) + return _FAIL; + +#if defined(CONFIG_RTL8188E) + if (rtw_get_chip_type(padapter) == RTL8188E) + rtl8188es_set_hal_ops(padapter); +#endif + +#if defined(CONFIG_RTL8723B) + if (rtw_get_chip_type(padapter) == RTL8723B) + rtl8723bs_set_hal_ops(padapter); +#endif + +#if defined(CONFIG_RTL8821A) + if (rtw_get_chip_type(padapter) == RTL8821) + rtl8821as_set_hal_ops(padapter); +#endif + +#if defined(CONFIG_RTL8192E) + if (rtw_get_chip_type(padapter) == RTL8192E) + rtl8192es_set_hal_ops(padapter); +#endif + +#if defined(CONFIG_RTL8703B) + if (rtw_get_chip_type(padapter) == RTL8703B) + rtl8703bs_set_hal_ops(padapter); +#endif + +#if defined(CONFIG_RTL8188F) + if (rtw_get_chip_type(padapter) == RTL8188F) + rtl8188fs_set_hal_ops(padapter); +#endif + + if( rtw_hal_ops_check(padapter) == _FAIL) + return _FAIL; + + if (hal_spec_init(padapter) == _FAIL) + return _FAIL; + + return _SUCCESS; +} + +static void sd_intf_start(PADAPTER padapter) +{ + if (padapter == NULL) { + DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__); + return; + } + + // hal dep + rtw_hal_enable_interrupt(padapter); +} + +static void sd_intf_stop(PADAPTER padapter) +{ + if (padapter == NULL) { + DBG_8192C(KERN_ERR "%s: padapter is NULL!\n", __func__); + return; + } + + // hal dep + rtw_hal_disable_interrupt(padapter); +} + + +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN +PADAPTER g_test_adapter = NULL; +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN + +_adapter *rtw_sdio_if1_init(struct dvobj_priv *dvobj) +{ + int status = _FAIL; + PADAPTER padapter = NULL; + + padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter)); + if (padapter == NULL) + goto exit; + + if (loadparam(padapter) != _SUCCESS) + goto free_adapter; + +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN + g_test_adapter = padapter; +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN + padapter->dvobj = dvobj; + + rtw_set_drv_stopped(padapter);/*init*/ + + dvobj->padapters[dvobj->iface_nums++] = padapter; + padapter->iface_id = IFACE_ID0; + +#if defined(CONFIG_CONCURRENT_MODE) + //set adapter_type/iface type for primary padapter + padapter->isprimary = _TRUE; + padapter->adapter_type = PRIMARY_ADAPTER; + #ifndef CONFIG_HWPORT_SWAP + padapter->iface_type = IFACE_PORT0; + #else + padapter->iface_type = IFACE_PORT1; + #endif +#endif + + //3 3. init driver special setting, interface, OS and hardware relative + + //4 3.1 set hardware operation functions + if (rtw_set_hal_ops(padapter)== _FAIL) + goto free_hal_data; + + //3 5. initialize Chip version + padapter->intf_start = &sd_intf_start; + padapter->intf_stop = &sd_intf_stop; + + padapter->intf_init = &sdio_init; + padapter->intf_deinit = &sdio_deinit; + padapter->intf_alloc_irq = &sdio_alloc_irq; + padapter->intf_free_irq = &sdio_free_irq; + + if (rtw_init_io_priv(padapter, sdio_set_intf_ops) == _FAIL) + { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, + ("rtw_drv_init: Can't init io_priv\n")); + goto free_hal_data; + } + + rtw_hal_read_chip_version(padapter); + + rtw_hal_chip_configure(padapter); + +#ifdef CONFIG_BT_COEXIST + rtw_btcoex_Initialize(padapter); +#endif // CONFIG_BT_COEXIST + + //3 6. read efuse/eeprom data + rtw_hal_read_chip_info(padapter); + + //3 7. init driver common data + if (rtw_init_drv_sw(padapter) == _FAIL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, + ("rtw_drv_init: Initialize driver software resource Failed!\n")); + goto free_hal_data; + } + + //3 8. get WLan MAC address + // set mac addr + rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter)); +#ifdef CONFIG_P2P + rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter)); +#endif /* CONFIG_P2P */ + + rtw_hal_disable_interrupt(padapter); + + DBG_871X("bDriverStopped:%s, bSurpriseRemoved:%s, bup:%d, hw_init_completed:%d\n" + , rtw_is_drv_stopped(padapter)?"True":"False" + , rtw_is_surprise_removed(padapter)?"True":"False" + , padapter->bup + , rtw_get_hw_init_completed(padapter) + ); + + status = _SUCCESS; + +free_hal_data: + if (status != _SUCCESS && padapter->HalData) + rtw_hal_free_data(padapter); + +free_adapter: + if (status != _SUCCESS && padapter) { + rtw_vmfree((u8 *)padapter, sizeof(*padapter)); + padapter = NULL; + } +exit: + return padapter; +} + +static void rtw_sdio_if1_deinit(_adapter *if1) +{ + struct mlme_priv *pmlmepriv= &if1->mlmepriv; + + if(check_fwstate(pmlmepriv, _FW_LINKED)) + rtw_disassoc_cmd(if1, 0, _FALSE); + +#ifdef CONFIG_AP_MODE + free_mlme_ap_info(if1); + #ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_unload(if1); + #endif +#endif + +#ifdef CONFIG_GPIO_WAKEUP +#ifdef CONFIG_PLATFORM_ARM_SUN6I + sw_gpio_eint_set_enable(gpio_eint_wlan, 0); + sw_gpio_irq_free(eint_wlan_handle); +#else + gpio_hostwakeup_free_irq(if1); +#endif +#endif + + rtw_cancel_all_timer(if1); + +#ifdef CONFIG_WOWLAN + adapter_to_pwrctl(if1)->wowlan_mode=_FALSE; + DBG_871X_LEVEL(_drv_always_, "%s wowlan_mode:%d\n", __func__, adapter_to_pwrctl(if1)->wowlan_mode); +#endif //CONFIG_WOWLAN + + rtw_dev_unload(if1); + DBG_871X("+r871xu_dev_remove, hw_init_completed=%d\n", rtw_get_hw_init_completed(if1)); + + rtw_free_drv_sw(if1); + + /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */ + rtw_os_ndev_free(if1); + + rtw_vmfree((u8 *)if1, sizeof(_adapter)); + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link down\n"); + rtd2885_wlan_netlink_sendMsg("linkdown", "8712"); +#endif + +#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN + g_test_adapter = NULL; +#endif // RTW_SUPPORT_PLATFORM_SHUTDOWN +} + +/* + * drv_init() - a device potentially for us + * + * notes: drv_init() is called when the bus driver has located a card for us to support. + * We accept the new device by returning 0. + */ +static int rtw_drv_init( + struct sdio_func *func, + const struct sdio_device_id *id) +{ + int status = _FAIL; + struct net_device *pnetdev; + PADAPTER if1 = NULL, if2 = NULL; + struct dvobj_priv *dvobj; + +#ifdef CONFIG_PLATFORM_INTEL_BYT + +#ifdef CONFIG_ACPI + acpi_handle handle; + struct acpi_device *adev; +#endif + +#if defined(CONFIG_ACPI) && defined(CONFIG_GPIO_WAKEUP) + handle = ACPI_HANDLE(&func->dev); + + if (handle) { + /* Dont try to do acpi pm for the wifi module */ + if (!handle || acpi_bus_get_device(handle, &adev)) + DBG_871X("Could not get acpi pointer!\n"); + else { + adev->flags.power_manageable = 0; + DBG_871X("Disabling ACPI power management support!\n"); + } + oob_gpio = acpi_get_gpio_by_index(&func->dev, 0, NULL); + DBG_871X("rtw_drv_init: ACPI_HANDLE found oob_gpio %d!\n", oob_gpio); + wifi_configure_gpio(); + } + else + DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n"); +#endif + +#if defined(CONFIG_ACPI) + if (&func->dev && ACPI_HANDLE(&func->dev)) { + wlan_en_gpio = acpi_get_gpio_by_index(&func->dev, 1, NULL); + DBG_871X("rtw_drv_init: ACPI_HANDLE found wlan_en %d!\n", wlan_en_gpio); + } + else + DBG_871X("rtw_drv_init: ACPI_HANDLE NOT found!\n"); +#endif +#endif //CONFIG_PLATFORM_INTEL_BYT + + + RT_TRACE(_module_hci_intfs_c_, _drv_info_, + ("+rtw_drv_init: vendor=0x%04x device=0x%04x class=0x%02x\n", + func->vendor, func->device, func->class)); + + if ((dvobj = sdio_dvobj_init(func, id)) == NULL) { + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("initialize device object priv Failed!\n")); + goto exit; + } + + if ((if1 = rtw_sdio_if1_init(dvobj)) == NULL) { + DBG_871X("rtw_init_primary_adapter Failed!\n"); + goto free_dvobj; + } + +#ifdef CONFIG_CONCURRENT_MODE + if ((if2 = rtw_drv_if2_init(if1, sdio_set_intf_ops)) == NULL) { + goto free_if1; + } +#endif + + //dev_alloc_name && register_netdev + if (rtw_os_ndevs_init(dvobj) != _SUCCESS) + goto free_if2; + +#ifdef CONFIG_HOSTAPD_MLME + hostapd_mode_init(if1); +#endif + +#ifdef CONFIG_PLATFORM_RTD2880B + DBG_871X("wlan link up\n"); + rtd2885_wlan_netlink_sendMsg("linkup", "8712"); +#endif + + if (sdio_alloc_irq(dvobj) != _SUCCESS) + goto os_ndevs_deinit; + +#ifdef CONFIG_GPIO_WAKEUP +#ifdef CONFIG_PLATFORM_ARM_SUN6I + eint_wlan_handle = sw_gpio_irq_request(gpio_eint_wlan, TRIG_EDGE_NEGATIVE,(peint_handle)gpio_hostwakeup_irq_thread, NULL); + if (!eint_wlan_handle) { + DBG_871X( "%s: request irq failed\n",__func__); + return -1; + } +#else + gpio_hostwakeup_alloc_irq(if1); +#endif +#endif + +#ifdef CONFIG_GLOBAL_UI_PID + if(ui_pid[1]!=0) { + DBG_871X("ui_pid[1]:%d\n",ui_pid[1]); + rtw_signal_process(ui_pid[1], SIGUSR2); + } +#endif + + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("-871x_drv - drv_init, success!\n")); + + status = _SUCCESS; + +os_ndevs_deinit: + if (status != _SUCCESS) + rtw_os_ndevs_deinit(dvobj); +free_if2: + if(status != _SUCCESS && if2) { + #ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_stop(if2); + rtw_drv_if2_free(if2); + #endif + } +free_if1: + if (status != _SUCCESS && if1) { + rtw_sdio_if1_deinit(if1); + } +free_dvobj: + if (status != _SUCCESS) + sdio_dvobj_deinit(func); +exit: + return status == _SUCCESS?0:-ENODEV; +} + +static void rtw_dev_remove(struct sdio_func *func) +{ + struct dvobj_priv *dvobj = sdio_get_drvdata(func); + struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj); + PADAPTER padapter = dvobj->padapters[IFACE_ID0]; + +_func_enter_; + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("+rtw_dev_remove\n")); + + dvobj->processing_dev_remove = _TRUE; + + /* TODO: use rtw_os_ndevs_deinit instead at the first stage of driver's dev deinit function */ + rtw_os_ndevs_unregister(dvobj); + + if (!rtw_is_surprise_removed(padapter)) { + int err; + + /* test surprise remove */ + sdio_claim_host(func); + sdio_readb(func, 0, &err); + sdio_release_host(func); + if (err == -ENOMEDIUM) { + rtw_set_surprise_removed(padapter); + DBG_871X(KERN_NOTICE "%s: device had been removed!\n", __func__); + } + } + +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + rtw_unregister_early_suspend(pwrctl); +#endif + + if (padapter->bFWReady == _TRUE) { + rtw_ps_deny(padapter, PS_DENY_DRV_REMOVE); + rtw_pm_set_ips(padapter, IPS_NONE); + rtw_pm_set_lps(padapter, PS_MODE_ACTIVE); + LeaveAllPowerSaveMode(padapter); + } + rtw_set_drv_stopped(padapter); /*for stop thread*/ +#ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_stop(dvobj->padapters[IFACE_ID1]); +#endif + +#ifdef CONFIG_BT_COEXIST + #ifdef CONFIG_BT_COEXIST_SOCKET_TRX + if (GET_HAL_DATA(padapter)->EEPROMBluetoothCoexist) + rtw_btcoex_close_socket(padapter); + #endif + rtw_btcoex_HaltNotify(padapter); +#endif + + rtw_sdio_if1_deinit(padapter); + +#ifdef CONFIG_CONCURRENT_MODE + rtw_drv_if2_free(dvobj->padapters[IFACE_ID1]); +#endif + + sdio_dvobj_deinit(func); + + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("-rtw_dev_remove\n")); + +_func_exit_; +} +extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal); +extern int pm_netdev_close(struct net_device *pnetdev,u8 bnormal); + +static int rtw_sdio_suspend(struct device *dev) +{ + struct sdio_func *func =dev_to_sdio_func(dev); + struct dvobj_priv *psdpriv = sdio_get_drvdata(func); + struct pwrctrl_priv *pwrpriv = NULL; + _adapter *padapter = NULL; + struct debug_priv *pdbgpriv = NULL; + int ret = 0; + u8 ch, bw, offset; + + if (psdpriv == NULL) + goto exit; + + pwrpriv = dvobj_to_pwrctl(psdpriv); + padapter = psdpriv->padapters[IFACE_ID0]; + pdbgpriv = &psdpriv->drv_dbg; + if (rtw_is_drv_stopped(padapter)) { + DBG_871X("%s bDriverStopped == _TRUE\n", __func__); + goto exit; + } + + if (pwrpriv->bInSuspend == _TRUE) + { + DBG_871X("%s bInSuspend = %d\n", __func__, pwrpriv->bInSuspend); + pdbgpriv->dbg_suspend_error_cnt++; + goto exit; + } + + ret = rtw_suspend_common(padapter); + +exit: +#ifdef CONFIG_RTW_SDIO_PM_KEEP_POWER +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) + //Android 4.0 don't support WIFI close power + //or power down or clock will close after wifi resume, + //this is sprd's bug in Android 4.0, but sprd don't + //want to fix it. + //we have test power under 8723as, power consumption is ok + if (func) { + mmc_pm_flag_t pm_flag = 0; + pm_flag = sdio_get_host_pm_caps(func); + DBG_871X("cmd: %s: suspend: PM flag = 0x%x\n", sdio_func_id(func), pm_flag); + if (!(pm_flag & MMC_PM_KEEP_POWER)) { + DBG_871X("%s: cannot remain alive while host is suspended\n", sdio_func_id(func)); + if (pdbgpriv) + pdbgpriv->dbg_suspend_error_cnt++; + return -ENOSYS; + } else { + DBG_871X("cmd: suspend with MMC_PM_KEEP_POWER\n"); + sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + } + } +#endif +#endif + return ret; +} +int rtw_resume_process(_adapter *padapter) +{ + struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); + struct dvobj_priv *psdpriv = padapter->dvobj; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + if (pwrpriv->bInSuspend == _FALSE) + { + pdbgpriv->dbg_resume_error_cnt++; + DBG_871X("%s bInSuspend = %d\n", __FUNCTION__, pwrpriv->bInSuspend); + return -1; + } + + return rtw_resume_common(padapter); +} + +static int rtw_sdio_resume(struct device *dev) +{ + struct sdio_func *func =dev_to_sdio_func(dev); + struct dvobj_priv *psdpriv = sdio_get_drvdata(func); + struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); + _adapter *padapter = psdpriv->padapters[IFACE_ID0]; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + int ret = 0; + struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + pdbgpriv->dbg_resume_cnt++; + + if(pwrpriv->bInternalAutoSuspend) + { + ret = rtw_resume_process(padapter); + } + else + { +#ifdef CONFIG_PLATFORM_INTEL_BYT + if(0) +#else + if(pwrpriv->wowlan_mode || pwrpriv->wowlan_ap_mode) +#endif + { + rtw_resume_lock_suspend(); + ret = rtw_resume_process(padapter); + rtw_resume_unlock_suspend(); + } + else + { +#ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_resume_in_workqueue(pwrpriv); +#else + if (rtw_is_earlysuspend_registered(pwrpriv)) + { + /* jeff: bypass resume here, do in late_resume */ + rtw_set_do_late_resume(pwrpriv, _TRUE); + } + else + { + rtw_resume_lock_suspend(); + ret = rtw_resume_process(padapter); + rtw_resume_unlock_suspend(); + } +#endif + } + } + pmlmeext->last_scan_time = rtw_get_current_time(); + DBG_871X("<======== %s return %d\n", __FUNCTION__, ret); + return ret; + +} + +static int __init rtw_drv_entry(void) +{ + int ret = 0; + + DBG_871X_LEVEL(_drv_always_, "module init start\n"); + dump_drv_version(RTW_DBGDUMP); +#ifdef BTCOEXVERSION + DBG_871X_LEVEL(_drv_always_, DRV_NAME" BT-Coex version = %s\n", BTCOEXVERSION); +#endif // BTCOEXVERSION + + ret = platform_wifi_power_on(); + if (ret) + { + DBG_871X("%s: power on failed!!(%d)\n", __FUNCTION__, ret); + ret = -1; + goto exit; + } + + sdio_drvpriv.drv_registered = _TRUE; + rtw_suspend_lock_init(); + rtw_drv_proc_init(); + rtw_ndev_notifier_register(); + + ret = sdio_register_driver(&sdio_drvpriv.r871xs_drv); + if (ret != 0) + { + sdio_drvpriv.drv_registered = _FALSE; + rtw_suspend_lock_uninit(); + rtw_drv_proc_deinit(); + rtw_ndev_notifier_unregister(); + DBG_871X("%s: register driver failed!!(%d)\n", __FUNCTION__, ret); + goto poweroff; + } + +#ifndef CONFIG_PLATFORM_INTEL_BYT + rtw_android_wifictrl_func_add(); +#endif //!CONFIG_PLATFORM_INTEL_BYT + goto exit; + +poweroff: + platform_wifi_power_off(); +exit: + DBG_871X_LEVEL(_drv_always_, "module init ret=%d\n", ret); + return ret; +} + +static void __exit rtw_drv_halt(void) +{ + DBG_871X_LEVEL(_drv_always_, "module exit start\n"); + + sdio_drvpriv.drv_registered = _FALSE; + + sdio_unregister_driver(&sdio_drvpriv.r871xs_drv); + + rtw_android_wifictrl_func_del(); + + platform_wifi_power_off(); + + rtw_suspend_lock_uninit(); + rtw_drv_proc_deinit(); + rtw_ndev_notifier_unregister(); + + DBG_871X_LEVEL(_drv_always_, "module exit success\n"); + + rtw_mstat_dump(RTW_DBGDUMP); +} + +#ifdef CONFIG_PLATFORM_INTEL_BYT +int rtw_sdio_set_power(int on) +{ + + if(wlan_en_gpio >= 0){ + if(on) + gpio_set_value(wlan_en_gpio,1); + else + gpio_set_value(wlan_en_gpio,0); + } + + return 0; +} +#endif //CONFIG_PLATFORM_INTEL_BYT + +module_init(rtw_drv_entry); +module_exit(rtw_drv_halt); + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_ops_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_ops_linux.c new file mode 100644 index 00000000..0ea81f15 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/sdio_ops_linux.c @@ -0,0 +1,910 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + *******************************************************************************/ +#define _SDIO_OPS_LINUX_C_ + +#include + +static bool rtw_sdio_claim_host_needed(struct sdio_func *func) +{ + struct dvobj_priv *dvobj = sdio_get_drvdata(func); + PSDIO_DATA sdio_data = &dvobj->intf_data; + + if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current) + return _FALSE; + return _TRUE; +} + +inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, _thread_hdl_ thd_hdl) +{ + PSDIO_DATA sdio_data = &dvobj->intf_data; + + sdio_data->sys_sdio_irq_thd = thd_hdl; +} + +u8 sd_f0_read8(struct intf_hdl *pintfhdl,u32 addr, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + u8 v=0; + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_f0_readb(func, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return v; +} + +void sd_f0_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_f0_writeb(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); + +_func_exit_; +} + +/* + * Return: + * 0 Success + * others Fail + */ +s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + int err=0, i; + struct sdio_func *func; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + + for (i = 0; i < cnt; i++) { + pdata[i] = sdio_readb(func, addr+i, &err); + if (err) { + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr+i); + break; + } + } + +_func_exit_; + + return err; +} + +/* + * Return: + * 0 Success + * others Fail + */ +s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + int err=0, i; + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + +_func_exit_; + + return err; +} + +/* + * Return: + * 0 Success + * others Fail + */ +s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + int err=0, i; + struct sdio_func *func; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + + for (i = 0; i < cnt; i++) { + sdio_writeb(func, pdata[i], addr+i, &err); + if (err) { + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr+i, pdata[i]); + break; + } + } + +_func_exit_; + + return err; +} + +/* + * Return: + * 0 Success + * others Fail + */ +s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + int err=0, i; + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); + +_func_exit_; + + return err; +} + +u8 _sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + u8 v=0; + struct sdio_func *func; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + + v = sdio_readb(func, addr, err); + + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return v; +} + +u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + u8 v=0; + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_readb(func, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return v; +} + +u16 sd_read16(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + u16 v=0; + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_readw(func, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return v; +} + +u32 _sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + u32 v=0; + struct sdio_func *func; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + + v = sdio_readl(func, addr, err); + + if (err && *err) + { + int i; + + DBG_871X(KERN_ERR "%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v); + + *err = 0; + for(i=0; ipadapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return v; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + v = sdio_readl(func, addr, err); + if (claim_needed) + sdio_release_host(func); + + if (err && *err) + { + int i; + + DBG_871X(KERN_ERR "%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v); + + *err = 0; + for(i=0; ipadapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return ; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_writeb(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v); + +_func_exit_; +} + +void sd_write16(struct intf_hdl *pintfhdl, u32 addr, u16 v, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + bool claim_needed; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return ; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_writew(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + if (err && *err) + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%04x\n", __func__, *err, addr, v); + +_func_exit_; +} + +void _sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return ; + } + + func = psdio->func; + + sdio_writel(func, v, addr, err); + + if (err && *err) + { + int i; + + DBG_871X(KERN_ERR "%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v); + + *err = 0; + for(i=0; ipadapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return ; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + sdio_writel(func, v, addr, err); + if (claim_needed) + sdio_release_host(func); + + if (err && *err) + { + int i; + + DBG_871X(KERN_ERR "%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v); + + *err = 0; + for(i=0; ipadapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + + if (unlikely((cnt==1) || (cnt==2))) + { + int i; + u8 *pbuf = (u8*)pdata; + + for (i = 0; i < cnt; i++) + { + *(pbuf+i) = sdio_readb(func, addr+i, &err); + + if (err) { + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr); + break; + } + } + return err; + } + + err = sdio_memcpy_fromio(func, pdata, addr, cnt); + if (err) { + DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d\n", __func__, err, addr, cnt); + } + +_func_exit_; + + return err; +} + +/* + * Use CMD53 to read data from SDIO device. + * + * Parameters: + * psdio pointer of SDIO_DATA + * addr address to read + * cnt amount to read + * pdata pointer to put data, this should be a "DMA:able scratch buffer"! + * + * Return: + * 0 Success + * others Fail + */ +s32 sd_read(struct intf_hdl * pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + bool claim_needed; + s32 err= -EPERM; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_read(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); +_func_exit_; + return err; +} + +/* + * Use CMD53 to write data to SDIO device. + * This function MUST be called after sdio_claim_host() or + * in SDIO ISR(host had been claimed). + * + * Parameters: + * psdio pointer of SDIO_DATA + * addr address to write + * cnt amount to write + * pdata data pointer, this should be a "DMA:able scratch buffer"! + * + * Return: + * 0 Success + * others Fail + */ +s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + u32 size; + s32 err=-EPERM; + +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; +// size = sdio_align_size(func, cnt); + + if (unlikely((cnt==1) || (cnt==2))) + { + int i; + u8 *pbuf = (u8*)pdata; + + for (i = 0; i < cnt; i++) + { + sdio_writeb(func, *(pbuf+i), addr+i, &err); + if (err) { + DBG_871X(KERN_ERR "%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf+i)); + break; + } + } + + return err; + } + + size = cnt; + err = sdio_memcpy_toio(func, addr, pdata, size); + if (err) { + DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size); + } + +_func_exit_; + + return err; +} + +/* + * Use CMD53 to write data to SDIO device. + * + * Parameters: + * psdio pointer of SDIO_DATA + * addr address to write + * cnt amount to write + * pdata data pointer, this should be a "DMA:able scratch buffer"! + * + * Return: + * 0 Success + * others Fail + */ +s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) +{ + PADAPTER padapter; + struct dvobj_priv *psdiodev; + PSDIO_DATA psdio; + + struct sdio_func *func; + bool claim_needed; + s32 err=-EPERM; +_func_enter_; + padapter = pintfhdl->padapter; + psdiodev = pintfhdl->pintf_dev; + psdio = &psdiodev->intf_data; + + if (rtw_is_surprise_removed(padapter)) { + //DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); + return err; + } + + func = psdio->func; + claim_needed = rtw_sdio_claim_host_needed(func); + + if (claim_needed) + sdio_claim_host(func); + err = _sd_write(pintfhdl, addr, cnt, pdata); + if (claim_needed) + sdio_release_host(func); +_func_exit_; + return err; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/wifi_regd.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/wifi_regd.c new file mode 100644 index 00000000..154a28fa --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/wifi_regd.c @@ -0,0 +1,548 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + *****************************************************************************/ + +#include + +#ifdef CONFIG_IOCTL_CFG80211 + +#include + +static struct country_code_to_enum_rd allCountries[] = { + {COUNTRY_CODE_USER, "RD"}, +}; + +/* + * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags) + */ + +/* + *Only these channels all allow active + *scan on all world regulatory domains + */ + +/* 2G chan 01 - chan 11 */ +#define RTW_2GHZ_CH01_11 \ + REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) + +/* + *We enable active scan on these a case + *by case basis by regulatory domain + */ + +/* 2G chan 12 - chan 13, PASSIV SCAN */ +#define RTW_2GHZ_CH12_13 \ + REG_RULE(2467-10, 2472+10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN) + +/* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */ +#define RTW_2GHZ_CH14 \ + REG_RULE(2484-10, 2484+10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) + +/* 5G chan 36 - chan 64 */ +#define RTW_5GHZ_5150_5350 \ + REG_RULE(5150-10, 5350+10, 40, 0, 30, \ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +/* 5G chan 100 - chan 165 */ +#define RTW_5GHZ_5470_5850 \ + REG_RULE(5470-10, 5850+10, 40, 0, 30, \ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +/* 5G chan 149 - chan 165 */ +#define RTW_5GHZ_5725_5850 \ + REG_RULE(5725-10, 5850+10, 40, 0, 30, \ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +/* 5G chan 36 - chan 165 */ +#define RTW_5GHZ_5150_5850 \ + REG_RULE(5150-10, 5850+10, 40, 0, 30, \ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +static const struct ieee80211_regdomain rtw_regdom_rd = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_5GHZ_5150_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_12_13 = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_no_midband = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_5GHZ_5150_5350, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_60_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_14_60_64 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_2GHZ_CH14, + RTW_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtw_regdom_14 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTW_2GHZ_CH01_11, + RTW_2GHZ_CH12_13, + RTW_2GHZ_CH14, + } +}; + +#if 0 +static struct rtw_regulatory *rtw_regd; +#endif + +static bool _rtw_is_radar_freq(u16 center_freq) +{ + return (center_freq >= 5260 && center_freq <= 5700); +} + +#if 0 // not_yet +static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + u32 bandwidth = 0; + int r; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (_rtw_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + r = freq_reg_info(wiphy, ch->center_freq, + bandwidth, ®_rule); + if (r) + continue; + + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (! + (reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + u32 bandwidth = 0; + int r; + + if (!wiphy->bands[IEEE80211_BAND_2GHZ]) + return; + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + + /* + * If no country IE has been received always enable active scan + * on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + * If a country IE has been received check its rule for this + * channel first before enabling active scan. The passive scan + * would have been enforced by the initial processing of our + * custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} +#endif + +/* + * Always apply Radar/DFS rules on + * freq range 5260 MHz - 5700 MHz + */ +static void _rtw_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!_rtw_is_radar_freq(ch->center_freq)) + continue; +#ifdef CONFIG_DFS + #if defined(CONFIG_DFS_MASTER) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) + 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 +#endif //CONFIG_DFS + +#if 0 + /* + * We always enable radar detection/DFS on this + * frequency range. Additionally we also apply on + * this frequency range: + * - If STA mode does not yet have DFS supports disable + * active scanning + * - If adhoc mode does not support DFS yet then disable + * adhoc in the frequency. + * - If AP mode does not yet support radar detection/DFS + * do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; +#endif + } +} + +static void _rtw_reg_apply_flags(struct wiphy *wiphy) +{ +#if 1 // by channel plan + _adapter *padapter = wiphy_to_adapter(wiphy); + u8 channel_plan = padapter->mlmepriv.ChannelPlan; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set; + u8 max_chan_nums = pmlmeext->max_chan_nums; + + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i, j; + u16 channel; + u32 freq; + + // all channels disable + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + sband = wiphy->bands[i]; + + if (sband) { + for (j = 0; j < sband->n_channels; j++) { + ch = &sband->channels[j]; + + if (ch) + ch->flags = IEEE80211_CHAN_DISABLED; + } + } + } + + // channels apply by channel plans. + for (i = 0; i < max_chan_nums; i++) { + channel = channel_set[i].ChannelNum; + freq = rtw_ch2freq(channel); + + ch = ieee80211_get_channel(wiphy, freq); + if (ch) { + if (channel_set[i].ScanType == SCAN_PASSIVE) { + #if defined(CONFIG_DFS_MASTER) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) + ch->flags = 0; + #elif (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 + } + else { + ch->flags = 0; + } + } + } + +#else + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i, j; + u16 channels[37] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, + 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 153, + 157, 161, 165 + }; + u16 channel; + u32 freq; + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + sband = wiphy->bands[i]; + + if (sband) + for (j = 0; j < sband->n_channels; j++) { + ch = &sband->channels[j]; + + if (ch) + ch->flags = IEEE80211_CHAN_DISABLED; + } + } + + for (i = 0; i < 37; i++) { + channel = channels[i]; + freq = rtw_ch2freq(channel); + + ch = ieee80211_get_channel(wiphy, freq); + if (ch) { + if (channel <= 11) + ch->flags = 0; + else + ch->flags = 0; //IEEE80211_CHAN_PASSIVE_SCAN; + } + //printk("%s: freq %d(%d) flag 0x%02X \n", __func__, freq, channel, ch->flags); + } +#endif +} + +static void _rtw_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct rtw_regulatory *reg) +{ + //_rtw_reg_apply_beaconing_flags(wiphy, initiator); + //_rtw_reg_apply_active_scan_flags(wiphy, initiator); + return; +} + +static int _rtw_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct rtw_regulatory *reg) +{ + + /* Hard code flags */ + _rtw_reg_apply_flags(wiphy); + + /* We always apply this */ + _rtw_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + DBG_8192C("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER"); + _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, + reg); + break; + case NL80211_REGDOM_SET_BY_CORE: + DBG_8192C("%s: %s\n", __func__, + "NL80211_REGDOM_SET_BY_CORE to DRV"); + _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, + reg); + break; + case NL80211_REGDOM_SET_BY_USER: + DBG_8192C("%s: %s\n", __func__, + "NL80211_REGDOM_SET_BY_USER to DRV"); + _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, + reg); + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + DBG_8192C("%s: %s\n", __func__, + "NL80211_REGDOM_SET_BY_COUNTRY_IE"); + _rtw_reg_apply_world_flags(wiphy, request->initiator, reg); + break; + } + + return 0; +} + +static const struct ieee80211_regdomain *_rtw_regdomain_select(struct + rtw_regulatory + *reg) +{ +#if 0 + switch (reg->country_code) { + case COUNTRY_CODE_USER: + default: + return &rtw_regdom_rd; + } +#else + return &rtw_regdom_rd; +#endif +} + +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 = rtw_reg_notifier; + + #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 + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; + wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + #endif + + regd = _rtw_regdomain_select(reg); + wiphy_apply_custom_regulatory(wiphy, regd); + + /* Hard code flags */ + _rtw_reg_apply_flags(wiphy); + _rtw_reg_apply_radar_flags(wiphy); + _rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); +} + +static struct country_code_to_enum_rd *_rtw_regd_find_country(u16 countrycode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { + if (allCountries[i].countrycode == countrycode) + return &allCountries[i]; + } + return NULL; +} + +int rtw_regd_init(_adapter * padapter) +{ + struct wiphy *wiphy = padapter->rtw_wdev->wiphy; + +#if 0 + if (rtw_regd == NULL) { + rtw_regd = (struct rtw_regulatory *) + rtw_malloc(sizeof(struct rtw_regulatory)); + + rtw_regd->alpha2[0] = '9'; + rtw_regd->alpha2[1] = '9'; + + rtw_regd->country_code = COUNTRY_CODE_USER; + } + + DBG_8192C("%s: Country alpha2 being used: %c%c\n", + __func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]); +#endif + + _rtw_regd_init_wiphy(NULL, wiphy); + + return 0; +} +#endif //CONFIG_IOCTL_CFG80211 + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/xmit_linux.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/xmit_linux.c new file mode 100644 index 00000000..12926994 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/linux/xmit_linux.c @@ -0,0 +1,546 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ +#define _XMIT_OSDEP_C_ + +#include + +#define DBG_DUMP_OS_QUEUE_CTL 0 + +uint rtw_remainder_len(struct pkt_file *pfile) +{ + return (pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start))); +} + +void _rtw_open_pktfile (_pkt *pktptr, struct pkt_file *pfile) +{ +_func_enter_; + + pfile->pkt = pktptr; + pfile->cur_addr = pfile->buf_start = pktptr->data; + pfile->pkt_len = pfile->buf_len = pktptr->len; + + pfile->cur_buffer = pfile->buf_start ; + +_func_exit_; +} + +uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) +{ + uint len = 0; + +_func_enter_; + + len = rtw_remainder_len(pfile); + len = (rlen > len)? len: rlen; + + if(rmem) + skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len); + + pfile->cur_addr += len; + pfile->pkt_len -= len; + +_func_exit_; + + return len; +} + +sint rtw_endofpktfile(struct pkt_file *pfile) +{ +_func_enter_; + + if (pfile->pkt_len == 0) { +_func_exit_; + return _TRUE; + } + +_func_exit_; + + return _FALSE; +} + +void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib) +{ + +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + struct sk_buff *skb = (struct sk_buff *)pkt; + pattrib->hw_tcp_csum = 0; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (skb_shinfo(skb)->nr_frags == 0) + { + const struct iphdr *ip = ip_hdr(skb); + if (ip->protocol == IPPROTO_TCP) { + // TCP checksum offload by HW + DBG_871X("CHECKSUM_PARTIAL TCP\n"); + pattrib->hw_tcp_csum = 1; + //skb_checksum_help(skb); + } else if (ip->protocol == IPPROTO_UDP) { + //DBG_871X("CHECKSUM_PARTIAL UDP\n"); +#if 1 + skb_checksum_help(skb); +#else + // Set UDP checksum = 0 to skip checksum check + struct udphdr *udp = skb_transport_header(skb); + udp->check = 0; +#endif + } else { + DBG_871X("%s-%d TCP CSUM offload Error!!\n", __FUNCTION__, __LINE__); + WARN_ON(1); /* we need a WARN() */ + } + } + else { // IP fragmentation case + DBG_871X("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __FUNCTION__, __LINE__); + skb_checksum_help(skb); + } + } +#endif + +} + +int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz, u8 flag) +{ + if (alloc_sz > 0) { +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + pxmitbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)alloc_sz, &pxmitbuf->dma_transfer_addr); + pxmitbuf->pbuf = pxmitbuf->pallocated_buf; + if(pxmitbuf->pallocated_buf == NULL) + return _FAIL; +#else // CONFIG_USE_USB_BUFFER_ALLOC_TX + + pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); + if (pxmitbuf->pallocated_buf == NULL) + { + return _FAIL; + } + + pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); + +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + } + + if (flag) { +#ifdef CONFIG_USB_HCI + int i; + for(i=0; i<8; i++) + { + pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); + if(pxmitbuf->pxmit_urb[i] == NULL) + { + DBG_871X("pxmitbuf->pxmit_urb[i]==NULL"); + return _FAIL; + } + } +#endif + } + + return _SUCCESS; +} + +void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz, u8 flag) +{ + if (flag) { +#ifdef CONFIG_USB_HCI + int i; + + for(i=0; i<8; i++) + { + if(pxmitbuf->pxmit_urb[i]) + { + //usb_kill_urb(pxmitbuf->pxmit_urb[i]); + usb_free_urb(pxmitbuf->pxmit_urb[i]); + } + } +#endif + } + + if (free_sz > 0 ) { +#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + struct usb_device *pusbd = pdvobjpriv->pusbdev; + + rtw_usb_buffer_free(pusbd, (size_t)free_sz, pxmitbuf->pallocated_buf, pxmitbuf->dma_transfer_addr); + pxmitbuf->pallocated_buf = NULL; + pxmitbuf->dma_transfer_addr = 0; +#else // CONFIG_USE_USB_BUFFER_ALLOC_TX + if(pxmitbuf->pallocated_buf) + rtw_mfree(pxmitbuf->pallocated_buf, free_sz); +#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX + } +} + +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) + +inline static bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + + if (padapter->registrypriv.wifi_spec) { + 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(pxmitpriv->free_xmitframe_cnt<=4) + return _TRUE; + } +#else + 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); +} + +void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe) +{ + if(pxframe->pkt) + rtw_os_pkt_complete(padapter, pxframe->pkt); + + pxframe->pkt = NULL; +} + +void rtw_os_xmit_schedule(_adapter *padapter) +{ + _adapter *pri_adapter = padapter; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + if(!padapter) + return; + +#ifdef CONFIG_CONCURRENT_MODE + if(padapter->adapter_type > PRIMARY_ADAPTER) + pri_adapter = padapter->pbuddy_adapter; +#endif + + if (_rtw_queue_empty(&padapter->xmitpriv.pending_xmitbuf_queue) == _FALSE) + _rtw_up_sema(&pri_adapter->xmitpriv.xmit_sema); + + +#else + _irqL irqL; + struct xmit_priv *pxmitpriv; + + if(!padapter) + return; + + pxmitpriv = &padapter->xmitpriv; + + _enter_critical_bh(&pxmitpriv->lock, &irqL); + + if(rtw_txframes_pending(padapter)) + { + tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); + } + + _exit_critical_bh(&pxmitpriv->lock, &irqL); +#endif +} + +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 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; +} + +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 (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 +} + +#ifdef CONFIG_TX_MCAST2UNI +int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb) +{ + struct sta_priv *pstapriv = &padapter->stapriv; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irqL; + _list *phead, *plist; + struct sk_buff *newskb; + struct sta_info *psta = NULL; + u8 chk_alive_num = 0; + char chk_alive_list[NUM_STA]; + u8 bc_addr[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 null_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + int i; + s32 res; + + DBG_COUNTER(padapter->tx_logs.os_tx_m2u); + + _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //free sta asoc_queue + while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { + int stainfo_offset; + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); + + stainfo_offset = rtw_stainfo_offset(pstapriv, psta); + if (stainfo_offset_valid(stainfo_offset)) { + chk_alive_list[chk_alive_num++] = stainfo_offset; + } + } + _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); + + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + if(!(psta->state &_FW_LINKED)) + { + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_fw_linked); + continue; + } + + /* avoid come from STA1 and send back STA1 */ + if (_rtw_memcmp(psta->hwaddr, &skb->data[6], 6) == _TRUE + || _rtw_memcmp(psta->hwaddr, null_addr, 6) == _TRUE + || _rtw_memcmp(psta->hwaddr, bc_addr, 6) == _TRUE + ) + { + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_self); + continue; + } + + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry); + + newskb = rtw_skb_copy(skb); + + if (newskb) { + _rtw_memcpy(newskb->data, psta->hwaddr, 6); + res = rtw_xmit(padapter, &newskb); + if (res < 0) { + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_xmit); + DBG_871X("%s()-%d: rtw_xmit() return error! res=%d\n", __FUNCTION__, __LINE__, res); + pxmitpriv->tx_drop++; + rtw_skb_free(newskb); + } + } else { + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb); + DBG_871X("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__); + pxmitpriv->tx_drop++; + //rtw_skb_free(skb); + return _FALSE; // Caller shall tx this multicast frame via normal way. + } + } + + rtw_skb_free(skb); + return _TRUE; +} +#endif // CONFIG_TX_MCAST2UNI + + +int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; +#ifdef CONFIG_TX_MCAST2UNI + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + extern int rtw_mc2u_disable; +#endif // CONFIG_TX_MCAST2UNI + s32 res = 0; +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) + u16 queue; +#endif + +_func_enter_; + + if(padapter->registrypriv.mp_mode) + { + DBG_871X("MP_TX_DROP_OS_FRAME\n"); + goto drop_packet; + } + DBG_COUNTER(padapter->tx_logs.os_tx); + RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n")); + + if (rtw_if_up(padapter) == _FALSE) { + DBG_COUNTER(padapter->tx_logs.os_tx_err_up); + RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n")); + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__); + #endif + goto drop_packet; + } + + rtw_check_xmit_resource(padapter, pkt); + +#ifdef CONFIG_TX_MCAST2UNI + if ( !rtw_mc2u_disable + && check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE + && ( IP_MCAST_MAC(pkt->data) + || ICMPV6_MCAST_MAC(pkt->data) + #ifdef CONFIG_TX_BCAST2UNI + || is_broadcast_mac_addr(pkt->data) + #endif + ) + && (padapter->registrypriv.wifi_spec == 0) + ) + { + if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) { + res = rtw_mlcst2unicst(padapter, pkt); + if (res == _TRUE) { + goto exit; + } + } else { + //DBG_871X("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); + //DBG_871X("!m2u ); + DBG_COUNTER(padapter->tx_logs.os_tx_m2u_stop); + } + } +#endif // CONFIG_TX_MCAST2UNI + + res = rtw_xmit(padapter, &pkt); + if (res < 0) { + #ifdef DBG_TX_DROP_FRAME + DBG_871X("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__); + #endif + goto drop_packet; + } + + RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts)); + goto exit; + +drop_packet: + pxmitpriv->tx_drop++; + 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: + +_func_exit_; + + return 0; +} + +int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev) +{ + _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + int ret = 0; + + if (pkt) { + if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) { + rtw_monitor_xmit_entry((struct sk_buff *)pkt, pnetdev); + } else { + rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize); + ret = _rtw_xmit_entry(pkt, pnetdev); + } + + } + + return ret; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/osdep_service.c b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/osdep_service.c new file mode 100644 index 00000000..7079096c --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/os_dep/osdep_service.c @@ -0,0 +1,2526 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 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 + * + * + ******************************************************************************/ + + +#define _OSDEP_SERVICE_C_ + +#include + +#define RT_TAG '1178' + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX +atomic_t _malloc_cnt = ATOMIC_INIT(0); +atomic_t _malloc_size = ATOMIC_INIT(0); +#endif +#endif /* DBG_MEMORY_LEAK */ + + +#if defined(PLATFORM_LINUX) +/* +* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE +* @return: one of RTW_STATUS_CODE +*/ +inline int RTW_STATUS_CODE(int error_code){ + if(error_code >=0) + return _SUCCESS; + + switch(error_code) { + //case -ETIMEDOUT: + // return RTW_STATUS_TIMEDOUT; + default: + return _FAIL; + } +} +#else +inline int RTW_STATUS_CODE(int error_code){ + return error_code; +} +#endif + +u32 rtw_atoi(u8* s) +{ + + int num=0,flag=0; + int i; + for(i=0;i<=strlen(s);i++) + { + if(s[i] >= '0' && s[i] <= '9') + num = num * 10 + s[i] -'0'; + else if(s[0] == '-' && i==0) + flag =1; + else + break; + } + + if(flag == 1) + num = num * -1; + + return(num); + +} + +inline u8* _rtw_vmalloc(u32 sz) +{ + u8 *pbuf; +#ifdef PLATFORM_LINUX + pbuf = vmalloc(sz); +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_NOWAIT); +#endif + +#ifdef PLATFORM_WINDOWS + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + if ( pbuf != NULL) { + atomic_inc(&_malloc_cnt); + atomic_add(sz, &_malloc_size); + } +#endif +#endif /* DBG_MEMORY_LEAK */ + + return pbuf; +} + +inline u8* _rtw_zvmalloc(u32 sz) +{ + u8 *pbuf; +#ifdef PLATFORM_LINUX + pbuf = _rtw_vmalloc(sz); + if (pbuf != NULL) + memset(pbuf, 0, sz); +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT); +#endif +#ifdef PLATFORM_WINDOWS + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); + if (pbuf != NULL) + NdisFillMemory(pbuf, sz, 0); +#endif + + return pbuf; +} + +inline void _rtw_vmfree(u8 *pbuf, u32 sz) +{ +#ifdef PLATFORM_LINUX + vfree(pbuf); +#endif +#ifdef PLATFORM_FREEBSD + free(pbuf,M_DEVBUF); +#endif +#ifdef PLATFORM_WINDOWS + NdisFreeMemory(pbuf,sz, 0); +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + atomic_dec(&_malloc_cnt); + atomic_sub(sz, &_malloc_size); +#endif +#endif /* DBG_MEMORY_LEAK */ +} + +u8* _rtw_malloc(u32 sz) +{ + + u8 *pbuf=NULL; + +#ifdef PLATFORM_LINUX +#ifdef RTK_DMP_PLATFORM + if(sz > 0x4000) + pbuf = (u8 *)dvr_malloc(sz); + else +#endif + pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + +#endif +#ifdef PLATFORM_FREEBSD + pbuf = malloc(sz,M_DEVBUF,M_NOWAIT); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG); + +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + if ( pbuf != NULL) { + atomic_inc(&_malloc_cnt); + atomic_add(sz, &_malloc_size); + } +#endif +#endif /* DBG_MEMORY_LEAK */ + + return pbuf; + +} + + +u8* _rtw_zmalloc(u32 sz) +{ +#ifdef PLATFORM_FREEBSD + return malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT); +#else // PLATFORM_FREEBSD + u8 *pbuf = _rtw_malloc(sz); + + if (pbuf != NULL) { + +#ifdef PLATFORM_LINUX + memset(pbuf, 0, sz); +#endif + +#ifdef PLATFORM_WINDOWS + NdisFillMemory(pbuf, sz, 0); +#endif + + } + + return pbuf; +#endif // PLATFORM_FREEBSD +} + +void _rtw_mfree(u8 *pbuf, u32 sz) +{ + +#ifdef PLATFORM_LINUX +#ifdef RTK_DMP_PLATFORM + if(sz > 0x4000) + dvr_free(pbuf); + else +#endif + kfree(pbuf); + +#endif +#ifdef PLATFORM_FREEBSD + free(pbuf,M_DEVBUF); +#endif +#ifdef PLATFORM_WINDOWS + + NdisFreeMemory(pbuf,sz, 0); + +#endif + +#ifdef DBG_MEMORY_LEAK +#ifdef PLATFORM_LINUX + atomic_dec(&_malloc_cnt); + atomic_sub(sz, &_malloc_size); +#endif +#endif /* DBG_MEMORY_LEAK */ + +} + +#ifdef PLATFORM_FREEBSD +//review again +struct sk_buff * dev_alloc_skb(unsigned int size) +{ + struct sk_buff *skb=NULL; + u8 *data=NULL; + + //skb = (struct sk_buff *)_rtw_zmalloc(sizeof(struct sk_buff)); // for skb->len, etc. + skb = (struct sk_buff *)_rtw_malloc(sizeof(struct sk_buff)); + if(!skb) + goto out; + data = _rtw_malloc(size); + if(!data) + goto nodata; + + skb->head = (unsigned char*)data; + skb->data = (unsigned char*)data; + skb->tail = (unsigned char*)data; + skb->end = (unsigned char*)data + size; + skb->len = 0; + //printf("%s()-%d: skb=%p, skb->head = %p\n", __FUNCTION__, __LINE__, skb, skb->head); + +out: + return skb; +nodata: + _rtw_mfree((u8 *)skb, sizeof(struct sk_buff)); + skb = NULL; +goto out; + +} + +void dev_kfree_skb_any(struct sk_buff *skb) +{ + //printf("%s()-%d: skb->head = %p\n", __FUNCTION__, __LINE__, skb->head); + if(skb->head) + _rtw_mfree(skb->head, 0); + //printf("%s()-%d: skb = %p\n", __FUNCTION__, __LINE__, skb); + if(skb) + _rtw_mfree((u8 *)skb, 0); +} +struct sk_buff *skb_clone(const struct sk_buff *skb) +{ + return NULL; +} + +#endif /* PLATFORM_FREEBSD */ + +inline struct sk_buff *_rtw_skb_alloc(u32 sz) +{ +#ifdef PLATFORM_LINUX + return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return dev_alloc_skb(sz); +#endif /* PLATFORM_FREEBSD */ +} + +inline void _rtw_skb_free(struct sk_buff *skb) +{ + dev_kfree_skb_any(skb); +} + +inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return NULL; +#endif /* PLATFORM_FREEBSD */ +} + +inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return skb_clone(skb); +#endif /* PLATFORM_FREEBSD */ +} + +inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb) +{ +#ifdef PLATFORM_LINUX + skb->dev = ndev; + return netif_rx(skb); +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return (*ndev->if_input)(ndev, skb); +#endif /* PLATFORM_FREEBSD */ +} + +void _rtw_skb_queue_purge(struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(list)) != NULL) + _rtw_skb_free(skb); +} + +#ifdef CONFIG_USB_HCI +inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma) +{ +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + return usb_alloc_coherent(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); +#else + return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); +#endif +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + return (malloc(size, M_USBDEV, M_NOWAIT | M_ZERO)); +#endif /* PLATFORM_FREEBSD */ +} +inline void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma) +{ +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + usb_free_coherent(dev, size, addr, dma); +#else + usb_buffer_free(dev, size, addr, dma); +#endif +#endif /* PLATFORM_LINUX */ + +#ifdef PLATFORM_FREEBSD + free(addr, M_USBDEV); +#endif /* PLATFORM_FREEBSD */ +} +#endif /* CONFIG_USB_HCI */ + +#if defined(DBG_MEM_ALLOC) + +struct rtw_mem_stat { + ATOMIC_T alloc; // the memory bytes we allocate currently + ATOMIC_T peak; // the peak memory bytes we allocate + ATOMIC_T alloc_cnt; // the alloc count for alloc currently + ATOMIC_T alloc_err_cnt; // the error times we fail to allocate memory +}; + +struct rtw_mem_stat rtw_mem_type_stat[mstat_tf_idx(MSTAT_TYPE_MAX)]; +#ifdef RTW_MEM_FUNC_STAT +struct rtw_mem_stat rtw_mem_func_stat[mstat_ff_idx(MSTAT_FUNC_MAX)]; +#endif + +char *MSTAT_TYPE_str[] = { + "VIR", + "PHY", + "SKB", + "USB", +}; + +#ifdef RTW_MEM_FUNC_STAT +char *MSTAT_FUNC_str[] = { + "UNSP", + "IO", + "TXIO", + "RXIO", + "TX", + "RX", +}; +#endif + +void rtw_mstat_dump(void *sel) +{ + int i; + int value_t[4][mstat_tf_idx(MSTAT_TYPE_MAX)]; +#ifdef RTW_MEM_FUNC_STAT + int value_f[4][mstat_ff_idx(MSTAT_FUNC_MAX)]; +#endif + + int vir_alloc, vir_peak, vir_alloc_err, phy_alloc, phy_peak, phy_alloc_err; + int tx_alloc, tx_peak, tx_alloc_err, rx_alloc, rx_peak, rx_alloc_err; + + for(i=0;i 5000) { + // rtw_mstat_dump(RTW_DBGDUMP); + update_time=rtw_get_current_time(); + //} +} + +#ifndef SIZE_MAX + #define SIZE_MAX (~(size_t)0) +#endif + +struct mstat_sniff_rule { + enum mstat_f flags; + size_t lb; + size_t hb; +}; + +struct mstat_sniff_rule mstat_sniff_rules[] = { + {MSTAT_TYPE_PHY, 4097, SIZE_MAX}, +}; + +int mstat_sniff_rule_num = sizeof(mstat_sniff_rules)/sizeof(struct mstat_sniff_rule); + +bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size) +{ + int i; + for (i = 0; i= size) + return _TRUE; + } + + return _FALSE; +} + +inline u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_vmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_zvmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline void dbg_rtw_vmfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + _rtw_vmfree((pbuf), (sz)); + + rtw_mstat_update( + flags + , MSTAT_FREE + , sz + ); +} + +inline u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p=_rtw_malloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + u8 *p; + + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + p = _rtw_zmalloc((sz)); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , sz + ); + + return p; +} + +inline void dbg_rtw_mfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line) +{ + if (match_mstat_sniff_rules(flags, sz)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz)); + + _rtw_mfree((pbuf), (sz)); + + rtw_mstat_update( + flags + , MSTAT_FREE + , sz + ); +} + +inline struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, int line) +{ + struct sk_buff *skb; + unsigned int truesize = 0; + + skb = _rtw_skb_alloc(size); + + if(skb) + truesize = skb->truesize; + + if(!skb || truesize < size || match_mstat_sniff_rules(flags, truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, size, skb, truesize); + + rtw_mstat_update( + flags + , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb; +} + +inline void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, 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); + + _rtw_skb_free(skb); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); +} + +inline struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb_cp; + unsigned int truesize = skb->truesize; + unsigned int cp_truesize = 0; + + skb_cp = _rtw_skb_copy(skb); + if(skb_cp) + cp_truesize = skb_cp->truesize; + + if(!skb_cp || cp_truesize < truesize || match_mstat_sniff_rules(flags, cp_truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cp:%p, cp_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cp, cp_truesize); + + rtw_mstat_update( + flags + , skb_cp ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb_cp; +} + +inline struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line) +{ + struct sk_buff *skb_cl; + unsigned int truesize = skb->truesize; + unsigned int cl_truesize = 0; + + skb_cl = _rtw_skb_clone(skb); + if(skb_cl) + cl_truesize = skb_cl->truesize; + + if(!skb_cl || cl_truesize < truesize || match_mstat_sniff_rules(flags, cl_truesize)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cl:%p, cl_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cl, cl_truesize); + + rtw_mstat_update( + flags + , skb_cl ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , truesize + ); + + return skb_cl; +} + +inline int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line) +{ + int ret; + 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); + + ret = _rtw_netif_rx(ndev, skb); + + rtw_mstat_update( + flags + , MSTAT_FREE + , truesize + ); + + return ret; +} + +inline void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(list)) != NULL) + dbg_rtw_skb_free(skb, flags, func, line); +} + +#ifdef CONFIG_USB_HCI +inline void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, int line) +{ + void *p; + + if(match_mstat_sniff_rules(flags, size)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size); + + p = _rtw_usb_buffer_alloc(dev, size, dma); + + rtw_mstat_update( + flags + , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL + , size + ); + + return p; +} + +inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, int line) +{ + + if(match_mstat_sniff_rules(flags, size)) + DBG_871X("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size); + + _rtw_usb_buffer_free(dev, size, addr, dma); + + rtw_mstat_update( + flags + , MSTAT_FREE + , size + ); +} +#endif /* CONFIG_USB_HCI */ + +#endif /* defined(DBG_MEM_ALLOC) */ + +void* rtw_malloc2d(int h, int w, size_t size) +{ + int j; + + void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size ); + if(a == NULL) + { + DBG_871X("%s: alloc memory fail!\n", __FUNCTION__); + return NULL; + } + + for( j=0; jprev = pnew; + pnew->next = pnext; + pnew->prev = pprev; + pprev->next = pnew; +} +#endif /* PLATFORM_FREEBSD */ + + +void _rtw_init_listhead(_list *list) +{ + +#ifdef PLATFORM_LINUX + + INIT_LIST_HEAD(list); + +#endif + +#ifdef PLATFORM_FREEBSD + list->next = list; + list->prev = list; +#endif +#ifdef PLATFORM_WINDOWS + + NdisInitializeListHead(list); + +#endif + +} + + +/* +For the following list_xxx operations, +caller must guarantee the atomic context. +Otherwise, there will be racing condition. +*/ +u32 rtw_is_list_empty(_list *phead) +{ + +#ifdef PLATFORM_LINUX + + if (list_empty(phead)) + return _TRUE; + else + return _FALSE; + +#endif +#ifdef PLATFORM_FREEBSD + + if (phead->next == phead) + return _TRUE; + else + return _FALSE; + +#endif + + +#ifdef PLATFORM_WINDOWS + + if (IsListEmpty(phead)) + return _TRUE; + else + return _FALSE; + +#endif + + +} + +void rtw_list_insert_head(_list *plist, _list *phead) +{ + +#ifdef PLATFORM_LINUX + list_add(plist, phead); +#endif + +#ifdef PLATFORM_FREEBSD + __list_add(plist, phead, phead->next); +#endif + +#ifdef PLATFORM_WINDOWS + InsertHeadList(phead, plist); +#endif +} + +void rtw_list_insert_tail(_list *plist, _list *phead) +{ + +#ifdef PLATFORM_LINUX + + list_add_tail(plist, phead); + +#endif +#ifdef PLATFORM_FREEBSD + + __list_add(plist, phead->prev, phead); + +#endif +#ifdef PLATFORM_WINDOWS + + InsertTailList(phead, plist); + +#endif + +} + +void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc) +{ + _adapter *adapter = (_adapter *)padapter; + +#ifdef PLATFORM_LINUX + _init_timer(ptimer, adapter->pnetdev, pfunc, adapter); +#endif +#ifdef PLATFORM_FREEBSD + _init_timer(ptimer, adapter->pifp, pfunc, adapter->mlmepriv.nic_hdl); +#endif +#ifdef PLATFORM_WINDOWS + _init_timer(ptimer, adapter->hndis_adapter, pfunc, adapter->mlmepriv.nic_hdl); +#endif +} + +/* + +Caller must check if the list is empty before calling rtw_list_delete + +*/ + + +void _rtw_init_sema(_sema *sema, int init_val) +{ + +#ifdef PLATFORM_LINUX + + sema_init(sema, init_val); + +#endif +#ifdef PLATFORM_FREEBSD + sema_init(sema, init_val, "rtw_drv"); +#endif +#ifdef PLATFORM_OS_XP + + KeInitializeSemaphore(sema, init_val, SEMA_UPBND); // count=0; + +#endif + +#ifdef PLATFORM_OS_CE + if(*sema == NULL) + *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL); +#endif + +} + +void _rtw_free_sema(_sema *sema) +{ +#ifdef PLATFORM_FREEBSD + sema_destroy(sema); +#endif +#ifdef PLATFORM_OS_CE + CloseHandle(*sema); +#endif + +} + +void _rtw_up_sema(_sema *sema) +{ + +#ifdef PLATFORM_LINUX + + up(sema); + +#endif +#ifdef PLATFORM_FREEBSD + sema_post(sema); +#endif +#ifdef PLATFORM_OS_XP + + KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1, FALSE ); + +#endif + +#ifdef PLATFORM_OS_CE + ReleaseSemaphore(*sema, 1, NULL ); +#endif +} + +u32 _rtw_down_sema(_sema *sema) +{ + +#ifdef PLATFORM_LINUX + + if (down_interruptible(sema)) + return _FAIL; + else + return _SUCCESS; + +#endif +#ifdef PLATFORM_FREEBSD + sema_wait(sema); + return _SUCCESS; +#endif +#ifdef PLATFORM_OS_XP + + if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL)) + return _SUCCESS; + else + return _FAIL; +#endif + +#ifdef PLATFORM_OS_CE + if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE )) + return _SUCCESS; + else + return _FAIL; +#endif +} + + + +void _rtw_mutex_init(_mutex *pmutex) +{ +#ifdef PLATFORM_LINUX + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_init(pmutex); +#else + init_MUTEX(pmutex); +#endif + +#endif +#ifdef PLATFORM_FREEBSD + mtx_init(pmutex, "", NULL, MTX_DEF|MTX_RECURSE); +#endif +#ifdef PLATFORM_OS_XP + + KeInitializeMutex(pmutex, 0); + +#endif + +#ifdef PLATFORM_OS_CE + *pmutex = CreateMutex( NULL, _FALSE, NULL); +#endif +} + +void _rtw_mutex_free(_mutex *pmutex); +void _rtw_mutex_free(_mutex *pmutex) +{ +#ifdef PLATFORM_LINUX + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + mutex_destroy(pmutex); +#else +#endif + +#ifdef PLATFORM_FREEBSD + sema_destroy(pmutex); +#endif + +#endif + +#ifdef PLATFORM_OS_XP + +#endif + +#ifdef PLATFORM_OS_CE + +#endif +} + +void _rtw_spinlock_init(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock_init(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_init(plock, "", NULL, MTX_DEF|MTX_RECURSE); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAllocateSpinLock(plock); + +#endif + +} + +void _rtw_spinlock_free(_lock *plock) +{ +#ifdef PLATFORM_FREEBSD + mtx_destroy(plock); +#endif + +#ifdef PLATFORM_WINDOWS + + NdisFreeSpinLock(plock); + +#endif + +} +#ifdef PLATFORM_FREEBSD +extern PADAPTER prtw_lock; + +void rtw_mtx_lock(_lock *plock){ + if(prtw_lock){ + mtx_lock(&prtw_lock->glock); + } + else{ + printf("%s prtw_lock==NULL",__FUNCTION__); + } +} +void rtw_mtx_unlock(_lock *plock){ + if(prtw_lock){ + mtx_unlock(&prtw_lock->glock); + } + else{ + printf("%s prtw_lock==NULL",__FUNCTION__); + } + +} +#endif //PLATFORM_FREEBSD + + +void _rtw_spinlock(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_lock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisAcquireSpinLock(plock); + +#endif + +} + +void _rtw_spinunlock(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_unlock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_unlock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisReleaseSpinLock(plock); + +#endif +} + + +void _rtw_spinlock_ex(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_lock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_lock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisDprAcquireSpinLock(plock); + +#endif + +} + +void _rtw_spinunlock_ex(_lock *plock) +{ + +#ifdef PLATFORM_LINUX + + spin_unlock(plock); + +#endif +#ifdef PLATFORM_FREEBSD + mtx_unlock(plock); +#endif +#ifdef PLATFORM_WINDOWS + + NdisDprReleaseSpinLock(plock); + +#endif +} + + + +void _rtw_init_queue(_queue *pqueue) +{ + _rtw_init_listhead(&(pqueue->queue)); + _rtw_spinlock_init(&(pqueue->lock)); +} + +void _rtw_deinit_queue(_queue *pqueue) +{ + _rtw_spinlock_free(&(pqueue->lock)); +} + +u32 _rtw_queue_empty(_queue *pqueue) +{ + return (rtw_is_list_empty(&(pqueue->queue))); +} + + +u32 rtw_end_of_queue_search(_list *head, _list *plist) +{ + if (head == plist) + return _TRUE; + else + return _FALSE; +} + + +u32 rtw_get_current_time(void) +{ + +#ifdef PLATFORM_LINUX + return jiffies; +#endif +#ifdef PLATFORM_FREEBSD + struct timeval tvp; + getmicrotime(&tvp); + return tvp.tv_sec; +#endif +#ifdef PLATFORM_WINDOWS + LARGE_INTEGER SystemTime; + NdisGetCurrentSystemTime(&SystemTime); + return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals +#endif +} + +inline u32 rtw_systime_to_ms(u32 systime) +{ +#ifdef PLATFORM_LINUX + return systime * 1000 / HZ; +#endif +#ifdef PLATFORM_FREEBSD + return systime * 1000; +#endif +#ifdef PLATFORM_WINDOWS + return systime / 10000 ; +#endif +} + +inline u32 rtw_ms_to_systime(u32 ms) +{ +#ifdef PLATFORM_LINUX + return ms * HZ / 1000; +#endif +#ifdef PLATFORM_FREEBSD + return ms /1000; +#endif +#ifdef PLATFORM_WINDOWS + return ms * 10000 ; +#endif +} + +// the input parameter start use the same unit as returned by rtw_get_current_time +inline s32 rtw_get_passing_time_ms(u32 start) +{ +#ifdef PLATFORM_LINUX + return rtw_systime_to_ms(jiffies-start); +#endif +#ifdef PLATFORM_FREEBSD + return rtw_systime_to_ms(rtw_get_current_time()); +#endif +#ifdef PLATFORM_WINDOWS + LARGE_INTEGER SystemTime; + NdisGetCurrentSystemTime(&SystemTime); + return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ; +#endif +} + +inline s32 rtw_get_time_interval_ms(u32 start, u32 end) +{ +#ifdef PLATFORM_LINUX + return rtw_systime_to_ms(end-start); +#endif +#ifdef PLATFORM_FREEBSD + return rtw_systime_to_ms(rtw_get_current_time()); +#endif +#ifdef PLATFORM_WINDOWS + return rtw_systime_to_ms(end-start); +#endif +} + + +void rtw_sleep_schedulable(int ms) +{ + +#ifdef PLATFORM_LINUX + + u32 delta; + + delta = (ms * HZ)/1000;//(ms) + if (delta == 0) { + delta = 1;// 1 ms + } + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(delta) != 0) { + return ; + } + return; + +#endif +#ifdef PLATFORM_FREEBSD + DELAY(ms*1000); + return ; +#endif + +#ifdef PLATFORM_WINDOWS + + NdisMSleep(ms*1000); //(us)*1000=(ms) + +#endif + +} + + +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 +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(ms*1000); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisMSleep(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void rtw_usleep_os(int us) +{ +#ifdef PLATFORM_LINUX + + // 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 + +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(us); + + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisMSleep(us); //(us) + +#endif + + +} + + +#ifdef DBG_DELAY_OS +void _rtw_mdelay_os(int ms, const char *func, const int line) +{ + #if 0 + if(ms>10) + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms); + rtw_msleep_os(ms); + return; + #endif + + + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms); + +#if defined(PLATFORM_LINUX) + + mdelay((unsigned long)ms); + +#elif defined(PLATFORM_WINDOWS) + + NdisStallExecution(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void _rtw_udelay_os(int us, const char *func, const int line) +{ + + #if 0 + if(us > 1000) { + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us); + rtw_usleep_os(us); + return; + } + #endif + + + DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us); + + +#if defined(PLATFORM_LINUX) + + udelay((unsigned long)us); + +#elif defined(PLATFORM_WINDOWS) + + NdisStallExecution(us); //(us) + +#endif + +} +#else +void rtw_mdelay_os(int ms) +{ + +#ifdef PLATFORM_LINUX + + mdelay((unsigned long)ms); + +#endif +#ifdef PLATFORM_FREEBSD + DELAY(ms*1000); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisStallExecution(ms*1000); //(us)*1000=(ms) + +#endif + + +} +void rtw_udelay_os(int us) +{ + +#ifdef PLATFORM_LINUX + + udelay((unsigned long)us); + +#endif +#ifdef PLATFORM_FREEBSD + //Delay for delay microseconds + DELAY(us); + return ; +#endif +#ifdef PLATFORM_WINDOWS + + NdisStallExecution(us); //(us) + +#endif + +} +#endif + +void rtw_yield_os(void) +{ +#ifdef PLATFORM_LINUX + yield(); +#endif +#ifdef PLATFORM_FREEBSD + yield(); +#endif +#ifdef PLATFORM_WINDOWS + SwitchToThread(); +#endif +} + +#define RTW_SUSPEND_LOCK_NAME "rtw_wifi" +#define RTW_SUSPEND_EXT_LOCK_NAME "rtw_wifi_ext" +#define RTW_SUSPEND_RX_LOCK_NAME "rtw_wifi_rx" +#define RTW_SUSPEND_TRAFFIC_LOCK_NAME "rtw_wifi_traffic" +#define RTW_SUSPEND_RESUME_LOCK_NAME "rtw_wifi_resume" +#define RTW_RESUME_SCAN_LOCK_NAME "rtw_wifi_scan" +#ifdef CONFIG_WAKELOCK +static struct wake_lock rtw_suspend_lock; +static struct wake_lock rtw_suspend_ext_lock; +static struct wake_lock rtw_suspend_rx_lock; +static struct wake_lock rtw_suspend_traffic_lock; +static struct wake_lock rtw_suspend_resume_lock; +static struct wake_lock rtw_resume_scan_lock; +#elif defined(CONFIG_ANDROID_POWER) +static android_suspend_lock_t rtw_suspend_lock ={ + .name = RTW_SUSPEND_LOCK_NAME +}; +static android_suspend_lock_t rtw_suspend_ext_lock ={ + .name = RTW_SUSPEND_EXT_LOCK_NAME +}; +static android_suspend_lock_t rtw_suspend_rx_lock ={ + .name = RTW_SUSPEND_RX_LOCK_NAME +}; +static android_suspend_lock_t rtw_suspend_traffic_lock ={ + .name = RTW_SUSPEND_TRAFFIC_LOCK_NAME +}; +static android_suspend_lock_t rtw_suspend_resume_lock ={ + .name = RTW_SUSPEND_RESUME_LOCK_NAME +}; +static android_suspend_lock_t rtw_resume_scan_lock ={ + .name = RTW_RESUME_SCAN_LOCK_NAME +}; +#endif + +inline void rtw_suspend_lock_init(void) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME); + wake_lock_init(&rtw_suspend_ext_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_EXT_LOCK_NAME); + wake_lock_init(&rtw_suspend_rx_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RX_LOCK_NAME); + wake_lock_init(&rtw_suspend_traffic_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_TRAFFIC_LOCK_NAME); + wake_lock_init(&rtw_suspend_resume_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RESUME_LOCK_NAME); + wake_lock_init(&rtw_resume_scan_lock, WAKE_LOCK_SUSPEND, RTW_RESUME_SCAN_LOCK_NAME); + #elif defined(CONFIG_ANDROID_POWER) + android_init_suspend_lock(&rtw_suspend_lock); + android_init_suspend_lock(&rtw_suspend_ext_lock); + android_init_suspend_lock(&rtw_suspend_rx_lock); + android_init_suspend_lock(&rtw_suspend_traffic_lock); + android_init_suspend_lock(&rtw_suspend_resume_lock); + android_init_suspend_lock(&rtw_resume_scan_lock); + #endif +} + +inline void rtw_suspend_lock_uninit(void) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_destroy(&rtw_suspend_lock); + wake_lock_destroy(&rtw_suspend_ext_lock); + wake_lock_destroy(&rtw_suspend_rx_lock); + wake_lock_destroy(&rtw_suspend_traffic_lock); + wake_lock_destroy(&rtw_suspend_resume_lock); + wake_lock_destroy(&rtw_resume_scan_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_uninit_suspend_lock(&rtw_suspend_lock); + android_uninit_suspend_lock(&rtw_suspend_ext_lock); + android_uninit_suspend_lock(&rtw_suspend_rx_lock); + android_uninit_suspend_lock(&rtw_suspend_traffic_lock); + android_uninit_suspend_lock(&rtw_suspend_resume_lock); + android_uninit_suspend_lock(&rtw_resume_scan_lock); + #endif +} + +inline void rtw_lock_suspend(void) +{ + #ifdef CONFIG_WAKELOCK + wake_lock(&rtw_suspend_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend(&rtw_suspend_lock); + #endif + + #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER) + //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); + #endif +} + +inline void rtw_unlock_suspend(void) +{ + #ifdef CONFIG_WAKELOCK + wake_unlock(&rtw_suspend_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_unlock_suspend(&rtw_suspend_lock); + #endif + + #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER) + //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); + #endif +} + +inline void rtw_resume_lock_suspend(void) +{ + #ifdef CONFIG_WAKELOCK + wake_lock(&rtw_suspend_resume_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend(&rtw_suspend_resume_lock); + #endif + + #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER) + //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); + #endif +} + +inline void rtw_resume_unlock_suspend(void) +{ + #ifdef CONFIG_WAKELOCK + wake_unlock(&rtw_suspend_resume_lock); + #elif defined(CONFIG_ANDROID_POWER) + android_unlock_suspend(&rtw_suspend_resume_lock); + #endif + + #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER) + //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); + #endif +} + +inline void rtw_lock_suspend_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms)); + #endif +} + +inline void rtw_lock_ext_suspend_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms)); + #endif + //DBG_871X("EXT lock timeout:%d\n", timeout_ms); +} + +inline void rtw_lock_rx_suspend_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms)); + #endif + //DBG_871X("RX lock timeout:%d\n", timeout_ms); +} + + +inline void rtw_lock_traffic_suspend_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms)); + #endif + //DBG_871X("traffic lock timeout:%d\n", timeout_ms); +} + +inline void rtw_lock_resume_scan_timeout(u32 timeout_ms) +{ + #ifdef CONFIG_WAKELOCK + wake_lock_timeout(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms)); + #elif defined(CONFIG_ANDROID_POWER) + android_lock_suspend_auto_expire(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms)); + #endif + //DBG_871X("resume scan lock:%d\n", timeout_ms); +} + +inline void ATOMIC_SET(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_set(v,i); + #elif defined(PLATFORM_WINDOWS) + *v=i;// other choice???? + #elif defined(PLATFORM_FREEBSD) + atomic_set_int(v,i); + #endif +} + +inline int ATOMIC_READ(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_read(v); + #elif defined(PLATFORM_WINDOWS) + return *v; // other choice???? + #elif defined(PLATFORM_FREEBSD) + return atomic_load_acq_32(v); + #endif +} + +inline void ATOMIC_ADD(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_add(i,v); + #elif defined(PLATFORM_WINDOWS) + InterlockedAdd(v,i); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,i); + #endif +} +inline void ATOMIC_SUB(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + atomic_sub(i,v); + #elif defined(PLATFORM_WINDOWS) + InterlockedAdd(v,-i); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,i); + #endif +} + +inline void ATOMIC_INC(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + atomic_inc(v); + #elif defined(PLATFORM_WINDOWS) + InterlockedIncrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,1); + #endif +} + +inline void ATOMIC_DEC(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + atomic_dec(v); + #elif defined(PLATFORM_WINDOWS) + InterlockedDecrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,1); + #endif +} + +inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + return atomic_add_return(i,v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedAdd(v,i); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,i); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i) +{ + #ifdef PLATFORM_LINUX + return atomic_sub_return(i,v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedAdd(v,-i); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,i); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_INC_RETURN(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_inc_return(v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedIncrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_add_int(v,1); + return atomic_load_acq_32(v); + #endif +} + +inline int ATOMIC_DEC_RETURN(ATOMIC_T *v) +{ + #ifdef PLATFORM_LINUX + return atomic_dec_return(v); + #elif defined(PLATFORM_WINDOWS) + return InterlockedDecrement(v); + #elif defined(PLATFORM_FREEBSD) + atomic_subtract_int(v,1); + return atomic_load_acq_32(v); + #endif +} + + +#ifdef PLATFORM_LINUX +/* +* Open a file with the specific @param path, @param flag, @param mode +* @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success +* @param path the path of the file to open +* @param flag file operation flags, please refer to linux document +* @param mode please refer to linux document +* @return Linux specific error code +*/ +static int openFile(struct file **fpp, char *path, int flag, int mode) +{ + struct file *fp; + + fp=filp_open(path, flag, mode); + if(IS_ERR(fp)) { + *fpp=NULL; + return PTR_ERR(fp); + } + else { + *fpp=fp; + return 0; + } +} + +/* +* Close the file with the specific @param fp +* @param fp the pointer of struct file to close +* @return always 0 +*/ +static int closeFile(struct file *fp) +{ + filp_close(fp,NULL); + return 0; +} + +static int readFile(struct file *fp,char *buf,int len) +{ + int rlen=0, sum=0; + + if (!fp->f_op || !fp->f_op->read) + return -EPERM; + + while(sumf_op->read(fp,buf+sum,len-sum, &fp->f_pos); + if(rlen>0) + sum+=rlen; + else if(0 != rlen) + return rlen; + else + break; + } + + return sum; + +} + +static int writeFile(struct file *fp,char *buf,int len) +{ + int wlen=0, sum=0; + + if (!fp->f_op || !fp->f_op->write) + return -EPERM; + + while(sumf_op->write(fp,buf+sum,len-sum, &fp->f_pos); + if(wlen>0) + sum+=wlen; + else if(0 != wlen) + return wlen; + else + break; + } + + return sum; + +} + +/* +* Test if the specifi @param path is a file and readable +* @param path the path of the file to test +* @return Linux specific error code +*/ +static int isFileReadable(char *path) +{ + struct file *fp; + int ret = 0; + mm_segment_t oldfs; + char buf; + + fp=filp_open(path, O_RDONLY, 0); + if(IS_ERR(fp)) { + ret = PTR_ERR(fp); + } + else { + oldfs = get_fs(); set_fs(get_ds()); + + if(1!=readFile(fp, &buf, 1)) + ret = PTR_ERR(fp); + + set_fs(oldfs); + filp_close(fp,NULL); + } + return ret; +} + +/* +* Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most +* @param path the path of the file to open and read +* @param buf the starting address of the buffer to store file content +* @param sz how many bytes to read at most +* @return the byte we've read, or Linux specific error code +*/ +static int retriveFromFile(char *path, u8* buf, u32 sz) +{ + int ret =-1; + mm_segment_t oldfs; + struct file *fp; + + if(path && buf) { + if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){ + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + + oldfs = get_fs(); set_fs(get_ds()); + ret=readFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); + + DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret); + + } else { + DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret); + } + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = -EINVAL; + } + return ret; +} + +/* +* Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file +* @param path the path of the file to open and write +* @param buf the starting address of the data to write into file +* @param sz how many bytes to write at most +* @return the byte we've written, or Linux specific error code +*/ +static int storeToFile(char *path, u8* buf, u32 sz) +{ + int ret =0; + mm_segment_t oldfs; + struct file *fp; + + if(path && buf) { + if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) { + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + + oldfs = get_fs(); set_fs(get_ds()); + ret=writeFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); + + DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret); + + } else { + DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret); + } + } else { + DBG_871X("%s NULL pointer\n",__FUNCTION__); + ret = -EINVAL; + } + return ret; +} +#endif //PLATFORM_LINUX + +/* +* Test if the specifi @param path is a file and readable +* @param path the path of the file to test +* @return _TRUE or _FALSE +*/ +int rtw_is_file_readable(char *path) +{ +#ifdef PLATFORM_LINUX + if(isFileReadable(path) == 0) + return _TRUE; + else + return _FALSE; +#else + //Todo... + return _FALSE; +#endif +} + +/* +* Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most +* @param path the path of the file to open and read +* @param buf the starting address of the buffer to store file content +* @param sz how many bytes to read at most +* @return the byte we've read +*/ +int rtw_retrieve_from_file(char *path, u8 *buf, u32 sz) +{ +#ifdef PLATFORM_LINUX + int ret =retriveFromFile(path, buf, sz); + return ret>=0?ret:0; +#else + //Todo... + return 0; +#endif +} + +/* +* Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file +* @param path the path of the file to open and write +* @param buf the starting address of the data to write into file +* @param sz how many bytes to write at most +* @return the byte we've written +*/ +int rtw_store_to_file(char *path, u8* buf, u32 sz) +{ +#ifdef PLATFORM_LINUX + int ret =storeToFile(path, buf, sz); + return ret>=0?ret:0; +#else + //Todo... + return 0; +#endif +} + +#ifdef PLATFORM_LINUX +struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv) +{ + struct net_device *pnetdev; + struct rtw_netdev_priv_indicator *pnpi; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); +#else + pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); +#endif + if (!pnetdev) + goto RETURN; + + pnpi = netdev_priv(pnetdev); + pnpi->priv=old_priv; + pnpi->sizeof_priv=sizeof_priv; + +RETURN: + return pnetdev; +} + +struct net_device *rtw_alloc_etherdev(int sizeof_priv) +{ + struct net_device *pnetdev; + struct rtw_netdev_priv_indicator *pnpi; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) + pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4); +#else + pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator)); +#endif + if (!pnetdev) + goto RETURN; + + pnpi = netdev_priv(pnetdev); + + pnpi->priv = rtw_zvmalloc(sizeof_priv); + if (!pnpi->priv) { + free_netdev(pnetdev); + pnetdev = NULL; + goto RETURN; + } + + pnpi->sizeof_priv=sizeof_priv; +RETURN: + return pnetdev; +} + +void rtw_free_netdev(struct net_device * netdev) +{ + struct rtw_netdev_priv_indicator *pnpi; + + if(!netdev) + goto RETURN; + + pnpi = netdev_priv(netdev); + + if(!pnpi->priv) + goto RETURN; + + free_netdev(netdev); + +RETURN: + return; +} + +/* +* Jeff: this function should be called under ioctl (rtnl_lock is accquired) while +* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +*/ +int rtw_change_ifname(_adapter *padapter, const char *ifname) +{ + struct net_device *pnetdev; + struct net_device *cur_pnetdev; + struct rereg_nd_name_data *rereg_priv; + int ret; + + if(!padapter) + goto error; + + cur_pnetdev = padapter->pnetdev; + rereg_priv = &padapter->rereg_nd_name_priv; + + //free the old_pnetdev + if(rereg_priv->old_pnetdev) { + free_netdev(rereg_priv->old_pnetdev); + rereg_priv->old_pnetdev = NULL; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + if(!rtnl_is_locked()) + unregister_netdev(cur_pnetdev); + else +#endif + unregister_netdevice(cur_pnetdev); + + rereg_priv->old_pnetdev=cur_pnetdev; + + pnetdev = rtw_init_netdev(padapter); + if (!pnetdev) { + ret = -1; + goto error; + } + + SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); + + rtw_init_netdev_name(pnetdev, ifname); + + _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + if(!rtnl_is_locked()) + ret = register_netdev(pnetdev); + else +#endif + ret = register_netdevice(pnetdev); + + if ( ret != 0) { + RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n")); + goto error; + } + + return 0; + +error: + + return -1; + +} +#endif + +#ifdef PLATFORM_FREEBSD +/* + * Copy a buffer from userspace and write into kernel address + * space. + * + * This emulation just calls the FreeBSD copyin function (to + * copy data from user space buffer into a kernel space buffer) + * and is designed to be used with the above io_write_wrapper. + * + * This function should return the number of bytes not copied. + * I.e. success results in a zero value. + * Negative error values are not returned. + */ +unsigned long +copy_from_user(void *to, const void *from, unsigned long n) +{ + if ( copyin(from, to, n) != 0 ) { + /* Any errors will be treated as a failure + to copy any of the requested bytes */ + return n; + } + + return 0; +} + +unsigned long +copy_to_user(void *to, const void *from, unsigned long n) +{ + if ( copyout(from, to, n) != 0 ) { + /* Any errors will be treated as a failure + to copy any of the requested bytes */ + return n; + } + + return 0; +} + + +/* + * The usb_register and usb_deregister functions are used to register + * usb drivers with the usb subsystem. In this compatibility layer + * emulation a list of drivers (struct usb_driver) is maintained + * and is used for probing/attaching etc. + * + * usb_register and usb_deregister simply call these functions. + */ +int +usb_register(struct usb_driver *driver) +{ + rtw_usb_linux_register(driver); + return 0; +} + + +int +usb_deregister(struct usb_driver *driver) +{ + rtw_usb_linux_deregister(driver); + return 0; +} + +void module_init_exit_wrapper(void *arg) +{ + int (*func)(void) = arg; + func(); + return; +} + +#endif //PLATFORM_FREEBSD + +#ifdef CONFIG_PLATFORM_SPRD +#ifdef do_div +#undef do_div +#endif +#include +#endif + +u64 rtw_modular64(u64 x, u64 y) +{ +#ifdef PLATFORM_LINUX + return do_div(x, y); +#elif defined(PLATFORM_WINDOWS) + return (x % y); +#elif defined(PLATFORM_FREEBSD) + return (x %y); +#endif +} + +u64 rtw_division64(u64 x, u64 y) +{ +#ifdef PLATFORM_LINUX + do_div(x, y); + return x; +#elif defined(PLATFORM_WINDOWS) + return (x / y); +#elif defined(PLATFORM_FREEBSD) + return (x / y); +#endif +} + +inline u32 rtw_random32(void) +{ +#ifdef PLATFORM_LINUX + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + return prandom_u32(); + #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)) + u32 random_int; + get_random_bytes( &random_int , 4 ); + return random_int; + #else + return random32(); + #endif +#elif defined(PLATFORM_WINDOWS) + #error "to be implemented\n" +#elif defined(PLATFORM_FREEBSD) + #error "to be implemented\n" +#endif +} + +void rtw_buf_free(u8 **buf, u32 *buf_len) +{ + u32 ori_len; + + if (!buf || !buf_len) + return; + + ori_len = *buf_len; + + if (*buf) { + u32 tmp_buf_len = *buf_len; + *buf_len = 0; + rtw_mfree(*buf, tmp_buf_len); + *buf = NULL; + } +} + +void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) +{ + u32 ori_len = 0, dup_len = 0; + u8 *ori = NULL; + u8 *dup = NULL; + + if (!buf || !buf_len) + return; + + if (!src || !src_len) + goto keep_ori; + + /* duplicate src */ + dup = rtw_malloc(src_len); + if (dup) { + dup_len = src_len; + _rtw_memcpy(dup, src, dup_len); + } + +keep_ori: + ori = *buf; + ori_len = *buf_len; + + /* replace buf with dup */ + *buf_len = 0; + *buf = dup; + *buf_len = dup_len; + + /* free ori */ + if (ori && ori_len > 0) + rtw_mfree(ori, ori_len); +} + + +/** + * rtw_cbuf_full - test if cbuf is full + * @cbuf: pointer of struct rtw_cbuf + * + * Returns: _TRUE if cbuf is full + */ +inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf) +{ + return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE; +} + +/** + * rtw_cbuf_empty - test if cbuf is empty + * @cbuf: pointer of struct rtw_cbuf + * + * Returns: _TRUE if cbuf is empty + */ +inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf) +{ + return (cbuf->write == cbuf->read)? _TRUE : _FALSE; +} + +/** + * rtw_cbuf_push - push a pointer into cbuf + * @cbuf: pointer of struct rtw_cbuf + * @buf: pointer to push in + * + * Lock free operation, be careful of the use scheme + * Returns: _TRUE push success + */ +bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) +{ + if (rtw_cbuf_full(cbuf)) + return _FAIL; + + if (0) + DBG_871X("%s on %u\n", __func__, cbuf->write); + cbuf->bufs[cbuf->write] = buf; + cbuf->write = (cbuf->write+1)%cbuf->size; + + return _SUCCESS; +} + +/** + * rtw_cbuf_pop - pop a pointer from cbuf + * @cbuf: pointer of struct rtw_cbuf + * + * Lock free operation, be careful of the use scheme + * Returns: pointer popped out + */ +void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) +{ + void *buf; + if (rtw_cbuf_empty(cbuf)) + return NULL; + + if (0) + DBG_871X("%s on %u\n", __func__, cbuf->read); + buf = cbuf->bufs[cbuf->read]; + cbuf->read = (cbuf->read+1)%cbuf->size; + + return buf; +} + +/** + * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization + * @size: size of pointer + * + * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure + */ +struct rtw_cbuf *rtw_cbuf_alloc(u32 size) +{ + struct rtw_cbuf *cbuf; + + cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size); + + if (cbuf) { + cbuf->write = cbuf->read = 0; + cbuf->size = size; + } + + return cbuf; +} + +/** + * rtw_cbuf_free - free the given rtw_cbuf + * @cbuf: pointer of struct rtw_cbuf to free + */ +void rtw_cbuf_free(struct rtw_cbuf *cbuf) +{ + rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size); +} + +/** +* IsHexDigit - +* +* Return TRUE if chTmp is represent for hex digit +* FALSE otherwise. +*/ +inline BOOLEAN IsHexDigit(char chTmp) +{ + if ((chTmp >= '0' && chTmp <= '9') || + (chTmp >= 'a' && chTmp <= 'f') || + (chTmp >= 'A' && chTmp <= 'F')) + return _TRUE; + else + return _FALSE; +} + +/** +* is_alpha - +* +* Return TRUE if chTmp is represent for alphabet +* FALSE otherwise. +*/ +inline BOOLEAN is_alpha(char chTmp) +{ + if ((chTmp >= 'a' && chTmp <= 'z') || + (chTmp >= 'A' && chTmp <= 'Z')) + return _TRUE; + else + return _FALSE; +} + +inline char alpha_to_upper(char c) +{ + if ((c >= 'a' && c <= 'z')) + c = 'A' + (c - 'a'); + return c; +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUN50IW1P1_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUN50IW1P1_sdio.c new file mode 100644 index 00000000..aec9cdbb --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUN50IW1P1_sdio.c @@ -0,0 +1,91 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +/* + * Description: + * This file can be applied to following platforms: + * CONFIG_PLATFORM_ARM_SUN50IW1P1 + */ +#include +#ifdef CONFIG_GPIO_WAKEUP +#include +#endif + +#ifdef CONFIG_MMC +#if defined(CONFIG_PLATFORM_ARM_SUN50IW1P1) +extern void sunxi_mmc_rescan_card(unsigned ids); +extern void sunxi_wlan_set_power(int on); +extern int sunxi_wlan_get_bus_index(void); +extern int sunxi_wlan_get_oob_irq(void); +extern int sunxi_wlan_get_oob_irq_flags(void); +#endif +#ifdef CONFIG_GPIO_WAKEUP +extern unsigned int oob_irq; +#endif +#endif // CONFIG_MMC + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; + +#ifdef CONFIG_MMC +{ + +#if defined(CONFIG_PLATFORM_ARM_SUN50IW1P1) + int wlan_bus_index = sunxi_wlan_get_bus_index(); + if(wlan_bus_index < 0) + return wlan_bus_index; + + sunxi_wlan_set_power(1); + mdelay(100); + sunxi_mmc_rescan_card(wlan_bus_index); +#endif + DBG_871X("%s: power up, rescan card.\n", __FUNCTION__); + +#ifdef CONFIG_GPIO_WAKEUP +#if defined(CONFIG_PLATFORM_ARM_SUN50IW1P1) + oob_irq = sunxi_wlan_get_oob_irq(); +#endif +#endif // CONFIG_GPIO_WAKEUP +} +#endif // CONFIG_MMC + + return ret; +} + +void platform_wifi_power_off(void) +{ +#ifdef CONFIG_MMC +#if defined(CONFIG_PLATFORM_ARM_SUN50IW1P1) + int wlan_bus_index = sunxi_wlan_get_bus_index(); + if(wlan_bus_index < 0) + return; + + sunxi_mmc_rescan_card(wlan_bus_index); + mdelay(100); + sunxi_wlan_set_power(0); +#endif + DBG_871X("%s: remove card, power off.\n", __FUNCTION__); +#endif // CONFIG_MMC +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNnI_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNnI_sdio.c new file mode 100644 index 00000000..601e7387 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNnI_sdio.c @@ -0,0 +1,114 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +/* + * Description: + * This file can be applied to following platforms: + * CONFIG_PLATFORM_ARM_SUN6I + * CONFIG_PLATFORM_ARM_SUN7I + * CONFIG_PLATFORM_ARM_SUN8I + */ +#include +#include +#ifdef CONFIG_GPIO_WAKEUP +#include +#endif + +#ifdef CONFIG_MMC +static int sdc_id = -1; +static signed int gpio_eint_wlan = -1; +static u32 eint_wlan_handle = 0; + +#if defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) +extern void sw_mci_rescan_card(unsigned id, unsigned insert); +#elif defined(CONFIG_PLATFORM_ARM_SUN8I) +extern void sunxi_mci_rescan_card(unsigned id, unsigned insert); +#endif + +extern void wifi_pm_power(int on); +#ifdef CONFIG_GPIO_WAKEUP +extern unsigned int oob_irq; +#endif +#endif // CONFIG_MMC + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; + +#ifdef CONFIG_MMC +{ + script_item_u val; + script_item_value_type_e type; + + type = script_get_item("wifi_para", "wifi_sdc_id", &val); + if (SCIRPT_ITEM_VALUE_TYPE_INT!=type) { + DBG_871X("get wifi_sdc_id failed\n"); + ret = -1; + } else { + sdc_id = val.val; + DBG_871X("----- %s sdc_id: %d\n", __FUNCTION__, sdc_id); + +#if defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) + sw_mci_rescan_card(sdc_id, 1); +#elif defined(CONFIG_PLATFORM_ARM_SUN8I) + sunxi_mci_rescan_card(sdc_id, 1); +#endif + mdelay(100); + wifi_pm_power(1); + + DBG_871X("%s: power up, rescan card.\n", __FUNCTION__); + } + +#ifdef CONFIG_GPIO_WAKEUP + type = script_get_item("wifi_para", "wl_host_wake", &val); + if (SCIRPT_ITEM_VALUE_TYPE_PIO != type) { + DBG_871X("No definition of wake up host PIN\n"); + ret = -1; + } else { + gpio_eint_wlan = val.gpio.gpio; +#ifdef CONFIG_PLATFORM_ARM_SUN8I + oob_irq = gpio_to_irq(gpio_eint_wlan); +#endif + } +#endif // CONFIG_GPIO_WAKEUP +} +#endif // CONFIG_MMC + + return ret; +} + +void platform_wifi_power_off(void) +{ +#ifdef CONFIG_MMC +#if defined(CONFIG_PLATFORM_ARM_SUN6I) ||defined(CONFIG_PLATFORM_ARM_SUN7I) + sw_mci_rescan_card(sdc_id, 0); +#elif defined(CONFIG_PLATFORM_ARM_SUN8I) + sunxi_mci_rescan_card(sdc_id, 0); +#endif + mdelay(100); + wifi_pm_power(0); + + DBG_871X("%s: remove card, power off.\n", __FUNCTION__); +#endif // CONFIG_MMC +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_sdio.c new file mode 100644 index 00000000..5bc888dc --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_sdio.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + +#ifdef CONFIG_MMC_SUNXI_POWER_CONTROL +#ifdef CONFIG_WITS_EVB_V13 +#define SDIOID 0 +#else // !CONFIG_WITS_EVB_V13 +#define SDIOID (CONFIG_CHIP_ID==1123 ? 3 : 1) +#endif // !CONFIG_WITS_EVB_V13 + +#define SUNXI_SDIO_WIFI_NUM_RTL8189ES 10 +extern void sunximmc_rescan_card(unsigned id, unsigned insert); +extern int mmc_pm_get_mod_type(void); +extern int mmc_pm_gpio_ctrl(char* name, int level); +/* + * rtl8189es_shdn = port:PH09<1><0> + * rtl8189es_wakeup = port:PH10<1><1> + * rtl8189es_vdd_en = port:PH11<1><0> + * rtl8189es_vcc_en = port:PH12<1><0> + */ + +int rtl8189es_sdio_powerup(void) +{ + mmc_pm_gpio_ctrl("rtl8189es_vdd_en", 1); + udelay(100); + mmc_pm_gpio_ctrl("rtl8189es_vcc_en", 1); + udelay(50); + mmc_pm_gpio_ctrl("rtl8189es_shdn", 1); + return 0; +} + +int rtl8189es_sdio_poweroff(void) +{ + mmc_pm_gpio_ctrl("rtl8189es_shdn", 0); + mmc_pm_gpio_ctrl("rtl8189es_vcc_en", 0); + mmc_pm_gpio_ctrl("rtl8189es_vdd_en", 0); + return 0; +} +#endif // CONFIG_MMC_SUNXI_POWER_CONTROL + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; +#ifdef CONFIG_MMC_SUNXI_POWER_CONTROL + unsigned int mod_sel = mmc_pm_get_mod_type(); +#endif // CONFIG_MMC_SUNXI_POWER_CONTROL + + +#ifdef CONFIG_MMC_SUNXI_POWER_CONTROL + if (mod_sel == SUNXI_SDIO_WIFI_NUM_RTL8189ES) { + rtl8189es_sdio_powerup(); + sunximmc_rescan_card(SDIOID, 1); + printk("[rtl8189es] %s: power up, rescan card.\n", __FUNCTION__); + } else { + ret = -1; + printk("[rtl8189es] %s: mod_sel = %d is incorrect.\n", __FUNCTION__, mod_sel); + } +#endif // CONFIG_MMC_SUNXI_POWER_CONTROL + + return ret; +} + +void platform_wifi_power_off(void) +{ +#ifdef CONFIG_MMC_SUNXI_POWER_CONTROL + sunximmc_rescan_card(SDIOID, 0); +#ifdef CONFIG_RTL8188E + rtl8189es_sdio_poweroff(); + printk("[rtl8189es] %s: remove card, power off.\n", __FUNCTION__); +#endif // CONFIG_RTL8188E +#endif // CONFIG_MMC_SUNXI_POWER_CONTROL +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_usb.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_usb.c new file mode 100644 index 00000000..5352313a --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_SUNxI_usb.c @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +/* + * Description: + * This file can be applied to following platforms: + * CONFIG_PLATFORM_ARM_SUNXI Series platform + * + */ + +#include +#include + +#ifdef CONFIG_PLATFORM_ARM_SUNxI +extern int sw_usb_disable_hcd(__u32 usbc_no); +extern int sw_usb_enable_hcd(__u32 usbc_no); +static int usb_wifi_host = 2; +#endif + +#if defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) +extern int sw_usb_disable_hcd(__u32 usbc_no); +extern int sw_usb_enable_hcd(__u32 usbc_no); +extern void wifi_pm_power(int on); +static script_item_u item; +#endif + +#ifdef CONFIG_PLATFORM_ARM_SUN8I +extern int sunxi_usb_disable_hcd(__u32 usbc_no); +extern int sunxi_usb_enable_hcd(__u32 usbc_no); +extern void wifi_pm_power(int on); +static script_item_u item; +#endif + + +int platform_wifi_power_on(void) +{ + int ret = 0; + +#ifdef CONFIG_PLATFORM_ARM_SUNxI +#ifndef CONFIG_RTL8723A + { + /* ----------get usb_wifi_usbc_num------------- */ + ret = script_parser_fetch("usb_wifi_para", "usb_wifi_usbc_num", (int *)&usb_wifi_host, 64); + if(ret != 0){ + DBG_8192C("ERR: script_parser_fetch usb_wifi_usbc_num failed\n"); + ret = -ENOMEM; + goto exit; + } + DBG_8192C("sw_usb_enable_hcd: usbc_num = %d\n", usb_wifi_host); + sw_usb_enable_hcd(usb_wifi_host); + } +#endif //CONFIG_RTL8723A +#endif //CONFIG_PLATFORM_ARM_SUNxI + +#if defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) + { + script_item_value_type_e type; + + type = script_get_item("wifi_para", "wifi_usbc_id", &item); + if(SCIRPT_ITEM_VALUE_TYPE_INT != type){ + printk("ERR: script_get_item wifi_usbc_id failed\n"); + ret = -ENOMEM; + goto exit; + } + + printk("sw_usb_enable_hcd: usbc_num = %d\n", item.val); + wifi_pm_power(1); + mdelay(10); + + #if !(defined(CONFIG_RTL8723A)) && !(defined(CONFIG_RTL8723B)) + sw_usb_enable_hcd(item.val); + #endif + } +#endif //defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) + +#if defined(CONFIG_PLATFORM_ARM_SUN8I) + { + script_item_value_type_e type; + + type = script_get_item("wifi_para", "wifi_usbc_id", &item); + if(SCIRPT_ITEM_VALUE_TYPE_INT != type){ + printk("ERR: script_get_item wifi_usbc_id failed\n"); + ret = -ENOMEM; + goto exit; + } + + printk("sw_usb_enable_hcd: usbc_num = %d\n", item.val); + wifi_pm_power(1); + mdelay(10); + + #if !(defined(CONFIG_RTL8723A)) && !(defined(CONFIG_RTL8723B)) + sunxi_usb_enable_hcd(item.val); + #endif + } +#endif //CONFIG_PLATFORM_ARM_SUN8I + +exit: + return ret; +} + +void platform_wifi_power_off(void) +{ + +#ifdef CONFIG_PLATFORM_ARM_SUNxI +#ifndef CONFIG_RTL8723A + DBG_8192C("sw_usb_disable_hcd: usbc_num = %d\n", usb_wifi_host); + sw_usb_disable_hcd(usb_wifi_host); +#endif //ifndef CONFIG_RTL8723A +#endif //CONFIG_PLATFORM_ARM_SUNxI + +#if defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) + #if !(defined(CONFIG_RTL8723A)) && !(defined(CONFIG_RTL8723B)) + sw_usb_disable_hcd(item.val); + #endif + wifi_pm_power(0); +#endif //defined(CONFIG_PLATFORM_ARM_SUN6I) || defined(CONFIG_PLATFORM_ARM_SUN7I) + +#if defined(CONFIG_PLATFORM_ARM_SUN8I) + #if !(defined(CONFIG_RTL8723A)) && !(defined(CONFIG_RTL8723B)) + sunxi_usb_disable_hcd(item.val); + #endif + wifi_pm_power(0); +#endif //defined(CONFIG_PLATFORM_ARM_SUN8I) + +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_WMT_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_WMT_sdio.c new file mode 100644 index 00000000..62e58258 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ARM_WMT_sdio.c @@ -0,0 +1,51 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + +extern void wmt_detect_sdio2(void); +extern void force_remove_sdio2(void); + +int platform_wifi_power_on(void) +{ + int err = 0; + err = gpio_request(WMT_PIN_GP62_SUSGPIO1, "wifi_chip_en"); + if (err < 0){ + printk("request gpio for rtl8188eu failed!\n"); + return err; + } + gpio_direction_output(WMT_PIN_GP62_SUSGPIO1, 0);//pull sus_gpio1 to 0 to open vcc_wifi. + printk("power on rtl8189.\n"); + msleep(500); + wmt_detect_sdio2(); + printk("[rtl8189es] %s: new card, power on.\n", __FUNCTION__); + return err; +} + +void platform_wifi_power_off(void) +{ + force_remove_sdio2(); + + gpio_direction_output(WMT_PIN_GP62_SUSGPIO1, 1);//pull sus_gpio1 to 1 to close vcc_wifi. + printk("power off rtl8189.\n"); + gpio_free(WMT_PIN_GP62_SUSGPIO1); + printk("[rtl8189es] %s: remove card, power off.\n", __FUNCTION__); +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_RTK_DMP_usb.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_RTK_DMP_usb.c new file mode 100644 index 00000000..53314338 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_RTK_DMP_usb.c @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + +int platform_wifi_power_on(void) +{ + int ret = 0; + u32 tmp; + tmp=readl((volatile unsigned int*)0xb801a608); + tmp &= 0xffffff00; + tmp |= 0x55; + writel(tmp,(volatile unsigned int*)0xb801a608);//write dummy register for 1055 + return ret; +} + +void platform_wifi_power_off(void) +{ +} + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_arm_act_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_arm_act_sdio.c new file mode 100644 index 00000000..539bb178 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_arm_act_sdio.c @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + * + * + ******************************************************************************/ +/* + * Description: + * This file can be applied to following platforms: + * CONFIG_PLATFORM_ACTIONS_ATM703X + */ +#include + +#ifdef CONFIG_PLATFORM_ACTIONS_ATM705X +extern int acts_wifi_init(void); +extern void acts_wifi_cleanup(void); +#endif + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; + +#ifdef CONFIG_PLATFORM_ACTIONS_ATM705X + ret = acts_wifi_init(); + if (unlikely(ret < 0)) { + pr_err("%s Failed to register the power control driver.\n", __FUNCTION__); + goto exit; + } +#endif + +exit: + return ret; +} + +void platform_wifi_power_off(void) +{ +#ifdef CONFIG_PLATFORM_ACTIONS_ATM705X + acts_wifi_cleanup(); +#endif +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.c new file mode 100644 index 00000000..f019cfc4 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.c @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 +#ifndef CONFIG_PLATFORM_OPS +extern void sdio_reinit(void); +extern void extern_wifi_set_enable(int is_on); +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; + + printk("######%s: \n",__func__); + extern_wifi_set_enable(0); + msleep(500); + extern_wifi_set_enable(1); + msleep(500); + sdio_reinit(); + return ret; +} + +void platform_wifi_power_off(void) +{ +} +#endif // !CONFIG_PLATFORM_OPS diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.h b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.h new file mode 100644 index 00000000..bd2e6683 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_ops.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 __PLATFORM_OPS_H__ +#define __PLATFORM_OPS_H__ + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void); +void platform_wifi_power_off(void); + +#endif // __PLATFORM_OPS_H__ diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_sprd_sdio.c b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_sprd_sdio.c new file mode 100644 index 00000000..a4e2502f --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/platform/platform_sprd_sdio.c @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2013 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 + +extern void sdhci_bus_scan(void); +#ifndef ANDROID_2X +extern int sdhci_device_attached(void); +#endif + +/* + * Return: + * 0: power on successfully + * others: power on failed + */ +int platform_wifi_power_on(void) +{ + int ret = 0; + + +#ifdef CONFIG_RTL8188E + rtw_wifi_gpio_wlan_ctrl(WLAN_POWER_ON); +#endif // CONFIG_RTL8188E + + /* Pull up pwd pin, make wifi leave power down mode. */ + rtw_wifi_gpio_init(); + rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_ON); + +#if (MP_DRIVER == 1) && (defined(CONFIG_RTL8723A)||defined(CONFIG_RTL8723B)) + // Pull up BT reset pin. + rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON); +#endif + rtw_mdelay_os(5); + + sdhci_bus_scan(); +#ifdef CONFIG_RTL8723B + //YJ,test,130305 + rtw_mdelay_os(1000); +#endif +#ifdef ANDROID_2X + rtw_mdelay_os(200); +#else // !ANDROID_2X + if (1) { + int i = 0; + + for (i = 0; i <= 50; i++) { + msleep(10); + if (sdhci_device_attached()) + break; + printk("%s delay times:%d\n", __func__, i); + } + } +#endif // !ANDROID_2X + + return ret; +} + +void platform_wifi_power_off(void) +{ + /* Pull down pwd pin, make wifi enter power down mode. */ + rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF); + rtw_mdelay_os(5); + rtw_wifi_gpio_deinit(); + +#ifdef CONFIG_RTL8188E + rtw_wifi_gpio_wlan_ctrl(WLAN_POWER_OFF); +#endif // CONFIG_RTL8188E + +#ifdef CONFIG_WOWLAN + if(mmc_host) + mmc_host->pm_flags &= ~MMC_PM_KEEP_POWER; +#endif // CONFIG_WOWLAN +} diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/runwpa b/linux-3.4/drivers/net/wireless/rtl8189fs/runwpa new file mode 100644 index 00000000..f825e8bd --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/runwpa @@ -0,0 +1,20 @@ +#!/bin/bash + +if [ "`which iwconfig`" = "" ] ; then + echo "WARNING:Wireless tool not exist!" + echo " Please install it!" + exit +else + if [ `uname -r | cut -d. -f2` -eq 4 ]; then + wpa_supplicant -D ipw -c wpa1.conf -i wlan0 + else + if [ `iwconfig -v |awk '{print $4}' | head -n 1` -lt 18 ] ; then + wpa_supplicant -D ipw -c wpa1.conf -i wlan0 + else + wpa_supplicant -D wext -c wpa1.conf -i wlan0 + fi + + fi +fi + + diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/wlan0dhcp b/linux-3.4/drivers/net/wireless/rtl8189fs/wlan0dhcp new file mode 100644 index 00000000..60433829 --- /dev/null +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/wlan0dhcp @@ -0,0 +1,16 @@ +#!/bin/bash + +var0=`ps aux|awk '/dhclient wlan0/'|awk '$11!="awk"{print $2}'` + +kill $var0 +cp ifcfg-wlan0 /etc/sysconfig/network-scripts/ + +dhclient wlan0 + +var1=`ifconfig wlan0 |awk '/inet/{print $2}'|awk -F: '{print $2}'` + + +rm -f /etc/sysconfig/network-scripts/ifcfg-wlan0 + +echo "get ip: $var1" + diff --git a/linux-3.4/drivers/thermal/cpu_budget_cooling.c b/linux-3.4/drivers/thermal/cpu_budget_cooling.c index fb316b61..6b4bb8c2 100755 --- a/linux-3.4/drivers/thermal/cpu_budget_cooling.c +++ b/linux-3.4/drivers/thermal/cpu_budget_cooling.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "thermal_core.h" #define CREATE_TRACE_POINTS @@ -59,6 +60,7 @@ static LIST_HEAD(cooling_cpufreq_list); static DEFINE_IDR(cpu_budget_idr); static DEFINE_MUTEX(cooling_cpu_budget_lock); static unsigned int cpu_budget_dev_count; +static int corekeeper_enabled; static struct cpu_budget_cooling_device* notify_device=NULL; /** * get_idr - function to get a unique id. @@ -108,6 +110,7 @@ static int is_cpufreq_valid(int cpu) struct cpufreq_policy policy; return !cpufreq_get_policy(&policy, cpu); } +#ifdef CONFIG_HOTPLUG_CPU static int get_any_online_cpu(const cpumask_t *mask) { int cpu,lastcpu=0xffff; @@ -123,6 +126,21 @@ static int get_any_online_cpu(const cpumask_t *mask) } return lastcpu; } +static int get_any_offline_cpu(const cpumask_t *mask) +{ + int cpu,lastcpu=0xffff; + + for_each_cpu(cpu, mask) { + if (!cpu_online(cpu)) + { + if(lastcpu == 0xffff) + lastcpu = cpu; + else if(cpu >lastcpu) + lastcpu = cpu; + } + } + return lastcpu; +} static int get_online_cpu(const cpumask_t *mask) { int cpu,num =0; @@ -133,6 +151,7 @@ static int get_online_cpu(const cpumask_t *mask) } return num; } +#endif static BLOCKING_NOTIFIER_HEAD(budget_cooling_notifier_list); int register_budget_cooling_notifier(struct notifier_block *nb) { @@ -149,18 +168,25 @@ EXPORT_SYMBOL(register_budget_cooling_notifier); #ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE extern int autohotplug_update_room(unsigned int c0min,unsigned int c1min,unsigned int c0max,unsigned int c1max); #endif +static int old_cooling_state = 0; int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) { - int i,ret = 0; + int ret = 0; unsigned int cpuid; - unsigned int c0_online=0,c1_online=0; - unsigned int c0_takedown=0,c1_takedown=0; - unsigned int c0_max,c1_max,c0_min,c1_min; +#ifdef CONFIG_HOTPLUG_CPU + int i = 0; + unsigned int c0_online=0,c1_online=0; + unsigned int c0_takedown=0,c1_takedown=0; + unsigned int c0_max,c1_max,c0_min,c1_min; + unsigned int c0_bringup=0,c1_bringup=0; +#endif struct cpumask *cluster0_cpus = &cpu_budget_device->cluster0_cpus; struct cpumask *cluster1_cpus = &cpu_budget_device->cluster1_cpus; struct cpufreq_policy policy; + int cooling_state = cpu_budget_device->cpu_budget_state; ret = 0; +#ifdef CONFIG_HOTPLUG_CPU // update cpu limit for_each_online_cpu(i) { if (cpumask_test_cpu(i, &cpu_budget_device->cluster0_cpus)) @@ -179,6 +205,22 @@ int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) c0_max:cpu_budget_device->cluster0_num_floor; c0_takedown = (c0_online > c0_max)?(c0_online - c0_max):0; c1_takedown = (c1_online > c1_max)?(c1_online - c1_max):0; +#ifdef CONFIG_ARCH_SUN8IW7 + if (corekeeper_enabled && (cooling_state < old_cooling_state) && (c0_takedown + c1_takedown == 0)) + { + /* pr_info("CPU Budget:plugging cores, old state %d, new state %d\n",old_cooling_state,cooling_state); */ + switch (cooling_state) + { + case 2: + case 1: + case 0: + c0_bringup = (c0_online < c0_max) ? c0_max - c0_online : 0; + c1_bringup = (c1_online < c1_max) ? c1_max - c1_online : 0; + break; + } + } + old_cooling_state = cooling_state; +#endif while(c1_takedown) { cpuid = get_any_online_cpu(&cpu_budget_device->cluster1_cpus); @@ -203,6 +245,27 @@ int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) } c0_takedown--; } + while(c0_bringup) + { + cpuid = get_any_offline_cpu(&cpu_budget_device->cluster0_cpus); + if (cpuid < nr_cpu_ids) + { + pr_info("CPU Budget:Try to up cpu %d, cluster0 online %d, limit %d\n",cpuid,c0_online,cpu_budget_device->cluster0_num_limit); + ret = work_on_cpu(BOOT_CPU,(long(*)(void *))cpu_up,(void *)cpuid); + } + c0_bringup--; + } + while(c1_bringup) + { + cpuid = get_any_offline_cpu(&cpu_budget_device->cluster1_cpus); + if (cpuid < nr_cpu_ids) + { + pr_info("CPU Budget:Try to up cpu %d, cluster1 online %d, limit %d\n",cpuid,c1_online,cpu_budget_device->cluster1_num_limit); + ret = work_on_cpu(BOOT_CPU,(long(*)(void *))cpu_up,(void *)cpuid); + } + c1_bringup--; + } +#endif #ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE autohotplug_update_room(c0_min,c1_min,c0_max,c1_max); #endif @@ -288,6 +351,7 @@ static int cpu_budget_apply_cooling(struct cpu_budget_cooling_device *cpu_budget return cpu_budget_update_state(cpu_budget_device); } +#ifdef CONFIG_HOTPLUG_CPU static int hotplug_thermal_notifier(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -335,6 +399,7 @@ static int hotplug_thermal_notifier(struct notifier_block *nfb, return NOTIFY_DONE; } +#endif /** * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. * @nb: struct notifier_block * with callback info. @@ -451,6 +516,17 @@ struct thermal_cooling_device *cpu_budget_cooling_register( int ret = 0, i; struct cpufreq_policy policy; + /* get corekeeper state */ + script_item_u val; + script_item_value_type_e type; + + type = script_get_item("corekeeper", "corekeeper_enabled", &val); + if (SCIRPT_ITEM_VALUE_TYPE_INT == type) { + corekeeper_enabled = !!val.val; + if (corekeeper_enabled) + pr_info("CPU Budget:corekeeper enabled\n"); + } + /*Verify that all the clip cpus have same freq_min, freq_max limit*/ for_each_cpu(i, cluster0_cpus) { /*continue if cpufreq policy not found and not return error*/ @@ -526,9 +602,10 @@ struct thermal_cooling_device *cpu_budget_cooling_register( cpu_budget_dev->cpufreq_notifer.notifier_call=cpufreq_thermal_notifier; cpufreq_register_notifier(&(cpu_budget_dev->cpufreq_notifer), CPUFREQ_POLICY_NOTIFIER); - +#ifdef CONFIG_HOTPLUG_CPU cpu_budget_dev->hotplug_notifer.notifier_call=hotplug_thermal_notifier; register_cpu_notifier(&(cpu_budget_dev->hotplug_notifer)); +#endif } cpu_budget_dev_count++; mutex_unlock(&cooling_cpu_budget_lock); @@ -553,7 +630,9 @@ void cpu_budget_cooling_unregister(struct thermal_cooling_device *cdev) cpufreq_unregister_notifier(&(cpu_budget_dev->cpufreq_notifer), CPUFREQ_POLICY_NOTIFIER); +#ifdef CONFIG_HOTPLUG_CPU unregister_cpu_notifier(&(cpu_budget_dev->hotplug_notifer)); +#endif } mutex_unlock(&cooling_cpu_budget_lock); @@ -563,4 +642,3 @@ void cpu_budget_cooling_unregister(struct thermal_cooling_device *cdev) pr_info("CPU Budget:unregister Success\n"); } EXPORT_SYMBOL(cpu_budget_cooling_unregister); - diff --git a/linux-3.4/include/linux/vm_event_item.h b/linux-3.4/include/linux/vm_event_item.h index a2bbaef4..06f8e385 100644 --- a/linux-3.4/include/linux/vm_event_item.h +++ b/linux-3.4/include/linux/vm_event_item.h @@ -35,6 +35,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, #endif PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL, KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, + KSWAPD_SKIP_CONGESTION_WAIT, PAGEOUTRUN, ALLOCSTALL, PGROTATED, #ifdef CONFIG_COMPACTION COMPACTBLOCKS, COMPACTPAGES, COMPACTPAGEFAILED, diff --git a/linux-3.4/mm/vmscan.c b/linux-3.4/mm/vmscan.c index db61d7f7..d6b0e399 100755 --- a/linux-3.4/mm/vmscan.c +++ b/linux-3.4/mm/vmscan.c @@ -2782,6 +2782,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, for (priority = DEF_PRIORITY; priority >= 0; priority--) { unsigned long lru_pages = 0; + int has_under_min_watermark_zone = 0; /* The swap token gets in the way of swapout... */ if (!priority) @@ -2923,7 +2924,17 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, continue; } - if (zone_balanced(zone, testorder, 0, end_zone)) { + if (!zone_balanced(zone, testorder, 0, end_zone)) { + all_zones_ok = 0; + /* + * We are still under min water mark. This + * means that we have a GFP_ATOMIC allocation + * failure risk. Hurry up! + */ + if (!zone_watermark_ok_safe(zone, order, + min_wmark_pages(zone), end_zone, 0)) + has_under_min_watermark_zone = 1; + } else { /* * If a zone reaches its high watermark, * consider it to be no longer congested. It's @@ -2939,6 +2950,17 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, } if (all_zones_ok || (order && pgdat_balanced(pgdat, balanced, *classzone_idx))) break; /* kswapd: all done */ + /* + * OK, kswapd is getting into trouble. Take a nap, then take + * another pass across the zones. + */ + if (total_scanned && (priority < DEF_PRIORITY - 2)) { + if (has_under_min_watermark_zone) + count_vm_event(KSWAPD_SKIP_CONGESTION_WAIT); + else + congestion_wait(BLK_RW_ASYNC, HZ/10); + } + /* * We do this so kswapd doesn't build up large priorities for * example when it is freeing in parallel with allocators. It diff --git a/linux-3.4/mm/vmstat.c b/linux-3.4/mm/vmstat.c index 1de03bfa..1034ebcc 100644 --- a/linux-3.4/mm/vmstat.c +++ b/linux-3.4/mm/vmstat.c @@ -758,6 +758,7 @@ const char * const vmstat_text[] = { "kswapd_inodesteal", "kswapd_low_wmark_hit_quickly", "kswapd_high_wmark_hit_quickly", + "kswapd_skip_congestion_wait", "pageoutrun", "allocstall", diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod index 9ef9275f..a775ca0b 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod @@ -1,2 +1,2 @@ -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers index db85f2e1..560c0339 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers @@ -1,21 +1,21 @@ -0x62c42e0c _mali_profiling_get_api_version /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xb9ac0503 mali_set_user_setting /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x94289922 mali_pmu_powerdown /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x2a7049ed mali_perf_set_num_pp_cores /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x0d8ccbae mali_dev_resume /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x7c2fb465 mali_dev_pause /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8224b12 mali_get_user_setting /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x428fd838 _mali_profiling_set_event /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xcdcdf6bf _mali_profiling_get_l2_counters /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x4580d143 _mali_profiling_control /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x706fc943 mali_pmu_powerup /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xdcd285aa _mali_profiling_get_mali_version /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x62c42e0c _mali_profiling_get_api_version /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xb9ac0503 mali_set_user_setting /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x94289922 mali_pmu_powerdown /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x2a7049ed mali_perf_set_num_pp_cores /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x0d8ccbae mali_dev_resume /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x7c2fb465 mali_dev_pause /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8224b12 mali_get_user_setting /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x428fd838 _mali_profiling_set_event /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xcdcdf6bf _mali_profiling_get_l2_counters /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x4580d143 _mali_profiling_control /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x706fc943 mali_pmu_powerup /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xdcd285aa _mali_profiling_get_mali_version /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod index 79a1b25e..012fb665 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod @@ -1,2 +1,2 @@ -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers index 020ed34a..e6ba8765 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers @@ -1,9 +1,9 @@ -0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod index 96c6764e..67378809 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod @@ -1,2 +1,2 @@ -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko -/home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /home/leonardo/Desktop/embedtool/orangepiKernel/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko +/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o From 9bf19efaa2e7b3794a1792c16284372ab66b46bd Mon Sep 17 00:00:00 2001 From: lhelontra Date: Fri, 16 Jun 2017 10:58:56 -0300 Subject: [PATCH 06/26] removed duplicates --- linux-3.4/drivers/cpufreq.new/Kconfig | 306 --- linux-3.4/drivers/cpufreq.new/Kconfig.arm | 93 - linux-3.4/drivers/cpufreq.new/Kconfig.powerpc | 7 - linux-3.4/drivers/cpufreq.new/Kconfig.x86 | 255 -- linux-3.4/drivers/cpufreq.new/Makefile | 60 - linux-3.4/drivers/cpufreq.new/acpi-cpufreq.c | 773 ------ linux-3.4/drivers/cpufreq.new/autohotplug.c | 1205 --------- linux-3.4/drivers/cpufreq.new/autohotplug.h | 124 - .../drivers/cpufreq.new/cpufreq-nforce2.c | 452 ---- linux-3.4/drivers/cpufreq.new/cpufreq.c | 2188 ----------------- .../cpufreq.new/cpufreq_conservative.c | 417 ---- .../drivers/cpufreq.new/cpufreq_fantasys.c | 1532 ------------ .../drivers/cpufreq.new/cpufreq_governor.c | 383 --- .../drivers/cpufreq.new/cpufreq_governor.h | 270 -- linux-3.4/drivers/cpufreq.new/cpufreq_iks.c | 1109 --------- .../drivers/cpufreq.new/cpufreq_interactive.c | 1733 ------------- .../drivers/cpufreq.new/cpufreq_ondemand.c | 667 ----- .../drivers/cpufreq.new/cpufreq_performance.c | 63 - .../drivers/cpufreq.new/cpufreq_powersave.c | 65 - linux-3.4/drivers/cpufreq.new/cpufreq_stats.c | 507 ---- .../drivers/cpufreq.new/cpufreq_userspace.c | 222 -- .../drivers/cpufreq.new/db8500-cpufreq.c | 170 -- linux-3.4/drivers/cpufreq.new/e_powersaver.c | 482 ---- linux-3.4/drivers/cpufreq.new/elanfreq.c | 309 --- .../drivers/cpufreq.new/exynos-cpufreq.c | 296 --- .../drivers/cpufreq.new/exynos4210-cpufreq.c | 304 --- .../drivers/cpufreq.new/exynos4x12-cpufreq.c | 536 ---- .../drivers/cpufreq.new/exynos5250-cpufreq.c | 347 --- linux-3.4/drivers/cpufreq.new/freq_table.c | 241 -- linux-3.4/drivers/cpufreq.new/gx-suspmod.c | 509 ---- linux-3.4/drivers/cpufreq.new/longhaul.c | 1030 -------- linux-3.4/drivers/cpufreq.new/longhaul.h | 353 --- linux-3.4/drivers/cpufreq.new/longrun.c | 327 --- linux-3.4/drivers/cpufreq.new/maple-cpufreq.c | 309 --- linux-3.4/drivers/cpufreq.new/mperf.c | 51 - linux-3.4/drivers/cpufreq.new/mperf.h | 9 - linux-3.4/drivers/cpufreq.new/omap-cpufreq.c | 335 --- linux-3.4/drivers/cpufreq.new/p4-clockmod.c | 334 --- linux-3.4/drivers/cpufreq.new/pcc-cpufreq.c | 624 ----- linux-3.4/drivers/cpufreq.new/powernow-k6.c | 265 -- linux-3.4/drivers/cpufreq.new/powernow-k7.c | 748 ------ linux-3.4/drivers/cpufreq.new/powernow-k7.h | 43 - linux-3.4/drivers/cpufreq.new/powernow-k8.c | 1627 ------------ linux-3.4/drivers/cpufreq.new/powernow-k8.h | 222 -- .../drivers/cpufreq.new/s3c2416-cpufreq.c | 542 ---- .../drivers/cpufreq.new/s3c64xx-cpufreq.c | 276 --- .../drivers/cpufreq.new/s5pv210-cpufreq.c | 649 ----- linux-3.4/drivers/cpufreq.new/sc520_freq.c | 194 -- .../drivers/cpufreq.new/speedstep-centrino.c | 649 ----- linux-3.4/drivers/cpufreq.new/speedstep-ich.c | 463 ---- linux-3.4/drivers/cpufreq.new/speedstep-lib.c | 479 ---- linux-3.4/drivers/cpufreq.new/speedstep-lib.h | 49 - linux-3.4/drivers/cpufreq.new/speedstep-smi.c | 479 ---- .../drivers/cpufreq.new/sunxi-autohotplug.c | 347 --- linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.c | 1202 --------- linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.h | 65 - .../drivers/cpufreq.new/sunxi-iks-cpufreq.c | 947 ------- .../drivers/cpufreq.new/sunxi-iks-cpufreq.h | 72 - linux-3.4/drivers/thermal.new/Kconfig | 156 -- linux-3.4/drivers/thermal.new/Makefile | 23 - .../drivers/thermal.new/cpu_budget_cooling.c | 558 ----- linux-3.4/drivers/thermal.new/cpu_cooling.c | 398 --- linux-3.4/drivers/thermal.new/fair_share.c | 133 - linux-3.4/drivers/thermal.new/rcar_thermal.c | 249 -- linux-3.4/drivers/thermal.new/spear_thermal.c | 212 -- linux-3.4/drivers/thermal.new/step_wise.c | 213 -- linux-3.4/drivers/thermal.new/sunxi-battery.c | 147 -- .../thermal.new/sunxi-cpu-budget-cooling.c | 553 ----- .../drivers/thermal.new/sunxi-cpu-cooling.c | 95 - .../drivers/thermal.new/sunxi-temperature.c | 1849 -------------- .../thermal.new/sunxi-temperature.c.orig | 1706 ------------- .../drivers/thermal.new/sunxi-temperature.h | 195 -- .../thermal.new/sunxi-temperature.h.orig | 193 -- .../drivers/thermal.new/sunxi-thermal-bind.c | 252 -- linux-3.4/drivers/thermal.new/sunxi-thermal.c | 409 --- linux-3.4/drivers/thermal.new/sunxi-thermal.h | 73 - linux-3.4/drivers/thermal.new/thermal_core.h | 53 - linux-3.4/drivers/thermal.new/thermal_sys.c | 1830 -------------- linux-3.4/drivers/thermal.new/user_space.c | 68 - 79 files changed, 37680 deletions(-) delete mode 100755 linux-3.4/drivers/cpufreq.new/Kconfig delete mode 100755 linux-3.4/drivers/cpufreq.new/Kconfig.arm delete mode 100644 linux-3.4/drivers/cpufreq.new/Kconfig.powerpc delete mode 100644 linux-3.4/drivers/cpufreq.new/Kconfig.x86 delete mode 100755 linux-3.4/drivers/cpufreq.new/Makefile delete mode 100644 linux-3.4/drivers/cpufreq.new/acpi-cpufreq.c delete mode 100755 linux-3.4/drivers/cpufreq.new/autohotplug.c delete mode 100755 linux-3.4/drivers/cpufreq.new/autohotplug.h delete mode 100644 linux-3.4/drivers/cpufreq.new/cpufreq-nforce2.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_conservative.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_fantasys.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_governor.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_governor.h delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_iks.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_interactive.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_ondemand.c delete mode 100644 linux-3.4/drivers/cpufreq.new/cpufreq_performance.c delete mode 100644 linux-3.4/drivers/cpufreq.new/cpufreq_powersave.c delete mode 100755 linux-3.4/drivers/cpufreq.new/cpufreq_stats.c delete mode 100644 linux-3.4/drivers/cpufreq.new/cpufreq_userspace.c delete mode 100644 linux-3.4/drivers/cpufreq.new/db8500-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/e_powersaver.c delete mode 100644 linux-3.4/drivers/cpufreq.new/elanfreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/exynos-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/exynos4210-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/exynos4x12-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/exynos5250-cpufreq.c delete mode 100755 linux-3.4/drivers/cpufreq.new/freq_table.c delete mode 100644 linux-3.4/drivers/cpufreq.new/gx-suspmod.c delete mode 100644 linux-3.4/drivers/cpufreq.new/longhaul.c delete mode 100644 linux-3.4/drivers/cpufreq.new/longhaul.h delete mode 100644 linux-3.4/drivers/cpufreq.new/longrun.c delete mode 100644 linux-3.4/drivers/cpufreq.new/maple-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/mperf.c delete mode 100644 linux-3.4/drivers/cpufreq.new/mperf.h delete mode 100644 linux-3.4/drivers/cpufreq.new/omap-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/p4-clockmod.c delete mode 100644 linux-3.4/drivers/cpufreq.new/pcc-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/powernow-k6.c delete mode 100644 linux-3.4/drivers/cpufreq.new/powernow-k7.c delete mode 100644 linux-3.4/drivers/cpufreq.new/powernow-k7.h delete mode 100644 linux-3.4/drivers/cpufreq.new/powernow-k8.c delete mode 100644 linux-3.4/drivers/cpufreq.new/powernow-k8.h delete mode 100644 linux-3.4/drivers/cpufreq.new/s3c2416-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/s3c64xx-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/s5pv210-cpufreq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/sc520_freq.c delete mode 100644 linux-3.4/drivers/cpufreq.new/speedstep-centrino.c delete mode 100644 linux-3.4/drivers/cpufreq.new/speedstep-ich.c delete mode 100644 linux-3.4/drivers/cpufreq.new/speedstep-lib.c delete mode 100644 linux-3.4/drivers/cpufreq.new/speedstep-lib.h delete mode 100644 linux-3.4/drivers/cpufreq.new/speedstep-smi.c delete mode 100755 linux-3.4/drivers/cpufreq.new/sunxi-autohotplug.c delete mode 100755 linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.c delete mode 100755 linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.h delete mode 100755 linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.c delete mode 100755 linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.h delete mode 100755 linux-3.4/drivers/thermal.new/Kconfig delete mode 100755 linux-3.4/drivers/thermal.new/Makefile delete mode 100755 linux-3.4/drivers/thermal.new/cpu_budget_cooling.c delete mode 100755 linux-3.4/drivers/thermal.new/cpu_cooling.c delete mode 100755 linux-3.4/drivers/thermal.new/fair_share.c delete mode 100755 linux-3.4/drivers/thermal.new/rcar_thermal.c delete mode 100755 linux-3.4/drivers/thermal.new/spear_thermal.c delete mode 100755 linux-3.4/drivers/thermal.new/step_wise.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-battery.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-cpu-budget-cooling.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-cpu-cooling.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-temperature.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-temperature.c.orig delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-temperature.h delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-temperature.h.orig delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-thermal-bind.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-thermal.c delete mode 100755 linux-3.4/drivers/thermal.new/sunxi-thermal.h delete mode 100755 linux-3.4/drivers/thermal.new/thermal_core.h delete mode 100755 linux-3.4/drivers/thermal.new/thermal_sys.c delete mode 100755 linux-3.4/drivers/thermal.new/user_space.c diff --git a/linux-3.4/drivers/cpufreq.new/Kconfig b/linux-3.4/drivers/cpufreq.new/Kconfig deleted file mode 100755 index a5189914..00000000 --- a/linux-3.4/drivers/cpufreq.new/Kconfig +++ /dev/null @@ -1,306 +0,0 @@ -menu "CPU Frequency scaling" - -config CPU_FREQ - bool "CPU Frequency scaling" - help - CPU Frequency scaling allows you to change the clock speed of - CPUs on the fly. This is a nice method to save power, because - the lower the CPU clock speed, the less power the CPU consumes. - - Note that this driver doesn't automatically change the CPU - clock speed, you need to either enable a dynamic cpufreq governor - (see below) after boot, or use a userspace tool. - - For details, take a look at . - - If in doubt, say N. - -if CPU_FREQ - -config CPU_FREQ_TABLE - tristate - -config CPU_FREQ_GOV_COMMON - bool - -config CPU_FREQ_STAT - tristate "CPU frequency translation statistics" - select CPU_FREQ_TABLE - default y - help - This driver exports CPU frequency statistics information through sysfs - file system. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_stats. - - If in doubt, say N. - -config CPU_FREQ_STAT_DETAILS - bool "CPU frequency translation statistics details" - depends on CPU_FREQ_STAT - help - This will show detail CPU frequency translation table in sysfs file - system. - - If in doubt, say N. - -choice - prompt "Default CPUFreq governor" - default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 - default CPU_FREQ_DEFAULT_GOV_PERFORMANCE - help - This option sets which CPUFreq governor shall be loaded at - startup. If in doubt, select 'performance'. - -config CPU_FREQ_DEFAULT_GOV_PERFORMANCE - bool "performance" - select CPU_FREQ_GOV_PERFORMANCE - help - Use the CPUFreq governor 'performance' as default. This sets - the frequency statically to the highest frequency supported by - the CPU. - -config CPU_FREQ_DEFAULT_GOV_POWERSAVE - bool "powersave" - depends on EXPERT - select CPU_FREQ_GOV_POWERSAVE - help - Use the CPUFreq governor 'powersave' as default. This sets - the frequency statically to the lowest frequency supported by - the CPU. - -config CPU_FREQ_DEFAULT_GOV_USERSPACE - bool "userspace" - select CPU_FREQ_GOV_USERSPACE - help - Use the CPUFreq governor 'userspace' as default. This allows - you to set the CPU frequency manually or when a userspace - program shall be able to set the CPU dynamically without having - to enable the userspace governor manually. - -config CPU_FREQ_DEFAULT_GOV_ONDEMAND - bool "ondemand" - select CPU_FREQ_GOV_ONDEMAND - select CPU_FREQ_GOV_PERFORMANCE - help - Use the CPUFreq governor 'ondemand' as default. This allows - you to get a full dynamic frequency capable system by simply - loading your cpufreq low-level hardware driver. - Be aware that not all cpufreq drivers support the ondemand - governor. If unsure have a look at the help section of the - driver. Fallback governor will be the performance governor. - -config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE - bool "conservative" - select CPU_FREQ_GOV_CONSERVATIVE - select CPU_FREQ_GOV_PERFORMANCE - help - Use the CPUFreq governor 'conservative' as default. This allows - you to get a full dynamic frequency capable system by simply - loading your cpufreq low-level hardware driver. - Be aware that not all cpufreq drivers support the conservative - governor. If unsure have a look at the help section of the - driver. Fallback governor will be the performance governor. - -config CPU_FREQ_DEFAULT_GOV_INTERACTIVE - bool "interactive" - select CPU_FREQ_GOV_INTERACTIVE - help - Use the CPUFreq governor 'interactive' as default. This allows - you to get a full dynamic cpu frequency capable system by simply - loading your cpufreq low-level hardware driver, using the - 'interactive' governor for latency-sensitive workloads. - -config CPU_FREQ_DEFAULT_GOV_FANTASYS - bool "fantasys" - select CPU_FREQ_GOV_FANTASYS - select CPU_FREQ_GOV_PERFORMANCE - help - Use the CPUFreq governor 'fantasys' as default. This allows - you to get a full dynamic frequency capable system by simply - loading your cpufreq low-level hardware driver. - Be aware that not all cpufreq drivers support the ondemand - governor. If unsure have a look at the help section of the - driver. Fallback governor will be the performance governor. - -endchoice - -config CPU_FREQ_GOV_PERFORMANCE - tristate "'performance' governor" - help - This cpufreq governor sets the frequency statically to the - highest available CPU frequency. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_performance. - - If in doubt, say Y. - -config CPU_FREQ_GOV_POWERSAVE - tristate "'powersave' governor" - help - This cpufreq governor sets the frequency statically to the - lowest available CPU frequency. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_powersave. - - If in doubt, say Y. - -config CPU_FREQ_GOV_USERSPACE - tristate "'userspace' governor for userspace frequency scaling" - help - Enable this cpufreq governor when you either want to set the - CPU frequency manually or when a userspace program shall - be able to set the CPU dynamically, like on LART - . - - To compile this driver as a module, choose M here: the - module will be called cpufreq_userspace. - - For details, take a look at . - - If in doubt, say Y. - -config CPU_FREQ_GOV_ONDEMAND - tristate "'ondemand' cpufreq policy governor" - select CPU_FREQ_TABLE - select CPU_FREQ_GOV_COMMON - help - 'ondemand' - This driver adds a dynamic cpufreq policy governor. - The governor does a periodic polling and - changes frequency based on the CPU utilization. - The support for this governor depends on CPU capability to - do fast frequency switching (i.e, very low latency frequency - transitions). - - To compile this driver as a module, choose M here: the - module will be called cpufreq_ondemand. - - For details, take a look at linux/Documentation/cpu-freq. - - If in doubt, say N. - -config CPU_FREQ_GOV_INTERACTIVE - tristate "'interactive' cpufreq policy governor" - help - 'interactive' - This driver adds a dynamic cpufreq policy governor - designed for latency-sensitive workloads. - - This governor attempts to reduce the latency of clock - increases so that the system is more responsive to - interactive workloads. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_interactive. - - For details, take a look at linux/Documentation/cpu-freq. - - If in doubt, say N. - -config CPU_FREQ_GOV_AUTO_HOTPLUG - tristate "cpu auto hotplug support" - depends on SCHED_HMP || SCHED_SMP_DCMP || SMP - depends on !ARCH_SUN8IW3 - depends on !BL_SWITCHER - default n - -config CPU_GOV_AUTO_HOTPLUG_WITHOUT_POLICY - tristate "cpu auto hotplug also support without cpufreq" - depends on CPU_FREQ_GOV_AUTO_HOTPLUG - default n -config CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE - tristate "cpu auto hotplug support roomage limit" - depends on CPU_FREQ_GOV_AUTO_HOTPLUG - default y - -config CPU_FREQ_GOV_CONSERVATIVE - tristate "'conservative' cpufreq governor" - depends on CPU_FREQ - select CPU_FREQ_GOV_COMMON - help - 'conservative' - this driver is rather similar to the 'ondemand' - governor both in its source code and its purpose, the difference is - its optimisation for better suitability in a battery powered - environment. The frequency is gracefully increased and decreased - rather than jumping to 100% when speed is required. - - If you have a desktop machine then you should really be considering - the 'ondemand' governor instead, however if you are using a laptop, - PDA or even an AMD64 based computer (due to the unacceptable - step-by-step latency issues between the minimum and maximum frequency - transitions in the CPU) you will probably want to use this governor. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_conservative. - - For details, take a look at linux/Documentation/cpu-freq. - - If in doubt, say N. - -config CPU_FREQ_GOV_FANTASYS - tristate "'fantasys' cpufreq policy governor" - depends on SMP - depends on ARCH_SUN8IW1 || ARCH_SUN8IW3 - select CPU_FREQ_TABLE - help - 'fantasys' - This driver adds a dynamic cpufreq policy governor. - The governor does a periodic polling and - changes frequency based on the CPU utilization. - This governor will switch on/off cpu cores automaticly. - The support for this governor depends on CPU capability to - do fast frequency switching (i.e, very low latency frequency - - transitions). - - To compile this driver as a module, choose M here: the - module will be called cpufreq_fantasys. - - If in doubt, say N. - -config CPU_FREQ_GOV_IKS - tristate "'iks' cpufreq policy governor" - default N - depends on SMP && ARCH_SUN9IW1 && BL_SWITCHER - select CPU_FREQ_TABLE - help - 'iks' - This driver adds a dynamic cpufreq policy governor for big-Little. - The governor does a periodic polling and - changes frequency based on the CPU utilization. - This governor will switch cores between big and little cluster, and switch - on/off cpu cores automaticly. - The support for this governor depends on CPU capability to - do fast frequency switching (i.e, very low latency frequency - - transitions). - - To compile this driver as a module, choose M here: the - module will be called cpufreq_iks. - - If in doubt, say N. - -config CPU_FREQ_INPUT_EVNT_NOTIFY - bool "CPU frequency input event notify" - depends on INPUT && (CPU_FREQ_GOV_FANTASYS || CPU_FREQ_GOV_IKS || CPU_FREQ_GOV_INTERACTIVE) - help - This will allow input sub-system notify cpu-freq that some user event has happend, - need up cpu frequency to response it. - - If in doubt, say N. - -menu "x86 CPU frequency scaling drivers" -depends on X86 -source "drivers/cpufreq/Kconfig.x86" -endmenu - -menu "ARM CPU frequency scaling drivers" -depends on ARM -source "drivers/cpufreq/Kconfig.arm" -endmenu - -menu "PowerPC CPU frequency scaling drivers" -depends on PPC32 || PPC64 -source "drivers/cpufreq/Kconfig.powerpc" -endmenu - -endif -endmenu diff --git a/linux-3.4/drivers/cpufreq.new/Kconfig.arm b/linux-3.4/drivers/cpufreq.new/Kconfig.arm deleted file mode 100755 index a9f3101f..00000000 --- a/linux-3.4/drivers/cpufreq.new/Kconfig.arm +++ /dev/null @@ -1,93 +0,0 @@ -# -# ARM CPU Frequency scaling drivers -# - -config ARM_SUNXI_IKS_CPUFREQ - bool "SUNXI CPUFreq IKS driver support" - depends on ARCH_SUN9IW1 || ARCH_SUN8IW6 || ARCH_SUN8IW9 - help - This adds the CPUFreq driver for sunxi big.little soc. - If in doubt, say N. - -config ARM_SUNXI_CPUFREQ - bool "SUNXI CPUFreq driver support" - depends on !ARCH_SUN9IW1 && !ARCH_SUN8IW6 && !ARCH_SUN8IW9 - help - This adds the CPUFreq driver for the Allwinner SUNXI SoC. - - If in doubt, say N. - -config ARM_OMAP2PLUS_CPUFREQ - bool "TI OMAP2+" - depends on ARCH_OMAP2PLUS - default ARCH_OMAP2PLUS - select CPU_FREQ_TABLE - -config ARM_S3C2416_CPUFREQ - bool "S3C2416 CPU Frequency scaling support" - depends on CPU_S3C2416 - help - This adds the CPUFreq driver for the Samsung S3C2416 and - S3C2450 SoC. The S3C2416 supports changing the rate of the - armdiv clock source and also entering a so called dynamic - voltage scaling mode in which it is possible to reduce the - core voltage of the cpu. - - If in doubt, say N. - -config ARM_S3C2416_CPUFREQ_VCORESCALE - bool "Allow voltage scaling for S3C2416 arm core (EXPERIMENTAL)" - depends on ARM_S3C2416_CPUFREQ && REGULATOR && EXPERIMENTAL - help - Enable CPU voltage scaling when entering the dvs mode. - It uses information gathered through existing hardware and - tests but not documented in any datasheet. - - If in doubt, say N. - -config ARM_S3C64XX_CPUFREQ - bool "Samsung S3C64XX" - depends on CPU_S3C6410 - default y - help - This adds the CPUFreq driver for Samsung S3C6410 SoC. - - If in doubt, say N. - -config ARM_S5PV210_CPUFREQ - bool "Samsung S5PV210 and S5PC110" - depends on CPU_S5PV210 - default y - help - This adds the CPUFreq driver for Samsung S5PV210 and - S5PC110 SoCs. - - If in doubt, say N. - -config ARM_EXYNOS_CPUFREQ - bool "SAMSUNG EXYNOS SoCs" - depends on ARCH_EXYNOS - default y - help - This adds the CPUFreq driver common part for Samsung - EXYNOS SoCs. - - If in doubt, say N. - -config ARM_EXYNOS4210_CPUFREQ - def_bool CPU_EXYNOS4210 - help - This adds the CPUFreq driver for Samsung EXYNOS4210 - SoC (S5PV310 or S5PC210). - -config ARM_EXYNOS4X12_CPUFREQ - def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412) - help - This adds the CPUFreq driver for Samsung EXYNOS4X12 - SoC (EXYNOS4212 or EXYNOS4412). - -config ARM_EXYNOS5250_CPUFREQ - def_bool SOC_EXYNOS5250 - help - This adds the CPUFreq driver for Samsung EXYNOS5250 - SoC. diff --git a/linux-3.4/drivers/cpufreq.new/Kconfig.powerpc b/linux-3.4/drivers/cpufreq.new/Kconfig.powerpc deleted file mode 100644 index e76992f7..00000000 --- a/linux-3.4/drivers/cpufreq.new/Kconfig.powerpc +++ /dev/null @@ -1,7 +0,0 @@ -config CPU_FREQ_MAPLE - bool "Support for Maple 970FX Evaluation Board" - depends on PPC_MAPLE - select CPU_FREQ_TABLE - help - This adds support for frequency switching on Maple 970FX - Evaluation Board and compatible boards (IBM JS2x blades). diff --git a/linux-3.4/drivers/cpufreq.new/Kconfig.x86 b/linux-3.4/drivers/cpufreq.new/Kconfig.x86 deleted file mode 100644 index 78ff7ee4..00000000 --- a/linux-3.4/drivers/cpufreq.new/Kconfig.x86 +++ /dev/null @@ -1,255 +0,0 @@ -# -# x86 CPU Frequency scaling drivers -# - -config X86_PCC_CPUFREQ - tristate "Processor Clocking Control interface driver" - depends on ACPI && ACPI_PROCESSOR - help - This driver adds support for the PCC interface. - - For details, take a look at: - . - - To compile this driver as a module, choose M here: the - module will be called pcc-cpufreq. - - If in doubt, say N. - -config X86_ACPI_CPUFREQ - tristate "ACPI Processor P-States driver" - select CPU_FREQ_TABLE - depends on ACPI_PROCESSOR - help - This driver adds a CPUFreq driver which utilizes the ACPI - Processor Performance States. - This driver also supports Intel Enhanced Speedstep. - - To compile this driver as a module, choose M here: the - module will be called acpi-cpufreq. - - For details, take a look at . - - If in doubt, say N. - -config ELAN_CPUFREQ - tristate "AMD Elan SC400 and SC410" - select CPU_FREQ_TABLE - depends on MELAN - ---help--- - This adds the CPUFreq driver for AMD Elan SC400 and SC410 - processors. - - You need to specify the processor maximum speed as boot - parameter: elanfreq=maxspeed (in kHz) or as module - parameter "max_freq". - - For details, take a look at . - - If in doubt, say N. - -config SC520_CPUFREQ - tristate "AMD Elan SC520" - select CPU_FREQ_TABLE - depends on MELAN - ---help--- - This adds the CPUFreq driver for AMD Elan SC520 processor. - - For details, take a look at . - - If in doubt, say N. - - -config X86_POWERNOW_K6 - tristate "AMD Mobile K6-2/K6-3 PowerNow!" - select CPU_FREQ_TABLE - depends on X86_32 - help - This adds the CPUFreq driver for mobile AMD K6-2+ and mobile - AMD K6-3+ processors. - - For details, take a look at . - - If in doubt, say N. - -config X86_POWERNOW_K7 - tristate "AMD Mobile Athlon/Duron PowerNow!" - select CPU_FREQ_TABLE - depends on X86_32 - help - This adds the CPUFreq driver for mobile AMD K7 mobile processors. - - For details, take a look at . - - If in doubt, say N. - -config X86_POWERNOW_K7_ACPI - bool - depends on X86_POWERNOW_K7 && ACPI_PROCESSOR - depends on !(X86_POWERNOW_K7 = y && ACPI_PROCESSOR = m) - depends on X86_32 - default y - -config X86_POWERNOW_K8 - tristate "AMD Opteron/Athlon64 PowerNow!" - select CPU_FREQ_TABLE - depends on ACPI && ACPI_PROCESSOR - help - This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors. - - To compile this driver as a module, choose M here: the - module will be called powernow-k8. - - For details, take a look at . - -config X86_GX_SUSPMOD - tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" - depends on X86_32 && PCI - help - This add the CPUFreq driver for NatSemi Geode processors which - support suspend modulation. - - For details, take a look at . - - If in doubt, say N. - -config X86_SPEEDSTEP_CENTRINO - tristate "Intel Enhanced SpeedStep (deprecated)" - select CPU_FREQ_TABLE - select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32 - depends on X86_32 || (X86_64 && ACPI_PROCESSOR) - help - This is deprecated and this functionality is now merged into - acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of - speedstep_centrino. - This adds the CPUFreq driver for Enhanced SpeedStep enabled - mobile CPUs. This means Intel Pentium M (Centrino) CPUs - or 64bit enabled Intel Xeons. - - To compile this driver as a module, choose M here: the - module will be called speedstep-centrino. - - For details, take a look at . - - If in doubt, say N. - -config X86_SPEEDSTEP_CENTRINO_TABLE - bool "Built-in tables for Banias CPUs" - depends on X86_32 && X86_SPEEDSTEP_CENTRINO - default y - help - Use built-in tables for Banias CPUs if ACPI encoding - is not available. - - If in doubt, say N. - -config X86_SPEEDSTEP_ICH - tristate "Intel Speedstep on ICH-M chipsets (ioport interface)" - select CPU_FREQ_TABLE - depends on X86_32 - help - This adds the CPUFreq driver for certain mobile Intel Pentium III - (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all - mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2, - ICH3 or ICH4 southbridge. - - For details, take a look at . - - If in doubt, say N. - -config X86_SPEEDSTEP_SMI - tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)" - select CPU_FREQ_TABLE - depends on X86_32 && EXPERIMENTAL - help - This adds the CPUFreq driver for certain mobile Intel Pentium III - (Coppermine), all mobile Intel Pentium III-M (Tualatin) - on systems which have an Intel 440BX/ZX/MX southbridge. - - For details, take a look at . - - If in doubt, say N. - -config X86_P4_CLOCKMOD - tristate "Intel Pentium 4 clock modulation" - select CPU_FREQ_TABLE - help - This adds the CPUFreq driver for Intel Pentium 4 / XEON - processors. When enabled it will lower CPU temperature by skipping - clocks. - - This driver should be only used in exceptional - circumstances when very low power is needed because it causes severe - slowdowns and noticeable latencies. Normally Speedstep should be used - instead. - - To compile this driver as a module, choose M here: the - module will be called p4-clockmod. - - For details, take a look at . - - Unless you are absolutely sure say N. - -config X86_CPUFREQ_NFORCE2 - tristate "nVidia nForce2 FSB changing" - depends on X86_32 && EXPERIMENTAL - help - This adds the CPUFreq driver for FSB changing on nVidia nForce2 - platforms. - - For details, take a look at . - - If in doubt, say N. - -config X86_LONGRUN - tristate "Transmeta LongRun" - depends on X86_32 - help - This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors - which support LongRun. - - For details, take a look at . - - If in doubt, say N. - -config X86_LONGHAUL - tristate "VIA Cyrix III Longhaul" - select CPU_FREQ_TABLE - depends on X86_32 && ACPI_PROCESSOR - help - This adds the CPUFreq driver for VIA Samuel/CyrixIII, - VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T - processors. - - For details, take a look at . - - If in doubt, say N. - -config X86_E_POWERSAVER - tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" - select CPU_FREQ_TABLE - depends on X86_32 && EXPERIMENTAL - help - This adds the CPUFreq driver for VIA C7 processors. However, this driver - does not have any safeguards to prevent operating the CPU out of spec - and is thus considered dangerous. Please use the regular ACPI cpufreq - driver, enabled by CONFIG_X86_ACPI_CPUFREQ. - - If in doubt, say N. - -comment "shared options" - -config X86_SPEEDSTEP_LIB - tristate - default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) - -config X86_SPEEDSTEP_RELAXED_CAP_CHECK - bool "Relaxed speedstep capability checks" - depends on X86_32 && (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) - help - Don't perform all checks for a speedstep capable system which would - normally be done. Some ancient or strange systems, though speedstep - capable, don't always indicate that they are speedstep capable. This - option lets the probing code bypass some of those checks if the - parameter "relaxed_check=1" is passed to the module. - diff --git a/linux-3.4/drivers/cpufreq.new/Makefile b/linux-3.4/drivers/cpufreq.new/Makefile deleted file mode 100755 index d43f9124..00000000 --- a/linux-3.4/drivers/cpufreq.new/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# CPUfreq core -obj-$(CONFIG_CPU_FREQ) += cpufreq.o -# CPUfreq stats -obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o - -# CPUfreq governors -obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o -obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o -obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o -obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o -obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o -obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o -obj-$(CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG) += autohotplug.o sunxi-autohotplug.o -obj-$(CONFIG_CPU_FREQ_GOV_FANTASYS) += cpufreq_fantasys.o -obj-$(CONFIG_CPU_FREQ_GOV_IKS) += cpufreq_iks.o -obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o -# CPUfreq cross-arch helpers -obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o - -################################################################################## -# x86 drivers. -# Link order matters. K8 is preferred to ACPI because of firmware bugs in early -# K8 systems. ACPI is preferred to all other hardware-specific drivers. -# speedstep-* is preferred over p4-clockmod. - -obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o mperf.o -obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o -obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o -obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o -obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o -obj-$(CONFIG_X86_LONGHAUL) += longhaul.o -obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o -obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o -obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o -obj-$(CONFIG_X86_LONGRUN) += longrun.o -obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o -obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o -obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o -obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o -obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o -obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o -obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o - -################################################################################## -# ARM SoC drivers -obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o -obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o -obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o -obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o -obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o -obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o -obj-$(CONFIG_ARM_SUNXI_CPUFREQ) += sunxi-cpufreq.o -obj-$(CONFIG_ARM_SUNXI_IKS_CPUFREQ) += sunxi-iks-cpufreq.o - -################################################################################## -# PowerPC platform drivers -obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o diff --git a/linux-3.4/drivers/cpufreq.new/acpi-cpufreq.c b/linux-3.4/drivers/cpufreq.new/acpi-cpufreq.c deleted file mode 100644 index 56c6c6b4..00000000 --- a/linux-3.4/drivers/cpufreq.new/acpi-cpufreq.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * acpi-cpufreq.c - ACPI Processor P-States Driver - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2002 - 2004 Dominik Brodowski - * Copyright (C) 2006 Denis Sadykov - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include "mperf.h" - -MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); -MODULE_DESCRIPTION("ACPI Processor P-States Driver"); -MODULE_LICENSE("GPL"); - -enum { - UNDEFINED_CAPABLE = 0, - SYSTEM_INTEL_MSR_CAPABLE, - SYSTEM_IO_CAPABLE, -}; - -#define INTEL_MSR_RANGE (0xffff) - -struct acpi_cpufreq_data { - struct acpi_processor_performance *acpi_data; - struct cpufreq_frequency_table *freq_table; - unsigned int resume; - unsigned int cpu_feature; -}; - -static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data); - -/* acpi_perf_data is a pointer to percpu data. */ -static struct acpi_processor_performance __percpu *acpi_perf_data; - -static struct cpufreq_driver acpi_cpufreq_driver; - -static unsigned int acpi_pstate_strict; - -static int check_est_cpu(unsigned int cpuid) -{ - struct cpuinfo_x86 *cpu = &cpu_data(cpuid); - - return cpu_has(cpu, X86_FEATURE_EST); -} - -static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) -{ - struct acpi_processor_performance *perf; - int i; - - perf = data->acpi_data; - - for (i = 0; i < perf->state_count; i++) { - if (value == perf->states[i].status) - return data->freq_table[i].frequency; - } - return 0; -} - -static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) -{ - int i; - struct acpi_processor_performance *perf; - - msr &= INTEL_MSR_RANGE; - perf = data->acpi_data; - - for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - if (msr == perf->states[data->freq_table[i].index].status) - return data->freq_table[i].frequency; - } - return data->freq_table[0].frequency; -} - -static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) -{ - switch (data->cpu_feature) { - case SYSTEM_INTEL_MSR_CAPABLE: - return extract_msr(val, data); - case SYSTEM_IO_CAPABLE: - return extract_io(val, data); - default: - return 0; - } -} - -struct msr_addr { - u32 reg; -}; - -struct io_addr { - u16 port; - u8 bit_width; -}; - -struct drv_cmd { - unsigned int type; - const struct cpumask *mask; - union { - struct msr_addr msr; - struct io_addr io; - } addr; - u32 val; -}; - -/* Called via smp_call_function_single(), on the target CPU */ -static void do_drv_read(void *_cmd) -{ - struct drv_cmd *cmd = _cmd; - u32 h; - - switch (cmd->type) { - case SYSTEM_INTEL_MSR_CAPABLE: - rdmsr(cmd->addr.msr.reg, cmd->val, h); - break; - case SYSTEM_IO_CAPABLE: - acpi_os_read_port((acpi_io_address)cmd->addr.io.port, - &cmd->val, - (u32)cmd->addr.io.bit_width); - break; - default: - break; - } -} - -/* Called via smp_call_function_many(), on the target CPUs */ -static void do_drv_write(void *_cmd) -{ - struct drv_cmd *cmd = _cmd; - u32 lo, hi; - - switch (cmd->type) { - case SYSTEM_INTEL_MSR_CAPABLE: - rdmsr(cmd->addr.msr.reg, lo, hi); - lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE); - wrmsr(cmd->addr.msr.reg, lo, hi); - break; - case SYSTEM_IO_CAPABLE: - acpi_os_write_port((acpi_io_address)cmd->addr.io.port, - cmd->val, - (u32)cmd->addr.io.bit_width); - break; - default: - break; - } -} - -static void drv_read(struct drv_cmd *cmd) -{ - int err; - cmd->val = 0; - - err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1); - WARN_ON_ONCE(err); /* smp_call_function_any() was buggy? */ -} - -static void drv_write(struct drv_cmd *cmd) -{ - int this_cpu; - - this_cpu = get_cpu(); - if (cpumask_test_cpu(this_cpu, cmd->mask)) - do_drv_write(cmd); - smp_call_function_many(cmd->mask, do_drv_write, cmd, 1); - put_cpu(); -} - -static u32 get_cur_val(const struct cpumask *mask) -{ - struct acpi_processor_performance *perf; - struct drv_cmd cmd; - - if (unlikely(cpumask_empty(mask))) - return 0; - - switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) { - case SYSTEM_INTEL_MSR_CAPABLE: - cmd.type = SYSTEM_INTEL_MSR_CAPABLE; - cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; - break; - case SYSTEM_IO_CAPABLE: - cmd.type = SYSTEM_IO_CAPABLE; - perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data; - cmd.addr.io.port = perf->control_register.address; - cmd.addr.io.bit_width = perf->control_register.bit_width; - break; - default: - return 0; - } - - cmd.mask = mask; - drv_read(&cmd); - - pr_debug("get_cur_val = %u\n", cmd.val); - - return cmd.val; -} - -static unsigned int get_cur_freq_on_cpu(unsigned int cpu) -{ - struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu); - unsigned int freq; - unsigned int cached_freq; - - pr_debug("get_cur_freq_on_cpu (%d)\n", cpu); - - if (unlikely(data == NULL || - data->acpi_data == NULL || data->freq_table == NULL)) { - return 0; - } - - cached_freq = data->freq_table[data->acpi_data->state].frequency; - freq = extract_freq(get_cur_val(cpumask_of(cpu)), data); - if (freq != cached_freq) { - /* - * The dreaded BIOS frequency change behind our back. - * Force set the frequency on next target call. - */ - data->resume = 1; - } - - pr_debug("cur freq = %u\n", freq); - - return freq; -} - -static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, - struct acpi_cpufreq_data *data) -{ - unsigned int cur_freq; - unsigned int i; - - for (i = 0; i < 100; i++) { - cur_freq = extract_freq(get_cur_val(mask), data); - if (cur_freq == freq) - return 1; - udelay(10); - } - return 0; -} - -static int acpi_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - struct acpi_processor_performance *perf; - struct cpufreq_freqs freqs; - struct drv_cmd cmd; - unsigned int next_state = 0; /* Index into freq_table */ - unsigned int next_perf_state = 0; /* Index into perf table */ - unsigned int i; - int result = 0; - - pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); - - if (unlikely(data == NULL || - data->acpi_data == NULL || data->freq_table == NULL)) { - return -ENODEV; - } - - perf = data->acpi_data; - result = cpufreq_frequency_table_target(policy, - data->freq_table, - target_freq, - relation, &next_state); - if (unlikely(result)) { - result = -ENODEV; - goto out; - } - - next_perf_state = data->freq_table[next_state].index; - if (perf->state == next_perf_state) { - if (unlikely(data->resume)) { - pr_debug("Called after resume, resetting to P%d\n", - next_perf_state); - data->resume = 0; - } else { - pr_debug("Already at target state (P%d)\n", - next_perf_state); - goto out; - } - } - - switch (data->cpu_feature) { - case SYSTEM_INTEL_MSR_CAPABLE: - cmd.type = SYSTEM_INTEL_MSR_CAPABLE; - cmd.addr.msr.reg = MSR_IA32_PERF_CTL; - cmd.val = (u32) perf->states[next_perf_state].control; - break; - case SYSTEM_IO_CAPABLE: - cmd.type = SYSTEM_IO_CAPABLE; - cmd.addr.io.port = perf->control_register.address; - cmd.addr.io.bit_width = perf->control_register.bit_width; - cmd.val = (u32) perf->states[next_perf_state].control; - break; - default: - result = -ENODEV; - goto out; - } - - /* cpufreq holds the hotplug lock, so we are safe from here on */ - if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) - cmd.mask = policy->cpus; - else - cmd.mask = cpumask_of(policy->cpu); - - freqs.old = perf->states[perf->state].core_frequency * 1000; - freqs.new = data->freq_table[next_state].frequency; - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - drv_write(&cmd); - - if (acpi_pstate_strict) { - if (!check_freqs(cmd.mask, freqs.new, data)) { - pr_debug("acpi_cpufreq_target failed (%d)\n", - policy->cpu); - result = -EAGAIN; - goto out; - } - } - - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - perf->state = next_perf_state; - -out: - return result; -} - -static int acpi_cpufreq_verify(struct cpufreq_policy *policy) -{ - struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - - pr_debug("acpi_cpufreq_verify\n"); - - return cpufreq_frequency_table_verify(policy, data->freq_table); -} - -static unsigned long -acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) -{ - struct acpi_processor_performance *perf = data->acpi_data; - - if (cpu_khz) { - /* search the closest match to cpu_khz */ - unsigned int i; - unsigned long freq; - unsigned long freqn = perf->states[0].core_frequency * 1000; - - for (i = 0; i < (perf->state_count-1); i++) { - freq = freqn; - freqn = perf->states[i+1].core_frequency * 1000; - if ((2 * cpu_khz) > (freqn + freq)) { - perf->state = i; - return freq; - } - } - perf->state = perf->state_count-1; - return freqn; - } else { - /* assume CPU is at P0... */ - perf->state = 0; - return perf->states[0].core_frequency * 1000; - } -} - -static void free_acpi_perf_data(void) -{ - unsigned int i; - - /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */ - for_each_possible_cpu(i) - free_cpumask_var(per_cpu_ptr(acpi_perf_data, i) - ->shared_cpu_map); - free_percpu(acpi_perf_data); -} - -/* - * acpi_cpufreq_early_init - initialize ACPI P-States library - * - * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c) - * in order to determine correct frequency and voltage pairings. We can - * do _PDC and _PSD and find out the processor dependency for the - * actual init that will happen later... - */ -static int __init acpi_cpufreq_early_init(void) -{ - unsigned int i; - pr_debug("acpi_cpufreq_early_init\n"); - - acpi_perf_data = alloc_percpu(struct acpi_processor_performance); - if (!acpi_perf_data) { - pr_debug("Memory allocation error for acpi_perf_data.\n"); - return -ENOMEM; - } - for_each_possible_cpu(i) { - if (!zalloc_cpumask_var_node( - &per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map, - GFP_KERNEL, cpu_to_node(i))) { - - /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ - free_acpi_perf_data(); - return -ENOMEM; - } - } - - /* Do initialization in ACPI core */ - acpi_processor_preregister_performance(acpi_perf_data); - return 0; -} - -#ifdef CONFIG_SMP -/* - * Some BIOSes do SW_ANY coordination internally, either set it up in hw - * or do it in BIOS firmware and won't inform about it to OS. If not - * detected, this has a side effect of making CPU run at a different speed - * than OS intended it to run at. Detect it and handle it cleanly. - */ -static int bios_with_sw_any_bug; - -static int sw_any_bug_found(const struct dmi_system_id *d) -{ - bios_with_sw_any_bug = 1; - return 0; -} - -static const struct dmi_system_id sw_any_bug_dmi_table[] = { - { - .callback = sw_any_bug_found, - .ident = "Supermicro Server X6DLP", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), - DMI_MATCH(DMI_BIOS_VERSION, "080010"), - DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"), - }, - }, - { } -}; - -static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) -{ - /* Intel Xeon Processor 7100 Series Specification Update - * http://www.intel.com/Assets/PDF/specupdate/314554.pdf - * AL30: A Machine Check Exception (MCE) Occurring during an - * Enhanced Intel SpeedStep Technology Ratio Change May Cause - * Both Processor Cores to Lock Up. */ - if (c->x86_vendor == X86_VENDOR_INTEL) { - if ((c->x86 == 15) && - (c->x86_model == 6) && - (c->x86_mask == 8)) { - printk(KERN_INFO "acpi-cpufreq: Intel(R) " - "Xeon(R) 7100 Errata AL30, processors may " - "lock up on frequency changes: disabling " - "acpi-cpufreq.\n"); - return -ENODEV; - } - } - return 0; -} -#endif - -static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int i; - unsigned int valid_states = 0; - unsigned int cpu = policy->cpu; - struct acpi_cpufreq_data *data; - unsigned int result = 0; - struct cpuinfo_x86 *c = &cpu_data(policy->cpu); - struct acpi_processor_performance *perf; -#ifdef CONFIG_SMP - static int blacklisted; -#endif - - pr_debug("acpi_cpufreq_cpu_init\n"); - -#ifdef CONFIG_SMP - if (blacklisted) - return blacklisted; - blacklisted = acpi_cpufreq_blacklist(c); - if (blacklisted) - return blacklisted; -#endif - - data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); - per_cpu(acfreq_data, cpu) = data; - - if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) - acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; - - result = acpi_processor_register_performance(data->acpi_data, cpu); - if (result) - goto err_free; - - perf = data->acpi_data; - policy->shared_type = perf->shared_type; - - /* - * Will let policy->cpus know about dependency only when software - * coordination is required. - */ - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || - policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { - cpumask_copy(policy->cpus, perf->shared_cpu_map); - } - cpumask_copy(policy->related_cpus, perf->shared_cpu_map); - -#ifdef CONFIG_SMP - dmi_check_system(sw_any_bug_dmi_table); - if (bios_with_sw_any_bug && cpumask_weight(policy->cpus) == 1) { - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - cpumask_copy(policy->cpus, cpu_core_mask(cpu)); - } -#endif - - /* capability check */ - if (perf->state_count <= 1) { - pr_debug("No P-States\n"); - result = -ENODEV; - goto err_unreg; - } - - if (perf->control_register.space_id != perf->status_register.space_id) { - result = -ENODEV; - goto err_unreg; - } - - switch (perf->control_register.space_id) { - case ACPI_ADR_SPACE_SYSTEM_IO: - pr_debug("SYSTEM IO addr space\n"); - data->cpu_feature = SYSTEM_IO_CAPABLE; - break; - case ACPI_ADR_SPACE_FIXED_HARDWARE: - pr_debug("HARDWARE addr space\n"); - if (!check_est_cpu(cpu)) { - result = -ENODEV; - goto err_unreg; - } - data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; - break; - default: - pr_debug("Unknown addr space %d\n", - (u32) (perf->control_register.space_id)); - result = -ENODEV; - goto err_unreg; - } - - data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * - (perf->state_count+1), GFP_KERNEL); - if (!data->freq_table) { - result = -ENOMEM; - goto err_unreg; - } - - /* detect transition latency */ - policy->cpuinfo.transition_latency = 0; - for (i = 0; i < perf->state_count; i++) { - if ((perf->states[i].transition_latency * 1000) > - policy->cpuinfo.transition_latency) - policy->cpuinfo.transition_latency = - perf->states[i].transition_latency * 1000; - } - - /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */ - if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && - policy->cpuinfo.transition_latency > 20 * 1000) { - policy->cpuinfo.transition_latency = 20 * 1000; - printk_once(KERN_INFO - "P-state transition latency capped at 20 uS\n"); - } - - /* table init */ - for (i = 0; i < perf->state_count; i++) { - if (i > 0 && perf->states[i].core_frequency >= - data->freq_table[valid_states-1].frequency / 1000) - continue; - - data->freq_table[valid_states].index = i; - data->freq_table[valid_states].frequency = - perf->states[i].core_frequency * 1000; - valid_states++; - } - data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; - perf->state = 0; - - result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); - if (result) - goto err_freqfree; - - if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq) - printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n"); - - switch (perf->control_register.space_id) { - case ACPI_ADR_SPACE_SYSTEM_IO: - /* Current speed is unknown and not detectable by IO port */ - policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); - break; - case ACPI_ADR_SPACE_FIXED_HARDWARE: - acpi_cpufreq_driver.get = get_cur_freq_on_cpu; - policy->cur = get_cur_freq_on_cpu(cpu); - break; - default: - break; - } - - /* notify BIOS that we exist */ - acpi_processor_notify_smm(THIS_MODULE); - - /* Check for APERF/MPERF support in hardware */ - if (boot_cpu_has(X86_FEATURE_APERFMPERF)) - acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; - - pr_debug("CPU%u - ACPI performance management activated.\n", cpu); - for (i = 0; i < perf->state_count; i++) - pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", - (i == perf->state ? '*' : ' '), i, - (u32) perf->states[i].core_frequency, - (u32) perf->states[i].power, - (u32) perf->states[i].transition_latency); - - cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); - - /* - * the first call to ->target() should result in us actually - * writing something to the appropriate registers. - */ - data->resume = 1; - - return result; - -err_freqfree: - kfree(data->freq_table); -err_unreg: - acpi_processor_unregister_performance(perf, cpu); -err_free: - kfree(data); - per_cpu(acfreq_data, cpu) = NULL; - - return result; -} - -static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) -{ - struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - - pr_debug("acpi_cpufreq_cpu_exit\n"); - - if (data) { - cpufreq_frequency_table_put_attr(policy->cpu); - per_cpu(acfreq_data, policy->cpu) = NULL; - acpi_processor_unregister_performance(data->acpi_data, - policy->cpu); - kfree(data->freq_table); - kfree(data); - } - - return 0; -} - -static int acpi_cpufreq_resume(struct cpufreq_policy *policy) -{ - struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); - - pr_debug("acpi_cpufreq_resume\n"); - - data->resume = 1; - - return 0; -} - -static struct freq_attr *acpi_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver acpi_cpufreq_driver = { - .verify = acpi_cpufreq_verify, - .target = acpi_cpufreq_target, - .bios_limit = acpi_processor_get_bios_limit, - .init = acpi_cpufreq_cpu_init, - .exit = acpi_cpufreq_cpu_exit, - .resume = acpi_cpufreq_resume, - .name = "acpi-cpufreq", - .owner = THIS_MODULE, - .attr = acpi_cpufreq_attr, -}; - -static int __init acpi_cpufreq_init(void) -{ - int ret; - - if (acpi_disabled) - return 0; - - pr_debug("acpi_cpufreq_init\n"); - - ret = acpi_cpufreq_early_init(); - if (ret) - return ret; - - ret = cpufreq_register_driver(&acpi_cpufreq_driver); - if (ret) - free_acpi_perf_data(); - - return ret; -} - -static void __exit acpi_cpufreq_exit(void) -{ - pr_debug("acpi_cpufreq_exit\n"); - - cpufreq_unregister_driver(&acpi_cpufreq_driver); - - free_acpi_perf_data(); -} - -module_param(acpi_pstate_strict, uint, 0644); -MODULE_PARM_DESC(acpi_pstate_strict, - "value 0 or non-zero. non-zero -> strict ACPI checks are " - "performed during frequency changes."); - -late_initcall(acpi_cpufreq_init); -module_exit(acpi_cpufreq_exit); - -MODULE_ALIAS("acpi"); diff --git a/linux-3.4/drivers/cpufreq.new/autohotplug.c b/linux-3.4/drivers/cpufreq.new/autohotplug.c deleted file mode 100755 index c9d14bb4..00000000 --- a/linux-3.4/drivers/cpufreq.new/autohotplug.c +++ /dev/null @@ -1,1205 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define CREATE_TRACE_POINTS -#include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) -#include -#endif -#include -#include "autohotplug.h" - -struct auto_hotplug_data_struct auto_hotplug_data; -static DEFINE_PER_CPU(struct auto_cpu_hotplug_cpuinfo, cpuinfo); -static struct auto_cpu_hotplug_governor governor; -static struct cpumask hmp_fast_cpu_mask; -static struct cpumask hmp_slow_cpu_mask; -static struct task_struct *auto_hotplug_task; -struct timer_list hotplug_task_timer; -struct timer_list hotplug_sample_timer; -static struct mutex hotplug_enable_mutex; -static spinlock_t hotplug_load_lock; -static spinlock_t cpumask_lock; -struct autohotplug_governor *cur_governor; - -static atomic_t hotplug_lock = ATOMIC_INIT(0); -static atomic_t g_hotplug_lock = ATOMIC_INIT(0); - -static unsigned int hotplug_enable = 0; -static unsigned int boost_all_online = 0; -static unsigned int hotplug_period_us = 500000; -static unsigned int hotplug_sample_us = 20000; -static unsigned int cpu_up_lastcpu = INVALID_CPU; - -static unsigned int hotplug_up_attempt_hold_us = 500000; -static unsigned int hotplug_up_cpu_hold_us = 1500000; -static unsigned int hotplug_boost_hold_us = 3000000; -static unsigned int total_nr_cpus = CONFIG_NR_CPUS; - -static unsigned long cpu_sleep_lasttime[CONFIG_NR_CPUS]; - -unsigned int load_try_down = 30; -unsigned int load_save_up = 75; -unsigned int load_try_up = 80; -unsigned int load_try_boost = 95; - -unsigned int load_last_big_min_freq = 300000; -unsigned int load_up_stable_us = 100000; -unsigned int load_down_stable_us = 500000; -unsigned int load_boost_stable_us = 200000; - -unsigned long cpu_boost_lasttime; -unsigned long cpu_up_lasttime; -unsigned long cpu_in_sleep[CONFIG_NR_CPUS]; - -static int c0_min = 0; -static int c0_max = 0; -static int c1_min = 0; -static int c1_max = 0; - -static char *cpu_state_sysfs[]= -{ - "cpu0_on", - "cpu1_off", - "cpu2_off", - "cpu3_off", - "cpu4_off", - "cpu5_off", - "cpu6_off", - "cpu7_off" -}; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) || \ -defined(CONFIG_ARCH_SUN9IW1) || \ -defined(CONFIG_ARCH_SUN8IW5) || \ -defined(CONFIG_ARCH_SUN8IW6) || \ -defined(CONFIG_ARCH_SUN8IW7) -extern u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy); -#else -static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, - cputime64_t *wall) -{ - u64 idle_time; - u64 cur_wall_time; - u64 busy_time; - - cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); - - busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; - - idle_time = cur_wall_time - busy_time; - if (wall) - *wall = jiffies_to_usecs(cur_wall_time); - - return jiffies_to_usecs(idle_time); -} - -static inline cputime64_t get_cpu_idle_time(unsigned int cpu, - cputime64_t *wall,int io_busy) -{ - u64 idle_time = get_cpu_idle_time_us(cpu, wall); - - if (idle_time == -1ULL) - idle_time = get_cpu_idle_time_jiffy(cpu, wall); - else if (!io_busy) - idle_time += get_cpu_iowait_time_us(cpu, wall); - - return idle_time; -} -#endif - -/* Check if cpu is in fastest hmp_domain */ -unsigned int is_cpu_big(int cpu) -{ - return cpumask_test_cpu(cpu, &hmp_fast_cpu_mask); -} - -/* Check if cpu is in slowest hmp_domain */ -unsigned int is_cpu_little(int cpu) -{ - return cpumask_test_cpu(cpu, &hmp_slow_cpu_mask); -} - -static int get_cpu_load_level(unsigned int load) -{ - if (load == INVALID_LOAD) - return LOAD_LEVEL_INVALID; - else if(load < load_try_down) - return LOAD_LEVEL_DOWN; - else if(load < load_save_up) - return LOAD_LEVEL_NORMAL; - else if(load < load_try_up) - return LOAD_LEVEL_MIDDLE; - else if(load < load_try_boost) - return LOAD_LEVEL_UP; - else - return LOAD_LEVEL_BOOST; -} - -static void set_cpu_load(unsigned int cpu, unsigned int load) -{ - if (cpu >= total_nr_cpus) - return; - - if (get_cpu_load_level(governor.load.cpu_load[cpu]) - != get_cpu_load_level(load)) - governor.load.cpu_load_lasttime[cpu] = jiffies; - - governor.load.cpu_load[cpu] = load; -} - -int do_cpu_down(unsigned int cpu) -{ - int i, c0_online=0, c1_online=0; - - if (cpu == 0 || cpu >= total_nr_cpus) - return 0; - - for_each_online_cpu(i) { - if (cpumask_test_cpu(i, &hmp_slow_cpu_mask)) - c0_online++; - else if (cpumask_test_cpu(i, &hmp_fast_cpu_mask)) - c1_online++; - } - - if (is_cpu_little(cpu) && c0_online <= c0_min) - return 0; - - if (is_cpu_big(cpu) && c1_online <= c1_min) - return 0; - - if (cpu == cpu_up_lastcpu && time_before(jiffies, - cpu_up_lasttime + usecs_to_jiffies(hotplug_up_cpu_hold_us))) - return 0; - - if (time_before(jiffies, - cpu_boost_lasttime + usecs_to_jiffies(hotplug_boost_hold_us))) - return 0; - - if (cpu_down(cpu)) - return 0; - - trace_cpu_autohotplug_operate(cpu, 0); - return 1; - -} - -int do_cpu_up(unsigned int cpu) -{ - int i, c0_online = 0, c1_online = 0; - - if (cpu == 0 || cpu >= total_nr_cpus) - return 0; - - for_each_online_cpu(i) { - if (cpumask_test_cpu(i, &hmp_slow_cpu_mask)) - c0_online++; - else if (cpumask_test_cpu(i, &hmp_fast_cpu_mask)) - c1_online++; - } - - if (is_cpu_little(cpu) && c0_online >= c0_max) - return 0; - - if (is_cpu_big(cpu) && c1_online >= c0_max) - return 0; - - if (cpu_up(cpu)) - return 0; - - cpu_up_lastcpu = cpu; - cpu_up_lasttime = jiffies; - - trace_cpu_autohotplug_operate(cpu, 1); - return 1; -} - -int get_cpus_stable_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first, int is_up) -{ - int i, found = 0, count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD) - && load->cpu_load[i] < level - && time_after_eq(jiffies, load->cpu_load_lasttime[i] - + usecs_to_jiffies(is_up ? load_up_stable_us - : load_down_stable_us)) - ) - { - if (first && (!found)) { - *first = i; - found = 1; - } - count++; - } - } - - return count; -} - -int get_bigs_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first) -{ - int i, found = 0, count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD) - && (load->cpu_load[i] < level) - && is_cpu_big(i)) - { - if (first && (!found)) { - *first = i; - found = 1; - } - count++; - } - } - - return count; -} - -int get_bigs_above(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first) -{ - int i, found = 0, count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD) - && (load->cpu_load[i] >= level) - && is_cpu_big(i)) - { - if (first && (!found)) { - *first = i; - found = 1; - } - count++; - } - } - - return count; -} - -int get_cpus_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first) -{ - int i, found = 0, count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD) && load->cpu_load[i] < level) { - if (first && (!found)) { - *first = i; - found = 1; - } - count++; - } - } - - return count; -} - -int get_littles_under(struct auto_cpu_hotplug_loadinfo* load, - unsigned char level, unsigned int* first) -{ - int i, found = 0, count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD) - && (load->cpu_load[i] < level) - && is_cpu_little(i)) - { - if (first && (!found)) { - *first = i; - found = 1; - } - count++; - } - } - - return count; -} - -int get_cpus_online(struct auto_cpu_hotplug_loadinfo *load, - int *little, int *big) -{ - int i, big_count = 0, little_count = 0; - - for (i = total_nr_cpus - 1; i >= 0; i--) { - if ((load->cpu_load[i] != INVALID_LOAD)) { - if (is_cpu_little(i)) - little_count++; - else - big_count++; - } - } - - *little = little_count; - *big = big_count; - - return 1; -} - -int try_up_big(void) -{ - unsigned int cpu = 0; - unsigned int found = total_nr_cpus; - - while (cpu < total_nr_cpus && cpu_possible(cpu)) { - cpu = cpumask_next_zero(cpu, cpu_online_mask); - if (is_cpu_big(cpu)) { - found = cpu; - break; - } - } - - if (found < total_nr_cpus && cpu_possible(found)) - return do_cpu_up(found); - else - return 0; -} - -int try_up_little(void) -{ - unsigned int cpu = 0; - unsigned int found = total_nr_cpus; - - while (cpu < total_nr_cpus && cpu_possible(cpu)) { - cpu = cpumask_next_zero(cpu, cpu_online_mask); - if (is_cpu_little(cpu)) { - found = cpu; - break; - } - } - - if (found < total_nr_cpus && cpu_possible(found)) - return do_cpu_up(found); - else - return 0; -} - -static int try_any_up(void) -{ - unsigned int cpu = 0; - - while (cpu < total_nr_cpus && cpu_possible(cpu)) { - cpu = cpumask_next_zero(cpu, cpu_online_mask); - if (cpu < total_nr_cpus && cpu_possible(cpu)) - return do_cpu_up(cpu); - } - - return 0; -} - -static int try_lock_up(int hotplug_lock) -{ - struct cpumask tmp_core_up_mask, tmp_core_down_mask; - int cpu, lock_flag = hotplug_lock - num_online_cpus(); - unsigned long flags; - - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_clear(&tmp_core_up_mask); - cpumask_clear(&tmp_core_down_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - - if (lock_flag > 0) { - for_each_cpu_not(cpu, cpu_online_mask) { - if (lock_flag-- == 0) - break; - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_or(&tmp_core_up_mask, cpumask_of(cpu), &tmp_core_up_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - } - } else if (lock_flag < 0) { - lock_flag = -lock_flag; - for (cpu = 7; cpu > 0; cpu--) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) { - if (lock_flag-- == 0) - break; - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_or(&tmp_core_down_mask, cpumask_of(cpu), - &tmp_core_down_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - } - } - } - - if (!cpumask_empty(&tmp_core_up_mask)) { - for_each_cpu(cpu, &tmp_core_up_mask) { - if (!cpu_online(cpu)) { - return do_cpu_up(cpu); - } - } - } else if (!cpumask_empty(&tmp_core_down_mask)) { - for_each_cpu(cpu, &tmp_core_down_mask) { - if (cpu_online(cpu)) { - cpu_down(cpu); - } - } - } - - return 0; -} - -#ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE -static int get_any_offline_cpu(const cpumask_t *mask) -{ - int cpu, lastcpu = 0xffff; - - for_each_cpu(cpu, mask) { - if ((cpu != 0) && !cpu_online(cpu)) - return cpu; - } - - return lastcpu; -} -static int get_any_online_cpu(const cpumask_t *mask) -{ - int cpu, lastcpu = 0xffff; - - for_each_cpu(cpu, mask) { - if ((cpu != 0) && cpu_online(cpu)) { - if (lastcpu == 0xffff) - lastcpu = cpu; - else if (cpu >lastcpu) - lastcpu = cpu; - } - } - - return lastcpu; -} - -static int autohotplug_tryroom(void) -{ - unsigned int to_down, to_up; - int i, c0_online = 0, c1_online = 0; - - for_each_online_cpu(i) { - if (cpumask_test_cpu(i, &hmp_slow_cpu_mask)) - c0_online++; - else if (cpumask_test_cpu(i, &hmp_fast_cpu_mask)) - c1_online++; - } - - while (c1_online > c1_max) { - to_down = get_any_online_cpu(&hmp_fast_cpu_mask); - do_cpu_down(to_down); - c1_online--; - } - - while (c0_online > c0_max) { - to_down = get_any_online_cpu(&hmp_slow_cpu_mask); - do_cpu_down(to_down); - c0_online--; - } - - while (c1_online < c1_min) { - to_up = get_any_offline_cpu(&hmp_fast_cpu_mask); - do_cpu_up(to_up); - c1_online++; - } - - while (c0_online < c0_min) { - to_up = get_any_offline_cpu(&hmp_slow_cpu_mask); - do_cpu_up(to_up); - c0_online++; - } - - return 1; -} - -int autohotplug_update_room(unsigned int c0min, unsigned int c1min, - unsigned int c0max, unsigned int c1max) -{ - mutex_lock(&hotplug_enable_mutex); - c0_min = c0min; - c1_min = c1min; - c0_max = c0max; - c1_max = c1max; - mutex_unlock(&hotplug_enable_mutex); - - return 0; -} -EXPORT_SYMBOL(autohotplug_update_room); -#endif - -static int autohotplug_task(void *data) -{ - int i, hotplug_lock, try_attemp = 0; // 0: no success 1: up success 2: down success - unsigned long flags; - struct auto_cpu_hotplug_loadinfo load; - - set_freezable(); - while (1) { - if (freezing(current)) { - if (try_to_freeze()) - continue; - } - - if (hotplug_enable) { - try_attemp = 0; - spin_lock_irqsave(&hotplug_load_lock, flags); - memcpy(&load, &governor.load, sizeof(load)); - spin_unlock_irqrestore(&hotplug_load_lock, flags); - - mutex_lock(&hotplug_enable_mutex); - load.max_load = 0; - load.min_load = 255; - load.max_cpu = INVALID_CPU; - load.min_cpu = INVALID_CPU; - - for (i = total_nr_cpus - 1; i>= 0; i--) { - if (!cpu_online(i)) - load.cpu_load[i] = INVALID_LOAD; - - if ((load.cpu_load[i] != INVALID_LOAD) - && (load.cpu_load[i] >= load.max_load)) - { - load.max_load =load.cpu_load[i]; - load.max_cpu = i; - } - - if ((load.cpu_load[i] != INVALID_LOAD) - && (load.cpu_load[i] < load.min_load)) - { - load.min_load =load.cpu_load[i]; - load.min_cpu = i; - } - } - - if (boost_all_online) { - try_any_up(); - } else { - hotplug_lock = atomic_read(&g_hotplug_lock); - /* check if current is in hotplug lock */ - if (hotplug_lock) { - try_lock_up(hotplug_lock); - } else { - if (cur_governor->try_up(&load)) { - try_attemp = 1; - if (cur_governor->update_limits) - cur_governor->update_limits(); - } else { - if (time_after_eq(jiffies, cpu_up_lasttime - + usecs_to_jiffies(hotplug_up_attempt_hold_us))) - { - if (cur_governor->try_down(&load)) { - try_attemp = 2; - if (cur_governor->update_limits) - cur_governor->update_limits(); - } - } - } - } - } - -#ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE - if (!try_attemp) - autohotplug_tryroom(); -#endif - mutex_unlock(&hotplug_enable_mutex); - } - - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - if (kthread_should_stop()) - break; - set_current_state(TASK_RUNNING); - } - - return 0; -} - -static unsigned int autohotplug_updateload(int cpu) -{ - struct auto_cpu_hotplug_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); - u64 now, now_idle, delta_idle, delta_time, active_time, load; - - now_idle = get_cpu_idle_time(cpu, &now, 1); - delta_idle = now_idle - pcpu->time_in_idle; - delta_time = now - pcpu->time_in_idle_timestamp; - - if (delta_time <= delta_idle) - active_time = 0; - else - active_time = delta_time - delta_idle; - - pcpu->time_in_idle = now_idle; - pcpu->time_in_idle_timestamp = now; - - load = active_time * 100; - do_div(load, delta_time); - - return ((unsigned int)load); -} - -static void autohotplug_governor_updateload(int cpu, unsigned int load, - unsigned int target, struct cpufreq_policy *policy) -{ - - unsigned long flags; - unsigned int cur = target; - - if (cur) { - spin_lock_irqsave(&hotplug_load_lock, flags); - set_cpu_load(cpu, (load * cur) / policy->max); - if (is_cpu_big(cpu)) { - governor.load.big_min_load = load_last_big_min_freq * 100 / policy->max; - } - spin_unlock_irqrestore(&hotplug_load_lock, flags); - } - -} -static void autohotplug_sample_timer(unsigned long data) -{ - unsigned int i, load; - struct cpufreq_policy policy; - struct auto_cpu_hotplug_cpuinfo *pcpu; - unsigned long flags, expires; - static const char performance_governor[] = "performance"; - static const char powersave_governor[] = "powersave"; - - if (!mutex_trylock(&hotplug_enable_mutex)) - goto rearm; - - for_each_possible_cpu(i) { - if ((cpufreq_get_policy(&policy, i) == 0) - && policy.governor->name - && !(!strncmp(policy.governor->name, performance_governor, - strlen(performance_governor)) - || !strncmp(policy.governor->name, powersave_governor, - strlen(powersave_governor)) - ) - ) - { - pcpu = &per_cpu(cpuinfo, i); - spin_lock_irqsave(&pcpu->load_lock, flags); - load = autohotplug_updateload(i); - autohotplug_governor_updateload(i, load, - (policy.cur ? policy.cur : policy.min), &policy); - spin_unlock_irqrestore(&pcpu->load_lock, flags); - } - else -#ifdef CONFIG_CPU_GOV_AUTO_HOTPLUG_WITHOUT_POLICY - { - policy.cur=1000000; - policy.max=1000000; - pcpu = &per_cpu(cpuinfo, i); - spin_lock_irqsave(&pcpu->load_lock, flags); - load = autohotplug_updateload(i); - autohotplug_governor_updateload(i, load, - (policy.cur ? policy.cur : policy.min), &policy); - spin_unlock_irqrestore(&pcpu->load_lock, flags); - } -#else - set_cpu_load(i, INVALID_LOAD); -#endif - } - - mutex_unlock(&hotplug_enable_mutex); - -rearm: - if (!timer_pending(&hotplug_sample_timer)) { - expires = jiffies + usecs_to_jiffies(hotplug_sample_us); - mod_timer_pinned(&hotplug_sample_timer, expires); - } - return; -} - -static void autohotplug_task_timer(unsigned long data) -{ - unsigned long expires; - - if (hotplug_enable) - wake_up_process(auto_hotplug_task); - - if (!timer_pending(&hotplug_task_timer)) { - expires = jiffies + usecs_to_jiffies(hotplug_period_us); - mod_timer_pinned(&hotplug_task_timer, expires); - } -} - -static int autohotplug_timer_start(void) -{ - int i; - - mutex_lock(&hotplug_enable_mutex); - - /* init sample timer */ - init_timer_deferrable(&hotplug_sample_timer); - hotplug_sample_timer.function = autohotplug_sample_timer; - hotplug_sample_timer.data = (unsigned long)&governor.load; - hotplug_sample_timer.expires = jiffies + usecs_to_jiffies(hotplug_sample_us); - add_timer_on(&hotplug_sample_timer, 0); - - /* init task timer */ - for (i = total_nr_cpus - 1; i >= 0; i--) { - set_cpu_load(i, INVALID_LOAD); - cpu_in_sleep[i] = 0; - cpu_sleep_lasttime[i] = i ? 0 : jiffies; - } - - cpu_up_lasttime = jiffies; - cpu_boost_lasttime = jiffies; - - /* init hotplug timer */ - init_timer(&hotplug_task_timer); - hotplug_task_timer.function = autohotplug_task_timer; - hotplug_task_timer.data = (unsigned long)&governor.load; - hotplug_task_timer.expires = jiffies + usecs_to_jiffies(hotplug_period_us); - add_timer_on(&hotplug_task_timer, 0); - - mutex_unlock(&hotplug_enable_mutex); - return 0; -} - -static int autohotplug_timer_stop(void) -{ - mutex_lock(&hotplug_enable_mutex); - del_timer_sync(&hotplug_task_timer); - del_timer_sync(&hotplug_sample_timer); - mutex_unlock(&hotplug_enable_mutex); - - return 0; -} - -int hotplug_cpu_lock(int num_core) -{ - int prev_lock; - - mutex_lock(&hotplug_enable_mutex); - if (num_core < 1 || num_core > num_possible_cpus()) { - mutex_unlock(&hotplug_enable_mutex); - return -EINVAL; - } - - prev_lock = atomic_read(&g_hotplug_lock); - if (prev_lock != 0 && prev_lock < num_core) { - mutex_unlock(&hotplug_enable_mutex); - return -EINVAL; - } - - atomic_set(&g_hotplug_lock, num_core); - wake_up_process(auto_hotplug_task); - mutex_unlock(&hotplug_enable_mutex); - - return 0; -} - -int hotplug_cpu_unlock(int num_core) -{ - int prev_lock = atomic_read(&g_hotplug_lock); - - mutex_lock(&hotplug_enable_mutex); - - if (prev_lock != num_core) { - mutex_unlock(&hotplug_enable_mutex); - return -EINVAL; - } - - atomic_set(&g_hotplug_lock, 0); - mutex_unlock(&hotplug_enable_mutex); - - return 0; -} - -unsigned int hotplug_enable_from_sysfs(unsigned int temp, unsigned int *value) -{ - int prev_lock; - - if (temp && (!hotplug_enable)) { - autohotplug_timer_start(); - } else if (!temp && hotplug_enable) { - prev_lock = atomic_read(&hotplug_lock); - if (prev_lock) - hotplug_cpu_unlock(prev_lock); - - atomic_set(&hotplug_lock, 0); - autohotplug_timer_stop(); - } - - return temp; -} - -unsigned int cpu_sleep_to_sysfs(unsigned int temp, unsigned int *value) -{ - unsigned int index = ((unsigned int)value - - (unsigned int)cpu_in_sleep) / sizeof(unsigned int); - - if (!index) - return (jiffies - cpu_sleep_lasttime[index]); - - if (cpu_online(index)) - return cpu_in_sleep[index]; - else - return (cpu_in_sleep[index] + (jiffies - cpu_sleep_lasttime[index])); -} - -unsigned int hotplug_lock_from_sysfs(unsigned int temp, unsigned int *value) -{ - int ret, prev_lock; - - if ((!hotplug_enable) || temp > NR_CPUS) { - return atomic_read(&g_hotplug_lock); - } - - prev_lock = atomic_read(&hotplug_lock); - if (prev_lock) - hotplug_cpu_unlock(prev_lock); - - if (temp == 0) { - atomic_set(&hotplug_lock, 0); - return 0; - } - - ret = hotplug_cpu_lock(temp); - if (ret) { - printk(KERN_ERR "[HOTPLUG] already locked with smaller value %d < %d\n", - atomic_read(&g_hotplug_lock), temp); - return ret; - } - - atomic_set(&hotplug_lock, temp); - - return temp; -} - -unsigned int hotplug_lock_to_sysfs(unsigned int temp, unsigned int *value) -{ - return atomic_read(&hotplug_lock); -} - -static ssize_t autohotplug_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - ssize_t ret = 0; - struct auto_hotplug_global_attr *auto_attr = - container_of(attr, struct auto_hotplug_global_attr, attr); - unsigned int temp = *(auto_attr->value); - - if (auto_attr->to_sysfs != NULL) - temp = auto_attr->to_sysfs(temp, auto_attr->value); - - ret = sprintf(buf, "%u\n", temp); - return ret; -} - -static ssize_t autohotplug_store(struct kobject *a, struct attribute *attr, - const char *buf, size_t count) -{ - unsigned int temp; - ssize_t ret = count; - struct auto_hotplug_global_attr *auto_attr = - container_of(attr, struct auto_hotplug_global_attr, attr); - char *str = vmalloc(count + 1); - - if (str == NULL) - return -ENOMEM; - - memcpy(str, buf, count); - str[count] = 0; - if (sscanf(str, "%u", &temp) < 1) { - ret = -EINVAL; - } else { - if (auto_attr->from_sysfs != NULL) - temp = auto_attr->from_sysfs(temp, auto_attr->value); - if (temp < 0) - ret = -EINVAL; - else - *(auto_attr->value) = temp; - } - - vfree(str); - return ret; -} - -void autohotplug_attr_add(const char *name, unsigned int *value, umode_t mode, - unsigned int (*to_sysfs)(unsigned int, unsigned int *), - unsigned int (*from_sysfs)(unsigned int ,unsigned int*)) -{ - int i = 0; - - while (auto_hotplug_data.attributes[i] != NULL) { - i++; - if (i >= HOTPLUG_DATA_SYSFS_MAX) - return; - } - - auto_hotplug_data.attr[i].attr.mode = mode; - auto_hotplug_data.attr[i].show = autohotplug_show; - auto_hotplug_data.attr[i].store = autohotplug_store; - auto_hotplug_data.attr[i].attr.name = name; - auto_hotplug_data.attr[i].value = value; - auto_hotplug_data.attr[i].to_sysfs = to_sysfs; - auto_hotplug_data.attr[i].from_sysfs = from_sysfs; - auto_hotplug_data.attributes[i] = &auto_hotplug_data.attr[i].attr; - auto_hotplug_data.attributes[i + 1] = NULL; -} - -static int __cpuinit autohotplug_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned long flags; - unsigned int cpu = (unsigned long)hcpu; - struct device *dev; - - dev = get_cpu_device(cpu); - if (dev) { - switch (action) { - case CPU_ONLINE: - spin_lock_irqsave(&hotplug_load_lock, flags); - set_cpu_load(cpu, INVALID_LOAD); - if (cpu_sleep_lasttime[cpu]) { - cpu_in_sleep[cpu] += jiffies - cpu_sleep_lasttime[cpu]; - cpu_sleep_lasttime[cpu] = 0; - } - spin_unlock_irqrestore(&hotplug_load_lock, flags); - break; - case CPU_DOWN_PREPARE: - case CPU_UP_CANCELED_FROZEN: - case CPU_DOWN_FAILED: - spin_lock_irqsave(&hotplug_load_lock, flags); - set_cpu_load(cpu, INVALID_LOAD); - spin_unlock_irqrestore(&hotplug_load_lock, flags); - break; - case CPU_DEAD: - spin_lock_irqsave(&hotplug_load_lock, flags); - cpu_sleep_lasttime[cpu] = jiffies; - spin_unlock_irqrestore(&hotplug_load_lock, flags); - break; - default: - break; - } - } - return NOTIFY_OK; -} - -static struct notifier_block __refdata hotplug_cpu_notifier = { - .notifier_call = autohotplug_cpu_callback, -}; - -#ifdef CONFIG_DEBUG_FS -static struct dentry *autohotplug_loaddbg_root; -static char autohotplug_load_info[256]; - -static int autohotplug_loaddbg_open(struct inode *inode, - struct file *file) -{ - return 0; -} -static int autohotplug_loaddbg_release(struct inode *inode, - struct file *file) -{ - return 0; -} -static ssize_t autohotplug_loaddbg_write(struct file *file, - const char __user *buf, size_t count, loff_t *ppos) -{ - return 0; -} -static ssize_t autohotplug_loaddbg_read(struct file *file, - char __user *buf, size_t count, loff_t *ppos) -{ - int i, len; - - for_each_possible_cpu(i) { - sprintf(autohotplug_load_info + i * 5,"%4d ", governor.load.cpu_load[i]); - } - - len = strlen(autohotplug_load_info); - autohotplug_load_info[len] = 0x0A; - autohotplug_load_info[len + 1] = 0x0; - - len = strlen(autohotplug_load_info); - if (len) { - if (*ppos >=len) - return 0; - if (count >=len) - count = len; - if (count > (len - *ppos)) - count = (len - *ppos); - if (copy_to_user((void __user *)buf, - (const void *)autohotplug_load_info, (unsigned long)len)) - return 0; - *ppos += count; - } else { - count = 0; - } - - return count; -} - -static const struct file_operations loaddbg_ops = { - .write = autohotplug_loaddbg_write, - .read = autohotplug_loaddbg_read, - .open = autohotplug_loaddbg_open, - .release = autohotplug_loaddbg_release, -}; - -int autohotplug_debug_init(void) -{ - autohotplug_loaddbg_root = debugfs_create_dir("hotplug", NULL); - - if (debugfs_create_file("load", 0444, autohotplug_loaddbg_root, - NULL, &loaddbg_ops)) - return 0; - - debugfs_remove_recursive(autohotplug_loaddbg_root); - autohotplug_loaddbg_root = NULL; - - return -ENOENT; -} -#endif /* CONFIG_DEBUG_FS */ - -static int autohotplug_attr_init(void) -{ - int i; - - memset(&auto_hotplug_data, sizeof(auto_hotplug_data), 0); - - for_each_possible_cpu(i) - autohotplug_attr_add(cpu_state_sysfs[i], (unsigned int*)&cpu_in_sleep[i], - 0444, cpu_sleep_to_sysfs, NULL); - - autohotplug_attr_add("enable", &hotplug_enable, 0644, - NULL, hotplug_enable_from_sysfs); - autohotplug_attr_add("boost_all", &boost_all_online, 0644, - NULL, NULL); - autohotplug_attr_add("timer_task_us", &hotplug_period_us, 0644, - NULL, NULL); - autohotplug_attr_add("try_cpuup_level", &load_try_up, 0644, - NULL, NULL); - autohotplug_attr_add("try_boost_level", &load_try_boost, 0644, - NULL, NULL); - autohotplug_attr_add("try_cpudn_level", &load_try_down, 0644, - NULL, NULL); - autohotplug_attr_add("save_all_up", &load_save_up, 0644, - NULL, NULL); - autohotplug_attr_add("hold_atept_us", &hotplug_up_attempt_hold_us, 0644, - NULL, NULL); - autohotplug_attr_add("hold_cpuup_us", &hotplug_up_cpu_hold_us, 0644, - NULL, NULL); - autohotplug_attr_add("hold_boost_us", &hotplug_boost_hold_us, 0644, - NULL, NULL); - autohotplug_attr_add("stable_tryup_us", &load_up_stable_us, 0644, - NULL, NULL); - autohotplug_attr_add("stable_boost_us", &load_boost_stable_us, 0644, - NULL, NULL); - autohotplug_attr_add("stable_tdown_us", &load_down_stable_us, 0644, - NULL, NULL); - autohotplug_attr_add("lock", (unsigned int *)&hotplug_lock, 0644, - hotplug_lock_to_sysfs, hotplug_lock_from_sysfs); - - /* init governor attr */ - if (cur_governor->init_attr) - cur_governor->init_attr(); - - auto_hotplug_data.attr_group.name = "autohotplug"; - auto_hotplug_data.attr_group.attrs = auto_hotplug_data.attributes; - - return sysfs_create_group(kernel_kobj, &auto_hotplug_data.attr_group); -} - -static int reboot_notifier_call(struct notifier_block *this, - unsigned long code, void *_cmd) -{ - printk("%s:%s: stop autoplug begin\n", __FILE__, __func__); - - // disable auto hotplug - hotplug_enable_from_sysfs(0, NULL); - - printk("%s:%s: stop autoplug done\n", __FILE__, __func__); - return NOTIFY_DONE; -} - -static struct notifier_block reboot_notifier = { - .notifier_call = reboot_notifier_call, - // autohotplug notifier must be invoked before cpufreq notifier - .priority = 1, -}; - -int autohotplug_init(void) -{ - int cpu; - struct auto_cpu_hotplug_cpuinfo *pcpu; - - cur_governor = &autohotplug_smart; - if (cur_governor == NULL) { - pr_err("autohotplug governor is NULL, failed\n"); - return -EINVAL; - } - - if (cur_governor->get_fast_and_slow_cpus == NULL) { - pr_err("get_fast_and_slow_cpus is NULL, failed\n"); - return -EINVAL; - } - - cur_governor->get_fast_and_slow_cpus(&hmp_fast_cpu_mask, &hmp_slow_cpu_mask); - - /* init per_cpu load_lock */ - for_each_possible_cpu(cpu) { - pcpu = &per_cpu(cpuinfo, cpu); - spin_lock_init(&pcpu->load_lock); - if (cpumask_test_cpu(cpu, &hmp_fast_cpu_mask)) - c1_max++; - else - c0_max++; - } - - mutex_init(&hotplug_enable_mutex); - spin_lock_init(&hotplug_load_lock); - spin_lock_init(&cpumask_lock); - - if (hotplug_enable) - autohotplug_timer_start(); - - /* start task */ - auto_hotplug_task = kthread_create(autohotplug_task, - NULL, "auto_cpu_hotplug"); - if (IS_ERR(auto_hotplug_task)) - return PTR_ERR(auto_hotplug_task); - get_task_struct(auto_hotplug_task); - - /* attr init */ - autohotplug_attr_init(); - /* register hotcpu notifier */ - register_hotcpu_notifier(&hotplug_cpu_notifier); -#ifdef CONFIG_DEBUG_FS - autohotplug_debug_init(); -#endif - - /* register reboot notifier for process cpus when reboot */ - register_reboot_notifier(&reboot_notifier); - - /* turn hotplug task on*/ - wake_up_process(auto_hotplug_task); - - pr_debug("%s init ok\n", __func__); - return 0; -} - -device_initcall(autohotplug_init); - -MODULE_DESCRIPTION("CPU Auto Hotplug"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/autohotplug.h b/linux-3.4/drivers/cpufreq.new/autohotplug.h deleted file mode 100755 index d74f065e..00000000 --- a/linux-3.4/drivers/cpufreq.new/autohotplug.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * drivers/cpufreq/autohotplug.h - * - * Copyright (c) 2012 Softwinner. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __AUTOHOTPLUG__ -#define __AUTOHOTPLUG__ - -#define INVALID_LOAD 0xffffffff -#define INVALID_CPU 0xffffffff - -#define STABLE_DOWN 0 -#define STABLE_UP 1 -#define STABLE_BOOST 2 -#define STABLE_LAST_BIG 3 - -#define LOAD_LEVEL_INVALID -1 -#define LOAD_LEVEL_DOWN 0 -#define LOAD_LEVEL_NORMAL 1 -#define LOAD_LEVEL_MIDDLE 2 -#define LOAD_LEVEL_UP 3 -#define LOAD_LEVEL_BOOST 4 - -#if defined(CONFIG_SCHED_HMP) - #define AUTOHOTPLUG_SUNXI_SYSFS_MAX (3) -#elif defined(CONFIG_SCHED_SMP_DCMP) - #define AUTOHOTPLUG_SUNXI_SYSFS_MAX (1) -#else - #define AUTOHOTPLUG_SUNXI_SYSFS_MAX (0) -#endif - -#define HOTPLUG_DATA_SYSFS_MAX (14 + AUTOHOTPLUG_SUNXI_SYSFS_MAX + CONFIG_NR_CPUS) - -struct auto_cpu_hotplug_loadinfo -{ - unsigned int cpu_load[CONFIG_NR_CPUS]; - unsigned long cpu_load_lasttime[CONFIG_NR_CPUS]; - unsigned int max_load; - unsigned int min_load; - unsigned int max_cpu; - unsigned int min_cpu; - unsigned int big_min_load; -}; - -struct auto_cpu_hotplug_governor -{ - struct timer_list cpu_timer; - struct auto_cpu_hotplug_loadinfo load; -}; - -struct auto_cpu_hotplug_cpuinfo { - spinlock_t load_lock; /* protects the next 4 fields */ - u64 time_in_idle; - u64 time_in_idle_timestamp; -}; - -struct auto_hotplug_global_attr { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, - struct attribute *attr, char *buf); - ssize_t (*store)(struct kobject *a, struct attribute *b, - const char *c, size_t count); - unsigned int *value; - unsigned int (*to_sysfs)(unsigned int, unsigned int *); - unsigned int (*from_sysfs)(unsigned int, unsigned int *); -}; - -struct auto_hotplug_data_struct { - struct attribute_group attr_group; - struct attribute *attributes[HOTPLUG_DATA_SYSFS_MAX + 1]; - struct auto_hotplug_global_attr attr[HOTPLUG_DATA_SYSFS_MAX]; -}; - -struct autohotplug_governor { - void (*init_attr)(void); - int (*get_fast_and_slow_cpus)(struct cpumask *hmp_fast_cpu_mask, - struct cpumask *hmp_slow_cpu_mask); - int (*try_up)(struct auto_cpu_hotplug_loadinfo *load); - int (*try_down)(struct auto_cpu_hotplug_loadinfo *load); - void (*update_limits)(void); -}; - -extern unsigned int is_cpu_big(int cpu); -extern unsigned int is_cpu_little(int cpu); -extern int do_cpu_down(unsigned int cpu); -extern int try_up_little(void); -extern int try_up_big(void); - -extern void autohotplug_attr_add(const char *name, - unsigned int *value, umode_t mode, - unsigned int (*to_sysfs)(unsigned int, unsigned int *), - unsigned int (*from_sysfs)(unsigned int ,unsigned int*)); -extern int get_cpus_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first); -extern int get_bigs_above(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first); -extern int get_littles_under(struct auto_cpu_hotplug_loadinfo* load, - unsigned char level, unsigned int* first); -extern int get_bigs_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first); -extern int get_cpus_stable_under(struct auto_cpu_hotplug_loadinfo *load, - unsigned char level, unsigned int *first, int is_up); -extern int get_cpus_online(struct auto_cpu_hotplug_loadinfo *load, - int *little, int *big); - - -extern struct autohotplug_governor autohotplug_smart; - -#endif /* #ifndef __AUTOHOTPLUG__ */ diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq-nforce2.c b/linux-3.4/drivers/cpufreq.new/cpufreq-nforce2.c deleted file mode 100644 index 13d311ee..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq-nforce2.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * (C) 2004-2006 Sebastian Witt - * - * Licensed under the terms of the GNU GPL License version 2. - * Based upon reverse engineered information - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include -#include -#include - -#define NFORCE2_XTAL 25 -#define NFORCE2_BOOTFSB 0x48 -#define NFORCE2_PLLENABLE 0xa8 -#define NFORCE2_PLLREG 0xa4 -#define NFORCE2_PLLADR 0xa0 -#define NFORCE2_PLL(mul, div) (0x100000 | (mul << 8) | div) - -#define NFORCE2_MIN_FSB 50 -#define NFORCE2_SAFE_DISTANCE 50 - -/* Delay in ms between FSB changes */ -/* #define NFORCE2_DELAY 10 */ - -/* - * nforce2_chipset: - * FSB is changed using the chipset - */ -static struct pci_dev *nforce2_dev; - -/* fid: - * multiplier * 10 - */ -static int fid; - -/* min_fsb, max_fsb: - * minimum and maximum FSB (= FSB at boot time) - */ -static int min_fsb; -static int max_fsb; - -MODULE_AUTHOR("Sebastian Witt "); -MODULE_DESCRIPTION("nForce2 FSB changing cpufreq driver"); -MODULE_LICENSE("GPL"); - -module_param(fid, int, 0444); -module_param(min_fsb, int, 0444); - -MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)"); -MODULE_PARM_DESC(min_fsb, - "Minimum FSB to use, if not defined: current FSB - 50"); - -#define PFX "cpufreq-nforce2: " - -/** - * nforce2_calc_fsb - calculate FSB - * @pll: PLL value - * - * Calculates FSB from PLL value - */ -static int nforce2_calc_fsb(int pll) -{ - unsigned char mul, div; - - mul = (pll >> 8) & 0xff; - div = pll & 0xff; - - if (div > 0) - return NFORCE2_XTAL * mul / div; - - return 0; -} - -/** - * nforce2_calc_pll - calculate PLL value - * @fsb: FSB - * - * Calculate PLL value for given FSB - */ -static int nforce2_calc_pll(unsigned int fsb) -{ - unsigned char xmul, xdiv; - unsigned char mul = 0, div = 0; - int tried = 0; - - /* Try to calculate multiplier and divider up to 4 times */ - while (((mul == 0) || (div == 0)) && (tried <= 3)) { - for (xdiv = 2; xdiv <= 0x80; xdiv++) - for (xmul = 1; xmul <= 0xfe; xmul++) - if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) == - fsb + tried) { - mul = xmul; - div = xdiv; - } - tried++; - } - - if ((mul == 0) || (div == 0)) - return -1; - - return NFORCE2_PLL(mul, div); -} - -/** - * nforce2_write_pll - write PLL value to chipset - * @pll: PLL value - * - * Writes new FSB PLL value to chipset - */ -static void nforce2_write_pll(int pll) -{ - int temp; - - /* Set the pll addr. to 0x00 */ - pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0); - - /* Now write the value in all 64 registers */ - for (temp = 0; temp <= 0x3f; temp++) - pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll); - - return; -} - -/** - * nforce2_fsb_read - Read FSB - * - * Read FSB from chipset - * If bootfsb != 0, return FSB at boot-time - */ -static unsigned int nforce2_fsb_read(int bootfsb) -{ - struct pci_dev *nforce2_sub5; - u32 fsb, temp = 0; - - /* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */ - nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF, - PCI_ANY_ID, PCI_ANY_ID, NULL); - if (!nforce2_sub5) - return 0; - - pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb); - fsb /= 1000000; - - /* Check if PLL register is already set */ - pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp); - - if (bootfsb || !temp) - return fsb; - - /* Use PLL register FSB value */ - pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp); - fsb = nforce2_calc_fsb(temp); - - return fsb; -} - -/** - * nforce2_set_fsb - set new FSB - * @fsb: New FSB - * - * Sets new FSB - */ -static int nforce2_set_fsb(unsigned int fsb) -{ - u32 temp = 0; - unsigned int tfsb; - int diff; - int pll = 0; - - if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { - printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb); - return -EINVAL; - } - - tfsb = nforce2_fsb_read(0); - if (!tfsb) { - printk(KERN_ERR PFX "Error while reading the FSB\n"); - return -EINVAL; - } - - /* First write? Then set actual value */ - pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp); - if (!temp) { - pll = nforce2_calc_pll(tfsb); - - if (pll < 0) - return -EINVAL; - - nforce2_write_pll(pll); - } - - /* Enable write access */ - temp = 0x01; - pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp); - - diff = tfsb - fsb; - - if (!diff) - return 0; - - while ((tfsb != fsb) && (tfsb <= max_fsb) && (tfsb >= min_fsb)) { - if (diff < 0) - tfsb++; - else - tfsb--; - - /* Calculate the PLL reg. value */ - pll = nforce2_calc_pll(tfsb); - if (pll == -1) - return -EINVAL; - - nforce2_write_pll(pll); -#ifdef NFORCE2_DELAY - mdelay(NFORCE2_DELAY); -#endif - } - - temp = 0x40; - pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp); - - return 0; -} - -/** - * nforce2_get - get the CPU frequency - * @cpu: CPU number - * - * Returns the CPU frequency - */ -static unsigned int nforce2_get(unsigned int cpu) -{ - if (cpu) - return 0; - return nforce2_fsb_read(0) * fid * 100; -} - -/** - * nforce2_target - set a new CPUFreq policy - * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) - * - * Sets a new CPUFreq policy. - */ -static int nforce2_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ -/* unsigned long flags; */ - struct cpufreq_freqs freqs; - unsigned int target_fsb; - - if ((target_freq > policy->max) || (target_freq < policy->min)) - return -EINVAL; - - target_fsb = target_freq / (fid * 100); - - freqs.old = nforce2_get(policy->cpu); - freqs.new = target_fsb * fid * 100; - freqs.cpu = 0; /* Only one CPU on nForce2 platforms */ - - if (freqs.old == freqs.new) - return 0; - - pr_debug("Old CPU frequency %d kHz, new %d kHz\n", - freqs.old, freqs.new); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* Disable IRQs */ - /* local_irq_save(flags); */ - - if (nforce2_set_fsb(target_fsb) < 0) - printk(KERN_ERR PFX "Changing FSB to %d failed\n", - target_fsb); - else - pr_debug("Changed FSB successfully to %d\n", - target_fsb); - - /* Enable IRQs */ - /* local_irq_restore(flags); */ - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return 0; -} - -/** - * nforce2_verify - verifies a new CPUFreq policy - * @policy: new policy - */ -static int nforce2_verify(struct cpufreq_policy *policy) -{ - unsigned int fsb_pol_max; - - fsb_pol_max = policy->max / (fid * 100); - - if (policy->min < (fsb_pol_max * fid * 100)) - policy->max = (fsb_pol_max + 1) * fid * 100; - - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - return 0; -} - -static int nforce2_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int fsb; - unsigned int rfid; - - /* capability check */ - if (policy->cpu != 0) - return -ENODEV; - - /* Get current FSB */ - fsb = nforce2_fsb_read(0); - - if (!fsb) - return -EIO; - - /* FIX: Get FID from CPU */ - if (!fid) { - if (!cpu_khz) { - printk(KERN_WARNING PFX - "cpu_khz not set, can't calculate multiplier!\n"); - return -ENODEV; - } - - fid = cpu_khz / (fsb * 100); - rfid = fid % 5; - - if (rfid) { - if (rfid > 2) - fid += 5 - rfid; - else - fid -= rfid; - } - } - - printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb, - fid / 10, fid % 10); - - /* Set maximum FSB to FSB at boot time */ - max_fsb = nforce2_fsb_read(1); - - if (!max_fsb) - return -EIO; - - if (!min_fsb) - min_fsb = max_fsb - NFORCE2_SAFE_DISTANCE; - - if (min_fsb < NFORCE2_MIN_FSB) - min_fsb = NFORCE2_MIN_FSB; - - /* cpuinfo and default policy values */ - policy->cpuinfo.min_freq = min_fsb * fid * 100; - policy->cpuinfo.max_freq = max_fsb * fid * 100; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - policy->cur = nforce2_get(policy->cpu); - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; - - return 0; -} - -static int nforce2_cpu_exit(struct cpufreq_policy *policy) -{ - return 0; -} - -static struct cpufreq_driver nforce2_driver = { - .name = "nforce2", - .verify = nforce2_verify, - .target = nforce2_target, - .get = nforce2_get, - .init = nforce2_cpu_init, - .exit = nforce2_cpu_exit, - .owner = THIS_MODULE, -}; - -#ifdef MODULE -static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, - {} -}; -MODULE_DEVICE_TABLE(pci, nforce2_ids); -#endif - -/** - * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic - * - * Detects nForce2 A2 and C1 stepping - * - */ -static int nforce2_detect_chipset(void) -{ - nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, - PCI_DEVICE_ID_NVIDIA_NFORCE2, - PCI_ANY_ID, PCI_ANY_ID, NULL); - - if (nforce2_dev == NULL) - return -ENODEV; - - printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n", - nforce2_dev->revision); - printk(KERN_INFO PFX - "FSB changing is maybe unstable and can lead to " - "crashes and data loss.\n"); - - return 0; -} - -/** - * nforce2_init - initializes the nForce2 CPUFreq driver - * - * Initializes the nForce2 FSB support. Returns -ENODEV on unsupported - * devices, -EINVAL on problems during initiatization, and zero on - * success. - */ -static int __init nforce2_init(void) -{ - /* TODO: do we need to detect the processor? */ - - /* detect chipset */ - if (nforce2_detect_chipset()) { - printk(KERN_INFO PFX "No nForce2 chipset.\n"); - return -ENODEV; - } - - return cpufreq_register_driver(&nforce2_driver); -} - -/** - * nforce2_exit - unregisters cpufreq module - * - * Unregisters nForce2 FSB change support. - */ -static void __exit nforce2_exit(void) -{ - cpufreq_unregister_driver(&nforce2_driver); -} - -module_init(nforce2_init); -module_exit(nforce2_exit); - diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq.c b/linux-3.4/drivers/cpufreq.new/cpufreq.c deleted file mode 100755 index 87c3fec4..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq.c +++ /dev/null @@ -1,2188 +0,0 @@ -/* - * linux/drivers/cpufreq/cpufreq.c - * - * Copyright (C) 2001 Russell King - * (C) 2002 - 2003 Dominik Brodowski - * - * Oct 2005 - Ashok Raj - * Added handling for CPU hotplug - * Feb 2006 - Jacob Shin - * Fix handling for CPU hotplug -- affected CPUs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/** - * The "cpufreq driver" - the arch- or hardware-dependent low - * level driver of CPUFreq support, and its spinlock. This lock - * also protects the cpufreq_cpu_data array. - */ -static struct cpufreq_driver *cpufreq_driver; -static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); -#ifdef CONFIG_HOTPLUG_CPU -/* This one keeps track of the previously set governor of a removed CPU */ -static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); -#endif -static DEFINE_RWLOCK(cpufreq_driver_lock); -static DEFINE_MUTEX(cpufreq_governor_lock); - -/* - * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure - * all cpufreq/hotplug/workqueue/etc related lock issues. - * - * The rules for this semaphore: - * - Any routine that wants to read from the policy structure will - * do a down_read on this semaphore. - * - Any routine that will write to the policy structure and/or may take away - * the policy altogether (eg. CPU hotplug), will hold this lock in write - * mode before doing so. - * - * Additional rules: - * - Governor routines that can be called in cpufreq hotplug path should not - * take this sem as top level hotplug notifier handler takes this. - * - Lock should not be held across - * __cpufreq_governor(data, CPUFREQ_GOV_STOP); - */ -static DEFINE_PER_CPU(int, cpufreq_policy_cpu); -static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); - -#define lock_policy_rwsem(mode, cpu) \ -static int lock_policy_rwsem_##mode(int cpu) \ -{ \ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ - BUG_ON(policy_cpu == -1); \ - down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ - \ - return 0; \ -} - -lock_policy_rwsem(read, cpu); -lock_policy_rwsem(write, cpu); - -#define unlock_policy_rwsem(mode, cpu) \ -static void unlock_policy_rwsem_##mode(int cpu) \ -{ \ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ - BUG_ON(policy_cpu == -1); \ - up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ -} - -unlock_policy_rwsem(read, cpu); -unlock_policy_rwsem(write, cpu); - -/* internal prototypes */ -static int __cpufreq_governor(struct cpufreq_policy *policy, - unsigned int event); -static unsigned int __cpufreq_get(unsigned int cpu); -static void handle_update(struct work_struct *work); - -/** - * Two notifier lists: the "policy" list is involved in the - * validation process for a new CPU frequency policy; the - * "transition" list for kernel code that needs to handle - * changes to devices when the CPU clock speed changes. - * The mutex locks both lists. - */ -static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); -static struct srcu_notifier_head cpufreq_transition_notifier_list; - -static bool init_cpufreq_transition_notifier_list_called; -static int __init init_cpufreq_transition_notifier_list(void) -{ - srcu_init_notifier_head(&cpufreq_transition_notifier_list); - init_cpufreq_transition_notifier_list_called = true; - return 0; -} -pure_initcall(init_cpufreq_transition_notifier_list); - -static int off __read_mostly; -static int cpufreq_disabled(void) -{ - return off; -} -void disable_cpufreq(void) -{ - off = 1; -} -static LIST_HEAD(cpufreq_governor_list); -static DEFINE_MUTEX(cpufreq_governor_mutex); - -bool have_governor_per_policy(void) -{ - return cpufreq_driver->have_governor_per_policy; -} -EXPORT_SYMBOL_GPL(have_governor_per_policy); - -struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy) -{ - if (have_governor_per_policy()) - return &policy->kobj; - else - return cpufreq_global_kobject; -} -EXPORT_SYMBOL_GPL(get_governor_parent_kobj); - -static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) -{ - u64 idle_time; - u64 cur_wall_time; - u64 busy_time; - - cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); - - busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; - - idle_time = cur_wall_time - busy_time; - if (wall) - *wall = cputime_to_usecs(cur_wall_time); - - return cputime_to_usecs(idle_time); -} - -u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) -{ - u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL); - - if (idle_time == -1ULL) - return get_cpu_idle_time_jiffy(cpu, wall); - else if (!io_busy) - idle_time += get_cpu_iowait_time_us(cpu, wall); - - return idle_time; -} -EXPORT_SYMBOL_GPL(get_cpu_idle_time); - -static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) -{ - struct cpufreq_policy *data; - unsigned long flags; - - if (cpu >= nr_cpu_ids) - goto err_out; - - /* get the cpufreq driver */ - read_lock_irqsave(&cpufreq_driver_lock, flags); - - if (!cpufreq_driver) - goto err_out_unlock; - - if (!try_module_get(cpufreq_driver->owner)) - goto err_out_unlock; - - - /* get the CPU */ - data = per_cpu(cpufreq_cpu_data, cpu); - - if (!data) - goto err_out_put_module; - - if (!sysfs && !kobject_get(&data->kobj)) - goto err_out_put_module; - - read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return data; - -err_out_put_module: - module_put(cpufreq_driver->owner); -err_out_unlock: - read_unlock_irqrestore(&cpufreq_driver_lock, flags); -err_out: - return NULL; -} - -struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) -{ - if (cpufreq_disabled()) - return NULL; - - return __cpufreq_cpu_get(cpu, false); -} -EXPORT_SYMBOL_GPL(cpufreq_cpu_get); - -static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu) -{ - return __cpufreq_cpu_get(cpu, true); -} - -static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs) -{ - if (!sysfs) - kobject_put(&data->kobj); - module_put(cpufreq_driver->owner); -} - -void cpufreq_cpu_put(struct cpufreq_policy *data) -{ - if (cpufreq_disabled()) - return; - - __cpufreq_cpu_put(data, false); -} -EXPORT_SYMBOL_GPL(cpufreq_cpu_put); - -static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data) -{ - __cpufreq_cpu_put(data, true); -} - -/********************************************************************* - * EXTERNALLY AFFECTING FREQUENCY CHANGES * - *********************************************************************/ - -/** - * adjust_jiffies - adjust the system "loops_per_jiffy" - * - * This function alters the system "loops_per_jiffy" for the clock - * speed change. Note that loops_per_jiffy cannot be updated on SMP - * systems as each CPU might be scaled differently. So, use the arch - * per-CPU loops_per_jiffy value wherever possible. - */ -#ifndef CONFIG_SMP -static unsigned long l_p_j_ref; -static unsigned int l_p_j_ref_freq; - -static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) -{ - if (ci->flags & CPUFREQ_CONST_LOOPS) - return; - - if (!l_p_j_ref_freq) { - l_p_j_ref = loops_per_jiffy; - l_p_j_ref_freq = ci->old; - pr_debug("saving %lu as reference value for loops_per_jiffy; " - "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); - } - if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) || - (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { - loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, - ci->new); - pr_debug("scaling loops_per_jiffy to %lu " - "for frequency %u kHz\n", loops_per_jiffy, ci->new); - } -} -#else -static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) -{ - return; -} -#endif - - -void __cpufreq_notify_transition(struct cpufreq_policy *policy, - struct cpufreq_freqs *freqs, unsigned int state) -{ - BUG_ON(irqs_disabled()); - - if (cpufreq_disabled()) - return; - - freqs->flags = cpufreq_driver->flags; - pr_debug("notification %u of frequency transition to %u kHz\n", - state, freqs->new); - - switch (state) { - - case CPUFREQ_PRECHANGE: - /* detect if the driver reported a value as "old frequency" - * which is not equal to what the cpufreq core thinks is - * "old frequency". - */ - if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { - if ((policy) && (policy->cpu == freqs->cpu) && - (policy->cur) && (policy->cur != freqs->old)) { - pr_debug("Warning: CPU frequency is" - " %u, cpufreq assumed %u kHz.\n", - freqs->old, policy->cur); - freqs->old = policy->cur; - } - } - srcu_notifier_call_chain(&cpufreq_transition_notifier_list, - CPUFREQ_PRECHANGE, freqs); - adjust_jiffies(CPUFREQ_PRECHANGE, freqs); - break; - - case CPUFREQ_POSTCHANGE: - adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); - pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, - (unsigned long)freqs->cpu); - trace_cpu_frequency(freqs->new, freqs->cpu); - srcu_notifier_call_chain(&cpufreq_transition_notifier_list, - CPUFREQ_POSTCHANGE, freqs); - if (likely(policy) && likely(policy->cpu == freqs->cpu)) - policy->cur = freqs->new; - break; - } -} -/** - * cpufreq_notify_transition - call notifier chain and adjust_jiffies - * on frequency transition. - * - * This function calls the transition notifiers and the "adjust_jiffies" - * function. It is called twice on all CPU frequency changes that have - * external effects. - */ -void cpufreq_notify_transition(struct cpufreq_policy *policy, - struct cpufreq_freqs *freqs, unsigned int state) -{ - for_each_cpu(freqs->cpu, policy->cpus) - __cpufreq_notify_transition(policy, freqs, state); -} -EXPORT_SYMBOL_GPL(cpufreq_notify_transition); - - - -/********************************************************************* - * SYSFS INTERFACE * - *********************************************************************/ - -static struct cpufreq_governor *__find_governor(const char *str_governor) -{ - struct cpufreq_governor *t; - - list_for_each_entry(t, &cpufreq_governor_list, governor_list) - if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN)) - return t; - - return NULL; -} - -/** - * cpufreq_parse_governor - parse a governor string - */ -static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, - struct cpufreq_governor **governor) -{ - int err = -EINVAL; - - if (!cpufreq_driver) - goto out; - - if (cpufreq_driver->setpolicy) { - if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_PERFORMANCE; - err = 0; - } else if (!strnicmp(str_governor, "powersave", - CPUFREQ_NAME_LEN)) { - *policy = CPUFREQ_POLICY_POWERSAVE; - err = 0; - } - } else if (cpufreq_driver->target) { - struct cpufreq_governor *t; - - mutex_lock(&cpufreq_governor_mutex); - - t = __find_governor(str_governor); - - if (t == NULL) { - int ret; - - mutex_unlock(&cpufreq_governor_mutex); - ret = request_module("cpufreq_%s", str_governor); - mutex_lock(&cpufreq_governor_mutex); - - if (ret == 0) - t = __find_governor(str_governor); - } - - if (t != NULL) { - *governor = t; - err = 0; - } - - mutex_unlock(&cpufreq_governor_mutex); - } -out: - return err; -} - - -/** - * cpufreq_per_cpu_attr_read() / show_##file_name() - - * print out cpufreq information - * - * Write out information from cpufreq_driver->policy[cpu]; object must be - * "unsigned int". - */ - -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - return sprintf(buf, "%u\n", policy->object); \ -} - -show_one(cpuinfo_min_freq, cpuinfo.min_freq); -show_one(cpuinfo_max_freq, cpuinfo.max_freq); -show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); -show_one(scaling_min_freq, min); -show_one(scaling_max_freq, max); -show_one(scaling_cur_freq, cur); - -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy); - -/** - * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access - */ -#define store_one(file_name, object) \ -static ssize_t store_##file_name \ -(struct cpufreq_policy *policy, const char *buf, size_t count) \ -{ \ - unsigned int ret; \ - struct cpufreq_policy new_policy; \ - \ - ret = cpufreq_get_policy(&new_policy, policy->cpu); \ - if (ret) \ - return -EINVAL; \ - \ - ret = sscanf(buf, "%u", &new_policy.object); \ - if (ret != 1) \ - return -EINVAL; \ - \ - ret = __cpufreq_set_policy(policy, &new_policy); \ - policy->user_policy.object = policy->object; \ - \ - return ret ? ret : count; \ -} - -store_one(scaling_min_freq, min); -store_one(scaling_max_freq, max); - -/** - * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware - */ -static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, - char *buf) -{ - unsigned int cur_freq = __cpufreq_get(policy->cpu); - if (!cur_freq) - return sprintf(buf, ""); - return sprintf(buf, "%u\n", cur_freq); -} - - -/** - * show_scaling_governor - show the current policy for the specified CPU - */ -static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) -{ - if (policy->policy == CPUFREQ_POLICY_POWERSAVE) - return sprintf(buf, "powersave\n"); - else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) - return sprintf(buf, "performance\n"); - else if (policy->governor) - return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", - policy->governor->name); - return -EINVAL; -} - - -/** - * store_scaling_governor - store policy for the specified CPU - */ -static ssize_t store_scaling_governor(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - unsigned int ret; - char str_governor[16]; - struct cpufreq_policy new_policy; - - ret = cpufreq_get_policy(&new_policy, policy->cpu); - if (ret) - return ret; - - ret = sscanf(buf, "%15s", str_governor); - if (ret != 1) - return -EINVAL; - - if (cpufreq_parse_governor(str_governor, &new_policy.policy, - &new_policy.governor)) - return -EINVAL; - - /* Do not use cpufreq_set_policy here or the user_policy.max - will be wrongly overridden */ - ret = __cpufreq_set_policy(policy, &new_policy); - - policy->user_policy.policy = policy->policy; - policy->user_policy.governor = policy->governor; - - if (ret) - return ret; - else - return count; -} - -/** - * show_scaling_driver - show the cpufreq driver currently loaded - */ -static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) -{ - return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name); -} - -/** - * show_scaling_available_governors - show the available CPUfreq governors - */ -static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, - char *buf) -{ - ssize_t i = 0; - struct cpufreq_governor *t; - - if (!cpufreq_driver->target) { - i += sprintf(buf, "performance powersave"); - goto out; - } - - list_for_each_entry(t, &cpufreq_governor_list, governor_list) { - if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - - (CPUFREQ_NAME_LEN + 2))) - goto out; - i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name); - } -out: - i += sprintf(&buf[i], "\n"); - return i; -} - -static ssize_t show_cpus(const struct cpumask *mask, char *buf) -{ - ssize_t i = 0; - unsigned int cpu; - - for_each_cpu(cpu, mask) { - if (i) - i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); - i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); - if (i >= (PAGE_SIZE - 5)) - break; - } - i += sprintf(&buf[i], "\n"); - return i; -} - -/** - * show_related_cpus - show the CPUs affected by each transition even if - * hw coordination is in use - */ -static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) -{ - return show_cpus(policy->related_cpus, buf); -} - -/** - * show_affected_cpus - show the CPUs affected by each transition - */ -static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) -{ - return show_cpus(policy->cpus, buf); -} - -#if defined(CONFIG_ARM_SUNXI_CPUFREQ) || (CONFIG_ARM_SUNXI_IKS_CPUFREQ) -extern int sunxi_dvfs_debug; -extern int sunxi_boot_freq_lock; - -static ssize_t show_dvfs_debug(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%d\n", sunxi_dvfs_debug); -} - -static ssize_t store_dvfs_debug(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - char value; - if(strlen(buf) != 2) - return -EINVAL; - if(buf[0] < '0' || buf[0] > '1') - return -EINVAL; - value = buf[0]; - switch(value) - { - case '1': - sunxi_dvfs_debug = 1; - break; - case '0': - sunxi_dvfs_debug = 0; - break; - default: - return -EINVAL; - } - return count; -} - -static ssize_t show_cpuinfo_boot_freq(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%u\n", policy->cpuinfo.boot_freq); -} -static ssize_t show_boot_lock(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%d\n", sunxi_boot_freq_lock); -} - -static ssize_t store_boot_lock(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - char value; - if(strlen(buf) != 2) - return -EINVAL; - if(buf[0] < '0' || buf[0] > '1') - return -EINVAL; - value = buf[0]; - switch(value) - { - case '1': - sunxi_boot_freq_lock = 1; - break; - case '0': - sunxi_boot_freq_lock = 0; - break; - default: - return -EINVAL; - } - return count; -} -#endif - -static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - unsigned int freq = 0; - unsigned int ret; - - if (!policy->governor || !policy->governor->store_setspeed) - return -EINVAL; - - ret = sscanf(buf, "%u", &freq); - if (ret != 1) - return -EINVAL; - - policy->governor->store_setspeed(policy, freq); - - return count; -} - -static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) -{ - if (!policy->governor || !policy->governor->show_setspeed) - return sprintf(buf, "\n"); - - return policy->governor->show_setspeed(policy, buf); -} - -/** - * show_bios_limit - show the current cpufreq HW/BIOS limitation - */ -static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) -{ - unsigned int limit; - int ret; - if (cpufreq_driver->bios_limit) { - ret = cpufreq_driver->bios_limit(policy->cpu, &limit); - if (!ret) - return sprintf(buf, "%u\n", limit); - } - return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); -} - -cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400); -cpufreq_freq_attr_ro(cpuinfo_min_freq); -cpufreq_freq_attr_ro(cpuinfo_max_freq); -cpufreq_freq_attr_ro(cpuinfo_transition_latency); -cpufreq_freq_attr_ro(scaling_available_governors); -cpufreq_freq_attr_ro(scaling_driver); -cpufreq_freq_attr_ro(scaling_cur_freq); -cpufreq_freq_attr_ro(bios_limit); -cpufreq_freq_attr_ro(related_cpus); -cpufreq_freq_attr_ro(affected_cpus); -cpufreq_freq_attr_rw(scaling_min_freq); -cpufreq_freq_attr_rw(scaling_max_freq); -cpufreq_freq_attr_rw(scaling_governor); -cpufreq_freq_attr_rw(scaling_setspeed); -#if defined(CONFIG_ARM_SUNXI_CPUFREQ) || (CONFIG_ARM_SUNXI_IKS_CPUFREQ) -cpufreq_freq_attr_rw(dvfs_debug); -cpufreq_freq_attr_ro(cpuinfo_boot_freq); -cpufreq_freq_attr_rw(boot_lock); -#endif - -static struct attribute *default_attrs[] = { - &cpuinfo_min_freq.attr, - &cpuinfo_max_freq.attr, - &cpuinfo_transition_latency.attr, - &scaling_min_freq.attr, - &scaling_max_freq.attr, - &affected_cpus.attr, - &related_cpus.attr, - &scaling_governor.attr, - &scaling_driver.attr, - &scaling_available_governors.attr, - &scaling_setspeed.attr, -#if defined(CONFIG_ARM_SUNXI_CPUFREQ) || (CONFIG_ARM_SUNXI_IKS_CPUFREQ) - &dvfs_debug.attr, - &cpuinfo_boot_freq.attr, - &boot_lock.attr, -#endif - NULL -}; - -struct kobject *cpufreq_global_kobject; -EXPORT_SYMBOL(cpufreq_global_kobject); - -#define to_policy(k) container_of(k, struct cpufreq_policy, kobj) -#define to_attr(a) container_of(a, struct freq_attr, attr) - -static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct cpufreq_policy *policy = to_policy(kobj); - struct freq_attr *fattr = to_attr(attr); - ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); - if (!policy) - goto no_policy; - - if (lock_policy_rwsem_read(policy->cpu) < 0) - goto fail; - - if (fattr->show) - ret = fattr->show(policy, buf); - else - ret = -EIO; - - unlock_policy_rwsem_read(policy->cpu); -fail: - cpufreq_cpu_put_sysfs(policy); -no_policy: - return ret; -} - -static ssize_t store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct cpufreq_policy *policy = to_policy(kobj); - struct freq_attr *fattr = to_attr(attr); - ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); - if (!policy) - goto no_policy; - - if (lock_policy_rwsem_write(policy->cpu) < 0) - goto fail; - - if (fattr->store) - ret = fattr->store(policy, buf, count); - else - ret = -EIO; - - unlock_policy_rwsem_write(policy->cpu); -fail: - cpufreq_cpu_put_sysfs(policy); -no_policy: - return ret; -} - -static void cpufreq_sysfs_release(struct kobject *kobj) -{ - struct cpufreq_policy *policy = to_policy(kobj); - pr_debug("last reference is dropped\n"); - complete(&policy->kobj_unregister); -} - -static const struct sysfs_ops sysfs_ops = { - .show = show, - .store = store, -}; - -static struct kobj_type ktype_cpufreq = { - .sysfs_ops = &sysfs_ops, - .default_attrs = default_attrs, - .release = cpufreq_sysfs_release, -}; - -/* symlink affected CPUs */ -static int cpufreq_add_dev_symlink(unsigned int cpu, - struct cpufreq_policy *policy) -{ - unsigned int j; - int ret = 0; - - for_each_cpu(j, policy->cpus) { - struct cpufreq_policy *managed_policy; - struct device *cpu_dev; - - if (j == cpu) - continue; - - pr_debug("CPU %u already managed, adding link\n", j); - managed_policy = cpufreq_cpu_get(cpu); - cpu_dev = get_cpu_device(j); - ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, - "cpufreq"); - if (ret) { - cpufreq_cpu_put(managed_policy); - return ret; - } - } - return ret; -} - -static int cpufreq_add_dev_interface(unsigned int cpu, - struct cpufreq_policy *policy, - struct device *dev) -{ - struct cpufreq_policy new_policy; - struct freq_attr **drv_attr; - unsigned long flags; - int ret = 0; - unsigned int j; - - /* prepare interface data */ - ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, - &dev->kobj, "cpufreq"); - if (ret) - return ret; - - /* set up files for this cpu device */ - drv_attr = cpufreq_driver->attr; - while ((drv_attr) && (*drv_attr)) { - ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); - if (ret) - goto err_out_kobj_put; - drv_attr++; - } - if (cpufreq_driver->get) { - ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); - if (ret) - goto err_out_kobj_put; - } - if (cpufreq_driver->target) { - ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); - if (ret) - goto err_out_kobj_put; - } - if (cpufreq_driver->bios_limit) { - ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); - if (ret) - goto err_out_kobj_put; - } - - write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) { - per_cpu(cpufreq_cpu_data, j) = policy; - per_cpu(cpufreq_policy_cpu, j) = policy->cpu; - } - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - ret = cpufreq_add_dev_symlink(cpu, policy); - if (ret) - goto err_out_kobj_put; - - memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); - /* assure that the starting sequence is run in __cpufreq_set_policy */ - policy->governor = NULL; - - /* set default policy */ - ret = __cpufreq_set_policy(policy, &new_policy); - policy->user_policy.policy = policy->policy; - policy->user_policy.governor = policy->governor; - - if (ret) { - pr_debug("setting policy failed\n"); - if (cpufreq_driver->exit) - cpufreq_driver->exit(policy); - } - return ret; - -err_out_kobj_put: - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - return ret; -} - -#ifdef CONFIG_HOTPLUG_CPU -static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, - struct device *dev) -{ - struct cpufreq_policy *policy; - int ret = 0, has_target = !!cpufreq_driver->target; - unsigned long flags; - - policy = cpufreq_cpu_get(sibling); - WARN_ON(!policy); - - if (has_target) - __cpufreq_governor(policy, CPUFREQ_GOV_STOP); - - lock_policy_rwsem_write(sibling); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - - cpumask_set_cpu(cpu, policy->cpus); - per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu; - per_cpu(cpufreq_cpu_data, cpu) = policy; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - unlock_policy_rwsem_write(sibling); - - if (has_target) { - __cpufreq_governor(policy, CPUFREQ_GOV_START); - __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); - } - - ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); - if (ret) { - cpufreq_cpu_put(policy); - return ret; - } - - return 0; -} -#endif - -/** - * cpufreq_add_dev - add a CPU device - * - * Adds the cpufreq interface for a CPU device. - * - * The Oracle says: try running cpufreq registration/unregistration concurrently - * with with cpu hotplugging and all hell will break loose. Tried to clean this - * mess up, but more thorough testing is needed. - Mathieu - */ -static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int j, cpu = dev->id; - int ret = -ENOMEM; - struct cpufreq_policy *policy; - unsigned long flags; -#ifdef CONFIG_HOTPLUG_CPU - struct cpufreq_governor *gov; - int sibling; -#endif - - if (cpu_is_offline(cpu)) - return 0; - - pr_debug("adding CPU %u\n", cpu); - -#ifdef CONFIG_SMP - /* check whether a different CPU already registered this - * CPU because it is in the same boat. */ - policy = cpufreq_cpu_get(cpu); - if (unlikely(policy)) { - cpufreq_cpu_put(policy); - return 0; - } - -#ifdef CONFIG_HOTPLUG_CPU - /* Check if this cpu was hot-unplugged earlier and has siblings */ - read_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_online_cpu(sibling) { - struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); - if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { - read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return cpufreq_add_policy_cpu(cpu, sibling, dev); - } - } - read_unlock_irqrestore(&cpufreq_driver_lock, flags); -#endif -#endif - - if (!try_module_get(cpufreq_driver->owner)) { - ret = -EINVAL; - goto module_out; - } - - policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); - if (!policy) - goto nomem_out; - - if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) - goto err_free_policy; - - if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) - goto err_free_cpumask; - - policy->cpu = cpu; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - cpumask_copy(policy->cpus, cpumask_of(cpu)); - - /* Initially set CPU itself as the policy_cpu */ - per_cpu(cpufreq_policy_cpu, cpu) = cpu; - - init_completion(&policy->kobj_unregister); - INIT_WORK(&policy->update, handle_update); - - /* call driver. From then on the cpufreq must be able - * to accept all calls to ->verify and ->setpolicy for this CPU - */ - ret = cpufreq_driver->init(policy); - if (ret) { - pr_debug("initialization failed\n"); - goto err_set_policy_cpu; - } - - /* related cpus should atleast have policy->cpus */ - cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); - - /* - * affected cpus must always be the one, which are online. We aren't - * managing offline cpus here. - */ - cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); - - policy->user_policy.min = policy->min; - policy->user_policy.max = policy->max; - - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_START, policy); - -#ifdef CONFIG_HOTPLUG_CPU - gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); - if (gov) { - policy->governor = gov; - pr_debug("Restoring governor %s for cpu %d\n", - policy->governor->name, cpu); - } -#endif - - ret = cpufreq_add_dev_interface(cpu, policy, dev); - if (ret) - goto err_out_unregister; - - kobject_uevent(&policy->kobj, KOBJ_ADD); - module_put(cpufreq_driver->owner); - pr_debug("initialization complete\n"); - - return 0; - -err_out_unregister: - write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) - per_cpu(cpufreq_cpu_data, j) = NULL; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - -err_set_policy_cpu: - per_cpu(cpufreq_policy_cpu, cpu) = -1; - free_cpumask_var(policy->related_cpus); -err_free_cpumask: - free_cpumask_var(policy->cpus); -err_free_policy: - kfree(policy); -nomem_out: - module_put(cpufreq_driver->owner); -module_out: - return ret; -} - -static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) -{ - int j; - - policy->last_cpu = policy->cpu; - policy->cpu = cpu; - - for_each_cpu(j, policy->cpus) - per_cpu(cpufreq_policy_cpu, j) = cpu; - -#ifdef CONFIG_CPU_FREQ_TABLE - cpufreq_frequency_table_update_policy_cpu(policy); -#endif - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_UPDATE_POLICY_CPU, policy); -} - -/** - * __cpufreq_remove_dev - remove a CPU device - * - * Removes the cpufreq interface for a CPU device. - * Caller should already have policy_rwsem in write mode for this CPU. - * This routine frees the rwsem before returning. - */ -static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int cpu = dev->id, ret, cpus; - unsigned long flags; - struct cpufreq_policy *data; - struct kobject *kobj; - struct completion *cmp; - struct device *cpu_dev; - - pr_debug("%s: unregistering CPU %u\n", __func__, cpu); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - - data = per_cpu(cpufreq_cpu_data, cpu); - per_cpu(cpufreq_cpu_data, cpu) = NULL; - - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - if (!data) { - pr_debug("%s: No cpu_data found\n", __func__); - return -EINVAL; - } - - if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_STOP); - -#ifdef CONFIG_HOTPLUG_CPU - if (!cpufreq_driver->setpolicy) - strncpy(per_cpu(cpufreq_cpu_governor, cpu), - data->governor->name, CPUFREQ_NAME_LEN); -#endif - - WARN_ON(lock_policy_rwsem_write(cpu)); - cpus = cpumask_weight(data->cpus); - - if (cpus > 1) - cpumask_clear_cpu(cpu, data->cpus); - unlock_policy_rwsem_write(cpu); - - if (cpu != data->cpu) { - sysfs_remove_link(&dev->kobj, "cpufreq"); - } else if (cpus > 1) { - /* first sibling now owns the new sysfs dir */ - cpu_dev = get_cpu_device(cpumask_first(data->cpus)); - sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); - ret = kobject_move(&data->kobj, &cpu_dev->kobj); - if (ret) { - pr_err("%s: Failed to move kobj: %d", __func__, ret); - - WARN_ON(lock_policy_rwsem_write(cpu)); - cpumask_set_cpu(cpu, data->cpus); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - per_cpu(cpufreq_cpu_data, cpu) = data; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - unlock_policy_rwsem_write(cpu); - - ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj, - "cpufreq"); - return -EINVAL; - } - - WARN_ON(lock_policy_rwsem_write(cpu)); - update_policy_cpu(data, cpu_dev->id); - unlock_policy_rwsem_write(cpu); - pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", - __func__, cpu_dev->id, cpu); - } - - /* If cpu is last user of policy, free policy */ - if (cpus == 1) { - if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); - - lock_policy_rwsem_read(cpu); - kobj = &data->kobj; - cmp = &data->kobj_unregister; - unlock_policy_rwsem_read(cpu); - kobject_put(kobj); - - /* we need to make sure that the underlying kobj is actually - * not referenced anymore by anybody before we proceed with - * unloading. - */ - pr_debug("waiting for dropping of refcount\n"); - wait_for_completion(cmp); - pr_debug("wait complete\n"); - - if (cpufreq_driver->exit) - cpufreq_driver->exit(data); - - free_cpumask_var(data->related_cpus); - free_cpumask_var(data->cpus); - kfree(data); - } else { - pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); - cpufreq_cpu_put(data); - if (cpufreq_driver->target) { - __cpufreq_governor(data, CPUFREQ_GOV_START); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); - } - } - - per_cpu(cpufreq_policy_cpu, cpu) = -1; - return 0; -} - - -static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) -{ - unsigned int cpu = dev->id; - int retval; - - if (cpu_is_offline(cpu)) - return 0; - - retval = __cpufreq_remove_dev(dev, sif); - return retval; -} - - -static void handle_update(struct work_struct *work) -{ - struct cpufreq_policy *policy = - container_of(work, struct cpufreq_policy, update); - unsigned int cpu = policy->cpu; - pr_debug("handle_update for cpu %u called\n", cpu); - cpufreq_update_policy(cpu); -} - -/** - * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble. - * @cpu: cpu number - * @old_freq: CPU frequency the kernel thinks the CPU runs at - * @new_freq: CPU frequency the CPU actually runs at - * - * We adjust to current frequency first, and need to clean up later. - * So either call to cpufreq_update_policy() or schedule handle_update()). - */ -static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, - unsigned int new_freq) -{ - struct cpufreq_policy *policy; - struct cpufreq_freqs freqs; - unsigned long flags; - - - pr_debug("Warning: CPU frequency out of sync: cpufreq and timing " - "core thinks of %u, is %u kHz.\n", old_freq, new_freq); - - freqs.old = old_freq; - freqs.new = new_freq; - - read_lock_irqsave(&cpufreq_driver_lock, flags); - policy = per_cpu(cpufreq_cpu_data, cpu); - read_unlock_irqrestore(&cpufreq_driver_lock, flags); - - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -} - - -/** - * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur - * @cpu: CPU number - * - * This is the last known freq, without actually getting it from the driver. - * Return value will be same as what is shown in scaling_cur_freq in sysfs. - */ -unsigned int cpufreq_quick_get(unsigned int cpu) -{ - struct cpufreq_policy *policy; - unsigned int ret_freq = 0; - - if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) - return cpufreq_driver->get(cpu); - - policy = cpufreq_cpu_get(cpu); - if (policy) { - ret_freq = policy->cur; - cpufreq_cpu_put(policy); - } - - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_quick_get); - -/** - * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU - * @cpu: CPU number - * - * Just return the max possible frequency for a given CPU. - */ -unsigned int cpufreq_quick_get_max(unsigned int cpu) -{ - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - unsigned int ret_freq = 0; - - if (policy) { - ret_freq = policy->max; - cpufreq_cpu_put(policy); - } - - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_quick_get_max); - - -static unsigned int __cpufreq_get(unsigned int cpu) -{ - struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); - unsigned int ret_freq = 0; - - if (!cpufreq_driver->get) - return ret_freq; - - ret_freq = cpufreq_driver->get(cpu); - - if (ret_freq && policy->cur && - !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { - /* verify no discrepancy between actual and - saved value exists */ - if (unlikely(ret_freq != policy->cur)) { - cpufreq_out_of_sync(cpu, policy->cur, ret_freq); - schedule_work(&policy->update); - } - } - - return ret_freq; -} - -/** - * cpufreq_get - get the current CPU frequency (in kHz) - * @cpu: CPU number - * - * Get the CPU current (static) CPU frequency - */ -unsigned int cpufreq_get(unsigned int cpu) -{ - unsigned int ret_freq = 0; - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - - if (!policy) - goto out; - - if (unlikely(lock_policy_rwsem_read(cpu))) - goto out_policy; - - ret_freq = __cpufreq_get(cpu); - - unlock_policy_rwsem_read(cpu); - -out_policy: - cpufreq_cpu_put(policy); -out: - return ret_freq; -} -EXPORT_SYMBOL(cpufreq_get); - -static struct subsys_interface cpufreq_interface = { - .name = "cpufreq", - .subsys = &cpu_subsys, - .add_dev = cpufreq_add_dev, - .remove_dev = cpufreq_remove_dev, -}; - - -/** - * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. - * - * This function is only executed for the boot processor. The other CPUs - * have been put offline by means of CPU hotplug. - */ -static int cpufreq_bp_suspend(void) -{ - int ret = 0; - - int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; - - pr_debug("suspending cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return 0; - - if (cpufreq_driver->suspend) { - ret = cpufreq_driver->suspend(cpu_policy); - if (ret) - printk(KERN_ERR "cpufreq: suspend failed in ->suspend " - "step on CPU %u\n", cpu_policy->cpu); - } - - cpufreq_cpu_put(cpu_policy); - return ret; -} - -/** - * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. - * - * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) - * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are - * restored. It will verify that the current freq is in sync with - * what we believe it to be. This is a bit later than when it - * should be, but nonethteless it's better than calling - * cpufreq_driver->get() here which might re-enable interrupts... - * - * This function is only executed for the boot CPU. The other CPUs have not - * been turned on yet. - */ -static void cpufreq_bp_resume(void) -{ - int ret = 0; - - int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; - - pr_debug("resuming cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return; - - if (cpufreq_driver->resume) { - ret = cpufreq_driver->resume(cpu_policy); - if (ret) { - printk(KERN_ERR "cpufreq: resume failed in ->resume " - "step on CPU %u\n", cpu_policy->cpu); - goto fail; - } - } - - schedule_work(&cpu_policy->update); - -fail: - cpufreq_cpu_put(cpu_policy); -} - -static struct syscore_ops cpufreq_syscore_ops = { - .suspend = cpufreq_bp_suspend, - .resume = cpufreq_bp_resume, -}; - -/** - * cpufreq_get_current_driver - return current driver's name - * - * Return the name string of the currently loaded cpufreq driver - * or NULL, if none. - */ -const char *cpufreq_get_current_driver(void) -{ - if (cpufreq_driver) - return cpufreq_driver->name; - - return NULL; -} -EXPORT_SYMBOL_GPL(cpufreq_get_current_driver); - -/********************************************************************* - * NOTIFIER LISTS INTERFACE * - *********************************************************************/ - -/** - * cpufreq_register_notifier - register a driver with cpufreq - * @nb: notifier function to register - * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER - * - * Add a driver to one of two lists: either a list of drivers that - * are notified about clock rate changes (once before and once after - * the transition), or a list of drivers that are notified about - * changes in cpufreq policy. - * - * This function may sleep, and has the same return conditions as - * blocking_notifier_chain_register. - */ -int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) -{ - int ret; - - if (cpufreq_disabled()) - return -EINVAL; - - WARN_ON(!init_cpufreq_transition_notifier_list_called); - - switch (list) { - case CPUFREQ_TRANSITION_NOTIFIER: - ret = srcu_notifier_chain_register( - &cpufreq_transition_notifier_list, nb); - break; - case CPUFREQ_POLICY_NOTIFIER: - ret = blocking_notifier_chain_register( - &cpufreq_policy_notifier_list, nb); - break; - default: - ret = -EINVAL; - } - - return ret; -} -EXPORT_SYMBOL(cpufreq_register_notifier); - - -/** - * cpufreq_unregister_notifier - unregister a driver with cpufreq - * @nb: notifier block to be unregistered - * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER - * - * Remove a driver from the CPU frequency notifier list. - * - * This function may sleep, and has the same return conditions as - * blocking_notifier_chain_unregister. - */ -int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) -{ - int ret; - - if (cpufreq_disabled()) - return -EINVAL; - - switch (list) { - case CPUFREQ_TRANSITION_NOTIFIER: - ret = srcu_notifier_chain_unregister( - &cpufreq_transition_notifier_list, nb); - break; - case CPUFREQ_POLICY_NOTIFIER: - ret = blocking_notifier_chain_unregister( - &cpufreq_policy_notifier_list, nb); - break; - default: - ret = -EINVAL; - } - - return ret; -} -EXPORT_SYMBOL(cpufreq_unregister_notifier); - - -/********************************************************************* - * GOVERNORS * - *********************************************************************/ - - -int __cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int retval = -EINVAL; - unsigned int old_target_freq = target_freq; - - if (cpufreq_disabled()) - return -ENODEV; - - /* Make sure that target_freq is within supported range */ - if (target_freq > policy->max) - target_freq = policy->max; - if (target_freq < policy->min) - target_freq = policy->min; - - pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", - policy->cpu, target_freq, relation, old_target_freq); - - if (target_freq == policy->cur) - return 0; - - if (cpufreq_driver->target) - retval = cpufreq_driver->target(policy, target_freq, relation); - - return retval; -} -EXPORT_SYMBOL_GPL(__cpufreq_driver_target); - -int cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int ret = -EINVAL; - - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - goto no_policy; - - if (unlikely(lock_policy_rwsem_write(policy->cpu))) - goto fail; - - ret = __cpufreq_driver_target(policy, target_freq, relation); - - unlock_policy_rwsem_write(policy->cpu); - -fail: - cpufreq_cpu_put(policy); -no_policy: - return ret; -} -EXPORT_SYMBOL_GPL(cpufreq_driver_target); - -int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) -{ - int ret = 0; - - if (cpufreq_disabled()) - return ret; - - if (!cpufreq_driver->getavg) - return 0; - - policy = cpufreq_cpu_get(policy->cpu); - if (!policy) - return -EINVAL; - - ret = cpufreq_driver->getavg(policy, cpu); - - cpufreq_cpu_put(policy); - return ret; -} -EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg); - -/* - * when "event" is CPUFREQ_GOV_LIMITS - */ - -static int __cpufreq_governor(struct cpufreq_policy *policy, - unsigned int event) -{ - int ret; - - /* Only must be defined when default governor is known to have latency - restrictions, like e.g. conservative or ondemand. - That this is the case is already ensured in Kconfig - */ -#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE - struct cpufreq_governor *gov = &cpufreq_gov_performance; -#else - struct cpufreq_governor *gov = NULL; -#endif - - if (policy->governor->max_transition_latency && - policy->cpuinfo.transition_latency > - policy->governor->max_transition_latency) { - if (!gov) - return -EINVAL; - else { - printk(KERN_WARNING "%s governor failed, too long" - " transition latency of HW, fallback" - " to %s governor\n", - policy->governor->name, - gov->name); - policy->governor = gov; - } - } - - if (!try_module_get(policy->governor->owner)) - return -EINVAL; - - pr_debug("__cpufreq_governor for CPU %u, event %u\n", - policy->cpu, event); - - mutex_lock(&cpufreq_governor_lock); - if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || - (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { - mutex_unlock(&cpufreq_governor_lock); - return -EBUSY; - } - - if (event == CPUFREQ_GOV_STOP) - policy->governor_enabled = false; - else if (event == CPUFREQ_GOV_START) - policy->governor_enabled = true; - - mutex_unlock(&cpufreq_governor_lock); - - ret = policy->governor->governor(policy, event); - - if (!ret) { - if (event == CPUFREQ_GOV_POLICY_INIT) - policy->governor->initialized++; - else if (event == CPUFREQ_GOV_POLICY_EXIT) - policy->governor->initialized--; - } else { - /* Restore original values */ - mutex_lock(&cpufreq_governor_lock); - if (event == CPUFREQ_GOV_STOP) - policy->governor_enabled = true; - else if (event == CPUFREQ_GOV_START) - policy->governor_enabled = false; - mutex_unlock(&cpufreq_governor_lock); - } - - /* we keep one module reference alive for - each CPU governed by this CPU */ - if ((event != CPUFREQ_GOV_START) || ret) - module_put(policy->governor->owner); - if ((event == CPUFREQ_GOV_STOP) && !ret) - module_put(policy->governor->owner); - - return ret; -} - - -int cpufreq_register_governor(struct cpufreq_governor *governor) -{ - int err; - - if (!governor) - return -EINVAL; - - if (cpufreq_disabled()) - return -ENODEV; - - mutex_lock(&cpufreq_governor_mutex); - - governor->initialized = 0; - err = -EBUSY; - if (__find_governor(governor->name) == NULL) { - err = 0; - list_add(&governor->governor_list, &cpufreq_governor_list); - } - - mutex_unlock(&cpufreq_governor_mutex); - return err; -} -EXPORT_SYMBOL_GPL(cpufreq_register_governor); - - -void cpufreq_unregister_governor(struct cpufreq_governor *governor) -{ -#ifdef CONFIG_HOTPLUG_CPU - int cpu; -#endif - - if (!governor) - return; - - if (cpufreq_disabled()) - return; - -#ifdef CONFIG_HOTPLUG_CPU - for_each_present_cpu(cpu) { - if (cpu_online(cpu)) - continue; - if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) - strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); - } -#endif - - mutex_lock(&cpufreq_governor_mutex); - list_del(&governor->governor_list); - mutex_unlock(&cpufreq_governor_mutex); - return; -} -EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); - - - -/********************************************************************* - * POLICY INTERFACE * - *********************************************************************/ - -/** - * cpufreq_get_policy - get the current cpufreq_policy - * @policy: struct cpufreq_policy into which the current cpufreq_policy - * is written - * - * Reads the current cpufreq policy. - */ -int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) -{ - struct cpufreq_policy *cpu_policy; - if (!policy) - return -EINVAL; - - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) - return -EINVAL; - - memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); - - cpufreq_cpu_put(cpu_policy); - return 0; -} -EXPORT_SYMBOL(cpufreq_get_policy); - - -/* - * data : current policy. - * policy : policy to be set. - */ -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy) -{ - int ret = 0, failed = 1; - - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, - policy->min, policy->max); - - memcpy(&policy->cpuinfo, &data->cpuinfo, - sizeof(struct cpufreq_cpuinfo)); - - if (policy->min > data->max || policy->max < data->min) { - ret = -EINVAL; - goto error_out; - } - - /* verify the cpu speed can be set within this limit */ - ret = cpufreq_driver->verify(policy); - if (ret) - goto error_out; - - /* adjust if necessary - all reasons */ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_ADJUST, policy); - - /* adjust if necessary - hardware incompatibility*/ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_INCOMPATIBLE, policy); - - /* verify the cpu speed can be set within this limit, - which might be different to the first one */ - ret = cpufreq_driver->verify(policy); - if (ret) - goto error_out; - - /* notification of the new policy */ - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_NOTIFY, policy); - - data->min = policy->min; - data->max = policy->max; - - pr_debug("new min and max freqs are %u - %u kHz\n", - data->min, data->max); - - if (cpufreq_driver->setpolicy) { - data->policy = policy->policy; - pr_debug("setting range\n"); - ret = cpufreq_driver->setpolicy(policy); - } else { - if (policy->governor != data->governor) { - /* save old, working values */ - struct cpufreq_governor *old_gov = data->governor; - - pr_debug("governor switch\n"); - - /* end old governor */ - if (data->governor) { - __cpufreq_governor(data, CPUFREQ_GOV_STOP); - unlock_policy_rwsem_write(policy->cpu); - __cpufreq_governor(data, - CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(policy->cpu); - } - - /* start new governor */ - data->governor = policy->governor; - if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { - if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) { - failed = 0; - } else { - unlock_policy_rwsem_write(policy->cpu); - __cpufreq_governor(data, - CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(policy->cpu); - } - } - - if (failed) { - /* new governor failed, so re-start old one */ - pr_debug("starting governor %s failed\n", - data->governor->name); - if (old_gov) { - data->governor = old_gov; - __cpufreq_governor(data, - CPUFREQ_GOV_POLICY_INIT); - __cpufreq_governor(data, - CPUFREQ_GOV_START); - } - ret = -EINVAL; - goto error_out; - } - /* might be a policy change, too, so fall through */ - } - pr_debug("governor: change or update limits\n"); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); - } - -error_out: - return ret; -} - -/** - * cpufreq_update_policy - re-evaluate an existing cpufreq policy - * @cpu: CPU which shall be re-evaluated - * - * Useful for policy notifiers which have different necessities - * at different times. - */ -int cpufreq_update_policy(unsigned int cpu) -{ - struct cpufreq_policy *data = cpufreq_cpu_get(cpu); - struct cpufreq_policy policy; - int ret; - - if (!data) { - ret = -ENODEV; - goto no_policy; - } - - if (unlikely(lock_policy_rwsem_write(cpu))) { - ret = -EINVAL; - goto fail; - } - - pr_debug("updating policy for CPU %u\n", cpu); - memcpy(&policy, data, sizeof(struct cpufreq_policy)); - policy.min = data->user_policy.min; - policy.max = data->user_policy.max; - policy.policy = data->user_policy.policy; - policy.governor = data->user_policy.governor; - - /* BIOS might change freq behind our back - -> ask driver for current freq and notify governors about a change */ - if (cpufreq_driver->get) { - policy.cur = cpufreq_driver->get(cpu); - if (!data->cur) { - pr_debug("Driver did not initialize current freq"); - data->cur = policy.cur; - } else { - if (data->cur != policy.cur && cpufreq_driver->target) - cpufreq_out_of_sync(cpu, data->cur, - policy.cur); - } - } - - ret = __cpufreq_set_policy(data, &policy); - - unlock_policy_rwsem_write(cpu); - -fail: - cpufreq_cpu_put(data); -no_policy: - return ret; -} -EXPORT_SYMBOL(cpufreq_update_policy); - -static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct device *dev; - - dev = get_cpu_device(cpu); - if (dev) { - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cpufreq_add_dev(dev, NULL); - break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - __cpufreq_remove_dev(dev, NULL); - break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_add_dev(dev, NULL); - break; - } - } - return NOTIFY_OK; -} - -static struct notifier_block __refdata cpufreq_cpu_notifier = { - .notifier_call = cpufreq_cpu_callback, -}; - -/********************************************************************* - * REGISTER / UNREGISTER CPUFREQ DRIVER * - *********************************************************************/ - -/** - * cpufreq_register_driver - register a CPU Frequency driver - * @driver_data: A struct cpufreq_driver containing the values# - * submitted by the CPU Frequency driver. - * - * Registers a CPU Frequency driver to this core code. This code - * returns zero on success, -EBUSY when another driver got here first - * (and isn't unregistered in the meantime). - * - */ -int cpufreq_register_driver(struct cpufreq_driver *driver_data) -{ - unsigned long flags; - int ret; - - if (cpufreq_disabled()) - return -ENODEV; - - if (!driver_data || !driver_data->verify || !driver_data->init || - ((!driver_data->setpolicy) && (!driver_data->target))) - return -EINVAL; - - pr_debug("trying to register driver %s\n", driver_data->name); - - if (driver_data->setpolicy) - driver_data->flags |= CPUFREQ_CONST_LOOPS; - - write_lock_irqsave(&cpufreq_driver_lock, flags); - if (cpufreq_driver) { - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - return -EBUSY; - } - cpufreq_driver = driver_data; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - ret = subsys_interface_register(&cpufreq_interface); - if (ret) - goto err_null_driver; - - if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { - int i; - ret = -ENODEV; - - /* check for at least one working CPU */ - for (i = 0; i < nr_cpu_ids; i++) - if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { - ret = 0; - break; - } - - /* if all ->init() calls failed, unregister */ - if (ret) { - pr_debug("no CPU initialized for driver %s\n", - driver_data->name); - goto err_if_unreg; - } - } - - register_hotcpu_notifier(&cpufreq_cpu_notifier); - pr_debug("driver %s up and running\n", driver_data->name); - - return 0; -err_if_unreg: - subsys_interface_unregister(&cpufreq_interface); -err_null_driver: - write_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(cpufreq_register_driver); - - -/** - * cpufreq_unregister_driver - unregister the current CPUFreq driver - * - * Unregister the current CPUFreq driver. Only call this if you have - * the right to do so, i.e. if you have succeeded in initialising before! - * Returns zero if successful, and -EINVAL if the cpufreq_driver is - * currently not initialised. - */ -int cpufreq_unregister_driver(struct cpufreq_driver *driver) -{ - unsigned long flags; - - if (!cpufreq_driver || (driver != cpufreq_driver)) - return -EINVAL; - - pr_debug("unregistering driver %s\n", driver->name); - - subsys_interface_unregister(&cpufreq_interface); - unregister_hotcpu_notifier(&cpufreq_cpu_notifier); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); - -#include -#ifdef CONFIG_CPU_FREQ_GOV_FANTASYS -extern int cpufreq_fantasys_cpu_lock(int num_core); -extern int fantasys_cpu_work_initialized; -#endif - -#if defined(CONFIG_ARCH_SUNXI) && defined(CONFIG_HOTPLUG_CPU) -static int reboot_notifier_call(struct notifier_block *this, unsigned long code, void *_cmd) -{ - int cpu; -#ifdef CONFIG_CPU_FREQ_GOV_FANTASYS - struct cpufreq_policy policy; -#endif - - printk("%s:%s: stop none boot cpus\n", __FILE__, __func__); - -#ifdef CONFIG_CPU_FREQ_GOV_FANTASYS - if (cpufreq_get_policy(&policy, 0)) { - printk("%s:%s try to get policy failed!\n", __FILE__, __func__); - return NOTIFY_DONE; - } - if (!strcmp(policy.governor->name, "fantasys")) { - while (!fantasys_cpu_work_initialized) { - msleep(1); - } - cpufreq_fantasys_cpu_lock(1); - while (num_online_cpus() != 1) { - msleep(20); - } - goto out; - } -#endif - - for_each_online_cpu(cpu) { - if (cpu == 0) - continue; - - cpu_down(cpu); - } - -#ifdef CONFIG_CPU_FREQ_GOV_FANTASYS -out: -#endif - printk("%s:%s: stop none boot cpus done\n", __FILE__, __func__); - return NOTIFY_DONE; -} - -static struct notifier_block reboot_notifier = { - .notifier_call = reboot_notifier_call, -}; -#endif - -static int __init cpufreq_core_init(void) -{ - int cpu; - - if (cpufreq_disabled()) - return -ENODEV; - - for_each_possible_cpu(cpu) { - per_cpu(cpufreq_policy_cpu, cpu) = -1; - init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); - } - - cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); - BUG_ON(!cpufreq_global_kobject); - register_syscore_ops(&cpufreq_syscore_ops); - -#if defined(CONFIG_ARCH_SUNXI) && defined(CONFIG_HOTPLUG_CPU) - /* register reboot notifier for process cpus when reboot */ - register_reboot_notifier(&reboot_notifier); -#endif - - return 0; -} -core_initcall(cpufreq_core_init); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_conservative.c b/linux-3.4/drivers/cpufreq.new/cpufreq_conservative.c deleted file mode 100755 index 2e654ef0..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_conservative.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_conservative.c - * - * Copyright (C) 2001 Russell King - * (C) 2003 Venkatesh Pallipadi . - * Jun Nakajima - * (C) 2009 Alexander Clouter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cpufreq_governor.h" - -/* Conservative governor macros */ -#define DEF_FREQUENCY_UP_THRESHOLD (80) -#define DEF_FREQUENCY_DOWN_THRESHOLD (20) -#define DEF_FREQUENCY_STEP (5) -#define DEF_SAMPLING_DOWN_FACTOR (1) -#define MAX_SAMPLING_DOWN_FACTOR (10) - -static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info); - -static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners, - struct cpufreq_policy *policy) -{ - unsigned int freq_target = (cs_tuners->freq_step * policy->max) / 100; - - /* max freq cannot be less than 100. But who knows... */ - if (unlikely(freq_target == 0)) - freq_target = DEF_FREQUENCY_STEP; - - return freq_target; -} - -/* - * Every sampling_rate, we check, if current idle time is less than 20% - * (default), then we try to increase frequency. Every sampling_rate * - * sampling_down_factor, we check, if current idle time is more than 80% - * (default), then we try to decrease frequency - * - * Any frequency increase takes it to the maximum frequency. Frequency reduction - * happens at minimum steps of 5% (default) of maximum frequency - */ -static void cs_check_cpu(int cpu, unsigned int load) -{ - struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); - struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; - struct dbs_data *dbs_data = policy->governor_data; - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - - /* - * break out if we 'cannot' reduce the speed as the user might - * want freq_step to be zero - */ - if (cs_tuners->freq_step == 0) - return; - - /* Check for frequency increase */ - if (load > cs_tuners->up_threshold) { - dbs_info->down_skip = 0; - - /* if we are already at full speed then break out early */ - if (dbs_info->requested_freq == policy->max) - return; - - dbs_info->requested_freq += get_freq_target(cs_tuners, policy); - if (dbs_info->requested_freq > policy->max) - dbs_info->requested_freq = policy->max; - - __cpufreq_driver_target(policy, dbs_info->requested_freq, - CPUFREQ_RELATION_H); - return; - } - - /* if sampling_down_factor is active break out early */ - if (++dbs_info->down_skip < cs_tuners->sampling_down_factor) - return; - dbs_info->down_skip = 0; - - /* Check for frequency decrease */ - if (load < cs_tuners->down_threshold) { - /* - * if we cannot reduce the frequency anymore, break out early - */ - if (policy->cur == policy->min) - return; - - dbs_info->requested_freq -= get_freq_target(cs_tuners, policy); - if (dbs_info->requested_freq < policy->min) - dbs_info->requested_freq = policy->min; - - __cpufreq_driver_target(policy, dbs_info->requested_freq, - CPUFREQ_RELATION_L); - return; - } -} - -static void cs_dbs_timer(struct work_struct *work) -{ - struct cs_cpu_dbs_info_s *dbs_info = container_of(work, - struct cs_cpu_dbs_info_s, cdbs.work.work); - unsigned int cpu = dbs_info->cdbs.cur_policy->cpu; - struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info, - cpu); - struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data; - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - int delay = delay_for_sampling_rate(cs_tuners->sampling_rate); - bool modify_all = true; - - mutex_lock(&core_dbs_info->cdbs.timer_mutex); - if (!need_load_eval(&core_dbs_info->cdbs, cs_tuners->sampling_rate)) - modify_all = false; - else - dbs_check_cpu(dbs_data, cpu); - - gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all); - mutex_unlock(&core_dbs_info->cdbs.timer_mutex); -} - -static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct cpufreq_freqs *freq = data; - struct cs_cpu_dbs_info_s *dbs_info = - &per_cpu(cs_cpu_dbs_info, freq->cpu); - struct cpufreq_policy *policy; - - if (!dbs_info->enable) - return 0; - - policy = dbs_info->cdbs.cur_policy; - - /* - * we only care if our internally tracked freq moves outside the 'valid' - * ranges of frequency available to us otherwise we do not change it - */ - if (dbs_info->requested_freq > policy->max - || dbs_info->requested_freq < policy->min) - dbs_info->requested_freq = freq->new; - - return 0; -} - -/************************** sysfs interface ************************/ -static struct common_dbs_data cs_dbs_cdata; - -static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, - const char *buf, size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) - return -EINVAL; - - cs_tuners->sampling_down_factor = input; - return count; -} - -static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1) - return -EINVAL; - - cs_tuners->sampling_rate = max(input, dbs_data->min_sampling_rate); - return count; -} - -static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1 || input > 100 || input <= cs_tuners->down_threshold) - return -EINVAL; - - cs_tuners->up_threshold = input; - return count; -} - -static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - /* cannot be lower than 11 otherwise freq will not fall */ - if (ret != 1 || input < 11 || input > 100 || - input >= cs_tuners->up_threshold) - return -EINVAL; - - cs_tuners->down_threshold = input; - return count; -} - -static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, - const char *buf, size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input, j; - int ret; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - - if (input > 1) - input = 1; - - if (input == cs_tuners->ignore_nice_load) /* nothing to do */ - return count; - - cs_tuners->ignore_nice_load = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - struct cs_cpu_dbs_info_s *dbs_info; - dbs_info = &per_cpu(cs_cpu_dbs_info, j); - dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, - &dbs_info->cdbs.prev_cpu_wall, 0); - - if (cs_tuners->ignore_nice_load) - dbs_info->cdbs.prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - } - return count; -} - -static ssize_t store_freq_step(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1) - return -EINVAL; - - if (input > 100) - input = 100; - - /* - * no need to test here if freq_step is zero as the user might actually - * want this, they would be crazy though :) - */ - cs_tuners->freq_step = input; - return count; -} - -show_store_one(cs, sampling_rate); -show_store_one(cs, sampling_down_factor); -show_store_one(cs, up_threshold); -show_store_one(cs, down_threshold); -show_store_one(cs, ignore_nice_load); -show_store_one(cs, freq_step); -declare_show_sampling_rate_min(cs); - -gov_sys_pol_attr_rw(sampling_rate); -gov_sys_pol_attr_rw(sampling_down_factor); -gov_sys_pol_attr_rw(up_threshold); -gov_sys_pol_attr_rw(down_threshold); -gov_sys_pol_attr_rw(ignore_nice_load); -gov_sys_pol_attr_rw(freq_step); -gov_sys_pol_attr_ro(sampling_rate_min); - -static struct attribute *dbs_attributes_gov_sys[] = { - &sampling_rate_min_gov_sys.attr, - &sampling_rate_gov_sys.attr, - &sampling_down_factor_gov_sys.attr, - &up_threshold_gov_sys.attr, - &down_threshold_gov_sys.attr, - &ignore_nice_load_gov_sys.attr, - &freq_step_gov_sys.attr, - NULL -}; - -static struct attribute_group cs_attr_group_gov_sys = { - .attrs = dbs_attributes_gov_sys, - .name = "conservative", -}; - -static struct attribute *dbs_attributes_gov_pol[] = { - &sampling_rate_min_gov_pol.attr, - &sampling_rate_gov_pol.attr, - &sampling_down_factor_gov_pol.attr, - &up_threshold_gov_pol.attr, - &down_threshold_gov_pol.attr, - &ignore_nice_load_gov_pol.attr, - &freq_step_gov_pol.attr, - NULL -}; - -static struct attribute_group cs_attr_group_gov_pol = { - .attrs = dbs_attributes_gov_pol, - .name = "conservative", -}; - -/************************** sysfs end ************************/ - -static int cs_init(struct dbs_data *dbs_data) -{ - struct cs_dbs_tuners *tuners; - - tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL); - if (!tuners) { - pr_err("%s: kzalloc failed\n", __func__); - return -ENOMEM; - } - - tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; - tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD; - tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; - tuners->ignore_nice_load = 0; - tuners->freq_step = DEF_FREQUENCY_STEP; - - dbs_data->tuners = tuners; - dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * - jiffies_to_usecs(10); - mutex_init(&dbs_data->mutex); - return 0; -} - -static void cs_exit(struct dbs_data *dbs_data) -{ - kfree(dbs_data->tuners); -} - -define_get_cpu_dbs_routines(cs_cpu_dbs_info); - -static struct notifier_block cs_cpufreq_notifier_block = { - .notifier_call = dbs_cpufreq_notifier, -}; - -static struct cs_ops cs_ops = { - .notifier_block = &cs_cpufreq_notifier_block, -}; - -static struct common_dbs_data cs_dbs_cdata = { - .governor = GOV_CONSERVATIVE, - .attr_group_gov_sys = &cs_attr_group_gov_sys, - .attr_group_gov_pol = &cs_attr_group_gov_pol, - .get_cpu_cdbs = get_cpu_cdbs, - .get_cpu_dbs_info_s = get_cpu_dbs_info_s, - .gov_dbs_timer = cs_dbs_timer, - .gov_check_cpu = cs_check_cpu, - .gov_ops = &cs_ops, - .init = cs_init, - .exit = cs_exit, -}; - -static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, - unsigned int event) -{ - return cpufreq_governor_dbs(policy, &cs_dbs_cdata, event); -} - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE -static -#endif -struct cpufreq_governor cpufreq_gov_conservative = { - .name = "conservative", - .governor = cs_cpufreq_governor_dbs, - .max_transition_latency = TRANSITION_LATENCY_LIMIT, - .owner = THIS_MODULE, -}; - -static int __init cpufreq_gov_dbs_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_conservative); -} - -static void __exit cpufreq_gov_dbs_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_conservative); -} - -MODULE_AUTHOR("Alexander Clouter "); -MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for " - "Low Latency Frequency Transition capable processors " - "optimised for use in a battery environment"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE -fs_initcall(cpufreq_gov_dbs_init); -#else -module_init(cpufreq_gov_dbs_init); -#endif -module_exit(cpufreq_gov_dbs_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_fantasys.c b/linux-3.4/drivers/cpufreq.new/cpufreq_fantasys.c deleted file mode 100755 index 232099f1..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_fantasys.c +++ /dev/null @@ -1,1532 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_fantasys.c - * - * copyright (c) 2012-2013 allwinnertech - * - * based on ondemand policy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SW_POWERNOW -#include -#endif - -#include "sunxi-cpufreq.h" - -/* - * dbs is used in this file as a shortform for demandbased switching - * It helps to keep variable names smaller, simpler - */ -#define FANTASY_DEBUG_LEVEL (1) - -#if (FANTASY_DEBUG_LEVEL == 0 ) - #define FANTASY_DBG(format,args...) - #define FANTASY_WRN(format,args...) - #define FANTASY_ERR(format,args...) -#elif(FANTASY_DEBUG_LEVEL == 1) - #define FANTASY_DBG(format,args...) - #define FANTASY_WRN(format,args...) - #define FANTASY_ERR(format,args...) printk(KERN_ERR "[fantasy] err "format,##args) -#elif(FANTASY_DEBUG_LEVEL == 2) - #define FANTASY_DBG(format,args...) - #define FANTASY_WRN(format,args...) printk(KERN_WARNING "[fantasy] wrn "format,##args) - #define FANTASY_ERR(format,args...) printk(KERN_ERR "[fantasy] err "format,##args) -#elif(FANTASY_DEBUG_LEVEL == 3) - #define FANTASY_DBG(format,args...) printk(KERN_DEBUG "[fantasy] dbg "format,##args) - #define FANTASY_WRN(format,args...) printk(KERN_WARNING "[fantasy] wrn "format,##args) - #define FANTASY_ERR(format,args...) printk(KERN_ERR "[fantasy] err "format,##args) -#endif - -#define DEF_CPU_UP_CYCLE_REF (10) /* check cpu up period is n*sample_rate=0.5 second */ -#define DEF_CPU_DOWN_RATE (10) /* check cpu down period is n*sample_rate=0.5 second */ -#define MAX_HOTPLUG_RATE (10) /* array size for save history sample data */ - -#define DEF_MAX_CPU_LOCK (0) -#define DEF_START_DELAY (0) - -#define DEF_SAMPLING_RATE (50000) /* check cpu frequency sample rate is 50ms */ - -#define CPU_STATE_DEBUG_TOTAL_MASK (0x1) -#define CPU_STATE_DEBUG_CORES_MASK (0x2) - -#define CPU_UP_DOWN_FREQ_REF (400000) - - -#define POWERNOW_PERFORM_MAX (1200000) /* config the maximum frequency of performance mode */ - -extern int sunxi_cpufreq_getvolt(void); -extern struct cpufreq_dvfs dvfs_table_syscfg[16]; - -/* - * static data of cpu usage - */ -struct cpu_usage { - unsigned int freq; /* cpu frequency value */ - unsigned int volt; /* cpu voltage value */ - unsigned int loading[NR_CPUS]; /* cpu frequency loading */ - unsigned int running[NR_CPUS]; /* cpu running list loading */ - unsigned int iowait[NR_CPUS]; /* cpu waiting */ - unsigned int loading_avg; /* system average freq loading */ - unsigned int running_avg; /* system average thread loading */ - unsigned int iowait_avg; /* system average waiting */ -}; - -/* record cpu history loading information */ -struct cpu_usage_history { - struct cpu_usage usage[MAX_HOTPLUG_RATE]; - unsigned int num_hist; /* current number of history data */ -}; -static struct cpu_usage_history *hotplug_history; - -/* - * get average loading of all cpu's run list - */ -static unsigned int get_rq_avg_sys(void) -{ - return nr_running_avg(); -} - -/* - * get average loading of spec cpu's run list - */ -static unsigned int get_rq_avg_cpu(int cpu) -{ - return nr_running_avg_cpu(cpu); -} - -/* - * define thread loading policy table for cpu hotplug - * if(rq > hotplug_rq[0][1]) cpu need plug in, run 2 cores; - * if(rq < hotplug_rq[1][0]) cpu can plug out, run 1 cores; - */ -#if defined(CONFIG_ARCH_SUN8IW3P1) -static int hotplug_rq_def[NR_CPUS][2] = { - {0 , 1500}, - {700 , 0 }, -}; -#elif defined(CONFIG_ARCH_SUN8IW1P1) || defined(CONFIG_ARCH_SUN8IW5P1) -static int hotplug_rq_def[NR_CPUS][2] = { - {0 , 1500}, - {1000 , 2500}, - {2000 , 3500}, - {3000 , 0 }, -}; -#endif - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -/* - * define frequency policy table for user event triger - * switch cpu frequency to policy->max * 100% if single core currently - * switch cpu frequency to policy->max * 80% if dual core currently - */ -#if defined(CONFIG_ARCH_SUN8IW3P1) -static int usrevent_freq_def[NR_CPUS] = { - 80, - 60, -}; -#elif defined(CONFIG_ARCH_SUN8IW1P1) || defined(CONFIG_ARCH_SUN8IW5P1) -static int usrevent_freq_def[NR_CPUS] = { - 80, - 80, - 60, - 60, -}; -#endif -#endif - -static int cpu_up_weight_tbl[10] = { - 25, - 20, - 15, - 10, - 5, - 5, - 5, - 5, - 5, - 5, -}; - -static int hotplug_rq[NR_CPUS][2]; - -#if defined(CONFIG_ARCH_SUN8IW3P1) -static int pulse_freq[NR_CPUS] = -{ - 80, - 80, -}; -#elif defined(CONFIG_ARCH_SUN8IW1P1) || defined(CONFIG_ARCH_SUN8IW5P1) -static int pulse_freq[NR_CPUS] = -{ - 80, - 80, - 80, - 80, -}; -#endif - -static int cpu_up_rq_hist[DEF_CPU_UP_CYCLE_REF]; -static int cpu_up_iow_hist[DEF_CPU_UP_CYCLE_REF]; - -/* - * define data structure for dbs - */ -struct cpu_dbs_info_s { - u64 prev_cpu_idle; /* previous idle time statistic */ - u64 prev_cpu_iowait; /* previous iowait time stat */ - u64 prev_cpu_wall; /* previous total time stat */ - struct cpufreq_policy *cur_policy; - struct delayed_work work; - struct work_struct up_work; /* cpu plug-in processor */ - struct work_struct down_work; /* cpu plug-out processer */ - struct cpufreq_frequency_table *freq_table; - int cpu; /* current cpu number */ - /* - * percpu mutex that serializes governor limit change with - * do_dbs_timer invocation. We do not want do_dbs_timer to run - * when user is changing the governor or limits. - */ - struct mutex timer_mutex; /* semaphore for protection */ -}; - -/* - * define percpu variable for dbs information - */ -static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info); -struct workqueue_struct *dvfs_workqueue; -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event); - -/* number of CPUs using this policy */ -static unsigned int dbs_enable; - -/* thread and flag for pulse cpu frequency */ -static struct task_struct *pulse_task; -atomic_t g_pulse_flag = ATOMIC_INIT(0); - -/* suspend flag */ -static int is_suspended = false; - -/* cpu up/down work flag */ -int fantasys_cpu_work_initialized = false; -/* - * dbs_mutex protects dbs_enable in governor start/stop. - */ -static DEFINE_MUTEX(dbs_mutex); - -static struct dbs_tuners { - unsigned int sampling_rate; /* dvfs sample rate */ - unsigned int io_is_busy; /* flag to mark if iowait calculate as cpu busy */ - unsigned int cpu_up_cycle_ref; /* history sample rate for cpu up */ - unsigned int cpu_down_rate; /* history sample rate for cpu down */ - unsigned int freq_down_delay; /* delay sample rate for cpu frequency down */ - unsigned int max_cpu_lock; /* max count of online cpu, user limit */ - atomic_t hotplug_lock; /* lock cpu online number, disable plug-in/out */ - unsigned int dvfs_debug; /* dvfs debug flag, print dbs information */ - unsigned int cpu_state_debug; /* cpu status debug flag, print cpu detail info */ -#ifdef CONFIG_SW_POWERNOW - unsigned int powernow; /* power now mode */ -#endif - unsigned int pn_perform_freq; /* performance mode max freq */ -} dbs_tuners_ins = { - .cpu_up_cycle_ref = DEF_CPU_UP_CYCLE_REF, - .cpu_down_rate = DEF_CPU_DOWN_RATE, - .freq_down_delay = 0, - .max_cpu_lock = DEF_MAX_CPU_LOCK, - .hotplug_lock = ATOMIC_INIT(0), - .dvfs_debug = 0, - .cpu_state_debug = 0, -#ifdef CONFIG_SW_POWERNOW - .powernow = SW_POWERNOW_PERFORMANCE, -#endif - .pn_perform_freq = POWERNOW_PERFORM_MAX, -}; - -struct cpufreq_governor cpufreq_gov_fantasys = { - .name = "fantasys", - .governor = cpufreq_governor_dbs, - .owner = THIS_MODULE, -}; - -/* - * CPU hotplug lock interface - */ -atomic_t g_hotplug_lock = ATOMIC_INIT(0); - -/* - * CPU max power flag - */ -atomic_t g_max_power_flag = ATOMIC_INIT(0); - -/* - * apply cpu hotplug lock, up or down cpu - */ -static void apply_hotplug_lock(void) -{ - int online, possible, lock, flag; - struct work_struct *work; - struct cpu_dbs_info_s *dbs_info; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - online = num_online_cpus(); - possible = num_possible_cpus(); - lock = atomic_read(&g_hotplug_lock); - flag = lock - online; - - if (flag == 0) - return; - - work = flag > 0 ? &dbs_info->up_work : &dbs_info->down_work; - - FANTASY_DBG("%s online:%d possible:%d lock:%d flag:%d %d\n", - __func__, online, possible, lock, flag, (int)abs(flag)); - - queue_work_on(dbs_info->cpu, dvfs_workqueue, work); -} - -/* - * lock cpu number, the number of onlie cpu should less then num_core - */ -int cpufreq_fantasys_cpu_lock(int num_core) -{ - int prev_lock; - struct cpu_dbs_info_s *dbs_info; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - - if (num_core < 1 || num_core > num_possible_cpus()) { - mutex_unlock(&dbs_info->timer_mutex); - return -EINVAL; - } - - prev_lock = atomic_read(&g_hotplug_lock); - if (prev_lock != 0 && prev_lock < num_core) { - mutex_unlock(&dbs_info->timer_mutex); - return -EINVAL; - } - - atomic_set(&g_hotplug_lock, num_core); - apply_hotplug_lock(); - mutex_unlock(&dbs_info->timer_mutex); - - return 0; -} - -/* - * unlock cpu hotplug number - */ -int cpufreq_fantasys_cpu_unlock(int num_core) -{ - int prev_lock = atomic_read(&g_hotplug_lock); - struct cpu_dbs_info_s *dbs_info; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - - if (prev_lock != num_core) { - mutex_unlock(&dbs_info->timer_mutex); - return -EINVAL; - } - - atomic_set(&g_hotplug_lock, 0); - mutex_unlock(&dbs_info->timer_mutex); - - return 0; -} - - -/* cpufreq_pegasusq Governor Tunables */ -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ -} -show_one(sampling_rate, sampling_rate); -show_one(io_is_busy, io_is_busy); -show_one(cpu_up_cycle_ref, cpu_up_cycle_ref); -show_one(cpu_down_rate, cpu_down_rate); -show_one(max_cpu_lock, max_cpu_lock); -show_one(dvfs_debug, dvfs_debug); -show_one(cpu_state_debug, cpu_state_debug); -static ssize_t show_hotplug_lock(struct kobject *kobj, struct attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", atomic_read(&g_hotplug_lock)); -} - -static ssize_t show_max_power(struct kobject *kobj, struct attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", atomic_read(&g_max_power_flag)); -} - -static ssize_t show_pulse(struct kobject *kobj, struct attribute *attr, char *buf) -{ - int nr_up, cpu, hotplug_lock; - struct cpu_dbs_info_s *dbs_info; - - mutex_lock(&dbs_mutex); - if (!dbs_enable) { - mutex_unlock(&dbs_mutex); - return -EINVAL; - } - mutex_unlock(&dbs_mutex); - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - - hotplug_lock = atomic_read(&g_hotplug_lock); - if (hotplug_lock) - goto unlock; - - __cpufreq_driver_target(dbs_info->cur_policy, dbs_info->cur_policy->max, CPUFREQ_RELATION_H); - nr_up = nr_cpu_ids - num_online_cpus(); - for_each_cpu_not(cpu, cpu_online_mask) { - if (cpu == 0) - continue; - - if (nr_up-- == 0) - break; - - cpu_up(cpu); - } - - /* avoid plug out cpu in the current cycle, reset the stat cycle */ - hotplug_history->num_hist = 0; - /* delay 40 sampling cycle for frequency down */ - dbs_tuners_ins.freq_down_delay = 40; - -unlock: - mutex_unlock(&dbs_info->timer_mutex); - - return sprintf(buf, "pulse\n"); -} - -static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.sampling_rate = input; - return count; -} - -static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - - dbs_tuners_ins.io_is_busy = !!input; - return count; -} - -static ssize_t store_cpu_up_cycle_ref(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.cpu_up_cycle_ref = (unsigned int)min((int)input, (int)MAX_HOTPLUG_RATE); - return count; -} - -static ssize_t store_cpu_down_rate(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.cpu_down_rate = (unsigned int)min((int)input, (int)MAX_HOTPLUG_RATE); - return count; -} - -static ssize_t store_max_cpu_lock(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - input = min(input, num_possible_cpus()); - dbs_tuners_ins.max_cpu_lock = input; - return count; -} - -static ssize_t store_hotplug_lock(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - int prev_lock; - - mutex_lock(&dbs_mutex); - if (!dbs_enable) { - mutex_unlock(&dbs_mutex); - return -EINVAL; - } - mutex_unlock(&dbs_mutex); - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - input = min(input, num_possible_cpus()); - prev_lock = atomic_read(&dbs_tuners_ins.hotplug_lock); - - if (prev_lock) - cpufreq_fantasys_cpu_unlock(prev_lock); - - if (input == 0) { - atomic_set(&dbs_tuners_ins.hotplug_lock, 0); - return count; - } - - ret = cpufreq_fantasys_cpu_lock(input); - if (ret) { - printk(KERN_ERR "[HOTPLUG] already locked with smaller value %d < %d\n", - atomic_read(&g_hotplug_lock), input); - return ret; - } - - atomic_set(&dbs_tuners_ins.hotplug_lock, input); - - return count; -} - -static ssize_t store_dvfs_debug(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.dvfs_debug = input > 0; - return count; -} - -static ssize_t store_cpu_state_debug(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - - if (input > 3) { - return -EINVAL; - } else { - dbs_tuners_ins.cpu_state_debug = input; - } - - return count; -} - -static ssize_t store_max_power(struct kobject *a, struct attribute *b, - const char *buf, size_t count) -{ - unsigned int input; - int ret, nr_up, cpu, max_power_flag; - struct cpu_dbs_info_s *dbs_info; - - mutex_lock(&dbs_mutex); - if (!dbs_enable) { - mutex_unlock(&dbs_mutex); - return -EINVAL; - } - mutex_unlock(&dbs_mutex); - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - ret = sscanf(buf, "%u", &input); - if (ret != 1) { - mutex_unlock(&dbs_info->timer_mutex); - return -EINVAL; - } - - atomic_set(&g_max_power_flag, !!input); - max_power_flag = atomic_read(&g_max_power_flag); - if (max_power_flag == 1) { - __cpufreq_driver_target(dbs_info->cur_policy, dbs_info->cur_policy->max, CPUFREQ_RELATION_H); - nr_up = nr_cpu_ids - num_online_cpus(); - for_each_cpu_not(cpu, cpu_online_mask) { - if (cpu == 0) - continue; - - if (nr_up-- == 0) - break; - - cpu_up(cpu); - } - } else if (max_power_flag == 0) { - hotplug_history->num_hist = 0; - queue_delayed_work_on(dbs_info->cpu, dvfs_workqueue, &dbs_info->work, 0); - } else { - mutex_unlock(&dbs_info->timer_mutex); - return -EINVAL; - } - mutex_unlock(&dbs_info->timer_mutex); - - return count; -} - -define_one_global_rw(sampling_rate); -define_one_global_rw(io_is_busy); -define_one_global_rw(cpu_up_cycle_ref); -define_one_global_rw(cpu_down_rate); -define_one_global_rw(max_cpu_lock); -define_one_global_rw(hotplug_lock); -define_one_global_rw(dvfs_debug); -define_one_global_rw(cpu_state_debug); -define_one_global_rw(max_power); -define_one_global_ro(pulse); - -static struct attribute *dbs_attributes[] = { - &sampling_rate.attr, - &io_is_busy.attr, - &cpu_up_cycle_ref.attr, - &cpu_down_rate.attr, - &max_cpu_lock.attr, - &hotplug_lock.attr, - &dvfs_debug.attr, - &cpu_state_debug.attr, - &max_power.attr, - &pulse.attr, - NULL -}; - -static struct attribute_group dbs_attr_group = { - .attrs = dbs_attributes, - .name = "fantasys", -}; - - -/* - * cpu hotplug, just plug in 2 cpu - */ -static void cpu_up_work(struct work_struct *work) -{ - int cpu, nr_up, online, hotplug_lock; - struct cpu_dbs_info_s *dbs_info; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - online = num_online_cpus(); - hotplug_lock = atomic_read(&g_hotplug_lock); - - if (hotplug_lock) { - nr_up = (hotplug_lock - online) > 0 ? (hotplug_lock - online) : 0; - } else { - nr_up = 1; - } - - for_each_cpu_not(cpu, cpu_online_mask) { - if (cpu == 0) - continue; - - if (nr_up-- == 0) - break; - - FANTASY_WRN("cpu up:%d\n", cpu); - cpu_up(cpu); - } - mutex_unlock(&dbs_info->timer_mutex); -} - -/* - * cpu hotplug, cpu plugout - */ -static void cpu_down_work(struct work_struct *work) -{ - int cpu, nr_down, online, hotplug_lock; - struct cpu_dbs_info_s *dbs_info; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - online = num_online_cpus(); - hotplug_lock = atomic_read(&g_hotplug_lock); - - if (hotplug_lock) { - nr_down = (online - hotplug_lock) > 0 ? (online - hotplug_lock) : 0; - } else { - nr_down = 1; - } - - for_each_online_cpu(cpu) { - if (cpu == 0) - continue; - - if (nr_down-- == 0) - break; - - FANTASY_DBG("cpu down:%d\n", cpu); - cpu_down(cpu); - } - - mutex_unlock(&dbs_info->timer_mutex); -} - -/* check cpu if need to run max power according to one core's loading/running/iowait */ -static int check_up(int num_hist, struct cpufreq_policy *policy) -{ - unsigned int cpu_rq_avg = 0, iow_avg = 0; - int i, online, index_mod, index_cur, up_rq; - int hotplug_lock = atomic_read(&g_hotplug_lock); - - /* hotplug has been locked, do nothing */ - if (hotplug_lock > 0) - return 0; - - online = num_online_cpus(); - if (online == num_possible_cpus()) - return 0; - - if (dbs_tuners_ins.max_cpu_lock != 0 && online >= dbs_tuners_ins.max_cpu_lock) - return 0; - - if (policy->cur * hotplug_history->usage[num_hist].loading_avg / 100 <= CPU_UP_DOWN_FREQ_REF) - return 0; - - up_rq = hotplug_rq[online-1][1]; - index_mod = num_hist%dbs_tuners_ins.cpu_up_cycle_ref; - cpu_up_rq_hist[index_mod] = hotplug_history->usage[num_hist].running_avg; - cpu_up_iow_hist[index_mod] = hotplug_history->usage[num_hist].iowait_avg; - - for (i=0; i up_rq) { - FANTASY_WRN("cpu need plugin, cpu_rq_avg: %d>%d\n", cpu_rq_avg, up_rq); - hotplug_history->num_hist = 0; - memset(cpu_up_rq_hist, 0, sizeof(cpu_up_rq_hist)); - return 1; - } - - if (iow_avg > 20) { - FANTASY_WRN("cpu need plugin, iow_avg: %u>%u\n", iow_avg, 20); - hotplug_history->num_hist = 0; - memset(cpu_up_iow_hist, 0, sizeof(cpu_up_iow_hist)); - return 1; - } - - return 0; -} - -/* - * check if need plug out one cpu core - */ -static int check_down(struct cpufreq_policy *policy) -{ - struct cpu_usage *usage; - int i, online, down_rq; - int avg_rq = 0, max_rq_avg = 0, avg_freq_fact = 0; - int down_rate = dbs_tuners_ins.cpu_down_rate; - int num_hist = hotplug_history->num_hist; - int hotplug_lock = atomic_read(&g_hotplug_lock); - - /* hotplug has been locked, do nothing */ - if (hotplug_lock > 0) - return 0; - - online = num_online_cpus(); - if (online == 1) - return 0; - - /* if count of online cpu is larger than the max value, plug out cpu */ - if (dbs_tuners_ins.max_cpu_lock != 0 && online > dbs_tuners_ins.max_cpu_lock) - return 1; - - /* check if reached the switch point */ - if (num_hist == 0 || num_hist % down_rate) - return 0; - - down_rq = hotplug_rq[online-1][0]; - - /* check system average loading */ - for (i = num_hist - 1; i >= num_hist - down_rate; --i) { - usage = &hotplug_history->usage[i]; - avg_rq = usage->running_avg; - avg_freq_fact += usage->freq * usage->loading_avg; - max_rq_avg = max(max_rq_avg, avg_rq); - } - - avg_freq_fact /= down_rate; - avg_freq_fact /= 100; - - if (dbs_tuners_ins.dvfs_debug) { - printk("%s: avg_freq_fact:%d, down_freq_ref:%d, max_rq_avg:%u, down_rq:%u\n", \ - __func__, avg_freq_fact, CPU_UP_DOWN_FREQ_REF, max_rq_avg, down_rq); - } - - if ((avg_freq_fact <= CPU_UP_DOWN_FREQ_REF) && (max_rq_avg <= down_rq)) { - FANTASY_WRN("cpu need plugout, avg_freq_fact: %d<%d, max_rq_avg: %d<%d\n", \ - avg_freq_fact, CPU_UP_DOWN_FREQ_REF, max_rq_avg, down_rq); - hotplug_history->num_hist = 0; - /* need plug out cpu, reset the stat cycle */ - return 1; - } - - return 0; -} - -/* - * define frequency limit for min londing, cpu frequency should be limit to lower if loading lower - */ -#define FANTASY_CPUFREQ_LOAD_MIN_RATE(freq) \ - (freq<200000? 30 : (freq<400000? 40 : (freq<600000? 60 : (freq<900000? 70 : 80)))) - -/* - * define frequency limit for max londing, cpu frequency should be limit to higher if loading higher - */ -#define FANTASY_CPUFREQ_LOAD_MAX_RATE(freq) \ - (freq<200000? 60 : (freq<400000? 70 : (freq<600000? 80 : (freq<900000? 90 : 95)))) - -/* - * define frequency limit for io-wait rate, cpu frequency should be limit to higher if io-wait higher - */ -#define FANTASY_CPUFREQ_IOW_LIMIT_RATE(iow) \ - (iow<10? (iow>0? 20 : 0) : (iow<20? 40 : (iow<40? 60 : (iow<60? 80 : 100)))) - -static inline unsigned int __get_target_freq(unsigned int freq) -{ - struct cpufreq_dvfs *dvfs_inf = NULL; - dvfs_inf = &dvfs_table_syscfg[0]; - - while((dvfs_inf+1)->freq > freq) dvfs_inf++; - - return dvfs_inf->freq; -} - -static int check_freq_up_down(struct cpu_dbs_info_s *this_dbs_info, unsigned int *target, int num_hist) -{ - unsigned int freq_load, freq_iow, index; - struct cpufreq_policy *policy = this_dbs_info->cur_policy; - unsigned int max_load = 0, max_iow = 0; - int cpu; - - if (dbs_tuners_ins.freq_down_delay) { - dbs_tuners_ins.freq_down_delay--; - *target = policy->cur; - return 0; - } - - for_each_online_cpu(cpu) { - max_load = max(max_load, hotplug_history->usage[num_hist].loading[cpu]); - max_iow = max(max_iow, hotplug_history->usage[num_hist].iowait[cpu]); - } - - if (max_load > FANTASY_CPUFREQ_LOAD_MAX_RATE(policy->cur)) { - if (dbs_tuners_ins.dvfs_debug) - printk("%s(%d): max_load=%d, cur_freq=%d, load_rate=%d\n", \ - __func__, __LINE__, max_load, policy->cur, FANTASY_CPUFREQ_LOAD_MAX_RATE(policy->cur)); - *target = __get_target_freq(policy->cur); - return 1; - } else if (max_load >= FANTASY_CPUFREQ_LOAD_MIN_RATE(policy->cur)) { - *target = policy->cur; - return 0; - } - - /* - * calculate freq load - * freq_load = (cur_freq * max_load) / ((min_rate + max_rate)/2) - */ - freq_load = (policy->cur * max_load) / 100; - freq_load = (policy->cur * max_load) / FANTASY_CPUFREQ_LOAD_MAX_RATE(freq_load); - - /* check cpu io-waiting */ - freq_iow = (policy->max*FANTASY_CPUFREQ_IOW_LIMIT_RATE(max_iow))/100; - - if (dbs_tuners_ins.dvfs_debug) { - printk("%s(%d): max_load=%d, cur_freq=%d, load_rate=%d, freq_load=%d\n", \ - __func__, __LINE__, max_load, policy->cur, FANTASY_CPUFREQ_LOAD_MIN_RATE(policy->cur), freq_load); - printk("%s(%d): max_iow=%d, limit_rate=%d, freq_iow=%d\n", \ - __func__, __LINE__, max_iow, FANTASY_CPUFREQ_IOW_LIMIT_RATE(max_iow), freq_iow); - } - - /* select target frequency */ - *target = max(freq_load, freq_iow); - - if (cpufreq_frequency_table_target(policy, this_dbs_info->freq_table, *target, CPUFREQ_RELATION_L, &index)) { - FANTASY_ERR("%s: failed to get next lowest frequency\n", __func__); - *target = policy->max; - return 1; - } - *target = this_dbs_info->freq_table[index].frequency; - - return 1; -} - -static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall) -{ - u64 iowait_time = get_cpu_iowait_time_us(cpu, wall); - - if (iowait_time == -1ULL) - return 0; - - return iowait_time; -} - -/* - * check if need plug in/out cpu, if need increase/decrease cpu frequency - */ -static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) -{ - unsigned int cpu, freq_target = 0; - struct cpufreq_policy *policy; - int num_hist = hotplug_history->num_hist; - int max_hotplug_rate = max((int)dbs_tuners_ins.cpu_up_cycle_ref, (int)dbs_tuners_ins.cpu_down_rate); - - policy = this_dbs_info->cur_policy; - /* static cpu loading */ - hotplug_history->usage[num_hist].freq = policy->cur; - hotplug_history->usage[num_hist].volt = sunxi_cpufreq_getvolt(); - hotplug_history->usage[num_hist].running_avg = get_rq_avg_sys(); - hotplug_history->usage[num_hist].loading_avg = 0; - hotplug_history->usage[num_hist].iowait_avg = 0; - ++hotplug_history->num_hist; - - for_each_online_cpu(cpu) { - struct cpu_dbs_info_s *j_dbs_info; - u64 cur_wall_time, cur_idle_time, cur_iowait_time; - u64 prev_wall_time, prev_idle_time, prev_iowait_time; - unsigned int idle_time, wall_time, iowait_time; - unsigned int load = 0, iowait = 0; - - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - prev_wall_time = j_dbs_info->prev_cpu_wall; - prev_idle_time = j_dbs_info->prev_cpu_idle; - prev_iowait_time = j_dbs_info->prev_cpu_iowait; - - cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, dbs_tuners_ins.io_is_busy); - cur_iowait_time = get_cpu_iowait_time(cpu, &cur_wall_time); - - wall_time = cur_wall_time - prev_wall_time; - j_dbs_info->prev_cpu_wall = cur_wall_time; - - idle_time = cur_idle_time - prev_idle_time; - j_dbs_info->prev_cpu_idle = cur_idle_time; - - iowait_time = cur_iowait_time - prev_iowait_time; - j_dbs_info->prev_cpu_iowait = cur_iowait_time; - - if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time) - idle_time -= iowait_time; - - if (wall_time && (wall_time > idle_time)) - load = 100 * (wall_time - idle_time) / wall_time; - else - load = 0; - hotplug_history->usage[num_hist].loading[cpu] = load; - - if (wall_time && (iowait_time < wall_time)) - iowait = 100 * iowait_time / wall_time; - else - iowait = 0; - hotplug_history->usage[num_hist].iowait[cpu] = iowait; - - /* calculate system average loading */ - hotplug_history->usage[num_hist].running[cpu] = get_rq_avg_cpu(cpu); - hotplug_history->usage[num_hist].loading_avg += load; - hotplug_history->usage[num_hist].iowait_avg += iowait; - - if (dbs_tuners_ins.cpu_state_debug & CPU_STATE_DEBUG_CORES_MASK) { - printk("[cpu%u] %u,%u,%u,%u,%u\n", cpu, \ - hotplug_history->usage[num_hist].freq, \ - hotplug_history->usage[num_hist].volt, \ - hotplug_history->usage[num_hist].loading[cpu], \ - hotplug_history->usage[num_hist].running[cpu], \ - hotplug_history->usage[num_hist].iowait[cpu]); - } - } - hotplug_history->usage[num_hist].loading_avg /= num_online_cpus(); - hotplug_history->usage[num_hist].iowait_avg /= num_online_cpus(); - - if (dbs_tuners_ins.cpu_state_debug & CPU_STATE_DEBUG_TOTAL_MASK) { - printk("%u,%u,%u,%u,%u,%u\n", hotplug_history->usage[num_hist].freq, \ - hotplug_history->usage[num_hist].volt, \ - num_online_cpus(), \ - hotplug_history->usage[num_hist].loading_avg, \ - hotplug_history->usage[num_hist].running_avg, \ - hotplug_history->usage[num_hist].iowait_avg); - } - - /* Check for every core is in high loading/running/iowait */ - if (check_up(num_hist, policy)) { - __cpufreq_driver_target(this_dbs_info->cur_policy, this_dbs_info->cur_policy->max, CPUFREQ_RELATION_H); - queue_work_on(this_dbs_info->cpu, dvfs_workqueue, &this_dbs_info->up_work); - return; - } else if (check_down(policy)) { - queue_work_on(this_dbs_info->cpu, dvfs_workqueue, &this_dbs_info->down_work); - } - - if (check_freq_up_down(this_dbs_info, &freq_target, num_hist)) { - FANTASY_WRN("%s, %d : try to switch cpu freq to %d \n", __func__, __LINE__, freq_target); - __cpufreq_driver_target(policy, freq_target, CPUFREQ_RELATION_L); - } - - /* check if history array is out of range */ - if (hotplug_history->num_hist == max_hotplug_rate) - hotplug_history->num_hist = 0; -} - - -static void do_dbs_timer(struct work_struct *work) -{ - struct cpu_dbs_info_s *dbs_info = container_of(work, struct cpu_dbs_info_s, work.work); - unsigned int cpu = dbs_info->cpu; - int delay; - - mutex_lock(&dbs_info->timer_mutex); - - if (is_suspended) - goto unlock; - - if (atomic_read(&g_max_power_flag)) - goto unlock; - - dbs_check_cpu(dbs_info); - - /* We want all CPUs to do sampling nearly on - * same jiffy - */ - delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - - queue_delayed_work_on(cpu, dvfs_workqueue, &dbs_info->work, delay); - -unlock: - mutex_unlock(&dbs_info->timer_mutex); -} - - -static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) -{ - /* We want all CPUs to do sampling nearly on same jiffy */ - int delay = usecs_to_jiffies(DEF_START_DELAY * 1000 * 1000 + dbs_tuners_ins.sampling_rate); - if (num_online_cpus() > 1) - delay -= jiffies % delay; - - INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); - INIT_WORK(&dbs_info->up_work, cpu_up_work); - INIT_WORK(&dbs_info->down_work, cpu_down_work); - queue_delayed_work_on(dbs_info->cpu, dvfs_workqueue, &dbs_info->work, delay); - fantasys_cpu_work_initialized = true; -} - -static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) -{ - cancel_delayed_work_sync(&dbs_info->work); - cancel_work_sync(&dbs_info->up_work); - cancel_work_sync(&dbs_info->down_work); - fantasys_cpu_work_initialized = false; -} - - -static int fantasys_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy) -{ - struct cpu_dbs_info_s *dbs_info; - struct cpufreq_policy policy; - - if (cpufreq_get_policy(&policy, 0)) { - printk(KERN_ERR "can not get cpu policy\n"); - return NOTIFY_BAD; - } - - if (strcmp(policy.governor->name, "fantasys")) - return NOTIFY_OK; - - dbs_info = &per_cpu(od_cpu_dbs_info, 0); - mutex_lock(&dbs_info->timer_mutex); - - if (event == PM_SUSPEND_PREPARE) { - is_suspended = true; - printk("sunxi cpufreq suspend ok\n"); - } else if (event == PM_POST_SUSPEND) { - is_suspended = false; - if (atomic_read(&g_max_power_flag)) - __cpufreq_driver_target(dbs_info->cur_policy, dbs_info->cur_policy->max, CPUFREQ_RELATION_H); - queue_delayed_work_on(dbs_info->cpu, dvfs_workqueue, &dbs_info->work, 0); - printk("sunxi cpufreq resume ok\n"); - } - - mutex_unlock(&dbs_info->timer_mutex); - return NOTIFY_OK; -} - -static struct notifier_block fantasys_pm_notifier = { - .notifier_call = fantasys_pm_notify, -}; - -static void pulse_cpufreq(void) -{ - - unsigned int freq_trig, index; - struct cpu_dbs_info_s *this_dbs_info = &per_cpu(od_cpu_dbs_info, 0); - - /* cpu frequency limitation has changed, adjust current frequency */ - if (!mutex_trylock(&this_dbs_info->timer_mutex)) { - FANTASY_WRN("try to lock mutex failed!\n"); - return; - } - - freq_trig = (this_dbs_info->cur_policy->max * pulse_freq[num_online_cpus() - 1])/100; - if(!cpufreq_frequency_table_target(this_dbs_info->cur_policy, this_dbs_info->freq_table, - freq_trig, CPUFREQ_RELATION_L, &index)) { - freq_trig = this_dbs_info->freq_table[index].frequency; - if(this_dbs_info->cur_policy->cur < freq_trig) { - /* set cpu frequenc to the max value, and reset state machine */ - FANTASY_DBG("CPUFREQ_GOV_USREVENT cpu to %u\n", freq_trig); - __cpufreq_driver_target(this_dbs_info->cur_policy, freq_trig, CPUFREQ_RELATION_L); - } - } - dbs_tuners_ins.freq_down_delay = 6; - mutex_unlock(&this_dbs_info->timer_mutex); - return; -} - -static int cpufreq_fantasys_pulse_task(void *data) -{ - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!atomic_read(&g_pulse_flag)) { - schedule_timeout(10*HZ); - if (kthread_should_stop()) - break; - - continue; - } - - set_current_state(TASK_RUNNING); - pulse_cpufreq(); - atomic_set(&g_pulse_flag, 0); - } - - return 0; -} - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -/* - * trigger cpu frequency to a high speed some when input event coming. - * such as key, ir, touchpannel for ex. , but skip gsensor. - */ -static void cpufreq_fantasys_input_event(struct input_handle *handle, - unsigned int type, - unsigned int code, int value) -{ - if (type == EV_SYN && code == SYN_REPORT) { - atomic_set(&g_pulse_flag, 1); - wake_up_process(pulse_task); - } -} - - -static int cpufreq_fantasys_input_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "cpufreq_fantasys"; - - error = input_register_handle(handle); - if (error) - goto err; - - error = input_open_device(handle); - if (error) - goto err_open; - - return 0; - -err_open: - input_unregister_handle(handle); -err: - kfree(handle); - return error; -} - -static void cpufreq_fantasys_input_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id cpufreq_fantasys_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = - BIT_MASK(ABS_MT_POSITION_X) | - BIT_MASK(ABS_MT_POSITION_Y) }, - }, /* multi-touch touchscreen */ - { - .flags = INPUT_DEVICE_ID_MATCH_KEYBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { [BIT_WORD(ABS_X)] = - BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, - }, /* touchpad */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_BUS | - INPUT_DEVICE_ID_MATCH_VENDOR | - INPUT_DEVICE_ID_MATCH_PRODUCT | - INPUT_DEVICE_ID_MATCH_VERSION, - .bustype = BUS_HOST, - .vendor = 0x0001, - .product = 0x0001, - .version = 0x0100, - .evbit = { BIT_MASK(EV_KEY) }, - }, /* keyboard/ir */ - { }, -}; - -static struct input_handler cpufreq_fantasys_input_handler = { - .event = cpufreq_fantasys_input_event, - .connect = cpufreq_fantasys_input_connect, - .disconnect = cpufreq_fantasys_input_disconnect, - .name = "cpufreq_fantasys", - .id_table = cpufreq_fantasys_ids, -}; -#endif /* #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY */ - - -/* - * cpufreq dbs governor - */ -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) -{ - unsigned int cpu = policy->cpu; - struct cpu_dbs_info_s *this_dbs_info; - unsigned int j; - int ret; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - - this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - - switch (event) { - case CPUFREQ_GOV_POLICY_INIT: - { - if ((!cpu_online(cpu)) || (!policy->cur)) - return -EINVAL; - - hotplug_history->num_hist = 0; - - mutex_lock(&dbs_mutex); - - for_each_possible_cpu(j) { - struct cpu_dbs_info_s *j_dbs_info; - j_dbs_info = &per_cpu(od_cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, &j_dbs_info->prev_cpu_wall, dbs_tuners_ins.io_is_busy); - } - this_dbs_info->cpu = cpu; - this_dbs_info->freq_table = cpufreq_frequency_get_table(cpu); - - mutex_init(&this_dbs_info->timer_mutex); - - /* - * Start the timerschedule work, when this governor - * is used for first time - */ - if (!(dbs_enable++)) { - dbs_tuners_ins.sampling_rate = DEF_SAMPLING_RATE; - dbs_tuners_ins.io_is_busy = 1; - dbs_tuners_ins.pn_perform_freq = policy->max; - - pulse_task = kthread_create(cpufreq_fantasys_pulse_task, NULL, - "kfantasys-pulse"); - if (IS_ERR(pulse_task)) { - ret = PTR_ERR(pulse_task); - mutex_destroy(&this_dbs_info->timer_mutex); - mutex_unlock(&dbs_mutex); - return ret; - } - kthread_bind(pulse_task, 0); - sched_setscheduler_nocheck(pulse_task, SCHED_FIFO, ¶m); - get_task_struct(pulse_task); - - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - ret = input_register_handler(&cpufreq_fantasys_input_handler); - if (ret) - pr_warn("%s: failed to register input handler\n", __func__); - #endif - } - mutex_unlock(&dbs_mutex); - - dbs_timer_init(this_dbs_info); - - break; - } - - case CPUFREQ_GOV_POLICY_EXIT: - { - dbs_timer_exit(this_dbs_info); - - mutex_lock(&dbs_mutex); - mutex_destroy(&this_dbs_info->timer_mutex); - if(!(--dbs_enable)) { - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - input_unregister_handler(&cpufreq_fantasys_input_handler); - #endif - kthread_stop(pulse_task); - put_task_struct(pulse_task); - } - mutex_unlock(&dbs_mutex); - - break; - } - - case CPUFREQ_GOV_LIMITS: - { - if (policy->max < this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); - - break; - } - } - return 0; -} - -#ifdef CONFIG_SW_POWERNOW -static int start_powernow(unsigned long mode) -{ - int retval = 0, nr_up = 0, cpu = 0; - struct cpu_dbs_info_s *this_dbs_info; - struct cpufreq_policy *policy; - - this_dbs_info = &per_cpu(od_cpu_dbs_info, 0); - policy = this_dbs_info->cur_policy; - - if (policy == NULL) { - printk("[cpufreq_fantasys] policy is null %s, %d, mode=%lu, powernow=%d\n", - __func__, __LINE__, mode, dbs_tuners_ins.powernow); - if (mode != SW_POWERNOW_MAXPOWER && mode != SW_POWERNOW_USEREVENT){ - dbs_tuners_ins.powernow = mode; - } - return -EINVAL; - } - if (policy->governor != &cpufreq_gov_fantasys) { - printk(KERN_DEBUG "scaling cur governor is not fantasys!\n"); - if (mode != SW_POWERNOW_MAXPOWER && mode != SW_POWERNOW_USEREVENT) { - dbs_tuners_ins.powernow = mode; - } - return -EINVAL; - } - - printk(KERN_DEBUG "start_powernow :%d!\n", (int)mode); - - // WARNING: may sleep - // cancel_delayed_work_sync(&this_dbs_info->work); - // dbs_timer_exit(this_dbs_info); - - mutex_lock(&this_dbs_info->timer_mutex); - switch (mode) { - case SW_POWERNOW_EXTREMITY: - atomic_set(&g_max_power_flag, 1); - policy->max = policy->cpuinfo.max_freq; - policy->user_policy.max = policy->cpuinfo.max_freq; - printk("%s, %d : max=%d, policy_add=%p\n", - __func__, __LINE__, policy->max, policy); - - __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - - nr_up = num_possible_cpus() - num_online_cpus(); - for_each_cpu_not(cpu, cpu_online_mask) { - if (cpu == 0) - continue; - - if (nr_up-- == 0) - break; - - cpu_up(cpu); - } - - break; - - case SW_POWERNOW_PERFORMANCE: - policy->max = dbs_tuners_ins.pn_perform_freq; - policy->user_policy.max = dbs_tuners_ins.pn_perform_freq; - if (atomic_read(&g_max_power_flag) == 1) { - atomic_set(&g_max_power_flag, 0); - hotplug_history->num_hist = 0; - queue_delayed_work_on(this_dbs_info->cpu, dvfs_workqueue, &this_dbs_info->work, 0); - } - break; - - default: - printk(KERN_ERR "start_powernow uncare mode:%d!\n", (int)mode); - atomic_set(&g_max_power_flag, 0); - mode = dbs_tuners_ins.powernow; - retval = -EINVAL; - break; - } - -#if 0 - if (mode != SW_POWERNOW_EXTREMITY && dbs_enable > 0){ -#else - if (dbs_enable > 0) { -#endif - // dbs_timer_init(this_dbs_info); - } - dbs_tuners_ins.powernow = mode; - mutex_unlock(&this_dbs_info->timer_mutex); - return retval; -} - -static int powernow_notifier_call(struct notifier_block *nfb, - unsigned long mode, void *cmd) -{ - int retval = NOTIFY_DONE; - printk("[cpufreq_fantasys] enter %s %d, mode=%lu, %s\n", - __func__, __LINE__, mode, (char *)cmd); - mutex_lock(&dbs_mutex); - retval = start_powernow(mode); - mutex_unlock(&dbs_mutex); - retval = retval ? NOTIFY_DONE : NOTIFY_OK; - return retval; -} - -static struct notifier_block fantasys_powernow_notifier = { - .notifier_call = powernow_notifier_call, -}; -#endif /* CONFIG_SW_POWERNOW*/ - -/* - * cpufreq governor dbs initiate - */ -static int __init cpufreq_gov_dbs_init(void) -{ - int i, ret; - - /* init policy table */ - for(i=0; i"); -MODULE_DESCRIPTION("'cpufreq_fantasys' - A dynamic cpufreq/cpuhotplug governor"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS -fs_initcall(cpufreq_gov_dbs_init); -#else -module_init(cpufreq_gov_dbs_init); -#endif -module_exit(cpufreq_gov_dbs_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_governor.c b/linux-3.4/drivers/cpufreq.new/cpufreq_governor.c deleted file mode 100755 index c519bf26..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_governor.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_governor.c - * - * CPUFREQ governors common code - * - * Copyright (C) 2001 Russell King - * (C) 2003 Venkatesh Pallipadi . - * (C) 2003 Jun Nakajima - * (C) 2009 Alexander Clouter - * (c) 2012 Viresh Kumar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cpufreq_governor.h" - -static struct attribute_group *get_sysfs_attr(struct dbs_data *dbs_data) -{ - if (have_governor_per_policy()) - return dbs_data->cdata->attr_group_gov_pol; - else - return dbs_data->cdata->attr_group_gov_sys; -} - -void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) -{ - struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - struct cpufreq_policy *policy; - unsigned int max_load = 0; - unsigned int ignore_nice; - unsigned int j; - - if (dbs_data->cdata->governor == GOV_ONDEMAND) - ignore_nice = od_tuners->ignore_nice_load; - else - ignore_nice = cs_tuners->ignore_nice_load; - - policy = cdbs->cur_policy; - - /* Get Absolute Load (in terms of freq for ondemand gov) */ - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_common_info *j_cdbs; - u64 cur_wall_time, cur_idle_time; - unsigned int idle_time, wall_time; - unsigned int load; - int io_busy = 0; - - j_cdbs = dbs_data->cdata->get_cpu_cdbs(j); - - /* - * For the purpose of ondemand, waiting for disk IO is - * an indication that you're performance critical, and - * not that the system is actually idle. So do not add - * the iowait time to the cpu idle time. - */ - if (dbs_data->cdata->governor == GOV_ONDEMAND) - io_busy = od_tuners->io_is_busy; - cur_idle_time = get_cpu_idle_time(j, &cur_wall_time, io_busy); - - wall_time = (unsigned int) - (cur_wall_time - j_cdbs->prev_cpu_wall); - j_cdbs->prev_cpu_wall = cur_wall_time; - - idle_time = (unsigned int) - (cur_idle_time - j_cdbs->prev_cpu_idle); - j_cdbs->prev_cpu_idle = cur_idle_time; - - if (ignore_nice) { - u64 cur_nice; - unsigned long cur_nice_jiffies; - - cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] - - cdbs->prev_cpu_nice; - /* - * Assumption: nice time between sampling periods will - * be less than 2^32 jiffies for 32 bit sys - */ - cur_nice_jiffies = (unsigned long) - cputime64_to_jiffies64(cur_nice); - - cdbs->prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - idle_time += jiffies_to_usecs(cur_nice_jiffies); - } - - if (unlikely(!wall_time || wall_time < idle_time)) - continue; - - load = 100 * (wall_time - idle_time) / wall_time; - - if (dbs_data->cdata->governor == GOV_ONDEMAND) { - int freq_avg = __cpufreq_driver_getavg(policy, j); - if (freq_avg <= 0) - freq_avg = policy->cur; - - load *= freq_avg; - } - - if (load > max_load) - max_load = load; - } - - dbs_data->cdata->gov_check_cpu(cpu, max_load); -} -EXPORT_SYMBOL_GPL(dbs_check_cpu); - -static inline void __gov_queue_work(int cpu, struct dbs_data *dbs_data, - unsigned int delay) -{ - struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); - - schedule_delayed_work_on(cpu, &cdbs->work, delay); -} - -void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, - unsigned int delay, bool all_cpus) -{ - int i; - - if (!policy->governor_enabled) - return; - - if (!all_cpus) { - __gov_queue_work(smp_processor_id(), dbs_data, delay); - } else { - for_each_cpu(i, policy->cpus) - __gov_queue_work(i, dbs_data, delay); - } -} -EXPORT_SYMBOL_GPL(gov_queue_work); - -static inline void gov_cancel_work(struct dbs_data *dbs_data, - struct cpufreq_policy *policy) -{ - struct cpu_dbs_common_info *cdbs; - int i; - - for_each_cpu(i, policy->cpus) { - cdbs = dbs_data->cdata->get_cpu_cdbs(i); - cancel_delayed_work_sync(&cdbs->work); - } -} - -/* Will return if we need to evaluate cpu load again or not */ -bool need_load_eval(struct cpu_dbs_common_info *cdbs, - unsigned int sampling_rate) -{ - if (policy_is_shared(cdbs->cur_policy)) { - ktime_t time_now = ktime_get(); - s64 delta_us = ktime_us_delta(time_now, cdbs->time_stamp); - - /* Do nothing if we recently have sampled */ - if (delta_us < (s64)(sampling_rate / 2)) - return false; - else - cdbs->time_stamp = time_now; - } - - return true; -} -EXPORT_SYMBOL_GPL(need_load_eval); - -static void set_sampling_rate(struct dbs_data *dbs_data, - unsigned int sampling_rate) -{ - if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { - struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; - cs_tuners->sampling_rate = sampling_rate; - } else { - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - od_tuners->sampling_rate = sampling_rate; - } -} - -int cpufreq_governor_dbs(struct cpufreq_policy *policy, - struct common_dbs_data *cdata, unsigned int event) -{ - struct dbs_data *dbs_data; - struct od_cpu_dbs_info_s *od_dbs_info = NULL; - struct cs_cpu_dbs_info_s *cs_dbs_info = NULL; - struct od_ops *od_ops = NULL; - struct od_dbs_tuners *od_tuners = NULL; - struct cs_dbs_tuners *cs_tuners = NULL; - struct cpu_dbs_common_info *cpu_cdbs; - unsigned int sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; - int io_busy = 0; - int rc; - - if (have_governor_per_policy()) - dbs_data = policy->governor_data; - else - dbs_data = cdata->gdbs_data; - - WARN_ON(!dbs_data && (event != CPUFREQ_GOV_POLICY_INIT)); - - switch (event) { - case CPUFREQ_GOV_POLICY_INIT: - if (have_governor_per_policy()) { - WARN_ON(dbs_data); - } else if (dbs_data) { - dbs_data->usage_count++; - policy->governor_data = dbs_data; - return 0; - } - - dbs_data = kzalloc(sizeof(*dbs_data), GFP_KERNEL); - if (!dbs_data) { - pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__); - return -ENOMEM; - } - - dbs_data->cdata = cdata; - dbs_data->usage_count = 1; - rc = cdata->init(dbs_data); - if (rc) { - pr_err("%s: POLICY_INIT: init() failed\n", __func__); - kfree(dbs_data); - return rc; - } - - rc = sysfs_create_group(get_governor_parent_kobj(policy), - get_sysfs_attr(dbs_data)); - if (rc) { - cdata->exit(dbs_data); - kfree(dbs_data); - return rc; - } - - policy->governor_data = dbs_data; - - /* policy latency is in nS. Convert it to uS first */ - latency = policy->cpuinfo.transition_latency / 1000; - if (latency == 0) - latency = 1; - - /* Bring kernel and HW constraints together */ - dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate, - MIN_LATENCY_MULTIPLIER * latency); - set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate, - latency * LATENCY_MULTIPLIER)); - - if ((cdata->governor == GOV_CONSERVATIVE) && - (!policy->governor->initialized)) { - struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; - - cpufreq_register_notifier(cs_ops->notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - - if (!have_governor_per_policy()) - cdata->gdbs_data = dbs_data; - - return 0; - case CPUFREQ_GOV_POLICY_EXIT: - if (!--dbs_data->usage_count) { - sysfs_remove_group(get_governor_parent_kobj(policy), - get_sysfs_attr(dbs_data)); - - if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) && - (policy->governor->initialized == 1)) { - struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; - - cpufreq_unregister_notifier(cs_ops->notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - - cdata->exit(dbs_data); - kfree(dbs_data); - cdata->gdbs_data = NULL; - } - - policy->governor_data = NULL; - return 0; - } - - cpu_cdbs = dbs_data->cdata->get_cpu_cdbs(cpu); - - if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { - cs_tuners = dbs_data->tuners; - cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu); - sampling_rate = cs_tuners->sampling_rate; - ignore_nice = cs_tuners->ignore_nice_load; - } else { - od_tuners = dbs_data->tuners; - od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu); - sampling_rate = od_tuners->sampling_rate; - ignore_nice = od_tuners->ignore_nice_load; - od_ops = dbs_data->cdata->gov_ops; - io_busy = od_tuners->io_is_busy; - } - - switch (event) { - case CPUFREQ_GOV_START: - if (!policy->cur) - return -EINVAL; - - mutex_lock(&dbs_data->mutex); - - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_common_info *j_cdbs = - dbs_data->cdata->get_cpu_cdbs(j); - - j_cdbs->cpu = j; - j_cdbs->cur_policy = policy; - j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, - &j_cdbs->prev_cpu_wall, io_busy); - if (ignore_nice) - j_cdbs->prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - - mutex_init(&j_cdbs->timer_mutex); - INIT_DELAYED_WORK_DEFERRABLE(&j_cdbs->work, - dbs_data->cdata->gov_dbs_timer); - } - - /* - * conservative does not implement micro like ondemand - * governor, thus we are bound to jiffes/HZ - */ - if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { - cs_dbs_info->down_skip = 0; - cs_dbs_info->enable = 1; - cs_dbs_info->requested_freq = policy->cur; - } else { - od_dbs_info->rate_mult = 1; - od_dbs_info->sample_type = OD_NORMAL_SAMPLE; - od_ops->powersave_bias_init_cpu(cpu); - } - - mutex_unlock(&dbs_data->mutex); - - /* Initiate timer time stamp */ - cpu_cdbs->time_stamp = ktime_get(); - - gov_queue_work(dbs_data, policy, - delay_for_sampling_rate(sampling_rate), true); - break; - - case CPUFREQ_GOV_STOP: - if (dbs_data->cdata->governor == GOV_CONSERVATIVE) - cs_dbs_info->enable = 0; - - gov_cancel_work(dbs_data, policy); - - mutex_lock(&dbs_data->mutex); - mutex_destroy(&cpu_cdbs->timer_mutex); - cpu_cdbs->cur_policy = NULL; - - mutex_unlock(&dbs_data->mutex); - - break; - - case CPUFREQ_GOV_LIMITS: - mutex_lock(&cpu_cdbs->timer_mutex); - if (policy->max < cpu_cdbs->cur_policy->cur) - __cpufreq_driver_target(cpu_cdbs->cur_policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > cpu_cdbs->cur_policy->cur) - __cpufreq_driver_target(cpu_cdbs->cur_policy, - policy->min, CPUFREQ_RELATION_L); - dbs_check_cpu(dbs_data, cpu); - mutex_unlock(&cpu_cdbs->timer_mutex); - break; - } - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_governor_dbs); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_governor.h b/linux-3.4/drivers/cpufreq.new/cpufreq_governor.h deleted file mode 100755 index c501ca83..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_governor.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_governor.h - * - * Header file for CPUFreq governors common code - * - * Copyright (C) 2001 Russell King - * (C) 2003 Venkatesh Pallipadi . - * (C) 2003 Jun Nakajima - * (C) 2009 Alexander Clouter - * (c) 2012 Viresh Kumar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _CPUFREQ_GOVERNOR_H -#define _CPUFREQ_GOVERNOR_H - -#include -#include -#include -#include -#include - -/* - * The polling frequency depends on the capability of the processor. Default - * polling frequency is 1000 times the transition latency of the processor. The - * governor will work on any processor with transition latency <= 10mS, using - * appropriate sampling rate. - * - * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) - * this governor will not work. All times here are in uS. - */ -#define MIN_SAMPLING_RATE_RATIO (2) -#define LATENCY_MULTIPLIER (1000) -#define MIN_LATENCY_MULTIPLIER (20) -#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) - -/* Ondemand Sampling types */ -enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; - -/* - * Macro for creating governors sysfs routines - * - * - gov_sys: One governor instance per whole system - * - gov_pol: One governor instance per policy - */ - -/* Create attributes */ -#define gov_sys_attr_ro(_name) \ -static struct global_attr _name##_gov_sys = \ -__ATTR(_name, 0444, show_##_name##_gov_sys, NULL) - -#define gov_sys_attr_rw(_name) \ -static struct global_attr _name##_gov_sys = \ -__ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys) - -#define gov_pol_attr_ro(_name) \ -static struct freq_attr _name##_gov_pol = \ -__ATTR(_name, 0444, show_##_name##_gov_pol, NULL) - -#define gov_pol_attr_rw(_name) \ -static struct freq_attr _name##_gov_pol = \ -__ATTR(_name, 0644, show_##_name##_gov_pol, store_##_name##_gov_pol) - -#define gov_sys_pol_attr_rw(_name) \ - gov_sys_attr_rw(_name); \ - gov_pol_attr_rw(_name) - -#define gov_sys_pol_attr_ro(_name) \ - gov_sys_attr_ro(_name); \ - gov_pol_attr_ro(_name) - -/* Create show/store routines */ -#define show_one(_gov, file_name) \ -static ssize_t show_##file_name##_gov_sys \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - struct _gov##_dbs_tuners *tuners = _gov##_dbs_cdata.gdbs_data->tuners; \ - return sprintf(buf, "%u\n", tuners->file_name); \ -} \ - \ -static ssize_t show_##file_name##_gov_pol \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - struct dbs_data *dbs_data = policy->governor_data; \ - struct _gov##_dbs_tuners *tuners = dbs_data->tuners; \ - return sprintf(buf, "%u\n", tuners->file_name); \ -} - -#define store_one(_gov, file_name) \ -static ssize_t store_##file_name##_gov_sys \ -(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) \ -{ \ - struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ - return store_##file_name(dbs_data, buf, count); \ -} \ - \ -static ssize_t store_##file_name##_gov_pol \ -(struct cpufreq_policy *policy, const char *buf, size_t count) \ -{ \ - struct dbs_data *dbs_data = policy->governor_data; \ - return store_##file_name(dbs_data, buf, count); \ -} - -#define show_store_one(_gov, file_name) \ -show_one(_gov, file_name); \ -store_one(_gov, file_name) - -/* create helper routines */ -#define define_get_cpu_dbs_routines(_dbs_info) \ -static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu) \ -{ \ - return &per_cpu(_dbs_info, cpu).cdbs; \ -} \ - \ -static void *get_cpu_dbs_info_s(int cpu) \ -{ \ - return &per_cpu(_dbs_info, cpu); \ -} - -/* - * Abbreviations: - * dbs: used as a shortform for demand based switching It helps to keep variable - * names smaller, simpler - * cdbs: common dbs - * od_*: On-demand governor - * cs_*: Conservative governor - */ - -/* Per cpu structures */ -struct cpu_dbs_common_info { - int cpu; - u64 prev_cpu_idle; - u64 prev_cpu_wall; - u64 prev_cpu_nice; - struct cpufreq_policy *cur_policy; - struct delayed_work work; - /* - * percpu mutex that serializes governor limit change with gov_dbs_timer - * invocation. We do not want gov_dbs_timer to run when user is changing - * the governor or limits. - */ - struct mutex timer_mutex; - ktime_t time_stamp; -}; - -struct od_cpu_dbs_info_s { - struct cpu_dbs_common_info cdbs; - struct cpufreq_frequency_table *freq_table; - unsigned int freq_lo; - unsigned int freq_lo_jiffies; - unsigned int freq_hi_jiffies; - unsigned int rate_mult; - unsigned int sample_type:1; -}; - -struct cs_cpu_dbs_info_s { - struct cpu_dbs_common_info cdbs; - unsigned int down_skip; - unsigned int requested_freq; - unsigned int enable:1; -}; - -/* Per policy Governers sysfs tunables */ -struct od_dbs_tuners { - unsigned int ignore_nice_load; - unsigned int sampling_rate; - unsigned int sampling_down_factor; - unsigned int up_threshold; - unsigned int adj_up_threshold; - unsigned int powersave_bias; - unsigned int io_is_busy; -}; - -struct cs_dbs_tuners { - unsigned int ignore_nice_load; - unsigned int sampling_rate; - unsigned int sampling_down_factor; - unsigned int up_threshold; - unsigned int down_threshold; - unsigned int freq_step; -}; - -/* Common Governer data across policies */ -struct dbs_data; -struct common_dbs_data { - /* Common across governors */ - #define GOV_ONDEMAND 0 - #define GOV_CONSERVATIVE 1 - int governor; - struct attribute_group *attr_group_gov_sys; /* one governor - system */ - struct attribute_group *attr_group_gov_pol; /* one governor - policy */ - - /* Common data for platforms that don't set have_governor_per_policy */ - struct dbs_data *gdbs_data; - - struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); - void *(*get_cpu_dbs_info_s)(int cpu); - void (*gov_dbs_timer)(struct work_struct *work); - void (*gov_check_cpu)(int cpu, unsigned int load); - int (*init)(struct dbs_data *dbs_data); - void (*exit)(struct dbs_data *dbs_data); - - /* Governor specific ops, see below */ - void *gov_ops; -}; - -/* Governer Per policy data */ -struct dbs_data { - struct common_dbs_data *cdata; - unsigned int min_sampling_rate; - int usage_count; - void *tuners; - - /* dbs_mutex protects dbs_enable in governor start/stop */ - struct mutex mutex; -}; - -/* Governor specific ops, will be passed to dbs_data->gov_ops */ -struct od_ops { - void (*powersave_bias_init_cpu)(int cpu); - unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, - unsigned int freq_next, unsigned int relation); - void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq); -}; - -struct cs_ops { - struct notifier_block *notifier_block; -}; - -static inline int delay_for_sampling_rate(unsigned int sampling_rate) -{ - int delay = usecs_to_jiffies(sampling_rate); - - /* We want all CPUs to do sampling nearly on same jiffy */ - if (num_online_cpus() > 1) - delay -= jiffies % delay; - - return delay; -} - -#define declare_show_sampling_rate_min(_gov) \ -static ssize_t show_sampling_rate_min_gov_sys \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data; \ - return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ -} \ - \ -static ssize_t show_sampling_rate_min_gov_pol \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - struct dbs_data *dbs_data = policy->governor_data; \ - return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ -} - -void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); -bool need_load_eval(struct cpu_dbs_common_info *cdbs, - unsigned int sampling_rate); -int cpufreq_governor_dbs(struct cpufreq_policy *policy, - struct common_dbs_data *cdata, unsigned int event); -void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, - unsigned int delay, bool all_cpus); -void od_register_powersave_bias_handler(unsigned int (*f) - (struct cpufreq_policy *, unsigned int, unsigned int), - unsigned int powersave_bias); -void od_unregister_powersave_bias_handler(void); -#endif /* _CPUFREQ_GOVERNOR_H */ diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_iks.c b/linux-3.4/drivers/cpufreq.new/cpufreq_iks.c deleted file mode 100755 index 214d839a..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_iks.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_iks.c - * - * Copyright (C) 2013 Allwinnertech, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - * Author: Kevin.z.m (kevin@allwinnertech.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct cpu_dbs_info_s { - int cpu; /* current cpu number */ - u64 prev_cpu_idle; /* previous idle time statistic */ - u64 prev_cpu_wall; /* previous total time stat */ - struct cpufreq_policy *cur_policy; - struct cpufreq_frequency_table *freq_table; - struct delayed_work work; /* work queue for check loading */ - struct mutex timer_mutex; /* semaphore for protection */ - unsigned int load; /* load of this cpu (%) */ - unsigned int load_freq; /* frequency for system needed */ - unsigned int target_freq; /* frequency for setting to hw */ - unsigned int cur_freq; /* frequency of current cpu */ - unsigned int max_freq; /* max frequency of current cpu */ - bool is_little; /* flag to mark if current cpu is little or big */ -}; - - -#define DEF_SAMPLING_RATE (50000) /* check cpu frequency sample rate is 50ms */ -#define DEF_IOWAIT_IS_BUSY (1) /* iowait is think as cpu busy in default */ -#define DEF_DVFS_DEBUG (1) -#define DEF_LITTLE_MAX_FREQ (500000) -#define DEF_BIG_MIN_FREQ (600000) -#define DEF_LITTLE_TRY_UP_THRESHOLD (80) -#define DEF_BIG_2_LITTLE_THRESHOLD (60) -#define DEF_LITTLE_2_BIG_THRESHOLD (95) -#define DEF_CORE_UP_THRESHOLD (80) /* increase cpu frequency, if the loading is higher */ -#define DEF_CORE_DOWN_THRESHOLD (30) -#define DEF_LITTLE_2_BIG_TARGET (800000) -#define DEF_BIG_2_LITTLE_TARGET (300000) -#define DEF_INPUT_PULSE (80) /* pulse cpu upper 80% than max frequency of little */ - -static struct dbs_tuners { - unsigned int sampling_rate; /* dvfs sample rate */ - unsigned int io_is_busy; /* flag to mark if iowait calculate as cpu busy */ - unsigned int dvfs_debug; /* dvfs debug flag, print dbs information */ - - unsigned int little_max_freq; /* max frequency of the little cpu */ - unsigned int big_min_freq; /* min frequency of the max cpu */ - unsigned int little_try_up_threshold; - /* if loading is higher, need check if core up or switch to big */ - unsigned int little_2_big_threshold; - /* if loading is higher, switch to big directly */ - unsigned int big_2_little_threshold; - /* if loading is lower, switch to little directly */ - unsigned int core_up_threshold; /* if all cpus's loading is higer, try to up core */ - unsigned int core_down_threshold; - /* if more than 2 cores' loading is lower, try to down core */ - unsigned int little_2_big_target; - /* taget frequency of a core, when it switch from little to big */ - unsigned int big_2_little_target; - /* taget frequency of a core, when it switch from little to big */ - unsigned int boost; /* boost mode, cpu lock to the max frequency, but not lock core */ - unsigned int pulse; /* boost cpu to the pulse_ratio * maxfreq a pulse_duration period */ - unsigned int pulse_duration; /* pulse period */ - unsigned int pulse_ratio; /* pulse frequency ratio */ - unsigned int max_power; /* max power mode, lock all cores to the max frequency */ -} dbs_tuners_ins = { - .sampling_rate = DEF_SAMPLING_RATE, - .io_is_busy = DEF_IOWAIT_IS_BUSY, - .dvfs_debug = DEF_DVFS_DEBUG, - .little_max_freq = DEF_LITTLE_MAX_FREQ, - .big_min_freq = DEF_BIG_MIN_FREQ, - .little_try_up_threshold = DEF_LITTLE_TRY_UP_THRESHOLD, - .little_2_big_threshold = DEF_LITTLE_2_BIG_THRESHOLD, - .big_2_little_threshold = DEF_BIG_2_LITTLE_THRESHOLD, - .core_up_threshold = DEF_CORE_UP_THRESHOLD, - .core_down_threshold = DEF_CORE_DOWN_THRESHOLD, - .little_2_big_target = DEF_LITTLE_2_BIG_TARGET, - .big_2_little_target = DEF_BIG_2_LITTLE_TARGET, - .boost = 0, - .pulse = 0, - .pulse_ratio = 80, - .pulse_duration = 50, - .max_power = 0, -}; - - -static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info); -static struct task_struct *power_change_task; -static DEFINE_MUTEX(dbs_mutex); -static unsigned int dbs_enable; /* number of CPUs using this policy */ -static struct cpumask core_down_mask; -static struct cpumask core_up_mask; -static struct cpumask speed_change_mask; -static spinlock_t cpumask_lock; -static unsigned long long pulse_start; - -#define EVENT_INPUT_DEVICE (1<<0) -#define EVENT_USER_BOOST (1<<1) -#define EVENT_USER_PULSE (1<<2) -#define EVENT_MAX_POWER (1<<3) -static unsigned long cpufreq_event_mask; - - -/* cpufreq_pegasusq Governor Tunables */ -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ -} - -show_one(sampling_rate, sampling_rate); -show_one(io_is_busy, io_is_busy); -show_one(dvfs_debug, dvfs_debug); -show_one(little_max_freq, little_max_freq); -show_one(big_min_freq, big_min_freq); -show_one(little_try_up_threshold, little_try_up_threshold); -show_one(little_2_big_threshold, little_2_big_threshold); -show_one(big_2_little_threshold, big_2_little_threshold); -show_one(core_up_threshold, core_up_threshold); -show_one(core_down_threshold, core_down_threshold); -show_one(little_2_big_target, little_2_big_target); -show_one(big_2_little_target, big_2_little_target); -show_one(boost, boost); -show_one(pulse, pulse); -show_one(pulse_ratio, pulse_ratio); -show_one(pulse_duration, pulse_duration); -show_one(max_power, max_power); - -static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.sampling_rate = input; - return count; -} -static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.io_is_busy = !!input; - return count; -} -static ssize_t store_dvfs_debug(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.dvfs_debug = !!input; - return count; -} -static ssize_t store_little_max_freq(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input > dbs_tuners_ins.big_min_freq)) - return -EINVAL; - dbs_tuners_ins.little_max_freq = input; - return count; -} -static ssize_t store_big_min_freq(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < dbs_tuners_ins.little_max_freq)) - return -EINVAL; - dbs_tuners_ins.big_min_freq = input; - return count; -} -static ssize_t store_little_try_up_threshold(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 30) || (input > 100)) - return -EINVAL; - dbs_tuners_ins.little_try_up_threshold = input; - return count; -} -static ssize_t store_little_2_big_threshold(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 50) || (input > 100)) - return -EINVAL; - dbs_tuners_ins.little_2_big_threshold = input; - return count; -} -static ssize_t store_big_2_little_threshold(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input > 100)) - return -EINVAL; - dbs_tuners_ins.big_2_little_threshold = input; - return count; -} -static ssize_t store_core_up_threshold(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 30) || (input > 100)) - return -EINVAL; - dbs_tuners_ins.core_up_threshold = input; - return count; -} -static ssize_t store_core_down_threshold(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 50)) - return -EINVAL; - dbs_tuners_ins.core_down_threshold = input; - return count; -} -static ssize_t store_little_2_big_target(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < dbs_tuners_ins.big_min_freq)) - return -EINVAL; - dbs_tuners_ins.little_2_big_target = input; - return count; -} -static ssize_t store_big_2_little_target(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input > dbs_tuners_ins.little_max_freq)) - return -EINVAL; - dbs_tuners_ins.big_2_little_target = input; - return count; -} - -static ssize_t store_boost(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - unsigned long flags; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.boost = !!input; - - spin_lock_irqsave(&cpumask_lock, flags); - cpufreq_event_mask |= EVENT_USER_BOOST; - spin_unlock_irqrestore(&cpumask_lock, flags); - - wake_up_process(power_change_task); - return count; -} -static ssize_t store_pulse(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - unsigned long flags; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - if(input) { - dbs_tuners_ins.pulse = 0; - spin_lock_irqsave(&cpumask_lock, flags); - cpufreq_event_mask |= EVENT_USER_PULSE; - spin_unlock_irqrestore(&cpumask_lock, flags); - wake_up_process(power_change_task); - } - return count; -} -static ssize_t store_pulse_ratio(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 10) || (input > 100)) - return -EINVAL; - dbs_tuners_ins.pulse_ratio = input; - return count; -} -static ssize_t store_pulse_duration(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if ((ret != 1) || (input < 50) || (input > 5000)) - return -EINVAL; - dbs_tuners_ins.pulse_duration = input; - return count; -} -static ssize_t store_max_power(struct kobject *a, struct attribute *b, const char *buf, size_t count) -{ - unsigned int input; - int ret; - unsigned long flags; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - dbs_tuners_ins.max_power = !!input; - spin_lock_irqsave(&cpumask_lock, flags); - cpufreq_event_mask |= EVENT_MAX_POWER; - spin_unlock_irqrestore(&cpumask_lock, flags); - - wake_up_process(power_change_task); - return count; -} - -define_one_global_rw(sampling_rate); -define_one_global_rw(io_is_busy); -define_one_global_rw(dvfs_debug); -define_one_global_rw(little_max_freq); -define_one_global_rw(big_min_freq); -define_one_global_rw(little_try_up_threshold); -define_one_global_rw(little_2_big_threshold); -define_one_global_rw(big_2_little_threshold); -define_one_global_rw(core_up_threshold); -define_one_global_rw(core_down_threshold); -define_one_global_rw(little_2_big_target); -define_one_global_rw(big_2_little_target); -define_one_global_rw(boost); -define_one_global_rw(pulse); -define_one_global_rw(pulse_ratio); -define_one_global_rw(pulse_duration); -define_one_global_rw(max_power); - -static struct attribute *dbs_attributes[] = { - &sampling_rate.attr, - &io_is_busy.attr, - &dvfs_debug.attr, - &little_max_freq.attr, - &big_min_freq.attr, - &little_try_up_threshold.attr, - &little_2_big_threshold.attr, - &big_2_little_threshold.attr, - &core_up_threshold.attr, - &core_down_threshold.attr, - &little_2_big_target.attr, - &big_2_little_target.attr, - &boost.attr, - &pulse.attr, - &pulse_ratio.attr, - &pulse_duration.attr, - &max_power.attr, - NULL -}; - -static struct attribute_group dbs_attr_group = { - .attrs = dbs_attributes, - .name = "iks", -}; - -unsigned int __cal_little_freq(int curfreq, int load, int maxfreq) -{ - unsigned int target; - - /* if current loading is higher than 90%, up frequency */ - if(load > 90) { - if(curfreq < 100000) - target = min(200000, maxfreq); - else if(curfreq < 200000) - target = min(300000, maxfreq); - else if(curfreq < 300000) - target = min(400000, maxfreq); - else if(curfreq < 400000) - target = min(500000, maxfreq); - else - target = maxfreq; - } else if(load > 60){ - /* if current loading is 60%~90%, keep it */ - target = curfreq; - } else { - /* if current loading is lower than 60%, scale down */ - target = min(curfreq * load / 70, maxfreq); - } - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s :cur:%d, load:%d, target:%d\n", __func__, curfreq, load, target); - } - - return target; -} - -unsigned int __cal_big_freq(int curfreq, int load, int maxfreq) -{ - unsigned int target; - - if(load > 90) { - if(curfreq < 800000) - target = min(1000000, maxfreq); - else if(curfreq < 1000000) - target = min(1200000, maxfreq); - else if(curfreq < 1200000) - target = min(1600000, maxfreq); - else - target = maxfreq; - } else if(load > 60){ - target = curfreq; - } else { - target = min(curfreq * load / 70, maxfreq); - } - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s :cur:%d, load:%d, target:%d\n", __func__, curfreq, load, target); - } - - return target; -} - -static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) -{ - struct cpufreq_policy *policy; - unsigned int cpu, loading, min_loading = 100; - struct cpu_dbs_info_s *j_dbs_info; - int little_2_big = -1, big_2_little = -1, request_up = 0, request_down = 0; - int heavy_load_core_cnt = 0, light_load_core_cnt = 0, light_load_core = -1; - unsigned long flags; - - policy = this_dbs_info->cur_policy; - - /* step 1: calculate per cpu loading */ - for_each_cpu(cpu, policy->cpus) { - u64 cur_wall_time, cur_idle_time; - u64 prev_wall_time, prev_idle_time; - unsigned int idle_time, wall_time; - - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - - prev_wall_time = j_dbs_info->prev_cpu_wall; - prev_idle_time = j_dbs_info->prev_cpu_idle; - - cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, dbs_tuners_ins.io_is_busy); - - wall_time = cur_wall_time - prev_wall_time; - j_dbs_info->prev_cpu_wall = cur_wall_time; - idle_time = cur_idle_time - prev_idle_time; - j_dbs_info->prev_cpu_idle = cur_idle_time; - - if (wall_time && (wall_time > idle_time)) - j_dbs_info->load = 100 * (wall_time - idle_time) / wall_time; - else - j_dbs_info->load = 0; - - j_dbs_info->load_freq = j_dbs_info->cur_freq * j_dbs_info->load; - - loading = j_dbs_info->load_freq / j_dbs_info->max_freq; - if(loading > dbs_tuners_ins.core_up_threshold) - heavy_load_core_cnt ++; - else if(j_dbs_info->is_little && loading < dbs_tuners_ins.core_down_threshold) { - light_load_core_cnt ++; - if((loading < min_loading) && (cpu != 0)) { - min_loading = loading; - light_load_core = cpu; - } - } - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step1: cpu(%d:%s) load:%d curfreq:%d maxfreq:%d loading:%d " - "(wall:%u,idle:%u)\n", __func__, cpu, j_dbs_info->is_little? - "little":"big", j_dbs_info->load, j_dbs_info->cur_freq, - j_dbs_info->max_freq, loading, wall_time, idle_time); - } - } - - /* skip frequency and cores check if current is max power mode */ - if(dbs_tuners_ins.max_power) { - goto __skip_core_check; - } - - if(dbs_tuners_ins.boost) { - for_each_cpu(cpu, policy->cpus) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = cpufreq_quick_get_max(0); - } - goto __skip_target_cal; - } - - /* step 2: calculate per cpu target frequency */ - for_each_cpu(cpu, policy->cpus) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - - if(this_dbs_info->is_little) { - /* check if little cpu need plug in or switch to big */ - if(j_dbs_info->load_freq >= dbs_tuners_ins.little_max_freq * - dbs_tuners_ins.little_2_big_threshold) { - /* loading of little cpu is too high, switch to big directly */ - little_2_big = cpu; - } else if(j_dbs_info->load_freq >= dbs_tuners_ins.little_max_freq * - dbs_tuners_ins.little_try_up_threshold) { - /* loading of little cpu is very high, - * check if need core up or switch to big - */ - int i, switch_flag = 0; - struct cpu_dbs_info_s *i_dbs_info; - - /* check if another little cpu's loading is too low, - * if so, we think the load can't be balance, try to - * swtich to a big cpu - */ - for_each_cpu(i, policy->cpus) { - if(i == cpu) - continue; - i_dbs_info = &per_cpu(od_cpu_dbs_info, i); - if(i_dbs_info->is_little && (i_dbs_info->load_freq < - dbs_tuners_ins.little_max_freq * dbs_tuners_ins.core_down_threshold)) { - little_2_big = (little_2_big < 0)? cpu : little_2_big; - switch_flag = 1; - break; - } - } - - /* if all load of every little cpu is not very high, we think the load is balanced, - * try to check if we can enable another little cpu, if all cpu online, try to switch - * to a big - */ - if(!switch_flag) { - if(num_online_cpus() < num_possible_cpus()) { - request_up++; - } else { - if(little_2_big < 0) - little_2_big = cpu; - else - j_dbs_info->target_freq = dbs_tuners_ins.little_max_freq; - } - } - } else { - /* adjust the frquency to a proper value */ - j_dbs_info->target_freq = __cal_little_freq(j_dbs_info->cur_freq, - j_dbs_info->load, dbs_tuners_ins.little_max_freq); - } - } - else { - /* current cpu is big, check if need switch to little */ - if(j_dbs_info->load_freq > dbs_tuners_ins.little_max_freq * - dbs_tuners_ins.big_2_little_threshold) { - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - j_dbs_info->target_freq = max(dbs_tuners_ins.big_min_freq, - __cal_big_freq(j_dbs_info->cur_freq, j_dbs_info->load, policy->max)); - } else { - if(big_2_little < 0) { - big_2_little = cpu; - j_dbs_info->target_freq = dbs_tuners_ins.big_2_little_target; - } - else - j_dbs_info->target_freq = max(dbs_tuners_ins.big_min_freq, - __cal_big_freq(j_dbs_info->cur_freq, j_dbs_info->load, policy->max)); - } - } - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step2: cpu(%d) target:%d\n", __func__, cpu, j_dbs_info->target_freq); - } - } - j_dbs_info = &per_cpu(od_cpu_dbs_info, little_2_big); - j_dbs_info->target_freq = dbs_tuners_ins.little_2_big_target; - - __skip_target_cal: - /* step 3: check if need plug-in or plug-out core */ - if(heavy_load_core_cnt >= num_online_cpus()) - request_up++; - else if(light_load_core_cnt > 1) - request_down++; - if(request_up > request_down) { - for_each_cpu_not(cpu, cpu_online_mask) { - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_or(&core_up_mask, cpumask_of(cpu), &core_up_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step3: core up:%d\n", __func__, cpu); - } - - break; - } - } else if(request_up < request_down) { - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_or(&core_down_mask, cpumask_of(light_load_core), &core_down_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step3: core down:%d\n", __func__, cpu); - } - } - - __skip_core_check: - /* step 4: try to wake up power change task to process the change */ - spin_lock_irqsave(&cpumask_lock, flags); - cpumask_or(&speed_change_mask, policy->cpus, &speed_change_mask); - spin_unlock_irqrestore(&cpumask_lock, flags); - wake_up_process(power_change_task); -} - - -static int cpufreq_iks_power_change_task(void *data) -{ - unsigned int little_cpu_freq, big_cpu_freq, cpu; - struct cpu_dbs_info_s *j_dbs_info; - struct cpufreq_policy *policy; - struct cpumask tmp_core_up_mask, tmp_core_down_mask, tmp_speed_change_mask; - struct cpumask tmp_little_cores, tmp_big_cores; - unsigned long flags, tmp_event; - - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irqsave(&cpumask_lock, flags); - if(cpumask_empty(&speed_change_mask) && cpumask_empty(&core_up_mask) - && cpumask_empty(&core_down_mask) && !cpufreq_event_mask) { - spin_unlock_irqrestore(&cpumask_lock, flags); - schedule_timeout(10*HZ); - if (kthread_should_stop()) - break; - continue; - } - - set_current_state(TASK_RUNNING); - tmp_core_up_mask = core_up_mask; - cpumask_clear(&core_up_mask); - tmp_core_down_mask = core_down_mask; - cpumask_clear(&core_down_mask); - tmp_speed_change_mask = speed_change_mask; - cpumask_clear(&speed_change_mask); - tmp_event = cpufreq_event_mask; - cpufreq_event_mask = 0; - spin_unlock_irqrestore(&cpumask_lock, flags); - - cpumask_clear(&tmp_little_cores); - cpumask_clear(&tmp_big_cores); - - /* check if current is under max power mode */ - if(dbs_tuners_ins.max_power) { - /* up all cores */ - cpumask_clear(&tmp_core_down_mask); - cpumask_copy(&tmp_core_up_mask, cpu_possible_mask); - /* set every core to the max frequency */ - cpumask_copy(&tmp_speed_change_mask, cpu_possible_mask); - little_cpu_freq = cpufreq_quick_get_max(0); - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = little_cpu_freq; - } - goto __process_power_change; - } - if(dbs_tuners_ins.boost) { - cpumask_copy(&tmp_speed_change_mask, cpu_online_mask); - little_cpu_freq = cpufreq_quick_get_max(0); - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = little_cpu_freq; - } - goto __process_power_change; - } - - if(tmp_event & EVENT_INPUT_DEVICE) { - /* scaling cpu frequency upper than 80% of little's max frequency */ - cpumask_copy(&tmp_speed_change_mask, cpu_online_mask); - little_cpu_freq = (dbs_tuners_ins.little_max_freq * DEF_INPUT_PULSE)/100; - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = max(little_cpu_freq, j_dbs_info->target_freq); - } - } - if(tmp_event & EVENT_USER_PULSE) { - cpumask_copy(&tmp_speed_change_mask, cpu_online_mask); - little_cpu_freq = (cpufreq_quick_get_max(0) * dbs_tuners_ins.pulse_ratio) / 100; - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = max(little_cpu_freq, j_dbs_info->target_freq); - } - pulse_start = sched_clock(); - } else if(pulse_start) { - unsigned long long now = sched_clock(); - if((now>pulse_start) && (((now - pulse_start) >> 20) > dbs_tuners_ins.pulse_duration)) { - /* pulse time end */ - pulse_start = 0; - } - cpumask_copy(&tmp_speed_change_mask, cpu_online_mask); - little_cpu_freq = (cpufreq_quick_get_max(0) * dbs_tuners_ins.pulse_ratio) / 100; - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->target_freq = max(little_cpu_freq, j_dbs_info->target_freq); - } - } - - __process_power_change: - /* step 1: core up or core down */ - if(!cpumask_empty(&tmp_core_up_mask)) { - for_each_cpu(cpu, &tmp_core_up_mask) { - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step1: core up:%u\n", __func__, cpu); - } - if(!cpu_online(cpu)) - cpu_up(cpu); - } - } else if(!cpumask_empty(&tmp_core_down_mask)) { - cpumask_andnot(&tmp_speed_change_mask, &tmp_speed_change_mask, &tmp_core_down_mask); - for_each_cpu(cpu, &tmp_core_down_mask) { - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step1: core down:%u\n", __func__, cpu); - } - if(cpu_online(cpu)) - cpu_down(cpu); - } - } - - /* step 2: look up big and little frequency */ - little_cpu_freq = big_cpu_freq = 0; - for_each_cpu(cpu, &tmp_speed_change_mask) { - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - if(j_dbs_info->target_freq <= dbs_tuners_ins.little_max_freq) { - cpumask_or(&tmp_little_cores, cpumask_of(cpu), &tmp_little_cores); - j_dbs_info->is_little = true; - little_cpu_freq = max(little_cpu_freq, j_dbs_info->target_freq); - } else { - j_dbs_info->is_little = false; - cpumask_or(&tmp_big_cores, cpumask_of(cpu), &tmp_big_cores); - big_cpu_freq = max(big_cpu_freq, j_dbs_info->target_freq); - } - } - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step2: little freq:%d, big freq:%d\n", __func__, - little_cpu_freq, big_cpu_freq); - } - - /* step 3: set big and little frequency */ - if(!cpumask_empty(&tmp_little_cores)) { - for_each_cpu(cpu, &tmp_little_cores) { - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step3: scaling little(%d) to %d Khz\n", __func__, cpu, little_cpu_freq); - } - policy = cpufreq_cpu_get(cpu); - cpufreq_driver_target(policy, little_cpu_freq, CPUFREQ_RELATION_L); - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->cur_freq = cpufreq_get(cpu); - j_dbs_info->max_freq = dbs_tuners_ins.little_max_freq; - } - } - if(!cpumask_empty(&tmp_big_cores)) { - for_each_cpu(cpu, &tmp_big_cores) { - if(dbs_tuners_ins.dvfs_debug) { - printk("%s step3: scaling big(%d) to %d Khz\n", __func__, cpu, big_cpu_freq); - } - policy = cpufreq_cpu_get(cpu); - cpufreq_driver_target(policy, big_cpu_freq, CPUFREQ_RELATION_L); - j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - j_dbs_info->cur_freq = cpufreq_get(cpu); - j_dbs_info->max_freq = policy->max; - } - } - } - - return 0; -} - -static void do_dbs_timer(struct work_struct *work) -{ - struct cpu_dbs_info_s *dbs_info = container_of(work, struct cpu_dbs_info_s, work.work); - unsigned int cpu = dbs_info->cpu; - int delay; - - mutex_lock(&dbs_info->timer_mutex); - dbs_check_cpu(dbs_info); - delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - schedule_delayed_work_on(cpu, &dbs_info->work, delay); - mutex_unlock(&dbs_info->timer_mutex); -} - -static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) -{ - /* We want all CPUs to do sampling nearly on same jiffy */ - int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - if (num_online_cpus() > 1) - delay -= jiffies % delay; - - INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); - schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); -} - -static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) -{ - cancel_delayed_work_sync(&dbs_info->work); -} - -static int __cpuinit cpu_hotplug_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct cpu_dbs_info_s *j_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - j_dbs_info->prev_cpu_idle = get_cpu_idle_time(cpu, &j_dbs_info->prev_cpu_wall, dbs_tuners_ins.io_is_busy); - j_dbs_info->cur_freq = cpufreq_get(cpu); - if(j_dbs_info->cur_freq <= dbs_tuners_ins.little_max_freq) { - j_dbs_info->max_freq = dbs_tuners_ins.little_max_freq; - j_dbs_info->is_little = true; - } - else { - j_dbs_info->max_freq = policy->max; - j_dbs_info->is_little = false; - } - break; - - } - return NOTIFY_OK; -} - -static struct notifier_block __refdata cpu_hotplug_notifier = { - .notifier_call = cpu_hotplug_callback, -}; - - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -/* - * trigger cpu frequency to a high speed some when input event coming. - * such as key, ir, touchpannel for ex. , but skip gsensor. - */ -static void cpufreq_input_event(struct input_handle *handle, - unsigned int type, - unsigned int code, int value) -{ - unsigned long flags; - - if (type == EV_SYN && code == SYN_REPORT) { - spin_lock_irqsave(&cpumask_lock, flags); - cpufreq_event_mask |= EVENT_INPUT_DEVICE; - spin_unlock_irqrestore(&cpumask_lock, flags); - wake_up_process(power_change_task); - } -} - - -static int cpufreq_input_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "cpufreq_input"; - - error = input_register_handle(handle); - if (error) - goto err; - - error = input_open_device(handle); - if (error) - goto err_open; - - return 0; - -err_open: - input_unregister_handle(handle); -err: - kfree(handle); - return error; -} - -static void cpufreq_input_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id cpufreq_input_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = - BIT_MASK(ABS_MT_POSITION_X) | - BIT_MASK(ABS_MT_POSITION_Y) }, - }, /* multi-touch touchscreen */ - { - .flags = INPUT_DEVICE_ID_MATCH_KEYBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { [BIT_WORD(ABS_X)] = - BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, - }, /* touchpad */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_BUS | - INPUT_DEVICE_ID_MATCH_VENDOR | - INPUT_DEVICE_ID_MATCH_PRODUCT | - INPUT_DEVICE_ID_MATCH_VERSION, - .bustype = BUS_HOST, - .vendor = 0x0001, - .product = 0x0001, - .version = 0x0100, - .evbit = { BIT_MASK(EV_KEY) }, - }, /* keyboard/ir */ - { }, -}; - -static struct input_handler cpufreq_input_handler = { - .event = cpufreq_input_event, - .connect = cpufreq_input_connect, - .disconnect = cpufreq_input_disconnect, - .name = "cpufreq_input", - .id_table = cpufreq_input_ids, -}; -#endif /* #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY */ - - -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) -{ - unsigned int cpu = policy->cpu; - struct cpu_dbs_info_s *this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - unsigned int j; - int ret; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - - switch (event) { - case CPUFREQ_GOV_START: - if ((!cpu_online(cpu)) || (!policy->cur)) - return -EINVAL; - - mutex_lock(&dbs_mutex); - /* init idle/wall time for per-cpu */ - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_info_s *j_dbs_info; - j_dbs_info = &per_cpu(od_cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, &j_dbs_info->prev_cpu_wall, dbs_tuners_ins.io_is_busy); - j_dbs_info->cur_freq = policy->cur; - if(j_dbs_info->cur_freq <= dbs_tuners_ins.little_max_freq) { - j_dbs_info->max_freq = dbs_tuners_ins.little_max_freq; - j_dbs_info->is_little = true; - } - else { - j_dbs_info->max_freq = policy->max; - j_dbs_info->is_little = false; - } - - if(dbs_tuners_ins.dvfs_debug) { - printk("%s cpu:%u(%s) wall:%llu, idle:%llu\n", __func__, j, - j_dbs_info->is_little? "little":"big", j_dbs_info->prev_cpu_wall, - j_dbs_info->prev_cpu_idle); - } - } - this_dbs_info->cpu = cpu; - this_dbs_info->freq_table = cpufreq_frequency_get_table(cpu); - mutex_init(&this_dbs_info->timer_mutex); - - if (!(dbs_enable++)) { - /* initialize some variable to default value */ - dbs_tuners_ins.sampling_rate = DEF_SAMPLING_RATE; - dbs_tuners_ins.io_is_busy = DEF_IOWAIT_IS_BUSY; - - /* crate sys_fs node for the governor attrs, the path is - * /sys/devices/system/cpu/cpufreq - */ - ret = sysfs_create_group(cpufreq_global_kobject, &dbs_attr_group); - if (ret) { - mutex_destroy(&this_dbs_info->timer_mutex); - mutex_unlock(&dbs_mutex); - return ret; - } - - /* create a high prio task to processing the power change, adjust - * frequency, process cpu hotplug for ex. - */ - power_change_task = kthread_create(cpufreq_iks_power_change_task, NULL, - "iks-pwr-change"); - if (IS_ERR(power_change_task)) { - ret = PTR_ERR(power_change_task); - sysfs_remove_group(cpufreq_global_kobject, &dbs_attr_group); - mutex_destroy(&this_dbs_info->timer_mutex); - mutex_unlock(&dbs_mutex); - return ret; - } - sched_setscheduler_nocheck(power_change_task, SCHED_FIFO, ¶m); - get_task_struct(power_change_task); - register_hotcpu_notifier(&cpu_hotplug_notifier); - - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - ret = input_register_handler(&cpufreq_input_handler); - if (ret) - pr_warn("%s: failed to register input handler\n", __func__); - #endif - } - - mutex_unlock(&dbs_mutex); - dbs_timer_init(this_dbs_info); - break; - - case CPUFREQ_GOV_STOP: - dbs_timer_exit(this_dbs_info); - mutex_lock(&dbs_mutex); - mutex_destroy(&this_dbs_info->timer_mutex); - if(!(--dbs_enable)) { - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - input_unregister_handler(&cpufreq_input_handler); - #endif - - unregister_hotcpu_notifier(&cpu_hotplug_notifier); - kthread_stop(power_change_task); - put_task_struct(power_change_task); - /* delete the sys_fs node */ - sysfs_remove_group(cpufreq_global_kobject, &dbs_attr_group); - } - mutex_unlock(&dbs_mutex); - break; - - case CPUFREQ_GOV_LIMITS: - mutex_lock(&this_dbs_info->timer_mutex); - if (policy->max < this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, - policy->min, CPUFREQ_RELATION_L); - mutex_unlock(&this_dbs_info->timer_mutex); - break; - } - - return 0; -} - -struct cpufreq_governor cpufreq_gov_iks = { - .name = "iks", - .governor = cpufreq_governor_dbs, - .owner = THIS_MODULE, -}; - - -static int __init cpufreq_dbs_init(void) -{ - int ret; - - /* register cpu freq governor */ - ret = cpufreq_register_governor(&cpufreq_gov_iks); - if (ret) - goto err_reg; - spin_lock_init(&cpumask_lock); - - return ret; - -err_reg: - return ret; -} - - -static void __exit cpufreq_dbs_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_iks); -} - - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_IKS -fs_initcall(cpufreq_dbs_init); -#else -module_init(cpufreq_dbs_init); -#endif -module_exit(cpufreq_dbs_exit); - - -MODULE_AUTHOR("Kevin.z.m "); -MODULE_DESCRIPTION("'cpufreq_iks' - A cpufreq governor for big-Little IKS"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_interactive.c b/linux-3.4/drivers/cpufreq.new/cpufreq_interactive.c deleted file mode 100755 index 8264ed51..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_interactive.c +++ /dev/null @@ -1,1733 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_interactive.c - * - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - * Author: Mike Chan (mike@android.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CREATE_TRACE_POINTS -#include - -struct cpufreq_interactive_cpuinfo { - struct timer_list cpu_timer; - struct timer_list cpu_slack_timer; - spinlock_t load_lock; /* protects the next 4 fields */ - u64 time_in_idle; - u64 time_in_idle_timestamp; - u64 cputime_speedadj; - u64 cputime_speedadj_timestamp; - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *freq_table; - spinlock_t target_freq_lock; /*protects target freq */ - unsigned int target_freq; - unsigned int floor_freq; - unsigned int max_freq; - u64 floor_validate_time; - u64 hispeed_validate_time; - struct rw_semaphore enable_sem; - int governor_enabled; -}; - -static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo); - -/* realtime thread handles frequency scaling */ -static struct task_struct *speedchange_task; -static cpumask_t speedchange_cpumask; -static spinlock_t speedchange_cpumask_lock; -static struct mutex gov_lock; - -/* Target load. Lower values result in higher CPU speeds. */ -#define DEFAULT_TARGET_LOAD 90 -static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD}; - -#define DEFAULT_TIMER_RATE (50 * USEC_PER_MSEC) -#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE - -static unsigned int default_above_hispeed_delay[] = { - DEFAULT_ABOVE_HISPEED_DELAY }; - -struct cpufreq_interactive_tunables { - int usage_count; - -#if defined(CONFIG_ARCH_SUN9IW1P1) - #define DEFAULT_HISPEED_FREQ_BIG (1296000) - #define DEFAULT_HISPEED_FREQ_LITTLE (864000) -#elif defined(CONFIG_ARCH_SUN8IW6P1) - #define DEFAULT_HISPEED_FREQ_LITTLE (864000) -#elif defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW8P1) - #define DEFAULT_HISPEED_FREQ_LITTLE (648000) -#endif - - /* Hi speed to bump to from lo speed when load burst (default max) */ - unsigned int hispeed_freq; - /* Go to hi speed when CPU load at or above this value. */ -#define DEFAULT_GO_HISPEED_LOAD 70 - unsigned long go_hispeed_load; - - spinlock_t target_loads_lock; - unsigned int *target_loads; - int ntarget_loads; - - /* The minimum amount of time to spend at a frequency before we can ramp down. */ -#define DEFAULT_MIN_SAMPLE_TIME (4 * DEFAULT_TIMER_RATE) - unsigned long min_sample_time; - - /* The sample rate of the timer used to increase frequency */ - unsigned long timer_rate; - - /* Wait this long before raising speed above hispeed, by default a single timer interval. */ - spinlock_t above_hispeed_delay_lock; - unsigned int *above_hispeed_delay; - int nabove_hispeed_delay; - - /* Non-zero means indefinite speed boost active */ - int boost_val; - /* Duration of a boot pulse in usecs */ - int boostpulse_duration_val; - /* End time of boost pulse in ktime converted to usecs */ - u64 boostpulse_endtime; - - /* Duration of a boot top in usecs */ - int boosttop_duration_val; - /* End time of boost top in ktime converted to usecs */ - u64 boosttop_endtime; - - /* - * Max additional time to wait in idle, beyond timer_rate, at speeds above - * minimum before wakeup to reduce speed, or -1 if unnecessary. - */ -#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE) - int timer_slack_val; - bool io_is_busy; - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -#if defined(CONFIG_ARCH_SUN9IW1P1) - #define DEFAULT_INPUT_EVENT_FRFQ_BIG (1296000) - #define DEFAULT_INPUT_EVENT_FRFQ_LITTLE (1008000) -#elif defined(CONFIG_ARCH_SUN8IW6P1) - #define DEFAULT_INPUT_EVENT_FRFQ_LITTLE (1008000) -#elif defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW8P1) - #define DEFAULT_INPUT_EVENT_FRFQ_LITTLE (816000) -#endif - - int input_dev_monitor; - int input_event_freq; -#endif -}; - -/* For cases where we have single governor instance for system */ -struct cpufreq_interactive_tunables *common_tunables; - -static struct attribute_group *get_sysfs_attr(void); - -#ifdef CONFIG_ARCH_SUN9IW1P1 -static struct cpumask interactive_fast_cpus; -static struct cpumask interactive_slow_cpus; -extern void __init arch_get_fast_and_slow_cpus(struct cpumask *fast, - struct cpumask *slow); -#endif - -static void cpufreq_interactive_timer_resched( - struct cpufreq_interactive_cpuinfo *pcpu) -{ - struct cpufreq_interactive_tunables *tunables = - pcpu->policy->governor_data; - unsigned long expires; - unsigned long flags; - - spin_lock_irqsave(&pcpu->load_lock, flags); - pcpu->time_in_idle = - get_cpu_idle_time(smp_processor_id(), - &pcpu->time_in_idle_timestamp, - tunables->io_is_busy); - pcpu->cputime_speedadj = 0; - pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp; - expires = jiffies + usecs_to_jiffies(tunables->timer_rate); - mod_timer_pinned(&pcpu->cpu_timer, expires); - - if (tunables->timer_slack_val >= 0 && - pcpu->target_freq > pcpu->policy->min) { - expires += usecs_to_jiffies(tunables->timer_slack_val); - mod_timer_pinned(&pcpu->cpu_slack_timer, expires); - } - - spin_unlock_irqrestore(&pcpu->load_lock, flags); -} - -/* The caller shall take enable_sem write semaphore to avoid any timer race. - * The cpu_timer and cpu_slack_timer must be deactivated when calling this - * function. - */ -static void cpufreq_interactive_timer_start( - struct cpufreq_interactive_tunables *tunables, int cpu) -{ - struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); - unsigned long expires = jiffies + - usecs_to_jiffies(tunables->timer_rate); - unsigned long flags; - - pcpu->cpu_timer.expires = expires; - add_timer_on(&pcpu->cpu_timer, cpu); - if (tunables->timer_slack_val >= 0 && - pcpu->target_freq > pcpu->policy->min) { - expires += usecs_to_jiffies(tunables->timer_slack_val); - pcpu->cpu_slack_timer.expires = expires; - add_timer_on(&pcpu->cpu_slack_timer, cpu); - } - - spin_lock_irqsave(&pcpu->load_lock, flags); - pcpu->time_in_idle = - get_cpu_idle_time(cpu, &pcpu->time_in_idle_timestamp, - tunables->io_is_busy); - pcpu->cputime_speedadj = 0; - pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp; - spin_unlock_irqrestore(&pcpu->load_lock, flags); -} - -static unsigned int freq_to_above_hispeed_delay( - struct cpufreq_interactive_tunables *tunables, - unsigned int freq) -{ - int i; - unsigned int ret; - unsigned long flags; - - spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags); - - for (i = 0; i < tunables->nabove_hispeed_delay - 1 && - freq >= tunables->above_hispeed_delay[i+1]; i += 2) - ; - - ret = tunables->above_hispeed_delay[i]; - spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags); - return ret; -} - -static unsigned int freq_to_targetload( - struct cpufreq_interactive_tunables *tunables, unsigned int freq) -{ - int i; - unsigned int ret; - unsigned long flags; - - spin_lock_irqsave(&tunables->target_loads_lock, flags); - - for (i = 0; i < tunables->ntarget_loads - 1 && - freq >= tunables->target_loads[i+1]; i += 2) - ; - - ret = tunables->target_loads[i]; - spin_unlock_irqrestore(&tunables->target_loads_lock, flags); - return ret; -} - -/* - * If increasing frequencies never map to a lower target load then - * choose_freq() will find the minimum frequency that does not exceed its - * target load given the current load. - */ -static unsigned int choose_freq(struct cpufreq_interactive_cpuinfo *pcpu, - unsigned int loadadjfreq) -{ - unsigned int freq = pcpu->policy->cur; - unsigned int prevfreq, freqmin, freqmax; - unsigned int tl; - int index; - - freqmin = 0; - freqmax = UINT_MAX; - - do { - prevfreq = freq; - tl = freq_to_targetload(pcpu->policy->governor_data, freq); - - /* - * Find the lowest frequency where the computed load is less - * than or equal to the target load. - */ - - if (cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, loadadjfreq / tl, - CPUFREQ_RELATION_L, &index)) - break; - freq = pcpu->freq_table[index].frequency; - - if (freq > prevfreq) { - /* The previous frequency is too low. */ - freqmin = prevfreq; - - if (freq >= freqmax) { - /* - * Find the highest frequency that is less - * than freqmax. - */ - if (cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, - freqmax - 1, CPUFREQ_RELATION_H, - &index)) - break; - freq = pcpu->freq_table[index].frequency; - - if (freq == freqmin) { - /* - * The first frequency below freqmax - * has already been found to be too - * low. freqmax is the lowest speed - * we found that is fast enough. - */ - freq = freqmax; - break; - } - } - } else if (freq < prevfreq) { - /* The previous frequency is high enough. */ - freqmax = prevfreq; - - if (freq <= freqmin) { - /* - * Find the lowest frequency that is higher - * than freqmin. - */ - if (cpufreq_frequency_table_target( - pcpu->policy, pcpu->freq_table, - freqmin + 1, CPUFREQ_RELATION_L, - &index)) - break; - freq = pcpu->freq_table[index].frequency; - - /* - * If freqmax is the first frequency above - * freqmin then we have already found that - * this speed is fast enough. - */ - if (freq == freqmax) - break; - } - } - - /* If same frequency chosen as previous then done. */ - } while (freq != prevfreq); - - return freq; -} - -static u64 update_load(int cpu) -{ - struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); - struct cpufreq_interactive_tunables *tunables = - pcpu->policy->governor_data; - u64 now; - u64 now_idle; - u64 delta_idle; - u64 delta_time; - u64 active_time; - - now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy); - delta_idle = (now_idle - pcpu->time_in_idle); - delta_time = (now - pcpu->time_in_idle_timestamp); - - if (delta_time <= delta_idle) - active_time = 0; - else - active_time = delta_time - delta_idle; - - pcpu->cputime_speedadj += active_time * pcpu->policy->cur; - - pcpu->time_in_idle = now_idle; - pcpu->time_in_idle_timestamp = now; - return now; -} - -static void cpufreq_interactive_timer(unsigned long data) -{ - u64 now; - unsigned int delta_time; - u64 cputime_speedadj; - int cpu_load; - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, data); - struct cpufreq_interactive_tunables *tunables = - pcpu->policy->governor_data; - unsigned int new_freq; - unsigned int loadadjfreq; - unsigned int index; - unsigned long flags; - bool boosted; - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) - goto exit; - - spin_lock_irqsave(&pcpu->load_lock, flags); - now = update_load(data); - delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp); - cputime_speedadj = pcpu->cputime_speedadj; - spin_unlock_irqrestore(&pcpu->load_lock, flags); - - if (WARN_ON_ONCE(!delta_time)) - goto rearm; - - spin_lock_irqsave(&pcpu->target_freq_lock, flags); - do_div(cputime_speedadj, delta_time); - loadadjfreq = (unsigned int)cputime_speedadj * 100; - cpu_load = loadadjfreq / pcpu->target_freq; - boosted = tunables->boost_val || now < tunables->boostpulse_endtime; - - if (now < tunables->boosttop_endtime) { - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - goto rearm; - } - - if (cpu_load >= tunables->go_hispeed_load || boosted) { - if (pcpu->target_freq < tunables->hispeed_freq) { - new_freq = tunables->hispeed_freq; - } else { - new_freq = choose_freq(pcpu, loadadjfreq); - - if (new_freq < tunables->hispeed_freq) - new_freq = tunables->hispeed_freq; - } - } else { - new_freq = choose_freq(pcpu, loadadjfreq); - } - - if (pcpu->target_freq >= tunables->hispeed_freq && - new_freq > pcpu->target_freq && - now - pcpu->hispeed_validate_time < - freq_to_above_hispeed_delay(tunables, pcpu->target_freq)) { - trace_cpufreq_interactive_notyet( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - goto rearm; - } - - pcpu->hispeed_validate_time = now; - - if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table, - new_freq, CPUFREQ_RELATION_L, - &index)) { - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - goto rearm; - } - - new_freq = pcpu->freq_table[index].frequency; - - /* - * Do not scale below floor_freq unless we have been at or above the - * floor frequency for the minimum sample time since last validated. - */ - if (new_freq < pcpu->floor_freq) { - if (now - pcpu->floor_validate_time < - tunables->min_sample_time) { - trace_cpufreq_interactive_notyet( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - goto rearm; - } - } - - /* - * Update the timestamp for checking whether speed has been held at - * or above the selected frequency for a minimum of min_sample_time, - * if not boosted to hispeed_freq. If boosted to hispeed_freq then we - * allow the speed to drop as soon as the boostpulse duration expires - * (or the indefinite boost is turned off). - */ - - if (!boosted || new_freq > tunables->hispeed_freq) { - pcpu->floor_freq = new_freq; - pcpu->floor_validate_time = now; - } - - if (pcpu->target_freq == new_freq) { - trace_cpufreq_interactive_already( - data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - goto rearm_if_notmax; - } - - trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq, - pcpu->policy->cur, new_freq); - - pcpu->target_freq = new_freq; - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - cpumask_set_cpu(data, &speedchange_cpumask); - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags); - wake_up_process(speedchange_task); - -rearm_if_notmax: - /* - * Already set max speed and don't see a need to change that, - * wait until next idle to re-evaluate, don't need timer. - */ - if (pcpu->target_freq == pcpu->policy->max) - goto exit; - -rearm: - if (!timer_pending(&pcpu->cpu_timer)) - cpufreq_interactive_timer_resched(pcpu); - -exit: - up_read(&pcpu->enable_sem); - return; -} - -static void cpufreq_interactive_idle_start(void) -{ - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, smp_processor_id()); - int pending; - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return; - } - - pending = timer_pending(&pcpu->cpu_timer); - - if (pcpu->target_freq != pcpu->policy->min) { - /* - * Entering idle while not at lowest speed. On some - * platforms this can hold the other CPU(s) at that speed - * even though the CPU is idle. Set a timer to re-evaluate - * speed so this idle CPU doesn't hold the other CPUs above - * min indefinitely. This should probably be a quirk of - * the CPUFreq driver. - */ - if (!pending) - cpufreq_interactive_timer_resched(pcpu); - } - - up_read(&pcpu->enable_sem); -} - -static void cpufreq_interactive_idle_end(void) -{ - struct cpufreq_interactive_cpuinfo *pcpu = - &per_cpu(cpuinfo, smp_processor_id()); - - if (!down_read_trylock(&pcpu->enable_sem)) - return; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return; - } - - /* Arm the timer for 1-2 ticks later if not already. */ - if (!timer_pending(&pcpu->cpu_timer)) { - cpufreq_interactive_timer_resched(pcpu); - } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) { - del_timer(&pcpu->cpu_timer); - del_timer(&pcpu->cpu_slack_timer); - cpufreq_interactive_timer(smp_processor_id()); - } - - up_read(&pcpu->enable_sem); -} - -static int cpufreq_interactive_speedchange_task(void *data) -{ - unsigned int cpu; - cpumask_t tmp_mask; - unsigned long flags; - struct cpufreq_interactive_cpuinfo *pcpu; - - set_freezable(); - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - - if (cpumask_empty(&speedchange_cpumask)) { - spin_unlock_irqrestore(&speedchange_cpumask_lock, - flags); - schedule(); - - if (kthread_should_stop()) - break; - - spin_lock_irqsave(&speedchange_cpumask_lock, flags); - } - - set_current_state(TASK_RUNNING); - tmp_mask = speedchange_cpumask; - cpumask_clear(&speedchange_cpumask); - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags); - - if (freezing(current)) { - try_to_freeze(); - } - - for_each_cpu(cpu, &tmp_mask) { - unsigned int j; - unsigned int max_freq = 0; - - pcpu = &per_cpu(cpuinfo, cpu); - if (!down_read_trylock(&pcpu->enable_sem)) - continue; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - continue; - } - - for_each_cpu(j, pcpu->policy->cpus) { - struct cpufreq_interactive_cpuinfo *pjcpu = - &per_cpu(cpuinfo, j); - - if (pjcpu->target_freq > max_freq) - max_freq = pjcpu->target_freq; - } - - if (max_freq != pcpu->policy->cur) - __cpufreq_driver_target(pcpu->policy, - max_freq, - CPUFREQ_RELATION_H); - trace_cpufreq_interactive_setspeed(cpu, - pcpu->target_freq, - pcpu->policy->cur); - - up_read(&pcpu->enable_sem); - } - } - - return 0; -} - -static void cpufreq_interactive_boost(void) -{ - int i; - int anyboost = 0; - unsigned long flags[2]; - struct cpufreq_interactive_cpuinfo *pcpu; - struct cpufreq_interactive_tunables *tunables; - - spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]); - - for_each_online_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - tunables = pcpu->policy->governor_data; - - spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]); - if (pcpu->target_freq < tunables->hispeed_freq) { - pcpu->target_freq = tunables->hispeed_freq; - cpumask_set_cpu(i, &speedchange_cpumask); - pcpu->hispeed_validate_time = - ktime_to_us(ktime_get()); - anyboost = 1; - } - - /* - * Set floor freq and (re)start timer for when last - * validated. - */ - - pcpu->floor_freq = tunables->hispeed_freq; - pcpu->floor_validate_time = ktime_to_us(ktime_get()); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]); - } - - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]); - - if (anyboost) - wake_up_process(speedchange_task); -} - -static int cpufreq_interactive_notifier( - struct notifier_block *nb, unsigned long val, void *data) -{ - struct cpufreq_freqs *freq = data; - struct cpufreq_interactive_cpuinfo *pcpu; - int cpu; - unsigned long flags; - - if (val == CPUFREQ_POSTCHANGE) { - pcpu = &per_cpu(cpuinfo, freq->cpu); - if (!down_read_trylock(&pcpu->enable_sem)) - return 0; - if (!pcpu->governor_enabled) { - up_read(&pcpu->enable_sem); - return 0; - } - - for_each_cpu(cpu, pcpu->policy->cpus) { - struct cpufreq_interactive_cpuinfo *pjcpu = - &per_cpu(cpuinfo, cpu); - if (cpu != freq->cpu) { - if (!down_read_trylock(&pjcpu->enable_sem)) - continue; - if (!pjcpu->governor_enabled) { - up_read(&pjcpu->enable_sem); - continue; - } - } - spin_lock_irqsave(&pjcpu->load_lock, flags); - update_load(cpu); - spin_unlock_irqrestore(&pjcpu->load_lock, flags); - if (cpu != freq->cpu) - up_read(&pjcpu->enable_sem); - } - - up_read(&pcpu->enable_sem); - } - return 0; -} - -static struct notifier_block cpufreq_notifier_block = { - .notifier_call = cpufreq_interactive_notifier, -}; - -static unsigned int *get_tokenized_data(const char *buf, int *num_tokens) -{ - const char *cp; - int i; - int ntokens = 1; - unsigned int *tokenized_data; - int err = -EINVAL; - - cp = buf; - while ((cp = strpbrk(cp + 1, " :"))) - ntokens++; - - if (!(ntokens & 0x1)) - goto err; - - tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL); - if (!tokenized_data) { - err = -ENOMEM; - goto err; - } - - cp = buf; - i = 0; - while (i < ntokens) { - if (sscanf(cp, "%u", &tokenized_data[i++]) != 1) - goto err_kfree; - - cp = strpbrk(cp, " :"); - if (!cp) - break; - cp++; - } - - if (i != ntokens) - goto err_kfree; - - *num_tokens = ntokens; - return tokenized_data; - -err_kfree: - kfree(tokenized_data); -err: - return ERR_PTR(err); -} - -static ssize_t show_target_loads( - struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - int i; - ssize_t ret = 0; - unsigned long flags; - - spin_lock_irqsave(&tunables->target_loads_lock, flags); - - for (i = 0; i < tunables->ntarget_loads; i++) - ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i], - i & 0x1 ? ":" : " "); - - sprintf(buf + ret - 1, "\n"); - spin_unlock_irqrestore(&tunables->target_loads_lock, flags); - return ret; -} - -static ssize_t store_target_loads( - struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ntokens; - unsigned int *new_target_loads = NULL; - unsigned long flags; - - new_target_loads = get_tokenized_data(buf, &ntokens); - if (IS_ERR(new_target_loads)) - return PTR_RET(new_target_loads); - - spin_lock_irqsave(&tunables->target_loads_lock, flags); - if (tunables->target_loads != default_target_loads) - kfree(tunables->target_loads); - tunables->target_loads = new_target_loads; - tunables->ntarget_loads = ntokens; - spin_unlock_irqrestore(&tunables->target_loads_lock, flags); - return count; -} - -static ssize_t show_above_hispeed_delay( - struct cpufreq_interactive_tunables *tunables, char *buf) -{ - int i; - ssize_t ret = 0; - unsigned long flags; - - spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags); - - for (i = 0; i < tunables->nabove_hispeed_delay; i++) - ret += sprintf(buf + ret, "%u%s", - tunables->above_hispeed_delay[i], - i & 0x1 ? ":" : " "); - - sprintf(buf + ret - 1, "\n"); - spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags); - return ret; -} - -static ssize_t store_above_hispeed_delay( - struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ntokens; - unsigned int *new_above_hispeed_delay = NULL; - unsigned long flags; - - new_above_hispeed_delay = get_tokenized_data(buf, &ntokens); - if (IS_ERR(new_above_hispeed_delay)) - return PTR_RET(new_above_hispeed_delay); - - spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags); - if (tunables->above_hispeed_delay != default_above_hispeed_delay) - kfree(tunables->above_hispeed_delay); - tunables->above_hispeed_delay = new_above_hispeed_delay; - tunables->nabove_hispeed_delay = ntokens; - spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags); - return count; - -} - -static ssize_t show_hispeed_freq(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%u\n", tunables->hispeed_freq); -} - -static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - long unsigned int val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->hispeed_freq = val; - return count; -} - -static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables - *tunables, char *buf) -{ - return sprintf(buf, "%lu\n", tunables->go_hispeed_load); -} - -static ssize_t store_go_hispeed_load(struct cpufreq_interactive_tunables - *tunables, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->go_hispeed_load = val; - return count; -} - -static ssize_t show_min_sample_time(struct cpufreq_interactive_tunables - *tunables, char *buf) -{ - return sprintf(buf, "%lu\n", tunables->min_sample_time); -} - -static ssize_t store_min_sample_time(struct cpufreq_interactive_tunables - *tunables, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->min_sample_time = val; - return count; -} - -static ssize_t show_timer_rate(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%lu\n", tunables->timer_rate); -} - -static ssize_t store_timer_rate(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = strict_strtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->timer_rate = val; - return count; -} - -static ssize_t show_timer_slack(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%d\n", tunables->timer_slack_val); -} - -static ssize_t store_timer_slack(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtol(buf, 10, &val); - if (ret < 0) - return ret; - - tunables->timer_slack_val = val; - return count; -} - -static ssize_t show_boost(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%d\n", tunables->boost_val); -} - -static ssize_t store_boost(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - tunables->boost_val = val; - - if (tunables->boost_val) { - trace_cpufreq_interactive_boost("on"); - cpufreq_interactive_boost(); - } else { - tunables->boostpulse_endtime = ktime_to_us(ktime_get()); - trace_cpufreq_interactive_unboost("off"); - } - - return count; -} - -static ssize_t store_boostpulse(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - tunables->boostpulse_endtime = ktime_to_us(ktime_get()) + - tunables->boostpulse_duration_val; - trace_cpufreq_interactive_boost("pulse"); - cpufreq_interactive_boost(); - return count; -} - -static ssize_t show_boostpulse_duration(struct cpufreq_interactive_tunables - *tunables, char *buf) -{ - return sprintf(buf, "%d\n", tunables->boostpulse_duration_val); -} - -static ssize_t store_boostpulse_duration(struct cpufreq_interactive_tunables - *tunables, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - tunables->boostpulse_duration_val = val; - return count; -} - -static ssize_t show_io_is_busy(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%u\n", tunables->io_is_busy); -} - -static ssize_t store_io_is_busy(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->io_is_busy = val; - return count; -} - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - -static ssize_t show_input_dev_monitor(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%u\n", tunables->input_dev_monitor); -} - -static ssize_t store_input_dev_monitor(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->input_dev_monitor = val? 1 : 0; - return count; -} - -static ssize_t show_input_event_freq(struct cpufreq_interactive_tunables *tunables, - char *buf) -{ - return sprintf(buf, "%u\n", tunables->input_event_freq); -} - -static ssize_t store_input_event_freq(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - tunables->input_event_freq = val; - return count; -} - -#endif /* #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY */ - - -static void cpufreq_interactive_boosttop(void) -{ - int i; - int anytop = 0; - unsigned long flags[2]; - struct cpufreq_interactive_cpuinfo *pcpu; - - spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]); - - for_each_online_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - - spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]); - if (pcpu->target_freq < pcpu->policy->max) { - pcpu->target_freq = pcpu->policy->max; - cpumask_set_cpu(i, &speedchange_cpumask); - anytop = 1; - } - - pcpu->floor_freq = pcpu->policy->max; - pcpu->floor_validate_time = ktime_to_us(ktime_get()); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]); - } - - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]); - - if (anytop) - wake_up_process(speedchange_task); -} - -static ssize_t store_boosttop(struct cpufreq_interactive_tunables *tunables, - const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - tunables->boosttop_endtime = ktime_to_us(ktime_get()) + - tunables->boosttop_duration_val; - trace_cpufreq_interactive_boost("boost top"); - cpufreq_interactive_boosttop(); - return count; -} - -static ssize_t show_boosttop_duration(struct cpufreq_interactive_tunables - *tunables, char *buf) -{ - return sprintf(buf, "%d\n", tunables->boosttop_duration_val); -} - -static ssize_t store_boosttop_duration(struct cpufreq_interactive_tunables - *tunables, const char *buf, size_t count) -{ - int ret; - unsigned long val; - - ret = kstrtoul(buf, 0, &val); - if (ret < 0) - return ret; - - tunables->boosttop_duration_val = val; - return count; -} - - -/* - * Create show/store routines - * - sys: One governor instance for complete SYSTEM - * - pol: One governor instance per struct cpufreq_policy - */ -#define show_gov_pol_sys(file_name) \ -static ssize_t show_##file_name##_gov_sys \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - return show_##file_name(common_tunables, buf); \ -} \ - \ -static ssize_t show_##file_name##_gov_pol \ -(struct cpufreq_policy *policy, char *buf) \ -{ \ - return show_##file_name(policy->governor_data, buf); \ -} - -#define store_gov_pol_sys(file_name) \ -static ssize_t store_##file_name##_gov_sys \ -(struct kobject *kobj, struct attribute *attr, const char *buf, \ - size_t count) \ -{ \ - return store_##file_name(common_tunables, buf, count); \ -} \ - \ -static ssize_t store_##file_name##_gov_pol \ -(struct cpufreq_policy *policy, const char *buf, size_t count) \ -{ \ - return store_##file_name(policy->governor_data, buf, count); \ -} - -#define show_store_gov_pol_sys(file_name) \ -show_gov_pol_sys(file_name); \ -store_gov_pol_sys(file_name) - -show_store_gov_pol_sys(target_loads); -show_store_gov_pol_sys(above_hispeed_delay); -show_store_gov_pol_sys(hispeed_freq); -show_store_gov_pol_sys(go_hispeed_load); -show_store_gov_pol_sys(min_sample_time); -show_store_gov_pol_sys(timer_rate); -show_store_gov_pol_sys(timer_slack); -show_store_gov_pol_sys(boost); -store_gov_pol_sys(boostpulse); -show_store_gov_pol_sys(boostpulse_duration); -show_store_gov_pol_sys(io_is_busy); -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -show_store_gov_pol_sys(input_dev_monitor); -show_store_gov_pol_sys(input_event_freq); -#endif -store_gov_pol_sys(boosttop); -show_store_gov_pol_sys(boosttop_duration); - -#define gov_sys_attr_rw(_name) \ -static struct global_attr _name##_gov_sys = \ -__ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys) - -#define gov_pol_attr_rw(_name) \ -static struct freq_attr _name##_gov_pol = \ -__ATTR(_name, 0644, show_##_name##_gov_pol, store_##_name##_gov_pol) - -#define gov_sys_pol_attr_rw(_name) \ - gov_sys_attr_rw(_name); \ - gov_pol_attr_rw(_name) - -gov_sys_pol_attr_rw(target_loads); -gov_sys_pol_attr_rw(above_hispeed_delay); -gov_sys_pol_attr_rw(hispeed_freq); -gov_sys_pol_attr_rw(go_hispeed_load); -gov_sys_pol_attr_rw(min_sample_time); -gov_sys_pol_attr_rw(timer_rate); -gov_sys_pol_attr_rw(timer_slack); -gov_sys_pol_attr_rw(boost); -gov_sys_pol_attr_rw(boostpulse_duration); -gov_sys_pol_attr_rw(io_is_busy); -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY -gov_sys_pol_attr_rw(input_dev_monitor); -gov_sys_pol_attr_rw(input_event_freq); -#endif -gov_sys_pol_attr_rw(boosttop_duration); - -static struct global_attr boostpulse_gov_sys = - __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys); - -static struct freq_attr boostpulse_gov_pol = - __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_pol); - -static struct global_attr boosttop_gov_sys = - __ATTR(boosttop, 0200, NULL, store_boosttop_gov_sys); - -static struct freq_attr boosttop_gov_pol = - __ATTR(boosttop, 0200, NULL, store_boosttop_gov_pol); - -/* One Governor instance for entire system */ -static struct attribute *interactive_attributes_gov_sys[] = { - &target_loads_gov_sys.attr, - &above_hispeed_delay_gov_sys.attr, - &hispeed_freq_gov_sys.attr, - &go_hispeed_load_gov_sys.attr, - &min_sample_time_gov_sys.attr, - &timer_rate_gov_sys.attr, - &timer_slack_gov_sys.attr, - &boost_gov_sys.attr, - &boostpulse_gov_sys.attr, - &boostpulse_duration_gov_sys.attr, - &io_is_busy_gov_sys.attr, - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - &input_dev_monitor_gov_sys.attr, - &input_event_freq_gov_sys.attr, - #endif - &boosttop_gov_sys.attr, - &boosttop_duration_gov_sys.attr, - NULL, -}; - -static struct attribute_group interactive_attr_group_gov_sys = { - .attrs = interactive_attributes_gov_sys, - .name = "interactive", -}; - -/* Per policy governor instance */ -static struct attribute *interactive_attributes_gov_pol[] = { - &target_loads_gov_pol.attr, - &above_hispeed_delay_gov_pol.attr, - &hispeed_freq_gov_pol.attr, - &go_hispeed_load_gov_pol.attr, - &min_sample_time_gov_pol.attr, - &timer_rate_gov_pol.attr, - &timer_slack_gov_pol.attr, - &boost_gov_pol.attr, - &boostpulse_gov_pol.attr, - &boostpulse_duration_gov_pol.attr, - &io_is_busy_gov_pol.attr, - #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - &input_dev_monitor_gov_pol.attr, - &input_event_freq_gov_pol.attr, - #endif - &boosttop_gov_pol.attr, - &boosttop_duration_gov_pol.attr, - NULL, -}; - -static struct attribute_group interactive_attr_group_gov_pol = { - .attrs = interactive_attributes_gov_pol, - .name = "interactive", -}; - -static struct attribute_group *get_sysfs_attr(void) -{ - if (have_governor_per_policy()) - return &interactive_attr_group_gov_pol; - else - return &interactive_attr_group_gov_sys; -} - -static int cpufreq_interactive_idle_notifier(struct notifier_block *nb, - unsigned long val, - void *data) -{ - switch (val) { - case IDLE_START: - cpufreq_interactive_idle_start(); - break; - case IDLE_END: - cpufreq_interactive_idle_end(); - break; - } - - return 0; -} - -static struct notifier_block cpufreq_interactive_idle_nb = { - .notifier_call = cpufreq_interactive_idle_notifier, -}; - - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - -static int input_handler_register_count = 0; -static cpumask_t interactive_cpumask; - -/* - * trigger cpu frequency to a high speed when input event coming. - * such as key, ir, touchpannel for ex. , but skip gsensor. - */ -static void cpufreq_interactive_input_event(struct input_handle *handle, - unsigned int type, - unsigned int code, int value) -{ - int i; - int anyboost = 0; - unsigned long flags[2]; - struct cpufreq_interactive_cpuinfo *pcpu; - struct cpufreq_interactive_tunables *tunables; - - if (type == EV_SYN && code == SYN_REPORT) { - spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]); - - for_each_cpu(i, &interactive_cpumask) { - pcpu = &per_cpu(cpuinfo, i); - tunables = pcpu->policy->governor_data; - - if(tunables->input_dev_monitor) { - spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]); - if (pcpu->target_freq < tunables->input_event_freq) { - pcpu->target_freq = tunables->input_event_freq; - cpumask_set_cpu(i, &speedchange_cpumask); - anyboost = 1; - } - - pcpu->floor_freq = tunables->input_event_freq; - pcpu->floor_validate_time = ktime_to_us(ktime_get()); - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]); - } - } - - spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]); - - if (anyboost) - wake_up_process(speedchange_task); - } -} - -static int cpufreq_interactive_input_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "cpufreq_interactive"; - - error = input_register_handle(handle); - if (error) - goto err; - - error = input_open_device(handle); - if (error) - goto err_open; - - return 0; - -err_open: - input_unregister_handle(handle); -err: - kfree(handle); - return error; -} - -static void cpufreq_interactive_input_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id cpufreq_interactive_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] = - BIT_MASK(ABS_MT_POSITION_X) | - BIT_MASK(ABS_MT_POSITION_Y) }, - }, /* multi-touch touchscreen */ - { - .flags = INPUT_DEVICE_ID_MATCH_KEYBIT | - INPUT_DEVICE_ID_MATCH_ABSBIT, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { [BIT_WORD(ABS_X)] = - BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, - }, /* touchpad */ - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_BUS | - INPUT_DEVICE_ID_MATCH_VENDOR | - INPUT_DEVICE_ID_MATCH_PRODUCT | - INPUT_DEVICE_ID_MATCH_VERSION, - .bustype = BUS_HOST, - .vendor = 0x0001, - .product = 0x0001, - .version = 0x0100, - .evbit = { BIT_MASK(EV_KEY) }, - }, /* keyboard/ir */ - { }, -}; - -static struct input_handler cpufreq_interactive_input_handler = { - .event = cpufreq_interactive_input_event, - .connect = cpufreq_interactive_input_connect, - .disconnect = cpufreq_interactive_input_disconnect, - .name = "cpufreq_interactive", - .id_table = cpufreq_interactive_ids, -}; - -#endif /* #ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY */ - -static int cpufreq_governor_interactive(struct cpufreq_policy *policy, - unsigned int event) -{ - int rc; - unsigned int j; - struct cpufreq_interactive_cpuinfo *pcpu; - struct cpufreq_frequency_table *freq_table; - struct cpufreq_interactive_tunables *tunables; - unsigned long flags; - - if (have_governor_per_policy()) - tunables = policy->governor_data; - else - tunables = common_tunables; - - WARN_ON(!tunables && (event != CPUFREQ_GOV_POLICY_INIT)); - - switch (event) { - case CPUFREQ_GOV_POLICY_INIT: - if (have_governor_per_policy()) { - WARN_ON(tunables); - } else if (tunables) { - tunables->usage_count++; - policy->governor_data = tunables; - return 0; - } - - tunables = kzalloc(sizeof(*tunables), GFP_KERNEL); - if (!tunables) { - pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__); - return -ENOMEM; - } - - tunables->usage_count = 1; - tunables->io_is_busy = true; - tunables->above_hispeed_delay = default_above_hispeed_delay; - tunables->nabove_hispeed_delay = - ARRAY_SIZE(default_above_hispeed_delay); - tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD; - tunables->target_loads = default_target_loads; - tunables->ntarget_loads = ARRAY_SIZE(default_target_loads); - tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME; - tunables->timer_rate = DEFAULT_TIMER_RATE; - tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME; - tunables->boosttop_duration_val = DEFAULT_MIN_SAMPLE_TIME; - tunables->timer_slack_val = DEFAULT_TIMER_SLACK; - - spin_lock_init(&tunables->target_loads_lock); - spin_lock_init(&tunables->above_hispeed_delay_lock); - - policy->governor_data = tunables; - if (!have_governor_per_policy()) - common_tunables = tunables; - - rc = sysfs_create_group(get_governor_parent_kobj(policy), - get_sysfs_attr()); - if (rc) { - kfree(tunables); - policy->governor_data = NULL; - if (!have_governor_per_policy()) - common_tunables = NULL; - return rc; - } - - if (!policy->governor->initialized) { - idle_notifier_register(&cpufreq_interactive_idle_nb); - cpufreq_register_notifier(&cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - if(!input_handler_register_count) { - cpumask_clear(&interactive_cpumask); - input_register_handler(&cpufreq_interactive_input_handler); - } - -#if defined(CONFIG_ARCH_SUN9IW1P1) - if (cpumask_test_cpu(policy->cpu, &interactive_fast_cpus)) - tunables->input_event_freq = DEFAULT_INPUT_EVENT_FRFQ_BIG; - else if (cpumask_test_cpu(policy->cpu, &interactive_slow_cpus)) - tunables->input_event_freq = DEFAULT_INPUT_EVENT_FRFQ_LITTLE; -#elif defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW8P1) - tunables->input_event_freq = DEFAULT_INPUT_EVENT_FRFQ_LITTLE; -#endif - - tunables->input_dev_monitor = true; - input_handler_register_count++; -#endif - - break; - - case CPUFREQ_GOV_POLICY_EXIT: - if (!--tunables->usage_count) { - if (policy->governor->initialized == 1) { - cpufreq_unregister_notifier(&cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - idle_notifier_unregister(&cpufreq_interactive_idle_nb); - } - sysfs_remove_group(get_governor_parent_kobj(policy), - - get_sysfs_attr()); - - kfree(tunables); - common_tunables = NULL; - } - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - if(input_handler_register_count > 0) - input_handler_register_count--; - if(!input_handler_register_count) { - cpumask_clear(&interactive_cpumask); - input_unregister_handler(&cpufreq_interactive_input_handler); - } -#endif - - policy->governor_data = NULL; - break; - - case CPUFREQ_GOV_START: - mutex_lock(&gov_lock); - - freq_table = cpufreq_frequency_get_table(policy->cpu); - if (!tunables->hispeed_freq) { -#if defined(CONFIG_ARCH_SUN9IW1P1) - if (cpumask_test_cpu(policy->cpu, &interactive_fast_cpus)) - tunables->hispeed_freq = DEFAULT_HISPEED_FREQ_BIG; - else if (cpumask_test_cpu(policy->cpu, &interactive_slow_cpus)) - tunables->hispeed_freq = DEFAULT_HISPEED_FREQ_LITTLE; -#elif defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW8P1) - tunables->hispeed_freq = DEFAULT_HISPEED_FREQ_LITTLE; -#endif - } - - for_each_cpu(j, policy->cpus) { - pcpu = &per_cpu(cpuinfo, j); - pcpu->policy = policy; - pcpu->target_freq = policy->cur; - pcpu->freq_table = freq_table; - pcpu->floor_freq = pcpu->target_freq; - pcpu->floor_validate_time = - ktime_to_us(ktime_get()); - pcpu->hispeed_validate_time = - pcpu->floor_validate_time; - pcpu->max_freq = policy->max; - down_write(&pcpu->enable_sem); - del_timer_sync(&pcpu->cpu_timer); - del_timer_sync(&pcpu->cpu_slack_timer); - cpufreq_interactive_timer_start(tunables, j); - pcpu->governor_enabled = 1; - up_write(&pcpu->enable_sem); - } - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - cpumask_or(&interactive_cpumask, &interactive_cpumask, policy->cpus); -#endif - - mutex_unlock(&gov_lock); - break; - - case CPUFREQ_GOV_STOP: - mutex_lock(&gov_lock); - for_each_cpu(j, policy->cpus) { - pcpu = &per_cpu(cpuinfo, j); - down_write(&pcpu->enable_sem); - pcpu->governor_enabled = 0; - del_timer_sync(&pcpu->cpu_timer); - del_timer_sync(&pcpu->cpu_slack_timer); - up_write(&pcpu->enable_sem); - } - -#ifdef CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY - cpumask_andnot(&interactive_cpumask, &interactive_cpumask, policy->cpus); -#endif - - mutex_unlock(&gov_lock); - break; - - case CPUFREQ_GOV_LIMITS: - if (policy->max < policy->cur) - __cpufreq_driver_target(policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > policy->cur) - __cpufreq_driver_target(policy, - policy->min, CPUFREQ_RELATION_L); - for_each_cpu(j, policy->cpus) { - pcpu = &per_cpu(cpuinfo, j); - - down_read(&pcpu->enable_sem); - if (pcpu->governor_enabled == 0) { - up_read(&pcpu->enable_sem); - continue; - } - - spin_lock_irqsave(&pcpu->target_freq_lock, flags); - if (policy->max < pcpu->target_freq) - pcpu->target_freq = policy->max; - else if (policy->min > pcpu->target_freq) - pcpu->target_freq = policy->min; - - spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); - up_read(&pcpu->enable_sem); - - /* Reschedule timer only if policy->max is raised. - * Delete the timers, else the timer callback may - * return without re-arm the timer when failed - * acquire the semaphore. This race may cause timer - * stopped unexpectedly. - */ - - if (policy->max > pcpu->max_freq) { - down_write(&pcpu->enable_sem); - del_timer_sync(&pcpu->cpu_timer); - del_timer_sync(&pcpu->cpu_slack_timer); - cpufreq_interactive_timer_start(tunables, j); - up_write(&pcpu->enable_sem); - } - - pcpu->max_freq = policy->max; - } - break; - } - return 0; -} - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -static -#endif -struct cpufreq_governor cpufreq_gov_interactive = { - .name = "interactive", - .governor = cpufreq_governor_interactive, - .max_transition_latency = 10000000, - .owner = THIS_MODULE, -}; - -static void cpufreq_interactive_nop_timer(unsigned long data) -{ -} - -static int __init cpufreq_interactive_init(void) -{ - unsigned int i; - struct cpufreq_interactive_cpuinfo *pcpu; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - -#ifdef CONFIG_ARCH_SUN9IW1P1 - arch_get_fast_and_slow_cpus(&interactive_fast_cpus, &interactive_slow_cpus); -#endif - - /* Initalize per-cpu timers */ - for_each_possible_cpu(i) { - pcpu = &per_cpu(cpuinfo, i); - init_timer_deferrable(&pcpu->cpu_timer); - pcpu->cpu_timer.function = cpufreq_interactive_timer; - pcpu->cpu_timer.data = i; - init_timer(&pcpu->cpu_slack_timer); - pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer; - spin_lock_init(&pcpu->load_lock); - spin_lock_init(&pcpu->target_freq_lock); - init_rwsem(&pcpu->enable_sem); - } - - spin_lock_init(&speedchange_cpumask_lock); - mutex_init(&gov_lock); - speedchange_task = - kthread_create(cpufreq_interactive_speedchange_task, NULL, - "cfinteractive"); - if (IS_ERR(speedchange_task)) - return PTR_ERR(speedchange_task); - - sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, ¶m); - get_task_struct(speedchange_task); - - /* NB: wake up so the thread does not look hung to the freezer */ - wake_up_process(speedchange_task); - - return cpufreq_register_governor(&cpufreq_gov_interactive); -} - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE -fs_initcall(cpufreq_interactive_init); -#else -module_init(cpufreq_interactive_init); -#endif - -static void __exit cpufreq_interactive_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_interactive); - kthread_stop(speedchange_task); - put_task_struct(speedchange_task); -} - -module_exit(cpufreq_interactive_exit); - -MODULE_AUTHOR("Mike Chan "); -MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for " - "Latency sensitive workloads"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_ondemand.c b/linux-3.4/drivers/cpufreq.new/cpufreq_ondemand.c deleted file mode 100755 index c087347d..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_ondemand.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_ondemand.c - * - * Copyright (C) 2001 Russell King - * (C) 2003 Venkatesh Pallipadi . - * Jun Nakajima - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cpufreq_governor.h" - -/* On-demand governor macros */ -#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) -#define DEF_FREQUENCY_UP_THRESHOLD (80) -#define DEF_SAMPLING_DOWN_FACTOR (1) -#define MAX_SAMPLING_DOWN_FACTOR (100000) -#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3) -#define MICRO_FREQUENCY_UP_THRESHOLD (95) -#define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000) -#define MIN_FREQUENCY_UP_THRESHOLD (11) -#define MAX_FREQUENCY_UP_THRESHOLD (100) - -static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info); - -static struct od_ops od_ops; - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -static struct cpufreq_governor cpufreq_gov_ondemand; -#endif - -static unsigned int default_powersave_bias; - -static void ondemand_powersave_bias_init_cpu(int cpu) -{ - struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - - dbs_info->freq_table = cpufreq_frequency_get_table(cpu); - dbs_info->freq_lo = 0; -} - -/* - * Not all CPUs want IO time to be accounted as busy; this depends on how - * efficient idling at a higher frequency/voltage is. - * Pavel Machek says this is not so for various generations of AMD and old - * Intel systems. - * Mike Chan (android.com) claims this is also not true for ARM. - * Because of this, whitelist specific known (series) of CPUs by default, and - * leave all others up to the user. - */ -static int should_io_be_busy(void) -{ -#if defined(CONFIG_X86) - /* - * For Intel, Core 2 (model 15) and later have an efficient idle. - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6 && - boot_cpu_data.x86_model >= 15) - return 1; -#endif - return 0; -} - -/* - * Find right freq to be set now with powersave_bias on. - * Returns the freq_hi to be used right now and will set freq_hi_jiffies, - * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs. - */ -static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, - unsigned int freq_next, unsigned int relation) -{ - unsigned int freq_req, freq_reduc, freq_avg; - unsigned int freq_hi, freq_lo; - unsigned int index = 0; - unsigned int jiffies_total, jiffies_hi, jiffies_lo; - struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, - policy->cpu); - struct dbs_data *dbs_data = policy->governor_data; - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - - if (!dbs_info->freq_table) { - dbs_info->freq_lo = 0; - dbs_info->freq_lo_jiffies = 0; - return freq_next; - } - - cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next, - relation, &index); - freq_req = dbs_info->freq_table[index].frequency; - freq_reduc = freq_req * od_tuners->powersave_bias / 1000; - freq_avg = freq_req - freq_reduc; - - /* Find freq bounds for freq_avg in freq_table */ - index = 0; - cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg, - CPUFREQ_RELATION_H, &index); - freq_lo = dbs_info->freq_table[index].frequency; - index = 0; - cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg, - CPUFREQ_RELATION_L, &index); - freq_hi = dbs_info->freq_table[index].frequency; - - /* Find out how long we have to be in hi and lo freqs */ - if (freq_hi == freq_lo) { - dbs_info->freq_lo = 0; - dbs_info->freq_lo_jiffies = 0; - return freq_lo; - } - jiffies_total = usecs_to_jiffies(od_tuners->sampling_rate); - jiffies_hi = (freq_avg - freq_lo) * jiffies_total; - jiffies_hi += ((freq_hi - freq_lo) / 2); - jiffies_hi /= (freq_hi - freq_lo); - jiffies_lo = jiffies_total - jiffies_hi; - dbs_info->freq_lo = freq_lo; - dbs_info->freq_lo_jiffies = jiffies_lo; - dbs_info->freq_hi_jiffies = jiffies_hi; - return freq_hi; -} - -static void ondemand_powersave_bias_init(void) -{ - int i; - for_each_online_cpu(i) { - ondemand_powersave_bias_init_cpu(i); - } -} - -static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) -{ - struct dbs_data *dbs_data = p->governor_data; - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - - if (od_tuners->powersave_bias) - freq = od_ops.powersave_bias_target(p, freq, - CPUFREQ_RELATION_H); - else if (p->cur == p->max) - return; - - __cpufreq_driver_target(p, freq, od_tuners->powersave_bias ? - CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); -} - -/* - * Every sampling_rate, we check, if current idle time is less than 20% - * (default), then we try to increase frequency. Every sampling_rate, we look - * for the lowest frequency which can sustain the load while keeping idle time - * over 30%. If such a frequency exist, we try to decrease to this frequency. - * - * Any frequency increase takes it to the maximum frequency. Frequency reduction - * happens at minimum steps of 5% (default) of current frequency - */ -static void od_check_cpu(int cpu, unsigned int load_freq) -{ - struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; - struct dbs_data *dbs_data = policy->governor_data; - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - - dbs_info->freq_lo = 0; - - /* Check for frequency increase */ - if (load_freq > od_tuners->up_threshold * policy->cur) { - /* If switching to max speed, apply sampling_down_factor */ - if (policy->cur < policy->max) - dbs_info->rate_mult = - od_tuners->sampling_down_factor; - dbs_freq_increase(policy, policy->max); - return; - } - - /* Check for frequency decrease */ - /* if we cannot reduce the frequency anymore, break out early */ - if (policy->cur == policy->min) - return; - - /* - * The optimal frequency is the frequency that is the lowest that can - * support the current CPU usage without triggering the up policy. To be - * safe, we focus 10 points under the threshold. - */ - if (load_freq < od_tuners->adj_up_threshold - * policy->cur) { - unsigned int freq_next; - freq_next = load_freq / od_tuners->adj_up_threshold; - - /* No longer fully busy, reset rate_mult */ - dbs_info->rate_mult = 1; - - if (freq_next < policy->min) - freq_next = policy->min; - - if (!od_tuners->powersave_bias) { - __cpufreq_driver_target(policy, freq_next, - CPUFREQ_RELATION_L); - return; - } - - freq_next = od_ops.powersave_bias_target(policy, freq_next, - CPUFREQ_RELATION_L); - __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); - } -} - -static void od_dbs_timer(struct work_struct *work) -{ - struct od_cpu_dbs_info_s *dbs_info = - container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work); - unsigned int cpu = dbs_info->cdbs.cur_policy->cpu; - struct od_cpu_dbs_info_s *core_dbs_info = &per_cpu(od_cpu_dbs_info, - cpu); - struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data; - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - int delay = 0, sample_type = core_dbs_info->sample_type; - bool modify_all = true; - - mutex_lock(&core_dbs_info->cdbs.timer_mutex); - if (!need_load_eval(&core_dbs_info->cdbs, od_tuners->sampling_rate)) { - modify_all = false; - goto max_delay; - } - - /* Common NORMAL_SAMPLE setup */ - core_dbs_info->sample_type = OD_NORMAL_SAMPLE; - if (sample_type == OD_SUB_SAMPLE) { - delay = core_dbs_info->freq_lo_jiffies; - __cpufreq_driver_target(core_dbs_info->cdbs.cur_policy, - core_dbs_info->freq_lo, CPUFREQ_RELATION_H); - } else { - dbs_check_cpu(dbs_data, cpu); - if (core_dbs_info->freq_lo) { - /* Setup timer for SUB_SAMPLE */ - core_dbs_info->sample_type = OD_SUB_SAMPLE; - delay = core_dbs_info->freq_hi_jiffies; - } - } - -max_delay: - if (!delay) - delay = delay_for_sampling_rate(od_tuners->sampling_rate - * core_dbs_info->rate_mult); - - gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all); - mutex_unlock(&core_dbs_info->cdbs.timer_mutex); -} - -/************************** sysfs interface ************************/ -static struct common_dbs_data od_dbs_cdata; - -/** - * update_sampling_rate - update sampling rate effective immediately if needed. - * @new_rate: new sampling rate - * - * If new rate is smaller than the old, simply updating - * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the - * original sampling_rate was 1 second and the requested new sampling rate is 10 - * ms because the user needs immediate reaction from ondemand governor, but not - * sure if higher frequency will be required or not, then, the governor may - * change the sampling rate too late; up to 1 second later. Thus, if we are - * reducing the sampling rate, we need to make the new value effective - * immediately. - */ -static void update_sampling_rate(struct dbs_data *dbs_data, - unsigned int new_rate) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - int cpu; - - od_tuners->sampling_rate = new_rate = max(new_rate, - dbs_data->min_sampling_rate); - - for_each_online_cpu(cpu) { - struct cpufreq_policy *policy; - struct od_cpu_dbs_info_s *dbs_info; - unsigned long next_sampling, appointed_at; - - policy = cpufreq_cpu_get(cpu); - if (!policy) - continue; - if (policy->governor != &cpufreq_gov_ondemand) { - cpufreq_cpu_put(policy); - continue; - } - dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - cpufreq_cpu_put(policy); - - mutex_lock(&dbs_info->cdbs.timer_mutex); - - if (!delayed_work_pending(&dbs_info->cdbs.work)) { - mutex_unlock(&dbs_info->cdbs.timer_mutex); - continue; - } - - next_sampling = jiffies + usecs_to_jiffies(new_rate); - appointed_at = dbs_info->cdbs.work.timer.expires; - - if (time_before(next_sampling, appointed_at)) { - - mutex_unlock(&dbs_info->cdbs.timer_mutex); - cancel_delayed_work_sync(&dbs_info->cdbs.work); - mutex_lock(&dbs_info->cdbs.timer_mutex); - - gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, - usecs_to_jiffies(new_rate), true); - - } - mutex_unlock(&dbs_info->cdbs.timer_mutex); - } -} - -static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - - update_sampling_rate(dbs_data, input); - return count; -} - -static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - unsigned int input; - int ret; - unsigned int j; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - od_tuners->io_is_busy = !!input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, - j); - dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, - &dbs_info->cdbs.prev_cpu_wall, od_tuners->io_is_busy); - } - return count; -} - -static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || - input < MIN_FREQUENCY_UP_THRESHOLD) { - return -EINVAL; - } - /* Calculate the new adj_up_threshold */ - od_tuners->adj_up_threshold += input; - od_tuners->adj_up_threshold -= od_tuners->up_threshold; - - od_tuners->up_threshold = input; - return count; -} - -static ssize_t store_sampling_down_factor(struct dbs_data *dbs_data, - const char *buf, size_t count) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - unsigned int input, j; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) - return -EINVAL; - od_tuners->sampling_down_factor = input; - - /* Reset down sampling multiplier in case it was active */ - for_each_online_cpu(j) { - struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, - j); - dbs_info->rate_mult = 1; - } - return count; -} - -static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data, - const char *buf, size_t count) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - unsigned int input; - int ret; - - unsigned int j; - - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; - - if (input > 1) - input = 1; - - if (input == od_tuners->ignore_nice_load) { /* nothing to do */ - return count; - } - od_tuners->ignore_nice_load = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - struct od_cpu_dbs_info_s *dbs_info; - dbs_info = &per_cpu(od_cpu_dbs_info, j); - dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, - &dbs_info->cdbs.prev_cpu_wall, od_tuners->io_is_busy); - if (od_tuners->ignore_nice_load) - dbs_info->cdbs.prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - - } - return count; -} - -static ssize_t store_powersave_bias(struct dbs_data *dbs_data, const char *buf, - size_t count) -{ - struct od_dbs_tuners *od_tuners = dbs_data->tuners; - unsigned int input; - int ret; - ret = sscanf(buf, "%u", &input); - - if (ret != 1) - return -EINVAL; - - if (input > 1000) - input = 1000; - - od_tuners->powersave_bias = input; - ondemand_powersave_bias_init(); - return count; -} - -show_store_one(od, sampling_rate); -show_store_one(od, io_is_busy); -show_store_one(od, up_threshold); -show_store_one(od, sampling_down_factor); -show_store_one(od, ignore_nice_load); -show_store_one(od, powersave_bias); -declare_show_sampling_rate_min(od); - -gov_sys_pol_attr_rw(sampling_rate); -gov_sys_pol_attr_rw(io_is_busy); -gov_sys_pol_attr_rw(up_threshold); -gov_sys_pol_attr_rw(sampling_down_factor); -gov_sys_pol_attr_rw(ignore_nice_load); -gov_sys_pol_attr_rw(powersave_bias); -gov_sys_pol_attr_ro(sampling_rate_min); - -static struct attribute *dbs_attributes_gov_sys[] = { - &sampling_rate_min_gov_sys.attr, - &sampling_rate_gov_sys.attr, - &up_threshold_gov_sys.attr, - &sampling_down_factor_gov_sys.attr, - &ignore_nice_load_gov_sys.attr, - &powersave_bias_gov_sys.attr, - &io_is_busy_gov_sys.attr, - NULL -}; - -static struct attribute_group od_attr_group_gov_sys = { - .attrs = dbs_attributes_gov_sys, - .name = "ondemand", -}; - -static struct attribute *dbs_attributes_gov_pol[] = { - &sampling_rate_min_gov_pol.attr, - &sampling_rate_gov_pol.attr, - &up_threshold_gov_pol.attr, - &sampling_down_factor_gov_pol.attr, - &ignore_nice_load_gov_pol.attr, - &powersave_bias_gov_pol.attr, - &io_is_busy_gov_pol.attr, - NULL -}; - -static struct attribute_group od_attr_group_gov_pol = { - .attrs = dbs_attributes_gov_pol, - .name = "ondemand", -}; - -/************************** sysfs end ************************/ - -static int od_init(struct dbs_data *dbs_data) -{ - struct od_dbs_tuners *tuners; - u64 idle_time; - int cpu; - - tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL); - if (!tuners) { - pr_err("%s: kzalloc failed\n", __func__); - return -ENOMEM; - } - - cpu = get_cpu(); - idle_time = get_cpu_idle_time_us(cpu, NULL); - put_cpu(); - if (idle_time != -1ULL) { - /* Idle micro accounting is supported. Use finer thresholds */ - tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; - tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD - - MICRO_FREQUENCY_DOWN_DIFFERENTIAL; - /* - * In nohz/micro accounting case we set the minimum frequency - * not depending on HZ, but fixed (very low). The deferred - * timer might skip some samples if idle/sleeping as needed. - */ - dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; - } else { - tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; - tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD - - DEF_FREQUENCY_DOWN_DIFFERENTIAL; - - /* For correct statistics, we need 10 ticks for each measure */ - dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * - jiffies_to_usecs(10); - } - - tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; - tuners->ignore_nice_load = 0; - tuners->powersave_bias = default_powersave_bias; - tuners->io_is_busy = should_io_be_busy(); - - dbs_data->tuners = tuners; - mutex_init(&dbs_data->mutex); - return 0; -} - -static void od_exit(struct dbs_data *dbs_data) -{ - kfree(dbs_data->tuners); -} - -define_get_cpu_dbs_routines(od_cpu_dbs_info); - -static struct od_ops od_ops = { - .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu, - .powersave_bias_target = generic_powersave_bias_target, - .freq_increase = dbs_freq_increase, -}; - -static struct common_dbs_data od_dbs_cdata = { - .governor = GOV_ONDEMAND, - .attr_group_gov_sys = &od_attr_group_gov_sys, - .attr_group_gov_pol = &od_attr_group_gov_pol, - .get_cpu_cdbs = get_cpu_cdbs, - .get_cpu_dbs_info_s = get_cpu_dbs_info_s, - .gov_dbs_timer = od_dbs_timer, - .gov_check_cpu = od_check_cpu, - .gov_ops = &od_ops, - .init = od_init, - .exit = od_exit, -}; - -static void od_set_powersave_bias(unsigned int powersave_bias) -{ - struct cpufreq_policy *policy; - struct dbs_data *dbs_data; - struct od_dbs_tuners *od_tuners; - unsigned int cpu; - cpumask_t done; - - default_powersave_bias = powersave_bias; - cpumask_clear(&done); - - get_online_cpus(); - for_each_online_cpu(cpu) { - if (cpumask_test_cpu(cpu, &done)) - continue; - - policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; - if (!policy) - continue; - - cpumask_or(&done, &done, policy->cpus); - - if (policy->governor != &cpufreq_gov_ondemand) - continue; - - dbs_data = policy->governor_data; - od_tuners = dbs_data->tuners; - od_tuners->powersave_bias = default_powersave_bias; - } - put_online_cpus(); -} - -void od_register_powersave_bias_handler(unsigned int (*f) - (struct cpufreq_policy *, unsigned int, unsigned int), - unsigned int powersave_bias) -{ - od_ops.powersave_bias_target = f; - od_set_powersave_bias(powersave_bias); -} -EXPORT_SYMBOL_GPL(od_register_powersave_bias_handler); - -void od_unregister_powersave_bias_handler(void) -{ - od_ops.powersave_bias_target = generic_powersave_bias_target; - od_set_powersave_bias(0); -} -EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler); - -static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, - unsigned int event) -{ - return cpufreq_governor_dbs(policy, &od_dbs_cdata, event); -} - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -static -#endif -struct cpufreq_governor cpufreq_gov_ondemand = { - .name = "ondemand", - .governor = od_cpufreq_governor_dbs, - .max_transition_latency = TRANSITION_LATENCY_LIMIT, - .owner = THIS_MODULE, -}; - -static int __init cpufreq_gov_dbs_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_ondemand); -} - -static void __exit cpufreq_gov_dbs_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_ondemand); -} - -MODULE_AUTHOR("Venkatesh Pallipadi "); -MODULE_AUTHOR("Alexey Starikovskiy "); -MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " - "Low Latency Frequency Transition capable processors"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -fs_initcall(cpufreq_gov_dbs_init); -#else -module_init(cpufreq_gov_dbs_init); -#endif -module_exit(cpufreq_gov_dbs_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_performance.c b/linux-3.4/drivers/cpufreq.new/cpufreq_performance.c deleted file mode 100644 index f13a8a9a..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_performance.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * linux/drivers/cpufreq/cpufreq_performance.c - * - * Copyright (C) 2002 - 2003 Dominik Brodowski - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include - - -static int cpufreq_governor_performance(struct cpufreq_policy *policy, - unsigned int event) -{ - switch (event) { - case CPUFREQ_GOV_START: - case CPUFREQ_GOV_LIMITS: - pr_debug("setting to %u kHz because of event %u\n", - policy->max, event); - __cpufreq_driver_target(policy, policy->max, - CPUFREQ_RELATION_H); - break; - default: - break; - } - return 0; -} - -#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE -static -#endif -struct cpufreq_governor cpufreq_gov_performance = { - .name = "performance", - .governor = cpufreq_governor_performance, - .owner = THIS_MODULE, -}; - - -static int __init cpufreq_gov_performance_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_performance); -} - - -static void __exit cpufreq_gov_performance_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_performance); -} - - -MODULE_AUTHOR("Dominik Brodowski "); -MODULE_DESCRIPTION("CPUfreq policy governor 'performance'"); -MODULE_LICENSE("GPL"); - -fs_initcall(cpufreq_gov_performance_init); -module_exit(cpufreq_gov_performance_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_powersave.c b/linux-3.4/drivers/cpufreq.new/cpufreq_powersave.c deleted file mode 100644 index 4c2eb512..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_powersave.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * linux/drivers/cpufreq/cpufreq_powersave.c - * - * Copyright (C) 2002 - 2003 Dominik Brodowski - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include - -static int cpufreq_governor_powersave(struct cpufreq_policy *policy, - unsigned int event) -{ - switch (event) { - case CPUFREQ_GOV_START: - case CPUFREQ_GOV_LIMITS: - pr_debug("setting to %u kHz because of event %u\n", - policy->min, event); - __cpufreq_driver_target(policy, policy->min, - CPUFREQ_RELATION_L); - break; - default: - break; - } - return 0; -} - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE -static -#endif -struct cpufreq_governor cpufreq_gov_powersave = { - .name = "powersave", - .governor = cpufreq_governor_powersave, - .owner = THIS_MODULE, -}; - -static int __init cpufreq_gov_powersave_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_powersave); -} - - -static void __exit cpufreq_gov_powersave_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_powersave); -} - - -MODULE_AUTHOR("Dominik Brodowski "); -MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE -fs_initcall(cpufreq_gov_powersave_init); -#else -module_init(cpufreq_gov_powersave_init); -#endif -module_exit(cpufreq_gov_powersave_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_stats.c b/linux-3.4/drivers/cpufreq.new/cpufreq_stats.c deleted file mode 100755 index 038c7cca..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_stats.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * drivers/cpufreq/cpufreq_stats.c - * - * Copyright (C) 2003-2004 Venkatesh Pallipadi . - * (C) 2004 Zou Nan hai . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_BL_SWITCHER -#include -#endif - -static spinlock_t cpufreq_stats_lock; - -struct cpufreq_stats { - unsigned int cpu; - unsigned int total_trans; - unsigned long long last_time; - unsigned int max_state; - unsigned int state_num; - unsigned int last_index; - u64 *time_in_state; - unsigned int *freq_table; -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS - unsigned int *trans_table; -#endif -}; - -static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table); - -struct cpufreq_stats_attribute { - struct attribute attr; - ssize_t(*show) (struct cpufreq_stats *, char *); -}; - -static int cpufreq_stats_update(unsigned int cpu) -{ - struct cpufreq_stats *stat; - unsigned long long cur_time; - - cur_time = get_jiffies_64(); - spin_lock(&cpufreq_stats_lock); - stat = per_cpu(cpufreq_stats_table, cpu); - if (stat->time_in_state) - stat->time_in_state[stat->last_index] += - cur_time - stat->last_time; - stat->last_time = cur_time; - spin_unlock(&cpufreq_stats_lock); - return 0; -} - -static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) -{ - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); - if (!stat) - return 0; - return sprintf(buf, "%d\n", - per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); -} - -static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) -{ - ssize_t len = 0; - int i; - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); - if (!stat) - return 0; - cpufreq_stats_update(stat->cpu); - for (i = 0; i < stat->state_num; i++) { - len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], - (unsigned long long) - cputime64_to_clock_t(stat->time_in_state[i])); - } - return len; -} - -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS -static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) -{ - ssize_t len = 0; - int i, j; - - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); - if (!stat) - return 0; - cpufreq_stats_update(stat->cpu); - len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); - len += snprintf(buf + len, PAGE_SIZE - len, " : "); - for (i = 0; i < stat->state_num; i++) { - if (len >= PAGE_SIZE) - break; - len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", - stat->freq_table[i]); - } - if (len >= PAGE_SIZE) - return PAGE_SIZE; - - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); - - for (i = 0; i < stat->state_num; i++) { - if (len >= PAGE_SIZE) - break; - - len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", - stat->freq_table[i]); - - for (j = 0; j < stat->state_num; j++) { - if (len >= PAGE_SIZE) - break; - len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", - stat->trans_table[i*stat->max_state+j]); - } - if (len >= PAGE_SIZE) - break; - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); - } - if (len >= PAGE_SIZE) - return PAGE_SIZE; - return len; -} -cpufreq_freq_attr_ro(trans_table); -#endif - -cpufreq_freq_attr_ro(total_trans); -cpufreq_freq_attr_ro(time_in_state); - -static struct attribute *default_attrs[] = { - &total_trans.attr, - &time_in_state.attr, -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS - &trans_table.attr, -#endif - NULL -}; -static struct attribute_group stats_attr_group = { - .attrs = default_attrs, - .name = "stats" -}; - -static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) -{ - int index; - for (index = 0; index < stat->max_state; index++) - if (stat->freq_table[index] == freq) - return index; - return -1; -} - -/* should be called late in the CPU removal sequence so that the stats - * memory is still available in case someone tries to use it. - */ -static void cpufreq_stats_free_table(unsigned int cpu) -{ - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu); - - if (stat) { - pr_debug("%s: Free stat table\n", __func__); - kfree(stat->time_in_state); - kfree(stat); - per_cpu(cpufreq_stats_table, cpu) = NULL; - } -} - -/* must be called early in the CPU removal sequence (before - * cpufreq_remove_dev) so that policy is still valid. - */ -static void cpufreq_stats_free_sysfs(unsigned int cpu) -{ - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - - if (!policy) - return; - - if (!cpufreq_frequency_get_table(cpu)) - goto put_ref; - - if (!policy_is_shared(policy)) { - pr_debug("%s: Free sysfs stat\n", __func__); - sysfs_remove_group(&policy->kobj, &stats_attr_group); - } - -put_ref: - cpufreq_cpu_put(policy); -} - -static int cpufreq_stats_create_table(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table) -{ - unsigned int i, j, count = 0, ret = 0; - struct cpufreq_stats *stat; - struct cpufreq_policy *data; - unsigned int alloc_size; - unsigned int cpu = policy->cpu; - if (per_cpu(cpufreq_stats_table, cpu)) - return -EBUSY; - stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL); - if ((stat) == NULL) - return -ENOMEM; - - data = cpufreq_cpu_get(cpu); - if (data == NULL) { - ret = -EINVAL; - goto error_get_fail; - } - - ret = sysfs_create_group(&data->kobj, &stats_attr_group); - if (ret) - goto error_out; - - stat->cpu = cpu; - per_cpu(cpufreq_stats_table, cpu) = stat; - - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - count++; - } - - alloc_size = count * sizeof(int) + count * sizeof(u64); - -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS - alloc_size += count * count * sizeof(int); -#endif - stat->max_state = count; - stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL); - if (!stat->time_in_state) { - ret = -ENOMEM; - goto error_out; - } - stat->freq_table = (unsigned int *)(stat->time_in_state + count); - -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS - stat->trans_table = stat->freq_table + count; -#endif - j = 0; - for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - if (freq_table_get_index(stat, freq) == -1) - stat->freq_table[j++] = freq; - } - stat->state_num = j; - spin_lock(&cpufreq_stats_lock); - stat->last_time = get_jiffies_64(); - stat->last_index = freq_table_get_index(stat, policy->cur); - spin_unlock(&cpufreq_stats_lock); - cpufreq_cpu_put(data); - return 0; -error_out: - cpufreq_cpu_put(data); -error_get_fail: - kfree(stat); - per_cpu(cpufreq_stats_table, cpu) = NULL; - return ret; -} - -static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) -{ - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, - policy->last_cpu); - - pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n", - policy->cpu, policy->last_cpu); - per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table, - policy->last_cpu); - per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL; - stat->cpu = policy->cpu; -} - -static int cpufreq_stat_notifier_policy(struct notifier_block *nb, - unsigned long val, void *data) -{ - int ret; - struct cpufreq_policy *policy = data; - struct cpufreq_frequency_table *table; - unsigned int cpu = policy->cpu; - - if (val == CPUFREQ_UPDATE_POLICY_CPU) { - cpufreq_stats_update_policy_cpu(policy); - return 0; - } - - if (val != CPUFREQ_NOTIFY) - return 0; - table = cpufreq_frequency_get_table(cpu); - if (!table) - return 0; - ret = cpufreq_stats_create_table(policy, table); - if (ret) - return ret; - return 0; -} - -static int cpufreq_stat_notifier_trans(struct notifier_block *nb, - unsigned long val, void *data) -{ - struct cpufreq_freqs *freq = data; - struct cpufreq_stats *stat; - int old_index, new_index; - - if (val != CPUFREQ_POSTCHANGE) - return 0; - - stat = per_cpu(cpufreq_stats_table, freq->cpu); - if (!stat) - return 0; - - old_index = stat->last_index; - new_index = freq_table_get_index(stat, freq->new); - - /* We can't do stat->time_in_state[-1]= .. */ - if (old_index == -1 || new_index == -1) - return 0; - - cpufreq_stats_update(freq->cpu); - - if (old_index == new_index) - return 0; - - spin_lock(&cpufreq_stats_lock); - stat->last_index = new_index; -#ifdef CONFIG_CPU_FREQ_STAT_DETAILS - stat->trans_table[old_index * stat->max_state + new_index]++; -#endif - stat->total_trans++; - spin_unlock(&cpufreq_stats_lock); - return 0; -} - -static int cpufreq_stats_create_table_cpu(unsigned int cpu) -{ - struct cpufreq_policy *policy; - struct cpufreq_frequency_table *table; - int ret = -ENODEV; - - policy = cpufreq_cpu_get(cpu); - if (!policy) - return -ENODEV; - - table = cpufreq_frequency_get_table(cpu); - if (!table) - goto out; - - ret = cpufreq_stats_create_table(policy, table); - -out: - cpufreq_cpu_put(policy); - return ret; -} - -static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, - unsigned long action, - void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cpufreq_update_policy(cpu); - break; - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - cpufreq_stats_free_sysfs(cpu); - break; - case CPU_DEAD: - case CPU_DEAD_FROZEN: - cpufreq_stats_free_table(cpu); - break; - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_stats_create_table_cpu(cpu); - break; - } - return NOTIFY_OK; -} - -/* priority=1 so this will get called before cpufreq_remove_dev */ -static struct notifier_block cpufreq_stat_cpu_notifier __refdata = { - .notifier_call = cpufreq_stat_cpu_callback, - .priority = 1, -}; - -static struct notifier_block notifier_policy_block = { - .notifier_call = cpufreq_stat_notifier_policy -}; - -static struct notifier_block notifier_trans_block = { - .notifier_call = cpufreq_stat_notifier_trans -}; - -static int cpufreq_stats_setup(void) -{ - int ret; - unsigned int cpu; - - spin_lock_init(&cpufreq_stats_lock); - ret = cpufreq_register_notifier(¬ifier_policy_block, - CPUFREQ_POLICY_NOTIFIER); - if (ret) - return ret; - - register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); - for_each_online_cpu(cpu) - cpufreq_update_policy(cpu); - - ret = cpufreq_register_notifier(¬ifier_trans_block, - CPUFREQ_TRANSITION_NOTIFIER); - if (ret) { - cpufreq_unregister_notifier(¬ifier_policy_block, - CPUFREQ_POLICY_NOTIFIER); - unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); - for_each_online_cpu(cpu) - cpufreq_stats_free_table(cpu); - return ret; - } - - return 0; -} - -static void cpufreq_stats_cleanup(void) -{ - unsigned int cpu; - - cpufreq_unregister_notifier(¬ifier_policy_block, - CPUFREQ_POLICY_NOTIFIER); - cpufreq_unregister_notifier(¬ifier_trans_block, - CPUFREQ_TRANSITION_NOTIFIER); - unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); - for_each_online_cpu(cpu) { - cpufreq_stats_free_table(cpu); - cpufreq_stats_free_sysfs(cpu); - } -} - -#ifdef CONFIG_BL_SWITCHER -static int cpufreq_stats_switcher_notifier(struct notifier_block *nfb, - unsigned long action, void *_arg) -{ - switch (action) { - case BL_NOTIFY_PRE_ENABLE: - case BL_NOTIFY_PRE_DISABLE: - cpufreq_stats_cleanup(); - break; - - case BL_NOTIFY_POST_ENABLE: - case BL_NOTIFY_POST_DISABLE: - cpufreq_stats_setup(); - break; - - default: - return NOTIFY_DONE; - } - - return NOTIFY_OK; -} - -static struct notifier_block switcher_notifier = { - .notifier_call = cpufreq_stats_switcher_notifier, -}; -#endif - -static int __init cpufreq_stats_init(void) -{ - int ret; - spin_lock_init(&cpufreq_stats_lock); - - ret = cpufreq_stats_setup(); -#ifdef CONFIG_BL_SWITCHER - if (!ret) - bL_switcher_register_notifier(&switcher_notifier); -#endif - return ret; -} - -static void __exit cpufreq_stats_exit(void) -{ -#ifdef CONFIG_BL_SWITCHER - bL_switcher_unregister_notifier(&switcher_notifier); -#endif - cpufreq_stats_cleanup(); -} - -MODULE_AUTHOR("Zou Nan hai "); -MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats " - "through sysfs filesystem"); -MODULE_LICENSE("GPL"); - -module_init(cpufreq_stats_init); -module_exit(cpufreq_stats_exit); diff --git a/linux-3.4/drivers/cpufreq.new/cpufreq_userspace.c b/linux-3.4/drivers/cpufreq.new/cpufreq_userspace.c deleted file mode 100644 index bedac1aa..00000000 --- a/linux-3.4/drivers/cpufreq.new/cpufreq_userspace.c +++ /dev/null @@ -1,222 +0,0 @@ - -/* - * linux/drivers/cpufreq/cpufreq_userspace.c - * - * Copyright (C) 2001 Russell King - * (C) 2002 - 2004 Dominik Brodowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * A few values needed by the userspace governor - */ -static DEFINE_PER_CPU(unsigned int, cpu_max_freq); -static DEFINE_PER_CPU(unsigned int, cpu_min_freq); -static DEFINE_PER_CPU(unsigned int, cpu_cur_freq); /* current CPU freq */ -static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by - userspace */ -static DEFINE_PER_CPU(unsigned int, cpu_is_managed); - -static DEFINE_MUTEX(userspace_mutex); -static int cpus_using_userspace_governor; - -/* keep track of frequency transitions */ -static int -userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct cpufreq_freqs *freq = data; - - if (!per_cpu(cpu_is_managed, freq->cpu)) - return 0; - - if (val == CPUFREQ_POSTCHANGE) { - pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n", - freq->cpu, freq->new); - per_cpu(cpu_cur_freq, freq->cpu) = freq->new; - } - - return 0; -} - -static struct notifier_block userspace_cpufreq_notifier_block = { - .notifier_call = userspace_cpufreq_notifier -}; - - -/** - * cpufreq_set - set the CPU frequency - * @policy: pointer to policy struct where freq is being set - * @freq: target frequency in kHz - * - * Sets the CPU frequency to freq. - */ -static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) -{ - int ret = -EINVAL; - - pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); - - mutex_lock(&userspace_mutex); - if (!per_cpu(cpu_is_managed, policy->cpu)) - goto err; - - per_cpu(cpu_set_freq, policy->cpu) = freq; - - if (freq < per_cpu(cpu_min_freq, policy->cpu)) - freq = per_cpu(cpu_min_freq, policy->cpu); - if (freq > per_cpu(cpu_max_freq, policy->cpu)) - freq = per_cpu(cpu_max_freq, policy->cpu); - - /* - * We're safe from concurrent calls to ->target() here - * as we hold the userspace_mutex lock. If we were calling - * cpufreq_driver_target, a deadlock situation might occur: - * A: cpufreq_set (lock userspace_mutex) -> - * cpufreq_driver_target(lock policy->lock) - * B: cpufreq_set_policy(lock policy->lock) -> - * __cpufreq_governor -> - * cpufreq_governor_userspace (lock userspace_mutex) - */ - ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); - - err: - mutex_unlock(&userspace_mutex); - return ret; -} - - -static ssize_t show_speed(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%u\n", per_cpu(cpu_cur_freq, policy->cpu)); -} - -static int cpufreq_governor_userspace(struct cpufreq_policy *policy, - unsigned int event) -{ - unsigned int cpu = policy->cpu; - int rc = 0; - - switch (event) { - case CPUFREQ_GOV_START: - if (!cpu_online(cpu)) - return -EINVAL; - BUG_ON(!policy->cur); - mutex_lock(&userspace_mutex); - - if (cpus_using_userspace_governor == 0) { - cpufreq_register_notifier( - &userspace_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - cpus_using_userspace_governor++; - - per_cpu(cpu_is_managed, cpu) = 1; - per_cpu(cpu_min_freq, cpu) = policy->min; - per_cpu(cpu_max_freq, cpu) = policy->max; - per_cpu(cpu_cur_freq, cpu) = policy->cur; - per_cpu(cpu_set_freq, cpu) = policy->cur; - pr_debug("managing cpu %u started " - "(%u - %u kHz, currently %u kHz)\n", - cpu, - per_cpu(cpu_min_freq, cpu), - per_cpu(cpu_max_freq, cpu), - per_cpu(cpu_cur_freq, cpu)); - - mutex_unlock(&userspace_mutex); - break; - case CPUFREQ_GOV_STOP: - mutex_lock(&userspace_mutex); - cpus_using_userspace_governor--; - if (cpus_using_userspace_governor == 0) { - cpufreq_unregister_notifier( - &userspace_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - - per_cpu(cpu_is_managed, cpu) = 0; - per_cpu(cpu_min_freq, cpu) = 0; - per_cpu(cpu_max_freq, cpu) = 0; - per_cpu(cpu_set_freq, cpu) = 0; - pr_debug("managing cpu %u stopped\n", cpu); - mutex_unlock(&userspace_mutex); - break; - case CPUFREQ_GOV_LIMITS: - mutex_lock(&userspace_mutex); - pr_debug("limit event for cpu %u: %u - %u kHz, " - "currently %u kHz, last set to %u kHz\n", - cpu, policy->min, policy->max, - per_cpu(cpu_cur_freq, cpu), - per_cpu(cpu_set_freq, cpu)); - if (policy->max < per_cpu(cpu_set_freq, cpu)) { - __cpufreq_driver_target(policy, policy->max, - CPUFREQ_RELATION_H); - } else if (policy->min > per_cpu(cpu_set_freq, cpu)) { - __cpufreq_driver_target(policy, policy->min, - CPUFREQ_RELATION_L); - } else { - __cpufreq_driver_target(policy, - per_cpu(cpu_set_freq, cpu), - CPUFREQ_RELATION_L); - } - per_cpu(cpu_min_freq, cpu) = policy->min; - per_cpu(cpu_max_freq, cpu) = policy->max; - per_cpu(cpu_cur_freq, cpu) = policy->cur; - mutex_unlock(&userspace_mutex); - break; - } - return rc; -} - - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE -static -#endif -struct cpufreq_governor cpufreq_gov_userspace = { - .name = "userspace", - .governor = cpufreq_governor_userspace, - .store_setspeed = cpufreq_set, - .show_setspeed = show_speed, - .owner = THIS_MODULE, -}; - -static int __init cpufreq_gov_userspace_init(void) -{ - return cpufreq_register_governor(&cpufreq_gov_userspace); -} - - -static void __exit cpufreq_gov_userspace_exit(void) -{ - cpufreq_unregister_governor(&cpufreq_gov_userspace); -} - - -MODULE_AUTHOR("Dominik Brodowski , " - "Russell King "); -MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE -fs_initcall(cpufreq_gov_userspace_init); -#else -module_init(cpufreq_gov_userspace_init); -#endif -module_exit(cpufreq_gov_userspace_exit); diff --git a/linux-3.4/drivers/cpufreq.new/db8500-cpufreq.c b/linux-3.4/drivers/cpufreq.new/db8500-cpufreq.c deleted file mode 100644 index 0bf1b891..00000000 --- a/linux-3.4/drivers/cpufreq.new/db8500-cpufreq.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * License Terms: GNU General Public License v2 - * Author: Sundar Iyer - * Author: Martin Persson - * Author: Jonas Aaberg - * - */ -#include -#include -#include -#include -#include -#include - -static struct cpufreq_frequency_table freq_table[] = { - [0] = { - .index = 0, - .frequency = 200000, - }, - [1] = { - .index = 1, - .frequency = 400000, - }, - [2] = { - .index = 2, - .frequency = 800000, - }, - [3] = { - /* Used for MAX_OPP, if available */ - .index = 3, - .frequency = CPUFREQ_TABLE_END, - }, - [4] = { - .index = 4, - .frequency = CPUFREQ_TABLE_END, - }, -}; - -static enum arm_opp idx2opp[] = { - ARM_EXTCLK, - ARM_50_OPP, - ARM_100_OPP, - ARM_MAX_OPP -}; - -static struct freq_attr *db8500_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static int db8500_cpufreq_verify_speed(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, freq_table); -} - -static int db8500_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct cpufreq_freqs freqs; - unsigned int idx; - - /* scale the target frequency to one of the extremes supported */ - if (target_freq < policy->cpuinfo.min_freq) - target_freq = policy->cpuinfo.min_freq; - if (target_freq > policy->cpuinfo.max_freq) - target_freq = policy->cpuinfo.max_freq; - - /* Lookup the next frequency */ - if (cpufreq_frequency_table_target - (policy, freq_table, target_freq, relation, &idx)) { - return -EINVAL; - } - - freqs.old = policy->cur; - freqs.new = freq_table[idx].frequency; - - if (freqs.old == freqs.new) - return 0; - - /* pre-change notification */ - for_each_cpu(freqs.cpu, policy->cpus) - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* request the PRCM unit for opp change */ - if (prcmu_set_arm_opp(idx2opp[idx])) { - pr_err("db8500-cpufreq: Failed to set OPP level\n"); - return -EINVAL; - } - - /* post change notification */ - for_each_cpu(freqs.cpu, policy->cpus) - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return 0; -} - -static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) -{ - int i; - /* request the prcm to get the current ARM opp */ - for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++) - ; - return freq_table[i].frequency; -} - -static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) -{ - int i, res; - - BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); - - if (prcmu_has_arm_maxopp()) - freq_table[3].frequency = 1000000; - - pr_info("db8500-cpufreq : Available frequencies:\n"); - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) - pr_info(" %d Mhz\n", freq_table[i].frequency/1000); - - /* get policy fields based on the table */ - res = cpufreq_frequency_table_cpuinfo(policy, freq_table); - if (!res) - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); - else { - pr_err("db8500-cpufreq : Failed to read policy table\n"); - return res; - } - - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; - policy->cur = db8500_cpufreq_getspeed(policy->cpu); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - - /* - * FIXME : Need to take time measurement across the target() - * function with no/some/all drivers in the notification - * list. - */ - policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */ - - /* policy sharing between dual CPUs */ - cpumask_copy(policy->cpus, cpu_present_mask); - - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; - - return 0; -} - -static struct cpufreq_driver db8500_cpufreq_driver = { - .flags = CPUFREQ_STICKY, - .verify = db8500_cpufreq_verify_speed, - .target = db8500_cpufreq_target, - .get = db8500_cpufreq_getspeed, - .init = db8500_cpufreq_init, - .name = "DB8500", - .attr = db8500_cpufreq_attr, -}; - -static int __init db8500_cpufreq_register(void) -{ - if (!cpu_is_u8500v20_or_later()) - return -ENODEV; - - pr_info("cpufreq for DB8500 started\n"); - return cpufreq_register_driver(&db8500_cpufreq_driver); -} -device_initcall(db8500_cpufreq_register); diff --git a/linux-3.4/drivers/cpufreq.new/e_powersaver.c b/linux-3.4/drivers/cpufreq.new/e_powersaver.c deleted file mode 100644 index 3fffbe60..00000000 --- a/linux-3.4/drivers/cpufreq.new/e_powersaver.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Based on documentation provided by Dave Jones. Thanks! - * - * Licensed under the terms of the GNU GPL License version 2. - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE -#include -#include -#endif - -#define EPS_BRAND_C7M 0 -#define EPS_BRAND_C7 1 -#define EPS_BRAND_EDEN 2 -#define EPS_BRAND_C3 3 -#define EPS_BRAND_C7D 4 - -struct eps_cpu_data { - u32 fsb; -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE - u32 bios_limit; -#endif - struct cpufreq_frequency_table freq_table[]; -}; - -static struct eps_cpu_data *eps_cpu[NR_CPUS]; - -/* Module parameters */ -static int freq_failsafe_off; -static int voltage_failsafe_off; -static int set_max_voltage; - -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE -static int ignore_acpi_limit; - -static struct acpi_processor_performance *eps_acpi_cpu_perf; - -/* Minimum necessary to get acpi_processor_get_bios_limit() working */ -static int eps_acpi_init(void) -{ - eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!eps_acpi_cpu_perf) - return -ENOMEM; - - if (!zalloc_cpumask_var(&eps_acpi_cpu_perf->shared_cpu_map, - GFP_KERNEL)) { - kfree(eps_acpi_cpu_perf); - eps_acpi_cpu_perf = NULL; - return -ENOMEM; - } - - if (acpi_processor_register_performance(eps_acpi_cpu_perf, 0)) { - free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map); - kfree(eps_acpi_cpu_perf); - eps_acpi_cpu_perf = NULL; - return -EIO; - } - return 0; -} - -static int eps_acpi_exit(struct cpufreq_policy *policy) -{ - if (eps_acpi_cpu_perf) { - acpi_processor_unregister_performance(eps_acpi_cpu_perf, 0); - free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map); - kfree(eps_acpi_cpu_perf); - eps_acpi_cpu_perf = NULL; - } - return 0; -} -#endif - -static unsigned int eps_get(unsigned int cpu) -{ - struct eps_cpu_data *centaur; - u32 lo, hi; - - if (cpu) - return 0; - centaur = eps_cpu[cpu]; - if (centaur == NULL) - return 0; - - /* Return current frequency */ - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - return centaur->fsb * ((lo >> 8) & 0xff); -} - -static int eps_set_state(struct eps_cpu_data *centaur, - unsigned int cpu, - u32 dest_state) -{ - struct cpufreq_freqs freqs; - u32 lo, hi; - int err = 0; - int i; - - freqs.old = eps_get(cpu); - freqs.new = centaur->fsb * ((dest_state >> 8) & 0xff); - freqs.cpu = cpu; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* Wait while CPU is busy */ - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - i = 0; - while (lo & ((1 << 16) | (1 << 17))) { - udelay(16); - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - i++; - if (unlikely(i > 64)) { - err = -ENODEV; - goto postchange; - } - } - /* Set new multiplier and voltage */ - wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0); - /* Wait until transition end */ - i = 0; - do { - udelay(16); - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - i++; - if (unlikely(i > 64)) { - err = -ENODEV; - goto postchange; - } - } while (lo & ((1 << 16) | (1 << 17))); - - /* Return current frequency */ -postchange: - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - freqs.new = centaur->fsb * ((lo >> 8) & 0xff); - -#ifdef DEBUG - { - u8 current_multiplier, current_voltage; - - /* Print voltage and multiplier */ - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - current_voltage = lo & 0xff; - printk(KERN_INFO "eps: Current voltage = %dmV\n", - current_voltage * 16 + 700); - current_multiplier = (lo >> 8) & 0xff; - printk(KERN_INFO "eps: Current multiplier = %d\n", - current_multiplier); - } -#endif - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - return err; -} - -static int eps_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct eps_cpu_data *centaur; - unsigned int newstate = 0; - unsigned int cpu = policy->cpu; - unsigned int dest_state; - int ret; - - if (unlikely(eps_cpu[cpu] == NULL)) - return -ENODEV; - centaur = eps_cpu[cpu]; - - if (unlikely(cpufreq_frequency_table_target(policy, - &eps_cpu[cpu]->freq_table[0], - target_freq, - relation, - &newstate))) { - return -EINVAL; - } - - /* Make frequency transition */ - dest_state = centaur->freq_table[newstate].index & 0xffff; - ret = eps_set_state(centaur, cpu, dest_state); - if (ret) - printk(KERN_ERR "eps: Timeout!\n"); - return ret; -} - -static int eps_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, - &eps_cpu[policy->cpu]->freq_table[0]); -} - -static int eps_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int i; - u32 lo, hi; - u64 val; - u8 current_multiplier, current_voltage; - u8 max_multiplier, max_voltage; - u8 min_multiplier, min_voltage; - u8 brand = 0; - u32 fsb; - struct eps_cpu_data *centaur; - struct cpuinfo_x86 *c = &cpu_data(0); - struct cpufreq_frequency_table *f_table; - int k, step, voltage; - int ret; - int states; -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE - unsigned int limit; -#endif - - if (policy->cpu != 0) - return -ENODEV; - - /* Check brand */ - printk(KERN_INFO "eps: Detected VIA "); - - switch (c->x86_model) { - case 10: - rdmsr(0x1153, lo, hi); - brand = (((lo >> 2) ^ lo) >> 18) & 3; - printk(KERN_CONT "Model A "); - break; - case 13: - rdmsr(0x1154, lo, hi); - brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff; - printk(KERN_CONT "Model D "); - break; - } - - switch (brand) { - case EPS_BRAND_C7M: - printk(KERN_CONT "C7-M\n"); - break; - case EPS_BRAND_C7: - printk(KERN_CONT "C7\n"); - break; - case EPS_BRAND_EDEN: - printk(KERN_CONT "Eden\n"); - break; - case EPS_BRAND_C7D: - printk(KERN_CONT "C7-D\n"); - break; - case EPS_BRAND_C3: - printk(KERN_CONT "C3\n"); - return -ENODEV; - break; - } - /* Enable Enhanced PowerSaver */ - rdmsrl(MSR_IA32_MISC_ENABLE, val); - if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { - val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP; - wrmsrl(MSR_IA32_MISC_ENABLE, val); - /* Can be locked at 0 */ - rdmsrl(MSR_IA32_MISC_ENABLE, val); - if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { - printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n"); - return -ENODEV; - } - } - - /* Print voltage and multiplier */ - rdmsr(MSR_IA32_PERF_STATUS, lo, hi); - current_voltage = lo & 0xff; - printk(KERN_INFO "eps: Current voltage = %dmV\n", - current_voltage * 16 + 700); - current_multiplier = (lo >> 8) & 0xff; - printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); - - /* Print limits */ - max_voltage = hi & 0xff; - printk(KERN_INFO "eps: Highest voltage = %dmV\n", - max_voltage * 16 + 700); - max_multiplier = (hi >> 8) & 0xff; - printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier); - min_voltage = (hi >> 16) & 0xff; - printk(KERN_INFO "eps: Lowest voltage = %dmV\n", - min_voltage * 16 + 700); - min_multiplier = (hi >> 24) & 0xff; - printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier); - - /* Sanity checks */ - if (current_multiplier == 0 || max_multiplier == 0 - || min_multiplier == 0) - return -EINVAL; - if (current_multiplier > max_multiplier - || max_multiplier <= min_multiplier) - return -EINVAL; - if (current_voltage > 0x1f || max_voltage > 0x1f) - return -EINVAL; - if (max_voltage < min_voltage - || current_voltage < min_voltage - || current_voltage > max_voltage) - return -EINVAL; - - /* Check for systems using underclocked CPU */ - if (!freq_failsafe_off && max_multiplier != current_multiplier) { - printk(KERN_INFO "eps: Your processor is running at different " - "frequency then its maximum. Aborting.\n"); - printk(KERN_INFO "eps: You can use freq_failsafe_off option " - "to disable this check.\n"); - return -EINVAL; - } - if (!voltage_failsafe_off && max_voltage != current_voltage) { - printk(KERN_INFO "eps: Your processor is running at different " - "voltage then its maximum. Aborting.\n"); - printk(KERN_INFO "eps: You can use voltage_failsafe_off " - "option to disable this check.\n"); - return -EINVAL; - } - - /* Calc FSB speed */ - fsb = cpu_khz / current_multiplier; - -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE - /* Check for ACPI processor speed limit */ - if (!ignore_acpi_limit && !eps_acpi_init()) { - if (!acpi_processor_get_bios_limit(policy->cpu, &limit)) { - printk(KERN_INFO "eps: ACPI limit %u.%uGHz\n", - limit/1000000, - (limit%1000000)/10000); - eps_acpi_exit(policy); - /* Check if max_multiplier is in BIOS limits */ - if (limit && max_multiplier * fsb > limit) { - printk(KERN_INFO "eps: Aborting.\n"); - return -EINVAL; - } - } - } -#endif - - /* Allow user to set lower maximum voltage then that reported - * by processor */ - if (brand == EPS_BRAND_C7M && set_max_voltage) { - u32 v; - - /* Change mV to something hardware can use */ - v = (set_max_voltage - 700) / 16; - /* Check if voltage is within limits */ - if (v >= min_voltage && v <= max_voltage) { - printk(KERN_INFO "eps: Setting %dmV as maximum.\n", - v * 16 + 700); - max_voltage = v; - } - } - - /* Calc number of p-states supported */ - if (brand == EPS_BRAND_C7M) - states = max_multiplier - min_multiplier + 1; - else - states = 2; - - /* Allocate private data and frequency table for current cpu */ - centaur = kzalloc(sizeof(struct eps_cpu_data) - + (states + 1) * sizeof(struct cpufreq_frequency_table), - GFP_KERNEL); - if (!centaur) - return -ENOMEM; - eps_cpu[0] = centaur; - - /* Copy basic values */ - centaur->fsb = fsb; -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE - centaur->bios_limit = limit; -#endif - - /* Fill frequency and MSR value table */ - f_table = ¢aur->freq_table[0]; - if (brand != EPS_BRAND_C7M) { - f_table[0].frequency = fsb * min_multiplier; - f_table[0].index = (min_multiplier << 8) | min_voltage; - f_table[1].frequency = fsb * max_multiplier; - f_table[1].index = (max_multiplier << 8) | max_voltage; - f_table[2].frequency = CPUFREQ_TABLE_END; - } else { - k = 0; - step = ((max_voltage - min_voltage) * 256) - / (max_multiplier - min_multiplier); - for (i = min_multiplier; i <= max_multiplier; i++) { - voltage = (k * step) / 256 + min_voltage; - f_table[k].frequency = fsb * i; - f_table[k].index = (i << 8) | voltage; - k++; - } - f_table[k].frequency = CPUFREQ_TABLE_END; - } - - policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ - policy->cur = fsb * current_multiplier; - - ret = cpufreq_frequency_table_cpuinfo(policy, ¢aur->freq_table[0]); - if (ret) { - kfree(centaur); - return ret; - } - - cpufreq_frequency_table_get_attr(¢aur->freq_table[0], policy->cpu); - return 0; -} - -static int eps_cpu_exit(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - - /* Bye */ - cpufreq_frequency_table_put_attr(policy->cpu); - kfree(eps_cpu[cpu]); - eps_cpu[cpu] = NULL; - return 0; -} - -static struct freq_attr *eps_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver eps_driver = { - .verify = eps_verify, - .target = eps_target, - .init = eps_cpu_init, - .exit = eps_cpu_exit, - .get = eps_get, - .name = "e_powersaver", - .owner = THIS_MODULE, - .attr = eps_attr, -}; - - -/* This driver will work only on Centaur C7 processors with - * Enhanced SpeedStep/PowerSaver registers */ -static const struct x86_cpu_id eps_cpu_id[] = { - { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id); - -static int __init eps_init(void) -{ - if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10) - return -ENODEV; - if (cpufreq_register_driver(&eps_driver)) - return -EINVAL; - return 0; -} - -static void __exit eps_exit(void) -{ - cpufreq_unregister_driver(&eps_driver); -} - -/* Allow user to overclock his machine or to change frequency to higher after - * unloading module */ -module_param(freq_failsafe_off, int, 0644); -MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check"); -module_param(voltage_failsafe_off, int, 0644); -MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check"); -#if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE -module_param(ignore_acpi_limit, int, 0644); -MODULE_PARM_DESC(ignore_acpi_limit, "Don't check ACPI's processor speed limit"); -#endif -module_param(set_max_voltage, int, 0644); -MODULE_PARM_DESC(set_max_voltage, "Set maximum CPU voltage (mV) C7-M only"); - -MODULE_AUTHOR("Rafal Bilski "); -MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's."); -MODULE_LICENSE("GPL"); - -module_init(eps_init); -module_exit(eps_exit); diff --git a/linux-3.4/drivers/cpufreq.new/elanfreq.c b/linux-3.4/drivers/cpufreq.new/elanfreq.c deleted file mode 100644 index 960671fd..00000000 --- a/linux-3.4/drivers/cpufreq.new/elanfreq.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * elanfreq: cpufreq driver for the AMD ELAN family - * - * (c) Copyright 2002 Robert Schwebel - * - * Parts of this code are (c) Sven Geggus - * - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * 2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel - * - */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#define REG_CSCIR 0x22 /* Chip Setup and Control Index Register */ -#define REG_CSCDR 0x23 /* Chip Setup and Control Data Register */ - -/* Module parameter */ -static int max_freq; - -struct s_elan_multiplier { - int clock; /* frequency in kHz */ - int val40h; /* PMU Force Mode register */ - int val80h; /* CPU Clock Speed Register */ -}; - -/* - * It is important that the frequencies - * are listed in ascending order here! - */ -static struct s_elan_multiplier elan_multiplier[] = { - {1000, 0x02, 0x18}, - {2000, 0x02, 0x10}, - {4000, 0x02, 0x08}, - {8000, 0x00, 0x00}, - {16000, 0x00, 0x02}, - {33000, 0x00, 0x04}, - {66000, 0x01, 0x04}, - {99000, 0x01, 0x05} -}; - -static struct cpufreq_frequency_table elanfreq_table[] = { - {0, 1000}, - {1, 2000}, - {2, 4000}, - {3, 8000}, - {4, 16000}, - {5, 33000}, - {6, 66000}, - {7, 99000}, - {0, CPUFREQ_TABLE_END}, -}; - - -/** - * elanfreq_get_cpu_frequency: determine current cpu speed - * - * Finds out at which frequency the CPU of the Elan SOC runs - * at the moment. Frequencies from 1 to 33 MHz are generated - * the normal way, 66 and 99 MHz are called "Hyperspeed Mode" - * and have the rest of the chip running with 33 MHz. - */ - -static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) -{ - u8 clockspeed_reg; /* Clock Speed Register */ - - local_irq_disable(); - outb_p(0x80, REG_CSCIR); - clockspeed_reg = inb_p(REG_CSCDR); - local_irq_enable(); - - if ((clockspeed_reg & 0xE0) == 0xE0) - return 0; - - /* Are we in CPU clock multiplied mode (66/99 MHz)? */ - if ((clockspeed_reg & 0xE0) == 0xC0) { - if ((clockspeed_reg & 0x01) == 0) - return 66000; - else - return 99000; - } - - /* 33 MHz is not 32 MHz... */ - if ((clockspeed_reg & 0xE0) == 0xA0) - return 33000; - - return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000; -} - - -/** - * elanfreq_set_cpu_frequency: Change the CPU core frequency - * @cpu: cpu number - * @freq: frequency in kHz - * - * This function takes a frequency value and changes the CPU frequency - * according to this. Note that the frequency has to be checked by - * elanfreq_validatespeed() for correctness! - * - * There is no return value. - */ - -static void elanfreq_set_cpu_state(unsigned int state) -{ - struct cpufreq_freqs freqs; - - freqs.old = elanfreq_get_cpu_frequency(0); - freqs.new = elan_multiplier[state].clock; - freqs.cpu = 0; /* elanfreq.c is UP only driver */ - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n", - elan_multiplier[state].clock); - - - /* - * Access to the Elan's internal registers is indexed via - * 0x22: Chip Setup & Control Register Index Register (CSCI) - * 0x23: Chip Setup & Control Register Data Register (CSCD) - * - */ - - /* - * 0x40 is the Power Management Unit's Force Mode Register. - * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency) - */ - - local_irq_disable(); - outb_p(0x40, REG_CSCIR); /* Disable hyperspeed mode */ - outb_p(0x00, REG_CSCDR); - local_irq_enable(); /* wait till internal pipelines and */ - udelay(1000); /* buffers have cleaned up */ - - local_irq_disable(); - - /* now, set the CPU clock speed register (0x80) */ - outb_p(0x80, REG_CSCIR); - outb_p(elan_multiplier[state].val80h, REG_CSCDR); - - /* now, the hyperspeed bit in PMU Force Mode Register (0x40) */ - outb_p(0x40, REG_CSCIR); - outb_p(elan_multiplier[state].val40h, REG_CSCDR); - udelay(10000); - local_irq_enable(); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -}; - - -/** - * elanfreq_validatespeed: test if frequency range is valid - * @policy: the policy to validate - * - * This function checks if a given frequency range in kHz is valid - * for the hardware supported by the driver. - */ - -static int elanfreq_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); -} - -static int elanfreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], - target_freq, relation, &newstate)) - return -EINVAL; - - elanfreq_set_cpu_state(newstate); - - return 0; -} - - -/* - * Module init and exit code - */ - -static int elanfreq_cpu_init(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - unsigned int i; - int result; - - /* capability check */ - if ((c->x86_vendor != X86_VENDOR_AMD) || - (c->x86 != 4) || (c->x86_model != 10)) - return -ENODEV; - - /* max freq */ - if (!max_freq) - max_freq = elanfreq_get_cpu_frequency(0); - - /* table init */ - for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) { - if (elanfreq_table[i].frequency > max_freq) - elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID; - } - - /* cpuinfo and default policy values */ - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - policy->cur = elanfreq_get_cpu_frequency(0); - - result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table); - if (result) - return result; - - cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); - return 0; -} - - -static int elanfreq_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - - -#ifndef MODULE -/** - * elanfreq_setup - elanfreq command line parameter parsing - * - * elanfreq command line parameter. Use: - * elanfreq=66000 - * to set the maximum CPU frequency to 66 MHz. Note that in - * case you do not give this boot parameter, the maximum - * frequency will fall back to _current_ CPU frequency which - * might be lower. If you build this as a module, use the - * max_freq module parameter instead. - */ -static int __init elanfreq_setup(char *str) -{ - max_freq = simple_strtoul(str, &str, 0); - printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n"); - return 1; -} -__setup("elanfreq=", elanfreq_setup); -#endif - - -static struct freq_attr *elanfreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - - -static struct cpufreq_driver elanfreq_driver = { - .get = elanfreq_get_cpu_frequency, - .verify = elanfreq_verify, - .target = elanfreq_target, - .init = elanfreq_cpu_init, - .exit = elanfreq_cpu_exit, - .name = "elanfreq", - .owner = THIS_MODULE, - .attr = elanfreq_attr, -}; - -static const struct x86_cpu_id elan_id[] = { - { X86_VENDOR_AMD, 4, 10, }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, elan_id); - -static int __init elanfreq_init(void) -{ - if (!x86_match_cpu(elan_id)) - return -ENODEV; - return cpufreq_register_driver(&elanfreq_driver); -} - - -static void __exit elanfreq_exit(void) -{ - cpufreq_unregister_driver(&elanfreq_driver); -} - - -module_param(max_freq, int, 0444); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Robert Schwebel , " - "Sven Geggus "); -MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs"); - -module_init(elanfreq_init); -module_exit(elanfreq_exit); diff --git a/linux-3.4/drivers/cpufreq.new/exynos-cpufreq.c b/linux-3.4/drivers/cpufreq.new/exynos-cpufreq.c deleted file mode 100644 index b243a7ee..00000000 --- a/linux-3.4/drivers/cpufreq.new/exynos-cpufreq.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS - CPU frequency scaling support for EXYNOS series - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static struct exynos_dvfs_info *exynos_info; - -static struct regulator *arm_regulator; -static struct cpufreq_freqs freqs; - -static unsigned int locking_frequency; -static bool frequency_locked; -static DEFINE_MUTEX(cpufreq_lock); - -int exynos_verify_speed(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, - exynos_info->freq_table); -} - -unsigned int exynos_getspeed(unsigned int cpu) -{ - return clk_get_rate(exynos_info->cpu_clk) / 1000; -} - -static int exynos_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int index, old_index; - unsigned int arm_volt, safe_arm_volt = 0; - int ret = 0; - struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; - unsigned int *volt_table = exynos_info->volt_table; - unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz; - - mutex_lock(&cpufreq_lock); - - freqs.old = policy->cur; - - if (frequency_locked && target_freq != locking_frequency) { - ret = -EAGAIN; - goto out; - } - - if (cpufreq_frequency_table_target(policy, freq_table, - freqs.old, relation, &old_index)) { - ret = -EINVAL; - goto out; - } - - if (cpufreq_frequency_table_target(policy, freq_table, - target_freq, relation, &index)) { - ret = -EINVAL; - goto out; - } - - freqs.new = freq_table[index].frequency; - freqs.cpu = policy->cpu; - - /* - * ARM clock source will be changed APLL to MPLL temporary - * To support this level, need to control regulator for - * required voltage level - */ - if (exynos_info->need_apll_change != NULL) { - if (exynos_info->need_apll_change(old_index, index) && - (freq_table[index].frequency < mpll_freq_khz) && - (freq_table[old_index].frequency < mpll_freq_khz)) - safe_arm_volt = volt_table[exynos_info->pll_safe_idx]; - } - arm_volt = volt_table[index]; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* When the new frequency is higher than current frequency */ - if ((freqs.new > freqs.old) && !safe_arm_volt) { - /* Firstly, voltage up to increase frequency */ - regulator_set_voltage(arm_regulator, arm_volt, - arm_volt); - } - - if (safe_arm_volt) - regulator_set_voltage(arm_regulator, safe_arm_volt, - safe_arm_volt); - if (freqs.new != freqs.old) - exynos_info->set_freq(old_index, index); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - /* When the new frequency is lower than current frequency */ - if ((freqs.new < freqs.old) || - ((freqs.new > freqs.old) && safe_arm_volt)) { - /* down the voltage after frequency change */ - regulator_set_voltage(arm_regulator, arm_volt, - arm_volt); - } - -out: - mutex_unlock(&cpufreq_lock); - - return ret; -} - -#ifdef CONFIG_PM -static int exynos_cpufreq_suspend(struct cpufreq_policy *policy) -{ - return 0; -} - -static int exynos_cpufreq_resume(struct cpufreq_policy *policy) -{ - return 0; -} -#endif - -/** - * exynos_cpufreq_pm_notifier - block CPUFREQ's activities in suspend-resume - * context - * @notifier - * @pm_event - * @v - * - * While frequency_locked == true, target() ignores every frequency but - * locking_frequency. The locking_frequency value is the initial frequency, - * which is set by the bootloader. In order to eliminate possible - * inconsistency in clock values, we save and restore frequencies during - * suspend and resume and block CPUFREQ activities. Note that the standard - * suspend/resume cannot be used as they are too deep (syscore_ops) for - * regulator actions. - */ -static int exynos_cpufreq_pm_notifier(struct notifier_block *notifier, - unsigned long pm_event, void *v) -{ - struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */ - static unsigned int saved_frequency; - unsigned int temp; - - mutex_lock(&cpufreq_lock); - switch (pm_event) { - case PM_SUSPEND_PREPARE: - if (frequency_locked) - goto out; - - frequency_locked = true; - - if (locking_frequency) { - saved_frequency = exynos_getspeed(0); - - mutex_unlock(&cpufreq_lock); - exynos_target(policy, locking_frequency, - CPUFREQ_RELATION_H); - mutex_lock(&cpufreq_lock); - } - break; - - case PM_POST_SUSPEND: - if (saved_frequency) { - /* - * While frequency_locked, only locking_frequency - * is valid for target(). In order to use - * saved_frequency while keeping frequency_locked, - * we temporarly overwrite locking_frequency. - */ - temp = locking_frequency; - locking_frequency = saved_frequency; - - mutex_unlock(&cpufreq_lock); - exynos_target(policy, locking_frequency, - CPUFREQ_RELATION_H); - mutex_lock(&cpufreq_lock); - - locking_frequency = temp; - } - frequency_locked = false; - break; - } -out: - mutex_unlock(&cpufreq_lock); - - return NOTIFY_OK; -} - -static struct notifier_block exynos_cpufreq_nb = { - .notifier_call = exynos_cpufreq_pm_notifier, -}; - -static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - policy->cur = policy->min = policy->max = exynos_getspeed(policy->cpu); - - cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu); - - locking_frequency = exynos_getspeed(0); - - /* set the transition latency value */ - policy->cpuinfo.transition_latency = 100000; - - /* - * EXYNOS4 multi-core processors has 2 cores - * that the frequency cannot be set independently. - * Each cpu is bound to the same speed. - * So the affected cpu is all of the cpus. - */ - if (num_online_cpus() == 1) { - cpumask_copy(policy->related_cpus, cpu_possible_mask); - cpumask_copy(policy->cpus, cpu_online_mask); - } else { - cpumask_setall(policy->cpus); - } - - return cpufreq_frequency_table_cpuinfo(policy, exynos_info->freq_table); -} - -static struct cpufreq_driver exynos_driver = { - .flags = CPUFREQ_STICKY, - .verify = exynos_verify_speed, - .target = exynos_target, - .get = exynos_getspeed, - .init = exynos_cpufreq_cpu_init, - .name = "exynos_cpufreq", -#ifdef CONFIG_PM - .suspend = exynos_cpufreq_suspend, - .resume = exynos_cpufreq_resume, -#endif -}; - -static int __init exynos_cpufreq_init(void) -{ - int ret = -EINVAL; - - exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL); - if (!exynos_info) - return -ENOMEM; - - if (soc_is_exynos4210()) - ret = exynos4210_cpufreq_init(exynos_info); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - ret = exynos4x12_cpufreq_init(exynos_info); - else if (soc_is_exynos5250()) - ret = exynos5250_cpufreq_init(exynos_info); - else - pr_err("%s: CPU type not found\n", __func__); - - if (ret) - goto err_vdd_arm; - - if (exynos_info->set_freq == NULL) { - pr_err("%s: No set_freq function (ERR)\n", __func__); - goto err_vdd_arm; - } - - arm_regulator = regulator_get(NULL, "vdd_arm"); - if (IS_ERR(arm_regulator)) { - pr_err("%s: failed to get resource vdd_arm\n", __func__); - goto err_vdd_arm; - } - - register_pm_notifier(&exynos_cpufreq_nb); - - if (cpufreq_register_driver(&exynos_driver)) { - pr_err("%s: failed to register cpufreq driver\n", __func__); - goto err_cpufreq; - } - - return 0; -err_cpufreq: - unregister_pm_notifier(&exynos_cpufreq_nb); - - if (!IS_ERR(arm_regulator)) - regulator_put(arm_regulator); -err_vdd_arm: - kfree(exynos_info); - pr_debug("%s: failed initialization\n", __func__); - return -EINVAL; -} -late_initcall(exynos_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/exynos4210-cpufreq.c b/linux-3.4/drivers/cpufreq.new/exynos4210-cpufreq.c deleted file mode 100644 index fb148fa2..00000000 --- a/linux-3.4/drivers/cpufreq.new/exynos4210-cpufreq.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4210 - CPU frequency scaling support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define CPUFREQ_LEVEL_END L5 - -static int max_support_idx = L0; -static int min_support_idx = (CPUFREQ_LEVEL_END - 1); - -static struct clk *cpu_clk; -static struct clk *moutcore; -static struct clk *mout_mpll; -static struct clk *mout_apll; - -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; -}; - -static unsigned int exynos4210_volt_table[CPUFREQ_LEVEL_END] = { - 1250000, 1150000, 1050000, 975000, 950000, -}; - - -static struct cpufreq_clkdiv exynos4210_clkdiv_table[CPUFREQ_LEVEL_END]; - -static struct cpufreq_frequency_table exynos4210_freq_table[] = { - {L0, 1200*1000}, - {L1, 1000*1000}, - {L2, 800*1000}, - {L3, 500*1000}, - {L4, 200*1000}, - {0, CPUFREQ_TABLE_END}, -}; - -static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = { - /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL } - */ - - /* ARM L0: 1200MHz */ - { 0, 3, 7, 3, 4, 1, 7 }, - - /* ARM L1: 1000MHz */ - { 0, 3, 7, 3, 4, 1, 7 }, - - /* ARM L2: 800MHz */ - { 0, 3, 7, 3, 3, 1, 7 }, - - /* ARM L3: 500MHz */ - { 0, 3, 7, 3, 3, 1, 7 }, - - /* ARM L4: 200MHz */ - { 0, 1, 3, 1, 3, 1, 0 }, -}; - -static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = { - /* - * Clock divider value for following - * { DIVCOPY, DIVHPM } - */ - - /* ARM L0: 1200MHz */ - { 5, 0 }, - - /* ARM L1: 1000MHz */ - { 4, 0 }, - - /* ARM L2: 800MHz */ - { 3, 0 }, - - /* ARM L3: 500MHz */ - { 3, 0 }, - - /* ARM L4: 200MHz */ - { 3, 0 }, -}; - -static unsigned int exynos4210_apll_pms_table[CPUFREQ_LEVEL_END] = { - /* APLL FOUT L0: 1200MHz */ - ((150 << 16) | (3 << 8) | 1), - - /* APLL FOUT L1: 1000MHz */ - ((250 << 16) | (6 << 8) | 1), - - /* APLL FOUT L2: 800MHz */ - ((200 << 16) | (6 << 8) | 1), - - /* APLL FOUT L3: 500MHz */ - ((250 << 16) | (6 << 8) | 2), - - /* APLL FOUT L4: 200MHz */ - ((200 << 16) | (6 << 8) | 3), -}; - -static void exynos4210_set_clkdiv(unsigned int div_index) -{ - unsigned int tmp; - - /* Change Divider - CPU0 */ - - tmp = exynos4210_clkdiv_table[div_index].clkdiv; - - __raw_writel(tmp, EXYNOS4_CLKDIV_CPU); - - do { - tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU); - } while (tmp & 0x1111111); - - /* Change Divider - CPU1 */ - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1); - - tmp &= ~((0x7 << 4) | 0x7); - - tmp |= ((clkdiv_cpu1[div_index][0] << 4) | - (clkdiv_cpu1[div_index][1] << 0)); - - __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1); - - do { - tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1); - } while (tmp & 0x11); -} - -static void exynos4210_set_apll(unsigned int index) -{ - unsigned int tmp; - - /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ - clk_set_parent(moutcore, mout_mpll); - - do { - tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU) - >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT); - tmp &= 0x7; - } while (tmp != 0x2); - - /* 2. Set APLL Lock time */ - __raw_writel(EXYNOS4_APLL_LOCKTIME, EXYNOS4_APLL_LOCK); - - /* 3. Change PLL PMS values */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos4210_apll_pms_table[index]; - __raw_writel(tmp, EXYNOS4_APLL_CON0); - - /* 4. wait_lock_time */ - do { - tmp = __raw_readl(EXYNOS4_APLL_CON0); - } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT))); - - /* 5. MUX_CORE_SEL = APLL */ - clk_set_parent(moutcore, mout_apll); - - do { - tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU); - tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK; - } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); -} - -bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index) -{ - unsigned int old_pm = (exynos4210_apll_pms_table[old_index] >> 8); - unsigned int new_pm = (exynos4210_apll_pms_table[new_index] >> 8); - - return (old_pm == new_pm) ? 0 : 1; -} - -static void exynos4210_set_frequency(unsigned int old_index, - unsigned int new_index) -{ - unsigned int tmp; - - if (old_index > new_index) { - if (!exynos4210_pms_change(old_index, new_index)) { - /* 1. Change the system clock divider values */ - exynos4210_set_clkdiv(new_index); - - /* 2. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos4210_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS4_APLL_CON0); - } else { - /* Clock Configuration Procedure */ - /* 1. Change the system clock divider values */ - exynos4210_set_clkdiv(new_index); - /* 2. Change the apll m,p,s value */ - exynos4210_set_apll(new_index); - } - } else if (old_index < new_index) { - if (!exynos4210_pms_change(old_index, new_index)) { - /* 1. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos4210_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS4_APLL_CON0); - - /* 2. Change the system clock divider values */ - exynos4210_set_clkdiv(new_index); - } else { - /* Clock Configuration Procedure */ - /* 1. Change the apll m,p,s value */ - exynos4210_set_apll(new_index); - /* 2. Change the system clock divider values */ - exynos4210_set_clkdiv(new_index); - } - } -} - -int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) -{ - int i; - unsigned int tmp; - unsigned long rate; - - cpu_clk = clk_get(NULL, "armclk"); - if (IS_ERR(cpu_clk)) - return PTR_ERR(cpu_clk); - - moutcore = clk_get(NULL, "moutcore"); - if (IS_ERR(moutcore)) - goto err_moutcore; - - mout_mpll = clk_get(NULL, "mout_mpll"); - if (IS_ERR(mout_mpll)) - goto err_mout_mpll; - - rate = clk_get_rate(mout_mpll) / 1000; - - mout_apll = clk_get(NULL, "mout_apll"); - if (IS_ERR(mout_apll)) - goto err_mout_apll; - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU); - - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK | - EXYNOS4_CLKDIV_CPU0_COREM0_MASK | - EXYNOS4_CLKDIV_CPU0_COREM1_MASK | - EXYNOS4_CLKDIV_CPU0_PERIPH_MASK | - EXYNOS4_CLKDIV_CPU0_ATB_MASK | - EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK | - EXYNOS4_CLKDIV_CPU0_APLL_MASK); - - tmp |= ((clkdiv_cpu0[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)); - - exynos4210_clkdiv_table[i].clkdiv = tmp; - } - - info->mpll_freq_khz = rate; - info->pm_lock_idx = L2; - info->pll_safe_idx = L2; - info->max_support_idx = max_support_idx; - info->min_support_idx = min_support_idx; - info->cpu_clk = cpu_clk; - info->volt_table = exynos4210_volt_table; - info->freq_table = exynos4210_freq_table; - info->set_freq = exynos4210_set_frequency; - info->need_apll_change = exynos4210_pms_change; - - return 0; - -err_mout_apll: - if (!IS_ERR(mout_mpll)) - clk_put(mout_mpll); -err_mout_mpll: - if (!IS_ERR(moutcore)) - clk_put(moutcore); -err_moutcore: - if (!IS_ERR(cpu_clk)) - clk_put(cpu_clk); - - pr_debug("%s: failed initialization\n", __func__); - return -EINVAL; -} -EXPORT_SYMBOL(exynos4210_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/exynos4x12-cpufreq.c b/linux-3.4/drivers/cpufreq.new/exynos4x12-cpufreq.c deleted file mode 100644 index 8c5a7afa..00000000 --- a/linux-3.4/drivers/cpufreq.new/exynos4x12-cpufreq.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4X12 - CPU frequency scaling support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define CPUFREQ_LEVEL_END (L13 + 1) - -static int max_support_idx; -static int min_support_idx = (CPUFREQ_LEVEL_END - 1); - -static struct clk *cpu_clk; -static struct clk *moutcore; -static struct clk *mout_mpll; -static struct clk *mout_apll; - -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; - unsigned int clkdiv1; -}; - -static unsigned int exynos4x12_volt_table[CPUFREQ_LEVEL_END]; - -static struct cpufreq_frequency_table exynos4x12_freq_table[] = { - {L0, 1500 * 1000}, - {L1, 1400 * 1000}, - {L2, 1300 * 1000}, - {L3, 1200 * 1000}, - {L4, 1100 * 1000}, - {L5, 1000 * 1000}, - {L6, 900 * 1000}, - {L7, 800 * 1000}, - {L8, 700 * 1000}, - {L9, 600 * 1000}, - {L10, 500 * 1000}, - {L11, 400 * 1000}, - {L12, 300 * 1000}, - {L13, 200 * 1000}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct cpufreq_clkdiv exynos4x12_clkdiv_table[CPUFREQ_LEVEL_END]; - -static unsigned int clkdiv_cpu0_4212[CPUFREQ_LEVEL_END][8] = { - /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 } - */ - /* ARM L0: 1500 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L1: 1400 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L2: 1300 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L3: 1200 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L4: 1100 MHz */ - { 0, 3, 6, 0, 4, 1, 2, 0 }, - - /* ARM L5: 1000 MHz */ - { 0, 2, 5, 0, 4, 1, 1, 0 }, - - /* ARM L6: 900 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L7: 800 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L8: 700 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L9: 600 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L10: 500 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L11: 400 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L12: 300 MHz */ - { 0, 2, 4, 0, 2, 1, 1, 0 }, - - /* ARM L13: 200 MHz */ - { 0, 1, 3, 0, 1, 1, 1, 0 }, -}; - -static unsigned int clkdiv_cpu0_4412[CPUFREQ_LEVEL_END][8] = { - /* - * Clock divider value for following - * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, - * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 } - */ - /* ARM L0: 1500 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L1: 1400 MHz */ - { 0, 3, 7, 0, 6, 1, 2, 0 }, - - /* ARM L2: 1300 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L3: 1200 MHz */ - { 0, 3, 7, 0, 5, 1, 2, 0 }, - - /* ARM L4: 1100 MHz */ - { 0, 3, 6, 0, 4, 1, 2, 0 }, - - /* ARM L5: 1000 MHz */ - { 0, 2, 5, 0, 4, 1, 1, 0 }, - - /* ARM L6: 900 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L7: 800 MHz */ - { 0, 2, 5, 0, 3, 1, 1, 0 }, - - /* ARM L8: 700 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L9: 600 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L10: 500 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L11: 400 MHz */ - { 0, 2, 4, 0, 3, 1, 1, 0 }, - - /* ARM L12: 300 MHz */ - { 0, 2, 4, 0, 2, 1, 1, 0 }, - - /* ARM L13: 200 MHz */ - { 0, 1, 3, 0, 1, 1, 1, 0 }, -}; - -static unsigned int clkdiv_cpu1_4212[CPUFREQ_LEVEL_END][2] = { - /* Clock divider value for following - * { DIVCOPY, DIVHPM } - */ - /* ARM L0: 1500 MHz */ - { 6, 0 }, - - /* ARM L1: 1400 MHz */ - { 6, 0 }, - - /* ARM L2: 1300 MHz */ - { 5, 0 }, - - /* ARM L3: 1200 MHz */ - { 5, 0 }, - - /* ARM L4: 1100 MHz */ - { 4, 0 }, - - /* ARM L5: 1000 MHz */ - { 4, 0 }, - - /* ARM L6: 900 MHz */ - { 3, 0 }, - - /* ARM L7: 800 MHz */ - { 3, 0 }, - - /* ARM L8: 700 MHz */ - { 3, 0 }, - - /* ARM L9: 600 MHz */ - { 3, 0 }, - - /* ARM L10: 500 MHz */ - { 3, 0 }, - - /* ARM L11: 400 MHz */ - { 3, 0 }, - - /* ARM L12: 300 MHz */ - { 3, 0 }, - - /* ARM L13: 200 MHz */ - { 3, 0 }, -}; - -static unsigned int clkdiv_cpu1_4412[CPUFREQ_LEVEL_END][3] = { - /* Clock divider value for following - * { DIVCOPY, DIVHPM, DIVCORES } - */ - /* ARM L0: 1500 MHz */ - { 6, 0, 7 }, - - /* ARM L1: 1400 MHz */ - { 6, 0, 6 }, - - /* ARM L2: 1300 MHz */ - { 5, 0, 6 }, - - /* ARM L3: 1200 MHz */ - { 5, 0, 5 }, - - /* ARM L4: 1100 MHz */ - { 4, 0, 5 }, - - /* ARM L5: 1000 MHz */ - { 4, 0, 4 }, - - /* ARM L6: 900 MHz */ - { 3, 0, 4 }, - - /* ARM L7: 800 MHz */ - { 3, 0, 3 }, - - /* ARM L8: 700 MHz */ - { 3, 0, 3 }, - - /* ARM L9: 600 MHz */ - { 3, 0, 2 }, - - /* ARM L10: 500 MHz */ - { 3, 0, 2 }, - - /* ARM L11: 400 MHz */ - { 3, 0, 1 }, - - /* ARM L12: 300 MHz */ - { 3, 0, 1 }, - - /* ARM L13: 200 MHz */ - { 3, 0, 0 }, -}; - -static unsigned int exynos4x12_apll_pms_table[CPUFREQ_LEVEL_END] = { - /* APLL FOUT L0: 1500 MHz */ - ((250 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L1: 1400 MHz */ - ((175 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L2: 1300 MHz */ - ((325 << 16) | (6 << 8) | (0x0)), - - /* APLL FOUT L3: 1200 MHz */ - ((200 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L4: 1100 MHz */ - ((275 << 16) | (6 << 8) | (0x0)), - - /* APLL FOUT L5: 1000 MHz */ - ((125 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L6: 900 MHz */ - ((150 << 16) | (4 << 8) | (0x0)), - - /* APLL FOUT L7: 800 MHz */ - ((100 << 16) | (3 << 8) | (0x0)), - - /* APLL FOUT L8: 700 MHz */ - ((175 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L9: 600 MHz */ - ((200 << 16) | (4 << 8) | (0x1)), - - /* APLL FOUT L10: 500 MHz */ - ((125 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L11 400 MHz */ - ((100 << 16) | (3 << 8) | (0x1)), - - /* APLL FOUT L12: 300 MHz */ - ((200 << 16) | (4 << 8) | (0x2)), - - /* APLL FOUT L13: 200 MHz */ - ((100 << 16) | (3 << 8) | (0x2)), -}; - -static const unsigned int asv_voltage_4x12[CPUFREQ_LEVEL_END] = { - 1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500, - 1000000, 987500, 975000, 950000, 925000, 900000, 900000 -}; - -static void exynos4x12_set_clkdiv(unsigned int div_index) -{ - unsigned int tmp; - unsigned int stat_cpu1; - - /* Change Divider - CPU0 */ - - tmp = exynos4x12_clkdiv_table[div_index].clkdiv; - - __raw_writel(tmp, EXYNOS4_CLKDIV_CPU); - - while (__raw_readl(EXYNOS4_CLKDIV_STATCPU) & 0x11111111) - cpu_relax(); - - /* Change Divider - CPU1 */ - tmp = exynos4x12_clkdiv_table[div_index].clkdiv1; - - __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1); - if (soc_is_exynos4212()) - stat_cpu1 = 0x11; - else - stat_cpu1 = 0x111; - - while (__raw_readl(EXYNOS4_CLKDIV_STATCPU1) & stat_cpu1) - cpu_relax(); -} - -static void exynos4x12_set_apll(unsigned int index) -{ - unsigned int tmp, pdiv; - - /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ - clk_set_parent(moutcore, mout_mpll); - - do { - cpu_relax(); - tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU) - >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT); - tmp &= 0x7; - } while (tmp != 0x2); - - /* 2. Set APLL Lock time */ - pdiv = ((exynos4x12_apll_pms_table[index] >> 8) & 0x3f); - - __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK); - - /* 3. Change PLL PMS values */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos4x12_apll_pms_table[index]; - __raw_writel(tmp, EXYNOS4_APLL_CON0); - - /* 4. wait_lock_time */ - do { - cpu_relax(); - tmp = __raw_readl(EXYNOS4_APLL_CON0); - } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT))); - - /* 5. MUX_CORE_SEL = APLL */ - clk_set_parent(moutcore, mout_apll); - - do { - cpu_relax(); - tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU); - tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK; - } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); -} - -bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index) -{ - unsigned int old_pm = exynos4x12_apll_pms_table[old_index] >> 8; - unsigned int new_pm = exynos4x12_apll_pms_table[new_index] >> 8; - - return (old_pm == new_pm) ? 0 : 1; -} - -static void exynos4x12_set_frequency(unsigned int old_index, - unsigned int new_index) -{ - unsigned int tmp; - - if (old_index > new_index) { - if (!exynos4x12_pms_change(old_index, new_index)) { - /* 1. Change the system clock divider values */ - exynos4x12_set_clkdiv(new_index); - /* 2. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS4_APLL_CON0); - - } else { - /* Clock Configuration Procedure */ - /* 1. Change the system clock divider values */ - exynos4x12_set_clkdiv(new_index); - /* 2. Change the apll m,p,s value */ - exynos4x12_set_apll(new_index); - } - } else if (old_index < new_index) { - if (!exynos4x12_pms_change(old_index, new_index)) { - /* 1. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS4_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS4_APLL_CON0); - /* 2. Change the system clock divider values */ - exynos4x12_set_clkdiv(new_index); - } else { - /* Clock Configuration Procedure */ - /* 1. Change the apll m,p,s value */ - exynos4x12_set_apll(new_index); - /* 2. Change the system clock divider values */ - exynos4x12_set_clkdiv(new_index); - } - } -} - -static void __init set_volt_table(void) -{ - unsigned int i; - - max_support_idx = L1; - - /* Not supported */ - exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID; - - for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) - exynos4x12_volt_table[i] = asv_voltage_4x12[i]; -} - -int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) -{ - int i; - unsigned int tmp; - unsigned long rate; - - set_volt_table(); - - cpu_clk = clk_get(NULL, "armclk"); - if (IS_ERR(cpu_clk)) - return PTR_ERR(cpu_clk); - - moutcore = clk_get(NULL, "moutcore"); - if (IS_ERR(moutcore)) - goto err_moutcore; - - mout_mpll = clk_get(NULL, "mout_mpll"); - if (IS_ERR(mout_mpll)) - goto err_mout_mpll; - - rate = clk_get_rate(mout_mpll) / 1000; - - mout_apll = clk_get(NULL, "mout_apll"); - if (IS_ERR(mout_apll)) - goto err_mout_apll; - - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - - exynos4x12_clkdiv_table[i].index = i; - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU); - - tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK | - EXYNOS4_CLKDIV_CPU0_COREM0_MASK | - EXYNOS4_CLKDIV_CPU0_COREM1_MASK | - EXYNOS4_CLKDIV_CPU0_PERIPH_MASK | - EXYNOS4_CLKDIV_CPU0_ATB_MASK | - EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK | - EXYNOS4_CLKDIV_CPU0_APLL_MASK); - - if (soc_is_exynos4212()) { - tmp |= ((clkdiv_cpu0_4212[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0_4212[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0_4212[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0_4212[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0_4212[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0_4212[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0_4212[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)); - } else { - tmp &= ~EXYNOS4_CLKDIV_CPU0_CORE2_MASK; - - tmp |= ((clkdiv_cpu0_4412[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) | - (clkdiv_cpu0_4412[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) | - (clkdiv_cpu0_4412[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) | - (clkdiv_cpu0_4412[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) | - (clkdiv_cpu0_4412[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) | - (clkdiv_cpu0_4412[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) | - (clkdiv_cpu0_4412[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) | - (clkdiv_cpu0_4412[i][7] << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT)); - } - - exynos4x12_clkdiv_table[i].clkdiv = tmp; - - tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1); - - if (soc_is_exynos4212()) { - tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK | - EXYNOS4_CLKDIV_CPU1_HPM_MASK); - tmp |= ((clkdiv_cpu1_4212[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) | - (clkdiv_cpu1_4212[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT)); - } else { - tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK | - EXYNOS4_CLKDIV_CPU1_HPM_MASK | - EXYNOS4_CLKDIV_CPU1_CORES_MASK); - tmp |= ((clkdiv_cpu1_4412[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) | - (clkdiv_cpu1_4412[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) | - (clkdiv_cpu1_4412[i][2] << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT)); - } - exynos4x12_clkdiv_table[i].clkdiv1 = tmp; - } - - info->mpll_freq_khz = rate; - info->pm_lock_idx = L5; - info->pll_safe_idx = L7; - info->max_support_idx = max_support_idx; - info->min_support_idx = min_support_idx; - info->cpu_clk = cpu_clk; - info->volt_table = exynos4x12_volt_table; - info->freq_table = exynos4x12_freq_table; - info->set_freq = exynos4x12_set_frequency; - info->need_apll_change = exynos4x12_pms_change; - - return 0; - -err_mout_apll: - clk_put(mout_mpll); -err_mout_mpll: - clk_put(moutcore); -err_moutcore: - clk_put(cpu_clk); - - pr_debug("%s: failed initialization\n", __func__); - return -EINVAL; -} -EXPORT_SYMBOL(exynos4x12_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/exynos5250-cpufreq.c b/linux-3.4/drivers/cpufreq.new/exynos5250-cpufreq.c deleted file mode 100644 index a8833164..00000000 --- a/linux-3.4/drivers/cpufreq.new/exynos5250-cpufreq.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2010-20122Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS5250 - CPU frequency scaling support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define CPUFREQ_LEVEL_END (L15 + 1) - -static int max_support_idx; -static int min_support_idx = (CPUFREQ_LEVEL_END - 1); -static struct clk *cpu_clk; -static struct clk *moutcore; -static struct clk *mout_mpll; -static struct clk *mout_apll; - -struct cpufreq_clkdiv { - unsigned int index; - unsigned int clkdiv; - unsigned int clkdiv1; -}; - -static unsigned int exynos5250_volt_table[CPUFREQ_LEVEL_END]; - -static struct cpufreq_frequency_table exynos5250_freq_table[] = { - {L0, 1700 * 1000}, - {L1, 1600 * 1000}, - {L2, 1500 * 1000}, - {L3, 1400 * 1000}, - {L4, 1300 * 1000}, - {L5, 1200 * 1000}, - {L6, 1100 * 1000}, - {L7, 1000 * 1000}, - {L8, 900 * 1000}, - {L9, 800 * 1000}, - {L10, 700 * 1000}, - {L11, 600 * 1000}, - {L12, 500 * 1000}, - {L13, 400 * 1000}, - {L14, 300 * 1000}, - {L15, 200 * 1000}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct cpufreq_clkdiv exynos5250_clkdiv_table[CPUFREQ_LEVEL_END]; - -static unsigned int clkdiv_cpu0_5250[CPUFREQ_LEVEL_END][8] = { - /* - * Clock divider value for following - * { ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2 } - */ - { 0, 3, 7, 7, 6, 1, 3, 0 }, /* 1700 MHz - N/A */ - { 0, 3, 7, 7, 6, 1, 3, 0 }, /* 1600 MHz - N/A */ - { 0, 3, 7, 7, 5, 1, 3, 0 }, /* 1500 MHz - N/A */ - { 0, 3, 7, 7, 6, 1, 3, 0 }, /* 1400 MHz */ - { 0, 3, 7, 7, 6, 1, 3, 0 }, /* 1300 MHz */ - { 0, 3, 7, 7, 5, 1, 3, 0 }, /* 1200 MHz */ - { 0, 2, 7, 7, 5, 1, 2, 0 }, /* 1100 MHz */ - { 0, 2, 7, 7, 4, 1, 2, 0 }, /* 1000 MHz */ - { 0, 2, 7, 7, 4, 1, 2, 0 }, /* 900 MHz */ - { 0, 2, 7, 7, 3, 1, 1, 0 }, /* 800 MHz */ - { 0, 1, 7, 7, 3, 1, 1, 0 }, /* 700 MHz */ - { 0, 1, 7, 7, 2, 1, 1, 0 }, /* 600 MHz */ - { 0, 1, 7, 7, 2, 1, 1, 0 }, /* 500 MHz */ - { 0, 1, 7, 7, 1, 1, 1, 0 }, /* 400 MHz */ - { 0, 1, 7, 7, 1, 1, 1, 0 }, /* 300 MHz */ - { 0, 1, 7, 7, 1, 1, 1, 0 }, /* 200 MHz */ -}; - -static unsigned int clkdiv_cpu1_5250[CPUFREQ_LEVEL_END][2] = { - /* Clock divider value for following - * { COPY, HPM } - */ - { 0, 2 }, /* 1700 MHz - N/A */ - { 0, 2 }, /* 1600 MHz - N/A */ - { 0, 2 }, /* 1500 MHz - N/A */ - { 0, 2 }, /* 1400 MHz */ - { 0, 2 }, /* 1300 MHz */ - { 0, 2 }, /* 1200 MHz */ - { 0, 2 }, /* 1100 MHz */ - { 0, 2 }, /* 1000 MHz */ - { 0, 2 }, /* 900 MHz */ - { 0, 2 }, /* 800 MHz */ - { 0, 2 }, /* 700 MHz */ - { 0, 2 }, /* 600 MHz */ - { 0, 2 }, /* 500 MHz */ - { 0, 2 }, /* 400 MHz */ - { 0, 2 }, /* 300 MHz */ - { 0, 2 }, /* 200 MHz */ -}; - -static unsigned int exynos5_apll_pms_table[CPUFREQ_LEVEL_END] = { - (0), /* 1700 MHz - N/A */ - (0), /* 1600 MHz - N/A */ - (0), /* 1500 MHz - N/A */ - (0), /* 1400 MHz */ - ((325 << 16) | (6 << 8) | 0), /* 1300 MHz */ - ((200 << 16) | (4 << 8) | 0), /* 1200 MHz */ - ((275 << 16) | (6 << 8) | 0), /* 1100 MHz */ - ((125 << 16) | (3 << 8) | 0), /* 1000 MHz */ - ((150 << 16) | (4 << 8) | 0), /* 900 MHz */ - ((100 << 16) | (3 << 8) | 0), /* 800 MHz */ - ((175 << 16) | (3 << 8) | 1), /* 700 MHz */ - ((200 << 16) | (4 << 8) | 1), /* 600 MHz */ - ((125 << 16) | (3 << 8) | 1), /* 500 MHz */ - ((100 << 16) | (3 << 8) | 1), /* 400 MHz */ - ((200 << 16) | (4 << 8) | 2), /* 300 MHz */ - ((100 << 16) | (3 << 8) | 2), /* 200 MHz */ -}; - -/* ASV group voltage table */ -static const unsigned int asv_voltage_5250[CPUFREQ_LEVEL_END] = { - 0, 0, 0, 0, 0, 0, 0, /* 1700 MHz ~ 1100 MHz Not supported */ - 1175000, 1125000, 1075000, 1050000, 1000000, - 950000, 925000, 925000, 900000 -}; - -static void set_clkdiv(unsigned int div_index) -{ - unsigned int tmp; - - /* Change Divider - CPU0 */ - - tmp = exynos5250_clkdiv_table[div_index].clkdiv; - - __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0); - - while (__raw_readl(EXYNOS5_CLKDIV_STATCPU0) & 0x11111111) - cpu_relax(); - - /* Change Divider - CPU1 */ - tmp = exynos5250_clkdiv_table[div_index].clkdiv1; - - __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1); - - while (__raw_readl(EXYNOS5_CLKDIV_STATCPU1) & 0x11) - cpu_relax(); -} - -static void set_apll(unsigned int new_index, - unsigned int old_index) -{ - unsigned int tmp, pdiv; - - /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ - clk_set_parent(moutcore, mout_mpll); - - do { - cpu_relax(); - tmp = (__raw_readl(EXYNOS5_CLKMUX_STATCPU) >> 16); - tmp &= 0x7; - } while (tmp != 0x2); - - /* 2. Set APLL Lock time */ - pdiv = ((exynos5_apll_pms_table[new_index] >> 8) & 0x3f); - - __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK); - - /* 3. Change PLL PMS values */ - tmp = __raw_readl(EXYNOS5_APLL_CON0); - tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); - tmp |= exynos5_apll_pms_table[new_index]; - __raw_writel(tmp, EXYNOS5_APLL_CON0); - - /* 4. wait_lock_time */ - do { - cpu_relax(); - tmp = __raw_readl(EXYNOS5_APLL_CON0); - } while (!(tmp & (0x1 << 29))); - - /* 5. MUX_CORE_SEL = APLL */ - clk_set_parent(moutcore, mout_apll); - - do { - cpu_relax(); - tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); - tmp &= (0x7 << 16); - } while (tmp != (0x1 << 16)); - -} - -bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index) -{ - unsigned int old_pm = (exynos5_apll_pms_table[old_index] >> 8); - unsigned int new_pm = (exynos5_apll_pms_table[new_index] >> 8); - - return (old_pm == new_pm) ? 0 : 1; -} - -static void exynos5250_set_frequency(unsigned int old_index, - unsigned int new_index) -{ - unsigned int tmp; - - if (old_index > new_index) { - if (!exynos5250_pms_change(old_index, new_index)) { - /* 1. Change the system clock divider values */ - set_clkdiv(new_index); - /* 2. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS5_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos5_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS5_APLL_CON0); - - } else { - /* Clock Configuration Procedure */ - /* 1. Change the system clock divider values */ - set_clkdiv(new_index); - /* 2. Change the apll m,p,s value */ - set_apll(new_index, old_index); - } - } else if (old_index < new_index) { - if (!exynos5250_pms_change(old_index, new_index)) { - /* 1. Change just s value in apll m,p,s value */ - tmp = __raw_readl(EXYNOS5_APLL_CON0); - tmp &= ~(0x7 << 0); - tmp |= (exynos5_apll_pms_table[new_index] & 0x7); - __raw_writel(tmp, EXYNOS5_APLL_CON0); - /* 2. Change the system clock divider values */ - set_clkdiv(new_index); - } else { - /* Clock Configuration Procedure */ - /* 1. Change the apll m,p,s value */ - set_apll(new_index, old_index); - /* 2. Change the system clock divider values */ - set_clkdiv(new_index); - } - } -} - -static void __init set_volt_table(void) -{ - unsigned int i; - - exynos5250_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L1].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L2].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L3].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L4].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L5].frequency = CPUFREQ_ENTRY_INVALID; - exynos5250_freq_table[L6].frequency = CPUFREQ_ENTRY_INVALID; - - max_support_idx = L7; - - for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) - exynos5250_volt_table[i] = asv_voltage_5250[i]; -} - -int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) -{ - int i; - unsigned int tmp; - unsigned long rate; - - set_volt_table(); - - cpu_clk = clk_get(NULL, "armclk"); - if (IS_ERR(cpu_clk)) - return PTR_ERR(cpu_clk); - - moutcore = clk_get(NULL, "mout_cpu"); - if (IS_ERR(moutcore)) - goto err_moutcore; - - mout_mpll = clk_get(NULL, "mout_mpll"); - if (IS_ERR(mout_mpll)) - goto err_mout_mpll; - - rate = clk_get_rate(mout_mpll) / 1000; - - mout_apll = clk_get(NULL, "mout_apll"); - if (IS_ERR(mout_apll)) - goto err_mout_apll; - - for (i = L0; i < CPUFREQ_LEVEL_END; i++) { - - exynos5250_clkdiv_table[i].index = i; - - tmp = __raw_readl(EXYNOS5_CLKDIV_CPU0); - - tmp &= ~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | - (0x7 << 12) | (0x7 << 16) | (0x7 << 20) | - (0x7 << 24) | (0x7 << 28)); - - tmp |= ((clkdiv_cpu0_5250[i][0] << 0) | - (clkdiv_cpu0_5250[i][1] << 4) | - (clkdiv_cpu0_5250[i][2] << 8) | - (clkdiv_cpu0_5250[i][3] << 12) | - (clkdiv_cpu0_5250[i][4] << 16) | - (clkdiv_cpu0_5250[i][5] << 20) | - (clkdiv_cpu0_5250[i][6] << 24) | - (clkdiv_cpu0_5250[i][7] << 28)); - - exynos5250_clkdiv_table[i].clkdiv = tmp; - - tmp = __raw_readl(EXYNOS5_CLKDIV_CPU1); - - tmp &= ~((0x7 << 0) | (0x7 << 4)); - - tmp |= ((clkdiv_cpu1_5250[i][0] << 0) | - (clkdiv_cpu1_5250[i][1] << 4)); - - exynos5250_clkdiv_table[i].clkdiv1 = tmp; - } - - info->mpll_freq_khz = rate; - /* 1000Mhz */ - info->pm_lock_idx = L7; - /* 800Mhz */ - info->pll_safe_idx = L9; - info->max_support_idx = max_support_idx; - info->min_support_idx = min_support_idx; - info->cpu_clk = cpu_clk; - info->volt_table = exynos5250_volt_table; - info->freq_table = exynos5250_freq_table; - info->set_freq = exynos5250_set_frequency; - info->need_apll_change = exynos5250_pms_change; - - return 0; - -err_mout_apll: - clk_put(mout_mpll); -err_mout_mpll: - clk_put(moutcore); -err_moutcore: - clk_put(cpu_clk); - - pr_err("%s: failed initialization\n", __func__); - return -EINVAL; -} -EXPORT_SYMBOL(exynos5250_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/freq_table.c b/linux-3.4/drivers/cpufreq.new/freq_table.c deleted file mode 100755 index d7a79662..00000000 --- a/linux-3.4/drivers/cpufreq.new/freq_table.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * linux/drivers/cpufreq/freq_table.c - * - * Copyright (C) 2002 - 2003 Dominik Brodowski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include - -/********************************************************************* - * FREQUENCY TABLE HELPERS * - *********************************************************************/ - -int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table) -{ - unsigned int min_freq = ~0; - unsigned int max_freq = 0; - unsigned int i; - - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) { - pr_debug("table entry %u is invalid, skipping\n", i); - - continue; - } - pr_debug("table entry %u: %u kHz, %u index\n", - i, freq, table[i].index); - if (freq < min_freq) - min_freq = freq; - if (freq > max_freq) - max_freq = freq; - } - - policy->min = policy->cpuinfo.min_freq = min_freq; - policy->max = policy->cpuinfo.max_freq = max_freq; - - if (policy->min == ~0) - return -EINVAL; - else - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); - - -int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table) -{ - unsigned int next_larger = ~0; - unsigned int i; - unsigned int count = 0; - - pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", - policy->min, policy->max, policy->cpu); - - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - if ((freq >= policy->min) && (freq <= policy->max)) - count++; - else if ((next_larger > freq) && (freq > policy->max)) - next_larger = freq; - } - - if (!count) - policy->max = next_larger; - - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - - pr_debug("verification lead to (%u - %u kHz) for cpu %u\n", - policy->min, policy->max, policy->cpu); - - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); - - -int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table, - unsigned int target_freq, - unsigned int relation, - unsigned int *index) -{ - struct cpufreq_frequency_table optimal = { - .index = ~0, - .frequency = 0, - }; - struct cpufreq_frequency_table suboptimal = { - .index = ~0, - .frequency = 0, - }; - unsigned int i; - - pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", - target_freq, relation, policy->cpu); - - switch (relation) { - case CPUFREQ_RELATION_H: - suboptimal.frequency = ~0; - break; - case CPUFREQ_RELATION_L: - optimal.frequency = ~0; - break; - } - - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - unsigned int freq = table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - if ((freq < policy->min) || (freq > policy->max)) - continue; - switch (relation) { - case CPUFREQ_RELATION_H: - if (freq <= target_freq) { - if (freq >= optimal.frequency) { - optimal.frequency = freq; - optimal.index = i; - } - } else { - if (freq <= suboptimal.frequency) { - suboptimal.frequency = freq; - suboptimal.index = i; - } - } - break; - case CPUFREQ_RELATION_L: - if (freq >= target_freq) { - if (freq <= optimal.frequency) { - optimal.frequency = freq; - optimal.index = i; - } - } else { - if (freq >= suboptimal.frequency) { - suboptimal.frequency = freq; - suboptimal.index = i; - } - } - break; - } - } - if (optimal.index > i) { - if (suboptimal.index > i) - return -EINVAL; - *index = suboptimal.index; - } else - *index = optimal.index; - - pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency, - table[*index].index); - - return 0; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); - -static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); -/** - * show_available_freqs - show available frequencies for the specified CPU - */ -static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) -{ - unsigned int i = 0; - unsigned int cpu = policy->cpu; - ssize_t count = 0; - struct cpufreq_frequency_table *table; - - if (!per_cpu(cpufreq_show_table, cpu)) - return -ENODEV; - - table = per_cpu(cpufreq_show_table, cpu); - - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - count += sprintf(&buf[count], "%d ", table[i].frequency); - } - count += sprintf(&buf[count], "\n"); - - return count; - -} - -struct freq_attr cpufreq_freq_attr_scaling_available_freqs = { - .attr = { .name = "scaling_available_frequencies", - .mode = 0444, - }, - .show = show_available_freqs, -}; -EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); - -/* - * if you use these, you must assure that the frequency table is valid - * all the time between get_attr and put_attr! - */ -void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, - unsigned int cpu) -{ - pr_debug("setting show_table for cpu %u to %p\n", cpu, table); - per_cpu(cpufreq_show_table, cpu) = table; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr); - -void cpufreq_frequency_table_put_attr(unsigned int cpu) -{ - pr_debug("clearing show_table for cpu %u\n", cpu); - per_cpu(cpufreq_show_table, cpu) = NULL; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); - -void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy) -{ - pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n", - policy->cpu, policy->last_cpu); - per_cpu(cpufreq_show_table, policy->cpu) = per_cpu(cpufreq_show_table, - policy->last_cpu); - per_cpu(cpufreq_show_table, policy->last_cpu) = NULL; -} - -struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) -{ - return per_cpu(cpufreq_show_table, cpu); -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); - -MODULE_AUTHOR("Dominik Brodowski "); -MODULE_DESCRIPTION("CPUfreq frequency table helpers"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/gx-suspmod.c b/linux-3.4/drivers/cpufreq.new/gx-suspmod.c deleted file mode 100644 index 456bee05..00000000 --- a/linux-3.4/drivers/cpufreq.new/gx-suspmod.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Cyrix MediaGX and NatSemi Geode Suspend Modulation - * (C) 2002 Zwane Mwaikambo - * (C) 2002 Hiroshi Miura - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * The author(s) of this software shall not be held liable for damages - * of any nature resulting due to the use of this software. This - * software is provided AS-IS with no warranties. - * - * Theoretical note: - * - * (see Geode(tm) CS5530 manual (rev.4.1) page.56) - * - * CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0 - * are based on Suspend Modulation. - * - * Suspend Modulation works by asserting and de-asserting the SUSP# pin - * to CPU(GX1/GXLV) for configurable durations. When asserting SUSP# - * the CPU enters an idle state. GX1 stops its core clock when SUSP# is - * asserted then power consumption is reduced. - * - * Suspend Modulation's OFF/ON duration are configurable - * with 'Suspend Modulation OFF Count Register' - * and 'Suspend Modulation ON Count Register'. - * These registers are 8bit counters that represent the number of - * 32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF) - * to the processor. - * - * These counters define a ratio which is the effective frequency - * of operation of the system. - * - * OFF Count - * F_eff = Fgx * ---------------------- - * OFF Count + ON Count - * - * 0 <= On Count, Off Count <= 255 - * - * From these limits, we can get register values - * - * off_duration + on_duration <= MAX_DURATION - * on_duration = off_duration * (stock_freq - freq) / freq - * - * off_duration = (freq * DURATION) / stock_freq - * on_duration = DURATION - off_duration - * - * - *--------------------------------------------------------------------------- - * - * ChangeLog: - * Dec. 12, 2003 Hiroshi Miura - * - fix on/off register mistake - * - fix cpu_khz calc when it stops cpu modulation. - * - * Dec. 11, 2002 Hiroshi Miura - * - rewrite for Cyrix MediaGX Cx5510/5520 and - * NatSemi Geode Cs5530(A). - * - * Jul. ??, 2002 Zwane Mwaikambo - * - cs5530_mod patch for 2.4.19-rc1. - * - *--------------------------------------------------------------------------- - * - * Todo - * Test on machines with 5510, 5530, 5530A - */ - -/************************************************************************ - * Suspend Modulation - Definitions * - ************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* PCI config registers, all at F0 */ -#define PCI_PMER1 0x80 /* power management enable register 1 */ -#define PCI_PMER2 0x81 /* power management enable register 2 */ -#define PCI_PMER3 0x82 /* power management enable register 3 */ -#define PCI_IRQTC 0x8c /* irq speedup timer counter register:typical 2 to 4ms */ -#define PCI_VIDTC 0x8d /* video speedup timer counter register: typical 50 to 100ms */ -#define PCI_MODOFF 0x94 /* suspend modulation OFF counter register, 1 = 32us */ -#define PCI_MODON 0x95 /* suspend modulation ON counter register */ -#define PCI_SUSCFG 0x96 /* suspend configuration register */ - -/* PMER1 bits */ -#define GPM (1<<0) /* global power management */ -#define GIT (1<<1) /* globally enable PM device idle timers */ -#define GTR (1<<2) /* globally enable IO traps */ -#define IRQ_SPDUP (1<<3) /* disable clock throttle during interrupt handling */ -#define VID_SPDUP (1<<4) /* disable clock throttle during vga video handling */ - -/* SUSCFG bits */ -#define SUSMOD (1<<0) /* enable/disable suspend modulation */ -/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */ -#define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */ - /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */ -#define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */ -/* the below is supported only with cs5530A */ -#define PWRSVE_ISA (1<<3) /* stop ISA clock */ -#define PWRSVE (1<<4) /* active idle */ - -struct gxfreq_params { - u8 on_duration; - u8 off_duration; - u8 pci_suscfg; - u8 pci_pmer1; - u8 pci_pmer2; - struct pci_dev *cs55x0; -}; - -static struct gxfreq_params *gx_params; -static int stock_freq; - -/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ -static int pci_busclk; -module_param(pci_busclk, int, 0444); - -/* maximum duration for which the cpu may be suspended - * (32us * MAX_DURATION). If no parameter is given, this defaults - * to 255. - * Note that this leads to a maximum of 8 ms(!) where the CPU clock - * is suspended -- processing power is just 0.39% of what it used to be, - * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ -static int max_duration = 255; -module_param(max_duration, int, 0444); - -/* For the default policy, we want at least some processing power - * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV) - */ -#define POLICY_MIN_DIV 20 - - -/** - * we can detect a core multipiler from dir0_lsb - * from GX1 datasheet p.56, - * MULT[3:0]: - * 0000 = SYSCLK multiplied by 4 (test only) - * 0001 = SYSCLK multiplied by 10 - * 0010 = SYSCLK multiplied by 4 - * 0011 = SYSCLK multiplied by 6 - * 0100 = SYSCLK multiplied by 9 - * 0101 = SYSCLK multiplied by 5 - * 0110 = SYSCLK multiplied by 7 - * 0111 = SYSCLK multiplied by 8 - * of 33.3MHz - **/ -static int gx_freq_mult[16] = { - 4, 10, 4, 6, 9, 5, 7, 8, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -/**************************************************************** - * Low Level chipset interface * - ****************************************************************/ -static struct pci_device_id gx_chipset_tbl[] __initdata = { - { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY), }, - { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), }, - { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, gx_chipset_tbl); - -static void gx_write_byte(int reg, int value) -{ - pci_write_config_byte(gx_params->cs55x0, reg, value); -} - -/** - * gx_detect_chipset: - * - **/ -static __init struct pci_dev *gx_detect_chipset(void) -{ - struct pci_dev *gx_pci = NULL; - - /* detect which companion chip is used */ - for_each_pci_dev(gx_pci) { - if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) - return gx_pci; - } - - pr_debug("error: no supported chipset found!\n"); - return NULL; -} - -/** - * gx_get_cpuspeed: - * - * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi - * Geode CPU runs. - */ -static unsigned int gx_get_cpuspeed(unsigned int cpu) -{ - if ((gx_params->pci_suscfg & SUSMOD) == 0) - return stock_freq; - - return (stock_freq * gx_params->off_duration) - / (gx_params->on_duration + gx_params->off_duration); -} - -/** - * gx_validate_speed: - * determine current cpu speed - * - **/ - -static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, - u8 *off_duration) -{ - unsigned int i; - u8 tmp_on, tmp_off; - int old_tmp_freq = stock_freq; - int tmp_freq; - - *off_duration = 1; - *on_duration = 0; - - for (i = max_duration; i > 0; i--) { - tmp_off = ((khz * i) / stock_freq) & 0xff; - tmp_on = i - tmp_off; - tmp_freq = (stock_freq * tmp_off) / i; - /* if this relation is closer to khz, use this. If it's equal, - * prefer it, too - lower latency */ - if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) { - *on_duration = tmp_on; - *off_duration = tmp_off; - old_tmp_freq = tmp_freq; - } - } - - return old_tmp_freq; -} - - -/** - * gx_set_cpuspeed: - * set cpu speed in khz. - **/ - -static void gx_set_cpuspeed(unsigned int khz) -{ - u8 suscfg, pmer1; - unsigned int new_khz; - unsigned long flags; - struct cpufreq_freqs freqs; - - freqs.cpu = 0; - freqs.old = gx_get_cpuspeed(0); - - new_khz = gx_validate_speed(khz, &gx_params->on_duration, - &gx_params->off_duration); - - freqs.new = new_khz; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - local_irq_save(flags); - - - - if (new_khz != stock_freq) { - /* if new khz == 100% of CPU speed, it is special case */ - switch (gx_params->cs55x0->device) { - case PCI_DEVICE_ID_CYRIX_5530_LEGACY: - pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP; - /* FIXME: need to test other values -- Zwane,Miura */ - /* typical 2 to 4ms */ - gx_write_byte(PCI_IRQTC, 4); - /* typical 50 to 100ms */ - gx_write_byte(PCI_VIDTC, 100); - gx_write_byte(PCI_PMER1, pmer1); - - if (gx_params->cs55x0->revision < 0x10) { - /* CS5530(rev 1.2, 1.3) */ - suscfg = gx_params->pci_suscfg|SUSMOD; - } else { - /* CS5530A,B.. */ - suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE; - } - break; - case PCI_DEVICE_ID_CYRIX_5520: - case PCI_DEVICE_ID_CYRIX_5510: - suscfg = gx_params->pci_suscfg | SUSMOD; - break; - default: - local_irq_restore(flags); - pr_debug("fatal: try to set unknown chipset.\n"); - return; - } - } else { - suscfg = gx_params->pci_suscfg & ~(SUSMOD); - gx_params->off_duration = 0; - gx_params->on_duration = 0; - pr_debug("suspend modulation disabled: cpu runs 100%% speed.\n"); - } - - gx_write_byte(PCI_MODOFF, gx_params->off_duration); - gx_write_byte(PCI_MODON, gx_params->on_duration); - - gx_write_byte(PCI_SUSCFG, suscfg); - pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg); - - local_irq_restore(flags); - - gx_params->pci_suscfg = suscfg; - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", - gx_params->on_duration * 32, gx_params->off_duration * 32); - pr_debug("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); -} - -/**************************************************************** - * High level functions * - ****************************************************************/ - -/* - * cpufreq_gx_verify: test if frequency range is valid - * - * This function checks if a given frequency range in kHz is valid - * for the hardware supported by the driver. - */ - -static int cpufreq_gx_verify(struct cpufreq_policy *policy) -{ - unsigned int tmp_freq = 0; - u8 tmp1, tmp2; - - if (!stock_freq || !policy) - return -EINVAL; - - policy->cpu = 0; - cpufreq_verify_within_limits(policy, (stock_freq / max_duration), - stock_freq); - - /* it needs to be assured that at least one supported frequency is - * within policy->min and policy->max. If it is not, policy->max - * needs to be increased until one freuqency is supported. - * policy->min may not be decreased, though. This way we guarantee a - * specific processing capacity. - */ - tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2); - if (tmp_freq < policy->min) - tmp_freq += stock_freq / max_duration; - policy->min = tmp_freq; - if (policy->min > policy->max) - policy->max = tmp_freq; - tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2); - if (tmp_freq > policy->max) - tmp_freq -= stock_freq / max_duration; - policy->max = tmp_freq; - if (policy->max < policy->min) - policy->max = policy->min; - cpufreq_verify_within_limits(policy, (stock_freq / max_duration), - stock_freq); - - return 0; -} - -/* - * cpufreq_gx_target: - * - */ -static int cpufreq_gx_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - u8 tmp1, tmp2; - unsigned int tmp_freq; - - if (!stock_freq || !policy) - return -EINVAL; - - policy->cpu = 0; - - tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2); - while (tmp_freq < policy->min) { - tmp_freq += stock_freq / max_duration; - tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2); - } - while (tmp_freq > policy->max) { - tmp_freq -= stock_freq / max_duration; - tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2); - } - - gx_set_cpuspeed(tmp_freq); - - return 0; -} - -static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int maxfreq, curfreq; - - if (!policy || policy->cpu != 0) - return -ENODEV; - - /* determine maximum frequency */ - if (pci_busclk) - maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; - else if (cpu_khz) - maxfreq = cpu_khz; - else - maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; - - stock_freq = maxfreq; - curfreq = gx_get_cpuspeed(0); - - pr_debug("cpu max frequency is %d.\n", maxfreq); - pr_debug("cpu current frequency is %dkHz.\n", curfreq); - - /* setup basic struct for cpufreq API */ - policy->cpu = 0; - - if (max_duration < POLICY_MIN_DIV) - policy->min = maxfreq / max_duration; - else - policy->min = maxfreq / POLICY_MIN_DIV; - policy->max = maxfreq; - policy->cur = curfreq; - policy->cpuinfo.min_freq = maxfreq / max_duration; - policy->cpuinfo.max_freq = maxfreq; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - - return 0; -} - -/* - * cpufreq_gx_init: - * MediaGX/Geode GX initialize cpufreq driver - */ -static struct cpufreq_driver gx_suspmod_driver = { - .get = gx_get_cpuspeed, - .verify = cpufreq_gx_verify, - .target = cpufreq_gx_target, - .init = cpufreq_gx_cpu_init, - .name = "gx-suspmod", - .owner = THIS_MODULE, -}; - -static int __init cpufreq_gx_init(void) -{ - int ret; - struct gxfreq_params *params; - struct pci_dev *gx_pci; - - /* Test if we have the right hardware */ - gx_pci = gx_detect_chipset(); - if (gx_pci == NULL) - return -ENODEV; - - /* check whether module parameters are sane */ - if (max_duration > 0xff) - max_duration = 0xff; - - pr_debug("geode suspend modulation available.\n"); - - params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); - if (params == NULL) - return -ENOMEM; - - params->cs55x0 = gx_pci; - gx_params = params; - - /* keep cs55x0 configurations */ - pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg)); - pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1)); - pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2)); - pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration)); - pci_read_config_byte(params->cs55x0, PCI_MODOFF, - &(params->off_duration)); - - ret = cpufreq_register_driver(&gx_suspmod_driver); - if (ret) { - kfree(params); - return ret; /* register error! */ - } - - return 0; -} - -static void __exit cpufreq_gx_exit(void) -{ - cpufreq_unregister_driver(&gx_suspmod_driver); - pci_dev_put(gx_params->cs55x0); - kfree(gx_params); -} - -MODULE_AUTHOR("Hiroshi Miura "); -MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode"); -MODULE_LICENSE("GPL"); - -module_init(cpufreq_gx_init); -module_exit(cpufreq_gx_exit); - diff --git a/linux-3.4/drivers/cpufreq.new/longhaul.c b/linux-3.4/drivers/cpufreq.new/longhaul.c deleted file mode 100644 index 53ddbc76..00000000 --- a/linux-3.4/drivers/cpufreq.new/longhaul.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * (C) 2001-2004 Dave Jones. - * (C) 2002 Padraig Brady. - * - * Licensed under the terms of the GNU GPL License version 2. - * Based upon datasheets & sample CPUs kindly provided by VIA. - * - * VIA have currently 3 different versions of Longhaul. - * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147. - * It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0. - * Version 2 of longhaul is backward compatible with v1, but adds - * LONGHAUL MSR for purpose of both frequency and voltage scaling. - * Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C). - * Version 3 of longhaul got renamed to Powersaver and redesigned - * to use only the POWERSAVER MSR at 0x110a. - * It is present in Ezra-T (C5M), Nehemiah (C5X) and above. - * It's pretty much the same feature wise to longhaul v2, though - * there is provision for scaling FSB too, but this doesn't work - * too well in practice so we don't even try to use this. - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "longhaul.h" - -#define PFX "longhaul: " - -#define TYPE_LONGHAUL_V1 1 -#define TYPE_LONGHAUL_V2 2 -#define TYPE_POWERSAVER 3 - -#define CPU_SAMUEL 1 -#define CPU_SAMUEL2 2 -#define CPU_EZRA 3 -#define CPU_EZRA_T 4 -#define CPU_NEHEMIAH 5 -#define CPU_NEHEMIAH_C 6 - -/* Flags */ -#define USE_ACPI_C3 (1 << 1) -#define USE_NORTHBRIDGE (1 << 2) - -static int cpu_model; -static unsigned int numscales = 16; -static unsigned int fsb; - -static const struct mV_pos *vrm_mV_table; -static const unsigned char *mV_vrm_table; - -static unsigned int highest_speed, lowest_speed; /* kHz */ -static unsigned int minmult, maxmult; -static int can_scale_voltage; -static struct acpi_processor *pr; -static struct acpi_processor_cx *cx; -static u32 acpi_regs_addr; -static u8 longhaul_flags; -static unsigned int longhaul_index; - -/* Module parameters */ -static int scale_voltage; -static int disable_acpi_c3; -static int revid_errata; - - -/* Clock ratios multiplied by 10 */ -static int mults[32]; -static int eblcr[32]; -static int longhaul_version; -static struct cpufreq_frequency_table *longhaul_table; - -static char speedbuffer[8]; - -static char *print_speed(int speed) -{ - if (speed < 1000) { - snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed); - return speedbuffer; - } - - if (speed%1000 == 0) - snprintf(speedbuffer, sizeof(speedbuffer), - "%dGHz", speed/1000); - else - snprintf(speedbuffer, sizeof(speedbuffer), - "%d.%dGHz", speed/1000, (speed%1000)/100); - - return speedbuffer; -} - - -static unsigned int calc_speed(int mult) -{ - int khz; - khz = (mult/10)*fsb; - if (mult%10) - khz += fsb/2; - khz *= 1000; - return khz; -} - - -static int longhaul_get_cpu_mult(void) -{ - unsigned long invalue = 0, lo, hi; - - rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi); - invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22; - if (longhaul_version == TYPE_LONGHAUL_V2 || - longhaul_version == TYPE_POWERSAVER) { - if (lo & (1<<27)) - invalue += 16; - } - return eblcr[invalue]; -} - -/* For processor with BCR2 MSR */ - -static void do_longhaul1(unsigned int mults_index) -{ - union msr_bcr2 bcr2; - - rdmsrl(MSR_VIA_BCR2, bcr2.val); - /* Enable software clock multiplier */ - bcr2.bits.ESOFTBF = 1; - bcr2.bits.CLOCKMUL = mults_index & 0xff; - - /* Sync to timer tick */ - safe_halt(); - /* Change frequency on next halt or sleep */ - wrmsrl(MSR_VIA_BCR2, bcr2.val); - /* Invoke transition */ - ACPI_FLUSH_CPU_CACHE(); - halt(); - - /* Disable software clock multiplier */ - local_irq_disable(); - rdmsrl(MSR_VIA_BCR2, bcr2.val); - bcr2.bits.ESOFTBF = 0; - wrmsrl(MSR_VIA_BCR2, bcr2.val); -} - -/* For processor with Longhaul MSR */ - -static void do_powersaver(int cx_address, unsigned int mults_index, - unsigned int dir) -{ - union msr_longhaul longhaul; - u32 t; - - rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); - /* Setup new frequency */ - if (!revid_errata) - longhaul.bits.RevisionKey = longhaul.bits.RevisionID; - else - longhaul.bits.RevisionKey = 0; - longhaul.bits.SoftBusRatio = mults_index & 0xf; - longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4; - /* Setup new voltage */ - if (can_scale_voltage) - longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f; - /* Sync to timer tick */ - safe_halt(); - /* Raise voltage if necessary */ - if (can_scale_voltage && dir) { - longhaul.bits.EnableSoftVID = 1; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - /* Change voltage */ - if (!cx_address) { - ACPI_FLUSH_CPU_CACHE(); - halt(); - } else { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C3 */ - inb(cx_address); - /* Dummy op - must do something useless after P_LVL3 - * read */ - t = inl(acpi_gbl_FADT.xpm_timer_block.address); - } - longhaul.bits.EnableSoftVID = 0; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - } - - /* Change frequency on next halt or sleep */ - longhaul.bits.EnableSoftBusRatio = 1; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - if (!cx_address) { - ACPI_FLUSH_CPU_CACHE(); - halt(); - } else { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C3 */ - inb(cx_address); - /* Dummy op - must do something useless after P_LVL3 read */ - t = inl(acpi_gbl_FADT.xpm_timer_block.address); - } - /* Disable bus ratio bit */ - longhaul.bits.EnableSoftBusRatio = 0; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - - /* Reduce voltage if necessary */ - if (can_scale_voltage && !dir) { - longhaul.bits.EnableSoftVID = 1; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - /* Change voltage */ - if (!cx_address) { - ACPI_FLUSH_CPU_CACHE(); - halt(); - } else { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C3 */ - inb(cx_address); - /* Dummy op - must do something useless after P_LVL3 - * read */ - t = inl(acpi_gbl_FADT.xpm_timer_block.address); - } - longhaul.bits.EnableSoftVID = 0; - wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - } -} - -/** - * longhaul_set_cpu_frequency() - * @mults_index : bitpattern of the new multiplier. - * - * Sets a new clock ratio. - */ - -static void longhaul_setstate(unsigned int table_index) -{ - unsigned int mults_index; - int speed, mult; - struct cpufreq_freqs freqs; - unsigned long flags; - unsigned int pic1_mask, pic2_mask; - u16 bm_status = 0; - u32 bm_timeout = 1000; - unsigned int dir = 0; - - mults_index = longhaul_table[table_index].index; - /* Safety precautions */ - mult = mults[mults_index & 0x1f]; - if (mult == -1) - return; - speed = calc_speed(mult); - if ((speed > highest_speed) || (speed < lowest_speed)) - return; - /* Voltage transition before frequency transition? */ - if (can_scale_voltage && longhaul_index < table_index) - dir = 1; - - freqs.old = calc_speed(longhaul_get_cpu_mult()); - freqs.new = speed; - freqs.cpu = 0; /* longhaul.c is UP only driver */ - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", - fsb, mult/10, mult%10, print_speed(speed/1000)); -retry_loop: - preempt_disable(); - local_irq_save(flags); - - pic2_mask = inb(0xA1); - pic1_mask = inb(0x21); /* works on C3. save mask. */ - outb(0xFF, 0xA1); /* Overkill */ - outb(0xFE, 0x21); /* TMR0 only */ - - /* Wait while PCI bus is busy. */ - if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE - || ((pr != NULL) && pr->flags.bm_control))) { - bm_status = inw(acpi_regs_addr); - bm_status &= 1 << 4; - while (bm_status && bm_timeout) { - outw(1 << 4, acpi_regs_addr); - bm_timeout--; - bm_status = inw(acpi_regs_addr); - bm_status &= 1 << 4; - } - } - - if (longhaul_flags & USE_NORTHBRIDGE) { - /* Disable AGP and PCI arbiters */ - outb(3, 0x22); - } else if ((pr != NULL) && pr->flags.bm_control) { - /* Disable bus master arbitration */ - acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); - } - switch (longhaul_version) { - - /* - * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B]) - * Software controlled multipliers only. - */ - case TYPE_LONGHAUL_V1: - do_longhaul1(mults_index); - break; - - /* - * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C] - * - * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N]) - * Nehemiah can do FSB scaling too, but this has never been proven - * to work in practice. - */ - case TYPE_LONGHAUL_V2: - case TYPE_POWERSAVER: - if (longhaul_flags & USE_ACPI_C3) { - /* Don't allow wakeup */ - acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0); - do_powersaver(cx->address, mults_index, dir); - } else { - do_powersaver(0, mults_index, dir); - } - break; - } - - if (longhaul_flags & USE_NORTHBRIDGE) { - /* Enable arbiters */ - outb(0, 0x22); - } else if ((pr != NULL) && pr->flags.bm_control) { - /* Enable bus master arbitration */ - acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); - } - outb(pic2_mask, 0xA1); /* restore mask */ - outb(pic1_mask, 0x21); - - local_irq_restore(flags); - preempt_enable(); - - freqs.new = calc_speed(longhaul_get_cpu_mult()); - /* Check if requested frequency is set. */ - if (unlikely(freqs.new != speed)) { - printk(KERN_INFO PFX "Failed to set requested frequency!\n"); - /* Revision ID = 1 but processor is expecting revision key - * equal to 0. Jumpers at the bottom of processor will change - * multiplier and FSB, but will not change bits in Longhaul - * MSR nor enable voltage scaling. */ - if (!revid_errata) { - printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" " - "option.\n"); - revid_errata = 1; - msleep(200); - goto retry_loop; - } - /* Why ACPI C3 sometimes doesn't work is a mystery for me. - * But it does happen. Processor is entering ACPI C3 state, - * but it doesn't change frequency. I tried poking various - * bits in northbridge registers, but without success. */ - if (longhaul_flags & USE_ACPI_C3) { - printk(KERN_INFO PFX "Disabling ACPI C3 support.\n"); - longhaul_flags &= ~USE_ACPI_C3; - if (revid_errata) { - printk(KERN_INFO PFX "Disabling \"Ignore " - "Revision ID\" option.\n"); - revid_errata = 0; - } - msleep(200); - goto retry_loop; - } - /* This shouldn't happen. Longhaul ver. 2 was reported not - * working on processors without voltage scaling, but with - * RevID = 1. RevID errata will make things right. Just - * to be 100% sure. */ - if (longhaul_version == TYPE_LONGHAUL_V2) { - printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n"); - longhaul_version = TYPE_LONGHAUL_V1; - msleep(200); - goto retry_loop; - } - } - /* Report true CPU frequency */ - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - if (!bm_timeout) - printk(KERN_INFO PFX "Warning: Timeout while waiting for " - "idle PCI bus.\n"); -} - -/* - * Centaur decided to make life a little more tricky. - * Only longhaul v1 is allowed to read EBLCR BSEL[0:1]. - * Samuel2 and above have to try and guess what the FSB is. - * We do this by assuming we booted at maximum multiplier, and interpolate - * between that value multiplied by possible FSBs and cpu_mhz which - * was calculated at boot time. Really ugly, but no other way to do this. - */ - -#define ROUNDING 0xf - -static int guess_fsb(int mult) -{ - int speed = cpu_khz / 1000; - int i; - int speeds[] = { 666, 1000, 1333, 2000 }; - int f_max, f_min; - - for (i = 0; i < 4; i++) { - f_max = ((speeds[i] * mult) + 50) / 100; - f_max += (ROUNDING / 2); - f_min = f_max - ROUNDING; - if ((speed <= f_max) && (speed >= f_min)) - return speeds[i] / 10; - } - return 0; -} - - -static int __cpuinit longhaul_get_ranges(void) -{ - unsigned int i, j, k = 0; - unsigned int ratio; - int mult; - - /* Get current frequency */ - mult = longhaul_get_cpu_mult(); - if (mult == -1) { - printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n"); - return -EINVAL; - } - fsb = guess_fsb(mult); - if (fsb == 0) { - printk(KERN_INFO PFX "Invalid (reserved) FSB!\n"); - return -EINVAL; - } - /* Get max multiplier - as we always did. - * Longhaul MSR is useful only when voltage scaling is enabled. - * C3 is booting at max anyway. */ - maxmult = mult; - /* Get min multiplier */ - switch (cpu_model) { - case CPU_NEHEMIAH: - minmult = 50; - break; - case CPU_NEHEMIAH_C: - minmult = 40; - break; - default: - minmult = 30; - break; - } - - pr_debug("MinMult:%d.%dx MaxMult:%d.%dx\n", - minmult/10, minmult%10, maxmult/10, maxmult%10); - - highest_speed = calc_speed(maxmult); - lowest_speed = calc_speed(minmult); - pr_debug("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb, - print_speed(lowest_speed/1000), - print_speed(highest_speed/1000)); - - if (lowest_speed == highest_speed) { - printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n"); - return -EINVAL; - } - if (lowest_speed > highest_speed) { - printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", - lowest_speed, highest_speed); - return -EINVAL; - } - - longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table), - GFP_KERNEL); - if (!longhaul_table) - return -ENOMEM; - - for (j = 0; j < numscales; j++) { - ratio = mults[j]; - if (ratio == -1) - continue; - if (ratio > maxmult || ratio < minmult) - continue; - longhaul_table[k].frequency = calc_speed(ratio); - longhaul_table[k].index = j; - k++; - } - if (k <= 1) { - kfree(longhaul_table); - return -ENODEV; - } - /* Sort */ - for (j = 0; j < k - 1; j++) { - unsigned int min_f, min_i; - min_f = longhaul_table[j].frequency; - min_i = j; - for (i = j + 1; i < k; i++) { - if (longhaul_table[i].frequency < min_f) { - min_f = longhaul_table[i].frequency; - min_i = i; - } - } - if (min_i != j) { - swap(longhaul_table[j].frequency, - longhaul_table[min_i].frequency); - swap(longhaul_table[j].index, - longhaul_table[min_i].index); - } - } - - longhaul_table[k].frequency = CPUFREQ_TABLE_END; - - /* Find index we are running on */ - for (j = 0; j < k; j++) { - if (mults[longhaul_table[j].index & 0x1f] == mult) { - longhaul_index = j; - break; - } - } - return 0; -} - - -static void __cpuinit longhaul_setup_voltagescaling(void) -{ - union msr_longhaul longhaul; - struct mV_pos minvid, maxvid, vid; - unsigned int j, speed, pos, kHz_step, numvscales; - int min_vid_speed; - - rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); - if (!(longhaul.bits.RevisionID & 1)) { - printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n"); - return; - } - - if (!longhaul.bits.VRMRev) { - printk(KERN_INFO PFX "VRM 8.5\n"); - vrm_mV_table = &vrm85_mV[0]; - mV_vrm_table = &mV_vrm85[0]; - } else { - printk(KERN_INFO PFX "Mobile VRM\n"); - if (cpu_model < CPU_NEHEMIAH) - return; - vrm_mV_table = &mobilevrm_mV[0]; - mV_vrm_table = &mV_mobilevrm[0]; - } - - minvid = vrm_mV_table[longhaul.bits.MinimumVID]; - maxvid = vrm_mV_table[longhaul.bits.MaximumVID]; - - if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) { - printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " - "Voltage scaling disabled.\n", - minvid.mV/1000, minvid.mV%1000, - maxvid.mV/1000, maxvid.mV%1000); - return; - } - - if (minvid.mV == maxvid.mV) { - printk(KERN_INFO PFX "Claims to support voltage scaling but " - "min & max are both %d.%03d. " - "Voltage scaling disabled\n", - maxvid.mV/1000, maxvid.mV%1000); - return; - } - - /* How many voltage steps*/ - numvscales = maxvid.pos - minvid.pos + 1; - printk(KERN_INFO PFX - "Max VID=%d.%03d " - "Min VID=%d.%03d, " - "%d possible voltage scales\n", - maxvid.mV/1000, maxvid.mV%1000, - minvid.mV/1000, minvid.mV%1000, - numvscales); - - /* Calculate max frequency at min voltage */ - j = longhaul.bits.MinMHzBR; - if (longhaul.bits.MinMHzBR4) - j += 16; - min_vid_speed = eblcr[j]; - if (min_vid_speed == -1) - return; - switch (longhaul.bits.MinMHzFSB) { - case 0: - min_vid_speed *= 13333; - break; - case 1: - min_vid_speed *= 10000; - break; - case 3: - min_vid_speed *= 6666; - break; - default: - return; - break; - } - if (min_vid_speed >= highest_speed) - return; - /* Calculate kHz for one voltage step */ - kHz_step = (highest_speed - min_vid_speed) / numvscales; - - j = 0; - while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { - speed = longhaul_table[j].frequency; - if (speed > min_vid_speed) - pos = (speed - min_vid_speed) / kHz_step + minvid.pos; - else - pos = minvid.pos; - longhaul_table[j].index |= mV_vrm_table[pos] << 8; - vid = vrm_mV_table[mV_vrm_table[pos]]; - printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", - speed, j, vid.mV); - j++; - } - - can_scale_voltage = 1; - printk(KERN_INFO PFX "Voltage scaling enabled.\n"); -} - - -static int longhaul_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, longhaul_table); -} - - -static int longhaul_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned int table_index = 0; - unsigned int i; - unsigned int dir = 0; - u8 vid, current_vid; - - if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, - relation, &table_index)) - return -EINVAL; - - /* Don't set same frequency again */ - if (longhaul_index == table_index) - return 0; - - if (!can_scale_voltage) - longhaul_setstate(table_index); - else { - /* On test system voltage transitions exceeding single - * step up or down were turning motherboard off. Both - * "ondemand" and "userspace" are unsafe. C7 is doing - * this in hardware, C3 is old and we need to do this - * in software. */ - i = longhaul_index; - current_vid = (longhaul_table[longhaul_index].index >> 8); - current_vid &= 0x1f; - if (table_index > longhaul_index) - dir = 1; - while (i != table_index) { - vid = (longhaul_table[i].index >> 8) & 0x1f; - if (vid != current_vid) { - longhaul_setstate(i); - current_vid = vid; - msleep(200); - } - if (dir) - i++; - else - i--; - } - longhaul_setstate(table_index); - } - longhaul_index = table_index; - return 0; -} - - -static unsigned int longhaul_get(unsigned int cpu) -{ - if (cpu) - return 0; - return calc_speed(longhaul_get_cpu_mult()); -} - -static acpi_status longhaul_walk_callback(acpi_handle obj_handle, - u32 nesting_level, - void *context, void **return_value) -{ - struct acpi_device *d; - - if (acpi_bus_get_device(obj_handle, &d)) - return 0; - - *return_value = acpi_driver_data(d); - return 1; -} - -/* VIA don't support PM2 reg, but have something similar */ -static int enable_arbiter_disable(void) -{ - struct pci_dev *dev; - int status = 1; - int reg; - u8 pci_cmd; - - /* Find PLE133 host bridge */ - reg = 0x78; - dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, - NULL); - /* Find PM133/VT8605 host bridge */ - if (dev == NULL) - dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_8605_0, NULL); - /* Find CLE266 host bridge */ - if (dev == NULL) { - reg = 0x76; - dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_862X_0, NULL); - /* Find CN400 V-Link host bridge */ - if (dev == NULL) - dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL); - } - if (dev != NULL) { - /* Enable access to port 0x22 */ - pci_read_config_byte(dev, reg, &pci_cmd); - if (!(pci_cmd & 1<<7)) { - pci_cmd |= 1<<7; - pci_write_config_byte(dev, reg, pci_cmd); - pci_read_config_byte(dev, reg, &pci_cmd); - if (!(pci_cmd & 1<<7)) { - printk(KERN_ERR PFX - "Can't enable access to port 0x22.\n"); - status = 0; - } - } - pci_dev_put(dev); - return status; - } - return 0; -} - -static int longhaul_setup_southbridge(void) -{ - struct pci_dev *dev; - u8 pci_cmd; - - /* Find VT8235 southbridge */ - dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); - if (dev == NULL) - /* Find VT8237 southbridge */ - dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_8237, NULL); - if (dev != NULL) { - /* Set transition time to max */ - pci_read_config_byte(dev, 0xec, &pci_cmd); - pci_cmd &= ~(1 << 2); - pci_write_config_byte(dev, 0xec, pci_cmd); - pci_read_config_byte(dev, 0xe4, &pci_cmd); - pci_cmd &= ~(1 << 7); - pci_write_config_byte(dev, 0xe4, pci_cmd); - pci_read_config_byte(dev, 0xe5, &pci_cmd); - pci_cmd |= 1 << 7; - pci_write_config_byte(dev, 0xe5, pci_cmd); - /* Get address of ACPI registers block*/ - pci_read_config_byte(dev, 0x81, &pci_cmd); - if (pci_cmd & 1 << 7) { - pci_read_config_dword(dev, 0x88, &acpi_regs_addr); - acpi_regs_addr &= 0xff00; - printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", - acpi_regs_addr); - } - - pci_dev_put(dev); - return 1; - } - return 0; -} - -static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - char *cpuname = NULL; - int ret; - u32 lo, hi; - - /* Check what we have on this motherboard */ - switch (c->x86_model) { - case 6: - cpu_model = CPU_SAMUEL; - cpuname = "C3 'Samuel' [C5A]"; - longhaul_version = TYPE_LONGHAUL_V1; - memcpy(mults, samuel1_mults, sizeof(samuel1_mults)); - memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr)); - break; - - case 7: - switch (c->x86_mask) { - case 0: - longhaul_version = TYPE_LONGHAUL_V1; - cpu_model = CPU_SAMUEL2; - cpuname = "C3 'Samuel 2' [C5B]"; - /* Note, this is not a typo, early Samuel2's had - * Samuel1 ratios. */ - memcpy(mults, samuel1_mults, sizeof(samuel1_mults)); - memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); - break; - case 1 ... 15: - longhaul_version = TYPE_LONGHAUL_V2; - if (c->x86_mask < 8) { - cpu_model = CPU_SAMUEL2; - cpuname = "C3 'Samuel 2' [C5B]"; - } else { - cpu_model = CPU_EZRA; - cpuname = "C3 'Ezra' [C5C]"; - } - memcpy(mults, ezra_mults, sizeof(ezra_mults)); - memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr)); - break; - } - break; - - case 8: - cpu_model = CPU_EZRA_T; - cpuname = "C3 'Ezra-T' [C5M]"; - longhaul_version = TYPE_POWERSAVER; - numscales = 32; - memcpy(mults, ezrat_mults, sizeof(ezrat_mults)); - memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr)); - break; - - case 9: - longhaul_version = TYPE_POWERSAVER; - numscales = 32; - memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults)); - memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr)); - switch (c->x86_mask) { - case 0 ... 1: - cpu_model = CPU_NEHEMIAH; - cpuname = "C3 'Nehemiah A' [C5XLOE]"; - break; - case 2 ... 4: - cpu_model = CPU_NEHEMIAH; - cpuname = "C3 'Nehemiah B' [C5XLOH]"; - break; - case 5 ... 15: - cpu_model = CPU_NEHEMIAH_C; - cpuname = "C3 'Nehemiah C' [C5P]"; - break; - } - break; - - default: - cpuname = "Unknown"; - break; - } - /* Check Longhaul ver. 2 */ - if (longhaul_version == TYPE_LONGHAUL_V2) { - rdmsr(MSR_VIA_LONGHAUL, lo, hi); - if (lo == 0 && hi == 0) - /* Looks like MSR isn't present */ - longhaul_version = TYPE_LONGHAUL_V1; - } - - printk(KERN_INFO PFX "VIA %s CPU detected. ", cpuname); - switch (longhaul_version) { - case TYPE_LONGHAUL_V1: - case TYPE_LONGHAUL_V2: - printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version); - break; - case TYPE_POWERSAVER: - printk(KERN_CONT "Powersaver supported.\n"); - break; - }; - - /* Doesn't hurt */ - longhaul_setup_southbridge(); - - /* Find ACPI data for processor */ - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, &longhaul_walk_callback, NULL, - NULL, (void *)&pr); - - /* Check ACPI support for C3 state */ - if (pr != NULL && longhaul_version == TYPE_POWERSAVER) { - cx = &pr->power.states[ACPI_STATE_C3]; - if (cx->address > 0 && cx->latency <= 1000) - longhaul_flags |= USE_ACPI_C3; - } - /* Disable if it isn't working */ - if (disable_acpi_c3) - longhaul_flags &= ~USE_ACPI_C3; - /* Check if northbridge is friendly */ - if (enable_arbiter_disable()) - longhaul_flags |= USE_NORTHBRIDGE; - - /* Check ACPI support for bus master arbiter disable */ - if (!(longhaul_flags & USE_ACPI_C3 - || longhaul_flags & USE_NORTHBRIDGE) - && ((pr == NULL) || !(pr->flags.bm_control))) { - printk(KERN_ERR PFX - "No ACPI support. Unsupported northbridge.\n"); - return -ENODEV; - } - - if (longhaul_flags & USE_NORTHBRIDGE) - printk(KERN_INFO PFX "Using northbridge support.\n"); - if (longhaul_flags & USE_ACPI_C3) - printk(KERN_INFO PFX "Using ACPI support.\n"); - - ret = longhaul_get_ranges(); - if (ret != 0) - return ret; - - if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0)) - longhaul_setup_voltagescaling(); - - policy->cpuinfo.transition_latency = 200000; /* nsec */ - policy->cur = calc_speed(longhaul_get_cpu_mult()); - - ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); - if (ret) - return ret; - - cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu); - - return 0; -} - -static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - -static struct freq_attr *longhaul_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver longhaul_driver = { - .verify = longhaul_verify, - .target = longhaul_target, - .get = longhaul_get, - .init = longhaul_cpu_init, - .exit = __devexit_p(longhaul_cpu_exit), - .name = "longhaul", - .owner = THIS_MODULE, - .attr = longhaul_attr, -}; - -static const struct x86_cpu_id longhaul_id[] = { - { X86_VENDOR_CENTAUR, 6 }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, longhaul_id); - -static int __init longhaul_init(void) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - - if (!x86_match_cpu(longhaul_id)) - return -ENODEV; - -#ifdef CONFIG_SMP - if (num_online_cpus() > 1) { - printk(KERN_ERR PFX "More than 1 CPU detected, " - "longhaul disabled.\n"); - return -ENODEV; - } -#endif -#ifdef CONFIG_X86_IO_APIC - if (cpu_has_apic) { - printk(KERN_ERR PFX "APIC detected. Longhaul is currently " - "broken in this configuration.\n"); - return -ENODEV; - } -#endif - switch (c->x86_model) { - case 6 ... 9: - return cpufreq_register_driver(&longhaul_driver); - case 10: - printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n"); - default: - ; - } - - return -ENODEV; -} - - -static void __exit longhaul_exit(void) -{ - int i; - - for (i = 0; i < numscales; i++) { - if (mults[i] == maxmult) { - longhaul_setstate(i); - break; - } - } - - cpufreq_unregister_driver(&longhaul_driver); - kfree(longhaul_table); -} - -/* Even if BIOS is exporting ACPI C3 state, and it is used - * with success when CPU is idle, this state doesn't - * trigger frequency transition in some cases. */ -module_param(disable_acpi_c3, int, 0644); -MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support"); -/* Change CPU voltage with frequency. Very useful to save - * power, but most VIA C3 processors aren't supporting it. */ -module_param(scale_voltage, int, 0644); -MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); -/* Force revision key to 0 for processors which doesn't - * support voltage scaling, but are introducing itself as - * such. */ -module_param(revid_errata, int, 0644); -MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); - -MODULE_AUTHOR("Dave Jones "); -MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); -MODULE_LICENSE("GPL"); - -late_initcall(longhaul_init); -module_exit(longhaul_exit); diff --git a/linux-3.4/drivers/cpufreq.new/longhaul.h b/linux-3.4/drivers/cpufreq.new/longhaul.h deleted file mode 100644 index cbf48fbc..00000000 --- a/linux-3.4/drivers/cpufreq.new/longhaul.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - * longhaul.h - * (C) 2003 Dave Jones. - * - * Licensed under the terms of the GNU GPL License version 2. - * - * VIA-specific information - */ - -union msr_bcr2 { - struct { - unsigned Reseved:19, // 18:0 - ESOFTBF:1, // 19 - Reserved2:3, // 22:20 - CLOCKMUL:4, // 26:23 - Reserved3:5; // 31:27 - } bits; - unsigned long val; -}; - -union msr_longhaul { - struct { - unsigned RevisionID:4, // 3:0 - RevisionKey:4, // 7:4 - EnableSoftBusRatio:1, // 8 - EnableSoftVID:1, // 9 - EnableSoftBSEL:1, // 10 - Reserved:3, // 11:13 - SoftBusRatio4:1, // 14 - VRMRev:1, // 15 - SoftBusRatio:4, // 19:16 - SoftVID:5, // 24:20 - Reserved2:3, // 27:25 - SoftBSEL:2, // 29:28 - Reserved3:2, // 31:30 - MaxMHzBR:4, // 35:32 - MaximumVID:5, // 40:36 - MaxMHzFSB:2, // 42:41 - MaxMHzBR4:1, // 43 - Reserved4:4, // 47:44 - MinMHzBR:4, // 51:48 - MinimumVID:5, // 56:52 - MinMHzFSB:2, // 58:57 - MinMHzBR4:1, // 59 - Reserved5:4; // 63:60 - } bits; - unsigned long long val; -}; - -/* - * Clock ratio tables. Div/Mod by 10 to get ratio. - * The eblcr values specify the ratio read from the CPU. - * The mults values specify what to write to the CPU. - */ - -/* - * VIA C3 Samuel 1 & Samuel 2 (stepping 0) - */ -static const int __cpuinitdata samuel1_mults[16] = { - -1, /* 0000 -> RESERVED */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - -1, /* 0011 -> RESERVED */ - -1, /* 0100 -> RESERVED */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 55, /* 0111 -> 5.5x */ - 60, /* 1000 -> 6.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 50, /* 1011 -> 5.0x */ - 65, /* 1100 -> 6.5x */ - 75, /* 1101 -> 7.5x */ - -1, /* 1110 -> RESERVED */ - -1, /* 1111 -> RESERVED */ -}; - -static const int __cpuinitdata samuel1_eblcr[16] = { - 50, /* 0000 -> RESERVED */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - -1, /* 0011 -> RESERVED */ - 55, /* 0100 -> 5.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - -1, /* 0111 -> RESERVED */ - -1, /* 1000 -> RESERVED */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 60, /* 1011 -> 6.0x */ - -1, /* 1100 -> RESERVED */ - 75, /* 1101 -> 7.5x */ - -1, /* 1110 -> RESERVED */ - 65, /* 1111 -> 6.5x */ -}; - -/* - * VIA C3 Samuel2 Stepping 1->15 - */ -static const int __cpuinitdata samuel2_eblcr[16] = { - 50, /* 0000 -> 5.0x */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - 100, /* 0011 -> 10.0x */ - 55, /* 0100 -> 5.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 110, /* 0111 -> 11.0x */ - 90, /* 1000 -> 9.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 60, /* 1011 -> 6.0x */ - 120, /* 1100 -> 12.0x */ - 75, /* 1101 -> 7.5x */ - 130, /* 1110 -> 13.0x */ - 65, /* 1111 -> 6.5x */ -}; - -/* - * VIA C3 Ezra - */ -static const int __cpuinitdata ezra_mults[16] = { - 100, /* 0000 -> 10.0x */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - 90, /* 0011 -> 9.0x */ - 95, /* 0100 -> 9.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 55, /* 0111 -> 5.5x */ - 60, /* 1000 -> 6.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 50, /* 1011 -> 5.0x */ - 65, /* 1100 -> 6.5x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 120, /* 1111 -> 12.0x */ -}; - -static const int __cpuinitdata ezra_eblcr[16] = { - 50, /* 0000 -> 5.0x */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - 100, /* 0011 -> 10.0x */ - 55, /* 0100 -> 5.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 95, /* 0111 -> 9.5x */ - 90, /* 1000 -> 9.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 60, /* 1011 -> 6.0x */ - 120, /* 1100 -> 12.0x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 65, /* 1111 -> 6.5x */ -}; - -/* - * VIA C3 (Ezra-T) [C5M]. - */ -static const int __cpuinitdata ezrat_mults[32] = { - 100, /* 0000 -> 10.0x */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - 90, /* 0011 -> 9.0x */ - 95, /* 0100 -> 9.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 55, /* 0111 -> 5.5x */ - 60, /* 1000 -> 6.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 50, /* 1011 -> 5.0x */ - 65, /* 1100 -> 6.5x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 120, /* 1111 -> 12.0x */ - - -1, /* 0000 -> RESERVED (10.0x) */ - 110, /* 0001 -> 11.0x */ - -1, /* 0010 -> 12.0x */ - -1, /* 0011 -> RESERVED (9.0x)*/ - 105, /* 0100 -> 10.5x */ - 115, /* 0101 -> 11.5x */ - 125, /* 0110 -> 12.5x */ - 135, /* 0111 -> 13.5x */ - 140, /* 1000 -> 14.0x */ - 150, /* 1001 -> 15.0x */ - 160, /* 1010 -> 16.0x */ - 130, /* 1011 -> 13.0x */ - 145, /* 1100 -> 14.5x */ - 155, /* 1101 -> 15.5x */ - -1, /* 1110 -> RESERVED (13.0x) */ - -1, /* 1111 -> RESERVED (12.0x) */ -}; - -static const int __cpuinitdata ezrat_eblcr[32] = { - 50, /* 0000 -> 5.0x */ - 30, /* 0001 -> 3.0x */ - 40, /* 0010 -> 4.0x */ - 100, /* 0011 -> 10.0x */ - 55, /* 0100 -> 5.5x */ - 35, /* 0101 -> 3.5x */ - 45, /* 0110 -> 4.5x */ - 95, /* 0111 -> 9.5x */ - 90, /* 1000 -> 9.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 60, /* 1011 -> 6.0x */ - 120, /* 1100 -> 12.0x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 65, /* 1111 -> 6.5x */ - - -1, /* 0000 -> RESERVED (9.0x) */ - 110, /* 0001 -> 11.0x */ - 120, /* 0010 -> 12.0x */ - -1, /* 0011 -> RESERVED (10.0x)*/ - 135, /* 0100 -> 13.5x */ - 115, /* 0101 -> 11.5x */ - 125, /* 0110 -> 12.5x */ - 105, /* 0111 -> 10.5x */ - 130, /* 1000 -> 13.0x */ - 150, /* 1001 -> 15.0x */ - 160, /* 1010 -> 16.0x */ - 140, /* 1011 -> 14.0x */ - -1, /* 1100 -> RESERVED (12.0x) */ - 155, /* 1101 -> 15.5x */ - -1, /* 1110 -> RESERVED (13.0x) */ - 145, /* 1111 -> 14.5x */ -}; - -/* - * VIA C3 Nehemiah */ - -static const int __cpuinitdata nehemiah_mults[32] = { - 100, /* 0000 -> 10.0x */ - -1, /* 0001 -> 16.0x */ - 40, /* 0010 -> 4.0x */ - 90, /* 0011 -> 9.0x */ - 95, /* 0100 -> 9.5x */ - -1, /* 0101 -> RESERVED */ - 45, /* 0110 -> 4.5x */ - 55, /* 0111 -> 5.5x */ - 60, /* 1000 -> 6.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 50, /* 1011 -> 5.0x */ - 65, /* 1100 -> 6.5x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 120, /* 1111 -> 12.0x */ - -1, /* 0000 -> 10.0x */ - 110, /* 0001 -> 11.0x */ - -1, /* 0010 -> 12.0x */ - -1, /* 0011 -> 9.0x */ - 105, /* 0100 -> 10.5x */ - 115, /* 0101 -> 11.5x */ - 125, /* 0110 -> 12.5x */ - 135, /* 0111 -> 13.5x */ - 140, /* 1000 -> 14.0x */ - 150, /* 1001 -> 15.0x */ - 160, /* 1010 -> 16.0x */ - 130, /* 1011 -> 13.0x */ - 145, /* 1100 -> 14.5x */ - 155, /* 1101 -> 15.5x */ - -1, /* 1110 -> RESERVED (13.0x) */ - -1, /* 1111 -> 12.0x */ -}; - -static const int __cpuinitdata nehemiah_eblcr[32] = { - 50, /* 0000 -> 5.0x */ - 160, /* 0001 -> 16.0x */ - 40, /* 0010 -> 4.0x */ - 100, /* 0011 -> 10.0x */ - 55, /* 0100 -> 5.5x */ - -1, /* 0101 -> RESERVED */ - 45, /* 0110 -> 4.5x */ - 95, /* 0111 -> 9.5x */ - 90, /* 1000 -> 9.0x */ - 70, /* 1001 -> 7.0x */ - 80, /* 1010 -> 8.0x */ - 60, /* 1011 -> 6.0x */ - 120, /* 1100 -> 12.0x */ - 75, /* 1101 -> 7.5x */ - 85, /* 1110 -> 8.5x */ - 65, /* 1111 -> 6.5x */ - 90, /* 0000 -> 9.0x */ - 110, /* 0001 -> 11.0x */ - 120, /* 0010 -> 12.0x */ - 100, /* 0011 -> 10.0x */ - 135, /* 0100 -> 13.5x */ - 115, /* 0101 -> 11.5x */ - 125, /* 0110 -> 12.5x */ - 105, /* 0111 -> 10.5x */ - 130, /* 1000 -> 13.0x */ - 150, /* 1001 -> 15.0x */ - 160, /* 1010 -> 16.0x */ - 140, /* 1011 -> 14.0x */ - 120, /* 1100 -> 12.0x */ - 155, /* 1101 -> 15.5x */ - -1, /* 1110 -> RESERVED (13.0x) */ - 145 /* 1111 -> 14.5x */ -}; - -/* - * Voltage scales. Div/Mod by 1000 to get actual voltage. - * Which scale to use depends on the VRM type in use. - */ - -struct mV_pos { - unsigned short mV; - unsigned short pos; -}; - -static const struct mV_pos __cpuinitdata vrm85_mV[32] = { - {1250, 8}, {1200, 6}, {1150, 4}, {1100, 2}, - {1050, 0}, {1800, 30}, {1750, 28}, {1700, 26}, - {1650, 24}, {1600, 22}, {1550, 20}, {1500, 18}, - {1450, 16}, {1400, 14}, {1350, 12}, {1300, 10}, - {1275, 9}, {1225, 7}, {1175, 5}, {1125, 3}, - {1075, 1}, {1825, 31}, {1775, 29}, {1725, 27}, - {1675, 25}, {1625, 23}, {1575, 21}, {1525, 19}, - {1475, 17}, {1425, 15}, {1375, 13}, {1325, 11} -}; - -static const unsigned char __cpuinitdata mV_vrm85[32] = { - 0x04, 0x14, 0x03, 0x13, 0x02, 0x12, 0x01, 0x11, - 0x00, 0x10, 0x0f, 0x1f, 0x0e, 0x1e, 0x0d, 0x1d, - 0x0c, 0x1c, 0x0b, 0x1b, 0x0a, 0x1a, 0x09, 0x19, - 0x08, 0x18, 0x07, 0x17, 0x06, 0x16, 0x05, 0x15 -}; - -static const struct mV_pos __cpuinitdata mobilevrm_mV[32] = { - {1750, 31}, {1700, 30}, {1650, 29}, {1600, 28}, - {1550, 27}, {1500, 26}, {1450, 25}, {1400, 24}, - {1350, 23}, {1300, 22}, {1250, 21}, {1200, 20}, - {1150, 19}, {1100, 18}, {1050, 17}, {1000, 16}, - {975, 15}, {950, 14}, {925, 13}, {900, 12}, - {875, 11}, {850, 10}, {825, 9}, {800, 8}, - {775, 7}, {750, 6}, {725, 5}, {700, 4}, - {675, 3}, {650, 2}, {625, 1}, {600, 0} -}; - -static const unsigned char __cpuinitdata mV_mobilevrm[32] = { - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, - 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 -}; - diff --git a/linux-3.4/drivers/cpufreq.new/longrun.c b/linux-3.4/drivers/cpufreq.new/longrun.c deleted file mode 100644 index 8bc9f5fb..00000000 --- a/linux-3.4/drivers/cpufreq.new/longrun.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * (C) 2002 - 2003 Dominik Brodowski - * - * Licensed under the terms of the GNU GPL License version 2. - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -static struct cpufreq_driver longrun_driver; - -/** - * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz - * values into per cent values. In TMTA microcode, the following is valid: - * performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) - */ -static unsigned int longrun_low_freq, longrun_high_freq; - - -/** - * longrun_get_policy - get the current LongRun policy - * @policy: struct cpufreq_policy where current policy is written into - * - * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS - * and MSR_TMTA_LONGRUN_CTRL - */ -static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy) -{ - u32 msr_lo, msr_hi; - - rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); - pr_debug("longrun flags are %x - %x\n", msr_lo, msr_hi); - if (msr_lo & 0x01) - policy->policy = CPUFREQ_POLICY_PERFORMANCE; - else - policy->policy = CPUFREQ_POLICY_POWERSAVE; - - rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - pr_debug("longrun ctrl is %x - %x\n", msr_lo, msr_hi); - msr_lo &= 0x0000007F; - msr_hi &= 0x0000007F; - - if (longrun_high_freq <= longrun_low_freq) { - /* Assume degenerate Longrun table */ - policy->min = policy->max = longrun_high_freq; - } else { - policy->min = longrun_low_freq + msr_lo * - ((longrun_high_freq - longrun_low_freq) / 100); - policy->max = longrun_low_freq + msr_hi * - ((longrun_high_freq - longrun_low_freq) / 100); - } - policy->cpu = 0; -} - - -/** - * longrun_set_policy - sets a new CPUFreq policy - * @policy: new policy - * - * Sets a new CPUFreq policy on LongRun-capable processors. This function - * has to be called with cpufreq_driver locked. - */ -static int longrun_set_policy(struct cpufreq_policy *policy) -{ - u32 msr_lo, msr_hi; - u32 pctg_lo, pctg_hi; - - if (!policy) - return -EINVAL; - - if (longrun_high_freq <= longrun_low_freq) { - /* Assume degenerate Longrun table */ - pctg_lo = pctg_hi = 100; - } else { - pctg_lo = (policy->min - longrun_low_freq) / - ((longrun_high_freq - longrun_low_freq) / 100); - pctg_hi = (policy->max - longrun_low_freq) / - ((longrun_high_freq - longrun_low_freq) / 100); - } - - if (pctg_hi > 100) - pctg_hi = 100; - if (pctg_lo > pctg_hi) - pctg_lo = pctg_hi; - - /* performance or economy mode */ - rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); - msr_lo &= 0xFFFFFFFE; - switch (policy->policy) { - case CPUFREQ_POLICY_PERFORMANCE: - msr_lo |= 0x00000001; - break; - case CPUFREQ_POLICY_POWERSAVE: - break; - } - wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi); - - /* lower and upper boundary */ - rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - msr_lo &= 0xFFFFFF80; - msr_hi &= 0xFFFFFF80; - msr_lo |= pctg_lo; - msr_hi |= pctg_hi; - wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - - return 0; -} - - -/** - * longrun_verify_poliy - verifies a new CPUFreq policy - * @policy: the policy to verify - * - * Validates a new CPUFreq policy. This function has to be called with - * cpufreq_driver locked. - */ -static int longrun_verify_policy(struct cpufreq_policy *policy) -{ - if (!policy) - return -EINVAL; - - policy->cpu = 0; - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - - if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && - (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) - return -EINVAL; - - return 0; -} - -static unsigned int longrun_get(unsigned int cpu) -{ - u32 eax, ebx, ecx, edx; - - if (cpu) - return 0; - - cpuid(0x80860007, &eax, &ebx, &ecx, &edx); - pr_debug("cpuid eax is %u\n", eax); - - return eax * 1000; -} - -/** - * longrun_determine_freqs - determines the lowest and highest possible core frequency - * @low_freq: an int to put the lowest frequency into - * @high_freq: an int to put the highest frequency into - * - * Determines the lowest and highest possible core frequencies on this CPU. - * This is necessary to calculate the performance percentage according to - * TMTA rules: - * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq) - */ -static int __cpuinit longrun_determine_freqs(unsigned int *low_freq, - unsigned int *high_freq) -{ - u32 msr_lo, msr_hi; - u32 save_lo, save_hi; - u32 eax, ebx, ecx, edx; - u32 try_hi; - struct cpuinfo_x86 *c = &cpu_data(0); - - if (!low_freq || !high_freq) - return -EINVAL; - - if (cpu_has(c, X86_FEATURE_LRTI)) { - /* if the LongRun Table Interface is present, the - * detection is a bit easier: - * For minimum frequency, read out the maximum - * level (msr_hi), write that into "currently - * selected level", and read out the frequency. - * For maximum frequency, read out level zero. - */ - /* minimum */ - rdmsr(MSR_TMTA_LRTI_READOUT, msr_lo, msr_hi); - wrmsr(MSR_TMTA_LRTI_READOUT, msr_hi, msr_hi); - rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); - *low_freq = msr_lo * 1000; /* to kHz */ - - /* maximum */ - wrmsr(MSR_TMTA_LRTI_READOUT, 0, msr_hi); - rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi); - *high_freq = msr_lo * 1000; /* to kHz */ - - pr_debug("longrun table interface told %u - %u kHz\n", - *low_freq, *high_freq); - - if (*low_freq > *high_freq) - *low_freq = *high_freq; - return 0; - } - - /* set the upper border to the value determined during TSC init */ - *high_freq = (cpu_khz / 1000); - *high_freq = *high_freq * 1000; - pr_debug("high frequency is %u kHz\n", *high_freq); - - /* get current borders */ - rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - save_lo = msr_lo & 0x0000007F; - save_hi = msr_hi & 0x0000007F; - - /* if current perf_pctg is larger than 90%, we need to decrease the - * upper limit to make the calculation more accurate. - */ - cpuid(0x80860007, &eax, &ebx, &ecx, &edx); - /* try decreasing in 10% steps, some processors react only - * on some barrier values */ - for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) { - /* set to 0 to try_hi perf_pctg */ - msr_lo &= 0xFFFFFF80; - msr_hi &= 0xFFFFFF80; - msr_hi |= try_hi; - wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); - - /* read out current core MHz and current perf_pctg */ - cpuid(0x80860007, &eax, &ebx, &ecx, &edx); - - /* restore values */ - wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi); - } - pr_debug("percentage is %u %%, freq is %u MHz\n", ecx, eax); - - /* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq) - * eqals - * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg) - * - * high_freq * perf_pctg is stored tempoarily into "ebx". - */ - ebx = (((cpu_khz / 1000) * ecx) / 100); /* to MHz */ - - if ((ecx > 95) || (ecx == 0) || (eax < ebx)) - return -EIO; - - edx = ((eax - ebx) * 100) / (100 - ecx); - *low_freq = edx * 1000; /* back to kHz */ - - pr_debug("low frequency is %u kHz\n", *low_freq); - - if (*low_freq > *high_freq) - *low_freq = *high_freq; - - return 0; -} - - -static int __cpuinit longrun_cpu_init(struct cpufreq_policy *policy) -{ - int result = 0; - - /* capability check */ - if (policy->cpu != 0) - return -ENODEV; - - /* detect low and high frequency */ - result = longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq); - if (result) - return result; - - /* cpuinfo and default policy values */ - policy->cpuinfo.min_freq = longrun_low_freq; - policy->cpuinfo.max_freq = longrun_high_freq; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - longrun_get_policy(policy); - - return 0; -} - - -static struct cpufreq_driver longrun_driver = { - .flags = CPUFREQ_CONST_LOOPS, - .verify = longrun_verify_policy, - .setpolicy = longrun_set_policy, - .get = longrun_get, - .init = longrun_cpu_init, - .name = "longrun", - .owner = THIS_MODULE, -}; - -static const struct x86_cpu_id longrun_ids[] = { - { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY, - X86_FEATURE_LONGRUN }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, longrun_ids); - -/** - * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver - * - * Initializes the LongRun support. - */ -static int __init longrun_init(void) -{ - if (!x86_match_cpu(longrun_ids)) - return -ENODEV; - return cpufreq_register_driver(&longrun_driver); -} - - -/** - * longrun_exit - unregisters LongRun support - */ -static void __exit longrun_exit(void) -{ - cpufreq_unregister_driver(&longrun_driver); -} - - -MODULE_AUTHOR("Dominik Brodowski "); -MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and " - "Efficeon processors."); -MODULE_LICENSE("GPL"); - -module_init(longrun_init); -module_exit(longrun_exit); diff --git a/linux-3.4/drivers/cpufreq.new/maple-cpufreq.c b/linux-3.4/drivers/cpufreq.new/maple-cpufreq.c deleted file mode 100644 index 89b178a3..00000000 --- a/linux-3.4/drivers/cpufreq.new/maple-cpufreq.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2011 Dmitry Eremin-Solenikov - * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt - * and Markus Demleitner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This driver adds basic cpufreq support for SMU & 970FX based G5 Macs, - * that is iMac G5 and latest single CPU desktop. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DBG(fmt...) pr_debug(fmt) - -/* see 970FX user manual */ - -#define SCOM_PCR 0x0aa001 /* PCR scom addr */ - -#define PCR_HILO_SELECT 0x80000000U /* 1 = PCR, 0 = PCRH */ -#define PCR_SPEED_FULL 0x00000000U /* 1:1 speed value */ -#define PCR_SPEED_HALF 0x00020000U /* 1:2 speed value */ -#define PCR_SPEED_QUARTER 0x00040000U /* 1:4 speed value */ -#define PCR_SPEED_MASK 0x000e0000U /* speed mask */ -#define PCR_SPEED_SHIFT 17 -#define PCR_FREQ_REQ_VALID 0x00010000U /* freq request valid */ -#define PCR_VOLT_REQ_VALID 0x00008000U /* volt request valid */ -#define PCR_TARGET_TIME_MASK 0x00006000U /* target time */ -#define PCR_STATLAT_MASK 0x00001f00U /* STATLAT value */ -#define PCR_SNOOPLAT_MASK 0x000000f0U /* SNOOPLAT value */ -#define PCR_SNOOPACC_MASK 0x0000000fU /* SNOOPACC value */ - -#define SCOM_PSR 0x408001 /* PSR scom addr */ -/* warning: PSR is a 64 bits register */ -#define PSR_CMD_RECEIVED 0x2000000000000000U /* command received */ -#define PSR_CMD_COMPLETED 0x1000000000000000U /* command completed */ -#define PSR_CUR_SPEED_MASK 0x0300000000000000U /* current speed */ -#define PSR_CUR_SPEED_SHIFT (56) - -/* - * The G5 only supports two frequencies (Quarter speed is not supported) - */ -#define CPUFREQ_HIGH 0 -#define CPUFREQ_LOW 1 - -static struct cpufreq_frequency_table maple_cpu_freqs[] = { - {CPUFREQ_HIGH, 0}, - {CPUFREQ_LOW, 0}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct freq_attr *maple_cpu_freqs_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -/* Power mode data is an array of the 32 bits PCR values to use for - * the various frequencies, retrieved from the device-tree - */ -static int maple_pmode_cur; - -static DEFINE_MUTEX(maple_switch_mutex); - -static const u32 *maple_pmode_data; -static int maple_pmode_max; - -/* - * SCOM based frequency switching for 970FX rev3 - */ -static int maple_scom_switch_freq(int speed_mode) -{ - unsigned long flags; - int to; - - local_irq_save(flags); - - /* Clear PCR high */ - scom970_write(SCOM_PCR, 0); - /* Clear PCR low */ - scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0); - /* Set PCR low */ - scom970_write(SCOM_PCR, PCR_HILO_SELECT | - maple_pmode_data[speed_mode]); - - /* Wait for completion */ - for (to = 0; to < 10; to++) { - unsigned long psr = scom970_read(SCOM_PSR); - - if ((psr & PSR_CMD_RECEIVED) == 0 && - (((psr >> PSR_CUR_SPEED_SHIFT) ^ - (maple_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3) - == 0) - break; - if (psr & PSR_CMD_COMPLETED) - break; - udelay(100); - } - - local_irq_restore(flags); - - maple_pmode_cur = speed_mode; - ppc_proc_freq = maple_cpu_freqs[speed_mode].frequency * 1000ul; - - return 0; -} - -static int maple_scom_query_freq(void) -{ - unsigned long psr = scom970_read(SCOM_PSR); - int i; - - for (i = 0; i <= maple_pmode_max; i++) - if ((((psr >> PSR_CUR_SPEED_SHIFT) ^ - (maple_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0) - break; - return i; -} - -/* - * Common interface to the cpufreq core - */ - -static int maple_cpufreq_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, maple_cpu_freqs); -} - -static int maple_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned int newstate = 0; - struct cpufreq_freqs freqs; - int rc; - - if (cpufreq_frequency_table_target(policy, maple_cpu_freqs, - target_freq, relation, &newstate)) - return -EINVAL; - - if (maple_pmode_cur == newstate) - return 0; - - mutex_lock(&maple_switch_mutex); - - freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency; - freqs.new = maple_cpu_freqs[newstate].frequency; - freqs.cpu = 0; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - rc = maple_scom_switch_freq(newstate); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - mutex_unlock(&maple_switch_mutex); - - return rc; -} - -static unsigned int maple_cpufreq_get_speed(unsigned int cpu) -{ - return maple_cpu_freqs[maple_pmode_cur].frequency; -} - -static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - policy->cpuinfo.transition_latency = 12000; - policy->cur = maple_cpu_freqs[maple_scom_query_freq()].frequency; - /* secondary CPUs are tied to the primary one by the - * cpufreq core if in the secondary policy we tell it that - * it actually must be one policy together with all others. */ - cpumask_copy(policy->cpus, cpu_online_mask); - cpufreq_frequency_table_get_attr(maple_cpu_freqs, policy->cpu); - - return cpufreq_frequency_table_cpuinfo(policy, - maple_cpu_freqs); -} - - -static struct cpufreq_driver maple_cpufreq_driver = { - .name = "maple", - .owner = THIS_MODULE, - .flags = CPUFREQ_CONST_LOOPS, - .init = maple_cpufreq_cpu_init, - .verify = maple_cpufreq_verify, - .target = maple_cpufreq_target, - .get = maple_cpufreq_get_speed, - .attr = maple_cpu_freqs_attr, -}; - -static int __init maple_cpufreq_init(void) -{ - struct device_node *cpus; - struct device_node *cpunode; - unsigned int psize; - unsigned long max_freq; - const u32 *valp; - u32 pvr_hi; - int rc = -ENODEV; - - /* - * Behave here like powermac driver which checks machine compatibility - * to ease merging of two drivers in future. - */ - if (!of_machine_is_compatible("Momentum,Maple") && - !of_machine_is_compatible("Momentum,Apache")) - return 0; - - cpus = of_find_node_by_path("/cpus"); - if (cpus == NULL) { - DBG("No /cpus node !\n"); - return -ENODEV; - } - - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - const u32 *reg = of_get_property(cpunode, "reg", NULL); - if (reg == NULL || (*reg) != 0) - continue; - if (!strcmp(cpunode->type, "cpu")) - break; - } - if (cpunode == NULL) { - printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); - goto bail_cpus; - } - - /* Check 970FX for now */ - /* we actually don't care on which CPU to access PVR */ - pvr_hi = PVR_VER(mfspr(SPRN_PVR)); - if (pvr_hi != 0x3c && pvr_hi != 0x44) { - printk(KERN_ERR "cpufreq: Unsupported CPU version (%x)\n", - pvr_hi); - goto bail_noprops; - } - - /* Look for the powertune data in the device-tree */ - /* - * On Maple this property is provided by PIBS in dual-processor config, - * not provided by PIBS in CPU0 config and also not provided by SLOF, - * so YMMV - */ - maple_pmode_data = of_get_property(cpunode, "power-mode-data", &psize); - if (!maple_pmode_data) { - DBG("No power-mode-data !\n"); - goto bail_noprops; - } - maple_pmode_max = psize / sizeof(u32) - 1; - - /* - * From what I see, clock-frequency is always the maximal frequency. - * The current driver can not slew sysclk yet, so we really only deal - * with powertune steps for now. We also only implement full freq and - * half freq in this version. So far, I haven't yet seen a machine - * supporting anything else. - */ - valp = of_get_property(cpunode, "clock-frequency", NULL); - if (!valp) - return -ENODEV; - max_freq = (*valp)/1000; - maple_cpu_freqs[0].frequency = max_freq; - maple_cpu_freqs[1].frequency = max_freq/2; - - /* Force apply current frequency to make sure everything is in - * sync (voltage is right for example). Firmware may leave us with - * a strange setting ... - */ - msleep(10); - maple_pmode_cur = -1; - maple_scom_switch_freq(maple_scom_query_freq()); - - printk(KERN_INFO "Registering Maple CPU frequency driver\n"); - printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n", - maple_cpu_freqs[1].frequency/1000, - maple_cpu_freqs[0].frequency/1000, - maple_cpu_freqs[maple_pmode_cur].frequency/1000); - - rc = cpufreq_register_driver(&maple_cpufreq_driver); - - of_node_put(cpunode); - of_node_put(cpus); - - return rc; - -bail_noprops: - of_node_put(cpunode); -bail_cpus: - of_node_put(cpus); - - return rc; -} - -module_init(maple_cpufreq_init); - - -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/mperf.c b/linux-3.4/drivers/cpufreq.new/mperf.c deleted file mode 100644 index 911e1930..00000000 --- a/linux-3.4/drivers/cpufreq.new/mperf.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "mperf.h" - -static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf); - -/* Called via smp_call_function_single(), on the target CPU */ -static void read_measured_perf_ctrs(void *_cur) -{ - struct aperfmperf *am = _cur; - - get_aperfmperf(am); -} - -/* - * Return the measured active (C0) frequency on this CPU since last call - * to this function. - * Input: cpu number - * Return: Average CPU frequency in terms of max frequency (zero on error) - * - * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance - * over a period of time, while CPU is in C0 state. - * IA32_MPERF counts at the rate of max advertised frequency - * IA32_APERF counts at the rate of actual CPU frequency - * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and - * no meaning should be associated with absolute values of these MSRs. - */ -unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, - unsigned int cpu) -{ - struct aperfmperf perf; - unsigned long ratio; - unsigned int retval; - - if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) - return 0; - - ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf); - per_cpu(acfreq_old_perf, cpu) = perf; - - retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; - - return retval; -} -EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/mperf.h b/linux-3.4/drivers/cpufreq.new/mperf.h deleted file mode 100644 index 5dbf2950..00000000 --- a/linux-3.4/drivers/cpufreq.new/mperf.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * (c) 2010 Advanced Micro Devices, Inc. - * Your use of this code is subject to the terms and conditions of the - * GNU general public license version 2. See "COPYING" or - * http://www.gnu.org/licenses/gpl.html - */ - -unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, - unsigned int cpu); diff --git a/linux-3.4/drivers/cpufreq.new/omap-cpufreq.c b/linux-3.4/drivers/cpufreq.new/omap-cpufreq.c deleted file mode 100644 index 17fa04d0..00000000 --- a/linux-3.4/drivers/cpufreq.new/omap-cpufreq.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * CPU frequency scaling for OMAP using OPP information - * - * Copyright (C) 2005 Nokia Corporation - * Written by Tony Lindgren - * - * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King - * - * Copyright (C) 2007-2011 Texas Instruments, Inc. - * - OMAP3/4 support by Rajendra Nayak, Santosh Shilimkar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -/* OPP tolerance in percentage */ -#define OPP_TOLERANCE 4 - -#ifdef CONFIG_SMP -struct lpj_info { - unsigned long ref; - unsigned int freq; -}; - -static DEFINE_PER_CPU(struct lpj_info, lpj_ref); -static struct lpj_info global_lpj_ref; -#endif - -static struct cpufreq_frequency_table *freq_table; -static atomic_t freq_table_users = ATOMIC_INIT(0); -static struct clk *mpu_clk; -static char *mpu_clk_name; -static struct device *mpu_dev; -static struct regulator *mpu_reg; - -static int omap_verify_speed(struct cpufreq_policy *policy) -{ - if (!freq_table) - return -EINVAL; - return cpufreq_frequency_table_verify(policy, freq_table); -} - -static unsigned int omap_getspeed(unsigned int cpu) -{ - unsigned long rate; - - if (cpu >= NR_CPUS) - return 0; - - rate = clk_get_rate(mpu_clk) / 1000; - return rate; -} - -static int omap_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int i; - int r, ret = 0; - struct cpufreq_freqs freqs; - struct opp *opp; - unsigned long freq, volt = 0, volt_old = 0, tol = 0; - - if (!freq_table) { - dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__, - policy->cpu); - return -EINVAL; - } - - ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, - relation, &i); - if (ret) { - dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n", - __func__, policy->cpu, target_freq, ret); - return ret; - } - freqs.new = freq_table[i].frequency; - if (!freqs.new) { - dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__, - policy->cpu, target_freq); - return -EINVAL; - } - - freqs.old = omap_getspeed(policy->cpu); - freqs.cpu = policy->cpu; - - if (freqs.old == freqs.new && policy->cur == freqs.new) - return ret; - - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - freq = freqs.new * 1000; - - if (mpu_reg) { - opp = opp_find_freq_ceil(mpu_dev, &freq); - if (IS_ERR(opp)) { - dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", - __func__, freqs.new); - return -EINVAL; - } - volt = opp_get_voltage(opp); - tol = volt * OPP_TOLERANCE / 100; - volt_old = regulator_get_voltage(mpu_reg); - } - - dev_dbg(mpu_dev, "cpufreq-omap: %u MHz, %ld mV --> %u MHz, %ld mV\n", - freqs.old / 1000, volt_old ? volt_old / 1000 : -1, - freqs.new / 1000, volt ? volt / 1000 : -1); - - /* scaling up? scale voltage before frequency */ - if (mpu_reg && (freqs.new > freqs.old)) { - r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); - if (r < 0) { - dev_warn(mpu_dev, "%s: unable to scale voltage up.\n", - __func__); - freqs.new = freqs.old; - goto done; - } - } - - ret = clk_set_rate(mpu_clk, freqs.new * 1000); - - /* scaling down? scale voltage after frequency */ - if (mpu_reg && (freqs.new < freqs.old)) { - r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); - if (r < 0) { - dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", - __func__); - ret = clk_set_rate(mpu_clk, freqs.old * 1000); - freqs.new = freqs.old; - goto done; - } - } - - freqs.new = omap_getspeed(policy->cpu); -#ifdef CONFIG_SMP - /* - * Note that loops_per_jiffy is not updated on SMP systems in - * cpufreq driver. So, update the per-CPU loops_per_jiffy value - * on frequency transition. We need to update all dependent CPUs. - */ - for_each_cpu(i, policy->cpus) { - struct lpj_info *lpj = &per_cpu(lpj_ref, i); - if (!lpj->freq) { - lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy; - lpj->freq = freqs.old; - } - - per_cpu(cpu_data, i).loops_per_jiffy = - cpufreq_scale(lpj->ref, lpj->freq, freqs.new); - } - - /* And don't forget to adjust the global one */ - if (!global_lpj_ref.freq) { - global_lpj_ref.ref = loops_per_jiffy; - global_lpj_ref.freq = freqs.old; - } - loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq, - freqs.new); -#endif - -done: - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - - return ret; -} - -static inline void freq_table_free(void) -{ - if (atomic_dec_and_test(&freq_table_users)) - opp_free_cpufreq_table(mpu_dev, &freq_table); -} - -static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) -{ - int result = 0; - - mpu_clk = clk_get(NULL, mpu_clk_name); - if (IS_ERR(mpu_clk)) - return PTR_ERR(mpu_clk); - - if (policy->cpu >= NR_CPUS) { - result = -EINVAL; - goto fail_ck; - } - - policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); - - if (atomic_inc_return(&freq_table_users) == 1) - result = opp_init_cpufreq_table(mpu_dev, &freq_table); - - if (result) { - dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", - __func__, policy->cpu, result); - goto fail_ck; - } - - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); - if (result) - goto fail_table; - - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); - - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; - policy->cur = omap_getspeed(policy->cpu); - - /* - * On OMAP SMP configuartion, both processors share the voltage - * and clock. So both CPUs needs to be scaled together and hence - * needs software co-ordination. Use cpufreq affected_cpus - * interface to handle this scenario. Additional is_smp() check - * is to keep SMP_ON_UP build working. - */ - if (is_smp()) { - policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; - cpumask_setall(policy->cpus); - } - - /* FIXME: what's the actual transition time? */ - policy->cpuinfo.transition_latency = 300 * 1000; - - return 0; - -fail_table: - freq_table_free(); -fail_ck: - clk_put(mpu_clk); - return result; -} - -static int omap_cpu_exit(struct cpufreq_policy *policy) -{ - freq_table_free(); - clk_put(mpu_clk); - return 0; -} - -static struct freq_attr *omap_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver omap_driver = { - .flags = CPUFREQ_STICKY, - .verify = omap_verify_speed, - .target = omap_target, - .get = omap_getspeed, - .init = omap_cpu_init, - .exit = omap_cpu_exit, - .name = "omap", - .attr = omap_cpufreq_attr, -}; - -static int __init omap_cpufreq_init(void) -{ - if (cpu_is_omap24xx()) - mpu_clk_name = "virt_prcm_set"; - else if (cpu_is_omap34xx()) - mpu_clk_name = "dpll1_ck"; - else if (cpu_is_omap44xx()) - mpu_clk_name = "dpll_mpu_ck"; - - if (!mpu_clk_name) { - pr_err("%s: unsupported Silicon?\n", __func__); - return -EINVAL; - } - - mpu_dev = omap_device_get_by_hwmod_name("mpu"); - if (!mpu_dev) { - pr_warning("%s: unable to get the mpu device\n", __func__); - return -EINVAL; - } - - mpu_reg = regulator_get(mpu_dev, "vcc"); - if (IS_ERR(mpu_reg)) { - pr_warning("%s: unable to get MPU regulator\n", __func__); - mpu_reg = NULL; - } else { - /* - * Ensure physical regulator is present. - * (e.g. could be dummy regulator.) - */ - if (regulator_get_voltage(mpu_reg) < 0) { - pr_warn("%s: physical regulator not present for MPU\n", - __func__); - regulator_put(mpu_reg); - mpu_reg = NULL; - } - } - - return cpufreq_register_driver(&omap_driver); -} - -static void __exit omap_cpufreq_exit(void) -{ - cpufreq_unregister_driver(&omap_driver); -} - -MODULE_DESCRIPTION("cpufreq driver for OMAP SoCs"); -MODULE_LICENSE("GPL"); -module_init(omap_cpufreq_init); -module_exit(omap_cpufreq_exit); diff --git a/linux-3.4/drivers/cpufreq.new/p4-clockmod.c b/linux-3.4/drivers/cpufreq.new/p4-clockmod.c deleted file mode 100644 index 827629c9..00000000 --- a/linux-3.4/drivers/cpufreq.new/p4-clockmod.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Pentium 4/Xeon CPU on demand clock modulation/speed scaling - * (C) 2002 - 2003 Dominik Brodowski - * (C) 2002 Zwane Mwaikambo - * (C) 2002 Arjan van de Ven - * (C) 2002 Tora T. Engstad - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * The author(s) of this software shall not be held liable for damages - * of any nature resulting due to the use of this software. This - * software is provided AS-IS with no warranties. - * - * Date Errata Description - * 20020525 N44, O17 12.5% or 25% DC causes lockup - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "speedstep-lib.h" - -#define PFX "p4-clockmod: " - -/* - * Duty Cycle (3bits), note DC_DISABLE is not specified in - * intel docs i just use it to mean disable - */ -enum { - DC_RESV, DC_DFLT, DC_25PT, DC_38PT, DC_50PT, - DC_64PT, DC_75PT, DC_88PT, DC_DISABLE -}; - -#define DC_ENTRIES 8 - - -static int has_N44_O17_errata[NR_CPUS]; -static unsigned int stock_freq; -static struct cpufreq_driver p4clockmod_driver; -static unsigned int cpufreq_p4_get(unsigned int cpu); - -static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) -{ - u32 l, h; - - if (!cpu_online(cpu) || - (newstate > DC_DISABLE) || (newstate == DC_RESV)) - return -EINVAL; - - rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); - - if (l & 0x01) - pr_debug("CPU#%d currently thermal throttled\n", cpu); - - if (has_N44_O17_errata[cpu] && - (newstate == DC_25PT || newstate == DC_DFLT)) - newstate = DC_38PT; - - rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); - if (newstate == DC_DISABLE) { - pr_debug("CPU#%d disabling modulation\n", cpu); - wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); - } else { - pr_debug("CPU#%d setting duty cycle to %d%%\n", - cpu, ((125 * newstate) / 10)); - /* bits 63 - 5 : reserved - * bit 4 : enable/disable - * bits 3-1 : duty cycle - * bit 0 : reserved - */ - l = (l & ~14); - l = l | (1<<4) | ((newstate & 0x7)<<1); - wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h); - } - - return 0; -} - - -static struct cpufreq_frequency_table p4clockmod_table[] = { - {DC_RESV, CPUFREQ_ENTRY_INVALID}, - {DC_DFLT, 0}, - {DC_25PT, 0}, - {DC_38PT, 0}, - {DC_50PT, 0}, - {DC_64PT, 0}, - {DC_75PT, 0}, - {DC_88PT, 0}, - {DC_DISABLE, 0}, - {DC_RESV, CPUFREQ_TABLE_END}, -}; - - -static int cpufreq_p4_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = DC_RESV; - struct cpufreq_freqs freqs; - int i; - - if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], - target_freq, relation, &newstate)) - return -EINVAL; - - freqs.old = cpufreq_p4_get(policy->cpu); - freqs.new = stock_freq * p4clockmod_table[newstate].index / 8; - - if (freqs.new == freqs.old) - return 0; - - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - /* run on each logical CPU, - * see section 13.15.3 of IA32 Intel Architecture Software - * Developer's Manual, Volume 3 - */ - for_each_cpu(i, policy->cpus) - cpufreq_p4_setdc(i, p4clockmod_table[newstate].index); - - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - - return 0; -} - - -static int cpufreq_p4_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]); -} - - -static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) -{ - if (c->x86 == 0x06) { - if (cpu_has(c, X86_FEATURE_EST)) - printk_once(KERN_WARNING PFX "Warning: EST-capable " - "CPU detected. The acpi-cpufreq module offers " - "voltage scaling in addition to frequency " - "scaling. You should use that instead of " - "p4-clockmod, if possible.\n"); - switch (c->x86_model) { - case 0x0E: /* Core */ - case 0x0F: /* Core Duo */ - case 0x16: /* Celeron Core */ - case 0x1C: /* Atom */ - p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; - return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE); - case 0x0D: /* Pentium M (Dothan) */ - p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; - /* fall through */ - case 0x09: /* Pentium M (Banias) */ - return speedstep_get_frequency(SPEEDSTEP_CPU_PM); - } - } - - if (c->x86 != 0xF) - return 0; - - /* on P-4s, the TSC runs with constant frequency independent whether - * throttling is active or not. */ - p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; - - if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) { - printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. " - "The speedstep-ich or acpi cpufreq modules offer " - "voltage scaling in addition of frequency scaling. " - "You should use either one instead of p4-clockmod, " - "if possible.\n"); - return speedstep_get_frequency(SPEEDSTEP_CPU_P4M); - } - - return speedstep_get_frequency(SPEEDSTEP_CPU_P4D); -} - - - -static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *c = &cpu_data(policy->cpu); - int cpuid = 0; - unsigned int i; - -#ifdef CONFIG_SMP - cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); -#endif - - /* Errata workaround */ - cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask; - switch (cpuid) { - case 0x0f07: - case 0x0f0a: - case 0x0f11: - case 0x0f12: - has_N44_O17_errata[policy->cpu] = 1; - pr_debug("has errata -- disabling low frequencies\n"); - } - - if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D && - c->x86_model < 2) { - /* switch to maximum frequency and measure result */ - cpufreq_p4_setdc(policy->cpu, DC_DISABLE); - recalibrate_cpu_khz(); - } - /* get max frequency */ - stock_freq = cpufreq_p4_get_frequency(c); - if (!stock_freq) - return -EINVAL; - - /* table init */ - for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { - if ((i < 2) && (has_N44_O17_errata[policy->cpu])) - p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; - else - p4clockmod_table[i].frequency = (stock_freq * i)/8; - } - cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); - - /* cpuinfo and default policy values */ - - /* the transition latency is set to be 1 higher than the maximum - * transition latency of the ondemand governor */ - policy->cpuinfo.transition_latency = 10000001; - policy->cur = stock_freq; - - return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]); -} - - -static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - -static unsigned int cpufreq_p4_get(unsigned int cpu) -{ - u32 l, h; - - rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); - - if (l & 0x10) { - l = l >> 1; - l &= 0x7; - } else - l = DC_DISABLE; - - if (l != DC_DISABLE) - return stock_freq * l / 8; - - return stock_freq; -} - -static struct freq_attr *p4clockmod_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver p4clockmod_driver = { - .verify = cpufreq_p4_verify, - .target = cpufreq_p4_target, - .init = cpufreq_p4_cpu_init, - .exit = cpufreq_p4_cpu_exit, - .get = cpufreq_p4_get, - .name = "p4-clockmod", - .owner = THIS_MODULE, - .attr = p4clockmod_attr, -}; - -static const struct x86_cpu_id cpufreq_p4_id[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC }, - {} -}; - -/* - * Intentionally no MODULE_DEVICE_TABLE here: this driver should not - * be auto loaded. Please don't add one. - */ - -static int __init cpufreq_p4_init(void) -{ - int ret; - - /* - * THERM_CONTROL is architectural for IA32 now, so - * we can rely on the capability checks - */ - if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI)) - return -ENODEV; - - ret = cpufreq_register_driver(&p4clockmod_driver); - if (!ret) - printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock " - "Modulation available\n"); - - return ret; -} - - -static void __exit cpufreq_p4_exit(void) -{ - cpufreq_unregister_driver(&p4clockmod_driver); -} - - -MODULE_AUTHOR("Zwane Mwaikambo "); -MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)"); -MODULE_LICENSE("GPL"); - -late_initcall(cpufreq_p4_init); -module_exit(cpufreq_p4_exit); diff --git a/linux-3.4/drivers/cpufreq.new/pcc-cpufreq.c b/linux-3.4/drivers/cpufreq.new/pcc-cpufreq.c deleted file mode 100644 index cdc02ac8..00000000 --- a/linux-3.4/drivers/cpufreq.new/pcc-cpufreq.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface - * - * Copyright (C) 2009 Red Hat, Matthew Garrett - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * Nagananda Chumbalkar - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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, GOOD TITLE or NON - * INFRINGEMENT. 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define PCC_VERSION "1.10.00" -#define POLL_LOOPS 300 - -#define CMD_COMPLETE 0x1 -#define CMD_GET_FREQ 0x0 -#define CMD_SET_FREQ 0x1 - -#define BUF_SZ 4 - -struct pcc_register_resource { - u8 descriptor; - u16 length; - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 access_size; - u64 address; -} __attribute__ ((packed)); - -struct pcc_memory_resource { - u8 descriptor; - u16 length; - u8 space_id; - u8 resource_usage; - u8 type_specific; - u64 granularity; - u64 minimum; - u64 maximum; - u64 translation_offset; - u64 address_length; -} __attribute__ ((packed)); - -static struct cpufreq_driver pcc_cpufreq_driver; - -struct pcc_header { - u32 signature; - u16 length; - u8 major; - u8 minor; - u32 features; - u16 command; - u16 status; - u32 latency; - u32 minimum_time; - u32 maximum_time; - u32 nominal; - u32 throttled_frequency; - u32 minimum_frequency; -}; - -static void __iomem *pcch_virt_addr; -static struct pcc_header __iomem *pcch_hdr; - -static DEFINE_SPINLOCK(pcc_lock); - -static struct acpi_generic_address doorbell; - -static u64 doorbell_preserve; -static u64 doorbell_write; - -static u8 OSC_UUID[16] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49, - 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46}; - -struct pcc_cpu { - u32 input_offset; - u32 output_offset; -}; - -static struct pcc_cpu __percpu *pcc_cpu_info; - -static int pcc_cpufreq_verify(struct cpufreq_policy *policy) -{ - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, - policy->cpuinfo.max_freq); - return 0; -} - -static inline void pcc_cmd(void) -{ - u64 doorbell_value; - int i; - - acpi_read(&doorbell_value, &doorbell); - acpi_write((doorbell_value & doorbell_preserve) | doorbell_write, - &doorbell); - - for (i = 0; i < POLL_LOOPS; i++) { - if (ioread16(&pcch_hdr->status) & CMD_COMPLETE) - break; - } -} - -static inline void pcc_clear_mapping(void) -{ - if (pcch_virt_addr) - iounmap(pcch_virt_addr); - pcch_virt_addr = NULL; -} - -static unsigned int pcc_get_freq(unsigned int cpu) -{ - struct pcc_cpu *pcc_cpu_data; - unsigned int curr_freq; - unsigned int freq_limit; - u16 status; - u32 input_buffer; - u32 output_buffer; - - spin_lock(&pcc_lock); - - pr_debug("get: get_freq for CPU %d\n", cpu); - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - input_buffer = 0x1; - iowrite32(input_buffer, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - iowrite16(CMD_GET_FREQ, &pcch_hdr->command); - - pcc_cmd(); - - output_buffer = - ioread32(pcch_virt_addr + pcc_cpu_data->output_offset); - - /* Clear the input buffer - we are done with the current command */ - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - - status = ioread16(&pcch_hdr->status); - if (status != CMD_COMPLETE) { - pr_debug("get: FAILED: for CPU %d, status is %d\n", - cpu, status); - goto cmd_incomplete; - } - iowrite16(0, &pcch_hdr->status); - curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff)) - / 100) * 1000); - - pr_debug("get: SUCCESS: (virtual) output_offset for cpu %d is " - "0x%p, contains a value of: 0x%x. Speed is: %d MHz\n", - cpu, (pcch_virt_addr + pcc_cpu_data->output_offset), - output_buffer, curr_freq); - - freq_limit = (output_buffer >> 8) & 0xff; - if (freq_limit != 0xff) { - pr_debug("get: frequency for cpu %d is being temporarily" - " capped at %d\n", cpu, curr_freq); - } - - spin_unlock(&pcc_lock); - return curr_freq; - -cmd_incomplete: - iowrite16(0, &pcch_hdr->status); - spin_unlock(&pcc_lock); - return 0; -} - -static int pcc_cpufreq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct pcc_cpu *pcc_cpu_data; - struct cpufreq_freqs freqs; - u16 status; - u32 input_buffer; - int cpu; - - spin_lock(&pcc_lock); - cpu = policy->cpu; - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - pr_debug("target: CPU %d should go to target freq: %d " - "(virtual) input_offset is 0x%p\n", - cpu, target_freq, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - - freqs.new = target_freq; - freqs.cpu = cpu; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - input_buffer = 0x1 | (((target_freq * 100) - / (ioread32(&pcch_hdr->nominal) * 1000)) << 8); - iowrite32(input_buffer, - (pcch_virt_addr + pcc_cpu_data->input_offset)); - iowrite16(CMD_SET_FREQ, &pcch_hdr->command); - - pcc_cmd(); - - /* Clear the input buffer - we are done with the current command */ - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - - status = ioread16(&pcch_hdr->status); - if (status != CMD_COMPLETE) { - pr_debug("target: FAILED for cpu %d, with status: 0x%x\n", - cpu, status); - goto cmd_incomplete; - } - iowrite16(0, &pcch_hdr->status); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu); - spin_unlock(&pcc_lock); - - return 0; - -cmd_incomplete: - iowrite16(0, &pcch_hdr->status); - spin_unlock(&pcc_lock); - return -EINVAL; -} - -static int pcc_get_offset(int cpu) -{ - acpi_status status; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *pccp, *offset; - struct pcc_cpu *pcc_cpu_data; - struct acpi_processor *pr; - int ret = 0; - - pr = per_cpu(processors, cpu); - pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); - - if (!pr) - return -ENODEV; - - status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer); - if (ACPI_FAILURE(status)) - return -ENODEV; - - pccp = buffer.pointer; - if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) { - ret = -ENODEV; - goto out_free; - }; - - offset = &(pccp->package.elements[0]); - if (!offset || offset->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto out_free; - } - - pcc_cpu_data->input_offset = offset->integer.value; - - offset = &(pccp->package.elements[1]); - if (!offset || offset->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto out_free; - } - - pcc_cpu_data->output_offset = offset->integer.value; - - memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); - memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ); - - pr_debug("pcc_get_offset: for CPU %d: pcc_cpu_data " - "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n", - cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset); -out_free: - kfree(buffer.pointer); - return ret; -} - -static int __init pcc_cpufreq_do_osc(acpi_handle *handle) -{ - acpi_status status; - struct acpi_object_list input; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object in_params[4]; - union acpi_object *out_obj; - u32 capabilities[2]; - u32 errors; - u32 supported; - int ret = 0; - - input.count = 4; - input.pointer = in_params; - in_params[0].type = ACPI_TYPE_BUFFER; - in_params[0].buffer.length = 16; - in_params[0].buffer.pointer = OSC_UUID; - in_params[1].type = ACPI_TYPE_INTEGER; - in_params[1].integer.value = 1; - in_params[2].type = ACPI_TYPE_INTEGER; - in_params[2].integer.value = 2; - in_params[3].type = ACPI_TYPE_BUFFER; - in_params[3].buffer.length = 8; - in_params[3].buffer.pointer = (u8 *)&capabilities; - - capabilities[0] = OSC_QUERY_ENABLE; - capabilities[1] = 0x1; - - status = acpi_evaluate_object(*handle, "_OSC", &input, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - if (!output.length) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) { - ret = -ENODEV; - goto out_free; - } - - supported = *((u32 *)(out_obj->buffer.pointer + 4)); - if (!(supported & 0x1)) { - ret = -ENODEV; - goto out_free; - } - - kfree(output.pointer); - capabilities[0] = 0x0; - capabilities[1] = 0x1; - - status = acpi_evaluate_object(*handle, "_OSC", &input, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - if (!output.length) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) { - ret = -ENODEV; - goto out_free; - } - - supported = *((u32 *)(out_obj->buffer.pointer + 4)); - if (!(supported & 0x1)) { - ret = -ENODEV; - goto out_free; - } - -out_free: - kfree(output.pointer); - return ret; -} - -static int __init pcc_cpufreq_probe(void) -{ - acpi_status status; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - struct pcc_memory_resource *mem_resource; - struct pcc_register_resource *reg_resource; - union acpi_object *out_obj, *member; - acpi_handle handle, osc_handle, pcch_handle; - int ret = 0; - - status = acpi_get_handle(NULL, "\\_SB", &handle); - if (ACPI_FAILURE(status)) - return -ENODEV; - - status = acpi_get_handle(handle, "PCCH", &pcch_handle); - if (ACPI_FAILURE(status)) - return -ENODEV; - - status = acpi_get_handle(handle, "_OSC", &osc_handle); - if (ACPI_SUCCESS(status)) { - ret = pcc_cpufreq_do_osc(&osc_handle); - if (ret) - pr_debug("probe: _OSC evaluation did not succeed\n"); - /* Firmware's use of _OSC is optional */ - ret = 0; - } - - status = acpi_evaluate_object(handle, "PCCH", NULL, &output); - if (ACPI_FAILURE(status)) - return -ENODEV; - - out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_PACKAGE) { - ret = -ENODEV; - goto out_free; - } - - member = &out_obj->package.elements[0]; - if (member->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto out_free; - } - - mem_resource = (struct pcc_memory_resource *)member->buffer.pointer; - - pr_debug("probe: mem_resource descriptor: 0x%x," - " length: %d, space_id: %d, resource_usage: %d," - " type_specific: %d, granularity: 0x%llx," - " minimum: 0x%llx, maximum: 0x%llx," - " translation_offset: 0x%llx, address_length: 0x%llx\n", - mem_resource->descriptor, mem_resource->length, - mem_resource->space_id, mem_resource->resource_usage, - mem_resource->type_specific, mem_resource->granularity, - mem_resource->minimum, mem_resource->maximum, - mem_resource->translation_offset, - mem_resource->address_length); - - if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { - ret = -ENODEV; - goto out_free; - } - - pcch_virt_addr = ioremap_nocache(mem_resource->minimum, - mem_resource->address_length); - if (pcch_virt_addr == NULL) { - pr_debug("probe: could not map shared mem region\n"); - goto out_free; - } - pcch_hdr = pcch_virt_addr; - - pr_debug("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr); - pr_debug("probe: PCCH header is at physical address: 0x%llx," - " signature: 0x%x, length: %d bytes, major: %d, minor: %d," - " supported features: 0x%x, command field: 0x%x," - " status field: 0x%x, nominal latency: %d us\n", - mem_resource->minimum, ioread32(&pcch_hdr->signature), - ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major), - ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features), - ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status), - ioread32(&pcch_hdr->latency)); - - pr_debug("probe: min time between commands: %d us," - " max time between commands: %d us," - " nominal CPU frequency: %d MHz," - " minimum CPU frequency: %d MHz," - " minimum CPU frequency without throttling: %d MHz\n", - ioread32(&pcch_hdr->minimum_time), - ioread32(&pcch_hdr->maximum_time), - ioread32(&pcch_hdr->nominal), - ioread32(&pcch_hdr->throttled_frequency), - ioread32(&pcch_hdr->minimum_frequency)); - - member = &out_obj->package.elements[1]; - if (member->type != ACPI_TYPE_BUFFER) { - ret = -ENODEV; - goto pcch_free; - } - - reg_resource = (struct pcc_register_resource *)member->buffer.pointer; - - doorbell.space_id = reg_resource->space_id; - doorbell.bit_width = reg_resource->bit_width; - doorbell.bit_offset = reg_resource->bit_offset; - doorbell.access_width = 64; - doorbell.address = reg_resource->address; - - pr_debug("probe: doorbell: space_id is %d, bit_width is %d, " - "bit_offset is %d, access_width is %d, address is 0x%llx\n", - doorbell.space_id, doorbell.bit_width, doorbell.bit_offset, - doorbell.access_width, reg_resource->address); - - member = &out_obj->package.elements[2]; - if (member->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto pcch_free; - } - - doorbell_preserve = member->integer.value; - - member = &out_obj->package.elements[3]; - if (member->type != ACPI_TYPE_INTEGER) { - ret = -ENODEV; - goto pcch_free; - } - - doorbell_write = member->integer.value; - - pr_debug("probe: doorbell_preserve: 0x%llx," - " doorbell_write: 0x%llx\n", - doorbell_preserve, doorbell_write); - - pcc_cpu_info = alloc_percpu(struct pcc_cpu); - if (!pcc_cpu_info) { - ret = -ENOMEM; - goto pcch_free; - } - - printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency" - " limits: %d MHz, %d MHz\n", PCC_VERSION, - ioread32(&pcch_hdr->minimum_frequency), - ioread32(&pcch_hdr->nominal)); - kfree(output.pointer); - return ret; -pcch_free: - pcc_clear_mapping(); -out_free: - kfree(output.pointer); - return ret; -} - -static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - unsigned int result = 0; - - if (!pcch_virt_addr) { - result = -1; - goto out; - } - - result = pcc_get_offset(cpu); - if (result) { - pr_debug("init: PCCP evaluation failed\n"); - goto out; - } - - policy->max = policy->cpuinfo.max_freq = - ioread32(&pcch_hdr->nominal) * 1000; - policy->min = policy->cpuinfo.min_freq = - ioread32(&pcch_hdr->minimum_frequency) * 1000; - policy->cur = pcc_get_freq(cpu); - - if (!policy->cur) { - pr_debug("init: Unable to get current CPU frequency\n"); - result = -EINVAL; - goto out; - } - - pr_debug("init: policy->max is %d, policy->min is %d\n", - policy->max, policy->min); -out: - return result; -} - -static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy) -{ - return 0; -} - -static struct cpufreq_driver pcc_cpufreq_driver = { - .flags = CPUFREQ_CONST_LOOPS, - .get = pcc_get_freq, - .verify = pcc_cpufreq_verify, - .target = pcc_cpufreq_target, - .init = pcc_cpufreq_cpu_init, - .exit = pcc_cpufreq_cpu_exit, - .name = "pcc-cpufreq", - .owner = THIS_MODULE, -}; - -static int __init pcc_cpufreq_init(void) -{ - int ret; - - if (acpi_disabled) - return 0; - - ret = pcc_cpufreq_probe(); - if (ret) { - pr_debug("pcc_cpufreq_init: PCCH evaluation failed\n"); - return ret; - } - - ret = cpufreq_register_driver(&pcc_cpufreq_driver); - - return ret; -} - -static void __exit pcc_cpufreq_exit(void) -{ - cpufreq_unregister_driver(&pcc_cpufreq_driver); - - pcc_clear_mapping(); - - free_percpu(pcc_cpu_info); -} - -MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); -MODULE_VERSION(PCC_VERSION); -MODULE_DESCRIPTION("Processor Clocking Control interface driver"); -MODULE_LICENSE("GPL"); - -late_initcall(pcc_cpufreq_init); -module_exit(pcc_cpufreq_exit); diff --git a/linux-3.4/drivers/cpufreq.new/powernow-k6.c b/linux-3.4/drivers/cpufreq.new/powernow-k6.c deleted file mode 100644 index af23e0b9..00000000 --- a/linux-3.4/drivers/cpufreq.new/powernow-k6.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * This file was based upon code in Powertweak Linux (http://powertweak.sf.net) - * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä, - * Dominik Brodowski. - * - * Licensed under the terms of the GNU GPL License version 2. - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long - as it is unused */ - -#define PFX "powernow-k6: " -static unsigned int busfreq; /* FSB, in 10 kHz */ -static unsigned int max_multiplier; - - -/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ -static struct cpufreq_frequency_table clock_ratio[] = { - {45, /* 000 -> 4.5x */ 0}, - {50, /* 001 -> 5.0x */ 0}, - {40, /* 010 -> 4.0x */ 0}, - {55, /* 011 -> 5.5x */ 0}, - {20, /* 100 -> 2.0x */ 0}, - {30, /* 101 -> 3.0x */ 0}, - {60, /* 110 -> 6.0x */ 0}, - {35, /* 111 -> 3.5x */ 0}, - {0, CPUFREQ_TABLE_END} -}; - - -/** - * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier - * - * Returns the current setting of the frequency multiplier. Core clock - * speed is frequency of the Front-Side Bus multiplied with this value. - */ -static int powernow_k6_get_cpu_multiplier(void) -{ - u64 invalue = 0; - u32 msrval; - - msrval = POWERNOW_IOPORT + 0x1; - wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ - invalue = inl(POWERNOW_IOPORT + 0x8); - msrval = POWERNOW_IOPORT + 0x0; - wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ - - return clock_ratio[(invalue >> 5)&7].index; -} - - -/** - * powernow_k6_set_state - set the PowerNow! multiplier - * @best_i: clock_ratio[best_i] is the target multiplier - * - * Tries to change the PowerNow! multiplier - */ -static void powernow_k6_set_state(unsigned int best_i) -{ - unsigned long outvalue = 0, invalue = 0; - unsigned long msrval; - struct cpufreq_freqs freqs; - - if (clock_ratio[best_i].index > max_multiplier) { - printk(KERN_ERR PFX "invalid target frequency\n"); - return; - } - - freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); - freqs.new = busfreq * clock_ratio[best_i].index; - freqs.cpu = 0; /* powernow-k6.c is UP only driver */ - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* we now need to transform best_i to the BVC format, see AMD#23446 */ - - outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5); - - msrval = POWERNOW_IOPORT + 0x1; - wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ - invalue = inl(POWERNOW_IOPORT + 0x8); - invalue = invalue & 0xf; - outvalue = outvalue | invalue; - outl(outvalue , (POWERNOW_IOPORT + 0x8)); - msrval = POWERNOW_IOPORT + 0x0; - wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return; -} - - -/** - * powernow_k6_verify - verifies a new CPUfreq policy - * @policy: new policy - * - * Policy must be within lowest and highest possible CPU Frequency, - * and at least one possible state must be within min and max. - */ -static int powernow_k6_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &clock_ratio[0]); -} - - -/** - * powernow_k6_setpolicy - sets a new CPUFreq policy - * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) - * - * sets a new CPUFreq policy - */ -static int powernow_k6_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, &clock_ratio[0], - target_freq, relation, &newstate)) - return -EINVAL; - - powernow_k6_set_state(newstate); - - return 0; -} - - -static int powernow_k6_cpu_init(struct cpufreq_policy *policy) -{ - unsigned int i, f; - int result; - - if (policy->cpu != 0) - return -ENODEV; - - /* get frequencies */ - max_multiplier = powernow_k6_get_cpu_multiplier(); - busfreq = cpu_khz / max_multiplier; - - /* table init */ - for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { - f = clock_ratio[i].index; - if (f > max_multiplier) - clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID; - else - clock_ratio[i].frequency = busfreq * f; - } - - /* cpuinfo and default policy values */ - policy->cpuinfo.transition_latency = 200000; - policy->cur = busfreq * max_multiplier; - - result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); - if (result) - return result; - - cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu); - - return 0; -} - - -static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) -{ - unsigned int i; - for (i = 0; i < 8; i++) { - if (i == max_multiplier) - powernow_k6_set_state(i); - } - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - -static unsigned int powernow_k6_get(unsigned int cpu) -{ - unsigned int ret; - ret = (busfreq * powernow_k6_get_cpu_multiplier()); - return ret; -} - -static struct freq_attr *powernow_k6_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver powernow_k6_driver = { - .verify = powernow_k6_verify, - .target = powernow_k6_target, - .init = powernow_k6_cpu_init, - .exit = powernow_k6_cpu_exit, - .get = powernow_k6_get, - .name = "powernow-k6", - .owner = THIS_MODULE, - .attr = powernow_k6_attr, -}; - -static const struct x86_cpu_id powernow_k6_ids[] = { - { X86_VENDOR_AMD, 5, 12 }, - { X86_VENDOR_AMD, 5, 13 }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, powernow_k6_ids); - -/** - * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver - * - * Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported - * devices, -EINVAL or -ENOMEM on problems during initiatization, and zero - * on success. - */ -static int __init powernow_k6_init(void) -{ - if (!x86_match_cpu(powernow_k6_ids)) - return -ENODEV; - - if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { - printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n"); - return -EIO; - } - - if (cpufreq_register_driver(&powernow_k6_driver)) { - release_region(POWERNOW_IOPORT, 16); - return -EINVAL; - } - - return 0; -} - - -/** - * powernow_k6_exit - unregisters AMD K6-2+/3+ PowerNow! support - * - * Unregisters AMD K6-2+ / K6-3+ PowerNow! support. - */ -static void __exit powernow_k6_exit(void) -{ - cpufreq_unregister_driver(&powernow_k6_driver); - release_region(POWERNOW_IOPORT, 16); -} - - -MODULE_AUTHOR("Arjan van de Ven, Dave Jones , " - "Dominik Brodowski "); -MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors."); -MODULE_LICENSE("GPL"); - -module_init(powernow_k6_init); -module_exit(powernow_k6_exit); diff --git a/linux-3.4/drivers/cpufreq.new/powernow-k7.c b/linux-3.4/drivers/cpufreq.new/powernow-k7.c deleted file mode 100644 index 334cc2f1..00000000 --- a/linux-3.4/drivers/cpufreq.new/powernow-k7.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - * AMD K7 Powernow driver. - * (C) 2003 Dave Jones on behalf of SuSE Labs. - * (C) 2003-2004 Dave Jones - * - * Licensed under the terms of the GNU GPL License version 2. - * Based upon datasheets & sample CPUs kindly provided by AMD. - * - * Errata 5: - * CPU may fail to execute a FID/VID change in presence of interrupt. - * - We cli/sti on stepping A0 CPUs around the FID/VID transition. - * Errata 15: - * CPU with half frequency multipliers may hang upon wakeup from disconnect. - * - We disable half multipliers if ACPI is used on A0 stepping CPUs. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* Needed for recalibrate_cpu_khz() */ -#include -#include - -#ifdef CONFIG_X86_POWERNOW_K7_ACPI -#include -#include -#endif - -#include "powernow-k7.h" - -#define PFX "powernow: " - - -struct psb_s { - u8 signature[10]; - u8 tableversion; - u8 flags; - u16 settlingtime; - u8 reserved1; - u8 numpst; -}; - -struct pst_s { - u32 cpuid; - u8 fsbspeed; - u8 maxfid; - u8 startvid; - u8 numpstates; -}; - -#ifdef CONFIG_X86_POWERNOW_K7_ACPI -union powernow_acpi_control_t { - struct { - unsigned long fid:5, - vid:5, - sgtc:20, - res1:2; - } bits; - unsigned long val; -}; -#endif - -/* divide by 1000 to get VCore voltage in V. */ -static const int mobile_vid_table[32] = { - 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, - 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, - 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, - 1075, 1050, 1025, 1000, 975, 950, 925, 0, -}; - -/* divide by 10 to get FID. */ -static const int fid_codes[32] = { - 110, 115, 120, 125, 50, 55, 60, 65, - 70, 75, 80, 85, 90, 95, 100, 105, - 30, 190, 40, 200, 130, 135, 140, 210, - 150, 225, 160, 165, 170, 180, -1, -1, -}; - -/* This parameter is used in order to force ACPI instead of legacy method for - * configuration purpose. - */ - -static int acpi_force; - -static struct cpufreq_frequency_table *powernow_table; - -static unsigned int can_scale_bus; -static unsigned int can_scale_vid; -static unsigned int minimum_speed = -1; -static unsigned int maximum_speed; -static unsigned int number_scales; -static unsigned int fsb; -static unsigned int latency; -static char have_a0; - -static int check_fsb(unsigned int fsbspeed) -{ - int delta; - unsigned int f = fsb / 1000; - - delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed; - return delta < 5; -} - -static const struct x86_cpu_id powernow_k7_cpuids[] = { - { X86_VENDOR_AMD, 6, }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids); - -static int check_powernow(void) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - unsigned int maxei, eax, ebx, ecx, edx; - - if (!x86_match_cpu(powernow_k7_cpuids)) - return 0; - - /* Get maximum capabilities */ - maxei = cpuid_eax(0x80000000); - if (maxei < 0x80000007) { /* Any powernow info ? */ -#ifdef MODULE - printk(KERN_INFO PFX "No powernow capabilities detected\n"); -#endif - return 0; - } - - if ((c->x86_model == 6) && (c->x86_mask == 0)) { - printk(KERN_INFO PFX "K7 660[A0] core detected, " - "enabling errata workarounds\n"); - have_a0 = 1; - } - - cpuid(0x80000007, &eax, &ebx, &ecx, &edx); - - /* Check we can actually do something before we say anything.*/ - if (!(edx & (1 << 1 | 1 << 2))) - return 0; - - printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); - - if (edx & 1 << 1) { - printk("frequency"); - can_scale_bus = 1; - } - - if ((edx & (1 << 1 | 1 << 2)) == 0x6) - printk(" and "); - - if (edx & 1 << 2) { - printk("voltage"); - can_scale_vid = 1; - } - - printk(".\n"); - return 1; -} - -#ifdef CONFIG_X86_POWERNOW_K7_ACPI -static void invalidate_entry(unsigned int entry) -{ - powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID; -} -#endif - -static int get_ranges(unsigned char *pst) -{ - unsigned int j; - unsigned int speed; - u8 fid, vid; - - powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * - (number_scales + 1)), GFP_KERNEL); - if (!powernow_table) - return -ENOMEM; - - for (j = 0 ; j < number_scales; j++) { - fid = *pst++; - - powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10; - powernow_table[j].index = fid; /* lower 8 bits */ - - speed = powernow_table[j].frequency; - - if ((fid_codes[fid] % 10) == 5) { -#ifdef CONFIG_X86_POWERNOW_K7_ACPI - if (have_a0 == 1) - invalidate_entry(j); -#endif - } - - if (speed < minimum_speed) - minimum_speed = speed; - if (speed > maximum_speed) - maximum_speed = speed; - - vid = *pst++; - powernow_table[j].index |= (vid << 8); /* upper 8 bits */ - - pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) " - "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, - fid_codes[fid] % 10, speed/1000, vid, - mobile_vid_table[vid]/1000, - mobile_vid_table[vid]%1000); - } - powernow_table[number_scales].frequency = CPUFREQ_TABLE_END; - powernow_table[number_scales].index = 0; - - return 0; -} - - -static void change_FID(int fid) -{ - union msr_fidvidctl fidvidctl; - - rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); - if (fidvidctl.bits.FID != fid) { - fidvidctl.bits.SGTC = latency; - fidvidctl.bits.FID = fid; - fidvidctl.bits.VIDC = 0; - fidvidctl.bits.FIDC = 1; - wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); - } -} - - -static void change_VID(int vid) -{ - union msr_fidvidctl fidvidctl; - - rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); - if (fidvidctl.bits.VID != vid) { - fidvidctl.bits.SGTC = latency; - fidvidctl.bits.VID = vid; - fidvidctl.bits.FIDC = 0; - fidvidctl.bits.VIDC = 1; - wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val); - } -} - - -static void change_speed(unsigned int index) -{ - u8 fid, vid; - struct cpufreq_freqs freqs; - union msr_fidvidstatus fidvidstatus; - int cfid; - - /* fid are the lower 8 bits of the index we stored into - * the cpufreq frequency table in powernow_decode_bios, - * vid are the upper 8 bits. - */ - - fid = powernow_table[index].index & 0xFF; - vid = (powernow_table[index].index & 0xFF00) >> 8; - - freqs.cpu = 0; - - rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); - cfid = fidvidstatus.bits.CFID; - freqs.old = fsb * fid_codes[cfid] / 10; - - freqs.new = powernow_table[index].frequency; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* Now do the magic poking into the MSRs. */ - - if (have_a0 == 1) /* A0 errata 5 */ - local_irq_disable(); - - if (freqs.old > freqs.new) { - /* Going down, so change FID first */ - change_FID(fid); - change_VID(vid); - } else { - /* Going up, so change VID first */ - change_VID(vid); - change_FID(fid); - } - - - if (have_a0 == 1) - local_irq_enable(); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -} - - -#ifdef CONFIG_X86_POWERNOW_K7_ACPI - -static struct acpi_processor_performance *acpi_processor_perf; - -static int powernow_acpi_init(void) -{ - int i; - int retval = 0; - union powernow_acpi_control_t pc; - - if (acpi_processor_perf != NULL && powernow_table != NULL) { - retval = -EINVAL; - goto err0; - } - - acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); - if (!acpi_processor_perf) { - retval = -ENOMEM; - goto err0; - } - - if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map, - GFP_KERNEL)) { - retval = -ENOMEM; - goto err05; - } - - if (acpi_processor_register_performance(acpi_processor_perf, 0)) { - retval = -EIO; - goto err1; - } - - if (acpi_processor_perf->control_register.space_id != - ACPI_ADR_SPACE_FIXED_HARDWARE) { - retval = -ENODEV; - goto err2; - } - - if (acpi_processor_perf->status_register.space_id != - ACPI_ADR_SPACE_FIXED_HARDWARE) { - retval = -ENODEV; - goto err2; - } - - number_scales = acpi_processor_perf->state_count; - - if (number_scales < 2) { - retval = -ENODEV; - goto err2; - } - - powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * - (number_scales + 1)), GFP_KERNEL); - if (!powernow_table) { - retval = -ENOMEM; - goto err2; - } - - pc.val = (unsigned long) acpi_processor_perf->states[0].control; - for (i = 0; i < number_scales; i++) { - u8 fid, vid; - struct acpi_processor_px *state = - &acpi_processor_perf->states[i]; - unsigned int speed, speed_mhz; - - pc.val = (unsigned long) state->control; - pr_debug("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", - i, - (u32) state->core_frequency, - (u32) state->power, - (u32) state->transition_latency, - (u32) state->control, - pc.bits.sgtc); - - vid = pc.bits.vid; - fid = pc.bits.fid; - - powernow_table[i].frequency = fsb * fid_codes[fid] / 10; - powernow_table[i].index = fid; /* lower 8 bits */ - powernow_table[i].index |= (vid << 8); /* upper 8 bits */ - - speed = powernow_table[i].frequency; - speed_mhz = speed / 1000; - - /* processor_perflib will multiply the MHz value by 1000 to - * get a KHz value (e.g. 1266000). However, powernow-k7 works - * with true KHz values (e.g. 1266768). To ensure that all - * powernow frequencies are available, we must ensure that - * ACPI doesn't restrict them, so we round up the MHz value - * to ensure that perflib's computed KHz value is greater than - * or equal to powernow's KHz value. - */ - if (speed % 1000 > 0) - speed_mhz++; - - if ((fid_codes[fid] % 10) == 5) { - if (have_a0 == 1) - invalidate_entry(i); - } - - pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) " - "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, - fid_codes[fid] % 10, speed_mhz, vid, - mobile_vid_table[vid]/1000, - mobile_vid_table[vid]%1000); - - if (state->core_frequency != speed_mhz) { - state->core_frequency = speed_mhz; - pr_debug(" Corrected ACPI frequency to %d\n", - speed_mhz); - } - - if (latency < pc.bits.sgtc) - latency = pc.bits.sgtc; - - if (speed < minimum_speed) - minimum_speed = speed; - if (speed > maximum_speed) - maximum_speed = speed; - } - - powernow_table[i].frequency = CPUFREQ_TABLE_END; - powernow_table[i].index = 0; - - /* notify BIOS that we exist */ - acpi_processor_notify_smm(THIS_MODULE); - - return 0; - -err2: - acpi_processor_unregister_performance(acpi_processor_perf, 0); -err1: - free_cpumask_var(acpi_processor_perf->shared_cpu_map); -err05: - kfree(acpi_processor_perf); -err0: - printk(KERN_WARNING PFX "ACPI perflib can not be used on " - "this platform\n"); - acpi_processor_perf = NULL; - return retval; -} -#else -static int powernow_acpi_init(void) -{ - printk(KERN_INFO PFX "no support for ACPI processor found." - " Please recompile your kernel with ACPI processor\n"); - return -EINVAL; -} -#endif - -static void print_pst_entry(struct pst_s *pst, unsigned int j) -{ - pr_debug("PST:%d (@%p)\n", j, pst); - pr_debug(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", - pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); -} - -static int powernow_decode_bios(int maxfid, int startvid) -{ - struct psb_s *psb; - struct pst_s *pst; - unsigned int i, j; - unsigned char *p; - unsigned int etuple; - unsigned int ret; - - etuple = cpuid_eax(0x80000001); - - for (i = 0xC0000; i < 0xffff0 ; i += 16) { - - p = phys_to_virt(i); - - if (memcmp(p, "AMDK7PNOW!", 10) == 0) { - pr_debug("Found PSB header at %p\n", p); - psb = (struct psb_s *) p; - pr_debug("Table version: 0x%x\n", psb->tableversion); - if (psb->tableversion != 0x12) { - printk(KERN_INFO PFX "Sorry, only v1.2 tables" - " supported right now\n"); - return -ENODEV; - } - - pr_debug("Flags: 0x%x\n", psb->flags); - if ((psb->flags & 1) == 0) - pr_debug("Mobile voltage regulator\n"); - else - pr_debug("Desktop voltage regulator\n"); - - latency = psb->settlingtime; - if (latency < 100) { - printk(KERN_INFO PFX "BIOS set settling time " - "to %d microseconds. " - "Should be at least 100. " - "Correcting.\n", latency); - latency = 100; - } - pr_debug("Settling Time: %d microseconds.\n", - psb->settlingtime); - pr_debug("Has %d PST tables. (Only dumping ones " - "relevant to this CPU).\n", - psb->numpst); - - p += sizeof(struct psb_s); - - pst = (struct pst_s *) p; - - for (j = 0; j < psb->numpst; j++) { - pst = (struct pst_s *) p; - number_scales = pst->numpstates; - - if ((etuple == pst->cpuid) && - check_fsb(pst->fsbspeed) && - (maxfid == pst->maxfid) && - (startvid == pst->startvid)) { - print_pst_entry(pst, j); - p = (char *)pst + sizeof(struct pst_s); - ret = get_ranges(p); - return ret; - } else { - unsigned int k; - p = (char *)pst + sizeof(struct pst_s); - for (k = 0; k < number_scales; k++) - p += 2; - } - } - printk(KERN_INFO PFX "No PST tables match this cpuid " - "(0x%x)\n", etuple); - printk(KERN_INFO PFX "This is indicative of a broken " - "BIOS.\n"); - - return -EINVAL; - } - p++; - } - - return -ENODEV; -} - - -static int powernow_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate; - - if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, - relation, &newstate)) - return -EINVAL; - - change_speed(newstate); - - return 0; -} - - -static int powernow_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, powernow_table); -} - -/* - * We use the fact that the bus frequency is somehow - * a multiple of 100000/3 khz, then we compute sgtc according - * to this multiple. - * That way, we match more how AMD thinks all of that work. - * We will then get the same kind of behaviour already tested under - * the "well-known" other OS. - */ -static int __cpuinit fixup_sgtc(void) -{ - unsigned int sgtc; - unsigned int m; - - m = fsb / 3333; - if ((m % 10) >= 5) - m += 5; - - m /= 10; - - sgtc = 100 * m * latency; - sgtc = sgtc / 3; - if (sgtc > 0xfffff) { - printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc); - sgtc = 0xfffff; - } - return sgtc; -} - -static unsigned int powernow_get(unsigned int cpu) -{ - union msr_fidvidstatus fidvidstatus; - unsigned int cfid; - - if (cpu) - return 0; - rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); - cfid = fidvidstatus.bits.CFID; - - return fsb * fid_codes[cfid] / 10; -} - - -static int __cpuinit acer_cpufreq_pst(const struct dmi_system_id *d) -{ - printk(KERN_WARNING PFX - "%s laptop with broken PST tables in BIOS detected.\n", - d->ident); - printk(KERN_WARNING PFX - "You need to downgrade to 3A21 (09/09/2002), or try a newer " - "BIOS than 3A71 (01/20/2003)\n"); - printk(KERN_WARNING PFX - "cpufreq scaling has been disabled as a result of this.\n"); - return 0; -} - -/* - * Some Athlon laptops have really fucked PST tables. - * A BIOS update is all that can save them. - * Mention this, and disable cpufreq. - */ -static struct dmi_system_id __cpuinitdata powernow_dmi_table[] = { - { - .callback = acer_cpufreq_pst, - .ident = "Acer Aspire", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"), - DMI_MATCH(DMI_BIOS_VERSION, "3A71"), - }, - }, - { } -}; - -static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy) -{ - union msr_fidvidstatus fidvidstatus; - int result; - - if (policy->cpu != 0) - return -ENODEV; - - rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val); - - recalibrate_cpu_khz(); - - fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; - if (!fsb) { - printk(KERN_WARNING PFX "can not determine bus frequency\n"); - return -EINVAL; - } - pr_debug("FSB: %3dMHz\n", fsb/1000); - - if (dmi_check_system(powernow_dmi_table) || acpi_force) { - printk(KERN_INFO PFX "PSB/PST known to be broken. " - "Trying ACPI instead\n"); - result = powernow_acpi_init(); - } else { - result = powernow_decode_bios(fidvidstatus.bits.MFID, - fidvidstatus.bits.SVID); - if (result) { - printk(KERN_INFO PFX "Trying ACPI perflib\n"); - maximum_speed = 0; - minimum_speed = -1; - latency = 0; - result = powernow_acpi_init(); - if (result) { - printk(KERN_INFO PFX - "ACPI and legacy methods failed\n"); - } - } else { - /* SGTC use the bus clock as timer */ - latency = fixup_sgtc(); - printk(KERN_INFO PFX "SGTC: %d\n", latency); - } - } - - if (result) - return result; - - printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", - minimum_speed/1000, maximum_speed/1000); - - policy->cpuinfo.transition_latency = - cpufreq_scale(2000000UL, fsb, latency); - - policy->cur = powernow_get(0); - - cpufreq_frequency_table_get_attr(powernow_table, policy->cpu); - - return cpufreq_frequency_table_cpuinfo(policy, powernow_table); -} - -static int powernow_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - -#ifdef CONFIG_X86_POWERNOW_K7_ACPI - if (acpi_processor_perf) { - acpi_processor_unregister_performance(acpi_processor_perf, 0); - free_cpumask_var(acpi_processor_perf->shared_cpu_map); - kfree(acpi_processor_perf); - } -#endif - - kfree(powernow_table); - return 0; -} - -static struct freq_attr *powernow_table_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver powernow_driver = { - .verify = powernow_verify, - .target = powernow_target, - .get = powernow_get, -#ifdef CONFIG_X86_POWERNOW_K7_ACPI - .bios_limit = acpi_processor_get_bios_limit, -#endif - .init = powernow_cpu_init, - .exit = powernow_cpu_exit, - .name = "powernow-k7", - .owner = THIS_MODULE, - .attr = powernow_table_attr, -}; - -static int __init powernow_init(void) -{ - if (check_powernow() == 0) - return -ENODEV; - return cpufreq_register_driver(&powernow_driver); -} - - -static void __exit powernow_exit(void) -{ - cpufreq_unregister_driver(&powernow_driver); -} - -module_param(acpi_force, int, 0444); -MODULE_PARM_DESC(acpi_force, "Force ACPI to be used."); - -MODULE_AUTHOR("Dave Jones "); -MODULE_DESCRIPTION("Powernow driver for AMD K7 processors."); -MODULE_LICENSE("GPL"); - -late_initcall(powernow_init); -module_exit(powernow_exit); - diff --git a/linux-3.4/drivers/cpufreq.new/powernow-k7.h b/linux-3.4/drivers/cpufreq.new/powernow-k7.h deleted file mode 100644 index 35fb4eaf..00000000 --- a/linux-3.4/drivers/cpufreq.new/powernow-k7.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * (C) 2003 Dave Jones. - * - * Licensed under the terms of the GNU GPL License version 2. - * - * AMD-specific information - * - */ - -union msr_fidvidctl { - struct { - unsigned FID:5, // 4:0 - reserved1:3, // 7:5 - VID:5, // 12:8 - reserved2:3, // 15:13 - FIDC:1, // 16 - VIDC:1, // 17 - reserved3:2, // 19:18 - FIDCHGRATIO:1, // 20 - reserved4:11, // 31-21 - SGTC:20, // 32:51 - reserved5:12; // 63:52 - } bits; - unsigned long long val; -}; - -union msr_fidvidstatus { - struct { - unsigned CFID:5, // 4:0 - reserved1:3, // 7:5 - SFID:5, // 12:8 - reserved2:3, // 15:13 - MFID:5, // 20:16 - reserved3:11, // 31:21 - CVID:5, // 36:32 - reserved4:3, // 39:37 - SVID:5, // 44:40 - reserved5:3, // 47:45 - MVID:5, // 52:48 - reserved6:11; // 63:53 - } bits; - unsigned long long val; -}; diff --git a/linux-3.4/drivers/cpufreq.new/powernow-k8.c b/linux-3.4/drivers/cpufreq.new/powernow-k8.c deleted file mode 100644 index c671369a..00000000 --- a/linux-3.4/drivers/cpufreq.new/powernow-k8.c +++ /dev/null @@ -1,1627 +0,0 @@ -/* - * (c) 2003-2012 Advanced Micro Devices, Inc. - * Your use of this code is subject to the terms and conditions of the - * GNU general public license version 2. See "COPYING" or - * http://www.gnu.org/licenses/gpl.html - * - * Maintainer: - * Andreas Herrmann - * - * Based on the powernow-k7.c module written by Dave Jones. - * (C) 2003 Dave Jones on behalf of SuSE Labs - * (C) 2004 Dominik Brodowski - * (C) 2004 Pavel Machek - * Licensed under the terms of the GNU GPL License version 2. - * Based upon datasheets & sample CPUs kindly provided by AMD. - * - * Valuable input gratefully received from Dave Jones, Pavel Machek, - * Dominik Brodowski, Jacob Shin, and others. - * Originally developed by Paul Devriendt. - * - * Processor information obtained from Chapter 9 (Power and Thermal - * Management) of the "BIOS and Kernel Developer's Guide (BKDG) for - * the AMD Athlon 64 and AMD Opteron Processors" and section "2.x - * Power Management" in BKDGs for newer AMD CPU families. - * - * Tables for specific CPUs can be inferred from AMD's processor - * power and thermal data sheets, (e.g. 30417.pdf, 30430.pdf, 43375.pdf) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define PFX "powernow-k8: " -#define VERSION "version 2.20.00" -#include "powernow-k8.h" -#include "mperf.h" - -/* serialize freq changes */ -static DEFINE_MUTEX(fidvid_mutex); - -static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data); - -static int cpu_family = CPU_OPTERON; - -/* array to map SW pstate number to acpi state */ -static u32 ps_to_as[8]; - -/* core performance boost */ -static bool cpb_capable, cpb_enabled; -static struct msr __percpu *msrs; - -static struct cpufreq_driver cpufreq_amd64_driver; - -#ifndef CONFIG_SMP -static inline const struct cpumask *cpu_core_mask(int cpu) -{ - return cpumask_of(0); -} -#endif - -/* Return a frequency in MHz, given an input fid */ -static u32 find_freq_from_fid(u32 fid) -{ - return 800 + (fid * 100); -} - -/* Return a frequency in KHz, given an input fid */ -static u32 find_khz_freq_from_fid(u32 fid) -{ - return 1000 * find_freq_from_fid(fid); -} - -static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, - u32 pstate) -{ - return data[ps_to_as[pstate]].frequency; -} - -/* Return the vco fid for an input fid - * - * Each "low" fid has corresponding "high" fid, and you can get to "low" fids - * only from corresponding high fids. This returns "high" fid corresponding to - * "low" one. - */ -static u32 convert_fid_to_vco_fid(u32 fid) -{ - if (fid < HI_FID_TABLE_BOTTOM) - return 8 + (2 * fid); - else - return fid; -} - -/* - * Return 1 if the pending bit is set. Unless we just instructed the processor - * to transition to a new state, seeing this bit set is really bad news. - */ -static int pending_bit_stuck(void) -{ - u32 lo, hi; - - if (cpu_family == CPU_HW_PSTATE) - return 0; - - rdmsr(MSR_FIDVID_STATUS, lo, hi); - return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0; -} - -/* - * Update the global current fid / vid values from the status msr. - * Returns 1 on error. - */ -static int query_current_values_with_pending_wait(struct powernow_k8_data *data) -{ - u32 lo, hi; - u32 i = 0; - - if (cpu_family == CPU_HW_PSTATE) { - rdmsr(MSR_PSTATE_STATUS, lo, hi); - i = lo & HW_PSTATE_MASK; - data->currpstate = i; - - /* - * a workaround for family 11h erratum 311 might cause - * an "out-of-range Pstate if the core is in Pstate-0 - */ - if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps)) - data->currpstate = HW_PSTATE_0; - - return 0; - } - do { - if (i++ > 10000) { - pr_debug("detected change pending stuck\n"); - return 1; - } - rdmsr(MSR_FIDVID_STATUS, lo, hi); - } while (lo & MSR_S_LO_CHANGE_PENDING); - - data->currvid = hi & MSR_S_HI_CURRENT_VID; - data->currfid = lo & MSR_S_LO_CURRENT_FID; - - return 0; -} - -/* the isochronous relief time */ -static void count_off_irt(struct powernow_k8_data *data) -{ - udelay((1 << data->irt) * 10); - return; -} - -/* the voltage stabilization time */ -static void count_off_vst(struct powernow_k8_data *data) -{ - udelay(data->vstable * VST_UNITS_20US); - return; -} - -/* need to init the control msr to a safe value (for each cpu) */ -static void fidvid_msr_init(void) -{ - u32 lo, hi; - u8 fid, vid; - - rdmsr(MSR_FIDVID_STATUS, lo, hi); - vid = hi & MSR_S_HI_CURRENT_VID; - fid = lo & MSR_S_LO_CURRENT_FID; - lo = fid | (vid << MSR_C_LO_VID_SHIFT); - hi = MSR_C_HI_STP_GNT_BENIGN; - pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi); - wrmsr(MSR_FIDVID_CTL, lo, hi); -} - -/* write the new fid value along with the other control fields to the msr */ -static int write_new_fid(struct powernow_k8_data *data, u32 fid) -{ - u32 lo; - u32 savevid = data->currvid; - u32 i = 0; - - if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) { - printk(KERN_ERR PFX "internal error - overflow on fid write\n"); - return 1; - } - - lo = fid; - lo |= (data->currvid << MSR_C_LO_VID_SHIFT); - lo |= MSR_C_LO_INIT_FID_VID; - - pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n", - fid, lo, data->plllock * PLL_LOCK_CONVERSION); - - do { - wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); - if (i++ > 100) { - printk(KERN_ERR PFX - "Hardware error - pending bit very stuck - " - "no further pstate changes possible\n"); - return 1; - } - } while (query_current_values_with_pending_wait(data)); - - count_off_irt(data); - - if (savevid != data->currvid) { - printk(KERN_ERR PFX - "vid change on fid trans, old 0x%x, new 0x%x\n", - savevid, data->currvid); - return 1; - } - - if (fid != data->currfid) { - printk(KERN_ERR PFX - "fid trans failed, fid 0x%x, curr 0x%x\n", fid, - data->currfid); - return 1; - } - - return 0; -} - -/* Write a new vid to the hardware */ -static int write_new_vid(struct powernow_k8_data *data, u32 vid) -{ - u32 lo; - u32 savefid = data->currfid; - int i = 0; - - if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) { - printk(KERN_ERR PFX "internal error - overflow on vid write\n"); - return 1; - } - - lo = data->currfid; - lo |= (vid << MSR_C_LO_VID_SHIFT); - lo |= MSR_C_LO_INIT_FID_VID; - - pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n", - vid, lo, STOP_GRANT_5NS); - - do { - wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); - if (i++ > 100) { - printk(KERN_ERR PFX "internal error - pending bit " - "very stuck - no further pstate " - "changes possible\n"); - return 1; - } - } while (query_current_values_with_pending_wait(data)); - - if (savefid != data->currfid) { - printk(KERN_ERR PFX "fid changed on vid trans, old " - "0x%x new 0x%x\n", - savefid, data->currfid); - return 1; - } - - if (vid != data->currvid) { - printk(KERN_ERR PFX "vid trans failed, vid 0x%x, " - "curr 0x%x\n", - vid, data->currvid); - return 1; - } - - return 0; -} - -/* - * Reduce the vid by the max of step or reqvid. - * Decreasing vid codes represent increasing voltages: - * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. - */ -static int decrease_vid_code_by_step(struct powernow_k8_data *data, - u32 reqvid, u32 step) -{ - if ((data->currvid - reqvid) > step) - reqvid = data->currvid - step; - - if (write_new_vid(data, reqvid)) - return 1; - - count_off_vst(data); - - return 0; -} - -/* Change hardware pstate by single MSR write */ -static int transition_pstate(struct powernow_k8_data *data, u32 pstate) -{ - wrmsr(MSR_PSTATE_CTRL, pstate, 0); - data->currpstate = pstate; - return 0; -} - -/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ -static int transition_fid_vid(struct powernow_k8_data *data, - u32 reqfid, u32 reqvid) -{ - if (core_voltage_pre_transition(data, reqvid, reqfid)) - return 1; - - if (core_frequency_transition(data, reqfid)) - return 1; - - if (core_voltage_post_transition(data, reqvid)) - return 1; - - if (query_current_values_with_pending_wait(data)) - return 1; - - if ((reqfid != data->currfid) || (reqvid != data->currvid)) { - printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, " - "curr 0x%x 0x%x\n", - smp_processor_id(), - reqfid, reqvid, data->currfid, data->currvid); - return 1; - } - - pr_debug("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n", - smp_processor_id(), data->currfid, data->currvid); - - return 0; -} - -/* Phase 1 - core voltage transition ... setup voltage */ -static int core_voltage_pre_transition(struct powernow_k8_data *data, - u32 reqvid, u32 reqfid) -{ - u32 rvosteps = data->rvo; - u32 savefid = data->currfid; - u32 maxvid, lo, rvomult = 1; - - pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " - "reqvid 0x%x, rvo 0x%x\n", - smp_processor_id(), - data->currfid, data->currvid, reqvid, data->rvo); - - if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP)) - rvomult = 2; - rvosteps *= rvomult; - rdmsr(MSR_FIDVID_STATUS, lo, maxvid); - maxvid = 0x1f & (maxvid >> 16); - pr_debug("ph1 maxvid=0x%x\n", maxvid); - if (reqvid < maxvid) /* lower numbers are higher voltages */ - reqvid = maxvid; - - while (data->currvid > reqvid) { - pr_debug("ph1: curr 0x%x, req vid 0x%x\n", - data->currvid, reqvid); - if (decrease_vid_code_by_step(data, reqvid, data->vidmvs)) - return 1; - } - - while ((rvosteps > 0) && - ((rvomult * data->rvo + data->currvid) > reqvid)) { - if (data->currvid == maxvid) { - rvosteps = 0; - } else { - pr_debug("ph1: changing vid for rvo, req 0x%x\n", - data->currvid - 1); - if (decrease_vid_code_by_step(data, data->currvid-1, 1)) - return 1; - rvosteps--; - } - } - - if (query_current_values_with_pending_wait(data)) - return 1; - - if (savefid != data->currfid) { - printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", - data->currfid); - return 1; - } - - pr_debug("ph1 complete, currfid 0x%x, currvid 0x%x\n", - data->currfid, data->currvid); - - return 0; -} - -/* Phase 2 - core frequency transition */ -static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) -{ - u32 vcoreqfid, vcocurrfid, vcofiddiff; - u32 fid_interval, savevid = data->currvid; - - if (data->currfid == reqfid) { - printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", - data->currfid); - return 0; - } - - pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " - "reqfid 0x%x\n", - smp_processor_id(), - data->currfid, data->currvid, reqfid); - - vcoreqfid = convert_fid_to_vco_fid(reqfid); - vcocurrfid = convert_fid_to_vco_fid(data->currfid); - vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid - : vcoreqfid - vcocurrfid; - - if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP)) - vcofiddiff = 0; - - while (vcofiddiff > 2) { - (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2); - - if (reqfid > data->currfid) { - if (data->currfid > LO_FID_TABLE_TOP) { - if (write_new_fid(data, - data->currfid + fid_interval)) - return 1; - } else { - if (write_new_fid - (data, - 2 + convert_fid_to_vco_fid(data->currfid))) - return 1; - } - } else { - if (write_new_fid(data, data->currfid - fid_interval)) - return 1; - } - - vcocurrfid = convert_fid_to_vco_fid(data->currfid); - vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid - : vcoreqfid - vcocurrfid; - } - - if (write_new_fid(data, reqfid)) - return 1; - - if (query_current_values_with_pending_wait(data)) - return 1; - - if (data->currfid != reqfid) { - printk(KERN_ERR PFX - "ph2: mismatch, failed fid transition, " - "curr 0x%x, req 0x%x\n", - data->currfid, reqfid); - return 1; - } - - if (savevid != data->currvid) { - printk(KERN_ERR PFX "ph2: vid changed, save 0x%x, curr 0x%x\n", - savevid, data->currvid); - return 1; - } - - pr_debug("ph2 complete, currfid 0x%x, currvid 0x%x\n", - data->currfid, data->currvid); - - return 0; -} - -/* Phase 3 - core voltage transition flow ... jump to the final vid. */ -static int core_voltage_post_transition(struct powernow_k8_data *data, - u32 reqvid) -{ - u32 savefid = data->currfid; - u32 savereqvid = reqvid; - - pr_debug("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n", - smp_processor_id(), - data->currfid, data->currvid); - - if (reqvid != data->currvid) { - if (write_new_vid(data, reqvid)) - return 1; - - if (savefid != data->currfid) { - printk(KERN_ERR PFX - "ph3: bad fid change, save 0x%x, curr 0x%x\n", - savefid, data->currfid); - return 1; - } - - if (data->currvid != reqvid) { - printk(KERN_ERR PFX - "ph3: failed vid transition\n, " - "req 0x%x, curr 0x%x", - reqvid, data->currvid); - return 1; - } - } - - if (query_current_values_with_pending_wait(data)) - return 1; - - if (savereqvid != data->currvid) { - pr_debug("ph3 failed, currvid 0x%x\n", data->currvid); - return 1; - } - - if (savefid != data->currfid) { - pr_debug("ph3 failed, currfid changed 0x%x\n", - data->currfid); - return 1; - } - - pr_debug("ph3 complete, currfid 0x%x, currvid 0x%x\n", - data->currfid, data->currvid); - - return 0; -} - -static const struct x86_cpu_id powernow_k8_ids[] = { - /* IO based frequency switching */ - { X86_VENDOR_AMD, 0xf }, - /* MSR based frequency switching supported */ - X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), - {} -}; -MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids); - -static void check_supported_cpu(void *_rc) -{ - u32 eax, ebx, ecx, edx; - int *rc = _rc; - - *rc = -ENODEV; - - eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - - if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { - if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || - ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { - printk(KERN_INFO PFX - "Processor cpuid %x not supported\n", eax); - return; - } - - eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); - if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { - printk(KERN_INFO PFX - "No frequency change capabilities detected\n"); - return; - } - - cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); - if ((edx & P_STATE_TRANSITION_CAPABLE) - != P_STATE_TRANSITION_CAPABLE) { - printk(KERN_INFO PFX - "Power state transitions not supported\n"); - return; - } - } else { /* must be a HW Pstate capable processor */ - cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); - if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE) - cpu_family = CPU_HW_PSTATE; - else - return; - } - - *rc = 0; -} - -static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, - u8 maxvid) -{ - unsigned int j; - u8 lastfid = 0xff; - - for (j = 0; j < data->numps; j++) { - if (pst[j].vid > LEAST_VID) { - printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n", - j, pst[j].vid); - return -EINVAL; - } - if (pst[j].vid < data->rvo) { - /* vid + rvo >= 0 */ - printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" - " %d\n", j); - return -ENODEV; - } - if (pst[j].vid < maxvid + data->rvo) { - /* vid + rvo >= maxvid */ - printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" - " %d\n", j); - return -ENODEV; - } - if (pst[j].fid > MAX_FID) { - printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate" - " %d\n", j); - return -ENODEV; - } - if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { - /* Only first fid is allowed to be in "low" range */ - printk(KERN_ERR FW_BUG PFX "two low fids - %d : " - "0x%x\n", j, pst[j].fid); - return -EINVAL; - } - if (pst[j].fid < lastfid) - lastfid = pst[j].fid; - } - if (lastfid & 1) { - printk(KERN_ERR FW_BUG PFX "lastfid invalid\n"); - return -EINVAL; - } - if (lastfid > LO_FID_TABLE_TOP) - printk(KERN_INFO FW_BUG PFX - "first fid not from lo freq table\n"); - - return 0; -} - -static void invalidate_entry(struct cpufreq_frequency_table *powernow_table, - unsigned int entry) -{ - powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID; -} - -static void print_basics(struct powernow_k8_data *data) -{ - int j; - for (j = 0; j < data->numps; j++) { - if (data->powernow_table[j].frequency != - CPUFREQ_ENTRY_INVALID) { - if (cpu_family == CPU_HW_PSTATE) { - printk(KERN_INFO PFX - " %d : pstate %d (%d MHz)\n", j, - data->powernow_table[j].index, - data->powernow_table[j].frequency/1000); - } else { - printk(KERN_INFO PFX - "fid 0x%x (%d MHz), vid 0x%x\n", - data->powernow_table[j].index & 0xff, - data->powernow_table[j].frequency/1000, - data->powernow_table[j].index >> 8); - } - } - } - if (data->batps) - printk(KERN_INFO PFX "Only %d pstates on battery\n", - data->batps); -} - -static u32 freq_from_fid_did(u32 fid, u32 did) -{ - u32 mhz = 0; - - if (boot_cpu_data.x86 == 0x10) - mhz = (100 * (fid + 0x10)) >> did; - else if (boot_cpu_data.x86 == 0x11) - mhz = (100 * (fid + 8)) >> did; - else - BUG(); - - return mhz * 1000; -} - -static int fill_powernow_table(struct powernow_k8_data *data, - struct pst_s *pst, u8 maxvid) -{ - struct cpufreq_frequency_table *powernow_table; - unsigned int j; - - if (data->batps) { - /* use ACPI support to get full speed on mains power */ - printk(KERN_WARNING PFX - "Only %d pstates usable (use ACPI driver for full " - "range\n", data->batps); - data->numps = data->batps; - } - - for (j = 1; j < data->numps; j++) { - if (pst[j-1].fid >= pst[j].fid) { - printk(KERN_ERR PFX "PST out of sequence\n"); - return -EINVAL; - } - } - - if (data->numps < 2) { - printk(KERN_ERR PFX "no p states to transition\n"); - return -ENODEV; - } - - if (check_pst_table(data, pst, maxvid)) - return -EINVAL; - - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) - * (data->numps + 1)), GFP_KERNEL); - if (!powernow_table) { - printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); - return -ENOMEM; - } - - for (j = 0; j < data->numps; j++) { - int freq; - powernow_table[j].index = pst[j].fid; /* lower 8 bits */ - powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ - freq = find_khz_freq_from_fid(pst[j].fid); - powernow_table[j].frequency = freq; - } - powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; - powernow_table[data->numps].index = 0; - - if (query_current_values_with_pending_wait(data)) { - kfree(powernow_table); - return -EIO; - } - - pr_debug("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); - data->powernow_table = powernow_table; - if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) - print_basics(data); - - for (j = 0; j < data->numps; j++) - if ((pst[j].fid == data->currfid) && - (pst[j].vid == data->currvid)) - return 0; - - pr_debug("currfid/vid do not match PST, ignoring\n"); - return 0; -} - -/* Find and validate the PSB/PST table in BIOS. */ -static int find_psb_table(struct powernow_k8_data *data) -{ - struct psb_s *psb; - unsigned int i; - u32 mvs; - u8 maxvid; - u32 cpst = 0; - u32 thiscpuid; - - for (i = 0xc0000; i < 0xffff0; i += 0x10) { - /* Scan BIOS looking for the signature. */ - /* It can not be at ffff0 - it is too big. */ - - psb = phys_to_virt(i); - if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0) - continue; - - pr_debug("found PSB header at 0x%p\n", psb); - - pr_debug("table vers: 0x%x\n", psb->tableversion); - if (psb->tableversion != PSB_VERSION_1_4) { - printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n"); - return -ENODEV; - } - - pr_debug("flags: 0x%x\n", psb->flags1); - if (psb->flags1) { - printk(KERN_ERR FW_BUG PFX "unknown flags\n"); - return -ENODEV; - } - - data->vstable = psb->vstable; - pr_debug("voltage stabilization time: %d(*20us)\n", - data->vstable); - - pr_debug("flags2: 0x%x\n", psb->flags2); - data->rvo = psb->flags2 & 3; - data->irt = ((psb->flags2) >> 2) & 3; - mvs = ((psb->flags2) >> 4) & 3; - data->vidmvs = 1 << mvs; - data->batps = ((psb->flags2) >> 6) & 3; - - pr_debug("ramp voltage offset: %d\n", data->rvo); - pr_debug("isochronous relief time: %d\n", data->irt); - pr_debug("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs); - - pr_debug("numpst: 0x%x\n", psb->num_tables); - cpst = psb->num_tables; - if ((psb->cpuid == 0x00000fc0) || - (psb->cpuid == 0x00000fe0)) { - thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - if ((thiscpuid == 0x00000fc0) || - (thiscpuid == 0x00000fe0)) - cpst = 1; - } - if (cpst != 1) { - printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); - return -ENODEV; - } - - data->plllock = psb->plllocktime; - pr_debug("plllocktime: 0x%x (units 1us)\n", psb->plllocktime); - pr_debug("maxfid: 0x%x\n", psb->maxfid); - pr_debug("maxvid: 0x%x\n", psb->maxvid); - maxvid = psb->maxvid; - - data->numps = psb->numps; - pr_debug("numpstates: 0x%x\n", data->numps); - return fill_powernow_table(data, - (struct pst_s *)(psb+1), maxvid); - } - /* - * If you see this message, complain to BIOS manufacturer. If - * he tells you "we do not support Linux" or some similar - * nonsense, remember that Windows 2000 uses the same legacy - * mechanism that the old Linux PSB driver uses. Tell them it - * is broken with Windows 2000. - * - * The reference to the AMD documentation is chapter 9 in the - * BIOS and Kernel Developer's Guide, which is available on - * www.amd.com - */ - printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n"); - printk(KERN_ERR PFX "Make sure that your BIOS is up to date" - " and Cool'N'Quiet support is enabled in BIOS setup\n"); - return -ENODEV; -} - -static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, - unsigned int index) -{ - u64 control; - - if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) - return; - - control = data->acpi_data.states[index].control; - data->irt = (control >> IRT_SHIFT) & IRT_MASK; - data->rvo = (control >> RVO_SHIFT) & RVO_MASK; - data->exttype = (control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; - data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; - data->vidmvs = 1 << ((control >> MVS_SHIFT) & MVS_MASK); - data->vstable = (control >> VST_SHIFT) & VST_MASK; -} - -static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) -{ - struct cpufreq_frequency_table *powernow_table; - int ret_val = -ENODEV; - u64 control, status; - - if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { - pr_debug("register performance failed: bad ACPI data\n"); - return -EIO; - } - - /* verify the data contained in the ACPI structures */ - if (data->acpi_data.state_count <= 1) { - pr_debug("No ACPI P-States\n"); - goto err_out; - } - - control = data->acpi_data.control_register.space_id; - status = data->acpi_data.status_register.space_id; - - if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) || - (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) { - pr_debug("Invalid control/status registers (%llx - %llx)\n", - control, status); - goto err_out; - } - - /* fill in data->powernow_table */ - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) - * (data->acpi_data.state_count + 1)), GFP_KERNEL); - if (!powernow_table) { - pr_debug("powernow_table memory alloc failure\n"); - goto err_out; - } - - /* fill in data */ - data->numps = data->acpi_data.state_count; - powernow_k8_acpi_pst_values(data, 0); - - if (cpu_family == CPU_HW_PSTATE) - ret_val = fill_powernow_table_pstate(data, powernow_table); - else - ret_val = fill_powernow_table_fidvid(data, powernow_table); - if (ret_val) - goto err_out_mem; - - powernow_table[data->acpi_data.state_count].frequency = - CPUFREQ_TABLE_END; - powernow_table[data->acpi_data.state_count].index = 0; - data->powernow_table = powernow_table; - - if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) - print_basics(data); - - /* notify BIOS that we exist */ - acpi_processor_notify_smm(THIS_MODULE); - - if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { - printk(KERN_ERR PFX - "unable to alloc powernow_k8_data cpumask\n"); - ret_val = -ENOMEM; - goto err_out_mem; - } - - return 0; - -err_out_mem: - kfree(powernow_table); - -err_out: - acpi_processor_unregister_performance(&data->acpi_data, data->cpu); - - /* data->acpi_data.state_count informs us at ->exit() - * whether ACPI was used */ - data->acpi_data.state_count = 0; - - return ret_val; -} - -static int fill_powernow_table_pstate(struct powernow_k8_data *data, - struct cpufreq_frequency_table *powernow_table) -{ - int i; - u32 hi = 0, lo = 0; - rdmsr(MSR_PSTATE_CUR_LIMIT, lo, hi); - data->max_hw_pstate = (lo & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT; - - for (i = 0; i < data->acpi_data.state_count; i++) { - u32 index; - - index = data->acpi_data.states[i].control & HW_PSTATE_MASK; - if (index > data->max_hw_pstate) { - printk(KERN_ERR PFX "invalid pstate %d - " - "bad value %d.\n", i, index); - printk(KERN_ERR PFX "Please report to BIOS " - "manufacturer\n"); - invalidate_entry(powernow_table, i); - continue; - } - - ps_to_as[index] = i; - - /* Frequency may be rounded for these */ - if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) - || boot_cpu_data.x86 == 0x11) { - - rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); - if (!(hi & HW_PSTATE_VALID_MASK)) { - pr_debug("invalid pstate %d, ignoring\n", index); - invalidate_entry(powernow_table, i); - continue; - } - - powernow_table[i].frequency = - freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); - } else - powernow_table[i].frequency = - data->acpi_data.states[i].core_frequency * 1000; - - powernow_table[i].index = index; - } - return 0; -} - -static int fill_powernow_table_fidvid(struct powernow_k8_data *data, - struct cpufreq_frequency_table *powernow_table) -{ - int i; - - for (i = 0; i < data->acpi_data.state_count; i++) { - u32 fid; - u32 vid; - u32 freq, index; - u64 status, control; - - if (data->exttype) { - status = data->acpi_data.states[i].status; - fid = status & EXT_FID_MASK; - vid = (status >> VID_SHIFT) & EXT_VID_MASK; - } else { - control = data->acpi_data.states[i].control; - fid = control & FID_MASK; - vid = (control >> VID_SHIFT) & VID_MASK; - } - - pr_debug(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); - - index = fid | (vid<<8); - powernow_table[i].index = index; - - freq = find_khz_freq_from_fid(fid); - powernow_table[i].frequency = freq; - - /* verify frequency is OK */ - if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) { - pr_debug("invalid freq %u kHz, ignoring\n", freq); - invalidate_entry(powernow_table, i); - continue; - } - - /* verify voltage is OK - - * BIOSs are using "off" to indicate invalid */ - if (vid == VID_OFF) { - pr_debug("invalid vid %u, ignoring\n", vid); - invalidate_entry(powernow_table, i); - continue; - } - - if (freq != (data->acpi_data.states[i].core_frequency * 1000)) { - printk(KERN_INFO PFX "invalid freq entries " - "%u kHz vs. %u kHz\n", freq, - (unsigned int) - (data->acpi_data.states[i].core_frequency - * 1000)); - invalidate_entry(powernow_table, i); - continue; - } - } - return 0; -} - -static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) -{ - if (data->acpi_data.state_count) - acpi_processor_unregister_performance(&data->acpi_data, - data->cpu); - free_cpumask_var(data->acpi_data.shared_cpu_map); -} - -static int get_transition_latency(struct powernow_k8_data *data) -{ - int max_latency = 0; - int i; - for (i = 0; i < data->acpi_data.state_count; i++) { - int cur_latency = data->acpi_data.states[i].transition_latency - + data->acpi_data.states[i].bus_master_latency; - if (cur_latency > max_latency) - max_latency = cur_latency; - } - if (max_latency == 0) { - /* - * Fam 11h and later may return 0 as transition latency. This - * is intended and means "very fast". While cpufreq core and - * governors currently can handle that gracefully, better set it - * to 1 to avoid problems in the future. - */ - if (boot_cpu_data.x86 < 0x11) - printk(KERN_ERR FW_WARN PFX "Invalid zero transition " - "latency\n"); - max_latency = 1; - } - /* value in usecs, needs to be in nanoseconds */ - return 1000 * max_latency; -} - -/* Take a frequency, and issue the fid/vid transition command */ -static int transition_frequency_fidvid(struct powernow_k8_data *data, - unsigned int index) -{ - u32 fid = 0; - u32 vid = 0; - int res, i; - struct cpufreq_freqs freqs; - - pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); - - /* fid/vid correctness check for k8 */ - /* fid are the lower 8 bits of the index we stored into - * the cpufreq frequency table in find_psb_table, vid - * are the upper 8 bits. - */ - fid = data->powernow_table[index].index & 0xFF; - vid = (data->powernow_table[index].index & 0xFF00) >> 8; - - pr_debug("table matched fid 0x%x, giving vid 0x%x\n", fid, vid); - - if (query_current_values_with_pending_wait(data)) - return 1; - - if ((data->currvid == vid) && (data->currfid == fid)) { - pr_debug("target matches current values (fid 0x%x, vid 0x%x)\n", - fid, vid); - return 0; - } - - pr_debug("cpu %d, changing to fid 0x%x, vid 0x%x\n", - smp_processor_id(), fid, vid); - freqs.old = find_khz_freq_from_fid(data->currfid); - freqs.new = find_khz_freq_from_fid(fid); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - res = transition_fid_vid(data, fid, vid); - if (res) - return res; - - freqs.new = find_khz_freq_from_fid(data->currfid); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - return res; -} - -/* Take a frequency, and issue the hardware pstate transition command */ -static int transition_frequency_pstate(struct powernow_k8_data *data, - unsigned int index) -{ - u32 pstate = 0; - int res, i; - struct cpufreq_freqs freqs; - - pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); - - /* get MSR index for hardware pstate transition */ - pstate = index & HW_PSTATE_MASK; - if (pstate > data->max_hw_pstate) - return -EINVAL; - - freqs.old = find_khz_freq_from_pstate(data->powernow_table, - data->currpstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - res = transition_pstate(data, pstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - return res; -} - -struct powernowk8_target_arg { - struct cpufreq_policy *pol; - unsigned targfreq; - unsigned relation; -}; - -static long powernowk8_target_fn(void *arg) -{ - struct powernowk8_target_arg *pta = arg; - struct cpufreq_policy *pol = pta->pol; - unsigned targfreq = pta->targfreq; - unsigned relation = pta->relation; - struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); - u32 checkfid; - u32 checkvid; - unsigned int newstate; - int ret; - - if (!data) - return -EINVAL; - - checkfid = data->currfid; - checkvid = data->currvid; - - if (pending_bit_stuck()) { - printk(KERN_ERR PFX "failing targ, change pending bit set\n"); - return -EIO; - } - - pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", - pol->cpu, targfreq, pol->min, pol->max, relation); - - if (query_current_values_with_pending_wait(data)) - return -EIO; - - if (cpu_family != CPU_HW_PSTATE) { - pr_debug("targ: curr fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); - - if ((checkvid != data->currvid) || - (checkfid != data->currfid)) { - printk(KERN_INFO PFX - "error - out of sync, fix 0x%x 0x%x, " - "vid 0x%x 0x%x\n", - checkfid, data->currfid, - checkvid, data->currvid); - } - } - - if (cpufreq_frequency_table_target(pol, data->powernow_table, - targfreq, relation, &newstate)) - return -EIO; - - mutex_lock(&fidvid_mutex); - - powernow_k8_acpi_pst_values(data, newstate); - - if (cpu_family == CPU_HW_PSTATE) - ret = transition_frequency_pstate(data, - data->powernow_table[newstate].index); - else - ret = transition_frequency_fidvid(data, newstate); - if (ret) { - printk(KERN_ERR PFX "transition frequency failed\n"); - mutex_unlock(&fidvid_mutex); - return 1; - } - mutex_unlock(&fidvid_mutex); - - if (cpu_family == CPU_HW_PSTATE) - pol->cur = find_khz_freq_from_pstate(data->powernow_table, - data->powernow_table[newstate].index); - else - pol->cur = find_khz_freq_from_fid(data->currfid); - - return 0; -} - -/* Driver entry point to switch to the target frequency */ -static int powernowk8_target(struct cpufreq_policy *pol, - unsigned targfreq, unsigned relation) -{ - struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, - .relation = relation }; - - return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); -} - -/* Driver entry point to verify the policy and range of frequencies */ -static int powernowk8_verify(struct cpufreq_policy *pol) -{ - struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); - - if (!data) - return -EINVAL; - - return cpufreq_frequency_table_verify(pol, data->powernow_table); -} - -struct init_on_cpu { - struct powernow_k8_data *data; - int rc; -}; - -static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu) -{ - struct init_on_cpu *init_on_cpu = _init_on_cpu; - - if (pending_bit_stuck()) { - printk(KERN_ERR PFX "failing init, change pending bit set\n"); - init_on_cpu->rc = -ENODEV; - return; - } - - if (query_current_values_with_pending_wait(init_on_cpu->data)) { - init_on_cpu->rc = -ENODEV; - return; - } - - if (cpu_family == CPU_OPTERON) - fidvid_msr_init(); - - init_on_cpu->rc = 0; -} - -/* per CPU init entry point to the driver */ -static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) -{ - static const char ACPI_PSS_BIOS_BUG_MSG[] = - KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n" - FW_BUG PFX "Try again with latest BIOS.\n"; - struct powernow_k8_data *data; - struct init_on_cpu init_on_cpu; - int rc; - struct cpuinfo_x86 *c = &cpu_data(pol->cpu); - - if (!cpu_online(pol->cpu)) - return -ENODEV; - - smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); - if (rc) - return -ENODEV; - - data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); - if (!data) { - printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); - return -ENOMEM; - } - - data->cpu = pol->cpu; - data->currpstate = HW_PSTATE_INVALID; - - if (powernow_k8_cpu_init_acpi(data)) { - /* - * Use the PSB BIOS structure. This is only available on - * an UP version, and is deprecated by AMD. - */ - if (num_online_cpus() != 1) { - printk_once(ACPI_PSS_BIOS_BUG_MSG); - goto err_out; - } - if (pol->cpu != 0) { - printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " - "CPU other than CPU0. Complain to your BIOS " - "vendor.\n"); - goto err_out; - } - rc = find_psb_table(data); - if (rc) - goto err_out; - - /* Take a crude guess here. - * That guess was in microseconds, so multiply with 1000 */ - pol->cpuinfo.transition_latency = ( - ((data->rvo + 8) * data->vstable * VST_UNITS_20US) + - ((1 << data->irt) * 30)) * 1000; - } else /* ACPI _PSS objects available */ - pol->cpuinfo.transition_latency = get_transition_latency(data); - - /* only run on specific CPU from here on */ - init_on_cpu.data = data; - smp_call_function_single(data->cpu, powernowk8_cpu_init_on_cpu, - &init_on_cpu, 1); - rc = init_on_cpu.rc; - if (rc != 0) - goto err_out_exit_acpi; - - if (cpu_family == CPU_HW_PSTATE) - cpumask_copy(pol->cpus, cpumask_of(pol->cpu)); - else - cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu)); - data->available_cores = pol->cpus; - - if (cpu_family == CPU_HW_PSTATE) - pol->cur = find_khz_freq_from_pstate(data->powernow_table, - data->currpstate); - else - pol->cur = find_khz_freq_from_fid(data->currfid); - pr_debug("policy current frequency %d kHz\n", pol->cur); - - /* min/max the cpu is capable of */ - if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) { - printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n"); - powernow_k8_cpu_exit_acpi(data); - kfree(data->powernow_table); - kfree(data); - return -EINVAL; - } - - /* Check for APERF/MPERF support in hardware */ - if (cpu_has(c, X86_FEATURE_APERFMPERF)) - cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf; - - cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); - - if (cpu_family == CPU_HW_PSTATE) - pr_debug("cpu_init done, current pstate 0x%x\n", - data->currpstate); - else - pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); - - per_cpu(powernow_data, pol->cpu) = data; - - return 0; - -err_out_exit_acpi: - powernow_k8_cpu_exit_acpi(data); - -err_out: - kfree(data); - return -ENODEV; -} - -static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol) -{ - struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); - - if (!data) - return -EINVAL; - - powernow_k8_cpu_exit_acpi(data); - - cpufreq_frequency_table_put_attr(pol->cpu); - - kfree(data->powernow_table); - kfree(data); - per_cpu(powernow_data, pol->cpu) = NULL; - - return 0; -} - -static void query_values_on_cpu(void *_err) -{ - int *err = _err; - struct powernow_k8_data *data = __this_cpu_read(powernow_data); - - *err = query_current_values_with_pending_wait(data); -} - -static unsigned int powernowk8_get(unsigned int cpu) -{ - struct powernow_k8_data *data = per_cpu(powernow_data, cpu); - unsigned int khz = 0; - int err; - - if (!data) - return 0; - - smp_call_function_single(cpu, query_values_on_cpu, &err, true); - if (err) - goto out; - - if (cpu_family == CPU_HW_PSTATE) - khz = find_khz_freq_from_pstate(data->powernow_table, - data->currpstate); - else - khz = find_khz_freq_from_fid(data->currfid); - - -out: - return khz; -} - -static void _cpb_toggle_msrs(bool t) -{ - int cpu; - - get_online_cpus(); - - rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); - - for_each_cpu(cpu, cpu_online_mask) { - struct msr *reg = per_cpu_ptr(msrs, cpu); - if (t) - reg->l &= ~BIT(25); - else - reg->l |= BIT(25); - } - wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); - - put_online_cpus(); -} - -/* - * Switch on/off core performance boosting. - * - * 0=disable - * 1=enable. - */ -static void cpb_toggle(bool t) -{ - if (!cpb_capable) - return; - - if (t && !cpb_enabled) { - cpb_enabled = true; - _cpb_toggle_msrs(t); - printk(KERN_INFO PFX "Core Boosting enabled.\n"); - } else if (!t && cpb_enabled) { - cpb_enabled = false; - _cpb_toggle_msrs(t); - printk(KERN_INFO PFX "Core Boosting disabled.\n"); - } -} - -static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, - size_t count) -{ - int ret = -EINVAL; - unsigned long val = 0; - - ret = strict_strtoul(buf, 10, &val); - if (!ret && (val == 0 || val == 1) && cpb_capable) - cpb_toggle(val); - else - return -EINVAL; - - return count; -} - -static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) -{ - return sprintf(buf, "%u\n", cpb_enabled); -} - -#define define_one_rw(_name) \ -static struct freq_attr _name = \ -__ATTR(_name, 0644, show_##_name, store_##_name) - -define_one_rw(cpb); - -static struct freq_attr *powernow_k8_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - &cpb, - NULL, -}; - -static struct cpufreq_driver cpufreq_amd64_driver = { - .verify = powernowk8_verify, - .target = powernowk8_target, - .bios_limit = acpi_processor_get_bios_limit, - .init = powernowk8_cpu_init, - .exit = __devexit_p(powernowk8_cpu_exit), - .get = powernowk8_get, - .name = "powernow-k8", - .owner = THIS_MODULE, - .attr = powernow_k8_attr, -}; - -/* - * Clear the boost-disable flag on the CPU_DOWN path so that this cpu - * cannot block the remaining ones from boosting. On the CPU_UP path we - * simply keep the boost-disable flag in sync with the current global - * state. - */ -static int cpb_notify(struct notifier_block *nb, unsigned long action, - void *hcpu) -{ - unsigned cpu = (long)hcpu; - u32 lo, hi; - - switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: - - if (!cpb_enabled) { - rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); - lo |= BIT(25); - wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi); - } - break; - - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi); - lo &= ~BIT(25); - wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi); - break; - - default: - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block cpb_nb = { - .notifier_call = cpb_notify, -}; - -/* driver entry point for init */ -static int __cpuinit powernowk8_init(void) -{ - unsigned int i, supported_cpus = 0, cpu; - int rv; - - if (!x86_match_cpu(powernow_k8_ids)) - return -ENODEV; - - for_each_online_cpu(i) { - int rc; - smp_call_function_single(i, check_supported_cpu, &rc, 1); - if (rc == 0) - supported_cpus++; - } - - if (supported_cpus != num_online_cpus()) - return -ENODEV; - - printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n", - num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); - - if (boot_cpu_has(X86_FEATURE_CPB)) { - - cpb_capable = true; - - msrs = msrs_alloc(); - if (!msrs) { - printk(KERN_ERR "%s: Error allocating msrs!\n", __func__); - return -ENOMEM; - } - - register_cpu_notifier(&cpb_nb); - - rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs); - - for_each_cpu(cpu, cpu_online_mask) { - struct msr *reg = per_cpu_ptr(msrs, cpu); - cpb_enabled |= !(!!(reg->l & BIT(25))); - } - - printk(KERN_INFO PFX "Core Performance Boosting: %s.\n", - (cpb_enabled ? "on" : "off")); - } - - rv = cpufreq_register_driver(&cpufreq_amd64_driver); - if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) { - unregister_cpu_notifier(&cpb_nb); - msrs_free(msrs); - msrs = NULL; - } - return rv; -} - -/* driver entry point for term */ -static void __exit powernowk8_exit(void) -{ - pr_debug("exit\n"); - - if (boot_cpu_has(X86_FEATURE_CPB)) { - msrs_free(msrs); - msrs = NULL; - - unregister_cpu_notifier(&cpb_nb); - } - - cpufreq_unregister_driver(&cpufreq_amd64_driver); -} - -MODULE_AUTHOR("Paul Devriendt and " - "Mark Langsdorf "); -MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); -MODULE_LICENSE("GPL"); - -late_initcall(powernowk8_init); -module_exit(powernowk8_exit); diff --git a/linux-3.4/drivers/cpufreq.new/powernow-k8.h b/linux-3.4/drivers/cpufreq.new/powernow-k8.h deleted file mode 100644 index 3744d26c..00000000 --- a/linux-3.4/drivers/cpufreq.new/powernow-k8.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * (c) 2003-2006 Advanced Micro Devices, Inc. - * Your use of this code is subject to the terms and conditions of the - * GNU general public license version 2. See "COPYING" or - * http://www.gnu.org/licenses/gpl.html - */ - -enum pstate { - HW_PSTATE_INVALID = 0xff, - HW_PSTATE_0 = 0, - HW_PSTATE_1 = 1, - HW_PSTATE_2 = 2, - HW_PSTATE_3 = 3, - HW_PSTATE_4 = 4, - HW_PSTATE_5 = 5, - HW_PSTATE_6 = 6, - HW_PSTATE_7 = 7, -}; - -struct powernow_k8_data { - unsigned int cpu; - - u32 numps; /* number of p-states */ - u32 batps; /* number of p-states supported on battery */ - u32 max_hw_pstate; /* maximum legal hardware pstate */ - - /* these values are constant when the PSB is used to determine - * vid/fid pairings, but are modified during the ->target() call - * when ACPI is used */ - u32 rvo; /* ramp voltage offset */ - u32 irt; /* isochronous relief time */ - u32 vidmvs; /* usable value calculated from mvs */ - u32 vstable; /* voltage stabilization time, units 20 us */ - u32 plllock; /* pll lock time, units 1 us */ - u32 exttype; /* extended interface = 1 */ - - /* keep track of the current fid / vid or pstate */ - u32 currvid; - u32 currfid; - enum pstate currpstate; - - /* the powernow_table includes all frequency and vid/fid pairings: - * fid are the lower 8 bits of the index, vid are the upper 8 bits. - * frequency is in kHz */ - struct cpufreq_frequency_table *powernow_table; - - /* the acpi table needs to be kept. it's only available if ACPI was - * used to determine valid frequency/vid/fid states */ - struct acpi_processor_performance acpi_data; - - /* we need to keep track of associated cores, but let cpufreq - * handle hotplug events - so just point at cpufreq pol->cpus - * structure */ - struct cpumask *available_cores; -}; - -/* processor's cpuid instruction support */ -#define CPUID_PROCESSOR_SIGNATURE 1 /* function 1 */ -#define CPUID_XFAM 0x0ff00000 /* extended family */ -#define CPUID_XFAM_K8 0 -#define CPUID_XMOD 0x000f0000 /* extended model */ -#define CPUID_XMOD_REV_MASK 0x000c0000 -#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ -#define CPUID_USE_XFAM_XMOD 0x00000f00 -#define CPUID_GET_MAX_CAPABILITIES 0x80000000 -#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 -#define P_STATE_TRANSITION_CAPABLE 6 - -/* Model Specific Registers for p-state transitions. MSRs are 64-bit. For */ -/* writes (wrmsr - opcode 0f 30), the register number is placed in ecx, and */ -/* the value to write is placed in edx:eax. For reads (rdmsr - opcode 0f 32), */ -/* the register number is placed in ecx, and the data is returned in edx:eax. */ - -#define MSR_FIDVID_CTL 0xc0010041 -#define MSR_FIDVID_STATUS 0xc0010042 - -/* Field definitions within the FID VID Low Control MSR : */ -#define MSR_C_LO_INIT_FID_VID 0x00010000 -#define MSR_C_LO_NEW_VID 0x00003f00 -#define MSR_C_LO_NEW_FID 0x0000003f -#define MSR_C_LO_VID_SHIFT 8 - -/* Field definitions within the FID VID High Control MSR : */ -#define MSR_C_HI_STP_GNT_TO 0x000fffff - -/* Field definitions within the FID VID Low Status MSR : */ -#define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ -#define MSR_S_LO_MAX_RAMP_VID 0x3f000000 -#define MSR_S_LO_MAX_FID 0x003f0000 -#define MSR_S_LO_START_FID 0x00003f00 -#define MSR_S_LO_CURRENT_FID 0x0000003f - -/* Field definitions within the FID VID High Status MSR : */ -#define MSR_S_HI_MIN_WORKING_VID 0x3f000000 -#define MSR_S_HI_MAX_WORKING_VID 0x003f0000 -#define MSR_S_HI_START_VID 0x00003f00 -#define MSR_S_HI_CURRENT_VID 0x0000003f -#define MSR_C_HI_STP_GNT_BENIGN 0x00000001 - - -/* Hardware Pstate _PSS and MSR definitions */ -#define USE_HW_PSTATE 0x00000080 -#define HW_PSTATE_MASK 0x00000007 -#define HW_PSTATE_VALID_MASK 0x80000000 -#define HW_PSTATE_MAX_MASK 0x000000f0 -#define HW_PSTATE_MAX_SHIFT 4 -#define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */ -#define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */ -#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */ -#define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */ - -/* define the two driver architectures */ -#define CPU_OPTERON 0 -#define CPU_HW_PSTATE 1 - - -/* - * There are restrictions frequencies have to follow: - * - only 1 entry in the low fid table ( <=1.4GHz ) - * - lowest entry in the high fid table must be >= 2 * the entry in the - * low fid table - * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry - * in the low fid table - * - the parts can only step at <= 200 MHz intervals, odd fid values are - * supported in revision G and later revisions. - * - lowest frequency must be >= interprocessor hypertransport link speed - * (only applies to MP systems obviously) - */ - -/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */ -#define LO_FID_TABLE_TOP 7 /* fid values marking the boundary */ -#define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */ - -#define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */ -#define HI_VCOFREQ_TABLE_BOTTOM 1600 - -#define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */ - -#define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */ -#define LEAST_VID 0x3e /* Lowest (numerically highest) useful vid value */ - -#define MIN_FREQ 800 /* Min and max freqs, per spec */ -#define MAX_FREQ 5000 - -#define INVALID_FID_MASK 0xffffffc0 /* not a valid fid if these bits are set */ -#define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ - -#define VID_OFF 0x3f - -#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */ - -#define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */ - -#define MAXIMUM_VID_STEPS 1 /* Current cpus only allow a single step of 25mV */ -#define VST_UNITS_20US 20 /* Voltage Stabilization Time is in units of 20us */ - -/* - * Most values of interest are encoded in a single field of the _PSS - * entries: the "control" value. - */ - -#define IRT_SHIFT 30 -#define RVO_SHIFT 28 -#define EXT_TYPE_SHIFT 27 -#define PLL_L_SHIFT 20 -#define MVS_SHIFT 18 -#define VST_SHIFT 11 -#define VID_SHIFT 6 -#define IRT_MASK 3 -#define RVO_MASK 3 -#define EXT_TYPE_MASK 1 -#define PLL_L_MASK 0x7f -#define MVS_MASK 3 -#define VST_MASK 0x7f -#define VID_MASK 0x1f -#define FID_MASK 0x1f -#define EXT_VID_MASK 0x3f -#define EXT_FID_MASK 0x3f - - -/* - * Version 1.4 of the PSB table. This table is constructed by BIOS and is - * to tell the OS's power management driver which VIDs and FIDs are - * supported by this particular processor. - * If the data in the PSB / PST is wrong, then this driver will program the - * wrong values into hardware, which is very likely to lead to a crash. - */ - -#define PSB_ID_STRING "AMDK7PNOW!" -#define PSB_ID_STRING_LEN 10 - -#define PSB_VERSION_1_4 0x14 - -struct psb_s { - u8 signature[10]; - u8 tableversion; - u8 flags1; - u16 vstable; - u8 flags2; - u8 num_tables; - u32 cpuid; - u8 plllocktime; - u8 maxfid; - u8 maxvid; - u8 numps; -}; - -/* Pairs of fid/vid values are appended to the version 1.4 PSB table. */ -struct pst_s { - u8 fid; - u8 vid; -}; - -static int core_voltage_pre_transition(struct powernow_k8_data *data, - u32 reqvid, u32 regfid); -static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid); -static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); - -static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); - -static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); -static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); diff --git a/linux-3.4/drivers/cpufreq.new/s3c2416-cpufreq.c b/linux-3.4/drivers/cpufreq.new/s3c2416-cpufreq.c deleted file mode 100644 index 50d2f15a..00000000 --- a/linux-3.4/drivers/cpufreq.new/s3c2416-cpufreq.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * S3C2416/2450 CPUfreq Support - * - * Copyright 2011 Heiko Stuebner - * - * based on s3c64xx_cpufreq.c - * - * Copyright 2009 Wolfson Microelectronics plc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_MUTEX(cpufreq_lock); - -struct s3c2416_data { - struct clk *armdiv; - struct clk *armclk; - struct clk *hclk; - - unsigned long regulator_latency; -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - struct regulator *vddarm; -#endif - - struct cpufreq_frequency_table *freq_table; - - bool is_dvs; - bool disable_dvs; -}; - -static struct s3c2416_data s3c2416_cpufreq; - -struct s3c2416_dvfs { - unsigned int vddarm_min; - unsigned int vddarm_max; -}; - -/* pseudo-frequency for dvs mode */ -#define FREQ_DVS 132333 - -/* frequency to sleep and reboot in - * it's essential to leave dvs, as some boards do not reconfigure the - * regulator on reboot - */ -#define FREQ_SLEEP 133333 - -/* Sources for the ARMCLK */ -#define SOURCE_HCLK 0 -#define SOURCE_ARMDIV 1 - -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE -/* S3C2416 only supports changing the voltage in the dvs-mode. - * Voltages down to 1.0V seem to work, so we take what the regulator - * can get us. - */ -static struct s3c2416_dvfs s3c2416_dvfs_table[] = { - [SOURCE_HCLK] = { 950000, 1250000 }, - [SOURCE_ARMDIV] = { 1250000, 1350000 }, -}; -#endif - -static struct cpufreq_frequency_table s3c2416_freq_table[] = { - { SOURCE_HCLK, FREQ_DVS }, - { SOURCE_ARMDIV, 133333 }, - { SOURCE_ARMDIV, 266666 }, - { SOURCE_ARMDIV, 400000 }, - { 0, CPUFREQ_TABLE_END }, -}; - -static struct cpufreq_frequency_table s3c2450_freq_table[] = { - { SOURCE_HCLK, FREQ_DVS }, - { SOURCE_ARMDIV, 133500 }, - { SOURCE_ARMDIV, 267000 }, - { SOURCE_ARMDIV, 534000 }, - { 0, CPUFREQ_TABLE_END }, -}; - -static int s3c2416_cpufreq_verify_speed(struct cpufreq_policy *policy) -{ - struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - - if (policy->cpu != 0) - return -EINVAL; - - return cpufreq_frequency_table_verify(policy, s3c_freq->freq_table); -} - -static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) -{ - struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - - if (cpu != 0) - return 0; - - /* return our pseudo-frequency when in dvs mode */ - if (s3c_freq->is_dvs) - return FREQ_DVS; - - return clk_get_rate(s3c_freq->armclk) / 1000; -} - -static int s3c2416_cpufreq_set_armdiv(struct s3c2416_data *s3c_freq, - unsigned int freq) -{ - int ret; - - if (clk_get_rate(s3c_freq->armdiv) / 1000 != freq) { - ret = clk_set_rate(s3c_freq->armdiv, freq * 1000); - if (ret < 0) { - pr_err("cpufreq: Failed to set armdiv rate %dkHz: %d\n", - freq, ret); - return ret; - } - } - - return 0; -} - -static int s3c2416_cpufreq_enter_dvs(struct s3c2416_data *s3c_freq, int idx) -{ -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - struct s3c2416_dvfs *dvfs; -#endif - int ret; - - if (s3c_freq->is_dvs) { - pr_debug("cpufreq: already in dvs mode, nothing to do\n"); - return 0; - } - - pr_debug("cpufreq: switching armclk to hclk (%lukHz)\n", - clk_get_rate(s3c_freq->hclk) / 1000); - ret = clk_set_parent(s3c_freq->armclk, s3c_freq->hclk); - if (ret < 0) { - pr_err("cpufreq: Failed to switch armclk to hclk: %d\n", ret); - return ret; - } - -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - /* changing the core voltage is only allowed when in dvs mode */ - if (s3c_freq->vddarm) { - dvfs = &s3c2416_dvfs_table[idx]; - - pr_debug("cpufreq: setting regultor to %d-%d\n", - dvfs->vddarm_min, dvfs->vddarm_max); - ret = regulator_set_voltage(s3c_freq->vddarm, - dvfs->vddarm_min, - dvfs->vddarm_max); - - /* when lowering the voltage failed, there is nothing to do */ - if (ret != 0) - pr_err("cpufreq: Failed to set VDDARM: %d\n", ret); - } -#endif - - s3c_freq->is_dvs = 1; - - return 0; -} - -static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx) -{ -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - struct s3c2416_dvfs *dvfs; -#endif - int ret; - - if (!s3c_freq->is_dvs) { - pr_debug("cpufreq: not in dvs mode, so can't leave\n"); - return 0; - } - -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - if (s3c_freq->vddarm) { - dvfs = &s3c2416_dvfs_table[idx]; - - pr_debug("cpufreq: setting regultor to %d-%d\n", - dvfs->vddarm_min, dvfs->vddarm_max); - ret = regulator_set_voltage(s3c_freq->vddarm, - dvfs->vddarm_min, - dvfs->vddarm_max); - if (ret != 0) { - pr_err("cpufreq: Failed to set VDDARM: %d\n", ret); - return ret; - } - } -#endif - - /* force armdiv to hclk frequency for transition from dvs*/ - if (clk_get_rate(s3c_freq->armdiv) > clk_get_rate(s3c_freq->hclk)) { - pr_debug("cpufreq: force armdiv to hclk frequency (%lukHz)\n", - clk_get_rate(s3c_freq->hclk) / 1000); - ret = s3c2416_cpufreq_set_armdiv(s3c_freq, - clk_get_rate(s3c_freq->hclk) / 1000); - if (ret < 0) { - pr_err("cpufreq: Failed to to set the armdiv to %lukHz: %d\n", - clk_get_rate(s3c_freq->hclk) / 1000, ret); - return ret; - } - } - - pr_debug("cpufreq: switching armclk parent to armdiv (%lukHz)\n", - clk_get_rate(s3c_freq->armdiv) / 1000); - - ret = clk_set_parent(s3c_freq->armclk, s3c_freq->armdiv); - if (ret < 0) { - pr_err("cpufreq: Failed to switch armclk clock parent to armdiv: %d\n", - ret); - return ret; - } - - s3c_freq->is_dvs = 0; - - return 0; -} - -static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - struct cpufreq_freqs freqs; - int idx, ret, to_dvs = 0; - unsigned int i; - - mutex_lock(&cpufreq_lock); - - pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation); - - ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table, - target_freq, relation, &i); - if (ret != 0) - goto out; - - idx = s3c_freq->freq_table[i].index; - - if (idx == SOURCE_HCLK) - to_dvs = 1; - - /* switching to dvs when it's not allowed */ - if (to_dvs && s3c_freq->disable_dvs) { - pr_debug("cpufreq: entering dvs mode not allowed\n"); - ret = -EINVAL; - goto out; - } - - freqs.cpu = 0; - freqs.flags = 0; - freqs.old = s3c_freq->is_dvs ? FREQ_DVS - : clk_get_rate(s3c_freq->armclk) / 1000; - - /* When leavin dvs mode, always switch the armdiv to the hclk rate - * The S3C2416 has stability issues when switching directly to - * higher frequencies. - */ - freqs.new = (s3c_freq->is_dvs && !to_dvs) - ? clk_get_rate(s3c_freq->hclk) / 1000 - : s3c_freq->freq_table[i].frequency; - - pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); - - if (!to_dvs && freqs.old == freqs.new) - goto out; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - if (to_dvs) { - pr_debug("cpufreq: enter dvs\n"); - ret = s3c2416_cpufreq_enter_dvs(s3c_freq, idx); - } else if (s3c_freq->is_dvs) { - pr_debug("cpufreq: leave dvs\n"); - ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx); - } else { - pr_debug("cpufreq: change armdiv to %dkHz\n", freqs.new); - ret = s3c2416_cpufreq_set_armdiv(s3c_freq, freqs.new); - } - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - -out: - mutex_unlock(&cpufreq_lock); - - return ret; -} - -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE -static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq) -{ - int count, v, i, found; - struct cpufreq_frequency_table *freq; - struct s3c2416_dvfs *dvfs; - - count = regulator_count_voltages(s3c_freq->vddarm); - if (count < 0) { - pr_err("cpufreq: Unable to check supported voltages\n"); - return; - } - - freq = s3c_freq->freq_table; - while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; - - dvfs = &s3c2416_dvfs_table[freq->index]; - found = 0; - - /* Check only the min-voltage, more is always ok on S3C2416 */ - for (i = 0; i < count; i++) { - v = regulator_list_voltage(s3c_freq->vddarm, i); - if (v >= dvfs->vddarm_min) - found = 1; - } - - if (!found) { - pr_debug("cpufreq: %dkHz unsupported by regulator\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; - } - - freq++; - } - - /* Guessed */ - s3c_freq->regulator_latency = 1 * 1000 * 1000; -} -#endif - -static int s3c2416_cpufreq_reboot_notifier_evt(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - int ret; - - mutex_lock(&cpufreq_lock); - - /* disable further changes */ - s3c_freq->disable_dvs = 1; - - mutex_unlock(&cpufreq_lock); - - /* some boards don't reconfigure the regulator on reboot, which - * could lead to undervolting the cpu when the clock is reset. - * Therefore we always leave the DVS mode on reboot. - */ - if (s3c_freq->is_dvs) { - pr_debug("cpufreq: leave dvs on reboot\n"); - ret = cpufreq_driver_target(cpufreq_cpu_get(0), FREQ_SLEEP, 0); - if (ret < 0) - return NOTIFY_BAD; - } - - return NOTIFY_DONE; -} - -static struct notifier_block s3c2416_cpufreq_reboot_notifier = { - .notifier_call = s3c2416_cpufreq_reboot_notifier_evt, -}; - -static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) -{ - struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; - struct cpufreq_frequency_table *freq; - struct clk *msysclk; - unsigned long rate; - int ret; - - if (policy->cpu != 0) - return -EINVAL; - - msysclk = clk_get(NULL, "msysclk"); - if (IS_ERR(msysclk)) { - ret = PTR_ERR(msysclk); - pr_err("cpufreq: Unable to obtain msysclk: %d\n", ret); - return ret; - } - - /* - * S3C2416 and S3C2450 share the same processor-ID and also provide no - * other means to distinguish them other than through the rate of - * msysclk. On S3C2416 msysclk runs at 800MHz and on S3C2450 at 533MHz. - */ - rate = clk_get_rate(msysclk); - if (rate == 800 * 1000 * 1000) { - pr_info("cpufreq: msysclk running at %lukHz, using S3C2416 frequency table\n", - rate / 1000); - s3c_freq->freq_table = s3c2416_freq_table; - policy->cpuinfo.max_freq = 400000; - } else if (rate / 1000 == 534000) { - pr_info("cpufreq: msysclk running at %lukHz, using S3C2450 frequency table\n", - rate / 1000); - s3c_freq->freq_table = s3c2450_freq_table; - policy->cpuinfo.max_freq = 534000; - } - - /* not needed anymore */ - clk_put(msysclk); - - if (s3c_freq->freq_table == NULL) { - pr_err("cpufreq: No frequency information for this CPU, msysclk at %lukHz\n", - rate / 1000); - return -ENODEV; - } - - s3c_freq->is_dvs = 0; - - s3c_freq->armdiv = clk_get(NULL, "armdiv"); - if (IS_ERR(s3c_freq->armdiv)) { - ret = PTR_ERR(s3c_freq->armdiv); - pr_err("cpufreq: Unable to obtain ARMDIV: %d\n", ret); - return ret; - } - - s3c_freq->hclk = clk_get(NULL, "hclk"); - if (IS_ERR(s3c_freq->hclk)) { - ret = PTR_ERR(s3c_freq->hclk); - pr_err("cpufreq: Unable to obtain HCLK: %d\n", ret); - goto err_hclk; - } - - /* chech hclk rate, we only support the common 133MHz for now - * hclk could also run at 66MHz, but this not often used - */ - rate = clk_get_rate(s3c_freq->hclk); - if (rate < 133 * 1000 * 1000) { - pr_err("cpufreq: HCLK not at 133MHz\n"); - clk_put(s3c_freq->hclk); - ret = -EINVAL; - goto err_armclk; - } - - s3c_freq->armclk = clk_get(NULL, "armclk"); - if (IS_ERR(s3c_freq->armclk)) { - ret = PTR_ERR(s3c_freq->armclk); - pr_err("cpufreq: Unable to obtain ARMCLK: %d\n", ret); - goto err_armclk; - } - -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - s3c_freq->vddarm = regulator_get(NULL, "vddarm"); - if (IS_ERR(s3c_freq->vddarm)) { - ret = PTR_ERR(s3c_freq->vddarm); - pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret); - goto err_vddarm; - } - - s3c2416_cpufreq_cfg_regulator(s3c_freq); -#else - s3c_freq->regulator_latency = 0; -#endif - - freq = s3c_freq->freq_table; - while (freq->frequency != CPUFREQ_TABLE_END) { - /* special handling for dvs mode */ - if (freq->index == 0) { - if (!s3c_freq->hclk) { - pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; - } else { - freq++; - continue; - } - } - - /* Check for frequencies we can generate */ - rate = clk_round_rate(s3c_freq->armdiv, - freq->frequency * 1000); - rate /= 1000; - if (rate != freq->frequency) { - pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n", - freq->frequency, rate); - freq->frequency = CPUFREQ_ENTRY_INVALID; - } - - freq++; - } - - policy->cur = clk_get_rate(s3c_freq->armclk) / 1000; - - /* Datasheet says PLL stabalisation time must be at least 300us, - * so but add some fudge. (reference in LOCKCON0 register description) - */ - policy->cpuinfo.transition_latency = (500 * 1000) + - s3c_freq->regulator_latency; - - ret = cpufreq_frequency_table_cpuinfo(policy, s3c_freq->freq_table); - if (ret) - goto err_freq_table; - - cpufreq_frequency_table_get_attr(s3c_freq->freq_table, 0); - - register_reboot_notifier(&s3c2416_cpufreq_reboot_notifier); - - return 0; - -err_freq_table: -#ifdef CONFIG_ARM_S3C2416_CPUFREQ_VCORESCALE - regulator_put(s3c_freq->vddarm); -err_vddarm: -#endif - clk_put(s3c_freq->armclk); -err_armclk: - clk_put(s3c_freq->hclk); -err_hclk: - clk_put(s3c_freq->armdiv); - - return ret; -} - -static struct freq_attr *s3c2416_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver s3c2416_cpufreq_driver = { - .owner = THIS_MODULE, - .flags = 0, - .verify = s3c2416_cpufreq_verify_speed, - .target = s3c2416_cpufreq_set_target, - .get = s3c2416_cpufreq_get_speed, - .init = s3c2416_cpufreq_driver_init, - .name = "s3c2416", - .attr = s3c2416_cpufreq_attr, -}; - -static int __init s3c2416_cpufreq_init(void) -{ - return cpufreq_register_driver(&s3c2416_cpufreq_driver); -} -module_init(s3c2416_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/s3c64xx-cpufreq.c b/linux-3.4/drivers/cpufreq.new/s3c64xx-cpufreq.c deleted file mode 100644 index 6f9490b3..00000000 --- a/linux-3.4/drivers/cpufreq.new/s3c64xx-cpufreq.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2009 Wolfson Microelectronics plc - * - * S3C64xx CPUfreq Support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define pr_fmt(fmt) "cpufreq: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct clk *armclk; -static struct regulator *vddarm; -static unsigned long regulator_latency; - -#ifdef CONFIG_CPU_S3C6410 -struct s3c64xx_dvfs { - unsigned int vddarm_min; - unsigned int vddarm_max; -}; - -static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { - [0] = { 1000000, 1150000 }, - [1] = { 1050000, 1150000 }, - [2] = { 1100000, 1150000 }, - [3] = { 1200000, 1350000 }, - [4] = { 1300000, 1350000 }, -}; - -static struct cpufreq_frequency_table s3c64xx_freq_table[] = { - { 0, 66000 }, - { 0, 100000 }, - { 0, 133000 }, - { 1, 200000 }, - { 1, 222000 }, - { 1, 266000 }, - { 2, 333000 }, - { 2, 400000 }, - { 2, 532000 }, - { 2, 533000 }, - { 3, 667000 }, - { 4, 800000 }, - { 0, CPUFREQ_TABLE_END }, -}; -#endif - -static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy) -{ - if (policy->cpu != 0) - return -EINVAL; - - return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table); -} - -static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) -{ - if (cpu != 0) - return 0; - - return clk_get_rate(armclk) / 1000; -} - -static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - int ret; - unsigned int i; - struct cpufreq_freqs freqs; - struct s3c64xx_dvfs *dvfs; - - ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table, - target_freq, relation, &i); - if (ret != 0) - return ret; - - freqs.cpu = 0; - freqs.old = clk_get_rate(armclk) / 1000; - freqs.new = s3c64xx_freq_table[i].frequency; - freqs.flags = 0; - dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index]; - - if (freqs.old == freqs.new) - return 0; - - pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - -#ifdef CONFIG_REGULATOR - if (vddarm && freqs.new > freqs.old) { - ret = regulator_set_voltage(vddarm, - dvfs->vddarm_min, - dvfs->vddarm_max); - if (ret != 0) { - pr_err("Failed to set VDDARM for %dkHz: %d\n", - freqs.new, ret); - goto err; - } - } -#endif - - ret = clk_set_rate(armclk, freqs.new * 1000); - if (ret < 0) { - pr_err("Failed to set rate %dkHz: %d\n", - freqs.new, ret); - goto err; - } - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - -#ifdef CONFIG_REGULATOR - if (vddarm && freqs.new < freqs.old) { - ret = regulator_set_voltage(vddarm, - dvfs->vddarm_min, - dvfs->vddarm_max); - if (ret != 0) { - pr_err("Failed to set VDDARM for %dkHz: %d\n", - freqs.new, ret); - goto err_clk; - } - } -#endif - - pr_debug("Set actual frequency %lukHz\n", - clk_get_rate(armclk) / 1000); - - return 0; - -err_clk: - if (clk_set_rate(armclk, freqs.old * 1000) < 0) - pr_err("Failed to restore original clock rate\n"); -err: - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return ret; -} - -#ifdef CONFIG_REGULATOR -static void __init s3c64xx_cpufreq_config_regulator(void) -{ - int count, v, i, found; - struct cpufreq_frequency_table *freq; - struct s3c64xx_dvfs *dvfs; - - count = regulator_count_voltages(vddarm); - if (count < 0) { - pr_err("Unable to check supported voltages\n"); - } - - freq = s3c64xx_freq_table; - while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; - - dvfs = &s3c64xx_dvfs_table[freq->index]; - found = 0; - - for (i = 0; i < count; i++) { - v = regulator_list_voltage(vddarm, i); - if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max) - found = 1; - } - - if (!found) { - pr_debug("%dkHz unsupported by regulator\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; - } - - freq++; - } - - /* Guess based on having to do an I2C/SPI write; in future we - * will be able to query the regulator performance here. */ - regulator_latency = 1 * 1000 * 1000; -} -#endif - -static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) -{ - int ret; - struct cpufreq_frequency_table *freq; - - if (policy->cpu != 0) - return -EINVAL; - - if (s3c64xx_freq_table == NULL) { - pr_err("No frequency information for this CPU\n"); - return -ENODEV; - } - - armclk = clk_get(NULL, "armclk"); - if (IS_ERR(armclk)) { - pr_err("Unable to obtain ARMCLK: %ld\n", - PTR_ERR(armclk)); - return PTR_ERR(armclk); - } - -#ifdef CONFIG_REGULATOR - vddarm = regulator_get(NULL, "vddarm"); - if (IS_ERR(vddarm)) { - ret = PTR_ERR(vddarm); - pr_err("Failed to obtain VDDARM: %d\n", ret); - pr_err("Only frequency scaling available\n"); - vddarm = NULL; - } else { - s3c64xx_cpufreq_config_regulator(); - } -#endif - - freq = s3c64xx_freq_table; - while (freq->frequency != CPUFREQ_TABLE_END) { - unsigned long r; - - /* Check for frequencies we can generate */ - r = clk_round_rate(armclk, freq->frequency * 1000); - r /= 1000; - if (r != freq->frequency) { - pr_debug("%dkHz unsupported by clock\n", - freq->frequency); - freq->frequency = CPUFREQ_ENTRY_INVALID; - } - - /* If we have no regulator then assume startup - * frequency is the maximum we can support. */ - if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0)) - freq->frequency = CPUFREQ_ENTRY_INVALID; - - freq++; - } - - policy->cur = clk_get_rate(armclk) / 1000; - - /* Datasheet says PLL stabalisation time (if we were to use - * the PLLs, which we don't currently) is ~300us worst case, - * but add some fudge. - */ - policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency; - - ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table); - if (ret != 0) { - pr_err("Failed to configure frequency table: %d\n", - ret); - regulator_put(vddarm); - clk_put(armclk); - } - - return ret; -} - -static struct cpufreq_driver s3c64xx_cpufreq_driver = { - .owner = THIS_MODULE, - .flags = 0, - .verify = s3c64xx_cpufreq_verify_speed, - .target = s3c64xx_cpufreq_set_target, - .get = s3c64xx_cpufreq_get_speed, - .init = s3c64xx_cpufreq_driver_init, - .name = "s3c", -}; - -static int __init s3c64xx_cpufreq_init(void) -{ - return cpufreq_register_driver(&s3c64xx_cpufreq_driver); -} -module_init(s3c64xx_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/s5pv210-cpufreq.c b/linux-3.4/drivers/cpufreq.new/s5pv210-cpufreq.c deleted file mode 100644 index a484aaea..00000000 --- a/linux-3.4/drivers/cpufreq.new/s5pv210-cpufreq.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * CPU frequency scaling for S5PC110/S5PV210 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static struct clk *cpu_clk; -static struct clk *dmc0_clk; -static struct clk *dmc1_clk; -static struct cpufreq_freqs freqs; -static DEFINE_MUTEX(set_freq_lock); - -/* APLL M,P,S values for 1G/800Mhz */ -#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1) -#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1) - -/* Use 800MHz when entering sleep mode */ -#define SLEEP_FREQ (800 * 1000) - -/* - * relation has an additional symantics other than the standard of cpufreq - * DISALBE_FURTHER_CPUFREQ: disable further access to target - * ENABLE_FURTUER_CPUFREQ: enable access to target - */ -enum cpufreq_access { - DISABLE_FURTHER_CPUFREQ = 0x10, - ENABLE_FURTHER_CPUFREQ = 0x20, -}; - -static bool no_cpufreq_access; - -/* - * DRAM configurations to calculate refresh counter for changing - * frequency of memory. - */ -struct dram_conf { - unsigned long freq; /* HZ */ - unsigned long refresh; /* DRAM refresh counter * 1000 */ -}; - -/* DRAM configuration (DMC0 and DMC1) */ -static struct dram_conf s5pv210_dram_conf[2]; - -enum perf_level { - L0, L1, L2, L3, L4, -}; - -enum s5pv210_mem_type { - LPDDR = 0x1, - LPDDR2 = 0x2, - DDR2 = 0x4, -}; - -enum s5pv210_dmc_port { - DMC0 = 0, - DMC1, -}; - -static struct cpufreq_frequency_table s5pv210_freq_table[] = { - {L0, 1000*1000}, - {L1, 800*1000}, - {L2, 400*1000}, - {L3, 200*1000}, - {L4, 100*1000}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct regulator *arm_regulator; -static struct regulator *int_regulator; - -struct s5pv210_dvs_conf { - int arm_volt; /* uV */ - int int_volt; /* uV */ -}; - -static const int arm_volt_max = 1350000; -static const int int_volt_max = 1250000; - -static struct s5pv210_dvs_conf dvs_conf[] = { - [L0] = { - .arm_volt = 1250000, - .int_volt = 1100000, - }, - [L1] = { - .arm_volt = 1200000, - .int_volt = 1100000, - }, - [L2] = { - .arm_volt = 1050000, - .int_volt = 1100000, - }, - [L3] = { - .arm_volt = 950000, - .int_volt = 1100000, - }, - [L4] = { - .arm_volt = 950000, - .int_volt = 1000000, - }, -}; - -static u32 clkdiv_val[5][11] = { - /* - * Clock divider value for following - * { APLL, A2M, HCLK_MSYS, PCLK_MSYS, - * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS, - * ONEDRAM, MFC, G3D } - */ - - /* L0 : [1000/200/100][166/83][133/66][200/200] */ - {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0}, - - /* L1 : [800/200/100][166/83][133/66][200/200] */ - {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0}, - - /* L2 : [400/200/100][166/83][133/66][200/200] */ - {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0}, - - /* L3 : [200/200/100][166/83][133/66][200/200] */ - {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0}, - - /* L4 : [100/100/100][83/83][66/66][100/100] */ - {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0}, -}; - -/* - * This function set DRAM refresh counter - * accoriding to operating frequency of DRAM - * ch: DMC port number 0 or 1 - * freq: Operating frequency of DRAM(KHz) - */ -static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) -{ - unsigned long tmp, tmp1; - void __iomem *reg = NULL; - - if (ch == DMC0) { - reg = (S5P_VA_DMC0 + 0x30); - } else if (ch == DMC1) { - reg = (S5P_VA_DMC1 + 0x30); - } else { - printk(KERN_ERR "Cannot find DMC port\n"); - return; - } - - /* Find current DRAM frequency */ - tmp = s5pv210_dram_conf[ch].freq; - - do_div(tmp, freq); - - tmp1 = s5pv210_dram_conf[ch].refresh; - - do_div(tmp1, tmp); - - __raw_writel(tmp1, reg); -} - -static int s5pv210_verify_speed(struct cpufreq_policy *policy) -{ - if (policy->cpu) - return -EINVAL; - - return cpufreq_frequency_table_verify(policy, s5pv210_freq_table); -} - -static unsigned int s5pv210_getspeed(unsigned int cpu) -{ - if (cpu) - return 0; - - return clk_get_rate(cpu_clk) / 1000; -} - -static int s5pv210_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned long reg; - unsigned int index, priv_index; - unsigned int pll_changing = 0; - unsigned int bus_speed_changing = 0; - int arm_volt, int_volt; - int ret = 0; - - mutex_lock(&set_freq_lock); - - if (relation & ENABLE_FURTHER_CPUFREQ) - no_cpufreq_access = false; - - if (no_cpufreq_access) { -#ifdef CONFIG_PM_VERBOSE - pr_err("%s:%d denied access to %s as it is disabled" - "temporarily\n", __FILE__, __LINE__, __func__); -#endif - ret = -EINVAL; - goto exit; - } - - if (relation & DISABLE_FURTHER_CPUFREQ) - no_cpufreq_access = true; - - relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ); - - freqs.old = s5pv210_getspeed(0); - - if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, - target_freq, relation, &index)) { - ret = -EINVAL; - goto exit; - } - - freqs.new = s5pv210_freq_table[index].frequency; - freqs.cpu = 0; - - if (freqs.new == freqs.old) - goto exit; - - /* Finding current running level index */ - if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, - freqs.old, relation, &priv_index)) { - ret = -EINVAL; - goto exit; - } - - arm_volt = dvs_conf[index].arm_volt; - int_volt = dvs_conf[index].int_volt; - - if (freqs.new > freqs.old) { - ret = regulator_set_voltage(arm_regulator, - arm_volt, arm_volt_max); - if (ret) - goto exit; - - ret = regulator_set_voltage(int_regulator, - int_volt, int_volt_max); - if (ret) - goto exit; - } - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - /* Check if there need to change PLL */ - if ((index == L0) || (priv_index == L0)) - pll_changing = 1; - - /* Check if there need to change System bus clock */ - if ((index == L4) || (priv_index == L4)) - bus_speed_changing = 1; - - if (bus_speed_changing) { - /* - * Reconfigure DRAM refresh counter value for minimum - * temporary clock while changing divider. - * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287 - */ - if (pll_changing) - s5pv210_set_refresh(DMC1, 83000); - else - s5pv210_set_refresh(DMC1, 100000); - - s5pv210_set_refresh(DMC0, 83000); - } - - /* - * APLL should be changed in this level - * APLL -> MPLL(for stable transition) -> APLL - * Some clock source's clock API are not prepared. - * Do not use clock API in below code. - */ - if (pll_changing) { - /* - * 1. Temporary Change divider for MFC and G3D - * SCLKA2M(200/1=200)->(200/4=50)Mhz - */ - reg = __raw_readl(S5P_CLK_DIV2); - reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK); - reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) | - (3 << S5P_CLKDIV2_MFC_SHIFT); - __raw_writel(reg, S5P_CLK_DIV2); - - /* For MFC, G3D dividing */ - do { - reg = __raw_readl(S5P_CLKDIV_STAT0); - } while (reg & ((1 << 16) | (1 << 17))); - - /* - * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX - * (200/4=50)->(667/4=166)Mhz - */ - reg = __raw_readl(S5P_CLK_SRC2); - reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK); - reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) | - (1 << S5P_CLKSRC2_MFC_SHIFT); - __raw_writel(reg, S5P_CLK_SRC2); - - do { - reg = __raw_readl(S5P_CLKMUX_STAT1); - } while (reg & ((1 << 7) | (1 << 3))); - - /* - * 3. DMC1 refresh count for 133Mhz if (index == L4) is - * true refresh counter is already programed in upper - * code. 0x287@83Mhz - */ - if (!bus_speed_changing) - s5pv210_set_refresh(DMC1, 133000); - - /* 4. SCLKAPLL -> SCLKMPLL */ - reg = __raw_readl(S5P_CLK_SRC0); - reg &= ~(S5P_CLKSRC0_MUX200_MASK); - reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT); - __raw_writel(reg, S5P_CLK_SRC0); - - do { - reg = __raw_readl(S5P_CLKMUX_STAT0); - } while (reg & (0x1 << 18)); - - } - - /* Change divider */ - reg = __raw_readl(S5P_CLK_DIV0); - - reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK | - S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK | - S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK | - S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK); - - reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) | - (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) | - (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) | - (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) | - (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) | - (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) | - (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) | - (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT)); - - __raw_writel(reg, S5P_CLK_DIV0); - - do { - reg = __raw_readl(S5P_CLKDIV_STAT0); - } while (reg & 0xff); - - /* ARM MCS value changed */ - reg = __raw_readl(S5P_ARM_MCS_CON); - reg &= ~0x3; - if (index >= L3) - reg |= 0x3; - else - reg |= 0x1; - - __raw_writel(reg, S5P_ARM_MCS_CON); - - if (pll_changing) { - /* 5. Set Lock time = 30us*24Mhz = 0x2cf */ - __raw_writel(0x2cf, S5P_APLL_LOCK); - - /* - * 6. Turn on APLL - * 6-1. Set PMS values - * 6-2. Wait untile the PLL is locked - */ - if (index == L0) - __raw_writel(APLL_VAL_1000, S5P_APLL_CON); - else - __raw_writel(APLL_VAL_800, S5P_APLL_CON); - - do { - reg = __raw_readl(S5P_APLL_CON); - } while (!(reg & (0x1 << 29))); - - /* - * 7. Change souce clock from SCLKMPLL(667Mhz) - * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX - * (667/4=166)->(200/4=50)Mhz - */ - reg = __raw_readl(S5P_CLK_SRC2); - reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK); - reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) | - (0 << S5P_CLKSRC2_MFC_SHIFT); - __raw_writel(reg, S5P_CLK_SRC2); - - do { - reg = __raw_readl(S5P_CLKMUX_STAT1); - } while (reg & ((1 << 7) | (1 << 3))); - - /* - * 8. Change divider for MFC and G3D - * (200/4=50)->(200/1=200)Mhz - */ - reg = __raw_readl(S5P_CLK_DIV2); - reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK); - reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) | - (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT); - __raw_writel(reg, S5P_CLK_DIV2); - - /* For MFC, G3D dividing */ - do { - reg = __raw_readl(S5P_CLKDIV_STAT0); - } while (reg & ((1 << 16) | (1 << 17))); - - /* 9. Change MPLL to APLL in MSYS_MUX */ - reg = __raw_readl(S5P_CLK_SRC0); - reg &= ~(S5P_CLKSRC0_MUX200_MASK); - reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT); - __raw_writel(reg, S5P_CLK_SRC0); - - do { - reg = __raw_readl(S5P_CLKMUX_STAT0); - } while (reg & (0x1 << 18)); - - /* - * 10. DMC1 refresh counter - * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c - * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618 - */ - if (!bus_speed_changing) - s5pv210_set_refresh(DMC1, 200000); - } - - /* - * L4 level need to change memory bus speed, hence onedram clock divier - * and memory refresh parameter should be changed - */ - if (bus_speed_changing) { - reg = __raw_readl(S5P_CLK_DIV6); - reg &= ~S5P_CLKDIV6_ONEDRAM_MASK; - reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT); - __raw_writel(reg, S5P_CLK_DIV6); - - do { - reg = __raw_readl(S5P_CLKDIV_STAT1); - } while (reg & (1 << 15)); - - /* Reconfigure DRAM refresh counter value */ - if (index != L4) { - /* - * DMC0 : 166Mhz - * DMC1 : 200Mhz - */ - s5pv210_set_refresh(DMC0, 166000); - s5pv210_set_refresh(DMC1, 200000); - } else { - /* - * DMC0 : 83Mhz - * DMC1 : 100Mhz - */ - s5pv210_set_refresh(DMC0, 83000); - s5pv210_set_refresh(DMC1, 100000); - } - } - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - if (freqs.new < freqs.old) { - regulator_set_voltage(int_regulator, - int_volt, int_volt_max); - - regulator_set_voltage(arm_regulator, - arm_volt, arm_volt_max); - } - - printk(KERN_DEBUG "Perf changed[L%d]\n", index); - -exit: - mutex_unlock(&set_freq_lock); - return ret; -} - -#ifdef CONFIG_PM -static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy) -{ - return 0; -} - -static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy) -{ - return 0; -} -#endif - -static int check_mem_type(void __iomem *dmc_reg) -{ - unsigned long val; - - val = __raw_readl(dmc_reg + 0x4); - val = (val & (0xf << 8)); - - return val >> 8; -} - -static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) -{ - unsigned long mem_type; - int ret; - - cpu_clk = clk_get(NULL, "armclk"); - if (IS_ERR(cpu_clk)) - return PTR_ERR(cpu_clk); - - dmc0_clk = clk_get(NULL, "sclk_dmc0"); - if (IS_ERR(dmc0_clk)) { - ret = PTR_ERR(dmc0_clk); - goto out_dmc0; - } - - dmc1_clk = clk_get(NULL, "hclk_msys"); - if (IS_ERR(dmc1_clk)) { - ret = PTR_ERR(dmc1_clk); - goto out_dmc1; - } - - if (policy->cpu != 0) { - ret = -EINVAL; - goto out_dmc1; - } - - /* - * check_mem_type : This driver only support LPDDR & LPDDR2. - * other memory type is not supported. - */ - mem_type = check_mem_type(S5P_VA_DMC0); - - if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { - printk(KERN_ERR "CPUFreq doesn't support this memory type\n"); - ret = -EINVAL; - goto out_dmc1; - } - - /* Find current refresh counter and frequency each DMC */ - s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000); - s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk); - - s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000); - s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk); - - policy->cur = policy->min = policy->max = s5pv210_getspeed(0); - - cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu); - - policy->cpuinfo.transition_latency = 40000; - - return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table); - -out_dmc1: - clk_put(dmc0_clk); -out_dmc0: - clk_put(cpu_clk); - return ret; -} - -static int s5pv210_cpufreq_notifier_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - int ret; - - switch (event) { - case PM_SUSPEND_PREPARE: - ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - DISABLE_FURTHER_CPUFREQ); - if (ret < 0) - return NOTIFY_BAD; - - return NOTIFY_OK; - case PM_POST_RESTORE: - case PM_POST_SUSPEND: - cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - ENABLE_FURTHER_CPUFREQ); - - return NOTIFY_OK; - } - - return NOTIFY_DONE; -} - -static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - int ret; - - ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, - DISABLE_FURTHER_CPUFREQ); - if (ret < 0) - return NOTIFY_BAD; - - return NOTIFY_DONE; -} - -static struct cpufreq_driver s5pv210_driver = { - .flags = CPUFREQ_STICKY, - .verify = s5pv210_verify_speed, - .target = s5pv210_target, - .get = s5pv210_getspeed, - .init = s5pv210_cpu_init, - .name = "s5pv210", -#ifdef CONFIG_PM - .suspend = s5pv210_cpufreq_suspend, - .resume = s5pv210_cpufreq_resume, -#endif -}; - -static struct notifier_block s5pv210_cpufreq_notifier = { - .notifier_call = s5pv210_cpufreq_notifier_event, -}; - -static struct notifier_block s5pv210_cpufreq_reboot_notifier = { - .notifier_call = s5pv210_cpufreq_reboot_notifier_event, -}; - -static int __init s5pv210_cpufreq_init(void) -{ - arm_regulator = regulator_get(NULL, "vddarm"); - if (IS_ERR(arm_regulator)) { - pr_err("failed to get regulator vddarm"); - return PTR_ERR(arm_regulator); - } - - int_regulator = regulator_get(NULL, "vddint"); - if (IS_ERR(int_regulator)) { - pr_err("failed to get regulator vddint"); - regulator_put(arm_regulator); - return PTR_ERR(int_regulator); - } - - register_pm_notifier(&s5pv210_cpufreq_notifier); - register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier); - - return cpufreq_register_driver(&s5pv210_driver); -} - -late_initcall(s5pv210_cpufreq_init); diff --git a/linux-3.4/drivers/cpufreq.new/sc520_freq.c b/linux-3.4/drivers/cpufreq.new/sc520_freq.c deleted file mode 100644 index e42e073c..00000000 --- a/linux-3.4/drivers/cpufreq.new/sc520_freq.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * sc520_freq.c: cpufreq driver for the AMD Elan sc520 - * - * Copyright (C) 2005 Sean Young - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Based on elanfreq.c - * - * 2005-03-30: - initial revision - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#define MMCR_BASE 0xfffef000 /* The default base address */ -#define OFFS_CPUCTL 0x2 /* CPU Control Register */ - -static __u8 __iomem *cpuctl; - -#define PFX "sc520_freq: " - -static struct cpufreq_frequency_table sc520_freq_table[] = { - {0x01, 100000}, - {0x02, 133000}, - {0, CPUFREQ_TABLE_END}, -}; - -static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) -{ - u8 clockspeed_reg = *cpuctl; - - switch (clockspeed_reg & 0x03) { - default: - printk(KERN_ERR PFX "error: cpuctl register has unexpected " - "value %02x\n", clockspeed_reg); - case 0x01: - return 100000; - case 0x02: - return 133000; - } -} - -static void sc520_freq_set_cpu_state(unsigned int state) -{ - - struct cpufreq_freqs freqs; - u8 clockspeed_reg; - - freqs.old = sc520_freq_get_cpu_frequency(0); - freqs.new = sc520_freq_table[state].frequency; - freqs.cpu = 0; /* AMD Elan is UP */ - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - pr_debug("attempting to set frequency to %i kHz\n", - sc520_freq_table[state].frequency); - - local_irq_disable(); - - clockspeed_reg = *cpuctl & ~0x03; - *cpuctl = clockspeed_reg | sc520_freq_table[state].index; - - local_irq_enable(); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -}; - -static int sc520_freq_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); -} - -static int sc520_freq_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - - if (cpufreq_frequency_table_target(policy, sc520_freq_table, - target_freq, relation, &newstate)) - return -EINVAL; - - sc520_freq_set_cpu_state(newstate); - - return 0; -} - - -/* - * Module init and exit code - */ - -static int sc520_freq_cpu_init(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - int result; - - /* capability check */ - if (c->x86_vendor != X86_VENDOR_AMD || - c->x86 != 4 || c->x86_model != 9) - return -ENODEV; - - /* cpuinfo and default policy values */ - policy->cpuinfo.transition_latency = 1000000; /* 1ms */ - policy->cur = sc520_freq_get_cpu_frequency(0); - - result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); - if (result) - return result; - - cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); - - return 0; -} - - -static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - - -static struct freq_attr *sc520_freq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - - -static struct cpufreq_driver sc520_freq_driver = { - .get = sc520_freq_get_cpu_frequency, - .verify = sc520_freq_verify, - .target = sc520_freq_target, - .init = sc520_freq_cpu_init, - .exit = sc520_freq_cpu_exit, - .name = "sc520_freq", - .owner = THIS_MODULE, - .attr = sc520_freq_attr, -}; - -static const struct x86_cpu_id sc520_ids[] = { - { X86_VENDOR_AMD, 4, 9 }, - {} -}; -MODULE_DEVICE_TABLE(x86cpu, sc520_ids); - -static int __init sc520_freq_init(void) -{ - int err; - - if (!x86_match_cpu(sc520_ids)) - return -ENODEV; - - cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); - if (!cpuctl) { - printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); - return -ENOMEM; - } - - err = cpufreq_register_driver(&sc520_freq_driver); - if (err) - iounmap(cpuctl); - - return err; -} - - -static void __exit sc520_freq_exit(void) -{ - cpufreq_unregister_driver(&sc520_freq_driver); - iounmap(cpuctl); -} - - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Sean Young "); -MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU"); - -module_init(sc520_freq_init); -module_exit(sc520_freq_exit); - diff --git a/linux-3.4/drivers/cpufreq.new/speedstep-centrino.c b/linux-3.4/drivers/cpufreq.new/speedstep-centrino.c deleted file mode 100644 index 3a953d51..00000000 --- a/linux-3.4/drivers/cpufreq.new/speedstep-centrino.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium - * M (part of the Centrino chipset). - * - * Since the original Pentium M, most new Intel CPUs support Enhanced - * SpeedStep. - * - * Despite the "SpeedStep" in the name, this is almost entirely unlike - * traditional SpeedStep. - * - * Modelled on speedstep.c - * - * Copyright (C) 2003 Jeremy Fitzhardinge - */ - -#include -#include -#include -#include -#include /* current */ -#include -#include -#include - -#include -#include -#include -#include - -#define PFX "speedstep-centrino: " -#define MAINTAINER "cpufreq@vger.kernel.org" - -#define INTEL_MSR_RANGE (0xffff) - -struct cpu_id -{ - __u8 x86; /* CPU family */ - __u8 x86_model; /* model */ - __u8 x86_mask; /* stepping */ -}; - -enum { - CPU_BANIAS, - CPU_DOTHAN_A1, - CPU_DOTHAN_A2, - CPU_DOTHAN_B0, - CPU_MP4HT_D0, - CPU_MP4HT_E0, -}; - -static const struct cpu_id cpu_ids[] = { - [CPU_BANIAS] = { 6, 9, 5 }, - [CPU_DOTHAN_A1] = { 6, 13, 1 }, - [CPU_DOTHAN_A2] = { 6, 13, 2 }, - [CPU_DOTHAN_B0] = { 6, 13, 6 }, - [CPU_MP4HT_D0] = {15, 3, 4 }, - [CPU_MP4HT_E0] = {15, 4, 1 }, -}; -#define N_IDS ARRAY_SIZE(cpu_ids) - -struct cpu_model -{ - const struct cpu_id *cpu_id; - const char *model_name; - unsigned max_freq; /* max clock in kHz */ - - struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */ -}; -static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, - const struct cpu_id *x); - -/* Operating points for current CPU */ -static DEFINE_PER_CPU(struct cpu_model *, centrino_model); -static DEFINE_PER_CPU(const struct cpu_id *, centrino_cpu); - -static struct cpufreq_driver centrino_driver; - -#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE - -/* Computes the correct form for IA32_PERF_CTL MSR for a particular - frequency/voltage operating point; frequency in MHz, volts in mV. - This is stored as "index" in the structure. */ -#define OP(mhz, mv) \ - { \ - .frequency = (mhz) * 1000, \ - .index = (((mhz)/100) << 8) | ((mv - 700) / 16) \ - } - -/* - * These voltage tables were derived from the Intel Pentium M - * datasheet, document 25261202.pdf, Table 5. I have verified they - * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium - * M. - */ - -/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */ -static struct cpufreq_frequency_table banias_900[] = -{ - OP(600, 844), - OP(800, 988), - OP(900, 1004), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */ -static struct cpufreq_frequency_table banias_1000[] = -{ - OP(600, 844), - OP(800, 972), - OP(900, 988), - OP(1000, 1004), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */ -static struct cpufreq_frequency_table banias_1100[] = -{ - OP( 600, 956), - OP( 800, 1020), - OP( 900, 1100), - OP(1000, 1164), - OP(1100, 1180), - { .frequency = CPUFREQ_TABLE_END } -}; - - -/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */ -static struct cpufreq_frequency_table banias_1200[] = -{ - OP( 600, 956), - OP( 800, 1004), - OP( 900, 1020), - OP(1000, 1100), - OP(1100, 1164), - OP(1200, 1180), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Intel Pentium M processor 1.30GHz (Banias) */ -static struct cpufreq_frequency_table banias_1300[] = -{ - OP( 600, 956), - OP( 800, 1260), - OP(1000, 1292), - OP(1200, 1356), - OP(1300, 1388), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Intel Pentium M processor 1.40GHz (Banias) */ -static struct cpufreq_frequency_table banias_1400[] = -{ - OP( 600, 956), - OP( 800, 1180), - OP(1000, 1308), - OP(1200, 1436), - OP(1400, 1484), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Intel Pentium M processor 1.50GHz (Banias) */ -static struct cpufreq_frequency_table banias_1500[] = -{ - OP( 600, 956), - OP( 800, 1116), - OP(1000, 1228), - OP(1200, 1356), - OP(1400, 1452), - OP(1500, 1484), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Intel Pentium M processor 1.60GHz (Banias) */ -static struct cpufreq_frequency_table banias_1600[] = -{ - OP( 600, 956), - OP( 800, 1036), - OP(1000, 1164), - OP(1200, 1276), - OP(1400, 1420), - OP(1600, 1484), - { .frequency = CPUFREQ_TABLE_END } -}; - -/* Intel Pentium M processor 1.70GHz (Banias) */ -static struct cpufreq_frequency_table banias_1700[] = -{ - OP( 600, 956), - OP( 800, 1004), - OP(1000, 1116), - OP(1200, 1228), - OP(1400, 1308), - OP(1700, 1484), - { .frequency = CPUFREQ_TABLE_END } -}; -#undef OP - -#define _BANIAS(cpuid, max, name) \ -{ .cpu_id = cpuid, \ - .model_name = "Intel(R) Pentium(R) M processor " name "MHz", \ - .max_freq = (max)*1000, \ - .op_points = banias_##max, \ -} -#define BANIAS(max) _BANIAS(&cpu_ids[CPU_BANIAS], max, #max) - -/* CPU models, their operating frequency range, and freq/voltage - operating points */ -static struct cpu_model models[] = -{ - _BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"), - BANIAS(1000), - BANIAS(1100), - BANIAS(1200), - BANIAS(1300), - BANIAS(1400), - BANIAS(1500), - BANIAS(1600), - BANIAS(1700), - - /* NULL model_name is a wildcard */ - { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, - { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, - { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, - { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, - { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, - - { NULL, } -}; -#undef _BANIAS -#undef BANIAS - -static int centrino_cpu_init_table(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu); - struct cpu_model *model; - - for(model = models; model->cpu_id != NULL; model++) - if (centrino_verify_cpu_id(cpu, model->cpu_id) && - (model->model_name == NULL || - strcmp(cpu->x86_model_id, model->model_name) == 0)) - break; - - if (model->cpu_id == NULL) { - /* No match at all */ - pr_debug("no support for CPU model \"%s\": " - "send /proc/cpuinfo to " MAINTAINER "\n", - cpu->x86_model_id); - return -ENOENT; - } - - if (model->op_points == NULL) { - /* Matched a non-match */ - pr_debug("no table support for CPU model \"%s\"\n", - cpu->x86_model_id); - pr_debug("try using the acpi-cpufreq driver\n"); - return -ENOENT; - } - - per_cpu(centrino_model, policy->cpu) = model; - - pr_debug("found \"%s\": max frequency: %dkHz\n", - model->model_name, model->max_freq); - - return 0; -} - -#else -static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) -{ - return -ENODEV; -} -#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */ - -static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, - const struct cpu_id *x) -{ - if ((c->x86 == x->x86) && - (c->x86_model == x->x86_model) && - (c->x86_mask == x->x86_mask)) - return 1; - return 0; -} - -/* To be called only after centrino_model is initialized */ -static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe) -{ - int i; - - /* - * Extract clock in kHz from PERF_CTL value - * for centrino, as some DSDTs are buggy. - * Ideally, this can be done using the acpi_data structure. - */ - if ((per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_BANIAS]) || - (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A1]) || - (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_B0])) { - msr = (msr >> 8) & 0xff; - return msr * 100000; - } - - if ((!per_cpu(centrino_model, cpu)) || - (!per_cpu(centrino_model, cpu)->op_points)) - return 0; - - msr &= 0xffff; - for (i = 0; - per_cpu(centrino_model, cpu)->op_points[i].frequency - != CPUFREQ_TABLE_END; - i++) { - if (msr == per_cpu(centrino_model, cpu)->op_points[i].index) - return per_cpu(centrino_model, cpu)-> - op_points[i].frequency; - } - if (failsafe) - return per_cpu(centrino_model, cpu)->op_points[i-1].frequency; - else - return 0; -} - -/* Return the current CPU frequency in kHz */ -static unsigned int get_cur_freq(unsigned int cpu) -{ - unsigned l, h; - unsigned clock_freq; - - rdmsr_on_cpu(cpu, MSR_IA32_PERF_STATUS, &l, &h); - clock_freq = extract_clock(l, cpu, 0); - - if (unlikely(clock_freq == 0)) { - /* - * On some CPUs, we can see transient MSR values (which are - * not present in _PSS), while CPU is doing some automatic - * P-state transition (like TM2). Get the last freq set - * in PERF_CTL. - */ - rdmsr_on_cpu(cpu, MSR_IA32_PERF_CTL, &l, &h); - clock_freq = extract_clock(l, cpu, 1); - } - return clock_freq; -} - - -static int centrino_cpu_init(struct cpufreq_policy *policy) -{ - struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu); - unsigned freq; - unsigned l, h; - int ret; - int i; - - /* Only Intel makes Enhanced Speedstep-capable CPUs */ - if (cpu->x86_vendor != X86_VENDOR_INTEL || - !cpu_has(cpu, X86_FEATURE_EST)) - return -ENODEV; - - if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) - centrino_driver.flags |= CPUFREQ_CONST_LOOPS; - - if (policy->cpu != 0) - return -ENODEV; - - for (i = 0; i < N_IDS; i++) - if (centrino_verify_cpu_id(cpu, &cpu_ids[i])) - break; - - if (i != N_IDS) - per_cpu(centrino_cpu, policy->cpu) = &cpu_ids[i]; - - if (!per_cpu(centrino_cpu, policy->cpu)) { - pr_debug("found unsupported CPU with " - "Enhanced SpeedStep: send /proc/cpuinfo to " - MAINTAINER "\n"); - return -ENODEV; - } - - if (centrino_cpu_init_table(policy)) { - return -ENODEV; - } - - /* Check to see if Enhanced SpeedStep is enabled, and try to - enable it if not. */ - rdmsr(MSR_IA32_MISC_ENABLE, l, h); - - if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { - l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP; - pr_debug("trying to enable Enhanced SpeedStep (%x)\n", l); - wrmsr(MSR_IA32_MISC_ENABLE, l, h); - - /* check to see if it stuck */ - rdmsr(MSR_IA32_MISC_ENABLE, l, h); - if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { - printk(KERN_INFO PFX - "couldn't enable Enhanced SpeedStep\n"); - return -ENODEV; - } - } - - freq = get_cur_freq(policy->cpu); - policy->cpuinfo.transition_latency = 10000; - /* 10uS transition latency */ - policy->cur = freq; - - pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur); - - ret = cpufreq_frequency_table_cpuinfo(policy, - per_cpu(centrino_model, policy->cpu)->op_points); - if (ret) - return (ret); - - cpufreq_frequency_table_get_attr( - per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu); - - return 0; -} - -static int centrino_cpu_exit(struct cpufreq_policy *policy) -{ - unsigned int cpu = policy->cpu; - - if (!per_cpu(centrino_model, cpu)) - return -ENODEV; - - cpufreq_frequency_table_put_attr(cpu); - - per_cpu(centrino_model, cpu) = NULL; - - return 0; -} - -/** - * centrino_verify - verifies a new CPUFreq policy - * @policy: new policy - * - * Limit must be within this model's frequency range at least one - * border included. - */ -static int centrino_verify (struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, - per_cpu(centrino_model, policy->cpu)->op_points); -} - -/** - * centrino_setpolicy - set a new CPUFreq policy - * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) - * - * Sets a new CPUFreq policy. - */ -static int centrino_target (struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0; - unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; - struct cpufreq_freqs freqs; - int retval = 0; - unsigned int j, k, first_cpu, tmp; - cpumask_var_t covered_cpus; - - if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) - return -ENOMEM; - - if (unlikely(per_cpu(centrino_model, cpu) == NULL)) { - retval = -ENODEV; - goto out; - } - - if (unlikely(cpufreq_frequency_table_target(policy, - per_cpu(centrino_model, cpu)->op_points, - target_freq, - relation, - &newstate))) { - retval = -EINVAL; - goto out; - } - - first_cpu = 1; - for_each_cpu(j, policy->cpus) { - int good_cpu; - - /* cpufreq holds the hotplug lock, so we are safe here */ - if (!cpu_online(j)) - continue; - - /* - * Support for SMP systems. - * Make sure we are running on CPU that wants to change freq - */ - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - good_cpu = cpumask_any_and(policy->cpus, - cpu_online_mask); - else - good_cpu = j; - - if (good_cpu >= nr_cpu_ids) { - pr_debug("couldn't limit to CPUs in this domain\n"); - retval = -EAGAIN; - if (first_cpu) { - /* We haven't started the transition yet. */ - goto out; - } - break; - } - - msr = per_cpu(centrino_model, cpu)->op_points[newstate].index; - - if (first_cpu) { - rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); - if (msr == (oldmsr & 0xffff)) { - pr_debug("no change needed - msr was and needs " - "to be %x\n", oldmsr); - retval = 0; - goto out; - } - - freqs.old = extract_clock(oldmsr, cpu, 0); - freqs.new = extract_clock(msr, cpu, 0); - - pr_debug("target=%dkHz old=%d new=%d msr=%04x\n", - target_freq, freqs.old, freqs.new, msr); - - for_each_cpu(k, policy->cpus) { - if (!cpu_online(k)) - continue; - freqs.cpu = k; - cpufreq_notify_transition(&freqs, - CPUFREQ_PRECHANGE); - } - - first_cpu = 0; - /* all but 16 LSB are reserved, treat them with care */ - oldmsr &= ~0xffff; - msr &= 0xffff; - oldmsr |= msr; - } - - wrmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, oldmsr, h); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) - break; - - cpumask_set_cpu(j, covered_cpus); - } - - for_each_cpu(k, policy->cpus) { - if (!cpu_online(k)) - continue; - freqs.cpu = k; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - - if (unlikely(retval)) { - /* - * We have failed halfway through the frequency change. - * We have sent callbacks to policy->cpus and - * MSRs have already been written on coverd_cpus. - * Best effort undo.. - */ - - for_each_cpu(j, covered_cpus) - wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h); - - tmp = freqs.new; - freqs.new = freqs.old; - freqs.old = tmp; - for_each_cpu(j, policy->cpus) { - if (!cpu_online(j)) - continue; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - } - retval = 0; - -out: - free_cpumask_var(covered_cpus); - return retval; -} - -static struct freq_attr* centrino_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver centrino_driver = { - .name = "centrino", /* should be speedstep-centrino, - but there's a 16 char limit */ - .init = centrino_cpu_init, - .exit = centrino_cpu_exit, - .verify = centrino_verify, - .target = centrino_target, - .get = get_cur_freq, - .attr = centrino_attr, - .owner = THIS_MODULE, -}; - -/* - * This doesn't replace the detailed checks above because - * the generic CPU IDs don't have a way to match for steppings - * or ASCII model IDs. - */ -static const struct x86_cpu_id centrino_ids[] = { - { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST }, - { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST }, - {} -}; -#if 0 -/* Autoload or not? Do not for now. */ -MODULE_DEVICE_TABLE(x86cpu, centrino_ids); -#endif - -/** - * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver - * - * Initializes the Enhanced SpeedStep support. Returns -ENODEV on - * unsupported devices, -ENOENT if there's no voltage table for this - * particular CPU model, -EINVAL on problems during initiatization, - * and zero on success. - * - * This is quite picky. Not only does the CPU have to advertise the - * "est" flag in the cpuid capability flags, we look for a specific - * CPU model and stepping, and we need to have the exact model name in - * our voltage tables. That is, be paranoid about not releasing - * someone's valuable magic smoke. - */ -static int __init centrino_init(void) -{ - if (!x86_match_cpu(centrino_ids)) - return -ENODEV; - return cpufreq_register_driver(¢rino_driver); -} - -static void __exit centrino_exit(void) -{ - cpufreq_unregister_driver(¢rino_driver); -} - -MODULE_AUTHOR ("Jeremy Fitzhardinge "); -MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors."); -MODULE_LICENSE ("GPL"); - -late_initcall(centrino_init); -module_exit(centrino_exit); diff --git a/linux-3.4/drivers/cpufreq.new/speedstep-ich.c b/linux-3.4/drivers/cpufreq.new/speedstep-ich.c deleted file mode 100644 index 7432b3a7..00000000 --- a/linux-3.4/drivers/cpufreq.new/speedstep-ich.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * (C) 2001 Dave Jones, Arjan van de ven. - * (C) 2002 - 2003 Dominik Brodowski - * - * Licensed under the terms of the GNU GPL License version 2. - * Based upon reverse engineered information, and on Intel documentation - * for chipsets ICH2-M and ICH3-M. - * - * Many thanks to Ducrot Bruno for finding and fixing the last - * "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler - * for extensive testing. - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - - -/********************************************************************* - * SPEEDSTEP - DEFINITIONS * - *********************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include - -#include "speedstep-lib.h" - - -/* speedstep_chipset: - * It is necessary to know which chipset is used. As accesses to - * this device occur at various places in this module, we need a - * static struct pci_dev * pointing to that device. - */ -static struct pci_dev *speedstep_chipset_dev; - - -/* speedstep_processor - */ -static enum speedstep_processor speedstep_processor; - -static u32 pmbase; - -/* - * There are only two frequency states for each processor. Values - * are in kHz for the time being. - */ -static struct cpufreq_frequency_table speedstep_freqs[] = { - {SPEEDSTEP_HIGH, 0}, - {SPEEDSTEP_LOW, 0}, - {0, CPUFREQ_TABLE_END}, -}; - - -/** - * speedstep_find_register - read the PMBASE address - * - * Returns: -ENODEV if no register could be found - */ -static int speedstep_find_register(void) -{ - if (!speedstep_chipset_dev) - return -ENODEV; - - /* get PMBASE */ - pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); - if (!(pmbase & 0x01)) { - printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); - return -ENODEV; - } - - pmbase &= 0xFFFFFFFE; - if (!pmbase) { - printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); - return -ENODEV; - } - - pr_debug("pmbase is 0x%x\n", pmbase); - return 0; -} - -/** - * speedstep_set_state - set the SpeedStep state - * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * - * Tries to change the SpeedStep state. Can be called from - * smp_call_function_single. - */ -static void speedstep_set_state(unsigned int state) -{ - u8 pm2_blk; - u8 value; - unsigned long flags; - - if (state > 0x1) - return; - - /* Disable IRQs */ - local_irq_save(flags); - - /* read state */ - value = inb(pmbase + 0x50); - - pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); - - /* write new state */ - value &= 0xFE; - value |= state; - - pr_debug("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); - - /* Disable bus master arbitration */ - pm2_blk = inb(pmbase + 0x20); - pm2_blk |= 0x01; - outb(pm2_blk, (pmbase + 0x20)); - - /* Actual transition */ - outb(value, (pmbase + 0x50)); - - /* Restore bus master arbitration */ - pm2_blk &= 0xfe; - outb(pm2_blk, (pmbase + 0x20)); - - /* check if transition was successful */ - value = inb(pmbase + 0x50); - - /* Enable IRQs */ - local_irq_restore(flags); - - pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); - - if (state == (value & 0x1)) - pr_debug("change to %u MHz succeeded\n", - speedstep_get_frequency(speedstep_processor) / 1000); - else - printk(KERN_ERR "cpufreq: change failed - I/O error\n"); - - return; -} - -/* Wrapper for smp_call_function_single. */ -static void _speedstep_set_state(void *_state) -{ - speedstep_set_state(*(unsigned int *)_state); -} - -/** - * speedstep_activate - activate SpeedStep control in the chipset - * - * Tries to activate the SpeedStep status and control registers. - * Returns -EINVAL on an unsupported chipset, and zero on success. - */ -static int speedstep_activate(void) -{ - u16 value = 0; - - if (!speedstep_chipset_dev) - return -EINVAL; - - pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value); - if (!(value & 0x08)) { - value |= 0x08; - pr_debug("activating SpeedStep (TM) registers\n"); - pci_write_config_word(speedstep_chipset_dev, 0x00A0, value); - } - - return 0; -} - - -/** - * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic - * - * Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to - * the LPC bridge / PM module which contains all power-management - * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected - * chipset, or zero on failure. - */ -static unsigned int speedstep_detect_chipset(void) -{ - speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82801DB_12, - PCI_ANY_ID, PCI_ANY_ID, - NULL); - if (speedstep_chipset_dev) - return 4; /* 4-M */ - - speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82801CA_12, - PCI_ANY_ID, PCI_ANY_ID, - NULL); - if (speedstep_chipset_dev) - return 3; /* 3-M */ - - - speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82801BA_10, - PCI_ANY_ID, PCI_ANY_ID, - NULL); - if (speedstep_chipset_dev) { - /* speedstep.c causes lockups on Dell Inspirons 8000 and - * 8100 which use a pretty old revision of the 82815 - * host brige. Abort on these systems. - */ - static struct pci_dev *hostbridge; - - hostbridge = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82815_MC, - PCI_ANY_ID, PCI_ANY_ID, - NULL); - - if (!hostbridge) - return 2; /* 2-M */ - - if (hostbridge->revision < 5) { - pr_debug("hostbridge does not support speedstep\n"); - speedstep_chipset_dev = NULL; - pci_dev_put(hostbridge); - return 0; - } - - pci_dev_put(hostbridge); - return 2; /* 2-M */ - } - - return 0; -} - -static void get_freq_data(void *_speed) -{ - unsigned int *speed = _speed; - - *speed = speedstep_get_frequency(speedstep_processor); -} - -static unsigned int speedstep_get(unsigned int cpu) -{ - unsigned int speed; - - /* You're supposed to ensure CPU is online. */ - if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0) - BUG(); - - pr_debug("detected %u kHz as current frequency\n", speed); - return speed; -} - -/** - * speedstep_target - set a new CPUFreq policy - * @policy: new policy - * @target_freq: the target frequency - * @relation: how that frequency relates to achieved frequency - * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) - * - * Sets a new CPUFreq policy. - */ -static int speedstep_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int newstate = 0, policy_cpu; - struct cpufreq_freqs freqs; - int i; - - if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], - target_freq, relation, &newstate)) - return -EINVAL; - - policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); - freqs.old = speedstep_get(policy_cpu); - freqs.new = speedstep_freqs[newstate].frequency; - freqs.cpu = policy->cpu; - - pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new); - - /* no transition necessary */ - if (freqs.old == freqs.new) - return 0; - - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate, - true); - - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - - return 0; -} - - -/** - * speedstep_verify - verifies a new CPUFreq policy - * @policy: new policy - * - * Limit must be within speedstep_low_freq and speedstep_high_freq, with - * at least one border included. - */ -static int speedstep_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); -} - -struct get_freqs { - struct cpufreq_policy *policy; - int ret; -}; - -static void get_freqs_on_cpu(void *_get_freqs) -{ - struct get_freqs *get_freqs = _get_freqs; - - get_freqs->ret = - speedstep_get_freqs(speedstep_processor, - &speedstep_freqs[SPEEDSTEP_LOW].frequency, - &speedstep_freqs[SPEEDSTEP_HIGH].frequency, - &get_freqs->policy->cpuinfo.transition_latency, - &speedstep_set_state); -} - -static int speedstep_cpu_init(struct cpufreq_policy *policy) -{ - int result; - unsigned int policy_cpu, speed; - struct get_freqs gf; - - /* only run on CPU to be set, or on its sibling */ -#ifdef CONFIG_SMP - cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); -#endif - policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); - - /* detect low and high frequency and transition latency */ - gf.policy = policy; - smp_call_function_single(policy_cpu, get_freqs_on_cpu, &gf, 1); - if (gf.ret) - return gf.ret; - - /* get current speed setting */ - speed = speedstep_get(policy_cpu); - if (!speed) - return -EIO; - - pr_debug("currently at %s speed setting - %i MHz\n", - (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) - ? "low" : "high", - (speed / 1000)); - - /* cpuinfo and default policy values */ - policy->cur = speed; - - result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); - if (result) - return result; - - cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); - - return 0; -} - - -static int speedstep_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - -static struct freq_attr *speedstep_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - - -static struct cpufreq_driver speedstep_driver = { - .name = "speedstep-ich", - .verify = speedstep_verify, - .target = speedstep_target, - .init = speedstep_cpu_init, - .exit = speedstep_cpu_exit, - .get = speedstep_get, - .owner = THIS_MODULE, - .attr = speedstep_attr, -}; - -static const struct x86_cpu_id ss_smi_ids[] = { - { X86_VENDOR_INTEL, 6, 0xb, }, - { X86_VENDOR_INTEL, 6, 0x8, }, - { X86_VENDOR_INTEL, 15, 2 }, - {} -}; -#if 0 -/* Autoload or not? Do not for now. */ -MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); -#endif - -/** - * speedstep_init - initializes the SpeedStep CPUFreq driver - * - * Initializes the SpeedStep support. Returns -ENODEV on unsupported - * devices, -EINVAL on problems during initiatization, and zero on - * success. - */ -static int __init speedstep_init(void) -{ - if (!x86_match_cpu(ss_smi_ids)) - return -ENODEV; - - /* detect processor */ - speedstep_processor = speedstep_detect_processor(); - if (!speedstep_processor) { - pr_debug("Intel(R) SpeedStep(TM) capable processor " - "not found\n"); - return -ENODEV; - } - - /* detect chipset */ - if (!speedstep_detect_chipset()) { - pr_debug("Intel(R) SpeedStep(TM) for this chipset not " - "(yet) available.\n"); - return -ENODEV; - } - - /* activate speedstep support */ - if (speedstep_activate()) { - pci_dev_put(speedstep_chipset_dev); - return -EINVAL; - } - - if (speedstep_find_register()) - return -ENODEV; - - return cpufreq_register_driver(&speedstep_driver); -} - - -/** - * speedstep_exit - unregisters SpeedStep support - * - * Unregisters SpeedStep support. - */ -static void __exit speedstep_exit(void) -{ - pci_dev_put(speedstep_chipset_dev); - cpufreq_unregister_driver(&speedstep_driver); -} - - -MODULE_AUTHOR("Dave Jones , " - "Dominik Brodowski "); -MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets " - "with ICH-M southbridges."); -MODULE_LICENSE("GPL"); - -module_init(speedstep_init); -module_exit(speedstep_exit); diff --git a/linux-3.4/drivers/cpufreq.new/speedstep-lib.c b/linux-3.4/drivers/cpufreq.new/speedstep-lib.c deleted file mode 100644 index 7047821a..00000000 --- a/linux-3.4/drivers/cpufreq.new/speedstep-lib.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * (C) 2002 - 2003 Dominik Brodowski - * - * Licensed under the terms of the GNU GPL License version 2. - * - * Library for common functions for Intel SpeedStep v.1 and v.2 support - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - -#include -#include -#include -#include -#include - -#include -#include -#include "speedstep-lib.h" - -#define PFX "speedstep-lib: " - -#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK -static int relaxed_check; -#else -#define relaxed_check 0 -#endif - -/********************************************************************* - * GET PROCESSOR CORE SPEED IN KHZ * - *********************************************************************/ - -static unsigned int pentium3_get_frequency(enum speedstep_processor processor) -{ - /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ - struct { - unsigned int ratio; /* Frequency Multiplier (x10) */ - u8 bitmap; /* power on configuration bits - [27, 25:22] (in MSR 0x2a) */ - } msr_decode_mult[] = { - { 30, 0x01 }, - { 35, 0x05 }, - { 40, 0x02 }, - { 45, 0x06 }, - { 50, 0x00 }, - { 55, 0x04 }, - { 60, 0x0b }, - { 65, 0x0f }, - { 70, 0x09 }, - { 75, 0x0d }, - { 80, 0x0a }, - { 85, 0x26 }, - { 90, 0x20 }, - { 100, 0x2b }, - { 0, 0xff } /* error or unknown value */ - }; - - /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ - struct { - unsigned int value; /* Front Side Bus speed in MHz */ - u8 bitmap; /* power on configuration bits [18: 19] - (in MSR 0x2a) */ - } msr_decode_fsb[] = { - { 66, 0x0 }, - { 100, 0x2 }, - { 133, 0x1 }, - { 0, 0xff} - }; - - u32 msr_lo, msr_tmp; - int i = 0, j = 0; - - /* read MSR 0x2a - we only need the low 32 bits */ - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); - msr_tmp = msr_lo; - - /* decode the FSB */ - msr_tmp &= 0x00c0000; - msr_tmp >>= 18; - while (msr_tmp != msr_decode_fsb[i].bitmap) { - if (msr_decode_fsb[i].bitmap == 0xff) - return 0; - i++; - } - - /* decode the multiplier */ - if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) { - pr_debug("workaround for early PIIIs\n"); - msr_lo &= 0x03c00000; - } else - msr_lo &= 0x0bc00000; - msr_lo >>= 22; - while (msr_lo != msr_decode_mult[j].bitmap) { - if (msr_decode_mult[j].bitmap == 0xff) - return 0; - j++; - } - - pr_debug("speed is %u\n", - (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100)); - - return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100; -} - - -static unsigned int pentiumM_get_frequency(void) -{ - u32 msr_lo, msr_tmp; - - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); - - /* see table B-2 of 24547212.pdf */ - if (msr_lo & 0x00040000) { - printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n", - msr_lo, msr_tmp); - return 0; - } - - msr_tmp = (msr_lo >> 22) & 0x1f; - pr_debug("bits 22-26 are 0x%x, speed is %u\n", - msr_tmp, (msr_tmp * 100 * 1000)); - - return msr_tmp * 100 * 1000; -} - -static unsigned int pentium_core_get_frequency(void) -{ - u32 fsb = 0; - u32 msr_lo, msr_tmp; - int ret; - - rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp); - /* see table B-2 of 25366920.pdf */ - switch (msr_lo & 0x07) { - case 5: - fsb = 100000; - break; - case 1: - fsb = 133333; - break; - case 3: - fsb = 166667; - break; - case 2: - fsb = 200000; - break; - case 0: - fsb = 266667; - break; - case 4: - fsb = 333333; - break; - default: - printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value"); - } - - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - pr_debug("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", - msr_lo, msr_tmp); - - msr_tmp = (msr_lo >> 22) & 0x1f; - pr_debug("bits 22-26 are 0x%x, speed is %u\n", - msr_tmp, (msr_tmp * fsb)); - - ret = (msr_tmp * fsb); - return ret; -} - - -static unsigned int pentium4_get_frequency(void) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - u32 msr_lo, msr_hi, mult; - unsigned int fsb = 0; - unsigned int ret; - u8 fsb_code; - - /* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency - * to System Bus Frequency Ratio Field in the Processor Frequency - * Configuration Register of the MSR. Therefore the current - * frequency cannot be calculated and has to be measured. - */ - if (c->x86_model < 2) - return cpu_khz; - - rdmsr(0x2c, msr_lo, msr_hi); - - pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); - - /* decode the FSB: see IA-32 Intel (C) Architecture Software - * Developer's Manual, Volume 3: System Prgramming Guide, - * revision #12 in Table B-1: MSRs in the Pentium 4 and - * Intel Xeon Processors, on page B-4 and B-5. - */ - fsb_code = (msr_lo >> 16) & 0x7; - switch (fsb_code) { - case 0: - fsb = 100 * 1000; - break; - case 1: - fsb = 13333 * 10; - break; - case 2: - fsb = 200 * 1000; - break; - } - - if (!fsb) - printk(KERN_DEBUG PFX "couldn't detect FSB speed. " - "Please send an e-mail to \n"); - - /* Multiplier. */ - mult = msr_lo >> 24; - - pr_debug("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", - fsb, mult, (fsb * mult)); - - ret = (fsb * mult); - return ret; -} - - -/* Warning: may get called from smp_call_function_single. */ -unsigned int speedstep_get_frequency(enum speedstep_processor processor) -{ - switch (processor) { - case SPEEDSTEP_CPU_PCORE: - return pentium_core_get_frequency(); - case SPEEDSTEP_CPU_PM: - return pentiumM_get_frequency(); - case SPEEDSTEP_CPU_P4D: - case SPEEDSTEP_CPU_P4M: - return pentium4_get_frequency(); - case SPEEDSTEP_CPU_PIII_T: - case SPEEDSTEP_CPU_PIII_C: - case SPEEDSTEP_CPU_PIII_C_EARLY: - return pentium3_get_frequency(processor); - default: - return 0; - }; - return 0; -} -EXPORT_SYMBOL_GPL(speedstep_get_frequency); - - -/********************************************************************* - * DETECT SPEEDSTEP-CAPABLE PROCESSOR * - *********************************************************************/ - -/* Keep in sync with the x86_cpu_id tables in the different modules */ -unsigned int speedstep_detect_processor(void) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - u32 ebx, msr_lo, msr_hi; - - pr_debug("x86: %x, model: %x\n", c->x86, c->x86_model); - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - ((c->x86 != 6) && (c->x86 != 0xF))) - return 0; - - if (c->x86 == 0xF) { - /* Intel Mobile Pentium 4-M - * or Intel Mobile Pentium 4 with 533 MHz FSB */ - if (c->x86_model != 2) - return 0; - - ebx = cpuid_ebx(0x00000001); - ebx &= 0x000000FF; - - pr_debug("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask); - - switch (c->x86_mask) { - case 4: - /* - * B-stepping [M-P4-M] - * sample has ebx = 0x0f, production has 0x0e. - */ - if ((ebx == 0x0e) || (ebx == 0x0f)) - return SPEEDSTEP_CPU_P4M; - break; - case 7: - /* - * C-stepping [M-P4-M] - * needs to have ebx=0x0e, else it's a celeron: - * cf. 25130917.pdf / page 7, footnote 5 even - * though 25072120.pdf / page 7 doesn't say - * samples are only of B-stepping... - */ - if (ebx == 0x0e) - return SPEEDSTEP_CPU_P4M; - break; - case 9: - /* - * D-stepping [M-P4-M or M-P4/533] - * - * this is totally strange: CPUID 0x0F29 is - * used by M-P4-M, M-P4/533 and(!) Celeron CPUs. - * The latter need to be sorted out as they don't - * support speedstep. - * Celerons with CPUID 0x0F29 may have either - * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything - * specific. - * M-P4-Ms may have either ebx=0xe or 0xf [see above] - * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf] - * also, M-P4M HTs have ebx=0x8, too - * For now, they are distinguished by the model_id - * string - */ - if ((ebx == 0x0e) || - (strstr(c->x86_model_id, - "Mobile Intel(R) Pentium(R) 4") != NULL)) - return SPEEDSTEP_CPU_P4M; - break; - default: - break; - } - return 0; - } - - switch (c->x86_model) { - case 0x0B: /* Intel PIII [Tualatin] */ - /* cpuid_ebx(1) is 0x04 for desktop PIII, - * 0x06 for mobile PIII-M */ - ebx = cpuid_ebx(0x00000001); - pr_debug("ebx is %x\n", ebx); - - ebx &= 0x000000FF; - - if (ebx != 0x06) - return 0; - - /* So far all PIII-M processors support SpeedStep. See - * Intel's 24540640.pdf of June 2003 - */ - return SPEEDSTEP_CPU_PIII_T; - - case 0x08: /* Intel PIII [Coppermine] */ - - /* all mobile PIII Coppermines have FSB 100 MHz - * ==> sort out a few desktop PIIIs. */ - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); - pr_debug("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", - msr_lo, msr_hi); - msr_lo &= 0x00c0000; - if (msr_lo != 0x0080000) - return 0; - - /* - * If the processor is a mobile version, - * platform ID has bit 50 set - * it has SpeedStep technology if either - * bit 56 or 57 is set - */ - rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); - pr_debug("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", - msr_lo, msr_hi); - if ((msr_hi & (1<<18)) && - (relaxed_check ? 1 : (msr_hi & (3<<24)))) { - if (c->x86_mask == 0x01) { - pr_debug("early PIII version\n"); - return SPEEDSTEP_CPU_PIII_C_EARLY; - } else - return SPEEDSTEP_CPU_PIII_C; - } - - default: - return 0; - } -} -EXPORT_SYMBOL_GPL(speedstep_detect_processor); - - -/********************************************************************* - * DETECT SPEEDSTEP SPEEDS * - *********************************************************************/ - -unsigned int speedstep_get_freqs(enum speedstep_processor processor, - unsigned int *low_speed, - unsigned int *high_speed, - unsigned int *transition_latency, - void (*set_state) (unsigned int state)) -{ - unsigned int prev_speed; - unsigned int ret = 0; - unsigned long flags; - struct timeval tv1, tv2; - - if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) - return -EINVAL; - - pr_debug("trying to determine both speeds\n"); - - /* get current speed */ - prev_speed = speedstep_get_frequency(processor); - if (!prev_speed) - return -EIO; - - pr_debug("previous speed is %u\n", prev_speed); - - local_irq_save(flags); - - /* switch to low state */ - set_state(SPEEDSTEP_LOW); - *low_speed = speedstep_get_frequency(processor); - if (!*low_speed) { - ret = -EIO; - goto out; - } - - pr_debug("low speed is %u\n", *low_speed); - - /* start latency measurement */ - if (transition_latency) - do_gettimeofday(&tv1); - - /* switch to high state */ - set_state(SPEEDSTEP_HIGH); - - /* end latency measurement */ - if (transition_latency) - do_gettimeofday(&tv2); - - *high_speed = speedstep_get_frequency(processor); - if (!*high_speed) { - ret = -EIO; - goto out; - } - - pr_debug("high speed is %u\n", *high_speed); - - if (*low_speed == *high_speed) { - ret = -ENODEV; - goto out; - } - - /* switch to previous state, if necessary */ - if (*high_speed != prev_speed) - set_state(SPEEDSTEP_LOW); - - if (transition_latency) { - *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC + - tv2.tv_usec - tv1.tv_usec; - pr_debug("transition latency is %u uSec\n", *transition_latency); - - /* convert uSec to nSec and add 20% for safety reasons */ - *transition_latency *= 1200; - - /* check if the latency measurement is too high or too low - * and set it to a safe value (500uSec) in that case - */ - if (*transition_latency > 10000000 || - *transition_latency < 50000) { - printk(KERN_WARNING PFX "frequency transition " - "measured seems out of range (%u " - "nSec), falling back to a safe one of" - "%u nSec.\n", - *transition_latency, 500000); - *transition_latency = 500000; - } - } - -out: - local_irq_restore(flags); - return ret; -} -EXPORT_SYMBOL_GPL(speedstep_get_freqs); - -#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK -module_param(relaxed_check, int, 0444); -MODULE_PARM_DESC(relaxed_check, - "Don't do all checks for speedstep capability."); -#endif - -MODULE_AUTHOR("Dominik Brodowski "); -MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers."); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/speedstep-lib.h b/linux-3.4/drivers/cpufreq.new/speedstep-lib.h deleted file mode 100644 index 70d9cea1..00000000 --- a/linux-3.4/drivers/cpufreq.new/speedstep-lib.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * (C) 2002 - 2003 Dominik Brodowski - * - * Licensed under the terms of the GNU GPL License version 2. - * - * Library for common functions for Intel SpeedStep v.1 and v.2 support - * - * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* - */ - - - -/* processors */ -enum speedstep_processor { - SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001, /* Coppermine core */ - SPEEDSTEP_CPU_PIII_C = 0x00000002, /* Coppermine core */ - SPEEDSTEP_CPU_PIII_T = 0x00000003, /* Tualatin core */ - SPEEDSTEP_CPU_P4M = 0x00000004, /* P4-M */ -/* the following processors are not speedstep-capable and are not auto-detected - * in speedstep_detect_processor(). However, their speed can be detected using - * the speedstep_get_frequency() call. */ - SPEEDSTEP_CPU_PM = 0xFFFFFF03, /* Pentium M */ - SPEEDSTEP_CPU_P4D = 0xFFFFFF04, /* desktop P4 */ - SPEEDSTEP_CPU_PCORE = 0xFFFFFF05, /* Core */ -}; - -/* speedstep states -- only two of them */ - -#define SPEEDSTEP_HIGH 0x00000000 -#define SPEEDSTEP_LOW 0x00000001 - - -/* detect a speedstep-capable processor */ -extern enum speedstep_processor speedstep_detect_processor(void); - -/* detect the current speed (in khz) of the processor */ -extern unsigned int speedstep_get_frequency(enum speedstep_processor processor); - - -/* detect the low and high speeds of the processor. The callback - * set_state"'s first argument is either SPEEDSTEP_HIGH or - * SPEEDSTEP_LOW; the second argument is zero so that no - * cpufreq_notify_transition calls are initiated. - */ -extern unsigned int speedstep_get_freqs(enum speedstep_processor processor, - unsigned int *low_speed, - unsigned int *high_speed, - unsigned int *transition_latency, - void (*set_state) (unsigned int state)); diff --git a/linux-3.4/drivers/cpufreq.new/speedstep-smi.c b/linux-3.4/drivers/cpufreq.new/speedstep-smi.c deleted file mode 100644 index 6a457fca..00000000 --- a/linux-3.4/drivers/cpufreq.new/speedstep-smi.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Intel SpeedStep SMI driver. - * - * (C) 2003 Hiroshi Miura - * - * Licensed under the terms of the GNU GPL License version 2. - * - */ - - -/********************************************************************* - * SPEEDSTEP - DEFINITIONS * - *********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "speedstep-lib.h" - -/* speedstep system management interface port/command. - * - * These parameters are got from IST-SMI BIOS call. - * If user gives it, these are used. - * - */ -static int smi_port; -static int smi_cmd; -static unsigned int smi_sig; - -/* info about the processor */ -static enum speedstep_processor speedstep_processor; - -/* - * There are only two frequency states for each processor. Values - * are in kHz for the time being. - */ -static struct cpufreq_frequency_table speedstep_freqs[] = { - {SPEEDSTEP_HIGH, 0}, - {SPEEDSTEP_LOW, 0}, - {0, CPUFREQ_TABLE_END}, -}; - -#define GET_SPEEDSTEP_OWNER 0 -#define GET_SPEEDSTEP_STATE 1 -#define SET_SPEEDSTEP_STATE 2 -#define GET_SPEEDSTEP_FREQS 4 - -/* how often shall the SMI call be tried if it failed, e.g. because - * of DMA activity going on? */ -#define SMI_TRIES 5 - -/** - * speedstep_smi_ownership - */ -static int speedstep_smi_ownership(void) -{ - u32 command, result, magic, dummy; - u32 function = GET_SPEEDSTEP_OWNER; - unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation"; - - command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - magic = virt_to_phys(magic_data); - - pr_debug("trying to obtain ownership with command %x at port %x\n", - command, smi_port); - - __asm__ __volatile__( - "push %%ebp\n" - "out %%al, (%%dx)\n" - "pop %%ebp\n" - : "=D" (result), - "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy), - "=S" (dummy) - : "a" (command), "b" (function), "c" (0), "d" (smi_port), - "D" (0), "S" (magic) - : "memory" - ); - - pr_debug("result is %x\n", result); - - return result; -} - -/** - * speedstep_smi_get_freqs - get SpeedStep preferred & current freq. - * @low: the low frequency value is placed here - * @high: the high frequency value is placed here - * - * Only available on later SpeedStep-enabled systems, returns false results or - * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing - * shows that the latter occurs if !(ist_info.event & 0xFFFF). - */ -static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high) -{ - u32 command, result = 0, edi, high_mhz, low_mhz, dummy; - u32 state = 0; - u32 function = GET_SPEEDSTEP_FREQS; - - if (!(ist_info.event & 0xFFFF)) { - pr_debug("bug #1422 -- can't read freqs from BIOS\n"); - return -ENODEV; - } - - command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - - pr_debug("trying to determine frequencies with command %x at port %x\n", - command, smi_port); - - __asm__ __volatile__( - "push %%ebp\n" - "out %%al, (%%dx)\n" - "pop %%ebp" - : "=a" (result), - "=b" (high_mhz), - "=c" (low_mhz), - "=d" (state), "=D" (edi), "=S" (dummy) - : "a" (command), - "b" (function), - "c" (state), - "d" (smi_port), "S" (0), "D" (0) - ); - - pr_debug("result %x, low_freq %u, high_freq %u\n", - result, low_mhz, high_mhz); - - /* abort if results are obviously incorrect... */ - if ((high_mhz + low_mhz) < 600) - return -EINVAL; - - *high = high_mhz * 1000; - *low = low_mhz * 1000; - - return result; -} - -/** - * speedstep_get_state - set the SpeedStep state - * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * - */ -static int speedstep_get_state(void) -{ - u32 function = GET_SPEEDSTEP_STATE; - u32 result, state, edi, command, dummy; - - command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - - pr_debug("trying to determine current setting with command %x " - "at port %x\n", command, smi_port); - - __asm__ __volatile__( - "push %%ebp\n" - "out %%al, (%%dx)\n" - "pop %%ebp\n" - : "=a" (result), - "=b" (state), "=D" (edi), - "=c" (dummy), "=d" (dummy), "=S" (dummy) - : "a" (command), "b" (function), "c" (0), - "d" (smi_port), "S" (0), "D" (0) - ); - - pr_debug("state is %x, result is %x\n", state, result); - - return state & 1; -} - - -/** - * speedstep_set_state - set the SpeedStep state - * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * - */ -static void speedstep_set_state(unsigned int state) -{ - unsigned int result = 0, command, new_state, dummy; - unsigned long flags; - unsigned int function = SET_SPEEDSTEP_STATE; - unsigned int retry = 0; - - if (state > 0x1) - return; - - /* Disable IRQs */ - local_irq_save(flags); - - command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); - - pr_debug("trying to set frequency to state %u " - "with command %x at port %x\n", - state, command, smi_port); - - do { - if (retry) { - pr_debug("retry %u, previous result %u, waiting...\n", - retry, result); - mdelay(retry * 50); - } - retry++; - __asm__ __volatile__( - "push %%ebp\n" - "out %%al, (%%dx)\n" - "pop %%ebp" - : "=b" (new_state), "=D" (result), - "=c" (dummy), "=a" (dummy), - "=d" (dummy), "=S" (dummy) - : "a" (command), "b" (function), "c" (state), - "d" (smi_port), "S" (0), "D" (0) - ); - } while ((new_state != state) && (retry <= SMI_TRIES)); - - /* enable IRQs */ - local_irq_restore(flags); - - if (new_state == state) - pr_debug("change to %u MHz succeeded after %u tries " - "with result %u\n", - (speedstep_freqs[new_state].frequency / 1000), - retry, result); - else - printk(KERN_ERR "cpufreq: change to state %u " - "failed with new_state %u and result %u\n", - state, new_state, result); - - return; -} - - -/** - * speedstep_target - set a new CPUFreq policy - * @policy: new policy - * @target_freq: new freq - * @relation: - * - * Sets a new CPUFreq policy/freq. - */ -static int speedstep_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned int newstate = 0; - struct cpufreq_freqs freqs; - - if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], - target_freq, relation, &newstate)) - return -EINVAL; - - freqs.old = speedstep_freqs[speedstep_get_state()].frequency; - freqs.new = speedstep_freqs[newstate].frequency; - freqs.cpu = 0; /* speedstep.c is UP only driver */ - - if (freqs.old == freqs.new) - return 0; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - speedstep_set_state(newstate); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return 0; -} - - -/** - * speedstep_verify - verifies a new CPUFreq policy - * @policy: new policy - * - * Limit must be within speedstep_low_freq and speedstep_high_freq, with - * at least one border included. - */ -static int speedstep_verify(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); -} - - -static int speedstep_cpu_init(struct cpufreq_policy *policy) -{ - int result; - unsigned int speed, state; - unsigned int *low, *high; - - /* capability check */ - if (policy->cpu != 0) - return -ENODEV; - - result = speedstep_smi_ownership(); - if (result) { - pr_debug("fails in acquiring ownership of a SMI interface.\n"); - return -EINVAL; - } - - /* detect low and high frequency */ - low = &speedstep_freqs[SPEEDSTEP_LOW].frequency; - high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency; - - result = speedstep_smi_get_freqs(low, high); - if (result) { - /* fall back to speedstep_lib.c dection mechanism: - * try both states out */ - pr_debug("could not detect low and high frequencies " - "by SMI call.\n"); - result = speedstep_get_freqs(speedstep_processor, - low, high, - NULL, - &speedstep_set_state); - - if (result) { - pr_debug("could not detect two different speeds" - " -- aborting.\n"); - return result; - } else - pr_debug("workaround worked.\n"); - } - - /* get current speed setting */ - state = speedstep_get_state(); - speed = speedstep_freqs[state].frequency; - - pr_debug("currently at %s speed setting - %i MHz\n", - (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) - ? "low" : "high", - (speed / 1000)); - - /* cpuinfo and default policy values */ - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - policy->cur = speed; - - result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); - if (result) - return result; - - cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); - - return 0; -} - -static int speedstep_cpu_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - return 0; -} - -static unsigned int speedstep_get(unsigned int cpu) -{ - if (cpu) - return -ENODEV; - return speedstep_get_frequency(speedstep_processor); -} - - -static int speedstep_resume(struct cpufreq_policy *policy) -{ - int result = speedstep_smi_ownership(); - - if (result) - pr_debug("fails in re-acquiring ownership of a SMI interface.\n"); - - return result; -} - -static struct freq_attr *speedstep_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver speedstep_driver = { - .name = "speedstep-smi", - .verify = speedstep_verify, - .target = speedstep_target, - .init = speedstep_cpu_init, - .exit = speedstep_cpu_exit, - .get = speedstep_get, - .resume = speedstep_resume, - .owner = THIS_MODULE, - .attr = speedstep_attr, -}; - -static const struct x86_cpu_id ss_smi_ids[] = { - { X86_VENDOR_INTEL, 6, 0xb, }, - { X86_VENDOR_INTEL, 6, 0x8, }, - { X86_VENDOR_INTEL, 15, 2 }, - {} -}; -#if 0 -/* Not auto loaded currently */ -MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); -#endif - -/** - * speedstep_init - initializes the SpeedStep CPUFreq driver - * - * Initializes the SpeedStep support. Returns -ENODEV on unsupported - * BIOS, -EINVAL on problems during initiatization, and zero on - * success. - */ -static int __init speedstep_init(void) -{ - if (!x86_match_cpu(ss_smi_ids)) - return -ENODEV; - - speedstep_processor = speedstep_detect_processor(); - - switch (speedstep_processor) { - case SPEEDSTEP_CPU_PIII_T: - case SPEEDSTEP_CPU_PIII_C: - case SPEEDSTEP_CPU_PIII_C_EARLY: - break; - default: - speedstep_processor = 0; - } - - if (!speedstep_processor) { - pr_debug("No supported Intel CPU detected.\n"); - return -ENODEV; - } - - pr_debug("signature:0x%.8ulx, command:0x%.8ulx, " - "event:0x%.8ulx, perf_level:0x%.8ulx.\n", - ist_info.signature, ist_info.command, - ist_info.event, ist_info.perf_level); - - /* Error if no IST-SMI BIOS or no PARM - sig= 'ISGE' aka 'Intel Speedstep Gate E' */ - if ((ist_info.signature != 0x47534943) && ( - (smi_port == 0) || (smi_cmd == 0))) - return -ENODEV; - - if (smi_sig == 1) - smi_sig = 0x47534943; - else - smi_sig = ist_info.signature; - - /* setup smi_port from MODLULE_PARM or BIOS */ - if ((smi_port > 0xff) || (smi_port < 0)) - return -EINVAL; - else if (smi_port == 0) - smi_port = ist_info.command & 0xff; - - if ((smi_cmd > 0xff) || (smi_cmd < 0)) - return -EINVAL; - else if (smi_cmd == 0) - smi_cmd = (ist_info.command >> 16) & 0xff; - - return cpufreq_register_driver(&speedstep_driver); -} - - -/** - * speedstep_exit - unregisters SpeedStep support - * - * Unregisters SpeedStep support. - */ -static void __exit speedstep_exit(void) -{ - cpufreq_unregister_driver(&speedstep_driver); -} - -module_param(smi_port, int, 0444); -module_param(smi_cmd, int, 0444); -module_param(smi_sig, uint, 0444); - -MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value " - "-- Intel's default setting is 0xb2"); -MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value " - "-- Intel's default setting is 0x82"); -MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the " - "SMI interface."); - -MODULE_AUTHOR("Hiroshi Miura"); -MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface."); -MODULE_LICENSE("GPL"); - -module_init(speedstep_init); -module_exit(speedstep_exit); diff --git a/linux-3.4/drivers/cpufreq.new/sunxi-autohotplug.c b/linux-3.4/drivers/cpufreq.new/sunxi-autohotplug.c deleted file mode 100755 index 9629e1d1..00000000 --- a/linux-3.4/drivers/cpufreq.new/sunxi-autohotplug.c +++ /dev/null @@ -1,347 +0,0 @@ -#include -#include -#include -#include "autohotplug.h" - -extern unsigned int load_try_down; -extern unsigned int load_try_up; -extern unsigned long cpu_up_lasttime; -extern unsigned int load_up_stable_us; -extern unsigned int load_down_stable_us; -extern unsigned int load_boost_stable_us; - -#if defined(CONFIG_SCHED_HMP) || defined(CONFIG_SCHED_SMP_DCMP) -extern unsigned int load_save_up; -static unsigned int little_core_coop_min_freq = 600000; - -#ifdef CONFIG_SCHED_HMP -extern void __init arch_get_fast_and_slow_cpus(struct cpumask *fast, - struct cpumask *slow); -extern unsigned long cpu_boost_lasttime; -extern unsigned int load_try_boost; -static unsigned int load_save_big_up = 80; -static unsigned int load_lastbig_stable_us = 1500000; -int hmp_cluster0_is_big = 0; -#endif -#endif - -static int is_cpu_load_stable(unsigned int cpu, int stable_type) -{ - if (cpu >= CONFIG_NR_CPUS) - return 0; - - if (stable_type == STABLE_DOWN) - return time_after_eq(jiffies, - cpu_up_lasttime + usecs_to_jiffies(load_down_stable_us)); - else if(stable_type == STABLE_UP) - return time_after_eq(jiffies, - cpu_up_lasttime + usecs_to_jiffies(load_up_stable_us)); - else if(stable_type == STABLE_BOOST) - return time_after_eq(jiffies, - cpu_up_lasttime + usecs_to_jiffies(load_boost_stable_us)); -#if defined(CONFIG_SCHED_HMP) - else if(stable_type == STABLE_LAST_BIG) - return time_after_eq(jiffies, - cpu_up_lasttime + usecs_to_jiffies(load_lastbig_stable_us)); -#endif - else - return 0; -} - -#if defined(CONFIG_SCHED_HMP) -static int autohotplug_smart_tryup_hmp_normal(struct auto_cpu_hotplug_loadinfo *load) -{ - unsigned int tmp = CONFIG_NR_CPUS; - int big_nr, little_nr, ret; - - if ((load->max_load != INVALID_LOAD) - && (load->max_load >= load_try_up) - && is_cpu_load_stable(load->max_cpu, STABLE_UP)) - { - if (load->max_load >= load_try_boost) { - if (get_bigs_under(load, load_save_up, NULL)) { - return 0; - } else { - get_cpus_online(load, &little_nr, &big_nr); - if (big_nr != 0) { - if (try_up_big()) - ret = 1; - else - ret = try_up_little(); - - if (ret) - cpu_boost_lasttime = jiffies; - return ret; - } else { - if (try_up_little()) - ret = 1; - else - ret = try_up_big(); - - if (ret) - cpu_boost_lasttime = jiffies; - return ret; - } - } - } else { - if (get_cpus_under(load, load_save_up, &tmp)) { - return 0; - } else { - if (try_up_little()) { - return 1; - } else { - if (get_cpus_under(load, load_save_big_up, NULL)) - return 0; - else - return try_up_big(); - } - } - } - } - - return 0; -} - -static int autohotplug_smart_trydown_hmp_normal(struct auto_cpu_hotplug_loadinfo *load) -{ - unsigned int to_down = CONFIG_NR_CPUS; - unsigned int on_boost = CONFIG_NR_CPUS; - - if (get_cpus_stable_under(load, load_try_down, &to_down, 0) >= 1) { - if (get_bigs_under(load, load_try_down, &to_down) >= 2) - return do_cpu_down(to_down); - else if (get_littles_under(load, load_try_down, &to_down) > 1) - return do_cpu_down(to_down); - else if (get_bigs_under(load, load_try_down, &to_down) == 1 - && !(get_bigs_above(load, load_try_boost, &on_boost) - && is_cpu_load_stable(on_boost, STABLE_BOOST)) - && (load->cpu_load[to_down] <= load->big_min_load) - && is_cpu_load_stable(to_down, STABLE_LAST_BIG)) - return do_cpu_down(to_down); - else - return 0; - } else { - return 0; - } -} - -static void autohotplug_smart_updatelimits_hmp_normal(void) -{ - int i, big_cpu = CONFIG_NR_CPUS; - struct cpufreq_policy *policy = cpufreq_cpu_get(0); - - for_each_online_cpu(i) { - if (is_cpu_big(i)) { - big_cpu = i; - break; - } - } - - if (big_cpu != CONFIG_NR_CPUS) { - if (policy) { - if (policy->min < little_core_coop_min_freq) { - policy->user_policy.min = little_core_coop_min_freq; - cpufreq_update_policy(0); - } - cpufreq_cpu_put(policy); - } - } else { - if (policy) { - if (policy->min > policy->cpuinfo.min_freq) { - policy->user_policy.min = policy->cpuinfo.min_freq; - cpufreq_update_policy(0); - } - cpufreq_cpu_put(policy); - } - } -} -#endif -#if defined(CONFIG_SCHED_HMP) || defined(CONFIG_SCHED_SMP_DCMP) -static int autohotplug_smart_tryup_hmp_simple(struct auto_cpu_hotplug_loadinfo *load) -{ - int ret =0; - unsigned int first; - - if (!get_cpus_under(load, load_save_up, &first) - && is_cpu_load_stable(load->max_cpu, STABLE_UP)) - { - if (try_up_big()) { - ret = 1; - } else { - try_up_little(); - ret = 1; - } - } - - return ret; -} - -static int autohotplug_smart_trydown_hmp_simple(struct auto_cpu_hotplug_loadinfo *load) -{ - int big_nr, little_nr; - unsigned int first, to_down; - - get_cpus_online(load, &little_nr, &big_nr); - if (get_cpus_under(load, load_try_down, &first) >= 2 - && is_cpu_load_stable(first, STABLE_DOWN)) - { - if (little_nr) { - if (get_littles_under(load, load_try_down * 2, &to_down)) - return do_cpu_down(to_down); - } else { - return do_cpu_down(first); - } - } - - return 0; -} - -#ifndef CONFIG_ARCH_SUN8IW6 -static void autohotplug_smart_updatelimits_hmp_simple(void) -{ - struct cpufreq_policy *policy1=NULL; - struct cpufreq_policy *policy2=NULL; - int i, big_nr = 0, little_nr = 0, big = 0, little = 0; - - for_each_online_cpu(i) { - if (is_cpu_little(i)) { - little_nr++; - little = i; - } else { - big = i; - big_nr++; - } - } - - if (little_nr && big_nr) { - policy1 = cpufreq_cpu_get(big); - if (policy1 && policy1->min < little_core_coop_min_freq) { - policy1->user_policy.min = little_core_coop_min_freq; - cpufreq_update_policy(big); - } - - policy2 = cpufreq_cpu_get(little); - if (policy2 && policy2->min < little_core_coop_min_freq) { - policy2->user_policy.min = little_core_coop_min_freq; - cpufreq_update_policy(little); - } - }else if(big_nr){ - policy1 = cpufreq_cpu_get(big); - if (policy1 && policy1->min < little_core_coop_min_freq) { - policy1->user_policy.min = little_core_coop_min_freq; - cpufreq_update_policy(big); - } - }else if(little_nr){ - policy2 = cpufreq_cpu_get(little); - if (policy2 && policy2->min < little_core_coop_min_freq) { - policy2->user_policy.min = little_core_coop_min_freq; - cpufreq_update_policy(little); - } - } - if(policy1) - cpufreq_cpu_put(policy1); - if(policy2) - cpufreq_cpu_put(policy2); -} -#endif -#endif - -#if !defined(CONFIG_SCHED_HMP) && !defined(CONFIG_SCHED_SMP_DCMP) -static int autohotplug_smart_tryup_smp_normal(struct auto_cpu_hotplug_loadinfo *load) -{ - unsigned int first; - - if (!get_cpus_under(load, load_try_up, &first) - && is_cpu_load_stable(load->max_cpu, STABLE_UP)) - { - return try_up_little(); - } - - return 0; -} - -static int autohotplug_smart_trydown_smp_normal(struct auto_cpu_hotplug_loadinfo *load) -{ - unsigned int first; - - if (get_cpus_under(load, load_try_down, &first) >= 2 - && is_cpu_load_stable(first, STABLE_DOWN)) - { - return do_cpu_down(first); - } - - return 0; -} - -static void autohotplug_smart_updatelimits_smp_normal(void) -{ - -} -#endif -static int autohotplug_smart_get_slow_fast_cpus(struct cpumask *fast, - struct cpumask *slow) -{ -#if defined(CONFIG_SCHED_HMP) - arch_get_fast_and_slow_cpus(fast, slow); - - if (cpumask_test_cpu(0, fast)) - hmp_cluster0_is_big = 1; - else - hmp_cluster0_is_big = 0; - - if (hmp_cluster0_is_big) { - autohotplug_smart.try_up = autohotplug_smart_tryup_hmp_simple; - autohotplug_smart.try_down = autohotplug_smart_trydown_hmp_simple; - autohotplug_smart.update_limits = autohotplug_smart_updatelimits_hmp_simple; - } - else - { - autohotplug_smart.try_up = autohotplug_smart_tryup_hmp_normal; - autohotplug_smart.try_down = autohotplug_smart_trydown_hmp_normal; - autohotplug_smart.update_limits = autohotplug_smart_updatelimits_hmp_normal; - } -#elif defined(CONFIG_SCHED_SMP_DCMP) - if (strlen(CONFIG_CLUSTER0_CPU_MASK) && strlen(CONFIG_CLUSTER1_CPU_MASK)) { - if (cpulist_parse(CONFIG_CLUSTER0_CPU_MASK, fast)) { - pr_err("Failed to parse cluster0 cpu mask!\n"); - return -1; - } - - if (cpulist_parse(CONFIG_CLUSTER1_CPU_MASK, slow)) { - pr_err("Failed to parse cluster1 cpu mask!\n"); - return -1; - } - } - autohotplug_smart.try_up = autohotplug_smart_tryup_hmp_simple; - autohotplug_smart.try_down = autohotplug_smart_trydown_hmp_simple; -#ifndef CONFIG_ARCH_SUN8IW6 - autohotplug_smart.update_limits = autohotplug_smart_updatelimits_hmp_simple; -#endif -#else - cpumask_copy(slow, cpu_possible_mask); - autohotplug_smart.try_up = autohotplug_smart_tryup_smp_normal; - autohotplug_smart.try_down = autohotplug_smart_trydown_smp_normal; - autohotplug_smart.update_limits = autohotplug_smart_updatelimits_smp_normal; -#endif - - return 0; -} - -static void autohotplug_smart_attr_init(void) -{ -#if defined(CONFIG_SCHED_HMP) || defined(CONFIG_SCHED_SMP_DCMP) - autohotplug_attr_add("little_min_freq", &little_core_coop_min_freq, 0644, NULL, NULL); -#ifdef CONFIG_SCHED_HMP - autohotplug_attr_add("save_big_up", &load_save_big_up, 0644, NULL, NULL); - autohotplug_attr_add("stable_lastB_us", &load_lastbig_stable_us, 0644, NULL, NULL); -#endif -#endif -} - -struct autohotplug_governor autohotplug_smart = { - .init_attr = autohotplug_smart_attr_init, - .get_fast_and_slow_cpus = autohotplug_smart_get_slow_fast_cpus, -}; - -MODULE_DESCRIPTION("CPU Auto Hotplug"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.c b/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.c deleted file mode 100755 index dddf904d..00000000 --- a/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.c +++ /dev/null @@ -1,1202 +0,0 @@ -/* - * drivers/cpufreq/sunxi-cpufreq.c - * - * Copyright (c) 2012 softwinner. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sunxi-cpufreq.h" - -#ifdef CONFIG_DEBUG_FS -static unsigned long long cpufreq_set_time_usecs = 0; -static unsigned long long cpufreq_get_time_usecs = 0; -#endif - -static struct sunxi_cpu_freq_t cpu_cur; /* current cpu frequency configuration */ -static unsigned int last_target = ~0; /* backup last target frequency */ - -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) -struct regulator *cpu_vdd; /* cpu vdd handler */ -#endif -static struct clk *clk_pll; /* pll clock handler */ -static struct clk *clk_cpu; /* cpu clock handler */ -static struct clk *clk_axi; /* axi clock handler */ -static DEFINE_MUTEX(sunxi_cpu_lock); - -static unsigned int cpu_freq_max = SUNXI_CPUFREQ_MAX / 1000; -static unsigned int cpu_freq_min = SUNXI_CPUFREQ_MIN / 1000; -static unsigned int cpu_freq_ext = SUNXI_CPUFREQ_MAX / 1000; // extremity cpu freq -static unsigned int cpu_freq_boot = SUNXI_CPUFREQ_MAX / 1000; - -int sunxi_dvfs_debug = 0; -int sunxi_boot_freq_lock = 0; - -#if defined(CONFIG_ARCH_SUN8IW3P1) && defined(CONFIG_DEVFREQ_DRAM_FREQ) -extern int dramfreq_need_suspend; -extern int __ahb_set_rate(unsigned long ahb_freq); -#endif - -int table_length_syscfg = 0; -struct cpufreq_dvfs dvfs_table_syscfg[16]; - -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) -struct pll_cpu_factor_t { - u8 factor_n; - u8 factor_k; - u8 factor_m; - u8 factor_p; -}; - -struct ccu_pll_cpu_ctrl_reg -{ - u32 factor_m:2; //bit0, factor M - u32 reserved0:2; //bit2, reserved - u32 factor_k:2; //bit4, factor K - u32 reserved1:2; //bit6, reserved - u32 factor_n:5; //bit8, factor N - u32 reserved2:3; //bit13, reserved - u32 factor_p:2; //bit16, factor P - u32 reserved3:6; //bit18, reserved - u32 cpu_sdm_en:1; //bit24, cpu sdm en - u32 reserved4:3; //bit25, reserved - u32 lock:1; //bit28, lock - u32 reserved5:2; //bit29, reserved - u32 pll_en:1; //bit31, pll enable -} ; - -struct ccu_cpu_axi_cfg_reg -{ - u32 axi_div:2; //bit0, axi clock div - u32 reserved0:6; //bit2, reserved - u32 apb_div:2; //bit8, apb clock div - u32 reserved1:6; //bit10, reserved - u32 cpu_src:2; //bit16, cpu clock source select - u32 reserved2:14; //bit18, reserved -}; - -static struct ccu_pll_cpu_ctrl_reg *pll_cpu_reg; -static struct ccu_cpu_axi_cfg_reg *cpu_axi_reg; - -static struct pll_cpu_factor_t pll_cpu_table[] = -{ //N K M P - { 9, 0, 0, 2}, //Theory Freq1 = 0 , Actual Freq2 = 60 , Index = 0 - { 9, 0, 0, 2}, //Theory Freq1 = 6 , Actual Freq2 = 60 , Index = 1 - { 9, 0, 0, 2}, //Theory Freq1 = 12 , Actual Freq2 = 60 , Index = 2 - { 9, 0, 0, 2}, //Theory Freq1 = 18 , Actual Freq2 = 60 , Index = 3 - { 9, 0, 0, 2}, //Theory Freq1 = 24 , Actual Freq2 = 60 , Index = 4 - { 9, 0, 0, 2}, //Theory Freq1 = 30 , Actual Freq2 = 60 , Index = 5 - { 9, 0, 0, 2}, //Theory Freq1 = 36 , Actual Freq2 = 60 , Index = 6 - { 9, 0, 0, 2}, //Theory Freq1 = 42 , Actual Freq2 = 60 , Index = 7 - { 9, 0, 0, 2}, //Theory Freq1 = 48 , Actual Freq2 = 60 , Index = 8 - { 9, 0, 0, 2}, //Theory Freq1 = 54 , Actual Freq2 = 60 , Index = 9 - { 9, 0, 0, 2}, //Theory Freq1 = 60 , Actual Freq2 = 60 , Index = 10 - {10, 0, 0, 2}, //Theory Freq1 = 66 , Actual Freq2 = 66 , Index = 11 - {11, 0, 0, 2}, //Theory Freq1 = 72 , Actual Freq2 = 72 , Index = 12 - {12, 0, 0, 2}, //Theory Freq1 = 78 , Actual Freq2 = 78 , Index = 13 - {13, 0, 0, 2}, //Theory Freq1 = 84 , Actual Freq2 = 84 , Index = 14 - {14, 0, 0, 2}, //Theory Freq1 = 90 , Actual Freq2 = 90 , Index = 15 - {15, 0, 0, 2}, //Theory Freq1 = 96 , Actual Freq2 = 96 , Index = 16 - {16, 0, 0, 2}, //Theory Freq1 = 102 , Actual Freq2 = 102 , Index = 17 - {17, 0, 0, 2}, //Theory Freq1 = 108 , Actual Freq2 = 108 , Index = 18 - {18, 0, 0, 2}, //Theory Freq1 = 114 , Actual Freq2 = 114 , Index = 19 - {9 , 0, 0, 1}, //Theory Freq1 = 120 , Actual Freq2 = 120 , Index = 20 - {10, 0, 0, 1}, //Theory Freq1 = 126 , Actual Freq2 = 132 , Index = 21 - {10, 0, 0, 1}, //Theory Freq1 = 132 , Actual Freq2 = 132 , Index = 22 - {11, 0, 0, 1}, //Theory Freq1 = 138 , Actual Freq2 = 144 , Index = 23 - {11, 0, 0, 1}, //Theory Freq1 = 144 , Actual Freq2 = 144 , Index = 24 - {12, 0, 0, 1}, //Theory Freq1 = 150 , Actual Freq2 = 156 , Index = 25 - {12, 0, 0, 1}, //Theory Freq1 = 156 , Actual Freq2 = 156 , Index = 26 - {13, 0, 0, 1}, //Theory Freq1 = 162 , Actual Freq2 = 168 , Index = 27 - {13, 0, 0, 1}, //Theory Freq1 = 168 , Actual Freq2 = 168 , Index = 28 - {14, 0, 0, 1}, //Theory Freq1 = 174 , Actual Freq2 = 180 , Index = 29 - {14, 0, 0, 1}, //Theory Freq1 = 180 , Actual Freq2 = 180 , Index = 30 - {15, 0, 0, 1}, //Theory Freq1 = 186 , Actual Freq2 = 192 , Index = 31 - {15, 0, 0, 1}, //Theory Freq1 = 192 , Actual Freq2 = 192 , Index = 32 - {16, 0, 0, 1}, //Theory Freq1 = 198 , Actual Freq2 = 204 , Index = 33 - {16, 0, 0, 1}, //Theory Freq1 = 204 , Actual Freq2 = 204 , Index = 34 - {17, 0, 0, 1}, //Theory Freq1 = 210 , Actual Freq2 = 216 , Index = 35 - {17, 0, 0, 1}, //Theory Freq1 = 216 , Actual Freq2 = 216 , Index = 36 - {18, 0, 0, 1}, //Theory Freq1 = 222 , Actual Freq2 = 228 , Index = 37 - {18, 0, 0, 1}, //Theory Freq1 = 228 , Actual Freq2 = 228 , Index = 38 - {9 , 0, 0, 0}, //Theory Freq1 = 234 , Actual Freq2 = 240 , Index = 39 - {9 , 0, 0, 0}, //Theory Freq1 = 240 , Actual Freq2 = 240 , Index = 40 - {10, 0, 0, 0}, //Theory Freq1 = 246 , Actual Freq2 = 264 , Index = 41 - {10, 0, 0, 0}, //Theory Freq1 = 252 , Actual Freq2 = 264 , Index = 42 - {10, 0, 0, 0}, //Theory Freq1 = 258 , Actual Freq2 = 264 , Index = 43 - {10, 0, 0, 0}, //Theory Freq1 = 264 , Actual Freq2 = 264 , Index = 44 - {11, 0, 0, 0}, //Theory Freq1 = 270 , Actual Freq2 = 288 , Index = 45 - {11, 0, 0, 0}, //Theory Freq1 = 276 , Actual Freq2 = 288 , Index = 46 - {11, 0, 0, 0}, //Theory Freq1 = 282 , Actual Freq2 = 288 , Index = 47 - {11, 0, 0, 0}, //Theory Freq1 = 288 , Actual Freq2 = 288 , Index = 48 - {12, 0, 0, 0}, //Theory Freq1 = 294 , Actual Freq2 = 312 , Index = 49 - {12, 0, 0, 0}, //Theory Freq1 = 300 , Actual Freq2 = 312 , Index = 50 - {12, 0, 0, 0}, //Theory Freq1 = 306 , Actual Freq2 = 312 , Index = 51 - {12, 0, 0, 0}, //Theory Freq1 = 312 , Actual Freq2 = 312 , Index = 52 - {13, 0, 0, 0}, //Theory Freq1 = 318 , Actual Freq2 = 336 , Index = 53 - {13, 0, 0, 0}, //Theory Freq1 = 324 , Actual Freq2 = 336 , Index = 54 - {13, 0, 0, 0}, //Theory Freq1 = 330 , Actual Freq2 = 336 , Index = 55 - {13, 0, 0, 0}, //Theory Freq1 = 336 , Actual Freq2 = 336 , Index = 56 - {14, 0, 0, 0}, //Theory Freq1 = 342 , Actual Freq2 = 360 , Index = 57 - {14, 0, 0, 0}, //Theory Freq1 = 348 , Actual Freq2 = 360 , Index = 58 - {14, 0, 0, 0}, //Theory Freq1 = 354 , Actual Freq2 = 360 , Index = 59 - {14, 0, 0, 0}, //Theory Freq1 = 360 , Actual Freq2 = 360 , Index = 60 - {15, 0, 0, 0}, //Theory Freq1 = 366 , Actual Freq2 = 384 , Index = 61 - {15, 0, 0, 0}, //Theory Freq1 = 372 , Actual Freq2 = 384 , Index = 62 - {15, 0, 0, 0}, //Theory Freq1 = 378 , Actual Freq2 = 384 , Index = 63 - {15, 0, 0, 0}, //Theory Freq1 = 384 , Actual Freq2 = 384 , Index = 64 - {16, 0, 0, 0}, //Theory Freq1 = 390 , Actual Freq2 = 408 , Index = 65 - {16, 0, 0, 0}, //Theory Freq1 = 396 , Actual Freq2 = 408 , Index = 66 - {16, 0, 0, 0}, //Theory Freq1 = 402 , Actual Freq2 = 408 , Index = 67 - {16, 0, 0, 0}, //Theory Freq1 = 408 , Actual Freq2 = 408 , Index = 68 - {17, 0, 0, 0}, //Theory Freq1 = 414 , Actual Freq2 = 432 , Index = 69 - {17, 0, 0, 0}, //Theory Freq1 = 420 , Actual Freq2 = 432 , Index = 70 - {17, 0, 0, 0}, //Theory Freq1 = 426 , Actual Freq2 = 432 , Index = 71 - {17, 0, 0, 0}, //Theory Freq1 = 432 , Actual Freq2 = 432 , Index = 72 - {18, 0, 0, 0}, //Theory Freq1 = 438 , Actual Freq2 = 456 , Index = 73 - {18, 0, 0, 0}, //Theory Freq1 = 444 , Actual Freq2 = 456 , Index = 74 - {18, 0, 0, 0}, //Theory Freq1 = 450 , Actual Freq2 = 456 , Index = 75 - {18, 0, 0, 0}, //Theory Freq1 = 456 , Actual Freq2 = 456 , Index = 76 - {19, 0, 0, 0}, //Theory Freq1 = 462 , Actual Freq2 = 480 , Index = 77 - {19, 0, 0, 0}, //Theory Freq1 = 468 , Actual Freq2 = 480 , Index = 78 - {19, 0, 0, 0}, //Theory Freq1 = 474 , Actual Freq2 = 480 , Index = 79 - {19, 0, 0, 0}, //Theory Freq1 = 480 , Actual Freq2 = 480 , Index = 80 - {20, 0, 0, 0}, //Theory Freq1 = 486 , Actual Freq2 = 504 , Index = 81 - {20, 0, 0, 0}, //Theory Freq1 = 492 , Actual Freq2 = 504 , Index = 82 - {20, 0, 0, 0}, //Theory Freq1 = 498 , Actual Freq2 = 504 , Index = 83 - {20, 0, 0, 0}, //Theory Freq1 = 504 , Actual Freq2 = 504 , Index = 84 - {21, 0, 0, 0}, //Theory Freq1 = 510 , Actual Freq2 = 528 , Index = 85 - {21, 0, 0, 0}, //Theory Freq1 = 516 , Actual Freq2 = 528 , Index = 86 - {21, 0, 0, 0}, //Theory Freq1 = 522 , Actual Freq2 = 528 , Index = 87 - {21, 0, 0, 0}, //Theory Freq1 = 528 , Actual Freq2 = 528 , Index = 88 - {22, 0, 0, 0}, //Theory Freq1 = 534 , Actual Freq2 = 552 , Index = 89 - {22, 0, 0, 0}, //Theory Freq1 = 540 , Actual Freq2 = 552 , Index = 90 - {22, 0, 0, 0}, //Theory Freq1 = 546 , Actual Freq2 = 552 , Index = 91 - {22, 0, 0, 0}, //Theory Freq1 = 552 , Actual Freq2 = 552 , Index = 92 - {23, 0, 0, 0}, //Theory Freq1 = 558 , Actual Freq2 = 576 , Index = 93 - {23, 0, 0, 0}, //Theory Freq1 = 564 , Actual Freq2 = 576 , Index = 94 - {23, 0, 0, 0}, //Theory Freq1 = 570 , Actual Freq2 = 576 , Index = 95 - {23, 0, 0, 0}, //Theory Freq1 = 576 , Actual Freq2 = 576 , Index = 96 - {24, 0, 0, 0}, //Theory Freq1 = 582 , Actual Freq2 = 600 , Index = 97 - {24, 0, 0, 0}, //Theory Freq1 = 588 , Actual Freq2 = 600 , Index = 98 - {24, 0, 0, 0}, //Theory Freq1 = 594 , Actual Freq2 = 600 , Index = 99 - {24, 0, 0, 0}, //Theory Freq1 = 600 , Actual Freq2 = 600 , Index = 100 - {25, 0, 0, 0}, //Theory Freq1 = 606 , Actual Freq2 = 624 , Index = 101 - {25, 0, 0, 0}, //Theory Freq1 = 612 , Actual Freq2 = 624 , Index = 102 - {25, 0, 0, 0}, //Theory Freq1 = 618 , Actual Freq2 = 624 , Index = 103 - {25, 0, 0, 0}, //Theory Freq1 = 624 , Actual Freq2 = 624 , Index = 104 - {26, 0, 0, 0}, //Theory Freq1 = 630 , Actual Freq2 = 648 , Index = 105 - {26, 0, 0, 0}, //Theory Freq1 = 636 , Actual Freq2 = 648 , Index = 106 - {26, 0, 0, 0}, //Theory Freq1 = 642 , Actual Freq2 = 648 , Index = 107 - {26, 0, 0, 0}, //Theory Freq1 = 648 , Actual Freq2 = 648 , Index = 108 - {27, 0, 0, 0}, //Theory Freq1 = 654 , Actual Freq2 = 672 , Index = 109 - {27, 0, 0, 0}, //Theory Freq1 = 660 , Actual Freq2 = 672 , Index = 110 - {27, 0, 0, 0}, //Theory Freq1 = 666 , Actual Freq2 = 672 , Index = 111 - {27, 0, 0, 0}, //Theory Freq1 = 672 , Actual Freq2 = 672 , Index = 112 - {28, 0, 0, 0}, //Theory Freq1 = 678 , Actual Freq2 = 696 , Index = 113 - {28, 0, 0, 0}, //Theory Freq1 = 684 , Actual Freq2 = 696 , Index = 114 - {28, 0, 0, 0}, //Theory Freq1 = 690 , Actual Freq2 = 696 , Index = 115 - {28, 0, 0, 0}, //Theory Freq1 = 696 , Actual Freq2 = 696 , Index = 116 - {29, 0, 0, 0}, //Theory Freq1 = 702 , Actual Freq2 = 720 , Index = 117 - {29, 0, 0, 0}, //Theory Freq1 = 708 , Actual Freq2 = 720 , Index = 118 - {29, 0, 0, 0}, //Theory Freq1 = 714 , Actual Freq2 = 720 , Index = 119 - {29, 0, 0, 0}, //Theory Freq1 = 720 , Actual Freq2 = 720 , Index = 120 - {15, 1, 0, 0}, //Theory Freq1 = 726 , Actual Freq2 = 768 , Index = 121 - {15, 1, 0, 0}, //Theory Freq1 = 732 , Actual Freq2 = 768 , Index = 122 - {15, 1, 0, 0}, //Theory Freq1 = 738 , Actual Freq2 = 768 , Index = 123 - {15, 1, 0, 0}, //Theory Freq1 = 744 , Actual Freq2 = 768 , Index = 124 - {15, 1, 0, 0}, //Theory Freq1 = 750 , Actual Freq2 = 768 , Index = 125 - {15, 1, 0, 0}, //Theory Freq1 = 756 , Actual Freq2 = 768 , Index = 126 - {15, 1, 0, 0}, //Theory Freq1 = 762 , Actual Freq2 = 768 , Index = 127 - {15, 1, 0, 0}, //Theory Freq1 = 768 , Actual Freq2 = 768 , Index = 128 - {10, 2, 0, 0}, //Theory Freq1 = 774 , Actual Freq2 = 792 , Index = 129 - {10, 2, 0, 0}, //Theory Freq1 = 780 , Actual Freq2 = 792 , Index = 130 - {10, 2, 0, 0}, //Theory Freq1 = 786 , Actual Freq2 = 792 , Index = 131 - {10, 2, 0, 0}, //Theory Freq1 = 792 , Actual Freq2 = 792 , Index = 132 - {16, 1, 0, 0}, //Theory Freq1 = 798 , Actual Freq2 = 816 , Index = 133 - {16, 1, 0, 0}, //Theory Freq1 = 804 , Actual Freq2 = 816 , Index = 134 - {16, 1, 0, 0}, //Theory Freq1 = 810 , Actual Freq2 = 816 , Index = 135 - {16, 1, 0, 0}, //Theory Freq1 = 816 , Actual Freq2 = 816 , Index = 136 - {17, 1, 0, 0}, //Theory Freq1 = 822 , Actual Freq2 = 864 , Index = 137 - {17, 1, 0, 0}, //Theory Freq1 = 828 , Actual Freq2 = 864 , Index = 138 - {17, 1, 0, 0}, //Theory Freq1 = 834 , Actual Freq2 = 864 , Index = 139 - {17, 1, 0, 0}, //Theory Freq1 = 840 , Actual Freq2 = 864 , Index = 140 - {17, 1, 0, 0}, //Theory Freq1 = 846 , Actual Freq2 = 864 , Index = 141 - {17, 1, 0, 0}, //Theory Freq1 = 852 , Actual Freq2 = 864 , Index = 142 - {17, 1, 0, 0}, //Theory Freq1 = 858 , Actual Freq2 = 864 , Index = 143 - {17, 1, 0, 0}, //Theory Freq1 = 864 , Actual Freq2 = 864 , Index = 144 - {18, 1, 0, 0}, //Theory Freq1 = 870 , Actual Freq2 = 912 , Index = 145 - {18, 1, 0, 0}, //Theory Freq1 = 876 , Actual Freq2 = 912 , Index = 146 - {18, 1, 0, 0}, //Theory Freq1 = 882 , Actual Freq2 = 912 , Index = 147 - {18, 1, 0, 0}, //Theory Freq1 = 888 , Actual Freq2 = 912 , Index = 148 - {18, 1, 0, 0}, //Theory Freq1 = 894 , Actual Freq2 = 912 , Index = 149 - {18, 1, 0, 0}, //Theory Freq1 = 900 , Actual Freq2 = 912 , Index = 150 - {18, 1, 0, 0}, //Theory Freq1 = 906 , Actual Freq2 = 912 , Index = 151 - {18, 1, 0, 0}, //Theory Freq1 = 912 , Actual Freq2 = 912 , Index = 152 - {12, 2, 0, 0}, //Theory Freq1 = 918 , Actual Freq2 = 936 , Index = 153 - {12, 2, 0, 0}, //Theory Freq1 = 924 , Actual Freq2 = 936 , Index = 154 - {12, 2, 0, 0}, //Theory Freq1 = 930 , Actual Freq2 = 936 , Index = 155 - {12, 2, 0, 0}, //Theory Freq1 = 936 , Actual Freq2 = 936 , Index = 156 - {19, 1, 0, 0}, //Theory Freq1 = 942 , Actual Freq2 = 960 , Index = 157 - {19, 1, 0, 0}, //Theory Freq1 = 948 , Actual Freq2 = 960 , Index = 158 - {19, 1, 0, 0}, //Theory Freq1 = 954 , Actual Freq2 = 960 , Index = 159 - {19, 1, 0, 0}, //Theory Freq1 = 960 , Actual Freq2 = 960 , Index = 160 - {20, 1, 0, 0}, //Theory Freq1 = 966 , Actual Freq2 = 1008, Index = 161 - {20, 1, 0, 0}, //Theory Freq1 = 972 , Actual Freq2 = 1008, Index = 162 - {20, 1, 0, 0}, //Theory Freq1 = 978 , Actual Freq2 = 1008, Index = 163 - {20, 1, 0, 0}, //Theory Freq1 = 984 , Actual Freq2 = 1008, Index = 164 - {20, 1, 0, 0}, //Theory Freq1 = 990 , Actual Freq2 = 1008, Index = 165 - {20, 1, 0, 0}, //Theory Freq1 = 996 , Actual Freq2 = 1008, Index = 166 - {20, 1, 0, 0}, //Theory Freq1 = 1002, Actual Freq2 = 1008, Index = 167 - {20, 1, 0, 0}, //Theory Freq1 = 1008, Actual Freq2 = 1008, Index = 168 - {21, 1, 0, 0}, //Theory Freq1 = 1014, Actual Freq2 = 1056, Index = 169 - {21, 1, 0, 0}, //Theory Freq1 = 1020, Actual Freq2 = 1056, Index = 170 - {21, 1, 0, 0}, //Theory Freq1 = 1026, Actual Freq2 = 1056, Index = 171 - {21, 1, 0, 0}, //Theory Freq1 = 1032, Actual Freq2 = 1056, Index = 172 - {21, 1, 0, 0}, //Theory Freq1 = 1038, Actual Freq2 = 1056, Index = 173 - {21, 1, 0, 0}, //Theory Freq1 = 1044, Actual Freq2 = 1056, Index = 174 - {21, 1, 0, 0}, //Theory Freq1 = 1050, Actual Freq2 = 1056, Index = 175 - {21, 1, 0, 0}, //Theory Freq1 = 1056, Actual Freq2 = 1056, Index = 176 - {14, 2, 0, 0}, //Theory Freq1 = 1062, Actual Freq2 = 1080, Index = 177 - {14, 2, 0, 0}, //Theory Freq1 = 1068, Actual Freq2 = 1080, Index = 178 - {14, 2, 0, 0}, //Theory Freq1 = 1074, Actual Freq2 = 1080, Index = 179 - {14, 2, 0, 0}, //Theory Freq1 = 1080, Actual Freq2 = 1080, Index = 180 - {22, 1, 0, 0}, //Theory Freq1 = 1086, Actual Freq2 = 1104, Index = 181 - {22, 1, 0, 0}, //Theory Freq1 = 1092, Actual Freq2 = 1104, Index = 182 - {22, 1, 0, 0}, //Theory Freq1 = 1098, Actual Freq2 = 1104, Index = 183 - {22, 1, 0, 0}, //Theory Freq1 = 1104, Actual Freq2 = 1104, Index = 184 - {23, 1, 0, 0}, //Theory Freq1 = 1110, Actual Freq2 = 1152, Index = 185 - {23, 1, 0, 0}, //Theory Freq1 = 1116, Actual Freq2 = 1152, Index = 186 - {23, 1, 0, 0}, //Theory Freq1 = 1122, Actual Freq2 = 1152, Index = 187 - {23, 1, 0, 0}, //Theory Freq1 = 1128, Actual Freq2 = 1152, Index = 188 - {23, 1, 0, 0}, //Theory Freq1 = 1134, Actual Freq2 = 1152, Index = 189 - {23, 1, 0, 0}, //Theory Freq1 = 1140, Actual Freq2 = 1152, Index = 190 - {23, 1, 0, 0}, //Theory Freq1 = 1146, Actual Freq2 = 1152, Index = 191 - {23, 1, 0, 0}, //Theory Freq1 = 1152, Actual Freq2 = 1152, Index = 192 - {24, 1, 0, 0}, //Theory Freq1 = 1158, Actual Freq2 = 1200, Index = 193 - {24, 1, 0, 0}, //Theory Freq1 = 1164, Actual Freq2 = 1200, Index = 194 - {24, 1, 0, 0}, //Theory Freq1 = 1170, Actual Freq2 = 1200, Index = 195 - {24, 1, 0, 0}, //Theory Freq1 = 1176, Actual Freq2 = 1200, Index = 196 - {24, 1, 0, 0}, //Theory Freq1 = 1182, Actual Freq2 = 1200, Index = 197 - {24, 1, 0, 0}, //Theory Freq1 = 1188, Actual Freq2 = 1200, Index = 198 - {24, 1, 0, 0}, //Theory Freq1 = 1194, Actual Freq2 = 1200, Index = 199 - {24, 1, 0, 0}, //Theory Freq1 = 1200, Actual Freq2 = 1200, Index = 200 - {16, 2, 0, 0}, //Theory Freq1 = 1206, Actual Freq2 = 1224, Index = 201 - {16, 2, 0, 0}, //Theory Freq1 = 1212, Actual Freq2 = 1224, Index = 202 - {16, 2, 0, 0}, //Theory Freq1 = 1218, Actual Freq2 = 1224, Index = 203 - {16, 2, 0, 0}, //Theory Freq1 = 1224, Actual Freq2 = 1224, Index = 204 - {25, 1, 0, 0}, //Theory Freq1 = 1230, Actual Freq2 = 1248, Index = 205 - {25, 1, 0, 0}, //Theory Freq1 = 1236, Actual Freq2 = 1248, Index = 206 - {25, 1, 0, 0}, //Theory Freq1 = 1242, Actual Freq2 = 1248, Index = 207 - {25, 1, 0, 0}, //Theory Freq1 = 1248, Actual Freq2 = 1248, Index = 208 - {26, 1, 0, 0}, //Theory Freq1 = 1254, Actual Freq2 = 1296, Index = 209 - {26, 1, 0, 0}, //Theory Freq1 = 1260, Actual Freq2 = 1296, Index = 210 - {26, 1, 0, 0}, //Theory Freq1 = 1266, Actual Freq2 = 1296, Index = 211 - {26, 1, 0, 0}, //Theory Freq1 = 1272, Actual Freq2 = 1296, Index = 212 - {26, 1, 0, 0}, //Theory Freq1 = 1278, Actual Freq2 = 1296, Index = 213 - {26, 1, 0, 0}, //Theory Freq1 = 1284, Actual Freq2 = 1296, Index = 214 - {26, 1, 0, 0}, //Theory Freq1 = 1290, Actual Freq2 = 1296, Index = 215 - {26, 1, 0, 0}, //Theory Freq1 = 1296, Actual Freq2 = 1296, Index = 216 - {27, 1, 0, 0}, //Theory Freq1 = 1302, Actual Freq2 = 1344, Index = 217 - {27, 1, 0, 0}, //Theory Freq1 = 1308, Actual Freq2 = 1344, Index = 218 - {27, 1, 0, 0}, //Theory Freq1 = 1314, Actual Freq2 = 1344, Index = 219 - {27, 1, 0, 0}, //Theory Freq1 = 1320, Actual Freq2 = 1344, Index = 220 - {27, 1, 0, 0}, //Theory Freq1 = 1326, Actual Freq2 = 1344, Index = 221 - {27, 1, 0, 0}, //Theory Freq1 = 1332, Actual Freq2 = 1344, Index = 222 - {27, 1, 0, 0}, //Theory Freq1 = 1338, Actual Freq2 = 1344, Index = 223 - {27, 1, 0, 0}, //Theory Freq1 = 1344, Actual Freq2 = 1344, Index = 224 - {18, 2, 0, 0}, //Theory Freq1 = 1350, Actual Freq2 = 1368, Index = 225 - {18, 2, 0, 0}, //Theory Freq1 = 1356, Actual Freq2 = 1368, Index = 226 - {18, 2, 0, 0}, //Theory Freq1 = 1362, Actual Freq2 = 1368, Index = 227 - {18, 2, 0, 0}, //Theory Freq1 = 1368, Actual Freq2 = 1368, Index = 228 - {19, 2, 0, 0}, //Theory Freq1 = 1374, Actual Freq2 = 1440, Index = 229 - {19, 2, 0, 0}, //Theory Freq1 = 1380, Actual Freq2 = 1440, Index = 230 - {19, 2, 0, 0}, //Theory Freq1 = 1386, Actual Freq2 = 1440, Index = 231 - {19, 2, 0, 0}, //Theory Freq1 = 1392, Actual Freq2 = 1440, Index = 232 - {19, 2, 0, 0}, //Theory Freq1 = 1398, Actual Freq2 = 1440, Index = 233 - {19, 2, 0, 0}, //Theory Freq1 = 1404, Actual Freq2 = 1440, Index = 234 - {19, 2, 0, 0}, //Theory Freq1 = 1410, Actual Freq2 = 1440, Index = 235 - {19, 2, 0, 0}, //Theory Freq1 = 1416, Actual Freq2 = 1440, Index = 236 - {19, 2, 0, 0}, //Theory Freq1 = 1422, Actual Freq2 = 1440, Index = 237 - {19, 2, 0, 0}, //Theory Freq1 = 1428, Actual Freq2 = 1440, Index = 238 - {19, 2, 0, 0}, //Theory Freq1 = 1434, Actual Freq2 = 1440, Index = 239 - {19, 2, 0, 0}, //Theory Freq1 = 1440, Actual Freq2 = 1440, Index = 240 - {20, 2, 0, 0}, //Theory Freq1 = 1446, Actual Freq2 = 1512, Index = 241 - {20, 2, 0, 0}, //Theory Freq1 = 1452, Actual Freq2 = 1512, Index = 242 - {20, 2, 0, 0}, //Theory Freq1 = 1458, Actual Freq2 = 1512, Index = 243 - {20, 2, 0, 0}, //Theory Freq1 = 1464, Actual Freq2 = 1512, Index = 244 - {20, 2, 0, 0}, //Theory Freq1 = 1470, Actual Freq2 = 1512, Index = 245 - {20, 2, 0, 0}, //Theory Freq1 = 1476, Actual Freq2 = 1512, Index = 246 - {20, 2, 0, 0}, //Theory Freq1 = 1482, Actual Freq2 = 1512, Index = 247 - {20, 2, 0, 0}, //Theory Freq1 = 1488, Actual Freq2 = 1512, Index = 248 - {20, 2, 0, 0}, //Theory Freq1 = 1494, Actual Freq2 = 1512, Index = 249 - {20, 2, 0, 0}, //Theory Freq1 = 1500, Actual Freq2 = 1512, Index = 250 - {20, 2, 0, 0}, //Theory Freq1 = 1506, Actual Freq2 = 1512, Index = 251 - {20, 2, 0, 0}, //Theory Freq1 = 1512, Actual Freq2 = 1512, Index = 252 - {15, 3, 0, 0}, //Theory Freq1 = 1518, Actual Freq2 = 1536, Index = 253 - {15, 3, 0, 0}, //Theory Freq1 = 1524, Actual Freq2 = 1536, Index = 254 - {15, 3, 0, 0}, //Theory Freq1 = 1530, Actual Freq2 = 1536, Index = 255 - {15, 3, 0, 0}, //Theory Freq1 = 1536, Actual Freq2 = 1536, Index = 256 -}; - -struct cpufreq_frequency_table sunxi_freq_tbl[] = { - { .frequency = 60000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 120000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 240000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 312000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 408000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 504000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 600000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 648000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 720000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 816000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 912000 , .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1008000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1104000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1200000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1344000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1440000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - { .frequency = 1536000, .index = SUNXI_CLK_DIV(1, 3, 0, 0), }, - - /* table end */ - { .frequency = CPUFREQ_TABLE_END, .index = 0, }, -}; - -#else -struct cpufreq_frequency_table sunxi_freq_tbl[] = { - { .frequency = 60000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 120000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 240000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 312000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 408000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 504000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 600000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, -#if defined(CONFIG_ARCH_SUN8IW5P1) - { .frequency = 648000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, -#endif - { .frequency = 720000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 816000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 912000 , .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1008000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1104000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1200000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1344000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1440000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - { .frequency = 1536000, .index = SUNXI_CLK_DIV(0, 0, 0, 0), }, - - /* table end */ - { .frequency = CPUFREQ_TABLE_END, .index = 0, }, -}; -#endif - -/* - *check if the cpu frequency policy is valid; - */ -static int sunxi_cpufreq_verify(struct cpufreq_policy *policy) -{ - return 0; -} - - -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) -/* - * get the current cpu vdd; - * return: cpu vdd, based on mv; - */ -int sunxi_cpufreq_getvolt(void) -{ - return regulator_get_voltage(cpu_vdd) / 1000; -} -#endif - -/* - * get the frequency that cpu currently is running; - * cpu: cpu number, all cpus use the same clock; - * return: cpu frequency, based on khz; - */ -static unsigned int sunxi_cpufreq_get(unsigned int cpu) -{ - unsigned int current_freq = 0; -#ifdef CONFIG_DEBUG_FS - ktime_t calltime = ktime_set(0, 0), delta, rettime; - - calltime = ktime_get(); -#endif - - clk_get_rate(clk_pll); - current_freq = clk_get_rate(clk_cpu) / 1000; - -#ifdef CONFIG_DEBUG_FS - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - cpufreq_get_time_usecs = ktime_to_ns(delta) >> 10; -#endif - - return current_freq; -} - - -/* - *show cpu frequency information; - */ -static void sunxi_cpufreq_show(const char *pfx, struct sunxi_cpu_freq_t *cfg) -{ - pr_debug("%s: pll=%u, cpudiv=%u, axidiv=%u\n", pfx, cfg->pll, cfg->div.cpu_div, cfg->div.axi_div); -} - - -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) -static int __set_cpufreq_target(struct sunxi_cpu_freq_t *target) -{ - struct pll_cpu_factor_t factor; - struct ccu_pll_cpu_ctrl_reg tmp_pll_cpu; - struct ccu_cpu_axi_cfg_reg tmp_cpu_axi_cfg; - unsigned int index; - - if (!target) - return -EINVAL; - - tmp_cpu_axi_cfg = *cpu_axi_reg; - /* try to increase axi divide ratio - * the axi_div of target freq should be increase first, - * this is to avoid axi bus clock beyond limition. - */ - if (tmp_cpu_axi_cfg.axi_div < target->div.axi_div) { - tmp_cpu_axi_cfg.axi_div = target->div.axi_div; - *cpu_axi_reg = tmp_cpu_axi_cfg; - } - - if (target->pll > 1536000000) - target->pll = 1536000000; - index = target->pll / 6000000; - - factor.factor_n = pll_cpu_table[index].factor_n; - factor.factor_k = pll_cpu_table[index].factor_k; - factor.factor_m = pll_cpu_table[index].factor_m; - factor.factor_p = pll_cpu_table[index].factor_p; - - if (unlikely(sunxi_dvfs_debug)) - printk("[cpufreq] target: N:%u K:%u M:%u P:%u axi_div:%u\n", - factor.factor_n, factor.factor_k, factor.factor_m, factor.factor_p, - target->div.axi_div); - - tmp_pll_cpu = *pll_cpu_reg; - /* try to increase factor p first */ - if (tmp_pll_cpu.factor_p < factor.factor_p) { - tmp_pll_cpu.factor_p = factor.factor_p; - *pll_cpu_reg = tmp_pll_cpu; - udelay(10); - } - - /* try to increase factor m first */ - if (tmp_pll_cpu.factor_m < factor.factor_m) { - tmp_pll_cpu.factor_m = factor.factor_m; - *pll_cpu_reg = tmp_pll_cpu; - udelay(10); - } - - /* write factor n & k */ - tmp_pll_cpu.factor_n = factor.factor_n; - tmp_pll_cpu.factor_k = factor.factor_k; - *pll_cpu_reg = tmp_pll_cpu; - - /* wait for lock change first */ - ndelay(100); - -#ifdef CONFIG_EVB_PLATFORM - /* wait for PLL CPU stable */ - while (pll_cpu_reg->lock != 1); -#endif - - //decease factor m - if (tmp_pll_cpu.factor_m > factor.factor_m) { - tmp_pll_cpu.factor_m = factor.factor_m; - *pll_cpu_reg = tmp_pll_cpu; - udelay(10); - } - - /* decease factor p */ - if (tmp_pll_cpu.factor_p > factor.factor_p) { - tmp_pll_cpu.factor_p = factor.factor_p; - *pll_cpu_reg = tmp_pll_cpu; - udelay(10); - } - - /* try to decrease axi divide ratio */ - if (tmp_cpu_axi_cfg.axi_div > target->div.axi_div) { - tmp_cpu_axi_cfg.axi_div = target->div.axi_div; - *cpu_axi_reg = tmp_cpu_axi_cfg; - } - - if (unlikely(sunxi_dvfs_debug)) - printk("[cpufreq] current: N:%u K:%u M:%u P:%u axi_div:%u\n", - pll_cpu_reg->factor_n, pll_cpu_reg->factor_k, pll_cpu_reg->factor_m, - pll_cpu_reg->factor_p, cpu_axi_reg->axi_div); - - return 0; -} -#endif - - -/* - * adjust the frequency that cpu is currently running; - * policy: cpu frequency policy; - * freq: target frequency to be set, based on khz; - * relation: method for selecting the target requency; - * return: result, return 0 if set target frequency successed, else, return -EINVAL; - * notes: this function is called by the cpufreq core; - */ -static int sunxi_cpufreq_target(struct cpufreq_policy *policy, __u32 freq, __u32 relation) -{ - int ret = 0; - unsigned int index; - struct sunxi_cpu_freq_t freq_cfg; - struct cpufreq_freqs freqs; -#ifdef CONFIG_DEBUG_FS - ktime_t calltime = ktime_set(0, 0), delta, rettime; -#endif -#ifdef CONFIG_SMP - int i; -#endif - - mutex_lock(&sunxi_cpu_lock); - - /* avoid repeated calls which cause a needless amout of duplicated - * logging output (and CPU time as the calculation process is - * done) */ - if (freq == last_target) - goto out; - - if (unlikely(sunxi_dvfs_debug)) - printk("[cpufreq] request frequency is %u\n", freq); - - if (unlikely(sunxi_boot_freq_lock)) - freq = freq > cpu_freq_boot ? cpu_freq_boot : freq; - - /* try to look for a valid frequency value from cpu frequency table */ - if (cpufreq_frequency_table_target(policy, sunxi_freq_tbl, freq, relation, &index)) { - CPUFREQ_ERR("try to look for a valid frequency for %u failed!\n", freq); - ret = -EINVAL; - goto out; - } - - /* frequency is same as the value last set, need not adjust */ - if (sunxi_freq_tbl[index].frequency == last_target) - goto out; - - freq = sunxi_freq_tbl[index].frequency; - - /* update the target frequency */ - freq_cfg.pll = sunxi_freq_tbl[index].frequency * 1000; - freq_cfg.div = *(struct sunxi_clk_div_t *)&sunxi_freq_tbl[index].index; - - if (unlikely(sunxi_dvfs_debug)) - printk("[cpufreq] target frequency find is %u, entry %u\n", freq_cfg.pll, index); - - /* notify that cpu clock will be adjust if needed */ - if (policy) { - freqs.cpu = policy->cpu; - freqs.old = last_target; - freqs.new = freq; - -#ifdef CONFIG_SMP - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - } -#else - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); -#endif - } - -#ifdef CONFIG_DEBUG_FS - calltime = ktime_get(); -#endif - -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) - if (__set_cpufreq_target(&freq_cfg)) { -#else - /* try to set cpu frequency */ - if (arisc_dvfs_set_cpufreq(freq, ARISC_DVFS_PLL1, ARISC_DVFS_SYN, NULL, NULL)) { -#endif - CPUFREQ_ERR("set cpu frequency to %uMHz failed!\n", freq / 1000); - /* set cpu frequency failed */ - if (policy) { - freqs.cpu = policy->cpu; - freqs.old = freqs.new; - freqs.new = last_target; - -#ifdef CONFIG_SMP - /* notifiers */ - for_each_cpu(i, policy->cpus) { - freqs.cpu = i; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - } -#else - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -#endif - } - - ret = -EINVAL; - goto out; - } - -#ifdef CONFIG_DEBUG_FS - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - cpufreq_set_time_usecs = ktime_to_ns(delta) >> 10; -#endif - - /* notify that cpu clock will be adjust if needed */ - if (policy) { -#ifdef CONFIG_SMP - /* - * Note that loops_per_jiffy is not updated on SMP systems in - * cpufreq driver. So, update the per-CPU loops_per_jiffy value - * on frequency transition. We need to update all dependent cpus - */ - for_each_cpu(i, policy->cpus) { - per_cpu(cpu_data, i).loops_per_jiffy = - cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, freqs.old, freqs.new); - freqs.cpu = i; - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - } -#else - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); -#endif - } - - last_target = freq; - -#if defined(CONFIG_ARCH_SUN8IW3P1) && defined(CONFIG_DEVFREQ_DRAM_FREQ) - if (!dramfreq_need_suspend) { - if (freq < 100000) { - if (__ahb_set_rate(100000000)) { - CPUFREQ_ERR("set ahb to 100MHz failed!\n"); - } - } else { - if (__ahb_set_rate(200000000)) { - CPUFREQ_ERR("set ahb to 200MHz failed!\n"); - } - } - } -#endif - - if (unlikely(sunxi_dvfs_debug)) { -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) - printk("[cpufreq] DVFS done! Freq[%uMHz] Volt[%umv] ok\n\n", \ - sunxi_cpufreq_get(0) / 1000, sunxi_cpufreq_getvolt()); -#else - printk("[cpufreq] DFS done! Freq[%uMHz] ok\n\n", \ - sunxi_cpufreq_get(0) / 1000); -#endif - } - - -out: - mutex_unlock(&sunxi_cpu_lock); - - return ret; -} - - -/* - * get the frequency that cpu average is running; - * cpu: cpu number, all cpus use the same clock; - * return: cpu frequency, based on khz; - */ -static unsigned int sunxi_cpufreq_getavg(struct cpufreq_policy *policy, unsigned int cpu) -{ - return clk_get_rate(clk_cpu) / 1000; -} - - -/* - * get a valid frequency from cpu frequency table; - * target_freq: target frequency to be judge, based on KHz; - * return: cpu frequency, based on khz; - */ -static unsigned int __get_valid_freq(unsigned int target_freq) -{ - struct cpufreq_frequency_table *tmp = &sunxi_freq_tbl[0]; - - while(tmp->frequency != CPUFREQ_TABLE_END){ - if((tmp+1)->frequency <= target_freq) - tmp++; - else - break; - } - - return tmp->frequency; -} - -static int __init_vftable_syscfg(char *tbl_name, int value) -{ - script_item_u val; - script_item_value_type_e type; - int i ,ret = -1; - char name[16] = {0}; - - type = script_get_item(tbl_name, "LV_count", &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("fetch LV_count from sysconfig failed\n"); - goto fail; - } - - table_length_syscfg = val.val; - if(table_length_syscfg >= 16){ - CPUFREQ_ERR("LV_count from sysconfig is out of bounder\n"); - goto fail; - } - - for (i = 1; i <= table_length_syscfg; i++){ - sprintf(name, "LV%d_freq", i); - type = script_get_item(tbl_name, name, &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get LV%d_freq from sysconfig failed\n", i); - goto fail; - } - dvfs_table_syscfg[i-1].freq = val.val / 1000; - - sprintf(name, "LV%d_volt", i); - type = script_get_item(tbl_name, name, &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get LV%d_volt from sysconfig failed\n", i); - goto fail; - } - -#ifdef CONFIG_ARCH_SUN8IW3P1 - if (value) { - dvfs_table_syscfg[i-1].volt = val.val >= SUNXI_CPUFREQ_VOLT_LIMIT ? val.val : SUNXI_CPUFREQ_VOLT_LIMIT; - } else { - dvfs_table_syscfg[i-1].volt = val.val; - } -#else - dvfs_table_syscfg[i-1].volt = val.val; -#endif - } - - return 0; - -fail: - return ret; -} - -static void __vftable_show(void) -{ - int i; - - pr_debug("----------------CPU V-F Table-------------\n"); - for(i = 0; i < table_length_syscfg; i++){ - pr_debug("\tfrequency = %4dKHz \tvoltage = %4dmv\n", \ - dvfs_table_syscfg[i].freq, dvfs_table_syscfg[i].volt); - } - pr_debug("------------------------------------------\n"); -} - -/* - * init cpu max/min frequency from sysconfig; - * return: 0 - init cpu max/min successed, !0 - init cpu max/min failed; - */ -static int __init_freq_syscfg(char *tbl_name) -{ - int ret = 0; - script_item_u max, min, boot; - script_item_value_type_e type; - - type = script_get_item(tbl_name, "max_freq", &max); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu max frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - cpu_freq_max = max.val; - - type = script_get_item(tbl_name, "min_freq", &min); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu min frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - cpu_freq_min = min.val; - - type = script_get_item(tbl_name, "extremity_freq", &max); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu extremity frequency from sysconfig failed, use max_freq\n"); - max.val = cpu_freq_max; - } - cpu_freq_ext = max.val; - - type = script_get_item(tbl_name, "boot_freq", &boot); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - boot.val = cpu_freq_max; - } else { - sunxi_boot_freq_lock = 1; - } - cpu_freq_boot = boot.val; - - if(cpu_freq_max > SUNXI_CPUFREQ_MAX || cpu_freq_max < SUNXI_CPUFREQ_MIN - || cpu_freq_min < SUNXI_CPUFREQ_MIN || cpu_freq_min > SUNXI_CPUFREQ_MAX){ - CPUFREQ_ERR("cpu max or min frequency from sysconfig is more than range\n"); - ret = -1; - goto fail; - } - - if(cpu_freq_min > cpu_freq_max){ - CPUFREQ_ERR("cpu min frequency can not be more than cpu max frequency\n"); - ret = -1; - goto fail; - } - - if (cpu_freq_ext < cpu_freq_max) { - CPUFREQ_ERR("cpu ext frequency can not be less than cpu max frequency\n"); - ret = -1; - goto fail; - } - - if(cpu_freq_boot > cpu_freq_max || cpu_freq_boot < cpu_freq_min){ - CPUFREQ_ERR("cpu boot frequency can not be more than cpu max frequency\n"); - ret = -1; - goto fail; - } - - /* get valid max/min frequency from cpu frequency table */ - cpu_freq_max = __get_valid_freq(cpu_freq_max / 1000); - cpu_freq_min = __get_valid_freq(cpu_freq_min / 1000); - cpu_freq_ext = __get_valid_freq(cpu_freq_ext / 1000); - cpu_freq_boot = __get_valid_freq(cpu_freq_boot / 1000); - - return 0; - -fail: - /* use default cpu max/min frequency */ - cpu_freq_max = SUNXI_CPUFREQ_MAX / 1000; - cpu_freq_min = SUNXI_CPUFREQ_MIN / 1000; - cpu_freq_ext = SUNXI_CPUFREQ_MAX / 1000; - cpu_freq_boot = cpu_freq_max; - - return ret; -} - - -/* - * cpu frequency initialise a policy; - * policy: cpu frequency policy; - * result: return 0 if init ok, else, return -EINVAL; - */ -static int sunxi_cpufreq_init(struct cpufreq_policy *policy) -{ - policy->cur = sunxi_cpufreq_get(0); - policy->min = cpu_freq_min; - policy->max = cpu_freq_ext; - policy->cpuinfo.min_freq = cpu_freq_min; - policy->cpuinfo.max_freq = cpu_freq_ext; - policy->cpuinfo.boot_freq = cpu_freq_boot; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - - /* feed the latency information from the cpu driver */ - policy->cpuinfo.transition_latency = SUNXI_FREQTRANS_LATENCY; - cpufreq_frequency_table_get_attr(sunxi_freq_tbl, policy->cpu); - -#ifdef CONFIG_SMP - /* - * both processors share the same voltage and the same clock, - * but have dedicated power domains. So both cores needs to be - * scaled together and hence needs software co-ordination. - * Use cpufreq affected_cpus interface to handle this scenario. - */ - policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; - cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu)); -#endif - - return 0; -} - - -/* - * get current cpu frequency configuration; - * cfg: cpu frequency cofniguration; - * return: result; - */ -static int sunxi_cpufreq_getcur(struct sunxi_cpu_freq_t *cfg) -{ - unsigned int freq, freq0; - - if(!cfg) { - return -EINVAL; - } - - cfg->pll = clk_get_rate(clk_pll); - freq = clk_get_rate(clk_cpu); - cfg->div.cpu_div = cfg->pll / freq; - freq0 = clk_get_rate(clk_axi); - cfg->div.axi_div = freq / freq0; - - return 0; -} - - -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) -static int __set_pll_cpu_lock_time(void) -{ - unsigned int value; - - /* modify pll cpu lock time */ - value = readl(SUNXI_CCM_VBASE + 0x204); - value &= ~(0xffff); - value |= 0x400; - writel(value, SUNXI_CCM_VBASE + 0x204); - - return 0; -} -#endif - - -#ifdef CONFIG_PM - -/* - * cpu frequency configuration suspend; - */ -static int sunxi_cpufreq_suspend(struct cpufreq_policy *policy) -{ - return 0; -} - -/* - * cpu frequency configuration resume; - */ -static int sunxi_cpufreq_resume(struct cpufreq_policy *policy) -{ -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) - __set_pll_cpu_lock_time(); -#endif - - /* invalidate last_target setting */ - last_target = ~0; - return 0; -} - - -#else /* #ifdef CONFIG_PM */ - -#define sunxi_cpufreq_suspend NULL -#define sunxi_cpufreq_resume NULL - -#endif /* #ifdef CONFIG_PM */ - - -static struct cpufreq_driver sunxi_cpufreq_driver = { - .name = "cpufreq-sunxi", - .flags = CPUFREQ_STICKY, - .init = sunxi_cpufreq_init, - .verify = sunxi_cpufreq_verify, - .target = sunxi_cpufreq_target, - .get = sunxi_cpufreq_get, - .getavg = sunxi_cpufreq_getavg, - .suspend = sunxi_cpufreq_suspend, - .resume = sunxi_cpufreq_resume, -}; - - -/* - * cpu frequency driver init - */ -static int __init sunxi_cpufreq_initcall(void) -{ - int ret = 0; - char vftbl_name[16] = {0}; - int flag = 0; - -#if defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) - __set_pll_cpu_lock_time(); - pll_cpu_reg = (struct ccu_pll_cpu_ctrl_reg *)SUNXI_CCM_VBASE; - cpu_axi_reg = (struct ccu_cpu_axi_cfg_reg *)(SUNXI_CCM_VBASE + 0x50); -#endif - -#if defined(CONFIG_ARCH_SUN8IW1P1) || defined(CONFIG_ARCH_SUN8IW3P1) - clk_pll = clk_get(NULL, PLL1_CLK); -#elif defined(CONFIG_ARCH_SUN8IW5P1) || defined(CONFIG_ARCH_SUN8IW7P1) || defined(CONFIG_ARCH_SUN8IW8P1) - clk_pll = clk_get(NULL, PLL_CPU_CLK); -#endif - - clk_cpu = clk_get(NULL, CPU_CLK); - clk_axi = clk_get(NULL, AXI_CLK); - - if (IS_ERR(clk_pll) || IS_ERR(clk_cpu) || IS_ERR(clk_axi)) { - CPUFREQ_ERR("%s: could not get clock(s)\n", __func__); - return -ENOENT; - } - - pr_debug("%s: clocks pll=%lu,cpu=%lu,axi=%lu\n", __func__, - clk_get_rate(clk_pll), clk_get_rate(clk_cpu), clk_get_rate(clk_axi)); - - /* initialise current frequency configuration */ - sunxi_cpufreq_getcur(&cpu_cur); - sunxi_cpufreq_show("cur", &cpu_cur); - -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) - cpu_vdd = regulator_get(NULL, SUNXI_CPUFREQ_CPUVDD); - if (IS_ERR(cpu_vdd)) { - CPUFREQ_ERR("%s: could not get cpu vdd\n", __func__); - return -ENOENT; - } -#endif - -#ifdef CONFIG_ARCH_SUN8IW3P1 - writel(BIT(15), IO_ADDRESS(0x01c00024)); - if ((readl(IO_ADDRESS(0x01c00024)) >> 16) == MAGIC0) { - sprintf(vftbl_name, "dvfs_table"); - } else { - if (script_is_main_key_exist("dvfs_table_bak")) { - sprintf(vftbl_name, "dvfs_table_bak"); - } else { - sprintf(vftbl_name, "dvfs_table"); - flag = 1; - } - } -#else - sprintf(vftbl_name, "dvfs_table"); -#endif - - /* init cpu frequency from sysconfig */ - if(__init_freq_syscfg(vftbl_name)) { - CPUFREQ_ERR("%s, use default cpu max/min frequency, max freq: %uMHz, min freq: %uMHz\n", - __func__, cpu_freq_max/1000, cpu_freq_min/1000); - }else{ - pr_debug("%s, get cpu frequency from sysconfig, max freq: %uMHz, min freq: %uMHz\n", - __func__, cpu_freq_max/1000, cpu_freq_min/1000); - } - - ret = __init_vftable_syscfg(vftbl_name, flag); - if (ret) { - CPUFREQ_ERR("%s get V-F table failed\n", __func__); - return ret; - } else { - __vftable_show(); - } - - /* register cpu frequency driver */ - ret = cpufreq_register_driver(&sunxi_cpufreq_driver); - - return ret; -} -module_init(sunxi_cpufreq_initcall); - -/* - * cpu frequency driver exit - */ -static void __exit sunxi_cpufreq_exitcall(void) -{ -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) - regulator_put(cpu_vdd); -#endif - clk_put(clk_pll); - clk_put(clk_cpu); - clk_put(clk_axi); - cpufreq_unregister_driver(&sunxi_cpufreq_driver); -} -module_exit(sunxi_cpufreq_exitcall); - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_cpufreq_root; - -static int cpufreq_get_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", cpufreq_get_time_usecs); - return 0; -} - -static int cpufreq_get_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, cpufreq_get_time_show, inode->i_private); -} - -static const struct file_operations cpufreq_get_time_fops = { - .open = cpufreq_get_time_open, - .read = seq_read, -}; - -static int cpufreq_set_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", cpufreq_set_time_usecs); - return 0; -} - -static int cpufreq_set_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, cpufreq_set_time_show, inode->i_private); -} - -static const struct file_operations cpufreq_set_time_fops = { - .open = cpufreq_set_time_open, - .read = seq_read, -}; - -static int __init cpufreq_debug_init(void) -{ - int err = 0; - - debugfs_cpufreq_root = debugfs_create_dir("cpufreq", 0); - if (!debugfs_cpufreq_root) - return -ENOMEM; - - if (!debugfs_create_file("get_time", 0444, debugfs_cpufreq_root, NULL, &cpufreq_get_time_fops)) { - err = -ENOMEM; - goto out; - } - - if (!debugfs_create_file("set_time", 0444, debugfs_cpufreq_root, NULL, &cpufreq_set_time_fops)) { - err = -ENOMEM; - goto out; - } - - return 0; - -out: - debugfs_remove_recursive(debugfs_cpufreq_root); - return err; -} - -static void __exit cpufreq_debug_exit(void) -{ - debugfs_remove_recursive(debugfs_cpufreq_root); -} - -late_initcall(cpufreq_debug_init); -module_exit(cpufreq_debug_exit); -#endif /* CONFIG_DEBUG_FS */ - -MODULE_DESCRIPTION("cpufreq driver for sunxi SOCs"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.h b/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.h deleted file mode 100755 index ca1389ab..00000000 --- a/linux-3.4/drivers/cpufreq.new/sunxi-cpufreq.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * drivers/cpufreq/sunxi-cpufreq.h - * - * Copyright (c) 2012 Softwinner. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __sunxi_CPU_FREQ_H__ -#define __sunxi_CPU_FREQ_H__ - -#include -#include - -#define CPUFREQ_ERR(format,args...) printk(KERN_ERR "[cpu_freq] ERR:"format,##args) - - -#define SUNXI_CPUFREQ_MAX (1536000000) /* config the maximum frequency of sunxi core */ -#define SUNXI_CPUFREQ_MIN (60000000) /* config the minimum frequency of sunxi core */ -#define SUNXI_FREQTRANS_LATENCY (2000000) /* config the transition latency, based on ns */ -#if !defined(CONFIG_ARCH_SUN8IW7P1) && !defined(CONFIG_ARCH_SUN8IW8P1) -#define SUNXI_CPUFREQ_CPUVDD "axp22_dcdc3" -#endif - -#ifdef CONFIG_ARCH_SUN8IW3P1 -#define SUNXI_CPUFREQ_VOLT_LIMIT (1100) -#endif - -struct sunxi_clk_div_t { - __u32 cpu_div:4; /* division of cpu clock, divide core_pll */ - __u32 axi_div:4; /* division of axi clock, divide cpu clock*/ - __u32 ahb_div:4; /* division of ahb clock, divide axi clock*/ - __u32 apb_div:4; /* division of apb clock, divide ahb clock*/ - __u32 reserved:16; -}; - -struct cpufreq_dvfs { - unsigned int freq; /* cpu frequency */ - unsigned int volt; /* voltage for the frequency */ -}; - -struct sunxi_cpu_freq_t { - __u32 pll; /* core pll frequency value */ - struct sunxi_clk_div_t div; /* division configuration */ -}; - - -#define SUNXI_CLK_DIV(cpu_div, axi_div, ahb_div, apb_div) \ - ((cpu_div<<0)|(axi_div<<4)|(ahb_div<<8)|(apb_div<<12)) - -#endif /* #ifndef __sunxi_CPU_FREQ_H__ */ - - diff --git a/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.c b/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.c deleted file mode 100755 index 17783fc4..00000000 --- a/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.c +++ /dev/null @@ -1,947 +0,0 @@ -/* - * linux/drivers/cpufreq/sunxi-iks-cpufreq.c - * - * Copyright(c) 2013-2015 Allwinnertech Co., Ltd. - * http://www.allwinnertech.com - * - * Author: sunny - * - * allwinner sunxi iks cpufreq driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_DEBUG_FS -#include -#include -#endif - -#include "sunxi-iks-cpufreq.h" - -#ifdef CONFIG_DEBUG_FS -static unsigned long long c0_set_time_usecs = 0; -static unsigned long long c0_get_time_usecs = 0; -static unsigned long long c1_set_time_usecs = 0; -static unsigned long long c1_get_time_usecs = 0; -#endif - - -#if defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW9P1) -#define PLL1_CLK PLL_CPU0_CLK -#define PLL2_CLK PLL_CPU1_CLK -static struct cpufreq_frequency_table sunxi_freq_table_ca7[] = { - {0, 2016 * 1000}, - {0, 1800 * 1000}, - {0, 1608 * 1000}, - {0, 1200 * 1000}, - {0, 1128 * 1000}, - {0, 1008 * 1000}, - {0, 912 * 1000}, - {0, 864 * 1000}, - {0, 720 * 1000}, - {0, 600 * 1000}, - {0, 480 * 1000}, - {0, CPUFREQ_TABLE_END}, -}; -#define sunxi_freq_table_ca15 sunxi_freq_table_ca7 - -/* - * Notice: - * The the definition of the minimum frequnecy should be a valid value - * in the frequnecy table, otherwise, there may be some power efficiency - * lost in the interactive governor, when the cpufreq_interactive_idle_start - * try to check the frequency status: - * if (pcpu->target_freq != pcpu->policy->min) {} - * the target_freq will never equal to the policy->min !!! Then, the timer - * will wakeup the cpu frequently -*/ -#define SUNXI_CPUFREQ_L_MAX (2016000000) /* config the maximum frequency of sunxi core */ -#define SUNXI_CPUFREQ_L_MIN (480000000) /* config the minimum frequency of sunxi core */ -#define SUNXI_CPUFREQ_B_MAX SUNXI_CPUFREQ_L_MAX /* config the maximum frequency of sunxi core */ -#define SUNXI_CPUFREQ_B_MIN SUNXI_CPUFREQ_L_MIN /* config the minimum frequency of sunxi core */ - -#else - -static struct cpufreq_frequency_table sunxi_freq_table_ca7[] = { - {0, 1200 * 1000}, - {0, 1104 * 1000}, - {0, 1008 * 1000}, - {0, 912 * 1000}, - {0, 816 * 1000}, - {0, 720 * 1000}, - {0, 600 * 1000}, - {0, 480 * 1000}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct cpufreq_frequency_table sunxi_freq_table_ca15[] = { - {0, 1800 * 1000}, - {0, 1704 * 1000}, - {0, 1608 * 1000}, - {0, 1512 * 1000}, - {0, 1416 * 1000}, - {0, 1320 * 1000}, - {0, 1200 * 1000}, - {0, 1104 * 1000}, - {0, 1008 * 1000}, - {0, 912 * 1000}, - {0, 816 * 1000}, - {0, 720 * 1000}, - {0, 600 * 1000}, - {0, CPUFREQ_TABLE_END}, -}; - -/* - * Notice: - * The the definition of the minimum frequnecy should be a valid value - * in the frequnecy table, otherwise, there may be some power efficiency - * lost in the interactive governor, when the cpufreq_interactive_idle_start - * try to check the frequency status: - * if (pcpu->target_freq != pcpu->policy->min) {} - * the target_freq will never equal to the policy->min !!! Then, the timer - * will wakeup the cpu frequently -*/ -#define SUNXI_CPUFREQ_L_MAX (1200000000) /* config the maximum frequency of sunxi core */ -#define SUNXI_CPUFREQ_L_MIN (480000000) /* config the minimum frequency of sunxi core */ -#define SUNXI_CPUFREQ_B_MAX (1800000000) /* config the maximum frequency of sunxi core */ -#define SUNXI_CPUFREQ_B_MIN (600000000) /* config the minimum frequency of sunxi core */ - -#endif - -static unsigned int l_freq_max = SUNXI_CPUFREQ_L_MAX / 1000; -static unsigned int l_freq_boot = SUNXI_CPUFREQ_L_MAX / 1000; -static unsigned int l_freq_ext = SUNXI_CPUFREQ_L_MAX / 1000; -static unsigned int l_freq_min = SUNXI_CPUFREQ_L_MIN / 1000; -static unsigned int b_freq_max = SUNXI_CPUFREQ_B_MAX / 1000; -static unsigned int b_freq_boot = SUNXI_CPUFREQ_B_MAX / 1000; -static unsigned int b_freq_ext = SUNXI_CPUFREQ_B_MAX / 1000; -static unsigned int b_freq_min = SUNXI_CPUFREQ_B_MIN / 1000; - -#ifdef CONFIG_BL_SWITCHER -bool bL_switching_enabled; -#endif - -int sunxi_dvfs_debug = 0; -int sunxi_boot_freq_lock = 0; - -static struct clk *clk_pll1; /* pll1 clock handler */ -static struct clk *clk_pll2; /* pll2 clock handler */ -static struct clk *cluster_clk[MAX_CLUSTERS]; -static unsigned int cluster_pll[MAX_CLUSTERS]; -static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; -static struct regulator *cpu_vdd[MAX_CLUSTERS]; /* cpu vdd handler */ - -static DEFINE_PER_CPU(unsigned int, physical_cluster); -static DEFINE_PER_CPU(unsigned int, cpu_last_req_freq); - -static struct mutex cluster_lock[MAX_CLUSTERS]; - -static unsigned int find_cluster_maxfreq(int cluster) -{ - int j; - u32 max_freq = 0, cpu_freq; - - for_each_online_cpu(j) { - cpu_freq = per_cpu(cpu_last_req_freq, j); - if ((cluster == per_cpu(physical_cluster, j)) && (max_freq < cpu_freq)) { - max_freq = cpu_freq; - } - } - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("%s: cluster:%d, max freq:%d\n", __func__, cluster, max_freq); - - return max_freq; -} - -/* - * get the current cpu vdd; - * return: cpu vdd, based on mv; - */ -static int sunxi_cpufreq_getvolt(unsigned int cpu) -{ - u32 cur_cluster = per_cpu(physical_cluster, cpu); - return regulator_get_voltage(cpu_vdd[cur_cluster]) / 1000; -} - - -static unsigned int sunxi_clk_get_cpu_rate(unsigned int cpu) -{ - u32 cur_cluster = per_cpu(physical_cluster, cpu), rate; -#ifdef CONFIG_DEBUG_FS - ktime_t calltime = ktime_set(0, 0), delta, rettime; -#endif - - mutex_lock(&cluster_lock[cur_cluster]); - -#ifdef CONFIG_DEBUG_FS - calltime = ktime_get(); -#endif - - if (cur_cluster == A7_CLUSTER) - clk_get_rate(clk_pll1); - else if (cur_cluster == A15_CLUSTER) - clk_get_rate(clk_pll2); - - rate = clk_get_rate(cluster_clk[cur_cluster]) / 1000; - - /* For switcher we use virtual A15 clock rates */ - if (is_bL_switching_enabled()) { - rate = VIRT_FREQ(cur_cluster, rate); - } - -#ifdef CONFIG_DEBUG_FS - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - if (cur_cluster == A7_CLUSTER) - c0_get_time_usecs = ktime_to_ns(delta) >> 10; - else if (cur_cluster == A15_CLUSTER) - c1_get_time_usecs = ktime_to_ns(delta) >> 10; -#endif - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("cpu:%d, cur_cluster:%d, cur_freq:%d\n", cpu, cur_cluster, rate); - - mutex_unlock(&cluster_lock[cur_cluster]); - - return rate; -} - -#ifdef CONFIG_SUNXI_ARISC -static int clk_set_fail_notify(void *arg) -{ - CPUFREQ_ERR("%s: cluster: %d\n", __func__, (u32)arg); - - /* maybe should do others */ - - return 0; -} -#endif - -static int sunxi_clk_set_cpu_rate(unsigned int cluster, unsigned int cpu, unsigned int rate) -{ - int ret; -#ifdef CONFIG_DEBUG_FS - ktime_t calltime = ktime_set(0, 0), delta, rettime; -#endif - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("cpu:%d, cluster:%d, set freq:%u\n", cpu, cluster, rate); - -#ifdef CONFIG_DEBUG_FS - calltime = ktime_get(); -#endif - -#ifndef CONFIG_SUNXI_ARISC - ret = 0; -#else - /* the rate is base on khz */ - ret = arisc_dvfs_set_cpufreq(rate, cluster_pll[cluster], - ARISC_MESSAGE_ATTR_SOFTSYN, clk_set_fail_notify, (void *)cluster); -#endif - -#ifdef CONFIG_DEBUG_FS - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - if (cluster == A7_CLUSTER) - c0_set_time_usecs = ktime_to_ns(delta) >> 10; - else if (cluster == A15_CLUSTER) - c1_set_time_usecs = ktime_to_ns(delta) >> 10; -#endif - - return ret; -} - -static unsigned int sunxi_cpufreq_set_rate(u32 cpu, u32 old_cluster, - u32 new_cluster, u32 rate) -{ - u32 new_rate, prev_rate; - int ret; - - mutex_lock(&cluster_lock[new_cluster]); - - prev_rate = per_cpu(cpu_last_req_freq, cpu); - per_cpu(cpu_last_req_freq, cpu) = rate; - per_cpu(physical_cluster, cpu) = new_cluster; - - if (is_bL_switching_enabled()) { - new_rate = find_cluster_maxfreq(new_cluster); - new_rate = ACTUAL_FREQ(new_cluster, new_rate); - } else { - new_rate = rate; - } - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("cpu:%d, old cluster:%d, new cluster:%d, target freq:%d\n", - cpu, old_cluster, new_cluster, new_rate); - - ret = sunxi_clk_set_cpu_rate(new_cluster, cpu, new_rate); - if (WARN_ON(ret)) { - CPUFREQ_ERR("clk_set_rate failed:%d, new cluster:%d\n", ret, new_cluster); - per_cpu(cpu_last_req_freq, cpu) = prev_rate; - per_cpu(physical_cluster, cpu) = old_cluster; - - mutex_unlock(&cluster_lock[new_cluster]); - - return ret; - } - mutex_unlock(&cluster_lock[new_cluster]); - - if (is_bL_switching_enabled()) { - /* Recalc freq for old cluster when switching clusters */ - if (old_cluster != new_cluster) { - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("cpu:%d, switch from cluster-%d to cluster-%d\n", cpu, old_cluster, new_cluster); - - bL_switch_request(cpu, new_cluster); - - mutex_lock(&cluster_lock[old_cluster]); - /* Set freq of old cluster if there are cpus left on it */ - new_rate = find_cluster_maxfreq(old_cluster); - new_rate = ACTUAL_FREQ(old_cluster, new_rate); - if (new_rate) { - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("Updating rate of old cluster:%d, to freq:%d\n", old_cluster, new_rate); - - if (sunxi_clk_set_cpu_rate(old_cluster, cpu, new_rate)) - CPUFREQ_ERR("clk_set_rate failed: %d, old cluster:%d\n", ret, old_cluster); - } - mutex_unlock(&cluster_lock[old_cluster]); - } - } - - return 0; -} - -/* Validate policy frequency range */ -static int sunxi_cpufreq_verify_policy(struct cpufreq_policy *policy) -{ - u32 cur_cluster = cpu_to_cluster(policy->cpu); - - return cpufreq_frequency_table_verify(policy, freq_table[cur_cluster]); -} - -/* Set clock frequency */ -static int sunxi_cpufreq_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - struct cpufreq_freqs freqs; - u32 cpu = policy->cpu, freq_tab_idx; - u32 cur_cluster, new_cluster, actual_cluster; - int ret = 0; - int boot_freq = 0; -#ifdef CONFIG_SCHED_SMP_DCMP - u32 i,other_cluster; -#endif - - freqs.old = sunxi_clk_get_cpu_rate(cpu); - if (freqs.old == target_freq) { - return 0; - } - - cur_cluster = cpu_to_cluster(cpu); - new_cluster = actual_cluster = per_cpu(physical_cluster, cpu); - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("request frequency is %u\n", target_freq); - - if (unlikely(sunxi_boot_freq_lock)) { - boot_freq = cur_cluster == A7_CLUSTER ? l_freq_boot : b_freq_boot; - target_freq = target_freq > boot_freq ? boot_freq : target_freq; - } - - /* Determine valid target frequency using freq_table */ - ret = cpufreq_frequency_table_target(policy, freq_table[cur_cluster], - target_freq, relation, &freq_tab_idx); - if (ret) { - CPUFREQ_ERR("try to look for a valid frequency for %u failed!\n", target_freq); - return ret; - } - - freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency; - if (freqs.old == freqs.new) { - return 0; - } - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("target frequency find is %u, entry %u\n", freqs.new, freq_tab_idx); - - if (is_bL_switching_enabled()) { - if ((actual_cluster == A15_CLUSTER) && - (freqs.new < SUNXI_BL_SWITCH_THRESHOLD)) { - new_cluster = A7_CLUSTER; - } else if ((actual_cluster == A7_CLUSTER) && - (freqs.new > SUNXI_BL_SWITCH_THRESHOLD)) { - new_cluster = A15_CLUSTER; - } - } - - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - - ret = sunxi_cpufreq_set_rate(cpu, actual_cluster, new_cluster, freqs.new); -#ifdef CONFIG_SCHED_SMP_DCMP - for_each_online_cpu(i) - { - other_cluster = cpu_to_cluster(i); - if(other_cluster != actual_cluster) - { - ret = sunxi_cpufreq_set_rate(i, other_cluster, other_cluster, freqs.new); - break; - } - } -#endif - - if (ret) { - return ret; - } - - policy->cur = freqs.new; - - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("DVFS done! Freq[%uMHz] Volt[%umv] ok\n\n", - sunxi_clk_get_cpu_rate(cpu) / 1000, sunxi_cpufreq_getvolt(cpu)); - - return ret; -} - -static inline u32 get_table_count(struct cpufreq_frequency_table *table) -{ - int count; - - for (count = 0; table[count].frequency != CPUFREQ_TABLE_END; count++) { - ; - } - - return count; -} - - -static int merge_cluster_tables(void) -{ - int i, j, k = 0, count = 1; - struct cpufreq_frequency_table *table; - - for (i = 0; i < MAX_CLUSTERS; i++) { - count += get_table_count(freq_table[i]); - } - - table = kzalloc(sizeof(*table) * count, GFP_KERNEL); - if (!table) { - return -ENOMEM; - } - freq_table[MAX_CLUSTERS] = table; - - /* Add in reverse order to get freqs in increasing order */ - for (i = MAX_CLUSTERS - 1; i >= 0; i--) { - for (j = 0; freq_table[i][j].frequency != CPUFREQ_TABLE_END; j++) { - table[k].frequency = VIRT_FREQ(i, freq_table[i][j].frequency); - CPUFREQ_DBG("%s: index: %d, freq: %d\n", __func__, k, table[k].frequency); - k++; - } - } - - table[k].index = k; - table[k].frequency = CPUFREQ_TABLE_END; - - CPUFREQ_DBG("%s: End, table: %p, count: %d\n", __func__, table, k); - - return 0; -} - -/* - * init cpu max/min frequency from sysconfig; - * return: 0 - init cpu max/min successed, !0 - init cpu max/min failed; - */ -static int __init_freq_syscfg(char *tbl_name) -{ - int ret = 0; - script_item_u l_max, l_min, b_max, b_min, l_boot, l_ext, b_boot, b_ext; - script_item_value_type_e type; - - type = script_get_item(tbl_name, "L_max_freq", &l_max); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu l_max frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - l_freq_max = l_max.val; - - type = script_get_item(tbl_name, "L_min_freq", &l_min); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu l_min frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - l_freq_min = l_min.val; - - type = script_get_item(tbl_name, "L_extremity_freq", &l_ext); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - l_ext.val = l_freq_max; - } - l_freq_ext = l_ext.val; - - type = script_get_item(tbl_name, "L_boot_freq", &l_boot); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - l_boot.val = l_freq_max; - } else { - sunxi_boot_freq_lock = 1; - } - l_freq_boot = l_boot.val; - - type = script_get_item(tbl_name, "B_max_freq", &b_max); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu b_max frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - b_freq_max = b_max.val; - - type = script_get_item(tbl_name, "B_min_freq", &b_min); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_ERR("get cpu b_min frequency from sysconfig failed\n"); - ret = -1; - goto fail; - } - b_freq_min = b_min.val; - - type = script_get_item(tbl_name, "B_extremity_freq", &b_ext); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - b_ext.val = b_freq_max; - } - b_freq_ext = b_ext.val; - - type = script_get_item(tbl_name, "B_boot_freq", &b_boot); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - b_boot.val = b_freq_max; - } else { - sunxi_boot_freq_lock = 1; - } - b_freq_boot = b_boot.val; - - if (l_freq_max > SUNXI_CPUFREQ_L_MAX || l_freq_max < SUNXI_CPUFREQ_L_MIN - || l_freq_min < SUNXI_CPUFREQ_L_MIN || l_freq_min > SUNXI_CPUFREQ_L_MAX) { - CPUFREQ_ERR("l_cpu max or min frequency from sysconfig is more than range\n"); - ret = -1; - goto fail; - } - - if (l_freq_min > l_freq_max) { - CPUFREQ_ERR("l_cpu min frequency can not be more than l_cpu max frequency\n"); - ret = -1; - goto fail; - } - - if (l_freq_ext < l_freq_max) { - CPUFREQ_ERR("l_cpu ext frequency can not be less than l_cpu max frequency\n"); - ret = -1; - goto fail; - } - - if (l_freq_boot > l_freq_max || l_freq_boot < l_freq_min) { - CPUFREQ_ERR("l_cpu boot frequency invalid\n"); - ret = -1; - goto fail; - } - - if (b_freq_max > SUNXI_CPUFREQ_B_MAX || b_freq_max < SUNXI_CPUFREQ_B_MIN - || b_freq_min < SUNXI_CPUFREQ_B_MIN || b_freq_min > SUNXI_CPUFREQ_B_MAX) { - CPUFREQ_ERR("b_cpu max or min frequency from sysconfig is more than range\n"); - ret = -1; - goto fail; - } - - if (b_freq_min > b_freq_max) { - CPUFREQ_ERR("b_cpu min frequency can not be more than b_cpu max frequency\n"); - ret = -1; - goto fail; - } - - if (b_freq_ext < b_freq_max) { - CPUFREQ_ERR("b_cpu ext frequency can not be less than b_cpu max frequency\n"); - ret = -1; - goto fail; - } - - if (b_freq_boot > b_freq_max || b_freq_boot < b_freq_min) { - CPUFREQ_ERR("b_cpu boot frequency invalid\n"); - ret = -1; - goto fail; - } - - l_freq_max /= 1000; - l_freq_min /= 1000; - l_freq_ext /= 1000; - l_freq_boot /= 1000; - b_freq_max /= 1000; - b_freq_min /= 1000; - b_freq_ext /= 1000; - b_freq_boot /= 1000; - - return 0; - -fail: - /* use default cpu max/min frequency */ - l_freq_max = SUNXI_CPUFREQ_L_MAX / 1000; - l_freq_min = SUNXI_CPUFREQ_L_MIN / 1000; - l_freq_ext = l_freq_max; - l_freq_boot = l_freq_max; - b_freq_max = SUNXI_CPUFREQ_B_MAX / 1000; - b_freq_min = SUNXI_CPUFREQ_B_MIN / 1000; - b_freq_ext = b_freq_max; - b_freq_boot = b_freq_max; - - return ret; -} - -static int sunxi_cpufreq_cpu_init(struct cpufreq_policy *policy) -{ - u32 cur_cluster = cpu_to_cluster(policy->cpu); - u32 cpu; - - /* set cpu freq-table */ - if (is_bL_switching_enabled()) { - /* bL switcher use the merged freq table */ - cpufreq_frequency_table_get_attr(freq_table[MAX_CLUSTERS], policy->cpu); - } else { - /* HMP use the per-cluster freq table */ - cpufreq_frequency_table_get_attr(freq_table[cur_cluster], policy->cpu); - } - - /* set the target cluster of cpu */ - if (cur_cluster < MAX_CLUSTERS) { - /* set cpu masks */ -#ifdef CONFIG_SCHED_SMP_DCMP - cpumask_copy(policy->cpus, cpu_possible_mask); -#else - cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu)); -#endif - /* set core sibling */ - for_each_cpu(cpu, topology_core_cpumask(policy->cpu)) { - per_cpu(physical_cluster, cpu) = cur_cluster; - } - } else { - /* Assumption: during init, we are always running on A7 */ - per_cpu(physical_cluster, policy->cpu) = A7_CLUSTER; - } - /* initialize current cpu freq */ - policy->cur = sunxi_clk_get_cpu_rate(policy->cpu); - per_cpu(cpu_last_req_freq, policy->cpu) = policy->cur; - - if (unlikely(sunxi_dvfs_debug)) - CPUFREQ_DBG("cpu:%d, cluster:%d, init freq:%d\n", policy->cpu, cur_cluster, policy->cur); - - /* set the policy min and max freq */ - if (is_bL_switching_enabled()) { - /* bL switcher use the merged freq table */ - cpufreq_frequency_table_cpuinfo(policy, freq_table[MAX_CLUSTERS]); - } else { - /* HMP use the per-cluster freq table */ - if (cur_cluster == A7_CLUSTER) { - policy->min = policy->cpuinfo.min_freq = l_freq_min; - policy->max = policy->cpuinfo.max_freq = l_freq_ext; - policy->cpuinfo.boot_freq = l_freq_boot; - } else if (cur_cluster == A15_CLUSTER) { - policy->min = policy->cpuinfo.min_freq = b_freq_min; - policy->max = policy->cpuinfo.max_freq = b_freq_ext; - policy->cpuinfo.boot_freq = b_freq_boot; - } - } - - /* set the transition latency value */ - policy->cpuinfo.transition_latency = SUNXI_FREQTRANS_LATENCY; - - return 0; -} - -/* Export freq_table to sysfs */ -static struct freq_attr *sunxi_cpufreq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver sunxi_cpufreq_driver = { - .name = "sunxi-iks", - .flags = CPUFREQ_STICKY, - .verify = sunxi_cpufreq_verify_policy, - .target = sunxi_cpufreq_set_target, - .get = sunxi_clk_get_cpu_rate, - .init = sunxi_cpufreq_cpu_init, - .have_governor_per_policy = true, - .attr = sunxi_cpufreq_attr, -}; - -static int sunxi_cpufreq_switcher_notifier(struct notifier_block *nfb, - unsigned long action, void *_arg) -{ - pr_info("%s: action:%lu\n", __func__, action); - - switch (action) { - case BL_NOTIFY_PRE_ENABLE: - case BL_NOTIFY_PRE_DISABLE: - cpufreq_unregister_driver(&sunxi_cpufreq_driver); - break; - - case BL_NOTIFY_POST_ENABLE: - set_switching_enabled(true); - cpufreq_register_driver(&sunxi_cpufreq_driver); - break; - - case BL_NOTIFY_POST_DISABLE: - set_switching_enabled(false); - cpufreq_register_driver(&sunxi_cpufreq_driver); - break; - - default: - return NOTIFY_DONE; - } - - return NOTIFY_OK; -} - -static struct notifier_block sunxi_switcher_notifier = { - .notifier_call = sunxi_cpufreq_switcher_notifier, -}; - -static int __init sunxi_cpufreq_init(void) -{ - int ret, i; - char vftbl_name[16] = {0}; - script_item_u vf_table_count; - script_item_value_type_e type; - unsigned int vf_table_type = 0; - - ret = bL_switcher_get_enabled(); - set_switching_enabled(ret); - - /* get pll1 pll2 clock handle */ - clk_pll1 = clk_get(NULL, PLL1_CLK); - clk_pll2 = clk_get(NULL, PLL2_CLK); - - /* get cluster clock handle */ - cluster_clk[A7_CLUSTER] = clk_get(NULL, CLUSTER0_CLK); - cluster_clk[A15_CLUSTER] = clk_get(NULL, CLUSTER1_CLK); - - /* initialize cpufreq table and merge ca7/ca15 table */ - freq_table[A7_CLUSTER] = sunxi_freq_table_ca7; - freq_table[A15_CLUSTER] = sunxi_freq_table_ca15; - merge_cluster_tables(); - - /* initialize ca7 and ca15 cluster pll number */ - cluster_pll[A7_CLUSTER] = ARISC_DVFS_PLL1; - cluster_pll[A15_CLUSTER] = ARISC_DVFS_PLL2; - - cpu_vdd[A7_CLUSTER] = regulator_get(NULL, SUNXI_CPUFREQ_C0_CPUVDD); - if (IS_ERR(cpu_vdd[A7_CLUSTER])) { - CPUFREQ_ERR("%s: could not get Cluster0 cpu vdd\n", __func__); - return -ENOENT; - } - - cpu_vdd[A15_CLUSTER] = regulator_get(NULL, SUNXI_CPUFREQ_C1_CPUVDD); - if (IS_ERR(cpu_vdd[A15_CLUSTER])) { - regulator_put(cpu_vdd[A7_CLUSTER]); - CPUFREQ_ERR("%s: could not get Cluster1 cpu vdd\n", __func__); - return -ENOENT; - } - - type = script_get_item("dvfs_table", "vf_table_count", &vf_table_count); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - CPUFREQ_DBG("%s: support only one vf_table\n", __func__); - sprintf(vftbl_name, "%s", "dvfs_table"); - } else { - vf_table_type = sunxi_get_soc_bin(); - sprintf(vftbl_name, "%s%d", "vf_table", vf_table_type); - } - - /* init cpu frequency from sysconfig */ - if(__init_freq_syscfg(vftbl_name)) { - CPUFREQ_ERR("%s, use default cpu max/min frequency, l_max: %uMHz, l_min: %uMHz, b_max: %uMHz, b_min: %uMHz\n", - __func__, l_freq_max/1000, l_freq_min/1000, b_freq_max/1000, b_freq_min/1000); - }else{ - CPUFREQ_DBG("%s, get cpu frequency from sysconfig, l_max: %uMHz, l_min: %uMHz, b_max: %uMHz, b_min: %uMHz\n", - __func__, l_freq_max/1000, l_freq_min/1000, b_freq_max/1000, b_freq_min/1000); - } - - for (i = 0; i < MAX_CLUSTERS; i++) { - mutex_init(&cluster_lock[i]); - } - - ret = cpufreq_register_driver(&sunxi_cpufreq_driver); - if (ret) { - CPUFREQ_ERR("sunxi register cpufreq driver fail, err: %d\n", ret); - } else { - CPUFREQ_DBG("sunxi register cpufreq driver succeed\n"); - ret = bL_switcher_register_notifier(&sunxi_switcher_notifier); - if (ret) { - CPUFREQ_ERR("sunxi register bL notifier fail, err: %d\n", ret); - cpufreq_unregister_driver(&sunxi_cpufreq_driver); - } else { - CPUFREQ_DBG("sunxi register bL notifier succeed\n"); - } - } - - bL_switcher_put_enabled(); - - pr_debug("%s: done!\n", __func__); - return ret; -} -module_init(sunxi_cpufreq_init); - -static void __exit sunxi_cpufreq_exit(void) -{ - int i; - - for (i = 0; i < MAX_CLUSTERS; i++) - mutex_destroy(&cluster_lock[i]); - - clk_put(clk_pll1); - clk_put(clk_pll2); - clk_put(cluster_clk[A7_CLUSTER]); - clk_put(cluster_clk[A15_CLUSTER]); - regulator_put(cpu_vdd[A7_CLUSTER]); - regulator_put(cpu_vdd[A15_CLUSTER]); - bL_switcher_get_enabled(); - bL_switcher_unregister_notifier(&sunxi_switcher_notifier); - cpufreq_unregister_driver(&sunxi_cpufreq_driver); - bL_switcher_put_enabled(); - CPUFREQ_DBG("%s: done!\n", __func__); -} -module_exit(sunxi_cpufreq_exit); - -#ifdef CONFIG_DEBUG_FS -static struct dentry *debugfs_cpufreq_root; - -static int get_c0_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", c0_get_time_usecs); - return 0; -} - -static int get_c0_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, get_c0_time_show, inode->i_private); -} - -static const struct file_operations get_c0_time_fops = { - .open = get_c0_time_open, - .read = seq_read, -}; - -static int set_c0_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", c0_set_time_usecs); - return 0; -} - -static int set_c0_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, set_c0_time_show, inode->i_private); -} - -static const struct file_operations set_c0_time_fops = { - .open = set_c0_time_open, - .read = seq_read, -}; - -static int get_c1_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", c1_get_time_usecs); - return 0; -} - -static int get_c1_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, get_c1_time_show, inode->i_private); -} - -static const struct file_operations get_c1_time_fops = { - .open = get_c1_time_open, - .read = seq_read, -}; - -static int set_c1_time_show(struct seq_file *s, void *data) -{ - seq_printf(s, "%Ld\n", c1_set_time_usecs); - return 0; -} - -static int set_c1_time_open(struct inode *inode, struct file *file) -{ - return single_open(file, set_c1_time_show, inode->i_private); -} - -static const struct file_operations set_c1_time_fops = { - .open = set_c1_time_open, - .read = seq_read, -}; - -static int __init debug_init(void) -{ - int err = 0; - - debugfs_cpufreq_root = debugfs_create_dir("cpufreq", 0); - if (!debugfs_cpufreq_root) - return -ENOMEM; - - if (!debugfs_create_file("c0_get_time", 0444, debugfs_cpufreq_root, NULL, &get_c0_time_fops)) { - err = -ENOMEM; - goto out; - } - - if (!debugfs_create_file("c0_set_time", 0444, debugfs_cpufreq_root, NULL, &set_c0_time_fops)) { - err = -ENOMEM; - goto out; - } - - if (!debugfs_create_file("c1_get_time", 0444, debugfs_cpufreq_root, NULL, &get_c1_time_fops)) { - err = -ENOMEM; - goto out; - } - - if (!debugfs_create_file("c1_set_time", 0444, debugfs_cpufreq_root, NULL, &set_c1_time_fops)) { - err = -ENOMEM; - goto out; - } - - return 0; - -out: - debugfs_remove_recursive(debugfs_cpufreq_root); - return err; -} - -static void __exit debug_exit(void) -{ - debugfs_remove_recursive(debugfs_cpufreq_root); -} - -late_initcall(debug_init); -module_exit(debug_exit); -#endif /* CONFIG_DEBUG_FS */ - -MODULE_AUTHOR("sunny "); -MODULE_DESCRIPTION("sunxi iks cpufreq driver"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.h b/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.h deleted file mode 100755 index 4ce836a3..00000000 --- a/linux-3.4/drivers/cpufreq.new/sunxi-iks-cpufreq.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * linux/drivers/cpufreq/sunxi-iks-cpufreq.h - * - * Copyright(c) 2013-2015 Allwinnertech Co., Ltd. - * http://www.allwinnertech.com - * - * Author: sunny - * - * allwinner sunxi iks cpufreq driver header file. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef CPUFREQ_SUNXI_IKS_H -#define CPUFREQ_SUNXI_IKS_H - -#include -#include -#include - -#define CPUFREQ_DBG(format,args...) pr_debug("[cpu_freq] DBG: "format,##args) -#define CPUFREQ_ERR(format,args...) printk(KERN_ERR "[cpu_freq] ERR: "format,##args) - -/* sun9i platform support two clusters, - * cluster0 : cortex-a7, - * cluster1 : cortex-a15. - */ -#define A7_CLUSTER 0 -#define A15_CLUSTER 1 -#define MAX_CLUSTERS 2 - - -#ifdef CONFIG_ARCH_SUN9IW1P1 -#define SUNXI_CPUFREQ_C0_CPUVDD "axp22_dcdc3" -#define SUNXI_CPUFREQ_C1_CPUVDD "axp15_dcdc1" -#elif defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW9P1) -#define SUNXI_CPUFREQ_C0_CPUVDD "vdd-cpua" -#define SUNXI_CPUFREQ_C1_CPUVDD "vdd-cpub" -#endif - -/* the actual and virtual freq convert */ -#define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) -#define VIRT_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq >> 1 : freq) - -/* the threshold freq of cpu big little switch */ -#define SUNXI_BL_SWITCH_THRESHOLD (600000) - -/* config the transition latency, based on ns */ -#define SUNXI_FREQTRANS_LATENCY (2000000) - -#ifdef CONFIG_BL_SWITCHER -extern bool bL_switching_enabled; -#define is_bL_switching_enabled() bL_switching_enabled -#define set_switching_enabled(x) (bL_switching_enabled = (x)) -#else -#define is_bL_switching_enabled() false -#define set_switching_enabled(x) do { } while (0) -#endif - -static inline int cpu_to_cluster(int cpu) -{ -#ifdef CONFIG_SMP - return is_bL_switching_enabled() ? MAX_CLUSTERS : topology_physical_package_id(cpu); -#else - return 0; -#endif -} - -#endif /* CPUFREQ_SUNXI_IKS_H */ diff --git a/linux-3.4/drivers/thermal.new/Kconfig b/linux-3.4/drivers/thermal.new/Kconfig deleted file mode 100755 index 96ead7d5..00000000 --- a/linux-3.4/drivers/thermal.new/Kconfig +++ /dev/null @@ -1,156 +0,0 @@ -# -# Generic thermal sysfs drivers configuration -# - -menuconfig THERMAL - tristate "Generic Thermal sysfs driver" - help - Generic Thermal Sysfs driver offers a generic mechanism for - thermal management. Usually it's made up of one or more thermal - zone and cooling device. - Each thermal zone contains its own temperature, trip points, - cooling devices. - All platforms with ACPI thermal support can use this driver. - If you want this support, you should say Y or M here. - -if THERMAL - -config THERMAL_HWMON - bool - depends on HWMON=y || HWMON=THERMAL - default y - -choice - prompt "Default Thermal governor" - default THERMAL_DEFAULT_GOV_STEP_WISE - help - This option sets which thermal governor shall be loaded at - startup. If in doubt, select 'step_wise'. - -config THERMAL_DEFAULT_GOV_STEP_WISE - bool "step_wise" - select STEP_WISE - help - Use the step_wise governor as default. This throttles the - devices one step at a time. - -config THERMAL_DEFAULT_GOV_FAIR_SHARE - bool "fair_share" - select FAIR_SHARE - help - Use the fair_share governor as default. This throttles the - devices based on their 'contribution' to a zone. The - contribution should be provided through platform data. - -config THERMAL_DEFAULT_GOV_USER_SPACE - bool "user_space" - select USER_SPACE - help - Select this if you want to let the user space manage the - lpatform thermals. - -endchoice - -config FAIR_SHARE - bool "Fair-share thermal governor" - help - Enable this to manage platform thermals using fair-share governor. - -config STEP_WISE - bool "Step_wise thermal governor" - help - Enable this to manage platform thermals using a simple linear - -config USER_SPACE - bool "User_space thermal governor" - help - Enable this to let the user space manage the platform thermals. - -config SUNXI_THERMAL_DYNAMIC - tristate "sunxi thermal dynamic binding" - depends on ARCH_SUNXI - depends on SUNXI_THERMAL - help - Adds sunxi thermal dynamic binding support. - -config CPU_THERMAL - tristate "generic cpu cooling support" - depends on CPU_FREQ - select CPU_FREQ_TABLE - help - This implements the generic cpu cooling mechanism through frequency - reduction, cpu hotplug and any other ways of reducing temperature. An - ACPI version of this already exists(drivers/acpi/processor_thermal.c). - This will be useful for platforms using the generic thermal interface - and not the ACPI interface. - If you want this support, you should say Y here. - -config CPU_BUDGET_THERMAL - tristate "generic cpu budget cooling support" - depends on CPU_FREQ && !CPU_THERMAL - select CPU_FREQ_TABLE - help - This implements the generic cpu budget with cpufreq and hotplug cooling mechanism through frequency - reduction, cpu hotplug and any other ways of reducing temperature. An - ACPI version of this already exists(drivers/acpi/processor_thermal.c). - This will be useful for platforms using the generic thermal interface - and not the ACPI interface. - If you want this support, you should say Y here. - -config SPEAR_THERMAL - bool "SPEAr thermal sensor driver" - depends on PLAT_SPEAR - depends on OF - help - Enable this to plug the SPEAr thermal sensor driver into the Linux - thermal framework - -config RCAR_THERMAL - tristate "Renesas R-Car thermal driver" - depends on ARCH_SHMOBILE - help - Enable this to plug the R-Car thermal sensor driver into the Linux - thermal framework - -config SUNXI_THERMAL - tristate "Temperature sensor on ALLWINNERTECH" - depends on ARCH_SUNXI - help - If you say yes here you get support for (Thermal Management - Unit) on ALLWINEER series of SoC. - -config SUNXI_BATTERY - tristate "Battery vol sensor on ALLWINNERTECH" - depends on ARCH_SUN9IW1P1 - help - If you say yes here you get support for (BATTERY VOL Thermal Management - Unit) on ALLWINEER series of SoC. - -config SUNXI_CPUFREQ_COOLING - tristate "sunxi cpufreq cooling" - depends on ARCH_SUNXI - depends on CPU_THERMAL - help - Adds sunxi cpufreq cooling devices, and these cooling devices can be - bound to thermal zone trip points. When a trip point reached, the - bound cpufreq cooling device turns active to set CPU frequency low to - cool down the CPU. - -config SUNXI_BUDGET_COOLING - tristate "sunxi cpu budget cooling" - depends on ARCH_SUNXI - depends on CPU_BUDGET_THERMAL - help - Adds sunxi cpu budget cooling devices, and these cooling devices can be - bound to thermal zone trip points. When a trip point reached, the - bound cpufreq cooling device turns active to set CPU frequency low to - cool down the CPU. - -config SUNXI_BUDGET_COOLING_VFTBL - tristate "sunxi cpu budget cooling parse VF table support" - depends on CPU_BUDGET_THERMAL - depends on SUNXI_BUDGET_COOLING - default y - help - Adds support to parse VF table when set cooling state params as VF table index -endif diff --git a/linux-3.4/drivers/thermal.new/Makefile b/linux-3.4/drivers/thermal.new/Makefile deleted file mode 100755 index 3d087345..00000000 --- a/linux-3.4/drivers/thermal.new/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Makefile for sensor chip drivers. -# - -obj-$(CONFIG_THERMAL) += thermal_sys.o - -# governors -obj-$(CONFIG_FAIR_SHARE) += fair_share.o -obj-$(CONFIG_STEP_WISE) += step_wise.o -obj-$(CONFIG_USER_SPACE) += user_space.o - -# cpufreq cooling -obj-$(CONFIG_CPU_THERMAL) += cpu_cooling.o -obj-$(CONFIG_CPU_BUDGET_THERMAL)+= cpu_budget_cooling.o -# platform thermal drivers -obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o -obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o -obj-$(CONFIG_SUNXI_THERMAL) += sunxi-thermal.o -obj-$(CONFIG_SUNXI_BATTERY) += sunxi-battery.o -obj-$(CONFIG_SUNXI_THERMAL_DYNAMIC) += sunxi-thermal-bind.o -obj-$(CONFIG_SUNXI_THERMAL) += sunxi-temperature.o -obj-$(CONFIG_SUNXI_CPUFREQ_COOLING) += sunxi-cpu-cooling.o -obj-$(CONFIG_SUNXI_BUDGET_COOLING) += sunxi-cpu-budget-cooling.o diff --git a/linux-3.4/drivers/thermal.new/cpu_budget_cooling.c b/linux-3.4/drivers/thermal.new/cpu_budget_cooling.c deleted file mode 100755 index ce1f9bbe..00000000 --- a/linux-3.4/drivers/thermal.new/cpu_budget_cooling.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * linux/drivers/thermal/cpu_budget_cooling.c - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) - * Copyright (C) 2012 Amit Daniel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define CREATE_TRACE_POINTS -#include -#define BOOT_CPU 0 - -/** - * struct cpu_budget_cooling_device - * @id: unique integer value corresponding to each cpu_budget_cooling_device - * registered. - * @cool_dev: thermal_cooling_device pointer to keep track of the the - * egistered cooling device. - * @cpu_budget_state: integer value representing the current state of cpufreq - * cooling devices. - * @cpufreq_val: integer value representing the absolute value of the clipped - * frequency. - * @allowed_cpus: all the cpus involved for this cpu_budget_cooling_device. - * @node: list_head to link all cpu_budget_cooling_device together. - * - * This structure is required for keeping information of each - * cpu_budget_cooling_device registered as a list whose head is represented by - * cooling_cpufreq_list. In order to prevent corruption of this list a - * mutex lock cooling_cpu_budget_lock is used. - */ - -static LIST_HEAD(cooling_cpufreq_list); -static DEFINE_IDR(cpu_budget_idr); -static DEFINE_MUTEX(cooling_cpu_budget_lock); -static unsigned int cpu_budget_dev_count; -static struct cpu_budget_cooling_device* notify_device=NULL; -/** - * get_idr - function to get a unique id. - * @idr: struct idr * handle used to create a id. - * @id: int * value generated by this function. - */ -static int get_idr(struct idr *idr, int *id) -{ - int err; -again: - if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) - return -ENOMEM; - - mutex_lock(&cooling_cpu_budget_lock); - err = idr_get_new(idr, NULL, id); - mutex_unlock(&cooling_cpu_budget_lock); - - if (unlikely(err == -EAGAIN)) - goto again; - else if (unlikely(err)) - return err; - - *id = *id & MAX_ID_MASK; - return 0; -} - -/** - * release_idr - function to free the unique id. - * @idr: struct idr * handle used for creating the id. - * @id: int value representing the unique id. - */ -static void release_idr(struct idr *idr, int id) -{ - mutex_lock(&cooling_cpu_budget_lock); - idr_remove(idr, id); - mutex_unlock(&cooling_cpu_budget_lock); -} - -/* Below code defines functions to be used for cpufreq as cooling device */ - -/** - * is_cpufreq_valid - function to check if a cpu has frequency transition policy. - * @cpu: cpu for which check is needed. - */ -static int is_cpufreq_valid(int cpu) -{ - struct cpufreq_policy policy; - return !cpufreq_get_policy(&policy, cpu); -} -static int get_any_online_cpu(const cpumask_t *mask) -{ - int cpu,lastcpu=0xffff; - - for_each_cpu(cpu, mask) { - if ((cpu != BOOT_CPU) && cpu_online(cpu)) - { - if(lastcpu == 0xffff) - lastcpu = cpu; - else if(cpu >lastcpu) - lastcpu = cpu; - } - } - return lastcpu; -} -static int get_online_cpu(const cpumask_t *mask) -{ - int cpu,num =0; - - for_each_cpu(cpu, mask) { - if (cpu_online(cpu)) - num++; - } - return num; -} -static BLOCKING_NOTIFIER_HEAD(budget_cooling_notifier_list); -int register_budget_cooling_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&budget_cooling_notifier_list, nb); -} -EXPORT_SYMBOL(register_budget_cooling_notifier); - -/** - * cpu_budget_apply_cooling - function to apply frequency clipping. - * @cpu_budget_device: cpu_budget_cooling_device pointer containing frequency - * clipping data. - * @cooling_state: value of the cooling state. - */ -#ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE -extern int autohotplug_update_room(unsigned int c0min,unsigned int c1min,unsigned int c0max,unsigned int c1max); -#endif -int cpu_budget_update_state(struct cpu_budget_cooling_device *cpu_budget_device) -{ - int i,ret = 0; - unsigned int cpuid; - unsigned int c0_online=0,c1_online=0; - unsigned int c0_takedown=0,c1_takedown=0; - unsigned int c0_max,c1_max,c0_min,c1_min; - struct cpumask *cluster0_cpus = &cpu_budget_device->cluster0_cpus; - struct cpumask *cluster1_cpus = &cpu_budget_device->cluster1_cpus; - struct cpufreq_policy policy; - - ret = 0; -// update cpu limit - for_each_online_cpu(i) { - if (cpumask_test_cpu(i, &cpu_budget_device->cluster0_cpus)) - c0_online++; - else if (cpumask_test_cpu(i, &cpu_budget_device->cluster1_cpus)) - c1_online++; - } - - c1_max = (cpu_budget_device->cluster1_num_roof >=cpu_budget_device->cluster1_num_limit)? - cpu_budget_device->cluster1_num_limit:cpu_budget_device->cluster1_num_roof; - c0_max = (cpu_budget_device->cluster0_num_roof >=cpu_budget_device->cluster0_num_limit)? - cpu_budget_device->cluster0_num_limit:cpu_budget_device->cluster0_num_roof; - c1_min = (cpu_budget_device->cluster1_num_floor >=c1_max)? - c1_max:cpu_budget_device->cluster1_num_floor; - c0_min = (cpu_budget_device->cluster0_num_floor >=c0_max)? - c0_max:cpu_budget_device->cluster0_num_floor; - c0_takedown = (c0_online > c0_max)?(c0_online - c0_max):0; - c1_takedown = (c1_online > c1_max)?(c1_online - c1_max):0; - while(c1_takedown) - { - cpuid = get_any_online_cpu(&cpu_budget_device->cluster1_cpus); - if (cpuid < nr_cpu_ids) - { - pr_info("CPU Budget:Try to down cpu %d, cluster1 online %d, max %d\n",cpuid,c1_online,c1_max); - ret = work_on_cpu(BOOT_CPU, - (long(*)(void *))cpu_down, - (void *)cpuid); - } - c1_takedown--; - } - while(c0_takedown) - { - cpuid = get_any_online_cpu(&cpu_budget_device->cluster0_cpus); - if (cpuid < nr_cpu_ids) - { - pr_info("CPU Budget:Try to down cpu %d, cluster0 online %d, limit %d\n",cpuid,c0_online,cpu_budget_device->cluster0_num_limit); - ret = work_on_cpu(BOOT_CPU, - (long(*)(void *))cpu_down, - (void *)cpuid); - } - c0_takedown--; - } -#ifdef CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG_ROOMAGE - autohotplug_update_room(c0_min,c1_min,c0_max,c1_max); -#endif - - // update gpu limit - if(cpu_budget_device->gpu_throttle) - blocking_notifier_call_chain(&budget_cooling_notifier_list,BUDGET_GPU_THROTTLE, NULL); - else - blocking_notifier_call_chain(&budget_cooling_notifier_list,BUDGET_GPU_UNTHROTTLE, NULL); - - // update cpufreq limit - for_each_cpu(cpuid, cluster0_cpus) { - if (is_cpufreq_valid(cpuid)) - { - if((cpufreq_get_policy(&policy, cpuid) == 0) && policy.user_policy.governor) - { - cpufreq_update_policy(cpuid); - break; - } - } - } - for_each_cpu(cpuid, cluster1_cpus) { - if (is_cpufreq_valid(cpuid)) - { - if((cpufreq_get_policy(&policy, cpuid) == 0) && policy.user_policy.governor) - { - cpufreq_update_policy(cpuid); - break; - } - } - } - - return ret; -} -EXPORT_SYMBOL(cpu_budget_update_state); - -/** - * cpu_budget_apply_cooling - function to apply frequency clipping. - * @cpu_budget_device: cpu_budget_cooling_device pointer containing frequency - * clipping data. - * @cooling_state: value of the cooling state. - */ -static int cpu_budget_apply_cooling(struct cpu_budget_cooling_device *cpu_budget_device, - unsigned long cooling_state) -{ - unsigned long flags; - - /* Check if the old cooling action is same as new cooling action */ - if (cpu_budget_device->cpu_budget_state == cooling_state) - return 0; - - cpu_budget_device->cpu_budget_state = cooling_state; - - if(cooling_state >= cpu_budget_device->tbl_num) - return -EINVAL; - - spin_lock_irqsave(&cpu_budget_device->lock, flags); - cpu_budget_device->cluster0_freq_limit = cpu_budget_device->tbl[cooling_state].cluster0_freq; - cpu_budget_device->cluster0_num_limit = cpu_budget_device->tbl[cooling_state].cluster0_cpunr; - cpu_budget_device->cluster1_freq_limit = cpu_budget_device->tbl[cooling_state].cluster1_freq; - cpu_budget_device->cluster1_num_limit = cpu_budget_device->tbl[cooling_state].cluster1_cpunr; - cpu_budget_device->gpu_throttle = cpu_budget_device->tbl[cooling_state].gpu_throttle; - spin_unlock_irqrestore(&cpu_budget_device->lock, flags); - - trace_cpu_budget_throttle(cooling_state, - cpu_budget_device->cluster0_freq_limit, - cpu_budget_device->cluster0_num_limit , - cpu_budget_device->cluster1_freq_limit, - cpu_budget_device->cluster1_num_limit, - cpu_budget_device->gpu_throttle); - pr_debug("CPU Budget: Limit state:%lu item[%d,%d,%d,%d %d]\n",cooling_state, - cpu_budget_device->cluster0_freq_limit, - cpu_budget_device->cluster0_num_limit , - cpu_budget_device->cluster1_freq_limit , - cpu_budget_device->cluster1_num_limit, - cpu_budget_device->gpu_throttle); - - return cpu_budget_update_state(cpu_budget_device); -} -static int hotplug_thermal_notifier(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - - - unsigned int c0_online=0,c1_online=0; - unsigned int c0_max=0,c1_max=0; -// unsigned int c0_min=0,c1_min=0; - unsigned int cpu = (unsigned long)hcpu; - - switch (action) { - case CPU_UP_PREPARE: - c0_online = get_online_cpu(¬ify_device->cluster0_cpus); - c1_online = get_online_cpu(¬ify_device->cluster1_cpus); - if (cpumask_test_cpu(cpu, ¬ify_device->cluster1_cpus)) - { - if(notify_device->cluster1_num_roof >=notify_device->cluster1_num_limit) - c1_max = notify_device->cluster1_num_limit; - else - c1_max = notify_device->cluster1_num_roof; - - if(c1_online >= c1_max) - { - pr_info("CPU Budget:reject cpu %d to up, cluster1 online %d, limit %d\n",cpu,c1_online,c1_max); - return NOTIFY_BAD; - } - } - else if (cpumask_test_cpu(cpu, ¬ify_device->cluster0_cpus)) - { - if(notify_device->cluster1_num_roof >=notify_device->cluster1_num_limit) - c0_max = notify_device->cluster0_num_limit; - else - c0_max = notify_device->cluster0_num_roof; - - if(c0_online >= c0_max) - { - pr_info("CPU Budget:reject cpu %d to up, cluster0 online %d, max %d\n",cpu,c0_online,c0_max); - return NOTIFY_BAD; - } - } - return NOTIFY_DONE; - default: - break; - } - - return NOTIFY_DONE; -} -/** - * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. - * @nb: struct notifier_block * with callback info. - * @event: value showing cpufreq event for which this function invoked. - * @data: callback-specific data - */ -static int cpufreq_thermal_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct cpufreq_policy *policy = data; - unsigned long limit_freq=0,base_freq=0,head_freq=0; - unsigned long max_freq=0,min_freq=0; - - if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID) - return 0; - - if (cpumask_test_cpu(policy->cpu, ¬ify_device->cluster0_cpus)) - { - limit_freq = notify_device->cluster0_freq_limit; - base_freq = notify_device->cluster0_freq_floor; - head_freq = notify_device->cluster0_freq_roof; - } - else if (cpumask_test_cpu(policy->cpu, ¬ify_device->cluster1_cpus)) - { - limit_freq = notify_device->cluster1_freq_limit; - base_freq = notify_device->cluster1_freq_floor; - head_freq = notify_device->cluster1_freq_roof; - } - else - return 0; - if(limit_freq && limit_freq != INVALID_FREQ) - { - max_freq =(head_freq >= limit_freq)?limit_freq:head_freq; - min_freq = base_freq; - /* Never exceed policy.max*/ - if (max_freq > policy->max) - max_freq = policy->max; - if (min_freq < policy->min) - { - min_freq = policy->min; - } - min_freq = (min_freq < max_freq)?min_freq:max_freq; - if (policy->max != max_freq || policy->min != min_freq ) - { - cpufreq_verify_within_limits(policy, min_freq, max_freq); - policy->user_policy.max = policy->max; - pr_debug("CPU Budget:update CPU %d cpufreq max to %lu min to %lu\n",policy->cpu,max_freq, min_freq); - } - } - return 0; -} - -/* - * cpufreq cooling device callback functions are defined below - */ - -/** - * cpu_budget_get_max_state - callback function to get the max cooling state. - * @cdev: thermal cooling device pointer. - * @state: fill this variable with the max cooling state. - */ -static int cpu_budget_get_max_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - struct cpu_budget_cooling_device *cpu_budget_device = cdev->devdata; - *state = cpu_budget_device->tbl_num-1; - return 0; -} - -/** - * cpu_budget_get_cur_state - callback function to get the current cooling state. - * @cdev: thermal cooling device pointer. - * @state: fill this variable with the current cooling state. - */ -static int cpu_budget_get_cur_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - struct cpu_budget_cooling_device *cpu_budget_device = cdev->devdata; - *state = cpu_budget_device->cpu_budget_state; - return 0; -} - -/** - * cpu_budget_set_cur_state - callback function to set the current cooling state. - * @cdev: thermal cooling device pointer. - * @state: set this variable to the current cooling state. - */ -static int cpu_budget_set_cur_state(struct thermal_cooling_device *cdev, - unsigned long state) -{ - struct cpu_budget_cooling_device *cpu_budget_device = cdev->devdata; - return cpu_budget_apply_cooling(cpu_budget_device, state); -} - -/* Bind cpufreq callbacks to thermal cooling device ops */ -static struct thermal_cooling_device_ops const cpu_budget_cooling_ops = { - .get_max_state = cpu_budget_get_max_state, - .get_cur_state = cpu_budget_get_cur_state, - .set_cur_state = cpu_budget_set_cur_state, -}; - -/** - * cpu_budget_cooling_register - function to create cpufreq cooling device. - * @clip_cpus: cpumask of cpus where the frequency constraints will happen. - */ -struct thermal_cooling_device *cpu_budget_cooling_register( - struct cpu_budget_table* tbl, unsigned int tbl_num, - const struct cpumask *cluster0_cpus,const struct cpumask *cluster1_cpus) -{ - struct thermal_cooling_device *cool_dev; - struct cpu_budget_cooling_device *cpu_budget_dev = NULL; - unsigned int min = 0, max = 0; - char dev_name[THERMAL_NAME_LENGTH]; - int ret = 0, i; - struct cpufreq_policy policy; - - /*Verify that all the clip cpus have same freq_min, freq_max limit*/ - for_each_cpu(i, cluster0_cpus) { - /*continue if cpufreq policy not found and not return error*/ - if (!cpufreq_get_policy(&policy, i)) - continue; - if (min == 0 && max == 0) { - min = policy.cpuinfo.min_freq; - max = policy.cpuinfo.max_freq; - } else { - if (min != policy.cpuinfo.min_freq || - max != policy.cpuinfo.max_freq) - return ERR_PTR(-EINVAL); - } - } - - /*Verify that all the clip cpus have same freq_min, freq_max limit*/ - for_each_cpu(i, cluster1_cpus) { - /*continue if cpufreq policy not found and not return error*/ - if (!cpufreq_get_policy(&policy, i)) - continue; - if (min == 0 && max == 0) { - min = policy.cpuinfo.min_freq; - max = policy.cpuinfo.max_freq; - } else { - if (min != policy.cpuinfo.min_freq || - max != policy.cpuinfo.max_freq) - return ERR_PTR(-EINVAL); - } - } - - cpu_budget_dev = kzalloc(sizeof(struct cpu_budget_cooling_device), - GFP_KERNEL); - if (!cpu_budget_dev) - return ERR_PTR(-ENOMEM); - spin_lock_init(&cpu_budget_dev->lock); - cpumask_copy(&cpu_budget_dev->cluster0_cpus, cluster0_cpus); - cpumask_copy(&cpu_budget_dev->cluster1_cpus, cluster1_cpus); - cpu_budget_dev->tbl = tbl; - cpu_budget_dev->tbl_num = tbl_num; - cpu_budget_dev->cluster0_freq_limit = cpu_budget_dev->tbl[0].cluster0_freq; - cpu_budget_dev->cluster0_num_limit = cpu_budget_dev->tbl[0].cluster0_cpunr; - cpu_budget_dev->cluster1_freq_limit = cpu_budget_dev->tbl[0].cluster1_freq; - cpu_budget_dev->cluster1_num_limit = cpu_budget_dev->tbl[0].cluster1_cpunr; - cpu_budget_dev->gpu_throttle = cpu_budget_dev->tbl[0].gpu_throttle; - - cpu_budget_dev->cluster0_freq_roof = cpu_budget_dev->cluster0_freq_limit; - cpu_budget_dev->cluster0_num_roof = cpu_budget_dev->cluster0_num_limit; - cpu_budget_dev->cluster1_freq_roof = cpu_budget_dev->cluster1_freq_limit; - cpu_budget_dev->cluster1_num_roof = cpu_budget_dev->cluster1_num_limit; - - ret = get_idr(&cpu_budget_idr, &cpu_budget_dev->id); - if (ret) { - kfree(cpu_budget_dev); - return ERR_PTR(-EINVAL); - } - - sprintf(dev_name, "thermal-budget-%d", cpu_budget_dev->id); - cool_dev = thermal_cooling_device_register(dev_name, cpu_budget_dev, - &cpu_budget_cooling_ops); - if (!cool_dev) { - release_idr(&cpu_budget_idr, cpu_budget_dev->id); - kfree(cpu_budget_dev); - return ERR_PTR(-EINVAL); - } - cpu_budget_dev->cool_dev = cool_dev; - cpu_budget_dev->cpu_budget_state = 0; - mutex_lock(&cooling_cpu_budget_lock); - /* Register the notifier for first cpufreq cooling device */ - if (cpu_budget_dev_count == 0) - { - pr_info("CPU Budget:Register notifier\n"); - notify_device=cpu_budget_dev; - cpu_budget_dev->cpufreq_notifer.notifier_call=cpufreq_thermal_notifier; - cpufreq_register_notifier(&(cpu_budget_dev->cpufreq_notifer), - CPUFREQ_POLICY_NOTIFIER); - - cpu_budget_dev->hotplug_notifer.notifier_call=hotplug_thermal_notifier; - register_cpu_notifier(&(cpu_budget_dev->hotplug_notifer)); - } - cpu_budget_dev_count++; - mutex_unlock(&cooling_cpu_budget_lock); - pr_info("CPU Budget:register Success\n"); - return cool_dev; -} -EXPORT_SYMBOL(cpu_budget_cooling_register); - -/** - * cpu_budget_cooling_unregister - function to remove cpufreq_hotplug cooling device. - * @cdev: thermal cooling device pointer. - */ -void cpu_budget_cooling_unregister(struct thermal_cooling_device *cdev) -{ - struct cpu_budget_cooling_device *cpu_budget_dev = cdev->devdata; - - mutex_lock(&cooling_cpu_budget_lock); - cpu_budget_dev_count--; - - /* Unregister the notifier for the last cpufreq cooling device */ - if (cpu_budget_dev_count == 0) { - - cpufreq_unregister_notifier(&(cpu_budget_dev->cpufreq_notifer), - CPUFREQ_POLICY_NOTIFIER); - unregister_cpu_notifier(&(cpu_budget_dev->hotplug_notifer)); - } - mutex_unlock(&cooling_cpu_budget_lock); - - thermal_cooling_device_unregister(cpu_budget_dev->cool_dev); - release_idr(&cpu_budget_idr, cpu_budget_dev->id); - kfree(cpu_budget_dev); - pr_info("CPU Budget:unregister Success\n"); -} -EXPORT_SYMBOL(cpu_budget_cooling_unregister); - diff --git a/linux-3.4/drivers/thermal.new/cpu_cooling.c b/linux-3.4/drivers/thermal.new/cpu_cooling.c deleted file mode 100755 index c49a0540..00000000 --- a/linux-3.4/drivers/thermal.new/cpu_cooling.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * linux/drivers/thermal/cpu_cooling.c - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) - * Copyright (C) 2012 Amit Daniel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * struct cpufreq_cooling_device - * @id: unique integer value corresponding to each cpufreq_cooling_device - * registered. - * @cool_dev: thermal_cooling_device pointer to keep track of the the - * egistered cooling device. - * @cpufreq_state: integer value representing the current state of cpufreq - * cooling devices. - * @cpufreq_val: integer value representing the absolute value of the clipped - * frequency. - * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. - * @node: list_head to link all cpufreq_cooling_device together. - * - * This structure is required for keeping information of each - * cpufreq_cooling_device registered as a list whose head is represented by - * cooling_cpufreq_list. In order to prevent corruption of this list a - * mutex lock cooling_cpufreq_lock is used. - */ -struct cpufreq_cooling_device { - int id; - struct thermal_cooling_device *cool_dev; - unsigned int cpufreq_state; - unsigned int cpufreq_val; - struct cpumask allowed_cpus; - struct list_head node; -}; -static LIST_HEAD(cooling_cpufreq_list); -static DEFINE_IDR(cpufreq_idr); -static DEFINE_MUTEX(cooling_cpufreq_lock); - -static unsigned int cpufreq_dev_count; - -/* notify_table passes value to the CPUFREQ_ADJUST callback function. */ -#define NOTIFY_INVALID NULL -static struct cpufreq_cooling_device *notify_device; - -/** - * get_idr - function to get a unique id. - * @idr: struct idr * handle used to create a id. - * @id: int * value generated by this function. - */ -static int get_idr(struct idr *idr, int *id) -{ - int err; -again: - if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) - return -ENOMEM; - - mutex_lock(&cooling_cpufreq_lock); - err = idr_get_new(idr, NULL, id); - mutex_unlock(&cooling_cpufreq_lock); - - if (unlikely(err == -EAGAIN)) - goto again; - else if (unlikely(err)) - return err; - - *id = *id & MAX_ID_MASK; - return 0; -} - -/** - * release_idr - function to free the unique id. - * @idr: struct idr * handle used for creating the id. - * @id: int value representing the unique id. - */ -static void release_idr(struct idr *idr, int id) -{ - mutex_lock(&cooling_cpufreq_lock); - idr_remove(idr, id); - mutex_unlock(&cooling_cpufreq_lock); -} - -/* Below code defines functions to be used for cpufreq as cooling device */ - -/** - * is_cpufreq_valid - function to check if a cpu has frequency transition policy. - * @cpu: cpu for which check is needed. - */ -static int is_cpufreq_valid(int cpu) -{ - struct cpufreq_policy policy; - return !cpufreq_get_policy(&policy, cpu); -} - -/** - * get_cpu_frequency - get the absolute value of frequency from level. - * @cpu: cpu for which frequency is fetched. - * @level: level of frequency of the CPU - * e.g level=1 --> 1st MAX FREQ, LEVEL=2 ---> 2nd MAX FREQ, .... etc - */ -static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level) -{ - int ret = 0, i = 0; - unsigned long level_index; - bool descend = false; - struct cpufreq_frequency_table *table = - cpufreq_frequency_get_table(cpu); - if (!table) - return ret; - - while (table[i].frequency != CPUFREQ_TABLE_END) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - - /*check if table in ascending or descending order*/ - if ((table[i + 1].frequency != CPUFREQ_TABLE_END) && - (table[i + 1].frequency < table[i].frequency) - && !descend) { - descend = true; - } - - /*return if level matched and table in descending order*/ - if (descend && i == level) - return table[i].frequency; - i++; - } - i--; - - if (level > i || descend) - return ret; - level_index = i - level; - - /*Scan the table in reverse order and match the level*/ - while (i >= 0) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - /*return if level matched*/ - if (i == level_index) - return table[i].frequency; - i--; - } - return ret; -} - -/** - * cpufreq_apply_cooling - function to apply frequency clipping. - * @cpufreq_device: cpufreq_cooling_device pointer containing frequency - * clipping data. - * @cooling_state: value of the cooling state. - */ -static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device, - unsigned long cooling_state) -{ - unsigned int cpuid, clip_freq; - struct cpumask *maskPtr = &cpufreq_device->allowed_cpus; - unsigned int cpu = cpumask_any(maskPtr); - - - /* Check if the old cooling action is same as new cooling action */ - if (cpufreq_device->cpufreq_state == cooling_state) - return 0; - - clip_freq = get_cpu_frequency(cpu, cooling_state); - if (!clip_freq) - return -EINVAL; - - cpufreq_device->cpufreq_state = cooling_state; - cpufreq_device->cpufreq_val = clip_freq; - notify_device = cpufreq_device; - - for_each_cpu(cpuid, maskPtr) { - if (is_cpufreq_valid(cpuid)) - cpufreq_update_policy(cpuid); - } - - notify_device = NOTIFY_INVALID; - - return 0; -} - -/** - * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. - * @nb: struct notifier_block * with callback info. - * @event: value showing cpufreq event for which this function invoked. - * @data: callback-specific data - */ -static int cpufreq_thermal_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct cpufreq_policy *policy = data; - unsigned long max_freq = 0; - - if (event != CPUFREQ_ADJUST || notify_device == NOTIFY_INVALID) - return 0; - - if (cpumask_test_cpu(policy->cpu, ¬ify_device->allowed_cpus)) - max_freq = notify_device->cpufreq_val; - - /* Never exceed user_policy.max*/ - if (max_freq > policy->user_policy.max) - max_freq = policy->user_policy.max; - - if (policy->max != max_freq) - cpufreq_verify_within_limits(policy, 0, max_freq); - - return 0; -} - -/* - * cpufreq cooling device callback functions are defined below - */ - -/** - * cpufreq_get_max_state - callback function to get the max cooling state. - * @cdev: thermal cooling device pointer. - * @state: fill this variable with the max cooling state. - */ -static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - struct cpumask *maskPtr = &cpufreq_device->allowed_cpus; - unsigned int cpu; - struct cpufreq_frequency_table *table; - unsigned long count = 0; - int i = 0; - - cpu = cpumask_any(maskPtr); - table = cpufreq_frequency_get_table(cpu); - if (!table) { - *state = 0; - return 0; - } - - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - count++; - } - - if (count > 0) { - *state = --count; - return 0; - } - - return -EINVAL; -} - -/** - * cpufreq_get_cur_state - callback function to get the current cooling state. - * @cdev: thermal cooling device pointer. - * @state: fill this variable with the current cooling state. - */ -static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - - *state = cpufreq_device->cpufreq_state; - return 0; -} - -/** - * cpufreq_set_cur_state - callback function to set the current cooling state. - * @cdev: thermal cooling device pointer. - * @state: set this variable to the current cooling state. - */ -static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, - unsigned long state) -{ - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - - return cpufreq_apply_cooling(cpufreq_device, state); -} - -/* Bind cpufreq callbacks to thermal cooling device ops */ -static struct thermal_cooling_device_ops const cpufreq_cooling_ops = { - .get_max_state = cpufreq_get_max_state, - .get_cur_state = cpufreq_get_cur_state, - .set_cur_state = cpufreq_set_cur_state, -}; - -/* Notifier for cpufreq policy change */ -static struct notifier_block thermal_cpufreq_notifier_block = { - .notifier_call = cpufreq_thermal_notifier, -}; - -/** - * cpufreq_cooling_register - function to create cpufreq cooling device. - * @clip_cpus: cpumask of cpus where the frequency constraints will happen. - */ -struct thermal_cooling_device *cpufreq_cooling_register( - const struct cpumask *clip_cpus) -{ - struct thermal_cooling_device *cool_dev; - struct cpufreq_cooling_device *cpufreq_dev = NULL; - unsigned int min = 0, max = 0; - char dev_name[THERMAL_NAME_LENGTH]; - int ret = 0, i; - struct cpufreq_policy policy; - - /*Verify that all the clip cpus have same freq_min, freq_max limit*/ - for_each_cpu(i, clip_cpus) { - /*continue if cpufreq policy not found and not return error*/ - if (!cpufreq_get_policy(&policy, i)) - continue; - if (min == 0 && max == 0) { - min = policy.cpuinfo.min_freq; - max = policy.cpuinfo.max_freq; - } else { - if (min != policy.cpuinfo.min_freq || - max != policy.cpuinfo.max_freq) - return ERR_PTR(-EINVAL); - } - } - cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), - GFP_KERNEL); - if (!cpufreq_dev) - return ERR_PTR(-ENOMEM); - - cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); - - ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); - if (ret) { - kfree(cpufreq_dev); - return ERR_PTR(-EINVAL); - } - - sprintf(dev_name, "thermal-cpufreq-%d", cpufreq_dev->id); - - cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev, - &cpufreq_cooling_ops); - if (!cool_dev) { - release_idr(&cpufreq_idr, cpufreq_dev->id); - kfree(cpufreq_dev); - return ERR_PTR(-EINVAL); - } - cpufreq_dev->cool_dev = cool_dev; - cpufreq_dev->cpufreq_state = 0; - mutex_lock(&cooling_cpufreq_lock); - - /* Register the notifier for first cpufreq cooling device */ - if (cpufreq_dev_count == 0) - cpufreq_register_notifier(&thermal_cpufreq_notifier_block, - CPUFREQ_POLICY_NOTIFIER); - cpufreq_dev_count++; - - mutex_unlock(&cooling_cpufreq_lock); - return cool_dev; -} -EXPORT_SYMBOL(cpufreq_cooling_register); - -/** - * cpufreq_cooling_unregister - function to remove cpufreq cooling device. - * @cdev: thermal cooling device pointer. - */ -void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) -{ - struct cpufreq_cooling_device *cpufreq_dev = cdev->devdata; - - mutex_lock(&cooling_cpufreq_lock); - cpufreq_dev_count--; - - /* Unregister the notifier for the last cpufreq cooling device */ - if (cpufreq_dev_count == 0) { - cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, - CPUFREQ_POLICY_NOTIFIER); - } - mutex_unlock(&cooling_cpufreq_lock); - - thermal_cooling_device_unregister(cpufreq_dev->cool_dev); - release_idr(&cpufreq_idr, cpufreq_dev->id); - kfree(cpufreq_dev); -} -EXPORT_SYMBOL(cpufreq_cooling_unregister); diff --git a/linux-3.4/drivers/thermal.new/fair_share.c b/linux-3.4/drivers/thermal.new/fair_share.c deleted file mode 100755 index 792479f2..00000000 --- a/linux-3.4/drivers/thermal.new/fair_share.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * fair_share.c - A simple weight based Thermal governor - * - * Copyright (C) 2012 Intel Corp - * Copyright (C) 2012 Durgadoss R - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - -#include "thermal_core.h" - -/** - * get_trip_level: - obtains the current trip level for a zone - * @tz: thermal zone device - */ -static int get_trip_level(struct thermal_zone_device *tz) -{ - int count = 0; - unsigned long trip_temp; - - if (tz->trips == 0 || !tz->ops->get_trip_temp) - return 0; - - for (count = 0; count < tz->trips; count++) { - tz->ops->get_trip_temp(tz, count, &trip_temp); - if (tz->temperature < trip_temp) - break; - } - return count; -} - -static long get_target_state(struct thermal_zone_device *tz, - struct thermal_cooling_device *cdev, int weight, int level) -{ - unsigned long max_state; - - cdev->ops->get_max_state(cdev, &max_state); - - return (long)(weight * level * max_state) / (100 * tz->trips); -} - -/** - * fair_share_throttle - throttles devices asscciated with the given zone - * @tz - thermal_zone_device - * - * Throttling Logic: This uses three parameters to calculate the new - * throttle state of the cooling devices associated with the given zone. - * - * Parameters used for Throttling: - * P1. max_state: Maximum throttle state exposed by the cooling device. - * P2. weight[i]/100: - * How 'effective' the 'i'th device is, in cooling the given zone. - * P3. cur_trip_level/max_no_of_trips: - * This describes the extent to which the devices should be throttled. - * We do not want to throttle too much when we trip a lower temperature, - * whereas the throttling is at full swing if we trip critical levels. - * (Heavily assumes the trip points are in ascending order) - * new_state of cooling device = P3 * P2 * P1 - */ -static int fair_share_throttle(struct thermal_zone_device *tz, int trip) -{ - const struct thermal_zone_params *tzp; - struct thermal_cooling_device *cdev; - struct thermal_instance *instance; - int i; - int cur_trip_level = get_trip_level(tz); - - if (!tz->tzp || !tz->tzp->tbp) - return -EINVAL; - - tzp = tz->tzp; - - for (i = 0; i < tzp->num_tbps; i++) { - if (!tzp->tbp[i].cdev) - continue; - - cdev = tzp->tbp[i].cdev; - instance = get_thermal_instance(tz, cdev, trip); - if (!instance) - continue; - - instance->target = get_target_state(tz, cdev, - tzp->tbp[i].weight, cur_trip_level); - - instance->cdev->updated = false; - thermal_cdev_update(cdev); - } - return 0; -} - -static struct thermal_governor thermal_gov_fair_share = { - .name = "fair_share", - .throttle = fair_share_throttle, - .owner = THIS_MODULE, -}; - -static int __init thermal_gov_fair_share_init(void) -{ - return thermal_register_governor(&thermal_gov_fair_share); -} - -static void __exit thermal_gov_fair_share_exit(void) -{ - thermal_unregister_governor(&thermal_gov_fair_share); -} - -/* This should load after thermal framework */ -fs_initcall(thermal_gov_fair_share_init); -module_exit(thermal_gov_fair_share_exit); - -MODULE_AUTHOR("Durgadoss R"); -MODULE_DESCRIPTION("A simple weight based thermal throttling governor"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/thermal.new/rcar_thermal.c b/linux-3.4/drivers/thermal.new/rcar_thermal.c deleted file mode 100755 index 90db9517..00000000 --- a/linux-3.4/drivers/thermal.new/rcar_thermal.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * R-Car THS/TSC thermal sensor driver - * - * Copyright (C) 2012 Renesas Solutions Corp. - * Kuninori Morimoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define THSCR 0x2c -#define THSSR 0x30 - -/* THSCR */ -#define CPTAP 0xf - -/* THSSR */ -#define CTEMP 0x3f - - -struct rcar_thermal_priv { - void __iomem *base; - struct device *dev; - spinlock_t lock; - u32 comp; -}; - -#define MCELSIUS(temp) ((temp) * 1000) -#define rcar_zone_to_priv(zone) (zone->devdata) - -/* - * basic functions - */ -static u32 rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg) -{ - unsigned long flags; - u32 ret; - - spin_lock_irqsave(&priv->lock, flags); - - ret = ioread32(priv->base + reg); - - spin_unlock_irqrestore(&priv->lock, flags); - - return ret; -} - -#if 0 /* no user at this point */ -static void rcar_thermal_write(struct rcar_thermal_priv *priv, - u32 reg, u32 data) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - - iowrite32(data, priv->base + reg); - - spin_unlock_irqrestore(&priv->lock, flags); -} -#endif - -static void rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg, - u32 mask, u32 data) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&priv->lock, flags); - - val = ioread32(priv->base + reg); - val &= ~mask; - val |= (data & mask); - iowrite32(val, priv->base + reg); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/* - * zone device functions - */ -static int rcar_thermal_get_temp(struct thermal_zone_device *zone, - unsigned long *temp) -{ - struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); - int val, min, max, tmp; - - tmp = -200; /* default */ - while (1) { - if (priv->comp < 1 || priv->comp > 12) { - dev_err(priv->dev, - "THSSR invalid data (%d)\n", priv->comp); - priv->comp = 4; /* for next thermal */ - return -EINVAL; - } - - /* - * THS comparator offset and the reference temperature - * - * Comparator | reference | Temperature field - * offset | temperature | measurement - * | (degrees C) | (degrees C) - * -------------+---------------+------------------- - * 1 | -45 | -45 to -30 - * 2 | -30 | -30 to -15 - * 3 | -15 | -15 to 0 - * 4 | 0 | 0 to +15 - * 5 | +15 | +15 to +30 - * 6 | +30 | +30 to +45 - * 7 | +45 | +45 to +60 - * 8 | +60 | +60 to +75 - * 9 | +75 | +75 to +90 - * 10 | +90 | +90 to +105 - * 11 | +105 | +105 to +120 - * 12 | +120 | +120 to +135 - */ - - /* calculate thermal limitation */ - min = (priv->comp * 15) - 60; - max = min + 15; - - /* - * we need to wait 300us after changing comparator offset - * to get stable temperature. - * see "Usage Notes" on datasheet - */ - rcar_thermal_bset(priv, THSCR, CPTAP, priv->comp); - udelay(300); - - /* calculate current temperature */ - val = rcar_thermal_read(priv, THSSR) & CTEMP; - val = (val * 5) - 65; - - dev_dbg(priv->dev, "comp/min/max/val = %d/%d/%d/%d\n", - priv->comp, min, max, val); - - /* - * If val is same as min/max, then, - * it should try again on next comparator. - * But the val might be correct temperature. - * Keep it on "tmp" and compare with next val. - */ - if (tmp == val) - break; - - if (val <= min) { - tmp = min; - priv->comp--; /* try again */ - } else if (val >= max) { - tmp = max; - priv->comp++; /* try again */ - } else { - tmp = val; - break; - } - } - - *temp = MCELSIUS(tmp); - return 0; -} - -static struct thermal_zone_device_ops rcar_thermal_zone_ops = { - .get_temp = rcar_thermal_get_temp, -}; - -/* - * platform functions - */ -static int rcar_thermal_probe(struct platform_device *pdev) -{ - struct thermal_zone_device *zone; - struct rcar_thermal_priv *priv; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Could not get platform resource\n"); - return -ENODEV; - } - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "Could not allocate priv\n"); - return -ENOMEM; - } - - priv->comp = 4; /* basic setup */ - priv->dev = &pdev->dev; - spin_lock_init(&priv->lock); - priv->base = devm_ioremap_nocache(&pdev->dev, - res->start, resource_size(res)); - if (!priv->base) { - dev_err(&pdev->dev, "Unable to ioremap thermal register\n"); - return -ENOMEM; - } - - zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, - &rcar_thermal_zone_ops, NULL, 0, 0); - if (IS_ERR(zone)) { - dev_err(&pdev->dev, "thermal zone device is NULL\n"); - return PTR_ERR(zone); - } - - platform_set_drvdata(pdev, zone); - - dev_info(&pdev->dev, "proved\n"); - - return 0; -} - -static int rcar_thermal_remove(struct platform_device *pdev) -{ - struct thermal_zone_device *zone = platform_get_drvdata(pdev); - - thermal_zone_device_unregister(zone); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver rcar_thermal_driver = { - .driver = { - .name = "rcar_thermal", - }, - .probe = rcar_thermal_probe, - .remove = rcar_thermal_remove, -}; -module_platform_driver(rcar_thermal_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver"); -MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/linux-3.4/drivers/thermal.new/spear_thermal.c b/linux-3.4/drivers/thermal.new/spear_thermal.c deleted file mode 100755 index 6b2d8b21..00000000 --- a/linux-3.4/drivers/thermal.new/spear_thermal.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * SPEAr thermal driver. - * - * Copyright (C) 2011-2012 ST Microelectronics - * Author: Vincenzo Frascino - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MD_FACTOR 1000 - -/* SPEAr Thermal Sensor Dev Structure */ -struct spear_thermal_dev { - /* pointer to base address of the thermal sensor */ - void __iomem *thermal_base; - /* clk structure */ - struct clk *clk; - /* pointer to thermal flags */ - unsigned int flags; -}; - -static inline int thermal_get_temp(struct thermal_zone_device *thermal, - unsigned long *temp) -{ - struct spear_thermal_dev *stdev = thermal->devdata; - - /* - * Data are ready to be read after 628 usec from POWERDOWN signal - * (PDN) = 1 - */ - *temp = (readl_relaxed(stdev->thermal_base) & 0x7F) * MD_FACTOR; - return 0; -} - -static struct thermal_zone_device_ops ops = { - .get_temp = thermal_get_temp, -}; - -#ifdef CONFIG_PM -static int spear_thermal_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - unsigned int actual_mask = 0; - - /* Disable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base); - - clk_disable(stdev->clk); - dev_info(dev, "Suspended.\n"); - - return 0; -} - -static int spear_thermal_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - unsigned int actual_mask = 0; - int ret = 0; - - ret = clk_enable(stdev->clk); - if (ret) { - dev_err(&pdev->dev, "Can't enable clock\n"); - return ret; - } - - /* Enable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask | stdev->flags, stdev->thermal_base); - - dev_info(dev, "Resumed.\n"); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(spear_thermal_pm_ops, spear_thermal_suspend, - spear_thermal_resume); - -static int spear_thermal_probe(struct platform_device *pdev) -{ - struct thermal_zone_device *spear_thermal = NULL; - struct spear_thermal_dev *stdev; - struct device_node *np = pdev->dev.of_node; - struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int ret = 0, val; - - if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) { - dev_err(&pdev->dev, "Failed: DT Pdata not passed\n"); - return -EINVAL; - } - - if (!stres) { - dev_err(&pdev->dev, "memory resource missing\n"); - return -ENODEV; - } - - stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL); - if (!stdev) { - dev_err(&pdev->dev, "kzalloc fail\n"); - return -ENOMEM; - } - - /* Enable thermal sensor */ - stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start, - resource_size(stres)); - if (!stdev->thermal_base) { - dev_err(&pdev->dev, "ioremap failed\n"); - return -ENOMEM; - } - - stdev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(stdev->clk)) { - dev_err(&pdev->dev, "Can't get clock\n"); - return PTR_ERR(stdev->clk); - } - - ret = clk_enable(stdev->clk); - if (ret) { - dev_err(&pdev->dev, "Can't enable clock\n"); - goto put_clk; - } - - stdev->flags = val; - writel_relaxed(stdev->flags, stdev->thermal_base); - - spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0, - stdev, &ops, NULL, 0, 0); - if (IS_ERR(spear_thermal)) { - dev_err(&pdev->dev, "thermal zone device is NULL\n"); - ret = PTR_ERR(spear_thermal); - goto disable_clk; - } - - platform_set_drvdata(pdev, spear_thermal); - - dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n", - stdev->thermal_base); - - return 0; - -disable_clk: - clk_disable(stdev->clk); -put_clk: - clk_put(stdev->clk); - - return ret; -} - -static int spear_thermal_exit(struct platform_device *pdev) -{ - unsigned int actual_mask = 0; - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - - thermal_zone_device_unregister(spear_thermal); - platform_set_drvdata(pdev, NULL); - - /* Disable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base); - - clk_disable(stdev->clk); - clk_put(stdev->clk); - - return 0; -} - -static const struct of_device_id spear_thermal_id_table[] = { - { .compatible = "st,thermal-spear1340" }, - {} -}; -MODULE_DEVICE_TABLE(of, spear_thermal_id_table); - -static struct platform_driver spear_thermal_driver = { - .probe = spear_thermal_probe, - .remove = spear_thermal_exit, - .driver = { - .name = "spear_thermal", - .owner = THIS_MODULE, - .pm = &spear_thermal_pm_ops, - .of_match_table = of_match_ptr(spear_thermal_id_table), - }, -}; - -module_platform_driver(spear_thermal_driver); - -MODULE_AUTHOR("Vincenzo Frascino "); -MODULE_DESCRIPTION("SPEAr thermal driver"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/thermal.new/step_wise.c b/linux-3.4/drivers/thermal.new/step_wise.c deleted file mode 100755 index 982e9044..00000000 --- a/linux-3.4/drivers/thermal.new/step_wise.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * step_wise.c - A step-by-step Thermal throttling governor - * - * Copyright (C) 2012 Intel Corp - * Copyright (C) 2012 Durgadoss R - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - -#include "thermal_core.h" - -/* - * If the temperature is higher than a trip point, - * a. if the trend is THERMAL_TREND_RAISING, use higher cooling - * state for this trip point - * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling - * state for this trip point - */ -static unsigned long get_target_state(struct thermal_instance *instance, - enum thermal_trend trend) -{ - struct thermal_cooling_device *cdev = instance->cdev; - unsigned long cur_state; - unsigned long next_target; - - cdev->ops->get_cur_state(cdev, &cur_state); - next_target = instance->target; - - switch (trend) { - case THERMAL_TREND_RAISING: - next_target = cur_state < instance->upper ? - (cur_state + 1) : instance->upper; - if (next_target < instance->lower) - next_target = instance->lower; - break; - case THERMAL_TREND_RAISE_FULL: - next_target = instance->upper; - break; - case THERMAL_TREND_DROPPING: - if (cur_state != instance->lower) { - next_target = cur_state - 1; - if (next_target > instance->upper) - next_target = instance->upper; - } - break; - case THERMAL_TREND_DROP_FULL: - if (cur_state != instance->lower) - next_target = instance->lower; - break; - default: - break; - } - - return next_target; -} - -static void update_passive_instance(struct thermal_zone_device *tz, - enum thermal_trip_type type, int value) -{ - /* - * If value is +1, activate a passive instance. - * If value is -1, deactivate a passive instance. - */ - if (type == THERMAL_TRIP_PASSIVE || type == THERMAL_TRIPS_NONE) - tz->passive += value; -} - -static void update_instance_for_throttle(struct thermal_zone_device *tz, - int trip, enum thermal_trip_type trip_type, - enum thermal_trend trend) -{ - struct thermal_instance *instance; - - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip) - continue; - - instance->target = get_target_state(instance, trend); - - /* Activate a passive thermal instance */ - if (instance->target == THERMAL_NO_TARGET) - update_passive_instance(tz, trip_type, 1); - - instance->cdev->updated = false; /* cdev needs update */ - } -} - -static void update_instance_for_dethrottle(struct thermal_zone_device *tz, - int trip, enum thermal_trip_type trip_type) -{ - struct thermal_instance *instance; - struct thermal_cooling_device *cdev; - unsigned long cur_state; - - list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip || - instance->target == THERMAL_NO_TARGET) - continue; - - cdev = instance->cdev; - cdev->ops->get_cur_state(cdev, &cur_state); - - instance->target = cur_state > instance->lower ? - (cur_state - 1) : THERMAL_NO_TARGET; - - /* Deactivate a passive thermal instance */ - if (instance->target == THERMAL_NO_TARGET) - update_passive_instance(tz, trip_type, -1); - - cdev->updated = false; /* cdev needs update */ - } -} - -static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) -{ - long trip_temp; - enum thermal_trip_type trip_type; - enum thermal_trend trend; - - if (trip == THERMAL_TRIPS_NONE) { - trip_temp = tz->forced_passive; - trip_type = THERMAL_TRIPS_NONE; - } else { - tz->ops->get_trip_temp(tz, trip, &trip_temp); - tz->ops->get_trip_type(tz, trip, &trip_type); - } - - trend = get_tz_trend(tz, trip); - - mutex_lock(&tz->lock); - - if (tz->temperature >= trip_temp) - update_instance_for_throttle(tz, trip, trip_type, trend); - else - update_instance_for_dethrottle(tz, trip, trip_type); - - mutex_unlock(&tz->lock); -} - -/** - * step_wise_throttle - throttles devices asscciated with the given zone - * @tz - thermal_zone_device - * @trip - the trip point - * @trip_type - type of the trip point - * - * Throttling Logic: This uses the trend of the thermal zone to throttle. - * If the thermal zone is 'heating up' this throttles all the cooling - * devices associated with the zone and its particular trip point, by one - * step. If the zone is 'cooling down' it brings back the performance of - * the devices by one step. - */ -static int step_wise_throttle(struct thermal_zone_device *tz, int trip) -{ - struct thermal_instance *instance; - - thermal_zone_trip_update(tz, trip); - - if (tz->forced_passive) - thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE); - - mutex_lock(&tz->lock); - - list_for_each_entry(instance, &tz->thermal_instances, tz_node) - thermal_cdev_update(instance->cdev); - - mutex_unlock(&tz->lock); - - return 0; -} - -static struct thermal_governor thermal_gov_step_wise = { - .name = "step_wise", - .throttle = step_wise_throttle, - .owner = THIS_MODULE, -}; - -static int __init thermal_gov_step_wise_init(void) -{ - return thermal_register_governor(&thermal_gov_step_wise); -} - -static void __exit thermal_gov_step_wise_exit(void) -{ - thermal_unregister_governor(&thermal_gov_step_wise); -} - -/* This should load after thermal framework */ -fs_initcall(thermal_gov_step_wise_init); -module_exit(thermal_gov_step_wise_exit); - -MODULE_AUTHOR("Durgadoss R"); -MODULE_DESCRIPTION("A step-by-step thermal throttling governor"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/thermal.new/sunxi-battery.c b/linux-3.4/drivers/thermal.new/sunxi-battery.c deleted file mode 100755 index 106a52c4..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-battery.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * drivers/thermal/sunxi-temperature.c - * - * Copyright (C) 2013-2014 allwinner. - * Li Ming - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include "sunxi-thermal.h" - -#ifdef CONFIG_SUNXI_BUDGET_COOLING - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-budget-0" -#else - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-cpufreq-0" -#endif - -enum { - DEBUG_INIT = 1U << 0, - DEBUG_CONTROL_INFO = 1U << 1, - DEBUG_DATA_INFO = 1U << 2, - DEBUG_SUSPEND = 1U << 3, -}; -static u32 debug_mask = 0xf; -#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \ - printk(KERN_DEBUG fmt , ## arg) - -static struct ths_config_info bat_info = { - .input_type = BAT_TYPE, -}; - -int sunxi_bat_read_cap(int value) -{ - int bat_cap = 0; - - bat_cap = axp_read_bat_cap(); - bat_cap = 100 - bat_cap; - if (axp_read_ac_chg()) - bat_cap = 0; - - return bat_cap; -} - -/****************************** bat zone 1 *************************************/ -static struct thermal_trip_point_conf sunxi_trip_data_1; - -static struct thermal_cooling_conf sunxi_cooling_data_1; - -static struct thermal_sensor_conf sunxi_bat_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = sunxi_bat_read_cap, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone bat_zone_1 = { - .id = 0, - .name = "sunxi-bat-1", - .sunxi_ths_sensor_conf = &sunxi_bat_conf_1, -}; - -/**************************** bat zone 1 end ***********************************/ - -static int __init sunxi_bat_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(bat_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = bat_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = 100-bat_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = 100-bat_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = 100-bat_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = 100-bat_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = 100-bat_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = 100-bat_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = 100-bat_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = 100-bat_info.trip1_7; - sunxi_cooling_data_1.freq_clip_count = bat_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = bat_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = bat_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = 100-bat_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = bat_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = bat_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = 100-bat_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = bat_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = bat_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = 100-bat_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = bat_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = bat_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = 100-bat_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = bat_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = bat_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = 100-bat_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = bat_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = bat_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = 100-bat_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = bat_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = bat_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = 100-bat_info.trip1_6; - bat_zone_1.sunxi_ths_sensor_conf->trend = bat_info.ths_trend; -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - err = sunxi_ths_register_thermal_dynamic(&bat_zone_1); -#else - err = sunxi_ths_register_thermal(&bat_zone_1); -#endif - if(err < 0) { - printk(KERN_ERR "bat: register thermal core failed\n"); - goto fail; - } - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail: - return err; -} - -static void __exit sunxi_bat_exit(void) -{ -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&bat_zone_1); -#else - sunxi_ths_unregister_thermal(&bat_zone_1); -#endif -} - -late_initcall(sunxi_bat_init); -module_exit(sunxi_bat_exit); -module_param_named(debug_mask, debug_mask, int, 0644); -MODULE_DESCRIPTION("bat thermal driver"); -MODULE_AUTHOR("Ming Li"); -MODULE_LICENSE("GPL"); - diff --git a/linux-3.4/drivers/thermal.new/sunxi-cpu-budget-cooling.c b/linux-3.4/drivers/thermal.new/sunxi-cpu-budget-cooling.c deleted file mode 100755 index 5bb1fe45..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-cpu-budget-cooling.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * drivers/thermal/sunxi-cpu-cooling.c - * - * Copyright (C) 2013-2014 allwinner. - * kevin.z.m - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ARCH_SUN8IW1 -static struct cpu_budget_table m_default_budgets_table[]= -{ - {1,1008000,4,INVALID_FREQ,0}, - {1,864000 ,4,INVALID_FREQ,0}, - {1,720000 ,4,INVALID_FREQ,0}, - {1,480000 ,4,INVALID_FREQ,0}, - {1,1008000,3,INVALID_FREQ,0}, - {1,864000 ,3,INVALID_FREQ,0}, - {1,720000 ,3,INVALID_FREQ,0}, - {1,480000 ,3,INVALID_FREQ,0}, - {1,1008000,2,INVALID_FREQ,0}, - {1,864000 ,2,INVALID_FREQ,0}, - {1,720000 ,2,INVALID_FREQ,0}, - {1,480000 ,2,INVALID_FREQ,0}, - {1,1008000,1,INVALID_FREQ,0}, - {1,864000 ,1,INVALID_FREQ,0}, - {1,720000 ,1,INVALID_FREQ,0}, - {1,480000 ,1,INVALID_FREQ,0}, -}; -#endif -#ifdef CONFIG_ARCH_SUN8IW5 -static struct cpu_budget_table m_default_budgets_table[]= -{ - {1,1344000,4,INVALID_FREQ,0}, - {1,1200000 ,4,INVALID_FREQ,0}, - {1,1008000 ,4,INVALID_FREQ,0}, - {1,648000 ,4,INVALID_FREQ,0}, -}; -#endif -#ifdef CONFIG_ARCH_SUN8IW6 -static struct cpu_budget_table m_default_budgets_table[]= -{ - {1,1200000,4,1200000,4}, - {1,1104000,4,1104000,4}, - {1,1008000,4,1008000,4}, - {1,816000,4,816000,4}, - {1,1200000,4,1200000,3}, - {1,1104000,4,1104000,3}, - {1,1008000,4,1008000,3}, - {1,816000,4,816000,3}, - {1,1200000,4,1200000,2}, - {1,1104000,4,1104000,2}, - {1,1008000,4,1008000,2}, - {1,816000,4,816000,2}, - {1,1200000,4,1200000,1}, - {1,1104000,4,1104000,1}, - {1,1008000,4,1008000,1}, - {1,816000,4,816000,1}, -}; -#endif -/* LOBO */ -#ifdef CONFIG_ARCH_SUN8IW7 -static struct cpu_budget_table m_default_budgets_table[]= -{ - {1,1200000 ,4,INVALID_FREQ,0}, - {1,1008000 ,4,INVALID_FREQ,0}, - {1,1008000 ,2,INVALID_FREQ,0}, - {1,1008000 ,1,INVALID_FREQ,0}, - {1,504000 ,1,INVALID_FREQ,0}, -}; -#endif -#ifdef CONFIG_ARCH_SUN9IW1 -static struct cpu_budget_table m_default_budgets_table[]= -{ - {1,1008000,4,1008000,4}, - {1,1008000,4,864000,4}, - {1,1008000,4,720000,4}, - {1,1008000,4,1008000,3}, - {1,1008000,4,864000,3}, - {1,1008000,4,720000,3}, - {1,1008000,4,1008000,2}, - {1,1008000,4,864000,2}, - {1,1008000,4,720000,2}, - {1,1008000,4,1008000,1}, - {1,1008000,4,864000,1}, - {1,1008000,4,720000,1}, - {1,1008000,4,INVALID_FREQ,0}, - {1,864000,4,INVALID_FREQ,0}, - {1,720000,4,INVALID_FREQ,0}, - {1,480000,4,INVALID_FREQ,0}, -}; - -#endif -#define SYSCFG_BUDGET_TABLE_MAX 64 -static struct cpu_budget_table m_syscfg_budgets_table[SYSCFG_BUDGET_TABLE_MAX]; -static unsigned int m_syscfg_budgets_table_num=0; -static struct cpu_budget_table* dynamic_tbl=NULL; -static struct cpu_budget_table* m_current_tbl=m_default_budgets_table; -static unsigned int dynamic_tbl_num=sizeof(m_default_budgets_table)/sizeof(struct cpu_budget_table); -static unsigned int max_tbl_num=sizeof(m_default_budgets_table)/sizeof(struct cpu_budget_table); -#ifdef CONFIG_SCHED_HMP -extern void __init arch_get_fast_and_slow_cpus(struct cpumask *fast, - struct cpumask *slow); -#endif -static int sunxi_cpu_budget_cooling_register(struct platform_device *pdev) -{ - struct thermal_cooling_device *cdev; - struct cpumask cluster0_mask; - struct cpumask cluster1_mask; - int i; - /* make sure cpufreq driver has been initialized */ - if (!cpufreq_frequency_get_table(0)) - return -EPROBE_DEFER; - cpumask_clear(&cluster0_mask); - cpumask_clear(&cluster1_mask); -#if defined(CONFIG_SCHED_HMP) - arch_get_fast_and_slow_cpus(&cluster1_mask,&cluster0_mask); -#elif defined(CONFIG_SCHED_SMP_DCMP) - if (strlen(CONFIG_CLUSTER0_CPU_MASK) && strlen(CONFIG_CLUSTER1_CPU_MASK)) { - if (cpulist_parse(CONFIG_CLUSTER0_CPU_MASK, &cluster0_mask)) { - pr_err("Failed to parse cluster0 cpu mask!\n"); - return -1; - } - if (cpulist_parse(CONFIG_CLUSTER1_CPU_MASK, &cluster1_mask)) { - pr_err("Failed to parse cluster1 cpu mask!\n"); - return -1; - } - } -#else - cpumask_copy(&cluster0_mask, cpu_possible_mask); -#endif - dynamic_tbl = kmalloc(sizeof(struct cpu_budget_table)*max_tbl_num,GFP_KERNEL); - dynamic_tbl_num=0; - for(i=0;idev, "Failed to register cooling device\n"); - return PTR_ERR(cdev); - } - platform_set_drvdata(pdev, cdev); - dev_info(&pdev->dev, "Cooling device registered: %s\n", cdev->type); - return 0; -} -static int sunxi_cpu_budget_cooling_unregister(struct platform_device *pdev) -{ - int ret = 0; - struct thermal_cooling_device *cdev = platform_get_drvdata(pdev); - cpu_budget_cooling_unregister(cdev); - kfree(dynamic_tbl); - return ret; -} - -static ssize_t -sunxi_cpu_budget_present_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret=0; - struct platform_device *pdev; - struct thermal_cooling_device *cdev; - struct cpu_budget_cooling_device *bdevice; - - pdev= to_platform_device(dev); - if(!pdev) - return ret; - - cdev = platform_get_drvdata(pdev); - if((!cdev) || (!cdev->devdata)) - return ret; - - bdevice= (struct cpu_budget_cooling_device *)cdev->devdata; - ret += sprintf(buf, "Limit:%d,%d,%d,%d,%d\n", - bdevice->cluster0_freq_limit, - bdevice->cluster0_num_limit, - bdevice->cluster1_freq_limit, - bdevice->cluster1_num_limit, - bdevice->gpu_throttle); - - return ret; -} -static ssize_t -sunxi_cpu_budget_online_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int i,j,ret=0; - for(i=0,j=0;idevdata)) - return ret; - bdevice= (struct cpu_budget_cooling_device *)cdev->devdata; - ret += sprintf(buf, "roomage:%d,%d,%d,%d,%d,%d,%d,%d\n", - bdevice->cluster0_freq_floor, - bdevice->cluster0_num_floor, - bdevice->cluster1_freq_floor, - bdevice->cluster1_num_floor, - bdevice->cluster0_freq_roof, - bdevice->cluster0_num_roof, - bdevice->cluster1_freq_roof, - bdevice->cluster1_num_roof); - return ret; -} -static ssize_t -sunxi_cpu_budget_roomage_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int ret=0; - struct platform_device *pdev; - struct thermal_cooling_device *cdev; - struct cpu_budget_cooling_device *bdevice; - unsigned int roomage_data[8]; - unsigned long flags; - - pdev= to_platform_device(dev); - if(!pdev) - return ret; - - cdev = platform_get_drvdata(pdev); - if((!cdev) || (!cdev->devdata)) - return ret; - sscanf(buf,"%u %u %u %u %u %u %u %u\n", - &roomage_data[0], - &roomage_data[1], - &roomage_data[2], - &roomage_data[3], - &roomage_data[4], - &roomage_data[5], - &roomage_data[6], - &roomage_data[7]); - bdevice= (struct cpu_budget_cooling_device *)cdev->devdata; - spin_lock_irqsave(&bdevice->lock, flags); - bdevice->cluster0_freq_floor = roomage_data[0]; - bdevice->cluster0_num_floor = roomage_data[1]; - bdevice->cluster1_freq_floor = roomage_data[2]; - bdevice->cluster1_num_floor = roomage_data[3]; - bdevice->cluster0_freq_roof = roomage_data[4]; - bdevice->cluster0_num_roof = roomage_data[5]; - bdevice->cluster1_freq_roof = roomage_data[6]; - bdevice->cluster1_num_roof = roomage_data[7]; - spin_unlock_irqrestore(&bdevice->lock, flags); - ret = cpu_budget_update_state(bdevice); - if(ret) - return ret; - return count; -} - -static DEVICE_ATTR(roomage, 0644,sunxi_cpu_budget_roomage_show, sunxi_cpu_budget_roomage_store); -static DEVICE_ATTR(online, 0644,sunxi_cpu_budget_online_show, sunxi_cpu_budget_online_store); -static DEVICE_ATTR(present, 0444,sunxi_cpu_budget_present_show, NULL); - -static int sunxi_cpu_budget_cooling_probe(struct platform_device *pdev) -{ - int ret=0; - ret=sunxi_cpu_budget_cooling_register(pdev); - device_create_file(&pdev->dev, &dev_attr_online); - device_create_file(&pdev->dev, &dev_attr_present); - device_create_file(&pdev->dev, &dev_attr_roomage); - return ret; -} -static int sunxi_cpu_budget_cooling_remove(struct platform_device *pdev) -{ - int ret=0; - device_remove_file(&pdev->dev, &dev_attr_roomage); - device_remove_file(&pdev->dev, &dev_attr_present); - device_remove_file(&pdev->dev, &dev_attr_online); - ret=sunxi_cpu_budget_cooling_unregister(pdev); - return ret; -} - -static struct platform_device sunxi_cpu_budget_cooling_device = { - .name = "sunxi-budget-cooling", - .id = PLATFORM_DEVID_NONE, -}; - -static struct platform_driver sunxi_cpu_budget_cooling_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "sunxi-budget-cooling", - }, - .probe = sunxi_cpu_budget_cooling_probe, - .remove = sunxi_cpu_budget_cooling_remove, -}; - -#ifdef CONFIG_SUNXI_BUDGET_COOLING_VFTBL -struct cpufreq_dvfs_s { - unsigned int freq; /* cpu frequency */ - unsigned int volt; /* voltage for the frequency */ -}; -static struct cpufreq_dvfs_s c0_vftable_syscfg[16]; -static struct cpufreq_dvfs_s c1_vftable_syscfg[16]; -static unsigned int c0_table_length=0; -static unsigned int c1_table_length=0; - -#if defined(CONFIG_ARCH_SUN9IW1)|| defined(CONFIG_ARCH_SUN8IW6) -static char* multi_cluster_prefix[]={"L_LV","B_LV"}; -#else -static char* single_cluster_prefix[]={"LV"}; -#endif - -static int sunxi_cpu_budget_vftable_init(void) -{ - script_item_u val; - script_item_value_type_e type; - struct cpufreq_dvfs_s *ptable; - unsigned int * plen; - unsigned int freq,volt; - int i,j,k,cluster_nr=1,ret = -1; - char tbl_name[]="dvfs_table"; - char name[16] = {0}; - unsigned int vf_table_type = 0; - char** prefix; - -#if defined(CONFIG_ARCH_SUN9IW1)|| defined(CONFIG_ARCH_SUN8IW6) - cluster_nr = 2; - prefix = multi_cluster_prefix; -#else - cluster_nr = 1; - prefix = single_cluster_prefix; -#endif - - type = script_get_item("dvfs_table", "vf_table_count", &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - pr_info("%s: support only one vf_table\n", __func__); - sprintf(tbl_name, "%s", "dvfs_table"); - } else { - vf_table_type = sunxi_get_soc_bin(); - sprintf(tbl_name, "%s%d", "vf_table", vf_table_type); - } - - for(k=0;k= 16){ - pr_err("%s from sysconfig is out of bounder\n",name); - goto fail; - } - for (i = 1,j=0; i <= *plen ; i++) - { - sprintf(name, "%s%d_freq", prefix[k],i); - type = script_get_item(tbl_name, name, &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - pr_err("get %s from sysconfig failed\n", name); - goto fail; - } - freq = val.val; - - sprintf(name, "%s%d_volt", prefix[k],i); - type = script_get_item(tbl_name, name, &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - pr_err("get %s from sysconfig failed\n", name); - goto fail; - } - volt = val.val; - - if(freq) - { - ptable[j].freq = freq / 1000; - ptable[j].volt = volt; - j++; - } - } - *plen = j; - } - return 0; -fail: - return ret; -} -#endif -static int sunxi_cpu_budget_syscfg_init(void) -{ - script_item_u val; - script_item_value_type_e type; - char tbl_name[]="cooler_table"; - int i,num=-1,ret = -1; - char name[32] = {0}; - - type = script_get_item(tbl_name, "cooler_count", &val); - if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { - printk("fetch cooler_count from sysconfig failed\n"); - goto fail; - } - - m_syscfg_budgets_table_num = val.val; - if(m_syscfg_budgets_table_num >= SYSCFG_BUDGET_TABLE_MAX){ - printk("cooler_count from sysconfig is out of bounder\n"); - goto fail; - } - memset(m_syscfg_budgets_table,0x0,sizeof(m_syscfg_budgets_table)); - for (i = 0; i < m_syscfg_budgets_table_num; i++){ - sprintf(name, "cooler%d", i); - type = script_get_item(tbl_name, name, &val); - if (SCIRPT_ITEM_VALUE_TYPE_STR != type) { - printk("get cooler%d from sysconfig failed\n", i); - goto fail; - } -#if defined(CONFIG_ARCH_SUN9IW1) - num=sscanf(val.str, "%u %u %u %u %u", - &m_syscfg_budgets_table[i].cluster0_freq, - &m_syscfg_budgets_table[i].cluster0_cpunr, - &m_syscfg_budgets_table[i].cluster1_freq, - &m_syscfg_budgets_table[i].cluster1_cpunr, - &m_syscfg_budgets_table[i].gpu_throttle); -#elif defined(CONFIG_ARCH_SUN8IW5) || defined(CONFIG_ARCH_SUN8IW6) - num=sscanf(val.str, "%u %u %u %u %u", - &m_syscfg_budgets_table[i].cluster0_freq, - &m_syscfg_budgets_table[i].cluster0_cpunr, - &m_syscfg_budgets_table[i].cluster1_freq, - &m_syscfg_budgets_table[i].cluster1_cpunr, - &m_syscfg_budgets_table[i].gpu_throttle); -#endif - if (num <= -1) { - printk("parse cooler%d from sysconfig failed\n", i); - goto fail; - } - m_syscfg_budgets_table[i].online = 1; - } - dynamic_tbl_num = m_syscfg_budgets_table_num; - max_tbl_num = m_syscfg_budgets_table_num; - m_current_tbl = m_syscfg_budgets_table; -#ifdef CONFIG_SUNXI_BUDGET_COOLING_VFTBL - if((!m_syscfg_budgets_table[0].cluster0_freq) && (!m_syscfg_budgets_table[0].cluster1_freq)) - for (i = 0; i < m_syscfg_budgets_table_num; i++) - { - if(m_syscfg_budgets_table[i].cluster0_freq < c0_table_length) - m_syscfg_budgets_table[i].cluster0_freq = c0_vftable_syscfg[m_syscfg_budgets_table[i].cluster0_freq].freq; - else - m_syscfg_budgets_table[i].cluster0_freq = c0_vftable_syscfg[c0_table_length-1].freq; - if(m_syscfg_budgets_table[i].cluster1_freq < c1_table_length) - m_syscfg_budgets_table[i].cluster1_freq = c1_vftable_syscfg[m_syscfg_budgets_table[i].cluster1_freq].freq; - else - m_syscfg_budgets_table[i].cluster1_freq = c1_vftable_syscfg[c1_table_length-1].freq; - } -#endif - return 0; - -fail: - m_syscfg_budgets_table_num=0; - return ret; -} - -static int __init sunxi_cpu_budget_cooling_init(void) -{ - int ret = 0; -#ifdef CONFIG_SUNXI_BUDGET_COOLING_VFTBL - sunxi_cpu_budget_vftable_init(); -#endif - sunxi_cpu_budget_syscfg_init(); - ret = platform_driver_register(&sunxi_cpu_budget_cooling_driver); - if (IS_ERR_VALUE(ret)) { - printk("register sunxi_cpu_budget_cooling_driver failed\n"); - return ret; - } - ret = platform_device_register(&sunxi_cpu_budget_cooling_device); - if (IS_ERR_VALUE(ret)) { - printk("register sunxi_cpu_budget_cooling_device failed\n"); - return ret; - } - return ret; -} - -static void __exit sunxi_cpu_budget_cooling_exit(void) -{ - platform_driver_unregister(&sunxi_cpu_budget_cooling_driver); -} - -/* Should be later than sunxi_cpufreq register */ -late_initcall(sunxi_cpu_budget_cooling_init); -module_exit(sunxi_cpu_budget_cooling_exit); - -MODULE_AUTHOR("kevin.z.m "); -MODULE_DESCRIPTION("sunxi cpufreq cooling driver"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/thermal.new/sunxi-cpu-cooling.c b/linux-3.4/drivers/thermal.new/sunxi-cpu-cooling.c deleted file mode 100755 index e820b079..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-cpu-cooling.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * drivers/thermal/sunxi-cpu-cooling.c - * - * Copyright (C) 2013-2014 allwinner. - * kevin.z.m - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include - -static int sunxi_cpufreq_cooling_probe(struct platform_device *pdev) -{ - struct thermal_cooling_device *cdev; - struct cpumask mask_val; - - /* make sure cpufreq driver has been initialized */ - if (!cpufreq_frequency_get_table(0)) - return -EPROBE_DEFER; - - cpumask_set_cpu(0, &mask_val); - cdev = cpufreq_cooling_register(&mask_val); - - if (IS_ERR_OR_NULL(cdev)) { - dev_err(&pdev->dev, "Failed to register cooling device\n"); - return PTR_ERR(cdev); - } - - platform_set_drvdata(pdev, cdev); - - dev_info(&pdev->dev, "Cooling device registered: %s\n", cdev->type); - - return 0; -} - -static int sunxi_cpufreq_cooling_remove(struct platform_device *pdev) -{ - struct thermal_cooling_device *cdev = platform_get_drvdata(pdev); - - cpufreq_cooling_unregister(cdev); - - return 0; -} - -static struct platform_device sunxi_cpufreq_cooling_device = { - .name = "sunxi-cpufreq-cooling", - .id = PLATFORM_DEVID_NONE, -}; - -static struct platform_driver sunxi_cpufreq_cooling_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "sunxi-cpufreq-cooling", - }, - .probe = sunxi_cpufreq_cooling_probe, - .remove = sunxi_cpufreq_cooling_remove, -}; - -static int __init sunxi_cpufreq_cooling_init(void) -{ - int ret = 0; - - ret = platform_driver_register(&sunxi_cpufreq_cooling_driver); - if (IS_ERR_VALUE(ret)) { - printk("register sunxi_cpufreq_cooling_driver failed\n"); - return ret; - } - - ret = platform_device_register(&sunxi_cpufreq_cooling_device); - if (IS_ERR_VALUE(ret)) { - printk("register sunxi_cpufreq_cooling_device failed\n"); - return ret; - } - - return ret; -} - -static void __exit sunxi_cpufreq_cooling_exit(void) -{ - platform_driver_unregister(&sunxi_cpufreq_cooling_driver); -} - -/* Should be later than sunxi_cpufreq register */ -late_initcall(sunxi_cpufreq_cooling_init); -module_exit(sunxi_cpufreq_cooling_exit); - -MODULE_AUTHOR("kevin.z.m "); -MODULE_DESCRIPTION("sunxi cpufreq cooling driver"); -MODULE_LICENSE("GPL"); diff --git a/linux-3.4/drivers/thermal.new/sunxi-temperature.c b/linux-3.4/drivers/thermal.new/sunxi-temperature.c deleted file mode 100755 index f623625a..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-temperature.c +++ /dev/null @@ -1,1849 +0,0 @@ -/* - * drivers/thermal/sunxi-temperature.c - * - * Copyright (C) 2013-2014 allwinner. - * Li Ming - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_ARCH_SUN9IW1P1) -#include -#elif defined(CONFIG_ARCH_SUN8IW7P1) -#include -#endif -#ifdef CONFIG_PM -#include -#endif -#include "sunxi-thermal.h" -#include "sunxi-temperature.h" - -#ifdef CONFIG_SUNXI_BUDGET_COOLING - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-budget-0" -#else - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-cpufreq-0" -#endif -static u32 debug_mask = 0x0; -#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \ - printk(fmt , ## arg) - -struct sunxi_ths_data { - void __iomem *base_addr; - int circle_num; - int temp_data1[10]; - int temp_data2[10]; - int temp_data3[10]; - int temp_data4[10]; - int thermal_data[6]; - atomic_t delay; - struct delayed_work work; - struct work_struct irq_work; - - int irq_used; - - struct input_dev *ths_input_dev; - atomic_t input_delay; - atomic_t input_enable; - struct delayed_work input_work; - struct mutex input_enable_mutex; - -#ifdef CONFIG_PM -struct dev_pm_domain ths_pm_domain; -#endif -}; -static struct sunxi_ths_data *thermal_data; -static int temperature[6] = {5, 5, 5, 5, 5, 5}; -static DEFINE_SPINLOCK(data_lock); -static struct ths_config_info ths_info = { - .input_type = THS_TYPE, -}; - -static void sunxi_ths_reg_clear(void); -static void sunxi_ths_reg_init(void); - -#if defined(CONFIG_ARCH_SUN9IW1P1) -static void sunxi_ths_clk_cfg(void); -static struct clk *gpadc_clk; -static struct clk *gpadc_clk_source; -#elif defined(CONFIG_ARCH_SUN8IW7P1) -static struct clk *ths_clk; -static struct clk *ths_clk_source; -#endif - -/********************************** input *****************************************/ - -static ssize_t sunxi_ths_input_delay_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - dprintk(DEBUG_CONTROL_INFO, "%d, %s\n", atomic_read(&thermal_data->input_delay), __FUNCTION__); - return sprintf(buf, "%d\n", atomic_read(&thermal_data->input_delay)); - -} - -static ssize_t sunxi_ths_input_delay_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (data > THERMAL_DATA_DELAY) - data = THERMAL_DATA_DELAY; - atomic_set(&thermal_data->input_delay, (unsigned int) data); - - return count; -} - - -static ssize_t sunxi_ths_input_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - dprintk(DEBUG_CONTROL_INFO, "%d, %s\n", atomic_read(&thermal_data->input_enable), __FUNCTION__); - return sprintf(buf, "%d\n", atomic_read(&thermal_data->input_enable)); -} - -static void sunxi_ths_input_set_enable(struct device *dev, int enable) -{ - int pre_enable = atomic_read(&thermal_data->input_enable); - - mutex_lock(&thermal_data->input_enable_mutex); - if (enable) { - if (pre_enable == 0) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - atomic_set(&thermal_data->input_enable, 1); - } - - } else { - if (pre_enable == 1) { - cancel_delayed_work_sync(&thermal_data->input_work); - atomic_set(&thermal_data->input_enable, 0); - } - } - mutex_unlock(&thermal_data->input_enable_mutex); -} - -static ssize_t sunxi_ths_input_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if ((data == 0)||(data==1)) { - sunxi_ths_input_set_enable(dev,data); - } - - return count; -} - -static ssize_t sunxi_ths_show_temp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t cnt = 0; - int i = 0; - printk("%s: enter \n", __func__); - - for (i=0; i<6; i++) { - cnt += sprintf(buf + cnt,"temperature[%d]:%d\n" , i, ths_read_data(i)); - } - - return cnt; -} - -static ssize_t sunxi_ths_set_temp(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int data1, data2; - unsigned long irqflags; - char *endp; - - cancel_delayed_work_sync(&thermal_data->work); - - data1 = simple_strtoul(buf, &endp, 10); - if (*endp != ' ') { - printk("%s: %d\n", __func__, __LINE__); - return -EINVAL; - } - buf = endp + 1; - - data2 = simple_strtoul(buf, &endp, 10); - - spin_lock_irqsave(&data_lock, irqflags); - temperature[data1] = data2; - spin_unlock_irqrestore(&data_lock, irqflags); - - printk("temperature[%d] = %d\n", data1, data2); - - return count; -} - - -static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_input_delay_show, sunxi_ths_input_delay_store); -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_input_enable_show, sunxi_ths_input_enable_store); -static DEVICE_ATTR(temperature, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_show_temp, sunxi_ths_set_temp); - -static struct attribute *sunxi_ths_input_attributes[] = { - &dev_attr_delay.attr, - &dev_attr_enable.attr, - &dev_attr_temperature.attr, - NULL -}; - -static struct attribute_group sunxi_ths_input_attribute_group = { - .attrs = sunxi_ths_input_attributes -}; - -static void sunxi_ths_input_work_func(struct work_struct *work) -{ - static int tempetature = 5; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, input_work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->input_delay)); - - tempetature = ths_read_data(4); - input_report_abs(data->ths_input_dev, ABS_MISC, tempetature); - input_sync(data->ths_input_dev); - dprintk(DEBUG_DATA_INFO, "%s: temperature %d,\n", __func__, tempetature); - - schedule_delayed_work(&data->input_work, delay); -} - - -static int sunxi_ths_input_init(struct sunxi_ths_data *data) -{ - int err = 0; - - data->ths_input_dev = input_allocate_device(); - if (IS_ERR_OR_NULL(data->ths_input_dev)) { - printk(KERN_ERR "temp_dev: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - data->ths_input_dev->name = "sunxi-ths"; - data->ths_input_dev->phys = "sunxiths/input0"; - data->ths_input_dev->id.bustype = BUS_HOST; - data->ths_input_dev->id.vendor = 0x0001; - data->ths_input_dev->id.product = 0x0001; - data->ths_input_dev->id.version = 0x0100; - - input_set_capability(data->ths_input_dev, EV_ABS, ABS_MISC); - input_set_abs_params(data->ths_input_dev, ABS_MISC, -50, 180, 0, 0); - - err = input_register_device(data->ths_input_dev); - if (0 < err) { - pr_err("%s: could not register input device\n", __func__); - input_free_device(data->ths_input_dev); - goto fail2; - } - - INIT_DELAYED_WORK(&data->input_work, sunxi_ths_input_work_func); - - mutex_init(&data->input_enable_mutex); - atomic_set(&data->input_enable, 0); - atomic_set(&data->input_delay, THERMAL_DATA_DELAY); - - err = sysfs_create_group(&data->ths_input_dev->dev.kobj, - &sunxi_ths_input_attribute_group); - if (err < 0) - { - pr_err("%s: sysfs_create_group err\n", __func__); - goto fail3; - } - - return err; -fail3: - input_unregister_device(data->ths_input_dev); -fail2: - kfree(data->ths_input_dev); -fail1: - return err; - -} - -static void sunxi_ths_input_exit(struct sunxi_ths_data *data) -{ - sysfs_remove_group(&data->ths_input_dev->dev.kobj, &sunxi_ths_input_attribute_group); - input_unregister_device(data->ths_input_dev); -} - -/********************************** input end *****************************************/ - - -static void ths_write_data(int index, struct sunxi_ths_data *data) -{ - unsigned long irqflags; - - spin_lock_irqsave(&data_lock, irqflags); - temperature[index] = data->thermal_data[index]; - spin_unlock_irqrestore(&data_lock, irqflags); - - return; -} - -int ths_read_data(int index) -{ - unsigned long irqflags; - int data; - - spin_lock_irqsave(&data_lock, irqflags); - data = temperature[index]; - spin_unlock_irqrestore(&data_lock, irqflags); - - return data; -} -EXPORT_SYMBOL(ths_read_data); - -static void calc_temperature(int value, int divisor, int minus, struct sunxi_ths_data *data) -{ - unsigned int i = 0; - int64_t avg_temp[4] = {0, 0, 0, 0}; - - if (data->circle_num % 5 || !data->circle_num) - return; - if (value > 0) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[0] += data->temp_data1[i]; - } - } - if (value > 1) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[1] += data->temp_data2[i]; - } - } - if (value > 2) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[2] += data->temp_data3[i]; - } - } - if (value > 3) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[3] += data->temp_data4[i]; - } - } - - for (i = 0; i < value; i++) { - do_div(avg_temp[i], data->circle_num); - dprintk(DEBUG_DATA_INFO, "avg_temp_reg=%lld\n", avg_temp[i]); - -#if defined(CONFIG_ARCH_SUN9IW1P1) || defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN8IW7P1) - avg_temp[i] *= 1000; - if (0 != avg_temp[i]) - do_div(avg_temp[i], divisor); - - avg_temp[i]= minus-avg_temp[i]; -#else - avg_temp[i] *= 100; - if (0 != avg_temp[i]) - do_div(avg_temp[i], divisor); - - avg_temp[i] -= minus; -#endif - dprintk(DEBUG_DATA_INFO, "avg_temp=%lld C\n", avg_temp[i]); - - data->thermal_data[i] = avg_temp[i]; - } - - data->circle_num = 0; - return; -} - -#ifdef CONFIG_PM -static int sunxi_ths_suspend(struct device *dev) -{ - dprintk(DEBUG_SUSPEND, "%s: suspend\n", __func__); - if (NORMAL_STANDBY == standby_type) { - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - cancel_delayed_work_sync(&thermal_data->input_work); - } - mutex_unlock(&thermal_data->input_enable_mutex); - - if (thermal_data->irq_used) - disable_irq_nosync(THS_IRQNO); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - } else if (SUPER_STANDBY == standby_type) { - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - cancel_delayed_work_sync(&thermal_data->input_work); - } - mutex_unlock(&thermal_data->input_enable_mutex); - - if (thermal_data->irq_used) - disable_irq_nosync(THS_IRQNO); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - } -#if defined(CONFIG_ARCH_SUN9IW1P1) - clk_disable_unprepare(gpadc_clk); -#elif defined(CONFIG_ARCH_SUN8IW7P1) - clk_disable_unprepare(ths_clk); -#endif - return 0; -} - -static int sunxi_ths_resume(struct device *dev) -{ - dprintk(DEBUG_SUSPEND, "%s: resume\n", __func__); - -#if defined(CONFIG_ARCH_SUN9IW1P1) - clk_prepare_enable(gpadc_clk); -#elif defined(CONFIG_ARCH_SUN8IW7P1) - clk_prepare_enable(ths_clk); -#endif - - if (NORMAL_STANDBY == standby_type) { - sunxi_ths_reg_init(); - if (thermal_data->irq_used) - enable_irq(THS_IRQNO); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - } - mutex_unlock(&thermal_data->input_enable_mutex); - } else if (SUPER_STANDBY == standby_type) { - sunxi_ths_reg_init(); - if (thermal_data->irq_used) - enable_irq(THS_IRQNO); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - } - mutex_unlock(&thermal_data->input_enable_mutex); - } - return 0; -} -#endif - -#ifdef CONFIG_ARCH_SUN8IW3P1 -static void sunxi_ths_work_func(struct work_struct *work) -{ - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if (1000 < data->temp_data1[data->circle_num]) - data->circle_num++; - calc_temperature(1, 625, 265, data); - - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(0, data); - ths_write_data(4, data); - - schedule_delayed_work(&data->work, delay); -} -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG1); - writel(0, thermal_data->base_addr + THS_PRO_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ - writel(THS_CTRL_REG0_VALUE, thermal_data->base_addr + THS_CTRL_REG0); - writel(THS_CTRL_REG1_VALUE, thermal_data->base_addr + THS_CTRL_REG1); - writel(THS_PRO_CTRL_REG_VALUE, thermal_data->base_addr + THS_PRO_CTRL_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG0 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG0)); - dprintk(DEBUG_INIT, "THS_CTRL_REG1 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG1)); - dprintk(DEBUG_INIT, "THS_PRO_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_PRO_CTRL_REG)); -} - -static struct thermal_trip_point_conf sunxi_trip_data; - -static struct thermal_cooling_conf sunxi_cooling_data; - -static struct thermal_sensor_conf sunxi_sensor_conf = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data, - .cooling_data = &sunxi_cooling_data, -}; - -static struct sunxi_thermal_zone ths_zone = { - .id = 0, - .name = "sunxi-therm", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf, -}; - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - pr_err("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data.trip_count = ths_info.trip1_count; - sunxi_trip_data.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data.trip_val[2] = ths_info.trip1_2; - - sunxi_cooling_data.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data.freq_data[1].temp_level = ths_info.trip1_1; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - pr_err("thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone); - if(err < 0) { - pr_err("therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - thermal_data->irq_used = 0; - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - sunxi_ths_unregister_thermal(&ths_zone); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW5P1) - -#define SUN8IW5_SID_CALIBRATION -#ifdef SUN8IW5_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1C23800) -#define SID_THS (SID_BASE + 0X10) -static void ths_calibration(void) -{ - u32 reg_val; - reg_val = readl(SID_THS); - if(reg_val != 0) - { - writel(reg_val,thermal_data->base_addr + TEMP_CATA); - } -} -#endif - -static void sunxi_ths_work_func(struct work_struct *work) -{ - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - //dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if (1000 < data->temp_data1[data->circle_num]) - data->circle_num++; - calc_temperature(1, 618, 269, data); - - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(0, data); - ths_write_data(4, data); - - schedule_delayed_work(&data->work, delay); -} -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG1); - writel(0, thermal_data->base_addr + THS_PRO_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ -#ifdef SUN8IW5_SID_CALIBRATION - ths_calibration(); -#endif - writel(THS_CTRL_REG0_VALUE, thermal_data->base_addr + THS_CTRL_REG0); - writel(THS_CTRL_REG1_VALUE, thermal_data->base_addr + THS_CTRL_REG1); - writel(THS_PRO_CTRL_REG_VALUE, thermal_data->base_addr + THS_PRO_CTRL_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG0 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG0)); - dprintk(DEBUG_INIT, "THS_CTRL_REG1 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG1)); - dprintk(DEBUG_INIT, "THS_PRO_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_PRO_CTRL_REG)); -} - -static struct thermal_trip_point_conf sunxi_trip_data; - -static struct thermal_cooling_conf sunxi_cooling_data; - -static struct thermal_sensor_conf sunxi_sensor_conf = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data, - .cooling_data = &sunxi_cooling_data, -}; - -static struct sunxi_thermal_zone ths_zone = { - .id = 0, - .name = "sunxi-therm", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf, -}; - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data.trip_count = ths_info.trip1_count; - sunxi_trip_data.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data.trip_val[2] = ths_info.trip1_2; - - sunxi_cooling_data.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data.freq_data[1].temp_level = ths_info.trip1_1; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - - ths_zone.sunxi_ths_sensor_conf->trend = ths_info.ths_trend; -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - err = sunxi_ths_register_thermal_dynamic(&ths_zone); -#else - err = sunxi_ths_register_thermal(&ths_zone); -#endif - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - thermal_data->irq_used = 0; - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone); -#else - sunxi_ths_unregister_thermal(&ths_zone); -#endif - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW6P1) -#define SUN8IW6_SID_CALIBRATION -#ifdef SUN8IW6_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1c14000) - -#define SID_SRAM (SID_BASE + 0x200) - -#define SID_THERMAL_CDATA1 (0xf1c0e000 + 0x34) -#define SID_THERMAL_CDATA2 (0xf1c0e000 + 0x38) - -#define SID_THERMAL_CDATA1_SRAM (SID_SRAM + 0x34) -#define SID_THERMAL_CDATA2_SRAM (SID_SRAM + 0x38) - -#endif - - -static struct workqueue_struct *thermal_wq; - -/****************************** thermal zone 1 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_1 = { - .trip_count = 3, - .trip_val[0] = 80, - .trip_val[1] = 100, - .trip_val[2] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_1 = { - .freq_data[0] = { - .freq_clip_min = 408000, - .freq_clip_max = 2016000, - .temp_level = 80, - }, - .freq_data[1] = { - .freq_clip_min = 60000, - .freq_clip_max = 408000, - .temp_level = 100, - }, - .freq_clip_count = 2, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 4, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2 = { - .trip_count = 1, - .trip_val[0] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - .temp_level = 110, - }, - .freq_clip_count = 1, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int temperature_to_reg(int temp_value, int multiplier, int minus) -{ - int64_t temp_reg; - - temp_reg = minus*1000 - multiplier*temp_value; - - do_div(temp_reg, 1000); - dprintk(DEBUG_INIT, "temp_reg=%lld \n", temp_reg); - - return (int)(temp_reg); -} - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (sunxi_smc_readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - sunxi_smc_writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static void ths_irq_work_func(struct work_struct *work) -{ - dprintk(DEBUG_DATA_INFO, "%s enter\n", __func__); - thermal_zone_device_update(ths_zone_2.therm_dev); - return; -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - unsigned long intsta; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(thermal_data); - - ths_clr_intsta(thermal_data); - - if (intsta & (THS_INTS_SHT0|THS_INTS_SHT1|THS_INTS_SHT2)){ - queue_work(thermal_wq, &thermal_data->irq_work); - } - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - int i = 0; - int temp; - uint64_t avg_temp = 0; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = sunxi_smc_readl(data->base_addr + THS_DATA_REG0); - dprintk(DEBUG_DATA_INFO, "THS data0 = %d\n", data->temp_data1[data->circle_num]); - data->temp_data2[data->circle_num] = sunxi_smc_readl(data->base_addr + THS_DATA_REG1); - dprintk(DEBUG_DATA_INFO, "THS data1 = %d\n", data->temp_data2[data->circle_num]); - data->temp_data3[data->circle_num] = sunxi_smc_readl(data->base_addr + THS_DATA_REG2); - dprintk(DEBUG_DATA_INFO, "THS data2 = %d\n", data->temp_data3[data->circle_num]); - - if ((1000 < data->temp_data1[data->circle_num]) && (1000 < data->temp_data2[data->circle_num]) - && (1000 < data->temp_data3[data->circle_num])) - data->circle_num++; - calc_temperature(3, 14186, 192, data); - - if (0 == data->circle_num) { - temp = data->thermal_data[0]; - for(i=0; i < 3; i++) { - if (temp < data->thermal_data[i]) - temp = data->thermal_data[i]; - ths_write_data(i, data); - avg_temp += data->thermal_data[i]; - } - data->thermal_data[4] = temp; - ths_write_data(4, data); - do_div(avg_temp, 3); - data->thermal_data[5] = (int)(avg_temp); - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_reg_clear(void) -{ - sunxi_smc_writel(0, thermal_data->base_addr + THS_CTRL2_REG); -} - -static void sunxi_ths_reg_init(void) -{ - int reg_value; - - sunxi_smc_writel(THS_CTRL1_VALUE, thermal_data->base_addr + THS_CTRL1_REG); - -#ifdef SUN8IW6_SID_CALIBRATION - reg_value = sunxi_smc_readl(SID_THERMAL_CDATA1_SRAM); - if (0 != reg_value) - sunxi_smc_writel(reg_value, thermal_data->base_addr + THS_0_1_CDATA_REG); - reg_value = sunxi_smc_readl(SID_THERMAL_CDATA2_SRAM); - if (0 != reg_value) - sunxi_smc_writel(reg_value, thermal_data->base_addr + THS_2_CDATA_REG); -#endif - - sunxi_smc_writel(THS_CTRL0_VALUE, thermal_data->base_addr + THS_CTRL0_REG); - sunxi_smc_writel(THS_CTRL2_VALUE, thermal_data->base_addr + THS_CTRL2_REG); - sunxi_smc_writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - sunxi_smc_writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - sunxi_smc_writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14186, 2794); - reg_value = (reg_value<<16); - - sunxi_smc_writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG0); - sunxi_smc_writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG1); - sunxi_smc_writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG2); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", sunxi_smc_readl(thermal_data->base_addr + THS_CTRL2_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", sunxi_smc_readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", sunxi_smc_readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", sunxi_smc_readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); -} - - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = ths_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = ths_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = ths_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = ths_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = ths_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = ths_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = ths_info.trip1_7; - - sunxi_cooling_data_1.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = ths_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = ths_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = ths_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = ths_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = ths_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = ths_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = ths_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = ths_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = ths_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = ths_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = ths_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = ths_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = ths_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = ths_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = ths_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = ths_info.trip1_6; - - sunxi_trip_data_2.trip_count = ths_info.trip2_count; - sunxi_trip_data_2.trip_val[0] = ths_info.trip2_0; - sunxi_cooling_data_2.freq_clip_count = ths_info.trip2_count-1; - sunxi_cooling_data_2.freq_data[0].temp_level = ths_info.trip2_0; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone_1); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - - INIT_WORK(&thermal_data->irq_work, ths_irq_work_func); - thermal_wq = create_singlethread_workqueue("thermal_wq"); - if (!thermal_wq) { - printk(KERN_ALERT "Creat thermal_wq failed.\n"); - return -ENOMEM; - } - flush_workqueue(thermal_wq); - - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - &(thermal_data->ths_input_dev))) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - if (thermal_wq) - destroy_workqueue(thermal_wq); - sunxi_ths_reg_clear(); - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW7P1) -#define SUN8IW7_SID_CALIBRATION -#ifdef SUN8IW7_SID_CALIBRATION -#define SID_CAL_DATA (void __iomem *)(0xf1c14234) -#endif - -static struct workqueue_struct *thermal_wq; - -/****************************** thermal zone 1 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_1 = { - .trip_count = 3, - .trip_val[0] = 80, - .trip_val[1] = 100, - .trip_val[2] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_1 = { - .freq_data[0] = { - .freq_clip_min = 408000, - .freq_clip_max = 2016000, - .temp_level = 80, - }, - .freq_data[1] = { - .freq_clip_min = 60000, - .freq_clip_max = 408000, - .temp_level = 100, - }, - .freq_clip_count = 2, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 4, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2 = { - .trip_count = 1, - .trip_val[0] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - .temp_level = 110, - }, - .freq_clip_count = 1, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int temperature_to_reg(int temp_value, int multiplier, int minus) -{ - int64_t temp_reg; - - temp_reg = minus*1000 - multiplier*temp_value; - - do_div(temp_reg, 1000); - dprintk(DEBUG_INIT, "temp_reg=%lld \n", temp_reg); - - return (int)(temp_reg); -} - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static void ths_irq_work_func(struct work_struct *work) -{ - dprintk(DEBUG_DATA_INFO, "%s enter\n", __func__); - thermal_zone_device_update(ths_zone_2.therm_dev); - return; -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - unsigned long intsta; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(thermal_data); - - ths_clr_intsta(thermal_data); - - if (intsta & (THS_INTS_SHT0)){ - queue_work(thermal_wq, &thermal_data->irq_work); - } - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if ((556 < data->temp_data1[data->circle_num]) && (2000 > data->temp_data1[data->circle_num])) - data->circle_num++; - calc_temperature(1, 8253, 217, data); - - if (0 == data->circle_num) { - ths_write_data(0, data); - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(4, data); - data->thermal_data[5] = data->thermal_data[0]; - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_clk_cfg(void) -{ - - unsigned long rate = 0; /* 3Mhz */ - - ths_clk_source = clk_get(NULL, HOSC_CLK); - if (!ths_clk_source || IS_ERR(ths_clk_source)) { - printk(KERN_DEBUG "try to get ths_clk_source clock failed!\n"); - return; - } - - rate = clk_get_rate(ths_clk_source); - dprintk(DEBUG_INIT, "%s: get ths_clk_source rate %dHZ\n", __func__, (__u32)rate); - - ths_clk = clk_get(NULL, THS_CLK); - if (!ths_clk || IS_ERR(ths_clk)) { - printk(KERN_DEBUG "try to get ths clock failed!\n"); - return; - } - - if(clk_set_parent(ths_clk, ths_clk_source)) - printk("%s: set ths_clk parent to ir_clk_source failed!\n", __func__); - - if (clk_set_rate(ths_clk, 4000000)) { - printk(KERN_DEBUG "set ths clock freq to 4M failed!\n"); - } - - if (clk_prepare_enable(ths_clk)) { - printk(KERN_DEBUG "try to enable ths_clk failed!\n"); - } - - return; -} - -static void sunxi_ths_clk_uncfg(void) -{ - - if(NULL == ths_clk || IS_ERR(ths_clk)) { - printk("ths_clk handle is invalid, just return!\n"); - return; - } else { - clk_disable_unprepare(ths_clk); - clk_put(ths_clk); - ths_clk = NULL; - } - - if(NULL == ths_clk_source || IS_ERR(ths_clk_source)) { - printk("ths_clk_source handle is invalid, just return!\n"); - return; - } else { - clk_put(ths_clk_source); - ths_clk_source = NULL; - } - return; -} - -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL2_REG); -} - -static void sunxi_ths_reg_init(void) -{ - int reg_value; - -#ifdef SUN8IW7_SID_CALIBRATION - reg_value = readl(SID_CAL_DATA); - reg_value &= 0xfff; - if (0 != reg_value) - writel(reg_value, thermal_data->base_addr + THS_CDATA_REG); -#endif - writel(THS_CTRL0_VALUE, thermal_data->base_addr + THS_CTRL0_REG); - writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 8253, 1794); - reg_value = (reg_value<<16); - - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG); - writel(THS_CTRL2_VALUE, thermal_data->base_addr + THS_CTRL2_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL2_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); -} - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = ths_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = ths_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = ths_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = ths_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = ths_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = ths_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = ths_info.trip1_7; - - sunxi_cooling_data_1.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = ths_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = ths_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = ths_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = ths_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = ths_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = ths_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = ths_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = ths_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = ths_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = ths_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = ths_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = ths_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = ths_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = ths_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = ths_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = ths_info.trip1_6; - - sunxi_trip_data_2.trip_count = ths_info.trip2_count; - sunxi_trip_data_2.trip_val[0] = ths_info.trip2_0; - sunxi_cooling_data_2.freq_clip_count = ths_info.trip2_count-1; - sunxi_cooling_data_2.freq_data[0].temp_level = ths_info.trip2_0; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone_1); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - sunxi_ths_clk_cfg(); - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - - INIT_WORK(&thermal_data->irq_work, ths_irq_work_func); - thermal_wq = create_singlethread_workqueue("thermal_wq"); - if (!thermal_wq) { - printk(KERN_ALERT "Creat thermal_wq failed.\n"); - return -ENOMEM; - } - flush_workqueue(thermal_wq); - - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - &(thermal_data->ths_input_dev))) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - sunxi_ths_reg_clear(); - sunxi_ths_clk_uncfg(); - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN9IW1P1) - -#define SUN9I_SID_CALIBRATION -#ifdef SUN9I_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1c0e000) -#define SID_PRCTL (SID_BASE + 0x40) -#define SID_PRKEY (SID_BASE + 0x50) -#define SID_RDKEY (SID_BASE + 0x60) -#define SJTAG_AT0 (SID_BASE + 0x80) -#define SJTAG_AT1 (SID_BASE + 0x84) -#define SJTAG_S (SID_BASE + 0x88) - -#define SID_SRAM (SID_BASE + 0x200) -#define SID_OP_LOCK (0xAC) - -#define SID_THERMAL1 (0xf1c0e000 + 0x44) -#define SID_THERMAL2 (0xf1c0e000 + 0x48) - -#define SID_THERMAL1_SRAM (SID_SRAM + 0x44) -#define SID_THERMAL2_SRAM (SID_SRAM + 0x48) - -#endif - -/****************************** thermal zone 1 *************************************/ -static struct workqueue_struct *thermal_wq; - -static struct thermal_trip_point_conf sunxi_trip_data_1; - -static struct thermal_cooling_conf sunxi_cooling_data_1; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 4, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - }, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int temperature_to_reg(int temp_value, int multiplier, int minus) -{ - int64_t temp_reg; - - temp_reg = minus*1000 - multiplier*temp_value; - - do_div(temp_reg, 1000); - dprintk(DEBUG_INIT, "temp_reg=%lld \n", temp_reg); - - return (int)(temp_reg); -} - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static void ths_irq_work_func(struct work_struct *work) -{ - dprintk(DEBUG_DATA_INFO, "%s enter\n", __func__); - thermal_zone_device_update(ths_zone_1.therm_dev); - return; -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - unsigned long intsta; - unsigned long intreg; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(thermal_data); - intreg = readl(thermal_data->base_addr + THS_INT_CTRL_REG); - if (intsta & (THS_INTS_ALARM0|THS_INTS_ALARM1|THS_INTS_ALARM2|THS_INTS_ALARM3)) - intreg &=0xff0; - writel(intreg, thermal_data->base_addr + THS_INT_CTRL_REG); - - ths_clr_intsta(thermal_data); - - queue_work(thermal_wq, &thermal_data->irq_work); - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - int i = 0; - int temp; - uint64_t avg_temp = 0; - unsigned long intreg; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG0); - //dprintk(DEBUG_DATA_INFO, "THS data0 = %d\n", data->temp_data1[data->circle_num]); - data->temp_data2[data->circle_num] = readl(data->base_addr + THS_DATA_REG1); - //dprintk(DEBUG_DATA_INFO, "THS data1 = %d\n", data->temp_data2[data->circle_num]); - data->temp_data3[data->circle_num] = readl(data->base_addr + THS_DATA_REG2); - //dprintk(DEBUG_DATA_INFO, "THS data2 = %d\n", data->temp_data3[data->circle_num]); - data->temp_data4[data->circle_num] = readl(data->base_addr + THS_DATA_REG3); - //dprintk(DEBUG_DATA_INFO, "THS data3 = %d\n", data->temp_data4[data->circle_num]); - - if ((1000 < data->temp_data1[data->circle_num]) && (1000 < data->temp_data2[data->circle_num]) - && (1000 < data->temp_data3[data->circle_num]) - && (1000 < data->temp_data4[data->circle_num])) - data->circle_num++; - calc_temperature(4, 14543, 190, data); - - if ((data->thermal_data[0] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[1] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[2] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[3] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0])) { - intreg = readl(thermal_data->base_addr + THS_INT_CTRL_REG); - if (!(intreg & 0x00f)) { - intreg |=0x00f; - writel(intreg, thermal_data->base_addr + THS_INT_CTRL_REG); - } - } - - if (0 == data->circle_num) { - temp = data->thermal_data[0]; - for(i=0; i < 4; i++) { - if (temp < data->thermal_data[i]) - temp = data->thermal_data[i]; - ths_write_data(i, data); - avg_temp += data->thermal_data[i]; - } - data->thermal_data[4] = temp; - ths_write_data(4, data); - do_div(avg_temp, 4); - data->thermal_data[5] = (int)(avg_temp); - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_clk_cfg(void) -{ - - unsigned long rate = 0; /* 3Mhz */ - - gpadc_clk_source = clk_get(NULL, HOSC_CLK); - if (!gpadc_clk_source || IS_ERR(gpadc_clk_source)) { - printk(KERN_DEBUG "try to get ir_clk_source clock failed!\n"); - return; - } - - rate = clk_get_rate(gpadc_clk_source); - dprintk(DEBUG_INIT, "%s: get ir_clk_source rate %dHZ\n", __func__, (__u32)rate); - - gpadc_clk = clk_get(NULL, GPADC_CLK); - if (!gpadc_clk || IS_ERR(gpadc_clk)) { - printk(KERN_DEBUG "try to get ir clock failed!\n"); - return; - } - - if(clk_set_parent(gpadc_clk, gpadc_clk_source)) - printk("%s: set ir_clk parent to ir_clk_source failed!\n", __func__); - - if (clk_set_rate(gpadc_clk, 4000000)) { - printk(KERN_DEBUG "set ir clock freq to 3M failed!\n"); - } - - if (clk_prepare_enable(gpadc_clk)) { - printk(KERN_DEBUG "try to enable ir_clk failed!\n"); - } - - return; -} - -static void sunxi_ths_clk_uncfg(void) -{ - - if(NULL == gpadc_clk || IS_ERR(gpadc_clk)) { - printk("gpadc_clk handle is invalid, just return!\n"); - return; - } else { - clk_disable_unprepare(gpadc_clk); - clk_put(gpadc_clk); - gpadc_clk = NULL; - } - - if(NULL == gpadc_clk_source || IS_ERR(gpadc_clk_source)) { - printk("gpadc_clk_source handle is invalid, just return!\n"); - return; - } else { - clk_put(gpadc_clk_source); - gpadc_clk_source = NULL; - } - return; -} - -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ - int reg_value; - - writel(THS_CTRL_VALUE, thermal_data->base_addr + THS_CTRL_REG); - writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - reg_value = temperature_to_reg(ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14882, 2794); - - reg_value = (reg_value<<16); - reg_value |= 0xfff; - - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG0); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG1); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG2); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG3); - - reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14882, 2794); - - reg_value = (reg_value<<16); - reg_value |= 0xfff; - - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG0); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG1); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG2); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG3); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); - -#ifdef SUN9I_SID_CALIBRATION - reg_value = readl(SID_THERMAL1_SRAM); - if (reg_value != 0) - writel(reg_value, thermal_data->base_addr + THS_0_1_CDAT_REG); - reg_value = readl(SID_THERMAL2_SRAM); - if (reg_value != 0) - writel(reg_value, thermal_data->base_addr + THS_2_3_CDAT_REG); -#endif - dprintk(DEBUG_INIT, "THS_0_1_CDAT_REG = 0x%x\n", readl(thermal_data->base_addr + THS_0_1_CDAT_REG)); - dprintk(DEBUG_INIT, "THS_2_3_CDAT_REG = 0x%x\n", readl(thermal_data->base_addr + THS_2_3_CDAT_REG)); -} - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = ths_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = ths_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = ths_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = ths_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = ths_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = ths_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = ths_info.trip1_7; - - sunxi_cooling_data_1.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = ths_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = ths_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = ths_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = ths_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = ths_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = ths_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = ths_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = ths_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = ths_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = ths_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = ths_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = ths_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = ths_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = ths_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = ths_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = ths_info.trip1_6; - - sunxi_trip_data_2.trip_count = ths_info.trip2_count; - sunxi_trip_data_2.trip_val[0] = ths_info.trip2_0; - sunxi_cooling_data_2.freq_clip_count = ths_info.trip2_count-1; - sunxi_cooling_data_2.freq_data[0].temp_level = ths_info.trip2_0; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - ths_zone_1.sunxi_ths_sensor_conf->trend = ths_info.ths_trend; -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - err = sunxi_ths_register_thermal_dynamic(&ths_zone_1); -#else - err = sunxi_ths_register_thermal(&ths_zone_1); -#endif - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - sunxi_ths_clk_cfg(); - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - - INIT_WORK(&thermal_data->irq_work, ths_irq_work_func); - thermal_wq = create_singlethread_workqueue("thermal_wq"); - if (!thermal_wq) { - printk(KERN_ALERT "Creat thermal_wq failed.\n"); - return -ENOMEM; - } - flush_workqueue(thermal_wq); - - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - thermal_data->ths_input_dev)) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone_1); -#else - sunxi_ths_unregister_thermal(&ths_zone_1); -#endif -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - if (thermal_wq) - destroy_workqueue(thermal_wq); - sunxi_ths_reg_clear(); - sunxi_ths_clk_uncfg(); - sunxi_ths_unregister_thermal(&ths_zone_2); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone_1); -#else - sunxi_ths_unregister_thermal(&ths_zone_1); -#endif - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} -#endif - -late_initcall(sunxi_ths_init); -module_exit(sunxi_ths_exit); -module_param_named(debug_mask, debug_mask, int, 0644); -MODULE_DESCRIPTION("thermal seneor driver"); -MODULE_AUTHOR("Li Ming "); -MODULE_LICENSE("GPL"); - diff --git a/linux-3.4/drivers/thermal.new/sunxi-temperature.c.orig b/linux-3.4/drivers/thermal.new/sunxi-temperature.c.orig deleted file mode 100755 index 9d051e8b..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-temperature.c.orig +++ /dev/null @@ -1,1706 +0,0 @@ -/* - * drivers/thermal/sunxi-temperature.c - * - * Copyright (C) 2013-2014 allwinner. - * Li Ming - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_ARCH_SUN9IW1P1 -#include -#endif -#ifdef CONFIG_PM -#include -#endif -#include "sunxi-thermal.h" -#include "sunxi-temperature.h" - -#ifdef CONFIG_SUNXI_BUDGET_COOLING - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-budget-0" -#else - #define SUNXI_THERMAL_COOLING_DEVICE_NAMER "thermal-cpufreq-0" -#endif -static u32 debug_mask = 0x0; -#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \ - printk(fmt , ## arg) - -struct sunxi_ths_data { - void __iomem *base_addr; - int circle_num; - int temp_data1[10]; - int temp_data2[10]; - int temp_data3[10]; - int temp_data4[10]; - int thermal_data[6]; - atomic_t delay; - struct delayed_work work; - struct work_struct irq_work; - - int irq_used; - - struct input_dev *ths_input_dev; - atomic_t input_delay; - atomic_t input_enable; - struct delayed_work input_work; - struct mutex input_enable_mutex; - -#ifdef CONFIG_PM -struct dev_pm_domain ths_pm_domain; -#endif -}; -static struct sunxi_ths_data *thermal_data; -static int temperature[6] = {5, 5, 5, 5, 5, 5}; -static DEFINE_SPINLOCK(data_lock); -static struct ths_config_info ths_info = { - .input_type = THS_TYPE, -}; - -static void sunxi_ths_reg_clear(void); -static void sunxi_ths_reg_init(void); - -#ifdef CONFIG_ARCH_SUN9IW1P1 -static void sunxi_ths_clk_cfg(void); -static struct clk *gpadc_clk; -static struct clk *gpadc_clk_source; -#endif - -/********************************** input *****************************************/ - -static ssize_t sunxi_ths_input_delay_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - dprintk(DEBUG_CONTROL_INFO, "%d, %s\n", atomic_read(&thermal_data->input_delay), __FUNCTION__); - return sprintf(buf, "%d\n", atomic_read(&thermal_data->input_delay)); - -} - -static ssize_t sunxi_ths_input_delay_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if (data > THERMAL_DATA_DELAY) - data = THERMAL_DATA_DELAY; - atomic_set(&thermal_data->input_delay, (unsigned int) data); - - return count; -} - - -static ssize_t sunxi_ths_input_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - dprintk(DEBUG_CONTROL_INFO, "%d, %s\n", atomic_read(&thermal_data->input_enable), __FUNCTION__); - return sprintf(buf, "%d\n", atomic_read(&thermal_data->input_enable)); -} - -static void sunxi_ths_input_set_enable(struct device *dev, int enable) -{ - int pre_enable = atomic_read(&thermal_data->input_enable); - - mutex_lock(&thermal_data->input_enable_mutex); - if (enable) { - if (pre_enable == 0) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - atomic_set(&thermal_data->input_enable, 1); - } - - } else { - if (pre_enable == 1) { - cancel_delayed_work_sync(&thermal_data->input_work); - atomic_set(&thermal_data->input_enable, 0); - } - } - mutex_unlock(&thermal_data->input_enable_mutex); -} - -static ssize_t sunxi_ths_input_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long data; - int error; - - error = strict_strtoul(buf, 10, &data); - if (error) - return error; - if ((data == 0)||(data==1)) { - sunxi_ths_input_set_enable(dev,data); - } - - return count; -} - -static ssize_t sunxi_ths_show_temp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t cnt = 0; - int i = 0; - printk("%s: enter \n", __func__); - - for (i=0; i<6; i++) { - cnt += sprintf(buf + cnt,"temperature[%d]:%d\n" , i, ths_read_data(i)); - } - - return cnt; -} - -static ssize_t sunxi_ths_set_temp(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int data1, data2; - unsigned long irqflags; - char *endp; - - cancel_delayed_work_sync(&thermal_data->work); - - data1 = simple_strtoul(buf, &endp, 10); - if (*endp != ' ') { - printk("%s: %d\n", __func__, __LINE__); - return -EINVAL; - } - buf = endp + 1; - - data2 = simple_strtoul(buf, &endp, 10); - - spin_lock_irqsave(&data_lock, irqflags); - temperature[data1] = data2; - spin_unlock_irqrestore(&data_lock, irqflags); - - printk("temperature[%d] = %d\n", data1, data2); - - return count; -} - - -static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_input_delay_show, sunxi_ths_input_delay_store); -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_input_enable_show, sunxi_ths_input_enable_store); -static DEVICE_ATTR(temperature, S_IRUGO|S_IWUSR|S_IWGRP, - sunxi_ths_show_temp, sunxi_ths_set_temp); - -static struct attribute *sunxi_ths_input_attributes[] = { - &dev_attr_delay.attr, - &dev_attr_enable.attr, - &dev_attr_temperature.attr, - NULL -}; - -static struct attribute_group sunxi_ths_input_attribute_group = { - .attrs = sunxi_ths_input_attributes -}; - -static void sunxi_ths_input_work_func(struct work_struct *work) -{ - static int tempetature = 5; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, input_work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->input_delay)); - - tempetature = ths_read_data(4); - input_report_abs(data->ths_input_dev, ABS_MISC, tempetature); - input_sync(data->ths_input_dev); - dprintk(DEBUG_DATA_INFO, "%s: temperature %d,\n", __func__, tempetature); - - schedule_delayed_work(&data->input_work, delay); -} - - -static int sunxi_ths_input_init(struct sunxi_ths_data *data) -{ - int err = 0; - - data->ths_input_dev = input_allocate_device(); - if (IS_ERR_OR_NULL(data->ths_input_dev)) { - printk(KERN_ERR "temp_dev: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - data->ths_input_dev->name = "sunxi-ths"; - data->ths_input_dev->phys = "sunxiths/input0"; - data->ths_input_dev->id.bustype = BUS_HOST; - data->ths_input_dev->id.vendor = 0x0001; - data->ths_input_dev->id.product = 0x0001; - data->ths_input_dev->id.version = 0x0100; - - input_set_capability(data->ths_input_dev, EV_ABS, ABS_MISC); - input_set_abs_params(data->ths_input_dev, ABS_MISC, -50, 180, 0, 0); - - err = input_register_device(data->ths_input_dev); - if (0 < err) { - pr_err("%s: could not register input device\n", __func__); - input_free_device(data->ths_input_dev); - goto fail2; - } - - INIT_DELAYED_WORK(&data->input_work, sunxi_ths_input_work_func); - - mutex_init(&data->input_enable_mutex); - atomic_set(&data->input_enable, 0); - atomic_set(&data->input_delay, THERMAL_DATA_DELAY); - - err = sysfs_create_group(&data->ths_input_dev->dev.kobj, - &sunxi_ths_input_attribute_group); - if (err < 0) - { - pr_err("%s: sysfs_create_group err\n", __func__); - goto fail3; - } - - return err; -fail3: - input_unregister_device(data->ths_input_dev); -fail2: - kfree(data->ths_input_dev); -fail1: - return err; - -} - -static void sunxi_ths_input_exit(struct sunxi_ths_data *data) -{ - sysfs_remove_group(&data->ths_input_dev->dev.kobj, &sunxi_ths_input_attribute_group); - input_unregister_device(data->ths_input_dev); -} - -/********************************** input end *****************************************/ - - -static void ths_write_data(int index, struct sunxi_ths_data *data) -{ - unsigned long irqflags; - - spin_lock_irqsave(&data_lock, irqflags); - temperature[index] = data->thermal_data[index]; - spin_unlock_irqrestore(&data_lock, irqflags); - - return; -} - -int ths_read_data(int index) -{ - unsigned long irqflags; - int data; - - spin_lock_irqsave(&data_lock, irqflags); - data = temperature[index]; - spin_unlock_irqrestore(&data_lock, irqflags); - - return data; -} - -static void calc_temperature(int value, int divisor, int minus, struct sunxi_ths_data *data) -{ - unsigned int i = 0; - int64_t avg_temp[4] = {0, 0, 0, 0}; - - if (data->circle_num % 5 || !data->circle_num) - return; - if (value > 0) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[0] += data->temp_data1[i]; - } - } - if (value > 1) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[1] += data->temp_data2[i]; - } - } - if (value > 2) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[2] += data->temp_data3[i]; - } - } - if (value > 3) { - for (i = 0; i < data->circle_num; i++) { - avg_temp[3] += data->temp_data4[i]; - } - } - - for (i = 0; i < value; i++) { - do_div(avg_temp[i], data->circle_num); - dprintk(DEBUG_DATA_INFO, "avg_temp_reg=%lld\n", avg_temp[i]); - -#if defined(CONFIG_ARCH_SUN9IW1P1) || defined(CONFIG_ARCH_SUN8IW6P1) - avg_temp[i] *= 1000; - if (0 != avg_temp[i]) - do_div(avg_temp[i], divisor); - - avg_temp[i]= minus-avg_temp[i]; -#else - avg_temp[i] *= 100; - if (0 != avg_temp[i]) - do_div(avg_temp[i], divisor); - - avg_temp[i] -= minus; -#endif - dprintk(DEBUG_DATA_INFO, "avg_temp=%lld C\n", avg_temp[i]); - - data->thermal_data[i] = avg_temp[i]; - } - - data->circle_num = 0; - return; -} - -#ifdef CONFIG_PM -static int sunxi_ths_suspend(struct device *dev) -{ - dprintk(DEBUG_SUSPEND, "%s: suspend\n", __func__); - if (NORMAL_STANDBY == standby_type) { - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - cancel_delayed_work_sync(&thermal_data->input_work); - } - mutex_unlock(&thermal_data->input_enable_mutex); - - if (thermal_data->irq_used) - disable_irq_nosync(THS_IRQNO); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - } else if (SUPER_STANDBY == standby_type) { - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - cancel_delayed_work_sync(&thermal_data->input_work); - } - mutex_unlock(&thermal_data->input_enable_mutex); - - if (thermal_data->irq_used) - disable_irq_nosync(THS_IRQNO); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - } -#ifdef CONFIG_ARCH_SUN9IW1P1 - clk_disable_unprepare(gpadc_clk); -#endif - return 0; -} - -static int sunxi_ths_resume(struct device *dev) -{ - dprintk(DEBUG_SUSPEND, "%s: resume\n", __func__); - -#ifdef CONFIG_ARCH_SUN9IW1P1 - clk_prepare_enable(gpadc_clk); -#endif - - if (NORMAL_STANDBY == standby_type) { - sunxi_ths_reg_init(); - if (thermal_data->irq_used) - enable_irq(THS_IRQNO); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - } - mutex_unlock(&thermal_data->input_enable_mutex); - } else if (SUPER_STANDBY == standby_type) { - sunxi_ths_reg_init(); - if (thermal_data->irq_used) - enable_irq(THS_IRQNO); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - mutex_lock(&thermal_data->input_enable_mutex); - if (atomic_read(&thermal_data->input_enable)==1) { - schedule_delayed_work(&thermal_data->input_work, - msecs_to_jiffies(atomic_read(&thermal_data->input_delay))); - } - mutex_unlock(&thermal_data->input_enable_mutex); - } - return 0; -} -#endif - -#ifdef CONFIG_ARCH_SUN8IW3P1 -static void sunxi_ths_work_func(struct work_struct *work) -{ - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if (1000 < data->temp_data1[data->circle_num]) - data->circle_num++; - calc_temperature(1, 625, 265, data); - - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(0, data); - ths_write_data(4, data); - - schedule_delayed_work(&data->work, delay); -} -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG1); - writel(0, thermal_data->base_addr + THS_PRO_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ - writel(THS_CTRL_REG0_VALUE, thermal_data->base_addr + THS_CTRL_REG0); - writel(THS_CTRL_REG1_VALUE, thermal_data->base_addr + THS_CTRL_REG1); - writel(THS_PRO_CTRL_REG_VALUE, thermal_data->base_addr + THS_PRO_CTRL_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG0 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG0)); - dprintk(DEBUG_INIT, "THS_CTRL_REG1 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG1)); - dprintk(DEBUG_INIT, "THS_PRO_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_PRO_CTRL_REG)); -} - -static struct thermal_trip_point_conf sunxi_trip_data; - -static struct thermal_cooling_conf sunxi_cooling_data; - -static struct thermal_sensor_conf sunxi_sensor_conf = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data, - .cooling_data = &sunxi_cooling_data, -}; - -static struct sunxi_thermal_zone ths_zone = { - .id = 0, - .name = "sunxi-therm", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf, -}; - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - pr_err("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data.trip_count = ths_info.trip1_count; - sunxi_trip_data.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data.trip_val[2] = ths_info.trip1_2; - - sunxi_cooling_data.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data.freq_data[1].temp_level = ths_info.trip1_1; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - pr_err("thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone); - if(err < 0) { - pr_err("therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - thermal_data->irq_used = 0; - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); - sunxi_ths_unregister_thermal(&ths_zone); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW5P1) - -#define SUN8IW5_SID_CALIBRATION -#ifdef SUN8IW5_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1C23800) -#define SID_THS (SID_BASE + 0X10) -static void ths_calibration(void) -{ - u32 reg_val; - reg_val = readl(SID_THS); - if(reg_val != 0) - { - writel(reg_val,thermal_data->base_addr + TEMP_CATA); - } -} -#endif - -static void sunxi_ths_work_func(struct work_struct *work) -{ - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - //dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if (1000 < data->temp_data1[data->circle_num]) - data->circle_num++; - calc_temperature(1, 618, 269, data); - - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(0, data); - ths_write_data(4, data); - - schedule_delayed_work(&data->work, delay); -} -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG1); - writel(0, thermal_data->base_addr + THS_PRO_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ -#ifdef SUN8IW5_SID_CALIBRATION - ths_calibration(); -#endif - writel(THS_CTRL_REG0_VALUE, thermal_data->base_addr + THS_CTRL_REG0); - writel(THS_CTRL_REG1_VALUE, thermal_data->base_addr + THS_CTRL_REG1); - writel(THS_PRO_CTRL_REG_VALUE, thermal_data->base_addr + THS_PRO_CTRL_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG0 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG0)); - dprintk(DEBUG_INIT, "THS_CTRL_REG1 = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG1)); - dprintk(DEBUG_INIT, "THS_PRO_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_PRO_CTRL_REG)); -} - -static struct thermal_trip_point_conf sunxi_trip_data; - -static struct thermal_cooling_conf sunxi_cooling_data; - -static struct thermal_sensor_conf sunxi_sensor_conf = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data, - .cooling_data = &sunxi_cooling_data, -}; - -static struct sunxi_thermal_zone ths_zone = { - .id = 0, - .name = "sunxi-therm", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf, -}; - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data.trip_count = ths_info.trip1_count; - sunxi_trip_data.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data.trip_val[2] = ths_info.trip1_2; - - sunxi_cooling_data.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data.freq_data[1].temp_level = ths_info.trip1_1; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - - ths_zone.sunxi_ths_sensor_conf->trend = ths_info.ths_trend; -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - err = sunxi_ths_register_thermal_dynamic(&ths_zone); -#else - err = sunxi_ths_register_thermal(&ths_zone); -#endif - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - thermal_data->irq_used = 0; - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - sunxi_ths_reg_clear(); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone); -#else - sunxi_ths_unregister_thermal(&ths_zone); -#endif - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW6P1) -#define SUN8IW6_SID_CALIBRATION -#ifdef SUN8IW6_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1c14000) - -#define SID_SRAM (SID_BASE + 0x200) - -#define SID_THERMAL_CDATA1 (0xf1c0e000 + 0x34) -#define SID_THERMAL_CDATA2 (0xf1c0e000 + 0x38) - -#define SID_THERMAL_CDATA1_SRAM (SID_SRAM + 0x34) -#define SID_THERMAL_CDATA2_SRAM (SID_SRAM + 0x38) - -#endif - - -static struct workqueue_struct *thermal_wq; - -/****************************** thermal zone 1 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_1 = { - .trip_count = 3, - .trip_val[0] = 80, - .trip_val[1] = 100, - .trip_val[2] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_1 = { - .freq_data[0] = { - .freq_clip_min = 408000, - .freq_clip_max = 2016000, - .temp_level = 80, - }, - .freq_data[1] = { - .freq_clip_min = 60000, - .freq_clip_max = 408000, - .temp_level = 100, - }, - .freq_clip_count = 2, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 4, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2 = { - .trip_count = 1, - .trip_val[0] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - .temp_level = 110, - }, - .freq_clip_count = 1, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int temperature_to_reg(int temp_value, int multiplier, int minus) -{ - int64_t temp_reg; - - temp_reg = minus*1000 - multiplier*temp_value; - - do_div(temp_reg, 1000); - dprintk(DEBUG_INIT, "temp_reg=%lld \n", temp_reg); - - return (int)(temp_reg); -} - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static void ths_irq_work_func(struct work_struct *work) -{ - dprintk(DEBUG_DATA_INFO, "%s enter\n", __func__); - thermal_zone_device_update(ths_zone_2.therm_dev); - return; -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - struct sunxi_ths_data *data = container_of(dev_id, - struct sunxi_ths_data, ths_input_dev); - unsigned long intsta; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(data); - - ths_clr_intsta(data); - - if (intsta & (THS_INTS_SHT0|THS_INTS_SHT1|THS_INTS_SHT2)){ - queue_work(thermal_wq, &thermal_data->irq_work); - } - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - int i = 0; - int temp; - uint64_t avg_temp = 0; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG0); - dprintk(DEBUG_DATA_INFO, "THS data0 = %d\n", data->temp_data1[data->circle_num]); - data->temp_data2[data->circle_num] = readl(data->base_addr + THS_DATA_REG1); - dprintk(DEBUG_DATA_INFO, "THS data1 = %d\n", data->temp_data2[data->circle_num]); - data->temp_data3[data->circle_num] = readl(data->base_addr + THS_DATA_REG2); - dprintk(DEBUG_DATA_INFO, "THS data2 = %d\n", data->temp_data3[data->circle_num]); - - if ((1000 < data->temp_data1[data->circle_num]) && (1000 < data->temp_data2[data->circle_num]) - && (1000 < data->temp_data3[data->circle_num])) - data->circle_num++; - calc_temperature(3, 14186, 192, data); - - if (0 == data->circle_num) { - temp = data->thermal_data[0]; - for(i=0; i < 3; i++) { - if (temp < data->thermal_data[i]) - temp = data->thermal_data[i]; - ths_write_data(i, data); - avg_temp += data->thermal_data[i]; - } - data->thermal_data[4] = temp; - ths_write_data(4, data); - do_div(avg_temp, 3); - data->thermal_data[5] = (int)(avg_temp); - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL2_REG); -} - -static void sunxi_ths_reg_init(void) -{ - int reg_value; - -#ifdef SUN8IW6_SID_CALIBRATION - reg_value = readl(SID_THERMAL_CDATA1_SRAM); - if (0 != reg_value) - writel(reg_value, thermal_data->base_addr + THS_0_1_CDATA_REG); - reg_value = readl(SID_THERMAL_CDATA2_SRAM); - if (0 != reg_value) - writel(reg_value, thermal_data->base_addr + THS_2_CDATA_REG); -#endif - - writel(THS_CTRL0_VALUE, thermal_data->base_addr + THS_CTRL0_REG); - writel(THS_CTRL2_VALUE, thermal_data->base_addr + THS_CTRL2_REG); - writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14186, 2794); - reg_value = (reg_value<<16); - - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG0); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG1); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG2); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL2_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); -} - - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = ths_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = ths_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = ths_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = ths_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = ths_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = ths_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = ths_info.trip1_7; - - sunxi_cooling_data_1.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = ths_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = ths_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = ths_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = ths_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = ths_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = ths_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = ths_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = ths_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = ths_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = ths_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = ths_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = ths_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = ths_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = ths_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = ths_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = ths_info.trip1_6; - - sunxi_trip_data_2.trip_count = ths_info.trip2_count; - sunxi_trip_data_2.trip_val[0] = ths_info.trip2_0; - sunxi_cooling_data_2.freq_clip_count = ths_info.trip2_count-1; - sunxi_cooling_data_2.freq_data[0].temp_level = ths_info.trip2_0; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone_1); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - - INIT_WORK(&thermal_data->irq_work, ths_irq_work_func); - thermal_wq = create_singlethread_workqueue("thermal_wq"); - if (!thermal_wq) { - printk(KERN_ALERT "Creat thermal_wq failed.\n"); - return -ENOMEM; - } - flush_workqueue(thermal_wq); - - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - thermal_data->ths_input_dev)) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - if (thermal_wq) - destroy_workqueue(thermal_wq); - sunxi_ths_reg_clear(); - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN8IW7P1) - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - struct sunxi_ths_data *data = container_of(dev_id, - struct sunxi_ths_data, ths_input_dev); - unsigned long intsta; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(data); - - ths_clr_intsta(data); - - if (intsta & THS_INTS_SHT0) { - } - - if (intsta & THS_INTS_ALARM0) { - } - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - int i = 0; - int temp; - - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG); - dprintk(DEBUG_DATA_INFO, "THS data = %d\n", data->temp_data1[data->circle_num]); - - if ((1000 < data->temp_data1[data->circle_num]) && (1000 < data->temp_data2[data->circle_num]) - && (1000 < data->temp_data3[data->circle_num])) - data->circle_num++; - calc_temperature(1, 625, 267, data);///gai - - if (0 == data->circle_num) { - ths_write_data(1, data); - data->thermal_data[4] = data->thermal_data[0]; - ths_write_data(4, data); - data->thermal_data[5] = data->thermal_data[0]; - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL2_REG); -} - -static void sunxi_ths_reg_init(void) -{ - writel(THS_CTRL0_VALUE, thermal_data->base_addr + THS_CTRL0_REG); - writel(THS_CTRL2_VALUE, thermal_data->base_addr + THS_CTRL2_REG); - writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - writel(0, thermal_data->base_addr + THS_INT_ALM_TH_REG); - - writel(0, thermal_data->base_addr + THS_INT_SHUT_TH_REG); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL2_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); -} - -/****************************** thermal zone 1 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_1 = { - .trip_count = 3, - .trip_val[0] = 80, - .trip_val[1] = 100, - .trip_val[2] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_1 = { - .freq_data[0] = { - .freq_clip_min = 408000, - .freq_clip_max = 2016000, - .temp_level = 80, - }, - .freq_data[1] = { - .freq_clip_min = 60000, - .freq_clip_max = 408000, - .temp_level = 100, - }, - .freq_clip_count = 2, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 5, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2 = { - .trip_count = 1, - .trip_val[0] = 110, -}; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - .temp_level = 110, - }, - .freq_clip_count = 1, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - err = sunxi_ths_register_thermal(&ths_zone_1); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - thermal_data->ths_input_dev)) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - sunxi_ths_reg_clear(); - sunxi_ths_unregister_thermal(&ths_zone_2); - sunxi_ths_unregister_thermal(&ths_zone_1); - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} - -#elif defined(CONFIG_ARCH_SUN9IW1P1) - -#define SUN9I_SID_CALIBRATION -#ifdef SUN9I_SID_CALIBRATION -#define SID_BASE (void __iomem *)(0xf1c0e000) -#define SID_PRCTL (SID_BASE + 0x40) -#define SID_PRKEY (SID_BASE + 0x50) -#define SID_RDKEY (SID_BASE + 0x60) -#define SJTAG_AT0 (SID_BASE + 0x80) -#define SJTAG_AT1 (SID_BASE + 0x84) -#define SJTAG_S (SID_BASE + 0x88) - -#define SID_SRAM (SID_BASE + 0x200) -#define SID_OP_LOCK (0xAC) - -#define SID_THERMAL1 (0xf1c0e000 + 0x44) -#define SID_THERMAL2 (0xf1c0e000 + 0x48) - -#define SID_THERMAL1_SRAM (SID_SRAM + 0x44) -#define SID_THERMAL2_SRAM (SID_SRAM + 0x48) - -#endif - -/****************************** thermal zone 1 *************************************/ -static struct workqueue_struct *thermal_wq; - -static struct thermal_trip_point_conf sunxi_trip_data_1; - -static struct thermal_cooling_conf sunxi_cooling_data_1; - -static struct thermal_sensor_conf sunxi_sensor_conf_1 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_1, - .cooling_data = &sunxi_cooling_data_1, -}; - -static struct sunxi_thermal_zone ths_zone_1 = { - .id = 4, - .name = "sunxi-therm-1", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_1, -}; - -/**************************** thermal zone 1 end ***********************************/ - -/****************************** thermal zone 2 *************************************/ - -static struct thermal_trip_point_conf sunxi_trip_data_2; - -static struct thermal_cooling_conf sunxi_cooling_data_2 = { - .freq_data[0] = { - .freq_clip_min = 60000, - .freq_clip_max = 2016000, - }, -}; - -static struct thermal_sensor_conf sunxi_sensor_conf_2 = { - .name = SUNXI_THERMAL_COOLING_DEVICE_NAMER, - .read_temperature = ths_read_data, - .trip_data = &sunxi_trip_data_2, - .cooling_data = &sunxi_cooling_data_2, -}; - -static struct sunxi_thermal_zone ths_zone_2 = { - .id = 4, - .name = "sunxi-therm-2", - .sunxi_ths_sensor_conf = &sunxi_sensor_conf_2, -}; - -/**************************** thermal zone 2 end ***********************************/ - -static int temperature_to_reg(int temp_value, int multiplier, int minus) -{ - int64_t temp_reg; - - temp_reg = minus*1000 - multiplier*temp_value; - - do_div(temp_reg, 1000); - dprintk(DEBUG_INIT, "temp_reg=%lld \n", temp_reg); - - return (int)(temp_reg); -} - -static inline unsigned long ths_get_intsta(struct sunxi_ths_data *data) -{ - return (readl(data->base_addr + THS_INT_STA_REG)); -} - -static inline void ths_clr_intsta(struct sunxi_ths_data *data) -{ - writel(THS_CLEAR_INT_STA, data->base_addr + THS_INT_STA_REG); -} - -static void ths_irq_work_func(struct work_struct *work) -{ - dprintk(DEBUG_DATA_INFO, "%s enter\n", __func__); - thermal_zone_device_update(ths_zone_1.therm_dev); - return; -} - -static irqreturn_t ths_irq_service(int irqno, void *dev_id) -{ - unsigned long intsta; - unsigned long intreg; - dprintk(DEBUG_DATA_INFO, "THS IRQ Serve\n"); - - intsta = ths_get_intsta(thermal_data); - intreg = readl(thermal_data->base_addr + THS_INT_CTRL_REG); - if (intsta & (THS_INTS_ALARM0|THS_INTS_ALARM1|THS_INTS_ALARM2|THS_INTS_ALARM3)) - intreg &=0xff0; - writel(intreg, thermal_data->base_addr + THS_INT_CTRL_REG); - - ths_clr_intsta(thermal_data); - - queue_work(thermal_wq, &thermal_data->irq_work); - - return IRQ_HANDLED; -} - -static void sunxi_ths_work_func(struct work_struct *work) -{ - int i = 0; - int temp; - uint64_t avg_temp = 0; - unsigned long intreg; - struct sunxi_ths_data *data = container_of((struct delayed_work *)work, - struct sunxi_ths_data, work); - unsigned long delay = msecs_to_jiffies(atomic_read(&data->delay)); - - data->temp_data1[data->circle_num] = readl(data->base_addr + THS_DATA_REG0); - //dprintk(DEBUG_DATA_INFO, "THS data0 = %d\n", data->temp_data1[data->circle_num]); - data->temp_data2[data->circle_num] = readl(data->base_addr + THS_DATA_REG1); - //dprintk(DEBUG_DATA_INFO, "THS data1 = %d\n", data->temp_data2[data->circle_num]); - data->temp_data3[data->circle_num] = readl(data->base_addr + THS_DATA_REG2); - //dprintk(DEBUG_DATA_INFO, "THS data2 = %d\n", data->temp_data3[data->circle_num]); - data->temp_data4[data->circle_num] = readl(data->base_addr + THS_DATA_REG3); - //dprintk(DEBUG_DATA_INFO, "THS data3 = %d\n", data->temp_data4[data->circle_num]); - - if ((1000 < data->temp_data1[data->circle_num]) && (1000 < data->temp_data2[data->circle_num]) - && (1000 < data->temp_data3[data->circle_num]) - && (1000 < data->temp_data4[data->circle_num])) - data->circle_num++; - calc_temperature(4, 14543, 190, data); - - if ((data->thermal_data[0] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[1] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[2] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0]) || - (data->thermal_data[3] < ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0])) { - intreg = readl(thermal_data->base_addr + THS_INT_CTRL_REG); - if (!(intreg & 0x00f)) { - intreg |=0x00f; - writel(intreg, thermal_data->base_addr + THS_INT_CTRL_REG); - } - } - - if (0 == data->circle_num) { - temp = data->thermal_data[0]; - for(i=0; i < 4; i++) { - if (temp < data->thermal_data[i]) - temp = data->thermal_data[i]; - ths_write_data(i, data); - avg_temp += data->thermal_data[i]; - } - data->thermal_data[4] = temp; - ths_write_data(4, data); - do_div(avg_temp, 4); - data->thermal_data[5] = (int)(avg_temp); - ths_write_data(5, data); - } - - schedule_delayed_work(&data->work, delay); -} - -static void sunxi_ths_clk_cfg(void) -{ - - unsigned long rate = 0; /* 3Mhz */ - - gpadc_clk_source = clk_get(NULL, HOSC_CLK); - if (!gpadc_clk_source || IS_ERR(gpadc_clk_source)) { - printk(KERN_DEBUG "try to get ir_clk_source clock failed!\n"); - return; - } - - rate = clk_get_rate(gpadc_clk_source); - dprintk(DEBUG_INIT, "%s: get ir_clk_source rate %dHZ\n", __func__, (__u32)rate); - - gpadc_clk = clk_get(NULL, GPADC_CLK); - if (!gpadc_clk || IS_ERR(gpadc_clk)) { - printk(KERN_DEBUG "try to get ir clock failed!\n"); - return; - } - - if(clk_set_parent(gpadc_clk, gpadc_clk_source)) - printk("%s: set ir_clk parent to ir_clk_source failed!\n", __func__); - - if (clk_set_rate(gpadc_clk, 4000000)) { - printk(KERN_DEBUG "set ir clock freq to 3M failed!\n"); - } - - if (clk_prepare_enable(gpadc_clk)) { - printk(KERN_DEBUG "try to enable ir_clk failed!\n"); - } - - return; -} - -static void sunxi_ths_clk_uncfg(void) -{ - - if(NULL == gpadc_clk || IS_ERR(gpadc_clk)) { - printk("gpadc_clk handle is invalid, just return!\n"); - return; - } else { - clk_disable_unprepare(gpadc_clk); - clk_put(gpadc_clk); - gpadc_clk = NULL; - } - - if(NULL == gpadc_clk_source || IS_ERR(gpadc_clk_source)) { - printk("gpadc_clk_source handle is invalid, just return!\n"); - return; - } else { - clk_put(gpadc_clk_source); - gpadc_clk_source = NULL; - } - return; -} - -static void sunxi_ths_reg_clear(void) -{ - writel(0, thermal_data->base_addr + THS_CTRL_REG); -} - -static void sunxi_ths_reg_init(void) -{ - int reg_value; - - writel(THS_CTRL_VALUE, thermal_data->base_addr + THS_CTRL_REG); - writel(THS_INT_CTRL_VALUE, thermal_data->base_addr + THS_INT_CTRL_REG); - writel(THS_CLEAR_INT_STA, thermal_data->base_addr + THS_INT_STA_REG); - writel(THS_FILT_CTRL_VALUE, thermal_data->base_addr + THS_FILT_CTRL_REG); - - reg_value = temperature_to_reg(ths_zone_1.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14882, 2794); - - reg_value = (reg_value<<16); - reg_value |= 0xfff; - - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG0); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG1); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG2); - writel(reg_value, thermal_data->base_addr + THS_INT_ALM_TH_REG3); - - reg_value = temperature_to_reg(ths_zone_2.sunxi_ths_sensor_conf->trip_data->trip_val[0], 14882, 2794); - - reg_value = (reg_value<<16); - reg_value |= 0xfff; - - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG0); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG1); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG2); - writel(reg_value, thermal_data->base_addr + THS_INT_SHUT_TH_REG3); - - dprintk(DEBUG_INIT, "THS_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_CTRL_REG)); - dprintk(DEBUG_INIT, "THS_INT_STA_REG = 0x%x\n", readl(thermal_data->base_addr + THS_INT_STA_REG)); - dprintk(DEBUG_INIT, "THS_FILT_CTRL_REG = 0x%x\n", readl(thermal_data->base_addr + THS_FILT_CTRL_REG)); - -#ifdef SUN9I_SID_CALIBRATION - reg_value = readl(SID_THERMAL1_SRAM); - if (reg_value != 0) - writel(reg_value, thermal_data->base_addr + THS_0_1_CDAT_REG); - reg_value = readl(SID_THERMAL2_SRAM); - if (reg_value != 0) - writel(reg_value, thermal_data->base_addr + THS_2_3_CDAT_REG); -#endif - dprintk(DEBUG_INIT, "THS_0_1_CDAT_REG = 0x%x\n", readl(thermal_data->base_addr + THS_0_1_CDAT_REG)); - dprintk(DEBUG_INIT, "THS_2_3_CDAT_REG = 0x%x\n", readl(thermal_data->base_addr + THS_2_3_CDAT_REG)); -} - -static int __init sunxi_ths_init(void) -{ - int err = 0; - - dprintk(DEBUG_INIT, "%s: enter!\n", __func__); - - if (input_fetch_sysconfig_para(&(ths_info.input_type))) { - printk("%s: err.\n", __func__); - return -EPERM; - } - - sunxi_trip_data_1.trip_count = ths_info.trip1_count; - sunxi_trip_data_1.trip_val[0] = ths_info.trip1_0; - sunxi_trip_data_1.trip_val[1] = ths_info.trip1_1; - sunxi_trip_data_1.trip_val[2] = ths_info.trip1_2; - sunxi_trip_data_1.trip_val[3] = ths_info.trip1_3; - sunxi_trip_data_1.trip_val[4] = ths_info.trip1_4; - sunxi_trip_data_1.trip_val[5] = ths_info.trip1_5; - sunxi_trip_data_1.trip_val[6] = ths_info.trip1_6; - sunxi_trip_data_1.trip_val[7] = ths_info.trip1_7; - - sunxi_cooling_data_1.freq_clip_count = ths_info.trip1_count-1; - sunxi_cooling_data_1.freq_data[0].freq_clip_min = ths_info.trip1_0_min; - sunxi_cooling_data_1.freq_data[0].freq_clip_max = ths_info.trip1_0_max; - sunxi_cooling_data_1.freq_data[0].temp_level = ths_info.trip1_0; - sunxi_cooling_data_1.freq_data[1].freq_clip_min = ths_info.trip1_1_min; - sunxi_cooling_data_1.freq_data[1].freq_clip_max = ths_info.trip1_1_max; - sunxi_cooling_data_1.freq_data[1].temp_level = ths_info.trip1_1; - sunxi_cooling_data_1.freq_data[2].freq_clip_min = ths_info.trip1_2_min; - sunxi_cooling_data_1.freq_data[2].freq_clip_max = ths_info.trip1_2_max; - sunxi_cooling_data_1.freq_data[2].temp_level = ths_info.trip1_2; - sunxi_cooling_data_1.freq_data[3].freq_clip_min = ths_info.trip1_3_min; - sunxi_cooling_data_1.freq_data[3].freq_clip_max = ths_info.trip1_3_max; - sunxi_cooling_data_1.freq_data[3].temp_level = ths_info.trip1_3; - sunxi_cooling_data_1.freq_data[4].freq_clip_min = ths_info.trip1_4_min; - sunxi_cooling_data_1.freq_data[4].freq_clip_max = ths_info.trip1_4_max; - sunxi_cooling_data_1.freq_data[4].temp_level = ths_info.trip1_4; - sunxi_cooling_data_1.freq_data[5].freq_clip_min = ths_info.trip1_5_min; - sunxi_cooling_data_1.freq_data[5].freq_clip_max = ths_info.trip1_5_max; - sunxi_cooling_data_1.freq_data[5].temp_level = ths_info.trip1_5; - sunxi_cooling_data_1.freq_data[6].freq_clip_min = ths_info.trip1_6_min; - sunxi_cooling_data_1.freq_data[6].freq_clip_max = ths_info.trip1_6_max; - sunxi_cooling_data_1.freq_data[6].temp_level = ths_info.trip1_6; - - sunxi_trip_data_2.trip_count = ths_info.trip2_count; - sunxi_trip_data_2.trip_val[0] = ths_info.trip2_0; - sunxi_cooling_data_2.freq_clip_count = ths_info.trip2_count-1; - sunxi_cooling_data_2.freq_data[0].temp_level = ths_info.trip2_0; - - thermal_data = kzalloc(sizeof(*thermal_data), GFP_KERNEL); - if (IS_ERR_OR_NULL(thermal_data)) { - printk(KERN_ERR "thermal_data: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; - } - - sunxi_ths_input_init(thermal_data); - ths_zone_1.sunxi_ths_sensor_conf->trend = ths_info.ths_trend; -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - err = sunxi_ths_register_thermal_dynamic(&ths_zone_1); -#else - err = sunxi_ths_register_thermal(&ths_zone_1); -#endif - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - err = sunxi_ths_register_thermal(&ths_zone_2); - if(err < 0) { - printk(KERN_ERR "therma: register thermal core failed\n"); - goto fail2; - } - - sunxi_ths_clk_cfg(); - - thermal_data->base_addr = (void __iomem *)THERMAL_BASSADDRESS; - sunxi_ths_reg_init(); - - INIT_WORK(&thermal_data->irq_work, ths_irq_work_func); - thermal_wq = create_singlethread_workqueue("thermal_wq"); - if (!thermal_wq) { - printk(KERN_ALERT "Creat thermal_wq failed.\n"); - return -ENOMEM; - } - flush_workqueue(thermal_wq); - - thermal_data->irq_used = 1; - if (request_irq(THS_IRQNO, ths_irq_service, 0, "Thermal", - thermal_data->ths_input_dev)) { - err = -EBUSY; - goto fail3; - } - -#ifdef CONFIG_PM - thermal_data->ths_pm_domain.ops.suspend = sunxi_ths_suspend; - thermal_data->ths_pm_domain.ops.resume = sunxi_ths_resume; - thermal_data->ths_input_dev->dev.pm_domain = &thermal_data->ths_pm_domain; -#endif - INIT_DELAYED_WORK(&thermal_data->work, sunxi_ths_work_func); - atomic_set(&thermal_data->delay, (unsigned int) THERMAL_DATA_DELAY); - schedule_delayed_work(&thermal_data->work, - msecs_to_jiffies(atomic_read(&thermal_data->delay))); - - dprintk(DEBUG_INIT, "%s: OK!\n", __func__); - - return 0; -fail3: - sunxi_ths_unregister_thermal(&ths_zone_2); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone_1); -#else - sunxi_ths_unregister_thermal(&ths_zone_1); -#endif -fail2: - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -fail1: - return err; -} - -static void __exit sunxi_ths_exit(void) -{ - cancel_delayed_work_sync(&thermal_data->input_work); - cancel_delayed_work_sync(&thermal_data->work); - free_irq(THS_IRQNO, thermal_data->ths_input_dev); - if (thermal_wq) - destroy_workqueue(thermal_wq); - sunxi_ths_reg_clear(); - sunxi_ths_clk_uncfg(); - sunxi_ths_unregister_thermal(&ths_zone_2); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC - sunxi_ths_unregister_thermal_dynamic(&ths_zone_1); -#else - sunxi_ths_unregister_thermal(&ths_zone_1); -#endif - sunxi_ths_input_exit(thermal_data); - kfree(thermal_data); -} -#endif - -late_initcall(sunxi_ths_init); -module_exit(sunxi_ths_exit); -module_param_named(debug_mask, debug_mask, int, 0644); -MODULE_DESCRIPTION("thermal seneor driver"); -MODULE_AUTHOR("Li Ming "); -MODULE_LICENSE("GPL"); - diff --git a/linux-3.4/drivers/thermal.new/sunxi-temperature.h b/linux-3.4/drivers/thermal.new/sunxi-temperature.h deleted file mode 100755 index c6078a1e..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-temperature.h +++ /dev/null @@ -1,195 +0,0 @@ -#ifndef _SUNXI_TEMPERATURE_H -#define _SUNXI_TEMPERATURE_H - -#define THERMAL_DATA_DELAY (100) - -#ifdef CONFIG_ARCH_SUN8IW3P1 -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL_REG0 (0x00) -#define THS_CTRL_REG1 (0x04) -#define THS_PRO_CTRL_REG (0x18) - -#define THS_CTRL_REG0_VALUE (0x00a300ff) -#define THS_CTRL_REG1_VALUE (0x120) -#define THS_PRO_CTRL_REG_VALUE (0x1005f) - -#define THS_DATA_REG (0x20) - -#define THS_IRQNO (0) - -#elif defined(CONFIG_ARCH_SUN8IW5P1) - -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL_REG0 (0x00) -#define THS_CTRL_REG1 (0x04) -#define THS_PRO_CTRL_REG (0x18) - -#define THS_CTRL_REG0_VALUE (0x002000ff) -#define THS_CTRL_REG1_VALUE (0x100) -#define THS_PRO_CTRL_REG_VALUE (0x1005f) - -#define THS_DATA_REG (0x20) -#define TEMP_CATA (0x40) - -#define THS_IRQNO (0) - -#elif defined(CONFIG_ARCH_SUN9IW1P1) - -#define THERMAL_BASSADDRESS (0xf6004C00) - -#define ADC_CTRL0_REG (0x00) -#define ADC_CTRL1_REG (0x04) -#define ADC_INT_CTRL_REG (0x08) -#define ADC_INT_STA_REG (0x0C) -#define ADC_DATA_REG (0x10) -#define ADC_CO_DATA_REG (0x14) -#define ADC_IO_CFG_REG (0x18) -#define ADC_IO_DATA_REG (0x20) - -#define ADC_CTRL0_VALUE (0x73fff) -#define ADC_CTRL1_VALUE (0x1000f) -#define ADC_INT_CTRL_VALUE (0x30f80) -#define ADC_IO_CFG_VALUE (0x2222) - -#define THS_CTRL_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG0 (0x50) -#define THS_INT_ALM_TH_REG1 (0x54) -#define THS_INT_ALM_TH_REG2 (0x58) -#define THS_INT_ALM_TH_REG3 (0x5C) -#define THS_INT_SHUT_TH_REG0 (0x60) -#define THS_INT_SHUT_TH_REG1 (0x64) -#define THS_INT_SHUT_TH_REG2 (0x68) -#define THS_INT_SHUT_TH_REG3 (0x6C) -#define THS_FILT_CTRL_REG (0x70) -#define THS_0_1_CDAT_REG (0x74) -#define THS_2_3_CDAT_REG (0x78) -#define THS_DATA_REG0 (0x80) -#define THS_DATA_REG1 (0x84) -#define THS_DATA_REG2 (0x88) -#define THS_DATA_REG3 (0x8C) -#define THS_INT_ALM_TH_VALUE0 (0x50) -#define THS_INT_ALM_TH_VALUE1 (0x54) -#define THS_INT_ALM_TH_VALUE2 (0x58) -#define THS_INT_ALM_TH_VALUE3 (0x5C) -#define THS_INT_SHUT_TH_VALUE0 (0x60) -#define THS_INT_SHUT_TH_VALUE1 (0x64) -#define THS_INT_SHUT_TH_VALUE2 (0x68) -#define THS_INT_SHUT_TH_VALUE3 (0x6C) - -#define THS_CTRL_VALUE (0x002f000f) -#define THS_INT_CTRL_VALUE (0x10ff) -#define THS_CLEAR_INT_STA (0xfff) -#define THS_FILT_CTRL_VALUE (0x05) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_DATA1 (0x200) -#define THS_INTS_DATA2 (0x400) -#define THS_INTS_DATA3 (0x800) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_SHT1 (0x020) -#define THS_INTS_SHT2 (0x040) -#define THS_INTS_SHT3 (0x080) -#define THS_INTS_ALARM0 (0x001) -#define THS_INTS_ALARM1 (0x002) -#define THS_INTS_ALARM2 (0x004) -#define THS_INTS_ALARM3 (0x008) - -#define THS_IRQNO (147) - -#elif defined(CONFIG_ARCH_SUN8IW6P1) - -#define THERMAL_BASSADDRESS (0xf1f04000) - -#define THS_CTRL0_REG (0x00) -#define THS_CTRL1_REG (0x04) -#define ADC_CDAT_REG (0x14) -#define THS_CTRL2_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG0 (0x50) -#define THS_INT_ALM_TH_REG1 (0x54) -#define THS_INT_ALM_TH_REG2 (0x58) -#define THS_INT_SHUT_TH_REG0 (0x60) -#define THS_INT_SHUT_TH_REG1 (0x64) -#define THS_INT_SHUT_TH_REG2 (0x68) -#define THS_FILT_CTRL_REG (0x70) -#define THS_0_1_CDATA_REG (0x74) -#define THS_2_CDATA_REG (0x78) -#define THS_DATA_REG0 (0x80) -#define THS_DATA_REG1 (0x84) -#define THS_DATA_REG2 (0x88) - -#define THS_INT_ALM_TH_VALUE0 (0x50) -#define THS_INT_ALM_TH_VALUE1 (0x54) -#define THS_INT_ALM_TH_VALUE2 (0x58) -#define THS_INT_SHUT_TH_VALUE0 (0x60) -#define THS_INT_SHUT_TH_VALUE1 (0x64) -#define THS_INT_SHUT_TH_VALUE2 (0x68) - -#define THS_CTRL0_VALUE (0x17) -#define THS_CTRL1_VALUE (0x1<<17) -#define THS_CTRL2_VALUE (0x00170007) -#define THS_INT_CTRL_VALUE (0x1070)//gai -#define THS_CLEAR_INT_STA (0x777) -#define THS_FILT_CTRL_VALUE (0x05) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_DATA1 (0x200) -#define THS_INTS_DATA2 (0x400) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_SHT1 (0x020) -#define THS_INTS_SHT2 (0x040) -#define THS_INTS_ALARM0 (0x001) -#define THS_INTS_ALARM1 (0x002) -#define THS_INTS_ALARM2 (0x004) - -#define THS_IRQNO (73) - -#elif defined(CONFIG_ARCH_SUN8IW7P1) - -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL0_REG (0x00) -#define THS_CTRL1_REG (0x04) -#define ADC_CDAT_REG (0x14) -#define THS_CTRL2_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG (0x50) -#define THS_INT_SHUT_TH_REG (0x60) -#define THS_FILT_CTRL_REG (0x70) -#define THS_CDATA_REG (0x74) -#define THS_DATA_REG (0x80) - -#define THS_INT_ALM_TH_VALUE (0x50) -#define THS_INT_SHUT_TH_VALUE (0x60) - -#define THS_CTRL0_VALUE (0x3f) -#define THS_CTRL1_VALUE (0x1<<17) -#define THS_CTRL2_VALUE (0x003f0001) -#define THS_INT_CTRL_VALUE (0x39010)///gai -#define THS_CLEAR_INT_STA (0x1111) -#define THS_FILT_CTRL_VALUE (0x06) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_ALARM0 (0x001) - -#define THS_IRQNO (63) - -#endif - -enum { - DEBUG_INIT = 1U << 0, - DEBUG_CONTROL_INFO = 1U << 1, - DEBUG_DATA_INFO = 1U << 2, - DEBUG_SUSPEND = 1U << 3, -}; - -extern int ths_read_data(int value); - -#endif /* _SUNXI_TEMPERATURE_H */ diff --git a/linux-3.4/drivers/thermal.new/sunxi-temperature.h.orig b/linux-3.4/drivers/thermal.new/sunxi-temperature.h.orig deleted file mode 100755 index a3e61dc4..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-temperature.h.orig +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef _SUNXI_TEMPERATURE_H -#define _SUNXI_TEMPERATURE_H - -#define THERMAL_DATA_DELAY (100) - -#ifdef CONFIG_ARCH_SUN8IW3P1 -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL_REG0 (0x00) -#define THS_CTRL_REG1 (0x04) -#define THS_PRO_CTRL_REG (0x18) - -#define THS_CTRL_REG0_VALUE (0x00a300ff) -#define THS_CTRL_REG1_VALUE (0x120) -#define THS_PRO_CTRL_REG_VALUE (0x1005f) - -#define THS_DATA_REG (0x20) - -#define THS_IRQNO (0) - -#elif defined(CONFIG_ARCH_SUN8IW5P1) - -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL_REG0 (0x00) -#define THS_CTRL_REG1 (0x04) -#define THS_PRO_CTRL_REG (0x18) - -#define THS_CTRL_REG0_VALUE (0x002000ff) -#define THS_CTRL_REG1_VALUE (0x100) -#define THS_PRO_CTRL_REG_VALUE (0x1005f) - -#define THS_DATA_REG (0x20) -#define TEMP_CATA (0x40) - -#define THS_IRQNO (0) - -#elif defined(CONFIG_ARCH_SUN9IW1P1) - -#define THERMAL_BASSADDRESS (0xf6004C00) - -#define ADC_CTRL0_REG (0x00) -#define ADC_CTRL1_REG (0x04) -#define ADC_INT_CTRL_REG (0x08) -#define ADC_INT_STA_REG (0x0C) -#define ADC_DATA_REG (0x10) -#define ADC_CO_DATA_REG (0x14) -#define ADC_IO_CFG_REG (0x18) -#define ADC_IO_DATA_REG (0x20) - -#define ADC_CTRL0_VALUE (0x73fff) -#define ADC_CTRL1_VALUE (0x1000f) -#define ADC_INT_CTRL_VALUE (0x30f80) -#define ADC_IO_CFG_VALUE (0x2222) - -#define THS_CTRL_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG0 (0x50) -#define THS_INT_ALM_TH_REG1 (0x54) -#define THS_INT_ALM_TH_REG2 (0x58) -#define THS_INT_ALM_TH_REG3 (0x5C) -#define THS_INT_SHUT_TH_REG0 (0x60) -#define THS_INT_SHUT_TH_REG1 (0x64) -#define THS_INT_SHUT_TH_REG2 (0x68) -#define THS_INT_SHUT_TH_REG3 (0x6C) -#define THS_FILT_CTRL_REG (0x70) -#define THS_0_1_CDAT_REG (0x74) -#define THS_2_3_CDAT_REG (0x78) -#define THS_DATA_REG0 (0x80) -#define THS_DATA_REG1 (0x84) -#define THS_DATA_REG2 (0x88) -#define THS_DATA_REG3 (0x8C) -#define THS_INT_ALM_TH_VALUE0 (0x50) -#define THS_INT_ALM_TH_VALUE1 (0x54) -#define THS_INT_ALM_TH_VALUE2 (0x58) -#define THS_INT_ALM_TH_VALUE3 (0x5C) -#define THS_INT_SHUT_TH_VALUE0 (0x60) -#define THS_INT_SHUT_TH_VALUE1 (0x64) -#define THS_INT_SHUT_TH_VALUE2 (0x68) -#define THS_INT_SHUT_TH_VALUE3 (0x6C) - -#define THS_CTRL_VALUE (0x002f000f) -#define THS_INT_CTRL_VALUE (0x10ff) -#define THS_CLEAR_INT_STA (0xfff) -#define THS_FILT_CTRL_VALUE (0x05) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_DATA1 (0x200) -#define THS_INTS_DATA2 (0x400) -#define THS_INTS_DATA3 (0x800) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_SHT1 (0x020) -#define THS_INTS_SHT2 (0x040) -#define THS_INTS_SHT3 (0x080) -#define THS_INTS_ALARM0 (0x001) -#define THS_INTS_ALARM1 (0x002) -#define THS_INTS_ALARM2 (0x004) -#define THS_INTS_ALARM3 (0x008) - -#define THS_IRQNO (147) - -#elif defined(CONFIG_ARCH_SUN8IW6P1) - -#define THERMAL_BASSADDRESS (0xf1f04000) - -#define THS_CTRL0_REG (0x00) -#define THS_CTRL1_REG (0x04) -#define ADC_CDAT_REG (0x14) -#define THS_CTRL2_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG0 (0x50) -#define THS_INT_ALM_TH_REG1 (0x54) -#define THS_INT_ALM_TH_REG2 (0x58) -#define THS_INT_SHUT_TH_REG0 (0x60) -#define THS_INT_SHUT_TH_REG1 (0x64) -#define THS_INT_SHUT_TH_REG2 (0x68) -#define THS_FILT_CTRL_REG (0x70) -#define THS_0_1_CDATA_REG (0x74) -#define THS_2_CDATA_REG (0x78) -#define THS_DATA_REG0 (0x80) -#define THS_DATA_REG1 (0x84) -#define THS_DATA_REG2 (0x88) - -#define THS_INT_ALM_TH_VALUE0 (0x50) -#define THS_INT_ALM_TH_VALUE1 (0x54) -#define THS_INT_ALM_TH_VALUE2 (0x58) -#define THS_INT_SHUT_TH_VALUE0 (0x60) -#define THS_INT_SHUT_TH_VALUE1 (0x64) -#define THS_INT_SHUT_TH_VALUE2 (0x68) - -#define THS_CTRL0_VALUE (0x17) -#define THS_CTRL2_VALUE (0x00170007) -#define THS_INT_CTRL_VALUE (0x1070)//gai -#define THS_CLEAR_INT_STA (0x777) -#define THS_FILT_CTRL_VALUE (0x05) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_DATA1 (0x200) -#define THS_INTS_DATA2 (0x400) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_SHT1 (0x020) -#define THS_INTS_SHT2 (0x040) -#define THS_INTS_ALARM0 (0x001) -#define THS_INTS_ALARM1 (0x002) -#define THS_INTS_ALARM2 (0x004) - -#define THS_IRQNO (73) - -#elif defined(CONFIG_ARCH_SUN8IW7P1) - -#define THERMAL_BASSADDRESS (0xf1c25000) - -#define THS_CTRL0_REG (0x00) -#define THS_CTRL1_REG (0x04) -#define ADC_CDAT_REG (0x14) -#define THS_CTRL2_REG (0x40) -#define THS_INT_CTRL_REG (0x44) -#define THS_INT_STA_REG (0x48) -#define THS_INT_ALM_TH_REG (0x50) -#define THS_INT_SHUT_TH_REG (0x60) -#define THS_FILT_CTRL_REG (0x70) -#define THS_CDATA_REG (0x74) -#define THS_DATA_REG (0x80) - -#define THS_INT_ALM_TH_VALUE (0x50) -#define THS_INT_SHUT_TH_VALUE (0x60) - -#define THS_CTRL0_VALUE (0x17) -#define THS_CTRL2_VALUE (0x00170001) -#define THS_INT_CTRL_VALUE (0x000)///gai -#define THS_CLEAR_INT_STA (0x1111) -#define THS_FILT_CTRL_VALUE (0x05) - -#define THS_INTS_DATA0 (0x100) -#define THS_INTS_SHT0 (0x010) -#define THS_INTS_ALARM0 (0x001) - -#define THS_IRQNO (63) - -#endif - -enum { - DEBUG_INIT = 1U << 0, - DEBUG_CONTROL_INFO = 1U << 1, - DEBUG_DATA_INFO = 1U << 2, - DEBUG_SUSPEND = 1U << 3, -}; - -extern int ths_read_data(int value); - -#endif /* _SUNXI_TEMPERATURE_H */ diff --git a/linux-3.4/drivers/thermal.new/sunxi-thermal-bind.c b/linux-3.4/drivers/thermal.new/sunxi-thermal-bind.c deleted file mode 100755 index ba0221cb..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-thermal-bind.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * drivers/thermal/sunxi-thermal-bind.c - * - * Copyright (C) 2013-2014 allwinner. - * Li Ming - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "sunxi-thermal.h" -#include -#define THERMAL_BIND_NODE_MAX 8 -#define MAX_BINDDEV 2 - -struct thermal_bind_nonde_t -{ - unsigned int temp; - unsigned int min; - unsigned int max; -}; -struct thermalbind_t -{ - unsigned int trip_count; - unsigned int trip_trend; - struct thermal_bind_nonde_t nodes[THERMAL_BIND_NODE_MAX]; - -}; -struct thermalbind_device -{ - struct sunxi_thermal_zone* zone; - unsigned int used; - struct thermalbind_t binddata; - struct miscdevice miscdev; - struct device_attribute devattr[2]; -}; -//////////////////////////////////////////////////////////////////// -static ssize_t thermaltrend_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret=0,total=0; - struct miscdevice* mdev = dev_get_drvdata(dev); - struct thermalbind_device* binddev = container_of(mdev, struct thermalbind_device, miscdev); - ret = sprintf(buf, "%d\n",binddev->zone->sunxi_ths_sensor_conf->trend); - buf += (ret >0?ret:0); - total += (ret >0?ret:0); - return total; -} -static ssize_t thermaltrend_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct miscdevice* mdev = dev_get_drvdata(dev); - struct thermalbind_device* binddev = container_of(mdev, struct thermalbind_device, miscdev); - - sscanf(buf,"%u\n",&binddev->binddata.trip_trend); - sunxi_ths_unregister_thermal(binddev->zone); - binddev->zone->sunxi_ths_sensor_conf->trend = binddev->binddata.trip_trend; - sunxi_ths_register_thermal(binddev->zone); - return count; -} - -static ssize_t thermalbind_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int i=0,ret=0,total=0; - struct miscdevice* mdev = dev_get_drvdata(dev); - struct thermalbind_device* binddev = container_of(mdev, struct thermalbind_device, miscdev); - - ret = sprintf(buf, "count %d",binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_count); - buf += (ret >0?ret:0); - total += (ret >0?ret:0); - for(i=0;izone->sunxi_ths_sensor_conf->trip_data->trip_count;i++) - { - if(i < binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_count -1) - ret = sprintf(buf, " trip%d %d %d %d",i, - binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_val[i], - binddev->zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_min, - binddev->zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_max); - else - ret = sprintf(buf, " trip%d %d %d %d\n",i, - binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_val[i],0,0); - buf += (ret >0?ret:0); - total += (ret >0?ret:0); - } - return total; -} -static ssize_t thermalbind_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int i=0; - struct miscdevice* mdev = dev_get_drvdata(dev); - struct thermalbind_device* binddev = container_of(mdev, struct thermalbind_device, miscdev); - - binddev->binddata.trip_count = 0; - sscanf(buf,"%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u\n", - &binddev->binddata.trip_count, - &binddev->binddata.nodes[0].temp, - &binddev->binddata.nodes[0].min, - &binddev->binddata.nodes[0].max, - &binddev->binddata.nodes[1].temp, - &binddev->binddata.nodes[1].min, - &binddev->binddata.nodes[1].max, - &binddev->binddata.nodes[2].temp, - &binddev->binddata.nodes[2].min, - &binddev->binddata.nodes[2].max, - &binddev->binddata.nodes[3].temp, - &binddev->binddata.nodes[3].min, - &binddev->binddata.nodes[3].max, - &binddev->binddata.nodes[4].temp, - &binddev->binddata.nodes[4].min, - &binddev->binddata.nodes[4].max, - &binddev->binddata.nodes[5].temp, - &binddev->binddata.nodes[5].min, - &binddev->binddata.nodes[5].max, - &binddev->binddata.nodes[6].temp, - &binddev->binddata.nodes[6].min, - &binddev->binddata.nodes[6].max, - &binddev->binddata.nodes[7].temp, - &binddev->binddata.nodes[7].min, - &binddev->binddata.nodes[7].max); - if(!binddev->binddata.trip_count ||binddev->binddata.trip_count >THERMAL_BIND_NODE_MAX) - return -1; - - sunxi_ths_unregister_thermal(binddev->zone); - binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_count = binddev->binddata.trip_count; - - for(i=0;ibinddata.trip_count;i++) - { - binddev->zone->sunxi_ths_sensor_conf->trip_data->trip_val[i]= binddev->binddata.nodes[i].temp; - if(i < binddev->binddata.trip_count -1) - { - binddev->zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_min = binddev->binddata.nodes[i].min; - binddev->zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_max = binddev->binddata.nodes[i].max; - binddev->zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].temp_level= binddev->binddata.nodes[i].temp; - } - } - sunxi_ths_register_thermal(binddev->zone); - return count; -} - -static struct thermalbind_device bindlist[]= -{ - {.zone = NULL, - .used = 0, - .miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "thermalbind0", - }, - .devattr ={ - { - .attr = { - .name = "bind", - .mode = 0644, - }, - .show = thermalbind_show, - .store= thermalbind_store, - }, - { - .attr = { - .name = "trend", - .mode = 0644, - }, - .show = thermaltrend_show, - .store= thermaltrend_store, - }, - }, - }, - {.zone = NULL, - .used = 0, - .miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "thermalbind1", - }, - .devattr ={ - { - .attr = { - .name = "bind", - .mode = 0644, - }, - .show = thermalbind_show, - .store= thermalbind_store, - }, - { - .attr = { - .name = "trend", - .mode = 0644, - }, - .show = thermaltrend_show, - .store= thermaltrend_store, - }, - }, - }, -}; -static unsigned int bindmax=sizeof(bindlist)/sizeof(struct thermalbind_device); - - -int sunxi_thermal_register_thermalbind(struct sunxi_thermal_zone *ths_zone) -{ - int i=0,ret=0; - - while (i < bindmax) - { - if(!bindlist[i].used) - break; - i++; - } - if(i >= bindmax) - return -1; - bindlist[i].zone = ths_zone; - bindlist[i].used = 1; - ret = misc_register(&bindlist[i].miscdev); - if(ret) { - pr_err("%s register sunxi debug register driver as misc device error\n", __func__); - goto exit; - } - ret=device_create_file(bindlist[i].miscdev.this_device, &bindlist[i].devattr[0]); - if(ret) - pr_err("%s sysfs_create_group error\n", __func__); - ret=device_create_file(bindlist[i].miscdev.this_device, &bindlist[i].devattr[1]); - if(ret) - pr_err("%s sysfs_create_group error\n", __func__); -exit: - return ret; -} -int sunxi_thermal_unregister_thermalbind(struct sunxi_thermal_zone *ths_zone) -{ - int i=0; - - while (i < bindmax) - { - if(bindlist[i].zone == ths_zone) - break; - i++; - } - if(i >= bindmax) - return -1; - misc_deregister(&(bindlist[i].miscdev)); - bindlist[i].used = 0; - device_remove_file(bindlist[i].miscdev.this_device, &bindlist[i].devattr[1]); - device_remove_file(bindlist[i].miscdev.this_device, &bindlist[i].devattr[0]); - return 0; -} -EXPORT_SYMBOL(sunxi_thermal_unregister_thermalbind); -EXPORT_SYMBOL(sunxi_thermal_register_thermalbind); diff --git a/linux-3.4/drivers/thermal.new/sunxi-thermal.c b/linux-3.4/drivers/thermal.new/sunxi-thermal.c deleted file mode 100755 index b2fa1d3b..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-thermal.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * drivers/thermal/sunxi-thermal.c - * - * Copyright (C) 2013-2014 allwinner. - * Li Ming - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include "sunxi-thermal.h" -#ifndef CONFIG_SUNXI_BUDGET_COOLING -static int sunxi_get_frequency_level(unsigned int cpu, unsigned int freq) -{ - int i = 0, ret = -EINVAL; - struct cpufreq_frequency_table *table = NULL; -#ifdef CONFIG_CPU_FREQ - table = cpufreq_frequency_get_table(cpu); -#endif - if (!table) - return ret; - - while (table[i].frequency != CPUFREQ_TABLE_END) { - if (table[i].frequency == CPUFREQ_ENTRY_INVALID) - continue; - if (table[i].frequency == freq) - return i; - i++; - } - return ret; -} -#endif - -/* Bind callback functions for thermal zone */ -static int sunxi_ths_bind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) -{ - int ret = 0, i; - unsigned long lower, upper; - unsigned long max_state = 0; - struct sunxi_thermal_zone *ths_zone = thermal->devdata; -#ifdef CONFIG_SUNXI_BUDGET_COOLING - int state_mismatch = 0; - unsigned int lowest,highest; -#endif - if (!strlen(ths_zone->sunxi_ths_sensor_conf->name)) - return -EINVAL; - - pr_debug("%s : %s", __func__, cdev->type); - - /* No matching cooling device */ - if (strcmp(ths_zone->sunxi_ths_sensor_conf->name, cdev->type) != 0) - return 0; - - lower = THERMAL_NO_LIMIT; - upper = THERMAL_NO_LIMIT; - cdev->ops->get_max_state(cdev, &max_state); -#ifdef CONFIG_SUNXI_BUDGET_COOLING - lowest = 0; - highest = 0; - for (i = 0; i < ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count; i++) { - if (ths_zone->sunxi_ths_sensor_conf->trip_data->trip_val[i] != - ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].temp_level) { - continue; - } - lower = ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_min; - upper = ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_max; - if(lower >max_state || upper> max_state) - { - state_mismatch =1; - if(upper >highest) - highest = upper; - } - } -#endif - /* Bind the thermal zone to the cpufreq cooling device */ - for (i = 0; i < ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count; i++) { - if (ths_zone->sunxi_ths_sensor_conf->trip_data->trip_val[i] != - ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].temp_level) { - continue; - } - -#ifndef CONFIG_SUNXI_BUDGET_COOLING - - lower = sunxi_get_frequency_level(0, - ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_max); - - lower = max_state - lower; - - upper = sunxi_get_frequency_level(0, - ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_min); - - upper = max_state - upper; - pr_debug("ths_zone trip = %d, lower = %ld, upper = %ld\n", - ths_zone->sunxi_ths_sensor_conf->trip_data->trip_val[i], - lower, upper); -#else - lower = ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_min; - upper = ths_zone->sunxi_ths_sensor_conf->cooling_data->freq_data[i].freq_clip_max; - if(state_mismatch) - { - - lower = ((max_state+1)*(lower-lowest))/(highest-lowest+1); - upper = ((max_state+1)*(upper-lowest))/(highest-lowest+1); - } - lower=(lower>max_state)?0:lower; - upper=(upper>max_state)?max_state:upper; - pr_debug("ths_zone trip = %d, adjust lower = %ld, upper = %ld\n", - ths_zone->sunxi_ths_sensor_conf->trip_data->trip_val[i], - lower, upper); -#endif - if (thermal_zone_bind_cooling_device(thermal, i, cdev, - upper, lower)) { - pr_err("error binding cdev inst %d\n", i); - ret = -EINVAL; - } - ths_zone->bind = true; - } - return ret; -} - -/* Unbind callback functions for thermal zone */ -static int sunxi_ths_unbind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) -{ - int ret = 0, i; - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - if (ths_zone->bind == false) - return 0; - - /* Unbind the thermal zone to the cpufreq cooling device */ - for (i = 0; i < ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count; i++) { - if (thermal_zone_unbind_cooling_device(thermal, i, - cdev)) { - pr_err("error unbinding cdev inst %d\n", i); - ret = -EINVAL; - } - ths_zone->bind = false; - } - return ret; -} - -/* Get trip type callback functions for thermal zone */ -static int sunxi_ths_get_trip_type(struct thermal_zone_device *thermal, int trip, - enum thermal_trip_type *type) -{ - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - if ((trip < 0) || (trip > ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count-1)) - return -EINVAL; - - if (trip == (ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count-1)) - *type = THERMAL_TRIP_CRITICAL; - else - *type = THERMAL_TRIP_ACTIVE; - return 0; -} - -/* Get trip temperature callback functions for thermal zone */ -static int sunxi_ths_get_trip_temp(struct thermal_zone_device *thermal, int trip, - unsigned long *temp) -{ - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - if ((trip < 0) || (trip > ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count-1)) - return -EINVAL; - - *temp = ths_zone->sunxi_ths_sensor_conf->trip_data->trip_val[trip]; - - return 0; -} - -/* Get critical temperature callback functions for thermal zone */ -static int sunxi_ths_get_crit_temp(struct thermal_zone_device *thermal, - unsigned long *temp) -{ - int ret; - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - ret = sunxi_ths_get_trip_temp(thermal, - (ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count-1), temp); - return ret; -} - -/* Get mode callback functions for thermal zone */ -static int sunxi_ths_get_mode(struct thermal_zone_device *thermal, - enum thermal_device_mode *mode) -{ - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - if (ths_zone) - *mode = ths_zone->mode; - return 0; -} - -/* Set mode callback functions for thermal zone */ -static int sunxi_ths_set_mode(struct thermal_zone_device *thermal, - enum thermal_device_mode mode) -{ - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - if (!ths_zone->therm_dev) { - pr_notice("thermal zone not registered\n"); - return 0; - } - - mutex_lock(&ths_zone->therm_dev->lock); - - if (mode == THERMAL_DEVICE_ENABLED) - ths_zone->therm_dev->polling_delay = IDLE_INTERVAL; - else - ths_zone->therm_dev->polling_delay = 0; - - mutex_unlock(&ths_zone->therm_dev->lock); - - ths_zone->mode = mode; - thermal_zone_device_update(ths_zone->therm_dev); - pr_debug("thermal polling set for duration=%d msec\n", - ths_zone->therm_dev->polling_delay); - return 0; -} - -static void sunxi_ths_update_trend_temp(struct sunxi_thermal_zone *ths_zone,unsigned long temp) -{ - ths_zone->ptrend->temp100[ths_zone->ptrend->index] = temp*100; - ths_zone->ptrend->index = (ths_zone->ptrend->index+1)%TREND_SAMPLE_MAX; - ths_zone->ptrend->cnt++; - ths_zone->ptrend->cnt=(ths_zone->ptrend->cnt >TREND_SAMPLE_MAX)?TREND_SAMPLE_MAX:ths_zone->ptrend->cnt; -} -static int sunxi_ths_get_trend_real(struct sunxi_thermal_zone *ths_zone,unsigned long temp, unsigned long limit, unsigned long pre, unsigned long next) -{ - int i,j; - int Y=0,X=0,XY=0,XX=0,M=ths_zone->ptrend->cnt; - for(i=0;iptrend->cnt;i++) - { - if(ths_zone->ptrend->cnt < TREND_SAMPLE_MAX) - j=i; - else - j = (i+ths_zone->ptrend->index)%TREND_SAMPLE_MAX; - Y+= ths_zone->ptrend->temp100[j]; - X += (i+1); - XY += ths_zone->ptrend->temp100[j]*(i+1); - XX += (i+1)*(i+1); - } - /*if sample data too little, return STABLE */ - if(ths_zone->ptrend->cnt < TREND_SAMPLE_MAX) - return THERMAL_TREND_STABLE; - /*Avoid div zero */ - if(!M || !((M* XX - X*X))) - return THERMAL_TREND_STABLE; - ths_zone->ptrend->a1 = (int)(M*XY - X*Y)/(M* XX - X*X); - ths_zone->ptrend->a0 = (int)(Y/M - ths_zone->ptrend->a1*X/M); - if (temp >= limit) - { - if(next && temp >=next && ths_zone->ptrend->a1 >0) - ths_zone->ptrend->trend = THERMAL_TREND_RAISE_FULL; - else - { - if(ths_zone->ptrend->a1 >1) - ths_zone->ptrend->trend = THERMAL_TREND_RAISING; - else if(ths_zone->ptrend->a1 >-1) - { - if (temp >= limit+2) - ths_zone->ptrend->trend = THERMAL_TREND_STABLE; - else - ths_zone->ptrend->trend = THERMAL_TREND_DROPPING; - } - else - ths_zone->ptrend->trend = THERMAL_TREND_STABLE; - } - } - else - { - if(pre && temp < pre && ths_zone->ptrend->a1 <0) - ths_zone->ptrend->trend = THERMAL_TREND_DROP_FULL; - else - { - if(ths_zone->ptrend->a1 >1) - ths_zone->ptrend->trend = THERMAL_TREND_RAISING; - else if(ths_zone->ptrend->a1 >-1) - ths_zone->ptrend->trend = THERMAL_TREND_DROPPING; - else - ths_zone->ptrend->trend = THERMAL_TREND_STABLE; - } - } - return ths_zone->ptrend->trend ; -} -/* Get temperature callback functions for thermal zone */ -static int sunxi_ths_get_temp(struct thermal_zone_device *thermal, - unsigned long *temp) -{ - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - *temp = (unsigned long)(ths_zone->sunxi_ths_sensor_conf->read_temperature(ths_zone->id)); - sunxi_ths_update_trend_temp(ths_zone,*temp); - return 0; -} - -/* Get the temperature trend */ -static int sunxi_ths_get_trend(struct thermal_zone_device *thermal, - int trip, enum thermal_trend *trend) -{ - int ret = 0; - unsigned long trip_temp,trip_next,trip_pre; - int simple_trend; - struct sunxi_thermal_zone *ths_zone = thermal->devdata; - - ret = sunxi_ths_get_trip_temp(thermal, trip, &trip_temp); - if(ret < 0) - return ret; - - if (thermal->temperature >= trip_temp) - simple_trend = THERMAL_TREND_RAISING; - else - simple_trend = THERMAL_TREND_DROPPING; - - ret = sunxi_ths_get_trip_temp(thermal, trip+1, &trip_next); - if(ret < 0) - trip_next = 0; - ret = sunxi_ths_get_trip_temp(thermal, trip+1, &trip_pre); - if(ret < 0) - trip_pre = 0; - if(!ths_zone->sunxi_ths_sensor_conf->trend) - *trend = simple_trend; - else - *trend = sunxi_ths_get_trend_real(ths_zone,thermal->temperature,trip_temp, trip_pre,trip_next); - - return 0; -} - -/* Operation callback functions for thermal zone */ -static struct thermal_zone_device_ops const sunxi_ths_dev_ops = { - .bind = sunxi_ths_bind, - .unbind = sunxi_ths_unbind, - .get_temp = sunxi_ths_get_temp, - .get_trend = sunxi_ths_get_trend, - .get_mode = sunxi_ths_get_mode, - .set_mode = sunxi_ths_set_mode, - .get_trip_type = sunxi_ths_get_trip_type, - .get_trip_temp = sunxi_ths_get_trip_temp, - .get_crit_temp = sunxi_ths_get_crit_temp, -}; - -/* Un-Register with the in-kernel thermal management */ -void sunxi_ths_unregister_thermal(struct sunxi_thermal_zone *ths_zone) -{ - if (!ths_zone) - return; - if (ths_zone->therm_dev) - thermal_zone_device_unregister(ths_zone->therm_dev); - if(ths_zone->ptrend) - { - kfree(ths_zone->ptrend); - ths_zone->ptrend = NULL; - } - pr_debug("suxi_ths: Kernel Thermal management unregistered\n"); -} -EXPORT_SYMBOL(sunxi_ths_unregister_thermal); -int sunxi_ths_register_thermal(struct sunxi_thermal_zone *ths_zone) -{ - int ret = 0; - ths_zone->ptrend = kzalloc(sizeof(struct sunxi_thermal_zone_trend_info),GFP_KERNEL); - ths_zone->therm_dev = thermal_zone_device_register(ths_zone->name, - ths_zone->sunxi_ths_sensor_conf->trip_data->trip_count, 0, ths_zone, &sunxi_ths_dev_ops, NULL, 0, - IDLE_INTERVAL); - - if (IS_ERR(ths_zone->therm_dev)) { - pr_err("Failed to register thermal zone device\n"); - ret = -EINVAL; - goto err_unregister; - } - ths_zone->mode = THERMAL_DEVICE_ENABLED; - - pr_debug("suxi_ths: Kernel Thermal management registered\n"); - return 0; - -err_unregister: - sunxi_ths_unregister_thermal(ths_zone); - return ret; -} -EXPORT_SYMBOL(sunxi_ths_register_thermal); - -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC -extern int sunxi_thermal_register_thermalbind(struct sunxi_thermal_zone *ths_zone); -extern int sunxi_thermal_unregister_thermalbind(struct sunxi_thermal_zone *ths_zone); -int sunxi_ths_register_thermal_dynamic(struct sunxi_thermal_zone *ths_zone) -{ - int ret = 0; - ret = sunxi_ths_register_thermal(ths_zone); - if(!ret) - sunxi_thermal_register_thermalbind(ths_zone); - return ret; -} -void sunxi_ths_unregister_thermal_dynamic(struct sunxi_thermal_zone *ths_zone) -{ - sunxi_thermal_unregister_thermalbind(ths_zone); - sunxi_ths_unregister_thermal(ths_zone); -} -EXPORT_SYMBOL(sunxi_ths_register_thermal_dynamic); -EXPORT_SYMBOL(sunxi_ths_unregister_thermal_dynamic); -#endif diff --git a/linux-3.4/drivers/thermal.new/sunxi-thermal.h b/linux-3.4/drivers/thermal.new/sunxi-thermal.h deleted file mode 100755 index 545db929..00000000 --- a/linux-3.4/drivers/thermal.new/sunxi-thermal.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _SUNXI_THERMAL_H -#define _SUNXI_THERMAL_H - -#define ACTIVE_INTERVAL (500) -#define IDLE_INTERVAL (500) -#define MAX_TRIP_COUNT (8) - -/** - * struct freq_clip_table - * @freq_clip_max: maximum frequency allowed for this cooling state. - * @temp_level: Temperature level at which the temperature clipping will - * happen. - * @mask_val: cpumask of the allowed cpu's where the clipping will take place. - * - * This structure is required to be filled and passed to the - * cpufreq_cooling_unregister function. - */ -struct freq_clip_table { - unsigned int freq_clip_max; - unsigned int freq_clip_min; - unsigned int temp_level; - const struct cpumask *mask_val; -}; - -struct thermal_trip_point_conf { - int trip_val[MAX_TRIP_COUNT]; - int trip_count; -}; - -struct thermal_cooling_conf { - struct freq_clip_table freq_data[MAX_TRIP_COUNT]; - int freq_clip_count; -}; - -struct thermal_sensor_conf { - char name[THERMAL_NAME_LENGTH]; - int (*read_temperature)(int index); - struct thermal_trip_point_conf *trip_data; - struct thermal_cooling_conf *cooling_data; - void *private_data; - int trend; -}; -#define TREND_SAMPLE_MAX 8 -struct sunxi_thermal_zone_trend_info -{ - unsigned short temp100[TREND_SAMPLE_MAX]; - unsigned int cnt; - unsigned int index; - int a0; - int a1; - int trend; -}; - -struct sunxi_thermal_zone { - int id; - char name[THERMAL_NAME_LENGTH]; - struct thermal_sensor_conf *sunxi_ths_sensor_conf; - enum thermal_device_mode mode; - struct thermal_zone_device *therm_dev; - bool bind; - struct sunxi_thermal_zone_trend_info* ptrend; -}; - -extern int sunxi_ths_register_thermal(struct sunxi_thermal_zone *ths_zone); -extern void sunxi_ths_unregister_thermal(struct sunxi_thermal_zone *ths_zone); -#ifdef CONFIG_SUNXI_THERMAL_DYNAMIC -extern int sunxi_ths_register_thermal_dynamic(struct sunxi_thermal_zone *ths_zone); -extern void sunxi_ths_unregister_thermal_dynamic(struct sunxi_thermal_zone *ths_zone); -extern int sunxi_thermal_register_thermalbind(struct sunxi_thermal_zone *ths_zone); -extern int sunxi_thermal_unregister_thermalbind(struct sunxi_thermal_zone *ths_zone); -#endif - -#endif /* _SUNXI_THERMAL_H */ diff --git a/linux-3.4/drivers/thermal.new/thermal_core.h b/linux-3.4/drivers/thermal.new/thermal_core.h deleted file mode 100755 index 0d3205a1..00000000 --- a/linux-3.4/drivers/thermal.new/thermal_core.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * thermal_core.h - * - * Copyright (C) 2012 Intel Corp - * Author: Durgadoss R - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef __THERMAL_CORE_H__ -#define __THERMAL_CORE_H__ - -#include -#include - -/* Initial state of a cooling device during binding */ -#define THERMAL_NO_TARGET -1UL - -/* - * This structure is used to describe the behavior of - * a certain cooling device on a certain trip point - * in a certain thermal zone - */ -struct thermal_instance { - int id; - char name[THERMAL_NAME_LENGTH]; - struct thermal_zone_device *tz; - struct thermal_cooling_device *cdev; - int trip; - unsigned long upper; /* Highest cooling state for this trip point */ - unsigned long lower; /* Lowest cooling state for this trip point */ - unsigned long target; /* expected cooling state */ - char attr_name[THERMAL_NAME_LENGTH]; - struct device_attribute attr; - struct list_head tz_node; /* node in tz->thermal_instances */ - struct list_head cdev_node; /* node in cdev->thermal_instances */ -}; - -#endif /* __THERMAL_CORE_H__ */ diff --git a/linux-3.4/drivers/thermal.new/thermal_sys.c b/linux-3.4/drivers/thermal.new/thermal_sys.c deleted file mode 100755 index 0e1fa39c..00000000 --- a/linux-3.4/drivers/thermal.new/thermal_sys.c +++ /dev/null @@ -1,1830 +0,0 @@ -/* - * thermal.c - Generic Thermal Management Sysfs support. - * - * Copyright (C) 2008 Intel Corp - * Copyright (C) 2008 Zhang Rui - * Copyright (C) 2008 Sujith Thomas - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define CREATE_TRACE_POINTS -#include -#include "thermal_core.h" - -MODULE_AUTHOR("Zhang Rui"); -MODULE_DESCRIPTION("Generic thermal management sysfs support"); -MODULE_LICENSE("GPL"); - -static DEFINE_IDR(thermal_tz_idr); -static DEFINE_IDR(thermal_cdev_idr); -static DEFINE_MUTEX(thermal_idr_lock); - -static LIST_HEAD(thermal_tz_list); -static LIST_HEAD(thermal_cdev_list); -static LIST_HEAD(thermal_governor_list); - -static DEFINE_MUTEX(thermal_list_lock); -static DEFINE_MUTEX(thermal_governor_lock); - -static struct thermal_governor *__find_governor(const char *name) -{ - struct thermal_governor *pos; - - list_for_each_entry(pos, &thermal_governor_list, governor_list) - if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) - return pos; - - return NULL; -} - -int thermal_register_governor(struct thermal_governor *governor) -{ - int err; - const char *name; - struct thermal_zone_device *pos; - - if (!governor) - return -EINVAL; - - mutex_lock(&thermal_governor_lock); - - err = -EBUSY; - if (__find_governor(governor->name) == NULL) { - err = 0; - list_add(&governor->governor_list, &thermal_governor_list); - } - - mutex_lock(&thermal_list_lock); - - list_for_each_entry(pos, &thermal_tz_list, node) { - if (pos->governor) - continue; - if (pos->tzp) - name = pos->tzp->governor_name; - else - name = DEFAULT_THERMAL_GOVERNOR; - if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) - pos->governor = governor; - } - - mutex_unlock(&thermal_list_lock); - mutex_unlock(&thermal_governor_lock); - - return err; -} -EXPORT_SYMBOL_GPL(thermal_register_governor); - -void thermal_unregister_governor(struct thermal_governor *governor) -{ - struct thermal_zone_device *pos; - - if (!governor) - return; - - mutex_lock(&thermal_governor_lock); - - if (__find_governor(governor->name) == NULL) - goto exit; - - mutex_lock(&thermal_list_lock); - - list_for_each_entry(pos, &thermal_tz_list, node) { - if (!strnicmp(pos->governor->name, governor->name, - THERMAL_NAME_LENGTH)) - pos->governor = NULL; - } - - mutex_unlock(&thermal_list_lock); - list_del(&governor->governor_list); -exit: - mutex_unlock(&thermal_governor_lock); - return; -} -EXPORT_SYMBOL_GPL(thermal_unregister_governor); - -static int get_idr(struct idr *idr, struct mutex *lock, int *id) -{ - int err; - -again: - if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) - return -ENOMEM; - - if (lock) - mutex_lock(lock); - err = idr_get_new(idr, NULL, id); - if (lock) - mutex_unlock(lock); - if (unlikely(err == -EAGAIN)) - goto again; - else if (unlikely(err)) - return err; - - *id = *id & MAX_ID_MASK; - return 0; -} - -static void release_idr(struct idr *idr, struct mutex *lock, int id) -{ - if (lock) - mutex_lock(lock); - idr_remove(idr, id); - if (lock) - mutex_unlock(lock); -} - -int get_tz_trend(struct thermal_zone_device *tz, int trip) -{ - enum thermal_trend trend; - - if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) { - if (tz->temperature > tz->last_temperature) - trend = THERMAL_TREND_RAISING; - else if (tz->temperature < tz->last_temperature) - trend = THERMAL_TREND_DROPPING; - else - trend = THERMAL_TREND_STABLE; - } - trace_get_tz_trend(tz->id,trend); - return trend; -} -EXPORT_SYMBOL(get_tz_trend); - -struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz, - struct thermal_cooling_device *cdev, int trip) -{ - struct thermal_instance *pos = NULL; - struct thermal_instance *target_instance = NULL; - - mutex_lock(&tz->lock); - mutex_lock(&cdev->lock); - - list_for_each_entry(pos, &tz->thermal_instances, tz_node) { - if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { - target_instance = pos; - break; - } - } - - mutex_unlock(&cdev->lock); - mutex_unlock(&tz->lock); - - return target_instance; -} -EXPORT_SYMBOL(get_thermal_instance); - -static void print_bind_err_msg(struct thermal_zone_device *tz, - struct thermal_cooling_device *cdev, int ret) -{ - dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n", - tz->type, cdev->type, ret); -} - -static void __bind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev) -{ - int i, ret; - - for (i = 0; i < tz->trips; i++) { - if (mask & (1 << i)) { - ret = thermal_zone_bind_cooling_device(tz, i, cdev, - THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); - if (ret) - print_bind_err_msg(tz, cdev, ret); - } - } -} - -static void __unbind(struct thermal_zone_device *tz, int mask, - struct thermal_cooling_device *cdev) -{ - int i; - - for (i = 0; i < tz->trips; i++) - if (mask & (1 << i)) - thermal_zone_unbind_cooling_device(tz, i, cdev); -} - -static void bind_cdev(struct thermal_cooling_device *cdev) -{ - int i, ret; - const struct thermal_zone_params *tzp; - struct thermal_zone_device *pos = NULL; - - mutex_lock(&thermal_list_lock); - - list_for_each_entry(pos, &thermal_tz_list, node) { - if (!pos->tzp && !pos->ops->bind) - continue; - - if (!pos->tzp && pos->ops->bind) { - ret = pos->ops->bind(pos, cdev); - if (ret) - print_bind_err_msg(pos, cdev, ret); - } - - tzp = pos->tzp; - if (!tzp || !tzp->tbp) - continue; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(pos, cdev)) - continue; - tzp->tbp[i].cdev = cdev; - __bind(pos, tzp->tbp[i].trip_mask, cdev); - } - } - - mutex_unlock(&thermal_list_lock); -} - -static void bind_tz(struct thermal_zone_device *tz) -{ - int i, ret; - struct thermal_cooling_device *pos = NULL; - const struct thermal_zone_params *tzp = tz->tzp; - - if (!tzp && !tz->ops->bind) - return; - - mutex_lock(&thermal_list_lock); - - /* If there is no platform data, try to use ops->bind */ - if (!tzp && tz->ops->bind) { - list_for_each_entry(pos, &thermal_cdev_list, node) { - ret = tz->ops->bind(tz, pos); - if (ret) - print_bind_err_msg(tz, pos, ret); - } - goto exit; - } - - if (!tzp || !tzp->tbp) - goto exit; - - list_for_each_entry(pos, &thermal_cdev_list, node) { - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev || !tzp->tbp[i].match) - continue; - if (tzp->tbp[i].match(tz, pos)) - continue; - tzp->tbp[i].cdev = pos; - __bind(tz, tzp->tbp[i].trip_mask, pos); - } - } -exit: - mutex_unlock(&thermal_list_lock); -} - -static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, - int delay) -{ - if (delay > 1000) - queue_delayed_work(system_freezable_wq, &tz->poll_queue, - round_jiffies(msecs_to_jiffies(delay))); - else if (delay) - queue_delayed_work(system_freezable_wq, &tz->poll_queue, - msecs_to_jiffies(delay)); - else - cancel_delayed_work(&tz->poll_queue); -} - -static void monitor_thermal_zone(struct thermal_zone_device *tz) -{ - mutex_lock(&tz->lock); - - if (tz->passive) - thermal_zone_device_set_polling(tz, tz->passive_delay); - else if (tz->polling_delay) - thermal_zone_device_set_polling(tz, tz->polling_delay); - else - thermal_zone_device_set_polling(tz, 0); - - mutex_unlock(&tz->lock); -} - -static void handle_non_critical_trips(struct thermal_zone_device *tz, - int trip, enum thermal_trip_type trip_type) -{ - if (tz->governor) - { - tz->governor->throttle(tz, trip); - trace_handle_non_critical_trips(tz->id,tz->temperature); - } -} - -static void handle_critical_trips(struct thermal_zone_device *tz, - int trip, enum thermal_trip_type trip_type) -{ - long trip_temp; - - tz->ops->get_trip_temp(tz, trip, &trip_temp); - - /* If we have not crossed the trip_temp, we do not care. */ - if (tz->temperature < trip_temp) - return; - - if (tz->ops->notify) - tz->ops->notify(tz, trip, trip_type); - - if (trip_type == THERMAL_TRIP_CRITICAL) { - pr_emerg("Critical temperature reached(%d C),shutting down\n", - tz->temperature / 1000); - orderly_poweroff(true); - } -} - -static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) -{ - enum thermal_trip_type type; - - tz->ops->get_trip_type(tz, trip, &type); - - if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT) - handle_critical_trips(tz, trip, type); - else - handle_non_critical_trips(tz, trip, type); - /* - * Alright, we handled this trip successfully. - * So, start monitoring again. - */ - monitor_thermal_zone(tz); -} - -static void update_temperature(struct thermal_zone_device *tz) -{ - long temp; - int ret; - - mutex_lock(&tz->lock); - - ret = tz->ops->get_temp(tz, &temp); - if (ret) { - pr_warn("failed to read out thermal zone %d\n", tz->id); - goto exit; - } - - tz->last_temperature = tz->temperature; - tz->temperature = temp; - -exit: - mutex_unlock(&tz->lock); -} - -void thermal_zone_device_update(struct thermal_zone_device *tz) -{ - int count; - - update_temperature(tz); - - for (count = 0; count < tz->trips; count++) - handle_thermal_trip(tz, count); -} -EXPORT_SYMBOL(thermal_zone_device_update); - -static void thermal_zone_device_check(struct work_struct *work) -{ - struct thermal_zone_device *tz = container_of(work, struct - thermal_zone_device, - poll_queue.work); - thermal_zone_device_update(tz); -} - -/* sys I/F for thermal zone */ - -#define to_thermal_zone(_dev) \ - container_of(_dev, struct thermal_zone_device, device) - -static ssize_t -type_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - - return sprintf(buf, "%s\n", tz->type); -} - -static ssize_t -temp_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - long temperature; - int ret; - - if (!tz->ops->get_temp) - return -EPERM; - - ret = tz->ops->get_temp(tz, &temperature); - - if (ret) - return ret; - - return sprintf(buf, "%ld\n", temperature); -} - -static ssize_t -mode_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - enum thermal_device_mode mode; - int result; - - if (!tz->ops->get_mode) - return -EPERM; - - result = tz->ops->get_mode(tz, &mode); - if (result) - return result; - - return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled" - : "disabled"); -} - -static ssize_t -mode_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int result; - - if (!tz->ops->set_mode) - return -EPERM; - - if (!strncmp(buf, "enabled", sizeof("enabled") - 1)) - result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); - else if (!strncmp(buf, "disabled", sizeof("disabled") - 1)) - result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); - else - result = -EINVAL; - - if (result) - return result; - - return count; -} - -static ssize_t -trip_point_type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - enum thermal_trip_type type; - int trip, result; - - if (!tz->ops->get_trip_type) - return -EPERM; - - if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip)) - return -EINVAL; - - result = tz->ops->get_trip_type(tz, trip, &type); - if (result) - return result; - - switch (type) { - case THERMAL_TRIP_CRITICAL: - return sprintf(buf, "critical\n"); - case THERMAL_TRIP_HOT: - return sprintf(buf, "hot\n"); - case THERMAL_TRIP_PASSIVE: - return sprintf(buf, "passive\n"); - case THERMAL_TRIP_ACTIVE: - return sprintf(buf, "active\n"); - default: - return sprintf(buf, "unknown\n"); - } -} - -static ssize_t -trip_point_temp_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - unsigned long temperature; - - if (!tz->ops->set_trip_temp) - return -EPERM; - - if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) - return -EINVAL; - - if (kstrtoul(buf, 10, &temperature)) - return -EINVAL; - - ret = tz->ops->set_trip_temp(tz, trip, temperature); - - return ret ? ret : count; -} - -static ssize_t -trip_point_temp_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - long temperature; - - if (!tz->ops->get_trip_temp) - return -EPERM; - - if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) - return -EINVAL; - - ret = tz->ops->get_trip_temp(tz, trip, &temperature); - - if (ret) - return ret; - - return sprintf(buf, "%ld\n", temperature); -} - -static ssize_t -trip_point_hyst_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - unsigned long temperature; - - if (!tz->ops->set_trip_hyst) - return -EPERM; - - if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip)) - return -EINVAL; - - if (kstrtoul(buf, 10, &temperature)) - return -EINVAL; - - /* - * We are not doing any check on the 'temperature' value - * here. The driver implementing 'set_trip_hyst' has to - * take care of this. - */ - ret = tz->ops->set_trip_hyst(tz, trip, temperature); - - return ret ? ret : count; -} - -static ssize_t -trip_point_hyst_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - int trip, ret; - unsigned long temperature; - - if (!tz->ops->get_trip_hyst) - return -EPERM; - - if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip)) - return -EINVAL; - - ret = tz->ops->get_trip_hyst(tz, trip, &temperature); - - return ret ? ret : sprintf(buf, "%ld\n", temperature); -} - -static ssize_t -passive_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - struct thermal_cooling_device *cdev = NULL; - int state; - - if (!sscanf(buf, "%d\n", &state)) - return -EINVAL; - - /* sanity check: values below 1000 millicelcius don't make sense - * and can cause the system to go into a thermal heart attack - */ - if (state && state < 1000) - return -EINVAL; - - if (state && !tz->forced_passive) { - mutex_lock(&thermal_list_lock); - list_for_each_entry(cdev, &thermal_cdev_list, node) { - if (!strncmp("Processor", cdev->type, - sizeof("Processor"))) - thermal_zone_bind_cooling_device(tz, - THERMAL_TRIPS_NONE, cdev, - THERMAL_NO_LIMIT, - THERMAL_NO_LIMIT); - } - mutex_unlock(&thermal_list_lock); - if (!tz->passive_delay) - tz->passive_delay = 1000; - } else if (!state && tz->forced_passive) { - mutex_lock(&thermal_list_lock); - list_for_each_entry(cdev, &thermal_cdev_list, node) { - if (!strncmp("Processor", cdev->type, - sizeof("Processor"))) - thermal_zone_unbind_cooling_device(tz, - THERMAL_TRIPS_NONE, - cdev); - } - mutex_unlock(&thermal_list_lock); - tz->passive_delay = 0; - } - - tz->forced_passive = state; - - thermal_zone_device_update(tz); - - return count; -} - -static ssize_t -passive_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - - return sprintf(buf, "%d\n", tz->forced_passive); -} - -static ssize_t -policy_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int ret = -EINVAL; - struct thermal_zone_device *tz = to_thermal_zone(dev); - struct thermal_governor *gov; - - mutex_lock(&thermal_governor_lock); - - gov = __find_governor(buf); - if (!gov) - goto exit; - - tz->governor = gov; - ret = count; - -exit: - mutex_unlock(&thermal_governor_lock); - return ret; -} - -static ssize_t -policy_show(struct device *dev, struct device_attribute *devattr, char *buf) -{ - struct thermal_zone_device *tz = to_thermal_zone(dev); - - return sprintf(buf, "%s\n", tz->governor->name); -} - -static DEVICE_ATTR(type, 0444, type_show, NULL); -static DEVICE_ATTR(temp, 0444, temp_show, NULL); -static DEVICE_ATTR(mode, 0644, mode_show, mode_store); -static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); -static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store); - -/* sys I/F for cooling device */ -#define to_cooling_device(_dev) \ - container_of(_dev, struct thermal_cooling_device, device) - -static ssize_t -thermal_cooling_device_type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct thermal_cooling_device *cdev = to_cooling_device(dev); - - return sprintf(buf, "%s\n", cdev->type); -} - -static ssize_t -thermal_cooling_device_max_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct thermal_cooling_device *cdev = to_cooling_device(dev); - unsigned long state; - int ret; - - ret = cdev->ops->get_max_state(cdev, &state); - if (ret) - return ret; - return sprintf(buf, "%ld\n", state); -} - -static ssize_t -thermal_cooling_device_cur_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct thermal_cooling_device *cdev = to_cooling_device(dev); - unsigned long state; - int ret; - - ret = cdev->ops->get_cur_state(cdev, &state); - if (ret) - return ret; - return sprintf(buf, "%ld\n", state); -} - -static ssize_t -thermal_cooling_device_cur_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct thermal_cooling_device *cdev = to_cooling_device(dev); - unsigned long state; - int result; - - if (!sscanf(buf, "%lu\n", &state)) - return -EINVAL; - - if ((long)state < 0) - return -EINVAL; - - result = cdev->ops->set_cur_state(cdev, state); - if (result) - return result; - return count; -} - -static struct device_attribute dev_attr_cdev_type = -__ATTR(type, 0444, thermal_cooling_device_type_show, NULL); -static DEVICE_ATTR(max_state, 0444, - thermal_cooling_device_max_state_show, NULL); -static DEVICE_ATTR(cur_state, 0644, - thermal_cooling_device_cur_state_show, - thermal_cooling_device_cur_state_store); - -static ssize_t -thermal_cooling_device_trip_point_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct thermal_instance *instance; - - instance = - container_of(attr, struct thermal_instance, attr); - - if (instance->trip == THERMAL_TRIPS_NONE) - return sprintf(buf, "-1\n"); - else - return sprintf(buf, "%d\n", instance->trip); -} - -/* Device management */ - -#if defined(CONFIG_THERMAL_HWMON) - -/* hwmon sys I/F */ -#include - -/* thermal zone devices with the same type share one hwmon device */ -struct thermal_hwmon_device { - char type[THERMAL_NAME_LENGTH]; - struct device *device; - int count; - struct list_head tz_list; - struct list_head node; -}; - -struct thermal_hwmon_attr { - struct device_attribute attr; - char name[16]; -}; - -/* one temperature input for each thermal zone */ -struct thermal_hwmon_temp { - struct list_head hwmon_node; - struct thermal_zone_device *tz; - struct thermal_hwmon_attr temp_input; /* hwmon sys attr */ - struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */ -}; - -static LIST_HEAD(thermal_hwmon_list); - -static ssize_t -name_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", hwmon->type); -} -static DEVICE_ATTR(name, 0444, name_show, NULL); - -static ssize_t -temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - long temperature; - int ret; - struct thermal_hwmon_attr *hwmon_attr - = container_of(attr, struct thermal_hwmon_attr, attr); - struct thermal_hwmon_temp *temp - = container_of(hwmon_attr, struct thermal_hwmon_temp, - temp_input); - struct thermal_zone_device *tz = temp->tz; - - ret = tz->ops->get_temp(tz, &temperature); - - if (ret) - return ret; - - return sprintf(buf, "%ld\n", temperature); -} - -static ssize_t -temp_crit_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct thermal_hwmon_attr *hwmon_attr - = container_of(attr, struct thermal_hwmon_attr, attr); - struct thermal_hwmon_temp *temp - = container_of(hwmon_attr, struct thermal_hwmon_temp, - temp_crit); - struct thermal_zone_device *tz = temp->tz; - long temperature; - int ret; - - ret = tz->ops->get_trip_temp(tz, 0, &temperature); - if (ret) - return ret; - - return sprintf(buf, "%ld\n", temperature); -} - - -static struct thermal_hwmon_device * -thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz) -{ - struct thermal_hwmon_device *hwmon; - - mutex_lock(&thermal_list_lock); - list_for_each_entry(hwmon, &thermal_hwmon_list, node) - if (!strcmp(hwmon->type, tz->type)) { - mutex_unlock(&thermal_list_lock); - return hwmon; - } - mutex_unlock(&thermal_list_lock); - - return NULL; -} - -/* Find the temperature input matching a given thermal zone */ -static struct thermal_hwmon_temp * -thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon, - const struct thermal_zone_device *tz) -{ - struct thermal_hwmon_temp *temp; - - mutex_lock(&thermal_list_lock); - list_for_each_entry(temp, &hwmon->tz_list, hwmon_node) - if (temp->tz == tz) { - mutex_unlock(&thermal_list_lock); - return temp; - } - mutex_unlock(&thermal_list_lock); - - return NULL; -} - -static int -thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) -{ - struct thermal_hwmon_device *hwmon; - struct thermal_hwmon_temp *temp; - int new_hwmon_device = 1; - int result; - - hwmon = thermal_hwmon_lookup_by_type(tz); - if (hwmon) { - new_hwmon_device = 0; - goto register_sys_interface; - } - - hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL); - if (!hwmon) - return -ENOMEM; - - INIT_LIST_HEAD(&hwmon->tz_list); - strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH); - hwmon->device = hwmon_device_register(NULL); - if (IS_ERR(hwmon->device)) { - result = PTR_ERR(hwmon->device); - goto free_mem; - } - dev_set_drvdata(hwmon->device, hwmon); - result = device_create_file(hwmon->device, &dev_attr_name); - if (result) - goto free_mem; - - register_sys_interface: - temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL); - if (!temp) { - result = -ENOMEM; - goto unregister_name; - } - - temp->tz = tz; - hwmon->count++; - - snprintf(temp->temp_input.name, sizeof(temp->temp_input.name), - "temp%d_input", hwmon->count); - temp->temp_input.attr.attr.name = temp->temp_input.name; - temp->temp_input.attr.attr.mode = 0444; - temp->temp_input.attr.show = temp_input_show; - sysfs_attr_init(&temp->temp_input.attr.attr); - result = device_create_file(hwmon->device, &temp->temp_input.attr); - if (result) - goto free_temp_mem; - - if (tz->ops->get_crit_temp) { - unsigned long temperature; - if (!tz->ops->get_crit_temp(tz, &temperature)) { - snprintf(temp->temp_crit.name, - sizeof(temp->temp_crit.name), - "temp%d_crit", hwmon->count); - temp->temp_crit.attr.attr.name = temp->temp_crit.name; - temp->temp_crit.attr.attr.mode = 0444; - temp->temp_crit.attr.show = temp_crit_show; - sysfs_attr_init(&temp->temp_crit.attr.attr); - result = device_create_file(hwmon->device, - &temp->temp_crit.attr); - if (result) - goto unregister_input; - } - } - - mutex_lock(&thermal_list_lock); - if (new_hwmon_device) - list_add_tail(&hwmon->node, &thermal_hwmon_list); - list_add_tail(&temp->hwmon_node, &hwmon->tz_list); - mutex_unlock(&thermal_list_lock); - - return 0; - - unregister_input: - device_remove_file(hwmon->device, &temp->temp_input.attr); - free_temp_mem: - kfree(temp); - unregister_name: - if (new_hwmon_device) { - device_remove_file(hwmon->device, &dev_attr_name); - hwmon_device_unregister(hwmon->device); - } - free_mem: - if (new_hwmon_device) - kfree(hwmon); - - return result; -} - -static void -thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) -{ - struct thermal_hwmon_device *hwmon; - struct thermal_hwmon_temp *temp; - - hwmon = thermal_hwmon_lookup_by_type(tz); - if (unlikely(!hwmon)) { - /* Should never happen... */ - dev_dbg(&tz->device, "hwmon device lookup failed!\n"); - return; - } - - temp = thermal_hwmon_lookup_temp(hwmon, tz); - if (unlikely(!temp)) { - /* Should never happen... */ - dev_dbg(&tz->device, "temperature input lookup failed!\n"); - return; - } - - device_remove_file(hwmon->device, &temp->temp_input.attr); - if (tz->ops->get_crit_temp) - device_remove_file(hwmon->device, &temp->temp_crit.attr); - - mutex_lock(&thermal_list_lock); - list_del(&temp->hwmon_node); - kfree(temp); - if (!list_empty(&hwmon->tz_list)) { - mutex_unlock(&thermal_list_lock); - return; - } - list_del(&hwmon->node); - mutex_unlock(&thermal_list_lock); - - device_remove_file(hwmon->device, &dev_attr_name); - hwmon_device_unregister(hwmon->device); - kfree(hwmon); -} -#else -static int -thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) -{ - return 0; -} - -static void -thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) -{ -} -#endif - -/** - * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone - * @tz: thermal zone device - * @trip: indicates which trip point the cooling devices is - * associated with in this thermal zone. - * @cdev: thermal cooling device - * - * This function is usually called in the thermal zone device .bind callback. - */ -int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, - int trip, - struct thermal_cooling_device *cdev, - unsigned long upper, unsigned long lower) -{ - struct thermal_instance *dev; - struct thermal_instance *pos; - struct thermal_zone_device *pos1; - struct thermal_cooling_device *pos2; - unsigned long max_state; - int result; - - if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) - return -EINVAL; - - list_for_each_entry(pos1, &thermal_tz_list, node) { - if (pos1 == tz) - break; - } - list_for_each_entry(pos2, &thermal_cdev_list, node) { - if (pos2 == cdev) - break; - } - - if (tz != pos1 || cdev != pos2) - return -EINVAL; - - cdev->ops->get_max_state(cdev, &max_state); - - /* lower default 0, upper default max_state */ - lower = lower == THERMAL_NO_LIMIT ? 0 : lower; - upper = upper == THERMAL_NO_LIMIT ? max_state : upper; - - if (lower > upper || upper > max_state) - return -EINVAL; - - dev = - kzalloc(sizeof(struct thermal_instance), GFP_KERNEL); - if (!dev) - return -ENOMEM; - dev->tz = tz; - dev->cdev = cdev; - dev->trip = trip; - dev->upper = upper; - dev->lower = lower; - dev->target = THERMAL_NO_TARGET; - - result = get_idr(&tz->idr, &tz->lock, &dev->id); - if (result) - goto free_mem; - - sprintf(dev->name, "cdev%d", dev->id); - result = - sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name); - if (result) - goto release_idr; - - sprintf(dev->attr_name, "cdev%d_trip_point", dev->id); - sysfs_attr_init(&dev->attr.attr); - dev->attr.attr.name = dev->attr_name; - dev->attr.attr.mode = 0444; - dev->attr.show = thermal_cooling_device_trip_point_show; - result = device_create_file(&tz->device, &dev->attr); - if (result) - goto remove_symbol_link; - - mutex_lock(&tz->lock); - mutex_lock(&cdev->lock); - list_for_each_entry(pos, &tz->thermal_instances, tz_node) - if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { - result = -EEXIST; - break; - } - if (!result) { - list_add_tail(&dev->tz_node, &tz->thermal_instances); - list_add_tail(&dev->cdev_node, &cdev->thermal_instances); - } - mutex_unlock(&cdev->lock); - mutex_unlock(&tz->lock); - - if (!result) - return 0; - - device_remove_file(&tz->device, &dev->attr); -remove_symbol_link: - sysfs_remove_link(&tz->device.kobj, dev->name); -release_idr: - release_idr(&tz->idr, &tz->lock, dev->id); -free_mem: - kfree(dev); - return result; -} -EXPORT_SYMBOL(thermal_zone_bind_cooling_device); - -/** - * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone - * @tz: thermal zone device - * @trip: indicates which trip point the cooling devices is - * associated with in this thermal zone. - * @cdev: thermal cooling device - * - * This function is usually called in the thermal zone device .unbind callback. - */ -int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, - int trip, - struct thermal_cooling_device *cdev) -{ - struct thermal_instance *pos, *next; - - mutex_lock(&tz->lock); - mutex_lock(&cdev->lock); - list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) { - if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { - list_del(&pos->tz_node); - list_del(&pos->cdev_node); - mutex_unlock(&cdev->lock); - mutex_unlock(&tz->lock); - goto unbind; - } - } - mutex_unlock(&cdev->lock); - mutex_unlock(&tz->lock); - - return -ENODEV; - -unbind: - device_remove_file(&tz->device, &pos->attr); - sysfs_remove_link(&tz->device.kobj, pos->name); - release_idr(&tz->idr, &tz->lock, pos->id); - kfree(pos); - return 0; -} -EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); - -static void thermal_release(struct device *dev) -{ - struct thermal_zone_device *tz; - struct thermal_cooling_device *cdev; - - if (!strncmp(dev_name(dev), "thermal_zone", - sizeof("thermal_zone") - 1)) { - tz = to_thermal_zone(dev); - kfree(tz); - } else { - cdev = to_cooling_device(dev); - kfree(cdev); - } -} - -static struct class thermal_class = { - .name = "thermal", - .dev_release = thermal_release, -}; - -/** - * thermal_cooling_device_register - register a new thermal cooling device - * @type: the thermal cooling device type. - * @devdata: device private data. - * @ops: standard thermal cooling devices callbacks. - */ -struct thermal_cooling_device * -thermal_cooling_device_register(char *type, void *devdata, - const struct thermal_cooling_device_ops *ops) -{ - struct thermal_cooling_device *cdev; - int result; - - if (type && strlen(type) >= THERMAL_NAME_LENGTH) - return ERR_PTR(-EINVAL); - - if (!ops || !ops->get_max_state || !ops->get_cur_state || - !ops->set_cur_state) - return ERR_PTR(-EINVAL); - - cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL); - if (!cdev) - return ERR_PTR(-ENOMEM); - - result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id); - if (result) { - kfree(cdev); - return ERR_PTR(result); - } - - strcpy(cdev->type, type ? : ""); - mutex_init(&cdev->lock); - INIT_LIST_HEAD(&cdev->thermal_instances); - cdev->ops = ops; - cdev->updated = true; - cdev->device.class = &thermal_class; - cdev->devdata = devdata; - dev_set_name(&cdev->device, "cooling_device%d", cdev->id); - result = device_register(&cdev->device); - if (result) { - release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); - kfree(cdev); - return ERR_PTR(result); - } - - /* sys I/F */ - if (type) { - result = device_create_file(&cdev->device, &dev_attr_cdev_type); - if (result) - goto unregister; - } - - result = device_create_file(&cdev->device, &dev_attr_max_state); - if (result) - goto unregister; - - result = device_create_file(&cdev->device, &dev_attr_cur_state); - if (result) - goto unregister; - - /* Add 'this' new cdev to the global cdev list */ - mutex_lock(&thermal_list_lock); - list_add(&cdev->node, &thermal_cdev_list); - mutex_unlock(&thermal_list_lock); - - /* Update binding information for 'this' new cdev */ - bind_cdev(cdev); - - return cdev; - -unregister: - release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); - device_unregister(&cdev->device); - return ERR_PTR(result); -} -EXPORT_SYMBOL(thermal_cooling_device_register); - -/** - * thermal_cooling_device_unregister - removes the registered thermal cooling device - * @cdev: the thermal cooling device to remove. - * - * thermal_cooling_device_unregister() must be called when the device is no - * longer needed. - */ -void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) -{ - int i; - const struct thermal_zone_params *tzp; - struct thermal_zone_device *tz; - struct thermal_cooling_device *pos = NULL; - - if (!cdev) - return; - - mutex_lock(&thermal_list_lock); - list_for_each_entry(pos, &thermal_cdev_list, node) - if (pos == cdev) - break; - if (pos != cdev) { - /* thermal cooling device not found */ - mutex_unlock(&thermal_list_lock); - return; - } - list_del(&cdev->node); - - /* Unbind all thermal zones associated with 'this' cdev */ - list_for_each_entry(tz, &thermal_tz_list, node) { - if (tz->ops->unbind) { - tz->ops->unbind(tz, cdev); - continue; - } - - if (!tz->tzp || !tz->tzp->tbp) - continue; - - tzp = tz->tzp; - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } - } - - mutex_unlock(&thermal_list_lock); - - if (cdev->type[0]) - device_remove_file(&cdev->device, &dev_attr_cdev_type); - device_remove_file(&cdev->device, &dev_attr_max_state); - device_remove_file(&cdev->device, &dev_attr_cur_state); - - release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); - device_unregister(&cdev->device); - return; -} -EXPORT_SYMBOL(thermal_cooling_device_unregister); - -void thermal_cdev_update(struct thermal_cooling_device *cdev) -{ - struct thermal_instance *instance; - unsigned long target = 0; - - /* cooling device is updated*/ - if (cdev->updated) - return; - - mutex_lock(&cdev->lock); - /* Make sure cdev enters the deepest cooling state */ - list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) { - if (instance->target == THERMAL_NO_TARGET) - continue; - if (instance->target > target) - target = instance->target; - } - mutex_unlock(&cdev->lock); - cdev->ops->set_cur_state(cdev, target); - cdev->updated = true; -} -EXPORT_SYMBOL(thermal_cdev_update); - -/** - * notify_thermal_framework - Sensor drivers use this API to notify framework - * @tz: thermal zone device - * @trip: indicates which trip point has been crossed - * - * This function handles the trip events from sensor drivers. It starts - * throttling the cooling devices according to the policy configured. - * For CRITICAL and HOT trip points, this notifies the respective drivers, - * and does actual throttling for other trip points i.e ACTIVE and PASSIVE. - * The throttling policy is based on the configured platform data; if no - * platform data is provided, this uses the step_wise throttling policy. - */ -void notify_thermal_framework(struct thermal_zone_device *tz, int trip) -{ - handle_thermal_trip(tz, trip); -} -EXPORT_SYMBOL(notify_thermal_framework); - -/** - * create_trip_attrs - create attributes for trip points - * @tz: the thermal zone device - * @mask: Writeable trip point bitmap. - */ -static int create_trip_attrs(struct thermal_zone_device *tz, int mask) -{ - int indx; - int size = sizeof(struct thermal_attr) * tz->trips; - - tz->trip_type_attrs = kzalloc(size, GFP_KERNEL); - if (!tz->trip_type_attrs) - return -ENOMEM; - - tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL); - if (!tz->trip_temp_attrs) { - kfree(tz->trip_type_attrs); - return -ENOMEM; - } - - if (tz->ops->get_trip_hyst) { - tz->trip_hyst_attrs = kzalloc(size, GFP_KERNEL); - if (!tz->trip_hyst_attrs) { - kfree(tz->trip_type_attrs); - kfree(tz->trip_temp_attrs); - return -ENOMEM; - } - } - - - for (indx = 0; indx < tz->trips; indx++) { - /* create trip type attribute */ - snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH, - "trip_point_%d_type", indx); - - sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr); - tz->trip_type_attrs[indx].attr.attr.name = - tz->trip_type_attrs[indx].name; - tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO; - tz->trip_type_attrs[indx].attr.show = trip_point_type_show; - - device_create_file(&tz->device, - &tz->trip_type_attrs[indx].attr); - - /* create trip temp attribute */ - snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH, - "trip_point_%d_temp", indx); - - sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr); - tz->trip_temp_attrs[indx].attr.attr.name = - tz->trip_temp_attrs[indx].name; - tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO; - tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show; - if (mask & (1 << indx)) { - tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR; - tz->trip_temp_attrs[indx].attr.store = - trip_point_temp_store; - } - - device_create_file(&tz->device, - &tz->trip_temp_attrs[indx].attr); - - /* create Optional trip hyst attribute */ - if (!tz->ops->get_trip_hyst) - continue; - snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH, - "trip_point_%d_hyst", indx); - - sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr); - tz->trip_hyst_attrs[indx].attr.attr.name = - tz->trip_hyst_attrs[indx].name; - tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO; - tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show; - if (tz->ops->set_trip_hyst) { - tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR; - tz->trip_hyst_attrs[indx].attr.store = - trip_point_hyst_store; - } - - device_create_file(&tz->device, - &tz->trip_hyst_attrs[indx].attr); - } - return 0; -} - -static void remove_trip_attrs(struct thermal_zone_device *tz) -{ - int indx; - - for (indx = 0; indx < tz->trips; indx++) { - device_remove_file(&tz->device, - &tz->trip_type_attrs[indx].attr); - device_remove_file(&tz->device, - &tz->trip_temp_attrs[indx].attr); - if (tz->ops->get_trip_hyst) - device_remove_file(&tz->device, - &tz->trip_hyst_attrs[indx].attr); - } - kfree(tz->trip_type_attrs); - kfree(tz->trip_temp_attrs); - kfree(tz->trip_hyst_attrs); -} - -/** - * thermal_zone_device_register - register a new thermal zone device - * @type: the thermal zone device type - * @trips: the number of trip points the thermal zone support - * @mask: a bit string indicating the writeablility of trip points - * @devdata: private device data - * @ops: standard thermal zone device callbacks - * @tzp: thermal zone platform parameters - * @passive_delay: number of milliseconds to wait between polls when - * performing passive cooling - * @polling_delay: number of milliseconds to wait between polls when checking - * whether trip points have been crossed (0 for interrupt - * driven systems) - * - * thermal_zone_device_unregister() must be called when the device is no - * longer needed. The passive cooling depends on the .get_trend() return value. - */ -struct thermal_zone_device *thermal_zone_device_register(const char *type, - int trips, int mask, void *devdata, - const struct thermal_zone_device_ops *ops, - const struct thermal_zone_params *tzp, - int passive_delay, int polling_delay) -{ - struct thermal_zone_device *tz; - enum thermal_trip_type trip_type; - int result; - int count; - int passive = 0; - - if (type && strlen(type) >= THERMAL_NAME_LENGTH) - return ERR_PTR(-EINVAL); - - if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) - return ERR_PTR(-EINVAL); - - if (!ops || !ops->get_temp) - return ERR_PTR(-EINVAL); - - tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL); - if (!tz) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&tz->thermal_instances); - idr_init(&tz->idr); - mutex_init(&tz->lock); - result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id); - if (result) { - kfree(tz); - return ERR_PTR(result); - } - - strcpy(tz->type, type ? : ""); - tz->ops = ops; - tz->tzp = tzp; - tz->device.class = &thermal_class; - tz->devdata = devdata; - tz->trips = trips; - tz->passive_delay = passive_delay; - tz->polling_delay = polling_delay; - - dev_set_name(&tz->device, "thermal_zone%d", tz->id); - result = device_register(&tz->device); - if (result) { - release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); - kfree(tz); - return ERR_PTR(result); - } - - /* sys I/F */ - if (type) { - result = device_create_file(&tz->device, &dev_attr_type); - if (result) - goto unregister; - } - - result = device_create_file(&tz->device, &dev_attr_temp); - if (result) - goto unregister; - - if (ops->get_mode) { - result = device_create_file(&tz->device, &dev_attr_mode); - if (result) - goto unregister; - } - - result = create_trip_attrs(tz, mask); - if (result) - goto unregister; - - for (count = 0; count < trips; count++) { - tz->ops->get_trip_type(tz, count, &trip_type); - if (trip_type == THERMAL_TRIP_PASSIVE) - passive = 1; - } - - if (!passive) { - result = device_create_file(&tz->device, &dev_attr_passive); - if (result) - goto unregister; - } - - /* Create policy attribute */ - result = device_create_file(&tz->device, &dev_attr_policy); - if (result) - goto unregister; - - /* Update 'this' zone's governor information */ - mutex_lock(&thermal_governor_lock); - - if (tz->tzp) - tz->governor = __find_governor(tz->tzp->governor_name); - else - tz->governor = __find_governor(DEFAULT_THERMAL_GOVERNOR); - - mutex_unlock(&thermal_governor_lock); - - result = thermal_add_hwmon_sysfs(tz); - if (result) - goto unregister; - - mutex_lock(&thermal_list_lock); - list_add_tail(&tz->node, &thermal_tz_list); - mutex_unlock(&thermal_list_lock); - - /* Bind cooling devices for this zone */ - bind_tz(tz); - - INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); - - thermal_zone_device_update(tz); - - if (!result) - return tz; - -unregister: - release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); - device_unregister(&tz->device); - return ERR_PTR(result); -} -EXPORT_SYMBOL(thermal_zone_device_register); - -/** - * thermal_device_unregister - removes the registered thermal zone device - * @tz: the thermal zone device to remove - */ -void thermal_zone_device_unregister(struct thermal_zone_device *tz) -{ - int i; - const struct thermal_zone_params *tzp; - struct thermal_cooling_device *cdev; - struct thermal_zone_device *pos = NULL; - - if (!tz) - return; - - tzp = tz->tzp; - - mutex_lock(&thermal_list_lock); - list_for_each_entry(pos, &thermal_tz_list, node) - if (pos == tz) - break; - if (pos != tz) { - /* thermal zone device not found */ - mutex_unlock(&thermal_list_lock); - return; - } - list_del(&tz->node); - - /* Unbind all cdevs associated with 'this' thermal zone */ - list_for_each_entry(cdev, &thermal_cdev_list, node) { - if (tz->ops->unbind) { - tz->ops->unbind(tz, cdev); - continue; - } - - if (!tzp || !tzp->tbp) - break; - - for (i = 0; i < tzp->num_tbps; i++) { - if (tzp->tbp[i].cdev == cdev) { - __unbind(tz, tzp->tbp[i].trip_mask, cdev); - tzp->tbp[i].cdev = NULL; - } - } - } - - mutex_unlock(&thermal_list_lock); - - thermal_zone_device_set_polling(tz, 0); - - if (tz->type[0]) - device_remove_file(&tz->device, &dev_attr_type); - device_remove_file(&tz->device, &dev_attr_temp); - if (tz->ops->get_mode) - device_remove_file(&tz->device, &dev_attr_mode); - device_remove_file(&tz->device, &dev_attr_policy); - remove_trip_attrs(tz); - tz->governor = NULL; - - thermal_remove_hwmon_sysfs(tz); - release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); - idr_destroy(&tz->idr); - mutex_destroy(&tz->lock); - device_unregister(&tz->device); - return; -} -EXPORT_SYMBOL(thermal_zone_device_unregister); - -#ifdef CONFIG_NET -static struct genl_family thermal_event_genl_family = { - .id = GENL_ID_GENERATE, - .name = THERMAL_GENL_FAMILY_NAME, - .version = THERMAL_GENL_VERSION, - .maxattr = THERMAL_GENL_ATTR_MAX, -}; - -static struct genl_multicast_group thermal_event_mcgrp = { - .name = THERMAL_GENL_MCAST_GROUP_NAME, -}; - -int thermal_generate_netlink_event(u32 orig, enum events event) -{ - struct sk_buff *skb; - struct nlattr *attr; - struct thermal_genl_event *thermal_event; - void *msg_header; - int size; - int result; - static unsigned int thermal_event_seqnum; - - /* allocate memory */ - size = nla_total_size(sizeof(struct thermal_genl_event)) + - nla_total_size(0); - - skb = genlmsg_new(size, GFP_ATOMIC); - if (!skb) - return -ENOMEM; - - /* add the genetlink message header */ - msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++, - &thermal_event_genl_family, 0, - THERMAL_GENL_CMD_EVENT); - if (!msg_header) { - nlmsg_free(skb); - return -ENOMEM; - } - - /* fill the data */ - attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, - sizeof(struct thermal_genl_event)); - - if (!attr) { - nlmsg_free(skb); - return -EINVAL; - } - - thermal_event = nla_data(attr); - if (!thermal_event) { - nlmsg_free(skb); - return -EINVAL; - } - - memset(thermal_event, 0, sizeof(struct thermal_genl_event)); - - thermal_event->orig = orig; - thermal_event->event = event; - - /* send multicast genetlink message */ - result = genlmsg_end(skb, msg_header); - if (result < 0) { - nlmsg_free(skb); - return result; - } - - result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); - if (result) - pr_info("failed to send netlink event:%d\n", result); - - return result; -} -EXPORT_SYMBOL(thermal_generate_netlink_event); - -static int genetlink_init(void) -{ - int result; - - result = genl_register_family(&thermal_event_genl_family); - if (result) - return result; - - result = genl_register_mc_group(&thermal_event_genl_family, - &thermal_event_mcgrp); - if (result) - genl_unregister_family(&thermal_event_genl_family); - return result; -} - -static void genetlink_exit(void) -{ - genl_unregister_family(&thermal_event_genl_family); -} -#else /* !CONFIG_NET */ -static inline int genetlink_init(void) { return 0; } -static inline void genetlink_exit(void) {} -#endif /* !CONFIG_NET */ - -static int __init thermal_init(void) -{ - int result = 0; - - result = class_register(&thermal_class); - if (result) { - idr_destroy(&thermal_tz_idr); - idr_destroy(&thermal_cdev_idr); - mutex_destroy(&thermal_idr_lock); - mutex_destroy(&thermal_list_lock); - } - result = genetlink_init(); - return result; -} - -static void __exit thermal_exit(void) -{ - class_unregister(&thermal_class); - idr_destroy(&thermal_tz_idr); - idr_destroy(&thermal_cdev_idr); - mutex_destroy(&thermal_idr_lock); - mutex_destroy(&thermal_list_lock); - genetlink_exit(); -} - -fs_initcall(thermal_init); -module_exit(thermal_exit); diff --git a/linux-3.4/drivers/thermal.new/user_space.c b/linux-3.4/drivers/thermal.new/user_space.c deleted file mode 100755 index 6bbb380b..00000000 --- a/linux-3.4/drivers/thermal.new/user_space.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * user_space.c - A simple user space Thermal events notifier - * - * Copyright (C) 2012 Intel Corp - * Copyright (C) 2012 Durgadoss R - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - -#include "thermal_core.h" - -/** - * notify_user_space - Notifies user space about thermal events - * @tz - thermal_zone_device - * - * This function notifies the user space through UEvents. - */ -static int notify_user_space(struct thermal_zone_device *tz, int trip) -{ - mutex_lock(&tz->lock); - kobject_uevent(&tz->device.kobj, KOBJ_CHANGE); - mutex_unlock(&tz->lock); - return 0; -} - -static struct thermal_governor thermal_gov_user_space = { - .name = "user_space", - .throttle = notify_user_space, - .owner = THIS_MODULE, -}; - -static int __init thermal_gov_user_space_init(void) -{ - return thermal_register_governor(&thermal_gov_user_space); -} - -static void __exit thermal_gov_user_space_exit(void) -{ - thermal_unregister_governor(&thermal_gov_user_space); -} - -/* This should load after thermal framework */ -fs_initcall(thermal_gov_user_space_init); -module_exit(thermal_gov_user_space_exit); - -MODULE_AUTHOR("Durgadoss R"); -MODULE_DESCRIPTION("A user space Thermal notifier"); -MODULE_LICENSE("GPL"); From cac61dfdc148889f0a4cdfa6f50c9f5245d4b1b3 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Fri, 16 Jun 2017 11:17:48 -0300 Subject: [PATCH 07/26] small fixes --- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35105 -> 35117 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 217 +++++++++--------- .../arm/mach-sunxi/power/brom/resumes.map | 6 +- .../src/devicedrv/mali/.tmp_versions/mali.mod | 4 +- .../driver/src/devicedrv/mali/Module.symvers | 42 ++-- .../src/devicedrv/ump/.tmp_versions/ump.mod | 4 +- .../driver/src/devicedrv/ump/Module.symvers | 18 +- .../mali_drm/.tmp_versions/mali_drm.mod | 4 +- 8 files changed, 149 insertions(+), 146 deletions(-) diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 5823357d6863a92d1192decc4af5265f3808e462..790828a65a3ab293dc2665477cb19a952cf7c7b5 100755 GIT binary patch delta 358 zcmZ2DiD~U5rU?p+H5(O=H`IS(U|?XJ1SHsi_zn~UDF!A+wg*6p*%e4Is+)sFIPQTc zCRQs(5XCMBq*z#3GxJIqn1K=ujM{M^c@}mRpaiQIkZr(d_YX+1?FY#^1cPLi8Q9){ zc#a?mrZi<1HW8p|Mkk0Q4_g*U(iy@NV7ma~xj=X#Y=t16D<8;qWeK(z5YG+5lVNKI z@!TOi1-3d6&jZ3!VKbb3wo#8K0A!C>Do}>gWixw|7^8}QenE+TS$~q zenC-wR%&udv3_o1c4~ZLQEKAk+s)FGWt*38{?@#Zaq^7TEsV*NecO~7t0ot=sWaZ2 YJQGOrPd*4FO(wqtl1nxVwhJ%;0M*k*6#xJL delta 369 zcmZ2GiD}^^rU?p+1sfHQH`G66U|?Vj1`=z5_zn~UDF!A+wuL~7nGHxVs+)sFIOc;W zCRSZW5XCMCq*z#3GxJIqn1K=ujM{M^c@}nYpad&7kZr(d_YX+1H2?`l2aq*P$_#Ax zK|Dv01XG$a3mZF7HKP+ml7~$jBVoD`VK?$Tnrh+{v|V m>Z})A7#IvE8@35g-qR+)$TazEn>wS$ - 70: 00800600 addeq r0, r0, r0, lsl #12 + 70: 00bf0600 adcseq r0, pc, r0, lsl #12 74: 40010000 andmi r0, r1, r0 78: 00000053 andeq r0, r0, r3, asr r0 7c: 06002302 streq r2, [r0], -r2, lsl #6 - 80: 000000df ldrdeq r0, [r0], -pc ; + 80: 000000ec andeq r0, r0, ip, ror #1 84: 00fe4101 rscseq r4, lr, r1, lsl #2 88: 23020000 movwcs r0, #8192 ; 0x2000 - 8c: 01070604 tsteq r7, r4, lsl #12 + 8c: 01140604 tsteq r4, r4, lsl #12 90: 42010000 andmi r0, r1, #0 94: 00000053 andeq r0, r0, r3, asr r0 98: 060c2302 streq r2, [ip], -r2, lsl #6 - 9c: 0000002b andeq r0, r0, fp, lsr #32 + 9c: 0000006a andeq r0, r0, sl, rrx a0: 00534301 subseq r4, r3, r1, lsl #6 a4: 23020000 movwcs r0, #8192 ; 0x2000 - a8: 00910610 addseq r0, r1, r0, lsl r6 + a8: 00d00610 sbcseq r0, r0, r0, lsl r6 ac: 44010000 strmi r0, [r1], #-0 b0: 00000053 andeq r0, r0, r3, asr r0 b4: 06142302 ldreq r2, [r4], -r2, lsl #6 - b8: 00000032 andeq r0, r0, r2, lsr r0 + b8: 00000071 andeq r0, r0, r1, ror r0 bc: 010e4501 tsteq lr, r1, lsl #10 c0: 23020000 movwcs r0, #8192 ; 0x2000 - c4: 001d0618 andseq r0, sp, r8, lsl r6 + c4: 005c0618 subseq r0, ip, r8, lsl r6 c8: 46010000 strmi r0, [r1], -r0 cc: 0000010e andeq r0, r0, lr, lsl #2 d0: 061c2302 ldreq r2, [ip], -r2, lsl #6 - d4: 00000048 andeq r0, r0, r8, asr #32 + d4: 00000087 andeq r0, r0, r7, lsl #1 d8: 010e4701 tsteq lr, r1, lsl #14 dc: 23020000 movwcs r0, #8192 ; 0x2000 - e0: 003f0620 eorseq r0, pc, r0, lsr #12 + e0: 007e0620 rsbseq r0, lr, r0, lsr #12 e4: 48010000 stmdami r1, {} ; e8: 0000010e andeq r0, r0, lr, lsl #2 ec: 06242302 strteq r2, [r4], -r2, lsl #6 - f0: 00000124 andeq r0, r0, r4, lsr #2 + f0: 00000131 andeq r0, r0, r1, lsr r1 f4: 00fe4901 rscseq r4, lr, r1, lsl #18 f8: 23020000 movwcs r0, #8192 ; 0x2000 fc: 2c070028 stccs 0, cr0, [r7], {40} ; 0x28 @@ -143,10 +143,10 @@ Disassembly of section .debug_info: 110: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0} 114: 08000001 stmdaeq r0, {r0} 118: 0000005e andeq r0, r0, lr, asr r0 - 11c: 43030003 movwmi r0, #12291 ; 0x3003 + 11c: 50030003 andpl r0, r3, r3 120: 01000001 tsteq r0, r1 124: 0000654a andeq r6, r0, sl, asr #10 - 128: 01370900 teqeq r7, r0, lsl #18 + 128: 01440900 cmpeq r4, r0, lsl #18 12c: 25020000 strcs r0, [r2, #-0] 130: 0000013b andeq r0, r0, fp, lsr r1 134: 00030501 andeq r0, r3, r1, lsl #10 @@ -231,91 +231,94 @@ Disassembly of section .debug_str: 00000000 <.debug_str>: 0: 33755f5f cmncc r5, #380 ; 0x17c - 4: 5f5f0032 svcpl 0x005f0032 - 8: 5f003875 svcpl 0x00003875 - c: 75736552 ldrbvc r6, [r3, #-1362]! ; 0x552 - 10: 665f656d ldrbvs r6, [pc], -sp, ror #10 - 14: 5f656c69 svcpl 0x00656c69 - 18: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 1c: 6c696600 stclvs 6, cr6, [r9], #-0 - 20: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - 24: 765f6461 ldrbvc r6, [pc], -r1, ror #8 - 28: 6c006e73 stcvs 14, cr6, [r0], {115} ; 0x73 - 2c: 74676e65 strbtvc r6, [r7], #-3685 ; 0xe65 - 30: 75700068 ldrbvc r0, [r0, #-104]! ; 0x68 - 34: 65685f62 strbvs r5, [r8, #-3938]! ; 0xf62 - 38: 765f6461 ldrbvc r6, [pc], -r1, ror #8 - 3c: 65006e73 strvs r6, [r0, #-3699] ; 0xe73 - 40: 5f4e4f47 svcpl 0x004e4f47 - 44: 006e7376 rsbeq r7, lr, r6, ror r3 - 48: 75736552 ldrbvc r6, [r3, #-1362]! ; 0x552 - 4c: 765f656d ldrbvc r6, [pc], -sp, ror #10 - 50: 61006e73 tstvs r0, r3, ror lr - 54: 2f686372 svccs 0x00686372 - 58: 2f6d7261 svccs 0x006d7261 - 5c: 6863616d stmdavs r3!, {r0, r2, r3, r5, r6, r8, sp, lr}^ - 60: 6e75732d cdpvs 3, 7, cr7, cr5, cr13, {1} - 64: 702f6978 eorvc r6, pc, r8, ror r9 ; - 68: 7265776f rsbvc r7, r5, #29097984 ; 0x1bc0000 - 6c: 6f72622f svcvs 0x0072622f - 70: 65722f6d ldrbvs r2, [r2, #-3949]! ; 0xf6d - 74: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 - 78: 6165685f cmnvs r5, pc, asr r8 - 7c: 00632e64 rsbeq r2, r3, r4, ror #28 - 80: 706d756a rsbvc r7, sp, sl, ror #10 - 84: 736e695f cmnvc lr, #1556480 ; 0x17c000 - 88: 63757274 cmnvs r5, #1073741831 ; 0x40000007 - 8c: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3} - 90: 62757000 rsbsvs r7, r5, #0 - 94: 6165685f cmnvs r5, pc, asr r8 - 98: 69735f64 ldmdbvs r3!, {r2, r5, r6, r8, r9, sl, fp, ip, lr}^ - 9c: 7500657a strvc r6, [r0, #-1402] ; 0x57a - a0: 6769736e strbvs r7, [r9, -lr, ror #6]! - a4: 2064656e rsbcs r6, r4, lr, ror #10 - a8: 72616863 rsbvc r6, r1, #6488064 ; 0x630000 - ac: 6f682f00 svcvs 0x00682f00 - b0: 6c2f656d cfstr32vs mvfx6, [pc], #-436 ; ffffff04 <__bss_end+0xfffffe28> - b4: 616e6f65 cmnvs lr, r5, ror #30 - b8: 2f6f6472 svccs 0x006f6472 - bc: 6a6f7270 bvs 1bdca84 <__bss_end+0x1bdc9a8> - c0: 73746365 cmnvc r4, #-1811939327 ; 0x94000001 - c4: 61724f2f cmnvs r2, pc, lsr #30 - c8: 5065676e rsbpl r6, r5, lr, ror #14 - cc: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 - d0: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 - d4: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} - d8: 332d7875 teqcc sp, #7667712 ; 0x750000 - dc: 6d00342e cfstrsvs mvf3, [r0, #-184] ; 0xffffff48 - e0: 63696761 cmnvs r9, #25427968 ; 0x1840000 - e4: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 - e8: 34204320 strtcc r4, [r0], #-800 ; 0x320 - ec: 332e362e teqcc lr, #48234496 ; 0x2e00000 - f0: 31303220 teqcc r0, r0, lsr #4 - f4: 30323032 eorscc r3, r2, r2, lsr r0 - f8: 70282031 eorvc r2, r8, r1, lsr r0 - fc: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 - 100: 7361656c cmnvc r1, #452984832 ; 0x1b000000 - 104: 63002965 movwvs r2, #2405 ; 0x965 - 108: 6b636568 blvs 18d96b0 <__bss_end+0x18d95d4> - 10c: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 - 110: 6f687300 svcvs 0x00687300 - 114: 75207472 strvc r7, [r0, #-1138]! ; 0x472 - 118: 6769736e strbvs r7, [r9, -lr, ror #6]! - 11c: 2064656e rsbcs r6, r4, lr, ror #10 - 120: 00746e69 rsbseq r6, r4, r9, ror #28 - 124: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 - 128: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 - 12c: 6f687300 svcvs 0x00687300 - 130: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} - 134: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 - 138: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 13c: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 - 140: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 - 144: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 148: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ - 14c: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 150: 5f646165 svcpl 0x00646165 - 154: Address 0x00000154 is out of bounds. + 4: 6f2f0032 svcvs 0x002f0032 + 8: 762f7470 ; instruction: 0x762f7470 + c: 74616c6f strbtvc r6, [r1], #-3183 ; 0xc6f + 10: 5f656c69 svcpl 0x00656c69 + 14: 2f766e65 svccs 0x00766e65 + 18: 6a6f7270 bvs 1bdc9e0 <__bss_end+0x1bdc904> + 1c: 73746365 cmnvc r4, #-1811939327 ; 0x94000001 + 20: 6b616d2f blvs 185b4e4 <__bss_end+0x185b408> + 24: 72615f65 rsbvc r5, r1, #404 ; 0x194 + 28: 4f2f6165 svcmi 0x002f6165 + 2c: 676e6172 ; instruction: 0x676e6172 + 30: 2d495065 stclcs 0, cr5, [r9, #-404] ; 0xfffffe6c + 34: 6e72654b cdpvs 5, 7, cr6, cr2, cr11, {2} + 38: 6c2f6c65 stcvs 12, cr6, [pc], #-404 ; fffffeac <__bss_end+0xfffffdd0> + 3c: 78756e69 ldmdavc r5!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^ + 40: 342e332d strtcc r3, [lr], #-813 ; 0x32d + 44: 755f5f00 ldrbvc r5, [pc, #-3840] ; fffff14c <__bss_end+0xfffff070> + 48: 525f0038 subspl r0, pc, #56 ; 0x38 + 4c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 50: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 54: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 58: 00646165 rsbeq r6, r4, r5, ror #2 + 5c: 656c6966 strbvs r6, [ip, #-2406]! ; 0x966 + 60: 6165685f cmnvs r5, pc, asr r8 + 64: 73765f64 cmnvc r6, #400 ; 0x190 + 68: 656c006e strbvs r0, [ip, #-110]! ; 0x6e + 6c: 6874676e ldmdavs r4!, {r1, r2, r3, r5, r6, r8, r9, sl, sp, lr}^ + 70: 62757000 rsbsvs r7, r5, #0 + 74: 6165685f cmnvs r5, pc, asr r8 + 78: 73765f64 cmnvc r6, #400 ; 0x190 + 7c: 4765006e strbmi r0, [r5, -lr, rrx]! + 80: 765f4e4f ldrbvc r4, [pc], -pc, asr #28 + 84: 52006e73 andpl r6, r0, #1840 ; 0x730 + 88: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 8c: 73765f65 cmnvc r6, #404 ; 0x194 + 90: 7261006e rsbvc r0, r1, #110 ; 0x6e + 94: 612f6863 teqvs pc, r3, ror #16 + 98: 6d2f6d72 stcvs 13, cr6, [pc, #-456]! ; fffffed8 <__bss_end+0xfffffdfc> + 9c: 2d686361 stclcs 3, cr6, [r8, #-388]! ; 0xfffffe7c + a0: 786e7573 stmdavc lr!, {r0, r1, r4, r5, r6, r8, sl, ip, sp, lr}^ + a4: 6f702f69 svcvs 0x00702f69 + a8: 2f726577 svccs 0x00726577 + ac: 6d6f7262 sfmvs f7, 2, [pc, #-392]! ; ffffff2c <__bss_end+0xfffffe50> + b0: 7365722f cmnvc r5, #-268435454 ; 0xf0000002 + b4: 5f656d75 svcpl 0x00656d75 + b8: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + bc: 6a00632e bvs 18d7c <__bss_end+0x18ca0> + c0: 5f706d75 svcpl 0x00706d75 + c4: 74736e69 ldrbtvc r6, [r3], #-3689 ; 0xe69 + c8: 74637572 strbtvc r7, [r3], #-1394 ; 0x572 + cc: 006e6f69 rsbeq r6, lr, r9, ror #30 + d0: 5f627570 svcpl 0x00627570 + d4: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + d8: 7a69735f bvc 1a5ce5c <__bss_end+0x1a5cd80> + dc: 6e750065 cdpvs 0, 7, cr0, cr5, cr5, {3} + e0: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} + e4: 63206465 teqvs r0, #1694498816 ; 0x65000000 + e8: 00726168 rsbseq r6, r2, r8, ror #2 + ec: 6967616d stmdbvs r7!, {r0, r2, r3, r5, r6, r8, sp, lr}^ + f0: 4e470063 cdpmi 0, 4, cr0, cr7, cr3, {3} + f4: 20432055 subcs r2, r3, r5, asr r0 + f8: 2e362e34 mrccs 14, 1, r2, cr6, cr4, {1} + fc: 30322033 eorscc r2, r2, r3, lsr r0 + 100: 32303231 eorscc r3, r0, #268435459 ; 0x10000003 + 104: 28203130 stmdacs r0!, {r4, r5, r8, ip, sp} + 108: 72657270 rsbvc r7, r5, #7 + 10c: 61656c65 cmnvs r5, r5, ror #24 + 110: 00296573 eoreq r6, r9, r3, ror r5 + 114: 63656863 cmnvs r5, #6488064 ; 0x630000 + 118: 75735f6b ldrbvc r5, [r3, #-3947]! ; 0xf6b + 11c: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ + 120: 2074726f rsbscs r7, r4, pc, ror #4 + 124: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ + 128: 64656e67 strbtvs r6, [r5], #-3687 ; 0xe67 + 12c: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 + 130: 616c7000 cmnvs ip, r0 + 134: 726f6674 rsbvc r6, pc, #121634816 ; 0x7400000 + 138: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ + 13c: 2074726f rsbscs r7, r4, pc, ror #4 + 140: 00746e69 rsbseq r6, r4, r9, ror #28 + 144: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 + 148: 685f656d ldmdavs pc, {r0, r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 14c: 00646165 rsbeq r6, r4, r5, ror #2 + 150: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 + 154: 665f656d ldrbvs r6, [pc], -sp, ror #10 + 158: 5f656c69 svcpl 0x00656c69 + 15c: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + 160: Address 0x00000160 is out of bounds. Disassembly of section .comment: diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 95e41507..659d64b8 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -71,9 +71,9 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) .debug_line 0x00000000 0x7b .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o -.debug_str 0x00000000 0x156 - .debug_str 0x00000000 0x156 arch/arm/mach-sunxi/power/brom/resume_head.o - 0x16f (size before relaxing) +.debug_str 0x00000000 0x163 + .debug_str 0x00000000 0x163 arch/arm/mach-sunxi/power/brom/resume_head.o + 0x17c (size before relaxing) .comment 0x00000000 0x64 .comment 0x00000000 0x64 arch/arm/mach-sunxi/power/brom/resume_head.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod index a775ca0b..44e66785 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod @@ -1,2 +1,2 @@ -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers index 560c0339..90538e7d 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers @@ -1,21 +1,21 @@ -0x62c42e0c _mali_profiling_get_api_version /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xb9ac0503 mali_set_user_setting /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x94289922 mali_pmu_powerdown /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x2a7049ed mali_perf_set_num_pp_cores /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x0d8ccbae mali_dev_resume /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x7c2fb465 mali_dev_pause /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8224b12 mali_get_user_setting /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x428fd838 _mali_profiling_set_event /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xcdcdf6bf _mali_profiling_get_l2_counters /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x4580d143 _mali_profiling_control /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x706fc943 mali_pmu_powerup /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xdcd285aa _mali_profiling_get_mali_version /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x62c42e0c _mali_profiling_get_api_version /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xb9ac0503 mali_set_user_setting /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x94289922 mali_pmu_powerdown /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x2a7049ed mali_perf_set_num_pp_cores /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x0d8ccbae mali_dev_resume /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x7c2fb465 mali_dev_pause /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8224b12 mali_get_user_setting /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x428fd838 _mali_profiling_set_event /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xcdcdf6bf _mali_profiling_get_l2_counters /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x4580d143 _mali_profiling_control /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x706fc943 mali_pmu_powerup /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xdcd285aa _mali_profiling_get_mali_version /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod index 012fb665..ff0c4ad3 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod @@ -1,2 +1,2 @@ -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers index e6ba8765..c95c7fff 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers @@ -1,9 +1,9 @@ -0x8164b1cc ump_dd_handle_create_from_secure_id /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod index 67378809..ec462119 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod @@ -1,2 +1,2 @@ -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko -/home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /home/leonardo/projects/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko +/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o From d2642351d3e7a9a815e36e15409ea9b5ace4a816 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Fri, 16 Jun 2017 11:21:07 -0300 Subject: [PATCH 08/26] silent cpu budget --- linux-3.4/drivers/thermal/cpu_budget_cooling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-3.4/drivers/thermal/cpu_budget_cooling.c b/linux-3.4/drivers/thermal/cpu_budget_cooling.c index 6b4bb8c2..d2e55116 100755 --- a/linux-3.4/drivers/thermal/cpu_budget_cooling.c +++ b/linux-3.4/drivers/thermal/cpu_budget_cooling.c @@ -342,7 +342,7 @@ static int cpu_budget_apply_cooling(struct cpu_budget_cooling_device *cpu_budget if(instance->tz->temperature > temperature) temperature = instance->tz->temperature; } - pr_info("CPU Budget: Temperature: %u Limit state:%lu item[%d,%d,%d,%d %d]\n",temperature,cooling_state, + pr_debug("CPU Budget: Temperature: %u Limit state:%lu item[%d,%d,%d,%d %d]\n",temperature,cooling_state, cpu_budget_device->cluster0_freq_limit, cpu_budget_device->cluster0_num_limit , cpu_budget_device->cluster1_freq_limit , @@ -446,7 +446,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, { cpufreq_verify_within_limits(policy, min_freq, max_freq); policy->user_policy.max = policy->max; - pr_info("CPU Budget:update CPU %d cpufreq max to %lu min to %lu\n",policy->cpu,max_freq, min_freq); + pr_debug("CPU Budget:update CPU %d cpufreq max to %lu min to %lu\n",policy->cpu,max_freq, min_freq); } } return 0; From 35e3ac836234f7e15c4fcec8c3c4adb9eca6f72c Mon Sep 17 00:00:00 2001 From: lhelontra Date: Fri, 16 Jun 2017 13:32:11 -0300 Subject: [PATCH 09/26] vfe_v4l2 sets a input if input is -1 --- linux-3.4/drivers/media/video/sunxi-vfe/vfe.c | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c index af27c5bb..7c9c7ffa 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c @@ -503,7 +503,7 @@ static int isp_resource_request(struct vfe_dev *dev) dev->isp_tbl_addr[i].isp_gamma_tbl_paddr = (void*)(pa_base + ISP_GAMMA_MEM_OFS); dev->isp_tbl_addr[i].isp_gamma_tbl_dma_addr = (void*)(dma_base + ISP_GAMMA_MEM_OFS); dev->isp_tbl_addr[i].isp_gamma_tbl_vaddr = (void*)(va_base + ISP_GAMMA_MEM_OFS); - + dev->isp_tbl_addr[i].isp_linear_tbl_paddr = (void*)(pa_base + ISP_LINEAR_MEM_OFS); dev->isp_tbl_addr[i].isp_linear_tbl_dma_addr = (void*)(dma_base + ISP_LINEAR_MEM_OFS); dev->isp_tbl_addr[i].isp_linear_tbl_vaddr = (void*)(va_base + ISP_LINEAR_MEM_OFS); @@ -527,7 +527,7 @@ static int isp_resource_request(struct vfe_dev *dev) dev->isp_tbl_addr[i].isp_drc_tbl_paddr = (void*)(pa_base + ISP_DRC_MEM_OFS); dev->isp_tbl_addr[i].isp_drc_tbl_dma_addr = (void*)(dma_base + ISP_DRC_MEM_OFS); dev->isp_tbl_addr[i].isp_drc_tbl_vaddr = (void*)(va_base + ISP_DRC_MEM_OFS); - + dev->isp_tbl_addr[i].isp_disc_tbl_paddr = (void*)(pa_base + ISP_DISC_MEM_OFS); dev->isp_tbl_addr[i].isp_disc_tbl_dma_addr = (void*)(dma_base + ISP_DISC_MEM_OFS); dev->isp_tbl_addr[i].isp_disc_tbl_vaddr = (void*)(va_base + ISP_DISC_MEM_OFS); @@ -1803,7 +1803,7 @@ static enum v4l2_mbus_pixelcode *try_fmt_internal(struct vfe_dev *dev,struct v4l /*judge the resolution*/ if(f->fmt.pix.width > MAX_WIDTH || f->fmt.pix.height > MAX_HEIGHT) { - vfe_err("size is too large,automatically set to maximum!\n"); + // vfe_err("size is too large,automatically set to maximum!\n"); f->fmt.pix.width = MAX_WIDTH; f->fmt.pix.height = MAX_HEIGHT; } @@ -2342,13 +2342,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, isp_size[ROT_CH].width = 0; isp_fmt[ROT_CH] = PIX_FMT_NONE; } - + if(f->fmt.pix.subchannel != NULL) { dev->isp_gen_set_pt->double_ch_flag = 1; } else { dev->isp_gen_set_pt->double_ch_flag = 0; } - + //dev->buf_byte_size = bsp_isp_set_size(isp_fmt,&ob_black_size, &ob_valid_size, &isp_size[MAIN_CH],&isp_size[ROT_CH],&ob_start,&isp_size[SUB_CH]); size_settings.full_size = isp_size[MAIN_CH]; size_settings.scale_size = isp_size[SUB_CH]; @@ -2651,7 +2651,7 @@ static int vidioc_enum_input(struct file *file, void *priv, { struct vfe_dev *dev = video_drvdata(file); if (inp->index > dev->dev_qty-1) { - vfe_err("input index(%d) > dev->dev_qty(%d)-1 invalid!\n", inp->index, dev->dev_qty); + // vfe_err("input index(%d) > dev->dev_qty(%d)-1 invalid!\n", inp->index, dev->dev_qty); return -EINVAL; } if (0 == dev->device_valid_flag[inp->index]) { @@ -3172,8 +3172,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, ctrl->value = dev->ctrl_para.exp_auto_pri; break; case V4L2_CID_FOCUS_ABSOLUTE: - ctrl->value = CLIP(((dev->isp_3a_result_pt->real_vcm_pos - dev->isp_gen_set_pt->stat.vcm_cfg.vcm_min_code ) << 10) / - (dev->isp_gen_set_pt->stat.vcm_cfg.vcm_max_code - + ctrl->value = CLIP(((dev->isp_3a_result_pt->real_vcm_pos - dev->isp_gen_set_pt->stat.vcm_cfg.vcm_min_code ) << 10) / + (dev->isp_gen_set_pt->stat.vcm_cfg.vcm_max_code - dev->isp_gen_set_pt->stat.vcm_cfg.vcm_min_code ), 0, 1023); break; case V4L2_CID_FOCUS_RELATIVE: @@ -3940,7 +3940,19 @@ static int vfe_open(struct file *file) { vfe_print("vfe_open ok\n"); vfe_opened_num ++; + + if (dev->input == -1) { + int i; + for (i = 0; i < dev->dev_qty; i++) { + if (!dev->device_valid_flag[i]) break; + } + i -= 1; + ret = internal_s_input(dev , i); + if (!ret) vfe_print("vfe set a valid input %d\n", i); + } + } + return ret; } @@ -5180,7 +5192,7 @@ static int vfe_probe(struct platform_device *pdev) ret = bsp_mipi_csi_set_base_addr(dev->mipi_sel, 0); if(ret < 0) goto free_resource; - ret = bsp_mipi_dphy_set_base_addr(dev->mipi_sel, 0); + ret = bsp_mipi_dphy_set_base_addr(dev->mipi_sel, 0); if(ret < 0) goto free_resource; #endif @@ -5662,5 +5674,3 @@ module_exit(vfe_exit); MODULE_AUTHOR("raymonxiu"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Video front end driver for sunxi"); - - From 569e7cdbc324b53fdc310e1b3d44e75152b4726a Mon Sep 17 00:00:00 2001 From: lhelontra Date: Fri, 16 Jun 2017 17:08:52 -0300 Subject: [PATCH 10/26] small fixes --- linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c | 0 linux-3.4/drivers/media/video/sunxi-vfe/vfe.c | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) mode change 100755 => 100644 linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c old mode 100755 new mode 100644 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c index 7c9c7ffa..d36e0f07 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c @@ -102,6 +102,7 @@ module_param(act_slave,uint, S_IRUGO|S_IWUSR); module_param(define_sensor_list,uint, S_IRUGO|S_IWUSR); module_param(vfe_i2c_dbg,uint, S_IRUGO|S_IWUSR); module_param(vips,uint, S_IRUGO|S_IWUSR); + static ssize_t vfe_dbg_en_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -187,6 +188,7 @@ static ssize_t isp_reparse_flag_store(struct device *dev, } return count; } + static ssize_t vfe_dbg_dump_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -3946,7 +3948,7 @@ static int vfe_open(struct file *file) for (i = 0; i < dev->dev_qty; i++) { if (!dev->device_valid_flag[i]) break; } - i -= 1; + if (i > 0) i -= 1; ret = internal_s_input(dev , i); if (!ret) vfe_print("vfe set a valid input %d\n", i); } From 35de465def7699fab8842dbe549b807b4427d6c3 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 28 Jun 2017 11:32:18 -0300 Subject: [PATCH 11/26] small changes --- linux-3.4/drivers/media/video/sunxi-vfe/vfe.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c index d36e0f07..1afc9ed9 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c @@ -43,6 +43,7 @@ #include "platform/vfe_resource.h" #include "utility/sensor_info.h" #include "utility/vfe_io.h" + #define IS_FLAG(x,y) (((x)&(y)) == y) #define CLIP_MAX(x,max) ((x) > max ? max : x ) @@ -1949,10 +1950,12 @@ static enum v4l2_mbus_pixelcode *try_fmt_internal(struct vfe_dev *dev,struct v4l f->fmt.pix.width = ccm_fmt.width; f->fmt.pix.height = ccm_fmt.height; + f->fmt.pix.sizeimage = ccm_fmt.height * f->fmt.pix.bytesperline; vfe_dbg(0,"bus pixel code = %x at %s\n",*bus_pix_code,__func__); vfe_dbg(0,"pix->width = %d at %s\n",f->fmt.pix.width,__func__); vfe_dbg(0,"pix->height = %d at %s\n",f->fmt.pix.height,__func__); + vfe_dbg(0,"pix->sizeimage = %d at %s\n",f->fmt.pix.sizeimage,__func__); return bus_pix_code; } @@ -3052,7 +3055,8 @@ static int vidioc_queryctrl(struct file *file, void *priv, { if(qc->id != V4L2_CID_GAIN) { - vfe_warn("v4l2 sub device queryctrl unsuccess,id = %x!\n",qc->id); + vfe_dbg(0, "v4l2 sub device queryctrl unsuccess,id = %x!\n",qc->id); + } } } @@ -3950,7 +3954,7 @@ static int vfe_open(struct file *file) } if (i > 0) i -= 1; ret = internal_s_input(dev , i); - if (!ret) vfe_print("vfe set a valid input %d\n", i); + if (!ret) vfe_dbg(0, "vfe set a valid input %d\n", i); } } From 4d6432646b8b7156c8ae4ed2b1b009393ed0cd42 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 28 Jun 2017 11:32:46 -0300 Subject: [PATCH 12/26] * resolution 1280x720 in hres0 mode, of 5fps to 8fps. * resolution 1600x1200 in hres0 mode, quality improvements. * resolution 1600x1200 in hres1, runs at 10fps and fixed darkness frames. * fixes cropped cif resolution in hres3. * change hres name, 3 to 2 and 2 to 3. * added auto choose hres based on fps or/and resolution. * new hres modes: - hres=0 (640x480|1280x720|1600x1200 - 8 FPS) - hres=1 (800x600|1600x1200 - 10 FPS) - hres=2 (320x240|352x288|640x480 - 15 FPS) - hres=3 (320x240|640x480|800x600|1600x1200 - 20 FPS) --- .../media/video/sunxi-vfe/device/gc2035.c | 5775 ++++++++++++----- 1 file changed, 4142 insertions(+), 1633 deletions(-) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index 83b73da9..ddffa83a 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -14,21 +14,30 @@ #include #include - #include "camera.h" +static unsigned int mclk = 0; +module_param(mclk, uint, 0); +MODULE_PARM_DESC(mclk, +"mclk override (default=0)"); -MODULE_AUTHOR("raymonxiu / leonardo lontra"); -MODULE_DESCRIPTION("A low-level driver for GalaxyCore gc2035 sensors\n\t\tWorks fine with 800x600 / 640x480 / 320x240 @ 20fps"); -MODULE_LICENSE("GPL"); +static unsigned int frate = 0; +module_param(frate, uint, 0); +MODULE_PARM_DESC(frate, +"frate override (default=0)"); +MODULE_AUTHOR("raymonxiu"); +MODULE_AUTHOR("leonardo lontra"); +MODULE_AUTHOR("@lex"); +MODULE_DESCRIPTION("A low-level driver for GalaxyCore gc2035 sensors."); +MODULE_LICENSE("GPL"); //for internel driver debug -#define DEV_DBG_EN 0 -#if(DEV_DBG_EN == 1) +#define DEV_DBG_EN 0 +#if(DEV_DBG_EN == 1) #define vfe_dev_dbg(x,arg...) printk("[CSI_DEBUG][GC2035]"x,##arg) #else -#define vfe_dev_dbg(x,arg...) +#define vfe_dev_dbg(x,arg...) #endif #define vfe_dev_err(x,arg...) printk("[CSI_ERR][GC2035]"x,##arg) @@ -44,7 +53,7 @@ MODULE_LICENSE("GPL"); } //define module timing -#define MCLK (34*1000*1000) +int MCLK = 24; #define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH #define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH #define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING @@ -67,15 +76,17 @@ MODULE_LICENSE("GPL"); /* * Our nominal (default) frame rate. */ -#define SENSOR_FRAME_RATE 20 - - - +int SENSOR_FRAME_RATE; +int N_WIN_SIZES; +static struct regval_list *sensor_default_regs; +static struct sensor_win_size *sensor_win_sizes; +int hres = 0; +struct sensor_resolutions_struct; /* * The gc2035 sits on i2c with ID 0x78 */ -#define I2C_ADDR 0x78 -#define SENSOR_NAME "gc2035" +#define I2C_ADDR 0x78 +#define SENSOR_NAME "gc2035" /* * Information we maintain about a known sensor. */ @@ -91,940 +102,3325 @@ static inline struct sensor_info *to_state(struct v4l2_subdev *sd) return container_of(sd, struct sensor_info, sd); } - - /* - * The default register settings + * The registers settings * */ + static struct regval_list sensor_default_regs_hres0[] = + { + {0xfe,0x80}, + {0xfe,0x80}, + {0xfe,0x80}, + {0xfc,0x06}, + {0xf9,0xfe}, //[0] pll enable + {0xfa,0x00}, + {0xf6,0x00}, + {0xf7,0x17}, //pll enable + {0xf8,0x00}, + {0xfe,0x00}, + {0x82,0x00}, + {0xb3,0x60}, + {0xb4,0x40}, + {0xb5,0x60}, + {0x03,0x05}, + {0x04,0x2e}, + + //measure window + {0xfe,0x00}, + {0xec,0x04}, + {0xed,0x04}, + {0xee,0x60}, + {0xef,0x90}, + + {0x0a,0x00}, //row start + {0x0c,0x02}, //col start + + {0x0d,0x04}, + {0x0e,0xc0}, + {0x0f,0x06}, //Window setting + {0x10,0x58},// + + {0x17,0x14}, //[0]mirror [1]flip + {0x18,0x0a}, //sdark 4 row in even frame?? + {0x19,0x0a}, //AD pipe number + + {0x1a,0x01}, //CISCTL mode4 + {0x1b,0x48}, + {0x1e,0x88}, //analog mode1 [7] tx-high en + {0x1f,0x0f}, //analog mode2 + + {0x20,0x05}, //[0]adclk mode [1]rowclk_MODE [2]rsthigh_en + {0x21,0x0f}, //[3]txlow_en + {0x22,0xf0}, //[3:0]vref + {0x23,0xc3}, //f3//ADC_r + {0x24,0x16}, //pad drive + + //==============================aec + //AEC + {0xfe,0x01}, + {0x09,0x00}, + + {0x11,0x10}, + {0x47,0x30}, + {0x0b,0x90}, + {0x13,0x80}, //0x75 + {0x1f,0xc0},//addd + {0x20,0x50},//add 0x60 + {0xfe,0x00}, + {0xf7,0x17}, //pll enable + {0xf8,0x00}, + {0x05,0x01}, + {0x06,0x18}, + {0x07,0x00}, + {0x08,0x48}, + {0xfe,0x01}, + {0x27,0x00}, + {0x28,0x6a}, + {0x29,0x03}, + {0x2a,0x50},//8fps + {0x2b,0x04}, + {0x2c,0xf8}, + {0x2d,0x06}, + {0x2e,0xa0},//6fps + {0x3e,0x40},//0x40 + {0xfe,0x00}, + {0xb6,0x03}, //AEC enable + {0xfe,0x00}, + + ///////BLK + {0x3f,0x00}, //prc close??? + {0x40,0xa7}, // a7 77 + {0x42,0x7f}, + {0x43,0x30},//0x30 + + {0x5c,0x08}, + //{0x6c 3a //manual_offset ,real B channel + //{0x6d 3a//manual_offset ,real B channel + //{0x6e 36//manual_offset ,real R channel + //{0x6f 36//manual_offset ,real R channel + {0x5e,0x20}, + {0x5f,0x20}, + {0x60,0x20}, + {0x61,0x20}, + {0x62,0x20}, + {0x63,0x20}, + {0x64,0x20}, + {0x65,0x20}, + {0x66,0x20}, + {0x67,0x20}, + {0x68,0x20}, + {0x69,0x20}, + + /////crop// + {0x90,0x01}, //crop enable + {0x95,0x04}, //1600x1200 + {0x96,0xb0}, + {0x97,0x06}, + {0x98,0x40}, + + {0xfe,0x03}, + {0x42,0x80}, + {0x43,0x06}, //output buf width //buf widthÕâÒ»¿éµÄÅäÖû¹ÃèÒªžãÇå³þ + {0x41,0x00}, // delay + {0x40,0x00}, //fifo half full trig + {0x17,0x01}, //wid mipi²¿·ÖµÄ·ÖƵÊÇΪʲÎv£¿ + {0xfe,0x00}, + + {0x80,0xff},//block enable 0xff + {0x81,0x26},//38 //skin_Y 8c_debug + + {0x03,0x05}, + {0x04,0x2e}, + {0x84,0x00}, //output put foramat + {0x86,0x03}, //sync plority + {0x87,0x80}, //middle gamma on + {0x8b,0xbc},//debug modeÃèÒªžãÇå³þһà+ {0xa7,0x80},//B_channel_gain + {0xa8,0x80},//B_channel_gain + {0xb0,0x80}, //globle gain + {0xc0,0x40}, -static struct regval_list sensor_default_regs[] = { -{0xfe , 0x80}, -{0xfe , 0x80}, -{0xfe , 0x80}, -{0xfc , 0x06}, -{0xf2 , 0x00}, -{0xf3 , 0x00}, -{0xf4 , 0x00}, -{0xf5 , 0x00}, -{0xf9 , 0xfe}, //[0] pll enable -{0xfa , 0x00}, -{0xf6 , 0x00}, -{0xf7 , 0x15}, //pll enable - -{0xf8 , 0x85}, - -{0xfe , 0x00}, -{0x82 , 0x00}, //00 -{0xb3 , 0x60}, //60 -{0xb4 , 0x40}, //60 40 -{0xb5 , 0x60}, //60 - -{0x03 , 0x02}, -{0x04 , 0x80}, - -//////////measure window /////////// -{0xfe , 0x00}, -{0xec , 0x06},//04 -{0xed , 0x06},//04 -{0xee , 0x62},//60 -{0xef , 0x92},//90 - -///////////analog///////////// -{0x0a , 0x00}, //row start -{0x0b , 0x10}, //row start -{0x0c , 0x00}, //col start -{0x0d , 0x04}, //4d0 = 1232 -{0x0e , 0xe0}, //d0/b0/d0/c0 -{0x0f , 0x06}, //Window setting -{0x10 , 0x58}, //40/50/58 -{0x17 , 0x14}, //[0]mirror [1]flip [4]better colour - - -//{0x18 , 0x0a}, //0a 2012.10.26 -{0x18 , 0x0f}, //0a 2012.10.26 -{0x19 , 0x0a}, //AD pipe number - -{0x1a , 0x01}, //CISCTL mode4 -{0x1b , 0x8b}, -{0x1c , 0x05}, //added -{0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias -{0x1f , 0x08}, //[3] tx-low en// -{0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en -{0x21 , 0x0f}, //[6:4]rsg -{0x22 , 0xf0}, //[3:0]vref 0xf0 -{0x23 , 0xc3}, //f3//ADC_r -{0x24 , 0x17}, //pad drive <=36MHz, use 0x00 is ok - -//AEC -{0xfe , 0x01}, -{0x11 , 0x20},//20 AEC_out_slope , 0x -{0x1f , 0xc0},//80 max_post_gain -{0x20 , 0x60},//40 max_pre_gain -{0x47 , 0x80},//30 AEC_outdoor_th -{0x0b , 0x13},//10 -{0x13 , 0x75},//y_target -{0xfe , 0x00}, - -{0xfe , 0x00}, -{0xfe , 0x00}, -{0x05 , 0x01},//hb -{0x06 , 0x0d}, -{0x07 , 0x00},//vb -{0x08 , 0x40}, - -{0xfe , 0x01}, -{0x27 , 0x00},//step -{0x28 , 0xa0},//a0 -{0x29 , 0x05},// level 0 12.5 -{0x2a , 0x00}, -{0x2b , 0x05},// level 1 12.5 -{0x2c , 0x00}, -{0x2d , 0x05},// level 2 12.5 640/10fps -{0x2e , 0x00}, -{0x2f , 0x08},// level 3 7.5 -{0x30 , 0x20}, - -{0xfe , 0x00}, -{0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x -{0xb6 , 0x03}, //AEC enable -{0xfe , 0x00}, - -/////////BLK////// -{0x3f, 0x00}, //prc close -{0x40, 0x77},// -{0x42, 0x7f}, -{0x43, 0x30}, -{0x5c, 0x08}, -{0x5e, 0x20}, -{0x5f, 0x20}, -{0x60, 0x20}, -{0x61, 0x20}, -{0x62, 0x20}, -{0x63, 0x20}, -{0x64, 0x20}, -{0x65, 0x20}, - -///block//////////// -{0x80 , 0xff}, -{0x81 , 0x26},//38 , 0x//skin_Y 8c_debug -{0x87 , 0x90}, //[7]middle gamma -{0x84 , 0x02}, //output put foramat -{0x86 , 0x07}, //02 //sync plority -{0x8b , 0xbc}, -{0xb0 , 0x80}, //globle gain -{0xc0 , 0x40},//Yuv bypass - -//////lsc///////////// -{0xfe,0x01}, -{0xc2,0x21}, -{0xc3,0x1a}, -{0xc4,0x13}, -{0xc8,0x17}, -{0xc9,0x0f}, -{0xca,0x00}, -{0xbc,0x36}, -{0xbd,0x2b}, -{0xbe,0x17}, -{0xb6,0x39}, -{0xb7,0x21}, -{0xb8,0x1c}, -{0xc5,0x00}, -{0xc6,0x00}, -{0xc7,0x00}, -{0xcb,0x00}, -{0xcc,0x0c}, -{0xcd,0x15}, -{0xbf,0x00}, -{0xc0,0x00}, -{0xc1,0x00}, -{0xb9,0x00}, -{0xba,0x00}, -{0xbb,0x00}, -{0xaa,0x15}, -{0xab,0x15}, -{0xac,0x15}, -{0xad,0x14}, -{0xae,0x13}, -{0xaf,0x12}, -{0xb0,0x1b}, -{0xb1,0x14}, -{0xb2,0x14}, -{0xb3,0x1f}, -{0xb4,0x12}, -{0xb5,0x13}, -{0xd0,0x00}, -{0xd2,0x00}, -{0xd3,0x0c}, -{0xd8,0x00}, -{0xda,0x00}, -{0xdb,0x13}, -{0xdc,0x00}, -{0xde,0x00}, -{0xdf,0x25}, -{0xd4,0x00}, -{0xd6,0x00}, -{0xd7,0x12}, -{0xa4,0x00}, -{0xa5,0x00}, -{0xa6,0x00}, -{0xa7,0x00}, -{0xa8,0x00}, -{0xa9,0x00}, -{0xa1,0x80}, -{0xa2,0x80}, - -//////////cc////////////// -{0xfe , 0x02}, -{0xc0 , 0x01}, -{0xc1 , 0x40}, //Green_cc for d -{0xc2 , 0xfc}, -{0xc3 , 0x05}, -{0xc4 , 0xec}, -{0xc5 , 0x42}, -{0xc6 , 0xf8}, -{0xc7 , 0x40},//for cwf -{0xc8 , 0xf8}, -{0xc9 , 0x06}, -{0xca , 0xfd}, -{0xcb , 0x3e}, -{0xcc , 0xf3}, -{0xcd , 0x36},//for A -{0xce , 0xf6}, -{0xcf , 0x04}, -{0xe3 , 0x0c}, -{0xe4 , 0x44}, -{0xe5 , 0xe5}, -{0xfe , 0x00}, - -///////awb start //////////////// -//AWB clear -{0xfe , 0x01}, -{0x4f , 0x00}, -{0x4d , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x10}, // 10 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x20}, // 20 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x30}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, // 30 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x40}, // 40 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x50}, // 50 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x60}, // 60 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x70}, // 70 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x80}, // 80 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0x90}, // 90 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0xa0}, // a0 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0xb0}, // b0 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0xc0}, // c0 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4d , 0xd0}, // d0 -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4e , 0x00}, -{0x4f , 0x01}, -/////// awb value//////// -{0xfe , 0x01}, -{0x4f , 0x00}, -{0x4d , 0x30}, -{0x4e , 0x00}, -{0x4e , 0x80}, -{0x4e , 0x80}, -{0x4e , 0x02}, -{0x4e , 0x02}, -{0x4d , 0x40}, -{0x4e , 0x00}, -{0x4e , 0x80}, -{0x4e , 0x80}, -{0x4e , 0x02}, -{0x4e , 0x02}, -{0x4e , 0x02}, -{0x4d , 0x53}, -{0x4e , 0x08}, -{0x4e , 0x04}, -{0x4d , 0x62}, -{0x4e , 0x10}, -{0x4d , 0x72}, -{0x4e , 0x20}, -{0x4f , 0x01}, - -/////awb//// -{0xfe , 0x01}, -{0x50 , 0x88},//c0//[6]green mode -{0x52 , 0x40}, -{0x54 , 0x60}, -{0x56 , 0x06}, -{0x57 , 0x20}, //pre adjust -{0x58 , 0x01}, -{0x5b , 0x02}, //AWB_gain_delta -{0x61 , 0xaa},//R/G stand -{0x62 , 0xaa},//R/G stand -{0x71 , 0x00}, -{0x74 , 0x10}, //0x//AWB_C_max -{0x77 , 0x08}, // 0x//AWB_p2_x -{0x78 , 0xfd}, //AWB_p2_y -{0x86 , 0x30}, -{0x87 , 0x00}, -{0x88 , 0x04},//06 , 0x//[1]dark mode -{0x8a , 0xc0},//awb move mode -{0x89 , 0x75}, -{0x84 , 0x08}, //0x//auto_window -{0x8b , 0x00}, // 0x//awb compare luma -{0x8d , 0x70}, //awb gain limit R -{0x8e , 0x70},//G -{0x8f , 0xf4},//B -{0xfe , 0x00}, -{0x82 , 0x02},//awb_en -/////////awb end ///////////// - -///==========asde -{0xfe, 0x01}, -{0x21, 0xbf}, -{0xfe, 0x02}, -{0xa4, 0x00},// -{0xa5, 0x40}, //lsc_th -{0xa2, 0xa0}, //lsc_dec_slope -{0x86, 0x27},//add for DPC travis 20140505 -{0x8a, 0x33},//add for DPC travis 20140505 -{0x8d, 0x85},//add for DPC travis 20140505 -{0xa6, 0xf0},//80//change for DPC travis 20140505 -{0xa7, 0x80}, //ot_th -{0xab, 0x31}, // -{0xa9, 0x6f}, // -{0xb0, 0x99}, //0x//edge effect slope low -{0xb1, 0x34},//edge effect slope low -{0xb3, 0x80}, //saturation dec slope -{0xde, 0xb6}, // -{0x38, 0x0f}, // -{0x39, 0x60}, // -{0xfe, 0x00}, -{0x81, 0x26}, -{0xfe, 0x02}, -{0x83, 0x00},// -{0x84, 0x45},// -////////////YCP////////// -{0xd1 , 0x34},//saturation_cb -{0xd2 , 0x34},//saturation_Cr -{0xd3 , 0x40},//contrast ? {0xd4 , 0x80},//contrast center -{0xd4 , 0x80},//contrast center -{0xd5 , 0x00},//luma_offset -{0xdc , 0x30}, -{0xdd , 0xb8},//edge_sa_g,b -{0xfe , 0x00}, -///////dndd/////////// -{0xfe , 0x02}, -{0x88 , 0x15},//dn_b_base -{0x8c , 0xf6}, //[2]b_in_dark_inc -{0x89 , 0x03}, //dn_c_weight -////////EE /////////// -{0xfe , 0x02}, -{0x90 , 0x6c},// EEINTP mode1 -{0x97 , 0x45},// edge effect -////==============RGB Gamma -{0xfe , 0x02}, -{0x15 , 0x0a}, -{0x16 , 0x12}, -{0x17 , 0x19}, -{0x18 , 0x1f}, -{0x19 , 0x2c}, -{0x1a , 0x38}, -{0x1b , 0x42}, -{0x1c , 0x4e}, -{0x1d , 0x63}, -{0x1e , 0x76}, -{0x1f , 0x87}, -{0x20 , 0x96}, -{0x21 , 0xa2}, -{0x22 , 0xb8}, -{0x23 , 0xca}, -{0x24 , 0xd8}, -{0x25 , 0xe3}, -{0x26 , 0xf0}, -{0x27 , 0xf8}, -{0x28 , 0xfd}, -{0x29 , 0xff}, - -///=================y gamma -{0xfe , 0x02}, -{0x2b , 0x00}, -{0x2c , 0x04}, -{0x2d , 0x09}, -{0x2e , 0x18}, -{0x2f , 0x27}, -{0x30 , 0x37}, -{0x31 , 0x49}, -{0x32 , 0x5c}, -{0x33 , 0x7e}, -{0x34 , 0xa0}, -{0x35 , 0xc0}, -{0x36 , 0xe0}, -{0x37 , 0xff}, -/////1600x1200size// -{0xfe, 0x00},// -{0x90, 0x01}, //0x//crop enable -{0x94, 0x04}, -{0x95, 0x04}, //0x//1600x1200 -{0x96, 0xb0}, -{0x97, 0x06}, -{0x98, 0x40}, - -{0xfe , 0x03}, -{0x40 , 0x40}, //00 -{0x41 , 0x02}, // Pclk_polarity -{0x42 , 0x40}, -{0x43 , 0x06}, //output buf width -{0x17 , 0x01}, //widv -{0xfe , 0x00}, - -////output DVP///// -{0xfe , 0x00}, -{0x82 , 0xfe}, // fe -{0xf2 , 0x70}, -{0xf3 , 0xff}, -{0xf4 , 0x00}, -{0xf5 , 0x30}, - -#if 1 -///////// re zao/// -{0xfe , 0x00}, -{0x22 , 0xf0}, -{0xfe , 0x01}, -{0x21 , 0xff}, -{0xfe , 0x02}, -{0x8a , 0x33}, -{0x8c , 0x76}, -{0x8d , 0x85}, -{0xa6 , 0xf0}, -{0xae , 0x9f}, -{0xa2 , 0x90}, -{0xa5 , 0x40}, -{0xa7 , 0x30}, -{0xb0 , 0x88}, -{0x38 , 0x0b}, -{0x39 , 0x30}, -{0xfe , 0x00}, - -{0x87 , 0xb0}, - -//// small RGB gamma//// -/* -{0xfe , 0x02}, -{0x15 , 0x0b}, -{0x16 , 0x0e}, -{0x17 , 0x10}, -{0x18 , 0x12}, -{0x19 , 0x19}, -{0x1a , 0x21}, -{0x1b , 0x29}, -{0x1c , 0x31}, -{0x1d , 0x41}, -{0x1e , 0x50}, -{0x1f , 0x5f}, -{0x20 , 0x6d}, -{0x21 , 0x79}, -{0x22 , 0x91}, -{0x23 , 0xa5}, -{0x24 , 0xb9}, -{0x25 , 0xc9}, -{0x26 , 0xe1}, -{0x27 , 0xee}, -{0x28 , 0xf7}, -{0x29 , 0xff}, -*/ -////dark sun///// -{0xfe , 0x02}, -{0x40 , 0x06}, -{0x41 , 0x23}, -{0x42 , 0x3f}, -{0x43 , 0x06}, -{0x44 , 0x00}, -{0x45 , 0x00}, -{0x46 , 0x14}, -{0x47 , 0x09}, -{0xfe , 0x00}, + #if 1 + //lsc, + {0xfe,0x01}, + {0xc2,0x10},//0x1f + {0xc3,0x02},//0x07 + {0xc4,0x03},//0x03 + {0xc8,0x10},//10 + {0xc9,0x0a},//0x0a + {0xca,0x08},//0x08 + {0xbc,0x16},// 3c + {0xbd,0x10},//0x1c + {0xbe,0x10},//0x1a + {0xb6,0x22},// 0x30 + {0xb7,0x18},//0x1c + {0xb8,0x15},//0x15 + {0xc5,0x00}, + {0xc6,0x00}, + {0xc7,0x00}, + {0xcb,0x00}, + {0xcc,0x00}, + {0xcd,0x00}, + {0xbf,0x0a},//0x0c + {0xc0,0x01},//0x04 + {0xc1,0x00}, + {0xb9,0x00}, + {0xba,0x00}, + {0xbb,0x00}, + {0xaa,0x00}, + {0xab,0x02},//00 + {0xac,0x00}, + {0xad,0x00}, + {0xae,0x00}, + {0xaf,0x00}, + {0xb0,0x00}, + {0xb1,0x00}, + {0xb2,0x00}, + {0xb3,0x00}, + {0xb4,0x02},//00 + {0xb5,0x00}, + {0xd0,0x01}, + {0xd2,0x02},//00 + {0xd3,0x00}, + {0xd8,0x18}, + {0xda,0x00}, + {0xdb,0x04}, + {0xdc,0x00}, + {0xde,0x07},//0x07 + {0xdf,0x00}, + {0xd4,0x00}, + {0xd6,0x00},//00 + {0xd7,0x00}, + {0xa4,0x20},//00 + {0xa5,0x02},//00 + {0xa6,0x04}, + {0xa7,0x00}, + {0xa8,0x20},//00 + {0xa9,0x02},//00 + {0xa1,0x80}, + {0xa2,0x80}, + + {0xfe,0x02}, + {0xa4,0x00}, + {0xfe,0x00}, + + {0xfe,0x02}, + {0xc0,0x01}, + {0xc1,0x40}, //Green_cc + {0xc2,0xfc}, + {0xc3,0x05}, + {0xc4,0xec}, + {0xc5,0x42}, + {0xc6,0xf8}, + {0xc7,0x40}, + {0xc8,0xf8}, + {0xc9,0x06}, + {0xca,0xfd}, + {0xcb,0x3e}, + {0xcc,0xf3}, + {0xcd,0x36}, + {0xce,0xf6}, + {0xcf,0x04}, + {0xe3,0x0c}, + {0xe4,0x44}, + {0xe5,0xe5}, + {0xfe,0x00}, + {0xfe,0x00}, + //awb + {0xfe,0x01}, + {0x4f,0x00}, + {0x4d,0x10}, ////////////////10 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x20}, ///////////////20 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x30}, //////////////////30 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x02}, // d65 + {0x4e,0x04}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x40}, //////////////////////40 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, //cwf + {0x4e,0x08}, // cwf + {0x4e,0x04}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x50}, //////////////////50 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x10}, // tl84 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x60}, /////////////////60 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x70}, ///////////////////70 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x20}, // a + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x80}, /////////////////////80 + {0x4e,0x00}, //H + {0x4e,0x40}, // h + {0x4e,0x00}, //A + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0x90}, //////////////////////90 + {0x4e,0x00}, // h + {0x4e,0x40}, + {0x4e,0x40}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xa0}, /////////////////a0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xb0}, //////////////////////////////////b0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xc0}, //////////////////////////////////c0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xd0}, ////////////////////////////d0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xe0}, /////////////////////////////////e0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4d,0xf0}, /////////////////////////////////f0 + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4e,0x00}, + {0x4f,0x01}, + #endif + {0xfe,0x01}, + {0x50,0x88}, + {0x52,0x40}, + {0x54,0x60}, + {0x56,0x06}, + {0x57,0x20}, //pre adjust + {0x58,0x01}, + {0x5c,0xf0}, + {0x5d,0x40}, + {0x5b,0x02}, //AWB_gain_delta + {0x61,0xaa},//R/G stand + {0x62,0xaa},//R/G stand + {0x71,0x00}, + {0x74,0x10}, //AWB_C_max + {0x77,0x08}, //AWB_p2_x + {0x78,0xfd}, //AWB_p2_y + {0x86,0x30}, + {0x87,0x00}, + {0x88,0x06},//04 + {0x8a,0x8a},//awb move mode + {0x89,0x75}, + {0x84,0x08}, //auto_window + {0x8b,0x00}, //awb compare luma + {0x8d,0x70}, //awb gain limit R + {0x8e,0x70},//G + {0x8f,0xf4},//B + {0x5e,0xa4}, + {0x5f,0x60}, + {0x92,0x58}, + {0xfe,0x00}, + {0x82,0x02},//awb_en + + //{0xfe ,0xec}, luma_value + {0xfe,0x01}, + {0x1e,0xf1}, + {0x9c,0x00}, //add abs slope 0x02 + {0x21,0xbf}, + {0xfe,0x02}, + {0xa5,0x60}, //lsc_th //40 + {0xa2,0xc0}, //lsc_dec_slope 0xa0 + {0xa3,0x30}, //when total gain is bigger than the value, enter dark light mode 0x20 added + {0xa4,0x00},//add + {0xa6,0x50}, //dd_th + {0xa7,0x80}, //ot_th 30 + {0xab,0x31}, //[0]b_dn_effect_dark_inc_or_dec + {0x88,0x15}, //[5:0]b_base + {0xa9,0x6c}, //[7:4] ASDE_DN_b_slope_high 0x6c 0x6f + + {0xb0,0x66}, //6edge effect slope 0x66 0x88 0x99 + + {0xb3,0x70}, //saturation dec slope //0x70 0x40 + {0xb4,0x32},//0x32 0x42 + {0x8c,0xf6}, //[2]b_in_dark_inc + {0x89,0x03}, //dn_c_weight 0x03 + + {0xde,0xb8}, //b6[7]asde_autogray [3:0]auto_gray_value 0xb9 0xb8 0xb9 + {0x38,0x06}, //0aasde_autogray_slope 0x08 0x05 0x06 0x0a + {0x39,0x50}, //50asde_autogray_threshold 0x50 0x30 + + {0xfe,0x00}, + {0x81,0x24}, //0x26 + {0x87,0x90}, //[5:4]first_dn_en first_dd_en enable 0x80 0xb0 + + {0xfe,0x02}, + {0x83,0x00},//[6]green_bks_auto [5]gobal_green_bks + {0x84,0x45},//RB offset + {0xd1,0x38}, //saturation_cb 0x3a + {0xd2,0x38}, //saturation_Cr 0x38 + {0xd3,0x30}, + {0xdc,0x30}, + {0xdd,0xb8}, //edge_sa_g,b + {0xfe,0x00}, + {0xad,0x80},//80 + {0xae,0x7d},//80 + {0xaf,0x80}, + + //gmma-curve4-low strech + {0xfe,0x02}, + {0x15,0x05}, + {0x16,0x0b}, + {0x17,0x10}, + {0x18,0x16}, + {0x19,0x24}, + {0x1a,0x32}, + {0x1b,0x42}, + {0x1c,0x4e}, + {0x1d,0x64}, + {0x1e,0x76}, + {0x1f,0x86}, + {0x20,0x94}, + {0x21,0x9f}, + {0x22,0xb4}, + {0x23,0xc3}, + {0x24,0xce}, + {0x25,0xd7}, + {0x26,0xe3}, + {0x27,0xec}, + {0x28,0xf7}, + {0x29,0xff}, + + //y-gamma + {0x2b,0x00}, + {0x2c,0x04}, + {0x2d,0x09}, + {0x2e,0x18}, + {0x2f,0x27}, + {0x30,0x37}, + {0x31,0x49}, + {0x32,0x5c}, + {0x33,0x7e}, + {0x34,0xa0}, + {0x35,0xc0}, + {0x36,0xe0}, + {0x37,0xff}, + {0xfe,0x00}, + + {0xfe,0x00}, + + {0x82,0xfe}, + //sleep 400 + {0xf2,0x70}, + {0xf3,0xff}, + {0xf4,0x00}, + {0xf5,0x30}, + {0xfe,0x01}, + {0x0b,0x90}, + {0x87,0x00},//0x10 + {0xfe,0x00}, + + /////,0xup},date + //ÈÈ?0x }, + {0xfe,0x02}, + {0xa6,0x80}, //dd_th + {0xa7,0x60}, //ot_th //0x80 + {0xa9,0x66}, //6f[7:4] ASDE_DN_b_slope_high 0x68 + {0xb0,0x88}, //edge effect slope 0x99 + {0x38,0x08}, //asde_autogray_slope 0x08 0x0f 0x0a 0b + {0x39,0x50}, //asde_autogray_threshold 0x60 + {0xfe,0x00}, + {0x87,0x90}, //[5:4]first_dn_en first_dd_en 0x90 + + {0xfe,0x00}, + {0x90,0x01}, + {0x95,0x01}, + {0x96,0xe0}, + {0x97,0x02}, + {0x98,0x80}, + {0xc8,0x14}, + {0xf7,0x0D}, + {0xf8,0x83}, + {0xfa,0x00},//pll=4 + {0x05,0x00}, + {0x06,0xc4}, + {0x07,0x00}, + {0x08,0xae}, + {0xad,0x80}, + {0xae,0x7a}, + {0xaf,0x7a}, + {0xfe,0x01}, + {0x27,0x00}, + {0x28,0xe5}, + {0x29,0x05}, + {0x2a,0x5e},//18fps + {0x2b,0x07}, + {0x2c,0x28},//12.5fps + {0x2d,0x0a}, + {0x2e,0xbc},//8fps + {0x3e,0x40},// exposure level + {0xfe,0x03}, + {0x42,0x04}, + {0x43,0x05}, //output buf width + {0x41,0x02}, // delay + {0x40,0x40}, //fifo half full trig + {0x17,0x00}, //widv is 0 + {0xfe,0x00}, + {0xc8,0x55}, + }; + + /* 1600X1200 UXGA capture */ + static struct regval_list sensor_uxga_regs_hres0[] = + { + {0xfe , 0x00}, + {0x0a , 0x00}, //row start + {0x0c , 0x00}, //col start + + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, //Window setting + {0x10 , 0x58},// + + {0x90 , 0x01}, //crop enable + {0x94 , 0x04},//add + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + {0x99 , 0x11}, + {0xc8 , 0x00}, + + {0xfa , 0x11}, + + {0xfe , 0x03}, + {0x42 , 0x80}, + {0x43 , 0x06}, //output buf width + {0x41 , 0x00}, // delay + {0x40 , 0x00}, //fifo half full trig + {0x17 , 0x01}, //widv + {0xfe , 0x00}, + {0xc8 , 0x00}, + }; + + /* 1280X720 720HD */ + static struct regval_list Gc2015_sensor_hd720_regs_hres0[] = + { + {0xfe , 0x00}, + {0x05, 0x01}, + {0x06, 0x9e}, + {0x07, 0x01}, + {0x08, 0x6d}, + {0x0a , 0xf0}, //row start + {0x0c , 0xa0}, //col start + {0x0d , 0x02}, + {0x0e , 0xd8}, + {0x0f , 0x05}, //Window setting + {0x10 , 0x18}, -#endif -}; + {0xfe, 0x01}, + {0x27, 0x00}, + {0x28, 0xd9}, + {0x29, 0x04}, + {0x2a, 0x3d},//18fps + {0x2b, 0x06}, + {0x2c, 0xc8},//12.5fps + {0x2d, 0x0a}, + {0x2e, 0x2c},//8fps + {0x3e, 0x40},//0x40 0x00 + + //measure window + {0xfe, 0x00}, + {0xec, 0x04}, + {0xed, 0x04}, + {0xee, 0x50}, + {0xef, 0x58}, + + {0x90 , 0x01}, //crop enable + {0x95 , 0x02}, + {0x96 , 0xd0}, + {0x97 , 0x05}, + {0x98 , 0x00}, + + {0xfe , 0x03}, + {0x42 , 0x80}, + {0x43 , 0x06}, //output buf width + {0x41 , 0x00}, // delay + {0x40 , 0x00}, //fifo half full trig + {0x17 , 0x01}, //widv + {0xfe , 0x00}, + {0x99, 0x11}, + {0xc8, 0x00}, + {0xfa, 0x11}, + {0xff, 0xff}, + }; + + /* 640X480 VGA */ + static struct regval_list sensor_vga_regs_hres0[] = + { + {0xfe , 0x00}, + + {0x0a , 0x00}, //row start + {0x0c , 0x00}, //col start + + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, //Window setting + {0x10 , 0x58},// + + {0x90 , 0x01}, + {0x94 , 0x00}, + {0x95 , 0x01}, + {0x96 , 0xe0}, + {0x97 , 0x02}, + {0x98 , 0x80}, + {0xc8 , 0x15}, + + {0xfa , 0x00}, + + {0xfe , 0x03}, + {0x42 , 0x00}, + {0x43 , 0x05}, //output buf width 280*2=500 + {0x41 , 0x02}, // delay + {0x40 , 0x40}, //fifo half full trig + {0x17 , 0x00}, //widv is 0 + + {0xfe , 0x00}, + {0xc8 , 0x55}, + {0xb6 , 0x03},//aec on + }; + + static struct regval_list sensor_default_regs_hres1[] = { + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfc , 0x06}, + {0xf2 , 0x00}, + {0xf3 , 0x00}, + {0xf4 , 0x00}, + {0xf5 , 0x00}, + {0xf9 , 0xfe}, //[0] pll enable + {0xfa , 0x00}, + {0xf6 , 0x00}, + {0xf7 , 0x15}, //pll enable + + {0xf8 , 0x85}, + {0xfe , 0x00}, + {0x82 , 0x00}, + {0xb3 , 0x60}, + {0xb4 , 0x40}, + {0xb5 , 0x60}, + + {0x03 , 0x02}, + {0x04 , 0x80}, + + //////////measure window /////////// + {0xfe , 0x00}, + {0xec , 0x06},//04 + {0xed , 0x06},//04 + {0xee , 0x62},//60 + {0xef , 0x92},//90 + + ///////////analog///////////// + {0x0a , 0x00}, //row start + {0x0c , 0x00}, //col start + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, //Window setting + {0x10 , 0x58}, + {0x17 , 0x14}, //[0]mirror [1]flip + {0x18 , 0x0a}, //0a 2012.10.26 + {0x19 , 0x0a}, //AD pipe number + + {0x1a, 0x01}, //CISCTL mode4 + {0x1b , 0x8b}, + {0x1c , 0x05}, //added + {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias + {0x1f , 0x08}, //[3] tx-low en// + {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en + {0x21 , 0x0f}, //[6:4]rsg + {0x22 , 0xf0}, //[3:0]vref 0xf0 + {0x23 , 0xc3}, //f3//ADC_r + {0x24 , 0x15}, //pad drive <=36MHz, use 0x00 is ok + + //AEC + {0xfe , 0x01}, + {0x11 , 0x20},//AEC_out_slope , 0x + {0x1f , 0xa0},//max_post_gain + {0x20 , 0x40},//max_pre_gain + {0x47 , 0x30},//AEC_outdoor_th + {0x0b , 0x10},// + {0x13 , 0x75},//y_target + {0xfe , 0x00}, + + {0x05 , 0x01},//hb + {0x06 , 0x11}, + {0x07 , 0x00},//vb + {0x08 , 0x50}, + {0xfe , 0x01}, + {0x27 , 0x00},//step + {0x28 , 0xa0}, + {0x29 , 0x05},//level1 + {0x2a , 0x00}, + {0x2b , 0x05},//level2 + {0x2c , 0x00}, + {0x2d , 0x06},//6e8//level3 + {0x2e , 0xe0}, + {0x2f , 0x0a},//level4 + {0x30 , 0x00}, + {0x3e , 0x40}, + {0xfe , 0x00}, + {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x + {0xb6 , 0x03}, //AEC enable + {0xfe , 0x00}, + + /////////BLK////// + {0x3f , 0x00}, //prc close + {0x40 , 0x77},// + {0x42 , 0x7f}, + {0x43 , 0x30}, + {0x5c , 0x08}, + {0x5e , 0x20}, + {0x5f , 0x20}, + {0x60 , 0x20}, + {0x61 , 0x20}, + {0x62 , 0x20}, + {0x63 , 0x20}, + {0x64 , 0x20}, + {0x65 , 0x20}, + + ///block//////////// + {0x80 , 0xff}, + {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug + {0x87 , 0x90}, //[7]middle gamma + {0x84 , 0x02}, //output put foramat + {0x86 , 0x07}, //02 //sync plority + {0x8b , 0xbc}, + {0xb0 , 0x80}, //globle gain + {0xc0 , 0x40},//Yuv bypass + + //////lsc///////////// + {0xfe , 0x01}, + {0xc2 , 0x38}, + {0xc3 , 0x25}, + {0xc4 , 0x21}, + {0xc8 , 0x19}, + {0xc9 , 0x12}, + {0xca , 0x0e}, + {0xbc , 0x43}, + {0xbd , 0x18}, + {0xbe , 0x1b}, + {0xb6 , 0x40}, + {0xb7 , 0x2e}, + {0xb8 , 0x26}, + {0xc5 , 0x05}, + {0xc6 , 0x03}, + {0xc7 , 0x04}, + {0xcb , 0x00}, + {0xcc , 0x00}, + {0xcd , 0x00}, + {0xbf , 0x14}, + {0xc0 , 0x22}, + {0xc1 , 0x1b}, + {0xb9 , 0x00}, + {0xba , 0x05}, + {0xbb , 0x05}, + {0xaa , 0x35}, + {0xab , 0x33}, + {0xac , 0x33}, + {0xad , 0x25}, + {0xae , 0x22}, + {0xaf , 0x27}, + {0xb0 , 0x1d}, + {0xb1 , 0x20}, + {0xb2 , 0x22}, + {0xb3 , 0x14}, + {0xb4 , 0x15}, + {0xb5 , 0x16}, + {0xd0 , 0x00}, + {0xd2 , 0x07}, + {0xd3 , 0x08}, + {0xd8 , 0x00}, + {0xda , 0x13}, + {0xdb , 0x17}, + {0xdc , 0x00}, + {0xde , 0x0a}, + {0xdf , 0x08}, + {0xd4 , 0x00}, + {0xd6 , 0x00}, + {0xd7 , 0x0c}, + {0xa4 , 0x00}, + {0xa5 , 0x00}, + {0xa6 , 0x00}, + {0xa7 , 0x00}, + {0xa8 , 0x00}, + {0xa9 , 0x00}, + {0xa1 , 0x80}, + {0xa2 , 0x80}, + + //////////cc////////////// + {0xfe , 0x02}, + {0xc0 , 0x01}, + {0xc1 , 0x40}, //Green_cc for d + {0xc2 , 0xfc}, + {0xc3 , 0x05}, + {0xc4 , 0xec}, + {0xc5 , 0x42}, + {0xc6 , 0xf8}, + {0xc7 , 0x40},//for cwf + {0xc8 , 0xf8}, + {0xc9 , 0x06}, + {0xca , 0xfd}, + {0xcb , 0x3e}, + {0xcc , 0xf3}, + {0xcd , 0x36},//for A + {0xce , 0xf6}, + {0xcf , 0x04}, + {0xe3 , 0x0c}, + {0xe4 , 0x44}, + {0xe5 , 0xe5}, + {0xfe , 0x00}, + + ///////awb start //////////////// + //AWB clear + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x10}, // 10 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x20}, // 20 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, // 30 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x40}, // 40 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x50}, // 50 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x60}, // 60 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x70}, // 70 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x80}, // 80 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x90}, // 90 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xa0}, // a0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xb0}, // b0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xc0}, // c0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xd0}, // d0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4f , 0x01}, + /////// awb value//////// + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x40}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x53}, + {0x4e , 0x08}, + {0x4e , 0x04}, + {0x4d , 0x62}, + {0x4e , 0x10}, + {0x4d , 0x72}, + {0x4e , 0x20}, + {0x4f , 0x01}, + + /////awb//// + {0xfe , 0x01}, + {0x50 , 0x88},//c0//[6]green mode + {0x52 , 0x40}, + {0x54 , 0x60}, + {0x56 , 0x06}, + {0x57 , 0x20}, //pre adjust + {0x58 , 0x01}, + {0x5b , 0x02}, //AWB_gain_delta + {0x61 , 0xaa},//R/G stand + {0x62 , 0xaa},//R/G stand + {0x71 , 0x00}, + {0x74 , 0x10}, //0x//AWB_C_max + {0x77 , 0x08}, // 0x//AWB_p2_x + {0x78 , 0xfd}, //AWB_p2_y + {0x86 , 0x30}, + {0x87 , 0x00}, + {0x88 , 0x04},//06 , 0x//[1]dark mode + {0x8a , 0xc0},//awb move mode + {0x89 , 0x75}, + {0x84 , 0x08}, //0x//auto_window + {0x8b , 0x00}, // 0x//awb compare luma + {0x8d , 0x70}, //awb gain limit R + {0x8e , 0x70},//G + {0x8f , 0xf4},//B + {0xfe , 0x00}, + {0x82 , 0x02},//awb_en + /////////awb end ///////////// + + ///==========asde + {0xfe , 0x01}, + {0x21 , 0xbf}, + {0xfe , 0x02}, + {0xa4 , 0x00},// + {0xa5 , 0x40}, //lsc_th + {0xa2 , 0xa0}, //lsc_dec_slope + {0xa6 , 0x80}, //dd_th + {0xa7 , 0x80}, //ot_th + {0xab , 0x31}, // + {0xa9 , 0x6f}, // + {0xb0 , 0x99}, //0x//edge effect slope low + {0xb1 , 0x34},//edge effect slope low + {0xb3 , 0xf0}, //saturation dec slope + {0xde , 0xb6}, // + {0x38 , 0x0f}, // + {0x39 , 0x60}, // + {0xfe , 0x00}, + {0x81 , 0x26}, + {0xfe , 0x02}, + {0x83 , 0x00},// + {0x84 , 0x45},// + ////////////YCP////////// + {0xd1 , 0x34},//saturation_cb + {0xd2 , 0x34},//saturation_Cr + {0xd3 , 0x40},//contrast ? {0xd4 , 0x80},//contrast center + {0xd4 , 0x80},//contrast center + {0xd5 , 0x00},//luma_offset + {0xdc , 0x30}, + {0xdd , 0xb8},//edge_sa_g,b + {0xfe , 0x00}, + ///////dndd/////////// + {0xfe , 0x02}, + {0x88 , 0x15},//dn_b_base + {0x8c , 0xf6}, //[2]b_in_dark_inc + {0x89 , 0x03}, //dn_c_weight + ////////EE /////////// + {0xfe , 0x02}, + {0x90 , 0x6c},// EEINTP mode1 + {0x97 , 0x45},// edge effect + ////==============RGB Gamma + {0xfe , 0x02}, + {0x15 , 0x0a}, + {0x16 , 0x12}, + {0x17 , 0x19}, + {0x18 , 0x1f}, + {0x19 , 0x2c}, + {0x1a , 0x38}, + {0x1b , 0x42}, + {0x1c , 0x4e}, + {0x1d , 0x63}, + {0x1e , 0x76}, + {0x1f , 0x87}, + {0x20 , 0x96}, + {0x21 , 0xa2}, + {0x22 , 0xb8}, + {0x23 , 0xca}, + {0x24 , 0xd8}, + {0x25 , 0xe3}, + {0x26 , 0xf0}, + {0x27 , 0xf8}, + {0x28 , 0xfd}, + {0x29 , 0xff}, + + ///=================y gamma + {0xfe , 0x02}, + {0x2b , 0x00}, + {0x2c , 0x04}, + {0x2d , 0x09}, + {0x2e , 0x18}, + {0x2f , 0x27}, + {0x30 , 0x37}, + {0x31 , 0x49}, + {0x32 , 0x5c}, + {0x33 , 0x7e}, + {0x34 , 0xa0}, + {0x35 , 0xc0}, + {0x36 , 0xe0}, + {0x37 , 0xff}, + /////1600x1200size// + {0xfe , 0x00},// + {0x90 , 0x01}, //0x//crop enable + {0x94 , 0x04}, + {0x95 , 0x04}, //0x//1600x1200 + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + + {0xfe , 0x03}, + {0x42 , 0x40}, + {0x43 , 0x06}, //output buf width + {0x41 , 0x02}, // Pclk_polarity + {0x40 , 0x40}, //00 + {0x17 , 0x00}, //widv + {0xfe , 0x00}, + ////output DVP///// + {0xfe , 0x00}, + {0x82 , 0xfe}, // fe + {0xf2 , 0x70}, + {0xf3 , 0xff}, + {0xf4 , 0x00}, + {0xf5 , 0x30}, + ////////sabsumple 800X600////// + {0xfe , 0x00}, + {0xb6 , 0x03}, + {0xfa , 0x00}, + + {0xc8 , 0x00},//close scaler + {0x99 , 0x22},// 1/2 subsample + {0x9a , 0x07}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 , 0x00}, + + {0x90 , 0x01}, //crop enable + {0x95 , 0x02}, + {0x96 , 0x58}, + {0x97 , 0x03}, + {0x98 , 0x20}, -/* 1600X1200 UXGA capture */ -static struct regval_list sensor_uxga_regs[] ={ - -{0xfe , 0x00}, -{0xfa , 0x11}, -{0xc8 , 0x00}, - -{0x99 , 0x11},// 1/2 subsample -{0x9a , 0x06}, -{0x9b , 0x00}, -{0x9c , 0x00}, -{0x9d , 0x00}, -{0x9e , 0x00}, -{0x9f , 0x00}, -{0xa0 , 0x00}, -{0xa1 , 0x00}, -{0xa2 , 0x00}, - -{0x90 , 0x01}, -{0x95 , 0x04}, -{0x96 , 0xb0}, -{0x97 , 0x06}, -{0x98 , 0x40}, + #if 1 + ///////// re zao/// + {0xfe , 0x00}, + {0x22 , 0xf0}, + {0xfe , 0x01}, + {0x21 , 0xff}, + {0xfe , 0x02}, + {0x8a , 0x33}, + {0x8c , 0x76}, + {0x8d , 0x85}, + {0xa6 , 0xf0}, + {0xae , 0x9f}, + {0xa2 , 0x90}, + {0xa5 , 0x40}, + {0xa7 , 0x30}, + {0xb0 , 0x88}, + {0x38 , 0x0b}, + {0x39 , 0x30}, + {0xfe , 0x00}, + {0x87 , 0xb0}, + + //// small RGB gamma//// + /* + {0xfe , 0x02}, + {0x15 , 0x0b}, + {0x16 , 0x0e}, + {0x17 , 0x10}, + {0x18 , 0x12}, + {0x19 , 0x19}, + {0x1a , 0x21}, + {0x1b , 0x29}, + {0x1c , 0x31}, + {0x1d , 0x41}, + {0x1e , 0x50}, + {0x1f , 0x5f}, + {0x20 , 0x6d}, + {0x21 , 0x79}, + {0x22 , 0x91}, + {0x23 , 0xa5}, + {0x24 , 0xb9}, + {0x25 , 0xc9}, + {0x26 , 0xe1}, + {0x27 , 0xee}, + {0x28 , 0xf7}, + {0x29 , 0xff}, + */ + ////dark sun///// + {0xfe , 0x02}, + {0x40 , 0x06}, + {0x41 , 0x23}, + {0x42 , 0x3f}, + {0x43 , 0x06}, + {0x44 , 0x00}, + {0x45 , 0x00}, + {0x46 , 0x14}, + {0x47 , 0x09}, + {0xfe , 0x00}, + #endif + }; + + /* 1600X1200 UXGA capture */ + static struct regval_list sensor_uxga_regs_hres1[] = + { + {0xfe , 0x00}, + {0xfa , 0x11}, + {0xc8 , 0x00}, + + {0x99 , 0x11},// 1/2 subsample + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 , 0x00}, + + {0x90 , 0x01}, + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + }; + + /* 800X600 SVGA,30fps*/ + static struct regval_list sensor_svga_regs_hres1[] = + { + {0xfe,0x00}, + {0xb6,0x03}, + {0xfa , 0x00}, + {0xc8,0x00},//close scaler + + {0x99,0x22},// 1/2 subsample + {0x9a , 0x07}, + {0x9b,0x00}, + {0x9c,0x00}, + {0x9d,0x00}, + {0x9e,0x00}, + {0x9f,0x00}, + {0xa0,0x00}, + {0xa1,0x00}, + {0xa2,0x00}, + + {0x90,0x01}, //crop enable + {0x95,0x02}, + {0x96,0x58}, + {0x97,0x03}, + {0x98,0x20}, + }; + + static struct regval_list sensor_default_regs_hres3[] = + { + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfc , 0x06}, + {0xf2 , 0x00}, + {0xf3 , 0x00}, + {0xf4 , 0x00}, + {0xf5 , 0x00}, + {0xf9 , 0xfe}, //[0] pll enable + {0xfa , 0x00}, + {0xf6 , 0x00}, + {0xf7 , 0x15}, //pll enable + + {0xf8 , 0x85}, + + {0xfe , 0x00}, + {0x82 , 0x00}, //00 + {0xb3 , 0x60}, //60 + {0xb4 , 0x40}, //60 40 + {0xb5 , 0x60}, //60 + + {0x03 , 0x02}, + {0x04 , 0x80}, + + //////////measure window /////////// + {0xfe , 0x00}, + {0xec , 0x06},//04 + {0xed , 0x06},//04 + {0xee , 0x62},//60 + {0xef , 0x92},//90 + + ///////////analog///////////// + {0x0a , 0x00}, //row start + {0x0b , 0x10}, //row start + {0x0c , 0x00}, //col start + {0x0d , 0x04}, //4d0 = 1232 + {0x0e , 0xe0}, //d0/b0/d0/c0 + {0x0f , 0x06}, //Window setting + {0x10 , 0x58}, //40/50/58 + {0x17 , 0x14}, //[0]mirror [1]flip [4]better colour + + + //{0x18 , 0x0a}, //0a 2012.10.26 + {0x18 , 0x0f}, //0a 2012.10.26 + {0x19 , 0x0a}, //AD pipe number + + {0x1a , 0x01}, //CISCTL mode4 + {0x1b , 0x8b}, + {0x1c , 0x05}, //added + {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias + {0x1f , 0x08}, //[3] tx-low en// + {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en + {0x21 , 0x0f}, //[6:4]rsg + {0x22 , 0xf0}, //[3:0]vref 0xf0 + {0x23 , 0xc3}, //f3//ADC_r + {0x24 , 0x17}, //pad drive <=36MHz, use 0x00 is ok + + //AEC + {0xfe , 0x01}, + {0x11 , 0x20},//20 AEC_out_slope , 0x + {0x1f , 0xc0},//80 max_post_gain + {0x20 , 0x60},//40 max_pre_gain + {0x47 , 0x80},//30 AEC_outdoor_th + {0x0b , 0x13},//10 + {0x13 , 0x75},//y_target + {0xfe , 0x00}, + + {0xfe , 0x00}, + {0xfe , 0x00}, + {0x05 , 0x01},//hb + {0x06 , 0x0d}, + {0x07 , 0x00},//vb + {0x08 , 0x40}, + + {0xfe , 0x01}, + {0x27 , 0x00},//step + {0x28 , 0xa0},//a0 + {0x29 , 0x05},// level 0 12.5 + {0x2a , 0x00}, + {0x2b , 0x05},// level 1 12.5 + {0x2c , 0x00}, + {0x2d , 0x05},// level 2 12.5 640/10fps + {0x2e , 0x00}, + {0x2f , 0x08},// level 3 7.5 + {0x30 , 0x20}, + + {0xfe , 0x00}, + {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x + {0xb6 , 0x03}, //AEC enable + {0xfe , 0x00}, + + /////////BLK////// + {0x3f, 0x00}, //prc close + {0x40, 0x77},// + {0x42, 0x7f}, + {0x43, 0x30}, + {0x5c, 0x08}, + {0x5e, 0x20}, + {0x5f, 0x20}, + {0x60, 0x20}, + {0x61, 0x20}, + {0x62, 0x20}, + {0x63, 0x20}, + {0x64, 0x20}, + {0x65, 0x20}, + + ///block//////////// + {0x80 , 0xff}, + {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug + {0x87 , 0x90}, //[7]middle gamma + {0x84 , 0x02}, //output put foramat + {0x86 , 0x07}, //02 //sync plority + {0x8b , 0xbc}, + {0xb0 , 0x80}, //globle gain + {0xc0 , 0x40},//Yuv bypass + + //////lsc///////////// + {0xfe,0x01}, + {0xc2,0x21}, + {0xc3,0x1a}, + {0xc4,0x13}, + {0xc8,0x17}, + {0xc9,0x0f}, + {0xca,0x00}, + {0xbc,0x36}, + {0xbd,0x2b}, + {0xbe,0x17}, + {0xb6,0x39}, + {0xb7,0x21}, + {0xb8,0x1c}, + {0xc5,0x00}, + {0xc6,0x00}, + {0xc7,0x00}, + {0xcb,0x00}, + {0xcc,0x0c}, + {0xcd,0x15}, + {0xbf,0x00}, + {0xc0,0x00}, + {0xc1,0x00}, + {0xb9,0x00}, + {0xba,0x00}, + {0xbb,0x00}, + {0xaa,0x15}, + {0xab,0x15}, + {0xac,0x15}, + {0xad,0x14}, + {0xae,0x13}, + {0xaf,0x12}, + {0xb0,0x1b}, + {0xb1,0x14}, + {0xb2,0x14}, + {0xb3,0x1f}, + {0xb4,0x12}, + {0xb5,0x13}, + {0xd0,0x00}, + {0xd2,0x00}, + {0xd3,0x0c}, + {0xd8,0x00}, + {0xda,0x00}, + {0xdb,0x13}, + {0xdc,0x00}, + {0xde,0x00}, + {0xdf,0x25}, + {0xd4,0x00}, + {0xd6,0x00}, + {0xd7,0x12}, + {0xa4,0x00}, + {0xa5,0x00}, + {0xa6,0x00}, + {0xa7,0x00}, + {0xa8,0x00}, + {0xa9,0x00}, + {0xa1,0x80}, + {0xa2,0x80}, + + //////////cc////////////// + {0xfe , 0x02}, + {0xc0 , 0x01}, + {0xc1 , 0x40}, //Green_cc for d + {0xc2 , 0xfc}, + {0xc3 , 0x05}, + {0xc4 , 0xec}, + {0xc5 , 0x42}, + {0xc6 , 0xf8}, + {0xc7 , 0x40},//for cwf + {0xc8 , 0xf8}, + {0xc9 , 0x06}, + {0xca , 0xfd}, + {0xcb , 0x3e}, + {0xcc , 0xf3}, + {0xcd , 0x36},//for A + {0xce , 0xf6}, + {0xcf , 0x04}, + {0xe3 , 0x0c}, + {0xe4 , 0x44}, + {0xe5 , 0xe5}, + {0xfe , 0x00}, + + ///////awb start //////////////// + //AWB clear + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x10}, // 10 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x20}, // 20 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, // 30 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x40}, // 40 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x50}, // 50 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x60}, // 60 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x70}, // 70 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x80}, // 80 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x90}, // 90 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xa0}, // a0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xb0}, // b0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xc0}, // c0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xd0}, // d0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4f , 0x01}, + /////// awb value//////// + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x40}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x53}, + {0x4e , 0x08}, + {0x4e , 0x04}, + {0x4d , 0x62}, + {0x4e , 0x10}, + {0x4d , 0x72}, + {0x4e , 0x20}, + {0x4f , 0x01}, + + /////awb//// + {0xfe , 0x01}, + {0x50 , 0x88},//c0//[6]green mode + {0x52 , 0x40}, + {0x54 , 0x60}, + {0x56 , 0x06}, + {0x57 , 0x20}, //pre adjust + {0x58 , 0x01}, + {0x5b , 0x02}, //AWB_gain_delta + {0x61 , 0xaa},//R/G stand + {0x62 , 0xaa},//R/G stand + {0x71 , 0x00}, + {0x74 , 0x10}, //0x//AWB_C_max + {0x77 , 0x08}, // 0x//AWB_p2_x + {0x78 , 0xfd}, //AWB_p2_y + {0x86 , 0x30}, + {0x87 , 0x00}, + {0x88 , 0x04},//06 , 0x//[1]dark mode + {0x8a , 0xc0},//awb move mode + {0x89 , 0x75}, + {0x84 , 0x08}, //0x//auto_window + {0x8b , 0x00}, // 0x//awb compare luma + {0x8d , 0x70}, //awb gain limit R + {0x8e , 0x70},//G + {0x8f , 0xf4},//B + {0xfe , 0x00}, + {0x82 , 0x02},//awb_en + /////////awb end ///////////// + + ///==========asde + {0xfe, 0x01}, + {0x21, 0xbf}, + {0xfe, 0x02}, + {0xa4, 0x00},// + {0xa5, 0x40}, //lsc_th + {0xa2, 0xa0}, //lsc_dec_slope + {0x86, 0x27},//add for DPC travis 20140505 + {0x8a, 0x33},//add for DPC travis 20140505 + {0x8d, 0x85},//add for DPC travis 20140505 + {0xa6, 0xf0},//80//change for DPC travis 20140505 + {0xa7, 0x80}, //ot_th + {0xab, 0x31}, // + {0xa9, 0x6f}, // + {0xb0, 0x99}, //0x//edge effect slope low + {0xb1, 0x34},//edge effect slope low + {0xb3, 0x80}, //saturation dec slope + {0xde, 0xb6}, // + {0x38, 0x0f}, // + {0x39, 0x60}, // + {0xfe, 0x00}, + {0x81, 0x26}, + {0xfe, 0x02}, + {0x83, 0x00},// + {0x84, 0x45},// + ////////////YCP////////// + {0xd1 , 0x34},//saturation_cb + {0xd2 , 0x34},//saturation_Cr + {0xd3 , 0x40},//contrast ? {0xd4 , 0x80},//contrast center + {0xd4 , 0x80},//contrast center + {0xd5 , 0x00},//luma_offset + {0xdc , 0x30}, + {0xdd , 0xb8},//edge_sa_g,b + {0xfe , 0x00}, + ///////dndd/////////// + {0xfe , 0x02}, + {0x88 , 0x15},//dn_b_base + {0x8c , 0xf6}, //[2]b_in_dark_inc + {0x89 , 0x03}, //dn_c_weight + ////////EE /////////// + {0xfe , 0x02}, + {0x90 , 0x6c},// EEINTP mode1 + {0x97 , 0x45},// edge effect + ////==============RGB Gamma + {0xfe , 0x02}, + {0x15 , 0x0a}, + {0x16 , 0x12}, + {0x17 , 0x19}, + {0x18 , 0x1f}, + {0x19 , 0x2c}, + {0x1a , 0x38}, + {0x1b , 0x42}, + {0x1c , 0x4e}, + {0x1d , 0x63}, + {0x1e , 0x76}, + {0x1f , 0x87}, + {0x20 , 0x96}, + {0x21 , 0xa2}, + {0x22 , 0xb8}, + {0x23 , 0xca}, + {0x24 , 0xd8}, + {0x25 , 0xe3}, + {0x26 , 0xf0}, + {0x27 , 0xf8}, + {0x28 , 0xfd}, + {0x29 , 0xff}, + + ///=================y gamma + {0xfe , 0x02}, + {0x2b , 0x00}, + {0x2c , 0x04}, + {0x2d , 0x09}, + {0x2e , 0x18}, + {0x2f , 0x27}, + {0x30 , 0x37}, + {0x31 , 0x49}, + {0x32 , 0x5c}, + {0x33 , 0x7e}, + {0x34 , 0xa0}, + {0x35 , 0xc0}, + {0x36 , 0xe0}, + {0x37 , 0xff}, + /////1600x1200size// + {0xfe, 0x00},// + {0x90, 0x01}, //0x//crop enable + {0x94, 0x04}, + {0x95, 0x04}, //0x//1600x1200 + {0x96, 0xb0}, + {0x97, 0x06}, + {0x98, 0x40}, + + {0xfe , 0x03}, + {0x40 , 0x40}, //00 + {0x41 , 0x02}, // Pclk_polarity + {0x42 , 0x40}, + {0x43 , 0x06}, //output buf width + {0x17 , 0x01}, //widv + {0xfe , 0x00}, + + ////output DVP///// + {0xfe , 0x00}, + {0x82 , 0xfe}, // fe + {0xf2 , 0x70}, + {0xf3 , 0xff}, + {0xf4 , 0x00}, + {0xf5 , 0x30}, + #if 1 + ///////// re zao/// + {0xfe , 0x00}, + {0x22 , 0xf0}, + {0xfe , 0x01}, + {0x21 , 0xff}, + {0xfe , 0x02}, + {0x8a , 0x33}, + {0x8c , 0x76}, + {0x8d , 0x85}, + {0xa6 , 0xf0}, + {0xae , 0x9f}, + {0xa2 , 0x90}, + {0xa5 , 0x40}, + {0xa7 , 0x30}, + {0xb0 , 0x88}, + {0x38 , 0x0b}, + {0x39 , 0x30}, + {0xfe , 0x00}, + + {0x87 , 0xb0}, + + //// small RGB gamma//// + /* + {0xfe , 0x02}, + {0x15 , 0x0b}, + {0x16 , 0x0e}, + {0x17 , 0x10}, + {0x18 , 0x12}, + {0x19 , 0x19}, + {0x1a , 0x21}, + {0x1b , 0x29}, + {0x1c , 0x31}, + {0x1d , 0x41}, + {0x1e , 0x50}, + {0x1f , 0x5f}, + {0x20 , 0x6d}, + {0x21 , 0x79}, + {0x22 , 0x91}, + {0x23 , 0xa5}, + {0x24 , 0xb9}, + {0x25 , 0xc9}, + {0x26 , 0xe1}, + {0x27 , 0xee}, + {0x28 , 0xf7}, + {0x29 , 0xff}, + */ + ////dark sun///// + {0xfe , 0x02}, + {0x40 , 0x06}, + {0x41 , 0x23}, + {0x42 , 0x3f}, + {0x43 , 0x06}, + {0x44 , 0x00}, + {0x45 , 0x00}, + {0x46 , 0x14}, + {0x47 , 0x09}, + {0xfe , 0x00}, + #endif + + }; + + /* 1600X1200 UXGA 20fps */ + static struct regval_list sensor_uxga_regs_hres3[] = + { + {0xfe , 0x00}, + {0xb6, 0x03}, + {0xfa , 0x00}, + {0xc8 , 0x00}, + + {0x99 , 0x11},// 1/2 subsample + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 , 0x00}, + + {0x90 , 0x01}, + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + + }; + + /* 800X600 SVGA,20fps*/ + static struct regval_list sensor_svga_regs_hres3[] = + { + {0xfe,0x00}, + {0xb6,0x03}, + {0xfa,0x00}, + {0xc8,0x00},//close scaler + + {0x99,0x22},// 1/2 subsample + {0x9a,0x07}, + {0x9b,0x00}, + {0x9c,0x00}, + {0x9d,0x00}, + {0x9e,0x00}, + {0x9f,0x00}, + {0xa0,0x00}, + {0xa1,0x00}, + {0xa2,0x00}, + + {0x90,0x01}, //crop enable + {0x95,0x02}, + {0x96,0x58}, + {0x97,0x03}, + {0x98,0x20}, + }; + + /* 640x480 VGA,20fps*/ + static struct regval_list sensor_vga_regs_hres3[] = + { + {0xfe,0x00}, + {0xb6,0x03}, + {0xfa,0x00}, + {0xc8,0x02}, //close scaler + + {0x99,0x22},// 1/2 subsample + {0x9a,0x06}, + {0x9b,0x00}, + {0x9c,0x00}, + {0x9d,0x00}, + {0x9e,0x00}, + {0x9f,0x00}, + {0xa0,0x00}, + {0xa1,0x00}, + {0xa2,0x00}, + + {0x90,0x01}, //crop enable + {0x95,0x02}, + {0x96,0x58}, + {0x97,0x03}, + {0x98,0x20}, + }; + + /* 320x240 QVGA,20fps*/ + static struct regval_list sensor_qvga_regs_hres3[] = + { + {0xfe,0x00}, + {0xb6,0x03}, + {0xfa,0x00}, + {0xc8,0x02}, //close scaler + + {0x99,0x44},// 1/2 subsample + {0x9a,0x06}, + {0x9b,0x00}, + {0x9c,0x00}, + {0x9d,0x00}, + {0x9e,0x00}, + {0x9f,0x00}, + {0xa0,0x00}, + {0xa1,0x00}, + {0xa2,0x00}, + + {0x90,0x01}, //crop enable + {0x95,0x02}, + {0x96,0x58}, + {0x97,0x03}, + {0x98,0x20}, + }; + + + static struct regval_list sensor_default_regs_hres2[] = + { + {0xfe, 0x80}, + {0xfe, 0x80}, + {0xfe, 0x80}, + {0xfc, 0x06}, + {0xf2, 0x00}, + {0xf3, 0x00}, + {0xf4, 0x00}, + {0xf5, 0x00}, + {0xf9, 0xfe}, //[0] pll enable + {0xfa, 0x00}, + {0xf6, 0x00}, + {0xf7, 0x15}, //pll enable + #if 1 + {0xf8, 0x85}, + #else + {0xf8, 0x84}, + #endif + {0xfe, 0x00}, + {0x82, 0x00}, + {0xb3, 0x60}, + {0xb4, 0x40}, + {0xb5, 0x60}, + + #if 1 + {0x03 , 0x02}, + {0x04 , 0x80}, + #else + {0x03, 0x04}, + {0x04, 0x9b}, + #endif + //////////measure window /////////// + {0xfe, 0x00}, + {0xec, 0x06},//04 + {0xed, 0x06},//04 + {0xee, 0x62},//60 + {0xef, 0x92},//90 + + ///////////analog///////////// + {0x0a, 0x00}, //row start + {0x0c, 0x00}, //col start + {0x0d, 0x04}, + {0x0e, 0xc0}, + {0x0f, 0x06}, //Window setting + {0x10, 0x58}, + {0x17, 0x14}, //[0]mirror [1]flip + + + {0x18, 0x0e}, //sdark 4 row in even frame?? + {0x19, 0x0c}, //AD pipe number + + /* + /// ë´Ì ÃÖÃó + {0x18,0x0a}, //sdark 4 row in even frame?? + {0x19,0x0a}, //AD pipe number + */ + + {0x1a , 0x01}, //CISCTL mode4 + {0x1b , 0x8b}, + {0x1c , 0x05}, + {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias + {0x1f , 0x08}, //[3] tx-low en// + {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en + {0x21 , 0x0f}, //[6:4]rsg + {0x22 , 0xf0}, //[3:0]vref + {0x23 , 0xc3}, //f3//ADC_r + {0x24 , 0x17}, //pad drive 16 + + //AEC + {0xfe, 0x01}, + {0x11, 0x20},//AEC_out_slope , 0x + {0x1f, 0xc0},//max_post_gain + {0x20, 0x60},//max_pre_gain + {0x47, 0x30},//AEC_outdoor_th + {0x0b, 0x10},// + {0x13, 0x75},//y_target + {0xfe, 0x00}, + + #if 0 + {0x05 , 0x01},//hb + {0x06 , 0x11}, + {0x07 , 0x00},//vb + {0x08 , 0x50}, + {0xfe , 0x01}, + {0x27 , 0x00},//step + {0x28 , 0xa0}, + {0x29 , 0x05},//level1 + {0x2a , 0x00}, + {0x2b , 0x05},//level2 + {0x2c , 0x00}, + {0x2d , 0x06},//6e8//level3 + {0x2e , 0xe0}, + {0x2f , 0x0a},//level4 + {0x30 , 0x00}, + {0x3e , 0x40}, + #else + {0xfe , 0x00}, + {0x05 , 0x01}, + {0x06 , 0x0d}, + {0x07 , 0x00}, + {0x08 , 0x40}, + {0xfe , 0x01}, + {0x27 , 0x00}, + {0x28 , 0xa0}, + {0x29 , 0x05},// level 0 12.5 + {0x2a , 0x00}, + {0x2b , 0x05},// level 1 12.5 + {0x2c , 0x00}, + {0x2d , 0x05},// level 2 12.5 640/10fps + {0x2e , 0x00}, + {0x2f , 0x08},// level 3 7.5 + {0x30 , 0x20}, + #endif + + {0xfe , 0x00}, + {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x + {0xb6 , 0x03}, //AEC enable + {0xfe , 0x00}, + + /////////BLK////// + {0x3f, 0x00}, //prc close + {0x40, 0x77},// + {0x42, 0x7f}, + {0x43, 0x30}, + {0x5c, 0x08}, + {0x5e, 0x20}, + {0x5f, 0x20}, + {0x60, 0x20}, + {0x61, 0x20}, + {0x62, 0x20}, + {0x63, 0x20}, + {0x64, 0x20}, + {0x65, 0x20}, + + ///block//////////// + {0x80, 0xff}, + {0x81, 0x26},//38 , 0x//skin_Y 8c_debug + {0x87, 0x90}, //[7]middle gamma + {0x84, 0x03}, //output put foramat + {0x86, 0x07}, ////sync plority 02 86 + {0x8b, 0xbc}, + {0xb0, 0x80}, //globle gain + {0xc0, 0x40},//Yuv bypass + + //////lsc///////////// + #if 0 + {0xfe, 0x01}, + {0xc2, 0x38}, + {0xc3, 0x25}, + {0xc4, 0x21}, + {0xc8, 0x19}, + {0xc9, 0x12}, + {0xca, 0x0e}, + {0xbc, 0x28},// left R 0x43 + {0xbd, 0x18},//0x18 + {0xbe, 0x1b},//0x1b + {0xb6, 0x40},//right 0x40 + {0xb7, 0x2e}, + {0xb8, 0x26}, + {0xc5, 0x05}, + {0xc6, 0x03}, + {0xc7, 0x04}, + {0xcb, 0x00}, + {0xcc, 0x00}, + {0xcd, 0x00}, + {0xbf, 0x14}, + {0xc0, 0x22}, + {0xc1, 0x1b}, + {0xb9, 0x00}, + {0xba, 0x05}, + {0xbb, 0x05}, + {0xaa, 0x35}, + {0xab, 0x33}, + {0xac, 0x33}, + {0xad, 0x25}, + {0xae, 0x22}, + {0xaf, 0x27}, + {0xb0, 0x1d}, + {0xb1, 0x20}, + {0xb2, 0x22}, + {0xb3, 0x14}, + {0xb4, 0x15}, + {0xb5, 0x16}, + {0xd0, 0x00}, + {0xd2, 0x07}, + {0xd3, 0x08}, + {0xd8, 0x00}, + {0xda, 0x13}, + {0xdb, 0x17}, + {0xdc, 0x00}, + {0xde, 0x0a}, + {0xdf, 0x08}, + {0xd4, 0x00}, + {0xd6, 0x00}, + {0xd7, 0x0c}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x00}, + {0xa7, 0x00}, + {0xa8, 0x00}, + {0xa9, 0x00}, + {0xa1, 0x80}, + {0xa2, 0x80}, + #else + //gc2035 Alight lsc reg setting list + ////Record date: 2013-11-29 13:30:15 + + {0xfe,0x01}, + {0xc2,0x21}, + {0xc3,0x1a}, + {0xc4,0x13}, + {0xc8,0x17}, + {0xc9,0x0f}, + {0xca,0x00}, + {0xbc,0x36}, + {0xbd,0x2b}, + {0xbe,0x17}, + {0xb6,0x39}, + {0xb7,0x21}, + {0xb8,0x1c}, + {0xc5,0x00}, + {0xc6,0x00}, + {0xc7,0x00}, + {0xcb,0x00}, + {0xcc,0x0c}, + {0xcd,0x15}, + {0xbf,0x00}, + {0xc0,0x00}, + {0xc1,0x00}, + {0xb9,0x00}, + {0xba,0x00}, + {0xbb,0x00}, + {0xaa,0x15}, + {0xab,0x15}, + {0xac,0x15}, + {0xad,0x14}, + {0xae,0x13}, + {0xaf,0x12}, + {0xb0,0x1b}, + {0xb1,0x14}, + {0xb2,0x14}, + {0xb3,0x1f}, + {0xb4,0x12}, + {0xb5,0x13}, + {0xd0,0x00}, + {0xd2,0x00}, + {0xd3,0x0c}, + {0xd8,0x00}, + {0xda,0x00}, + {0xdb,0x13}, + {0xdc,0x00}, + {0xde,0x00}, + {0xdf,0x25}, + {0xd4,0x00}, + {0xd6,0x00}, + {0xd7,0x12}, + {0xa4,0x00}, + {0xa5,0x00}, + {0xa6,0x00}, + {0xa7,0x00}, + {0xa8,0x00}, + {0xa9,0x00}, + {0xa1,0x80}, + {0xa2,0x80}, + #endif + + //////////cc////////////// + {0xfe, 0x02}, + {0xc0, 0x01}, + {0xc1, 0x40}, //Green_cc for d + {0xc2, 0xfc}, + {0xc3, 0x05}, + {0xc4, 0xec}, + {0xc5, 0x42}, + {0xc6, 0xf8}, + {0xc7, 0x40},//for cwf + {0xc8, 0xf8}, + {0xc9, 0x06}, + {0xca, 0xfd}, + {0xcb, 0x3e}, + {0xcc, 0xf3}, + {0xcd, 0x36},//for A + {0xce, 0xf6}, + {0xcf, 0x04}, + {0xe3, 0x0c}, + {0xe4, 0x44}, + {0xe5, 0xe5}, + {0xfe, 0x00}, + + ///////awb start //////////////// + //AWB clear + {0xfe, 0x01}, + {0x4f, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x10}, // 10 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x20}, // 20 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x30}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, // 30 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x40}, // 40 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x50}, // 50 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x60}, // 60 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x70}, // 70 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x80}, // 80 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0x90}, // 90 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0xa0}, // a0 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0xb0}, // b0 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0xc0}, // c0 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4d, 0xd0}, // d0 + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x01}, + /////// awb value//////// + {0xfe, 0x01}, + {0x4f, 0x00}, + {0x4d, 0x30}, + {0x4e, 0x00}, + {0x4e, 0x80}, + {0x4e, 0x80}, + {0x4e, 0x02}, + {0x4e, 0x02}, + {0x4d, 0x40}, + {0x4e, 0x00}, + {0x4e, 0x80}, + {0x4e, 0x80}, + {0x4e, 0x02}, + {0x4e, 0x02}, + {0x4e, 0x02}, + {0x4d, 0x53}, + {0x4e, 0x08}, + {0x4e, 0x04}, + {0x4d, 0x62}, + {0x4e, 0x10}, + {0x4d, 0x72}, + {0x4e, 0x20}, + {0x4f, 0x01}, + + /////awb//// + {0xfe, 0x01}, + {0x50, 0x88},//c0//[6]green mode + {0x52, 0x40}, + {0x54, 0x60}, + {0x56, 0x06}, + {0x57, 0x20}, //pre adjust + {0x58, 0x01}, + {0x5b, 0x02}, //AWB_gain_delta + {0x61, 0xaa},//R/G stand + {0x62, 0xaa},//R/G stand + {0x71, 0x00}, + {0x74, 0x10}, //0x//AWB_C_max + {0x77, 0x08}, // 0x//AWB_p2_x + {0x78, 0xfd}, //AWB_p2_y + {0x86, 0x30}, + {0x87, 0x00}, + {0x88, 0x04},//06 , 0x//[1]dark mode + {0x8a, 0xc0},//awb move mode + {0x89, 0x75}, + {0x84, 0x08}, //0x//auto_window + {0x8b, 0x00}, // 0x//awb compare luma + {0x8d, 0x70}, //awb gain limit R + {0x8e, 0x70},//G + {0x8f, 0xf4},//B + {0xfe, 0x00}, + {0x82, 0x02},//awb_en + /////////awb end ///////////// + + ///==========asde + {0xfe, 0x01}, + {0x21, 0xbf}, + {0xfe, 0x02}, + {0xa4, 0x00},// + {0xa5, 0x40}, //lsc_th + {0xa2, 0xa0}, //lsc_dec_slope + {0x86, 0x27},//add for DPC travis 20140505 + {0x8a, 0x33},//add for DPC travis 20140505 + {0x8d, 0x85},//add for DPC travis 20140505 + {0xa6, 0xf0},//80//change for DPC travis 20140505 + {0xa7, 0x80}, //ot_th + {0xab, 0x31}, // + {0xa9, 0x6f}, // + {0xb0, 0x99}, //0x//edge effect slope low + {0xb1, 0x34},//edge effect slope low + {0xb3, 0x80}, //saturation dec slope + {0xde, 0xb6}, // + {0x38, 0x0f}, // + {0x39, 0x60}, // + {0xfe, 0x00}, + {0x81, 0x26}, + {0xfe, 0x02}, + {0x83, 0x00},// + {0x84, 0x45},// + ////////////YCP////////// + {0xd1, 0x38},//saturation_cb + {0xd2, 0x38},//saturation_Cr + {0xd3, 0x40},//contrast ? + {0xd4, 0x80},//contrast center + {0xd5, 0x00},//luma_offset + {0xdc, 0x30}, + {0xdd, 0xb8}, //edge_sa_g,b + {0xfe, 0x00}, + ///////dndd/////////// + {0xfe, 0x02}, + {0x88, 0x15},//dn_b_base + {0x8c, 0xf6}, //[2]b_in_dark_inc + {0x89, 0x03}, //dn_c_weight + ////////EE /////////// + {0xfe, 0x02}, + {0x90, 0x6c},// EEINTP mode1 + {0x97, 0x45},// edge effect + ////==============RGB Gamma + {0xfe, 0x02}, + {0x15, 0x0a}, + {0x16, 0x12}, + {0x17, 0x19}, + {0x18, 0x1f}, + {0x19, 0x2c}, + {0x1a, 0x38}, + {0x1b, 0x42}, + {0x1c, 0x4e}, + {0x1d, 0x63}, + {0x1e, 0x76}, + {0x1f, 0x87}, + {0x20, 0x96}, + {0x21, 0xa2}, + {0x22, 0xb8}, + {0x23, 0xca}, + {0x24, 0xd8}, + {0x25, 0xe3}, + {0x26, 0xf0}, + {0x27, 0xf8}, + {0x28, 0xfd}, + {0x29, 0xff}, + + ///=================y gamma + {0xfe, 0x02}, + {0x2b, 0x00}, + {0x2c, 0x04}, + {0x2d, 0x09}, + {0x2e, 0x18}, + {0x2f, 0x27}, + {0x30, 0x37}, + {0x31, 0x49}, + {0x32, 0x5c}, + {0x33, 0x7e}, + {0x34, 0xa0}, + {0x35, 0xc0}, + {0x36, 0xe0}, + {0x37, 0xff}, + /////1600x1200size// + {0xfe, 0x00},// + {0x90, 0x01}, //0x//crop enable + {0x95, 0x04}, //0x//1600x1200 + {0x96, 0xb0}, + {0x97, 0x06}, + {0x98, 0x40}, + + {0xfe, 0x03}, + {0x42, 0x40}, + {0x43, 0x06}, //output buf width + {0x41, 0x02}, // Pclk_polarity + {0x40, 0x40}, //00 + {0x17, 0x00}, //widv + {0xfe, 0x00}, + ////output DVP///// + {0xfe , 0x00}, + {0xb6 , 0x03}, + {0xfa , 0x00}, + + {0xc8, 0x00},//close scaler + {0x99, 0x22},// 1/2 subsample + {0x9a, 0x06}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x00}, + {0x9e, 0x00}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x00}, + {0xa2, 0x00}, + + {0x90, 0x01}, //crop enable + {0x94, 0x02}, + {0x95, 0x02}, + {0x96, 0x5a}, + {0x97, 0x03}, + {0x98, 0x20}, + {0xfe, 0x00}, + {0x82, 0xfe}, // fe + {0xf2, 0x70}, + {0xf3, 0xff}, + {0xf4, 0x00}, + {0xf5, 0x30}, + + #if 0 + ///////// re zao/// + {0xfe,0x00}, + {0x22,0xf0}, + {0xfe,0x01}, + {0x21,0xff}, + {0xfe,0x02}, + {0x8a,0x33}, + {0x8c,0x76}, + {0x8d,0x85}, + {0xa6,0xf0}, + {0xae,0x9f}, + {0xa2,0x90}, + {0xa5,0x40}, + {0xa7,0x30}, + {0xb0,0x88}, + {0x38,0x0b}, + {0x39,0x30}, + {0xfe,0x00}, + {0x87,0xb0}, + + //// small RGB gamma//// + {0xfe, 0x02}, + {0x15, 0x0b}, + {0x16, 0x0e}, + {0x17, 0x10}, + {0x18, 0x12}, + {0x19, 0x19}, + {0x1a, 0x21}, + {0x1b, 0x29}, + {0x1c, 0x31}, + {0x1d, 0x41}, + {0x1e, 0x50}, + {0x1f, 0x5f}, + {0x20, 0x6d}, + {0x21, 0x79}, + {0x22, 0x91}, + {0x23, 0xa5}, + {0x24, 0xb9}, + {0x25, 0xc9}, + {0x26, 0xe1}, + {0x27, 0xee}, + {0x28, 0xf7}, + {0x29, 0xff}, + + ////dark sun///// + {0xfe, 0x02}, + {0x40, 0x06}, + {0x41, 0x23}, + {0x42, 0x3f}, + {0x43, 0x06}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x14}, + {0x47, 0x09}, + #endif + #ifdef Auto_LSC_debug + {0xfe , 0x00}, + {0x80 , 0x08}, + {0x81 , 0x00}, + {0x82 , 0x00}, + {0xa3 , 0x80}, + {0xa4 , 0x80}, + {0xa5 , 0x80}, + {0xa6 , 0x80}, + {0xa7 , 0x80}, + {0xa8 , 0x80}, + {0xa9 , 0x80}, + {0xaa , 0x80}, + {0xad , 0x80}, + {0xae , 0x80}, + {0xaf , 0x80}, + {0xb3 , 0x40}, + {0xb4 , 0x40}, + {0xb5 , 0x40}, + {0xfe , 0x01}, + {0x0a , 0x40}, + {0x13 , 0x48}, + {0x9f , 0x40}, + {0xfe , 0x02}, + {0xd0 , 0x40}, + {0xd1 , 0x20}, + {0xd2 , 0x20}, + {0xd3 , 0x40}, + {0xd5 , 0x00}, + {0xdd , 0x00}, + {0xfe , 0x00}, + #endif + }; + +/* 640x480 VGA,15fps*/ +static struct regval_list sensor_vga_regs_hres2[] ={}; + +/* 352x288 CIF,15fps*/ +static struct regval_list sensor_cif_regs_hres2[] = {}; + +/* 320x240 QVGA,15fps*/ +static struct regval_list sensor_qvga_regs_hres2[] = {}; + +static struct sensor_win_size +sensor_win_sizes_hres0[] = +{ + /* UXGA */ + { + .width = UXGA_WIDTH, + .height = UXGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_uxga_regs_hres0, + .regs_size = ARRAY_SIZE(sensor_uxga_regs_hres0), + .set_size = NULL, + }, + /* 720p */ + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = Gc2015_sensor_hd720_regs_hres0, + .regs_size = ARRAY_SIZE(Gc2015_sensor_hd720_regs_hres0), + .set_size = NULL, + }, + /* VGA */ + { + .width = VGA_WIDTH, + .height = VGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_vga_regs_hres0, + .regs_size = ARRAY_SIZE(sensor_vga_regs_hres0), + .set_size = NULL, + }, }; -/* 800X600 SVGA,20fps*/ -static struct regval_list sensor_svga_regs[] = -{ -{0xfe,0x00}, -{0xb6,0x03}, -{0xfa,0x00}, -{0xc8,0x00},//close scaler - -{0x99,0x22},// 1/2 subsample -{0x9a,0x07}, -{0x9b,0x00}, -{0x9c,0x00}, -{0x9d,0x00}, -{0x9e,0x00}, -{0x9f,0x00}, -{0xa0,0x00}, -{0xa1,0x00}, -{0xa2,0x00}, - -{0x90,0x01}, //crop enable -{0x95,0x02}, -{0x96,0x58}, -{0x97,0x03}, -{0x98,0x20}, +static struct sensor_win_size +sensor_win_sizes_hres1[] = +{ + /* UXGA */ + { + .width = UXGA_WIDTH, + .height = UXGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_uxga_regs_hres1, + .regs_size = ARRAY_SIZE(sensor_uxga_regs_hres1), + .set_size = NULL, + }, + /* SVGA */ + { + .width = SVGA_WIDTH, + .height = SVGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_svga_regs_hres1, + .regs_size = ARRAY_SIZE(sensor_svga_regs_hres1), + .set_size = NULL, + }, }; -/* 640x480 VGA,20fps*/ -static struct regval_list sensor_vga_regs[] = -{ -{0xfe,0x00}, -{0xb6,0x03}, -{0xfa,0x00}, -{0xc8,0x02}, //close scaler - -{0x99,0x22},// 1/2 subsample -{0x9a,0x06}, -{0x9b,0x00}, -{0x9c,0x00}, -{0x9d,0x00}, -{0x9e,0x00}, -{0x9f,0x00}, -{0xa0,0x00}, -{0xa1,0x00}, -{0xa2,0x00}, - -{0x90,0x01}, //crop enable -{0x95,0x02}, -{0x96,0x58}, -{0x97,0x03}, -{0x98,0x20}, +static struct sensor_win_size +sensor_win_sizes_hres2[] = +{ + /* VGA */ + { + .width = VGA_WIDTH, + .height = VGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_vga_regs_hres2, + .regs_size = ARRAY_SIZE(sensor_vga_regs_hres2), + .set_size = NULL, + }, + /* CIF */ + { + .width = CIF_WIDTH, + .height = CIF_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_cif_regs_hres2, + .regs_size = ARRAY_SIZE(sensor_qvga_regs_hres2), + .set_size = NULL, + }, + /* QVGA */ + { + .width = QVGA_WIDTH, + .height = QVGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_qvga_regs_hres2, + .regs_size = ARRAY_SIZE(sensor_qvga_regs_hres2), + .set_size = NULL, + }, }; -/* 320x240 QVGA,20fps*/ -static struct regval_list sensor_qvga_regs[] = -{ -{0xfe,0x00}, -{0xb6,0x03}, -{0xfa,0x00}, -{0xc8,0x02}, //close scaler - -{0x99,0x44},// 1/2 subsample -{0x9a,0x06}, -{0x9b,0x00}, -{0x9c,0x00}, -{0x9d,0x00}, -{0x9e,0x00}, -{0x9f,0x00}, -{0xa0,0x00}, -{0xa1,0x00}, -{0xa2,0x00}, - -{0x90,0x01}, //crop enable -{0x95,0x02}, -{0x96,0x58}, -{0x97,0x03}, -{0x98,0x20}, +static struct sensor_win_size +sensor_win_sizes_hres3[] = +{ + /* UXGA */ + { + .width = UXGA_WIDTH, + .height = UXGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_uxga_regs_hres3, + .regs_size = ARRAY_SIZE(sensor_uxga_regs_hres3), + .set_size = NULL, + }, + /* SVGA */ + { + .width = SVGA_WIDTH, + .height = SVGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_svga_regs_hres3, + .regs_size = ARRAY_SIZE(sensor_svga_regs_hres3), + .set_size = NULL, + }, + /* VGA */ + { + .width = VGA_WIDTH, + .height = VGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_vga_regs_hres3, + .regs_size = ARRAY_SIZE(sensor_vga_regs_hres3), + .set_size = NULL, + }, + /* QVGA */ + { + .width = QVGA_WIDTH, + .height = QVGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .regs = sensor_qvga_regs_hres3, + .regs_size = ARRAY_SIZE(sensor_qvga_regs_hres3), + .set_size = NULL, + }, }; -////1280*720---init---/// -//static struct regval_list Gc2015_sensor_hd720_regs[] = { -// -// -//{0xfe , 0x00}, -//{0x05, 0x01}, -//{0x06, 0x9e}, -//{0x07, 0x01}, -//{0x08, 0x6d}, -//{0x0a , 0xf0}, //row start -//{0x0c , 0xa0}, //col start -//{0x0d , 0x02}, -//{0x0e , 0xd8}, -//{0x0f , 0x05}, //Window setting -//{0x10 , 0x18}, -// -//{0xfe, 0x01}, -//{0x27, 0x00}, -//{0x28, 0xd9}, -//{0x29, 0x04}, -//{0x2a, 0x3d},//18fps -//{0x2b, 0x06}, -//{0x2c, 0xc8},//12.5fps -//{0x2d, 0x0a}, -//{0x2e, 0x2c},//8fps -//{0x3e, 0x40},//0x40 0x00 -// -////measure window -//{0xfe, 0x00}, -//{0xec, 0x04}, -//{0xed, 0x04}, -//{0xee, 0x50}, -//{0xef, 0x58}, -// -// -// -// -//{0x90 , 0x01}, //crop enable -//{0x95 , 0x02}, -//{0x96 , 0xd0}, -//{0x97 , 0x05}, -//{0x98 , 0x00}, -// -// -//{0xfe , 0x03}, -//{0x42 , 0x80}, -//{0x43 , 0x06}, //output buf width -//{0x41 , 0x00}, // delay -//{0x40 , 0x00}, //fifo half full trig -//{0x17 , 0x01}, //widv -//{0xfe , 0x00}, -// -// -//{0x99, 0x11}, -//{0xc8, 0x00}, -// -//{0xfa, 0x11}, -// -// -// -// -// -//{0xff, 0xff}, -// -// -// -//}; - - - /* * The white balance settings - * Here only tune the R G B channel gain. + * Here only tune the R G B channel gain. * The white balance enalbe bit is modified in sensor_s_autowb and sensor_s_wb */ -static struct regval_list sensor_wb_manual[] = { -//null -}; +static struct regval_list sensor_wb_manual[] = {}; -static struct regval_list sensor_wb_auto_regs[] = { +static struct regval_list sensor_wb_auto_regs[] = +{ {0x82, 0xfe}, {0xb3, 0x61}, - {0xb4, 0x40}, + {0xb4, 0x40}, {0xb5, 0x61}, {0xff, 0xff}, }; -static struct regval_list sensor_wb_incandescence_regs[] = { - //bai re guang +static struct regval_list sensor_wb_incandescence_regs[] = +{ + //bai re guang {0x82, 0xfd}, {0xb3, 0x50}, - {0xb4, 0x40}, + {0xb4, 0x40}, {0xb5, 0xa8}, - {0xff, 0xff}, + {0xff, 0xff}, }; -static struct regval_list sensor_wb_fluorescent_regs[] = { +static struct regval_list sensor_wb_fluorescent_regs[] = +{ //ri guang deng {0x82, 0xfd}, {0xb3, 0x72}, - {0xb4, 0x40}, + {0xb4, 0x40}, {0xb5, 0x5b}, - {0xff, 0xff}, + {0xff, 0xff}, }; -static struct regval_list sensor_wb_tungsten_regs[] = { +static struct regval_list sensor_wb_tungsten_regs[] = +{ //wu si deng {0x82, 0xfd}, {0xb3, 0xa0}, - {0xb4, 0x45}, + {0xb4, 0x45}, {0xb5, 0x40}, - {0xff, 0xff}, + {0xff, 0xff}, }; -static struct regval_list sensor_wb_horizon[] = { -//null -}; -static struct regval_list sensor_wb_daylight_regs[] = { +static struct regval_list sensor_wb_horizon[] = {}; + +static struct regval_list sensor_wb_daylight_regs[] = +{ //tai yang guang - //Sunny + //Sunny {0x82, 0xfd}, {0xb3, 0x58}, - {0xb4, 0x40}, + {0xb4, 0x40}, {0xb5, 0x50}, - {0xff, 0xff}, + {0xff, 0xff}, }; -static struct regval_list sensor_wb_flash[] = { -//null -}; +static struct regval_list sensor_wb_flash[] = {}; -static struct regval_list sensor_wb_cloud_regs[] = { +static struct regval_list sensor_wb_cloud_regs[] = +{ {0x82, 0xfd}, {0xb3, 0x58}, - {0xb4, 0x40}, + {0xb4, 0x40}, {0xb5, 0x50}, {0xff, 0xff}, }; -static struct regval_list sensor_wb_shade[] = { -//null -}; +static struct regval_list sensor_wb_shade[] = {}; -static struct cfg_array sensor_wb[] = { - { - .regs = sensor_wb_manual, //V4L2_WHITE_BALANCE_MANUAL +static struct cfg_array sensor_wb[] = +{ + { + .regs = sensor_wb_manual, //V4L2_WHITE_BALANCE_MANUAL .size = ARRAY_SIZE(sensor_wb_manual), }, { - .regs = sensor_wb_auto_regs, //V4L2_WHITE_BALANCE_AUTO + .regs = sensor_wb_auto_regs, //V4L2_WHITE_BALANCE_AUTO .size = ARRAY_SIZE(sensor_wb_auto_regs), }, { - .regs = sensor_wb_incandescence_regs, //V4L2_WHITE_BALANCE_INCANDESCENT + .regs = sensor_wb_incandescence_regs, //V4L2_WHITE_BALANCE_INCANDESCENT .size = ARRAY_SIZE(sensor_wb_incandescence_regs), }, { - .regs = sensor_wb_fluorescent_regs, //V4L2_WHITE_BALANCE_FLUORESCENT + .regs = sensor_wb_fluorescent_regs, //V4L2_WHITE_BALANCE_FLUORESCENT .size = ARRAY_SIZE(sensor_wb_fluorescent_regs), }, { @@ -1032,23 +3428,23 @@ static struct cfg_array sensor_wb[] = { .size = ARRAY_SIZE(sensor_wb_tungsten_regs), }, { - .regs = sensor_wb_horizon, //V4L2_WHITE_BALANCE_HORIZON + .regs = sensor_wb_horizon, //V4L2_WHITE_BALANCE_HORIZON .size = ARRAY_SIZE(sensor_wb_horizon), - }, + }, { - .regs = sensor_wb_daylight_regs, //V4L2_WHITE_BALANCE_DAYLIGHT + .regs = sensor_wb_daylight_regs, //V4L2_WHITE_BALANCE_DAYLIGHT .size = ARRAY_SIZE(sensor_wb_daylight_regs), }, { - .regs = sensor_wb_flash, //V4L2_WHITE_BALANCE_FLASH + .regs = sensor_wb_flash, //V4L2_WHITE_BALANCE_FLASH .size = ARRAY_SIZE(sensor_wb_flash), }, { - .regs = sensor_wb_cloud_regs, //V4L2_WHITE_BALANCE_CLOUDY + .regs = sensor_wb_cloud_regs, //V4L2_WHITE_BALANCE_CLOUDY .size = ARRAY_SIZE(sensor_wb_cloud_regs), }, { - .regs = sensor_wb_shade, //V4L2_WHITE_BALANCE_SHADE + .regs = sensor_wb_shade, //V4L2_WHITE_BALANCE_SHADE .size = ARRAY_SIZE(sensor_wb_shade), }, // { @@ -1056,136 +3452,119 @@ static struct cfg_array sensor_wb[] = { // .size = 0, // }, }; - + /* * The color effect settings */ -static struct regval_list sensor_colorfx_none_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_none_regs[] = +{ + {0xfe, 0x00}, {0x83, 0xe0}, - }; -static struct regval_list sensor_colorfx_bw_regs[] = { - -}; +static struct regval_list sensor_colorfx_bw_regs[] = {}; -static struct regval_list sensor_colorfx_sepia_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_sepia_regs[] = +{ + {0xfe, 0x00}, {0x83, 0x82}, - }; -static struct regval_list sensor_colorfx_negative_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_negative_regs[] = +{ + {0xfe, 0x00}, {0x83, 0x01}, - }; -static struct regval_list sensor_colorfx_emboss_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_emboss_regs[] = +{ + {0xfe, 0x00}, {0x83, 0x12},///CAM_EFFECT_ENC_GRAYSCALE }; -static struct regval_list sensor_colorfx_sketch_regs[] = { -//NULL -}; +static struct regval_list sensor_colorfx_sketch_regs[] = {}; -static struct regval_list sensor_colorfx_sky_blue_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_sky_blue_regs[] = +{ + {0xfe, 0x00}, {0x83, 0x62}, - }; -static struct regval_list sensor_colorfx_grass_green_regs[] = { - {0xfe, 0x00}, +static struct regval_list sensor_colorfx_grass_green_regs[] = +{ + {0xfe, 0x00}, {0x83, 0x52}, }; -static struct regval_list sensor_colorfx_skin_whiten_regs[] = { -//NULL -}; +static struct regval_list sensor_colorfx_skin_whiten_regs[] = {}; -static struct regval_list sensor_colorfx_vivid_regs[] = { -//NULL -}; +static struct regval_list sensor_colorfx_vivid_regs[] = {}; -static struct regval_list sensor_colorfx_aqua_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_aqua_regs[] = {}; -static struct regval_list sensor_colorfx_art_freeze_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_art_freeze_regs[] = {}; -static struct regval_list sensor_colorfx_silhouette_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_silhouette_regs[] = {}; -static struct regval_list sensor_colorfx_solarization_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_solarization_regs[] = {}; -static struct regval_list sensor_colorfx_antique_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_antique_regs[] = {}; -static struct regval_list sensor_colorfx_set_cbcr_regs[] = { -//null -}; +static struct regval_list sensor_colorfx_set_cbcr_regs[] = {}; -static struct cfg_array sensor_colorfx[] = { +static struct cfg_array sensor_colorfx[] = +{ { - .regs = sensor_colorfx_none_regs, //V4L2_COLORFX_NONE = 0, + .regs = sensor_colorfx_none_regs, //V4L2_COLORFX_NONE = 0, .size = ARRAY_SIZE(sensor_colorfx_none_regs), }, { - .regs = sensor_colorfx_bw_regs, //V4L2_COLORFX_BW = 1, + .regs = sensor_colorfx_bw_regs, //V4L2_COLORFX_BW = 1, .size = ARRAY_SIZE(sensor_colorfx_bw_regs), }, { - .regs = sensor_colorfx_sepia_regs, //V4L2_COLORFX_SEPIA = 2, + .regs = sensor_colorfx_sepia_regs, //V4L2_COLORFX_SEPIA = 2, .size = ARRAY_SIZE(sensor_colorfx_sepia_regs), }, { - .regs = sensor_colorfx_negative_regs, //V4L2_COLORFX_NEGATIVE = 3, + .regs = sensor_colorfx_negative_regs, //V4L2_COLORFX_NEGATIVE = 3, .size = ARRAY_SIZE(sensor_colorfx_negative_regs), }, { - .regs = sensor_colorfx_emboss_regs, //V4L2_COLORFX_EMBOSS = 4, + .regs = sensor_colorfx_emboss_regs, //V4L2_COLORFX_EMBOSS = 4, .size = ARRAY_SIZE(sensor_colorfx_emboss_regs), }, { - .regs = sensor_colorfx_sketch_regs, //V4L2_COLORFX_SKETCH = 5, + .regs = sensor_colorfx_sketch_regs, //V4L2_COLORFX_SKETCH = 5, .size = ARRAY_SIZE(sensor_colorfx_sketch_regs), }, { - .regs = sensor_colorfx_sky_blue_regs, //V4L2_COLORFX_SKY_BLUE = 6, + .regs = sensor_colorfx_sky_blue_regs, //V4L2_COLORFX_SKY_BLUE = 6, .size = ARRAY_SIZE(sensor_colorfx_sky_blue_regs), }, { - .regs = sensor_colorfx_grass_green_regs, //V4L2_COLORFX_GRASS_GREEN = 7, + .regs = sensor_colorfx_grass_green_regs, //V4L2_COLORFX_GRASS_GREEN = 7, .size = ARRAY_SIZE(sensor_colorfx_grass_green_regs), }, { - .regs = sensor_colorfx_skin_whiten_regs, //V4L2_COLORFX_SKIN_WHITEN = 8, + .regs = sensor_colorfx_skin_whiten_regs, //V4L2_COLORFX_SKIN_WHITEN = 8, .size = ARRAY_SIZE(sensor_colorfx_skin_whiten_regs), }, { - .regs = sensor_colorfx_vivid_regs, //V4L2_COLORFX_VIVID = 9, + .regs = sensor_colorfx_vivid_regs, //V4L2_COLORFX_VIVID = 9, .size = ARRAY_SIZE(sensor_colorfx_vivid_regs), }, { - .regs = sensor_colorfx_aqua_regs, //V4L2_COLORFX_AQUA = 10, + .regs = sensor_colorfx_aqua_regs, //V4L2_COLORFX_AQUA = 10, .size = ARRAY_SIZE(sensor_colorfx_aqua_regs), }, { - .regs = sensor_colorfx_art_freeze_regs, //V4L2_COLORFX_ART_FREEZE = 11, + .regs = sensor_colorfx_art_freeze_regs, //V4L2_COLORFX_ART_FREEZE = 11, .size = ARRAY_SIZE(sensor_colorfx_art_freeze_regs), }, { - .regs = sensor_colorfx_silhouette_regs, //V4L2_COLORFX_SILHOUETTE = 12, + .regs = sensor_colorfx_silhouette_regs, //V4L2_COLORFX_SILHOUETTE = 12, .size = ARRAY_SIZE(sensor_colorfx_silhouette_regs), }, { @@ -1193,57 +3572,38 @@ static struct cfg_array sensor_colorfx[] = { .size = ARRAY_SIZE(sensor_colorfx_solarization_regs), }, { - .regs = sensor_colorfx_antique_regs, //V4L2_COLORFX_ANTIQUE = 14, + .regs = sensor_colorfx_antique_regs, //V4L2_COLORFX_ANTIQUE = 14, .size = ARRAY_SIZE(sensor_colorfx_antique_regs), }, { - .regs = sensor_colorfx_set_cbcr_regs, //V4L2_COLORFX_SET_CBCR = 15, + .regs = sensor_colorfx_set_cbcr_regs, //V4L2_COLORFX_SET_CBCR = 15, .size = ARRAY_SIZE(sensor_colorfx_set_cbcr_regs), }, }; - - /* * The brightness setttings */ -static struct regval_list sensor_brightness_neg4_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_neg4_regs[] = {}; -static struct regval_list sensor_brightness_neg3_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_neg3_regs[] = {}; -static struct regval_list sensor_brightness_neg2_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_neg2_regs[] = {}; -static struct regval_list sensor_brightness_neg1_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_neg1_regs[] = {}; -static struct regval_list sensor_brightness_zero_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_zero_regs[] = {}; -static struct regval_list sensor_brightness_pos1_regs[] = { - //NULL -}; +static struct regval_list sensor_brightness_pos1_regs[] = {}; -static struct regval_list sensor_brightness_pos2_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_pos2_regs[] = {}; -static struct regval_list sensor_brightness_pos3_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_pos3_regs[] = {}; -static struct regval_list sensor_brightness_pos4_regs[] = { -//NULL -}; +static struct regval_list sensor_brightness_pos4_regs[] = {}; -static struct cfg_array sensor_brightness[] = { +static struct cfg_array sensor_brightness[] = +{ { .regs = sensor_brightness_neg4_regs, .size = ARRAY_SIZE(sensor_brightness_neg4_regs), @@ -1285,42 +3645,26 @@ static struct cfg_array sensor_brightness[] = { /* * The contrast setttings */ -static struct regval_list sensor_contrast_neg4_regs[] = { - -}; - -static struct regval_list sensor_contrast_neg3_regs[] = { - -}; - -static struct regval_list sensor_contrast_neg2_regs[] = { - -}; - -static struct regval_list sensor_contrast_neg1_regs[] = { - -}; +static struct regval_list sensor_contrast_neg4_regs[] = {}; -static struct regval_list sensor_contrast_zero_regs[] = { +static struct regval_list sensor_contrast_neg3_regs[] = {}; -}; +static struct regval_list sensor_contrast_neg2_regs[] = {}; -static struct regval_list sensor_contrast_pos1_regs[] = { +static struct regval_list sensor_contrast_neg1_regs[] = {}; -}; +static struct regval_list sensor_contrast_zero_regs[] = {}; -static struct regval_list sensor_contrast_pos2_regs[] = { +static struct regval_list sensor_contrast_pos1_regs[] = {}; -}; +static struct regval_list sensor_contrast_pos2_regs[] = {}; -static struct regval_list sensor_contrast_pos3_regs[] = { - -}; +static struct regval_list sensor_contrast_pos3_regs[] = {}; -static struct regval_list sensor_contrast_pos4_regs[] = { -}; +static struct regval_list sensor_contrast_pos4_regs[] = {}; -static struct cfg_array sensor_contrast[] = { +static struct cfg_array sensor_contrast[] = +{ { .regs = sensor_contrast_neg4_regs, .size = ARRAY_SIZE(sensor_contrast_neg4_regs), @@ -1362,43 +3706,26 @@ static struct cfg_array sensor_contrast[] = { /* * The saturation setttings */ -static struct regval_list sensor_saturation_neg4_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_neg4_regs[] = {}; -static struct regval_list sensor_saturation_neg3_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_neg3_regs[] = {}; -static struct regval_list sensor_saturation_neg2_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_neg2_regs[] = {}; -static struct regval_list sensor_saturation_neg1_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_neg1_regs[] = {}; -static struct regval_list sensor_saturation_zero_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_zero_regs[] = {}; -static struct regval_list sensor_saturation_pos1_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_pos1_regs[] = {}; -static struct regval_list sensor_saturation_pos2_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_pos2_regs[] = {}; -static struct regval_list sensor_saturation_pos3_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_pos3_regs[] = {}; -static struct regval_list sensor_saturation_pos4_regs[] = { -//NULL -}; +static struct regval_list sensor_saturation_pos4_regs[] = {}; -static struct cfg_array sensor_saturation[] = { +static struct cfg_array sensor_saturation[] = +{ { .regs = sensor_saturation_neg4_regs, .size = ARRAY_SIZE(sensor_saturation_neg4_regs), @@ -1440,79 +3767,89 @@ static struct cfg_array sensor_saturation[] = { /* * The exposure target setttings */ -static struct regval_list sensor_ev_neg4_regs[] = { +static struct regval_list sensor_ev_neg4_regs[] = +{ {0xfe, 0x01}, {0x13, 0x40}, {0xfe, 0x02}, - {0xd5, 0xc0}, + {0xd5, 0xc0}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_neg3_regs[] = { +static struct regval_list sensor_ev_neg3_regs[] = +{ {0xfe, 0x01}, - {0x13, 0x50}, + {0x13, 0x50}, {0xfe, 0x02}, - {0xd5, 0xd0}, + {0xd5, 0xd0}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_neg2_regs[] = { +static struct regval_list sensor_ev_neg2_regs[] = +{ {0xfe, 0x01}, - {0x13, 0x60}, + {0x13, 0x60}, {0xfe, 0x02}, - {0xd5, 0xe0}, + {0xd5, 0xe0}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_neg1_regs[] = { +static struct regval_list sensor_ev_neg1_regs[] = +{ {0xfe, 0x01}, - {0x13 , 0x70}, + {0x13, 0x70}, {0xfe, 0x02}, - {0xd5, 0xf0}, + {0xd5, 0xf0}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_zero_regs[] = { +static struct regval_list sensor_ev_zero_regs[] = +{ {0xfe, 0x01}, - {0x13 , 0x80}, + {0x13, 0x80}, {0xfe, 0x02}, - {0xd5, 0x00}, + {0xd5, 0x00}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_pos1_regs[] = { +static struct regval_list sensor_ev_pos1_regs[] = +{ {0xfe, 0x01}, - {0x13 , 0x98}, + {0x13, 0x98}, {0xfe, 0x02}, - {0xd5, 0x10}, + {0xd5, 0x10}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_pos2_regs[] = { +static struct regval_list sensor_ev_pos2_regs[] = +{ {0xfe, 0x01}, - {0x13 , 0xb0}, + {0x13, 0xb0}, {0xfe, 0x02}, - {0xd5, 0x20}, + {0xd5, 0x20}, {0xfe, 0x00}, }; -static struct regval_list sensor_ev_pos3_regs[] = { - {0xfe, 0x01}, - {0x13 , 0xc0}, +static struct regval_list sensor_ev_pos3_regs[] = +{ + {0xfe, 0x01}, + {0x13, 0xc0}, {0xfe, 0x02}, - {0xd5, 0x30}, - {0xfe, 0x00}, + {0xd5, 0x30}, + {0xfe, 0x00}, }; -static struct regval_list sensor_ev_pos4_regs[] = { +static struct regval_list sensor_ev_pos4_regs[] = +{ {0xfe, 0x01}, - {0x13 , 0xd0}, + {0x13, 0xd0}, {0xfe, 0x02}, - {0xd5, 0x50}, - {0xfe, 0x00}, + {0xd5, 0x50}, + {0xfe, 0x00}, }; -static struct cfg_array sensor_ev[] = { +static struct cfg_array sensor_ev[] = +{ { .regs = sensor_ev_neg4_regs, .size = ARRAY_SIZE(sensor_ev_neg4_regs), @@ -1554,112 +3891,205 @@ static struct cfg_array sensor_ev[] = { /* * Here we'll try to encapsulate the changes for just the output * video format. - * + * */ - -static struct regval_list sensor_fmt_yuv422_yuyv[] = { +static struct regval_list sensor_fmt_yuv422_yuyv[] = +{ {0x84, 0x02}, //output put foramat - }; - -static struct regval_list sensor_fmt_yuv422_yvyu[] = { +static struct regval_list sensor_fmt_yuv422_yvyu[] = +{ {0x84, 0x03}, //output put foramat - }; -static struct regval_list sensor_fmt_yuv422_vyuy[] = { +static struct regval_list sensor_fmt_yuv422_vyuy[] = +{ {0x84, 0x01}, //output put foramat - }; -static struct regval_list sensor_fmt_yuv422_uyvy[] = { +static struct regval_list sensor_fmt_yuv422_uyvy[] = +{ {0x84, 0x00}, //output put foramat - }; -static struct regval_list sensor_fmt_raw[] = { - +static struct regval_list sensor_fmt_raw[] = +{ {0x84, 0x18}, //output put foramat - - }; //misc -static struct regval_list sensor_oe_disable_regs[] = { +static struct regval_list sensor_oe_disable_regs[] = +{ //{0x3002,0x00}, //{REG_TERM,VAL_TERM}, }; -static struct regval_list sensor_oe_enable_regs[] = { +static struct regval_list sensor_oe_enable_regs[] = +{ //{0x3002,0xe4}, //{REG_TERM,VAL_TERM}, }; - - /* - * Low-level register I/O. - * + * Store information about the video data format. */ - - +static struct sensor_format_struct +{ + __u8 *desc; + //__u32 pixelformat; + enum v4l2_mbus_pixelcode mbus_code;//linux-3.0 + struct regval_list *regs; + int regs_size; + int bpp; /* Bytes per pixel */ +} sensor_formats[] = { + { + .desc = "UYVY 4:2:2", + .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,//linux-3.0 + .regs = sensor_fmt_yuv422_uyvy, + .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_uyvy), + .bpp = 2, + }, + { + .desc = "YUYV 4:2:2", + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,//linux-3.0 + .regs = sensor_fmt_yuv422_yuyv, + .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yuyv), + .bpp = 2, + }, + { + .desc = "YVYU 4:2:2", + .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,//linux-3.0 + .regs = sensor_fmt_yuv422_yvyu, + .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yvyu), + .bpp = 2, + }, + { + .desc = "VYUY 4:2:2", + .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,//linux-3.0 + .regs = sensor_fmt_yuv422_vyuy, + .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_vyuy), + .bpp = 2, + }, + // when try set format as bgr24 for example, this format was returned + { + .desc = "Raw RGB Bayer", + .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0 + .regs = sensor_fmt_raw, + .regs_size = ARRAY_SIZE(sensor_fmt_raw), + .bpp = 1 + }, +}; +#define N_FMTS ARRAY_SIZE(sensor_formats) + +/* + * Store information about resolutions mode support. + */ +static struct sensor_resolutions_struct +{ + struct regval_list *regs; + struct sensor_win_size *win_sizes; + int nwin_sizes; + int nsize; + int framerate; + int mclk; +} sensor_resolutions[] = { + { + .regs = sensor_default_regs_hres0, + .win_sizes = sensor_win_sizes_hres0, + .nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres0)), + .nsize = ARRAY_SIZE(sensor_default_regs_hres0), + .framerate = 8, + .mclk = 24, + }, + { + .regs = sensor_default_regs_hres1, + .win_sizes = sensor_win_sizes_hres1, + .nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres1)), + .nsize = ARRAY_SIZE(sensor_default_regs_hres1), + .framerate = 10, + .mclk = 24, + }, + { + .regs = sensor_default_regs_hres2, + .win_sizes = sensor_win_sizes_hres2, + .nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres2)), + .nsize = ARRAY_SIZE(sensor_default_regs_hres2), + .framerate = 15, + .mclk = 24, + }, + { + .regs = sensor_default_regs_hres3, + .win_sizes = sensor_win_sizes_hres3, + .nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres3)), + .nsize = ARRAY_SIZE(sensor_default_regs_hres3), + .framerate = 20, + .mclk = 34, + }, +}; +#define N_RESOLUTIONS ARRAY_SIZE(sensor_resolutions) + +/* + * Low-level register I/O. + * + */ + /* * On most platforms, we'd rather do straight i2c I/O. */ static int sensor_read(struct v4l2_subdev *sd, unsigned char reg, unsigned char *value) //!!!!be careful of the para type!!! { - int ret=0; - int cnt=0; - + int ret = 0; + int cnt = 0; + ret = cci_read_a8_d8(sd,reg,value); - while(ret!=0&&cnt<2) + while (ret !=0 && cnt < 2) { ret = cci_read_a8_d8(sd,reg,value); cnt++; } - if(cnt>0) + if (cnt > 0) vfe_dev_dbg("sensor read retry=%d\n",cnt); - + return ret; } static int sensor_write(struct v4l2_subdev *sd, unsigned short reg, unsigned char value) { - int ret=0; - int cnt=0; + int ret = 0; + int cnt = 0; ret = cci_write_a8_d8(sd,reg,value); - while(ret!=0&&cnt<2) + while (ret !=0 && cnt < 2) { ret = cci_write_a8_d8(sd,reg,value); cnt++; } - if(cnt>0) + if (cnt > 0) vfe_dev_dbg("sensor write retry=%d\n",cnt); return ret; } - /* * Write a list of register settings; */ static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size) { - int i=0; - - if(!regs) - return -EINVAL; - - while(iaddr == REG_DLY) { + if (regs->addr == REG_DLY) + { msleep(regs->data); - } - else { + } + else + { //printk("write 0x%x=0x%x\n", regs->addr, regs->data); LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data)) } @@ -1676,22 +4106,24 @@ static int sensor_g_hflip(struct v4l2_subdev *sd, __s32 *value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_g_hflip!\n"); return ret; } - + ret = sensor_read(sd, 0x17, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_g_hflip!\n"); return ret; } - + val &= (1<<0); val = val>>0; //0x29 bit0 is mirror - + *value = val; info->hflip = *value; @@ -1704,19 +4136,22 @@ static int sensor_s_hflip(struct v4l2_subdev *sd, int value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_hflip!\n"); return ret; } ret = sensor_read(sd, 0x17, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_s_hflip!\n"); return ret; } - - switch (value) { + + switch (value) + { case 0: val &= 0xfe; break; @@ -1727,13 +4162,14 @@ static int sensor_s_hflip(struct v4l2_subdev *sd, int value) return -EINVAL; } ret = sensor_write(sd, 0x17, val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_hflip!\n"); return ret; } - + usleep_range(20000,22000); - + info->hflip = value; return 0; } @@ -1744,22 +4180,24 @@ static int sensor_g_vflip(struct v4l2_subdev *sd, __s32 *value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_g_vflip!\n"); return ret; } - + ret = sensor_read(sd, 0x17, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_g_vflip!\n"); return ret; } - + val &= (1<<1); val = val>>1; //0x29 bit1 is upsidedown - + *value = val; info->vflip = *value; @@ -1772,20 +4210,23 @@ static int sensor_s_vflip(struct v4l2_subdev *sd, int value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_vflip!\n"); return ret; } - + ret = sensor_read(sd, 0x17, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_s_vflip!\n"); return ret; } - - switch (value) { + + switch (value) + { case 0: val &= 0xfd; break; @@ -1795,14 +4236,16 @@ static int sensor_s_vflip(struct v4l2_subdev *sd, int value) default: return -EINVAL; } + ret = sensor_write(sd, 0x17, val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_vflip!\n"); return ret; } - + usleep_range(20000,22000); - + info->vflip = value; return 0; } @@ -1821,30 +4264,32 @@ static int sensor_g_autoexp(struct v4l2_subdev *sd, __s32 *value) { int ret; struct sensor_info *info = to_state(sd); -// struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_g_autoexp!\n"); return ret; } - + ret = sensor_read(sd, 0xb6, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_g_autoexp!\n"); return ret; } val &= 0x01; - if (val == 0x01) { + if (val == 0x01) + { *value = V4L2_EXPOSURE_AUTO; } else { *value = V4L2_EXPOSURE_MANUAL; } - + info->autoexp = *value; return 0; } @@ -1856,20 +4301,23 @@ static int sensor_s_autoexp(struct v4l2_subdev *sd, struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_autoexp!\n"); return ret; } - + ret = sensor_read(sd, 0xb6, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_s_autoexp!\n"); return ret; } - switch (value) { + switch (value) + { case V4L2_EXPOSURE_AUTO: val |= 0x01; break; @@ -1877,21 +4325,21 @@ static int sensor_s_autoexp(struct v4l2_subdev *sd, val &= 0xfe; break; case V4L2_EXPOSURE_SHUTTER_PRIORITY: - return -EINVAL; + return -EINVAL; case V4L2_EXPOSURE_APERTURE_PRIORITY: return -EINVAL; default: return -EINVAL; } - + //ret = sensor_write(sd, 0xb6, val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_autoexp!\n"); return ret; } - + usleep_range(10000,12000); - info->autoexp = value; return 0; } @@ -1902,25 +4350,26 @@ static int sensor_g_autowb(struct v4l2_subdev *sd, int *value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write(sd, 0xfe, 0x00); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_g_autowb!\n"); return ret; } - + ret = sensor_read(sd, 0x82, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_g_autowb!\n"); return ret; } val &= (1<<1); val = val>>1; //0x42 bit1 is awb enable - + *value = val; info->autowb = *value; - return 0; } @@ -1930,20 +4379,23 @@ static int sensor_s_autowb(struct v4l2_subdev *sd, int value) struct sensor_info *info = to_state(sd); // struct regval_list regs; unsigned char val; - + ret = sensor_write_array(sd, sensor_wb_auto_regs, ARRAY_SIZE(sensor_wb_auto_regs)); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write_array err at sensor_s_autowb!\n"); return ret; } - + ret = sensor_read(sd, 0x82, &val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_read err at sensor_s_autowb!\n"); return ret; } - switch(value) { + switch(value) + { case 0: val &= 0xfd; break; @@ -1952,15 +4404,15 @@ static int sensor_s_autowb(struct v4l2_subdev *sd, int value) break; default: break; - } + } ret = sensor_write(sd, 0x82, val); - if (ret < 0) { + if (ret < 0) + { vfe_dev_err("sensor_write err at sensor_s_autowb!\n"); return ret; } - + usleep_range(10000,12000); - info->autowb = value; return 0; } @@ -1990,7 +4442,6 @@ static int sensor_s_gain(struct v4l2_subdev *sd, int value) static int sensor_g_brightness(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); - *value = info->brightness; return 0; } @@ -1998,13 +4449,13 @@ static int sensor_g_brightness(struct v4l2_subdev *sd, __s32 *value) static int sensor_s_brightness(struct v4l2_subdev *sd, int value) { struct sensor_info *info = to_state(sd); - + if(info->brightness == value) return 0; - + if(value < -4 || value > 4) return -ERANGE; - + LOG_ERR_RET(sensor_write_array(sd, sensor_brightness[value+4].regs, sensor_brightness[value+4].size)) info->brightness = value; @@ -2014,7 +4465,6 @@ static int sensor_s_brightness(struct v4l2_subdev *sd, int value) static int sensor_g_contrast(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); - *value = info->contrast; return 0; } @@ -2022,15 +4472,13 @@ static int sensor_g_contrast(struct v4l2_subdev *sd, __s32 *value) static int sensor_s_contrast(struct v4l2_subdev *sd, int value) { struct sensor_info *info = to_state(sd); - - if(info->contrast == value) - return 0; - - if(value < -4 || value > 4) - return -ERANGE; - + + if (info->contrast == value) return 0; + + if (value < -4 || value > 4) return -ERANGE; + LOG_ERR_RET(sensor_write_array(sd, sensor_contrast[value+4].regs, sensor_contrast[value+4].size)) - + info->contrast = value; return 0; } @@ -2038,7 +4486,6 @@ static int sensor_s_contrast(struct v4l2_subdev *sd, int value) static int sensor_g_saturation(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); - *value = info->saturation; return 0; } @@ -2046,13 +4493,11 @@ static int sensor_g_saturation(struct v4l2_subdev *sd, __s32 *value) static int sensor_s_saturation(struct v4l2_subdev *sd, int value) { struct sensor_info *info = to_state(sd); - - if(info->saturation == value) - return 0; - if(value < -4 || value > 4) - return -ERANGE; - + if (info->saturation == value) return 0; + + if(value < -4 || value > 4) return -ERANGE; + LOG_ERR_RET(sensor_write_array(sd, sensor_saturation[value+4].regs, sensor_saturation[value+4].size)) info->saturation = value; @@ -2062,7 +4507,6 @@ static int sensor_s_saturation(struct v4l2_subdev *sd, int value) static int sensor_g_exp_bias(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); - *value = info->exp_bias; return 0; } @@ -2071,12 +4515,10 @@ static int sensor_s_exp_bias(struct v4l2_subdev *sd, int value) { struct sensor_info *info = to_state(sd); - if(info->exp_bias == value) - return 0; + if(info->exp_bias == value) return 0; + + if(value < -4 || value > 4) return -ERANGE; - if(value < -4 || value > 4) - return -ERANGE; - LOG_ERR_RET(sensor_write_array(sd, sensor_ev[value+4].regs, sensor_ev[value+4].size)) info->exp_bias = value; @@ -2087,9 +4529,9 @@ static int sensor_g_wb(struct v4l2_subdev *sd, int *value) { struct sensor_info *info = to_state(sd); enum v4l2_auto_n_preset_white_balance *wb_type = (enum v4l2_auto_n_preset_white_balance*)value; - + *wb_type = info->wb; - + return 0; } @@ -2097,101 +4539,71 @@ static int sensor_s_wb(struct v4l2_subdev *sd, enum v4l2_auto_n_preset_white_balance value) { struct sensor_info *info = to_state(sd); - - if(info->capture_mode == V4L2_MODE_IMAGE) - return 0; - - if(info->wb == value) - return 0; - + + if (info->capture_mode == V4L2_MODE_IMAGE) return 0; + + if (info->wb == value) return 0; + LOG_ERR_RET(sensor_write_array(sd, sensor_wb[value].regs ,sensor_wb[value].size) ) - - if (value == V4L2_WHITE_BALANCE_AUTO) + + if (value == V4L2_WHITE_BALANCE_AUTO) + { info->autowb = 1; - else + } else { info->autowb = 0; - + } + info->wb = value; return 0; } -static int sensor_g_colorfx(struct v4l2_subdev *sd, - __s32 *value) +static int sensor_g_colorfx(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); enum v4l2_colorfx *clrfx_type = (enum v4l2_colorfx*)value; - + *clrfx_type = info->clrfx; return 0; } -static int sensor_s_colorfx(struct v4l2_subdev *sd, - enum v4l2_colorfx value) +static int sensor_s_colorfx(struct v4l2_subdev *sd, enum v4l2_colorfx value) { struct sensor_info *info = to_state(sd); if(info->clrfx == value) return 0; - + LOG_ERR_RET(sensor_write_array(sd, sensor_colorfx[value].regs, sensor_colorfx[value].size)) info->clrfx = value; return 0; } -static int sensor_g_flash_mode(struct v4l2_subdev *sd, - __s32 *value) +static int sensor_g_flash_mode(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); enum v4l2_flash_led_mode *flash_mode = (enum v4l2_flash_led_mode*)value; - + *flash_mode = info->flash_mode; return 0; } -static int sensor_s_flash_mode(struct v4l2_subdev *sd, - enum v4l2_flash_led_mode value) +static int sensor_s_flash_mode(struct v4l2_subdev *sd, enum v4l2_flash_led_mode value) { struct sensor_info *info = to_state(sd); -// struct vfe_dev *dev=(struct vfe_dev *)dev_get_drvdata(sd->v4l2_dev->dev); -// int flash_on,flash_off; -// -// flash_on = (dev->flash_pol!=0)?1:0; -// flash_off = (flash_on==1)?0:1; -// -// switch (value) { -// case V4L2_FLASH_MODE_OFF: -// os_gpio_write(&dev->flash_io,flash_off); -// break; -// case V4L2_FLASH_MODE_AUTO: -// return -EINVAL; -// break; -// case V4L2_FLASH_MODE_ON: -// os_gpio_write(&dev->flash_io,flash_on); -// break; -// case V4L2_FLASH_MODE_TORCH: -// return -EINVAL; -// break; -// case V4L2_FLASH_MODE_RED_EYE: -// return -EINVAL; -// break; -// default: -// return -EINVAL; -// } - info->flash_mode = value; return 0; } static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) { - int ret=0; + int ret = 0; // unsigned char rdval; -// +// // ret=sensor_read(sd, 0x00, &rdval); // if(ret!=0) // return ret; -// +// // if(on_off==CSI_STBY_ON)//sw stby on // { // ret=sensor_write(sd, 0x00, rdval&0x7f); @@ -2206,11 +4618,11 @@ static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) /* * Stuff that knows about the sensor. */ - + static int sensor_power(struct v4l2_subdev *sd, int on) { int ret; - + cci_lock(sd); switch(on) { @@ -2236,7 +4648,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) vfe_gpio_write(sd,PWDN, CSI_GPIO_LOW); usleep_range(10000,12000); //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk_freq(sd, (MCLK*1000*1000)); vfe_set_mclk(sd,ON); usleep_range(10000,12000); vfe_dev_print("enable oe!\n"); @@ -2248,7 +4660,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) vfe_dev_dbg("CSI_SUBDEV_PWR_ON\n"); vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk_freq(sd,(MCLK*1000*1000)); vfe_set_mclk(sd,ON); vfe_gpio_write(sd,PWDN, CSI_GPIO_LOW); vfe_gpio_write(sd,RESET, CSI_GPIO_LOW); @@ -2271,12 +4683,12 @@ static int sensor_power(struct v4l2_subdev *sd, int on) usleep_range(5000,12000); //power supply off vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); usleep_range(5000,12000); - vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); vfe_set_pmu_channel(sd,AFVDD,OFF); vfe_set_pmu_channel(sd,DVDD,OFF); vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); usleep_range(10000,12000); vfe_set_mclk(sd,OFF); vfe_gpio_set_status(sd,RESET,0);//set the gpio to input @@ -2284,11 +4696,11 @@ static int sensor_power(struct v4l2_subdev *sd, int on) break; default: return -EINVAL; - } - cci_unlock(sd); + } + cci_unlock(sd); return 0; } - + static int sensor_reset(struct v4l2_subdev *sd, u32 val) { switch(val) @@ -2304,46 +4716,46 @@ static int sensor_reset(struct v4l2_subdev *sd, u32 val) default: return -EINVAL; } - + return 0; } static int sensor_detect(struct v4l2_subdev *sd) { int ret; - unsigned int SENSOR_ID=0; + unsigned int SENSOR_ID = 0; unsigned char val; - + // ret = sensor_write(sd, 0xfe, 0x00); // if (ret < 0) { // vfe_dev_err("sensor_write err at sensor_detect!\n"); // return ret; // } - + ret = sensor_read(sd, 0xf0, &val); SENSOR_ID|= (val<< 8); if (ret < 0) { vfe_dev_err("sensor_read err at sensor_detect!\n"); return ret; } - + ret = sensor_read(sd, 0xf1, &val); - SENSOR_ID|= (val); + SENSOR_ID |= (val); vfe_dev_print("V4L2_IDENT_SENSOR=%x",SENSOR_ID); if (ret < 0) { vfe_dev_err("sensor_read err at sensor_detect!\n"); return ret; } - + if(SENSOR_ID != V4L2_IDENT_SENSOR) return -ENODEV; - + return 0; } static int sensor_init(struct v4l2_subdev *sd, u32 val) { - int ret; + int ret, nsize; vfe_dev_dbg("sensor_init\n"); /*Make sure it is a target sensor*/ ret = sensor_detect(sd); @@ -2351,15 +4763,17 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) vfe_dev_err("chip found is not an target chip.\n"); return ret; } - ret = sensor_write_array(sd, sensor_default_regs , ARRAY_SIZE(sensor_default_regs)); + + nsize = sensor_resolutions[hres].nsize; + ret = sensor_write_array(sd, sensor_default_regs , nsize); msleep(350); - return 0; + return 0; } static int sensor_g_exif(struct v4l2_subdev *sd, struct sensor_exif_attribute *exif) { - int ret = 0;//, gain_val, exp_val; - unsigned int temp=0,shutter=0, gain = 0; + int ret = 0; //, gain_val, exp_val; + unsigned int temp = 0, shutter = 0, gain = 0; unsigned char val; sensor_write(sd, 0xfe, 0x00); @@ -2370,8 +4784,8 @@ static int sensor_g_exif(struct v4l2_subdev *sd, struct sensor_exif_attribute *e temp |= (val<< 8); sensor_read(sd, 0x04, &val); temp |= (val & 0xff); - shutter=temp; - + shutter = temp; + sensor_read(sd, 0xb2, &val); gain = val; exif->fnumber = 280; @@ -2386,7 +4800,7 @@ static int sensor_g_exif(struct v4l2_subdev *sd, struct sensor_exif_attribute *e static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - int ret=0; + int ret = 0; //struct sensor_info *info = to_state(sd); switch(cmd) { case GET_SENSOR_EXIF: @@ -2398,145 +4812,23 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return ret; } - -/* - * Store information about the video data format. - */ -static struct sensor_format_struct { - __u8 *desc; - //__u32 pixelformat; - enum v4l2_mbus_pixelcode mbus_code;//linux-3.0 - struct regval_list *regs; - int regs_size; - int bpp; /* Bytes per pixel */ -} sensor_formats[] = { - { - .desc = "YUYV 4:2:2", - .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,//linux-3.0 - .regs = sensor_fmt_yuv422_yuyv, - .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yuyv), - .bpp = 2, - }, - { - .desc = "YVYU 4:2:2", - .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,//linux-3.0 - .regs = sensor_fmt_yuv422_yvyu, - .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yvyu), - .bpp = 2, - }, - { - .desc = "UYVY 4:2:2", - .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,//linux-3.0 - .regs = sensor_fmt_yuv422_uyvy, - .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_uyvy), - .bpp = 2, - }, - { - .desc = "VYUY 4:2:2", - .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,//linux-3.0 - .regs = sensor_fmt_yuv422_vyuy, - .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_vyuy), - .bpp = 2, - }, - { - .desc = "Raw RGB Bayer", - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0 - .regs = sensor_fmt_raw, - .regs_size = ARRAY_SIZE(sensor_fmt_raw), - .bpp = 1 - }, -}; -#define N_FMTS ARRAY_SIZE(sensor_formats) - - - -/* - * Then there is the issue of window sizes. Try to capture the info here. - */ - - -static struct sensor_win_size -sensor_win_sizes[] = { - /* UXGA */ - { - .width = UXGA_WIDTH, - .height = UXGA_HEIGHT, - .hoffset = 0, - .voffset = 0, - .regs = sensor_uxga_regs, - .regs_size = ARRAY_SIZE(sensor_uxga_regs), - .set_size = NULL, - }, -// /* 720p */ -// { -// .width = HD720_WIDTH, -// .height = HD720_HEIGHT, -// .hoffset = 0, -// .voffset = 0, -// .regs = Gc2015_sensor_hd720_regs, -// .regs_size = ARRAY_SIZE(Gc2015_sensor_hd720_regs), -// .set_size = NULL, -// }, - /* SVGA */ - { - .width = SVGA_WIDTH, - .height = SVGA_HEIGHT, - .hoffset = 0, - .voffset = 0, - .regs = sensor_svga_regs, - .regs_size = ARRAY_SIZE(sensor_svga_regs), - .set_size = NULL, - }, - /* VGA */ - { - .width = VGA_WIDTH, - .height = VGA_HEIGHT, - .hoffset = 0, - .voffset = 0, - .regs = sensor_vga_regs, - .regs_size = ARRAY_SIZE(sensor_vga_regs), - .set_size = NULL, - }, - /* QVGA */ - { - .width = QVGA_WIDTH, - .height = QVGA_HEIGHT, - .hoffset = 0, - .voffset = 0, - .regs = sensor_qvga_regs, - .regs_size = ARRAY_SIZE(sensor_qvga_regs), - .set_size = NULL, - }, - - -}; - -#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) - -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, - enum v4l2_mbus_pixelcode *code) +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, enum v4l2_mbus_pixelcode *code) { - if (index >= N_FMTS) - return -EINVAL; - + if (index >= N_FMTS) return -EINVAL; *code = sensor_formats[index].mbus_code; return 0; } -static int sensor_enum_size(struct v4l2_subdev *sd, - struct v4l2_frmsizeenum *fsize) +static int sensor_enum_size(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize) { - if(fsize->index > N_WIN_SIZES-1) - return -EINVAL; - + if (fsize->index > N_WIN_SIZES-1) return -EINVAL; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; fsize->discrete.width = sensor_win_sizes[fsize->index].width; fsize->discrete.height = sensor_win_sizes[fsize->index].height; - return 0; } - static int sensor_try_fmt_internal(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt, struct sensor_format_struct **ret_fmt, @@ -2546,156 +4838,312 @@ static int sensor_try_fmt_internal(struct v4l2_subdev *sd, struct sensor_win_size *wsize; for (index = 0; index < N_FMTS; index++) - if (sensor_formats[index].mbus_code == fmt->code) - break; + { + if (sensor_formats[index].mbus_code == fmt->code) break; + } + + if (index >= N_FMTS) return -EINVAL; + + if (ret_fmt != NULL) *ret_fmt = sensor_formats + index; - if (index >= N_FMTS) - return -EINVAL; - - if (ret_fmt != NULL) - *ret_fmt = sensor_formats + index; - /* * Fields: the sensor devices claim to be progressive. */ - + fmt->field = V4L2_FIELD_NONE; - - /* - * Round requested image size down to the nearest - * we support, but not below the smallest. - */ - for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; - wsize++) - if (fmt->width >= wsize->width && fmt->height >= wsize->height) - break; - - if (wsize >= sensor_win_sizes + N_WIN_SIZES) - wsize--; /* Take the smallest one */ - if (ret_wsize != NULL) - *ret_wsize = wsize; + + // a try format + // finds window format in all hres modes + if (ret_fmt == NULL && ret_wsize == NULL) + { + int i; + bool found_hres = false; + struct sensor_resolutions_struct *res; + for (i = 0; i < N_RESOLUTIONS; i++) + { + if (found_hres) break; + res = &sensor_resolutions[i]; + for (index = 0; index < res->nwin_sizes; index++) + { + wsize = &res->win_sizes[index]; + if (fmt->width == wsize->width && fmt->height == wsize->height) + { + vfe_dev_dbg("%s Found hres: %d / resolution: %dx%d\n", __func__, i, fmt->width, fmt->height); + found_hres = true; + break; + } + } + } + } + // set window size + else + { + /* + * Round requested image size down to the nearest + * we support, but not below the smallest. + */ + for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; wsize++) + { + if (fmt->width >= wsize->width && fmt->height >= wsize->height) break; + } + + /* Take the smallest one */ + if (wsize >= sensor_win_sizes + N_WIN_SIZES) wsize--; + + if (ret_wsize != NULL) *ret_wsize = wsize; + } + /* * Note the size we'll actually handle. */ fmt->width = wsize->width; fmt->height = wsize->height; - //pix->bytesperline = pix->width*sensor_formats[index].bpp; - //pix->sizeimage = pix->height*pix->bytesperline; return 0; } -static int sensor_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { return sensor_try_fmt_internal(sd, fmt, NULL, NULL); } -static int sensor_g_mbus_config(struct v4l2_subdev *sd, - struct v4l2_mbus_config *cfg) +static int sensor_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { cfg->type = V4L2_MBUS_PARALLEL; cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL ; - return 0; } -/* - * Set a format. - */ -static int sensor_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *fmt)//linux-3.0 + +/* Sets a window size +*/ +static int sensor_s_wsize(struct v4l2_subdev *sd, + struct sensor_format_struct *sensor_fmt, + struct sensor_win_size *wsize) { - int ret; - unsigned int temp=0,shutter=0; - unsigned char val; + int ret; + unsigned int temp = 0, shutter = 0; + unsigned char val; - struct sensor_format_struct *sensor_fmt; - struct sensor_win_size *wsize; - struct sensor_info *info = to_state(sd); + if (hres == 1 || hres == 3) + { + if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT)) + { + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0xb6, 0x02); + + /*read shutter */ + sensor_read(sd, 0x03, &val); + temp |= (val<< 8); + + sensor_read(sd, 0x04, &val); + temp |= (val & 0xff); + shutter = temp; + } + } -// printk("chr wsize.width = [%d], wsize.height = [%d]\n", wsize->width, wsize->height); - //vfe_dev_dbg("sensor_s_fmt\n"); + if (sensor_fmt == NULL) + { + struct sensor_info *info = to_state(sd); + sensor_fmt = info->fmt; + } + sensor_write_array(sd, sensor_fmt->regs , sensor_fmt->regs_size); - //////////////shutter-gain/////////////// - ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); - if (ret) - return ret; + ret = 0; + if (wsize->regs) + { + ret = sensor_write_array(sd, wsize->regs , wsize->regs_size); + if (ret < 0) + return ret; + } - if((wsize->width==UXGA_WIDTH)&&(wsize->height==UXGA_HEIGHT)) //capture mode >640*480 - { - // printk(" read 2035 exptime 11111111\n" ); - - sensor_write(sd, 0xfe, 0x00); - - sensor_write(sd, 0xb6, 0x02); - - /*read shutter */ - sensor_read(sd, 0x03, &val); - temp |= (val<< 8); - // printk(" read 0x03 = [%x]\n", regs.value[0]); - - sensor_read(sd, 0x04, &val); - temp |= (val & 0xff); - // printk(" read 0x04 = [%x]\n", regs.value[0]); - - shutter=temp; - // printk(" shutter = [%x]\n", shutter); - } + if (wsize->set_size) + { + ret = wsize->set_size(sd); + if (ret < 0) + return ret; + } - sensor_write_array(sd, sensor_fmt->regs , sensor_fmt->regs_size); + if (hres == 0) + { + if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT)) + { + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0xb6, 0x03); // AEC ON + sensor_write(sd, 0xfa, 0x08); // clk div mode + sensor_read(sd, 0x03, &val); + temp |= (val<< 8); + sensor_read(sd, 0x04, &val); + temp |= (val & 0xff); + shutter = temp; + shutter = shutter / 2; + if (shutter < 1) shutter = 1; + val = ((shutter>>8) & 0xff); + sensor_write(sd, 0x03, val); + val = (shutter & 0xff); + sensor_write(sd, 0x04, val); + msleep(550); + } + + else if ((wsize->width == VGA_WIDTH && wsize->height == VGA_HEIGHT) || + (wsize->width == HD720_WIDTH && wsize->height == HD720_HEIGHT)) + { + mdelay(50); + sensor_write(sd, 0xb6, 0x03); // AEC ON + + if (wsize->width == HD720_WIDTH && wsize->height == HD720_HEIGHT) + { + sensor_write(sd, 0xfa, 0x08); // clk div mode + } + mdelay(300); + } + } - ret = 0; - if (wsize->regs) - { - ret = sensor_write_array(sd, wsize->regs , wsize->regs_size); - if (ret < 0) - return ret; - } - - if (wsize->set_size) - { - ret = wsize->set_size(sd); - if (ret < 0) - return ret; - } + else if (hres == 1) + { + if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT)) + { + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0xb6, 0x03); // AEC ON + sensor_write(sd, 0xfa, 0x08); // clk div mode + + shutter = shutter / 2; + if(shutter < 1) shutter = 1; + val = ((shutter>>8)&0xff); + sensor_write(sd, 0x03, val); + val = (shutter&0xff); + sensor_write(sd, 0x04, val); + msleep(550); + } + } - ////////// + else if (hres == 2) + { - #if 1 - if((wsize->width==UXGA_WIDTH)&&(wsize->height==UXGA_HEIGHT)) - { + sensor_write(sd, 0xfe, 0x01); + sensor_write(sd, 0x21, 0xbf); + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0x03, 0); + sensor_write(sd, 0x04, 0); - //printk(" write 2035 exptime 22222222\n" ); + sensor_write(sd, 0xb6, 0x03); + sensor_write(sd, 0xfa, 0x00); + if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT)) + { + sensor_write(sd, 0xc8, 0x02); + sensor_write(sd, 0x99, 0x44); + } - sensor_write(sd, 0xfe, 0x00); + else if ((wsize->width == CIF_WIDTH && wsize->height == CIF_HEIGHT)) + { + sensor_write(sd, 0xc8, 0x03); + sensor_write(sd, 0x99, 0x44); + } - shutter= shutter /2; // 2 - - if(shutter < 1) shutter = 1; - val = ((shutter>>8)&0xff); - // printk(" write0x03 = [%x]\n", regs.value[0]); - sensor_write(sd, 0x03, val); + else if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT)) + { + sensor_write(sd, 0xc8, 0x00); + sensor_write(sd, 0x99, 0x22); + } - val = (shutter&0xff); + sensor_write(sd, 0x9a, 0x07); + sensor_write(sd, 0x9b, 0x00); + sensor_write(sd, 0x9c, 0x00); + sensor_write(sd, 0x9d, 0x00); + sensor_write(sd, 0x9e, 0x00); + sensor_write(sd, 0x9f, 0x00); + + sensor_write(sd, 0xa1, 0x00); + sensor_write(sd, 0xa2, 0x00); + + sensor_write(sd, 0x90, 0x01); // crop enable + sensor_write(sd, 0x94, 0x02); + sensor_write(sd, 0x95, 0x02); + + if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT) || + (wsize->width == CIF_WIDTH && wsize->height == CIF_HEIGHT)) + { + sensor_write(sd, 0x96, 0x58); + } else + { + sensor_write(sd, 0x96, 0x5a); + } - sensor_write(sd, 0x04, val); + sensor_write(sd, 0x97, 0x03); + sensor_write(sd, 0x98, 0x22); + mdelay(50); + } - msleep(550); - } - -#endif -///////////////////////////// + return 0; +} + +/* + * Set a format. +*/ +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)//linux-3.0 +{ + int ret; + struct sensor_format_struct *sensor_fmt; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + int i, nsize, index; + bool found_hres = false; + struct sensor_resolutions_struct *res; + for (i = 0; i < N_RESOLUTIONS; i++) + { + if (found_hres) break; + res = &sensor_resolutions[i]; + for (index = 0; index < res->nwin_sizes; index++) + { + wsize = &res->win_sizes[index]; + if (fmt->width == wsize->width && fmt->height == wsize->height) + { + found_hres = true; + if (hres != i) + { + vfe_dev_dbg("%s Change hres %d to: %d\n", __func__, hres, i); + hres = i; + sensor_default_regs = res->regs; + sensor_win_sizes = res->win_sizes; + N_WIN_SIZES = res->nwin_sizes; + nsize = res->nsize; + if (!frate) SENSOR_FRAME_RATE = res->framerate; + + if ((res->mclk != MCLK) && !mclk) + { + MCLK = res->mclk; + vfe_dev_dbg("%s Change mclk: %d\n", __func__, MCLK*1000*10000); + vfe_set_mclk_freq(sd, (MCLK*1000*1000)); + vfe_set_mclk(sd, ON); + usleep_range(10000, 12000); + } + + ret = sensor_write_array(sd, sensor_default_regs, nsize); + msleep(350); + } + break; + } + } + } + + ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); + if (ret) + return ret; + + ret = sensor_s_wsize(sd, sensor_fmt, wsize); + if (ret < 0) + return ret; sensor_s_hflip(sd,info->hflip); sensor_s_vflip(sd,info->vflip); - info->fmt = sensor_fmt; - info->width = wsize->width; - info->height = wsize->height; + info->fmt = sensor_fmt; + info->width = wsize->width; + info->height = wsize->height; - return 0; + return 0; } /* @@ -2706,8 +5154,7 @@ static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { struct v4l2_captureparm *cp = &parms->parm.capture; - if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; memset(cp, 0, sizeof(struct v4l2_captureparm)); cp->capability = V4L2_CAP_TIMEPERFRAME; @@ -2721,33 +5168,94 @@ static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) struct v4l2_captureparm *cp = &parms->parm.capture; struct sensor_info *info = to_state(sd); struct v4l2_fract *tpf = &cp->timeperframe; - int div; - int clkrc = 1; + int div, clkrc; + clkrc = 1; + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + if (cp->extendedmode != 0) return -EINVAL; + + if (tpf->denominator != SENSOR_FRAME_RATE) + { + int index, i, ret; + // finds compatible framerate + for (index = 0; index < N_RESOLUTIONS; index++) + { + if (sensor_resolutions[index].framerate >= tpf->denominator) break; + } + + if (hres != index) + { + // checks if exists resolution compatible with selected framerate + struct sensor_resolutions_struct *res; + struct sensor_win_size *wsize; + res = &sensor_resolutions[index]; + int nsize; + + for (i = 0; i < res->nwin_sizes; i++) + { + + wsize = &res->win_sizes[i]; + if (info->width == wsize->width && info->height == wsize->height) + { + vfe_dev_dbg("%s Change hres %d to: %d\n", __func__, hres, index); + hres = index; + sensor_default_regs = res->regs; + sensor_win_sizes = res->win_sizes; + N_WIN_SIZES = res->nwin_sizes; + nsize = res->nsize; + SENSOR_FRAME_RATE = res->framerate; + + if ((res->mclk != MCLK) && !mclk) + { + MCLK = res->mclk; + vfe_dev_dbg("%s Change mclk: %d\n", __func__, MCLK*1000*10000); + vfe_set_mclk_freq(sd, (MCLK*1000*1000)); + vfe_set_mclk(sd, ON); + usleep_range(10000, 12000); + } + + ret = sensor_write_array(sd, sensor_default_regs, nsize); + if (ret < 0) + return ret; + msleep(350); + + ret = sensor_s_wsize(sd, NULL, wsize); + if (ret < 0) + return ret; + + break; + } + + } + + } + + } + + // reset to full framerate + tpf->numerator = 0; - if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (cp->extendedmode != 0) - return -EINVAL; - if (tpf->numerator == 0 || tpf->denominator == 0) - div = 1; // Reset to full rate - else - div = (tpf->numerator*SENSOR_FRAME_RATE)/tpf->denominator; - - if (div == 0) - div = 1; - else if (div > 8) - div = 8; - - clkrc = (clkrc & 0x80) | div; - tpf->numerator = 1; - tpf->denominator = SENSOR_FRAME_RATE/div; - sensor_write(sd, REG_CLKRC, clkrc); - return 0; + { + div = 1; // Reset to full rate + } + else + { + div = (tpf->numerator*SENSOR_FRAME_RATE)/tpf->denominator; + } + + if (div == 0) div = 1; + else if (div > 8) div = 8; + + clkrc = (clkrc & 0x80) | div; + tpf->numerator = 1; + tpf->denominator = SENSOR_FRAME_RATE / div; + sensor_write(sd, REG_CLKRC, clkrc); + return 0; } -/* +/* * Code for dealing with controls. * fill with different sensor module * different sensor module has different settings here @@ -2761,55 +5269,65 @@ static int sensor_queryctrl(struct v4l2_subdev *sd, /* Fill in min, max, step and default value for these controls. */ /* see include/linux/videodev2.h for details */ /* see sensor_s_parm and sensor_g_parm for the meaning of value */ - switch (qc->id) { -// case V4L2_CID_BRIGHTNESS: -// return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); -// case V4L2_CID_CONTRAST: -// return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); -// case V4L2_CID_SATURATION: -// return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); -// case V4L2_CID_HUE: -// return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); + + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); + + case V4L2_CID_SATURATION: + return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1); + + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); + case V4L2_CID_VFLIP: case V4L2_CID_HFLIP: return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); -// case V4L2_CID_GAIN: -// return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); -// case V4L2_CID_AUTOGAIN: -// return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + + case V4L2_CID_GAIN: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); + + case V4L2_CID_AUTOGAIN: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + case V4L2_CID_EXPOSURE: case V4L2_CID_AUTO_EXPOSURE_BIAS: return v4l2_ctrl_query_fill(qc, -4, 4, 1, 0); + case V4L2_CID_EXPOSURE_AUTO: return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return v4l2_ctrl_query_fill(qc, 0, 9, 1, 1); + case V4L2_CID_AUTO_WHITE_BALANCE: return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); + case V4L2_CID_COLORFX: return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0); case V4L2_CID_FLASH_LED_MODE: - return v4l2_ctrl_query_fill(qc, 0, 4, 1, 0); - -// case V4L2_CID_3A_LOCK: -// return v4l2_ctrl_query_fill(qc, 0, V4L2_LOCK_EXPOSURE | -// V4L2_LOCK_WHITE_BALANCE | -// V4L2_LOCK_FOCUS, 1, 0); -// case V4L2_CID_AUTO_FOCUS_RANGE: -// return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);//only auto -// case V4L2_CID_AUTO_FOCUS_INIT: -// case V4L2_CID_AUTO_FOCUS_RELEASE: -// case V4L2_CID_AUTO_FOCUS_START: -// case V4L2_CID_AUTO_FOCUS_STOP: -// case V4L2_CID_AUTO_FOCUS_STATUS: -// return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0); -// case V4L2_CID_FOCUS_AUTO: -// return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); -// case V4L2_CID_AUTO_EXPOSURE_WIN_NUM: -// return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); -// case V4L2_CID_AUTO_FOCUS_WIN_NUM: -// return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + return v4l2_ctrl_query_fill(qc, 0, 4, 1, 0); + + case V4L2_CID_3A_LOCK: + return v4l2_ctrl_query_fill(qc, 0, V4L2_LOCK_EXPOSURE | + V4L2_LOCK_WHITE_BALANCE | + V4L2_LOCK_FOCUS, 1, 0); + case V4L2_CID_AUTO_FOCUS_RANGE: + return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);//only auto + + case V4L2_CID_AUTO_FOCUS_STATUS: + return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0); + + case V4L2_CID_FOCUS_AUTO: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + + case V4L2_CID_AUTO_EXPOSURE_WIN_NUM: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); + + case V4L2_CID_AUTO_FOCUS_WIN_NUM: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); } return -EINVAL; } @@ -2820,54 +5338,47 @@ static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: return sensor_g_brightness(sd, &ctrl->value); + case V4L2_CID_CONTRAST: return sensor_g_contrast(sd, &ctrl->value); + case V4L2_CID_SATURATION: return sensor_g_saturation(sd, &ctrl->value); + case V4L2_CID_HUE: - return sensor_g_hue(sd, &ctrl->value); + return sensor_g_hue(sd, &ctrl->value); + case V4L2_CID_VFLIP: return sensor_g_vflip(sd, &ctrl->value); + case V4L2_CID_HFLIP: return sensor_g_hflip(sd, &ctrl->value); + case V4L2_CID_GAIN: return sensor_g_gain(sd, &ctrl->value); + case V4L2_CID_AUTOGAIN: return sensor_g_autogain(sd, &ctrl->value); + case V4L2_CID_EXPOSURE: + case V4L2_CID_AUTO_EXPOSURE_BIAS: return sensor_g_exp_bias(sd, &ctrl->value); + case V4L2_CID_EXPOSURE_AUTO: return sensor_g_autoexp(sd, &ctrl->value); + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return sensor_g_wb(sd, &ctrl->value); + case V4L2_CID_AUTO_WHITE_BALANCE: return sensor_g_autowb(sd, &ctrl->value); + case V4L2_CID_COLORFX: return sensor_g_colorfx(sd, &ctrl->value); + case V4L2_CID_FLASH_LED_MODE: return sensor_g_flash_mode(sd, &ctrl->value); -// case V4L2_CID_POWER_LINE_FREQUENCY: -// return sensor_g_band_filter(sd, &ctrl->value); - -// case V4L2_CID_3A_LOCK: -// return 0; -// case V4L2_CID_AUTO_FOCUS_RANGE: -// ctrl->value=0;//only auto -// return 0; -// case V4L2_CID_AUTO_FOCUS_INIT: -// case V4L2_CID_AUTO_FOCUS_RELEASE: -// case V4L2_CID_AUTO_FOCUS_START: -// case V4L2_CID_AUTO_FOCUS_STOP: -// case V4L2_CID_AUTO_FOCUS_STATUS: -// return 0;//sensor_g_af_status(sd); -//// case V4L2_CID_FOCUS_AUTO: -// case V4L2_CID_AUTO_FOCUS_WIN_NUM: -// ctrl->value=1; -// return 0; -// case V4L2_CID_AUTO_EXPOSURE_WIN_NUM: -// ctrl->value=1; -// return 0; } return -EINVAL; } @@ -2876,8 +5387,7 @@ static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct v4l2_queryctrl qc; int ret; - -// vfe_dev_dbg("sensor_s_ctrl ctrl->id=0x%8x\n", ctrl->id); + qc.id = ctrl->id; ret = sensor_queryctrl(sd, &qc); if (ret < 0) { @@ -2895,62 +5405,50 @@ static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: return sensor_s_brightness(sd, ctrl->value); + case V4L2_CID_CONTRAST: return sensor_s_contrast(sd, ctrl->value); + case V4L2_CID_SATURATION: return sensor_s_saturation(sd, ctrl->value); + case V4L2_CID_HUE: - return sensor_s_hue(sd, ctrl->value); + return sensor_s_hue(sd, ctrl->value); + case V4L2_CID_VFLIP: return sensor_s_vflip(sd, ctrl->value); + case V4L2_CID_HFLIP: return sensor_s_hflip(sd, ctrl->value); + case V4L2_CID_GAIN: return sensor_s_gain(sd, ctrl->value); + case V4L2_CID_AUTOGAIN: return sensor_s_autogain(sd, ctrl->value); + case V4L2_CID_EXPOSURE: case V4L2_CID_AUTO_EXPOSURE_BIAS: return sensor_s_exp_bias(sd, ctrl->value); + case V4L2_CID_EXPOSURE_AUTO: return sensor_s_autoexp(sd, (enum v4l2_exposure_auto_type) ctrl->value); + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return sensor_s_wb(sd, - (enum v4l2_auto_n_preset_white_balance) ctrl->value); + (enum v4l2_auto_n_preset_white_balance) ctrl->value); + case V4L2_CID_AUTO_WHITE_BALANCE: return sensor_s_autowb(sd, ctrl->value); + case V4L2_CID_COLORFX: return sensor_s_colorfx(sd, (enum v4l2_colorfx) ctrl->value); + case V4L2_CID_FLASH_LED_MODE: return sensor_s_flash_mode(sd, (enum v4l2_flash_led_mode) ctrl->value); -// case V4L2_CID_POWER_LINE_FREQUENCY: -// return sensor_s_band_filter(sd, -// (enum v4l2_power_line_frequency) ctrl->value); - -// case V4L2_CID_3A_LOCK: -// return 0;//sensor_s_3a(sd, ctrl->value); -// case V4L2_CID_AUTO_FOCUS_RANGE: -// return 0; -// case V4L2_CID_AUTO_FOCUS_INIT: -// return sensor_s_init_af(sd); -// case V4L2_CID_AUTO_FOCUS_RELEASE: -// return sensor_s_release_af(sd); -// case V4L2_CID_AUTO_FOCUS_START: -// return sensor_s_single_af(sd); -// case V4L2_CID_AUTO_FOCUS_STOP: -// return sensor_s_pause_af(sd); -// case V4L2_CID_AUTO_FOCUS_STATUS: -// return 0; -// case V4L2_CID_FOCUS_AUTO: -// return sensor_s_continueous_af(sd, ctrl->value); -// case V4L2_CID_AUTO_FOCUS_WIN_NUM: -// vfe_dev_dbg("s_ctrl win value=%d\n",ctrl->value); -// return sensor_s_af_zone(sd, (struct v4l2_win_coordinate *)(ctrl->user_pt)); -// case V4L2_CID_AUTO_EXPOSURE_WIN_NUM: -// return 0; } return -EINVAL; } @@ -2967,7 +5465,8 @@ static int sensor_g_chip_ident(struct v4l2_subdev *sd, /* ----------------------------------------------------------------------- */ -static const struct v4l2_subdev_core_ops sensor_core_ops = { +static const struct v4l2_subdev_core_ops sensor_core_ops = +{ .g_chip_ident = sensor_g_chip_ident, .g_ctrl = sensor_g_ctrl, .s_ctrl = sensor_s_ctrl, @@ -2978,7 +5477,8 @@ static const struct v4l2_subdev_core_ops sensor_core_ops = { .ioctl = sensor_ioctl, }; -static const struct v4l2_subdev_video_ops sensor_video_ops = { +static const struct v4l2_subdev_video_ops sensor_video_ops = +{ .enum_mbus_fmt = sensor_enum_fmt, .enum_framesizes = sensor_enum_size, .try_mbus_fmt = sensor_try_fmt, @@ -2988,36 +5488,33 @@ static const struct v4l2_subdev_video_ops sensor_video_ops = { .g_mbus_config = sensor_g_mbus_config, }; -static const struct v4l2_subdev_ops sensor_ops = { +static const struct v4l2_subdev_ops sensor_ops = +{ .core = &sensor_core_ops, .video = &sensor_video_ops, }; /* ----------------------------------------------------------------------- */ -static struct cci_driver cci_drv = { +static struct cci_driver cci_drv = +{ .name = SENSOR_NAME, .addr_width = CCI_BITS_8, .data_width = CCI_BITS_8, }; -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; struct sensor_info *info; -// int ret; info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); - if (info == NULL) - return -ENOMEM; + if (info == NULL) return -ENOMEM; sd = &info->sd; cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); - if(client) { - client->addr=0x78>>1; - } + if(client) client->addr = 0x78>>1; info->fmt = &sensor_formats[0]; - + info->brightness = 0; info->contrast = 0; info->saturation = 0; @@ -3032,28 +5529,28 @@ static int sensor_probe(struct i2c_client *client, info->wb = 0; info->clrfx = 0; //info->clkrc = 1; /* 30fps */ - return 0; } - static int sensor_remove(struct i2c_client *client) { struct v4l2_subdev *sd; - sd = cci_dev_remove_helper(client, &cci_drv); kfree(to_state(sd)); return 0; } -static const struct i2c_device_id sensor_id[] = { +static const struct i2c_device_id sensor_id[] = +{ { SENSOR_NAME, 0 }, { } }; + MODULE_DEVICE_TABLE(i2c, sensor_id); //linux-3.0 -static struct i2c_driver sensor_driver = { +static struct i2c_driver sensor_driver = +{ .driver = { .owner = THIS_MODULE, .name = SENSOR_NAME, @@ -3062,8 +5559,20 @@ static struct i2c_driver sensor_driver = { .remove = sensor_remove, .id_table = sensor_id, }; + static __init int init_sensor(void) { + if (mclk > 34) mclk = 0; + sensor_default_regs = sensor_resolutions[hres].regs; + sensor_win_sizes = sensor_resolutions[hres].win_sizes; + N_WIN_SIZES = sensor_resolutions[hres].nwin_sizes; + SENSOR_FRAME_RATE = sensor_resolutions[hres].framerate; + MCLK = sensor_resolutions[hres].mclk; + + if (mclk) MCLK = mclk; + + if (frate) SENSOR_FRAME_RATE = frate; + return cci_dev_init_helper(&sensor_driver); } @@ -3073,4 +5582,4 @@ static __exit void exit_sensor(void) } module_init(init_sensor); -module_exit(exit_sensor); \ No newline at end of file +module_exit(exit_sensor); From 28bf1bfb9b4331ec3f935fda931d2cde085b3668 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 28 Jun 2017 17:28:36 -0300 Subject: [PATCH 13/26] small fixes --- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35117 -> 35113 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 220 +++++++++--------- .../arm/mach-sunxi/power/brom/resumes.map | 6 +- .../media/video/sunxi-vfe/device/gc2035.c | 6 +- 4 files changed, 115 insertions(+), 117 deletions(-) diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 790828a65a3ab293dc2665477cb19a952cf7c7b5..74fb697653a8afb3738f8cd2edcb66af5c75758b 100755 GIT binary patch delta 357 zcmZ2GiD~5|rU?p+6&n?gH`G64U|?Wu0}}Q?deSM(sF|JPW%7P=b{k$TncK`v;`hHiKjxfEth&3cpPHLv1Gb@%s+FDuU5?A{W?IC)9y7RH3hk!{M1<&$gM)LC!0FfbTSHf$4~ ayr)fok!SMRHg!gW$zOrwg3Yq+0!#qEB|%&O delta 352 zcmZ2EiD~U5rU?p+H5(O=H`IS(U|?XJ1SHsi_zn~UDF!A+wg*6p*%e4Is+)sFIPQTc zCRQs(5XCMBq*z#3GxJIqn1K=ujM{M^c@}mRpaiQIkZr(d_YX+1?FY#^1cPLi8Q9){ zc#a?mrZi<1HW8p|Mkk0Q4_g*U(iy@NV7ma~xj=X#Y=t16D<8;qWeK(z5YG+5lVNKI z@!TOi1-3d6&jZ3!VKbb3wo#8K0A!C>Do}>gWixw|7^9$menE+TS$5+w R1d=9`KLW`mn - 70: 00bf0600 adcseq r0, pc, r0, lsl #12 + 70: 00b30600 adcseq r0, r3, r0, lsl #12 74: 40010000 andmi r0, r1, r0 78: 00000053 andeq r0, r0, r3, asr r0 7c: 06002302 streq r2, [r0], -r2, lsl #6 - 80: 000000ec andeq r0, r0, ip, ror #1 + 80: 000000e0 andeq r0, r0, r0, ror #1 84: 00fe4101 rscseq r4, lr, r1, lsl #2 88: 23020000 movwcs r0, #8192 ; 0x2000 - 8c: 01140604 tsteq r4, r4, lsl #12 + 8c: 01080604 tsteq r8, r4, lsl #12 90: 42010000 andmi r0, r1, #0 94: 00000053 andeq r0, r0, r3, asr r0 98: 060c2302 streq r2, [ip], -r2, lsl #6 - 9c: 0000006a andeq r0, r0, sl, rrx + 9c: 0000002b andeq r0, r0, fp, lsr #32 a0: 00534301 subseq r4, r3, r1, lsl #6 a4: 23020000 movwcs r0, #8192 ; 0x2000 - a8: 00d00610 sbcseq r0, r0, r0, lsl r6 + a8: 00c40610 sbceq r0, r4, r0, lsl r6 ac: 44010000 strmi r0, [r1], #-0 b0: 00000053 andeq r0, r0, r3, asr r0 b4: 06142302 ldreq r2, [r4], -r2, lsl #6 - b8: 00000071 andeq r0, r0, r1, ror r0 + b8: 00000032 andeq r0, r0, r2, lsr r0 bc: 010e4501 tsteq lr, r1, lsl #10 c0: 23020000 movwcs r0, #8192 ; 0x2000 - c4: 005c0618 subseq r0, ip, r8, lsl r6 + c4: 001d0618 andseq r0, sp, r8, lsl r6 c8: 46010000 strmi r0, [r1], -r0 cc: 0000010e andeq r0, r0, lr, lsl #2 d0: 061c2302 ldreq r2, [ip], -r2, lsl #6 - d4: 00000087 andeq r0, r0, r7, lsl #1 + d4: 0000007b andeq r0, r0, fp, ror r0 d8: 010e4701 tsteq lr, r1, lsl #14 dc: 23020000 movwcs r0, #8192 ; 0x2000 - e0: 007e0620 rsbseq r0, lr, r0, lsr #12 + e0: 01250620 teqeq r5, r0, lsr #12 e4: 48010000 stmdami r1, {} ; e8: 0000010e andeq r0, r0, lr, lsl #2 ec: 06242302 strteq r2, [r4], -r2, lsl #6 - f0: 00000131 andeq r0, r0, r1, lsr r1 + f0: 0000012e andeq r0, r0, lr, lsr #2 f4: 00fe4901 rscseq r4, lr, r1, lsl #18 f8: 23020000 movwcs r0, #8192 ; 0x2000 fc: 2c070028 stccs 0, cr0, [r7], {40} ; 0x28 @@ -143,10 +143,10 @@ Disassembly of section .debug_info: 110: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0} 114: 08000001 stmdaeq r0, {r0} 118: 0000005e andeq r0, r0, lr, asr r0 - 11c: 50030003 andpl r0, r3, r3 + 11c: 4d030003 stcmi 0, cr0, [r3, #-12] 120: 01000001 tsteq r0, r1 124: 0000654a andeq r6, r0, sl, asr #10 - 128: 01440900 cmpeq r4, r0, lsl #18 + 128: 01410900 cmpeq r1, r0, lsl #18 12c: 25020000 strcs r0, [r2, #-0] 130: 0000013b andeq r0, r0, fp, lsr r1 134: 00030501 andeq r0, r3, r1, lsl #10 @@ -231,95 +231,93 @@ Disassembly of section .debug_str: 00000000 <.debug_str>: 0: 33755f5f cmncc r5, #380 ; 0x17c - 4: 6f2f0032 svcvs 0x002f0032 - 8: 762f7470 ; instruction: 0x762f7470 - c: 74616c6f strbtvc r6, [r1], #-3183 ; 0xc6f - 10: 5f656c69 svcpl 0x00656c69 - 14: 2f766e65 svccs 0x00766e65 - 18: 6a6f7270 bvs 1bdc9e0 <__bss_end+0x1bdc904> - 1c: 73746365 cmnvc r4, #-1811939327 ; 0x94000001 - 20: 6b616d2f blvs 185b4e4 <__bss_end+0x185b408> - 24: 72615f65 rsbvc r5, r1, #404 ; 0x194 - 28: 4f2f6165 svcmi 0x002f6165 - 2c: 676e6172 ; instruction: 0x676e6172 - 30: 2d495065 stclcs 0, cr5, [r9, #-404] ; 0xfffffe6c - 34: 6e72654b cdpvs 5, 7, cr6, cr2, cr11, {2} - 38: 6c2f6c65 stcvs 12, cr6, [pc], #-404 ; fffffeac <__bss_end+0xfffffdd0> - 3c: 78756e69 ldmdavc r5!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^ - 40: 342e332d strtcc r3, [lr], #-813 ; 0x32d - 44: 755f5f00 ldrbvc r5, [pc, #-3840] ; fffff14c <__bss_end+0xfffff070> - 48: 525f0038 subspl r0, pc, #56 ; 0x38 - 4c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 50: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ - 54: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 58: 00646165 rsbeq r6, r4, r5, ror #2 - 5c: 656c6966 strbvs r6, [ip, #-2406]! ; 0x966 - 60: 6165685f cmnvs r5, pc, asr r8 - 64: 73765f64 cmnvc r6, #400 ; 0x190 - 68: 656c006e strbvs r0, [ip, #-110]! ; 0x6e - 6c: 6874676e ldmdavs r4!, {r1, r2, r3, r5, r6, r8, r9, sl, sp, lr}^ - 70: 62757000 rsbsvs r7, r5, #0 - 74: 6165685f cmnvs r5, pc, asr r8 - 78: 73765f64 cmnvc r6, #400 ; 0x190 - 7c: 4765006e strbmi r0, [r5, -lr, rrx]! - 80: 765f4e4f ldrbvc r4, [pc], -pc, asr #28 - 84: 52006e73 andpl r6, r0, #1840 ; 0x730 - 88: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 8c: 73765f65 cmnvc r6, #404 ; 0x194 - 90: 7261006e rsbvc r0, r1, #110 ; 0x6e - 94: 612f6863 teqvs pc, r3, ror #16 - 98: 6d2f6d72 stcvs 13, cr6, [pc, #-456]! ; fffffed8 <__bss_end+0xfffffdfc> - 9c: 2d686361 stclcs 3, cr6, [r8, #-388]! ; 0xfffffe7c - a0: 786e7573 stmdavc lr!, {r0, r1, r4, r5, r6, r8, sl, ip, sp, lr}^ - a4: 6f702f69 svcvs 0x00702f69 - a8: 2f726577 svccs 0x00726577 - ac: 6d6f7262 sfmvs f7, 2, [pc, #-392]! ; ffffff2c <__bss_end+0xfffffe50> - b0: 7365722f cmnvc r5, #-268435454 ; 0xf0000002 - b4: 5f656d75 svcpl 0x00656d75 - b8: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - bc: 6a00632e bvs 18d7c <__bss_end+0x18ca0> - c0: 5f706d75 svcpl 0x00706d75 - c4: 74736e69 ldrbtvc r6, [r3], #-3689 ; 0xe69 - c8: 74637572 strbtvc r7, [r3], #-1394 ; 0x572 - cc: 006e6f69 rsbeq r6, lr, r9, ror #30 - d0: 5f627570 svcpl 0x00627570 - d4: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - d8: 7a69735f bvc 1a5ce5c <__bss_end+0x1a5cd80> - dc: 6e750065 cdpvs 0, 7, cr0, cr5, cr5, {3} - e0: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} - e4: 63206465 teqvs r0, #1694498816 ; 0x65000000 - e8: 00726168 rsbseq r6, r2, r8, ror #2 - ec: 6967616d stmdbvs r7!, {r0, r2, r3, r5, r6, r8, sp, lr}^ - f0: 4e470063 cdpmi 0, 4, cr0, cr7, cr3, {3} - f4: 20432055 subcs r2, r3, r5, asr r0 - f8: 2e362e34 mrccs 14, 1, r2, cr6, cr4, {1} - fc: 30322033 eorscc r2, r2, r3, lsr r0 - 100: 32303231 eorscc r3, r0, #268435459 ; 0x10000003 - 104: 28203130 stmdacs r0!, {r4, r5, r8, ip, sp} - 108: 72657270 rsbvc r7, r5, #7 - 10c: 61656c65 cmnvs r5, r5, ror #24 - 110: 00296573 eoreq r6, r9, r3, ror r5 - 114: 63656863 cmnvs r5, #6488064 ; 0x630000 - 118: 75735f6b ldrbvc r5, [r3, #-3947]! ; 0xf6b - 11c: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ - 120: 2074726f rsbscs r7, r4, pc, ror #4 - 124: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ - 128: 64656e67 strbtvs r6, [r5], #-3687 ; 0xe67 - 12c: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 - 130: 616c7000 cmnvs ip, r0 - 134: 726f6674 rsbvc r6, pc, #121634816 ; 0x7400000 - 138: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ - 13c: 2074726f rsbscs r7, r4, pc, ror #4 - 140: 00746e69 rsbseq r6, r4, r9, ror #28 - 144: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 - 148: 685f656d ldmdavs pc, {r0, r2, r3, r5, r6, r8, sl, sp, lr}^ ; - 14c: 00646165 rsbeq r6, r4, r5, ror #2 - 150: 75736572 ldrbvc r6, [r3, #-1394]! ; 0x572 - 154: 665f656d ldrbvs r6, [pc], -sp, ror #10 - 158: 5f656c69 svcpl 0x00656c69 - 15c: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 160: Address 0x00000160 is out of bounds. - + 4: 5f5f0032 svcpl 0x005f0032 + 8: 5f003875 svcpl 0x00003875 + c: 75736552 ldrbvc r6, [r3, #-1362]! ; 0x552 + 10: 665f656d ldrbvs r6, [pc], -sp, ror #10 + 14: 5f656c69 svcpl 0x00656c69 + 18: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + 1c: 6c696600 stclvs 6, cr6, [r9], #-0 + 20: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 + 24: 765f6461 ldrbvc r6, [pc], -r1, ror #8 + 28: 6c006e73 stcvs 14, cr6, [r0], {115} ; 0x73 + 2c: 74676e65 strbtvc r6, [r7], #-3685 ; 0xe65 + 30: 75700068 ldrbvc r0, [r0, #-104]! ; 0x68 + 34: 65685f62 strbvs r5, [r8, #-3938]! ; 0xf62 + 38: 765f6461 ldrbvc r6, [pc], -r1, ror #8 + 3c: 2f006e73 svccs 0x00006e73 + 40: 656d6f68 strbvs r6, [sp, #-3944]! ; 0xf68 + 44: 6f656c2f svcvs 0x00656c2f + 48: 6472616e ldrbtvs r6, [r2], #-366 ; 0x16e + 4c: 72702f6f rsbsvc r2, r0, #444 ; 0x1bc + 50: 63656a6f cmnvs r5, #454656 ; 0x6f000 + 54: 6d2f7374 stcvs 3, cr7, [pc, #-464]! ; fffffe8c <__bss_end+0xfffffdb0> + 58: 5f656b61 svcpl 0x00656b61 + 5c: 61657261 cmnvs r5, r1, ror #4 + 60: 61724f2f cmnvs r2, pc, lsr #30 + 64: 5065676e rsbpl r6, r5, lr, ror #14 + 68: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 + 6c: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 + 70: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} + 74: 332d7875 teqcc sp, #7667712 ; 0x750000 + 78: 5200342e andpl r3, r0, #771751936 ; 0x2e000000 + 7c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 80: 73765f65 cmnvc r6, #404 ; 0x194 + 84: 7261006e rsbvc r0, r1, #110 ; 0x6e + 88: 612f6863 teqvs pc, r3, ror #16 + 8c: 6d2f6d72 stcvs 13, cr6, [pc, #-456]! ; fffffecc <__bss_end+0xfffffdf0> + 90: 2d686361 stclcs 3, cr6, [r8, #-388]! ; 0xfffffe7c + 94: 786e7573 stmdavc lr!, {r0, r1, r4, r5, r6, r8, sl, ip, sp, lr}^ + 98: 6f702f69 svcvs 0x00702f69 + 9c: 2f726577 svccs 0x00726577 + a0: 6d6f7262 sfmvs f7, 2, [pc, #-392]! ; ffffff20 <__bss_end+0xfffffe44> + a4: 7365722f cmnvc r5, #-268435454 ; 0xf0000002 + a8: 5f656d75 svcpl 0x00656d75 + ac: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + b0: 6a00632e bvs 18d70 <__bss_end+0x18c94> + b4: 5f706d75 svcpl 0x00706d75 + b8: 74736e69 ldrbtvc r6, [r3], #-3689 ; 0xe69 + bc: 74637572 strbtvc r7, [r3], #-1394 ; 0x572 + c0: 006e6f69 rsbeq r6, lr, r9, ror #30 + c4: 5f627570 svcpl 0x00627570 + c8: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + cc: 7a69735f bvc 1a5ce50 <__bss_end+0x1a5cd74> + d0: 6e750065 cdpvs 0, 7, cr0, cr5, cr5, {3} + d4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} + d8: 63206465 teqvs r0, #1694498816 ; 0x65000000 + dc: 00726168 rsbseq r6, r2, r8, ror #2 + e0: 6967616d stmdbvs r7!, {r0, r2, r3, r5, r6, r8, sp, lr}^ + e4: 4e470063 cdpmi 0, 4, cr0, cr7, cr3, {3} + e8: 20432055 subcs r2, r3, r5, asr r0 + ec: 2e362e34 mrccs 14, 1, r2, cr6, cr4, {1} + f0: 30322033 eorscc r2, r2, r3, lsr r0 + f4: 32303231 eorscc r3, r0, #268435459 ; 0x10000003 + f8: 28203130 stmdacs r0!, {r4, r5, r8, ip, sp} + fc: 72657270 rsbvc r7, r5, #7 + 100: 61656c65 cmnvs r5, r5, ror #24 + 104: 00296573 eoreq r6, r9, r3, ror r5 + 108: 63656863 cmnvs r5, #6488064 ; 0x630000 + 10c: 75735f6b ldrbvc r5, [r3, #-3947]! ; 0xf6b + 110: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ + 114: 2074726f rsbscs r7, r4, pc, ror #4 + 118: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ + 11c: 64656e67 strbtvs r6, [r5], #-3687 ; 0xe67 + 120: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 + 124: 4f476500 svcmi 0x00476500 + 128: 73765f4e cmnvc r6, #312 ; 0x138 + 12c: 6c70006e ldclvs 0, cr0, [r0], #-440 ; 0xfffffe48 + 130: 6f667461 svcvs 0x00667461 + 134: 73006d72 movwvc r6, #3442 ; 0xd72 + 138: 74726f68 ldrbtvc r6, [r2], #-3944 ; 0xf68 + 13c: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 + 140: 73657200 cmnvc r5, #0 + 144: 5f656d75 svcpl 0x00656d75 + 148: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 + 14c: 73657200 cmnvc r5, #0 + 150: 5f656d75 svcpl 0x00656d75 + 154: 656c6966 strbvs r6, [ip, #-2406]! ; 0x966 + 158: 6165685f cmnvs r5, pc, asr r8 + 15c: 00745f64 rsbseq r5, r4, r4, ror #30 Disassembly of section .comment: diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 659d64b8..0947a995 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -71,9 +71,9 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) .debug_line 0x00000000 0x7b .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o -.debug_str 0x00000000 0x163 - .debug_str 0x00000000 0x163 arch/arm/mach-sunxi/power/brom/resume_head.o - 0x17c (size before relaxing) +.debug_str 0x00000000 0x160 + .debug_str 0x00000000 0x160 arch/arm/mach-sunxi/power/brom/resume_head.o + 0x179 (size before relaxing) .comment 0x00000000 0x64 .comment 0x00000000 0x64 arch/arm/mach-sunxi/power/brom/resume_head.o diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index ddffa83a..d626a3e3 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -4859,7 +4859,7 @@ static int sensor_try_fmt_internal(struct v4l2_subdev *sd, int i; bool found_hres = false; struct sensor_resolutions_struct *res; - for (i = 0; i < N_RESOLUTIONS; i++) + for (i = 0; i < N_RESOLUTIONS-1; i++) { if (found_hres) break; res = &sensor_resolutions[i]; @@ -5091,7 +5091,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)/ int i, nsize, index; bool found_hres = false; struct sensor_resolutions_struct *res; - for (i = 0; i < N_RESOLUTIONS; i++) + for (i = 0; i < N_RESOLUTIONS-1; i++) { if (found_hres) break; res = &sensor_resolutions[i]; @@ -5178,7 +5178,7 @@ static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { int index, i, ret; // finds compatible framerate - for (index = 0; index < N_RESOLUTIONS; index++) + for (index = 0; index < N_RESOLUTIONS-1; index++) { if (sensor_resolutions[index].framerate >= tpf->denominator) break; } From bc75e67b32570ae64fb8a750b9b4d268eae3469f Mon Sep 17 00:00:00 2001 From: lhelontra Date: Sat, 1 Jul 2017 01:13:06 -0300 Subject: [PATCH 14/26] when trying set fmt, like V4L2_PIX_FMT_{BGR24,SGBRG8}, driver sets BGGR 8bits format and causes segmentation fault. The raw bayer format was disable. --- .../media/video/sunxi-vfe/device/gc2035.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index d626a3e3..b1c2b1f3 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -3971,14 +3971,14 @@ static struct sensor_format_struct .regs_size = ARRAY_SIZE(sensor_fmt_yuv422_vyuy), .bpp = 2, }, - // when try set format as bgr24 for example, this format was returned - { - .desc = "Raw RGB Bayer", - .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0 - .regs = sensor_fmt_raw, - .regs_size = ARRAY_SIZE(sensor_fmt_raw), - .bpp = 1 - }, + // NOTE: when trying set fmt, like V4L2_PIX_FMT_{BGR24,SGBRG8}, driver sets BGGR 8bits format and causes segmentation fault + // { + // .desc = "RAW Bayer BGGR 8bit", + // .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0 + // .regs = sensor_fmt_raw, + // .regs_size = ARRAY_SIZE(sensor_fmt_raw), + // .bpp = 1 + // }, }; #define N_FMTS ARRAY_SIZE(sensor_formats) From 3854765bbc79de229f2ba65ccfd9c6696f02fb7f Mon Sep 17 00:00:00 2001 From: lhelontra Date: Mon, 7 Aug 2017 16:31:03 -0300 Subject: [PATCH 15/26] enabled heartbeat leds trigger --- build/sun8iw7p1smp_lobo_defconfig | 14 +++++++------- build/sun8iw7p1smp_lobo_defconfig.old | 8 ++++++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 78eac9b5..18b739ea 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -128,7 +128,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=0 +CONFIG_PANIC_TIMEOUT=5 CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -2603,10 +2603,10 @@ CONFIG_LEDS_TRIGGERS=y # LED Triggers # CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # # iptables trigger is under Netfilter config (LED target) diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 6b7385ff..78eac9b5 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -1013,7 +1013,8 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set @@ -1339,11 +1340,14 @@ CONFIG_ZD1211RW=m # CONFIG_MWIFIEX is not set CONFIG_RTL8188EU=m CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m CONFIG_RTL8723BS=m # -# Enable WiMAX (Networking options) to see the WiMAX drivers +# WiMAX Wireless Broadband devices # +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set # CONFIG_WAN is not set # CONFIG_ISDN is not set From c5ae49e110e6a5273f93d00bed649e54a93ace84 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Mon, 7 Aug 2017 18:00:54 -0300 Subject: [PATCH 16/26] small changes --- build/sun8iw7p1smp_lobo_defconfig | 472 +++++++++-------- build/sun8iw7p1smp_lobo_defconfig.old | 486 ++++++++++-------- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 486 ++++++++++-------- .../arm/mach-sunxi/power/brom/resumes.elf | Bin 35113 -> 35109 bytes .../arm/mach-sunxi/power/brom/resumes.lst | 180 +++---- .../arm/mach-sunxi/power/brom/resumes.map | 6 +- .../src/devicedrv/mali/.tmp_versions/mali.mod | 4 +- .../driver/src/devicedrv/mali/Module.symvers | 42 +- .../src/devicedrv/ump/.tmp_versions/ump.mod | 4 +- .../driver/src/devicedrv/ump/Module.symvers | 18 +- .../mali_drm/.tmp_versions/mali_drm.mod | 4 +- 11 files changed, 914 insertions(+), 788 deletions(-) diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 18b739ea..ad59869b 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -643,29 +643,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=y CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y @@ -674,192 +674,232 @@ CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # -CONFIG_NETFILTER_NETLINK=y -# CONFIG_NETFILTER_NETLINK_ACCT is not set -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_BROADCAST=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -# CONFIG_NF_CONNTRACK_SNMP is not set -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -CONFIG_NETFILTER_TPROXY=y -CONFIG_NETFILTER_XTABLES=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m # # Xtables combined modules # -CONFIG_NETFILTER_XT_MARK=y -CONFIG_NETFILTER_XT_CONNMARK=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m # # Xtables targets # -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m # # Xtables matches # -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ECN=y -# CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_HL=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -CONFIG_NETFILTER_XT_MATCH_POLICY=y -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QTAGUID=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -# CONFIG_IP_SET is not set -# CONFIG_IP_VS is not set +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 # # IP: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_REJECT_SKERR=y -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_GRE=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_FTP=y -CONFIG_NF_NAT_IRC=y -CONFIG_NF_NAT_TFTP=y -CONFIG_NF_NAT_AMANDA=y -CONFIG_NF_NAT_PPTP=y -CONFIG_NF_NAT_H323=y -# CONFIG_NF_NAT_SIP is not set -CONFIG_IP_NF_MANGLE=y -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV6=y -CONFIG_NF_CONNTRACK_IPV6=y -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=y -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set -CONFIG_L2TP=y +CONFIG_L2TP=m # CONFIG_L2TP_DEBUGFS is not set CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=y -CONFIG_L2TP_ETH=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m CONFIG_STP=m CONFIG_GARP=m CONFIG_BRIDGE=m @@ -883,71 +923,73 @@ CONFIG_NET_SCHED=y # # Queueing/Scheduling # -# CONFIG_NET_SCH_CBQ is not set -CONFIG_NET_SCH_HTB=y -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_PLUG is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m # # Classification # CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_CGROUP is not set +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_NBYTE is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m CONFIG_NET_CLS_ACT=y -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m # CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y # CONFIG_DCB is not set CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_DEBUG is not set # CONFIG_OPENVSWITCH is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y -# CONFIG_NETPRIO_CGROUP is not set +CONFIG_NETPRIO_CGROUP=m CONFIG_BQL=y CONFIG_HAVE_BPF_JIT=y -# CONFIG_BPF_JIT is not set +CONFIG_BPF_JIT=y # # Network testing @@ -2684,7 +2726,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=m +CONFIG_RTC_DRV_SUNXI=y CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -3166,7 +3208,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 78eac9b5..ad59869b 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -128,7 +128,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=0 +CONFIG_PANIC_TIMEOUT=5 CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -643,29 +643,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=y CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y @@ -674,192 +674,232 @@ CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # -CONFIG_NETFILTER_NETLINK=y -# CONFIG_NETFILTER_NETLINK_ACCT is not set -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_BROADCAST=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -# CONFIG_NF_CONNTRACK_SNMP is not set -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -CONFIG_NETFILTER_TPROXY=y -CONFIG_NETFILTER_XTABLES=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m # # Xtables combined modules # -CONFIG_NETFILTER_XT_MARK=y -CONFIG_NETFILTER_XT_CONNMARK=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m # # Xtables targets # -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m # # Xtables matches # -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ECN=y -# CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_HL=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -CONFIG_NETFILTER_XT_MATCH_POLICY=y -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QTAGUID=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -# CONFIG_IP_SET is not set -# CONFIG_IP_VS is not set +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 # # IP: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_REJECT_SKERR=y -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_GRE=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_FTP=y -CONFIG_NF_NAT_IRC=y -CONFIG_NF_NAT_TFTP=y -CONFIG_NF_NAT_AMANDA=y -CONFIG_NF_NAT_PPTP=y -CONFIG_NF_NAT_H323=y -# CONFIG_NF_NAT_SIP is not set -CONFIG_IP_NF_MANGLE=y -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV6=y -CONFIG_NF_CONNTRACK_IPV6=y -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=y -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set -CONFIG_L2TP=y +CONFIG_L2TP=m # CONFIG_L2TP_DEBUGFS is not set CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=y -CONFIG_L2TP_ETH=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m CONFIG_STP=m CONFIG_GARP=m CONFIG_BRIDGE=m @@ -883,71 +923,73 @@ CONFIG_NET_SCHED=y # # Queueing/Scheduling # -# CONFIG_NET_SCH_CBQ is not set -CONFIG_NET_SCH_HTB=y -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_PLUG is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m # # Classification # CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_CGROUP is not set +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_NBYTE is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m CONFIG_NET_CLS_ACT=y -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m # CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y # CONFIG_DCB is not set CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_DEBUG is not set # CONFIG_OPENVSWITCH is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y -# CONFIG_NETPRIO_CGROUP is not set +CONFIG_NETPRIO_CGROUP=m CONFIG_BQL=y CONFIG_HAVE_BPF_JIT=y -# CONFIG_BPF_JIT is not set +CONFIG_BPF_JIT=y # # Network testing @@ -2603,10 +2645,10 @@ CONFIG_LEDS_TRIGGERS=y # LED Triggers # CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # # iptables trigger is under Netfilter config (LED target) @@ -2684,7 +2726,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=m +CONFIG_RTC_DRV_SUNXI=y CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -3166,7 +3208,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index 78eac9b5..ad59869b 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -128,7 +128,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=0 +CONFIG_PANIC_TIMEOUT=5 CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=5 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1" +CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -519,9 +519,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -643,29 +643,29 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=y -CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=y CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y @@ -674,192 +674,232 @@ CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # -CONFIG_NETFILTER_NETLINK=y -# CONFIG_NETFILTER_NETLINK_ACCT is not set -CONFIG_NETFILTER_NETLINK_QUEUE=y -CONFIG_NETFILTER_NETLINK_LOG=y -CONFIG_NF_CONNTRACK=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_BROADCAST=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -# CONFIG_NF_CONNTRACK_SNMP is not set -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -CONFIG_NETFILTER_TPROXY=y -CONFIG_NETFILTER_XTABLES=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m # # Xtables combined modules # -CONFIG_NETFILTER_XT_MARK=y -CONFIG_NETFILTER_XT_CONNMARK=y +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m # # Xtables targets # -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m # # Xtables matches # -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -CONFIG_NETFILTER_XT_MATCH_ECN=y -# CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_HL=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -CONFIG_NETFILTER_XT_MATCH_POLICY=y -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QTAGUID=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -# CONFIG_IP_SET is not set -# CONFIG_IP_VS is not set +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 # # IP: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=y -CONFIG_IP_NF_MATCH_ECN=y -# CONFIG_IP_NF_MATCH_RPFILTER is not set -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_REJECT_SKERR=y -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_GRE=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_FTP=y -CONFIG_NF_NAT_IRC=y -CONFIG_NF_NAT_TFTP=y -CONFIG_NF_NAT_AMANDA=y -CONFIG_NF_NAT_PPTP=y -CONFIG_NF_NAT_H323=y -# CONFIG_NF_NAT_SIP is not set -CONFIG_IP_NF_MANGLE=y -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration # -CONFIG_NF_DEFRAG_IPV6=y -CONFIG_NF_CONNTRACK_IPV6=y -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=y -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set -CONFIG_L2TP=y +CONFIG_L2TP=m # CONFIG_L2TP_DEBUGFS is not set CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=y -CONFIG_L2TP_ETH=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m CONFIG_STP=m CONFIG_GARP=m CONFIG_BRIDGE=m @@ -883,71 +923,73 @@ CONFIG_NET_SCHED=y # # Queueing/Scheduling # -# CONFIG_NET_SCH_CBQ is not set -CONFIG_NET_SCH_HTB=y -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_PLUG is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m # # Classification # CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_CGROUP is not set +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_NBYTE is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m CONFIG_NET_CLS_ACT=y -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m # CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y # CONFIG_DCB is not set CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_DEBUG is not set # CONFIG_OPENVSWITCH is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y -# CONFIG_NETPRIO_CGROUP is not set +CONFIG_NETPRIO_CGROUP=m CONFIG_BQL=y CONFIG_HAVE_BPF_JIT=y -# CONFIG_BPF_JIT is not set +CONFIG_BPF_JIT=y # # Network testing @@ -2603,10 +2645,10 @@ CONFIG_LEDS_TRIGGERS=y # LED Triggers # CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # # iptables trigger is under Netfilter config (LED target) @@ -2684,7 +2726,7 @@ CONFIG_RTC_DRV_DS1307=y # # on-CPU RTC drivers # -CONFIG_RTC_DRV_SUNXI=m +CONFIG_RTC_DRV_SUNXI=y CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -3166,7 +3208,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.elf index 74fb697653a8afb3738f8cd2edcb66af5c75758b..84e42c7be35c294cb619ac1f659c89775952155e 100755 GIT binary patch delta 326 zcmZ2EiD~I1rU?p+B^wowH`KpmU|?Vj1`=z5_zn~UDF!A+wuL~7nGHxVs+)sFIOc;W zCRRg65XCMEq*z#3GxJIqn1K=ujM{M^c@}nQpad&7kZr(d_YX+1H2?`l2aq*P$_#9e zK|Dv01QUxg3mf<3>_%zEiIdwKHDx_OQto^p^OY6Y>_I#a2v3DgWAfQXJsx+U9HUn% zP=?cbGkcRiBS)&czh8V=ao*&K&1t6k`2{8VW%)UYC7C&?@u_)b`Y!q9c{%xsDaHE! zMTvRosR5q4-l;`-sX6*NnR%rZy2g4YlfN~)ZFX&mW}G~)bsJ;UeSM(sF|JPW%7P=b{k$TncK`v;`hHiKjxf)ERG2p4+C*%G1igkUg2PO?dL1 ZHUUP1$!~#T3pyAWIzeKab=rS20sy^`OThpD diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst index 004524d0..899793ca 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.lst @@ -75,46 +75,46 @@ Disassembly of section .debug_info: 0: 0000013d andeq r0, r0, sp, lsr r1 4: 00000002 andeq r0, r0, r2 8: 01040000 mrseq r0, (UNDEF: 4) - c: 000000e6 andeq r0, r0, r6, ror #1 - 10: 00008601 andeq r8, r0, r1, lsl #12 - 14: 00003f00 andeq r3, r0, r0, lsl #30 + c: 000000e9 andeq r0, r0, r9, ror #1 + 10: 00005301 andeq r5, r0, r1, lsl #6 + 14: 0000ad00 andeq sl, r0, r0, lsl #26 18: 0000dc00 andeq sp, r0, r0, lsl #24 1c: 0000dc00 andeq sp, r0, r0, lsl #24 20: 00000000 andeq r0, r0, r0 24: 06010200 streq r0, [r1], -r0, lsl #4 - 28: 000000d4 ldrdeq r0, [r0], -r4 + 28: 000000a1 andeq r0, r0, r1, lsr #1 2c: 00000603 andeq r0, r0, r3, lsl #12 30: 37270100 strcc r0, [r7, -r0, lsl #2]! 34: 02000000 andeq r0, r0, #0 - 38: 00d20801 sbcseq r0, r2, r1, lsl #16 + 38: 009f0801 addseq r0, pc, r1, lsl #16 3c: 02020000 andeq r0, r2, #0 - 40: 00013705 andeq r3, r1, r5, lsl #14 + 40: 00013105 andeq r3, r1, r5, lsl #2 44: 07020200 streq r0, [r2, -r0, lsl #4] - 48: 00000112 andeq r0, r0, r2, lsl r1 + 48: 00000115 andeq r0, r0, r5, lsl r1 4c: 69050404 stmdbvs r5, {r2, sl} 50: 0300746e movweq r7, #1134 ; 0x46e 54: 00000000 andeq r0, r0, r0 58: 005e2b01 subseq r2, lr, r1, lsl #22 5c: 04020000 streq r0, [r2], #-0 - 60: 00011807 andeq r1, r1, r7, lsl #16 + 60: 00011b07 andeq r1, r1, r7, lsl #22 64: 000b0500 andeq r0, fp, r0, lsl #10 68: 01300000 teqeq r0, r0 6c: 0000fe3e andeq pc, r0, lr, lsr lr ; - 70: 00b30600 adcseq r0, r3, r0, lsl #12 + 70: 00800600 addeq r0, r0, r0, lsl #12 74: 40010000 andmi r0, r1, r0 78: 00000053 andeq r0, r0, r3, asr r0 7c: 06002302 streq r2, [r0], -r2, lsl #6 - 80: 000000e0 andeq r0, r0, r0, ror #1 + 80: 000000e3 andeq r0, r0, r3, ror #1 84: 00fe4101 rscseq r4, lr, r1, lsl #2 88: 23020000 movwcs r0, #8192 ; 0x2000 - 8c: 01080604 tsteq r8, r4, lsl #12 + 8c: 010b0604 tsteq fp, r4, lsl #12 90: 42010000 andmi r0, r1, #0 94: 00000053 andeq r0, r0, r3, asr r0 98: 060c2302 streq r2, [ip], -r2, lsl #6 9c: 0000002b andeq r0, r0, fp, lsr #32 a0: 00534301 subseq r4, r3, r1, lsl #6 a4: 23020000 movwcs r0, #8192 ; 0x2000 - a8: 00c40610 sbceq r0, r4, r0, lsl r6 + a8: 00910610 addseq r0, r1, r0, lsl r6 ac: 44010000 strmi r0, [r1], #-0 b0: 00000053 andeq r0, r0, r3, asr r0 b4: 06142302 ldreq r2, [r4], -r2, lsl #6 @@ -125,14 +125,14 @@ Disassembly of section .debug_info: c8: 46010000 strmi r0, [r1], -r0 cc: 0000010e andeq r0, r0, lr, lsl #2 d0: 061c2302 ldreq r2, [ip], -r2, lsl #6 - d4: 0000007b andeq r0, r0, fp, ror r0 + d4: 00000048 andeq r0, r0, r8, asr #32 d8: 010e4701 tsteq lr, r1, lsl #14 dc: 23020000 movwcs r0, #8192 ; 0x2000 - e0: 01250620 teqeq r5, r0, lsr #12 + e0: 003f0620 eorseq r0, pc, r0, lsr #12 e4: 48010000 stmdami r1, {} ; e8: 0000010e andeq r0, r0, lr, lsl #2 ec: 06242302 strteq r2, [r4], -r2, lsl #6 - f0: 0000012e andeq r0, r0, lr, lsr #2 + f0: 00000128 andeq r0, r0, r8, lsr #2 f4: 00fe4901 rscseq r4, lr, r1, lsl #18 f8: 23020000 movwcs r0, #8192 ; 0x2000 fc: 2c070028 stccs 0, cr0, [r7], {40} ; 0x28 @@ -143,10 +143,10 @@ Disassembly of section .debug_info: 110: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0} 114: 08000001 stmdaeq r0, {r0} 118: 0000005e andeq r0, r0, lr, asr r0 - 11c: 4d030003 stcmi 0, cr0, [r3, #-12] + 11c: 47030003 strmi r0, [r3, -r3] 120: 01000001 tsteq r0, r1 124: 0000654a andeq r6, r0, sl, asr #10 - 128: 01410900 cmpeq r1, r0, lsl #18 + 128: 013b0900 teqeq fp, r0, lsl #18 12c: 25020000 strcs r0, [r2, #-0] 130: 0000013b andeq r0, r0, fp, lsr r1 134: 00030501 andeq r0, r3, r1, lsl #10 @@ -245,79 +245,79 @@ Disassembly of section .debug_str: 30: 75700068 ldrbvc r0, [r0, #-104]! ; 0x68 34: 65685f62 strbvs r5, [r8, #-3938]! ; 0xf62 38: 765f6461 ldrbvc r6, [pc], -r1, ror #8 - 3c: 2f006e73 svccs 0x00006e73 - 40: 656d6f68 strbvs r6, [sp, #-3944]! ; 0xf68 - 44: 6f656c2f svcvs 0x00656c2f - 48: 6472616e ldrbtvs r6, [r2], #-366 ; 0x16e - 4c: 72702f6f rsbsvc r2, r0, #444 ; 0x1bc - 50: 63656a6f cmnvs r5, #454656 ; 0x6f000 - 54: 6d2f7374 stcvs 3, cr7, [pc, #-464]! ; fffffe8c <__bss_end+0xfffffdb0> - 58: 5f656b61 svcpl 0x00656b61 - 5c: 61657261 cmnvs r5, r1, ror #4 - 60: 61724f2f cmnvs r2, pc, lsr #30 - 64: 5065676e rsbpl r6, r5, lr, ror #14 - 68: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 - 6c: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 - 70: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} - 74: 332d7875 teqcc sp, #7667712 ; 0x750000 - 78: 5200342e andpl r3, r0, #771751936 ; 0x2e000000 - 7c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c - 80: 73765f65 cmnvc r6, #404 ; 0x194 - 84: 7261006e rsbvc r0, r1, #110 ; 0x6e - 88: 612f6863 teqvs pc, r3, ror #16 - 8c: 6d2f6d72 stcvs 13, cr6, [pc, #-456]! ; fffffecc <__bss_end+0xfffffdf0> - 90: 2d686361 stclcs 3, cr6, [r8, #-388]! ; 0xfffffe7c - 94: 786e7573 stmdavc lr!, {r0, r1, r4, r5, r6, r8, sl, ip, sp, lr}^ - 98: 6f702f69 svcvs 0x00702f69 - 9c: 2f726577 svccs 0x00726577 - a0: 6d6f7262 sfmvs f7, 2, [pc, #-392]! ; ffffff20 <__bss_end+0xfffffe44> - a4: 7365722f cmnvc r5, #-268435454 ; 0xf0000002 - a8: 5f656d75 svcpl 0x00656d75 - ac: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - b0: 6a00632e bvs 18d70 <__bss_end+0x18c94> - b4: 5f706d75 svcpl 0x00706d75 - b8: 74736e69 ldrbtvc r6, [r3], #-3689 ; 0xe69 - bc: 74637572 strbtvc r7, [r3], #-1394 ; 0x572 - c0: 006e6f69 rsbeq r6, lr, r9, ror #30 - c4: 5f627570 svcpl 0x00627570 - c8: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - cc: 7a69735f bvc 1a5ce50 <__bss_end+0x1a5cd74> - d0: 6e750065 cdpvs 0, 7, cr0, cr5, cr5, {3} - d4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} - d8: 63206465 teqvs r0, #1694498816 ; 0x65000000 - dc: 00726168 rsbseq r6, r2, r8, ror #2 - e0: 6967616d stmdbvs r7!, {r0, r2, r3, r5, r6, r8, sp, lr}^ - e4: 4e470063 cdpmi 0, 4, cr0, cr7, cr3, {3} - e8: 20432055 subcs r2, r3, r5, asr r0 - ec: 2e362e34 mrccs 14, 1, r2, cr6, cr4, {1} - f0: 30322033 eorscc r2, r2, r3, lsr r0 - f4: 32303231 eorscc r3, r0, #268435459 ; 0x10000003 - f8: 28203130 stmdacs r0!, {r4, r5, r8, ip, sp} - fc: 72657270 rsbvc r7, r5, #7 - 100: 61656c65 cmnvs r5, r5, ror #24 - 104: 00296573 eoreq r6, r9, r3, ror r5 - 108: 63656863 cmnvs r5, #6488064 ; 0x630000 - 10c: 75735f6b ldrbvc r5, [r3, #-3947]! ; 0xf6b - 110: 6873006d ldmdavs r3!, {r0, r2, r3, r5, r6}^ - 114: 2074726f rsbscs r7, r4, pc, ror #4 - 118: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^ - 11c: 64656e67 strbtvs r6, [r5], #-3687 ; 0xe67 - 120: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 - 124: 4f476500 svcmi 0x00476500 - 128: 73765f4e cmnvc r6, #312 ; 0x138 - 12c: 6c70006e ldclvs 0, cr0, [r0], #-440 ; 0xfffffe48 - 130: 6f667461 svcvs 0x00667461 - 134: 73006d72 movwvc r6, #3442 ; 0xd72 - 138: 74726f68 ldrbtvc r6, [r2], #-3944 ; 0xf68 - 13c: 746e6920 strbtvc r6, [lr], #-2336 ; 0x920 - 140: 73657200 cmnvc r5, #0 - 144: 5f656d75 svcpl 0x00656d75 - 148: 64616568 strbtvs r6, [r1], #-1384 ; 0x568 - 14c: 73657200 cmnvc r5, #0 - 150: 5f656d75 svcpl 0x00656d75 - 154: 656c6966 strbvs r6, [ip, #-2406]! ; 0x966 - 158: 6165685f cmnvs r5, pc, asr r8 - 15c: 00745f64 rsbseq r5, r4, r4, ror #30 + 3c: 65006e73 strvs r6, [r0, #-3699] ; 0xe73 + 40: 5f4e4f47 svcpl 0x004e4f47 + 44: 006e7376 rsbeq r7, lr, r6, ror r3 + 48: 75736552 ldrbvc r6, [r3, #-1362]! ; 0x552 + 4c: 765f656d ldrbvc r6, [pc], -sp, ror #10 + 50: 61006e73 tstvs r0, r3, ror lr + 54: 2f686372 svccs 0x00686372 + 58: 2f6d7261 svccs 0x006d7261 + 5c: 6863616d stmdavs r3!, {r0, r2, r3, r5, r6, r8, sp, lr}^ + 60: 6e75732d cdpvs 3, 7, cr7, cr5, cr13, {1} + 64: 702f6978 eorvc r6, pc, r8, ror r9 ; + 68: 7265776f rsbvc r7, r5, #29097984 ; 0x1bc0000 + 6c: 6f72622f svcvs 0x0072622f + 70: 65722f6d ldrbvs r2, [r2, #-3949]! ; 0xf6d + 74: 656d7573 strbvs r7, [sp, #-1395]! ; 0x573 + 78: 6165685f cmnvs r5, pc, asr r8 + 7c: 00632e64 rsbeq r2, r3, r4, ror #28 + 80: 706d756a rsbvc r7, sp, sl, ror #10 + 84: 736e695f cmnvc lr, #1556480 ; 0x17c000 + 88: 63757274 cmnvs r5, #1073741831 ; 0x40000007 + 8c: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3} + 90: 62757000 rsbsvs r7, r5, #0 + 94: 6165685f cmnvs r5, pc, asr r8 + 98: 69735f64 ldmdbvs r3!, {r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 9c: 7500657a strvc r6, [r0, #-1402] ; 0x57a + a0: 6769736e strbvs r7, [r9, -lr, ror #6]! + a4: 2064656e rsbcs r6, r4, lr, ror #10 + a8: 72616863 rsbvc r6, r1, #6488064 ; 0x630000 + ac: 706f2f00 rsbvc r2, pc, r0, lsl #30 + b0: 6f762f74 svcvs 0x00762f74 + b4: 6974616c ldmdbvs r4!, {r2, r3, r5, r6, r8, sp, lr}^ + b8: 655f656c ldrbvs r6, [pc, #-1388] ; fffffb54 <__bss_end+0xfffffa78> + bc: 442f766e strtmi r7, [pc], #-1646 ; c4 + c0: 6c6e776f stclvs 7, cr7, [lr], #-444 ; 0xfffffe44 + c4: 7364616f cmnvc r4, #-1073741797 ; 0xc000001b + c8: 61724f2f cmnvs r2, pc, lsr #30 + cc: 5065676e rsbpl r6, r5, lr, ror #14 + d0: 654b2d49 strbvs r2, [fp, #-3401] ; 0xd49 + d4: 6c656e72 stclvs 14, cr6, [r5], #-456 ; 0xfffffe38 + d8: 6e696c2f cdpvs 12, 6, cr6, cr9, cr15, {1} + dc: 332d7875 teqcc sp, #7667712 ; 0x750000 + e0: 6d00342e cfstrsvs mvf3, [r0, #-184] ; 0xffffff48 + e4: 63696761 cmnvs r9, #25427968 ; 0x1840000 + e8: 554e4700 strbpl r4, [lr, #-1792] ; 0x700 + ec: 34204320 strtcc r4, [r0], #-800 ; 0x320 + f0: 332e362e teqcc lr, #48234496 ; 0x2e00000 + f4: 31303220 teqcc r0, r0, lsr #4 + f8: 30323032 eorscc r3, r2, r2, lsr r0 + fc: 70282031 eorvc r2, r8, r1, lsr r0 + 100: 65726572 ldrbvs r6, [r2, #-1394]! ; 0x572 + 104: 7361656c cmnvc r1, #452984832 ; 0x1b000000 + 108: 63002965 movwvs r2, #2405 ; 0x965 + 10c: 6b636568 blvs 18d96b4 <__bss_end+0x18d95d8> + 110: 6d75735f ldclvs 3, cr7, [r5, #-380]! ; 0xfffffe84 + 114: 6f687300 svcvs 0x00687300 + 118: 75207472 strvc r7, [r0, #-1138]! ; 0x472 + 11c: 6769736e strbvs r7, [r9, -lr, ror #6]! + 120: 2064656e rsbcs r6, r4, lr, ror #10 + 124: 00746e69 rsbseq r6, r4, r9, ror #28 + 128: 74616c70 strbtvc r6, [r1], #-3184 ; 0xc70 + 12c: 6d726f66 ldclvs 15, cr6, [r2, #-408]! ; 0xfffffe68 + 130: 6f687300 svcvs 0x00687300 + 134: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr} + 138: 7200746e andvc r7, r0, #1845493760 ; 0x6e000000 + 13c: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 140: 65685f65 strbvs r5, [r8, #-3941]! ; 0xf65 + 144: 72006461 andvc r6, r0, #1627389952 ; 0x61000000 + 148: 6d757365 ldclvs 3, cr7, [r5, #-404]! ; 0xfffffe6c + 14c: 69665f65 stmdbvs r6!, {r0, r2, r5, r6, r8, r9, sl, fp, ip, lr}^ + 150: 685f656c ldmdavs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; + 154: 5f646165 svcpl 0x00646165 + 158: Address 0x00000158 is out of bounds. + Disassembly of section .comment: diff --git a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map index 0947a995..cf8e9fcb 100644 --- a/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map +++ b/linux-3.4/arch/arm/mach-sunxi/power/brom/resumes.map @@ -71,9 +71,9 @@ OUTPUT(arch/arm/mach-sunxi/power/brom/resumes.elf elf32-littlearm) .debug_line 0x00000000 0x7b .debug_line 0x00000000 0x7b arch/arm/mach-sunxi/power/brom/resume_head.o -.debug_str 0x00000000 0x160 - .debug_str 0x00000000 0x160 arch/arm/mach-sunxi/power/brom/resume_head.o - 0x179 (size before relaxing) +.debug_str 0x00000000 0x15a + .debug_str 0x00000000 0x15a arch/arm/mach-sunxi/power/brom/resume_head.o + 0x173 (size before relaxing) .comment 0x00000000 0x64 .comment 0x00000000 0x64 arch/arm/mach-sunxi/power/brom/resume_head.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod index 44e66785..0a7e3e5f 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/.tmp_versions/mali.mod @@ -1,2 +1,2 @@ -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali.ko +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_atomics.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_irq.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wq.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_locks.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_wait_queue.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_math.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_memory.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_misc.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_mali.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_notification.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_time.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_timers.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_os_alloc.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_external.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_block_alloc.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_mem.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_gp.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_pp.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_core.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_soft_job.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_timeline.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_platform.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_core.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_linux.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_session.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_device_pause_resume.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_vsync.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_vsync.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mmu_page_directory.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_mem_validation.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_hw_core.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_job.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_job.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_soft_job.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_scheduler.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_gp_scheduler.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pp_scheduler.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_group.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dlbu.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_broadcast.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pmu.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_user_settings_db.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_kernel_utilization.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_l2_cache.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_dma.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_fence_wait.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_timeline_sync_fence.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_spinlock_reentrant.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/common/mali_pm_domain.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_pm.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/__malidrv_build_info.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_ukk_profiling.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_osk_profiling.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_dma_buf.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_sync.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/linux/mali_memory_ump.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers index 90538e7d..326ff160 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/Module.symvers @@ -1,21 +1,21 @@ -0x62c42e0c _mali_profiling_get_api_version /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xb9ac0503 mali_set_user_setting /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x94289922 mali_pmu_powerdown /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x2a7049ed mali_perf_set_num_pp_cores /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x0d8ccbae mali_dev_resume /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x7c2fb465 mali_dev_pause /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xf8224b12 mali_get_user_setting /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x428fd838 _mali_profiling_set_event /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xcdcdf6bf _mali_profiling_get_l2_counters /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0x4580d143 _mali_profiling_control /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x706fc943 mali_pmu_powerup /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xdcd285aa _mali_profiling_get_mali_version /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x62c42e0c _mali_profiling_get_api_version /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xb9ac0503 mali_set_user_setting /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x94289922 mali_pmu_powerdown /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x2a7049ed mali_perf_set_num_pp_cores /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x0d8ccbae mali_dev_resume /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x7c2fb465 mali_dev_pause /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xf8224b12 mali_get_user_setting /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x428fd838 _mali_profiling_set_event /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xcdcdf6bf _mali_profiling_get_l2_counters /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0x4580d143 _mali_profiling_control /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x706fc943 mali_pmu_powerup /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xdcd285aa _mali_profiling_get_mali_version /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/mali/mali EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod index ff0c4ad3..601f5e81 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/.tmp_versions/ump.mod @@ -1,2 +1,2 @@ -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump.ko +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_common.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_api.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/common/ump_kernel_ref_drv.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_linux.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_memory_backend.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_atomics.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/linux/ump_osk_misc.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_atomics.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_locks.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_memory.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_math.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/../mali/linux/mali_osk_misc.o diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers index c95c7fff..2ccd3e9d 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/Module.symvers @@ -1,9 +1,9 @@ -0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x9b680a42 ump_dd_reference_release /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x920accbd ump_dd_secure_id_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x59dddb40 ump_dd_reference_add /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0x8ee7279a ump_dd_size_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL -0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8164b1cc ump_dd_handle_create_from_secure_id /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x9b680a42 ump_dd_reference_release /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xf8d54998 ump_dd_handle_create_from_phys_blocks /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x920accbd ump_dd_secure_id_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x639399b9 ump_dd_phys_block_count_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xbc25aac9 ump_dd_phys_blocks_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x59dddb40 ump_dd_reference_add /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0x8ee7279a ump_dd_size_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL +0xa7dd8c46 ump_dd_phys_block_get /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/devicedrv/ump/ump EXPORT_SYMBOL diff --git a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod index ec462119..09222301 100644 --- a/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod +++ b/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/.tmp_versions/mali_drm.mod @@ -1,2 +1,2 @@ -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko -/opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /opt/volatile_env/projects/make_area/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali_drm.ko +/opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_drv.o /opt/volatile_env/Downloads/OrangePI-Kernel/linux-3.4/modules/mali/DX910-SW-99002-r4p0-00rel0_modify/driver/src/egl/x11/drm_module/mali_drm/mali/mali_mm.o From 575d95914871f76c6c0b885929364d1d803f095d Mon Sep 17 00:00:00 2001 From: lhelontra Date: Mon, 7 Aug 2017 18:18:13 -0300 Subject: [PATCH 17/26] small changes --- build/sun8iw7p1smp_lobo_defconfig | 84 ++++++++++++++++++--------- build/sun8iw7p1smp_lobo_defconfig.old | 84 ++++++++++++++++++--------- 2 files changed, 114 insertions(+), 54 deletions(-) diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index ad59869b..3074a9ff 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -608,38 +608,66 @@ CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -658,10 +686,13 @@ CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -2657,8 +2688,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_HCTOSYS is not set # CONFIG_RTC_DEBUG is not set # diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index ad59869b..3074a9ff 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -608,38 +608,66 @@ CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -658,10 +686,13 @@ CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -2657,8 +2688,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_HCTOSYS is not set # CONFIG_RTC_DEBUG is not set # From 961776c0502a62cffc4e28c920833a664c66b02f Mon Sep 17 00:00:00 2001 From: lhelontra Date: Mon, 7 Aug 2017 18:33:25 -0300 Subject: [PATCH 18/26] small fixes --- build/sun8iw7p1smp_lobo_defconfig | 2 +- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 84 +++++++++++++------ 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 3074a9ff..8a48129b 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index ad59869b..3074a9ff 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -608,38 +608,66 @@ CONFIG_XFRM_USER=y # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=y +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -658,10 +686,13 @@ CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -2657,8 +2688,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_HCTOSYS is not set # CONFIG_RTC_DEBUG is not set # From 9691f90ba012d7a1ee4d195cae3f115feacfb83a Mon Sep 17 00:00:00 2001 From: lhelontra Date: Mon, 7 Aug 2017 18:35:47 -0300 Subject: [PATCH 19/26] small fixes --- build/sun8iw7p1smp_lobo_defconfig.old | 2 +- linux-3.4/.config | 3333 +++++++++++++++++++++++++ linux-3.4/.config.bak | 3333 +++++++++++++++++++++++++ linux-3.4/.gitignore | 107 - 4 files changed, 6667 insertions(+), 108 deletions(-) create mode 100644 linux-3.4/.config create mode 100644 linux-3.4/.config.bak delete mode 100644 linux-3.4/.gitignore diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 3074a9ff..8a48129b 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y diff --git a/linux-3.4/.config b/linux-3.4/.config new file mode 100644 index 00000000..8a48129b --- /dev/null +++ b/linux-3.4/.config @@ -0,0 +1,3333 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.4.39-02-lobo Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_NEED_MACH_IO_H=y +CONFIG_NEED_MACH_MEMORY_H=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="sun8i" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_FHANDLE=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y +# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y +CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="output/rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# System MMU +# +CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 +CONFIG_ARCH_SUN8I=y +# CONFIG_ARCH_SUN9I is not set +# CONFIG_ARCH_SUN8IW1 is not set +# CONFIG_ARCH_SUN8IW3 is not set +# CONFIG_ARCH_SUN8IW5 is not set +# CONFIG_ARCH_SUN8IW6 is not set +CONFIG_ARCH_SUN8IW7=y +# CONFIG_ARCH_SUN8IW8 is not set +# CONFIG_ARCH_SUN8IW9 is not set +CONFIG_ARCH_SUN8IW7P1=y +# CONFIG_FPGA_V4_PLATFORM is not set +# CONFIG_FPGA_V7_PLATFORM is not set +CONFIG_EVB_PLATFORM=y + +# +# Power management +# + +# +# Common Features Selection +# + +# +# Boot Options +# +# CONFIG_SUNXI_TRUSTZONE is not set +CONFIG_HOMLET_PLATFORM=y +# CONFIG_SUNXI_BOOTUP_EXTEND is not set +CONFIG_SUNXI_OOPS_HOOK=y + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +CONFIG_ARM_GIC=y +# CONFIG_FIQ_DEBUGGER is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_NR_GPIO=2048 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y + +# +# Boot options +# +# CONFIG_USE_OF is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +# CONFIG_CMDLINE_EXTEND is not set +CONFIG_CMDLINE_FORCE=y +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y + +# +# ARM CPU frequency scaling drivers +# +CONFIG_ARM_SUNXI_CPUFREQ=y +# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set +# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_WAKELOCK is not set +CONFIG_SCENELOCK=y +CONFIG_USER_SCENELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_APM_EMULATION=y +CONFIG_PM_CLK=y +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_NET_ACTIVITY_STATS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=m +# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +# CONFIG_NET_ACT_SIMP is not set +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_DEBUG is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_NETPRIO_CGROUP=m +CONFIG_BQL=y +CONFIG_HAVE_BPF_JIT=y +CONFIG_BPF_JIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_RTKH5=y +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_BCM_BT_LPM=m +CONFIG_RTL_BT_LPM=m +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# +CONFIG_SUNXI_ARISC=y + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_RESERVE_BASE=0x43400000 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=0 +CONFIG_CMA_AREAS=7 +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +# CONFIG_SW_SYNC_USER is not set + +# +# Bus devices +# +CONFIG_SUNXI_MBUS=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SUNXI_VIBRATOR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +CONFIG_UID_STAT=y +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SUNXI_BROM_READ is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +# CONFIG_SW_3G_MODULE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MULTICORE_RAID456 is not set +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=m +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_MIRROR is not set +CONFIG_DM_RAID=m +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +CONFIG_MII=y +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +CONFIG_VETH=m + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_NET_VENDOR_SUNXI=y +CONFIG_SUNXI_GETH=y +CONFIG_GETH_SCRIPT_SYS=y +CONFIG_GETH_CLK_SYS=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_QF9700=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=m +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BCMDHD=m +CONFIG_BCMDHD_FW_PATH=y +CONFIG_BCMDHD_NVRAM_PATH=y +CONFIG_BCMDHD_CONFIG_PATH=y +CONFIG_BCMDHD_OOB=y +# CONFIG_BCMDHD_SDIO_IRQ is not set +# CONFIG_AP6210 is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +# CONFIG_RT2500USB is not set +# CONFIG_RT73USB is not set +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_DEBUG=y +CONFIG_RTL8192C_COMMON=m +# CONFIG_WL1251 is not set +# CONFIG_WL12XX_MENU is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +CONFIG_RTL8188EU=m +CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m +CONFIG_RTL8723BS=m + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_APMPOWER is not set +# CONFIG_INPUT_KEYRESET is not set +CONFIG_INPUT_SW_DEVICE=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_SUNXI=y +CONFIG_IR_RX_SUNXI=m +# CONFIG_SUNXI_ANYIR_SUPPORT is not set +# CONFIG_IR_TX_SUNXI is not set +# CONFIG_SUNXI_GPIO_KEY is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_TOUCHSCREEN_GT82X=m +# CONFIG_TOUCHSCREEN_SUN6I_TS is not set +CONFIG_TOUCHSCREEN_FT5X_TS=m +CONFIG_TOUCHSCREEN_GT9XX_TS=m +CONFIG_TOUCHSCREEN_GT9XXF_TS=m +CONFIG_TOUCHSCREEN_GSLX680=m +CONFIG_TOUCHSCREEN_GSLX680NEW=m +CONFIG_TOUCHSCREEN_AW5X06_TS=m +CONFIG_TOUCHSCREEN_GT818_TS=m +CONFIG_TOUCHSCREEN_TU_TS=m +CONFIG_TOUCHSCREEN_ICN83XX_TS=m +CONFIG_INPUT_MISC=y +# CONFIG_E_COMPASS_L3M303D is not set +# CONFIG_E_COMPASS_FXOS8700 is not set +# CONFIG_E_COMPASS_AKM8963 is not set +# CONFIG_GYR_L3GD20 is not set +# CONFIG_GYR_BMG160 is not set +CONFIG_INPUT_LTR501ALS=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_CMA3000 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +CONFIG_SERIAL_SUNXI=y +CONFIG_SERIAL_SUNXI_CONSOLE=y +# CONFIG_SERIAL_DEBUG is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_RAMOOPS is not set +# CONFIG_SUNXI_D7S is not set +CONFIG_SUNXI_CMATESET=y +# CONFIG_SUNXI_ARISC_TEST is not set +# CONFIG_SUNXI_MODULE is not set +# CONFIG_SUNXI_TIMER_TEST is not set +# CONFIG_SUNXI_DMA_TEST is not set +CONFIG_SUNXI_SCR=m +CONFIG_SUNXI_DI=m +CONFIG_SUNXI_SOC_INFO=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_SUNXI=y +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_SUNXI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUNXI_DEBUG is not set +# CONFIG_SUNXI_PINCTRL_TEST is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_GPIO_SUNXI=m +CONFIG_W1=m +CONFIG_W1_SUNXI=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_KIONIX is not set +# CONFIG_SENSORS_MMA7660 is not set +# CONFIG_SENSORS_MMA865x is not set +# CONFIG_SENSORS_MMA8452 is not set +# CONFIG_SENSORS_AFA750 is not set +# CONFIG_SENSORS_BMA250 is not set +# CONFIG_SENSORS_LIS3DH_ACC is not set +# CONFIG_SENSORS_LIS3DE_ACC is not set +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set + +# +# INA219 drivers +# +# CONFIG_SENSORS_INA219 is not set +# CONFIG_SENSORS_DUMMY_ACC is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_FAIR_SHARE is not set +CONFIG_STEP_WISE=y +# CONFIG_USER_SPACE is not set +# CONFIG_SUNXI_THERMAL_DYNAMIC is not set +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_BUDGET_THERMAL=y +CONFIG_SUNXI_THERMAL=y +CONFIG_SUNXI_BUDGET_COOLING=y +# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_SUNXI_WDT=m + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_AC100 is not set +# CONFIG_MFD_AC200 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_REGULATOR is not set +CONFIG_PWM=y +CONFIG_PWM_SUNXI=m +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_MAP=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_CUSTOMISE=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +# CONFIG_VIDEO_IR_I2C is not set + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_AK881X is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SR030PC30 is not set + +# +# Flash devices +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_VIDEO_SUNXI_VFE=m +CONFIG_CSI_VFE=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_AW_TSC=y +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_UDL is not set +CONFIG_ION=y +CONFIG_ION_SUNXI=y +CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# + +# +# Video support for sunxi +# +CONFIG_FB_CONSOLE_SUNXI=y +CONFIG_DISP2_SUNXI=y +CONFIG_HDMI_DISP2_SUNXI=y +CONFIG_TV_DISP2_SUNXI=m +# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set +CONFIG_DISP2_SUNXI_DEBUG=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y +CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y +CONFIG_SND_SUN8IW7_SNDCODEC=y +# CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE is not set +CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y +CONFIG_SND_SUN8IW7_HDMIPCM=y +CONFIG_SND_SUNXI_SOC_SPDIF=m +# CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE is not set +# CONFIG_SND_SUN8IW7_AUDIOHUB is not set +# CONFIG_SND_SUNXI_SOC_SUPPORT_AUDIO_RAW is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_UHID=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_REMOTE_WAKEUP is not set +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +CONFIG_HID_PRODIKEYS=y +# CONFIG_HID_CYPRESS is not set +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EMS_FF=y +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_EZKEY is not set +CONFIG_HID_HOLTEK=y +# CONFIG_HOLTEK_FF is not set +CONFIG_HID_KEYTOUCH=y +# CONFIG_HID_KYE is not set +CONFIG_HID_UCLOGIC=y +CONFIG_HID_WALTOP=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LCPOWER=y +CONFIG_HID_LOGITECH=y +# CONFIG_HID_LOGITECH_DJ is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIWHEELS_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +CONFIG_HID_PRIMAX=y +CONFIG_HID_ROCCAT=y +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SPEEDLINK=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +# CONFIG_HID_TIVO is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set +CONFIG_HID_ZYDACRON=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_SUNXI is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_SUNXI_HCD=y +CONFIG_USB_SUNXI_HCD0=y +CONFIG_USB_SUNXI_HCI=y +CONFIG_USB_SUNXI_EHCI0=y +CONFIG_USB_SUNXI_EHCI1=y +CONFIG_USB_SUNXI_OHCI0=y +CONFIG_USB_SUNXI_OHCI1=y +CONFIG_USB_SUNXI_EHCI2=y +CONFIG_USB_SUNXI_OHCI2=y +CONFIG_USB_SUNXI_EHCI3=y +CONFIG_USB_SUNXI_OHCI3=y +CONFIG_USB_SUNXI_HSIC=y +# CONFIG_SW_USB_3G is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_SUNXI_UDC0=y +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_SUNXI_USB=y +CONFIG_USB_SUNXI_USB_MANAGER=y +# CONFIG_USB_SUNXI_USB0_NULL is not set +# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set +# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set +CONFIG_USB_SUNXI_USB0_OTG=y +CONFIG_USB_SUNXI_USB_DEBUG=y +CONFIG_USB_SUNXI_HOST=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +# CONFIG_MMC_CLKGATE is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_DW is not set +CONFIG_MMC_SUNXI=y +# CONFIG_MMC_DEBUG_SUNXI is not set +CONFIG_MMC_PRE_DBGLVL_SUNXI=0 +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_SUNXI_LEDS=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_OT200 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SUNXI=y +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +CONFIG_SUNXI_DMA=y +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y +CONFIG_COMMON_CLK_DEBUG=y + +# +# SUNXI Clock Configuration +# +CONFIG_SUNXI_CLK_DEFAULT_INIT=y +CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y +CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 +CONFIG_AHB1_CLK_DFT_VALUE=200000000 +CONFIG_APB1_CLK_DFT_VALUE=100000000 + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_MMIO=y +CONFIG_SUNXI_TIMER=y +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_DRAM_FREQ=y +# CONFIG_DRAM_FREQ_BSP_TEST is not set +# CONFIG_GATOR_PERF is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=y +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFS_FSCACHE is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_FAULT_INJECTION=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_FSCACHE is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=20 +CONFIG_RCU_CPU_STALL_VERBOSE=y +CONFIG_RCU_CPU_STALL_INFO=y +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_ASYNC_RAID6_TEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +# CONFIG_TEST_KSTRTOX is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_RODATA is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_SUNXI_UART0=y +# CONFIG_DEBUG_SUNXI_UART1 is not set +# CONFIG_DEBUG_SUNXI_UART2 is not set +# CONFIG_DEBUG_LL_UART_NONE is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +CONFIG_EARLY_PRINTK=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_TRUSTED_LITTLE_KERNEL is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_SUNXI=m +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_AVERAGE=y +# CONFIG_CORDIC is not set diff --git a/linux-3.4/.config.bak b/linux-3.4/.config.bak new file mode 100644 index 00000000..8a48129b --- /dev/null +++ b/linux-3.4/.config.bak @@ -0,0 +1,3333 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.4.39-02-lobo Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_NEED_MACH_IO_H=y +CONFIG_NEED_MACH_MEMORY_H=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="sun8i" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_FHANDLE=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y +# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y +CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="output/rootfs.cpio.gz" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=5 +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_SYSV68_PARTITION=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# System MMU +# +CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 +CONFIG_ARCH_SUN8I=y +# CONFIG_ARCH_SUN9I is not set +# CONFIG_ARCH_SUN8IW1 is not set +# CONFIG_ARCH_SUN8IW3 is not set +# CONFIG_ARCH_SUN8IW5 is not set +# CONFIG_ARCH_SUN8IW6 is not set +CONFIG_ARCH_SUN8IW7=y +# CONFIG_ARCH_SUN8IW8 is not set +# CONFIG_ARCH_SUN8IW9 is not set +CONFIG_ARCH_SUN8IW7P1=y +# CONFIG_FPGA_V4_PLATFORM is not set +# CONFIG_FPGA_V7_PLATFORM is not set +CONFIG_EVB_PLATFORM=y + +# +# Power management +# + +# +# Common Features Selection +# + +# +# Boot Options +# +# CONFIG_SUNXI_TRUSTZONE is not set +CONFIG_HOMLET_PLATFORM=y +# CONFIG_SUNXI_BOOTUP_EXTEND is not set +CONFIG_SUNXI_OOPS_HOOK=y + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +CONFIG_ARM_GIC=y +# CONFIG_FIQ_DEBUGGER is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_NR_GPIO=2048 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y + +# +# Boot options +# +# CONFIG_USE_OF is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set +# CONFIG_CMDLINE_EXTEND is not set +CONFIG_CMDLINE_FORCE=y +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y + +# +# ARM CPU frequency scaling drivers +# +CONFIG_ARM_SUNXI_CPUFREQ=y +# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set +# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_WAKELOCK is not set +CONFIG_SCENELOCK=y +CONFIG_USER_SCENELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_APM_EMULATION=y +CONFIG_PM_CLK=y +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_NET_ACTIVITY_STATS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_TIMEOUT=y +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_NETLINK_TIMEOUT=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_QUOTA2=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_REJECT_SKERR=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=m +# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=y +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +# CONFIG_NET_ACT_SIMP is not set +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +# CONFIG_BATMAN_ADV_DEBUG is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_NETPRIO_CGROUP=m +CONFIG_BQL=y +CONFIG_HAVE_BPF_JIT=y +CONFIG_BPF_JIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART_RTKH5=y +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_BCM_BT_LPM=m +CONFIG_RTL_BT_LPM=m +# CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# +CONFIG_SUNXI_ARISC=y + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_RESERVE_BASE=0x43400000 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=0 +CONFIG_CMA_AREAS=7 +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +# CONFIG_SW_SYNC_USER is not set + +# +# Bus devices +# +CONFIG_SUNXI_MBUS=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SUNXI_VIBRATOR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +CONFIG_UID_STAT=y +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SUNXI_BROM_READ is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +# CONFIG_SW_3G_MODULE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MULTICORE_RAID456 is not set +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=m +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_MIRROR is not set +CONFIG_DM_RAID=m +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +CONFIG_MII=y +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +CONFIG_VETH=m + +# +# CAIF transport drivers +# +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_NET_VENDOR_SUNXI=y +CONFIG_SUNXI_GETH=y +CONFIG_GETH_SCRIPT_SYS=y +CONFIG_GETH_CLK_SYS=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_QF9700=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=m +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BCMDHD=m +CONFIG_BCMDHD_FW_PATH=y +CONFIG_BCMDHD_NVRAM_PATH=y +CONFIG_BCMDHD_CONFIG_PATH=y +CONFIG_BCMDHD_OOB=y +# CONFIG_BCMDHD_SDIO_IRQ is not set +# CONFIG_AP6210 is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +# CONFIG_RT2500USB is not set +# CONFIG_RT73USB is not set +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_DEBUG=y +CONFIG_RTL8192C_COMMON=m +# CONFIG_WL1251 is not set +# CONFIG_WL12XX_MENU is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +CONFIG_RTL8188EU=m +CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m +CONFIG_RTL8723BS=m + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_APMPOWER is not set +# CONFIG_INPUT_KEYRESET is not set +CONFIG_INPUT_SW_DEVICE=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_SUNXI=y +CONFIG_IR_RX_SUNXI=m +# CONFIG_SUNXI_ANYIR_SUPPORT is not set +# CONFIG_IR_TX_SUNXI is not set +# CONFIG_SUNXI_GPIO_KEY is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +CONFIG_TOUCHSCREEN_GT82X=m +# CONFIG_TOUCHSCREEN_SUN6I_TS is not set +CONFIG_TOUCHSCREEN_FT5X_TS=m +CONFIG_TOUCHSCREEN_GT9XX_TS=m +CONFIG_TOUCHSCREEN_GT9XXF_TS=m +CONFIG_TOUCHSCREEN_GSLX680=m +CONFIG_TOUCHSCREEN_GSLX680NEW=m +CONFIG_TOUCHSCREEN_AW5X06_TS=m +CONFIG_TOUCHSCREEN_GT818_TS=m +CONFIG_TOUCHSCREEN_TU_TS=m +CONFIG_TOUCHSCREEN_ICN83XX_TS=m +CONFIG_INPUT_MISC=y +# CONFIG_E_COMPASS_L3M303D is not set +# CONFIG_E_COMPASS_FXOS8700 is not set +# CONFIG_E_COMPASS_AKM8963 is not set +# CONFIG_GYR_L3GD20 is not set +# CONFIG_GYR_BMG160 is not set +CONFIG_INPUT_LTR501ALS=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_CMA3000 is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +CONFIG_SERIAL_SUNXI=y +CONFIG_SERIAL_SUNXI_CONSOLE=y +# CONFIG_SERIAL_DEBUG is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_RAMOOPS is not set +# CONFIG_SUNXI_D7S is not set +CONFIG_SUNXI_CMATESET=y +# CONFIG_SUNXI_ARISC_TEST is not set +# CONFIG_SUNXI_MODULE is not set +# CONFIG_SUNXI_TIMER_TEST is not set +# CONFIG_SUNXI_DMA_TEST is not set +CONFIG_SUNXI_SCR=m +CONFIG_SUNXI_DI=m +CONFIG_SUNXI_SOC_INFO=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_SUNXI=y +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_SUNXI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUNXI_DEBUG is not set +# CONFIG_SUNXI_PINCTRL_TEST is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +CONFIG_GPIO_SUNXI=m +CONFIG_W1=m +CONFIG_W1_SUNXI=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2408 is not set +# CONFIG_W1_SLAVE_DS2423 is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_KIONIX is not set +# CONFIG_SENSORS_MMA7660 is not set +# CONFIG_SENSORS_MMA865x is not set +# CONFIG_SENSORS_MMA8452 is not set +# CONFIG_SENSORS_AFA750 is not set +# CONFIG_SENSORS_BMA250 is not set +# CONFIG_SENSORS_LIS3DH_ACC is not set +# CONFIG_SENSORS_LIS3DE_ACC is not set +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set + +# +# INA219 drivers +# +# CONFIG_SENSORS_INA219 is not set +# CONFIG_SENSORS_DUMMY_ACC is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_FAIR_SHARE is not set +CONFIG_STEP_WISE=y +# CONFIG_USER_SPACE is not set +# CONFIG_SUNXI_THERMAL_DYNAMIC is not set +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_BUDGET_THERMAL=y +CONFIG_SUNXI_THERMAL=y +CONFIG_SUNXI_BUDGET_COOLING=y +# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_SUNXI_WDT=m + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_AC100 is not set +# CONFIG_MFD_AC200 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_REGULATOR is not set +CONFIG_PWM=y +CONFIG_PWM_SUNXI=m +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_MAP=y +# CONFIG_IR_NEC_DECODER is not set +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_RC5_SZ_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_LIRC_CODEC is not set +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_CUSTOMISE=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +# CONFIG_VIDEO_IR_I2C is not set + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_AK881X is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SR030PC30 is not set + +# +# Flash devices +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_TIMBERDALE is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_VIDEO_SUNXI_VFE=m +CONFIG_CSI_VFE=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +CONFIG_AW_TSC=y +# CONFIG_RADIO_ADAPTERS is not set +CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_UDL is not set +CONFIG_ION=y +CONFIG_ION_SUNXI=y +CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# + +# +# Video support for sunxi +# +CONFIG_FB_CONSOLE_SUNXI=y +CONFIG_DISP2_SUNXI=y +CONFIG_HDMI_DISP2_SUNXI=y +CONFIG_TV_DISP2_SUNXI=m +# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set +CONFIG_DISP2_SUNXI_DEBUG=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y +CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y +CONFIG_SND_SUN8IW7_SNDCODEC=y +# CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE is not set +# CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE is not set +CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y +CONFIG_SND_SUN8IW7_HDMIPCM=y +CONFIG_SND_SUNXI_SOC_SPDIF=m +# CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE is not set +# CONFIG_SND_SUN8IW7_AUDIOHUB is not set +# CONFIG_SND_SUNXI_SOC_SUPPORT_AUDIO_RAW is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_UHID=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_REMOTE_WAKEUP is not set +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +CONFIG_HID_PRODIKEYS=y +# CONFIG_HID_CYPRESS is not set +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EMS_FF=y +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_EZKEY is not set +CONFIG_HID_HOLTEK=y +# CONFIG_HOLTEK_FF is not set +CONFIG_HID_KEYTOUCH=y +# CONFIG_HID_KYE is not set +CONFIG_HID_UCLOGIC=y +CONFIG_HID_WALTOP=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LCPOWER=y +CONFIG_HID_LOGITECH=y +# CONFIG_HID_LOGITECH_DJ is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +# CONFIG_LOGIWHEELS_FF is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +CONFIG_HID_PRIMAX=y +CONFIG_HID_ROCCAT=y +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SPEEDLINK=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +# CONFIG_HID_TIVO is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set +CONFIG_HID_ZYDACRON=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_SUNXI is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_SUNXI_HCD=y +CONFIG_USB_SUNXI_HCD0=y +CONFIG_USB_SUNXI_HCI=y +CONFIG_USB_SUNXI_EHCI0=y +CONFIG_USB_SUNXI_EHCI1=y +CONFIG_USB_SUNXI_OHCI0=y +CONFIG_USB_SUNXI_OHCI1=y +CONFIG_USB_SUNXI_EHCI2=y +CONFIG_USB_SUNXI_OHCI2=y +CONFIG_USB_SUNXI_EHCI3=y +CONFIG_USB_SUNXI_OHCI3=y +CONFIG_USB_SUNXI_HSIC=y +# CONFIG_SW_USB_3G is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_SUNXI_UDC0=y +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_SUNXI_USB=y +CONFIG_USB_SUNXI_USB_MANAGER=y +# CONFIG_USB_SUNXI_USB0_NULL is not set +# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set +# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set +CONFIG_USB_SUNXI_USB0_OTG=y +CONFIG_USB_SUNXI_USB_DEBUG=y +CONFIG_USB_SUNXI_HOST=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +# CONFIG_MMC_CLKGATE is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_DW is not set +CONFIG_MMC_SUNXI=y +# CONFIG_MMC_DEBUG_SUNXI is not set +CONFIG_MMC_PRE_DBGLVL_SUNXI=0 +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_SUNXI_LEDS=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_OT200 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SUNXI=y +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_DW_DMAC is not set +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +CONFIG_SUNXI_DMA=y +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y +CONFIG_COMMON_CLK_DEBUG=y + +# +# SUNXI Clock Configuration +# +CONFIG_SUNXI_CLK_DEFAULT_INIT=y +CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y +CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 +CONFIG_AHB1_CLK_DFT_VALUE=200000000 +CONFIG_APB1_CLK_DFT_VALUE=100000000 + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_MMIO=y +CONFIG_SUNXI_TIMER=y +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_DRAM_FREQ=y +# CONFIG_DRAM_FREQ_BSP_TEST is not set +# CONFIG_GATOR_PERF is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=y +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFS_FSCACHE is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_FAULT_INJECTION=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_FSCACHE is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=20 +CONFIG_RCU_CPU_STALL_VERBOSE=y +CONFIG_RCU_CPU_STALL_INFO=y +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_ASYNC_RAID6_TEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +# CONFIG_TEST_KSTRTOX is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_RODATA is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_SUNXI_UART0=y +# CONFIG_DEBUG_SUNXI_UART1 is not set +# CONFIG_DEBUG_SUNXI_UART2 is not set +# CONFIG_DEBUG_LL_UART_NONE is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +CONFIG_EARLY_PRINTK=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_TRUSTED_LITTLE_KERNEL is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_SUNXI=m +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_AVERAGE=y +# CONFIG_CORDIC is not set diff --git a/linux-3.4/.gitignore b/linux-3.4/.gitignore deleted file mode 100644 index 45690eb5..00000000 --- a/linux-3.4/.gitignore +++ /dev/null @@ -1,107 +0,0 @@ -# -# NOTE! Don't add files that are generated in specific -# subdirectories here. Add them in the ".gitignore" file -# in that subdirectory instead. -# -# NOTE! Please use 'git ls-files -i --exclude-standard' -# command after changing this file, to see if there are -# any tracked files which get ignored after the change. -# -# Normal rules -# -.* -*.o -*.o.* -*.a -*.s -*.ko -*.so -*.so.dbg -*.mod.c -*.i -*.lst -*.symtypes -*.order -*.map -modules.builtin -Module.symvers -Module.markers -*.elf -*.bin -*.gz -*.bz2 -*.lzma -*.xz -*.lzo -*.patch -*.gcno -standby.code -resume1.code - -# -# Gcov files -# -*.gcda -*.gcno -*.gcov - -# -# Top-level generic files -# -/tags -/TAGS -/linux -/vmlinux -/vmlinuz -/System.map -/Module.markers -/Module.symvers - -# -# Debian directory (make deb-pkg) -# -/debian/ - -# -# git files that we don't want to ignore even it they are dot-files -# -!.gitignore -!.mailmap - -# -# Generated include files -# -include/config -include/linux/version.h -include/generated -arch/*/include/generated - -# stgit generated dirs -patches-* - -# quilt's files -patches -series - -# cscope files -cscope.* -ncscope.* - -# gnu global files -GPATH -GRTAGS -GSYMS -GTAGS - -*.orig -*~ -\#*# - -# lichee ingnore files -skel/ -output/ -bImage -*.swp -rootfs.cpio.gz -drivers/arisc/binary/arisc -modules/eurasia_km/eurasiacon/binary2_sunxi_android_release/ From 44013b36d2003fdcdc779ae4678a8dd37abf61de Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 9 Aug 2017 01:55:54 -0300 Subject: [PATCH 20/26] update rtl8192cu driver --- extra_modules/rtl8192cu-fixes/Makefile | 37 +- extra_modules/rtl8192cu-fixes/README.md | 10 +- .../blacklist-native-rtl8192.conf | 2 + .../rtl8192cu-fixes/core/rtw_br_ext.c | 1 + .../rtl8192cu-fixes/include/ieee80211.h | 6 +- .../rtl8192cu-fixes/include/osdep_service.h | 4 + extra_modules/rtl8192cu-fixes/installer.sh | 2 - .../os_dep/linux/ioctl_cfg80211.c | 32 + .../rtl8192cu-fixes/os_dep/linux/os_intfs.c | 6 + .../rtl8192cu-fixes/os_dep/linux/usb_intf.c | 3 +- linux-3.4/.config | 3333 ----------------- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 2 +- 12 files changed, 76 insertions(+), 3362 deletions(-) delete mode 100644 extra_modules/rtl8192cu-fixes/installer.sh delete mode 100644 linux-3.4/.config diff --git a/extra_modules/rtl8192cu-fixes/Makefile b/extra_modules/rtl8192cu-fixes/Makefile index 661e7aa0..5bc6ba21 100644 --- a/extra_modules/rtl8192cu-fixes/Makefile +++ b/extra_modules/rtl8192cu-fixes/Makefile @@ -68,9 +68,9 @@ CONFIG_PLATFORM_TI_DM365 = n CONFIG_PLATFORM_MN10300 = n CONFIG_PLATFORM_MSTAR_TITANIA12 = n CONFIG_PLATFORM_MSTAR_A3 = n +CONFIG_PLATFORM_ARM_SUN8I = y CONFIG_PLATFORM_ARM_SUNxI = n CONFIG_PLATFORM_ARM_SUN6I = n -CONFIG_PLATFORM_ARM_SUN8I = y CONFIG_DRVEXT_MODULE = n @@ -510,30 +510,12 @@ KVER := 3.0.8 #KSRC:= ../lichee/linux-3.0/ endif -ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y) -EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN6I -EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX -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 -ARCH := arm -CROSS_COMPILE := arm-none-linux-gnueabi- -KVER := 3.3.0 -#KSRC:= ../lichee/linux-3.3/ -endif - ifeq ($(CONFIG_PLATFORM_ARM_SUN8I), y) EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN8I EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT EXTRA_CFLAGS += -DCONFIG_PLATFORM_OPS -EXTRA_CFLAGS += -DCONFIG_LOAD_PHY_PARA_FROM_FILE -# sobe 2 wlans -EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_P2P_IPS @@ -543,6 +525,21 @@ KVER := 3.4 KSRC:= ../linux-3.4/ endif +ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y) +EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN +EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN6I +EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX +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 +ARCH := arm +CROSS_COMPILE := arm-none-linux-gnueabi- +KVER := 3.3.0 +#KSRC:= ../lichee/linux-3.3/ +endif + ifneq ($(USER_MODULE_NAME),) MODULE_NAME := $(USER_MODULE_NAME) endif @@ -600,7 +597,7 @@ export CONFIG_RTL8192CU = m all: modules modules: - $(MAKE) -j $(shell nproc) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules + $(MAKE) -j $(shell nproc) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules strip: $(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded diff --git a/extra_modules/rtl8192cu-fixes/README.md b/extra_modules/rtl8192cu-fixes/README.md index c484059b..a2d5a78d 100644 --- a/extra_modules/rtl8192cu-fixes/README.md +++ b/extra_modules/rtl8192cu-fixes/README.md @@ -4,8 +4,14 @@ Compatibility ============= These devices are known to work with this driver: -- Belkin N300 -- TP-Link TL-WN823N +- ASUSTek USB-N13 **rev. B1** (0b05:17ab) +- Belkin N300 (050d:2103) +- D-Link DWA-121 802.11n Wireless N 150 Pico Adapter [RTL8188CUS] +- Edimax EW-7811Un (7392:7811) +- Kootek KT-RPWF (0bda:8176) +- TP-Link TL-WN821N**v4** (0bda:8178) +- TP-Link TL-WN822N (0bda:8178) +- TP-Link TL-WN823N (only models that use the rtl8192cu chip) - TRENDnet TEW-648UBM N150 These devices are known not to be supported: diff --git a/extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf b/extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf index 73bf61fc..507744e7 100644 --- a/extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf +++ b/extra_modules/rtl8192cu-fixes/blacklist-native-rtl8192.conf @@ -4,3 +4,5 @@ install rtl8192cu /bin/false install rtl8192c_common /bin/false install rtlwifi /bin/false +## There is also a new mainline driver starting with kernel v4.4 +install rtl8xxxu /bin/false diff --git a/extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c b/extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c index 6bb924e0..2f84a38e 100755 --- a/extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c +++ b/extra_modules/rtl8192cu-fixes/core/rtw_br_ext.c @@ -51,6 +51,7 @@ #include #include #include +#include #endif #endif diff --git a/extra_modules/rtl8192cu-fixes/include/ieee80211.h b/extra_modules/rtl8192cu-fixes/include/ieee80211.h index e283a5f2..d07bdb80 100755 --- a/extra_modules/rtl8192cu-fixes/include/ieee80211.h +++ b/extra_modules/rtl8192cu-fixes/include/ieee80211.h @@ -1194,18 +1194,18 @@ enum ieee80211_state { (((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ (((Addr[5]) & 0xff) == 0xff)) #else -extern __inline int is_multicast_mac_addr(const u8 *addr) +static __inline int is_multicast_mac_addr(const u8 *addr) { return ((addr[0] != 0xff) && (0x01 & addr[0])); } -extern __inline int is_broadcast_mac_addr(const u8 *addr) +static __inline int is_broadcast_mac_addr(const u8 *addr) { return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); } -extern __inline int is_zero_mac_addr(const u8 *addr) +static __inline int is_zero_mac_addr(const u8 *addr) { return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); diff --git a/extra_modules/rtl8192cu-fixes/include/osdep_service.h b/extra_modules/rtl8192cu-fixes/include/osdep_service.h index c5c465e7..579fe4f5 100755 --- a/extra_modules/rtl8192cu-fixes/include/osdep_service.h +++ b/extra_modules/rtl8192cu-fixes/include/osdep_service.h @@ -20,6 +20,10 @@ #ifndef __OSDEP_SERVICE_H_ #define __OSDEP_SERVICE_H_ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) +#include +#endif #include #include //#include diff --git a/extra_modules/rtl8192cu-fixes/installer.sh b/extra_modules/rtl8192cu-fixes/installer.sh deleted file mode 100644 index 410baa95..00000000 --- a/extra_modules/rtl8192cu-fixes/installer.sh +++ /dev/null @@ -1,2 +0,0 @@ -install -p -m 644 8192cu.ko /lib/modules/$(uname -r)/kernel/drivers/net/wireless/ -depmod -a $(uname -r) diff --git a/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c index 5013d9dd..8c8457d9 100755 --- a/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c +++ b/extra_modules/rtl8192cu-fixes/os_dep/linux/ioctl_cfg80211.c @@ -634,6 +634,19 @@ void rtw_cfg80211_indicate_connect(_adapter *padapter) #endif DBG_871X("%s call cfg80211_roamed\n", __FUNCTION__); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + { + struct cfg80211_roam_info roam_info = { + .channel = notify_channel, + .bssid = cur_network->network.MacAddress, + .req_ie = pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2, + .req_ie_len = pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2, + .resp_ie = pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6, + .resp_ie_len = pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6, + }; + cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC); + } + #else cfg80211_roamed(padapter->pnetdev #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE) , notify_channel @@ -644,6 +657,7 @@ void rtw_cfg80211_indicate_connect(_adapter *padapter) , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6 , GFP_ATOMIC); + #endif } else #endif @@ -1639,10 +1653,17 @@ enum nl80211_iftype { NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 }; */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +static int cfg80211_rtw_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + struct vif_params *params) +#else static int cfg80211_rtw_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) +#endif { enum nl80211_iftype old_type; NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ; @@ -1789,7 +1810,14 @@ void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool abor } else { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) + struct cfg80211_scan_info info = { + .aborted = aborted + }; + cfg80211_scan_done(pwdev_priv->scan_request, &info); +#else cfg80211_scan_done(pwdev_priv->scan_request, aborted); +#endif } pwdev_priv->scan_request = NULL; @@ -3482,7 +3510,11 @@ static int #else char *name, #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) + enum nl80211_iftype type, struct vif_params *params) + #else enum nl80211_iftype type, u32 *flags, struct vif_params *params) + #endif { int ret = 0; struct net_device* ndev = NULL; diff --git a/extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c index 3a3cf913..87901aa7 100755 --- a/extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c +++ b/extra_modules/rtl8192cu-fixes/os_dep/linux/os_intfs.c @@ -949,7 +949,13 @@ unsigned int rtw_classify8021d(struct sk_buff *skb) return dscp >> 5; } +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,14,0)) +static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, + select_queue_fallback_t fallback) +#else static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb) +#endif { _adapter *padapter = rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; diff --git a/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c b/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c index 47e095c1..47f95131 100755 --- a/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c +++ b/extra_modules/rtl8192cu-fixes/os_dep/linux/usb_intf.c @@ -96,6 +96,7 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf); {USB_DEVICE(0x2019, 0xED17)},/* PCI - Edimax */ \ {USB_DEVICE(0x0DF6, 0x0052)},/* Sitecom - Edimax */ \ {USB_DEVICE(0x7392, 0x7811)},/* Edimax - Edimax */ \ + {USB_DEVICE(0x07B8, 0x8188)},/* Abocom - Abocom */ \ {USB_DEVICE(0x07B8, 0x8189)},/* Abocom - Abocom */ \ {USB_DEVICE(0x0EB0, 0x9071)},/* NO Brand - Etop */ \ {USB_DEVICE(0x06F8, 0xE033)},/* Hercules - Edimax */ \ @@ -120,7 +121,6 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf); {USB_DEVICE(0x0B05, 0x17BA)}, /* ASUS - Edimax */ \ {USB_DEVICE(0x0BDA, 0x1E1E)}, /* Intel - - */ \ {USB_DEVICE(0x04BB, 0x094c)}, /* I-O DATA - Edimax */ \ - {USB_DEVICE(0X0BDA, 0x8176)}, /* TP-Link - TL-WN723N */ \ /****** 8188CTV ********/ \ {USB_DEVICE(0xCDAB, 0x8011)}, /* - - compare */ \ {USB_DEVICE(0x0BDA, 0x0A8A)}, /* Sony - Foxconn */ \ @@ -151,6 +151,7 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf); {USB_DEVICE(0x4855, 0x0091)},/* - Feixun */ \ {USB_DEVICE(0x050D, 0x2102)},/* Belkin - Sercomm */ \ {USB_DEVICE(0x050D, 0x2103)},/* Belkin - Edimax */ \ + {USB_DEVICE(0x050D, 0x21F2)},/* Belkin - Edimax */ \ {USB_DEVICE(0x20F4, 0x624D)},/* TRENDnet */ \ {USB_DEVICE(0x0DF6, 0x0061)},/* Sitecom - Edimax */ \ {USB_DEVICE(0x0B05, 0x17AB)},/* ASUS - Edimax */ \ diff --git a/linux-3.4/.config b/linux-3.4/.config deleted file mode 100644 index 8a48129b..00000000 --- a/linux-3.4/.config +++ /dev/null @@ -1,3333 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/arm 3.4.39-02-lobo Kernel Configuration -# -CONFIG_ARM=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_USES_GETTIMEOFFSET is not set -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_KTIME_SCALAR=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_LOCKBREAK=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_ARCH_HAS_CPUFREQ=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_NEED_MACH_IO_H=y -CONFIG_NEED_MACH_MEMORY_H=y -CONFIG_GENERIC_BUG=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_XZ is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_DEFAULT_HOSTNAME="sun8i" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_FHANDLE=y -# CONFIG_TASKSTATS is not set -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=y -# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_IRQ_DOMAIN=y -# CONFIG_IRQ_DOMAIN_DEBUG is not set - -# -# RCU Subsystem -# -CONFIG_TREE_PREEMPT_RCU=y -CONFIG_PREEMPT_RCU=y -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_RCU_BOOST is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y -CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_CFS_BANDWIDTH is not set -CONFIG_RT_GROUP_SCHED=y -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -# CONFIG_CHECKPOINT_RESTORE is not set -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="output/rootfs.cpio.gz" -CONFIG_INITRAMFS_ROOT_UID=0 -CONFIG_INITRAMFS_ROOT_GID=0 -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y -# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_PANIC_TIMEOUT=5 -CONFIG_EXPERT=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_COMPAT_BRK=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_JUMP_LABEL=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_USE_GENERIC_SMP_HELPERS=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_STOP_MACHINE=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_DEV_THROTTLING is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -CONFIG_ACORN_PARTITION=y -# CONFIG_ACORN_PARTITION_CUMANA is not set -# CONFIG_ACORN_PARTITION_EESOX is not set -CONFIG_ACORN_PARTITION_ICS=y -# CONFIG_ACORN_PARTITION_ADFS is not set -# CONFIG_ACORN_PARTITION_POWERTEC is not set -CONFIG_ACORN_PARTITION_RISCIX=y -CONFIG_OSF_PARTITION=y -CONFIG_AMIGA_PARTITION=y -CONFIG_ATARI_PARTITION=y -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -CONFIG_LDM_PARTITION=y -# CONFIG_LDM_DEBUG is not set -CONFIG_SGI_PARTITION=y -CONFIG_ULTRIX_PARTITION=y -CONFIG_SUN_PARTITION=y -CONFIG_KARMA_PARTITION=y -CONFIG_EFI_PARTITION=y -CONFIG_SYSV68_PARTITION=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_CFQ_GROUP_IOSCHED is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_UNINLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_UNLOCK is not set -# CONFIG_INLINE_READ_UNLOCK_BH is not set -# CONFIG_INLINE_READ_UNLOCK_IRQ is not set -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_UNLOCK is not set -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -CONFIG_ARCH_SUNXI=y -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_HIGHBANK is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_PRIMA2 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_PICOXCELL is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P64X0 is not set -# CONFIG_ARCH_S5PC100 is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_ARCH_ZYNQ is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set - -# -# System MMU -# -CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 -CONFIG_ARCH_SUN8I=y -# CONFIG_ARCH_SUN9I is not set -# CONFIG_ARCH_SUN8IW1 is not set -# CONFIG_ARCH_SUN8IW3 is not set -# CONFIG_ARCH_SUN8IW5 is not set -# CONFIG_ARCH_SUN8IW6 is not set -CONFIG_ARCH_SUN8IW7=y -# CONFIG_ARCH_SUN8IW8 is not set -# CONFIG_ARCH_SUN8IW9 is not set -CONFIG_ARCH_SUN8IW7P1=y -# CONFIG_FPGA_V4_PLATFORM is not set -# CONFIG_FPGA_V7_PLATFORM is not set -CONFIG_EVB_PLATFORM=y - -# -# Power management -# - -# -# Common Features Selection -# - -# -# Boot Options -# -# CONFIG_SUNXI_TRUSTZONE is not set -CONFIG_HOMLET_PLATFORM=y -# CONFIG_SUNXI_BOOTUP_EXTEND is not set -CONFIG_SUNXI_OOPS_HOOK=y - -# -# Processor Type -# -CONFIG_CPU_V7=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_SWP_EMULATE=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARM_NR_BANKS=8 -CONFIG_CPU_HAS_PMU=y -CONFIG_MULTI_IRQ_HANDLER=y -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_742230 is not set -# CONFIG_ARM_ERRATA_742231 is not set -# CONFIG_ARM_ERRATA_720789 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_751472 is not set -# CONFIG_ARM_ERRATA_754322 is not set -# CONFIG_ARM_ERRATA_754327 is not set -# CONFIG_ARM_ERRATA_764369 is not set -# CONFIG_ARM_ERRATA_775420 is not set -CONFIG_ARM_GIC=y -# CONFIG_FIQ_DEBUGGER is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_HAVE_SMP=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_ARM_CPU_TOPOLOGY=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y -# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set -CONFIG_HAVE_ARM_SCU=y -CONFIG_ARM_ARCH_TIMER=y -# CONFIG_MCPM is not set -# CONFIG_BIG_LITTLE is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_NR_CPUS=4 -CONFIG_HOTPLUG_CPU=y -CONFIG_ARCH_NR_GPIO=2048 -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -CONFIG_HZ=100 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HW_PERF_EVENTS=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 -# CONFIG_CLEANCACHE is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_SECCOMP is not set -# CONFIG_CC_STACKPROTECTOR is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set -CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y - -# -# Boot options -# -# CONFIG_USE_OF is not set -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" -# CONFIG_CMDLINE_FROM_BOOTLOADER is not set -# CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE_FORCE=y -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_AUTO_ZRELADDR is not set - -# -# CPU Power Management -# - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_STAT_DETAILS=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_INTERACTIVE=y -# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y - -# -# ARM CPU frequency scaling drivers -# -CONFIG_ARM_SUNXI_CPUFREQ=y -# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set -# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set -# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set - -# -# CPU Idle -# -# CONFIG_CPU_IDLE is not set -# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -# CONFIG_WAKELOCK is not set -CONFIG_SCENELOCK=y -CONFIG_USER_SCENELOCK=y -# CONFIG_HIBERNATION is not set -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_WAKELOCKS is not set -CONFIG_PM_RUNTIME=y -CONFIG_PM=y -CONFIG_PM_DEBUG=y -CONFIG_PM_ADVANCED_DEBUG=y -# CONFIG_PM_TEST_SUSPEND is not set -CONFIG_CAN_PM_TRACE=y -CONFIG_APM_EMULATION=y -CONFIG_PM_CLK=y -CONFIG_CPU_PM=y -CONFIG_SUSPEND_TIME=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -# CONFIG_UNIX_DIAG is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_FIB_TRIE_STATS=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_CLASSID=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_LRO=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_INET_UDP_DIAG=m -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=y -CONFIG_TCP_CONG_HTCP=y -CONFIG_TCP_CONG_HSTCP=y -CONFIG_TCP_CONG_HYBLA=y -CONFIG_TCP_CONG_VEGAS=y -CONFIG_TCP_CONG_SCALABLE=y -CONFIG_TCP_CONG_LP=y -CONFIG_TCP_CONG_VENO=y -CONFIG_TCP_CONG_YEAH=y -CONFIG_TCP_CONG_ILLINOIS=y -# CONFIG_DEFAULT_BIC is not set -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_HYBLA is not set -# CONFIG_DEFAULT_VEGAS is not set -# CONFIG_DEFAULT_VENO is not set -# CONFIG_DEFAULT_WESTWOOD is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_SIT_6RD=y -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETLABEL=y -# CONFIG_ANDROID_PARANOID_NETWORK is not set -CONFIG_NET_ACTIVITY_STATS=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_ACCT=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_PROCFS=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMEOUT=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CT_PROTO_DCCP=m -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CT_PROTO_UDPLITE=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NETFILTER_TPROXY=m -CONFIG_NETFILTER_XTABLES=m - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_SET=m - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_AUDIT=m -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -CONFIG_NETFILTER_XT_TARGET_LED=m -CONFIG_NETFILTER_XT_TARGET_LOG=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ECN=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_NFACCT=m -CONFIG_NETFILTER_XT_MATCH_OSF=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_QUOTA2=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_IP_SET=m -CONFIG_IP_SET_MAX=256 -CONFIG_IP_SET_BITMAP_IP=m -CONFIG_IP_SET_BITMAP_IPMAC=m -CONFIG_IP_SET_BITMAP_PORT=m -CONFIG_IP_SET_HASH_IP=m -CONFIG_IP_SET_HASH_IPPORT=m -CONFIG_IP_SET_HASH_IPPORTIP=m -CONFIG_IP_SET_HASH_IPPORTNET=m -CONFIG_IP_SET_HASH_NET=m -CONFIG_IP_SET_HASH_NETPORT=m -CONFIG_IP_SET_HASH_NETIFACE=m -CONFIG_IP_SET_LIST_SET=m -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_RPFILTER=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_REJECT_SKERR=y -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_DCCP=m -CONFIG_NF_NAT_PROTO_GRE=m -CONFIG_NF_NAT_PROTO_UDPLITE=m -CONFIG_NF_NAT_PROTO_SCTP=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_RPFILTER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_REJECT_SKERR=y -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_IP6=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_ULOG=m -CONFIG_BRIDGE_EBT_NFLOG=m -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_L2TP=m -# CONFIG_L2TP_DEBUGFS is not set -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_STP=m -CONFIG_GARP=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=m -CONFIG_VLAN_8021Q_GVRP=y -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFB=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_CHOKE=m -CONFIG_NET_SCH_QFQ=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=y -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -# CONFIG_NET_ACT_SIMP is not set -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_CSUM=m -CONFIG_NET_CLS_IND=y -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -CONFIG_BATMAN_ADV=m -# CONFIG_BATMAN_ADV_DEBUG is not set -# CONFIG_OPENVSWITCH is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -CONFIG_NETPRIO_CGROUP=m -CONFIG_BQL=y -CONFIG_HAVE_BPF_JIT=y -CONFIG_BPF_JIT=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIBTUSB=m -# CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set -CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m -CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=y -# CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_REG_DEBUG is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set -CONFIG_MAC80211=m -CONFIG_MAC80211_HAS_RC=y -# CONFIG_MAC80211_RC_PID is not set -CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_MINSTREL_HT=y -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_WIMAX=m -CONFIG_WIMAX_DEBUG_LEVEL=8 -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set -# CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_NFC is not set - -# -# Device Drivers -# -CONFIG_SUNXI_ARISC=y - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=16 -CONFIG_CMA_RESERVE_BASE=0x43400000 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=0 -CONFIG_CMA_AREAS=7 -CONFIG_SYNC=y -CONFIG_SW_SYNC=y -# CONFIG_SW_SYNC_USER is not set - -# -# Bus devices -# -CONFIG_SUNXI_MBUS=y -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -CONFIG_BLK_DEV_CRYPTOLOOP=y - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -# CONFIG_BLK_DEV_RBD is not set - -# -# Misc devices -# -# CONFIG_SUNXI_VIBRATOR is not set -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_AD525X_DPOT is not set -# CONFIG_ATMEL_PWM is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_SENSORS_AK8975 is not set -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -CONFIG_UID_STAT=y -# CONFIG_BMP085 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_SUNXI_BROM_READ is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=m -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_IWMC3200TOP is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -# CONFIG_SW_3G_MODULE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -# CONFIG_MULTICORE_RAID456 is not set -CONFIG_MD_MULTIPATH=m -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=y -CONFIG_DM_SNAPSHOT=m -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_MIRROR is not set -CONFIG_DM_RAID=m -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_DM_VERITY is not set -CONFIG_NETDEVICES=y -CONFIG_NET_CORE=y -# CONFIG_BONDING is not set -# CONFIG_DUMMY is not set -# CONFIG_EQUALIZER is not set -CONFIG_MII=y -# CONFIG_IFB is not set -# CONFIG_NET_TEAM is not set -CONFIG_MACVLAN=m -# CONFIG_MACVTAP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_TUN=y -CONFIG_VETH=m - -# -# CAIF transport drivers -# -CONFIG_ETHERNET=y -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_CALXEDA_XGMAC is not set -CONFIG_NET_VENDOR_CHELSIO=y -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_DM9000 is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_INTEL is not set -CONFIG_NET_VENDOR_MARVELL=y -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_ETHOC is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -CONFIG_NET_VENDOR_SUNXI=y -CONFIG_SUNXI_GETH=y -CONFIG_GETH_SCRIPT_SYS=y -CONFIG_GETH_CLK_SYS=y -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_AMD_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MICREL_KS8995MA is not set -CONFIG_PPP=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=y -CONFIG_PPPOL2TP=y -CONFIG_PPPOLAC=y -CONFIG_PPPOPNS=y -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=y -# CONFIG_SLIP is not set -CONFIG_SLHC=y - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_QF9700=m -CONFIG_USB_NET_CDCETHER=m -# CONFIG_USB_NET_CDC_EEM is not set -# CONFIG_USB_NET_CDC_NCM is not set -# CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_SMSC75XX is not set -# CONFIG_USB_NET_SMSC95XX is not set -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -CONFIG_USB_NET_MCS7830=m -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_USB_NET_CX82310_ETH is not set -# CONFIG_USB_NET_KALMIA is not set -# CONFIG_USB_NET_QMI_WWAN is not set -# CONFIG_USB_NET_INT51X1 is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_USB_SIERRA_NET is not set -# CONFIG_USB_VL600 is not set -CONFIG_WLAN=y -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_AT76C50X_USB is not set -CONFIG_USB_ZD1201=m -# CONFIG_USB_NET_RNDIS_WLAN is not set -CONFIG_RTL8187=m -CONFIG_RTL8187_LEDS=y -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_WIFI_CONTROL_FUNC is not set -CONFIG_ATH_COMMON=m -# CONFIG_ATH_DEBUG is not set -CONFIG_ATH9K_HW=m -CONFIG_ATH9K_COMMON=m -CONFIG_ATH9K_BTCOEX_SUPPORT=y -CONFIG_ATH9K=m -# CONFIG_ATH9K_AHB is not set -# CONFIG_ATH9K_DEBUGFS is not set -# CONFIG_ATH9K_DFS_CERTIFIED is not set -CONFIG_ATH9K_RATE_CONTROL=y -CONFIG_ATH9K_HTC=m -# CONFIG_ATH9K_HTC_DEBUGFS is not set -# CONFIG_CARL9170 is not set -# CONFIG_ATH6KL is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -CONFIG_BCMDHD=m -CONFIG_BCMDHD_FW_PATH=y -CONFIG_BCMDHD_NVRAM_PATH=y -CONFIG_BCMDHD_CONFIG_PATH=y -CONFIG_BCMDHD_OOB=y -# CONFIG_BCMDHD_SDIO_IRQ is not set -# CONFIG_AP6210 is not set -# CONFIG_BRCMFMAC is not set -# CONFIG_HOSTAP is not set -# CONFIG_IWM is not set -# CONFIG_LIBERTAS is not set -# CONFIG_P54_COMMON is not set -CONFIG_RT2X00=m -# CONFIG_RT2500USB is not set -# CONFIG_RT73USB is not set -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT33XX=y -CONFIG_RT2800USB_RT35XX=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_UNKNOWN=y -CONFIG_RT2800_LIB=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTLWIFI_DEBUG=y -CONFIG_RTL8192C_COMMON=m -# CONFIG_WL1251 is not set -# CONFIG_WL12XX_MENU is not set -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_MWIFIEX is not set -CONFIG_RTL8188EU=m -CONFIG_RTL8189ES=m -CONFIG_RTL8189FS=m -CONFIG_RTL8723BS=m - -# -# WiMAX Wireless Broadband devices -# -# CONFIG_WIMAX_I2400M_USB is not set -# CONFIG_WIMAX_I2400M_SDIO is not set -# CONFIG_WAN is not set -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_POLLDEV=y -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_APMPOWER is not set -# CONFIG_INPUT_KEYRESET is not set -CONFIG_INPUT_SW_DEVICE=m - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_XTKBD is not set -CONFIG_KEYBOARD_SUNXI=y -CONFIG_IR_RX_SUNXI=m -# CONFIG_SUNXI_ANYIR_SUPPORT is not set -# CONFIG_IR_TX_SUNXI is not set -# CONFIG_SUNXI_GPIO_KEY is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_JOYSTICK=y -# CONFIG_JOYSTICK_ANALOG is not set -# CONFIG_JOYSTICK_A3D is not set -# CONFIG_JOYSTICK_ADI is not set -# CONFIG_JOYSTICK_COBRA is not set -# CONFIG_JOYSTICK_GF2K is not set -# CONFIG_JOYSTICK_GRIP is not set -# CONFIG_JOYSTICK_GRIP_MP is not set -# CONFIG_JOYSTICK_GUILLEMOT is not set -# CONFIG_JOYSTICK_INTERACT is not set -# CONFIG_JOYSTICK_SIDEWINDER is not set -# CONFIG_JOYSTICK_TMDC is not set -# CONFIG_JOYSTICK_IFORCE is not set -# CONFIG_JOYSTICK_WARRIOR is not set -# CONFIG_JOYSTICK_MAGELLAN is not set -# CONFIG_JOYSTICK_SPACEORB is not set -# CONFIG_JOYSTICK_SPACEBALL is not set -# CONFIG_JOYSTICK_STINGER is not set -# CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set -# CONFIG_JOYSTICK_AS5011 is not set -# CONFIG_JOYSTICK_JOYDUMP is not set -# CONFIG_JOYSTICK_XPAD is not set -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_ADS7846 is not set -# CONFIG_TOUCHSCREEN_AD7877 is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_ILI210X is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -CONFIG_TOUCHSCREEN_USB_EGALAX=y -CONFIG_TOUCHSCREEN_USB_PANJIT=y -CONFIG_TOUCHSCREEN_USB_3M=y -CONFIG_TOUCHSCREEN_USB_ITM=y -CONFIG_TOUCHSCREEN_USB_ETURBO=y -CONFIG_TOUCHSCREEN_USB_GUNZE=y -CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y -CONFIG_TOUCHSCREEN_USB_IRTOUCH=y -CONFIG_TOUCHSCREEN_USB_IDEALTEK=y -CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y -CONFIG_TOUCHSCREEN_USB_GOTOP=y -CONFIG_TOUCHSCREEN_USB_JASTEC=y -CONFIG_TOUCHSCREEN_USB_ELO=y -CONFIG_TOUCHSCREEN_USB_E2I=y -CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y -CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y -CONFIG_TOUCHSCREEN_USB_NEXIO=y -CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_TPS6507X is not set -CONFIG_TOUCHSCREEN_GT82X=m -# CONFIG_TOUCHSCREEN_SUN6I_TS is not set -CONFIG_TOUCHSCREEN_FT5X_TS=m -CONFIG_TOUCHSCREEN_GT9XX_TS=m -CONFIG_TOUCHSCREEN_GT9XXF_TS=m -CONFIG_TOUCHSCREEN_GSLX680=m -CONFIG_TOUCHSCREEN_GSLX680NEW=m -CONFIG_TOUCHSCREEN_AW5X06_TS=m -CONFIG_TOUCHSCREEN_GT818_TS=m -CONFIG_TOUCHSCREEN_TU_TS=m -CONFIG_TOUCHSCREEN_ICN83XX_TS=m -CONFIG_INPUT_MISC=y -# CONFIG_E_COMPASS_L3M303D is not set -# CONFIG_E_COMPASS_FXOS8700 is not set -# CONFIG_E_COMPASS_AKM8963 is not set -# CONFIG_GYR_L3GD20 is not set -# CONFIG_GYR_BMG160 is not set -CONFIG_INPUT_LTR501ALS=y -# CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_MPU3050 is not set -# CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_TILT_POLLED is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYCHORD is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_UINPUT=y -# CONFIG_INPUT_GPIO is not set -# CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -# CONFIG_INPUT_ADXL34X is not set -# CONFIG_INPUT_CMA3000 is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=m -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_UNIX98_PTYS=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=0 -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_CONSOLE_POLL=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -CONFIG_SERIAL_SUNXI=y -CONFIG_SERIAL_SUNXI_CONSOLE=y -# CONFIG_SERIAL_DEBUG is not set -# CONFIG_TTY_PRINTK is not set -# CONFIG_HVC_DCC is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_DCC_TTY is not set -# CONFIG_RAMOOPS is not set -# CONFIG_SUNXI_D7S is not set -CONFIG_SUNXI_CMATESET=y -# CONFIG_SUNXI_ARISC_TEST is not set -# CONFIG_SUNXI_MODULE is not set -# CONFIG_SUNXI_TIMER_TEST is not set -# CONFIG_SUNXI_DMA_TEST is not set -CONFIG_SUNXI_SCR=m -CONFIG_SUNXI_DI=m -CONFIG_SUNXI_SOC_INFO=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_MUX is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -CONFIG_I2C_SUNXI=y -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_PXA2XX_PCI is not set -CONFIG_SPI_SUNXI=y -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=y -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_HSI is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# - -# -# PTP clock support -# - -# -# Enable Device Drivers -> PPS to see the PTP clock options. -# -CONFIG_PINCTRL=y - -# -# Pin controllers -# -CONFIG_PINMUX=y -CONFIG_PINCONF=y -CONFIG_GENERIC_PINCONF=y -# CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_SUNXI=y -# CONFIG_PINCTRL_SUNXI_DEBUG is not set -# CONFIG_SUNXI_PINCTRL_TEST is not set -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO drivers: -# -# CONFIG_GPIO_GENERIC_PLATFORM is not set - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -CONFIG_GPIO_SUNXI=m -CONFIG_W1=m -CONFIG_W1_SUNXI=m - -# -# 1-wire Bus Masters -# -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS1WM is not set -CONFIG_W1_MASTER_GPIO=m - -# -# 1-wire Slaves -# -CONFIG_W1_SLAVE_THERM=m -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2408 is not set -# CONFIG_W1_SLAVE_DS2423 is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_BQ27000 is not set -# CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# CONFIG_SENSORS_KIONIX is not set -# CONFIG_SENSORS_MMA7660 is not set -# CONFIG_SENSORS_MMA865x is not set -# CONFIG_SENSORS_MMA8452 is not set -# CONFIG_SENSORS_AFA750 is not set -# CONFIG_SENSORS_BMA250 is not set -# CONFIG_SENSORS_LIS3DH_ACC is not set -# CONFIG_SENSORS_LIS3DE_ACC is not set -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_GPIO_FAN is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4151 is not set -# CONFIG_SENSORS_LTC4215 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LTC4261 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_MCP3021 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_PMBUS is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_SCH5636 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set - -# -# INA219 drivers -# -# CONFIG_SENSORS_INA219 is not set -# CONFIG_SENSORS_DUMMY_ACC is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_FAIR_SHARE is not set -CONFIG_STEP_WISE=y -# CONFIG_USER_SPACE is not set -# CONFIG_SUNXI_THERMAL_DYNAMIC is not set -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_BUDGET_THERMAL=y -CONFIG_SUNXI_THERMAL=y -CONFIG_SUNXI_BUDGET_COOLING=y -# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_CORE is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=m - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set -CONFIG_BCMA_POSSIBLE=y - -# -# Broadcom specific AMBA -# -# CONFIG_BCMA is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL6040_CORE is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_S5M_CORE is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_AC100 is not set -# CONFIG_MFD_AC200 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_REGULATOR is not set -CONFIG_PWM=y -CONFIG_PWM_SUNXI=m -CONFIG_MEDIA_SUPPORT=y - -# -# Multimedia core support -# -# CONFIG_MEDIA_CONTROLLER is not set -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=y - -# -# Multimedia drivers -# -CONFIG_RC_CORE=y -CONFIG_LIRC=y -CONFIG_RC_MAP=y -# CONFIG_IR_NEC_DECODER is not set -# CONFIG_IR_RC5_DECODER is not set -# CONFIG_IR_RC6_DECODER is not set -# CONFIG_IR_JVC_DECODER is not set -# CONFIG_IR_SONY_DECODER is not set -# CONFIG_IR_RC5_SZ_DECODER is not set -# CONFIG_IR_SANYO_DECODER is not set -# CONFIG_IR_MCE_KBD_DECODER is not set -# CONFIG_IR_LIRC_CODEC is not set -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_STREAMZAP is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_IR_GPIO_CIR is not set -# CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=y -CONFIG_MEDIA_TUNER_CUSTOMISE=y - -# -# Customize TV tuners -# -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_DMA_CONTIG=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set -# CONFIG_VIDEO_IR_I2C is not set - -# -# Encoders, decoders, sensors and other helper chips -# - -# -# Audio decoders, processors and mixers -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set - -# -# RDS decoders -# -# CONFIG_VIDEO_SAA6588 is not set - -# -# Video decoders -# -# CONFIG_VIDEO_ADV7180 is not set -# CONFIG_VIDEO_ADV7183 is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7191 is not set -# CONFIG_VIDEO_TVP514X is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_TVP7002 is not set -# CONFIG_VIDEO_VPX3220 is not set - -# -# Video and audio decoders -# -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_CX25840 is not set - -# -# MPEG video encoders -# -# CONFIG_VIDEO_CX2341X is not set - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_AK881X is not set - -# -# Camera sensor devices -# -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_VS6624 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_SR030PC30 is not set - -# -# Flash devices -# - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set - -# -# Miscelaneous helper chips -# -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_VIVI is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_GSPCA is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_HDPVR is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_CX231XX is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_PWC is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set -CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_VIDEO_TIMBERDALE is not set -# CONFIG_SOC_CAMERA is not set -CONFIG_VIDEO_SUNXI_VFE=m -CONFIG_CSI_VFE=m -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -CONFIG_AW_TSC=y -# CONFIG_RADIO_ADAPTERS is not set -CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y - -# -# Graphics support -# -CONFIG_DRM=m -# CONFIG_DRM_UDL is not set -CONFIG_ION=y -CONFIG_ION_SUNXI=y -CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_WMT_GE_ROPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# - -# -# Video support for sunxi -# -CONFIG_FB_CONSOLE_SUNXI=y -CONFIG_DISP2_SUNXI=y -CONFIG_HDMI_DISP2_SUNXI=y -CONFIG_TV_DISP2_SUNXI=m -# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set -CONFIG_DISP2_SUNXI_DEBUG=y -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_EXYNOS_VIDEO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set -# CONFIG_LOGO is not set -CONFIG_SOUND=y -# CONFIG_SOUND_OSS_CORE is not set -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=y -CONFIG_SND_JACK=y -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_RAWMIDI_SEQ is not set -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_ALOOP is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -CONFIG_SND_ARM=y -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=m -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_6FIRE is not set -CONFIG_SND_SOC=y -CONFIG_SND_SOC_DMAENGINE_PCM=y -CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y -CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y -CONFIG_SND_SUN8IW7_SNDCODEC=y -# CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE is not set -# CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE is not set -# CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE is not set -CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y -CONFIG_SND_SUN8IW7_HDMIPCM=y -CONFIG_SND_SUNXI_SOC_SPDIF=m -# CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE is not set -# CONFIG_SND_SUN8IW7_AUDIOHUB is not set -# CONFIG_SND_SUNXI_SOC_SUPPORT_AUDIO_RAW is not set -CONFIG_SND_SOC_I2C_AND_SPI=y -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -CONFIG_HIDRAW=y -CONFIG_UHID=y - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_REMOTE_WAKEUP is not set -# CONFIG_HID_PID is not set -CONFIG_USB_HIDDEV=y - -# -# Special HID drivers -# -CONFIG_HID_A4TECH=y -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -CONFIG_HID_PRODIKEYS=y -# CONFIG_HID_CYPRESS is not set -CONFIG_HID_DRAGONRISE=y -# CONFIG_DRAGONRISE_FF is not set -CONFIG_HID_EMS_FF=y -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_EZKEY is not set -CONFIG_HID_HOLTEK=y -# CONFIG_HOLTEK_FF is not set -CONFIG_HID_KEYTOUCH=y -# CONFIG_HID_KYE is not set -CONFIG_HID_UCLOGIC=y -CONFIG_HID_WALTOP=y -CONFIG_HID_GYRATION=y -CONFIG_HID_TWINHAN=y -# CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LCPOWER=y -CONFIG_HID_LOGITECH=y -# CONFIG_HID_LOGITECH_DJ is not set -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIWHEELS_FF is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -CONFIG_HID_MULTITOUCH=y -CONFIG_HID_NTRIG=y -CONFIG_HID_ORTEK=y -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -# CONFIG_HID_PICOLCD is not set -CONFIG_HID_PRIMAX=y -CONFIG_HID_ROCCAT=y -# CONFIG_HID_SAITEK is not set -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SPEEDLINK=y -CONFIG_HID_SUNPLUS=y -CONFIG_HID_GREENASIA=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_SMARTJOYPLUS=y -# CONFIG_SMARTJOYPLUS_FF is not set -# CONFIG_HID_TIVO is not set -CONFIG_HID_TOPSEED=y -CONFIG_HID_THRUSTMASTER=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WIIMOTE is not set -CONFIG_HID_ZEROPLUS=y -# CONFIG_ZEROPLUS_FF is not set -CONFIG_HID_ZYDACRON=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB_ARCH_HAS_XHCI=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_SUSPEND=y -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_SUNXI is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_XHCI_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_ISP1362_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PLATFORM is not set -CONFIG_USB_EHCI_HCD_PLATFORM=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_SUNXI_HCD=y -CONFIG_USB_SUNXI_HCD0=y -CONFIG_USB_SUNXI_HCI=y -CONFIG_USB_SUNXI_EHCI0=y -CONFIG_USB_SUNXI_EHCI1=y -CONFIG_USB_SUNXI_OHCI0=y -CONFIG_USB_SUNXI_OHCI1=y -CONFIG_USB_SUNXI_EHCI2=y -CONFIG_USB_SUNXI_OHCI2=y -CONFIG_USB_SUNXI_EHCI3=y -CONFIG_USB_SUNXI_OHCI3=y -CONFIG_USB_SUNXI_HSIC=y -# CONFIG_SW_USB_3G is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_RENESAS_USBHS is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=y -# CONFIG_USB_SERIAL_CONSOLE is not set -# CONFIG_USB_EZUSB is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -CONFIG_USB_SERIAL_CH341=m -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -CONFIG_USB_SERIAL_CP210X=m -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -CONFIG_USB_SERIAL_FTDI_SIO=m -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_F81232 is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_METRO is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MOTOROLA is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIEMENS_MPI is not set -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -CONFIG_USB_SERIAL_WWAN=y -CONFIG_USB_SERIAL_OPTION=y -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set -# CONFIG_USB_SERIAL_ZIO is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_DEBUG is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -# CONFIG_USB_FUSB300 is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_M66592 is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_DUMMY_HCD is not set -CONFIG_USB_SUNXI_UDC0=y -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_G_NCM is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -CONFIG_USB_G_ANDROID=y -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_G_MULTI is not set -# CONFIG_USB_G_HID is not set -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_WEBCAM is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ULPI is not set -# CONFIG_NOP_USB_XCEIV is not set -CONFIG_USB_SUNXI_USB=y -CONFIG_USB_SUNXI_USB_MANAGER=y -# CONFIG_USB_SUNXI_USB0_NULL is not set -# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set -# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set -CONFIG_USB_SUNXI_USB0_OTG=y -CONFIG_USB_SUNXI_USB_DEBUG=y -CONFIG_USB_SUNXI_HOST=y -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_CLKGATE is not set -# CONFIG_MMC_EMBEDDED_SDIO is not set -CONFIG_MMC_PARANOID_SD_INIT=y - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=16 -CONFIG_MMC_BLOCK_BOUNCE=y -# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_SDHCI_PXAV3 is not set -# CONFIG_MMC_SDHCI_PXAV2 is not set -# CONFIG_MMC_DW is not set -CONFIG_MMC_SUNXI=y -# CONFIG_MMC_DEBUG_SUNXI is not set -CONFIG_MMC_PRE_DBGLVL_SUNXI=0 -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -CONFIG_SUNXI_LEDS=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA9633 is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_RENESAS_TPU is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_OT200 is not set -CONFIG_LEDS_TRIGGERS=y - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=y -CONFIG_LEDS_TRIGGER_GPIO=m -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -# CONFIG_SWITCH is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_HCTOSYS is not set -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_SUNXI=y -CONFIG_DMADEVICES=y -# CONFIG_DMADEVICES_DEBUG is not set - -# -# DMA Devices -# -# CONFIG_DW_DMAC is not set -# CONFIG_TIMB_DMA is not set -CONFIG_DMA_ENGINE=y -CONFIG_DMA_VIRTUAL_CHANNELS=y - -# -# DMA Clients -# -# CONFIG_NET_DMA is not set -# CONFIG_ASYNC_TX_DMA is not set -CONFIG_SUNXI_DMA=y -# CONFIG_DMATEST is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# Virtio drivers -# -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_MMIO is not set - -# -# Microsoft Hyper-V guest support -# -# CONFIG_STAGING is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_COMMON_CLK=y - -# -# Common Clock Framework -# -# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set -CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y -CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y -CONFIG_COMMON_CLK_DEBUG=y - -# -# SUNXI Clock Configuration -# -CONFIG_SUNXI_CLK_DEFAULT_INIT=y -CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y -CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 -CONFIG_AHB1_CLK_DFT_VALUE=200000000 -CONFIG_APB1_CLK_DFT_VALUE=100000000 - -# -# Hardware Spinlock drivers -# -CONFIG_CLKSRC_MMIO=y -CONFIG_SUNXI_TIMER=y -# CONFIG_IOMMU_SUPPORT is not set - -# -# Remoteproc drivers (EXPERIMENTAL) -# - -# -# Rpmsg drivers (EXPERIMENTAL) -# -# CONFIG_VIRT_DRIVERS is not set -CONFIG_PM_DEVFREQ=y - -# -# DEVFREQ Governors -# -# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -CONFIG_DEVFREQ_GOV_USERSPACE=y - -# -# DEVFREQ Drivers -# -CONFIG_DEVFREQ_DRAM_FREQ=y -# CONFIG_DRAM_FREQ_BSP_TEST is not set -# CONFIG_GATOR_PERF is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT23=y -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_FANOTIFY=y -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=y -CONFIG_CUSE=y -CONFIG_GENERIC_ACL=y - -# -# Caches -# -CONFIG_FSCACHE=y -CONFIG_FSCACHE_STATS=y -# CONFIG_FSCACHE_HISTOGRAM is not set -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_OBJECT_LIST is not set -CONFIG_CACHEFILES=y -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_XATTR=y -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_LOGFS is not set -CONFIG_CRAMFS=y -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y -CONFIG_SQUASHFS_EMBEDDED=y -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_V4_1 is not set -# CONFIG_NFS_FSCACHE is not set -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFSD=y -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_FAULT_INJECTION=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -# CONFIG_SUNRPC_DEBUG is not set -# CONFIG_CEPH_FS is not set -CONFIG_CIFS=y -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_UPCALL is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_DFS_UPCALL is not set -# CONFIG_CIFS_FSCACHE is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -CONFIG_NLS_CODEPAGE_936=y -CONFIG_NLS_CODEPAGE_950=y -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y - -# -# Kernel hacking -# -CONFIG_PRINTK_TIME=y -CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOCKUP_DETECTOR=y -# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set -CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y -CONFIG_HARDLOCKUP_DETECTOR=y -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -CONFIG_FRAME_POINTER=y -CONFIG_BOOT_PRINTK_DELAY=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=20 -CONFIG_RCU_CPU_STALL_VERBOSE=y -CONFIG_RCU_CPU_STALL_INFO=y -# CONFIG_RCU_TRACE is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_LKDTM is not set -# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_TRACER_MAX_TRACE=y -CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_EVENT_POWER_TRACING_DEPRECATED=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING=y -CONFIG_GENERIC_TRACER=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -CONFIG_FUNCTION_TRACER=y -CONFIG_FUNCTION_GRAPH_TRACER=y -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -CONFIG_SCHED_TRACER=y -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -CONFIG_STACK_TRACER=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_DYNAMIC_FTRACE=y -CONFIG_FUNCTION_PROFILER=y -CONFIG_FTRACE_MCOUNT_RECORD=y -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_KGDB=y -CONFIG_KGDB_SERIAL_CONSOLE=y -# CONFIG_KGDB_TESTS is not set -CONFIG_KGDB_KDB=y -CONFIG_KDB_KEYBOARD=y -# CONFIG_TEST_KSTRTOX is not set -CONFIG_STRICT_DEVMEM=y -CONFIG_ARM_UNWIND=y -CONFIG_OLD_MCOUNT=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_RODATA is not set -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_SUNXI_UART0=y -# CONFIG_DEBUG_SUNXI_UART1 is not set -# CONFIG_DEBUG_SUNXI_UART2 is not set -# CONFIG_DEBUG_LL_UART_NONE is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -CONFIG_EARLY_PRINTK=y - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_TRUSTED_LITTLE_KERNEL is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=m -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_GHASH is not set -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC -CONFIG_CRYPTO_SHA256=y -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_SUNXI=m -# CONFIG_ASYMMETRIC_KEY_TYPE is not set -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_RAID6_PQ=m -CONFIG_BITREVERSE=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_IO=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -# CONFIG_CRC32_SELFTEST is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC32_SLICEBY4 is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_BIT is not set -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -# CONFIG_CRC8 is not set -CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_XZ_DEC=y -CONFIG_XZ_DEC_X86=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_NLATTR=y -CONFIG_AVERAGE=y -# CONFIG_CORDIC is not set diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index 3074a9ff..8a48129b 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="earlyprintk=ttyS0,115200 loglevel=1 initcall_debug=0 console=ttyS0,115200 console=tty0 fsck.mode=force fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y From 3af901cf57793f5e3680976f2164020a9569398d Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 9 Aug 2017 14:27:57 -0300 Subject: [PATCH 21/26] small fixes --- build/sun8iw7p1smp_lobo_defconfig | 53 +- build/sun8iw7p1smp_lobo_defconfig.old | 53 +- extra_modules/rtl8192cu-fixes/Makefile | 4 +- linux-3.4/.config.bak | 51 +- linux-3.4/ap6210_defconfig.patch | 17 - linux-3.4/ap6210_module.patch | 127005 --------------- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 53 +- linux-3.4/arch/arm/mach-sunxi/Makefile | 2 +- linux-3.4/drivers/cpufreq/sunxi-cpufreq.c | 6 + .../drivers/devfreq/dramfreq/sunxi-ddrfreq.c | 3 +- .../media/video/sunxi-vfe/device/gc2035.c | 4 +- .../video/sunxi-vfe/lib/isp_module_cfg.h | 2 +- .../media/video/sunxi-vfe/lib/lib_mipicsi2_v1 | Bin .../media/video/sunxi-vfe/lib/lib_mipicsi2_v2 | Bin .../drivers/media/video/sunxi-vfe/lib/libisp | Bin 371956 -> 607408 bytes linux-3.4/drivers/media/video/sunxi-vfe/vfe.c | 34 +- .../media/video/sunxi-vfe/vfe_subdev.c | 4 +- .../wireless/rtl8189fs/core/rtw_ieee80211.c | 2 +- .../thermal/sunxi-cpu-budget-cooling.c | 19 - linux-3.4/drivers/watchdog/sunxi_wdt.c | 4 +- 20 files changed, 207 insertions(+), 127109 deletions(-) delete mode 100644 linux-3.4/ap6210_defconfig.patch delete mode 100644 linux-3.4/ap6210_module.patch mode change 100755 => 100644 linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 mode change 100755 => 100644 linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 mode change 100755 => 100644 linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index 8a48129b..b7f3737c 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -692,7 +692,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -833,6 +832,40 @@ CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 +# +# IPVS transport protocol load balancing support +# +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +# CONFIG_IP_VS_PROTO_AH_ESP is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_AH is not set +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +# CONFIG_IP_VS_RR is not set +# CONFIG_IP_VS_WRR is not set +# CONFIG_IP_VS_LC is not set +# CONFIG_IP_VS_WLC is not set +# CONFIG_IP_VS_LBLC is not set +# CONFIG_IP_VS_LBLCR is not set +# CONFIG_IP_VS_DH is not set +# CONFIG_IP_VS_SH is not set +# CONFIG_IP_VS_SED is not set +# CONFIG_IP_VS_NQ is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +# CONFIG_IP_VS_NFCT is not set + # # IP: Netfilter Configuration # @@ -871,7 +904,6 @@ CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m @@ -898,7 +930,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1312,7 +1343,8 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPPOL2TP=y +# CONFIG_PPTP is not set +CONFIG_PPPOL2TP=m CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y @@ -1953,7 +1985,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=m +CONFIG_SUNXI_WDT=y # # USB-based Watchdog Cards @@ -2697,7 +2729,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_DEV_UIE_EMUL=y # CONFIG_RTC_DRV_TEST is not set # @@ -2955,6 +2987,7 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_V4_1 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFS_FSCACHE is not set # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y @@ -3238,7 +3271,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3320,9 +3353,9 @@ CONFIG_XZ_DEC_BCJ=y CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index 8a48129b..b7f3737c 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -692,7 +692,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -833,6 +832,40 @@ CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 +# +# IPVS transport protocol load balancing support +# +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +# CONFIG_IP_VS_PROTO_AH_ESP is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_AH is not set +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +# CONFIG_IP_VS_RR is not set +# CONFIG_IP_VS_WRR is not set +# CONFIG_IP_VS_LC is not set +# CONFIG_IP_VS_WLC is not set +# CONFIG_IP_VS_LBLC is not set +# CONFIG_IP_VS_LBLCR is not set +# CONFIG_IP_VS_DH is not set +# CONFIG_IP_VS_SH is not set +# CONFIG_IP_VS_SED is not set +# CONFIG_IP_VS_NQ is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +# CONFIG_IP_VS_NFCT is not set + # # IP: Netfilter Configuration # @@ -871,7 +904,6 @@ CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m @@ -898,7 +930,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1312,7 +1343,8 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPPOL2TP=y +# CONFIG_PPTP is not set +CONFIG_PPPOL2TP=m CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y @@ -1953,7 +1985,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=m +CONFIG_SUNXI_WDT=y # # USB-based Watchdog Cards @@ -2697,7 +2729,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_DEV_UIE_EMUL=y # CONFIG_RTC_DRV_TEST is not set # @@ -2955,6 +2987,7 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_V4_1 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFS_FSCACHE is not set # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y @@ -3238,7 +3271,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3320,9 +3353,9 @@ CONFIG_XZ_DEC_BCJ=y CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/extra_modules/rtl8192cu-fixes/Makefile b/extra_modules/rtl8192cu-fixes/Makefile index 5bc6ba21..3ad2300d 100644 --- a/extra_modules/rtl8192cu-fixes/Makefile +++ b/extra_modules/rtl8192cu-fixes/Makefile @@ -520,9 +520,9 @@ EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT EXTRA_CFLAGS += -DCONFIG_P2P_IPS ARCH := arm -CROSS_COMPILE := ../../brandy/gcc-linaro/bin/arm-linux-gnueabi- +CROSS_COMPILE := arm-linux-gnueabi- KVER := 3.4 -KSRC:= ../linux-3.4/ +KSRC:= ../../linux-3.4/ endif ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y) diff --git a/linux-3.4/.config.bak b/linux-3.4/.config.bak index 8a48129b..f973480b 100644 --- a/linux-3.4/.config.bak +++ b/linux-3.4/.config.bak @@ -692,7 +692,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -833,6 +832,40 @@ CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 +# +# IPVS transport protocol load balancing support +# +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +# CONFIG_IP_VS_PROTO_AH_ESP is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_AH is not set +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +# CONFIG_IP_VS_RR is not set +# CONFIG_IP_VS_WRR is not set +# CONFIG_IP_VS_LC is not set +# CONFIG_IP_VS_WLC is not set +# CONFIG_IP_VS_LBLC is not set +# CONFIG_IP_VS_LBLCR is not set +# CONFIG_IP_VS_DH is not set +# CONFIG_IP_VS_SH is not set +# CONFIG_IP_VS_SED is not set +# CONFIG_IP_VS_NQ is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +# CONFIG_IP_VS_NFCT is not set + # # IP: Netfilter Configuration # @@ -871,7 +904,6 @@ CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m @@ -898,7 +930,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1312,7 +1343,8 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPPOL2TP=y +# CONFIG_PPTP is not set +CONFIG_PPPOL2TP=m CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y @@ -1953,7 +1985,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=m +CONFIG_SUNXI_WDT=y # # USB-based Watchdog Cards @@ -2955,6 +2987,7 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_V4_1 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFS_FSCACHE is not set # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y @@ -3238,7 +3271,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3320,9 +3353,9 @@ CONFIG_XZ_DEC_BCJ=y CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/linux-3.4/ap6210_defconfig.patch b/linux-3.4/ap6210_defconfig.patch deleted file mode 100644 index 0898d76c..00000000 --- a/linux-3.4/ap6210_defconfig.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -uNr linux-sunxi/arch/arm/configs/sun7i_defconfig linux-sunxi-ap6210/arch/arm/configs/sun7i_defconfig ---- linux-sunxi-o/arch/arm/configs/sun7i_defconfig 2014-05-30 18:33:05.650561315 -0400 -+++ linux-sunxi-n/arch/arm/configs/sun7i_defconfig 2014-05-30 19:50:29.914561315 -0400 -@@ -539,7 +539,12 @@ - CONFIG_B43_PHY_N=y - CONFIG_B43_PHY_HT=y - CONFIG_B43LEGACY=m --CONFIG_BCMDHD=m -+# CONFIG_BCMDHD is not set -+CONFIG_AP6210=m -+CONFIG_AP6210_FW_PATH="/lib/firmware/ap6210/fw_bcmxxxx.bin" -+CONFIG_AP6210_NVRAM_PATH="/lib/firmware/ap6210/nvram_apxxxx.txt" -+CONFIG_AP6210_OOB=y -+# CONFIG_AP6210_SDIO_IRQ is not set - CONFIG_BRCMFMAC=m - CONFIG_BRCMFMAC_USB=y - CONFIG_HOSTAP=m diff --git a/linux-3.4/ap6210_module.patch b/linux-3.4/ap6210_module.patch deleted file mode 100644 index 81f6b9d7..00000000 --- a/linux-3.4/ap6210_module.patch +++ /dev/null @@ -1,127005 +0,0 @@ -diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig -index a17fd93..6afeab3 100644 ---- a/drivers/net/wireless/Kconfig -+++ b/drivers/net/wireless/Kconfig -@@ -278,6 +278,7 @@ source "drivers/net/wireless/ath/Kconfig" - source "drivers/net/wireless/b43/Kconfig" - source "drivers/net/wireless/b43legacy/Kconfig" - source "drivers/net/wireless/bcmdhd/Kconfig" -+source "drivers/net/wireless/ap6210/Kconfig" - source "drivers/net/wireless/brcm80211/Kconfig" - source "drivers/net/wireless/bcm4330/Kconfig" - source "drivers/net/wireless/hostap/Kconfig" -diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile -index 0db00ba..a970c43 100644 ---- a/drivers/net/wireless/Makefile -+++ b/drivers/net/wireless/Makefile -@@ -65,6 +65,7 @@ obj-$(CONFIG_IWM) += iwmc3200wifi/ - obj-$(CONFIG_MWIFIEX) += mwifiex/ - - obj-$(CONFIG_BCMDHD) += bcmdhd/ -+obj-$(CONFIG_AP6210) += ap6210/ - - obj-$(CONFIG_BRCMFMAC) += brcm80211/ - obj-$(CONFIG_BRCMSMAC) += brcm80211/ -diff --git a/drivers/net/wireless/ap6210/Kconfig b/drivers/net/wireless/ap6210/Kconfig -new file mode 100644 -index 0000000..9756ac7 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/Kconfig -@@ -0,0 +1,45 @@ -+config AP6210 -+ tristate "AMPAK AP6210 wireless/bluetooth module support" -+ depends on MMC -+ default n -+ ---help--- -+ This module adds support for the wireless and bluetooth -+ module of the CubieTruck. -+ -+config AP6210_FW_PATH -+ depends on AP6210 -+ string "Firmware path" -+ default "/system/vendor/modules/fw_bcmxxxx.bin" -+ ---help--- -+ Path to the firmware file. -+ -+config AP6210_NVRAM_PATH -+ depends on AP6210 -+ string "NVRAM path" -+ default "/system/vendor/modules/nvram_apxxxx.txt" -+ ---help--- -+ Path to the calibration file. -+ -+config AP6210_WEXT -+ bool "Enable WEXT support" -+ depends on AP6210 && CFG80211 = n -+ select WIRELESS_EXT -+ select WEXT_PRIV -+ help -+ Enables WEXT support -+ -+choice -+ depends on AP6210 -+ prompt "Interrupt type" -+config AP6210_OOB -+ depends on AP6210 -+ bool "Out-of-Band Interrupt" -+ ---help--- -+ Interrupt through WL_HOST_WAKE. -+config AP6210_SDIO_IRQ -+ depends on AP6210 -+ bool "In-Band Interrupt" -+ default y -+ ---help--- -+ Interrupt through SDIO DAT[1] -+endchoice -diff --git a/drivers/net/wireless/ap6210/Makefile b/drivers/net/wireless/ap6210/Makefile -new file mode 100644 -index 0000000..02c0b0f ---- /dev/null -+++ b/drivers/net/wireless/ap6210/Makefile -@@ -0,0 +1,65 @@ -+# ap6210 -+DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ -+ -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \ -+ -DDHDTHREAD -DDHD_DEBUG -DSDTEST -DBDC -DTOE \ -+ -DDHD_BCMEVENTS -DSHOW_EVENTS -DPROP_TXSTATUS -DBCMDBG \ -+ -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \ -+ -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ -+ -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \ -+ -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \ -+ -DDHD_USE_IDLECOUNT -DSET_RANDOM_MAC_SOFTAP -DVSDB \ -+ -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -DSDIO_CRC_ERROR_FIX \ -+ -DESCAN_RESULT_PATCH -DHT40_GO -DPASS_ARP_PACKET -DSUPPORT_PM2_ONLY \ -+ -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DAMPDU_HOSTREORDER \ -+ -DDISABLE_FW_ROAM_SUSPEND -DDISABLE_BUILTIN_ROAM \ -+ -DCUSTOM_SDIO_F2_BLKSIZE=128 -DWL_SDO -DWL_SUPPORT_BACKPORTED_KPATCHES\ -+ -Idrivers/net/wireless/ap6210 -Idrivers/net/wireless/ap6210/include -+ -+DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o \ -+ dhd_linux_sched.o dhd_sdio.o bcmwifi_channels.o bcmevent.o hndpmu.o \ -+ bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o \ -+ bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o \ -+ ap6210_gpio_wifi.o ap6210_gpio_bt.o -+ -+obj-$(CONFIG_AP6210) += ap6210.o -+ap6210-objs += $(DHDOFILES) -+ -+DHDOFILES += dhd_gpio.o -+DHDCFLAGS += -DCUSTOMER_HW -+#DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI -+ -+ifeq ($(CONFIG_AP6210_OOB),y) -+DHDCFLAGS += -DOOB_INTR_ONLY -DHW_OOB -DCUSTOMER_OOB -+else -+DHDCFLAGS += -DSDIO_ISR_THREAD -+endif -+ -+ifeq ($(CONFIG_AP6210_AG),y) -+ DHDCFLAGS += -DBAND_AG -+endif -+ -+ifneq ($(CONFIG_WIRELESS_EXT),) -+ap6210-objs += wl_iw.o -+DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW -+endif -+ifneq ($(CONFIG_CFG80211),) -+ap6210-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o dhd_cfg80211.o -+DHDCFLAGS += -DWL_CFG80211 -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF -+DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65 -+DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15 -+DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000 -+DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7 -+DHDCFLAGS += -fno-aggressive-loop-optimizations -+endif -+ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),) -+DHDCFLAGS += -DWL_SCHED_SCAN -+endif -+EXTRA_CFLAGS = $(DHDCFLAGS) -+ifeq ($(CONFIG_AP6210),m) -+EXTRA_LDFLAGS += --strip-debug -+endif -+ -+# GPIO Power Management Modules -+ -+#obj-$(CONFIG_AP6210) += ap6210_gpio_wifi.o -+#obj-$(CONFIG_AP6210) += ap6210_gpio_bt.o -diff --git a/drivers/net/wireless/ap6210/aiutils.c b/drivers/net/wireless/ap6210/aiutils.c -new file mode 100644 -index 0000000..bc116d7 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/aiutils.c -@@ -0,0 +1,873 @@ -+/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: aiutils.c 347614 2012-07-27 10:24:51Z $ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "siutils_priv.h" -+ -+#include -+ -+#define BCM47162_DMP() (0) -+#define BCM5357_DMP() (0) -+#define remap_coreid(sih, coreid) (coreid) -+#define remap_corerev(sih, corerev) (corerev) -+ -+/* EROM parsing */ -+ -+static uint32 -+get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match) -+{ -+ uint32 ent; -+ uint inv = 0, nom = 0; -+ -+ while (TRUE) { -+ ent = R_REG(si_osh(sih), *eromptr); -+ (*eromptr)++; -+ -+ if (mask == 0) -+ break; -+ -+ if ((ent & ER_VALID) == 0) { -+ inv++; -+ continue; -+ } -+ -+ if (ent == (ER_END | ER_VALID)) -+ break; -+ -+ if ((ent & mask) == match) -+ break; -+ -+ nom++; -+ } -+ -+ AP6210_DEBUG("%s: Returning ent 0x%08x\n", __FUNCTION__, ent); -+ if (inv + nom) { -+ AP6210_DEBUG(" after %d invalid and %d non-matching entries\n", inv, nom); -+ } -+ return ent; -+} -+ -+static uint32 -+get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh, -+ uint32 *sizel, uint32 *sizeh) -+{ -+ uint32 asd, sz, szd; -+ -+ asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); -+ if (((asd & ER_TAG1) != ER_ADD) || -+ (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || -+ ((asd & AD_ST_MASK) != st)) { -+ /* This is not what we want, "push" it back */ -+ (*eromptr)--; -+ return 0; -+ } -+ *addrl = asd & AD_ADDR_MASK; -+ if (asd & AD_AG32) -+ *addrh = get_erom_ent(sih, eromptr, 0, 0); -+ else -+ *addrh = 0; -+ *sizeh = 0; -+ sz = asd & AD_SZ_MASK; -+ if (sz == AD_SZ_SZD) { -+ szd = get_erom_ent(sih, eromptr, 0, 0); -+ *sizel = szd & SD_SZ_MASK; -+ if (szd & SD_SG32) -+ *sizeh = get_erom_ent(sih, eromptr, 0, 0); -+ } else -+ *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); -+ -+ AP6210_DEBUG(" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", -+ sp, ad, st, *sizeh, *sizel, *addrh, *addrl); -+ -+ return asd; -+} -+ -+static void -+ai_hwfixup(si_info_t *sii) -+{ -+} -+ -+ -+/* parse the enumeration rom to identify all cores */ -+void -+ai_scan(si_t *sih, void *regs, uint devid) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ chipcregs_t *cc = (chipcregs_t *)regs; -+ uint32 erombase, *eromptr, *eromlim; -+ -+ erombase = R_REG(sii->osh, &cc->eromptr); -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case SI_BUS: -+ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); -+ break; -+ -+ case PCI_BUS: -+ /* Set wrappers address */ -+ sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); -+ -+ /* Now point the window at the erom */ -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); -+ eromptr = regs; -+ break; -+ -+ case SPI_BUS: -+ case SDIO_BUS: -+ eromptr = (uint32 *)(uintptr)erombase; -+ break; -+ -+ case PCMCIA_BUS: -+ default: -+ AP6210_ERR("Don't know how to do AXI enumertion on bus %d\n", sih->bustype); -+ ASSERT(0); -+ return; -+ } -+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); -+ -+ AP6210_DEBUG("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", -+ regs, erombase, eromptr, eromlim); -+ while (eromptr < eromlim) { -+ uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; -+ uint32 mpd, asd, addrl, addrh, sizel, sizeh; -+ uint i, j, idx; -+ bool br; -+ -+ br = FALSE; -+ -+ /* Grok a component */ -+ cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); -+ if (cia == (ER_END | ER_VALID)) { -+ AP6210_DEBUG("Found END of erom after %d cores\n", sii->numcores); -+ ai_hwfixup(sii); -+ return; -+ } -+ -+ cib = get_erom_ent(sih, &eromptr, 0, 0); -+ -+ if ((cib & ER_TAG) != ER_CI) { -+ AP6210_ERR("CIA not followed by CIB\n"); -+ goto error; -+ } -+ -+ cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; -+ mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; -+ crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; -+ nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; -+ nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; -+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; -+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; -+ -+#ifdef BCMDBG_SI -+ AP6210_DEBUG("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " -+ "nsw = %d, nmp = %d & nsp = %d\n", -+ mfg, cid, crev, eromptr - 1, nmw, nsw, nmp, nsp); -+#else -+ BCM_REFERENCE(crev); -+#endif -+ -+ if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) -+ continue; -+ if ((nmw + nsw == 0)) { -+ /* A component which is not a core */ -+ if (cid == OOB_ROUTER_CORE_ID) { -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, -+ &addrl, &addrh, &sizel, &sizeh); -+ if (asd != 0) { -+ sii->oob_router = addrl; -+ } -+ } -+ if (cid != GMAC_COMMON_4706_CORE_ID) -+ continue; -+ } -+ -+ idx = sii->numcores; -+ -+ sii->cia[idx] = cia; -+ sii->cib[idx] = cib; -+ sii->coreid[idx] = remap_coreid(sih, cid); -+ -+ for (i = 0; i < nmp; i++) { -+ mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); -+ if ((mpd & ER_TAG) != ER_MP) { -+ AP6210_ERR("Not enough MP entries for component 0x%x\n", cid); -+ goto error; -+ } -+ AP6210_DEBUG(" Master port %d, mp: %d id: %d\n", i, -+ (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, -+ (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT); -+ } -+ -+ /* First Slave Address Descriptor should be port 0: -+ * the main register space for the core -+ */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); -+ if (asd == 0) { -+ do { -+ /* Try again to see if it is a bridge */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd != 0) -+ br = TRUE; -+ else { -+ if (br == TRUE) { -+ break; -+ } -+ else if ((addrh != 0) || (sizeh != 0) || -+ (sizel != SI_CORE_SIZE)) { -+ AP6210_ERR("addrh = 0x%x\t sizeh = 0x%x\t size1 =" -+ "0x%x\n", addrh, sizeh, sizel); -+ AP6210_ERR("First Slave ASD for" -+ "core 0x%04x malformed " -+ "(0x%08x)\n", cid, asd); -+ goto error; -+ } -+ } -+ } while (1); -+ } -+ sii->coresba[idx] = addrl; -+ sii->coresba_size[idx] = sizel; -+ /* Get any more ASDs in port 0 */ -+ j = 1; -+ do { -+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { -+ sii->coresba2[idx] = addrl; -+ sii->coresba2_size[idx] = sizel; -+ } -+ j++; -+ } while (asd != 0); -+ -+ /* Go through the ASDs for other slave ports */ -+ for (i = 1; i < nsp; i++) { -+ j = 0; -+ do { -+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ -+ if (asd == 0) -+ break; -+ j++; -+ } while (1); -+ if (j == 0) { -+ AP6210_ERR(" SP %d has no address descriptors\n", i); -+ goto error; -+ } -+ } -+ -+ /* Now get master wrappers */ -+ for (i = 0; i < nmw; i++) { -+ asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) { -+ AP6210_ERR("Missing descriptor for MW %d\n", i); -+ goto error; -+ } -+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { -+ AP6210_ERR("Master wrapper %d is not 4KB\n", i); -+ goto error; -+ } -+ if (i == 0) -+ sii->wrapba[idx] = addrl; -+ } -+ -+ /* And finally slave wrappers */ -+ for (i = 0; i < nsw; i++) { -+ uint fwp = (nsp == 1) ? 0 : 1; -+ asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) { -+ AP6210_ERR("Missing descriptor for SW %d\n", i); -+ goto error; -+ } -+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { -+ AP6210_ERR("Slave wrapper %d is not 4KB\n", i); -+ goto error; -+ } -+ if ((nmw == 0) && (i == 0)) -+ sii->wrapba[idx] = addrl; -+ } -+ -+ -+ /* Don't record bridges */ -+ if (br) -+ continue; -+ -+ /* Done with core */ -+ sii->numcores++; -+ } -+ -+ AP6210_ERR("Reached end of erom without finding END"); -+ -+error: -+ sii->numcores = 0; -+ return; -+} -+ -+/* This function changes the logical "focus" to the indicated core. -+ * Return the current core's virtual address. -+ */ -+void * -+ai_setcoreidx(si_t *sih, uint coreidx) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ uint32 addr, wrap; -+ void *regs; -+ -+ if (coreidx >= MIN(sii->numcores, SI_MAXCORES)) -+ return (NULL); -+ -+ addr = sii->coresba[coreidx]; -+ wrap = sii->wrapba[coreidx]; -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case SI_BUS: -+ /* map new one */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ sii->curmap = regs = sii->regs[coreidx]; -+ if (!sii->wrappers[coreidx]) { -+ sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->wrappers[coreidx])); -+ } -+ sii->curwrap = sii->wrappers[coreidx]; -+ break; -+ -+ -+ case SPI_BUS: -+ case SDIO_BUS: -+ sii->curmap = regs = (void *)((uintptr)addr); -+ sii->curwrap = (void *)((uintptr)wrap); -+ break; -+ -+ case PCMCIA_BUS: -+ default: -+ ASSERT(0); -+ regs = NULL; -+ break; -+ } -+ -+ sii->curmap = regs; -+ sii->curidx = coreidx; -+ -+ return regs; -+} -+ -+void -+ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ chipcregs_t *cc = NULL; -+ uint32 erombase, *eromptr, *eromlim; -+ uint i, j, cidx; -+ uint32 cia, cib, nmp, nsp; -+ uint32 asd, addrl, addrh, sizel, sizeh; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ if (sii->coreid[i] == CC_CORE_ID) { -+ cc = (chipcregs_t *)sii->regs[i]; -+ break; -+ } -+ } -+ if (cc == NULL) -+ goto error; -+ -+ erombase = R_REG(sii->osh, &cc->eromptr); -+ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); -+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); -+ -+ cidx = sii->curidx; -+ cia = sii->cia[cidx]; -+ cib = sii->cib[cidx]; -+ -+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; -+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; -+ -+ /* scan for cores */ -+ while (eromptr < eromlim) { -+ if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) && -+ (get_erom_ent(sih, &eromptr, 0, 0) == cib)) { -+ break; -+ } -+ } -+ -+ /* skip master ports */ -+ for (i = 0; i < nmp; i++) -+ get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); -+ -+ /* Skip ASDs in port 0 */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); -+ if (asd == 0) { -+ /* Try again to see if it is a bridge */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, -+ &sizel, &sizeh); -+ } -+ -+ j = 1; -+ do { -+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ j++; -+ } while (asd != 0); -+ -+ /* Go through the ASDs for other slave ports */ -+ for (i = 1; i < nsp; i++) { -+ j = 0; -+ do { -+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) -+ break; -+ -+ if (!asidx--) { -+ *addr = addrl; -+ *size = sizel; -+ return; -+ } -+ j++; -+ } while (1); -+ -+ if (j == 0) { -+ AP6210_ERR(" SP %d has no address descriptors\n", i); -+ break; -+ } -+ } -+ -+error: -+ *size = 0; -+ return; -+} -+ -+/* Return the number of address spaces in current core */ -+int -+ai_numaddrspaces(si_t *sih) -+{ -+ return 2; -+} -+ -+/* Return the address of the nth address space in the current core */ -+uint32 -+ai_addrspace(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ uint cidx; -+ -+ sii = SI_INFO(sih); -+ cidx = sii->curidx; -+ -+ if (asidx == 0) -+ return sii->coresba[cidx]; -+ else if (asidx == 1) -+ return sii->coresba2[cidx]; -+ else { -+ AP6210_ERR("%s: Need to parse the erom again to find addr space %d\n", -+ __FUNCTION__, asidx); -+ return 0; -+ } -+} -+ -+/* Return the size of the nth address space in the current core */ -+uint32 -+ai_addrspacesize(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ uint cidx; -+ -+ sii = SI_INFO(sih); -+ cidx = sii->curidx; -+ -+ if (asidx == 0) -+ return sii->coresba_size[cidx]; -+ else if (asidx == 1) -+ return sii->coresba2_size[cidx]; -+ else { -+ AP6210_ERR("%s: Need to parse the erom again to find addr space %d\n", -+ __FUNCTION__, asidx); -+ return 0; -+ } -+} -+ -+uint -+ai_flag(si_t *sih) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ if (BCM47162_DMP()) { -+ AP6210_ERR("%s: Attempting to read MIPS DMP registers on 47162a0", __FUNCTION__); -+ return sii->curidx; -+ } -+ if (BCM5357_DMP()) { -+ AP6210_ERR("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__); -+ return sii->curidx; -+ } -+ ai = sii->curwrap; -+ -+ return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); -+} -+ -+void -+ai_setint(si_t *sih, int siflag) -+{ -+} -+ -+uint -+ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ uint32 *map = (uint32 *) sii->curwrap; -+ -+ if (mask || val) { -+ uint32 w = R_REG(sii->osh, map+(offset/4)); -+ w &= ~mask; -+ w |= val; -+ W_REG(sii->osh, map+(offset/4), val); -+ } -+ -+ return (R_REG(sii->osh, map+(offset/4))); -+} -+ -+uint -+ai_corevendor(si_t *sih) -+{ -+ si_info_t *sii; -+ uint32 cia; -+ -+ sii = SI_INFO(sih); -+ cia = sii->cia[sii->curidx]; -+ return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); -+} -+ -+uint -+ai_corerev(si_t *sih) -+{ -+ si_info_t *sii; -+ uint32 cib; -+ -+ sii = SI_INFO(sih); -+ cib = sii->cib[sii->curidx]; -+ return remap_corerev(sih, (cib & CIB_REV_MASK) >> CIB_REV_SHIFT); -+} -+ -+bool -+ai_iscoreup(si_t *sih) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ ai = sii->curwrap; -+ -+ return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && -+ ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); -+} -+ -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ * -+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed. -+ * -+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers -+ * and (on newer pci cores) chipcommon registers. -+ */ -+uint -+ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ uint origidx = 0; -+ uint32 *r = NULL; -+ uint w; -+ uint intr_val = 0; -+ bool fast = FALSE; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SI_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); -+ -+ if (coreidx >= SI_MAXCORES) -+ return 0; -+ -+ if (BUSTYPE(sih->bustype) == SI_BUS) { -+ /* If internal bus, we can always get at everything */ -+ fast = TRUE; -+ /* map if does not exist */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], -+ SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); -+ } else if (BUSTYPE(sih->bustype) == PCI_BUS) { -+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ -+ -+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { -+ /* Chipc registers are mapped at 12KB */ -+ -+ fast = TRUE; -+ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); -+ } else if (sii->pub.buscoreidx == coreidx) { -+ /* pci registers are at either in the last 2KB of an 8KB window -+ * or, in pcie and pci rev 13 at 8KB -+ */ -+ fast = TRUE; -+ if (SI_FAST(sii)) -+ r = (uint32 *)((char *)sii->curmap + -+ PCI_16KB0_PCIREGS_OFFSET + regoff); -+ else -+ r = (uint32 *)((char *)sii->curmap + -+ ((regoff >= SBCONFIGOFF) ? -+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + -+ regoff); -+ } -+ } -+ -+ if (!fast) { -+ INTR_OFF(sii, intr_val); -+ -+ /* save current core index */ -+ origidx = si_coreidx(&sii->pub); -+ -+ /* switch core */ -+ r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); -+ } -+ ASSERT(r != NULL); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_REG(sii->osh, r) & ~mask) | val; -+ W_REG(sii->osh, r, w); -+ } -+ -+ /* readback */ -+ w = R_REG(sii->osh, r); -+ -+ if (!fast) { -+ /* restore core index */ -+ if (origidx != coreidx) -+ ai_setcoreidx(&sii->pub, origidx); -+ -+ INTR_RESTORE(sii, intr_val); -+ } -+ -+ return (w); -+} -+ -+void -+ai_core_disable(si_t *sih, uint32 bits) -+{ -+ si_info_t *sii; -+ volatile uint32 dummy; -+ uint32 status; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ /* if core is already in reset, just return */ -+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) -+ return; -+ -+ /* ensure there are no pending backplane operations */ -+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300); -+ -+ /* if pending backplane ops still, try waiting longer */ -+ if (status != 0) { -+ /* 300usecs was sufficient to allow backplane ops to clear for big hammer */ -+ /* during driver load we may need more time */ -+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000); -+ /* if still pending ops, continue on and try disable anyway */ -+ /* this is in big hammer path, so don't call wl_reinit in this case... */ -+ } -+ -+ W_REG(sii->osh, &ai->ioctrl, bits); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(10); -+ -+ W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); -+ dummy = R_REG(sii->osh, &ai->resetctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+} -+ -+/* reset and re-enable a core -+ * inputs: -+ * bits - core specific bits that are set during and after reset sequence -+ * resetbits - core specific bits that are set only during reset sequence -+ */ -+void -+ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ volatile uint32 dummy; -+ -+ sii = SI_INFO(sih); -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ ai_core_disable(sih, (bits | resetbits)); -+ -+ /* -+ * Now do the initialization sequence. -+ */ -+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ -+ W_REG(sii->osh, &ai->resetctrl, 0); -+ dummy = R_REG(sii->osh, &ai->resetctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ -+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+} -+ -+void -+ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ -+ if (BCM47162_DMP()) { -+ AP6210_ERR("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", -+ __FUNCTION__); -+ return; -+ } -+ if (BCM5357_DMP()) { -+ AP6210_ERR("%s: Accessing USB20H DMP register (ioctrl) on 5357\n", -+ __FUNCTION__); -+ return; -+ } -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); -+ W_REG(sii->osh, &ai->ioctrl, w); -+ } -+} -+ -+uint32 -+ai_core_cflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ if (BCM47162_DMP()) { -+ AP6210_ERR("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", -+ __FUNCTION__); -+ return 0; -+ } -+ if (BCM5357_DMP()) { -+ AP6210_ERR("%s: Accessing USB20H DMP register (ioctrl) on 5357\n", -+ __FUNCTION__); -+ return 0; -+ } -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); -+ W_REG(sii->osh, &ai->ioctrl, w); -+ } -+ -+ return R_REG(sii->osh, &ai->ioctrl); -+} -+ -+uint32 -+ai_core_sflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ if (BCM47162_DMP()) { -+ AP6210_ERR("%s: Accessing MIPS DMP register (iostatus) on 47162a0", -+ __FUNCTION__); -+ return 0; -+ } -+ if (BCM5357_DMP()) { -+ AP6210_ERR("%s: Accessing USB20H DMP register (iostatus) on 5357\n", -+ __FUNCTION__); -+ return 0; -+ } -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SISF_CORE_BITS) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); -+ W_REG(sii->osh, &ai->iostatus, w); -+ } -+ -+ return R_REG(sii->osh, &ai->iostatus); -+} -diff --git a/drivers/net/wireless/ap6210/ap6210.h b/drivers/net/wireless/ap6210/ap6210.h -new file mode 100644 -index 0000000..90e7d8d ---- /dev/null -+++ b/drivers/net/wireless/ap6210/ap6210.h -@@ -0,0 +1,22 @@ -+#ifndef __AP6210_H__ -+#define __AP6210_H__ -+ -+#define AP6210_EMERG(...) pr_emerg("[ap6210] "__VA_ARGS__) -+#define AP6210_ALERT(...) pr_alert("[ap6210] "__VA_ARGS__) -+#define AP6210_CRIT(...) pr_crit("[ap6210] "__VA_ARGS__) -+#define AP6210_ERR(...) pr_err("[ap6210] "__VA_ARGS__) -+#define AP6210_WARN(...) pr_warn("[ap6210] "__VA_ARGS__) -+#define AP6210_NOTICE(...) pr_notice("[ap6210] "__VA_ARGS__) -+#define AP6210_INFO(...) pr_info("[ap6210] "__VA_ARGS__) -+#define AP6210_DEBUG(...) pr_debug("[ap6210] "__VA_ARGS__) -+#define AP6210_DUMP(...) pr_debug(__VA_ARGS__) -+#define AP6210_CONT(...) pr_cont(__VA_ARGS__) -+ -+extern int __init sw_rfkill_init(void); -+extern void __exit sw_rfkill_exit(void); -+ -+extern int __init ap6210_gpio_wifi_init(void); -+extern void __exit ap6210_gpio_wifi_exit(void); -+ -+ -+#endif /* __AP6210_H__ */ -diff --git a/drivers/net/wireless/ap6210/ap6210_gpio.h b/drivers/net/wireless/ap6210/ap6210_gpio.h -new file mode 100644 -index 0000000..96a3166 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/ap6210_gpio.h -@@ -0,0 +1,9 @@ -+#ifndef __AP6210_GPIO_H__ -+#define __AP6210_GPIO_H__ -+ -+extern int ap6210_gpio_wifi_get_mod_type(void); -+extern int ap6210_gpio_wifi_gpio_ctrl(char* name, int level); -+extern void ap6210_gpio_wifi_power(int on); -+extern char *ap6210_gpio_wifi_get_name(int module_sel); -+ -+#endif /* __AP6210_GPIO_H__ */ -diff --git a/drivers/net/wireless/ap6210/ap6210_gpio_bt.c b/drivers/net/wireless/ap6210/ap6210_gpio_bt.c -new file mode 100644 -index 0000000..4686615 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/ap6210_gpio_bt.c -@@ -0,0 +1,164 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if (defined CONFIG_MMC) -+#include "ap6210_gpio.h" -+#else -+static __inline int ap6210_gpio_wifi_get_mod_type(void) -+{ -+ AP6210_DEBUG("%s : not implemented!\n", __FUNCTION__ ); -+ return 0; -+} -+static __inline int ap6210_gpio_wifi_gpio_ctrl(char* name, int level) -+{ -+ AP6210_DEBUG("%s : not implemented!\n", __FUNCTION__ ); -+ return -1; -+} -+#endif -+ -+#include -+ -+static const char bt_name[] = "bcm40183"; -+static struct rfkill *sw_rfkill; -+static int bt_used; -+ -+static int rfkill_set_power(void *data, bool blocked) -+{ -+ unsigned int mod_sel = ap6210_gpio_wifi_get_mod_type(); -+ -+ AP6210_DEBUG("rfkill set power %s\n", ( blocked ? "blocked" : "unblocked" )); -+ -+ switch (mod_sel) -+ { -+ case 2: /* bcm40183 */ -+ if (!blocked) { -+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_regon", 1); -+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_rst", 1); -+ } else { -+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_rst", 0); -+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_regon", 0); -+ } -+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) ); -+ break; -+ case 3: /* realtek rtl8723as */ -+ if (!blocked) { -+ ap6210_gpio_wifi_gpio_ctrl("rtk_rtl8723as_bt_dis", 1); -+ } else { -+ ap6210_gpio_wifi_gpio_ctrl("rtk_rtl8723as_bt_dis", 0); -+ } -+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) ); -+ break; -+ case 7: /* ap6210 */ -+ case 8: /* ap6330 */ -+ if (!blocked) { -+ ap6210_gpio_wifi_gpio_ctrl("ap6xxx_bt_regon", 1); -+ } else { -+ ap6210_gpio_wifi_gpio_ctrl("ap6xxx_bt_regon", 0); -+ } -+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) ); -+ break; -+ case 10: /* realtek rtl8723au */ -+ if (!blocked) { -+ ap6210_gpio_wifi_gpio_ctrl("rtl8723au_bt", 1); -+ } else { -+ ap6210_gpio_wifi_gpio_ctrl("rtl8723au_bt", 0); -+ } -+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) ); -+ break; -+ default: -+ AP6210_ERR("no bluetooth module matched.\n" ); -+ } -+ -+ msleep(10); -+ return 0; -+} -+ -+static struct rfkill_ops sw_rfkill_ops = { -+ .set_block = rfkill_set_power, -+}; -+ -+static int sw_rfkill_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ sw_rfkill = rfkill_alloc(bt_name, &pdev->dev, -+ RFKILL_TYPE_BLUETOOTH, &sw_rfkill_ops, NULL); -+ if (unlikely(!sw_rfkill)) { -+ AP6210_DEBUG("Unable to alocate rfkill structure.\n" ); -+ return -ENOMEM; -+ } -+ -+ ret = rfkill_register(sw_rfkill); -+ if (unlikely(ret)) { -+ AP6210_DEBUG("Unable to register rfkill structure.\n" ); -+ rfkill_destroy(sw_rfkill); -+ } -+ AP6210_DEBUG("rfkill structure registered successfully.\n" ); -+ return ret; -+} -+ -+static int sw_rfkill_remove(struct platform_device *pdev) -+{ -+ if (likely(sw_rfkill)) { -+ rfkill_unregister(sw_rfkill); -+ rfkill_destroy(sw_rfkill); -+ AP6210_DEBUG("rfkill structure removed successfully.\n" ); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver sw_rfkill_driver = { -+ .probe = sw_rfkill_probe, -+ .remove = sw_rfkill_remove, -+ .driver = { -+ .name = "sunxi-rfkill", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static struct platform_device sw_rfkill_dev = { -+ .name = "sunxi-rfkill", -+}; -+ -+int __init sw_rfkill_init(void) -+{ -+ if (SCRIPT_PARSER_OK != script_parser_fetch("bt_para", "bt_used", &bt_used, 1)) { -+ AP6210_DEBUG("parse bt_used failed in script.fex.\n" ); -+ return -1; -+ } -+ -+ if (!bt_used) { -+ AP6210_ERR("bluetooth is disable in script.fex.\n" ); -+ return 0; -+ } -+ -+ platform_device_register(&sw_rfkill_dev); -+ AP6210_ERR("platform device registered successfully.\n" ); -+ return platform_driver_register(&sw_rfkill_driver); -+} -+ -+void __exit sw_rfkill_exit(void) -+{ -+ if (!bt_used) { -+ AP6210_ERR("exit no bt used in configuration\n" ); -+ return ; -+ } -+ -+ platform_device_unregister(&sw_rfkill_dev); -+ platform_driver_unregister(&sw_rfkill_driver); -+} -+ -+/* -+module_init(sw_rfkill_init); -+module_exit(sw_rfkill_exit); -+ -+MODULE_DESCRIPTION("sunxi-rfkill driver"); -+MODULE_AUTHOR("Aaron.magic"); -+MODULE_LICENSE("GPL"); -+*/ -+ -diff --git a/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c b/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c -new file mode 100644 -index 0000000..13e0bdf ---- /dev/null -+++ b/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c -@@ -0,0 +1,433 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static char* wifi_para = "wifi_para"; -+ -+struct ap6210_gpio_wifi_ops { -+ char* mod_name; -+ int wifi_used; -+ int sdio_id; -+ int usb_id; -+ int module_sel; -+ int (*gpio_ctrl)(char* name, int level); -+ void (*standby)(int in); -+ void (*power)(int mode, int *updown); -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_root; -+ struct proc_dir_entry *proc_power; -+#endif /* CONFIG_PROC_FS */ -+}; -+ -+static int ap6210_wl_regon = 0; -+static int ap6210_bt_regon = 0; -+ -+struct ap6210_gpio_wifi_ops ap6210_wifi_select_pm_ops; -+ -+char *ap6210_gpio_wifi_get_name(int module_sel) { -+ char* mod_name[] = { " ", -+ "bcm40181", /* 1 - BCM40181(BCM4330)*/ -+ "bcm40183", /* 2 - BCM40183(BCM4330)*/ -+ "rtl8723as", /* 3 - RTL8723AS(RF-SM02B) */ -+ "rtl8189es", /* 4 - RTL8189ES(SM89E00) */ -+ "rtl8192cu", /* 5 - RTL8192CU*/ -+ "rtl8188eu", /* 6 - RTL8188EU*/ -+ "ap6210", /* 7 - AP6210*/ -+ "ap6330", /* 8 - AP6330*/ -+ "ap6181", /* 9 - AP6181*/ -+ "rtl8723au", /* 10 - RTL8723AU */ -+ }; -+ -+ return(mod_name[module_sel]); -+} -+ -+EXPORT_SYMBOL(ap6210_gpio_wifi_get_name); -+ -+static int ap6210_gpio_ctrl(char* name, int level) -+{ -+ int i = 0; -+ int ret = 0; -+ int gpio = 0; -+ char * gpio_name[2] = {"ap6210_wl_regon", "ap6210_bt_regon"}; -+ -+ for (i = 0; i < 2; i++) { -+ if (strcmp(name, gpio_name[i]) == 0) { -+ switch (i) -+ { -+ case 0: /*ap6210_wl_regon*/ -+ gpio = ap6210_wl_regon; -+ break; -+ case 1: /*ap6210_bt_regon*/ -+ gpio = ap6210_bt_regon; -+ break; -+ default: -+ AP6210_ERR("no matched gpio.\n" ); -+ } -+ break; -+ } -+ } -+ -+ ret = gpio_write_one_pin_value(gpio, level, name); -+ -+ return 0; -+} -+ -+static int ap6210_gpio_read(char* name) -+{ -+ int i = 0; -+ int gpio = 0; -+ int val = 0; -+ char * gpio_name[2] = {"ap6210_wl_regon", "ap6210_bt_regon"}; -+ -+ for (i = 0; i < 2; i++) { -+ if (strcmp(name, gpio_name[i]) == 0) { -+ switch (i) -+ { -+ case 0: /*ap6210_wl_regon*/ -+ gpio = ap6210_wl_regon; -+ break; -+ case 1: /*ap6210_bt_regon*/ -+ gpio = ap6210_bt_regon; -+ break; -+ default: -+ AP6210_ERR("no matched gpio.\n" ); -+ } -+ break; -+ } -+ } -+ -+ val = gpio_read_one_pin_value(gpio, name); -+ -+ return val; -+} -+ -+ -+void ap6210_power(int mode, int *updown) -+{ -+ if (mode) { -+ if (*updown) { -+ ap6210_gpio_ctrl("ap6210_wl_regon", 1); -+ mdelay(100); -+ } else { -+ ap6210_gpio_ctrl("ap6210_wl_regon", 0); -+ mdelay(100); -+ } -+ AP6210_DEBUG("sdio wifi power state: %s\n", *updown ? "on" : "off"); -+ } else { -+ *updown = ap6210_gpio_read("ap6210_wl_regon"); -+ } -+ -+ return; -+} -+ -+static void ap6210_cfg_gpio_32k_clkout(int gpio_index) -+{ -+ int ret; -+ struct clk *clk_32k, *parent; -+ -+ parent = clk_get(NULL, CLK_SYS_LOSC); -+ clk_32k = clk_get(NULL, CLK_MOD_OUTA); -+ ret = clk_set_parent(clk_32k, parent); -+ -+ if(ret){ -+ AP6210_ERR("32k clk_set_parent fail.\n" ); -+ return; -+ } -+ -+ ret = clk_set_rate(clk_32k, 32768); -+ if(ret){ -+ AP6210_ERR("32k clk_set_rate fail.\n" ); -+ return; -+ } -+ -+ clk_enable(clk_32k); -+} -+void ap6210_gpio_init(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ int ap6210_lpo = 0; -+ -+/* CT expected ap6210_lpo as a GPIO */ -+ ap6210_lpo = gpio_request_ex(wifi_para, "ap6xxx_lpo"); -+ if (!ap6210_lpo) { -+ AP6210_ERR("request lpo gpio failed.\n" ); -+ return; -+ } -+ -+ if(ap6210_lpo) { -+ AP6210_DEBUG("config 32k clock.\n" ); -+ ap6210_cfg_gpio_32k_clkout(ap6210_lpo); -+ } -+ -+ ap6210_wl_regon = gpio_request_ex(wifi_para, "ap6xxx_wl_regon"); -+ if (!ap6210_wl_regon) { -+ AP6210_ERR("request wl_regon gpio failed.\n" ); -+ return; -+ } -+ -+ ap6210_bt_regon = gpio_request_ex(wifi_para, "ap6xxx_bt_regon"); -+ if (!ap6210_bt_regon) { -+ AP6210_ERR("request ap6210_bt_regon gpio failed.\n" ); -+ return; -+ } -+ -+ ops->gpio_ctrl = ap6210_gpio_ctrl; -+ ops->power = ap6210_power; -+} -+ -+int ap6210_gpio_wifi_get_mod_type(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ if (ops->wifi_used) -+ return ops->module_sel; -+ else { -+ AP6210_ERR("No wifi type selected, please check your config.\n" ); -+ return 0; -+ } -+} -+EXPORT_SYMBOL(ap6210_gpio_wifi_get_mod_type); -+ -+int ap6210_gpio_wifi_gpio_ctrl(char* name, int level) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ if (ops->wifi_used && ops->gpio_ctrl) -+ return ops->gpio_ctrl(name, level); -+ else { -+ AP6210_ERR("No wifi type selected, please check your config.\n" ); -+ return -1; -+ } -+} -+EXPORT_SYMBOL(ap6210_gpio_wifi_gpio_ctrl); -+ -+void ap6210_gpio_wifi_power(int on) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ int power = on; -+ -+ if (ops->wifi_used && ops->power) -+ return ops->power(1, &power); -+ else { -+ AP6210_ERR("No wifi type selected, please check your config.\n" ); -+ return; -+ } -+} -+EXPORT_SYMBOL(ap6210_gpio_wifi_power); -+ -+#ifdef CONFIG_PROC_FS -+static int ap6210_gpio_wifi_power_stat(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ struct ap6210_gpio_wifi_ops *ops = (struct ap6210_gpio_wifi_ops *)data; -+ char *p = page; -+ int power = 0; -+ -+ if (ops->power) -+ ops->power(0, &power); -+ -+ p += sprintf(p, "%s : power state %s\n", ops->mod_name, power ? "on" : "off"); -+ return p - page; -+} -+ -+static int ap6210_gpio_wifi_power_ctrl(struct file *file, const char __user *buffer, unsigned long count, void *data) -+{ -+ struct ap6210_gpio_wifi_ops *ops = (struct ap6210_gpio_wifi_ops *)data; -+ int power = simple_strtoul(buffer, NULL, 10); -+ -+ power = power ? 1 : 0; -+ if (ops->power) -+ ops->power(1, &power); -+ else -+ AP6210_ERR("No power control for %s\n", ops->mod_name); -+ return sizeof(power); -+} -+ -+static inline void awwifi_procfs_attach(void) -+{ -+ char proc_rootname[] = "driver/ap6210_gpio_wifi"; -+ char proc_powername[] = "power"; -+ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ ops->proc_root = proc_mkdir(proc_rootname, NULL); -+ if (IS_ERR(ops->proc_root)) -+ { -+ AP6210_ERR("failed to create procfs \"%s\".\n", proc_rootname ); -+ } -+ -+ ops->proc_power = create_proc_entry(proc_powername, 0644, ops->proc_root); -+ if (IS_ERR(ops->proc_power)) -+ { -+ AP6210_ERR("failed to create procfs \"%s\".\n", proc_powername); -+ } -+ ops->proc_power->data = ops; -+ ops->proc_power->read_proc = ap6210_gpio_wifi_power_stat; -+ ops->proc_power->write_proc = ap6210_gpio_wifi_power_ctrl; -+} -+ -+static inline void awwifi_procfs_remove(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ char proc_rootname[] = "driver/ap6210_gpio_wifi"; -+ -+ remove_proc_entry("power", ops->proc_root); -+ remove_proc_entry(proc_rootname, NULL); -+} -+#else -+static inline void awwifi_procfs_attach(void) {} -+static inline void awwifi_procfs_remove(void) {} -+#endif -+ -+ -+ -+static int ap6210_gpio_wifi_get_res(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_used", &ops->wifi_used, 1)) { -+ AP6210_ERR("parse wifi_used failed in script.fex.\n" ); -+ return -1; -+ } -+ if (!ops->wifi_used) { -+ AP6210_ERR("wifi pm disable in script.fex.\n" ); -+ return -1; -+ } -+ -+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_sdc_id", &ops->sdio_id, 1)) { -+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" ); -+ return -1; -+ } -+ -+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_usbc_id", &ops->usb_id, 1)) { -+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" ); -+ return -1; -+ } -+ -+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_mod_sel", &ops->module_sel, 1)) { -+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" ); -+ return -1; -+ } -+ -+ ops->mod_name = ap6210_gpio_wifi_get_name(ops->module_sel); -+ -+ AP6210_ERR("select wifi %s\n", ops->mod_name); -+ -+ return 0; -+} -+ -+static int __devinit ap6210_gpio_wifi_probe(struct platform_device *pdev) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ switch (ops->module_sel) { -+ case 1: /* BCM40181 */ -+ case 2: /* BCM40183 */ -+ case 3: /* RTL8723AS */ -+ case 4: /* RTL8189ES */ -+ case 5: /* RTL8192CU */ -+ case 6: /* RTL8188EU */ -+ AP6210_ERR("Unsupported device.\n"); -+ break; -+ case 7: /* AP6210 */ -+ case 8: /* AP6330 */ -+ case 9: /* AP6181 */ -+ AP6210_ERR("Initializing %s.\n", ops->mod_name); -+ ap6210_gpio_init(); -+ break; -+ case 10: /* RTL8723AU */ -+ AP6210_ERR("Unsupported device.\n"); -+ break; -+ default: -+ AP6210_ERR("Unsupported device.\n"); -+ } -+ -+ awwifi_procfs_attach(); -+ AP6210_DEBUG("wifi gpio attached.\n" ); -+ return 0; -+} -+ -+static int __devexit ap6210_gpio_wifi_remove(struct platform_device *pdev) -+{ -+ awwifi_procfs_remove(); -+ AP6210_DEBUG("wifi gpio released.\n" ); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int ap6210_gpio_wifi_suspend(struct device *dev) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ if (ops->standby) -+ ops->standby(1); -+ return 0; -+} -+ -+static int ap6210_gpio_wifi_resume(struct device *dev) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ if (ops->standby) -+ ops->standby(0); -+ return 0; -+} -+ -+static struct dev_pm_ops wifi_dev_pm_ops = { -+ .suspend = ap6210_gpio_wifi_suspend, -+ .resume = ap6210_gpio_wifi_resume, -+}; -+#endif -+ -+static struct platform_device ap6210_gpio_wifi_dev = { -+ .name = "ap6210_gpio_wifi", -+}; -+ -+static struct platform_driver ap6210_gpio_wifi_driver = { -+ .driver.name = "ap6210_gpio_wifi", -+ .driver.owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .driver.pm = &wifi_dev_pm_ops, -+#endif -+ .probe = ap6210_gpio_wifi_probe, -+ .remove = __devexit_p(ap6210_gpio_wifi_remove), -+}; -+ -+int __init ap6210_gpio_wifi_init(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ -+ memset(ops, 0, sizeof(struct ap6210_gpio_wifi_ops)); -+ ap6210_gpio_wifi_get_res(); -+ if (!ops->wifi_used) -+ return 0; -+ -+ platform_device_register(&ap6210_gpio_wifi_dev); -+ return platform_driver_register(&ap6210_gpio_wifi_driver); -+} -+ -+void __exit ap6210_gpio_wifi_exit(void) -+{ -+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops; -+ if (!ops->wifi_used) -+ return; -+ -+ platform_driver_unregister(&ap6210_gpio_wifi_driver); -+ memset(ops, 0, sizeof(struct ap6210_gpio_wifi_ops)); -+} -+ -+/* -+module_init(ap6210_gpio_wifi_init); -+module_exit(ap6210_gpio_wifi_exit); -+ -+MODULE_LICENSE("GPL"); -+*/ -\ No newline at end of file -diff --git a/drivers/net/wireless/ap6210/bcmevent.c b/drivers/net/wireless/ap6210/bcmevent.c -new file mode 100644 -index 0000000..16e2fca ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmevent.c -@@ -0,0 +1,152 @@ -+/* -+ * bcmevent read-only data shared by kernel or app layers -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: bcmevent.c 370587 2012-11-22 09:32:38Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if WLC_E_LAST != 107 -+#error "You need to add an entry to bcmevent_names[] for the new event" -+#endif -+ -+const bcmevent_name_t bcmevent_names[] = { -+ { WLC_E_SET_SSID, "SET_SSID" }, -+ { WLC_E_JOIN, "JOIN" }, -+ { WLC_E_START, "START" }, -+ { WLC_E_AUTH, "AUTH" }, -+ { WLC_E_AUTH_IND, "AUTH_IND" }, -+ { WLC_E_DEAUTH, "DEAUTH" }, -+ { WLC_E_DEAUTH_IND, "DEAUTH_IND" }, -+ { WLC_E_ASSOC, "ASSOC" }, -+ { WLC_E_ASSOC_IND, "ASSOC_IND" }, -+ { WLC_E_REASSOC, "REASSOC" }, -+ { WLC_E_REASSOC_IND, "REASSOC_IND" }, -+ { WLC_E_DISASSOC, "DISASSOC" }, -+ { WLC_E_DISASSOC_IND, "DISASSOC_IND" }, -+ { WLC_E_QUIET_START, "START_QUIET" }, -+ { WLC_E_QUIET_END, "END_QUIET" }, -+ { WLC_E_BEACON_RX, "BEACON_RX" }, -+ { WLC_E_LINK, "LINK" }, -+ { WLC_E_MIC_ERROR, "MIC_ERROR" }, -+ { WLC_E_NDIS_LINK, "NDIS_LINK" }, -+ { WLC_E_ROAM, "ROAM" }, -+ { WLC_E_TXFAIL, "TXFAIL" }, -+ { WLC_E_PMKID_CACHE, "PMKID_CACHE" }, -+ { WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, -+ { WLC_E_PRUNE, "PRUNE" }, -+ { WLC_E_AUTOAUTH, "AUTOAUTH" }, -+ { WLC_E_EAPOL_MSG, "EAPOL_MSG" }, -+ { WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, -+ { WLC_E_ADDTS_IND, "ADDTS_IND" }, -+ { WLC_E_DELTS_IND, "DELTS_IND" }, -+ { WLC_E_BCNSENT_IND, "BCNSENT_IND" }, -+ { WLC_E_BCNRX_MSG, "BCNRX_MSG" }, -+ { WLC_E_BCNLOST_MSG, "BCNLOST_IND" }, -+ { WLC_E_ROAM_PREP, "ROAM_PREP" }, -+ { WLC_E_PFN_NET_FOUND, "PFNFOUND_IND" }, -+ { WLC_E_PFN_NET_LOST, "PFNLOST_IND" }, -+#if defined(IBSS_PEER_DISCOVERY_EVENT) -+ { WLC_E_IBSS_ASSOC, "IBSS_ASSOC" }, -+#endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */ -+ { WLC_E_RADIO, "RADIO" }, -+ { WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, -+ { WLC_E_PROBREQ_MSG, "PROBE_REQ_MSG" }, -+ { WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, -+ { WLC_E_PSK_SUP, "PSK_SUP" }, -+ { WLC_E_COUNTRY_CODE_CHANGED, "CNTRYCODE_IND" }, -+ { WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, -+ { WLC_E_ICV_ERROR, "ICV_ERROR" }, -+ { WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, -+ { WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, -+ { WLC_E_TRACE, "TRACE" }, -+#ifdef WLBTAMP -+ { WLC_E_BTA_HCI_EVENT, "BTA_HCI_EVENT" }, -+#endif -+ { WLC_E_IF, "IF" }, -+#ifdef WLP2P -+ { WLC_E_P2P_DISC_LISTEN_COMPLETE, "WLC_E_P2P_DISC_LISTEN_COMPLETE" }, -+#endif -+ { WLC_E_RSSI, "RSSI" }, -+ { WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE" }, -+ { WLC_E_EXTLOG_MSG, "EXTERNAL LOG MESSAGE" }, -+#ifdef WIFI_ACT_FRAME -+ { WLC_E_ACTION_FRAME, "ACTION_FRAME" }, -+ { WLC_E_ACTION_FRAME_RX, "ACTION_FRAME_RX" }, -+ { WLC_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, -+#endif -+#ifdef BCMWAPI_WAI -+ { WLC_E_WAI_STA_EVENT, "WAI_STA_EVENT" }, -+ { WLC_E_WAI_MSG, "WAI_MSG" }, -+#endif /* BCMWAPI_WAI */ -+#if 0 && (NDISVER >= 0x0620) -+ { WLC_E_PRE_ASSOC_IND, "ASSOC_RECV" }, -+ { WLC_E_PRE_REASSOC_IND, "REASSOC_RECV" }, -+ { WLC_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, -+ { WLC_E_AP_STARTED, "AP_STARTED" }, -+ { WLC_E_DFS_AP_STOP, "DFS_AP_STOP" }, -+ { WLC_E_DFS_AP_RESUME, "DFS_AP_RESUME" }, -+ { WLC_E_ASSOC_IND_NDIS, "ASSOC_IND_NDIS"}, -+ { WLC_E_REASSOC_IND_NDIS, "REASSOC_IND_NDIS"}, -+ { WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" }, -+ { WLC_E_AUTH_REQ, "WLC_E_AUTH_REQ" }, -+#endif -+ { WLC_E_ESCAN_RESULT, "WLC_E_ESCAN_RESULT" }, -+ { WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "WLC_E_AF_OFF_CHAN_COMPLETE" }, -+#ifdef WLP2P -+ { WLC_E_PROBRESP_MSG, "PROBE_RESP_MSG" }, -+ { WLC_E_P2P_PROBREQ_MSG, "P2P PROBE_REQ_MSG" }, -+#endif -+#ifdef PROP_TXSTATUS -+ { WLC_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP" }, -+#endif -+ { WLC_E_WAKE_EVENT, "WAKE_EVENT" }, -+ { WLC_E_DCS_REQUEST, "DCS_REQUEST" }, -+ { WLC_E_RM_COMPLETE, "RM_COMPLETE" }, -+#ifdef WLMEDIA_HTSF -+ { WLC_E_HTSFSYNC, "HTSF_SYNC_EVENT" }, -+#endif -+ { WLC_E_OVERLAY_REQ, "OVERLAY_REQ_EVENT" }, -+ { WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND"}, -+ { WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" }, -+ { WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" }, -+ { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" }, -+#ifdef SOFTAP -+ { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" }, -+#endif -+ { WLC_E_ASSOC_REQ_IE, "ASSOC_REQ_IE" }, -+ { WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" }, -+ { WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" }, -+#ifdef WLTDLS -+ { WLC_E_TDLS_PEER_EVENT, "TDLS_PEER_EVENT" }, -+#endif /* WLTDLS */ -+ { WLC_E_SERVICE_FOUND, "SERVICE_FOUND" }, -+ { WLC_E_P2PO_ADD_DEVICE, "P2PO_DEV_FOUND" }, -+ { WLC_E_P2PO_DEL_DEVICE, "P2PO_DEV_LOST" }, -+}; -+ -+const int bcmevent_names_size = ARRAYSIZE(bcmevent_names); -diff --git a/drivers/net/wireless/ap6210/bcmsdh.c b/drivers/net/wireless/ap6210/bcmsdh.c -new file mode 100644 -index 0000000..ca59ff8 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmsdh.c -@@ -0,0 +1,778 @@ -+/* -+ * BCMSDH interface glue -+ * implement bcmsdh API for SDIOH driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh.c 373330 2012-12-07 04:46:17Z $ -+ */ -+ -+/** -+ * @file bcmsdh.c -+ */ -+ -+/* ****************** BCMSDH Interface Functions *************************** */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include /* BRCM API for SDIO clients (such as wl, dhd) */ -+#include /* common SDIO/controller interface */ -+#include /* SDIO device core hardware definitions. */ -+ -+#include /* SDIO Device and Protocol Specs */ -+ -+#include -+ -+#define SDIOH_API_ACCESS_RETRY_LIMIT 2 -+const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; -+ -+/** -+ * BCMSDH API context -+ */ -+struct bcmsdh_info -+{ -+ bool init_success; /* underlying driver successfully attached */ -+ void *sdioh; /* handler for sdioh */ -+ uint32 vendevid; /* Target Vendor and Device ID on SD bus */ -+ osl_t *osh; -+ bool regfail; /* Save status of last reg_read/reg_write call */ -+ uint32 sbwad; /* Save backplane window address */ -+}; -+/* local copy of bcm sd handler */ -+bcmsdh_info_t * l_bcmsdh = NULL; -+ -+#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -+extern int -+sdioh_enable_hw_oob_intr(void *sdioh, bool enable); -+ -+void -+bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) -+{ -+ sdioh_enable_hw_oob_intr(sdh->sdioh, enable); -+} -+#endif -+ -+#if defined(HW_OOB) -+#include -+void -+bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) -+{ -+ uint32 gpiocontrol, addr; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ if (CHIPID(chip) == BCM43362_CHIP_ID) { -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); -+ gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); -+ gpiocontrol |= 0x2; -+ bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); -+ } -+} -+#endif -+ -+/* Attach BCMSDH layer to SDIO Host Controller Driver -+ * -+ * @param osh OSL Handle. -+ * @param cfghdl Configuration Handle. -+ * @param regsva Virtual address of controller registers. -+ * @param irq Interrupt number of SDIO controller. -+ * -+ * @return bcmsdh_info_t Handle to BCMSDH context. -+ */ -+bcmsdh_info_t * -+bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) -+{ -+ bcmsdh_info_t *bcmsdh; -+ -+ if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) { -+ BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh))); -+ return NULL; -+ } -+ bzero((char *)bcmsdh, sizeof(bcmsdh_info_t)); -+ -+ /* save the handler locally */ -+ l_bcmsdh = bcmsdh; -+ -+ if (!(bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq))) { -+ bcmsdh_detach(osh, bcmsdh); -+ return NULL; -+ } -+ -+ bcmsdh->osh = osh; -+ bcmsdh->init_success = TRUE; -+ -+ *regsva = (uint32 *)SI_ENUM_BASE; -+ -+ /* Report the BAR, to fix if needed */ -+ bcmsdh->sbwad = SI_ENUM_BASE; -+ return bcmsdh; -+} -+ -+int -+bcmsdh_detach(osl_t *osh, void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ if (bcmsdh != NULL) { -+ if (bcmsdh->sdioh) { -+ sdioh_detach(osh, bcmsdh->sdioh); -+ bcmsdh->sdioh = NULL; -+ } -+ MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t)); -+ } -+ -+ l_bcmsdh = NULL; -+ return 0; -+} -+ -+int -+bcmsdh_iovar_op(void *sdh, const char *name, -+ void *params, int plen, void *arg, int len, bool set) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set); -+} -+ -+bool -+bcmsdh_intr_query(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ bool on; -+ -+ ASSERT(bcmsdh); -+ status = sdioh_interrupt_query(bcmsdh->sdioh, &on); -+ if (SDIOH_API_SUCCESS(status)) -+ return FALSE; -+ else -+ return on; -+} -+ -+int -+bcmsdh_intr_enable(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ ASSERT(bcmsdh); -+ -+ status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE); -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+int -+bcmsdh_intr_disable(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ ASSERT(bcmsdh); -+ -+ status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE); -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+int -+bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ ASSERT(bcmsdh); -+ -+ status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+int -+bcmsdh_intr_dereg(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ ASSERT(bcmsdh); -+ -+ status = sdioh_interrupt_deregister(bcmsdh->sdioh); -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+#if defined(DHD_DEBUG) -+bool -+bcmsdh_intr_pending(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ ASSERT(sdh); -+ return sdioh_interrupt_pending(bcmsdh->sdioh); -+} -+#endif -+ -+ -+int -+bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -+{ -+ ASSERT(sdh); -+ -+ /* don't support yet */ -+ return BCME_UNSUPPORTED; -+} -+ -+/** -+ * Read from SDIO Configuration Space -+ * @param sdh SDIO Host context. -+ * @param func_num Function number to read from. -+ * @param addr Address to read from. -+ * @param err Error return. -+ * @return value read from SDIO configuration space. -+ */ -+uint8 -+bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ int32 retry = 0; -+#endif -+ uint8 data = 0; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ do { -+ if (retry) /* wait for 1 ms till bus get settled down */ -+ OSL_DELAY(1000); -+#endif -+ status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -+#endif -+ if (err) -+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, -+ fnc_num, addr, data)); -+ -+ return data; -+} -+ -+void -+bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ int32 retry = 0; -+#endif -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ do { -+ if (retry) /* wait for 1 ms till bus get settled down */ -+ OSL_DELAY(1000); -+#endif -+ status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data); -+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT -+ } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -+#endif -+ if (err) -+ *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR; -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__, -+ fnc_num, addr, data)); -+} -+ -+uint32 -+bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ uint32 data = 0; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num, -+ addr, &data, 4); -+ -+ if (err) -+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, -+ fnc_num, addr, data)); -+ -+ return data; -+} -+ -+void -+bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num, -+ addr, &data, 4); -+ -+ if (err) -+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num, -+ addr, data)); -+} -+ -+ -+int -+bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ -+ uint8 *tmp_buf, *tmp_ptr; -+ uint8 *ptr; -+ bool ascii = func & ~0xf; -+ func &= 0x7; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ ASSERT(cis); -+ ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT); -+ -+ status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length); -+ -+ if (ascii) { -+ /* Move binary bits to tmp and format them into the provided buffer. */ -+ if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) { -+ BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__)); -+ return BCME_NOMEM; -+ } -+ bcopy(cis, tmp_buf, length); -+ for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) { -+ ptr += snprintf((char*)ptr, (cis + length - ptr - 4), -+ "%.2x ", *tmp_ptr & 0xff); -+ if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0) -+ ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n"); -+ } -+ MFREE(bcmsdh->osh, tmp_buf, length); -+ } -+ -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+ -+int -+bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set) -+{ -+ int err = 0; -+ uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK; -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ if (bar0 != bcmsdh->sbwad || force_set) { -+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, -+ (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); -+ if (!err) -+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, -+ (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); -+ if (!err) -+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, -+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); -+ -+ if (!err) -+ bcmsdh->sbwad = bar0; -+ else -+ /* invalidate cached window var */ -+ bcmsdh->sbwad = 0; -+ -+ } -+ -+ return err; -+} -+ -+uint32 -+bcmsdh_reg_read(void *sdh, uint32 addr, uint size) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ uint32 word = 0; -+ -+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr)); -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+ if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)) -+ return 0xFFFFFFFF; -+ -+ addr &= SBSDIO_SB_OFT_ADDR_MASK; -+ if (size == 4) -+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -+ -+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, -+ SDIOH_READ, SDIO_FUNC_1, addr, &word, size); -+ -+ bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); -+ -+ BCMSDH_INFO(("uint32data = 0x%x\n", word)); -+ -+ /* if ok, return appropriately masked word */ -+ if (SDIOH_API_SUCCESS(status)) { -+ switch (size) { -+ case sizeof(uint8): -+ return (word & 0xff); -+ case sizeof(uint16): -+ return (word & 0xffff); -+ case sizeof(uint32): -+ return word; -+ default: -+ bcmsdh->regfail = TRUE; -+ -+ } -+ } -+ -+ /* otherwise, bad sdio access or invalid size */ -+ BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size)); -+ return 0xFFFFFFFF; -+} -+ -+uint32 -+bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ int err = 0; -+ -+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", -+ __FUNCTION__, addr, size*8, data)); -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ ASSERT(bcmsdh->init_success); -+ -+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) -+ return err; -+ -+ addr &= SBSDIO_SB_OFT_ADDR_MASK; -+ if (size == 4) -+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, -+ addr, &data, size); -+ bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); -+ -+ if (SDIOH_API_SUCCESS(status)) -+ return 0; -+ -+ BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", -+ __FUNCTION__, data, addr, size)); -+ return 0xFFFFFFFF; -+} -+ -+bool -+bcmsdh_regfail(void *sdh) -+{ -+ return ((bcmsdh_info_t *)sdh)->regfail; -+} -+ -+int -+bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, void *pkt, -+ bcmsdh_cmplt_fn_t complete_fn, void *handle) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ uint incr_fix; -+ uint width; -+ int err = 0; -+ -+ ASSERT(bcmsdh); -+ ASSERT(bcmsdh->init_success); -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", -+ __FUNCTION__, fn, addr, nbytes)); -+ -+ /* Async not implemented yet */ -+ ASSERT(!(flags & SDIO_REQ_ASYNC)); -+ if (flags & SDIO_REQ_ASYNC) -+ return BCME_UNSUPPORTED; -+ -+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) -+ return err; -+ -+ addr &= SBSDIO_SB_OFT_ADDR_MASK; -+ -+ incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; -+ width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; -+ if (width == 4) -+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -+ -+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, -+ SDIOH_READ, fn, addr, width, nbytes, buf, pkt); -+ -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR); -+} -+ -+int -+bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, void *pkt, -+ bcmsdh_cmplt_fn_t complete_fn, void *handle) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ uint incr_fix; -+ uint width; -+ int err = 0; -+ -+ ASSERT(bcmsdh); -+ ASSERT(bcmsdh->init_success); -+ -+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", -+ __FUNCTION__, fn, addr, nbytes)); -+ -+ /* Async not implemented yet */ -+ ASSERT(!(flags & SDIO_REQ_ASYNC)); -+ if (flags & SDIO_REQ_ASYNC) -+ return BCME_UNSUPPORTED; -+ -+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) -+ return err; -+ -+ addr &= SBSDIO_SB_OFT_ADDR_MASK; -+ -+ incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; -+ width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; -+ if (width == 4) -+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -+ -+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, -+ SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); -+ -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+int -+bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ SDIOH_API_RC status; -+ -+ ASSERT(bcmsdh); -+ ASSERT(bcmsdh->init_success); -+ ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0); -+ -+ addr &= SBSDIO_SB_OFT_ADDR_MASK; -+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; -+ -+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC, -+ (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, -+ addr, 4, nbytes, buf, NULL); -+ -+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR); -+} -+ -+int -+bcmsdh_abort(void *sdh, uint fn) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ return sdioh_abort(bcmsdh->sdioh, fn); -+} -+ -+int -+bcmsdh_start(void *sdh, int stage) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ return sdioh_start(bcmsdh->sdioh, stage); -+} -+ -+int -+bcmsdh_stop(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ return sdioh_stop(bcmsdh->sdioh); -+} -+ -+int -+bcmsdh_waitlockfree(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ return sdioh_waitlockfree(bcmsdh->sdioh); -+} -+ -+ -+int -+bcmsdh_query_device(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; -+ return (bcmsdh->vendevid); -+} -+ -+uint -+bcmsdh_query_iofnum(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ return (sdioh_query_iofnum(bcmsdh->sdioh)); -+} -+ -+int -+bcmsdh_reset(bcmsdh_info_t *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ return sdioh_sdio_reset(bcmsdh->sdioh); -+} -+ -+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh) -+{ -+ ASSERT(sdh); -+ return sdh->sdioh; -+} -+ -+/* Function to pass device-status bits to DHD. */ -+uint32 -+bcmsdh_get_dstatus(void *sdh) -+{ -+ return 0; -+} -+uint32 -+bcmsdh_cur_sbwad(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ -+ if (!bcmsdh) -+ bcmsdh = l_bcmsdh; -+ -+ return (bcmsdh->sbwad); -+} -+ -+void -+bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev) -+{ -+ return; -+} -+ -+ -+int -+bcmsdh_sleep(void *sdh, bool enab) -+{ -+#ifdef SDIOH_SLEEP_ENABLED -+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; -+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); -+ -+ return sdioh_sleep(sd, enab); -+#else -+ return BCME_UNSUPPORTED; -+#endif -+} -+ -+int -+bcmsdh_gpio_init(void *sdh) -+{ -+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; -+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); -+ -+ return sdioh_gpio_init(sd); -+} -+ -+bool -+bcmsdh_gpioin(void *sdh, uint32 gpio) -+{ -+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; -+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); -+ -+ return sdioh_gpioin(sd, gpio); -+} -+ -+int -+bcmsdh_gpioouten(void *sdh, uint32 gpio) -+{ -+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; -+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); -+ -+ return sdioh_gpioouten(sd, gpio); -+} -+ -+int -+bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab) -+{ -+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; -+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); -+ -+ return sdioh_gpioout(sd, gpio, enab); -+} -+ -+#ifdef BCMSDIOH_TXGLOM -+void -+bcmsdh_glom_post(void *sdh, uint8 *frame, uint len) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ sdioh_glom_post(bcmsdh->sdioh, frame, len); -+} -+ -+void -+bcmsdh_glom_clear(void *sdh) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ sdioh_glom_clear(bcmsdh->sdioh); -+} -+ -+uint -+bcmsdh_set_mode(void *sdh, uint mode) -+{ -+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; -+ return (sdioh_set_mode(bcmsdh->sdioh, mode)); -+} -+ -+bool -+bcmsdh_glom_enabled(void) -+{ -+ return (sdioh_glom_enabled()); -+} -+#endif /* BCMSDIOH_TXGLOM */ -diff --git a/drivers/net/wireless/ap6210/bcmsdh_linux.c b/drivers/net/wireless/ap6210/bcmsdh_linux.c -new file mode 100644 -index 0000000..71bb3d9 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmsdh_linux.c -@@ -0,0 +1,796 @@ -+/* -+ * SDIO access interface for drivers - linux specific (pci only) -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh_linux.c 373359 2012-12-07 06:36:37Z $ -+ */ -+ -+/** -+ * @file bcmsdh_linux.c -+ */ -+ -+#define __UNDEF_NO_VERSION__ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(OOB_INTR_ONLY) -+#include -+extern void dhdsdio_isr(void * args); -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+#include -+ -+/** -+ * SDIO Host Controller info -+ */ -+typedef struct bcmsdh_hc bcmsdh_hc_t; -+ -+struct bcmsdh_hc { -+ bcmsdh_hc_t *next; -+#ifdef BCMPLATFORM_BUS -+ struct device *dev; /* platform device handle */ -+#else -+ struct pci_dev *dev; /* pci device handle */ -+#endif /* BCMPLATFORM_BUS */ -+ osl_t *osh; -+ void *regs; /* SDIO Host Controller address */ -+ bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ -+ void *ch; -+ unsigned int oob_irq; -+ unsigned long oob_flags; /* OOB Host specifiction as edge and etc */ -+ bool oob_irq_registered; -+ bool oob_irq_enable_flag; -+#if defined(OOB_INTR_ONLY) -+ spinlock_t irq_lock; -+#endif -+}; -+static bcmsdh_hc_t *sdhcinfo = NULL; -+ -+/* driver info, initialized when bcmsdh_register is called */ -+static bcmsdh_driver_t drvinfo = {NULL, NULL}; -+ -+/** -+ * Checks to see if vendor and device IDs match a supported SDIO Host Controller. -+ */ -+bool -+bcmsdh_chipmatch(uint16 vendor, uint16 device) -+{ -+ /* Add other vendors and devices as required */ -+ -+#ifdef BCMSDIOH_STD -+ /* Check for Arasan host controller */ -+ if (vendor == VENDOR_SI_IMAGE) { -+ return (TRUE); -+ } -+ /* Check for BRCM 27XX Standard host controller */ -+ if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) { -+ return (TRUE); -+ } -+ /* Check for BRCM Standard host controller */ -+ if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) { -+ return (TRUE); -+ } -+ /* Check for TI PCIxx21 Standard host controller */ -+ if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) { -+ return (TRUE); -+ } -+ if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) { -+ return (TRUE); -+ } -+ /* Ricoh R5C822 Standard SDIO Host */ -+ if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) { -+ return (TRUE); -+ } -+ /* JMicron Standard SDIO Host */ -+ if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) { -+ return (TRUE); -+ } -+ -+#endif /* BCMSDIOH_STD */ -+#ifdef BCMSDIOH_SPI -+ /* This is the PciSpiHost. */ -+ if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { -+ AP6210_ERR("Found PCI SPI Host Controller\n"); -+ return (TRUE); -+ } -+ -+#endif /* BCMSDIOH_SPI */ -+ -+ return (FALSE); -+} -+ -+#if defined(BCMPLATFORM_BUS) -+#if defined(BCMLXSDMMC) -+/* forward declarations */ -+int bcmsdh_probe(struct device *dev); -+int bcmsdh_remove(struct device *dev); -+ -+EXPORT_SYMBOL(bcmsdh_probe); -+EXPORT_SYMBOL(bcmsdh_remove); -+ -+#else -+/* forward declarations */ -+static int __devinit bcmsdh_probe(struct device *dev); -+static int __devexit bcmsdh_remove(struct device *dev); -+#endif -+ -+#if !defined(BCMLXSDMMC) -+static -+#endif -+int bcmsdh_probe(struct device *dev) -+{ -+ osl_t *osh = NULL; -+ bcmsdh_hc_t *sdhc = NULL; -+ ulong regs = 0; -+ bcmsdh_info_t *sdh = NULL; -+#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) -+ struct platform_device *pdev; -+ struct resource *r; -+#endif -+ int irq = 0; -+ uint32 vendevid; -+ unsigned long irq_flags = 0; -+ -+#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) -+ pdev = to_platform_device(dev); -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ irq = platform_get_irq(pdev, 0); -+ if (!r || irq == NO_IRQ) -+ return -ENXIO; -+#endif -+ -+#if defined(OOB_INTR_ONLY) -+#ifdef HW_OOB -+ irq_flags = -+ IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; -+#else -+ irq_flags = IRQF_TRIGGER_FALLING; -+#endif /* HW_OOB */ -+ -+ /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */ -+ irq = dhd_customer_oob_irq_map(&irq_flags); -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) -+ /* Do not disable this IRQ during suspend */ -+ irq_flags |= IRQF_NO_SUSPEND; -+#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */ -+ if (irq < 0) { -+ AP6210_ERR("%s: Host irq is not defined\n", __FUNCTION__); -+ return 1; -+ } -+#endif -+ /* allocate SDIO Host Controller state info */ -+ if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) { -+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { -+ AP6210_ERR("%s: out of memory, allocated %d bytes\n", -+ __FUNCTION__, -+ MALLOCED(osh)); -+ goto err; -+ } -+ bzero(sdhc, sizeof(bcmsdh_hc_t)); -+ sdhc->osh = osh; -+ -+ sdhc->dev = (void *)dev; -+ -+#if defined(BCMLXSDMMC) -+ if (!(sdh = bcmsdh_attach(osh, (void *)0, -+ (void **)®s, irq))) { -+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+#else -+ if (!(sdh = bcmsdh_attach(osh, (void *)r->start, -+ (void **)®s, irq))) { -+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+#endif -+ sdhc->sdh = sdh; -+ sdhc->oob_irq = irq; -+ sdhc->oob_flags = irq_flags; -+ sdhc->oob_irq_registered = FALSE; /* to make sure.. */ -+ sdhc->oob_irq_enable_flag = FALSE; -+#if defined(OOB_INTR_ONLY) -+ spin_lock_init(&sdhc->irq_lock); -+#endif -+ -+ /* chain SDIO Host Controller info together */ -+ sdhc->next = sdhcinfo; -+ sdhcinfo = sdhc; -+ -+ /* Read the vendor/device ID from the CIS */ -+ vendevid = bcmsdh_query_device(sdh); -+ /* try to attach to the target device */ -+ if (!(sdhc->ch = drvinfo.attach((vendevid >> 16), -+ (vendevid & 0xFFFF), 0, 0, 0, 0, -+ (void *)regs, NULL, sdh))) { -+ AP6210_ERR("%s: device attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ return 0; -+ -+ /* error handling */ -+err: -+ if (sdhc) { -+ if (sdhc->sdh) -+ bcmsdh_detach(sdhc->osh, sdhc->sdh); -+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); -+ } -+ if (osh) -+ osl_detach(osh); -+ return -ENODEV; -+} -+ -+#if !defined(BCMLXSDMMC) -+static -+#endif -+int bcmsdh_remove(struct device *dev) -+{ -+ bcmsdh_hc_t *sdhc, *prev; -+ osl_t *osh; -+ -+ sdhc = sdhcinfo; -+ drvinfo.detach(sdhc->ch); -+ bcmsdh_detach(sdhc->osh, sdhc->sdh); -+ -+ /* find the SDIO Host Controller state for this pdev and take it out from the list */ -+ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { -+ if (sdhc->dev == (void *)dev) { -+ if (prev) -+ prev->next = sdhc->next; -+ else -+ sdhcinfo = NULL; -+ break; -+ } -+ prev = sdhc; -+ } -+ if (!sdhc) { -+ AP6210_ERR("%s: failed\n", __FUNCTION__); -+ return 0; -+ } -+ -+ /* release SDIO Host Controller info */ -+ osh = sdhc->osh; -+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); -+ osl_detach(osh); -+ -+#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY) -+ dev_set_drvdata(dev, NULL); -+#endif -+ -+ return 0; -+} -+ -+#else /* BCMPLATFORM_BUS */ -+ -+#if !defined(BCMLXSDMMC) -+/* forward declarations for PCI probe and remove functions. */ -+static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -+static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); -+ -+/** -+ * pci id table -+ */ -+static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { -+ { vendor: PCI_ANY_ID, -+ device: PCI_ANY_ID, -+ subvendor: PCI_ANY_ID, -+ subdevice: PCI_ANY_ID, -+ class: 0, -+ class_mask: 0, -+ driver_data: 0, -+ }, -+ { 0, } -+}; -+MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); -+ -+/** -+ * SDIO Host Controller pci driver info -+ */ -+static struct pci_driver bcmsdh_pci_driver = { -+ node: {}, -+ name: "bcmsdh", -+ id_table: bcmsdh_pci_devid, -+ probe: bcmsdh_pci_probe, -+ remove: bcmsdh_pci_remove, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+ save_state: NULL, -+#endif -+ suspend: NULL, -+ resume: NULL, -+ }; -+ -+ -+extern uint sd_pci_slot; /* Force detection to a particular PCI */ -+ /* slot only . Allows for having multiple */ -+ /* WL devices at once in a PC */ -+ /* Only one instance of dhd will be */ -+ /* usable at a time */ -+ /* Upper word is bus number, */ -+ /* lower word is slot number */ -+ /* Default value of 0xffffffff turns this */ -+ /* off */ -+module_param(sd_pci_slot, uint, 0); -+ -+ -+/** -+ * Detect supported SDIO Host Controller and attach if found. -+ * -+ * Determine if the device described by pdev is a supported SDIO Host -+ * Controller. If so, attach to it and attach to the target device. -+ */ -+static int __devinit -+bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -+{ -+ osl_t *osh = NULL; -+ bcmsdh_hc_t *sdhc = NULL; -+ ulong regs; -+ bcmsdh_info_t *sdh = NULL; -+ int rc; -+ -+ if (sd_pci_slot != 0xFFFFffff) { -+ if (pdev->bus->number != (sd_pci_slot>>16) || -+ PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) { -+ AP6210_DEBUG("%s: %s: bus %X, slot %X, vend %X, dev %X\n", -+ __FUNCTION__, -+ bcmsdh_chipmatch(pdev->vendor, pdev->device) -+ ?"Found compatible SDIOHC" -+ :"Probing unknown device", -+ pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, -+ pdev->device); -+ return -ENODEV; -+ } -+ AP6210_DEBUG("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n", -+ __FUNCTION__, -+ bcmsdh_chipmatch(pdev->vendor, pdev->device) -+ ?"Using compatible SDIOHC" -+ :"WARNING, forced use of unkown device", -+ pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device); -+ } -+ -+ if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) || -+ (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { -+ uint32 config_reg; -+ -+ AP6210_ERR("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__); -+ if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { -+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); -+ -+ /* -+ * Set MMC_SD_DIS bit in FlashMedia Controller. -+ * Disbling the SD/MMC Controller in the FlashMedia Controller -+ * allows the Standard SD Host Controller to take over control -+ * of the SD Slot. -+ */ -+ config_reg |= 0x02; -+ OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); -+ osl_detach(osh); -+ } -+ /* match this pci device with what we support */ -+ /* we can't solely rely on this to believe it is our SDIO Host Controller! */ -+ if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { -+ return -ENODEV; -+ } -+ -+ /* this is a pci device we might support */ -+ AP6210_ERR("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n", -+ __FUNCTION__, -+ pdev->bus->number, PCI_SLOT(pdev->devfn), -+ PCI_FUNC(pdev->devfn), pdev->irq); -+ -+ /* use bcmsdh_query_device() to get the vendor ID of the target device so -+ * it will eventually appear in the Broadcom string on the console -+ */ -+ -+ /* allocate SDIO Host Controller state info */ -+ if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) { -+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) { -+ AP6210_ERR("%s: out of memory, allocated %d bytes\n", -+ __FUNCTION__, -+ MALLOCED(osh)); -+ goto err; -+ } -+ bzero(sdhc, sizeof(bcmsdh_hc_t)); -+ sdhc->osh = osh; -+ -+ sdhc->dev = pdev; -+ -+ /* map to address where host can access */ -+ pci_set_master(pdev); -+ rc = pci_enable_device(pdev); -+ if (rc) { -+ AP6210_ERR("%s: Cannot enable PCI device\n", __FUNCTION__); -+ goto err; -+ } -+ if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0), -+ (void **)®s, pdev->irq))) { -+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ sdhc->sdh = sdh; -+ -+ /* try to attach to the target device */ -+ if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ -+ bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, -+ (void *)regs, NULL, sdh))) { -+ AP6210_ERR("%s: device attach failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ /* chain SDIO Host Controller info together */ -+ sdhc->next = sdhcinfo; -+ sdhcinfo = sdhc; -+ -+ return 0; -+ -+ /* error handling */ -+err: -+ if (sdhc) { -+ if (sdhc->sdh) -+ bcmsdh_detach(sdhc->osh, sdhc->sdh); -+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); -+ } -+ if (osh) -+ osl_detach(osh); -+ return -ENODEV; -+} -+ -+ -+/** -+ * Detach from target devices and SDIO Host Controller -+ */ -+static void __devexit -+bcmsdh_pci_remove(struct pci_dev *pdev) -+{ -+ bcmsdh_hc_t *sdhc, *prev; -+ osl_t *osh; -+ -+ /* find the SDIO Host Controller state for this pdev and take it out from the list */ -+ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { -+ if (sdhc->dev == pdev) { -+ if (prev) -+ prev->next = sdhc->next; -+ else -+ sdhcinfo = NULL; -+ break; -+ } -+ prev = sdhc; -+ } -+ if (!sdhc) -+ return; -+ -+ drvinfo.detach(sdhc->ch); -+ -+ bcmsdh_detach(sdhc->osh, sdhc->sdh); -+ -+ /* release SDIO Host Controller info */ -+ osh = sdhc->osh; -+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); -+ osl_detach(osh); -+} -+#endif /* BCMLXSDMMC */ -+#endif /* BCMPLATFORM_BUS */ -+ -+extern int sdio_function_init(void); -+ -+extern int sdio_func_reg_notify(void* semaphore); -+extern void sdio_func_unreg_notify(void); -+ -+#if defined(BCMLXSDMMC) -+int bcmsdh_reg_sdio_notify(void* semaphore) -+{ -+ return sdio_func_reg_notify(semaphore); -+} -+ -+void bcmsdh_unreg_sdio_notify(void) -+{ -+ sdio_func_unreg_notify(); -+} -+#endif /* defined(BCMLXSDMMC) */ -+ -+int -+bcmsdh_register(bcmsdh_driver_t *driver) -+{ -+ int error = 0; -+ -+ drvinfo = *driver; -+ -+#if defined(BCMPLATFORM_BUS) -+ AP6210_ERR("Linux Kernel SDIO/MMC Driver\n"); -+ error = sdio_function_init(); -+ return error; -+#endif /* defined(BCMPLATFORM_BUS) */ -+ -+#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+ if (!(error = pci_module_init(&bcmsdh_pci_driver))) -+ return 0; -+#else -+ if (!(error = pci_register_driver(&bcmsdh_pci_driver))) -+ return 0; -+#endif -+ -+ AP6210_ERR("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error); -+#endif /* BCMPLATFORM_BUS */ -+ -+ return error; -+} -+ -+extern void sdio_function_cleanup(void); -+ -+void -+bcmsdh_unregister(void) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+ if (bcmsdh_pci_driver.node.next) -+#endif -+ -+#if defined(BCMLXSDMMC) -+ sdio_function_cleanup(); -+#endif /* BCMLXSDMMC */ -+ -+#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) -+ pci_unregister_driver(&bcmsdh_pci_driver); -+#endif /* BCMPLATFORM_BUS */ -+} -+ -+int bcmsdh_set_drvdata(void * dhdp) -+{ -+ AP6210_DEBUG("%s Enter \n", __FUNCTION__); -+ -+ dev_set_drvdata(sdhcinfo->dev, dhdp); -+ -+ return 0; -+} -+ -+#if defined(OOB_INTR_ONLY) -+#define CONFIG_ARCH_SUN6I_AP6210 1 -+ -+void bcmsdh_oob_intr_set(bool enable) -+{ -+ static bool curstate = 1; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sdhcinfo->irq_lock, flags); -+ if (curstate != enable) { -+ if(enable) { -+ enable_irq(sdhcinfo->oob_irq); -+ } -+ else { -+ disable_irq_nosync(sdhcinfo->oob_irq); -+ } -+ curstate = enable; -+ } -+ -+ spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); -+} -+ -+static irqreturn_t wlan_oob_irq(int irq, void *dev_id) -+{ -+ dhd_pub_t *dhdp; -+ -+ dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev); -+ -+ bcmsdh_oob_intr_set(0); -+ -+ if (dhdp == NULL) { -+ AP6210_ERR("Out of band GPIO interrupt fired way too early\n"); -+ return IRQ_HANDLED; -+ } -+ -+ dhdsdio_isr((void *)dhdp->bus); -+ -+ return IRQ_HANDLED; -+} -+ -+extern int wl_host_wake_irqno; -+irqreturn_t bcmdhd_gpio_irq_handler(int irq, void *dev) -+{ -+ wlan_oob_irq(0, NULL); -+ return IRQ_HANDLED; -+} -+ -+int bcmsdh_register_oob_intr(void * dhdp) -+{ -+ int error = 0; -+ int ret; -+ AP6210_DEBUG("%s Enter \n", __FUNCTION__); -+ -+ /* IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ -+ dev_set_drvdata(sdhcinfo->dev, dhdp); -+ -+ if (!sdhcinfo->oob_irq_registered) { -+ AP6210_DEBUG("%s IRQ=%d Type=%X \n", __FUNCTION__, -+ (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags); -+ -+ ret = request_irq(wl_host_wake_irqno, bcmdhd_gpio_irq_handler, IRQF_DISABLED| IRQF_SHARED| IRQF_TRIGGER_HIGH, "bcmdhd_gpio_irq", (void *)&wl_host_wake_irqno); -+ if (ret) { -+ AP6210_ERR("request irq%d failed\n", wl_host_wake_irqno); -+ return -1; -+ } -+ -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210) -+ if (device_may_wakeup(sdhcinfo->dev)) { -+#endif -+ error = enable_irq_wake(sdhcinfo->oob_irq); -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210) -+ } -+#endif -+ if (error) -+ AP6210_ERR("%s enable_irq_wake error=%d \n", __FUNCTION__, error); -+ sdhcinfo->oob_irq_registered = TRUE; -+ sdhcinfo->oob_irq_enable_flag = TRUE; -+ } -+ -+ return 0; -+} -+ -+void bcmsdh_set_irq(int flag) -+{ -+ if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) { -+ AP6210_ERR("%s Flag = %d\n", __FUNCTION__, flag); -+ sdhcinfo->oob_irq_enable_flag = flag; -+ if (flag) { -+ enable_irq(sdhcinfo->oob_irq); -+ -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210) -+ if (device_may_wakeup(sdhcinfo->dev)) -+#endif -+ enable_irq_wake(sdhcinfo->oob_irq); -+ } else { -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210) -+ if (device_may_wakeup(sdhcinfo->dev)) -+#endif -+ disable_irq_wake(sdhcinfo->oob_irq); -+ -+ -+ disable_irq(sdhcinfo->oob_irq); -+ } -+ } -+} -+ -+void bcmsdh_unregister_oob_intr(void) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (sdhcinfo->oob_irq_registered == TRUE) { -+ -+ if(0 != wl_host_wake_irqno) { -+ AP6210_DEBUG("free_irq %d\n", wl_host_wake_irqno); -+ free_irq(wl_host_wake_irqno, &wl_host_wake_irqno); -+ } -+ -+ sdhcinfo->oob_irq_registered = FALSE; -+ } -+} -+#endif -+ -+#if defined(BCMLXSDMMC) -+void *bcmsdh_get_drvdata(void) -+{ -+ if (!sdhcinfo) -+ return NULL; -+ return dev_get_drvdata(sdhcinfo->dev); -+} -+#endif -+ -+/* Module parameters specific to each host-controller driver */ -+ -+extern uint sd_msglevel; /* Debug message level */ -+module_param(sd_msglevel, uint, 0); -+ -+extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */ -+module_param(sd_power, uint, 0); -+ -+extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */ -+module_param(sd_clock, uint, 0); -+ -+extern uint sd_divisor; /* Divisor (-1 means external clock) */ -+module_param(sd_divisor, uint, 0); -+ -+extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ -+module_param(sd_sdmode, uint, 0); -+ -+extern uint sd_hiok; /* Ok to use hi-speed mode */ -+module_param(sd_hiok, uint, 0); -+ -+extern uint sd_f2_blocksize; -+module_param(sd_f2_blocksize, int, 0); -+ -+#ifdef BCMSDIOH_STD -+extern int sd_uhsimode; -+module_param(sd_uhsimode, int, 0); -+#endif -+ -+#ifdef BCMSDIOH_TXGLOM -+extern uint sd_txglom; -+module_param(sd_txglom, uint, 0); -+#endif -+ -+#ifdef BCMSDH_MODULE -+EXPORT_SYMBOL(bcmsdh_attach); -+EXPORT_SYMBOL(bcmsdh_detach); -+EXPORT_SYMBOL(bcmsdh_intr_query); -+EXPORT_SYMBOL(bcmsdh_intr_enable); -+EXPORT_SYMBOL(bcmsdh_intr_disable); -+EXPORT_SYMBOL(bcmsdh_intr_reg); -+EXPORT_SYMBOL(bcmsdh_intr_dereg); -+ -+#if defined(DHD_DEBUG) -+EXPORT_SYMBOL(bcmsdh_intr_pending); -+#endif -+ -+EXPORT_SYMBOL(bcmsdh_devremove_reg); -+EXPORT_SYMBOL(bcmsdh_cfg_read); -+EXPORT_SYMBOL(bcmsdh_cfg_write); -+EXPORT_SYMBOL(bcmsdh_cis_read); -+EXPORT_SYMBOL(bcmsdh_reg_read); -+EXPORT_SYMBOL(bcmsdh_reg_write); -+EXPORT_SYMBOL(bcmsdh_regfail); -+EXPORT_SYMBOL(bcmsdh_send_buf); -+EXPORT_SYMBOL(bcmsdh_recv_buf); -+ -+EXPORT_SYMBOL(bcmsdh_rwdata); -+EXPORT_SYMBOL(bcmsdh_abort); -+EXPORT_SYMBOL(bcmsdh_query_device); -+EXPORT_SYMBOL(bcmsdh_query_iofnum); -+EXPORT_SYMBOL(bcmsdh_iovar_op); -+EXPORT_SYMBOL(bcmsdh_register); -+EXPORT_SYMBOL(bcmsdh_unregister); -+EXPORT_SYMBOL(bcmsdh_chipmatch); -+EXPORT_SYMBOL(bcmsdh_reset); -+EXPORT_SYMBOL(bcmsdh_waitlockfree); -+ -+EXPORT_SYMBOL(bcmsdh_get_dstatus); -+EXPORT_SYMBOL(bcmsdh_cfg_read_word); -+EXPORT_SYMBOL(bcmsdh_cfg_write_word); -+EXPORT_SYMBOL(bcmsdh_cur_sbwad); -+EXPORT_SYMBOL(bcmsdh_chipinfo); -+ -+#endif /* BCMSDH_MODULE */ -diff --git a/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c b/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c -new file mode 100644 -index 0000000..5f0d300 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c -@@ -0,0 +1,1532 @@ -+/* -+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh_sdmmc.c 362913 2012-10-15 11:26:11Z $ -+ */ -+#include -+ -+#include -+#include -+#include -+#include -+#include /* SDIO Device and Protocol Specs */ -+#include /* Standard SDIO Host Controller Specification */ -+#include /* bcmsdh to/from specific controller APIs */ -+#include /* ioctl/iovars */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+#include -+extern volatile bool dhd_mmc_suspend; -+#endif -+#include "bcmsdh_sdmmc.h" -+ -+#include -+ -+#ifndef BCMSDH_MODULE -+extern int sdio_function_init(void); -+extern void sdio_function_cleanup(void); -+#endif /* BCMSDH_MODULE */ -+ -+#if !defined(OOB_INTR_ONLY) -+static void IRQHandler(struct sdio_func *func); -+static void IRQHandlerF2(struct sdio_func *func); -+#endif /* !defined(OOB_INTR_ONLY) */ -+static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr); -+extern int sdio_reset_comm(struct mmc_card *card); -+extern int sw_mci_check_r1_ready(struct mmc_host* mmc, unsigned ms); -+ -+extern PBCMSDH_SDMMC_INSTANCE gInstance; -+ -+#define DEFAULT_SDIO_F2_BLKSIZE 512 -+#ifndef CUSTOM_SDIO_F2_BLKSIZE -+#define CUSTOM_SDIO_F2_BLKSIZE DEFAULT_SDIO_F2_BLKSIZE -+#endif -+ -+uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -+uint sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE; -+uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ -+ -+uint sd_power = 1; /* Default to SD Slot powered ON */ -+uint sd_clock = 1; /* Default to SD Clock turned ON */ -+uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */ -+uint sd_msglevel = 0x01; -+uint sd_use_dma = TRUE; -+DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -+DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -+DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -+DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); -+ -+#define DMA_ALIGN_MASK 0x03 -+#define MMC_SDIO_ABORT_RETRY_LIMIT 5 -+ -+int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data); -+ -+static int -+sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) -+{ -+ int err_ret; -+ uint32 fbraddr; -+ uint8 func; -+ -+ AP6210_DEBUG("%s\n", __FUNCTION__);; -+ -+ /* Get the Card's common CIS address */ -+ sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); -+ sd->func_cis_ptr[0] = sd->com_cis_ptr; -+ AP6210_DEBUG("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr); -+ -+ /* Get the Card's function CIS (for each function) */ -+ for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; -+ func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { -+ sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); -+ AP6210_DEBUG("%s: Function %d CIS Ptr = 0x%x\n", -+ __FUNCTION__, func, sd->func_cis_ptr[func]); -+ } -+ -+ sd->func_cis_ptr[0] = sd->com_cis_ptr; -+ AP6210_DEBUG("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr); -+ -+ /* Enable Function 1 */ -+ sdio_claim_host(gInstance->func[1]); -+ err_ret = sdio_enable_func(gInstance->func[1]); -+ sdio_release_host(gInstance->func[1]); -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret); -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * Public entry points & extern's -+ */ -+extern sdioh_info_t * -+sdioh_attach(osl_t *osh, void *bar0, uint irq) -+{ -+ sdioh_info_t *sd; -+ int err_ret; -+ -+ AP6210_DEBUG("%s\n", __FUNCTION__); -+ -+ if (gInstance == NULL) { -+ AP6210_ERR("%s: SDIO Device not present\n", __FUNCTION__); -+ return NULL; -+ } -+ -+ if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) { -+ AP6210_ERR("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)); -+ return NULL; -+ } -+ bzero((char *)sd, sizeof(sdioh_info_t)); -+ sd->osh = osh; -+ if (sdioh_sdmmc_osinit(sd) != 0) { -+ AP6210_ERR("%s:sdioh_sdmmc_osinit() failed\n", __FUNCTION__); -+ MFREE(sd->osh, sd, sizeof(sdioh_info_t)); -+ return NULL; -+ } -+ -+ sd->num_funcs = 2; -+ sd->sd_blockmode = TRUE; -+ sd->use_client_ints = TRUE; -+ sd->client_block_size[0] = 64; -+ sd->use_rxchain = FALSE; -+ -+ gInstance->sd = sd; -+ -+ /* Claim host controller */ -+ if (gInstance->func[1]) { -+ sdio_claim_host(gInstance->func[1]); -+ -+ sd->client_block_size[1] = 64; -+ err_ret = sdio_set_block_size(gInstance->func[1], 64); -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F1 blocksize\n"); -+ } -+ -+ /* Release host controller F1 */ -+ sdio_release_host(gInstance->func[1]); -+ } else { -+ AP6210_ERR("%s:gInstance->func[1] is null\n", __FUNCTION__); -+ MFREE(sd->osh, sd, sizeof(sdioh_info_t)); -+ return NULL; -+ } -+ -+ if (gInstance->func[2]) { -+ /* Claim host controller F2 */ -+ sdio_claim_host(gInstance->func[2]); -+ -+ sd->client_block_size[2] = sd_f2_blocksize; -+ err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n", -+ sd_f2_blocksize); -+ } -+ -+ /* Release host controller F2 */ -+ sdio_release_host(gInstance->func[2]); -+ } else { -+ AP6210_ERR("%s:gInstance->func[2] is null\n", __FUNCTION__); -+ MFREE(sd->osh, sd, sizeof(sdioh_info_t)); -+ return NULL; -+ } -+ -+ sdioh_sdmmc_card_enablefuncs(sd); -+ -+ AP6210_DEBUG("%s: Done\n", __FUNCTION__); -+ return sd; -+} -+ -+ -+extern SDIOH_API_RC -+sdioh_detach(osl_t *osh, sdioh_info_t *sd) -+{ -+ AP6210_DEBUG("%s\n", __FUNCTION__); -+ -+ if (sd) { -+ -+ /* Disable Function 2 */ -+ sdio_claim_host(gInstance->func[2]); -+ sdio_disable_func(gInstance->func[2]); -+ sdio_release_host(gInstance->func[2]); -+ -+ /* Disable Function 1 */ -+ if (gInstance->func[1]) { -+ sdio_claim_host(gInstance->func[1]); -+ sdio_disable_func(gInstance->func[1]); -+ sdio_release_host(gInstance->func[1]); -+ } -+ -+ gInstance->func[1] = NULL; -+ gInstance->func[2] = NULL; -+ -+ /* deregister irq */ -+ sdioh_sdmmc_osfree(sd); -+ -+ MFREE(sd->osh, sd, sizeof(sdioh_info_t)); -+ } -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -+ -+extern SDIOH_API_RC -+sdioh_enable_func_intr(void) -+{ -+ uint8 reg; -+ int err; -+ -+ if (gInstance->func[0]) { -+ sdio_claim_host(gInstance->func[0]); -+ -+ reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); -+ if (err) { -+ AP6210_ERR("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err); -+ sdio_release_host(gInstance->func[0]); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ /* Enable F1 and F2 interrupts, set master enable */ -+ reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN); -+ -+ sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); -+ sdio_release_host(gInstance->func[0]); -+ -+ if (err) { -+ AP6210_ERR("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err); -+ return SDIOH_API_RC_FAIL; -+ } -+ } -+ -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+extern SDIOH_API_RC -+sdioh_disable_func_intr(void) -+{ -+ uint8 reg; -+ int err; -+ -+ if (gInstance->func[0]) { -+ sdio_claim_host(gInstance->func[0]); -+ reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); -+ if (err) { -+ AP6210_ERR("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err); -+ sdio_release_host(gInstance->func[0]); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); -+ /* Disable master interrupt with the last function interrupt */ -+ if (!(reg & 0xFE)) -+ reg = 0; -+ sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); -+ -+ sdio_release_host(gInstance->func[0]); -+ if (err) { -+ AP6210_ERR("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err); -+ return SDIOH_API_RC_FAIL; -+ } -+ } -+ return SDIOH_API_RC_SUCCESS; -+} -+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ -+ -+/* Configure callback to client when we recieve client interrupt */ -+extern SDIOH_API_RC -+sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) -+{ -+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__); -+ if (fn == NULL) { -+ AP6210_ERR("%s: interrupt handler is NULL, not registering\n", __FUNCTION__); -+ return SDIOH_API_RC_FAIL; -+ } -+#if !defined(OOB_INTR_ONLY) -+ sd->intr_handler = fn; -+ sd->intr_handler_arg = argh; -+ sd->intr_handler_valid = TRUE; -+ -+ /* register and unmask irq */ -+ if (gInstance->func[2]) { -+ sdio_claim_host(gInstance->func[2]); -+ sdio_claim_irq(gInstance->func[2], IRQHandlerF2); -+ sdio_release_host(gInstance->func[2]); -+ } -+ -+ if (gInstance->func[1]) { -+ sdio_claim_host(gInstance->func[1]); -+ sdio_claim_irq(gInstance->func[1], IRQHandler); -+ sdio_release_host(gInstance->func[1]); -+ } -+#elif defined(HW_OOB) -+ sdioh_enable_func_intr(); -+#endif /* !defined(OOB_INTR_ONLY) */ -+ -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+extern SDIOH_API_RC -+sdioh_interrupt_deregister(sdioh_info_t *sd) -+{ -+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__); -+ -+#if !defined(OOB_INTR_ONLY) -+ if (gInstance->func[1]) { -+ /* register and unmask irq */ -+ sdio_claim_host(gInstance->func[1]); -+ sdio_release_irq(gInstance->func[1]); -+ sdio_release_host(gInstance->func[1]); -+ } -+ -+ if (gInstance->func[2]) { -+ /* Claim host controller F2 */ -+ sdio_claim_host(gInstance->func[2]); -+ sdio_release_irq(gInstance->func[2]); -+ /* Release host controller F2 */ -+ sdio_release_host(gInstance->func[2]); -+ } -+ -+ sd->intr_handler_valid = FALSE; -+ sd->intr_handler = NULL; -+ sd->intr_handler_arg = NULL; -+#elif defined(HW_OOB) -+ sdioh_disable_func_intr(); -+#endif /* !defined(OOB_INTR_ONLY) */ -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+extern SDIOH_API_RC -+sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -+{ -+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__); -+ *onoff = sd->client_intr_enabled; -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+#if defined(DHD_DEBUG) -+extern bool -+sdioh_interrupt_pending(sdioh_info_t *sd) -+{ -+ return (0); -+} -+#endif -+ -+uint -+sdioh_query_iofnum(sdioh_info_t *sd) -+{ -+ return sd->num_funcs; -+} -+ -+/* IOVar table */ -+enum { -+ IOV_MSGLEVEL = 1, -+ IOV_BLOCKMODE, -+ IOV_BLOCKSIZE, -+ IOV_DMA, -+ IOV_USEINTS, -+ IOV_NUMINTS, -+ IOV_NUMLOCALINTS, -+ IOV_HOSTREG, -+ IOV_DEVREG, -+ IOV_DIVISOR, -+ IOV_SDMODE, -+ IOV_HISPEED, -+ IOV_HCIREGS, -+ IOV_POWER, -+ IOV_CLOCK, -+ IOV_RXCHAIN -+}; -+ -+const bcm_iovar_t sdioh_iovars[] = { -+ {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, -+ {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 }, -+ {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */ -+ {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 }, -+ {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 }, -+ {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 }, -+ {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 }, -+ {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, -+ {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, -+ {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 }, -+ {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 }, -+ {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 }, -+ {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}, -+ {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0 }, -+ {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0 }, -+ {NULL, 0, 0, 0, 0 } -+}; -+ -+int -+sdioh_iovar_op(sdioh_info_t *si, const char *name, -+ void *params, int plen, void *arg, int len, bool set) -+{ -+ const bcm_iovar_t *vi = NULL; -+ int bcmerror = 0; -+ int val_size; -+ int32 int_val = 0; -+ bool bool_val; -+ uint32 actionid; -+ -+ ASSERT(name); -+ ASSERT(len >= 0); -+ -+ /* Get must have return space; Set does not take qualifiers */ -+ ASSERT(set || (arg && len)); -+ ASSERT(!set || (!params && !plen)); -+ -+ AP6210_DEBUG("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name); -+ -+ if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) { -+ bcmerror = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ -+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0) -+ goto exit; -+ -+ /* Set up params so get and set can share the convenience variables */ -+ if (params == NULL) { -+ params = arg; -+ plen = len; -+ } -+ -+ if (vi->type == IOVT_VOID) -+ val_size = 0; -+ else if (vi->type == IOVT_BUFFER) -+ val_size = len; -+ else -+ val_size = sizeof(int); -+ -+ if (plen >= (int)sizeof(int_val)) -+ bcopy(params, &int_val, sizeof(int_val)); -+ -+ bool_val = (int_val != 0) ? TRUE : FALSE; -+ BCM_REFERENCE(bool_val); -+ -+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); -+ switch (actionid) { -+ case IOV_GVAL(IOV_MSGLEVEL): -+ int_val = (int32)sd_msglevel; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_MSGLEVEL): -+ sd_msglevel = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_BLOCKMODE): -+ int_val = (int32)si->sd_blockmode; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_BLOCKMODE): -+ si->sd_blockmode = (bool)int_val; -+ /* Haven't figured out how to make non-block mode with DMA */ -+ break; -+ -+ case IOV_GVAL(IOV_BLOCKSIZE): -+ if ((uint32)int_val > si->num_funcs) { -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ int_val = (int32)si->client_block_size[int_val]; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_BLOCKSIZE): -+ { -+ uint func = ((uint32)int_val >> 16); -+ uint blksize = (uint16)int_val; -+ uint maxsize; -+ -+ if (func > si->num_funcs) { -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ switch (func) { -+ case 0: maxsize = 32; break; -+ case 1: maxsize = BLOCK_SIZE_4318; break; -+ case 2: maxsize = BLOCK_SIZE_4328; break; -+ default: maxsize = 0; -+ } -+ if (blksize > maxsize) { -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ if (!blksize) { -+ blksize = maxsize; -+ } -+ -+ /* Now set it */ -+ si->client_block_size[func] = blksize; -+ -+ break; -+ } -+ -+ case IOV_GVAL(IOV_RXCHAIN): -+ int_val = (int32)si->use_rxchain; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_DMA): -+ int_val = (int32)si->sd_use_dma; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_DMA): -+ si->sd_use_dma = (bool)int_val; -+ break; -+ -+ case IOV_GVAL(IOV_USEINTS): -+ int_val = (int32)si->use_client_ints; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_USEINTS): -+ si->use_client_ints = (bool)int_val; -+ if (si->use_client_ints) -+ si->intmask |= CLIENT_INTR; -+ else -+ si->intmask &= ~CLIENT_INTR; -+ -+ break; -+ -+ case IOV_GVAL(IOV_DIVISOR): -+ int_val = (uint32)sd_divisor; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_DIVISOR): -+ sd_divisor = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_POWER): -+ int_val = (uint32)sd_power; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_POWER): -+ sd_power = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_CLOCK): -+ int_val = (uint32)sd_clock; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_CLOCK): -+ sd_clock = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_SDMODE): -+ int_val = (uint32)sd_sdmode; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_SDMODE): -+ sd_sdmode = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_HISPEED): -+ int_val = (uint32)sd_hiok; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_HISPEED): -+ sd_hiok = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_NUMINTS): -+ int_val = (int32)si->intrcount; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_NUMLOCALINTS): -+ int_val = (int32)0; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_HOSTREG): -+ { -+ sdreg_t *sd_ptr = (sdreg_t *)params; -+ -+ if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { -+ AP6210_ERR("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset); -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ AP6210_DEBUG("%s: rreg%d at offset %d\n", __FUNCTION__, -+ (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), -+ sd_ptr->offset); -+ if (sd_ptr->offset & 1) -+ int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */ -+ else if (sd_ptr->offset & 2) -+ int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */ -+ else -+ int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */ -+ -+ bcopy(&int_val, arg, sizeof(int_val)); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_HOSTREG): -+ { -+ sdreg_t *sd_ptr = (sdreg_t *)params; -+ -+ if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) { -+ AP6210_ERR("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset); -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ AP6210_DEBUG("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value, -+ (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32), -+ sd_ptr->offset); -+ break; -+ } -+ -+ case IOV_GVAL(IOV_DEVREG): -+ { -+ sdreg_t *sd_ptr = (sdreg_t *)params; -+ uint8 data = 0; -+ -+ if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) { -+ bcmerror = BCME_SDIO_ERROR; -+ break; -+ } -+ -+ int_val = (int)data; -+ bcopy(&int_val, arg, sizeof(int_val)); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_DEVREG): -+ { -+ sdreg_t *sd_ptr = (sdreg_t *)params; -+ uint8 data = (uint8)sd_ptr->value; -+ -+ if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) { -+ bcmerror = BCME_SDIO_ERROR; -+ break; -+ } -+ break; -+ } -+ -+ default: -+ bcmerror = BCME_UNSUPPORTED; -+ break; -+ } -+exit: -+ -+ return bcmerror; -+} -+ -+#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -+ -+SDIOH_API_RC -+sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable) -+{ -+ SDIOH_API_RC status; -+ uint8 data; -+ -+ if (enable) -+ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI; -+ else -+ data = SDIO_SEPINT_ACT_HI; /* disable hw oob interrupt */ -+ -+ status = sdioh_request_byte(sd, SDIOH_WRITE, 0, SDIOD_CCCR_BRCM_SEPINT, &data); -+ return status; -+} -+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ -+ -+extern SDIOH_API_RC -+sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -+{ -+ SDIOH_API_RC status; -+ /* No lock needed since sdioh_request_byte does locking */ -+ status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); -+ return status; -+} -+ -+extern SDIOH_API_RC -+sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data) -+{ -+ /* No lock needed since sdioh_request_byte does locking */ -+ SDIOH_API_RC status; -+ status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); -+ return status; -+} -+ -+static int -+sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr) -+{ -+ /* read 24 bits and return valid 17 bit addr */ -+ int i; -+ uint32 scratch, regdata; -+ uint8 *ptr = (uint8 *)&scratch; -+ for (i = 0; i < 3; i++) { -+ if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, ®data)) != SUCCESS) -+ AP6210_ERR("%s: Can't read!\n", __FUNCTION__); -+ -+ *ptr++ = (uint8) regdata; -+ regaddr++; -+ } -+ -+ /* Only the lower 17-bits are valid */ -+ scratch = ltoh32(scratch); -+ scratch &= 0x0001FFFF; -+ return (scratch); -+} -+ -+extern SDIOH_API_RC -+sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length) -+{ -+ uint32 count; -+ int offset; -+ uint32 foo; -+ uint8 *cis = cisd; -+ -+ AP6210_DEBUG("%s: Func = %d\n", __FUNCTION__, func); -+ -+ if (!sd->func_cis_ptr[func]) { -+ bzero(cis, length); -+ AP6210_ERR("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ AP6210_ERR("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func]); -+ -+ for (count = 0; count < length; count++) { -+ offset = sd->func_cis_ptr[func] + count; -+ if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) { -+ AP6210_ERR("%s: regread failed: Can't read CIS\n", __FUNCTION__); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ *cis = (uint8)(foo & 0xff); -+ cis++; -+ } -+ -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+extern SDIOH_API_RC -+sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) -+{ -+ int err_ret; -+#if defined(MMC_SDIO_ABORT) -+ int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; -+#endif -+ int ret = 0; -+ -+ AP6210_DEBUG("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr); -+ -+ DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); -+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); -+ if(rw) { /* CMD52 Write */ -+ if (func == 0) { -+ /* Can only directly write to some F0 registers. Handle F2 enable -+ * as a special case. -+ */ -+ if (regaddr == SDIOD_CCCR_IOEN) { -+ if (gInstance->func[2]) { -+ sdio_claim_host(gInstance->func[2]); -+ if (*byte & SDIO_FUNC_ENABLE_2) { -+ /* Enable Function 2 */ -+ err_ret = sdio_enable_func(gInstance->func[2]); -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: enable F2 failed:%d", -+ err_ret); -+ } -+ } else { -+ /* Disable Function 2 */ -+ err_ret = sdio_disable_func(gInstance->func[2]); -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: Disab F2 failed:%d", -+ err_ret); -+ } -+ } -+ sdio_release_host(gInstance->func[2]); -+ } -+ } -+#if defined(MMC_SDIO_ABORT) -+ /* to allow abort command through F1 */ -+ else if (regaddr == SDIOD_CCCR_IOABORT) { -+ /* Because of SDIO3.0 host issue on Manta, -+ * sometimes the abort fails. -+ * Retrying again will fix this issue. -+ */ -+ while (sdio_abort_retry--) { -+ if (gInstance->func[func]) { -+ sdio_claim_host(gInstance->func[func]); -+ /* -+ * this sdio_f0_writeb() can be replaced with -+ * another api depending upon MMC driver change. -+ * As of this time, this is temporaray one -+ */ -+ sdio_writeb(gInstance->func[func], -+ *byte, regaddr, &err_ret); -+ sdio_release_host(gInstance->func[func]); -+ } -+ if (!err_ret) -+ break; -+ } -+ } -+#endif /* MMC_SDIO_ABORT */ -+ else if (regaddr < 0xF0) { -+ AP6210_ERR("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr); -+ } else { -+ /* Claim host controller, perform F0 write, and release */ -+ if (gInstance->func[func]) { -+ sdio_claim_host(gInstance->func[func]); -+ sdio_f0_writeb(gInstance->func[func], -+ *byte, regaddr, &err_ret); -+ sdio_release_host(gInstance->func[func]); -+ } -+ } -+ } else { -+ /* Claim host controller, perform Fn write, and release */ -+ if (gInstance->func[func]) { -+ sdio_claim_host(gInstance->func[func]); -+ sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); -+ sdio_release_host(gInstance->func[func]); -+ } -+ } -+ } else { /* CMD52 Read */ -+ /* Claim host controller, perform Fn read, and release */ -+ if (gInstance->func[func]) { -+ sdio_claim_host(gInstance->func[func]); -+ if (func == 0) { -+ *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret); -+ } else { -+ *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret); -+ } -+ sdio_release_host(gInstance->func[func]); -+ } -+ } -+ -+ //AW judge sdio read write timeout, 1s -+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); -+ if (ret != 0) -+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__); -+ -+ if (err_ret) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", -+ rw ? "Write" : "Read", func, regaddr, *byte, err_ret); -+ } -+ -+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -+} -+ -+extern SDIOH_API_RC -+sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr, -+ uint32 *word, uint nbytes) -+{ -+ int err_ret = SDIOH_API_RC_FAIL; -+#if defined(MMC_SDIO_ABORT) -+ int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; -+#endif -+ int ret = 0; -+ -+ if (func == 0) { -+ AP6210_ERR("%s: Only CMD52 allowed to F0.\n", __FUNCTION__); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ AP6210_DEBUG("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", -+ __FUNCTION__, cmd_type, rw, func, addr, nbytes); -+ -+ DHD_PM_RESUME_WAIT(sdioh_request_word_wait); -+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); -+ /* Claim host controller */ -+ sdio_claim_host(gInstance->func[func]); -+ -+ if(rw) { /* CMD53 Write */ -+ if (nbytes == 4) { -+ sdio_writel(gInstance->func[func], *word, addr, &err_ret); -+ } else if (nbytes == 2) { -+ sdio_writew(gInstance->func[func], (*word & 0xFFFF), addr, &err_ret); -+ } else { -+ AP6210_ERR("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes); -+ } -+ } else { /* CMD52 Read */ -+ if (nbytes == 4) { -+ *word = sdio_readl(gInstance->func[func], addr, &err_ret); -+ } else if (nbytes == 2) { -+ *word = sdio_readw(gInstance->func[func], addr, &err_ret) & 0xFFFF; -+ } else { -+ AP6210_ERR("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes); -+ } -+ } -+ -+ //AW judge sdio read write timeout, 1s -+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); -+ if (ret != 0) -+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__); -+ -+ /* Release host controller */ -+ sdio_release_host(gInstance->func[func]); -+ -+ if (err_ret) { -+#if defined(MMC_SDIO_ABORT) -+ /* Any error on CMD53 transaction should abort that function using function 0. */ -+ while (sdio_abort_retry--) { -+ if (gInstance->func[0]) { -+ sdio_claim_host(gInstance->func[0]); -+ /* -+ * this sdio_f0_writeb() can be replaced with another api -+ * depending upon MMC driver change. -+ * As of this time, this is temporaray one -+ */ -+ sdio_writeb(gInstance->func[0], -+ func, SDIOD_CCCR_IOABORT, &err_ret); -+ sdio_release_host(gInstance->func[0]); -+ } -+ if (!err_ret) -+ break; -+ } -+ if (err_ret) -+#endif /* MMC_SDIO_ABORT */ -+ { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x\n", -+ rw ? "Write" : "Read", err_ret); -+ } -+ } -+ -+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -+} -+ -+static SDIOH_API_RC -+sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, -+ uint addr, void *pkt) -+{ -+ bool fifo = (fix_inc == SDIOH_DATA_FIX); -+ uint32 SGCount = 0; -+ int err_ret = 0; -+ void *pnext, *pprev; -+ uint ttl_len, dma_len, lft_len, xfred_len, pkt_len; -+ uint blk_num; -+ int blk_size; -+ struct mmc_request mmc_req; -+ struct mmc_command mmc_cmd; -+ struct mmc_data mmc_dat; -+ int ret = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(pkt); -+ DHD_PM_RESUME_WAIT(sdioh_request_packet_wait); -+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); -+ -+ ttl_len = xfred_len = 0; -+ /* at least 4 bytes alignment of skb buff is guaranteed */ -+ for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) -+ ttl_len += PKTLEN(sd->osh, pnext); -+ -+ blk_size = sd->client_block_size[func]; -+ if (!sd->use_rxchain || ttl_len <= blk_size) { -+ blk_num = 0; -+ dma_len = 0; -+ } else { -+ blk_num = ttl_len / blk_size; -+ dma_len = blk_num * blk_size; -+ } -+ lft_len = ttl_len - dma_len; -+ -+ AP6210_DEBUG("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n", -+ __FUNCTION__, write ? "W" : "R", -+ ttl_len, func, addr, blk_num, lft_len); -+ -+ if (0 != dma_len) { -+ memset(&mmc_req, 0, sizeof(struct mmc_request)); -+ memset(&mmc_cmd, 0, sizeof(struct mmc_command)); -+ memset(&mmc_dat, 0, sizeof(struct mmc_data)); -+ -+ /* Set up DMA descriptors */ -+ pprev = pkt; -+ for (pnext = pkt; -+ pnext && dma_len; -+ pnext = PKTNEXT(sd->osh, pnext)) { -+ pkt_len = PKTLEN(sd->osh, pnext); -+ -+ if (dma_len > pkt_len) -+ dma_len -= pkt_len; -+ else { -+ pkt_len = xfred_len = dma_len; -+ dma_len = 0; -+ pkt = pnext; -+ } -+ -+ sg_set_buf(&sd->sg_list[SGCount++], -+ (uint8*)PKTDATA(sd->osh, pnext), -+ pkt_len); -+ -+ if (SGCount >= SDIOH_SDMMC_MAX_SG_ENTRIES) { -+ AP6210_ERR("%s: sg list entries exceed limit\n", -+ __FUNCTION__); -+ return (SDIOH_API_RC_FAIL); -+ } -+ } -+ -+ mmc_dat.sg = sd->sg_list; -+ mmc_dat.sg_len = SGCount; -+ mmc_dat.blksz = blk_size; -+ mmc_dat.blocks = blk_num; -+ mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; -+ -+ mmc_cmd.opcode = 53; /* SD_IO_RW_EXTENDED */ -+ mmc_cmd.arg = write ? 1<<31 : 0; -+ mmc_cmd.arg |= (func & 0x7) << 28; -+ mmc_cmd.arg |= 1<<27; -+ mmc_cmd.arg |= fifo ? 0 : 1<<26; -+ mmc_cmd.arg |= (addr & 0x1FFFF) << 9; -+ mmc_cmd.arg |= blk_num & 0x1FF; -+ mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; -+ -+ mmc_req.cmd = &mmc_cmd; -+ mmc_req.data = &mmc_dat; -+ -+ sdio_claim_host(gInstance->func[func]); -+ mmc_set_data_timeout(&mmc_dat, gInstance->func[func]->card); -+ mmc_wait_for_req(gInstance->func[func]->card->host, &mmc_req); -+ sdio_release_host(gInstance->func[func]); -+ -+ err_ret = mmc_cmd.error? mmc_cmd.error : mmc_dat.error; -+ if (0 != err_ret) { -+ AP6210_ERR("%s:CMD53 %s failed with code %d\n", -+ __FUNCTION__, -+ write ? "write" : "read", -+ err_ret); -+ AP6210_ERR("%s:Disabling rxchain and fire it with PIO\n", -+ __FUNCTION__); -+ sd->use_rxchain = FALSE; -+ pkt = pprev; -+ lft_len = ttl_len; -+ } else if (!fifo) { -+ addr = addr + ttl_len - lft_len - dma_len; -+ } -+ } -+ -+ /* PIO mode */ -+ if (0 != lft_len) { -+ /* Claim host controller */ -+ sdio_claim_host(gInstance->func[func]); -+ for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) { -+ uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext) + -+ xfred_len; -+ pkt_len = PKTLEN(sd->osh, pnext); -+ if (0 != xfred_len) { -+ pkt_len -= xfred_len; -+ xfred_len = 0; -+ } -+ -+ /* Align Patch -+ * read or small packet(ex:BDC header) skip 32 byte align -+ * otherwise, padding DHD_SDALIGN for performance -+ */ -+ if (write == 0 || pkt_len < 32) -+ pkt_len = (pkt_len + 3) & 0xFFFFFFFC; -+ else if (pkt_len % blk_size) -+ pkt_len += blk_size - (pkt_len % blk_size); -+ -+#ifdef CONFIG_MMC_MSM7X00A -+ if ((pkt_len % 64) == 32) { -+ AP6210_DEBUG("%s: Rounding up TX packet +=32\n", __FUNCTION__); -+ pkt_len += 32; -+ } -+#endif /* CONFIG_MMC_MSM7X00A */ -+ -+ if ((write) && (!fifo)) -+ err_ret = sdio_memcpy_toio( -+ gInstance->func[func], -+ addr, buf, pkt_len); -+ else if (write) -+ err_ret = sdio_memcpy_toio( -+ gInstance->func[func], -+ addr, buf, pkt_len); -+ else if (fifo) -+ err_ret = sdio_readsb( -+ gInstance->func[func], -+ buf, addr, pkt_len); -+ else -+ err_ret = sdio_memcpy_fromio( -+ gInstance->func[func], -+ buf, addr, pkt_len); -+ -+ //AW judge sdio read write timeout, 1s -+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); -+ if (ret != 0) -+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__); -+ -+ if (err_ret) -+ AP6210_ERR("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n", -+ __FUNCTION__, -+ (write) ? "TX" : "RX", -+ pnext, SGCount, addr, pkt_len, err_ret); -+ else -+ AP6210_DEBUG("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", -+ __FUNCTION__, -+ (write) ? "TX" : "RX", -+ pnext, SGCount, addr, pkt_len); -+ -+ if (!fifo) -+ addr += pkt_len; -+ SGCount ++; -+ } -+ sdio_release_host(gInstance->func[func]); -+ } -+ -+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__); -+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); -+} -+ -+ -+/* -+ * This function takes a buffer or packet, and fixes everything up so that in the -+ * end, a DMA-able packet is created. -+ * -+ * A buffer does not have an associated packet pointer, and may or may not be aligned. -+ * A packet may consist of a single packet, or a packet chain. If it is a packet chain, -+ * then all the packets in the chain must be properly aligned. If the packet data is not -+ * aligned, then there may only be one packet, and in this case, it is copied to a new -+ * aligned packet. -+ * -+ */ -+extern SDIOH_API_RC -+sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, -+ uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) -+{ -+ SDIOH_API_RC Status; -+ void *mypkt = NULL; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); -+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); -+ /* Case 1: we don't have a packet. */ -+ if (pkt == NULL) { -+ AP6210_DEBUG("%s: Creating new %s Packet, len=%d\n", -+ __FUNCTION__, write ? "TX" : "RX", buflen_u); -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) -+#else -+ if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ { -+ AP6210_ERR("%s: PKTGET failed: len %d\n", -+ __FUNCTION__, buflen_u); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ /* For a write, copy the buffer data into the packet. */ -+ if (write) { -+ bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u); -+ } -+ -+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); -+ -+ /* For a read, copy the packet data back to the buffer. */ -+ if (!write) { -+ bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); -+ } -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -+#else -+ PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { -+ /* Case 2: We have a packet, but it is unaligned. */ -+ -+ /* In this case, we cannot have a chain. */ -+ ASSERT(PKTNEXT(sd->osh, pkt) == NULL); -+ -+ AP6210_DEBUG("%s: Creating aligned %s Packet, len=%d\n", -+ __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt)); -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) -+#else -+ if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ { -+ AP6210_ERR("%s: PKTGET failed: len %d\n", -+ __FUNCTION__, PKTLEN(sd->osh, pkt)); -+ return SDIOH_API_RC_FAIL; -+ } -+ -+ /* For a write, copy the buffer data into the packet. */ -+ if (write) { -+ bcopy(PKTDATA(sd->osh, pkt), -+ PKTDATA(sd->osh, mypkt), -+ PKTLEN(sd->osh, pkt)); -+ } -+ -+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); -+ -+ /* For a read, copy the packet data back to the buffer. */ -+ if (!write) { -+ bcopy(PKTDATA(sd->osh, mypkt), -+ PKTDATA(sd->osh, pkt), -+ PKTLEN(sd->osh, mypkt)); -+ } -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); -+#else -+ PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ } else { /* case 3: We have a packet and it is aligned. */ -+ AP6210_DEBUG("%s: Aligned %s Packet, direct DMA\n", -+ __FUNCTION__, write ? "Tx" : "Rx"); -+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); -+ } -+ -+ return (Status); -+} -+ -+/* this function performs "abort" for both of host & device */ -+extern int -+sdioh_abort(sdioh_info_t *sd, uint func) -+{ -+#if defined(MMC_SDIO_ABORT) -+ char t_func = (char) func; -+#endif /* defined(MMC_SDIO_ABORT) */ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+#if defined(MMC_SDIO_ABORT) -+ /* issue abort cmd52 command through F1 */ -+ sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func); -+#endif /* defined(MMC_SDIO_ABORT) */ -+ -+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__); -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+/* Reset and re-initialize the device */ -+int sdioh_sdio_reset(sdioh_info_t *si) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__); -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+/* Disable device interrupt */ -+void -+sdioh_sdmmc_devintr_off(sdioh_info_t *sd) -+{ -+ AP6210_DEBUG("%s: %d\n", __FUNCTION__, sd->use_client_ints); -+ sd->intmask &= ~CLIENT_INTR; -+} -+ -+/* Enable device interrupt */ -+void -+sdioh_sdmmc_devintr_on(sdioh_info_t *sd) -+{ -+ AP6210_DEBUG("%s: %d\n", __FUNCTION__, sd->use_client_ints); -+ sd->intmask |= CLIENT_INTR; -+} -+ -+/* Read client card reg */ -+int -+sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data) -+{ -+ -+ if ((func == 0) || (regsize == 1)) { -+ uint8 temp = 0; -+ -+ sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); -+ *data = temp; -+ *data &= 0xff; -+ AP6210_DEBUG("%s: byte read data=0x%02x\n", -+ __FUNCTION__, *data); -+ } else { -+ sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize); -+ if (regsize == 2) -+ *data &= 0xffff; -+ -+ AP6210_DEBUG("%s: word read data=0x%08x\n", -+ __FUNCTION__, *data); -+ } -+ -+ return SUCCESS; -+} -+ -+#if !defined(OOB_INTR_ONLY) -+/* bcmsdh_sdmmc interrupt handler */ -+static void IRQHandler(struct sdio_func *func) -+{ -+ sdioh_info_t *sd; -+ -+ AP6210_DEBUG("bcmsdh_sdmmc: ***IRQHandler\n"); -+ sd = gInstance->sd; -+ -+ ASSERT(sd != NULL); -+ sdio_release_host(gInstance->func[0]); -+ -+ if (sd->use_client_ints) { -+ sd->intrcount++; -+ ASSERT(sd->intr_handler); -+ ASSERT(sd->intr_handler_arg); -+ (sd->intr_handler)(sd->intr_handler_arg); -+ } else { -+ AP6210_ERR("bcmsdh_sdmmc: ***IRQHandler\n"); -+ -+ AP6210_ERR("%s: Not ready for intr: enabled %d, handler %p\n", -+ __FUNCTION__, sd->client_intr_enabled, sd->intr_handler); -+ } -+ -+ sdio_claim_host(gInstance->func[0]); -+} -+ -+/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */ -+static void IRQHandlerF2(struct sdio_func *func) -+{ -+ sdioh_info_t *sd; -+ -+ AP6210_DEBUG("bcmsdh_sdmmc: ***IRQHandlerF2\n"); -+ -+ sd = gInstance->sd; -+ -+ ASSERT(sd != NULL); -+ BCM_REFERENCE(sd); -+} -+#endif /* !defined(OOB_INTR_ONLY) */ -+ -+#ifdef NOTUSED -+/* Write client card reg */ -+static int -+sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data) -+{ -+ -+ if ((func == 0) || (regsize == 1)) { -+ uint8 temp; -+ -+ temp = data & 0xff; -+ sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); -+ AP6210_DEBUG("%s: byte write data=0x%02x\n", -+ __FUNCTION__, data); -+ } else { -+ if (regsize == 2) -+ data &= 0xffff; -+ -+ sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize); -+ -+ AP6210_DEBUG("%s: word write data=0x%08x\n", -+ __FUNCTION__, data); -+ } -+ -+ return SUCCESS; -+} -+#endif /* NOTUSED */ -+ -+int -+sdioh_start(sdioh_info_t *si, int stage) -+{ -+ int ret; -+ sdioh_info_t *sd = gInstance->sd; -+ -+ if (!sd) return (0); -+ -+ /* Need to do this stages as we can't enable the interrupt till -+ downloading of the firmware is complete, other wise polling -+ sdio access will come in way -+ */ -+ if (gInstance->func[0]) { -+ if (stage == 0) { -+ /* Since the power to the chip is killed, we will have -+ re enumerate the device again. Set the block size -+ and enable the fucntion 1 for in preparation for -+ downloading the code -+ */ -+ /* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux -+ 2.6.27. The implementation prior to that is buggy, and needs broadcom's -+ patch for it -+ */ -+ if ((ret = sdio_reset_comm(gInstance->func[0]->card))) { -+ AP6210_ERR("%s Failed, error = %d\n", __FUNCTION__, ret); -+ return ret; -+ } -+ else { -+ sd->num_funcs = 2; -+ sd->sd_blockmode = TRUE; -+ sd->use_client_ints = TRUE; -+ sd->client_block_size[0] = 64; -+ -+ if (gInstance->func[1]) { -+ /* Claim host controller */ -+ sdio_claim_host(gInstance->func[1]); -+ -+ sd->client_block_size[1] = 64; -+ if (sdio_set_block_size(gInstance->func[1], 64)) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F1 blocksize\n"); -+ } -+ -+ /* Release host controller F1 */ -+ sdio_release_host(gInstance->func[1]); -+ } -+ -+ if (gInstance->func[2]) { -+ /* Claim host controller F2 */ -+ sdio_claim_host(gInstance->func[2]); -+ -+ sd->client_block_size[2] = sd_f2_blocksize; -+ if (sdio_set_block_size(gInstance->func[2], -+ sd_f2_blocksize)) { -+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F2 " -+ "blocksize to %d\n", sd_f2_blocksize); -+ } -+ -+ /* Release host controller F2 */ -+ sdio_release_host(gInstance->func[2]); -+ } -+ -+ sdioh_sdmmc_card_enablefuncs(sd); -+ } -+ } else { -+#if !defined(OOB_INTR_ONLY) -+ sdio_claim_host(gInstance->func[0]); -+ if (gInstance->func[2]) -+ sdio_claim_irq(gInstance->func[2], IRQHandlerF2); -+ if (gInstance->func[1]) -+ sdio_claim_irq(gInstance->func[1], IRQHandler); -+ sdio_release_host(gInstance->func[0]); -+#else /* defined(OOB_INTR_ONLY) */ -+#if defined(HW_OOB) -+ sdioh_enable_func_intr(); -+#endif -+ bcmsdh_oob_intr_set(TRUE); -+#endif /* !defined(OOB_INTR_ONLY) */ -+ } -+ } -+ else -+ AP6210_ERR("%s Failed\n", __FUNCTION__); -+ -+ return (0); -+} -+ -+int -+sdioh_stop(sdioh_info_t *si) -+{ -+ /* MSM7201A Android sdio stack has bug with interrupt -+ So internaly within SDIO stack they are polling -+ which cause issue when device is turned off. So -+ unregister interrupt with SDIO stack to stop the -+ polling -+ */ -+ if (gInstance->func[0]) { -+#if !defined(OOB_INTR_ONLY) -+ sdio_claim_host(gInstance->func[0]); -+ if (gInstance->func[1]) -+ sdio_release_irq(gInstance->func[1]); -+ if (gInstance->func[2]) -+ sdio_release_irq(gInstance->func[2]); -+ sdio_release_host(gInstance->func[0]); -+#else /* defined(OOB_INTR_ONLY) */ -+#if defined(HW_OOB) -+ sdioh_disable_func_intr(); -+#endif -+ bcmsdh_oob_intr_set(FALSE); -+#endif /* !defined(OOB_INTR_ONLY) */ -+ } -+ else -+ AP6210_ERR("%s Failed\n", __FUNCTION__); -+ return (0); -+} -+ -+int -+sdioh_waitlockfree(sdioh_info_t *sd) -+{ -+ return (1); -+} -+ -+ -+SDIOH_API_RC -+sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio) -+{ -+ return SDIOH_API_RC_FAIL; -+} -+ -+SDIOH_API_RC -+sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab) -+{ -+ return SDIOH_API_RC_FAIL; -+} -+ -+bool -+sdioh_gpioin(sdioh_info_t *sd, uint32 gpio) -+{ -+ return FALSE; -+} -+ -+SDIOH_API_RC -+sdioh_gpio_init(sdioh_info_t *sd) -+{ -+ return SDIOH_API_RC_FAIL; -+} -diff --git a/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c -new file mode 100644 -index 0000000..98b5818 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c -@@ -0,0 +1,427 @@ -+/* -+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh_sdmmc_linux.c 363783 2012-10-19 06:27:14Z $ -+ */ -+ -+#include -+#include -+#include /* SDIO Device and Protocol Specs */ -+#include /* bcmsdh to/from specific controller APIs */ -+#include /* to get msglevel bit values */ -+ -+#include /* request_irq() */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#if !defined(SDIO_VENDOR_ID_BROADCOM) -+#define SDIO_VENDOR_ID_BROADCOM 0x02d0 -+#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ -+ -+#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 -+ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) -+#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) -+#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) -+#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) -+#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4319) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4330) -+#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4330) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4334) -+#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_4324) -+#define SDIO_DEVICE_ID_BROADCOM_4324 0x4324 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4324) */ -+#if !defined(SDIO_DEVICE_ID_BROADCOM_43239) -+#define SDIO_DEVICE_ID_BROADCOM_43239 43239 -+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */ -+ -+ -+#include -+ -+#include -+ -+#ifdef WL_CFG80211 -+extern void wl_cfg80211_set_parent_dev(void *dev); -+#endif -+ -+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -+extern int dhd_os_check_wakelock(void *dhdp); -+extern int dhd_os_check_if_up(void *dhdp); -+extern void *bcmsdh_get_drvdata(void); -+ -+int sdio_function_init(void); -+void sdio_function_cleanup(void); -+ -+#define DESCRIPTION "bcmsdh_sdmmc Driver" -+#define AUTHOR "Broadcom Corporation" -+ -+/* module param defaults */ -+static int clockoverride = 0; -+ -+module_param(clockoverride, int, 0644); -+MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); -+ -+PBCMSDH_SDMMC_INSTANCE gInstance; -+ -+/* Maximum number of bcmsdh_sdmmc devices supported by driver */ -+#define BCMSDH_SDMMC_MAX_DEVICES 1 -+ -+extern int bcmsdh_probe(struct device *dev); -+extern int bcmsdh_remove(struct device *dev); -+extern volatile bool dhd_mmc_suspend; -+ -+static int bcmsdh_sdmmc_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ int ret = 0; -+ static struct sdio_func sdio_func_0; -+ -+ if (func) { -+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__); -+ AP6210_DEBUG("sdio_bcmsdh: func->class=%x\n", func->class); -+ AP6210_DEBUG("sdio_vendor: 0x%04x\n", func->vendor); -+ AP6210_DEBUG("sdio_device: 0x%04x\n", func->device); -+ AP6210_DEBUG("Function#: 0x%04x\n", func->num); -+ -+ if (func->num == 1) { -+ sdio_func_0.num = 0; -+ sdio_func_0.card = func->card; -+ gInstance->func[0] = &sdio_func_0; -+ if(func->device == 0x4) { /* 4318 */ -+ gInstance->func[2] = NULL; -+ AP6210_DEBUG("NIC found, calling bcmsdh_probe...\n"); -+ ret = bcmsdh_probe(&func->dev); -+ } -+ } -+ -+ gInstance->func[func->num] = func; -+ -+ if (func->num == 2) { -+ #ifdef WL_CFG80211 -+ wl_cfg80211_set_parent_dev(&func->dev); -+ #endif -+ AP6210_DEBUG("F2 found, calling bcmsdh_probe...\n"); -+ ret = bcmsdh_probe(&func->dev); -+ } -+ } else { -+ ret = -ENODEV; -+ } -+ -+ return ret; -+} -+ -+static void bcmsdh_sdmmc_remove(struct sdio_func *func) -+{ -+ if (func) { -+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__); -+ AP6210_DEBUG("sdio_bcmsdh: func->class=%x\n", func->class); -+ AP6210_DEBUG("sdio_vendor: 0x%04x\n", func->vendor); -+ AP6210_DEBUG("sdio_device: 0x%04x\n", func->device); -+ AP6210_DEBUG("Function#: 0x%04x\n", func->num); -+ -+ if (gInstance->func[2]) { -+ AP6210_DEBUG("F2 found, calling bcmsdh_remove...\n"); -+ bcmsdh_remove(&func->dev); -+ gInstance->func[2] = NULL; -+ } -+ if (func->num == 1) { -+ sdio_claim_host(func); -+ sdio_disable_func(func); -+ sdio_release_host(func); -+ gInstance->func[1] = NULL; -+ } -+ } -+} -+ -+/* devices we support, null terminated */ -+static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, -+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, -+ { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) }, -+ { /* end: all zeroes */ }, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) -+static int bcmsdh_sdmmc_suspend(struct device *pdev) -+{ -+ struct sdio_func *func = dev_to_sdio_func(pdev); -+ mmc_pm_flag_t sdio_flags; -+ int ret; -+ -+ if (func->num != 2) -+ return 0; -+ -+ AP6210_DEBUG("%s Enter\n", __FUNCTION__); -+ -+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) -+ return -EBUSY; -+ -+ sdio_flags = sdio_get_host_pm_caps(func); -+ -+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) { -+ AP6210_ERR("%s: can't keep power while host is suspended\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ /* keep power while host suspended */ -+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); -+ if (ret) { -+ AP6210_ERR("%s: error while trying to keep power\n", __FUNCTION__); -+ return ret; -+ } -+ -+#if defined(OOB_INTR_ONLY) -+ bcmsdh_oob_intr_set(0); -+#endif /* defined(OOB_INTR_ONLY) */ -+ dhd_mmc_suspend = TRUE; -+ smp_mb(); -+ -+ return 0; -+} -+ -+static int bcmsdh_sdmmc_resume(struct device *pdev) -+{ -+#if defined(OOB_INTR_ONLY) -+ struct sdio_func *func = dev_to_sdio_func(pdev); -+#endif /* defined(OOB_INTR_ONLY) */ -+ AP6210_DEBUG("%s Enter\n", __FUNCTION__); -+ -+ dhd_mmc_suspend = FALSE; -+#if defined(OOB_INTR_ONLY) -+ if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) -+ bcmsdh_oob_intr_set(1); -+#endif /* (OOB_INTR_ONLY) */ -+ smp_mb(); -+ return 0; -+} -+ -+static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = { -+ .suspend = bcmsdh_sdmmc_suspend, -+ .resume = bcmsdh_sdmmc_resume, -+}; -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ -+ -+#if defined(BCMLXSDMMC) -+static struct semaphore *notify_semaphore = NULL; -+ -+static int dummy_probe(struct sdio_func *func, -+ const struct sdio_device_id *id) -+{ -+ if (notify_semaphore) -+ up(notify_semaphore); -+ return 0; -+} -+ -+static void dummy_remove(struct sdio_func *func) -+{ -+} -+ -+static struct sdio_driver dummy_sdmmc_driver = { -+ .probe = dummy_probe, -+ .remove = dummy_remove, -+ .name = "dummy_sdmmc", -+ .id_table = bcmsdh_sdmmc_ids, -+ }; -+ -+int sdio_func_reg_notify(void* semaphore) -+{ -+ notify_semaphore = semaphore; -+ return sdio_register_driver(&dummy_sdmmc_driver); -+} -+ -+void sdio_func_unreg_notify(void) -+{ -+ sdio_unregister_driver(&dummy_sdmmc_driver); -+} -+ -+#endif /* defined(BCMLXSDMMC) */ -+ -+static struct sdio_driver bcmsdh_sdmmc_driver = { -+ .probe = bcmsdh_sdmmc_probe, -+ .remove = bcmsdh_sdmmc_remove, -+ .name = "bcmsdh_sdmmc", -+ .id_table = bcmsdh_sdmmc_ids, -+#if !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI) -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) -+ .drv = { -+ .pm = &bcmsdh_sdmmc_pm_ops, -+ }, -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ -+#endif /* !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI) */ -+ }; -+ -+struct sdos_info { -+ sdioh_info_t *sd; -+ spinlock_t lock; -+}; -+ -+ -+int -+sdioh_sdmmc_osinit(sdioh_info_t *sd) -+{ -+ struct sdos_info *sdos; -+ -+ if (!sd) -+ return BCME_BADARG; -+ -+ sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info)); -+ sd->sdos_info = (void*)sdos; -+ if (sdos == NULL) -+ return BCME_NOMEM; -+ -+ sdos->sd = sd; -+ spin_lock_init(&sdos->lock); -+ return BCME_OK; -+} -+ -+void -+sdioh_sdmmc_osfree(sdioh_info_t *sd) -+{ -+ struct sdos_info *sdos; -+ ASSERT(sd && sd->sdos_info); -+ -+ sdos = (struct sdos_info *)sd->sdos_info; -+ MFREE(sd->osh, sdos, sizeof(struct sdos_info)); -+} -+ -+/* Interrupt enable/disable */ -+SDIOH_API_RC -+sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -+{ -+ ulong flags; -+ struct sdos_info *sdos; -+ -+ if (!sd) -+ return BCME_BADARG; -+ -+ AP6210_DEBUG("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling"); -+ -+ sdos = (struct sdos_info *)sd->sdos_info; -+ ASSERT(sdos); -+ -+#if !defined(OOB_INTR_ONLY) -+ if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { -+ AP6210_ERR("%s: no handler registered, will not enable\n", __FUNCTION__); -+ return SDIOH_API_RC_FAIL; -+ } -+#endif /* !defined(OOB_INTR_ONLY) */ -+ -+ /* Ensure atomicity for enable/disable calls */ -+ spin_lock_irqsave(&sdos->lock, flags); -+ -+ sd->client_intr_enabled = enable; -+ if (enable) { -+ sdioh_sdmmc_devintr_on(sd); -+ } else { -+ sdioh_sdmmc_devintr_off(sd); -+ } -+ -+ spin_unlock_irqrestore(&sdos->lock, flags); -+ -+ return SDIOH_API_RC_SUCCESS; -+} -+ -+ -+#ifdef BCMSDH_MODULE -+static int __init -+bcmsdh_module_init(void) -+{ -+ int error = 0; -+ error = sdio_function_init(); -+ return error; -+} -+ -+static void __exit -+bcmsdh_module_cleanup(void) -+{ -+ sdio_function_cleanup(); -+} -+ -+module_init(bcmsdh_module_init); -+module_exit(bcmsdh_module_cleanup); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION(DESCRIPTION); -+MODULE_AUTHOR(AUTHOR); -+ -+#endif /* BCMSDH_MODULE */ -+/* -+ * module init -+*/ -+int sdio_function_init(void) -+{ -+ int error = 0; -+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__); -+ -+ gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL); -+ if (!gInstance) -+ return -ENOMEM; -+ -+ error = sdio_register_driver(&bcmsdh_sdmmc_driver); -+ if (error && gInstance) { -+ kfree(gInstance); -+ gInstance = 0; -+ } -+ -+ return error; -+} -+ -+/* -+ * module cleanup -+*/ -+extern int bcmsdh_remove(struct device *dev); -+void sdio_function_cleanup(void) -+{ -+ AP6210_DEBUG("%s Enter\n", __FUNCTION__); -+ -+ -+ sdio_unregister_driver(&bcmsdh_sdmmc_driver); -+ -+ if (gInstance) -+ kfree(gInstance); -+} -diff --git a/drivers/net/wireless/ap6210/bcmutils.c b/drivers/net/wireless/ap6210/bcmutils.c -new file mode 100644 -index 0000000..631125a ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmutils.c -@@ -0,0 +1,2095 @@ -+/* -+ * Driver O/S-independent utility routines -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: bcmutils.c 312855 2012-02-04 02:01:18Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#ifdef BCMDRIVER -+ -+#include -+#include -+ -+#else /* !BCMDRIVER */ -+ -+#include -+#include -+#include -+ -+#if defined(BCMEXTSUP) -+#include -+#endif -+ -+ -+#endif /* !BCMDRIVER */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+void *_bcmutils_dummy_fn = NULL; -+ -+#include -+ -+ -+#ifdef BCMDRIVER -+ -+ -+ -+/* copy a pkt buffer chain into a buffer */ -+uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ if (len < 0) -+ len = 4096; /* "infinite" */ -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) -+ return 0; -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } -+ -+ return ret; -+} -+ -+/* copy a buffer into a pkt buffer chain */ -+uint -+pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) -+ return 0; -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(buf, PKTDATA(osh, p) + offset, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } -+ -+ return ret; -+} -+ -+ -+ -+/* return total length of buffer chain */ -+uint BCMFASTPATH -+pkttotlen(osl_t *osh, void *p) -+{ -+ uint total; -+ int len; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) { -+ len = PKTLEN(osh, p); -+ total += len; -+ } -+ -+ return (total); -+} -+ -+/* return the last buffer of chained pkt */ -+void * -+pktlast(osl_t *osh, void *p) -+{ -+ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) -+ ; -+ -+ return (p); -+} -+ -+/* count segments of a chained packet */ -+uint BCMFASTPATH -+pktsegcnt(osl_t *osh, void *p) -+{ -+ uint cnt; -+ -+ for (cnt = 0; p; p = PKTNEXT(osh, p)) -+ cnt++; -+ -+ return cnt; -+} -+ -+ -+/* count segments of a chained packet */ -+uint BCMFASTPATH -+pktsegcnt_war(osl_t *osh, void *p) -+{ -+ uint cnt; -+ uint8 *pktdata; -+ uint len, remain, align64; -+ -+ for (cnt = 0; p; p = PKTNEXT(osh, p)) { -+ cnt++; -+ len = PKTLEN(osh, p); -+ if (len > 128) { -+ pktdata = (uint8 *)PKTDATA(osh, p); /* starting address of data */ -+ /* Check for page boundary straddle (2048B) */ -+ if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff)) -+ cnt++; -+ -+ align64 = (uint)((uintptr)pktdata & 0x3f); /* aligned to 64B */ -+ align64 = (64 - align64) & 0x3f; -+ len -= align64; /* bytes from aligned 64B to end */ -+ /* if aligned to 128B, check for MOD 128 between 1 to 4B */ -+ remain = len % 128; -+ if (remain > 0 && remain <= 4) -+ cnt++; /* add extra seg */ -+ } -+ } -+ -+ return cnt; -+} -+ -+uint8 * BCMFASTPATH -+pktoffset(osl_t *osh, void *p, uint offset) -+{ -+ uint total = pkttotlen(osh, p); -+ uint pkt_off = 0, len = 0; -+ uint8 *pdata = (uint8 *) PKTDATA(osh, p); -+ -+ if (offset > total) -+ return NULL; -+ -+ for (; p; p = PKTNEXT(osh, p)) { -+ pdata = (uint8 *) PKTDATA(osh, p); -+ pkt_off = offset - len; -+ len += PKTLEN(osh, p); -+ if (len > offset) -+ break; -+ } -+ return (uint8*) (pdata+pkt_off); -+} -+ -+/* -+ * osl multiple-precedence packet queue -+ * hi_prec is always >= the number of the highest non-empty precedence -+ */ -+void * BCMFASTPATH -+pktq_penq(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head) -+ PKTSETLINK(q->tail, p); -+ else -+ q->head = p; -+ -+ q->tail = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_penq_head(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == NULL) -+ q->tail = p; -+ -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if (prev_p == NULL) -+ return NULL; -+ -+ if ((p = PKTLINK(prev_p)) == NULL) -+ return NULL; -+ -+ q->len--; -+ -+ pq->len--; -+ -+ PKTSETLINK(prev_p, PKTLINK(p)); -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq_tail(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ return p; -+} -+ -+void -+pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) -+{ -+ struct pktq_prec *q; -+ void *p, *prev = NULL; -+ -+ q = &pq->q[prec]; -+ p = q->head; -+ while (p) { -+ if (fn == NULL || (*fn)(p, arg)) { -+ bool head = (p == q->head); -+ if (head) -+ q->head = PKTLINK(p); -+ else -+ PKTSETLINK(prev, PKTLINK(p)); -+ PKTSETLINK(p, NULL); -+ PKTFREE(osh, p, dir); -+ q->len--; -+ pq->len--; -+ p = (head ? q->head : PKTLINK(prev)); -+ } else { -+ prev = p; -+ p = PKTLINK(p); -+ } -+ } -+ -+ if (q->head == NULL) { -+ ASSERT(q->len == 0); -+ q->tail = NULL; -+ } -+} -+ -+bool BCMFASTPATH -+pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ if (!pktbuf) -+ return FALSE; -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == pktbuf) { -+ if ((q->head = PKTLINK(pktbuf)) == NULL) -+ q->tail = NULL; -+ } else { -+ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) -+ ; -+ if (p == NULL) -+ return FALSE; -+ -+ PKTSETLINK(p, PKTLINK(pktbuf)); -+ if (q->tail == pktbuf) -+ q->tail = p; -+ } -+ -+ q->len--; -+ pq->len--; -+ PKTSETLINK(pktbuf, NULL); -+ return TRUE; -+} -+ -+void -+pktq_init(struct pktq *pq, int num_prec, int max_len) -+{ -+ int prec; -+ -+ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); -+ -+ /* pq is variable size; only zero out what's requested */ -+ bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); -+ -+ pq->num_prec = (uint16)num_prec; -+ -+ pq->max = (uint16)max_len; -+ -+ for (prec = 0; prec < num_prec; prec++) -+ pq->q[prec].max = pq->max; -+} -+ -+void -+pktq_set_max_plen(struct pktq *pq, int prec, int max_len) -+{ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ if (prec < pq->num_prec) -+ pq->q[prec].max = (uint16)max_len; -+} -+ -+void * BCMFASTPATH -+pktq_deq(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_deq_tail(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) -+ break; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * -+pktq_peek(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return (pq->q[prec].head); -+} -+ -+void * -+pktq_peek_tail(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) -+ break; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return (pq->q[prec].tail); -+} -+ -+void -+pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) -+{ -+ int prec; -+ -+ /* Optimize flush, if pktq len = 0, just return. -+ * pktq len of 0 means pktq's prec q's are all empty. -+ */ -+ if (pq->len == 0) { -+ return; -+ } -+ -+ for (prec = 0; prec < pq->num_prec; prec++) -+ pktq_pflush(osh, pq, prec, dir, fn, arg); -+ if (fn == NULL) -+ ASSERT(pq->len == 0); -+} -+ -+/* Return sum of lengths of a specific set of precedences */ -+int -+pktq_mlen(struct pktq *pq, uint prec_bmp) -+{ -+ int prec, len; -+ -+ len = 0; -+ -+ for (prec = 0; prec <= pq->hi_prec; prec++) -+ if (prec_bmp & (1 << prec)) -+ len += pq->q[prec].len; -+ -+ return len; -+} -+ -+/* Priority peek from a specific set of precedences */ -+void * BCMFASTPATH -+pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ { -+ return NULL; -+ } -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) -+ if (prec-- == 0) -+ return NULL; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return p; -+} -+/* Priority dequeue from a specific set of precedences */ -+void * BCMFASTPATH -+pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0)) -+ if (prec-- == 0) -+ return NULL; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+#endif /* BCMDRIVER */ -+ -+const unsigned char bcm_ctype[] = { -+ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ -+ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, -+ _BCM_C, /* 8-15 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ -+ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ -+ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ -+ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, -+ _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ -+ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, -+ _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ -+ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ -+}; -+ -+ulong -+bcm_strtoul(const char *cp, char **endp, uint base) -+{ -+ ulong result, last_result = 0, value; -+ bool minus; -+ -+ minus = FALSE; -+ -+ while (bcm_isspace(*cp)) -+ cp++; -+ -+ if (cp[0] == '+') -+ cp++; -+ else if (cp[0] == '-') { -+ minus = TRUE; -+ cp++; -+ } -+ -+ if (base == 0) { -+ if (cp[0] == '0') { -+ if ((cp[1] == 'x') || (cp[1] == 'X')) { -+ base = 16; -+ cp = &cp[2]; -+ } else { -+ base = 8; -+ cp = &cp[1]; -+ } -+ } else -+ base = 10; -+ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { -+ cp = &cp[2]; -+ } -+ -+ result = 0; -+ -+ while (bcm_isxdigit(*cp) && -+ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { -+ result = result*base + value; -+ /* Detected overflow */ -+ if (result < last_result && !minus) -+ return (ulong)-1; -+ last_result = result; -+ cp++; -+ } -+ -+ if (minus) -+ result = (ulong)(-(long)result); -+ -+ if (endp) -+ *endp = DISCARD_QUAL(cp, char); -+ -+ return (result); -+} -+ -+int -+bcm_atoi(const char *s) -+{ -+ return (int)bcm_strtoul(s, NULL, 10); -+} -+ -+/* return pointer to location of substring 'needle' in 'haystack' */ -+char * -+bcmstrstr(const char *haystack, const char *needle) -+{ -+ int len, nlen; -+ int i; -+ -+ if ((haystack == NULL) || (needle == NULL)) -+ return DISCARD_QUAL(haystack, char); -+ -+ nlen = strlen(needle); -+ len = strlen(haystack) - nlen + 1; -+ -+ for (i = 0; i < len; i++) -+ if (memcmp(needle, &haystack[i], nlen) == 0) -+ return DISCARD_QUAL(&haystack[i], char); -+ return (NULL); -+} -+ -+char * -+bcmstrcat(char *dest, const char *src) -+{ -+ char *p; -+ -+ p = dest + strlen(dest); -+ -+ while ((*p++ = *src++) != '\0') -+ ; -+ -+ return (dest); -+} -+ -+char * -+bcmstrncat(char *dest, const char *src, uint size) -+{ -+ char *endp; -+ char *p; -+ -+ p = dest + strlen(dest); -+ endp = p + size; -+ -+ while (p != endp && (*p++ = *src++) != '\0') -+ ; -+ -+ return (dest); -+} -+ -+ -+/**************************************************************************** -+* Function: bcmstrtok -+* -+* Purpose: -+* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), -+* but allows strToken() to be used by different strings or callers at the same -+* time. Each call modifies '*string' by substituting a NULL character for the -+* first delimiter that is encountered, and updates 'string' to point to the char -+* after the delimiter. Leading delimiters are skipped. -+* -+* Parameters: -+* string (mod) Ptr to string ptr, updated by token. -+* delimiters (in) Set of delimiter characters. -+* tokdelim (out) Character that delimits the returned token. (May -+* be set to NULL if token delimiter is not required). -+* -+* Returns: Pointer to the next token found. NULL when no more tokens are found. -+***************************************************************************** -+*/ -+char * -+bcmstrtok(char **string, const char *delimiters, char *tokdelim) -+{ -+ unsigned char *str; -+ unsigned long map[8]; -+ int count; -+ char *nextoken; -+ -+ if (tokdelim != NULL) { -+ /* Prime the token delimiter */ -+ *tokdelim = '\0'; -+ } -+ -+ /* Clear control map */ -+ for (count = 0; count < 8; count++) { -+ map[count] = 0; -+ } -+ -+ /* Set bits in delimiter table */ -+ do { -+ map[*delimiters >> 5] |= (1 << (*delimiters & 31)); -+ } -+ while (*delimiters++); -+ -+ str = (unsigned char*)*string; -+ -+ /* Find beginning of token (skip over leading delimiters). Note that -+ * there is no token iff this loop sets str to point to the terminal -+ * null (*str == '\0') -+ */ -+ while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { -+ str++; -+ } -+ -+ nextoken = (char*)str; -+ -+ /* Find the end of the token. If it is not the end of the string, -+ * put a null there. -+ */ -+ for (; *str; str++) { -+ if (map[*str >> 5] & (1 << (*str & 31))) { -+ if (tokdelim != NULL) { -+ *tokdelim = *str; -+ } -+ -+ *str++ = '\0'; -+ break; -+ } -+ } -+ -+ *string = (char*)str; -+ -+ /* Determine if a token has been found. */ -+ if (nextoken == (char *) str) { -+ return NULL; -+ } -+ else { -+ return nextoken; -+ } -+} -+ -+ -+#define xToLower(C) \ -+ ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) -+ -+ -+/**************************************************************************** -+* Function: bcmstricmp -+* -+* Purpose: Compare to strings case insensitively. -+* -+* Parameters: s1 (in) First string to compare. -+* s2 (in) Second string to compare. -+* -+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -+* t1 > t2, when ignoring case sensitivity. -+***************************************************************************** -+*/ -+int -+bcmstricmp(const char *s1, const char *s2) -+{ -+ char dc, sc; -+ -+ while (*s2 && *s1) { -+ dc = xToLower(*s1); -+ sc = xToLower(*s2); -+ if (dc < sc) return -1; -+ if (dc > sc) return 1; -+ s1++; -+ s2++; -+ } -+ -+ if (*s1 && !*s2) return 1; -+ if (!*s1 && *s2) return -1; -+ return 0; -+} -+ -+ -+/**************************************************************************** -+* Function: bcmstrnicmp -+* -+* Purpose: Compare to strings case insensitively, upto a max of 'cnt' -+* characters. -+* -+* Parameters: s1 (in) First string to compare. -+* s2 (in) Second string to compare. -+* cnt (in) Max characters to compare. -+* -+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -+* t1 > t2, when ignoring case sensitivity. -+***************************************************************************** -+*/ -+int -+bcmstrnicmp(const char* s1, const char* s2, int cnt) -+{ -+ char dc, sc; -+ -+ while (*s2 && *s1 && cnt) { -+ dc = xToLower(*s1); -+ sc = xToLower(*s2); -+ if (dc < sc) return -1; -+ if (dc > sc) return 1; -+ s1++; -+ s2++; -+ cnt--; -+ } -+ -+ if (!cnt) return 0; -+ if (*s1 && !*s2) return 1; -+ if (!*s1 && *s2) return -1; -+ return 0; -+} -+ -+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -+int -+bcm_ether_atoe(const char *p, struct ether_addr *ea) -+{ -+ int i = 0; -+ char *ep; -+ -+ for (;;) { -+ ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16); -+ p = ep; -+ if (!*p++ || i == 6) -+ break; -+ } -+ -+ return (i == 6); -+} -+ -+ -+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -+/* registry routine buffer preparation utility functions: -+ * parameter order is like strncpy, but returns count -+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) -+ */ -+ulong -+wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) -+{ -+ ulong copyct = 1; -+ ushort i; -+ -+ if (abuflen == 0) -+ return 0; -+ -+ /* wbuflen is in bytes */ -+ wbuflen /= sizeof(ushort); -+ -+ for (i = 0; i < wbuflen; ++i) { -+ if (--abuflen == 0) -+ break; -+ *abuf++ = (char) *wbuf++; -+ ++copyct; -+ } -+ *abuf = '\0'; -+ -+ return copyct; -+} -+#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ -+ -+char * -+bcm_ether_ntoa(const struct ether_addr *ea, char *buf) -+{ -+ static const char hex[] = -+ { -+ '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -+ }; -+ const uint8 *octet = ea->octet; -+ char *p = buf; -+ int i; -+ -+ for (i = 0; i < 6; i++, octet++) { -+ *p++ = hex[(*octet >> 4) & 0xf]; -+ *p++ = hex[*octet & 0xf]; -+ *p++ = ':'; -+ } -+ -+ *(p-1) = '\0'; -+ -+ return (buf); -+} -+ -+char * -+bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) -+{ -+ snprintf(buf, 16, "%d.%d.%d.%d", -+ ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); -+ return (buf); -+} -+ -+#ifdef BCMDRIVER -+ -+void -+bcm_mdelay(uint ms) -+{ -+ uint i; -+ -+ for (i = 0; i < ms; i++) { -+ OSL_DELAY(1000); -+ } -+} -+ -+ -+ -+ -+ -+#if defined(DHD_DEBUG) -+/* pretty hex print a pkt buffer chain */ -+void -+prpkt(const char *msg, osl_t *osh, void *p0) -+{ -+ void *p; -+ -+ if (msg && (msg[0] != '\0')) -+ AP6210_DEBUG("%s:\n", msg); -+ -+ for (p = p0; p; p = PKTNEXT(osh, p)) -+ prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); -+} -+#endif -+ -+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. -+ * Also updates the inplace vlan tag if requested. -+ * For debugging, it returns an indication of what it did. -+ */ -+uint BCMFASTPATH -+pktsetprio(void *pkt, bool update_vtag) -+{ -+ struct ether_header *eh; -+ struct ethervlan_header *evh; -+ uint8 *pktdata; -+ int priority = 0; -+ int rc = 0; -+ -+ pktdata = (uint8 *)PKTDATA(NULL, pkt); -+ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); -+ -+ eh = (struct ether_header *) pktdata; -+ -+ if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { -+ uint16 vlan_tag; -+ int vlan_prio, dscp_prio = 0; -+ -+ evh = (struct ethervlan_header *)eh; -+ -+ vlan_tag = ntoh16(evh->vlan_tag); -+ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; -+ -+ if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { -+ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); -+ uint8 tos_tc = IP_TOS46(ip_body); -+ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ } -+ -+ /* DSCP priority gets precedence over 802.1P (vlan tag) */ -+ if (dscp_prio != 0) { -+ priority = dscp_prio; -+ rc |= PKTPRIO_VDSCP; -+ } else { -+ priority = vlan_prio; -+ rc |= PKTPRIO_VLAN; -+ } -+ /* -+ * If the DSCP priority is not the same as the VLAN priority, -+ * then overwrite the priority field in the vlan tag, with the -+ * DSCP priority value. This is required for Linux APs because -+ * the VLAN driver on Linux, overwrites the skb->priority field -+ * with the priority value in the vlan tag -+ */ -+ if (update_vtag && (priority != vlan_prio)) { -+ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); -+ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; -+ evh->vlan_tag = hton16(vlan_tag); -+ rc |= PKTPRIO_UPD; -+ } -+ } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { -+ uint8 *ip_body = pktdata + sizeof(struct ether_header); -+ uint8 tos_tc = IP_TOS46(ip_body); -+ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ rc |= PKTPRIO_DSCP; -+ } -+ -+ ASSERT(priority >= 0 && priority <= MAXPRIO); -+ PKTSETPRIO(pkt, priority); -+ return (rc | priority); -+} -+ -+ -+static char bcm_undeferrstr[32]; -+static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; -+ -+/* Convert the error codes into related error strings */ -+const char * -+bcmerrorstr(int bcmerror) -+{ -+ /* check if someone added a bcmerror code but forgot to add errorstring */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); -+ -+ if (bcmerror > 0 || bcmerror < BCME_LAST) { -+ snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror); -+ return bcm_undeferrstr; -+ } -+ -+ ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); -+ -+ return bcmerrorstrtable[-bcmerror]; -+} -+ -+ -+ -+/* iovar table lookup */ -+const bcm_iovar_t* -+bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) -+{ -+ const bcm_iovar_t *vi; -+ const char *lookup_name; -+ -+ /* skip any ':' delimited option prefixes */ -+ lookup_name = strrchr(name, ':'); -+ if (lookup_name != NULL) -+ lookup_name++; -+ else -+ lookup_name = name; -+ -+ ASSERT(table != NULL); -+ -+ for (vi = table; vi->name; vi++) { -+ if (!strcmp(vi->name, lookup_name)) -+ return vi; -+ } -+ /* ran to end of table */ -+ -+ return NULL; /* var name not found */ -+} -+ -+int -+bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -+{ -+ int bcmerror = 0; -+ -+ /* length check on io buf */ -+ switch (vi->type) { -+ case IOVT_BOOL: -+ case IOVT_INT8: -+ case IOVT_INT16: -+ case IOVT_INT32: -+ case IOVT_UINT8: -+ case IOVT_UINT16: -+ case IOVT_UINT32: -+ /* all integers are int32 sized args at the ioctl interface */ -+ if (len < (int)sizeof(int)) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_BUFFER: -+ /* buffer must meet minimum length requirement */ -+ if (len < vi->minlen) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_VOID: -+ if (!set) { -+ /* Cannot return nil... */ -+ bcmerror = BCME_UNSUPPORTED; -+ } else if (len) { -+ /* Set is an action w/o parameters */ -+ bcmerror = BCME_BUFTOOLONG; -+ } -+ break; -+ -+ default: -+ /* unknown type for length check in iovar info */ -+ ASSERT(0); -+ bcmerror = BCME_UNSUPPORTED; -+ } -+ -+ return bcmerror; -+} -+ -+#endif /* BCMDRIVER */ -+ -+ -+/******************************************************************************* -+ * crc8 -+ * -+ * Computes a crc8 over the input data using the polynomial: -+ * -+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 -+ * -+ * The caller provides the initial value (either CRC8_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC8_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ * **************************************************************************** -+ */ -+ -+static const uint8 crc8_table[256] = { -+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, -+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, -+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, -+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, -+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, -+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, -+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, -+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, -+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, -+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, -+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, -+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, -+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, -+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, -+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, -+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, -+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, -+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, -+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, -+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, -+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, -+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, -+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, -+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, -+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, -+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, -+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, -+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, -+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, -+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, -+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, -+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -+}; -+ -+#define CRC_INNER_LOOP(n, c, x) \ -+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] -+ -+uint8 -+hndcrc8( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -+) -+{ -+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro -+ * to avoid the undefined and unnecessary (uint8 >> 8) operation. -+ */ -+ while (nbytes-- > 0) -+ crc = crc8_table[(crc ^ *pdata++) & 0xff]; -+ -+ return crc; -+} -+ -+/******************************************************************************* -+ * crc16 -+ * -+ * Computes a crc16 over the input data using the polynomial: -+ * -+ * x^16 + x^12 +x^5 + 1 -+ * -+ * The caller provides the initial value (either CRC16_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC16_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ * **************************************************************************** -+ */ -+ -+static const uint16 crc16_table[256] = { -+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, -+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, -+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, -+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, -+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, -+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, -+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, -+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, -+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, -+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, -+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, -+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, -+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, -+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, -+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, -+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, -+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, -+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, -+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, -+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, -+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, -+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, -+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, -+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, -+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, -+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, -+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, -+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, -+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, -+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, -+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, -+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -+}; -+ -+uint16 -+hndcrc16( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -+) -+{ -+ while (nbytes-- > 0) -+ CRC_INNER_LOOP(16, crc, *pdata++); -+ return crc; -+} -+ -+static const uint32 crc32_table[256] = { -+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, -+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, -+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, -+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, -+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, -+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, -+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, -+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, -+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, -+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, -+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, -+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, -+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, -+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, -+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, -+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, -+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, -+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, -+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, -+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, -+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, -+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, -+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, -+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, -+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, -+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, -+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, -+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, -+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, -+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, -+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, -+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, -+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, -+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, -+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, -+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, -+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, -+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, -+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, -+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, -+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, -+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, -+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, -+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, -+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, -+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, -+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, -+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, -+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, -+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, -+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, -+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, -+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, -+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, -+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, -+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, -+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, -+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, -+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, -+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, -+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -+}; -+ -+/* -+ * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if -+ * accumulating over multiple pieces. -+ */ -+uint32 -+hndcrc32(uint8 *pdata, uint nbytes, uint32 crc) -+{ -+ uint8 *pend; -+ pend = pdata + nbytes; -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ -+ return crc; -+} -+ -+#ifdef notdef -+#define CLEN 1499 /* CRC Length */ -+#define CBUFSIZ (CLEN+4) -+#define CNBUFS 5 /* # of bufs */ -+ -+void -+testcrc32(void) -+{ -+ uint j, k, l; -+ uint8 *buf; -+ uint len[CNBUFS]; -+ uint32 crcr; -+ uint32 crc32tv[CNBUFS] = -+ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; -+ -+ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); -+ -+ /* step through all possible alignments */ -+ for (l = 0; l <= 4; l++) { -+ for (j = 0; j < CNBUFS; j++) { -+ len[j] = CLEN; -+ for (k = 0; k < len[j]; k++) -+ *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; -+ } -+ -+ for (j = 0; j < CNBUFS; j++) { -+ crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); -+ ASSERT(crcr == crc32tv[j]); -+ } -+ } -+ -+ MFREE(buf, CBUFSIZ*CNBUFS); -+ return; -+} -+#endif /* notdef */ -+ -+/* -+ * Advance from the current 1-byte tag/1-byte length/variable-length value -+ * triple, to the next, returning a pointer to the next. -+ * If the current or next TLV is invalid (does not fit in given buffer length), -+ * NULL is returned. -+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented -+ * by the TLV parameter's length if it is valid. -+ */ -+bcm_tlv_t * -+bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -+{ -+ int len; -+ -+ /* validate current elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ /* advance to next elt */ -+ len = elt->len; -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (TLV_HDR_LEN + len); -+ -+ /* validate next elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ return elt; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag -+ */ -+bcm_tlv_t * -+bcm_parse_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= TLV_HDR_LEN) { -+ int len = elt->len; -+ -+ /* validate remaining totlen */ -+ if ((elt->id == key) && -+ (totlen >= (len + TLV_HDR_LEN))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); -+ totlen -= (len + TLV_HDR_LEN); -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag. Stop parsing when we see an element whose ID is greater -+ * than the target key. -+ */ -+bcm_tlv_t * -+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= TLV_HDR_LEN) { -+ uint id = elt->id; -+ int len = elt->len; -+ -+ /* Punt if we start seeing IDs > than target key */ -+ if (id > key) -+ return (NULL); -+ -+ /* validate remaining totlen */ -+ if ((id == key) && -+ (totlen >= (len + TLV_HDR_LEN))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); -+ totlen -= (len + TLV_HDR_LEN); -+ } -+ return NULL; -+} -+ -+#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ -+ defined(DHD_DEBUG) -+int -+bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) -+{ -+ int i; -+ char* p = buf; -+ char hexstr[16]; -+ int slen = 0, nlen = 0; -+ uint32 bit; -+ const char* name; -+ -+ if (len < 2 || !buf) -+ return 0; -+ -+ buf[0] = '\0'; -+ -+ for (i = 0; flags != 0; i++) { -+ bit = bd[i].bit; -+ name = bd[i].name; -+ if (bit == 0 && flags != 0) { -+ /* print any unnamed bits */ -+ snprintf(hexstr, 16, "0x%X", flags); -+ name = hexstr; -+ flags = 0; /* exit loop */ -+ } else if ((flags & bit) == 0) -+ continue; -+ flags &= ~bit; -+ nlen = strlen(name); -+ slen += nlen; -+ /* count btwn flag space */ -+ if (flags != 0) -+ slen += 1; -+ /* need NULL char as well */ -+ if (len <= slen) -+ break; -+ /* copy NULL char but don't count it */ -+ strncpy(p, name, nlen + 1); -+ p += nlen; -+ /* copy btwn flag space and NULL char */ -+ if (flags != 0) -+ p += snprintf(p, 2, " "); -+ } -+ -+ /* indicate the str was too short */ -+ if (flags != 0) { -+ if (len < 2) -+ p -= 2 - len; /* overwrite last char */ -+ p += snprintf(p, 2, ">"); -+ } -+ -+ return (int)(p - buf); -+} -+ -+/* print bytes formatted as hex to a string. return the resulting string length */ -+int -+bcm_format_hex(char *str, const void *bytes, int len) -+{ -+ int i; -+ char *p = str; -+ const uint8 *src = (const uint8*)bytes; -+ -+ for (i = 0; i < len; i++) { -+ p += snprintf(p, 3, "%02X", *src); -+ src++; -+ } -+ return (int)(p - str); -+} -+#endif -+ -+/* pretty hex print a contiguous buffer */ -+void -+prhex(const char *msg, uchar *buf, uint nbytes) -+{ -+ char line[128], *p; -+ int len = sizeof(line); -+ int nchar; -+ uint i; -+ -+ if (msg && (msg[0] != '\0')) -+ AP6210_DEBUG("%s:\n", msg); -+ -+ p = line; -+ for (i = 0; i < nbytes; i++) { -+ if (i % 16 == 0) { -+ nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ -+ p += nchar; -+ len -= nchar; -+ } -+ if (len > 0) { -+ nchar = snprintf(p, len, "%02x ", buf[i]); -+ p += nchar; -+ len -= nchar; -+ } -+ -+ if (i % 16 == 15) { -+ AP6210_DEBUG("%s\n", line); /* flush line */ -+ p = line; -+ len = sizeof(line); -+ } -+ } -+ -+ /* flush last partial line */ -+ if (p != line) -+ AP6210_DUMP("%s\n", line); -+} -+ -+static const char *crypto_algo_names[] = { -+ "NONE", -+ "WEP1", -+ "TKIP", -+ "WEP128", -+ "AES_CCM", -+ "AES_OCB_MSDU", -+ "AES_OCB_MPDU", -+ "NALG" -+ "UNDEF", -+ "UNDEF", -+ "UNDEF", -+#ifdef BCMWAPI_WPI -+ "WAPI", -+#endif /* BCMWAPI_WPI */ -+ "UNDEF" -+}; -+ -+const char * -+bcm_crypto_algo_name(uint algo) -+{ -+ return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR"; -+} -+ -+ -+char * -+bcm_chipname(uint chipid, char *buf, uint len) -+{ -+ const char *fmt; -+ -+ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; -+ snprintf(buf, len, fmt, chipid); -+ return buf; -+} -+ -+/* Produce a human-readable string for boardrev */ -+char * -+bcm_brev_str(uint32 brev, char *buf) -+{ -+ if (brev < 0x100) -+ snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); -+ else -+ snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); -+ -+ return (buf); -+} -+ -+#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ -+ -+/* dump large strings to console */ -+void -+printbig(char *buf) -+{ -+ uint len, max_len; -+ char c; -+ -+ len = strlen(buf); -+ -+ max_len = BUFSIZE_TODUMP_ATONCE; -+ -+ while (len > max_len) { -+ c = buf[max_len]; -+ buf[max_len] = '\0'; -+ AP6210_DUMP("%s", buf); -+ buf[max_len] = c; -+ -+ buf += max_len; -+ len -= max_len; -+ } -+ /* print the remaining string */ -+ AP6210_DUMP("%s\n", buf); -+ return; -+} -+ -+/* routine to dump fields in a fileddesc structure */ -+uint -+bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, -+ char *buf, uint32 bufsize) -+{ -+ uint filled_len; -+ int len; -+ struct fielddesc *cur_ptr; -+ -+ filled_len = 0; -+ cur_ptr = fielddesc_array; -+ -+ while (bufsize > 1) { -+ if (cur_ptr->nameandfmt == NULL) -+ break; -+ len = snprintf(buf, bufsize, cur_ptr->nameandfmt, -+ read_rtn(arg0, arg1, cur_ptr->offset)); -+ /* check for snprintf overflow or error */ -+ if (len < 0 || (uint32)len >= bufsize) -+ len = bufsize - 1; -+ buf += len; -+ bufsize -= len; -+ filled_len += len; -+ cur_ptr++; -+ } -+ return filled_len; -+} -+ -+uint -+bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -+{ -+ uint len; -+ -+ len = strlen(name) + 1; -+ -+ if ((len + datalen) > buflen) -+ return 0; -+ -+ strncpy(buf, name, buflen); -+ -+ /* append data onto the end of the name string */ -+ memcpy(&buf[len], data, datalen); -+ len += datalen; -+ -+ return len; -+} -+ -+/* Quarter dBm units to mW -+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 -+ * Table is offset so the last entry is largest mW value that fits in -+ * a uint16. -+ */ -+ -+#define QDBM_OFFSET 153 /* Offset for first entry */ -+#define QDBM_TABLE_LEN 40 /* Table size */ -+ -+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. -+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 -+ */ -+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ -+ -+/* Largest mW value that will round down to the last table entry, -+ * QDBM_OFFSET + QDBM_TABLE_LEN-1. -+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. -+ */ -+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ -+ -+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -+}; -+ -+uint16 -+bcm_qdbm_to_mw(uint8 qdbm) -+{ -+ uint factor = 1; -+ int idx = qdbm - QDBM_OFFSET; -+ -+ if (idx >= QDBM_TABLE_LEN) { -+ /* clamp to max uint16 mW value */ -+ return 0xFFFF; -+ } -+ -+ /* scale the qdBm index up to the range of the table 0-40 -+ * where an offset of 40 qdBm equals a factor of 10 mW. -+ */ -+ while (idx < 0) { -+ idx += 40; -+ factor *= 10; -+ } -+ -+ /* return the mW value scaled down to the correct factor of 10, -+ * adding in factor/2 to get proper rounding. -+ */ -+ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -+} -+ -+uint8 -+bcm_mw_to_qdbm(uint16 mw) -+{ -+ uint8 qdbm; -+ int offset; -+ uint mw_uint = mw; -+ uint boundary; -+ -+ /* handle boundary case */ -+ if (mw_uint <= 1) -+ return 0; -+ -+ offset = QDBM_OFFSET; -+ -+ /* move mw into the range of the table */ -+ while (mw_uint < QDBM_TABLE_LOW_BOUND) { -+ mw_uint *= 10; -+ offset -= 40; -+ } -+ -+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { -+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - -+ nqdBm_to_mW_map[qdbm])/2; -+ if (mw_uint < boundary) break; -+ } -+ -+ qdbm += (uint8)offset; -+ -+ return (qdbm); -+} -+ -+ -+uint -+bcm_bitcount(uint8 *bitmap, uint length) -+{ -+ uint bitcount = 0, i; -+ uint8 tmp; -+ for (i = 0; i < length; i++) { -+ tmp = bitmap[i]; -+ while (tmp) { -+ bitcount++; -+ tmp &= (tmp - 1); -+ } -+ } -+ return bitcount; -+} -+ -+#ifdef BCMDRIVER -+ -+/* Initialization of bcmstrbuf structure */ -+void -+bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -+{ -+ b->origsize = b->size = size; -+ b->origbuf = b->buf = buf; -+} -+ -+/* Buffer sprintf wrapper to guard against buffer overflow */ -+int -+bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -+{ -+ va_list ap; -+ int r; -+ -+ va_start(ap, fmt); -+ -+ r = vsnprintf(b->buf, b->size, fmt, ap); -+ -+ /* Non Ansi C99 compliant returns -1, -+ * Ansi compliant return r >= b->size, -+ * bcmstdlib returns 0, handle all -+ */ -+ /* r == 0 is also the case when strlen(fmt) is zero. -+ * typically the case when "" is passed as argument. -+ */ -+ if ((r == -1) || (r >= (int)b->size)) { -+ b->size = 0; -+ } else { -+ b->size -= r; -+ b->buf += r; -+ } -+ -+ va_end(ap); -+ -+ return r; -+} -+ -+void -+bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len) -+{ -+ int i; -+ -+ if (msg != NULL && msg[0] != '\0') -+ bcm_bprintf(b, "%s", msg); -+ for (i = 0; i < len; i ++) -+ bcm_bprintf(b, "%02X", buf[i]); -+ if (newline) -+ bcm_bprintf(b, "\n"); -+} -+ -+void -+bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) -+{ -+ int i; -+ -+ for (i = 0; i < num_bytes; i++) { -+ num[i] += amount; -+ if (num[i] >= amount) -+ break; -+ amount = 1; -+ } -+} -+ -+int -+bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes) -+{ -+ int i; -+ -+ for (i = nbytes - 1; i >= 0; i--) { -+ if (arg1[i] != arg2[i]) -+ return (arg1[i] - arg2[i]); -+ } -+ return 0; -+} -+ -+void -+bcm_print_bytes(const char *name, const uchar *data, int len) -+{ -+ int i; -+ int per_line = 0; -+ -+ AP6210_DEBUG("%s: %d \n", name ? name : "", len); -+ for (i = 0; i < len; i++) { -+ AP6210_DUMP("%02x ", *data++); -+ per_line++; -+ if (per_line == 16) { -+ per_line = 0; -+ AP6210_DUMP("\n"); -+ } -+ } -+ AP6210_DUMP("\n"); -+} -+#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ -+ defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) -+ -+int -+bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) -+{ -+ uint i, c; -+ char *p = buf; -+ char *endp = buf + SSID_FMT_BUF_LEN; -+ -+ if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN; -+ -+ for (i = 0; i < ssid_len; i++) { -+ c = (uint)ssid[i]; -+ if (c == '\\') { -+ *p++ = '\\'; -+ *p++ = '\\'; -+ } else if (bcm_isprint((uchar)c)) { -+ *p++ = (char)c; -+ } else { -+ p += snprintf(p, (endp - p), "\\x%02X", c); -+ } -+ } -+ *p = '\0'; -+ ASSERT(p < endp); -+ -+ return (int)(p - buf); -+} -+#endif -+ -+#endif /* BCMDRIVER */ -+ -+/* -+ * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. -+ * also accepts nvram files which are already in the format of =\0\=\0 -+ * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. -+ * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. -+*/ -+ -+unsigned int -+process_nvram_vars(char *varbuf, unsigned int len) -+{ -+ char *dp; -+ bool findNewline; -+ int column; -+ unsigned int buf_len, n; -+ unsigned int pad = 0; -+ -+ dp = varbuf; -+ -+ findNewline = FALSE; -+ column = 0; -+ -+ for (n = 0; n < len; n++) { -+ if (varbuf[n] == '\r') -+ continue; -+ if (findNewline && varbuf[n] != '\n') -+ continue; -+ findNewline = FALSE; -+ if (varbuf[n] == '#') { -+ findNewline = TRUE; -+ continue; -+ } -+ if (varbuf[n] == '\n') { -+ if (column == 0) -+ continue; -+ *dp++ = 0; -+ column = 0; -+ continue; -+ } -+ *dp++ = varbuf[n]; -+ column++; -+ } -+ buf_len = (unsigned int)(dp - varbuf); -+ if (buf_len % 4) { -+ pad = 4 - buf_len % 4; -+ if (pad && (buf_len + pad <= len)) { -+ buf_len += pad; -+ } -+ } -+ -+ while (dp < varbuf + n) -+ *dp++ = 0; -+ -+ return buf_len; -+} -diff --git a/drivers/net/wireless/ap6210/bcmwifi_channels.c b/drivers/net/wireless/ap6210/bcmwifi_channels.c -new file mode 100644 -index 0000000..6b5b0a3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/bcmwifi_channels.c -@@ -0,0 +1,1179 @@ -+/* -+ * Misc utility routines used by kernel or app-level. -+ * Contents are wifi-specific, used by any kernel or app-level -+ * software that might want wifi things as it grows. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: bcmwifi_channels.c 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#include -+#include -+ -+#ifdef BCMDRIVER -+#include -+#include -+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -+#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -+#else -+#include -+#include -+#include -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+#endif /* BCMDRIVER */ -+ -+#ifdef _bcmwifi_c_ -+/* temporary for transitional compatibility */ -+#include -+#else -+#include -+#endif -+ -+#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) -+#include /* For wl/exe/GNUmakefile.brcm_wlu and GNUmakefile.wlm_dll */ -+#endif -+ -+#ifndef D11AC_IOTYPES -+ -+/* Definitions for legacy Chanspec type */ -+ -+/* Chanspec ASCII representation: -+ * -+ * digit [AB] [N] [UL] -+ * -+ * : channel number of the 10MHz or 20MHz channel, -+ * or control sideband channel of 40MHz channel. -+ * : A for 5GHz, B for 2.4GHz -+ * : N for 10MHz, nothing for 20MHz or 40MHz -+ * (ctl-sideband spec implies 40MHz) -+ * : U for upper, L for lower -+ * -+ * may be omitted on input, and will be assumed to be -+ * 2.4GHz if channel number <= 14. -+ * -+ * Examples: -+ * 8 -> 2.4GHz channel 8, 20MHz -+ * 8b -> 2.4GHz channel 8, 20MHz -+ * 8l -> 2.4GHz channel 8, 40MHz, lower ctl sideband -+ * 8a -> 5GHz channel 8 (low 5 GHz band), 20MHz -+ * 36 -> 5GHz channel 36, 20MHz -+ * 36l -> 5GHz channel 36, 40MHz, lower ctl sideband -+ * 40u -> 5GHz channel 40, 40MHz, upper ctl sideband -+ * 180n -> channel 180, 10MHz -+ */ -+ -+ -+/* given a chanspec and a string buffer, format the chanspec as a -+ * string, and return the original pointer a. -+ * Min buffer length must be CHANSPEC_STR_LEN. -+ * On error return NULL -+ */ -+char * -+wf_chspec_ntoa(chanspec_t chspec, char *buf) -+{ -+ const char *band, *bw, *sb; -+ uint channel; -+ -+ band = ""; -+ bw = ""; -+ sb = ""; -+ channel = CHSPEC_CHANNEL(chspec); -+ /* check for non-default band spec */ -+ if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) || -+ (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL)) -+ band = (CHSPEC_IS2G(chspec)) ? "b" : "a"; -+ if (CHSPEC_IS40(chspec)) { -+ if (CHSPEC_SB_UPPER(chspec)) { -+ sb = "u"; -+ channel += CH_10MHZ_APART; -+ } else { -+ sb = "l"; -+ channel -= CH_10MHZ_APART; -+ } -+ } else if (CHSPEC_IS10(chspec)) { -+ bw = "n"; -+ } -+ -+ /* Outputs a max of 6 chars including '\0' */ -+ snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb); -+ return (buf); -+} -+ -+/* given a chanspec string, convert to a chanspec. -+ * On error return 0 -+ */ -+chanspec_t -+wf_chspec_aton(const char *a) -+{ -+ char *endp = NULL; -+ uint channel, band, bw, ctl_sb; -+ char c; -+ -+ channel = strtoul(a, &endp, 10); -+ -+ /* check for no digits parsed */ -+ if (endp == a) -+ return 0; -+ -+ if (channel > MAXCHANNEL) -+ return 0; -+ -+ band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); -+ bw = WL_CHANSPEC_BW_20; -+ ctl_sb = WL_CHANSPEC_CTL_SB_NONE; -+ -+ a = endp; -+ -+ c = tolower(a[0]); -+ if (c == '\0') -+ goto done; -+ -+ /* parse the optional ['A' | 'B'] band spec */ -+ if (c == 'a' || c == 'b') { -+ band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G; -+ a++; -+ c = tolower(a[0]); -+ if (c == '\0') -+ goto done; -+ } -+ -+ /* parse bandwidth 'N' (10MHz) or 40MHz ctl sideband ['L' | 'U'] */ -+ if (c == 'n') { -+ bw = WL_CHANSPEC_BW_10; -+ } else if (c == 'l') { -+ bw = WL_CHANSPEC_BW_40; -+ ctl_sb = WL_CHANSPEC_CTL_SB_LOWER; -+ /* adjust channel to center of 40MHz band */ -+ if (channel <= (MAXCHANNEL - CH_20MHZ_APART)) -+ channel += CH_10MHZ_APART; -+ else -+ return 0; -+ } else if (c == 'u') { -+ bw = WL_CHANSPEC_BW_40; -+ ctl_sb = WL_CHANSPEC_CTL_SB_UPPER; -+ /* adjust channel to center of 40MHz band */ -+ if (channel > CH_20MHZ_APART) -+ channel -= CH_10MHZ_APART; -+ else -+ return 0; -+ } else { -+ return 0; -+ } -+ -+done: -+ return (channel | band | bw | ctl_sb); -+} -+ -+/* -+ * Verify the chanspec is using a legal set of parameters, i.e. that the -+ * chanspec specified a band, bw, ctl_sb and channel and that the -+ * combination could be legal given any set of circumstances. -+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good. -+ */ -+bool -+wf_chspec_malformed(chanspec_t chanspec) -+{ -+ /* must be 2G or 5G band */ -+ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) -+ return TRUE; -+ /* must be 20 or 40 bandwidth */ -+ if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec)) -+ return TRUE; -+ -+ /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */ -+ if (CHSPEC_IS20(chanspec)) { -+ if (!CHSPEC_SB_NONE(chanspec)) -+ return TRUE; -+ } else { -+ if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * This function returns the channel number that control traffic is being sent on, for legacy -+ * channels this is just the channel number, for 40MHZ channels it is the upper or lower 20MHZ -+ * sideband depending on the chanspec selected -+ */ -+uint8 -+wf_chspec_ctlchan(chanspec_t chspec) -+{ -+ uint8 ctl_chan; -+ -+ /* Is there a sideband ? */ -+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { -+ return CHSPEC_CHANNEL(chspec); -+ } else { -+ /* we only support 40MHZ with sidebands */ -+ ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40); -+ /* chanspec channel holds the centre frequency, use that and the -+ * side band information to reconstruct the control channel number -+ */ -+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { -+ /* control chan is the upper 20 MHZ SB of the 40MHZ channel */ -+ ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); -+ } else { -+ ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER); -+ /* control chan is the lower 20 MHZ SB of the 40MHZ channel */ -+ ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); -+ } -+ } -+ -+ return ctl_chan; -+} -+ -+chanspec_t -+wf_chspec_ctlchspec(chanspec_t chspec) -+{ -+ chanspec_t ctl_chspec = 0; -+ uint8 channel; -+ -+ ASSERT(!wf_chspec_malformed(chspec)); -+ -+ /* Is there a sideband ? */ -+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { -+ return chspec; -+ } else { -+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { -+ channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); -+ } else { -+ channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); -+ } -+ ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; -+ ctl_chspec |= CHSPEC_BAND(chspec); -+ } -+ return ctl_chspec; -+} -+ -+#else /* D11AC_IOTYPES */ -+ -+/* Definitions for D11AC capable Chanspec type */ -+ -+/* Chanspec ASCII representation with 802.11ac capability: -+ * [ 'g'] ['/' []['/'<1st80channel>'-'<2nd80channel>]] -+ * -+ * : -+ * (optional) 2, 3, 4, 5 for 2.4GHz, 3GHz, 4GHz, and 5GHz respectively. -+ * Default value is 2g if channel <= 14, otherwise 5g. -+ * : -+ * channel number of the 5MHz, 10MHz, 20MHz channel, -+ * or primary channel of 40MHz, 80MHz, 160MHz, or 80+80MHz channel. -+ * : -+ * (optional) 5, 10, 20, 40, 80, 160, or 80+80. Default value is 20. -+ * : -+ * (only for 2.4GHz band 40MHz) U for upper sideband primary, L for lower. -+ * -+ * For 2.4GHz band 40MHz channels, the same primary channel may be the -+ * upper sideband for one 40MHz channel, and the lower sideband for an -+ * overlapping 40MHz channel. The U/L disambiguates which 40MHz channel -+ * is being specified. -+ * -+ * For 40MHz in the 5GHz band and all channel bandwidths greater than -+ * 40MHz, the U/L specificaion is not allowed since the channels are -+ * non-overlapping and the primary sub-band is derived from its -+ * position in the wide bandwidth channel. -+ * -+ * <1st80Channel>: -+ * <2nd80Channel>: -+ * Required for 80+80, otherwise not allowed. -+ * Specifies the center channel of the first and second 80MHz band. -+ * -+ * In its simplest form, it is a 20MHz channel number, with the implied band -+ * of 2.4GHz if channel number <= 14, and 5GHz otherwise. -+ * -+ * To allow for backward compatibility with scripts, the old form for -+ * 40MHz channels is also allowed: -+ * -+ * : -+ * primary channel of 40MHz, channel <= 14 is 2GHz, otherwise 5GHz -+ * : -+ * "U" for upper, "L" for lower (or lower case "u" "l") -+ * -+ * 5 GHz Examples: -+ * Chanspec BW Center Ch Channel Range Primary Ch -+ * 5g8 20MHz 8 - - -+ * 52 20MHz 52 - - -+ * 52/40 40MHz 54 52-56 52 -+ * 56/40 40MHz 54 52-56 56 -+ * 52/80 80MHz 58 52-64 52 -+ * 56/80 80MHz 58 52-64 56 -+ * 60/80 80MHz 58 52-64 60 -+ * 64/80 80MHz 58 52-64 64 -+ * 52/160 160MHz 50 36-64 52 -+ * 36/160 160MGz 50 36-64 36 -+ * 36/80+80/42-106 80+80MHz 42,106 36-48,100-112 36 -+ * -+ * 2 GHz Examples: -+ * Chanspec BW Center Ch Channel Range Primary Ch -+ * 2g8 20MHz 8 - - -+ * 8 20MHz 8 - - -+ * 6 20MHz 6 - - -+ * 6/40l 40MHz 8 6-10 6 -+ * 6l 40MHz 8 6-10 6 -+ * 6/40u 40MHz 4 2-6 6 -+ * 6u 40MHz 4 2-6 6 -+ */ -+ -+/* bandwidth ASCII string */ -+static const char *wf_chspec_bw_str[] = -+{ -+ "5", -+ "10", -+ "20", -+ "40", -+ "80", -+ "160", -+ "80+80", -+ "na" -+}; -+ -+static const uint8 wf_chspec_bw_mhz[] = -+{5, 10, 20, 40, 80, 160, 160}; -+ -+#define WF_NUM_BW \ -+ (sizeof(wf_chspec_bw_mhz)/sizeof(uint8)) -+ -+/* 40MHz channels in 5GHz band */ -+static const uint8 wf_5g_40m_chans[] = -+{38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159}; -+#define WF_NUM_5G_40M_CHANS \ -+ (sizeof(wf_5g_40m_chans)/sizeof(uint8)) -+ -+/* 80MHz channels in 5GHz band */ -+static const uint8 wf_5g_80m_chans[] = -+{42, 58, 106, 122, 138, 155}; -+#define WF_NUM_5G_80M_CHANS \ -+ (sizeof(wf_5g_80m_chans)/sizeof(uint8)) -+ -+/* 160MHz channels in 5GHz band */ -+static const uint8 wf_5g_160m_chans[] = -+{50, 114}; -+#define WF_NUM_5G_160M_CHANS \ -+ (sizeof(wf_5g_160m_chans)/sizeof(uint8)) -+ -+ -+/* convert bandwidth from chanspec to MHz */ -+static uint -+bw_chspec_to_mhz(chanspec_t chspec) -+{ -+ uint bw; -+ -+ bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT; -+ return (bw >= WF_NUM_BW ? 0 : wf_chspec_bw_mhz[bw]); -+} -+ -+/* bw in MHz, return the channel count from the center channel to the -+ * the channel at the edge of the band -+ */ -+static uint8 -+center_chan_to_edge(uint bw) -+{ -+ /* edge channels separated by BW - 10MHz on each side -+ * delta from cf to edge is half of that, -+ * MHz to channel num conversion is 5MHz/channel -+ */ -+ return (uint8)(((bw - 20) / 2) / 5); -+} -+ -+/* return channel number of the low edge of the band -+ * given the center channel and BW -+ */ -+static uint8 -+channel_low_edge(uint center_ch, uint bw) -+{ -+ return (uint8)(center_ch - center_chan_to_edge(bw)); -+} -+ -+/* return side band number given center channel and control channel -+ * return -1 on error -+ */ -+static int -+channel_to_sb(uint center_ch, uint ctl_ch, uint bw) -+{ -+ uint lowest = channel_low_edge(center_ch, bw); -+ uint sb; -+ -+ if ((ctl_ch - lowest) % 4) { -+ /* bad ctl channel, not mult 4 */ -+ return -1; -+ } -+ -+ sb = ((ctl_ch - lowest) / 4); -+ -+ /* sb must be a index to a 20MHz channel in range */ -+ if (sb >= (bw / 20)) { -+ /* ctl_ch must have been too high for the center_ch */ -+ return -1; -+ } -+ -+ return sb; -+} -+ -+/* return control channel given center channel and side band */ -+static uint8 -+channel_to_ctl_chan(uint center_ch, uint bw, uint sb) -+{ -+ return (uint8)(channel_low_edge(center_ch, bw) + sb * 4); -+} -+ -+/* return index of 80MHz channel from channel number -+ * return -1 on error -+ */ -+static int -+channel_80mhz_to_id(uint ch) -+{ -+ uint i; -+ for (i = 0; i < WF_NUM_5G_80M_CHANS; i ++) { -+ if (ch == wf_5g_80m_chans[i]) -+ return i; -+ } -+ -+ return -1; -+} -+ -+/* given a chanspec and a string buffer, format the chanspec as a -+ * string, and return the original pointer a. -+ * Min buffer length must be CHANSPEC_STR_LEN. -+ * On error return NULL -+ */ -+char * -+wf_chspec_ntoa(chanspec_t chspec, char *buf) -+{ -+ const char *band; -+ uint ctl_chan; -+ -+ if (wf_chspec_malformed(chspec)) -+ return NULL; -+ -+ band = ""; -+ -+ /* check for non-default band spec */ -+ if ((CHSPEC_IS2G(chspec) && CHSPEC_CHANNEL(chspec) > CH_MAX_2G_CHANNEL) || -+ (CHSPEC_IS5G(chspec) && CHSPEC_CHANNEL(chspec) <= CH_MAX_2G_CHANNEL)) -+ band = (CHSPEC_IS2G(chspec)) ? "2g" : "5g"; -+ -+ /* ctl channel */ -+ ctl_chan = wf_chspec_ctlchan(chspec); -+ -+ /* bandwidth and ctl sideband */ -+ if (CHSPEC_IS20(chspec)) { -+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, ctl_chan); -+ } else if (!CHSPEC_IS8080(chspec)) { -+ const char *bw; -+ const char *sb = ""; -+ -+ bw = wf_chspec_bw_str[(chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT]; -+ -+#ifdef CHANSPEC_NEW_40MHZ_FORMAT -+ /* ctl sideband string if needed for 2g 40MHz */ -+ if (CHSPEC_IS40(chspec) && CHSPEC_IS2G(chspec)) { -+ sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; -+ } -+ -+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s%s", band, ctl_chan, bw, sb); -+#else -+ /* ctl sideband string instead of BW for 40MHz */ -+ if (CHSPEC_IS40(chspec)) { -+ sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; -+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d%s", band, ctl_chan, sb); -+ } else { -+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, ctl_chan, bw); -+ } -+#endif /* CHANSPEC_NEW_40MHZ_FORMAT */ -+ -+ } else { -+ /* 80+80 */ -+ uint chan1 = (chspec & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT; -+ uint chan2 = (chspec & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT; -+ -+ /* convert to channel number */ -+ chan1 = (chan1 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan1] : 0; -+ chan2 = (chan2 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan2] : 0; -+ -+ /* Outputs a max of CHANSPEC_STR_LEN chars including '\0' */ -+ snprintf(buf, CHANSPEC_STR_LEN, "%d/80+80/%d-%d", ctl_chan, chan1, chan2); -+ } -+ -+ return (buf); -+} -+ -+static int -+read_uint(const char **p, unsigned int *num) -+{ -+ unsigned long val; -+ char *endp = NULL; -+ -+ val = strtoul(*p, &endp, 10); -+ /* if endp is the initial pointer value, then a number was not read */ -+ if (endp == *p) -+ return 0; -+ -+ /* advance the buffer pointer to the end of the integer string */ -+ *p = endp; -+ /* return the parsed integer */ -+ *num = (unsigned int)val; -+ -+ return 1; -+} -+ -+/* given a chanspec string, convert to a chanspec. -+ * On error return 0 -+ */ -+chanspec_t -+wf_chspec_aton(const char *a) -+{ -+ chanspec_t chspec; -+ uint chspec_ch, chspec_band, bw, chspec_bw, chspec_sb; -+ uint num, ctl_ch; -+ uint ch1, ch2; -+ char c, sb_ul = '\0'; -+ int i; -+ -+ bw = 20; -+ chspec_sb = 0; -+ chspec_ch = ch1 = ch2 = 0; -+ -+ /* parse channel num or band */ -+ if (!read_uint(&a, &num)) -+ return 0; -+ -+ /* if we are looking at a 'g', then the first number was a band */ -+ c = tolower(a[0]); -+ if (c == 'g') { -+ a ++; /* consume the char */ -+ -+ /* band must be "2" or "5" */ -+ if (num == 2) -+ chspec_band = WL_CHANSPEC_BAND_2G; -+ else if (num == 5) -+ chspec_band = WL_CHANSPEC_BAND_5G; -+ else -+ return 0; -+ -+ /* read the channel number */ -+ if (!read_uint(&a, &ctl_ch)) -+ return 0; -+ -+ c = tolower(a[0]); -+ } -+ else { -+ /* first number is channel, use default for band */ -+ ctl_ch = num; -+ chspec_band = ((ctl_ch <= CH_MAX_2G_CHANNEL) ? -+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); -+ } -+ -+ if (c == '\0') { -+ /* default BW of 20MHz */ -+ chspec_bw = WL_CHANSPEC_BW_20; -+ goto done_read; -+ } -+ -+ a ++; /* consume the 'u','l', or '/' */ -+ -+ /* check 'u'/'l' */ -+ if (c == 'u' || c == 'l') { -+ sb_ul = c; -+ chspec_bw = WL_CHANSPEC_BW_40; -+ goto done_read; -+ } -+ -+ /* next letter must be '/' */ -+ if (c != '/') -+ return 0; -+ -+ /* read bandwidth */ -+ if (!read_uint(&a, &bw)) -+ return 0; -+ -+ /* convert to chspec value */ -+ if (bw == 20) { -+ chspec_bw = WL_CHANSPEC_BW_20; -+ } else if (bw == 40) { -+ chspec_bw = WL_CHANSPEC_BW_40; -+ } else if (bw == 80) { -+ chspec_bw = WL_CHANSPEC_BW_80; -+ } else if (bw == 160) { -+ chspec_bw = WL_CHANSPEC_BW_160; -+ } else { -+ return 0; -+ } -+ -+ /* So far we have g/ -+ * Can now be followed by u/l if bw = 40, -+ * or '+80' if bw = 80, to make '80+80' bw. -+ */ -+ -+ c = tolower(a[0]); -+ -+ /* if we have a 2g/40 channel, we should have a l/u spec now */ -+ if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) { -+ if (c == 'u' || c == 'l') { -+ a ++; /* consume the u/l char */ -+ sb_ul = c; -+ goto done_read; -+ } -+ } -+ -+ /* check for 80+80 */ -+ if (c == '+') { -+ /* 80+80 */ -+ static const char *plus80 = "80/"; -+ -+ /* must be looking at '+80/' -+ * check and consume this string. -+ */ -+ chspec_bw = WL_CHANSPEC_BW_8080; -+ -+ a ++; /* consume the char '+' */ -+ -+ /* consume the '80/' string */ -+ for (i = 0; i < 3; i++) { -+ if (*a++ != *plus80++) { -+ return 0; -+ } -+ } -+ -+ /* read primary 80MHz channel */ -+ if (!read_uint(&a, &ch1)) -+ return 0; -+ -+ /* must followed by '-' */ -+ if (a[0] != '-') -+ return 0; -+ a ++; /* consume the char */ -+ -+ /* read secondary 80MHz channel */ -+ if (!read_uint(&a, &ch2)) -+ return 0; -+ } -+ -+done_read: -+ /* skip trailing white space */ -+ while (a[0] == ' ') { -+ a ++; -+ } -+ -+ /* must be end of string */ -+ if (a[0] != '\0') -+ return 0; -+ -+ /* Now have all the chanspec string parts read; -+ * chspec_band, ctl_ch, chspec_bw, sb_ul, ch1, ch2. -+ * chspec_band and chspec_bw are chanspec values. -+ * Need to convert ctl_ch, sb_ul, and ch1,ch2 into -+ * a center channel (or two) and sideband. -+ */ -+ -+ /* if a sb u/l string was given, just use that, -+ * guaranteed to be bw = 40 by sting parse. -+ */ -+ if (sb_ul != '\0') { -+ if (sb_ul == 'l') { -+ chspec_ch = UPPER_20_SB(ctl_ch); -+ chspec_sb = WL_CHANSPEC_CTL_SB_LLL; -+ } else if (sb_ul == 'u') { -+ chspec_ch = LOWER_20_SB(ctl_ch); -+ chspec_sb = WL_CHANSPEC_CTL_SB_LLU; -+ } -+ } -+ /* if the bw is 20, center and sideband are trivial */ -+ else if (chspec_bw == WL_CHANSPEC_BW_20) { -+ chspec_ch = ctl_ch; -+ chspec_sb = 0; -+ } -+ /* if the bw is 40/80/160, not 80+80, a single method -+ * can be used to to find the center and sideband -+ */ -+ else if (chspec_bw != WL_CHANSPEC_BW_8080) { -+ /* figure out ctl sideband based on ctl channel and bandwidth */ -+ const uint8 *center_ch = NULL; -+ int num_ch = 0; -+ int sb = -1; -+ -+ if (chspec_bw == WL_CHANSPEC_BW_40) { -+ center_ch = wf_5g_40m_chans; -+ num_ch = WF_NUM_5G_40M_CHANS; -+ } else if (chspec_bw == WL_CHANSPEC_BW_80) { -+ center_ch = wf_5g_80m_chans; -+ num_ch = WF_NUM_5G_80M_CHANS; -+ } else if (chspec_bw == WL_CHANSPEC_BW_160) { -+ center_ch = wf_5g_160m_chans; -+ num_ch = WF_NUM_5G_160M_CHANS; -+ } else { -+ return 0; -+ } -+ -+ for (i = 0; i < num_ch; i ++) { -+ sb = channel_to_sb(center_ch[i], ctl_ch, bw); -+ if (sb >= 0) { -+ chspec_ch = center_ch[i]; -+ chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; -+ break; -+ } -+ } -+ -+ /* check for no matching sb/center */ -+ if (sb < 0) { -+ return 0; -+ } -+ } -+ /* Otherwise, bw is 80+80. Figure out channel pair and sb */ -+ else { -+ int ch1_id = 0, ch2_id = 0; -+ int sb; -+ -+ ch1_id = channel_80mhz_to_id(ch1); -+ ch2_id = channel_80mhz_to_id(ch2); -+ -+ /* validate channels */ -+ if (ch1 >= ch2 || ch1_id < 0 || ch2_id < 0) -+ return 0; -+ -+ /* combined channel in chspec */ -+ chspec_ch = (((uint16)ch1_id << WL_CHANSPEC_CHAN1_SHIFT) | -+ ((uint16)ch2_id << WL_CHANSPEC_CHAN2_SHIFT)); -+ -+ /* figure out ctl sideband */ -+ -+ /* does the primary channel fit with the 1st 80MHz channel ? */ -+ sb = channel_to_sb(ch1, ctl_ch, bw); -+ if (sb < 0) { -+ /* no, so does the primary channel fit with the 2nd 80MHz channel ? */ -+ sb = channel_to_sb(ch2, ctl_ch, bw); -+ if (sb < 0) { -+ /* no match for ctl_ch to either 80MHz center channel */ -+ return 0; -+ } -+ /* sb index is 0-3 for the low 80MHz channel, and 4-7 for -+ * the high 80MHz channel. Add 4 to to shift to high set. -+ */ -+ sb += 4; -+ } -+ -+ chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; -+ } -+ -+ chspec = (chspec_ch | chspec_band | chspec_bw | chspec_sb); -+ -+ if (wf_chspec_malformed(chspec)) -+ return 0; -+ -+ return chspec; -+} -+ -+/* -+ * Verify the chanspec is using a legal set of parameters, i.e. that the -+ * chanspec specified a band, bw, ctl_sb and channel and that the -+ * combination could be legal given any set of circumstances. -+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good. -+ */ -+bool -+wf_chspec_malformed(chanspec_t chanspec) -+{ -+ uint chspec_bw = CHSPEC_BW(chanspec); -+ uint chspec_ch = CHSPEC_CHANNEL(chanspec); -+ -+ /* must be 2G or 5G band */ -+ if (CHSPEC_IS2G(chanspec)) { -+ /* must be valid bandwidth */ -+ if (chspec_bw != WL_CHANSPEC_BW_20 && -+ chspec_bw != WL_CHANSPEC_BW_40) { -+ return TRUE; -+ } -+ } else if (CHSPEC_IS5G(chanspec)) { -+ if (chspec_bw == WL_CHANSPEC_BW_8080) { -+ uint ch1_id, ch2_id; -+ -+ /* channel number in 80+80 must be in range */ -+ ch1_id = CHSPEC_CHAN1(chanspec); -+ ch2_id = CHSPEC_CHAN2(chanspec); -+ if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS) -+ return TRUE; -+ -+ /* ch2 must be above ch1 for the chanspec */ -+ if (ch2_id <= ch1_id) -+ return TRUE; -+ } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 || -+ chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) { -+ -+ if (chspec_ch > MAXCHANNEL) { -+ return TRUE; -+ } -+ } else { -+ /* invalid bandwidth */ -+ return TRUE; -+ } -+ } else { -+ /* must be 2G or 5G band */ -+ return TRUE; -+ } -+ -+ /* side band needs to be consistent with bandwidth */ -+ if (chspec_bw == WL_CHANSPEC_BW_20) { -+ if (CHSPEC_CTL_SB(chanspec) != WL_CHANSPEC_CTL_SB_LLL) -+ return TRUE; -+ } else if (chspec_bw == WL_CHANSPEC_BW_40) { -+ if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LLU) -+ return TRUE; -+ } else if (chspec_bw == WL_CHANSPEC_BW_80) { -+ if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LUU) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * Verify the chanspec specifies a valid channel according to 802.11. -+ * RETURNS: TRUE if the chanspec is a valid 802.11 channel -+ */ -+bool -+wf_chspec_valid(chanspec_t chanspec) -+{ -+ uint chspec_bw = CHSPEC_BW(chanspec); -+ uint chspec_ch = CHSPEC_CHANNEL(chanspec); -+ -+ if (wf_chspec_malformed(chanspec)) -+ return FALSE; -+ -+ if (CHSPEC_IS2G(chanspec)) { -+ /* must be valid bandwidth and channel range */ -+ if (chspec_bw == WL_CHANSPEC_BW_20) { -+ if (chspec_ch >= 1 && chspec_ch <= 14) -+ return TRUE; -+ } else if (chspec_bw == WL_CHANSPEC_BW_40) { -+ if (chspec_ch >= 3 && chspec_ch <= 11) -+ return TRUE; -+ } -+ } else if (CHSPEC_IS5G(chanspec)) { -+ if (chspec_bw == WL_CHANSPEC_BW_8080) { -+ uint16 ch1, ch2; -+ -+ ch1 = wf_5g_80m_chans[CHSPEC_CHAN1(chanspec)]; -+ ch2 = wf_5g_80m_chans[CHSPEC_CHAN2(chanspec)]; -+ -+ /* the two channels must be separated by more than 80MHz by VHT req, -+ * and ch2 above ch1 for the chanspec -+ */ -+ if (ch2 > ch1 + CH_80MHZ_APART) -+ return TRUE; -+ } else { -+ const uint8 *center_ch; -+ uint num_ch, i; -+ -+ if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40) { -+ center_ch = wf_5g_40m_chans; -+ num_ch = WF_NUM_5G_40M_CHANS; -+ } else if (chspec_bw == WL_CHANSPEC_BW_80) { -+ center_ch = wf_5g_80m_chans; -+ num_ch = WF_NUM_5G_80M_CHANS; -+ } else if (chspec_bw == WL_CHANSPEC_BW_160) { -+ center_ch = wf_5g_160m_chans; -+ num_ch = WF_NUM_5G_160M_CHANS; -+ } else { -+ /* invalid bandwidth */ -+ return FALSE; -+ } -+ -+ /* check for a valid center channel */ -+ if (chspec_bw == WL_CHANSPEC_BW_20) { -+ /* We don't have an array of legal 20MHz 5G channels, but they are -+ * each side of the legal 40MHz channels. Check the chanspec -+ * channel against either side of the 40MHz channels. -+ */ -+ for (i = 0; i < num_ch; i ++) { -+ if (chspec_ch == (uint)LOWER_20_SB(center_ch[i]) || -+ chspec_ch == (uint)UPPER_20_SB(center_ch[i])) -+ break; /* match found */ -+ } -+ -+ if (i == num_ch) { -+ /* check for legacy JP channels on failure */ -+ if (chspec_ch == 34 || chspec_ch == 38 || -+ chspec_ch == 42 || chspec_ch == 46) -+ i = 0; -+ } -+ } else { -+ /* check the chanspec channel to each legal channel */ -+ for (i = 0; i < num_ch; i ++) { -+ if (chspec_ch == center_ch[i]) -+ break; /* match found */ -+ } -+ } -+ -+ if (i < num_ch) { -+ /* match found */ -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+/* -+ * This function returns the channel number that control traffic is being sent on, for 20MHz -+ * channels this is just the channel number, for 40MHZ, 80MHz, 160MHz channels it is the 20MHZ -+ * sideband depending on the chanspec selected -+ */ -+uint8 -+wf_chspec_ctlchan(chanspec_t chspec) -+{ -+ uint center_chan; -+ uint bw_mhz; -+ uint sb; -+ -+ ASSERT(!wf_chspec_malformed(chspec)); -+ -+ /* Is there a sideband ? */ -+ if (CHSPEC_IS20(chspec)) { -+ return CHSPEC_CHANNEL(chspec); -+ } else { -+ sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT; -+ -+ if (CHSPEC_IS8080(chspec)) { -+ bw_mhz = 80; -+ -+ if (sb < 4) { -+ center_chan = CHSPEC_CHAN1(chspec); -+ } -+ else { -+ center_chan = CHSPEC_CHAN2(chspec); -+ sb -= 4; -+ } -+ -+ /* convert from channel index to channel number */ -+ center_chan = wf_5g_80m_chans[center_chan]; -+ } -+ else { -+ bw_mhz = bw_chspec_to_mhz(chspec); -+ center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT; -+ } -+ -+ return (channel_to_ctl_chan(center_chan, bw_mhz, sb)); -+ } -+} -+ -+/* -+ * This function returns the chanspec of the control channel of a given chanspec -+ */ -+chanspec_t -+wf_chspec_ctlchspec(chanspec_t chspec) -+{ -+ chanspec_t ctl_chspec = chspec; -+ uint8 ctl_chan; -+ -+ ASSERT(!wf_chspec_malformed(chspec)); -+ -+ /* Is there a sideband ? */ -+ if (!CHSPEC_IS20(chspec)) { -+ ctl_chan = wf_chspec_ctlchan(chspec); -+ ctl_chspec = ctl_chan | WL_CHANSPEC_BW_20; -+ ctl_chspec |= CHSPEC_BAND(chspec); -+ } -+ return ctl_chspec; -+} -+ -+/* return chanspec given control channel and bandwidth -+ * return 0 on error -+ */ -+uint16 -+wf_channel2chspec(uint ctl_ch, uint bw) -+{ -+ uint16 chspec; -+ const uint8 *center_ch = NULL; -+ int num_ch = 0; -+ int sb = -1; -+ int i = 0; -+ -+ chspec = ((ctl_ch <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); -+ -+ chspec |= bw; -+ -+ if (bw == WL_CHANSPEC_BW_40) { -+ center_ch = wf_5g_40m_chans; -+ num_ch = WF_NUM_5G_40M_CHANS; -+ bw = 40; -+ } else if (bw == WL_CHANSPEC_BW_80) { -+ center_ch = wf_5g_80m_chans; -+ num_ch = WF_NUM_5G_80M_CHANS; -+ bw = 80; -+ } else if (bw == WL_CHANSPEC_BW_160) { -+ center_ch = wf_5g_160m_chans; -+ num_ch = WF_NUM_5G_160M_CHANS; -+ bw = 160; -+ } else if (bw == WL_CHANSPEC_BW_20) { -+ chspec |= ctl_ch; -+ return chspec; -+ } else { -+ return 0; -+ } -+ -+ for (i = 0; i < num_ch; i ++) { -+ sb = channel_to_sb(center_ch[i], ctl_ch, bw); -+ if (sb >= 0) { -+ chspec |= center_ch[i]; -+ chspec |= (sb << WL_CHANSPEC_CTL_SB_SHIFT); -+ break; -+ } -+ } -+ -+ /* check for no matching sb/center */ -+ if (sb < 0) { -+ return 0; -+ } -+ -+ return chspec; -+} -+#endif /* D11AC_IOTYPES */ -+ -+/* -+ * This function returns the chanspec for the primary 40MHz of an 80MHz channel. -+ * The control sideband specifies the same 20MHz channel that the 80MHz channel is using -+ * as the primary 20MHz channel. -+ */ -+extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec) -+{ -+ chanspec_t chspec40 = chspec; -+ uint center_chan; -+ uint sb; -+ -+ ASSERT(!wf_chspec_malformed(chspec)); -+ -+ if (CHSPEC_IS80(chspec)) { -+ center_chan = CHSPEC_CHANNEL(chspec); -+ sb = CHSPEC_CTL_SB(chspec); -+ -+ if (sb == WL_CHANSPEC_CTL_SB_UL) { -+ /* Primary 40MHz is on upper side */ -+ sb = WL_CHANSPEC_CTL_SB_L; -+ center_chan += CH_20MHZ_APART; -+ } else if (sb == WL_CHANSPEC_CTL_SB_UU) { -+ /* Primary 40MHz is on upper side */ -+ sb = WL_CHANSPEC_CTL_SB_U; -+ center_chan += CH_20MHZ_APART; -+ } else { -+ /* Primary 40MHz is on lower side */ -+ /* sideband bits are the same for LL/LU and L/U */ -+ center_chan -= CH_20MHZ_APART; -+ } -+ -+ /* Create primary 40MHz chanspec */ -+ chspec40 = (WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 | -+ sb | center_chan); -+ } -+ -+ return chspec40; -+} -+ -+/* -+ * Return the channel number for a given frequency and base frequency. -+ * The returned channel number is relative to the given base frequency. -+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for -+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz. -+ * -+ * Frequency is specified in MHz. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for -+ * 2.4 GHz and 5 GHz bands. -+ * -+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band -+ * and [0, 200] otherwise. -+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the -+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even -+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ */ -+int -+wf_mhz2channel(uint freq, uint start_factor) -+{ -+ int ch = -1; -+ uint base; -+ int offset; -+ -+ /* take the default channel start frequency */ -+ if (start_factor == 0) { -+ if (freq >= 2400 && freq <= 2500) -+ start_factor = WF_CHAN_FACTOR_2_4_G; -+ else if (freq >= 5000 && freq <= 6000) -+ start_factor = WF_CHAN_FACTOR_5_G; -+ } -+ -+ if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) -+ return 14; -+ -+ base = start_factor / 2; -+ -+ /* check that the frequency is in 1GHz range of the base */ -+ if ((freq < base) || (freq > base + 1000)) -+ return -1; -+ -+ offset = freq - base; -+ ch = offset / 5; -+ -+ /* check that frequency is a 5MHz multiple from the base */ -+ if (offset != (ch * 5)) -+ return -1; -+ -+ /* restricted channel range check for 2.4G */ -+ if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13)) -+ return -1; -+ -+ return ch; -+} -+ -+/* -+ * Return the center frequency in MHz of the given channel and base frequency. -+ * The channel number is interpreted relative to the given base frequency. -+ * -+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_4_G, and WF_CHAN_FACTOR_5_G -+ * are defined for 2.4 GHz, 4 GHz, and 5 GHz bands. -+ * The channel range of [1, 14] is only checked for a start_factor of -+ * WF_CHAN_FACTOR_2_4_G (4814 = 2407 * 2). -+ * Odd start_factors produce channels on .5 MHz boundaries, in which case -+ * the answer is rounded down to an integral MHz. -+ * -1 is returned for an out of range channel. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ */ -+int -+wf_channel2mhz(uint ch, uint start_factor) -+{ -+ int freq; -+ -+ if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || -+ (ch > 200)) -+ freq = -1; -+ else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) -+ freq = 2484; -+ else -+ freq = ch * 5 + start_factor / 2; -+ -+ return freq; -+} -diff --git a/drivers/net/wireless/ap6210/dhd.h b/drivers/net/wireless/ap6210/dhd.h -new file mode 100644 -index 0000000..006a41c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd.h -@@ -0,0 +1,888 @@ -+/* -+ * Header file describing the internal (inter-module) DHD interfaces. -+ * -+ * Provides type definitions and function prototypes used to link the -+ * DHD OS, bus, and protocol modules. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd.h 373887 2012-12-10 21:58:02Z $ -+ */ -+ -+/**************** -+ * Common types * -+ */ -+ -+#ifndef _dhd_h_ -+#define _dhd_h_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK) -+#include -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */ -+/* The kernel threading is sdio-specific */ -+struct task_struct; -+struct sched_param; -+int setScheduler(struct task_struct *p, int policy, struct sched_param *param); -+ -+#define ALL_INTERFACES 0xff -+ -+#include -+#include -+ -+ -+/* Forward decls */ -+struct dhd_bus; -+struct dhd_prot; -+struct dhd_info; -+ -+/* The level of bus communication with the dongle */ -+enum dhd_bus_state { -+ DHD_BUS_DOWN, /* Not ready for frame transfers */ -+ DHD_BUS_LOAD, /* Download access only (CPU reset) */ -+ DHD_BUS_DATA /* Ready for frame transfers */ -+}; -+ -+enum dhd_op_flags { -+/* Firmware requested operation mode */ -+ DHD_FLAG_STA_MODE = BIT(0), /* STA only */ -+ DHD_FLAG_HOSTAP_MODE = BIT(1), /* SOFTAP only */ -+ DHD_FLAG_P2P_MODE = BIT(2), /* P2P Only */ -+ /* STA + P2P */ -+ DHD_FLAG_CONCURR_SINGLE_CHAN_MODE = (DHD_FLAG_STA_MODE | DHD_FLAG_P2P_MODE), -+ DHD_FLAG_CONCURR_MULTI_CHAN_MODE = BIT(4), /* STA + P2P */ -+ /* Current P2P mode for P2P connection */ -+ DHD_FLAG_P2P_GC_MODE = BIT(5), -+ DHD_FLAG_P2P_GO_MODE = BIT(6), -+ DHD_FLAG_MBSS_MODE = BIT(7) /* MBSS in future */ -+}; -+ -+#define MANUFACTRING_FW "WLTEST" -+ -+/* max sequential rxcntl timeouts to set HANG event */ -+#ifndef MAX_CNTL_TIMEOUT -+#define MAX_CNTL_TIMEOUT 2 -+#endif -+ -+#define DHD_SCAN_ASSOC_ACTIVE_TIME 40 /* ms: Embedded default Active setting from DHD */ -+#define DHD_SCAN_UNASSOC_ACTIVE_TIME 80 /* ms: Embedded def. Unassoc Active setting from DHD */ -+#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD */ -+ -+#ifndef POWERUP_MAX_RETRY -+#define POWERUP_MAX_RETRY 3 /* how many times we retry to power up the chip */ -+#endif -+#ifndef POWERUP_WAIT_MS -+#define POWERUP_WAIT_MS 2000 /* ms: time out in waiting wifi to come up */ -+#endif -+ -+enum dhd_bus_wake_state { -+ WAKE_LOCK_OFF, -+ WAKE_LOCK_PRIV, -+ WAKE_LOCK_DPC, -+ WAKE_LOCK_IOCTL, -+ WAKE_LOCK_DOWNLOAD, -+ WAKE_LOCK_TMOUT, -+ WAKE_LOCK_WATCHDOG, -+ WAKE_LOCK_LINK_DOWN_TMOUT, -+ WAKE_LOCK_PNO_FIND_TMOUT, -+ WAKE_LOCK_SOFTAP_SET, -+ WAKE_LOCK_SOFTAP_STOP, -+ WAKE_LOCK_SOFTAP_START, -+ WAKE_LOCK_SOFTAP_THREAD, -+ WAKE_LOCK_MAX -+}; -+ -+enum dhd_prealloc_index { -+ DHD_PREALLOC_PROT = 0, -+ DHD_PREALLOC_RXBUF, -+ DHD_PREALLOC_DATABUF, -+#if defined(STATIC_WL_PRIV_STRUCT) -+ DHD_PREALLOC_OSL_BUF, -+ DHD_PREALLOC_WIPHY_ESCAN0 = 5, -+#else -+ DHD_PREALLOC_OSL_BUF -+#endif /* STATIC_WL_PRIV_STRUCT */ -+}; -+ -+typedef enum { -+ DHD_IF_NONE = 0, -+ DHD_IF_ADD, -+ DHD_IF_DEL, -+ DHD_IF_CHANGE, -+ DHD_IF_DELETING -+} dhd_if_state_t; -+ -+ -+#if defined(CONFIG_DHD_USE_STATIC_BUF) -+ -+uint8* dhd_os_prealloc(void *osh, int section, uint size); -+void dhd_os_prefree(void *osh, void *addr, uint size); -+#define DHD_OS_PREALLOC(osh, section, size) dhd_os_prealloc(osh, section, size) -+#define DHD_OS_PREFREE(osh, addr, size) dhd_os_prefree(osh, addr, size) -+ -+#else -+ -+#define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size) -+#define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size) -+ -+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ -+ -+/* Packet alignment for most efficient SDIO (can change based on platform) */ -+#ifndef DHD_SDALIGN -+#define DHD_SDALIGN 32 -+#endif -+ -+/* host reordering packts logic */ -+/* followed the structure to hold the reorder buffers (void **p) */ -+typedef struct reorder_info { -+ void **p; -+ uint8 flow_id; -+ uint8 cur_idx; -+ uint8 exp_idx; -+ uint8 max_idx; -+ uint8 pend_pkts; -+} reorder_info_t; -+ -+/* Common structure for module and instance linkage */ -+typedef struct dhd_pub { -+ /* Linkage ponters */ -+ osl_t *osh; /* OSL handle */ -+ struct dhd_bus *bus; /* Bus module handle */ -+ struct dhd_prot *prot; /* Protocol module handle */ -+ struct dhd_info *info; /* Info module handle */ -+ -+ /* Internal dhd items */ -+ bool up; /* Driver up/down (to OS) */ -+ bool txoff; /* Transmit flow-controlled */ -+ bool dongle_reset; /* TRUE = DEVRESET put dongle into reset */ -+ enum dhd_bus_state busstate; -+ uint hdrlen; /* Total DHD header length (proto + bus) */ -+ uint maxctl; /* Max size rxctl request from proto to bus */ -+ uint rxsz; /* Rx buffer size bus module should use */ -+ uint8 wme_dp; /* wme discard priority */ -+ -+ /* Dongle media info */ -+ bool iswl; /* Dongle-resident driver is wl */ -+ ulong drv_version; /* Version of dongle-resident driver */ -+ struct ether_addr mac; /* MAC address obtained from dongle */ -+ dngl_stats_t dstats; /* Stats for dongle-based data */ -+ -+ /* Additional stats for the bus level */ -+ ulong tx_packets; /* Data packets sent to dongle */ -+ ulong tx_multicast; /* Multicast data packets sent to dongle */ -+ ulong tx_errors; /* Errors in sending data to dongle */ -+ ulong tx_ctlpkts; /* Control packets sent to dongle */ -+ ulong tx_ctlerrs; /* Errors sending control frames to dongle */ -+ ulong rx_packets; /* Packets sent up the network interface */ -+ ulong rx_multicast; /* Multicast packets sent up the network interface */ -+ ulong rx_errors; /* Errors processing rx data packets */ -+ ulong rx_ctlpkts; /* Control frames processed from dongle */ -+ ulong rx_ctlerrs; /* Errors in processing rx control frames */ -+ ulong rx_dropped; /* Packets dropped locally (no memory) */ -+ ulong rx_flushed; /* Packets flushed due to unscheduled sendup thread */ -+ ulong wd_dpc_sched; /* Number of times dhd dpc scheduled by watchdog timer */ -+ -+ ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */ -+ ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */ -+ ulong fc_packets; /* Number of flow control pkts recvd */ -+ -+ /* Last error return */ -+ int bcmerror; -+ uint tickcnt; -+ -+ /* Last error from dongle */ -+ int dongle_error; -+ -+ uint8 country_code[WLC_CNTRY_BUF_SZ]; -+ -+ /* Suspend disable flag and "in suspend" flag */ -+ int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ -+ int in_suspend; /* flag set to 1 when early suspend called */ -+#ifdef PNO_SUPPORT -+ int pno_enable; /* pno status : "1" is pno enable */ -+ int pno_suspend; /* pno suspend status : "1" is pno suspended */ -+#endif /* PNO_SUPPORT */ -+ /* DTIM skip value, default 0(or 1) means wake each DTIM -+ * 3 means skip 2 DTIMs and wake up 3rd DTIM(9th beacon when AP DTIM is 3) -+ */ -+ int suspend_bcn_li_dtim; /* bcn_li_dtim value in suspend mode */ -+#ifdef PKT_FILTER_SUPPORT -+ int early_suspended; /* Early suspend status */ -+ int dhcp_in_progress; /* DHCP period */ -+#endif -+ -+ /* Pkt filter defination */ -+ char * pktfilter[100]; -+ int pktfilter_count; -+ -+ wl_country_t dhd_cspec; /* Current Locale info */ -+ char eventmask[WL_EVENTING_MASK_LEN]; -+ int op_mode; /* STA, HostAPD, WFD, SoftAP */ -+ -+/* Set this to 1 to use a seperate interface (p2p0) for p2p operations. -+ * For ICS MR1 releases it should be disable to be compatable with ICS MR1 Framework -+ * see target dhd-cdc-sdmmc-panda-cfg80211-icsmr1-gpl-debug in Makefile -+ */ -+/* #define WL_ENABLE_P2P_IF 1 */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */ -+ struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */ -+#endif -+ -+#ifdef WLBTAMP -+ uint16 maxdatablks; -+#endif /* WLBTAMP */ -+#ifdef PROP_TXSTATUS -+ int wlfc_enabled; -+ void* wlfc_state; -+#endif -+ bool dongle_isolation; -+ bool dongle_trap_occured; /* flag for sending HANG event to upper layer */ -+ int hang_was_sent; -+ int rxcnt_timeout; /* counter rxcnt timeout to send HANG */ -+ int txcnt_timeout; /* counter txcnt timeout to send HANG */ -+#ifdef WLMEDIA_HTSF -+ uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */ -+#endif -+ struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS]; -+#if defined(ARP_OFFLOAD_SUPPORT) -+ uint32 arp_version; -+#endif -+} dhd_pub_t; -+ -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+ -+ #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -+ #define _DHD_PM_RESUME_WAIT(a, b) do {\ -+ int retry = 0; \ -+ SMP_RD_BARRIER_DEPENDS(); \ -+ while (dhd_mmc_suspend && retry++ != b) { \ -+ SMP_RD_BARRIER_DEPENDS(); \ -+ wait_event_interruptible_timeout(a, !dhd_mmc_suspend, 1); \ -+ } \ -+ } while (0) -+ #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) -+ #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) -+ #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) -+ #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0) -+ -+ #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -+ #define SPINWAIT_SLEEP(a, exp, us) do { \ -+ uint countdown = (us) + 9999; \ -+ while ((exp) && (countdown >= 10000)) { \ -+ wait_event_interruptible_timeout(a, FALSE, 1); \ -+ countdown -= 10000; \ -+ } \ -+ } while (0) -+ -+ #else -+ -+ #define DHD_PM_RESUME_WAIT_INIT(a) -+ #define DHD_PM_RESUME_WAIT(a) -+ #define DHD_PM_RESUME_WAIT_FOREVER(a) -+ #define DHD_PM_RESUME_RETURN_ERROR(a) -+ #define DHD_PM_RESUME_RETURN -+ -+ #define DHD_SPINWAIT_SLEEP_INIT(a) -+ #define SPINWAIT_SLEEP(a, exp, us) do { \ -+ uint countdown = (us) + 9; \ -+ while ((exp) && (countdown >= 10)) { \ -+ OSL_DELAY(10); \ -+ countdown -= 10; \ -+ } \ -+ } while (0) -+ -+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -+#ifndef DHDTHREAD -+#undef SPINWAIT_SLEEP -+#define SPINWAIT_SLEEP(a, exp, us) SPINWAIT(exp, us) -+#endif /* DHDTHREAD */ -+#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ -+ -+unsigned long dhd_os_spin_lock(dhd_pub_t *pub); -+void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags); -+ -+/* Wakelock Functions */ -+extern int dhd_os_wake_lock(dhd_pub_t *pub); -+extern int dhd_os_wake_unlock(dhd_pub_t *pub); -+extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); -+extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val); -+extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val); -+extern int dhd_os_wd_wake_lock(dhd_pub_t *pub); -+extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub); -+ -+inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ mutex_init(&dhdp->wl_softap_lock); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+} -+ -+inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ mutex_lock(&dhdp->wl_softap_lock); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+} -+ -+inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ mutex_unlock(&dhdp->wl_softap_lock); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+} -+ -+#define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub) -+#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub) -+#define DHD_OS_WD_WAKE_LOCK(pub) dhd_os_wd_wake_lock(pub) -+#define DHD_OS_WD_WAKE_UNLOCK(pub) dhd_os_wd_wake_unlock(pub) -+#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub) -+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) \ -+ dhd_os_wake_lock_rx_timeout_enable(pub, val) -+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) \ -+ dhd_os_wake_lock_ctrl_timeout_enable(pub, val) -+#define DHD_PACKET_TIMEOUT_MS 1000 -+#define DHD_EVENT_TIMEOUT_MS 1500 -+ -+/* interface operations (register, remove) should be atomic, use this lock to prevent race -+ * condition among wifi on/off and interface operation functions -+ */ -+void dhd_net_if_lock(struct net_device *dev); -+void dhd_net_if_unlock(struct net_device *dev); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+extern struct mutex _dhd_sdio_mutex_lock_; -+#endif -+ -+typedef struct dhd_if_event { -+ uint8 ifidx; -+ uint8 action; -+ uint8 flags; -+ uint8 bssidx; -+ uint8 is_AP; -+} dhd_if_event_t; -+ -+typedef enum dhd_attach_states -+{ -+ DHD_ATTACH_STATE_INIT = 0x0, -+ DHD_ATTACH_STATE_NET_ALLOC = 0x1, -+ DHD_ATTACH_STATE_DHD_ALLOC = 0x2, -+ DHD_ATTACH_STATE_ADD_IF = 0x4, -+ DHD_ATTACH_STATE_PROT_ATTACH = 0x8, -+ DHD_ATTACH_STATE_WL_ATTACH = 0x10, -+ DHD_ATTACH_STATE_THREADS_CREATED = 0x20, -+ DHD_ATTACH_STATE_WAKELOCKS_INIT = 0x40, -+ DHD_ATTACH_STATE_CFG80211 = 0x80, -+ DHD_ATTACH_STATE_EARLYSUSPEND_DONE = 0x100, -+ DHD_ATTACH_STATE_DONE = 0x200 -+} dhd_attach_states_t; -+ -+/* Value -1 means we are unsuccessful in creating the kthread. */ -+#define DHD_PID_KT_INVALID -1 -+/* Value -2 means we are unsuccessful in both creating the kthread and tasklet */ -+#define DHD_PID_KT_TL_INVALID -2 -+ -+/* -+ * Exported from dhd OS modules (dhd_linux/dhd_ndis) -+ */ -+ -+/* To allow osl_attach/detach calls from os-independent modules */ -+osl_t *dhd_osl_attach(void *pdev, uint bustype); -+void dhd_osl_detach(osl_t *osh); -+ -+/* Indication from bus module regarding presence/insertion of dongle. -+ * Return dhd_pub_t pointer, used as handle to OS module in later calls. -+ * Returned structure should have bus and prot pointers filled in. -+ * bus_hdrlen specifies required headroom for bus module header. -+ */ -+extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen); -+#if defined(WLP2P) && defined(WL_CFG80211) -+/* To allow attach/detach calls corresponding to p2p0 interface */ -+extern int dhd_attach_p2p(dhd_pub_t *); -+extern int dhd_detach_p2p(dhd_pub_t *); -+#endif /* WLP2P && WL_CFG80211 */ -+extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); -+ -+/* Indication from bus module regarding removal/absence of dongle */ -+extern void dhd_detach(dhd_pub_t *dhdp); -+extern void dhd_free(dhd_pub_t *dhdp); -+ -+/* Indication from bus module to change flow-control state */ -+extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); -+ -+extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); -+ -+/* Receive frame for delivery to OS. Callee disposes of rxp. */ -+extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan); -+ -+/* Return pointer to interface name */ -+extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); -+ -+/* Request scheduling of the bus dpc */ -+extern void dhd_sched_dpc(dhd_pub_t *dhdp); -+ -+/* Notify tx completion */ -+extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); -+ -+/* OS independent layer functions */ -+extern int dhd_os_proto_block(dhd_pub_t * pub); -+extern int dhd_os_proto_unblock(dhd_pub_t * pub); -+extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending); -+extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub); -+extern unsigned int dhd_os_get_ioctl_resp_timeout(void); -+extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -+extern void * dhd_os_open_image(char * filename); -+extern int dhd_os_get_image_block(char * buf, int len, void * image); -+extern void dhd_os_close_image(void * image); -+extern void dhd_os_wd_timer(void *bus, uint wdtick); -+extern void dhd_os_sdlock(dhd_pub_t * pub); -+extern void dhd_os_sdunlock(dhd_pub_t * pub); -+extern void dhd_os_sdlock_txq(dhd_pub_t * pub); -+extern void dhd_os_sdunlock_txq(dhd_pub_t * pub); -+extern void dhd_os_sdlock_rxq(dhd_pub_t * pub); -+extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub); -+extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub); -+extern void dhd_customer_gpio_wlan_ctrl(int onoff); -+extern int dhd_custom_get_mac_address(unsigned char *buf); -+extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); -+extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); -+extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); -+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret); -+extern int dhd_os_send_hang_message(dhd_pub_t *dhdp); -+extern void dhd_set_version_info(dhd_pub_t *pub, char *fw); -+ -+#ifdef PNO_SUPPORT -+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -+extern int dhd_pno_clean(dhd_pub_t *dhd); -+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, -+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -+extern int dhd_pno_get_status(dhd_pub_t *dhd); -+extern int dhd_dev_pno_reset(struct net_device *dev); -+extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, -+ int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -+extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -+extern int dhd_dev_get_pno_status(struct net_device *dev); -+#endif /* PNO_SUPPORT */ -+ -+#ifdef PKT_FILTER_SUPPORT -+#define DHD_UNICAST_FILTER_NUM 0 -+#define DHD_BROADCAST_FILTER_NUM 1 -+#define DHD_MULTICAST4_FILTER_NUM 2 -+#define DHD_MULTICAST6_FILTER_NUM 3 -+#define DHD_MDNS_FILTER_NUM 4 -+extern int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val); -+extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd); -+extern int net_os_enable_packet_filter(struct net_device *dev, int val); -+extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); -+#endif /* PKT_FILTER_SUPPORT */ -+ -+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd); -+extern bool dhd_support_sta_mode(dhd_pub_t *dhd); -+ -+#ifdef DHD_DEBUG -+extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); -+#endif /* DHD_DEBUG */ -+#if defined(OOB_INTR_ONLY) -+extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr); -+#endif -+extern void dhd_os_sdtxlock(dhd_pub_t * pub); -+extern void dhd_os_sdtxunlock(dhd_pub_t * pub); -+ -+typedef struct { -+ uint32 limit; /* Expiration time (usec) */ -+ uint32 increment; /* Current expiration increment (usec) */ -+ uint32 elapsed; /* Current elapsed time (usec) */ -+ uint32 tick; /* O/S tick time (usec) */ -+} dhd_timeout_t; -+ -+extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec); -+extern int dhd_timeout_expired(dhd_timeout_t *tmo); -+ -+extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); -+extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net); -+extern struct net_device * dhd_idx2net(void *pub, int ifidx); -+extern int net_os_send_hang_message(struct net_device *dev); -+extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, -+ wl_event_msg_t *, void **data_ptr); -+extern void wl_event_to_host_order(wl_event_msg_t * evt); -+ -+extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len); -+extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, -+ int ifindex); -+ -+extern void dhd_common_init(osl_t *osh); -+ -+extern int dhd_do_driver_init(struct net_device *net); -+extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, -+ char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx); -+extern void dhd_del_if(struct dhd_info *dhd, int ifidx); -+ -+extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name); -+extern void dhd_vif_del(struct dhd_info *dhd, int ifidx); -+ -+extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx); -+extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len); -+ -+ -+/* Send packet to dongle via data channel */ -+extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt); -+ -+/* send up locally generated event */ -+extern void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -+/* Send event to host */ -+extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data); -+extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag); -+extern uint dhd_bus_status(dhd_pub_t *dhdp); -+extern int dhd_bus_start(dhd_pub_t *dhdp); -+extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size); -+extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line); -+extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval); -+extern uint dhd_bus_chip_id(dhd_pub_t *dhdp); -+extern uint dhd_bus_chiprev_id(dhd_pub_t *dhdp); -+extern uint dhd_bus_chippkg_id(dhd_pub_t *dhdp); -+ -+#if defined(KEEP_ALIVE) -+extern int dhd_keep_alive_onoff(dhd_pub_t *dhd); -+#endif /* KEEP_ALIVE */ -+ -+extern bool dhd_is_concurrent_mode(dhd_pub_t *dhd); -+ -+typedef enum cust_gpio_modes { -+ WLAN_RESET_ON, -+ WLAN_RESET_OFF, -+ WLAN_POWER_ON, -+ WLAN_POWER_OFF -+} cust_gpio_modes_t; -+ -+extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -+extern int wl_iw_send_priv_event(struct net_device *dev, char *flag); -+/* -+ * Insmod parameters for debug/test -+ */ -+ -+/* Watchdog timer interval */ -+extern uint dhd_watchdog_ms; -+ -+#if defined(DHD_DEBUG) -+/* Console output poll interval */ -+extern uint dhd_console_ms; -+#endif /* defined(DHD_DEBUG) */ -+//extern uint android_msg_level; -+#ifdef CONFIG_WIRELESS_EXT -+extern uint iw_msg_level; -+#endif -+#ifdef WL_CFG80211 -+extern uint wl_dbg_level; -+#endif -+extern uint dhd_slpauto; -+ -+/* Use interrupts */ -+extern uint dhd_intr; -+ -+/* Use polling */ -+extern uint dhd_poll; -+ -+/* ARP offload agent mode */ -+extern uint dhd_arp_mode; -+ -+/* ARP offload enable */ -+extern uint dhd_arp_enable; -+ -+/* Pkt filte enable control */ -+extern uint dhd_pkt_filter_enable; -+ -+/* Pkt filter init setup */ -+extern uint dhd_pkt_filter_init; -+ -+/* Pkt filter mode control */ -+extern uint dhd_master_mode; -+ -+/* Roaming mode control */ -+extern uint dhd_roam_disable; -+ -+/* Roaming mode control */ -+extern uint dhd_radio_up; -+ -+/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -+extern int dhd_idletime; -+#ifdef DHD_USE_IDLECOUNT -+#define DHD_IDLETIME_TICKS 5 -+#else -+#define DHD_IDLETIME_TICKS 1 -+#endif /* DHD_USE_IDLECOUNT */ -+ -+/* SDIO Drive Strength */ -+extern uint dhd_sdiod_drive_strength; -+ -+/* Override to force tx queueing all the time */ -+extern uint dhd_force_tx_queueing; -+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */ -+#define DEFAULT_KEEP_ALIVE_VALUE 55000 /* msec */ -+#ifndef CUSTOM_KEEP_ALIVE_SETTING -+#define CUSTOM_KEEP_ALIVE_SETTING DEFAULT_KEEP_ALIVE_VALUE -+#endif /* DEFAULT_KEEP_ALIVE_VALUE */ -+ -+#define NULL_PKT_STR "null_pkt" -+ -+/* hooks for custom glom setting option via Makefile */ -+#define DEFAULT_GLOM_VALUE -1 -+#ifndef CUSTOM_GLOM_SETTING -+#define CUSTOM_GLOM_SETTING DEFAULT_GLOM_VALUE -+#endif -+ -+/* hooks for custom Roaming Trigger setting via Makefile */ -+#define DEFAULT_ROAM_TRIGGER_VALUE -75 /* dBm default roam trigger all band */ -+#define DEFAULT_ROAM_TRIGGER_SETTING -1 -+#ifndef CUSTOM_ROAM_TRIGGER_SETTING -+#define CUSTOM_ROAM_TRIGGER_SETTING DEFAULT_ROAM_TRIGGER_VALUE -+#endif -+ -+/* hooks for custom Roaming Romaing setting via Makefile */ -+#define DEFAULT_ROAM_DELTA_VALUE 10 /* dBm default roam delta all band */ -+#define DEFAULT_ROAM_DELTA_SETTING -1 -+#ifndef CUSTOM_ROAM_DELTA_SETTING -+#define CUSTOM_ROAM_DELTA_SETTING DEFAULT_ROAM_DELTA_VALUE -+#endif -+ -+/* hooks for custom PNO Event wake lock to guarantee enough time -+ for the Platform to detect Event before system suspended -+*/ -+#define DEFAULT_PNO_EVENT_LOCK_xTIME 2 /* multiplay of DHD_PACKET_TIMEOUT_MS */ -+#ifndef CUSTOM_PNO_EVENT_LOCK_xTIME -+#define CUSTOM_PNO_EVENT_LOCK_xTIME DEFAULT_PNO_EVENT_LOCK_xTIME -+#endif -+ -+/* hooks for custom dhd_dpc_prio setting option via Makefile */ -+#define DEFAULT_DHP_DPC_PRIO 1 -+#ifndef CUSTOM_DPC_PRIO_SETTING -+#define CUSTOM_DPC_PRIO_SETTING DEFAULT_DHP_DPC_PRIO -+#endif -+ -+#define DEFAULT_SUSPEND_BCN_LI_DTIM 3 -+#ifndef CUSTOM_SUSPEND_BCN_LI_DTIM -+#define CUSTOM_SUSPEND_BCN_LI_DTIM DEFAULT_SUSPEND_BCN_LI_DTIM -+#endif -+ -+#ifdef SDTEST -+/* Echo packet generator (SDIO), pkts/s */ -+extern uint dhd_pktgen; -+ -+/* Echo packet len (0 => sawtooth, max 1800) */ -+extern uint dhd_pktgen_len; -+#define MAX_PKTGEN_LEN 1800 -+#endif -+ -+ -+/* optionally set by a module_param_string() */ -+#define MOD_PARAM_PATHLEN 2048 -+extern char fw_path[MOD_PARAM_PATHLEN]; -+extern char nv_path[MOD_PARAM_PATHLEN]; -+ -+#define MOD_PARAM_INFOLEN 512 -+ -+#ifdef SOFTAP -+extern char fw_path2[MOD_PARAM_PATHLEN]; -+#endif -+ -+#define FW_PATH_AUTO_SELECT 1 -+extern char firmware_path[MOD_PARAM_PATHLEN]; -+extern void dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src); -+#define COPY_FW_PATH_BY_CHIP(bus, dst, src) dhd_bus_select_firmware_name_by_chip(bus, dst, src); -+ -+/* Flag to indicate if we should download firmware on driver load */ -+extern uint dhd_download_fw_on_driverload; -+ -+ -+/* For supporting multiple interfaces */ -+#define DHD_MAX_IFS 16 -+#define DHD_DEL_IF -0xe -+#define DHD_BAD_IF -0xf -+#define WL_AUTO_ROAM_TRIGGER -75 -+ -+#ifdef PROP_TXSTATUS -+/* Please be mindful that total pkttag space is 32 octets only */ -+typedef struct dhd_pkttag { -+ /* -+ b[11 ] - 1 = this packet was sent in response to one time packet request, -+ do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET]. -+ b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on] -+ b[9 ] - 1 = packet is host->firmware (transmit direction) -+ - 0 = packet received from firmware (firmware->host) -+ b[8 ] - 1 = packet was sent due to credit_request (pspoll), -+ packet does not count against FIFO credit. -+ - 0 = normal transaction, packet counts against FIFO credit -+ b[7 ] - 1 = AP, 0 = STA -+ b[6:4] - AC FIFO number -+ b[3:0] - interface index -+ */ -+ uint16 if_flags; -+ /* destination MAC address for this packet so that not every -+ module needs to open the packet to find this -+ */ -+ uint8 dstn_ether[ETHER_ADDR_LEN]; -+ /* -+ This 32-bit goes from host to device for every packet. -+ */ -+ uint32 htod_tag; -+ /* bus specific stuff */ -+ union { -+ struct { -+ void* stuff; -+ uint32 thing1; -+ uint32 thing2; -+ } sd; -+ struct { -+ void* bus; -+ void* urb; -+ } usb; -+ } bus_specific; -+} dhd_pkttag_t; -+ -+#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue) -+#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag) -+ -+#define DHD_PKTTAG_IFMASK 0xf -+#define DHD_PKTTAG_IFTYPE_MASK 0x1 -+#define DHD_PKTTAG_IFTYPE_SHIFT 7 -+#define DHD_PKTTAG_FIFO_MASK 0x7 -+#define DHD_PKTTAG_FIFO_SHIFT 4 -+ -+#define DHD_PKTTAG_SIGNALONLY_MASK 0x1 -+#define DHD_PKTTAG_SIGNALONLY_SHIFT 10 -+ -+#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1 -+#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11 -+ -+#define DHD_PKTTAG_PKTDIR_MASK 0x1 -+#define DHD_PKTTAG_PKTDIR_SHIFT 9 -+ -+#define DHD_PKTTAG_CREDITCHECK_MASK 0x1 -+#define DHD_PKTTAG_CREDITCHECK_SHIFT 8 -+ -+#define DHD_PKTTAG_INVALID_FIFOID 0x7 -+ -+#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \ -+ (((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT) -+#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK) -+ -+#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & ~DHD_PKTTAG_IFMASK) | ((if) & DHD_PKTTAG_IFMASK) -+#define DHD_PKTTAG_IF(tag) (((dhd_pkttag_t*)(tag))->if_flags & DHD_PKTTAG_IFMASK) -+ -+#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & \ -+ ~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \ -+ (((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT) -+#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK) -+ -+#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & \ -+ ~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \ -+ (((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT) -+#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK) -+ -+#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & \ -+ ~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \ -+ (((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT) -+#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK) -+ -+#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & \ -+ ~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \ -+ (((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT) -+#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK) -+ -+#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \ -+ (((dhd_pkttag_t*)(tag))->if_flags & \ -+ ~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \ -+ (1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) -+#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ -+ DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK) -+ -+#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \ -+ (dstn_MAC_ea), ETHER_ADDR_LEN) -+#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether -+ -+typedef int (*f_commitpkt_t)(void* ctx, void* p, bool wlfc_locked); -+ -+#ifdef PROP_TXSTATUS_DEBUG -+#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0) -+#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0) -+#else -+#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0) -+#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0) -+#endif -+ -+#endif /* PROP_TXSTATUS */ -+ -+extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar); -+extern void dhd_wait_event_wakeup(dhd_pub_t*dhd); -+ -+#define IFLOCK_INIT(lock) *lock = 0 -+#define IFLOCK(lock) while (InterlockedCompareExchange((lock), 1, 0)) \ -+ NdisStallExecution(1); -+#define IFUNLOCK(lock) InterlockedExchange((lock), 0) -+#define IFLOCK_FREE(lock) -+ -+#ifdef PNO_SUPPORT -+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -+extern int dhd_pnoenable(dhd_pub_t *dhd, int pfn_enabled); -+extern int dhd_pno_clean(dhd_pub_t *dhd); -+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, -+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -+extern int dhd_pno_get_status(dhd_pub_t *dhd); -+extern int dhd_pno_set_add(dhd_pub_t *dhd, wl_pfn_t *netinfo, int nssid, ushort scan_fr, -+ ushort slowscan_fr, uint8 pno_repeat, uint8 pno_freq_expo_max, int16 flags); -+extern int dhd_pno_cfg(dhd_pub_t *dhd, wl_pfn_cfg_t *pcfg); -+extern int dhd_pno_suspend(dhd_pub_t *dhd, int pfn_suspend); -+#endif /* PNO_SUPPORT */ -+#ifdef ARP_OFFLOAD_SUPPORT -+#define MAX_IPV4_ENTRIES 8 -+void dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode); -+void dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable); -+ -+/* dhd_commn arp offload wrapers */ -+void dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx); -+void dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx); -+int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx); -+void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx); -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+#endif /* _dhd_h_ */ -diff --git a/drivers/net/wireless/ap6210/dhd_bta.c b/drivers/net/wireless/ap6210/dhd_bta.c -new file mode 100644 -index 0000000..3752bbd ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_bta.c -@@ -0,0 +1,338 @@ -+/* -+ * BT-AMP support routines -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_bta.c 303834 2011-12-20 06:17:39Z $ -+ */ -+#ifndef WLBTAMP -+#error "WLBTAMP is not defined" -+#endif /* WLBTAMP */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+ -+#ifdef SEND_HCI_CMD_VIA_IOCTL -+#define BTA_HCI_CMD_MAX_LEN HCI_CMD_PREAMBLE_SIZE + HCI_CMD_DATA_SIZE -+ -+/* Send HCI cmd via wl iovar HCI_cmd to the dongle. */ -+int -+dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len) -+{ -+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf; -+ uint8 buf[BTA_HCI_CMD_MAX_LEN + 16]; -+ uint len = sizeof(buf); -+ wl_ioctl_t ioc; -+ -+ if (cmd_len < HCI_CMD_PREAMBLE_SIZE) -+ return BCME_BADLEN; -+ -+ if ((uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE > cmd_len) -+ return BCME_BADLEN; -+ -+ len = bcm_mkiovar("HCI_cmd", -+ (char *)cmd, (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE, (char *)buf, len); -+ -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ -+ ioc.cmd = WLC_SET_VAR; -+ ioc.buf = buf; -+ ioc.len = len; -+ ioc.set = TRUE; -+ -+ return dhd_wl_ioctl(pub, &ioc, ioc.buf, ioc.len); -+} -+#else /* !SEND_HCI_CMD_VIA_IOCTL */ -+ -+static void -+dhd_bta_flush_hcidata(dhd_pub_t *pub, uint16 llh) -+{ -+ int prec; -+ struct pktq *q; -+ uint count = 0; -+ -+ q = dhd_bus_txq(pub->bus); -+ if (q == NULL) -+ return; -+ -+ DHD_BTA(("dhd: flushing HCI ACL data for logical link %u...\n", llh)); -+ -+ dhd_os_sdlock_txq(pub); -+ -+ /* Walk through the txq and toss all HCI ACL data packets */ -+ PKTQ_PREC_ITER(q, prec) { -+ void *head_pkt = NULL; -+ -+ while (pktq_ppeek(q, prec) != head_pkt) { -+ void *pkt = pktq_pdeq(q, prec); -+ int ifidx; -+ -+ PKTPULL(pub->osh, pkt, dhd_bus_hdrlen(pub->bus)); -+ dhd_prot_hdrpull(pub, &ifidx, pkt, NULL, NULL); -+ -+ if (PKTLEN(pub->osh, pkt) >= RFC1042_HDR_LEN) { -+ struct ether_header *eh = -+ (struct ether_header *)PKTDATA(pub->osh, pkt); -+ -+ if (ntoh16(eh->ether_type) < ETHER_TYPE_MIN) { -+ struct dot11_llc_snap_header *lsh = -+ (struct dot11_llc_snap_header *)&eh[1]; -+ -+ if (bcmp(lsh, BT_SIG_SNAP_MPROT, -+ DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && -+ ntoh16(lsh->type) == BTA_PROT_L2CAP) { -+ amp_hci_ACL_data_t *ACL_data = -+ (amp_hci_ACL_data_t *)&lsh[1]; -+ uint16 handle = ltoh16(ACL_data->handle); -+ -+ if (HCI_ACL_DATA_HANDLE(handle) == llh) { -+ PKTFREE(pub->osh, pkt, TRUE); -+ count ++; -+ continue; -+ } -+ } -+ } -+ } -+ -+ dhd_prot_hdrpush(pub, ifidx, pkt); -+ PKTPUSH(pub->osh, pkt, dhd_bus_hdrlen(pub->bus)); -+ -+ if (head_pkt == NULL) -+ head_pkt = pkt; -+ pktq_penq(q, prec, pkt); -+ } -+ } -+ -+ dhd_os_sdunlock_txq(pub); -+ -+ DHD_BTA(("dhd: flushed %u packet(s) for logical link %u...\n", count, llh)); -+} -+ -+/* Handle HCI cmd locally. -+ * Return 0: continue to send the cmd across SDIO -+ * < 0: stop, fail -+ * > 0: stop, succuess -+ */ -+static int -+_dhd_bta_docmd(dhd_pub_t *pub, amp_hci_cmd_t *cmd) -+{ -+ int status = 0; -+ -+ switch (ltoh16_ua((uint8 *)&cmd->opcode)) { -+ case HCI_Enhanced_Flush: { -+ eflush_cmd_parms_t *cmdparms = (eflush_cmd_parms_t *)cmd->parms; -+ dhd_bta_flush_hcidata(pub, ltoh16_ua(cmdparms->llh)); -+ break; -+ } -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/* Send HCI cmd encapsulated in BT-SIG frame via data channel to the dongle. */ -+int -+dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len) -+{ -+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf; -+ struct ether_header *eh; -+ struct dot11_llc_snap_header *lsh; -+ osl_t *osh = pub->osh; -+ uint len; -+ void *p; -+ int status; -+ -+ if (cmd_len < HCI_CMD_PREAMBLE_SIZE) { -+ AP6210_ERR("dhd_bta_docmd: short command, cmd_len %u\n", cmd_len); -+ return BCME_BADLEN; -+ } -+ -+ if ((len = (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE) > cmd_len) { -+ AP6210_ERR("dhd_bta_docmd: malformed command, len %u cmd_len %u\n", -+ len, cmd_len); -+ /* return BCME_BADLEN; */ -+ } -+ -+ p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE); -+ if (p == NULL) { -+ AP6210_ERR("dhd_bta_docmd: out of memory\n"); -+ return BCME_NOMEM; -+ } -+ -+ -+ /* intercept and handle the HCI cmd locally */ -+ if ((status = _dhd_bta_docmd(pub, cmd)) > 0) -+ return 0; -+ else if (status < 0) -+ return status; -+ -+ /* copy in HCI cmd */ -+ PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN); -+ bcopy(cmd, PKTDATA(osh, p), len); -+ -+ /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */ -+ PKTPUSH(osh, p, RFC1042_HDR_LEN); -+ eh = (struct ether_header *)PKTDATA(osh, p); -+ bzero(eh->ether_dhost, ETHER_ADDR_LEN); -+ ETHER_SET_LOCALADDR(eh->ether_dhost); -+ bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN); -+ eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN); -+ lsh = (struct dot11_llc_snap_header *)&eh[1]; -+ bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2); -+ lsh->type = 0; -+ -+ return dhd_sendpkt(pub, 0, p); -+} -+#endif /* !SEND_HCI_CMD_VIA_IOCTL */ -+ -+/* Send HCI ACL data to dongle via data channel */ -+int -+dhd_bta_tx_hcidata(dhd_pub_t *pub, void *data_buf, uint data_len) -+{ -+ amp_hci_ACL_data_t *data = (amp_hci_ACL_data_t *)data_buf; -+ struct ether_header *eh; -+ struct dot11_llc_snap_header *lsh; -+ osl_t *osh = pub->osh; -+ uint len; -+ void *p; -+ -+ if (data_len < HCI_ACL_DATA_PREAMBLE_SIZE) { -+ AP6210_ERR("dhd_bta_tx_hcidata: short data_buf, data_len %u\n", data_len); -+ return BCME_BADLEN; -+ } -+ -+ if ((len = (uint)ltoh16(data->dlen) + HCI_ACL_DATA_PREAMBLE_SIZE) > data_len) { -+ AP6210_ERR("dhd_bta_tx_hcidata: malformed hci data, len %u data_len %u\n", -+ len, data_len); -+ /* return BCME_BADLEN; */ -+ } -+ -+ p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE); -+ if (p == NULL) { -+ AP6210_ERR("dhd_bta_tx_hcidata: out of memory\n"); -+ return BCME_NOMEM; -+ } -+ -+ -+ /* copy in HCI ACL data header and HCI ACL data */ -+ PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN); -+ bcopy(data, PKTDATA(osh, p), len); -+ -+ /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */ -+ PKTPUSH(osh, p, RFC1042_HDR_LEN); -+ eh = (struct ether_header *)PKTDATA(osh, p); -+ bzero(eh->ether_dhost, ETHER_ADDR_LEN); -+ bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN); -+ eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN); -+ lsh = (struct dot11_llc_snap_header *)&eh[1]; -+ bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2); -+ lsh->type = HTON16(BTA_PROT_L2CAP); -+ -+ return dhd_sendpkt(pub, 0, p); -+} -+ -+/* txcomplete callback */ -+void -+dhd_bta_tx_hcidata_complete(dhd_pub_t *dhdp, void *txp, bool success) -+{ -+ uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, txp); -+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)(pktdata + RFC1042_HDR_LEN); -+ uint16 handle = ltoh16(ACL_data->handle); -+ uint16 llh = HCI_ACL_DATA_HANDLE(handle); -+ -+ wl_event_msg_t event; -+ uint8 data[HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t)]; -+ amp_hci_event_t *evt; -+ num_completed_data_blocks_evt_parms_t *parms; -+ -+ uint16 len = HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t); -+ -+ /* update the event struct */ -+ memset(&event, 0, sizeof(event)); -+ event.version = hton16(BCM_EVENT_MSG_VERSION); -+ event.event_type = hton32(WLC_E_BTA_HCI_EVENT); -+ event.status = 0; -+ event.reason = 0; -+ event.auth_type = 0; -+ event.datalen = hton32(len); -+ event.flags = 0; -+ -+ /* generate Number of Completed Blocks event */ -+ evt = (amp_hci_event_t *)data; -+ evt->ecode = HCI_Number_of_Completed_Data_Blocks; -+ evt->plen = sizeof(num_completed_data_blocks_evt_parms_t); -+ -+ parms = (num_completed_data_blocks_evt_parms_t *)evt->parms; -+ htol16_ua_store(dhdp->maxdatablks, (uint8 *)&parms->num_blocks); -+ parms->num_handles = 1; -+ htol16_ua_store(llh, (uint8 *)&parms->completed[0].handle); -+ parms->completed[0].pkts = 1; -+ parms->completed[0].blocks = 1; -+ -+ dhd_sendup_event_common(dhdp, &event, data); -+} -+ -+/* event callback */ -+void -+dhd_bta_doevt(dhd_pub_t *dhdp, void *data_buf, uint data_len) -+{ -+ amp_hci_event_t *evt = (amp_hci_event_t *)data_buf; -+ -+ switch (evt->ecode) { -+ case HCI_Command_Complete: { -+ cmd_complete_parms_t *parms = (cmd_complete_parms_t *)evt->parms; -+ switch (ltoh16_ua((uint8 *)&parms->opcode)) { -+ case HCI_Read_Data_Block_Size: { -+ read_data_block_size_evt_parms_t *parms2 = -+ (read_data_block_size_evt_parms_t *)parms->parms; -+ dhdp->maxdatablks = ltoh16_ua((uint8 *)&parms2->data_block_num); -+ break; -+ } -+ } -+ break; -+ } -+ -+ case HCI_Flush_Occurred: { -+ flush_occurred_evt_parms_t *evt_parms = (flush_occurred_evt_parms_t *)evt->parms; -+ dhd_bta_flush_hcidata(dhdp, ltoh16_ua((uint8 *)&evt_parms->handle)); -+ break; -+ } -+ default: -+ break; -+ } -+} -diff --git a/drivers/net/wireless/ap6210/dhd_bta.h b/drivers/net/wireless/ap6210/dhd_bta.h -new file mode 100644 -index 0000000..0337f15 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_bta.h -@@ -0,0 +1,39 @@ -+/* -+ * BT-AMP support routines -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_bta.h 291086 2011-10-21 01:17:24Z $ -+ */ -+#ifndef __dhd_bta_h__ -+#define __dhd_bta_h__ -+ -+struct dhd_pub; -+ -+extern int dhd_bta_docmd(struct dhd_pub *pub, void *cmd_buf, uint cmd_len); -+ -+extern void dhd_bta_doevt(struct dhd_pub *pub, void *data_buf, uint data_len); -+ -+extern int dhd_bta_tx_hcidata(struct dhd_pub *pub, void *data_buf, uint data_len); -+extern void dhd_bta_tx_hcidata_complete(struct dhd_pub *dhdp, void *txp, bool success); -+ -+ -+#endif /* __dhd_bta_h__ */ -diff --git a/drivers/net/wireless/ap6210/dhd_bus.h b/drivers/net/wireless/ap6210/dhd_bus.h -new file mode 100644 -index 0000000..131907d ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_bus.h -@@ -0,0 +1,111 @@ -+/* -+ * Header file describing the internal (inter-module) DHD interfaces. -+ * -+ * Provides type definitions and function prototypes used to link the -+ * DHD OS, bus, and protocol modules. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_bus.h 347614 2012-07-27 10:24:51Z $ -+ */ -+ -+#ifndef _dhd_bus_h_ -+#define _dhd_bus_h_ -+ -+/* -+ * Exported from dhd bus module (dhd_usb, dhd_sdio) -+ */ -+ -+/* Indicate (dis)interest in finding dongles. */ -+extern int dhd_bus_register(void); -+extern void dhd_bus_unregister(void); -+ -+/* Download firmware image and nvram image */ -+extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, -+ char *fw_path, char *nv_path); -+ -+/* Stop bus module: clear pending frames, disable data flow */ -+extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); -+ -+/* Initialize bus module: prepare for communication w/dongle */ -+extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); -+ -+/* Get the Bus Idle Time */ -+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime); -+ -+/* Set the Bus Idle Time */ -+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time); -+ -+/* Send a data frame to the dongle. Callee disposes of txp. */ -+extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp, bool wlfc_locked); -+ -+/* Send/receive a control message to/from the dongle. -+ * Expects caller to enforce a single outstanding transaction. -+ */ -+extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen); -+extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen); -+ -+/* Watchdog timer function */ -+extern bool dhd_bus_watchdog(dhd_pub_t *dhd); -+extern void dhd_disable_intr(dhd_pub_t *dhd); -+ -+#if defined(DHD_DEBUG) -+/* Device console input function */ -+extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen); -+#endif /* defined(DHD_DEBUG) */ -+ -+/* Deferred processing for the bus, return TRUE requests reschedule */ -+extern bool dhd_bus_dpc(struct dhd_bus *bus); -+extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg); -+ -+ -+/* Check for and handle local prot-specific iovar commands */ -+extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, -+ void *params, int plen, void *arg, int len, bool set); -+ -+/* Add bus dump output to a buffer */ -+extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); -+ -+/* Clear any bus counters */ -+extern void dhd_bus_clearcounts(dhd_pub_t *dhdp); -+ -+/* return the dongle chipid */ -+extern uint dhd_bus_chip(struct dhd_bus *bus); -+ -+/* Set user-specified nvram parameters. */ -+extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params); -+ -+extern void *dhd_bus_pub(struct dhd_bus *bus); -+extern void *dhd_bus_txq(struct dhd_bus *bus); -+extern uint dhd_bus_hdrlen(struct dhd_bus *bus); -+ -+ -+#define DHD_SET_BUS_STATE_DOWN(_bus) do { \ -+ (_bus)->dhd->busstate = DHD_BUS_DOWN; \ -+} while (0) -+ -+/* Register a dummy SDIO client driver in order to be notified of new SDIO device */ -+extern int dhd_bus_reg_sdio_notify(void* semaphore); -+extern void dhd_bus_unreg_sdio_notify(void); -+ -+extern void dhd_txglom_enable(dhd_pub_t *dhdp, bool enable); -+ -+#endif /* _dhd_bus_h_ */ -diff --git a/drivers/net/wireless/ap6210/dhd_cdc.c b/drivers/net/wireless/ap6210/dhd_cdc.c -new file mode 100644 -index 0000000..3a7f55b ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_cdc.c -@@ -0,0 +1,3191 @@ -+/* -+ * DHD Protocol Module for CDC and BDC. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_cdc.c 368762 2012-11-14 21:59:17Z $ -+ * -+ * BDC is like CDC, except it includes a header for data packets to convey -+ * packet priority over the bus, and flags (e.g. to indicate checksum status -+ * for dongle offload.) -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+#ifdef PROP_TXSTATUS -+#include -+#include -+#endif -+ -+#include -+ -+#define RETRIES 2 /* # of retries to retrieve matching ioctl response */ -+#define BUS_HEADER_LEN (24+DHD_SDALIGN) /* Must be at least SDPCM_RESERVE -+ * defined in dhd_sdio.c (amount of header tha might be added) -+ * plus any space that might be needed for alignment padding. -+ */ -+#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for -+ * round off at the end of buffer -+ */ -+ -+#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */ -+ -+#ifdef PROP_TXSTATUS -+typedef struct dhd_wlfc_commit_info { -+ uint8 needs_hdr; -+ uint8 ac_fifo_credit_spent; -+ ewlfc_packet_state_t pkt_type; -+ wlfc_mac_descriptor_t* mac_entry; -+ void* p; -+} dhd_wlfc_commit_info_t; -+#endif /* PROP_TXSTATUS */ -+ -+ -+typedef struct dhd_prot { -+ uint16 reqid; -+ uint8 pending; -+ uint32 lastcmd; -+ uint8 bus_header[BUS_HEADER_LEN]; -+ cdc_ioctl_t msg; -+ unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; -+} dhd_prot_t; -+ -+ -+static int -+dhdcdc_msg(dhd_pub_t *dhd) -+{ -+ int err = 0; -+ dhd_prot_t *prot = dhd->prot; -+ int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t); -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ DHD_OS_WAKE_LOCK(dhd); -+ -+ /* NOTE : cdc->msg.len holds the desired length of the buffer to be -+ * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area -+ * is actually sent to the dongle -+ */ -+ if (len > CDC_MAX_MSG_SIZE) -+ len = CDC_MAX_MSG_SIZE; -+ -+ /* Send request */ -+ err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len); -+ -+ DHD_OS_WAKE_UNLOCK(dhd); -+ return err; -+} -+ -+static int -+dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len) -+{ -+ int ret; -+ int cdc_len = len + sizeof(cdc_ioctl_t); -+ dhd_prot_t *prot = dhd->prot; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ do { -+ ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len); -+ if (ret < 0) -+ break; -+ } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); -+ -+ return ret; -+} -+ -+static int -+dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action) -+{ -+ dhd_prot_t *prot = dhd->prot; -+ cdc_ioctl_t *msg = &prot->msg; -+ void *info; -+ int ret = 0, retries = 0; -+ uint32 id, flags = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ AP6210_DEBUG("%s: cmd %d len %d\n", __FUNCTION__, cmd, len); -+ -+ -+ /* Respond "bcmerror" and "bcmerrorstr" with local cache */ -+ if (cmd == WLC_GET_VAR && buf) -+ { -+ if (!strcmp((char *)buf, "bcmerrorstr")) -+ { -+ strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN); -+ goto done; -+ } -+ else if (!strcmp((char *)buf, "bcmerror")) -+ { -+ *(int *)buf = dhd->dongle_error; -+ goto done; -+ } -+ } -+ -+ memset(msg, 0, sizeof(cdc_ioctl_t)); -+ -+ msg->cmd = htol32(cmd); -+ msg->len = htol32(len); -+ msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); -+ CDC_SET_IF_IDX(msg, ifidx); -+ /* add additional action bits */ -+ action &= WL_IOCTL_ACTION_MASK; -+ msg->flags |= (action << CDCF_IOC_ACTION_SHIFT); -+ msg->flags = htol32(msg->flags); -+ -+ if (buf) -+ memcpy(prot->buf, buf, len); -+ -+ if ((ret = dhdcdc_msg(dhd)) < 0) { -+ if (!dhd->hang_was_sent) -+ AP6210_ERR("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret); -+ goto done; -+ } -+ -+retry: -+ /* wait for interrupt and get first fragment */ -+ if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) -+ goto done; -+ -+ flags = ltoh32(msg->flags); -+ id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; -+ -+ if ((id < prot->reqid) && (++retries < RETRIES)) -+ goto retry; -+ if (id != prot->reqid) { -+ AP6210_ERR("%s: %s: unexpected request id %d (expected %d)\n", -+ dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid); -+ ret = -EINVAL; -+ goto done; -+ } -+ -+ /* Check info buffer */ -+ info = (void*)&msg[1]; -+ -+ /* Copy info buffer */ -+ if (buf) -+ { -+ if (ret < (int)len) -+ len = ret; -+ memcpy(buf, info, len); -+ } -+ -+ /* Check the ERROR flag */ -+ if (flags & CDCF_IOC_ERROR) -+ { -+ ret = ltoh32(msg->status); -+ /* Cache error from dongle */ -+ dhd->dongle_error = ret; -+ } -+ -+done: -+ return ret; -+} -+ -+static int -+dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action) -+{ -+ dhd_prot_t *prot = dhd->prot; -+ cdc_ioctl_t *msg = &prot->msg; -+ int ret = 0; -+ uint32 flags, id; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ AP6210_DEBUG("%s: cmd %d len %d\n", __FUNCTION__, cmd, len); -+ -+ if (dhd->busstate == DHD_BUS_DOWN) { -+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__); -+ return -EIO; -+ } -+ -+ /* don't talk to the dongle if fw is about to be reloaded */ -+ if (dhd->hang_was_sent) { -+ AP6210_ERR("%s: HANG was sent up earlier. Not talking to the chip\n", -+ __FUNCTION__); -+ return -EIO; -+ } -+ -+ memset(msg, 0, sizeof(cdc_ioctl_t)); -+ -+ msg->cmd = htol32(cmd); -+ msg->len = htol32(len); -+ msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); -+ CDC_SET_IF_IDX(msg, ifidx); -+ /* add additional action bits */ -+ action &= WL_IOCTL_ACTION_MASK; -+ msg->flags |= (action << CDCF_IOC_ACTION_SHIFT) | CDCF_IOC_SET; -+ msg->flags = htol32(msg->flags); -+ -+ if (buf) -+ memcpy(prot->buf, buf, len); -+ -+ if ((ret = dhdcdc_msg(dhd)) < 0) { -+ AP6210_ERR("%s: dhdcdc_msg failed w/status %d\n", __FUNCTION__, ret); -+ goto done; -+ } -+ -+ if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0) -+ goto done; -+ -+ flags = ltoh32(msg->flags); -+ id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; -+ -+ if (id != prot->reqid) { -+ AP6210_ERR("%s: %s: unexpected request id %d (expected %d)\n", -+ dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid); -+ ret = -EINVAL; -+ goto done; -+ } -+ -+ /* Check the ERROR flag */ -+ if (flags & CDCF_IOC_ERROR) -+ { -+ ret = ltoh32(msg->status); -+ /* Cache error from dongle */ -+ dhd->dongle_error = ret; -+ } -+ -+done: -+ return ret; -+} -+ -+ -+int -+dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len) -+{ -+ dhd_prot_t *prot = dhd->prot; -+ int ret = -1; -+ uint8 action; -+#if defined(NDIS630) -+ bool acquired = FALSE; -+#endif -+ -+ if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) { -+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__); -+ goto done; -+ } -+#if defined(NDIS630) -+ if (dhd_os_proto_block(dhd)) -+ { -+ acquired = TRUE; -+ } -+ else -+ { -+ /* attempt to acquire protocol mutex timed out. */ -+ ret = -1; -+ return ret; -+ } -+#endif /* NDIS630 */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(len <= WLC_IOCTL_MAXLEN); -+ -+ if (len > WLC_IOCTL_MAXLEN) -+ goto done; -+ -+ if (prot->pending == TRUE) { -+ AP6210_ERR("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", -+ ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, -+ (unsigned long)prot->lastcmd); -+ if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) { -+ AP6210_DEBUG("iovar cmd=%s\n", (char*)buf); -+ } -+ goto done; -+ } -+ -+ prot->pending = TRUE; -+ prot->lastcmd = ioc->cmd; -+ action = ioc->set; -+ if (action & WL_IOCTL_ACTION_SET) -+ ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action); -+ else { -+ ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action); -+ if (ret > 0) -+ ioc->used = ret - sizeof(cdc_ioctl_t); -+ } -+ -+ /* Too many programs assume ioctl() returns 0 on success */ -+ if (ret >= 0) -+ ret = 0; -+ else { -+ cdc_ioctl_t *msg = &prot->msg; -+ ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */ -+ } -+ -+ /* Intercept the wme_dp ioctl here */ -+ if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) { -+ int slen, val = 0; -+ -+ slen = strlen("wme_dp") + 1; -+ if (len >= (int)(slen + sizeof(int))) -+ bcopy(((char *)buf + slen), &val, sizeof(int)); -+ dhd->wme_dp = (uint8) ltoh32(val); -+ } -+ -+ prot->pending = FALSE; -+ -+done: -+#if defined(NDIS630) -+ if (acquired) -+ dhd_os_proto_unblock(dhd); -+#endif -+ return ret; -+} -+ -+int -+dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, -+ void *params, int plen, void *arg, int len, bool set) -+{ -+ return BCME_UNSUPPORTED; -+} -+ -+#ifdef PROP_TXSTATUS -+void -+dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -+{ -+ int i; -+ uint8* ea; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhdp->wlfc_state; -+ wlfc_hanger_t* h; -+ wlfc_mac_descriptor_t* mac_table; -+ wlfc_mac_descriptor_t* interfaces; -+ char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"}; -+ -+ if (wlfc == NULL) { -+ bcm_bprintf(strbuf, "wlfc not initialized yet\n"); -+ return; -+ } -+ h = (wlfc_hanger_t*)wlfc->hanger; -+ if (h == NULL) { -+ bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n"); -+ } -+ -+ mac_table = wlfc->destination_entries.nodes; -+ interfaces = wlfc->destination_entries.interfaces; -+ bcm_bprintf(strbuf, "---- wlfc stats ----\n"); -+ if (h) { -+ bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push," -+ "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n", -+ h->pushed, -+ h->popped, -+ h->failed_to_push, -+ h->failed_to_pop, -+ h->failed_slotfind, -+ (h->pushed - h->popped)); -+ } -+ -+ bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), " -+ "(dq_full,sendq_full, rollback_fail) = (%d,%d,%d,%d), (%d,%d,%d)\n", -+ wlfc->stats.tlv_parse_failed, -+ wlfc->stats.credit_request_failed, -+ wlfc->stats.mac_update_failed, -+ wlfc->stats.psmode_update_failed, -+ wlfc->stats.delayq_full_error, -+ wlfc->stats.sendq_full_error, -+ wlfc->stats.rollback_failed); -+ -+ bcm_bprintf(strbuf, "SENDQ (len,credit,sent) " -+ "(AC0[%d,%d,%d],AC1[%d,%d,%d],AC2[%d,%d,%d],AC3[%d,%d,%d],BC_MC[%d,%d,%d])\n", -+ wlfc->SENDQ.q[0].len, wlfc->FIFO_credit[0], wlfc->stats.sendq_pkts[0], -+ wlfc->SENDQ.q[1].len, wlfc->FIFO_credit[1], wlfc->stats.sendq_pkts[1], -+ wlfc->SENDQ.q[2].len, wlfc->FIFO_credit[2], wlfc->stats.sendq_pkts[2], -+ wlfc->SENDQ.q[3].len, wlfc->FIFO_credit[3], wlfc->stats.sendq_pkts[3], -+ wlfc->SENDQ.q[4].len, wlfc->FIFO_credit[4], wlfc->stats.sendq_pkts[4]); -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ bcm_bprintf(strbuf, "SENDQ dropped: AC[0-3]:(%d,%d,%d,%d), (bcmc,atim):(%d,%d)\n", -+ wlfc->stats.dropped_qfull[0], wlfc->stats.dropped_qfull[1], -+ wlfc->stats.dropped_qfull[2], wlfc->stats.dropped_qfull[3], -+ wlfc->stats.dropped_qfull[4], wlfc->stats.dropped_qfull[5]); -+#endif -+ -+ bcm_bprintf(strbuf, "\n"); -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (interfaces[i].occupied) { -+ char* iftype_desc; -+ -+ if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT) -+ iftype_desc = "hostif_flow_state[i] == OFF) -+ ? " OFF":" ON")); -+ -+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)" -+ "= (%d,%s,%d)\n", -+ i, -+ interfaces[i].psq.len, -+ ((interfaces[i].state == -+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), -+ interfaces[i].requested_credit); -+ -+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ" -+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " -+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", -+ i, -+ interfaces[i].psq.q[0].len, -+ interfaces[i].psq.q[1].len, -+ interfaces[i].psq.q[2].len, -+ interfaces[i].psq.q[3].len, -+ interfaces[i].psq.q[4].len, -+ interfaces[i].psq.q[5].len, -+ interfaces[i].psq.q[6].len, -+ interfaces[i].psq.q[7].len); -+ } -+ } -+ -+ bcm_bprintf(strbuf, "\n"); -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (mac_table[i].occupied) { -+ ea = mac_table[i].ea; -+ bcm_bprintf(strbuf, "MAC_table[%d].ea = " -+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i, -+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], -+ mac_table[i].interface_id); -+ -+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)" -+ "= (%d,%s,%d)\n", -+ i, -+ mac_table[i].psq.len, -+ ((mac_table[i].state == -+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), -+ mac_table[i].requested_credit); -+#ifdef PROP_TXSTATUS_DEBUG -+ bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n", -+ i, mac_table[i].opened_ct, mac_table[i].closed_ct); -+#endif -+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ" -+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " -+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", -+ i, -+ mac_table[i].psq.q[0].len, -+ mac_table[i].psq.q[1].len, -+ mac_table[i].psq.q[2].len, -+ mac_table[i].psq.q[3].len, -+ mac_table[i].psq.q[4].len, -+ mac_table[i].psq.q[5].len, -+ mac_table[i].psq.q[6].len, -+ mac_table[i].psq.q[7].len); -+ } -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ int avg; -+ int moving_avg = 0; -+ int moving_samples; -+ -+ if (wlfc->stats.latency_sample_count) { -+ moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32); -+ -+ for (i = 0; i < moving_samples; i++) -+ moving_avg += wlfc->stats.deltas[i]; -+ moving_avg /= moving_samples; -+ -+ avg = (100 * wlfc->stats.total_status_latency) / -+ wlfc->stats.latency_sample_count; -+ bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = " -+ "(%d.%d, %03d, %03d)\n", -+ moving_samples, avg/100, (avg - (avg/100)*100), -+ wlfc->stats.latency_most_recent, -+ moving_avg); -+ } -+ } -+ -+ bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), " -+ "back = (%d,%d,%d,%d,%d,%d)\n", -+ wlfc->stats.fifo_credits_sent[0], -+ wlfc->stats.fifo_credits_sent[1], -+ wlfc->stats.fifo_credits_sent[2], -+ wlfc->stats.fifo_credits_sent[3], -+ wlfc->stats.fifo_credits_sent[4], -+ wlfc->stats.fifo_credits_sent[5], -+ -+ wlfc->stats.fifo_credits_back[0], -+ wlfc->stats.fifo_credits_back[1], -+ wlfc->stats.fifo_credits_back[2], -+ wlfc->stats.fifo_credits_back[3], -+ wlfc->stats.fifo_credits_back[4], -+ wlfc->stats.fifo_credits_back[5]); -+ { -+ uint32 fifo_cr_sent = 0; -+ uint32 fifo_cr_acked = 0; -+ uint32 request_cr_sent = 0; -+ uint32 request_cr_ack = 0; -+ uint32 bc_mc_cr_ack = 0; -+ -+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) { -+ fifo_cr_sent += wlfc->stats.fifo_credits_sent[i]; -+ } -+ -+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) { -+ fifo_cr_acked += wlfc->stats.fifo_credits_back[i]; -+ } -+ -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (wlfc->destination_entries.nodes[i].occupied) { -+ request_cr_sent += -+ wlfc->destination_entries.nodes[i].dstncredit_sent_packets; -+ } -+ } -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (wlfc->destination_entries.interfaces[i].occupied) { -+ request_cr_sent += -+ wlfc->destination_entries.interfaces[i].dstncredit_sent_packets; -+ } -+ } -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (wlfc->destination_entries.nodes[i].occupied) { -+ request_cr_ack += -+ wlfc->destination_entries.nodes[i].dstncredit_acks; -+ } -+ } -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (wlfc->destination_entries.interfaces[i].occupied) { -+ request_cr_ack += -+ wlfc->destination_entries.interfaces[i].dstncredit_acks; -+ } -+ } -+ bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d)," -+ "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)", -+ fifo_cr_sent, fifo_cr_acked, -+ request_cr_sent, request_cr_ack, -+ wlfc->destination_entries.other.dstncredit_acks, -+ bc_mc_cr_ack, -+ wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed); -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ bcm_bprintf(strbuf, "\n"); -+ bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)" -+ "(freed,free_err,rollback)) = " -+ "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", -+ wlfc->stats.pktin, -+ wlfc->stats.pkt2bus, -+ wlfc->stats.txstatus_in, -+ wlfc->stats.dhd_hdrpulls, -+ -+ wlfc->stats.pktdropped, -+ wlfc->stats.wlfc_header_only_pkt, -+ wlfc->stats.wlc_tossed_pkts, -+ -+ wlfc->stats.pkt_freed, -+ wlfc->stats.pkt_free_err, wlfc->stats.rollback); -+ -+ bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = " -+ "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n", -+ -+ wlfc->stats.d11_suppress, -+ wlfc->stats.wl_suppress, -+ wlfc->stats.bad_suppress, -+ -+ wlfc->stats.psq_d11sup_enq, -+ wlfc->stats.psq_wlsup_enq, -+ wlfc->stats.psq_hostq_enq, -+ wlfc->stats.mac_handle_notfound, -+ -+ wlfc->stats.psq_d11sup_retx, -+ wlfc->stats.psq_wlsup_retx, -+ wlfc->stats.psq_hostq_retx); -+ return; -+} -+ -+/* Create a place to store all packet pointers submitted to the firmware until -+ a status comes back, suppress or otherwise. -+ -+ hang-er: noun, a contrivance on which things are hung, as a hook. -+*/ -+static void* -+dhd_wlfc_hanger_create(osl_t *osh, int max_items) -+{ -+ int i; -+ wlfc_hanger_t* hanger; -+ -+ /* allow only up to a specific size for now */ -+ ASSERT(max_items == WLFC_HANGER_MAXITEMS); -+ -+ if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL) -+ return NULL; -+ -+ memset(hanger, 0, WLFC_HANGER_SIZE(max_items)); -+ hanger->max_items = max_items; -+ -+ for (i = 0; i < hanger->max_items; i++) { -+ hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ return hanger; -+} -+ -+static int -+dhd_wlfc_hanger_delete(osl_t *osh, void* hanger) -+{ -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h) { -+ MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items)); -+ return BCME_OK; -+ } -+ return BCME_BADARG; -+} -+ -+static uint16 -+dhd_wlfc_hanger_get_free_slot(void* hanger) -+{ -+ uint32 i; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h) { -+ for (i = (h->slot_pos + 1); i != h->slot_pos;) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) { -+ h->slot_pos = i; -+ return (uint16)i; -+ } -+ (i == h->max_items)? i = 0 : i++; -+ } -+ h->failed_slotfind++; -+ } -+ return WLFC_HANGER_MAXITEMS; -+} -+ -+static int -+dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ *gen = 0xff; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ -+ if (h) { -+ if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) || -+ (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) { -+ *gen = h->items[slot_id].gen; -+ } -+ else { -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h && (slot_id < WLFC_HANGER_MAXITEMS)) { -+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) { -+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE; -+ h->items[slot_id].pkt = pkt; -+ h->items[slot_id].identifier = slot_id; -+ h->pushed++; -+ } -+ else { -+ h->failed_to_push++; -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ -+ if (h) { -+ if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) { -+ *pktout = h->items[slot_id].pkt; -+ if (remove_from_hanger) { -+ h->items[slot_id].state = -+ WLFC_HANGER_ITEM_STATE_FREE; -+ h->items[slot_id].pkt = NULL; -+ h->items[slot_id].identifier = 0; -+ h->items[slot_id].gen = 0xff; -+ h->popped++; -+ } -+ } -+ else { -+ h->failed_to_pop++; -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ if (h) { -+ h->items[slot_id].gen = gen; -+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED; -+ } -+ else -+ rc = BCME_BADARG; -+ } -+ else -+ rc = BCME_BADARG; -+ -+ return rc; -+} -+ -+static int -+_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal, -+ uint8 tim_bmp, uint8 mac_handle, uint32 htodtag) -+{ -+ uint32 wl_pktinfo = 0; -+ uint8* wlh; -+ uint8 dataOffset; -+ uint8 fillers; -+ uint8 tim_signal_len = 0; -+ -+ struct bdc_header *h; -+ -+ if (tim_signal) { -+ tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; -+ } -+ -+ /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ -+ dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len; -+ fillers = ROUNDUP(dataOffset, 4) - dataOffset; -+ dataOffset += fillers; -+ -+ PKTPUSH(ctx->osh, p, dataOffset); -+ wlh = (uint8*) PKTDATA(ctx->osh, p); -+ -+ wl_pktinfo = htol32(htodtag); -+ -+ wlh[0] = WLFC_CTL_TYPE_PKTTAG; -+ wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG; -+ memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32)); -+ -+ if (tim_signal_len) { -+ wlh[dataOffset - fillers - tim_signal_len ] = -+ WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP; -+ wlh[dataOffset - fillers - tim_signal_len + 1] = -+ WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; -+ wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle; -+ wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp; -+ } -+ if (fillers) -+ memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers); -+ -+ PKTPUSH(ctx->osh, p, BDC_HEADER_LEN); -+ h = (struct bdc_header *)PKTDATA(ctx->osh, p); -+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); -+ if (PKTSUMNEEDED(p)) -+ h->flags |= BDC_FLAG_SUM_NEEDED; -+ -+ -+ h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); -+ h->flags2 = 0; -+ h->dataOffset = dataOffset >> 2; -+ BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p))); -+ return BCME_OK; -+} -+ -+static int -+_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) -+{ -+ struct bdc_header *h; -+ -+ if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) { -+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN); -+ return BCME_ERROR; -+ } -+ h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf); -+ -+ /* pull BDC header */ -+ PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); -+ -+ if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) { -+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2)); -+ return BCME_ERROR; -+ } -+ /* pull wl-header */ -+ PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); -+ return BCME_OK; -+} -+ -+static wlfc_mac_descriptor_t* -+_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p) -+{ -+ int i; -+ wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes; -+ uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p)); -+ uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p)); -+ -+ if (((ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_STA) || -+ ETHER_ISMULTI(dstn) || -+ (ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_P2P_CLIENT)) && -+ (ctx->destination_entries.interfaces[ifid].occupied)) { -+ return &ctx->destination_entries.interfaces[ifid]; -+ } -+ -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (table[i].occupied) { -+ if (table[i].interface_id == ifid) { -+ if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) -+ return &table[i]; -+ } -+ } -+ } -+ return &ctx->destination_entries.other; -+} -+ -+static int -+_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, -+ void* p, ewlfc_packet_state_t pkt_type, uint32 hslot) -+{ -+ /* -+ put the packet back to the head of queue -+ -+ - a packet from send-q will need to go back to send-q and not delay-q -+ since that will change the order of packets. -+ - suppressed packet goes back to suppress sub-queue -+ - pull out the header, if new or delayed packet -+ -+ Note: hslot is used only when header removal is done. -+ */ -+ wlfc_mac_descriptor_t* entry; -+ void* pktout; -+ int rc = BCME_OK; -+ int prec; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ prec = DHD_PKTTAG_FIFO(PKTTAG(p)); -+ if (entry != NULL) { -+ if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) { -+ /* wl-header is saved for suppressed packets */ -+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ } -+ else { -+ /* remove header first */ -+ rc = _dhd_wlfc_pullheader(ctx, p); -+ if (rc != BCME_OK) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ /* free the hanger slot */ -+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); -+ PKTFREE(ctx->osh, p, TRUE); -+ rc = BCME_ERROR; -+ return rc; -+ } -+ -+ if (pkt_type == eWLFC_PKTTYPE_DELAYED) { -+ /* delay-q packets are going to delay-q */ -+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ } -+ else { -+ /* these are going to SENDQ */ -+ if (WLFC_PKTQ_PENQ_HEAD(&ctx->SENDQ, prec, p) == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ } -+ /* free the hanger slot */ -+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); -+ -+ /* decrement sequence count */ -+ WLFC_DECR_SEQCOUNT(entry, prec); -+ } -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the firmware (for pspoll etc.) -+ */ -+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { -+ entry->requested_credit++; -+ } -+ } -+ else { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ if (rc != BCME_OK) -+ ctx->stats.rollback_failed++; -+ else -+ ctx->stats.rollback++; -+ -+ return rc; -+} -+ -+static void -+_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id) -+{ -+ if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { -+ /* start traffic */ -+ ctx->hostif_flow_state[if_id] = OFF; -+ /* -+ AP6210_DEBUG("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", -+ pq->len, if_id, __FUNCTION__); -+ */ -+ AP6210_DEBUG("F"); -+ dhd_txflowcontrol(ctx->dhdp, if_id, OFF); -+ ctx->toggle_host_if = 0; -+ } -+ if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { -+ /* stop traffic */ -+ ctx->hostif_flow_state[if_id] = ON; -+ /* -+ AP6210_DEBUG("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", -+ pq->len, if_id, __FUNCTION__); -+ */ -+ AP6210_DEBUG("N"); -+ dhd_txflowcontrol(ctx->dhdp, if_id, ON); -+ ctx->host_ifidx = if_id; -+ ctx->toggle_host_if = 1; -+ } -+ return; -+} -+ -+static int -+_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ uint8 ta_bmp) -+{ -+ int rc = BCME_OK; -+ void* p = NULL; -+ int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12; -+ -+ /* allocate a dummy packet */ -+ p = PKTGET(ctx->osh, dummylen, TRUE); -+ if (p) { -+ PKTPULL(ctx->osh, p, dummylen); -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0); -+ _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0); -+ DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1); -+#ifdef PROP_TXSTATUS_DEBUG -+ ctx->stats.signal_only_pkts_sent++; -+#endif -+ rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p, FALSE); -+ if (rc != BCME_OK) { -+ PKTFREE(ctx->osh, p, TRUE); -+ } -+ } -+ else { -+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n", -+ __FUNCTION__, dummylen); -+ rc = BCME_NOMEM; -+ } -+ return rc; -+} -+ -+/* Return TRUE if traffic availability changed */ -+static bool -+_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ int prec) -+{ -+ bool rc = FALSE; -+ -+ if (entry->state == WLFC_STATE_CLOSE) { -+ if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && -+ (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { -+ -+ if (entry->traffic_pending_bmp & NBITVAL(prec)) { -+ rc = TRUE; -+ entry->traffic_pending_bmp = -+ entry->traffic_pending_bmp & ~ NBITVAL(prec); -+ } -+ } -+ else { -+ if (!(entry->traffic_pending_bmp & NBITVAL(prec))) { -+ rc = TRUE; -+ entry->traffic_pending_bmp = -+ entry->traffic_pending_bmp | NBITVAL(prec); -+ } -+ } -+ } -+ if (rc) { -+ /* request a TIM update to firmware at the next piggyback opportunity */ -+ if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) { -+ entry->send_tim_signal = 1; -+ _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp); -+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; -+ entry->send_tim_signal = 0; -+ } -+ else { -+ rc = FALSE; -+ } -+ } -+ return rc; -+} -+ -+static int -+_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p) -+{ -+ wlfc_mac_descriptor_t* entry; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_NOTFOUND; -+ } -+ /* -+ - suppressed packets go to sub_queue[2*prec + 1] AND -+ - delayed packets go to sub_queue[2*prec + 0] to ensure -+ order of delivery. -+ */ -+ if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) { -+ ctx->stats.delayq_full_error++; -+ /* AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); */ -+ AP6210_DEBUG("s"); -+ return BCME_ERROR; -+ } -+ /* A packet has been pushed, update traffic availability bitmap, if applicable */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); -+ return BCME_OK; -+} -+ -+static int -+_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, -+ wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot) -+{ -+ int rc = BCME_OK; -+ int hslot = WLFC_HANGER_MAXITEMS; -+ bool send_tim_update = FALSE; -+ uint32 htod = 0; -+ uint8 free_ctr; -+ -+ *slot = hslot; -+ -+ if (entry == NULL) { -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ } -+ -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_ERROR; -+ } -+ if (entry->send_tim_signal) { -+ send_tim_update = TRUE; -+ entry->send_tim_signal = 0; -+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; -+ } -+ if (header_needed) { -+ hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger); -+ free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); -+ WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation); -+ entry->transit_count++; -+ } -+ else { -+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ } -+ WLFC_PKTID_HSLOT_SET(htod, hslot); -+ WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr); -+ DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); -+ WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); -+ WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); -+ -+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { -+ /* -+ Indicate that this packet is being sent in response to an -+ explicit request from the firmware side. -+ */ -+ WLFC_PKTFLAG_SET_PKTREQUESTED(htod); -+ } -+ else { -+ WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); -+ } -+ if (header_needed) { -+ rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, -+ entry->traffic_lastreported_bmp, entry->mac_handle, htod); -+ if (rc == BCME_OK) { -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); -+ /* -+ a new header was created for this packet. -+ push to hanger slot and scrub q. Since bus -+ send succeeded, increment seq number as well. -+ */ -+ rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot); -+ if (rc == BCME_OK) { -+ /* increment free running sequence count */ -+ WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -+#ifdef PROP_TXSTATUS_DEBUG -+ ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time = -+ OSL_SYSUPTIME(); -+#endif -+ } -+ else { -+ AP6210_DEBUG("%s() hanger_pushpkt() failed, rc: %d\n", -+ __FUNCTION__, rc); -+ } -+ } -+ } -+ else { -+ int gen; -+ -+ /* remove old header */ -+ rc = _dhd_wlfc_pullheader(ctx, p); -+ if (rc == BCME_OK) { -+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); -+ -+ WLFC_PKTFLAG_SET_GENERATION(htod, gen); -+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ /* push new header */ -+ _dhd_wlfc_pushheader(ctx, p, send_tim_update, -+ entry->traffic_lastreported_bmp, entry->mac_handle, htod); -+ } -+ } -+ *slot = hslot; -+ return rc; -+} -+ -+static int -+_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx, -+ wlfc_mac_descriptor_t* entry, int prec) -+{ -+ if (ctx->destination_entries.interfaces[entry->interface_id].iftype == -+ WLC_E_IF_ROLE_P2P_GO) { -+ /* - destination interface is of type p2p GO. -+ For a p2pGO interface, if the destination is OPEN but the interface is -+ CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is -+ destination-specific-credit left send packets. This is because the -+ firmware storing the destination-specific-requested packet in queue. -+ */ -+ if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && -+ (entry->requested_packet == 0)) -+ return 1; -+ } -+ /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ -+ if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && -+ (entry->requested_packet == 0)) || -+ (!(entry->ac_bitmap & (1 << prec)))) -+ return 1; -+ -+ return 0; -+} -+ -+static void* -+_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, -+ int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out) -+{ -+ wlfc_mac_descriptor_t* entry; -+ wlfc_mac_descriptor_t* table; -+ uint8 token_pos; -+ int total_entries; -+ void* p = NULL; -+ int pout; -+ int i; -+ -+ *entry_out = NULL; -+ token_pos = ctx->token_pos[prec]; -+ /* most cases a packet will count against FIFO credit */ -+ *ac_credit_spent = 1; -+ *needs_hdr = 1; -+ -+ /* search all entries, include nodes as well as interfaces */ -+ table = (wlfc_mac_descriptor_t*)&ctx->destination_entries; -+ total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t); -+ -+ for (i = 0; i < total_entries; i++) { -+ entry = &table[(token_pos + i) % total_entries]; -+ if (entry->occupied) { -+ if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) { -+ p = pktq_mdeq(&entry->psq, -+ /* higher precedence will be picked up first, -+ * i.e. suppressed packets before delayed ones -+ */ -+ NBITVAL((prec << 1) + 1), &pout); -+ *needs_hdr = 0; -+ -+ if (p == NULL) { -+ if (entry->suppressed == TRUE) { -+ if ((entry->suppr_transit_count <= -+ entry->suppress_count)) { -+ entry->suppressed = FALSE; -+ } else { -+ return NULL; -+ } -+ } -+ /* De-Q from delay Q */ -+ p = pktq_mdeq(&entry->psq, -+ NBITVAL((prec << 1)), -+ &pout); -+ *needs_hdr = 1; -+ } -+ -+ if (p != NULL) { -+ /* did the packet come from suppress sub-queue? */ -+ if (entry->requested_credit > 0) { -+ entry->requested_credit--; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_sent_packets++; -+#endif -+ /* -+ if the packet was pulled out while destination is in -+ closed state but had a non-zero packets requested, -+ then this should not count against the FIFO credit. -+ That is due to the fact that the firmware will -+ most likely hold onto this packet until a suitable -+ time later to push it to the appropriate AC FIFO. -+ */ -+ if (entry->state == WLFC_STATE_CLOSE) -+ *ac_credit_spent = 0; -+ } -+ else if (entry->requested_packet > 0) { -+ entry->requested_packet--; -+ DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); -+ if (entry->state == WLFC_STATE_CLOSE) -+ *ac_credit_spent = 0; -+ } -+ /* move token to ensure fair round-robin */ -+ ctx->token_pos[prec] = -+ (token_pos + i + 1) % total_entries; -+ *entry_out = entry; -+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, -+ DHD_PKTTAG_IF(PKTTAG(p))); -+ /* -+ A packet has been picked up, update traffic -+ availability bitmap, if applicable -+ */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ return p; -+ } -+ } -+ } -+ } -+ return NULL; -+} -+ -+static void* -+_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec) -+{ -+ wlfc_mac_descriptor_t* entry; -+ void* p; -+ -+ -+ p = pktq_pdeq(&ctx->SENDQ, prec); -+ if (p != NULL) { -+ if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p)))) -+ /* bc/mc packets do not have a delay queue */ -+ return p; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return p; -+ } -+ -+ while ((p != NULL)) { -+ /* -+ - suppressed packets go to sub_queue[2*prec + 1] AND -+ - delayed packets go to sub_queue[2*prec + 0] to ensure -+ order of delivery. -+ */ -+ if (WLFC_PKTQ_PENQ(&entry->psq, (prec << 1), p) == NULL) { -+ AP6210_DEBUG("D"); -+ /* dhd_txcomplete(ctx->dhdp, p, FALSE); */ -+ PKTFREE(ctx->osh, p, TRUE); -+ ctx->stats.delayq_full_error++; -+ } -+ /* -+ A packet has been pushed, update traffic availability bitmap, -+ if applicable -+ */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ -+ p = pktq_pdeq(&ctx->SENDQ, prec); -+ if (p == NULL) -+ break; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ -+ if ((entry == NULL) || (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p))))) { -+ return p; -+ } -+ } -+ } -+ return p; -+} -+ -+static int -+_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -+{ -+ int rc = BCME_OK; -+ -+ if (action == eWLFC_MAC_ENTRY_ACTION_ADD) { -+ entry->occupied = 1; -+ entry->state = WLFC_STATE_OPEN; -+ entry->requested_credit = 0; -+ entry->interface_id = ifid; -+ entry->iftype = iftype; -+ entry->ac_bitmap = 0xff; /* update this when handling APSD */ -+ /* for an interface entry we may not care about the MAC address */ -+ if (ea != NULL) -+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); -+ pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); -+ } -+ else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) { -+ entry->occupied = 1; -+ entry->state = WLFC_STATE_OPEN; -+ entry->requested_credit = 0; -+ entry->interface_id = ifid; -+ entry->iftype = iftype; -+ entry->ac_bitmap = 0xff; /* update this when handling APSD */ -+ /* for an interface entry we may not care about the MAC address */ -+ if (ea != NULL) -+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); -+ } -+ else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) { -+ entry->occupied = 0; -+ entry->state = WLFC_STATE_CLOSE; -+ entry->requested_credit = 0; -+ /* enable after packets are queued-deqeued properly. -+ pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0); -+ */ -+ } -+ return rc; -+} -+ -+int -+_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac) -+{ -+ int lender_ac; -+ int rc = BCME_ERROR; -+ -+ if (ctx == NULL || available_credit_map == 0) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_BADARG; -+ } -+ -+ /* Borrow from lowest priority available AC (including BC/MC credits) */ -+ for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) { -+ if ((available_credit_map && (1 << lender_ac)) && -+ (ctx->FIFO_credit[lender_ac] > 0)) { -+ ctx->credits_borrowed[borrower_ac][lender_ac]++; -+ ctx->FIFO_credit[lender_ac]--; -+ rc = BCME_OK; -+ break; -+ } -+ } -+ -+ return rc; -+} -+ -+int -+dhd_wlfc_interface_entry_update(void* state, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -+{ -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ wlfc_mac_descriptor_t* entry; -+ -+ if (ifid >= WLFC_MAX_IFNUM) -+ return BCME_BADARG; -+ -+ entry = &ctx->destination_entries.interfaces[ifid]; -+ return _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea); -+} -+ -+int -+dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits) -+{ -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ -+ /* update the AC FIFO credit map */ -+ ctx->FIFO_credit[0] = credits[0]; -+ ctx->FIFO_credit[1] = credits[1]; -+ ctx->FIFO_credit[2] = credits[2]; -+ ctx->FIFO_credit[3] = credits[3]; -+ /* credit for bc/mc packets */ -+ ctx->FIFO_credit[4] = credits[4]; -+ /* credit for ATIM FIFO is not used yet. */ -+ ctx->FIFO_credit[5] = 0; -+ return BCME_OK; -+} -+ -+int -+dhd_wlfc_enque_sendq(void* state, int prec, void* p) -+{ -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ -+ if ((state == NULL) || -+ /* prec = AC_COUNT is used for bc/mc queue */ -+ (prec > AC_COUNT) || -+ (p == NULL)) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_BADARG; -+ } -+ if (FALSE == dhd_prec_enq(ctx->dhdp, &ctx->SENDQ, p, prec)) { -+ ctx->stats.sendq_full_error++; -+ /* -+ AP6210_DEBUG("Error: %s():%d, qlen:%d\n", -+ __FUNCTION__, __LINE__, ctx->SENDQ.len); -+ */ -+ WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, prec); -+ AP6210_DEBUG("Q"); -+ PKTFREE(ctx->osh, p, TRUE); -+ return BCME_ERROR; -+ } -+ ctx->stats.pktin++; -+ /* _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p))); */ -+ return BCME_OK; -+} -+ -+int -+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac, -+ dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx) -+{ -+ uint32 hslot; -+ int rc; -+ -+ /* -+ if ac_fifo_credit_spent = 0 -+ -+ This packet will not count against the FIFO credit. -+ To ensure the txstatus corresponding to this packet -+ does not provide an implied credit (default behavior) -+ mark the packet accordingly. -+ -+ if ac_fifo_credit_spent = 1 -+ -+ This is a normal packet and it counts against the FIFO -+ credit count. -+ */ -+ DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent); -+ rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p, -+ commit_info->needs_hdr, &hslot); -+ -+ if (rc == BCME_OK) -+ rc = fcommit(commit_ctx, commit_info->p, TRUE); -+ else -+ ctx->stats.generic_error++; -+ -+ if (rc == BCME_OK) { -+ ctx->stats.pkt2bus++; -+ if (commit_info->ac_fifo_credit_spent) { -+ ctx->stats.sendq_pkts[ac]++; -+ WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); -+ } -+ } else if (rc == BCME_NORESOURCE) -+ rc = BCME_ERROR; -+ else { -+ /* -+ bus commit has failed, rollback. -+ - remove wl-header for a delayed packet -+ - save wl-header header for suppressed packets -+ */ -+ rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p, -+ (commit_info->pkt_type), hslot); -+ if (rc != BCME_OK) -+ ctx->stats.rollback_failed++; -+ -+ rc = BCME_ERROR; -+ } -+ -+ return rc; -+} -+ -+int -+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx) -+{ -+ int ac; -+ int credit; -+ int rc; -+ dhd_wlfc_commit_info_t commit_info; -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ int credit_count = 0; -+ int bus_retry_count = 0; -+ uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */ -+ -+ if ((state == NULL) || -+ (fcommit == NULL)) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_BADARG; -+ } -+ -+ memset(&commit_info, 0, sizeof(commit_info)); -+ -+ /* -+ Commit packets for regular AC traffic. Higher priority first. -+ First, use up FIFO credits available to each AC. Based on distribution -+ and credits left, borrow from other ACs as applicable -+ -+ -NOTE: -+ If the bus between the host and firmware is overwhelmed by the -+ traffic from host, it is possible that higher priority traffic -+ starves the lower priority queue. If that occurs often, we may -+ have to employ weighted round-robin or ucode scheme to avoid -+ low priority packet starvation. -+ */ -+ -+ for (ac = AC_COUNT; ac >= 0; ac--) { -+ -+ int initial_credit_count = ctx->FIFO_credit[ac]; -+ -+ /* packets from SENDQ are fresh and they'd need header and have no MAC entry */ -+ commit_info.needs_hdr = 1; -+ commit_info.mac_entry = NULL; -+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW; -+ -+ do { -+ commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac); -+ if (commit_info.p == NULL) -+ break; -+ else if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(commit_info.p)))) { -+ ASSERT(ac == AC_COUNT); -+ -+ if (ctx->FIFO_credit[ac]) { -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ (void) _dhd_wlfc_borrow_credit(ctx, -+ ac_available, ac); -+ credit_count--; -+ } -+ } else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR(" %s: bus error\n", -+ __FUNCTION__); -+ return rc; -+ } -+ } -+ } -+ } -+ -+ } while (commit_info.p); -+ -+ for (credit = 0; credit < ctx->FIFO_credit[ac];) { -+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, -+ &(commit_info.ac_fifo_credit_spent), -+ &(commit_info.needs_hdr), -+ &(commit_info.mac_entry)); -+ -+ if (commit_info.p == NULL) -+ break; -+ -+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : -+ eWLFC_PKTTYPE_SUPPRESSED; -+ -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ credit++; -+ } -+ } -+ else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR("dhd_wlfc_commit_packets(): bus error\n"); -+ ctx->FIFO_credit[ac] -= credit; -+ return rc; -+ } -+ } -+ } -+ -+ ctx->FIFO_credit[ac] -= credit; -+ -+ -+ /* If no credits were used, the queue is idle and can be re-used -+ Note that resv credits cannot be borrowed -+ */ -+ if (initial_credit_count == ctx->FIFO_credit[ac]) { -+ ac_available |= (1 << ac); -+ credit_count += ctx->FIFO_credit[ac]; -+ } -+ } -+ -+ /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD -+ -+ Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to: -+ a) ignore BC/MC for deferring borrow -+ b) ignore AC_BE being available along with other ACs -+ (this should happen only for pure BC/MC traffic) -+ -+ i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and -+ we do not care if AC_BE and BC/MC are available or not -+ */ -+ if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) { -+ -+ if (ctx->allow_credit_borrow) { -+ ac = 1; /* Set ac to AC_BE and borrow credits */ -+ } -+ else { -+ int delta; -+ int curr_t = OSL_SYSUPTIME(); -+ -+ if (curr_t > ctx->borrow_defer_timestamp) -+ delta = curr_t - ctx->borrow_defer_timestamp; -+ else -+ delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp; -+ -+ if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) { -+ /* Reset borrow but defer to next iteration (defensive borrowing) */ -+ ctx->allow_credit_borrow = TRUE; -+ ctx->borrow_defer_timestamp = 0; -+ } -+ return BCME_OK; -+ } -+ } -+ else { -+ /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */ -+ ctx->allow_credit_borrow = FALSE; -+ ctx->borrow_defer_timestamp = OSL_SYSUPTIME(); -+ return BCME_OK; -+ } -+ -+ /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE) -+ Generically use "ac" only in case we extend to all ACs in future -+ */ -+ for (; (credit_count > 0);) { -+ -+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, -+ &(commit_info.ac_fifo_credit_spent), -+ &(commit_info.needs_hdr), -+ &(commit_info.mac_entry)); -+ if (commit_info.p == NULL) -+ break; -+ -+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : -+ eWLFC_PKTTYPE_SUPPRESSED; -+ -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); -+ credit_count--; -+ } -+ } -+ else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR("dhd_wlfc_commit_packets(): bus error\n"); -+ return rc; -+ } -+ } -+ } -+ -+ return BCME_OK; -+} -+ -+static uint8 -+dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea) -+{ -+ wlfc_mac_descriptor_t* table = -+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes; -+ uint8 table_index; -+ -+ if (ea != NULL) { -+ for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) { -+ if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) && -+ table[table_index].occupied) -+ return table_index; -+ } -+ } -+ return WLFC_MAC_DESC_ID_INVALID; -+} -+ -+void -+dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wake_locked) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ void* p; -+ int fifo_id; -+ -+ if (!wake_locked) -+ dhd_os_wlfc_block(dhd); -+ -+ if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { -+#ifdef PROP_TXSTATUS_DEBUG -+ wlfc->stats.signal_only_pkts_freed++; -+#endif -+ if (success) -+ /* is this a signal-only packet? */ -+ PKTFREE(wlfc->osh, txp, TRUE); -+ if (!wake_locked) -+ dhd_os_wlfc_unblock(dhd); -+ return; -+ } -+ if (!success) { -+ AP6210_DEBUG("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n", -+ __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp))); -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG -+ (PKTTAG(txp))), &p, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, txp, FALSE); -+ -+ /* return the credit, if necessary */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) { -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp)); -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ -+ PKTFREE(wlfc->osh, txp, TRUE); -+ } -+ if (!wake_locked) -+ dhd_os_wlfc_unblock(dhd); -+ return; -+} -+ -+static int -+dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len) -+{ -+ uint8 status_flag; -+ uint32 status; -+ int ret; -+ int remove_from_hanger = 1; -+ void* pktbuf; -+ uint8 fifo_id; -+ uint8 count = 0; -+ uint32 status_g; -+ uint32 hslot, hcnt; -+ wlfc_mac_descriptor_t* entry = NULL; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ memcpy(&status, pkt_info, sizeof(uint32)); -+ status_flag = WL_TXSTATUS_GET_FLAGS(status); -+ status_g = status & 0xff000000; -+ hslot = (status & 0x00ffff00) >> 8; -+ hcnt = status & 0xff; -+ len = pkt_info[4]; -+ -+ wlfc->stats.txstatus_in++; -+ -+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { -+ wlfc->stats.pkt_freed++; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { -+ wlfc->stats.d11_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { -+ wlfc->stats.wl_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { -+ wlfc->stats.wlc_tossed_pkts++; -+ } -+ while (count < len) { -+ status = (status_g << 24) | (hslot << 8) | (hcnt); -+ count++; -+ hslot++; -+ hcnt++; -+ -+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); -+ if (ret != BCME_OK) { -+ /* do something */ -+ continue; -+ } -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ -+ if (!remove_from_hanger) { -+ /* this packet was suppressed */ -+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { -+ entry->suppressed = TRUE; -+ entry->suppress_count = pktq_mlen(&entry->psq, -+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); -+ entry->suppr_transit_count = entry->transit_count; -+ } -+ entry->generation = WLFC_PKTID_GEN(status); -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ uint32 new_t = OSL_SYSUPTIME(); -+ uint32 old_t; -+ uint32 delta; -+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ -+ WLFC_PKTID_HSLOT_GET(status)].push_time; -+ -+ -+ wlfc->stats.latency_sample_count++; -+ if (new_t > old_t) -+ delta = new_t - old_t; -+ else -+ delta = 0xffffffff + new_t - old_t; -+ wlfc->stats.total_status_latency += delta; -+ wlfc->stats.latency_most_recent = delta; -+ -+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; -+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) -+ wlfc->stats.idx_delta = 0; -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); -+ -+ /* pick up the implicit credit from this packet */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { -+ -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ } -+ else { -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the destination entry (for pspoll etc.) -+ */ -+ if (!entry) { -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ } -+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) -+ entry->requested_credit++; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_acks++; -+#endif -+ } -+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || -+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { -+ -+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); -+ if (ret != BCME_OK) { -+ /* delay q is full, drop this packet */ -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), -+ &pktbuf, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, pktbuf, FALSE); -+ entry->transit_count--; -+ /* packet is transmitted Successfully by dongle -+ * after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } else { -+ /* Mark suppressed to avoid a double free during wlfc cleanup */ -+ -+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); -+ entry->suppress_count++; -+ } -+ } -+ else { -+ dhd_txcomplete(dhd, pktbuf, TRUE); -+ entry->transit_count--; -+ -+ /* This packet is transmitted Successfully by dongle -+ * even after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ /* free the packet */ -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } -+ } -+ return BCME_OK; -+} -+ -+/* Handle discard or suppress indication */ -+static int -+dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info) -+{ -+ uint8 status_flag; -+ uint32 status; -+ int ret; -+ int remove_from_hanger = 1; -+ void* pktbuf; -+ uint8 fifo_id; -+ wlfc_mac_descriptor_t* entry = NULL; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ memcpy(&status, pkt_info, sizeof(uint32)); -+ status_flag = WL_TXSTATUS_GET_FLAGS(status); -+ wlfc->stats.txstatus_in++; -+ -+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { -+ wlfc->stats.pkt_freed++; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { -+ wlfc->stats.d11_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { -+ wlfc->stats.wl_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { -+ wlfc->stats.wlc_tossed_pkts++; -+ } -+ -+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); -+ if (ret != BCME_OK) { -+ /* do something */ -+ return ret; -+ } -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ -+ if (!remove_from_hanger) { -+ /* this packet was suppressed */ -+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { -+ entry->suppressed = TRUE; -+ entry->suppress_count = pktq_mlen(&entry->psq, -+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); -+ entry->suppr_transit_count = entry->transit_count; -+ } -+ entry->generation = WLFC_PKTID_GEN(status); -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ uint32 new_t = OSL_SYSUPTIME(); -+ uint32 old_t; -+ uint32 delta; -+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ -+ WLFC_PKTID_HSLOT_GET(status)].push_time; -+ -+ -+ wlfc->stats.latency_sample_count++; -+ if (new_t > old_t) -+ delta = new_t - old_t; -+ else -+ delta = 0xffffffff + new_t - old_t; -+ wlfc->stats.total_status_latency += delta; -+ wlfc->stats.latency_most_recent = delta; -+ -+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; -+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) -+ wlfc->stats.idx_delta = 0; -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); -+ -+ /* pick up the implicit credit from this packet */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { -+ -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ } -+ else { -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the destination entry (for pspoll etc.) -+ */ -+ if (!entry) { -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ } -+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) -+ entry->requested_credit++; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_acks++; -+#endif -+ } -+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || -+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { -+ -+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); -+ if (ret != BCME_OK) { -+ /* delay q is full, drop this packet */ -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), -+ &pktbuf, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, pktbuf, FALSE); -+ entry->transit_count--; -+ /* This packet is transmitted Successfully by -+ * dongle even after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } else { -+ /* Mark suppressed to avoid a double free during wlfc cleanup */ -+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); -+ entry->suppress_count++; -+ } -+ } -+ else { -+ dhd_txcomplete(dhd, pktbuf, TRUE); -+ entry->transit_count--; -+ -+ /* This packet is transmitted Successfully by dongle even after first suppress. */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ /* free the packet */ -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits) -+{ -+ int i; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { -+#ifdef PROP_TXSTATUS_DEBUG -+ wlfc->stats.fifo_credits_back[i] += credits[i]; -+#endif -+ /* update FIFO credits */ -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) -+ { -+ int lender; /* Note that borrower is i */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) { -+ if (wlfc->credits_borrowed[i][lender] > 0) { -+ if (credits[i] >= wlfc->credits_borrowed[i][lender]) { -+ credits[i] -= wlfc->credits_borrowed[i][lender]; -+ wlfc->FIFO_credit[lender] += -+ wlfc->credits_borrowed[i][lender]; -+ wlfc->credits_borrowed[i][lender] = 0; -+ } -+ else { -+ wlfc->credits_borrowed[i][lender] -= credits[i]; -+ wlfc->FIFO_credit[lender] += credits[i]; -+ credits[i] = 0; -+ } -+ } -+ } -+ -+ /* If we have more credits left over, these must belong to the AC */ -+ if (credits[i] > 0) { -+ wlfc->FIFO_credit[i] += credits[i]; -+ } -+ } -+ } -+ -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value) -+{ -+ uint32 timestamp; -+ -+ (void)dhd; -+ -+ bcopy(&value[2], ×tamp, sizeof(uint32)); -+ AP6210_DEBUG("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp); -+ return BCME_OK; -+} -+ -+ -+static int -+dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi) -+{ -+ (void)dhd; -+ (void)rssi; -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ int rc; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ uint8 existing_index; -+ uint8 table_index; -+ uint8 ifid; -+ uint8* ea; -+ -+ AP6210_DEBUG("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", -+ __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], -+ ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), -+ WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]); -+ -+ table = wlfc->destination_entries.nodes; -+ table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]); -+ ifid = value[1]; -+ ea = &value[2]; -+ -+ if (type == WLFC_CTL_TYPE_MACDESC_ADD) { -+ existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]); -+ if (existing_index == WLFC_MAC_DESC_ID_INVALID) { -+ /* this MAC entry does not exist, create one */ -+ if (!table[table_index].occupied) { -+ table[table_index].mac_handle = value[0]; -+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], -+ eWLFC_MAC_ENTRY_ACTION_ADD, ifid, -+ wlfc->destination_entries.interfaces[ifid].iftype, -+ ea); -+ } -+ else { -+ /* the space should have been empty, but it's not */ -+ wlfc->stats.mac_update_failed++; -+ } -+ } -+ else { -+ /* -+ there is an existing entry, move it to new index -+ if necessary. -+ */ -+ if (existing_index != table_index) { -+ /* if we already have an entry, free the old one */ -+ table[existing_index].occupied = 0; -+ table[existing_index].state = WLFC_STATE_CLOSE; -+ table[existing_index].requested_credit = 0; -+ table[existing_index].interface_id = 0; -+ /* enable after packets are queued-deqeued properly. -+ pktq_flush(dhd->osh, &table[existing_index].psq, FALSE, NULL, 0); -+ */ -+ } -+ } -+ } -+ if (type == WLFC_CTL_TYPE_MACDESC_DEL) { -+ if (table[table_index].occupied) { -+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], -+ eWLFC_MAC_ENTRY_ACTION_DEL, ifid, -+ wlfc->destination_entries.interfaces[ifid].iftype, -+ ea); -+ } -+ else { -+ /* the space should have been occupied, but it's not */ -+ wlfc->stats.mac_update_failed++; -+ } -+ } -+ BCM_REFERENCE(rc); -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ /* Handle PS on/off indication */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle = value[0]; -+ int i; -+ -+ table = wlfc->destination_entries.nodes; -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ /* a fresh PS mode should wipe old ps credits? */ -+ desc->requested_credit = 0; -+ if (type == WLFC_CTL_TYPE_MAC_OPEN) { -+ desc->state = WLFC_STATE_OPEN; -+ DHD_WLFC_CTRINC_MAC_OPEN(desc); -+ } -+ else { -+ desc->state = WLFC_STATE_CLOSE; -+ DHD_WLFC_CTRINC_MAC_CLOSE(desc); -+ /* -+ Indicate to firmware if there is any traffic pending. -+ */ -+ for (i = AC_BE; i < AC_COUNT; i++) { -+ _dhd_wlfc_traffic_pending_check(wlfc, desc, i); -+ } -+ } -+ } -+ else { -+ wlfc->stats.psmode_update_failed++; -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ /* Handle PS on/off indication */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ uint8 if_id = value[0]; -+ -+ if (if_id < WLFC_MAX_IFNUM) { -+ table = wlfc->destination_entries.interfaces; -+ if (table[if_id].occupied) { -+ if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) { -+ table[if_id].state = WLFC_STATE_OPEN; -+ /* AP6210_DEBUG("INTERFACE[%d] OPEN\n", if_id); */ -+ } -+ else { -+ table[if_id].state = WLFC_STATE_CLOSE; -+ /* AP6210_DEBUG("INTERFACE[%d] CLOSE\n", if_id); */ -+ } -+ return BCME_OK; -+ } -+ } -+ wlfc->stats.interface_update_failed++; -+ -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle; -+ uint8 credit; -+ -+ table = wlfc->destination_entries.nodes; -+ mac_handle = value[1]; -+ credit = value[0]; -+ -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ desc->requested_credit = credit; -+ -+ desc->ac_bitmap = value[2]; -+ } -+ else { -+ wlfc->stats.credit_request_failed++; -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle; -+ uint8 packet_count; -+ -+ table = wlfc->destination_entries.nodes; -+ mac_handle = value[1]; -+ packet_count = value[0]; -+ -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ desc->requested_packet = packet_count; -+ -+ desc->ac_bitmap = value[2]; -+ } -+ else { -+ wlfc->stats.packet_request_failed++; -+ } -+ return BCME_OK; -+} -+ -+static void -+dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len) -+{ -+ if (info_len) { -+ if (info_buf) { -+ bcopy(val, info_buf, len); -+ *info_len = len; -+ } -+ else -+ *info_len = 0; -+ } -+} -+ -+static int -+dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf, -+ uint *reorder_info_len) -+{ -+ uint8 type, len; -+ uint8* value; -+ uint8* tmpbuf; -+ uint16 remainder = tlv_hdr_len; -+ uint16 processed = 0; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf); -+ if (remainder) { -+ while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) { -+ type = tmpbuf[processed]; -+ if (type == WLFC_CTL_TYPE_FILLER) { -+ remainder -= 1; -+ processed += 1; -+ continue; -+ } -+ -+ len = tmpbuf[processed + 1]; -+ value = &tmpbuf[processed + 2]; -+ -+ if (remainder < (2 + len)) -+ break; -+ -+ remainder -= 2 + len; -+ processed += 2 + len; -+ if (type == WLFC_CTL_TYPE_TXSTATUS) -+ dhd_wlfc_txstatus_update(dhd, value); -+ if (type == WLFC_CTL_TYPE_COMP_TXSTATUS) -+ dhd_wlfc_compressed_txstatus_update(dhd, value, len); -+ -+ else if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS) -+ dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf, -+ reorder_info_len); -+ else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK) -+ dhd_wlfc_fifocreditback_indicate(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_RSSI) -+ dhd_wlfc_rssi_indicate(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) -+ dhd_wlfc_credit_request(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) -+ dhd_wlfc_packet_request(dhd, value); -+ -+ else if ((type == WLFC_CTL_TYPE_MAC_OPEN) || -+ (type == WLFC_CTL_TYPE_MAC_CLOSE)) -+ dhd_wlfc_psmode_update(dhd, value, type); -+ -+ else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) || -+ (type == WLFC_CTL_TYPE_MACDESC_DEL)) -+ dhd_wlfc_mac_table_update(dhd, value, type); -+ -+ else if (type == WLFC_CTL_TYPE_TRANS_ID) -+ dhd_wlfc_dbg_senum_check(dhd, value); -+ -+ else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) || -+ (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) { -+ dhd_wlfc_interface_update(dhd, value, type); -+ } -+ } -+ if (remainder != 0) { -+ /* trouble..., something is not right */ -+ wlfc->stats.tlv_parse_failed++; -+ } -+ } -+ return BCME_OK; -+} -+ -+int -+dhd_wlfc_init(dhd_pub_t *dhd) -+{ -+ char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */ -+ /* enable all signals & indicate host proptxstatus logic is active */ -+ uint32 tlv = dhd->wlfc_enabled? -+ WLFC_FLAGS_RSSI_SIGNALS | -+ WLFC_FLAGS_XONXOFF_SIGNALS | -+ WLFC_FLAGS_CREDIT_STATUS_SIGNALS | -+ WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | -+ WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; -+ /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */ -+ -+ -+ /* -+ try to enable/disable signaling by sending "tlv" iovar. if that fails, -+ fallback to no flow control? Print a message for now. -+ */ -+ -+ /* enable proptxtstatus signaling by default */ -+ bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf)); -+ if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { -+ AP6210_ERR("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n"); -+ } -+ else { -+ /* -+ Leaving the message for now, it should be removed after a while; once -+ the tlv situation is stable. -+ */ -+ AP6210_DEBUG("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n", -+ dhd->wlfc_enabled?"enabled":"disabled", tlv); -+ } -+ return BCME_OK; -+} -+ -+int -+dhd_wlfc_enable(dhd_pub_t *dhd) -+{ -+ int i; -+ athost_wl_status_info_t* wlfc; -+ -+ AP6210_DEBUG("Enter %s\n", __FUNCTION__); -+ -+ if (!dhd->wlfc_enabled || dhd->wlfc_state) -+ return BCME_OK; -+ -+ /* allocate space to track txstatus propagated from firmware */ -+ dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t)); -+ if (dhd->wlfc_state == NULL) -+ return BCME_NOMEM; -+ -+ /* initialize state space */ -+ wlfc = (athost_wl_status_info_t*)dhd->wlfc_state; -+ memset(wlfc, 0, sizeof(athost_wl_status_info_t)); -+ -+ /* remember osh & dhdp */ -+ wlfc->osh = dhd->osh; -+ wlfc->dhdp = dhd; -+ -+ wlfc->hanger = -+ dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS); -+ if (wlfc->hanger == NULL) { -+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); -+ dhd->wlfc_state = NULL; -+ return BCME_NOMEM; -+ } -+ -+ /* initialize all interfaces to accept traffic */ -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ wlfc->hostif_flow_state[i] = OFF; -+ } -+ -+ /* -+ create the SENDQ containing -+ sub-queues for all AC precedences + 1 for bc/mc traffic -+ */ -+ pktq_init(&wlfc->SENDQ, (AC_COUNT + 1), WLFC_SENDQ_LEN); -+ -+ wlfc->destination_entries.other.state = WLFC_STATE_OPEN; -+ /* bc/mc FIFO is always open [credit aside], i.e. b[5] */ -+ wlfc->destination_entries.other.ac_bitmap = 0x1f; -+ wlfc->destination_entries.other.interface_id = 0; -+ -+ wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT; -+ -+ wlfc->allow_credit_borrow = TRUE; -+ wlfc->borrow_defer_timestamp = 0; -+ -+ return BCME_OK; -+} -+ -+/* release all packet resources */ -+void -+dhd_wlfc_cleanup(dhd_pub_t *dhd) -+{ -+ int i; -+ int total_entries; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_hanger_t* h; -+ int prec; -+ void *pkt = NULL; -+ struct pktq *txq = NULL; -+ -+ AP6210_DEBUG("Enter %s\n", __FUNCTION__); -+ if (dhd->wlfc_state == NULL) -+ return; -+ /* flush bus->txq */ -+ txq = dhd_bus_txq(dhd->bus); -+ -+ /* any in the hanger? */ -+ h = (wlfc_hanger_t*)wlfc->hanger; -+ total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); -+ /* search all entries, include nodes as well as interfaces */ -+ table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries; -+ -+ for (i = 0; i < total_entries; i++) { -+ if (table[i].occupied) { -+ if (table[i].psq.len) { -+ AP6210_DEBUG("%s(): DELAYQ[%d].len = %d\n", -+ __FUNCTION__, i, table[i].psq.len); -+ /* release packets held in DELAYQ */ -+ pktq_flush(wlfc->osh, &table[i].psq, TRUE, NULL, 0); -+ } -+ table[i].occupied = 0; -+ } -+ } -+ /* release packets held in SENDQ */ -+ if (wlfc->SENDQ.len) -+ pktq_flush(wlfc->osh, &wlfc->SENDQ, TRUE, NULL, 0); -+ for (prec = 0; prec < txq->num_prec; prec++) { -+ pkt = pktq_pdeq(txq, prec); -+ while (pkt) { -+ for (i = 0; i < h->max_items; i++) { -+ if (pkt == h->items[i].pkt) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ h->items[i].pkt = NULL; -+ h->items[i].identifier = 0; -+ } else if (h->items[i].state == -+ WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { -+ /* These are already freed from the psq */ -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ break; -+ } -+ } -+ pkt = pktq_pdeq(txq, prec); -+ } -+ } -+ /* flush remained pkt in hanger queue, not in bus->txq */ -+ for (i = 0; i < h->max_items; i++) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { -+ /* These are freed from the psq so no need to free again */ -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ } -+ -+ return; -+} -+ -+void -+dhd_wlfc_deinit(dhd_pub_t *dhd) -+{ -+ /* cleanup all psq related resources */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ AP6210_DEBUG("Enter %s\n", __FUNCTION__); -+ -+ dhd_os_wlfc_block(dhd); -+ if (dhd->wlfc_state == NULL) { -+ dhd_os_wlfc_unblock(dhd); -+ return; -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ int i; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger; -+ for (i = 0; i < h->max_items; i++) { -+ if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) { -+ AP6210_DEBUG("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n", -+ __FUNCTION__, i, h->items[i].pkt, -+ DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt))); -+ } -+ } -+ } -+#endif -+ /* delete hanger */ -+ dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger); -+ -+ /* free top structure */ -+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); -+ dhd->wlfc_state = NULL; -+ dhd_os_wlfc_unblock(dhd); -+ -+ return; -+} -+#endif /* PROP_TXSTATUS */ -+ -+void -+dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -+{ -+ bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -+#ifdef PROP_TXSTATUS -+ dhd_os_wlfc_block(dhdp); -+ if (dhdp->wlfc_state) -+ dhd_wlfc_dump(dhdp, strbuf); -+ dhd_os_wlfc_unblock(dhdp); -+#endif -+} -+ -+void -+dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) -+{ -+#ifdef BDC -+ struct bdc_header *h; -+#endif /* BDC */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+#ifdef BDC -+ /* Push BDC header used to convey priority for buses that don't */ -+ -+ PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN); -+ -+ h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); -+ -+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); -+ if (PKTSUMNEEDED(pktbuf)) -+ h->flags |= BDC_FLAG_SUM_NEEDED; -+ -+ -+ h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); -+ h->flags2 = 0; -+ h->dataOffset = 0; -+#endif /* BDC */ -+ BDC_SET_IF_IDX(h, ifidx); -+} -+ -+int -+dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info, -+ uint *reorder_info_len) -+{ -+#ifdef BDC -+ struct bdc_header *h; -+#endif -+ uint8 data_offset = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+#ifdef BDC -+ if (reorder_info_len) -+ *reorder_info_len = 0; -+ /* Pop BDC header used to convey priority for buses that don't */ -+ -+ if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { -+ AP6210_ERR("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN); -+ return BCME_ERROR; -+ } -+ -+ h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); -+ -+#if defined(NDIS630) -+ h->dataOffset = 0; -+#endif -+ -+ if (!ifidx) { -+ /* for tx packet, skip the analysis */ -+ data_offset = h->dataOffset; -+ PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -+ goto exit; -+ } -+ -+ if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { -+ AP6210_ERR("%s: rx data ifnum out of range (%d)\n", -+ __FUNCTION__, *ifidx); -+ return BCME_ERROR; -+ } -+ -+ if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { -+ AP6210_ERR("%s: non-BDC packet received, flags = 0x%x\n", -+ dhd_ifname(dhd, *ifidx), h->flags); -+ if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1) -+ h->dataOffset = 0; -+ else -+ return BCME_ERROR; -+ } -+ -+ if (h->flags & BDC_FLAG_SUM_GOOD) { -+ AP6210_DEBUG("%s: BDC packet received with good rx-csum, flags 0x%x\n", -+ dhd_ifname(dhd, *ifidx), h->flags); -+ PKTSETSUMGOOD(pktbuf, TRUE); -+ } -+ -+ PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); -+ data_offset = h->dataOffset; -+ PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -+#endif /* BDC */ -+ -+#if !defined(NDIS630) -+ if (PKTLEN(dhd->osh, pktbuf) < (uint32) (data_offset << 2)) { -+ AP6210_ERR("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(dhd->osh, pktbuf), (data_offset * 4)); -+ return BCME_ERROR; -+ } -+#endif -+#ifdef PROP_TXSTATUS -+ if (dhd->wlfc_state && -+ ((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode -+ != WLFC_FCMODE_NONE && -+ (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf)))) { -+ /* -+ - parse txstatus only for packets that came from the firmware -+ */ -+ dhd_os_wlfc_block(dhd); -+ dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2), -+ reorder_buf_info, reorder_info_len); -+ ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++; -+ dhd_os_wlfc_unblock(dhd); -+ } -+#endif /* PROP_TXSTATUS */ -+ -+exit: -+#if !defined(NDIS630) -+ PKTPULL(dhd->osh, pktbuf, (data_offset << 2)); -+#endif -+ return 0; -+} -+ -+#if defined(PROP_TXSTATUS) -+void -+dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd) -+{ -+ if (dhd->wlfc_state && -+ (((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode -+ != WLFC_FCMODE_NONE)) { -+ dhd_os_wlfc_block(dhd); -+ dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, -+ (void *)dhd->bus); -+ dhd_os_wlfc_unblock(dhd); -+ } -+} -+#endif -+ -+int -+dhd_prot_attach(dhd_pub_t *dhd) -+{ -+ dhd_prot_t *cdc; -+ -+ if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd->osh, DHD_PREALLOC_PROT, -+ sizeof(dhd_prot_t)))) { -+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__); -+ goto fail; -+ } -+ memset(cdc, 0, sizeof(dhd_prot_t)); -+ -+ /* ensure that the msg buf directly follows the cdc msg struct */ -+ if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { -+ AP6210_ERR("dhd_prot_t is not correctly defined\n"); -+ goto fail; -+ } -+ -+ dhd->prot = cdc; -+#ifdef BDC -+ dhd->hdrlen += BDC_HEADER_LEN; -+#endif -+ dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; -+ return 0; -+ -+fail: -+#ifndef CONFIG_DHD_USE_STATIC_BUF -+ if (cdc != NULL) -+ MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ return BCME_NOMEM; -+} -+ -+/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -+void -+dhd_prot_detach(dhd_pub_t *dhd) -+{ -+#ifdef PROP_TXSTATUS -+ dhd_wlfc_deinit(dhd); -+#endif -+#ifndef CONFIG_DHD_USE_STATIC_BUF -+ MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ dhd->prot = NULL; -+} -+ -+void -+dhd_prot_dstats(dhd_pub_t *dhd) -+{ -+ /* No stats from dongle added yet, copy bus stats */ -+ dhd->dstats.tx_packets = dhd->tx_packets; -+ dhd->dstats.tx_errors = dhd->tx_errors; -+ dhd->dstats.rx_packets = dhd->rx_packets; -+ dhd->dstats.rx_errors = dhd->rx_errors; -+ dhd->dstats.rx_dropped = dhd->rx_dropped; -+ dhd->dstats.multicast = dhd->rx_multicast; -+ return; -+} -+ -+int -+dhd_prot_init(dhd_pub_t *dhd) -+{ -+ int ret = 0; -+ wlc_rev_info_t revinfo; -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ -+ /* Get the device rev info */ -+ memset(&revinfo, 0, sizeof(revinfo)); -+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0); -+ if (ret < 0) -+ goto done; -+ -+ -+#if defined(WL_CFG80211) -+ if (dhd_download_fw_on_driverload) -+#endif /* defined(WL_CFG80211) */ -+ ret = dhd_preinit_ioctls(dhd); -+ -+#ifdef PROP_TXSTATUS -+ ret = dhd_wlfc_init(dhd); -+#endif -+ -+ /* Always assumes wl for now */ -+ dhd->iswl = TRUE; -+ -+done: -+ return ret; -+} -+ -+void -+dhd_prot_stop(dhd_pub_t *dhd) -+{ -+ /* Nothing to do for CDC */ -+} -+ -+ -+static void -+dhd_get_hostreorder_pkts(void *osh, struct reorder_info *ptr, void **pkt, -+ uint32 *pkt_count, void **pplast, uint8 start, uint8 end) -+{ -+ uint i; -+ void *plast = NULL, *p; -+ uint32 pkt_cnt = 0; -+ -+ if (ptr->pend_pkts == 0) { -+ AP6210_DEBUG("%s: no packets in reorder queue \n", __FUNCTION__); -+ *pplast = NULL; -+ *pkt_count = 0; -+ *pkt = NULL; -+ return; -+ } -+ if (start == end) -+ i = ptr->max_idx + 1; -+ else { -+ if (start > end) -+ i = ((ptr->max_idx + 1) - start) + end; -+ else -+ i = end - start; -+ } -+ while (i) { -+ p = (void *)(ptr->p[start]); -+ ptr->p[start] = NULL; -+ -+ if (p != NULL) { -+ if (plast == NULL) -+ *pkt = p; -+ else -+ PKTSETNEXT(osh, plast, p); -+ -+ plast = p; -+ pkt_cnt++; -+ } -+ i--; -+ if (start++ == ptr->max_idx) -+ start = 0; -+ } -+ *pplast = plast; -+ *pkt_count = (uint32)pkt_cnt; -+} -+ -+int -+dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len, -+ void **pkt, uint32 *pkt_count) -+{ -+ uint8 flow_id, max_idx, cur_idx, exp_idx; -+ struct reorder_info *ptr; -+ uint8 flags; -+ void *cur_pkt, *plast = NULL; -+ uint32 cnt = 0; -+ -+ if (pkt == NULL) { -+ if (pkt_count != NULL) -+ *pkt_count = 0; -+ return 0; -+ } -+ -+ flow_id = reorder_info_buf[WLHOST_REORDERDATA_FLOWID_OFFSET]; -+ flags = reorder_info_buf[WLHOST_REORDERDATA_FLAGS_OFFSET]; -+ -+ AP6210_DEBUG("flow_id %d, flags 0x%02x, idx(%d, %d, %d)\n", flow_id, flags, -+ reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET], -+ reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET], -+ reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]); -+ -+ /* validate flags and flow id */ -+ if (flags == 0xFF) { -+ AP6210_ERR("%s: invalid flags...so ignore this packet\n", __FUNCTION__); -+ *pkt_count = 1; -+ return 0; -+ } -+ -+ cur_pkt = *pkt; -+ *pkt = NULL; -+ -+ ptr = dhd->reorder_bufs[flow_id]; -+ if (flags & WLHOST_REORDERDATA_DEL_FLOW) { -+ uint32 buf_size = sizeof(struct reorder_info); -+ -+ AP6210_DEBUG("%s: Flags indicating to delete a flow id %d\n", -+ __FUNCTION__, flow_id); -+ -+ if (ptr == NULL) { -+ AP6210_ERR("%s: received flags to cleanup, but no flow (%d) yet\n", -+ __FUNCTION__, flow_id); -+ *pkt_count = 1; -+ *pkt = cur_pkt; -+ return 0; -+ } -+ -+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, -+ ptr->exp_idx, ptr->exp_idx); -+ /* set it to the last packet */ -+ if (plast) { -+ PKTSETNEXT(dhd->osh, plast, cur_pkt); -+ cnt++; -+ } -+ else { -+ if (cnt != 0) { -+ AP6210_ERR("%s: del flow: something fishy, pending packets %d\n", -+ __FUNCTION__, cnt); -+ } -+ *pkt = cur_pkt; -+ cnt = 1; -+ } -+ buf_size += ((ptr->max_idx + 1) * sizeof(void *)); -+ MFREE(dhd->osh, ptr, buf_size); -+ dhd->reorder_bufs[flow_id] = NULL; -+ *pkt_count = cnt; -+ return 0; -+ } -+ /* all the other cases depend on the existance of the reorder struct for that flow id */ -+ if (ptr == NULL) { -+ uint32 buf_size_alloc = sizeof(reorder_info_t); -+ max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]; -+ -+ buf_size_alloc += ((max_idx + 1) * sizeof(void*)); -+ /* allocate space to hold the buffers, index etc */ -+ -+ AP6210_DEBUG("%s: alloc buffer of size %d size, reorder info id %d, maxidx %d\n", -+ __FUNCTION__, buf_size_alloc, flow_id, max_idx); -+ ptr = (struct reorder_info *)MALLOC(dhd->osh, buf_size_alloc); -+ if (ptr == NULL) { -+ AP6210_ERR("%s: Malloc failed to alloc buffer\n", __FUNCTION__); -+ *pkt_count = 1; -+ return 0; -+ } -+ bzero(ptr, buf_size_alloc); -+ dhd->reorder_bufs[flow_id] = ptr; -+ ptr->p = (void *)(ptr+1); -+ ptr->max_idx = max_idx; -+ } -+ if (flags & WLHOST_REORDERDATA_NEW_HOLE) { -+ AP6210_DEBUG("%s: new hole, so cleanup pending buffers\n", __FUNCTION__); -+ if (ptr->pend_pkts) { -+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, -+ ptr->exp_idx, ptr->exp_idx); -+ ptr->pend_pkts = 0; -+ } -+ ptr->cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET]; -+ ptr->exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; -+ ptr->max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]; -+ ptr->p[ptr->cur_idx] = cur_pkt; -+ ptr->pend_pkts++; -+ *pkt_count = cnt; -+ } -+ else if (flags & WLHOST_REORDERDATA_CURIDX_VALID) { -+ cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET]; -+ exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; -+ -+ -+ if ((exp_idx == ptr->exp_idx) && (cur_idx != ptr->exp_idx)) { -+ /* still in the current hole */ -+ /* enqueue the current on the buffer chain */ -+ if (ptr->p[cur_idx] != NULL) { -+ AP6210_DEBUG("%s: HOLE: ERROR buffer pending..free it\n", -+ __FUNCTION__); -+ PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE); -+ ptr->p[cur_idx] = NULL; -+ } -+ ptr->p[cur_idx] = cur_pkt; -+ ptr->pend_pkts++; -+ ptr->cur_idx = cur_idx; -+ AP6210_DEBUG("%s: fill up a hole..pending packets is %d\n", -+ __FUNCTION__, ptr->pend_pkts); -+ *pkt_count = 0; -+ *pkt = NULL; -+ } -+ else if (ptr->exp_idx == cur_idx) { -+ /* got the right one ..flush from cur to exp and update exp */ -+ AP6210_DEBUG("%s: got the right one now, cur_idx is %d\n", -+ __FUNCTION__, cur_idx); -+ if (ptr->p[cur_idx] != NULL) { -+ AP6210_DEBUG("%s: Error buffer pending..free it\n", -+ __FUNCTION__); -+ PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE); -+ ptr->p[cur_idx] = NULL; -+ } -+ ptr->p[cur_idx] = cur_pkt; -+ ptr->pend_pkts++; -+ -+ ptr->cur_idx = cur_idx; -+ ptr->exp_idx = exp_idx; -+ -+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, -+ cur_idx, exp_idx); -+ ptr->pend_pkts -= (uint8)cnt; -+ *pkt_count = cnt; -+ AP6210_DEBUG("%s: freeing up buffers %d, still pending %d\n", -+ __FUNCTION__, cnt, ptr->pend_pkts); -+ } -+ else { -+ uint8 end_idx; -+ bool flush_current = FALSE; -+ /* both cur and exp are moved now .. */ -+ AP6210_DEBUG("%s:, flow %d, both moved, cur %d(%d), exp %d(%d)\n", -+ __FUNCTION__, flow_id, ptr->cur_idx, cur_idx, -+ ptr->exp_idx, exp_idx); -+ if (flags & WLHOST_REORDERDATA_FLUSH_ALL) -+ end_idx = ptr->exp_idx; -+ else -+ end_idx = exp_idx; -+ -+ /* flush pkts first */ -+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, -+ ptr->exp_idx, end_idx); -+ -+ if (cur_idx == ptr->max_idx) { -+ if (exp_idx == 0) -+ flush_current = TRUE; -+ } else { -+ if (exp_idx == cur_idx + 1) -+ flush_current = TRUE; -+ } -+ if (flush_current) { -+ if (plast) -+ PKTSETNEXT(dhd->osh, plast, cur_pkt); -+ else -+ *pkt = cur_pkt; -+ cnt++; -+ } -+ else { -+ ptr->p[cur_idx] = cur_pkt; -+ ptr->pend_pkts++; -+ } -+ ptr->exp_idx = exp_idx; -+ ptr->cur_idx = cur_idx; -+ *pkt_count = cnt; -+ } -+ } -+ else { -+ uint8 end_idx; -+ /* no real packet but update to exp_seq...that means explicit window move */ -+ exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; -+ -+ AP6210_DEBUG("%s: move the window, cur_idx is %d, exp is %d, new exp is %d\n", -+ __FUNCTION__, ptr->cur_idx, ptr->exp_idx, exp_idx); -+ if (flags & WLHOST_REORDERDATA_FLUSH_ALL) -+ end_idx = ptr->exp_idx; -+ else -+ end_idx = exp_idx; -+ -+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, ptr->exp_idx, end_idx); -+ ptr->pend_pkts -= (uint8)cnt; -+ if (plast) -+ PKTSETNEXT(dhd->osh, plast, cur_pkt); -+ else -+ *pkt = cur_pkt; -+ cnt++; -+ *pkt_count = cnt; -+ /* set the new expected idx */ -+ ptr->exp_idx = exp_idx; -+ } -+ return 0; -+} -diff --git a/drivers/net/wireless/ap6210/dhd_cfg80211.c b/drivers/net/wireless/ap6210/dhd_cfg80211.c -new file mode 100644 -index 0000000..8cb440e ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_cfg80211.c -@@ -0,0 +1,680 @@ -+/* -+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef PKT_FILTER_SUPPORT -+#include -+#include -+#endif -+ -+extern struct wl_priv *wlcfg_drv_priv; -+ -+#ifdef PKT_FILTER_SUPPORT -+extern uint dhd_pkt_filter_enable; -+extern uint dhd_master_mode; -+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -+#endif -+ -+static int dhd_dongle_up = FALSE; -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+static s32 wl_dongle_up(struct net_device *ndev, u32 up); -+ -+/** -+ * Function implementations -+ */ -+ -+s32 dhd_cfg80211_init(struct wl_priv *wl) -+{ -+ dhd_dongle_up = FALSE; -+ return 0; -+} -+ -+s32 dhd_cfg80211_deinit(struct wl_priv *wl) -+{ -+ dhd_dongle_up = FALSE; -+ return 0; -+} -+ -+s32 dhd_cfg80211_down(struct wl_priv *wl) -+{ -+ dhd_dongle_up = FALSE; -+ return 0; -+} -+ -+s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val) -+{ -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+ dhd->op_mode |= val; -+ AP6210_ERR("Set : op_mode=0x%04x\n", dhd->op_mode); -+#ifdef ARP_OFFLOAD_SUPPORT -+ if (dhd->arp_version == 1) { -+ /* IF P2P is enabled, disable arpoe */ -+ dhd_arp_offload_set(dhd, 0); -+ dhd_arp_offload_enable(dhd, false); -+ } -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+ return 0; -+} -+ -+s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl) -+{ -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+ dhd->op_mode &= ~(DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE); -+ AP6210_ERR("Clean : op_mode=0x%04x\n", dhd->op_mode); -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ if (dhd->arp_version == 1) { -+ /* IF P2P is disabled, enable arpoe back for STA mode. */ -+ dhd_arp_offload_set(dhd, dhd_arp_mode); -+ dhd_arp_offload_enable(dhd, true); -+ } -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+ return 0; -+} -+ -+static s32 wl_dongle_up(struct net_device *ndev, u32 up) -+{ -+ s32 err = 0; -+ -+ err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_UP error (%d)\n", err); -+ } -+ return err; -+} -+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock) -+{ -+#ifndef DHD_SDALIGN -+#define DHD_SDALIGN 32 -+#endif -+ struct net_device *ndev; -+ s32 err = 0; -+ -+ AP6210_DEBUG("In\n"); -+ if (dhd_dongle_up) { -+ AP6210_ERR("Dongle is already up\n"); -+ return err; -+ } -+ -+ ndev = wl_to_prmry_ndev(wl); -+ -+ if (need_lock) -+ rtnl_lock(); -+ -+ err = wl_dongle_up(ndev, 0); -+ if (unlikely(err)) { -+ AP6210_ERR("wl_dongle_up failed\n"); -+ goto default_conf_out; -+ } -+ dhd_dongle_up = true; -+ -+default_conf_out: -+ if (need_lock) -+ rtnl_unlock(); -+ return err; -+ -+} -+ -+ -+/* TODO: clean up the BT-Coex code, it still have some legacy ioctl/iovar functions */ -+#define COEX_DHCP -+ -+#if defined(COEX_DHCP) -+ -+/* use New SCO/eSCO smart YG suppression */ -+#define BT_DHCP_eSCO_FIX -+/* this flag boost wifi pkt priority to max, caution: -not fair to sco */ -+#define BT_DHCP_USE_FLAGS -+/* T1 start SCO/ESCo priority suppression */ -+#define BT_DHCP_OPPR_WIN_TIME 2500 -+/* T2 turn off SCO/SCO supperesion is (timeout) */ -+#define BT_DHCP_FLAG_FORCE_TIME 5500 -+ -+enum wl_cfg80211_btcoex_status { -+ BT_DHCP_IDLE, -+ BT_DHCP_START, -+ BT_DHCP_OPPR_WIN, -+ BT_DHCP_FLAG_FORCE_TIMEOUT -+}; -+ -+/* -+ * get named driver variable to uint register value and return error indication -+ * calling example: dev_wlc_intvar_get_reg(dev, "btc_params",66, ®_value) -+ */ -+static int -+dev_wlc_intvar_get_reg(struct net_device *dev, char *name, -+ uint reg, int *retval) -+{ -+ union { -+ char buf[WLC_IOCTL_SMLEN]; -+ int val; -+ } var; -+ int error; -+ -+ bcm_mkiovar(name, (char *)(®), sizeof(reg), -+ (char *)(&var), sizeof(var.buf)); -+ error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false); -+ -+ *retval = dtoh32(var.val); -+ return (error); -+} -+ -+static int -+dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) -+ char ioctlbuf_local[1024]; -+#else -+ static char ioctlbuf_local[1024]; -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ -+ -+ bcm_mkiovar(name, buf, len, ioctlbuf_local, sizeof(ioctlbuf_local)); -+ -+ return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local), true)); -+} -+/* -+get named driver variable to uint register value and return error indication -+calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value) -+*/ -+static int -+dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val) -+{ -+ char reg_addr[8]; -+ -+ memset(reg_addr, 0, sizeof(reg_addr)); -+ memcpy((char *)®_addr[0], (char *)addr, 4); -+ memcpy((char *)®_addr[4], (char *)val, 4); -+ -+ return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -+} -+ -+static bool btcoex_is_sco_active(struct net_device *dev) -+{ -+ int ioc_res = 0; -+ bool res = FALSE; -+ int sco_id_cnt = 0; -+ int param27; -+ int i; -+ -+ for (i = 0; i < 12; i++) { -+ -+ ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); -+ -+ AP6210_DEBUG("%s, sample[%d], btc params: 27:%x\n", -+ __FUNCTION__, i, param27); -+ -+ if (ioc_res < 0) { -+ AP6210_ERR("%s ioc read btc params error\n", __FUNCTION__); -+ break; -+ } -+ -+ if ((param27 & 0x6) == 2) { /* count both sco & esco */ -+ sco_id_cnt++; -+ } -+ -+ if (sco_id_cnt > 2) { -+ AP6210_DEBUG("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", -+ __FUNCTION__, sco_id_cnt, i); -+ res = TRUE; -+ break; -+ } -+ -+ msleep(5); -+ } -+ -+ return res; -+} -+ -+#if defined(BT_DHCP_eSCO_FIX) -+/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */ -+static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -+{ -+ static bool saved_status = FALSE; -+ -+ char buf_reg50va_dhcp_on[8] = -+ { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; -+ char buf_reg51va_dhcp_on[8] = -+ { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; -+ char buf_reg64va_dhcp_on[8] = -+ { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; -+ char buf_reg65va_dhcp_on[8] = -+ { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; -+ char buf_reg71va_dhcp_on[8] = -+ { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; -+ uint32 regaddr; -+ static uint32 saved_reg50; -+ static uint32 saved_reg51; -+ static uint32 saved_reg64; -+ static uint32 saved_reg65; -+ static uint32 saved_reg71; -+ -+ if (trump_sco) { -+ /* this should reduce eSCO agressive retransmit -+ * w/o breaking it -+ */ -+ -+ /* 1st save current */ -+ AP6210_DEBUG("Do new SCO/eSCO coex algo {save &" -+ "override}\n"); -+ if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { -+ saved_status = TRUE; -+ AP6210_DEBUG("%s saved bt_params[50,51,64,65,71]:" -+ "0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ __FUNCTION__, saved_reg50, saved_reg51, -+ saved_reg64, saved_reg65, saved_reg71); -+ } else { -+ AP6210_ERR(":%s: save btc_params failed\n", -+ __FUNCTION__); -+ saved_status = FALSE; -+ return -1; -+ } -+ -+ AP6210_DEBUG("override with [50,51,64,65,71]:" -+ "0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ *(u32 *)(buf_reg50va_dhcp_on+4), -+ *(u32 *)(buf_reg51va_dhcp_on+4), -+ *(u32 *)(buf_reg64va_dhcp_on+4), -+ *(u32 *)(buf_reg65va_dhcp_on+4), -+ *(u32 *)(buf_reg71va_dhcp_on+4)); -+ -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg50va_dhcp_on[0], 8); -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg51va_dhcp_on[0], 8); -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg64va_dhcp_on[0], 8); -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg65va_dhcp_on[0], 8); -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg71va_dhcp_on[0], 8); -+ -+ saved_status = TRUE; -+ } else if (saved_status) { -+ /* restore previously saved bt params */ -+ AP6210_DEBUG("Do new SCO/eSCO coex algo {save &" -+ "override}\n"); -+ -+ regaddr = 50; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg50); -+ regaddr = 51; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg51); -+ regaddr = 64; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg64); -+ regaddr = 65; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg65); -+ regaddr = 71; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg71); -+ -+ AP6210_DEBUG("restore bt_params[50,51,64,65,71]:" -+ "0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ saved_reg50, saved_reg51, saved_reg64, -+ saved_reg65, saved_reg71); -+ -+ saved_status = FALSE; -+ } else { -+ AP6210_ERR(":%s att to restore not saved BTCOEX params\n", -+ __FUNCTION__); -+ return -1; -+ } -+ return 0; -+} -+#endif /* BT_DHCP_eSCO_FIX */ -+ -+static void -+wl_cfg80211_bt_setflag(struct net_device *dev, bool set) -+{ -+#if defined(BT_DHCP_USE_FLAGS) -+ char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; -+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -+#endif -+ -+ -+#if defined(BT_DHCP_eSCO_FIX) -+ /* set = 1, save & turn on 0 - off & restore prev settings */ -+ set_btc_esco_params(dev, set); -+#endif -+ -+#if defined(BT_DHCP_USE_FLAGS) -+ AP6210_DEBUG("WI-FI priority boost via bt flags, set:%d\n", set); -+ if (set == TRUE) -+ /* Forcing bt_flag7 */ -+ dev_wlc_bufvar_set(dev, "btc_flags", -+ (char *)&buf_flag7_dhcp_on[0], -+ sizeof(buf_flag7_dhcp_on)); -+ else -+ /* Restoring default bt flag7 */ -+ dev_wlc_bufvar_set(dev, "btc_flags", -+ (char *)&buf_flag7_default[0], -+ sizeof(buf_flag7_default)); -+#endif -+} -+ -+static void wl_cfg80211_bt_timerfunc(ulong data) -+{ -+ struct btcoex_info *bt_local = (struct btcoex_info *)data; -+ AP6210_DEBUG("%s\n", __FUNCTION__); -+ bt_local->timer_on = 0; -+ schedule_work(&bt_local->work); -+} -+ -+static void wl_cfg80211_bt_handler(struct work_struct *work) -+{ -+ struct btcoex_info *btcx_inf; -+ -+ btcx_inf = container_of(work, struct btcoex_info, work); -+ -+ if (btcx_inf->timer_on) { -+ btcx_inf->timer_on = 0; -+ del_timer_sync(&btcx_inf->timer); -+ } -+ -+ switch (btcx_inf->bt_state) { -+ case BT_DHCP_START: -+ /* DHCP started -+ * provide OPPORTUNITY window to get DHCP address -+ */ -+ AP6210_DEBUG("%s bt_dhcp stm: started \n", -+ __FUNCTION__); -+ btcx_inf->bt_state = BT_DHCP_OPPR_WIN; -+ mod_timer(&btcx_inf->timer, -+ jiffies + msecs_to_jiffies(BT_DHCP_OPPR_WIN_TIME)); -+ btcx_inf->timer_on = 1; -+ break; -+ -+ case BT_DHCP_OPPR_WIN: -+ if (btcx_inf->dhcp_done) { -+ AP6210_DEBUG("%s DHCP Done before T1 expiration\n", -+ __FUNCTION__); -+ goto btc_coex_idle; -+ } -+ -+ /* DHCP is not over yet, start lowering BT priority -+ * enforce btc_params + flags if necessary -+ */ -+ AP6210_DEBUG("%s DHCP T1:%d expired\n", __FUNCTION__, -+ BT_DHCP_OPPR_WIN_TIME); -+ if (btcx_inf->dev) -+ wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE); -+ btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; -+ mod_timer(&btcx_inf->timer, -+ jiffies + msecs_to_jiffies(BT_DHCP_FLAG_FORCE_TIME)); -+ btcx_inf->timer_on = 1; -+ break; -+ -+ case BT_DHCP_FLAG_FORCE_TIMEOUT: -+ if (btcx_inf->dhcp_done) { -+ AP6210_DEBUG("%s DHCP Done before T2 expiration\n", -+ __FUNCTION__); -+ } else { -+ /* Noo dhcp during T1+T2, restore BT priority */ -+ AP6210_DEBUG("%s DHCP wait interval T2:%d" -+ "msec expired\n", __FUNCTION__, -+ BT_DHCP_FLAG_FORCE_TIME); -+ } -+ -+ /* Restoring default bt priority */ -+ if (btcx_inf->dev) -+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE); -+btc_coex_idle: -+ btcx_inf->bt_state = BT_DHCP_IDLE; -+ btcx_inf->timer_on = 0; -+ break; -+ -+ default: -+ AP6210_ERR("%s error g_status=%d !!!\n", __FUNCTION__, -+ btcx_inf->bt_state); -+ if (btcx_inf->dev) -+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE); -+ btcx_inf->bt_state = BT_DHCP_IDLE; -+ btcx_inf->timer_on = 0; -+ break; -+ } -+ -+ net_os_wake_unlock(btcx_inf->dev); -+} -+ -+int wl_cfg80211_btcoex_init(struct wl_priv *wl) -+{ -+ struct btcoex_info *btco_inf = NULL; -+ -+ btco_inf = kmalloc(sizeof(struct btcoex_info), GFP_KERNEL); -+ if (!btco_inf) -+ return -ENOMEM; -+ -+ btco_inf->bt_state = BT_DHCP_IDLE; -+ btco_inf->ts_dhcp_start = 0; -+ btco_inf->ts_dhcp_ok = 0; -+ /* Set up timer for BT */ -+ btco_inf->timer_ms = 10; -+ init_timer(&btco_inf->timer); -+ btco_inf->timer.data = (ulong)btco_inf; -+ btco_inf->timer.function = wl_cfg80211_bt_timerfunc; -+ -+ btco_inf->dev = wl->wdev->netdev; -+ -+ INIT_WORK(&btco_inf->work, wl_cfg80211_bt_handler); -+ -+ wl->btcoex_info = btco_inf; -+ return 0; -+} -+ -+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl) -+{ -+ if (!wl->btcoex_info) -+ return; -+ -+ if (wl->btcoex_info->timer_on) { -+ wl->btcoex_info->timer_on = 0; -+ del_timer_sync(&wl->btcoex_info->timer); -+ } -+ -+ cancel_work_sync(&wl->btcoex_info->work); -+ -+ kfree(wl->btcoex_info); -+ wl->btcoex_info = NULL; -+} -+#endif -+ -+int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) -+{ -+ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ char powermode_val = 0; -+ char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; -+ char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; -+ char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; -+ -+ uint32 regaddr; -+ static uint32 saved_reg66; -+ static uint32 saved_reg41; -+ static uint32 saved_reg68; -+ static bool saved_status = FALSE; -+ -+#ifdef COEX_DHCP -+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -+ struct btcoex_info *btco_inf = wl->btcoex_info; -+#endif /* COEX_DHCP */ -+ -+#ifdef PKT_FILTER_SUPPORT -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+#endif -+ -+ /* Figure out powermode 1 or o command */ -+ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); -+ -+ if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { -+ AP6210_DEBUG("%s: DHCP session starts\n", __FUNCTION__); -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+ /* Suppress scan during the DHCP */ -+ wl_cfg80211_scan_suppress(dev, 1); -+#endif /* OEM_ANDROID */ -+ -+#ifdef PKT_FILTER_SUPPORT -+ dhd->dhcp_in_progress = 1; -+ -+ if (dhd->early_suspended) { -+ AP6210_DEBUG("DHCP in progressing , disable packet filter!!!\n"); -+ dhd_enable_packet_filter(0, dhd); -+ } -+#endif -+ -+ /* Retrieve and saved orig regs value */ -+ if ((saved_status == FALSE) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && -+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { -+ saved_status = TRUE; -+ AP6210_DEBUG("Saved 0x%x 0x%x 0x%x\n", -+ saved_reg66, saved_reg41, saved_reg68); -+ -+ /* Disable PM mode during dhpc session */ -+ -+ /* Disable PM mode during dhpc session */ -+#ifdef COEX_DHCP -+ /* Start BT timer only for SCO connection */ -+ if (btcoex_is_sco_active(dev)) { -+ /* btc_params 66 */ -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg66va_dhcp_on[0], -+ sizeof(buf_reg66va_dhcp_on)); -+ /* btc_params 41 0x33 */ -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg41va_dhcp_on[0], -+ sizeof(buf_reg41va_dhcp_on)); -+ /* btc_params 68 0x190 */ -+ dev_wlc_bufvar_set(dev, "btc_params", -+ (char *)&buf_reg68va_dhcp_on[0], -+ sizeof(buf_reg68va_dhcp_on)); -+ saved_status = TRUE; -+ -+ btco_inf->bt_state = BT_DHCP_START; -+ btco_inf->timer_on = 1; -+ mod_timer(&btco_inf->timer, btco_inf->timer.expires); -+ AP6210_DEBUG("%s enable BT DHCP Timer\n", -+ __FUNCTION__); -+ } -+#endif /* COEX_DHCP */ -+ } -+ else if (saved_status == TRUE) { -+ AP6210_ERR("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__); -+ } -+ } -+ else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { -+ -+ -+#ifdef PKT_FILTER_SUPPORT -+ dhd->dhcp_in_progress = 0; -+ AP6210_DEBUG("%s: DHCP is complete \n", __FUNCTION__); -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+ /* Since DHCP is complete, enable the scan back */ -+ wl_cfg80211_scan_suppress(dev, 0); -+#endif /* OEM_ANDROID */ -+ -+ /* Enable packet filtering */ -+ if (dhd->early_suspended) { -+ AP6210_DEBUG("DHCP is complete , enable packet filter!!!\n"); -+ dhd_enable_packet_filter(1, dhd); -+ } -+#endif /* PKT_FILTER_SUPPORT */ -+ -+ /* Restoring PM mode */ -+ -+#ifdef COEX_DHCP -+ /* Stop any bt timer because DHCP session is done */ -+ AP6210_DEBUG("%s disable BT DHCP Timer\n", __FUNCTION__); -+ if (btco_inf->timer_on) { -+ btco_inf->timer_on = 0; -+ del_timer_sync(&btco_inf->timer); -+ -+ if (btco_inf->bt_state != BT_DHCP_IDLE) { -+ /* need to restore original btc flags & extra btc params */ -+ AP6210_DEBUG("%s bt->bt_state:%d\n", -+ __FUNCTION__, btco_inf->bt_state); -+ /* wake up btcoex thread to restore btlags+params */ -+ schedule_work(&btco_inf->work); -+ } -+ } -+ -+ /* Restoring btc_flag paramter anyway */ -+ if (saved_status == TRUE) -+ dev_wlc_bufvar_set(dev, "btc_flags", -+ (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); -+#endif /* COEX_DHCP */ -+ -+ /* Restore original values */ -+ if (saved_status == TRUE) { -+ regaddr = 66; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg66); -+ regaddr = 41; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg41); -+ regaddr = 68; -+ dev_wlc_intvar_set_reg(dev, "btc_params", -+ (char *)®addr, (char *)&saved_reg68); -+ -+ AP6210_DEBUG("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", -+ saved_reg66, saved_reg41, saved_reg68); -+ } -+ saved_status = FALSE; -+ -+ } -+ else { -+ AP6210_ERR("%s Unkwown yet power setting, ignored\n", -+ __FUNCTION__); -+ } -+ -+ snprintf(command, 3, "OK"); -+ -+ return (strlen("OK")); -+} -diff --git a/drivers/net/wireless/ap6210/dhd_cfg80211.h b/drivers/net/wireless/ap6210/dhd_cfg80211.h -new file mode 100644 -index 0000000..922d6ed ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_cfg80211.h -@@ -0,0 +1,44 @@ -+/* -+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ -+ */ -+ -+ -+#ifndef __DHD_CFG80211__ -+#define __DHD_CFG80211__ -+ -+#include -+#include -+ -+s32 dhd_cfg80211_init(struct wl_priv *wl); -+s32 dhd_cfg80211_deinit(struct wl_priv *wl); -+s32 dhd_cfg80211_down(struct wl_priv *wl); -+s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val); -+s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl); -+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock); -+ -+int wl_cfg80211_btcoex_init(struct wl_priv *wl); -+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl); -+ -+#endif /* __DHD_CFG80211__ */ -diff --git a/drivers/net/wireless/ap6210/dhd_common.c b/drivers/net/wireless/ap6210/dhd_common.c -new file mode 100644 -index 0000000..96c021f ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_common.c -@@ -0,0 +1,2255 @@ -+/* -+ * Broadcom Dongle Host Driver (DHD), common DHD core. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_common.c 373873 2012-12-10 20:45:58Z $ -+ */ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef WL_CFG80211 -+#include -+#endif -+#ifdef WLBTAMP -+#include -+#include -+#endif -+#ifdef SET_RANDOM_MAC_SOFTAP -+#include -+#include -+#endif -+ -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+ -+#ifdef PROP_TXSTATUS -+#include -+#include -+#endif -+ -+#include -+#include -+ -+#ifdef WLMEDIA_HTSF -+extern void htsf_update(struct dhd_info *dhd, void *data); -+#endif -+int dhd_msg_level = DHD_ERROR_VAL; -+ -+ -+#include -+ -+char fw_path[MOD_PARAM_PATHLEN]; -+char nv_path[MOD_PARAM_PATHLEN]; -+ -+#ifdef SOFTAP -+char fw_path2[MOD_PARAM_PATHLEN]; -+extern bool softap_enabled; -+#endif -+ -+/* Last connection success/failure status */ -+uint32 dhd_conn_event; -+uint32 dhd_conn_status; -+uint32 dhd_conn_reason; -+ -+extern int dhd_iscan_request(void * dhdp, uint16 action); -+extern void dhd_ind_scan_confirm(void *h, bool status); -+extern int dhd_iscan_in_progress(void *h); -+void dhd_iscan_lock(void); -+void dhd_iscan_unlock(void); -+extern int dhd_change_mtu(dhd_pub_t *dhd, int new_mtu, int ifidx); -+#if !defined(AP) && defined(WLP2P) -+extern int dhd_get_concurrent_capabilites(dhd_pub_t *dhd); -+#endif -+bool ap_cfg_running = FALSE; -+bool ap_fw_loaded = FALSE; -+ -+ -+#ifdef DHD_DEBUG -+const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " -+ __DATE__ " at " __TIME__; -+#else -+const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR; -+#endif -+ -+void dhd_set_timer(void *bus, uint wdtick); -+ -+/* IOVar table */ -+enum { -+ IOV_VERSION = 1, -+ IOV_WLMSGLEVEL, -+ IOV_MSGLEVEL, -+ IOV_BCMERRORSTR, -+ IOV_BCMERROR, -+ IOV_WDTICK, -+ IOV_DUMP, -+ IOV_CLEARCOUNTS, -+ IOV_LOGDUMP, -+ IOV_LOGCAL, -+ IOV_LOGSTAMP, -+ IOV_GPIOOB, -+ IOV_IOCTLTIMEOUT, -+#ifdef WLBTAMP -+ IOV_HCI_CMD, /* HCI command */ -+ IOV_HCI_ACL_DATA, /* HCI data packet */ -+#endif -+#if defined(DHD_DEBUG) -+ IOV_CONS, -+ IOV_DCONSOLE_POLL, -+#endif /* defined(DHD_DEBUG) */ -+#ifdef PROP_TXSTATUS -+ IOV_PROPTXSTATUS_ENABLE, -+ IOV_PROPTXSTATUS_MODE, -+#endif -+ IOV_BUS_TYPE, -+#ifdef WLMEDIA_HTSF -+ IOV_WLPKTDLYSTAT_SZ, -+#endif -+ IOV_CHANGEMTU, -+ IOV_HOSTREORDER_FLOWS, -+ IOV_LAST -+}; -+ -+const bcm_iovar_t dhd_iovars[] = { -+ {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) }, -+ {"wlmsglevel", IOV_WLMSGLEVEL, 0, IOVT_UINT32, 0 }, -+#ifdef DHD_DEBUG -+ {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, -+#endif /* DHD_DEBUG */ -+ {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN }, -+ {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 }, -+ {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 }, -+ {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, -+#ifdef DHD_DEBUG -+ {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 }, -+ {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 }, -+#endif -+ {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, -+ {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, -+ {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, -+#ifdef WLBTAMP -+ {"HCI_cmd", IOV_HCI_CMD, 0, IOVT_BUFFER, 0}, -+ {"HCI_ACL_data", IOV_HCI_ACL_DATA, 0, IOVT_BUFFER, 0}, -+#endif -+#ifdef PROP_TXSTATUS -+ {"proptx", IOV_PROPTXSTATUS_ENABLE, 0, IOVT_UINT32, 0 }, -+ /* -+ set the proptxtstatus operation mode: -+ 0 - Do not do any proptxtstatus flow control -+ 1 - Use implied credit from a packet status -+ 2 - Use explicit credit -+ */ -+ {"ptxmode", IOV_PROPTXSTATUS_MODE, 0, IOVT_UINT32, 0 }, -+#endif -+ {"bustype", IOV_BUS_TYPE, 0, IOVT_UINT32, 0}, -+#ifdef WLMEDIA_HTSF -+ {"pktdlystatsz", IOV_WLPKTDLYSTAT_SZ, 0, IOVT_UINT8, 0 }, -+#endif -+ {"changemtu", IOV_CHANGEMTU, 0, IOVT_UINT32, 0 }, -+ {"host_reorder_flows", IOV_HOSTREORDER_FLOWS, 0, IOVT_BUFFER, -+ (WLHOST_REORDERDATA_MAXFLOWS + 1) }, -+ {NULL, 0, 0, 0, 0 } -+}; -+ -+void -+dhd_common_init(osl_t *osh) -+{ -+ int select_type = 0; -+ //aw checkout which wifi had select -+ select_type = ap6210_gpio_wifi_get_mod_type(); -+ -+#ifdef CONFIG_AP6210_FW_PATH -+ //select bcm40181/ap6181/ap6210 -+ if (select_type == 1 || select_type == 7 || select_type == 9) { -+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40181a2.bin", MOD_PARAM_PATHLEN-1); -+ } -+ //select bcm40183 -+ if (select_type == 2) { -+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2.bin", MOD_PARAM_PATHLEN-1); -+ } -+ //select ap6330 -+ if (select_type == 8) { -+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2_ag.bin", MOD_PARAM_PATHLEN-1); -+ } -+ -+#else /* CONFIG_AP6210_FW_PATH */ -+ fw_path[0] = '\0'; -+#endif /* CONFIG_AP6210_FW_PATH */ -+#ifdef CONFIG_AP6210_NVRAM_PATH -+ //select bcm40181 -+ if (select_type == 1) { -+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40181.txt", MOD_PARAM_PATHLEN-1); -+ } -+ //select bcm40183 -+ if (select_type == 2) { -+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40183.txt", MOD_PARAM_PATHLEN-1); -+ } -+ //select ap6210 -+ if (select_type == 7) { -+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6210.txt", MOD_PARAM_PATHLEN-1); -+ } -+ -+ //select ap6330 -+ if (select_type == 8) { -+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6330.txt", MOD_PARAM_PATHLEN-1); -+ } -+ //select ap6181 -+ if (select_type == 9) { -+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6181.txt", MOD_PARAM_PATHLEN-1); -+ } -+#else /* CONFIG_AP6210_NVRAM_PATH */ -+ nv_path[0] = '\0'; -+#endif /* CONFIG_AP6210_NVRAM_PATH */ -+#ifdef SOFTAP -+ fw_path2[0] = '\0'; -+#endif -+} -+ -+static int -+dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) -+{ -+ char eabuf[ETHER_ADDR_STR_LEN]; -+ -+ struct bcmstrbuf b; -+ struct bcmstrbuf *strbuf = &b; -+ -+ bcm_binit(strbuf, buf, buflen); -+ -+ /* Base DHD info */ -+ bcm_bprintf(strbuf, "%s\n", dhd_version); -+ bcm_bprintf(strbuf, "\n"); -+ bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", -+ dhdp->up, dhdp->txoff, dhdp->busstate); -+ bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", -+ dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); -+ bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n", -+ dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf)); -+ bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt); -+ -+ bcm_bprintf(strbuf, "dongle stats:\n"); -+ bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", -+ dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, -+ dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); -+ bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", -+ dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, -+ dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); -+ bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); -+ -+ bcm_bprintf(strbuf, "bus stats:\n"); -+ bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", -+ dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); -+ bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", -+ dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); -+ bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n", -+ dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); -+ bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld\n", -+ dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped); -+ bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld\n", -+ dhdp->rx_readahead_cnt, dhdp->tx_realloc); -+ bcm_bprintf(strbuf, "\n"); -+ -+ /* Add any prot info */ -+ dhd_prot_dump(dhdp, strbuf); -+ bcm_bprintf(strbuf, "\n"); -+ -+ /* Add any bus info */ -+ dhd_bus_dump(dhdp, strbuf); -+ -+ return (!strbuf->size ? BCME_BUFTOOSHORT : 0); -+} -+ -+int -+dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex) -+{ -+ wl_ioctl_t ioc; -+ -+ ioc.cmd = cmd; -+ ioc.buf = arg; -+ ioc.len = len; -+ ioc.set = set; -+ -+ return dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len); -+} -+ -+ -+int -+dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len) -+{ -+ int ret; -+ -+ dhd_os_proto_block(dhd_pub); -+ -+ ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len); -+ if ((ret) && (dhd_pub->up)) -+ /* Send hang event only if dhd_open() was success */ -+ dhd_os_check_hang(dhd_pub, ifindex, ret); -+ -+ dhd_os_proto_unblock(dhd_pub); -+ -+ return ret; -+} -+ -+static int -+dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name, -+ void *params, int plen, void *arg, int len, int val_size) -+{ -+ int bcmerror = 0; -+ int32 int_val = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ AP6210_DEBUG("%s: actionid = %d; name %s\n", __FUNCTION__, actionid, name); -+ -+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) -+ goto exit; -+ -+ if (plen >= (int)sizeof(int_val)) -+ bcopy(params, &int_val, sizeof(int_val)); -+ -+ switch (actionid) { -+ case IOV_GVAL(IOV_VERSION): -+ /* Need to have checked buffer length */ -+ bcm_strncpy_s((char*)arg, len, dhd_version, len); -+ break; -+ -+ case IOV_GVAL(IOV_WLMSGLEVEL): -+ //AP6210_DEBUG("android_msg_level=0x%x\n", android_msg_level); -+#if defined(CONFIG_WIRELESS_EXT) -+ int_val = (int32)iw_msg_level; -+ bcopy(&int_val, arg, val_size); -+ AP6210_DEBUG("iw_msg_level=0x%x\n", iw_msg_level); -+#endif -+#ifdef WL_CFG80211 -+ int_val = (int32)wl_dbg_level; -+ bcopy(&int_val, arg, val_size); -+ AP6210_DEBUG("cfg_msg_level=0x%x\n", wl_dbg_level); -+#endif -+ break; -+ -+ case IOV_SVAL(IOV_WLMSGLEVEL): -+#if defined(CONFIG_WIRELESS_EXT) -+ if (int_val & DHD_IW_VAL) { -+ iw_msg_level = (uint)(int_val & 0xFFFF); -+ AP6210_DEBUG("iw_msg_level=0x%x\n", iw_msg_level); -+ } else -+#endif -+#ifdef WL_CFG80211 -+ if (int_val & DHD_CFG_VAL) { -+ wl_cfg80211_enable_trace((u32)(int_val & 0xFFFF)); -+ } else -+#endif -+ { -+ //android_msg_level = (uint)int_val; -+ //AP6210_DEBUG("android_msg_level=0x%x\n", android_msg_level); -+ } -+ break; -+ -+ case IOV_GVAL(IOV_MSGLEVEL): -+ int_val = (int32)dhd_msg_level; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_MSGLEVEL): -+ dhd_msg_level = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_BCMERRORSTR): -+ bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); -+ ((char *)arg)[BCME_STRLEN - 1] = 0x00; -+ break; -+ -+ case IOV_GVAL(IOV_BCMERROR): -+ int_val = (int32)dhd_pub->bcmerror; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_WDTICK): -+ int_val = (int32)dhd_watchdog_ms; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_WDTICK): -+ if (!dhd_pub->up) { -+ bcmerror = BCME_NOTUP; -+ break; -+ } -+ dhd_os_wd_timer(dhd_pub, (uint)int_val); -+ break; -+ -+ case IOV_GVAL(IOV_DUMP): -+ bcmerror = dhd_dump(dhd_pub, arg, len); -+ break; -+ -+#ifdef DHD_DEBUG -+ case IOV_GVAL(IOV_DCONSOLE_POLL): -+ int_val = (int32)dhd_console_ms; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_DCONSOLE_POLL): -+ dhd_console_ms = (uint)int_val; -+ break; -+ -+ case IOV_SVAL(IOV_CONS): -+ if (len > 0) -+ bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1); -+ break; -+#endif /* DHD_DEBUG */ -+ -+ case IOV_SVAL(IOV_CLEARCOUNTS): -+ dhd_pub->tx_packets = dhd_pub->rx_packets = 0; -+ dhd_pub->tx_errors = dhd_pub->rx_errors = 0; -+ dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0; -+ dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0; -+ dhd_pub->rx_dropped = 0; -+ dhd_pub->rx_readahead_cnt = 0; -+ dhd_pub->tx_realloc = 0; -+ dhd_pub->wd_dpc_sched = 0; -+ memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats)); -+ dhd_bus_clearcounts(dhd_pub); -+#ifdef PROP_TXSTATUS -+ /* clear proptxstatus related counters */ -+ if (dhd_pub->wlfc_state) { -+ athost_wl_status_info_t *wlfc = -+ (athost_wl_status_info_t*)dhd_pub->wlfc_state; -+ wlfc_hanger_t* hanger; -+ -+ memset(&wlfc->stats, 0, sizeof(athost_wl_stat_counters_t)); -+ -+ hanger = (wlfc_hanger_t*)wlfc->hanger; -+ hanger->pushed = 0; -+ hanger->popped = 0; -+ hanger->failed_slotfind = 0; -+ hanger->failed_to_pop = 0; -+ hanger->failed_to_push = 0; -+ } -+#endif /* PROP_TXSTATUS */ -+ break; -+ -+ -+ case IOV_GVAL(IOV_IOCTLTIMEOUT): { -+ int_val = (int32)dhd_os_get_ioctl_resp_timeout(); -+ bcopy(&int_val, arg, sizeof(int_val)); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_IOCTLTIMEOUT): { -+ if (int_val <= 0) -+ bcmerror = BCME_BADARG; -+ else -+ dhd_os_set_ioctl_resp_timeout((unsigned int)int_val); -+ break; -+ } -+ -+#ifdef WLBTAMP -+ case IOV_SVAL(IOV_HCI_CMD): { -+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg; -+ -+ /* sanity check: command preamble present */ -+ if (len < HCI_CMD_PREAMBLE_SIZE) -+ return BCME_BUFTOOSHORT; -+ -+ /* sanity check: command parameters are present */ -+ if (len < (int)(HCI_CMD_PREAMBLE_SIZE + cmd->plen)) -+ return BCME_BUFTOOSHORT; -+ -+ dhd_bta_docmd(dhd_pub, cmd, len); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_HCI_ACL_DATA): { -+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)arg; -+ -+ /* sanity check: HCI header present */ -+ if (len < HCI_ACL_DATA_PREAMBLE_SIZE) -+ return BCME_BUFTOOSHORT; -+ -+ /* sanity check: ACL data is present */ -+ if (len < (int)(HCI_ACL_DATA_PREAMBLE_SIZE + ACL_data->dlen)) -+ return BCME_BUFTOOSHORT; -+ -+ dhd_bta_tx_hcidata(dhd_pub, ACL_data, len); -+ break; -+ } -+#endif /* WLBTAMP */ -+ -+#ifdef PROP_TXSTATUS -+ case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): -+ int_val = dhd_pub->wlfc_enabled? 1 : 0; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_PROPTXSTATUS_ENABLE): -+ dhd_pub->wlfc_enabled = int_val? 1 : 0; -+ break; -+ -+ case IOV_GVAL(IOV_PROPTXSTATUS_MODE): { -+ athost_wl_status_info_t *wlfc = -+ (athost_wl_status_info_t*)dhd_pub->wlfc_state; -+ int_val = dhd_pub->wlfc_state ? (int32)wlfc->proptxstatus_mode : 0; -+ bcopy(&int_val, arg, val_size); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_PROPTXSTATUS_MODE): -+ if (dhd_pub->wlfc_state) { -+ athost_wl_status_info_t *wlfc = -+ (athost_wl_status_info_t*)dhd_pub->wlfc_state; -+ wlfc->proptxstatus_mode = int_val & 0xff; -+ } -+ break; -+#endif /* PROP_TXSTATUS */ -+ -+ case IOV_GVAL(IOV_BUS_TYPE): -+ /* The dhd application queries the driver to check if its usb or sdio. */ -+#ifdef AP6210USB -+ int_val = BUS_TYPE_USB; -+#endif -+ int_val = BUS_TYPE_SDIO; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ -+#ifdef WLMEDIA_HTSF -+ case IOV_GVAL(IOV_WLPKTDLYSTAT_SZ): -+ int_val = dhd_pub->htsfdlystat_sz; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_WLPKTDLYSTAT_SZ): -+ dhd_pub->htsfdlystat_sz = int_val & 0xff; -+ AP6210_DEBUG("Setting tsfdlystat_sz:%d\n", dhd_pub->htsfdlystat_sz); -+ break; -+#endif -+ case IOV_SVAL(IOV_CHANGEMTU): -+ int_val &= 0xffff; -+ bcmerror = dhd_change_mtu(dhd_pub, int_val, 0); -+ break; -+ -+ case IOV_GVAL(IOV_HOSTREORDER_FLOWS): -+ { -+ uint i = 0; -+ uint8 *ptr = (uint8 *)arg; -+ uint8 count = 0; -+ -+ ptr++; -+ for (i = 0; i < WLHOST_REORDERDATA_MAXFLOWS; i++) { -+ if (dhd_pub->reorder_bufs[i] != NULL) { -+ *ptr = dhd_pub->reorder_bufs[i]->flow_id; -+ ptr++; -+ count++; -+ } -+ } -+ ptr = (uint8 *)arg; -+ *ptr = count; -+ break; -+ } -+ -+ default: -+ bcmerror = BCME_UNSUPPORTED; -+ break; -+ } -+ -+exit: -+ AP6210_DEBUG("%s: actionid %d, bcmerror %d\n", __FUNCTION__, actionid, bcmerror); -+ return bcmerror; -+} -+ -+/* Store the status of a connection attempt for later retrieval by an iovar */ -+void -+dhd_store_conn_status(uint32 event, uint32 status, uint32 reason) -+{ -+ /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID -+ * because an encryption/rsn mismatch results in both events, and -+ * the important information is in the WLC_E_PRUNE. -+ */ -+ if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL && -+ dhd_conn_event == WLC_E_PRUNE)) { -+ dhd_conn_event = event; -+ dhd_conn_status = status; -+ dhd_conn_reason = reason; -+ } -+} -+ -+bool -+dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) -+{ -+ void *p; -+ int eprec = -1; /* precedence to evict from */ -+ bool discard_oldest; -+ -+ /* Fast case, precedence queue is not full and we are also not -+ * exceeding total queue length -+ */ -+ if (!pktq_pfull(q, prec) && !pktq_full(q)) { -+ pktq_penq(q, prec, pkt); -+ return TRUE; -+ } -+ -+ /* Determine precedence from which to evict packet, if any */ -+ if (pktq_pfull(q, prec)) -+ eprec = prec; -+ else if (pktq_full(q)) { -+ pktq_peek_tail(q, &eprec); -+ if (eprec > prec || eprec < 0) -+ return FALSE; -+ } -+ -+ /* Evict if needed */ -+ if (eprec >= 0) { -+ /* Detect queueing to unconfigured precedence */ -+ ASSERT(!pktq_pempty(q, eprec)); -+ discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); -+ if (eprec == prec && !discard_oldest) -+ return FALSE; /* refuse newer (incoming) packet */ -+ /* Evict packet according to discard policy */ -+ p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec); -+ ASSERT(p); -+ -+ PKTFREE(dhdp->osh, p, TRUE); -+ } -+ -+ /* Enqueue */ -+ pktq_penq(q, prec, pkt); -+ -+ return TRUE; -+} -+ -+static int -+dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, -+ void *params, int plen, void *arg, int len, bool set) -+{ -+ int bcmerror = 0; -+ int val_size; -+ const bcm_iovar_t *vi = NULL; -+ uint32 actionid; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(name); -+ ASSERT(len >= 0); -+ -+ /* Get MUST have return space */ -+ ASSERT(set || (arg && len)); -+ -+ /* Set does NOT take qualifiers */ -+ ASSERT(!set || (!params && !plen)); -+ -+ if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) { -+ bcmerror = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ -+ AP6210_DEBUG("%s: %s %s, len %d plen %d\n", __FUNCTION__, -+ name, (set ? "set" : "get"), len, plen); -+ -+ /* set up 'params' pointer in case this is a set command so that -+ * the convenience int and bool code can be common to set and get -+ */ -+ if (params == NULL) { -+ params = arg; -+ plen = len; -+ } -+ -+ if (vi->type == IOVT_VOID) -+ val_size = 0; -+ else if (vi->type == IOVT_BUFFER) -+ val_size = len; -+ else -+ /* all other types are integer sized */ -+ val_size = sizeof(int); -+ -+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); -+ -+ bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size); -+ -+exit: -+ return bcmerror; -+} -+ -+int -+dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen) -+{ -+ int bcmerror = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (!buf) { -+ return BCME_BADARG; -+ } -+ -+ switch (ioc->cmd) { -+ case DHD_GET_MAGIC: -+ if (buflen < sizeof(int)) -+ bcmerror = BCME_BUFTOOSHORT; -+ else -+ *(int*)buf = DHD_IOCTL_MAGIC; -+ break; -+ -+ case DHD_GET_VERSION: -+ if (buflen < sizeof(int)) -+ bcmerror = -BCME_BUFTOOSHORT; -+ else -+ *(int*)buf = DHD_IOCTL_VERSION; -+ break; -+ -+ case DHD_GET_VAR: -+ case DHD_SET_VAR: { -+ char *arg; -+ uint arglen; -+ -+ /* scan past the name to any arguments */ -+ for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--) -+ ; -+ -+ if (*arg) { -+ bcmerror = BCME_BUFTOOSHORT; -+ break; -+ } -+ -+ /* account for the NUL terminator */ -+ arg++, arglen--; -+ -+ /* call with the appropriate arguments */ -+ if (ioc->cmd == DHD_GET_VAR) -+ bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen, -+ buf, buflen, IOV_GET); -+ else -+ bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET); -+ if (bcmerror != BCME_UNSUPPORTED) -+ break; -+ -+ /* not in generic table, try protocol module */ -+ if (ioc->cmd == DHD_GET_VAR) -+ bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg, -+ arglen, buf, buflen, IOV_GET); -+ else -+ bcmerror = dhd_prot_iovar_op(dhd_pub, buf, -+ NULL, 0, arg, arglen, IOV_SET); -+ if (bcmerror != BCME_UNSUPPORTED) -+ break; -+ -+ /* if still not found, try bus module */ -+ if (ioc->cmd == DHD_GET_VAR) { -+ bcmerror = dhd_bus_iovar_op(dhd_pub, buf, -+ arg, arglen, buf, buflen, IOV_GET); -+ } else { -+ bcmerror = dhd_bus_iovar_op(dhd_pub, buf, -+ NULL, 0, arg, arglen, IOV_SET); -+ } -+ -+ break; -+ } -+ -+ default: -+ bcmerror = BCME_UNSUPPORTED; -+ } -+ -+ return bcmerror; -+} -+ -+#ifdef SHOW_EVENTS -+static void -+wl_show_host_event(wl_event_msg_t *event, void *event_data) -+{ -+ uint i, status, reason; -+ bool group = FALSE, flush_txq = FALSE, link = FALSE; -+ const char *auth_str; -+ const char *event_name; -+ uchar *buf; -+ char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; -+ uint event_type, flags, auth_type, datalen; -+ -+ event_type = ntoh32(event->event_type); -+ flags = ntoh16(event->flags); -+ status = ntoh32(event->status); -+ reason = ntoh32(event->reason); -+ BCM_REFERENCE(reason); -+ auth_type = ntoh32(event->auth_type); -+ datalen = ntoh32(event->datalen); -+ -+ /* debug dump of event messages */ -+ snprintf(eabuf, sizeof(eabuf), "%02x:%02x:%02x:%02x:%02x:%02x", -+ (uchar)event->addr.octet[0]&0xff, -+ (uchar)event->addr.octet[1]&0xff, -+ (uchar)event->addr.octet[2]&0xff, -+ (uchar)event->addr.octet[3]&0xff, -+ (uchar)event->addr.octet[4]&0xff, -+ (uchar)event->addr.octet[5]&0xff); -+ -+ event_name = "UNKNOWN"; -+ for (i = 0; i < (uint)bcmevent_names_size; i++) -+ if (bcmevent_names[i].event == event_type) -+ event_name = bcmevent_names[i].name; -+ -+ if (flags & WLC_EVENT_MSG_LINK) -+ link = TRUE; -+ if (flags & WLC_EVENT_MSG_GROUP) -+ group = TRUE; -+ if (flags & WLC_EVENT_MSG_FLUSHTXQ) -+ flush_txq = TRUE; -+ -+ switch (event_type) { -+ case WLC_E_START: -+ case WLC_E_DEAUTH: -+ case WLC_E_DISASSOC: -+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf); -+ break; -+ -+ case WLC_E_ASSOC_IND: -+ case WLC_E_REASSOC_IND: -+ -+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf); -+ break; -+ -+ case WLC_E_ASSOC: -+ case WLC_E_REASSOC: -+ if (status == WLC_E_STATUS_SUCCESS) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf); -+ } else if (status == WLC_E_STATUS_TIMEOUT) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf); -+ } else if (status == WLC_E_STATUS_FAIL) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", -+ event_name, eabuf, (int)reason); -+ } else { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, unexpected status %d\n", -+ event_name, eabuf, (int)status); -+ } -+ break; -+ -+ case WLC_E_DEAUTH_IND: -+ case WLC_E_DISASSOC_IND: -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason); -+ break; -+ -+ case WLC_E_AUTH: -+ case WLC_E_AUTH_IND: -+ if (auth_type == DOT11_OPEN_SYSTEM) -+ auth_str = "Open System"; -+ else if (auth_type == DOT11_SHARED_KEY) -+ auth_str = "Shared Key"; -+ else { -+ snprintf(err_msg, sizeof(err_msg), "AUTH unknown: %d", (int)auth_type); -+ auth_str = err_msg; -+ } -+ if (event_type == WLC_E_AUTH_IND) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str); -+ } else if (status == WLC_E_STATUS_SUCCESS) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, SUCCESS\n", -+ event_name, eabuf, auth_str); -+ } else if (status == WLC_E_STATUS_TIMEOUT) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", -+ event_name, eabuf, auth_str); -+ } else if (status == WLC_E_STATUS_FAIL) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", -+ event_name, eabuf, auth_str, (int)reason); -+ } -+ BCM_REFERENCE(auth_str); -+ -+ break; -+ -+ case WLC_E_JOIN: -+ case WLC_E_ROAM: -+ case WLC_E_SET_SSID: -+ if (status == WLC_E_STATUS_SUCCESS) { -+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf); -+ } else if (status == WLC_E_STATUS_FAIL) { -+ AP6210_DEBUG("MACEVENT: %s, failed\n", event_name); -+ } else if (status == WLC_E_STATUS_NO_NETWORKS) { -+ AP6210_DEBUG("MACEVENT: %s, no networks found\n", event_name); -+ } else { -+ AP6210_DEBUG("MACEVENT: %s, unexpected status %d\n", -+ event_name, (int)status); -+ } -+ break; -+ -+ case WLC_E_BEACON_RX: -+ if (status == WLC_E_STATUS_SUCCESS) { -+ AP6210_DEBUG("MACEVENT: %s, SUCCESS\n", event_name); -+ } else if (status == WLC_E_STATUS_FAIL) { -+ AP6210_DEBUG("MACEVENT: %s, FAIL\n", event_name); -+ } else { -+ AP6210_DEBUG("MACEVENT: %s, status %d\n", event_name, status); -+ } -+ break; -+ -+ case WLC_E_LINK: -+ AP6210_DEBUG("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN"); -+ BCM_REFERENCE(link); -+ break; -+ -+ case WLC_E_MIC_ERROR: -+ AP6210_DEBUG("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", -+ event_name, eabuf, group, flush_txq); -+ BCM_REFERENCE(group); -+ BCM_REFERENCE(flush_txq); -+ break; -+ -+ case WLC_E_ICV_ERROR: -+ case WLC_E_UNICAST_DECODE_ERROR: -+ case WLC_E_MULTICAST_DECODE_ERROR: -+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", -+ event_name, eabuf); -+ break; -+ -+ case WLC_E_TXFAIL: -+ AP6210_DEBUG("MACEVENT: %s, RA %s\n", event_name, eabuf); -+ break; -+ -+ case WLC_E_SCAN_COMPLETE: -+ case WLC_E_ASSOC_REQ_IE: -+ case WLC_E_ASSOC_RESP_IE: -+ case WLC_E_PMKID_CACHE: -+ AP6210_DEBUG("MACEVENT: %s\n", event_name); -+ break; -+ -+ case WLC_E_PFN_NET_FOUND: -+ case WLC_E_PFN_NET_LOST: -+ case WLC_E_PFN_SCAN_COMPLETE: -+ case WLC_E_PFN_SCAN_NONE: -+ case WLC_E_PFN_SCAN_ALLGONE: -+ AP6210_DEBUG("PNOEVENT: %s\n", event_name); -+ break; -+ -+ case WLC_E_PSK_SUP: -+ case WLC_E_PRUNE: -+ AP6210_DEBUG("MACEVENT: %s, status %d, reason %d\n", -+ event_name, (int)status, (int)reason); -+ break; -+ -+#ifdef WIFI_ACT_FRAME -+ case WLC_E_ACTION_FRAME: -+ AP6210_DEBUG("MACEVENT: %s Bssid %s\n", event_name, eabuf); -+ break; -+#endif /* WIFI_ACT_FRAME */ -+ -+ case WLC_E_TRACE: { -+ static uint32 seqnum_prev = 0; -+ msgtrace_hdr_t hdr; -+ uint32 nblost; -+ char *s, *p; -+ -+ buf = (uchar *) event_data; -+ memcpy(&hdr, buf, MSGTRACE_HDRLEN); -+ -+ if (hdr.version != MSGTRACE_VERSION) { -+ AP6210_DEBUG("MACEVENT: %s [unsupported version --> " -+ "dhd version:%d dongle version:%d]\n", -+ event_name, MSGTRACE_VERSION, hdr.version); -+ /* Reset datalen to avoid display below */ -+ datalen = 0; -+ break; -+ } -+ -+ /* There are 2 bytes available at the end of data */ -+ buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; -+ -+ if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { -+ AP6210_DEBUG("WLC_E_TRACE: [Discarded traces in dongle -->" -+ "discarded_bytes %d discarded_printf %d]\n", -+ ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); -+ } -+ -+ nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; -+ if (nblost > 0) { -+ AP6210_DEBUG("WLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", -+ ntoh32(hdr.seqnum), nblost); -+ } -+ seqnum_prev = ntoh32(hdr.seqnum); -+ -+ /* Display the trace buffer. Advance from \n to \n to avoid display big -+ * printf (issue with Linux printk ) -+ */ -+ p = (char *)&buf[MSGTRACE_HDRLEN]; -+ while ((s = strstr(p, "\n")) != NULL) { -+ *s = '\0'; -+ AP6210_DEBUG("%s\n", p); -+ p = s+1; -+ } -+ AP6210_DEBUG("%s\n", p); -+ -+ /* Reset datalen to avoid display below */ -+ datalen = 0; -+ break; -+ } -+ -+ -+ case WLC_E_RSSI: -+ AP6210_DEBUG("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data))); -+ break; -+ -+ case WLC_E_SERVICE_FOUND: -+ case WLC_E_P2PO_ADD_DEVICE: -+ case WLC_E_P2PO_DEL_DEVICE: -+ AP6210_DEBUG("MACEVENT: %s, MAC: %s\n", event_name, eabuf); -+ break; -+ -+ default: -+ AP6210_DEBUG("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", -+ event_name, event_type, eabuf, (int)status, (int)reason, -+ (int)auth_type); -+ break; -+ } -+ -+ /* show any appended data */ -+ if (datalen) { -+ buf = (uchar *) event_data; -+ AP6210_DEBUG(" data (%d) : ", datalen); -+ for (i = 0; i < datalen; i++) -+ AP6210_DUMP(" 0x%02x ", *buf++); -+ AP6210_DUMP("\n"); -+ } -+} -+#endif /* SHOW_EVENTS */ -+ -+int -+wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, -+ wl_event_msg_t *event, void **data_ptr) -+{ -+ /* check whether packet is a BRCM event pkt */ -+ bcm_event_t *pvt_data = (bcm_event_t *)pktdata; -+ uint8 *event_data; -+ uint32 type, status, datalen; -+ uint16 flags; -+ int evlen; -+ -+ if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { -+ AP6210_ERR("%s: mismatched OUI, bailing\n", __FUNCTION__); -+ return (BCME_ERROR); -+ } -+ -+ /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ -+ if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { -+ AP6210_ERR("%s: mismatched subtype, bailing\n", __FUNCTION__); -+ return (BCME_ERROR); -+ } -+ -+ *data_ptr = &pvt_data[1]; -+ event_data = *data_ptr; -+ -+ /* memcpy since BRCM event pkt may be unaligned. */ -+ memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); -+ -+ type = ntoh32_ua((void *)&event->event_type); -+ flags = ntoh16_ua((void *)&event->flags); -+ status = ntoh32_ua((void *)&event->status); -+ datalen = ntoh32_ua((void *)&event->datalen); -+ evlen = datalen + sizeof(bcm_event_t); -+ -+ switch (type) { -+#ifdef PROP_TXSTATUS -+ case WLC_E_FIFO_CREDIT_MAP: -+ dhd_wlfc_event(dhd_pub->info); -+ dhd_wlfc_FIFOcreditmap_event(dhd_pub->info, event_data); -+ AP6210_DEBUG("WLC_E_FIFO_CREDIT_MAP:(AC0,AC1,AC2,AC3),(BC_MC),(OTHER): " -+ "(%d,%d,%d,%d),(%d),(%d)\n", event_data[0], event_data[1], -+ event_data[2], -+ event_data[3], event_data[4], event_data[5]); -+ break; -+#endif -+ -+ case WLC_E_IF: -+ { -+ dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; -+#ifdef PROP_TXSTATUS -+ { -+ uint8* ea = pvt_data->eth.ether_dhost; -+ AP6210_DEBUG("WLC_E_IF: idx:%d, action:%s, iftype:%s, " -+ "[%02x:%02x:%02x:%02x:%02x:%02x]\n", -+ ifevent->ifidx, -+ ((ifevent->action == WLC_E_IF_ADD) ? "ADD":"DEL"), -+ ((ifevent->is_AP == 0) ? "STA":"AP "), -+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]); -+ (void)ea; -+ if (ifevent->action == WLC_E_IF_CHANGE) -+ dhd_wlfc_interface_event(dhd_pub->info, -+ eWLFC_MAC_ENTRY_ACTION_UPDATE, -+ ifevent->ifidx, ifevent->is_AP, ea); -+ else -+ dhd_wlfc_interface_event(dhd_pub->info, -+ ((ifevent->action == WLC_E_IF_ADD) ? -+ eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL), -+ ifevent->ifidx, ifevent->is_AP, ea); -+ -+ -+ /* dhd already has created an interface by default, for 0 */ -+ if (ifevent->ifidx == 0) -+ break; -+ } -+#endif /* PROP_TXSTATUS */ -+ -+#ifdef WL_CFG80211 -+ if (wl_cfg80211_is_progress_ifchange()) { -+ AP6210_ERR("%s: ifidx %d for %s action %d\n", -+ __FUNCTION__, ifevent->ifidx, -+ event->ifname, ifevent->action); -+ if (ifevent->action == WLC_E_IF_ADD || -+ ifevent->action == WLC_E_IF_CHANGE) -+ wl_cfg80211_notify_ifchange(); -+ return (BCME_OK); -+ } -+#endif /* WL_CFG80211 */ -+ if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) { -+ if (ifevent->action == WLC_E_IF_ADD) { -+ if (dhd_add_if(dhd_pub->info, ifevent->ifidx, -+ NULL, event->ifname, -+ event->addr.octet, -+ ifevent->flags, ifevent->bssidx)) { -+ AP6210_ERR("%s: dhd_add_if failed!!" -+ " ifidx: %d for %s\n", -+ __FUNCTION__, -+ ifevent->ifidx, -+ event->ifname); -+ return (BCME_ERROR); -+ } -+ } -+ else if (ifevent->action == WLC_E_IF_DEL) -+ dhd_del_if(dhd_pub->info, ifevent->ifidx); -+ } else { -+#ifndef PROP_TXSTATUS -+ AP6210_ERR("%s: Invalid ifidx %d for %s\n", -+ __FUNCTION__, ifevent->ifidx, event->ifname); -+#endif /* !PROP_TXSTATUS */ -+ } -+ } -+ /* send up the if event: btamp user needs it */ -+ *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname); -+ /* push up to external supp/auth */ -+ dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); -+ break; -+ -+ -+#ifdef WLMEDIA_HTSF -+ case WLC_E_HTSFSYNC: -+ htsf_update(dhd_pub->info, event_data); -+ break; -+#endif /* WLMEDIA_HTSF */ -+#if defined(NDIS630) -+ case WLC_E_NDIS_LINK: -+ break; -+#else /* defined(NDIS630) && defined(BCMDONGLEHOST) */ -+ case WLC_E_NDIS_LINK: { -+ uint32 temp = hton32(WLC_E_LINK); -+ -+ memcpy((void *)(&pvt_data->event.event_type), &temp, -+ sizeof(pvt_data->event.event_type)); -+ } -+#endif -+ /* These are what external supplicant/authenticator wants */ -+ /* fall through */ -+ case WLC_E_LINK: -+ case WLC_E_DEAUTH: -+ case WLC_E_DEAUTH_IND: -+ case WLC_E_DISASSOC: -+ case WLC_E_DISASSOC_IND: -+ AP6210_DEBUG("%s: Link event %d, flags %x, status %x\n", -+ __FUNCTION__, type, flags, status); -+ /* fall through */ -+ default: -+ *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname); -+ /* push up to external supp/auth */ -+ dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); -+ AP6210_DEBUG("%s: MAC event %d, flags %x, status %x\n", -+ __FUNCTION__, type, flags, status); -+ BCM_REFERENCE(flags); -+ BCM_REFERENCE(status); -+ -+ /* put it back to WLC_E_NDIS_LINK */ -+ if (type == WLC_E_NDIS_LINK) { -+ uint32 temp; -+ -+ temp = ntoh32_ua((void *)&event->event_type); -+ AP6210_DEBUG("Converted to WLC_E_LINK type %d\n", temp); -+ -+ temp = ntoh32(WLC_E_NDIS_LINK); -+ memcpy((void *)(&pvt_data->event.event_type), &temp, -+ sizeof(pvt_data->event.event_type)); -+ } -+ break; -+ } -+ -+#ifdef SHOW_EVENTS -+ wl_show_host_event(event, (void *)event_data); -+#endif /* SHOW_EVENTS */ -+ -+ return (BCME_OK); -+} -+ -+void -+wl_event_to_host_order(wl_event_msg_t * evt) -+{ -+ /* Event struct members passed from dongle to host are stored in network -+ * byte order. Convert all members to host-order. -+ */ -+ evt->event_type = ntoh32(evt->event_type); -+ evt->flags = ntoh16(evt->flags); -+ evt->status = ntoh32(evt->status); -+ evt->reason = ntoh32(evt->reason); -+ evt->auth_type = ntoh32(evt->auth_type); -+ evt->datalen = ntoh32(evt->datalen); -+ evt->version = ntoh16(evt->version); -+} -+ -+void -+dhd_print_buf(void *pbuf, int len, int bytes_per_line) -+{ -+#ifdef DHD_DEBUG -+ int i, j = 0; -+ unsigned char *buf = pbuf; -+ -+ if (bytes_per_line == 0) { -+ bytes_per_line = len; -+ } -+ -+ for (i = 0; i < len; i++) { -+ AP6210_DUMP("%2.2x", *buf++); -+ j++; -+ if (j == bytes_per_line) { -+ AP6210_DUMP("\n"); -+ j = 0; -+ } else { -+ AP6210_DUMP(":"); -+ } -+ } -+ AP6210_DUMP("\n"); -+#endif /* DHD_DEBUG */ -+} -+ -+#ifndef strtoul -+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) -+#endif -+ -+#ifdef PKT_FILTER_SUPPORT -+/* Convert user's input in hex pattern to byte-size mask */ -+static int -+wl_pattern_atoh(char *src, char *dst) -+{ -+ int i; -+ if (strncmp(src, "0x", 2) != 0 && -+ strncmp(src, "0X", 2) != 0) { -+ AP6210_ERR("Mask invalid format. Needs to start with 0x\n"); -+ return -1; -+ } -+ src = src + 2; /* Skip past 0x */ -+ if (strlen(src) % 2 != 0) { -+ AP6210_ERR("Mask invalid format. Needs to be of even length\n"); -+ return -1; -+ } -+ for (i = 0; *src != '\0'; i++) { -+ char num[3]; -+ bcm_strncpy_s(num, sizeof(num), src, 2); -+ num[2] = '\0'; -+ dst[i] = (uint8)strtoul(num, NULL, 16); -+ src += 2; -+ } -+ return i; -+} -+ -+void -+dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode) -+{ -+ char *argv[8]; -+ int i = 0; -+ const char *str; -+ int buf_len; -+ int str_len; -+ char *arg_save = 0, *arg_org = 0; -+ int rc; -+ char buf[128]; -+ wl_pkt_filter_enable_t enable_parm; -+ wl_pkt_filter_enable_t * pkt_filterp; -+ -+ if (!arg) -+ return; -+ -+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { -+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__); -+ goto fail; -+ } -+ arg_org = arg_save; -+ memcpy(arg_save, arg, strlen(arg) + 1); -+ -+ argv[i] = bcmstrtok(&arg_save, " ", 0); -+ -+ i = 0; -+ if (argv[i] == NULL) { -+ AP6210_ERR("No args provided\n"); -+ goto fail; -+ } -+ -+ str = "pkt_filter_enable"; -+ str_len = strlen(str); -+ bcm_strncpy_s(buf, sizeof(buf), str, str_len); -+ buf[str_len] = '\0'; -+ buf_len = str_len + 1; -+ -+ pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1); -+ -+ /* Parse packet filter id. */ -+ enable_parm.id = htod32(strtoul(argv[i], NULL, 0)); -+ -+ /* Parse enable/disable value. */ -+ enable_parm.enable = htod32(enable); -+ -+ buf_len += sizeof(enable_parm); -+ memcpy((char *)pkt_filterp, -+ &enable_parm, -+ sizeof(enable_parm)); -+ -+ /* Enable/disable the specified filter. */ -+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); -+ rc = rc >= 0 ? 0 : rc; -+ if (rc) -+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n", -+ __FUNCTION__, arg, rc); -+ else -+ AP6210_DEBUG("%s: successfully added pktfilter %s\n", -+ __FUNCTION__, arg); -+ -+ /* Contorl the master mode */ -+ bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf)); -+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); -+ rc = rc >= 0 ? 0 : rc; -+ if (rc) -+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n", -+ __FUNCTION__, arg, rc); -+ -+fail: -+ if (arg_org) -+ MFREE(dhd->osh, arg_org, strlen(arg) + 1); -+} -+ -+void -+dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg) -+{ -+ const char *str; -+ wl_pkt_filter_t pkt_filter; -+ wl_pkt_filter_t *pkt_filterp; -+ int buf_len; -+ int str_len; -+ int rc; -+ uint32 mask_size; -+ uint32 pattern_size; -+ char *argv[8], * buf = 0; -+ int i = 0; -+ char *arg_save = 0, *arg_org = 0; -+#define BUF_SIZE 2048 -+ -+ if (!arg) -+ return; -+ -+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) { -+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ arg_org = arg_save; -+ -+ if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) { -+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ memcpy(arg_save, arg, strlen(arg) + 1); -+ -+ if (strlen(arg) > BUF_SIZE) { -+ AP6210_ERR("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf)); -+ goto fail; -+ } -+ -+ argv[i] = bcmstrtok(&arg_save, " ", 0); -+ while (argv[i++]) -+ argv[i] = bcmstrtok(&arg_save, " ", 0); -+ -+ i = 0; -+ if (argv[i] == NULL) { -+ AP6210_ERR("No args provided\n"); -+ goto fail; -+ } -+ -+ str = "pkt_filter_add"; -+ str_len = strlen(str); -+ bcm_strncpy_s(buf, BUF_SIZE, str, str_len); -+ buf[ str_len ] = '\0'; -+ buf_len = str_len + 1; -+ -+ pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); -+ -+ /* Parse packet filter id. */ -+ pkt_filter.id = htod32(strtoul(argv[i], NULL, 0)); -+ -+ if (argv[++i] == NULL) { -+ AP6210_ERR("Polarity not provided\n"); -+ goto fail; -+ } -+ -+ /* Parse filter polarity. */ -+ pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0)); -+ -+ if (argv[++i] == NULL) { -+ AP6210_ERR("Filter type not provided\n"); -+ goto fail; -+ } -+ -+ /* Parse filter type. */ -+ pkt_filter.type = htod32(strtoul(argv[i], NULL, 0)); -+ -+ if (argv[++i] == NULL) { -+ AP6210_ERR("Offset not provided\n"); -+ goto fail; -+ } -+ -+ /* Parse pattern filter offset. */ -+ pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0)); -+ -+ if (argv[++i] == NULL) { -+ AP6210_ERR("Bitmask not provided\n"); -+ goto fail; -+ } -+ -+ /* Parse pattern filter mask. */ -+ mask_size = -+ htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern)); -+ -+ if (argv[++i] == NULL) { -+ AP6210_ERR("Pattern not provided\n"); -+ goto fail; -+ } -+ -+ /* Parse pattern filter pattern. */ -+ pattern_size = -+ htod32(wl_pattern_atoh(argv[i], -+ (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size])); -+ -+ if (mask_size != pattern_size) { -+ AP6210_ERR("Mask and pattern not the same size\n"); -+ goto fail; -+ } -+ -+ pkt_filter.u.pattern.size_bytes = mask_size; -+ buf_len += WL_PKT_FILTER_FIXED_LEN; -+ buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); -+ -+ /* Keep-alive attributes are set in local variable (keep_alive_pkt), and -+ ** then memcpy'ed into buffer (keep_alive_pktp) since there is no -+ ** guarantee that the buffer is properly aligned. -+ */ -+ memcpy((char *)pkt_filterp, -+ &pkt_filter, -+ WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); -+ -+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); -+ rc = rc >= 0 ? 0 : rc; -+ -+ if (rc) -+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n", -+ __FUNCTION__, arg, rc); -+ else -+ AP6210_DEBUG("%s: successfully added pktfilter %s\n", -+ __FUNCTION__, arg); -+ -+fail: -+ if (arg_org) -+ MFREE(dhd->osh, arg_org, strlen(arg) + 1); -+ -+ if (buf) -+ MFREE(dhd->osh, buf, BUF_SIZE); -+} -+#endif /* PKT_FILTER_SUPPORT */ -+ -+/* ========================== */ -+/* ==== ARP OFFLOAD SUPPORT = */ -+/* ========================== */ -+#ifdef ARP_OFFLOAD_SUPPORT -+void -+dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode) -+{ -+ char iovbuf[32]; -+ int retcode; -+ -+ bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); -+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ retcode = retcode >= 0 ? 0 : retcode; -+ if (retcode) -+ AP6210_DEBUG("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n", -+ __FUNCTION__, arp_mode, retcode); -+ else -+ AP6210_DEBUG("%s: successfully set ARP offload mode to 0x%x\n", -+ __FUNCTION__, arp_mode); -+} -+ -+void -+dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable) -+{ -+ char iovbuf[32]; -+ int retcode; -+ -+ bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); -+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ retcode = retcode >= 0 ? 0 : retcode; -+ if (retcode) -+ AP6210_DEBUG("%s: failed to enabe ARP offload to %d, retcode = %d\n", -+ __FUNCTION__, arp_enable, retcode); -+ else -+ AP6210_DEBUG("%s: successfully enabed ARP offload to %d\n", -+ __FUNCTION__, arp_enable); -+ if (arp_enable) { -+ uint32 version; -+ bcm_mkiovar("arp_version", 0, 0, iovbuf, sizeof(iovbuf)); -+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0); -+ if (retcode) { -+ AP6210_DEBUG("%s: fail to get version (maybe version 1:retcode = %d\n", -+ __FUNCTION__, retcode); -+ dhd->arp_version = 1; -+ } -+ else { -+ memcpy(&version, iovbuf, sizeof(version)); -+ AP6210_DEBUG("%s: ARP Version= %x\n", __FUNCTION__, version); -+ dhd->arp_version = version; -+ } -+ } -+} -+ -+void -+dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx) -+{ -+ int ret = 0; -+ int iov_len = 0; -+ char iovbuf[128]; -+ -+ if (dhd == NULL) return; -+ if (dhd->arp_version == 1) -+ idx = 0; -+ -+ iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx) < 0)) -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret); -+} -+ -+void -+dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx) -+{ -+ int ret = 0; -+ int iov_len = 0; -+ char iovbuf[128]; -+ -+ if (dhd == NULL) return; -+ if (dhd->arp_version == 1) -+ idx = 0; -+ -+ iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx)) < 0) -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret); -+} -+ -+void -+dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx) -+{ -+ int iov_len = 0; -+ char iovbuf[32]; -+ int retcode; -+ -+ -+ if (dhd == NULL) return; -+ if (dhd->arp_version == 1) -+ idx = 0; -+ iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr, -+ sizeof(ipaddr), iovbuf, sizeof(iovbuf)); -+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx); -+ -+ if (retcode) -+ AP6210_DEBUG("%s: ARP ip addr add failed, retcode = %d\n", -+ __FUNCTION__, retcode); -+ else -+ AP6210_DEBUG("%s: sARP H ipaddr entry added \n", -+ __FUNCTION__); -+} -+ -+int -+dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx) -+{ -+ int retcode, i; -+ int iov_len; -+ uint32 *ptr32 = buf; -+ bool clr_bottom = FALSE; -+ -+ if (!buf) -+ return -1; -+ if (dhd == NULL) return -1; -+ if (dhd->arp_version == 1) -+ idx = 0; -+ -+ iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); -+ BCM_REFERENCE(iov_len); -+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, idx); -+ -+ if (retcode) { -+ AP6210_DEBUG("%s: ioctl WLC_GET_VAR error %d\n", -+ __FUNCTION__, retcode); -+ -+ return -1; -+ } -+ -+ /* clean up the buf, ascii reminder */ -+ for (i = 0; i < MAX_IPV4_ENTRIES; i++) { -+ if (!clr_bottom) { -+ if (*ptr32 == 0) -+ clr_bottom = TRUE; -+ } else { -+ *ptr32 = 0; -+ } -+ ptr32++; -+ } -+ -+ return 0; -+} -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+/* send up locally generated event */ -+void -+dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -+{ -+ switch (ntoh32(event->event_type)) { -+#ifdef WLBTAMP -+ case WLC_E_BTA_HCI_EVENT: -+ break; -+#endif /* WLBTAMP */ -+ default: -+ break; -+ } -+ -+ /* Call per-port handler. */ -+ dhd_sendup_event(dhdp, event, data); -+} -+ -+ -+/* -+ * returns = TRUE if associated, FALSE if not associated -+ */ -+bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval) -+{ -+ char bssid[6], zbuf[6]; -+ int ret = -1; -+ -+ bzero(bssid, 6); -+ bzero(zbuf, 6); -+ -+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0); -+ AP6210_DEBUG(" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret); -+ -+ if (ret == BCME_NOTASSOCIATED) { -+ AP6210_DEBUG("%s: not associated! res:%d\n", __FUNCTION__, ret); -+ } -+ -+ if (retval) -+ *retval = ret; -+ -+ if (ret < 0) -+ return FALSE; -+ -+ if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) { -+ /* STA is assocoated BSSID is non zero */ -+ -+ if (bss_buf) { -+ /* return bss if caller provided buf */ -+ memcpy(bss_buf, bssid, ETHER_ADDR_LEN); -+ } -+ return TRUE; -+ } else { -+ AP6210_DEBUG("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__); -+ return FALSE; -+ } -+} -+ -+ -+/* Function to estimate possible DTIM_SKIP value */ -+int -+dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd) -+{ -+ int bcn_li_dtim; -+ int ret = -1; -+ int dtim_assoc = 0; -+ -+ bcn_li_dtim = dhd->suspend_bcn_li_dtim; -+ -+ /* Check if associated */ -+ if (dhd_is_associated(dhd, NULL, NULL) == FALSE) { -+ AP6210_DEBUG("%s NOT assoc ret %d\n", __FUNCTION__, ret); -+ goto exit; -+ } -+ -+ /* if assoc grab ap's dtim value */ -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD, -+ &dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) { -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret); -+ goto exit; -+ } -+ -+ AP6210_ERR("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", -+ __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL); -+ -+ /* if not assocated just eixt */ -+ if (dtim_assoc == 0) { -+ goto exit; -+ } -+ -+ /* check if sta listen interval fits into AP dtim */ -+ if (dtim_assoc > LISTEN_INTERVAL) { -+ /* AP DTIM to big for our Listen Interval : no dtim skiping */ -+ bcn_li_dtim = 1; -+ AP6210_ERR("%s DTIM=%d > Listen=%d : too big ...\n", -+ __FUNCTION__, dtim_assoc, LISTEN_INTERVAL); -+ goto exit; -+ } -+ -+ if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) { -+ /* Round up dtim_skip to fit into STAs Listen Interval */ -+ bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc); -+ AP6210_DEBUG("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim); -+ } -+ -+exit: -+ return bcn_li_dtim; -+} -+ -+/* Check if the mode supports STA MODE */ -+bool dhd_support_sta_mode(dhd_pub_t *dhd) -+{ -+ -+#ifdef WL_CFG80211 -+ if (!(dhd->op_mode & DHD_FLAG_STA_MODE)) -+ return FALSE; -+ else -+#endif /* WL_CFG80211 */ -+ return TRUE; -+} -+ -+#if defined(PNO_SUPPORT) -+int -+dhd_pno_clean(dhd_pub_t *dhd) -+{ -+ char iovbuf[128]; -+ int pfn_enabled = 0; -+ int iov_len = 0; -+ int ret; -+ -+ /* Disable pfn */ -+ iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) >= 0) { -+ /* clear pfn */ -+ iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); -+ if (iov_len) { -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, -+ iov_len, TRUE, 0)) < 0) { -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret); -+ } -+ } -+ else { -+ ret = -1; -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, iov_len); -+ } -+ } -+ else -+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret); -+ -+ return ret; -+} -+ -+int -+dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) -+{ -+ char iovbuf[128]; -+ int ret = -1; -+ -+ if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { -+ AP6210_ERR("%s error exit\n", __FUNCTION__); -+ return ret; -+ } -+ -+#ifndef WL_SCHED_SCAN -+ if (!dhd_support_sta_mode(dhd)) -+ return (ret); -+ -+ memset(iovbuf, 0, sizeof(iovbuf)); -+ -+ if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) { -+ AP6210_ERR("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__); -+ return ret; -+ } -+#endif /* !WL_SCHED_SCAN */ -+ -+ /* Enable/disable PNO */ -+ if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, -+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { -+ AP6210_ERR("%s failed for error=%d\n", __FUNCTION__, ret); -+ return ret; -+ } -+ else { -+ dhd->pno_enable = pfn_enabled; -+ AP6210_DEBUG("%s set pno as %s\n", -+ __FUNCTION__, dhd->pno_enable ? "Enable" : "Disable"); -+ } -+ } -+ else AP6210_ERR("%s failed err=%d\n", __FUNCTION__, ret); -+ -+ return ret; -+} -+ -+/* Function to execute combined scan */ -+int -+dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr, -+ int pno_repeat, int pno_freq_expo_max) -+{ -+ int err = -1; -+ char iovbuf[128]; -+ int k, i; -+ wl_pfn_param_t pfn_param; -+ wl_pfn_t pfn_element; -+ uint len = 0; -+ -+ AP6210_DEBUG("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr); -+ -+ if ((!dhd) || (!ssids_local)) { -+ AP6210_ERR("%s error exit(%s %s)\n", __FUNCTION__, -+ (!dhd)?"dhd is null":"", (!ssids_local)?"ssid is null":""); -+ err = -1; -+ return err; -+ } -+#ifndef WL_SCHED_SCAN -+ if (!dhd_support_sta_mode(dhd)) -+ return err; -+#endif /* !WL_SCHED_SCAN */ -+ -+ /* Check for broadcast ssid */ -+ for (k = 0; k < nssid; k++) { -+ if (!ssids_local[k].SSID_len) { -+ AP6210_ERR("%d: Broadcast SSID is ilegal for PNO setting\n", k); -+ return err; -+ } -+ } -+/* #define PNO_DUMP 1 */ -+#ifdef PNO_DUMP -+ { -+ int j; -+ for (j = 0; j < nssid; j++) { -+ AP6210_ERR("%d: scan for %s size =%d\n", j, -+ ssids_local[j].SSID, ssids_local[j].SSID_len); -+ } -+ } -+#endif /* PNO_DUMP */ -+ -+ /* clean up everything */ -+ if ((err = dhd_pno_clean(dhd)) < 0) { -+ AP6210_ERR("%s failed error=%d\n", __FUNCTION__, err); -+ return err; -+ } -+ memset(iovbuf, 0, sizeof(iovbuf)); -+ memset(&pfn_param, 0, sizeof(pfn_param)); -+ memset(&pfn_element, 0, sizeof(pfn_element)); -+ -+ /* set pfn parameters */ -+ pfn_param.version = htod32(PFN_VERSION); -+ pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); -+ -+ /* check and set extra pno params */ -+ if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { -+ pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); -+ pfn_param.repeat = (uchar) (pno_repeat); -+ pfn_param.exp = (uchar) (pno_freq_expo_max); -+ } -+ /* set up pno scan fr */ -+ if (scan_fr != 0) -+ pfn_param.scan_freq = htod32(scan_fr); -+ -+ if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { -+ AP6210_ERR("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC); -+ return err; -+ } -+ if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { -+ AP6210_ERR("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC); -+ return err; -+ } -+ -+ len = bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); -+ if ((err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { -+ AP6210_ERR("%s pfn_set failed for error=%d\n", -+ __FUNCTION__, err); -+ return err; -+ } -+ -+ /* set all pfn ssid */ -+ for (i = 0; i < nssid; i++) { -+ -+ pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); -+ pfn_element.auth = (DOT11_OPEN_SYSTEM); -+ pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); -+ pfn_element.wsec = htod32(0); -+ pfn_element.infra = htod32(1); -+ pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); -+ memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); -+ pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; -+ -+ if ((len = -+ bcm_mkiovar("pfn_add", (char *)&pfn_element, -+ sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { -+ if ((err = -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { -+ AP6210_ERR("%s failed for i=%d error=%d\n", -+ __FUNCTION__, i, err); -+ return err; -+ } -+ else -+ AP6210_DEBUG("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", -+ __FUNCTION__, pfn_param.scan_freq, -+ pfn_param.repeat, pfn_param.exp); -+ } -+ else AP6210_ERR("%s failed err=%d\n", __FUNCTION__, err); -+ } -+ -+ /* Enable PNO */ -+ /* dhd_pno_enable(dhd, 1); */ -+ return err; -+} -+ -+int -+dhd_pno_get_status(dhd_pub_t *dhd) -+{ -+ int ret = -1; -+ -+ if (!dhd) -+ return ret; -+ else -+ return (dhd->pno_enable); -+} -+ -+#endif /* OEM_ANDROID && PNO_SUPPORT */ -+ -+#if defined(KEEP_ALIVE) -+int dhd_keep_alive_onoff(dhd_pub_t *dhd) -+{ -+ char buf[256]; -+ const char *str; -+ wl_mkeep_alive_pkt_t mkeep_alive_pkt; -+ wl_mkeep_alive_pkt_t *mkeep_alive_pktp; -+ int buf_len; -+ int str_len; -+ int res = -1; -+ -+ if (!dhd_support_sta_mode(dhd)) -+ return res; -+ -+ AP6210_DEBUG("%s execution\n", __FUNCTION__); -+ -+ str = "mkeep_alive"; -+ str_len = strlen(str); -+ strncpy(buf, str, str_len); -+ buf[ str_len ] = '\0'; -+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1); -+ mkeep_alive_pkt.period_msec = CUSTOM_KEEP_ALIVE_SETTING; -+ buf_len = str_len + 1; -+ mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION); -+ mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN); -+ /* Setup keep alive zero for null packet generation */ -+ mkeep_alive_pkt.keep_alive_id = 0; -+ mkeep_alive_pkt.len_bytes = 0; -+ buf_len += WL_MKEEP_ALIVE_FIXED_LEN; -+ bzero(mkeep_alive_pkt.data, sizeof(mkeep_alive_pkt.data)); -+ /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and -+ * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no -+ * guarantee that the buffer is properly aligned. -+ */ -+ memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN); -+ -+ res = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0); -+ -+ return res; -+} -+#endif /* defined(KEEP_ALIVE) */ -+/* Android ComboSCAN support */ -+ -+/* -+ * data parsing from ComboScan tlv list -+*/ -+int -+wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token, -+ int input_size, int *bytes_left) -+{ -+ char* str; -+ uint16 short_temp; -+ uint32 int_temp; -+ -+ if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { -+ AP6210_ERR("%s error paramters\n", __FUNCTION__); -+ return -1; -+ } -+ str = *list_str; -+ -+ /* Clean all dest bytes */ -+ memset(dst, 0, dst_size); -+ while (*bytes_left > 0) { -+ -+ if (str[0] != token) { -+ AP6210_DEBUG("%s NOT Type=%d get=%d left_parse=%d \n", -+ __FUNCTION__, token, str[0], *bytes_left); -+ return -1; -+ } -+ -+ *bytes_left -= 1; -+ str += 1; -+ -+ if (input_size == 1) { -+ memcpy(dst, str, input_size); -+ } -+ else if (input_size == 2) { -+ memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)), -+ input_size); -+ } -+ else if (input_size == 4) { -+ memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)), -+ input_size); -+ } -+ -+ *bytes_left -= input_size; -+ str += input_size; -+ *list_str = str; -+ return 1; -+ } -+ return 1; -+} -+ -+/* -+ * channel list parsing from cscan tlv list -+*/ -+int -+wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, -+ int channel_num, int *bytes_left) -+{ -+ char* str; -+ int idx = 0; -+ -+ if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) { -+ AP6210_ERR("%s error paramters\n", __FUNCTION__); -+ return -1; -+ } -+ str = *list_str; -+ -+ while (*bytes_left > 0) { -+ -+ if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) { -+ *list_str = str; -+ AP6210_DEBUG("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0]); -+ return idx; -+ } -+ /* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */ -+ *bytes_left -= 1; -+ str += 1; -+ -+ if (str[0] == 0) { -+ /* All channels */ -+ channel_list[idx] = 0x0; -+ } -+ else { -+ channel_list[idx] = (uint16)str[0]; -+ AP6210_DEBUG("%s channel=%d \n", __FUNCTION__, channel_list[idx]); -+ } -+ *bytes_left -= 1; -+ str += 1; -+ -+ if (idx++ > 255) { -+ AP6210_ERR("%s Too many channels \n", __FUNCTION__); -+ return -1; -+ } -+ } -+ -+ *list_str = str; -+ return idx; -+} -+ -+/* -+ * SSIDs list parsing from cscan tlv list -+ */ -+int -+wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left) -+{ -+ char* str; -+ int idx = 0; -+ -+ if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) { -+ AP6210_ERR("%s error paramters\n", __FUNCTION__); -+ return -1; -+ } -+ str = *list_str; -+ while (*bytes_left > 0) { -+ -+ if (str[0] != CSCAN_TLV_TYPE_SSID_IE) { -+ *list_str = str; -+ AP6210_DEBUG("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]); -+ return idx; -+ } -+ -+ /* Get proper CSCAN_TLV_TYPE_SSID_IE */ -+ *bytes_left -= 1; -+ str += 1; -+ -+ if (str[0] == 0) { -+ /* Broadcast SSID */ -+ ssid[idx].SSID_len = 0; -+ memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN); -+ *bytes_left -= 1; -+ str += 1; -+ -+ AP6210_DEBUG("BROADCAST SCAN left=%d\n", *bytes_left); -+ } -+ else if (str[0] <= DOT11_MAX_SSID_LEN) { -+ /* Get proper SSID size */ -+ ssid[idx].SSID_len = str[0]; -+ *bytes_left -= 1; -+ str += 1; -+ -+ /* Get SSID */ -+ if (ssid[idx].SSID_len > *bytes_left) { -+ AP6210_ERR("%s out of memory range len=%d but left=%d\n", -+ __FUNCTION__, ssid[idx].SSID_len, *bytes_left); -+ return -1; -+ } -+ -+ memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len); -+ -+ *bytes_left -= ssid[idx].SSID_len; -+ str += ssid[idx].SSID_len; -+ -+ AP6210_DEBUG("%s :size=%d left=%d\n", -+ (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left); -+ } -+ else { -+ AP6210_ERR("### SSID size more that %d\n", str[0]); -+ return -1; -+ } -+ -+ if (idx++ > max) { -+ AP6210_ERR("%s number of SSIDs more that %d\n", __FUNCTION__, idx); -+ return -1; -+ } -+ } -+ -+ *list_str = str; -+ return idx; -+} -+ -+/* Parse a comma-separated list from list_str into ssid array, starting -+ * at index idx. Max specifies size of the ssid array. Parses ssids -+ * and returns updated idx; if idx >= max not all fit, the excess have -+ * not been copied. Returns -1 on empty string, or on ssid too long. -+ */ -+int -+wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max) -+{ -+ char* str, *ptr; -+ -+ if ((list_str == NULL) || (*list_str == NULL)) -+ return -1; -+ -+ for (str = *list_str; str != NULL; str = ptr) { -+ -+ /* check for next TAG */ -+ if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) { -+ *list_str = str + strlen(GET_CHANNEL); -+ return idx; -+ } -+ -+ if ((ptr = strchr(str, ',')) != NULL) { -+ *ptr++ = '\0'; -+ } -+ -+ if (strlen(str) > DOT11_MAX_SSID_LEN) { -+ AP6210_ERR("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN); -+ return -1; -+ } -+ -+ if (strlen(str) == 0) -+ ssid[idx].SSID_len = 0; -+ -+ if (idx < max) { -+ bzero(ssid[idx].SSID, sizeof(ssid[idx].SSID)); -+ strncpy((char*)ssid[idx].SSID, str, sizeof(ssid[idx].SSID) - 1); -+ ssid[idx].SSID_len = strlen(str); -+ } -+ idx++; -+ } -+ return idx; -+} -+ -+/* -+ * Parse channel list from iwpriv CSCAN -+ */ -+int -+wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num) -+{ -+ int num; -+ int val; -+ char* str; -+ char* endptr = NULL; -+ -+ if ((list_str == NULL)||(*list_str == NULL)) -+ return -1; -+ -+ str = *list_str; -+ num = 0; -+ while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) { -+ val = (int)strtoul(str, &endptr, 0); -+ if (endptr == str) { -+ AP6210_ERR("could not parse channel number starting at" -+ " substring \"%s\" in list:\n%s\n", -+ str, *list_str); -+ return -1; -+ } -+ str = endptr + strspn(endptr, " ,"); -+ -+ if (num == channel_num) { -+ AP6210_ERR("too many channels (more than %d) in channel list:\n%s\n", -+ channel_num, *list_str); -+ return -1; -+ } -+ -+ channel_list[num++] = (uint16)val; -+ } -+ *list_str = str; -+ return num; -+} -diff --git a/drivers/net/wireless/ap6210/dhd_custom_gpio.c b/drivers/net/wireless/ap6210/dhd_custom_gpio.c -new file mode 100644 -index 0000000..afdb9b3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_custom_gpio.c -@@ -0,0 +1,313 @@ -+/* -+* Customer code to add GPIO control during WLAN start/stop -+* Copyright (C) 1999-2012, Broadcom Corporation -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2 (the "GPL"), -+* available at http://www.broadcom.com/licenses/GPLv2.php, with the -+* following added to such license: -+* -+* As a special exception, the copyright holders of this software give you -+* permission to link this software with independent modules, and to copy and -+* distribute the resulting executable under terms of your choice, provided that -+* you also meet, for each linked independent module, the terms and conditions of -+* the license of that module. An independent module is a module which is not -+* derived from this software. The special exception does not apply to any -+* modifications of the software. -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a license -+* other than the GPL, without Broadcom's express prior written consent. -+* -+* $Id: dhd_custom_gpio.c 353167 2012-08-24 22:11:30Z $ -+*/ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+extern void sunximmc_rescan_card(unsigned id, unsigned insert); -+ -+#ifdef CUSTOMER_HW -+#include -+#if defined(CUSTOMER_OOB) -+extern int bcm_wlan_get_oob_irq(void); -+#endif -+extern void bcm_wlan_power_off(int); -+extern void bcm_wlan_power_on(int); -+#endif /* CUSTOMER_HW */ -+#if defined(CUSTOMER_HW2) -+#ifdef CONFIG_WIFI_CONTROL_FUNC -+int wifi_set_power(int on, unsigned long msec); -+int wifi_get_irq_number(unsigned long *irq_flags_ptr); -+int wifi_get_mac_addr(unsigned char *buf); -+void *wifi_get_country_code(char *ccode); -+#else -+int wifi_set_power(int on, unsigned long msec) { return -1; } -+int wifi_get_irq_number(unsigned long *irq_flags_ptr) { return -1; } -+int wifi_get_mac_addr(unsigned char *buf) { return -1; } -+void *wifi_get_country_code(char *ccode) { return NULL; } -+#endif /* CONFIG_WIFI_CONTROL_FUNC */ -+#endif -+ -+#if defined(OOB_INTR_ONLY) -+ -+#if defined(BCMLXSDMMC) -+extern int sdioh_mmc_irq(int irq); -+#endif /* (BCMLXSDMMC) */ -+ -+#ifdef CUSTOMER_HW3 -+#include -+#endif -+ -+/* Customer specific Host GPIO defintion */ -+static int dhd_oob_gpio_num = 2; -+ -+module_param(dhd_oob_gpio_num, int, 0644); -+MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); -+ -+/* This function will return: -+ * 1) return : Host gpio interrupt number per customer platform -+ * 2) irq_flags_ptr : Type of Host interrupt as Level or Edge -+ * -+ * NOTE : -+ * Customer should check his platform definitions -+ * and his Host Interrupt spec -+ * to figure out the proper setting for his platform. -+ * Broadcom provides just reference settings as example. -+ * -+ */ -+int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) -+{ -+ int host_oob_irq = -1; -+ -+#if defined(CUSTOMER_HW2) -+ host_oob_irq = wifi_get_irq_number(irq_flags_ptr); -+ -+#elif defined(CUSTOMER_OOB) -+ host_oob_irq = bcm_wlan_get_oob_irq(); -+ AP6210_DEBUG("irq=%d, flags=0x%08lx\n", host_oob_irq, *irq_flags_ptr); -+#else -+#if defined(CUSTOM_OOB_GPIO_NUM) -+ if (dhd_oob_gpio_num < 0) { -+ dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; -+ } -+#endif /* CUSTOMER_OOB_GPIO_NUM */ -+ -+ if (dhd_oob_gpio_num < 0) { -+ AP6210_ERR("%s: ERROR customer specific Host GPIO is NOT defined \n", -+ __FUNCTION__); -+ return (dhd_oob_gpio_num); -+ } -+ -+ AP6210_ERR("%s: customer specific Host GPIO number is (%d)\n", -+ __FUNCTION__, dhd_oob_gpio_num); -+ -+#if defined CUSTOMER_HW -+ AP6210_ERR("%s: should not be here!\n", __FUNCTION__); -+#elif defined CUSTOMER_HW3 -+ gpio_request(dhd_oob_gpio_num, "oob irq"); -+ host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); -+ gpio_direction_input(dhd_oob_gpio_num); -+#endif /* CUSTOMER_HW */ -+#endif -+ -+ return (host_oob_irq); -+} -+#endif -+ -+/* Customer function to control hw specific wlan gpios */ -+void -+dhd_customer_gpio_wlan_ctrl(int onoff) -+{ -+ static int sdc_id = 3; -+ -+ switch (onoff) { -+ case WLAN_RESET_OFF: -+ AP6210_DEBUG("%s: call customer specific GPIO to insert WLAN RESET\n", -+ __FUNCTION__); -+#ifdef CUSTOMER_HW -+ ap6210_gpio_wifi_power(0); -+#endif /* CUSTOMER_HW */ -+#if defined(CUSTOMER_HW2) -+ wifi_set_power(0, 0); -+#endif -+ mdelay(100); -+ AP6210_ERR("WLAN placed in RESET\n"); -+ break; -+ -+ case WLAN_RESET_ON: -+ AP6210_DEBUG("%s: callc customer specific GPIO to remove WLAN RESET\n", -+ __FUNCTION__); -+#ifdef CUSTOMER_HW -+ ap6210_gpio_wifi_power(1); -+#endif /* CUSTOMER_HW */ -+#if defined(CUSTOMER_HW2) -+ wifi_set_power(1, 0); -+#endif -+ mdelay(100); -+ AP6210_ERR("WLAN going back to live\n"); -+ break; -+ -+ case WLAN_POWER_OFF: -+ AP6210_DEBUG("%s: call customer specific GPIO to turn off WL_REG_ON\n", -+ __FUNCTION__); -+#ifdef CUSTOMER_HW -+ ap6210_gpio_wifi_power(0); -+ sunximmc_rescan_card(sdc_id, 0); -+#endif /* CUSTOMER_HW */ -+ AP6210_ERR("WLAN placed in POWER OFF\n"); -+ break; -+ -+ case WLAN_POWER_ON: -+ AP6210_DEBUG("%s: call customer specific GPIO to turn on WL_REG_ON\n", -+ __FUNCTION__); -+#ifdef CUSTOMER_HW -+ ap6210_gpio_wifi_power(1); -+ sunximmc_rescan_card(sdc_id, 1); -+ /* Lets customer power to get stable */ -+#endif /* CUSTOMER_HW */ -+ mdelay(100); -+ AP6210_ERR("WLAN placed in POWER ON\n"); -+ break; -+ } -+} -+ -+#ifdef GET_CUSTOM_MAC_ENABLE -+/* Function to get custom MAC address */ -+int -+dhd_custom_get_mac_address(unsigned char *buf) -+{ -+ int ret = 0; -+ -+ AP6210_DEBUG("%s Enter\n", __FUNCTION__); -+ if (!buf) -+ return -EINVAL; -+ -+ /* Customer access to MAC address stored outside of DHD driver */ -+#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -+ ret = wifi_get_mac_addr(buf); -+#endif -+ -+#ifdef EXAMPLE_GET_MAC -+ /* EXAMPLE code */ -+ { -+ struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}}; -+ bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); -+ } -+#endif /* EXAMPLE_GET_MAC */ -+ -+ return ret; -+} -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+ -+/* Customized Locale table : OPTIONAL feature */ -+const struct cntry_locales_custom translate_custom_table[] = { -+/* Table should be filled out based on custom platform regulatory requirement */ -+#ifdef EXAMPLE_TABLE -+ {"", "XY", 4}, /* Universal if Country code is unknown or empty */ -+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */ -+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */ -+ {"EU", "EU", 5}, /* European union countries to : EU regrev 05 */ -+ {"AT", "EU", 5}, -+ {"BE", "EU", 5}, -+ {"BG", "EU", 5}, -+ {"CY", "EU", 5}, -+ {"CZ", "EU", 5}, -+ {"DK", "EU", 5}, -+ {"EE", "EU", 5}, -+ {"FI", "EU", 5}, -+ {"FR", "EU", 5}, -+ {"DE", "EU", 5}, -+ {"GR", "EU", 5}, -+ {"HU", "EU", 5}, -+ {"IE", "EU", 5}, -+ {"IT", "EU", 5}, -+ {"LV", "EU", 5}, -+ {"LI", "EU", 5}, -+ {"LT", "EU", 5}, -+ {"LU", "EU", 5}, -+ {"MT", "EU", 5}, -+ {"NL", "EU", 5}, -+ {"PL", "EU", 5}, -+ {"PT", "EU", 5}, -+ {"RO", "EU", 5}, -+ {"SK", "EU", 5}, -+ {"SI", "EU", 5}, -+ {"ES", "EU", 5}, -+ {"SE", "EU", 5}, -+ {"GB", "EU", 5}, -+ {"KR", "XY", 3}, -+ {"AU", "XY", 3}, -+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */ -+ {"TW", "XY", 3}, -+ {"AR", "XY", 3}, -+ {"MX", "XY", 3}, -+ {"IL", "IL", 0}, -+ {"CH", "CH", 0}, -+ {"TR", "TR", 0}, -+ {"NO", "NO", 0}, -+#endif /* EXMAPLE_TABLE */ -+}; -+ -+ -+/* Customized Locale convertor -+* input : ISO 3166-1 country abbreviation -+* output: customized cspec -+*/ -+void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) -+{ -+#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+ -+ struct cntry_locales_custom *cloc_ptr; -+ -+ if (!cspec) -+ return; -+ -+ cloc_ptr = wifi_get_country_code(country_iso_code); -+ if (cloc_ptr) { -+ strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ); -+ cspec->rev = cloc_ptr->custom_locale_rev; -+ } -+ return; -+#else -+ int size, i; -+ -+ size = ARRAYSIZE(translate_custom_table); -+ -+ if (cspec == 0) -+ return; -+ -+ if (size == 0) -+ return; -+ -+ for (i = 0; i < size; i++) { -+ if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) { -+ memcpy(cspec->ccode, -+ translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ); -+ cspec->rev = translate_custom_table[i].custom_locale_rev; -+ return; -+ } -+ } -+#ifdef EXAMPLE_TABLE -+ /* if no country code matched return first universal code from translate_custom_table */ -+ memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ); -+ cspec->rev = translate_custom_table[0].custom_locale_rev; -+#endif /* EXMAPLE_TABLE */ -+ return; -+#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) */ -+} -diff --git a/drivers/net/wireless/ap6210/dhd_dbg.h b/drivers/net/wireless/ap6210/dhd_dbg.h -new file mode 100644 -index 0000000..67cd2e5 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_dbg.h -@@ -0,0 +1,79 @@ -+/* -+ * Debug/trace/assert driver definitions for Dongle Host Driver. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_dbg.h 353490 2012-08-27 21:10:02Z $ -+ */ -+ -+#ifndef _dhd_dbg_ -+#define _dhd_dbg_ -+ -+#define USE_NET_RATELIMIT net_ratelimit() -+ -+#if defined(DHD_DEBUG) -+ -+#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) -+#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) -+#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL) -+#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL) -+#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL) -+#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL) -+#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL) -+#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL) -+#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL) -+#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL) -+#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL) -+#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) -+#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) -+#define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL) -+#define DHD_REORDER_ON() (dhd_msg_level & DHD_REORDER_VAL) -+ -+#else /* defined(BCMDBG) || defined(DHD_DEBUG) */ -+ -+#define DHD_ERROR_ON() 0 -+#define DHD_TRACE_ON() 0 -+#define DHD_INFO_ON() 0 -+#define DHD_DATA_ON() 0 -+#define DHD_CTL_ON() 0 -+#define DHD_TIMER_ON() 0 -+#define DHD_HDRS_ON() 0 -+#define DHD_BYTES_ON() 0 -+#define DHD_INTR_ON() 0 -+#define DHD_GLOM_ON() 0 -+#define DHD_EVENT_ON() 0 -+#define DHD_BTA_ON() 0 -+#define DHD_ISCAN_ON() 0 -+#define DHD_ARPOE_ON() 0 -+#define DHD_REORDER_ON() 0 -+#endif -+ -+#define DHD_LOG(args) -+ -+#define DHD_BLOG(cp, size) -+ -+#define DHD_NONE(args) -+extern int dhd_msg_level; -+ -+/* Defines msg bits */ -+#include -+ -+#endif /* _dhd_dbg_ */ -diff --git a/drivers/net/wireless/ap6210/dhd_gpio.c b/drivers/net/wireless/ap6210/dhd_gpio.c -new file mode 100644 -index 0000000..dae0dd3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_gpio.c -@@ -0,0 +1,47 @@ -+/* -+* Customer code to add GPIO control during WLAN start/stop -+* Copyright (C) 1999-2011, Broadcom Corporation -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2 (the "GPL"), -+* available at http://www.broadcom.com/licenses/GPLv2.php, with the -+* following added to such license: -+* -+* As a special exception, the copyright holders of this software give you -+* permission to link this software with independent modules, and to copy and -+* distribute the resulting executable under terms of your choice, provided that -+* you also meet, for each linked independent module, the terms and conditions of -+* the license of that module. An independent module is a module which is not -+* derived from this software. The special exception does not apply to any -+* modifications of the software. -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a license -+* other than the GPL, without Broadcom's express prior written consent. -+* -+* $Id: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $ -+*/ -+ -+#include -+ -+#include -+#include -+ -+#ifdef CUSTOMER_HW -+ -+extern int __gpio_to_irq(unsigned gpio); -+extern int gpio_direction_input(unsigned gpio); -+extern int gpio_request(unsigned gpio, const char *label); -+extern void gpio_free(unsigned gpio); -+ -+#ifdef CUSTOMER_OOB -+extern int wl_host_wake_irqno; -+int bcm_wlan_get_oob_irq(void) -+{ -+ return wl_host_wake_irqno; -+} -+#endif -+ -+ -+#endif /* CUSTOMER_HW */ -diff --git a/drivers/net/wireless/ap6210/dhd_ip.c b/drivers/net/wireless/ap6210/dhd_ip.c -new file mode 100644 -index 0000000..05abc93 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_ip.c -@@ -0,0 +1,111 @@ -+/* -+ * IP Packet Parser Module. -+ * -+ * Copyright (C) 1999-2013, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id$ -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+/* special values */ -+/* 802.3 llc/snap header */ -+static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; -+ -+pkt_frag_t pkt_frag_info(osl_t *osh, void *p) -+{ -+ uint8 *frame; -+ int length; -+ uint8 *pt; /* Pointer to type field */ -+ uint16 ethertype; -+ struct ipv4_hdr *iph; /* IP frame pointer */ -+ int ipl; /* IP frame length */ -+ uint16 iph_frag; -+ -+ ASSERT(osh && p); -+ -+ frame = PKTDATA(osh, p); -+ length = PKTLEN(osh, p); -+ -+ /* Process Ethernet II or SNAP-encapsulated 802.3 frames */ -+ if (length < ETHER_HDR_LEN) { -+ AP6210_DEBUG("%s: short eth frame (%d)\n", __FUNCTION__, length); -+ return DHD_PKT_FRAG_NONE; -+ } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) { -+ /* Frame is Ethernet II */ -+ pt = frame + ETHER_TYPE_OFFSET; -+ } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN && -+ !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) { -+ pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN; -+ } else { -+ AP6210_DEBUG("%s: non-SNAP 802.3 frame\n", __FUNCTION__); -+ return DHD_PKT_FRAG_NONE; -+ } -+ -+ ethertype = ntoh16(*(uint16 *)pt); -+ -+ /* Skip VLAN tag, if any */ -+ if (ethertype == ETHER_TYPE_8021Q) { -+ pt += VLAN_TAG_LEN; -+ -+ if (pt + ETHER_TYPE_LEN > frame + length) { -+ AP6210_DEBUG("%s: short VLAN frame (%d)\n", __FUNCTION__, length); -+ return DHD_PKT_FRAG_NONE; -+ } -+ -+ ethertype = ntoh16(*(uint16 *)pt); -+ } -+ -+ if (ethertype != ETHER_TYPE_IP) { -+ AP6210_DEBUG("%s: non-IP frame (ethertype 0x%x, length %d)\n", -+ __FUNCTION__, ethertype, length); -+ return DHD_PKT_FRAG_NONE; -+ } -+ -+ iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN); -+ ipl = length - (pt + ETHER_TYPE_LEN - frame); -+ -+ /* We support IPv4 only */ -+ if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) { -+ AP6210_DEBUG("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl); -+ return DHD_PKT_FRAG_NONE; -+ } -+ -+ iph_frag = ntoh16(iph->frag); -+ -+ if (iph_frag & IPV4_FRAG_DONT) { -+ return DHD_PKT_FRAG_NONE; -+ } else if ((iph_frag & IPV4_FRAG_MORE) == 0) { -+ return DHD_PKT_FRAG_LAST; -+ } else { -+ return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST; -+ } -+} -diff --git a/drivers/net/wireless/ap6210/dhd_ip.h b/drivers/net/wireless/ap6210/dhd_ip.h -new file mode 100644 -index 0000000..ceb3877 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_ip.h -@@ -0,0 +1,42 @@ -+/* -+ * Header file describing the common ip parser function. -+ * -+ * Provides type definitions and function prototypes used to parse ip packet. -+ * -+ * Copyright (C) 1999-2013, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _dhd_ip_h_ -+#define _dhd_ip_h_ -+ -+typedef enum pkt_frag -+{ -+ DHD_PKT_FRAG_NONE = 0, -+ DHD_PKT_FRAG_FIRST, -+ DHD_PKT_FRAG_CONT, -+ DHD_PKT_FRAG_LAST -+} pkt_frag_t; -+ -+extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p); -+ -+#endif /* _dhd_ip_h_ */ -diff --git a/drivers/net/wireless/ap6210/dhd_linux.c b/drivers/net/wireless/ap6210/dhd_linux.c -new file mode 100644 -index 0000000..82a0a58 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_linux.c -@@ -0,0 +1,6151 @@ -+/* -+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface -+ * Basically selected code segments from usb-cdc.c and usb-rndis.c -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_linux.c 374275 2012-12-12 11:44:18Z $ -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_HAS_WAKELOCK -+#include -+#endif -+#ifdef WL_CFG80211 -+#include -+#endif -+ -+#ifdef WLBTAMP -+#include -+#include -+#include -+#endif -+ -+#include -+#include -+ -+#ifdef WLMEDIA_HTSF -+#include -+#include -+ -+#define HTSF_MINLEN 200 /* min. packet length to timestamp */ -+#define HTSF_BUS_DELAY 150 /* assume a fix propagation in us */ -+#define TSMAX 1000 /* max no. of timing record kept */ -+#define NUMBIN 34 -+static uint32 tsidx = 0; -+static uint32 htsf_seqnum = 0; -+uint32 tsfsync; -+struct timeval tsync; -+static uint32 tsport = 5010; -+ -+typedef struct histo_ { -+ uint32 bin[NUMBIN]; -+} histo_t; -+ -+#if !ISPOWEROF2(DHD_SDALIGN) -+#error DHD_SDALIGN is not a power of 2! -+#endif -+ -+static histo_t vi_d1, vi_d2, vi_d3, vi_d4; -+#endif /* WLMEDIA_HTSF */ -+ -+#if defined(PKT_FILTER_SUPPORT) -+#endif /* PKT_FILTER_SUPPORT */ -+ -+#if defined(SOFTAP) -+extern bool ap_cfg_running; -+extern bool ap_fw_loaded; -+#endif -+ -+/* enable HOSTIP cache update from the host side when an eth0:N is up */ -+#define AOE_IP_ALIAS_SUPPORT 1 -+ -+#ifdef BCM_FD_AGGR -+#include -+#include -+#endif -+#ifdef PROP_TXSTATUS -+#include -+#include -+#endif -+ -+#include -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx); -+static int dhd_device_event(struct notifier_block *this, -+ unsigned long event, -+ void *ptr); -+ -+static struct notifier_block dhd_notifier = { -+ .notifier_call = dhd_device_event -+}; -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+#include -+volatile bool dhd_mmc_suspend = FALSE; -+DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -+ -+#if defined(OOB_INTR_ONLY) -+extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -+#endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) -+static void dhd_hang_process(struct work_struct *work); -+#endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+MODULE_LICENSE("GPL v2"); -+#endif /* LinuxVer */ -+ -+#include -+ -+#ifdef BCM_FD_AGGR -+#define DBUS_RX_BUFFER_SIZE_DHD(net) (BCM_RPC_TP_DNGL_AGG_MAX_BYTE) -+#else -+#ifndef PROP_TXSTATUS -+#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen) -+#else -+#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen + 128) -+#endif -+#endif /* BCM_FD_AGGR */ -+ -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) -+const char * -+print_tainted() -+{ -+ return ""; -+} -+#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */ -+ -+/* Linux wireless extension support */ -+#if defined(CONFIG_WIRELESS_EXT) -+#include -+extern wl_iw_extra_params_t g_wl_iw_params; -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+#include -+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */ -+ -+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd); -+ -+#ifdef PKT_FILTER_SUPPORT -+extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg); -+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -+#endif -+ -+#ifdef READ_MACADDR -+extern int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac); -+#endif -+#ifdef RDWR_MACADDR -+extern int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac); -+extern int dhd_write_rdwr_macaddr(struct ether_addr *mac); -+#endif -+#ifdef WRITE_MACADDR -+extern int dhd_write_macaddr(struct ether_addr *mac); -+#endif -+#ifdef GET_MAC_FROM_OTP -+extern int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac); -+#endif -+#ifdef MIMO_ANT_SETTING -+extern int dhd_sel_ant_from_file(dhd_pub_t *dhd); -+#endif -+ -+#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE -+int dhd_customer_set_country(dhd_pub_t *dhd); -+#endif -+ -+/* Interface control information */ -+typedef struct dhd_if { -+ struct dhd_info *info; /* back pointer to dhd_info */ -+ /* OS/stack specifics */ -+ struct net_device *net; -+ struct net_device_stats stats; -+ int idx; /* iface idx in dongle */ -+ dhd_if_state_t state; /* interface state */ -+ uint subunit; /* subunit */ -+ uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */ -+ bool attached; /* Delayed attachment when unset */ -+ bool txflowcontrol; /* Per interface flow control indicator */ -+ char name[IFNAMSIZ+1]; /* linux interface name */ -+ uint8 bssidx; /* bsscfg index for the interface */ -+ bool set_multicast; -+ bool event2cfg80211; /* To determine if pass event to cfg80211 */ -+} dhd_if_t; -+ -+#ifdef WLMEDIA_HTSF -+typedef struct { -+ uint32 low; -+ uint32 high; -+} tsf_t; -+ -+typedef struct { -+ uint32 last_cycle; -+ uint32 last_sec; -+ uint32 last_tsf; -+ uint32 coef; /* scaling factor */ -+ uint32 coefdec1; /* first decimal */ -+ uint32 coefdec2; /* second decimal */ -+} htsf_t; -+ -+typedef struct { -+ uint32 t1; -+ uint32 t2; -+ uint32 t3; -+ uint32 t4; -+} tstamp_t; -+ -+static tstamp_t ts[TSMAX]; -+static tstamp_t maxdelayts; -+static uint32 maxdelay = 0, tspktcnt = 0, maxdelaypktno = 0; -+ -+#endif /* WLMEDIA_HTSF */ -+ -+/* Local private structure (extension of pub) */ -+typedef struct dhd_info { -+#if defined(CONFIG_WIRELESS_EXT) -+ wl_iw_t iw; /* wireless extensions state (must be first) */ -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+ dhd_pub_t pub; -+ -+ /* For supporting multiple interfaces */ -+ dhd_if_t *iflist[DHD_MAX_IFS]; -+ -+ struct semaphore proto_sem; -+#ifdef PROP_TXSTATUS -+ spinlock_t wlfc_spinlock; -+#endif /* PROP_TXSTATUS */ -+#ifdef WLMEDIA_HTSF -+ htsf_t htsf; -+#endif -+ wait_queue_head_t ioctl_resp_wait; -+ struct timer_list timer; -+ bool wd_timer_valid; -+ struct tasklet_struct tasklet; -+ spinlock_t sdlock; -+ spinlock_t txqlock; -+ spinlock_t dhd_lock; -+#ifdef DHDTHREAD -+ /* Thread based operation */ -+ bool threads_only; -+ struct semaphore sdsem; -+ -+ tsk_ctl_t thr_dpc_ctl; -+ tsk_ctl_t thr_wdt_ctl; -+#endif /* DHDTHREAD */ -+ bool dhd_tasklet_create; -+ tsk_ctl_t thr_sysioc_ctl; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ struct work_struct work_hang; -+#endif -+ -+ /* Wakelocks */ -+#if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ struct wake_lock *wl_wifi; /* Wifi wakelock */ -+ struct wake_lock *wl_rxwake; /* Wifi rx wakelock */ -+ struct wake_lock *wl_ctrlwake; /* Wifi ctrl wakelock */ -+ struct wake_lock *wl_wdwake; /* Wifi wd wakelock */ -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ /* net_device interface lock, prevent race conditions among net_dev interface -+ * calls and wifi_on or wifi_off -+ */ -+ struct mutex dhd_net_if_mutex; -+ struct mutex dhd_suspend_mutex; -+#endif -+ spinlock_t wakelock_spinlock; -+ int wakelock_counter; -+ int wakelock_wd_counter; -+ int wakelock_rx_timeout_enable; -+ int wakelock_ctrl_timeout_enable; -+ -+ /* Thread to issue ioctl for multicast */ -+ unsigned char set_macaddress; -+ struct ether_addr macvalue; -+ wait_queue_head_t ctrl_wait; -+ atomic_t pend_8021x_cnt; -+ dhd_attach_states_t dhd_state; -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+ struct early_suspend early_suspend; -+#endif /* CONFIG_HAS_EARLYSUSPEND && defined(DHD_USE_EARLYSUSPEND) */ -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ u32 pend_ipaddr; -+#endif /* ARP_OFFLOAD_SUPPORT */ -+#ifdef BCM_FD_AGGR -+ void *rpc_th; -+ void *rpc_osh; -+ struct timer_list rpcth_timer; -+ bool rpcth_timer_active; -+ bool fdaggr; -+#endif -+} dhd_info_t; -+ -+/* Flag to indicate if we should download firmware on driver load */ -+uint dhd_download_fw_on_driverload = TRUE; -+ -+/* Definitions to provide path to the firmware and nvram -+ * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt" -+ */ -+char firmware_path[MOD_PARAM_PATHLEN]; -+char nvram_path[MOD_PARAM_PATHLEN]; -+ -+/* information string to keep firmware, chio, cheip version info visiable from log */ -+char info_string[MOD_PARAM_INFOLEN]; -+module_param_string(info_string, info_string, MOD_PARAM_INFOLEN, 0444); -+ -+int op_mode = 0; -+int disable_proptx = 0; -+module_param(op_mode, int, 0644); -+extern int wl_control_wl_start(struct net_device *dev); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+struct semaphore dhd_registration_sem; -+struct semaphore dhd_chipup_sem; -+int dhd_registration_check = FALSE; -+ -+#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+/* Spawn a thread for system ioctls (set mac, set mcast) */ -+uint dhd_sysioc = TRUE; -+module_param(dhd_sysioc, uint, 0); -+ -+/* Error bits */ -+module_param(dhd_msg_level, int, 0); -+#if defined(CONFIG_WIRELESS_EXT) -+module_param(iw_msg_level, int, 0); -+#endif -+#ifdef WL_CFG80211 -+module_param(wl_dbg_level, int, 0); -+#endif -+//module_param(android_msg_level, int, 0); -+ -+/* Disable Prop tx */ -+module_param(disable_proptx, int, 0644); -+ -+/* load firmware and/or nvram values from the filesystem */ -+module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0660); -+module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); -+ -+/* Watchdog interval */ -+uint dhd_watchdog_ms = 10; -+module_param(dhd_watchdog_ms, uint, 0); -+ -+#if defined(DHD_DEBUG) -+/* Console poll interval */ -+uint dhd_console_ms = 0; -+module_param(dhd_console_ms, uint, 0644); -+#endif /* defined(DHD_DEBUG) */ -+ -+uint dhd_slpauto = TRUE; -+module_param(dhd_slpauto, uint, 0); -+ -+/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ -+uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY; -+module_param(dhd_arp_mode, uint, 0); -+ -+/* ARP offload enable */ -+uint dhd_arp_enable = TRUE; -+module_param(dhd_arp_enable, uint, 0); -+ -+#ifdef PKT_FILTER_SUPPORT -+/* Global Pkt filter enable control */ -+uint dhd_pkt_filter_enable = TRUE; -+module_param(dhd_pkt_filter_enable, uint, 0); -+#endif -+ -+/* Pkt filter init setup */ -+uint dhd_pkt_filter_init = 0; -+module_param(dhd_pkt_filter_init, uint, 0); -+ -+/* Pkt filter mode control */ -+#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER -+uint dhd_master_mode = FALSE; -+#else -+uint dhd_master_mode = TRUE; -+#endif /* GAL_LITE_NAT_KEEPALIVE_FILTER */ -+module_param(dhd_master_mode, uint, 0); -+ -+#ifdef DHDTHREAD -+int dhd_watchdog_prio = 0; -+module_param(dhd_watchdog_prio, int, 0); -+ -+/* DPC thread priority */ -+int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING; -+module_param(dhd_dpc_prio, int, 0); -+ -+/* DPC thread priority, -1 to use tasklet */ -+extern int dhd_dongle_memsize; -+module_param(dhd_dongle_memsize, int, 0); -+#endif /* DHDTHREAD */ -+/* Control fw roaming */ -+uint dhd_roam_disable = 0; -+ -+/* Control radio state */ -+uint dhd_radio_up = 1; -+ -+/* Network inteface name */ -+char iface_name[IFNAMSIZ] = {'\0'}; -+module_param_string(iface_name, iface_name, IFNAMSIZ, 0); -+ -+/* The following are specific to the SDIO dongle */ -+ -+/* IOCTL response timeout */ -+int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; -+ -+/* Idle timeout for backplane clock */ -+int dhd_idletime = DHD_IDLETIME_TICKS; -+module_param(dhd_idletime, int, 0); -+ -+/* Use polling */ -+uint dhd_poll = FALSE; -+module_param(dhd_poll, uint, 0); -+ -+/* Use interrupts */ -+uint dhd_intr = TRUE; -+module_param(dhd_intr, uint, 0); -+ -+/* SDIO Drive Strength (in milliamps) */ -+uint dhd_sdiod_drive_strength = 6; -+module_param(dhd_sdiod_drive_strength, uint, 0); -+ -+/* Tx/Rx bounds */ -+extern uint dhd_txbound; -+extern uint dhd_rxbound; -+module_param(dhd_txbound, uint, 0); -+module_param(dhd_rxbound, uint, 0); -+ -+/* Deferred transmits */ -+extern uint dhd_deferred_tx; -+module_param(dhd_deferred_tx, uint, 0); -+ -+#ifdef BCMDBGFS -+extern void dhd_dbg_init(dhd_pub_t *dhdp); -+extern void dhd_dbg_remove(void); -+#endif /* BCMDBGFS */ -+ -+/* -+ * the the 2 vars init at init time -+ *benn@cubietech.com -+ */ -+#define WL_HOST_WAKE_DEF_GPIO 2 -+int wl_host_wake_irqno = -1; -+int wl_host_wake = -1; -+ -+ -+#ifdef SDTEST -+/* Echo packet generator (pkts/s) */ -+uint dhd_pktgen = 0; -+module_param(dhd_pktgen, uint, 0); -+ -+/* Echo packet len (0 => sawtooth, max 2040) */ -+uint dhd_pktgen_len = 0; -+module_param(dhd_pktgen_len, uint, 0); -+#endif /* SDTEST */ -+ -+/* Version string to report */ -+#ifdef DHD_DEBUG -+#ifndef SRCBASE -+#define SRCBASE "drivers/net/wireless/ap6210" -+#endif -+#define DHD_COMPILED "\nCompiled in " SRCBASE -+#else -+#define DHD_COMPILED -+#endif /* DHD_DEBUG */ -+ -+static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "."; -+#ifdef DHD_DEBUG -+static char dhd_version_info[] = "Compiled in " SRCBASE " on " __DATE__ " at " __TIME__ "."; -+#endif -+ -+static void dhd_net_if_lock_local(dhd_info_t *dhd); -+static void dhd_net_if_unlock_local(dhd_info_t *dhd); -+static void dhd_suspend_lock(dhd_pub_t *dhdp); -+static void dhd_suspend_unlock(dhd_pub_t *dhdp); -+ -+#ifdef WLMEDIA_HTSF -+void htsf_update(dhd_info_t *dhd, void *data); -+tsf_t prev_tsf, cur_tsf; -+ -+uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx); -+static int dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx); -+static void dhd_dump_latency(void); -+static void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf); -+static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf); -+static void dhd_dump_htsfhisto(histo_t *his, char *s); -+#endif /* WLMEDIA_HTSF */ -+ -+/* Monitor interface */ -+int dhd_monitor_init(void *dhd_pub); -+int dhd_monitor_uninit(void); -+ -+ -+#if defined(CONFIG_WIRELESS_EXT) -+struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+static void dhd_dpc(ulong data); -+/* forward decl */ -+extern int dhd_wait_pend8021x(struct net_device *dev); -+ -+#ifdef TOE -+#ifndef BDC -+#error TOE requires BDC -+#endif /* !BDC */ -+static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol); -+static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); -+#endif /* TOE */ -+ -+static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, -+ wl_event_msg_t *event_ptr, void **data_ptr); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) -+{ -+ int ret = NOTIFY_DONE; -+ -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || (LINUX_VERSION_CODE <= \ -+ KERNEL_VERSION(2, 6, 39)) -+ switch (action) { -+ case PM_HIBERNATION_PREPARE: -+ case PM_SUSPEND_PREPARE: -+ dhd_mmc_suspend = TRUE; -+ ret = NOTIFY_OK; -+ break; -+ case PM_POST_HIBERNATION: -+ case PM_POST_SUSPEND: -+ dhd_mmc_suspend = FALSE; -+ ret = NOTIFY_OK; -+ break; -+ } -+ smp_mb(); -+#endif -+ return ret; -+} -+ -+static struct notifier_block dhd_sleep_pm_notifier = { -+ .notifier_call = dhd_sleep_pm_callback, -+ .priority = 10 -+}; -+extern int register_pm_notifier(struct notifier_block *nb); -+extern int unregister_pm_notifier(struct notifier_block *nb); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -+ -+void dhd_set_packet_filter(dhd_pub_t *dhd) -+{ -+#ifdef PKT_FILTER_SUPPORT -+ int i; -+ -+ AP6210_DEBUG("%s: enter\n", __FUNCTION__); -+ if (dhd_pkt_filter_enable) { -+ for (i = 0; i < dhd->pktfilter_count; i++) { -+ dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); -+ } -+ } -+#endif /* PKT_FILTER_SUPPORT */ -+} -+ -+void dhd_enable_packet_filter(int value, dhd_pub_t *dhd) -+{ -+#ifdef PKT_FILTER_SUPPORT -+ int i; -+ -+ AP6210_DEBUG("%s: enter, value = %d\n", __FUNCTION__, value); -+ /* 1 - Enable packet filter, only allow unicast packet to send up */ -+ /* 0 - Disable packet filter */ -+ if (dhd_pkt_filter_enable && (!value || -+ (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress))) { -+ for (i = 0; i < dhd->pktfilter_count; i++) { -+#ifdef PASS_ARP_PACKET -+ if (value && (i == dhd->pktfilter_count -1) && -+ !(dhd->op_mode & (DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE))) { -+ AP6210_DEBUG("Do not turn on ARP white list pkt filter:" -+ "val %d, cnt %d, op_mode 0x%x\n", -+ value, i, dhd->op_mode); -+ continue; -+ } -+#endif -+ dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], -+ value, dhd_master_mode); -+ } -+ } -+#endif /* PKT_FILTER_SUPPORT */ -+} -+ -+static int dhd_set_suspend(int value, dhd_pub_t *dhd) -+{ -+#if !defined(SUPPORT_PM2_ONLY) -+ int power_mode = PM_MAX; -+#endif -+ /* wl_pkt_filter_enable_t enable_parm; */ -+ char iovbuf[32]; -+ int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */ -+#ifndef DISABLE_FW_ROAM_SUSPEND -+ uint roamvar = 1; -+#endif -+#ifdef ENABLE_BCN_LI_BCN_WAKEUP -+ int bcn_li_bcn; -+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ -+#ifdef PASS_ALL_MCAST_PKTS -+ struct dhd_info *dhdinfo = dhd->info; -+ uint32 allmulti; -+ uint i; -+#endif /* PASS_ALL_MCAST_PKTS */ -+ -+ AP6210_DEBUG("%s: enter, value = %d in_suspend=%d\n", -+ __FUNCTION__, value, dhd->in_suspend); -+ -+ dhd_suspend_lock(dhd); -+ if (dhd && dhd->up) { -+ if (value && dhd->in_suspend) { -+#ifdef PKT_FILTER_SUPPORT -+ dhd->early_suspended = 1; -+#endif -+ /* Kernel suspended */ -+ AP6210_ERR("%s: force extra Suspend setting\n", __FUNCTION__); -+ -+#if !defined(SUPPORT_PM2_ONLY) -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, -+ sizeof(power_mode), TRUE, 0); -+#endif -+ /* Enable packet filter, only allow unicast packet to send up */ -+ dhd_enable_packet_filter(1, dhd); -+#ifdef PASS_ALL_MCAST_PKTS -+ allmulti = 0; -+ bcm_mkiovar("allmulti", (char *)&allmulti, -+ 4, iovbuf, sizeof(iovbuf)); -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net) -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, -+ sizeof(iovbuf), TRUE, i); -+ } -+#endif /* PASS_ALL_MCAST_PKTS */ -+ -+ /* If DTIM skip is set up as default, force it to wake -+ * each third DTIM for better power savings. Note that -+ * one side effect is a chance to miss BC/MC packet. -+ */ -+ bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd); -+ bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, -+ 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ -+#ifndef DISABLE_FW_ROAM_SUSPEND -+ /* Disable firmware roaming during suspend */ -+ bcm_mkiovar("roam_off", (char *)&roamvar, 4, -+ iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif -+#ifdef ENABLE_BCN_LI_BCN_WAKEUP -+ bcn_li_bcn = 0; -+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, -+ 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ -+ -+ } else { -+#ifdef PKT_FILTER_SUPPORT -+ dhd->early_suspended = 0; -+#endif -+ /* Kernel resumed */ -+ AP6210_ERR("%s: Remove extra suspend setting\n", __FUNCTION__); -+ -+#if !defined(SUPPORT_PM2_ONLY) -+ power_mode = PM_FAST; -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, -+ sizeof(power_mode), TRUE, 0); -+#endif -+ /* disable pkt filter */ -+ dhd_enable_packet_filter(0, dhd); -+#ifdef PASS_ALL_MCAST_PKTS -+ allmulti = 1; -+ bcm_mkiovar("allmulti", (char *)&allmulti, -+ 4, iovbuf, sizeof(iovbuf)); -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net) -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, -+ sizeof(iovbuf), TRUE, i); -+ } -+#endif /* PASS_ALL_MCAST_PKTS */ -+ -+ /* restore pre-suspend setting for dtim_skip */ -+ bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, -+ 4, iovbuf, sizeof(iovbuf)); -+ -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#ifndef DISABLE_FW_ROAM_SUSPEND -+ roamvar = dhd_roam_disable; -+ bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, -+ sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif -+#ifdef ENABLE_BCN_LI_BCN_WAKEUP -+ bcn_li_bcn = 1; -+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, -+ 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ -+ -+ } -+ } -+ -+ dhd_suspend_unlock(dhd); -+ return 0; -+} -+ -+static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force) -+{ -+ dhd_pub_t *dhdp = &dhd->pub; -+ int ret = 0; -+ -+ DHD_OS_WAKE_LOCK(dhdp); -+ /* Set flag when early suspend was called */ -+ dhdp->in_suspend = val; -+ if ((force || !dhdp->suspend_disable_flag) && -+ dhd_support_sta_mode(dhdp)) -+ { -+ ret = dhd_set_suspend(val, dhdp); -+ } -+ -+ DHD_OS_WAKE_UNLOCK(dhdp); -+ return ret; -+} -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+static void dhd_early_suspend(struct early_suspend *h) -+{ -+ struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); -+ AP6210_DEBUG("%s: enter\n", __FUNCTION__); -+ -+ if (dhd) -+ dhd_suspend_resume_helper(dhd, 1, 0); -+} -+ -+static void dhd_late_resume(struct early_suspend *h) -+{ -+ struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); -+ AP6210_DEBUG("%s: enter\n", __FUNCTION__); -+ -+ if (dhd) -+ dhd_suspend_resume_helper(dhd, 0, 0); -+} -+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ -+ -+/* -+ * Generalized timeout mechanism. Uses spin sleep with exponential back-off until -+ * the sleep time reaches one jiffy, then switches over to task delay. Usage: -+ * -+ * dhd_timeout_start(&tmo, usec); -+ * while (!dhd_timeout_expired(&tmo)) -+ * if (poll_something()) -+ * break; -+ * if (dhd_timeout_expired(&tmo)) -+ * fatal(); -+ */ -+ -+void -+dhd_timeout_start(dhd_timeout_t *tmo, uint usec) -+{ -+ tmo->limit = usec; -+ tmo->increment = 0; -+ tmo->elapsed = 0; -+ tmo->tick = jiffies_to_usecs(1); -+} -+ -+int -+dhd_timeout_expired(dhd_timeout_t *tmo) -+{ -+ /* Does nothing the first call */ -+ if (tmo->increment == 0) { -+ tmo->increment = 1; -+ return 0; -+ } -+ -+ if (tmo->elapsed >= tmo->limit) -+ return 1; -+ -+ /* Add the delay that's about to take place */ -+ tmo->elapsed += tmo->increment; -+ -+ if (tmo->increment < tmo->tick) { -+ OSL_DELAY(tmo->increment); -+ tmo->increment *= 2; -+ if (tmo->increment > tmo->tick) -+ tmo->increment = tmo->tick; -+ } else { -+ wait_queue_head_t delay_wait; -+ DECLARE_WAITQUEUE(wait, current); -+ init_waitqueue_head(&delay_wait); -+ add_wait_queue(&delay_wait, &wait); -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(1); -+ remove_wait_queue(&delay_wait, &wait); -+ set_current_state(TASK_RUNNING); -+ } -+ -+ return 0; -+} -+ -+int -+dhd_net2idx(dhd_info_t *dhd, struct net_device *net) -+{ -+ int i = 0; -+ -+ ASSERT(dhd); -+ while (i < DHD_MAX_IFS) { -+ if (dhd->iflist[i] && (dhd->iflist[i]->net == net)) -+ return i; -+ i++; -+ } -+ -+ return DHD_BAD_IF; -+} -+ -+struct net_device * dhd_idx2net(void *pub, int ifidx) -+{ -+ struct dhd_pub *dhd_pub = (struct dhd_pub *)pub; -+ struct dhd_info *dhd_info; -+ -+ if (!dhd_pub || ifidx < 0 || ifidx >= DHD_MAX_IFS) -+ return NULL; -+ dhd_info = dhd_pub->info; -+ if (dhd_info && dhd_info->iflist[ifidx]) -+ return dhd_info->iflist[ifidx]->net; -+ return NULL; -+} -+ -+int -+dhd_ifname2idx(dhd_info_t *dhd, char *name) -+{ -+ int i = DHD_MAX_IFS; -+ -+ ASSERT(dhd); -+ -+ if (name == NULL || *name == '\0') -+ return 0; -+ -+ while (--i > 0) -+ if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ)) -+ break; -+ -+ AP6210_DEBUG("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name); -+ -+ return i; /* default - the primary interface */ -+} -+ -+char * -+dhd_ifname(dhd_pub_t *dhdp, int ifidx) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -+ -+ ASSERT(dhd); -+ -+ if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { -+ AP6210_ERR("%s: ifidx %d out of range\n", __FUNCTION__, ifidx); -+ return ""; -+ } -+ -+ if (dhd->iflist[ifidx] == NULL) { -+ AP6210_ERR("%s: null i/f %d\n", __FUNCTION__, ifidx); -+ return ""; -+ } -+ -+ if (dhd->iflist[ifidx]->net) -+ return dhd->iflist[ifidx]->net->name; -+ -+ return ""; -+} -+ -+uint8 * -+dhd_bssidx2bssid(dhd_pub_t *dhdp, int idx) -+{ -+ int i; -+ dhd_info_t *dhd = (dhd_info_t *)dhdp; -+ -+ ASSERT(dhd); -+ for (i = 0; i < DHD_MAX_IFS; i++) -+ if (dhd->iflist[i] && dhd->iflist[i]->bssidx == idx) -+ return dhd->iflist[i]->mac_addr; -+ -+ return NULL; -+} -+ -+ -+static void -+_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) -+{ -+ struct net_device *dev; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+ struct netdev_hw_addr *ha; -+#else -+ struct dev_mc_list *mclist; -+#endif -+ uint32 allmulti, cnt; -+ -+ wl_ioctl_t ioc; -+ char *buf, *bufp; -+ uint buflen; -+ int ret; -+ -+ ASSERT(dhd && dhd->iflist[ifidx]); -+ dev = dhd->iflist[ifidx]->net; -+ if (!dev) -+ return; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+ netif_addr_lock_bh(dev); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+ cnt = netdev_mc_count(dev); -+#else -+ cnt = dev->mc_count; -+#endif /* LINUX_VERSION_CODE */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+ netif_addr_unlock_bh(dev); -+#endif -+ -+ /* Determine initial value of allmulti flag */ -+ allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; -+#ifdef PASS_ALL_MCAST_PKTS -+#ifdef PKT_FILTER_SUPPORT -+ if (!dhd->pub.early_suspended) -+#endif /* PKT_FILTER_SUPPORT */ -+ allmulti = TRUE; -+#endif /* PASS_ALL_MCAST_PKTS */ -+ -+ /* Send down the multicast list first. */ -+ -+ -+ buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN); -+ if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) { -+ AP6210_ERR("%s: out of memory for mcast_list, cnt %d\n", -+ dhd_ifname(&dhd->pub, ifidx), cnt); -+ return; -+ } -+ -+ strncpy(bufp, "mcast_list", buflen - 1); -+ bufp[buflen - 1] = '\0'; -+ bufp += strlen("mcast_list") + 1; -+ -+ cnt = htol32(cnt); -+ memcpy(bufp, &cnt, sizeof(cnt)); -+ bufp += sizeof(cnt); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+ netif_addr_lock_bh(dev); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+ netdev_for_each_mc_addr(ha, dev) { -+ if (!cnt) -+ break; -+ memcpy(bufp, ha->addr, ETHER_ADDR_LEN); -+ bufp += ETHER_ADDR_LEN; -+ cnt--; -+ } -+#else -+ for (mclist = dev->mc_list; (mclist && (cnt > 0)); -+ cnt--, mclist = mclist->next) { -+ memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); -+ bufp += ETHER_ADDR_LEN; -+ } -+#endif /* LINUX_VERSION_CODE */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+ netif_addr_unlock_bh(dev); -+#endif -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = WLC_SET_VAR; -+ ioc.buf = buf; -+ ioc.len = buflen; -+ ioc.set = TRUE; -+ -+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); -+ if (ret < 0) { -+ AP6210_ERR("%s: set mcast_list failed, cnt %d\n", -+ dhd_ifname(&dhd->pub, ifidx), cnt); -+ allmulti = cnt ? TRUE : allmulti; -+ } -+ -+ MFREE(dhd->pub.osh, buf, buflen); -+ -+ /* Now send the allmulti setting. This is based on the setting in the -+ * net_device flags, but might be modified above to be turned on if we -+ * were trying to set some addresses and dongle rejected it... -+ */ -+ -+ buflen = sizeof("allmulti") + sizeof(allmulti); -+ if (!(buf = MALLOC(dhd->pub.osh, buflen))) { -+ AP6210_ERR("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx)); -+ return; -+ } -+ allmulti = htol32(allmulti); -+ -+ if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) { -+ AP6210_ERR("%s: mkiovar failed for allmulti, datalen %d buflen %u\n", -+ dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen); -+ MFREE(dhd->pub.osh, buf, buflen); -+ return; -+ } -+ -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = WLC_SET_VAR; -+ ioc.buf = buf; -+ ioc.len = buflen; -+ ioc.set = TRUE; -+ -+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); -+ if (ret < 0) { -+ AP6210_ERR("%s: set allmulti %d failed\n", -+ dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti)); -+ } -+ -+ MFREE(dhd->pub.osh, buf, buflen); -+ -+ /* Finally, pick up the PROMISC flag as well, like the NIC driver does */ -+ -+ allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE; -+ allmulti = htol32(allmulti); -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = WLC_SET_PROMISC; -+ ioc.buf = &allmulti; -+ ioc.len = sizeof(allmulti); -+ ioc.set = TRUE; -+ -+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); -+ if (ret < 0) { -+ AP6210_ERR("%s: set promisc %d failed\n", -+ dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti)); -+ } -+} -+ -+int -+_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) -+{ -+ char buf[32]; -+ wl_ioctl_t ioc; -+ int ret; -+ -+ if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) { -+ AP6210_ERR("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx)); -+ return -1; -+ } -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = WLC_SET_VAR; -+ ioc.buf = buf; -+ ioc.len = 32; -+ ioc.set = TRUE; -+ -+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); -+ if (ret < 0) { -+ AP6210_ERR("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx)); -+ } else { -+ memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); -+ memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN); -+ } -+ -+ return ret; -+} -+ -+#ifdef SOFTAP -+extern struct net_device *ap_net_dev; -+extern tsk_ctl_t ap_eth_ctl; /* ap netdev heper thread ctl */ -+#endif -+ -+static void -+dhd_op_if(dhd_if_t *ifp) -+{ -+ dhd_info_t *dhd; -+ int ret = 0, err = 0; -+#ifdef SOFTAP -+ unsigned long flags; -+#endif -+ -+ if (!ifp || !ifp->info || !ifp->idx) -+ return; -+ ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */ -+ dhd = ifp->info; -+ -+ AP6210_DEBUG("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state); -+ -+#ifdef WL_CFG80211 -+ if (wl_cfg80211_is_progress_ifchange()) -+ return; -+ -+#endif -+ switch (ifp->state) { -+ case DHD_IF_ADD: -+ /* -+ * Delete the existing interface before overwriting it -+ * in case we missed the WLC_E_IF_DEL event. -+ */ -+ if (ifp->net != NULL) { -+ AP6210_ERR("%s: ERROR: netdev:%s already exists, try free & unregister \n", -+ __FUNCTION__, ifp->net->name); -+ netif_stop_queue(ifp->net); -+ unregister_netdev(ifp->net); -+ free_netdev(ifp->net); -+ } -+ /* Allocate etherdev, including space for private structure */ -+ if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) { -+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__); -+ ret = -ENOMEM; -+ } -+ if (ret == 0) { -+ strncpy(ifp->net->name, ifp->name, IFNAMSIZ); -+ ifp->net->name[IFNAMSIZ - 1] = '\0'; -+ memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd)); -+#ifdef WL_CFG80211 -+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) -+ if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx, -+ (void*)dhd_net_attach)) { -+ ifp->state = DHD_IF_NONE; -+ ifp->event2cfg80211 = TRUE; -+ return; -+ } -+#endif -+ if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) { -+ AP6210_ERR("%s: dhd_net_attach failed, err %d\n", -+ __FUNCTION__, err); -+ ret = -EOPNOTSUPP; -+ } else { -+#if defined(SOFTAP) -+ if (ap_fw_loaded && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { -+ /* semaphore that the soft AP CODE waits on */ -+ flags = dhd_os_spin_lock(&dhd->pub); -+ -+ /* save ptr to wl0.1 netdev for use in wl_iw.c */ -+ ap_net_dev = ifp->net; -+ /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */ -+ up(&ap_eth_ctl.sema); -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ } -+#endif -+ AP6210_DEBUG(" ==== pid:%x, net_device for if:%s created ===\n\n", -+ current->pid, ifp->net->name); -+ ifp->state = DHD_IF_NONE; -+ } -+ } -+ break; -+ case DHD_IF_DEL: -+ /* Make sure that we don't enter again here if .. */ -+ /* dhd_op_if is called again from some other context */ -+ ifp->state = DHD_IF_DELETING; -+ if (ifp->net != NULL) { -+ AP6210_DEBUG("%s: got 'DHD_IF_DEL' state\n", __FUNCTION__); -+ netif_stop_queue(ifp->net); -+#ifdef WL_CFG80211 -+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { -+ wl_cfg80211_ifdel_ops(ifp->net); -+ } -+#endif -+ unregister_netdev(ifp->net); -+ ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */ -+#ifdef WL_CFG80211 -+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { -+ wl_cfg80211_notify_ifdel(); -+ } -+#endif -+ } -+ break; -+ case DHD_IF_DELETING: -+ break; -+ default: -+ AP6210_ERR("%s: bad op %d\n", __FUNCTION__, ifp->state); -+ ASSERT(!ifp->state); -+ break; -+ } -+ -+ if (ret < 0) { -+ ifp->set_multicast = FALSE; -+ if (ifp->net) { -+ free_netdev(ifp->net); -+ ifp->net = NULL; -+ } -+ dhd->iflist[ifp->idx] = NULL; -+#ifdef SOFTAP -+ flags = dhd_os_spin_lock(&dhd->pub); -+ if (ifp->net == ap_net_dev) -+ ap_net_dev = NULL; /* NULL SOFTAP global wl0.1 as well */ -+ dhd_os_spin_unlock(&dhd->pub, flags); -+#endif /* SOFTAP */ -+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); -+ } -+} -+ -+static int -+_dhd_sysioc_thread(void *data) -+{ -+ tsk_ctl_t *tsk = (tsk_ctl_t *)data; -+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent; -+ -+ -+ int i; -+#ifdef SOFTAP -+ bool in_ap = FALSE; -+ unsigned long flags; -+#endif -+#ifndef USE_KTHREAD_API -+ DAEMONIZE("dhd_sysioc"); -+ -+ complete(&tsk->completed); -+#endif -+ -+ while (down_interruptible(&tsk->sema) == 0) { -+ -+ SMP_RD_BARRIER_DEPENDS(); -+ if (tsk->terminated) { -+ break; -+ } -+ -+ dhd_net_if_lock_local(dhd); -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (dhd->iflist[i]) { -+ AP6210_DEBUG("%s: interface %d\n", __FUNCTION__, i); -+#ifdef SOFTAP -+ flags = dhd_os_spin_lock(&dhd->pub); -+ in_ap = (ap_net_dev != NULL); -+ dhd_os_spin_unlock(&dhd->pub, flags); -+#endif /* SOFTAP */ -+ if (dhd->iflist[i] && dhd->iflist[i]->state) -+ dhd_op_if(dhd->iflist[i]); -+ -+ if (dhd->iflist[i] == NULL) { -+ AP6210_DEBUG("%s: interface %d just been removed,!\n", __FUNCTION__, i); -+ continue; -+ } -+#ifdef SOFTAP -+ if (in_ap && dhd->set_macaddress == i+1) { -+ AP6210_DEBUG("attempt to set MAC for %s in AP Mode," -+ "blocked. \n", dhd->iflist[i]->net->name); -+ dhd->set_macaddress = 0; -+ continue; -+ } -+ -+ if (in_ap && dhd->iflist[i]->set_multicast) { -+ AP6210_DEBUG("attempt to set MULTICAST list for %s" -+ "in AP Mode, blocked. \n", dhd->iflist[i]->net->name); -+ dhd->iflist[i]->set_multicast = FALSE; -+ continue; -+ } -+#endif /* SOFTAP */ -+ if (dhd->pub.up == 0) -+ continue; -+ if (dhd->iflist[i]->set_multicast) { -+ dhd->iflist[i]->set_multicast = FALSE; -+ _dhd_set_multicast_list(dhd, i); -+ } -+ if (dhd->set_macaddress == i+1) { -+ dhd->set_macaddress = 0; -+ if (_dhd_set_mac_address(dhd, i, &dhd->macvalue) == 0) { -+ AP6210_DEBUG( -+ "dhd_sysioc_thread: MACID is overwritten\n"); -+ } else { -+ AP6210_ERR( -+ "dhd_sysioc_thread: _dhd_set_mac_address() failed\n"); -+ } -+ } -+ } -+ } -+ -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ dhd_net_if_unlock_local(dhd); -+ } -+ AP6210_DEBUG("%s: stopped\n", __FUNCTION__); -+ complete_and_exit(&tsk->completed, 0); -+} -+ -+static int -+dhd_set_mac_address(struct net_device *dev, void *addr) -+{ -+ int ret = 0; -+ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ struct sockaddr *sa = (struct sockaddr *)addr; -+ int ifidx; -+ -+ ifidx = dhd_net2idx(dhd, dev); -+ if (ifidx == DHD_BAD_IF) -+ return -1; -+ -+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); -+ memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); -+ dhd->set_macaddress = ifidx+1; -+ up(&dhd->thr_sysioc_ctl.sema); -+ -+ return ret; -+} -+ -+static void -+dhd_set_multicast_list(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ifidx; -+ -+ ifidx = dhd_net2idx(dhd, dev); -+ if (ifidx == DHD_BAD_IF) -+ return; -+ -+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); -+ dhd->iflist[ifidx]->set_multicast = TRUE; -+ up(&dhd->thr_sysioc_ctl.sema); -+} -+ -+#ifdef PROP_TXSTATUS -+int -+dhd_os_wlfc_block(dhd_pub_t *pub) -+{ -+ dhd_info_t *di = (dhd_info_t *)(pub->info); -+ ASSERT(di != NULL); -+ spin_lock_bh(&di->wlfc_spinlock); -+ return 1; -+} -+ -+int -+dhd_os_wlfc_unblock(dhd_pub_t *pub) -+{ -+ dhd_info_t *di = (dhd_info_t *)(pub->info); -+ -+ ASSERT(di != NULL); -+ spin_unlock_bh(&di->wlfc_spinlock); -+ return 1; -+} -+ -+const uint8 wme_fifo2ac[] = { 0, 1, 2, 3, 1, 1 }; -+uint8 prio2fifo[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] -+ -+#endif /* PROP_TXSTATUS */ -+int -+dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) -+{ -+ int ret; -+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); -+ struct ether_header *eh = NULL; -+ -+ /* Reject if down */ -+ if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) { -+ /* free the packet here since the caller won't */ -+ PKTFREE(dhdp->osh, pktbuf, TRUE); -+ return -ENODEV; -+ } -+ -+ /* Update multicast statistic */ -+ if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_HDR_LEN) { -+ uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf); -+ eh = (struct ether_header *)pktdata; -+ -+ if (ETHER_ISMULTI(eh->ether_dhost)) -+ dhdp->tx_multicast++; -+ if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) -+ atomic_inc(&dhd->pend_8021x_cnt); -+ } else { -+ PKTFREE(dhd->pub.osh, pktbuf, TRUE); -+ return BCME_ERROR; -+ } -+ -+ /* Look into the packet and update the packet priority */ -+#ifndef PKTPRIO_OVERRIDE -+ if (PKTPRIO(pktbuf) == 0) -+#endif -+ pktsetprio(pktbuf, FALSE); -+ -+#ifdef PROP_TXSTATUS -+ if (dhdp->wlfc_state) { -+ /* store the interface ID */ -+ DHD_PKTTAG_SETIF(PKTTAG(pktbuf), ifidx); -+ -+ /* store destination MAC in the tag as well */ -+ DHD_PKTTAG_SETDSTN(PKTTAG(pktbuf), eh->ether_dhost); -+ -+ /* decide which FIFO this packet belongs to */ -+ if (ETHER_ISMULTI(eh->ether_dhost)) -+ /* one additional queue index (highest AC + 1) is used for bc/mc queue */ -+ DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), AC_COUNT); -+ else -+ DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), WME_PRIO2AC(PKTPRIO(pktbuf))); -+ } else -+#endif /* PROP_TXSTATUS */ -+ /* If the protocol uses a data header, apply it */ -+ dhd_prot_hdrpush(dhdp, ifidx, pktbuf); -+ -+ /* Use bus module to send data frame */ -+#ifdef WLMEDIA_HTSF -+ dhd_htsf_addtxts(dhdp, pktbuf); -+#endif -+#ifdef PROP_TXSTATUS -+ dhd_os_wlfc_block(dhdp); -+ if (dhdp->wlfc_state && ((athost_wl_status_info_t*)dhdp->wlfc_state)->proptxstatus_mode -+ != WLFC_FCMODE_NONE) { -+ ret = dhd_wlfc_enque_sendq(dhdp->wlfc_state, DHD_PKTTAG_FIFO(PKTTAG(pktbuf)), -+ pktbuf); -+ dhd_wlfc_commit_packets(dhdp->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, -+ dhdp->bus); -+ if (((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if) { -+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if = 0; -+ } -+ dhd_os_wlfc_unblock(dhdp); -+ } -+ else { -+ dhd_os_wlfc_unblock(dhdp); -+ /* non-proptxstatus way */ -+ ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE); -+ } -+#else -+ ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE); -+#endif /* PROP_TXSTATUS */ -+ -+ return ret; -+} -+ -+int -+dhd_start_xmit(struct sk_buff *skb, struct net_device *net) -+{ -+ int ret; -+ void *pktbuf; -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+ int ifidx; -+#ifdef WLMEDIA_HTSF -+ uint8 htsfdlystat_sz = dhd->pub.htsfdlystat_sz; -+#else -+ uint8 htsfdlystat_sz = 0; -+#endif -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ -+ /* Reject if down */ -+ if (dhd->pub.busstate == DHD_BUS_DOWN || dhd->pub.hang_was_sent) { -+ AP6210_ERR("%s: xmit rejected pub.up=%d busstate=%d \n", -+ __FUNCTION__, dhd->pub.up, dhd->pub.busstate); -+ netif_stop_queue(net); -+ /* Send Event when bus down detected during data session */ -+ if (dhd->pub.up) { -+ AP6210_ERR("%s: Event HANG sent up\n", __FUNCTION__); -+ net_os_send_hang_message(net); -+ } -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)) -+ return -ENODEV; -+#else -+ return NETDEV_TX_BUSY; -+#endif -+ } -+ -+ ifidx = dhd_net2idx(dhd, net); -+ if (ifidx == DHD_BAD_IF) { -+ AP6210_ERR("%s: bad ifidx %d\n", __FUNCTION__, ifidx); -+ netif_stop_queue(net); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)) -+ return -ENODEV; -+#else -+ return NETDEV_TX_BUSY; -+#endif -+ } -+ -+ /* Make sure there's enough room for any header */ -+ -+ if (skb_headroom(skb) < dhd->pub.hdrlen + htsfdlystat_sz) { -+ struct sk_buff *skb2; -+ -+ AP6210_DEBUG("%s: insufficient headroom\n", -+ dhd_ifname(&dhd->pub, ifidx)); -+ dhd->pub.tx_realloc++; -+ -+ skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen + htsfdlystat_sz); -+ -+ dev_kfree_skb(skb); -+ if ((skb = skb2) == NULL) { -+ AP6210_ERR("%s: skb_realloc_headroom failed\n", -+ dhd_ifname(&dhd->pub, ifidx)); -+ ret = -ENOMEM; -+ goto done; -+ } -+ } -+ -+ /* Convert to packet */ -+ if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) { -+ AP6210_ERR("%s: PKTFRMNATIVE failed\n", -+ dhd_ifname(&dhd->pub, ifidx)); -+ dev_kfree_skb_any(skb); -+ ret = -ENOMEM; -+ goto done; -+ } -+#ifdef WLMEDIA_HTSF -+ if (htsfdlystat_sz && PKTLEN(dhd->pub.osh, pktbuf) >= ETHER_ADDR_LEN) { -+ uint8 *pktdata = (uint8 *)PKTDATA(dhd->pub.osh, pktbuf); -+ struct ether_header *eh = (struct ether_header *)pktdata; -+ -+ if (!ETHER_ISMULTI(eh->ether_dhost) && -+ (ntoh16(eh->ether_type) == ETHER_TYPE_IP)) { -+ eh->ether_type = hton16(ETHER_TYPE_BRCM_PKTDLYSTATS); -+ } -+ } -+#endif -+ -+ ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); -+ -+ -+done: -+ if (ret) -+ dhd->pub.dstats.tx_dropped++; -+ else -+ dhd->pub.tx_packets++; -+ -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ -+ /* Return ok: we always eat the packet */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)) -+ return 0; -+#else -+ return NETDEV_TX_OK; -+#endif -+} -+ -+void -+dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) -+{ -+ struct net_device *net; -+ dhd_info_t *dhd = dhdp->info; -+ int i; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(dhd); -+ -+ if (ifidx == ALL_INTERFACES) { -+ /* Flow control on all active interfaces */ -+ dhdp->txoff = state; -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (dhd->iflist[i]) { -+ net = dhd->iflist[i]->net; -+ if (state == ON) -+ netif_stop_queue(net); -+ else -+ netif_wake_queue(net); -+ } -+ } -+ } -+ else { -+ if (dhd->iflist[ifidx]) { -+ net = dhd->iflist[ifidx]->net; -+ if (state == ON) -+ netif_stop_queue(net); -+ else -+ netif_wake_queue(net); -+ } -+ } -+} -+ -+#ifdef DHD_RX_DUMP -+typedef struct { -+ uint16 type; -+ const char *str; -+} PKTTYPE_INFO; -+ -+static const PKTTYPE_INFO packet_type_info[] = -+{ -+ { ETHER_TYPE_IP, "IP" }, -+ { ETHER_TYPE_ARP, "ARP" }, -+ { ETHER_TYPE_BRCM, "BRCM" }, -+ { ETHER_TYPE_802_1X, "802.1X" }, -+ { ETHER_TYPE_WAI, "WAPI" }, -+ { 0, ""} -+}; -+ -+static const char *_get_packet_type_str(uint16 type) -+{ -+ int i; -+ int n = sizeof(packet_type_info)/sizeof(packet_type_info[1]) - 1; -+ -+ for (i = 0; i < n; i++) { -+ if (packet_type_info[i].type == type) -+ return packet_type_info[i].str; -+ } -+ -+ return packet_type_info[n].str; -+} -+#endif /* DHD_RX_DUMP */ -+ -+void -+dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -+ struct sk_buff *skb; -+ uchar *eth; -+ uint len; -+ void *data, *pnext = NULL; -+ int i; -+ dhd_if_t *ifp; -+ wl_event_msg_t event; -+ int tout_rx = 0; -+ int tout_ctrl = 0; -+ -+#ifdef DHD_RX_DUMP -+#ifdef DHD_RX_FULL_DUMP -+ int k; -+#endif /* DHD_RX_FULL_DUMP */ -+ char *dump_data; -+ uint16 protocol; -+#endif /* DHD_RX_DUMP */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { -+#ifdef WLBTAMP -+ struct ether_header *eh; -+ struct dot11_llc_snap_header *lsh; -+#endif -+ -+ ifp = dhd->iflist[ifidx]; -+ if (ifp == NULL) { -+ AP6210_ERR("%s: ifp is NULL. drop packet\n", -+ __FUNCTION__); -+ PKTFREE(dhdp->osh, pktbuf, TRUE); -+ continue; -+ } -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ /* Dropping packets before registering net device to avoid kernel panic */ -+#ifndef PROP_TXSTATUS_VSDB -+ if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) { -+#else -+ if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED || !dhd->pub.up) { -+#endif /* PROP_TXSTATUS_VSDB */ -+ AP6210_ERR("%s: net device is NOT registered yet. drop packet\n", -+ __FUNCTION__); -+ PKTFREE(dhdp->osh, pktbuf, TRUE); -+ continue; -+ } -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ -+ -+ pnext = PKTNEXT(dhdp->osh, pktbuf); -+ PKTSETNEXT(wl->sh.osh, pktbuf, NULL); -+ -+#ifdef WLBTAMP -+ eh = (struct ether_header *)PKTDATA(wl->sh.osh, pktbuf); -+ lsh = (struct dot11_llc_snap_header *)&eh[1]; -+ -+ if ((ntoh16(eh->ether_type) < ETHER_TYPE_MIN) && -+ (PKTLEN(wl->sh.osh, pktbuf) >= RFC1042_HDR_LEN) && -+ bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && -+ lsh->type == HTON16(BTA_PROT_L2CAP)) { -+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *) -+ ((uint8 *)eh + RFC1042_HDR_LEN); -+ ACL_data = NULL; -+ } -+#endif /* WLBTAMP */ -+ -+#ifdef PROP_TXSTATUS -+ if (dhdp->wlfc_state && PKTLEN(wl->sh.osh, pktbuf) == 0) { -+ /* WLFC may send header only packet when -+ there is an urgent message but no packet to -+ piggy-back on -+ */ -+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->stats.wlfc_header_only_pkt++; -+ PKTFREE(dhdp->osh, pktbuf, TRUE); -+ continue; -+ } -+#endif -+ -+ skb = PKTTONATIVE(dhdp->osh, pktbuf); -+ -+ /* Get the protocol, maintain skb around eth_type_trans() -+ * The main reason for this hack is for the limitation of -+ * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len' -+ * to perform skb_pull inside vs ETH_HLEN. Since to avoid -+ * coping of the packet coming from the network stack to add -+ * BDC, Hardware header etc, during network interface registration -+ * we set the 'net->hard_header_len' to ETH_HLEN + extra space required -+ * for BDC, Hardware header etc. and not just the ETH_HLEN -+ */ -+ eth = skb->data; -+ len = skb->len; -+ -+#ifdef DHD_RX_DUMP -+ dump_data = skb->data; -+ protocol = (dump_data[12] << 8) | dump_data[13]; -+ AP6210_ERR("RX DUMP - %s\n", _get_packet_type_str(protocol)); -+ -+#ifdef DHD_RX_FULL_DUMP -+ if (protocol != ETHER_TYPE_BRCM) { -+ for (k = 0; k < skb->len; k++) { -+ AP6210_ERR("%02X ", dump_data[k])); -+ if ((k & 15) == 15) -+ AP6210_ERR("\n"); -+ } -+ AP6210_ERR("\n"); -+ } -+#endif /* DHD_RX_FULL_DUMP */ -+ -+ if (protocol != ETHER_TYPE_BRCM) { -+ if (dump_data[0] == 0xFF) { -+ AP6210_ERR("%s: BROADCAST\n", __FUNCTION__); -+ -+ if ((dump_data[12] == 8) && -+ (dump_data[13] == 6)) { -+ AP6210_ERR("%s: ARP %d\n", -+ __FUNCTION__, dump_data[0x15]); -+ } -+ } else if (dump_data[0] & 1) { -+ AP6210_ERR("%s: MULTICAST: " MACDBG "\n", -+ __FUNCTION__, MAC2STRDBG(dump_data)); -+ } -+ -+ if (protocol == ETHER_TYPE_802_1X) { -+ AP6210_ERR("ETHER_TYPE_802_1X: " -+ "ver %d, type %d, replay %d\n", -+ dump_data[14], dump_data[15], -+ dump_data[30]); -+ } -+ } -+ -+#endif /* DHD_RX_DUMP */ -+ -+ ifp = dhd->iflist[ifidx]; -+ if (ifp == NULL) -+ ifp = dhd->iflist[0]; -+ -+ ASSERT(ifp); -+ skb->dev = ifp->net; -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ -+ if (skb->pkt_type == PACKET_MULTICAST) { -+ dhd->pub.rx_multicast++; -+ } -+ -+ skb->data = eth; -+ skb->len = len; -+ -+#ifdef WLMEDIA_HTSF -+ dhd_htsf_addrxts(dhdp, pktbuf); -+#endif -+ /* Strip header, count, deliver upward */ -+ skb_pull(skb, ETH_HLEN); -+ -+ /* Process special event packets and then discard them */ -+ if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) { -+ dhd_wl_host_event(dhd, &ifidx, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -+ skb->mac_header, -+#else -+ skb->mac.raw, -+#endif -+ &event, -+ &data); -+ -+ wl_event_to_host_order(&event); -+ if (!tout_ctrl) -+ tout_ctrl = DHD_PACKET_TIMEOUT_MS; -+#ifdef WLBTAMP -+ if (event.event_type == WLC_E_BTA_HCI_EVENT) { -+ dhd_bta_doevt(dhdp, data, event.datalen); -+ } -+#endif /* WLBTAMP */ -+ -+#if defined(PNO_SUPPORT) -+ if (event.event_type == WLC_E_PFN_NET_FOUND) { -+ /* enforce custom wake lock to garantee that Kernel not suspended */ -+ tout_ctrl = CUSTOM_PNO_EVENT_LOCK_xTIME * DHD_PACKET_TIMEOUT_MS; -+ } -+#endif /* PNO_SUPPORT */ -+ -+#ifdef DHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -+ PKTFREE(dhdp->osh, pktbuf, TRUE); -+ continue; -+#endif -+ } else { -+ tout_rx = DHD_PACKET_TIMEOUT_MS; -+ } -+ -+ ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); -+ if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) -+ ifp = dhd->iflist[ifidx]; -+ -+ if (ifp->net) -+ ifp->net->last_rx = jiffies; -+ -+ dhdp->dstats.rx_bytes += skb->len; -+ dhdp->rx_packets++; /* Local count */ -+ -+ if (in_interrupt()) { -+ netif_rx(skb); -+ } else { -+ /* If the receive is not processed inside an ISR, -+ * the softirqd must be woken explicitly to service -+ * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled -+ * by netif_rx_ni(), but in earlier kernels, we need -+ * to do it manually. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ netif_rx_ni(skb); -+#else -+ ulong flags; -+ netif_rx(skb); -+ local_irq_save(flags); -+ RAISE_RX_SOFTIRQ(); -+ local_irq_restore(flags); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ -+ } -+ } -+ -+ DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx); -+ DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl); -+} -+ -+void -+dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) -+{ -+ /* Linux version has nothing to do */ -+ return; -+} -+ -+void -+dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); -+ struct ether_header *eh; -+ uint16 type; -+#ifdef WLBTAMP -+ uint len; -+#endif -+ -+ dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL); -+ -+ eh = (struct ether_header *)PKTDATA(dhdp->osh, txp); -+ type = ntoh16(eh->ether_type); -+ -+ if (type == ETHER_TYPE_802_1X) -+ atomic_dec(&dhd->pend_8021x_cnt); -+ -+#ifdef WLBTAMP -+ /* Crack open the packet and check to see if it is BT HCI ACL data packet. -+ * If yes generate packet completion event. -+ */ -+ len = PKTLEN(dhdp->osh, txp); -+ -+ /* Generate ACL data tx completion event locally to avoid SDIO bus transaction */ -+ if ((type < ETHER_TYPE_MIN) && (len >= RFC1042_HDR_LEN)) { -+ struct dot11_llc_snap_header *lsh = (struct dot11_llc_snap_header *)&eh[1]; -+ -+ if (bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && -+ ntoh16(lsh->type) == BTA_PROT_L2CAP) { -+ -+ dhd_bta_tx_hcidata_complete(dhdp, txp, success); -+ } -+ } -+#endif /* WLBTAMP */ -+} -+ -+static struct net_device_stats * -+dhd_get_stats(struct net_device *net) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+ dhd_if_t *ifp; -+ int ifidx; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ifidx = dhd_net2idx(dhd, net); -+ if (ifidx == DHD_BAD_IF) { -+ AP6210_ERR("%s: BAD_IF\n", __FUNCTION__); -+ return NULL; -+ } -+ -+ ifp = dhd->iflist[ifidx]; -+ ASSERT(dhd && ifp); -+ -+ if (dhd->pub.up) { -+ /* Use the protocol to get dongle stats */ -+ dhd_prot_dstats(&dhd->pub); -+ } -+ -+ /* Copy dongle stats to net device stats */ -+ ifp->stats.rx_packets = dhd->pub.dstats.rx_packets; -+ ifp->stats.tx_packets = dhd->pub.dstats.tx_packets; -+ ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes; -+ ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes; -+ ifp->stats.rx_errors = dhd->pub.dstats.rx_errors; -+ ifp->stats.tx_errors = dhd->pub.dstats.tx_errors; -+ ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped; -+ ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped; -+ ifp->stats.multicast = dhd->pub.dstats.multicast; -+ -+ return &ifp->stats; -+} -+ -+#ifdef DHDTHREAD -+static int -+dhd_watchdog_thread(void *data) -+{ -+ tsk_ctl_t *tsk = (tsk_ctl_t *)data; -+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent; -+ /* This thread doesn't need any user-level access, -+ * so get rid of all our resources -+ */ -+ if (dhd_watchdog_prio > 0) { -+ struct sched_param param; -+ param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)? -+ dhd_watchdog_prio:(MAX_RT_PRIO-1); -+ setScheduler(current, SCHED_FIFO, ¶m); -+ } -+#ifndef USE_KTHREAD_API -+ DAEMONIZE("dhd_watchdog"); -+ -+ /* Run until signal received */ -+ complete(&tsk->completed); -+#endif -+ -+ while (1) -+ if (down_interruptible (&tsk->sema) == 0) { -+ unsigned long flags; -+ unsigned long jiffies_at_start = jiffies; -+ unsigned long time_lapse; -+ -+ SMP_RD_BARRIER_DEPENDS(); -+ if (tsk->terminated) { -+ break; -+ } -+ -+ dhd_os_sdlock(&dhd->pub); -+ if (dhd->pub.dongle_reset == FALSE) { -+ AP6210_DEBUG("%s:\n", __FUNCTION__); -+ -+ /* Call the bus module watchdog */ -+ dhd_bus_watchdog(&dhd->pub); -+ -+ flags = dhd_os_spin_lock(&dhd->pub); -+ /* Count the tick for reference */ -+ dhd->pub.tickcnt++; -+ time_lapse = jiffies - jiffies_at_start; -+ -+ /* Reschedule the watchdog */ -+ if (dhd->wd_timer_valid) -+ mod_timer(&dhd->timer, -+ jiffies + -+ msecs_to_jiffies(dhd_watchdog_ms) - -+ min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse)); -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ } -+ dhd_os_sdunlock(&dhd->pub); -+ } else { -+ break; -+ } -+ -+ complete_and_exit(&tsk->completed, 0); -+} -+#endif /* DHDTHREAD */ -+ -+static void dhd_watchdog(ulong data) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)data; -+ unsigned long flags; -+ -+ if (dhd->pub.dongle_reset) { -+ return; -+ } -+ -+#ifdef DHDTHREAD -+ if (dhd->thr_wdt_ctl.thr_pid >= 0) { -+ up(&dhd->thr_wdt_ctl.sema); -+ return; -+ } -+#endif /* DHDTHREAD */ -+ -+ dhd_os_sdlock(&dhd->pub); -+ /* Call the bus module watchdog */ -+ dhd_bus_watchdog(&dhd->pub); -+ -+ flags = dhd_os_spin_lock(&dhd->pub); -+ /* Count the tick for reference */ -+ dhd->pub.tickcnt++; -+ -+ /* Reschedule the watchdog */ -+ if (dhd->wd_timer_valid) -+ mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms)); -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ dhd_os_sdunlock(&dhd->pub); -+} -+ -+#ifdef DHDTHREAD -+static int -+dhd_dpc_thread(void *data) -+{ -+ tsk_ctl_t *tsk = (tsk_ctl_t *)data; -+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent; -+ -+ /* This thread doesn't need any user-level access, -+ * so get rid of all our resources -+ */ -+ if (dhd_dpc_prio > 0) -+ { -+ struct sched_param param; -+ param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1); -+ setScheduler(current, SCHED_FIFO, ¶m); -+ } -+#ifndef USE_KTHREAD_API -+ DAEMONIZE("dhd_dpc"); -+ /* DHD_OS_WAKE_LOCK is called in dhd_sched_dpc[dhd_linux.c] down below */ -+ -+ /* signal: thread has started */ -+ complete(&tsk->completed); -+#endif -+ -+ /* Run until signal received */ -+ while (1) { -+ if (down_interruptible(&tsk->sema) == 0) { -+ -+ SMP_RD_BARRIER_DEPENDS(); -+ if (tsk->terminated) { -+ break; -+ } -+ -+ /* Call bus dpc unless it indicated down (then clean stop) */ -+ if (dhd->pub.busstate != DHD_BUS_DOWN) { -+ if (dhd_bus_dpc(dhd->pub.bus)) { -+ up(&tsk->sema); -+ } -+ else { -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ } -+ } else { -+ if (dhd->pub.up) -+ dhd_bus_stop(dhd->pub.bus, TRUE); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ } -+ } -+ else -+ break; -+ } -+ -+ complete_and_exit(&tsk->completed, 0); -+} -+#endif /* DHDTHREAD */ -+ -+static void -+dhd_dpc(ulong data) -+{ -+ dhd_info_t *dhd; -+ -+ dhd = (dhd_info_t *)data; -+ -+ /* this (tasklet) can be scheduled in dhd_sched_dpc[dhd_linux.c] -+ * down below , wake lock is set, -+ * the tasklet is initialized in dhd_attach() -+ */ -+ /* Call bus dpc unless it indicated down (then clean stop) */ -+ if (dhd->pub.busstate != DHD_BUS_DOWN) { -+ if (dhd_bus_dpc(dhd->pub.bus)) -+ tasklet_schedule(&dhd->tasklet); -+ else -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ } else { -+ dhd_bus_stop(dhd->pub.bus, TRUE); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ } -+} -+ -+void -+dhd_sched_dpc(dhd_pub_t *dhdp) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -+ -+ DHD_OS_WAKE_LOCK(dhdp); -+#ifdef DHDTHREAD -+ if (dhd->thr_dpc_ctl.thr_pid >= 0) { -+ up(&dhd->thr_dpc_ctl.sema); -+ return; -+ } -+#endif /* DHDTHREAD */ -+ -+ if (dhd->dhd_tasklet_create) -+ tasklet_schedule(&dhd->tasklet); -+} -+ -+#ifdef TOE -+/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -+static int -+dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) -+{ -+ wl_ioctl_t ioc; -+ char buf[32]; -+ int ret; -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ -+ ioc.cmd = WLC_GET_VAR; -+ ioc.buf = buf; -+ ioc.len = (uint)sizeof(buf); -+ ioc.set = FALSE; -+ -+ strncpy(buf, "toe_ol", sizeof(buf) - 1); -+ buf[sizeof(buf) - 1] = '\0'; -+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { -+ /* Check for older dongle image that doesn't support toe_ol */ -+ if (ret == -EIO) { -+ AP6210_ERR("%s: toe not supported by device\n", -+ dhd_ifname(&dhd->pub, ifidx)); -+ return -EOPNOTSUPP; -+ } -+ -+ AP6210_DEBUG("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret); -+ return ret; -+ } -+ -+ memcpy(toe_ol, buf, sizeof(uint32)); -+ return 0; -+} -+ -+/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */ -+static int -+dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol) -+{ -+ wl_ioctl_t ioc; -+ char buf[32]; -+ int toe, ret; -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ -+ ioc.cmd = WLC_SET_VAR; -+ ioc.buf = buf; -+ ioc.len = (uint)sizeof(buf); -+ ioc.set = TRUE; -+ -+ /* Set toe_ol as requested */ -+ -+ strncpy(buf, "toe_ol", sizeof(buf) - 1); -+ buf[sizeof(buf) - 1] = '\0'; -+ memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32)); -+ -+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { -+ AP6210_ERR("%s: could not set toe_ol: ret=%d\n", -+ dhd_ifname(&dhd->pub, ifidx), ret); -+ return ret; -+ } -+ -+ /* Enable toe globally only if any components are enabled. */ -+ -+ toe = (toe_ol != 0); -+ -+ strcpy(buf, "toe"); -+ memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32)); -+ -+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { -+ AP6210_ERR("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret); -+ return ret; -+ } -+ -+ return 0; -+} -+#endif /* TOE */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -+static void -+dhd_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+ -+ snprintf(info->driver, sizeof(info->driver), "wl"); -+ snprintf(info->version, sizeof(info->version), "%lu", dhd->pub.drv_version); -+} -+ -+struct ethtool_ops dhd_ethtool_ops = { -+ .get_drvinfo = dhd_ethtool_get_drvinfo -+}; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -+ -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) -+static int -+dhd_ethtool(dhd_info_t *dhd, void *uaddr) -+{ -+ struct ethtool_drvinfo info; -+ char drvname[sizeof(info.driver)]; -+ uint32 cmd; -+#ifdef TOE -+ struct ethtool_value edata; -+ uint32 toe_cmpnt, csum_dir; -+ int ret; -+#endif -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* all ethtool calls start with a cmd word */ -+ if (copy_from_user(&cmd, uaddr, sizeof (uint32))) -+ return -EFAULT; -+ -+ switch (cmd) { -+ case ETHTOOL_GDRVINFO: -+ /* Copy out any request driver name */ -+ if (copy_from_user(&info, uaddr, sizeof(info))) -+ return -EFAULT; -+ strncpy(drvname, info.driver, sizeof(info.driver)); -+ drvname[sizeof(info.driver)-1] = '\0'; -+ -+ /* clear struct for return */ -+ memset(&info, 0, sizeof(info)); -+ info.cmd = cmd; -+ -+ /* if dhd requested, identify ourselves */ -+ if (strcmp(drvname, "?dhd") == 0) { -+ snprintf(info.driver, sizeof(info.driver), "dhd"); -+ strncpy(info.version, EPI_VERSION_STR, sizeof(info.version) - 1); -+ info.version[sizeof(info.version) - 1] = '\0'; -+ } -+ -+ /* otherwise, require dongle to be up */ -+ else if (!dhd->pub.up) { -+ AP6210_ERR("%s: dongle is not up\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ /* finally, report dongle driver type */ -+ else if (dhd->pub.iswl) -+ snprintf(info.driver, sizeof(info.driver), "wl"); -+ else -+ snprintf(info.driver, sizeof(info.driver), "xx"); -+ -+ snprintf(info.version, sizeof(info.version), "%lu", dhd->pub.drv_version); -+ if (copy_to_user(uaddr, &info, sizeof(info))) -+ return -EFAULT; -+ AP6210_DEBUG("%s: given %*s, returning %s\n", __FUNCTION__, -+ (int)sizeof(drvname), drvname, info.driver); -+ break; -+ -+#ifdef TOE -+ /* Get toe offload components from dongle */ -+ case ETHTOOL_GRXCSUM: -+ case ETHTOOL_GTXCSUM: -+ if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) -+ return ret; -+ -+ csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; -+ -+ edata.cmd = cmd; -+ edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; -+ -+ if (copy_to_user(uaddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ break; -+ -+ /* Set toe offload components in dongle */ -+ case ETHTOOL_SRXCSUM: -+ case ETHTOOL_STXCSUM: -+ if (copy_from_user(&edata, uaddr, sizeof(edata))) -+ return -EFAULT; -+ -+ /* Read the current settings, update and write back */ -+ if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0) -+ return ret; -+ -+ csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; -+ -+ if (edata.data != 0) -+ toe_cmpnt |= csum_dir; -+ else -+ toe_cmpnt &= ~csum_dir; -+ -+ if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0) -+ return ret; -+ -+ /* If setting TX checksum mode, tell Linux the new mode */ -+ if (cmd == ETHTOOL_STXCSUM) { -+ if (edata.data) -+ dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM; -+ else -+ dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM; -+ } -+ -+ break; -+#endif /* TOE */ -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ -+ -+static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) -+{ -+ dhd_info_t * dhd; -+ -+ if (!dhdp) -+ return FALSE; -+ -+ dhd = (dhd_info_t *)dhdp->info; -+ if (dhd->thr_sysioc_ctl.thr_pid < 0) { -+ AP6210_ERR("%s : skipped due to negative pid - unloading?\n", __FUNCTION__); -+ return FALSE; -+ } -+ -+ if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) || -+ ((dhdp->busstate == DHD_BUS_DOWN) && (!dhdp->dongle_reset))) { -+ AP6210_ERR("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__, -+ dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error, dhdp->busstate); -+ net_os_send_hang_message(net); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+static int -+dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+ dhd_ioctl_t ioc; -+ int bcmerror = 0; -+ int buflen = 0; -+ void *buf = NULL; -+ uint driver = 0; -+ int ifidx; -+ int ret; -+ -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ -+ /* send to dongle only if we are not waiting for reload already */ -+ if (dhd->pub.hang_was_sent) { -+ AP6210_ERR("%s: HANG was sent up earlier\n", __FUNCTION__); -+ DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return OSL_ERROR(BCME_DONGLE_DOWN); -+ } -+ -+ ifidx = dhd_net2idx(dhd, net); -+ AP6210_DEBUG("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd); -+ -+ if (ifidx == DHD_BAD_IF) { -+ AP6210_ERR("%s: BAD IF\n", __FUNCTION__); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return -1; -+ } -+ -+#if defined(CONFIG_WIRELESS_EXT) -+ /* linux wireless extensions */ -+ if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { -+ /* may recurse, do NOT lock */ -+ ret = wl_iw_ioctl(net, ifr, cmd); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return ret; -+ } -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) -+ if (cmd == SIOCETHTOOL) { -+ ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return ret; -+ } -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ -+ -+ if (cmd == SIOCDEVPRIVATE+1) { -+ ret = wl_android_priv_cmd(net, ifr, cmd); -+ dhd_check_hang(net, &dhd->pub, ret); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return ret; -+ } -+ -+ if (cmd != SIOCDEVPRIVATE) { -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return -EOPNOTSUPP; -+ } -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ -+ /* Copy the ioc control structure part of ioctl request */ -+ if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { -+ bcmerror = BCME_BADADDR; -+ goto done; -+ } -+ -+ /* Copy out any buffer passed */ -+ if (ioc.buf) { -+ if (ioc.len == 0) { -+ AP6210_DEBUG("%s: ioc.len=0, returns BCME_BADARG \n", __FUNCTION__); -+ bcmerror = BCME_BADARG; -+ goto done; -+ } -+ buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); -+ /* optimization for direct ioctl calls from kernel */ -+ /* -+ if (segment_eq(get_fs(), KERNEL_DS)) { -+ buf = ioc.buf; -+ } else { -+ */ -+ { -+ if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) { -+ bcmerror = BCME_NOMEM; -+ goto done; -+ } -+ if (copy_from_user(buf, ioc.buf, buflen)) { -+ bcmerror = BCME_BADADDR; -+ goto done; -+ } -+ } -+ } -+ -+ /* To differentiate between wl and dhd read 4 more byes */ -+ if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), -+ sizeof(uint)) != 0)) { -+ bcmerror = BCME_BADADDR; -+ goto done; -+ } -+ -+ if (!capable(CAP_NET_ADMIN)) { -+ bcmerror = BCME_EPERM; -+ goto done; -+ } -+ -+ /* check for local dhd ioctl and handle it */ -+ if (driver == DHD_IOCTL_MAGIC) { -+ bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); -+ if (bcmerror) -+ dhd->pub.bcmerror = bcmerror; -+ goto done; -+ } -+ -+ /* send to dongle (must be up, and wl). */ -+ if (dhd->pub.busstate != DHD_BUS_DATA) { -+ bcmerror = BCME_DONGLE_DOWN; -+ goto done; -+ } -+ -+ if (!dhd->pub.iswl) { -+ bcmerror = BCME_DONGLE_DOWN; -+ goto done; -+ } -+ -+ /* -+ * Flush the TX queue if required for proper message serialization: -+ * Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to -+ * prevent M4 encryption and -+ * intercept WLC_DISASSOC IOCTL - serialize WPS-DONE and WLC_DISASSOC IOCTL to -+ * prevent disassoc frame being sent before WPS-DONE frame. -+ */ -+ if (ioc.cmd == WLC_SET_KEY || -+ (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && -+ strncmp("wsec_key", ioc.buf, 9) == 0) || -+ (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && -+ strncmp("bsscfg:wsec_key", ioc.buf, 15) == 0) || -+ ioc.cmd == WLC_DISASSOC) -+ dhd_wait_pend8021x(net); -+ -+#ifdef WLMEDIA_HTSF -+ if (ioc.buf) { -+ /* short cut wl ioctl calls here */ -+ if (strcmp("htsf", ioc.buf) == 0) { -+ dhd_ioctl_htsf_get(dhd, 0); -+ return BCME_OK; -+ } -+ -+ if (strcmp("htsflate", ioc.buf) == 0) { -+ if (ioc.set) { -+ memset(ts, 0, sizeof(tstamp_t)*TSMAX); -+ memset(&maxdelayts, 0, sizeof(tstamp_t)); -+ maxdelay = 0; -+ tspktcnt = 0; -+ maxdelaypktno = 0; -+ memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN); -+ } else { -+ dhd_dump_latency(); -+ } -+ return BCME_OK; -+ } -+ if (strcmp("htsfclear", ioc.buf) == 0) { -+ memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN); -+ memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN); -+ htsf_seqnum = 0; -+ return BCME_OK; -+ } -+ if (strcmp("htsfhis", ioc.buf) == 0) { -+ dhd_dump_htsfhisto(&vi_d1, "H to D"); -+ dhd_dump_htsfhisto(&vi_d2, "D to D"); -+ dhd_dump_htsfhisto(&vi_d3, "D to H"); -+ dhd_dump_htsfhisto(&vi_d4, "H to H"); -+ return BCME_OK; -+ } -+ if (strcmp("tsport", ioc.buf) == 0) { -+ if (ioc.set) { -+ memcpy(&tsport, ioc.buf + 7, 4); -+ } else { -+ AP6210_ERR("current timestamp port: %d \n", tsport); -+ } -+ return BCME_OK; -+ } -+ } -+#endif /* WLMEDIA_HTSF */ -+ -+ if ((ioc.cmd == WLC_SET_VAR || ioc.cmd == WLC_GET_VAR) && -+ ioc.buf != NULL && strncmp("rpc_", ioc.buf, 4) == 0) { -+#ifdef BCM_FD_AGGR -+ bcmerror = dhd_fdaggr_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); -+#else -+ bcmerror = BCME_UNSUPPORTED; -+#endif -+ goto done; -+ } -+ bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); -+ -+done: -+ dhd_check_hang(net, &dhd->pub, bcmerror); -+ -+ if (!bcmerror && buf && ioc.buf) { -+ if (copy_to_user(ioc.buf, buf, buflen)) -+ bcmerror = -EFAULT; -+ } -+ -+ if (buf) -+ MFREE(dhd->pub.osh, buf, buflen); -+ -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ -+ return OSL_ERROR(bcmerror); -+} -+ -+#ifdef WL_CFG80211 -+static int -+dhd_cleanup_virt_ifaces(dhd_info_t *dhd) -+{ -+ int i = 1; /* Leave ifidx 0 [Primary Interface] */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ int rollback_lock = FALSE; -+#endif -+ -+ AP6210_DEBUG("%s: Enter \n", __func__); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ /* release lock for unregister_netdev */ -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = TRUE; -+ } -+#endif -+ -+ for (i = 1; i < DHD_MAX_IFS; i++) { -+ dhd_net_if_lock_local(dhd); -+ if (dhd->iflist[i]) { -+ AP6210_DEBUG("Deleting IF: %d \n", i); -+ if ((dhd->iflist[i]->state != DHD_IF_DEL) && -+ (dhd->iflist[i]->state != DHD_IF_DELETING)) { -+ dhd->iflist[i]->state = DHD_IF_DEL; -+ dhd->iflist[i]->idx = i; -+ dhd_op_if(dhd->iflist[i]); -+ } -+ } -+ dhd_net_if_unlock_local(dhd); -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ if (rollback_lock) -+ rtnl_lock(); -+#endif -+ -+ return 0; -+} -+#endif /* WL_CFG80211 */ -+ -+ -+static int -+dhd_stop(struct net_device *net) -+{ -+ int ifidx = 0; -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ AP6210_DEBUG("%s: Enter %p\n", __FUNCTION__, net); -+ if (dhd->pub.up == 0) { -+ goto exit; -+ } -+ ifidx = dhd_net2idx(dhd, net); -+ BCM_REFERENCE(ifidx); -+ -+ /* Set state and stop OS transmissions */ -+ netif_stop_queue(net); -+ dhd->pub.up = 0; -+ -+#ifdef WL_CFG80211 -+ if (ifidx == 0) { -+ wl_cfg80211_down(NULL); -+ -+ /* -+ * For CFG80211: Clean up all the left over virtual interfaces -+ * when the primary Interface is brought down. [ifconfig wlan0 down] -+ */ -+ if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) && -+ (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { -+ dhd_cleanup_virt_ifaces(dhd); -+ } -+ } -+#endif -+ -+#ifdef PROP_TXSTATUS -+ dhd_os_wlfc_block(&dhd->pub); -+ dhd_wlfc_cleanup(&dhd->pub); -+ dhd_os_wlfc_unblock(&dhd->pub); -+#endif -+ /* Stop the protocol module */ -+ dhd_prot_stop(&dhd->pub); -+ -+ OLD_MOD_DEC_USE_COUNT; -+exit: -+#if defined(WL_CFG80211) -+ if (ifidx == 0) { -+ if (!dhd_download_fw_on_driverload) -+ wl_android_wifi_off(net); -+ } -+#endif -+ dhd->pub.rxcnt_timeout = 0; -+ dhd->pub.txcnt_timeout = 0; -+ -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ return 0; -+} -+ -+static int -+dhd_open(struct net_device *net) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); -+#ifdef TOE -+ uint32 toe_ol; -+#endif -+ int ifidx; -+ int32 ret = 0; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { -+ AP6210_ERR("%s : dhd_open: call dev open before insmod complete!\n", __FUNCTION__); -+ } -+ mutex_lock(&_dhd_sdio_mutex_lock_); -+#endif -+ -+ AP6210_DEBUG("%s, firmware path %s\n", __func__, firmware_path); -+ -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ /* Update FW path if it was changed */ -+ if (strlen(firmware_path) != 0) { -+ if (firmware_path[strlen(firmware_path)-1] == '\n') -+ firmware_path[strlen(firmware_path)-1] = '\0'; -+ COPY_FW_PATH_BY_CHIP( dhd->pub.bus, fw_path, firmware_path); -+ } -+ -+ -+ dhd->pub.dongle_trap_occured = 0; -+ dhd->pub.hang_was_sent = 0; -+#if !defined(WL_CFG80211) -+ /* -+ * Force start if ifconfig_up gets called before START command -+ * We keep WEXT's wl_control_wl_start to provide backward compatibility -+ * This should be removed in the future -+ */ -+ ret = wl_control_wl_start(net); -+ if (ret != 0) { -+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret); -+ ret = -1; -+ goto exit; -+ } -+#endif -+ -+ ifidx = dhd_net2idx(dhd, net); -+ AP6210_DEBUG("%s: ifidx %d\n", __FUNCTION__, ifidx); -+ -+ if (ifidx < 0) { -+ AP6210_ERR("%s: Error: called with invalid IF\n", __FUNCTION__); -+ ret = -1; -+ goto exit; -+ } -+ -+ if (!dhd->iflist[ifidx] || dhd->iflist[ifidx]->state == DHD_IF_DEL) { -+ AP6210_ERR("%s: Error: called when IF already deleted\n", __FUNCTION__); -+ ret = -1; -+ goto exit; -+ } -+ -+ if (ifidx == 0) { -+ atomic_set(&dhd->pend_8021x_cnt, 0); -+#if defined(WL_CFG80211) -+ AP6210_ERR("%s\n", dhd_version); -+#if defined(DHD_DEBUG) -+ AP6210_ERR("%s\n", dhd_version_info); -+#endif -+ -+ if (!dhd_download_fw_on_driverload) { -+ ret = wl_android_wifi_on(net); -+ if (ret != 0) { -+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret); -+ ret = -1; -+ goto exit; -+ } -+ } else { -+ } -+#endif -+ -+ if (dhd->pub.busstate != DHD_BUS_DATA) { -+ -+ /* try to bring up bus */ -+ if ((ret = dhd_bus_start(&dhd->pub)) != 0) { -+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret); -+ ret = -1; -+ goto exit; -+ } -+ -+ } -+ -+ /* dhd_prot_init has been called in dhd_bus_start or wl_android_wifi_on */ -+ memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); -+ -+#ifdef TOE -+ /* Get current TOE mode from dongle */ -+ if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) -+ dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM; -+ else -+ dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM; -+#endif /* TOE */ -+ -+#if defined(WL_CFG80211) -+ if (unlikely(wl_cfg80211_up(NULL))) { -+ AP6210_ERR("%s: failed to bring up cfg80211\n", __FUNCTION__); -+ ret = -1; -+ goto exit; -+ } -+#endif /* WL_CFG80211 */ -+ } -+ -+ /* Allow transmit calls */ -+ netif_start_queue(net); -+ dhd->pub.up = 1; -+ -+#ifdef BCMDBGFS -+ dhd_dbg_init(&dhd->pub); -+#endif -+ -+ OLD_MOD_INC_USE_COUNT; -+exit: -+ if (ret) -+ dhd_stop(net); -+ -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ mutex_unlock(&_dhd_sdio_mutex_lock_); -+#endif -+ return ret; -+} -+ -+int dhd_do_driver_init(struct net_device *net) -+{ -+ dhd_info_t *dhd = NULL; -+ -+ if (!net) { -+ AP6210_ERR("Primary Interface not initialized \n"); -+ return -EINVAL; -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+#ifdef MULTIPLE_SUPPLICANT -+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { -+ AP6210_ERR("%s : dhdsdio_probe is already running!\n", __FUNCTION__); -+ return 0; -+ } -+#endif /* MULTIPLE_SUPPLICANT */ -+#endif -+ -+ dhd = *(dhd_info_t **)netdev_priv(net); -+ -+ /* If driver is already initialized, do nothing -+ */ -+ if (dhd->pub.busstate == DHD_BUS_DATA) { -+ AP6210_DEBUG("Driver already Inititalized. Nothing to do"); -+ return 0; -+ } -+ -+ if (dhd_open(net) < 0) { -+ AP6210_ERR("Driver Init Failed \n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+osl_t * -+dhd_osl_attach(void *pdev, uint bustype) -+{ -+ return osl_attach(pdev, bustype, TRUE); -+} -+ -+void -+dhd_osl_detach(osl_t *osh) -+{ -+ if (MALLOCED(osh)) { -+ AP6210_ERR("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh)); -+ } -+ osl_detach(osh); -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ dhd_registration_check = FALSE; -+ up(&dhd_registration_sem); -+#if defined(BCMLXSDMMC) -+ up(&dhd_chipup_sem); -+#endif -+#endif -+} -+ -+int -+dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, -+ uint8 *mac_addr, uint32 flags, uint8 bssidx) -+{ -+ dhd_if_t *ifp; -+ -+ AP6210_DEBUG("%s: idx %d, handle->%p\n", __FUNCTION__, ifidx, handle); -+ -+ ASSERT(dhd && (ifidx < DHD_MAX_IFS)); -+ -+ ifp = dhd->iflist[ifidx]; -+ if (ifp != NULL) { -+ if (ifp->net != NULL) { -+ netif_stop_queue(ifp->net); -+ unregister_netdev(ifp->net); -+ free_netdev(ifp->net); -+ } -+ } else -+ if ((ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t))) == NULL) { -+ AP6210_ERR("%s: OOM - dhd_if_t\n", __FUNCTION__); -+ return -ENOMEM; -+ } -+ -+ memset(ifp, 0, sizeof(dhd_if_t)); -+ ifp->event2cfg80211 = FALSE; -+ ifp->info = dhd; -+ dhd->iflist[ifidx] = ifp; -+ strncpy(ifp->name, name, IFNAMSIZ); -+ ifp->name[IFNAMSIZ] = '\0'; -+ if (mac_addr != NULL) -+ memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); -+ -+ if (handle == NULL) { -+ ifp->state = DHD_IF_ADD; -+ ifp->idx = ifidx; -+ ifp->bssidx = bssidx; -+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); -+ up(&dhd->thr_sysioc_ctl.sema); -+ } else -+ ifp->net = (struct net_device *)handle; -+ -+ if (ifidx == 0) { -+ ifp->event2cfg80211 = TRUE; -+ } -+ -+ return 0; -+} -+ -+void -+dhd_del_if(dhd_info_t *dhd, int ifidx) -+{ -+ dhd_if_t *ifp; -+ -+ AP6210_DEBUG("%s: idx %d\n", __FUNCTION__, ifidx); -+ -+ ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS)); -+ ifp = dhd->iflist[ifidx]; -+ if (!ifp) { -+ AP6210_ERR("%s: Null interface\n", __FUNCTION__); -+ return; -+ } -+ -+ ifp->state = DHD_IF_DEL; -+ ifp->idx = ifidx; -+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); -+ up(&dhd->thr_sysioc_ctl.sema); -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -+static struct net_device_ops dhd_ops_pri = { -+ .ndo_open = dhd_open, -+ .ndo_stop = dhd_stop, -+ .ndo_get_stats = dhd_get_stats, -+ .ndo_do_ioctl = dhd_ioctl_entry, -+ .ndo_start_xmit = dhd_start_xmit, -+ .ndo_set_mac_address = dhd_set_mac_address, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ .ndo_set_rx_mode = dhd_set_multicast_list, -+#else -+ .ndo_set_multicast_list = dhd_set_multicast_list, -+#endif -+}; -+ -+static struct net_device_ops dhd_ops_virt = { -+ .ndo_get_stats = dhd_get_stats, -+ .ndo_do_ioctl = dhd_ioctl_entry, -+ .ndo_start_xmit = dhd_start_xmit, -+ .ndo_set_mac_address = dhd_set_mac_address, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ .ndo_set_rx_mode = dhd_set_multicast_list, -+#else -+ .ndo_set_multicast_list = dhd_set_multicast_list, -+#endif -+}; -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */ -+ -+dhd_pub_t * -+dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) -+{ -+ dhd_info_t *dhd = NULL; -+ struct net_device *net = NULL; -+ -+ dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT; -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ AP6210_DEBUG("%s, firmware path %s\n", __func__, firmware_path); -+ -+ /* updates firmware nvram path if it was provided as module parameters */ -+ if ((firmware_path != NULL) && (firmware_path[0] != '\0')) -+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); -+ if (strlen(nvram_path) != 0) { -+ strncpy(nv_path, nvram_path, sizeof(nv_path) -1); -+ nv_path[sizeof(nv_path) -1] = '\0'; -+ } -+ -+ /* Allocate etherdev, including space for private structure */ -+ if (!(net = alloc_etherdev(sizeof(dhd)))) { -+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__); -+ goto fail; -+ } -+ dhd_state |= DHD_ATTACH_STATE_NET_ALLOC; -+ -+ /* Allocate primary dhd_info */ -+ if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) { -+ AP6210_ERR("%s: OOM - alloc dhd_info\n", __FUNCTION__); -+ goto fail; -+ } -+ memset(dhd, 0, sizeof(dhd_info_t)); -+ -+#ifdef DHDTHREAD -+ dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID; -+ dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID; -+#endif /* DHDTHREAD */ -+ dhd->dhd_tasklet_create = FALSE; -+ dhd->thr_sysioc_ctl.thr_pid = DHD_PID_KT_INVALID; -+ dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC; -+ -+ /* -+ * Save the dhd_info into the priv -+ */ -+ memcpy((void *)netdev_priv(net), &dhd, sizeof(dhd)); -+ dhd->pub.osh = osh; -+ -+ /* Link to info module */ -+ dhd->pub.info = dhd; -+ /* Link to bus module */ -+ dhd->pub.bus = bus; -+ dhd->pub.hdrlen = bus_hdrlen; -+ -+ /* Set network interface name if it was provided as module parameter */ -+ if (iface_name[0]) { -+ int len; -+ char ch; -+ strncpy(net->name, iface_name, IFNAMSIZ); -+ net->name[IFNAMSIZ - 1] = 0; -+ len = strlen(net->name); -+ ch = net->name[len - 1]; -+ if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) -+ strcat(net->name, "%d"); -+ } -+ -+ if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF) -+ goto fail; -+ dhd_state |= DHD_ATTACH_STATE_ADD_IF; -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) -+ net->open = NULL; -+#else -+ net->netdev_ops = NULL; -+#endif -+ -+ sema_init(&dhd->proto_sem, 1); -+ -+#ifdef PROP_TXSTATUS -+ spin_lock_init(&dhd->wlfc_spinlock); -+#ifdef PROP_TXSTATUS_VSDB -+ dhd->pub.wlfc_enabled = FALSE; -+#else -+ dhd->pub.wlfc_enabled = TRUE; -+#endif /* PROP_TXSTATUS_VSDB */ -+#endif /* PROP_TXSTATUS */ -+ -+ /* Initialize other structure content */ -+ init_waitqueue_head(&dhd->ioctl_resp_wait); -+ init_waitqueue_head(&dhd->ctrl_wait); -+ -+ /* Initialize the spinlocks */ -+ spin_lock_init(&dhd->sdlock); -+ spin_lock_init(&dhd->txqlock); -+ spin_lock_init(&dhd->dhd_lock); -+ -+ /* Initialize Wakelock stuff */ -+ spin_lock_init(&dhd->wakelock_spinlock); -+ dhd->wakelock_counter = 0; -+ dhd->wakelock_wd_counter = 0; -+ dhd->wakelock_rx_timeout_enable = 0; -+ dhd->wakelock_ctrl_timeout_enable = 0; -+#ifdef CONFIG_HAS_WAKELOCK -+ dhd->wl_wifi = MALLOC(osh, sizeof(struct wake_lock)); -+ dhd->wl_rxwake = MALLOC(osh, sizeof(struct wake_lock)); -+ dhd->wl_ctrlwake = MALLOC(osh, sizeof(struct wake_lock)); -+ dhd->wl_wdwake = MALLOC(osh, sizeof(struct wake_lock)); -+ if (!dhd->wl_wifi || !dhd->wl_rxwake || !dhd->wl_ctrlwake || !dhd->wl_wdwake) { -+ AP6210_ERR("%s: mem alloc for wake lock failed\n", __FUNCTION__); -+ goto fail; -+ } -+ wake_lock_init(dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); -+ wake_lock_init(dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); -+ wake_lock_init(dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake"); -+ wake_lock_init(dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake"); -+#endif /* CONFIG_HAS_WAKELOCK */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ mutex_init(&dhd->dhd_net_if_mutex); -+ mutex_init(&dhd->dhd_suspend_mutex); -+#endif -+ dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT; -+ -+ /* Attach and link in the protocol */ -+ if (dhd_prot_attach(&dhd->pub) != 0) { -+ AP6210_ERR("dhd_prot_attach failed\n"); -+ goto fail; -+ } -+ dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH; -+ -+#ifdef WL_CFG80211 -+ /* Attach and link in the cfg80211 */ -+ if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) { -+ AP6210_ERR("wl_cfg80211_attach failed\n"); -+ goto fail; -+ } -+ -+ dhd_monitor_init(&dhd->pub); -+ dhd_state |= DHD_ATTACH_STATE_CFG80211; -+#endif -+#if defined(CONFIG_WIRELESS_EXT) -+ /* Attach and link in the iw */ -+ if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) { -+ if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { -+ AP6210_ERR("wl_iw_attach failed\n"); -+ goto fail; -+ } -+ dhd_state |= DHD_ATTACH_STATE_WL_ATTACH; -+ } -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+ -+ /* Set up the watchdog timer */ -+ init_timer(&dhd->timer); -+ dhd->timer.data = (ulong)dhd; -+ dhd->timer.function = dhd_watchdog; -+ -+#ifdef DHDTHREAD -+ /* Initialize thread based operation and lock */ -+ sema_init(&dhd->sdsem, 1); -+ if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) { -+ dhd->threads_only = TRUE; -+ } -+ else { -+ dhd->threads_only = FALSE; -+ } -+ -+ if (dhd_watchdog_prio >= 0) { -+ /* Initialize watchdog thread */ -+#ifdef USE_KTHREAD_API -+ PROC_START2(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0, "dhd_watchdog_thread"); -+#else -+ PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0); -+#endif -+ } else { -+ dhd->thr_wdt_ctl.thr_pid = -1; -+ } -+ -+ /* Set up the bottom half handler */ -+ if (dhd_dpc_prio >= 0) { -+ /* Initialize DPC thread */ -+#ifdef USE_KTHREAD_API -+ PROC_START2(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0, "dhd_dpc"); -+#else -+ PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0); -+#endif -+ } else { -+ /* use tasklet for dpc */ -+ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); -+ dhd->thr_dpc_ctl.thr_pid = -1; -+ } -+#else -+ /* Set up the bottom half handler */ -+ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); -+ dhd->dhd_tasklet_create = TRUE; -+#endif /* DHDTHREAD */ -+ -+ if (dhd_sysioc) { -+#ifdef USE_KTHREAD_API -+ PROC_START2(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0, "dhd_sysioc"); -+#else -+ PROC_START(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0); -+#endif -+ } else { -+ dhd->thr_sysioc_ctl.thr_pid = -1; -+ } -+ dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) -+ INIT_WORK(&dhd->work_hang, dhd_hang_process); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ /* -+ * Save the dhd_info into the priv -+ */ -+ memcpy(netdev_priv(net), &dhd, sizeof(dhd)); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+ register_pm_notifier(&dhd_sleep_pm_notifier); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+ dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; -+ dhd->early_suspend.suspend = dhd_early_suspend; -+ dhd->early_suspend.resume = dhd_late_resume; -+ register_early_suspend(&dhd->early_suspend); -+ dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE; -+#endif -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ dhd->pend_ipaddr = 0; -+ register_inetaddr_notifier(&dhd_notifier); -+#endif /* ARP_OFFLOAD_SUPPORT */ -+#ifdef IPV6 -+ register_inet6addr_notifier(&dhd_notifier_ipv6); -+#endif -+ -+#ifdef DHDTCPACK_SUPPRESS -+ dhd->pub.tcp_ack_info_cnt = 0; -+ bzero(dhd->pub.tcp_ack_info_tbl, sizeof(struct tcp_ack_info)*MAXTCPSTREAMS); -+#endif /* DHDTCPACK_SUPPRESS */ -+ -+ dhd_state |= DHD_ATTACH_STATE_DONE; -+ dhd->dhd_state = dhd_state; -+ return &dhd->pub; -+ -+fail: -+ if (dhd_state < DHD_ATTACH_STATE_DHD_ALLOC) { -+ if (net) free_netdev(net); -+ } else { -+ AP6210_DEBUG("%s: Calling dhd_detach dhd_state 0x%x &dhd->pub %p\n", -+ __FUNCTION__, dhd_state, &dhd->pub); -+ dhd->dhd_state = dhd_state; -+ dhd_detach(&dhd->pub); -+ dhd_free(&dhd->pub); -+ } -+ -+ return NULL; -+} -+ -+int -+dhd_bus_start(dhd_pub_t *dhdp) -+{ -+ int ret = -1; -+ dhd_info_t *dhd = (dhd_info_t*)dhdp->info; -+ unsigned long flags; -+ -+ ASSERT(dhd); -+ -+ AP6210_DEBUG("Enter %s:\n", __FUNCTION__); -+ -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdlock(dhdp); -+#endif /* DHDTHREAD */ -+ -+ -+ /* try to download image and nvram to the dongle */ -+ if ((dhd->pub.busstate == DHD_BUS_DOWN) && -+ (fw_path != NULL) && (fw_path[0] != '\0') && -+ (nv_path != NULL) && (nv_path[0] != '\0')) { -+ /* wake lock moved to dhdsdio_download_firmware */ -+ if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, -+ fw_path, nv_path))) { -+ AP6210_ERR("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n", -+ __FUNCTION__, fw_path, nv_path); -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ return -1; -+ } -+ } -+ if (dhd->pub.busstate != DHD_BUS_LOAD) { -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ return -ENETDOWN; -+ } -+ -+ /* Start the watchdog timer */ -+ dhd->pub.tickcnt = 0; -+ dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); -+ -+ /* Bring up the bus */ -+ if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) { -+ -+ AP6210_ERR("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret); -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ return ret; -+ } -+ bcmsdh_set_drvdata(dhdp); -+#if defined(OOB_INTR_ONLY) -+ /* Host registration for OOB interrupt */ -+ if (bcmsdh_register_oob_intr(dhdp)) { -+ /* deactivate timer and wait for the handler to finish */ -+ -+ flags = dhd_os_spin_lock(&dhd->pub); -+ dhd->wd_timer_valid = FALSE; -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ del_timer_sync(&dhd->timer); -+ AP6210_ERR("%s Host failed to register for OOB\n", __FUNCTION__); -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub); -+ return -ENODEV; -+ } -+ -+ /* Enable oob at firmware */ -+ dhd_enable_oob_intr(dhd->pub.bus, TRUE); -+#endif -+ -+ /* If bus is not ready, can't come up */ -+ if (dhd->pub.busstate != DHD_BUS_DATA) { -+ flags = dhd_os_spin_lock(&dhd->pub); -+ dhd->wd_timer_valid = FALSE; -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ del_timer_sync(&dhd->timer); -+ AP6210_ERR("%s failed bus is not ready\n", __FUNCTION__); -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub); -+ return -ENODEV; -+ } -+ -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ -+#ifdef BCMSDIOH_TXGLOM -+ if ((dhd->pub.busstate == DHD_BUS_DATA) && bcmsdh_glom_enabled()) { -+ dhd_txglom_enable(dhdp, TRUE); -+ } -+#endif -+ -+#ifdef READ_MACADDR -+ dhd_read_macaddr(dhd); -+#endif -+ -+ /* Bus is ready, do any protocol initialization */ -+ if ((ret = dhd_prot_init(&dhd->pub)) < 0) -+ return ret; -+ -+#ifdef WRITE_MACADDR -+ dhd_write_macaddr(dhd->pub.mac.octet); -+#endif -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ if (dhd->pend_ipaddr) { -+#ifdef AOE_IP_ALIAS_SUPPORT -+ aoe_update_host_ipv4_table(&dhd->pub, dhd->pend_ipaddr, TRUE, 0); -+#endif /* AOE_IP_ALIAS_SUPPORT */ -+ dhd->pend_ipaddr = 0; -+ } -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+ return 0; -+} -+ -+bool dhd_is_concurrent_mode(dhd_pub_t *dhd) -+{ -+ if (!dhd) -+ return FALSE; -+ -+ if (dhd->op_mode & DHD_FLAG_CONCURR_MULTI_CHAN_MODE) -+ return TRUE; -+ else if ((dhd->op_mode & DHD_FLAG_CONCURR_SINGLE_CHAN_MODE) == -+ DHD_FLAG_CONCURR_SINGLE_CHAN_MODE) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+#if !defined(AP) && defined(WLP2P) -+/* From Android JerryBean release, the concurrent mode is enabled by default and the firmware -+ * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA -+ * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware -+ * would still be named as fw_bcmdhd_apsta. -+ */ -+uint32 -+dhd_get_concurrent_capabilites(dhd_pub_t *dhd) -+{ -+ int32 ret = 0; -+ char buf[WLC_IOCTL_SMLEN]; -+ bool mchan_supported = FALSE; -+ /* if dhd->op_mode is already set for HOSTAP, -+ * that means we only will use the mode as it is -+ */ -+ if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) -+ return 0; -+ memset(buf, 0, sizeof(buf)); -+ bcm_mkiovar("cap", 0, 0, buf, sizeof(buf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), -+ FALSE, 0)) < 0) { -+ AP6210_ERR("%s: Get Capability failed (error=%d)\n", -+ __FUNCTION__, ret); -+ return 0; -+ } -+ if (strstr(buf, "vsdb")) { -+ mchan_supported = TRUE; -+ } -+ if (strstr(buf, "p2p") == NULL) { -+ AP6210_DEBUG("Chip does not support p2p\n"); -+ return 0; -+ } -+ else { -+ /* Chip supports p2p but ensure that p2p is really implemented in firmware or not */ -+ memset(buf, 0, sizeof(buf)); -+ bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), -+ FALSE, 0)) < 0) { -+ AP6210_ERR("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret); -+ return 0; -+ } -+ else { -+ if (buf[0] == 1) { -+ /* By default, chip supports single chan concurrency, -+ * now lets check for mchan -+ */ -+ ret = DHD_FLAG_CONCURR_SINGLE_CHAN_MODE; -+ if (mchan_supported) -+ ret |= DHD_FLAG_CONCURR_MULTI_CHAN_MODE; -+#if defined(WL_ENABLE_P2P_IF) -+ /* For customer_hw4, although ICS, -+ * we still support concurrent mode -+ */ -+ return ret; -+#else -+ return 0; -+#endif -+ } -+ } -+ } -+ return 0; -+} -+#endif -+int -+dhd_preinit_ioctls(dhd_pub_t *dhd) -+{ -+ int ret = 0; -+ char eventmask[WL_EVENTING_MASK_LEN]; -+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -+ -+#if !defined(WL_CFG80211) -+ uint up = 0; -+#endif /* !defined(WL_CFG80211) */ -+ uint power_mode = PM_FAST; -+ uint32 dongle_align = DHD_SDALIGN; -+ uint32 glom = CUSTOM_GLOM_SETTING; -+#if defined(VSDB) || defined(ROAM_ENABLE) -+ uint bcn_timeout = 8; -+#else -+ uint bcn_timeout = 4; -+#endif -+#ifdef ENABLE_BCN_LI_BCN_WAKEUP -+ uint32 bcn_li_bcn = 1; -+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ -+ uint retry_max = 3; -+#if defined(ARP_OFFLOAD_SUPPORT) -+ int arpoe = 1; -+#endif -+ int scan_assoc_time = DHD_SCAN_ASSOC_ACTIVE_TIME; -+ int scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME; -+ int scan_passive_time = DHD_SCAN_PASSIVE_TIME; -+ char buf[WLC_IOCTL_SMLEN]; -+ char *ptr; -+ uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ -+#ifdef ROAM_ENABLE -+ uint roamvar = 0; -+ int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL}; -+ int roam_scan_period[2] = {10, WLC_BAND_ALL}; -+ int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL}; -+#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC -+ int roam_fullscan_period = 60; -+#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ -+ int roam_fullscan_period = 120; -+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ -+#else -+#ifdef DISABLE_BUILTIN_ROAM -+ uint roamvar = 1; -+#endif /* DISABLE_BUILTIN_ROAM */ -+#endif /* ROAM_ENABLE */ -+ -+#if defined(SOFTAP) -+ uint dtim = 1; -+#endif -+#if (defined(AP) && !defined(WLP2P)) || (!defined(AP) && defined(WL_CFG80211)) -+ uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */ -+ struct ether_addr p2p_ea; -+#endif -+ uint32 mimo_bw_cap = 1; /* Turn HT40 on in 2.4 GHz */ -+ -+#if defined(AP) || defined(WLP2P) -+ uint32 apsta = 1; /* Enable APSTA mode */ -+#endif /* defined(AP) || defined(WLP2P) */ -+#ifdef GET_CUSTOM_MAC_ENABLE -+ struct ether_addr ea_addr; -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+#ifdef DISABLE_11N -+ uint32 nmode = 0; -+#else -+#ifdef AMPDU_HOSTREORDER -+ uint32 hostreorder = 1; -+#endif -+#endif /* DISABLE_11N */ -+ dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM; -+#ifdef PROP_TXSTATUS -+#ifdef PROP_TXSTATUS_VSDB -+ dhd->wlfc_enabled = FALSE; -+ /* enable WLFC only if the firmware is VSDB */ -+#else -+ dhd->wlfc_enabled = TRUE; -+#endif /* PROP_TXSTATUS_VSDB */ -+#endif /* PROP_TXSTATUS */ -+ AP6210_DEBUG("Enter %s\n", __FUNCTION__); -+ dhd->op_mode = 0; -+#ifdef GET_CUSTOM_MAC_ENABLE -+ ret = dhd_custom_get_mac_address(ea_addr.octet); -+ if (!ret) { -+ memset(buf, 0, sizeof(buf)); -+ bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf)); -+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); -+ if (ret < 0) { -+ AP6210_ERR("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret); -+ return BCME_NOTUP; -+ } -+ memcpy(dhd->mac.octet, ea_addr.octet, ETHER_ADDR_LEN); -+ } else { -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+ /* Get the default device MAC address directly from firmware */ -+ memset(buf, 0, sizeof(buf)); -+ bcm_mkiovar("cur_etheraddr", 0, 0, buf, sizeof(buf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), -+ FALSE, 0)) < 0) { -+ AP6210_ERR("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret); -+ return BCME_NOTUP; -+ } -+ /* Update public MAC address after reading from Firmware */ -+ memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); -+ -+#ifdef GET_CUSTOM_MAC_ENABLE -+ } -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+ -+ AP6210_DEBUG("Firmware = %s\n", fw_path); -+ -+ if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || -+ (op_mode == DHD_FLAG_HOSTAP_MODE)) { -+#ifdef SET_RANDOM_MAC_SOFTAP -+ uint rand_mac; -+#endif -+ dhd->op_mode = DHD_FLAG_HOSTAP_MODE; -+#if defined(ARP_OFFLOAD_SUPPORT) -+ arpoe = 0; -+#endif -+#ifdef PKT_FILTER_SUPPORT -+ dhd_pkt_filter_enable = FALSE; -+#endif -+#ifdef SET_RANDOM_MAC_SOFTAP -+ srandom32((uint)jiffies); -+ rand_mac = random32(); -+ iovbuf[0] = 0x02; /* locally administered bit */ -+ iovbuf[1] = 0x1A; -+ iovbuf[2] = 0x11; -+ iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0; -+ iovbuf[4] = (unsigned char)(rand_mac >> 8); -+ iovbuf[5] = (unsigned char)(rand_mac >> 16); -+ -+ bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf)); -+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); -+ if (ret < 0) { -+ AP6210_ERR("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret); -+ } else -+ memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN); -+#endif /* SET_RANDOM_MAC_SOFTAP */ -+#if !defined(AP) && defined(WL_CFG80211) -+ /* Turn off MPC in AP mode */ -+ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, -+ sizeof(iovbuf), TRUE, 0)) < 0) { -+ AP6210_ERR("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret); -+ } -+#endif -+ -+ } -+ else { -+ uint32 concurrent_mode = 0; -+ if ((!op_mode && strstr(fw_path, "_p2p") != NULL) || -+ (op_mode == DHD_FLAG_P2P_MODE)) { -+#if defined(ARP_OFFLOAD_SUPPORT) -+ arpoe = 0; -+#endif -+#ifdef PKT_FILTER_SUPPORT -+ dhd_pkt_filter_enable = FALSE; -+#endif -+ dhd->op_mode = DHD_FLAG_P2P_MODE; -+ } -+ else -+ dhd->op_mode = DHD_FLAG_STA_MODE; -+#if !defined(AP) && defined(WLP2P) -+ if ((concurrent_mode = dhd_get_concurrent_capabilites(dhd))) { -+#if defined(ARP_OFFLOAD_SUPPORT) -+ arpoe = 1; -+#endif -+ dhd->op_mode |= concurrent_mode; -+ } -+ -+ /* Check if we are enabling p2p */ -+ if (dhd->op_mode & DHD_FLAG_P2P_MODE) { -+ bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, -+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { -+ AP6210_ERR("%s APSTA for P2P failed ret= %d\n", __FUNCTION__, ret); -+ } -+ -+ memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN); -+ ETHER_SET_LOCALADDR(&p2p_ea); -+ bcm_mkiovar("p2p_da_override", (char *)&p2p_ea, -+ ETHER_ADDR_LEN, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, -+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { -+ AP6210_ERR("%s p2p_da_override ret= %d\n", __FUNCTION__, ret); -+ } else { -+ AP6210_DEBUG("dhd_preinit_ioctls: p2p_da_override succeeded\n"); -+ } -+ } -+#else -+ (void)concurrent_mode; -+#endif -+ } -+ -+ AP6210_ERR("Firmware up: op_mode=0x%04x, " -+ "Broadcom Dongle Host Driver mac="MACDBG"\n", -+ dhd->op_mode, -+ MAC2STRDBG(dhd->mac.octet)); -+ /* Set Country code */ -+ if (dhd->dhd_cspec.ccode[0] != 0) { -+ bcm_mkiovar("country", (char *)&dhd->dhd_cspec, -+ sizeof(wl_country_t), iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ AP6210_ERR("%s: country code setting failed\n", __FUNCTION__); -+ } -+ -+ /* Set Listen Interval */ -+ bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ AP6210_ERR("%s assoc_listen failed %d\n", __FUNCTION__, ret); -+ -+#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM) -+ /* Disable built-in roaming to allowed ext supplicant to take care of roaming */ -+ bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */ -+#ifdef ROAM_ENABLE -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger, -+ sizeof(roam_trigger), TRUE, 0)) < 0) -+ AP6210_ERR("%s: roam trigger set failed %d\n", __FUNCTION__, ret); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_SCAN_PERIOD, roam_scan_period, -+ sizeof(roam_scan_period), TRUE, 0)) < 0) -+ AP6210_ERR("%s: roam scan period set failed %d\n", __FUNCTION__, ret); -+ if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta, -+ sizeof(roam_delta), TRUE, 0)) < 0) -+ AP6210_ERR("%s: roam delta set failed %d\n", __FUNCTION__, ret); -+ bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ AP6210_ERR("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret); -+#endif /* ROAM_ENABLE */ -+ -+ /* Set PowerSave mode */ -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); -+ -+ /* Match Host and Dongle rx alignment */ -+ bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ -+ if (glom != DEFAULT_GLOM_VALUE) { -+ AP6210_DEBUG("%s set glom=0x%X\n", __FUNCTION__, glom); -+ bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ } -+ -+ /* Setup timeout if Beacons are lost and roam is off to report link down */ -+ bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ /* Setup assoc_retry_max count to reconnect target AP in dongle */ -+ bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#if defined(AP) && !defined(WLP2P) -+ /* Turn off MPC in AP mode */ -+ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif /* defined(AP) && !defined(WLP2P) */ -+ -+ if (dhd_bus_chip_id(dhd) == BCM43341_CHIP_ID || dhd_bus_chip_id(dhd) == BCM4324_CHIP_ID) { -+ /* Turn on HT40 in 2.4 GHz */ -+ bcm_mkiovar("mimo_bw_cap", (char *)&mimo_bw_cap, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+ } -+ -+#if defined(SOFTAP) -+ if (ap_fw_loaded == TRUE) { -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0); -+ } -+#endif -+ -+#if defined(KEEP_ALIVE) -+ { -+ /* Set Keep Alive : be sure to use FW with -keepalive */ -+ int res; -+ -+#if defined(SOFTAP) -+ if (ap_fw_loaded == FALSE) -+#endif -+ if (!(dhd->op_mode & DHD_FLAG_HOSTAP_MODE)) { -+ if ((res = dhd_keep_alive_onoff(dhd)) < 0) -+ AP6210_ERR("%s set keeplive failed %d\n", -+ __FUNCTION__, res); -+ } -+ } -+#endif /* defined(KEEP_ALIVE) */ -+ -+ /* Read event_msgs mask */ -+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { -+ AP6210_ERR("%s read Event mask failed %d\n", __FUNCTION__, ret); -+ goto done; -+ } -+ bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); -+ -+ /* Setup event_msgs */ -+ setbit(eventmask, WLC_E_SET_SSID); -+ setbit(eventmask, WLC_E_PRUNE); -+ setbit(eventmask, WLC_E_AUTH); -+ setbit(eventmask, WLC_E_ASSOC); -+ setbit(eventmask, WLC_E_REASSOC); -+ setbit(eventmask, WLC_E_REASSOC_IND); -+ setbit(eventmask, WLC_E_DEAUTH); -+ setbit(eventmask, WLC_E_DEAUTH_IND); -+ setbit(eventmask, WLC_E_DISASSOC_IND); -+ setbit(eventmask, WLC_E_DISASSOC); -+ setbit(eventmask, WLC_E_JOIN); -+ setbit(eventmask, WLC_E_ASSOC_IND); -+ setbit(eventmask, WLC_E_PSK_SUP); -+ setbit(eventmask, WLC_E_LINK); -+ setbit(eventmask, WLC_E_NDIS_LINK); -+ setbit(eventmask, WLC_E_MIC_ERROR); -+ setbit(eventmask, WLC_E_ASSOC_REQ_IE); -+ setbit(eventmask, WLC_E_ASSOC_RESP_IE); -+#ifndef WL_CFG80211 -+ setbit(eventmask, WLC_E_PMKID_CACHE); -+ setbit(eventmask, WLC_E_TXFAIL); -+#endif -+ setbit(eventmask, WLC_E_JOIN_START); -+ setbit(eventmask, WLC_E_SCAN_COMPLETE); -+#ifdef WLMEDIA_HTSF -+ setbit(eventmask, WLC_E_HTSFSYNC); -+#endif /* WLMEDIA_HTSF */ -+#ifdef PNO_SUPPORT -+ setbit(eventmask, WLC_E_PFN_NET_FOUND); -+#endif /* PNO_SUPPORT */ -+ /* enable dongle roaming event */ -+ setbit(eventmask, WLC_E_ROAM); -+#ifdef WL_CFG80211 -+ setbit(eventmask, WLC_E_ESCAN_RESULT); -+ if (dhd->op_mode & DHD_FLAG_P2P_MODE) { -+ setbit(eventmask, WLC_E_ACTION_FRAME_RX); -+ setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE); -+ } -+#endif /* WL_CFG80211 */ -+ -+ /* Write updated Event mask */ -+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { -+ AP6210_ERR("%s Set Event mask failed %d\n", __FUNCTION__, ret); -+ goto done; -+ } -+ -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, -+ sizeof(scan_assoc_time), TRUE, 0); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, -+ sizeof(scan_unassoc_time), TRUE, 0); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, (char *)&scan_passive_time, -+ sizeof(scan_passive_time), TRUE, 0); -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ /* Set and enable ARP offload feature for STA only */ -+#if defined(SOFTAP) -+ if (arpoe && !ap_fw_loaded) { -+#else -+ if (arpoe) { -+#endif -+ dhd_arp_offload_enable(dhd, TRUE); -+ dhd_arp_offload_set(dhd, dhd_arp_mode); -+ } else { -+ dhd_arp_offload_enable(dhd, FALSE); -+ dhd_arp_offload_set(dhd, 0); -+ } -+ dhd_arp_enable = arpoe; -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+#ifdef PKT_FILTER_SUPPORT -+ /* Setup default defintions for pktfilter , enable in suspend */ -+ dhd->pktfilter_count = 5; -+ /* Setup filter to allow only unicast */ -+ dhd->pktfilter[0] = "100 0 0 0 0x01 0x00"; -+ dhd->pktfilter[1] = NULL; -+ dhd->pktfilter[2] = NULL; -+ dhd->pktfilter[3] = NULL; -+ /* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */ -+ dhd->pktfilter[4] = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB"; -+ dhd_set_packet_filter(dhd); -+ -+#if defined(SOFTAP) -+ if (ap_fw_loaded) { -+ dhd_enable_packet_filter(0, dhd); -+ } -+#endif /* defined(SOFTAP) */ -+ -+#endif /* PKT_FILTER_SUPPORT */ -+#ifdef DISABLE_11N -+ bcm_mkiovar("nmode", (char *)&nmode, 4, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ AP6210_ERR("%s wl nmode 0 failed %d\n", __FUNCTION__, ret); -+#else -+#ifdef AMPDU_HOSTREORDER -+ bcm_mkiovar("ampdu_hostreorder", (char *)&hostreorder, 4, buf, sizeof(buf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); -+#endif /* AMPDU_HOSTREORDER */ -+#endif /* DISABLE_11N */ -+ -+#if !defined(WL_CFG80211) -+ /* Force STA UP */ -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) { -+ AP6210_ERR("%s Setting WL UP failed %d\n", __FUNCTION__, ret); -+ goto done; -+ } -+#endif -+ -+#ifdef ENABLE_BCN_LI_BCN_WAKEUP -+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf)); -+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ -+ -+ /* query for 'ver' to get version info from firmware */ -+ memset(buf, 0, sizeof(buf)); -+ ptr = buf; -+ bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0) -+ AP6210_ERR("%s failed %d\n", __FUNCTION__, ret); -+ else { -+ bcmstrtok(&ptr, "\n", 0); -+ /* Print fw version info */ -+ AP6210_ERR("Firmware version = %s\n", buf); -+ -+ dhd_set_version_info(dhd, buf); -+ -+ DHD_BLOG(buf, strlen(buf) + 1); -+ DHD_BLOG(dhd_version, strlen(dhd_version) + 1); -+ DHD_BLOG(dhd_version_info, strlen(dhd_version_info) +1); -+ -+ /* Check and adjust IOCTL response timeout for Manufactring firmware */ -+ if (strstr(buf, MANUFACTRING_FW) != NULL) { -+ dhd_os_set_ioctl_resp_timeout(20000); -+ AP6210_ERR("%s : adjust IOCTL response time for Manufactring Firmware\n", -+ __FUNCTION__); -+ } -+ } -+ -+done: -+ return ret; -+} -+ -+ -+int -+dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set) -+{ -+ char buf[strlen(name) + 1 + cmd_len]; -+ int len = sizeof(buf); -+ wl_ioctl_t ioc; -+ int ret; -+ -+ len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len); -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ -+ ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR; -+ ioc.buf = buf; -+ ioc.len = len; -+ ioc.set = TRUE; -+ -+ ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); -+ if (!set && ret >= 0) -+ memcpy(cmd_buf, buf, cmd_len); -+ -+ return ret; -+} -+ -+int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx) -+{ -+ struct dhd_info *dhd = dhdp->info; -+ struct net_device *dev = NULL; -+ -+ ASSERT(dhd && dhd->iflist[ifidx]); -+ dev = dhd->iflist[ifidx]->net; -+ ASSERT(dev); -+ -+ if (netif_running(dev)) { -+ AP6210_ERR("%s: Must be down to change its MTU", dev->name); -+ return BCME_NOTDOWN; -+ } -+ -+#define DHD_MIN_MTU 1500 -+#define DHD_MAX_MTU 1752 -+ -+ if ((new_mtu < DHD_MIN_MTU) || (new_mtu > DHD_MAX_MTU)) { -+ AP6210_ERR("%s: MTU size %d is invalid.\n", __FUNCTION__, new_mtu); -+ return BCME_BADARG; -+ } -+ -+ dev->mtu = new_mtu; -+ return 0; -+} -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+/* add or remove AOE host ip(s) (up to 8 IPs on the interface) */ -+void -+aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx) -+{ -+ u32 ipv4_buf[MAX_IPV4_ENTRIES]; /* temp save for AOE host_ip table */ -+ int i; -+ int ret; -+ -+ bzero(ipv4_buf, sizeof(ipv4_buf)); -+ -+ /* display what we've got */ -+ ret = dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx); -+ AP6210_DEBUG("%s: hostip table read from Dongle:\n", __FUNCTION__); -+#ifdef AOE_DBG -+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */ -+#endif -+ /* now we saved hoste_ip table, clr it in the dongle AOE */ -+ dhd_aoe_hostip_clr(dhd_pub, idx); -+ -+ if (ret) { -+ AP6210_ERR("%s failed\n", __FUNCTION__); -+ return; -+ } -+ -+ for (i = 0; i < MAX_IPV4_ENTRIES; i++) { -+ if (add && (ipv4_buf[i] == 0)) { -+ ipv4_buf[i] = ipa; -+ add = FALSE; /* added ipa to local table */ -+ AP6210_DEBUG("%s: Saved new IP in temp arp_hostip[%d]\n", -+ __FUNCTION__, i); -+ } else if (ipv4_buf[i] == ipa) { -+ ipv4_buf[i] = 0; -+ AP6210_DEBUG("%s: removed IP:%x from temp table %d\n", -+ __FUNCTION__, ipa, i); -+ } -+ -+ if (ipv4_buf[i] != 0) { -+ /* add back host_ip entries from our local cache */ -+ dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i], idx); -+ AP6210_DEBUG("%s: added IP:%x to dongle arp_hostip[%d]\n\n", -+ __FUNCTION__, ipv4_buf[i], i); -+ } -+ } -+#ifdef AOE_DBG -+ /* see the resulting hostip table */ -+ dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx); -+ AP6210_DEBUG("%s: read back arp_hostip table:\n", __FUNCTION__); -+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */ -+#endif -+} -+ -+/* -+ * Notification mechanism from kernel to our driver. This function is called by the Linux kernel -+ * whenever there is an event related to an IP address. -+ * ptr : kernel provided pointer to IP address that has changed -+ */ -+static int dhd_device_event(struct notifier_block *this, -+ unsigned long event, -+ void *ptr) -+{ -+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ -+ dhd_info_t *dhd; -+ dhd_pub_t *dhd_pub; -+ int idx; -+ -+ if (!dhd_arp_enable) -+ return NOTIFY_DONE; -+ if (!ifa || !(ifa->ifa_dev->dev)) -+ return NOTIFY_DONE; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -+ /* Filter notifications meant for non Broadcom devices */ -+ if ((ifa->ifa_dev->dev->netdev_ops != &dhd_ops_pri) && -+ (ifa->ifa_dev->dev->netdev_ops != &dhd_ops_virt)) { -+#ifdef WLP2P -+ if (!wl_cfgp2p_is_ifops(ifa->ifa_dev->dev->netdev_ops)) -+#endif -+ return NOTIFY_DONE; -+ } -+#endif /* LINUX_VERSION_CODE */ -+ -+ dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev); -+ if (!dhd) -+ return NOTIFY_DONE; -+ -+ dhd_pub = &dhd->pub; -+ -+ if (dhd_pub->arp_version == 1) { -+ idx = 0; -+ } -+ else { -+ for (idx = 0; idx < DHD_MAX_IFS; idx++) { -+ if (dhd->iflist[idx] && dhd->iflist[idx]->net == ifa->ifa_dev->dev) -+ break; -+ } -+ if (idx < DHD_MAX_IFS) -+ AP6210_DEBUG("ifidx : %p %s %d\n", dhd->iflist[idx]->net, -+ dhd->iflist[idx]->name, dhd->iflist[idx]->idx); -+ else { -+ AP6210_ERR("Cannot find ifidx for(%s) set to 0\n", ifa->ifa_label); -+ idx = 0; -+ } -+ } -+ -+ switch (event) { -+ case NETDEV_UP: -+ AP6210_DEBUG("%s: [%s] Up IP: 0x%x\n", -+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address); -+ -+ if (dhd->pub.busstate != DHD_BUS_DATA) { -+ AP6210_ERR("%s: bus not ready, exit\n", __FUNCTION__); -+ if (dhd->pend_ipaddr) { -+ AP6210_ERR("%s: overwrite pending ipaddr: 0x%x\n", -+ __FUNCTION__, dhd->pend_ipaddr); -+ } -+ dhd->pend_ipaddr = ifa->ifa_address; -+ break; -+ } -+ -+#ifdef AOE_IP_ALIAS_SUPPORT -+ AP6210_DEBUG("%s:add aliased IP to AOE hostip cache\n", -+ __FUNCTION__); -+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE, idx); -+#endif -+ break; -+ -+ case NETDEV_DOWN: -+ AP6210_DEBUG("%s: [%s] Down IP: 0x%x\n", -+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address); -+ dhd->pend_ipaddr = 0; -+#ifdef AOE_IP_ALIAS_SUPPORT -+ AP6210_DEBUG("%s:interface is down, AOE clr all for this if\n", -+ __FUNCTION__); -+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx); -+#else -+ dhd_aoe_hostip_clr(&dhd->pub, idx); -+ dhd_aoe_arp_clr(&dhd->pub, idx); -+#endif /* AOE_IP_ALIAS_SUPPORT */ -+ break; -+ -+ default: -+ AP6210_DEBUG("%s: do noting for [%s] Event: %lu\n", -+ __func__, ifa->ifa_label, event); -+ break; -+ } -+ return NOTIFY_DONE; -+} -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+int -+dhd_net_attach(dhd_pub_t *dhdp, int ifidx) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -+ struct net_device *net = NULL; -+ int err = 0; -+ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 }; -+ -+ AP6210_DEBUG("%s: ifidx %d\n", __FUNCTION__, ifidx); -+ -+ ASSERT(dhd && dhd->iflist[ifidx]); -+ -+ net = dhd->iflist[ifidx]->net; -+ ASSERT(net); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) -+ ASSERT(!net->open); -+ net->get_stats = dhd_get_stats; -+ net->do_ioctl = dhd_ioctl_entry; -+ net->hard_start_xmit = dhd_start_xmit; -+ net->set_mac_address = dhd_set_mac_address; -+ net->set_multicast_list = dhd_set_multicast_list; -+ net->open = net->stop = NULL; -+#else -+ ASSERT(!net->netdev_ops); -+ net->netdev_ops = &dhd_ops_virt; -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ -+ -+ /* Ok, link into the network layer... */ -+ if (ifidx == 0) { -+ /* -+ * device functions for the primary interface only -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) -+ net->open = dhd_open; -+ net->stop = dhd_stop; -+#else -+ net->netdev_ops = &dhd_ops_pri; -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ -+ if (!ETHER_ISNULLADDR(dhd->pub.mac.octet)) -+ memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); -+ } else { -+ /* -+ * We have to use the primary MAC for virtual interfaces -+ */ -+ memcpy(temp_addr, dhd->iflist[ifidx]->mac_addr, ETHER_ADDR_LEN); -+ /* -+ * Android sets the locally administered bit to indicate that this is a -+ * portable hotspot. This will not work in simultaneous AP/STA mode, -+ * nor with P2P. Need to set the Donlge's MAC address, and then use that. -+ */ -+ if (!memcmp(temp_addr, dhd->iflist[0]->mac_addr, -+ ETHER_ADDR_LEN)) { -+ AP6210_ERR("%s interface [%s]: set locally administered bit in MAC\n", -+ __func__, net->name); -+ temp_addr[0] |= 0x02; -+ } -+ } -+ -+ net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -+ net->ethtool_ops = &dhd_ethtool_ops; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -+ -+#if defined(CONFIG_WIRELESS_EXT) -+#if WIRELESS_EXT < 19 -+ net->get_wireless_stats = dhd_get_wireless_stats; -+#endif /* WIRELESS_EXT < 19 */ -+#if WIRELESS_EXT > 12 -+ net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def; -+#endif /* WIRELESS_EXT > 12 */ -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+ dhd->pub.rxsz = DBUS_RX_BUFFER_SIZE_DHD(net); -+ -+ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); -+ -+ if ((err = register_netdev(net)) != 0) { -+ AP6210_ERR("couldn't register the net device, err %d\n", err); -+ goto fail; -+ } -+ AP6210_ERR("Broadcom Dongle Host Driver: register interface [%s] MAC: "MACDBG"\n", -+ net->name, -+ MAC2STRDBG(net->dev_addr)); -+ -+#if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211) -+ wl_iw_iscan_set_scan_broadcast_prep(net, 1); -+#endif -+ -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ if (ifidx == 0) { -+ dhd_registration_check = TRUE; -+ up(&dhd_registration_sem); -+ } -+#endif -+ return 0; -+ -+fail: -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) -+ net->open = NULL; -+#else -+ net->netdev_ops = NULL; -+#endif -+ return err; -+} -+ -+void -+dhd_bus_detach(dhd_pub_t *dhdp) -+{ -+ dhd_info_t *dhd; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (dhdp) { -+ dhd = (dhd_info_t *)dhdp->info; -+ if (dhd) { -+ -+ /* -+ * In case of Android cfg80211 driver, the bus is down in dhd_stop, -+ * calling stop again will cuase SD read/write errors. -+ */ -+ if (dhd->pub.busstate != DHD_BUS_DOWN) { -+ /* Stop the protocol module */ -+ dhd_prot_stop(&dhd->pub); -+ -+ /* Stop the bus module */ -+ dhd_bus_stop(dhd->pub.bus, TRUE); -+ } -+ -+#if defined(OOB_INTR_ONLY) -+ bcmsdh_unregister_oob_intr(); -+#endif -+ } -+ } -+} -+ -+ -+void dhd_detach(dhd_pub_t *dhdp) -+{ -+ dhd_info_t *dhd; -+ unsigned long flags; -+ int timer_valid = FALSE; -+ -+ if (!dhdp) -+ return; -+ -+ dhd = (dhd_info_t *)dhdp->info; -+ if (!dhd) -+ return; -+ -+ AP6210_DEBUG("%s: Enter state 0x%x\n", __FUNCTION__, dhd->dhd_state); -+#ifdef ARP_OFFLOAD_SUPPORT -+ unregister_inetaddr_notifier(&dhd_notifier); -+#endif /* ARP_OFFLOAD_SUPPORT */ -+#ifdef IPV6 -+ unregister_inet6addr_notifier(&dhd_notifier_ipv6); -+#endif -+ -+ dhd->pub.up = 0; -+ if (!(dhd->dhd_state & DHD_ATTACH_STATE_DONE)) { -+ /* Give sufficient time for threads to start running in case -+ * dhd_attach() has failed -+ */ -+ osl_delay(1000*100); -+ } -+ -+ if (dhd->dhd_state & DHD_ATTACH_STATE_PROT_ATTACH) { -+ dhd_bus_detach(dhdp); -+ -+ if (dhdp->prot) -+ dhd_prot_detach(dhdp); -+ } -+ -+#ifdef ARP_OFFLOAD_SUPPORT -+ unregister_inetaddr_notifier(&dhd_notifier); -+#endif /* ARP_OFFLOAD_SUPPORT */ -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+ if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) { -+ if (dhd->early_suspend.suspend) -+ unregister_early_suspend(&dhd->early_suspend); -+ } -+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ cancel_work_sync(&dhd->work_hang); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+#if defined(CONFIG_WIRELESS_EXT) -+ if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) { -+ /* Detatch and unlink in the iw */ -+ wl_iw_detach(); -+ } -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+ if (dhd->thr_sysioc_ctl.thr_pid >= 0) { -+ PROC_STOP(&dhd->thr_sysioc_ctl); -+ } -+ -+ /* delete all interfaces, start with virtual */ -+ if (dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) { -+ int i = 1; -+ dhd_if_t *ifp; -+ -+ /* Cleanup virtual interfaces */ -+ for (i = 1; i < DHD_MAX_IFS; i++) { -+ dhd_net_if_lock_local(dhd); -+ if (dhd->iflist[i]) { -+ dhd->iflist[i]->state = DHD_IF_DEL; -+ dhd->iflist[i]->idx = i; -+ dhd_op_if(dhd->iflist[i]); -+ } -+ -+ dhd_net_if_unlock_local(dhd); -+ } -+ /* delete primary interface 0 */ -+ ifp = dhd->iflist[0]; -+ ASSERT(ifp); -+ ASSERT(ifp->net); -+ if (ifp && ifp->net) { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) -+ if (ifp->net->open) -+#else -+ if (ifp->net->netdev_ops == &dhd_ops_pri) -+#endif -+ { -+ unregister_netdev(ifp->net); -+ free_netdev(ifp->net); -+ ifp->net = NULL; -+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); -+ dhd->iflist[0] = NULL; -+ } -+ } -+ } -+ -+ /* Clear the watchdog timer */ -+ flags = dhd_os_spin_lock(&dhd->pub); -+ timer_valid = dhd->wd_timer_valid; -+ dhd->wd_timer_valid = FALSE; -+ dhd_os_spin_unlock(&dhd->pub, flags); -+ if (timer_valid) -+ del_timer_sync(&dhd->timer); -+ -+ if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) { -+#ifdef DHDTHREAD -+ if (dhd->thr_wdt_ctl.thr_pid >= 0) { -+ PROC_STOP(&dhd->thr_wdt_ctl); -+ } -+ -+ if (dhd->thr_dpc_ctl.thr_pid >= 0) { -+ PROC_STOP(&dhd->thr_dpc_ctl); -+ } -+ else -+#endif /* DHDTHREAD */ -+ tasklet_kill(&dhd->tasklet); -+ } -+ -+#ifdef WL_CFG80211 -+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { -+ wl_cfg80211_detach(NULL); -+ dhd_monitor_uninit(); -+ } -+#endif -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) -+ unregister_pm_notifier(&dhd_sleep_pm_notifier); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ -+ /* && defined(CONFIG_PM_SLEEP) */ -+ -+ if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) { -+#ifdef CONFIG_HAS_WAKELOCK -+ dhd->wakelock_counter = 0; -+ dhd->wakelock_wd_counter = 0; -+ dhd->wakelock_rx_timeout_enable = 0; -+ dhd->wakelock_ctrl_timeout_enable = 0; -+ if (dhd->wl_wifi) { -+ wake_lock_destroy(dhd->wl_wifi); -+ MFREE(dhd->pub.osh, dhd->wl_wifi, sizeof(struct wake_lock)); -+ dhd->wl_wifi = NULL; -+ } -+ if (dhd->wl_rxwake) { -+ wake_lock_destroy(dhd->wl_rxwake); -+ MFREE(dhd->pub.osh, dhd->wl_rxwake, sizeof(struct wake_lock)); -+ dhd->wl_rxwake = NULL; -+ } -+ if (dhd->wl_ctrlwake) { -+ wake_lock_destroy(dhd->wl_ctrlwake); -+ MFREE(dhd->pub.osh, dhd->wl_ctrlwake, sizeof(struct wake_lock)); -+ dhd->wl_ctrlwake = NULL; -+ } -+ if (dhd->wl_wdwake) { -+ wake_lock_destroy(dhd->wl_wdwake); -+ MFREE(dhd->pub.osh, dhd->wl_wdwake, sizeof(struct wake_lock)); -+ dhd->wl_wdwake = NULL; -+ } -+#endif /* CONFIG_HAS_WAKELOCK */ -+ } -+} -+ -+ -+void -+dhd_free(dhd_pub_t *dhdp) -+{ -+ dhd_info_t *dhd; -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (dhdp) { -+ int i; -+ for (i = 0; i < ARRAYSIZE(dhdp->reorder_bufs); i++) { -+ if (dhdp->reorder_bufs[i]) { -+ reorder_info_t *ptr; -+ uint32 buf_size = sizeof(struct reorder_info); -+ -+ ptr = dhdp->reorder_bufs[i]; -+ -+ buf_size += ((ptr->max_idx + 1) * sizeof(void*)); -+ AP6210_DEBUG("free flow id buf %d, maxidx is %d, buf_size %d\n", -+ i, ptr->max_idx, buf_size); -+ -+ MFREE(dhdp->osh, dhdp->reorder_bufs[i], buf_size); -+ dhdp->reorder_bufs[i] = NULL; -+ } -+ } -+ dhd = (dhd_info_t *)dhdp->info; -+ if (dhd) -+ MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); -+ } -+} -+ -+static void __exit -+dhd_module_cleanup(void) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ dhd_bus_unregister(); -+ -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ wl_android_wifictrl_func_del(); -+#endif /* CONFIG_WIFI_CONTROL_FUNC */ -+ wl_android_exit(); -+ -+ /* Call customer gpio to turn off power with WL_REG_ON signal */ -+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -+ -+ if (wl_host_wake > 0) -+ gpio_free(wl_host_wake); -+ wl_host_wake = -1; -+ -+ sw_rfkill_exit(); -+ ap6210_gpio_wifi_exit(); -+} -+ -+ -+static int __init -+dhd_module_init(void) -+{ -+ int error = 0; -+ -+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ int retry = POWERUP_MAX_RETRY; -+ int chip_up = 0; -+#endif -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ap6210_gpio_wifi_init(); -+ sw_rfkill_init(); -+ -+ if (gpio_request(WL_HOST_WAKE_DEF_GPIO, "wl_host_wake")) { -+ AP6210_ERR("[%s] get wl_host_wake gpio failed\n", __FUNCTION__); -+ wl_host_wake = -1; -+ return -1; -+ } -+ wl_host_wake = WL_HOST_WAKE_DEF_GPIO; -+ gpio_direction_input(wl_host_wake); -+ wl_host_wake_irqno = gpio_to_irq(wl_host_wake); -+ AP6210_DEBUG("got gpio%d, mapped to irqno%d\n", wl_host_wake, wl_host_wake_irqno); -+ -+ wl_android_init(); -+ -+#if defined(DHDTHREAD) -+ /* Sanity check on the module parameters */ -+ do { -+ /* Both watchdog and DPC as tasklets are ok */ -+ if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0)) -+ break; -+ -+ /* If both watchdog and DPC are threads, TX must be deferred */ -+ if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) && dhd_deferred_tx) -+ break; -+ -+ AP6210_ERR("Invalid module parameters.\n"); -+ return -EINVAL; -+ } while (0); -+#endif -+ -+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ do { -+ sema_init(&dhd_chipup_sem, 0); -+ dhd_bus_reg_sdio_notify(&dhd_chipup_sem); -+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ if (wl_android_wifictrl_func_add() < 0) { -+ dhd_bus_unreg_sdio_notify(); -+ goto fail_1; -+ } -+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -+ if (down_timeout(&dhd_chipup_sem, -+ msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) { -+ dhd_bus_unreg_sdio_notify(); -+ chip_up = 1; -+ break; -+ } -+ AP6210_ERR("failed to power up wifi chip, retry again (%d left) **\n\n", -+ retry+1); -+ dhd_bus_unreg_sdio_notify(); -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ wl_android_wifictrl_func_del(); -+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -+ } while (retry-- > 0); -+ -+ if (!chip_up) { -+ AP6210_ERR("failed to power up wifi chip, max retry reached, exits **\n\n"); -+ return -ENODEV; -+ } -+#else -+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ if (wl_android_wifictrl_func_add() < 0) -+ goto fail_1; -+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -+ -+#endif -+ -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ sema_init(&dhd_registration_sem, 0); -+#endif -+ -+ -+ error = dhd_bus_register(); -+ -+ if (!error) -+ AP6210_DEBUG("%s\n", dhd_version); -+ else { -+ AP6210_ERR("%s: sdio_register_driver failed\n", __FUNCTION__); -+ goto fail_1; -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ /* -+ * Wait till MMC sdio_register_driver callback called and made driver attach. -+ * It's needed to make sync up exit from dhd insmod and -+ * Kernel MMC sdio device callback registration -+ */ -+ if ((down_timeout(&dhd_registration_sem, -+ msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) || -+ (dhd_registration_check != TRUE)) { -+ error = -ENODEV; -+ AP6210_ERR("%s: sdio_register_driver timeout or error \n", __FUNCTION__); -+ goto fail_2; -+ } -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+#if defined(WL_CFG80211) -+ wl_android_post_init(); -+#endif /* defined(WL_CFG80211) */ -+ -+ return error; -+ -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+fail_2: -+ dhd_bus_unregister(); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+fail_1: -+ -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ wl_android_wifictrl_func_del(); -+#endif -+ -+ /* Call customer gpio to turn off power with WL_REG_ON signal */ -+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -+ -+ return error; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+late_initcall(dhd_module_init); -+#else -+module_init(dhd_module_init); -+#endif -+ -+module_exit(dhd_module_cleanup); -+ -+/* -+ * OS specific functions required to implement DHD driver in OS independent way -+ */ -+int -+dhd_os_proto_block(dhd_pub_t *pub) -+{ -+ dhd_info_t * dhd = (dhd_info_t *)(pub->info); -+ -+ if (dhd) { -+ down(&dhd->proto_sem); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+int -+dhd_os_proto_unblock(dhd_pub_t *pub) -+{ -+ dhd_info_t * dhd = (dhd_info_t *)(pub->info); -+ -+ if (dhd) { -+ up(&dhd->proto_sem); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+unsigned int -+dhd_os_get_ioctl_resp_timeout(void) -+{ -+ return ((unsigned int)dhd_ioctl_timeout_msec); -+} -+ -+void -+dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec) -+{ -+ dhd_ioctl_timeout_msec = (int)timeout_msec; -+} -+ -+int -+dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) -+{ -+ dhd_info_t * dhd = (dhd_info_t *)(pub->info); -+ int timeout; -+ -+ /* Convert timeout in millsecond to jiffies */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ timeout = msecs_to_jiffies(dhd_ioctl_timeout_msec); -+#else -+ timeout = dhd_ioctl_timeout_msec * HZ / 1000; -+#endif -+ -+ timeout = wait_event_timeout(dhd->ioctl_resp_wait, (*condition), timeout); -+ return timeout; -+} -+ -+int -+dhd_os_ioctl_resp_wake(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ -+ if (waitqueue_active(&dhd->ioctl_resp_wait)) { -+ wake_up(&dhd->ioctl_resp_wait); -+ } -+ -+ return 0; -+} -+ -+void -+dhd_os_wd_timer(void *bus, uint wdtick) -+{ -+ dhd_pub_t *pub = bus; -+ dhd_info_t *dhd = (dhd_info_t *)pub->info; -+ unsigned long flags; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (!dhd) -+ return; -+ if (wdtick) -+ DHD_OS_WD_WAKE_LOCK(pub); -+ -+ flags = dhd_os_spin_lock(pub); -+ -+ /* don't start the wd until fw is loaded */ -+ if (pub->busstate == DHD_BUS_DOWN) { -+ dhd_os_spin_unlock(pub, flags); -+ DHD_OS_WD_WAKE_UNLOCK(pub); -+ return; -+ } -+ -+ /* totally stop the timer */ -+ if (!wdtick && dhd->wd_timer_valid == TRUE) { -+ dhd->wd_timer_valid = FALSE; -+ dhd_os_spin_unlock(pub, flags); -+#ifdef DHDTHREAD -+ del_timer_sync(&dhd->timer); -+#else -+ del_timer(&dhd->timer); -+#endif /* DHDTHREAD */ -+ /* Unlock when timer deleted */ -+ DHD_OS_WD_WAKE_UNLOCK(pub); -+ return; -+ } -+ -+ if (wdtick) { -+ dhd_watchdog_ms = (uint)wdtick; -+ /* Re arm the timer, at last watchdog period */ -+ mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms)); -+ dhd->wd_timer_valid = TRUE; -+ } -+ dhd_os_spin_unlock(pub, flags); -+} -+ -+void * -+dhd_os_open_image(char *filename) -+{ -+ struct file *fp; -+ -+ fp = filp_open(filename, O_RDONLY, 0); -+ /* -+ * 2.6.11 (FC4) supports filp_open() but later revs don't? -+ * Alternative: -+ * fp = open_namei(AT_FDCWD, filename, O_RD, 0); -+ * ??? -+ */ -+ if (IS_ERR(fp)) -+ fp = NULL; -+ -+ return fp; -+} -+ -+int -+dhd_os_get_image_block(char *buf, int len, void *image) -+{ -+ struct file *fp = (struct file *)image; -+ int rdlen; -+ -+ if (!image) -+ return 0; -+ -+ rdlen = kernel_read(fp, fp->f_pos, buf, len); -+ if (rdlen > 0) -+ fp->f_pos += rdlen; -+ -+ return rdlen; -+} -+ -+void -+dhd_os_close_image(void *image) -+{ -+ if (image) -+ filp_close((struct file *)image, NULL); -+} -+ -+ -+void -+dhd_os_sdlock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd; -+ -+ dhd = (dhd_info_t *)(pub->info); -+ -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ down(&dhd->sdsem); -+ else -+#endif /* DHDTHREAD */ -+ spin_lock_bh(&dhd->sdlock); -+} -+ -+void -+dhd_os_sdunlock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd; -+ -+ dhd = (dhd_info_t *)(pub->info); -+ -+#ifdef DHDTHREAD -+ if (dhd->threads_only) -+ up(&dhd->sdsem); -+ else -+#endif /* DHDTHREAD */ -+ spin_unlock_bh(&dhd->sdlock); -+} -+ -+void -+dhd_os_sdlock_txq(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd; -+ -+ dhd = (dhd_info_t *)(pub->info); -+ spin_lock_bh(&dhd->txqlock); -+} -+ -+void -+dhd_os_sdunlock_txq(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd; -+ -+ dhd = (dhd_info_t *)(pub->info); -+ spin_unlock_bh(&dhd->txqlock); -+} -+ -+void -+dhd_os_sdlock_rxq(dhd_pub_t *pub) -+{ -+} -+ -+void -+dhd_os_sdunlock_rxq(dhd_pub_t *pub) -+{ -+} -+ -+void -+dhd_os_sdtxlock(dhd_pub_t *pub) -+{ -+ dhd_os_sdlock(pub); -+} -+ -+void -+dhd_os_sdtxunlock(dhd_pub_t *pub) -+{ -+ dhd_os_sdunlock(pub); -+} -+ -+#if defined(CONFIG_DHD_USE_STATIC_BUF) -+uint8* dhd_os_prealloc(void *osh, int section, uint size) -+{ -+ return (uint8*)wl_android_prealloc(section, size); -+} -+ -+void dhd_os_prefree(void *osh, void *addr, uint size) -+{ -+} -+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -+ -+#if defined(CONFIG_WIRELESS_EXT) -+struct iw_statistics * -+dhd_get_wireless_stats(struct net_device *dev) -+{ -+ int res = 0; -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ if (!dhd->pub.up) { -+ return NULL; -+ } -+ -+ res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats); -+ -+ if (res == 0) -+ return &dhd->iw.wstats; -+ else -+ return NULL; -+} -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+static int -+dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, -+ wl_event_msg_t *event, void **data) -+{ -+ int bcmerror = 0; -+ ASSERT(dhd != NULL); -+ -+ bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data); -+ if (bcmerror != BCME_OK) -+ return (bcmerror); -+ -+#if defined(CONFIG_WIRELESS_EXT) -+ if (event->bsscfgidx == 0) { -+ /* -+ * Wireless ext is on primary interface only -+ */ -+ -+ ASSERT(dhd->iflist[*ifidx] != NULL); -+ ASSERT(dhd->iflist[*ifidx]->net != NULL); -+ -+ if (dhd->iflist[*ifidx]->net) { -+ wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); -+ } -+ } -+#endif /* defined(CONFIG_WIRELESS_EXT) */ -+ -+#ifdef WL_CFG80211 -+ if ((ntoh32(event->event_type) == WLC_E_IF) && -+ (((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD)) -+ /* If ADD_IF has been called directly by wl utility then we -+ * should not report this. In case if ADD_IF was called from -+ * CFG stack, then too this event need not be reported back -+ */ -+ return (BCME_OK); -+ if ((wl_cfg80211_is_progress_ifchange() || -+ wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) { -+ /* -+ * If IF_ADD/CHANGE operation is going on, -+ * discard any event received on the virtual I/F -+ */ -+ return (BCME_OK); -+ } -+ -+ ASSERT(dhd->iflist[*ifidx] != NULL); -+ ASSERT(dhd->iflist[*ifidx]->net != NULL); -+ if (dhd->iflist[*ifidx]->event2cfg80211 && dhd->iflist[*ifidx]->net) { -+ wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data); -+ } -+#endif /* defined(WL_CFG80211) */ -+ -+ return (bcmerror); -+} -+ -+/* send up locally generated event */ -+void -+dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) -+{ -+ switch (ntoh32(event->event_type)) { -+#ifdef WLBTAMP -+ /* Send up locally generated AMP HCI Events */ -+ case WLC_E_BTA_HCI_EVENT: { -+ struct sk_buff *p, *skb; -+ bcm_event_t *msg; -+ wl_event_msg_t *p_bcm_event; -+ char *ptr; -+ uint32 len; -+ uint32 pktlen; -+ dhd_if_t *ifp; -+ dhd_info_t *dhd; -+ uchar *eth; -+ int ifidx; -+ -+ len = ntoh32(event->datalen); -+ pktlen = sizeof(bcm_event_t) + len + 2; -+ dhd = dhdp->info; -+ ifidx = dhd_ifname2idx(dhd, event->ifname); -+ -+ if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) { -+ ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32))); -+ -+ msg = (bcm_event_t *) PKTDATA(dhdp->osh, p); -+ -+ bcopy(&dhdp->mac, &msg->eth.ether_dhost, ETHER_ADDR_LEN); -+ bcopy(&dhdp->mac, &msg->eth.ether_shost, ETHER_ADDR_LEN); -+ ETHER_TOGGLE_LOCALADDR(&msg->eth.ether_shost); -+ -+ msg->eth.ether_type = hton16(ETHER_TYPE_BRCM); -+ -+ /* BCM Vendor specific header... */ -+ msg->bcm_hdr.subtype = hton16(BCMILCP_SUBTYPE_VENDOR_LONG); -+ msg->bcm_hdr.version = BCMILCP_BCM_SUBTYPEHDR_VERSION; -+ bcopy(BRCM_OUI, &msg->bcm_hdr.oui[0], DOT11_OUI_LEN); -+ -+ /* vendor spec header length + pvt data length (private indication -+ * hdr + actual message itself) -+ */ -+ msg->bcm_hdr.length = hton16(BCMILCP_BCM_SUBTYPEHDR_MINLENGTH + -+ BCM_MSG_LEN + sizeof(wl_event_msg_t) + (uint16)len); -+ msg->bcm_hdr.usr_subtype = hton16(BCMILCP_BCM_SUBTYPE_EVENT); -+ -+ PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); -+ -+ /* copy wl_event_msg_t into sk_buf */ -+ -+ /* pointer to wl_event_msg_t in sk_buf */ -+ p_bcm_event = &msg->event; -+ bcopy(event, p_bcm_event, sizeof(wl_event_msg_t)); -+ -+ /* copy hci event into sk_buf */ -+ bcopy(data, (p_bcm_event + 1), len); -+ -+ msg->bcm_hdr.length = hton16(sizeof(wl_event_msg_t) + -+ ntoh16(msg->bcm_hdr.length)); -+ PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); -+ -+ ptr = (char *)(msg + 1); -+ /* Last 2 bytes of the message are 0x00 0x00 to signal that there -+ * are no ethertypes which are following this -+ */ -+ ptr[len+0] = 0x00; -+ ptr[len+1] = 0x00; -+ -+ skb = PKTTONATIVE(dhdp->osh, p); -+ eth = skb->data; -+ len = skb->len; -+ -+ ifp = dhd->iflist[ifidx]; -+ if (ifp == NULL) -+ ifp = dhd->iflist[0]; -+ -+ ASSERT(ifp); -+ skb->dev = ifp->net; -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ -+ skb->data = eth; -+ skb->len = len; -+ -+ /* Strip header, count, deliver upward */ -+ skb_pull(skb, ETH_HLEN); -+ -+ /* Send the packet */ -+ if (in_interrupt()) { -+ netif_rx(skb); -+ } else { -+ netif_rx_ni(skb); -+ } -+ } -+ else { -+ /* Could not allocate a sk_buf */ -+ AP6210_ERR("%s: unable to alloc sk_buf", __FUNCTION__); -+ } -+ break; -+ } /* case WLC_E_BTA_HCI_EVENT */ -+#endif /* WLBTAMP */ -+ -+ default: -+ break; -+ } -+} -+ -+void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) -+{ -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+ struct dhd_info *dhdinfo = dhd->info; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ int timeout = msecs_to_jiffies(IOCTL_RESP_TIMEOUT); -+#else -+ int timeout = (IOCTL_RESP_TIMEOUT / 1000) * HZ; -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+ dhd_os_sdunlock(dhd); -+ wait_event_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), timeout); -+ dhd_os_sdlock(dhd); -+#endif -+ return; -+} -+ -+void dhd_wait_event_wakeup(dhd_pub_t *dhd) -+{ -+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+ struct dhd_info *dhdinfo = dhd->info; -+ if (waitqueue_active(&dhdinfo->ctrl_wait)) -+ wake_up(&dhdinfo->ctrl_wait); -+#endif -+ return; -+} -+ -+int -+dhd_dev_reset(struct net_device *dev, uint8 flag) -+{ -+ int ret; -+ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ if (flag == TRUE) { -+ /* Issue wl down command before resetting the chip */ -+ if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) { -+ AP6210_DEBUG("%s: wl down failed\n", __FUNCTION__); -+ } -+ } -+ -+ ret = dhd_bus_devreset(&dhd->pub, flag); -+ if (ret) { -+ AP6210_ERR("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+int net_os_set_suspend_disable(struct net_device *dev, int val) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) { -+ ret = dhd->pub.suspend_disable_flag; -+ dhd->pub.suspend_disable_flag = val; -+ } -+ return ret; -+} -+ -+int net_os_set_suspend(struct net_device *dev, int val, int force) -+{ -+ int ret = 0; -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ if (dhd) { -+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) -+ ret = dhd_set_suspend(val, &dhd->pub); -+#else -+ ret = dhd_suspend_resume_helper(dhd, val, force); -+#endif -+#ifdef WL_CFG80211 -+ wl_cfg80211_update_power_mode(dev); -+#endif -+ } -+ return ret; -+} -+ -+int net_os_set_suspend_bcn_li_dtim(struct net_device *dev, int val) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ if (dhd) -+ dhd->pub.suspend_bcn_li_dtim = val; -+ -+ return 0; -+} -+ -+#ifdef PKT_FILTER_SUPPORT -+int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) -+{ -+#ifndef GAN_LITE_NAT_KEEPALIVE_FILTER -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ char *filterp = NULL; -+ int ret = 0; -+ -+ if (!dhd || (num == DHD_UNICAST_FILTER_NUM) || -+ (num == DHD_MDNS_FILTER_NUM)) -+ return ret; -+ if (num >= dhd->pub.pktfilter_count) -+ return -EINVAL; -+ if (add_remove) { -+ switch (num) { -+ case DHD_BROADCAST_FILTER_NUM: -+ filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; -+ break; -+ case DHD_MULTICAST4_FILTER_NUM: -+ filterp = "102 0 0 0 0xFFFFFF 0x01005E"; -+ break; -+ case DHD_MULTICAST6_FILTER_NUM: -+ filterp = "103 0 0 0 0xFFFF 0x3333"; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ dhd->pub.pktfilter[num] = filterp; -+ dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]); -+ return ret; -+#else -+ return 0; -+#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */ -+} -+ -+int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val) -+{ -+ int ret = 0; -+ -+ /* Packet filtering is set only if we still in early-suspend and -+ * we need either to turn it ON or turn it OFF -+ * We can always turn it OFF in case of early-suspend, but we turn it -+ * back ON only if suspend_disable_flag was not set -+ */ -+ if (dhdp && dhdp->up) { -+ if (dhdp->in_suspend) { -+ if (!val || (val && !dhdp->suspend_disable_flag)) -+ dhd_enable_packet_filter(val, dhdp); -+ } -+ } -+ return ret; -+} -+ -+/* function to enable/disable packet for Network device */ -+int net_os_enable_packet_filter(struct net_device *dev, int val) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ return dhd_os_enable_packet_filter(&dhd->pub, val); -+} -+#endif /* PKT_FILTER_SUPPORT */ -+ -+int -+dhd_dev_init_ioctl(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ return dhd_preinit_ioctls(&dhd->pub); -+} -+ -+#ifdef PNO_SUPPORT -+/* Linux wrapper to call common dhd_pno_clean */ -+int -+dhd_dev_pno_reset(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ return (dhd_pno_clean(&dhd->pub)); -+} -+ -+ -+/* Linux wrapper to call common dhd_pno_enable */ -+int -+dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ return (dhd_pno_enable(&dhd->pub, pfn_enabled)); -+} -+ -+ -+/* Linux wrapper to call common dhd_pno_set */ -+int -+dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, -+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); -+} -+ -+/* Linux wrapper to get pno status */ -+int -+dhd_dev_get_pno_status(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ return (dhd_pno_get_status(&dhd->pub)); -+} -+ -+#endif /* PNO_SUPPORT */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) -+static void dhd_hang_process(struct work_struct *work) -+{ -+ dhd_info_t *dhd; -+ struct net_device *dev; -+ -+ dhd = (dhd_info_t *)container_of(work, dhd_info_t, work_hang); -+ dev = dhd->iflist[0]->net; -+ -+ if (dev) { -+ rtnl_lock(); -+ dev_close(dev); -+ rtnl_unlock(); -+#if defined(WL_WIRELESS_EXT) -+ wl_iw_send_priv_event(dev, "HANG"); -+#endif -+#if defined(WL_CFG80211) -+ wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); -+#endif -+ } -+} -+ -+int dhd_os_send_hang_message(dhd_pub_t *dhdp) -+{ -+ int ret = 0; -+ if (dhdp) { -+ if (!dhdp->hang_was_sent) { -+ dhdp->hang_was_sent = 1; -+ schedule_work(&dhdp->info->work_hang); -+ } -+ } -+ return ret; -+} -+ -+int net_os_send_hang_message(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ ret = dhd_os_send_hang_message(&dhd->pub); -+#else -+ ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); -+#endif -+ return ret; -+} -+#endif /* (OEM_ANDROID) */ -+ -+void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ -+ if (dhd && dhd->pub.up) { -+ memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); -+#ifdef WL_CFG80211 -+ wl_update_wiphybands(NULL, true); -+#endif -+ } -+} -+ -+void dhd_bus_band_set(struct net_device *dev, uint band) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ if (dhd && dhd->pub.up) { -+#ifdef WL_CFG80211 -+ wl_update_wiphybands(NULL, true); -+#endif -+ } -+} -+ -+void dhd_net_if_lock(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ dhd_net_if_lock_local(dhd); -+} -+ -+void dhd_net_if_unlock(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ dhd_net_if_unlock_local(dhd); -+} -+ -+static void dhd_net_if_lock_local(dhd_info_t *dhd) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ if (dhd) -+ mutex_lock(&dhd->dhd_net_if_mutex); -+#endif -+} -+ -+static void dhd_net_if_unlock_local(dhd_info_t *dhd) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ if (dhd) -+ mutex_unlock(&dhd->dhd_net_if_mutex); -+#endif -+} -+ -+static void dhd_suspend_lock(dhd_pub_t *pub) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ if (dhd) -+ mutex_lock(&dhd->dhd_suspend_mutex); -+#endif -+} -+ -+static void dhd_suspend_unlock(dhd_pub_t *pub) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ if (dhd) -+ mutex_unlock(&dhd->dhd_suspend_mutex); -+#endif -+} -+ -+unsigned long dhd_os_spin_lock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags = 0; -+ -+ if (dhd) -+ spin_lock_irqsave(&dhd->dhd_lock, flags); -+ -+ return flags; -+} -+ -+void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ -+ if (dhd) -+ spin_unlock_irqrestore(&dhd->dhd_lock, flags); -+} -+ -+static int -+dhd_get_pend_8021x_cnt(dhd_info_t *dhd) -+{ -+ return (atomic_read(&dhd->pend_8021x_cnt)); -+} -+ -+#define MAX_WAIT_FOR_8021X_TX 25 -+ -+int -+dhd_wait_pend8021x(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int timeout = msecs_to_jiffies(10); -+ int ntimes = MAX_WAIT_FOR_8021X_TX; -+ int pend = dhd_get_pend_8021x_cnt(dhd); -+ -+ while (ntimes && pend) { -+ if (pend) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(timeout); -+ set_current_state(TASK_RUNNING); -+ ntimes--; -+ } -+ pend = dhd_get_pend_8021x_cnt(dhd); -+ } -+ if (ntimes == 0) -+ AP6210_ERR("%s: TIMEOUT\n", __FUNCTION__); -+ return pend; -+} -+ -+#ifdef DHD_DEBUG -+int -+write_to_file(dhd_pub_t *dhd, uint8 *buf, int size) -+{ -+ int ret = 0; -+ struct file *fp; -+ mm_segment_t old_fs; -+ loff_t pos = 0; -+ -+ /* change to KERNEL_DS address limit */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* open file to write */ -+ fp = filp_open("/tmp/mem_dump", O_WRONLY|O_CREAT, 0640); -+ if (!fp) { -+ AP6210_ERR("%s: open file error\n", __FUNCTION__); -+ ret = -1; -+ goto exit; -+ } -+ -+ /* Write buf to file */ -+ fp->f_op->write(fp, buf, size, &pos); -+ -+exit: -+ /* free buf before return */ -+ MFREE(dhd->osh, buf, size); -+ /* close file before return */ -+ if (fp) -+ filp_close(fp, current->files); -+ /* restore previous address limit */ -+ set_fs(old_fs); -+ -+ return ret; -+} -+#endif /* DHD_DEBUG */ -+ -+int dhd_os_wake_lock_timeout(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ int ret = 0; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+ ret = dhd->wakelock_rx_timeout_enable > dhd->wakelock_ctrl_timeout_enable ? -+ dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable; -+#ifdef CONFIG_HAS_WAKELOCK -+ if (dhd->wakelock_rx_timeout_enable) -+ wake_lock_timeout(dhd->wl_rxwake, -+ msecs_to_jiffies(dhd->wakelock_rx_timeout_enable)); -+ if (dhd->wakelock_ctrl_timeout_enable) -+ wake_lock_timeout(dhd->wl_ctrlwake, -+ msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable)); -+#endif -+ dhd->wakelock_rx_timeout_enable = 0; -+ dhd->wakelock_ctrl_timeout_enable = 0; -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return ret; -+} -+ -+int net_os_wake_lock_timeout(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+ ret = dhd_os_wake_lock_timeout(&dhd->pub); -+ return ret; -+} -+ -+int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+ if (val > dhd->wakelock_rx_timeout_enable) -+ dhd->wakelock_rx_timeout_enable = val; -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return 0; -+} -+ -+int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+ if (val > dhd->wakelock_ctrl_timeout_enable) -+ dhd->wakelock_ctrl_timeout_enable = val; -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return 0; -+} -+ -+int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+ ret = dhd_os_wake_lock_rx_timeout_enable(&dhd->pub, val); -+ return ret; -+} -+ -+int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+ ret = dhd_os_wake_lock_ctrl_timeout_enable(&dhd->pub, val); -+ return ret; -+} -+ -+int dhd_os_wake_lock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ int ret = 0; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+#ifdef CONFIG_HAS_WAKELOCK -+ if (!dhd->wakelock_counter) -+ wake_lock(dhd->wl_wifi); -+#endif -+ dhd->wakelock_counter++; -+ ret = dhd->wakelock_counter; -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return ret; -+} -+ -+int net_os_wake_lock(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+ ret = dhd_os_wake_lock(&dhd->pub); -+ return ret; -+} -+ -+int dhd_os_wake_unlock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ int ret = 0; -+ -+ dhd_os_wake_lock_timeout(pub); -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+ if (dhd->wakelock_counter) { -+ dhd->wakelock_counter--; -+#ifdef CONFIG_HAS_WAKELOCK -+ if (!dhd->wakelock_counter) -+ wake_unlock(dhd->wl_wifi); -+#endif -+ ret = dhd->wakelock_counter; -+ } -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return ret; -+} -+ -+int dhd_os_check_wakelock(void *dhdp) -+{ -+#ifdef CONFIG_HAS_WAKELOCK -+ dhd_pub_t *pub = (dhd_pub_t *)dhdp; -+ dhd_info_t *dhd; -+ -+ if (!pub) -+ return 0; -+ dhd = (dhd_info_t *)(pub->info); -+ -+ /* Indicate to the SD Host to avoid going to suspend if internal locks are up */ -+ if (dhd && (wake_lock_active(dhd->wl_wifi) || -+ (wake_lock_active(dhd->wl_wdwake)))) -+ return 1; -+#endif -+ return 0; -+} -+ -+int net_os_wake_unlock(struct net_device *dev) -+{ -+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); -+ int ret = 0; -+ -+ if (dhd) -+ ret = dhd_os_wake_unlock(&dhd->pub); -+ return ret; -+} -+ -+int dhd_os_wd_wake_lock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ int ret = 0; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+#ifdef CONFIG_HAS_WAKELOCK -+ /* if wakelock_wd_counter was never used : lock it at once */ -+ if (!dhd->wakelock_wd_counter) { -+ if (dhd->wl_wdwake) -+ wake_lock(dhd->wl_wdwake); -+ else { -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ return 0; -+ } -+ } -+#endif -+ dhd->wakelock_wd_counter++; -+ ret = dhd->wakelock_wd_counter; -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return ret; -+} -+ -+int dhd_os_wd_wake_unlock(dhd_pub_t *pub) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(pub->info); -+ unsigned long flags; -+ int ret = 0; -+ -+ if (dhd) { -+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags); -+ if (dhd->wakelock_wd_counter) { -+ dhd->wakelock_wd_counter = 0; -+#ifdef CONFIG_HAS_WAKELOCK -+ wake_unlock(dhd->wl_wdwake); -+#endif -+ } -+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); -+ } -+ return ret; -+} -+ -+int dhd_os_check_if_up(void *dhdp) -+{ -+ dhd_pub_t *pub = (dhd_pub_t *)dhdp; -+ -+ if (!pub) -+ return 0; -+ return pub->up; -+} -+ -+/* function to collect firmware, chip id and chip version info */ -+void dhd_set_version_info(dhd_pub_t *dhdp, char *fw) -+{ -+ int i; -+ -+ i = snprintf(info_string, sizeof(info_string), "Driver: %s\n Firmware: %s ", EPI_VERSION_STR, fw); -+ -+ if (!dhdp) -+ return; -+ -+ i = snprintf(&info_string[i], sizeof(info_string) - i, -+ "\n Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp), -+ dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp)); -+ AP6210_ERR("Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp), dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp)); -+} -+ -+int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd) -+{ -+ int ifidx; -+ int ret = 0; -+ dhd_info_t *dhd = NULL; -+ -+ if (!net || !netdev_priv(net)) { -+ AP6210_ERR("%s invalid parameter\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dhd = *(dhd_info_t **)netdev_priv(net); -+ ifidx = dhd_net2idx(dhd, net); -+ if (ifidx == DHD_BAD_IF) { -+ AP6210_ERR("%s bad ifidx\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ DHD_OS_WAKE_LOCK(&dhd->pub); -+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, ioc, ioc->buf, ioc->len); -+ dhd_check_hang(net, &dhd->pub, ret); -+ DHD_OS_WAKE_UNLOCK(&dhd->pub); -+ -+ return ret; -+} -+ -+bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret) -+{ -+ struct net_device *net; -+ -+ net = dhd_idx2net(dhdp, ifidx); -+ return dhd_check_hang(net, dhdp, ret); -+} -+ -+ -+#ifdef PROP_TXSTATUS -+extern int dhd_wlfc_interface_entry_update(void* state, ewlfc_mac_entry_action_t action, uint8 ifid, -+ uint8 iftype, uint8* ea); -+extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits); -+ -+int dhd_wlfc_interface_event(struct dhd_info *dhd, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -+{ -+ int status; -+ -+ dhd_os_wlfc_block(&dhd->pub); -+ if (dhd->pub.wlfc_state == NULL) { -+ dhd_os_wlfc_unblock(&dhd->pub); -+ return BCME_OK; -+ } -+ -+ status = dhd_wlfc_interface_entry_update(dhd->pub.wlfc_state, action, ifid, iftype, ea); -+ dhd_os_wlfc_unblock(&dhd->pub); -+ return status; -+} -+ -+int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data) -+{ -+ int status; -+ -+ dhd_os_wlfc_block(&dhd->pub); -+ if (dhd->pub.wlfc_state == NULL) { -+ dhd_os_wlfc_unblock(&dhd->pub); -+ return BCME_OK; -+ } -+ -+ status = dhd_wlfc_FIFOcreditmap_update(dhd->pub.wlfc_state, event_data); -+ dhd_os_wlfc_unblock(&dhd->pub); -+ return status; -+} -+ -+int dhd_wlfc_event(struct dhd_info *dhd) -+{ -+ int status; -+ -+ dhd_os_wlfc_block(&dhd->pub); -+ status = dhd_wlfc_enable(&dhd->pub); -+ dhd_os_wlfc_unblock(&dhd->pub); -+ return status; -+} -+#endif /* PROP_TXSTATUS */ -+ -+#ifdef BCMDBGFS -+ -+#include -+ -+extern uint32 dhd_readregl(void *bp, uint32 addr); -+extern uint32 dhd_writeregl(void *bp, uint32 addr, uint32 data); -+ -+typedef struct dhd_dbgfs { -+ struct dentry *debugfs_dir; -+ struct dentry *debugfs_mem; -+ dhd_pub_t *dhdp; -+ uint32 size; -+} dhd_dbgfs_t; -+ -+dhd_dbgfs_t g_dbgfs; -+ -+static int -+dhd_dbg_state_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+ -+static ssize_t -+dhd_dbg_state_read(struct file *file, char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t rval; -+ uint32 tmp; -+ loff_t pos = *ppos; -+ size_t ret; -+ -+ if (pos < 0) -+ return -EINVAL; -+ if (pos >= g_dbgfs.size || !count) -+ return 0; -+ if (count > g_dbgfs.size - pos) -+ count = g_dbgfs.size - pos; -+ -+ /* Basically enforce aligned 4 byte reads. It's up to the user to work out the details */ -+ tmp = dhd_readregl(g_dbgfs.dhdp->bus, file->f_pos & (~3)); -+ -+ ret = copy_to_user(ubuf, &tmp, 4); -+ if (ret == count) -+ return -EFAULT; -+ -+ count -= ret; -+ *ppos = pos + count; -+ rval = count; -+ -+ return rval; -+} -+ -+ -+static ssize_t -+dhd_debugfs_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) -+{ -+ loff_t pos = *ppos; -+ size_t ret; -+ uint32 buf; -+ -+ if (pos < 0) -+ return -EINVAL; -+ if (pos >= g_dbgfs.size || !count) -+ return 0; -+ if (count > g_dbgfs.size - pos) -+ count = g_dbgfs.size - pos; -+ -+ ret = copy_from_user(&buf, ubuf, sizeof(uint32)); -+ if (ret == count) -+ return -EFAULT; -+ -+ /* Basically enforce aligned 4 byte writes. It's up to the user to work out the details */ -+ dhd_writeregl(g_dbgfs.dhdp->bus, file->f_pos & (~3), buf); -+ -+ return count; -+} -+ -+ -+loff_t -+dhd_debugfs_lseek(struct file *file, loff_t off, int whence) -+{ -+ loff_t pos = -1; -+ -+ switch (whence) { -+ case 0: -+ pos = off; -+ break; -+ case 1: -+ pos = file->f_pos + off; -+ break; -+ case 2: -+ pos = g_dbgfs.size - off; -+ } -+ return (pos < 0 || pos > g_dbgfs.size) ? -EINVAL : (file->f_pos = pos); -+} -+ -+static const struct file_operations dhd_dbg_state_ops = { -+ .read = dhd_dbg_state_read, -+ .write = dhd_debugfs_write, -+ .open = dhd_dbg_state_open, -+ .llseek = dhd_debugfs_lseek -+}; -+ -+static void dhd_dbg_create(void) -+{ -+ if (g_dbgfs.debugfs_dir) { -+ g_dbgfs.debugfs_mem = debugfs_create_file("mem", 0644, g_dbgfs.debugfs_dir, -+ NULL, &dhd_dbg_state_ops); -+ } -+} -+ -+void dhd_dbg_init(dhd_pub_t *dhdp) -+{ -+ int err; -+ -+ g_dbgfs.dhdp = dhdp; -+ g_dbgfs.size = 0x20000000; /* Allow access to various cores regs */ -+ -+ g_dbgfs.debugfs_dir = debugfs_create_dir("dhd", 0); -+ if (IS_ERR(g_dbgfs.debugfs_dir)) { -+ err = PTR_ERR(g_dbgfs.debugfs_dir); -+ g_dbgfs.debugfs_dir = NULL; -+ return; -+ } -+ -+ dhd_dbg_create(); -+ -+ return; -+} -+ -+void dhd_dbg_remove(void) -+{ -+ debugfs_remove(g_dbgfs.debugfs_mem); -+ debugfs_remove(g_dbgfs.debugfs_dir); -+ -+ bzero((unsigned char *) &g_dbgfs, sizeof(g_dbgfs)); -+ -+} -+#endif /* ifdef BCMDBGFS */ -+ -+#ifdef WLMEDIA_HTSF -+ -+static -+void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); -+ struct sk_buff *skb; -+ uint32 htsf = 0; -+ uint16 dport = 0, oldmagic = 0xACAC; -+ char *p1; -+ htsfts_t ts; -+ -+ /* timestamp packet */ -+ -+ p1 = (char*) PKTDATA(dhdp->osh, pktbuf); -+ -+ if (PKTLEN(dhdp->osh, pktbuf) > HTSF_MINLEN) { -+/* memcpy(&proto, p1+26, 4); */ -+ memcpy(&dport, p1+40, 2); -+/* proto = ((ntoh32(proto))>> 16) & 0xFF; */ -+ dport = ntoh16(dport); -+ } -+ -+ /* timestamp only if icmp or udb iperf with port 5555 */ -+/* if (proto == 17 && dport == tsport) { */ -+ if (dport >= tsport && dport <= tsport + 20) { -+ -+ skb = (struct sk_buff *) pktbuf; -+ -+ htsf = dhd_get_htsf(dhd, 0); -+ memset(skb->data + 44, 0, 2); /* clear checksum */ -+ memcpy(skb->data+82, &oldmagic, 2); -+ memcpy(skb->data+84, &htsf, 4); -+ -+ memset(&ts, 0, sizeof(htsfts_t)); -+ ts.magic = HTSFMAGIC; -+ ts.prio = PKTPRIO(pktbuf); -+ ts.seqnum = htsf_seqnum++; -+ ts.c10 = get_cycles(); -+ ts.t10 = htsf; -+ ts.endmagic = HTSFENDMAGIC; -+ -+ memcpy(skb->data + HTSF_HOSTOFFSET, &ts, sizeof(ts)); -+ } -+} -+ -+static void dhd_dump_htsfhisto(histo_t *his, char *s) -+{ -+ int pktcnt = 0, curval = 0, i; -+ for (i = 0; i < (NUMBIN-2); i++) { -+ curval += 500; -+ AP6210_DUMP("%d ", his->bin[i]); -+ pktcnt += his->bin[i]; -+ } -+ AP6210_DUMP(" max: %d TotPkt: %d neg: %d [%s]\n", his->bin[NUMBIN-2], pktcnt, -+ his->bin[NUMBIN-1], s); -+} -+ -+static -+void sorttobin(int value, histo_t *histo) -+{ -+ int i, binval = 0; -+ -+ if (value < 0) { -+ histo->bin[NUMBIN-1]++; -+ return; -+ } -+ if (value > histo->bin[NUMBIN-2]) /* store the max value */ -+ histo->bin[NUMBIN-2] = value; -+ -+ for (i = 0; i < (NUMBIN-2); i++) { -+ binval += 500; /* 500m s bins */ -+ if (value <= binval) { -+ histo->bin[i]++; -+ return; -+ } -+ } -+ histo->bin[NUMBIN-3]++; -+} -+ -+static -+void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf) -+{ -+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info; -+ struct sk_buff *skb; -+ char *p1; -+ uint16 old_magic; -+ int d1, d2, d3, end2end; -+ htsfts_t *htsf_ts; -+ uint32 htsf; -+ -+ skb = PKTTONATIVE(dhdp->osh, pktbuf); -+ p1 = (char*)PKTDATA(dhdp->osh, pktbuf); -+ -+ if (PKTLEN(osh, pktbuf) > HTSF_MINLEN) { -+ memcpy(&old_magic, p1+78, 2); -+ htsf_ts = (htsfts_t*) (p1 + HTSF_HOSTOFFSET - 4); -+ } -+ else -+ return; -+ -+ if (htsf_ts->magic == HTSFMAGIC) { -+ htsf_ts->tE0 = dhd_get_htsf(dhd, 0); -+ htsf_ts->cE0 = get_cycles(); -+ } -+ -+ if (old_magic == 0xACAC) { -+ -+ tspktcnt++; -+ htsf = dhd_get_htsf(dhd, 0); -+ memcpy(skb->data+92, &htsf, sizeof(uint32)); -+ -+ memcpy(&ts[tsidx].t1, skb->data+80, 16); -+ -+ d1 = ts[tsidx].t2 - ts[tsidx].t1; -+ d2 = ts[tsidx].t3 - ts[tsidx].t2; -+ d3 = ts[tsidx].t4 - ts[tsidx].t3; -+ end2end = ts[tsidx].t4 - ts[tsidx].t1; -+ -+ sorttobin(d1, &vi_d1); -+ sorttobin(d2, &vi_d2); -+ sorttobin(d3, &vi_d3); -+ sorttobin(end2end, &vi_d4); -+ -+ if (end2end > 0 && end2end > maxdelay) { -+ maxdelay = end2end; -+ maxdelaypktno = tspktcnt; -+ memcpy(&maxdelayts, &ts[tsidx], 16); -+ } -+ if (++tsidx >= TSMAX) -+ tsidx = 0; -+ } -+} -+ -+uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx) -+{ -+ uint32 htsf = 0, cur_cycle, delta, delta_us; -+ uint32 factor, baseval, baseval2; -+ cycles_t t; -+ -+ t = get_cycles(); -+ cur_cycle = t; -+ -+ if (cur_cycle > dhd->htsf.last_cycle) -+ delta = cur_cycle - dhd->htsf.last_cycle; -+ else { -+ delta = cur_cycle + (0xFFFFFFFF - dhd->htsf.last_cycle); -+ } -+ -+ delta = delta >> 4; -+ -+ if (dhd->htsf.coef) { -+ /* times ten to get the first digit */ -+ factor = (dhd->htsf.coef*10 + dhd->htsf.coefdec1); -+ baseval = (delta*10)/factor; -+ baseval2 = (delta*10)/(factor+1); -+ delta_us = (baseval - (((baseval - baseval2) * dhd->htsf.coefdec2)) / 10); -+ htsf = (delta_us << 4) + dhd->htsf.last_tsf + HTSF_BUS_DELAY; -+ } -+ else { -+ AP6210_ERR("-------dhd->htsf.coef = 0 -------\n"); -+ } -+ -+ return htsf; -+} -+ -+static void dhd_dump_latency(void) -+{ -+ int i, max = 0; -+ int d1, d2, d3, d4, d5; -+ -+ AP6210_DEBUG("T1 T2 T3 T4 d1 d2 t4-t1 i \n"); -+ for (i = 0; i < TSMAX; i++) { -+ d1 = ts[i].t2 - ts[i].t1; -+ d2 = ts[i].t3 - ts[i].t2; -+ d3 = ts[i].t4 - ts[i].t3; -+ d4 = ts[i].t4 - ts[i].t1; -+ d5 = ts[max].t4-ts[max].t1; -+ if (d4 > d5 && d4 > 0) { -+ max = i; -+ } -+ AP6210_DUMP("%08X %08X %08X %08X \t%d %d %d %d i=%d\n", -+ ts[i].t1, ts[i].t2, ts[i].t3, ts[i].t4, -+ d1, d2, d3, d4, i); -+ } -+ -+ AP6210_DEBUG("current idx = %d \n", tsidx); -+ -+ AP6210_DEBUG("Highest latency %d pkt no.%d total=%d\n", maxdelay, maxdelaypktno, tspktcnt); -+ AP6210_DEBUG("%08X %08X %08X %08X \t%d %d %d %d\n", -+ maxdelayts.t1, maxdelayts.t2, maxdelayts.t3, maxdelayts.t4, -+ maxdelayts.t2 - maxdelayts.t1, -+ maxdelayts.t3 - maxdelayts.t2, -+ maxdelayts.t4 - maxdelayts.t3, -+ maxdelayts.t4 - maxdelayts.t1); -+} -+ -+ -+static int -+dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx) -+{ -+ wl_ioctl_t ioc; -+ char buf[32]; -+ int ret; -+ uint32 s1, s2; -+ -+ struct tsf { -+ uint32 low; -+ uint32 high; -+ } tsf_buf; -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ memset(&tsf_buf, 0, sizeof(tsf_buf)); -+ -+ ioc.cmd = WLC_GET_VAR; -+ ioc.buf = buf; -+ ioc.len = (uint)sizeof(buf); -+ ioc.set = FALSE; -+ -+ strncpy(buf, "tsf", sizeof(buf) - 1); -+ buf[sizeof(buf) - 1] = '\0'; -+ s1 = dhd_get_htsf(dhd, 0); -+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) { -+ if (ret == -EIO) { -+ AP6210_ERR("%s: tsf is not supported by device\n", -+ dhd_ifname(&dhd->pub, ifidx)); -+ return -EOPNOTSUPP; -+ } -+ return ret; -+ } -+ s2 = dhd_get_htsf(dhd, 0); -+ -+ memcpy(&tsf_buf, buf, sizeof(tsf_buf)); -+ AP6210_DEBUG("TSF_h=%04X lo=%08X Calc:htsf=%08X, coef=%d.%d%d delta=%d ", -+ tsf_buf.high, tsf_buf.low, s2, dhd->htsf.coef, dhd->htsf.coefdec1, -+ dhd->htsf.coefdec2, s2-tsf_buf.low); -+ AP6210_DEBUG("lasttsf=%08X lastcycle=%08X\n", dhd->htsf.last_tsf, dhd->htsf.last_cycle); -+ return 0; -+} -+ -+void htsf_update(dhd_info_t *dhd, void *data) -+{ -+ static ulong cur_cycle = 0, prev_cycle = 0; -+ uint32 htsf, tsf_delta = 0; -+ uint32 hfactor = 0, cyc_delta, dec1 = 0, dec2, dec3, tmp; -+ ulong b, a; -+ cycles_t t; -+ -+ /* cycles_t in inlcude/mips/timex.h */ -+ -+ t = get_cycles(); -+ -+ prev_cycle = cur_cycle; -+ cur_cycle = t; -+ -+ if (cur_cycle > prev_cycle) -+ cyc_delta = cur_cycle - prev_cycle; -+ else { -+ b = cur_cycle; -+ a = prev_cycle; -+ cyc_delta = cur_cycle + (0xFFFFFFFF - prev_cycle); -+ } -+ -+ if (data == NULL) -+ AP6210_DEBUG(" tsf update ata point er is null \n"); -+ -+ memcpy(&prev_tsf, &cur_tsf, sizeof(tsf_t)); -+ memcpy(&cur_tsf, data, sizeof(tsf_t)); -+ -+ if (cur_tsf.low == 0) { -+ AP6210_DEBUG(" ---- 0 TSF, do not update, return\n"); -+ return; -+ } -+ -+ if (cur_tsf.low > prev_tsf.low) -+ tsf_delta = (cur_tsf.low - prev_tsf.low); -+ else { -+ AP6210_DEBUG(" ---- tsf low is smaller cur_tsf= %08X, prev_tsf=%08X, \n", -+ cur_tsf.low, prev_tsf.low); -+ if (cur_tsf.high > prev_tsf.high) { -+ tsf_delta = cur_tsf.low + (0xFFFFFFFF - prev_tsf.low); -+ AP6210_DEBUG(" ---- Wrap around tsf coutner adjusted TSF=%08X\n", tsf_delta); -+ } -+ else -+ return; /* do not update */ -+ } -+ -+ if (tsf_delta) { -+ hfactor = cyc_delta / tsf_delta; -+ tmp = (cyc_delta - (hfactor * tsf_delta))*10; -+ dec1 = tmp/tsf_delta; -+ dec2 = ((tmp - dec1*tsf_delta)*10) / tsf_delta; -+ tmp = (tmp - (dec1*tsf_delta))*10; -+ dec3 = ((tmp - dec2*tsf_delta)*10) / tsf_delta; -+ -+ if (dec3 > 4) { -+ if (dec2 == 9) { -+ dec2 = 0; -+ if (dec1 == 9) { -+ dec1 = 0; -+ hfactor++; -+ } -+ else { -+ dec1++; -+ } -+ } -+ else -+ dec2++; -+ } -+ } -+ -+ if (hfactor) { -+ htsf = ((cyc_delta * 10) / (hfactor*10+dec1)) + prev_tsf.low; -+ dhd->htsf.coef = hfactor; -+ dhd->htsf.last_cycle = cur_cycle; -+ dhd->htsf.last_tsf = cur_tsf.low; -+ dhd->htsf.coefdec1 = dec1; -+ dhd->htsf.coefdec2 = dec2; -+ } -+ else { -+ htsf = prev_tsf.low; -+ } -+} -+ -+#endif /* WLMEDIA_HTSF */ -diff --git a/drivers/net/wireless/ap6210/dhd_linux_sched.c b/drivers/net/wireless/ap6210/dhd_linux_sched.c -new file mode 100644 -index 0000000..290caf7 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_linux_sched.c -@@ -0,0 +1,39 @@ -+/* -+ * Expose some of the kernel scheduler routines -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_linux_sched.c 291086 2011-10-21 01:17:24Z $ -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+int setScheduler(struct task_struct *p, int policy, struct sched_param *param) -+{ -+ int rc = 0; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+ rc = sched_setscheduler(p, policy, param); -+#endif /* LinuxVer */ -+ return rc; -+} -diff --git a/drivers/net/wireless/ap6210/dhd_pno.c b/drivers/net/wireless/ap6210/dhd_pno.c -new file mode 100644 -index 0000000..317a063 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_pno.c -@@ -0,0 +1,1838 @@ -+/* -+ * Broadcom Dongle Host Driver (DHD) -+ * Prefered Network Offload and Wi-Fi Location Service(WLS) code. -+ * -+ * Copyright (C) 1999-2013, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_pno.c 420056 2013-08-24 00:53:12Z $ -+ */ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#ifdef __BIG_ENDIAN -+#include -+#define htod32(i) (bcmswap32(i)) -+#define htod16(i) (bcmswap16(i)) -+#define dtoh32(i) (bcmswap32(i)) -+#define dtoh16(i) (bcmswap16(i)) -+#define htodchanspec(i) htod16(i) -+#define dtohchanspec(i) dtoh16(i) -+#else -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+#endif /* IL_BIGENDINA */ -+ -+#define NULL_CHECK(p, s, err) \ -+ do { \ -+ if (!(p)) { \ -+ printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \ -+ err = BCME_ERROR; \ -+ return err; \ -+ } \ -+ } while (0) -+#define PNO_GET_PNOSTATE(dhd) ((dhd_pno_status_info_t *)dhd->pno_state) -+#define PNO_BESTNET_LEN 1024 -+#define PNO_ON 1 -+#define PNO_OFF 0 -+#define CHANNEL_2G_MAX 14 -+#define MAX_NODE_CNT 5 -+#define WLS_SUPPORTED(pno_state) (pno_state->wls_supported == TRUE) -+#define TIME_DIFF(timestamp1, timestamp2) (abs((uint32)(timestamp1/1000) \ -+ - (uint32)(timestamp2/1000))) -+ -+#define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====") -+#define TIME_MIN_DIFF 5 -+static inline bool -+is_dfs(uint16 channel) -+{ -+ if (channel >= 52 && channel <= 64) /* class 2 */ -+ return TRUE; -+ else if (channel >= 100 && channel <= 140) /* class 4 */ -+ return TRUE; -+ else -+ return FALSE; -+} -+static int -+_dhd_pno_clean(dhd_pub_t *dhd) -+{ -+ int pfn = 0; -+ int err; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ /* Disable PNO */ -+ err = dhd_iovar(dhd, 0, "pfn", (char *)&pfn, sizeof(pfn), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn(error : %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ _pno_state->pno_status = DHD_PNO_DISABLED; -+ err = dhd_iovar(dhd, 0, "pfnclear", NULL, 0, 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfnclear(error : %d)\n", -+ __FUNCTION__, err); -+ } -+exit: -+ return err; -+} -+ -+static int -+_dhd_pno_suspend(dhd_pub_t *dhd) -+{ -+ int err; -+ int suspend = 1; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ err = dhd_iovar(dhd, 0, "pfn_suspend", (char *)&suspend, sizeof(suspend), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to suspend pfn(error :%d)\n", __FUNCTION__, err); -+ goto exit; -+ -+ } -+ _pno_state->pno_status = DHD_PNO_SUSPEND; -+exit: -+ return err; -+} -+static int -+_dhd_pno_enable(dhd_pub_t *dhd, int enable) -+{ -+ int err = BCME_OK; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ -+ if (enable & 0xfffe) { -+ AP6210_ERR("%s invalid value\n", __FUNCTION__); -+ err = BCME_BADARG; -+ goto exit; -+ } -+ if (!dhd_support_sta_mode(dhd)) { -+ AP6210_ERR("PNO is not allowed for non-STA mode"); -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ if (enable) { -+ if ((_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) && -+ dhd_is_associated(dhd, NULL, NULL)) { -+ AP6210_ERR("%s Legacy PNO mode cannot be enabled " -+ "in assoc mode , ignore it\n", __FUNCTION__); -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ } -+ /* Enable/Disable PNO */ -+ err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn_set\n", __FUNCTION__); -+ goto exit; -+ } -+ _pno_state->pno_status = (enable)? -+ DHD_PNO_ENABLED : DHD_PNO_DISABLED; -+ if (!enable) -+ _pno_state->pno_mode = DHD_PNO_NONE_MODE; -+ -+ AP6210_DEBUG("%s set pno as %s\n", -+ __FUNCTION__, enable ? "Enable" : "Disable"); -+exit: -+ return err; -+} -+ -+static int -+_dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t mode) -+{ -+ int err = BCME_OK; -+ wl_pfn_param_t pfn_param; -+ dhd_pno_params_t *_params; -+ dhd_pno_status_info_t *_pno_state; -+ bool combined_scan = FALSE; -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ -+ memset(&pfn_param, 0, sizeof(pfn_param)); -+ -+ /* set pfn parameters */ -+ pfn_param.version = htod32(PFN_VERSION); -+ pfn_param.flags = ((PFN_LIST_ORDER << SORT_CRITERIA_BIT) | -+ (ENABLE << IMMEDIATE_SCAN_BIT) | (ENABLE << REPORT_SEPERATELY_BIT)); -+ if (mode == DHD_PNO_LEGACY_MODE) { -+ /* check and set extra pno params */ -+ if ((pno_params->params_legacy.pno_repeat != 0) || -+ (pno_params->params_legacy.pno_freq_expo_max != 0)) { -+ pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); -+ pfn_param.repeat = (uchar) (pno_params->params_legacy.pno_repeat); -+ pfn_param.exp = (uchar) (pno_params->params_legacy.pno_freq_expo_max); -+ } -+ /* set up pno scan fr */ -+ if (pno_params->params_legacy.scan_fr != 0) -+ pfn_param.scan_freq = htod32(pno_params->params_legacy.scan_fr); -+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { -+ AP6210_DEBUG("will enable combined scan with BATCHIG SCAN MODE\n"); -+ mode |= DHD_PNO_BATCH_MODE; -+ combined_scan = TRUE; -+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { -+ AP6210_DEBUG("will enable combined scan with HOTLIST SCAN MODE\n"); -+ mode |= DHD_PNO_HOTLIST_MODE; -+ combined_scan = TRUE; -+ } -+ } -+ if (mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { -+ /* Scan frequency of 30 sec */ -+ pfn_param.scan_freq = htod32(30); -+ /* slow adapt scan is off by default */ -+ pfn_param.slow_freq = htod32(0); -+ /* RSSI margin of 30 dBm */ -+ pfn_param.rssi_margin = htod16(30); -+ /* Network timeout 60 sec */ -+ pfn_param.lost_network_timeout = htod32(60); -+ /* best n = 2 by default */ -+ pfn_param.bestn = DEFAULT_BESTN; -+ /* mscan m=0 by default, so not record best networks by default */ -+ pfn_param.mscan = DEFAULT_MSCAN; -+ /* default repeat = 10 */ -+ pfn_param.repeat = DEFAULT_REPEAT; -+ /* by default, maximum scan interval = 2^2 -+ * scan_freq when adaptive scan is turned on -+ */ -+ pfn_param.exp = DEFAULT_EXP; -+ if (mode == DHD_PNO_BATCH_MODE) { -+ /* In case of BATCH SCAN */ -+ if (pno_params->params_batch.bestn) -+ pfn_param.bestn = pno_params->params_batch.bestn; -+ if (pno_params->params_batch.scan_fr) -+ pfn_param.scan_freq = htod32(pno_params->params_batch.scan_fr); -+ if (pno_params->params_batch.mscan) -+ pfn_param.mscan = pno_params->params_batch.mscan; -+ /* enable broadcast scan */ -+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT); -+ } else if (mode == DHD_PNO_HOTLIST_MODE) { -+ /* In case of HOTLIST SCAN */ -+ if (pno_params->params_hotlist.scan_fr) -+ pfn_param.scan_freq = htod32(pno_params->params_hotlist.scan_fr); -+ pfn_param.bestn = 0; -+ pfn_param.repeat = 0; -+ /* enable broadcast scan */ -+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT); -+ } -+ if (combined_scan) { -+ /* Disable Adaptive Scan */ -+ pfn_param.flags &= ~(htod16(ENABLE << ENABLE_ADAPTSCAN_BIT)); -+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT); -+ pfn_param.repeat = 0; -+ pfn_param.exp = 0; -+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { -+ /* In case of Legacy PNO + BATCH SCAN */ -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]); -+ if (_params->params_batch.bestn) -+ pfn_param.bestn = _params->params_batch.bestn; -+ if (_params->params_batch.scan_fr) -+ pfn_param.scan_freq = htod32(_params->params_batch.scan_fr); -+ if (_params->params_batch.mscan) -+ pfn_param.mscan = _params->params_batch.mscan; -+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { -+ /* In case of Legacy PNO + HOTLIST SCAN */ -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]); -+ if (_params->params_hotlist.scan_fr) -+ pfn_param.scan_freq = htod32(_params->params_hotlist.scan_fr); -+ pfn_param.bestn = 0; -+ pfn_param.repeat = 0; -+ } -+ } -+ } -+ if (pfn_param.scan_freq < htod32(PNO_SCAN_MIN_FW_SEC) || -+ pfn_param.scan_freq > htod32(PNO_SCAN_MAX_FW_SEC)) { -+ AP6210_ERR("%s pno freq(%d sec) is not valid \n", -+ __FUNCTION__, PNO_SCAN_MIN_FW_SEC); -+ err = BCME_BADARG; -+ goto exit; -+ } -+ if (mode == DHD_PNO_BATCH_MODE) { -+ int _tmp = pfn_param.bestn; -+ /* set bestn to calculate the max mscan which firmware supports */ -+ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to set pfnmscan\n", __FUNCTION__); -+ goto exit; -+ } -+ /* get max mscan which the firmware supports */ -+ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 0); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to get pfnmscan\n", __FUNCTION__); -+ goto exit; -+ } -+ AP6210_DEBUG(" returned mscan : %d, set bestn : %d\n", _tmp, pfn_param.bestn); -+ pfn_param.mscan = MIN(pfn_param.mscan, _tmp); -+ } -+ err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn_set\n", __FUNCTION__); -+ goto exit; -+ } -+ /* need to return mscan if this is for batch scan instead of err */ -+ err = (mode == DHD_PNO_BATCH_MODE)? pfn_param.mscan : err; -+exit: -+ return err; -+} -+static int -+_dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssids_list, int nssid) -+{ -+ int err = BCME_OK; -+ int i = 0; -+ wl_pfn_t pfn_element; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ if (nssid) { -+ NULL_CHECK(ssids_list, "ssid list is NULL", err); -+ } -+ memset(&pfn_element, 0, sizeof(pfn_element)); -+ { -+ int j; -+ for (j = 0; j < nssid; j++) { -+ AP6210_DEBUG("%d: scan for %s size = %d\n", j, -+ ssids_list[j].SSID, ssids_list[j].SSID_len); -+ } -+ } -+ /* Check for broadcast ssid */ -+ for (i = 0; i < nssid; i++) { -+ if (!ssids_list[i].SSID_len) { -+ AP6210_ERR("%d: Broadcast SSID is ilegal for PNO setting\n", i); -+ err = BCME_ERROR; -+ goto exit; -+ } -+ } -+ /* set all pfn ssid */ -+ for (i = 0; i < nssid; i++) { -+ pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); -+ pfn_element.auth = (DOT11_OPEN_SYSTEM); -+ pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); -+ pfn_element.wsec = htod32(0); -+ pfn_element.infra = htod32(1); -+ pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); -+ memcpy((char *)pfn_element.ssid.SSID, ssids_list[i].SSID, -+ ssids_list[i].SSID_len); -+ pfn_element.ssid.SSID_len = ssids_list[i].SSID_len; -+ err = dhd_iovar(dhd, 0, "pfn_add", (char *)&pfn_element, -+ sizeof(pfn_element), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn_add\n", __FUNCTION__); -+ goto exit; -+ } -+ } -+exit: -+ return err; -+} -+/* qsort compare function */ -+static int -+_dhd_pno_cmpfunc(const void *a, const void *b) -+{ -+ return (*(uint16*)a - *(uint16*)b); -+} -+static int -+_dhd_pno_chan_merge(uint16 *d_chan_list, int *nchan, -+ uint16 *chan_list1, int nchan1, uint16 *chan_list2, int nchan2) -+{ -+ int err = BCME_OK; -+ int i = 0, j = 0, k = 0; -+ uint16 tmp; -+ NULL_CHECK(d_chan_list, "d_chan_list is NULL", err); -+ NULL_CHECK(nchan, "nchan is NULL", err); -+ NULL_CHECK(chan_list1, "chan_list1 is NULL", err); -+ NULL_CHECK(chan_list2, "chan_list2 is NULL", err); -+ /* chan_list1 and chan_list2 should be sorted at first */ -+ while (i < nchan1 && j < nchan2) { -+ tmp = chan_list1[i] < chan_list2[j]? -+ chan_list1[i++] : chan_list2[j++]; -+ for (; i < nchan1 && chan_list1[i] == tmp; i++); -+ for (; j < nchan2 && chan_list2[j] == tmp; j++); -+ d_chan_list[k++] = tmp; -+ } -+ -+ while (i < nchan1) { -+ tmp = chan_list1[i++]; -+ for (; i < nchan1 && chan_list1[i] == tmp; i++); -+ d_chan_list[k++] = tmp; -+ } -+ -+ while (j < nchan2) { -+ tmp = chan_list2[j++]; -+ for (; j < nchan2 && chan_list2[j] == tmp; j++); -+ d_chan_list[k++] = tmp; -+ -+ } -+ *nchan = k; -+ return err; -+} -+static int -+_dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list, -+ int *nchan, uint8 band, bool skip_dfs) -+{ -+ int err = BCME_OK; -+ int i, j; -+ uint32 chan_buf[WL_NUMCHANNELS + 1]; -+ wl_uint32_list_t *list; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ if (*nchan) { -+ NULL_CHECK(d_chan_list, "d_chan_list is NULL", err); -+ } -+ list = (wl_uint32_list_t *) (void *)chan_buf; -+ list->count = htod32(WL_NUMCHANNELS); -+ err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, chan_buf, sizeof(chan_buf), FALSE, 0); -+ if (err < 0) { -+ AP6210_ERR("failed to get channel list (err: %d)\n", err); -+ goto exit; -+ } -+ for (i = 0, j = 0; i < dtoh32(list->count) && i < *nchan; i++) { -+ if (band == WLC_BAND_2G) { -+ if (dtoh32(list->element[i]) > CHANNEL_2G_MAX) -+ continue; -+ } else if (band == WLC_BAND_5G) { -+ if (dtoh32(list->element[i]) <= CHANNEL_2G_MAX) -+ continue; -+ if (skip_dfs && is_dfs(dtoh32(list->element[i]))) -+ continue; -+ -+ } else { /* All channels */ -+ if (skip_dfs && is_dfs(dtoh32(list->element[i]))) -+ continue; -+ } -+ d_chan_list[j++] = dtoh32(list->element[i]); -+ } -+ *nchan = j; -+exit: -+ return err; -+} -+static int -+_dhd_pno_convert_format(dhd_pub_t *dhd, struct dhd_pno_batch_params *params_batch, -+ char *buf, int nbufsize) -+{ -+ int err = BCME_OK; -+ int bytes_written = 0, nreadsize = 0; -+ int t_delta = 0; -+ int nleftsize = nbufsize; -+ uint8 cnt = 0; -+ char *bp = buf; -+ char eabuf[ETHER_ADDR_STR_LEN]; -+#ifdef PNO_DEBUG -+ char *_base_bp; -+ char msg[150]; -+#endif -+ dhd_pno_bestnet_entry_t *iter, *next; -+ dhd_pno_scan_results_t *siter, *snext; -+ dhd_pno_best_header_t *phead, *pprev; -+ NULL_CHECK(params_batch, "params_batch is NULL", err); -+ if (nbufsize > 0) -+ NULL_CHECK(buf, "buf is NULL", err); -+ /* initialize the buffer */ -+ memset(buf, 0, nbufsize); -+ AP6210_DEBUG("%s enter \n", __FUNCTION__); -+ /* # of scans */ -+ if (!params_batch->get_batch.batch_started) { -+ bp += nreadsize = sprintf(bp, "scancount=%d\n", -+ params_batch->get_batch.expired_tot_scan_cnt); -+ nleftsize -= nreadsize; -+ params_batch->get_batch.batch_started = TRUE; -+ } -+ AP6210_DEBUG("%s scancount %d\n", __FUNCTION__, params_batch->get_batch.expired_tot_scan_cnt); -+ /* preestimate scan count until which scan result this report is going to end */ -+ list_for_each_entry_safe(siter, snext, -+ ¶ms_batch->get_batch.expired_scan_results_list, list) { -+ phead = siter->bestnetheader; -+ while (phead != NULL) { -+ /* if left_size is less than bestheader total size , stop this */ -+ if (nleftsize <= -+ (phead->tot_size + phead->tot_cnt * ENTRY_OVERHEAD)) -+ goto exit; -+ /* increase scan count */ -+ cnt++; -+ /* # best of each scan */ -+ AP6210_DEBUG("\n", cnt - 1, phead->tot_cnt); -+ /* attribute of the scan */ -+ if (phead->reason & PNO_STATUS_ABORT_MASK) { -+ bp += nreadsize = sprintf(bp, "trunc\n"); -+ nleftsize -= nreadsize; -+ } -+ list_for_each_entry_safe(iter, next, -+ &phead->entry_list, list) { -+ t_delta = jiffies_to_msecs(jiffies - iter->recorded_time); -+#ifdef PNO_DEBUG -+ _base_bp = bp; -+ memset(msg, 0, sizeof(msg)); -+#endif -+ /* BSSID info */ -+ bp += nreadsize = sprintf(bp, "bssid=%s\n", -+ bcm_ether_ntoa((const struct ether_addr *)&iter->BSSID, eabuf)); -+ nleftsize -= nreadsize; -+ /* SSID */ -+ bp += nreadsize = sprintf(bp, "ssid=%s\n", iter->SSID); -+ nleftsize -= nreadsize; -+ /* channel */ -+ bp += nreadsize = sprintf(bp, "freq=%d\n", -+ wf_channel2mhz(iter->channel, -+ iter->channel <= CH_MAX_2G_CHANNEL? -+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G)); -+ nleftsize -= nreadsize; -+ /* RSSI */ -+ bp += nreadsize = sprintf(bp, "level=%d\n", iter->RSSI); -+ nleftsize -= nreadsize; -+ /* add the time consumed in Driver to the timestamp of firmware */ -+ iter->timestamp += t_delta; -+ bp += nreadsize = sprintf(bp, "age=%d\n", iter->timestamp); -+ nleftsize -= nreadsize; -+ /* RTT0 */ -+ bp += nreadsize = sprintf(bp, "dist=%d\n", -+ (iter->rtt0 == 0)? -1 : iter->rtt0); -+ nleftsize -= nreadsize; -+ /* RTT1 */ -+ bp += nreadsize = sprintf(bp, "distSd=%d\n", -+ (iter->rtt0 == 0)? -1 : iter->rtt1); -+ nleftsize -= nreadsize; -+ bp += nreadsize = sprintf(bp, "%s", AP_END_MARKER); -+ nleftsize -= nreadsize; -+ list_del(&iter->list); -+ MFREE(dhd->osh, iter, BESTNET_ENTRY_SIZE); -+#ifdef PNO_DEBUG -+ memcpy(msg, _base_bp, bp - _base_bp); -+ AP6210_DEBUG("Entry : \n%s", msg); -+#endif -+ } -+ bp += nreadsize = sprintf(bp, "%s", SCAN_END_MARKER); -+ AP6210_DEBUG("%s", SCAN_END_MARKER); -+ nleftsize -= nreadsize; -+ pprev = phead; -+ /* reset the header */ -+ siter->bestnetheader = phead = phead->next; -+ MFREE(dhd->osh, pprev, BEST_HEADER_SIZE); -+ -+ siter->cnt_header--; -+ } -+ if (phead == NULL) { -+ /* we store all entry in this scan , so it is ok to delete */ -+ list_del(&siter->list); -+ MFREE(dhd->osh, siter, SCAN_RESULTS_SIZE); -+ } -+ } -+exit: -+ if (cnt < params_batch->get_batch.expired_tot_scan_cnt) { -+ AP6210_ERR("Buffer size is small to save all batch entry," -+ " cnt : %d (remained_scan_cnt): %d\n", -+ cnt, params_batch->get_batch.expired_tot_scan_cnt - cnt); -+ } -+ params_batch->get_batch.expired_tot_scan_cnt -= cnt; -+ /* set FALSE only if the link list is empty after returning the data */ -+ if (list_empty(¶ms_batch->get_batch.expired_scan_results_list)) { -+ params_batch->get_batch.batch_started = FALSE; -+ bp += sprintf(bp, "%s", RESULTS_END_MARKER); -+ AP6210_DEBUG("%s", RESULTS_END_MARKER); -+ AP6210_DEBUG("%s : Getting the batching data is complete\n", __FUNCTION__); -+ } -+ /* return used memory in buffer */ -+ bytes_written = (int32)(bp - buf); -+ return bytes_written; -+} -+static int -+_dhd_pno_clear_all_batch_results(dhd_pub_t *dhd, struct list_head *head, bool only_last) -+{ -+ int err = BCME_OK; -+ int removed_scan_cnt = 0; -+ dhd_pno_scan_results_t *siter, *snext; -+ dhd_pno_best_header_t *phead, *pprev; -+ dhd_pno_bestnet_entry_t *iter, *next; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(head, "head is NULL", err); -+ NULL_CHECK(head->next, "head->next is NULL", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ list_for_each_entry_safe(siter, snext, -+ head, list) { -+ if (only_last) { -+ /* in case that we need to delete only last one */ -+ if (!list_is_last(&siter->list, head)) { -+ /* skip if the one is not last */ -+ continue; -+ } -+ } -+ /* delete all data belong if the one is last */ -+ phead = siter->bestnetheader; -+ while (phead != NULL) { -+ removed_scan_cnt++; -+ list_for_each_entry_safe(iter, next, -+ &phead->entry_list, list) { -+ list_del(&iter->list); -+ MFREE(dhd->osh, iter, BESTNET_ENTRY_SIZE); -+ } -+ pprev = phead; -+ phead = phead->next; -+ MFREE(dhd->osh, pprev, BEST_HEADER_SIZE); -+ } -+ if (phead == NULL) { -+ /* it is ok to delete top node */ -+ list_del(&siter->list); -+ MFREE(dhd->osh, siter, SCAN_RESULTS_SIZE); -+ } -+ } -+ return removed_scan_cnt; -+} -+ -+static int -+_dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan) -+{ -+ int err = BCME_OK; -+ int i = 0; -+ wl_pfn_cfg_t pfncfg_param; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ if (nchan) { -+ NULL_CHECK(channel_list, "nchan is NULL", err); -+ } -+ AP6210_DEBUG("%s enter : nchan : %d\n", __FUNCTION__, nchan); -+ memset(&pfncfg_param, 0, sizeof(wl_pfn_cfg_t)); -+ /* Setup default values */ -+ pfncfg_param.reporttype = htod32(WL_PFN_REPORT_ALLNET); -+ pfncfg_param.channel_num = htod32(0); -+ -+ for (i = 0; i < nchan && nchan < WL_NUMCHANNELS; i++) -+ pfncfg_param.channel_list[i] = channel_list[i]; -+ -+ pfncfg_param.channel_num = htod32(nchan); -+ err = dhd_iovar(dhd, 0, "pfn_cfg", (char *)&pfncfg_param, sizeof(pfncfg_param), 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn_cfg\n", __FUNCTION__); -+ goto exit; -+ } -+exit: -+ return err; -+} -+static int -+_dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mode_t mode) -+{ -+ int err = BCME_OK; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL\n", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL\n", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ mutex_lock(&_pno_state->pno_mutex); -+ switch (mode) { -+ case DHD_PNO_LEGACY_MODE: { -+ struct dhd_pno_ssid *iter, *next; -+ if (params->params_legacy.nssid > 0) { -+ list_for_each_entry_safe(iter, next, -+ ¶ms->params_legacy.ssid_list, list) { -+ list_del(&iter->list); -+ kfree(iter); -+ } -+ } -+ params->params_legacy.scan_fr = 0; -+ params->params_legacy.pno_freq_expo_max = 0; -+ params->params_legacy.pno_repeat = 0; -+ params->params_legacy.nchan = 0; -+ memset(params->params_legacy.chan_list, 0, -+ sizeof(params->params_legacy.chan_list)); -+ break; -+ } -+ case DHD_PNO_BATCH_MODE: { -+ params->params_batch.scan_fr = 0; -+ params->params_batch.mscan = 0; -+ params->params_batch.nchan = 0; -+ params->params_batch.rtt = 0; -+ params->params_batch.bestn = 0; -+ params->params_batch.nchan = 0; -+ params->params_batch.band = WLC_BAND_AUTO; -+ memset(params->params_batch.chan_list, 0, -+ sizeof(params->params_batch.chan_list)); -+ params->params_batch.get_batch.batch_started = FALSE; -+ params->params_batch.get_batch.buf = NULL; -+ params->params_batch.get_batch.bufsize = 0; -+ params->params_batch.get_batch.reason = 0; -+ _dhd_pno_clear_all_batch_results(dhd, -+ ¶ms->params_batch.get_batch.scan_results_list, FALSE); -+ _dhd_pno_clear_all_batch_results(dhd, -+ ¶ms->params_batch.get_batch.expired_scan_results_list, FALSE); -+ params->params_batch.get_batch.tot_scan_cnt = 0; -+ params->params_batch.get_batch.expired_tot_scan_cnt = 0; -+ params->params_batch.get_batch.top_node_cnt = 0; -+ INIT_LIST_HEAD(¶ms->params_batch.get_batch.scan_results_list); -+ INIT_LIST_HEAD(¶ms->params_batch.get_batch.expired_scan_results_list); -+ break; -+ } -+ case DHD_PNO_HOTLIST_MODE: { -+ struct dhd_pno_bssid *iter, *next; -+ if (params->params_hotlist.nbssid > 0) { -+ list_for_each_entry_safe(iter, next, -+ ¶ms->params_hotlist.bssid_list, list) { -+ list_del(&iter->list); -+ kfree(iter); -+ } -+ } -+ params->params_hotlist.scan_fr = 0; -+ params->params_hotlist.nbssid = 0; -+ params->params_hotlist.nchan = 0; -+ params->params_batch.band = WLC_BAND_AUTO; -+ memset(params->params_hotlist.chan_list, 0, -+ sizeof(params->params_hotlist.chan_list)); -+ break; -+ } -+ default: -+ AP6210_ERR("%s : unknown mode : %d\n", __FUNCTION__, mode); -+ break; -+ } -+ mutex_unlock(&_pno_state->pno_mutex); -+ return err; -+} -+static int -+_dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid) -+{ -+ int err = BCME_OK; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ if (nbssid) { -+ NULL_CHECK(p_pfn_bssid, "bssid list is NULL", err); -+ } -+ err = dhd_iovar(dhd, 0, "pfn_add_bssid", (char *)&p_pfn_bssid, -+ sizeof(wl_pfn_bssid_t) * nbssid, 1); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to execute pfn_cfg\n", __FUNCTION__); -+ goto exit; -+ } -+exit: -+ return err; -+} -+int -+dhd_pno_stop_for_ssid(dhd_pub_t *dhd) -+{ -+ int err = BCME_OK; -+ uint32 mode = 0; -+ dhd_pno_status_info_t *_pno_state; -+ dhd_pno_params_t *_params; -+ wl_pfn_bssid_t *p_pfn_bssid; -+ NULL_CHECK(dhd, "dev is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ if (!(_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)) { -+ AP6210_ERR("%s : LEGACY PNO MODE is not enabled\n", __FUNCTION__); -+ goto exit; -+ } -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ /* restart Batch mode if the batch mode is on */ -+ if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { -+ /* retrieve the batching data from firmware into host */ -+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); -+ /* save current pno_mode before calling dhd_pno_clean */ -+ mode = _pno_state->pno_mode; -+ _dhd_pno_clean(dhd); -+ /* restore previous pno_mode */ -+ _pno_state->pno_mode = mode; -+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]); -+ /* restart BATCH SCAN */ -+ err = dhd_pno_set_for_batch(dhd, &_params->params_batch); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; -+ AP6210_ERR("%s : failed to restart batch scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { -+ /* restart HOTLIST SCAN */ -+ struct dhd_pno_bssid *iter, *next; -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]); -+ p_pfn_bssid = kzalloc(sizeof(wl_pfn_bssid_t) * -+ _params->params_hotlist.nbssid, GFP_KERNEL); -+ if (p_pfn_bssid == NULL) { -+ AP6210_ERR("%s : failed to allocate wl_pfn_bssid_t array" -+ " (count: %d)", -+ __FUNCTION__, _params->params_hotlist.nbssid); -+ err = BCME_ERROR; -+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; -+ goto exit; -+ } -+ /* convert dhd_pno_bssid to wl_pfn_bssid */ -+ list_for_each_entry_safe(iter, next, -+ &_params->params_hotlist.bssid_list, list) { -+ memcpy(&p_pfn_bssid->macaddr, -+ &iter->macaddr, ETHER_ADDR_LEN); -+ p_pfn_bssid->flags = iter->flags; -+ p_pfn_bssid++; -+ } -+ err = dhd_pno_set_for_hotlist(dhd, p_pfn_bssid, &_params->params_hotlist); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; -+ AP6210_ERR("%s : failed to restart hotlist scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ } else { -+ err = _dhd_pno_clean(dhd); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+exit: -+ return err; -+} -+ -+int -+dhd_pno_enable(dhd_pub_t *dhd, int enable) -+{ -+ int err = BCME_OK; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ return (_dhd_pno_enable(dhd, enable)); -+} -+ -+int -+dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, -+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan) -+{ -+ struct dhd_pno_ssid *_pno_ssid; -+ dhd_pno_params_t *_params; -+ dhd_pno_params_t *_params2; -+ dhd_pno_status_info_t *_pno_state; -+ uint16 _chan_list[WL_NUMCHANNELS]; -+ int32 tot_nchan = 0; -+ int err = BCME_OK; -+ int i; -+ int mode = 0; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ AP6210_DEBUG("%s enter : scan_fr :%d, pno_repeat :%d," -+ "pno_freq_expo_max: %d, nchan :%d\n", __FUNCTION__, -+ scan_fr, pno_repeat, pno_freq_expo_max, nchan); -+ -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); -+ if (!(_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)) { -+ _pno_state->pno_mode |= DHD_PNO_LEGACY_MODE; -+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to reinitialize profile (err %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ memset(_chan_list, 0, sizeof(_chan_list)); -+ tot_nchan = nchan; -+ if (tot_nchan > 0 && channel_list) { -+ for (i = 0; i < nchan; i++) -+ _params->params_legacy.chan_list[i] = _chan_list[i] = channel_list[i]; -+ } -+ if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) { -+ AP6210_DEBUG("BATCH SCAN is on progress in firmware\n"); -+ /* retrieve the batching data from firmware into host */ -+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); -+ /* store current pno_mode before disabling pno */ -+ mode = _pno_state->pno_mode; -+ err = _dhd_pno_enable(dhd, PNO_OFF); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__); -+ goto exit; -+ } -+ /* restore the previous mode */ -+ _pno_state->pno_mode = mode; -+ /* use superset of channel list between two mode */ -+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { -+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]); -+ if (_params2->params_batch.nchan > 0 && nchan > 0) { -+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, -+ &_params2->params_batch.chan_list[0], -+ _params2->params_batch.nchan, -+ &channel_list[0], nchan); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to merge channel list" -+ " between legacy and batch\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } else { -+ AP6210_DEBUG("superset channel will use" -+ " all channels in firmware\n"); -+ } -+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { -+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]); -+ if (_params2->params_hotlist.nchan > 0 && nchan > 0) { -+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, -+ &_params2->params_hotlist.chan_list[0], -+ _params2->params_hotlist.nchan, -+ &channel_list[0], nchan); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to merge channel list" -+ " between legacy and hotlist\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } -+ } -+ } -+ _params->params_legacy.scan_fr = scan_fr; -+ _params->params_legacy.pno_repeat = pno_repeat; -+ _params->params_legacy.pno_freq_expo_max = pno_freq_expo_max; -+ _params->params_legacy.nchan = nchan; -+ _params->params_legacy.nssid = nssid; -+ INIT_LIST_HEAD(&_params->params_legacy.ssid_list); -+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_LEGACY_MODE)) < 0) { -+ AP6210_ERR("failed to set call pno_set (err %d) in firmware\n", err); -+ goto exit; -+ } -+ if ((err = _dhd_pno_add_ssid(dhd, ssid_list, nssid)) < 0) { -+ AP6210_ERR("failed to add ssid list (err %d) in firmware\n", err); -+ goto exit; -+ } -+ for (i = 0; i < nssid; i++) { -+ _pno_ssid = kzalloc(sizeof(struct dhd_pno_ssid), GFP_KERNEL); -+ if (_pno_ssid == NULL) { -+ AP6210_ERR("%s : failed to allocate struct dhd_pno_ssid\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ _pno_ssid->SSID_len = ssid_list[i].SSID_len; -+ memcpy(_pno_ssid->SSID, ssid_list[i].SSID, _pno_ssid->SSID_len); -+ list_add_tail(&_pno_ssid->list, &_params->params_legacy.ssid_list); -+ -+ } -+ if (tot_nchan > 0) { -+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) { -+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ if (_pno_state->pno_status == DHD_PNO_DISABLED) { -+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0) -+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__); -+ } -+exit: -+ /* clear mode in case of error */ -+ if (err < 0) -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ return err; -+} -+int -+dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params) -+{ -+ int err = BCME_OK; -+ uint16 _chan_list[WL_NUMCHANNELS]; -+ int rem_nchan = 0, tot_nchan = 0; -+ int mode = 0, mscan = 0; -+ int i = 0; -+ dhd_pno_params_t *_params; -+ dhd_pno_params_t *_params2; -+ dhd_pno_status_info_t *_pno_state; -+ wlc_ssid_t *p_ssid_list = NULL; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ NULL_CHECK(batch_params, "batch_params is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; -+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { -+ _pno_state->pno_mode |= DHD_PNO_BATCH_MODE; -+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_reinitialize_prof\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } -+ _params->params_batch.scan_fr = batch_params->scan_fr; -+ _params->params_batch.bestn = batch_params->bestn; -+ _params->params_batch.mscan = (batch_params->mscan)? -+ batch_params->mscan : DEFAULT_BATCH_MSCAN; -+ _params->params_batch.nchan = batch_params->nchan; -+ memcpy(_params->params_batch.chan_list, batch_params->chan_list, -+ sizeof(_params->params_batch.chan_list)); -+ -+ memset(_chan_list, 0, sizeof(_chan_list)); -+ -+ rem_nchan = ARRAYSIZE(batch_params->chan_list) - batch_params->nchan; -+ if (batch_params->band == WLC_BAND_2G || batch_params->band == WLC_BAND_5G) { -+ /* get a valid channel list based on band B or A */ -+ err = _dhd_pno_get_channels(dhd, -+ &_params->params_batch.chan_list[batch_params->nchan], -+ &rem_nchan, batch_params->band, FALSE); -+ if (err < 0) { -+ AP6210_ERR("%s: failed to get valid channel list(band : %d)\n", -+ __FUNCTION__, batch_params->band); -+ goto exit; -+ } -+ /* now we need to update nchan because rem_chan has valid channel count */ -+ _params->params_batch.nchan += rem_nchan; -+ /* need to sort channel list */ -+ sort(_params->params_batch.chan_list, _params->params_batch.nchan, -+ sizeof(_params->params_batch.chan_list[0]), _dhd_pno_cmpfunc, NULL); -+ } -+#ifdef PNO_DEBUG -+{ -+ AP6210_DEBUG("Channel list : "); -+ for (i = 0; i < _params->params_batch.nchan; i++) { -+ AP6210_DEBUG("%d ", _params->params_batch.chan_list[i]); -+ } -+ AP6210_DEBUG("\n"); -+} -+#endif -+ if (_params->params_batch.nchan) { -+ /* copy the channel list into local array */ -+ memcpy(_chan_list, _params->params_batch.chan_list, sizeof(_chan_list)); -+ tot_nchan = _params->params_batch.nchan; -+ } -+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { -+ struct dhd_pno_ssid *iter, *next; -+ AP6210_DEBUG("PNO SSID is on progress in firmware\n"); -+ /* store current pno_mode before disabling pno */ -+ mode = _pno_state->pno_mode; -+ err = _dhd_pno_enable(dhd, PNO_OFF); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__); -+ goto exit; -+ } -+ /* restore the previous mode */ -+ _pno_state->pno_mode = mode; -+ /* Use the superset for channelist between two mode */ -+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); -+ if (_params2->params_legacy.nchan > 0 && _params->params_batch.nchan > 0) { -+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, -+ &_params2->params_legacy.chan_list[0], -+ _params2->params_legacy.nchan, -+ &_params->params_batch.chan_list[0], _params->params_batch.nchan); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to merge channel list" -+ " between legacy and batch\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } else { -+ AP6210_DEBUG("superset channel will use all channels in firmware\n"); -+ } -+ p_ssid_list = kzalloc(sizeof(wlc_ssid_t) * -+ _params2->params_legacy.nssid, GFP_KERNEL); -+ if (p_ssid_list == NULL) { -+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)", -+ __FUNCTION__, _params2->params_legacy.nssid); -+ err = BCME_ERROR; -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ goto exit; -+ } -+ i = 0; -+ /* convert dhd_pno_ssid to dhd_pno_ssid */ -+ list_for_each_entry_safe(iter, next, &_params2->params_legacy.ssid_list, list) { -+ p_ssid_list[i].SSID_len = iter->SSID_len; -+ memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list[i].SSID_len); -+ i++; -+ } -+ if ((err = _dhd_pno_add_ssid(dhd, p_ssid_list, -+ _params2->params_legacy.nssid)) < 0) { -+ AP6210_ERR("failed to add ssid list (err %d) in firmware\n", err); -+ goto exit; -+ } -+ } -+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_BATCH_MODE)) < 0) { -+ AP6210_ERR("%s : failed to set call pno_set (err %d) in firmware\n", -+ __FUNCTION__, err); -+ goto exit; -+ } else { -+ /* we need to return mscan */ -+ mscan = err; -+ } -+ if (tot_nchan > 0) { -+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) { -+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ if (_pno_state->pno_status == DHD_PNO_DISABLED) { -+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0) -+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__); -+ } -+exit: -+ /* clear mode in case of error */ -+ if (err < 0) -+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; -+ else { -+ /* return #max scan firmware can do */ -+ err = mscan; -+ } -+ if (p_ssid_list) -+ kfree(p_ssid_list); -+ return err; -+} -+ -+static int -+_dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) -+{ -+ int err = BCME_OK; -+ int i, j; -+ uint32 timestamp = 0; -+ dhd_pno_params_t *_params = NULL; -+ dhd_pno_status_info_t *_pno_state = NULL; -+ wl_pfn_lscanresults_t *plbestnet = NULL; -+ wl_pfn_lnet_info_t *plnetinfo; -+ dhd_pno_bestnet_entry_t *pbestnet_entry; -+ dhd_pno_best_header_t *pbestnetheader = NULL; -+ dhd_pno_scan_results_t *pscan_results = NULL, *siter, *snext; -+ bool allocate_header = FALSE; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { -+ AP6210_ERR("%s: Batching SCAN mode is not enabled\n", __FUNCTION__); -+ goto exit; -+ } -+ mutex_lock(&_pno_state->pno_mutex); -+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; -+ if (buf && bufsize) { -+ if (!list_empty(&_params->params_batch.get_batch.expired_scan_results_list)) { -+ /* need to check whether we have cashed data or not */ -+ AP6210_DEBUG("%s: have cashed batching data in Driver\n", -+ __FUNCTION__); -+ /* convert to results format */ -+ goto convert_format; -+ } else { -+ /* this is a first try to get batching results */ -+ if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) { -+ /* move the scan_results_list to expired_scan_results_lists */ -+ list_for_each_entry_safe(siter, snext, -+ &_params->params_batch.get_batch.scan_results_list, list) { -+ list_move_tail(&siter->list, -+ &_params->params_batch.get_batch.expired_scan_results_list); -+ } -+ _params->params_batch.get_batch.top_node_cnt = 0; -+ _params->params_batch.get_batch.expired_tot_scan_cnt = -+ _params->params_batch.get_batch.tot_scan_cnt; -+ _params->params_batch.get_batch.tot_scan_cnt = 0; -+ goto convert_format; -+ } -+ } -+ } -+ /* create dhd_pno_scan_results_t whenever we got event WLC_E_PFN_BEST_BATCHING */ -+ pscan_results = (dhd_pno_scan_results_t *)MALLOC(dhd->osh, SCAN_RESULTS_SIZE); -+ if (pscan_results == NULL) { -+ err = BCME_NOMEM; -+ AP6210_ERR("failed to allocate dhd_pno_scan_results_t\n"); -+ goto exit; -+ } -+ pscan_results->bestnetheader = NULL; -+ pscan_results->cnt_header = 0; -+ /* add the element into list unless total node cnt is less than MAX_NODE_ CNT */ -+ if (_params->params_batch.get_batch.top_node_cnt < MAX_NODE_CNT) { -+ list_add(&pscan_results->list, &_params->params_batch.get_batch.scan_results_list); -+ _params->params_batch.get_batch.top_node_cnt++; -+ } else { -+ int _removed_scan_cnt; -+ /* remove oldest one and add new one */ -+ AP6210_DEBUG("%s : Remove oldest node and add new one\n", __FUNCTION__); -+ _removed_scan_cnt = _dhd_pno_clear_all_batch_results(dhd, -+ &_params->params_batch.get_batch.scan_results_list, TRUE); -+ _params->params_batch.get_batch.tot_scan_cnt -= _removed_scan_cnt; -+ list_add(&pscan_results->list, &_params->params_batch.get_batch.scan_results_list); -+ -+ } -+ plbestnet = (wl_pfn_lscanresults_t *)MALLOC(dhd->osh, PNO_BESTNET_LEN); -+ NULL_CHECK(plbestnet, "failed to allocate buffer for bestnet", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ memset(plbestnet, 0, PNO_BESTNET_LEN); -+ while (plbestnet->status != PFN_COMPLETE) { -+ memset(plbestnet, 0, PNO_BESTNET_LEN); -+ err = dhd_iovar(dhd, 0, "pfnlbest", (char *)plbestnet, PNO_BESTNET_LEN, 0); -+ if (err < 0) { -+ if (err == BCME_EPERM) { -+ AP6210_ERR("we cannot get the batching data " -+ "during scanning in firmware, try again\n,"); -+ msleep(500); -+ continue; -+ } else { -+ AP6210_ERR("%s : failed to execute pfnlbest (err :%d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ AP6210_DEBUG("ver %d, status : %d, count %d\n", plbestnet->version, -+ plbestnet->status, plbestnet->count); -+ if (plbestnet->version != PFN_SCANRESULT_VERSION) { -+ err = BCME_VERSION; -+ AP6210_ERR("bestnet version(%d) is mismatch with Driver version(%d)\n", -+ plbestnet->version, PFN_SCANRESULT_VERSION); -+ goto exit; -+ } -+ plnetinfo = plbestnet->netinfo; -+ for (i = 0; i < plbestnet->count; i++) { -+ pbestnet_entry = (dhd_pno_bestnet_entry_t *) -+ MALLOC(dhd->osh, BESTNET_ENTRY_SIZE); -+ if (pbestnet_entry == NULL) { -+ err = BCME_NOMEM; -+ AP6210_ERR("failed to allocate dhd_pno_bestnet_entry\n"); -+ goto exit; -+ } -+ pbestnet_entry->recorded_time = jiffies; /* record the current time */ -+ /* create header for the first entry */ -+ allocate_header = (i == 0)? TRUE : FALSE; -+ /* check whether the new generation is started or not */ -+ if (timestamp && (TIME_DIFF(timestamp, plnetinfo->timestamp) -+ > TIME_MIN_DIFF)) -+ allocate_header = TRUE; -+ timestamp = plnetinfo->timestamp; -+ if (allocate_header) { -+ pbestnetheader = (dhd_pno_best_header_t *) -+ MALLOC(dhd->osh, BEST_HEADER_SIZE); -+ if (pbestnetheader == NULL) { -+ err = BCME_NOMEM; -+ if (pbestnet_entry) -+ MFREE(dhd->osh, pbestnet_entry, -+ BESTNET_ENTRY_SIZE); -+ AP6210_ERR("failed to allocate dhd_pno_bestnet_entry\n"); -+ goto exit; -+ } -+ /* increase total cnt of bestnet header */ -+ pscan_results->cnt_header++; -+ /* need to record the reason to call dhd_pno_get_for_bach */ -+ if (reason) -+ pbestnetheader->reason = (ENABLE << reason); -+ memset(pbestnetheader, 0, BEST_HEADER_SIZE); -+ /* initialize the head of linked list */ -+ INIT_LIST_HEAD(&(pbestnetheader->entry_list)); -+ /* link the pbestnet heaer into existed list */ -+ if (pscan_results->bestnetheader == NULL) -+ /* In case of header */ -+ pscan_results->bestnetheader = pbestnetheader; -+ else { -+ dhd_pno_best_header_t *head = pscan_results->bestnetheader; -+ pscan_results->bestnetheader = pbestnetheader; -+ pbestnetheader->next = head; -+ } -+ } -+ /* fills the best network info */ -+ pbestnet_entry->channel = plnetinfo->pfnsubnet.channel; -+ pbestnet_entry->RSSI = plnetinfo->RSSI; -+ if (plnetinfo->flags & PFN_PARTIAL_SCAN_MASK) { -+ /* if RSSI is positive value, we assume that -+ * this scan is aborted by other scan -+ */ -+ AP6210_DEBUG("This scan is aborted\n"); -+ pbestnetheader->reason = (ENABLE << PNO_STATUS_ABORT); -+ } -+ pbestnet_entry->rtt0 = plnetinfo->rtt0; -+ pbestnet_entry->rtt1 = plnetinfo->rtt1; -+ pbestnet_entry->timestamp = plnetinfo->timestamp; -+ pbestnet_entry->SSID_len = plnetinfo->pfnsubnet.SSID_len; -+ memcpy(pbestnet_entry->SSID, plnetinfo->pfnsubnet.SSID, -+ pbestnet_entry->SSID_len); -+ memcpy(&pbestnet_entry->BSSID, &plnetinfo->pfnsubnet.BSSID, ETHER_ADDR_LEN); -+ /* add the element into list */ -+ list_add_tail(&pbestnet_entry->list, &pbestnetheader->entry_list); -+ /* increase best entry count */ -+ pbestnetheader->tot_cnt++; -+ pbestnetheader->tot_size += BESTNET_ENTRY_SIZE; -+ AP6210_DEBUG("Header %d\n", pscan_results->cnt_header - 1); -+ AP6210_DEBUG("\tSSID : "); -+ for (j = 0; j < plnetinfo->pfnsubnet.SSID_len; j++) -+ AP6210_DEBUG("%c", plnetinfo->pfnsubnet.SSID[j]); -+ AP6210_DEBUG("\n"); -+ AP6210_DEBUG("\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", -+ plnetinfo->pfnsubnet.BSSID.octet[0], -+ plnetinfo->pfnsubnet.BSSID.octet[1], -+ plnetinfo->pfnsubnet.BSSID.octet[2], -+ plnetinfo->pfnsubnet.BSSID.octet[3], -+ plnetinfo->pfnsubnet.BSSID.octet[4], -+ plnetinfo->pfnsubnet.BSSID.octet[5]); -+ AP6210_DEBUG("\tchannel: %d, RSSI: %d, timestamp: %d ms\n", -+ plnetinfo->pfnsubnet.channel, -+ plnetinfo->RSSI, plnetinfo->timestamp); -+ AP6210_DEBUG("\tRTT0 : %d, RTT1: %d\n", plnetinfo->rtt0, plnetinfo->rtt1); -+ plnetinfo++; -+ } -+ } -+ /* increase total scan count using current scan count */ -+ _params->params_batch.get_batch.tot_scan_cnt += pscan_results->cnt_header; -+ -+ if (buf && bufsize) { -+ /* This is a first try to get batching results */ -+ if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) { -+ /* move the scan_results_list to expired_scan_results_lists */ -+ list_for_each_entry_safe(siter, snext, -+ &_params->params_batch.get_batch.scan_results_list, list) { -+ list_move_tail(&siter->list, -+ &_params->params_batch.get_batch.expired_scan_results_list); -+ } -+ /* reset gloval values after moving to expired list */ -+ _params->params_batch.get_batch.top_node_cnt = 0; -+ _params->params_batch.get_batch.expired_tot_scan_cnt = -+ _params->params_batch.get_batch.tot_scan_cnt; -+ _params->params_batch.get_batch.tot_scan_cnt = 0; -+ } -+convert_format: -+ err = _dhd_pno_convert_format(dhd, &_params->params_batch, buf, bufsize); -+ if (err < 0) { -+ AP6210_ERR("failed to convert the data into upper layer format\n"); -+ goto exit; -+ } -+ } -+exit: -+ if (plbestnet) -+ MFREE(dhd->osh, plbestnet, PNO_BESTNET_LEN); -+ _params->params_batch.get_batch.buf = NULL; -+ _params->params_batch.get_batch.bufsize = 0; -+ mutex_unlock(&_pno_state->pno_mutex); -+ complete(&_pno_state->get_batch_done); -+ return err; -+} -+static void -+_dhd_pno_get_batch_handler(struct work_struct *work) -+{ -+ dhd_pno_status_info_t *_pno_state; -+ dhd_pub_t *dhd; -+ struct dhd_pno_batch_params *params_batch; -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ _pno_state = container_of(work, struct dhd_pno_status_info, work); -+ dhd = _pno_state->dhd; -+ if (dhd == NULL) { -+ AP6210_ERR("%s : dhd is NULL\n", __FUNCTION__); -+ return; -+ } -+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; -+ _dhd_pno_get_for_batch(dhd, params_batch->get_batch.buf, -+ params_batch->get_batch.bufsize, params_batch->get_batch.reason); -+ -+} -+ -+int -+dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) -+{ -+ int err = BCME_OK; -+ dhd_pno_status_info_t *_pno_state; -+ struct dhd_pno_batch_params *params_batch; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; -+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { -+ AP6210_ERR("%s: Batching SCAN mode is not enabled\n", __FUNCTION__); -+ goto exit; -+ } -+ params_batch->get_batch.buf = buf; -+ params_batch->get_batch.bufsize = bufsize; -+ params_batch->get_batch.reason = reason; -+ schedule_work(&_pno_state->work); -+ wait_for_completion(&_pno_state->get_batch_done); -+exit: -+ return err; -+} -+ -+int -+dhd_pno_stop_for_batch(dhd_pub_t *dhd) -+{ -+ int err = BCME_OK; -+ int mode = 0; -+ int i = 0; -+ dhd_pno_status_info_t *_pno_state; -+ dhd_pno_params_t *_params; -+ wl_pfn_bssid_t *p_pfn_bssid; -+ wlc_ssid_t *p_ssid_list = NULL; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", -+ __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { -+ AP6210_ERR("%s : PNO BATCH MODE is not enabled\n", __FUNCTION__); -+ goto exit; -+ } -+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; -+ if (_pno_state->pno_mode & (DHD_PNO_LEGACY_MODE | DHD_PNO_HOTLIST_MODE)) { -+ mode = _pno_state->pno_mode; -+ _dhd_pno_clean(dhd); -+ _pno_state->pno_mode = mode; -+ /* restart Legacy PNO if the Legacy PNO is on */ -+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { -+ struct dhd_pno_legacy_params *_params_legacy; -+ struct dhd_pno_ssid *iter, *next; -+ _params_legacy = -+ &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy); -+ p_ssid_list = kzalloc(sizeof(wlc_ssid_t) * -+ _params_legacy->nssid, GFP_KERNEL); -+ if (p_ssid_list == NULL) { -+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)", -+ __FUNCTION__, _params_legacy->nssid); -+ err = BCME_ERROR; -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ goto exit; -+ } -+ i = 0; -+ /* convert dhd_pno_ssid to dhd_pno_ssid */ -+ list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) { -+ p_ssid_list[i].SSID_len = iter->SSID_len; -+ memcpy(p_ssid_list[i].SSID, iter->SSID, p_ssid_list[i].SSID_len); -+ i++; -+ } -+ err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid, -+ _params_legacy->scan_fr, _params_legacy->pno_repeat, -+ _params_legacy->pno_freq_expo_max, _params_legacy->chan_list, -+ _params_legacy->nchan); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ AP6210_ERR("%s : failed to restart legacy PNO scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) { -+ struct dhd_pno_bssid *iter, *next; -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]); -+ p_pfn_bssid = kzalloc(sizeof(wl_pfn_bssid_t) * -+ _params->params_hotlist.nbssid, GFP_KERNEL); -+ if (p_pfn_bssid == NULL) { -+ AP6210_ERR("%s : failed to allocate wl_pfn_bssid_t array" -+ " (count: %d)", -+ __FUNCTION__, _params->params_hotlist.nbssid); -+ err = BCME_ERROR; -+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; -+ goto exit; -+ } -+ i = 0; -+ /* convert dhd_pno_bssid to wl_pfn_bssid */ -+ list_for_each_entry_safe(iter, next, -+ &_params->params_hotlist.bssid_list, list) { -+ memcpy(&p_pfn_bssid[i].macaddr, &iter->macaddr, ETHER_ADDR_LEN); -+ p_pfn_bssid[i].flags = iter->flags; -+ i++; -+ } -+ err = dhd_pno_set_for_hotlist(dhd, p_pfn_bssid, &_params->params_hotlist); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; -+ AP6210_ERR("%s : failed to restart hotlist scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ } else { -+ err = _dhd_pno_clean(dhd); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+exit: -+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; -+ _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE); -+ if (p_ssid_list) -+ kfree(p_ssid_list); -+ return err; -+} -+ -+int -+dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, -+ struct dhd_pno_hotlist_params *hotlist_params) -+{ -+ int err = BCME_OK; -+ int i; -+ uint16 _chan_list[WL_NUMCHANNELS]; -+ int rem_nchan = 0; -+ int tot_nchan = 0; -+ int mode = 0; -+ dhd_pno_params_t *_params; -+ dhd_pno_params_t *_params2; -+ struct dhd_pno_bssid *_pno_bssid; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ NULL_CHECK(hotlist_params, "hotlist_params is NULL", err); -+ NULL_CHECK(p_pfn_bssid, "p_pfn_bssid is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ -+ if (!dhd_support_sta_mode(dhd)) { -+ err = BCME_BADOPTION; -+ goto exit; -+ } -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ _params = &_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]; -+ if (!(_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE)) { -+ _pno_state->pno_mode |= DHD_PNO_HOTLIST_MODE; -+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_HOTLIST_MODE); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_reinitialize_prof\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } -+ _params->params_batch.nchan = hotlist_params->nchan; -+ _params->params_batch.scan_fr = hotlist_params->scan_fr; -+ if (hotlist_params->nchan) -+ memcpy(_params->params_hotlist.chan_list, hotlist_params->chan_list, -+ sizeof(_params->params_hotlist.chan_list)); -+ memset(_chan_list, 0, sizeof(_chan_list)); -+ -+ rem_nchan = ARRAYSIZE(hotlist_params->chan_list) - hotlist_params->nchan; -+ if (hotlist_params->band == WLC_BAND_2G || hotlist_params->band == WLC_BAND_5G) { -+ /* get a valid channel list based on band B or A */ -+ err = _dhd_pno_get_channels(dhd, -+ &_params->params_hotlist.chan_list[hotlist_params->nchan], -+ &rem_nchan, hotlist_params->band, FALSE); -+ if (err < 0) { -+ AP6210_ERR("%s: failed to get valid channel list(band : %d)\n", -+ __FUNCTION__, hotlist_params->band); -+ goto exit; -+ } -+ /* now we need to update nchan because rem_chan has valid channel count */ -+ _params->params_hotlist.nchan += rem_nchan; -+ /* need to sort channel list */ -+ sort(_params->params_hotlist.chan_list, _params->params_hotlist.nchan, -+ sizeof(_params->params_hotlist.chan_list[0]), _dhd_pno_cmpfunc, NULL); -+ } -+#ifdef PNO_DEBUG -+{ -+ int i; -+ AP6210_DEBUG("Channel list : "); -+ for (i = 0; i < _params->params_batch.nchan; i++) { -+ AP6210_DEBUG("%d ", _params->params_batch.chan_list[i]); -+ } -+ AP6210_DEBUG("\n"); -+} -+#endif -+ if (_params->params_hotlist.nchan) { -+ /* copy the channel list into local array */ -+ memcpy(_chan_list, _params->params_hotlist.chan_list, -+ sizeof(_chan_list)); -+ tot_nchan = _params->params_hotlist.nchan; -+ } -+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { -+ AP6210_DEBUG("PNO SSID is on progress in firmware\n"); -+ /* store current pno_mode before disabling pno */ -+ mode = _pno_state->pno_mode; -+ err = _dhd_pno_enable(dhd, PNO_OFF); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__); -+ goto exit; -+ } -+ /* restore the previous mode */ -+ _pno_state->pno_mode = mode; -+ /* Use the superset for channelist between two mode */ -+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); -+ if (_params2->params_legacy.nchan > 0 && -+ _params->params_hotlist.nchan > 0) { -+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan, -+ &_params2->params_legacy.chan_list[0], -+ _params2->params_legacy.nchan, -+ &_params->params_hotlist.chan_list[0], -+ _params->params_hotlist.nchan); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to merge channel list" -+ "between legacy and hotlist\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ } -+ -+ } -+ -+ INIT_LIST_HEAD(&(_params->params_hotlist.bssid_list)); -+ -+ err = _dhd_pno_add_bssid(dhd, p_pfn_bssid, hotlist_params->nbssid); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_add_bssid(err :%d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_HOTLIST_MODE)) < 0) { -+ AP6210_ERR("%s : failed to set call pno_set (err %d) in firmware\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ if (tot_nchan > 0) { -+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) { -+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ for (i = 0; i < hotlist_params->nbssid; i++) { -+ _pno_bssid = kzalloc(sizeof(struct dhd_pno_bssid), GFP_KERNEL); -+ NULL_CHECK(_pno_bssid, "_pfn_bssid is NULL", err); -+ memcpy(&_pno_bssid->macaddr, &p_pfn_bssid[i].macaddr, ETHER_ADDR_LEN); -+ _pno_bssid->flags = p_pfn_bssid[i].flags; -+ list_add_tail(&_pno_bssid->list, &_params->params_hotlist.bssid_list); -+ } -+ _params->params_hotlist.nbssid = hotlist_params->nbssid; -+ if (_pno_state->pno_status == DHD_PNO_DISABLED) { -+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0) -+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__); -+ } -+exit: -+ /* clear mode in case of error */ -+ if (err < 0) -+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE; -+ return err; -+} -+ -+int -+dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) -+{ -+ int err = BCME_OK; -+ uint32 mode = 0; -+ dhd_pno_status_info_t *_pno_state; -+ dhd_pno_params_t *_params; -+ wlc_ssid_t *p_ssid_list; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", -+ __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ -+ if (!(_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE)) { -+ AP6210_ERR("%s : Hotlist MODE is not enabled\n", -+ __FUNCTION__); -+ goto exit; -+ } -+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; -+ -+ if (_pno_state->pno_mode & (DHD_PNO_LEGACY_MODE | DHD_PNO_BATCH_MODE)) { -+ /* retrieve the batching data from firmware into host */ -+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); -+ /* save current pno_mode before calling dhd_pno_clean */ -+ mode = _pno_state->pno_mode; -+ err = _dhd_pno_clean(dhd); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ /* restore previos pno mode */ -+ _pno_state->pno_mode = mode; -+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { -+ /* restart Legacy PNO Scan */ -+ struct dhd_pno_legacy_params *_params_legacy; -+ struct dhd_pno_ssid *iter, *next; -+ _params_legacy = -+ &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy); -+ p_ssid_list = -+ kzalloc(sizeof(wlc_ssid_t) * _params_legacy->nssid, GFP_KERNEL); -+ if (p_ssid_list == NULL) { -+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)", -+ __FUNCTION__, _params_legacy->nssid); -+ err = BCME_ERROR; -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ goto exit; -+ } -+ /* convert dhd_pno_ssid to dhd_pno_ssid */ -+ list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) { -+ p_ssid_list->SSID_len = iter->SSID_len; -+ memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list->SSID_len); -+ p_ssid_list++; -+ } -+ err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid, -+ _params_legacy->scan_fr, _params_legacy->pno_repeat, -+ _params_legacy->pno_freq_expo_max, _params_legacy->chan_list, -+ _params_legacy->nchan); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE; -+ AP6210_ERR("%s : failed to restart legacy PNO scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } else if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { -+ /* restart Batching Scan */ -+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]); -+ /* restart BATCH SCAN */ -+ err = dhd_pno_set_for_batch(dhd, &_params->params_batch); -+ if (err < 0) { -+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; -+ AP6210_ERR("%s : failed to restart batch scan(err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+ } else { -+ err = _dhd_pno_clean(dhd); -+ if (err < 0) { -+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n", -+ __FUNCTION__, err); -+ goto exit; -+ } -+ } -+exit: -+ return err; -+} -+ -+int -+dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data) -+{ -+ int err = BCME_OK; -+ uint status, event_type, flags, datalen; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ if (!WLS_SUPPORTED(_pno_state)) { -+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__); -+ err = BCME_UNSUPPORTED; -+ goto exit; -+ } -+ event_type = ntoh32(event->event_type); -+ flags = ntoh16(event->flags); -+ status = ntoh32(event->status); -+ datalen = ntoh32(event->datalen); -+ AP6210_DEBUG("%s enter : event_type :%d\n", __FUNCTION__, event_type); -+ switch (event_type) { -+ case WLC_E_PFN_BSSID_NET_FOUND: -+ case WLC_E_PFN_BSSID_NET_LOST: -+ /* XXX : how can we inform this to framework ? */ -+ /* TODO : need to implement event logic using generic netlink */ -+ break; -+ case WLC_E_PFN_BEST_BATCHING: -+ { -+ struct dhd_pno_batch_params *params_batch; -+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; -+ AP6210_DEBUG("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__); -+ params_batch->get_batch.buf = NULL; -+ params_batch->get_batch.bufsize = 0; -+ params_batch->get_batch.reason = PNO_STATUS_EVENT; -+ schedule_work(&_pno_state->work); -+ break; -+ } -+ default: -+ AP6210_ERR("unknown event : %d\n", event_type); -+ } -+exit: -+ return err; -+} -+ -+int dhd_pno_init(dhd_pub_t *dhd) -+{ -+ int err = BCME_OK; -+ dhd_pno_status_info_t *_pno_state; -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ UNUSED_PARAMETER(_dhd_pno_suspend); -+ if (dhd->pno_state) -+ goto exit; -+ dhd->pno_state = MALLOC(dhd->osh, sizeof(dhd_pno_status_info_t)); -+ memset(dhd->pno_state, 0, sizeof(dhd_pno_status_info_t)); -+ NULL_CHECK(dhd, "failed to create dhd_pno_state", err); -+ /* need to check whether current firmware support batching and hotlist scan */ -+ _pno_state = PNO_GET_PNOSTATE(dhd); -+ _pno_state->wls_supported = TRUE; -+ _pno_state->dhd = dhd; -+ mutex_init(&_pno_state->pno_mutex); -+ INIT_WORK(&_pno_state->work, _dhd_pno_get_batch_handler); -+ init_completion(&_pno_state->get_batch_done); -+ err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, 0); -+ if (err == BCME_UNSUPPORTED) { -+ _pno_state->wls_supported = FALSE; -+ AP6210_DEBUG("Current firmware doesn't support" -+ " Android Location Service\n"); -+ } -+exit: -+ return err; -+} -+int dhd_pno_deinit(dhd_pub_t *dhd) -+{ -+ int err = BCME_OK; -+ dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); -+ NULL_CHECK(dhd, "dhd is NULL", err); -+ AP6210_DEBUG("%s enter\n", __FUNCTION__); -+ cancel_work_sync(&_pno_state->work); -+ if (dhd->pno_state) -+ MFREE(dhd->osh, dhd->pno_state, sizeof(dhd_pno_status_info_t)); -+ dhd->pno_state = NULL; -+ return err; -+} -diff --git a/drivers/net/wireless/ap6210/dhd_pno.h b/drivers/net/wireless/ap6210/dhd_pno.h -new file mode 100644 -index 0000000..1e02db1 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_pno.h -@@ -0,0 +1,249 @@ -+/* -+ * Header file of Broadcom Dongle Host Driver (DHD) -+ * Prefered Network Offload code and Wi-Fi Location Service(WLS) code. -+ * Copyright (C) 1999-2013, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_pno.h 419969 2013-08-23 18:54:36Z $ -+ */ -+ -+#ifndef __DHD_PNO_H__ -+#define __DHD_PNO_H__ -+ -+#define PNO_TLV_PREFIX 'S' -+#define PNO_TLV_VERSION '1' -+#define PNO_TLV_SUBTYPE_LEGACY_PNO '2' -+#define PNO_TLV_RESERVED '0' -+ -+#define PNO_BATCHING_SET "SET" -+#define PNO_BATCHING_GET "GET" -+#define PNO_BATCHING_STOP "STOP" -+ -+#define PNO_PARAMS_DELIMETER " " -+#define PNO_PARAM_CHANNEL_DELIMETER "," -+#define PNO_PARAM_VALUE_DELLIMETER '=' -+#define PNO_PARAM_SCANFREQ "SCANFREQ" -+#define PNO_PARAM_BESTN "BESTN" -+#define PNO_PARAM_MSCAN "MSCAN" -+#define PNO_PARAM_CHANNEL "CHANNEL" -+#define PNO_PARAM_RTT "RTT" -+ -+#define PNO_TLV_TYPE_SSID_IE 'S' -+#define PNO_TLV_TYPE_TIME 'T' -+#define PNO_TLV_FREQ_REPEAT 'R' -+#define PNO_TLV_FREQ_EXPO_MAX 'M' -+ -+#define MAXNUM_SSID_PER_ADD 16 -+#define MAXNUM_PNO_PARAMS 2 -+#define PNO_TLV_COMMON_LENGTH 1 -+#define DEFAULT_BATCH_MSCAN 16 -+ -+#define RESULTS_END_MARKER "----\n" -+#define SCAN_END_MARKER "####\n" -+#define AP_END_MARKER "====\n" -+ -+enum scan_status { -+ /* SCAN ABORT by other scan */ -+ PNO_STATUS_ABORT, -+ /* RTT is presence or not */ -+ PNO_STATUS_RTT_PRESENCE, -+ /* Disable PNO by Driver */ -+ PNO_STATUS_DISABLE, -+ /* NORMAL BATCHING GET */ -+ PNO_STATUS_NORMAL, -+ /* WLC_E_PFN_BEST_BATCHING */ -+ PNO_STATUS_EVENT, -+ PNO_STATUS_MAX -+}; -+#define PNO_STATUS_ABORT_MASK 0x0001 -+#define PNO_STATUS_RTT_MASK 0x0002 -+#define PNO_STATUS_DISABLE_MASK 0x0004 -+#define PNO_STATUS_OOM_MASK 0x0010 -+ -+enum index_mode { -+ INDEX_OF_LEGACY_PARAMS, -+ INDEX_OF_BATCH_PARAMS, -+ INDEX_OF_HOTLIST_PARAMS, -+ INDEX_MODE_MAX -+}; -+enum dhd_pno_status { -+ DHD_PNO_DISABLED, -+ DHD_PNO_ENABLED, -+ DHD_PNO_SUSPEND -+}; -+typedef struct cmd_tlv { -+ char prefix; -+ char version; -+ char subtype; -+ char reserved; -+} cmd_tlv_t; -+typedef enum dhd_pno_mode { -+ /* Wi-Fi Legacy PNO Mode */ -+ DHD_PNO_NONE_MODE = 0, -+ DHD_PNO_LEGACY_MODE = (1 << (0)), -+ /* Wi-Fi Android BATCH SCAN Mode */ -+ DHD_PNO_BATCH_MODE = (1 << (1)), -+ /* Wi-Fi Android Hotlist SCAN Mode */ -+ DHD_PNO_HOTLIST_MODE = (1 << (2)) -+} dhd_pno_mode_t; -+struct dhd_pno_ssid { -+ uint32 SSID_len; -+ uchar SSID[DOT11_MAX_SSID_LEN]; -+ struct list_head list; -+}; -+struct dhd_pno_bssid { -+ struct ether_addr macaddr; -+ /* Bit4: suppress_lost, Bit3: suppress_found */ -+ uint16 flags; -+ struct list_head list; -+}; -+typedef struct dhd_pno_bestnet_entry { -+ struct ether_addr BSSID; -+ uint8 SSID_len; -+ uint8 SSID[DOT11_MAX_SSID_LEN]; -+ int8 RSSI; -+ uint8 channel; -+ uint32 timestamp; -+ uint16 rtt0; /* distance_cm based on RTT */ -+ uint16 rtt1; /* distance_cm based on sample standard deviation */ -+ unsigned long recorded_time; -+ struct list_head list; -+} dhd_pno_bestnet_entry_t; -+#define BESTNET_ENTRY_SIZE (sizeof(dhd_pno_bestnet_entry_t)) -+ -+typedef struct dhd_pno_bestnet_header { -+ struct dhd_pno_bestnet_header *next; -+ uint8 reason; -+ uint32 tot_cnt; -+ uint32 tot_size; -+ struct list_head entry_list; -+} dhd_pno_best_header_t; -+#define BEST_HEADER_SIZE (sizeof(dhd_pno_best_header_t)) -+ -+typedef struct dhd_pno_scan_results { -+ dhd_pno_best_header_t *bestnetheader; -+ uint8 cnt_header; -+ struct list_head list; -+} dhd_pno_scan_results_t; -+#define SCAN_RESULTS_SIZE (sizeof(dhd_pno_scan_results_t)) -+ -+struct dhd_pno_get_batch_info { -+ /* info related to get batch */ -+ char *buf; -+ bool batch_started; -+ uint32 tot_scan_cnt; -+ uint32 expired_tot_scan_cnt; -+ uint32 top_node_cnt; -+ uint32 bufsize; -+ int reason; -+ struct list_head scan_results_list; -+ struct list_head expired_scan_results_list; -+}; -+struct dhd_pno_legacy_params { -+ uint16 scan_fr; -+ uint16 chan_list[WL_NUMCHANNELS]; -+ uint16 nchan; -+ int pno_repeat; -+ int pno_freq_expo_max; -+ int nssid; -+ struct list_head ssid_list; -+}; -+struct dhd_pno_batch_params { -+ int32 scan_fr; -+ uint8 bestn; -+ uint8 mscan; -+ uint8 band; -+ uint16 chan_list[WL_NUMCHANNELS]; -+ uint16 nchan; -+ uint16 rtt; -+ struct dhd_pno_get_batch_info get_batch; -+}; -+struct dhd_pno_hotlist_params { -+ uint8 band; -+ int32 scan_fr; -+ uint16 chan_list[WL_NUMCHANNELS]; -+ uint16 nchan; -+ uint16 nbssid; -+ struct list_head bssid_list; -+}; -+typedef union dhd_pno_params { -+ struct dhd_pno_legacy_params params_legacy; -+ struct dhd_pno_batch_params params_batch; -+ struct dhd_pno_hotlist_params params_hotlist; -+} dhd_pno_params_t; -+typedef struct dhd_pno_status_info { -+ dhd_pub_t *dhd; -+ struct work_struct work; -+ struct mutex pno_mutex; -+ struct completion get_batch_done; -+ bool wls_supported; /* wifi location service supported or not */ -+ enum dhd_pno_status pno_status; -+ enum dhd_pno_mode pno_mode; -+ dhd_pno_params_t pno_params_arr[INDEX_MODE_MAX]; -+ struct list_head head_list; -+} dhd_pno_status_info_t; -+ -+/* wrapper functions */ -+extern int -+dhd_dev_pno_enable(struct net_device *dev, int enable); -+ -+extern int -+dhd_dev_pno_stop_for_ssid(struct net_device *dev); -+ -+extern int -+dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, -+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan); -+ -+extern int -+dhd_dev_pno_set_for_batch(struct net_device *dev, -+ struct dhd_pno_batch_params *batch_params); -+ -+extern int -+dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize); -+ -+extern int -+dhd_dev_pno_stop_for_batch(struct net_device *dev); -+ -+extern int -+dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid, -+ struct dhd_pno_hotlist_params *hotlist_params); -+ -+/* dhd pno fuctions */ -+extern int dhd_pno_stop_for_ssid(dhd_pub_t *dhd); -+extern int dhd_pno_enable(dhd_pub_t *dhd, int enable); -+extern int dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid, -+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan); -+ -+extern int dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params); -+ -+extern int dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason); -+ -+ -+extern int dhd_pno_stop_for_batch(dhd_pub_t *dhd); -+ -+extern int dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, -+ struct dhd_pno_hotlist_params *hotlist_params); -+ -+extern int dhd_pno_stop_for_hotlist(dhd_pub_t *dhd); -+ -+extern int dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data); -+extern int dhd_pno_init(dhd_pub_t *dhd); -+extern int dhd_pno_deinit(dhd_pub_t *dhd); -+#endif /* __DHD_PNO_H__ */ -diff --git a/drivers/net/wireless/ap6210/dhd_proto.h b/drivers/net/wireless/ap6210/dhd_proto.h -new file mode 100644 -index 0000000..09d5468 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_proto.h -@@ -0,0 +1,113 @@ -+/* -+ * Header file describing the internal (inter-module) DHD interfaces. -+ * -+ * Provides type definitions and function prototypes used to link the -+ * DHD OS, bus, and protocol modules. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_proto.h 343390 2012-07-06 22:34:19Z $ -+ */ -+ -+#ifndef _dhd_proto_h_ -+#define _dhd_proto_h_ -+ -+#include -+#include -+ -+#ifndef IOCTL_RESP_TIMEOUT -+#define IOCTL_RESP_TIMEOUT 2000 /* In milli second default value for Production FW */ -+#endif /* IOCTL_RESP_TIMEOUT */ -+ -+/* -+ * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) -+ */ -+ -+/* Linkage, sets prot link and updates hdrlen in pub */ -+extern int dhd_prot_attach(dhd_pub_t *dhdp); -+ -+/* Unlink, frees allocated protocol memory (including dhd_prot) */ -+extern void dhd_prot_detach(dhd_pub_t *dhdp); -+ -+/* Initialize protocol: sync w/dongle state. -+ * Sets dongle media info (iswl, drv_version, mac address). -+ */ -+extern int dhd_prot_init(dhd_pub_t *dhdp); -+ -+/* Stop protocol: sync w/dongle state. */ -+extern void dhd_prot_stop(dhd_pub_t *dhdp); -+#ifdef PROP_TXSTATUS -+extern int dhd_wlfc_init(dhd_pub_t *dhd); -+extern void dhd_wlfc_deinit(dhd_pub_t *dhd); -+#endif /* PROP_TXSTATUS */ -+ -+/* Add any protocol-specific data header. -+ * Caller must reserve prot_hdrlen prepend space. -+ */ -+extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); -+ -+/* Remove any protocol-specific data header. */ -+extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp, uchar *buf, uint *len); -+ -+/* Use protocol to issue ioctl to dongle */ -+extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len); -+ -+/* Handles a protocol control response asynchronously */ -+extern int dhd_prot_ctl_complete(dhd_pub_t *dhd); -+ -+/* Check for and handle local prot-specific iovar commands */ -+extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, -+ void *params, int plen, void *arg, int len, bool set); -+ -+/* Add prot dump output to a buffer */ -+extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); -+ -+/* Update local copy of dongle statistics */ -+extern void dhd_prot_dstats(dhd_pub_t *dhdp); -+ -+extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen); -+ -+extern int dhd_preinit_ioctls(dhd_pub_t *dhd); -+ -+#ifdef PROP_TXSTATUS -+extern int dhd_wlfc_enque_sendq(void* state, int prec, void* p); -+extern int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx); -+extern void dhd_wlfc_cleanup(dhd_pub_t *dhd); -+#endif /* PROP_TXSTATUS */ -+ -+extern int dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, -+ uint reorder_info_len, void **pkt, uint32 *free_buf_count); -+ -+ -+/******************************** -+ * For version-string expansion * -+ */ -+#if defined(BDC) -+#define DHD_PROTOCOL "bdc" -+#elif defined(CDC) -+#define DHD_PROTOCOL "cdc" -+#elif defined(RNDIS) -+#define DHD_PROTOCOL "rndis" -+#else -+#define DHD_PROTOCOL "unknown" -+#endif /* proto */ -+ -+#endif /* _dhd_proto_h_ */ -diff --git a/drivers/net/wireless/ap6210/dhd_sdio.c b/drivers/net/wireless/ap6210/dhd_sdio.c -new file mode 100644 -index 0000000..786f287 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_sdio.c -@@ -0,0 +1,7856 @@ -+/* -+ * DHD Bus Module for SDIO -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_sdio.c 373330 2012-12-07 04:46:17Z $ -+ */ -+ -+#include -+#include -+#include -+ -+#ifdef BCMEMBEDIMAGE -+#include BCMEMBEDIMAGE -+#endif /* BCMEMBEDIMAGE */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#if defined(DHD_DEBUG) -+#include -+#include -+#endif /* defined(DHD_DEBUG) */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#ifndef DHDSDIO_MEM_DUMP_FNAME -+#define DHDSDIO_MEM_DUMP_FNAME "mem_dump" -+#endif -+ -+#define QLEN 256 /* bulk rx and tx queue lengths */ -+#define FCHI (QLEN - 10) -+#define FCLOW (FCHI / 2) -+#define PRIOMASK 7 -+ -+#define TXRETRIES 2 /* # of retries for tx frames */ -+ -+#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */ -+ -+#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */ -+ -+#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ -+ -+#define MEMBLOCK 2048 /* Block size used for downloading of dongle image */ -+#define MAX_NVRAMBUF_SIZE 4096 /* max nvram buf size */ -+#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ -+ -+#ifndef DHD_FIRSTREAD -+#define DHD_FIRSTREAD 32 -+#endif -+#if !ISPOWEROF2(DHD_FIRSTREAD) -+#error DHD_FIRSTREAD is not a power of 2! -+#endif -+ -+#ifdef BCMSDIOH_TXGLOM -+/* Total length of TX frame header for dongle protocol */ -+#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN + SDPCM_SWHEADER_LEN) -+/* Total length of RX frame for dongle protocol */ -+#else -+/* Total length of TX frame header for dongle protocol */ -+#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -+#endif -+ -+#define SDPCM_HDRLEN_RX (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -+ -+#ifdef SDTEST -+#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN) -+#else -+#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN) -+#endif -+ -+/* Space for header read, limit for data packets */ -+#ifndef MAX_HDR_READ -+#define MAX_HDR_READ 32 -+#endif -+#if !ISPOWEROF2(MAX_HDR_READ) -+#error MAX_HDR_READ is not a power of 2! -+#endif -+ -+#define MAX_RX_DATASZ 2048 -+ -+/* Maximum milliseconds to wait for F2 to come up */ -+#define DHD_WAIT_F2RDY 3000 -+ -+/* Bump up limit on waiting for HT to account for first startup; -+ * if the image is doing a CRC calculation before programming the PMU -+ * for HT availability, it could take a couple hundred ms more, so -+ * max out at a 1 second (1000000us). -+ */ -+#if (PMU_MAX_TRANSITION_DLY <= 1000000) -+#undef PMU_MAX_TRANSITION_DLY -+#define PMU_MAX_TRANSITION_DLY 1000000 -+#endif -+ -+/* Value for ChipClockCSR during initial setup */ -+#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ) -+#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP) -+ -+/* Flags for SDH calls */ -+#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) -+ -+/* Packet free applicable unconditionally for sdio and sdspi. Conditional if -+ * bufpool was present for gspi bus. -+ */ -+#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -+#if defined(OOB_INTR_ONLY) -+extern void bcmsdh_set_irq(int flag); -+#endif -+#ifdef PROP_TXSTATUS -+extern void dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wlfc_locked); -+extern void dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd); -+#endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+DEFINE_MUTEX(_dhd_sdio_mutex_lock_); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -+ -+#ifdef DHD_DEBUG -+/* Device console log buffer state */ -+#define CONSOLE_LINE_MAX 192 -+#define CONSOLE_BUFFER_MAX 2024 -+typedef struct dhd_console { -+ uint count; /* Poll interval msec counter */ -+ uint log_addr; /* Log struct address (fixed) */ -+ hndrte_log_t log; /* Log struct (host copy) */ -+ uint bufsize; /* Size of log buffer */ -+ uint8 *buf; /* Log buffer (host copy) */ -+ uint last; /* Last buffer read index */ -+} dhd_console_t; -+#endif /* DHD_DEBUG */ -+ -+#define REMAP_ENAB(bus) ((bus)->remap) -+#define REMAP_ISADDR(bus, a) (((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize))) -+#define KSO_ENAB(bus) ((bus)->kso) -+#define SR_ENAB(bus) ((bus)->_srenab) -+#define SLPAUTO_ENAB(bus) ((SR_ENAB(bus)) && ((bus)->_slpauto)) -+#define MIN_RSRC_ADDR (SI_ENUM_BASE + 0x618) -+#define MIN_RSRC_SR 0x3 -+#define CORE_CAPEXT_ADDR (SI_ENUM_BASE + 0x64c) -+#define CORE_CAPEXT_SR_SUPPORTED_MASK (1 << 1) -+#define RCTL_MACPHY_DISABLE_MASK (1 << 26) -+#define RCTL_LOGIC_DISABLE_MASK (1 << 27) -+ -+#define OOB_WAKEUP_ENAB(bus) ((bus)->_oobwakeup) -+#define GPIO_DEV_SRSTATE 16 /* Host gpio17 mapped to device gpio0 SR state */ -+#define GPIO_DEV_SRSTATE_TIMEOUT 320000 /* 320ms */ -+#define GPIO_DEV_WAKEUP 17 /* Host gpio17 mapped to device gpio1 wakeup */ -+#define CC_CHIPCTRL2_GPIO1_WAKEUP (1 << 0) -+ -+#define CC_PMUCC3 (0x3) -+/* Private data for SDIO bus interaction */ -+typedef struct dhd_bus { -+ dhd_pub_t *dhd; -+ -+ bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ -+ si_t *sih; /* Handle for SI calls */ -+ char *vars; /* Variables (from CIS and/or other) */ -+ uint varsz; /* Size of variables buffer */ -+ uint32 sbaddr; /* Current SB window pointer (-1, invalid) */ -+ -+ sdpcmd_regs_t *regs; /* Registers for SDIO core */ -+ uint sdpcmrev; /* SDIO core revision */ -+ uint armrev; /* CPU core revision */ -+ uint ramrev; /* SOCRAM core revision */ -+ uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */ -+ uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ -+ uint32 srmemsize; /* Size of SRMEM */ -+ -+ uint32 bus; /* gSPI or SDIO bus */ -+ uint32 hostintmask; /* Copy of Host Interrupt Mask */ -+ uint32 intstatus; /* Intstatus bits (events) pending */ -+ bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ -+ bool fcstate; /* State of dongle flow-control */ -+ -+ uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ -+ char *fw_path; /* module_param: path to firmware image */ -+ char *nv_path; /* module_param: path to nvram vars file */ -+ const char *nvram_params; /* user specified nvram params. */ -+ -+ uint blocksize; /* Block size of SDIO transfers */ -+ uint roundup; /* Max roundup limit */ -+ -+ struct pktq txq; /* Queue length used for flow-control */ -+ uint8 flowcontrol; /* per prio flow control bitmask */ -+ uint8 tx_seq; /* Transmit sequence number (next) */ -+ uint8 tx_max; /* Maximum transmit sequence allowed */ -+ -+ uint8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN]; -+ uint8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ -+ uint16 nextlen; /* Next Read Len from last header */ -+ uint8 rx_seq; /* Receive sequence number (expected) */ -+ bool rxskip; /* Skip receive (awaiting NAK ACK) */ -+ -+ void *glomd; /* Packet containing glomming descriptor */ -+ void *glom; /* Packet chain for glommed superframe */ -+ uint glomerr; /* Glom packet read errors */ -+ -+ uint8 *rxbuf; /* Buffer for receiving control packets */ -+ uint rxblen; /* Allocated length of rxbuf */ -+ uint8 *rxctl; /* Aligned pointer into rxbuf */ -+ uint8 *databuf; /* Buffer for receiving big glom packet */ -+ uint8 *dataptr; /* Aligned pointer into databuf */ -+ uint rxlen; /* Length of valid data in buffer */ -+ -+ uint8 sdpcm_ver; /* Bus protocol reported by dongle */ -+ -+ bool intr; /* Use interrupts */ -+ bool poll; /* Use polling */ -+ bool ipend; /* Device interrupt is pending */ -+ bool intdis; /* Interrupts disabled by isr */ -+ uint intrcount; /* Count of device interrupt callbacks */ -+ uint lastintrs; /* Count as of last watchdog timer */ -+ uint spurious; /* Count of spurious interrupts */ -+ uint pollrate; /* Ticks between device polls */ -+ uint polltick; /* Tick counter */ -+ uint pollcnt; /* Count of active polls */ -+ -+#ifdef DHD_DEBUG -+ dhd_console_t console; /* Console output polling support */ -+ uint console_addr; /* Console address from shared struct */ -+#endif /* DHD_DEBUG */ -+ -+ uint regfails; /* Count of R_REG/W_REG failures */ -+ -+ uint clkstate; /* State of sd and backplane clock(s) */ -+ bool activity; /* Activity flag for clock down */ -+ int32 idletime; /* Control for activity timeout */ -+ int32 idlecount; /* Activity timeout counter */ -+ int32 idleclock; /* How to set bus driver when idle */ -+ int32 sd_divisor; /* Speed control to bus driver */ -+ int32 sd_mode; /* Mode control to bus driver */ -+ int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ -+ bool use_rxchain; /* If dhd should use PKT chains */ -+ bool sleeping; /* Is SDIO bus sleeping? */ -+ uint rxflow_mode; /* Rx flow control mode */ -+ bool rxflow; /* Is rx flow control on */ -+ uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */ -+ bool alp_only; /* Don't use HT clock (ALP only) */ -+ /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ -+ bool usebufpool; -+ -+#ifdef SDTEST -+ /* external loopback */ -+ bool ext_loop; -+ uint8 loopid; -+ -+ /* pktgen configuration */ -+ uint pktgen_freq; /* Ticks between bursts */ -+ uint pktgen_count; /* Packets to send each burst */ -+ uint pktgen_print; /* Bursts between count displays */ -+ uint pktgen_total; /* Stop after this many */ -+ uint pktgen_minlen; /* Minimum packet data len */ -+ uint pktgen_maxlen; /* Maximum packet data len */ -+ uint pktgen_mode; /* Configured mode: tx, rx, or echo */ -+ uint pktgen_stop; /* Number of tx failures causing stop */ -+ -+ /* active pktgen fields */ -+ uint pktgen_tick; /* Tick counter for bursts */ -+ uint pktgen_ptick; /* Burst counter for printing */ -+ uint pktgen_sent; /* Number of test packets generated */ -+ uint pktgen_rcvd; /* Number of test packets received */ -+ uint pktgen_prev_time; /* Time at which previous stats where printed */ -+ uint pktgen_prev_sent; /* Number of test packets generated when -+ * previous stats were printed -+ */ -+ uint pktgen_prev_rcvd; /* Number of test packets received when -+ * previous stats were printed -+ */ -+ uint pktgen_fail; /* Number of failed send attempts */ -+ uint16 pktgen_len; /* Length of next packet to send */ -+#define PKTGEN_RCV_IDLE (0) -+#define PKTGEN_RCV_ONGOING (1) -+ uint16 pktgen_rcv_state; /* receive state */ -+ uint pktgen_rcvd_rcvsession; /* test pkts rcvd per rcv session. */ -+#endif /* SDTEST */ -+ -+ /* Some additional counters */ -+ uint tx_sderrs; /* Count of tx attempts with sd errors */ -+ uint fcqueued; /* Tx packets that got queued */ -+ uint rxrtx; /* Count of rtx requests (NAK to dongle) */ -+ uint rx_toolong; /* Receive frames too long to receive */ -+ uint rxc_errors; /* SDIO errors when reading control frames */ -+ uint rx_hdrfail; /* SDIO errors on header reads */ -+ uint rx_badhdr; /* Bad received headers (roosync?) */ -+ uint rx_badseq; /* Mismatched rx sequence number */ -+ uint fc_rcvd; /* Number of flow-control events received */ -+ uint fc_xoff; /* Number which turned on flow-control */ -+ uint fc_xon; /* Number which turned off flow-control */ -+ uint rxglomfail; /* Failed deglom attempts */ -+ uint rxglomframes; /* Number of glom frames (superframes) */ -+ uint rxglompkts; /* Number of packets from glom frames */ -+ uint f2rxhdrs; /* Number of header reads */ -+ uint f2rxdata; /* Number of frame data reads */ -+ uint f2txdata; /* Number of f2 frame writes */ -+ uint f1regdata; /* Number of f1 register accesses */ -+ -+ uint8 *ctrl_frame_buf; -+ uint32 ctrl_frame_len; -+ bool ctrl_frame_stat; -+ uint32 rxint_mode; /* rx interrupt mode */ -+ bool remap; /* Contiguous 1MB RAM: 512K socram + 512K devram -+ * Available with socram rev 16 -+ * Remap region not DMA-able -+ */ -+ bool kso; -+ bool _slpauto; -+ bool _oobwakeup; -+ bool _srenab; -+ bool readframes; -+ bool reqbussleep; -+ uint32 resetinstr; -+ uint32 dongle_ram_base; -+#ifdef BCMSDIOH_TXGLOM -+ void *glom_pkt_arr[SDPCM_MAXGLOM_SIZE]; /* Array of pkts for glomming */ -+ uint16 glom_cnt; /* Number of pkts in the glom array */ -+ uint16 glom_total_len; /* Total length of pkts in glom array */ -+ bool glom_enable; /* Flag to indicate whether tx glom is enabled/disabled */ -+ uint8 glom_mode; /* Glom mode - 0-copy mode, 1 - Multi-descriptor mode */ -+ uint32 glomsize; /* Glom size limitation */ -+#endif -+} dhd_bus_t; -+ -+/* clkstate */ -+#define CLK_NONE 0 -+#define CLK_SDONLY 1 -+#define CLK_PENDING 2 /* Not used yet */ -+#define CLK_AVAIL 3 -+ -+#define DHD_NOPMU(dhd) (FALSE) -+ -+#ifdef DHD_DEBUG -+static int qcount[NUMPRIO]; -+static int tx_packets[NUMPRIO]; -+#endif /* DHD_DEBUG */ -+ -+/* Deferred transmit */ -+const uint dhd_deferred_tx = 1; -+ -+extern uint dhd_watchdog_ms; -+extern void dhd_os_wd_timer(void *bus, uint wdtick); -+ -+/* Tx/Rx bounds */ -+uint dhd_txbound; -+uint dhd_rxbound; -+uint dhd_txminmax = DHD_TXMINMAX; -+ -+/* override the RAM size if possible */ -+#define DONGLE_MIN_MEMSIZE (128 *1024) -+int dhd_dongle_memsize; -+ -+static bool dhd_doflow; -+static bool dhd_alignctl; -+ -+static bool sd1idle; -+ -+static bool retrydata; -+#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) -+ -+#if defined(SDIO_CRC_ERROR_FIX) -+static uint watermark = 48; -+static uint mesbusyctrl = 80; -+#else -+static const uint watermark = 8; -+static const uint mesbusyctrl = 0; -+#endif -+static const uint firstread = DHD_FIRSTREAD; -+ -+#define HDATLEN (firstread - (SDPCM_HDRLEN)) -+ -+/* Retry count for register access failures */ -+static const uint retry_limit = 2; -+ -+/* Force even SD lengths (some host controllers mess up on odd bytes) */ -+static bool forcealign; -+ -+#define FW_TYPE_STA 0 -+#define FW_TYPE_APSTA 1 -+#define FW_TYPE_P2P 2 -+#define FW_TYPE_MFG 3 -+#define FW_TYPE_G 0 -+#define FW_TYPE_AG 1 -+ -+const static char *bcm40183b2_fw_name[] = { -+ "fw_bcm40183b2.bin", -+ "fw_bcm40183b2_apsta.bin", -+ "fw_bcm40183b2_p2p.bin", -+ "fw_bcm40183b2_mfg.bin" -+}; -+ -+const static char *bcm40183b2ag_fw_name[] = { -+ "fw_bcm40183b2_ag.bin", -+ "fw_bcm40183b2_ag_apsta.bin", -+ "fw_bcm40183b2_ag_p2p.bin", -+ "fw_bcm40183b2_ag_mfg.bin" -+}; -+ -+const static char *bcm40181a0_fw_name[] = { -+ "fw_bcm40181a0.bin", -+ "fw_bcm40181a0_apsta.bin", -+ "fw_bcm40181a0_p2p.bin", -+ "fw_bcm40181a0_mfg.bin" -+}; -+ -+const static char *bcm40181a2_fw_name[] = { -+ "fw_bcm40181a2.bin", -+ "fw_bcm40181a2_apsta.bin", -+ "fw_bcm40181a2_p2p.bin", -+ "fw_bcm40181a2_mfg.bin" -+}; -+ -+const static char *bcm43341b0ag_fw_name[] = { -+ "fw_bcm43341b0_ag.bin", -+ "fw_bcm43341b0_ag_apsta.bin", -+ "fw_bcm43341b0_ag_p2p.bin", -+ "fw_bcm43341b0_ag_mfg.bin" -+}; -+ -+const static char *bcm43241b4ag_fw_name[] = { -+ "fw_bcm43241b4_ag.bin", -+ "fw_bcm43241b4_ag_apsta.bin", -+ "fw_bcm43241b4_ag_p2p.bin", -+ "fw_bcm43241b4_ag_mfg.bin" -+}; -+ -+#define BCM4330B2_CHIP_REV 4 -+#define BCM43362A0_CHIP_REV 0 -+#define BCM43362A2_CHIP_REV 1 -+#define BCM43341B0_CHIP_REV 2 -+#define BCM43241B4_CHIP_REV 5 -+ -+#define ALIGNMENT 4 -+ -+#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -+extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); -+#endif -+ -+#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) -+#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD -+#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -+#define PKTALIGN(osh, p, len, align) \ -+ do { \ -+ uint datalign; \ -+ datalign = (uintptr)PKTDATA((osh), (p)); \ -+ datalign = ROUNDUP(datalign, (align)) - datalign; \ -+ ASSERT(datalign < (align)); \ -+ ASSERT(PKTLEN((osh), (p)) >= ((len) + datalign)); \ -+ if (datalign) \ -+ PKTPULL((osh), (p), datalign); \ -+ PKTSETLEN((osh), (p), (len)); \ -+ } while (0) -+ -+/* Limit on rounding up frames */ -+static const uint max_roundup = 512; -+ -+/* Try doing readahead */ -+static bool dhd_readahead; -+ -+ -+/* To check if there's window offered */ -+#define DATAOK(bus) \ -+ (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \ -+ (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) -+ -+/* To check if there's window offered for ctrl frame */ -+#define TXCTLOK(bus) \ -+ (((uint8)(bus->tx_max - bus->tx_seq) != 0) && \ -+ (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) -+ -+/* Number of pkts available in dongle for data RX */ -+#define DATABUFCNT(bus) \ -+ ((uint8)(bus->tx_max - bus->tx_seq) - 1) -+ -+/* Macros to get register read/write status */ -+/* NOTE: these assume a local dhdsdio_bus_t *bus! */ -+#define R_SDREG(regvar, regaddr, retryvar) \ -+do { \ -+ retryvar = 0; \ -+ do { \ -+ regvar = R_REG(bus->dhd->osh, regaddr); \ -+ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ -+ if (retryvar) { \ -+ bus->regfails += (retryvar-1); \ -+ if (retryvar > retry_limit) { \ -+ AP6210_ERR("%s: FAILED" #regvar "READ, LINE %d\n", \ -+ __FUNCTION__, __LINE__); \ -+ regvar = 0; \ -+ } \ -+ } \ -+} while (0) -+ -+#define W_SDREG(regval, regaddr, retryvar) \ -+do { \ -+ retryvar = 0; \ -+ do { \ -+ W_REG(bus->dhd->osh, regaddr, regval); \ -+ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ -+ if (retryvar) { \ -+ bus->regfails += (retryvar-1); \ -+ if (retryvar > retry_limit) \ -+ AP6210_ERR("%s: FAILED REGISTER WRITE, LINE %d\n", \ -+ __FUNCTION__, __LINE__); \ -+ } \ -+} while (0) -+ -+#define BUS_WAKE(bus) \ -+ do { \ -+ bus->idlecount = 0; \ -+ if ((bus)->sleeping) \ -+ dhdsdio_bussleep((bus), FALSE); \ -+ } while (0); -+ -+/* -+ * pktavail interrupts from dongle to host can be managed in 3 different ways -+ * whenever there is a packet available in dongle to transmit to host. -+ * -+ * Mode 0: Dongle writes the software host mailbox and host is interrupted. -+ * Mode 1: (sdiod core rev >= 4) -+ * Device sets a new bit in the intstatus whenever there is a packet -+ * available in fifo. Host can't clear this specific status bit until all the -+ * packets are read from the FIFO. No need to ack dongle intstatus. -+ * Mode 2: (sdiod core rev >= 4) -+ * Device sets a bit in the intstatus, and host acks this by writing -+ * one to this bit. Dongle won't generate anymore packet interrupts -+ * until host reads all the packets from the dongle and reads a zero to -+ * figure that there are no more packets. No need to disable host ints. -+ * Need to ack the intstatus. -+ */ -+ -+#define SDIO_DEVICE_HMB_RXINT 0 /* default old way */ -+#define SDIO_DEVICE_RXDATAINT_MODE_0 1 /* from sdiod rev 4 */ -+#define SDIO_DEVICE_RXDATAINT_MODE_1 2 /* from sdiod rev 4 */ -+ -+ -+#define FRAME_AVAIL_MASK(bus) \ -+ ((bus->rxint_mode == SDIO_DEVICE_HMB_RXINT) ? I_HMB_FRAME_IND : I_XMTDATA_AVAIL) -+ -+#define DHD_BUS SDIO_BUS -+ -+#define PKT_AVAILABLE(bus, intstatus) ((intstatus) & (FRAME_AVAIL_MASK(bus))) -+ -+#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) -+ -+#define GSPI_PR55150_BAILOUT -+ -+#ifdef SDTEST -+static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); -+static void dhdsdio_sdtest_set(dhd_bus_t *bus, uint count); -+#endif -+ -+#ifdef DHD_DEBUG -+static int dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size); -+static int dhd_serialconsole(dhd_bus_t *bus, bool get, bool enable, int *bcmerror); -+#endif /* DHD_DEBUG */ -+ -+static int dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap); -+static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); -+ -+static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); -+static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh); -+static void dhdsdio_disconnect(void *ptr); -+static bool dhdsdio_chipmatch(uint16 chipid); -+static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh, -+ void * regsva, uint16 devid); -+static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh); -+static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh); -+static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, -+ bool reset_flag); -+ -+static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -+static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, -+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -+static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, -+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -+#ifdef BCMSDIOH_TXGLOM -+static void dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len); -+static void dhd_bcmsdh_glom_clear(dhd_bus_t *bus); -+#endif -+ -+static bool dhdsdio_download_firmware(dhd_bus_t *bus, osl_t *osh, void *sdh); -+static int _dhdsdio_download_firmware(dhd_bus_t *bus); -+ -+static int dhdsdio_download_code_file(dhd_bus_t *bus, char *image_path); -+static int dhdsdio_download_nvram(dhd_bus_t *bus); -+#ifdef BCMEMBEDIMAGE -+static int dhdsdio_download_code_array(dhd_bus_t *bus); -+#endif -+static int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep); -+static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok); -+static uint8 dhdsdio_sleepcsr_get(dhd_bus_t *bus); -+ -+#ifdef WLMEDIA_HTSF -+#include -+extern uint32 dhd_get_htsf(void *dhd, int ifidx); -+#endif /* WLMEDIA_HTSF */ -+ -+static void -+dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) -+{ -+ int32 min_size = DONGLE_MIN_MEMSIZE; -+ /* Restrict the memsize to user specified limit */ -+ AP6210_DEBUG("user: Restrict the dongle ram size to %d, min accepted %d\n", -+ dhd_dongle_memsize, min_size); -+ if ((dhd_dongle_memsize > min_size) && -+ (dhd_dongle_memsize < (int32)bus->orig_ramsize)) -+ bus->ramsize = dhd_dongle_memsize; -+} -+ -+static int -+dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address) -+{ -+ int err = 0; -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, -+ (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); -+ if (!err) -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, -+ (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); -+ if (!err) -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, -+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); -+ return err; -+} -+ -+ -+#ifdef USE_OOB_GPIO1 -+static int -+dhdsdio_oobwakeup_init(dhd_bus_t *bus) -+{ -+ uint32 val, addr, data; -+ -+ bcmsdh_gpioouten(bus->sdh, GPIO_DEV_WAKEUP); -+ -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); -+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); -+ -+ /* Set device for gpio1 wakeup */ -+ bcmsdh_reg_write(bus->sdh, addr, 4, 2); -+ val = bcmsdh_reg_read(bus->sdh, data, 4); -+ val |= CC_CHIPCTRL2_GPIO1_WAKEUP; -+ bcmsdh_reg_write(bus->sdh, data, 4, val); -+ -+ bus->_oobwakeup = TRUE; -+ -+ return 0; -+} -+#endif /* USE_OOB_GPIO1 */ -+ -+/* -+ * Query if FW is in SR mode -+ */ -+static bool -+dhdsdio_sr_cap(dhd_bus_t *bus) -+{ -+ bool cap = FALSE; -+ uint32 min = 0, core_capext, addr, data; -+ if (bus->sih->chip == BCM4324_CHIP_ID) { -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); -+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); -+ bcmsdh_reg_write(bus->sdh, addr, 4, 3); -+ core_capext = bcmsdh_reg_read(bus->sdh, data, 4); -+ } else if (bus->sih->chip == BCM4330_CHIP_ID || bus->sih->chip == BCM43362_CHIP_ID) { -+ core_capext = FALSE; -+ } else if (bus->sih->chip == BCM4335_CHIP_ID) { -+ core_capext = TRUE; -+ } else { -+ core_capext = bcmsdh_reg_read(bus->sdh, CORE_CAPEXT_ADDR, 4); -+ core_capext = (core_capext & CORE_CAPEXT_SR_SUPPORTED_MASK); -+ } -+ if (!(core_capext)) -+ return FALSE; -+ -+ if (bus->sih->chip == BCM4324_CHIP_ID) { -+ /* FIX: Should change to query SR control register instead */ -+ min = bcmsdh_reg_read(bus->sdh, MIN_RSRC_ADDR, 4); -+ if (min == MIN_RSRC_SR) -+ cap = TRUE; -+ } else if (bus->sih->chip == BCM4335_CHIP_ID) { -+ uint32 enabval = 0; -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); -+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); -+ bcmsdh_reg_write(bus->sdh, addr, 4, CC_PMUCC3); -+ enabval = bcmsdh_reg_read(bus->sdh, data, 4); -+ -+ if (enabval) -+ cap = TRUE; -+ } else { -+ data = bcmsdh_reg_read(bus->sdh, -+ SI_ENUM_BASE + OFFSETOF(chipcregs_t, retention_ctl), 4); -+ if ((data & (RCTL_MACPHY_DISABLE_MASK | RCTL_LOGIC_DISABLE_MASK)) == 0) -+ cap = TRUE; -+ } -+ -+ return cap; -+} -+ -+static int -+dhdsdio_srwar_init(dhd_bus_t *bus) -+{ -+ -+ bcmsdh_gpio_init(bus->sdh); -+ -+#ifdef USE_OOB_GPIO1 -+ dhdsdio_oobwakeup_init(bus); -+#endif -+ -+ -+ return 0; -+} -+ -+static int -+dhdsdio_sr_init(dhd_bus_t *bus) -+{ -+ uint8 val; -+ int err = 0; -+ -+ if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) -+ dhdsdio_srwar_init(bus); -+ -+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL); -+ val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, -+ 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT, &err); -+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL); -+ -+ /* Add CMD14 Support */ -+ dhdsdio_devcap_set(bus, -+ (SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT)); -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err); -+ -+ bus->_slpauto = dhd_slpauto ? TRUE : FALSE; -+ -+ bus->_srenab = TRUE; -+ -+ return 0; -+} -+ -+/* -+ * FIX: Be sure KSO bit is enabled -+ * Currently, it's defaulting to 0 which should be 1. -+ */ -+static int -+dhdsdio_clk_kso_init(dhd_bus_t *bus) -+{ -+ uint8 val; -+ int err = 0; -+ -+ /* set flag */ -+ bus->kso = TRUE; -+ -+ /* -+ * Enable KeepSdioOn (KSO) bit for normal operation -+ * Default is 0 (4334A0) so set it. Fixed in B0. -+ */ -+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, NULL); -+ if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { -+ val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, val, &err); -+ if (err) -+ AP6210_ERR("%s: SBSDIO_FUNC1_SLEEPCSR err: 0x%x\n", __FUNCTION__, err); -+ } -+ -+ return 0; -+} -+ -+#define KSO_DBG(x) -+#define MAX_KSO_ATTEMPTS 64 -+static int -+dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on) -+{ -+ uint8 wr_val = 0, rd_val, cmp_val, bmask; -+ int err = 0; -+ int try_cnt = 0; -+ -+ KSO_DBG(("%s> op:%s\n", __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"))); -+ -+ wr_val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); -+ -+ if (on) { -+ cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK; -+ bmask = cmp_val; -+ -+ msleep(3); -+ -+ } else { -+ /* Put device to sleep, turn off KSO */ -+ cmp_val = 0; -+ bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK; -+ } -+ -+ do { -+ rd_val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, &err); -+ if (((rd_val & bmask) == cmp_val) && !err) -+ break; -+ -+ KSO_DBG(("%s> KSO wr/rd retry:%d, ERR:%x \n", __FUNCTION__, try_cnt, err)); -+ OSL_DELAY(50); -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); -+ -+ } while (try_cnt++ < MAX_KSO_ATTEMPTS); -+ -+ -+ if (try_cnt > 1) { -+ KSO_DBG(("%s> op:%s, try_cnt:%d, rd_val:%x, ERR:%x \n", -+ __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"), try_cnt, rd_val, err)); -+ } -+ -+ if (try_cnt > MAX_KSO_ATTEMPTS) { -+ AP6210_ERR("%s> op:%s, ERROR: try_cnt:%d, rd_val:%x, ERR:%x \n", -+ __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"), try_cnt, rd_val, err); -+ } -+ return err; -+} -+ -+static int -+dhdsdio_clk_kso_iovar(dhd_bus_t *bus, bool on) -+{ -+ int err = 0; -+ -+ if (on == FALSE) { -+ -+ BUS_WAKE(bus); -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ AP6210_DEBUG("%s: KSO disable clk: 0x%x\n", __FUNCTION__, -+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, &err)); -+ dhdsdio_clk_kso_enab(bus, FALSE); -+ } else { -+ AP6210_DEBUG("%s: KSO enable\n", __FUNCTION__); -+ -+ /* Make sure we have SD bus access */ -+ if (bus->clkstate == CLK_NONE) { -+ AP6210_DEBUG("%s: Request SD clk\n", __FUNCTION__); -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ } -+ -+ /* Double-write to be safe in case transition of AOS */ -+ dhdsdio_clk_kso_enab(bus, TRUE); -+ dhdsdio_clk_kso_enab(bus, TRUE); -+ OSL_DELAY(4000); -+ -+ /* Wait for device ready during transition to wake-up */ -+ SPINWAIT(((dhdsdio_sleepcsr_get(bus)) != -+ (SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | -+ SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), -+ (10000)); -+ -+ AP6210_DEBUG("%s: sleepcsr: 0x%x\n", __FUNCTION__, -+ dhdsdio_sleepcsr_get(bus)); -+ } -+ -+ bus->kso = on; -+ BCM_REFERENCE(err); -+ -+ return 0; -+} -+ -+static uint8 -+dhdsdio_sleepcsr_get(dhd_bus_t *bus) -+{ -+ int err = 0; -+ uint8 val = 0; -+ -+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, &err); -+ if (err) -+ AP6210_DEBUG("Failed to read SLEEPCSR: %d\n", err); -+ -+ return val; -+} -+ -+uint8 -+dhdsdio_devcap_get(dhd_bus_t *bus) -+{ -+ return bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL); -+} -+ -+static int -+dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap) -+{ -+ int err = 0; -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, cap, &err); -+ if (err) -+ AP6210_ERR("%s: devcap set err: 0x%x\n", __FUNCTION__, err); -+ -+ return 0; -+} -+ -+static int -+dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) -+{ -+ int err = 0, retry; -+ uint8 val; -+ -+ retry = 0; -+ if (on == TRUE) { -+ /* Enter Sleep */ -+ -+ /* Be sure we request clk before going to sleep -+ * so we can wake-up with clk request already set -+ * else device can go back to sleep immediately -+ */ -+ if (!SLPAUTO_ENAB(bus)) -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ else { -+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ if ((val & SBSDIO_CSR_MASK) == 0) { -+ AP6210_DEBUG("%s: No clock before enter sleep:0x%x\n", -+ __FUNCTION__, val); -+ -+ /* Reset clock request */ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ SBSDIO_ALP_AVAIL_REQ, &err); -+ AP6210_DEBUG("%s: clock before sleep:0x%x\n", __FUNCTION__, -+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, &err)); -+ } -+ } -+ -+ AP6210_DEBUG("%s: clk before sleep: 0x%x\n", __FUNCTION__, -+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, &err)); -+#ifdef USE_CMD14 -+ err = bcmsdh_sleep(bus->sdh, TRUE); -+#else -+ err = dhdsdio_clk_kso_enab(bus, FALSE); -+ if (OOB_WAKEUP_ENAB(bus)) -+ err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, FALSE); /* GPIO_1 is off */ -+#endif -+ } else { -+ /* Exit Sleep */ -+ /* Make sure we have SD bus access */ -+ if (bus->clkstate == CLK_NONE) { -+ AP6210_DEBUG("%s: Request SD clk\n", __FUNCTION__); -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ } -+ -+ if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) { -+ SPINWAIT((bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) != TRUE), -+ GPIO_DEV_SRSTATE_TIMEOUT); -+ -+ if (bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) == FALSE) { -+ AP6210_ERR("ERROR: GPIO_DEV_SRSTATE still low!\n"); -+ } -+ } -+#ifdef USE_CMD14 -+ err = bcmsdh_sleep(bus->sdh, FALSE); -+ if (SLPAUTO_ENAB(bus) && (err != 0)) { -+ OSL_DELAY(10000); -+ AP6210_DEBUG("%s: Resync device sleep\n", __FUNCTION__); -+ -+ /* Toggle sleep to resync with host and device */ -+ err = bcmsdh_sleep(bus->sdh, TRUE); -+ OSL_DELAY(10000); -+ err = bcmsdh_sleep(bus->sdh, FALSE); -+ -+ if (err) { -+ OSL_DELAY(10000); -+ AP6210_ERR("%s: CMD14 exit failed again!\n", __FUNCTION__); -+ -+ /* Toggle sleep to resync with host and device */ -+ err = bcmsdh_sleep(bus->sdh, TRUE); -+ OSL_DELAY(10000); -+ err = bcmsdh_sleep(bus->sdh, FALSE); -+ if (err) { -+ AP6210_ERR("%s: CMD14 exit failed twice!\n", __FUNCTION__); -+ AP6210_ERR("%s: FATAL: Device non-response!\n", -+ __FUNCTION__); -+ err = 0; -+ } -+ } -+ } -+#else -+ if (OOB_WAKEUP_ENAB(bus)) -+ err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, TRUE); /* GPIO_1 is on */ -+ -+ do { -+ err = dhdsdio_clk_kso_enab(bus, TRUE); -+ if (err) -+ OSL_DELAY(10000); -+ } while ((err != 0) && (++retry < 3)); -+ -+ if (err != 0) { -+ AP6210_ERR("ERROR: kso set failed retry: %d\n", retry); -+ err = 0; /* continue anyway */ -+ } -+#endif /* !USE_CMD14 */ -+ -+ if (err == 0) { -+ uint8 csr; -+ -+ /* Wait for device ready during transition to wake-up */ -+ SPINWAIT((((csr = dhdsdio_sleepcsr_get(bus)) & -+ SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK) != -+ (SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), (20000)); -+ -+ AP6210_DEBUG("%s: ExitSleep sleepcsr: 0x%x\n", __FUNCTION__, csr); -+ -+ if (!(csr & SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)) { -+ AP6210_ERR("%s:ERROR: ExitSleep device NOT Ready! 0x%x\n", -+ __FUNCTION__, csr); -+ err = BCME_NODEVICE; -+ } -+ -+ SPINWAIT((((csr = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, &err)) & SBSDIO_HT_AVAIL) != -+ (SBSDIO_HT_AVAIL)), (10000)); -+ -+ } -+ } -+ -+ /* Update if successful */ -+ if (err == 0) -+ bus->kso = on ? FALSE : TRUE; -+ else { -+ AP6210_ERR("%s: Sleep request failed: on:%d err:%d\n", __FUNCTION__, on, err); -+ if (!on && retry > 2) -+ bus->kso = TRUE; -+ } -+ -+ return err; -+} -+ -+/* Turn backplane clock on or off */ -+static int -+dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) -+{ -+#define HT_AVAIL_ERROR_MAX 10 -+ static int ht_avail_error = 0; -+ int err; -+ uint8 clkctl, clkreq, devctl; -+ bcmsdh_info_t *sdh; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+#if defined(OOB_INTR_ONLY) -+ pendok = FALSE; -+#endif -+ clkctl = 0; -+ sdh = bus->sdh; -+ -+ -+ if (!KSO_ENAB(bus)) -+ return BCME_OK; -+ -+ if (SLPAUTO_ENAB(bus)) { -+ bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY); -+ return BCME_OK; -+ } -+ -+ if (on) { -+ /* Request HT Avail */ -+ clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; -+ -+ -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); -+ if (err) { -+ ht_avail_error++; -+ if (ht_avail_error < HT_AVAIL_ERROR_MAX) { -+ AP6210_ERR("%s: HT Avail request error: %d\n", __FUNCTION__, err); -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+ else if (ht_avail_error == HT_AVAIL_ERROR_MAX) { -+ dhd_os_send_hang_message(bus->dhd); -+ } -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) */ -+ return BCME_ERROR; -+ } else { -+ ht_avail_error = 0; -+ } -+ -+ if (pendok && -+ ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) { -+ uint32 dummy, retries; -+ R_SDREG(dummy, &bus->regs->clockctlstatus, retries); -+ BCM_REFERENCE(dummy); -+ } -+ -+ /* Check current status */ -+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ if (err) { -+ AP6210_ERR("%s: HT Avail read error: %d\n", __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ -+ /* Go to pending and await interrupt if appropriate */ -+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { -+ /* Allow only clock-available interrupt */ -+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); -+ if (err) { -+ AP6210_ERR("%s: Devctl access error setting CA: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ -+ devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); -+ AP6210_DEBUG("CLKCTL: set PENDING\n"); -+ bus->clkstate = CLK_PENDING; -+ return BCME_OK; -+ } else if (bus->clkstate == CLK_PENDING) { -+ /* Cancel CA-only interrupt filter */ -+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); -+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); -+ } -+ -+ /* Otherwise, wait here (polling) for HT Avail */ -+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { -+ SPINWAIT_SLEEP(sdioh_spinwait_sleep, -+ ((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, &err)), -+ !SBSDIO_CLKAV(clkctl, bus->alp_only)), PMU_MAX_TRANSITION_DLY); -+ } -+ if (err) { -+ AP6210_ERR("%s: HT Avail request error: %d\n", __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { -+ AP6210_ERR("%s: HT Avail timeout (%d): clkctl 0x%02x\n", -+ __FUNCTION__, PMU_MAX_TRANSITION_DLY, clkctl); -+ return BCME_ERROR; -+ } -+ -+ /* Mark clock available */ -+ bus->clkstate = CLK_AVAIL; -+ AP6210_DEBUG("CLKCTL: turned ON\n"); -+ -+#if defined(DHD_DEBUG) -+ if (bus->alp_only == TRUE) { -+#if !defined(BCMLXSDMMC) -+ if (!SBSDIO_ALPONLY(clkctl)) { -+ AP6210_ERR("%s: HT Clock, when ALP Only\n", __FUNCTION__); -+ } -+#endif /* !defined(BCMLXSDMMC) */ -+ } else { -+ if (SBSDIO_ALPONLY(clkctl)) { -+ AP6210_ERR("%s: HT Clock should be on.\n", __FUNCTION__); -+ } -+ } -+#endif /* defined (DHD_DEBUG) */ -+ -+ bus->activity = TRUE; -+#ifdef DHD_USE_IDLECOUNT -+ bus->idlecount = 0; -+#endif /* DHD_USE_IDLECOUNT */ -+ } else { -+ clkreq = 0; -+ if (bus->clkstate == CLK_PENDING) { -+ /* Cancel CA-only interrupt filter */ -+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); -+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); -+ } -+ -+ bus->clkstate = CLK_SDONLY; -+ if (!SR_ENAB(bus)) { -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); -+ AP6210_DEBUG("CLKCTL: turned OFF\n"); -+ if (err) { -+ AP6210_ERR("%s: Failed access turning clock off: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } -+ } -+ return BCME_OK; -+} -+ -+/* Change idle/active SD state */ -+static int -+dhdsdio_sdclk(dhd_bus_t *bus, bool on) -+{ -+ int err; -+ int32 iovalue; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (on) { -+ if (bus->idleclock == DHD_IDLE_STOP) { -+ /* Turn on clock and restore mode */ -+ iovalue = 1; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error enabling sd_clock: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ -+ iovalue = bus->sd_mode; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error changing sd_mode: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } else if (bus->idleclock != DHD_IDLE_ACTIVE) { -+ /* Restore clock speed */ -+ iovalue = bus->sd_divisor; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error restoring sd_divisor: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } -+ bus->clkstate = CLK_SDONLY; -+ } else { -+ /* Stop or slow the SD clock itself */ -+ if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { -+ AP6210_DEBUG("%s: can't idle clock, divisor %d mode %d\n", -+ __FUNCTION__, bus->sd_divisor, bus->sd_mode); -+ return BCME_ERROR; -+ } -+ if (bus->idleclock == DHD_IDLE_STOP) { -+ if (sd1idle) { -+ /* Change to SD1 mode and turn off clock */ -+ iovalue = 1; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error changing sd_clock: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } -+ -+ iovalue = 0; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error disabling sd_clock: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } else if (bus->idleclock != DHD_IDLE_ACTIVE) { -+ /* Set divisor to idle value */ -+ iovalue = bus->idleclock; -+ err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, -+ &iovalue, sizeof(iovalue), TRUE); -+ if (err) { -+ AP6210_ERR("%s: error changing sd_divisor: %d\n", -+ __FUNCTION__, err); -+ return BCME_ERROR; -+ } -+ } -+ bus->clkstate = CLK_NONE; -+ } -+ -+ return BCME_OK; -+} -+ -+/* Transition SD and backplane clock readiness */ -+static int -+dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) -+{ -+ int ret = BCME_OK; -+#ifdef DHD_DEBUG -+ uint oldstate = bus->clkstate; -+#endif /* DHD_DEBUG */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* Early exit if we're already there */ -+ if (bus->clkstate == target) { -+ if (target == CLK_AVAIL) { -+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); -+ bus->activity = TRUE; -+#ifdef DHD_USE_IDLECOUNT -+ bus->idlecount = 0; -+#endif /* DHD_USE_IDLECOUNT */ -+ } -+ return ret; -+ } -+ -+ switch (target) { -+ case CLK_AVAIL: -+ /* Make sure SD clock is available */ -+ if (bus->clkstate == CLK_NONE) -+ dhdsdio_sdclk(bus, TRUE); -+ /* Now request HT Avail on the backplane */ -+ ret = dhdsdio_htclk(bus, TRUE, pendok); -+ if (ret == BCME_OK) { -+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); -+ bus->activity = TRUE; -+#ifdef DHD_USE_IDLECOUNT -+ bus->idlecount = 0; -+#endif /* DHD_USE_IDLECOUNT */ -+ } -+ break; -+ -+ case CLK_SDONLY: -+ /* Remove HT request, or bring up SD clock */ -+ if (bus->clkstate == CLK_NONE) -+ ret = dhdsdio_sdclk(bus, TRUE); -+ else if (bus->clkstate == CLK_AVAIL) -+ ret = dhdsdio_htclk(bus, FALSE, FALSE); -+ else -+ AP6210_DEBUG("dhdsdio_clkctl: request for %d -> %d\n", -+ bus->clkstate, target); -+ if (ret == BCME_OK) { -+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); -+ } -+ break; -+ -+ case CLK_NONE: -+ /* Make sure to remove HT request */ -+ if (bus->clkstate == CLK_AVAIL) -+ ret = dhdsdio_htclk(bus, FALSE, FALSE); -+ /* Now remove the SD clock */ -+ ret = dhdsdio_sdclk(bus, FALSE); -+#ifdef DHD_DEBUG -+ if (dhd_console_ms == 0) -+#endif /* DHD_DEBUG */ -+ if (bus->poll == 0) -+ dhd_os_wd_timer(bus->dhd, 0); -+ break; -+ } -+#ifdef DHD_DEBUG -+ AP6210_DEBUG("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate); -+#endif /* DHD_DEBUG */ -+ -+ return ret; -+} -+ -+static int -+dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) -+{ -+ int err = 0; -+ bcmsdh_info_t *sdh = bus->sdh; -+ sdpcmd_regs_t *regs = bus->regs; -+ uint retries = 0; -+ -+ AP6210_DEBUG("dhdsdio_bussleep: request %s (currently %s)\n", -+ (sleep ? "SLEEP" : "WAKE"), -+ (bus->sleeping ? "SLEEP" : "WAKE")); -+ -+ /* Done if we're already in the requested state */ -+ if (sleep == bus->sleeping) -+ return BCME_OK; -+ -+ /* Going to sleep: set the alarm and turn off the lights... */ -+ if (sleep) { -+ /* Don't sleep if something is pending */ -+ if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) -+ return BCME_BUSY; -+ -+ -+ if (!SLPAUTO_ENAB(bus)) { -+ /* Disable SDIO interrupts (no longer interested) */ -+ bcmsdh_intr_disable(bus->sdh); -+ -+ /* Make sure the controller has the bus up */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ /* Tell device to start using OOB wakeup */ -+ W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); -+ if (retries > retry_limit) -+ AP6210_ERR("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); -+ -+ /* Turn off our contribution to the HT clock request */ -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); -+ -+ /* Isolate the bus */ -+ if (bus->sih->chip != BCM4329_CHIP_ID && -+ bus->sih->chip != BCM4319_CHIP_ID) { -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, -+ SBSDIO_DEVCTL_PADS_ISO, NULL); -+ } -+ } else { -+ /* Leave interrupts enabled since device can exit sleep and -+ * interrupt host -+ */ -+ err = dhdsdio_clk_devsleep_iovar(bus, TRUE /* sleep */); -+ } -+ -+ /* Change state */ -+ bus->sleeping = TRUE; -+ -+ } else { -+ /* Waking up: bus power up is ok, set local state */ -+ -+ if (!SLPAUTO_ENAB(bus)) { -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, &err); -+ -+ /* Force pad isolation off if possible (in case power never toggled) */ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); -+ -+ -+ /* Make sure the controller has the bus up */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ /* Send misc interrupt to indicate OOB not needed */ -+ W_SDREG(0, ®s->tosbmailboxdata, retries); -+ if (retries <= retry_limit) -+ W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); -+ -+ if (retries > retry_limit) -+ AP6210_ERR("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); -+ -+ /* Make sure we have SD bus access */ -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ -+ /* Enable interrupts again */ -+ if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { -+ bus->intdis = FALSE; -+ bcmsdh_intr_enable(bus->sdh); -+ } -+ } else { -+ err = dhdsdio_clk_devsleep_iovar(bus, FALSE /* wake */); -+ } -+ -+ if (err == 0) { -+ /* Change state */ -+ bus->sleeping = FALSE; -+ } -+ } -+ -+ return err; -+} -+ -+#if defined(OOB_INTR_ONLY) -+void -+dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) -+{ -+#if defined(HW_OOB) -+ bcmsdh_enable_hw_oob_intr(bus->sdh, enable); -+#else -+ sdpcmd_regs_t *regs = bus->regs; -+ uint retries = 0; -+ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ if (enable == TRUE) { -+ -+ /* Tell device to start using OOB wakeup */ -+ W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); -+ if (retries > retry_limit) -+ AP6210_ERR("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); -+ -+ } else { -+ /* Send misc interrupt to indicate OOB not needed */ -+ W_SDREG(0, ®s->tosbmailboxdata, retries); -+ if (retries <= retry_limit) -+ W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); -+ } -+ -+ /* Turn off our contribution to the HT clock request */ -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+#endif /* !defined(HW_OOB) */ -+} -+#endif -+ -+/* Writes a HW/SW header into the packet and sends it. */ -+/* Assumes: (a) header space already there, (b) caller holds lock */ -+static int -+dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt, bool queue_only) -+{ -+ int ret; -+ osl_t *osh; -+ uint8 *frame; -+ uint16 len, pad1 = 0; -+ uint32 swheader; -+ uint retries = 0; -+ bcmsdh_info_t *sdh; -+ void *new; -+ int i; -+ int pkt_cnt; -+#ifdef BCMSDIOH_TXGLOM -+ uint8 *frame_tmp; -+#endif -+#ifdef WLMEDIA_HTSF -+ char *p; -+ htsfts_t *htsf_ts; -+#endif -+ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ sdh = bus->sdh; -+ osh = bus->dhd->osh; -+ -+ if (bus->dhd->dongle_reset) { -+ ret = BCME_NOTREADY; -+ goto done; -+ } -+ -+ frame = (uint8*)PKTDATA(osh, pkt); -+ -+#ifdef WLMEDIA_HTSF -+ if (PKTLEN(osh, pkt) >= 100) { -+ p = PKTDATA(osh, pkt); -+ htsf_ts = (htsfts_t*) (p + HTSF_HOSTOFFSET + 12); -+ if (htsf_ts->magic == HTSFMAGIC) { -+ htsf_ts->c20 = get_cycles(); -+ htsf_ts->t20 = dhd_get_htsf(bus->dhd->info, 0); -+ } -+ } -+#endif /* WLMEDIA_HTSF */ -+ -+ /* Add alignment padding, allocate new packet if needed */ -+ if (!((uintptr)frame & 1) && (pad1 = ((uintptr)frame % DHD_SDALIGN))) { -+ if (PKTHEADROOM(osh, pkt) < pad1) { -+ AP6210_ERR("%s: insufficient headroom %d for %d pad1\n", -+ __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad1); -+ bus->dhd->tx_realloc++; -+ new = PKTGET(osh, (PKTLEN(osh, pkt) + DHD_SDALIGN), TRUE); -+ if (!new) { -+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n", -+ __FUNCTION__, PKTLEN(osh, pkt) + DHD_SDALIGN); -+ ret = BCME_NOMEM; -+ goto done; -+ } -+ -+ PKTALIGN(osh, new, PKTLEN(osh, pkt), DHD_SDALIGN); -+ bcopy(PKTDATA(osh, pkt), PKTDATA(osh, new), PKTLEN(osh, pkt)); -+ if (free_pkt) -+ PKTFREE(osh, pkt, TRUE); -+ /* free the pkt if canned one is not used */ -+ free_pkt = TRUE; -+ pkt = new; -+ frame = (uint8*)PKTDATA(osh, pkt); -+ ASSERT(((uintptr)frame % DHD_SDALIGN) == 0); -+ pad1 = 0; -+ } else { -+ PKTPUSH(osh, pkt, pad1); -+ frame = (uint8*)PKTDATA(osh, pkt); -+ -+ ASSERT((pad1 + SDPCM_HDRLEN) <= (int) PKTLEN(osh, pkt)); -+ bzero(frame, pad1 + SDPCM_HDRLEN); -+ } -+ } -+ ASSERT(pad1 < DHD_SDALIGN); -+ -+ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ -+ len = (uint16)PKTLEN(osh, pkt); -+ *(uint16*)frame = htol16(len); -+ *(((uint16*)frame) + 1) = htol16(~len); -+ -+#ifdef BCMSDIOH_TXGLOM -+ if (bus->glom_enable) { -+ uint32 hwheader1 = 0, hwheader2 = 0, act_len = len; -+ -+ /* Software tag: channel, sequence number, data offset */ -+ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | -+ ((bus->tx_seq + bus->glom_cnt) % SDPCM_SEQUENCE_WRAP) | -+ (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); -+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN); -+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN + sizeof(swheader)); -+ -+ if (queue_only) { -+ if (forcealign && (len & (ALIGNMENT - 1))) -+ len = ROUNDUP(len, ALIGNMENT); -+ /* Hardware extention tag */ -+ /* 2byte frame length, 1byte-, 1byte frame flag, -+ * 2byte-hdrlength, 2byte padlenght -+ */ -+ hwheader1 = (act_len - SDPCM_FRAMETAG_LEN) | (0 << 24); -+ hwheader2 = (len - act_len) << 16; -+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN); -+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4); -+ /* Post the frame pointer to sdio glom array */ -+ dhd_bcmsdh_glom_post(bus, frame, len); -+ /* Save the pkt pointer in bus glom array */ -+ bus->glom_pkt_arr[bus->glom_cnt] = pkt; -+ bus->glom_total_len += len; -+ bus->glom_cnt++; -+ return BCME_OK; -+ } else { -+ /* Raise len to next SDIO block to eliminate tail command */ -+ if (bus->roundup && bus->blocksize && -+ ((bus->glom_total_len + len) > bus->blocksize)) { -+ uint16 pad2 = bus->blocksize - -+ ((bus->glom_total_len + len) % bus->blocksize); -+ if ((pad2 <= bus->roundup) && (pad2 < bus->blocksize)) { -+ len += pad2; -+ } else { -+ } -+ } else if ((bus->glom_total_len + len) % DHD_SDALIGN) { -+ len += DHD_SDALIGN -+ - ((bus->glom_total_len + len) % DHD_SDALIGN); -+ } -+ if (forcealign && (len & (ALIGNMENT - 1))) { -+ len = ROUNDUP(len, ALIGNMENT); -+ } -+ -+ /* Hardware extention tag */ -+ /* 2byte frame length, 1byte-, 1byte frame flag, -+ * 2byte-hdrlength, 2byte padlenght -+ */ -+ hwheader1 = (act_len - SDPCM_FRAMETAG_LEN) | (1 << 24); -+ hwheader2 = (len - act_len) << 16; -+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN); -+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4); -+ -+ /* Post the frame pointer to sdio glom array */ -+ dhd_bcmsdh_glom_post(bus, frame, len); -+ /* Save the pkt pointer in bus glom array */ -+ bus->glom_pkt_arr[bus->glom_cnt] = pkt; -+ bus->glom_cnt++; -+ bus->glom_total_len += len; -+ -+ /* Update the total length on the first pkt */ -+ frame_tmp = (uint8*)PKTDATA(osh, bus->glom_pkt_arr[0]); -+ *(uint16*)frame_tmp = htol16(bus->glom_total_len); -+ *(((uint16*)frame_tmp) + 1) = htol16(~bus->glom_total_len); -+ } -+ } else -+#endif /* BCMSDIOH_TXGLOM */ -+ { -+ /* Software tag: channel, sequence number, data offset */ -+ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | -+ (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); -+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); -+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -+ -+#ifdef DHD_DEBUG -+ if (PKTPRIO(pkt) < ARRAYSIZE(tx_packets)) { -+ tx_packets[PKTPRIO(pkt)]++; -+ } -+ if (DHD_BYTES_ON() && -+ (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || -+ (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { -+ prhex("Tx Frame", frame, len); -+ } else if (DHD_HDRS_ON()) { -+ prhex("TxHdr", frame, MIN(len, 16)); -+ } -+#endif -+ -+ /* Raise len to next SDIO block to eliminate tail command */ -+ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { -+ uint16 pad2 = bus->blocksize - (len % bus->blocksize); -+ if ((pad2 <= bus->roundup) && (pad2 < bus->blocksize)) -+#ifdef NOTUSED -+ if (pad2 <= PKTTAILROOM(osh, pkt)) -+#endif /* NOTUSED */ -+ len += pad2; -+ } else if (len % DHD_SDALIGN) { -+ len += DHD_SDALIGN - (len % DHD_SDALIGN); -+ } -+ -+ /* Some controllers have trouble with odd bytes -- round to even */ -+ if (forcealign && (len & (ALIGNMENT - 1))) { -+#ifdef NOTUSED -+ if (PKTTAILROOM(osh, pkt)) -+#endif -+ len = ROUNDUP(len, ALIGNMENT); -+#ifdef NOTUSED -+ else -+ AP6210_DEBUG("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len); -+#endif -+ } -+ } -+ -+ do { -+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ frame, len, pkt, NULL, NULL); -+ bus->f2txdata++; -+ ASSERT(ret != BCME_PENDING); -+ -+ if (ret == BCME_NODEVICE) { -+ AP6210_ERR("%s: Device asleep already\n", __FUNCTION__); -+ } else if (ret < 0) { -+ /* On failure, abort the command and terminate the frame */ -+ AP6210_ERR("%s: sdio error %d, abort command and terminate frame.\n", -+ __FUNCTION__, ret); -+ bus->tx_sderrs++; -+ -+ bcmsdh_abort(sdh, SDIO_FUNC_2); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, -+ SFC_WF_TERM, NULL); -+ bus->f1regdata++; -+ -+ for (i = 0; i < 3; i++) { -+ uint8 hi, lo; -+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCHI, NULL); -+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCLO, NULL); -+ bus->f1regdata += 2; -+ if ((hi == 0) && (lo == 0)) -+ break; -+ } -+ } -+ if (ret == 0) { -+#ifdef BCMSDIOH_TXGLOM -+ if (bus->glom_enable) { -+ bus->tx_seq = (bus->tx_seq + bus->glom_cnt) % SDPCM_SEQUENCE_WRAP; -+ } else -+#endif -+ { -+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; -+ } -+ } -+ } while ((ret < 0) && retrydata && retries++ < TXRETRIES); -+ -+done: -+ -+#ifdef BCMSDIOH_TXGLOM -+ if (bus->glom_enable) { -+ dhd_bcmsdh_glom_clear(bus); -+ pkt_cnt = bus->glom_cnt; -+ } else -+#endif -+ { -+ pkt_cnt = 1; -+ } -+ /* restore pkt buffer pointer before calling tx complete routine */ -+ while (pkt_cnt) { -+#ifdef BCMSDIOH_TXGLOM -+ uint32 doff; -+ if (bus->glom_enable) { -+ pkt = bus->glom_pkt_arr[bus->glom_cnt - pkt_cnt]; -+ frame = (uint8*)PKTDATA(osh, pkt); -+ doff = ltoh32_ua(frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN); -+ doff = (doff & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT; -+ PKTPULL(osh, pkt, doff); -+ } else -+#endif -+ { -+ PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1); -+ } -+#ifdef PROP_TXSTATUS -+ if (bus->dhd->wlfc_state) { -+ dhd_os_sdunlock(bus->dhd); -+ dhd_wlfc_txcomplete(bus->dhd, pkt, ret == 0, FALSE); -+ dhd_os_sdlock(bus->dhd); -+ } else { -+#endif /* PROP_TXSTATUS */ -+#ifdef SDTEST -+ if (chan != SDPCM_TEST_CHANNEL) { -+ dhd_txcomplete(bus->dhd, pkt, ret != 0); -+ } -+#else /* SDTEST */ -+ dhd_txcomplete(bus->dhd, pkt, ret != 0); -+#endif /* SDTEST */ -+ if (free_pkt) -+ PKTFREE(osh, pkt, TRUE); -+ -+#ifdef PROP_TXSTATUS -+ } -+#endif -+ pkt_cnt--; -+ } -+ -+#ifdef BCMSDIOH_TXGLOM -+ /* Reset the glom array */ -+ if (bus->glom_enable) { -+ bus->glom_cnt = 0; -+ bus->glom_total_len = 0; -+ } -+#endif -+ return ret; -+} -+ -+int -+dhd_bus_txdata(struct dhd_bus *bus, void *pkt, bool wlfc_locked) -+{ -+ int ret = BCME_ERROR; -+ osl_t *osh; -+ uint datalen, prec; -+#ifdef DHD_TX_DUMP -+ uint8 *dump_data; -+ uint16 protocol; -+#ifdef DHD_TX_FULL_DUMP -+ int i; -+#endif /* DHD_TX_FULL_DUMP */ -+#endif /* DHD_TX_DUMP */ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ osh = bus->dhd->osh; -+ datalen = PKTLEN(osh, pkt); -+ -+#ifdef SDTEST -+ /* Push the test header if doing loopback */ -+ if (bus->ext_loop) { -+ uint8* data; -+ PKTPUSH(osh, pkt, SDPCM_TEST_HDRLEN); -+ data = PKTDATA(osh, pkt); -+ *data++ = SDPCM_TEST_ECHOREQ; -+ *data++ = (uint8)bus->loopid++; -+ *data++ = (datalen >> 0); -+ *data++ = (datalen >> 8); -+ datalen += SDPCM_TEST_HDRLEN; -+ } -+#endif /* SDTEST */ -+ -+#ifdef DHD_TX_DUMP -+ dump_data = PKTDATA(osh, pkt); -+ dump_data += 4; /* skip 4 bytes header */ -+ protocol = (dump_data[12] << 8) | dump_data[13]; -+#ifdef DHD_TX_FULL_DUMP -+ AP6210_DEBUG("TX DUMP\n"); -+ -+ for (i = 0; i < (datalen - 4); i++) { -+ DHD_CONT("%02X ", dump_data[i]); -+ if ((i & 15) == 15) -+ DHD_CONT("\n"); -+ } -+ AP6210_DEBUG("\n"); -+ -+#endif /* DHD_TX_FULL_DUMP */ -+ if (protocol == ETHER_TYPE_802_1X) { -+ AP6210_DEBUG("ETHER_TYPE_802_1X: ver %d, type %d, replay %d\n", -+ dump_data[14], dump_data[15], dump_data[30]); -+ } -+#endif /* DHD_TX_DUMP */ -+ -+ /* Add space for the header */ -+ PKTPUSH(osh, pkt, SDPCM_HDRLEN); -+ ASSERT(ISALIGNED((uintptr)PKTDATA(osh, pkt), 2)); -+ -+ prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); -+#ifndef DHDTHREAD -+ /* Lock: we're about to use shared data/code (and SDIO) */ -+ dhd_os_sdlock(bus->dhd); -+#endif /* DHDTHREAD */ -+ -+ /* Check for existing queue, current flow-control, pending event, or pending clock */ -+ if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched || -+ (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || -+ (bus->clkstate != CLK_AVAIL)) { -+ AP6210_DEBUG("%s: deferring pktq len %d\n", __FUNCTION__, -+ pktq_len(&bus->txq)); -+ bus->fcqueued++; -+ -+ /* Priority based enq */ -+ dhd_os_sdlock_txq(bus->dhd); -+ if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == FALSE) { -+ PKTPULL(osh, pkt, SDPCM_HDRLEN); -+#ifndef DHDTHREAD -+ /* Need to also release txqlock before releasing sdlock. -+ * This thread still has txqlock and releases sdlock. -+ * Deadlock happens when dpc() grabs sdlock first then -+ * attempts to grab txqlock. -+ */ -+ dhd_os_sdunlock_txq(bus->dhd); -+ dhd_os_sdunlock(bus->dhd); -+#endif -+#ifdef PROP_TXSTATUS -+ if (bus->dhd->wlfc_state) -+ dhd_wlfc_txcomplete(bus->dhd, pkt, FALSE, wlfc_locked); -+ else -+#endif -+ dhd_txcomplete(bus->dhd, pkt, FALSE); -+#ifndef DHDTHREAD -+ dhd_os_sdlock(bus->dhd); -+ dhd_os_sdlock_txq(bus->dhd); -+#endif -+#ifdef PROP_TXSTATUS -+ /* let the caller decide whether to free the packet */ -+ if (!bus->dhd->wlfc_state) -+#endif -+ PKTFREE(osh, pkt, TRUE); -+ ret = BCME_NORESOURCE; -+ } -+ else -+ ret = BCME_OK; -+ dhd_os_sdunlock_txq(bus->dhd); -+ -+ if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) -+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON); -+ -+#ifdef DHD_DEBUG -+ if (pktq_plen(&bus->txq, prec) > qcount[prec]) -+ qcount[prec] = pktq_plen(&bus->txq, prec); -+#endif -+ /* Schedule DPC if needed to send queued packet(s) */ -+ if (dhd_deferred_tx && !bus->dpc_sched) { -+ bus->dpc_sched = TRUE; -+ dhd_sched_dpc(bus->dhd); -+ } -+ } else { -+#ifdef DHDTHREAD -+ /* Lock: we're about to use shared data/code (and SDIO) */ -+ dhd_os_sdlock(bus->dhd); -+#endif /* DHDTHREAD */ -+ -+ /* Otherwise, send it now */ -+ BUS_WAKE(bus); -+ /* Make sure back plane ht clk is on, no pending allowed */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); -+#ifndef SDTEST -+ ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE, FALSE); -+#else -+ ret = dhdsdio_txpkt(bus, pkt, -+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE, FALSE); -+#endif -+ if (ret) -+ bus->dhd->tx_errors++; -+ else -+ bus->dhd->dstats.tx_bytes += datalen; -+ -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, TRUE); -+ } -+ -+#ifdef DHDTHREAD -+ dhd_os_sdunlock(bus->dhd); -+#endif /* DHDTHREAD */ -+ } -+ -+#ifndef DHDTHREAD -+ dhd_os_sdunlock(bus->dhd); -+#endif /* DHDTHREAD */ -+ -+ return ret; -+} -+ -+static uint -+dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) -+{ -+ void *pkt; -+ uint32 intstatus = 0; -+ uint retries = 0; -+ int ret = 0, prec_out; -+ uint cnt = 0; -+ uint datalen; -+ uint8 tx_prec_map; -+#ifdef BCMSDIOH_TXGLOM -+ uint i; -+ uint8 glom_cnt; -+#endif -+ -+ dhd_pub_t *dhd = bus->dhd; -+ sdpcmd_regs_t *regs = bus->regs; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (!KSO_ENAB(bus)) { -+ AP6210_DEBUG("%s: Device asleep\n", __FUNCTION__); -+ return BCME_NODEVICE; -+ } -+ -+ tx_prec_map = ~bus->flowcontrol; -+ -+ /* Send frames until the limit or some other event */ -+ for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { -+#ifdef BCMSDIOH_TXGLOM -+ if (bus->glom_enable) { -+ glom_cnt = MIN(DATABUFCNT(bus), bus->glomsize); -+ glom_cnt = MIN(glom_cnt, pktq_mlen(&bus->txq, tx_prec_map)); -+ glom_cnt = MIN(glom_cnt, maxframes-cnt); -+ -+ /* Limiting the size to 2pkts in case of copy */ -+ if (bus->glom_mode == SDPCM_TXGLOM_CPY) -+ glom_cnt = MIN(glom_cnt, 5); -+ -+ if (glom_cnt == 0) -+ break; -+ datalen = 0; -+ for (i = 0; i < glom_cnt; i++) { -+ dhd_os_sdlock_txq(bus->dhd); -+ if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { -+ /* This case should not happen */ -+ AP6210_DEBUG("No pkts in the queue for glomming\n"); -+ dhd_os_sdunlock_txq(bus->dhd); -+ break; -+ } -+ dhd_os_sdunlock_txq(bus->dhd); -+ -+ datalen += (PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN); -+#ifndef SDTEST -+ ret = dhdsdio_txpkt(bus, -+ pkt, -+ SDPCM_DATA_CHANNEL, -+ TRUE, -+ (i == (glom_cnt-1))? FALSE: TRUE); -+#else -+ ret = dhdsdio_txpkt(bus, -+ pkt, -+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), -+ TRUE, -+ (i == (glom_cnt-1))? FALSE: TRUE); -+#endif -+ } -+ cnt += i-1; -+ } else -+#endif /* BCMSDIOH_TXGLOM */ -+ { -+ dhd_os_sdlock_txq(bus->dhd); -+ if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { -+ dhd_os_sdunlock_txq(bus->dhd); -+ break; -+ } -+ dhd_os_sdunlock_txq(bus->dhd); -+ datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN; -+ -+#ifndef SDTEST -+ ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE, FALSE); -+#else -+ ret = dhdsdio_txpkt(bus, -+ pkt, -+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), -+ TRUE, -+ FALSE); -+#endif -+ } -+ -+ if (ret) -+ bus->dhd->tx_errors++; -+ else -+ bus->dhd->dstats.tx_bytes += datalen; -+ -+ /* In poll mode, need to check for other events */ -+ if (!bus->intr && cnt) -+ { -+ /* Check device status, signal pending interrupt */ -+ R_SDREG(intstatus, ®s->intstatus, retries); -+ bus->f2txdata++; -+ if (bcmsdh_regfail(bus->sdh)) -+ break; -+ if (intstatus & bus->hostintmask) -+ bus->ipend = TRUE; -+ } -+ } -+ -+ /* Deflow-control stack if needed */ -+ if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && -+ dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) -+ dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF); -+ -+ return cnt; -+} -+ -+int -+dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) -+{ -+ uint8 *frame; -+ uint16 len; -+ uint32 swheader; -+ uint retries = 0; -+ bcmsdh_info_t *sdh = bus->sdh; -+ uint8 doff = 0; -+ int ret = -1; -+ int i; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus->dhd->dongle_reset) -+ return -EIO; -+ -+ /* Back the pointer to make a room for bus header */ -+ frame = msg - SDPCM_HDRLEN; -+ len = (msglen += SDPCM_HDRLEN); -+ -+ /* Add alignment padding (optional for ctl frames) */ -+ if (dhd_alignctl) { -+ if ((doff = ((uintptr)frame % DHD_SDALIGN))) { -+ frame -= doff; -+ len += doff; -+ msglen += doff; -+ bzero(frame, doff + SDPCM_HDRLEN); -+ } -+ ASSERT(doff < DHD_SDALIGN); -+ } -+ doff += SDPCM_HDRLEN; -+ -+ /* Round send length to next SDIO block */ -+ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { -+ uint16 pad = bus->blocksize - (len % bus->blocksize); -+ if ((pad <= bus->roundup) && (pad < bus->blocksize)) -+ len += pad; -+ } else if (len % DHD_SDALIGN) { -+ len += DHD_SDALIGN - (len % DHD_SDALIGN); -+ } -+ -+ /* Satisfy length-alignment requirements */ -+ if (forcealign && (len & (ALIGNMENT - 1))) -+ len = ROUNDUP(len, ALIGNMENT); -+ -+ ASSERT(ISALIGNED((uintptr)frame, 2)); -+ -+ -+ /* Need to lock here to protect txseq and SDIO tx calls */ -+ dhd_os_sdlock(bus->dhd); -+ -+ BUS_WAKE(bus); -+ -+ /* Make sure backplane clock is on */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ -+ *(uint16*)frame = htol16((uint16)msglen); -+ *(((uint16*)frame) + 1) = htol16(~msglen); -+ -+#ifdef BCMSDIOH_TXGLOM -+ if (bus->glom_enable) { -+ uint32 hwheader1, hwheader2; -+ /* Software tag: channel, sequence number, data offset */ -+ swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) -+ | bus->tx_seq -+ | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); -+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN); -+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN -+ + SDPCM_HWEXT_LEN + sizeof(swheader)); -+ -+ hwheader1 = (msglen - SDPCM_FRAMETAG_LEN) | (1 << 24); -+ hwheader2 = (len - (msglen)) << 16; -+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN); -+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4); -+ -+ *(uint16*)frame = htol16(len); -+ *(((uint16*)frame) + 1) = htol16(~(len)); -+ } else -+#endif /* BCMSDIOH_TXGLOM */ -+ { -+ /* Software tag: channel, sequence number, data offset */ -+ swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) -+ | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); -+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); -+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -+ } -+ if (!TXCTLOK(bus)) { -+ AP6210_DEBUG("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", -+ __FUNCTION__, bus->tx_max, bus->tx_seq); -+ bus->ctrl_frame_stat = TRUE; -+ /* Send from dpc */ -+ bus->ctrl_frame_buf = frame; -+ bus->ctrl_frame_len = len; -+ -+ if (!bus->dpc_sched) { -+ bus->dpc_sched = TRUE; -+ dhd_sched_dpc(bus->dhd); -+ } -+ if (bus->ctrl_frame_stat) { -+ dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); -+ } -+ -+ if (bus->ctrl_frame_stat == FALSE) { -+ AP6210_DEBUG("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__); -+ ret = 0; -+ } else { -+ bus->dhd->txcnt_timeout++; -+ if (!bus->dhd->hang_was_sent) { -+ AP6210_DEBUG("%s: ctrl_frame_stat == TRUE txcnt_timeout=%d\n", -+ __FUNCTION__, bus->dhd->txcnt_timeout); -+ } -+ ret = -1; -+ bus->ctrl_frame_stat = FALSE; -+ goto done; -+ } -+ } -+ -+ bus->dhd->txcnt_timeout = 0; -+ -+ if (ret == -1) { -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_CTL_ON()) { -+ prhex("Tx Frame", frame, len); -+ } else if (DHD_HDRS_ON()) { -+ prhex("TxHdr", frame, MIN(len, 16)); -+ } -+#endif -+ -+ do { -+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ frame, len, NULL, NULL, NULL); -+ ASSERT(ret != BCME_PENDING); -+ -+ if (ret == BCME_NODEVICE) { -+ AP6210_DEBUG("%s: Device asleep already\n", __FUNCTION__); -+ } else if (ret < 0) { -+ /* On failure, abort the command and terminate the frame */ -+ AP6210_DEBUG("%s: sdio error %d, abort command and terminate frame.\n", -+ __FUNCTION__, ret); -+ bus->tx_sderrs++; -+ -+ bcmsdh_abort(sdh, SDIO_FUNC_2); -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, -+ SFC_WF_TERM, NULL); -+ bus->f1regdata++; -+ -+ for (i = 0; i < 3; i++) { -+ uint8 hi, lo; -+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCHI, NULL); -+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCLO, NULL); -+ bus->f1regdata += 2; -+ if ((hi == 0) && (lo == 0)) -+ break; -+ } -+ } -+ if (ret == 0) { -+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; -+ } -+ } while ((ret < 0) && retries++ < TXRETRIES); -+ } -+ -+done: -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, TRUE); -+ } -+ -+ dhd_os_sdunlock(bus->dhd); -+ -+ if (ret) -+ bus->dhd->tx_ctlerrs++; -+ else -+ bus->dhd->tx_ctlpkts++; -+ -+ if (bus->dhd->txcnt_timeout >= MAX_CNTL_TIMEOUT) -+ return -ETIMEDOUT; -+ -+ return ret ? -EIO : 0; -+} -+ -+int -+dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) -+{ -+ int timeleft; -+ uint rxlen = 0; -+ bool pending; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus->dhd->dongle_reset) -+ return -EIO; -+ -+ /* Wait until control frame is available */ -+ timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending); -+ -+ dhd_os_sdlock(bus->dhd); -+ rxlen = bus->rxlen; -+ bcopy(bus->rxctl, msg, MIN(msglen, rxlen)); -+ bus->rxlen = 0; -+ dhd_os_sdunlock(bus->dhd); -+ -+ if (rxlen) { -+ AP6210_DEBUG("%s: resumed on rxctl frame, got %d expected %d\n", -+ __FUNCTION__, rxlen, msglen); -+ } else if (timeleft == 0) { -+#ifdef DHD_DEBUG -+ uint32 status, retry = 0; -+ R_SDREG(status, &bus->regs->intstatus, retry); -+ AP6210_DEBUG("%s: resumed on timeout, INT status=0x%08X\n", -+ __FUNCTION__, status); -+#else -+ AP6210_DEBUG("%s: resumed on timeout\n", __FUNCTION__); -+#endif /* DHD_DEBUG */ -+#ifdef DHD_DEBUG -+ dhd_os_sdlock(bus->dhd); -+ dhdsdio_checkdied(bus, NULL, 0); -+ dhd_os_sdunlock(bus->dhd); -+#endif /* DHD_DEBUG */ -+ } else if (pending == TRUE) { -+ /* signal pending */ -+ AP6210_DEBUG("%s: signal pending\n", __FUNCTION__); -+ return -EINTR; -+ } else { -+ AP6210_DEBUG("%s: resumed for unknown reason?\n", __FUNCTION__); -+#ifdef DHD_DEBUG -+ dhd_os_sdlock(bus->dhd); -+ dhdsdio_checkdied(bus, NULL, 0); -+ dhd_os_sdunlock(bus->dhd); -+#endif /* DHD_DEBUG */ -+ } -+ if (timeleft == 0) { -+ bus->dhd->rxcnt_timeout++; -+ AP6210_DEBUG("%s: rxcnt_timeout=%d\n", __FUNCTION__, bus->dhd->rxcnt_timeout); -+ } -+ else -+ bus->dhd->rxcnt_timeout = 0; -+ -+ if (rxlen) -+ bus->dhd->rx_ctlpkts++; -+ else -+ bus->dhd->rx_ctlerrs++; -+ -+ if (bus->dhd->rxcnt_timeout >= MAX_CNTL_TIMEOUT) -+ return -ETIMEDOUT; -+ -+ if (bus->dhd->dongle_trap_occured) -+ return -EREMOTEIO; -+ -+ return rxlen ? (int)rxlen : -EIO; -+} -+ -+/* IOVar table */ -+enum { -+ IOV_INTR = 1, -+ IOV_POLLRATE, -+ IOV_SDREG, -+ IOV_SBREG, -+ IOV_SDCIS, -+ IOV_MEMBYTES, -+ IOV_MEMSIZE, -+#ifdef DHD_DEBUG -+ IOV_CHECKDIED, -+ IOV_SERIALCONS, -+#endif /* DHD_DEBUG */ -+ IOV_SET_DOWNLOAD_STATE, -+ IOV_SOCRAM_STATE, -+ IOV_FORCEEVEN, -+ IOV_SDIOD_DRIVE, -+ IOV_READAHEAD, -+ IOV_SDRXCHAIN, -+ IOV_ALIGNCTL, -+ IOV_SDALIGN, -+ IOV_DEVRESET, -+ IOV_CPU, -+#if defined(SDIO_CRC_ERROR_FIX) -+ IOV_WATERMARK, -+ IOV_MESBUSYCTRL, -+#endif /* SDIO_CRC_ERROR_FIX */ -+#ifdef SDTEST -+ IOV_PKTGEN, -+ IOV_EXTLOOP, -+#endif /* SDTEST */ -+ IOV_SPROM, -+ IOV_TXBOUND, -+ IOV_RXBOUND, -+ IOV_TXMINMAX, -+ IOV_IDLETIME, -+ IOV_IDLECLOCK, -+ IOV_SD1IDLE, -+ IOV_SLEEP, -+ IOV_DONGLEISOLATION, -+ IOV_KSO, -+ IOV_DEVSLEEP, -+ IOV_DEVCAP, -+ IOV_VARS, -+#ifdef SOFTAP -+ IOV_FWPATH, -+#endif -+ IOV_TXGLOMSIZE, -+ IOV_TXGLOMMODE -+}; -+ -+const bcm_iovar_t dhdsdio_iovars[] = { -+ {"intr", IOV_INTR, 0, IOVT_BOOL, 0 }, -+ {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0 }, -+ {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0 }, -+ {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0 }, -+ {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 }, -+ {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, -+ {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, -+ {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 }, -+ {"dwnldstate", IOV_SET_DOWNLOAD_STATE, 0, IOVT_BOOL, 0 }, -+ {"socram_state", IOV_SOCRAM_STATE, 0, IOVT_BOOL, 0 }, -+ {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 }, -+ {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 }, -+ {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0 }, -+ {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0 }, -+ {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0 }, -+ {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0 }, -+ {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0 }, -+#ifdef DHD_DEBUG -+ {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, -+ {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) }, -+ {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN }, -+ {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0 }, -+ {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0 }, -+ {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 }, -+ {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 }, -+ {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 }, -+#ifdef DHD_DEBUG -+ {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 }, -+ {"serial", IOV_SERIALCONS, 0, IOVT_UINT32, 0 }, -+#endif /* DHD_DEBUG */ -+#endif /* DHD_DEBUG */ -+#ifdef SDTEST -+ {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, -+ {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, -+#endif /* SDTEST */ -+#if defined(SDIO_CRC_ERROR_FIX) -+ {"watermark", IOV_WATERMARK, 0, IOVT_UINT32, 0 }, -+ {"mesbusyctrl", IOV_MESBUSYCTRL, 0, IOVT_UINT32, 0 }, -+#endif /* SDIO_CRC_ERROR_FIX */ -+ {"devcap", IOV_DEVCAP, 0, IOVT_UINT32, 0 }, -+ {"dngl_isolation", IOV_DONGLEISOLATION, 0, IOVT_UINT32, 0 }, -+ {"kso", IOV_KSO, 0, IOVT_UINT32, 0 }, -+ {"devsleep", IOV_DEVSLEEP, 0, IOVT_UINT32, 0 }, -+#ifdef SOFTAP -+ {"fwpath", IOV_FWPATH, 0, IOVT_BUFFER, 0 }, -+#endif -+ {"txglomsize", IOV_TXGLOMSIZE, 0, IOVT_UINT32, 0 }, -+ {"txglommode", IOV_TXGLOMMODE, 0, IOVT_UINT32, 0 }, -+ {NULL, 0, 0, 0, 0 } -+}; -+ -+static void -+dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div) -+{ -+ uint q1, q2; -+ -+ if (!div) { -+ bcm_bprintf(strbuf, "%s N/A", desc); -+ } else { -+ q1 = num / div; -+ q2 = (100 * (num - (q1 * div))) / div; -+ bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); -+ } -+} -+ -+void -+dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ -+ bcm_bprintf(strbuf, "Bus SDIO structure:\n"); -+ bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", -+ bus->hostintmask, bus->intstatus, bus->sdpcm_ver); -+ bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", -+ bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, -+ bus->rxlen, bus->rx_seq); -+ bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", -+ bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); -+ bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", -+ bus->pollrate, bus->pollcnt, bus->regfails); -+ -+ bcm_bprintf(strbuf, "\nAdditional counters:\n"); -+ bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", -+ bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, -+ bus->rxc_errors); -+ bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", -+ bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); -+ bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", -+ bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); -+ bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", -+ bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); -+ bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", -+ (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata, -+ bus->f2txdata, bus->f1regdata); -+ { -+ dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets, -+ (bus->f2rxhdrs + bus->f2rxdata)); -+ dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, bus->f1regdata); -+ dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets, -+ (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); -+ dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, bus->intrcount); -+ bcm_bprintf(strbuf, "\n"); -+ -+ dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), -+ bus->dhd->rx_packets); -+ dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes); -+ bcm_bprintf(strbuf, "\n"); -+ -+ dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, bus->f2txdata); -+ dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, bus->f1regdata); -+ dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets, -+ (bus->f2txdata + bus->f1regdata)); -+ dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, bus->intrcount); -+ bcm_bprintf(strbuf, "\n"); -+ -+ dhd_dump_pct(strbuf, "Total: pkts/f2rw", -+ (bus->dhd->tx_packets + bus->dhd->rx_packets), -+ (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); -+ dhd_dump_pct(strbuf, ", pkts/f1sd", -+ (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->f1regdata); -+ dhd_dump_pct(strbuf, ", pkts/sd", -+ (bus->dhd->tx_packets + bus->dhd->rx_packets), -+ (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); -+ dhd_dump_pct(strbuf, ", pkts/int", -+ (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->intrcount); -+ bcm_bprintf(strbuf, "\n\n"); -+ } -+ -+#ifdef SDTEST -+ if (bus->pktgen_count) { -+ bcm_bprintf(strbuf, "pktgen config and count:\n"); -+ bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", -+ bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, -+ bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); -+ bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", -+ bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); -+ } -+#endif /* SDTEST */ -+#ifdef DHD_DEBUG -+ bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", -+ bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); -+ bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); -+#endif /* DHD_DEBUG */ -+ bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", -+ bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); -+} -+ -+void -+dhd_bus_clearcounts(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus; -+ -+ bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; -+ bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; -+ bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0; -+ bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0; -+ bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0; -+ bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; -+} -+ -+#ifdef SDTEST -+static int -+dhdsdio_pktgen_get(dhd_bus_t *bus, uint8 *arg) -+{ -+ dhd_pktgen_t pktgen; -+ -+ pktgen.version = DHD_PKTGEN_VERSION; -+ pktgen.freq = bus->pktgen_freq; -+ pktgen.count = bus->pktgen_count; -+ pktgen.print = bus->pktgen_print; -+ pktgen.total = bus->pktgen_total; -+ pktgen.minlen = bus->pktgen_minlen; -+ pktgen.maxlen = bus->pktgen_maxlen; -+ pktgen.numsent = bus->pktgen_sent; -+ pktgen.numrcvd = bus->pktgen_rcvd; -+ pktgen.numfail = bus->pktgen_fail; -+ pktgen.mode = bus->pktgen_mode; -+ pktgen.stop = bus->pktgen_stop; -+ -+ bcopy(&pktgen, arg, sizeof(pktgen)); -+ -+ return 0; -+} -+ -+static int -+dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg) -+{ -+ dhd_pktgen_t pktgen; -+ uint oldcnt, oldmode; -+ -+ bcopy(arg, &pktgen, sizeof(pktgen)); -+ if (pktgen.version != DHD_PKTGEN_VERSION) -+ return BCME_BADARG; -+ -+ oldcnt = bus->pktgen_count; -+ oldmode = bus->pktgen_mode; -+ -+ bus->pktgen_freq = pktgen.freq; -+ bus->pktgen_count = pktgen.count; -+ bus->pktgen_print = pktgen.print; -+ bus->pktgen_total = pktgen.total; -+ bus->pktgen_minlen = pktgen.minlen; -+ bus->pktgen_maxlen = pktgen.maxlen; -+ bus->pktgen_mode = pktgen.mode; -+ bus->pktgen_stop = pktgen.stop; -+ -+ bus->pktgen_tick = bus->pktgen_ptick = 0; -+ bus->pktgen_prev_time = jiffies; -+ bus->pktgen_len = MAX(bus->pktgen_len, bus->pktgen_minlen); -+ bus->pktgen_len = MIN(bus->pktgen_len, bus->pktgen_maxlen); -+ -+ /* Clear counts for a new pktgen (mode change, or was stopped) */ -+ if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) { -+ bus->pktgen_sent = bus->pktgen_prev_sent = bus->pktgen_rcvd = 0; -+ bus->pktgen_prev_rcvd = bus->pktgen_fail = 0; -+ } -+ -+ return 0; -+} -+#endif /* SDTEST */ -+ -+static void -+dhdsdio_devram_remap(dhd_bus_t *bus, bool val) -+{ -+ uint8 enable, protect, remap; -+ -+ si_socdevram(bus->sih, FALSE, &enable, &protect, &remap); -+ remap = val ? TRUE : FALSE; -+ si_socdevram(bus->sih, TRUE, &enable, &protect, &remap); -+} -+ -+static int -+dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size) -+{ -+ int bcmerror = 0; -+ uint32 sdaddr; -+ uint dsize; -+ -+ /* In remap mode, adjust address beyond socram and redirect -+ * to devram at SOCDEVRAM_BP_ADDR since remap address > orig_ramsize -+ * is not backplane accessible -+ */ -+ if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address)) { -+ address -= bus->orig_ramsize; -+ address += SOCDEVRAM_BP_ADDR; -+ } -+ -+ /* Determine initial transfer parameters */ -+ sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; -+ if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) -+ dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); -+ else -+ dsize = size; -+ -+ /* Set the backplane window to include the start address */ -+ if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { -+ AP6210_ERR("%s: window change failed\n", __FUNCTION__); -+ goto xfer_done; -+ } -+ -+ /* Do the transfer(s) */ -+ while (size) { -+ AP6210_DEBUG("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n", -+ __FUNCTION__, (write ? "write" : "read"), dsize, sdaddr, -+ (address & SBSDIO_SBWINDOW_MASK)); -+ if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) { -+ AP6210_ERR("%s: membytes transfer failed\n", __FUNCTION__); -+ break; -+ } -+ -+ /* Adjust for next transfer (if any) */ -+ if ((size -= dsize)) { -+ data += dsize; -+ address += dsize; -+ if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) { -+ AP6210_ERR("%s: window change failed\n", __FUNCTION__); -+ break; -+ } -+ sdaddr = 0; -+ dsize = MIN(SBSDIO_SB_OFT_ADDR_LIMIT, size); -+ } -+ -+ } -+ -+xfer_done: -+ /* Return the window to backplane enumeration space for core access */ -+ if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) { -+ AP6210_ERR("%s: FAILED to set window back to 0x%x\n", __FUNCTION__, -+ bcmsdh_cur_sbwad(bus->sdh)); -+ } -+ -+ return bcmerror; -+} -+ -+#ifdef DHD_DEBUG -+static int -+dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) -+{ -+ uint32 addr; -+ int rv, i; -+ uint32 shaddr = 0; -+ -+ shaddr = bus->dongle_ram_base + bus->ramsize - 4; -+ i = 0; -+ do { -+ /* Read last word in memory to determine address of sdpcm_shared structure */ -+ if ((rv = dhdsdio_membytes(bus, FALSE, shaddr, (uint8 *)&addr, 4)) < 0) -+ return rv; -+ -+ addr = ltoh32(addr); -+ -+ AP6210_DEBUG("sdpcm_shared address 0x%08X\n", addr); -+ -+ /* -+ * Check if addr is valid. -+ * NVRAM length at the end of memory should have been overwritten. -+ */ -+ if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { -+ if ((bus->srmemsize > 0) && (i++ == 0)) { -+ shaddr -= bus->srmemsize; -+ } else { -+ AP6210_ERR("%s: address (0x%08x) of sdpcm_shared invalid\n", -+ __FUNCTION__, addr); -+ return BCME_ERROR; -+ } -+ } else -+ break; -+ } while (i < 2); -+ -+ /* Read hndrte_shared structure */ -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0) -+ return rv; -+ -+ /* Endianness */ -+ sh->flags = ltoh32(sh->flags); -+ sh->trap_addr = ltoh32(sh->trap_addr); -+ sh->assert_exp_addr = ltoh32(sh->assert_exp_addr); -+ sh->assert_file_addr = ltoh32(sh->assert_file_addr); -+ sh->assert_line = ltoh32(sh->assert_line); -+ sh->console_addr = ltoh32(sh->console_addr); -+ sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); -+ -+ if ((sh->flags & SDPCM_SHARED_VERSION_MASK) == 3 && SDPCM_SHARED_VERSION == 1) -+ return BCME_OK; -+ -+ if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { -+ AP6210_ERR("%s: sdpcm_shared version %d in dhd " -+ "is different than sdpcm_shared version %d in dongle\n", -+ __FUNCTION__, SDPCM_SHARED_VERSION, -+ sh->flags & SDPCM_SHARED_VERSION_MASK); -+ return BCME_ERROR; -+ } -+ -+ return BCME_OK; -+} -+ -+#define CONSOLE_LINE_MAX 192 -+ -+static int -+dhdsdio_readconsole(dhd_bus_t *bus) -+{ -+ dhd_console_t *c = &bus->console; -+ uint8 line[CONSOLE_LINE_MAX], ch; -+ uint32 n, idx, addr; -+ int rv; -+ -+ /* Don't do anything until FWREADY updates console address */ -+ if (bus->console_addr == 0) -+ return 0; -+ -+ if (!KSO_ENAB(bus)) -+ return 0; -+ -+ /* Read console log struct */ -+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log); -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0) -+ return rv; -+ -+ /* Allocate console buffer (one time only) */ -+ if (c->buf == NULL) { -+ c->bufsize = ltoh32(c->log.buf_size); -+ if ((c->buf = MALLOC(bus->dhd->osh, c->bufsize)) == NULL) -+ return BCME_NOMEM; -+ } -+ -+ idx = ltoh32(c->log.idx); -+ -+ /* Protect against corrupt value */ -+ if (idx > c->bufsize) -+ return BCME_ERROR; -+ -+ /* Skip reading the console buffer if the index pointer has not moved */ -+ if (idx == c->last) -+ return BCME_OK; -+ -+ /* Read the console buffer */ -+ addr = ltoh32(c->log.buf); -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0) -+ return rv; -+ -+ while (c->last != idx) { -+ for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { -+ if (c->last == idx) { -+ /* This would output a partial line. Instead, back up -+ * the buffer pointer and output this line next time around. -+ */ -+ if (c->last >= n) -+ c->last -= n; -+ else -+ c->last = c->bufsize - n; -+ goto break2; -+ } -+ ch = c->buf[c->last]; -+ c->last = (c->last + 1) % c->bufsize; -+ if (ch == '\n') -+ break; -+ line[n] = ch; -+ } -+ -+ if (n > 0) { -+ if (line[n - 1] == '\r') -+ n--; -+ line[n] = 0; -+ AP6210_DEBUG("CONSOLE: %s\n", line); -+ } -+ } -+break2: -+ -+ return BCME_OK; -+} -+ -+static int -+dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size) -+{ -+ int bcmerror = 0; -+ uint msize = 512; -+ char *mbuffer = NULL; -+ char *console_buffer = NULL; -+ uint maxstrlen = 256; -+ char *str = NULL; -+ trap_t tr; -+ sdpcm_shared_t sdpcm_shared; -+ struct bcmstrbuf strbuf; -+ uint32 console_ptr, console_size, console_index; -+ uint8 line[CONSOLE_LINE_MAX], ch; -+ uint32 n, i, addr; -+ int rv; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (data == NULL) { -+ /* -+ * Called after a rx ctrl timeout. "data" is NULL. -+ * allocate memory to trace the trap or assert. -+ */ -+ size = msize; -+ mbuffer = data = MALLOC(bus->dhd->osh, msize); -+ if (mbuffer == NULL) { -+ AP6210_ERR("%s: MALLOC(%d) failed \n", __FUNCTION__, msize); -+ bcmerror = BCME_NOMEM; -+ goto done; -+ } -+ } -+ -+ if ((str = MALLOC(bus->dhd->osh, maxstrlen)) == NULL) { -+ AP6210_ERR("%s: MALLOC(%d) failed \n", __FUNCTION__, maxstrlen); -+ bcmerror = BCME_NOMEM; -+ goto done; -+ } -+ -+ if ((bcmerror = dhdsdio_readshared(bus, &sdpcm_shared)) < 0) -+ goto done; -+ -+ bcm_binit(&strbuf, data, size); -+ -+ bcm_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", -+ sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); -+ -+ if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { -+ /* NOTE: Misspelled assert is intentional - DO NOT FIX. -+ * (Avoids conflict with real asserts for programmatic parsing of output.) -+ */ -+ bcm_bprintf(&strbuf, "Assrt not built in dongle\n"); -+ } -+ -+ if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT|SDPCM_SHARED_TRAP)) == 0) { -+ /* NOTE: Misspelled assert is intentional - DO NOT FIX. -+ * (Avoids conflict with real asserts for programmatic parsing of output.) -+ */ -+ bcm_bprintf(&strbuf, "No trap%s in dongle", -+ (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) -+ ?"/assrt" :""); -+ } else { -+ if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { -+ /* Download assert */ -+ bcm_bprintf(&strbuf, "Dongle assert"); -+ if (sdpcm_shared.assert_exp_addr != 0) { -+ str[0] = '\0'; -+ if ((bcmerror = dhdsdio_membytes(bus, FALSE, -+ sdpcm_shared.assert_exp_addr, -+ (uint8 *)str, maxstrlen)) < 0) -+ goto done; -+ -+ str[maxstrlen - 1] = '\0'; -+ bcm_bprintf(&strbuf, " expr \"%s\"", str); -+ } -+ -+ if (sdpcm_shared.assert_file_addr != 0) { -+ str[0] = '\0'; -+ if ((bcmerror = dhdsdio_membytes(bus, FALSE, -+ sdpcm_shared.assert_file_addr, -+ (uint8 *)str, maxstrlen)) < 0) -+ goto done; -+ -+ str[maxstrlen - 1] = '\0'; -+ bcm_bprintf(&strbuf, " file \"%s\"", str); -+ } -+ -+ bcm_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line); -+ } -+ -+ if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { -+ bus->dhd->dongle_trap_occured = TRUE; -+ if ((bcmerror = dhdsdio_membytes(bus, FALSE, -+ sdpcm_shared.trap_addr, -+ (uint8*)&tr, sizeof(trap_t))) < 0) -+ goto done; -+ -+ bcm_bprintf(&strbuf, -+ "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," -+ "lp 0x%x, rpc 0x%x Trap offset 0x%x, " -+ "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, " -+ "r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n\n", -+ ltoh32(tr.type), ltoh32(tr.epc), ltoh32(tr.cpsr), ltoh32(tr.spsr), -+ ltoh32(tr.r13), ltoh32(tr.r14), ltoh32(tr.pc), -+ ltoh32(sdpcm_shared.trap_addr), -+ ltoh32(tr.r0), ltoh32(tr.r1), ltoh32(tr.r2), ltoh32(tr.r3), -+ ltoh32(tr.r4), ltoh32(tr.r5), ltoh32(tr.r6), ltoh32(tr.r7)); -+ -+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log); -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, -+ (uint8 *)&console_ptr, sizeof(console_ptr))) < 0) -+ goto printbuf; -+ -+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.buf_size); -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, -+ (uint8 *)&console_size, sizeof(console_size))) < 0) -+ goto printbuf; -+ -+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.idx); -+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, -+ (uint8 *)&console_index, sizeof(console_index))) < 0) -+ goto printbuf; -+ -+ console_ptr = ltoh32(console_ptr); -+ console_size = ltoh32(console_size); -+ console_index = ltoh32(console_index); -+ -+ if (console_size > CONSOLE_BUFFER_MAX || -+ !(console_buffer = MALLOC(bus->dhd->osh, console_size))) -+ goto printbuf; -+ -+ if ((rv = dhdsdio_membytes(bus, FALSE, console_ptr, -+ (uint8 *)console_buffer, console_size)) < 0) -+ goto printbuf; -+ -+ for (i = 0, n = 0; i < console_size; i += n + 1) { -+ for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { -+ ch = console_buffer[(console_index + i + n) % console_size]; -+ if (ch == '\n') -+ break; -+ line[n] = ch; -+ } -+ -+ -+ if (n > 0) { -+ if (line[n - 1] == '\r') -+ n--; -+ line[n] = 0; -+ /* Don't use DHD_ERROR macro since we print -+ * a lot of information quickly. The macro -+ * will truncate a lot of the printfs -+ */ -+ -+ if (dhd_msg_level & DHD_ERROR_VAL) -+ AP6210_DEBUG("CONSOLE: %s\n", line); -+ } -+ } -+ } -+ } -+ -+printbuf: -+ if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) { -+ AP6210_DEBUG("%s: %s\n", __FUNCTION__, strbuf.origbuf); -+ } -+ -+ -+done: -+ if (mbuffer) -+ MFREE(bus->dhd->osh, mbuffer, msize); -+ if (str) -+ MFREE(bus->dhd->osh, str, maxstrlen); -+ if (console_buffer) -+ MFREE(bus->dhd->osh, console_buffer, console_size); -+ -+ return bcmerror; -+} -+#endif /* #ifdef DHD_DEBUG */ -+ -+ -+int -+dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) -+{ -+ int bcmerror = BCME_OK; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* Basic sanity checks */ -+ if (bus->dhd->up) { -+ bcmerror = BCME_NOTDOWN; -+ goto err; -+ } -+ if (!len) { -+ bcmerror = BCME_BUFTOOSHORT; -+ goto err; -+ } -+ -+ /* Free the old ones and replace with passed variables */ -+ if (bus->vars) -+ MFREE(bus->dhd->osh, bus->vars, bus->varsz); -+ -+ bus->vars = MALLOC(bus->dhd->osh, len); -+ bus->varsz = bus->vars ? len : 0; -+ if (bus->vars == NULL) { -+ bcmerror = BCME_NOMEM; -+ goto err; -+ } -+ -+ /* Copy the passed variables, which should include the terminating double-null */ -+ bcopy(arg, bus->vars, bus->varsz); -+err: -+ return bcmerror; -+} -+ -+#ifdef DHD_DEBUG -+ -+#define CC_PLL_CHIPCTRL_SERIAL_ENAB (1 << 24) -+#define CC_CHIPCTRL_JTAG_SEL (1 << 3) -+#define CC_CHIPCTRL_GPIO_SEL (0x3) -+#define CC_PLL_CHIPCTRL_SERIAL_ENAB_4334 (1 << 28) -+ -+static int -+dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) -+{ -+ int int_val; -+ uint32 addr, data, uart_enab = 0; -+ uint32 jtag_sel = CC_CHIPCTRL_JTAG_SEL; -+ uint32 gpio_sel = CC_CHIPCTRL_GPIO_SEL; -+ -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); -+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); -+ *bcmerror = 0; -+ -+ bcmsdh_reg_write(bus->sdh, addr, 4, 1); -+ if (bcmsdh_regfail(bus->sdh)) { -+ *bcmerror = BCME_SDIO_ERROR; -+ return -1; -+ } -+ int_val = bcmsdh_reg_read(bus->sdh, data, 4); -+ if (bcmsdh_regfail(bus->sdh)) { -+ *bcmerror = BCME_SDIO_ERROR; -+ return -1; -+ } -+ if (bus->sih->chip == BCM4330_CHIP_ID) { -+ uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB; -+ } -+ else if (bus->sih->chip == BCM4334_CHIP_ID || -+ bus->sih->chip == BCM43341_CHIP_ID) { -+ if (enable) { -+ /* Moved to PMU chipcontrol 1 from 4330 */ -+ int_val &= ~gpio_sel; -+ int_val |= jtag_sel; -+ } else { -+ int_val |= gpio_sel; -+ int_val &= ~jtag_sel; -+ } -+ uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB_4334; -+ } -+ -+ if (!set) -+ return (int_val & uart_enab); -+ if (enable) -+ int_val |= uart_enab; -+ else -+ int_val &= ~uart_enab; -+ bcmsdh_reg_write(bus->sdh, data, 4, int_val); -+ if (bcmsdh_regfail(bus->sdh)) { -+ *bcmerror = BCME_SDIO_ERROR; -+ return -1; -+ } -+ if (bus->sih->chip == BCM4330_CHIP_ID) { -+ uint32 chipcontrol; -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol); -+ chipcontrol = bcmsdh_reg_read(bus->sdh, addr, 4); -+ chipcontrol &= ~jtag_sel; -+ if (enable) { -+ chipcontrol |= jtag_sel; -+ chipcontrol &= ~gpio_sel; -+ } -+ bcmsdh_reg_write(bus->sdh, addr, 4, chipcontrol); -+ } -+ -+ return (int_val & uart_enab); -+} -+#endif -+ -+static int -+dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, -+ void *params, int plen, void *arg, int len, int val_size) -+{ -+ int bcmerror = 0; -+ int32 int_val = 0; -+ bool bool_val = 0; -+ -+ AP6210_DEBUG("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", -+ __FUNCTION__, actionid, name, params, plen, arg, len, val_size); -+ -+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) -+ goto exit; -+ -+ if (plen >= (int)sizeof(int_val)) -+ bcopy(params, &int_val, sizeof(int_val)); -+ -+ bool_val = (int_val != 0) ? TRUE : FALSE; -+ -+ -+ /* Some ioctls use the bus */ -+ dhd_os_sdlock(bus->dhd); -+ -+ /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ -+ if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || -+ actionid == IOV_GVAL(IOV_DEVRESET))) { -+ bcmerror = BCME_NOTREADY; -+ goto exit; -+ } -+ -+ /* -+ * Special handling for keepSdioOn: New SDIO Wake-up Mechanism -+ */ -+ if ((vi->varid == IOV_KSO) && (IOV_ISSET(actionid))) { -+ dhdsdio_clk_kso_iovar(bus, bool_val); -+ goto exit; -+ } else if ((vi->varid == IOV_DEVSLEEP) && (IOV_ISSET(actionid))) { -+ { -+ dhdsdio_clk_devsleep_iovar(bus, bool_val); -+ if (!SLPAUTO_ENAB(bus) && (bool_val == FALSE) && (bus->ipend)) { -+ AP6210_DEBUG("INT pending in devsleep 1, dpc_sched: %d\n", -+ bus->dpc_sched); -+ if (!bus->dpc_sched) { -+ bus->dpc_sched = TRUE; -+ dhd_sched_dpc(bus->dhd); -+ } -+ } -+ } -+ goto exit; -+ } -+ -+ /* Handle sleep stuff before any clock mucking */ -+ if (vi->varid == IOV_SLEEP) { -+ if (IOV_ISSET(actionid)) { -+ bcmerror = dhdsdio_bussleep(bus, bool_val); -+ } else { -+ int_val = (int32)bus->sleeping; -+ bcopy(&int_val, arg, val_size); -+ } -+ goto exit; -+ } -+ -+ /* Request clock to allow SDIO accesses */ -+ if (!bus->dhd->dongle_reset) { -+ BUS_WAKE(bus); -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ } -+ -+ switch (actionid) { -+ case IOV_GVAL(IOV_INTR): -+ int_val = (int32)bus->intr; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_INTR): -+ bus->intr = bool_val; -+ bus->intdis = FALSE; -+ if (bus->dhd->up) { -+ if (bus->intr) { -+ AP6210_DEBUG("%s: enable SDIO device interrupts\n", __FUNCTION__); -+ bcmsdh_intr_enable(bus->sdh); -+ } else { -+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__); -+ bcmsdh_intr_disable(bus->sdh); -+ } -+ } -+ break; -+ -+ case IOV_GVAL(IOV_POLLRATE): -+ int_val = (int32)bus->pollrate; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_POLLRATE): -+ bus->pollrate = (uint)int_val; -+ bus->poll = (bus->pollrate != 0); -+ break; -+ -+ case IOV_GVAL(IOV_IDLETIME): -+ int_val = bus->idletime; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_IDLETIME): -+ if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) { -+ bcmerror = BCME_BADARG; -+ } else { -+ bus->idletime = int_val; -+ } -+ break; -+ -+ case IOV_GVAL(IOV_IDLECLOCK): -+ int_val = (int32)bus->idleclock; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_IDLECLOCK): -+ bus->idleclock = int_val; -+ break; -+ -+ case IOV_GVAL(IOV_SD1IDLE): -+ int_val = (int32)sd1idle; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_SD1IDLE): -+ sd1idle = bool_val; -+ break; -+ -+ -+ case IOV_SVAL(IOV_MEMBYTES): -+ case IOV_GVAL(IOV_MEMBYTES): -+ { -+ uint32 address; -+ uint size, dsize; -+ uint8 *data; -+ -+ bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); -+ -+ ASSERT(plen >= 2*sizeof(int)); -+ -+ address = (uint32)int_val; -+ bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val)); -+ size = (uint)int_val; -+ -+ /* Do some validation */ -+ dsize = set ? plen - (2 * sizeof(int)) : len; -+ if (dsize < size) { -+ AP6210_ERR("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n", -+ __FUNCTION__, (set ? "set" : "get"), address, size, dsize); -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ AP6210_DEBUG("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, -+ (set ? "write" : "read"), size, address); -+ -+ /* If we know about SOCRAM, check for a fit */ -+ if ((bus->orig_ramsize) && -+ ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) -+ { -+ uint8 enable, protect, remap; -+ si_socdevram(bus->sih, FALSE, &enable, &protect, &remap); -+ if (!enable || protect) { -+ AP6210_ERR("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", -+ __FUNCTION__, bus->orig_ramsize, size, address); -+ AP6210_DEBUG("%s: socram enable %d, protect %d\n", -+ __FUNCTION__, enable, protect); -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ if (!REMAP_ENAB(bus) && (address >= SOCDEVRAM_ARM_ADDR)) { -+ uint32 devramsize = si_socdevram_size(bus->sih); -+ if ((address < SOCDEVRAM_ARM_ADDR) || -+ (address + size > (SOCDEVRAM_ARM_ADDR + devramsize))) { -+ AP6210_ERR("%s: bad address 0x%08x, size 0x%08x\n", -+ __FUNCTION__, address, size); -+ AP6210_DEBUG("%s: socram range 0x%08x,size 0x%08x\n", -+ __FUNCTION__, SOCDEVRAM_ARM_ADDR, devramsize); -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ /* move it such that address is real now */ -+ address -= SOCDEVRAM_ARM_ADDR; -+ address += SOCDEVRAM_BP_ADDR; -+ AP6210_DEBUG("%s: Request to %s %d bytes @ Mapped address 0x%08x\n", -+ __FUNCTION__, (set ? "write" : "read"), size, address); -+ } else if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address) && remap) { -+ /* Can not access remap region while devram remap bit is set -+ * ROM content would be returned in this case -+ */ -+ AP6210_ERR("%s: Need to disable remap for address 0x%08x\n", -+ __FUNCTION__, address); -+ bcmerror = BCME_ERROR; -+ break; -+ } -+ } -+ -+ /* Generate the actual data pointer */ -+ data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; -+ -+ /* Call to do the transfer */ -+ bcmerror = dhdsdio_membytes(bus, set, address, data, size); -+ -+ break; -+ } -+ -+ case IOV_GVAL(IOV_MEMSIZE): -+ int_val = (int32)bus->ramsize; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_SDIOD_DRIVE): -+ int_val = (int32)dhd_sdiod_drive_strength; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_SDIOD_DRIVE): -+ dhd_sdiod_drive_strength = int_val; -+ si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength); -+ break; -+ -+ case IOV_SVAL(IOV_SET_DOWNLOAD_STATE): -+ bcmerror = dhdsdio_download_state(bus, bool_val); -+ break; -+ -+ case IOV_SVAL(IOV_SOCRAM_STATE): -+ bcmerror = dhdsdio_download_state(bus, bool_val); -+ break; -+ -+ case IOV_SVAL(IOV_VARS): -+ bcmerror = dhdsdio_downloadvars(bus, arg, len); -+ break; -+ -+ case IOV_GVAL(IOV_READAHEAD): -+ int_val = (int32)dhd_readahead; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_READAHEAD): -+ if (bool_val && !dhd_readahead) -+ bus->nextlen = 0; -+ dhd_readahead = bool_val; -+ break; -+ -+ case IOV_GVAL(IOV_SDRXCHAIN): -+ int_val = (int32)bus->use_rxchain; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_SDRXCHAIN): -+ if (bool_val && !bus->sd_rxchain) -+ bcmerror = BCME_UNSUPPORTED; -+ else -+ bus->use_rxchain = bool_val; -+ break; -+ case IOV_GVAL(IOV_ALIGNCTL): -+ int_val = (int32)dhd_alignctl; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_ALIGNCTL): -+ dhd_alignctl = bool_val; -+ break; -+ -+ case IOV_GVAL(IOV_SDALIGN): -+ int_val = DHD_SDALIGN; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+#ifdef DHD_DEBUG -+ case IOV_GVAL(IOV_VARS): -+ if (bus->varsz < (uint)len) -+ bcopy(bus->vars, arg, bus->varsz); -+ else -+ bcmerror = BCME_BUFTOOSHORT; -+ break; -+#endif /* DHD_DEBUG */ -+ -+#ifdef DHD_DEBUG -+ case IOV_GVAL(IOV_SDREG): -+ { -+ sdreg_t *sd_ptr; -+ uint32 addr, size; -+ -+ sd_ptr = (sdreg_t *)params; -+ -+ addr = (uintptr)bus->regs + sd_ptr->offset; -+ size = sd_ptr->func; -+ int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); -+ if (bcmsdh_regfail(bus->sdh)) -+ bcmerror = BCME_SDIO_ERROR; -+ bcopy(&int_val, arg, sizeof(int32)); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_SDREG): -+ { -+ sdreg_t *sd_ptr; -+ uint32 addr, size; -+ -+ sd_ptr = (sdreg_t *)params; -+ -+ addr = (uintptr)bus->regs + sd_ptr->offset; -+ size = sd_ptr->func; -+ bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); -+ if (bcmsdh_regfail(bus->sdh)) -+ bcmerror = BCME_SDIO_ERROR; -+ break; -+ } -+ -+ /* Same as above, but offset is not backplane (not SDIO core) */ -+ case IOV_GVAL(IOV_SBREG): -+ { -+ sdreg_t sdreg; -+ uint32 addr, size; -+ -+ bcopy(params, &sdreg, sizeof(sdreg)); -+ -+ addr = SI_ENUM_BASE + sdreg.offset; -+ size = sdreg.func; -+ int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size); -+ if (bcmsdh_regfail(bus->sdh)) -+ bcmerror = BCME_SDIO_ERROR; -+ bcopy(&int_val, arg, sizeof(int32)); -+ break; -+ } -+ -+ case IOV_SVAL(IOV_SBREG): -+ { -+ sdreg_t sdreg; -+ uint32 addr, size; -+ -+ bcopy(params, &sdreg, sizeof(sdreg)); -+ -+ addr = SI_ENUM_BASE + sdreg.offset; -+ size = sdreg.func; -+ bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); -+ if (bcmsdh_regfail(bus->sdh)) -+ bcmerror = BCME_SDIO_ERROR; -+ break; -+ } -+ -+ case IOV_GVAL(IOV_SDCIS): -+ { -+ *(char *)arg = 0; -+ -+ bcmstrcat(arg, "\nFunc 0\n"); -+ bcmsdh_cis_read(bus->sdh, 0x10, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); -+ bcmstrcat(arg, "\nFunc 1\n"); -+ bcmsdh_cis_read(bus->sdh, 0x11, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); -+ bcmstrcat(arg, "\nFunc 2\n"); -+ bcmsdh_cis_read(bus->sdh, 0x12, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); -+ break; -+ } -+ -+ case IOV_GVAL(IOV_FORCEEVEN): -+ int_val = (int32)forcealign; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_FORCEEVEN): -+ forcealign = bool_val; -+ break; -+ -+ case IOV_GVAL(IOV_TXBOUND): -+ int_val = (int32)dhd_txbound; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_TXBOUND): -+ dhd_txbound = (uint)int_val; -+ break; -+ -+ case IOV_GVAL(IOV_RXBOUND): -+ int_val = (int32)dhd_rxbound; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_RXBOUND): -+ dhd_rxbound = (uint)int_val; -+ break; -+ -+ case IOV_GVAL(IOV_TXMINMAX): -+ int_val = (int32)dhd_txminmax; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_TXMINMAX): -+ dhd_txminmax = (uint)int_val; -+ break; -+ -+ case IOV_GVAL(IOV_SERIALCONS): -+ int_val = dhd_serialconsole(bus, FALSE, 0, &bcmerror); -+ if (bcmerror != 0) -+ break; -+ -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_SERIALCONS): -+ dhd_serialconsole(bus, TRUE, bool_val, &bcmerror); -+ break; -+ -+ -+ -+#endif /* DHD_DEBUG */ -+ -+ -+#ifdef SDTEST -+ case IOV_GVAL(IOV_EXTLOOP): -+ int_val = (int32)bus->ext_loop; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_EXTLOOP): -+ bus->ext_loop = bool_val; -+ break; -+ -+ case IOV_GVAL(IOV_PKTGEN): -+ bcmerror = dhdsdio_pktgen_get(bus, arg); -+ break; -+ -+ case IOV_SVAL(IOV_PKTGEN): -+ bcmerror = dhdsdio_pktgen_set(bus, arg); -+ break; -+#endif /* SDTEST */ -+ -+#if defined(SDIO_CRC_ERROR_FIX) -+ case IOV_GVAL(IOV_WATERMARK): -+ int_val = (int32)watermark; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_WATERMARK): -+ watermark = (uint)int_val; -+ watermark = (watermark > SBSDIO_WATERMARK_MASK) ? SBSDIO_WATERMARK_MASK : watermark; -+ AP6210_DEBUG("Setting watermark as 0x%x.\n", watermark); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, NULL); -+ break; -+ -+ case IOV_GVAL(IOV_MESBUSYCTRL): -+ int_val = (int32)mesbusyctrl; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_MESBUSYCTRL): -+ mesbusyctrl = (uint)int_val; -+ mesbusyctrl = (mesbusyctrl > SBSDIO_MESBUSYCTRL_MASK) -+ ? SBSDIO_MESBUSYCTRL_MASK : mesbusyctrl; -+ AP6210_DEBUG("Setting mesbusyctrl as 0x%x.\n", mesbusyctrl); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, -+ ((uint8)mesbusyctrl | 0x80), NULL); -+ break; -+#endif /* SDIO_CRC_ERROR_FIX */ -+ -+ case IOV_GVAL(IOV_DONGLEISOLATION): -+ int_val = bus->dhd->dongle_isolation; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_DONGLEISOLATION): -+ bus->dhd->dongle_isolation = bool_val; -+ break; -+ -+ case IOV_SVAL(IOV_DEVRESET): -+ AP6210_DEBUG("%s: Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n", -+ __FUNCTION__, bool_val, bus->dhd->dongle_reset, -+ bus->dhd->busstate); -+ -+ ASSERT(bus->dhd->osh); -+ /* ASSERT(bus->cl_devid); */ -+ -+ dhd_bus_devreset(bus->dhd, (uint8)bool_val); -+ -+ break; -+#ifdef SOFTAP -+ case IOV_GVAL(IOV_FWPATH): -+ { -+ uint32 fw_path_len; -+ -+ fw_path_len = strlen(bus->fw_path); -+ AP6210_DEBUG("[softap] get fwpath, l=%d\n", len); -+ -+ if (fw_path_len > len-1) { -+ bcmerror = BCME_BUFTOOSHORT; -+ break; -+ } -+ -+ if (fw_path_len) { -+ bcopy(bus->fw_path, arg, fw_path_len); -+ ((uchar*)arg)[fw_path_len] = 0; -+ } -+ break; -+ } -+ -+ case IOV_SVAL(IOV_FWPATH): -+ AP6210_DEBUG("[softap] set fwpath, idx=%d\n", int_val); -+ -+ switch (int_val) { -+ case 1: -+ bus->fw_path = fw_path; /* ordinary one */ -+ break; -+ case 2: -+ bus->fw_path = fw_path2; -+ break; -+ default: -+ bcmerror = BCME_BADARG; -+ break; -+ } -+ -+ AP6210_DEBUG("[softap] new fw path: %s\n", (bus->fw_path[0] ? bus->fw_path : "NULL")); -+ break; -+ -+#endif /* SOFTAP */ -+ case IOV_GVAL(IOV_DEVRESET): -+ AP6210_DEBUG("%s: Called get IOV_DEVRESET\n", __FUNCTION__); -+ -+ /* Get its status */ -+ int_val = (bool) bus->dhd->dongle_reset; -+ bcopy(&int_val, arg, val_size); -+ -+ break; -+ -+ case IOV_GVAL(IOV_KSO): -+ int_val = dhdsdio_sleepcsr_get(bus); -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_GVAL(IOV_DEVCAP): -+ int_val = dhdsdio_devcap_get(bus); -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_DEVCAP): -+ dhdsdio_devcap_set(bus, (uint8) int_val); -+ break; -+ -+#ifdef BCMSDIOH_TXGLOM -+ case IOV_GVAL(IOV_TXGLOMSIZE): -+ int_val = (int32)bus->glomsize; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_TXGLOMSIZE): -+ if (int_val > SDPCM_MAXGLOM_SIZE) { -+ bcmerror = BCME_ERROR; -+ } else { -+ bus->glomsize = (uint)int_val; -+ } -+ break; -+ case IOV_GVAL(IOV_TXGLOMMODE): -+ int_val = (int32)bus->glom_mode; -+ bcopy(&int_val, arg, val_size); -+ break; -+ -+ case IOV_SVAL(IOV_TXGLOMMODE): -+ if ((int_val != SDPCM_TXGLOM_CPY) && (int_val != SDPCM_TXGLOM_MDESC)) { -+ bcmerror = BCME_RANGE; -+ } else { -+ if ((bus->glom_mode = bcmsdh_set_mode(bus->sdh, (uint)int_val)) != int_val) -+ bcmerror = BCME_ERROR; -+ } -+ break; -+#endif /* BCMSDIOH_TXGLOM */ -+ default: -+ bcmerror = BCME_UNSUPPORTED; -+ break; -+ } -+ -+exit: -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, TRUE); -+ } -+ -+ dhd_os_sdunlock(bus->dhd); -+ -+ return bcmerror; -+} -+ -+static int -+dhdsdio_write_vars(dhd_bus_t *bus) -+{ -+ int bcmerror = 0; -+ uint32 varsize, phys_size; -+ uint32 varaddr; -+ uint8 *vbuffer; -+ uint32 varsizew; -+#ifdef DHD_DEBUG -+ uint8 *nvram_ularray; -+#endif /* DHD_DEBUG */ -+ -+ /* Even if there are no vars are to be written, we still need to set the ramsize. */ -+ varsize = bus->varsz ? ROUNDUP(bus->varsz, 4) : 0; -+ varaddr = (bus->ramsize - 4) - varsize; -+ -+ varaddr += bus->dongle_ram_base; -+ -+ if (bus->vars) { -+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 7)) { -+ if (((varaddr & 0x3C) == 0x3C) && (varsize > 4)) { -+ AP6210_DEBUG("PR85623WAR in place\n"); -+ varsize += 4; -+ varaddr -= 4; -+ } -+ } -+ -+ vbuffer = (uint8 *)MALLOC(bus->dhd->osh, varsize); -+ if (!vbuffer) -+ return BCME_NOMEM; -+ -+ bzero(vbuffer, varsize); -+ bcopy(bus->vars, vbuffer, bus->varsz); -+ -+ /* Write the vars list */ -+ bcmerror = dhdsdio_membytes(bus, TRUE, varaddr, vbuffer, varsize); -+#ifdef DHD_DEBUG -+ /* Verify NVRAM bytes */ -+ AP6210_DEBUG("Compare NVRAM dl & ul; varsize=%d\n", varsize); -+ nvram_ularray = (uint8*)MALLOC(bus->dhd->osh, varsize); -+ if (!nvram_ularray) -+ return BCME_NOMEM; -+ -+ /* Upload image to verify downloaded contents. */ -+ memset(nvram_ularray, 0xaa, varsize); -+ -+ /* Read the vars list to temp buffer for comparison */ -+ bcmerror = dhdsdio_membytes(bus, FALSE, varaddr, nvram_ularray, varsize); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on reading %d nvram bytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, varsize, varaddr); -+ } -+ /* Compare the org NVRAM with the one read from RAM */ -+ if (memcmp(vbuffer, nvram_ularray, varsize)) { -+ AP6210_ERR("%s: Downloaded NVRAM image is corrupted.\n", __FUNCTION__); -+ } else -+ AP6210_DEBUG("%s: Download, Upload and compare of NVRAM succeeded.\n", -+ __FUNCTION__); -+ -+ MFREE(bus->dhd->osh, nvram_ularray, varsize); -+#endif /* DHD_DEBUG */ -+ -+ MFREE(bus->dhd->osh, vbuffer, varsize); -+ } -+ -+ phys_size = REMAP_ENAB(bus) ? bus->ramsize : bus->orig_ramsize; -+ -+ phys_size += bus->dongle_ram_base; -+ -+ /* adjust to the user specified RAM */ -+ AP6210_DEBUG("Physical memory size: %d, usable memory size: %d\n", -+ phys_size, bus->ramsize); -+ AP6210_DEBUG("Vars are at %d, orig varsize is %d\n", -+ varaddr, varsize); -+ varsize = ((phys_size - 4) - varaddr); -+ -+ /* -+ * Determine the length token: -+ * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits. -+ */ -+ if (bcmerror) { -+ varsizew = 0; -+ } else { -+ varsizew = varsize / 4; -+ varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); -+ varsizew = htol32(varsizew); -+ } -+ -+ AP6210_DEBUG("New varsize is %d, length token=0x%08x\n", varsize, varsizew); -+ -+ /* Write the length token to the last word */ -+ bcmerror = dhdsdio_membytes(bus, TRUE, (phys_size - 4), -+ (uint8*)&varsizew, 4); -+ -+ return bcmerror; -+} -+ -+static int -+dhdsdio_download_state(dhd_bus_t *bus, bool enter) -+{ -+ uint retries; -+ int bcmerror = 0; -+ int foundcr4 = 0; -+ -+ /* To enter download state, disable ARM and reset SOCRAM. -+ * To exit download state, simply reset ARM (default is RAM boot). -+ */ -+ if (enter) { -+ bus->alp_only = TRUE; -+ -+ if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && -+ !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { -+ if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { -+ foundcr4 = 1; -+ } else { -+ AP6210_ERR("%s: Failed to find ARM core!\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ } -+ -+ if (!foundcr4) { -+ si_core_disable(bus->sih, 0); -+ if (bcmsdh_regfail(bus->sdh)) { -+ bcmerror = BCME_SDIO_ERROR; -+ goto fail; -+ } -+ -+ if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { -+ AP6210_ERR("%s: Failed to find SOCRAM core!\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ -+ si_core_reset(bus->sih, 0, 0); -+ if (bcmsdh_regfail(bus->sdh)) { -+ AP6210_ERR("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__); -+ bcmerror = BCME_SDIO_ERROR; -+ goto fail; -+ } -+ -+ /* Disable remap for download */ -+ if (REMAP_ENAB(bus) && si_socdevram_remap_isenb(bus->sih)) -+ dhdsdio_devram_remap(bus, FALSE); -+ -+ /* Clear the top bit of memory */ -+ if (bus->ramsize) { -+ uint32 zeros = 0; -+ if (dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4) < 0) { -+ bcmerror = BCME_SDIO_ERROR; -+ goto fail; -+ } -+ } -+ } else { -+ /* For CR4, -+ * Halt ARM -+ * Remove ARM reset -+ * Read RAM base address [0x18_0000] -+ * [next] Download firmware -+ * [done at else] Populate the reset vector -+ * [done at else] Remove ARM halt -+ */ -+ /* Halt ARM & remove reset */ -+ si_core_reset(bus->sih, SICF_CPUHALT, SICF_CPUHALT); -+ } -+ } else { -+ if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { -+ if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { -+ AP6210_ERR("%s: Failed to find SOCRAM core!\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ -+ if (!si_iscoreup(bus->sih)) { -+ AP6210_ERR("%s: SOCRAM core is down after reset?\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ -+ if ((bcmerror = dhdsdio_write_vars(bus))) { -+ AP6210_ERR("%s: could not write vars to RAM\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ /* Enable remap before ARM reset but after vars. -+ * No backplane access in remap mode -+ */ -+ if (REMAP_ENAB(bus) && !si_socdevram_remap_isenb(bus->sih)) -+ dhdsdio_devram_remap(bus, TRUE); -+ -+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && -+ !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { -+ AP6210_ERR("%s: Can't change back to SDIO core?\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); -+ -+ -+ if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && -+ !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { -+ AP6210_ERR("%s: Failed to find ARM core!\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ } else { -+ /* cr4 has no socram, but tcm's */ -+ /* write vars */ -+ if ((bcmerror = dhdsdio_write_vars(bus))) { -+ AP6210_ERR("%s: could not write vars to RAM\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && -+ !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { -+ AP6210_ERR("%s: Can't change back to SDIO core?\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); -+ -+ /* switch back to arm core again */ -+ if (!(si_setcore(bus->sih, ARMCR4_CORE_ID, 0))) { -+ AP6210_ERR("%s: Failed to find ARM CR4 core!\n", __FUNCTION__); -+ bcmerror = BCME_ERROR; -+ goto fail; -+ } -+ /* write address 0 with reset instruction */ -+ bcmerror = dhdsdio_membytes(bus, TRUE, 0, -+ (uint8 *)&bus->resetinstr, sizeof(bus->resetinstr)); -+ -+ /* now remove reset and halt and continue to run CR4 */ -+ } -+ -+ si_core_reset(bus->sih, 0, 0); -+ if (bcmsdh_regfail(bus->sdh)) { -+ AP6210_ERR("%s: Failure trying to reset ARM core?\n", __FUNCTION__); -+ bcmerror = BCME_SDIO_ERROR; -+ goto fail; -+ } -+ -+ /* Allow HT Clock now that the ARM is running. */ -+ bus->alp_only = FALSE; -+ -+ bus->dhd->busstate = DHD_BUS_LOAD; -+ } -+ -+fail: -+ /* Always return to SDIOD core */ -+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) -+ si_setcore(bus->sih, SDIOD_CORE_ID, 0); -+ -+ return bcmerror; -+} -+ -+int -+dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, -+ void *params, int plen, void *arg, int len, bool set) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ const bcm_iovar_t *vi = NULL; -+ int bcmerror = 0; -+ int val_size; -+ uint32 actionid; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(name); -+ ASSERT(len >= 0); -+ -+ /* Get MUST have return space */ -+ ASSERT(set || (arg && len)); -+ -+ /* Set does NOT take qualifiers */ -+ ASSERT(!set || (!params && !plen)); -+ -+ /* Look up var locally; if not found pass to host driver */ -+ if ((vi = bcm_iovar_lookup(dhdsdio_iovars, name)) == NULL) { -+ dhd_os_sdlock(bus->dhd); -+ -+ BUS_WAKE(bus); -+ -+ /* Turn on clock in case SD command needs backplane */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ bcmerror = bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, set); -+ -+ /* Check for bus configuration changes of interest */ -+ -+ /* If it was divisor change, read the new one */ -+ if (set && strcmp(name, "sd_divisor") == 0) { -+ if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, -+ &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { -+ bus->sd_divisor = -1; -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, name); -+ } else { -+ AP6210_DEBUG("%s: noted %s update, value now %d\n", -+ __FUNCTION__, name, bus->sd_divisor); -+ } -+ } -+ /* If it was a mode change, read the new one */ -+ if (set && strcmp(name, "sd_mode") == 0) { -+ if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, -+ &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { -+ bus->sd_mode = -1; -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, name); -+ } else { -+ AP6210_DEBUG("%s: noted %s update, value now %d\n", -+ __FUNCTION__, name, bus->sd_mode); -+ } -+ } -+ /* Similar check for blocksize change */ -+ if (set && strcmp(name, "sd_blocksize") == 0) { -+ int32 fnum = 2; -+ if (bcmsdh_iovar_op(bus->sdh, "sd_blocksize", &fnum, sizeof(int32), -+ &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { -+ bus->blocksize = 0; -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize"); -+ } else { -+ AP6210_DEBUG("%s: noted %s update, value now %d\n", -+ __FUNCTION__, "sd_blocksize", bus->blocksize); -+ } -+ } -+ bus->roundup = MIN(max_roundup, bus->blocksize); -+ -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, TRUE); -+ } -+ -+ dhd_os_sdunlock(bus->dhd); -+ goto exit; -+ } -+ -+ AP6210_DEBUG("%s: %s %s, len %d plen %d\n", __FUNCTION__, -+ name, (set ? "set" : "get"), len, plen); -+ -+ /* set up 'params' pointer in case this is a set command so that -+ * the convenience int and bool code can be common to set and get -+ */ -+ if (params == NULL) { -+ params = arg; -+ plen = len; -+ } -+ -+ if (vi->type == IOVT_VOID) -+ val_size = 0; -+ else if (vi->type == IOVT_BUFFER) -+ val_size = len; -+ else -+ /* all other types are integer sized */ -+ val_size = sizeof(int); -+ -+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); -+ bcmerror = dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, val_size); -+ -+exit: -+ return bcmerror; -+} -+ -+void -+dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) -+{ -+ osl_t *osh; -+ uint32 local_hostintmask; -+ uint8 saveclk, dat; -+ uint retries; -+ int err; -+ if (!bus->dhd) -+ return; -+ -+ osh = bus->dhd->osh; -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ bcmsdh_waitlockfree(NULL); -+ -+ if (enforce_mutex) -+ dhd_os_sdlock(bus->dhd); -+ -+ if ((bus->dhd->busstate == DHD_BUS_DOWN) || bus->dhd->hang_was_sent) { -+ /* if Firmware already hangs disbale any interrupt */ -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ bus->hostintmask = 0; -+ bcmsdh_intr_disable(bus->sdh); -+ } else { -+ BUS_WAKE(bus); -+ -+ if (KSO_ENAB(bus)) { -+ /* Mask the interrupt */ -+ dat = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, NULL); -+ dat &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, dat, NULL); -+ } -+ -+ /* Change our idea of bus state */ -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ -+ if (KSO_ENAB(bus)) { -+ -+ /* Enable clock for device interrupts */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ /* Disable and clear interrupts at the chip level also */ -+ W_SDREG(0, &bus->regs->hostintmask, retries); -+ local_hostintmask = bus->hostintmask; -+ bus->hostintmask = 0; -+ -+ /* Force clocks on backplane to be sure F2 interrupt propagates */ -+ saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ if (!err) { -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ (saveclk | SBSDIO_FORCE_HT), &err); -+ } -+ if (err) { -+ AP6210_ERR("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err); -+ } -+ -+ /* Turn off the bus (F2), free any pending packets */ -+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__); -+ bcmsdh_intr_disable(bus->sdh); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); -+ -+ /* Clear any pending interrupts now that F2 is disabled */ -+ W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); -+ } -+ -+ /* Turn off the backplane clock (only) */ -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ } -+ -+ /* Clear the data packet queues */ -+ pktq_flush(osh, &bus->txq, TRUE, NULL, 0); -+ -+ /* Clear any held glomming stuff */ -+ if (bus->glomd) -+ PKTFREE(osh, bus->glomd, FALSE); -+ -+ if (bus->glom) -+ PKTFREE(osh, bus->glom, FALSE); -+ -+ bus->glom = bus->glomd = NULL; -+ -+ /* Clear rx control and wake any waiters */ -+ bus->rxlen = 0; -+ dhd_os_ioctl_resp_wake(bus->dhd); -+ -+ /* Reset some F2 state stuff */ -+ bus->rxskip = FALSE; -+ bus->tx_seq = bus->rx_seq = 0; -+ -+ if (enforce_mutex) -+ dhd_os_sdunlock(bus->dhd); -+} -+ -+#ifdef BCMSDIOH_TXGLOM -+void -+dhd_txglom_enable(dhd_pub_t *dhdp, bool enable) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ -+ char buf[256]; -+ uint32 rxglom; -+ int32 ret; -+ -+ if (enable) { -+ rxglom = 1; -+ memset(buf, 0, sizeof(buf)); -+ bcm_mkiovar("bus:rxglom", -+ (void *)&rxglom, -+ 4, buf, sizeof(buf)); -+ ret = dhd_wl_ioctl_cmd(dhdp, -+ WLC_SET_VAR, buf, -+ sizeof(buf), TRUE, 0); -+ if (!(ret < 0)) { -+ bus->glom_enable = TRUE; -+ } -+ } else { -+ bus->glom_enable = FALSE; -+ } -+} -+#endif /* BCMSDIOH_TXGLOM */ -+ -+int -+dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ dhd_timeout_t tmo; -+ uint retries = 0; -+ uint8 ready, enable; -+ int err, ret = 0; -+ uint8 saveclk; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ ASSERT(bus->dhd); -+ if (!bus->dhd) -+ return 0; -+ -+ if (enforce_mutex) -+ dhd_os_sdlock(bus->dhd); -+ -+ /* Make sure backplane clock is on, needed to generate F2 interrupt */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ if (bus->clkstate != CLK_AVAIL) { -+ AP6210_ERR("%s: clock state is wrong. state = %d\n", __FUNCTION__, bus->clkstate); -+ ret = -1; -+ goto exit; -+ } -+ -+ -+ /* Force clocks on backplane to be sure F2 interrupt propagates */ -+ saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ if (!err) { -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ (saveclk | SBSDIO_FORCE_HT), &err); -+ } -+ if (err) { -+ AP6210_ERR("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err); -+ ret = -1; -+ goto exit; -+ } -+ -+ /* Enable function 2 (frame transfers) */ -+ W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT), -+ &bus->regs->tosbmailboxdata, retries); -+ enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); -+ -+ /* Give the dongle some time to do its thing and set IOR2 */ -+ dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000); -+ -+ ready = 0; -+ while (ready != enable && !dhd_timeout_expired(&tmo)) -+ ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL); -+ -+ AP6210_DEBUG("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", -+ __FUNCTION__, enable, ready, tmo.elapsed); -+ -+ -+ /* If F2 successfully enabled, set core and enable interrupts */ -+ if (ready == enable) { -+ /* Make sure we're talking to the core. */ -+ if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0))) -+ bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0); -+ ASSERT(bus->regs != NULL); -+ -+ /* Set up the interrupt mask and enable interrupts */ -+ bus->hostintmask = HOSTINTMASK; -+ /* corerev 4 could use the newer interrupt logic to detect the frames */ -+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 4) && -+ (bus->rxint_mode != SDIO_DEVICE_HMB_RXINT)) { -+ bus->hostintmask &= ~I_HMB_FRAME_IND; -+ bus->hostintmask |= I_XMTDATA_AVAIL; -+ } -+ W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); -+#ifdef SDIO_CRC_ERROR_FIX -+ if (bus->blocksize < 512) { -+ mesbusyctrl = watermark = bus->blocksize / 4; -+ } -+#endif /* SDIO_CRC_ERROR_FIX */ -+ -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); -+#ifdef SDIO_CRC_ERROR_FIX -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, -+ (uint8)mesbusyctrl|0x80, &err); -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, -+ SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK, NULL); -+#endif /* SDIO_CRC_ERROR_FIX */ -+ -+ /* Set bus state according to enable result */ -+ dhdp->busstate = DHD_BUS_DATA; -+ -+ /* bcmsdh_intr_unmask(bus->sdh); */ -+ -+ bus->intdis = FALSE; -+ if (bus->intr) { -+ AP6210_DEBUG("%s: enable SDIO device interrupts\n", __FUNCTION__); -+ bcmsdh_intr_enable(bus->sdh); -+ } else { -+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__); -+ bcmsdh_intr_disable(bus->sdh); -+ } -+ -+ } -+ -+ -+ else { -+ /* Disable F2 again */ -+ enable = SDIO_FUNC_ENABLE_1; -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); -+ } -+ -+ if (dhdsdio_sr_cap(bus)) -+ dhdsdio_sr_init(bus); -+ else -+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); -+ -+ /* If we didn't come up, turn off backplane clock */ -+ if (dhdp->busstate != DHD_BUS_DATA) -+ dhdsdio_clkctl(bus, CLK_NONE, FALSE); -+ -+exit: -+ if (enforce_mutex) -+ dhd_os_sdunlock(bus->dhd); -+ -+ return ret; -+} -+ -+static void -+dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) -+{ -+ bcmsdh_info_t *sdh = bus->sdh; -+ sdpcmd_regs_t *regs = bus->regs; -+ uint retries = 0; -+ uint16 lastrbc; -+ uint8 hi, lo; -+ int err; -+ -+ AP6210_ERR("%s: %sterminate frame%s\n", __FUNCTION__, -+ (abort ? "abort command, " : ""), (rtx ? ", send NAK" : "")); -+ -+ if (!KSO_ENAB(bus)) { -+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__); -+ return; -+ } -+ -+ if (abort) { -+ bcmsdh_abort(sdh, SDIO_FUNC_2); -+ } -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); -+ bus->f1regdata++; -+ -+ /* Wait until the packet has been flushed (device/FIFO stable) */ -+ for (lastrbc = retries = 0xffff; retries > 0; retries--) { -+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); -+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); -+ bus->f1regdata += 2; -+ -+ if ((hi == 0) && (lo == 0)) -+ break; -+ -+ if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { -+ AP6210_DEBUG("%s: count growing: last 0x%04x now 0x%04x\n", -+ __FUNCTION__, lastrbc, ((hi << 8) + lo)); -+ } -+ lastrbc = (hi << 8) + lo; -+ } -+ -+ if (!retries) { -+ AP6210_ERR("%s: count never zeroed: last 0x%04x\n", __FUNCTION__, lastrbc); -+ } else { -+ AP6210_DEBUG("%s: flush took %d iterations\n", __FUNCTION__, (0xffff - retries)); -+ } -+ -+ if (rtx) { -+ bus->rxrtx++; -+ W_SDREG(SMB_NAK, ®s->tosbmailbox, retries); -+ bus->f1regdata++; -+ if (retries <= retry_limit) { -+ bus->rxskip = TRUE; -+ } -+ } -+ -+ /* Clear partial in any case */ -+ bus->nextlen = 0; -+ -+ /* If we can't reach the device, signal failure */ -+ if (err || bcmsdh_regfail(sdh)) -+ bus->dhd->busstate = DHD_BUS_DOWN; -+} -+ -+static void -+dhdsdio_read_control(dhd_bus_t *bus, uint8 *hdr, uint len, uint doff) -+{ -+ bcmsdh_info_t *sdh = bus->sdh; -+ uint rdlen, pad; -+ -+ int sdret; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* Control data already received in aligned rxctl */ -+ if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) -+ goto gotpkt; -+ -+ ASSERT(bus->rxbuf); -+ /* Set rxctl for frame (w/optional alignment) */ -+ bus->rxctl = bus->rxbuf; -+ if (dhd_alignctl) { -+ bus->rxctl += firstread; -+ if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) -+ bus->rxctl += (DHD_SDALIGN - pad); -+ bus->rxctl -= firstread; -+ } -+ ASSERT(bus->rxctl >= bus->rxbuf); -+ -+ /* Copy the already-read portion over */ -+ bcopy(hdr, bus->rxctl, firstread); -+ if (len <= firstread) -+ goto gotpkt; -+ -+ /* Copy the full data pkt in gSPI case and process ioctl. */ -+ if (bus->bus == SPI_BUS) { -+ bcopy(hdr, bus->rxctl, len); -+ goto gotpkt; -+ } -+ -+ /* Raise rdlen to next SDIO block to avoid tail command */ -+ rdlen = len - firstread; -+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { -+ pad = bus->blocksize - (rdlen % bus->blocksize); -+ if ((pad <= bus->roundup) && (pad < bus->blocksize) && -+ ((len + pad) < bus->dhd->maxctl)) -+ rdlen += pad; -+ } else if (rdlen % DHD_SDALIGN) { -+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); -+ } -+ -+ /* Satisfy length-alignment requirements */ -+ if (forcealign && (rdlen & (ALIGNMENT - 1))) -+ rdlen = ROUNDUP(rdlen, ALIGNMENT); -+ -+ /* Drop if the read is too big or it exceeds our maximum */ -+ if ((rdlen + firstread) > bus->dhd->maxctl) { -+ AP6210_ERR("%s: %d-byte control read exceeds %d-byte buffer\n", -+ __FUNCTION__, rdlen, bus->dhd->maxctl); -+ bus->dhd->rx_errors++; -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ goto done; -+ } -+ -+ if ((len - doff) > bus->dhd->maxctl) { -+ AP6210_ERR("%s: %d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", -+ __FUNCTION__, len, (len - doff), bus->dhd->maxctl); -+ bus->dhd->rx_errors++; bus->rx_toolong++; -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ goto done; -+ } -+ -+ -+ /* Read remainder of frame body into the rxctl buffer */ -+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ (bus->rxctl + firstread), rdlen, NULL, NULL, NULL); -+ bus->f2rxdata++; -+ ASSERT(sdret != BCME_PENDING); -+ -+ /* Control frame failures need retransmission */ -+ if (sdret < 0) { -+ AP6210_ERR("%s: read %d control bytes failed: %d\n", __FUNCTION__, rdlen, sdret); -+ bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */ -+ dhdsdio_rxfail(bus, TRUE, TRUE); -+ goto done; -+ } -+ -+gotpkt: -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_CTL_ON()) { -+ prhex("RxCtrl", bus->rxctl, len); -+ } -+#endif -+ -+ /* Point to valid data and indicate its length */ -+ bus->rxctl += doff; -+ bus->rxlen = len - doff; -+ -+done: -+ /* Awake any waiters */ -+ dhd_os_ioctl_resp_wake(bus->dhd); -+} -+ -+static uint8 -+dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) -+{ -+ uint16 dlen, totlen; -+ uint8 *dptr, num = 0; -+ -+ uint16 sublen, check; -+ void *pfirst, *plast, *pnext; -+ void * list_tail[DHD_MAX_IFS] = { NULL }; -+ void * list_head[DHD_MAX_IFS] = { NULL }; -+ uint8 idx; -+ osl_t *osh = bus->dhd->osh; -+ -+ int errcode; -+ uint8 chan, seq, doff, sfdoff; -+ uint8 txmax; -+ uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN]; -+ uint reorder_info_len; -+ -+ int ifidx = 0; -+ bool usechain = bus->use_rxchain; -+ -+ /* If packets, issue read(s) and send up packet chain */ -+ /* Return sequence numbers consumed? */ -+ -+ AP6210_DEBUG("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, bus->glom); -+ -+ /* If there's a descriptor, generate the packet chain */ -+ if (bus->glomd) { -+ dhd_os_sdlock_rxq(bus->dhd); -+ -+ pfirst = plast = pnext = NULL; -+ dlen = (uint16)PKTLEN(osh, bus->glomd); -+ dptr = PKTDATA(osh, bus->glomd); -+ if (!dlen || (dlen & 1)) { -+ AP6210_ERR("%s: bad glomd len (%d), ignore descriptor\n", -+ __FUNCTION__, dlen); -+ dlen = 0; -+ } -+ -+ for (totlen = num = 0; dlen; num++) { -+ /* Get (and move past) next length */ -+ sublen = ltoh16_ua(dptr); -+ dlen -= sizeof(uint16); -+ dptr += sizeof(uint16); -+ if ((sublen < SDPCM_HDRLEN_RX) || -+ ((num == 0) && (sublen < (2 * SDPCM_HDRLEN_RX)))) { -+ AP6210_ERR("%s: descriptor len %d bad: %d\n", -+ __FUNCTION__, num, sublen); -+ pnext = NULL; -+ break; -+ } -+ if (sublen % DHD_SDALIGN) { -+ AP6210_ERR("%s: sublen %d not a multiple of %d\n", -+ __FUNCTION__, sublen, DHD_SDALIGN); -+ usechain = FALSE; -+ } -+ totlen += sublen; -+ -+ /* For last frame, adjust read len so total is a block multiple */ -+ if (!dlen) { -+ sublen += (ROUNDUP(totlen, bus->blocksize) - totlen); -+ totlen = ROUNDUP(totlen, bus->blocksize); -+ } -+ -+ /* Allocate/chain packet for next subframe */ -+ if ((pnext = PKTGET(osh, sublen + DHD_SDALIGN, FALSE)) == NULL) { -+ AP6210_ERR("%s: PKTGET failed, num %d len %d\n", -+ __FUNCTION__, num, sublen); -+ break; -+ } -+ ASSERT(!PKTLINK(pnext)); -+ if (!pfirst) { -+ ASSERT(!plast); -+ pfirst = plast = pnext; -+ } else { -+ ASSERT(plast); -+ PKTSETNEXT(osh, plast, pnext); -+ plast = pnext; -+ } -+ -+ /* Adhere to start alignment requirements */ -+ PKTALIGN(osh, pnext, sublen, DHD_SDALIGN); -+ } -+ -+ /* If all allocations succeeded, save packet chain in bus structure */ -+ if (pnext) { -+ AP6210_DEBUG("%s: allocated %d-byte packet chain for %d subframes\n", -+ __FUNCTION__, totlen, num); -+ if (DHD_GLOM_ON() && bus->nextlen) { -+ if (totlen != bus->nextlen) { -+ AP6210_DEBUG("%s: glomdesc mismatch: nextlen %d glomdesc %d " -+ "rxseq %d\n", __FUNCTION__, bus->nextlen, -+ totlen, rxseq); -+ } -+ } -+ bus->glom = pfirst; -+ pfirst = pnext = NULL; -+ } else { -+ if (pfirst) -+ PKTFREE(osh, pfirst, FALSE); -+ bus->glom = NULL; -+ num = 0; -+ } -+ -+ /* Done with descriptor packet */ -+ PKTFREE(osh, bus->glomd, FALSE); -+ bus->glomd = NULL; -+ bus->nextlen = 0; -+ -+ dhd_os_sdunlock_rxq(bus->dhd); -+ } -+ -+ /* Ok -- either we just generated a packet chain, or had one from before */ -+ if (bus->glom) { -+ if (DHD_GLOM_ON()) { -+ AP6210_DEBUG("%s: attempt superframe read, packet chain:\n", __FUNCTION__); -+ for (pnext = bus->glom; pnext; pnext = PKTNEXT(osh, pnext)) { -+ AP6210_DEBUG(" %p: %p len 0x%04x (%d)\n", -+ pnext, (uint8*)PKTDATA(osh, pnext), -+ PKTLEN(osh, pnext), PKTLEN(osh, pnext)); -+ } -+ } -+ -+ pfirst = bus->glom; -+ dlen = (uint16)pkttotlen(osh, pfirst); -+ -+ /* Do an SDIO read for the superframe. Configurable iovar to -+ * read directly into the chained packet, or allocate a large -+ * packet and and copy into the chain. -+ */ -+ if (usechain) { -+ errcode = dhd_bcmsdh_recv_buf(bus, -+ bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, -+ F2SYNC, (uint8*)PKTDATA(osh, pfirst), -+ dlen, pfirst, NULL, NULL); -+ } else if (bus->dataptr) { -+ errcode = dhd_bcmsdh_recv_buf(bus, -+ bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, -+ F2SYNC, bus->dataptr, -+ dlen, NULL, NULL, NULL); -+ sublen = (uint16)pktfrombuf(osh, pfirst, 0, dlen, bus->dataptr); -+ if (sublen != dlen) { -+ AP6210_ERR("%s: FAILED TO COPY, dlen %d sublen %d\n", -+ __FUNCTION__, dlen, sublen); -+ errcode = -1; -+ } -+ pnext = NULL; -+ } else { -+ AP6210_ERR("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", dlen); -+ errcode = -1; -+ } -+ bus->f2rxdata++; -+ ASSERT(errcode != BCME_PENDING); -+ -+ /* On failure, kill the superframe, allow a couple retries */ -+ if (errcode < 0) { -+ AP6210_ERR("%s: glom read of %d bytes failed: %d\n", -+ __FUNCTION__, dlen, errcode); -+ bus->dhd->rx_errors++; -+ -+ if (bus->glomerr++ < 3) { -+ dhdsdio_rxfail(bus, TRUE, TRUE); -+ } else { -+ bus->glomerr = 0; -+ dhdsdio_rxfail(bus, TRUE, FALSE); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(osh, bus->glom, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ bus->rxglomfail++; -+ bus->glom = NULL; -+ } -+ return 0; -+ } -+ -+#ifdef DHD_DEBUG -+ if (DHD_GLOM_ON()) { -+ prhex("SUPERFRAME", PKTDATA(osh, pfirst), -+ MIN(PKTLEN(osh, pfirst), 48)); -+ } -+#endif -+ -+ -+ /* Validate the superframe header */ -+ dptr = (uint8 *)PKTDATA(osh, pfirst); -+ sublen = ltoh16_ua(dptr); -+ check = ltoh16_ua(dptr + sizeof(uint16)); -+ -+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); -+ seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); -+ bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; -+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) { -+ AP6210_DEBUG("%s: got frame w/nextlen too large (%d) seq %d\n", -+ __FUNCTION__, bus->nextlen, seq); -+ bus->nextlen = 0; -+ } -+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -+ txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -+ -+ errcode = 0; -+ if ((uint16)~(sublen^check)) { -+ AP6210_ERR("%s (superframe): HW hdr error: len/check 0x%04x/0x%04x\n", -+ __FUNCTION__, sublen, check); -+ errcode = -1; -+ } else if (ROUNDUP(sublen, bus->blocksize) != dlen) { -+ AP6210_ERR("%s (superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", -+ __FUNCTION__, sublen, ROUNDUP(sublen, bus->blocksize), dlen); -+ errcode = -1; -+ } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { -+ AP6210_ERR("%s (superframe): bad channel %d\n", __FUNCTION__, -+ SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN])); -+ errcode = -1; -+ } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { -+ AP6210_ERR("%s (superframe): got second descriptor?\n", __FUNCTION__); -+ errcode = -1; -+ } else if ((doff < SDPCM_HDRLEN_RX) || -+ (doff > (PKTLEN(osh, pfirst) - SDPCM_HDRLEN_RX))) { -+ AP6210_ERR("%s (superframe): Bad data offset %d: HW %d pkt %d min %d\n", -+ __FUNCTION__, doff, sublen, PKTLEN(osh, pfirst), -+ SDPCM_HDRLEN_RX); -+ errcode = -1; -+ } -+ -+ /* Check sequence number of superframe SW header */ -+ if (rxseq != seq) { -+ AP6210_DEBUG("%s: (superframe) rx_seq %d, expected %d\n", -+ __FUNCTION__, seq, rxseq); -+ bus->rx_badseq++; -+ rxseq = seq; -+ } -+ -+ /* Check window for sanity */ -+ if ((uint8)(txmax - bus->tx_seq) > 0x40) { -+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n", -+ __FUNCTION__, txmax, bus->tx_seq); -+ txmax = bus->tx_max; -+ } -+ bus->tx_max = txmax; -+ -+ /* Remove superframe header, remember offset */ -+ PKTPULL(osh, pfirst, doff); -+ sfdoff = doff; -+ -+ /* Validate all the subframe headers */ -+ for (num = 0, pnext = pfirst; pnext && !errcode; -+ num++, pnext = PKTNEXT(osh, pnext)) { -+ dptr = (uint8 *)PKTDATA(osh, pnext); -+ dlen = (uint16)PKTLEN(osh, pnext); -+ sublen = ltoh16_ua(dptr); -+ check = ltoh16_ua(dptr + sizeof(uint16)); -+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); -+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -+#ifdef DHD_DEBUG -+ if (DHD_GLOM_ON()) { -+ prhex("subframe", dptr, 32); -+ } -+#endif -+ -+ if ((uint16)~(sublen^check)) { -+ AP6210_ERR("%s (subframe %d): HW hdr error: " -+ "len/check 0x%04x/0x%04x\n", -+ __FUNCTION__, num, sublen, check); -+ errcode = -1; -+ } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN_RX)) { -+ AP6210_ERR("%s (subframe %d): length mismatch: " -+ "len 0x%04x, expect 0x%04x\n", -+ __FUNCTION__, num, sublen, dlen); -+ errcode = -1; -+ } else if ((chan != SDPCM_DATA_CHANNEL) && -+ (chan != SDPCM_EVENT_CHANNEL)) { -+ AP6210_ERR("%s (subframe %d): bad channel %d\n", -+ __FUNCTION__, num, chan); -+ errcode = -1; -+ } else if ((doff < SDPCM_HDRLEN_RX) || (doff > sublen)) { -+ AP6210_ERR("%s (subframe %d): Bad data offset %d: HW %d min %d\n", -+ __FUNCTION__, num, doff, sublen, SDPCM_HDRLEN_RX); -+ errcode = -1; -+ } -+ } -+ -+ if (errcode) { -+ /* Terminate frame on error, request a couple retries */ -+ if (bus->glomerr++ < 3) { -+ /* Restore superframe header space */ -+ PKTPUSH(osh, pfirst, sfdoff); -+ dhdsdio_rxfail(bus, TRUE, TRUE); -+ } else { -+ bus->glomerr = 0; -+ dhdsdio_rxfail(bus, TRUE, FALSE); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(osh, bus->glom, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ bus->rxglomfail++; -+ bus->glom = NULL; -+ } -+ bus->nextlen = 0; -+ return 0; -+ } -+ -+ /* Basic SD framing looks ok - process each packet (header) */ -+ bus->glom = NULL; -+ plast = NULL; -+ -+ dhd_os_sdlock_rxq(bus->dhd); -+ for (num = 0; pfirst; rxseq++, pfirst = pnext) { -+ pnext = PKTNEXT(osh, pfirst); -+ PKTSETNEXT(osh, pfirst, NULL); -+ -+ dptr = (uint8 *)PKTDATA(osh, pfirst); -+ sublen = ltoh16_ua(dptr); -+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); -+ seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); -+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -+ -+ AP6210_DEBUG("%s: Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", -+ __FUNCTION__, num, pfirst, PKTDATA(osh, pfirst), -+ PKTLEN(osh, pfirst), sublen, chan, seq); -+ -+ ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL)); -+ -+ if (rxseq != seq) { -+ AP6210_DEBUG("%s: rx_seq %d, expected %d\n", -+ __FUNCTION__, seq, rxseq); -+ bus->rx_badseq++; -+ rxseq = seq; -+ } -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_DATA_ON()) { -+ prhex("Rx Subframe Data", dptr, dlen); -+ } -+#endif -+ -+ PKTSETLEN(osh, pfirst, sublen); -+ PKTPULL(osh, pfirst, doff); -+ -+ reorder_info_len = sizeof(reorder_info_buf); -+ -+ if (PKTLEN(osh, pfirst) == 0) { -+ PKTFREE(bus->dhd->osh, pfirst, FALSE); -+ continue; -+ } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst, reorder_info_buf, -+ &reorder_info_len) != 0) { -+ AP6210_ERR("%s: rx protocol error\n", __FUNCTION__); -+ bus->dhd->rx_errors++; -+ PKTFREE(osh, pfirst, FALSE); -+ continue; -+ } -+ if (reorder_info_len) { -+ uint32 free_buf_count; -+ void *ppfirst; -+ -+ ppfirst = pfirst; -+ /* Reordering info from the firmware */ -+ dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf, -+ reorder_info_len, &ppfirst, &free_buf_count); -+ -+ if (free_buf_count == 0) { -+ continue; -+ } -+ else { -+ void *temp; -+ -+ /* go to the end of the chain and attach the pnext there */ -+ temp = ppfirst; -+ while (PKTNEXT(osh, temp) != NULL) { -+ temp = PKTNEXT(osh, temp); -+ } -+ pfirst = temp; -+ if (list_tail[ifidx] == NULL) { -+ list_head[ifidx] = ppfirst; -+ list_tail[ifidx] = pfirst; -+ } -+ else { -+ PKTSETNEXT(osh, list_tail[ifidx], ppfirst); -+ list_tail[ifidx] = pfirst; -+ } -+ } -+ -+ num += (uint8)free_buf_count; -+ } -+ else { -+ /* this packet will go up, link back into chain and count it */ -+ -+ if (list_tail[ifidx] == NULL) { -+ list_head[ifidx] = list_tail[ifidx] = pfirst; -+ } -+ else { -+ PKTSETNEXT(osh, list_tail[ifidx], pfirst); -+ list_tail[ifidx] = pfirst; -+ } -+ num++; -+ } -+#ifdef DHD_DEBUG -+ if (DHD_GLOM_ON()) { -+ AP6210_DEBUG("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n", -+ __FUNCTION__, num, pfirst, -+ PKTDATA(osh, pfirst), PKTLEN(osh, pfirst), -+ PKTNEXT(osh, pfirst), PKTLINK(pfirst)); -+ prhex("", (uint8 *)PKTDATA(osh, pfirst), -+ MIN(PKTLEN(osh, pfirst), 32)); -+ } -+#endif /* DHD_DEBUG */ -+ } -+ dhd_os_sdunlock_rxq(bus->dhd); -+ -+ for (idx = 0; idx < DHD_MAX_IFS; idx++) { -+ if (list_head[idx]) { -+ void *temp; -+ uint8 cnt = 0; -+ temp = list_head[idx]; -+ do { -+ temp = PKTNEXT(osh, temp); -+ cnt++; -+ } while (temp); -+ if (cnt) { -+ dhd_os_sdunlock(bus->dhd); -+ dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0); -+ dhd_os_sdlock(bus->dhd); -+ } -+ } -+ } -+ bus->rxglomframes++; -+ bus->rxglompkts += num; -+ } -+ return num; -+} -+ -+ -+/* Return TRUE if there may be more frames to read */ -+static uint -+dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) -+{ -+ osl_t *osh = bus->dhd->osh; -+ bcmsdh_info_t *sdh = bus->sdh; -+ -+ uint16 len, check; /* Extracted hardware header fields */ -+ uint8 chan, seq, doff; /* Extracted software header fields */ -+ uint8 fcbits; /* Extracted fcbits from software header */ -+ uint8 delta; -+ -+ void *pkt; /* Packet for event or data frames */ -+ uint16 pad; /* Number of pad bytes to read */ -+ uint16 rdlen; /* Total number of bytes to read */ -+ uint8 rxseq; /* Next sequence number to expect */ -+ uint rxleft = 0; /* Remaining number of frames allowed */ -+ int sdret; /* Return code from bcmsdh calls */ -+ uint8 txmax; /* Maximum tx sequence offered */ -+ bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */ -+ uint8 *rxbuf; -+ int ifidx = 0; -+ uint rxcount = 0; /* Total frames read */ -+ uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN]; -+ uint reorder_info_len; -+ uint pkt_count; -+ -+#if defined(DHD_DEBUG) || defined(SDTEST) -+ bool sdtest = FALSE; /* To limit message spew from test mode */ -+#endif -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ bus->readframes = TRUE; -+ -+ if (!KSO_ENAB(bus)) { -+ AP6210_DEBUG("%s: KSO off\n", __FUNCTION__); -+ bus->readframes = FALSE; -+ return 0; -+ } -+ -+ ASSERT(maxframes); -+ -+#ifdef SDTEST -+ /* Allow pktgen to override maxframes */ -+ if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) { -+ maxframes = bus->pktgen_count; -+ sdtest = TRUE; -+ } -+#endif -+ -+ /* Not finished unless we encounter no more frames indication */ -+ *finished = FALSE; -+ -+ -+ for (rxseq = bus->rx_seq, rxleft = maxframes; -+ !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN; -+ rxseq++, rxleft--) { -+ -+#ifdef DHDTHREAD -+ /* terence: fix got unlikely tx max for 43362a0*/ -+ if (bus->sih->chip!=BCM43362_CHIP_ID && bus->sih->chiprev!=BCM43362A0_CHIP_REV) { -+ /* tx more to improve rx performance */ -+ if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && -+ pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) { -+ dhdsdio_sendfromq(bus, dhd_txbound); -+ } -+ } -+#endif /* DHDTHREAD */ -+ -+ /* Handle glomming separately */ -+ if (bus->glom || bus->glomd) { -+ uint8 cnt; -+ AP6210_DEBUG("%s: calling rxglom: glomd %p, glom %p\n", -+ __FUNCTION__, bus->glomd, bus->glom); -+ cnt = dhdsdio_rxglom(bus, rxseq); -+ AP6210_DEBUG("%s: rxglom returned %d\n", __FUNCTION__, cnt); -+ rxseq += cnt - 1; -+ rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; -+ continue; -+ } -+ -+ /* Try doing single read if we can */ -+ if (dhd_readahead && bus->nextlen) { -+ uint16 nextlen = bus->nextlen; -+ bus->nextlen = 0; -+ -+ if (bus->bus == SPI_BUS) { -+ rdlen = len = nextlen; -+ } -+ else { -+ rdlen = len = nextlen << 4; -+ -+ /* Pad read to blocksize for efficiency */ -+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { -+ pad = bus->blocksize - (rdlen % bus->blocksize); -+ if ((pad <= bus->roundup) && (pad < bus->blocksize) && -+ ((rdlen + pad + firstread) < MAX_RX_DATASZ)) -+ rdlen += pad; -+ } else if (rdlen % DHD_SDALIGN) { -+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); -+ } -+ } -+ -+ /* We use bus->rxctl buffer in WinXP for initial control pkt receives. -+ * Later we use buffer-poll for data as well as control packets. -+ * This is required because dhd receives full frame in gSPI unlike SDIO. -+ * After the frame is received we have to distinguish whether it is data -+ * or non-data frame. -+ */ -+ /* Allocate a packet buffer */ -+ dhd_os_sdlock_rxq(bus->dhd); -+ if (!(pkt = PKTGET(osh, rdlen + DHD_SDALIGN, FALSE))) { -+ if (bus->bus == SPI_BUS) { -+ bus->usebufpool = FALSE; -+ bus->rxctl = bus->rxbuf; -+ if (dhd_alignctl) { -+ bus->rxctl += firstread; -+ if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN))) -+ bus->rxctl += (DHD_SDALIGN - pad); -+ bus->rxctl -= firstread; -+ } -+ ASSERT(bus->rxctl >= bus->rxbuf); -+ rxbuf = bus->rxctl; -+ /* Read the entire frame */ -+ sdret = dhd_bcmsdh_recv_buf(bus, -+ bcmsdh_cur_sbwad(sdh), -+ SDIO_FUNC_2, -+ F2SYNC, rxbuf, rdlen, -+ NULL, NULL, NULL); -+ bus->f2rxdata++; -+ ASSERT(sdret != BCME_PENDING); -+ -+ -+ /* Control frame failures need retransmission */ -+ if (sdret < 0) { -+ AP6210_ERR("%s: read %d control bytes failed: %d\n", -+ __FUNCTION__, rdlen, sdret); -+ /* dhd.rx_ctlerrs is higher level */ -+ bus->rxc_errors++; -+ dhd_os_sdunlock_rxq(bus->dhd); -+ dhdsdio_rxfail(bus, TRUE, -+ (bus->bus == SPI_BUS) ? FALSE : TRUE); -+ continue; -+ } -+ } else { -+ /* Give up on data, request rtx of events */ -+ AP6210_ERR("%s (nextlen): PKTGET failed: len %d rdlen %d " -+ "expected rxseq %d\n", -+ __FUNCTION__, len, rdlen, rxseq); -+ /* Just go try again w/normal header read */ -+ dhd_os_sdunlock_rxq(bus->dhd); -+ continue; -+ } -+ } else { -+ if (bus->bus == SPI_BUS) -+ bus->usebufpool = TRUE; -+ -+ ASSERT(!PKTLINK(pkt)); -+ PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); -+ rxbuf = (uint8 *)PKTDATA(osh, pkt); -+ /* Read the entire frame */ -+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), -+ SDIO_FUNC_2, -+ F2SYNC, rxbuf, rdlen, -+ pkt, NULL, NULL); -+ bus->f2rxdata++; -+ ASSERT(sdret != BCME_PENDING); -+ -+ if (sdret < 0) { -+ AP6210_ERR("%s (nextlen): read %d bytes failed: %d\n", -+ __FUNCTION__, rdlen, sdret); -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+ bus->dhd->rx_errors++; -+ dhd_os_sdunlock_rxq(bus->dhd); -+ /* Force retry w/normal header read. Don't attempt NAK for -+ * gSPI -+ */ -+ dhdsdio_rxfail(bus, TRUE, -+ (bus->bus == SPI_BUS) ? FALSE : TRUE); -+ continue; -+ } -+ } -+ dhd_os_sdunlock_rxq(bus->dhd); -+ -+ /* Now check the header */ -+ bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN_RX); -+ -+ /* Extract hardware header fields */ -+ len = ltoh16_ua(bus->rxhdr); -+ check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); -+ -+ /* All zeros means readahead info was bad */ -+ if (!(len|check)) { -+ AP6210_DEBUG("%s (nextlen): read zeros in HW header???\n", -+ __FUNCTION__); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ GSPI_PR55150_BAILOUT; -+ continue; -+ } -+ -+ /* Validate check bytes */ -+ if ((uint16)~(len^check)) { -+ AP6210_ERR("%s (nextlen): HW hdr error: nextlen/len/check" -+ " 0x%04x/0x%04x/0x%04x\n", __FUNCTION__, nextlen, -+ len, check); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ bus->rx_badhdr++; -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ GSPI_PR55150_BAILOUT; -+ continue; -+ } -+ -+ /* Validate frame length */ -+ if (len < SDPCM_HDRLEN_RX) { -+ AP6210_ERR("%s (nextlen): HW hdr length invalid: %d\n", -+ __FUNCTION__, len); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ GSPI_PR55150_BAILOUT; -+ continue; -+ } -+ -+ /* Check for consistency with readahead info */ -+ len_consistent = (nextlen != (ROUNDUP(len, 16) >> 4)); -+ if (len_consistent) { -+ /* Mismatch, force retry w/normal header (may be >4K) */ -+ AP6210_ERR("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " -+ "expected rxseq %d\n", -+ __FUNCTION__, nextlen, len, ROUNDUP(len, 16), rxseq); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ dhdsdio_rxfail(bus, TRUE, (bus->bus == SPI_BUS) ? FALSE : TRUE); -+ GSPI_PR55150_BAILOUT; -+ continue; -+ } -+ -+ -+ /* Extract software header fields */ -+ chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ -+ bus->nextlen = -+ bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; -+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) { -+ AP6210_DEBUG("%s (nextlen): got frame w/nextlen too large" -+ " (%d), seq %d\n", __FUNCTION__, bus->nextlen, -+ seq); -+ bus->nextlen = 0; -+ } -+ -+ bus->dhd->rx_readahead_cnt ++; -+ /* Handle Flow Control */ -+ fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ -+ delta = 0; -+ if (~bus->flowcontrol & fcbits) { -+ bus->fc_xoff++; -+ delta = 1; -+ } -+ if (bus->flowcontrol & ~fcbits) { -+ bus->fc_xon++; -+ delta = 1; -+ } -+ -+ if (delta) { -+ bus->fc_rcvd++; -+ bus->flowcontrol = fcbits; -+ } -+ -+ /* Check and update sequence number */ -+ if (rxseq != seq) { -+ AP6210_DEBUG("%s (nextlen): rx_seq %d, expected %d\n", -+ __FUNCTION__, seq, rxseq); -+ bus->rx_badseq++; -+ rxseq = seq; -+ } -+ -+ /* Check window for sanity */ -+ if ((uint8)(txmax - bus->tx_seq) > 0x40) { -+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n", -+ __FUNCTION__, txmax, bus->tx_seq); -+ txmax = bus->tx_max; -+ } -+ bus->tx_max = txmax; -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_DATA_ON()) { -+ prhex("Rx Data", rxbuf, len); -+ } else if (DHD_HDRS_ON()) { -+ prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN_RX); -+ } -+#endif -+ -+ if (chan == SDPCM_CONTROL_CHANNEL) { -+ if (bus->bus == SPI_BUS) { -+ dhdsdio_read_control(bus, rxbuf, len, doff); -+ if (bus->usebufpool) { -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ } -+ continue; -+ } else { -+ AP6210_ERR("%s (nextlen): readahead on control" -+ " packet %d?\n", __FUNCTION__, seq); -+ /* Force retry w/normal header read */ -+ bus->nextlen = 0; -+ dhdsdio_rxfail(bus, FALSE, TRUE); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ continue; -+ } -+ } -+ -+ if ((bus->bus == SPI_BUS) && !bus->usebufpool) { -+ AP6210_ERR("Received %d bytes on %d channel. Running out of " -+ "rx pktbuf's or not yet malloced.\n", len, chan); -+ continue; -+ } -+ -+ /* Validate data offset */ -+ if ((doff < SDPCM_HDRLEN_RX) || (doff > len)) { -+ AP6210_ERR("%s (nextlen): bad data offset %d: HW len %d min %d\n", -+ __FUNCTION__, doff, len, SDPCM_HDRLEN_RX); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE2(); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ ASSERT(0); -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ continue; -+ } -+ -+ /* All done with this one -- now deliver the packet */ -+ goto deliver; -+ } -+ /* gSPI frames should not be handled in fractions */ -+ if (bus->bus == SPI_BUS) { -+ break; -+ } -+ -+ /* Read frame header (hardware and software) */ -+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ bus->rxhdr, firstread, NULL, NULL, NULL); -+ bus->f2rxhdrs++; -+ ASSERT(sdret != BCME_PENDING); -+ -+ if (sdret < 0) { -+ AP6210_ERR("%s: RXHEADER FAILED: %d\n", __FUNCTION__, sdret); -+ bus->rx_hdrfail++; -+ dhdsdio_rxfail(bus, TRUE, TRUE); -+ continue; -+ } -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() || DHD_HDRS_ON()) { -+ prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN_RX); -+ } -+#endif -+ -+ /* Extract hardware header fields */ -+ len = ltoh16_ua(bus->rxhdr); -+ check = ltoh16_ua(bus->rxhdr + sizeof(uint16)); -+ -+ /* All zeros means no more frames */ -+ if (!(len|check)) { -+ *finished = TRUE; -+ break; -+ } -+ -+ /* Validate check bytes */ -+ if ((uint16)~(len^check)) { -+ AP6210_ERR("%s: HW hdr error: len/check 0x%04x/0x%04x\n", -+ __FUNCTION__, len, check); -+ bus->rx_badhdr++; -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ continue; -+ } -+ -+ /* Validate frame length */ -+ if (len < SDPCM_HDRLEN_RX) { -+ AP6210_ERR("%s: HW hdr length invalid: %d\n", __FUNCTION__, len); -+ continue; -+ } -+ -+ /* Extract software header fields */ -+ chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ -+ /* Validate data offset */ -+ if ((doff < SDPCM_HDRLEN_RX) || (doff > len)) { -+ AP6210_ERR("%s: Bad data offset %d: HW len %d, min %d seq %d\n", -+ __FUNCTION__, doff, len, SDPCM_HDRLEN_RX, seq); -+ bus->rx_badhdr++; -+ ASSERT(0); -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ continue; -+ } -+ -+ /* Save the readahead length if there is one */ -+ bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; -+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) { -+ AP6210_DEBUG("%s (nextlen): got frame w/nextlen too large (%d), seq %d\n", -+ __FUNCTION__, bus->nextlen, seq); -+ bus->nextlen = 0; -+ } -+ -+ /* Handle Flow Control */ -+ fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]); -+ -+ delta = 0; -+ if (~bus->flowcontrol & fcbits) { -+ bus->fc_xoff++; -+ delta = 1; -+ } -+ if (bus->flowcontrol & ~fcbits) { -+ bus->fc_xon++; -+ delta = 1; -+ } -+ -+ if (delta) { -+ bus->fc_rcvd++; -+ bus->flowcontrol = fcbits; -+ } -+ -+ /* Check and update sequence number */ -+ if (rxseq != seq) { -+ AP6210_DEBUG("%s: rx_seq %d, expected %d\n", __FUNCTION__, seq, rxseq); -+ bus->rx_badseq++; -+ rxseq = seq; -+ } -+ -+ /* Check window for sanity */ -+ if ((uint8)(txmax - bus->tx_seq) > 0x40) { -+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n", -+ __FUNCTION__, txmax, bus->tx_seq); -+ txmax = bus->tx_max; -+ } -+ bus->tx_max = txmax; -+ -+ /* Call a separate function for control frames */ -+ if (chan == SDPCM_CONTROL_CHANNEL) { -+ dhdsdio_read_control(bus, bus->rxhdr, len, doff); -+ continue; -+ } -+ -+ ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL) || -+ (chan == SDPCM_TEST_CHANNEL) || (chan == SDPCM_GLOM_CHANNEL)); -+ -+ /* Length to read */ -+ rdlen = (len > firstread) ? (len - firstread) : 0; -+ -+ /* May pad read to blocksize for efficiency */ -+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { -+ pad = bus->blocksize - (rdlen % bus->blocksize); -+ if ((pad <= bus->roundup) && (pad < bus->blocksize) && -+ ((rdlen + pad + firstread) < MAX_RX_DATASZ)) -+ rdlen += pad; -+ } else if (rdlen % DHD_SDALIGN) { -+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); -+ } -+ -+ /* Satisfy length-alignment requirements */ -+ if (forcealign && (rdlen & (ALIGNMENT - 1))) -+ rdlen = ROUNDUP(rdlen, ALIGNMENT); -+ -+ if ((rdlen + firstread) > MAX_RX_DATASZ) { -+ /* Too long -- skip this frame */ -+ AP6210_ERR("%s: too long: len %d rdlen %d\n", __FUNCTION__, len, rdlen); -+ bus->dhd->rx_errors++; bus->rx_toolong++; -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ continue; -+ } -+ -+ dhd_os_sdlock_rxq(bus->dhd); -+ if (!(pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), FALSE))) { -+ /* Give up on data, request rtx of events */ -+ AP6210_ERR("%s: PKTGET failed: rdlen %d chan %d\n", -+ __FUNCTION__, rdlen, chan); -+ bus->dhd->rx_dropped++; -+ dhd_os_sdunlock_rxq(bus->dhd); -+ dhdsdio_rxfail(bus, FALSE, RETRYCHAN(chan)); -+ continue; -+ } -+ dhd_os_sdunlock_rxq(bus->dhd); -+ -+ ASSERT(!PKTLINK(pkt)); -+ -+ /* Leave room for what we already read, and align remainder */ -+ ASSERT(firstread < (PKTLEN(osh, pkt))); -+ PKTPULL(osh, pkt, firstread); -+ PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); -+ -+ /* Read the remaining frame data */ -+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ ((uint8 *)PKTDATA(osh, pkt)), rdlen, pkt, NULL, NULL); -+ bus->f2rxdata++; -+ ASSERT(sdret != BCME_PENDING); -+ -+ if (sdret < 0) { -+ AP6210_ERR("%s: read %d %s bytes failed: %d\n", __FUNCTION__, rdlen, -+ ((chan == SDPCM_EVENT_CHANNEL) ? "event" : -+ ((chan == SDPCM_DATA_CHANNEL) ? "data" : "test")), sdret); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ bus->dhd->rx_errors++; -+ dhdsdio_rxfail(bus, TRUE, RETRYCHAN(chan)); -+ continue; -+ } -+ -+ /* Copy the already-read portion */ -+ PKTPUSH(osh, pkt, firstread); -+ bcopy(bus->rxhdr, PKTDATA(osh, pkt), firstread); -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_DATA_ON()) { -+ prhex("Rx Data", PKTDATA(osh, pkt), len); -+ } -+#endif -+ -+deliver: -+ /* Save superframe descriptor and allocate packet frame */ -+ if (chan == SDPCM_GLOM_CHANNEL) { -+ if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { -+ AP6210_DEBUG("%s: got glom descriptor, %d bytes:\n", -+ __FUNCTION__, len); -+#ifdef DHD_DEBUG -+ if (DHD_GLOM_ON()) { -+ prhex("Glom Data", PKTDATA(osh, pkt), len); -+ } -+#endif -+ PKTSETLEN(osh, pkt, len); -+ ASSERT(doff == SDPCM_HDRLEN_RX); -+ PKTPULL(osh, pkt, SDPCM_HDRLEN_RX); -+ bus->glomd = pkt; -+ } else { -+ AP6210_ERR("%s: glom superframe w/o descriptor!\n", __FUNCTION__); -+ dhdsdio_rxfail(bus, FALSE, FALSE); -+ } -+ continue; -+ } -+ -+ /* Fill in packet len and prio, deliver upward */ -+ PKTSETLEN(osh, pkt, len); -+ PKTPULL(osh, pkt, doff); -+ -+#ifdef SDTEST -+ /* Test channel packets are processed separately */ -+ if (chan == SDPCM_TEST_CHANNEL) { -+ dhdsdio_testrcv(bus, pkt, seq); -+ continue; -+ } -+#endif /* SDTEST */ -+ -+ if (PKTLEN(osh, pkt) == 0) { -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ continue; -+ } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt, reorder_info_buf, -+ &reorder_info_len) != 0) { -+ AP6210_ERR("%s: rx protocol error\n", __FUNCTION__); -+ dhd_os_sdlock_rxq(bus->dhd); -+ PKTFREE(bus->dhd->osh, pkt, FALSE); -+ dhd_os_sdunlock_rxq(bus->dhd); -+ bus->dhd->rx_errors++; -+ continue; -+ } -+ if (reorder_info_len) { -+ /* Reordering info from the firmware */ -+ dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf, reorder_info_len, -+ &pkt, &pkt_count); -+ if (pkt_count == 0) -+ continue; -+ } -+ else -+ pkt_count = 1; -+ -+ -+ /* Unlock during rx call */ -+ dhd_os_sdunlock(bus->dhd); -+ dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan); -+ dhd_os_sdlock(bus->dhd); -+ } -+ rxcount = maxframes - rxleft; -+#ifdef DHD_DEBUG -+ /* Message if we hit the limit */ -+ if (!rxleft && !sdtest) -+ AP6210_DEBUG("%s: hit rx limit of %d frames\n", __FUNCTION__, maxframes); -+ else -+#endif /* DHD_DEBUG */ -+ AP6210_DEBUG("%s: processed %d frames\n", __FUNCTION__, rxcount); -+ /* Back off rxseq if awaiting rtx, update rx_seq */ -+ if (bus->rxskip) -+ rxseq--; -+ bus->rx_seq = rxseq; -+ -+ if (bus->reqbussleep) -+ { -+ dhdsdio_bussleep(bus, TRUE); -+ bus->reqbussleep = FALSE; -+ } -+ bus->readframes = FALSE; -+ -+ return rxcount; -+} -+ -+static uint32 -+dhdsdio_hostmail(dhd_bus_t *bus) -+{ -+ sdpcmd_regs_t *regs = bus->regs; -+ uint32 intstatus = 0; -+ uint32 hmb_data; -+ uint8 fcbits; -+ uint retries = 0; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* Read mailbox data and ack that we did so */ -+ R_SDREG(hmb_data, ®s->tohostmailboxdata, retries); -+ if (retries <= retry_limit) -+ W_SDREG(SMB_INT_ACK, ®s->tosbmailbox, retries); -+ bus->f1regdata += 2; -+ -+ /* Dongle recomposed rx frames, accept them again */ -+ if (hmb_data & HMB_DATA_NAKHANDLED) { -+ AP6210_DEBUG("Dongle reports NAK handled, expect rtx of %d\n", bus->rx_seq); -+ if (!bus->rxskip) { -+ AP6210_ERR("%s: unexpected NAKHANDLED!\n", __FUNCTION__); -+ } -+ bus->rxskip = FALSE; -+ intstatus |= FRAME_AVAIL_MASK(bus); -+ } -+ -+ /* -+ * DEVREADY does not occur with gSPI. -+ */ -+ if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) { -+ bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; -+ if (bus->sdpcm_ver != SDPCM_PROT_VERSION) -+ AP6210_ERR("Version mismatch, dongle reports %d, expecting %d\n", -+ bus->sdpcm_ver, SDPCM_PROT_VERSION); -+ else -+ AP6210_ERR("Dongle ready, protocol version %d\n", bus->sdpcm_ver); -+ /* make sure for the SDIO_DEVICE_RXDATAINT_MODE_1 corecontrol is proper */ -+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) && -+ (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1)) { -+ uint32 val; -+ -+ val = R_REG(bus->dhd->osh, &bus->regs->corecontrol); -+ val &= ~CC_XMTDATAAVAIL_MODE; -+ val |= CC_XMTDATAAVAIL_CTRL; -+ W_REG(bus->dhd->osh, &bus->regs->corecontrol, val); -+ -+ val = R_REG(bus->dhd->osh, &bus->regs->corecontrol); -+ } -+ -+#ifdef DHD_DEBUG -+ /* Retrieve console state address now that firmware should have updated it */ -+ { -+ sdpcm_shared_t shared; -+ if (dhdsdio_readshared(bus, &shared) == 0) -+ bus->console_addr = shared.console_addr; -+ } -+#endif /* DHD_DEBUG */ -+ } -+ -+ /* -+ * Flow Control has been moved into the RX headers and this out of band -+ * method isn't used any more. Leave this here for possibly remaining backward -+ * compatible with older dongles -+ */ -+ if (hmb_data & HMB_DATA_FC) { -+ fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT; -+ -+ if (fcbits & ~bus->flowcontrol) -+ bus->fc_xoff++; -+ if (bus->flowcontrol & ~fcbits) -+ bus->fc_xon++; -+ -+ bus->fc_rcvd++; -+ bus->flowcontrol = fcbits; -+ } -+ -+#ifdef DHD_DEBUG -+ /* At least print a message if FW halted */ -+ if (hmb_data & HMB_DATA_FWHALT) { -+ AP6210_ERR("INTERNAL ERROR: FIRMWARE HALTED : set BUS DOWN\n"); -+ dhdsdio_checkdied(bus, NULL, 0); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ } -+#endif /* DHD_DEBUG */ -+ -+ /* Shouldn't be any others */ -+ if (hmb_data & ~(HMB_DATA_DEVREADY | -+ HMB_DATA_FWHALT | -+ HMB_DATA_NAKHANDLED | -+ HMB_DATA_FC | -+ HMB_DATA_FWREADY | -+ HMB_DATA_FCDATA_MASK | -+ HMB_DATA_VERSION_MASK)) { -+ AP6210_ERR("Unknown mailbox data content: 0x%02x\n", hmb_data); -+ } -+ -+ return intstatus; -+} -+ -+static bool -+dhdsdio_dpc(dhd_bus_t *bus) -+{ -+ bcmsdh_info_t *sdh = bus->sdh; -+ sdpcmd_regs_t *regs = bus->regs; -+ uint32 intstatus, newstatus = 0; -+ uint retries = 0; -+ uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */ -+ uint txlimit = dhd_txbound; /* Tx frames to send before resched */ -+ uint framecnt = 0; /* Temporary counter of tx/rx frames */ -+ bool rxdone = TRUE; /* Flag for no more read data */ -+ bool resched = FALSE; /* Flag indicating resched wanted */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus->dhd->busstate == DHD_BUS_DOWN) { -+ AP6210_ERR("%s: Bus down, ret\n", __FUNCTION__); -+ bus->intstatus = 0; -+ return 0; -+ } -+ -+ /* Start with leftover status bits */ -+ intstatus = bus->intstatus; -+ -+ dhd_os_sdlock(bus->dhd); -+ -+ if (!SLPAUTO_ENAB(bus) && !KSO_ENAB(bus)) { -+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__); -+ goto exit; -+ } -+ -+ /* If waiting for HTAVAIL, check status */ -+ if (!SLPAUTO_ENAB(bus) && (bus->clkstate == CLK_PENDING)) { -+ int err; -+ uint8 clkctl, devctl = 0; -+ -+#ifdef DHD_DEBUG -+ /* Check for inconsistent device control */ -+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); -+ if (err) { -+ AP6210_ERR("%s: error reading DEVCTL: %d\n", __FUNCTION__, err); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ } else { -+ ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY); -+ } -+#endif /* DHD_DEBUG */ -+ -+ /* Read CSR, if clock on switch to AVAIL, else ignore */ -+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ if (err) { -+ AP6210_ERR("%s: error reading CSR: %d\n", __FUNCTION__, err); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ } -+ -+ AP6210_DEBUG("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl); -+ -+ if (SBSDIO_HTAV(clkctl)) { -+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); -+ if (err) { -+ AP6210_ERR("%s: error reading DEVCTL: %d\n", -+ __FUNCTION__, err); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ } -+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); -+ if (err) { -+ AP6210_ERR("%s: error writing DEVCTL: %d\n", -+ __FUNCTION__, err); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ } -+ bus->clkstate = CLK_AVAIL; -+ } else { -+ goto clkwait; -+ } -+ } -+ -+ BUS_WAKE(bus); -+ -+ /* Make sure backplane clock is on */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, TRUE); -+ if (bus->clkstate != CLK_AVAIL) -+ goto clkwait; -+ -+ /* Pending interrupt indicates new device status */ -+ if (bus->ipend) { -+ bus->ipend = FALSE; -+ R_SDREG(newstatus, ®s->intstatus, retries); -+ bus->f1regdata++; -+ if (bcmsdh_regfail(bus->sdh)) -+ newstatus = 0; -+ newstatus &= bus->hostintmask; -+ bus->fcstate = !!(newstatus & I_HMB_FC_STATE); -+ if (newstatus) { -+ bus->f1regdata++; -+ if ((bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_0) && -+ (newstatus == I_XMTDATA_AVAIL)) { -+ } -+ else -+ W_SDREG(newstatus, ®s->intstatus, retries); -+ } -+ } -+ -+ /* Merge new bits with previous */ -+ intstatus |= newstatus; -+ bus->intstatus = 0; -+ -+ /* Handle flow-control change: read new state in case our ack -+ * crossed another change interrupt. If change still set, assume -+ * FC ON for safety, let next loop through do the debounce. -+ */ -+ if (intstatus & I_HMB_FC_CHANGE) { -+ intstatus &= ~I_HMB_FC_CHANGE; -+ W_SDREG(I_HMB_FC_CHANGE, ®s->intstatus, retries); -+ R_SDREG(newstatus, ®s->intstatus, retries); -+ bus->f1regdata += 2; -+ bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); -+ intstatus |= (newstatus & bus->hostintmask); -+ } -+ -+ /* Just being here means nothing more to do for chipactive */ -+ if (intstatus & I_CHIPACTIVE) { -+ /* ASSERT(bus->clkstate == CLK_AVAIL); */ -+ intstatus &= ~I_CHIPACTIVE; -+ } -+ -+ /* Handle host mailbox indication */ -+ if (intstatus & I_HMB_HOST_INT) { -+ intstatus &= ~I_HMB_HOST_INT; -+ intstatus |= dhdsdio_hostmail(bus); -+ } -+ -+ /* Generally don't ask for these, can get CRC errors... */ -+ if (intstatus & I_WR_OOSYNC) { -+ AP6210_DEBUG("Dongle reports WR_OOSYNC\n"); -+ intstatus &= ~I_WR_OOSYNC; -+ } -+ -+ if (intstatus & I_RD_OOSYNC) { -+ AP6210_DEBUG("Dongle reports RD_OOSYNC\n"); -+ intstatus &= ~I_RD_OOSYNC; -+ } -+ -+ if (intstatus & I_SBINT) { -+ AP6210_DEBUG("Dongle reports SBINT\n"); -+ intstatus &= ~I_SBINT; -+ } -+ -+ /* Would be active due to wake-wlan in gSPI */ -+ if (intstatus & I_CHIPACTIVE) { -+ AP6210_DEBUG("Dongle reports CHIPACTIVE\n"); -+ intstatus &= ~I_CHIPACTIVE; -+ } -+ -+ /* Ignore frame indications if rxskip is set */ -+ if (bus->rxskip) { -+ intstatus &= ~FRAME_AVAIL_MASK(bus); -+ } -+ -+ /* On frame indication, read available frames */ -+ if (PKT_AVAILABLE(bus, intstatus)) { -+ framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone); -+ if (rxdone || bus->rxskip) -+ intstatus &= ~FRAME_AVAIL_MASK(bus); -+ rxlimit -= MIN(framecnt, rxlimit); -+ } -+ -+ /* Keep still-pending events for next scheduling */ -+ bus->intstatus = intstatus; -+ -+clkwait: -+ /* Re-enable interrupts to detect new device events (mailbox, rx frame) -+ * or clock availability. (Allows tx loop to check ipend if desired.) -+ * (Unless register access seems hosed, as we may not be able to ACK...) -+ */ -+ if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) { -+ AP6210_DEBUG("%s: enable SDIO interrupts, rxdone %d framecnt %d\n", -+ __FUNCTION__, rxdone, framecnt); -+ bus->intdis = FALSE; -+#if defined(OOB_INTR_ONLY) -+ bcmsdh_oob_intr_set(1); -+#endif /* defined(OOB_INTR_ONLY) */ -+ bcmsdh_intr_enable(sdh); -+ } -+ -+#if defined(OOB_INTR_ONLY) && !defined(HW_OOB) -+ /* In case of SW-OOB(using edge trigger), -+ * Check interrupt status in the dongle again after enable irq on the host. -+ * and rechedule dpc if interrupt is pended in the dongle. -+ * There is a chance to miss OOB interrupt while irq is disabled on the host. -+ * No need to do this with HW-OOB(level trigger) -+ */ -+ R_SDREG(newstatus, ®s->intstatus, retries); -+ if (bcmsdh_regfail(bus->sdh)) -+ newstatus = 0; -+ if (newstatus & bus->hostintmask) { -+ bus->ipend = TRUE; -+ resched = TRUE; -+ } -+#endif /* defined(OOB_INTR_ONLY) && !defined(HW_OOB) */ -+#ifdef PROP_TXSTATUS -+ dhd_wlfc_trigger_pktcommit(bus->dhd); -+#endif -+ if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { -+ int ret, i; -+ -+ uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN; -+ -+ if (*frame_seq != bus->tx_seq) { -+ AP6210_DEBUG("%s IOCTL frame seq lag detected!" -+ " frm_seq:%d != bus->tx_seq:%d, corrected\n", -+ __FUNCTION__, *frame_seq, bus->tx_seq); -+ *frame_seq = bus->tx_seq; -+ } -+ -+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, -+ (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, -+ NULL, NULL, NULL); -+ ASSERT(ret != BCME_PENDING); -+ if (ret == BCME_NODEVICE) { -+ AP6210_ERR("%s: Device asleep already\n", __FUNCTION__); -+ } else if (ret < 0) { -+ /* On failure, abort the command and terminate the frame */ -+ AP6210_DEBUG("%s: sdio error %d, abort command and terminate frame.\n", -+ __FUNCTION__, ret); -+ bus->tx_sderrs++; -+ -+ bcmsdh_abort(sdh, SDIO_FUNC_2); -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, -+ SFC_WF_TERM, NULL); -+ bus->f1regdata++; -+ -+ for (i = 0; i < 3; i++) { -+ uint8 hi, lo; -+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCHI, NULL); -+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_WFRAMEBCLO, NULL); -+ bus->f1regdata += 2; -+ if ((hi == 0) && (lo == 0)) -+ break; -+ } -+ } -+ if (ret == 0) { -+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; -+ } -+ -+ bus->ctrl_frame_stat = FALSE; -+ dhd_wait_event_wakeup(bus->dhd); -+ } -+ /* Send queued frames (limit 1 if rx may still be pending) */ -+ else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && -+ pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { -+ framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax); -+ framecnt = dhdsdio_sendfromq(bus, framecnt); -+ txlimit -= framecnt; -+ } -+ /* Resched the DPC if ctrl cmd is pending on bus credit */ -+ if (bus->ctrl_frame_stat) -+ resched = TRUE; -+ -+ /* Resched if events or tx frames are pending, else await next interrupt */ -+ /* On failed register access, all bets are off: no resched or interrupts */ -+ if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { -+ if ((bus->sih && bus->sih->buscorerev >= 12) && !(dhdsdio_sleepcsr_get(bus) & -+ SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { -+ /* Bus failed because of KSO */ -+ AP6210_ERR("%s: Bus failed due to KSO\n", __FUNCTION__); -+ bus->kso = FALSE; -+ } else { -+ AP6210_ERR("%s: failed backplane access over SDIO, halting operation\n", -+ __FUNCTION__); -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ bus->intstatus = 0; -+ } -+ } else if (bus->clkstate == CLK_PENDING) { -+ /* Awaiting I_CHIPACTIVE; don't resched */ -+ } else if (bus->intstatus || bus->ipend || -+ (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) || -+ PKT_AVAILABLE(bus, bus->intstatus)) { /* Read multiple frames */ -+ resched = TRUE; -+ } -+ -+ bus->dpc_sched = resched; -+ -+ /* If we're done for now, turn off clock request. */ -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && (bus->clkstate != CLK_PENDING)) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, FALSE); -+ } -+ -+exit: -+ dhd_os_sdunlock(bus->dhd); -+ return resched; -+} -+ -+bool -+dhd_bus_dpc(struct dhd_bus *bus) -+{ -+ bool resched; -+ -+ /* Call the DPC directly. */ -+ AP6210_DEBUG("Calling dhdsdio_dpc() from %s\n", __FUNCTION__); -+ resched = dhdsdio_dpc(bus); -+ -+ return resched; -+} -+ -+void -+dhdsdio_isr(void *arg) -+{ -+ dhd_bus_t *bus = (dhd_bus_t*)arg; -+ bcmsdh_info_t *sdh; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (!bus) { -+ AP6210_ERR("%s : bus is null pointer , exit \n", __FUNCTION__); -+ return; -+ } -+ sdh = bus->sdh; -+ -+ if (bus->dhd->busstate == DHD_BUS_DOWN) { -+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__); -+ return; -+ } -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ /* Count the interrupt call */ -+ bus->intrcount++; -+ bus->ipend = TRUE; -+ -+ /* Shouldn't get this interrupt if we're sleeping? */ -+ if (!SLPAUTO_ENAB(bus)) { -+ if (bus->sleeping) { -+ AP6210_ERR("INTERRUPT WHILE SLEEPING??\n"); -+ return; -+ } else if (!KSO_ENAB(bus)) { -+ AP6210_ERR("ISR in devsleep 1\n"); -+ } -+ } -+ -+ /* Disable additional interrupts (is this needed now)? */ -+ if (bus->intr) { -+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__); -+ } else { -+ AP6210_ERR("dhdsdio_isr() w/o interrupt configured!\n"); -+ } -+ -+ bcmsdh_intr_disable(sdh); -+ bus->intdis = TRUE; -+ -+#if defined(SDIO_ISR_THREAD) -+ AP6210_DEBUG("Calling dhdsdio_dpc() from %s\n", __FUNCTION__); -+ DHD_OS_WAKE_LOCK(bus->dhd); -+ while (dhdsdio_dpc(bus)); -+ DHD_OS_WAKE_UNLOCK(bus->dhd); -+#else -+ bus->dpc_sched = TRUE; -+ dhd_sched_dpc(bus->dhd); -+#endif -+ -+} -+ -+#ifdef SDTEST -+static void -+dhdsdio_pktgen_init(dhd_bus_t *bus) -+{ -+ /* Default to specified length, or full range */ -+ if (dhd_pktgen_len) { -+ bus->pktgen_maxlen = MIN(dhd_pktgen_len, MAX_PKTGEN_LEN); -+ bus->pktgen_minlen = bus->pktgen_maxlen; -+ } else { -+ bus->pktgen_maxlen = MAX_PKTGEN_LEN; -+ bus->pktgen_minlen = 0; -+ } -+ bus->pktgen_len = (uint16)bus->pktgen_minlen; -+ -+ /* Default to per-watchdog burst with 10s print time */ -+ bus->pktgen_freq = 1; -+ bus->pktgen_print = dhd_watchdog_ms ? (10000/dhd_watchdog_ms):0; -+ bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; -+ -+ /* Default to echo mode */ -+ bus->pktgen_mode = DHD_PKTGEN_ECHO; -+ bus->pktgen_stop = 1; -+} -+ -+static void -+dhdsdio_pktgen(dhd_bus_t *bus) -+{ -+ void *pkt; -+ uint8 *data; -+ uint pktcount; -+ uint fillbyte; -+ osl_t *osh = bus->dhd->osh; -+ uint16 len; -+ ulong time_lapse; -+ uint sent_pkts; -+ uint rcvd_pkts; -+ -+ /* Display current count if appropriate */ -+ if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { -+ bus->pktgen_ptick = 0; -+ AP6210_DEBUG("%s: send attempts %d, rcvd %d, errors %d\n", -+ __FUNCTION__, bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); -+ -+ /* Print throughput stats only for constant length packet runs */ -+ if (bus->pktgen_minlen == bus->pktgen_maxlen) { -+ time_lapse = jiffies - bus->pktgen_prev_time; -+ bus->pktgen_prev_time = jiffies; -+ sent_pkts = bus->pktgen_sent - bus->pktgen_prev_sent; -+ bus->pktgen_prev_sent = bus->pktgen_sent; -+ rcvd_pkts = bus->pktgen_rcvd - bus->pktgen_prev_rcvd; -+ bus->pktgen_prev_rcvd = bus->pktgen_rcvd; -+ -+ AP6210_DEBUG("%s: Tx Throughput %d kbps, Rx Throughput %d kbps\n", -+ __FUNCTION__, -+ (sent_pkts * bus->pktgen_len / jiffies_to_msecs(time_lapse)) * 8, -+ (rcvd_pkts * bus->pktgen_len / jiffies_to_msecs(time_lapse)) * 8); -+ } -+ } -+ -+ /* For recv mode, just make sure dongle has started sending */ -+ if (bus->pktgen_mode == DHD_PKTGEN_RECV) { -+ if (bus->pktgen_rcv_state == PKTGEN_RCV_IDLE) { -+ bus->pktgen_rcv_state = PKTGEN_RCV_ONGOING; -+ dhdsdio_sdtest_set(bus, bus->pktgen_total); -+ } -+ return; -+ } -+ -+ /* Otherwise, generate or request the specified number of packets */ -+ for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) { -+ /* Stop if total has been reached */ -+ if (bus->pktgen_total && (bus->pktgen_sent >= bus->pktgen_total)) { -+ bus->pktgen_count = 0; -+ break; -+ } -+ -+ /* Allocate an appropriate-sized packet */ -+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) { -+ len = SDPCM_TEST_PKT_CNT_FLD_LEN; -+ } else { -+ len = bus->pktgen_len; -+ } -+ if (!(pkt = PKTGET(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), -+ TRUE))) {; -+ AP6210_ERR("%s: PKTGET failed!\n", __FUNCTION__); -+ break; -+ } -+ PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); -+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; -+ -+ /* Write test header cmd and extra based on mode */ -+ switch (bus->pktgen_mode) { -+ case DHD_PKTGEN_ECHO: -+ *data++ = SDPCM_TEST_ECHOREQ; -+ *data++ = (uint8)bus->pktgen_sent; -+ break; -+ -+ case DHD_PKTGEN_SEND: -+ *data++ = SDPCM_TEST_DISCARD; -+ *data++ = (uint8)bus->pktgen_sent; -+ break; -+ -+ case DHD_PKTGEN_RXBURST: -+ *data++ = SDPCM_TEST_BURST; -+ *data++ = (uint8)bus->pktgen_count; /* Just for backward compatability */ -+ break; -+ -+ default: -+ AP6210_ERR("Unrecognized pktgen mode %d\n", bus->pktgen_mode); -+ PKTFREE(osh, pkt, TRUE); -+ bus->pktgen_count = 0; -+ return; -+ } -+ -+ /* Write test header length field */ -+ *data++ = (bus->pktgen_len >> 0); -+ *data++ = (bus->pktgen_len >> 8); -+ -+ /* Write frame count in a 4 byte field adjucent to SDPCM test header for -+ * burst mode -+ */ -+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) { -+ *data++ = (uint8)(bus->pktgen_count >> 0); -+ *data++ = (uint8)(bus->pktgen_count >> 8); -+ *data++ = (uint8)(bus->pktgen_count >> 16); -+ *data++ = (uint8)(bus->pktgen_count >> 24); -+ } else { -+ -+ /* Then fill in the remainder -- N/A for burst */ -+ for (fillbyte = 0; fillbyte < len; fillbyte++) -+ *data++ = SDPCM_TEST_FILL(fillbyte, (uint8)bus->pktgen_sent); -+ } -+ -+#ifdef DHD_DEBUG -+ if (DHD_BYTES_ON() && DHD_DATA_ON()) { -+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; -+ prhex("dhdsdio_pktgen: Tx Data", data, PKTLEN(osh, pkt) - SDPCM_HDRLEN); -+ } -+#endif -+ -+ /* Send it */ -+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE)) { -+ bus->pktgen_fail++; -+ if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail) -+ bus->pktgen_count = 0; -+ } -+ bus->pktgen_sent++; -+ -+ /* Bump length if not fixed, wrap at max */ -+ if (++bus->pktgen_len > bus->pktgen_maxlen) -+ bus->pktgen_len = (uint16)bus->pktgen_minlen; -+ -+ /* Special case for burst mode: just send one request! */ -+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) -+ break; -+ } -+} -+ -+static void -+dhdsdio_sdtest_set(dhd_bus_t *bus, uint count) -+{ -+ void *pkt; -+ uint8 *data; -+ osl_t *osh = bus->dhd->osh; -+ -+ /* Allocate the packet */ -+ if (!(pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + -+ SDPCM_TEST_PKT_CNT_FLD_LEN + DHD_SDALIGN, TRUE))) { -+ AP6210_ERR("%s: PKTGET failed!\n", __FUNCTION__); -+ return; -+ } -+ PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + -+ SDPCM_TEST_PKT_CNT_FLD_LEN), DHD_SDALIGN); -+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN; -+ -+ /* Fill in the test header */ -+ *data++ = SDPCM_TEST_SEND; -+ *data++ = (count > 0)?TRUE:FALSE; -+ *data++ = (bus->pktgen_maxlen >> 0); -+ *data++ = (bus->pktgen_maxlen >> 8); -+ *data++ = (uint8)(count >> 0); -+ *data++ = (uint8)(count >> 8); -+ *data++ = (uint8)(count >> 16); -+ *data++ = (uint8)(count >> 24); -+ -+ /* Send it */ -+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE)) -+ bus->pktgen_fail++; -+} -+ -+ -+static void -+dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) -+{ -+ osl_t *osh = bus->dhd->osh; -+ uint8 *data; -+ uint pktlen; -+ -+ uint8 cmd; -+ uint8 extra; -+ uint16 len; -+ uint16 offset; -+ -+ /* Check for min length */ -+ if ((pktlen = PKTLEN(osh, pkt)) < SDPCM_TEST_HDRLEN) { -+ AP6210_ERR("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen); -+ PKTFREE(osh, pkt, FALSE); -+ return; -+ } -+ -+ /* Extract header fields */ -+ data = PKTDATA(osh, pkt); -+ cmd = *data++; -+ extra = *data++; -+ len = *data++; len += *data++ << 8; -+ AP6210_DEBUG("%s:cmd:%d, xtra:%d,len:%d\n", __FUNCTION__, cmd, extra, len); -+ /* Check length for relevant commands */ -+ if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) { -+ if (pktlen != len + SDPCM_TEST_HDRLEN) { -+ AP6210_ERR("dhdsdio_testrcv: frame length mismatch, pktlen %d seq %d" -+ " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len); -+ PKTFREE(osh, pkt, FALSE); -+ return; -+ } -+ } -+ -+ /* Process as per command */ -+ switch (cmd) { -+ case SDPCM_TEST_ECHOREQ: -+ /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ -+ *(uint8 *)(PKTDATA(osh, pkt)) = SDPCM_TEST_ECHORSP; -+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE) == 0) { -+ bus->pktgen_sent++; -+ } else { -+ bus->pktgen_fail++; -+ PKTFREE(osh, pkt, FALSE); -+ } -+ bus->pktgen_rcvd++; -+ break; -+ -+ case SDPCM_TEST_ECHORSP: -+ if (bus->ext_loop) { -+ PKTFREE(osh, pkt, FALSE); -+ bus->pktgen_rcvd++; -+ break; -+ } -+ -+ for (offset = 0; offset < len; offset++, data++) { -+ if (*data != SDPCM_TEST_FILL(offset, extra)) { -+ AP6210_ERR("dhdsdio_testrcv: echo data mismatch: " -+ "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n", -+ offset, len, SDPCM_TEST_FILL(offset, extra), *data); -+ break; -+ } -+ } -+ PKTFREE(osh, pkt, FALSE); -+ bus->pktgen_rcvd++; -+ break; -+ -+ case SDPCM_TEST_DISCARD: -+ { -+ int i = 0; -+ uint8 *prn = data; -+ uint8 testval = extra; -+ for (i = 0; i < len; i++) { -+ if (*prn != testval) { -+ AP6210_ERR("DIErr@Pkt#:%d,Ix:%d, expected:0x%x, got:0x%x\n", -+ i, bus->pktgen_rcvd_rcvsession, testval, *prn); -+ prn++; testval++; -+ } -+ } -+ } -+ PKTFREE(osh, pkt, FALSE); -+ bus->pktgen_rcvd++; -+ break; -+ -+ case SDPCM_TEST_BURST: -+ case SDPCM_TEST_SEND: -+ default: -+ AP6210_DEBUG("dhdsdio_testrcv: unsupported or unknown command, pktlen %d seq %d" -+ " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len); -+ PKTFREE(osh, pkt, FALSE); -+ break; -+ } -+ -+ /* For recv mode, stop at limit (and tell dongle to stop sending) */ -+ if (bus->pktgen_mode == DHD_PKTGEN_RECV) { -+ if (bus->pktgen_rcv_state != PKTGEN_RCV_IDLE) { -+ bus->pktgen_rcvd_rcvsession++; -+ -+ if (bus->pktgen_total && -+ (bus->pktgen_rcvd_rcvsession >= bus->pktgen_total)) { -+ bus->pktgen_count = 0; -+ AP6210_ERR("Pktgen:rcv test complete!\n"); -+ bus->pktgen_rcv_state = PKTGEN_RCV_IDLE; -+ dhdsdio_sdtest_set(bus, FALSE); -+ bus->pktgen_rcvd_rcvsession = 0; -+ } -+ } -+ } -+} -+#endif /* SDTEST */ -+ -+extern void -+dhd_disable_intr(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus; -+ bus = dhdp->bus; -+ bcmsdh_intr_disable(bus->sdh); -+} -+ -+extern bool -+dhd_bus_watchdog(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ bus = dhdp->bus; -+ -+ if (bus->dhd->dongle_reset) -+ return FALSE; -+ -+ /* Ignore the timer if simulating bus down */ -+ if (!SLPAUTO_ENAB(bus) && bus->sleeping) -+ return FALSE; -+ -+ if (dhdp->busstate == DHD_BUS_DOWN) -+ return FALSE; -+ -+ /* Poll period: check device if appropriate. */ -+ if (!SLPAUTO_ENAB(bus) && (bus->poll && (++bus->polltick >= bus->pollrate))) { -+ uint32 intstatus = 0; -+ -+ /* Reset poll tick */ -+ bus->polltick = 0; -+ -+ /* Check device if no interrupts */ -+ if (!bus->intr || (bus->intrcount == bus->lastintrs)) { -+ -+ if (!bus->dpc_sched) { -+ uint8 devpend; -+ devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, -+ SDIOD_CCCR_INTPEND, NULL); -+ intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); -+ } -+ -+ /* If there is something, make like the ISR and schedule the DPC */ -+ if (intstatus) { -+ bus->pollcnt++; -+ bus->ipend = TRUE; -+ if (bus->intr) { -+ bcmsdh_intr_disable(bus->sdh); -+ } -+ bus->dpc_sched = TRUE; -+ dhd_sched_dpc(bus->dhd); -+ -+ } -+ } -+ -+ /* Update interrupt tracking */ -+ bus->lastintrs = bus->intrcount; -+ } -+ -+#ifdef DHD_DEBUG -+ /* Poll for console output periodically */ -+ if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) { -+ bus->console.count += dhd_watchdog_ms; -+ if (bus->console.count >= dhd_console_ms) { -+ bus->console.count -= dhd_console_ms; -+ /* Make sure backplane clock is on */ -+ if (SLPAUTO_ENAB(bus)) -+ dhdsdio_bussleep(bus, FALSE); -+ else -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ if (dhdsdio_readconsole(bus) < 0) -+ dhd_console_ms = 0; /* On error, stop trying */ -+ } -+ } -+#endif /* DHD_DEBUG */ -+ -+#ifdef SDTEST -+ /* Generate packets if configured */ -+ if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { -+ /* Make sure backplane clock is on */ -+ if (SLPAUTO_ENAB(bus)) -+ dhdsdio_bussleep(bus, FALSE); -+ else -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ bus->pktgen_tick = 0; -+ dhdsdio_pktgen(bus); -+ } -+#endif -+ -+ /* On idle timeout clear activity flag and/or turn off clock */ -+#ifdef DHD_USE_IDLECOUNT -+ if (bus->activity) -+ bus->activity = FALSE; -+ else { -+ bus->idlecount++; -+ -+ if (bus->idlecount >= bus->idletime) { -+ AP6210_DEBUG("%s: DHD Idle state!!\n", __FUNCTION__); -+ -+ if (SLPAUTO_ENAB(bus)) { -+ if (dhdsdio_bussleep(bus, TRUE) != BCME_BUSY) -+ dhd_os_wd_timer(bus->dhd, 0); -+ } else -+ dhdsdio_clkctl(bus, CLK_NONE, FALSE); -+ -+ bus->idlecount = 0; -+ } -+ } -+#else -+ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { -+ if (++bus->idlecount > bus->idletime) { -+ bus->idlecount = 0; -+ if (bus->activity) { -+ bus->activity = FALSE; -+ if (SLPAUTO_ENAB(bus)) { -+ if (!bus->readframes) -+ dhdsdio_bussleep(bus, TRUE); -+ else -+ bus->reqbussleep = TRUE; -+ } -+ else -+ dhdsdio_clkctl(bus, CLK_NONE, FALSE); -+ } -+ } -+ } -+#endif /* DHD_USE_IDLECOUNT */ -+ -+ return bus->ipend; -+} -+ -+#ifdef DHD_DEBUG -+extern int -+dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ uint32 addr, val; -+ int rv; -+ void *pkt; -+ -+ /* Address could be zero if CONSOLE := 0 in dongle Makefile */ -+ if (bus->console_addr == 0) -+ return BCME_UNSUPPORTED; -+ -+ /* Exclusive bus access */ -+ dhd_os_sdlock(bus->dhd); -+ -+ /* Don't allow input if dongle is in reset */ -+ if (bus->dhd->dongle_reset) { -+ dhd_os_sdunlock(bus->dhd); -+ return BCME_NOTREADY; -+ } -+ -+ /* Request clock to allow SDIO accesses */ -+ BUS_WAKE(bus); -+ /* No pend allowed since txpkt is called later, ht clk has to be on */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ /* Zero cbuf_index */ -+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf_idx); -+ val = htol32(0); -+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) -+ goto done; -+ -+ /* Write message into cbuf */ -+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf); -+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)msg, msglen)) < 0) -+ goto done; -+ -+ /* Write length into vcons_in */ -+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, vcons_in); -+ val = htol32(msglen); -+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0) -+ goto done; -+ -+ /* Bump dongle by sending an empty packet on the event channel. -+ * sdpcm_sendup (RX) checks for virtual console input. -+ */ -+ if ((pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, TRUE)) != NULL) -+ dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, TRUE, FALSE); -+ -+done: -+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { -+ bus->activity = FALSE; -+ dhdsdio_clkctl(bus, CLK_NONE, TRUE); -+ } -+ -+ dhd_os_sdunlock(bus->dhd); -+ -+ return rv; -+} -+#endif /* DHD_DEBUG */ -+ -+#ifdef DHD_DEBUG -+static void -+dhd_dump_cis(uint fn, uint8 *cis) -+{ -+ uint byte, tag, tdata; -+ AP6210_DEBUG("Function %d CIS:\n", fn); -+ -+ for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) { -+ if ((byte % 16) == 0) -+ AP6210_DUMP(" "); -+ AP6210_DUMP("%02x ", cis[byte]); -+ if ((byte % 16) == 15) -+ AP6210_DUMP("\n"); -+ if (!tdata--) { -+ tag = cis[byte]; -+ if (tag == 0xff) -+ break; -+ else if (!tag) -+ tdata = 0; -+ else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT) -+ tdata = cis[byte + 1] + 1; -+ else -+ AP6210_DUMP("]"); -+ } -+ } -+ if ((byte % 16) != 15) -+ AP6210_DUMP("\n"); -+} -+#endif /* DHD_DEBUG */ -+ -+static bool -+dhdsdio_chipmatch(uint16 chipid) -+{ -+ if (chipid == BCM4325_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4329_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4315_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4319_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4336_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4330_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM43237_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM43362_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4314_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4334_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM43341_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM43239_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4324_CHIP_ID) -+ return TRUE; -+ if (chipid == BCM4335_CHIP_ID) -+ return TRUE; -+ return FALSE; -+} -+ -+static void * -+dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, -+ uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh) -+{ -+ int ret; -+ dhd_bus_t *bus; -+#ifdef GET_CUSTOM_MAC_ENABLE -+ struct ether_addr ea_addr; -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+ -+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { -+ AP6210_DEBUG("%s : no mutex held. set lock\n", __FUNCTION__); -+ } -+ else { -+ AP6210_DEBUG("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__); -+ } -+ mutex_lock(&_dhd_sdio_mutex_lock_); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -+ -+ /* Init global variables at run-time, not as part of the declaration. -+ * This is required to support init/de-init of the driver. Initialization -+ * of globals as part of the declaration results in non-deterministic -+ * behavior since the value of the globals may be different on the -+ * first time that the driver is initialized vs subsequent initializations. -+ */ -+ dhd_txbound = DHD_TXBOUND; -+ dhd_rxbound = DHD_RXBOUND; -+ dhd_alignctl = TRUE; -+ sd1idle = TRUE; -+ dhd_readahead = TRUE; -+ retrydata = FALSE; -+ dhd_doflow = FALSE; -+ dhd_dongle_memsize = 0; -+ dhd_txminmax = DHD_TXMINMAX; -+ -+ forcealign = TRUE; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ AP6210_DEBUG("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid); -+ -+ /* We make assumptions about address window mappings */ -+ ASSERT((uintptr)regsva == SI_ENUM_BASE); -+ -+ /* BCMSDH passes venid and devid based on CIS parsing -- but low-power start -+ * means early parse could fail, so here we should get either an ID -+ * we recognize OR (-1) indicating we must request power first. -+ */ -+ /* Check the Vendor ID */ -+ switch (venid) { -+ case 0x0000: -+ case VENDOR_BROADCOM: -+ break; -+ default: -+ AP6210_ERR("%s: unknown vendor: 0x%04x\n", -+ __FUNCTION__, venid); -+ goto forcereturn; -+ } -+ -+ /* Check the Device ID and make sure it's one that we support */ -+ switch (devid) { -+ case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ -+ case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ -+ case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ -+ AP6210_DEBUG("%s: found 4325 Dongle\n", __FUNCTION__); -+ break; -+ case BCM4329_D11N_ID: /* 4329 802.11n dualband device */ -+ case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ -+ case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ -+ case 0x4329: -+ AP6210_DEBUG("%s: found 4329 Dongle\n", __FUNCTION__); -+ break; -+ case BCM4315_D11DUAL_ID: /* 4315 802.11a/g id */ -+ case BCM4315_D11G_ID: /* 4315 802.11g id */ -+ case BCM4315_D11A_ID: /* 4315 802.11a id */ -+ AP6210_DEBUG("%s: found 4315 Dongle\n", __FUNCTION__); -+ break; -+ case BCM4319_D11N_ID: /* 4319 802.11n id */ -+ case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ -+ case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ -+ AP6210_DEBUG("%s: found 4319 Dongle\n", __FUNCTION__); -+ break; -+ case 0: -+ AP6210_DEBUG("%s: allow device id 0, will check chip internals\n", -+ __FUNCTION__); -+ break; -+ -+ default: -+ AP6210_ERR("%s: skipping 0x%04x/0x%04x, not a dongle\n", -+ __FUNCTION__, venid, devid); -+ goto forcereturn; -+ } -+ -+ if (osh == NULL) { -+ /* Ask the OS interface part for an OSL handle */ -+ if (!(osh = dhd_osl_attach(sdh, DHD_BUS))) { -+ AP6210_ERR("%s: osl_attach failed!\n", __FUNCTION__); -+ goto forcereturn; -+ } -+ } -+ -+ /* Allocate private bus interface state */ -+ if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) { -+ AP6210_ERR("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__); -+ goto fail; -+ } -+ bzero(bus, sizeof(dhd_bus_t)); -+ bus->sdh = sdh; -+ bus->cl_devid = (uint16)devid; -+ bus->bus = DHD_BUS; -+ bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; -+ bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */ -+ -+ /* attach the common module */ -+ dhd_common_init(osh); -+ -+ /* attempt to attach to the dongle */ -+ if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) { -+ AP6210_ERR("%s: dhdsdio_probe_attach failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ /* Attach to the dhd/OS/network interface */ -+ if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) { -+ AP6210_ERR("%s: dhd_attach failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ /* Allocate buffers */ -+ if (!(dhdsdio_probe_malloc(bus, osh, sdh))) { -+ AP6210_ERR("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ if (!(dhdsdio_probe_init(bus, osh, sdh))) { -+ AP6210_ERR("%s: dhdsdio_probe_init failed\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ if (bus->intr) { -+ /* Register interrupt callback, but mask it (not operational yet). */ -+ AP6210_DEBUG("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__); -+ bcmsdh_intr_disable(sdh); -+ if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) { -+ AP6210_ERR("%s: FAILED: bcmsdh_intr_reg returned %d\n", -+ __FUNCTION__, ret); -+ goto fail; -+ } -+ AP6210_DEBUG("%s: registered SDIO interrupt function ok\n", __FUNCTION__); -+ } else { -+ AP6210_DEBUG("%s: SDIO interrupt function is NOT registered due to polling mode\n", -+ __FUNCTION__); -+ } -+ -+ AP6210_DEBUG("%s: completed!!\n", __FUNCTION__); -+ -+#ifdef GET_CUSTOM_MAC_ENABLE -+ /* Read MAC address from external customer place */ -+ memset(&ea_addr, 0, sizeof(ea_addr)); -+ ret = dhd_custom_get_mac_address(ea_addr.octet); -+ if (!ret) { -+ memcpy(bus->dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN); -+ } -+#endif /* GET_CUSTOM_MAC_ENABLE */ -+ -+ /* if firmware path present try to download and bring up bus */ -+ if (dhd_download_fw_on_driverload) { -+ if ((ret = dhd_bus_start(bus->dhd)) != 0) { -+ AP6210_ERR("%s: dhd_bus_start failed\n", __FUNCTION__); -+ goto fail; -+ } -+ } -+ /* Ok, have the per-port tell the stack we're open for business */ -+ if (dhd_net_attach(bus->dhd, 0) != 0) { -+ AP6210_ERR("%s: Net attach failed!!\n", __FUNCTION__); -+ goto fail; -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+ mutex_unlock(&_dhd_sdio_mutex_lock_); -+ AP6210_DEBUG("%s : the lock is released.\n", __FUNCTION__); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+ return bus; -+ -+fail: -+ dhdsdio_release(bus, osh); -+ -+forcereturn: -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+ mutex_unlock(&_dhd_sdio_mutex_lock_); -+ AP6210_DEBUG("%s : the lock is released.\n", __FUNCTION__); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+ -+ return NULL; -+} -+ -+static bool -+dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, -+ uint16 devid) -+{ -+ int err = 0; -+ uint8 clkctl = 0; -+ -+ bus->alp_only = TRUE; -+ bus->sih = NULL; -+ -+ /* Return the window to backplane enumeration space for core access */ -+ if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) { -+ AP6210_ERR("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__); -+ } -+ -+#ifdef DHD_DEBUG -+ AP6210_DEBUG("F1 signature read @0x18000000=0x%4x\n", -+ bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4)); -+ -+#endif /* DHD_DEBUG */ -+ -+ -+ /* Force PLL off until si_attach() programs PLL control regs */ -+ -+ -+ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err); -+ if (!err) -+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); -+ -+ if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) { -+ AP6210_ERR("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", -+ err, DHD_INIT_CLKCTL1, clkctl); -+ goto fail; -+ } -+ -+#ifdef DHD_DEBUG -+ if (DHD_INFO_ON()) { -+ uint fn, numfn; -+ uint8 *cis[SDIOD_MAX_IOFUNCS]; -+ int err = 0; -+ -+ numfn = bcmsdh_query_iofnum(sdh); -+ ASSERT(numfn <= SDIOD_MAX_IOFUNCS); -+ -+ /* Make sure ALP is available before trying to read CIS */ -+ SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, NULL)), -+ !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY); -+ -+ /* Now request ALP be put on the bus */ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ DHD_INIT_CLKCTL2, &err); -+ OSL_DELAY(65); -+ -+ for (fn = 0; fn <= numfn; fn++) { -+ if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) { -+ AP6210_DEBUG("dhdsdio_probe: fn %d cis malloc failed\n", fn); -+ break; -+ } -+ bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT); -+ -+ if ((err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT))) { -+ AP6210_DEBUG("dhdsdio_probe: fn %d cis read err %d\n", fn, err); -+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); -+ break; -+ } -+ dhd_dump_cis(fn, cis[fn]); -+ } -+ -+ while (fn-- > 0) { -+ ASSERT(cis[fn]); -+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT); -+ } -+ -+ if (err) { -+ AP6210_ERR("dhdsdio_probe: failure reading or parsing CIS\n"); -+ goto fail; -+ } -+ } -+#endif /* DHD_DEBUG */ -+ -+ /* si_attach() will provide an SI handle and scan the backplane */ -+ if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh, -+ &bus->vars, &bus->varsz))) { -+ AP6210_ERR("%s: si_attach failed!\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); -+ -+ if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) { -+ AP6210_ERR("%s: unsupported chip: 0x%04x\n", -+ __FUNCTION__, bus->sih->chip); -+ goto fail; -+ } -+ -+ if (bus->sih->buscorerev >= 12) -+ dhdsdio_clk_kso_init(bus); -+ else -+ bus->kso = TRUE; -+ -+ if (CST4330_CHIPMODE_SDIOD(bus->sih->chipst)) { -+ } -+ -+ si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); -+ -+ -+ /* Get info on the ARM and SOCRAM cores... */ -+ if (!DHD_NOPMU(bus)) { -+ if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) || -+ (si_setcore(bus->sih, ARMCM3_CORE_ID, 0)) || -+ (si_setcore(bus->sih, ARMCR4_CORE_ID, 0))) { -+ bus->armrev = si_corerev(bus->sih); -+ } else { -+ AP6210_ERR("%s: failed to find ARM core!\n", __FUNCTION__); -+ goto fail; -+ } -+ -+ if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { -+ if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { -+ AP6210_ERR("%s: failed to find SOCRAM memory!\n", __FUNCTION__); -+ goto fail; -+ } -+ } else { -+ /* cr4 has a different way to find the RAM size from TCM's */ -+ if (!(bus->orig_ramsize = si_tcm_size(bus->sih))) { -+ AP6210_ERR("%s: failed to find CR4-TCM memory!\n", __FUNCTION__); -+ goto fail; -+ } -+ /* also populate base address */ -+ bus->dongle_ram_base = CR4_RAM_BASE; -+ } -+ bus->ramsize = bus->orig_ramsize; -+ if (dhd_dongle_memsize) -+ dhd_dongle_setmemsize(bus, dhd_dongle_memsize); -+ -+ AP6210_DEBUG("DHD: dongle ram size is set to %d(orig %d)\n", -+ bus->ramsize, bus->orig_ramsize); -+ -+ bus->srmemsize = si_socram_srmem_size(bus->sih); -+ } -+ -+ /* ...but normally deal with the SDPCMDEV core */ -+ if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) && -+ !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) { -+ AP6210_ERR("%s: failed to find SDIODEV core!\n", __FUNCTION__); -+ goto fail; -+ } -+ bus->sdpcmrev = si_corerev(bus->sih); -+ -+ /* Set core control so an SDIO reset does a backplane reset */ -+ OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN); -+ bus->rxint_mode = SDIO_DEVICE_HMB_RXINT; -+ -+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) && -+ (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1)) -+ { -+ uint32 val; -+ -+ val = R_REG(osh, &bus->regs->corecontrol); -+ val &= ~CC_XMTDATAAVAIL_MODE; -+ val |= CC_XMTDATAAVAIL_CTRL; -+ W_REG(osh, &bus->regs->corecontrol, val); -+ } -+ -+ -+ pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); -+ -+ /* Locate an appropriately-aligned portion of hdrbuf */ -+ bus->rxhdr = (uint8 *)ROUNDUP((uintptr)&bus->hdrbuf[0], DHD_SDALIGN); -+ -+ /* Set the poll and/or interrupt flags */ -+ bus->intr = (bool)dhd_intr; -+ if ((bus->poll = (bool)dhd_poll)) -+ bus->pollrate = 1; -+ -+#ifdef BCMSDIOH_TXGLOM -+ /* Setting default Glom mode */ -+ bus->glom_mode = SDPCM_TXGLOM_CPY; -+ /* Setting default Glom size */ -+ bus->glomsize = SDPCM_DEFGLOM_SIZE; -+#endif -+ -+ return TRUE; -+ -+fail: -+ if (bus->sih != NULL) { -+ si_detach(bus->sih); -+ bus->sih = NULL; -+ } -+ return FALSE; -+} -+ -+static bool -+dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus->dhd->maxctl) { -+ bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN; -+ if (!(bus->rxbuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_RXBUF, bus->rxblen))) { -+ AP6210_ERR("%s: MALLOC of %d-byte rxbuf failed\n", -+ __FUNCTION__, bus->rxblen); -+ goto fail; -+ } -+ } -+ /* Allocate buffer to receive glomed packet */ -+ if (!(bus->databuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_DATABUF, MAX_DATA_BUF))) { -+ AP6210_ERR("%s: MALLOC of %d-byte databuf failed\n", -+ __FUNCTION__, MAX_DATA_BUF); -+ /* release rxbuf which was already located as above */ -+ if (!bus->rxblen) -+ DHD_OS_PREFREE(osh, bus->rxbuf, bus->rxblen); -+ goto fail; -+ } -+ -+ /* Align the buffer */ -+ if ((uintptr)bus->databuf % DHD_SDALIGN) -+ bus->dataptr = bus->databuf + (DHD_SDALIGN - ((uintptr)bus->databuf % DHD_SDALIGN)); -+ else -+ bus->dataptr = bus->databuf; -+ -+ return TRUE; -+ -+fail: -+ return FALSE; -+} -+ -+static bool -+dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) -+{ -+ int32 fnum; -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+#ifdef SDTEST -+ dhdsdio_pktgen_init(bus); -+#endif /* SDTEST */ -+ -+ /* Disable F2 to clear any intermediate frame state on the dongle */ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); -+ -+ bus->dhd->busstate = DHD_BUS_DOWN; -+ bus->sleeping = FALSE; -+ bus->rxflow = FALSE; -+ bus->prev_rxlim_hit = 0; -+ -+ /* Done with backplane-dependent accesses, can drop clock... */ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); -+ -+ /* ...and initialize clock/power states */ -+ bus->clkstate = CLK_SDONLY; -+ bus->idletime = (int32)dhd_idletime; -+ bus->idleclock = DHD_IDLE_ACTIVE; -+ -+ /* Query the SD clock speed */ -+ if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, -+ &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) { -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_divisor"); -+ bus->sd_divisor = -1; -+ } else { -+ AP6210_DEBUG("%s: Initial value for %s is %d\n", -+ __FUNCTION__, "sd_divisor", bus->sd_divisor); -+ } -+ -+ /* Query the SD bus mode */ -+ if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, -+ &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) { -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_mode"); -+ bus->sd_mode = -1; -+ } else { -+ AP6210_DEBUG("%s: Initial value for %s is %d\n", -+ __FUNCTION__, "sd_mode", bus->sd_mode); -+ } -+ -+ /* Query the F2 block size, set roundup accordingly */ -+ fnum = 2; -+ if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(int32), -+ &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) { -+ bus->blocksize = 0; -+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize"); -+ } else { -+ AP6210_DEBUG("%s: Initial value for %s is %d\n", -+ __FUNCTION__, "sd_blocksize", bus->blocksize); -+ } -+ bus->roundup = MIN(max_roundup, bus->blocksize); -+ -+ /* Query if bus module supports packet chaining, default to use if supported */ -+ if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, -+ &bus->sd_rxchain, sizeof(int32), FALSE) != BCME_OK) { -+ bus->sd_rxchain = FALSE; -+ } else { -+ AP6210_DEBUG("%s: bus module (through bcmsdh API) %s chaining\n", -+ __FUNCTION__, (bus->sd_rxchain ? "supports" : "does not support")); -+ } -+ bus->use_rxchain = (bool)bus->sd_rxchain; -+ -+ return TRUE; -+} -+ -+void -+dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src) -+{ -+ int fw_type, ag_type; -+ static uint chip, chiprev, first=1; -+ int i; -+ -+ if (first) { -+ chip = bus->sih->chip; -+ chiprev = bus->sih->chiprev; -+ first = 0; -+ } -+ if (src[0] == '\0') { -+#ifdef CONFIG_AP6210_FW_PATH -+ bcm_strncpy_s(src, sizeof(fw_path), CONFIG_AP6210_FW_PATH, MOD_PARAM_PATHLEN-1); -+ if (src[0] == '\0') -+#endif -+ { -+ AP6210_DEBUG("src firmware path is null\n"); -+ return; -+ } -+ } -+ -+ strcpy(dst, src); -+#ifndef FW_PATH_AUTO_SELECT -+ return; -+#endif -+ -+ /* find out the last '/' */ -+ i = strlen(dst); -+ while (i>0){ -+ if (dst[i] == '/') break; -+ i--; -+ } -+#ifdef BAND_AG -+ ag_type = FW_TYPE_AG; -+#else -+ ag_type = strstr(&dst[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; -+#endif -+ fw_type = (strstr(&dst[i], "_mfg") ? -+ FW_TYPE_MFG : (strstr(&dst[i], "_apsta") ? -+ FW_TYPE_APSTA : (strstr(&dst[i], "_p2p") ? -+ FW_TYPE_P2P : FW_TYPE_STA))); -+ -+ -+ switch (chip) { -+ case BCM4330_CHIP_ID: -+ if (ag_type == FW_TYPE_G) { -+ if (chiprev == BCM4330B2_CHIP_REV) -+ strcpy(&dst[i+1], bcm40183b2_fw_name[fw_type]); -+ break; -+ } else { -+ if (chiprev == BCM4330B2_CHIP_REV) -+ strcpy(&dst[i+1], bcm40183b2ag_fw_name[fw_type]); -+ break; -+ } -+ case BCM43362_CHIP_ID: -+ if (chiprev == BCM43362A0_CHIP_REV) -+ strcpy(&dst[i+1], bcm40181a0_fw_name[fw_type]); -+ else -+ strcpy(&dst[i+1], bcm40181a2_fw_name[fw_type]); -+ break; -+ case BCM43341_CHIP_ID: -+ if (chiprev == BCM43341B0_CHIP_REV) -+ strcpy(&dst[i+1], bcm43341b0ag_fw_name[fw_type]); -+ break; -+ case BCM4324_CHIP_ID: -+ if (chiprev == BCM43241B4_CHIP_REV) -+ strcpy(&dst[i+1], bcm43241b4ag_fw_name[fw_type]); -+ break; -+ } -+ -+ AP6210_DEBUG("%s: firmware_path=%s\n", __FUNCTION__, dst); -+} -+ -+bool -+dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, -+ char *pfw_path, char *pnv_path) -+{ -+ bool ret; -+ bus->fw_path = pfw_path; -+ bus->nv_path = pnv_path; -+ -+ ret = dhdsdio_download_firmware(bus, osh, bus->sdh); -+ -+ -+ return ret; -+} -+ -+static bool -+dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) -+{ -+ bool ret; -+ -+ DHD_OS_WAKE_LOCK(bus->dhd); -+ -+ /* Download the firmware */ -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ -+ AP6210_ERR("Final fw_path=%s\n", bus->fw_path); -+ AP6210_ERR("Final nv_path=%s\n", bus->nv_path); -+ ret = _dhdsdio_download_firmware(bus) == 0; -+ -+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); -+ -+ DHD_OS_WAKE_UNLOCK(bus->dhd); -+ return ret; -+} -+ -+/* Detach and free everything */ -+static void -+dhdsdio_release(dhd_bus_t *bus, osl_t *osh) -+{ -+ bool dongle_isolation = FALSE; -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus) { -+ ASSERT(osh); -+ -+ if (bus->dhd) { -+ dongle_isolation = bus->dhd->dongle_isolation; -+ dhd_detach(bus->dhd); -+ } -+ -+ /* De-register interrupt handler */ -+ bcmsdh_intr_disable(bus->sdh); -+ bcmsdh_intr_dereg(bus->sdh); -+ -+ if (bus->dhd) { -+ dhdsdio_release_dongle(bus, osh, dongle_isolation, TRUE); -+ dhd_free(bus->dhd); -+ bus->dhd = NULL; -+ } -+ -+ dhdsdio_release_malloc(bus, osh); -+ -+#ifdef DHD_DEBUG -+ if (bus->console.buf != NULL) -+ MFREE(osh, bus->console.buf, bus->console.bufsize); -+#endif -+ -+ MFREE(osh, bus, sizeof(dhd_bus_t)); -+ } -+ -+ if (osh) -+ dhd_osl_detach(osh); -+ -+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__); -+} -+ -+static void -+dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus->dhd && bus->dhd->dongle_reset) -+ return; -+ -+ if (bus->rxbuf) { -+#ifndef CONFIG_DHD_USE_STATIC_BUF -+ MFREE(osh, bus->rxbuf, bus->rxblen); -+#endif -+ bus->rxctl = bus->rxbuf = NULL; -+ bus->rxlen = 0; -+ } -+ -+ if (bus->databuf) { -+#ifndef CONFIG_DHD_USE_STATIC_BUF -+ MFREE(osh, bus->databuf, MAX_DATA_BUF); -+#endif -+ bus->databuf = NULL; -+ } -+ -+ if (bus->vars && bus->varsz) { -+ MFREE(osh, bus->vars, bus->varsz); -+ bus->vars = NULL; -+ } -+ -+} -+ -+ -+static void -+dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bool reset_flag) -+{ -+ AP6210_DEBUG("%s: Enter bus->dhd %p bus->dhd->dongle_reset %d \n", __FUNCTION__, -+ bus->dhd, bus->dhd->dongle_reset); -+ -+ if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag) -+ return; -+ -+ if (bus->sih) { -+#if !defined(BCMLXSDMMC) -+ if (bus->dhd) { -+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); -+ } -+ if (KSO_ENAB(bus) && (dongle_isolation == FALSE)) -+ si_watchdog(bus->sih, 4); -+#endif /* !defined(BCMLXSDMMC) */ -+ if (bus->dhd) { -+ dhdsdio_clkctl(bus, CLK_NONE, FALSE); -+ } -+ si_detach(bus->sih); -+ bus->sih = NULL; -+ if (bus->vars && bus->varsz) -+ MFREE(osh, bus->vars, bus->varsz); -+ bus->vars = NULL; -+ } -+ -+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__); -+} -+ -+static void -+dhdsdio_disconnect(void *ptr) -+{ -+ dhd_bus_t *bus = (dhd_bus_t *)ptr; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+ -+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { -+ AP6210_DEBUG("%s : no mutex held. set lock\n", __FUNCTION__); -+ } -+ else { -+ AP6210_DEBUG("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__); -+ } -+ mutex_lock(&_dhd_sdio_mutex_lock_); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -+ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ if (bus) { -+ ASSERT(bus->dhd); -+ dhdsdio_release(bus, bus->dhd->osh); -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) -+ mutex_unlock(&_dhd_sdio_mutex_lock_); -+ AP6210_ERR("%s : the lock is released.\n", __FUNCTION__); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ -+ -+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__); -+} -+ -+ -+/* Register/Unregister functions are called by the main DHD entry -+ * point (e.g. module insertion) to link with the bus driver, in -+ * order to look for or await the device. -+ */ -+ -+static bcmsdh_driver_t dhd_sdio = { -+ dhdsdio_probe, -+ dhdsdio_disconnect -+}; -+ -+int -+dhd_bus_register(void) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ return bcmsdh_register(&dhd_sdio); -+} -+ -+void -+dhd_bus_unregister(void) -+{ -+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__); -+ -+ bcmsdh_unregister(); -+} -+ -+#if defined(BCMLXSDMMC) -+/* Register a dummy SDIO client driver in order to be notified of new SDIO device */ -+int dhd_bus_reg_sdio_notify(void* semaphore) -+{ -+ return bcmsdh_reg_sdio_notify(semaphore); -+} -+ -+void dhd_bus_unreg_sdio_notify(void) -+{ -+ bcmsdh_unreg_sdio_notify(); -+} -+#endif /* defined(BCMLXSDMMC) */ -+ -+#ifdef BCMEMBEDIMAGE -+static int -+dhdsdio_download_code_array(struct dhd_bus *bus) -+{ -+ int bcmerror = -1; -+ int offset = 0; -+ unsigned char *ularray = NULL; -+ -+ AP6210_ERR("%s: download embedded firmware...\n", __FUNCTION__); -+ -+ /* Download image */ -+ while ((offset + MEMBLOCK) < sizeof(dlarray)) { -+ bcmerror = dhdsdio_membytes(bus, TRUE, offset, -+ (uint8 *) (dlarray + offset), MEMBLOCK); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, MEMBLOCK, offset); -+ goto err; -+ } -+ -+ offset += MEMBLOCK; -+ } -+ -+ if (offset < sizeof(dlarray)) { -+ bcmerror = dhdsdio_membytes(bus, TRUE, offset, -+ (uint8 *) (dlarray + offset), sizeof(dlarray) - offset); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset); -+ goto err; -+ } -+ } -+ -+#ifdef DHD_DEBUG -+ /* Upload and compare the downloaded code */ -+ { -+ ularray = MALLOC(bus->dhd->osh, bus->ramsize); -+ /* Upload image to verify downloaded contents. */ -+ offset = 0; -+ memset(ularray, 0xaa, bus->ramsize); -+ while ((offset + MEMBLOCK) < sizeof(dlarray)) { -+ bcmerror = dhdsdio_membytes(bus, FALSE, offset, ularray + offset, MEMBLOCK); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, MEMBLOCK, offset); -+ goto err; -+ } -+ -+ offset += MEMBLOCK; -+ } -+ -+ if (offset < sizeof(dlarray)) { -+ bcmerror = dhdsdio_membytes(bus, FALSE, offset, -+ ularray + offset, sizeof(dlarray) - offset); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset); -+ goto err; -+ } -+ } -+ -+ if (memcmp(dlarray, ularray, sizeof(dlarray))) { -+ AP6210_ERR("%s: Downloaded image is corrupted (%s, %s, %s).\n", -+ __FUNCTION__, dlimagename, dlimagever, dlimagedate); -+ goto err; -+ } else -+ AP6210_ERR("%s: Download, Upload and compare succeeded (%s, %s, %s).\n", -+ __FUNCTION__, dlimagename, dlimagever, dlimagedate); -+ -+ } -+#endif /* DHD_DEBUG */ -+ -+err: -+ if (ularray) -+ MFREE(bus->dhd->osh, ularray, bus->ramsize); -+ return bcmerror; -+} -+#endif /* BCMEMBEDIMAGE */ -+ -+static int -+dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path) -+{ -+ int bcmerror = -1; -+ int offset = 0; -+ int len; -+ void *image = NULL; -+ uint8 *memblock = NULL, *memptr; -+ uint8 *memptr_tmp = NULL; // terence: check downloaded firmware is correct -+ -+ AP6210_ERR("download firmware %s\n", pfw_path); -+ -+ image = dhd_os_open_image(pfw_path); -+ if (image == NULL) -+ goto err; -+ -+ memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); -+ if (memblock == NULL) { -+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK); -+ goto err; -+ } -+ if (dhd_msg_level & DHD_TRACE_VAL) { -+ memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); -+ if (memptr_tmp == NULL) { -+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK); -+ goto err; -+ } -+ } -+ if ((uint32)(uintptr)memblock % DHD_SDALIGN) -+ memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); -+ -+ /* Download image */ -+ while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, image))) { -+ if (len < 0) { -+ AP6210_ERR("%s: dhd_os_get_image_block failed (%d)\n", __FUNCTION__, len); -+ bcmerror = BCME_ERROR; -+ goto err; -+ } -+ bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, MEMBLOCK, offset); -+ goto err; -+ } -+ -+ if (dhd_msg_level & DHD_TRACE_VAL) { -+ bcmerror = dhdsdio_membytes(bus, FALSE, offset, memptr_tmp, len); -+ if (bcmerror) { -+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n", -+ __FUNCTION__, bcmerror, MEMBLOCK, offset); -+ goto err; -+ } -+ if (memcmp(memptr_tmp, memptr, len)) { -+ AP6210_ERR("%s: Downloaded image is corrupted.\n", __FUNCTION__); -+ goto err; -+ } else -+ AP6210_ERR("%s: Download, Upload and compare succeeded.\n", __FUNCTION__); -+ } -+ offset += MEMBLOCK; -+ } -+ -+err: -+ if (memblock) -+ MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN); -+ if (dhd_msg_level & DHD_TRACE_VAL) { -+ if (memptr_tmp) -+ MFREE(bus->dhd->osh, memptr_tmp, MEMBLOCK + DHD_SDALIGN); -+ } -+ -+ if (image) -+ dhd_os_close_image(image); -+ -+ return bcmerror; -+} -+ -+/* -+ EXAMPLE: nvram_array -+ nvram_arry format: -+ name=value -+ Use carriage return at the end of each assignment, and an empty string with -+ carriage return at the end of array. -+ -+ For example: -+ unsigned char nvram_array[] = {"name1=value1\n", "name2=value2\n", "\n"}; -+ Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx. -+ -+ Search "EXAMPLE: nvram_array" to see how the array is activated. -+*/ -+ -+void -+dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params) -+{ -+ bus->nvram_params = nvram_params; -+} -+ -+static int -+dhdsdio_download_nvram(struct dhd_bus *bus) -+{ -+ int bcmerror = -1; -+ uint len; -+ void * image = NULL; -+ char * memblock = NULL; -+ char *bufp; -+ char *pnv_path; -+ bool nvram_file_exists; -+ -+ pnv_path = bus->nv_path; -+ -+ nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0')); -+ if (!nvram_file_exists && (bus->nvram_params == NULL)) -+ return (0); -+ -+ if (nvram_file_exists) { -+ image = dhd_os_open_image(pnv_path); -+ if (image == NULL) -+ goto err; -+ } -+ -+ memblock = MALLOC(bus->dhd->osh, MAX_NVRAMBUF_SIZE); -+ if (memblock == NULL) { -+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n", -+ __FUNCTION__, MAX_NVRAMBUF_SIZE); -+ goto err; -+ } -+ -+ /* Download variables */ -+ if (nvram_file_exists) { -+ len = dhd_os_get_image_block(memblock, MAX_NVRAMBUF_SIZE, image); -+ } -+ else { -+ len = strlen(bus->nvram_params); -+ ASSERT(len <= MAX_NVRAMBUF_SIZE); -+ memcpy(memblock, bus->nvram_params, len); -+ } -+ if (len > 0 && len < MAX_NVRAMBUF_SIZE) { -+ bufp = (char *)memblock; -+ bufp[len] = 0; -+ len = process_nvram_vars(bufp, len); -+ if (len % 4) { -+ len += 4 - (len % 4); -+ } -+ bufp += len; -+ *bufp++ = 0; -+ if (len) -+ bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); -+ if (bcmerror) { -+ AP6210_ERR("%s: error downloading vars: %d\n", -+ __FUNCTION__, bcmerror); -+ } -+ } -+ else { -+ AP6210_ERR("%s: error reading nvram file: %d\n", -+ __FUNCTION__, len); -+ bcmerror = BCME_SDIO_ERROR; -+ } -+ -+err: -+ if (memblock) -+ MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE); -+ -+ if (image) -+ dhd_os_close_image(image); -+ -+ return bcmerror; -+} -+ -+static int -+_dhdsdio_download_firmware(struct dhd_bus *bus) -+{ -+ int bcmerror = -1; -+ -+ bool embed = FALSE; /* download embedded firmware */ -+ bool dlok = FALSE; /* download firmware succeeded */ -+ -+ /* Out immediately if no image to download */ -+ if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) { -+#ifdef BCMEMBEDIMAGE -+ embed = TRUE; -+#else -+ return 0; -+#endif -+ } -+ -+ /* Keep arm in reset */ -+ if (dhdsdio_download_state(bus, TRUE)) { -+ AP6210_ERR("%s: error placing ARM core in reset\n", __FUNCTION__); -+ goto err; -+ } -+ -+ /* External image takes precedence if specified */ -+ if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { -+ if (dhdsdio_download_code_file(bus, bus->fw_path)) { -+ AP6210_ERR("%s: dongle image file download failed\n", __FUNCTION__); -+#ifdef BCMEMBEDIMAGE -+ embed = TRUE; -+#else -+ goto err; -+#endif -+ } -+ else { -+ embed = FALSE; -+ dlok = TRUE; -+ } -+ } -+#ifdef BCMEMBEDIMAGE -+ if (embed) { -+ if (dhdsdio_download_code_array(bus)) { -+ AP6210_ERR("%s: dongle image array download failed\n", __FUNCTION__); -+ goto err; -+ } -+ else { -+ dlok = TRUE; -+ } -+ } -+#else -+ BCM_REFERENCE(embed); -+#endif -+ if (!dlok) { -+ AP6210_ERR("%s: dongle image download failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ /* EXAMPLE: nvram_array */ -+ /* If a valid nvram_arry is specified as above, it can be passed down to dongle */ -+ /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ -+ -+ /* External nvram takes precedence if specified */ -+ if (dhdsdio_download_nvram(bus)) { -+ AP6210_ERR("%s: dongle nvram file download failed\n", __FUNCTION__); -+ goto err; -+ } -+ -+ /* Take arm out of reset */ -+ if (dhdsdio_download_state(bus, FALSE)) { -+ AP6210_ERR("%s: error getting out of ARM core reset\n", __FUNCTION__); -+ goto err; -+ } -+ -+ bcmerror = 0; -+ -+err: -+ return bcmerror; -+} -+ -+static int -+dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, -+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -+{ -+ int status; -+ -+ if (!KSO_ENAB(bus)) { -+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__); -+ return BCME_NODEVICE; -+ } -+ -+ status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle); -+ -+ return status; -+} -+ -+static int -+dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, -+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) -+{ -+ if (!KSO_ENAB(bus)) { -+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__); -+ return BCME_NODEVICE; -+ } -+ -+ return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle)); -+} -+ -+#ifdef BCMSDIOH_TXGLOM -+static void -+dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len) -+{ -+ bcmsdh_glom_post(bus->sdh, frame, len); -+} -+ -+static void -+dhd_bcmsdh_glom_clear(dhd_bus_t *bus) -+{ -+ bcmsdh_glom_clear(bus->sdh); -+} -+#endif -+ -+uint -+dhd_bus_chip(struct dhd_bus *bus) -+{ -+ ASSERT(bus->sih != NULL); -+ return bus->sih->chip; -+} -+ -+void * -+dhd_bus_pub(struct dhd_bus *bus) -+{ -+ return bus->dhd; -+} -+ -+void * -+dhd_bus_txq(struct dhd_bus *bus) -+{ -+ return &bus->txq; -+} -+ -+uint -+dhd_bus_hdrlen(struct dhd_bus *bus) -+{ -+ return SDPCM_HDRLEN; -+} -+ -+int -+dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) -+{ -+ int bcmerror = 0; -+ dhd_bus_t *bus; -+ -+ bus = dhdp->bus; -+ -+ if (flag == TRUE) { -+ if (!bus->dhd->dongle_reset) { -+ dhd_os_sdlock(dhdp); -+ dhd_os_wd_timer(dhdp, 0); -+#if !defined(IGNORE_ETH0_DOWN) -+ /* Force flow control as protection when stop come before ifconfig_down */ -+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON); -+#endif /* !defined(IGNORE_ETH0_DOWN) */ -+ /* Expect app to have torn down any connection before calling */ -+ /* Stop the bus, disable F2 */ -+ dhd_bus_stop(bus, FALSE); -+ -+#if defined(OOB_INTR_ONLY) -+ /* Clean up any pending IRQ */ -+ bcmsdh_set_irq(FALSE); -+#endif -+ -+ /* Clean tx/rx buffer pointers, detach from the dongle */ -+ dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE, TRUE); -+ -+ bus->dhd->dongle_reset = TRUE; -+ bus->dhd->up = FALSE; -+#ifdef BCMSDIOH_TXGLOM -+ dhd_txglom_enable(dhdp, FALSE); -+#endif -+ dhd_os_sdunlock(dhdp); -+ -+ AP6210_ERR("%s: WLAN OFF DONE\n", __FUNCTION__); -+ /* App can now remove power from device */ -+ } else -+ bcmerror = BCME_SDIO_ERROR; -+ } else { -+ /* App must have restored power to device before calling */ -+ -+ AP6210_ERR("%s: WLAN ON\n", __FUNCTION__); -+ -+ if (bus->dhd->dongle_reset) { -+ /* Turn on WLAN */ -+#ifdef DHDTHREAD -+ dhd_os_sdlock(dhdp); -+#endif /* DHDTHREAD */ -+ /* Reset SD client */ -+ bcmsdh_reset(bus->sdh); -+ -+ /* Attempt to re-attach & download */ -+ if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh, -+ (uint32 *)SI_ENUM_BASE, -+ bus->cl_devid)) { -+ /* Attempt to download binary to the dongle */ -+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); // terence -+ if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) && -+ dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) { -+ -+ /* Re-init bus, enable F2 transfer */ -+ bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); -+ if (bcmerror == BCME_OK) { -+#if defined(OOB_INTR_ONLY) -+ bcmsdh_set_irq(TRUE); -+ dhd_enable_oob_intr(bus, TRUE); -+#endif -+ -+ bus->dhd->dongle_reset = FALSE; -+ bus->dhd->up = TRUE; -+ -+#if !defined(IGNORE_ETH0_DOWN) -+ /* Restore flow control */ -+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF); -+#endif -+ dhd_os_wd_timer(dhdp, dhd_watchdog_ms); -+#ifdef BCMSDIOH_TXGLOM -+ if ((dhdp->busstate == DHD_BUS_DATA) && -+ bcmsdh_glom_enabled()) { -+ dhd_txglom_enable(dhdp, TRUE); -+ } -+#endif /* BCMSDIOH_TXGLOM */ -+ AP6210_ERR("%s: WLAN ON DONE\n", __FUNCTION__); -+ } else { -+ dhd_bus_stop(bus, FALSE); -+ dhdsdio_release_dongle(bus, bus->dhd->osh, -+ TRUE, FALSE); -+ } -+ } else -+ bcmerror = BCME_SDIO_ERROR; -+ } else -+ bcmerror = BCME_SDIO_ERROR; -+ -+#ifdef DHDTHREAD -+ dhd_os_sdunlock(dhdp); -+#endif /* DHDTHREAD */ -+ } else { -+ bcmerror = BCME_SDIO_ERROR; -+ AP6210_DEBUG("%s called when dongle is not in reset\n", -+ __FUNCTION__); -+ AP6210_DEBUG("Will call dhd_bus_start instead\n"); -+ sdioh_start(NULL, 1); -+#if defined(HW_OOB) -+ bcmsdh_config_hw_oob_intr(bus->sdh, bus->sih->chip); // terence 20120615: fix for OOB initial issue -+#endif -+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); -+ if ((bcmerror = dhd_bus_start(dhdp)) != 0) -+ AP6210_ERR("%s: dhd_bus_start fail with %d\n", -+ __FUNCTION__, bcmerror); -+ } -+ } -+ return bcmerror; -+} -+ -+/* Get Chip ID version */ -+uint dhd_bus_chip_id(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ -+ return bus->sih->chip; -+} -+ -+/* Get Chip Rev ID version */ -+uint dhd_bus_chiprev_id(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ -+ return bus->sih->chiprev; -+} -+ -+/* Get Chip Pkg ID version */ -+uint dhd_bus_chippkg_id(dhd_pub_t *dhdp) -+{ -+ dhd_bus_t *bus = dhdp->bus; -+ -+ return bus->sih->chippkg; -+} -+ -+int -+dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size) -+{ -+ dhd_bus_t *bus; -+ -+ bus = dhdp->bus; -+ return dhdsdio_membytes(bus, set, address, data, size); -+} -diff --git a/drivers/net/wireless/ap6210/dhd_wlfc.c b/drivers/net/wireless/ap6210/dhd_wlfc.c -new file mode 100644 -index 0000000..93b4ca3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_wlfc.c -@@ -0,0 +1,2441 @@ -+/* -+ * DHD PROP_TXSTATUS Module. -+ * -+ * Copyright (C) 1999-2013, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_wlfc.c 412994 2013-07-17 12:38:03Z $ -+ * -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#ifdef PROP_TXSTATUS -+#include -+#include -+#endif -+ -+ -+ -+ -+#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */ -+ -+#ifdef PROP_TXSTATUS -+typedef struct dhd_wlfc_commit_info { -+ uint8 needs_hdr; -+ uint8 ac_fifo_credit_spent; -+ ewlfc_packet_state_t pkt_type; -+ wlfc_mac_descriptor_t* mac_entry; -+ void* p; -+} dhd_wlfc_commit_info_t; -+#endif /* PROP_TXSTATUS */ -+ -+ -+#ifdef PROP_TXSTATUS -+ -+#define DHD_WLFC_QMON_COMPLETE(entry) -+ -+void -+dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -+{ -+ int i; -+ uint8* ea; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhdp->wlfc_state; -+ wlfc_hanger_t* h; -+ wlfc_mac_descriptor_t* mac_table; -+ wlfc_mac_descriptor_t* interfaces; -+ char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"}; -+ -+ if (wlfc == NULL) { -+ bcm_bprintf(strbuf, "wlfc not initialized yet\n"); -+ return; -+ } -+ h = (wlfc_hanger_t*)wlfc->hanger; -+ if (h == NULL) { -+ bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n"); -+ } -+ -+ mac_table = wlfc->destination_entries.nodes; -+ interfaces = wlfc->destination_entries.interfaces; -+ bcm_bprintf(strbuf, "---- wlfc stats ----\n"); -+ if (h) { -+ bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push," -+ "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n", -+ h->pushed, -+ h->popped, -+ h->failed_to_push, -+ h->failed_to_pop, -+ h->failed_slotfind, -+ (h->pushed - h->popped)); -+ } -+ -+ bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), " -+ "(dq_full,rollback_fail) = (%d,%d,%d,%d), (%d,%d)\n", -+ wlfc->stats.tlv_parse_failed, -+ wlfc->stats.credit_request_failed, -+ wlfc->stats.mac_update_failed, -+ wlfc->stats.psmode_update_failed, -+ wlfc->stats.delayq_full_error, -+ wlfc->stats.rollback_failed); -+ -+ bcm_bprintf(strbuf, "PKTS (credit,sent) " -+ "(AC0[%d,%d],AC1[%d,%d],AC2[%d,%d],AC3[%d,%d],BC_MC[%d,%d])\n", -+ wlfc->FIFO_credit[0], wlfc->stats.send_pkts[0], -+ wlfc->FIFO_credit[1], wlfc->stats.send_pkts[1], -+ wlfc->FIFO_credit[2], wlfc->stats.send_pkts[2], -+ wlfc->FIFO_credit[3], wlfc->stats.send_pkts[3], -+ wlfc->FIFO_credit[4], wlfc->stats.send_pkts[4]); -+ -+ bcm_bprintf(strbuf, "\n"); -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (interfaces[i].occupied) { -+ char* iftype_desc; -+ -+ if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT) -+ iftype_desc = "hostif_flow_state[i] == OFF) -+ ? " OFF":" ON")); -+ -+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)" -+ "= (%d,%s,%d)\n", -+ i, -+ interfaces[i].psq.len, -+ ((interfaces[i].state == -+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), -+ interfaces[i].requested_credit); -+ -+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ" -+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " -+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", -+ i, -+ interfaces[i].psq.q[0].len, -+ interfaces[i].psq.q[1].len, -+ interfaces[i].psq.q[2].len, -+ interfaces[i].psq.q[3].len, -+ interfaces[i].psq.q[4].len, -+ interfaces[i].psq.q[5].len, -+ interfaces[i].psq.q[6].len, -+ interfaces[i].psq.q[7].len); -+ } -+ } -+ -+ bcm_bprintf(strbuf, "\n"); -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (mac_table[i].occupied) { -+ ea = mac_table[i].ea; -+ bcm_bprintf(strbuf, "MAC_table[%d].ea = " -+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i, -+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], -+ mac_table[i].interface_id); -+ -+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)" -+ "= (%d,%s,%d)\n", -+ i, -+ mac_table[i].psq.len, -+ ((mac_table[i].state == -+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), -+ mac_table[i].requested_credit); -+#ifdef PROP_TXSTATUS_DEBUG -+ bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n", -+ i, mac_table[i].opened_ct, mac_table[i].closed_ct); -+#endif -+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ" -+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " -+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", -+ i, -+ mac_table[i].psq.q[0].len, -+ mac_table[i].psq.q[1].len, -+ mac_table[i].psq.q[2].len, -+ mac_table[i].psq.q[3].len, -+ mac_table[i].psq.q[4].len, -+ mac_table[i].psq.q[5].len, -+ mac_table[i].psq.q[6].len, -+ mac_table[i].psq.q[7].len); -+ } -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ int avg; -+ int moving_avg = 0; -+ int moving_samples; -+ -+ if (wlfc->stats.latency_sample_count) { -+ moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32); -+ -+ for (i = 0; i < moving_samples; i++) -+ moving_avg += wlfc->stats.deltas[i]; -+ moving_avg /= moving_samples; -+ -+ avg = (100 * wlfc->stats.total_status_latency) / -+ wlfc->stats.latency_sample_count; -+ bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = " -+ "(%d.%d, %03d, %03d)\n", -+ moving_samples, avg/100, (avg - (avg/100)*100), -+ wlfc->stats.latency_most_recent, -+ moving_avg); -+ } -+ } -+ -+ bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), " -+ "back = (%d,%d,%d,%d,%d,%d)\n", -+ wlfc->stats.fifo_credits_sent[0], -+ wlfc->stats.fifo_credits_sent[1], -+ wlfc->stats.fifo_credits_sent[2], -+ wlfc->stats.fifo_credits_sent[3], -+ wlfc->stats.fifo_credits_sent[4], -+ wlfc->stats.fifo_credits_sent[5], -+ -+ wlfc->stats.fifo_credits_back[0], -+ wlfc->stats.fifo_credits_back[1], -+ wlfc->stats.fifo_credits_back[2], -+ wlfc->stats.fifo_credits_back[3], -+ wlfc->stats.fifo_credits_back[4], -+ wlfc->stats.fifo_credits_back[5]); -+ { -+ uint32 fifo_cr_sent = 0; -+ uint32 fifo_cr_acked = 0; -+ uint32 request_cr_sent = 0; -+ uint32 request_cr_ack = 0; -+ uint32 bc_mc_cr_ack = 0; -+ -+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) { -+ fifo_cr_sent += wlfc->stats.fifo_credits_sent[i]; -+ } -+ -+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) { -+ fifo_cr_acked += wlfc->stats.fifo_credits_back[i]; -+ } -+ -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (wlfc->destination_entries.nodes[i].occupied) { -+ request_cr_sent += -+ wlfc->destination_entries.nodes[i].dstncredit_sent_packets; -+ } -+ } -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (wlfc->destination_entries.interfaces[i].occupied) { -+ request_cr_sent += -+ wlfc->destination_entries.interfaces[i].dstncredit_sent_packets; -+ } -+ } -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (wlfc->destination_entries.nodes[i].occupied) { -+ request_cr_ack += -+ wlfc->destination_entries.nodes[i].dstncredit_acks; -+ } -+ } -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ if (wlfc->destination_entries.interfaces[i].occupied) { -+ request_cr_ack += -+ wlfc->destination_entries.interfaces[i].dstncredit_acks; -+ } -+ } -+ bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d)," -+ "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)", -+ fifo_cr_sent, fifo_cr_acked, -+ request_cr_sent, request_cr_ack, -+ wlfc->destination_entries.other.dstncredit_acks, -+ bc_mc_cr_ack, -+ wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed); -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ bcm_bprintf(strbuf, "\n"); -+ bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)" -+ "(freed,free_err,rollback)) = " -+ "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", -+ wlfc->stats.pktin, -+ wlfc->stats.pkt2bus, -+ wlfc->stats.txstatus_in, -+ wlfc->stats.dhd_hdrpulls, -+ -+ wlfc->stats.pktdropped, -+ wlfc->stats.wlfc_header_only_pkt, -+ wlfc->stats.wlc_tossed_pkts, -+ -+ wlfc->stats.pkt_freed, -+ wlfc->stats.pkt_free_err, wlfc->stats.rollback); -+ -+ bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = " -+ "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n", -+ -+ wlfc->stats.d11_suppress, -+ wlfc->stats.wl_suppress, -+ wlfc->stats.bad_suppress, -+ -+ wlfc->stats.psq_d11sup_enq, -+ wlfc->stats.psq_wlsup_enq, -+ wlfc->stats.psq_hostq_enq, -+ wlfc->stats.mac_handle_notfound, -+ -+ wlfc->stats.psq_d11sup_retx, -+ wlfc->stats.psq_wlsup_retx, -+ wlfc->stats.psq_hostq_retx); -+ bcm_bprintf(strbuf, "wlfc- generic error: %d", wlfc->stats.generic_error); -+ -+ return; -+} -+ -+/* Create a place to store all packet pointers submitted to the firmware until -+ a status comes back, suppress or otherwise. -+ -+ hang-er: noun, a contrivance on which things are hung, as a hook. -+*/ -+static void* -+dhd_wlfc_hanger_create(osl_t *osh, int max_items) -+{ -+ int i; -+ wlfc_hanger_t* hanger; -+ -+ /* allow only up to a specific size for now */ -+ ASSERT(max_items == WLFC_HANGER_MAXITEMS); -+ -+ if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL) -+ return NULL; -+ -+ memset(hanger, 0, WLFC_HANGER_SIZE(max_items)); -+ hanger->max_items = max_items; -+ -+ for (i = 0; i < hanger->max_items; i++) { -+ hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ return hanger; -+} -+ -+static int -+dhd_wlfc_hanger_delete(osl_t *osh, void* hanger) -+{ -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h) { -+ MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items)); -+ return BCME_OK; -+ } -+ return BCME_BADARG; -+} -+ -+static uint16 -+dhd_wlfc_hanger_get_free_slot(void* hanger) -+{ -+ uint32 i; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h) { -+ i = h->slot_pos + 1; -+ if (i == h->max_items) { -+ i = 0; -+ } -+ while (i != h->slot_pos) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) { -+ h->slot_pos = i; -+ return (uint16)i; -+ } -+ i++; -+ if (i == h->max_items) -+ i = 0; -+ } -+ h->failed_slotfind++; -+ } -+ return WLFC_HANGER_MAXITEMS; -+} -+ -+static int -+dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ *gen = 0xff; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ -+ if (h) { -+ if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) || -+ (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) { -+ *gen = h->items[slot_id].gen; -+ } -+ else { -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ if (h && (slot_id < WLFC_HANGER_MAXITEMS)) { -+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) { -+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE; -+ h->items[slot_id].pkt = pkt; -+ h->items[slot_id].identifier = slot_id; -+ h->pushed++; -+ } -+ else { -+ h->failed_to_push++; -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ -+ if (h) { -+ if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) { -+ *pktout = h->items[slot_id].pkt; -+ if (remove_from_hanger) { -+ h->items[slot_id].state = -+ WLFC_HANGER_ITEM_STATE_FREE; -+ h->items[slot_id].pkt = NULL; -+ h->items[slot_id].identifier = 0; -+ h->items[slot_id].gen = 0xff; -+ h->popped++; -+ } -+ } -+ else { -+ h->failed_to_pop++; -+ rc = BCME_NOTFOUND; -+ } -+ } -+ else -+ rc = BCME_BADARG; -+ return rc; -+} -+ -+static int -+dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen) -+{ -+ int rc = BCME_OK; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; -+ -+ /* this packet was not pushed at the time it went to the firmware */ -+ if (slot_id == WLFC_HANGER_MAXITEMS) -+ return BCME_NOTFOUND; -+ if (h) { -+ h->items[slot_id].gen = gen; -+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED; -+ } -+ else -+ rc = BCME_BADARG; -+ } -+ else -+ rc = BCME_BADARG; -+ -+ return rc; -+} -+ -+static int -+_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal, -+ uint8 tim_bmp, uint8 mac_handle, uint32 htodtag) -+{ -+ uint32 wl_pktinfo = 0; -+ uint8* wlh; -+ uint8 dataOffset; -+ uint8 fillers; -+ uint8 tim_signal_len = 0; -+ -+ struct bdc_header *h; -+ -+ if (tim_signal) { -+ tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; -+ } -+ -+ /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ -+ dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len; -+ fillers = ROUNDUP(dataOffset, 4) - dataOffset; -+ dataOffset += fillers; -+ -+ PKTPUSH(ctx->osh, p, dataOffset); -+ wlh = (uint8*) PKTDATA(ctx->osh, p); -+ -+ wl_pktinfo = htol32(htodtag); -+ -+ wlh[0] = WLFC_CTL_TYPE_PKTTAG; -+ wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG; -+ memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32)); -+ -+ if (tim_signal_len) { -+ wlh[dataOffset - fillers - tim_signal_len ] = -+ WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP; -+ wlh[dataOffset - fillers - tim_signal_len + 1] = -+ WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; -+ wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle; -+ wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp; -+ } -+ if (fillers) -+ memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers); -+ -+ PKTPUSH(ctx->osh, p, BDC_HEADER_LEN); -+ h = (struct bdc_header *)PKTDATA(ctx->osh, p); -+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); -+ if (PKTSUMNEEDED(p)) -+ h->flags |= BDC_FLAG_SUM_NEEDED; -+ -+ -+ h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); -+ h->flags2 = 0; -+ h->dataOffset = dataOffset >> 2; -+ BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p))); -+ return BCME_OK; -+} -+ -+static int -+_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) -+{ -+ struct bdc_header *h; -+ -+ if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) { -+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN); -+ return BCME_ERROR; -+ } -+ h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf); -+ -+ /* pull BDC header */ -+ PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); -+ -+ if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) { -+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__, -+ PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2)); -+ return BCME_ERROR; -+ } -+ -+ /* pull wl-header */ -+ PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); -+ return BCME_OK; -+} -+ -+static wlfc_mac_descriptor_t* -+_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p) -+{ -+ int i; -+ wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes; -+ uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p)); -+ uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p)); -+ wlfc_mac_descriptor_t* entry = NULL; -+ int iftype = ctx->destination_entries.interfaces[ifid].iftype; -+ -+ /* Multicast destination and P2P clients get the interface entry. -+ * STA gets the interface entry if there is no exact match. For -+ * example, TDLS destinations have their own entry. -+ */ -+ if ((iftype == WLC_E_IF_ROLE_STA || ETHER_ISMULTI(dstn) || -+ iftype == WLC_E_IF_ROLE_P2P_CLIENT) && -+ (ctx->destination_entries.interfaces[ifid].occupied)) { -+ entry = &ctx->destination_entries.interfaces[ifid]; -+ } -+ -+ if (entry != NULL && ETHER_ISMULTI(dstn)) -+ return entry; -+ -+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { -+ if (table[i].occupied) { -+ if (table[i].interface_id == ifid) { -+ if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) { -+ entry = &table[i]; -+ break; -+ } -+ } -+ } -+ } -+ -+ return entry != NULL ? entry : &ctx->destination_entries.other; -+} -+ -+static int -+_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, -+ void* p, ewlfc_packet_state_t pkt_type, uint32 hslot) -+{ -+ /* -+ put the packet back to the head of queue -+ -+ - suppressed packet goes back to suppress sub-queue -+ - pull out the header, if new or delayed packet -+ -+ Note: hslot is used only when header removal is done. -+ */ -+ wlfc_mac_descriptor_t* entry; -+ void* pktout; -+ int rc = BCME_OK; -+ int prec; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ prec = DHD_PKTTAG_FIFO(PKTTAG(p)); -+ if (entry != NULL) { -+ if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) { -+ /* wl-header is saved for suppressed packets */ -+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ } -+ else { -+ /* remove header first */ -+ rc = _dhd_wlfc_pullheader(ctx, p); -+ if (rc != BCME_OK) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ /* free the hanger slot */ -+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); -+ PKTFREE(ctx->osh, p, TRUE); -+ ctx->stats.rollback_failed++; -+ return BCME_ERROR; -+ } -+ -+ if (pkt_type == eWLFC_PKTTYPE_DELAYED) { -+ /* delay-q packets are going to delay-q */ -+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ } -+ -+ /* free the hanger slot */ -+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); -+ -+ /* decrement sequence count */ -+ WLFC_DECR_SEQCOUNT(entry, prec); -+ } -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the firmware (for pspoll etc.) -+ */ -+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { -+ entry->requested_credit++; -+ } -+ } -+ else { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ rc = BCME_ERROR; -+ } -+ if (rc != BCME_OK) -+ ctx->stats.rollback_failed++; -+ else -+ ctx->stats.rollback++; -+ -+ return rc; -+} -+ -+static void -+_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id) -+{ -+ dhd_pub_t *dhdp; -+ -+ ASSERT(ctx); -+ -+ dhdp = (dhd_pub_t *)ctx->dhdp; -+ -+ if (dhdp && dhdp->skip_fc && dhdp->skip_fc()) -+ return; -+ -+ if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { -+ /* start traffic */ -+ ctx->hostif_flow_state[if_id] = OFF; -+ /* -+ AP6210_DEBUG("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", -+ pq->len, if_id, __FUNCTION__); -+ */ -+ AP6210_DEBUG("F"); -+ -+ dhd_txflowcontrol(ctx->dhdp, if_id, OFF); -+ -+ ctx->toggle_host_if = 0; -+ } -+ if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { -+ /* stop traffic */ -+ ctx->hostif_flow_state[if_id] = ON; -+ /* -+ AP6210_DEBUG("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", -+ pq->len, if_id, __FUNCTION__); -+ */ -+ AP6210_DEBUG("N"); -+ -+ dhd_txflowcontrol(ctx->dhdp, if_id, ON); -+ -+ ctx->host_ifidx = if_id; -+ ctx->toggle_host_if = 1; -+ } -+ -+ return; -+} -+ -+static int -+_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ uint8 ta_bmp) -+{ -+ int rc = BCME_OK; -+ void* p = NULL; -+ int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12; -+ -+ /* allocate a dummy packet */ -+ p = PKTGET(ctx->osh, dummylen, TRUE); -+ if (p) { -+ PKTPULL(ctx->osh, p, dummylen); -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0); -+ _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0); -+ DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1); -+#ifdef PROP_TXSTATUS_DEBUG -+ ctx->stats.signal_only_pkts_sent++; -+#endif -+ rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p); -+ if (rc != BCME_OK) { -+ PKTFREE(ctx->osh, p, TRUE); -+ } -+ } -+ else { -+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n", -+ __FUNCTION__, dummylen); -+ rc = BCME_NOMEM; -+ } -+ return rc; -+} -+ -+/* Return TRUE if traffic availability changed */ -+static bool -+_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ int prec) -+{ -+ bool rc = FALSE; -+ -+ if (entry->state == WLFC_STATE_CLOSE) { -+ if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && -+ (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { -+ -+ if (entry->traffic_pending_bmp & NBITVAL(prec)) { -+ rc = TRUE; -+ entry->traffic_pending_bmp = -+ entry->traffic_pending_bmp & ~ NBITVAL(prec); -+ } -+ } -+ else { -+ if (!(entry->traffic_pending_bmp & NBITVAL(prec))) { -+ rc = TRUE; -+ entry->traffic_pending_bmp = -+ entry->traffic_pending_bmp | NBITVAL(prec); -+ } -+ } -+ } -+ if (rc) { -+ /* request a TIM update to firmware at the next piggyback opportunity */ -+ if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) { -+ entry->send_tim_signal = 1; -+ _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp); -+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; -+ entry->send_tim_signal = 0; -+ } -+ else { -+ rc = FALSE; -+ } -+ } -+ return rc; -+} -+ -+static int -+_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p) -+{ -+ wlfc_mac_descriptor_t* entry; -+ -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_NOTFOUND; -+ } -+ /* -+ - suppressed packets go to sub_queue[2*prec + 1] AND -+ - delayed packets go to sub_queue[2*prec + 0] to ensure -+ order of delivery. -+ */ -+ if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) { -+ ctx->stats.delayq_full_error++; -+ /* AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); */ -+ AP6210_DEBUG("s"); -+ return BCME_ERROR; -+ } -+ /* A packet has been pushed, update traffic availability bitmap, if applicable */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); -+ return BCME_OK; -+} -+ -+static int -+_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, -+ wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot) -+{ -+ int rc = BCME_OK; -+ int hslot = WLFC_HANGER_MAXITEMS; -+ bool send_tim_update = FALSE; -+ uint32 htod = 0; -+ uint8 free_ctr; -+ -+ *slot = hslot; -+ -+ if (entry == NULL) { -+ entry = _dhd_wlfc_find_table_entry(ctx, p); -+ } -+ -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_ERROR; -+ } -+ if (entry->send_tim_signal) { -+ send_tim_update = TRUE; -+ entry->send_tim_signal = 0; -+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; -+ } -+ if (header_needed) { -+ hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger); -+ free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); -+ WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation); -+ entry->transit_count++; -+ } -+ else { -+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ } -+ WLFC_PKTID_HSLOT_SET(htod, hslot); -+ WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr); -+ DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); -+ WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); -+ WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); -+ -+ -+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { -+ /* -+ Indicate that this packet is being sent in response to an -+ explicit request from the firmware side. -+ */ -+ WLFC_PKTFLAG_SET_PKTREQUESTED(htod); -+ } -+ else { -+ WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); -+ } -+ if (header_needed) { -+ rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, -+ entry->traffic_lastreported_bmp, entry->mac_handle, htod); -+ if (rc == BCME_OK) { -+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); -+ /* -+ a new header was created for this packet. -+ push to hanger slot and scrub q. Since bus -+ send succeeded, increment seq number as well. -+ */ -+ rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot); -+ if (rc == BCME_OK) { -+ /* increment free running sequence count */ -+ WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -+#ifdef PROP_TXSTATUS_DEBUG -+ ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time = -+ OSL_SYSUPTIME(); -+#endif -+ } -+ else { -+ AP6210_DEBUG("%s() hanger_pushpkt() failed, rc: %d\n", -+ __FUNCTION__, rc); -+ } -+ } -+ } -+ else { -+ int gen; -+ -+ /* remove old header */ -+ rc = _dhd_wlfc_pullheader(ctx, p); -+ if (rc == BCME_OK) { -+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); -+ -+ WLFC_PKTFLAG_SET_GENERATION(htod, gen); -+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); -+ /* push new header */ -+ _dhd_wlfc_pushheader(ctx, p, send_tim_update, -+ entry->traffic_lastreported_bmp, entry->mac_handle, htod); -+ } -+ } -+ *slot = hslot; -+ return rc; -+} -+ -+static int -+_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx, -+ wlfc_mac_descriptor_t* entry, int prec) -+{ -+ if (ctx->destination_entries.interfaces[entry->interface_id].iftype == -+ WLC_E_IF_ROLE_P2P_GO) { -+ /* - destination interface is of type p2p GO. -+ For a p2pGO interface, if the destination is OPEN but the interface is -+ CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is -+ destination-specific-credit left send packets. This is because the -+ firmware storing the destination-specific-requested packet in queue. -+ */ -+ if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && -+ (entry->requested_packet == 0)) -+ return 1; -+ } -+ /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ -+ if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && -+ (entry->requested_packet == 0)) || -+ (!(entry->ac_bitmap & (1 << prec)))) -+ return 1; -+ -+ return 0; -+} -+ -+static void* -+_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, -+ int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out) -+{ -+ wlfc_mac_descriptor_t* entry; -+ wlfc_mac_descriptor_t* table; -+ uint8 token_pos; -+ int total_entries; -+ void* p = NULL; -+ int pout; -+ int i; -+ -+ *entry_out = NULL; -+ token_pos = ctx->token_pos[prec]; -+ /* most cases a packet will count against FIFO credit */ -+ *ac_credit_spent = 1; -+ *needs_hdr = 1; -+ -+ /* search all entries, include nodes as well as interfaces */ -+ table = (wlfc_mac_descriptor_t*)&ctx->destination_entries; -+ total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t); -+ -+ for (i = 0; i < total_entries; i++) { -+ entry = &table[(token_pos + i) % total_entries]; -+ if (entry->occupied && !entry->deleting) { -+ if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) { -+ p = pktq_mdeq(&entry->psq, -+ /* higher precedence will be picked up first, -+ * i.e. suppressed packets before delayed ones -+ */ -+ NBITVAL((prec << 1) + 1), &pout); -+ *needs_hdr = 0; -+ -+ if (p == NULL) { -+ if (entry->suppressed == TRUE) { -+ if ((entry->suppr_transit_count <= -+ entry->suppress_count)) { -+ entry->suppressed = FALSE; -+ } else { -+ return NULL; -+ } -+ } -+ /* De-Q from delay Q */ -+ p = pktq_mdeq(&entry->psq, -+ NBITVAL((prec << 1)), -+ &pout); -+ *needs_hdr = 1; -+ } -+ -+ if (p != NULL) { -+ /* did the packet come from suppress sub-queue? */ -+ if (entry->requested_credit > 0) { -+ entry->requested_credit--; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_sent_packets++; -+#endif -+ /* -+ if the packet was pulled out while destination is in -+ closed state but had a non-zero packets requested, -+ then this should not count against the FIFO credit. -+ That is due to the fact that the firmware will -+ most likely hold onto this packet until a suitable -+ time later to push it to the appropriate AC FIFO. -+ */ -+ if (entry->state == WLFC_STATE_CLOSE) -+ *ac_credit_spent = 0; -+ } -+ else if (entry->requested_packet > 0) { -+ entry->requested_packet--; -+ DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); -+ if (entry->state == WLFC_STATE_CLOSE) -+ *ac_credit_spent = 0; -+ } -+ /* move token to ensure fair round-robin */ -+ ctx->token_pos[prec] = -+ (token_pos + i + 1) % total_entries; -+ *entry_out = entry; -+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, -+ DHD_PKTTAG_IF(PKTTAG(p))); -+ /* -+ A packet has been picked up, update traffic -+ availability bitmap, if applicable -+ */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ return p; -+ } -+ } -+ } -+ } -+ return NULL; -+} -+ -+void * -+_dhd_wlfc_pktq_peek_tail(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ ASSERT(pq); -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ /* only pick packets from dealyed-q */ -+ if (((prec & 1) == 0) && pq->q[prec].head) -+ break; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return (pq->q[prec].tail); -+} -+ -+bool -+_dhd_wlfc_prec_enq_with_drop(dhd_pub_t *dhdp, struct pktq *pq, void *pkt, int prec) -+{ -+ void *p = NULL; -+ int eprec = -1; /* precedence to evict from */ -+ -+ ASSERT(dhdp && pq && pkt); -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ /* Fast case, precedence queue is not full and we are also not -+ * exceeding total queue length -+ */ -+ if (!pktq_pfull(pq, prec) && !pktq_full(pq)) { -+ pktq_penq(pq, prec, pkt); -+ return TRUE; -+ } -+ -+ /* Determine precedence from which to evict packet, if any */ -+ if (pktq_pfull(pq, prec)) -+ eprec = prec; -+ else if (pktq_full(pq)) { -+ p = _dhd_wlfc_pktq_peek_tail(pq, &eprec); -+ if (!p) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return FALSE; -+ } -+ if ((eprec > prec) || (eprec < 0)) { -+ if (!pktq_pempty(pq, prec)) { -+ eprec = prec; -+ } else { -+ return FALSE; -+ } -+ } -+ } -+ -+ /* Evict if needed */ -+ if (eprec >= 0) { -+ /* Detect queueing to unconfigured precedence */ -+ ASSERT(!pktq_pempty(pq, eprec)); -+ /* Evict all fragmented frames */ -+ dhd_prec_drop_pkts(dhdp->osh, pq, eprec); -+ } -+ -+ /* Enqueue */ -+ p = pktq_penq(pq, prec, pkt); -+ if (!p) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static int -+_dhd_wlfc_enque_delayq(athost_wl_status_info_t* ctx, void* pktbuf, int prec) -+{ -+ wlfc_mac_descriptor_t* entry; -+ -+ if (pktbuf != NULL) { -+ entry = _dhd_wlfc_find_table_entry(ctx, pktbuf); -+ -+ if (entry == NULL) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_ERROR; -+ } -+ -+ /* -+ - suppressed packets go to sub_queue[2*prec + 1] AND -+ - delayed packets go to sub_queue[2*prec + 0] to ensure -+ order of delivery. -+ */ -+ if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, pktbuf, (prec << 1)) -+ == FALSE) { -+ AP6210_DEBUG("D"); -+ /* dhd_txcomplete(ctx->dhdp, pktbuf, FALSE); */ -+ PKTFREE(ctx->osh, pktbuf, TRUE); -+ ctx->stats.delayq_full_error++; -+ return BCME_ERROR; -+ } -+ -+ /* -+ A packet has been pushed, update traffic availability bitmap, -+ if applicable -+ */ -+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec); -+ -+ } -+ return BCME_OK; -+} -+ -+bool ifpkt_fn(void* p, int ifid) -+{ -+ return (ifid == DHD_PKTTAG_IF(PKTTAG(p))); -+} -+ -+static int -+_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -+{ -+ int rc = BCME_OK; -+ -+ if (action == eWLFC_MAC_ENTRY_ACTION_ADD) { -+ entry->occupied = 1; -+ entry->state = WLFC_STATE_OPEN; -+ entry->requested_credit = 0; -+ entry->interface_id = ifid; -+ entry->iftype = iftype; -+ entry->ac_bitmap = 0xff; /* update this when handling APSD */ -+ /* for an interface entry we may not care about the MAC address */ -+ if (ea != NULL) -+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); -+ pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); -+ } -+ else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) { -+ entry->occupied = 1; -+ entry->state = WLFC_STATE_OPEN; -+ entry->requested_credit = 0; -+ entry->interface_id = ifid; -+ entry->iftype = iftype; -+ entry->ac_bitmap = 0xff; /* update this when handling APSD */ -+ /* for an interface entry we may not care about the MAC address */ -+ if (ea != NULL) -+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); -+ } -+ else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) { -+ /* When the entry is deleted, the packets that are queued in the entry must be -+ cleanup. The cleanup action should be before the occupied is set as 0. The -+ flag deleting is set to avoid de-queue action when these queues are being -+ cleanup -+ */ -+ entry->deleting = 1; -+ dhd_wlfc_cleanup(ctx->dhdp, ifpkt_fn, ifid); -+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid); -+ entry->deleting = 0; -+ -+ entry->occupied = 0; -+ entry->suppressed = 0; -+ entry->state = WLFC_STATE_CLOSE; -+ entry->requested_credit = 0; -+ entry->transit_count = 0; -+ entry->suppr_transit_count = 0; -+ entry->suppress_count = 0; -+ memset(&entry->ea[0], 0, ETHER_ADDR_LEN); -+ -+ /* enable after packets are queued-deqeued properly. -+ pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0); -+ */ -+ } -+ return rc; -+} -+ -+int -+_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac) -+{ -+ int lender_ac; -+ int rc = BCME_ERROR; -+ -+ if (ctx == NULL || available_credit_map == 0) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_BADARG; -+ } -+ -+ /* Borrow from lowest priority available AC (including BC/MC credits) */ -+ for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) { -+ if ((available_credit_map && (1 << lender_ac)) && -+ (ctx->FIFO_credit[lender_ac] > 0)) { -+ ctx->credits_borrowed[borrower_ac][lender_ac]++; -+ ctx->FIFO_credit[lender_ac]--; -+ rc = BCME_OK; -+ break; -+ } -+ } -+ -+ return rc; -+} -+ -+int -+dhd_wlfc_interface_entry_update(void* state, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -+{ -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ wlfc_mac_descriptor_t* entry; -+ int ret; -+ -+ if (ifid >= WLFC_MAX_IFNUM) -+ return BCME_BADARG; -+ -+ entry = &ctx->destination_entries.interfaces[ifid]; -+ ret = _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea); -+ return ret; -+} -+ -+int -+dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits) -+{ -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ -+ /* update the AC FIFO credit map */ -+ ctx->FIFO_credit[0] = credits[0]; -+ ctx->FIFO_credit[1] = credits[1]; -+ ctx->FIFO_credit[2] = credits[2]; -+ ctx->FIFO_credit[3] = credits[3]; -+ /* credit for bc/mc packets */ -+ ctx->FIFO_credit[4] = credits[4]; -+ /* credit for ATIM FIFO is not used yet. */ -+ ctx->FIFO_credit[5] = 0; -+ return BCME_OK; -+} -+ -+int -+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac, -+ dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx) -+{ -+ uint32 hslot; -+ int rc; -+ -+ /* -+ if ac_fifo_credit_spent = 0 -+ -+ This packet will not count against the FIFO credit. -+ To ensure the txstatus corresponding to this packet -+ does not provide an implied credit (default behavior) -+ mark the packet accordingly. -+ -+ if ac_fifo_credit_spent = 1 -+ -+ This is a normal packet and it counts against the FIFO -+ credit count. -+ */ -+ DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent); -+ rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p, -+ commit_info->needs_hdr, &hslot); -+ -+ if (rc == BCME_OK) -+ rc = fcommit(commit_ctx, commit_info->p); -+ else -+ ctx->stats.generic_error++; -+ -+ if (rc == BCME_OK) { -+ ctx->stats.pkt2bus++; -+ if (commit_info->ac_fifo_credit_spent) { -+ ctx->stats.send_pkts[ac]++; -+ WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); -+ } -+ } else if (rc == BCME_NORESOURCE) -+ rc = BCME_ERROR; -+ else { -+ /* -+ bus commit has failed, rollback. -+ - remove wl-header for a delayed packet -+ - save wl-header header for suppressed packets -+ */ -+ rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p, -+ (commit_info->pkt_type), hslot); -+ -+ rc = BCME_ERROR; -+ } -+ -+ return rc; -+} -+ -+int -+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, void *pktbuf) -+{ -+ int ac; -+ int credit; -+ int rc; -+ dhd_wlfc_commit_info_t commit_info; -+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; -+ int credit_count = 0; -+ int bus_retry_count = 0; -+ uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */ -+ -+ if ((state == NULL) || -+ (fcommit == NULL)) { -+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); -+ return BCME_BADARG; -+ } -+ -+ memset(&commit_info, 0, sizeof(commit_info)); -+ -+ /* -+ Commit packets for regular AC traffic. Higher priority first. -+ First, use up FIFO credits available to each AC. Based on distribution -+ and credits left, borrow from other ACs as applicable -+ -+ -NOTE: -+ If the bus between the host and firmware is overwhelmed by the -+ traffic from host, it is possible that higher priority traffic -+ starves the lower priority queue. If that occurs often, we may -+ have to employ weighted round-robin or ucode scheme to avoid -+ low priority packet starvation. -+ */ -+ -+ if (pktbuf) { -+ ac = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); -+ if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(pktbuf)))) { -+ ASSERT(ac == AC_COUNT); -+ commit_info.needs_hdr = 1; -+ commit_info.mac_entry = NULL; -+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW; -+ commit_info.p = pktbuf; -+ if (ctx->FIFO_credit[ac]) { -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ (void) _dhd_wlfc_borrow_credit(ctx, -+ ac_available, ac); -+ credit_count--; -+ } -+ } else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR(" %s: bus error %d\n", -+ __FUNCTION__, rc); -+ return rc; -+ } -+ } -+ } -+ } -+ else { -+ /* en-queue the packets to respective queue. */ -+ rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac); -+ } -+ } -+ -+ for (ac = AC_COUNT; ac >= 0; ac--) { -+ -+ bool bQueueIdle = TRUE; -+ -+ /* packets from delayQ with less priority are fresh and they'd need header and -+ * have no MAC entry -+ */ -+ commit_info.needs_hdr = 1; -+ commit_info.mac_entry = NULL; -+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW; -+ -+ for (credit = 0; credit < ctx->FIFO_credit[ac];) { -+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, -+ &(commit_info.ac_fifo_credit_spent), -+ &(commit_info.needs_hdr), -+ &(commit_info.mac_entry)); -+ -+ if (commit_info.p == NULL) -+ break; -+ -+ bQueueIdle = FALSE; -+ -+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : -+ eWLFC_PKTTYPE_SUPPRESSED; -+ -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ credit++; -+ } -+ } -+ else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR("%s: bus error %d\n", __FUNCTION__, rc); -+ ctx->FIFO_credit[ac] -= credit; -+ return rc; -+ } -+ } -+ } -+ -+ ctx->FIFO_credit[ac] -= credit; -+ -+ -+ /* If no pkts can be dequed, the credit can be borrowed */ -+ if (bQueueIdle) { -+ ac_available |= (1 << ac); -+ credit_count += ctx->FIFO_credit[ac]; -+ } -+ } -+ -+ /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD -+ -+ Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to: -+ a) ignore BC/MC for deferring borrow -+ b) ignore AC_BE being available along with other ACs -+ (this should happen only for pure BC/MC traffic) -+ -+ i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and -+ we do not care if AC_BE and BC/MC are available or not -+ */ -+ if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) { -+ -+ if (ctx->allow_credit_borrow) { -+ ac = 1; /* Set ac to AC_BE and borrow credits */ -+ } -+ else { -+ int delta; -+ int curr_t = OSL_SYSUPTIME(); -+ -+ if (curr_t > ctx->borrow_defer_timestamp) -+ delta = curr_t - ctx->borrow_defer_timestamp; -+ else -+ delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp; -+ -+ if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) { -+ /* Reset borrow but defer to next iteration (defensive borrowing) */ -+ ctx->allow_credit_borrow = TRUE; -+ ctx->borrow_defer_timestamp = 0; -+ } -+ return BCME_OK; -+ } -+ } -+ else { -+ /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */ -+ ctx->allow_credit_borrow = FALSE; -+ ctx->borrow_defer_timestamp = OSL_SYSUPTIME(); -+ return BCME_OK; -+ } -+ -+ /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE) -+ Generically use "ac" only in case we extend to all ACs in future -+ */ -+ for (; (credit_count > 0);) { -+ -+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, -+ &(commit_info.ac_fifo_credit_spent), -+ &(commit_info.needs_hdr), -+ &(commit_info.mac_entry)); -+ if (commit_info.p == NULL) -+ break; -+ -+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : -+ eWLFC_PKTTYPE_SUPPRESSED; -+ -+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, -+ fcommit, commit_ctx); -+ -+ /* Bus commits may fail (e.g. flow control); abort after retries */ -+ if (rc == BCME_OK) { -+ if (commit_info.ac_fifo_credit_spent) { -+ (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); -+ credit_count--; -+ } -+ } -+ else { -+ bus_retry_count++; -+ if (bus_retry_count >= BUS_RETRIES) { -+ AP6210_ERR("%s: bus error %d\n", __FUNCTION__, rc); -+ return rc; -+ } -+ } -+ } -+ return BCME_OK; -+} -+ -+static uint8 -+dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea) -+{ -+ wlfc_mac_descriptor_t* table = -+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes; -+ uint8 table_index; -+ -+ if (ea != NULL) { -+ for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) { -+ if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) && -+ table[table_index].occupied) -+ return table_index; -+ } -+ } -+ return WLFC_MAC_DESC_ID_INVALID; -+} -+ -+void -+dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ void* p; -+ int fifo_id; -+ -+ if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { -+#ifdef PROP_TXSTATUS_DEBUG -+ wlfc->stats.signal_only_pkts_freed++; -+#endif -+ /* is this a signal-only packet? */ -+ if (success) -+ PKTFREE(wlfc->osh, txp, TRUE); -+ return; -+ } -+ if (!success) { -+ AP6210_DEBUG("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n", -+ __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp))); -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG -+ (PKTTAG(txp))), &p, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, txp, FALSE); -+ -+ /* return the credit, if necessary */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) { -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp)); -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ -+ PKTFREE(wlfc->osh, txp, TRUE); -+ } -+ return; -+} -+ -+static int -+dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len) -+{ -+ uint8 status_flag; -+ uint32 status; -+ int ret; -+ int remove_from_hanger = 1; -+ void* pktbuf; -+ uint8 fifo_id; -+ uint8 count = 0; -+ uint32 status_g; -+ uint32 hslot, hcnt; -+ wlfc_mac_descriptor_t* entry = NULL; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ memcpy(&status, pkt_info, sizeof(uint32)); -+ status_flag = WL_TXSTATUS_GET_FLAGS(status); -+ status_g = status & 0xff000000; -+ hslot = (status & 0x00ffff00) >> 8; -+ hcnt = status & 0xff; -+ len = pkt_info[4]; -+ -+ wlfc->stats.txstatus_in++; -+ -+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { -+ wlfc->stats.pkt_freed++; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { -+ wlfc->stats.d11_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { -+ wlfc->stats.wl_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { -+ wlfc->stats.wlc_tossed_pkts++; -+ } -+ while (count < len) { -+ status = (status_g << 24) | (hslot << 8) | (hcnt); -+ count++; -+ hslot++; -+ hcnt++; -+ -+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); -+ if (ret != BCME_OK) { -+ /* do something */ -+ continue; -+ } -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ -+ if (!remove_from_hanger) { -+ /* this packet was suppressed */ -+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { -+ entry->suppressed = TRUE; -+ entry->suppress_count = pktq_mlen(&entry->psq, -+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); -+ entry->suppr_transit_count = entry->transit_count; -+ } -+ entry->generation = WLFC_PKTID_GEN(status); -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ uint32 new_t = OSL_SYSUPTIME(); -+ uint32 old_t; -+ uint32 delta; -+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ -+ WLFC_PKTID_HSLOT_GET(status)].push_time; -+ -+ -+ wlfc->stats.latency_sample_count++; -+ if (new_t > old_t) -+ delta = new_t - old_t; -+ else -+ delta = 0xffffffff + new_t - old_t; -+ wlfc->stats.total_status_latency += delta; -+ wlfc->stats.latency_most_recent = delta; -+ -+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; -+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) -+ wlfc->stats.idx_delta = 0; -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); -+ -+ /* pick up the implicit credit from this packet */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { -+ -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ } -+ else { -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the destination entry (for pspoll etc.) -+ */ -+ if (!entry) { -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ } -+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) -+ entry->requested_credit++; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_acks++; -+#endif -+ } -+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || -+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { -+ -+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); -+ if (ret != BCME_OK) { -+ /* delay q is full, drop this packet */ -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), -+ &pktbuf, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, pktbuf, FALSE); -+ entry->transit_count--; -+ DHD_WLFC_QMON_COMPLETE(entry); -+ /* packet is transmitted Successfully by dongle -+ * after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } else { -+ /* Mark suppressed to avoid a double free during wlfc cleanup */ -+ -+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); -+ entry->suppress_count++; -+ } -+ } -+ else { -+ dhd_txcomplete(dhd, pktbuf, TRUE); -+ entry->transit_count--; -+ DHD_WLFC_QMON_COMPLETE(entry); -+ -+ /* This packet is transmitted Successfully by dongle -+ * even after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ /* free the packet */ -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } -+ } -+ return BCME_OK; -+} -+ -+/* Handle discard or suppress indication */ -+static int -+dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info) -+{ -+ uint8 status_flag; -+ uint32 status; -+ int ret; -+ int remove_from_hanger = 1; -+ void* pktbuf; -+ uint8 fifo_id; -+ wlfc_mac_descriptor_t* entry = NULL; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ memcpy(&status, pkt_info, sizeof(uint32)); -+ status_flag = WL_TXSTATUS_GET_FLAGS(status); -+ wlfc->stats.txstatus_in++; -+ -+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { -+ wlfc->stats.pkt_freed++; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { -+ wlfc->stats.d11_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { -+ wlfc->stats.wl_suppress++; -+ remove_from_hanger = 0; -+ } -+ -+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { -+ wlfc->stats.wlc_tossed_pkts++; -+ } -+ -+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); -+ if (ret != BCME_OK) { -+ /* do something */ -+ return ret; -+ } -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ -+ if (!remove_from_hanger) { -+ /* this packet was suppressed */ -+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { -+ entry->suppressed = TRUE; -+ entry->suppress_count = pktq_mlen(&entry->psq, -+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); -+ entry->suppr_transit_count = entry->transit_count; -+ } -+ entry->generation = WLFC_PKTID_GEN(status); -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ uint32 new_t = OSL_SYSUPTIME(); -+ uint32 old_t; -+ uint32 delta; -+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ -+ WLFC_PKTID_HSLOT_GET(status)].push_time; -+ -+ -+ wlfc->stats.latency_sample_count++; -+ if (new_t > old_t) -+ delta = new_t - old_t; -+ else -+ delta = 0xffffffff + new_t - old_t; -+ wlfc->stats.total_status_latency += delta; -+ wlfc->stats.latency_most_recent = delta; -+ -+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; -+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) -+ wlfc->stats.idx_delta = 0; -+ } -+#endif /* PROP_TXSTATUS_DEBUG */ -+ -+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); -+ -+ /* pick up the implicit credit from this packet */ -+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { -+ -+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; lender >= 0; lender--) { -+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) { -+ wlfc->FIFO_credit[lender]++; -+ wlfc->credits_borrowed[fifo_id][lender]--; -+ credit_returned = 1; -+ break; -+ } -+ } -+ -+ if (!credit_returned) { -+ wlfc->FIFO_credit[fifo_id]++; -+ } -+ } -+ } -+ else { -+ /* -+ if this packet did not count against FIFO credit, it must have -+ taken a requested_credit from the destination entry (for pspoll etc.) -+ */ -+ if (!entry) { -+ -+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); -+ } -+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) -+ entry->requested_credit++; -+#ifdef PROP_TXSTATUS_DEBUG -+ entry->dstncredit_acks++; -+#endif -+ } -+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || -+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { -+ -+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); -+ if (ret != BCME_OK) { -+ /* delay q is full, drop this packet */ -+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), -+ &pktbuf, 1); -+ -+ /* indicate failure and free the packet */ -+ dhd_txcomplete(dhd, pktbuf, FALSE); -+ entry->transit_count--; -+ DHD_WLFC_QMON_COMPLETE(entry); -+ /* This packet is transmitted Successfully by -+ * dongle even after first suppress. -+ */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } else { -+ /* Mark suppressed to avoid a double free during wlfc cleanup */ -+ -+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, -+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); -+ entry->suppress_count++; -+ } -+ } -+ else { -+ dhd_txcomplete(dhd, pktbuf, TRUE); -+ entry->transit_count--; -+ DHD_WLFC_QMON_COMPLETE(entry); -+ -+ /* This packet is transmitted Successfully by dongle even after first suppress. */ -+ if (entry->suppressed) { -+ entry->suppr_transit_count--; -+ } -+ /* free the packet */ -+ PKTFREE(wlfc->osh, pktbuf, TRUE); -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits) -+{ -+ int i; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { -+#ifdef PROP_TXSTATUS_DEBUG -+ wlfc->stats.fifo_credits_back[i] += credits[i]; -+#endif -+ /* update FIFO credits */ -+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) -+ { -+ int lender; /* Note that borrower is i */ -+ -+ /* Return credits to highest priority lender first */ -+ for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) { -+ if (wlfc->credits_borrowed[i][lender] > 0) { -+ if (credits[i] >= wlfc->credits_borrowed[i][lender]) { -+ credits[i] -= wlfc->credits_borrowed[i][lender]; -+ wlfc->FIFO_credit[lender] += -+ wlfc->credits_borrowed[i][lender]; -+ wlfc->credits_borrowed[i][lender] = 0; -+ } -+ else { -+ wlfc->credits_borrowed[i][lender] -= credits[i]; -+ wlfc->FIFO_credit[lender] += credits[i]; -+ credits[i] = 0; -+ } -+ } -+ } -+ -+ /* If we have more credits left over, these must belong to the AC */ -+ if (credits[i] > 0) { -+ wlfc->FIFO_credit[i] += credits[i]; -+ } -+ } -+ } -+ -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value) -+{ -+ uint32 timestamp; -+ -+ (void)dhd; -+ -+ bcopy(&value[2], ×tamp, sizeof(uint32)); -+ AP6210_DEBUG("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp); -+ return BCME_OK; -+} -+ -+ -+static int -+dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi) -+{ -+ (void)dhd; -+ (void)rssi; -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ int rc; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ uint8 existing_index; -+ uint8 table_index; -+ uint8 ifid; -+ uint8* ea; -+ -+ AP6210_DEBUG("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", -+ __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], -+ ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), -+ WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]); -+ -+ table = wlfc->destination_entries.nodes; -+ table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]); -+ ifid = value[1]; -+ ea = &value[2]; -+ -+ if (type == WLFC_CTL_TYPE_MACDESC_ADD) { -+ existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]); -+ if (existing_index == WLFC_MAC_DESC_ID_INVALID) { -+ /* this MAC entry does not exist, create one */ -+ if (!table[table_index].occupied) { -+ table[table_index].mac_handle = value[0]; -+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], -+ eWLFC_MAC_ENTRY_ACTION_ADD, ifid, -+ wlfc->destination_entries.interfaces[ifid].iftype, -+ ea); -+ } -+ else { -+ /* the space should have been empty, but it's not */ -+ wlfc->stats.mac_update_failed++; -+ } -+ } -+ else { -+ /* -+ there is an existing entry, move it to new index -+ if necessary. -+ */ -+ if (existing_index != table_index) { -+ /* if we already have an entry, free the old one */ -+ table[existing_index].occupied = 0; -+ table[existing_index].state = WLFC_STATE_CLOSE; -+ table[existing_index].requested_credit = 0; -+ table[existing_index].interface_id = 0; -+ /* enable after packets are queued-deqeued properly. -+ pktq_flush(dhd->osh, &table[existing_index].psq, FALSE, NULL, 0); -+ */ -+ } -+ } -+ } -+ if (type == WLFC_CTL_TYPE_MACDESC_DEL) { -+ if (table[table_index].occupied) { -+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], -+ eWLFC_MAC_ENTRY_ACTION_DEL, ifid, -+ wlfc->destination_entries.interfaces[ifid].iftype, -+ ea); -+ } -+ else { -+ /* the space should have been occupied, but it's not */ -+ wlfc->stats.mac_update_failed++; -+ } -+ } -+ BCM_REFERENCE(rc); -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ /* Handle PS on/off indication */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle = value[0]; -+ int i; -+ -+ table = wlfc->destination_entries.nodes; -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ /* a fresh PS mode should wipe old ps credits? */ -+ desc->requested_credit = 0; -+ if (type == WLFC_CTL_TYPE_MAC_OPEN) { -+ desc->state = WLFC_STATE_OPEN; -+ DHD_WLFC_CTRINC_MAC_OPEN(desc); -+ } -+ else { -+ desc->state = WLFC_STATE_CLOSE; -+ DHD_WLFC_CTRINC_MAC_CLOSE(desc); -+ /* -+ Indicate to firmware if there is any traffic pending. -+ */ -+ for (i = AC_BE; i < AC_COUNT; i++) { -+ _dhd_wlfc_traffic_pending_check(wlfc, desc, i); -+ } -+ } -+ } -+ else { -+ wlfc->stats.psmode_update_failed++; -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) -+{ -+ /* Handle PS on/off indication */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ uint8 if_id = value[0]; -+ -+ if (if_id < WLFC_MAX_IFNUM) { -+ table = wlfc->destination_entries.interfaces; -+ if (table[if_id].occupied) { -+ if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) { -+ table[if_id].state = WLFC_STATE_OPEN; -+ /* AP6210_DEBUG("INTERFACE[%d] OPEN\n", if_id); */ -+ } -+ else { -+ table[if_id].state = WLFC_STATE_CLOSE; -+ /* AP6210_DEBUG("INTERFACE[%d] CLOSE\n", if_id); */ -+ } -+ return BCME_OK; -+ } -+ } -+ wlfc->stats.interface_update_failed++; -+ -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle; -+ uint8 credit; -+ -+ table = wlfc->destination_entries.nodes; -+ mac_handle = value[1]; -+ credit = value[0]; -+ -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ desc->requested_credit = credit; -+ -+ desc->ac_bitmap = value[2]; -+ } -+ else { -+ wlfc->stats.credit_request_failed++; -+ } -+ return BCME_OK; -+} -+ -+static int -+dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) -+{ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_mac_descriptor_t* desc; -+ uint8 mac_handle; -+ uint8 packet_count; -+ -+ table = wlfc->destination_entries.nodes; -+ mac_handle = value[1]; -+ packet_count = value[0]; -+ -+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; -+ if (desc->occupied) { -+ desc->requested_packet = packet_count; -+ -+ desc->ac_bitmap = value[2]; -+ } -+ else { -+ wlfc->stats.packet_request_failed++; -+ } -+ return BCME_OK; -+} -+ -+static void -+dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len) -+{ -+ if (info_len) { -+ if (info_buf) { -+ bcopy(val, info_buf, len); -+ *info_len = len; -+ } -+ else -+ *info_len = 0; -+ } -+} -+ -+int -+dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf, -+ uint *reorder_info_len) -+{ -+ uint8 type, len; -+ uint8* value; -+ uint8* tmpbuf; -+ uint16 remainder = tlv_hdr_len; -+ uint16 processed = 0; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf); -+ if (remainder) { -+ while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) { -+ type = tmpbuf[processed]; -+ if (type == WLFC_CTL_TYPE_FILLER) { -+ remainder -= 1; -+ processed += 1; -+ continue; -+ } -+ -+ len = tmpbuf[processed + 1]; -+ value = &tmpbuf[processed + 2]; -+ -+ if (remainder < (2 + len)) -+ break; -+ -+ remainder -= 2 + len; -+ processed += 2 + len; -+ if (type == WLFC_CTL_TYPE_TXSTATUS) -+ dhd_wlfc_txstatus_update(dhd, value); -+ if (type == WLFC_CTL_TYPE_COMP_TXSTATUS) -+ dhd_wlfc_compressed_txstatus_update(dhd, value, len); -+ -+ else if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS) -+ dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf, -+ reorder_info_len); -+ else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK) -+ dhd_wlfc_fifocreditback_indicate(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_RSSI) -+ dhd_wlfc_rssi_indicate(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) -+ dhd_wlfc_credit_request(dhd, value); -+ -+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) -+ dhd_wlfc_packet_request(dhd, value); -+ -+ else if ((type == WLFC_CTL_TYPE_MAC_OPEN) || -+ (type == WLFC_CTL_TYPE_MAC_CLOSE)) -+ dhd_wlfc_psmode_update(dhd, value, type); -+ -+ else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) || -+ (type == WLFC_CTL_TYPE_MACDESC_DEL)) -+ dhd_wlfc_mac_table_update(dhd, value, type); -+ -+ else if (type == WLFC_CTL_TYPE_TRANS_ID) -+ dhd_wlfc_dbg_senum_check(dhd, value); -+ -+ else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) || -+ (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) { -+ dhd_wlfc_interface_update(dhd, value, type); -+ } -+ } -+ if (remainder != 0) { -+ /* trouble..., something is not right */ -+ wlfc->stats.tlv_parse_failed++; -+ } -+ } -+ return BCME_OK; -+} -+ -+int -+dhd_wlfc_init(dhd_pub_t *dhd) -+{ -+ char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */ -+ /* enable all signals & indicate host proptxstatus logic is active */ -+ uint32 tlv = dhd->wlfc_enabled? -+ WLFC_FLAGS_RSSI_SIGNALS | -+ WLFC_FLAGS_XONXOFF_SIGNALS | -+ WLFC_FLAGS_CREDIT_STATUS_SIGNALS | -+ WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | -+ WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; -+ /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */ -+ -+ -+ /* -+ try to enable/disable signaling by sending "tlv" iovar. if that fails, -+ fallback to no flow control? Print a message for now. -+ */ -+ -+ /* enable proptxtstatus signaling by default */ -+ bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf)); -+ if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { -+ AP6210_ERR("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n"); -+ } -+ else { -+ /* -+ Leaving the message for now, it should be removed after a while; once -+ the tlv situation is stable. -+ */ -+ AP6210_ERR("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n", -+ dhd->wlfc_enabled?"enabled":"disabled", tlv); -+ } -+ return BCME_OK; -+} -+ -+int -+dhd_wlfc_enable(dhd_pub_t *dhd) -+{ -+ int i; -+ athost_wl_status_info_t* wlfc; -+ -+ if (!dhd->wlfc_enabled || dhd->wlfc_state) -+ return BCME_OK; -+ -+ /* allocate space to track txstatus propagated from firmware */ -+ dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t)); -+ if (dhd->wlfc_state == NULL) -+ return BCME_NOMEM; -+ -+ /* initialize state space */ -+ wlfc = (athost_wl_status_info_t*)dhd->wlfc_state; -+ memset(wlfc, 0, sizeof(athost_wl_status_info_t)); -+ -+ /* remember osh & dhdp */ -+ wlfc->osh = dhd->osh; -+ wlfc->dhdp = dhd; -+ -+ wlfc->hanger = -+ dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS); -+ if (wlfc->hanger == NULL) { -+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); -+ dhd->wlfc_state = NULL; -+ AP6210_ERR("Failed to malloc dhd->wlfc_state\n"); -+ return BCME_NOMEM; -+ } -+ -+ /* initialize all interfaces to accept traffic */ -+ for (i = 0; i < WLFC_MAX_IFNUM; i++) { -+ wlfc->hostif_flow_state[i] = OFF; -+ } -+ -+ wlfc->destination_entries.other.state = WLFC_STATE_OPEN; -+ /* bc/mc FIFO is always open [credit aside], i.e. b[5] */ -+ wlfc->destination_entries.other.ac_bitmap = 0x1f; -+ wlfc->destination_entries.other.interface_id = 0; -+ -+ wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT; -+ -+ wlfc->allow_credit_borrow = TRUE; -+ wlfc->borrow_defer_timestamp = 0; -+ -+ return BCME_OK; -+} -+ -+/* release all packet resources */ -+void -+dhd_wlfc_cleanup(dhd_pub_t *dhd, ifpkt_cb_t fn, int arg) -+{ -+ int i; -+ int total_entries; -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ wlfc_mac_descriptor_t* table; -+ wlfc_hanger_t* h; -+ int prec; -+ void *pkt = NULL; -+ struct pktq *txq = NULL; -+ if (dhd->wlfc_state == NULL) -+ return; -+ /* flush bus->txq */ -+ txq = dhd_bus_txq(dhd->bus); -+ /* any in the hanger? */ -+ h = (wlfc_hanger_t*)wlfc->hanger; -+ total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); -+ /* search all entries, include nodes as well as interfaces */ -+ table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries; -+ -+ for (i = 0; i < total_entries; i++) { -+ if (table[i].occupied && (fn == NULL || (arg == table[i].interface_id))) { -+ if (table[i].psq.len) { -+ AP6210_DEBUG("%s(): DELAYQ[%d].len = %d\n", -+ __FUNCTION__, i, table[i].psq.len); -+ /* release packets held in DELAYQ */ -+ pktq_flush(wlfc->osh, &table[i].psq, TRUE, fn, arg); -+ } -+ if (fn == NULL) -+ table[i].occupied = 0; -+ } -+ } -+ for (prec = 0; prec < txq->num_prec; prec++) { -+ pkt = pktq_pdeq_with_fn(txq, prec, fn, arg); -+ while (pkt) { -+ for (i = 0; i < h->max_items; i++) { -+ if (pkt == h->items[i].pkt) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } else if (h->items[i].state == -+ WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { -+ /* These are already freed from the psq */ -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ break; -+ } -+ } -+ pkt = pktq_pdeq(txq, prec); -+ } -+ } -+ /* flush remained pkt in hanger queue, not in bus->txq */ -+ for (i = 0; i < h->max_items; i++) { -+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { -+ if (fn == NULL || (*fn)(h->items[i].pkt, arg)) { -+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { -+ if (fn == NULL || (*fn)(h->items[i].pkt, arg)) { -+ /* These are freed from the psq so no need to free again */ -+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; -+ } -+ } -+ } -+ return; -+} -+ -+void -+dhd_wlfc_deinit(dhd_pub_t *dhd) -+{ -+ /* cleanup all psq related resources */ -+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) -+ dhd->wlfc_state; -+ -+ dhd_os_wlfc_block(dhd); -+ if (dhd->wlfc_state == NULL) { -+ dhd_os_wlfc_unblock(dhd); -+ return; -+ } -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ { -+ int i; -+ wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger; -+ for (i = 0; i < h->max_items; i++) { -+ if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) { -+ AP6210_DEBUG("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n", -+ __FUNCTION__, i, h->items[i].pkt, -+ DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt))); -+ } -+ } -+ } -+#endif -+ /* delete hanger */ -+ dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger); -+ -+ /* free top structure */ -+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); -+ dhd->wlfc_state = NULL; -+ dhd_os_wlfc_unblock(dhd); -+ -+ return; -+} -+#endif /* PROP_TXSTATUS */ -diff --git a/drivers/net/wireless/ap6210/dhd_wlfc.h b/drivers/net/wireless/ap6210/dhd_wlfc.h -new file mode 100644 -index 0000000..42b350c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dhd_wlfc.h -@@ -0,0 +1,288 @@ -+/* -+* Copyright (C) 1999-2012, Broadcom Corporation -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2 (the "GPL"), -+* available at http://www.broadcom.com/licenses/GPLv2.php, with the -+* following added to such license: -+* -+* As a special exception, the copyright holders of this software give you -+* permission to link this software with independent modules, and to copy and -+* distribute the resulting executable under terms of your choice, provided that -+* you also meet, for each linked independent module, the terms and conditions of -+* the license of that module. An independent module is a module which is not -+* derived from this software. The special exception does not apply to any -+* modifications of the software. -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a license -+* other than the GPL, without Broadcom's express prior written consent. -+* $Id: dhd_wlfc.h 361006 2012-10-05 07:45:51Z $ -+* -+*/ -+#ifndef __wlfc_host_driver_definitions_h__ -+#define __wlfc_host_driver_definitions_h__ -+ -+/* 16 bits will provide an absolute max of 65536 slots */ -+#define WLFC_HANGER_MAXITEMS 1024 -+ -+#define WLFC_HANGER_ITEM_STATE_FREE 1 -+#define WLFC_HANGER_ITEM_STATE_INUSE 2 -+#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3 -+#define WLFC_PKTID_HSLOT_MASK 0xffff /* allow 16 bits only */ -+#define WLFC_PKTID_HSLOT_SHIFT 8 -+ -+/* x -> TXSTATUS TAG to/from firmware */ -+#define WLFC_PKTID_HSLOT_GET(x) \ -+ (((x) >> WLFC_PKTID_HSLOT_SHIFT) & WLFC_PKTID_HSLOT_MASK) -+#define WLFC_PKTID_HSLOT_SET(var, slot) \ -+ ((var) = ((var) & ~(WLFC_PKTID_HSLOT_MASK << WLFC_PKTID_HSLOT_SHIFT)) | \ -+ (((slot) & WLFC_PKTID_HSLOT_MASK) << WLFC_PKTID_HSLOT_SHIFT)) -+ -+#define WLFC_PKTID_FREERUNCTR_MASK 0xff -+ -+#define WLFC_PKTID_FREERUNCTR_GET(x) ((x) & WLFC_PKTID_FREERUNCTR_MASK) -+#define WLFC_PKTID_FREERUNCTR_SET(var, ctr) \ -+ ((var) = (((var) & ~WLFC_PKTID_FREERUNCTR_MASK) | \ -+ (((ctr) & WLFC_PKTID_FREERUNCTR_MASK)))) -+ -+#define WLFC_PKTQ_PENQ(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec)))? \ -+ NULL : pktq_penq((pq), (prec), (p))) -+#define WLFC_PKTQ_PENQ_HEAD(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec))) ? \ -+ NULL : pktq_penq_head((pq), (prec), (p))) -+ -+typedef enum ewlfc_packet_state { -+ eWLFC_PKTTYPE_NEW, -+ eWLFC_PKTTYPE_DELAYED, -+ eWLFC_PKTTYPE_SUPPRESSED, -+ eWLFC_PKTTYPE_MAX -+} ewlfc_packet_state_t; -+ -+typedef enum ewlfc_mac_entry_action { -+ eWLFC_MAC_ENTRY_ACTION_ADD, -+ eWLFC_MAC_ENTRY_ACTION_DEL, -+ eWLFC_MAC_ENTRY_ACTION_UPDATE, -+ eWLFC_MAC_ENTRY_ACTION_MAX -+} ewlfc_mac_entry_action_t; -+ -+typedef struct wlfc_hanger_item { -+ uint8 state; -+ uint8 gen; -+ uint8 pad[2]; -+ uint32 identifier; -+ void* pkt; -+#ifdef PROP_TXSTATUS_DEBUG -+ uint32 push_time; -+#endif -+} wlfc_hanger_item_t; -+ -+typedef struct wlfc_hanger { -+ int max_items; -+ uint32 pushed; -+ uint32 popped; -+ uint32 failed_to_push; -+ uint32 failed_to_pop; -+ uint32 failed_slotfind; -+ wlfc_hanger_item_t items[1]; -+ uint32 slot_pos; -+} wlfc_hanger_t; -+ -+#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \ -+ sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t))) -+ -+#define WLFC_STATE_OPEN 1 -+#define WLFC_STATE_CLOSE 2 -+ -+#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /* 2 for each AC traffic and bc/mc */ -+ -+#define WLFC_PSQ_LEN 2048 -+ -+#define WLFC_SENDQ_LEN 256 -+ -+ -+#define WLFC_FLOWCONTROL_HIWATER (2048 - 256) -+#define WLFC_FLOWCONTROL_LOWATER 256 -+ -+ -+typedef struct wlfc_mac_descriptor { -+ uint8 occupied; -+ uint8 interface_id; -+ uint8 iftype; -+ uint8 state; -+ uint8 ac_bitmap; /* for APSD */ -+ uint8 requested_credit; -+ uint8 requested_packet; -+ uint8 ea[ETHER_ADDR_LEN]; -+ /* -+ maintain (MAC,AC) based seq count for -+ packets going to the device. As well as bc/mc. -+ */ -+ uint8 seq[AC_COUNT + 1]; -+ uint8 generation; -+ struct pktq psq; -+ /* The AC pending bitmap that was reported to the fw at last change */ -+ uint8 traffic_lastreported_bmp; -+ /* The new AC pending bitmap */ -+ uint8 traffic_pending_bmp; -+ /* 1= send on next opportunity */ -+ uint8 send_tim_signal; -+ uint8 mac_handle; -+ uint transit_count; -+ uint suppr_transit_count; -+ uint suppress_count; -+ uint8 suppressed; -+ -+#ifdef PROP_TXSTATUS_DEBUG -+ uint32 dstncredit_sent_packets; -+ uint32 dstncredit_acks; -+ uint32 opened_ct; -+ uint32 closed_ct; -+#endif -+} wlfc_mac_descriptor_t; -+ -+#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\ -+ entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0) -+ -+#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++ -+#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)] -+ -+typedef struct athost_wl_stat_counters { -+ uint32 pktin; -+ uint32 pkt2bus; -+ uint32 pktdropped; -+ uint32 tlv_parse_failed; -+ uint32 rollback; -+ uint32 rollback_failed; -+ uint32 sendq_full_error; -+ uint32 delayq_full_error; -+ uint32 credit_request_failed; -+ uint32 packet_request_failed; -+ uint32 mac_update_failed; -+ uint32 psmode_update_failed; -+ uint32 interface_update_failed; -+ uint32 wlfc_header_only_pkt; -+ uint32 txstatus_in; -+ uint32 d11_suppress; -+ uint32 wl_suppress; -+ uint32 bad_suppress; -+ uint32 pkt_freed; -+ uint32 pkt_free_err; -+ uint32 psq_wlsup_retx; -+ uint32 psq_wlsup_enq; -+ uint32 psq_d11sup_retx; -+ uint32 psq_d11sup_enq; -+ uint32 psq_hostq_retx; -+ uint32 psq_hostq_enq; -+ uint32 mac_handle_notfound; -+ uint32 wlc_tossed_pkts; -+ uint32 dhd_hdrpulls; -+ uint32 generic_error; -+ /* an extra one for bc/mc traffic */ -+ uint32 sendq_pkts[AC_COUNT + 1]; -+#ifdef PROP_TXSTATUS_DEBUG -+ /* all pkt2bus -> txstatus latency accumulated */ -+ uint32 latency_sample_count; -+ uint32 total_status_latency; -+ uint32 latency_most_recent; -+ int idx_delta; -+ uint32 deltas[10]; -+ uint32 fifo_credits_sent[6]; -+ uint32 fifo_credits_back[6]; -+ uint32 dropped_qfull[6]; -+ uint32 signal_only_pkts_sent; -+ uint32 signal_only_pkts_freed; -+#endif -+} athost_wl_stat_counters_t; -+ -+#ifdef PROP_TXSTATUS_DEBUG -+#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \ -+ (ctx)->stats.fifo_credits_sent[(ac)]++;} while (0) -+#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \ -+ (ctx)->stats.fifo_credits_back[(ac)]++;} while (0) -+#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \ -+ (ctx)->stats.dropped_qfull[(ac)]++;} while (0) -+#else -+#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0) -+#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0) -+#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0) -+#endif -+ -+#define WLFC_FCMODE_NONE 0 -+#define WLFC_FCMODE_IMPLIED_CREDIT 1 -+#define WLFC_FCMODE_EXPLICIT_CREDIT 2 -+ -+/* How long to defer borrowing in milliseconds */ -+#define WLFC_BORROW_DEFER_PERIOD_MS 100 -+ -+/* Mask to represent available ACs (note: BC/MC is ignored */ -+#define WLFC_AC_MASK 0xF -+ -+/* Mask to check for only on-going AC_BE traffic */ -+#define WLFC_AC_BE_TRAFFIC_ONLY 0xD -+ -+typedef struct athost_wl_status_info { -+ uint8 last_seqid_to_wlc; -+ -+ /* OSL handle */ -+ osl_t* osh; -+ /* dhd pub */ -+ void* dhdp; -+ -+ /* stats */ -+ athost_wl_stat_counters_t stats; -+ -+ /* the additional ones are for bc/mc and ATIM FIFO */ -+ int FIFO_credit[AC_COUNT + 2]; -+ -+ /* Credit borrow counts for each FIFO from each of the other FIFOs */ -+ int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2]; -+ -+ struct pktq SENDQ; -+ -+ /* packet hanger and MAC->handle lookup table */ -+ void* hanger; -+ struct { -+ /* table for individual nodes */ -+ wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE]; -+ /* table for interfaces */ -+ wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM]; -+ /* OS may send packets to unknown (unassociated) destinations */ -+ /* A place holder for bc/mc and packets to unknown destinations */ -+ wlfc_mac_descriptor_t other; -+ } destination_entries; -+ /* token position for different priority packets */ -+ uint8 token_pos[AC_COUNT+1]; -+ /* ON/OFF state for flow control to the host network interface */ -+ uint8 hostif_flow_state[WLFC_MAX_IFNUM]; -+ uint8 host_ifidx; -+ /* to flow control an OS interface */ -+ uint8 toggle_host_if; -+ -+ /* -+ Mode in which the dhd flow control shall operate. Must be set before -+ traffic starts to the device. -+ 0 - Do not do any proptxtstatus flow control -+ 1 - Use implied credit from a packet status -+ 2 - Use explicit credit -+ */ -+ uint8 proptxstatus_mode; -+ -+ /* To borrow credits */ -+ uint8 allow_credit_borrow; -+ -+ /* Timestamp to compute how long to defer borrowing for */ -+ uint32 borrow_defer_timestamp; -+ -+ bool wlfc_locked; -+} athost_wl_status_info_t; -+ -+int dhd_wlfc_enable(dhd_pub_t *dhd); -+int dhd_wlfc_interface_event(struct dhd_info *, -+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea); -+int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data); -+int dhd_wlfc_event(struct dhd_info *dhd); -+int dhd_os_wlfc_block(dhd_pub_t *pub); -+int dhd_os_wlfc_unblock(dhd_pub_t *pub); -+ -+#endif /* __wlfc_host_driver_definitions_h__ */ -diff --git a/drivers/net/wireless/ap6210/dngl_stats.h b/drivers/net/wireless/ap6210/dngl_stats.h -new file mode 100644 -index 0000000..5e5a2e2 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dngl_stats.h -@@ -0,0 +1,43 @@ -+/* -+ * Common stats definitions for clients of dongle -+ * ports -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dngl_stats.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _dngl_stats_h_ -+#define _dngl_stats_h_ -+ -+typedef struct { -+ unsigned long rx_packets; /* total packets received */ -+ unsigned long tx_packets; /* total packets transmitted */ -+ unsigned long rx_bytes; /* total bytes received */ -+ unsigned long tx_bytes; /* total bytes transmitted */ -+ unsigned long rx_errors; /* bad packets received */ -+ unsigned long tx_errors; /* packet transmit problems */ -+ unsigned long rx_dropped; /* packets dropped by dongle */ -+ unsigned long tx_dropped; /* packets dropped by dongle */ -+ unsigned long multicast; /* multicast packets received */ -+} dngl_stats_t; -+ -+#endif /* _dngl_stats_h_ */ -diff --git a/drivers/net/wireless/ap6210/dngl_wlhdr.h b/drivers/net/wireless/ap6210/dngl_wlhdr.h -new file mode 100644 -index 0000000..0e37df6 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/dngl_wlhdr.h -@@ -0,0 +1,40 @@ -+/* -+ * Dongle WL Header definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dngl_wlhdr.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _dngl_wlhdr_h_ -+#define _dngl_wlhdr_h_ -+ -+typedef struct wl_header { -+ uint8 type; /* Header type */ -+ uint8 version; /* Header version */ -+ int8 rssi; /* RSSI */ -+ uint8 pad; /* Unused */ -+} wl_header_t; -+ -+#define WL_HEADER_LEN sizeof(wl_header_t) -+#define WL_HEADER_TYPE 0 -+#define WL_HEADER_VER 1 -+#endif /* _dngl_wlhdr_h_ */ -diff --git a/drivers/net/wireless/ap6210/hndpmu.c b/drivers/net/wireless/ap6210/hndpmu.c -new file mode 100644 -index 0000000..e639015 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/hndpmu.c -@@ -0,0 +1,208 @@ -+/* -+ * Misc utility routines for accessing PMU corerev specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: hndpmu.c 354194 2012-08-30 08:39:03Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PMU_ERROR(args) -+ -+#define PMU_MSG(args) -+ -+/* To check in verbose debugging messages not intended -+ * to be on except on private builds. -+ */ -+#define PMU_NONE(args) -+ -+ -+/* SDIO Pad drive strength to select value mappings. -+ * The last strength value in each table must be 0 (the tri-state value). -+ */ -+typedef struct { -+ uint8 strength; /* Pad Drive Strength in mA */ -+ uint8 sel; /* Chip-specific select value */ -+} sdiod_drive_str_t; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 1 */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = { -+ {4, 0x2}, -+ {2, 0x3}, -+ {1, 0x0}, -+ {0, 0x0} }; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = { -+ {12, 0x7}, -+ {10, 0x6}, -+ {8, 0x5}, -+ {6, 0x4}, -+ {4, 0x2}, -+ {2, 0x1}, -+ {0, 0x0} }; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { -+ {32, 0x7}, -+ {26, 0x6}, -+ {22, 0x5}, -+ {16, 0x4}, -+ {12, 0x3}, -+ {8, 0x2}, -+ {4, 0x1}, -+ {0, 0x0} }; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8v) */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab4_1v8[] = { -+ {32, 0x6}, -+ {26, 0x7}, -+ {22, 0x4}, -+ {16, 0x5}, -+ {12, 0x2}, -+ {8, 0x3}, -+ {4, 0x0}, -+ {0, 0x1} }; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */ -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */ -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab5_1v8[] = { -+ {6, 0x7}, -+ {5, 0x6}, -+ {4, 0x5}, -+ {3, 0x4}, -+ {2, 0x2}, -+ {1, 0x1}, -+ {0, 0x0} }; -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */ -+ -+/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */ -+static const sdiod_drive_str_t sdiod_drive_strength_tab6_1v8[] = { -+ {3, 0x3}, -+ {2, 0x2}, -+ {1, 0x1}, -+ {0, 0x0} }; -+ -+#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) -+ -+void -+si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength) -+{ -+ chipcregs_t *cc; -+ uint origidx, intr_val = 0; -+ sdiod_drive_str_t *str_tab = NULL; -+ uint32 str_mask = 0; -+ uint32 str_shift = 0; -+ -+ if (!(sih->cccaps & CC_CAP_PMU)) { -+ return; -+ } -+ -+ /* Remember original core before switch to chipc */ -+ cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); -+ -+ switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) { -+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1; -+ str_mask = 0x30000000; -+ str_shift = 28; -+ break; -+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): -+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): -+ case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4): -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2; -+ str_mask = 0x00003800; -+ str_shift = 11; -+ break; -+ case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): -+ case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 11): -+ if (sih->pmurev == 8) { -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3; -+ } -+ else if (sih->pmurev == 11) { -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; -+ } -+ str_mask = 0x00003800; -+ str_shift = 11; -+ break; -+ case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12): -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8; -+ str_mask = 0x00003800; -+ str_shift = 11; -+ break; -+ case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab5_1v8; -+ str_mask = 0x00003800; -+ str_shift = 11; -+ break; -+ case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17): -+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab6_1v8; -+ str_mask = 0x00001800; -+ str_shift = 11; -+ break; -+ default: -+ PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", -+ bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); -+ -+ break; -+ } -+ -+ if (str_tab != NULL && cc != NULL) { -+ uint32 cc_data_temp; -+ int i; -+ -+ /* Pick the lowest available drive strength equal or greater than the -+ * requested strength. Drive strength of 0 requests tri-state. -+ */ -+ for (i = 0; drivestrength < str_tab[i].strength; i++) -+ ; -+ -+ if (i > 0 && drivestrength > str_tab[i].strength) -+ i--; -+ -+ W_REG(osh, &cc->chipcontrol_addr, 1); -+ cc_data_temp = R_REG(osh, &cc->chipcontrol_data); -+ cc_data_temp &= ~str_mask; -+ cc_data_temp |= str_tab[i].sel << str_shift; -+ W_REG(osh, &cc->chipcontrol_data, cc_data_temp); -+ -+ PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n", -+ drivestrength, str_tab[i].strength)); -+ } -+ -+ /* Return to original core */ -+ si_restore_core(sih, origidx, intr_val); -+} -diff --git a/drivers/net/wireless/ap6210/include/Makefile b/drivers/net/wireless/ap6210/include/Makefile -new file mode 100644 -index 0000000..8483b54 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/Makefile -@@ -0,0 +1,54 @@ -+#!/bin/bash -+# -+# This script serves following purpose: -+# -+# 1. It generates native version information by querying -+# automerger maintained database to see where src/include -+# came from -+# 2. For select components, as listed in compvers.sh -+# it generates component version files -+# -+# Copyright 2005, Broadcom, Inc. -+# -+# $Id: Makefile 241686 2011-02-19 00:22:45Z prakashd $ -+# -+ -+SRCBASE := .. -+ -+TARGETS := epivers.h -+ -+ifdef VERBOSE -+export VERBOSE -+endif -+ -+all release: epivers compvers -+ -+# Generate epivers.h for native branch version -+epivers: -+ bash epivers.sh -+ -+# Generate epivers.h for native branch version -+compvers: -+ @if [ -s "compvers.sh" ]; then \ -+ echo "Generating component versions, if any"; \ -+ bash compvers.sh; \ -+ else \ -+ echo "Skipping component version generation"; \ -+ fi -+ -+# Generate epivers.h for native branch version -+clean_compvers: -+ @if [ -s "compvers.sh" ]; then \ -+ echo "bash compvers.sh clean"; \ -+ bash compvers.sh clean; \ -+ else \ -+ echo "Skipping component version clean"; \ -+ fi -+ -+clean: -+ rm -f $(TARGETS) *.prev -+ -+clean_all: clean clean_compvers -+ -+.PHONY: all release clean epivers compvers clean_compvers -+ -diff --git a/drivers/net/wireless/ap6210/include/aidmp.h b/drivers/net/wireless/ap6210/include/aidmp.h -new file mode 100644 -index 0000000..d557079 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/aidmp.h -@@ -0,0 +1,375 @@ -+/* -+ * Broadcom AMBA Interconnect definitions. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _AIDMP_H -+#define _AIDMP_H -+ -+/* Manufacturer Ids */ -+#define MFGID_ARM 0x43b -+#define MFGID_BRCM 0x4bf -+#define MFGID_MIPS 0x4a7 -+ -+/* Component Classes */ -+#define CC_SIM 0 -+#define CC_EROM 1 -+#define CC_CORESIGHT 9 -+#define CC_VERIF 0xb -+#define CC_OPTIMO 0xd -+#define CC_GEN 0xe -+#define CC_PRIMECELL 0xf -+ -+/* Enumeration ROM registers */ -+#define ER_EROMENTRY 0x000 -+#define ER_REMAPCONTROL 0xe00 -+#define ER_REMAPSELECT 0xe04 -+#define ER_MASTERSELECT 0xe10 -+#define ER_ITCR 0xf00 -+#define ER_ITIP 0xf04 -+ -+/* Erom entries */ -+#define ER_TAG 0xe -+#define ER_TAG1 0x6 -+#define ER_VALID 1 -+#define ER_CI 0 -+#define ER_MP 2 -+#define ER_ADD 4 -+#define ER_END 0xe -+#define ER_BAD 0xffffffff -+ -+/* EROM CompIdentA */ -+#define CIA_MFG_MASK 0xfff00000 -+#define CIA_MFG_SHIFT 20 -+#define CIA_CID_MASK 0x000fff00 -+#define CIA_CID_SHIFT 8 -+#define CIA_CCL_MASK 0x000000f0 -+#define CIA_CCL_SHIFT 4 -+ -+/* EROM CompIdentB */ -+#define CIB_REV_MASK 0xff000000 -+#define CIB_REV_SHIFT 24 -+#define CIB_NSW_MASK 0x00f80000 -+#define CIB_NSW_SHIFT 19 -+#define CIB_NMW_MASK 0x0007c000 -+#define CIB_NMW_SHIFT 14 -+#define CIB_NSP_MASK 0x00003e00 -+#define CIB_NSP_SHIFT 9 -+#define CIB_NMP_MASK 0x000001f0 -+#define CIB_NMP_SHIFT 4 -+ -+/* EROM MasterPortDesc */ -+#define MPD_MUI_MASK 0x0000ff00 -+#define MPD_MUI_SHIFT 8 -+#define MPD_MP_MASK 0x000000f0 -+#define MPD_MP_SHIFT 4 -+ -+/* EROM AddrDesc */ -+#define AD_ADDR_MASK 0xfffff000 -+#define AD_SP_MASK 0x00000f00 -+#define AD_SP_SHIFT 8 -+#define AD_ST_MASK 0x000000c0 -+#define AD_ST_SHIFT 6 -+#define AD_ST_SLAVE 0x00000000 -+#define AD_ST_BRIDGE 0x00000040 -+#define AD_ST_SWRAP 0x00000080 -+#define AD_ST_MWRAP 0x000000c0 -+#define AD_SZ_MASK 0x00000030 -+#define AD_SZ_SHIFT 4 -+#define AD_SZ_4K 0x00000000 -+#define AD_SZ_8K 0x00000010 -+#define AD_SZ_16K 0x00000020 -+#define AD_SZ_SZD 0x00000030 -+#define AD_AG32 0x00000008 -+#define AD_ADDR_ALIGN 0x00000fff -+#define AD_SZ_BASE 0x00001000 /* 4KB */ -+ -+/* EROM SizeDesc */ -+#define SD_SZ_MASK 0xfffff000 -+#define SD_SG32 0x00000008 -+#define SD_SZ_ALIGN 0x00000fff -+ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+typedef volatile struct _aidmp { -+ uint32 oobselina30; /* 0x000 */ -+ uint32 oobselina74; /* 0x004 */ -+ uint32 PAD[6]; -+ uint32 oobselinb30; /* 0x020 */ -+ uint32 oobselinb74; /* 0x024 */ -+ uint32 PAD[6]; -+ uint32 oobselinc30; /* 0x040 */ -+ uint32 oobselinc74; /* 0x044 */ -+ uint32 PAD[6]; -+ uint32 oobselind30; /* 0x060 */ -+ uint32 oobselind74; /* 0x064 */ -+ uint32 PAD[38]; -+ uint32 oobselouta30; /* 0x100 */ -+ uint32 oobselouta74; /* 0x104 */ -+ uint32 PAD[6]; -+ uint32 oobseloutb30; /* 0x120 */ -+ uint32 oobseloutb74; /* 0x124 */ -+ uint32 PAD[6]; -+ uint32 oobseloutc30; /* 0x140 */ -+ uint32 oobseloutc74; /* 0x144 */ -+ uint32 PAD[6]; -+ uint32 oobseloutd30; /* 0x160 */ -+ uint32 oobseloutd74; /* 0x164 */ -+ uint32 PAD[38]; -+ uint32 oobsynca; /* 0x200 */ -+ uint32 oobseloutaen; /* 0x204 */ -+ uint32 PAD[6]; -+ uint32 oobsyncb; /* 0x220 */ -+ uint32 oobseloutben; /* 0x224 */ -+ uint32 PAD[6]; -+ uint32 oobsyncc; /* 0x240 */ -+ uint32 oobseloutcen; /* 0x244 */ -+ uint32 PAD[6]; -+ uint32 oobsyncd; /* 0x260 */ -+ uint32 oobseloutden; /* 0x264 */ -+ uint32 PAD[38]; -+ uint32 oobaextwidth; /* 0x300 */ -+ uint32 oobainwidth; /* 0x304 */ -+ uint32 oobaoutwidth; /* 0x308 */ -+ uint32 PAD[5]; -+ uint32 oobbextwidth; /* 0x320 */ -+ uint32 oobbinwidth; /* 0x324 */ -+ uint32 oobboutwidth; /* 0x328 */ -+ uint32 PAD[5]; -+ uint32 oobcextwidth; /* 0x340 */ -+ uint32 oobcinwidth; /* 0x344 */ -+ uint32 oobcoutwidth; /* 0x348 */ -+ uint32 PAD[5]; -+ uint32 oobdextwidth; /* 0x360 */ -+ uint32 oobdinwidth; /* 0x364 */ -+ uint32 oobdoutwidth; /* 0x368 */ -+ uint32 PAD[37]; -+ uint32 ioctrlset; /* 0x400 */ -+ uint32 ioctrlclear; /* 0x404 */ -+ uint32 ioctrl; /* 0x408 */ -+ uint32 PAD[61]; -+ uint32 iostatus; /* 0x500 */ -+ uint32 PAD[127]; -+ uint32 ioctrlwidth; /* 0x700 */ -+ uint32 iostatuswidth; /* 0x704 */ -+ uint32 PAD[62]; -+ uint32 resetctrl; /* 0x800 */ -+ uint32 resetstatus; /* 0x804 */ -+ uint32 resetreadid; /* 0x808 */ -+ uint32 resetwriteid; /* 0x80c */ -+ uint32 PAD[60]; -+ uint32 errlogctrl; /* 0x900 */ -+ uint32 errlogdone; /* 0x904 */ -+ uint32 errlogstatus; /* 0x908 */ -+ uint32 errlogaddrlo; /* 0x90c */ -+ uint32 errlogaddrhi; /* 0x910 */ -+ uint32 errlogid; /* 0x914 */ -+ uint32 errloguser; /* 0x918 */ -+ uint32 errlogflags; /* 0x91c */ -+ uint32 PAD[56]; -+ uint32 intstatus; /* 0xa00 */ -+ uint32 PAD[255]; -+ uint32 config; /* 0xe00 */ -+ uint32 PAD[63]; -+ uint32 itcr; /* 0xf00 */ -+ uint32 PAD[3]; -+ uint32 itipooba; /* 0xf10 */ -+ uint32 itipoobb; /* 0xf14 */ -+ uint32 itipoobc; /* 0xf18 */ -+ uint32 itipoobd; /* 0xf1c */ -+ uint32 PAD[4]; -+ uint32 itipoobaout; /* 0xf30 */ -+ uint32 itipoobbout; /* 0xf34 */ -+ uint32 itipoobcout; /* 0xf38 */ -+ uint32 itipoobdout; /* 0xf3c */ -+ uint32 PAD[4]; -+ uint32 itopooba; /* 0xf50 */ -+ uint32 itopoobb; /* 0xf54 */ -+ uint32 itopoobc; /* 0xf58 */ -+ uint32 itopoobd; /* 0xf5c */ -+ uint32 PAD[4]; -+ uint32 itopoobain; /* 0xf70 */ -+ uint32 itopoobbin; /* 0xf74 */ -+ uint32 itopoobcin; /* 0xf78 */ -+ uint32 itopoobdin; /* 0xf7c */ -+ uint32 PAD[4]; -+ uint32 itopreset; /* 0xf90 */ -+ uint32 PAD[15]; -+ uint32 peripherialid4; /* 0xfd0 */ -+ uint32 peripherialid5; /* 0xfd4 */ -+ uint32 peripherialid6; /* 0xfd8 */ -+ uint32 peripherialid7; /* 0xfdc */ -+ uint32 peripherialid0; /* 0xfe0 */ -+ uint32 peripherialid1; /* 0xfe4 */ -+ uint32 peripherialid2; /* 0xfe8 */ -+ uint32 peripherialid3; /* 0xfec */ -+ uint32 componentid0; /* 0xff0 */ -+ uint32 componentid1; /* 0xff4 */ -+ uint32 componentid2; /* 0xff8 */ -+ uint32 componentid3; /* 0xffc */ -+} aidmp_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* Out-of-band Router registers */ -+#define OOB_BUSCONFIG 0x020 -+#define OOB_STATUSA 0x100 -+#define OOB_STATUSB 0x104 -+#define OOB_STATUSC 0x108 -+#define OOB_STATUSD 0x10c -+#define OOB_ENABLEA0 0x200 -+#define OOB_ENABLEA1 0x204 -+#define OOB_ENABLEA2 0x208 -+#define OOB_ENABLEA3 0x20c -+#define OOB_ENABLEB0 0x280 -+#define OOB_ENABLEB1 0x284 -+#define OOB_ENABLEB2 0x288 -+#define OOB_ENABLEB3 0x28c -+#define OOB_ENABLEC0 0x300 -+#define OOB_ENABLEC1 0x304 -+#define OOB_ENABLEC2 0x308 -+#define OOB_ENABLEC3 0x30c -+#define OOB_ENABLED0 0x380 -+#define OOB_ENABLED1 0x384 -+#define OOB_ENABLED2 0x388 -+#define OOB_ENABLED3 0x38c -+#define OOB_ITCR 0xf00 -+#define OOB_ITIPOOBA 0xf10 -+#define OOB_ITIPOOBB 0xf14 -+#define OOB_ITIPOOBC 0xf18 -+#define OOB_ITIPOOBD 0xf1c -+#define OOB_ITOPOOBA 0xf30 -+#define OOB_ITOPOOBB 0xf34 -+#define OOB_ITOPOOBC 0xf38 -+#define OOB_ITOPOOBD 0xf3c -+ -+/* DMP wrapper registers */ -+#define AI_OOBSELINA30 0x000 -+#define AI_OOBSELINA74 0x004 -+#define AI_OOBSELINB30 0x020 -+#define AI_OOBSELINB74 0x024 -+#define AI_OOBSELINC30 0x040 -+#define AI_OOBSELINC74 0x044 -+#define AI_OOBSELIND30 0x060 -+#define AI_OOBSELIND74 0x064 -+#define AI_OOBSELOUTA30 0x100 -+#define AI_OOBSELOUTA74 0x104 -+#define AI_OOBSELOUTB30 0x120 -+#define AI_OOBSELOUTB74 0x124 -+#define AI_OOBSELOUTC30 0x140 -+#define AI_OOBSELOUTC74 0x144 -+#define AI_OOBSELOUTD30 0x160 -+#define AI_OOBSELOUTD74 0x164 -+#define AI_OOBSYNCA 0x200 -+#define AI_OOBSELOUTAEN 0x204 -+#define AI_OOBSYNCB 0x220 -+#define AI_OOBSELOUTBEN 0x224 -+#define AI_OOBSYNCC 0x240 -+#define AI_OOBSELOUTCEN 0x244 -+#define AI_OOBSYNCD 0x260 -+#define AI_OOBSELOUTDEN 0x264 -+#define AI_OOBAEXTWIDTH 0x300 -+#define AI_OOBAINWIDTH 0x304 -+#define AI_OOBAOUTWIDTH 0x308 -+#define AI_OOBBEXTWIDTH 0x320 -+#define AI_OOBBINWIDTH 0x324 -+#define AI_OOBBOUTWIDTH 0x328 -+#define AI_OOBCEXTWIDTH 0x340 -+#define AI_OOBCINWIDTH 0x344 -+#define AI_OOBCOUTWIDTH 0x348 -+#define AI_OOBDEXTWIDTH 0x360 -+#define AI_OOBDINWIDTH 0x364 -+#define AI_OOBDOUTWIDTH 0x368 -+ -+ -+#define AI_IOCTRLSET 0x400 -+#define AI_IOCTRLCLEAR 0x404 -+#define AI_IOCTRL 0x408 -+#define AI_IOSTATUS 0x500 -+#define AI_RESETCTRL 0x800 -+#define AI_RESETSTATUS 0x804 -+ -+#define AI_IOCTRLWIDTH 0x700 -+#define AI_IOSTATUSWIDTH 0x704 -+ -+#define AI_RESETREADID 0x808 -+#define AI_RESETWRITEID 0x80c -+#define AI_ERRLOGCTRL 0xa00 -+#define AI_ERRLOGDONE 0xa04 -+#define AI_ERRLOGSTATUS 0xa08 -+#define AI_ERRLOGADDRLO 0xa0c -+#define AI_ERRLOGADDRHI 0xa10 -+#define AI_ERRLOGID 0xa14 -+#define AI_ERRLOGUSER 0xa18 -+#define AI_ERRLOGFLAGS 0xa1c -+#define AI_INTSTATUS 0xa00 -+#define AI_CONFIG 0xe00 -+#define AI_ITCR 0xf00 -+#define AI_ITIPOOBA 0xf10 -+#define AI_ITIPOOBB 0xf14 -+#define AI_ITIPOOBC 0xf18 -+#define AI_ITIPOOBD 0xf1c -+#define AI_ITIPOOBAOUT 0xf30 -+#define AI_ITIPOOBBOUT 0xf34 -+#define AI_ITIPOOBCOUT 0xf38 -+#define AI_ITIPOOBDOUT 0xf3c -+#define AI_ITOPOOBA 0xf50 -+#define AI_ITOPOOBB 0xf54 -+#define AI_ITOPOOBC 0xf58 -+#define AI_ITOPOOBD 0xf5c -+#define AI_ITOPOOBAIN 0xf70 -+#define AI_ITOPOOBBIN 0xf74 -+#define AI_ITOPOOBCIN 0xf78 -+#define AI_ITOPOOBDIN 0xf7c -+#define AI_ITOPRESET 0xf90 -+#define AI_PERIPHERIALID4 0xfd0 -+#define AI_PERIPHERIALID5 0xfd4 -+#define AI_PERIPHERIALID6 0xfd8 -+#define AI_PERIPHERIALID7 0xfdc -+#define AI_PERIPHERIALID0 0xfe0 -+#define AI_PERIPHERIALID1 0xfe4 -+#define AI_PERIPHERIALID2 0xfe8 -+#define AI_PERIPHERIALID3 0xfec -+#define AI_COMPONENTID0 0xff0 -+#define AI_COMPONENTID1 0xff4 -+#define AI_COMPONENTID2 0xff8 -+#define AI_COMPONENTID3 0xffc -+ -+/* resetctrl */ -+#define AIRC_RESET 1 -+ -+/* config */ -+#define AICFG_OOB 0x00000020 -+#define AICFG_IOS 0x00000010 -+#define AICFG_IOC 0x00000008 -+#define AICFG_TO 0x00000004 -+#define AICFG_ERRL 0x00000002 -+#define AICFG_RST 0x00000001 -+ -+/* bit defines for AI_OOBSELOUTB74 reg */ -+#define OOB_SEL_OUTEN_B_5 15 -+#define OOB_SEL_OUTEN_B_6 23 -+ -+#endif /* _AIDMP_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcm_cfg.h b/drivers/net/wireless/ap6210/include/bcm_cfg.h -new file mode 100644 -index 0000000..ecff4f4 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcm_cfg.h -@@ -0,0 +1,29 @@ -+/* -+ * BCM common config options -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $ -+ */ -+ -+#ifndef _bcm_cfg_h_ -+#define _bcm_cfg_h_ -+#endif /* _bcm_cfg_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h b/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h -new file mode 100644 -index 0000000..8fe3de7 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h -@@ -0,0 +1,361 @@ -+/* -+ * Memory pools library, Public interface -+ * -+ * API Overview -+ * -+ * This package provides a memory allocation subsystem based on pools of -+ * homogenous objects. -+ * -+ * Instrumentation is available for reporting memory utilization both -+ * on a per-data-structure basis and system wide. -+ * -+ * There are two main types defined in this API. -+ * -+ * pool manager: A singleton object that acts as a factory for -+ * pool allocators. It also is used for global -+ * instrumentation, such as reporting all blocks -+ * in use across all data structures. The pool manager -+ * creates and provides individual memory pools -+ * upon request to application code. -+ * -+ * memory pool: An object for allocating homogenous memory blocks. -+ * -+ * Global identifiers in this module use the following prefixes: -+ * bcm_mpm_* Memory pool manager -+ * bcm_mp_* Memory pool -+ * -+ * There are two main types of memory pools: -+ * -+ * prealloc: The contiguous memory block of objects can either be supplied -+ * by the client or malloc'ed by the memory manager. The objects are -+ * allocated out of a block of memory and freed back to the block. -+ * -+ * heap: The memory pool allocator uses the heap (malloc/free) for memory. -+ * In this case, the pool allocator is just providing statistics -+ * and instrumentation on top of the heap, without modifying the heap -+ * allocation implementation. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _BCM_MPOOL_PUB_H -+#define _BCM_MPOOL_PUB_H 1 -+ -+#include /* needed for uint16 */ -+ -+ -+/* -+************************************************************************** -+* -+* Type definitions, handles -+* -+************************************************************************** -+*/ -+ -+/* Forward declaration of OSL handle. */ -+struct osl_info; -+ -+/* Forward declaration of string buffer. */ -+struct bcmstrbuf; -+ -+/* -+ * Opaque type definition for the pool manager handle. This object is used for global -+ * memory pool operations such as obtaining a new pool, deleting a pool, iterating and -+ * instrumentation/debugging. -+ */ -+struct bcm_mpm_mgr; -+typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h; -+ -+/* -+ * Opaque type definition for an instance of a pool. This handle is used for allocating -+ * and freeing memory through the pool, as well as management/instrumentation on this -+ * specific pool. -+ */ -+struct bcm_mp_pool; -+typedef struct bcm_mp_pool *bcm_mp_pool_h; -+ -+ -+/* -+ * To make instrumentation more readable, every memory -+ * pool must have a readable name. Pool names are up to -+ * 8 bytes including '\0' termination. (7 printable characters.) -+ */ -+#define BCM_MP_NAMELEN 8 -+ -+ -+/* -+ * Type definition for pool statistics. -+ */ -+typedef struct bcm_mp_stats { -+ char name[BCM_MP_NAMELEN]; /* Name of this pool. */ -+ unsigned int objsz; /* Object size allocated in this pool */ -+ uint16 nobj; /* Total number of objects in this pool */ -+ uint16 num_alloc; /* Number of objects currently allocated */ -+ uint16 high_water; /* Max number of allocated objects. */ -+ uint16 failed_alloc; /* Failed allocations. */ -+} bcm_mp_stats_t; -+ -+ -+/* -+************************************************************************** -+* -+* API Routines on the pool manager. -+* -+************************************************************************** -+*/ -+ -+/* -+ * bcm_mpm_init() - initialize the whole memory pool system. -+ * -+ * Parameters: -+ * osh: INPUT Operating system handle. Needed for heap memory allocation. -+ * max_pools: INPUT Maximum number of mempools supported. -+ * mgr: OUTPUT The handle is written with the new pools manager object/handle. -+ * -+ * Returns: -+ * BCME_OK Object initialized successfully. May be used. -+ * BCME_NOMEM Initialization failed due to no memory. Object must not be used. -+ */ -+int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp); -+ -+ -+/* -+ * bcm_mpm_deinit() - de-initialize the whole memory pool system. -+ * -+ * Parameters: -+ * mgr: INPUT Pointer to pool manager handle. -+ * -+ * Returns: -+ * BCME_OK Memory pool manager successfully de-initialized. -+ * other Indicated error occured during de-initialization. -+ */ -+int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp); -+ -+/* -+ * bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The -+ * pool uses a contiguous block of pre-alloced -+ * memory. The memory block may either be provided -+ * by the client or dynamically allocated by the -+ * pool manager. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pool manager -+ * obj_sz: INPUT Size of objects that will be allocated by the new pool -+ * Must be >= sizeof(void *). -+ * nobj: INPUT Maximum number of concurrently existing objects to support -+ * memstart INPUT Pointer to the memory to use, or NULL to malloc() -+ * memsize INPUT Number of bytes referenced from memstart (for error checking). -+ * Must be 0 if 'memstart' is NULL. -+ * poolname INPUT For instrumentation, the name of the pool -+ * newp: OUTPUT The handle for the new pool, if creation is successful -+ * -+ * Returns: -+ * BCME_OK Pool created ok. -+ * other Pool not created due to indicated error. newpoolp set to NULL. -+ * -+ * -+ */ -+int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr, -+ unsigned int obj_sz, -+ int nobj, -+ void *memstart, -+ unsigned int memsize, -+ char poolname[BCM_MP_NAMELEN], -+ bcm_mp_pool_h *newp); -+ -+ -+/* -+ * bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after -+ * all memory objects have been freed back to the pool. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * pool: INPUT The handle of the pool to delete -+ * -+ * Returns: -+ * BCME_OK Pool deleted ok. -+ * other Pool not deleted due to indicated error. -+ * -+ */ -+int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); -+ -+/* -+ * bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory -+ * pool allocator uses the heap (malloc/free) for memory. -+ * In this case, the pool allocator is just providing -+ * statistics and instrumentation on top of the heap, -+ * without modifying the heap allocation implementation. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pool manager -+ * obj_sz: INPUT Size of objects that will be allocated by the new pool -+ * poolname INPUT For instrumentation, the name of the pool -+ * newp: OUTPUT The handle for the new pool, if creation is successful -+ * -+ * Returns: -+ * BCME_OK Pool created ok. -+ * other Pool not created due to indicated error. newpoolp set to NULL. -+ * -+ * -+ */ -+int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz, -+ char poolname[BCM_MP_NAMELEN], -+ bcm_mp_pool_h *newp); -+ -+ -+/* -+ * bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after -+ * all memory objects have been freed back to the pool. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * pool: INPUT The handle of the pool to delete -+ * -+ * Returns: -+ * BCME_OK Pool deleted ok. -+ * other Pool not deleted due to indicated error. -+ * -+ */ -+int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); -+ -+ -+/* -+ * bcm_mpm_stats() - Return stats for all pools -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * stats: OUTPUT Array of pool statistics. -+ * nentries: MOD Max elements in 'stats' array on INPUT. Actual number -+ * of array elements copied to 'stats' on OUTPUT. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error getting stats. -+ * -+ */ -+int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries); -+ -+ -+/* -+ * bcm_mpm_dump() - Display statistics on all pools -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * b: OUTPUT Output buffer. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during dump. -+ * -+ */ -+int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b); -+ -+ -+/* -+ * bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to -+ * compensate for alignment requirements of the objects. -+ * This function provides the padded object size. If clients -+ * pre-allocate a memory slab for a memory pool, the -+ * padded object size should be used by the client to allocate -+ * the memory slab (in order to provide sufficent space for -+ * the maximum number of objects). -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager. -+ * obj_sz: INPUT Input object size. -+ * padded_obj_sz: OUTPUT Padded object size. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * BCME_BADARG Bad arguments. -+ * -+ */ -+int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz); -+ -+ -+/* -+*************************************************************************** -+* -+* API Routines on a specific pool. -+* -+*************************************************************************** -+*/ -+ -+ -+/* -+ * bcm_mp_alloc() - Allocate a memory pool object. -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool. -+ * -+ * Returns: -+ * A pointer to the new object. NULL on error. -+ * -+ */ -+void* bcm_mp_alloc(bcm_mp_pool_h pool); -+ -+/* -+ * bcm_mp_free() - Free a memory pool object. -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool. -+ * objp: INPUT A pointer to the object to free. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during free. -+ * -+ */ -+int bcm_mp_free(bcm_mp_pool_h pool, void *objp); -+ -+/* -+ * bcm_mp_stats() - Return stats for this pool -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool -+ * stats: OUTPUT Pool statistics -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error getting statistics. -+ * -+ */ -+int bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats); -+ -+ -+/* -+ * bcm_mp_dump() - Dump a pool -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool -+ * b OUTPUT Output buffer -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during dump. -+ * -+ */ -+int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b); -+ -+ -+#endif /* _BCM_MPOOL_PUB_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmcdc.h b/drivers/net/wireless/ap6210/include/bcmcdc.h -new file mode 100644 -index 0000000..a1d1271 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmcdc.h -@@ -0,0 +1,132 @@ -+/* -+ * CDC network driver ioctl/indication encoding -+ * Broadcom 802.11abg Networking Device Driver -+ * -+ * Definitions subject to change without notice. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmcdc.h 318308 2012-03-02 02:23:42Z $ -+ */ -+#ifndef _bcmcdc_h_ -+#define _bcmcdc_h_ -+#include -+ -+typedef struct cdc_ioctl { -+ uint32 cmd; /* ioctl command value */ -+ uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ -+ uint32 flags; /* flag defns given below */ -+ uint32 status; /* status code returned from the device */ -+} cdc_ioctl_t; -+ -+/* Max valid buffer size that can be sent to the dongle */ -+#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN -+ -+/* len field is divided into input and output buffer lengths */ -+#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */ -+ /* excluding IOCTL header */ -+#define CDCL_IOC_OUTLEN_SHIFT 0 -+#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */ -+#define CDCL_IOC_INLEN_SHIFT 16 -+ -+/* CDC flag definitions */ -+#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -+#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -+#define CDCF_IOC_OVL_IDX_MASK 0x3c /* overlay region index mask */ -+#define CDCF_IOC_OVL_RSV 0x40 /* 1=reserve this overlay region */ -+#define CDCF_IOC_OVL 0x80 /* 1=this ioctl corresponds to an overlay */ -+#define CDCF_IOC_ACTION_MASK 0xfe /* SET/GET, OVL_IDX, OVL_RSV, OVL mask */ -+#define CDCF_IOC_ACTION_SHIFT 1 /* SET/GET, OVL_IDX, OVL_RSV, OVL shift */ -+#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -+#define CDCF_IOC_IF_SHIFT 12 -+#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */ -+#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ -+ -+#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -+#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) -+ -+#define CDC_GET_IF_IDX(hdr) \ -+ ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -+#define CDC_SET_IF_IDX(hdr, idx) \ -+ ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) -+ -+/* -+ * BDC header -+ * -+ * The BDC header is used on data packets to convey priority across USB. -+ */ -+ -+struct bdc_header { -+ uint8 flags; /* Flags */ -+ uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 USB flow control info */ -+ uint8 flags2; -+ uint8 dataOffset; /* Offset from end of BDC header to packet data, in -+ * 4-byte words. Leaves room for optional headers. -+ */ -+}; -+ -+#define BDC_HEADER_LEN 4 -+ -+/* flags field bitmap */ -+#define BDC_FLAG_80211_PKT 0x01 /* Packet is in 802.11 format (dongle -> host) */ -+#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */ -+#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums: host->device */ -+#define BDC_FLAG_EVENT_MSG 0x08 /* Payload contains an event msg: device->host */ -+#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -+#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ -+ -+/* priority field bitmap */ -+#define BDC_PRIORITY_MASK 0x07 -+#define BDC_PRIORITY_FC_MASK 0xf0 /* flow control info mask */ -+#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ -+ -+/* flags2 field bitmap */ -+#define BDC_FLAG2_IF_MASK 0x0f /* interface index (host <-> dongle) */ -+#define BDC_FLAG2_IF_SHIFT 0 -+#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ -+ /* FLOW CONTROL info only */ -+ -+/* version numbers */ -+#define BDC_PROTO_VER_1 1 /* Old Protocol version */ -+#define BDC_PROTO_VER 2 /* Protocol version */ -+ -+/* flags2.if field access macros */ -+#define BDC_GET_IF_IDX(hdr) \ -+ ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -+#define BDC_SET_IF_IDX(hdr, idx) \ -+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) -+ -+#define BDC_FLAG2_PAD_MASK 0xf0 -+#define BDC_FLAG_PAD_MASK 0x03 -+#define BDC_FLAG2_PAD_SHIFT 2 -+#define BDC_FLAG_PAD_SHIFT 0 -+#define BDC_FLAG2_PAD_IDX 0x3c -+#define BDC_FLAG_PAD_IDX 0x03 -+#define BDC_GET_PAD_LEN(hdr) \ -+ ((int)(((((hdr)->flags2) & BDC_FLAG2_PAD_MASK) >> BDC_FLAG2_PAD_SHIFT) | \ -+ ((((hdr)->flags) & BDC_FLAG_PAD_MASK) >> BDC_FLAG_PAD_SHIFT))) -+#define BDC_SET_PAD_LEN(hdr, idx) \ -+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_PAD_MASK) | \ -+ (((idx) & BDC_FLAG2_PAD_IDX) << BDC_FLAG2_PAD_SHIFT))); \ -+ ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \ -+ (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT))) -+ -+#endif /* _bcmcdc_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmdefs.h b/drivers/net/wireless/ap6210/include/bcmdefs.h -new file mode 100644 -index 0000000..00906e3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmdefs.h -@@ -0,0 +1,270 @@ -+/* -+ * Misc system wide definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmdefs.h 316830 2012-02-23 20:29:22Z $ -+ */ -+ -+#ifndef _bcmdefs_h_ -+#define _bcmdefs_h_ -+ -+/* -+ * One doesn't need to include this file explicitly, gets included automatically if -+ * typedefs.h is included. -+ */ -+ -+/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function -+ * arguments or local variables. -+ */ -+#define BCM_REFERENCE(data) ((void)(data)) -+ -+/* Compile-time assert can be used in place of ASSERT if the expression evaluates -+ * to a constant at compile time. -+ */ -+#define STATIC_ASSERT(expr) { \ -+ /* Make sure the expression is constant. */ \ -+ typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \ -+ /* Make sure the expression is true. */ \ -+ typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \ -+} -+ -+/* Reclaiming text and data : -+ * The following macros specify special linker sections that can be reclaimed -+ * after a system is considered 'up'. -+ * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN, -+ * as in most cases, the attach function calls the detach function to clean up on error). -+ */ -+ -+#define bcmreclaimed 0 -+#define _data _data -+#define _fn _fn -+#define BCMPREATTACHDATA(_data) _data -+#define BCMPREATTACHFN(_fn) _fn -+#define _data _data -+#define _fn _fn -+#define _fn _fn -+#define BCMNMIATTACHFN(_fn) _fn -+#define BCMNMIATTACHDATA(_data) _data -+#define CONST const -+#ifndef BCMFASTPATH -+#define BCMFASTPATH -+#define BCMFASTPATH_HOST -+#endif /* BCMFASTPATH */ -+ -+ -+/* Put some library data/code into ROM to reduce RAM requirements */ -+#define _data _data -+#define BCMROMDAT_NAME(_data) _data -+#define _fn _fn -+#define _fn _fn -+#define STATIC static -+#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data) -+#define BCMROMDAT_SIZEOF(data) sizeof(data) -+#define BCMROMDAT_APATCH(data) -+#define BCMROMDAT_SPATCH(data) -+ -+/* Bus types */ -+#define SI_BUS 0 /* SOC Interconnect */ -+#define PCI_BUS 1 /* PCI target */ -+#define PCMCIA_BUS 2 /* PCMCIA target */ -+#define SDIO_BUS 3 /* SDIO target */ -+#define JTAG_BUS 4 /* JTAG */ -+#define USB_BUS 5 /* USB (does not support R/W REG) */ -+#define SPI_BUS 6 /* gSPI target */ -+#define RPC_BUS 7 /* RPC target */ -+ -+/* Allows size optimization for single-bus image */ -+#ifdef BCMBUSTYPE -+#define BUSTYPE(bus) (BCMBUSTYPE) -+#else -+#define BUSTYPE(bus) (bus) -+#endif -+ -+/* Allows size optimization for single-backplane image */ -+#ifdef BCMCHIPTYPE -+#define CHIPTYPE(bus) (BCMCHIPTYPE) -+#else -+#define CHIPTYPE(bus) (bus) -+#endif -+ -+ -+/* Allows size optimization for SPROM support */ -+#if defined(BCMSPROMBUS) -+#define SPROMBUS (BCMSPROMBUS) -+#elif defined(SI_PCMCIA_SROM) -+#define SPROMBUS (PCMCIA_BUS) -+#else -+#define SPROMBUS (PCI_BUS) -+#endif -+ -+/* Allows size optimization for single-chip image */ -+#ifdef BCMCHIPID -+#define CHIPID(chip) (BCMCHIPID) -+#else -+#define CHIPID(chip) (chip) -+#endif -+ -+#ifdef BCMCHIPREV -+#define CHIPREV(rev) (BCMCHIPREV) -+#else -+#define CHIPREV(rev) (rev) -+#endif -+ -+/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ -+#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ -+#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ -+#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ -+ -+#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ -+#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ -+#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ -+#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ -+ -+#ifdef BCMDMA64OSL -+typedef struct { -+ uint32 loaddr; -+ uint32 hiaddr; -+} dma64addr_t; -+ -+typedef dma64addr_t dmaaddr_t; -+#define PHYSADDRHI(_pa) ((_pa).hiaddr) -+#define PHYSADDRHISET(_pa, _val) \ -+ do { \ -+ (_pa).hiaddr = (_val); \ -+ } while (0) -+#define PHYSADDRLO(_pa) ((_pa).loaddr) -+#define PHYSADDRLOSET(_pa, _val) \ -+ do { \ -+ (_pa).loaddr = (_val); \ -+ } while (0) -+ -+#else -+typedef unsigned long dmaaddr_t; -+#define PHYSADDRHI(_pa) (0) -+#define PHYSADDRHISET(_pa, _val) -+#define PHYSADDRLO(_pa) ((_pa)) -+#define PHYSADDRLOSET(_pa, _val) \ -+ do { \ -+ (_pa) = (_val); \ -+ } while (0) -+#endif /* BCMDMA64OSL */ -+ -+/* One physical DMA segment */ -+typedef struct { -+ dmaaddr_t addr; -+ uint32 length; -+} hnddma_seg_t; -+ -+#define MAX_DMA_SEGS 4 -+ -+ -+typedef struct { -+ void *oshdmah; /* Opaque handle for OSL to store its information */ -+ uint origsize; /* Size of the virtual packet */ -+ uint nsegs; -+ hnddma_seg_t segs[MAX_DMA_SEGS]; -+} hnddma_seg_map_t; -+ -+ -+/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). -+ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. -+ * There is a compile time check in wlc.c which ensure that this value is at least as big -+ * as TXOFF. This value is used in dma_rxfill (hnddma.c). -+ */ -+ -+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) -+/* add 40 bytes to allow for extra RPC header and info */ -+#define BCMEXTRAHDROOM 220 -+#else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ -+#define BCMEXTRAHDROOM 172 -+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ -+ -+/* Packet alignment for most efficient SDIO (can change based on platform) */ -+#ifndef SDALIGN -+#define SDALIGN 32 -+#endif -+ -+/* Headroom required for dongle-to-host communication. Packets allocated -+ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should -+ * leave this much room in front for low-level message headers which may -+ * be needed to get across the dongle bus to the host. (These messages -+ * don't go over the network, so room for the full WL header above would -+ * be a waste.). -+*/ -+#define BCMDONGLEHDRSZ 12 -+#define BCMDONGLEPADSZ 16 -+ -+#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) -+ -+ -+#if defined(NO_BCMDBG_ASSERT) -+# undef BCMDBG_ASSERT -+# undef BCMASSERT_LOG -+#endif -+ -+#if defined(BCMASSERT_LOG) -+#define BCMASSERT_SUPPORT -+#endif -+ -+/* Macros for doing definition and get/set of bitfields -+ * Usage example, e.g. a three-bit field (bits 4-6): -+ * #define _M BITFIELD_MASK(3) -+ * #define _S 4 -+ * ... -+ * regval = R_REG(osh, ®s->regfoo); -+ * field = GFIELD(regval, ); -+ * regval = SFIELD(regval, , 1); -+ * W_REG(osh, ®s->regfoo, regval); -+ */ -+#define BITFIELD_MASK(width) \ -+ (((unsigned)1 << (width)) - 1) -+#define GFIELD(val, field) \ -+ (((val) >> field ## _S) & field ## _M) -+#define SFIELD(val, field, bits) \ -+ (((val) & (~(field ## _M << field ## _S))) | \ -+ ((unsigned)(bits) << field ## _S)) -+ -+/* define BCMSMALL to remove misc features for memory-constrained environments */ -+#ifdef BCMSMALL -+#undef BCMSPACE -+#define bcmspace FALSE /* if (bcmspace) code is discarded */ -+#else -+#define BCMSPACE -+#define bcmspace TRUE /* if (bcmspace) code is retained */ -+#endif -+ -+/* Max. nvram variable table size */ -+#define MAXSZ_NVRAM_VARS 4096 -+ -+ -+/* Max size for reclaimable NVRAM array */ -+#ifdef DL_NVRAM -+#define NVRAM_ARRAY_MAXSIZE DL_NVRAM -+#else -+#define NVRAM_ARRAY_MAXSIZE MAXSZ_NVRAM_VARS -+#endif /* DL_NVRAM */ -+ -+#ifdef BCMUSBDEV_ENABLED -+extern uint32 gFWID; -+#endif -+ -+#endif /* _bcmdefs_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmdevs.h b/drivers/net/wireless/ap6210/include/bcmdevs.h -new file mode 100644 -index 0000000..c3dd89f ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmdevs.h -@@ -0,0 +1,503 @@ -+/* -+ * Broadcom device-specific manifest constants. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmdevs.h 329854 2012-04-27 01:42:28Z $ -+ */ -+ -+#ifndef _BCMDEVS_H -+#define _BCMDEVS_H -+ -+/* PCI vendor IDs */ -+#define VENDOR_EPIGRAM 0xfeda -+#define VENDOR_BROADCOM 0x14e4 -+#define VENDOR_3COM 0x10b7 -+#define VENDOR_NETGEAR 0x1385 -+#define VENDOR_DIAMOND 0x1092 -+#define VENDOR_INTEL 0x8086 -+#define VENDOR_DELL 0x1028 -+#define VENDOR_HP 0x103c -+#define VENDOR_HP_COMPAQ 0x0e11 -+#define VENDOR_APPLE 0x106b -+#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */ -+#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */ -+#define VENDOR_TI 0x104c /* Texas Instruments */ -+#define VENDOR_RICOH 0x1180 /* Ricoh */ -+#define VENDOR_JMICRON 0x197b -+ -+ -+/* PCMCIA vendor IDs */ -+#define VENDOR_BROADCOM_PCMCIA 0x02d0 -+ -+/* SDIO vendor IDs */ -+#define VENDOR_BROADCOM_SDIO 0x00BF -+ -+/* DONGLE VID/PIDs */ -+#define BCM_DNGL_VID 0x0a5c -+#define BCM_DNGL_BL_PID_4328 0xbd12 -+#define BCM_DNGL_BL_PID_4322 0xbd13 -+#define BCM_DNGL_BL_PID_4319 0xbd16 -+#define BCM_DNGL_BL_PID_43236 0xbd17 -+#define BCM_DNGL_BL_PID_4332 0xbd18 -+#define BCM_DNGL_BL_PID_4330 0xbd19 -+#define BCM_DNGL_BL_PID_4334 0xbd1a -+#define BCM_DNGL_BL_PID_43239 0xbd1b -+#define BCM_DNGL_BL_PID_4324 0xbd1c -+#define BCM_DNGL_BL_PID_4360 0xbd1d -+ -+#define BCM_DNGL_BDC_PID 0x0bdc -+#define BCM_DNGL_JTAG_PID 0x4a44 -+ -+/* HW USB BLOCK [CPULESS USB] PIDs */ -+#define BCM_HWUSB_PID_43239 43239 -+ -+/* PCI Device IDs */ -+#define BCM4210_DEVICE_ID 0x1072 /* never used */ -+#define BCM4230_DEVICE_ID 0x1086 /* never used */ -+#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ -+#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ -+#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ -+#define BCM4211_DEVICE_ID 0x4211 -+#define BCM4231_DEVICE_ID 0x4231 -+#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ -+#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ -+#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ -+#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ -+#define BCM4328_D11DUAL_ID 0x4314 /* 4328/4312 802.11a/g id */ -+#define BCM4328_D11G_ID 0x4315 /* 4328/4312 802.11g id */ -+#define BCM4328_D11A_ID 0x4316 /* 4328/4312 802.11a id */ -+#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ -+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ -+#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ -+#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */ -+#define BCM4325_D11G_ID 0x431c /* 4325 802.11g id */ -+#define BCM4325_D11A_ID 0x431d /* 4325 802.11a id */ -+#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ -+#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ -+#define BCM4306_UART_ID 0x4322 /* 4306 uart */ -+#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ -+#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ -+#define BCM4306_D11G_ID2 0x4325 /* BCM4306_D11G_ID; INF w/loose binding war */ -+#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ -+#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */ -+#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ -+#define BCM4322_D11N_ID 0x432b /* 4322 802.11n dualband device */ -+#define BCM4322_D11N2G_ID 0x432c /* 4322 802.11n 2.4GHz device */ -+#define BCM4322_D11N5G_ID 0x432d /* 4322 802.11n 5GHz device */ -+#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */ -+#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ -+#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ -+#define BCM4315_D11DUAL_ID 0x4334 /* 4315 802.11a/g id */ -+#define BCM4315_D11G_ID 0x4335 /* 4315 802.11g id */ -+#define BCM4315_D11A_ID 0x4336 /* 4315 802.11a id */ -+#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */ -+#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */ -+#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ -+#define BCM43231_D11N2G_ID 0x4340 /* 43231 802.11n 2.4GHz device */ -+#define BCM43221_D11N2G_ID 0x4341 /* 43221 802.11n 2.4GHz device */ -+#define BCM43222_D11N_ID 0x4350 /* 43222 802.11n dualband device */ -+#define BCM43222_D11N2G_ID 0x4351 /* 43222 802.11n 2.4GHz device */ -+#define BCM43222_D11N5G_ID 0x4352 /* 43222 802.11n 5GHz device */ -+#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ -+#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db device */ -+#define BCM43226_D11N_ID 0x4354 /* 43226 802.11n dualband device */ -+#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ -+#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ -+#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */ -+#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ -+#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */ -+#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ -+#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */ -+#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */ -+#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ -+#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ -+#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ -+#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ -+#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ -+#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ -+#define BCM43237_D11N_ID 0x4355 /* 43237 802.11n dualband device */ -+#define BCM43237_D11N5G_ID 0x4356 /* 43237 802.11n 5GHz device */ -+#define BCM43227_D11N2G_ID 0x4358 /* 43228 802.11n 2.4GHz device */ -+#define BCM43228_D11N_ID 0x4359 /* 43228 802.11n DualBand device */ -+#define BCM43228_D11N5G_ID 0x435a /* 43228 802.11n 5GHz device */ -+#define BCM43362_D11N_ID 0x4363 /* 43362 802.11n 2.4GHz device */ -+#define BCM43239_D11N_ID 0x4370 /* 43239 802.11n dualband device */ -+#define BCM4324_D11N_ID 0x4374 /* 4324 802.11n dualband device */ -+#define BCM43217_D11N2G_ID 0x43a9 /* 43217 802.11n 2.4GHz device */ -+#define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */ -+#define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */ -+#define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */ -+#define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */ -+#define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */ -+#define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */ -+#define BCM43341_D11N_ID 0x4386 /* 43341 802.11n dualband device */ -+#define BCM43341_D11N2G_ID 0x4387 /* 43341 802.11n 2.4G device */ -+#define BCM43341_D11N5G_ID 0x4388 /* 43341 802.11n 5G device */ -+#define BCM4360_D11AC_ID 0x43a0 -+#define BCM4360_D11AC2G_ID 0x43a1 -+#define BCM4360_D11AC5G_ID 0x43a2 -+ -+/* PCI Subsystem ID */ -+#define BCM943228HMB_SSID_VEN1 0x0607 -+#define BCM94313HMGBL_SSID_VEN1 0x0608 -+#define BCM94313HMG_SSID_VEN1 0x0609 -+ -+ -+#define BCM4335_D11AC_ID 0x43ae -+#define BCM4335_D11AC2G_ID 0x43af -+#define BCM4335_D11AC5G_ID 0x43b0 -+#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */ -+#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */ -+#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */ -+ -+#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ -+#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ -+#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ -+#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */ -+#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ -+#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */ -+#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ -+#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */ -+#define BCM_SPIH_ID 0x43f6 /* Synopsis SPI Host Controller */ -+#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ -+#define BCM_JTAGM2_ID 0x43f9 /* BCM alternate jtagm device id */ -+#define SDHCI_FPGA_ID 0x43fa /* Standard SDIO Host Controller FPGA */ -+#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ -+#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ -+#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ -+#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ -+#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ -+#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ -+#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ -+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ -+#define BCM47XX_AUDIO_ID 0x4711 /* 47xx audio codec */ -+#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ -+#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ -+#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ -+#define BCM47XX_GMAC_ID 0x4715 /* 47xx Unimac based GbE */ -+#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ -+#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ -+#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ -+#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ -+#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ -+#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ -+#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ -+#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ -+#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ -+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ -+#define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */ -+#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ -+#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ -+#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ -+#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ -+#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */ -+#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */ -+#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */ -+#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */ -+#define R5C822_SDIOH_ID 0x0822 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host */ -+#define JMICRON_SDIOH_ID 0x2381 /* JMicron Standard SDIO Host Controller */ -+ -+/* Chip IDs */ -+#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ -+#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ -+#define BCM43111_CHIP_ID 43111 /* 43111 chipcommon chipid (OTP chipid) */ -+#define BCM43112_CHIP_ID 43112 /* 43112 chipcommon chipid (OTP chipid) */ -+#define BCM4312_CHIP_ID 0x4312 /* 4312 chipcommon chipid */ -+#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ -+#define BCM43131_CHIP_ID 43131 /* 43131 chip id (OTP chipid) */ -+#define BCM4315_CHIP_ID 0x4315 /* 4315 chip id */ -+#define BCM4318_CHIP_ID 0x4318 /* 4318 chipcommon chipid */ -+#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ -+#define BCM4320_CHIP_ID 0x4320 /* 4320 chipcommon chipid */ -+#define BCM4321_CHIP_ID 0x4321 /* 4321 chipcommon chipid */ -+#define BCM43217_CHIP_ID 43217 /* 43217 chip id (OTP chipid) */ -+#define BCM4322_CHIP_ID 0x4322 /* 4322 chipcommon chipid */ -+#define BCM43221_CHIP_ID 43221 /* 43221 chipcommon chipid (OTP chipid) */ -+#define BCM43222_CHIP_ID 43222 /* 43222 chipcommon chipid */ -+#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ -+#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ -+#define BCM43227_CHIP_ID 43227 /* 43227 chipcommon chipid */ -+#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */ -+#define BCM43226_CHIP_ID 43226 /* 43226 chipcommon chipid */ -+#define BCM43231_CHIP_ID 43231 /* 43231 chipcommon chipid (OTP chipid) */ -+#define BCM43234_CHIP_ID 43234 /* 43234 chipcommon chipid */ -+#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ -+#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ -+#define BCM43237_CHIP_ID 43237 /* 43237 chipcommon chipid */ -+#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */ -+#define BCM43239_CHIP_ID 43239 /* 43239 chipcommon chipid */ -+#define BCM43420_CHIP_ID 43420 /* 43222 chipcommon chipid (OTP, RBBU) */ -+#define BCM43421_CHIP_ID 43421 /* 43224 chipcommon chipid (OTP, RBBU) */ -+#define BCM43428_CHIP_ID 43428 /* 43228 chipcommon chipid (OTP, RBBU) */ -+#define BCM43431_CHIP_ID 43431 /* 4331 chipcommon chipid (OTP, RBBU) */ -+#define BCM43460_CHIP_ID 43460 /* 4360 chipcommon chipid (OTP, RBBU) */ -+#define BCM4325_CHIP_ID 0x4325 /* 4325 chip id */ -+#define BCM4328_CHIP_ID 0x4328 /* 4328 chip id */ -+#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */ -+#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */ -+#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */ -+#define BCM43362_CHIP_ID 43362 /* 43362 chipcommon chipid */ -+#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */ -+#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ -+#define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */ -+#define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */ -+#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */ -+#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */ -+#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */ -+#define BCM4360_CHIP_ID 0x4360 /* 4360 chipcommon chipid */ -+#define BCM4352_CHIP_ID 0x4352 /* 4352 chipcommon chipid */ -+#define BCM43526_CHIP_ID 0xAA06 -+#define BCM43341_CHIP_ID 43341 /* 43341 chipcommon chipid */ -+#define BCM43342_CHIP_ID 43342 /* 43342 chipcommon chipid */ -+ -+#define BCM4335_CHIP_ID 0x4335 -+ -+#define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */ -+#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ -+#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ -+#define BCM4706_CHIP_ID 0x5300 /* 4706 chipcommon chipid */ -+#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */ -+#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ -+#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ -+#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ -+#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ -+#define BCM4749_CHIP_ID 0x4749 /* 5357 chipcommon chipid (OTP, RBBU) */ -+#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ -+#define BCM5350_CHIP_ID 0x5350 /* 5350 chipcommon chipid */ -+#define BCM5352_CHIP_ID 0x5352 /* 5352 chipcommon chipid */ -+#define BCM5354_CHIP_ID 0x5354 /* 5354 chipcommon chipid */ -+#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ -+#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ -+#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ -+#define BCM53572_CHIP_ID 53572 /* 53572 chipcommon chipid */ -+ -+/* Package IDs */ -+#define BCM4303_PKG_ID 2 /* 4303 package id */ -+#define BCM4309_PKG_ID 1 /* 4309 package id */ -+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ -+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ -+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ -+#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */ -+#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */ -+#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */ -+#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */ -+#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ -+#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ -+#define BCM5354E_PKG_ID 1 /* 5354E package id */ -+#define BCM4716_PKG_ID 8 /* 4716 package id */ -+#define BCM4717_PKG_ID 9 /* 4717 package id */ -+#define BCM4718_PKG_ID 10 /* 4718 package id */ -+#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */ -+#define BCM5358U_PKG_ID 8 /* 5358U package id */ -+#define BCM5358_PKG_ID 9 /* 5358 package id */ -+#define BCM47186_PKG_ID 10 /* 47186 package id */ -+#define BCM5357_PKG_ID 11 /* 5357 package id */ -+#define BCM5356U_PKG_ID 12 /* 5356U package id */ -+#define BCM53572_PKG_ID 8 /* 53572 package id */ -+#define BCM5357C0_PKG_ID 8 /* 5357c0 package id (the same as 53572) */ -+#define BCM47188_PKG_ID 9 /* 47188 package id */ -+#define BCM5358C0_PKG_ID 0xa /* 5358c0 package id */ -+#define BCM5356C0_PKG_ID 0xb /* 5356c0 package id */ -+#define BCM4331TT_PKG_ID 8 /* 4331 12x12 package id */ -+#define BCM4331TN_PKG_ID 9 /* 4331 12x9 package id */ -+#define BCM4331TNA0_PKG_ID 0xb /* 4331 12x9 package id */ -+#define BCM4706L_PKG_ID 1 /* 4706L package id */ -+ -+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ -+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ -+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ -+#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */ -+#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ -+#define BCM4336_WLBGA_PKG_ID 0x8 -+#define BCM4330_WLBGA_PKG_ID 0x0 -+#define BCM4314PCIE_ARM_PKG_ID (8 | 0) /* 4314 QFN PCI package id, bit 3 tie high */ -+#define BCM4314SDIO_PKG_ID (8 | 1) /* 4314 QFN SDIO package id */ -+#define BCM4314PCIE_PKG_ID (8 | 2) /* 4314 QFN PCI (ARM-less) package id */ -+#define BCM4314SDIO_ARM_PKG_ID (8 | 3) /* 4314 QFN SDIO (ARM-less) package id */ -+#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) /* 4314 FpBGA SDIO package id */ -+#define BCM4314DEV_PKG_ID (8 | 6) /* 4314 Developement package id */ -+ -+#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */ -+#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */ -+ -+/* boardflags */ -+#define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */ -+#define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */ -+#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -+#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication, UNUSED */ -+#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ -+#define BFL_RFPLL 0x00000008 /* ACPHY: Changing RFPLL BW to be 150 MHz */ -+#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ -+#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -+#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ -+#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ -+#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ -+#define BFL_UNUSED 0x00000200 -+#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ -+#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ -+#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -+#define BFL_HGPA 0x00002000 /* Board has a high gain PA */ -+#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */ -+#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ -+#define BFL_NOPA 0x00010000 /* Board has no PA */ -+#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ -+#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */ -+#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */ -+#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ -+#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ -+#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ -+#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -+#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ -+#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -+#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ -+#define BFL_FASTPWR 0x08000000 -+#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ -+#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -+#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ -+#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ -+#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field -+ * when this flag is set -+ */ -+#define BFL_EXTLNA_TX 0x20000000 /* Temp boardflag to indicate to */ -+ -+/* boardflags2 */ -+#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ -+#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ -+#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ -+#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ -+#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ -+#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ -+#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */ -+#define BFL2_BTC3WIRE 0x00000080 /* Board support legacy 3 wire or 4 wire */ -+#define BFL2_BTCLEGACY 0x00000080 /* Board support legacy 3/4 wire, to replace -+ * BFL2_BTC3WIRE -+ */ -+#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ -+#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ -+#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -+#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */ -+#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ -+#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -+#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */ -+#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* Activates WAR to improve FCC bandedge performance */ -+#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ -+#define BFL2_IPALVLSHIFT_3P3 0x00020000 -+#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ -+#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio on */ -+ /* Most drivers will turn it off without this flag */ -+ /* to save power. */ -+ -+#define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */ -+#define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */ -+#define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */ -+#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */ -+#define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value -+ * than programmed. The exact delta is decided by -+ * driver per chip/boardtype. This can be used -+ * when tempsense qualification happens after shipment -+ */ -+#define BFL2_BTC3WIREONLY 0x02000000 /* standard 3 wire btc only. 4 wire not supported */ -+#define BFL2_PWR_NOMINAL 0x04000000 /* 0: power reduction on, 1: no power reduction */ -+#define BFL2_EXTLNA_PWRSAVE 0x08000000 /* boardflag to enable ucode to apply power save */ -+ /* ucode control of eLNA during Tx */ -+#define BFL2_4313_RADIOREG 0x10000000 -+ /* board rework */ -+#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */ -+ -+/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -+#define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */ -+#define BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */ -+#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */ -+#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */ -+#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */ -+#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */ -+#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ -+#define BOARD_GPIO_12 0x1000 /* gpio 12 */ -+#define BOARD_GPIO_13 0x2000 /* gpio 13 */ -+#define BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */ -+#define BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */ -+#define BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */ -+#define BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */ -+#define BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */ -+#define BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */ -+#define BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */ -+ -+#define GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43224 0x020 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43225 0x0e0 /* bit 5 BT_IODISABLE, bit 6 SW_BT, bit 7 SW_WL */ -+#define GPIO_BTC4W_OUT_43421 0x020 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_4313 0x060 /* bit 5 SW_BT, bit 6 SW_WL */ -+#define GPIO_BTC4W_OUT_4331_SHARED 0x010 /* GPIO 4 */ -+ -+#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -+#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ -+#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ -+#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ -+ -+/* power control defines */ -+#define PLL_DELAY 150 /* us pll on delay */ -+#define FREF_DELAY 200 /* us fref change delay */ -+#define MIN_SLOW_CLK 32 /* us Slow clock period */ -+#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ -+ -+ -+/* 43341 Boards */ -+#define BCM943341WLABGS_SSID 0x062d -+ -+/* # of GPIO pins */ -+#define GPIO_NUMPINS 32 -+ -+/* These values are used by dhd host driver. */ -+#define RDL_RAM_BASE_4319 0x60000000 -+#define RDL_RAM_BASE_4329 0x60000000 -+#define RDL_RAM_SIZE_4319 0x48000 -+#define RDL_RAM_SIZE_4329 0x48000 -+#define RDL_RAM_SIZE_43236 0x70000 -+#define RDL_RAM_BASE_43236 0x60000000 -+#define RDL_RAM_SIZE_4328 0x60000 -+#define RDL_RAM_BASE_4328 0x80000000 -+#define RDL_RAM_SIZE_4322 0x60000 -+#define RDL_RAM_BASE_4322 0x60000000 -+ -+/* generic defs for nvram "muxenab" bits */ -+#define MUXENAB_UART 0x00000001 -+#define MUXENAB_GPIO 0x00000002 -+#define MUXENAB_ERCX 0x00000004 /* External Radio BT coex */ -+#define MUXENAB_JTAG 0x00000008 -+#define MUXENAB_HOST_WAKE 0x00000010 /* configure GPIO for SDIO host_wake */ -+#define MUXENAB_I2S_EN 0x00000020 -+#define MUXENAB_I2S_MASTER 0x00000040 -+#define MUXENAB_I2S_FULL 0x00000080 -+#define MUXENAB_SFLASH 0x00000100 -+#define MUXENAB_RFSWCTRL0 0x00000200 -+#define MUXENAB_RFSWCTRL1 0x00000400 -+#define MUXENAB_RFSWCTRL2 0x00000800 -+#define MUXENAB_SECI 0x00001000 -+#define MUXENAB_BT_LEGACY 0x00002000 -+#define MUXENAB_HOST_WAKE1 0x00004000 /* configure alternative GPIO for SDIO host_wake */ -+ -+/* Boot flags */ -+#define FLASH_KERNEL_NFLASH 0x00000001 -+#define FLASH_BOOT_NFLASH 0x00000002 -+ -+#endif /* _BCMDEVS_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmendian.h b/drivers/net/wireless/ap6210/include/bcmendian.h -new file mode 100644 -index 0000000..0cf9145 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmendian.h -@@ -0,0 +1,299 @@ -+/* -+ * Byte order utilities -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmendian.h 241182 2011-02-17 21:50:03Z $ -+ * -+ * This file by default provides proper behavior on little-endian architectures. -+ * On big-endian architectures, IL_BIGENDIAN should be defined. -+ */ -+ -+#ifndef _BCMENDIAN_H_ -+#define _BCMENDIAN_H_ -+ -+#include -+ -+/* Reverse the bytes in a 16-bit value */ -+#define BCMSWAP16(val) \ -+ ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ -+ (((uint16)(val) & (uint16)0xff00U) >> 8))) -+ -+/* Reverse the bytes in a 32-bit value */ -+#define BCMSWAP32(val) \ -+ ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ -+ (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ -+ (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ -+ (((uint32)(val) & (uint32)0xff000000U) >> 24))) -+ -+/* Reverse the two 16-bit halves of a 32-bit value */ -+#define BCMSWAP32BY16(val) \ -+ ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ -+ (((uint32)(val) & (uint32)0xffff0000U) >> 16))) -+ -+/* Byte swapping macros -+ * Host <=> Network (Big Endian) for 16- and 32-bit values -+ * Host <=> Little-Endian for 16- and 32-bit values -+ */ -+#ifndef hton16 -+#define HTON16(i) BCMSWAP16(i) -+#define hton16(i) bcmswap16(i) -+#define HTON32(i) BCMSWAP32(i) -+#define hton32(i) bcmswap32(i) -+#define NTOH16(i) BCMSWAP16(i) -+#define ntoh16(i) bcmswap16(i) -+#define NTOH32(i) BCMSWAP32(i) -+#define ntoh32(i) bcmswap32(i) -+#define LTOH16(i) (i) -+#define ltoh16(i) (i) -+#define LTOH32(i) (i) -+#define ltoh32(i) (i) -+#define HTOL16(i) (i) -+#define htol16(i) (i) -+#define HTOL32(i) (i) -+#define htol32(i) (i) -+#endif /* hton16 */ -+ -+#define ltoh16_buf(buf, i) -+#define htol16_buf(buf, i) -+ -+/* Unaligned loads and stores in host byte order */ -+#define load32_ua(a) ltoh32_ua(a) -+#define store32_ua(a, v) htol32_ua_store(v, a) -+#define load16_ua(a) ltoh16_ua(a) -+#define store16_ua(a, v) htol16_ua_store(v, a) -+ -+#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -+#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -+#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -+#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) -+ -+#define ltoh_ua(ptr) \ -+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \ -+ sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \ -+ *(uint8 *)0) -+ -+#define ntoh_ua(ptr) \ -+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \ -+ sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \ -+ *(uint8 *)0) -+ -+#ifdef __GNUC__ -+ -+/* GNU macro versions avoid referencing the argument multiple times, while also -+ * avoiding the -fno-inline used in ROM builds. -+ */ -+ -+#define bcmswap16(val) ({ \ -+ uint16 _val = (val); \ -+ BCMSWAP16(_val); \ -+}) -+ -+#define bcmswap32(val) ({ \ -+ uint32 _val = (val); \ -+ BCMSWAP32(_val); \ -+}) -+ -+#define bcmswap32by16(val) ({ \ -+ uint32 _val = (val); \ -+ BCMSWAP32BY16(_val); \ -+}) -+ -+#define bcmswap16_buf(buf, len) ({ \ -+ uint16 *_buf = (uint16 *)(buf); \ -+ uint _wds = (len) / 2; \ -+ while (_wds--) { \ -+ *_buf = bcmswap16(*_buf); \ -+ _buf++; \ -+ } \ -+}) -+ -+#define htol16_ua_store(val, bytes) ({ \ -+ uint16 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val & 0xff; \ -+ _bytes[1] = _val >> 8; \ -+}) -+ -+#define htol32_ua_store(val, bytes) ({ \ -+ uint32 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val & 0xff; \ -+ _bytes[1] = (_val >> 8) & 0xff; \ -+ _bytes[2] = (_val >> 16) & 0xff; \ -+ _bytes[3] = _val >> 24; \ -+}) -+ -+#define hton16_ua_store(val, bytes) ({ \ -+ uint16 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val >> 8; \ -+ _bytes[1] = _val & 0xff; \ -+}) -+ -+#define hton32_ua_store(val, bytes) ({ \ -+ uint32 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val >> 24; \ -+ _bytes[1] = (_val >> 16) & 0xff; \ -+ _bytes[2] = (_val >> 8) & 0xff; \ -+ _bytes[3] = _val & 0xff; \ -+}) -+ -+#define ltoh16_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _LTOH16_UA(_bytes); \ -+}) -+ -+#define ltoh32_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _LTOH32_UA(_bytes); \ -+}) -+ -+#define ntoh16_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _NTOH16_UA(_bytes); \ -+}) -+ -+#define ntoh32_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _NTOH32_UA(_bytes); \ -+}) -+ -+#else /* !__GNUC__ */ -+ -+/* Inline versions avoid referencing the argument multiple times */ -+static INLINE uint16 -+bcmswap16(uint16 val) -+{ -+ return BCMSWAP16(val); -+} -+ -+static INLINE uint32 -+bcmswap32(uint32 val) -+{ -+ return BCMSWAP32(val); -+} -+ -+static INLINE uint32 -+bcmswap32by16(uint32 val) -+{ -+ return BCMSWAP32BY16(val); -+} -+ -+/* Reverse pairs of bytes in a buffer (not for high-performance use) */ -+/* buf - start of buffer of shorts to swap */ -+/* len - byte length of buffer */ -+static INLINE void -+bcmswap16_buf(uint16 *buf, uint len) -+{ -+ len = len / 2; -+ -+ while (len--) { -+ *buf = bcmswap16(*buf); -+ buf++; -+ } -+} -+ -+/* -+ * Store 16-bit value to unaligned little-endian byte array. -+ */ -+static INLINE void -+htol16_ua_store(uint16 val, uint8 *bytes) -+{ -+ bytes[0] = val & 0xff; -+ bytes[1] = val >> 8; -+} -+ -+/* -+ * Store 32-bit value to unaligned little-endian byte array. -+ */ -+static INLINE void -+htol32_ua_store(uint32 val, uint8 *bytes) -+{ -+ bytes[0] = val & 0xff; -+ bytes[1] = (val >> 8) & 0xff; -+ bytes[2] = (val >> 16) & 0xff; -+ bytes[3] = val >> 24; -+} -+ -+/* -+ * Store 16-bit value to unaligned network-(big-)endian byte array. -+ */ -+static INLINE void -+hton16_ua_store(uint16 val, uint8 *bytes) -+{ -+ bytes[0] = val >> 8; -+ bytes[1] = val & 0xff; -+} -+ -+/* -+ * Store 32-bit value to unaligned network-(big-)endian byte array. -+ */ -+static INLINE void -+hton32_ua_store(uint32 val, uint8 *bytes) -+{ -+ bytes[0] = val >> 24; -+ bytes[1] = (val >> 16) & 0xff; -+ bytes[2] = (val >> 8) & 0xff; -+ bytes[3] = val & 0xff; -+} -+ -+/* -+ * Load 16-bit value from unaligned little-endian byte array. -+ */ -+static INLINE uint16 -+ltoh16_ua(const void *bytes) -+{ -+ return _LTOH16_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 32-bit value from unaligned little-endian byte array. -+ */ -+static INLINE uint32 -+ltoh32_ua(const void *bytes) -+{ -+ return _LTOH32_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 16-bit value from unaligned big-(network-)endian byte array. -+ */ -+static INLINE uint16 -+ntoh16_ua(const void *bytes) -+{ -+ return _NTOH16_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 32-bit value from unaligned big-(network-)endian byte array. -+ */ -+static INLINE uint32 -+ntoh32_ua(const void *bytes) -+{ -+ return _NTOH32_UA((const uint8 *)bytes); -+} -+ -+#endif /* !__GNUC__ */ -+#endif /* !_BCMENDIAN_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmpcispi.h b/drivers/net/wireless/ap6210/include/bcmpcispi.h -new file mode 100644 -index 0000000..44b263c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmpcispi.h -@@ -0,0 +1,181 @@ -+/* -+ * Broadcom PCI-SPI Host Controller Register Definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmpcispi.h 241182 2011-02-17 21:50:03Z $ -+ */ -+#ifndef _BCM_PCI_SPI_H -+#define _BCM_PCI_SPI_H -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+ -+typedef volatile struct { -+ uint32 spih_ctrl; /* 0x00 SPI Control Register */ -+ uint32 spih_stat; /* 0x04 SPI Status Register */ -+ uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */ -+ uint32 spih_ext; /* 0x0C SPI Extension Register */ -+ uint32 PAD[4]; /* 0x10-0x1F PADDING */ -+ -+ uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */ -+ uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */ -+ uint32 PAD[6]; /* 0x28-0x3F PADDING */ -+ -+ uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */ -+ uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */ -+ /* 1=Active High) */ -+ uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */ -+ uint32 spih_int_status; /* 0x4C SPI Interrupt Status */ -+ uint32 PAD[4]; /* 0x50-0x5F PADDING */ -+ -+ uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */ -+ uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */ -+ uint32 PAD[1]; /* 0x68 PADDING */ -+ uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */ -+ uint32 PAD[4]; /* 0x70-0x7F PADDING */ -+ uint32 PAD[8]; /* 0x80-0x9F PADDING */ -+ uint32 PAD[8]; /* 0xA0-0xBF PADDING */ -+ uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */ -+ uint32 spih_pll_status; /* 0xC4 PLL Status Register */ -+ uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */ -+ uint32 spih_clk_count; /* 0xCC External Clock Count Register */ -+ -+} spih_regs_t; -+ -+typedef volatile struct { -+ uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */ -+ uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */ -+ -+ uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */ -+ uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */ -+ uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */ -+ uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */ -+ uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */ -+ uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */ -+ uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */ -+ uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */ -+ uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */ -+ uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */ -+ uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */ -+ uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */ -+ uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */ -+ uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */ -+ uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */ -+ uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */ -+ uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */ -+ uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */ -+ uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */ -+ uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */ -+ uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */ -+ uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */ -+ uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */ -+ uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */ -+ uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */ -+ uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */ -+ -+ uint32 PAD[5]; /* 0x16C-0x17F PADDING */ -+ -+ uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */ -+ uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */ -+ uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */ -+ uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */ -+ uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */ -+ uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */ -+ uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */ -+ uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */ -+ uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */ -+ uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */ -+ uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */ -+ uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */ -+ uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */ -+ uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */ -+ uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */ -+ uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */ -+ uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */ -+ uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */ -+ uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */ -+ uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */ -+ uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */ -+ uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */ -+ uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */ -+ uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */ -+ uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */ -+ uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */ -+ -+ uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */ -+ uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */ -+ uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */ -+} spih_pciregs_t; -+ -+/* -+ * PCI Core interrupt enable and status bit definitions. -+ */ -+ -+/* PCI Core ICR Register bit definitions */ -+#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */ -+#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */ -+#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */ -+#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */ -+#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */ -+#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */ -+ -+ -+/* PCI Core ISR Register bit definitions */ -+#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */ -+#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */ -+#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */ -+#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */ -+#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */ -+ -+ -+/* Registers on the Wishbone bus */ -+#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */ -+#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */ -+#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */ -+ -+/* GPIO Bit definitions */ -+#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */ -+#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */ -+#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */ -+ -+/* SPI Status Register Bit definitions */ -+#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */ -+#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */ -+#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */ -+#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */ -+#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */ -+#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */ -+ -+#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */ -+ -+#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */ -+#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */ -+ -+/* Spin bit loop bound check */ -+#define SPI_SPIN_BOUND 0xf4240 /* 1 million */ -+ -+#endif /* _BCM_PCI_SPI_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmperf.h b/drivers/net/wireless/ap6210/include/bcmperf.h -new file mode 100644 -index 0000000..7438307 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmperf.h -@@ -0,0 +1,36 @@ -+/* -+ * Performance counters software interface. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $ -+ */ -+/* essai */ -+#ifndef _BCMPERF_H_ -+#define _BCMPERF_H_ -+/* get cache hits and misses */ -+#define BCMPERF_ENABLE_INSTRCOUNT() -+#define BCMPERF_ENABLE_ICACHE_MISS() -+#define BCMPERF_ENABLE_ICACHE_HIT() -+#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) -+#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) -+#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) -+#endif /* _BCMPERF_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdbus.h b/drivers/net/wireless/ap6210/include/bcmsdbus.h -new file mode 100644 -index 0000000..2fa706d ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdbus.h -@@ -0,0 +1,152 @@ -+/* -+ * Definitions for API from sdio common code (bcmsdh) to individual -+ * host controller drivers. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdbus.h 347614 2012-07-27 10:24:51Z $ -+ */ -+ -+#ifndef _sdio_api_h_ -+#define _sdio_api_h_ -+ -+ -+#define SDIOH_API_RC_SUCCESS (0x00) -+#define SDIOH_API_RC_FAIL (0x01) -+#define SDIOH_API_SUCCESS(status) (status == 0) -+ -+#define SDIOH_READ 0 /* Read request */ -+#define SDIOH_WRITE 1 /* Write request */ -+ -+#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -+#define SDIOH_DATA_INC 1 /* Incremental addressing */ -+ -+#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -+#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -+#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ -+ -+#define SDIOH_DATA_PIO 0 /* PIO mode */ -+#define SDIOH_DATA_DMA 1 /* DMA mode */ -+ -+#ifdef BCMSDIOH_TXGLOM -+/* Max number of glommed pkts */ -+#define SDPCM_MAXGLOM_SIZE 10 -+#define SDPCM_DEFGLOM_SIZE 3 -+ -+#define SDPCM_TXGLOM_CPY 0 /* SDIO 2.0 should use copy mode */ -+#define SDPCM_TXGLOM_MDESC 1 /* SDIO 3.0 should use multi-desc mode */ -+#endif -+ -+ -+typedef int SDIOH_API_RC; -+ -+/* SDio Host structure */ -+typedef struct sdioh_info sdioh_info_t; -+ -+/* callback function, taking one arg */ -+typedef void (*sdioh_cb_fn_t)(void *); -+ -+/* attach, return handler on success, NULL if failed. -+ * The handler shall be provided by all subsequent calls. No local cache -+ * cfghdl points to the starting address of pci device mapped memory -+ */ -+extern sdioh_info_t * sdioh_attach(osl_t *osh, void *cfghdl, uint irq); -+extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si); -+extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); -+extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); -+ -+/* query whether SD interrupt is enabled or not */ -+extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); -+ -+/* enable or disable SD interrupt */ -+extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); -+ -+#if defined(DHD_DEBUG) -+extern bool sdioh_interrupt_pending(sdioh_info_t *si); -+#endif -+ -+/* read or write one byte using cmd52 */ -+extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, uint addr, uint8 *byte); -+ -+/* read or write 2/4 bytes using cmd53 */ -+extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, uint rw, uint fnc, -+ uint addr, uint32 *word, uint nbyte); -+ -+/* read or write any buffer using cmd53 */ -+extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc, -+ uint rw, uint fnc_num, uint32 addr, uint regwidth, uint32 buflen, uint8 *buffer, -+ void *pkt); -+ -+#ifdef BCMSDIOH_TXGLOM -+extern void sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, uint len); -+extern void sdioh_glom_clear(sdioh_info_t *sd); -+extern uint sdioh_set_mode(sdioh_info_t *sd, uint mode); -+extern bool sdioh_glom_enabled(void); -+#else -+#define sdioh_glom_post(a, b, c) -+#define sdioh_glom_clear(a) -+#define sdioh_set_mode(a) (0) -+#define sdioh_glom_enabled() (FALSE) -+#endif -+ -+/* get cis data */ -+extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis, uint32 length); -+ -+extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); -+extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data); -+ -+/* query number of io functions */ -+extern uint sdioh_query_iofnum(sdioh_info_t *si); -+ -+/* handle iovars */ -+extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, -+ void *params, int plen, void *arg, int len, bool set); -+ -+/* Issue abort to the specified function and clear controller as needed */ -+extern int sdioh_abort(sdioh_info_t *si, uint fnc); -+ -+/* Start and Stop SDIO without re-enumerating the SD card. */ -+extern int sdioh_start(sdioh_info_t *si, int stage); -+extern int sdioh_stop(sdioh_info_t *si); -+ -+/* Wait system lock free */ -+extern int sdioh_waitlockfree(sdioh_info_t *si); -+ -+/* Reset and re-initialize the device */ -+extern int sdioh_sdio_reset(sdioh_info_t *si); -+ -+/* Helper function */ -+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); -+ -+ -+ -+#if defined(BCMSDIOH_STD) -+ #define SDIOH_SLEEP_ENABLED -+#endif -+extern SDIOH_API_RC sdioh_sleep(sdioh_info_t *si, bool enab); -+ -+/* GPIO support */ -+extern SDIOH_API_RC sdioh_gpio_init(sdioh_info_t *sd); -+extern bool sdioh_gpioin(sdioh_info_t *sd, uint32 gpio); -+extern SDIOH_API_RC sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio); -+extern SDIOH_API_RC sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab); -+ -+#endif /* _sdio_api_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdh.h b/drivers/net/wireless/ap6210/include/bcmsdh.h -new file mode 100644 -index 0000000..8e5a563 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdh.h -@@ -0,0 +1,247 @@ -+/* -+ * SDIO host client driver interface of Broadcom HNBU -+ * export functions to client drivers -+ * abstract OS and BUS specific details of SDIO -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh.h 347614 2012-07-27 10:24:51Z $ -+ */ -+ -+/** -+ * @file bcmsdh.h -+ */ -+ -+#ifndef _bcmsdh_h_ -+#define _bcmsdh_h_ -+ -+#define BCMSDH_ERROR_VAL 0x0001 /* Error */ -+#define BCMSDH_INFO_VAL 0x0002 /* Info */ -+extern const uint bcmsdh_msglevel; -+ -+#define BCMSDH_ERROR(x) -+#define BCMSDH_INFO(x) -+ -+#if (defined(BCMSDIOH_STD) || defined(BCMSDIOH_BCM) || defined(BCMSDIOH_SPI)) -+#define BCMSDH_ADAPTER -+#endif /* BCMSDIO && (BCMSDIOH_STD || BCMSDIOH_BCM || BCMSDIOH_SPI) */ -+ -+/* forward declarations */ -+typedef struct bcmsdh_info bcmsdh_info_t; -+typedef void (*bcmsdh_cb_fn_t)(void *); -+ -+/* Attach and build an interface to the underlying SD host driver. -+ * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. -+ * - Returns the bcmsdh handle and virtual address base for register access. -+ * The returned handle should be used in all subsequent calls, but the bcmsh -+ * implementation may maintain a single "default" handle (e.g. the first or -+ * most recent one) to enable single-instance implementations to pass NULL. -+ */ -+ -+#if 0 && (NDISVER >= 0x0630) && 1 -+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, -+ void **regsva, uint irq, shared_info_t *sh); -+#else -+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq); -+#endif -+ -+/* Detach - freeup resources allocated in attach */ -+extern int bcmsdh_detach(osl_t *osh, void *sdh); -+ -+/* Query if SD device interrupts are enabled */ -+extern bool bcmsdh_intr_query(void *sdh); -+ -+/* Enable/disable SD interrupt */ -+extern int bcmsdh_intr_enable(void *sdh); -+extern int bcmsdh_intr_disable(void *sdh); -+ -+/* Register/deregister device interrupt handler. */ -+extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -+extern int bcmsdh_intr_dereg(void *sdh); -+/* Enable/disable SD card interrupt forward */ -+extern void bcmsdh_intr_forward(void *sdh, bool pass); -+ -+#if defined(DHD_DEBUG) -+/* Query pending interrupt status from the host controller */ -+extern bool bcmsdh_intr_pending(void *sdh); -+#endif -+ -+/* Register a callback to be called if and when bcmsdh detects -+ * device removal. No-op in the case of non-removable/hardwired devices. -+ */ -+extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -+ -+/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). -+ * fn: function number -+ * addr: unmodified SDIO-space address -+ * data: data byte to write -+ * err: pointer to error code (or NULL) -+ */ -+extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err); -+extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data, int *err); -+ -+/* Read/Write 4bytes from/to cfg space */ -+extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err); -+extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err); -+ -+/* Read CIS content for specified function. -+ * fn: function whose CIS is being requested (0 is common CIS) -+ * cis: pointer to memory location to place results -+ * length: number of bytes to read -+ * Internally, this routine uses the values from the cis base regs (0x9-0xB) -+ * to form an SDIO-space address to read the data from. -+ */ -+extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length); -+ -+/* Synchronous access to device (client) core registers via CMD53 to F1. -+ * addr: backplane address (i.e. >= regsva from attach) -+ * size: register width in bytes (2 or 4) -+ * data: data for register write -+ */ -+extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size); -+extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data); -+ -+/* set sb address window */ -+extern int bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set); -+ -+/* Indicate if last reg read/write failed */ -+extern bool bcmsdh_regfail(void *sdh); -+ -+/* Buffer transfer to/from device (client) core via cmd53. -+ * fn: function number -+ * addr: backplane address (i.e. >= regsva from attach) -+ * flags: backplane width, address increment, sync/async -+ * buf: pointer to memory data buffer -+ * nbytes: number of bytes to transfer to/from buf -+ * pkt: pointer to packet associated with buf (if any) -+ * complete: callback function for command completion (async only) -+ * handle: handle for completion callback (first arg in callback) -+ * Returns 0 or error code. -+ * NOTE: Async operation is not currently supported. -+ */ -+typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting); -+extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, void *pkt, -+ bcmsdh_cmplt_fn_t complete_fn, void *handle); -+extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, -+ uint8 *buf, uint nbytes, void *pkt, -+ bcmsdh_cmplt_fn_t complete_fn, void *handle); -+ -+extern void bcmsdh_glom_post(void *sdh, uint8 *frame, uint len); -+extern void bcmsdh_glom_clear(void *sdh); -+extern uint bcmsdh_set_mode(void *sdh, uint mode); -+extern bool bcmsdh_glom_enabled(void); -+/* Flags bits */ -+#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ -+#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ -+#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ -+#define SDIO_BYTE_MODE 0x8 /* Byte mode request(non-block mode) */ -+ -+/* Pending (non-error) return code */ -+#define BCME_PENDING 1 -+ -+/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). -+ * rw: read or write (0/1) -+ * addr: direct SDIO address -+ * buf: pointer to memory data buffer -+ * nbytes: number of bytes to transfer to/from buf -+ * Returns 0 or error code. -+ */ -+extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes); -+ -+/* Issue an abort to the specified function */ -+extern int bcmsdh_abort(void *sdh, uint fn); -+ -+/* Start SDIO Host Controller communication */ -+extern int bcmsdh_start(void *sdh, int stage); -+ -+/* Stop SDIO Host Controller communication */ -+extern int bcmsdh_stop(void *sdh); -+ -+/* Wait system lock free */ -+extern int bcmsdh_waitlockfree(void *sdh); -+ -+/* Returns the "Device ID" of target device on the SDIO bus. */ -+extern int bcmsdh_query_device(void *sdh); -+ -+/* Returns the number of IO functions reported by the device */ -+extern uint bcmsdh_query_iofnum(void *sdh); -+ -+/* Miscellaneous knob tweaker. */ -+extern int bcmsdh_iovar_op(void *sdh, const char *name, -+ void *params, int plen, void *arg, int len, bool set); -+ -+/* Reset and reinitialize the device */ -+extern int bcmsdh_reset(bcmsdh_info_t *sdh); -+ -+/* helper functions */ -+ -+extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); -+ -+/* callback functions */ -+typedef struct { -+ /* attach to device */ -+ void *(*attach)(uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot, -+ uint16 func, uint bustype, void * regsva, osl_t * osh, -+ void * param); -+ /* detach from device */ -+ void (*detach)(void *ch); -+} bcmsdh_driver_t; -+ -+/* platform specific/high level functions */ -+extern int bcmsdh_register(bcmsdh_driver_t *driver); -+extern void bcmsdh_unregister(void); -+extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device); -+extern void bcmsdh_device_remove(void * sdh); -+ -+extern int bcmsdh_reg_sdio_notify(void* semaphore); -+extern void bcmsdh_unreg_sdio_notify(void); -+ -+extern int bcmsdh_set_drvdata(void * dhdp); -+ -+#if defined(OOB_INTR_ONLY) -+extern int bcmsdh_register_oob_intr(void * dhdp); -+extern void bcmsdh_unregister_oob_intr(void); -+extern void bcmsdh_oob_intr_set(bool enable); -+#endif -+#if defined(HW_OOB) -+void bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip); -+#endif -+ -+/* Function to pass device-status bits to DHD. */ -+extern uint32 bcmsdh_get_dstatus(void *sdh); -+ -+/* Function to return current window addr */ -+extern uint32 bcmsdh_cur_sbwad(void *sdh); -+ -+/* Function to pass chipid and rev to lower layers for controlling pr's */ -+extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev); -+ -+ -+extern int bcmsdh_sleep(void *sdh, bool enab); -+ -+/* GPIO support */ -+extern int bcmsdh_gpio_init(void *sd); -+extern bool bcmsdh_gpioin(void *sd, uint32 gpio); -+extern int bcmsdh_gpioouten(void *sd, uint32 gpio); -+extern int bcmsdh_gpioout(void *sd, uint32 gpio, bool enab); -+ -+#endif /* _bcmsdh_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h b/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h -new file mode 100644 -index 0000000..a169588 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h -@@ -0,0 +1,109 @@ -+/* -+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdh_sdmmc.h 366812 2012-11-05 13:49:32Z $ -+ */ -+ -+#ifndef __BCMSDH_SDMMC_H__ -+#define __BCMSDH_SDMMC_H__ -+ -+#define sd_sync_dma(sd, read, nbytes) -+#define sd_init_dma(sd) -+#define sd_ack_intr(sd) -+#define sd_wakeup(sd); -+ -+/* Allocate/init/free per-OS private data */ -+extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -+extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); -+ -+#define BLOCK_SIZE_4318 64 -+#define BLOCK_SIZE_4328 512 -+ -+/* internal return code */ -+#define SUCCESS 0 -+#define ERROR 1 -+ -+/* private bus modes */ -+#define SDIOH_MODE_SD4 2 -+#define CLIENT_INTR 0x100 /* Get rid of this! */ -+ -+struct sdioh_info { -+ osl_t *osh; /* osh handler */ -+ bool client_intr_enabled; /* interrupt connnected flag */ -+ bool intr_handler_valid; /* client driver interrupt handler valid */ -+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ -+ void *intr_handler_arg; /* argument to call interrupt handler */ -+ uint16 intmask; /* Current active interrupts */ -+ void *sdos_info; /* Pointer to per-OS private data */ -+ -+ uint irq; /* Client irq */ -+ int intrcount; /* Client interrupts */ -+ -+ bool sd_use_dma; /* DMA on CMD53 */ -+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ -+ /* Must be on for sd_multiblock to be effective */ -+ bool use_client_ints; /* If this is false, make sure to restore */ -+ int sd_mode; /* SD1/SD4/SPI */ -+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ -+ uint8 num_funcs; /* Supported funcs on client */ -+ uint32 com_cis_ptr; -+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; -+ -+#define SDIOH_SDMMC_MAX_SG_ENTRIES 32 -+ struct scatterlist sg_list[SDIOH_SDMMC_MAX_SG_ENTRIES]; -+ bool use_rxchain; -+}; -+ -+/************************************************************ -+ * Internal interfaces: per-port references into bcmsdh_sdmmc.c -+ */ -+ -+/* Global message bits */ -+extern uint sd_msglevel; -+ -+/* OS-independent interrupt handler */ -+extern bool check_client_intr(sdioh_info_t *sd); -+ -+/* Core interrupt enable/disable of device interrupts */ -+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -+ -+ -+/************************************************************** -+ * Internal interfaces: bcmsdh_sdmmc.c references to per-port code -+ */ -+ -+/* Register mapping routines */ -+extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size); -+extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size); -+ -+/* Interrupt (de)registration routines */ -+extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -+extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); -+ -+typedef struct _BCMSDH_SDMMC_INSTANCE { -+ sdioh_info_t *sd; -+ struct sdio_func *func[SDIOD_MAX_IOFUNCS]; -+} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; -+ -+#endif /* __BCMSDH_SDMMC_H__ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdpcm.h b/drivers/net/wireless/ap6210/include/bcmsdpcm.h -new file mode 100644 -index 0000000..fb2ec3a ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdpcm.h -@@ -0,0 +1,281 @@ -+/* -+ * Broadcom SDIO/PCMCIA -+ * Software-specific definitions shared between device and host side -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdpcm.h 362722 2012-10-12 23:55:55Z $ -+ */ -+ -+#ifndef _bcmsdpcm_h_ -+#define _bcmsdpcm_h_ -+ -+/* -+ * Software allocation of To SB Mailbox resources -+ */ -+ -+/* intstatus bits */ -+#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -+#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -+#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -+#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ -+ -+#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT) -+ -+/* tosbmailbox bits corresponding to intstatus bits */ -+#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -+#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -+#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -+#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -+#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ -+ -+/* tosbmailboxdata */ -+#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -+#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ -+ -+/* -+ * Software allocation of To Host Mailbox resources -+ */ -+ -+/* intstatus bits */ -+#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -+#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -+#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -+#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ -+ -+#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT) -+ -+/* tohostmailbox bits corresponding to intstatus bits */ -+#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -+#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -+#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -+#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -+#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ -+ -+/* tohostmailboxdata */ -+#define HMB_DATA_NAKHANDLED 0x01 /* we're ready to retransmit NAK'd frame to host */ -+#define HMB_DATA_DEVREADY 0x02 /* we're ready to to talk to host after enable */ -+#define HMB_DATA_FC 0x04 /* per prio flowcontrol update flag to host */ -+#define HMB_DATA_FWREADY 0x08 /* firmware is ready for protocol activity */ -+#define HMB_DATA_FWHALT 0x10 /* firmware has halted operation */ -+ -+#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -+#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ -+ -+#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -+#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ -+ -+/* -+ * Software-defined protocol header -+ */ -+ -+/* Current protocol version */ -+#define SDPCM_PROT_VERSION 4 -+ -+/* SW frame header */ -+#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -+#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ -+ -+#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -+#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -+#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ -+ -+#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -+#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -+#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ -+ -+/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -+#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -+#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -+#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -+#define SDPCM_NEXTLEN_OFFSET 2 -+ -+/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -+#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -+#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -+#define SDPCM_DOFFSET_MASK 0xff000000 -+#define SDPCM_DOFFSET_SHIFT 24 -+ -+#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -+#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) -+#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -+#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -+#define SDPCM_VERSION_OFFSET 6 /* Version # */ -+#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -+#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -+#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) -+ -+#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ -+ -+/* logical channel numbers */ -+#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -+#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -+#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -+#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -+#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -+#define SDPCM_MAX_CHANNEL 15 -+ -+#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ -+ -+#define SDPCM_FLAG_RESVD0 0x01 -+#define SDPCM_FLAG_RESVD1 0x02 -+#define SDPCM_FLAG_GSPI_TXENAB 0x04 -+#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ -+ -+/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -+#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) -+ -+#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) -+ -+/* For TEST_CHANNEL packets, define another 4-byte header */ -+#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); -+ * Semantics of Ext byte depend on command. -+ * Len is current or requested frame length, not -+ * including test header; sent little-endian. -+ */ -+#define SDPCM_TEST_PKT_CNT_FLD_LEN 4 /* Packet count filed legth */ -+#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -+#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -+#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -+#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count -+ * (Backward compatabilty) Set frame count in a -+ * 4 byte filed adjacent to the HDR -+ */ -+#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off -+ * Set frame count in a 4 byte filed adjacent to -+ * the HDR -+ */ -+ -+/* Handy macro for filling in datagen packets with a pattern */ -+#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) -+ -+/* -+ * Software counters (first part matches hardware counters) -+ */ -+ -+typedef volatile struct { -+ uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ -+ uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ -+ uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ -+ uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ -+ uint32 abort; /* AbortCount, SDIO: aborts */ -+ uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ -+ uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ -+ uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ -+ uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ -+ uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ -+ uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ -+ uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ -+ uint32 rxdescuflo; /* receive descriptor underflows */ -+ uint32 rxfifooflo; /* receive fifo overflows */ -+ uint32 txfifouflo; /* transmit fifo underflows */ -+ uint32 runt; /* runt (too short) frames recv'd from bus */ -+ uint32 badlen; /* frame's rxh len does not match its hw tag len */ -+ uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ -+ uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ -+ uint32 rxfcrc; /* frame rx header indicates crc error */ -+ uint32 rxfwoos; /* frame rx header indicates write out of sync */ -+ uint32 rxfwft; /* frame rx header indicates write frame termination */ -+ uint32 rxfabort; /* frame rx header indicates frame aborted */ -+ uint32 woosint; /* write out of sync interrupt */ -+ uint32 roosint; /* read out of sync interrupt */ -+ uint32 rftermint; /* read frame terminate interrupt */ -+ uint32 wftermint; /* write frame terminate interrupt */ -+} sdpcmd_cnt_t; -+ -+/* -+ * Register Access Macros -+ */ -+ -+#define SDIODREV_IS(var, val) ((var) == (val)) -+#define SDIODREV_GE(var, val) ((var) >= (val)) -+#define SDIODREV_GT(var, val) ((var) > (val)) -+#define SDIODREV_LT(var, val) ((var) < (val)) -+#define SDIODREV_LE(var, val) ((var) <= (val)) -+ -+#define SDIODDMAREG32(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) -+ -+#define SDIODDMAREG64(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) -+ -+#define SDIODDMAREG(h, dir, chnl) \ -+ (SDIODREV_LT((h)->corerev, 1) ? \ -+ SDIODDMAREG32((h), (dir), (chnl)) : \ -+ SDIODDMAREG64((h), (dir), (chnl))) -+ -+#define PCMDDMAREG(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) -+ -+#define SDPCMDMAREG(h, dir, chnl, coreid) \ -+ ((coreid) == SDIOD_CORE_ID ? \ -+ SDIODDMAREG(h, dir, chnl) : \ -+ PCMDDMAREG(h, dir, chnl)) -+ -+#define SDIODFIFOREG(h, corerev) \ -+ (SDIODREV_LT((corerev), 1) ? \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) -+ -+#define PCMDFIFOREG(h) \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) -+ -+#define SDPCMFIFOREG(h, coreid, corerev) \ -+ ((coreid) == SDIOD_CORE_ID ? \ -+ SDIODFIFOREG(h, corerev) : \ -+ PCMDFIFOREG(h)) -+ -+/* -+ * Shared structure between dongle and the host. -+ * The structure contains pointers to trap or assert information. -+ */ -+#define SDPCM_SHARED_VERSION 0x0001 -+#define SDPCM_SHARED_VERSION_MASK 0x00FF -+#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -+#define SDPCM_SHARED_ASSERT 0x0200 -+#define SDPCM_SHARED_TRAP 0x0400 -+#define SDPCM_SHARED_IN_BRPT 0x0800 -+#define SDPCM_SHARED_SET_BRPT 0x1000 -+#define SDPCM_SHARED_PENDING_BRPT 0x2000 -+ -+typedef struct { -+ uint32 flags; -+ uint32 trap_addr; -+ uint32 assert_exp_addr; -+ uint32 assert_file_addr; -+ uint32 assert_line; -+ uint32 console_addr; /* Address of hndrte_cons_t */ -+ uint32 msgtrace_addr; -+ uint32 brpt_addr; -+} sdpcm_shared_t; -+ -+extern sdpcm_shared_t sdpcm_shared; -+ -+/* Function can be used to notify host of FW halt */ -+extern void sdpcmd_fwhalt(void); -+ -+#endif /* _bcmsdpcm_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdspi.h b/drivers/net/wireless/ap6210/include/bcmsdspi.h -new file mode 100644 -index 0000000..9a7496b ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdspi.h -@@ -0,0 +1,119 @@ -+/* -+ * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdspi.h 294363 2011-11-06 23:02:20Z $ -+ */ -+#ifndef _BCM_SD_SPI_H -+#define _BCM_SD_SPI_H -+ -+#define BLOCK_SIZE_4318 64 -+#define BLOCK_SIZE_4328 512 -+ -+/* internal return code */ -+#define SUCCESS 0 -+#undef ERROR -+#define ERROR 1 -+ -+/* private bus modes */ -+#define SDIOH_MODE_SPI 0 -+ -+#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -+#define USE_MULTIBLOCK 0x4 -+ -+struct sdioh_info { -+ uint cfg_bar; /* pci cfg address for bar */ -+ uint32 caps; /* cached value of capabilities reg */ -+ uint bar0; /* BAR0 for PCI Device */ -+ osl_t *osh; /* osh handler */ -+ void *controller; /* Pointer to SPI Controller's private data struct */ -+ -+ uint lockcount; /* nest count of sdspi_lock() calls */ -+ bool client_intr_enabled; /* interrupt connnected flag */ -+ bool intr_handler_valid; /* client driver interrupt handler valid */ -+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ -+ void *intr_handler_arg; /* argument to call interrupt handler */ -+ bool initialized; /* card initialized */ -+ uint32 target_dev; /* Target device ID */ -+ uint32 intmask; /* Current active interrupts */ -+ void *sdos_info; /* Pointer to per-OS private data */ -+ -+ uint32 controller_type; /* Host controller type */ -+ uint8 version; /* Host Controller Spec Compliance Version */ -+ uint irq; /* Client irq */ -+ uint32 intrcount; /* Client interrupts */ -+ uint32 local_intrcount; /* Controller interrupts */ -+ bool host_init_done; /* Controller initted */ -+ bool card_init_done; /* Client SDIO interface initted */ -+ bool polled_mode; /* polling for command completion */ -+ -+ bool sd_use_dma; /* DMA on CMD53 */ -+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ -+ /* Must be on for sd_multiblock to be effective */ -+ bool use_client_ints; /* If this is false, make sure to restore */ -+ bool got_hcint; /* Host Controller interrupt. */ -+ /* polling hack in wl_linux.c:wl_timer() */ -+ int adapter_slot; /* Maybe dealing with multiple slots/controllers */ -+ int sd_mode; /* SD1/SD4/SPI */ -+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ -+ uint32 data_xfer_count; /* Current register transfer size */ -+ uint32 cmd53_wr_data; /* Used to pass CMD53 write data */ -+ uint32 card_response; /* Used to pass back response status byte */ -+ uint32 card_rsp_data; /* Used to pass back response data word */ -+ uint16 card_rca; /* Current Address */ -+ uint8 num_funcs; /* Supported funcs on client */ -+ uint32 com_cis_ptr; -+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; -+ void *dma_buf; -+ ulong dma_phys; -+ int r_cnt; /* rx count */ -+ int t_cnt; /* tx_count */ -+}; -+ -+/************************************************************ -+ * Internal interfaces: per-port references into bcmsdspi.c -+ */ -+ -+/* Global message bits */ -+extern uint sd_msglevel; -+ -+/************************************************************** -+ * Internal interfaces: bcmsdspi.c references to per-port code -+ */ -+ -+/* Register mapping routines */ -+extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size); -+extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size); -+ -+/* Interrupt (de)registration routines */ -+extern int spi_register_irq(sdioh_info_t *sd, uint irq); -+extern void spi_free_irq(uint irq, sdioh_info_t *sd); -+ -+/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -+extern void spi_lock(sdioh_info_t *sd); -+extern void spi_unlock(sdioh_info_t *sd); -+ -+/* Allocate/init/free per-OS private data */ -+extern int spi_osinit(sdioh_info_t *sd); -+extern void spi_osfree(sdioh_info_t *sd); -+ -+#endif /* _BCM_SD_SPI_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmsdstd.h b/drivers/net/wireless/ap6210/include/bcmsdstd.h -new file mode 100644 -index 0000000..1c854b2 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmsdstd.h -@@ -0,0 +1,248 @@ -+0/* -+ * 'Standard' SDIO HOST CONTROLLER driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmsdstd.h 347614 2012-07-27 10:24:51Z $ -+ */ -+#ifndef _BCM_SD_STD_H -+#define _BCM_SD_STD_H -+ -+#define sd_sync_dma(sd, read, nbytes) -+#define sd_init_dma(sd) -+#define sd_ack_intr(sd) -+#define sd_wakeup(sd); -+/* Allocate/init/free per-OS private data */ -+extern int sdstd_osinit(sdioh_info_t *sd); -+extern void sdstd_osfree(sdioh_info_t *sd); -+ -+#define BLOCK_SIZE_4318 64 -+#define BLOCK_SIZE_4328 512 -+ -+/* internal return code */ -+#define SUCCESS 0 -+#define ERROR 1 -+ -+/* private bus modes */ -+#define SDIOH_MODE_SPI 0 -+#define SDIOH_MODE_SD1 1 -+#define SDIOH_MODE_SD4 2 -+ -+#define MAX_SLOTS 6 /* For PCI: Only 6 BAR entries => 6 slots */ -+#define SDIOH_REG_WINSZ 0x100 /* Number of registers in Standard Host Controller */ -+ -+#define SDIOH_TYPE_ARASAN_HDK 1 -+#define SDIOH_TYPE_BCM27XX 2 -+#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */ -+#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */ -+#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */ -+ -+/* For linux, allow yielding for dongle */ -+#define BCMSDYIELD -+ -+/* Expected card status value for CMD7 */ -+#define SDIOH_CMD7_EXP_STATUS 0x00001E00 -+ -+#define RETRIES_LARGE 100000 -+#define sdstd_os_yield(sd) do {} while (0) -+#define RETRIES_SMALL 100 -+ -+ -+#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ -+#define USE_MULTIBLOCK 0x4 -+ -+#define USE_FIFO 0x8 /* Fifo vs non-fifo */ -+ -+#define CLIENT_INTR 0x100 /* Get rid of this! */ -+ -+#define HC_INTR_RETUNING 0x1000 -+ -+ -+#ifdef BCMSDIOH_TXGLOM -+/* Setting the MAX limit to 10 */ -+#define SDIOH_MAXGLOM_SIZE 10 -+ -+typedef struct glom_buf { -+ uint32 count; /* Total number of pkts queued */ -+ void *dma_buf_arr[SDIOH_MAXGLOM_SIZE]; /* Frame address */ -+ ulong dma_phys_arr[SDIOH_MAXGLOM_SIZE]; /* DMA_MAPed address of frames */ -+ uint16 nbytes[SDIOH_MAXGLOM_SIZE]; /* Size of each frame */ -+} glom_buf_t; -+#endif -+ -+struct sdioh_info { -+ uint cfg_bar; /* pci cfg address for bar */ -+ uint32 caps; /* cached value of capabilities reg */ -+ uint32 curr_caps; /* max current capabilities reg */ -+ -+ osl_t *osh; /* osh handler */ -+ volatile char *mem_space; /* pci device memory va */ -+ uint lockcount; /* nest count of sdstd_lock() calls */ -+ bool client_intr_enabled; /* interrupt connnected flag */ -+ bool intr_handler_valid; /* client driver interrupt handler valid */ -+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ -+ void *intr_handler_arg; /* argument to call interrupt handler */ -+ bool initialized; /* card initialized */ -+ uint target_dev; /* Target device ID */ -+ uint16 intmask; /* Current active interrupts */ -+ void *sdos_info; /* Pointer to per-OS private data */ -+ -+ uint32 controller_type; /* Host controller type */ -+ uint8 version; /* Host Controller Spec Compliance Version */ -+ uint irq; /* Client irq */ -+ int intrcount; /* Client interrupts */ -+ int local_intrcount; /* Controller interrupts */ -+ bool host_init_done; /* Controller initted */ -+ bool card_init_done; /* Client SDIO interface initted */ -+ bool polled_mode; /* polling for command completion */ -+ -+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ -+ /* Must be on for sd_multiblock to be effective */ -+ bool use_client_ints; /* If this is false, make sure to restore */ -+ /* polling hack in wl_linux.c:wl_timer() */ -+ int adapter_slot; /* Maybe dealing with multiple slots/controllers */ -+ int sd_mode; /* SD1/SD4/SPI */ -+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ -+ uint32 data_xfer_count; /* Current transfer */ -+ uint16 card_rca; /* Current Address */ -+ int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */ -+ uint8 num_funcs; /* Supported funcs on client */ -+ uint32 com_cis_ptr; -+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; -+ void *dma_buf; /* DMA Buffer virtual address */ -+ ulong dma_phys; /* DMA Buffer physical address */ -+ void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */ -+ ulong adma2_dscr_phys; /* ADMA2 Descriptor Buffer physical address */ -+ -+ /* adjustments needed to make the dma align properly */ -+ void *dma_start_buf; -+ ulong dma_start_phys; -+ uint alloced_dma_size; -+ void *adma2_dscr_start_buf; -+ ulong adma2_dscr_start_phys; -+ uint alloced_adma2_dscr_size; -+ -+ int r_cnt; /* rx count */ -+ int t_cnt; /* tx_count */ -+ bool got_hcint; /* local interrupt flag */ -+ uint16 last_intrstatus; /* to cache intrstatus */ -+ int host_UHSISupported; /* whether UHSI is supported for HC. */ -+ int card_UHSI_voltage_Supported; /* whether UHSI is supported for -+ * Card in terms of Voltage [1.8 or 3.3]. -+ */ -+ int global_UHSI_Supp; /* type of UHSI support in both host and card. -+ * HOST_SDR_UNSUPP: capabilities not supported/matched -+ * HOST_SDR_12_25: SDR12 and SDR25 supported -+ * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd -+ */ -+ volatile int sd3_dat_state; /* data transfer state used for retuning check */ -+ volatile int sd3_tun_state; /* tuning state used for retuning check */ -+ bool sd3_tuning_reqd; /* tuning requirement parameter */ -+ uint32 caps3; /* cached value of 32 MSbits capabilities reg (SDIO 3.0) */ -+#ifdef BCMSDIOH_TXGLOM -+ glom_buf_t glom_info; /* pkt information used for glomming */ -+ uint txglom_mode; /* Txglom mode: 0 - copy, 1 - multi-descriptor */ -+#endif -+}; -+ -+#define DMA_MODE_NONE 0 -+#define DMA_MODE_SDMA 1 -+#define DMA_MODE_ADMA1 2 -+#define DMA_MODE_ADMA2 3 -+#define DMA_MODE_ADMA2_64 4 -+#define DMA_MODE_AUTO -1 -+ -+#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE)) -+ -+/* States for Tuning and corr data */ -+#define TUNING_IDLE 0 -+#define TUNING_START 1 -+#define TUNING_START_AFTER_DAT 2 -+#define TUNING_ONGOING 3 -+ -+#define DATA_TRANSFER_IDLE 0 -+#define DATA_TRANSFER_ONGOING 1 -+ -+#define CHECK_TUNING_PRE_DATA 1 -+#define CHECK_TUNING_POST_DATA 2 -+ -+/************************************************************ -+ * Internal interfaces: per-port references into bcmsdstd.c -+ */ -+ -+/* Global message bits */ -+extern uint sd_msglevel; -+ -+/* OS-independent interrupt handler */ -+extern bool check_client_intr(sdioh_info_t *sd); -+ -+/* Core interrupt enable/disable of device interrupts */ -+extern void sdstd_devintr_on(sdioh_info_t *sd); -+extern void sdstd_devintr_off(sdioh_info_t *sd); -+ -+/* Enable/disable interrupts for local controller events */ -+extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err); -+extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err); -+ -+/* Wait for specified interrupt and error bits to be set */ -+extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err); -+ -+ -+/************************************************************** -+ * Internal interfaces: bcmsdstd.c references to per-port code -+ */ -+ -+/* Register mapping routines */ -+extern uint32 *sdstd_reg_map(osl_t *osh, int32 addr, int size); -+extern void sdstd_reg_unmap(osl_t *osh, int32 addr, int size); -+ -+/* Interrupt (de)registration routines */ -+extern int sdstd_register_irq(sdioh_info_t *sd, uint irq); -+extern void sdstd_free_irq(uint irq, sdioh_info_t *sd); -+ -+/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ -+extern void sdstd_lock(sdioh_info_t *sd); -+extern void sdstd_unlock(sdioh_info_t *sd); -+extern void sdstd_waitlockfree(sdioh_info_t *sd); -+ -+/* OS-specific wait-for-interrupt-or-status */ -+extern int sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield, uint16 *bits); -+ -+/* used by bcmsdstd_linux [implemented in sdstd] */ -+extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd); -+extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd); -+extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd); -+extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param); -+extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd); -+extern int sdstd_3_get_tune_state(sdioh_info_t *sd); -+extern int sdstd_3_get_data_state(sdioh_info_t *sd); -+extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state); -+extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state); -+extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd); -+extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd); -+extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode); -+ -+/* used by sdstd [implemented in bcmsdstd_linux/ndis] */ -+extern void sdstd_3_start_tuning(sdioh_info_t *sd); -+extern void sdstd_3_osinit_tuning(sdioh_info_t *sd); -+extern void sdstd_3_osclean_tuning(sdioh_info_t *sd); -+ -+#endif /* _BCM_SD_STD_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmspi.h b/drivers/net/wireless/ap6210/include/bcmspi.h -new file mode 100644 -index 0000000..e226cb1 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmspi.h -@@ -0,0 +1,40 @@ -+/* -+ * Broadcom SPI Low-Level Hardware Driver API -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmspi.h 241182 2011-02-17 21:50:03Z $ -+ */ -+#ifndef _BCM_SPI_H -+#define _BCM_SPI_H -+ -+extern void spi_devintr_off(sdioh_info_t *sd); -+extern void spi_devintr_on(sdioh_info_t *sd); -+extern bool spi_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor); -+extern bool spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode); -+extern bool spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr); -+extern bool spi_hw_attach(sdioh_info_t *sd); -+extern bool spi_hw_detach(sdioh_info_t *sd); -+extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen); -+extern void spi_spinbits(sdioh_info_t *sd); -+extern void spi_waitbits(sdioh_info_t *sd, bool yield); -+ -+#endif /* _BCM_SPI_H */ -diff --git a/drivers/net/wireless/ap6210/include/bcmutils.h b/drivers/net/wireless/ap6210/include/bcmutils.h -new file mode 100644 -index 0000000..71af3dc ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmutils.h -@@ -0,0 +1,808 @@ -+/* -+ * Misc useful os-independent macros and functions. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmutils.h 354837 2012-09-04 06:58:44Z $ -+ */ -+ -+#ifndef _bcmutils_h_ -+#define _bcmutils_h_ -+ -+#define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src)) -+#define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count)) -+#define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src)) -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#ifdef PKTQ_LOG -+#include -+#endif -+ -+/* ctype replacement */ -+#define _BCM_U 0x01 /* upper */ -+#define _BCM_L 0x02 /* lower */ -+#define _BCM_D 0x04 /* digit */ -+#define _BCM_C 0x08 /* cntrl */ -+#define _BCM_P 0x10 /* punct */ -+#define _BCM_S 0x20 /* white space (space/lf/tab) */ -+#define _BCM_X 0x40 /* hex digit */ -+#define _BCM_SP 0x80 /* hard space (0x20) */ -+ -+extern const unsigned char bcm_ctype[]; -+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) -+ -+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -+#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -+#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) -+ -+/* Buffer structure for collecting string-formatted data -+* using bcm_bprintf() API. -+* Use bcm_binit() to initialize before use -+*/ -+ -+struct bcmstrbuf { -+ char *buf; /* pointer to current position in origbuf */ -+ unsigned int size; /* current (residual) size in bytes */ -+ char *origbuf; /* unmodified pointer to orignal buffer */ -+ unsigned int origsize; /* unmodified orignal buffer size in bytes */ -+}; -+ -+/* ** driver-only section ** */ -+#ifdef BCMDRIVER -+#include -+ -+#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ -+ -+/* -+ * Spin at most 'us' microseconds while 'exp' is true. -+ * Caller should explicitly test 'exp' when this completes -+ * and take appropriate error action if 'exp' is still true. -+ */ -+#define SPINWAIT(exp, us) { \ -+ uint countdown = (us) + 9; \ -+ while ((exp) && (countdown >= 10)) {\ -+ OSL_DELAY(10); \ -+ countdown -= 10; \ -+ } \ -+} -+ -+/* osl multi-precedence packet queue */ -+#ifndef PKTQ_LEN_DEFAULT -+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ -+#endif -+#ifndef PKTQ_MAX_PREC -+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ -+#endif -+ -+typedef struct pktq_prec { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint16 len; /* number of queued packets */ -+ uint16 max; /* maximum number of queued packets */ -+} pktq_prec_t; -+ -+#ifdef PKTQ_LOG -+typedef struct { -+ uint32 requested; /* packets requested to be stored */ -+ uint32 stored; /* packets stored */ -+ uint32 saved; /* packets saved, -+ because a lowest priority queue has given away one packet -+ */ -+ uint32 selfsaved; /* packets saved, -+ because an older packet from the same queue has been dropped -+ */ -+ uint32 full_dropped; /* packets dropped, -+ because pktq is full with higher precedence packets -+ */ -+ uint32 dropped; /* packets dropped because pktq per that precedence is full */ -+ uint32 sacrificed; /* packets dropped, -+ in order to save one from a queue of a highest priority -+ */ -+ uint32 busy; /* packets droped because of hardware/transmission error */ -+ uint32 retry; /* packets re-sent because they were not received */ -+ uint32 ps_retry; /* packets retried again prior to moving power save mode */ -+ uint32 retry_drop; /* packets finally dropped after retry limit */ -+ uint32 max_avail; /* the high-water mark of the queue capacity for packets - -+ goes to zero as queue fills -+ */ -+ uint32 max_used; /* the high-water mark of the queue utilisation for packets - -+ increases with use ('inverse' of max_avail) -+ */ -+ uint32 queue_capacity; /* the maximum capacity of the queue */ -+} pktq_counters_t; -+#endif /* PKTQ_LOG */ -+ -+ -+#define PKTQ_COMMON \ -+ uint16 num_prec; /* number of precedences in use */ \ -+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ \ -+ uint16 max; /* total max packets */ \ -+ uint16 len; /* total number of packets */ -+ -+/* multi-priority pkt queue */ -+struct pktq { -+ PKTQ_COMMON -+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ -+ struct pktq_prec q[PKTQ_MAX_PREC]; -+#ifdef PKTQ_LOG -+ pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */ -+#endif -+}; -+ -+/* simple, non-priority pkt queue */ -+struct spktq { -+ PKTQ_COMMON -+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ -+ struct pktq_prec q[1]; -+}; -+ -+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) -+ -+/* fn(pkt, arg). return true if pkt belongs to if */ -+typedef bool (*ifpkt_cb_t)(void*, int); -+ -+#ifdef BCMPKTPOOL -+#define POOL_ENAB(pool) ((pool) && (pool)->inited) -+#define SHARED_POOL (pktpool_shared) -+#else /* BCMPKTPOOL */ -+#define POOL_ENAB(bus) 0 -+#define SHARED_POOL ((struct pktpool *)NULL) -+#endif /* BCMPKTPOOL */ -+ -+#ifndef PKTPOOL_LEN_MAX -+#define PKTPOOL_LEN_MAX 40 -+#endif /* PKTPOOL_LEN_MAX */ -+#define PKTPOOL_CB_MAX 3 -+ -+struct pktpool; -+typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); -+typedef struct { -+ pktpool_cb_t cb; -+ void *arg; -+} pktpool_cbinfo_t; -+ -+#ifdef BCMDBG_POOL -+/* pkt pool debug states */ -+#define POOL_IDLE 0 -+#define POOL_RXFILL 1 -+#define POOL_RXDH 2 -+#define POOL_RXD11 3 -+#define POOL_TXDH 4 -+#define POOL_TXD11 5 -+#define POOL_AMPDU 6 -+#define POOL_TXENQ 7 -+ -+typedef struct { -+ void *p; -+ uint32 cycles; -+ uint32 dur; -+} pktpool_dbg_t; -+ -+typedef struct { -+ uint8 txdh; /* tx to host */ -+ uint8 txd11; /* tx to d11 */ -+ uint8 enq; /* waiting in q */ -+ uint8 rxdh; /* rx from host */ -+ uint8 rxd11; /* rx from d11 */ -+ uint8 rxfill; /* dma_rxfill */ -+ uint8 idle; /* avail in pool */ -+} pktpool_stats_t; -+#endif /* BCMDBG_POOL */ -+ -+typedef struct pktpool { -+ bool inited; -+ uint16 r; -+ uint16 w; -+ uint16 len; -+ uint16 maxlen; -+ uint16 plen; -+ bool istx; -+ bool empty; -+ uint8 cbtoggle; -+ uint8 cbcnt; -+ uint8 ecbcnt; -+ bool emptycb_disable; -+ pktpool_cbinfo_t *availcb_excl; -+ pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX]; -+ pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; -+ void *q[PKTPOOL_LEN_MAX + 1]; -+ -+#ifdef BCMDBG_POOL -+ uint8 dbg_cbcnt; -+ pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; -+ uint16 dbg_qlen; -+ pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; -+#endif -+} pktpool_t; -+ -+extern pktpool_t *pktpool_shared; -+ -+extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx); -+extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); -+extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); -+extern void* pktpool_get(pktpool_t *pktp); -+extern void pktpool_free(pktpool_t *pktp, void *p); -+extern int pktpool_add(pktpool_t *pktp, void *p); -+extern uint16 pktpool_avail(pktpool_t *pktp); -+extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); -+extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); -+extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); -+extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen); -+extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); -+extern bool pktpool_emptycb_disabled(pktpool_t *pktp); -+ -+#define POOLPTR(pp) ((pktpool_t *)(pp)) -+#define pktpool_len(pp) (POOLPTR(pp)->len - 1) -+#define pktpool_plen(pp) (POOLPTR(pp)->plen) -+#define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen) -+ -+#ifdef BCMDBG_POOL -+extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_start_trigger(pktpool_t *pktp, void *p); -+extern int pktpool_dbg_dump(pktpool_t *pktp); -+extern int pktpool_dbg_notify(pktpool_t *pktp); -+extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); -+#endif /* BCMDBG_POOL */ -+ -+/* forward definition of ether_addr structure used by some function prototypes */ -+ -+struct ether_addr; -+ -+extern int ether_isbcast(const void *ea); -+extern int ether_isnulladdr(const void *ea); -+ -+/* operations on a specific precedence in packet queue */ -+ -+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -+#define pktq_pmax(pq, prec) ((pq)->q[prec].max) -+#define pktq_plen(pq, prec) ((pq)->q[prec].len) -+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) -+ -+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) -+ -+extern void *pktq_penq(struct pktq *pq, int prec, void *p); -+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -+extern void *pktq_pdeq(struct pktq *pq, int prec); -+extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p); -+extern void *pktq_pdeq_tail(struct pktq *pq, int prec); -+/* Empty the queue at particular precedence level */ -+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, -+ ifpkt_cb_t fn, int arg); -+/* Remove a specified packet from its queue */ -+extern bool pktq_pdel(struct pktq *pq, void *p, int prec); -+ -+/* operations on a set of precedences in packet queue */ -+ -+extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); -+extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out); -+ -+/* operations on packet queue as a whole */ -+ -+#define pktq_len(pq) ((int)(pq)->len) -+#define pktq_max(pq) ((int)(pq)->max) -+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -+#define pktq_full(pq) ((pq)->len >= (pq)->max) -+#define pktq_empty(pq) ((pq)->len == 0) -+ -+/* operations for single precedence queues */ -+#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p)) -+#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p)) -+#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0) -+#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0) -+#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len) -+ -+extern void pktq_init(struct pktq *pq, int num_prec, int max_len); -+extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len); -+ -+/* prec_out may be NULL if caller is not interested in return value */ -+extern void *pktq_deq(struct pktq *pq, int *prec_out); -+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -+extern void *pktq_peek(struct pktq *pq, int *prec_out); -+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); -+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); -+ -+/* externs */ -+/* packet */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *p); -+extern void *pktlast(osl_t *osh, void *p); -+extern uint pktsegcnt(osl_t *osh, void *p); -+extern uint pktsegcnt_war(osl_t *osh, void *p); -+extern uint8 *pktoffset(osl_t *osh, void *p, uint offset); -+ -+/* Get priority from a packet and pass it back in scb (or equiv) */ -+#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */ -+#define PKTPRIO_VLAN 0x200 /* VLAN prio found */ -+#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */ -+#define PKTPRIO_DSCP 0x800 /* DSCP prio found */ -+ -+extern uint pktsetprio(void *pkt, bool update_vtag); -+ -+/* string */ -+extern int bcm_atoi(const char *s); -+extern ulong bcm_strtoul(const char *cp, char **endp, uint base); -+extern char *bcmstrstr(const char *haystack, const char *needle); -+extern char *bcmstrcat(char *dest, const char *src); -+extern char *bcmstrncat(char *dest, const char *src, uint size); -+extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -+char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); -+int bcmstricmp(const char *s1, const char *s2); -+int bcmstrnicmp(const char* s1, const char* s2, int cnt); -+ -+ -+/* ethernet address */ -+extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -+extern int bcm_ether_atoe(const char *p, struct ether_addr *ea); -+ -+/* ip address */ -+struct ipv4_addr; -+extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); -+ -+/* delay */ -+extern void bcm_mdelay(uint ms); -+/* variable access */ -+#define NVRAM_RECLAIM_CHECK(name) -+ -+extern char *getvar(char *vars, const char *name); -+extern int getintvar(char *vars, const char *name); -+extern int getintvararray(char *vars, const char *name, int index); -+extern int getintvararraysize(char *vars, const char *name); -+extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -+#define bcm_perf_enable() -+#define bcmstats(fmt) -+#define bcmlog(fmt, a1, a2) -+#define bcmdumplog(buf, size) *buf = '\0' -+#define bcmdumplogent(buf, idx) -1 -+ -+#define bcmtslog(tstamp, fmt, a1, a2) -+#define bcmprinttslogs() -+#define bcmprinttstamp(us) -+#define bcmdumptslog(buf, size) -+ -+extern char *bcm_nvram_vars(uint *length); -+extern int bcm_nvram_cache(void *sih); -+ -+/* Support for sharing code across in-driver iovar implementations. -+ * The intent is that a driver use this structure to map iovar names -+ * to its (private) iovar identifiers, and the lookup function to -+ * find the entry. Macros are provided to map ids and get/set actions -+ * into a single number space for a switch statement. -+ */ -+ -+/* iovar structure */ -+typedef struct bcm_iovar { -+ const char *name; /* name for lookup and display */ -+ uint16 varid; /* id for switch */ -+ uint16 flags; /* driver-specific flag bits */ -+ uint16 type; /* base type of argument */ -+ uint16 minlen; /* min length for buffer vars */ -+} bcm_iovar_t; -+ -+/* varid definitions are per-driver, may use these get/set bits */ -+ -+/* IOVar action bits for id mapping */ -+#define IOV_GET 0 /* Get an iovar */ -+#define IOV_SET 1 /* Set an iovar */ -+ -+/* Varid to actionid mapping */ -+#define IOV_GVAL(id) ((id) * 2) -+#define IOV_SVAL(id) ((id) * 2 + IOV_SET) -+#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) -+#define IOV_ID(actionid) (actionid >> 1) -+ -+/* flags are per-driver based on driver attributes */ -+ -+extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); -+extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); -+#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ -+ defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -+extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); -+#endif -+#endif /* BCMDRIVER */ -+ -+/* Base type definitions */ -+#define IOVT_VOID 0 /* no value (implictly set only) */ -+#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ -+#define IOVT_INT8 2 /* integer values are range-checked */ -+#define IOVT_UINT8 3 /* unsigned int 8 bits */ -+#define IOVT_INT16 4 /* int 16 bits */ -+#define IOVT_UINT16 5 /* unsigned int 16 bits */ -+#define IOVT_INT32 6 /* int 32 bits */ -+#define IOVT_UINT32 7 /* unsigned int 32 bits */ -+#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ -+#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) -+ -+/* Initializer for IOV type strings */ -+#define BCM_IOV_TYPE_INIT { \ -+ "void", \ -+ "bool", \ -+ "int8", \ -+ "uint8", \ -+ "int16", \ -+ "uint16", \ -+ "int32", \ -+ "uint32", \ -+ "buffer", \ -+ "" } -+ -+#define BCM_IOVT_IS_INT(type) (\ -+ (type == IOVT_BOOL) || \ -+ (type == IOVT_INT8) || \ -+ (type == IOVT_UINT8) || \ -+ (type == IOVT_INT16) || \ -+ (type == IOVT_UINT16) || \ -+ (type == IOVT_INT32) || \ -+ (type == IOVT_UINT32)) -+ -+/* ** driver/apps-shared section ** */ -+ -+#define BCME_STRLEN 64 /* Max string length for BCM errors */ -+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) -+ -+ -+/* -+ * error codes could be added but the defined ones shouldn't be changed/deleted -+ * these error codes are exposed to the user code -+ * when ever a new error code is added to this list -+ * please update errorstring table with the related error string and -+ * update osl files with os specific errorcode map -+*/ -+ -+#define BCME_OK 0 /* Success */ -+#define BCME_ERROR -1 /* Error generic */ -+#define BCME_BADARG -2 /* Bad Argument */ -+#define BCME_BADOPTION -3 /* Bad option */ -+#define BCME_NOTUP -4 /* Not up */ -+#define BCME_NOTDOWN -5 /* Not down */ -+#define BCME_NOTAP -6 /* Not AP */ -+#define BCME_NOTSTA -7 /* Not STA */ -+#define BCME_BADKEYIDX -8 /* BAD Key Index */ -+#define BCME_RADIOOFF -9 /* Radio Off */ -+#define BCME_NOTBANDLOCKED -10 /* Not band locked */ -+#define BCME_NOCLK -11 /* No Clock */ -+#define BCME_BADRATESET -12 /* BAD Rate valueset */ -+#define BCME_BADBAND -13 /* BAD Band */ -+#define BCME_BUFTOOSHORT -14 /* Buffer too short */ -+#define BCME_BUFTOOLONG -15 /* Buffer too long */ -+#define BCME_BUSY -16 /* Busy */ -+#define BCME_NOTASSOCIATED -17 /* Not Associated */ -+#define BCME_BADSSIDLEN -18 /* Bad SSID len */ -+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ -+#define BCME_BADCHAN -20 /* Bad Channel */ -+#define BCME_BADADDR -21 /* Bad Address */ -+#define BCME_NORESOURCE -22 /* Not Enough Resources */ -+#define BCME_UNSUPPORTED -23 /* Unsupported */ -+#define BCME_BADLEN -24 /* Bad length */ -+#define BCME_NOTREADY -25 /* Not Ready */ -+#define BCME_EPERM -26 /* Not Permitted */ -+#define BCME_NOMEM -27 /* No Memory */ -+#define BCME_ASSOCIATED -28 /* Associated */ -+#define BCME_RANGE -29 /* Not In Range */ -+#define BCME_NOTFOUND -30 /* Not Found */ -+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ -+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ -+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ -+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ -+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ -+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ -+#define BCME_VERSION -37 /* Incorrect version */ -+#define BCME_TXFAIL -38 /* TX failure */ -+#define BCME_RXFAIL -39 /* RX failure */ -+#define BCME_NODEVICE -40 /* Device not present */ -+#define BCME_NMODE_DISABLED -41 /* NMODE disabled */ -+#define BCME_NONRESIDENT -42 /* access to nonresident overlay */ -+#define BCME_LAST BCME_NONRESIDENT -+ -+/* These are collection of BCME Error strings */ -+#define BCMERRSTRINGTABLE { \ -+ "OK", \ -+ "Undefined error", \ -+ "Bad Argument", \ -+ "Bad Option", \ -+ "Not up", \ -+ "Not down", \ -+ "Not AP", \ -+ "Not STA", \ -+ "Bad Key Index", \ -+ "Radio Off", \ -+ "Not band locked", \ -+ "No clock", \ -+ "Bad Rate valueset", \ -+ "Bad Band", \ -+ "Buffer too short", \ -+ "Buffer too long", \ -+ "Busy", \ -+ "Not Associated", \ -+ "Bad SSID len", \ -+ "Out of Range Channel", \ -+ "Bad Channel", \ -+ "Bad Address", \ -+ "Not Enough Resources", \ -+ "Unsupported", \ -+ "Bad length", \ -+ "Not Ready", \ -+ "Not Permitted", \ -+ "No Memory", \ -+ "Associated", \ -+ "Not In Range", \ -+ "Not Found", \ -+ "WME Not Enabled", \ -+ "TSPEC Not Found", \ -+ "ACM Not Supported", \ -+ "Not WME Association", \ -+ "SDIO Bus Error", \ -+ "Dongle Not Accessible", \ -+ "Incorrect version", \ -+ "TX Failure", \ -+ "RX Failure", \ -+ "Device Not Present", \ -+ "NMODE Disabled", \ -+ "Nonresident overlay access", \ -+} -+ -+#ifndef ABS -+#define ABS(a) (((a) < 0) ? -(a) : (a)) -+#endif /* ABS */ -+ -+#ifndef MIN -+#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -+#endif /* MIN */ -+ -+#ifndef MAX -+#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -+#endif /* MAX */ -+ -+#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) -+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -+#define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0) -+#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ -+ & ~((boundary) - 1)) -+#define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \ -+ & ~((boundary) - 1)) -+#define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0) -+#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -+ -+#ifndef OFFSETOF -+#ifdef __ARMCC_VERSION -+/* -+ * The ARM RVCT compiler complains when using OFFSETOF where a constant -+ * expression is expected, such as an initializer for a static object. -+ * offsetof from the runtime library doesn't have that problem. -+ */ -+#include -+#define OFFSETOF(type, member) offsetof(type, member) -+#else -+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -+#endif /* __ARMCC_VERSION */ -+#endif /* OFFSETOF */ -+ -+#ifndef ARRAYSIZE -+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) -+#endif -+ -+/* Reference a function; used to prevent a static function from being optimized out */ -+extern void *_bcmutils_dummy_fn; -+#define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f)) -+ -+/* bit map related macros */ -+#ifndef setbit -+#ifndef NBBY /* the BSD family defines NBBY */ -+#define NBBY 8 /* 8 bits per byte */ -+#endif /* #ifndef NBBY */ -+#define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY)) -+#define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY))) -+#define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) -+#define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0) -+#endif /* setbit */ -+ -+#define NBITS(type) (sizeof(type) * 8) -+#define NBITVAL(nbits) (1 << (nbits)) -+#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -+#define NBITMASK(nbits) MAXBITVAL(nbits) -+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) -+ -+/* basic mux operation - can be optimized on several architectures */ -+#define MUX(pred, true, false) ((pred) ? (true) : (false)) -+ -+/* modulo inc/dec - assumes x E [0, bound - 1] */ -+#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -+#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) -+ -+/* modulo inc/dec, bound = 2^k */ -+#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -+#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) -+ -+/* modulo add/sub - assumes x, y E [0, bound - 1] */ -+#define MODADD(x, y, bound) \ -+ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -+#define MODSUB(x, y, bound) \ -+ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) -+ -+/* module add/sub, bound = 2^k */ -+#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -+#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) -+ -+/* crc defines */ -+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ -+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ -+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ -+ -+/* use for direct output of MAC address in printf etc */ -+#define MACF "%02x:%02x:%02x:%02x:%02x:%02x" -+#define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \ -+ ((struct ether_addr *) (ea))->octet[1], \ -+ ((struct ether_addr *) (ea))->octet[2], \ -+ ((struct ether_addr *) (ea))->octet[3], \ -+ ((struct ether_addr *) (ea))->octet[4], \ -+ ((struct ether_addr *) (ea))->octet[5] -+ -+#define ETHER_TO_MACF(ea) (ea).octet[0], \ -+ (ea).octet[1], \ -+ (ea).octet[2], \ -+ (ea).octet[3], \ -+ (ea).octet[4], \ -+ (ea).octet[5] -+#if !defined(SIMPLE_MAC_PRINT) -+#define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x" -+#define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5] -+#else -+#define MACDBG "%02x:%02x:%02x" -+#define MAC2STRDBG(ea) (ea)[0], (ea)[4], (ea)[5] -+#endif /* SIMPLE_MAC_PRINT */ -+ -+/* bcm_format_flags() bit description structure */ -+typedef struct bcm_bit_desc { -+ uint32 bit; -+ const char* name; -+} bcm_bit_desc_t; -+ -+/* tag_ID/length/value_buffer tuple */ -+typedef struct bcm_tlv { -+ uint8 id; -+ uint8 len; -+ uint8 data[1]; -+} bcm_tlv_t; -+ -+/* Check that bcm_tlv_t fits into the given buflen */ -+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) -+ -+/* buffer length for ethernet address from bcm_ether_ntoa() */ -+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ -+ -+/* crypto utility function */ -+/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */ -+static INLINE void -+xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) -+{ -+ if ( -+#ifdef __i386__ -+ 1 || -+#endif -+ (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { -+ /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */ -+ /* x86 supports unaligned. This version runs 6x-9x faster on x86. */ -+ ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0]; -+ ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1]; -+ ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2]; -+ ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3]; -+ } else { -+ /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */ -+ int k; -+ for (k = 0; k < 16; k++) -+ dst[k] = src1[k] ^ src2[k]; -+ } -+} -+ -+/* externs */ -+/* crc */ -+extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); -+extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); -+extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); -+ -+/* format/print */ -+#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ -+ defined(WLMSG_ASSOC) -+extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); -+#endif -+ -+#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ -+ defined(WLMSG_ASSOC) || defined(WLMEDIA_PEAKRATE) -+extern int bcm_format_hex(char *str, const void *bytes, int len); -+#endif -+ -+extern const char *bcm_crypto_algo_name(uint algo); -+extern char *bcm_chipname(uint chipid, char *buf, uint len); -+extern char *bcm_brev_str(uint32 brev, char *buf); -+extern void printbig(char *buf); -+extern void prhex(const char *msg, uchar *buf, uint len); -+ -+/* IE parsing */ -+extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); -+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -+extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); -+ -+/* bcmerror */ -+extern const char *bcmerrorstr(int bcmerror); -+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -+ -+/* multi-bool data type: set of bools, mbool is true if any is set */ -+typedef uint32 mbool; -+#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ -+#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ -+#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */ -+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) -+ -+/* generic datastruct to help dump routines */ -+struct fielddesc { -+ const char *nameandfmt; -+ uint32 offset; -+ uint32 len; -+}; -+ -+extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -+extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len); -+ -+extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -+extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes); -+extern void bcm_print_bytes(const char *name, const uchar *cdata, int len); -+ -+typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); -+extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, -+ char *buf, uint32 bufsize); -+extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); -+ -+extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -+ -+/* power conversion */ -+extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -+extern uint8 bcm_mw_to_qdbm(uint16 mw); -+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); -+ -+unsigned int process_nvram_vars(char *varbuf, unsigned int len); -+ -+#ifdef __cplusplus -+ } -+#endif -+ -+#endif /* _bcmutils_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmwifi_channels.h b/drivers/net/wireless/ap6210/include/bcmwifi_channels.h -new file mode 100644 -index 0000000..bc57aca ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmwifi_channels.h -@@ -0,0 +1,490 @@ -+/* -+ * Misc utility routines for WL and Apps -+ * This header file housing the define and function prototype use by -+ * both the wl driver, tools & Apps. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _bcmwifi_channels_h_ -+#define _bcmwifi_channels_h_ -+ -+ -+/* A chanspec holds the channel number, band, bandwidth and control sideband */ -+typedef uint16 chanspec_t; -+ -+/* channel defines */ -+#define CH_UPPER_SB 0x01 -+#define CH_LOWER_SB 0x02 -+#define CH_EWA_VALID 0x04 -+#define CH_80MHZ_APART 16 -+#define CH_40MHZ_APART 8 -+#define CH_20MHZ_APART 4 -+#define CH_10MHZ_APART 2 -+#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ -+#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ -+#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216, -+ * this is that + 1 rounded up to a multiple of NBBY (8). -+ * DO NOT MAKE it > 255: channels are uint8's all over -+ */ -+#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep) -+ -+/* All builds use the new 11ac ratespec/chanspec */ -+#undef D11AC_IOTYPES -+#define D11AC_IOTYPES -+ -+#ifndef D11AC_IOTYPES -+ -+#define WL_CHANSPEC_CHAN_MASK 0x00ff -+#define WL_CHANSPEC_CHAN_SHIFT 0 -+ -+#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -+#define WL_CHANSPEC_CTL_SB_SHIFT 8 -+#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -+#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -+#define WL_CHANSPEC_CTL_SB_NONE 0x0300 -+ -+#define WL_CHANSPEC_BW_MASK 0x0C00 -+#define WL_CHANSPEC_BW_SHIFT 10 -+#define WL_CHANSPEC_BW_10 0x0400 -+#define WL_CHANSPEC_BW_20 0x0800 -+#define WL_CHANSPEC_BW_40 0x0C00 -+ -+#define WL_CHANSPEC_BAND_MASK 0xf000 -+#define WL_CHANSPEC_BAND_SHIFT 12 -+#ifdef WL_CHANSPEC_BAND_5G -+#undef WL_CHANSPEC_BAND_5G -+#endif -+#ifdef WL_CHANSPEC_BAND_2G -+#undef WL_CHANSPEC_BAND_2G -+#endif -+#define WL_CHANSPEC_BAND_5G 0x1000 -+#define WL_CHANSPEC_BAND_2G 0x2000 -+#define INVCHANSPEC 255 -+ -+/* channel defines */ -+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) -+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ -+ ((channel) + CH_10MHZ_APART) : 0) -+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ -+ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ -+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ -+ ((channel) + CH_20MHZ_APART) : 0) -+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) -+ -+/* chanspec stores radio channel & flags to indicate control channel location, i.e. upper/lower */ -+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) -+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) -+ -+#ifdef WL11N_20MHZONLY -+ -+#define CHSPEC_IS10(chspec) 0 -+#define CHSPEC_IS20(chspec) 1 -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) 0 -+#endif -+ -+#else /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -+#endif -+ -+#endif /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -+#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -+#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -+#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -+#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ -+ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ -+ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) -+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) -+ -+#define CHANSPEC_STR_LEN 8 -+ -+#else /* D11AC_IOTYPES */ -+ -+#define WL_CHANSPEC_CHAN_MASK 0x00ff -+#define WL_CHANSPEC_CHAN_SHIFT 0 -+#define WL_CHANSPEC_CHAN1_MASK 0x000f -+#define WL_CHANSPEC_CHAN1_SHIFT 0 -+#define WL_CHANSPEC_CHAN2_MASK 0x00f0 -+#define WL_CHANSPEC_CHAN2_SHIFT 4 -+ -+#define WL_CHANSPEC_CTL_SB_MASK 0x0700 -+#define WL_CHANSPEC_CTL_SB_SHIFT 8 -+#define WL_CHANSPEC_CTL_SB_LLL 0x0000 -+#define WL_CHANSPEC_CTL_SB_LLU 0x0100 -+#define WL_CHANSPEC_CTL_SB_LUL 0x0200 -+#define WL_CHANSPEC_CTL_SB_LUU 0x0300 -+#define WL_CHANSPEC_CTL_SB_ULL 0x0400 -+#define WL_CHANSPEC_CTL_SB_ULU 0x0500 -+#define WL_CHANSPEC_CTL_SB_UUL 0x0600 -+#define WL_CHANSPEC_CTL_SB_UUU 0x0700 -+#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU -+#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL -+#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU -+#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU -+#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU -+ -+#define WL_CHANSPEC_BW_MASK 0x3800 -+#define WL_CHANSPEC_BW_SHIFT 11 -+#define WL_CHANSPEC_BW_5 0x0000 -+#define WL_CHANSPEC_BW_10 0x0800 -+#define WL_CHANSPEC_BW_20 0x1000 -+#define WL_CHANSPEC_BW_40 0x1800 -+#define WL_CHANSPEC_BW_80 0x2000 -+#define WL_CHANSPEC_BW_160 0x2800 -+#define WL_CHANSPEC_BW_8080 0x3000 -+ -+#define WL_CHANSPEC_BAND_MASK 0xc000 -+#define WL_CHANSPEC_BAND_SHIFT 14 -+#define WL_CHANSPEC_BAND_2G 0x0000 -+#define WL_CHANSPEC_BAND_3G 0x4000 -+#define WL_CHANSPEC_BAND_4G 0x8000 -+#define WL_CHANSPEC_BAND_5G 0xc000 -+#define INVCHANSPEC 255 -+ -+/* channel defines */ -+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \ -+ ((channel) - CH_10MHZ_APART) : 0) -+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ -+ ((channel) + CH_10MHZ_APART) : 0) -+#define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART) -+#define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART) -+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ -+ (((channel) <= CH_MAX_2G_CHANNEL) ? \ -+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ -+ ((channel) + CH_20MHZ_APART) : 0) -+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | \ -+ WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G) -+#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | \ -+ WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G) -+ -+/* simple MACROs to get different fields of chanspec */ -+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -+#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) -+#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) -+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) -+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) -+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) -+ -+#ifdef WL11N_20MHZONLY -+ -+#define CHSPEC_IS10(chspec) 0 -+#define CHSPEC_IS20(chspec) 1 -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) 0 -+#endif -+#ifndef CHSPEC_IS80 -+#define CHSPEC_IS80(chspec) 0 -+#endif -+#ifndef CHSPEC_IS160 -+#define CHSPEC_IS160(chspec) 0 -+#endif -+#ifndef CHSPEC_IS8080 -+#define CHSPEC_IS8080(chspec) 0 -+#endif -+ -+#else /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -+#endif -+#ifndef CHSPEC_IS80 -+#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) -+#endif -+#ifndef CHSPEC_IS160 -+#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160) -+#endif -+#ifndef CHSPEC_IS8080 -+#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080) -+#endif -+ -+#endif /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -+#define CHSPEC_SB_UPPER(chspec) \ -+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \ -+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) -+#define CHSPEC_SB_LOWER(chspec) \ -+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \ -+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) -+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) -+ -+/** -+ * Number of chars needed for wf_chspec_ntoa() destination character buffer. -+ */ -+#define CHANSPEC_STR_LEN 20 -+ -+ -+/* Legacy Chanspec defines -+ * These are the defines for the previous format of the chanspec_t -+ */ -+#define WL_LCHANSPEC_CHAN_MASK 0x00ff -+#define WL_LCHANSPEC_CHAN_SHIFT 0 -+ -+#define WL_LCHANSPEC_CTL_SB_MASK 0x0300 -+#define WL_LCHANSPEC_CTL_SB_SHIFT 8 -+#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100 -+#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200 -+#define WL_LCHANSPEC_CTL_SB_NONE 0x0300 -+ -+#define WL_LCHANSPEC_BW_MASK 0x0C00 -+#define WL_LCHANSPEC_BW_SHIFT 10 -+#define WL_LCHANSPEC_BW_10 0x0400 -+#define WL_LCHANSPEC_BW_20 0x0800 -+#define WL_LCHANSPEC_BW_40 0x0C00 -+ -+#define WL_LCHANSPEC_BAND_MASK 0xf000 -+#define WL_LCHANSPEC_BAND_SHIFT 12 -+#define WL_LCHANSPEC_BAND_5G 0x1000 -+#define WL_LCHANSPEC_BAND_2G 0x2000 -+ -+#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK)) -+#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK) -+#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK) -+#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK) -+#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10) -+#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20) -+#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40) -+#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G) -+#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G) -+ -+#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) -+ -+#endif /* D11AC_IOTYPES */ -+ -+/* -+ * WF_CHAN_FACTOR_* constants are used to calculate channel frequency -+ * given a channel number. -+ * chan_freq = chan_factor * 500Mhz + chan_number * 5 -+ */ -+ -+/** -+ * Channel Factor for the starting frequence of 2.4 GHz channels. -+ * The value corresponds to 2407 MHz. -+ */ -+#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */ -+ -+/** -+ * Channel Factor for the starting frequence of 5 GHz channels. -+ * The value corresponds to 5000 MHz. -+ */ -+#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */ -+ -+/** -+ * Channel Factor for the starting frequence of 4.9 GHz channels. -+ * The value corresponds to 4000 MHz. -+ */ -+#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ -+ -+/* defined rate in 500kbps */ -+#define WLC_MAXRATE 108 /* in 500kbps units */ -+#define WLC_RATE_1M 2 /* in 500kbps units */ -+#define WLC_RATE_2M 4 /* in 500kbps units */ -+#define WLC_RATE_5M5 11 /* in 500kbps units */ -+#define WLC_RATE_11M 22 /* in 500kbps units */ -+#define WLC_RATE_6M 12 /* in 500kbps units */ -+#define WLC_RATE_9M 18 /* in 500kbps units */ -+#define WLC_RATE_12M 24 /* in 500kbps units */ -+#define WLC_RATE_18M 36 /* in 500kbps units */ -+#define WLC_RATE_24M 48 /* in 500kbps units */ -+#define WLC_RATE_36M 72 /* in 500kbps units */ -+#define WLC_RATE_48M 96 /* in 500kbps units */ -+#define WLC_RATE_54M 108 /* in 500kbps units */ -+ -+#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ -+ -+/** -+ * Convert chanspec to ascii string -+ * -+ * @param chspec chanspec format -+ * @param buf ascii string of chanspec -+ * -+ * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes -+ * -+ * @see CHANSPEC_STR_LEN -+ */ -+extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); -+ -+/** -+ * Convert ascii string to chanspec -+ * -+ * @param a pointer to input string -+ * -+ * @return >= 0 if successful or 0 otherwise -+ */ -+extern chanspec_t wf_chspec_aton(const char *a); -+ -+/** -+ * Verify the chanspec fields are valid. -+ * -+ * Verify the chanspec is using a legal set field values, i.e. that the chanspec -+ * specified a band, bw, ctl_sb and channel and that the combination could be -+ * legal given some set of circumstances. -+ * -+ * @param chanspec input chanspec to verify -+ * -+ * @return TRUE if the chanspec is malformed, FALSE if it looks good. -+ */ -+extern bool wf_chspec_malformed(chanspec_t chanspec); -+ -+/** -+ * Verify the chanspec specifies a valid channel according to 802.11. -+ * -+ * @param chanspec input chanspec to verify -+ * -+ * @return TRUE if the chanspec is a valid 802.11 channel -+ */ -+extern bool wf_chspec_valid(chanspec_t chanspec); -+ -+/** -+ * Return the primary (control) channel. -+ * -+ * This function returns the channel number of the primary 20MHz channel. For -+ * 20MHz channels this is just the channel number. For 40MHz or wider channels -+ * it is the primary 20MHz channel specified by the chanspec. -+ * -+ * @param chspec input chanspec -+ * -+ * @return Returns the channel number of the primary 20MHz channel -+ */ -+extern uint8 wf_chspec_ctlchan(chanspec_t chspec); -+ -+/** -+ * Return the primary (control) chanspec. -+ * -+ * This function returns the chanspec of the primary 20MHz channel. For 20MHz -+ * channels this is just the chanspec. For 40MHz or wider channels it is the -+ * chanspec of the primary 20MHZ channel specified by the chanspec. -+ * -+ * @param chspec input chanspec -+ * -+ * @return Returns the chanspec of the primary 20MHz channel -+ */ -+extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); -+ -+/** -+ * Return a channel number corresponding to a frequency. -+ * -+ * This function returns the chanspec for the primary 40MHz of an 80MHz channel. -+ * The control sideband specifies the same 20MHz channel that the 80MHz channel is using -+ * as the primary 20MHz channel. -+ */ -+extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec); -+ -+/* -+ * Return the channel number for a given frequency and base frequency. -+ * The returned channel number is relative to the given base frequency. -+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for -+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz. -+ * -+ * Frequency is specified in MHz. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for -+ * 2.4 GHz and 5 GHz bands. -+ * -+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band -+ * and [0, 200] otherwise. -+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the -+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even -+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ * -+ * @param freq frequency in MHz -+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz -+ * -+ * @return Returns a channel number -+ * -+ * @see WF_CHAN_FACTOR_2_4_G -+ * @see WF_CHAN_FACTOR_5_G -+ */ -+extern int wf_mhz2channel(uint freq, uint start_factor); -+ -+/** -+ * Return the center frequency in MHz of the given channel and base frequency. -+ * -+ * Return the center frequency in MHz of the given channel and base frequency. -+ * The channel number is interpreted relative to the given base frequency. -+ * -+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for -+ * 2.4 GHz and 5 GHz bands. -+ * The channel range of [1, 14] is only checked for a start_factor of -+ * WF_CHAN_FACTOR_2_4_G (4814). -+ * Odd start_factors produce channels on .5 MHz boundaries, in which case -+ * the answer is rounded down to an integral MHz. -+ * -1 is returned for an out of range channel. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ * -+ * @param channel input channel number -+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz -+ * -+ * @return Returns a frequency in MHz -+ * -+ * @see WF_CHAN_FACTOR_2_4_G -+ * @see WF_CHAN_FACTOR_5_G -+ */ -+extern int wf_channel2mhz(uint channel, uint start_factor); -+ -+/** -+ * Convert ctl chan and bw to chanspec -+ * -+ * @param ctl_ch channel -+ * @param bw bandwidth -+ * -+ * @return > 0 if successful or 0 otherwise -+ * -+ */ -+extern uint16 wf_channel2chspec(uint ctl_ch, uint bw); -+ -+#endif /* _bcmwifi_channels_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/bcmwifi_rates.h b/drivers/net/wireless/ap6210/include/bcmwifi_rates.h -new file mode 100644 -index 0000000..ddc6ab5 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/bcmwifi_rates.h -@@ -0,0 +1,318 @@ -+/* -+ * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmwifi_rates.h 252708 2011-04-12 06:45:56Z $ -+ */ -+ -+#ifndef _bcmwifi_rates_h_ -+#define _bcmwifi_rates_h_ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif /* __cplusplus */ -+ -+ -+#define WL_RATESET_SZ_DSSS 4 -+#define WL_RATESET_SZ_OFDM 8 -+#define WL_RATESET_SZ_HT_MCS 8 -+#define WL_RATESET_SZ_VHT_MCS 10 -+ -+#define WL_TX_CHAINS_MAX 3 -+ -+#define WL_RATE_DISABLED (-128) /* Power value corresponding to unsupported rate */ -+ -+/* Transmit channel bandwidths */ -+typedef enum wl_tx_bw { -+ WL_TX_BW_20, -+ WL_TX_BW_40, -+ WL_TX_BW_80, -+ WL_TX_BW_20IN40, -+ WL_TX_BW_20IN80, -+ WL_TX_BW_40IN80, -+ WL_TX_BW_ALL -+} wl_tx_bw_t; -+ -+ -+/* -+ * Transmit modes. -+ * Not all modes are listed here, only those required for disambiguation. e.g. SPEXP is not listed -+ */ -+typedef enum wl_tx_mode { -+ WL_TX_MODE_NONE, -+ WL_TX_MODE_STBC, -+ WL_TX_MODE_CDD, -+ WL_TX_MODE_SDM -+} wl_tx_mode_t; -+ -+ -+/* Number of transmit chains */ -+typedef enum wl_tx_chains { -+ WL_TX_CHAINS_1 = 1, -+ WL_TX_CHAINS_2, -+ WL_TX_CHAINS_3 -+} wl_tx_chains_t; -+ -+ -+/* Number of transmit streams */ -+typedef enum wl_tx_nss { -+ WL_TX_NSS_1 = 1, -+ WL_TX_NSS_2, -+ WL_TX_NSS_3 -+} wl_tx_nss_t; -+ -+ -+typedef enum clm_rates { -+ /************ -+ * 1 chain * -+ ************ -+ */ -+ -+ /* 1 Stream */ -+ WL_RATE_1X1_DSSS_1 = 0, -+ WL_RATE_1X1_DSSS_2 = 1, -+ WL_RATE_1X1_DSSS_5_5 = 2, -+ WL_RATE_1X1_DSSS_11 = 3, -+ -+ WL_RATE_1X1_OFDM_6 = 4, -+ WL_RATE_1X1_OFDM_9 = 5, -+ WL_RATE_1X1_OFDM_12 = 6, -+ WL_RATE_1X1_OFDM_18 = 7, -+ WL_RATE_1X1_OFDM_24 = 8, -+ WL_RATE_1X1_OFDM_36 = 9, -+ WL_RATE_1X1_OFDM_48 = 10, -+ WL_RATE_1X1_OFDM_54 = 11, -+ -+ WL_RATE_1X1_MCS0 = 12, -+ WL_RATE_1X1_MCS1 = 13, -+ WL_RATE_1X1_MCS2 = 14, -+ WL_RATE_1X1_MCS3 = 15, -+ WL_RATE_1X1_MCS4 = 16, -+ WL_RATE_1X1_MCS5 = 17, -+ WL_RATE_1X1_MCS6 = 18, -+ WL_RATE_1X1_MCS7 = 19, -+ -+ WL_RATE_1X1_VHT0SS1 = 12, -+ WL_RATE_1X1_VHT1SS1 = 13, -+ WL_RATE_1X1_VHT2SS1 = 14, -+ WL_RATE_1X1_VHT3SS1 = 15, -+ WL_RATE_1X1_VHT4SS1 = 16, -+ WL_RATE_1X1_VHT5SS1 = 17, -+ WL_RATE_1X1_VHT6SS1 = 18, -+ WL_RATE_1X1_VHT7SS1 = 19, -+ WL_RATE_1X1_VHT8SS1 = 20, -+ WL_RATE_1X1_VHT9SS1 = 21, -+ -+ -+ /************ -+ * 2 chains * -+ ************ -+ */ -+ -+ /* 1 Stream expanded + 1 */ -+ WL_RATE_1X2_DSSS_1 = 22, -+ WL_RATE_1X2_DSSS_2 = 23, -+ WL_RATE_1X2_DSSS_5_5 = 24, -+ WL_RATE_1X2_DSSS_11 = 25, -+ -+ WL_RATE_1X2_CDD_OFDM_6 = 26, -+ WL_RATE_1X2_CDD_OFDM_9 = 27, -+ WL_RATE_1X2_CDD_OFDM_12 = 28, -+ WL_RATE_1X2_CDD_OFDM_18 = 29, -+ WL_RATE_1X2_CDD_OFDM_24 = 30, -+ WL_RATE_1X2_CDD_OFDM_36 = 31, -+ WL_RATE_1X2_CDD_OFDM_48 = 32, -+ WL_RATE_1X2_CDD_OFDM_54 = 33, -+ -+ WL_RATE_1X2_CDD_MCS0 = 34, -+ WL_RATE_1X2_CDD_MCS1 = 35, -+ WL_RATE_1X2_CDD_MCS2 = 36, -+ WL_RATE_1X2_CDD_MCS3 = 37, -+ WL_RATE_1X2_CDD_MCS4 = 38, -+ WL_RATE_1X2_CDD_MCS5 = 39, -+ WL_RATE_1X2_CDD_MCS6 = 40, -+ WL_RATE_1X2_CDD_MCS7 = 41, -+ -+ WL_RATE_1X2_VHT0SS1 = 34, -+ WL_RATE_1X2_VHT1SS1 = 35, -+ WL_RATE_1X2_VHT2SS1 = 36, -+ WL_RATE_1X2_VHT3SS1 = 37, -+ WL_RATE_1X2_VHT4SS1 = 38, -+ WL_RATE_1X2_VHT5SS1 = 39, -+ WL_RATE_1X2_VHT6SS1 = 40, -+ WL_RATE_1X2_VHT7SS1 = 41, -+ WL_RATE_1X2_VHT8SS1 = 42, -+ WL_RATE_1X2_VHT9SS1 = 43, -+ -+ /* 2 Streams */ -+ WL_RATE_2X2_STBC_MCS0 = 44, -+ WL_RATE_2X2_STBC_MCS1 = 45, -+ WL_RATE_2X2_STBC_MCS2 = 46, -+ WL_RATE_2X2_STBC_MCS3 = 47, -+ WL_RATE_2X2_STBC_MCS4 = 48, -+ WL_RATE_2X2_STBC_MCS5 = 49, -+ WL_RATE_2X2_STBC_MCS6 = 50, -+ WL_RATE_2X2_STBC_MCS7 = 51, -+ -+ WL_RATE_2X2_STBC_VHT0SS1 = 44, -+ WL_RATE_2X2_STBC_VHT1SS1 = 45, -+ WL_RATE_2X2_STBC_VHT2SS1 = 46, -+ WL_RATE_2X2_STBC_VHT3SS1 = 47, -+ WL_RATE_2X2_STBC_VHT4SS1 = 48, -+ WL_RATE_2X2_STBC_VHT5SS1 = 49, -+ WL_RATE_2X2_STBC_VHT6SS1 = 50, -+ WL_RATE_2X2_STBC_VHT7SS1 = 51, -+ WL_RATE_2X2_STBC_VHT8SS1 = 52, -+ WL_RATE_2X2_STBC_VHT9SS1 = 53, -+ -+ WL_RATE_2X2_SDM_MCS8 = 54, -+ WL_RATE_2X2_SDM_MCS9 = 55, -+ WL_RATE_2X2_SDM_MCS10 = 56, -+ WL_RATE_2X2_SDM_MCS11 = 57, -+ WL_RATE_2X2_SDM_MCS12 = 58, -+ WL_RATE_2X2_SDM_MCS13 = 59, -+ WL_RATE_2X2_SDM_MCS14 = 60, -+ WL_RATE_2X2_SDM_MCS15 = 61, -+ -+ WL_RATE_2X2_VHT0SS2 = 54, -+ WL_RATE_2X2_VHT1SS2 = 55, -+ WL_RATE_2X2_VHT2SS2 = 56, -+ WL_RATE_2X2_VHT3SS2 = 57, -+ WL_RATE_2X2_VHT4SS2 = 58, -+ WL_RATE_2X2_VHT5SS2 = 59, -+ WL_RATE_2X2_VHT6SS2 = 60, -+ WL_RATE_2X2_VHT7SS2 = 61, -+ WL_RATE_2X2_VHT8SS2 = 62, -+ WL_RATE_2X2_VHT9SS2 = 63, -+ -+ -+ /************ -+ * 3 chains * -+ ************ -+ */ -+ -+ /* 1 Stream expanded + 2 */ -+ WL_RATE_1X3_DSSS_1 = 64, -+ WL_RATE_1X3_DSSS_2 = 65, -+ WL_RATE_1X3_DSSS_5_5 = 66, -+ WL_RATE_1X3_DSSS_11 = 67, -+ -+ WL_RATE_1X3_CDD_OFDM_6 = 68, -+ WL_RATE_1X3_CDD_OFDM_9 = 69, -+ WL_RATE_1X3_CDD_OFDM_12 = 70, -+ WL_RATE_1X3_CDD_OFDM_18 = 71, -+ WL_RATE_1X3_CDD_OFDM_24 = 72, -+ WL_RATE_1X3_CDD_OFDM_36 = 73, -+ WL_RATE_1X3_CDD_OFDM_48 = 74, -+ WL_RATE_1X3_CDD_OFDM_54 = 75, -+ -+ WL_RATE_1X3_CDD_MCS0 = 76, -+ WL_RATE_1X3_CDD_MCS1 = 77, -+ WL_RATE_1X3_CDD_MCS2 = 78, -+ WL_RATE_1X3_CDD_MCS3 = 79, -+ WL_RATE_1X3_CDD_MCS4 = 80, -+ WL_RATE_1X3_CDD_MCS5 = 81, -+ WL_RATE_1X3_CDD_MCS6 = 82, -+ WL_RATE_1X3_CDD_MCS7 = 83, -+ -+ WL_RATE_1X3_VHT0SS1 = 76, -+ WL_RATE_1X3_VHT1SS1 = 77, -+ WL_RATE_1X3_VHT2SS1 = 78, -+ WL_RATE_1X3_VHT3SS1 = 79, -+ WL_RATE_1X3_VHT4SS1 = 80, -+ WL_RATE_1X3_VHT5SS1 = 81, -+ WL_RATE_1X3_VHT6SS1 = 82, -+ WL_RATE_1X3_VHT7SS1 = 83, -+ WL_RATE_1X3_VHT8SS1 = 84, -+ WL_RATE_1X3_VHT9SS1 = 85, -+ -+ /* 2 Streams expanded + 1 */ -+ WL_RATE_2X3_STBC_MCS0 = 86, -+ WL_RATE_2X3_STBC_MCS1 = 87, -+ WL_RATE_2X3_STBC_MCS2 = 88, -+ WL_RATE_2X3_STBC_MCS3 = 89, -+ WL_RATE_2X3_STBC_MCS4 = 90, -+ WL_RATE_2X3_STBC_MCS5 = 91, -+ WL_RATE_2X3_STBC_MCS6 = 92, -+ WL_RATE_2X3_STBC_MCS7 = 93, -+ -+ WL_RATE_2X3_STBC_VHT0SS1 = 86, -+ WL_RATE_2X3_STBC_VHT1SS1 = 87, -+ WL_RATE_2X3_STBC_VHT2SS1 = 88, -+ WL_RATE_2X3_STBC_VHT3SS1 = 89, -+ WL_RATE_2X3_STBC_VHT4SS1 = 90, -+ WL_RATE_2X3_STBC_VHT5SS1 = 91, -+ WL_RATE_2X3_STBC_VHT6SS1 = 92, -+ WL_RATE_2X3_STBC_VHT7SS1 = 93, -+ WL_RATE_2X3_STBC_VHT8SS1 = 94, -+ WL_RATE_2X3_STBC_VHT9SS1 = 95, -+ -+ WL_RATE_2X3_SDM_MCS8 = 96, -+ WL_RATE_2X3_SDM_MCS9 = 97, -+ WL_RATE_2X3_SDM_MCS10 = 98, -+ WL_RATE_2X3_SDM_MCS11 = 99, -+ WL_RATE_2X3_SDM_MCS12 = 100, -+ WL_RATE_2X3_SDM_MCS13 = 101, -+ WL_RATE_2X3_SDM_MCS14 = 102, -+ WL_RATE_2X3_SDM_MCS15 = 103, -+ -+ WL_RATE_2X3_VHT0SS2 = 96, -+ WL_RATE_2X3_VHT1SS2 = 97, -+ WL_RATE_2X3_VHT2SS2 = 98, -+ WL_RATE_2X3_VHT3SS2 = 99, -+ WL_RATE_2X3_VHT4SS2 = 100, -+ WL_RATE_2X3_VHT5SS2 = 101, -+ WL_RATE_2X3_VHT6SS2 = 102, -+ WL_RATE_2X3_VHT7SS2 = 103, -+ WL_RATE_2X3_VHT8SS2 = 104, -+ WL_RATE_2X3_VHT9SS2 = 105, -+ -+ /* 3 Streams */ -+ WL_RATE_3X3_SDM_MCS16 = 106, -+ WL_RATE_3X3_SDM_MCS17 = 107, -+ WL_RATE_3X3_SDM_MCS18 = 108, -+ WL_RATE_3X3_SDM_MCS19 = 109, -+ WL_RATE_3X3_SDM_MCS20 = 110, -+ WL_RATE_3X3_SDM_MCS21 = 111, -+ WL_RATE_3X3_SDM_MCS22 = 112, -+ WL_RATE_3X3_SDM_MCS23 = 113, -+ -+ WL_RATE_3X3_VHT0SS3 = 106, -+ WL_RATE_3X3_VHT1SS3 = 107, -+ WL_RATE_3X3_VHT2SS3 = 108, -+ WL_RATE_3X3_VHT3SS3 = 109, -+ WL_RATE_3X3_VHT4SS3 = 110, -+ WL_RATE_3X3_VHT5SS3 = 111, -+ WL_RATE_3X3_VHT6SS3 = 112, -+ WL_RATE_3X3_VHT7SS3 = 113, -+ WL_RATE_3X3_VHT8SS3 = 114, -+ WL_RATE_3X3_VHT9SS3 = 115, -+ -+ /* Number of rate codes */ -+ WL_NUMRATES = 116 -+} clm_rates_t; -+ -+#ifdef __cplusplus -+} -+#endif /* __cplusplus */ -+ -+#endif /* _bcmwifi_rates_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/dhdioctl.h b/drivers/net/wireless/ap6210/include/dhdioctl.h -new file mode 100644 -index 0000000..6909dc2 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/dhdioctl.h -@@ -0,0 +1,136 @@ -+/* -+ * Definitions for ioctls to access DHD iovars. -+ * Based on wlioctl.h (for Broadcom 802.11abg driver). -+ * (Moves towards generic ioctls for BCM drivers/iovars.) -+ * -+ * Definitions subject to change without notice. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhdioctl.h 354894 2012-09-04 12:34:07Z $ -+ */ -+ -+#ifndef _dhdioctl_h_ -+#define _dhdioctl_h_ -+ -+#include -+ -+ -+/* require default structure packing */ -+#define BWL_DEFAULT_PACKING -+#include -+ -+ -+/* Linux network driver ioctl encoding */ -+typedef struct dhd_ioctl { -+ uint cmd; /* common ioctl definition */ -+ void *buf; /* pointer to user buffer */ -+ uint len; /* length of user buffer */ -+ bool set; /* get or set request (optional) */ -+ uint used; /* bytes read or written (optional) */ -+ uint needed; /* bytes needed (optional) */ -+ uint driver; /* to identify target driver */ -+} dhd_ioctl_t; -+ -+/* Underlying BUS definition */ -+enum { -+ BUS_TYPE_USB = 0, /* for USB dongles */ -+ BUS_TYPE_SDIO /* for SDIO dongles */ -+}; -+ -+/* per-driver magic numbers */ -+#define DHD_IOCTL_MAGIC 0x00444944 -+ -+/* bump this number if you change the ioctl interface */ -+#define DHD_IOCTL_VERSION 1 -+ -+#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -+#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ -+ -+/* common ioctl definitions */ -+#define DHD_GET_MAGIC 0 -+#define DHD_GET_VERSION 1 -+#define DHD_GET_VAR 2 -+#define DHD_SET_VAR 3 -+ -+/* message levels */ -+#define DHD_ERROR_VAL 0x0001 -+#define DHD_TRACE_VAL 0x0002 -+#define DHD_INFO_VAL 0x0004 -+#define DHD_DATA_VAL 0x0008 -+#define DHD_CTL_VAL 0x0010 -+#define DHD_TIMER_VAL 0x0020 -+#define DHD_HDRS_VAL 0x0040 -+#define DHD_BYTES_VAL 0x0080 -+#define DHD_INTR_VAL 0x0100 -+#define DHD_LOG_VAL 0x0200 -+#define DHD_GLOM_VAL 0x0400 -+#define DHD_EVENT_VAL 0x0800 -+#define DHD_BTA_VAL 0x1000 -+#if 0 && (NDISVER >= 0x0630) && 1 -+#define DHD_SCAN_VAL 0x2000 -+#else -+#define DHD_ISCAN_VAL 0x2000 -+#endif -+#define DHD_ARPOE_VAL 0x4000 -+#define DHD_REORDER_VAL 0x8000 -+#define DHD_IW_VAL 0x10000 -+#define DHD_CFG_VAL 0x20000 -+ -+#ifdef SDTEST -+/* For pktgen iovar */ -+typedef struct dhd_pktgen { -+ uint version; /* To allow structure change tracking */ -+ uint freq; /* Max ticks between tx/rx attempts */ -+ uint count; /* Test packets to send/rcv each attempt */ -+ uint print; /* Print counts every attempts */ -+ uint total; /* Total packets (or bursts) */ -+ uint minlen; /* Minimum length of packets to send */ -+ uint maxlen; /* Maximum length of packets to send */ -+ uint numsent; /* Count of test packets sent */ -+ uint numrcvd; /* Count of test packets received */ -+ uint numfail; /* Count of test send failures */ -+ uint mode; /* Test mode (type of test packets) */ -+ uint stop; /* Stop after this many tx failures */ -+} dhd_pktgen_t; -+ -+/* Version in case structure changes */ -+#define DHD_PKTGEN_VERSION 2 -+ -+/* Type of test packets to use */ -+#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -+#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -+#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -+#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous tx dongle */ -+#endif /* SDTEST */ -+ -+/* Enter idle immediately (no timeout) */ -+#define DHD_IDLE_IMMEDIATE (-1) -+ -+/* Values for idleclock iovar: other values are the sd_divisor to use when idle */ -+#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */ -+#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */ -+ -+ -+/* require default structure packing */ -+#include -+ -+#endif /* _dhdioctl_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/epivers.h b/drivers/net/wireless/ap6210/include/epivers.h -new file mode 100644 -index 0000000..cff9ebd ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/epivers.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 csm Exp $ -+ * -+*/ -+ -+#ifndef _epivers_h_ -+#define _epivers_h_ -+ -+#define EPI_MAJOR_VERSION 1 -+ -+#define EPI_MINOR_VERSION 28 -+ -+#define EPI_RC_NUMBER 23 -+ -+#define EPI_INCREMENTAL_NUMBER 0 -+ -+#define EPI_BUILD_NUMBER 0 -+ -+#define EPI_VERSION 1, 28, 23, 0 -+ -+#define EPI_VERSION_NUM 0x011c1700 -+ -+#define EPI_VERSION_DEV 1.28.23 -+ -+/* Driver Version String, ASCII, 32 chars max */ -+#ifdef BCMINTERNAL -+#define EPI_VERSION_STR "1.28.23.3 (r BCMINT)" -+#else -+#ifdef WLTEST -+#define EPI_VERSION_STR "1.28.23.3 (r WLTEST)" -+#else -+#define EPI_VERSION_STR "1.28.23.3 (r)" -+#endif -+#endif /* BCMINTERNAL */ -+ -+#endif /* _epivers_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/hndpmu.h b/drivers/net/wireless/ap6210/include/hndpmu.h -new file mode 100644 -index 0000000..c41def6 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/hndpmu.h -@@ -0,0 +1,36 @@ -+/* -+ * HND SiliconBackplane PMU support. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: hndpmu.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _hndpmu_h_ -+#define _hndpmu_h_ -+ -+ -+extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); -+extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength); -+ -+extern void si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear); -+ -+#endif /* _hndpmu_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/hndrte_armtrap.h b/drivers/net/wireless/ap6210/include/hndrte_armtrap.h -new file mode 100644 -index 0000000..90d9799 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/hndrte_armtrap.h -@@ -0,0 +1,88 @@ -+/* -+ * HNDRTE arm trap handling. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: hndrte_armtrap.h 261365 2011-05-24 20:42:23Z $ -+ */ -+ -+#ifndef _hndrte_armtrap_h -+#define _hndrte_armtrap_h -+ -+ -+/* ARM trap handling */ -+ -+/* Trap types defined by ARM (see arminc.h) */ -+ -+/* Trap locations in lo memory */ -+#define TRAP_STRIDE 4 -+#define FIRST_TRAP TR_RST -+#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) -+ -+#if defined(__ARM_ARCH_4T__) -+#define MAX_TRAP_TYPE (TR_FIQ + 1) -+#elif defined(__ARM_ARCH_7M__) -+#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -+#endif /* __ARM_ARCH_7M__ */ -+ -+/* The trap structure is defined here as offsets for assembly */ -+#define TR_TYPE 0x00 -+#define TR_EPC 0x04 -+#define TR_CPSR 0x08 -+#define TR_SPSR 0x0c -+#define TR_REGS 0x10 -+#define TR_REG(n) (TR_REGS + (n) * 4) -+#define TR_SP TR_REG(13) -+#define TR_LR TR_REG(14) -+#define TR_PC TR_REG(15) -+ -+#define TRAP_T_SIZE 80 -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+#include -+ -+typedef struct _trap_struct { -+ uint32 type; -+ uint32 epc; -+ uint32 cpsr; -+ uint32 spsr; -+ uint32 r0; /* a1 */ -+ uint32 r1; /* a2 */ -+ uint32 r2; /* a3 */ -+ uint32 r3; /* a4 */ -+ uint32 r4; /* v1 */ -+ uint32 r5; /* v2 */ -+ uint32 r6; /* v3 */ -+ uint32 r7; /* v4 */ -+ uint32 r8; /* v5 */ -+ uint32 r9; /* sb/v6 */ -+ uint32 r10; /* sl/v7 */ -+ uint32 r11; /* fp/v8 */ -+ uint32 r12; /* ip */ -+ uint32 r13; /* sp */ -+ uint32 r14; /* lr */ -+ uint32 pc; /* r15 */ -+} trap_t; -+ -+#endif /* !_LANGUAGE_ASSEMBLY */ -+ -+#endif /* _hndrte_armtrap_h */ -diff --git a/drivers/net/wireless/ap6210/include/hndrte_cons.h b/drivers/net/wireless/ap6210/include/hndrte_cons.h -new file mode 100644 -index 0000000..57abbbd ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/hndrte_cons.h -@@ -0,0 +1,67 @@ -+/* -+ * Console support for hndrte. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: hndrte_cons.h 300516 2011-12-04 17:39:44Z $ -+ */ -+#ifndef _HNDRTE_CONS_H -+#define _HNDRTE_CONS_H -+ -+#include -+ -+#define CBUF_LEN (128) -+ -+#define LOG_BUF_LEN 1024 -+ -+typedef struct { -+ uint32 buf; /* Can't be pointer on (64-bit) hosts */ -+ uint buf_size; -+ uint idx; -+ char *_buf_compat; /* redundant pointer for backward compat. */ -+} hndrte_log_t; -+ -+typedef struct { -+ /* Virtual UART -+ * When there is no UART (e.g. Quickturn), the host should write a complete -+ * input line directly into cbuf and then write the length into vcons_in. -+ * This may also be used when there is a real UART (at risk of conflicting with -+ * the real UART). vcons_out is currently unused. -+ */ -+ volatile uint vcons_in; -+ volatile uint vcons_out; -+ -+ /* Output (logging) buffer -+ * Console output is written to a ring buffer log_buf at index log_idx. -+ * The host may read the output when it sees log_idx advance. -+ * Output will be lost if the output wraps around faster than the host polls. -+ */ -+ hndrte_log_t log; -+ -+ /* Console input line buffer -+ * Characters are read one at a time into cbuf until is received, then -+ * the buffer is processed as a command line. Also used for virtual UART. -+ */ -+ uint cbuf_idx; -+ char cbuf[CBUF_LEN]; -+} hndrte_cons_t; -+ -+#endif /* _HNDRTE_CONS_H */ -diff --git a/drivers/net/wireless/ap6210/include/hndsoc.h b/drivers/net/wireless/ap6210/include/hndsoc.h -new file mode 100644 -index 0000000..66640c3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/hndsoc.h -@@ -0,0 +1,235 @@ -+/* -+ * Broadcom HND chip & on-chip-interconnect-related definitions. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: hndsoc.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _HNDSOC_H -+#define _HNDSOC_H -+ -+/* Include the soci specific files */ -+#include -+#include -+ -+/* -+ * SOC Interconnect Address Map. -+ * All regions may not exist on all chips. -+ */ -+#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -+#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -+#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -+#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -+#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -+#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */ -+ -+#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -+ -+#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ -+#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -+#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software -+ * convenience and could be changed if we -+ * make any larger chips -+ */ -+ -+#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ -+#define SI_FASTRAM_SWAPPED 0x19800000 -+ -+#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -+#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -+#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -+#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -+#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -+#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -+#define SI_ARMCR4_ROM 0x000f0000 /* ARM Cortex-R4 ROM */ -+#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -+#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -+#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -+#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ -+ -+#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -+#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -+#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -+#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), low 32 bits -+ */ -+#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), high 32 bits -+ */ -+ -+/* core codes */ -+#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -+#define CC_CORE_ID 0x800 /* chipcommon core */ -+#define ILINE20_CORE_ID 0x801 /* iline20 core */ -+#define SRAM_CORE_ID 0x802 /* sram core */ -+#define SDRAM_CORE_ID 0x803 /* sdram core */ -+#define PCI_CORE_ID 0x804 /* pci core */ -+#define MIPS_CORE_ID 0x805 /* mips core */ -+#define ENET_CORE_ID 0x806 /* enet mac core */ -+#define CODEC_CORE_ID 0x807 /* v90 codec core */ -+#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -+#define ADSL_CORE_ID 0x809 /* ADSL core */ -+#define ILINE100_CORE_ID 0x80a /* iline100 core */ -+#define IPSEC_CORE_ID 0x80b /* ipsec core */ -+#define UTOPIA_CORE_ID 0x80c /* utopia core */ -+#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -+#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -+#define MEMC_CORE_ID 0x80f /* memc sdram core */ -+#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -+#define EXTIF_CORE_ID 0x811 /* external interface core */ -+#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -+#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -+#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -+#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -+#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -+#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -+#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -+#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -+#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -+#define SDIOH_CORE_ID 0x81b /* sdio host core */ -+#define ROBO_CORE_ID 0x81c /* roboswitch core */ -+#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -+#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -+#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -+#define PCIE_CORE_ID 0x820 /* pci express core */ -+#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -+#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -+#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -+#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -+#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -+#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -+#define PMU_CORE_ID 0x827 /* PMU core */ -+#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -+#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -+#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -+#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -+#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -+#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -+#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -+#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -+#define SC_CORE_ID 0x831 /* shared common core */ -+#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -+#define SPIH_CORE_ID 0x833 /* SPI host core */ -+#define I2S_CORE_ID 0x834 /* I2S core */ -+#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ -+#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ -+ -+#define ACPHY_CORE_ID 0x83b /* Dot11 ACPHY */ -+#define PCIE2_CORE_ID 0x83c /* pci express Gen2 core */ -+#define USB30D_CORE_ID 0x83d /* usb 3.0 device core */ -+#define ARMCR4_CORE_ID 0x83e /* ARM CR4 CPU */ -+#define APB_BRIDGE_CORE_ID 0x135 /* APB bridge core ID */ -+#define AXI_CORE_ID 0x301 /* AXI/GPV core ID */ -+#define EROM_CORE_ID 0x366 /* EROM core ID */ -+#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -+#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all -+ * unused address ranges -+ */ -+ -+#define CC_4706_CORE_ID 0x500 /* chipcommon core */ -+#define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */ -+#define GMAC_COMMON_4706_CORE_ID 0x5dc /* Gigabit MAC core */ -+#define GMAC_4706_CORE_ID 0x52d /* Gigabit MAC core */ -+#define AMEMC_CORE_ID 0x52e /* DDR1/2 memory controller core */ -+#define ALTA_CORE_ID 0x534 /* I2S core */ -+#define DDR23_PHY_CORE_ID 0x5dd -+ -+#define SI_PCI1_MEM 0x40000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -+#define SI_PCI1_CFG 0x44000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -+#define SI_PCIE1_DMA_H32 0xc0000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), high 32 bits -+ */ -+#define CC_4706B0_CORE_REV 0x8000001f /* chipcommon core */ -+#define SOCRAM_4706B0_CORE_REV 0x80000005 /* internal memory core */ -+#define GMAC_4706B0_CORE_REV 0x80000000 /* Gigabit MAC core */ -+ -+/* There are TWO constants on all HND chips: SI_ENUM_BASE above, -+ * and chipcommon being the first core: -+ */ -+#define SI_CC_IDX 0 -+ -+/* SOC Interconnect types (aka chip types) */ -+#define SOCI_SB 0 -+#define SOCI_AI 1 -+#define SOCI_UBUS 2 -+ -+/* Common core control flags */ -+#define SICF_BIST_EN 0x8000 -+#define SICF_PME_EN 0x4000 -+#define SICF_CORE_BITS 0x3ffc -+#define SICF_FGC 0x0002 -+#define SICF_CLOCK_EN 0x0001 -+ -+/* Common core status flags */ -+#define SISF_BIST_DONE 0x8000 -+#define SISF_BIST_ERROR 0x4000 -+#define SISF_GATED_CLK 0x2000 -+#define SISF_DMA64 0x1000 -+#define SISF_CORE_BITS 0x0fff -+ -+/* A register that is common to all cores to -+ * communicate w/PMU regarding clock control. -+ */ -+#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ -+ -+/* clk_ctl_st register */ -+#define CCS_FORCEALP 0x00000001 /* force ALP request */ -+#define CCS_FORCEHT 0x00000002 /* force HT request */ -+#define CCS_FORCEILP 0x00000004 /* force ILP request */ -+#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -+#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -+#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -+#define CCS_HQCLKREQ 0x00000040 /* HQ Clock Required */ -+#define CCS_USBCLKREQ 0x00000100 /* USB Clock Req */ -+#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ -+#define CCS_ERSRC_REQ_SHIFT 8 -+#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -+#define CCS_HTAVAIL 0x00020000 /* HT is available */ -+#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */ -+#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */ -+#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ -+#define CCS_ERSRC_STS_SHIFT 24 -+ -+#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -+#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ -+ -+/* Not really related to SOC Interconnect, but a couple of software -+ * conventions for the use the flash space: -+ */ -+ -+/* Minumum amount of flash we support */ -+#define FLASH_MIN 0x00020000 /* Minimum flash size */ -+ -+/* A boot/binary may have an embedded block that describes its size */ -+#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -+#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -+#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -+#define BISZ_TXTST_IDX 1 /* 1: text start */ -+#define BISZ_TXTEND_IDX 2 /* 2: text end */ -+#define BISZ_DATAST_IDX 3 /* 3: data start */ -+#define BISZ_DATAEND_IDX 4 /* 4: data end */ -+#define BISZ_BSSST_IDX 5 /* 5: bss start */ -+#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -+#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ -+ -+#endif /* _HNDSOC_H */ -diff --git a/drivers/net/wireless/ap6210/include/linux_osl.h b/drivers/net/wireless/ap6210/include/linux_osl.h -new file mode 100644 -index 0000000..ca28f6b ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/linux_osl.h -@@ -0,0 +1,430 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: linux_osl.h 354452 2012-08-31 04:59:17Z $ -+ */ -+ -+#ifndef _linux_osl_h_ -+#define _linux_osl_h_ -+ -+#include -+ -+/* Linux Kernel: File Operations: start */ -+extern void * osl_os_open_image(char * filename); -+extern int osl_os_get_image_block(char * buf, int len, void * image); -+extern void osl_os_close_image(void * image); -+extern int osl_os_image_size(void *image); -+/* Linux Kernel: File Operations: end */ -+ -+#ifdef BCMDRIVER -+ -+/* OSL initialization */ -+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); -+extern void osl_detach(osl_t *osh); -+ -+/* Global ASSERT type */ -+extern uint32 g_assert_type; -+ -+/* ASSERT */ -+#if defined(BCMASSERT_LOG) -+ #define ASSERT(exp) \ -+ do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -+extern void osl_assert(const char *exp, const char *file, int line); -+#else -+ #ifdef __GNUC__ -+ #define GCC_VERSION \ -+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+ #if GCC_VERSION > 30100 -+ #define ASSERT(exp) do {} while (0) -+ #else -+ /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ -+ #define ASSERT(exp) -+ #endif /* GCC_VERSION > 30100 */ -+ #endif /* __GNUC__ */ -+#endif -+ -+/* microsecond delay */ -+#define OSL_DELAY(usec) osl_delay(usec) -+extern void osl_delay(uint usec); -+ -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); -+ -+/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(osh, offset, size) \ -+ osl_pci_read_config((osh), (offset), (size)) -+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ -+ osl_pci_write_config((osh), (offset), (size), (val)) -+extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); -+ -+/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -+extern uint osl_pci_bus(osl_t *osh); -+extern uint osl_pci_slot(osl_t *osh); -+extern struct pci_dev *osl_pci_device(osl_t *osh); -+ -+/* Pkttag flag should be part of public information */ -+typedef struct { -+ bool pkttag; -+ uint pktalloced; /* Number of allocated packet buffers */ -+ bool mmbus; /* Bus supports memory-mapped register accesses */ -+ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ -+ void *tx_ctx; /* Context to the callback function */ -+ void *unused[3]; -+} osl_pubinfo_t; -+ -+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ -+ do { \ -+ ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ -+ ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ -+ } while (0) -+ -+ -+/* host/bus architecture-specific byte swap */ -+#define BUS_SWAP32(v) (v) -+ -+ #define MALLOC(osh, size) osl_malloc((osh), (size)) -+ #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -+ #define MALLOCED(osh) osl_malloced((osh)) -+ extern void *osl_malloc(osl_t *osh, uint size); -+ extern void osl_mfree(osl_t *osh, void *addr, uint size); -+ extern uint osl_malloced(osl_t *osh); -+ -+#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC) -+#define NATIVE_MFREE(osh, addr, size) kfree(addr) -+ -+#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) -+extern uint osl_malloc_failed(osl_t *osh); -+ -+/* allocate/free shared (dma-able) consistent memory */ -+#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() -+#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ -+ osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ -+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -+extern uint osl_dma_consistent_align(void); -+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap); -+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); -+ -+/* map/unmap direction */ -+#define DMA_TX 1 /* TX direction for DMA */ -+#define DMA_RX 2 /* RX direction for DMA */ -+ -+/* map/unmap shared (dma-able) memory */ -+#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ -+ osl_dma_unmap((osh), (pa), (size), (direction)) -+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); -+ -+/* API for DMA addressing capability */ -+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) -+ -+/* register access macros */ -+ #include -+ #define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v))) -+ #define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r)))) -+ -+ #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ -+ mmap_op else bus_op -+ #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ -+ mmap_op : bus_op -+ -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int bcmerror); -+ -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ * Macros expand to calls to functions defined in linux_osl.c . -+ */ -+#include /* use current 2.4.x calling conventions */ -+#include /* for vsn/printf's */ -+#include /* for mem*, str* */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 29) -+#define OSL_SYSUPTIME() ((uint32)jiffies_to_msecs(jiffies)) -+#else -+#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 29) */ -+#define printf(fmt, args...) pr_info(fmt , ## args) -+#include /* for vsn/printf's */ -+#include /* for mem*, str* */ -+/* bcopy's: Linux kernel doesn't provide these (anymore) */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* register access macros */ -+ -+#define R_REG(osh, r) (\ -+ SELECT_BUS_READ(osh, \ -+ ({ \ -+ __typeof(*(r)) __osl_v; \ -+ BCM_REFERENCE(osh); \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = \ -+ readb((volatile uint8*)(r)); break; \ -+ case sizeof(uint16): __osl_v = \ -+ readw((volatile uint16*)(r)); break; \ -+ case sizeof(uint32): __osl_v = \ -+ readl((volatile uint32*)(r)); break; \ -+ } \ -+ __osl_v; \ -+ }), \ -+ OSL_READ_REG(osh, r)) \ -+) -+ -+#define W_REG(osh, r, v) do { \ -+ BCM_REFERENCE(osh); \ -+ SELECT_BUS_WRITE(osh, \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ }, \ -+ (OSL_WRITE_REG(osh, r, v))); \ -+ } while (0) -+ -+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -+ -+/* bcopy, bcmp, and bzero functions */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* uncached/cached virtual address */ -+#define OSL_UNCACHED(va) ((void *)va) -+#define OSL_CACHED(va) ((void *)va) -+ -+#define OSL_PREF_RANGE_LD(va, sz) -+#define OSL_PREF_RANGE_ST(va, sz) -+ -+/* get processor cycle count */ -+#if defined(__i386__) -+#define OSL_GETCYCLES(x) rdtscl((x)) -+#else -+#define OSL_GETCYCLES(x) ((x) = 0) -+#endif -+ -+/* dereference an address that may cause a bus exception */ -+#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) -+ -+/* map/unmap physical to virtual I/O */ -+#if !defined(CONFIG_MMC_MSM7X00A) -+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -+#else -+#define REG_MAP(pa, size) (void *)(0) -+#endif /* !defined(CONFIG_MMC_MSM7X00A */ -+#define REG_UNMAP(va) iounmap((va)) -+ -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) memset((r), '\0', (len)) -+ -+/* Because the non BINOSL implemenation of the PKT OSL routines are macros (for -+ * performance reasons), we need the Linux headers. -+ */ -+#include /* use current 2.4.x calling conventions */ -+ -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTLIST_DUMP(osh, buf) -+#define PKTDBG_TRACE(osh, pkt, bit) -+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) -+#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -+#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -+#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -+#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced -+#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -+#define PKTPOOL(osh, skb) FALSE -+#define PKTSHRINK(osh, m) (m) -+ -+#ifdef CTFPOOL -+#define CTFPOOL_REFILL_THRESH 3 -+typedef struct ctfpool { -+ void *head; -+ spinlock_t lock; -+ uint max_obj; -+ uint curr_obj; -+ uint obj_size; -+ uint refills; -+ uint fast_allocs; -+ uint fast_frees; -+ uint slow_allocs; -+} ctfpool_t; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -+#define FASTBUF (1 << 16) -+#define CTFBUF (1 << 17) -+#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF) -+#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF)) -+#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF) -+#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF)) -+#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF) -+#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF) -+#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len) -+#else -+#define FASTBUF (1 << 0) -+#define CTFBUF (1 << 1) -+#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF) -+#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF)) -+#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF) -+#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF)) -+#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF) -+#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF) -+#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused) -+#endif /* 2.6.22 */ -+ -+#define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk) -+#define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head) -+ -+extern void *osl_ctfpool_add(osl_t *osh); -+extern void osl_ctfpool_replenish(osl_t *osh, uint thresh); -+extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size); -+extern void osl_ctfpool_cleanup(osl_t *osh); -+extern void osl_ctfpool_stats(osl_t *osh, void *b); -+#endif /* CTFPOOL */ -+ -+ -+#ifdef HNDCTF -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -+#define SKIPCT (1 << 18) -+#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len |= SKIPCT) -+#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~SKIPCT)) -+#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len & SKIPCT) -+#else /* 2.6.22 */ -+#define SKIPCT (1 << 2) -+#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT) -+#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT)) -+#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT) -+#endif /* 2.6.22 */ -+#else /* HNDCTF */ -+#define PKTSETSKIPCT(osh, skb) -+#define PKTCLRSKIPCT(osh, skb) -+#define PKTSKIPCT(osh, skb) -+#endif /* HNDCTF */ -+ -+extern void osl_pktfree(osl_t *osh, void *skb, bool send); -+extern void *osl_pktget_static(osl_t *osh, uint len); -+extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); -+ -+extern void *osl_pkt_frmnative(osl_t *osh, void *skb); -+extern void *osl_pktget(osl_t *osh, uint len); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); -+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb)) -+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt)) -+ -+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -+#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) -+#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ -+ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) -+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ -+#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) -+ -+#define DMA_MAP(osh, va, size, direction, p, dmah) \ -+ osl_dma_map((osh), (va), (size), (direction)) -+ -+#ifdef PKTC -+/* Use 8 bytes of skb tstamp field to store below info */ -+struct chain_node { -+ struct sk_buff *link; -+ unsigned int flags:3, pkts:9, bytes:20; -+}; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -+#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->tstamp)) -+#else -+#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->stamp)) -+#endif -+ -+#define PKTCCNT(skb) (CHAIN_NODE(skb)->pkts) -+#define PKTCLEN(skb) (CHAIN_NODE(skb)->bytes) -+#define PKTCFLAGS(skb) (CHAIN_NODE(skb)->flags) -+#define PKTCSETCNT(skb, c) (CHAIN_NODE(skb)->pkts = (c) & ((1 << 9) - 1)) -+#define PKTCSETLEN(skb, l) (CHAIN_NODE(skb)->bytes = (l) & ((1 << 20) - 1)) -+#define PKTCSETFLAG(skb, fb) (CHAIN_NODE(skb)->flags |= (fb)) -+#define PKTCCLRFLAG(skb, fb) (CHAIN_NODE(skb)->flags &= ~(fb)) -+#define PKTCLINK(skb) (CHAIN_NODE(skb)->link) -+#define PKTSETCLINK(skb, x) (CHAIN_NODE(skb)->link = (struct sk_buff*)(x)) -+#define PKTISCHAINED(skb) (PKTCLINK(skb) != NULL) -+#define FOREACH_CHAINED_PKT(skb, nskb) \ -+ for (; (skb) != NULL; (skb) = (nskb)) \ -+ if ((nskb) = PKTCLINK(skb), PKTSETCLINK((skb), NULL), 1) -+#define PKTCFREE(osh, skb, send) \ -+do { \ -+ void *nskb; \ -+ ASSERT((skb) != NULL); \ -+ FOREACH_CHAINED_PKT((skb), nskb) { \ -+ PKTFREE((osh), (skb), (send)); \ -+ } \ -+} while (0) -+#endif /* PKTC */ -+ -+#else /* ! BCMDRIVER */ -+ -+ -+/* ASSERT */ -+ #define ASSERT(exp) do {} while (0) -+ -+/* MALLOC and MFREE */ -+#define MALLOC(o, l) malloc(l) -+#define MFREE(o, p, l) free(p) -+#include -+ -+/* str* and mem* functions */ -+#include -+ -+/* *printf functions */ -+#include -+ -+/* bcopy, bcmp, and bzero */ -+extern void bcopy(const void *src, void *dst, size_t len); -+extern int bcmp(const void *b1, const void *b2, size_t len); -+extern void bzero(void *b, size_t len); -+#endif /* ! BCMDRIVER */ -+ -+#endif /* _linux_osl_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/linuxver.h b/drivers/net/wireless/ap6210/include/linuxver.h -new file mode 100644 -index 0000000..e01b8f0 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/linuxver.h -@@ -0,0 +1,652 @@ -+/* -+ * Linux-specific abstractions to gain some independence from linux kernel versions. -+ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: linuxver.h 366812 2012-11-05 13:49:32Z $ -+ */ -+ -+#ifndef _linuxver_h_ -+#define _linuxver_h_ -+ -+#include -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+#include -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) -+#include -+#else -+#include -+#endif -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ -+#include -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) -+/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ -+#ifdef __UNDEF_NO_VERSION__ -+#undef __NO_VERSION__ -+#else -+#define __NO_VERSION__ -+#endif -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -+#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -+#define module_param_string(_name_, _string_, _size_, _perm_) \ -+ MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -+#endif -+ -+/* linux/malloc.h is deprecated, use linux/slab.h instead. */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) -+#include -+#else -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+#include -+#else -+#include -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -+#undef IP_TOS -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) */ -+#include -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) -+#include -+#else -+#include -+#ifndef work_struct -+#define work_struct tq_struct -+#endif -+#ifndef INIT_WORK -+#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -+#endif -+#ifndef schedule_work -+#define schedule_work(_work) schedule_task((_work)) -+#endif -+#ifndef flush_scheduled_work -+#define flush_scheduled_work() flush_scheduled_tasks() -+#endif -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#define DAEMONIZE(a) daemonize(a); \ -+ allow_signal(SIGKILL); \ -+ allow_signal(SIGTERM); -+#else /* Linux 2.4 (w/o preemption patch) */ -+#define RAISE_RX_SOFTIRQ() \ -+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -+#define DAEMONIZE(a) daemonize(); \ -+ do { if (a) \ -+ strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a)))); \ -+ } while (0); -+#endif /* LINUX_VERSION_CODE */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func) -+#else -+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work) -+#if !(LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) && defined(RHEL_MAJOR) && \ -+ (RHEL_MAJOR == 5)) -+/* Exclude RHEL 5 */ -+typedef void (*work_func_t)(void *work); -+#endif -+#endif /* >= 2.6.20 */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+/* Some distributions have their own 2.6.x compatibility layers */ -+#ifndef IRQ_NONE -+typedef void irqreturn_t; -+#define IRQ_NONE -+#define IRQ_HANDLED -+#define IRQ_RETVAL(x) -+#endif -+#else -+typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -+#define IRQF_SHARED SA_SHIRQ -+#endif /* < 2.6.18 */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) -+#ifdef CONFIG_NET_RADIO -+#define CONFIG_WIRELESS_EXT -+#endif -+#endif /* < 2.6.17 */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -+#define MOD_INC_USE_COUNT -+#define MOD_DEC_USE_COUNT -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) -+#include -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -+#include -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -+#include -+#else -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -+#include -+#endif -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */ -+ -+ -+ -+#ifndef __exit -+#define __exit -+#endif -+#ifndef __devexit -+#define __devexit -+#endif -+#ifndef __devinit -+#define __devinit __init -+#endif -+#ifndef __devinitdata -+#define __devinitdata -+#endif -+#ifndef __devexit_p -+#define __devexit_p(x) x -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) -+ -+#define pci_get_drvdata(dev) (dev)->sysdata -+#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) -+ -+/* -+ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration -+ */ -+ -+struct pci_device_id { -+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ -+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ -+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ -+ unsigned long driver_data; /* Data private to the driver */ -+}; -+ -+struct pci_driver { -+ struct list_head node; -+ char *name; -+ const struct pci_device_id *id_table; /* NULL if wants all devices */ -+ int (*probe)(struct pci_dev *dev, -+ const struct pci_device_id *id); /* New device inserted */ -+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug -+ * capable driver) -+ */ -+ void (*suspend)(struct pci_dev *dev); /* Device suspended */ -+ void (*resume)(struct pci_dev *dev); /* Device woken up */ -+}; -+ -+#define MODULE_DEVICE_TABLE(type, name) -+#define PCI_ANY_ID (~0) -+ -+/* compatpci.c */ -+#define pci_module_init pci_register_driver -+extern int pci_register_driver(struct pci_driver *drv); -+extern void pci_unregister_driver(struct pci_driver *drv); -+ -+#endif /* PCI registration */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) -+#define pci_module_init pci_register_driver -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) -+#ifdef MODULE -+#define module_init(x) int init_module(void) { return x(); } -+#define module_exit(x) void cleanup_module(void) { x(); } -+#else -+#define module_init(x) __initcall(x); -+#define module_exit(x) __exitcall(x); -+#endif -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) -+#define WL_USE_NETDEV_OPS -+#else -+#undef WL_USE_NETDEV_OPS -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL) -+#define WL_CONFIG_RFKILL -+#else -+#undef WL_CONFIG_RFKILL -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) -+#define list_for_each(pos, head) \ -+ for (pos = (head)->next; pos != (head); pos = pos->next) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) -+#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) -+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) -+#define pci_enable_device(dev) do { } while (0) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) -+#define net_device device -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) -+ -+/* -+ * DMA mapping -+ * -+ * See linux/Documentation/DMA-mapping.txt -+ */ -+ -+#ifndef PCI_DMA_TODEVICE -+#define PCI_DMA_TODEVICE 1 -+#define PCI_DMA_FROMDEVICE 2 -+#endif -+ -+typedef u32 dma_addr_t; -+ -+/* Pure 2^n version of get_order */ -+static inline int get_order(unsigned long size) -+{ -+ int order; -+ -+ size = (size-1) >> (PAGE_SHIFT-1); -+ order = -1; -+ do { -+ size >>= 1; -+ order++; -+ } while (size); -+ return order; -+} -+ -+static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, -+ dma_addr_t *dma_handle) -+{ -+ void *ret; -+ int gfp = GFP_ATOMIC | GFP_DMA; -+ -+ ret = (void *)__get_free_pages(gfp, get_order(size)); -+ -+ if (ret != NULL) { -+ memset(ret, 0, size); -+ *dma_handle = virt_to_bus(ret); -+ } -+ return ret; -+} -+static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, -+ void *vaddr, dma_addr_t dma_handle) -+{ -+ free_pages((unsigned long)vaddr, get_order(size)); -+} -+#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -+#define pci_unmap_single(cookie, address, size, dir) -+ -+#endif /* DMA mapping */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) -+ -+#define dev_kfree_skb_any(a) dev_kfree_skb(a) -+#define netif_down(dev) do { (dev)->start = 0; } while (0) -+ -+/* pcmcia-cs provides its own netdevice compatibility layer */ -+#ifndef _COMPAT_NETDEVICE_H -+ -+/* -+ * SoftNet -+ * -+ * For pre-softnet kernels we need to tell the upper layer not to -+ * re-enter start_xmit() while we are in there. However softnet -+ * guarantees not to enter while we are in there so there is no need -+ * to do the netif_stop_queue() dance unless the transmit queue really -+ * gets stuck. This should also improve performance according to tests -+ * done by Aman Singla. -+ */ -+ -+#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -+#define netif_wake_queue(dev) \ -+ do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) -+#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) -+ -+static inline void netif_start_queue(struct net_device *dev) -+{ -+ dev->tbusy = 0; -+ dev->interrupt = 0; -+ dev->start = 1; -+} -+ -+#define netif_queue_stopped(dev) (dev)->tbusy -+#define netif_running(dev) (dev)->start -+ -+#endif /* _COMPAT_NETDEVICE_H */ -+ -+#define netif_device_attach(dev) netif_start_queue(dev) -+#define netif_device_detach(dev) netif_stop_queue(dev) -+ -+/* 2.4.x renamed bottom halves to tasklets */ -+#define tasklet_struct tq_struct -+static inline void tasklet_schedule(struct tasklet_struct *tasklet) -+{ -+ queue_task(tasklet, &tq_immediate); -+ mark_bh(IMMEDIATE_BH); -+} -+ -+static inline void tasklet_init(struct tasklet_struct *tasklet, -+ void (*func)(unsigned long), -+ unsigned long data) -+{ -+ tasklet->next = NULL; -+ tasklet->sync = 0; -+ tasklet->routine = (void (*)(void *))func; -+ tasklet->data = (void *)data; -+} -+#define tasklet_kill(tasklet) { do {} while (0); } -+ -+/* 2.4.x introduced del_timer_sync() */ -+#define del_timer_sync(timer) del_timer(timer) -+ -+#else -+ -+#define netif_down(dev) -+ -+#endif /* SoftNet */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) -+ -+/* -+ * Emit code to initialise a tq_struct's routine and data pointers -+ */ -+#define PREPARE_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ (_tq)->routine = _routine; \ -+ (_tq)->data = _data; \ -+ } while (0) -+ -+/* -+ * Emit code to initialise all of a tq_struct -+ */ -+#define INIT_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ INIT_LIST_HEAD(&(_tq)->list); \ -+ (_tq)->sync = 0; \ -+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ -+ } while (0) -+ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */ -+ -+/* Power management related macro & routines */ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9) -+#define PCI_SAVE_STATE(a, b) pci_save_state(a) -+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a) -+#else -+#define PCI_SAVE_STATE(a, b) pci_save_state(a, b) -+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) -+static inline int -+pci_save_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_read_config_dword(dev, i * 4, &buffer[i]); -+ } -+ return 0; -+} -+ -+static inline int -+pci_restore_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_write_config_dword(dev, i * 4, buffer[i]); -+ } -+ /* -+ * otherwise, write the context information we know from bootup. -+ * This works around a problem where warm-booting from Windows -+ * combined with a D3(hot)->D0 transition causes PCI config -+ * header data to be forgotten. -+ */ -+ else { -+ for (i = 0; i < 6; i ++) -+ pci_write_config_dword(dev, -+ PCI_BASE_ADDRESS_0 + (i * 4), -+ pci_resource_start(dev, i)); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); -+ } -+ return 0; -+} -+#endif /* PCI power management */ -+ -+/* Old cp0 access macros deprecated in 2.4.19 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) -+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -+#endif -+ -+/* Module refcount handled internally in 2.6.x */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#else -+#define OLD_MOD_INC_USE_COUNT do {} while (0) -+#define OLD_MOD_DEC_USE_COUNT do {} while (0) -+#endif -+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#endif -+#ifndef MOD_INC_USE_COUNT -+#define MOD_INC_USE_COUNT do {} while (0) -+#endif -+#ifndef MOD_DEC_USE_COUNT -+#define MOD_DEC_USE_COUNT do {} while (0) -+#endif -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ -+ -+#ifndef SET_NETDEV_DEV -+#define SET_NETDEV_DEV(net, pdev) do {} while (0) -+#endif -+ -+#ifndef HAVE_FREE_NETDEV -+#define free_netdev(dev) kfree(dev) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+/* struct packet_type redefined in 2.6.x */ -+#define af_packet_priv data -+#endif -+ -+/* suspend args */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -+#define DRV_SUSPEND_STATE_TYPE pm_message_t -+#else -+#define DRV_SUSPEND_STATE_TYPE uint32 -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -+#define CHECKSUM_HW CHECKSUM_PARTIAL -+#endif -+ -+typedef struct { -+ void *parent; /* some external entity that the thread supposed to work for */ -+ struct task_struct *p_task; -+ long thr_pid; -+ int prio; /* priority */ -+ struct semaphore sema; -+ int terminated; -+ struct completion completed; -+} tsk_ctl_t; -+ -+ -+/* requires tsk_ctl_t tsk argument, the caller's priv data is passed in owner ptr */ -+/* note this macro assumes there may be only one context waiting on thread's completion */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) -+#else -+#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) -+#endif -+ -+ -+#define PROC_START(thread_func, owner, tsk_ctl, flags) \ -+{ \ -+ sema_init(&((tsk_ctl)->sema), 0); \ -+ init_completion(&((tsk_ctl)->completed)); \ -+ (tsk_ctl)->parent = owner; \ -+ (tsk_ctl)->terminated = FALSE; \ -+ (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \ -+ if ((tsk_ctl)->thr_pid > 0) \ -+ wait_for_completion(&((tsk_ctl)->completed)); \ -+} -+ -+#ifdef USE_KTHREAD_API -+#define PROC_START2(thread_func, owner, tsk_ctl, flags, name) \ -+{ \ -+ sema_init(&((tsk_ctl)->sema), 0); \ -+ init_completion(&((tsk_ctl)->completed)); \ -+ (tsk_ctl)->parent = owner; \ -+ (tsk_ctl)->terminated = FALSE; \ -+ (tsk_ctl)->p_task = kthread_run(thread_func, tsk_ctl, (char*)name); \ -+ (tsk_ctl)->thr_pid = (tsk_ctl)->p_task->pid; \ -+} -+#endif -+ -+#define PROC_STOP(tsk_ctl) \ -+{ \ -+ (tsk_ctl)->terminated = TRUE; \ -+ smp_wmb(); \ -+ up(&((tsk_ctl)->sema)); \ -+ wait_for_completion(&((tsk_ctl)->completed)); \ -+ (tsk_ctl)->thr_pid = -1; \ -+} -+ -+/* ----------------------- */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -+#define KILL_PROC(nr, sig) \ -+{ \ -+struct task_struct *tsk; \ -+struct pid *pid; \ -+pid = find_get_pid((pid_t)nr); \ -+tsk = pid_task(pid, PIDTYPE_PID); \ -+if (tsk) send_sig(sig, tsk, 1); \ -+} -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ -+ KERNEL_VERSION(2, 6, 30)) -+#define KILL_PROC(pid, sig) \ -+{ \ -+ struct task_struct *tsk; \ -+ tsk = find_task_by_vpid(pid); \ -+ if (tsk) send_sig(sig, tsk, 1); \ -+} -+#else -+#define KILL_PROC(pid, sig) \ -+{ \ -+ kill_proc(pid, sig, 1); \ -+} -+#endif -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#include -+#include -+#else -+#include -+ -+#define __wait_event_interruptible_timeout(wq, condition, ret) \ -+do { \ -+ wait_queue_t __wait; \ -+ init_waitqueue_entry(&__wait, current); \ -+ \ -+ add_wait_queue(&wq, &__wait); \ -+ for (;;) { \ -+ set_current_state(TASK_INTERRUPTIBLE); \ -+ if (condition) \ -+ break; \ -+ if (!signal_pending(current)) { \ -+ ret = schedule_timeout(ret); \ -+ if (!ret) \ -+ break; \ -+ continue; \ -+ } \ -+ ret = -ERESTARTSYS; \ -+ break; \ -+ } \ -+ current->state = TASK_RUNNING; \ -+ remove_wait_queue(&wq, &__wait); \ -+} while (0) -+ -+#define wait_event_interruptible_timeout(wq, condition, timeout) \ -+({ \ -+ long __ret = timeout; \ -+ if (!(condition)) \ -+ __wait_event_interruptible_timeout(wq, condition, __ret); \ -+ __ret; \ -+}) -+ -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ -+ -+/* -+For < 2.6.24, wl creates its own netdev but doesn't -+align the priv area like the genuine alloc_netdev(). -+Since netdev_priv() always gives us the aligned address, it will -+not match our unaligned address for < 2.6.24 -+*/ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -+#define DEV_PRIV(dev) (dev->priv) -+#else -+#define DEV_PRIV(dev) netdev_priv(dev) -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -+#define WL_ISR(i, d, p) wl_isr((i), (d)) -+#else -+#define WL_ISR(i, d, p) wl_isr((i), (d), (p)) -+#endif /* < 2.6.20 */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+#define netdev_priv(dev) dev->priv -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ -+ -+#endif /* _linuxver_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/miniopt.h b/drivers/net/wireless/ap6210/include/miniopt.h -new file mode 100644 -index 0000000..c1eca68 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/miniopt.h -@@ -0,0 +1,77 @@ -+/* -+ * Command line options parser. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: miniopt.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+ -+#ifndef MINI_OPT_H -+#define MINI_OPT_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* ---- Include Files ---------------------------------------------------- */ -+/* ---- Constants and Types ---------------------------------------------- */ -+ -+#define MINIOPT_MAXKEY 128 /* Max options */ -+typedef struct miniopt { -+ -+ /* These are persistent after miniopt_init() */ -+ const char* name; /* name for prompt in error strings */ -+ const char* flags; /* option chars that take no args */ -+ bool longflags; /* long options may be flags */ -+ bool opt_end; /* at end of options (passed a "--") */ -+ -+ /* These are per-call to miniopt() */ -+ -+ int consumed; /* number of argv entries cosumed in -+ * the most recent call to miniopt() -+ */ -+ bool positional; -+ bool good_int; /* 'val' member is the result of a sucessful -+ * strtol conversion of the option value -+ */ -+ char opt; -+ char key[MINIOPT_MAXKEY]; -+ char* valstr; /* positional param, or value for the option, -+ * or null if the option had -+ * no accompanying value -+ */ -+ uint uval; /* strtol translation of valstr */ -+ int val; /* strtol translation of valstr */ -+} miniopt_t; -+ -+void miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags); -+int miniopt(miniopt_t *t, char **argv); -+ -+ -+/* ---- Variable Externs ------------------------------------------------- */ -+/* ---- Function Prototypes ---------------------------------------------- */ -+ -+ -+#ifdef __cplusplus -+ } -+#endif -+ -+#endif /* MINI_OPT_H */ -diff --git a/drivers/net/wireless/ap6210/include/msgtrace.h b/drivers/net/wireless/ap6210/include/msgtrace.h -new file mode 100644 -index 0000000..7c5fd81 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/msgtrace.h -@@ -0,0 +1,74 @@ -+/* -+ * Trace messages sent over HBUS -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: msgtrace.h 281527 2011-09-02 17:12:53Z $ -+ */ -+ -+#ifndef _MSGTRACE_H -+#define _MSGTRACE_H -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#define MSGTRACE_VERSION 1 -+ -+/* Message trace header */ -+typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { -+ uint8 version; -+ uint8 spare; -+ uint16 len; /* Len of the trace */ -+ uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost -+ * because of DMA error or a bus reset (ex: SDIO Func2) -+ */ -+ uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */ -+ uint32 discarded_printf; /* Number of discarded printf because of trace overflow */ -+} BWL_POST_PACKED_STRUCT msgtrace_hdr_t; -+ -+#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) -+ -+/* The hbus driver generates traces when sending a trace message. This causes endless traces. -+ * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put. -+ * This prevents endless traces but generates hasardous lost of traces only in bus device code. -+ * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing -+ * hbus error traces. hbus error trace should not generates endless traces. -+ */ -+extern bool msgtrace_hbus_trace; -+ -+typedef void (*msgtrace_func_send_t)(void *hdl1, void *hdl2, uint8 *hdr, -+ uint16 hdrlen, uint8 *buf, uint16 buflen); -+extern void msgtrace_start(void); -+extern void msgtrace_stop(void); -+extern void msgtrace_sent(void); -+extern void msgtrace_put(char *buf, int count); -+extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); -+extern bool msgtrace_event_enabled(void); -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _MSGTRACE_H */ -diff --git a/drivers/net/wireless/ap6210/include/osl.h b/drivers/net/wireless/ap6210/include/osl.h -new file mode 100644 -index 0000000..0a11d23 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/osl.h -@@ -0,0 +1,90 @@ -+/* -+ * OS Abstraction Layer -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: osl.h 320905 2012-03-13 15:33:25Z $ -+ */ -+ -+#ifndef _osl_h_ -+#define _osl_h_ -+ -+/* osl handle type forward declaration */ -+typedef struct osl_info osl_t; -+typedef struct osl_dmainfo osldma_t; -+ -+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ -+ -+/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */ -+typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); -+ -+/* Drivers use REGOPSSET() to register register read/write funcitons */ -+typedef unsigned int (*osl_rreg_fn_t)(void *ctx, volatile void *reg, unsigned int size); -+typedef void (*osl_wreg_fn_t)(void *ctx, volatile void *reg, unsigned int val, unsigned int size); -+ -+ -+#include -+ -+#ifndef PKTDBG_TRACE -+#define PKTDBG_TRACE(osh, pkt, bit) -+#endif -+ -+#define PKTCTFMAP(osh, p) -+ -+/* -------------------------------------------------------------------------- -+** Register manipulation macros. -+*/ -+ -+#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) -+ -+#ifndef AND_REG -+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -+#endif /* !AND_REG */ -+ -+#ifndef OR_REG -+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -+#endif /* !OR_REG */ -+ -+#if !defined(OSL_SYSUPTIME) -+#define OSL_SYSUPTIME() (0) -+#define OSL_SYSUPTIME_SUPPORT FALSE -+#else -+#define OSL_SYSUPTIME_SUPPORT TRUE -+#endif /* OSL_SYSUPTIME */ -+ -+#if !defined(PKTC) -+#define PKTCCNT(skb) (0) -+#define PKTCLEN(skb) (0) -+#define PKTCFLAGS(skb) (0) -+#define PKTCSETCNT(skb, c) -+#define PKTCSETLEN(skb, l) -+#define PKTCSETFLAG(skb, fb) -+#define PKTCCLRFLAG(skb, fb) -+#define PKTCLINK(skb) PKTLINK(skb) -+#define PKTSETCLINK(skb, x) PKTSETLINK((skb), (x)) -+#define PKTISCHAINED(skb) FALSE -+#define FOREACH_CHAINED_PKT(skb, nskb) \ -+ for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb)) -+#define PKTCFREE PKTFREE -+#endif -+ -+ -+#endif /* _osl_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/packed_section_end.h b/drivers/net/wireless/ap6210/include/packed_section_end.h -new file mode 100644 -index 0000000..0779b04 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/packed_section_end.h -@@ -0,0 +1,59 @@ -+/* -+ * Declare directives for structure packing. No padding will be provided -+ * between the members of packed structures, and therefore, there is no -+ * guarantee that structure members will be aligned. -+ * -+ * Declaring packed structures is compiler specific. In order to handle all -+ * cases, packed structures should be delared as: -+ * -+ * #include -+ * -+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { -+ * some_struct_members; -+ * } BWL_POST_PACKED_STRUCT foobar_t; -+ * -+ * #include -+ * -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: packed_section_end.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+ -+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h -+ * and undefined in packed_section_end.h. If it is NOT defined at this -+ * point, then there is a missing include of packed_section_start.h. -+ */ -+#ifdef BWL_PACKED_SECTION -+ #undef BWL_PACKED_SECTION -+#else -+ #error "BWL_PACKED_SECTION is NOT defined!" -+#endif -+ -+ -+ -+ -+/* Compiler-specific directives for structure packing are declared in -+ * packed_section_start.h. This marks the end of the structure packing section, -+ * so, undef them here. -+ */ -+#undef BWL_PRE_PACKED_STRUCT -+#undef BWL_POST_PACKED_STRUCT -diff --git a/drivers/net/wireless/ap6210/include/packed_section_start.h b/drivers/net/wireless/ap6210/include/packed_section_start.h -new file mode 100644 -index 0000000..ee93a4b ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/packed_section_start.h -@@ -0,0 +1,63 @@ -+/* -+ * Declare directives for structure packing. No padding will be provided -+ * between the members of packed structures, and therefore, there is no -+ * guarantee that structure members will be aligned. -+ * -+ * Declaring packed structures is compiler specific. In order to handle all -+ * cases, packed structures should be delared as: -+ * -+ * #include -+ * -+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { -+ * some_struct_members; -+ * } BWL_POST_PACKED_STRUCT foobar_t; -+ * -+ * #include -+ * -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: packed_section_start.h 286783 2011-09-29 06:18:57Z $ -+ */ -+ -+ -+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h -+ * and undefined in packed_section_end.h. If it is already defined at this -+ * point, then there is a missing include of packed_section_end.h. -+ */ -+#ifdef BWL_PACKED_SECTION -+ #error "BWL_PACKED_SECTION is already defined!" -+#else -+ #define BWL_PACKED_SECTION -+#endif -+ -+ -+ -+ -+/* Declare compiler-specific directives for structure packing. */ -+#if defined(__GNUC__) || defined(__lint) -+ #define BWL_PRE_PACKED_STRUCT -+ #define BWL_POST_PACKED_STRUCT __attribute__ ((packed)) -+#elif defined(__CC_ARM) -+ #define BWL_PRE_PACKED_STRUCT __packed -+ #define BWL_POST_PACKED_STRUCT -+#else -+ #error "Unknown compiler!" -+#endif -diff --git a/drivers/net/wireless/ap6210/include/pcicfg.h b/drivers/net/wireless/ap6210/include/pcicfg.h -new file mode 100644 -index 0000000..0278bb2 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/pcicfg.h -@@ -0,0 +1,100 @@ -+/* -+ * pcicfg.h: PCI configuration constants and structures. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: pcicfg.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _h_pcicfg_ -+#define _h_pcicfg_ -+ -+/* A structure for the config registers is nice, but in most -+ * systems the config space is not memory mapped, so we need -+ * field offsetts. :-( -+ */ -+#define PCI_CFG_VID 0 -+#define PCI_CFG_DID 2 -+#define PCI_CFG_CMD 4 -+#define PCI_CFG_STAT 6 -+#define PCI_CFG_REV 8 -+#define PCI_CFG_PROGIF 9 -+#define PCI_CFG_SUBCL 0xa -+#define PCI_CFG_BASECL 0xb -+#define PCI_CFG_CLSZ 0xc -+#define PCI_CFG_LATTIM 0xd -+#define PCI_CFG_HDR 0xe -+#define PCI_CFG_BIST 0xf -+#define PCI_CFG_BAR0 0x10 -+#define PCI_CFG_BAR1 0x14 -+#define PCI_CFG_BAR2 0x18 -+#define PCI_CFG_BAR3 0x1c -+#define PCI_CFG_BAR4 0x20 -+#define PCI_CFG_BAR5 0x24 -+#define PCI_CFG_CIS 0x28 -+#define PCI_CFG_SVID 0x2c -+#define PCI_CFG_SSID 0x2e -+#define PCI_CFG_ROMBAR 0x30 -+#define PCI_CFG_CAPPTR 0x34 -+#define PCI_CFG_INT 0x3c -+#define PCI_CFG_PIN 0x3d -+#define PCI_CFG_MINGNT 0x3e -+#define PCI_CFG_MAXLAT 0x3f -+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ -+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ -+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ -+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -+#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ -+#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ -+#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ -+#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ -+ -+#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ -+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ -+#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the -+ * 8KB window, so their address is the "regular" -+ * address plus 4K -+ */ -+/* -+ * PCIE GEN2 changed some of the above locations for -+ * Bar0WrapperBase, SecondaryBAR0Window and SecondaryBAR0WrapperBase -+ * BAR0 maps 32K of register space -+*/ -+#define PCIE2_BAR0_WIN2 0x70 /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCIE2_BAR0_CORE2_WIN 0x74 /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCIE2_BAR0_CORE2_WIN2 0x78 /* backplane addres space accessed by second 4KB of BAR0 */ -+ -+#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */ -+/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ -+#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ -+#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ -+#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ -+ -+ -+#define PCI_CONFIG_SPACE_SIZE 256 -+#endif /* _h_pcicfg_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/802.11.h b/drivers/net/wireless/ap6210/include/proto/802.11.h -new file mode 100644 -index 0000000..15cd56c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/802.11.h -@@ -0,0 +1,2355 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * Fundamental types and constants relating to 802.11 -+ * -+ * $Id: 802.11.h 346820 2012-07-24 13:53:12Z $ -+ */ -+ -+#ifndef _802_11_H_ -+#define _802_11_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+#ifndef _NET_ETHERNET_H_ -+#include -+#endif -+ -+#include -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ -+ -+/* Generic 802.11 frame constants */ -+#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ -+#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ -+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ -+#define DOT11_FCS_LEN 4 /* d11 FCS length */ -+#define DOT11_ICV_LEN 4 /* d11 ICV length */ -+#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ -+#define DOT11_QOS_LEN 2 /* d11 QoS length */ -+#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ -+ -+#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ -+#define DOT11_IV_LEN 4 /* d11 IV length */ -+#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ -+#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ -+#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ -+#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ -+ -+/* Includes MIC */ -+#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ -+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ -+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ -+ DOT11_QOS_LEN + \ -+ DOT11_IV_AES_CCM_LEN + \ -+ DOT11_MAX_MPDU_BODY_LEN + \ -+ DOT11_ICV_LEN + \ -+ DOT11_FCS_LEN) /* d11 max MPDU length */ -+ -+#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ -+ -+/* dot11RTSThreshold */ -+#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ -+#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ -+ -+/* dot11FragmentationThreshold */ -+#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ -+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength -+ * of the attached PHY -+ */ -+#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ -+ -+/* dot11BeaconPeriod */ -+#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ -+#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ -+ -+/* dot11DTIMPeriod */ -+#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ -+#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ -+ -+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ -+#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ -+#define DOT11_OUI_LEN 3 /* d11 OUI length */ -+BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { -+ uint8 dsap; /* always 0xAA */ -+ uint8 ssap; /* always 0xAA */ -+ uint8 ctl; /* always 0x03 */ -+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 -+ * Bridge-Tunnel: 0x00 0x00 0xF8 -+ */ -+ uint16 type; /* ethertype */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* RFC1042 header used by 802.11 per 802.1H */ -+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ -+ -+/* Generic 802.11 MAC header */ -+/* -+ * N.B.: This struct reflects the full 4 address 802.11 MAC header. -+ * The fields are defined such that the shorter 1, 2, and 3 -+ * address headers just use the first k fields. -+ */ -+BWL_PRE_PACKED_STRUCT struct dot11_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr a1; /* address 1 */ -+ struct ether_addr a2; /* address 2 */ -+ struct ether_addr a3; /* address 3 */ -+ uint16 seq; /* sequence control */ -+ struct ether_addr a4; /* address 4 */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* Control frames */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* AID */ -+ struct ether_addr bssid; /* receiver address, STA in AP */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr bssid; /* transmitter address, STA in AP */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ -+ -+/* RWL wifi protocol: The Vendor Specific Action frame is defined for vendor-specific signaling -+* category+OUI+vendor specific content ( this can be variable) -+*/ -+BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { -+ uint8 category; -+ uint8 OUI[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 data[1040]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; -+ -+/* generic vender specific action frame with variable length */ -+BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { -+ uint8 category; -+ uint8 OUI[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; -+#define DOT11_ACTION_VS_HDR_LEN 6 -+ -+#define BCM_ACTION_OUI_BYTE0 0x00 -+#define BCM_ACTION_OUI_BYTE1 0x90 -+#define BCM_ACTION_OUI_BYTE2 0x4c -+ -+/* BA/BAR Control parameters */ -+#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ -+#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ -+#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ -+ -+#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ -+#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ -+ -+#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ -+#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ -+ -+#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ -+#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ -+ -+/* control frame header (BA/BAR) */ -+BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */ -+ -+/* BAR frame payload */ -+BWL_PRE_PACKED_STRUCT struct dot11_bar { -+ uint16 bar_control; /* BAR Control */ -+ uint16 seqnum; /* Starting Sequence control */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BAR_LEN 4 /* BAR frame payload length */ -+ -+#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ -+#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ -+/* BA frame payload */ -+BWL_PRE_PACKED_STRUCT struct dot11_ba { -+ uint16 ba_control; /* BA Control */ -+ uint16 seqnum; /* Starting Sequence control */ -+ uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */ -+ -+/* Management frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_management_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr da; /* receiver address */ -+ struct ether_addr sa; /* transmitter address */ -+ struct ether_addr bssid; /* BSS ID */ -+ uint16 seq; /* sequence control */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ -+ -+/* Management frame payloads */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { -+ uint32 timestamp[2]; -+ uint16 beacon_interval; -+ uint16 capability; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */ -+#define DOT11_BCN_PRB_FIXED_LEN 12 /* 802.11 beacon/probe frame fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_auth { -+ uint16 alg; /* algorithm */ -+ uint16 seq; /* sequence control */ -+ uint16 status; /* status code */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge IE */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+ struct ether_addr ap; /* Current AP address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { -+ uint16 capability; /* capability information */ -+ uint16 status; /* status code */ -+ uint16 aid; /* association ID */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ASSOC_RESP_FIXED_LEN 6 /* length of assoc resp frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_measure { -+ uint8 category; -+ uint8 action; -+ uint8 token; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { -+ uint8 category; -+ uint8 action; -+ uint8 ch_width; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { -+ uint8 category; -+ uint8 action; -+ uint8 control; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_sa_query { -+ uint8 category; -+ uint8 action; -+ uint16 id; -+} BWL_POST_PACKED_STRUCT; -+ -+#define SM_PWRSAVE_ENABLE 1 -+#define SM_PWRSAVE_MODE 2 -+ -+/* ************* 802.11h related definitions. ************* */ -+BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { -+ uint8 id; -+ uint8 len; -+ uint8 power; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_power_cnst dot11_power_cnst_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_power_cap { -+ uint8 min; -+ uint8 max; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_power_cap dot11_power_cap_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { -+ uint8 id; -+ uint8 len; -+ uint8 tx_pwr; -+ uint8 margin; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_tpc_rep dot11_tpc_rep_t; -+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { -+ uint8 id; -+ uint8 len; -+ uint8 first_channel; -+ uint8 num_channels; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_supp_channels dot11_supp_channels_t; -+ -+/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband -+ * offset for 40MHz operation. The possible 3 values are: -+ * 1 = above control channel -+ * 3 = below control channel -+ * 0 = no extension channel -+ */ -+BWL_PRE_PACKED_STRUCT struct dot11_extch { -+ uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */ -+ uint8 len; /* IE length */ -+ uint8 extch; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extch dot11_extch_ie_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* type inidicates what follows */ -+ uint8 extch; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; -+ -+#define BRCM_EXTCH_IE_LEN 5 -+#define BRCM_EXTCH_IE_TYPE 53 /* 802.11n ID not yet assigned */ -+#define DOT11_EXTCH_IE_LEN 1 -+#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */ -+#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ -+#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ -+#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { -+ uint8 category; -+ uint8 action; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACTION_FRMHDR_LEN 2 -+ -+/* CSA IE data structure */ -+BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { -+ uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */ -+ uint8 len; /* length of IE */ -+ uint8 mode; /* mode 0 or 1 */ -+ uint8 channel; /* channel switch to */ -+ uint8 count; /* number of beacons before switching */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_channel_switch dot11_chan_switch_ie_t; -+ -+#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ -+/* CSA mode - 802.11h-2003 $7.3.2.20 */ -+#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ -+#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { -+ uint8 category; -+ uint8 action; -+ dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */ -+ dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_csa_body { -+ uint8 mode; /* mode 0 or 1 */ -+ uint8 reg; /* regulatory class */ -+ uint8 channel; /* channel switch to */ -+ uint8 count; /* number of beacons before switching */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* 11n Extended Channel Switch IE data structure */ -+BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { -+ uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */ -+ uint8 len; /* length of IE */ -+ struct dot11_csa_body b; /* body of the ie */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -+#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { -+ uint8 category; -+ uint8 action; -+ dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { -+ uint8 category; -+ uint8 action; -+ struct dot11_csa_body b; /* body of the ie */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { -+ uint8 id; -+ uint8 len; -+ uint8 info; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_coex dot11_obss_coex_t; -+#define DOT11_OBSS_COEXINFO_LEN 1 /* length of OBSS Coexistence INFO IE */ -+ -+#define DOT11_OBSS_COEX_INFO_REQ 0x01 -+#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -+#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { -+ uint8 id; -+ uint8 len; -+ uint8 regclass; -+ uint8 chanlist[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -+#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 /* fixed length of regclass */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { -+ uint8 id; -+ uint8 len; -+ uint8 cap[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extcap_ie dot11_extcap_ie_t; -+ -+#define DOT11_EXTCAP_LEN_MAX 7 -+#define DOT11_EXTCAP_LEN_COEX 1 -+#define DOT11_EXTCAP_LEN_BT 3 -+#define DOT11_EXTCAP_LEN_IW 4 -+#define DOT11_EXTCAP_LEN_SI 6 -+ -+#define DOT11_EXTCAP_LEN_TDLS 5 -+BWL_PRE_PACKED_STRUCT struct dot11_extcap { -+ uint8 extcap[DOT11_EXTCAP_LEN_TDLS]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extcap dot11_extcap_t; -+ -+/* TDLS Capabilities */ -+#define TDLS_CAP_TDLS 37 /* TDLS support */ -+#define TDLS_CAP_PU_BUFFER_STA 28 /* TDLS Peer U-APSD buffer STA support */ -+#define TDLS_CAP_PEER_PSM 20 /* TDLS Peer PSM support */ -+#define TDLS_CAP_CH_SW 30 /* TDLS Channel switch */ -+#define TDLS_CAP_PROH 38 /* TDLS prohibited */ -+#define TDLS_CAP_CH_SW_PROH 39 /* TDLS Channel switch prohibited */ -+ -+#define TDLS_CAP_MAX_BIT 39 /* TDLS max bit defined in ext cap */ -+ -+/* 802.11h/802.11k Measurement Request/Report IEs */ -+/* Measurement Type field */ -+#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ -+#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ -+#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement RPI type */ -+#define DOT11_MEASURE_TYPE_CHLOAD 3 /* d11 measurement Channel Load type */ -+#define DOT11_MEASURE_TYPE_NOISE 4 /* d11 measurement Noise Histogram type */ -+#define DOT11_MEASURE_TYPE_BEACON 5 /* d11 measurement Beacon type */ -+#define DOT11_MEASURE_TYPE_FRAME 6 /* d11 measurement Frame type */ -+#define DOT11_MEASURE_TYPE_STATS 7 /* d11 measurement STA Statistics type */ -+#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */ -+#define DOT11_MEASURE_TYPE_TXSTREAM 9 /* d11 measurement TX Stream type */ -+#define DOT11_MEASURE_TYPE_PAUSE 255 /* d11 measurement pause type */ -+ -+/* Measurement Request Modes */ -+#define DOT11_MEASURE_MODE_PARALLEL (1<<0) /* d11 measurement parallel */ -+#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ -+#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ -+#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ -+#define DOT11_MEASURE_MODE_DUR (1<<4) /* d11 measurement dur mandatory */ -+/* Measurement Report Modes */ -+#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ -+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ -+#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ -+/* Basic Measurement Map bits */ -+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ -+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ -+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ -+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ -+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_req { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_req dot11_meas_req_t; -+#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ -+/* length of Measure Request IE data not including variable len */ -+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ BWL_PRE_PACKED_STRUCT union -+ { -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+ } BWL_POST_PACKED_STRUCT basic; -+ uint8 data[1]; -+ } BWL_POST_PACKED_STRUCT rep; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_rep dot11_meas_rep_t; -+ -+/* length of Measure Report IE data not including variable len */ -+#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -+#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_quiet { -+ uint8 id; -+ uint8 len; -+ uint8 count; /* TBTTs until beacon interval in quiet starts */ -+ uint8 period; /* Beacon intervals between periodic quiet periods ? */ -+ uint16 duration; /* Length of quiet period, in TU's */ -+ uint16 offset; /* TU's offset from TBTT in Count field */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_quiet dot11_quiet_t; -+ -+BWL_PRE_PACKED_STRUCT struct chan_map_tuple { -+ uint8 channel; -+ uint8 map; -+} BWL_POST_PACKED_STRUCT; -+typedef struct chan_map_tuple chan_map_tuple_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { -+ uint8 id; -+ uint8 len; -+ uint8 eaddr[ETHER_ADDR_LEN]; -+ uint8 interval; -+ chan_map_tuple_t map[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; -+ -+/* WME Elements */ -+#define WME_OUI "\x00\x50\xf2" /* WME OUI */ -+#define WME_OUI_LEN 3 -+#define WME_OUI_TYPE 2 /* WME type */ -+#define WME_TYPE 2 /* WME type, deprecated */ -+#define WME_SUBTYPE_IE 0 /* Information Element */ -+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ -+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ -+#define WME_VER 1 /* WME version */ -+ -+/* WME Access Category Indices (ACIs) */ -+#define AC_BE 0 /* Best Effort */ -+#define AC_BK 1 /* Background */ -+#define AC_VI 2 /* Video */ -+#define AC_VO 3 /* Voice */ -+#define AC_COUNT 4 /* number of ACs */ -+ -+typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ -+ -+#define AC_BITMAP_NONE 0x0 /* No ACs */ -+#define AC_BITMAP_ALL 0xf /* All ACs */ -+#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -+#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) -+#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) -+ -+/* WME Information Element (IE) */ -+BWL_PRE_PACKED_STRUCT struct wme_ie { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 qosinfo; -+} BWL_POST_PACKED_STRUCT; -+typedef struct wme_ie wme_ie_t; -+#define WME_IE_LEN 7 /* WME IE length */ -+ -+BWL_PRE_PACKED_STRUCT struct edcf_acparam { -+ uint8 ACI; -+ uint8 ECW; -+ uint16 TXOP; /* stored in network order (ls octet first) */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct edcf_acparam edcf_acparam_t; -+ -+/* WME Parameter Element (PE) */ -+BWL_PRE_PACKED_STRUCT struct wme_param_ie { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 qosinfo; -+ uint8 rsvd; -+ edcf_acparam_t acparam[AC_COUNT]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct wme_param_ie wme_param_ie_t; -+#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ -+ -+/* QoS Info field for IE as sent from AP */ -+#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ -+#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ -+#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ -+#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ -+ -+/* QoS Info field for IE as sent from STA */ -+#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ -+#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ -+#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ -+#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ -+#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ -+#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ -+#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ -+#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ -+#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ -+#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ -+#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ -+#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ -+ -+/* ACI */ -+#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ -+#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ -+#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ -+#define EDCF_ACM_MASK 0x10 /* ACM mask */ -+#define EDCF_ACI_MASK 0x60 /* ACI mask */ -+#define EDCF_ACI_SHIFT 5 /* ACI shift */ -+#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ -+ -+/* ECW */ -+#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ -+#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ -+#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -+#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ -+#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ -+#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ -+ -+/* TXOP */ -+#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ -+#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ -+#define EDCF_TXOP2USEC(txop) ((txop) << 5) -+ -+/* Default BE ACI value for non-WME connection STA */ -+#define NON_EDCF_AC_BE_ACI_STA 0x02 -+ -+/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ -+#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ -+#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ -+#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ -+#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ -+#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ -+#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ -+#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ -+#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ -+#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ -+#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ -+#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ -+#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ -+ -+/* Default EDCF parameters that AP uses; WMM draft Table 14 */ -+#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ -+#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ -+#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ -+#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ -+#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ -+#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ -+#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ -+#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ -+#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ -+#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ -+#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ -+#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ -+ -+/* EDCA Parameter IE */ -+BWL_PRE_PACKED_STRUCT struct edca_param_ie { -+ uint8 qosinfo; -+ uint8 rsvd; -+ edcf_acparam_t acparam[AC_COUNT]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct edca_param_ie edca_param_ie_t; -+#define EDCA_PARAM_IE_LEN 18 /* EDCA Parameter IE length */ -+ -+/* QoS Capability IE */ -+BWL_PRE_PACKED_STRUCT struct qos_cap_ie { -+ uint8 qosinfo; -+} BWL_POST_PACKED_STRUCT; -+typedef struct qos_cap_ie qos_cap_ie_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { -+ uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ -+ uint8 length; -+ uint16 station_count; /* total number of STAs associated */ -+ uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ -+ uint16 aac; /* available admission capacity */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; -+#define BSS_LOAD_IE_SIZE 7 /* BSS load IE size */ -+ -+/* nom_msdu_size */ -+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ -+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ -+ -+/* surplus_bandwidth */ -+/* Represented as 3 bits of integer, binary point, 13 bits fraction */ -+#define INTEGER_SHIFT 13 /* integer shift */ -+#define FRACTION_MASK 0x1FFF /* fraction mask */ -+ -+/* Management Notification Frame */ -+BWL_PRE_PACKED_STRUCT struct dot11_management_notification { -+ uint8 category; /* DOT11_ACTION_NOTIFICATION */ -+ uint8 action; -+ uint8 token; -+ uint8 status; -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ -+ -+/* Timeout Interval IE */ -+BWL_PRE_PACKED_STRUCT struct ti_ie { -+ uint8 ti_type; -+ uint32 ti_val; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ti_ie ti_ie_t; -+#define TI_TYPE_REASSOC_DEADLINE 1 -+#define TI_TYPE_KEY_LIFETIME 2 -+ -+/* WME Action Codes */ -+#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ -+#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ -+#define WME_DELTS_REQUEST 2 /* WME DELTS request */ -+ -+/* WME Setup Response Status Codes */ -+#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ -+#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ -+#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ -+ -+/* Macro to take a pointer to a beacon or probe response -+ * body and return the char* pointer to the SSID info element -+ */ -+#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) -+ -+/* Authentication frame payload constants */ -+#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ -+#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ -+#define DOT11_FAST_BSS 2 /* d11 fast bss authentication */ -+#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */ -+ -+/* Frame control macros */ -+#define FC_PVER_MASK 0x3 /* PVER mask */ -+#define FC_PVER_SHIFT 0 /* PVER shift */ -+#define FC_TYPE_MASK 0xC /* type mask */ -+#define FC_TYPE_SHIFT 2 /* type shift */ -+#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ -+#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ -+#define FC_TODS 0x100 /* to DS */ -+#define FC_TODS_SHIFT 8 /* to DS shift */ -+#define FC_FROMDS 0x200 /* from DS */ -+#define FC_FROMDS_SHIFT 9 /* from DS shift */ -+#define FC_MOREFRAG 0x400 /* more frag. */ -+#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ -+#define FC_RETRY 0x800 /* retry */ -+#define FC_RETRY_SHIFT 11 /* retry shift */ -+#define FC_PM 0x1000 /* PM */ -+#define FC_PM_SHIFT 12 /* PM shift */ -+#define FC_MOREDATA 0x2000 /* more data */ -+#define FC_MOREDATA_SHIFT 13 /* more data shift */ -+#define FC_WEP 0x4000 /* WEP */ -+#define FC_WEP_SHIFT 14 /* WEP shift */ -+#define FC_ORDER 0x8000 /* order */ -+#define FC_ORDER_SHIFT 15 /* order shift */ -+ -+/* sequence control macros */ -+#define SEQNUM_SHIFT 4 /* seq. number shift */ -+#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ -+#define FRAGNUM_MASK 0xF /* frag. number mask */ -+ -+/* Frame Control type/subtype defs */ -+ -+/* FC Types */ -+#define FC_TYPE_MNG 0 /* management type */ -+#define FC_TYPE_CTL 1 /* control type */ -+#define FC_TYPE_DATA 2 /* data type */ -+ -+/* Management Subtypes */ -+#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ -+#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ -+#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ -+#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ -+#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ -+#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ -+#define FC_SUBTYPE_BEACON 8 /* beacon */ -+#define FC_SUBTYPE_ATIM 9 /* ATIM */ -+#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ -+#define FC_SUBTYPE_AUTH 11 /* authentication */ -+#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ -+#define FC_SUBTYPE_ACTION 13 /* action */ -+#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */ -+ -+/* Control Subtypes */ -+#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */ -+#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ -+#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ -+#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ -+#define FC_SUBTYPE_RTS 11 /* RTS */ -+#define FC_SUBTYPE_CTS 12 /* CTS */ -+#define FC_SUBTYPE_ACK 13 /* ACK */ -+#define FC_SUBTYPE_CF_END 14 /* CF-END */ -+#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ -+ -+/* Data Subtypes */ -+#define FC_SUBTYPE_DATA 0 /* Data */ -+#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ -+#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ -+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_NULL 4 /* Null */ -+#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ -+#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ -+#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ -+#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ -+#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ -+#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ -+#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ -+#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ -+ -+/* Data Subtype Groups */ -+#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -+#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -+#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -+#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) -+ -+/* Type/Subtype Combos */ -+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ -+ -+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ -+ -+#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ -+#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ -+ -+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ -+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ -+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ -+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ -+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ -+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ -+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ -+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ -+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ -+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ -+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ -+#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */ -+ -+#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */ -+#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ -+#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ -+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ -+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ -+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ -+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ -+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ -+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ -+ -+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ -+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ -+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ -+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ -+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ -+ -+/* QoS Control Field */ -+ -+/* 802.1D Priority */ -+#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ -+#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ -+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ -+ -+/* Traffic Identifier */ -+#define QOS_TID_SHIFT 0 /* QoS TID shift */ -+#define QOS_TID_MASK 0x000f /* QoS TID mask */ -+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ -+ -+/* End of Service Period (U-APSD) */ -+#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ -+#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ -+#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ -+ -+/* Ack Policy */ -+#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ -+#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ -+#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ -+#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ -+#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ -+#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ -+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ -+ -+/* A-MSDU flag */ -+#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ -+#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ -+ -+/* Management Frames */ -+ -+/* Management Frame Constants */ -+ -+/* Fixed fields */ -+#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ -+#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ -+#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ -+#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ -+#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ -+#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ -+#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ -+#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ -+#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ -+#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ -+ -+/* DUR/ID field in assoc resp is 0xc000 | AID */ -+#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ -+ -+/* Reason Codes */ -+#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ -+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ -+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ -+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station -+ * is leaving (or has left) IBSS or ESS -+ */ -+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ -+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle -+ * all currently associated stations -+ */ -+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from -+ * nonauthenticated station -+ */ -+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from -+ * nonassociated station -+ */ -+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is -+ * leaving (or has left) BSS -+ */ -+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not -+ * authenticated with responding station -+ */ -+#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ -+#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ -+/* 12 is unused */ -+ -+/* 32-39 are QSTA specific reasons added in 11e */ -+#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */ -+#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */ -+#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */ -+#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */ -+#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */ -+#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */ -+#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */ -+#define DOT11_RC_TIMEOUT 39 /* timeout */ -+ -+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ -+ -+#define DOT11_RC_TDLS_PEER_UNREACH 25 -+#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 -+ -+/* Status Codes */ -+#define DOT11_SC_SUCCESS 0 /* Successful */ -+#define DOT11_SC_FAILURE 1 /* Unspecified failure */ -+#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 /* TDLS wakeup schedule rejected but alternative */ -+ /* schedule provided */ -+#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 /* TDLS wakeup schedule rejected */ -+#define DOT11_SC_TDLS_SEC_DISABLED 5 /* TDLS Security disabled */ -+#define DOT11_SC_LIFETIME_REJ 6 /* Unacceptable lifetime */ -+#define DOT11_SC_NOT_SAME_BSS 7 /* Not in same BSS */ -+#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested -+ * capabilities in the Capability -+ * Information field -+ */ -+#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability -+ * to confirm that association exists -+ */ -+#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason -+ * outside the scope of this standard -+ */ -+#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support -+ * the specified authentication -+ * algorithm -+ */ -+#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame -+ * with authentication transaction -+ * sequence number out of expected -+ * sequence -+ */ -+#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of -+ * challenge failure -+ */ -+#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout -+ * waiting for next frame in sequence -+ */ -+#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is -+ * unable to handle additional -+ * associated stations -+ */ -+#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting -+ * station not supporting all of the -+ * data rates in the BSSBasicRateSet -+ * parameter -+ */ -+#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting -+ * station not supporting the Short -+ * Preamble option -+ */ -+#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting -+ * station not supporting the PBCC -+ * Modulation option -+ */ -+#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting -+ * station not supporting the Channel -+ * Agility option -+ */ -+#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum -+ * Management capability is required. -+ */ -+#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info -+ * in the Power Cap element is -+ * unacceptable. -+ */ -+#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info -+ * in the Supported Channel element is -+ * unacceptable -+ */ -+#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting -+ * station not supporting the Short Slot -+ * Time option -+ */ -+#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting -+ * station not supporting the ER-PBCC -+ * Modulation option -+ */ -+#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting -+ * station not supporting the DSS-OFDM -+ * option -+ */ -+#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 /* Association denied due to AP -+ * being unable to reach the R0 Key Holder -+ */ -+#define DOT11_SC_ASSOC_TRY_LATER 30 /* Association denied temporarily, try again later -+ */ -+#define DOT11_SC_ASSOC_MFP_VIOLATION 31 /* Association denied due to Robust Management -+ * frame policy violation -+ */ -+ -+#define DOT11_SC_DECLINED 37 /* request declined */ -+#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */ -+#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */ -+#define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */ -+#define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */ -+#define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */ -+#define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */ -+#define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */ -+#define DOT11_SC_INVALID_FTIE 55 /* Association denied due to invalid FTIE */ -+ -+#define DOT11_SC_UNEXP_MSG 70 /* Unexpected message */ -+#define DOT11_SC_INVALID_SNONCE 71 /* Invalid SNonce */ -+#define DOT11_SC_INVALID_RSNIE 72 /* Invalid contents of RSNIE */ -+ -+/* Info Elts, length of INFORMATION portion of Info Elts */ -+#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ -+#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ -+ -+/* TIM Info element has 3 bytes fixed info in INFORMATION field, -+ * followed by 1 to 251 bytes of Partial Virtual Bitmap -+ */ -+#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ -+#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ -+#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ -+#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ -+#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ -+ -+/* TLV defines */ -+#define TLV_TAG_OFF 0 /* tag offset */ -+#define TLV_LEN_OFF 1 /* length offset */ -+#define TLV_HDR_LEN 2 /* header length */ -+#define TLV_BODY_OFF 2 /* body offset */ -+ -+/* Management Frame Information Element IDs */ -+#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ -+#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ -+#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ -+#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ -+#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ -+#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ -+#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ -+#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ -+#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ -+#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ -+#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ -+#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ -+#define DOT11_MNG_EDCA_PARAM_ID 12 /* 11E EDCA Parameter id */ -+#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ -+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ -+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ -+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ -+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ -+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ -+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ -+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ -+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ -+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ -+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ -+#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ -+#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ -+#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */ -+#define DOT11_MNG_QOS_CAP_ID 46 /* 11E QoS Capability id */ -+#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ -+#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ -+#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ -+#define DOT11_MNG_AP_CHREP_ID 51 /* 11k AP Channel report id */ -+#define DOT11_MNG_NBR_REP_ID 52 /* 11k Neighbor report id */ -+#define DOT11_MNG_MDIE_ID 54 /* 11r Mobility domain id */ -+#define DOT11_MNG_FTIE_ID 55 /* 11r Fast Bss Transition id */ -+#define DOT11_MNG_FT_TI_ID 56 /* 11r Timeout Interval id */ -+#define DOT11_MNG_REGCLASS_ID 59 /* d11 management regulatory class id */ -+#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */ -+#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */ -+#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */ -+#ifdef BCMWAPI_WAI -+#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ -+#endif -+#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ -+#define DOT11_MNG_TIME_ADVERTISE_ID 69 /* 11p time advertisement */ -+#define DOT11_MNG_RRM_CAP_ID 70 /* 11k radio measurement capability */ -+#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 /* d11 mgmt OBSS Coexistence INFO */ -+#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 /* d11 mgmt OBSS Intolerant Channel list */ -+#define DOT11_MNG_HT_OBSS_ID 74 /* d11 mgmt OBSS HT info */ -+#define DOT11_MNG_CHANNEL_USAGE 97 /* 11v channel usage */ -+#define DOT11_MNG_TIME_ZONE_ID 98 /* 11v time zone */ -+#define DOT11_MNG_LINK_IDENTIFIER_ID 101 /* 11z TDLS Link Identifier IE */ -+#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 /* 11z TDLS Wakeup Schedule IE */ -+#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 /* 11z TDLS Channel Switch Timing IE */ -+#define DOT11_MNG_PTI_CONTROL_ID 105 /* 11z TDLS PTI Control IE */ -+#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 /* 11z TDLS PU Buffer Status IE */ -+#define DOT11_MNG_INTERWORKING_ID 107 /* 11u interworking */ -+#define DOT11_MNG_ADVERTISEMENT_ID 108 /* 11u advertisement protocol */ -+#define DOT11_MNG_EXP_BW_REQ_ID 109 /* 11u expedited bandwith request */ -+#define DOT11_MNG_QOS_MAP_ID 110 /* 11u QoS map set */ -+#define DOT11_MNG_ROAM_CONSORT_ID 111 /* 11u roaming consortium */ -+#define DOT11_MNG_EMERGCY_ALERT_ID 112 /* 11u emergency alert identifier */ -+#define DOT11_MNG_EXT_CAP_ID 127 /* d11 mgmt ext capability */ -+#define DOT11_MNG_VHT_CAP_ID 191 /* d11 mgmt VHT cap id */ -+#define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */ -+ -+#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ -+#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ -+/* should start using this one instead of above two */ -+#define DOT11_MNG_VS_ID 221 /* d11 management Vendor Specific IE */ -+ -+/* Rate element Basic flag and rate mask */ -+#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ -+#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ -+ -+/* ERP info element bit values */ -+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ -+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present -+ *in the BSS -+ */ -+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for -+ *ERP-OFDM frames -+ */ -+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, -+ * 1 == not allowed -+ */ -+/* TS Delay element offset & size */ -+#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ -+#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ -+ -+/* Capability Information Field */ -+#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ -+#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ -+#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ -+#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ -+#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ -+#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ -+#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ -+#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ -+#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ -+#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ -+#define DOT11_CAP_RRM 0x1000 /* d11 cap. 11k radio measurement */ -+#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ -+ -+/* Extended capabilities IE bitfields */ -+/* 20/40 BSS Coexistence Management support bit position */ -+#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0 -+/* scheduled PSMP support bit position */ -+#define DOT11_EXT_CAP_SPSMP 6 -+/* BSS Transition Management support bit position */ -+#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 -+/* Interworking support bit position */ -+#define DOT11_EXT_CAP_IW 31 -+/* service Interval granularity bit position and mask */ -+#define DOT11_EXT_CAP_SI 41 -+#define DOT11_EXT_CAP_SI_MASK 0x0E -+ -+/* -+ * Action Frame Constants -+ */ -+#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action field */ -+#define DOT11_ACTION_CAT_OFF 0 /* category offset */ -+#define DOT11_ACTION_ACT_OFF 1 /* action offset */ -+ -+/* Action Category field (sec 7.3.1.11) */ -+#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* category error mask */ -+#define DOT11_ACTION_CAT_MASK 0x7F /* category mask */ -+#define DOT11_ACTION_CAT_SPECT_MNG 0 /* category spectrum management */ -+#define DOT11_ACTION_CAT_QOS 1 /* category QoS */ -+#define DOT11_ACTION_CAT_DLS 2 /* category DLS */ -+#define DOT11_ACTION_CAT_BLOCKACK 3 /* category block ack */ -+#define DOT11_ACTION_CAT_PUBLIC 4 /* category public */ -+#define DOT11_ACTION_CAT_RRM 5 /* category radio measurements */ -+#define DOT11_ACTION_CAT_FBT 6 /* category fast bss transition */ -+#define DOT11_ACTION_CAT_HT 7 /* category for HT */ -+#define DOT11_ACTION_CAT_SA_QUERY 8 /* security association query */ -+#define DOT11_ACTION_CAT_PDPA 9 /* protected dual of public action */ -+#define DOT11_ACTION_CAT_BSSMGMT 10 /* category for BSS transition management */ -+#define DOT11_ACTION_NOTIFICATION 17 -+#define DOT11_ACTION_CAT_VSP 126 /* protected vendor specific */ -+#define DOT11_ACTION_CAT_VS 127 /* category Vendor Specific */ -+ -+/* Spectrum Management Action IDs (sec 7.4.1) */ -+#define DOT11_SM_ACTION_M_REQ 0 /* d11 action measurement request */ -+#define DOT11_SM_ACTION_M_REP 1 /* d11 action measurement response */ -+#define DOT11_SM_ACTION_TPC_REQ 2 /* d11 action TPC request */ -+#define DOT11_SM_ACTION_TPC_REP 3 /* d11 action TPC response */ -+#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ -+#define DOT11_SM_ACTION_EXT_CSA 5 /* d11 extened CSA for 11n */ -+ -+/* HT action ids */ -+#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */ -+#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */ -+ -+/* Public action ids */ -+#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 /* 20/40 Coexistence Management action id */ -+#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ -+ -+/* Block Ack action types */ -+#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ -+#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ -+#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ -+ -+/* ADDBA action parameters */ -+#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */ -+#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ -+#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ -+#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ -+#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ -+#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ -+#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ -+ -+#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ -+#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ -+ -+/* Fast Transition action types */ -+#define DOT11_FT_ACTION_FT_RESERVED 0 -+#define DOT11_FT_ACTION_FT_REQ 1 /* FBT request - for over-the-DS FBT */ -+#define DOT11_FT_ACTION_FT_RES 2 /* FBT response - for over-the-DS FBT */ -+#define DOT11_FT_ACTION_FT_CON 3 /* FBT confirm - for OTDS with RRP */ -+#define DOT11_FT_ACTION_FT_ACK 4 /* FBT ack */ -+ -+/* DLS action types */ -+#define DOT11_DLS_ACTION_REQ 0 /* DLS Request */ -+#define DOT11_DLS_ACTION_RESP 1 /* DLS Response */ -+#define DOT11_DLS_ACTION_TD 2 /* DLS Teardown */ -+ -+/* Wireless Network Management (WNM) action types */ -+#define DOT11_WNM_ACTION_EVENT_REQ 0 -+#define DOT11_WNM_ACTION_EVENT_REP 1 -+#define DOT11_WNM_ACTION_DIAG_REQ 2 -+#define DOT11_WNM_ACTION_DIAG_REP 3 -+#define DOT11_WNM_ACTION_LOC_CFG_REQ 4 -+#define DOT11_WNM_ACTION_LOC_RFG_RESP 5 -+#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6 -+#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7 -+#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8 -+#define DOT11_WNM_ACTION_FMS_REQ 9 -+#define DOT11_WNM_ACTION_FMS_RESP 10 -+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11 -+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12 -+#define DOT11_WNM_ACTION_TFS_REQ 13 -+#define DOT11_WNM_ACTION_TFS_RESP 14 -+#define DOT11_WNM_ACTION_TFS_NOTIFY 15 -+#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16 -+#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17 -+#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18 -+#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19 -+#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20 -+#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21 -+#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22 -+#define DOT11_WNM_ACTION_DMS_REQ 23 -+#define DOT11_WNM_ACTION_DMS_RESP 24 -+#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25 -+#define DOT11_WNM_ACTION_NOTFCTN_REQ 26 -+#define DOT11_WNM_ACTION_NOTFCTN_RES 27 -+ -+#define DOT11_MNG_COUNTRY_ID_LEN 3 -+ -+/* DLS Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_dls_req { -+ uint8 category; /* category of action frame (2) */ -+ uint8 action; /* DLS action: req (0) */ -+ struct ether_addr da; /* destination address */ -+ struct ether_addr sa; /* source address */ -+ uint16 cap; /* capability */ -+ uint16 timeout; /* timeout value */ -+ uint8 data[1]; /* IE:support rate, extend support rate, HT cap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_dls_req dot11_dls_req_t; -+#define DOT11_DLS_REQ_LEN 18 /* Fixed length */ -+ -+/* DLS response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_dls_resp { -+ uint8 category; /* category of action frame (2) */ -+ uint8 action; /* DLS action: req (0) */ -+ uint16 status; /* status code field */ -+ struct ether_addr da; /* destination address */ -+ struct ether_addr sa; /* source address */ -+ uint8 data[1]; /* optional: capability, rate ... */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_dls_resp dot11_dls_resp_t; -+#define DOT11_DLS_RESP_LEN 16 /* Fixed length */ -+ -+ -+/* BSS Management Transition Query frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_query (6) */ -+ uint8 token; /* dialog token */ -+ uint8 reason; /* transition query reason */ -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_query dot11_bss_trans_query_t; -+#define DOT11_BSS_TRANS_QUERY_LEN 4 /* Fixed length */ -+ -+/* BSS Management Transition Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_req (7) */ -+ uint8 token; /* dialog token */ -+ uint8 reqmode; /* transition request mode */ -+ uint16 disassoc_tmr; /* disassociation timer */ -+ uint8 validity_intrvl; /* validity interval */ -+ uint8 data[1]; /* optional: BSS term duration, ... */ -+ /* ...session info URL, list */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_req dot11_bss_trans_req_t; -+#define DOT11_BSS_TRANS_REQ_LEN 7 /* Fixed length */ -+ -+#define DOT11_BSS_TERM_DUR_LEN 12 /* Fixed length if present */ -+ -+ -+/* BSS Mgmt Transition Request Mode Field - 802.11v */ -+#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01 -+#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02 -+#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04 -+#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08 -+#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10 -+ -+ -+/* BSS Management transition response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_res (8) */ -+ uint8 token; /* dialog token */ -+ uint8 status; /* transition status */ -+ uint8 term_delay; /* validity interval */ -+ uint8 data[1]; /* optional: BSS term duration, ... */ -+ /* ...session info URL, list */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; -+#define DOT11_BSS_TRANS_RES_LEN 5 /* Fixed length */ -+ -+/* BSS Mgmt Transition Response Status Field */ -+#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0 -+#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8 -+ -+ -+/* Neighbor Report BSSID Information Field */ -+#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003 -+#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004 -+#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0 -+ -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200 -+ -+/* Neighbor Report Subelements */ -+#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 -+ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_addba_req { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba req */ -+ uint8 token; /* identifier */ -+ uint16 addba_param_set; /* parameter set */ -+ uint16 timeout; /* timeout in seconds */ -+ uint16 start_seqnum; /* starting sequence number */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_addba_req dot11_addba_req_t; -+#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba resp */ -+ uint8 token; /* identifier */ -+ uint16 status; /* status of add request */ -+ uint16 addba_param_set; /* negotiated parameter set */ -+ uint16 timeout; /* negotiated timeout in seconds */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_addba_resp dot11_addba_resp_t; -+#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ -+ -+/* DELBA action parameters */ -+#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ -+#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ -+#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ -+#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_delba { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba req */ -+ uint16 delba_param_set; /* paarmeter set */ -+ uint16 reason; /* reason for dellba */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_delba dot11_delba_t; -+#define DOT11_DELBA_LEN 6 /* length of delba frame */ -+ -+/* SA Query action field value */ -+#define SA_QUERY_REQUEST 0 -+#define SA_QUERY_RESPONSE 1 -+ -+/* ************* 802.11r related definitions. ************* */ -+ -+/* Over-the-DS Fast Transition Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_req { -+ uint8 category; /* category of action frame (6) */ -+ uint8 action; /* action: ft req */ -+ uint8 sta_addr[ETHER_ADDR_LEN]; -+ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_req dot11_ft_req_t; -+#define DOT11_FT_REQ_FIXED_LEN 14 -+ -+/* Over-the-DS Fast Transition Response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_res { -+ uint8 category; /* category of action frame (6) */ -+ uint8 action; /* action: ft resp */ -+ uint8 sta_addr[ETHER_ADDR_LEN]; -+ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; -+ uint16 status; /* status code */ -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_res dot11_ft_res_t; -+#define DOT11_FT_RES_FIXED_LEN 16 -+ -+ -+/* ************* 802.11k related definitions. ************* */ -+ -+/* Radio measurements enabled capability ie */ -+ -+#define DOT11_RRM_CAP_LEN 5 /* length of rrm cap bitmap */ -+BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie { -+ uint8 cap[DOT11_RRM_CAP_LEN]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t; -+ -+/* Bitmap definitions for cap ie */ -+#define DOT11_RRM_CAP_LINK 0 -+#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 -+#define DOT11_RRM_CAP_PARALLEL 2 -+#define DOT11_RRM_CAP_REPEATED 3 -+#define DOT11_RRM_CAP_BCN_PASSIVE 4 -+#define DOT11_RRM_CAP_BCN_ACTIVE 5 -+#define DOT11_RRM_CAP_BCN_TABLE 6 -+#define DOT11_RRM_CAP_BCN_REP_COND 7 -+#define DOT11_RRM_CAP_AP_CHANREP 16 -+ -+ -+/* Operating Class (formerly "Regulatory Class") definitions */ -+#define DOT11_OP_CLASS_NONE 255 -+ -+ -+/* Radio Measurements action ids */ -+#define DOT11_RM_ACTION_RM_REQ 0 /* Radio measurement request */ -+#define DOT11_RM_ACTION_RM_REP 1 /* Radio measurement report */ -+#define DOT11_RM_ACTION_LM_REQ 2 /* Link measurement request */ -+#define DOT11_RM_ACTION_LM_REP 3 /* Link measurement report */ -+#define DOT11_RM_ACTION_NR_REQ 4 /* Neighbor report request */ -+#define DOT11_RM_ACTION_NR_REP 5 /* Neighbor report response */ -+ -+/* Generic radio measurement action frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_rm_action { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rm_action dot11_rm_action_t; -+#define DOT11_RM_ACTION_LEN 3 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmreq { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint16 reps; /* no. of repetitions */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmreq dot11_rmreq_t; -+#define DOT11_RMREQ_LEN 5 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rm_ie dot11_rm_ie_t; -+#define DOT11_RM_IE_LEN 5 -+ -+/* Definitions for "mode" bits in rm req */ -+#define DOT11_RMREQ_MODE_PARALLEL 1 -+#define DOT11_RMREQ_MODE_ENABLE 2 -+#define DOT11_RMREQ_MODE_REQUEST 4 -+#define DOT11_RMREQ_MODE_REPORT 8 -+#define DOT11_RMREQ_MODE_DURMAND 0x10 /* Duration Mandatory */ -+ -+/* Definitions for "mode" bits in rm rep */ -+#define DOT11_RMREP_MODE_LATE 1 -+#define DOT11_RMREP_MODE_INCAPABLE 2 -+#define DOT11_RMREP_MODE_REFUSED 4 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ uint8 reg; -+ uint8 channel; -+ uint16 interval; -+ uint16 duration; -+ uint8 bcn_mode; -+ struct ether_addr bssid; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; -+#define DOT11_RMREQ_BCN_LEN 18 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { -+ uint8 reg; -+ uint8 channel; -+ uint32 starttime[2]; -+ uint16 duration; -+ uint8 frame_info; -+ uint8 rcpi; -+ uint8 rsni; -+ struct ether_addr bssid; -+ uint8 antenna_id; -+ uint32 parent_tsf; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t; -+#define DOT11_RMREP_BCN_LEN 26 -+ -+/* Beacon request measurement mode */ -+#define DOT11_RMREQ_BCN_PASSIVE 0 -+#define DOT11_RMREQ_BCN_ACTIVE 1 -+#define DOT11_RMREQ_BCN_TABLE 2 -+ -+/* Sub-element IDs for Beacon Request */ -+#define DOT11_RMREQ_BCN_SSID_ID 0 -+#define DOT11_RMREQ_BCN_REPINFO_ID 1 -+#define DOT11_RMREQ_BCN_REPDET_ID 2 -+#define DOT11_RMREQ_BCN_REQUEST_ID 10 -+#define DOT11_RMREQ_BCN_APCHREP_ID 51 -+ -+/* Reporting Detail element definition */ -+#define DOT11_RMREQ_BCN_REPDET_FIXED 0 /* Fixed length fields only */ -+#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 /* + requested information elems */ -+#define DOT11_RMREQ_BCN_REPDET_ALL 2 /* All fields */ -+ -+/* Sub-element IDs for Beacon Report */ -+#define DOT11_RMREP_BCN_FRM_BODY 1 -+ -+/* Neighbor measurement report */ -+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { -+ struct ether_addr bssid; -+ uint32 bssid_info; -+ uint8 reg; -+ uint8 channel; -+ uint8 phytype; -+ uchar sub_elements[1]; /* Variable size data */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; -+#define DOT11_RMREP_NBR_LEN 13 -+ -+/* MLME Enumerations */ -+#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ -+#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ -+#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ -+#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ -+#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ -+ -+/* Link Measurement */ -+BWL_PRE_PACKED_STRUCT struct dot11_lmreq { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint8 txpwr; /* Transmit Power Used */ -+ uint8 maxtxpwr; /* Max Transmit Power */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_lmreq dot11_lmreq_t; -+#define DOT11_LMREQ_LEN 5 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_lmrep { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ dot11_tpc_rep_t tpc; /* TPC element */ -+ uint8 rxant; /* Receive Antenna ID */ -+ uint8 txant; /* Transmit Antenna ID */ -+ uint8 rcpi; /* RCPI */ -+ uint8 rsni; /* RSNI */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_lmrep dot11_lmrep_t; -+#define DOT11_LMREP_LEN 11 -+ -+/* 802.11 BRCM "Compromise" Pre N constants */ -+#define PREN_PREAMBLE 24 /* green field preamble time */ -+#define PREN_MM_EXT 12 /* extra mixed mode preamble time */ -+#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ -+ -+/* 802.11N PHY constants */ -+#define RIFS_11N_TIME 2 /* NPHY RIFS time */ -+ -+/* 802.11 HT PLCP format 802.11n-2009, sec 20.3.9.4.3 -+ * HT-SIG is composed of two 24 bit parts, HT-SIG1 and HT-SIG2 -+ */ -+/* HT-SIG1 */ -+#define HT_SIG1_MCS_MASK 0x00007F -+#define HT_SIG1_CBW 0x000080 -+#define HT_SIG1_HT_LENGTH 0xFFFF00 -+ -+/* HT-SIG2 */ -+#define HT_SIG2_SMOOTHING 0x000001 -+#define HT_SIG2_NOT_SOUNDING 0x000002 -+#define HT_SIG2_RESERVED 0x000004 -+#define HT_SIG2_AGGREGATION 0x000008 -+#define HT_SIG2_STBC_MASK 0x000030 -+#define HT_SIG2_STBC_SHIFT 4 -+#define HT_SIG2_FEC_CODING 0x000040 -+#define HT_SIG2_SHORT_GI 0x000080 -+#define HT_SIG2_ESS_MASK 0x000300 -+#define HT_SIG2_ESS_SHIFT 8 -+#define HT_SIG2_CRC 0x03FC00 -+#define HT_SIG2_TAIL 0x1C0000 -+ -+/* 802.11 A PHY constants */ -+#define APHY_SLOT_TIME 9 /* APHY slot time */ -+#define APHY_SIFS_TIME 16 /* APHY SIFS time */ -+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ -+#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ -+#define APHY_SIGNAL_TIME 4 /* APHY signal time */ -+#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ -+#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ -+#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ -+#define APHY_CWMIN 15 /* APHY cwmin */ -+ -+/* 802.11 B PHY constants */ -+#define BPHY_SLOT_TIME 20 /* BPHY slot time */ -+#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ -+#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ -+#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ -+#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ -+#define BPHY_CWMIN 31 /* BPHY cwmin */ -+ -+/* 802.11 G constants */ -+#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ -+ -+#define PHY_CWMAX 1023 /* PHY cwmax */ -+ -+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ -+ -+/* 802.11 AC (VHT) constants */ -+ -+typedef int vht_group_id_t; -+ -+/* for VHT-A1 */ -+/* SIG-A1 reserved bits */ -+#define VHT_SIGA1_CONST_MASK 0x800004 -+ -+#define VHT_SIGA1_20MHZ_VAL 0x000000 -+#define VHT_SIGA1_40MHZ_VAL 0x000001 -+#define VHT_SIGA1_80MHZ_VAL 0x000002 -+#define VHT_SIGA1_160MHZ_VAL 0x000003 -+ -+#define VHT_SIGA1_STBC 0x000008 -+ -+#define VHT_SIGA1_GID_MAX_GID 0x3f -+#define VHT_SIGA1_GID_SHIFT 4 -+#define VHT_SIGA1_GID_TO_AP 0x00 -+#define VHT_SIGA1_GID_NOT_TO_AP 0x3f -+ -+#define VHT_SIGA1_NSTS_SHIFT 10 -+#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00 -+ -+#define VHT_SIGA1_PARTIAL_AID_SHIFT 13 -+ -+/* for VHT-A2 */ -+#define VHT_SIGA2_GI_NONE 0x000000 -+#define VHT_SIGA2_GI_SHORT 0x000001 -+#define VHT_SIGA2_GI_W_MOD10 0x000002 -+#define VHT_SIGA2_CODING_LDPC 0x000004 -+#define VHT_SIGA2_BEAMFORM_ENABLE 0x000100 -+#define VHT_SIGA2_MCS_SHIFT 4 -+ -+#define VHT_SIGA2_B9_RESERVED 0x000200 -+#define VHT_SIGA2_TAIL_MASK 0xfc0000 -+#define VHT_SIGA2_TAIL_VALUE 0x000000 -+ -+#define VHT_SIGA2_SVC_BITS 16 -+#define VHT_SIGA2_TAIL_BITS 6 -+ -+ -+/* dot11Counters Table - 802.11 spec., Annex D */ -+typedef struct d11cnt { -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+} d11cnt_t; -+ -+/* OUI for BRCM proprietary IE */ -+#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ -+ -+ -+/* BRCM OUI: Used in the proprietary(221) IE in all broadcom devices */ -+#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ -+ -+/* BRCM info element */ -+BWL_PRE_PACKED_STRUCT struct brcm_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ -+ uint8 ver; /* type/ver of this IE */ -+ uint8 assoc; /* # of assoc STAs */ -+ uint8 flags; /* misc flags */ -+ uint8 flags1; /* misc flags */ -+ uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct brcm_ie brcm_ie_t; -+#define BRCM_IE_LEN 11 /* BRCM IE length */ -+#define BRCM_IE_VER 2 /* BRCM IE version */ -+#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ -+ -+/* brcm_ie flags */ -+#define BRF_LZWDS 0x4 /* lazy wds enabled */ -+#define BRF_BLOCKACK 0x8 /* BlockACK capable */ -+ -+/* brcm_ie flags1 */ -+#define BRF1_AMSDU 0x1 /* A-MSDU capable */ -+#define BRF1_WMEPS 0x4 /* AP is capable of handling WME + PS w/o APSD */ -+#define BRF1_PSOFIX 0x8 /* AP has fixed PS mode out-of-order packets */ -+#define BRF1_RX_LARGE_AGG 0x10 /* device can rx large aggregates */ -+#define BRF1_RFAWARE_DCS 0x20 /* RFAWARE dynamic channel selection (DCS) */ -+#define BRF1_SOFTAP 0x40 /* Configure as Broadcom SOFTAP */ -+ -+/* Vendor IE structure */ -+BWL_PRE_PACKED_STRUCT struct vndr_ie { -+ uchar id; -+ uchar len; -+ uchar oui [3]; -+ uchar data [1]; /* Variable size data */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct vndr_ie vndr_ie_t; -+ -+#define VNDR_IE_HDR_LEN 2 /* id + len field */ -+#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ -+#define VNDR_IE_FIXED_LEN (VNDR_IE_HDR_LEN + VNDR_IE_MIN_LEN) -+#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ -+ -+/* ************* HT definitions. ************* */ -+#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ -+#define MAX_MCS_NUM (128) /* max mcs number = 128 */ -+ -+BWL_PRE_PACKED_STRUCT struct ht_cap_ie { -+ uint16 cap; -+ uint8 params; -+ uint8 supp_mcs[MCSSET_LEN]; -+ uint16 ext_htcap; -+ uint32 txbf_cap; -+ uint8 as_cap; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_cap_ie ht_cap_ie_t; -+ -+/* CAP IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -+/* the capability IE is primarily used to convey this nodes abilities */ -+BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* type inidicates what follows */ -+ ht_cap_ie_t cap_ie; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; -+ -+#define HT_PROP_IE_OVERHEAD 4 /* overhead bytes for prop oui ie */ -+#define HT_CAP_IE_LEN 26 /* HT capability len (based on .11n d2.0) */ -+#define HT_CAP_IE_TYPE 51 -+ -+#define HT_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */ -+#define HT_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */ -+#define HT_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ -+#define HT_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ -+#define HT_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ -+#define HT_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ -+#define HT_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ -+#define HT_CAP_GF 0x0010 /* Greenfield preamble support */ -+#define HT_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ -+#define HT_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ -+#define HT_CAP_TX_STBC 0x0080 /* Tx STBC support */ -+#define HT_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ -+#define HT_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ -+#define HT_CAP_DELAYED_BA 0x0400 /* delayed BA support */ -+#define HT_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ -+ -+#define HT_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ -+#define HT_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ -+#define HT_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */ -+#define HT_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ -+ -+#define HT_CAP_RX_STBC_NO 0x0 /* no rx STBC support */ -+#define HT_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */ -+#define HT_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */ -+#define HT_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */ -+ -+#define VHT_MAX_MPDU 11454 /* max mpdu size for now (bytes) */ -+#define VHT_MPDU_MSDU_DELTA 56 /* Difference in spec - vht mpdu, amsdu len */ -+/* Max AMSDU len - per spec */ -+#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA) -+ -+#define HT_MAX_AMSDU 7935 /* max amsdu size (bytes) per the HT spec */ -+#define HT_MIN_AMSDU 3835 /* min amsdu size (bytes) per the HT spec */ -+ -+#define HT_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ -+#define HT_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ -+#define HT_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ -+ -+/* HT/AMPDU specific define */ -+#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/4 usec units */ -+#define AMPDU_DENSITY_NONE 0 /* No density requirement */ -+#define AMPDU_DENSITY_1over4_US 1 /* 1/4 us density */ -+#define AMPDU_DENSITY_1over2_US 2 /* 1/2 us density */ -+#define AMPDU_DENSITY_1_US 3 /* 1 us density */ -+#define AMPDU_DENSITY_2_US 4 /* 2 us density */ -+#define AMPDU_DENSITY_4_US 5 /* 4 us density */ -+#define AMPDU_DENSITY_8_US 6 /* 8 us density */ -+#define AMPDU_DENSITY_16_US 7 /* 16 us density */ -+#define AMPDU_RX_FACTOR_8K 0 /* max rcv ampdu len (8kb) */ -+#define AMPDU_RX_FACTOR_16K 1 /* max rcv ampdu len (16kb) */ -+#define AMPDU_RX_FACTOR_32K 2 /* max rcv ampdu len (32kb) */ -+#define AMPDU_RX_FACTOR_64K 3 /* max rcv ampdu len (64kb) */ -+#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ -+ -+#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ -+#define AMPDU_DELIMITER_LEN_MAX 63 /* max length of ampdu delimiter(enforced in HW) */ -+ -+#define HT_CAP_EXT_PCO 0x0001 -+#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 -+#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 -+#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 -+#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 -+#define HT_CAP_EXT_HTC 0x0400 -+#define HT_CAP_EXT_RD_RESP 0x0800 -+ -+BWL_PRE_PACKED_STRUCT struct ht_add_ie { -+ uint8 ctl_ch; /* control channel number */ -+ uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ -+ uint16 opmode; /* operation mode */ -+ uint16 misc_bits; /* misc bits */ -+ uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_add_ie ht_add_ie_t; -+ -+/* ADD IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -+/* the additional IE is primarily used to convey the current BSS configuration */ -+BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* indicates what follows */ -+ ht_add_ie_t add_ie; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_prop_add_ie ht_prop_add_ie_t; -+ -+#define HT_ADD_IE_LEN 22 -+#define HT_ADD_IE_TYPE 52 -+ -+/* byte1 defn's */ -+#define HT_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ -+#define HT_RIFS_PERMITTED 0x08 /* RIFS allowed */ -+ -+/* opmode defn's */ -+#define HT_OPMODE_MASK 0x0003 /* protection mode mask */ -+#define HT_OPMODE_SHIFT 0 /* protection mode shift */ -+#define HT_OPMODE_PURE 0x0000 /* protection mode PURE */ -+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ -+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ -+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ -+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ -+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ -+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ -+ -+/* misc_bites defn's */ -+#define HT_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ -+#define HT_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ -+#define HT_SECOND_BCN 0x0100 /* Secondary beacon support */ -+#define HT_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ -+#define HT_PCO_ACTIVE 0x0400 /* PCO active */ -+#define HT_PCO_PHASE 0x0800 /* PCO phase */ -+#define HT_DUALCTS_PROTECTION 0x0080 /* DUAL CTS protection needed */ -+ -+/* Tx Burst Limits */ -+#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */ -+#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */ -+ -+/* Macros for opmode */ -+#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ >> HT_OPMODE_SHIFT) -+#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_MIXED) /* mixed mode present */ -+#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_HT20IN40) /* 20MHz HT present */ -+#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_OPTIONAL) /* Optional protection present */ -+#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ -+ HT_MIXEDMODE_PRESENT((add_ie))) /* use protection */ -+#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ -+ == HT_OPMODE_NONGF) /* non-GF present */ -+#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ -+ == DOT11N_TXBURST) /* Tx Burst present */ -+#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ -+ == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */ -+ -+BWL_PRE_PACKED_STRUCT struct obss_params { -+ uint16 passive_dwell; -+ uint16 active_dwell; -+ uint16 bss_widthscan_interval; -+ uint16 passive_total; -+ uint16 active_total; -+ uint16 chanwidth_transition_dly; -+ uint16 activity_threshold; -+} BWL_POST_PACKED_STRUCT; -+typedef struct obss_params obss_params_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { -+ uint8 id; -+ uint8 len; -+ obss_params_t obss_params; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_ie dot11_obss_ie_t; -+#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) /* HT OBSS len (based on 802.11n d3.0) */ -+ -+/* HT control field */ -+#define HT_CTRL_LA_TRQ 0x00000002 /* sounding request */ -+#define HT_CTRL_LA_MAI 0x0000003C /* MCS request or antenna selection indication */ -+#define HT_CTRL_LA_MAI_SHIFT 2 -+#define HT_CTRL_LA_MAI_MRQ 0x00000004 /* MCS request */ -+#define HT_CTRL_LA_MAI_MSI 0x00000038 /* MCS request sequence identifier */ -+#define HT_CTRL_LA_MFSI 0x000001C0 /* MFB sequence identifier */ -+#define HT_CTRL_LA_MFSI_SHIFT 6 -+#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 /* MCS feedback, antenna selection command/data */ -+#define HT_CTRL_LA_MFB_ASELC_SH 9 -+#define HT_CTRL_LA_ASELC_CMD 0x00000C00 /* ASEL command */ -+#define HT_CTRL_LA_ASELC_DATA 0x0000F000 /* ASEL data */ -+#define HT_CTRL_CAL_POS 0x00030000 /* Calibration position */ -+#define HT_CTRL_CAL_SEQ 0x000C0000 /* Calibration sequence */ -+#define HT_CTRL_CSI_STEERING 0x00C00000 /* CSI/Steering */ -+#define HT_CTRL_CSI_STEER_SHIFT 22 -+#define HT_CTRL_CSI_STEER_NFB 0 /* no fedback required */ -+#define HT_CTRL_CSI_STEER_CSI 1 /* CSI, H matrix */ -+#define HT_CTRL_CSI_STEER_NCOM 2 /* non-compressed beamforming */ -+#define HT_CTRL_CSI_STEER_COM 3 /* compressed beamforming */ -+#define HT_CTRL_NDP_ANNOUNCE 0x01000000 /* NDP announcement */ -+#define HT_CTRL_AC_CONSTRAINT 0x40000000 /* AC Constraint */ -+#define HT_CTRL_RDG_MOREPPDU 0x80000000 /* RDG/More PPDU */ -+ -+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ -+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ -+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ -+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ -+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ -+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ -+ -+/* ************* VHT definitions. ************* */ -+ -+BWL_PRE_PACKED_STRUCT struct vht_cap_ie { -+ uint32 vht_cap_info; -+ /* supported MCS set - 64 bit field */ -+ uint16 rx_mcs_map; -+ uint16 rx_max_rate; -+ uint16 tx_mcs_map; -+ uint16 tx_max_rate; -+} BWL_POST_PACKED_STRUCT; -+typedef struct vht_cap_ie vht_cap_ie_t; -+/* 4B cap_info + 8B supp_mcs */ -+#define VHT_CAP_IE_LEN 12 -+/* 32bit - cap info */ -+#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK 0x00000003 -+#define VHT_CAP_INFO_SUPP_CHAN_WIDTH_MASK 0x0000000c -+#define VHT_CAP_INFO_LDPC 0x00000010 -+#define VHT_CAP_INFO_SGI_80MHZ 0x00000020 -+ -+#define VHT_CAP_INFO_SGI_160MHZ 0x00000040 -+#define VHT_CAP_INFO_TX_STBC 0x00000080 -+ -+#define VHT_CAP_INFO_RX_STBC_MASK 0x00000700 -+#define VHT_CAP_INFO_RX_STBC_SHIFT 8 -+#define VHT_CAP_INFO_SU_BEAMFMR 0x00000800 -+#define VHT_CAP_INFO_SU_BEAMFMEE 0x00001000 -+#define VHT_CAP_INFO_NUM_BMFMR_ANT_MASK 0x0000e000 -+#define VHT_CAP_INFO_NUM_BMFMR_ANT_SHIFT 13 -+ -+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_MASK 0x00070000 -+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_SHIFT 16 -+#define VHT_CAP_INFO_MU_BEAMFMR 0x00080000 -+#define VHT_CAP_INFO_MU_BEAMFMEE 0x00100000 -+#define VHT_CAP_INFO_TXOPPS 0x00200000 -+#define VHT_CAP_INFO_HTCVHT 0x00400000 -+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_MASK 0x03800000 -+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT 23 -+ -+#define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK 0x0c000000 -+#define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT 26 -+ -+/* 64-bit Supp MCS. */ -+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK 0x1fff -+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_SHIFT 0 -+ -+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK 0x1fff -+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT 0 -+ -+#define VHT_CAP_MCS_MAP_0_7 0 -+#define VHT_CAP_MCS_MAP_0_8 1 -+#define VHT_CAP_MCS_MAP_0_9 2 -+#define VHT_CAP_MCS_MAP_NONE 3 -+ -+#define VHT_CAP_MCS_MAP_NSS_MAX 8 -+ -+/* VHT Capabilities Supported Channel Width */ -+typedef enum vht_cap_chan_width { -+ VHT_CAP_CHAN_WIDTH_20_40 = 0x00, -+ VHT_CAP_CHAN_WIDTH_80 = 0x04, -+ VHT_CAP_CHAN_WIDTH_160 = 0x08 -+} vht_cap_chan_width_t; -+ -+/* VHT Capabilities Supported max MPDU LEN */ -+typedef enum vht_cap_max_mpdu_len { -+ VHT_CAP_MPDU_MAX_4K = 0x00, -+ VHT_CAP_MPDU_MAX_8K = 0x01, -+ VHT_CAP_MPDU_MAX_11K = 0x02 -+} vht_cap_max_mpdu_len_t; -+ -+/* VHT Operation Element */ -+BWL_PRE_PACKED_STRUCT struct vht_op_ie { -+ uint8 chan_width; -+ uint8 chan1; -+ uint8 chan2; -+ uint16 supp_mcs; /* same def as above in vht cap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct vht_op_ie vht_op_ie_t; -+/* 3B VHT Op info + 2B Basic MCS */ -+#define VHT_OP_IE_LEN 5 -+ -+typedef enum vht_op_chan_width { -+ VHT_OP_CHAN_WIDTH_20_40 = 0, -+ VHT_OP_CHAN_WIDTH_80 = 1, -+ VHT_OP_CHAN_WIDTH_160 = 2, -+ VHT_OP_CHAN_WIDTH_80_80 = 3 -+} vht_op_chan_width_t; -+ -+/* Def for rx & tx basic mcs maps - ea ss num has 2 bits of info */ -+#define VHT_MCS_MAP_GET_SS_IDX(nss) (((nss)-1)*2) -+#define VHT_MCS_MAP_GET_MCS_PER_SS(nss, mcsMap) \ -+ (((mcsMap) >> VHT_MCS_MAP_GET_SS_IDX(nss)) & 0x3) -+#define VHT_MCS_MAP_SET_MCS_PER_SS(nss, numMcs, mcsMap) \ -+ ((mcsMap) |= (((numMcs) & 0x3) << VHT_MCS_MAP_GET_SS_IDX(nss))) -+ -+/* ************* WPA definitions. ************* */ -+#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ -+#define WPA_OUI_LEN 3 /* WPA OUI length */ -+#define WPA_OUI_TYPE 1 -+#define WPA_VERSION 1 /* WPA version */ -+#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ -+#define WPA2_OUI_LEN 3 /* WPA2 OUI length */ -+#define WPA2_VERSION 1 /* WPA2 version */ -+#define WPA2_VERSION_LEN 2 /* WAP2 version length */ -+ -+/* ************* WPS definitions. ************* */ -+#define WPS_OUI "\x00\x50\xF2" /* WPS OUI */ -+#define WPS_OUI_LEN 3 /* WPS OUI length */ -+#define WPS_OUI_TYPE 4 -+ -+/* ************* WFA definitions. ************* */ -+ -+#ifdef P2P_IE_OVRD -+#define WFA_OUI MAC_OUI -+#else -+#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */ -+#endif /* P2P_IE_OVRD */ -+#define WFA_OUI_LEN 3 /* WFA OUI length */ -+#ifdef P2P_IE_OVRD -+#define WFA_OUI_TYPE_P2P MAC_OUI_TYPE_P2P -+#else -+#define WFA_OUI_TYPE_P2P 9 -+#endif -+ -+#define WFA_OUI_TYPE_TPC 8 -+#ifdef WLTDLS -+#define WFA_OUI_TYPE_WFD 10 -+#endif /* WTDLS */ -+ -+/* RSN authenticated key managment suite */ -+#define RSN_AKM_NONE 0 /* None (IBSS) */ -+#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ -+#define RSN_AKM_PSK 2 /* Pre-shared Key */ -+#define RSN_AKM_FBT_1X 3 /* Fast Bss transition using 802.1X */ -+#define RSN_AKM_FBT_PSK 4 /* Fast Bss transition using Pre-shared Key */ -+#define RSN_AKM_MFP_1X 5 /* SHA256 key derivation, using 802.1X */ -+#define RSN_AKM_MFP_PSK 6 /* SHA256 key derivation, using Pre-shared Key */ -+#define RSN_AKM_TPK 7 /* TPK(TDLS Peer Key) handshake */ -+ -+/* Key related defines */ -+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ -+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ -+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ -+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ -+#define DOT11_WPA_KEY_RSC_LEN 8 /* WPA RSC key len */ -+ -+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ -+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ -+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ -+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ -+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ -+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ -+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ -+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ -+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ -+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ -+#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ -+#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ -+#define AES_KEY_SIZE 16 /* size of AES key */ -+#define AES_MIC_SIZE 8 /* size of AES MIC */ -+#define BIP_KEY_SIZE 16 /* size of BIP key */ -+ -+/* WCN */ -+#define WCN_OUI "\x00\x50\xf2" /* WCN OUI */ -+#define WCN_TYPE 4 /* WCN type */ -+#ifdef BCMWAPI_WPI -+#define SMS4_KEY_LEN 16 -+#define SMS4_WPI_CBC_MAC_LEN 16 -+#endif -+ -+ -+/* 802.11r protocol definitions */ -+ -+/* Mobility Domain IE */ -+BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { -+ uint8 id; -+ uint8 len; -+ uint16 mdid; /* Mobility Domain Id */ -+ uint8 cap; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_mdid_ie dot11_mdid_ie_t; -+ -+#define FBT_MDID_CAP_OVERDS 0x01 /* Fast Bss transition over the DS support */ -+#define FBT_MDID_CAP_RRP 0x02 /* Resource request protocol support */ -+ -+/* Fast Bss Transition IE */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { -+ uint8 id; -+ uint8 len; -+ uint16 mic_control; /* Mic Control */ -+ uint8 mic[16]; -+ uint8 anonce[32]; -+ uint8 snonce[32]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_ie dot11_ft_ie_t; -+ -+#define TIE_TYPE_RESERVED 0 -+#define TIE_TYPE_REASSOC_DEADLINE 1 -+#define TIE_TYPE_KEY_LIEFTIME 2 -+#define TIE_TYPE_ASSOC_COMEBACK 3 -+BWL_PRE_PACKED_STRUCT struct dot11_timeout_ie { -+ uint8 id; -+ uint8 len; -+ uint8 type; /* timeout interval type */ -+ uint32 value; /* timeout interval value */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_timeout_ie dot11_timeout_ie_t; -+ -+ -+/* GTK ie */ -+BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { -+ uint8 id; -+ uint8 len; -+ uint16 key_info; -+ uint8 key_len; -+ uint8 rsc[8]; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_gtk_ie dot11_gtk_ie_t; -+ -+#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" -+#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" -+ -+ -+/* ************* WMM Parameter definitions. ************* */ -+#define WMM_OUI "\x00\x50\xF2" /* WNN OUI */ -+#define WMM_OUI_LEN 3 /* WMM OUI length */ -+#define WMM_OUI_TYPE 2 /* WMM OUT type */ -+#define WMM_VERSION 1 -+#define WMM_VERSION_LEN 1 -+ -+/* WMM OUI subtype */ -+#define WMM_OUI_SUBTYPE_PARAMETER 1 -+#define WMM_PARAMETER_IE_LEN 24 -+ -+/* Link Identifier Element */ -+BWL_PRE_PACKED_STRUCT struct link_id_ie { -+ uint8 id; -+ uint8 len; -+ struct ether_addr bssid; -+ struct ether_addr tdls_init_mac; -+ struct ether_addr tdls_resp_mac; -+} BWL_POST_PACKED_STRUCT; -+typedef struct link_id_ie link_id_ie_t; -+#define TDLS_LINK_ID_IE_LEN 18 -+ -+/* Link Wakeup Schedule Element */ -+BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie { -+ uint8 id; -+ uint8 len; -+ uint32 offset; /* in ms between TSF0 and start of 1st Awake Window */ -+ uint32 interval; /* in ms bwtween the start of 2 Awake Windows */ -+ uint32 awake_win_slots; /* in backof slots, duration of Awake Window */ -+ uint32 max_wake_win; /* in ms, max duration of Awake Window */ -+ uint16 idle_cnt; /* number of consecutive Awake Windows */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wakeup_sch_ie wakeup_sch_ie_t; -+#define TDLS_WAKEUP_SCH_IE_LEN 18 -+ -+/* Channel Switch Timing Element */ -+BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie { -+ uint8 id; -+ uint8 len; -+ uint16 switch_time; /* in ms, time to switch channels */ -+ uint16 switch_timeout; /* in ms */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct channel_switch_timing_ie channel_switch_timing_ie_t; -+#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4 -+ -+/* PTI Control Element */ -+BWL_PRE_PACKED_STRUCT struct pti_control_ie { -+ uint8 id; -+ uint8 len; -+ uint8 tid; -+ uint16 seq_control; -+} BWL_POST_PACKED_STRUCT; -+typedef struct pti_control_ie pti_control_ie_t; -+#define TDLS_PTI_CONTROL_IE_LEN 3 -+ -+/* PU Buffer Status Element */ -+BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie { -+ uint8 id; -+ uint8 len; -+ uint8 status; -+} BWL_POST_PACKED_STRUCT; -+typedef struct pu_buffer_status_ie pu_buffer_status_ie_t; -+#define TDLS_PU_BUFFER_STATUS_IE_LEN 1 -+#define TDLS_PU_BUFFER_STATUS_AC_BK 1 -+#define TDLS_PU_BUFFER_STATUS_AC_BE 2 -+#define TDLS_PU_BUFFER_STATUS_AC_VI 4 -+#define TDLS_PU_BUFFER_STATUS_AC_VO 8 -+ -+#ifdef BCMWAPI_WAI -+#define WAPI_IE_MIN_LEN 20 /* WAPI IE min length */ -+#define WAPI_VERSION 1 /* WAPI version */ -+#define WAPI_VERSION_LEN 2 /* WAPI version length */ -+#define WAPI_OUI "\x00\x14\x72" /* WAPI OUI */ -+#define WAPI_OUI_LEN DOT11_OUI_LEN /* WAPI OUI length */ -+#endif /* BCMWAPI_WAI */ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _802_11_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/802.11_bta.h b/drivers/net/wireless/ap6210/include/proto/802.11_bta.h -new file mode 100644 -index 0000000..3ee5a74 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/802.11_bta.h -@@ -0,0 +1,45 @@ -+/* -+ * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer) -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: 802.11_bta.h 294267 2011-11-04 23:41:52Z $ -+*/ -+ -+#ifndef _802_11_BTA_H_ -+#define _802_11_BTA_H_ -+ -+#define BT_SIG_SNAP_MPROT "\xAA\xAA\x03\x00\x19\x58" -+ -+/* BT-AMP 802.11 PAL Protocols */ -+#define BTA_PROT_L2CAP 1 -+#define BTA_PROT_ACTIVITY_REPORT 2 -+#define BTA_PROT_SECURITY 3 -+#define BTA_PROT_LINK_SUPERVISION_REQUEST 4 -+#define BTA_PROT_LINK_SUPERVISION_REPLY 5 -+ -+/* BT-AMP 802.11 PAL AMP_ASSOC Type IDs */ -+#define BTA_TYPE_ID_MAC_ADDRESS 1 -+#define BTA_TYPE_ID_PREFERRED_CHANNELS 2 -+#define BTA_TYPE_ID_CONNECTED_CHANNELS 3 -+#define BTA_TYPE_ID_CAPABILITIES 4 -+#define BTA_TYPE_ID_VERSION 5 -+#endif /* _802_11_bta_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/802.11e.h b/drivers/net/wireless/ap6210/include/proto/802.11e.h -new file mode 100644 -index 0000000..f391e68 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/802.11e.h -@@ -0,0 +1,131 @@ -+/* -+ * 802.11e protocol header file -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: 802.11e.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _802_11e_H_ -+#define _802_11e_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* WME Traffic Specification (TSPEC) element */ -+#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */ -+#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */ -+ -+#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */ -+#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */ -+#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */ -+#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */ -+ -+BWL_PRE_PACKED_STRUCT struct tsinfo { -+ uint8 octets[3]; -+} BWL_POST_PACKED_STRUCT; -+ -+typedef struct tsinfo tsinfo_t; -+ -+/* 802.11e TSPEC IE */ -+typedef BWL_PRE_PACKED_STRUCT struct tspec { -+ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ -+ uint8 type; /* WME_TYPE */ -+ uint8 subtype; /* WME_SUBTYPE_TSPEC */ -+ uint8 version; /* WME_VERSION */ -+ tsinfo_t tsinfo; /* TS Info bit field */ -+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ -+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ -+ uint32 min_srv_interval; /* Minimum Service Interval (us) */ -+ uint32 max_srv_interval; /* Maximum Service Interval (us) */ -+ uint32 inactivity_interval; /* Inactivity Interval (us) */ -+ uint32 suspension_interval; /* Suspension Interval (us) */ -+ uint32 srv_start_time; /* Service Start Time (us) */ -+ uint32 min_data_rate; /* Minimum Data Rate (bps) */ -+ uint32 mean_data_rate; /* Mean Data Rate (bps) */ -+ uint32 peak_data_rate; /* Peak Data Rate (bps) */ -+ uint32 max_burst_size; /* Maximum Burst Size (bytes) */ -+ uint32 delay_bound; /* Delay Bound (us) */ -+ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ -+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */ -+ uint16 medium_time; /* Medium Time (32 us/s periods) */ -+} BWL_POST_PACKED_STRUCT tspec_t; -+ -+#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */ -+ -+/* ts_info */ -+/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ -+#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */ -+#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */ -+#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */ -+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */ -+#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */ -+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */ -+#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */ -+#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */ -+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */ -+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */ -+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */ -+#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */ -+/* TS info. user priority mask */ -+#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT) -+ -+/* Macro to get/set bit(s) field in TSINFO */ -+#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT) -+#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \ -+ TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT) -+#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT) -+#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \ -+ TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT) -+ -+#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \ -+ ((id) << TS_INFO_TID_SHIFT)) -+#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \ -+ ((prio) << TS_INFO_USER_PRIO_SHIFT)) -+ -+/* 802.11e QBSS Load IE */ -+#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */ -+#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */ -+ -+#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */ -+ -+/* 802.11e ADDTS status code */ -+#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */ -+#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ -+#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ -+#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ -+ -+/* 802.11e DELTS status code */ -+#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ -+#define DOT11E_STATUS_END_TS 37 /* END TS */ -+#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */ -+#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */ -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _802_11e_CAC_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/802.1d.h b/drivers/net/wireless/ap6210/include/proto/802.1d.h -new file mode 100644 -index 0000000..f11cc6c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/802.1d.h -@@ -0,0 +1,50 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * Fundamental types and constants relating to 802.1D -+ * -+ * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _802_1_D_ -+#define _802_1_D_ -+ -+/* 802.1D priority defines */ -+#define PRIO_8021D_NONE 2 /* None = - */ -+#define PRIO_8021D_BK 1 /* BK - Background */ -+#define PRIO_8021D_BE 0 /* BE - Best-effort */ -+#define PRIO_8021D_EE 3 /* EE - Excellent-effort */ -+#define PRIO_8021D_CL 4 /* CL - Controlled Load */ -+#define PRIO_8021D_VI 5 /* Vi - Video */ -+#define PRIO_8021D_VO 6 /* Vo - Voice */ -+#define PRIO_8021D_NC 7 /* NC - Network Control */ -+#define MAXPRIO 7 /* 0-7 */ -+#define NUMPRIO (MAXPRIO + 1) -+ -+#define ALLPRIO -1 /* All prioirty */ -+ -+/* Converts prio to precedence since the numerical value of -+ * PRIO_8021D_BE and PRIO_8021D_NONE are swapped. -+ */ -+#define PRIO2PREC(prio) \ -+ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) -+ -+#endif /* _802_1_D__ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/bcmeth.h b/drivers/net/wireless/ap6210/include/proto/bcmeth.h -new file mode 100644 -index 0000000..91ae75c ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/bcmeth.h -@@ -0,0 +1,112 @@ -+/* -+ * Broadcom Ethernettype protocol definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bcmeth.h 294352 2011-11-06 19:23:00Z $ -+ */ -+ -+/* -+ * Broadcom Ethernet protocol defines -+ */ -+ -+#ifndef _BCMETH_H_ -+#define _BCMETH_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+/* ETHER_TYPE_BRCM is defined in ethernet.h */ -+ -+/* -+ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field -+ * in one of two formats: (only subtypes 32768-65535 are in use now) -+ * -+ * subtypes 0-32767: -+ * 8 bit subtype (0-127) -+ * 8 bit length in bytes (0-255) -+ * -+ * subtypes 32768-65535: -+ * 16 bit big-endian subtype -+ * 16 bit big-endian length in bytes (0-65535) -+ * -+ * length is the number of additional bytes beyond the 4 or 6 byte header -+ * -+ * Reserved values: -+ * 0 reserved -+ * 5-15 reserved for iLine protocol assignments -+ * 17-126 reserved, assignable -+ * 127 reserved -+ * 32768 reserved -+ * 32769-65534 reserved, assignable -+ * 65535 reserved -+ */ -+ -+/* -+ * While adding the subtypes and their specific processing code make sure -+ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition -+ */ -+ -+#define BCMILCP_SUBTYPE_RATE 1 -+#define BCMILCP_SUBTYPE_LINK 2 -+#define BCMILCP_SUBTYPE_CSA 3 -+#define BCMILCP_SUBTYPE_LARQ 4 -+#define BCMILCP_SUBTYPE_VENDOR 5 -+#define BCMILCP_SUBTYPE_FLH 17 -+ -+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -+#define BCMILCP_SUBTYPE_CERT 32770 -+#define BCMILCP_SUBTYPE_SES 32771 -+ -+ -+#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -+#define BCMILCP_BCM_SUBTYPE_EVENT 1 -+#define BCMILCP_BCM_SUBTYPE_SES 2 -+/* -+ * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded -+ * within BCMILCP_BCM_SUBTYPE_EVENT type messages -+ */ -+/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ -+#define BCMILCP_BCM_SUBTYPE_DPT 4 -+ -+#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -+#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 -+ -+/* These fields are stored in network order */ -+typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr -+{ -+ uint16 subtype; /* Vendor specific..32769 */ -+ uint16 length; -+ uint8 version; /* Version is 0 */ -+ uint8 oui[3]; /* Broadcom OUI */ -+ /* user specific Data */ -+ uint16 usr_subtype; -+} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _BCMETH_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/bcmevent.h b/drivers/net/wireless/ap6210/include/proto/bcmevent.h -new file mode 100644 -index 0000000..c439707 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/bcmevent.h -@@ -0,0 +1,368 @@ -+/* -+ * Broadcom Event protocol definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * Dependencies: proto/bcmeth.h -+ * -+ * $Id: bcmevent.h 374275 2012-12-12 11:44:18Z $ -+ * -+ */ -+ -+/* -+ * Broadcom Ethernet Events protocol defines -+ * -+ */ -+ -+#ifndef _BCMEVENT_H_ -+#define _BCMEVENT_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#define BCM_EVENT_MSG_VERSION 2 /* wl_event_msg_t struct version */ -+#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ -+ -+/* flags */ -+#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ -+#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ -+#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ -+#define WLC_EVENT_MSG_UNKBSS 0x08 /* unknown source bsscfg */ -+#define WLC_EVENT_MSG_UNKIF 0x10 /* unknown source OS i/f */ -+ -+/* these fields are stored in network order */ -+ -+/* version 1 */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint16 version; -+ uint16 flags; /* see flags below */ -+ uint32 event_type; /* Message (see below) */ -+ uint32 status; /* Status code (see below) */ -+ uint32 reason; /* Reason code (if applicable) */ -+ uint32 auth_type; /* WLC_E_AUTH */ -+ uint32 datalen; /* data buf */ -+ struct ether_addr addr; /* Station address (if applicable) */ -+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ -+} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t; -+ -+/* the current version */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint16 version; -+ uint16 flags; /* see flags below */ -+ uint32 event_type; /* Message (see below) */ -+ uint32 status; /* Status code (see below) */ -+ uint32 reason; /* Reason code (if applicable) */ -+ uint32 auth_type; /* WLC_E_AUTH */ -+ uint32 datalen; /* data buf */ -+ struct ether_addr addr; /* Station address (if applicable) */ -+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ -+ uint8 ifidx; /* destination OS i/f index */ -+ uint8 bsscfgidx; /* source bsscfg index */ -+} BWL_POST_PACKED_STRUCT wl_event_msg_t; -+ -+/* used by driver msgs */ -+typedef BWL_PRE_PACKED_STRUCT struct bcm_event { -+ struct ether_header eth; -+ bcmeth_hdr_t bcm_hdr; -+ wl_event_msg_t event; -+ /* data portion follows */ -+} BWL_POST_PACKED_STRUCT bcm_event_t; -+ -+#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) -+ -+/* Event messages */ -+#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ -+#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ -+#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ -+#define WLC_E_AUTH 3 /* 802.11 AUTH request */ -+#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ -+#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ -+#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ -+#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ -+#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ -+#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ -+#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ -+#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ -+#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ -+#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ -+#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ -+#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ -+#define WLC_E_LINK 16 /* generic link indication */ -+#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ -+#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ -+#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ -+#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ -+#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ -+#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ -+#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ -+#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ -+#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ -+#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ -+#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ -+#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ -+#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ -+#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ -+#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */ -+#define WLC_E_ROAM_PREP 32 /* before attempting to roam */ -+#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */ -+#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */ -+#define WLC_E_RESET_COMPLETE 35 -+#define WLC_E_JOIN_START 36 -+#define WLC_E_ROAM_START 37 -+#define WLC_E_ASSOC_START 38 -+#define WLC_E_IBSS_ASSOC 39 -+#define WLC_E_RADIO 40 -+#define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */ -+#define WLC_E_PROBREQ_MSG 44 /* probe request received */ -+#define WLC_E_SCAN_CONFIRM_IND 45 -+#define WLC_E_PSK_SUP 46 /* WPA Handshake fail */ -+#define WLC_E_COUNTRY_CODE_CHANGED 47 -+#define WLC_E_EXCEEDED_MEDIUM_TIME 48 /* WMMAC excedded medium time */ -+#define WLC_E_ICV_ERROR 49 /* WEP ICV error occurred */ -+#define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */ -+#define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */ -+#define WLC_E_TRACE 52 -+#ifdef WLBTAMP -+#define WLC_E_BTA_HCI_EVENT 53 /* BT-AMP HCI event */ -+#endif -+#define WLC_E_IF 54 /* I/F change (for dongle host notification) */ -+#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */ -+#define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */ -+#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */ -+#define WLC_E_EXTLOG_MSG 58 -+#define WLC_E_ACTION_FRAME 59 /* Action frame Rx */ -+#define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */ -+#define WLC_E_PRE_ASSOC_IND 61 /* assoc request received */ -+#define WLC_E_PRE_REASSOC_IND 62 /* re-assoc request received */ -+#define WLC_E_CHANNEL_ADOPTED 63 -+#define WLC_E_AP_STARTED 64 /* AP started */ -+#define WLC_E_DFS_AP_STOP 65 /* AP stopped due to DFS */ -+#define WLC_E_DFS_AP_RESUME 66 /* AP resumed due to DFS */ -+#define WLC_E_WAI_STA_EVENT 67 /* WAI stations event */ -+#define WLC_E_WAI_MSG 68 /* event encapsulating an WAI message */ -+#define WLC_E_ESCAN_RESULT 69 /* escan result event */ -+#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 /* action frame off channel complete */ -+#define WLC_E_PROBRESP_MSG 71 /* probe response received */ -+#define WLC_E_P2P_PROBREQ_MSG 72 /* P2P Probe request received */ -+#define WLC_E_DCS_REQUEST 73 -+ -+#define WLC_E_FIFO_CREDIT_MAP 74 /* credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */ -+ -+#define WLC_E_ACTION_FRAME_RX 75 /* Received action frame event WITH -+ * wl_event_rx_frame_data_t header -+ */ -+#define WLC_E_WAKE_EVENT 76 /* Wake Event timer fired, used for wake WLAN test mode */ -+#define WLC_E_RM_COMPLETE 77 /* Radio measurement complete */ -+#define WLC_E_HTSFSYNC 78 /* Synchronize TSF with the host */ -+#define WLC_E_OVERLAY_REQ 79 /* request an overlay IOCTL/iovar from the host */ -+#define WLC_E_CSA_COMPLETE_IND 80 /* 802.11 CHANNEL SWITCH ACTION completed */ -+#define WLC_E_EXCESS_PM_WAKE_EVENT 81 /* excess PM Wake Event to inform host */ -+#define WLC_E_PFN_SCAN_NONE 82 /* no PFN networks around */ -+#define WLC_E_PFN_SCAN_ALLGONE 83 /* last found PFN network gets lost */ -+#define WLC_E_GTK_PLUMBED 84 -+#define WLC_E_ASSOC_IND_NDIS 85 /* 802.11 ASSOC indication for NDIS only */ -+#define WLC_E_REASSOC_IND_NDIS 86 /* 802.11 REASSOC indication for NDIS only */ -+#define WLC_E_ASSOC_REQ_IE 87 -+#define WLC_E_ASSOC_RESP_IE 88 -+#define WLC_E_ASSOC_RECREATED 89 /* association recreated on resume */ -+#define WLC_E_ACTION_FRAME_RX_NDIS 90 /* rx action frame event for NDIS only */ -+#define WLC_E_AUTH_REQ 91 /* authentication request received */ -+#define WLC_E_TDLS_PEER_EVENT 92 /* discovered peer, connected or disconnected peer */ -+#define WLC_E_SPEEDY_RECREATE_FAIL 93 /* fast assoc recreation failed */ -+#define WLC_E_SERVICE_FOUND 102 /* desired service found */ -+#define WLC_E_GAS_FRAGMENT_RX 103 /* GAS fragment received */ -+#define WLC_E_GAS_COMPLETE 104 /* GAS sessions all complete */ -+#define WLC_E_P2PO_ADD_DEVICE 105 /* New device found by p2p offload */ -+#define WLC_E_P2PO_DEL_DEVICE 106 /* device has been removed by p2p offload */ -+#define WLC_E_LAST 107 /* highest val + 1 for range checking */ -+ -+ -+/* Table of event name strings for UIs and debugging dumps */ -+typedef struct { -+ uint event; -+ const char *name; -+} bcmevent_name_t; -+ -+extern const bcmevent_name_t bcmevent_names[]; -+extern const int bcmevent_names_size; -+ -+/* Event status codes */ -+#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ -+#define WLC_E_STATUS_FAIL 1 /* operation failed */ -+#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ -+#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ -+#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ -+#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ -+#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ -+#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ -+#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */ -+#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */ -+#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */ -+#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */ -+#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */ -+#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */ -+#define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */ -+#define WLC_E_STATUS_ERROR 16 /* request failed due to error */ -+ -+/* roam reason codes */ -+#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ -+#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ -+#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ -+#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ -+#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ -+#define WLC_E_REASON_MINTXRATE 9 /* roamed because at mintxrate for too long */ -+#define WLC_E_REASON_TXFAIL 10 /* We can hear AP, but AP can't hear us */ -+ -+/* Roam codes used primarily by CCX */ -+#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ -+#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ -+#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ -+#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ -+ -+ -+#define WLC_E_REASON_REQUESTED_ROAM 11 /* roamed due to BSS Mgmt Transition request by AP */ -+ -+/* prune reason codes */ -+#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */ -+#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ -+#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ -+#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ -+#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ -+#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ -+#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ -+#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ -+#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ -+#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ -+#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ -+#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ -+#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ -+#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ -+#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ -+ -+/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ -+#define WLC_E_SUP_OTHER 0 /* Other reason */ -+#define WLC_E_SUP_DECRYPT_KEY_DATA 1 /* Decryption of key data failed */ -+#define WLC_E_SUP_BAD_UCAST_WEP128 2 /* Illegal use of ucast WEP128 */ -+#define WLC_E_SUP_BAD_UCAST_WEP40 3 /* Illegal use of ucast WEP40 */ -+#define WLC_E_SUP_UNSUP_KEY_LEN 4 /* Unsupported key length */ -+#define WLC_E_SUP_PW_KEY_CIPHER 5 /* Unicast cipher mismatch in pairwise key */ -+#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 /* WPA IE contains > 1 RSN IE in key msg 3 */ -+#define WLC_E_SUP_MSG3_IE_MISMATCH 7 /* WPA IE mismatch in key message 3 */ -+#define WLC_E_SUP_NO_INSTALL_FLAG 8 /* INSTALL flag unset in 4-way msg */ -+#define WLC_E_SUP_MSG3_NO_GTK 9 /* encapsulated GTK missing from msg 3 */ -+#define WLC_E_SUP_GRP_KEY_CIPHER 10 /* Multicast cipher mismatch in group key */ -+#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 /* encapsulated GTK missing from group msg 1 */ -+#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 /* GTK decrypt failure */ -+#define WLC_E_SUP_SEND_FAIL 13 /* message send failure */ -+#define WLC_E_SUP_DEAUTH 14 /* received FC_DEAUTH */ -+#define WLC_E_SUP_WPA_PSK_TMO 15 /* WPA PSK 4-way handshake timeout */ -+ -+/* Event data for events that include frames received over the air */ -+/* WLC_E_PROBRESP_MSG -+ * WLC_E_P2P_PROBREQ_MSG -+ * WLC_E_ACTION_FRAME_RX -+ */ -+typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { -+ uint16 version; -+ uint16 channel; /* Matches chanspec_t format from bcmwifi_channels.h */ -+ int32 rssi; -+ uint32 mactime; -+ uint32 rate; -+} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t; -+ -+#define BCM_RX_FRAME_DATA_VERSION 1 -+ -+/* WLC_E_IF event data */ -+typedef struct wl_event_data_if { -+ uint8 ifidx; /* RTE virtual device index (for dongle) */ -+ uint8 opcode; /* see I/F opcode */ -+ uint8 reserved; -+ uint8 bssidx; /* bsscfg index */ -+ uint8 role; /* see I/F role */ -+} wl_event_data_if_t; -+ -+/* opcode in WLC_E_IF event */ -+#define WLC_E_IF_ADD 1 /* bsscfg add */ -+#define WLC_E_IF_DEL 2 /* bsscfg delete */ -+#define WLC_E_IF_CHANGE 3 /* bsscfg role change */ -+ -+/* I/F role code in WLC_E_IF event */ -+#define WLC_E_IF_ROLE_STA 0 /* Infra STA */ -+#define WLC_E_IF_ROLE_AP 1 /* Access Point */ -+#define WLC_E_IF_ROLE_WDS 2 /* WDS link */ -+#define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */ -+#define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */ -+#ifdef WLBTAMP -+#define WLC_E_IF_ROLE_BTA_CREATOR 5 /* BT-AMP Creator */ -+#define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 /* BT-AMP Acceptor */ -+#endif -+ -+/* Reason codes for LINK */ -+#define WLC_E_LINK_BCN_LOSS 1 /* Link down because of beacon loss */ -+#define WLC_E_LINK_DISASSOC 2 /* Link down because of disassoc */ -+#define WLC_E_LINK_ASSOC_REC 3 /* Link down because assoc recreate failed */ -+#define WLC_E_LINK_BSSCFG_DIS 4 /* Link down due to bsscfg down */ -+ -+/* reason codes for WLC_E_OVERLAY_REQ event */ -+#define WLC_E_OVL_DOWNLOAD 0 /* overlay download request */ -+#define WLC_E_OVL_UPDATE_IND 1 /* device indication of host overlay update */ -+ -+/* reason codes for WLC_E_TDLS_PEER_EVENT event */ -+#define WLC_E_TDLS_PEER_DISCOVERED 0 /* peer is ready to establish TDLS */ -+#define WLC_E_TDLS_PEER_CONNECTED 1 -+#define WLC_E_TDLS_PEER_DISCONNECTED 2 -+ -+/* GAS event data */ -+typedef BWL_PRE_PACKED_STRUCT struct wl_event_gas { -+ uint16 channel; /* channel of GAS protocol */ -+ uint8 dialog_token; /* GAS dialog token */ -+ uint8 fragment_id; /* fragment id */ -+ uint16 status_code; /* status code on GAS completion */ -+ uint16 data_len; /* length of data to follow */ -+ uint8 data[1]; /* variable length specified by data_len */ -+} BWL_POST_PACKED_STRUCT wl_event_gas_t; -+ -+/* service discovery TLV */ -+typedef BWL_PRE_PACKED_STRUCT struct wl_sd_tlv { -+ uint16 length; /* length of response_data */ -+ uint8 protocol; /* service protocol type */ -+ uint8 transaction_id; /* service transaction id */ -+ uint8 status_code; /* status code */ -+ uint8 data[1]; /* response data */ -+} BWL_POST_PACKED_STRUCT wl_sd_tlv_t; -+ -+/* service discovery event data */ -+typedef BWL_PRE_PACKED_STRUCT struct wl_event_sd { -+ uint16 channel; /* channel */ -+ uint8 count; /* number of tlvs */ -+ wl_sd_tlv_t tlv[1]; /* service discovery TLV */ -+} BWL_POST_PACKED_STRUCT wl_event_sd_t; -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _BCMEVENT_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/bcmip.h b/drivers/net/wireless/ap6210/include/proto/bcmip.h -new file mode 100644 -index 0000000..52cd71d ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/bcmip.h -@@ -0,0 +1,210 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * Fundamental constants relating to IP Protocol -+ * -+ * $Id: bcmip.h 290206 2011-10-17 19:13:51Z $ -+ */ -+ -+#ifndef _bcmip_h_ -+#define _bcmip_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* IPV4 and IPV6 common */ -+#define IP_VER_OFFSET 0x0 /* offset to version field */ -+#define IP_VER_MASK 0xf0 /* version mask */ -+#define IP_VER_SHIFT 4 /* version shift */ -+#define IP_VER_4 4 /* version number for IPV4 */ -+#define IP_VER_6 6 /* version number for IPV6 */ -+ -+#define IP_VER(ip_body) \ -+ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) -+ -+#define IP_PROT_ICMP 0x1 /* ICMP protocol */ -+#define IP_PROT_IGMP 0x2 /* IGMP protocol */ -+#define IP_PROT_TCP 0x6 /* TCP protocol */ -+#define IP_PROT_UDP 0x11 /* UDP protocol type */ -+#define IP_PROT_ICMP6 0x3a /* ICMPv6 protocol type */ -+ -+/* IPV4 field offsets */ -+#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ -+#define IPV4_TOS_OFFSET 1 /* type of service offset */ -+#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */ -+#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */ -+#define IPV4_PROT_OFFSET 9 /* protocol type offset */ -+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ -+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ -+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ -+#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */ -+ -+/* IPV4 field decodes */ -+#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ -+#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ -+ -+#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ -+#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) -+ -+#define IPV4_ADDR_LEN 4 /* IPV4 address length */ -+ -+#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ -+ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) -+ -+#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ -+ ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) -+ -+#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ -+#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ -+ -+#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) -+ -+#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ -+#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ -+ -+#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ -+#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ -+#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ -+ -+#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) -+ -+#define IPV4_FRAG_RESV 0x8000 /* Reserved */ -+#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */ -+#define IPV4_FRAG_MORE 0x2000 /* More fragments */ -+#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */ -+ -+#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ -+ -+/* IPV4 packet formats */ -+BWL_PRE_PACKED_STRUCT struct ipv4_addr { -+ uint8 addr[IPV4_ADDR_LEN]; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct ipv4_hdr { -+ uint8 version_ihl; /* Version and Internet Header Length */ -+ uint8 tos; /* Type Of Service */ -+ uint16 tot_len; /* Number of bytes in packet (max 65535) */ -+ uint16 id; -+ uint16 frag; /* 3 flag bits and fragment offset */ -+ uint8 ttl; /* Time To Live */ -+ uint8 prot; /* Protocol */ -+ uint16 hdr_chksum; /* IP header checksum */ -+ uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */ -+ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* IPV6 field offsets */ -+#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ -+#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ -+#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ -+#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ -+#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ -+ -+/* IPV6 field decodes */ -+#define IPV6_TRAFFIC_CLASS(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ -+ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) -+ -+#define IPV6_FLOW_LABEL(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ -+ (((uint8 *)(ipv6_body))[2] << 8) | \ -+ (((uint8 *)(ipv6_body))[3])) -+ -+#define IPV6_PAYLOAD_LEN(ipv6_body) \ -+ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ -+ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) -+ -+#define IPV6_NEXT_HDR(ipv6_body) \ -+ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) -+ -+#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) -+ -+#define IPV6_ADDR_LEN 16 /* IPV6 address length */ -+ -+/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ -+#define IP_TOS46(ip_body) \ -+ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ -+ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) -+ -+/* IPV6 extension headers (options) */ -+#define IPV6_EXTHDR_HOP 0 -+#define IPV6_EXTHDR_ROUTING 43 -+#define IPV6_EXTHDR_FRAGMENT 44 -+#define IPV6_EXTHDR_AUTH 51 -+#define IPV6_EXTHDR_NONE 59 -+#define IPV6_EXTHDR_DEST 60 -+ -+#define IPV6_EXTHDR(prot) (((prot) == IPV6_EXTHDR_HOP) || \ -+ ((prot) == IPV6_EXTHDR_ROUTING) || \ -+ ((prot) == IPV6_EXTHDR_FRAGMENT) || \ -+ ((prot) == IPV6_EXTHDR_AUTH) || \ -+ ((prot) == IPV6_EXTHDR_NONE) || \ -+ ((prot) == IPV6_EXTHDR_DEST)) -+ -+#define IPV6_MIN_HLEN 40 -+ -+#define IPV6_EXTHDR_LEN(eh) ((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3) -+ -+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr { -+ uint8 nexthdr; -+ uint8 hdrlen; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag { -+ uint8 nexthdr; -+ uint8 rsvd; -+ uint16 frag_off; -+ uint32 ident; -+} BWL_POST_PACKED_STRUCT; -+ -+static INLINE int32 -+ipv6_exthdr_len(uint8 *h, uint8 *proto) -+{ -+ uint16 len = 0, hlen; -+ struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h; -+ -+ while (IPV6_EXTHDR(eh->nexthdr)) { -+ if (eh->nexthdr == IPV6_EXTHDR_NONE) -+ return -1; -+ else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT) -+ hlen = 8; -+ else if (eh->nexthdr == IPV6_EXTHDR_AUTH) -+ hlen = (eh->hdrlen + 2) << 2; -+ else -+ hlen = IPV6_EXTHDR_LEN(eh); -+ -+ len += hlen; -+ eh = (struct ipv6_exthdr *)(h + len); -+ } -+ -+ *proto = eh->nexthdr; -+ return len; -+} -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _bcmip_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h b/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h -new file mode 100644 -index 0000000..8617985 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h -@@ -0,0 +1,441 @@ -+/* -+ * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface) -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: bt_amp_hci.h 294267 2011-11-04 23:41:52Z $ -+*/ -+ -+#ifndef _bt_amp_hci_h -+#define _bt_amp_hci_h -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* AMP HCI CMD packet format */ -+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_cmd { -+ uint16 opcode; -+ uint8 plen; -+ uint8 parms[1]; -+} BWL_POST_PACKED_STRUCT amp_hci_cmd_t; -+ -+#define HCI_CMD_PREAMBLE_SIZE OFFSETOF(amp_hci_cmd_t, parms) -+#define HCI_CMD_DATA_SIZE 255 -+ -+/* AMP HCI CMD opcode layout */ -+#define HCI_CMD_OPCODE(ogf, ocf) ((((ogf) & 0x3F) << 10) | ((ocf) & 0x03FF)) -+#define HCI_CMD_OGF(opcode) ((uint8)(((opcode) >> 10) & 0x3F)) -+#define HCI_CMD_OCF(opcode) ((opcode) & 0x03FF) -+ -+/* AMP HCI command opcodes */ -+#define HCI_Read_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0001) -+#define HCI_Reset_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0002) -+#define HCI_Read_Link_Quality HCI_CMD_OPCODE(0x05, 0x0003) -+#define HCI_Read_Local_AMP_Info HCI_CMD_OPCODE(0x05, 0x0009) -+#define HCI_Read_Local_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000A) -+#define HCI_Write_Remote_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000B) -+#define HCI_Create_Physical_Link HCI_CMD_OPCODE(0x01, 0x0035) -+#define HCI_Accept_Physical_Link_Request HCI_CMD_OPCODE(0x01, 0x0036) -+#define HCI_Disconnect_Physical_Link HCI_CMD_OPCODE(0x01, 0x0037) -+#define HCI_Create_Logical_Link HCI_CMD_OPCODE(0x01, 0x0038) -+#define HCI_Accept_Logical_Link HCI_CMD_OPCODE(0x01, 0x0039) -+#define HCI_Disconnect_Logical_Link HCI_CMD_OPCODE(0x01, 0x003A) -+#define HCI_Logical_Link_Cancel HCI_CMD_OPCODE(0x01, 0x003B) -+#define HCI_Flow_Spec_Modify HCI_CMD_OPCODE(0x01, 0x003C) -+#define HCI_Write_Flow_Control_Mode HCI_CMD_OPCODE(0x01, 0x0067) -+#define HCI_Read_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x0069) -+#define HCI_Write_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x006A) -+#define HCI_Short_Range_Mode HCI_CMD_OPCODE(0x01, 0x006B) -+#define HCI_Reset HCI_CMD_OPCODE(0x03, 0x0003) -+#define HCI_Read_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0015) -+#define HCI_Write_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0016) -+#define HCI_Read_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0036) -+#define HCI_Write_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0037) -+#define HCI_Enhanced_Flush HCI_CMD_OPCODE(0x03, 0x005F) -+#define HCI_Read_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0061) -+#define HCI_Write_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0062) -+#define HCI_Set_Event_Mask_Page_2 HCI_CMD_OPCODE(0x03, 0x0063) -+#define HCI_Read_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0064) -+#define HCI_Write_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0065) -+#define HCI_Read_Local_Version_Info HCI_CMD_OPCODE(0x04, 0x0001) -+#define HCI_Read_Local_Supported_Commands HCI_CMD_OPCODE(0x04, 0x0002) -+#define HCI_Read_Buffer_Size HCI_CMD_OPCODE(0x04, 0x0005) -+#define HCI_Read_Data_Block_Size HCI_CMD_OPCODE(0x04, 0x000A) -+ -+/* AMP HCI command parameters */ -+typedef BWL_PRE_PACKED_STRUCT struct read_local_cmd_parms { -+ uint8 plh; -+ uint8 offset[2]; /* length so far */ -+ uint8 max_remote[2]; -+} BWL_POST_PACKED_STRUCT read_local_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct write_remote_cmd_parms { -+ uint8 plh; -+ uint8 offset[2]; -+ uint8 len[2]; -+ uint8 frag[1]; -+} BWL_POST_PACKED_STRUCT write_remote_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct phy_link_cmd_parms { -+ uint8 plh; -+ uint8 key_length; -+ uint8 key_type; -+ uint8 key[1]; -+} BWL_POST_PACKED_STRUCT phy_link_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_cmd_parms { -+ uint8 plh; -+ uint8 reason; -+} BWL_POST_PACKED_STRUCT dis_phy_link_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct log_link_cmd_parms { -+ uint8 plh; -+ uint8 txflow[16]; -+ uint8 rxflow[16]; -+} BWL_POST_PACKED_STRUCT log_link_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct ext_flow_spec { -+ uint8 id; -+ uint8 service_type; -+ uint8 max_sdu[2]; -+ uint8 sdu_ia_time[4]; -+ uint8 access_latency[4]; -+ uint8 flush_timeout[4]; -+} BWL_POST_PACKED_STRUCT ext_flow_spec_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_cmd_parms { -+ uint8 plh; -+ uint8 tx_fs_ID; -+} BWL_POST_PACKED_STRUCT log_link_cancel_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_cmd_parms { -+ uint8 llh[2]; -+ uint8 txflow[16]; -+ uint8 rxflow[16]; -+} BWL_POST_PACKED_STRUCT flow_spec_mod_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct plh_pad { -+ uint8 plh; -+ uint8 pad; -+} BWL_POST_PACKED_STRUCT plh_pad_t; -+ -+typedef BWL_PRE_PACKED_STRUCT union hci_handle { -+ uint16 bredr; -+ plh_pad_t amp; -+} BWL_POST_PACKED_STRUCT hci_handle_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct ls_to_cmd_parms { -+ hci_handle_t handle; -+ uint8 timeout[2]; -+} BWL_POST_PACKED_STRUCT ls_to_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct befto_cmd_parms { -+ uint8 llh[2]; -+ uint8 befto[4]; -+} BWL_POST_PACKED_STRUCT befto_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct srm_cmd_parms { -+ uint8 plh; -+ uint8 srm; -+} BWL_POST_PACKED_STRUCT srm_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct ld_cmd_parms { -+ uint8 ld_aware; -+ uint8 ld[2]; -+ uint8 ld_opts; -+ uint8 l_opts; -+} BWL_POST_PACKED_STRUCT ld_cmd_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct eflush_cmd_parms { -+ uint8 llh[2]; -+ uint8 packet_type; -+} BWL_POST_PACKED_STRUCT eflush_cmd_parms_t; -+ -+/* Generic AMP extended flow spec service types */ -+#define EFS_SVCTYPE_NO_TRAFFIC 0 -+#define EFS_SVCTYPE_BEST_EFFORT 1 -+#define EFS_SVCTYPE_GUARANTEED 2 -+ -+/* AMP HCI event packet format */ -+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_event { -+ uint8 ecode; -+ uint8 plen; -+ uint8 parms[1]; -+} BWL_POST_PACKED_STRUCT amp_hci_event_t; -+ -+#define HCI_EVT_PREAMBLE_SIZE OFFSETOF(amp_hci_event_t, parms) -+ -+/* AMP HCI event codes */ -+#define HCI_Command_Complete 0x0E -+#define HCI_Command_Status 0x0F -+#define HCI_Flush_Occurred 0x11 -+#define HCI_Enhanced_Flush_Complete 0x39 -+#define HCI_Physical_Link_Complete 0x40 -+#define HCI_Channel_Select 0x41 -+#define HCI_Disconnect_Physical_Link_Complete 0x42 -+#define HCI_Logical_Link_Complete 0x45 -+#define HCI_Disconnect_Logical_Link_Complete 0x46 -+#define HCI_Flow_Spec_Modify_Complete 0x47 -+#define HCI_Number_of_Completed_Data_Blocks 0x48 -+#define HCI_Short_Range_Mode_Change_Complete 0x4C -+#define HCI_Status_Change_Event 0x4D -+#define HCI_Vendor_Specific 0xFF -+ -+/* AMP HCI event mask bit positions */ -+#define HCI_Physical_Link_Complete_Event_Mask 0x0001 -+#define HCI_Channel_Select_Event_Mask 0x0002 -+#define HCI_Disconnect_Physical_Link_Complete_Event_Mask 0x0004 -+#define HCI_Logical_Link_Complete_Event_Mask 0x0020 -+#define HCI_Disconnect_Logical_Link_Complete_Event_Mask 0x0040 -+#define HCI_Flow_Spec_Modify_Complete_Event_Mask 0x0080 -+#define HCI_Number_of_Completed_Data_Blocks_Event_Mask 0x0100 -+#define HCI_Short_Range_Mode_Change_Complete_Event_Mask 0x1000 -+#define HCI_Status_Change_Event_Mask 0x2000 -+#define HCI_All_Event_Mask 0x31e7 -+/* AMP HCI event parameters */ -+typedef BWL_PRE_PACKED_STRUCT struct cmd_status_parms { -+ uint8 status; -+ uint8 cmdpkts; -+ uint16 opcode; -+} BWL_POST_PACKED_STRUCT cmd_status_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct cmd_complete_parms { -+ uint8 cmdpkts; -+ uint16 opcode; -+ uint8 parms[1]; -+} BWL_POST_PACKED_STRUCT cmd_complete_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct flush_occurred_evt_parms { -+ uint16 handle; -+} BWL_POST_PACKED_STRUCT flush_occurred_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct write_remote_evt_parms { -+ uint8 status; -+ uint8 plh; -+} BWL_POST_PACKED_STRUCT write_remote_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_local_evt_parms { -+ uint8 status; -+ uint8 plh; -+ uint16 len; -+ uint8 frag[1]; -+} BWL_POST_PACKED_STRUCT read_local_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_local_info_evt_parms { -+ uint8 status; -+ uint8 AMP_status; -+ uint32 bandwidth; -+ uint32 gbandwidth; -+ uint32 latency; -+ uint32 PDU_size; -+ uint8 ctrl_type; -+ uint16 PAL_cap; -+ uint16 AMP_ASSOC_len; -+ uint32 max_flush_timeout; -+ uint32 be_flush_timeout; -+} BWL_POST_PACKED_STRUCT read_local_info_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct log_link_evt_parms { -+ uint8 status; -+ uint16 llh; -+ uint8 plh; -+ uint8 tx_fs_ID; -+} BWL_POST_PACKED_STRUCT log_link_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct disc_log_link_evt_parms { -+ uint8 status; -+ uint16 llh; -+ uint8 reason; -+} BWL_POST_PACKED_STRUCT disc_log_link_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_evt_parms { -+ uint8 status; -+ uint8 plh; -+ uint8 tx_fs_ID; -+} BWL_POST_PACKED_STRUCT log_link_cancel_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_evt_parms { -+ uint8 status; -+ uint16 llh; -+} BWL_POST_PACKED_STRUCT flow_spec_mod_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct phy_link_evt_parms { -+ uint8 status; -+ uint8 plh; -+} BWL_POST_PACKED_STRUCT phy_link_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_evt_parms { -+ uint8 status; -+ uint8 plh; -+ uint8 reason; -+} BWL_POST_PACKED_STRUCT dis_phy_link_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_ls_to_evt_parms { -+ uint8 status; -+ hci_handle_t handle; -+ uint16 timeout; -+} BWL_POST_PACKED_STRUCT read_ls_to_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_lla_ca_to_evt_parms { -+ uint8 status; -+ uint16 timeout; -+} BWL_POST_PACKED_STRUCT read_lla_ca_to_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_data_block_size_evt_parms { -+ uint8 status; -+ uint16 ACL_pkt_len; -+ uint16 data_block_len; -+ uint16 data_block_num; -+} BWL_POST_PACKED_STRUCT read_data_block_size_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct data_blocks { -+ uint16 handle; -+ uint16 pkts; -+ uint16 blocks; -+} BWL_POST_PACKED_STRUCT data_blocks_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct num_completed_data_blocks_evt_parms { -+ uint16 num_blocks; -+ uint8 num_handles; -+ data_blocks_t completed[1]; -+} BWL_POST_PACKED_STRUCT num_completed_data_blocks_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct befto_evt_parms { -+ uint8 status; -+ uint32 befto; -+} BWL_POST_PACKED_STRUCT befto_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct srm_evt_parms { -+ uint8 status; -+ uint8 plh; -+ uint8 srm; -+} BWL_POST_PACKED_STRUCT srm_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct contact_counter_evt_parms { -+ uint8 status; -+ uint8 llh[2]; -+ uint16 counter; -+} BWL_POST_PACKED_STRUCT contact_counter_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct contact_counter_reset_evt_parms { -+ uint8 status; -+ uint8 llh[2]; -+} BWL_POST_PACKED_STRUCT contact_counter_reset_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct read_linkq_evt_parms { -+ uint8 status; -+ hci_handle_t handle; -+ uint8 link_quality; -+} BWL_POST_PACKED_STRUCT read_linkq_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct ld_evt_parms { -+ uint8 status; -+ uint8 ld_aware; -+ uint8 ld[2]; -+ uint8 ld_opts; -+ uint8 l_opts; -+} BWL_POST_PACKED_STRUCT ld_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct eflush_complete_evt_parms { -+ uint16 handle; -+} BWL_POST_PACKED_STRUCT eflush_complete_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct vendor_specific_evt_parms { -+ uint8 len; -+ uint8 parms[1]; -+} BWL_POST_PACKED_STRUCT vendor_specific_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct local_version_info_evt_parms { -+ uint8 status; -+ uint8 hci_version; -+ uint16 hci_revision; -+ uint8 pal_version; -+ uint16 mfg_name; -+ uint16 pal_subversion; -+} BWL_POST_PACKED_STRUCT local_version_info_evt_parms_t; -+ -+#define MAX_SUPPORTED_CMD_BYTE 64 -+typedef BWL_PRE_PACKED_STRUCT struct local_supported_cmd_evt_parms { -+ uint8 status; -+ uint8 cmd[MAX_SUPPORTED_CMD_BYTE]; -+} BWL_POST_PACKED_STRUCT local_supported_cmd_evt_parms_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct status_change_evt_parms { -+ uint8 status; -+ uint8 amp_status; -+} BWL_POST_PACKED_STRUCT status_change_evt_parms_t; -+ -+/* AMP HCI error codes */ -+#define HCI_SUCCESS 0x00 -+#define HCI_ERR_ILLEGAL_COMMAND 0x01 -+#define HCI_ERR_NO_CONNECTION 0x02 -+#define HCI_ERR_MEMORY_FULL 0x07 -+#define HCI_ERR_CONNECTION_TIMEOUT 0x08 -+#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09 -+#define HCI_ERR_CONNECTION_EXISTS 0x0B -+#define HCI_ERR_CONNECTION_DISALLOWED 0x0C -+#define HCI_ERR_CONNECTION_ACCEPT_TIMEOUT 0x10 -+#define HCI_ERR_UNSUPPORTED_VALUE 0x11 -+#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12 -+#define HCI_ERR_CONN_TERM_BY_LOCAL_HOST 0x16 -+#define HCI_ERR_UNSPECIFIED 0x1F -+#define HCI_ERR_UNIT_KEY_USED 0x26 -+#define HCI_ERR_QOS_REJECTED 0x2D -+#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 -+#define HCI_ERR_NO_SUITABLE_CHANNEL 0x39 -+#define HCI_ERR_CHANNEL_MOVE 0xFF -+ -+/* AMP HCI ACL Data packet format */ -+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_ACL_data { -+ uint16 handle; /* 12-bit connection handle + 2-bit PB and 2-bit BC flags */ -+ uint16 dlen; /* data total length */ -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT amp_hci_ACL_data_t; -+ -+#define HCI_ACL_DATA_PREAMBLE_SIZE OFFSETOF(amp_hci_ACL_data_t, data) -+ -+#define HCI_ACL_DATA_BC_FLAGS (0x0 << 14) -+#define HCI_ACL_DATA_PB_FLAGS (0x3 << 12) -+ -+#define HCI_ACL_DATA_HANDLE(handle) ((handle) & 0x0fff) -+#define HCI_ACL_DATA_FLAGS(handle) ((handle) >> 12) -+ -+/* AMP Activity Report packet formats */ -+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report { -+ uint8 ScheduleKnown; -+ uint8 NumReports; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT amp_hci_activity_report_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report_triple { -+ uint32 StartTime; -+ uint32 Duration; -+ uint32 Periodicity; -+} BWL_POST_PACKED_STRUCT amp_hci_activity_report_triple_t; -+ -+#define HCI_AR_SCHEDULE_KNOWN 0x01 -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _bt_amp_hci_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/eapol.h b/drivers/net/wireless/ap6210/include/proto/eapol.h -new file mode 100644 -index 0000000..8936d16 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/eapol.h -@@ -0,0 +1,193 @@ -+/* -+ * 802.1x EAPOL definitions -+ * -+ * See -+ * IEEE Std 802.1X-2001 -+ * IEEE 802.1X RADIUS Usage Guidelines -+ * -+ * Copyright (C) 2002 Broadcom Corporation -+ * -+ * $Id: eapol.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _eapol_h_ -+#define _eapol_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#include -+ -+/* EAPOL for 802.3/Ethernet */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ struct ether_header eth; /* 802.3/Ethernet header */ -+ unsigned char version; /* EAPOL protocol version */ -+ unsigned char type; /* EAPOL type */ -+ unsigned short length; /* Length of body */ -+ unsigned char body[1]; /* Body (optional) */ -+} BWL_POST_PACKED_STRUCT eapol_header_t; -+ -+#define EAPOL_HEADER_LEN 18 -+ -+typedef struct { -+ unsigned char version; /* EAPOL protocol version */ -+ unsigned char type; /* EAPOL type */ -+ unsigned short length; /* Length of body */ -+} eapol_hdr_t; -+ -+#define EAPOL_HDR_LEN 4 -+ -+/* EAPOL version */ -+#define WPA2_EAPOL_VERSION 2 -+#define WPA_EAPOL_VERSION 1 -+#define LEAP_EAPOL_VERSION 1 -+#define SES_EAPOL_VERSION 1 -+ -+/* EAPOL types */ -+#define EAP_PACKET 0 -+#define EAPOL_START 1 -+#define EAPOL_LOGOFF 2 -+#define EAPOL_KEY 3 -+#define EAPOL_ASF 4 -+ -+/* EAPOL-Key types */ -+#define EAPOL_RC4_KEY 1 -+#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */ -+#define EAPOL_WPA_KEY 254 /* WPA */ -+ -+/* RC4 EAPOL-Key header field sizes */ -+#define EAPOL_KEY_REPLAY_LEN 8 -+#define EAPOL_KEY_IV_LEN 16 -+#define EAPOL_KEY_SIG_LEN 16 -+ -+/* RC4 EAPOL-Key */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ unsigned char type; /* Key Descriptor Type */ -+ unsigned short length; /* Key Length (unaligned) */ -+ unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */ -+ unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */ -+ unsigned char index; /* Key Flags & Index */ -+ unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */ -+ unsigned char key[1]; /* Key (optional) */ -+} BWL_POST_PACKED_STRUCT eapol_key_header_t; -+ -+#define EAPOL_KEY_HEADER_LEN 44 -+ -+/* RC4 EAPOL-Key flags */ -+#define EAPOL_KEY_FLAGS_MASK 0x80 -+#define EAPOL_KEY_BROADCAST 0 -+#define EAPOL_KEY_UNICAST 0x80 -+ -+/* RC4 EAPOL-Key index */ -+#define EAPOL_KEY_INDEX_MASK 0x7f -+ -+/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */ -+#define EAPOL_WPA_KEY_REPLAY_LEN 8 -+#define EAPOL_WPA_KEY_NONCE_LEN 32 -+#define EAPOL_WPA_KEY_IV_LEN 16 -+#define EAPOL_WPA_KEY_RSC_LEN 8 -+#define EAPOL_WPA_KEY_ID_LEN 8 -+#define EAPOL_WPA_KEY_MIC_LEN 16 -+#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN) -+#define EAPOL_WPA_MAX_KEY_SIZE 32 -+ -+/* WPA EAPOL-Key */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ unsigned char type; /* Key Descriptor Type */ -+ unsigned short key_info; /* Key Information (unaligned) */ -+ unsigned short key_len; /* Key Length (unaligned) */ -+ unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */ -+ unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */ -+ unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */ -+ unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */ -+ unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */ -+ unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */ -+ unsigned short data_len; /* Key Data Length */ -+ unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */ -+} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t; -+ -+#define EAPOL_WPA_KEY_LEN 95 -+ -+/* WPA/802.11i/WPA2 KEY KEY_INFO bits */ -+#define WPA_KEY_DESC_V1 0x01 -+#define WPA_KEY_DESC_V2 0x02 -+#define WPA_KEY_DESC_V3 0x03 -+#define WPA_KEY_PAIRWISE 0x08 -+#define WPA_KEY_INSTALL 0x40 -+#define WPA_KEY_ACK 0x80 -+#define WPA_KEY_MIC 0x100 -+#define WPA_KEY_SECURE 0x200 -+#define WPA_KEY_ERROR 0x400 -+#define WPA_KEY_REQ 0x800 -+ -+#define WPA_KEY_DESC_V2_OR_V3 WPA_KEY_DESC_V2 -+ -+/* WPA-only KEY KEY_INFO bits */ -+#define WPA_KEY_INDEX_0 0x00 -+#define WPA_KEY_INDEX_1 0x10 -+#define WPA_KEY_INDEX_2 0x20 -+#define WPA_KEY_INDEX_3 0x30 -+#define WPA_KEY_INDEX_MASK 0x30 -+#define WPA_KEY_INDEX_SHIFT 0x04 -+ -+/* 802.11i/WPA2-only KEY KEY_INFO bits */ -+#define WPA_KEY_ENCRYPTED_DATA 0x1000 -+ -+/* Key Data encapsulation */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 type; -+ uint8 length; -+ uint8 oui[3]; -+ uint8 subtype; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t; -+ -+#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6 -+ -+#define WPA2_KEY_DATA_SUBTYPE_GTK 1 -+#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2 -+#define WPA2_KEY_DATA_SUBTYPE_MAC 3 -+#define WPA2_KEY_DATA_SUBTYPE_PMKID 4 -+#define WPA2_KEY_DATA_SUBTYPE_IGTK 9 -+ -+/* GTK encapsulation */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 flags; -+ uint8 reserved; -+ uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE]; -+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t; -+ -+#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2 -+ -+#define WPA2_GTK_INDEX_MASK 0x03 -+#define WPA2_GTK_INDEX_SHIFT 0x00 -+ -+#define WPA2_GTK_TRANSMIT 0x04 -+ -+/* IGTK encapsulation */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint16 key_id; -+ uint8 ipn[6]; -+ uint8 key[EAPOL_WPA_MAX_KEY_SIZE]; -+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_igtk_encap_t; -+ -+#define EAPOL_WPA2_KEY_IGTK_ENCAP_HDR_LEN 8 -+ -+/* STAKey encapsulation */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 reserved[2]; -+ uint8 mac[ETHER_ADDR_LEN]; -+ uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE]; -+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t; -+ -+#define WPA2_KEY_DATA_PAD 0xdd -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _eapol_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/ethernet.h b/drivers/net/wireless/ap6210/include/proto/ethernet.h -new file mode 100644 -index 0000000..a6ce6e1 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/ethernet.h -@@ -0,0 +1,190 @@ -+/* -+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: ethernet.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ -+#define _NET_ETHERNET_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include "typedefs.h" -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* -+ * The number of bytes in an ethernet (MAC) address. -+ */ -+#define ETHER_ADDR_LEN 6 -+ -+/* -+ * The number of bytes in the type field. -+ */ -+#define ETHER_TYPE_LEN 2 -+ -+/* -+ * The number of bytes in the trailing CRC field. -+ */ -+#define ETHER_CRC_LEN 4 -+ -+/* -+ * The length of the combined header. -+ */ -+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) -+ -+/* -+ * The minimum packet length. -+ */ -+#define ETHER_MIN_LEN 64 -+ -+/* -+ * The minimum packet user data length. -+ */ -+#define ETHER_MIN_DATA 46 -+ -+/* -+ * The maximum packet length. -+ */ -+#define ETHER_MAX_LEN 1518 -+ -+/* -+ * The maximum packet user data length. -+ */ -+#define ETHER_MAX_DATA 1500 -+ -+/* ether types */ -+#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ -+#define ETHER_TYPE_IP 0x0800 /* IP */ -+#define ETHER_TYPE_ARP 0x0806 /* ARP */ -+#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ -+#define ETHER_TYPE_IPV6 0x86dd /* IPv6 */ -+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ -+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ -+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ -+#define ETHER_TYPE_WAI 0x88b4 /* WAI */ -+#define ETHER_TYPE_89_0D 0x890d /* 89-0d frame for TDLS */ -+ -+#define ETHER_TYPE_IPV6 0x86dd /* IPV6 */ -+ -+/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ -+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ -+ -+/* ether header */ -+#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */ -+#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */ -+#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */ -+ -+/* -+ * A macro to validate a length with -+ */ -+#define ETHER_IS_VALID_LEN(foo) \ -+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) -+ -+#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ -+ ((uint8 *)ea)[0] = 0x01; \ -+ ((uint8 *)ea)[1] = 0x00; \ -+ ((uint8 *)ea)[2] = 0x5e; \ -+ ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ -+ ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ -+ ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ -+} -+ -+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ -+/* -+ * Structure of a 10Mb/s Ethernet header. -+ */ -+BWL_PRE_PACKED_STRUCT struct ether_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 ether_type; -+} BWL_POST_PACKED_STRUCT; -+ -+/* -+ * Structure of a 48-bit Ethernet address. -+ */ -+BWL_PRE_PACKED_STRUCT struct ether_addr { -+ uint8 octet[ETHER_ADDR_LEN]; -+} BWL_POST_PACKED_STRUCT; -+#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ -+ -+/* -+ * Takes a pointer, set, test, clear, toggle locally admininistered -+ * address bit in the 48-bit Ethernet address. -+ */ -+#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) -+#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -+#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xfd)) -+#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) -+ -+/* Takes a pointer, marks unicast address bit in the MAC address */ -+#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) -+ -+/* -+ * Takes a pointer, returns true if a 48-bit multicast address -+ * (including broadcast, since it is all ones) -+ */ -+#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) -+ -+ -+/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ -+#define ether_cmp(a, b) (!(((short*)(a))[0] == ((short*)(b))[0]) | \ -+ !(((short*)(a))[1] == ((short*)(b))[1]) | \ -+ !(((short*)(a))[2] == ((short*)(b))[2])) -+ -+/* copy an ethernet address - assumes the pointers can be referenced as shorts */ -+#define ether_copy(s, d) { \ -+ ((short*)(d))[0] = ((const short*)(s))[0]; \ -+ ((short*)(d))[1] = ((const short*)(s))[1]; \ -+ ((short*)(d))[2] = ((const short*)(s))[2]; } -+ -+ -+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -+static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; -+ -+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ -+ ((uint8 *)(ea))[1] & \ -+ ((uint8 *)(ea))[2] & \ -+ ((uint8 *)(ea))[3] & \ -+ ((uint8 *)(ea))[4] & \ -+ ((uint8 *)(ea))[5]) == 0xff) -+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ -+ ((uint8 *)(ea))[1] | \ -+ ((uint8 *)(ea))[2] | \ -+ ((uint8 *)(ea))[3] | \ -+ ((uint8 *)(ea))[4] | \ -+ ((uint8 *)(ea))[5]) == 0) -+ -+#define ETHER_MOVE_HDR(d, s) \ -+do { \ -+ struct ether_header t; \ -+ t = *(struct ether_header *)(s); \ -+ *(struct ether_header *)(d) = t; \ -+} while (0) -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _NET_ETHERNET_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/p2p.h b/drivers/net/wireless/ap6210/include/proto/p2p.h -new file mode 100644 -index 0000000..6716e2a ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/p2p.h -@@ -0,0 +1,579 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * Fundamental types and constants relating to WFA P2P (aka WiFi Direct) -+ * -+ * $Id: p2p.h 356417 2012-09-12 16:41:24Z $ -+ */ -+ -+#ifndef _P2P_H_ -+#define _P2P_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+#include -+#include -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* WiFi P2P OUI values */ -+#define P2P_OUI WFA_OUI /* WiFi P2P OUI */ -+#define P2P_VER WFA_OUI_TYPE_P2P /* P2P version: 9=WiFi P2P v1.0 */ -+ -+#define P2P_IE_ID 0xdd /* P2P IE element ID */ -+ -+/* WiFi P2P IE */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_ie { -+ uint8 id; /* IE ID: 0xDD */ -+ uint8 len; /* IE length */ -+ uint8 OUI[3]; /* WiFi P2P specific OUI: P2P_OUI */ -+ uint8 oui_type; /* Identifies P2P version: P2P_VER */ -+ uint8 subelts[1]; /* variable length subelements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_ie wifi_p2p_ie_t; -+ -+#define P2P_IE_FIXED_LEN 6 -+ -+#define P2P_ATTR_ID_OFF 0 -+#define P2P_ATTR_LEN_OFF 1 -+#define P2P_ATTR_DATA_OFF 3 -+ -+#define P2P_ATTR_ID_LEN 1 /* ID filed length */ -+#define P2P_ATTR_LEN_LEN 2 /* length field length */ -+#define P2P_ATTR_HDR_LEN 3 /* ID + 2-byte length field spec 1.02 */ -+ -+/* P2P IE Subelement IDs from WiFi P2P Technical Spec 1.00 */ -+#define P2P_SEID_STATUS 0 /* Status */ -+#define P2P_SEID_MINOR_RC 1 /* Minor Reason Code */ -+#define P2P_SEID_P2P_INFO 2 /* P2P Capability (capabilities info) */ -+#define P2P_SEID_DEV_ID 3 /* P2P Device ID */ -+#define P2P_SEID_INTENT 4 /* Group Owner Intent */ -+#define P2P_SEID_CFG_TIMEOUT 5 /* Configuration Timeout */ -+#define P2P_SEID_CHANNEL 6 /* Channel */ -+#define P2P_SEID_GRP_BSSID 7 /* P2P Group BSSID */ -+#define P2P_SEID_XT_TIMING 8 /* Extended Listen Timing */ -+#define P2P_SEID_INTINTADDR 9 /* Intended P2P Interface Address */ -+#define P2P_SEID_P2P_MGBTY 10 /* P2P Manageability */ -+#define P2P_SEID_CHAN_LIST 11 /* Channel List */ -+#define P2P_SEID_ABSENCE 12 /* Notice of Absence */ -+#define P2P_SEID_DEV_INFO 13 /* Device Info */ -+#define P2P_SEID_GROUP_INFO 14 /* Group Info */ -+#define P2P_SEID_GROUP_ID 15 /* Group ID */ -+#define P2P_SEID_P2P_IF 16 /* P2P Interface */ -+#define P2P_SEID_OP_CHANNEL 17 /* Operating Channel */ -+#define P2P_SEID_INVITE_FLAGS 18 /* Invitation Flags */ -+#define P2P_SEID_VNDR 221 /* Vendor-specific subelement */ -+ -+#define P2P_SE_VS_ID_SERVICES 0x1b /* BRCM proprietary subel: L2 Services */ -+ -+ -+/* WiFi P2P IE subelement: P2P Capability (capabilities info) */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_info_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_P2P_INFO */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 dev; /* Device Capability Bitmap */ -+ uint8 group; /* Group Capability Bitmap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_info_se_s wifi_p2p_info_se_t; -+ -+/* P2P Capability subelement's Device Capability Bitmap bit values */ -+#define P2P_CAPSE_DEV_SERVICE_DIS 0x1 /* Service Discovery */ -+#define P2P_CAPSE_DEV_CLIENT_DIS 0x2 /* Client Discoverability */ -+#define P2P_CAPSE_DEV_CONCURRENT 0x4 /* Concurrent Operation */ -+#define P2P_CAPSE_DEV_INFRA_MAN 0x8 /* P2P Infrastructure Managed */ -+#define P2P_CAPSE_DEV_LIMIT 0x10 /* P2P Device Limit */ -+#define P2P_CAPSE_INVITE_PROC 0x20 /* P2P Invitation Procedure */ -+ -+/* P2P Capability subelement's Group Capability Bitmap bit values */ -+#define P2P_CAPSE_GRP_OWNER 0x1 /* P2P Group Owner */ -+#define P2P_CAPSE_PERSIST_GRP 0x2 /* Persistent P2P Group */ -+#define P2P_CAPSE_GRP_LIMIT 0x4 /* P2P Group Limit */ -+#define P2P_CAPSE_GRP_INTRA_BSS 0x8 /* Intra-BSS Distribution */ -+#define P2P_CAPSE_GRP_X_CONNECT 0x10 /* Cross Connection */ -+#define P2P_CAPSE_GRP_PERSISTENT 0x20 /* Persistent Reconnect */ -+#define P2P_CAPSE_GRP_FORMATION 0x40 /* Group Formation */ -+ -+ -+/* WiFi P2P IE subelement: Group Owner Intent */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intent_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_INTENT */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 intent; /* Intent Value 0...15 (0=legacy 15=master only) */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_intent_se_s wifi_p2p_intent_se_t; -+ -+/* WiFi P2P IE subelement: Configuration Timeout */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_cfg_tmo_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_CFG_TIMEOUT */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 go_tmo; /* GO config timeout in units of 10 ms */ -+ uint8 client_tmo; /* Client config timeout in units of 10 ms */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t; -+ -+/* WiFi P2P IE subelement: Listen Channel */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_listen_channel_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_CHANNEL */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 country[3]; /* Country String */ -+ uint8 op_class; /* Operating Class */ -+ uint8 channel; /* Channel */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_listen_channel_se_s wifi_p2p_listen_channel_se_t; -+ -+/* WiFi P2P IE subelement: P2P Group BSSID */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_bssid_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_GRP_BSSID */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mac[6]; /* P2P group bssid */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_grp_bssid_se_s wifi_p2p_grp_bssid_se_t; -+ -+/* WiFi P2P IE subelement: P2P Group ID */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_id_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_GROUP_ID */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mac[6]; /* P2P device address */ -+ uint8 ssid[1]; /* ssid. device id. variable length */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_grp_id_se_s wifi_p2p_grp_id_se_t; -+ -+/* WiFi P2P IE subelement: P2P Interface */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intf_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_P2P_IF */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mac[6]; /* P2P device address */ -+ uint8 ifaddrs; /* P2P Interface Address count */ -+ uint8 ifaddr[1][6]; /* P2P Interface Address list */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_intf_se_s wifi_p2p_intf_se_t; -+ -+/* WiFi P2P IE subelement: Status */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_status_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_STATUS */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 status; /* Status Code: P2P_STATSE_* */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_status_se_s wifi_p2p_status_se_t; -+ -+/* Status subelement Status Code definitions */ -+#define P2P_STATSE_SUCCESS 0 -+ /* Success */ -+#define P2P_STATSE_FAIL_INFO_CURR_UNAVAIL 1 -+ /* Failed, information currently unavailable */ -+#define P2P_STATSE_PASSED_UP P2P_STATSE_FAIL_INFO_CURR_UNAVAIL -+ /* Old name for above in P2P spec 1.08 and older */ -+#define P2P_STATSE_FAIL_INCOMPAT_PARAMS 2 -+ /* Failed, incompatible parameters */ -+#define P2P_STATSE_FAIL_LIMIT_REACHED 3 -+ /* Failed, limit reached */ -+#define P2P_STATSE_FAIL_INVALID_PARAMS 4 -+ /* Failed, invalid parameters */ -+#define P2P_STATSE_FAIL_UNABLE_TO_ACCOM 5 -+ /* Failed, unable to accomodate request */ -+#define P2P_STATSE_FAIL_PROTO_ERROR 6 -+ /* Failed, previous protocol error or disruptive behaviour */ -+#define P2P_STATSE_FAIL_NO_COMMON_CHAN 7 -+ /* Failed, no common channels */ -+#define P2P_STATSE_FAIL_UNKNOWN_GROUP 8 -+ /* Failed, unknown P2P Group */ -+#define P2P_STATSE_FAIL_INTENT 9 -+ /* Failed, both peers indicated Intent 15 in GO Negotiation */ -+#define P2P_STATSE_FAIL_INCOMPAT_PROVIS 10 -+ /* Failed, incompatible provisioning method */ -+#define P2P_STATSE_FAIL_USER_REJECT 11 -+ /* Failed, rejected by user */ -+ -+/* WiFi P2P IE attribute: Extended Listen Timing */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_ext_se_s { -+ uint8 eltId; /* ID: P2P_SEID_EXT_TIMING */ -+ uint8 len[2]; /* length not including eltId, len fields */ -+ uint8 avail[2]; /* availibility period */ -+ uint8 interval[2]; /* availibility interval */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_ext_se_s wifi_p2p_ext_se_t; -+ -+#define P2P_EXT_MIN 10 /* minimum 10ms */ -+ -+/* WiFi P2P IE subelement: Intended P2P Interface Address */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intintad_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_INTINTADDR */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mac[6]; /* intended P2P interface MAC address */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_intintad_se_s wifi_p2p_intintad_se_t; -+ -+/* WiFi P2P IE subelement: Channel */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_channel_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_STATUS */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 band; /* Regulatory Class (band) */ -+ uint8 channel; /* Channel */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_channel_se_s wifi_p2p_channel_se_t; -+ -+ -+/* Channel Entry structure within the Channel List SE */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_entry_s { -+ uint8 band; /* Regulatory Class (band) */ -+ uint8 num_channels; /* # of channels in the channel list */ -+ uint8 channels[WL_NUMCHANNELS]; /* Channel List */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_chanlist_entry_s wifi_p2p_chanlist_entry_t; -+#define WIFI_P2P_CHANLIST_SE_MAX_ENTRIES 2 -+ -+/* WiFi P2P IE subelement: Channel List */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_CHAN_LIST */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 country[3]; /* Country String */ -+ uint8 num_entries; /* # of channel entries */ -+ wifi_p2p_chanlist_entry_t entries[WIFI_P2P_CHANLIST_SE_MAX_ENTRIES]; -+ /* Channel Entry List */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t; -+ -+/* WiFi Primary Device Type structure */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_pri_devtype_s { -+ uint16 cat_id; /* Category ID */ -+ uint8 OUI[3]; /* WFA OUI: 0x0050F2 */ -+ uint8 oui_type; /* WPS_OUI_TYPE */ -+ uint16 sub_cat_id; /* Sub Category ID */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_pri_devtype_s wifi_p2p_pri_devtype_t; -+ -+/* WiFi P2P IE's Device Info subelement */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_devinfo_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_DEVINFO */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mac[6]; /* P2P Device MAC address */ -+ uint16 wps_cfg_meths; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ -+ uint8 pri_devtype[8]; /* Primary Device Type */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_devinfo_se_s wifi_p2p_devinfo_se_t; -+ -+#define P2P_DEV_TYPE_LEN 8 -+ -+/* WiFi P2P IE's Group Info subelement Client Info Descriptor */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_cid_fixed_s { -+ uint8 len; -+ uint8 devaddr[ETHER_ADDR_LEN]; /* P2P Device Address */ -+ uint8 ifaddr[ETHER_ADDR_LEN]; /* P2P Interface Address */ -+ uint8 devcap; /* Device Capability */ -+ uint8 cfg_meths[2]; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ -+ uint8 pridt[P2P_DEV_TYPE_LEN]; /* Primary Device Type */ -+ uint8 secdts; /* Number of Secondary Device Types */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_cid_fixed_s wifi_p2p_cid_fixed_t; -+ -+/* WiFi P2P IE's Device ID subelement */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_devid_se_s { -+ uint8 eltId; -+ uint8 len[2]; -+ struct ether_addr addr; /* P2P Device MAC address */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_devid_se_s wifi_p2p_devid_se_t; -+ -+/* WiFi P2P IE subelement: P2P Manageability */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_mgbt_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_P2P_MGBTY */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 mg_bitmap; /* manageability bitmap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_mgbt_se_s wifi_p2p_mgbt_se_t; -+/* mg_bitmap field bit values */ -+#define P2P_MGBTSE_P2PDEVMGMT_FLAG 0x1 /* AP supports Managed P2P Device */ -+ -+/* WiFi P2P IE subelement: Group Info */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grpinfo_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_GROUP_INFO */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t; -+ -+/* WiFi IE subelement: Operating Channel */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_op_channel_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_OP_CHANNEL */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 country[3]; /* Country String */ -+ uint8 op_class; /* Operating Class */ -+ uint8 channel; /* Channel */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_op_channel_se_s wifi_p2p_op_channel_se_t; -+ -+/* WiFi IE subelement: INVITATION FLAGS */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_invite_flags_se_s { -+ uint8 eltId; /* SE ID: P2P_SEID_INVITE_FLAGS */ -+ uint8 len[2]; /* SE length not including eltId, len fields */ -+ uint8 flags; /* Flags */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_invite_flags_se_s wifi_p2p_invite_flags_se_t; -+ -+/* WiFi P2P Action Frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_action_frame { -+ uint8 category; /* P2P_AF_CATEGORY */ -+ uint8 OUI[3]; /* OUI - P2P_OUI */ -+ uint8 type; /* OUI Type - P2P_VER */ -+ uint8 subtype; /* OUI Subtype - P2P_AF_* */ -+ uint8 dialog_token; /* nonzero, identifies req/resp tranaction */ -+ uint8 elts[1]; /* Variable length information elements. Max size = -+ * ACTION_FRAME_SIZE - sizeof(this structure) - 1 -+ */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_action_frame wifi_p2p_action_frame_t; -+#define P2P_AF_CATEGORY 0x7f -+ -+#define P2P_AF_FIXED_LEN 7 -+ -+/* WiFi P2P Action Frame OUI Subtypes */ -+#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */ -+#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */ -+#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */ -+#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */ -+ -+ -+/* WiFi P2P Public Action Frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_pub_act_frame { -+ uint8 category; /* P2P_PUB_AF_CATEGORY */ -+ uint8 action; /* P2P_PUB_AF_ACTION */ -+ uint8 oui[3]; /* P2P_OUI */ -+ uint8 oui_type; /* OUI type - P2P_VER */ -+ uint8 subtype; /* OUI subtype - P2P_TYPE_* */ -+ uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ -+ uint8 elts[1]; /* Variable length information elements. Max size = -+ * ACTION_FRAME_SIZE - sizeof(this structure) - 1 -+ */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_pub_act_frame wifi_p2p_pub_act_frame_t; -+#define P2P_PUB_AF_FIXED_LEN 8 -+#define P2P_PUB_AF_CATEGORY 0x04 -+#define P2P_PUB_AF_ACTION 0x09 -+ -+/* WiFi P2P Public Action Frame OUI Subtypes */ -+#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */ -+#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */ -+#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */ -+#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */ -+#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */ -+#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */ -+#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */ -+#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */ -+#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Response */ -+#define P2P_PAF_SUBTYPE_INVALID 255 /* Invalid Subtype */ -+ -+/* TODO: Stop using these obsolete aliases for P2P_PAF_GON_* */ -+#define P2P_TYPE_MNREQ P2P_PAF_GON_REQ -+#define P2P_TYPE_MNRSP P2P_PAF_GON_RSP -+#define P2P_TYPE_MNCONF P2P_PAF_GON_CONF -+ -+/* WiFi P2P IE subelement: Notice of Absence */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_desc { -+ uint8 cnt_type; /* Count/Type */ -+ uint32 duration; /* Duration */ -+ uint32 interval; /* Interval */ -+ uint32 start; /* Start Time */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_noa_desc wifi_p2p_noa_desc_t; -+ -+BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_se { -+ uint8 eltId; /* Subelement ID */ -+ uint8 len[2]; /* Length */ -+ uint8 index; /* Index */ -+ uint8 ops_ctw_parms; /* CTWindow and OppPS Parameters */ -+ wifi_p2p_noa_desc_t desc[1]; /* Notice of Absence Descriptor(s) */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2p_noa_se wifi_p2p_noa_se_t; -+ -+#define P2P_NOA_SE_FIXED_LEN 5 -+ -+/* cnt_type field values */ -+#define P2P_NOA_DESC_CNT_RESERVED 0 /* reserved and should not be used */ -+#define P2P_NOA_DESC_CNT_REPEAT 255 /* continuous schedule */ -+#define P2P_NOA_DESC_TYPE_PREFERRED 1 /* preferred values */ -+#define P2P_NOA_DESC_TYPE_ACCEPTABLE 2 /* acceptable limits */ -+ -+/* ctw_ops_parms field values */ -+#define P2P_NOA_CTW_MASK 0x7f -+#define P2P_NOA_OPS_MASK 0x80 -+#define P2P_NOA_OPS_SHIFT 7 -+ -+#define P2P_CTW_MIN 10 /* minimum 10TU */ -+ -+/* -+ * P2P Service Discovery related -+ */ -+#define P2PSD_ACTION_CATEGORY 0x04 -+ /* Public action frame */ -+#define P2PSD_ACTION_ID_GAS_IREQ 0x0a -+ /* Action value for GAS Initial Request AF */ -+#define P2PSD_ACTION_ID_GAS_IRESP 0x0b -+ /* Action value for GAS Initial Response AF */ -+#define P2PSD_ACTION_ID_GAS_CREQ 0x0c -+ /* Action value for GAS Comback Request AF */ -+#define P2PSD_ACTION_ID_GAS_CRESP 0x0d -+ /* Action value for GAS Comback Response AF */ -+#define P2PSD_AD_EID 0x6c -+ /* Advertisement Protocol IE ID */ -+#define P2PSD_ADP_TUPLE_QLMT_PAMEBI 0x00 -+ /* Query Response Length Limit 7 bits plus PAME-BI 1 bit */ -+#define P2PSD_ADP_PROTO_ID 0x00 -+ /* Advertisement Protocol ID. Always 0 for P2P SD */ -+#define P2PSD_GAS_OUI P2P_OUI -+ /* WFA OUI */ -+#define P2PSD_GAS_OUI_SUBTYPE P2P_VER -+ /* OUI Subtype for GAS IE */ -+#define P2PSD_GAS_NQP_INFOID 0xDDDD -+ /* NQP Query Info ID: 56797 */ -+#define P2PSD_GAS_COMEBACKDEALY 0x00 -+ /* Not used in the Native GAS protocol */ -+ -+/* Service Protocol Type */ -+typedef enum p2psd_svc_protype { -+ SVC_RPOTYPE_ALL = 0, -+ SVC_RPOTYPE_BONJOUR = 1, -+ SVC_RPOTYPE_UPNP = 2, -+ SVC_RPOTYPE_WSD = 3, -+ SVC_RPOTYPE_VENDOR = 255 -+} p2psd_svc_protype_t; -+ -+/* Service Discovery response status code */ -+typedef enum { -+ P2PSD_RESP_STATUS_SUCCESS = 0, -+ P2PSD_RESP_STATUS_PROTYPE_NA = 1, -+ P2PSD_RESP_STATUS_DATA_NA = 2, -+ P2PSD_RESP_STATUS_BAD_REQUEST = 3 -+} p2psd_resp_status_t; -+ -+/* Advertisement Protocol IE tuple field */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_tpl { -+ uint8 llm_pamebi; /* Query Response Length Limit bit 0-6, set to 0 plus -+ * Pre-Associated Message Exchange BSSID Independent bit 7, set to 0 -+ */ -+ uint8 adp_id; /* Advertisement Protocol ID: 0 for NQP Native Query Protocol */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_adp_tpl wifi_p2psd_adp_tpl_t; -+ -+/* Advertisement Protocol IE */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_ie { -+ uint8 id; /* IE ID: 0x6c - 108 */ -+ uint8 len; /* IE length */ -+ wifi_p2psd_adp_tpl_t adp_tpl; /* Advertisement Protocol Tuple field. Only one -+ * tuple is defined for P2P Service Discovery -+ */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_adp_ie wifi_p2psd_adp_ie_t; -+ -+/* NQP Vendor-specific Content */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_nqp_query_vsc { -+ uint8 oui_subtype; /* OUI Subtype: 0x09 */ -+ uint16 svc_updi; /* Service Update Indicator */ -+ uint8 svc_tlvs[1]; /* wifi_p2psd_qreq_tlv_t type for service request, -+ * wifi_p2psd_qresp_tlv_t type for service response -+ */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_nqp_query_vsc wifi_p2psd_nqp_query_vsc_t; -+ -+/* Service Request TLV */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_tlv { -+ uint16 len; /* Length: 5 plus size of Query Data */ -+ uint8 svc_prot; /* Service Protocol Type */ -+ uint8 svc_tscid; /* Service Transaction ID */ -+ uint8 query_data[1]; /* Query Data, passed in from above Layer 2 */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_qreq_tlv wifi_p2psd_qreq_tlv_t; -+ -+/* Query Request Frame, defined in generic format, instead of NQP specific */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_frame { -+ uint16 info_id; /* Info ID: 0xDDDD */ -+ uint16 len; /* Length of service request TLV, 5 plus the size of request data */ -+ uint8 oui[3]; /* WFA OUI: 0x0050F2 */ -+ uint8 qreq_vsc[1]; /* Vendor-specific Content: wifi_p2psd_nqp_query_vsc_t type for NQP */ -+ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_qreq_frame wifi_p2psd_qreq_frame_t; -+ -+/* GAS Initial Request AF body, "elts" in wifi_p2p_pub_act_frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_ireq_frame { -+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ -+ uint16 qreq_len; /* Query Request Length */ -+ uint8 qreq_frm[1]; /* Query Request Frame wifi_p2psd_qreq_frame_t */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_gas_ireq_frame wifi_p2psd_gas_ireq_frame_t; -+ -+/* Service Response TLV */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_tlv { -+ uint16 len; /* Length: 5 plus size of Query Data */ -+ uint8 svc_prot; /* Service Protocol Type */ -+ uint8 svc_tscid; /* Service Transaction ID */ -+ uint8 status; /* Value defined in Table 57 of P2P spec. */ -+ uint8 query_data[1]; /* Response Data, passed in from above Layer 2 */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_qresp_tlv wifi_p2psd_qresp_tlv_t; -+ -+/* Query Response Frame, defined in generic format, instead of NQP specific */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_frame { -+ uint16 info_id; /* Info ID: 0xDDDD */ -+ uint16 len; /* Lenth of service response TLV, 6 plus the size of resp data */ -+ uint8 oui[3]; /* WFA OUI: 0x0050F2 */ -+ uint8 qresp_vsc[1]; /* Vendor-specific Content: wifi_p2psd_qresp_tlv_t type for NQP */ -+ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_qresp_frame wifi_p2psd_qresp_frame_t; -+ -+/* GAS Initial Response AF body, "elts" in wifi_p2p_pub_act_frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_iresp_frame { -+ uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ -+ uint16 cb_delay; /* GAS Comeback Delay */ -+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ -+ uint16 qresp_len; /* Query Response Length */ -+ uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_gas_iresp_frame wifi_p2psd_gas_iresp_frame_t; -+ -+/* GAS Comeback Response AF body, "elts" in wifi_p2p_pub_act_frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_cresp_frame { -+ uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ -+ uint8 fragment_id; /* Fragmentation ID */ -+ uint16 cb_delay; /* GAS Comeback Delay */ -+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ -+ uint16 qresp_len; /* Query Response Length */ -+ uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_gas_cresp_frame wifi_p2psd_gas_cresp_frame_t; -+ -+/* Wi-Fi GAS Public Action Frame */ -+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_pub_act_frame { -+ uint8 category; /* 0x04 Public Action Frame */ -+ uint8 action; /* 0x6c Advertisement Protocol */ -+ uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ -+ uint8 query_data[1]; /* Query Data. wifi_p2psd_gas_ireq_frame_t -+ * or wifi_p2psd_gas_iresp_frame_t format -+ */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wifi_p2psd_gas_pub_act_frame wifi_p2psd_gas_pub_act_frame_t; -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _P2P_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/sdspi.h b/drivers/net/wireless/ap6210/include/proto/sdspi.h -new file mode 100644 -index 0000000..a4900ed ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/sdspi.h -@@ -0,0 +1,75 @@ -+/* -+ * SD-SPI Protocol Standard -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sdspi.h 241182 2011-02-17 21:50:03Z $ -+ */ -+#ifndef _SD_SPI_H -+#define _SD_SPI_H -+ -+#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */ -+#define SPI_START_S 31 -+#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */ -+#define SPI_DIR_S 30 -+#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */ -+#define SPI_CMD_INDEX_S 24 -+#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */ -+#define SPI_RW_S 23 -+#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */ -+#define SPI_FUNC_S 20 -+#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */ -+#define SPI_RAW_S 19 -+#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */ -+#define SPI_STUFF_S 18 -+#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */ -+#define SPI_BLKMODE_S 19 -+#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */ -+#define SPI_OPCODE_S 18 -+#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */ -+#define SPI_ADDR_S 1 -+#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */ -+#define SPI_STUFF0_S 0 -+ -+#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */ -+#define SPI_RSP_START_S 7 -+#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */ -+#define SPI_RSP_PARAM_ERR_S 6 -+#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */ -+#define SPI_RSP_RFU5_S 5 -+#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */ -+#define SPI_RSP_FUNC_ERR_S 4 -+#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */ -+#define SPI_RSP_CRC_ERR_S 3 -+#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */ -+#define SPI_RSP_ILL_CMD_S 2 -+#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */ -+#define SPI_RSP_RFU1_S 1 -+#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */ -+#define SPI_RSP_IDLE_S 0 -+ -+/* SD-SPI Protocol Definitions */ -+#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */ -+#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */ -+#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */ -+#define SDSPI_START_BIT_MASK 0x80 -+ -+#endif /* _SD_SPI_H */ -diff --git a/drivers/net/wireless/ap6210/include/proto/vlan.h b/drivers/net/wireless/ap6210/include/proto/vlan.h -new file mode 100644 -index 0000000..88502bf ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/vlan.h -@@ -0,0 +1,69 @@ -+/* -+ * 802.1Q VLAN protocol definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: vlan.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _vlan_h_ -+#define _vlan_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ -+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ -+#define VLAN_PRI_SHIFT 13 /* user priority */ -+ -+#define VLAN_PRI_MASK 7 /* 3 bits of priority */ -+ -+#define VLAN_TAG_LEN 4 -+#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */ -+ -+#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */ -+ -+struct ethervlan_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 vlan_type; /* 0x8100 */ -+ uint16 vlan_tag; /* priority, cfi and vid */ -+ uint16 ether_type; -+}; -+ -+#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#define ETHERVLAN_MOVE_HDR(d, s) \ -+do { \ -+ struct ethervlan_header t; \ -+ t = *(struct ethervlan_header *)(s); \ -+ *(struct ethervlan_header *)(d) = t; \ -+} while (0) -+ -+#endif /* _vlan_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/proto/wpa.h b/drivers/net/wireless/ap6210/include/proto/wpa.h -new file mode 100644 -index 0000000..23ab8d6 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/proto/wpa.h -@@ -0,0 +1,206 @@ -+/* -+ * Fundamental types and constants relating to WPA -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wpa.h 261155 2011-05-23 23:51:32Z $ -+ */ -+ -+#ifndef _proto_wpa_h_ -+#define _proto_wpa_h_ -+ -+#include -+#include -+ -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+/* Reason Codes */ -+ -+/* 13 through 23 taken from IEEE Std 802.11i-2004 */ -+#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ -+#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ -+#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ -+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from -+ * (re-)assoc. request/probe response -+ */ -+#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ -+#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ -+#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ -+#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ -+#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ -+#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ -+ -+#define WPA2_PMKID_LEN 16 -+ -+/* WPA IE fixed portion */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ uint8 oui[3]; /* IE OUI */ -+ uint8 oui_type; /* OUI type */ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT version; /* IE version */ -+} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -+#define WPA_IE_OUITYPE_LEN 4 -+#define WPA_IE_FIXED_LEN 8 -+#define WPA_IE_TAG_FIXED_LEN 6 -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT version; /* IE version */ -+} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -+#define WPA_RSN_IE_FIXED_LEN 4 -+#define WPA_RSN_IE_TAG_FIXED_LEN 2 -+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; -+ -+/* WPA suite/multicast suite */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint8 oui[3]; -+ uint8 type; -+} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -+#define WPA_SUITE_LEN 4 -+ -+/* WPA unicast suite list/key management suite list */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT count; -+ wpa_suite_t list[1]; -+} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -+#define WPA_IE_SUITE_COUNT_LEN 2 -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT count; -+ wpa_pmkid_t list[1]; -+} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; -+ -+/* WPA cipher suites */ -+#define WPA_CIPHER_NONE 0 /* None */ -+#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ -+#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ -+#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ -+#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ -+#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ -+#define WPA_CIPHER_BIP 6 /* WEP (104-bit) */ -+#define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */ -+#ifdef BCMWAPI_WPI -+#define WAPI_CIPHER_NONE WPA_CIPHER_NONE -+#define WAPI_CIPHER_SMS4 11 -+ -+#define WAPI_CSE_WPI_SMS4 1 -+#endif /* BCMWAPI_WPI */ -+ -+ -+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ -+ (cipher) == WPA_CIPHER_WEP_40 || \ -+ (cipher) == WPA_CIPHER_WEP_104 || \ -+ (cipher) == WPA_CIPHER_TKIP || \ -+ (cipher) == WPA_CIPHER_AES_OCB || \ -+ (cipher) == WPA_CIPHER_AES_CCM || \ -+ (cipher) == WPA_CIPHER_TPK) -+ -+#ifdef BCMWAPI_WAI -+#define IS_WAPI_CIPHER(cipher) ((cipher) == WAPI_CIPHER_NONE || \ -+ (cipher) == WAPI_CSE_WPI_SMS4) -+ -+/* convert WAPI_CSE_WPI_XXX to WAPI_CIPHER_XXX */ -+#define WAPI_CSE_WPI_2_CIPHER(cse) ((cse) == WAPI_CSE_WPI_SMS4 ? \ -+ WAPI_CIPHER_SMS4 : WAPI_CIPHER_NONE) -+ -+#define WAPI_CIPHER_2_CSE_WPI(cipher) ((cipher) == WAPI_CIPHER_SMS4 ? \ -+ WAPI_CSE_WPI_SMS4 : WAPI_CIPHER_NONE) -+#endif /* BCMWAPI_WAI */ -+ -+ -+/* WPA TKIP countermeasures parameters */ -+#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ -+#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ -+ -+/* RSN IE defines */ -+#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */ -+ -+/* RSN Capabilities defined in 802.11i */ -+#define RSN_CAP_PREAUTH 0x0001 -+#define RSN_CAP_NOPAIRWISE 0x0002 -+#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -+#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -+#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -+#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 -+#define RSN_CAP_1_REPLAY_CNTR 0 -+#define RSN_CAP_2_REPLAY_CNTRS 1 -+#define RSN_CAP_4_REPLAY_CNTRS 2 -+#define RSN_CAP_16_REPLAY_CNTRS 3 -+#ifdef MFP -+#define RSN_CAP_MFPR 0x0040 -+#define RSN_CAP_MFPC 0x0080 -+#endif -+ -+/* WPA capabilities defined in 802.11i */ -+#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -+#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -+#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -+#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK -+ -+/* WPA capabilities defined in 802.11zD9.0 */ -+#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) /* bit 9 */ -+ -+/* WPA Specific defines */ -+#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */ -+#define WPA_PMKID_CNT_LEN 2 /* Length of RSN PMKID count (2 octests) */ -+ -+#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH -+ -+#ifdef BCMWAPI_WAI -+#define WAPI_CAP_PREAUTH RSN_CAP_PREAUTH -+ -+/* Other WAI definition */ -+#define WAPI_WAI_REQUEST 0x00F1 -+#define WAPI_UNICAST_REKEY 0x00F2 -+#define WAPI_STA_AGING 0x00F3 -+#define WAPI_MUTIL_REKEY 0x00F4 -+#define WAPI_STA_STATS 0x00F5 -+ -+#define WAPI_USK_REKEY_COUNT 0x4000000 /* 0xA00000 */ -+#define WAPI_MSK_REKEY_COUNT 0x4000000 /* 0xA00000 */ -+#endif /* BCMWAPI_WAI */ -+#define WPA2_PMKID_COUNT_LEN 2 -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _proto_wpa_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/sbchipc.h b/drivers/net/wireless/ap6210/include/sbchipc.h -new file mode 100644 -index 0000000..c694291 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbchipc.h -@@ -0,0 +1,2405 @@ -+/* -+ * SiliconBackplane Chipcommon core hardware definitions. -+ * -+ * The chipcommon core provides chip identification, SB control, -+ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, -+ * GPIO interface, extbus, and support for serial and parallel flashes. -+ * -+ * $Id: sbchipc.h 347614 2012-07-27 10:24:51Z $ -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ */ -+ -+#ifndef _SBCHIPC_H -+#define _SBCHIPC_H -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+typedef struct eci_prerev35 { -+ uint32 eci_output; -+ uint32 eci_control; -+ uint32 eci_inputlo; -+ uint32 eci_inputmi; -+ uint32 eci_inputhi; -+ uint32 eci_inputintpolaritylo; -+ uint32 eci_inputintpolaritymi; -+ uint32 eci_inputintpolarityhi; -+ uint32 eci_intmasklo; -+ uint32 eci_intmaskmi; -+ uint32 eci_intmaskhi; -+ uint32 eci_eventlo; -+ uint32 eci_eventmi; -+ uint32 eci_eventhi; -+ uint32 eci_eventmasklo; -+ uint32 eci_eventmaskmi; -+ uint32 eci_eventmaskhi; -+ uint32 PAD[3]; -+} eci_prerev35_t; -+ -+typedef struct eci_rev35 { -+ uint32 eci_outputlo; -+ uint32 eci_outputhi; -+ uint32 eci_controllo; -+ uint32 eci_controlhi; -+ uint32 eci_inputlo; -+ uint32 eci_inputhi; -+ uint32 eci_inputintpolaritylo; -+ uint32 eci_inputintpolarityhi; -+ uint32 eci_intmasklo; -+ uint32 eci_intmaskhi; -+ uint32 eci_eventlo; -+ uint32 eci_eventhi; -+ uint32 eci_eventmasklo; -+ uint32 eci_eventmaskhi; -+ uint32 eci_auxtx; -+ uint32 eci_auxrx; -+ uint32 eci_datatag; -+ uint32 eci_uartescvalue; -+ uint32 eci_autobaudctr; -+ uint32 eci_uartfifolevel; -+} eci_rev35_t; -+ -+typedef struct flash_config { -+ uint32 PAD[19]; -+ /* Flash struct configuration registers (0x18c) for BCM4706 (corerev = 31) */ -+ uint32 flashstrconfig; -+} flash_config_t; -+ -+typedef volatile struct { -+ uint32 chipid; /* 0x0 */ -+ uint32 capabilities; -+ uint32 corecontrol; /* corerev >= 1 */ -+ uint32 bist; -+ -+ /* OTP */ -+ uint32 otpstatus; /* 0x10, corerev >= 10 */ -+ uint32 otpcontrol; -+ uint32 otpprog; -+ uint32 otplayout; /* corerev >= 23 */ -+ -+ /* Interrupt control */ -+ uint32 intstatus; /* 0x20 */ -+ uint32 intmask; -+ -+ /* Chip specific regs */ -+ uint32 chipcontrol; /* 0x28, rev >= 11 */ -+ uint32 chipstatus; /* 0x2c, rev >= 11 */ -+ -+ /* Jtag Master */ -+ uint32 jtagcmd; /* 0x30, rev >= 10 */ -+ uint32 jtagir; -+ uint32 jtagdr; -+ uint32 jtagctrl; -+ -+ /* serial flash interface registers */ -+ uint32 flashcontrol; /* 0x40 */ -+ uint32 flashaddress; -+ uint32 flashdata; -+ uint32 otplayoutextension; /* rev >= 35 */ -+ -+ /* Silicon backplane configuration broadcast control */ -+ uint32 broadcastaddress; /* 0x50 */ -+ uint32 broadcastdata; -+ -+ /* gpio - cleared only by power-on-reset */ -+ uint32 gpiopullup; /* 0x58, corerev >= 20 */ -+ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */ -+ uint32 gpioin; /* 0x60 */ -+ uint32 gpioout; /* 0x64 */ -+ uint32 gpioouten; /* 0x68 */ -+ uint32 gpiocontrol; /* 0x6C */ -+ uint32 gpiointpolarity; /* 0x70 */ -+ uint32 gpiointmask; /* 0x74 */ -+ -+ /* GPIO events corerev >= 11 */ -+ uint32 gpioevent; -+ uint32 gpioeventintmask; -+ -+ /* Watchdog timer */ -+ uint32 watchdog; /* 0x80 */ -+ -+ /* GPIO events corerev >= 11 */ -+ uint32 gpioeventintpolarity; -+ -+ /* GPIO based LED powersave registers corerev >= 16 */ -+ uint32 gpiotimerval; /* 0x88 */ -+ uint32 gpiotimeroutmask; -+ -+ /* clock control */ -+ uint32 clockcontrol_n; /* 0x90 */ -+ uint32 clockcontrol_sb; /* aka m0 */ -+ uint32 clockcontrol_pci; /* aka m1 */ -+ uint32 clockcontrol_m2; /* mii/uart/mipsref */ -+ uint32 clockcontrol_m3; /* cpu */ -+ uint32 clkdiv; /* corerev >= 3 */ -+ uint32 gpiodebugsel; /* corerev >= 28 */ -+ uint32 capabilities_ext; /* 0xac */ -+ -+ /* pll delay registers (corerev >= 4) */ -+ uint32 pll_on_delay; /* 0xb0 */ -+ uint32 fref_sel_delay; -+ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ -+ uint32 PAD; -+ -+ /* Instaclock registers (corerev >= 10) */ -+ uint32 system_clk_ctl; /* 0xc0 */ -+ uint32 clkstatestretch; -+ uint32 PAD[2]; -+ -+ /* Indirect backplane access (corerev >= 22) */ -+ uint32 bp_addrlow; /* 0xd0 */ -+ uint32 bp_addrhigh; -+ uint32 bp_data; -+ uint32 PAD; -+ uint32 bp_indaccess; -+ /* SPI registers, corerev >= 37 */ -+ uint32 gsioctrl; -+ uint32 gsioaddress; -+ uint32 gsiodata; -+ -+ /* More clock dividers (corerev >= 32) */ -+ uint32 clkdiv2; -+ /* FAB ID (corerev >= 40) */ -+ uint32 otpcontrol1; -+ uint32 fabid; /* 0xf8 */ -+ -+ /* In AI chips, pointer to erom */ -+ uint32 eromptr; /* 0xfc */ -+ -+ /* ExtBus control registers (corerev >= 3) */ -+ uint32 pcmcia_config; /* 0x100 */ -+ uint32 pcmcia_memwait; -+ uint32 pcmcia_attrwait; -+ uint32 pcmcia_iowait; -+ uint32 ide_config; -+ uint32 ide_memwait; -+ uint32 ide_attrwait; -+ uint32 ide_iowait; -+ uint32 prog_config; -+ uint32 prog_waitcount; -+ uint32 flash_config; -+ uint32 flash_waitcount; -+ uint32 SECI_config; /* 0x130 SECI configuration */ -+ uint32 SECI_status; -+ uint32 SECI_statusmask; -+ uint32 SECI_rxnibchanged; -+ -+ uint32 PAD[20]; -+ -+ /* SROM interface (corerev >= 32) */ -+ uint32 sromcontrol; /* 0x190 */ -+ uint32 sromaddress; -+ uint32 sromdata; -+ uint32 PAD[1]; /* 0x19C */ -+ /* NAND flash registers for BCM4706 (corerev = 31) */ -+ uint32 nflashctrl; /* 0x1a0 */ -+ uint32 nflashconf; -+ uint32 nflashcoladdr; -+ uint32 nflashrowaddr; -+ uint32 nflashdata; -+ uint32 nflashwaitcnt0; /* 0x1b4 */ -+ uint32 PAD[2]; -+ -+ uint32 seci_uart_data; /* 0x1C0 */ -+ uint32 seci_uart_bauddiv; -+ uint32 seci_uart_fcr; -+ uint32 seci_uart_lcr; -+ uint32 seci_uart_mcr; -+ uint32 seci_uart_lsr; -+ uint32 seci_uart_msr; -+ uint32 seci_uart_baudadj; -+ /* Clock control and hardware workarounds (corerev >= 20) */ -+ uint32 clk_ctl_st; /* 0x1e0 */ -+ uint32 hw_war; -+ uint32 PAD[70]; -+ -+ /* UARTs */ -+ uint8 uart0data; /* 0x300 */ -+ uint8 uart0imr; -+ uint8 uart0fcr; -+ uint8 uart0lcr; -+ uint8 uart0mcr; -+ uint8 uart0lsr; -+ uint8 uart0msr; -+ uint8 uart0scratch; -+ uint8 PAD[248]; /* corerev >= 1 */ -+ -+ uint8 uart1data; /* 0x400 */ -+ uint8 uart1imr; -+ uint8 uart1fcr; -+ uint8 uart1lcr; -+ uint8 uart1mcr; -+ uint8 uart1lsr; -+ uint8 uart1msr; -+ uint8 uart1scratch; -+ uint32 PAD[126]; -+ -+ /* PMU registers (corerev >= 20) */ -+ /* Note: all timers driven by ILP clock are updated asynchronously to HT/ALP. -+ * The CPU must read them twice, compare, and retry if different. -+ */ -+ uint32 pmucontrol; /* 0x600 */ -+ uint32 pmucapabilities; -+ uint32 pmustatus; -+ uint32 res_state; -+ uint32 res_pending; -+ uint32 pmutimer; -+ uint32 min_res_mask; -+ uint32 max_res_mask; -+ uint32 res_table_sel; -+ uint32 res_dep_mask; -+ uint32 res_updn_timer; -+ uint32 res_timer; -+ uint32 clkstretch; -+ uint32 pmuwatchdog; -+ uint32 gpiosel; /* 0x638, rev >= 1 */ -+ uint32 gpioenable; /* 0x63c, rev >= 1 */ -+ uint32 res_req_timer_sel; -+ uint32 res_req_timer; -+ uint32 res_req_mask; -+ uint32 PAD; -+ uint32 chipcontrol_addr; /* 0x650 */ -+ uint32 chipcontrol_data; /* 0x654 */ -+ uint32 regcontrol_addr; -+ uint32 regcontrol_data; -+ uint32 pllcontrol_addr; -+ uint32 pllcontrol_data; -+ uint32 pmustrapopt; /* 0x668, corerev >= 28 */ -+ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ -+ uint32 retention_ctl; /* 0x670 */ -+ uint32 PAD[3]; -+ uint32 retention_grpidx; /* 0x680 */ -+ uint32 retention_grpctl; /* 0x684 */ -+ uint32 PAD[94]; -+ uint16 sromotp[512]; /* 0x800 */ -+#ifdef NFLASH_SUPPORT -+ /* Nand flash MLC controller registers (corerev >= 38) */ -+ uint32 nand_revision; /* 0xC00 */ -+ uint32 nand_cmd_start; -+ uint32 nand_cmd_addr_x; -+ uint32 nand_cmd_addr; -+ uint32 nand_cmd_end_addr; -+ uint32 nand_cs_nand_select; -+ uint32 nand_cs_nand_xor; -+ uint32 PAD; -+ uint32 nand_spare_rd0; -+ uint32 nand_spare_rd4; -+ uint32 nand_spare_rd8; -+ uint32 nand_spare_rd12; -+ uint32 nand_spare_wr0; -+ uint32 nand_spare_wr4; -+ uint32 nand_spare_wr8; -+ uint32 nand_spare_wr12; -+ uint32 nand_acc_control; -+ uint32 PAD; -+ uint32 nand_config; -+ uint32 PAD; -+ uint32 nand_timing_1; -+ uint32 nand_timing_2; -+ uint32 nand_semaphore; -+ uint32 PAD; -+ uint32 nand_devid; -+ uint32 nand_devid_x; -+ uint32 nand_block_lock_status; -+ uint32 nand_intfc_status; -+ uint32 nand_ecc_corr_addr_x; -+ uint32 nand_ecc_corr_addr; -+ uint32 nand_ecc_unc_addr_x; -+ uint32 nand_ecc_unc_addr; -+ uint32 nand_read_error_count; -+ uint32 nand_corr_stat_threshold; -+ uint32 PAD[2]; -+ uint32 nand_read_addr_x; -+ uint32 nand_read_addr; -+ uint32 nand_page_program_addr_x; -+ uint32 nand_page_program_addr; -+ uint32 nand_copy_back_addr_x; -+ uint32 nand_copy_back_addr; -+ uint32 nand_block_erase_addr_x; -+ uint32 nand_block_erase_addr; -+ uint32 nand_inv_read_addr_x; -+ uint32 nand_inv_read_addr; -+ uint32 PAD[2]; -+ uint32 nand_blk_wr_protect; -+ uint32 PAD[3]; -+ uint32 nand_acc_control_cs1; -+ uint32 nand_config_cs1; -+ uint32 nand_timing_1_cs1; -+ uint32 nand_timing_2_cs1; -+ uint32 PAD[20]; -+ uint32 nand_spare_rd16; -+ uint32 nand_spare_rd20; -+ uint32 nand_spare_rd24; -+ uint32 nand_spare_rd28; -+ uint32 nand_cache_addr; -+ uint32 nand_cache_data; -+ uint32 nand_ctrl_config; -+ uint32 nand_ctrl_status; -+#endif /* NFLASH_SUPPORT */ -+ uint32 gci_corecaps0; /* GCI starting at 0xC00 */ -+ uint32 gci_corecaps1; -+ uint32 gci_corecaps2; -+ uint32 gci_corectrl; -+ uint32 gci_corestat; /* 0xC10 */ -+ uint32 PAD[11]; -+ uint32 gci_indirect_addr; /* 0xC40 */ -+ uint32 PAD[111]; -+ uint32 gci_chipctrl; /* 0xE00 */ -+} chipcregs_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+ -+#define CC_CHIPID 0 -+#define CC_CAPABILITIES 4 -+#define CC_CHIPST 0x2c -+#define CC_EROMPTR 0xfc -+ -+#define CC_OTPST 0x10 -+#define CC_JTAGCMD 0x30 -+#define CC_JTAGIR 0x34 -+#define CC_JTAGDR 0x38 -+#define CC_JTAGCTRL 0x3c -+#define CC_GPIOPU 0x58 -+#define CC_GPIOPD 0x5c -+#define CC_GPIOIN 0x60 -+#define CC_GPIOOUT 0x64 -+#define CC_GPIOOUTEN 0x68 -+#define CC_GPIOCTRL 0x6c -+#define CC_GPIOPOL 0x70 -+#define CC_GPIOINTM 0x74 -+#define CC_WATCHDOG 0x80 -+#define CC_CLKC_N 0x90 -+#define CC_CLKC_M0 0x94 -+#define CC_CLKC_M1 0x98 -+#define CC_CLKC_M2 0x9c -+#define CC_CLKC_M3 0xa0 -+#define CC_CLKDIV 0xa4 -+#define CC_SYS_CLK_CTL 0xc0 -+#define CC_CLK_CTL_ST SI_CLK_CTL_ST -+#define PMU_CTL 0x600 -+#define PMU_CAP 0x604 -+#define PMU_ST 0x608 -+#define PMU_RES_STATE 0x60c -+#define PMU_TIMER 0x614 -+#define PMU_MIN_RES_MASK 0x618 -+#define PMU_MAX_RES_MASK 0x61c -+#define CC_CHIPCTL_ADDR 0x650 -+#define CC_CHIPCTL_DATA 0x654 -+#define PMU_REG_CONTROL_ADDR 0x658 -+#define PMU_REG_CONTROL_DATA 0x65C -+#define PMU_PLL_CONTROL_ADDR 0x660 -+#define PMU_PLL_CONTROL_DATA 0x664 -+#define CC_SROM_OTP 0x800 /* SROM/OTP address space */ -+#define CC_GCI_INDIRECT_ADDR_REG 0xC40 -+#define CC_GCI_CHIP_CTRL_REG 0xE00 -+#define CC_GCI_CC_OFFSET_2 2 -+#define CC_GCI_CC_OFFSET_5 5 -+ -+#ifdef NFLASH_SUPPORT -+/* NAND flash support */ -+#define CC_NAND_REVISION 0xC00 -+#define CC_NAND_CMD_START 0xC04 -+#define CC_NAND_CMD_ADDR 0xC0C -+#define CC_NAND_SPARE_RD_0 0xC20 -+#define CC_NAND_SPARE_RD_4 0xC24 -+#define CC_NAND_SPARE_RD_8 0xC28 -+#define CC_NAND_SPARE_RD_C 0xC2C -+#define CC_NAND_CONFIG 0xC48 -+#define CC_NAND_DEVID 0xC60 -+#define CC_NAND_DEVID_EXT 0xC64 -+#define CC_NAND_INTFC_STATUS 0xC6C -+#endif /* NFLASH_SUPPORT */ -+ -+/* chipid */ -+#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ -+#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ -+#define CID_REV_SHIFT 16 /* Chip Revision shift */ -+#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ -+#define CID_PKG_SHIFT 20 /* Package Option shift */ -+#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ -+#define CID_CC_SHIFT 24 -+#define CID_TYPE_MASK 0xf0000000 /* Chip Type */ -+#define CID_TYPE_SHIFT 28 -+ -+/* capabilities */ -+#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ -+#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ -+#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ -+#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ -+#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ -+#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ -+#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ -+#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ -+#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ -+#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */ -+#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */ -+#define CC_CAP_PWR_CTL 0x00040000 /* Power control */ -+#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ -+#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ -+#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */ -+#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */ -+#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */ -+#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ -+#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ -+#define CC_CAP_ECI 0x20000000 /* ECI Present, rev >= 21 */ -+#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ -+#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ -+ -+#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ -+#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ -+ -+/* capabilities extension */ -+#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */ -+ -+/* PLL type */ -+#define PLL_NONE 0x00000000 -+#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */ -+#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */ -+#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */ -+#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */ -+#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */ -+#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ -+#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */ -+ -+/* ILP clock */ -+#define ILP_CLOCK 32000 -+ -+/* ALP clock on pre-PMU chips */ -+#define ALP_CLOCK 20000000 -+ -+/* HT clock */ -+#define HT_CLOCK 80000000 -+ -+/* corecontrol */ -+#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ -+#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ -+#define CC_ASYNCGPIO 0x00000004 /* 1=generate GPIO interrupt without backplane clock */ -+#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */ -+ -+/* 4321 chipcontrol */ -+#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -+#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -+#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */ -+ -+/* Fields in the otpstatus register in rev >= 21 */ -+#define OTPS_OL_MASK 0x000000ff -+#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */ -+#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */ -+#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */ -+#define OTPS_OL_GU 0x00000008 /* general use region is locked */ -+#define OTPS_GUP_MASK 0x00000f00 -+#define OTPS_GUP_SHIFT 8 -+#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ -+#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ -+#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ -+#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ -+#define OTPS_READY 0x00001000 -+#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */ -+#define OTPS_RV_MASK 0x0fff0000 -+#define OTPS_PROGOK 0x40000000 -+ -+/* Fields in the otpcontrol register in rev >= 21 */ -+#define OTPC_PROGSEL 0x00000001 -+#define OTPC_PCOUNT_MASK 0x0000000e -+#define OTPC_PCOUNT_SHIFT 1 -+#define OTPC_VSEL_MASK 0x000000f0 -+#define OTPC_VSEL_SHIFT 4 -+#define OTPC_TMM_MASK 0x00000700 -+#define OTPC_TMM_SHIFT 8 -+#define OTPC_ODM 0x00000800 -+#define OTPC_PROGEN 0x80000000 -+ -+/* Fields in the 40nm otpcontrol register in rev >= 40 */ -+#define OTPC_40NM_PROGSEL_SHIFT 0 -+#define OTPC_40NM_PCOUNT_SHIFT 1 -+#define OTPC_40NM_PCOUNT_WR 0xA -+#define OTPC_40NM_PCOUNT_V1X 0xB -+#define OTPC_40NM_REGCSEL_SHIFT 5 -+#define OTPC_40NM_REGCSEL_DEF 0x4 -+#define OTPC_40NM_PROGIN_SHIFT 8 -+#define OTPC_40NM_R2X_SHIFT 10 -+#define OTPC_40NM_ODM_SHIFT 11 -+#define OTPC_40NM_DF_SHIFT 15 -+#define OTPC_40NM_VSEL_SHIFT 16 -+#define OTPC_40NM_VSEL_WR 0xA -+#define OTPC_40NM_VSEL_V1X 0xA -+#define OTPC_40NM_VSEL_R1X 0x5 -+#define OTPC_40NM_COFAIL_SHIFT 30 -+ -+#define OTPC1_CPCSEL_SHIFT 0 -+#define OTPC1_CPCSEL_DEF 6 -+#define OTPC1_TM_SHIFT 8 -+#define OTPC1_TM_WR 0x84 -+#define OTPC1_TM_V1X 0x84 -+#define OTPC1_TM_R1X 0x4 -+ -+/* Fields in otpprog in rev >= 21 and HND OTP */ -+#define OTPP_COL_MASK 0x000000ff -+#define OTPP_COL_SHIFT 0 -+#define OTPP_ROW_MASK 0x0000ff00 -+#define OTPP_ROW_SHIFT 8 -+#define OTPP_OC_MASK 0x0f000000 -+#define OTPP_OC_SHIFT 24 -+#define OTPP_READERR 0x10000000 -+#define OTPP_VALUE_MASK 0x20000000 -+#define OTPP_VALUE_SHIFT 29 -+#define OTPP_START_BUSY 0x80000000 -+#define OTPP_READ 0x40000000 /* HND OTP */ -+ -+/* Fields in otplayout register */ -+#define OTPL_HWRGN_OFF_MASK 0x00000FFF -+#define OTPL_HWRGN_OFF_SHIFT 0 -+#define OTPL_WRAP_REVID_MASK 0x00F80000 -+#define OTPL_WRAP_REVID_SHIFT 19 -+#define OTPL_WRAP_TYPE_MASK 0x00070000 -+#define OTPL_WRAP_TYPE_SHIFT 16 -+#define OTPL_WRAP_TYPE_65NM 0 -+#define OTPL_WRAP_TYPE_40NM 1 -+ -+/* otplayout reg corerev >= 36 */ -+#define OTP_CISFORMAT_NEW 0x80000000 -+ -+/* Opcodes for OTPP_OC field */ -+#define OTPPOC_READ 0 -+#define OTPPOC_BIT_PROG 1 -+#define OTPPOC_VERIFY 3 -+#define OTPPOC_INIT 4 -+#define OTPPOC_SET 5 -+#define OTPPOC_RESET 6 -+#define OTPPOC_OCST 7 -+#define OTPPOC_ROW_LOCK 8 -+#define OTPPOC_PRESCN_TEST 9 -+ -+/* Opcodes for OTPP_OC field (40NM) */ -+#define OTPPOC_READ_40NM 0 -+#define OTPPOC_PROG_ENABLE_40NM 1 -+#define OTPPOC_PROG_DISABLE_40NM 2 -+#define OTPPOC_VERIFY_40NM 3 -+#define OTPPOC_WORD_VERIFY_1_40NM 4 -+#define OTPPOC_ROW_LOCK_40NM 5 -+#define OTPPOC_STBY_40NM 6 -+#define OTPPOC_WAKEUP_40NM 7 -+#define OTPPOC_WORD_VERIFY_0_40NM 8 -+#define OTPPOC_PRESCN_TEST_40NM 9 -+#define OTPPOC_BIT_PROG_40NM 10 -+#define OTPPOC_WORDPROG_40NM 11 -+#define OTPPOC_BURNIN_40NM 12 -+#define OTPPOC_AUTORELOAD_40NM 13 -+#define OTPPOC_OVST_READ_40NM 14 -+#define OTPPOC_OVST_PROG_40NM 15 -+ -+/* Fields in otplayoutextension */ -+#define OTPLAYOUTEXT_FUSE_MASK 0x3FF -+ -+ -+/* Jtagm characteristics that appeared at a given corerev */ -+#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */ -+#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */ -+#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */ -+ -+/* jtagcmd */ -+#define JCMD_START 0x80000000 -+#define JCMD_BUSY 0x80000000 -+#define JCMD_STATE_MASK 0x60000000 -+#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */ -+#define JCMD_STATE_PIR 0x20000000 /* Pause IR */ -+#define JCMD_STATE_PDR 0x40000000 /* Pause DR */ -+#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */ -+#define JCMD0_ACC_MASK 0x0000f000 -+#define JCMD0_ACC_IRDR 0x00000000 -+#define JCMD0_ACC_DR 0x00001000 -+#define JCMD0_ACC_IR 0x00002000 -+#define JCMD0_ACC_RESET 0x00003000 -+#define JCMD0_ACC_IRPDR 0x00004000 -+#define JCMD0_ACC_PDR 0x00005000 -+#define JCMD0_IRW_MASK 0x00000f00 -+#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ -+#define JCMD_ACC_IRDR 0x00000000 -+#define JCMD_ACC_DR 0x00010000 -+#define JCMD_ACC_IR 0x00020000 -+#define JCMD_ACC_RESET 0x00030000 -+#define JCMD_ACC_IRPDR 0x00040000 -+#define JCMD_ACC_PDR 0x00050000 -+#define JCMD_ACC_PIR 0x00060000 -+#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */ -+#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */ -+#define JCMD_IRW_MASK 0x00001f00 -+#define JCMD_IRW_SHIFT 8 -+#define JCMD_DRW_MASK 0x0000003f -+ -+/* jtagctrl */ -+#define JCTRL_FORCE_CLK 4 /* Force clock */ -+#define JCTRL_EXT_EN 2 /* Enable external targets */ -+#define JCTRL_EN 1 /* Enable Jtag master */ -+ -+/* Fields in clkdiv */ -+#define CLKD_SFLASH 0x0f000000 -+#define CLKD_SFLASH_SHIFT 24 -+#define CLKD_OTP 0x000f0000 -+#define CLKD_OTP_SHIFT 16 -+#define CLKD_JTAG 0x00000f00 -+#define CLKD_JTAG_SHIFT 8 -+#define CLKD_UART 0x000000ff -+ -+#define CLKD2_SROM 0x00000003 -+ -+/* intstatus/intmask */ -+#define CI_GPIO 0x00000001 /* gpio intr */ -+#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */ -+#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */ -+#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */ -+#define CI_ECI 0x00000010 /* eci intr (corerev >= 21) */ -+#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */ -+#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */ -+#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ -+ -+/* slow_clk_ctl */ -+#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ -+#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ -+#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ -+#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ -+#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ -+#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, -+ * 0: LPO is enabled -+ */ -+#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, -+ * 0: power logic control -+ */ -+#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors -+ * PLL clock disable requests from core -+ */ -+#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't -+ * disable crystal when appropriate -+ */ -+#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ -+#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ -+#define SCC_CD_SHIFT 16 -+ -+/* system_clk_ctl */ -+#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ -+#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ -+#define SYCC_FP 0x00000004 /* ForcePLLOn */ -+#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ -+#define SYCC_HR 0x00000010 /* Force HT */ -+#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ -+#define SYCC_CD_SHIFT 16 -+ -+/* Indirect backplane access */ -+#define BPIA_BYTEEN 0x0000000f -+#define BPIA_SZ1 0x00000001 -+#define BPIA_SZ2 0x00000003 -+#define BPIA_SZ4 0x00000007 -+#define BPIA_SZ8 0x0000000f -+#define BPIA_WRITE 0x00000100 -+#define BPIA_START 0x00000200 -+#define BPIA_BUSY 0x00000200 -+#define BPIA_ERROR 0x00000400 -+ -+/* pcmcia/prog/flash_config */ -+#define CF_EN 0x00000001 /* enable */ -+#define CF_EM_MASK 0x0000000e /* mode */ -+#define CF_EM_SHIFT 1 -+#define CF_EM_FLASH 0 /* flash/asynchronous mode */ -+#define CF_EM_SYNC 2 /* synchronous mode */ -+#define CF_EM_PCMCIA 4 /* pcmcia mode */ -+#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */ -+#define CF_BS 0x00000020 /* byteswap */ -+#define CF_CD_MASK 0x000000c0 /* clock divider */ -+#define CF_CD_SHIFT 6 -+#define CF_CD_DIV2 0x00000000 /* backplane/2 */ -+#define CF_CD_DIV3 0x00000040 /* backplane/3 */ -+#define CF_CD_DIV4 0x00000080 /* backplane/4 */ -+#define CF_CE 0x00000100 /* clock enable */ -+#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */ -+ -+/* pcmcia_memwait */ -+#define PM_W0_MASK 0x0000003f /* waitcount0 */ -+#define PM_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PM_W1_SHIFT 8 -+#define PM_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PM_W2_SHIFT 16 -+#define PM_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PM_W3_SHIFT 24 -+ -+/* pcmcia_attrwait */ -+#define PA_W0_MASK 0x0000003f /* waitcount0 */ -+#define PA_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PA_W1_SHIFT 8 -+#define PA_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PA_W2_SHIFT 16 -+#define PA_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PA_W3_SHIFT 24 -+ -+/* pcmcia_iowait */ -+#define PI_W0_MASK 0x0000003f /* waitcount0 */ -+#define PI_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PI_W1_SHIFT 8 -+#define PI_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PI_W2_SHIFT 16 -+#define PI_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PI_W3_SHIFT 24 -+ -+/* prog_waitcount */ -+#define PW_W0_MASK 0x0000001f /* waitcount0 */ -+#define PW_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PW_W1_SHIFT 8 -+#define PW_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PW_W2_SHIFT 16 -+#define PW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PW_W3_SHIFT 24 -+ -+#define PW_W0 0x0000000c -+#define PW_W1 0x00000a00 -+#define PW_W2 0x00020000 -+#define PW_W3 0x01000000 -+ -+/* flash_waitcount */ -+#define FW_W0_MASK 0x0000003f /* waitcount0 */ -+#define FW_W1_MASK 0x00001f00 /* waitcount1 */ -+#define FW_W1_SHIFT 8 -+#define FW_W2_MASK 0x001f0000 /* waitcount2 */ -+#define FW_W2_SHIFT 16 -+#define FW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define FW_W3_SHIFT 24 -+ -+/* When Srom support present, fields in sromcontrol */ -+#define SRC_START 0x80000000 -+#define SRC_BUSY 0x80000000 -+#define SRC_OPCODE 0x60000000 -+#define SRC_OP_READ 0x00000000 -+#define SRC_OP_WRITE 0x20000000 -+#define SRC_OP_WRDIS 0x40000000 -+#define SRC_OP_WREN 0x60000000 -+#define SRC_OTPSEL 0x00000010 -+#define SRC_LOCK 0x00000008 -+#define SRC_SIZE_MASK 0x00000006 -+#define SRC_SIZE_1K 0x00000000 -+#define SRC_SIZE_4K 0x00000002 -+#define SRC_SIZE_16K 0x00000004 -+#define SRC_SIZE_SHIFT 1 -+#define SRC_PRESENT 0x00000001 -+ -+/* Fields in pmucontrol */ -+#define PCTL_ILP_DIV_MASK 0xffff0000 -+#define PCTL_ILP_DIV_SHIFT 16 -+#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ -+#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ -+#define PCTL_HT_REQ_EN 0x00000100 -+#define PCTL_ALP_REQ_EN 0x00000080 -+#define PCTL_XTALFREQ_MASK 0x0000007c -+#define PCTL_XTALFREQ_SHIFT 2 -+#define PCTL_ILP_DIV_EN 0x00000002 -+#define PCTL_LPO_SEL 0x00000001 -+ -+/* Fields in clkstretch */ -+#define CSTRETCH_HT 0xffff0000 -+#define CSTRETCH_ALP 0x0000ffff -+ -+/* gpiotimerval */ -+#define GPIO_ONTIME_SHIFT 16 -+ -+/* clockcontrol_n */ -+#define CN_N1_MASK 0x3f /* n1 control */ -+#define CN_N2_MASK 0x3f00 /* n2 control */ -+#define CN_N2_SHIFT 8 -+#define CN_PLLC_MASK 0xf0000 /* pll control */ -+#define CN_PLLC_SHIFT 16 -+ -+/* clockcontrol_sb/pci/uart */ -+#define CC_M1_MASK 0x3f /* m1 control */ -+#define CC_M2_MASK 0x3f00 /* m2 control */ -+#define CC_M2_SHIFT 8 -+#define CC_M3_MASK 0x3f0000 /* m3 control */ -+#define CC_M3_SHIFT 16 -+#define CC_MC_MASK 0x1f000000 /* mux control */ -+#define CC_MC_SHIFT 24 -+ -+/* N3M Clock control magic field values */ -+#define CC_F6_2 0x02 /* A factor of 2 in */ -+#define CC_F6_3 0x03 /* 6-bit fields like */ -+#define CC_F6_4 0x05 /* N1, M1 or M3 */ -+#define CC_F6_5 0x09 -+#define CC_F6_6 0x11 -+#define CC_F6_7 0x21 -+ -+#define CC_F5_BIAS 5 /* 5-bit fields get this added */ -+ -+#define CC_MC_BYPASS 0x08 -+#define CC_MC_M1 0x04 -+#define CC_MC_M1M2 0x02 -+#define CC_MC_M1M2M3 0x01 -+#define CC_MC_M1M3 0x11 -+ -+/* Type 2 Clock control magic field values */ -+#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ -+#define CC_T2M2_BIAS 3 /* m2 bias */ -+ -+#define CC_T2MC_M1BYP 1 -+#define CC_T2MC_M2BYP 2 -+#define CC_T2MC_M3BYP 4 -+ -+/* Type 6 Clock control magic field values */ -+#define CC_T6_MMASK 1 /* bits of interest in m */ -+#define CC_T6_M0 120000000 /* sb clock for m = 0 */ -+#define CC_T6_M1 100000000 /* sb clock for m = 1 */ -+#define SB2MIPS_T6(sb) (2 * (sb)) -+ -+/* Common clock base */ -+#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ -+#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */ -+ -+/* Clock control values for 200MHz in 5350 */ -+#define CLKC_5350_N 0x0311 -+#define CLKC_5350_M 0x04020009 -+ -+/* Flash types in the chipcommon capabilities register */ -+#define FLASH_NONE 0x000 /* No flash */ -+#define SFLASH_ST 0x100 /* ST serial flash */ -+#define SFLASH_AT 0x200 /* Atmel serial flash */ -+#define NFLASH 0x300 -+#define PFLASH 0x700 /* Parallel flash */ -+ -+/* Bits in the ExtBus config registers */ -+#define CC_CFG_EN 0x0001 /* Enable */ -+#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ -+#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */ -+#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */ -+#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */ -+#define CC_CFG_EM_IDE 0x0006 /* IDE */ -+#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ -+#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */ -+#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */ -+#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */ -+#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */ -+ -+/* ExtBus address space */ -+#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */ -+#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */ -+#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */ -+#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */ -+#define CC_EB_IDE 0x1a800000 /* IDE memory base */ -+#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */ -+#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */ -+#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */ -+#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */ -+ -+ -+/* Start/busy bit in flashcontrol */ -+#define SFLASH_OPCODE 0x000000ff -+#define SFLASH_ACTION 0x00000700 -+#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */ -+#define SFLASH_START 0x80000000 -+#define SFLASH_BUSY SFLASH_START -+ -+/* flashcontrol action codes */ -+#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */ -+#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */ -+#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */ -+#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */ -+#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */ -+#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */ -+#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */ -+ -+/* flashcontrol action+opcodes for ST flashes */ -+#define SFLASH_ST_WREN 0x0006 /* Write Enable */ -+#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ -+#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ -+#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ -+#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ -+#define SFLASH_ST_PP 0x0302 /* Page Program */ -+#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ -+#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ -+#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ -+#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ -+#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */ -+#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */ -+ -+#define SFLASH_MXIC_RDID 0x0390 /* Read Manufacture ID */ -+#define SFLASH_MXIC_MFID 0xc2 /* MXIC Manufacture ID */ -+ -+/* Status register bits for ST flashes */ -+#define SFLASH_ST_WIP 0x01 /* Write In Progress */ -+#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ -+#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ -+#define SFLASH_ST_BP_SHIFT 2 -+#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ -+ -+/* flashcontrol action+opcodes for Atmel flashes */ -+#define SFLASH_AT_READ 0x07e8 -+#define SFLASH_AT_PAGE_READ 0x07d2 -+#define SFLASH_AT_BUF1_READ -+#define SFLASH_AT_BUF2_READ -+#define SFLASH_AT_STATUS 0x01d7 -+#define SFLASH_AT_BUF1_WRITE 0x0384 -+#define SFLASH_AT_BUF2_WRITE 0x0387 -+#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -+#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -+#define SFLASH_AT_BUF1_PROGRAM 0x0288 -+#define SFLASH_AT_BUF2_PROGRAM 0x0289 -+#define SFLASH_AT_PAGE_ERASE 0x0281 -+#define SFLASH_AT_BLOCK_ERASE 0x0250 -+#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -+#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -+#define SFLASH_AT_BUF1_LOAD 0x0253 -+#define SFLASH_AT_BUF2_LOAD 0x0255 -+#define SFLASH_AT_BUF1_COMPARE 0x0260 -+#define SFLASH_AT_BUF2_COMPARE 0x0261 -+#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -+#define SFLASH_AT_BUF2_REPROGRAM 0x0259 -+ -+/* Status register bits for Atmel flashes */ -+#define SFLASH_AT_READY 0x80 -+#define SFLASH_AT_MISMATCH 0x40 -+#define SFLASH_AT_ID_MASK 0x38 -+#define SFLASH_AT_ID_SHIFT 3 -+ -+/* SPI register bits, corerev >= 37 */ -+#define GSIO_START 0x80000000 -+#define GSIO_BUSY GSIO_START -+ -+/* -+ * These are the UART port assignments, expressed as offsets from the base -+ * register. These assignments should hold for any serial port based on -+ * a 8250, 16450, or 16550(A). -+ */ -+ -+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ -+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ -+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ -+#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */ -+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ -+#define UART_IIR 2 /* In: Interrupt Identity Register */ -+#define UART_FCR 2 /* Out: FIFO Control Register */ -+#define UART_LCR 3 /* Out: Line Control Register */ -+#define UART_MCR 4 /* Out: Modem Control Register */ -+#define UART_LSR 5 /* In: Line Status Register */ -+#define UART_MSR 6 /* In: Modem Status Register */ -+#define UART_SCR 7 /* I/O: Scratch Register */ -+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -+#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */ -+#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */ -+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -+#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */ -+#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */ -+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ -+#define UART_LSR_BREAK 0x10 /* Break interrupt */ -+#define UART_LSR_FRAMING 0x08 /* Framing error */ -+#define UART_LSR_PARITY 0x04 /* Parity error */ -+#define UART_LSR_OVERRUN 0x02 /* Overrun error */ -+#define UART_LSR_RXRDY 0x01 /* Receiver ready */ -+#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */ -+ -+/* Interrupt Identity Register (IIR) bits */ -+#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */ -+#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */ -+#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */ -+#define UART_IIR_NOINT 0x1 /* No interrupt pending */ -+#define UART_IIR_THRE 0x2 /* THR empty */ -+#define UART_IIR_RCVD_DATA 0x4 /* Received data available */ -+#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */ -+#define UART_IIR_CHAR_TIME 0xc /* Character time */ -+ -+/* Interrupt Enable Register (IER) bits */ -+#define UART_IER_EDSSI 8 /* enable modem status interrupt */ -+#define UART_IER_ELSI 4 /* enable receiver line status interrupt */ -+#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */ -+#define UART_IER_ERBFI 1 /* enable data available interrupt */ -+ -+/* pmustatus */ -+#define PST_EXTLPOAVAIL 0x0100 -+#define PST_WDRESET 0x0080 -+#define PST_INTPEND 0x0040 -+#define PST_SBCLKST 0x0030 -+#define PST_SBCLKST_ILP 0x0010 -+#define PST_SBCLKST_ALP 0x0020 -+#define PST_SBCLKST_HT 0x0030 -+#define PST_ALPAVAIL 0x0008 -+#define PST_HTAVAIL 0x0004 -+#define PST_RESINIT 0x0003 -+ -+/* pmucapabilities */ -+#define PCAP_REV_MASK 0x000000ff -+#define PCAP_RC_MASK 0x00001f00 -+#define PCAP_RC_SHIFT 8 -+#define PCAP_TC_MASK 0x0001e000 -+#define PCAP_TC_SHIFT 13 -+#define PCAP_PC_MASK 0x001e0000 -+#define PCAP_PC_SHIFT 17 -+#define PCAP_VC_MASK 0x01e00000 -+#define PCAP_VC_SHIFT 21 -+#define PCAP_CC_MASK 0x1e000000 -+#define PCAP_CC_SHIFT 25 -+#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */ -+#define PCAP5_PC_SHIFT 17 -+#define PCAP5_VC_MASK 0x07c00000 -+#define PCAP5_VC_SHIFT 22 -+#define PCAP5_CC_MASK 0xf8000000 -+#define PCAP5_CC_SHIFT 27 -+ -+/* PMU Resource Request Timer registers */ -+/* This is based on PmuRev0 */ -+#define PRRT_TIME_MASK 0x03ff -+#define PRRT_INTEN 0x0400 -+#define PRRT_REQ_ACTIVE 0x0800 -+#define PRRT_ALP_REQ 0x1000 -+#define PRRT_HT_REQ 0x2000 -+#define PRRT_HQ_REQ 0x4000 -+ -+/* PMU resource bit position */ -+#define PMURES_BIT(bit) (1 << (bit)) -+ -+/* PMU resource number limit */ -+#define PMURES_MAX_RESNUM 30 -+ -+/* PMU chip control0 register */ -+#define PMU_CHIPCTL0 0 -+ -+/* clock req types */ -+#define PMU_CC1_CLKREQ_TYPE_SHIFT 19 -+#define PMU_CC1_CLKREQ_TYPE_MASK (1 << PMU_CC1_CLKREQ_TYPE_SHIFT) -+ -+#define CLKREQ_TYPE_CONFIG_OPENDRAIN 0 -+#define CLKREQ_TYPE_CONFIG_PUSHPULL 1 -+ -+/* PMU chip control1 register */ -+#define PMU_CHIPCTL1 1 -+#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 -+ -+#define PMU_CC1_IF_TYPE_MASK 0x00000030 -+#define PMU_CC1_IF_TYPE_RMII 0x00000000 -+#define PMU_CC1_IF_TYPE_MII 0x00000010 -+#define PMU_CC1_IF_TYPE_RGMII 0x00000020 -+ -+#define PMU_CC1_SW_TYPE_MASK 0x000000c0 -+#define PMU_CC1_SW_TYPE_EPHY 0x00000000 -+#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 -+#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 -+#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 -+ -+/* PMU chip control2 register */ -+#define PMU_CHIPCTL2 2 -+ -+/* PMU chip control3 register */ -+#define PMU_CHIPCTL3 3 -+ -+#define PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT 19 -+#define PMU_CC3_ENABLE_RF_SHIFT 22 -+#define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23 -+ -+ -+/* PMU corerev and chip specific PLL controls. -+ * PMU_PLL_XX where is PMU corerev and is an arbitrary number -+ * to differentiate different PLLs controlled by the same PMU rev. -+ */ -+/* pllcontrol registers */ -+/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */ -+#define PMU0_PLL0_PLLCTL0 0 -+#define PMU0_PLL0_PC0_PDIV_MASK 1 -+#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -+#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -+#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -+#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 -+ -+/* PC0_DIV_ARM for PLLOUT_ARM */ -+#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -+#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -+#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -+#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */ -+#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -+#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -+#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -+#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 -+ -+/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */ -+#define PMU0_PLL0_PLLCTL1 1 -+#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -+#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -+#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -+#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -+#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 -+ -+/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */ -+#define PMU0_PLL0_PLLCTL2 2 -+#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -+#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 -+ -+/* pllcontrol registers */ -+/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -+#define PMU1_PLL0_PLLCTL0 0 -+#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 -+#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 -+#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 -+#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 -+ -+/* mdiv */ -+#define PMU1_PLL0_PLLCTL1 1 -+#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff -+#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 -+#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 -+#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 -+#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 -+#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 -+#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 -+#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 -+#define PMU1_PLL0_PC1_M4DIV_BY_9 9 -+#define PMU1_PLL0_PC1_M4DIV_BY_18 0x12 -+#define PMU1_PLL0_PC1_M4DIV_BY_36 0x24 -+ -+#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -+#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -+#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -+ -+/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -+#define PMU1_PLL0_PLLCTL2 2 -+#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff -+#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 -+#define PMU1_PLL0_PC2_M5DIV_BY_12 0xc -+#define PMU1_PLL0_PC2_M5DIV_BY_18 0x12 -+#define PMU1_PLL0_PC2_M5DIV_BY_36 0x24 -+#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 -+#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 -+#define PMU1_PLL0_PC2_M6DIV_BY_18 0x12 -+#define PMU1_PLL0_PC2_M6DIV_BY_36 0x24 -+#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 -+#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 -+#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 -+#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */ -+#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 -+#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 -+ -+/* ndiv_frac */ -+#define PMU1_PLL0_PLLCTL3 3 -+#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff -+#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 -+ -+/* pll_ctrl */ -+#define PMU1_PLL0_PLLCTL4 4 -+ -+/* pll_ctrl, vco_rng, clkdrive_ch */ -+#define PMU1_PLL0_PLLCTL5 5 -+#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 -+#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 -+ -+/* PMU rev 2 control words */ -+#define PMU2_PHY_PLL_PLLCTL 4 -+#define PMU2_SI_PLL_PLLCTL 10 -+ -+/* PMU rev 2 */ -+/* pllcontrol registers */ -+/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -+#define PMU2_PLL_PLLCTL0 0 -+#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 -+#define PMU2_PLL_PC0_P1DIV_SHIFT 20 -+#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 -+#define PMU2_PLL_PC0_P2DIV_SHIFT 24 -+ -+/* mdiv */ -+#define PMU2_PLL_PLLCTL1 1 -+#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff -+#define PMU2_PLL_PC1_M1DIV_SHIFT 0 -+#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 -+#define PMU2_PLL_PC1_M2DIV_SHIFT 8 -+#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 -+#define PMU2_PLL_PC1_M3DIV_SHIFT 16 -+#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 -+#define PMU2_PLL_PC1_M4DIV_SHIFT 24 -+ -+/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -+#define PMU2_PLL_PLLCTL2 2 -+#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff -+#define PMU2_PLL_PC2_M5DIV_SHIFT 0 -+#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 -+#define PMU2_PLL_PC2_M6DIV_SHIFT 8 -+#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 -+#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 -+#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 -+#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 -+ -+/* ndiv_frac */ -+#define PMU2_PLL_PLLCTL3 3 -+#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff -+#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 -+ -+/* pll_ctrl */ -+#define PMU2_PLL_PLLCTL4 4 -+ -+/* pll_ctrl, vco_rng, clkdrive_ch */ -+#define PMU2_PLL_PLLCTL5 5 -+#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 -+#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 -+#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 -+#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 -+#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 -+#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 -+#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 -+ -+/* PMU rev 5 (& 6) */ -+#define PMU5_PLL_P1P2_OFF 0 -+#define PMU5_PLL_P1_MASK 0x0f000000 -+#define PMU5_PLL_P1_SHIFT 24 -+#define PMU5_PLL_P2_MASK 0x00f00000 -+#define PMU5_PLL_P2_SHIFT 20 -+#define PMU5_PLL_M14_OFF 1 -+#define PMU5_PLL_MDIV_MASK 0x000000ff -+#define PMU5_PLL_MDIV_WIDTH 8 -+#define PMU5_PLL_NM5_OFF 2 -+#define PMU5_PLL_NDIV_MASK 0xfff00000 -+#define PMU5_PLL_NDIV_SHIFT 20 -+#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 -+#define PMU5_PLL_NDIV_MODE_SHIFT 17 -+#define PMU5_PLL_FMAB_OFF 3 -+#define PMU5_PLL_MRAT_MASK 0xf0000000 -+#define PMU5_PLL_MRAT_SHIFT 28 -+#define PMU5_PLL_ABRAT_MASK 0x08000000 -+#define PMU5_PLL_ABRAT_SHIFT 27 -+#define PMU5_PLL_FDIV_MASK 0x07ffffff -+#define PMU5_PLL_PLLCTL_OFF 4 -+#define PMU5_PLL_PCHI_OFF 5 -+#define PMU5_PLL_PCHI_MASK 0x0000003f -+ -+/* pmu XtalFreqRatio */ -+#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF -+#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 -+#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 -+ -+/* Divider allocation in 4716/47162/5356/5357 */ -+#define PMU5_MAINPLL_CPU 1 -+#define PMU5_MAINPLL_MEM 2 -+#define PMU5_MAINPLL_SI 3 -+ -+/* 4706 PMU */ -+#define PMU4706_MAINPLL_PLL0 0 -+#define PMU6_4706_PROCPLL_OFF 4 /* The CPU PLL */ -+#define PMU6_4706_PROC_P2DIV_MASK 0x000f0000 -+#define PMU6_4706_PROC_P2DIV_SHIFT 16 -+#define PMU6_4706_PROC_P1DIV_MASK 0x0000f000 -+#define PMU6_4706_PROC_P1DIV_SHIFT 12 -+#define PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8 -+#define PMU6_4706_PROC_NDIV_INT_SHIFT 3 -+#define PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 -+#define PMU6_4706_PROC_NDIV_MODE_SHIFT 0 -+ -+#define PMU7_PLL_PLLCTL7 7 -+#define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000 -+#define PMU7_PLL_CTL7_M4DIV_SHIFT 24 -+#define PMU7_PLL_CTL7_M4DIV_BY_6 6 -+#define PMU7_PLL_CTL7_M4DIV_BY_12 0xc -+#define PMU7_PLL_CTL7_M4DIV_BY_24 0x18 -+#define PMU7_PLL_PLLCTL8 8 -+#define PMU7_PLL_CTL8_M5DIV_MASK 0x000000ff -+#define PMU7_PLL_CTL8_M5DIV_SHIFT 0 -+#define PMU7_PLL_CTL8_M5DIV_BY_8 8 -+#define PMU7_PLL_CTL8_M5DIV_BY_12 0xc -+#define PMU7_PLL_CTL8_M5DIV_BY_24 0x18 -+#define PMU7_PLL_CTL8_M6DIV_MASK 0x0000ff00 -+#define PMU7_PLL_CTL8_M6DIV_SHIFT 8 -+#define PMU7_PLL_CTL8_M6DIV_BY_12 0xc -+#define PMU7_PLL_CTL8_M6DIV_BY_24 0x18 -+#define PMU7_PLL_PLLCTL11 11 -+#define PMU7_PLL_PLLCTL11_MASK 0xffffff00 -+#define PMU7_PLL_PLLCTL11_VAL 0x22222200 -+ -+/* PMU rev 15 */ -+#define PMU15_PLL_PLLCTL0 0 -+#define PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 -+#define PMU15_PLL_PC0_CLKSEL_SHIFT 0 -+#define PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC -+#define PMU15_PLL_PC0_FREQTGT_SHIFT 2 -+#define PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 -+#define PMU15_PLL_PC0_PRESCALE_SHIFT 22 -+#define PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 -+#define PMU15_PLL_PC0_KPCTRL_SHIFT 24 -+#define PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 -+#define PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 -+#define PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 -+#define PMU15_PLL_PC0_FDCMODE_SHIFT 30 -+#define PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 -+#define PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 -+ -+#define PMU15_PLL_PLLCTL1 1 -+#define PMU15_PLL_PC1_BIAS_CTLM_MASK 0x00000060 -+#define PMU15_PLL_PC1_BIAS_CTLM_SHIFT 5 -+#define PMU15_PLL_PC1_BIAS_CTLM_RST_MASK 0x00000040 -+#define PMU15_PLL_PC1_BIAS_CTLM_RST_SHIFT 6 -+#define PMU15_PLL_PC1_BIAS_SS_DIVR_MASK 0x0001FF80 -+#define PMU15_PLL_PC1_BIAS_SS_DIVR_SHIFT 7 -+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_MASK 0x03FE0000 -+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_SHIFT 17 -+#define PMU15_PLL_PC1_BIAS_INTG_BW_MASK 0x0C000000 -+#define PMU15_PLL_PC1_BIAS_INTG_BW_SHIFT 26 -+#define PMU15_PLL_PC1_BIAS_INTG_BYP_MASK 0x10000000 -+#define PMU15_PLL_PC1_BIAS_INTG_BYP_SHIFT 28 -+#define PMU15_PLL_PC1_OPENLP_EN_MASK 0x40000000 -+#define PMU15_PLL_PC1_OPENLP_EN_SHIFT 30 -+ -+#define PMU15_PLL_PLLCTL2 2 -+#define PMU15_PLL_PC2_CTEN_MASK 0x00000001 -+#define PMU15_PLL_PC2_CTEN_SHIFT 0 -+ -+#define PMU15_PLL_PLLCTL3 3 -+#define PMU15_PLL_PC3_DITHER_EN_MASK 0x00000001 -+#define PMU15_PLL_PC3_DITHER_EN_SHIFT 0 -+#define PMU15_PLL_PC3_DCOCTLSP_MASK 0xFE000000 -+#define PMU15_PLL_PC3_DCOCTLSP_SHIFT 25 -+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_MASK 0x01 -+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_SHIFT 0 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_MASK 0x02 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_SHIFT 1 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_MASK 0x04 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_SHIFT 2 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_MASK 0x18 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_SHIFT 3 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_MASK 0x60 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_SHIFT 5 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV1 0 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV2 1 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV3 2 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV5 3 -+ -+#define PMU15_PLL_PLLCTL4 4 -+#define PMU15_PLL_PC4_FLLCLK1_DIV_MASK 0x00000007 -+#define PMU15_PLL_PC4_FLLCLK1_DIV_SHIFT 0 -+#define PMU15_PLL_PC4_FLLCLK2_DIV_MASK 0x00000038 -+#define PMU15_PLL_PC4_FLLCLK2_DIV_SHIFT 3 -+#define PMU15_PLL_PC4_FLLCLK3_DIV_MASK 0x000001C0 -+#define PMU15_PLL_PC4_FLLCLK3_DIV_SHIFT 6 -+#define PMU15_PLL_PC4_DBGMODE_MASK 0x00000E00 -+#define PMU15_PLL_PC4_DBGMODE_SHIFT 9 -+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_MASK 0x00001000 -+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_SHIFT 12 -+#define PMU15_PLL_PC4_FLL480_CTLSP_MASK 0x000FE000 -+#define PMU15_PLL_PC4_FLL480_CTLSP_SHIFT 13 -+#define PMU15_PLL_PC4_DINPOL_MASK 0x00100000 -+#define PMU15_PLL_PC4_DINPOL_SHIFT 20 -+#define PMU15_PLL_PC4_CLKOUT_PD_MASK 0x00200000 -+#define PMU15_PLL_PC4_CLKOUT_PD_SHIFT 21 -+#define PMU15_PLL_PC4_CLKDIV2_PD_MASK 0x00400000 -+#define PMU15_PLL_PC4_CLKDIV2_PD_SHIFT 22 -+#define PMU15_PLL_PC4_CLKDIV4_PD_MASK 0x00800000 -+#define PMU15_PLL_PC4_CLKDIV4_PD_SHIFT 23 -+#define PMU15_PLL_PC4_CLKDIV8_PD_MASK 0x01000000 -+#define PMU15_PLL_PC4_CLKDIV8_PD_SHIFT 24 -+#define PMU15_PLL_PC4_CLKDIV16_PD_MASK 0x02000000 -+#define PMU15_PLL_PC4_CLKDIV16_PD_SHIFT 25 -+#define PMU15_PLL_PC4_TEST_EN_MASK 0x04000000 -+#define PMU15_PLL_PC4_TEST_EN_SHIFT 26 -+ -+#define PMU15_PLL_PLLCTL5 5 -+#define PMU15_PLL_PC5_FREQTGT_MASK 0x000FFFFF -+#define PMU15_PLL_PC5_FREQTGT_SHIFT 0 -+#define PMU15_PLL_PC5_DCOCTLSP_MASK 0x07F00000 -+#define PMU15_PLL_PC5_DCOCTLSP_SHIFT 20 -+#define PMU15_PLL_PC5_PRESCALE_MASK 0x18000000 -+#define PMU15_PLL_PC5_PRESCALE_SHIFT 27 -+ -+#define PMU15_PLL_PLLCTL6 6 -+#define PMU15_PLL_PC6_FREQTGT_MASK 0x000FFFFF -+#define PMU15_PLL_PC6_FREQTGT_SHIFT 0 -+#define PMU15_PLL_PC6_DCOCTLSP_MASK 0x07F00000 -+#define PMU15_PLL_PC6_DCOCTLSP_SHIFT 20 -+#define PMU15_PLL_PC6_PRESCALE_MASK 0x18000000 -+#define PMU15_PLL_PC6_PRESCALE_SHIFT 27 -+ -+#define PMU15_FREQTGT_480_DEFAULT 0x19AB1 -+#define PMU15_FREQTGT_492_DEFAULT 0x1A4F5 -+#define PMU15_ARM_96MHZ 96000000 /* 96 Mhz */ -+#define PMU15_ARM_98MHZ 98400000 /* 98.4 Mhz */ -+#define PMU15_ARM_97MHZ 97000000 /* 97 Mhz */ -+ -+ -+#define PMU17_PLLCTL2_NDIVTYPE_MASK 0x00000070 -+#define PMU17_PLLCTL2_NDIVTYPE_SHIFT 4 -+ -+#define PMU17_PLLCTL2_NDIV_MODE_INT 0 -+#define PMU17_PLLCTL2_NDIV_MODE_INT1B8 1 -+#define PMU17_PLLCTL2_NDIV_MODE_MASH111 2 -+#define PMU17_PLLCTL2_NDIV_MODE_MASH111B8 3 -+ -+#define PMU17_PLLCTL0_BBPLL_PWRDWN 0 -+#define PMU17_PLLCTL0_BBPLL_DRST 3 -+#define PMU17_PLLCTL0_BBPLL_DISBL_CLK 8 -+ -+/* PLL usage in 4716/47162 */ -+#define PMU4716_MAINPLL_PLL0 12 -+ -+/* PLL usage in 5356/5357 */ -+#define PMU5356_MAINPLL_PLL0 0 -+#define PMU5357_MAINPLL_PLL0 0 -+ -+/* 4716/47162 resources */ -+#define RES4716_PROC_PLL_ON 0x00000040 -+#define RES4716_PROC_HT_AVAIL 0x00000080 -+ -+/* 4716/4717/4718 Chip specific ChipControl register bits */ -+#define CCTRL_471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared w/ pflash */ -+ -+/* 5357 Chip specific ChipControl register bits */ -+/* 2nd - 32-bit reg */ -+#define CCTRL_5357_I2S_PINS_ENABLE 0x00040000 /* I2S pins enable */ -+#define CCTRL_5357_I2CSPI_PINS_ENABLE 0x00080000 /* I2C/SPI pins enable */ -+ -+/* 5354 resources */ -+#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */ -+#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */ -+#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */ -+#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -+#define RES5354_ILP_REQUEST 4 /* 0x00010 */ -+#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -+#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -+#define RES5354_ROM_SWITCH 7 /* 0x00080 */ -+#define RES5354_PA_REF_LDO 8 /* 0x00100 */ -+#define RES5354_RADIO_LDO 9 /* 0x00200 */ -+#define RES5354_AFE_LDO 10 /* 0x00400 */ -+#define RES5354_PLL_LDO 11 /* 0x00800 */ -+#define RES5354_BG_FILTBYP 12 /* 0x01000 */ -+#define RES5354_TX_FILTBYP 13 /* 0x02000 */ -+#define RES5354_RX_FILTBYP 14 /* 0x04000 */ -+#define RES5354_XTAL_PU 15 /* 0x08000 */ -+#define RES5354_XTAL_EN 16 /* 0x10000 */ -+#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */ -+#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */ -+#define RES5354_BB_PLL_PU 19 /* 0x80000 */ -+ -+/* 5357 Chip specific ChipControl register bits */ -+#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ -+#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ -+#define CCTRL5357_NFLASH (1<<16) /* Nandflash in ChipControl 1, bit 16 */ -+ -+/* 43217 Chip specific ChipControl register bits */ -+#define CCTRL43217_EXTPA_C0 (1<<13) /* core0 extPA in ChipControl 1, bit 13 */ -+#define CCTRL43217_EXTPA_C1 (1<<8) /* core1 extPA in ChipControl 1, bit 8 */ -+ -+/* 4328 resources */ -+#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ -+#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ -+#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */ -+#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -+#define RES4328_ILP_REQUEST 4 /* 0x00010 */ -+#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -+#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -+#define RES4328_ROM_SWITCH 7 /* 0x00080 */ -+#define RES4328_PA_REF_LDO 8 /* 0x00100 */ -+#define RES4328_RADIO_LDO 9 /* 0x00200 */ -+#define RES4328_AFE_LDO 10 /* 0x00400 */ -+#define RES4328_PLL_LDO 11 /* 0x00800 */ -+#define RES4328_BG_FILTBYP 12 /* 0x01000 */ -+#define RES4328_TX_FILTBYP 13 /* 0x02000 */ -+#define RES4328_RX_FILTBYP 14 /* 0x04000 */ -+#define RES4328_XTAL_PU 15 /* 0x08000 */ -+#define RES4328_XTAL_EN 16 /* 0x10000 */ -+#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */ -+#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */ -+#define RES4328_BB_PLL_PU 19 /* 0x80000 */ -+ -+/* 4325 A0/A1 resources */ -+#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */ -+#define RES4325_CBUCK_BURST 1 /* 0x00000002 */ -+#define RES4325_CBUCK_PWM 2 /* 0x00000004 */ -+#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */ -+#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */ -+#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */ -+#define RES4325_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4325_ABUCK_BURST 7 /* 0x00000080 */ -+#define RES4325_ABUCK_PWM 8 /* 0x00000100 */ -+#define RES4325_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4325_OTP_PU 10 /* 0x00000400 */ -+#define RES4325_LNLDO3_PU 11 /* 0x00000800 */ -+#define RES4325_LNLDO4_PU 12 /* 0x00001000 */ -+#define RES4325_XTAL_PU 13 /* 0x00002000 */ -+#define RES4325_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4325_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4325 B0/C0 resources */ -+#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4325B0_CLDO_PU 4 /* 0x00000010 */ -+ -+/* 4325 C1 resources */ -+#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */ -+ -+/* 4325 chip-specific ChipStatus register bits */ -+#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -+#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -+#define CST4325_SDIO_USB_MODE_SHIFT 2 -+#define CST4325_RCAL_VALID_MASK 0x00000008 -+#define CST4325_RCAL_VALID_SHIFT 3 -+#define CST4325_RCAL_VALUE_MASK 0x000001f0 -+#define CST4325_RCAL_VALUE_SHIFT 4 -+#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */ -+#define CST4325_PMUTOP_2B_SHIFT 9 -+ -+#define RES4329_RESERVED0 0 /* 0x00000001 */ -+#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4329_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4329_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4329_CLDO_PU 4 /* 0x00000010 */ -+#define RES4329_PALDO_PU 5 /* 0x00000020 */ -+#define RES4329_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4329_RESERVED7 7 /* 0x00000080 */ -+#define RES4329_RESERVED8 8 /* 0x00000100 */ -+#define RES4329_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4329_OTP_PU 10 /* 0x00000400 */ -+#define RES4329_RESERVED11 11 /* 0x00000800 */ -+#define RES4329_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4329_XTAL_PU 13 /* 0x00002000 */ -+#define RES4329_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4329_HT_AVAIL 21 /* 0x00200000 */ -+ -+#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -+#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -+#define CST4329_SPI_SDIO_MODE_SHIFT 2 -+ -+/* 4312 chip-specific ChipStatus register bits */ -+#define CST4312_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */ -+ -+/* 4312 resources (all PMU chips with little memory constraint) */ -+#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */ -+#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */ -+#define RES4312_PA_REF_LDO 2 /* 0x00000004 */ -+#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */ -+#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */ -+#define RES4312_RADIO_LDO 5 /* 0x00000020 */ -+#define RES4312_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4312_BG_FILTBYP 7 /* 0x00000080 */ -+#define RES4312_TX_FILTBYP 8 /* 0x00000100 */ -+#define RES4312_RX_FILTBYP 9 /* 0x00000200 */ -+#define RES4312_XTAL_PU 10 /* 0x00000400 */ -+#define RES4312_ALP_AVAIL 11 /* 0x00000800 */ -+#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */ -+#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */ -+#define RES4312_HT_AVAIL 14 /* 0x00004000 */ -+ -+/* 4322 resources */ -+#define RES4322_RF_LDO 0 -+#define RES4322_ILP_REQUEST 1 -+#define RES4322_XTAL_PU 2 -+#define RES4322_ALP_AVAIL 3 -+#define RES4322_SI_PLL_ON 4 -+#define RES4322_HT_SI_AVAIL 5 -+#define RES4322_PHY_PLL_ON 6 -+#define RES4322_HT_PHY_AVAIL 7 -+#define RES4322_OTP_PU 8 -+ -+/* 4322 chip-specific ChipStatus register bits */ -+#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -+#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -+#define CST4322_SPROM_OTP_SEL_SHIFT 6 -+#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */ -+#define CST4322_SPROM_PRESENT 1 /* SPROM is present */ -+#define CST4322_OTP_PRESENT 2 /* OTP is present */ -+#define CST4322_PCI_OR_USB 0x00000100 -+#define CST4322_BOOT_MASK 0x00000600 -+#define CST4322_BOOT_SHIFT 9 -+#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST4322_BOOT_FROM_INVALID 3 -+#define CST4322_ILP_DIV_EN 0x00000800 -+#define CST4322_FLASH_TYPE_MASK 0x00001000 -+#define CST4322_FLASH_TYPE_SHIFT 12 -+#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */ -+#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */ -+#define CST4322_ARM_TAP_SEL 0x00002000 -+#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -+#define CST4322_RES_INIT_MODE_SHIFT 14 -+#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */ -+#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */ -+#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */ -+#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */ -+#define CST4322_PCIPLLCLK_GATING 0x00010000 -+#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -+#define CST4322_PCI_CARDBUS_MODE 0x00040000 -+ -+/* 43224 chip-specific ChipControl register bits */ -+#define CCTRL43224_GPIO_TOGGLE 0x8000 /* gpio[3:0] pins as btcoex or s/w gpio */ -+#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ -+#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ -+ -+/* 43236 resources */ -+#define RES43236_REGULATOR 0 -+#define RES43236_ILP_REQUEST 1 -+#define RES43236_XTAL_PU 2 -+#define RES43236_ALP_AVAIL 3 -+#define RES43236_SI_PLL_ON 4 -+#define RES43236_HT_SI_AVAIL 5 -+ -+/* 43236 chip-specific ChipControl register bits */ -+#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */ -+#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ -+#define CCTRL43236_GSIO (1<<4) /* 0 disable */ -+ -+/* 43236 Chip specific ChipStatus register bits */ -+#define CST43236_SFLASH_MASK 0x00000040 -+#define CST43236_OTP_SEL_MASK 0x00000080 -+#define CST43236_OTP_SEL_SHIFT 7 -+#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ -+#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ -+#define CST43236_BOOT_MASK 0x00001800 -+#define CST43236_BOOT_SHIFT 11 -+#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST43236_BOOT_FROM_INVALID 3 -+ -+/* 43237 resources */ -+#define RES43237_REGULATOR 0 -+#define RES43237_ILP_REQUEST 1 -+#define RES43237_XTAL_PU 2 -+#define RES43237_ALP_AVAIL 3 -+#define RES43237_SI_PLL_ON 4 -+#define RES43237_HT_SI_AVAIL 5 -+ -+/* 43237 chip-specific ChipControl register bits */ -+#define CCTRL43237_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL43237_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL43237_EXT_LNA (1<<2) /* 0 disable */ -+#define CCTRL43237_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ -+#define CCTRL43237_GSIO (1<<4) /* 0 disable */ -+ -+/* 43237 Chip specific ChipStatus register bits */ -+#define CST43237_SFLASH_MASK 0x00000040 -+#define CST43237_OTP_SEL_MASK 0x00000080 -+#define CST43237_OTP_SEL_SHIFT 7 -+#define CST43237_HSIC_MASK 0x00000100 /* USB/HSIC */ -+#define CST43237_BP_CLK 0x00000200 /* 120/96Mbps */ -+#define CST43237_BOOT_MASK 0x00001800 -+#define CST43237_BOOT_SHIFT 11 -+#define CST43237_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST43237_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST43237_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST43237_BOOT_FROM_INVALID 3 -+ -+/* 43239 resources */ -+#define RES43239_OTP_PU 9 -+#define RES43239_MACPHY_CLKAVAIL 23 -+#define RES43239_HT_AVAIL 24 -+ -+/* 43239 Chip specific ChipStatus register bits */ -+#define CST43239_SPROM_MASK 0x00000002 -+#define CST43239_SFLASH_MASK 0x00000004 -+#define CST43239_RES_INIT_MODE_SHIFT 7 -+#define CST43239_RES_INIT_MODE_MASK 0x000001f0 -+#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15)) /* SDIO || gSPI */ -+#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15)) /* USB || USBDA */ -+#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0) /* SDIO */ -+#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) /* gSPI */ -+ -+/* 4324 resources */ -+#define RES4324_OTP_PU 10 -+#define RES4324_HT_AVAIL 29 -+#define RES4324_MACPHY_CLKAVAIL 30 -+ -+/* 4324 Chip specific ChipStatus register bits */ -+#define CST4324_SPROM_MASK 0x00000080 -+#define CST4324_SFLASH_MASK 0x00400000 -+#define CST4324_RES_INIT_MODE_SHIFT 10 -+#define CST4324_RES_INIT_MODE_MASK 0x00000c00 -+#define CST4324_CHIPMODE_MASK 0x7 -+#define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) /* SDIO || gSPI */ -+#define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) /* USB || USBDA */ -+ -+/* 4331 resources */ -+#define RES4331_REGULATOR 0 -+#define RES4331_ILP_REQUEST 1 -+#define RES4331_XTAL_PU 2 -+#define RES4331_ALP_AVAIL 3 -+#define RES4331_SI_PLL_ON 4 -+#define RES4331_HT_SI_AVAIL 5 -+ -+/* 4331 chip-specific ChipControl register bits */ -+#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL4331_EXT_LNA_G (1<<2) /* 0 disable */ -+#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ -+#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ -+#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ -+#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ -+#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ -+#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ -+#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ -+#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ -+#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ -+#define CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa disable, 1 ext pa enabled */ -+#define CCTRL4331_EXT_LNA_A (1<<13) /* 0 disable */ -+#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ -+#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ -+#define CCTRL4331_EXTPA_ANA_EN (1<<24) /* 0 ext pa disable, 1 ext pa enabled */ -+ -+/* 4331 Chip specific ChipStatus register bits */ -+#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ -+#define CST4331_SPROM_OTP_SEL_MASK 0x00000006 -+#define CST4331_SPROM_OTP_SEL_SHIFT 1 -+#define CST4331_SPROM_PRESENT 0x00000002 -+#define CST4331_OTP_PRESENT 0x00000004 -+#define CST4331_LDO_RF 0x00000008 -+#define CST4331_LDO_PAR 0x00000010 -+ -+/* 4315 resource */ -+#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4315_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4315_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4315_CLDO_PU 4 /* 0x00000010 */ -+#define RES4315_PALDO_PU 5 /* 0x00000020 */ -+#define RES4315_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4315_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4315_OTP_PU 10 /* 0x00000400 */ -+#define RES4315_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4315_XTAL_PU 13 /* 0x00002000 */ -+#define RES4315_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4315_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4315 chip-specific ChipStatus register bits */ -+#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */ -+#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -+#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */ -+#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */ -+#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */ -+#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */ -+#define CST4315_RCAL_VALID 0x00000008 -+#define CST4315_RCAL_VALUE_MASK 0x000001f0 -+#define CST4315_RCAL_VALUE_SHIFT 4 -+#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */ -+#define CST4315_CBUCK_MODE_MASK 0x00000c00 -+#define CST4315_CBUCK_MODE_BURST 0x00000400 -+#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 -+ -+/* 4319 resources */ -+#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4319_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4319_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4319_CLDO_PU 4 /* 0x00000010 */ -+#define RES4319_PALDO_PU 5 /* 0x00000020 */ -+#define RES4319_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4319_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4319_OTP_PU 10 /* 0x00000400 */ -+#define RES4319_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4319_XTAL_PU 13 /* 0x00002000 */ -+#define RES4319_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4319_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4319 chip-specific ChipStatus register bits */ -+#define CST4319_SPI_CPULESSUSB 0x00000001 -+#define CST4319_SPI_CLK_POL 0x00000002 -+#define CST4319_SPI_CLK_PH 0x00000008 -+#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ -+#define CST4319_SPROM_OTP_SEL_SHIFT 6 -+#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -+#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ -+#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ -+#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ -+#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ -+#define CST4319_REMAP_SEL_MASK 0x00000600 -+#define CST4319_ILPDIV_EN 0x00000800 -+#define CST4319_XTAL_PD_POL 0x00001000 -+#define CST4319_LPO_SEL 0x00002000 -+#define CST4319_RES_INIT_MODE 0x0000c000 -+#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ -+#define CST4319_CBUCK_MODE_MASK 0x00060000 -+#define CST4319_CBUCK_MODE_BURST 0x00020000 -+#define CST4319_CBUCK_MODE_LPBURST 0x00060000 -+#define CST4319_RCAL_VALID 0x01000000 -+#define CST4319_RCAL_VALUE_MASK 0x3e000000 -+#define CST4319_RCAL_VALUE_SHIFT 25 -+ -+#define PMU1_PLL0_CHIPCTL0 0 -+#define PMU1_PLL0_CHIPCTL1 1 -+#define PMU1_PLL0_CHIPCTL2 2 -+#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 -+#define CCTL_4319USB_XTAL_SEL_SHIFT 19 -+#define CCTL_4319USB_48MHZ_PLL_SEL 1 -+#define CCTL_4319USB_24MHZ_PLL_SEL 2 -+ -+/* PMU resources for 4336 */ -+#define RES4336_CBUCK_LPOM 0 -+#define RES4336_CBUCK_BURST 1 -+#define RES4336_CBUCK_LP_PWM 2 -+#define RES4336_CBUCK_PWM 3 -+#define RES4336_CLDO_PU 4 -+#define RES4336_DIS_INT_RESET_PD 5 -+#define RES4336_ILP_REQUEST 6 -+#define RES4336_LNLDO_PU 7 -+#define RES4336_LDO3P3_PU 8 -+#define RES4336_OTP_PU 9 -+#define RES4336_XTAL_PU 10 -+#define RES4336_ALP_AVAIL 11 -+#define RES4336_RADIO_PU 12 -+#define RES4336_BG_PU 13 -+#define RES4336_VREG1p4_PU_PU 14 -+#define RES4336_AFE_PWRSW_PU 15 -+#define RES4336_RX_PWRSW_PU 16 -+#define RES4336_TX_PWRSW_PU 17 -+#define RES4336_BB_PWRSW_PU 18 -+#define RES4336_SYNTH_PWRSW_PU 19 -+#define RES4336_MISC_PWRSW_PU 20 -+#define RES4336_LOGEN_PWRSW_PU 21 -+#define RES4336_BBPLL_PWRSW_PU 22 -+#define RES4336_MACPHY_CLKAVAIL 23 -+#define RES4336_HT_AVAIL 24 -+#define RES4336_RSVD 25 -+ -+/* 4336 chip-specific ChipStatus register bits */ -+#define CST4336_SPI_MODE_MASK 0x00000001 -+#define CST4336_SPROM_PRESENT 0x00000002 -+#define CST4336_OTP_PRESENT 0x00000004 -+#define CST4336_ARMREMAP_0 0x00000008 -+#define CST4336_ILPDIV_EN_MASK 0x00000010 -+#define CST4336_ILPDIV_EN_SHIFT 4 -+#define CST4336_XTAL_PD_POL_MASK 0x00000020 -+#define CST4336_XTAL_PD_POL_SHIFT 5 -+#define CST4336_LPO_SEL_MASK 0x00000040 -+#define CST4336_LPO_SEL_SHIFT 6 -+#define CST4336_RES_INIT_MODE_MASK 0x00000180 -+#define CST4336_RES_INIT_MODE_SHIFT 7 -+#define CST4336_CBUCK_MODE_MASK 0x00000600 -+#define CST4336_CBUCK_MODE_SHIFT 9 -+ -+/* 4336 Chip specific PMU ChipControl register bits */ -+#define PCTL_4336_SERIAL_ENAB (1 << 24) -+ -+/* 4330 resources */ -+#define RES4330_CBUCK_LPOM 0 -+#define RES4330_CBUCK_BURST 1 -+#define RES4330_CBUCK_LP_PWM 2 -+#define RES4330_CBUCK_PWM 3 -+#define RES4330_CLDO_PU 4 -+#define RES4330_DIS_INT_RESET_PD 5 -+#define RES4330_ILP_REQUEST 6 -+#define RES4330_LNLDO_PU 7 -+#define RES4330_LDO3P3_PU 8 -+#define RES4330_OTP_PU 9 -+#define RES4330_XTAL_PU 10 -+#define RES4330_ALP_AVAIL 11 -+#define RES4330_RADIO_PU 12 -+#define RES4330_BG_PU 13 -+#define RES4330_VREG1p4_PU_PU 14 -+#define RES4330_AFE_PWRSW_PU 15 -+#define RES4330_RX_PWRSW_PU 16 -+#define RES4330_TX_PWRSW_PU 17 -+#define RES4330_BB_PWRSW_PU 18 -+#define RES4330_SYNTH_PWRSW_PU 19 -+#define RES4330_MISC_PWRSW_PU 20 -+#define RES4330_LOGEN_PWRSW_PU 21 -+#define RES4330_BBPLL_PWRSW_PU 22 -+#define RES4330_MACPHY_CLKAVAIL 23 -+#define RES4330_HT_AVAIL 24 -+#define RES4330_5gRX_PWRSW_PU 25 -+#define RES4330_5gTX_PWRSW_PU 26 -+#define RES4330_5g_LOGEN_PWRSW_PU 27 -+ -+/* 4330 chip-specific ChipStatus register bits */ -+#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ -+#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ -+#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ -+#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ -+#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ -+#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ -+#define CST4330_OTP_PRESENT 0x00000010 -+#define CST4330_LPO_AUTODET_EN 0x00000020 -+#define CST4330_ARMREMAP_0 0x00000040 -+#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ -+#define CST4330_ILPDIV_EN 0x00000100 -+#define CST4330_LPO_SEL 0x00000200 -+#define CST4330_RES_INIT_MODE_SHIFT 10 -+#define CST4330_RES_INIT_MODE_MASK 0x00000c00 -+#define CST4330_CBUCK_MODE_SHIFT 12 -+#define CST4330_CBUCK_MODE_MASK 0x00003000 -+#define CST4330_CBUCK_POWER_OK 0x00004000 -+#define CST4330_BB_PLL_LOCKED 0x00008000 -+#define SOCDEVRAM_BP_ADDR 0x1E000000 -+#define SOCDEVRAM_ARM_ADDR 0x00800000 -+ -+/* 4330 Chip specific PMU ChipControl register bits */ -+#define PCTL_4330_SERIAL_ENAB (1 << 24) -+ -+/* 4330 Chip specific ChipControl register bits */ -+#define CCTRL_4330_GPIO_SEL 0x00000001 /* 1=select GPIOs to be muxed out */ -+#define CCTRL_4330_ERCX_SEL 0x00000002 /* 1=select ERCX BT coex to be muxed out */ -+#define CCTRL_4330_SDIO_HOST_WAKE 0x00000004 /* SDIO: 1=configure GPIO0 for host wake */ -+#define CCTRL_4330_JTAG_DISABLE 0x00000008 /* 1=disable JTAG interface on mux'd pins */ -+ -+#define PMU_VREG0_ADDR 0 -+#define PMU_VREG0_DISABLE_PULLD_BT_SHIFT 2 -+#define PMU_VREG0_DISABLE_PULLD_WL_SHIFT 3 -+ -+/* 4334 resources */ -+#define RES4334_LPLDO_PU 0 -+#define RES4334_RESET_PULLDN_DIS 1 -+#define RES4334_PMU_BG_PU 2 -+#define RES4334_HSIC_LDO_PU 3 -+#define RES4334_CBUCK_LPOM_PU 4 -+#define RES4334_CBUCK_PFM_PU 5 -+#define RES4334_CLDO_PU 6 -+#define RES4334_LPLDO2_LVM 7 -+#define RES4334_LNLDO_PU 8 -+#define RES4334_LDO3P3_PU 9 -+#define RES4334_OTP_PU 10 -+#define RES4334_XTAL_PU 11 -+#define RES4334_WL_PWRSW_PU 12 -+#define RES4334_LQ_AVAIL 13 -+#define RES4334_LOGIC_RET 14 -+#define RES4334_MEM_SLEEP 15 -+#define RES4334_MACPHY_RET 16 -+#define RES4334_WL_CORE_READY 17 -+#define RES4334_ILP_REQ 18 -+#define RES4334_ALP_AVAIL 19 -+#define RES4334_MISC_PWRSW_PU 20 -+#define RES4334_SYNTH_PWRSW_PU 21 -+#define RES4334_RX_PWRSW_PU 22 -+#define RES4334_RADIO_PU 23 -+#define RES4334_WL_PMU_PU 24 -+#define RES4334_VCO_LDO_PU 25 -+#define RES4334_AFE_LDO_PU 26 -+#define RES4334_RX_LDO_PU 27 -+#define RES4334_TX_LDO_PU 28 -+#define RES4334_HT_AVAIL 29 -+#define RES4334_MACPHY_CLK_AVAIL 30 -+ -+/* 4334 chip-specific ChipStatus register bits */ -+#define CST4334_CHIPMODE_MASK 7 -+#define CST4334_SDIO_MODE 0x00000000 -+#define CST4334_SPI_MODE 0x00000004 -+#define CST4334_HSIC_MODE 0x00000006 -+#define CST4334_BLUSB_MODE 0x00000007 -+#define CST4334_CHIPMODE_HSIC(cs) (((cs) & CST4334_CHIPMODE_MASK) == CST4334_HSIC_MODE) -+#define CST4334_OTP_PRESENT 0x00000010 -+#define CST4334_LPO_AUTODET_EN 0x00000020 -+#define CST4334_ARMREMAP_0 0x00000040 -+#define CST4334_SPROM_PRESENT 0x00000080 -+#define CST4334_ILPDIV_EN_MASK 0x00000100 -+#define CST4334_ILPDIV_EN_SHIFT 8 -+#define CST4334_LPO_SEL_MASK 0x00000200 -+#define CST4334_LPO_SEL_SHIFT 9 -+#define CST4334_RES_INIT_MODE_MASK 0x00000C00 -+#define CST4334_RES_INIT_MODE_SHIFT 10 -+ -+/* 4334 Chip specific PMU ChipControl register bits */ -+#define PCTL_4334_GPIO3_ENAB (1 << 3) -+ -+/* 4334 Chip control */ -+#define CCTRL4334_HSIC_LDO_PU (1 << 23) -+ -+/* 4324 Chip specific ChipControl1 register bits */ -+#define CCTRL1_4324_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ -+#define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -+ -+ -+/* 4313 resources */ -+#define RES4313_BB_PU_RSRC 0 -+#define RES4313_ILP_REQ_RSRC 1 -+#define RES4313_XTAL_PU_RSRC 2 -+#define RES4313_ALP_AVAIL_RSRC 3 -+#define RES4313_RADIO_PU_RSRC 4 -+#define RES4313_BG_PU_RSRC 5 -+#define RES4313_VREG1P4_PU_RSRC 6 -+#define RES4313_AFE_PWRSW_RSRC 7 -+#define RES4313_RX_PWRSW_RSRC 8 -+#define RES4313_TX_PWRSW_RSRC 9 -+#define RES4313_BB_PWRSW_RSRC 10 -+#define RES4313_SYNTH_PWRSW_RSRC 11 -+#define RES4313_MISC_PWRSW_RSRC 12 -+#define RES4313_BB_PLL_PWRSW_RSRC 13 -+#define RES4313_HT_AVAIL_RSRC 14 -+#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 -+ -+/* 4313 chip-specific ChipStatus register bits */ -+#define CST4313_SPROM_PRESENT 1 -+#define CST4313_OTP_PRESENT 2 -+#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 -+#define CST4313_SPROM_OTP_SEL_SHIFT 0 -+ -+/* 4313 Chip specific ChipControl register bits */ -+#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ -+ -+/* PMU respources for 4314 */ -+#define RES4314_LPLDO_PU 0 -+#define RES4314_PMU_SLEEP_DIS 1 -+#define RES4314_PMU_BG_PU 2 -+#define RES4314_CBUCK_LPOM_PU 3 -+#define RES4314_CBUCK_PFM_PU 4 -+#define RES4314_CLDO_PU 5 -+#define RES4314_LPLDO2_LVM 6 -+#define RES4314_WL_PMU_PU 7 -+#define RES4314_LNLDO_PU 8 -+#define RES4314_LDO3P3_PU 9 -+#define RES4314_OTP_PU 10 -+#define RES4314_XTAL_PU 11 -+#define RES4314_WL_PWRSW_PU 12 -+#define RES4314_LQ_AVAIL 13 -+#define RES4314_LOGIC_RET 14 -+#define RES4314_MEM_SLEEP 15 -+#define RES4314_MACPHY_RET 16 -+#define RES4314_WL_CORE_READY 17 -+#define RES4314_ILP_REQ 18 -+#define RES4314_ALP_AVAIL 19 -+#define RES4314_MISC_PWRSW_PU 20 -+#define RES4314_SYNTH_PWRSW_PU 21 -+#define RES4314_RX_PWRSW_PU 22 -+#define RES4314_RADIO_PU 23 -+#define RES4314_VCO_LDO_PU 24 -+#define RES4314_AFE_LDO_PU 25 -+#define RES4314_RX_LDO_PU 26 -+#define RES4314_TX_LDO_PU 27 -+#define RES4314_HT_AVAIL 28 -+#define RES4314_MACPHY_CLK_AVAIL 29 -+ -+/* 4314 chip-specific ChipStatus register bits */ -+#define CST4314_OTP_ENABLED 0x00200000 -+ -+/* 43228 resources */ -+#define RES43228_NOT_USED 0 -+#define RES43228_ILP_REQUEST 1 -+#define RES43228_XTAL_PU 2 -+#define RES43228_ALP_AVAIL 3 -+#define RES43228_PLL_EN 4 -+#define RES43228_HT_PHY_AVAIL 5 -+ -+/* 43228 chipstatus reg bits */ -+#define CST43228_ILP_DIV_EN 0x1 -+#define CST43228_OTP_PRESENT 0x2 -+#define CST43228_SERDES_REFCLK_PADSEL 0x4 -+#define CST43228_SDIO_MODE 0x8 -+#define CST43228_SDIO_OTP_PRESENT 0x10 -+#define CST43228_SDIO_RESET 0x20 -+ -+/* 4706 chipstatus reg bits */ -+#define CST4706_PKG_OPTION (1<<0) /* 0: full-featured package 1: low-cost package */ -+#define CST4706_SFLASH_PRESENT (1<<1) /* 0: parallel, 1: serial flash is present */ -+#define CST4706_SFLASH_TYPE (1<<2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */ -+#define CST4706_MIPS_BENDIAN (1<<3) /* 0: little, 1: big endian */ -+#define CST4706_PCIE1_DISABLE (1<<5) /* PCIE1 enable strap pin */ -+ -+/* 4706 flashstrconfig reg bits */ -+#define FLSTRCF4706_MASK 0x000000ff -+#define FLSTRCF4706_SF1 0x00000001 /* 2nd serial flash present */ -+#define FLSTRCF4706_PF1 0x00000002 /* 2nd parallel flash present */ -+#define FLSTRCF4706_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */ -+#define FLSTRCF4706_NF1 0x00000008 /* 2nd NAND flash present */ -+#define FLSTRCF4706_1ST_MADDR_SEG_MASK 0x000000f0 /* Valid value mask */ -+#define FLSTRCF4706_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */ -+ -+/* 4360 Chip specific ChipControl register bits */ -+#define CCTRL4360_SECI_MODE (1 << 2) -+#define CCTRL4360_BTSWCTRL_MODE (1 << 3) -+#define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8) -+#define CCTRL4360_BT_LGCY_MODE (1 << 9) -+#define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21) -+ -+/* 4360 PMU resources and chip status bits */ -+#define RES4360_REGULATOR 0 -+#define RES4360_ILP_AVAIL 1 -+#define RES4360_ILP_REQ 2 -+#define RES4360_XTAL_LDO_PU 3 -+#define RES4360_XTAL_PU 4 -+#define RES4360_ALP_AVAIL 5 -+#define RES4360_BBPLLPWRSW_PU 6 -+#define RES4360_HT_AVAIL 7 -+#define RES4360_OTP_PU 8 -+ -+#define CST4360_XTAL_40MZ 0x00000001 -+#define CST4360_SFLASH 0x00000002 -+#define CST4360_SPROM_PRESENT 0x00000004 -+#define CST4360_SFLASH_TYPE 0x00000004 -+#define CST4360_OTP_ENABLED 0x00000008 -+#define CST4360_REMAP_ROM 0x00000010 -+#define CST4360_RSRC_INIT_MODE_MASK 0x00000060 -+#define CST4360_RSRC_INIT_MODE_SHIFT 5 -+#define CST4360_ILP_DIVEN 0x00000080 -+#define CST4360_MODE_USB 0x00000100 -+#define CST4360_SPROM_SIZE_MASK 0x00000600 -+#define CST4360_SPROM_SIZE_SHIFT 9 -+#define CST4360_BBPLL_LOCK 0x00000800 -+#define CST4360_AVBBPLL_LOCK 0x00001000 -+#define CST4360_USBBBPLL_LOCK 0x00002000 -+ -+#define CCTRL_4360_UART_SEL 0x2 -+ -+/* 4335 resources */ -+#define RES4335_LPLDO_PO 0 -+#define RES4335_PMU_BG_PU 1 -+#define RES4335_PMU_SLEEP 2 -+#define RES4335_RSVD_3 3 -+#define RES4335_CBUCK_LPOM_PU 4 -+#define RES4335_CBUCK_PFM_PU 5 -+#define RES4335_RSVD_6 6 -+#define RES4335_RSVD_7 7 -+#define RES4335_LNLDO_PU 8 -+#define RES4335_XTALLDO_PU 9 -+#define RES4335_LDO3P3_PU 10 -+#define RES4335_OTP_PU 11 -+#define RES4335_XTAL_PU 12 -+#define RES4335_SR_CLK_START 13 -+#define RES4335_LQ_AVAIL 14 -+#define RES4335_LQ_START 15 -+#define RES4335_RSVD_16 16 -+#define RES4335_WL_CORE_RDY 17 -+#define RES4335_ILP_REQ 18 -+#define RES4335_ALP_AVAIL 19 -+#define RES4335_MINI_PMU 20 -+#define RES4335_RADIO_PU 21 -+#define RES4335_SR_CLK_STABLE 22 -+#define RES4335_SR_SAVE_RESTORE 23 -+#define RES4335_SR_PHY_PWRSW 24 -+#define RES4335_SR_VDDM_PWRSW 25 -+#define RES4335_SR_SUBCORE_PWRSW 26 -+#define RES4335_SR_SLEEP 27 -+#define RES4335_HT_START 28 -+#define RES4335_HT_AVAIL 29 -+#define RES4335_MACPHY_CLKAVAIL 30 -+ -+/* 4335 Chip specific ChipStatus register bits */ -+#define CST4335_SPROM_MASK 0x00000020 -+#define CST4335_SFLASH_MASK 0x00000040 -+#define CST4335_RES_INIT_MODE_SHIFT 7 -+#define CST4335_RES_INIT_MODE_MASK 0x00000180 -+#define CST4335_CHIPMODE_MASK 0xF -+#define CST4335_CHIPMODE_SDIOD(cs) (((cs) & (1 << 0)) != 0) /* SDIO */ -+#define CST4335_CHIPMODE_GSPI(cs) (((cs) & (1 << 1)) != 0) /* gSPI */ -+#define CST4335_CHIPMODE_USB20D(cs) (((cs) & (1 << 2)) != 0) /* USB || USBDA */ -+#define CST4335_CHIPMODE_PCIE(cs) (((cs) & (1 << 3)) != 0) /* PCIE */ -+ -+/* 4335 Chip specific ChipControl1 register bits */ -+#define CCTRL1_4335_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ -+#define CCTRL1_4335_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -+ -+ -+#define CR4_RAM_BASE (0x180000) -+ -+/* 4335 resources--END */ -+ -+/* GCI chipcontrol register indices */ -+#define CC_GCI_CHIPCTRL_00 (0) -+#define CC_GCI_CHIPCTRL_01 (1) -+#define CC_GCI_CHIPCTRL_02 (2) -+#define CC_GCI_CHIPCTRL_03 (3) -+#define CC_GCI_CHIPCTRL_04 (4) -+#define CC_GCI_CHIPCTRL_05 (5) -+#define CC_GCI_CHIPCTRL_06 (6) -+#define CC_GCI_CHIPCTRL_07 (7) -+#define CC_GCI_CHIPCTRL_08 (8) -+ -+#define CC_GCI_NUMCHIPCTRLREGS(cap1) ((cap1 & 0xF00) >> 8) -+ -+/* 4335 pins -+* note: only the values set as default/used are added here. -+*/ -+#define CC4335_PIN_GPIO_00 (0) -+#define CC4335_PIN_GPIO_01 (1) -+#define CC4335_PIN_GPIO_02 (2) -+#define CC4335_PIN_GPIO_03 (3) -+#define CC4335_PIN_GPIO_04 (4) -+#define CC4335_PIN_GPIO_05 (5) -+#define CC4335_PIN_GPIO_06 (6) -+#define CC4335_PIN_GPIO_07 (7) -+#define CC4335_PIN_GPIO_08 (8) -+#define CC4335_PIN_GPIO_09 (9) -+#define CC4335_PIN_GPIO_10 (10) -+#define CC4335_PIN_GPIO_11 (11) -+#define CC4335_PIN_GPIO_12 (12) -+#define CC4335_PIN_GPIO_13 (13) -+#define CC4335_PIN_GPIO_14 (14) -+#define CC4335_PIN_GPIO_15 (15) -+#define CC4335_PIN_SDIO_CLK (16) -+#define CC4335_PIN_SDIO_CMD (17) -+#define CC4335_PIN_SDIO_DATA0 (18) -+#define CC4335_PIN_SDIO_DATA1 (19) -+#define CC4335_PIN_SDIO_DATA2 (20) -+#define CC4335_PIN_SDIO_DATA3 (21) -+#define CC4335_PIN_RF_SW_CTRL_0 (22) -+#define CC4335_PIN_RF_SW_CTRL_1 (23) -+#define CC4335_PIN_RF_SW_CTRL_2 (24) -+#define CC4335_PIN_RF_SW_CTRL_3 (25) -+#define CC4335_PIN_RF_SW_CTRL_4 (26) -+#define CC4335_PIN_RF_SW_CTRL_5 (27) -+#define CC4335_PIN_RF_SW_CTRL_6 (28) -+#define CC4335_PIN_RF_SW_CTRL_7 (29) -+#define CC4335_PIN_RF_SW_CTRL_8 (30) -+#define CC4335_PIN_RF_SW_CTRL_9 (31) -+ -+/* 4335 GCI function sel values -+*/ -+#define CC4335_FNSEL_HWDEF (0) -+#define CC4335_FNSEL_SAMEASPIN (1) -+#define CC4335_FNSEL_GPIO0 (2) -+#define CC4335_FNSEL_GPIO1 (3) -+#define CC4335_FNSEL_GCI0 (4) -+#define CC4335_FNSEL_GCI1 (5) -+#define CC4335_FNSEL_UART (6) -+#define CC4335_FNSEL_SFLASH (7) -+#define CC4335_FNSEL_SPROM (8) -+#define CC4335_FNSEL_MISC0 (9) -+#define CC4335_FNSEL_MISC1 (10) -+#define CC4335_FNSEL_MISC2 (11) -+#define CC4335_FNSEL_IND (12) -+#define CC4335_FNSEL_PDN (13) -+#define CC4335_FNSEL_PUP (14) -+#define CC4335_FNSEL_TRI (15) -+ -+/* find the 4 bit mask given the bit position */ -+#define GCIMASK(pos) (((uint32)0xF) << pos) -+ -+/* get the value which can be used to directly OR with chipcontrol reg */ -+#define GCIPOSVAL(val, pos) ((((uint32)val) << pos) & GCIMASK(pos)) -+ -+/* 4335 MUX options. each nibble belongs to a setting. Non-zero value specifies a logic -+* for now only UART for bootloader. -+*/ -+#define MUXENAB4335_UART_MASK (0x0000000f) -+ -+ -+/* defines to detect active host interface in use */ -+#define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB) -+ -+/* -+* Maximum delay for the PMU state transition in us. -+* This is an upper bound intended for spinwaits etc. -+*/ -+#define PMU_MAX_TRANSITION_DLY 15000 -+ -+/* PMU resource up transition time in ILP cycles */ -+#define PMURES_UP_TRANSITION 2 -+ -+ -+/* SECI configuration */ -+#define SECI_MODE_UART 0x0 -+#define SECI_MODE_SECI 0x1 -+#define SECI_MODE_LEGACY_3WIRE_BT 0x2 -+#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3 -+#define SECI_MODE_HALF_SECI 0x4 -+ -+#define SECI_RESET (1 << 0) -+#define SECI_RESET_BAR_UART (1 << 1) -+#define SECI_ENAB_SECI_ECI (1 << 2) -+#define SECI_ENAB_SECIOUT_DIS (1 << 3) -+#define SECI_MODE_MASK 0x7 -+#define SECI_MODE_SHIFT 4 /* (bits 5, 6, 7) */ -+#define SECI_UPD_SECI (1 << 7) -+ -+#define SECI_SIGNOFF_0 0xDB -+#define SECI_SIGNOFF_1 0 -+ -+/* seci clk_ctl_st bits */ -+#define CLKCTL_STS_SECI_CLK_REQ (1 << 8) -+#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24) -+ -+#define SECI_UART_MSR_CTS_STATE (1 << 0) -+#define SECI_UART_MSR_RTS_STATE (1 << 1) -+#define SECI_UART_SECI_IN_STATE (1 << 2) -+#define SECI_UART_SECI_IN2_STATE (1 << 3) -+ -+/* SECI UART LCR/MCR register bits */ -+#define SECI_UART_LCR_STOP_BITS (1 << 0) /* 0 - 1bit, 1 - 2bits */ -+#define SECI_UART_LCR_PARITY_EN (1 << 1) -+#define SECI_UART_LCR_PARITY (1 << 2) /* 0 - odd, 1 - even */ -+#define SECI_UART_LCR_RX_EN (1 << 3) -+#define SECI_UART_LCR_LBRK_CTRL (1 << 4) /* 1 => SECI_OUT held low */ -+#define SECI_UART_LCR_TXO_EN (1 << 5) -+#define SECI_UART_LCR_RTSO_EN (1 << 6) -+#define SECI_UART_LCR_SLIPMODE_EN (1 << 7) -+#define SECI_UART_LCR_RXCRC_CHK (1 << 8) -+#define SECI_UART_LCR_TXCRC_INV (1 << 9) -+#define SECI_UART_LCR_TXCRC_LSBF (1 << 10) -+#define SECI_UART_LCR_TXCRC_EN (1 << 11) -+ -+#define SECI_UART_MCR_TX_EN (1 << 0) -+#define SECI_UART_MCR_PRTS (1 << 1) -+#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2) -+#define SECI_UART_MCR_HIGHRATE_EN (1 << 3) -+#define SECI_UART_MCR_LOOPBK_EN (1 << 4) -+#define SECI_UART_MCR_AUTO_RTS (1 << 5) -+#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6) -+#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7) -+#define SECI_UART_MCR_XONOFF_RPT (1 << 9) -+ -+/* WLAN channel numbers - used from wifi.h */ -+ -+/* WLAN BW */ -+#define ECI_BW_20 0x0 -+#define ECI_BW_25 0x1 -+#define ECI_BW_30 0x2 -+#define ECI_BW_35 0x3 -+#define ECI_BW_40 0x4 -+#define ECI_BW_45 0x5 -+#define ECI_BW_50 0x6 -+#define ECI_BW_ALL 0x7 -+ -+/* WLAN - number of antenna */ -+#define WLAN_NUM_ANT1 TXANT_0 -+#define WLAN_NUM_ANT2 TXANT_1 -+ -+#endif /* _SBCHIPC_H */ -diff --git a/drivers/net/wireless/ap6210/include/sbconfig.h b/drivers/net/wireless/ap6210/include/sbconfig.h -new file mode 100644 -index 0000000..73ddadd ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbconfig.h -@@ -0,0 +1,282 @@ -+/* -+ * Broadcom SiliconBackplane hardware register definitions. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbconfig.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _SBCONFIG_H -+#define _SBCONFIG_H -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif -+ -+/* enumeration in SB is based on the premise that cores are contiguos in the -+ * enumeration space. -+ */ -+#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */ -+#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -+#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */ -+ -+/* -+ * Sonics Configuration Space Registers. -+ */ -+#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ -+#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ -+ -+#define SBIPSFLAG 0x08 -+#define SBTPSFLAG 0x18 -+#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ -+#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ -+#define SBADMATCH3 0x60 -+#define SBADMATCH2 0x68 -+#define SBADMATCH1 0x70 -+#define SBIMSTATE 0x90 -+#define SBINTVEC 0x94 -+#define SBTMSTATELOW 0x98 -+#define SBTMSTATEHIGH 0x9c -+#define SBBWA0 0xa0 -+#define SBIMCONFIGLOW 0xa8 -+#define SBIMCONFIGHIGH 0xac -+#define SBADMATCH0 0xb0 -+#define SBTMCONFIGLOW 0xb8 -+#define SBTMCONFIGHIGH 0xbc -+#define SBBCONFIG 0xc0 -+#define SBBSTATE 0xc8 -+#define SBACTCNFG 0xd8 -+#define SBFLAGST 0xe8 -+#define SBIDLOW 0xf8 -+#define SBIDHIGH 0xfc -+ -+/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have -+ * a few registers *below* that line. I think it would be very confusing to try -+ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here, -+ */ -+ -+#define SBIMERRLOGA 0xea8 -+#define SBIMERRLOG 0xeb0 -+#define SBTMPORTCONNID0 0xed8 -+#define SBTMPORTLOCK0 0xef8 -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+typedef volatile struct _sbconfig { -+ uint32 PAD[2]; -+ uint32 sbipsflag; /* initiator port ocp slave flag */ -+ uint32 PAD[3]; -+ uint32 sbtpsflag; /* target port ocp slave flag */ -+ uint32 PAD[11]; -+ uint32 sbtmerrloga; /* (sonics >= 2.3) */ -+ uint32 PAD; -+ uint32 sbtmerrlog; /* (sonics >= 2.3) */ -+ uint32 PAD[3]; -+ uint32 sbadmatch3; /* address match3 */ -+ uint32 PAD; -+ uint32 sbadmatch2; /* address match2 */ -+ uint32 PAD; -+ uint32 sbadmatch1; /* address match1 */ -+ uint32 PAD[7]; -+ uint32 sbimstate; /* initiator agent state */ -+ uint32 sbintvec; /* interrupt mask */ -+ uint32 sbtmstatelow; /* target state */ -+ uint32 sbtmstatehigh; /* target state */ -+ uint32 sbbwa0; /* bandwidth allocation table0 */ -+ uint32 PAD; -+ uint32 sbimconfiglow; /* initiator configuration */ -+ uint32 sbimconfighigh; /* initiator configuration */ -+ uint32 sbadmatch0; /* address match0 */ -+ uint32 PAD; -+ uint32 sbtmconfiglow; /* target configuration */ -+ uint32 sbtmconfighigh; /* target configuration */ -+ uint32 sbbconfig; /* broadcast configuration */ -+ uint32 PAD; -+ uint32 sbbstate; /* broadcast state */ -+ uint32 PAD[3]; -+ uint32 sbactcnfg; /* activate configuration */ -+ uint32 PAD[3]; -+ uint32 sbflagst; /* current sbflags */ -+ uint32 PAD[3]; -+ uint32 sbidlow; /* identification */ -+ uint32 sbidhigh; /* identification */ -+} sbconfig_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* sbipsflag */ -+#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ -+#define SBIPS_INT1_SHIFT 0 -+#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ -+#define SBIPS_INT2_SHIFT 8 -+#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ -+#define SBIPS_INT3_SHIFT 16 -+#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ -+#define SBIPS_INT4_SHIFT 24 -+ -+/* sbtpsflag */ -+#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ -+#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ -+ -+/* sbtmerrlog */ -+#define SBTMEL_CM 0x00000007 /* command */ -+#define SBTMEL_CI 0x0000ff00 /* connection id */ -+#define SBTMEL_EC 0x0f000000 /* error code */ -+#define SBTMEL_ME 0x80000000 /* multiple error */ -+ -+/* sbimstate */ -+#define SBIM_PC 0xf /* pipecount */ -+#define SBIM_AP_MASK 0x30 /* arbitration policy */ -+#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ -+#define SBIM_AP_TS 0x10 /* use timesliaces only */ -+#define SBIM_AP_TK 0x20 /* use token only */ -+#define SBIM_AP_RSV 0x30 /* reserved */ -+#define SBIM_IBE 0x20000 /* inbanderror */ -+#define SBIM_TO 0x40000 /* timeout */ -+#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ -+#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ -+ -+/* sbtmstatelow */ -+#define SBTML_RESET 0x0001 /* reset */ -+#define SBTML_REJ_MASK 0x0006 /* reject field */ -+#define SBTML_REJ 0x0002 /* reject */ -+#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ -+ -+#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ -+ -+/* sbtmstatehigh */ -+#define SBTMH_SERR 0x0001 /* serror */ -+#define SBTMH_INT 0x0002 /* interrupt */ -+#define SBTMH_BUSY 0x0004 /* busy */ -+#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ -+ -+#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ -+ -+/* sbbwa0 */ -+#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ -+#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ -+#define SBBWA_TAB1_SHIFT 16 -+ -+/* sbimconfiglow */ -+#define SBIMCL_STO_MASK 0x7 /* service timeout */ -+#define SBIMCL_RTO_MASK 0x70 /* request timeout */ -+#define SBIMCL_RTO_SHIFT 4 -+#define SBIMCL_CID_MASK 0xff0000 /* connection id */ -+#define SBIMCL_CID_SHIFT 16 -+ -+/* sbimconfighigh */ -+#define SBIMCH_IEM_MASK 0xc /* inband error mode */ -+#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ -+#define SBIMCH_TEM_SHIFT 4 -+#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ -+#define SBIMCH_BEM_SHIFT 6 -+ -+/* sbadmatch0 */ -+#define SBAM_TYPE_MASK 0x3 /* address type */ -+#define SBAM_AD64 0x4 /* reserved */ -+#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ -+#define SBAM_ADINT0_SHIFT 3 -+#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ -+#define SBAM_ADINT1_SHIFT 3 -+#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ -+#define SBAM_ADINT2_SHIFT 3 -+#define SBAM_ADEN 0x400 /* enable */ -+#define SBAM_ADNEG 0x800 /* negative decode */ -+#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ -+#define SBAM_BASE0_SHIFT 8 -+#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ -+#define SBAM_BASE1_SHIFT 12 -+#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ -+#define SBAM_BASE2_SHIFT 16 -+ -+/* sbtmconfiglow */ -+#define SBTMCL_CD_MASK 0xff /* clock divide */ -+#define SBTMCL_CO_MASK 0xf800 /* clock offset */ -+#define SBTMCL_CO_SHIFT 11 -+#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ -+#define SBTMCL_IF_SHIFT 18 -+#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ -+#define SBTMCL_IM_SHIFT 24 -+ -+/* sbtmconfighigh */ -+#define SBTMCH_BM_MASK 0x3 /* busy mode */ -+#define SBTMCH_RM_MASK 0x3 /* retry mode */ -+#define SBTMCH_RM_SHIFT 2 -+#define SBTMCH_SM_MASK 0x30 /* stop mode */ -+#define SBTMCH_SM_SHIFT 4 -+#define SBTMCH_EM_MASK 0x300 /* sb error mode */ -+#define SBTMCH_EM_SHIFT 8 -+#define SBTMCH_IM_MASK 0xc00 /* int mode */ -+#define SBTMCH_IM_SHIFT 10 -+ -+/* sbbconfig */ -+#define SBBC_LAT_MASK 0x3 /* sb latency */ -+#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ -+#define SBBC_MAX0_SHIFT 16 -+#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ -+#define SBBC_MAX1_SHIFT 20 -+ -+/* sbbstate */ -+#define SBBS_SRD 0x1 /* st reg disable */ -+#define SBBS_HRD 0x2 /* hold reg disable */ -+ -+/* sbidlow */ -+#define SBIDL_CS_MASK 0x3 /* config space */ -+#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ -+#define SBIDL_AR_SHIFT 3 -+#define SBIDL_SYNCH 0x40 /* sync */ -+#define SBIDL_INIT 0x80 /* initiator */ -+#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ -+#define SBIDL_MINLAT_SHIFT 8 -+#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ -+#define SBIDL_MAXLAT_SHIFT 12 -+#define SBIDL_FIRST 0x10000 /* this initiator is first */ -+#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ -+#define SBIDL_CW_SHIFT 18 -+#define SBIDL_TP_MASK 0xf00000 /* target ports */ -+#define SBIDL_TP_SHIFT 20 -+#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ -+#define SBIDL_IP_SHIFT 24 -+#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ -+#define SBIDL_RV_SHIFT 28 -+#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ -+#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ -+ -+/* sbidhigh */ -+#define SBIDH_RC_MASK 0x000f /* revision code */ -+#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ -+#define SBIDH_RCE_SHIFT 8 -+#define SBCOREREV(sbidh) \ -+ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -+#define SBIDH_CC_MASK 0x8ff0 /* core code */ -+#define SBIDH_CC_SHIFT 4 -+#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ -+#define SBIDH_VC_SHIFT 16 -+ -+#define SB_COMMIT 0xfd8 /* update buffered registers value */ -+ -+/* vendor codes */ -+#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ -+ -+#endif /* _SBCONFIG_H */ -diff --git a/drivers/net/wireless/ap6210/include/sbhnddma.h b/drivers/net/wireless/ap6210/include/sbhnddma.h -new file mode 100644 -index 0000000..40ebd8a ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbhnddma.h -@@ -0,0 +1,384 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbhnddma.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ -+ -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ -+ -+ -+/* 32 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; -+ -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; -+ -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32RINGALIGN_BITS 12 -+#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -+#define D32RINGALIGN (1 << D32RINGALIGN_BITS) -+ -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) -+ -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ -+#define XC_MR_SHIFT 6 -+#define XC_PD ((uint32)1 << 11) /* parity check disable */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 -+#define XC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define XC_BL_SHIFT 18 -+#define XC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define XC_PC_SHIFT 21 -+#define XC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define XC_PT_SHIFT 24 -+ -+/* Multiple outstanding reads */ -+#define DMA_MR_1 0 -+#define DMA_MR_2 1 -+/* 2, 3: reserved */ -+ -+/* DMA Burst Length in bytes */ -+#define DMA_BL_16 0 -+#define DMA_BL_32 1 -+#define DMA_BL_64 2 -+#define DMA_BL_128 3 -+#define DMA_BL_256 4 -+#define DMA_BL_512 5 -+#define DMA_BL_1024 6 -+ -+/* Prefetch control */ -+#define DMA_PC_0 0 -+#define DMA_PC_4 1 -+#define DMA_PC_8 2 -+#define DMA_PC_16 3 -+/* others: reserved */ -+ -+/* Prefetch threshold */ -+#define DMA_PT_1 0 -+#define DMA_PT_2 1 -+#define DMA_PT_4 2 -+#define DMA_PT_8 3 -+ -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 -+ -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_SH ((uint32)1 << 9) /* separate rx header descriptor enable */ -+#define RC_OC ((uint32)1 << 10) /* overflow continue */ -+#define RC_PD ((uint32)1 << 11) /* parity check disable */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 -+#define RC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define RC_BL_SHIFT 18 -+#define RC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define RC_PC_SHIFT 21 -+#define RC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define RC_PT_SHIFT 24 -+ -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 -+ -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_PARITY ((uint32)3 << 18) /* parity bit */ -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 -+ -+/* 64 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; -+ -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ -+} dma64dd_t; -+ -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. -+ */ -+#define D64RINGALIGN_BITS 13 -+#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -+#define D64RINGALIGN (1 << D64RINGALIGN_BITS) -+ -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) -+ -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ -+#define D64_XC_MR_SHIFT 6 -+#define D64_XC_PD 0x00000800 /* parity check disable */ -+#define D64_XC_AE 0x00030000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 -+#define D64_XC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define D64_XC_BL_SHIFT 18 -+#define D64_XC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define D64_XC_PC_SHIFT 21 -+#define D64_XC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define D64_XC_PT_SHIFT 24 -+ -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00001fff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ -+ -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ -+#define D64_RC_OC 0x00000400 /* overflow continue */ -+#define D64_RC_PD 0x00000800 /* parity check disable */ -+#define D64_RC_AE 0x00030000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 -+#define D64_RC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define D64_RC_BL_SHIFT 18 -+#define D64_RC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define D64_RC_PC_SHIFT 21 -+#define D64_RC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define D64_RC_PT_SHIFT 24 -+ -+/* flags for dma controller */ -+#define DMA_CTRL_PEN (1 << 0) /* partity enable */ -+#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ -+#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ -+#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ -+#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4) -+#define DMA_CTRL_DMA_AVOIDANCE_WAR (1 << 5) /* DMA avoidance WAR for 4331 */ -+ -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00001fff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ -+ -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags 1 */ -+#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ -+#define D64_CTRL2_AE 0x00030000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 -+#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 -+ -+#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ -+#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ -+#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */ -+#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ -+ -+/* receive frame status */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+} dma_rxh_t; -+ -+#endif /* _sbhnddma_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/sbpcmcia.h b/drivers/net/wireless/ap6210/include/sbpcmcia.h -new file mode 100644 -index 0000000..c4e9d46 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbpcmcia.h -@@ -0,0 +1,113 @@ -+/* -+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbpcmcia.h 326494 2012-04-09 13:29:57Z $ -+ */ -+ -+#ifndef _SBPCMCIA_H -+#define _SBPCMCIA_H -+ -+/* All the addresses that are offsets in attribute space are divided -+ * by two to account for the fact that odd bytes are invalid in -+ * attribute space and our read/write routines make the space appear -+ * as if they didn't exist. Still we want to show the original numbers -+ * as documented in the hnd_pcmcia core manual. -+ */ -+ -+/* PCMCIA Function Configuration Registers */ -+#define PCMCIA_FCR (0x700 / 2) -+ -+#define FCR0_OFF 0 -+#define FCR1_OFF (0x40 / 2) -+#define FCR2_OFF (0x80 / 2) -+#define FCR3_OFF (0xc0 / 2) -+ -+#define PCMCIA_FCR0 (0x700 / 2) -+#define PCMCIA_FCR1 (0x740 / 2) -+#define PCMCIA_FCR2 (0x780 / 2) -+#define PCMCIA_FCR3 (0x7c0 / 2) -+ -+/* Standard PCMCIA FCR registers */ -+ -+#define PCMCIA_COR 0 -+ -+#define COR_RST 0x80 -+#define COR_LEV 0x40 -+#define COR_IRQEN 0x04 -+#define COR_BLREN 0x01 -+#define COR_FUNEN 0x01 -+ -+ -+#define PCICIA_FCSR (2 / 2) -+#define PCICIA_PRR (4 / 2) -+#define PCICIA_SCR (6 / 2) -+#define PCICIA_ESR (8 / 2) -+ -+ -+#define PCM_MEMOFF 0x0000 -+#define F0_MEMOFF 0x1000 -+#define F1_MEMOFF 0x2000 -+#define F2_MEMOFF 0x3000 -+#define F3_MEMOFF 0x4000 -+ -+/* Memory base in the function fcr's */ -+#define MEM_ADDR0 (0x728 / 2) -+#define MEM_ADDR1 (0x72a / 2) -+#define MEM_ADDR2 (0x72c / 2) -+ -+/* PCMCIA base plus Srom access in fcr0: */ -+#define PCMCIA_ADDR0 (0x072e / 2) -+#define PCMCIA_ADDR1 (0x0730 / 2) -+#define PCMCIA_ADDR2 (0x0732 / 2) -+ -+#define MEM_SEG (0x0734 / 2) -+#define SROM_CS (0x0736 / 2) -+#define SROM_DATAL (0x0738 / 2) -+#define SROM_DATAH (0x073a / 2) -+#define SROM_ADDRL (0x073c / 2) -+#define SROM_ADDRH (0x073e / 2) -+#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */ -+#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */ -+ -+/* Values for srom_cs: */ -+#define SROM_IDLE 0 -+#define SROM_WRITE 1 -+#define SROM_READ 2 -+#define SROM_WEN 4 -+#define SROM_WDS 7 -+#define SROM_DONE 8 -+ -+/* Fields in srom_info: */ -+#define SRI_SZ_MASK 0x03 -+#define SRI_BLANK 0x04 -+#define SRI_OTP 0x80 -+ -+ -+/* sbtmstatelow */ -+#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ -+#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ -+ -+/* sbtmstatehigh */ -+#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ -+ -+#endif /* _SBPCMCIA_H */ -diff --git a/drivers/net/wireless/ap6210/include/sbsdio.h b/drivers/net/wireless/ap6210/include/sbsdio.h -new file mode 100644 -index 0000000..8d0139d ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbsdio.h -@@ -0,0 +1,188 @@ -+/* -+ * SDIO device core hardware definitions. -+ * sdio is a portion of the pcmcia core in core rev 3 - rev 8 -+ * -+ * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbsdio.h 361940 2012-10-10 08:32:12Z $ -+ */ -+ -+#ifndef _SBSDIO_H -+#define _SBSDIO_H -+ -+#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ -+ -+/* function 1 miscellaneous registers */ -+#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ -+#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ -+#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ -+#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ -+#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ -+#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ -+#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ -+#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ -+#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ -+#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ -+ -+/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ -+#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ -+#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ -+#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ -+#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ -+#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ -+#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ -+#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ -+#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ -+#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ -+#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ -+#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D /* MesBusyCtl at 0x1001D (rev 11) */ -+ -+#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -+#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ -+ -+/* Sdio Core Rev 12 */ -+#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E -+#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 -+#define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0 -+#define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2 -+#define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1 -+#define SBSDIO_FUNC1_SLEEPCSR 0x1001F -+#define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1 -+#define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0 -+#define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1 -+#define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2 -+#define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1 -+ -+/* SBSDIO_SPROM_CS */ -+#define SBSDIO_SPROM_IDLE 0 -+#define SBSDIO_SPROM_WRITE 1 -+#define SBSDIO_SPROM_READ 2 -+#define SBSDIO_SPROM_WEN 4 -+#define SBSDIO_SPROM_WDS 7 -+#define SBSDIO_SPROM_DONE 8 -+ -+/* SBSDIO_SPROM_INFO */ -+#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ -+#define SROM_BLANK 0x04 /* depreciated in corerev 6 */ -+#define SROM_OTP 0x80 /* OTP present */ -+ -+/* SBSDIO_CHIP_CTRL */ -+#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu, -+ * 1: power on oscillator -+ * (for 4318 only) -+ */ -+/* SBSDIO_WATERMARK */ -+#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device -+ * to wait before sending data to host -+ */ -+ -+/* SBSDIO_MESBUSYCTRL */ -+/* When RX FIFO has less entries than this & MBE is set -+ * => busy signal is asserted between data blocks. -+*/ -+#define SBSDIO_MESBUSYCTRL_MASK 0x7f -+ -+/* SBSDIO_DEVICE_CTL */ -+#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when -+ * receiving CMD53 -+ */ -+#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is -+ * synchronous to the sdio clock -+ */ -+#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host -+ * except the chipActive (rev 8) -+ */ -+#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put -+ * external pads in tri-state; requires -+ * sdio bus power cycle to clear (rev 9) -+ */ -+#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -+#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -+#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -+#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ -+#define SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK 0x10 /* Enable function 2 tx for each block */ -+ -+ -+/* SBSDIO_FUNC1_CHIPCLKCSR */ -+#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -+#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -+#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -+#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -+#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -+#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -+#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -+#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ -+/* In rev8, actual avail bits followed original docs */ -+#define SBSDIO_Rev8_HT_AVAIL 0x40 -+#define SBSDIO_Rev8_ALP_AVAIL 0x80 -+#define SBSDIO_CSR_MASK 0x1F -+ -+#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -+#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -+#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -+#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -+#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ -+ (alponly ? 1 : SBSDIO_HTAV(regval))) -+ -+/* SBSDIO_FUNC1_SDIOPULLUP */ -+#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */ -+#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */ -+#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */ -+#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */ -+#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */ -+ -+/* function 1 OCP space */ -+#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -+#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -+#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ -+ -+/* some duplication with sbsdpcmdev.h here */ -+/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ -+#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -+#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -+#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ -+#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ -+ -+/* direct(mapped) cis space */ -+#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -+#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -+#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */ -+ -+#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ -+ -+#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, -+ * link bytes -+ */ -+ -+/* indirect cis access (in sprom) */ -+#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from -+ * 8th byte -+ */ -+ -+#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one -+ * data comamnd -+ */ -+ -+#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ -+ -+#endif /* _SBSDIO_H */ -diff --git a/drivers/net/wireless/ap6210/include/sbsdpcmdev.h b/drivers/net/wireless/ap6210/include/sbsdpcmdev.h -new file mode 100644 -index 0000000..10c7401 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbsdpcmdev.h -@@ -0,0 +1,295 @@ -+/* -+ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific -+ * device core support -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbsdpcmdev.h 347614 2012-07-27 10:24:51Z $ -+ */ -+ -+#ifndef _sbsdpcmdev_h_ -+#define _sbsdpcmdev_h_ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+ -+typedef volatile struct { -+ dma64regs_t xmt; /* dma tx */ -+ uint32 PAD[2]; -+ dma64regs_t rcv; /* dma rx */ -+ uint32 PAD[2]; -+} dma64p_t; -+ -+/* dma64 sdiod corerev >= 1 */ -+typedef volatile struct { -+ dma64p_t dma64regs[2]; -+ dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */ -+ uint32 PAD[92]; -+} sdiodma64_t; -+ -+/* dma32 sdiod corerev == 0 */ -+typedef volatile struct { -+ dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */ -+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */ -+ uint32 PAD[108]; -+} sdiodma32_t; -+ -+/* dma32 regs for pcmcia core */ -+typedef volatile struct { -+ dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */ -+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */ -+ uint32 PAD[116]; -+} pcmdma32_t; -+ -+/* core registers */ -+typedef volatile struct { -+ uint32 corecontrol; /* CoreControl, 0x000, rev8 */ -+ uint32 corestatus; /* CoreStatus, 0x004, rev8 */ -+ uint32 PAD[1]; -+ uint32 biststatus; /* BistStatus, 0x00c, rev8 */ -+ -+ /* PCMCIA access */ -+ uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */ -+ uint16 PAD[1]; -+ uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */ -+ uint16 PAD[1]; -+ uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */ -+ uint16 PAD[1]; -+ uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */ -+ uint16 PAD[1]; -+ -+ /* interrupt */ -+ uint32 intstatus; /* IntStatus, 0x020, rev8 */ -+ uint32 hostintmask; /* IntHostMask, 0x024, rev8 */ -+ uint32 intmask; /* IntSbMask, 0x028, rev8 */ -+ uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */ -+ uint32 sbintmask; /* SBIntMask, 0x030, rev8 */ -+ uint32 funcintmask; /* SDIO Function Interrupt Mask, SDIO rev4 */ -+ uint32 PAD[2]; -+ uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */ -+ uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */ -+ uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */ -+ uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */ -+ -+ /* synchronized access to registers in SDIO clock domain */ -+ uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */ -+ uint32 PAD[3]; -+ -+ /* PCMCIA frame control */ -+ uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */ -+ uint8 PAD[3]; -+ uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */ -+ uint8 PAD[155]; -+ -+ /* interrupt batching control */ -+ uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */ -+ uint32 PAD[3]; -+ -+ /* counters */ -+ uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */ -+ uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */ -+ uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */ -+ uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */ -+ uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */ -+ uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */ -+ uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */ -+ uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */ -+ uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */ -+ uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */ -+ uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */ -+ uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */ -+ uint32 PAD[40]; -+ uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */ -+ uint32 PAD[7]; -+ -+ /* DMA engines */ -+ volatile union { -+ pcmdma32_t pcm32; -+ sdiodma32_t sdiod32; -+ sdiodma64_t sdiod64; -+ } dma; -+ -+ /* SDIO/PCMCIA CIS region */ -+ char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */ -+ -+ /* PCMCIA function control registers */ -+ char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */ -+ uint16 PAD[55]; -+ -+ /* PCMCIA backplane access */ -+ uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */ -+ uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */ -+ uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */ -+ uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */ -+ uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */ -+ uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */ -+ uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */ -+ uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */ -+ uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */ -+ uint16 PAD[31]; -+ -+ /* sprom "size" & "blank" info */ -+ uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */ -+ uint32 PAD[464]; -+ -+ /* Sonics SiliconBackplane registers */ -+ sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */ -+} sdpcmd_regs_t; -+ -+/* corecontrol */ -+#define CC_CISRDY (1 << 0) /* CIS Ready */ -+#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */ -+#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ -+#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */ -+#define CC_XMTDATAAVAIL_MODE (1 << 4) /* data avail generates an interrupt */ -+#define CC_XMTDATAAVAIL_CTRL (1 << 5) /* data avail interrupt ctrl */ -+ -+/* corestatus */ -+#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */ -+#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */ -+#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */ -+ -+#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */ -+#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */ -+#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */ -+#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */ -+ -+/* intstatus */ -+#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ -+#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ -+#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ -+#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ -+#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ -+#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ -+#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ -+#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ -+#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ -+#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ -+#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ -+#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ -+#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ -+#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ -+#define I_PC (1 << 10) /* descriptor error */ -+#define I_PD (1 << 11) /* data error */ -+#define I_DE (1 << 12) /* Descriptor protocol Error */ -+#define I_RU (1 << 13) /* Receive descriptor Underflow */ -+#define I_RO (1 << 14) /* Receive fifo Overflow */ -+#define I_XU (1 << 15) /* Transmit fifo Underflow */ -+#define I_RI (1 << 16) /* Receive Interrupt */ -+#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ -+#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */ -+#define I_XI (1 << 24) /* Transmit Interrupt */ -+#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ -+#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ -+#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ -+#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ -+#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */ -+#define I_SRESET (1 << 30) /* CCCR RES interrupt */ -+#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ -+#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */ -+#define I_DMA (I_RI | I_XI | I_ERRORS) -+ -+/* sbintstatus */ -+#define I_SB_SERR (1 << 8) /* Backplane SError (write) */ -+#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */ -+#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */ -+ -+/* sdioaccess */ -+#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */ -+#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */ -+#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */ -+#define SDA_WRITE 0x01000000 /* Write bit */ -+#define SDA_READ 0x00000000 /* Write bit cleared for Read */ -+#define SDA_BUSY 0x80000000 /* Busy bit */ -+ -+/* sdioaccess-accessible register address spaces */ -+#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */ -+#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */ -+#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */ -+#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */ -+ -+/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */ -+#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */ -+#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */ -+#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */ -+#define SDA_DEVICECONTROL 0x009 /* DeviceControl */ -+#define SDA_SBADDRLOW 0x00a /* SbAddrLow */ -+#define SDA_SBADDRMID 0x00b /* SbAddrMid */ -+#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */ -+#define SDA_FRAMECTRL 0x00d /* FrameCtrl */ -+#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */ -+#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */ -+#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */ -+#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */ -+#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */ -+#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */ -+ -+/* SDA_F2WATERMARK */ -+#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */ -+ -+/* SDA_SBADDRLOW */ -+#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */ -+ -+/* SDA_SBADDRMID */ -+#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */ -+ -+/* SDA_SBADDRHIGH */ -+#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */ -+ -+/* SDA_FRAMECTRL */ -+#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -+#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -+#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */ -+#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */ -+ -+/* pcmciaframectrl */ -+#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -+#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -+ -+/* intrcvlazy */ -+#define IRL_TO_MASK 0x00ffffff /* timeout */ -+#define IRL_FC_MASK 0xff000000 /* frame count */ -+#define IRL_FC_SHIFT 24 /* frame count */ -+ -+/* rx header */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+} sdpcmd_rxh_t; -+ -+/* rx header flags */ -+#define RXF_CRC 0x0001 /* CRC error detected */ -+#define RXF_WOOS 0x0002 /* write frame out of sync */ -+#define RXF_WF_TERM 0x0004 /* write frame terminated */ -+#define RXF_ABORT 0x0008 /* write frame aborted */ -+#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */ -+ -+/* HW frame tag */ -+#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ -+ -+#define SDPCM_HWEXT_LEN 8 -+ -+#endif /* _sbsdpcmdev_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/sbsocram.h b/drivers/net/wireless/ap6210/include/sbsocram.h -new file mode 100644 -index 0000000..6455f2b ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sbsocram.h -@@ -0,0 +1,199 @@ -+/* -+ * BCM47XX Sonics SiliconBackplane embedded ram core -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $ -+ */ -+ -+#ifndef _SBSOCRAM_H -+#define _SBSOCRAM_H -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* Memcsocram core registers */ -+typedef volatile struct sbsocramregs { -+ uint32 coreinfo; -+ uint32 bwalloc; -+ uint32 extracoreinfo; -+ uint32 biststat; -+ uint32 bankidx; -+ uint32 standbyctrl; -+ -+ uint32 errlogstatus; /* rev 6 */ -+ uint32 errlogaddr; /* rev 6 */ -+ /* used for patching rev 3 & 5 */ -+ uint32 cambankidx; -+ uint32 cambankstandbyctrl; -+ uint32 cambankpatchctrl; -+ uint32 cambankpatchtblbaseaddr; -+ uint32 cambankcmdreg; -+ uint32 cambankdatareg; -+ uint32 cambankmaskreg; -+ uint32 PAD[1]; -+ uint32 bankinfo; /* corev 8 */ -+ uint32 PAD[15]; -+ uint32 extmemconfig; -+ uint32 extmemparitycsr; -+ uint32 extmemparityerrdata; -+ uint32 extmemparityerrcnt; -+ uint32 extmemwrctrlandsize; -+ uint32 PAD[84]; -+ uint32 workaround; -+ uint32 pwrctl; /* corerev >= 2 */ -+ uint32 PAD[133]; -+ uint32 sr_control; /* corerev >= 15 */ -+ uint32 sr_status; /* corerev >= 15 */ -+ uint32 sr_address; /* corerev >= 15 */ -+ uint32 sr_data; /* corerev >= 15 */ -+} sbsocramregs_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* Register offsets */ -+#define SR_COREINFO 0x00 -+#define SR_BWALLOC 0x04 -+#define SR_BISTSTAT 0x0c -+#define SR_BANKINDEX 0x10 -+#define SR_BANKSTBYCTL 0x14 -+#define SR_PWRCTL 0x1e8 -+ -+/* Coreinfo register */ -+#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ -+#define SRCI_PT_SHIFT 16 -+/* port types : SRCI_PT__ */ -+#define SRCI_PT_OCP_OCP 0 -+#define SRCI_PT_AXI_OCP 1 -+#define SRCI_PT_ARM7AHB_OCP 2 -+#define SRCI_PT_CM3AHB_OCP 3 -+#define SRCI_PT_AXI_AXI 4 -+#define SRCI_PT_AHB_AXI 5 -+/* corerev >= 3 */ -+#define SRCI_LSS_MASK 0x00f00000 -+#define SRCI_LSS_SHIFT 20 -+#define SRCI_LRS_MASK 0x0f000000 -+#define SRCI_LRS_SHIFT 24 -+ -+/* In corerev 0, the memory size is 2 to the power of the -+ * base plus 16 plus to the contents of the memsize field plus 1. -+ */ -+#define SRCI_MS0_MASK 0xf -+#define SR_MS0_BASE 16 -+ -+/* -+ * In corerev 1 the bank size is 2 ^ the bank size field plus 14, -+ * the memory size is number of banks times bank size. -+ * The same applies to rom size. -+ */ -+#define SRCI_ROMNB_MASK 0xf000 -+#define SRCI_ROMNB_SHIFT 12 -+#define SRCI_ROMBSZ_MASK 0xf00 -+#define SRCI_ROMBSZ_SHIFT 8 -+#define SRCI_SRNB_MASK 0xf0 -+#define SRCI_SRNB_SHIFT 4 -+#define SRCI_SRBSZ_MASK 0xf -+#define SRCI_SRBSZ_SHIFT 0 -+ -+#define SR_BSZ_BASE 14 -+ -+/* Standby control register */ -+#define SRSC_SBYOVR_MASK 0x80000000 -+#define SRSC_SBYOVR_SHIFT 31 -+#define SRSC_SBYOVRVAL_MASK 0x60000000 -+#define SRSC_SBYOVRVAL_SHIFT 29 -+#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ -+#define SRSC_SBYEN_SHIFT 24 -+ -+/* Power control register */ -+#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ -+#define SRPC_PMU_STBYDIS_SHIFT 4 -+#define SRPC_STBYOVRVAL_MASK 0x00000008 -+#define SRPC_STBYOVRVAL_SHIFT 3 -+#define SRPC_STBYOVR_MASK 0x00000007 -+#define SRPC_STBYOVR_SHIFT 0 -+ -+/* Extra core capability register */ -+#define SRECC_NUM_BANKS_MASK 0x000000F0 -+#define SRECC_NUM_BANKS_SHIFT 4 -+#define SRECC_BANKSIZE_MASK 0x0000000F -+#define SRECC_BANKSIZE_SHIFT 0 -+ -+#define SRECC_BANKSIZE(value) (1 << (value)) -+ -+/* CAM bank patch control */ -+#define SRCBPC_PATCHENABLE 0x80000000 -+ -+#define SRP_ADDRESS 0x0001FFFC -+#define SRP_VALID 0x8000 -+ -+/* CAM bank command reg */ -+#define SRCMD_WRITE 0x00020000 -+#define SRCMD_READ 0x00010000 -+#define SRCMD_DONE 0x80000000 -+ -+#define SRCMD_DONE_DLY 1000 -+ -+/* bankidx and bankinfo reg defines corerev >= 8 */ -+#define SOCRAM_BANKINFO_SZMASK 0x7f -+#define SOCRAM_BANKIDX_ROM_MASK 0x100 -+ -+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 -+/* socram bankinfo memtype */ -+#define SOCRAM_MEMTYPE_RAM 0 -+#define SOCRAM_MEMTYPE_R0M 1 -+#define SOCRAM_MEMTYPE_DEVRAM 2 -+ -+#define SOCRAM_BANKINFO_REG 0x40 -+#define SOCRAM_BANKIDX_REG 0x10 -+#define SOCRAM_BANKINFO_STDBY_MASK 0x400 -+#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 -+ -+/* bankinfo rev >= 10 */ -+#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -+#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -+#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -+#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 -+#define SOCRAM_BANKINFO_SLPSUPP_SHIFT 15 -+#define SOCRAM_BANKINFO_SLPSUPP_MASK 0x8000 -+#define SOCRAM_BANKINFO_RETNTRAM_SHIFT 16 -+#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 -+#define SOCRAM_BANKINFO_PDASZ_SHIFT 17 -+#define SOCRAM_BANKINFO_PDASZ_MASK 0x003E0000 -+#define SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT 24 -+#define SOCRAM_BANKINFO_DEVRAMREMAP_MASK 0x01000000 -+ -+/* extracoreinfo register */ -+#define SOCRAM_DEVRAMBANK_MASK 0xF000 -+#define SOCRAM_DEVRAMBANK_SHIFT 12 -+ -+/* bank info to calculate bank size */ -+#define SOCRAM_BANKINFO_SZBASE 8192 -+#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ -+ -+ -+#endif /* _SBSOCRAM_H */ -diff --git a/drivers/net/wireless/ap6210/include/sdio.h b/drivers/net/wireless/ap6210/include/sdio.h -new file mode 100644 -index 0000000..b8eee1f ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sdio.h -@@ -0,0 +1,617 @@ -+/* -+ * SDIO spec header file -+ * Protocol and standard (common) device definitions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sdio.h 308973 2012-01-18 04:19:34Z $ -+ */ -+ -+#ifndef _SDIO_H -+#define _SDIO_H -+ -+ -+/* CCCR structure for function 0 */ -+typedef volatile struct { -+ uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */ -+ uint8 sd_rev; /* RO, sd spec revision */ -+ uint8 io_en; /* I/O enable */ -+ uint8 io_rdy; /* I/O ready reg */ -+ uint8 intr_ctl; /* Master and per function interrupt enable control */ -+ uint8 intr_status; /* RO, interrupt pending status */ -+ uint8 io_abort; /* read/write abort or reset all functions */ -+ uint8 bus_inter; /* bus interface control */ -+ uint8 capability; /* RO, card capability */ -+ -+ uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */ -+ uint8 cis_base_mid; -+ uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */ -+ -+ /* suspend/resume registers */ -+ uint8 bus_suspend; /* 0xC */ -+ uint8 func_select; /* 0xD */ -+ uint8 exec_flag; /* 0xE */ -+ uint8 ready_flag; /* 0xF */ -+ -+ uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */ -+ -+ uint8 power_control; /* 0x12 (SDIO version 1.10) */ -+ -+ uint8 speed_control; /* 0x13 */ -+} sdio_regs_t; -+ -+/* SDIO Device CCCR offsets */ -+#define SDIOD_CCCR_REV 0x00 -+#define SDIOD_CCCR_SDREV 0x01 -+#define SDIOD_CCCR_IOEN 0x02 -+#define SDIOD_CCCR_IORDY 0x03 -+#define SDIOD_CCCR_INTEN 0x04 -+#define SDIOD_CCCR_INTPEND 0x05 -+#define SDIOD_CCCR_IOABORT 0x06 -+#define SDIOD_CCCR_BICTRL 0x07 -+#define SDIOD_CCCR_CAPABLITIES 0x08 -+#define SDIOD_CCCR_CISPTR_0 0x09 -+#define SDIOD_CCCR_CISPTR_1 0x0A -+#define SDIOD_CCCR_CISPTR_2 0x0B -+#define SDIOD_CCCR_BUSSUSP 0x0C -+#define SDIOD_CCCR_FUNCSEL 0x0D -+#define SDIOD_CCCR_EXECFLAGS 0x0E -+#define SDIOD_CCCR_RDYFLAGS 0x0F -+#define SDIOD_CCCR_BLKSIZE_0 0x10 -+#define SDIOD_CCCR_BLKSIZE_1 0x11 -+#define SDIOD_CCCR_POWER_CONTROL 0x12 -+#define SDIOD_CCCR_SPEED_CONTROL 0x13 -+#define SDIOD_CCCR_UHSI_SUPPORT 0x14 -+#define SDIOD_CCCR_DRIVER_STRENGTH 0x15 -+#define SDIOD_CCCR_INTR_EXTN 0x16 -+ -+/* Broadcom extensions (corerev >= 1) */ -+#define SDIOD_CCCR_BRCM_CARDCAP 0xf0 -+#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 -+#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 -+#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 -+#define SDIOD_CCCR_BRCM_CARDCTL 0xf1 -+#define SDIOD_CCCR_BRCM_SEPINT 0xf2 -+ -+/* cccr_sdio_rev */ -+#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ -+#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ -+ -+/* sd_rev */ -+#define SD_REV_PHY_MASK 0x0f /* SD format version number */ -+ -+/* io_en */ -+#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ -+#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */ -+ -+/* io_rdys */ -+#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ -+#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */ -+ -+/* intr_ctl */ -+#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ -+#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ -+#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */ -+ -+/* intr_status */ -+#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ -+#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */ -+ -+/* io_abort */ -+#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ -+#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */ -+ -+/* bus_inter */ -+#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ -+#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ -+#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ -+#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */ -+#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ -+#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ -+ -+/* capability */ -+#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ -+#define SDIO_CAP_LSC 0x40 /* low speed card */ -+#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */ -+#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */ -+#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ -+#define SDIO_CAP_SRW 0x04 /* support read wait */ -+#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ -+#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */ -+ -+/* power_control */ -+#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */ -+#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */ -+ -+/* speed_control (control device entry into high-speed clocking mode) */ -+#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */ -+#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */ -+ -+/* for setting bus speed in card: 0x13h */ -+#define SDIO_BUS_SPEED_UHSISEL_M BITFIELD_MASK(3) -+#define SDIO_BUS_SPEED_UHSISEL_S 1 -+ -+/* for getting bus speed cap in card: 0x14h */ -+#define SDIO_BUS_SPEED_UHSICAP_M BITFIELD_MASK(3) -+#define SDIO_BUS_SPEED_UHSICAP_S 0 -+ -+/* for getting driver type CAP in card: 0x15h */ -+#define SDIO_BUS_DRVR_TYPE_CAP_M BITFIELD_MASK(3) -+#define SDIO_BUS_DRVR_TYPE_CAP_S 0 -+ -+/* for setting driver type selection in card: 0x15h */ -+#define SDIO_BUS_DRVR_TYPE_SEL_M BITFIELD_MASK(2) -+#define SDIO_BUS_DRVR_TYPE_SEL_S 4 -+ -+/* for getting async int support in card: 0x16h */ -+#define SDIO_BUS_ASYNCINT_CAP_M BITFIELD_MASK(1) -+#define SDIO_BUS_ASYNCINT_CAP_S 0 -+ -+/* for setting async int selection in card: 0x16h */ -+#define SDIO_BUS_ASYNCINT_SEL_M BITFIELD_MASK(1) -+#define SDIO_BUS_ASYNCINT_SEL_S 1 -+ -+/* brcm sepint */ -+#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */ -+#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */ -+#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */ -+ -+/* FBR structure for function 1-7, FBR addresses and register offsets */ -+typedef volatile struct { -+ uint8 devctr; /* device interface, CSA control */ -+ uint8 ext_dev; /* extended standard I/O device type code */ -+ uint8 pwr_sel; /* power selection support */ -+ uint8 PAD[6]; /* reserved */ -+ -+ uint8 cis_low; /* CIS LSB */ -+ uint8 cis_mid; -+ uint8 cis_high; /* CIS MSB */ -+ uint8 csa_low; /* code storage area, LSB */ -+ uint8 csa_mid; -+ uint8 csa_high; /* code storage area, MSB */ -+ uint8 csa_dat_win; /* data access window to function */ -+ -+ uint8 fnx_blk_size[2]; /* block size, little endian */ -+} sdio_fbr_t; -+ -+/* Maximum number of I/O funcs */ -+#define SDIOD_MAX_FUNCS 8 -+#define SDIOD_MAX_IOFUNCS 7 -+ -+/* SDIO Device FBR Start Address */ -+#define SDIOD_FBR_STARTADDR 0x100 -+ -+/* SDIO Device FBR Size */ -+#define SDIOD_FBR_SIZE 0x100 -+ -+/* Macro to calculate FBR register base */ -+#define SDIOD_FBR_BASE(n) ((n) * 0x100) -+ -+/* Function register offsets */ -+#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */ -+#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */ -+#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */ -+ -+/* SDIO Function CIS ptr offset */ -+#define SDIOD_FBR_CISPTR_0 0x09 -+#define SDIOD_FBR_CISPTR_1 0x0A -+#define SDIOD_FBR_CISPTR_2 0x0B -+ -+/* Code Storage Area pointer */ -+#define SDIOD_FBR_CSA_ADDR_0 0x0C -+#define SDIOD_FBR_CSA_ADDR_1 0x0D -+#define SDIOD_FBR_CSA_ADDR_2 0x0E -+#define SDIOD_FBR_CSA_DATA 0x0F -+ -+/* SDIO Function I/O Block Size */ -+#define SDIOD_FBR_BLKSIZE_0 0x10 -+#define SDIOD_FBR_BLKSIZE_1 0x11 -+ -+/* devctr */ -+#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */ -+#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */ -+#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */ -+/* interface codes */ -+#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */ -+#define SDIOD_DIC_UART 1 -+#define SDIOD_DIC_BLUETOOTH_A 2 -+#define SDIOD_DIC_BLUETOOTH_B 3 -+#define SDIOD_DIC_GPS 4 -+#define SDIOD_DIC_CAMERA 5 -+#define SDIOD_DIC_PHS 6 -+#define SDIOD_DIC_WLAN 7 -+#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */ -+ -+/* pwr_sel */ -+#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */ -+#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */ -+ -+/* misc defines */ -+#define SDIO_FUNC_0 0 -+#define SDIO_FUNC_1 1 -+#define SDIO_FUNC_2 2 -+#define SDIO_FUNC_3 3 -+#define SDIO_FUNC_4 4 -+#define SDIO_FUNC_5 5 -+#define SDIO_FUNC_6 6 -+#define SDIO_FUNC_7 7 -+ -+#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */ -+#define SD_CARD_TYPE_IO 1 /* IO only card */ -+#define SD_CARD_TYPE_MEMORY 2 /* memory only card */ -+#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */ -+ -+#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */ -+#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */ -+ -+/* Card registers: status bit position */ -+#define CARDREG_STATUS_BIT_OUTOFRANGE 31 -+#define CARDREG_STATUS_BIT_COMCRCERROR 23 -+#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22 -+#define CARDREG_STATUS_BIT_ERROR 19 -+#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12 -+#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11 -+#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10 -+#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9 -+#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4 -+ -+ -+ -+#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ -+#define SD_CMD_SEND_OPCOND 1 -+#define SD_CMD_MMC_SET_RCA 3 -+#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ -+#define SD_CMD_SELECT_DESELECT_CARD 7 -+#define SD_CMD_SEND_CSD 9 -+#define SD_CMD_SEND_CID 10 -+#define SD_CMD_STOP_TRANSMISSION 12 -+#define SD_CMD_SEND_STATUS 13 -+#define SD_CMD_GO_INACTIVE_STATE 15 -+#define SD_CMD_SET_BLOCKLEN 16 -+#define SD_CMD_READ_SINGLE_BLOCK 17 -+#define SD_CMD_READ_MULTIPLE_BLOCK 18 -+#define SD_CMD_WRITE_BLOCK 24 -+#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 -+#define SD_CMD_PROGRAM_CSD 27 -+#define SD_CMD_SET_WRITE_PROT 28 -+#define SD_CMD_CLR_WRITE_PROT 29 -+#define SD_CMD_SEND_WRITE_PROT 30 -+#define SD_CMD_ERASE_WR_BLK_START 32 -+#define SD_CMD_ERASE_WR_BLK_END 33 -+#define SD_CMD_ERASE 38 -+#define SD_CMD_LOCK_UNLOCK 42 -+#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ -+#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ -+#define SD_CMD_APP_CMD 55 -+#define SD_CMD_GEN_CMD 56 -+#define SD_CMD_READ_OCR 58 -+#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ -+#define SD_ACMD_SD_STATUS 13 -+#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 -+#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 -+#define SD_ACMD_SD_SEND_OP_COND 41 -+#define SD_ACMD_SET_CLR_CARD_DETECT 42 -+#define SD_ACMD_SEND_SCR 51 -+ -+/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ -+#define SD_IO_OP_READ 0 /* Read_Write: Read */ -+#define SD_IO_OP_WRITE 1 /* Read_Write: Write */ -+#define SD_IO_RW_NORMAL 0 /* no RAW */ -+#define SD_IO_RW_RAW 1 /* RAW */ -+#define SD_IO_BYTE_MODE 0 /* Byte Mode */ -+#define SD_IO_BLOCK_MODE 1 /* BlockMode */ -+#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ -+#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */ -+ -+/* build SD_CMD_IO_RW_DIRECT Argument */ -+#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \ -+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \ -+ (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF)) -+ -+/* build SD_CMD_IO_RW_EXTENDED Argument */ -+#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \ -+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \ -+ (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF)) -+ -+/* SDIO response parameters */ -+#define SD_RSP_NO_NONE 0 -+#define SD_RSP_NO_1 1 -+#define SD_RSP_NO_2 2 -+#define SD_RSP_NO_3 3 -+#define SD_RSP_NO_4 4 -+#define SD_RSP_NO_5 5 -+#define SD_RSP_NO_6 6 -+ -+ /* Modified R6 response (to CMD3) */ -+#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 -+#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 -+#define SD_RSP_MR6_ERROR 0x2000 -+ -+ /* Modified R1 in R4 Response (to CMD5) */ -+#define SD_RSP_MR1_SBIT 0x80 -+#define SD_RSP_MR1_PARAMETER_ERROR 0x40 -+#define SD_RSP_MR1_RFU5 0x20 -+#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 -+#define SD_RSP_MR1_COM_CRC_ERROR 0x08 -+#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04 -+#define SD_RSP_MR1_RFU1 0x02 -+#define SD_RSP_MR1_IDLE_STATE 0x01 -+ -+ /* R5 response (to CMD52 and CMD53) */ -+#define SD_RSP_R5_COM_CRC_ERROR 0x80 -+#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 -+#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 -+#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 -+#define SD_RSP_R5_ERROR 0x08 -+#define SD_RSP_R5_RFU 0x04 -+#define SD_RSP_R5_FUNC_NUM_ERROR 0x02 -+#define SD_RSP_R5_OUT_OF_RANGE 0x01 -+ -+#define SD_RSP_R5_ERRBITS 0xCB -+ -+ -+/* ------------------------------------------------ -+ * SDIO Commands and responses -+ * -+ * I/O only commands are: -+ * CMD0, CMD3, CMD5, CMD7, CMD14, CMD15, CMD52, CMD53 -+ * ------------------------------------------------ -+ */ -+ -+/* SDIO Commands */ -+#define SDIOH_CMD_0 0 -+#define SDIOH_CMD_3 3 -+#define SDIOH_CMD_5 5 -+#define SDIOH_CMD_7 7 -+#define SDIOH_CMD_11 11 -+#define SDIOH_CMD_14 14 -+#define SDIOH_CMD_15 15 -+#define SDIOH_CMD_19 19 -+#define SDIOH_CMD_52 52 -+#define SDIOH_CMD_53 53 -+#define SDIOH_CMD_59 59 -+ -+/* SDIO Command Responses */ -+#define SDIOH_RSP_NONE 0 -+#define SDIOH_RSP_R1 1 -+#define SDIOH_RSP_R2 2 -+#define SDIOH_RSP_R3 3 -+#define SDIOH_RSP_R4 4 -+#define SDIOH_RSP_R5 5 -+#define SDIOH_RSP_R6 6 -+ -+/* -+ * SDIO Response Error flags -+ */ -+#define SDIOH_RSP5_ERROR_FLAGS 0xCB -+ -+/* ------------------------------------------------ -+ * SDIO Command structures. I/O only commands are: -+ * -+ * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 -+ * ------------------------------------------------ -+ */ -+ -+#define CMD5_OCR_M BITFIELD_MASK(24) -+#define CMD5_OCR_S 0 -+ -+#define CMD5_S18R_M BITFIELD_MASK(1) -+#define CMD5_S18R_S 24 -+ -+#define CMD7_RCA_M BITFIELD_MASK(16) -+#define CMD7_RCA_S 16 -+ -+#define CMD14_RCA_M BITFIELD_MASK(16) -+#define CMD14_RCA_S 16 -+#define CMD14_SLEEP_M BITFIELD_MASK(1) -+#define CMD14_SLEEP_S 15 -+ -+#define CMD_15_RCA_M BITFIELD_MASK(16) -+#define CMD_15_RCA_S 16 -+ -+#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52 -+ */ -+#define CMD52_DATA_S 0 -+#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -+#define CMD52_REG_ADDR_S 9 -+#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */ -+#define CMD52_RAW_S 27 -+#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -+#define CMD52_FUNCTION_S 28 -+#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -+#define CMD52_RW_FLAG_S 31 -+ -+ -+#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */ -+#define CMD53_BYTE_BLK_CNT_S 0 -+#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -+#define CMD53_REG_ADDR_S 9 -+#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */ -+#define CMD53_OP_CODE_S 26 -+#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */ -+#define CMD53_BLK_MODE_S 27 -+#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -+#define CMD53_FUNCTION_S 28 -+#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -+#define CMD53_RW_FLAG_S 31 -+ -+/* ------------------------------------------------------ -+ * SDIO Command Response structures for SD1 and SD4 modes -+ * ----------------------------------------------------- -+ */ -+#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */ -+#define RSP4_IO_OCR_S 0 -+ -+#define RSP4_S18A_M BITFIELD_MASK(1) /* Bits [23:0] - Card's OCR Bits [23:0] */ -+#define RSP4_S18A_S 24 -+ -+#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */ -+#define RSP4_STUFF_S 24 -+#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */ -+#define RSP4_MEM_PRESENT_S 27 -+#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */ -+#define RSP4_NUM_FUNCS_S 28 -+#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */ -+#define RSP4_CARD_READY_S 31 -+ -+#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0] -+ */ -+#define RSP6_STATUS_S 0 -+#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */ -+#define RSP6_IO_RCA_S 16 -+ -+#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */ -+#define RSP1_AKE_SEQ_ERROR_S 3 -+#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -+#define RSP1_APP_CMD_S 5 -+#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */ -+#define RSP1_READY_FOR_DATA_S 8 -+#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card -+ * when Cmd was received -+ */ -+#define RSP1_CURR_STATE_S 9 -+#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */ -+#define RSP1_EARSE_RESET_S 13 -+#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */ -+#define RSP1_CARD_ECC_DISABLE_S 14 -+#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */ -+#define RSP1_WP_ERASE_SKIP_S 15 -+#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits -+ * of CSD -+ */ -+#define RSP1_CID_CSD_OVERW_S 16 -+#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */ -+#define RSP1_ERROR_S 19 -+#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */ -+#define RSP1_CC_ERROR_S 20 -+#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed -+ * to correct data -+ */ -+#define RSP1_CARD_ECC_FAILED_S 21 -+#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */ -+#define RSP1_ILLEGAL_CMD_S 22 -+#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed -+ */ -+#define RSP1_COM_CRC_ERROR_S 23 -+#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */ -+#define RSP1_LOCK_UNLOCK_FAIL_S 24 -+#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */ -+#define RSP1_CARD_LOCKED_S 25 -+#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program -+ * write-protected blocks -+ */ -+#define RSP1_WP_VIOLATION_S 26 -+#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */ -+#define RSP1_ERASE_PARAM_S 27 -+#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */ -+#define RSP1_ERASE_SEQ_ERR_S 28 -+#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */ -+#define RSP1_BLK_LEN_ERR_S 29 -+#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */ -+#define RSP1_ADDR_ERR_S 30 -+#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */ -+#define RSP1_OUT_OF_RANGE_S 31 -+ -+ -+#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */ -+#define RSP5_DATA_S 0 -+#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */ -+#define RSP5_FLAGS_S 8 -+#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */ -+#define RSP5_STUFF_S 16 -+ -+/* ---------------------------------------------- -+ * SDIO Command Response structures for SPI mode -+ * ---------------------------------------------- -+ */ -+#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */ -+#define SPIRSP4_IO_OCR_S 0 -+#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */ -+#define SPIRSP4_STUFF_S 16 -+#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */ -+#define SPIRSP4_MEM_PRESENT_S 19 -+#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */ -+#define SPIRSP4_NUM_FUNCS_S 20 -+#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */ -+#define SPIRSP4_CARD_READY_S 23 -+#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */ -+#define SPIRSP4_IDLE_STATE_S 24 -+#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -+#define SPIRSP4_ILLEGAL_CMD_S 26 -+#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -+#define SPIRSP4_COM_CRC_ERROR_S 27 -+#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error -+ */ -+#define SPIRSP4_FUNC_NUM_ERROR_S 28 -+#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -+#define SPIRSP4_PARAM_ERROR_S 30 -+#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -+#define SPIRSP4_START_BIT_S 31 -+ -+#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */ -+#define SPIRSP5_DATA_S 16 -+#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */ -+#define SPIRSP5_IDLE_STATE_S 24 -+#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -+#define SPIRSP5_ILLEGAL_CMD_S 26 -+#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -+#define SPIRSP5_COM_CRC_ERROR_S 27 -+#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error -+ */ -+#define SPIRSP5_FUNC_NUM_ERROR_S 28 -+#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -+#define SPIRSP5_PARAM_ERROR_S 30 -+#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -+#define SPIRSP5_START_BIT_S 31 -+ -+/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */ -+#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error -+ */ -+#define RSP6STAT_AKE_SEQ_ERROR_S 3 -+#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -+#define RSP6STAT_APP_CMD_S 5 -+#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data -+ * (buff empty) -+ */ -+#define RSP6STAT_READY_FOR_DATA_S 8 -+#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at -+ * Cmd reception -+ */ -+#define RSP6STAT_CURR_STATE_S 9 -+#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19 -+ */ -+#define RSP6STAT_ERROR_S 13 -+#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for -+ * card state Bit 22 -+ */ -+#define RSP6STAT_ILLEGAL_CMD_S 14 -+#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command -+ * failed Bit 23 -+ */ -+#define RSP6STAT_COM_CRC_ERROR_S 15 -+ -+#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ -+#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE -+ -+/* command issue options */ -+#define CMD_OPTION_DEFAULT 0 -+#define CMD_OPTION_TUNING 1 -+#endif /* _SDIO_H */ -diff --git a/drivers/net/wireless/ap6210/include/sdioh.h b/drivers/net/wireless/ap6210/include/sdioh.h -new file mode 100644 -index 0000000..5517a71 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sdioh.h -@@ -0,0 +1,445 @@ -+/* -+ * SDIO Host Controller Spec header file -+ * Register map and definitions for the Standard Host Controller -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sdioh.h 347633 2012-07-27 11:02:02Z $ -+ */ -+ -+#ifndef _SDIOH_H -+#define _SDIOH_H -+ -+#define SD_SysAddr 0x000 -+#define SD_BlockSize 0x004 -+#define SD_BlockCount 0x006 -+#define SD_Arg0 0x008 -+#define SD_Arg1 0x00A -+#define SD_TransferMode 0x00C -+#define SD_Command 0x00E -+#define SD_Response0 0x010 -+#define SD_Response1 0x012 -+#define SD_Response2 0x014 -+#define SD_Response3 0x016 -+#define SD_Response4 0x018 -+#define SD_Response5 0x01A -+#define SD_Response6 0x01C -+#define SD_Response7 0x01E -+#define SD_BufferDataPort0 0x020 -+#define SD_BufferDataPort1 0x022 -+#define SD_PresentState 0x024 -+#define SD_HostCntrl 0x028 -+#define SD_PwrCntrl 0x029 -+#define SD_BlockGapCntrl 0x02A -+#define SD_WakeupCntrl 0x02B -+#define SD_ClockCntrl 0x02C -+#define SD_TimeoutCntrl 0x02E -+#define SD_SoftwareReset 0x02F -+#define SD_IntrStatus 0x030 -+#define SD_ErrorIntrStatus 0x032 -+#define SD_IntrStatusEnable 0x034 -+#define SD_ErrorIntrStatusEnable 0x036 -+#define SD_IntrSignalEnable 0x038 -+#define SD_ErrorIntrSignalEnable 0x03A -+#define SD_CMD12ErrorStatus 0x03C -+#define SD_Capabilities 0x040 -+#define SD_Capabilities3 0x044 -+#define SD_MaxCurCap 0x048 -+#define SD_MaxCurCap_Reserved 0x04C -+#define SD_ADMA_ErrStatus 0x054 -+#define SD_ADMA_SysAddr 0x58 -+#define SD_SlotInterruptStatus 0x0FC -+#define SD_HostControllerVersion 0x0FE -+#define SD_GPIO_Reg 0x100 -+#define SD_GPIO_OE 0x104 -+#define SD_GPIO_Enable 0x108 -+ -+/* SD specific registers in PCI config space */ -+#define SD_SlotInfo 0x40 -+ -+/* HC 3.0 specific registers and offsets */ -+#define SD3_HostCntrl2 0x03E -+/* preset regsstart and count */ -+#define SD3_PresetValStart 0x060 -+#define SD3_PresetValCount 8 -+/* preset-indiv regs */ -+#define SD3_PresetVal_init 0x060 -+#define SD3_PresetVal_default 0x062 -+#define SD3_PresetVal_HS 0x064 -+#define SD3_PresetVal_SDR12 0x066 -+#define SD3_PresetVal_SDR25 0x068 -+#define SD3_PresetVal_SDR50 0x06a -+#define SD3_PresetVal_SDR104 0x06c -+#define SD3_PresetVal_DDR50 0x06e -+/* SDIO3.0 Revx specific Registers */ -+#define SD3_Tuning_Info_Register 0x0EC -+#define SD3_WL_BT_reset_register 0x0F0 -+ -+ -+/* preset value indices */ -+#define SD3_PRESETVAL_INITIAL_IX 0 -+#define SD3_PRESETVAL_DESPEED_IX 1 -+#define SD3_PRESETVAL_HISPEED_IX 2 -+#define SD3_PRESETVAL_SDR12_IX 3 -+#define SD3_PRESETVAL_SDR25_IX 4 -+#define SD3_PRESETVAL_SDR50_IX 5 -+#define SD3_PRESETVAL_SDR104_IX 6 -+#define SD3_PRESETVAL_DDR50_IX 7 -+ -+/* SD_Capabilities reg (0x040) */ -+#define CAP_TO_CLKFREQ_M BITFIELD_MASK(6) -+#define CAP_TO_CLKFREQ_S 0 -+#define CAP_TO_CLKUNIT_M BITFIELD_MASK(1) -+#define CAP_TO_CLKUNIT_S 7 -+/* Note: for sdio-2.0 case, this mask has to be 6 bits, but msb 2 -+ bits are reserved. going ahead with 8 bits, as it is req for 3.0 -+*/ -+#define CAP_BASECLK_M BITFIELD_MASK(8) -+#define CAP_BASECLK_S 8 -+#define CAP_MAXBLOCK_M BITFIELD_MASK(2) -+#define CAP_MAXBLOCK_S 16 -+#define CAP_ADMA2_M BITFIELD_MASK(1) -+#define CAP_ADMA2_S 19 -+#define CAP_ADMA1_M BITFIELD_MASK(1) -+#define CAP_ADMA1_S 20 -+#define CAP_HIGHSPEED_M BITFIELD_MASK(1) -+#define CAP_HIGHSPEED_S 21 -+#define CAP_DMA_M BITFIELD_MASK(1) -+#define CAP_DMA_S 22 -+#define CAP_SUSPEND_M BITFIELD_MASK(1) -+#define CAP_SUSPEND_S 23 -+#define CAP_VOLT_3_3_M BITFIELD_MASK(1) -+#define CAP_VOLT_3_3_S 24 -+#define CAP_VOLT_3_0_M BITFIELD_MASK(1) -+#define CAP_VOLT_3_0_S 25 -+#define CAP_VOLT_1_8_M BITFIELD_MASK(1) -+#define CAP_VOLT_1_8_S 26 -+#define CAP_64BIT_HOST_M BITFIELD_MASK(1) -+#define CAP_64BIT_HOST_S 28 -+ -+#define SDIO_OCR_READ_FAIL (2) -+ -+ -+#define CAP_ASYNCINT_SUP_M BITFIELD_MASK(1) -+#define CAP_ASYNCINT_SUP_S 29 -+ -+#define CAP_SLOTTYPE_M BITFIELD_MASK(2) -+#define CAP_SLOTTYPE_S 30 -+ -+#define CAP3_MSBits_OFFSET (32) -+/* note: following are caps MSB32 bits. -+ So the bits start from 0, instead of 32. that is why -+ CAP3_MSBits_OFFSET is subtracted. -+*/ -+#define CAP3_SDR50_SUP_M BITFIELD_MASK(1) -+#define CAP3_SDR50_SUP_S (32 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_SDR104_SUP_M BITFIELD_MASK(1) -+#define CAP3_SDR104_SUP_S (33 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_DDR50_SUP_M BITFIELD_MASK(1) -+#define CAP3_DDR50_SUP_S (34 - CAP3_MSBits_OFFSET) -+ -+/* for knowing the clk caps in a single read */ -+#define CAP3_30CLKCAP_M BITFIELD_MASK(3) -+#define CAP3_30CLKCAP_S (32 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_DRIVTYPE_A_M BITFIELD_MASK(1) -+#define CAP3_DRIVTYPE_A_S (36 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_DRIVTYPE_C_M BITFIELD_MASK(1) -+#define CAP3_DRIVTYPE_C_S (37 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_DRIVTYPE_D_M BITFIELD_MASK(1) -+#define CAP3_DRIVTYPE_D_S (38 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_RETUNING_TC_M BITFIELD_MASK(4) -+#define CAP3_RETUNING_TC_S (40 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_TUNING_SDR50_M BITFIELD_MASK(1) -+#define CAP3_TUNING_SDR50_S (45 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_RETUNING_MODES_M BITFIELD_MASK(2) -+#define CAP3_RETUNING_MODES_S (46 - CAP3_MSBits_OFFSET) -+ -+#define CAP3_CLK_MULT_M BITFIELD_MASK(8) -+#define CAP3_CLK_MULT_S (48 - CAP3_MSBits_OFFSET) -+ -+#define PRESET_DRIVR_SELECT_M BITFIELD_MASK(2) -+#define PRESET_DRIVR_SELECT_S 14 -+ -+#define PRESET_CLK_DIV_M BITFIELD_MASK(10) -+#define PRESET_CLK_DIV_S 0 -+ -+/* SD_MaxCurCap reg (0x048) */ -+#define CAP_CURR_3_3_M BITFIELD_MASK(8) -+#define CAP_CURR_3_3_S 0 -+#define CAP_CURR_3_0_M BITFIELD_MASK(8) -+#define CAP_CURR_3_0_S 8 -+#define CAP_CURR_1_8_M BITFIELD_MASK(8) -+#define CAP_CURR_1_8_S 16 -+ -+/* SD_SysAddr: Offset 0x0000, Size 4 bytes */ -+ -+/* SD_BlockSize: Offset 0x004, Size 2 bytes */ -+#define BLKSZ_BLKSZ_M BITFIELD_MASK(12) -+#define BLKSZ_BLKSZ_S 0 -+#define BLKSZ_BNDRY_M BITFIELD_MASK(3) -+#define BLKSZ_BNDRY_S 12 -+ -+/* SD_BlockCount: Offset 0x006, size 2 bytes */ -+ -+/* SD_Arg0: Offset 0x008, size = 4 bytes */ -+/* SD_TransferMode Offset 0x00C, size = 2 bytes */ -+#define XFER_DMA_ENABLE_M BITFIELD_MASK(1) -+#define XFER_DMA_ENABLE_S 0 -+#define XFER_BLK_COUNT_EN_M BITFIELD_MASK(1) -+#define XFER_BLK_COUNT_EN_S 1 -+#define XFER_CMD_12_EN_M BITFIELD_MASK(1) -+#define XFER_CMD_12_EN_S 2 -+#define XFER_DATA_DIRECTION_M BITFIELD_MASK(1) -+#define XFER_DATA_DIRECTION_S 4 -+#define XFER_MULTI_BLOCK_M BITFIELD_MASK(1) -+#define XFER_MULTI_BLOCK_S 5 -+ -+/* SD_Command: Offset 0x00E, size = 2 bytes */ -+/* resp_type field */ -+#define RESP_TYPE_NONE 0 -+#define RESP_TYPE_136 1 -+#define RESP_TYPE_48 2 -+#define RESP_TYPE_48_BUSY 3 -+/* type field */ -+#define CMD_TYPE_NORMAL 0 -+#define CMD_TYPE_SUSPEND 1 -+#define CMD_TYPE_RESUME 2 -+#define CMD_TYPE_ABORT 3 -+ -+#define CMD_RESP_TYPE_M BITFIELD_MASK(2) /* Bits [0-1] - Response type */ -+#define CMD_RESP_TYPE_S 0 -+#define CMD_CRC_EN_M BITFIELD_MASK(1) /* Bit 3 - CRC enable */ -+#define CMD_CRC_EN_S 3 -+#define CMD_INDEX_EN_M BITFIELD_MASK(1) /* Bit 4 - Enable index checking */ -+#define CMD_INDEX_EN_S 4 -+#define CMD_DATA_EN_M BITFIELD_MASK(1) /* Bit 5 - Using DAT line */ -+#define CMD_DATA_EN_S 5 -+#define CMD_TYPE_M BITFIELD_MASK(2) /* Bit [6-7] - Normal, abort, resume, etc -+ */ -+#define CMD_TYPE_S 6 -+#define CMD_INDEX_M BITFIELD_MASK(6) /* Bits [8-13] - Command number */ -+#define CMD_INDEX_S 8 -+ -+/* SD_BufferDataPort0 : Offset 0x020, size = 2 or 4 bytes */ -+/* SD_BufferDataPort1 : Offset 0x022, size = 2 bytes */ -+/* SD_PresentState : Offset 0x024, size = 4 bytes */ -+#define PRES_CMD_INHIBIT_M BITFIELD_MASK(1) /* Bit 0 May use CMD */ -+#define PRES_CMD_INHIBIT_S 0 -+#define PRES_DAT_INHIBIT_M BITFIELD_MASK(1) /* Bit 1 May use DAT */ -+#define PRES_DAT_INHIBIT_S 1 -+#define PRES_DAT_BUSY_M BITFIELD_MASK(1) /* Bit 2 DAT is busy */ -+#define PRES_DAT_BUSY_S 2 -+#define PRES_PRESENT_RSVD_M BITFIELD_MASK(5) /* Bit [3-7] rsvd */ -+#define PRES_PRESENT_RSVD_S 3 -+#define PRES_WRITE_ACTIVE_M BITFIELD_MASK(1) /* Bit 8 Write is active */ -+#define PRES_WRITE_ACTIVE_S 8 -+#define PRES_READ_ACTIVE_M BITFIELD_MASK(1) /* Bit 9 Read is active */ -+#define PRES_READ_ACTIVE_S 9 -+#define PRES_WRITE_DATA_RDY_M BITFIELD_MASK(1) /* Bit 10 Write buf is avail */ -+#define PRES_WRITE_DATA_RDY_S 10 -+#define PRES_READ_DATA_RDY_M BITFIELD_MASK(1) /* Bit 11 Read buf data avail */ -+#define PRES_READ_DATA_RDY_S 11 -+#define PRES_CARD_PRESENT_M BITFIELD_MASK(1) /* Bit 16 Card present - debounced */ -+#define PRES_CARD_PRESENT_S 16 -+#define PRES_CARD_STABLE_M BITFIELD_MASK(1) /* Bit 17 Debugging */ -+#define PRES_CARD_STABLE_S 17 -+#define PRES_CARD_PRESENT_RAW_M BITFIELD_MASK(1) /* Bit 18 Not debounced */ -+#define PRES_CARD_PRESENT_RAW_S 18 -+#define PRES_WRITE_ENABLED_M BITFIELD_MASK(1) /* Bit 19 Write protected? */ -+#define PRES_WRITE_ENABLED_S 19 -+#define PRES_DAT_SIGNAL_M BITFIELD_MASK(4) /* Bit [20-23] Debugging */ -+#define PRES_DAT_SIGNAL_S 20 -+#define PRES_CMD_SIGNAL_M BITFIELD_MASK(1) /* Bit 24 Debugging */ -+#define PRES_CMD_SIGNAL_S 24 -+ -+/* SD_HostCntrl: Offset 0x028, size = 1 bytes */ -+#define HOST_LED_M BITFIELD_MASK(1) /* Bit 0 LED On/Off */ -+#define HOST_LED_S 0 -+#define HOST_DATA_WIDTH_M BITFIELD_MASK(1) /* Bit 1 4 bit enable */ -+#define HOST_DATA_WIDTH_S 1 -+#define HOST_HI_SPEED_EN_M BITFIELD_MASK(1) /* Bit 2 High speed vs low speed */ -+#define HOST_DMA_SEL_S 3 -+#define HOST_DMA_SEL_M BITFIELD_MASK(2) /* Bit 4:3 DMA Select */ -+#define HOST_HI_SPEED_EN_S 2 -+ -+/* Host Control2: */ -+#define HOSTCtrl2_PRESVAL_EN_M BITFIELD_MASK(1) /* 1 bit */ -+#define HOSTCtrl2_PRESVAL_EN_S 15 /* bit# */ -+ -+#define HOSTCtrl2_ASYINT_EN_M BITFIELD_MASK(1) /* 1 bit */ -+#define HOSTCtrl2_ASYINT_EN_S 14 /* bit# */ -+ -+#define HOSTCtrl2_SAMPCLK_SEL_M BITFIELD_MASK(1) /* 1 bit */ -+#define HOSTCtrl2_SAMPCLK_SEL_S 7 /* bit# */ -+ -+#define HOSTCtrl2_EXEC_TUNING_M BITFIELD_MASK(1) /* 1 bit */ -+#define HOSTCtrl2_EXEC_TUNING_S 6 /* bit# */ -+ -+#define HOSTCtrl2_DRIVSTRENGTH_SEL_M BITFIELD_MASK(2) /* 2 bit */ -+#define HOSTCtrl2_DRIVSTRENGTH_SEL_S 4 /* bit# */ -+ -+#define HOSTCtrl2_1_8SIG_EN_M BITFIELD_MASK(1) /* 1 bit */ -+#define HOSTCtrl2_1_8SIG_EN_S 3 /* bit# */ -+ -+#define HOSTCtrl2_UHSMODE_SEL_M BITFIELD_MASK(3) /* 3 bit */ -+#define HOSTCtrl2_UHSMODE_SEL_S 0 /* bit# */ -+ -+#define HOST_CONTR_VER_2 (1) -+#define HOST_CONTR_VER_3 (2) -+ -+/* misc defines */ -+#define SD1_MODE 0x1 /* SD Host Cntrlr Spec */ -+#define SD4_MODE 0x2 /* SD Host Cntrlr Spec */ -+ -+/* SD_PwrCntrl: Offset 0x029, size = 1 bytes */ -+#define PWR_BUS_EN_M BITFIELD_MASK(1) /* Bit 0 Power the bus */ -+#define PWR_BUS_EN_S 0 -+#define PWR_VOLTS_M BITFIELD_MASK(3) /* Bit [1-3] Voltage Select */ -+#define PWR_VOLTS_S 1 -+ -+/* SD_SoftwareReset: Offset 0x02F, size = 1 byte */ -+#define SW_RESET_ALL_M BITFIELD_MASK(1) /* Bit 0 Reset All */ -+#define SW_RESET_ALL_S 0 -+#define SW_RESET_CMD_M BITFIELD_MASK(1) /* Bit 1 CMD Line Reset */ -+#define SW_RESET_CMD_S 1 -+#define SW_RESET_DAT_M BITFIELD_MASK(1) /* Bit 2 DAT Line Reset */ -+#define SW_RESET_DAT_S 2 -+ -+/* SD_IntrStatus: Offset 0x030, size = 2 bytes */ -+/* Defs also serve SD_IntrStatusEnable and SD_IntrSignalEnable */ -+#define INTSTAT_CMD_COMPLETE_M BITFIELD_MASK(1) /* Bit 0 */ -+#define INTSTAT_CMD_COMPLETE_S 0 -+#define INTSTAT_XFER_COMPLETE_M BITFIELD_MASK(1) -+#define INTSTAT_XFER_COMPLETE_S 1 -+#define INTSTAT_BLOCK_GAP_EVENT_M BITFIELD_MASK(1) -+#define INTSTAT_BLOCK_GAP_EVENT_S 2 -+#define INTSTAT_DMA_INT_M BITFIELD_MASK(1) -+#define INTSTAT_DMA_INT_S 3 -+#define INTSTAT_BUF_WRITE_READY_M BITFIELD_MASK(1) -+#define INTSTAT_BUF_WRITE_READY_S 4 -+#define INTSTAT_BUF_READ_READY_M BITFIELD_MASK(1) -+#define INTSTAT_BUF_READ_READY_S 5 -+#define INTSTAT_CARD_INSERTION_M BITFIELD_MASK(1) -+#define INTSTAT_CARD_INSERTION_S 6 -+#define INTSTAT_CARD_REMOVAL_M BITFIELD_MASK(1) -+#define INTSTAT_CARD_REMOVAL_S 7 -+#define INTSTAT_CARD_INT_M BITFIELD_MASK(1) -+#define INTSTAT_CARD_INT_S 8 -+#define INTSTAT_RETUNING_INT_M BITFIELD_MASK(1) /* Bit 12 */ -+#define INTSTAT_RETUNING_INT_S 12 -+#define INTSTAT_ERROR_INT_M BITFIELD_MASK(1) /* Bit 15 */ -+#define INTSTAT_ERROR_INT_S 15 -+ -+/* SD_ErrorIntrStatus: Offset 0x032, size = 2 bytes */ -+/* Defs also serve SD_ErrorIntrStatusEnable and SD_ErrorIntrSignalEnable */ -+#define ERRINT_CMD_TIMEOUT_M BITFIELD_MASK(1) -+#define ERRINT_CMD_TIMEOUT_S 0 -+#define ERRINT_CMD_CRC_M BITFIELD_MASK(1) -+#define ERRINT_CMD_CRC_S 1 -+#define ERRINT_CMD_ENDBIT_M BITFIELD_MASK(1) -+#define ERRINT_CMD_ENDBIT_S 2 -+#define ERRINT_CMD_INDEX_M BITFIELD_MASK(1) -+#define ERRINT_CMD_INDEX_S 3 -+#define ERRINT_DATA_TIMEOUT_M BITFIELD_MASK(1) -+#define ERRINT_DATA_TIMEOUT_S 4 -+#define ERRINT_DATA_CRC_M BITFIELD_MASK(1) -+#define ERRINT_DATA_CRC_S 5 -+#define ERRINT_DATA_ENDBIT_M BITFIELD_MASK(1) -+#define ERRINT_DATA_ENDBIT_S 6 -+#define ERRINT_CURRENT_LIMIT_M BITFIELD_MASK(1) -+#define ERRINT_CURRENT_LIMIT_S 7 -+#define ERRINT_AUTO_CMD12_M BITFIELD_MASK(1) -+#define ERRINT_AUTO_CMD12_S 8 -+#define ERRINT_VENDOR_M BITFIELD_MASK(4) -+#define ERRINT_VENDOR_S 12 -+#define ERRINT_ADMA_M BITFIELD_MASK(1) -+#define ERRINT_ADMA_S 9 -+ -+/* Also provide definitions in "normal" form to allow combined masks */ -+#define ERRINT_CMD_TIMEOUT_BIT 0x0001 -+#define ERRINT_CMD_CRC_BIT 0x0002 -+#define ERRINT_CMD_ENDBIT_BIT 0x0004 -+#define ERRINT_CMD_INDEX_BIT 0x0008 -+#define ERRINT_DATA_TIMEOUT_BIT 0x0010 -+#define ERRINT_DATA_CRC_BIT 0x0020 -+#define ERRINT_DATA_ENDBIT_BIT 0x0040 -+#define ERRINT_CURRENT_LIMIT_BIT 0x0080 -+#define ERRINT_AUTO_CMD12_BIT 0x0100 -+#define ERRINT_ADMA_BIT 0x0200 -+ -+/* Masks to select CMD vs. DATA errors */ -+#define ERRINT_CMD_ERRS (ERRINT_CMD_TIMEOUT_BIT | ERRINT_CMD_CRC_BIT |\ -+ ERRINT_CMD_ENDBIT_BIT | ERRINT_CMD_INDEX_BIT) -+#define ERRINT_DATA_ERRS (ERRINT_DATA_TIMEOUT_BIT | ERRINT_DATA_CRC_BIT |\ -+ ERRINT_DATA_ENDBIT_BIT | ERRINT_ADMA_BIT) -+#define ERRINT_TRANSFER_ERRS (ERRINT_CMD_ERRS | ERRINT_DATA_ERRS) -+ -+/* SD_WakeupCntr_BlockGapCntrl : Offset 0x02A , size = bytes */ -+/* SD_ClockCntrl : Offset 0x02C , size = bytes */ -+/* SD_SoftwareReset_TimeoutCntrl : Offset 0x02E , size = bytes */ -+/* SD_IntrStatus : Offset 0x030 , size = bytes */ -+/* SD_ErrorIntrStatus : Offset 0x032 , size = bytes */ -+/* SD_IntrStatusEnable : Offset 0x034 , size = bytes */ -+/* SD_ErrorIntrStatusEnable : Offset 0x036 , size = bytes */ -+/* SD_IntrSignalEnable : Offset 0x038 , size = bytes */ -+/* SD_ErrorIntrSignalEnable : Offset 0x03A , size = bytes */ -+/* SD_CMD12ErrorStatus : Offset 0x03C , size = bytes */ -+/* SD_Capabilities : Offset 0x040 , size = bytes */ -+/* SD_MaxCurCap : Offset 0x048 , size = bytes */ -+/* SD_MaxCurCap_Reserved: Offset 0x04C , size = bytes */ -+/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */ -+/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */ -+ -+/* SDIO Host Control Register DMA Mode Definitions */ -+#define SDIOH_SDMA_MODE 0 -+#define SDIOH_ADMA1_MODE 1 -+#define SDIOH_ADMA2_MODE 2 -+#define SDIOH_ADMA2_64_MODE 3 -+ -+#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */ -+#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */ -+#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */ -+#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */ -+#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */ -+#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */ -+#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */ -+#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */ -+ -+/* ADMA2 Descriptor Table Entry for 32-bit Address */ -+typedef struct adma2_dscr_32b { -+ uint32 len_attr; -+ uint32 phys_addr; -+} adma2_dscr_32b_t; -+ -+/* ADMA1 Descriptor Table Entry */ -+typedef struct adma1_dscr { -+ uint32 phys_addr_attr; -+} adma1_dscr_t; -+ -+#endif /* _SDIOH_H */ -diff --git a/drivers/net/wireless/ap6210/include/sdiovar.h b/drivers/net/wireless/ap6210/include/sdiovar.h -new file mode 100644 -index 0000000..83f82de ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/sdiovar.h -@@ -0,0 +1,58 @@ -+/* -+ * Structure used by apps whose drivers access SDIO drivers. -+ * Pulled out separately so dhdu and wlu can both use it. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sdiovar.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _sdiovar_h_ -+#define _sdiovar_h_ -+ -+#include -+ -+/* require default structure packing */ -+#define BWL_DEFAULT_PACKING -+#include -+ -+typedef struct sdreg { -+ int func; -+ int offset; -+ int value; -+} sdreg_t; -+ -+/* Common msglevel constants */ -+#define SDH_ERROR_VAL 0x0001 /* Error */ -+#define SDH_TRACE_VAL 0x0002 /* Trace */ -+#define SDH_INFO_VAL 0x0004 /* Info */ -+#define SDH_DEBUG_VAL 0x0008 /* Debug */ -+#define SDH_DATA_VAL 0x0010 /* Data */ -+#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -+#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -+#define SDH_DMA_VAL 0x0080 /* DMA */ -+ -+#define NUM_PREV_TRANSACTIONS 16 -+ -+ -+#include -+ -+#endif /* _sdiovar_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/siutils.h b/drivers/net/wireless/ap6210/include/siutils.h -new file mode 100644 -index 0000000..acc72ee ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/siutils.h -@@ -0,0 +1,347 @@ -+/* -+ * Misc utility routines for accessing the SOC Interconnects -+ * of Broadcom HNBU chips. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: siutils.h 347614 2012-07-27 10:24:51Z $ -+ */ -+ -+#ifndef _siutils_h_ -+#define _siutils_h_ -+ -+/* -+ * Data structure to export all chip specific common variables -+ * public (read-only) portion of siutils handle returned by si_attach()/si_kattach() -+ */ -+struct si_pub { -+ uint socitype; /* SOCI_SB, SOCI_AI */ -+ -+ uint bustype; /* SI_BUS, PCI_BUS */ -+ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ -+ uint buscorerev; /* buscore rev */ -+ uint buscoreidx; /* buscore index */ -+ int ccrev; /* chip common core rev */ -+ uint32 cccaps; /* chip common capabilities */ -+ uint32 cccaps_ext; /* chip common capabilities extension */ -+ int pmurev; /* pmu core rev */ -+ uint32 pmucaps; /* pmu capabilities */ -+ uint boardtype; /* board type */ -+ uint boardrev; /* board rev */ -+ uint boardvendor; /* board vendor */ -+ uint boardflags; /* board flags */ -+ uint boardflags2; /* board flags2 */ -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint chippkg; /* chip package option */ -+ uint32 chipst; /* chip status */ -+ bool issim; /* chip is in simulation or emulation */ -+ uint socirev; /* SOC interconnect rev */ -+ bool pci_pr32414; -+ -+}; -+ -+/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver -+ * for monolithic driver, it is readonly to prevent accident change -+ */ -+typedef const struct si_pub si_t; -+ -+ -+/* -+ * Many of the routines below take an 'sih' handle as their first arg. -+ * Allocate this by calling si_attach(). Free it by calling si_detach(). -+ * At any one time, the sih is logically focused on one particular si core -+ * (the "current core"). -+ * Use si_setcore() or si_setcoreidx() to change the association to another core. -+ */ -+#define SI_OSH NULL /* Use for si_kattach when no osh is available */ -+ -+#define BADIDX (SI_MAXCORES + 1) -+ -+/* clkctl xtal what flags */ -+#define XTAL 0x1 /* primary crystal oscillator (2050) */ -+#define PLL 0x2 /* main chip pll */ -+ -+/* clkctl clk mode */ -+#define CLK_FAST 0 /* force fast (pll) clock */ -+#define CLK_DYNAMIC 2 /* enable dynamic clock control */ -+ -+/* GPIO usage priorities */ -+#define GPIO_DRV_PRIORITY 0 /* Driver */ -+#define GPIO_APP_PRIORITY 1 /* Application */ -+#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */ -+ -+/* GPIO pull up/down */ -+#define GPIO_PULLUP 0 -+#define GPIO_PULLDN 1 -+ -+/* GPIO event regtype */ -+#define GPIO_REGEVT 0 /* GPIO register event */ -+#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ -+#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ -+ -+/* device path */ -+#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ -+ -+/* SI routine enumeration: to be used by update function with multiple hooks */ -+#define SI_DOATTACH 1 -+#define SI_PCIDOWN 2 -+#define SI_PCIUP 3 -+ -+#define ISSIM_ENAB(sih) 0 -+ -+/* PMU clock/power control */ -+#if defined(BCMPMUCTL) -+#define PMUCTL_ENAB(sih) (BCMPMUCTL) -+#else -+#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -+#endif -+ -+/* chipcommon clock/power control (exclusive with PMU's) */ -+#if defined(BCMPMUCTL) && BCMPMUCTL -+#define CCCTL_ENAB(sih) (0) -+#define CCPLL_ENAB(sih) (0) -+#else -+#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -+#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -+#endif -+ -+typedef void (*gpio_handler_t)(uint32 stat, void *arg); -+/* External BT Coex enable mask */ -+#define CC_BTCOEX_EN_MASK 0x01 -+/* External PA enable mask */ -+#define GPIO_CTRL_EPA_EN_MASK 0x40 -+/* WL/BT control enable mask */ -+#define GPIO_CTRL_5_6_EN_MASK 0x60 -+#define GPIO_CTRL_7_6_EN_MASK 0xC0 -+#define GPIO_OUT_7_EN_MASK 0x80 -+ -+ -+/* CR4 specific defines used by the host driver */ -+#define SI_CR4_CAP (0x04) -+#define SI_CR4_BANKIDX (0x40) -+#define SI_CR4_BANKINFO (0x44) -+ -+#define ARMCR4_TCBBNB_MASK 0xf0 -+#define ARMCR4_TCBBNB_SHIFT 4 -+#define ARMCR4_TCBANB_MASK 0xf -+#define ARMCR4_TCBANB_SHIFT 0 -+ -+#define SICF_CPUHALT (0x0020) -+#define ARMCR4_BSZ_MASK 0x3f -+#define ARMCR4_BSZ_MULT 8192 -+ -+ -+/* === exported functions === */ -+extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, -+ void *sdh, char **vars, uint *varsz); -+extern si_t *si_kattach(osl_t *osh); -+extern void si_detach(si_t *sih); -+extern bool si_pci_war16165(si_t *sih); -+ -+extern uint si_corelist(si_t *sih, uint coreid[]); -+extern uint si_coreid(si_t *sih); -+extern uint si_flag(si_t *sih); -+extern uint si_intflag(si_t *sih); -+extern uint si_coreidx(si_t *sih); -+extern uint si_coreunit(si_t *sih); -+extern uint si_corevendor(si_t *sih); -+extern uint si_corerev(si_t *sih); -+extern void *si_osh(si_t *sih); -+extern void si_setosh(si_t *sih, osl_t *osh); -+extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -+extern void *si_coreregs(si_t *sih); -+extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -+extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); -+extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -+extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); -+extern bool si_iscoreup(si_t *sih); -+extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -+extern void *si_setcoreidx(si_t *sih, uint coreidx); -+extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -+extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); -+extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -+extern int si_numaddrspaces(si_t *sih); -+extern uint32 si_addrspace(si_t *sih, uint asidx); -+extern uint32 si_addrspacesize(si_t *sih, uint asidx); -+extern void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); -+extern int si_corebist(si_t *sih); -+extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -+extern void si_core_disable(si_t *sih, uint32 bits); -+extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -+extern bool si_read_pmu_autopll(si_t *sih); -+extern uint32 si_clock(si_t *sih); -+extern uint32 si_alp_clock(si_t *sih); -+extern uint32 si_ilp_clock(si_t *sih); -+extern void si_pci_setup(si_t *sih, uint coremask); -+extern void si_pcmcia_init(si_t *sih); -+extern void si_setint(si_t *sih, int siflag); -+extern bool si_backplane64(si_t *sih); -+extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, -+ void *intrsenabled_fn, void *intr_arg); -+extern void si_deregister_intr_callback(si_t *sih); -+extern void si_clkctl_init(si_t *sih); -+extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih); -+extern bool si_clkctl_cc(si_t *sih, uint mode); -+extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -+extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val); -+extern void si_btcgpiowar(si_t *sih); -+extern bool si_deviceremoved(si_t *sih); -+extern uint32 si_socram_size(si_t *sih); -+extern uint32 si_socdevram_size(si_t *sih); -+extern uint32 si_socram_srmem_size(si_t *sih); -+extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect, uint8 *remap); -+extern bool si_socdevram_pkg(si_t *sih); -+extern bool si_socdevram_remap_isenb(si_t *sih); -+extern uint32 si_socdevram_remap_size(si_t *sih); -+ -+extern void si_watchdog(si_t *sih, uint ticks); -+extern void si_watchdog_ms(si_t *sih, uint32 ms); -+extern uint32 si_watchdog_msticks(void); -+extern void *si_gpiosetcore(si_t *sih); -+extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpioin(si_t *sih); -+extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val); -+extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority); -+extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority); -+extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val); -+extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val); -+extern uint32 si_gpio_int_enable(si_t *sih, bool enable); -+ -+/* GPIO event handlers */ -+extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev, gpio_handler_t cb, void *arg); -+extern void si_gpio_handler_unregister(si_t *sih, void* gpioh); -+extern void si_gpio_handler_process(si_t *sih); -+ -+/* Wake-on-wireless-LAN (WOWL) */ -+extern bool si_pci_pmecap(si_t *sih); -+struct osl_info; -+extern bool si_pci_fastpmecap(struct osl_info *osh); -+extern bool si_pci_pmestat(si_t *sih); -+extern void si_pci_pmeclr(si_t *sih); -+extern void si_pci_pmeen(si_t *sih); -+extern void si_pci_pmestatclr(si_t *sih); -+extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset); -+ -+extern void si_sdio_init(si_t *sih); -+ -+extern uint16 si_d11_devid(si_t *sih); -+extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice, -+ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader); -+ -+#define si_eci(sih) 0 -+static INLINE void * si_eci_init(si_t *sih) {return NULL;} -+#define si_eci_notify_bt(sih, type, val) (0) -+#define si_seci(sih) 0 -+#define si_seci_upd(sih, a) do {} while (0) -+static INLINE void * si_seci_init(si_t *sih, uint8 use_seci) {return NULL;} -+#define si_seci_down(sih) do {} while (0) -+ -+/* OTP status */ -+extern bool si_is_otp_disabled(si_t *sih); -+extern bool si_is_otp_powered(si_t *sih); -+extern void si_otp_power(si_t *sih, bool on); -+ -+/* SPROM availability */ -+extern bool si_is_sprom_available(si_t *sih); -+extern bool si_is_sprom_enabled(si_t *sih); -+extern void si_sprom_enable(si_t *sih, bool enable); -+ -+/* OTP/SROM CIS stuff */ -+extern int si_cis_source(si_t *sih); -+#define CIS_DEFAULT 0 -+#define CIS_SROM 1 -+#define CIS_OTP 2 -+ -+/* Fab-id information */ -+#define DEFAULT_FAB 0x0 /* Original/first fab used for this chip */ -+#define CSM_FAB7 0x1 /* CSM Fab7 chip */ -+#define TSMC_FAB12 0x2 /* TSMC Fab12/Fab14 chip */ -+#define SMIC_FAB4 0x3 /* SMIC Fab4 chip */ -+extern int si_otp_fabid(si_t *sih, uint16 *fabid, bool rw); -+extern uint16 si_fabid(si_t *sih); -+ -+/* -+ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. -+ * The returned path is NULL terminated and has trailing '/'. -+ * Return 0 on success, nonzero otherwise. -+ */ -+extern int si_devpath(si_t *sih, char *path, int size); -+/* Read variable with prepending the devpath to the name */ -+extern char *si_getdevpathvar(si_t *sih, const char *name); -+extern int si_getdevpathintvar(si_t *sih, const char *name); -+extern char *si_coded_devpathvar(si_t *sih, char *varname, int var_len, const char *name); -+ -+ -+extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); -+extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val); -+extern void si_war42780_clkreq(si_t *sih, bool clkreq); -+extern void si_pci_down(si_t *sih); -+extern void si_pci_up(si_t *sih); -+extern void si_pci_sleep(si_t *sih); -+extern void si_pcie_war_ovr_update(si_t *sih, uint8 aspm); -+extern void si_pcie_power_save_enable(si_t *sih, bool enable); -+extern void si_pcie_extendL1timer(si_t *sih, bool extend); -+extern int si_pci_fixcfg(si_t *sih); -+extern void si_chippkg_set(si_t *sih, uint); -+ -+extern void si_chipcontrl_btshd0_4331(si_t *sih, bool on); -+extern void si_chipcontrl_restore(si_t *sih, uint32 val); -+extern uint32 si_chipcontrl_read(si_t *sih); -+extern void si_chipcontrl_epa4331(si_t *sih, bool on); -+extern void si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl); -+extern void si_chipcontrl_srom4360(si_t *sih, bool on); -+/* Enable BT-COEX & Ex-PA for 4313 */ -+extern void si_epa_4313war(si_t *sih); -+extern void si_btc_enable_chipcontrol(si_t *sih); -+/* BT/WL selection for 4313 bt combo >= P250 boards */ -+extern void si_btcombo_p250_4313_war(si_t *sih); -+extern void si_btcombo_43228_war(si_t *sih); -+extern void si_clk_pmu_htavail_set(si_t *sih, bool set_clear); -+extern uint si_pll_reset(si_t *sih); -+/* === debug routines === */ -+ -+extern bool si_taclear(si_t *sih, bool details); -+ -+ -+ -+extern uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type); -+extern uint32 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val); -+extern void si_pcie_set_request_size(si_t *sih, uint16 size); -+extern uint16 si_pcie_get_request_size(si_t *sih); -+extern uint16 si_pcie_get_ssid(si_t *sih); -+extern uint32 si_pcie_get_bar0(si_t *sih); -+extern int si_pcie_configspace_cache(si_t *sih); -+extern int si_pcie_configspace_restore(si_t *sih); -+extern int si_pcie_configspace_get(si_t *sih, uint8 *buf, uint size); -+ -+char *si_getnvramflvar(si_t *sih, const char *name); -+ -+ -+extern uint32 si_tcm_size(si_t *sih); -+ -+extern int si_set_sromctl(si_t *sih, uint32 value); -+extern uint32 si_get_sromctl(si_t *sih); -+#endif /* _siutils_h_ */ -diff --git a/drivers/net/wireless/ap6210/include/trxhdr.h b/drivers/net/wireless/ap6210/include/trxhdr.h -new file mode 100644 -index 0000000..bf92a56 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/trxhdr.h -@@ -0,0 +1,53 @@ -+/* -+ * TRX image file header format. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: trxhdr.h 260898 2011-05-20 23:11:12Z $ -+ */ -+ -+#ifndef _TRX_HDR_H -+#define _TRX_HDR_H -+ -+#include -+ -+#define TRX_MAGIC 0x30524448 /* "HDR0" */ -+#define TRX_VERSION 1 /* Version 1 */ -+#define TRX_MAX_LEN 0x3B0000 /* Max length */ -+#define TRX_NO_HEADER 1 /* Do not write TRX header */ -+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -+#define TRX_EMBED_UCODE 0x8 /* Trx contains embedded ucode image */ -+#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */ -+#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ -+#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -+ -+struct trx_header { -+ uint32 magic; /* "HDR0" */ -+ uint32 len; /* Length of file including header */ -+ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32 flag_version; /* 0:15 flags, 16:31 version */ -+ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+}; -+ -+/* Compatibility */ -+typedef struct trx_header TRXHDR, *PTRXHDR; -+ -+#endif /* _TRX_HDR_H */ -diff --git a/drivers/net/wireless/ap6210/include/typedefs.h b/drivers/net/wireless/ap6210/include/typedefs.h -new file mode 100644 -index 0000000..fe1d162 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/typedefs.h -@@ -0,0 +1,343 @@ -+/* -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $ -+ */ -+ -+#ifndef _TYPEDEFS_H_ -+#define _TYPEDEFS_H_ -+ -+#ifdef SITE_TYPEDEFS -+ -+/* -+ * Define SITE_TYPEDEFS in the compile to include a site-specific -+ * typedef file "site_typedefs.h". -+ * -+ * If SITE_TYPEDEFS is not defined, then the code section below makes -+ * inferences about the compile environment based on defined symbols and -+ * possibly compiler pragmas. -+ * -+ * Following these two sections is the Default Typedefs section. -+ * This section is only processed if USE_TYPEDEF_DEFAULTS is -+ * defined. This section has a default set of typedefs and a few -+ * preprocessor symbols (TRUE, FALSE, NULL, ...). -+ */ -+ -+#include "site_typedefs.h" -+ -+#else -+ -+/* -+ * Infer the compile environment based on preprocessor symbols and pragmas. -+ * Override type definitions as needed, and include configuration-dependent -+ * header files to define types. -+ */ -+ -+#ifdef __cplusplus -+ -+#define TYPEDEF_BOOL -+#ifndef FALSE -+#define FALSE false -+#endif -+#ifndef TRUE -+#define TRUE true -+#endif -+ -+#else /* ! __cplusplus */ -+ -+ -+#endif /* ! __cplusplus */ -+ -+#if defined(__x86_64__) -+#define TYPEDEF_UINTPTR -+typedef unsigned long long int uintptr; -+#endif -+ -+ -+ -+ -+ -+#if defined(_NEED_SIZE_T_) -+typedef long unsigned int size_t; -+#endif -+ -+ -+ -+ -+#if defined(__sparc__) -+#define TYPEDEF_ULONG -+#endif -+ -+ -+/* -+ * If this is either a Linux hybrid build or the per-port code of a hybrid build -+ * then use the Linux header files to get some of the typedefs. Otherwise, define -+ * them entirely in this file. We can't always define the types because we get -+ * a duplicate typedef error; there is no way to "undefine" a typedef. -+ * We know when it's per-port code because each file defines LINUX_PORT at the top. -+ */ -+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -+#define TYPEDEF_UINT -+#ifndef TARGETENV_android -+#define TYPEDEF_USHORT -+#define TYPEDEF_ULONG -+#endif /* TARGETENV_android */ -+#ifdef __KERNEL__ -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -+#define TYPEDEF_BOOL -+#endif /* >= 2.6.19 */ -+/* special detection for 2.6.18-128.7.1.0.1.el5 */ -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) -+#include -+#ifdef noinline_for_stack -+#define TYPEDEF_BOOL -+#endif -+#endif /* == 2.6.18 */ -+#endif /* __KERNEL__ */ -+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ -+ -+ -+ -+ -+/* Do not support the (u)int64 types with strict ansi for GNU C */ -+#if defined(__GNUC__) && defined(__STRICT_ANSI__) -+#define TYPEDEF_INT64 -+#define TYPEDEF_UINT64 -+#endif -+ -+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode -+ * for signed or unsigned -+ */ -+#if defined(__ICL) -+ -+#define TYPEDEF_INT64 -+ -+#if defined(__STDC__) -+#define TYPEDEF_UINT64 -+#endif -+ -+#endif /* __ICL */ -+ -+#if !defined(__DJGPP__) -+ -+/* pick up ushort & uint from standard types.h */ -+#if defined(__KERNEL__) -+ -+/* See note above */ -+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -+#include /* sys/types.h and linux/types.h are oil and water */ -+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ -+ -+#else -+ -+ -+#include -+ -+#endif /* linux && __KERNEL__ */ -+ -+#endif -+ -+ -+ -+/* use the default typedefs in the next section of this file */ -+#define USE_TYPEDEF_DEFAULTS -+ -+#endif /* SITE_TYPEDEFS */ -+ -+ -+/* -+ * Default Typedefs -+ */ -+ -+#ifdef USE_TYPEDEF_DEFAULTS -+#undef USE_TYPEDEF_DEFAULTS -+ -+#ifndef TYPEDEF_BOOL -+typedef /* @abstract@ */ unsigned char bool; -+#endif -+ -+/* define uchar, ushort, uint, ulong */ -+ -+#ifndef TYPEDEF_UCHAR -+typedef unsigned char uchar; -+#endif -+ -+#ifndef TYPEDEF_USHORT -+typedef unsigned short ushort; -+#endif -+ -+#ifndef TYPEDEF_UINT -+typedef unsigned int uint; -+#endif -+ -+#ifndef TYPEDEF_ULONG -+typedef unsigned long ulong; -+#endif -+ -+/* define [u]int8/16/32/64, uintptr */ -+ -+#ifndef TYPEDEF_UINT8 -+typedef unsigned char uint8; -+#endif -+ -+#ifndef TYPEDEF_UINT16 -+typedef unsigned short uint16; -+#endif -+ -+#ifndef TYPEDEF_UINT32 -+typedef unsigned int uint32; -+#endif -+ -+#ifndef TYPEDEF_UINT64 -+typedef unsigned long long uint64; -+#endif -+ -+#ifndef TYPEDEF_UINTPTR -+typedef unsigned int uintptr; -+#endif -+ -+#ifndef TYPEDEF_INT8 -+typedef signed char int8; -+#endif -+ -+#ifndef TYPEDEF_INT16 -+typedef signed short int16; -+#endif -+ -+#ifndef TYPEDEF_INT32 -+typedef signed int int32; -+#endif -+ -+#ifndef TYPEDEF_INT64 -+typedef signed long long int64; -+#endif -+ -+/* define float32/64, float_t */ -+ -+#ifndef TYPEDEF_FLOAT32 -+typedef float float32; -+#endif -+ -+#ifndef TYPEDEF_FLOAT64 -+typedef double float64; -+#endif -+ -+/* -+ * abstracted floating point type allows for compile time selection of -+ * single or double precision arithmetic. Compiling with -DFLOAT32 -+ * selects single precision; the default is double precision. -+ */ -+ -+#ifndef TYPEDEF_FLOAT_T -+ -+#if defined(FLOAT32) -+typedef float32 float_t; -+#else /* default to double precision floating point */ -+typedef float64 float_t; -+#endif -+ -+#endif /* TYPEDEF_FLOAT_T */ -+ -+/* define macro values */ -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 /* TRUE */ -+#endif -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+#ifndef OFF -+#define OFF 0 -+#endif -+ -+#ifndef ON -+#define ON 1 /* ON = 1 */ -+#endif -+ -+#define AUTO (-1) /* Auto = -1 */ -+ -+/* define PTRSZ, INLINE */ -+ -+#ifndef PTRSZ -+#define PTRSZ sizeof(char*) -+#endif -+ -+ -+/* Detect compiler type. */ -+#if defined(__GNUC__) || defined(__lint) -+ #define BWL_COMPILER_GNU -+#elif defined(__CC_ARM) && __CC_ARM -+ #define BWL_COMPILER_ARMCC -+#else -+ #error "Unknown compiler!" -+#endif -+ -+ -+#ifndef INLINE -+ #if defined(BWL_COMPILER_MICROSOFT) -+ #define INLINE __inline -+ #elif defined(BWL_COMPILER_GNU) -+ #define INLINE __inline__ -+ #elif defined(BWL_COMPILER_ARMCC) -+ #define INLINE __inline -+ #else -+ #define INLINE -+ #endif -+#endif /* INLINE */ -+ -+#undef TYPEDEF_BOOL -+#undef TYPEDEF_UCHAR -+#undef TYPEDEF_USHORT -+#undef TYPEDEF_UINT -+#undef TYPEDEF_ULONG -+#undef TYPEDEF_UINT8 -+#undef TYPEDEF_UINT16 -+#undef TYPEDEF_UINT32 -+#undef TYPEDEF_UINT64 -+#undef TYPEDEF_UINTPTR -+#undef TYPEDEF_INT8 -+#undef TYPEDEF_INT16 -+#undef TYPEDEF_INT32 -+#undef TYPEDEF_INT64 -+#undef TYPEDEF_FLOAT32 -+#undef TYPEDEF_FLOAT64 -+#undef TYPEDEF_FLOAT_T -+ -+#endif /* USE_TYPEDEF_DEFAULTS */ -+ -+/* Suppress unused parameter warning */ -+#define UNUSED_PARAMETER(x) (void)(x) -+ -+/* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */ -+#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr)) -+ -+/* -+ * Including the bcmdefs.h here, to make sure everyone including typedefs.h -+ * gets this automatically -+*/ -+#include -+#endif /* _TYPEDEFS_H_ */ -diff --git a/drivers/net/wireless/ap6210/include/wlfc_proto.h b/drivers/net/wireless/ap6210/include/wlfc_proto.h -new file mode 100644 -index 0000000..98d2fa9 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/wlfc_proto.h -@@ -0,0 +1,217 @@ -+/* -+* Copyright (C) 1999-2012, Broadcom Corporation -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2 (the "GPL"), -+* available at http://www.broadcom.com/licenses/GPLv2.php, with the -+* following added to such license: -+* -+* As a special exception, the copyright holders of this software give you -+* permission to link this software with independent modules, and to copy and -+* distribute the resulting executable under terms of your choice, provided that -+* you also meet, for each linked independent module, the terms and conditions of -+* the license of that module. An independent module is a module which is not -+* derived from this software. The special exception does not apply to any -+* modifications of the software. -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a license -+* other than the GPL, without Broadcom's express prior written consent. -+* $Id: wlfc_proto.h 361006 2012-10-05 07:45:51Z $ -+* -+*/ -+#ifndef __wlfc_proto_definitions_h__ -+#define __wlfc_proto_definitions_h__ -+ -+ /* Use TLV to convey WLFC information. -+ --------------------------------------------------------------------------- -+ | Type | Len | value | Description -+ --------------------------------------------------------------------------- -+ | 1 | 1 | (handle) | MAC OPEN -+ --------------------------------------------------------------------------- -+ | 2 | 1 | (handle) | MAC CLOSE -+ --------------------------------------------------------------------------- -+ | 3 | 2 | (count, handle, prec_bmp)| Set the credit depth for a MAC dstn -+ --------------------------------------------------------------------------- -+ | 4 | 4 | see pkttag comments | TXSTATUS -+ --------------------------------------------------------------------------- -+ | 5 | 4 | see pkttag comments | PKKTTAG [host->firmware] -+ --------------------------------------------------------------------------- -+ | 6 | 8 | (handle, ifid, MAC) | MAC ADD -+ --------------------------------------------------------------------------- -+ | 7 | 8 | (handle, ifid, MAC) | MAC DEL -+ --------------------------------------------------------------------------- -+ | 8 | 1 | (rssi) | RSSI - RSSI value for the packet. -+ --------------------------------------------------------------------------- -+ | 9 | 1 | (interface ID) | Interface OPEN -+ --------------------------------------------------------------------------- -+ | 10 | 1 | (interface ID) | Interface CLOSE -+ --------------------------------------------------------------------------- -+ | 11 | 8 | fifo credit returns map | FIFO credits back to the host -+ | | | | -+ | | | | -------------------------------------- -+ | | | | | ac0 | ac1 | ac2 | ac3 | bcmc | atim | -+ | | | | -------------------------------------- -+ | | | | -+ --------------------------------------------------------------------------- -+ | 12 | 2 | MAC handle, | Host provides a bitmap of pending -+ | | | AC[0-3] traffic bitmap | unicast traffic for MAC-handle dstn. -+ | | | | [host->firmware] -+ --------------------------------------------------------------------------- -+ | 13 | 3 | (count, handle, prec_bmp)| One time request for packet to a specific -+ | | | | MAC destination. -+ --------------------------------------------------------------------------- -+ | 15 | 1 | interface ID | NIC period start -+ --------------------------------------------------------------------------- -+ | 16 | 1 | interface ID | NIC period end -+ --------------------------------------------------------------------------- -+ | 17 | 3 | (ifid, txs) | Action frame tx status -+ --------------------------------------------------------------------------- -+ | 255 | N/A | N/A | FILLER - This is a special type -+ | | | | that has no length or value. -+ | | | | Typically used for padding. -+ --------------------------------------------------------------------------- -+ */ -+ -+#define WLFC_CTL_TYPE_MAC_OPEN 1 -+#define WLFC_CTL_TYPE_MAC_CLOSE 2 -+#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT 3 -+#define WLFC_CTL_TYPE_TXSTATUS 4 -+#define WLFC_CTL_TYPE_PKTTAG 5 -+ -+#define WLFC_CTL_TYPE_MACDESC_ADD 6 -+#define WLFC_CTL_TYPE_MACDESC_DEL 7 -+#define WLFC_CTL_TYPE_RSSI 8 -+ -+#define WLFC_CTL_TYPE_INTERFACE_OPEN 9 -+#define WLFC_CTL_TYPE_INTERFACE_CLOSE 10 -+ -+#define WLFC_CTL_TYPE_FIFO_CREDITBACK 11 -+ -+#define WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP 12 -+#define WLFC_CTL_TYPE_MAC_REQUEST_PACKET 13 -+#define WLFC_CTL_TYPE_HOST_REORDER_RXPKTS 14 -+ -+#define WLFC_CTL_TYPE_NIC_PRD_START 15 -+#define WLFC_CTL_TYPE_NIC_PRD_END 16 -+#define WLFC_CTL_TYPE_AF_TXS 17 -+#define WLFC_CTL_TYPE_TRANS_ID 18 -+#define WLFC_CTL_TYPE_COMP_TXSTATUS 19 -+ -+#define WLFC_CTL_TYPE_FILLER 255 -+ -+#define WLFC_CTL_VALUE_LEN_MACDESC 8 /* handle, interface, MAC */ -+ -+#define WLFC_CTL_VALUE_LEN_MAC 1 /* MAC-handle */ -+#define WLFC_CTL_VALUE_LEN_RSSI 1 -+ -+#define WLFC_CTL_VALUE_LEN_INTERFACE 1 -+#define WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP 2 -+ -+#define WLFC_CTL_VALUE_LEN_TXSTATUS 4 -+#define WLFC_CTL_VALUE_LEN_PKTTAG 4 -+ -+/* enough space to host all 4 ACs, bc/mc and atim fifo credit */ -+#define WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK 6 -+ -+#define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT 3 /* credit, MAC-handle, prec_bitmap */ -+#define WLFC_CTL_VALUE_LEN_REQUEST_PACKET 3 /* credit, MAC-handle, prec_bitmap */ -+ -+#define WLFC_CTL_VALUE_LEN_NIC_PRD_START 1 -+#define WLFC_CTL_VALUE_LEN_NIC_PRD_END 1 -+#define WLFC_CTL_VALUE_LEN_AF_TXS 3 -+ -+ -+#define WLFC_PKTID_GEN_MASK 0x80000000 -+#define WLFC_PKTID_GEN_SHIFT 31 -+ -+#define WLFC_PKTID_GEN(x) (((x) & WLFC_PKTID_GEN_MASK) >> WLFC_PKTID_GEN_SHIFT) -+#define WLFC_PKTID_SETGEN(x, gen) (x) = ((x) & ~WLFC_PKTID_GEN_MASK) | \ -+ (((gen) << WLFC_PKTID_GEN_SHIFT) & WLFC_PKTID_GEN_MASK) -+ -+#define WLFC_PKTFLAG_PKTFROMHOST 0x01 -+#define WLFC_PKTFLAG_PKT_REQUESTED 0x02 -+ -+#define WL_TXSTATUS_FLAGS_MASK 0xf /* allow 4 bits only */ -+#define WL_TXSTATUS_FLAGS_SHIFT 27 -+ -+#define WL_TXSTATUS_SET_FLAGS(x, flags) ((x) = \ -+ ((x) & ~(WL_TXSTATUS_FLAGS_MASK << WL_TXSTATUS_FLAGS_SHIFT)) | \ -+ (((flags) & WL_TXSTATUS_FLAGS_MASK) << WL_TXSTATUS_FLAGS_SHIFT)) -+#define WL_TXSTATUS_GET_FLAGS(x) (((x) >> WL_TXSTATUS_FLAGS_SHIFT) & \ -+ WL_TXSTATUS_FLAGS_MASK) -+ -+#define WL_TXSTATUS_FIFO_MASK 0x7 /* allow 3 bits for FIFO ID */ -+#define WL_TXSTATUS_FIFO_SHIFT 24 -+ -+#define WL_TXSTATUS_SET_FIFO(x, flags) ((x) = \ -+ ((x) & ~(WL_TXSTATUS_FIFO_MASK << WL_TXSTATUS_FIFO_SHIFT)) | \ -+ (((flags) & WL_TXSTATUS_FIFO_MASK) << WL_TXSTATUS_FIFO_SHIFT)) -+#define WL_TXSTATUS_GET_FIFO(x) (((x) >> WL_TXSTATUS_FIFO_SHIFT) & WL_TXSTATUS_FIFO_MASK) -+ -+#define WL_TXSTATUS_PKTID_MASK 0xffffff /* allow 24 bits */ -+#define WL_TXSTATUS_SET_PKTID(x, num) ((x) = \ -+ ((x) & ~WL_TXSTATUS_PKTID_MASK) | (num)) -+#define WL_TXSTATUS_GET_PKTID(x) ((x) & WL_TXSTATUS_PKTID_MASK) -+ -+/* 32 STA should be enough??, 6 bits; Must be power of 2 */ -+#define WLFC_MAC_DESC_TABLE_SIZE 32 -+#define WLFC_MAX_IFNUM 16 -+#define WLFC_MAC_DESC_ID_INVALID 0xff -+ -+/* b[7:5] -reuse guard, b[4:0] -value */ -+#define WLFC_MAC_DESC_GET_LOOKUP_INDEX(x) ((x) & 0x1f) -+ -+#define WLFC_PKTFLAG_SET_PKTREQUESTED(x) (x) |= \ -+ (WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) -+ -+#define WLFC_PKTFLAG_CLR_PKTREQUESTED(x) (x) &= \ -+ ~(WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT) -+ -+#define WL_TXSTATUS_GENERATION_MASK 1 -+#define WL_TXSTATUS_GENERATION_SHIFT 31 -+ -+#define WLFC_PKTFLAG_SET_GENERATION(x, gen) ((x) = \ -+ ((x) & ~(WL_TXSTATUS_GENERATION_MASK << WL_TXSTATUS_GENERATION_SHIFT)) | \ -+ (((gen) & WL_TXSTATUS_GENERATION_MASK) << WL_TXSTATUS_GENERATION_SHIFT)) -+ -+#define WLFC_PKTFLAG_GENERATION(x) (((x) >> WL_TXSTATUS_GENERATION_SHIFT) & \ -+ WL_TXSTATUS_GENERATION_MASK) -+ -+#define WLFC_MAX_PENDING_DATALEN 120 -+ -+/* host is free to discard the packet */ -+#define WLFC_CTL_PKTFLAG_DISCARD 0 -+/* D11 suppressed a packet */ -+#define WLFC_CTL_PKTFLAG_D11SUPPRESS 1 -+/* WL firmware suppressed a packet because MAC is -+ already in PSMode (short time window) -+*/ -+#define WLFC_CTL_PKTFLAG_WLSUPPRESS 2 -+/* Firmware tossed this packet */ -+#define WLFC_CTL_PKTFLAG_TOSSED_BYWLC 3 -+ -+#define WLFC_D11_STATUS_INTERPRET(txs) \ -+ (((txs)->status.suppr_ind != 0) ? WLFC_CTL_PKTFLAG_D11SUPPRESS : WLFC_CTL_PKTFLAG_DISCARD) -+ -+/* AMPDU host reorder packet flags */ -+#define WLHOST_REORDERDATA_MAXFLOWS 256 -+#define WLHOST_REORDERDATA_LEN 10 -+#define WLHOST_REORDERDATA_TOTLEN (WLHOST_REORDERDATA_LEN + 1 + 1) /* +tag +len */ -+ -+#define WLHOST_REORDERDATA_FLOWID_OFFSET 0 -+#define WLHOST_REORDERDATA_MAXIDX_OFFSET 2 -+#define WLHOST_REORDERDATA_FLAGS_OFFSET 4 -+#define WLHOST_REORDERDATA_CURIDX_OFFSET 6 -+#define WLHOST_REORDERDATA_EXPIDX_OFFSET 8 -+ -+#define WLHOST_REORDERDATA_DEL_FLOW 0x01 -+#define WLHOST_REORDERDATA_FLUSH_ALL 0x02 -+#define WLHOST_REORDERDATA_CURIDX_VALID 0x04 -+#define WLHOST_REORDERDATA_EXPIDX_VALID 0x08 -+#define WLHOST_REORDERDATA_NEW_HOLE 0x10 -+/* transaction id data len byte 0: rsvd, byte 1: seqnumber, byte 2-5 will be used for timestampe */ -+#define WLFC_CTL_TRANS_ID_LEN 6 -+ -+#endif /* __wlfc_proto_definitions_h__ */ -diff --git a/drivers/net/wireless/ap6210/include/wlioctl.h b/drivers/net/wireless/ap6210/include/wlioctl.h -new file mode 100644 -index 0000000..a3e7003 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/include/wlioctl.h -@@ -0,0 +1,5079 @@ -+/* -+ * Custom OID/ioctl definitions for -+ * Broadcom 802.11abg Networking Device Driver -+ * -+ * Definitions subject to change without notice. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wlioctl.h 366141 2012-11-01 01:55:06Z $ -+ */ -+ -+#ifndef _wlioctl_h_ -+#define _wlioctl_h_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#include -+#include -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* LINUX_POSTMOGRIFY_REMOVAL: undefined during compile phase, so its -+ * a no-op for most cases. For hybrid and other open source releases, -+ * its defined during a second pass and mogrified out for distribution. -+ */ -+ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+#ifndef INTF_NAME_SIZ -+#define INTF_NAME_SIZ 16 -+#endif -+ -+/* Used to send ioctls over the transport pipe */ -+typedef struct remote_ioctl { -+ cdc_ioctl_t msg; -+ uint data_len; -+ char intf_name[INTF_NAME_SIZ]; -+} rem_ioctl_t; -+#define REMOTE_SIZE sizeof(rem_ioctl_t) -+ -+#define ACTION_FRAME_SIZE 1800 -+ -+typedef struct wl_action_frame { -+ struct ether_addr da; -+ uint16 len; -+ uint32 packetId; -+ uint8 data[ACTION_FRAME_SIZE]; -+} wl_action_frame_t; -+ -+#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) -+ -+typedef struct ssid_info -+{ -+ uint8 ssid_len; /* the length of SSID */ -+ uint8 ssid[32]; /* SSID string */ -+} ssid_info_t; -+ -+typedef struct wl_af_params { -+ uint32 channel; -+ int32 dwell_time; -+ struct ether_addr BSSID; -+ wl_action_frame_t action_frame; -+} wl_af_params_t; -+ -+#define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) -+ -+#define MFP_TEST_FLAG_NORMAL 0 -+#define MFP_TEST_FLAG_ANY_KEY 1 -+typedef struct wl_sa_query { -+ uint32 flag; -+ uint8 action; -+ uint16 id; -+ struct ether_addr da; -+} wl_sa_query_t; -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* require default structure packing */ -+#define BWL_DEFAULT_PACKING -+#include -+ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* Legacy structure to help keep backward compatible wl tool and tray app */ -+ -+#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ -+ -+typedef struct wl_bss_info_107 { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ uint8 channel; /* Channel no. */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ /* variable length Information Elements */ -+} wl_bss_info_107_t; -+ -+/* -+ * Per-BSS information structure. -+ */ -+ -+#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */ -+ -+/* BSS info structure -+ * Applications MUST CHECK ie_offset field and length field to access IEs and -+ * next bss_info structure in a vector (in wl_scan_results_t) -+ */ -+typedef struct wl_bss_info_108 { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ chanspec_t chanspec; /* chanspec for bss */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ -+ uint8 n_cap; /* BSS is 802.11N Capable */ -+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ -+ uint8 ctl_ch; /* 802.11N BSS control channel number */ -+ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */ -+ uint8 flags; /* flags */ -+ uint8 reserved[3]; /* Reserved for expansion of BSS properties */ -+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ -+ -+ uint16 ie_offset; /* offset at which IEs start, from beginning */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ /* Add new fields here */ -+ /* variable length Information Elements */ -+} wl_bss_info_108_t; -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */ -+ -+/* BSS info structure -+ * Applications MUST CHECK ie_offset field and length field to access IEs and -+ * next bss_info structure in a vector (in wl_scan_results_t) -+ */ -+typedef struct wl_bss_info { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ chanspec_t chanspec; /* chanspec for bss */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ -+ uint8 n_cap; /* BSS is 802.11N Capable */ -+ uint32 nbss_cap; /* 802.11N+AC BSS Capabilities */ -+ uint8 ctl_ch; /* 802.11N BSS control channel number */ -+ uint8 padding1[3]; /* explicit struct alignment padding */ -+ uint16 vht_rxmcsmap; /* VHT rx mcs map */ -+ uint16 vht_txmcsmap; /* VHT tx mcs map */ -+ uint8 flags; /* flags */ -+ uint8 vht_cap; /* BSS is vht capable */ -+ uint8 reserved[2]; /* Reserved for expansion of BSS properties */ -+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ -+ -+ uint16 ie_offset; /* offset at which IEs start, from beginning */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ int16 SNR; /* average SNR of during frame reception */ -+ /* Add new fields here */ -+ /* variable length Information Elements */ -+} wl_bss_info_t; -+ -+/* bss_info_cap_t flags */ -+#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ -+#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ -+#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */ -+ -+/* bssinfo flag for nbss_cap */ -+#define VHT_BI_SGI_80MHZ 0x00000100 -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+typedef struct wl_bsscfg { -+ uint32 wsec; -+ uint32 WPA_auth; -+ uint32 wsec_index; -+ uint32 associated; -+ uint32 BSS; -+ uint32 phytest_on; -+ struct ether_addr prev_BSSID; -+ struct ether_addr BSSID; -+ uint32 targetbss_wpa2_flags; -+ uint32 assoc_type; -+ uint32 assoc_state; -+} wl_bsscfg_t; -+ -+typedef struct wl_bss_config { -+ uint32 atim_window; -+ uint32 beacon_period; -+ uint32 chanspec; -+} wl_bss_config_t; -+ -+#define DLOAD_HANDLER_VER 1 /* Downloader version */ -+#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ -+#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ -+ -+#define DL_CRC_NOT_INUSE 0x0001 -+ -+/* generic download types & flags */ -+enum { -+ DL_TYPE_UCODE = 1, -+ DL_TYPE_CLM = 2 -+}; -+ -+/* ucode type values */ -+enum { -+ UCODE_FW, -+ INIT_VALS, -+ BS_INIT_VALS -+}; -+ -+struct wl_dload_data { -+ uint16 flag; -+ uint16 dload_type; -+ uint32 len; -+ uint32 crc; -+ uint8 data[1]; -+}; -+typedef struct wl_dload_data wl_dload_data_t; -+ -+struct wl_ucode_info { -+ uint32 ucode_type; -+ uint32 num_chunks; -+ uint32 chunk_len; -+ uint32 chunk_num; -+ uint8 data_chunk[1]; -+}; -+typedef struct wl_ucode_info wl_ucode_info_t; -+ -+struct wl_clm_dload_info { -+ uint32 ds_id; -+ uint32 clm_total_len; -+ uint32 num_chunks; -+ uint32 chunk_len; -+ uint32 chunk_offset; -+ uint8 data_chunk[1]; -+}; -+typedef struct wl_clm_dload_info wl_clm_dload_info_t; -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+typedef struct wlc_ssid { -+ uint32 SSID_len; -+ uchar SSID[32]; -+} wlc_ssid_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+#define MAX_PREFERRED_AP_NUM 5 -+typedef struct wlc_fastssidinfo { -+ uint32 SSID_channel[MAX_PREFERRED_AP_NUM]; -+ wlc_ssid_t SSID_info[MAX_PREFERRED_AP_NUM]; -+} wlc_fastssidinfo_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct wnm_url { -+ uint8 len; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT wnm_url_t; -+ -+typedef struct chan_scandata { -+ uint8 txpower; -+ uint8 pad; -+ chanspec_t channel; /* Channel num, bw, ctrl_sb and band */ -+ uint32 channel_mintime; -+ uint32 channel_maxtime; -+} chan_scandata_t; -+ -+typedef enum wl_scan_type { -+ EXTDSCAN_FOREGROUND_SCAN, -+ EXTDSCAN_BACKGROUND_SCAN, -+ EXTDSCAN_FORCEDBACKGROUND_SCAN -+} wl_scan_type_t; -+ -+#define WLC_EXTDSCAN_MAX_SSID 5 -+ -+typedef struct wl_extdscan_params { -+ int8 nprobes; /* 0, passive, otherwise active */ -+ int8 split_scan; /* split scan */ -+ int8 band; /* band */ -+ int8 pad; -+ wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */ -+ uint32 tx_rate; /* in 500ksec units */ -+ wl_scan_type_t scan_type; /* enum */ -+ int32 channel_num; -+ chan_scandata_t channel_list[1]; /* list of chandata structs */ -+} wl_extdscan_params_t; -+ -+#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t)) -+ -+#define WL_BSSTYPE_INFRA 1 -+#define WL_BSSTYPE_INDEP 0 -+#define WL_BSSTYPE_ANY 2 -+ -+/* Bitmask for scan_type */ -+#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */ -+#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */ -+#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */ -+ -+#define WL_SCAN_PARAMS_SSID_MAX 10 -+ -+typedef struct wl_scan_params { -+ wlc_ssid_t ssid; /* default: {0, ""} */ -+ struct ether_addr bssid; /* default: bcast */ -+ int8 bss_type; /* default: any, -+ * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT -+ */ -+ uint8 scan_type; /* flags, 0 use default */ -+ int32 nprobes; /* -1 use default, number of probes per channel */ -+ int32 active_time; /* -1 use default, dwell time per channel for -+ * active scanning -+ */ -+ int32 passive_time; /* -1 use default, dwell time per channel -+ * for passive scanning -+ */ -+ int32 home_time; /* -1 use default, dwell time for the home channel -+ * between channel scans -+ */ -+ int32 channel_num; /* count of channels and ssids that follow -+ * -+ * low half is count of channels in channel_list, 0 -+ * means default (use all available channels) -+ * -+ * high half is entries in wlc_ssid_t array that -+ * follows channel_list, aligned for int32 (4 bytes) -+ * meaning an odd channel count implies a 2-byte pad -+ * between end of channel_list and first ssid -+ * -+ * if ssid count is zero, single ssid in the fixed -+ * parameter portion is assumed, otherwise ssid in -+ * the fixed portion is ignored -+ */ -+ uint16 channel_list[1]; /* list of chanspecs */ -+} wl_scan_params_t; -+ -+/* size of wl_scan_params not including variable length array */ -+#define WL_SCAN_PARAMS_FIXED_SIZE 64 -+ -+/* masks for channel and ssid count */ -+#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -+#define WL_SCAN_PARAMS_NSSID_SHIFT 16 -+ -+#define WL_SCAN_ACTION_START 1 -+#define WL_SCAN_ACTION_CONTINUE 2 -+#define WL_SCAN_ACTION_ABORT 3 -+ -+#define ISCAN_REQ_VERSION 1 -+ -+/* incremental scan struct */ -+typedef struct wl_iscan_params { -+ uint32 version; -+ uint16 action; -+ uint16 scan_duration; -+ wl_scan_params_t params; -+} wl_iscan_params_t; -+ -+/* 3 fields + size of wl_scan_params, not including variable length array */ -+#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+typedef struct wl_scan_results { -+ uint32 buflen; -+ uint32 version; -+ uint32 count; -+ wl_bss_info_t bss_info[1]; -+} wl_scan_results_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* size of wl_scan_results not including variable length array */ -+#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) -+ -+/* wl_iscan_results status values */ -+#define WL_SCAN_RESULTS_SUCCESS 0 -+#define WL_SCAN_RESULTS_PARTIAL 1 -+#define WL_SCAN_RESULTS_PENDING 2 -+#define WL_SCAN_RESULTS_ABORTED 3 -+#define WL_SCAN_RESULTS_NO_MEM 4 -+ -+/* Used in EXT_STA */ -+#define DNGL_RXCTXT_SIZE 45 -+ -+ -+#define ESCAN_REQ_VERSION 1 -+ -+typedef struct wl_escan_params { -+ uint32 version; -+ uint16 action; -+ uint16 sync_id; -+ wl_scan_params_t params; -+} wl_escan_params_t; -+ -+#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) -+ -+typedef struct wl_escan_result { -+ uint32 buflen; -+ uint32 version; -+ uint16 sync_id; -+ uint16 bss_count; -+ wl_bss_info_t bss_info[1]; -+} wl_escan_result_t; -+ -+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) -+ -+/* incremental scan results struct */ -+typedef struct wl_iscan_results { -+ uint32 status; -+ wl_scan_results_t results; -+} wl_iscan_results_t; -+ -+/* size of wl_iscan_results not including variable length array */ -+#define WL_ISCAN_RESULTS_FIXED_SIZE \ -+ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) -+ -+typedef struct wl_probe_params { -+ wlc_ssid_t ssid; -+ struct ether_addr bssid; -+ struct ether_addr mac; -+} wl_probe_params_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ -+typedef struct wl_rateset { -+ uint32 count; /* # rates in this set */ -+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ -+} wl_rateset_t; -+ -+typedef struct wl_rateset_args { -+ uint32 count; /* # rates in this set */ -+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ -+ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -+} wl_rateset_args_t; -+ -+/* uint32 list */ -+typedef struct wl_uint32_list { -+ /* in - # of elements, out - # of entries */ -+ uint32 count; -+ /* variable length uint32 list */ -+ uint32 element[1]; -+} wl_uint32_list_t; -+ -+/* used for association with a specific BSSID and chanspec list */ -+typedef struct wl_assoc_params { -+ struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ -+ uint16 bssid_cnt; /* 0: use chanspec_num, and the single bssid, -+ * otherwise count of chanspecs in chanspec_list -+ * AND paired bssids following chanspec_list -+ */ -+ int32 chanspec_num; /* 0: all available channels, -+ * otherwise count of chanspecs in chanspec_list -+ */ -+ chanspec_t chanspec_list[1]; /* list of chanspecs */ -+} wl_assoc_params_t; -+#define WL_ASSOC_PARAMS_FIXED_SIZE OFFSETOF(wl_assoc_params_t, chanspec_list) -+ -+/* used for reassociation/roam to a specific BSSID and channel */ -+typedef wl_assoc_params_t wl_reassoc_params_t; -+#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE -+ -+/* used for association to a specific BSSID and channel */ -+typedef wl_assoc_params_t wl_join_assoc_params_t; -+#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE -+ -+/* used for join with or without a specific bssid and channel list */ -+typedef struct wl_join_params { -+ wlc_ssid_t ssid; -+ wl_assoc_params_t params; /* optional field, but it must include the fixed portion -+ * of the wl_assoc_params_t struct when it does present. -+ */ -+} wl_join_params_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \ -+ WL_ASSOC_PARAMS_FIXED_SIZE) -+/* scan params for extended join */ -+typedef struct wl_join_scan_params { -+ uint8 scan_type; /* 0 use default, active or passive scan */ -+ int32 nprobes; /* -1 use default, number of probes per channel */ -+ int32 active_time; /* -1 use default, dwell time per channel for -+ * active scanning -+ */ -+ int32 passive_time; /* -1 use default, dwell time per channel -+ * for passive scanning -+ */ -+ int32 home_time; /* -1 use default, dwell time for the home channel -+ * between channel scans -+ */ -+} wl_join_scan_params_t; -+ -+/* extended join params */ -+typedef struct wl_extjoin_params { -+ wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ -+ wl_join_scan_params_t scan; -+ wl_join_assoc_params_t assoc; /* optional field, but it must include the fixed portion -+ * of the wl_join_assoc_params_t struct when it does -+ * present. -+ */ -+} wl_extjoin_params_t; -+#define WL_EXTJOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_extjoin_params_t, assoc) + \ -+ WL_JOIN_ASSOC_PARAMS_FIXED_SIZE) -+ -+/* All builds use the new 11ac ratespec/chanspec */ -+#undef D11AC_IOTYPES -+#define D11AC_IOTYPES -+ -+#ifndef D11AC_IOTYPES -+ -+/* defines used by the nrate iovar */ -+#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -+#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -+#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -+#define NRATE_STF_SHIFT 8 /* stf mode shift */ -+#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -+#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ -+#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ -+#define NRATE_SGI_SHIFT 23 /* sgi mode */ -+#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -+#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ -+ -+#define NRATE_STF_SISO 0 /* stf mode SISO */ -+#define NRATE_STF_CDD 1 /* stf mode CDD */ -+#define NRATE_STF_STBC 2 /* stf mode STBC */ -+#define NRATE_STF_SDM 3 /* stf mode SDM */ -+ -+#else /* D11AC_IOTYPES */ -+ -+/* WL_RSPEC defines for rate information */ -+#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ -+#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ -+#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ -+#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ -+#define WL_RSPEC_TXEXP_MASK 0x00000300 -+#define WL_RSPEC_TXEXP_SHIFT 8 -+#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ -+#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ -+#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ -+#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ -+#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ -+#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ -+#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ -+#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ -+ -+/* WL_RSPEC_ENCODING field defs */ -+#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ -+#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ -+#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ -+ -+/* WL_RSPEC_BW field defs */ -+#define WL_RSPEC_BW_UNSPECIFIED 0 -+#define WL_RSPEC_BW_20MHZ 0x00010000 -+#define WL_RSPEC_BW_40MHZ 0x00020000 -+#define WL_RSPEC_BW_80MHZ 0x00030000 -+#define WL_RSPEC_BW_160MHZ 0x00040000 -+ -+/* Legacy defines for the nrate iovar */ -+#define OLD_NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -+#define OLD_NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -+#define OLD_NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -+#define OLD_NRATE_STF_SHIFT 8 /* stf mode shift */ -+#define OLD_NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -+#define OLD_NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ -+#define OLD_NRATE_SGI 0x00800000 /* sgi mode */ -+#define OLD_NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -+ -+#define OLD_NRATE_STF_SISO 0 /* stf mode SISO */ -+#define OLD_NRATE_STF_CDD 1 /* stf mode CDD */ -+#define OLD_NRATE_STF_STBC 2 /* stf mode STBC */ -+#define OLD_NRATE_STF_SDM 3 /* stf mode SDM */ -+ -+#endif /* D11AC_IOTYPES */ -+ -+#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ -+#define ANTENNA_NUM_2 2 -+#define ANTENNA_NUM_3 3 -+#define ANTENNA_NUM_4 4 -+ -+#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ -+#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ -+#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ -+#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ -+#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ -+#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ -+#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ -+ -+#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ -+ -+typedef struct { -+ uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ -+ uint8 num_antcfg; /* number of available antenna configurations */ -+} wlc_antselcfg_t; -+ -+#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ -+ -+#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ -+#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ -+ -+#define IBSS_MED 15 /* Mediom in-bss congestion percentage */ -+#define IBSS_HI 25 /* Hi in-bss congestion percentage */ -+#define OBSS_MED 12 -+#define OBSS_HI 25 -+#define INTERFER_MED 5 -+#define INTERFER_HI 10 -+ -+#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */ -+#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */ -+#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */ -+#define CCA_FLAGS_PREFER_1_6_11 0x10 -+#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */ -+ -+#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */ -+#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */ -+#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */ -+#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */ -+#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */ -+ -+typedef struct { -+ uint32 duration; /* millisecs spent sampling this channel */ -+ uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */ -+ /* move if cur bss moves channels) */ -+ uint32 congest_obss; /* traffic not in our bss */ -+ uint32 interference; /* millisecs detecting a non 802.11 interferer. */ -+ uint32 timestamp; /* second timestamp */ -+} cca_congest_t; -+ -+typedef struct { -+ chanspec_t chanspec; /* Which channel? */ -+ uint8 num_secs; /* How many secs worth of data */ -+ cca_congest_t secs[1]; /* Data */ -+} cca_congest_channel_req_t; -+ -+/* interference source detection and identification mode */ -+#define ITFR_MODE_DISABLE 0 /* disable feature */ -+#define ITFR_MODE_MANUAL_ENABLE 1 /* enable manual detection */ -+#define ITFR_MODE_AUTO_ENABLE 2 /* enable auto detection */ -+ -+/* interference sources */ -+enum interference_source { -+ ITFR_NONE = 0, /* interference */ -+ ITFR_PHONE, /* wireless phone */ -+ ITFR_VIDEO_CAMERA, /* wireless video camera */ -+ ITFR_MICROWAVE_OVEN, /* microwave oven */ -+ ITFR_BABY_MONITOR, /* wireless baby monitor */ -+ ITFR_BLUETOOTH, /* bluetooth */ -+ ITFR_VIDEO_CAMERA_OR_BABY_MONITOR, /* wireless camera or baby monitor */ -+ ITFR_BLUETOOTH_OR_BABY_MONITOR, /* bluetooth or baby monitor */ -+ ITFR_VIDEO_CAMERA_OR_PHONE, /* video camera or phone */ -+ ITFR_UNIDENTIFIED /* interference from unidentified source */ -+}; -+ -+/* structure for interference source report */ -+typedef struct { -+ uint32 flags; /* flags. bit definitions below */ -+ uint32 source; /* last detected interference source */ -+ uint32 timestamp; /* second timestamp on interferenced flag change */ -+} interference_source_rep_t; -+ -+/* bit definitions for flags in interference source report */ -+#define ITFR_INTERFERENCED 1 /* interference detected */ -+#define ITFR_HOME_CHANNEL 2 /* home channel has interference */ -+#define ITFR_NOISY_ENVIRONMENT 4 /* noisy environemnt so feature stopped */ -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+typedef struct wl_country { -+ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in -+ * the Country IE -+ */ -+ int32 rev; /* revision specifier for ccode -+ * on set, -1 indicates unspecified. -+ * on get, rev >= 0 -+ */ -+ char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code. -+ * variable length, but fixed size in -+ * struct allows simple allocation for -+ * expected country strings <= 3 chars. -+ */ -+} wl_country_t; -+ -+typedef struct wl_channels_in_country { -+ uint32 buflen; -+ uint32 band; -+ char country_abbrev[WLC_CNTRY_BUF_SZ]; -+ uint32 count; -+ uint32 channel[1]; -+} wl_channels_in_country_t; -+ -+typedef struct wl_country_list { -+ uint32 buflen; -+ uint32 band_set; -+ uint32 band; -+ uint32 count; -+ char country_abbrev[1]; -+} wl_country_list_t; -+ -+#define WL_NUM_RPI_BINS 8 -+#define WL_RM_TYPE_BASIC 1 -+#define WL_RM_TYPE_CCA 2 -+#define WL_RM_TYPE_RPI 3 -+ -+#define WL_RM_FLAG_PARALLEL (1<<0) -+ -+#define WL_RM_FLAG_LATE (1<<1) -+#define WL_RM_FLAG_INCAPABLE (1<<2) -+#define WL_RM_FLAG_REFUSED (1<<3) -+ -+typedef struct wl_rm_req_elt { -+ int8 type; -+ int8 flags; -+ chanspec_t chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+} wl_rm_req_elt_t; -+ -+typedef struct wl_rm_req { -+ uint32 token; /* overall measurement set token */ -+ uint32 count; /* number of measurement requests */ -+ void *cb; /* completion callback function: may be NULL */ -+ void *cb_arg; /* arg to completion callback function */ -+ wl_rm_req_elt_t req[1]; /* variable length block of requests */ -+} wl_rm_req_t; -+#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) -+ -+typedef struct wl_rm_rep_elt { -+ int8 type; -+ int8 flags; -+ chanspec_t chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+ uint32 len; /* byte length of data block */ -+ uint8 data[1]; /* variable length data block */ -+} wl_rm_rep_elt_t; -+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ -+ -+#define WL_RPI_REP_BIN_NUM 8 -+typedef struct wl_rm_rpi_rep { -+ uint8 rpi[WL_RPI_REP_BIN_NUM]; -+ int8 rpi_max[WL_RPI_REP_BIN_NUM]; -+} wl_rm_rpi_rep_t; -+ -+typedef struct wl_rm_rep { -+ uint32 token; /* overall measurement set token */ -+ uint32 len; /* length of measurement report block */ -+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ -+} wl_rm_rep_t; -+#define WL_RM_REP_FIXED_LEN 8 -+ -+ -+typedef enum sup_auth_status { -+ /* Basic supplicant authentication states */ -+ WLC_SUP_DISCONNECTED = 0, -+ WLC_SUP_CONNECTING, -+ WLC_SUP_IDREQUIRED, -+ WLC_SUP_AUTHENTICATING, -+ WLC_SUP_AUTHENTICATED, -+ WLC_SUP_KEYXCHANGE, -+ WLC_SUP_KEYED, -+ WLC_SUP_TIMEOUT, -+ WLC_SUP_LAST_BASIC_STATE, -+ -+ /* Extended supplicant authentication states */ -+ /* Waiting to receive handshake msg M1 */ -+ WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, -+ /* Preparing to send handshake msg M2 */ -+ WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, -+ /* Waiting to receive handshake msg M3 */ -+ WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, -+ WLC_SUP_KEYXCHANGE_PREP_M4, /* Preparing to send handshake msg M4 */ -+ WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */ -+ WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */ -+} sup_auth_status_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Enumerate crypto algorithms */ -+#define CRYPTO_ALGO_OFF 0 -+#define CRYPTO_ALGO_WEP1 1 -+#define CRYPTO_ALGO_TKIP 2 -+#define CRYPTO_ALGO_WEP128 3 -+#define CRYPTO_ALGO_AES_CCM 4 -+#define CRYPTO_ALGO_AES_OCB_MSDU 5 -+#define CRYPTO_ALGO_AES_OCB_MPDU 6 -+#if !defined(BCMEXTCCX) -+#define CRYPTO_ALGO_NALG 7 -+#else -+#define CRYPTO_ALGO_CKIP 7 -+#define CRYPTO_ALGO_CKIP_MMH 8 -+#define CRYPTO_ALGO_WEP_MMH 9 -+#define CRYPTO_ALGO_NALG 10 -+#endif -+#ifdef BCMWAPI_WPI -+#define CRYPTO_ALGO_SMS4 11 -+#endif /* BCMWAPI_WPI */ -+#define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */ -+ -+#define WSEC_GEN_MIC_ERROR 0x0001 -+#define WSEC_GEN_REPLAY 0x0002 -+#define WSEC_GEN_ICV_ERROR 0x0004 -+#define WSEC_GEN_MFP_ACT_ERROR 0x0008 -+#define WSEC_GEN_MFP_DISASSOC_ERROR 0x0010 -+#define WSEC_GEN_MFP_DEAUTH_ERROR 0x0020 -+ -+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -+#if defined(BCMEXTCCX) -+#define WL_CKIP_KP (1 << 4) /* CMIC */ -+#define WL_CKIP_MMH (1 << 5) /* CKIP */ -+#else -+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -+#endif -+#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ -+ -+typedef struct wl_wsec_key { -+ uint32 index; /* key index */ -+ uint32 len; /* key length */ -+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ -+ uint32 pad_1[18]; -+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ -+ uint32 flags; /* misc flags */ -+ uint32 pad_2[2]; -+ int pad_3; -+ int iv_initialized; /* has IV been initialized already? */ -+ int pad_4; -+ /* Rx IV */ -+ struct { -+ uint32 hi; /* upper 32 bits of IV */ -+ uint16 lo; /* lower 16 bits of IV */ -+ } rxiv; -+ uint32 pad_5[2]; -+ struct ether_addr ea; /* per station */ -+} wl_wsec_key_t; -+ -+#define WSEC_MIN_PSK_LEN 8 -+#define WSEC_MAX_PSK_LEN 64 -+ -+/* Flag for key material needing passhash'ing */ -+#define WSEC_PASSPHRASE (1<<0) -+ -+/* receptacle for WLC_SET_WSEC_PMK parameter */ -+typedef struct { -+ ushort key_len; /* octets in key material */ -+ ushort flags; /* key handling qualification */ -+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ -+} wsec_pmk_t; -+ -+/* wireless security bitvec */ -+#define WEP_ENABLED 0x0001 -+#define TKIP_ENABLED 0x0002 -+#define AES_ENABLED 0x0004 -+#define WSEC_SWFLAG 0x0008 -+#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ -+ -+/* wsec macros for operating on the above definitions */ -+#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED) -+#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED) -+#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED) -+ -+#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -+#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) -+#ifdef BCMWAPI_WPI -+#define SMS4_ENABLED 0x0100 -+#endif /* BCMWAPI_WPI */ -+ -+#ifdef MFP -+#define MFP_CAPABLE 0x0200 -+#define MFP_REQUIRED 0x0400 -+#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ -+#endif /* MFP */ -+ -+/* WPA authentication mode bitvec */ -+#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ -+#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ -+#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ -+#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -+#if defined(BCMEXTCCX) -+#define WPA_AUTH_CCKM 0x0008 /* CCKM */ -+#define WPA2_AUTH_CCKM 0x0010 /* CCKM2 */ -+#endif -+/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ -+#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ -+#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ -+#define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */ -+#define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */ -+#ifdef BCMWAPI_WAI -+#define WPA_AUTH_WAPI 0x0400 -+#define WAPI_AUTH_NONE WPA_AUTH_NONE /* none (IBSS) */ -+#define WAPI_AUTH_UNSPECIFIED 0x0400 /* over AS */ -+#define WAPI_AUTH_PSK 0x0800 /* Pre-shared key */ -+#endif /* BCMWAPI_WAI */ -+#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ -+#define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ -+#define WPA2_AUTH_FT 0x4000 /* Fast Transition. */ -+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ -+ -+/* pmkid */ -+#define MAXPMKID 16 -+ -+typedef struct _pmkid { -+ struct ether_addr BSSID; -+ uint8 PMKID[WPA2_PMKID_LEN]; -+} pmkid_t; -+ -+typedef struct _pmkid_list { -+ uint32 npmkid; -+ pmkid_t pmkid[1]; -+} pmkid_list_t; -+ -+typedef struct _pmkid_cand { -+ struct ether_addr BSSID; -+ uint8 preauth; -+} pmkid_cand_t; -+ -+typedef struct _pmkid_cand_list { -+ uint32 npmkid_cand; -+ pmkid_cand_t pmkid_cand[1]; -+} pmkid_cand_list_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+typedef struct wl_assoc_info { -+ uint32 req_len; -+ uint32 resp_len; -+ uint32 flags; -+ struct dot11_assoc_req req; -+ struct ether_addr reassoc_bssid; /* used in reassoc's */ -+ struct dot11_assoc_resp resp; -+} wl_assoc_info_t; -+ -+/* flags */ -+#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ -+ -+typedef struct wl_led_info { -+ uint32 index; /* led index */ -+ uint32 behavior; -+ uint8 activehi; -+} wl_led_info_t; -+ -+ -+/* srom read/write struct passed through ioctl */ -+typedef struct { -+ uint byteoff; /* byte offset */ -+ uint nbytes; /* number of bytes */ -+ uint16 buf[1]; -+} srom_rw_t; -+ -+/* similar cis (srom or otp) struct [iovar: may not be aligned] */ -+typedef struct { -+ uint32 source; /* cis source */ -+ uint32 byteoff; /* byte offset */ -+ uint32 nbytes; /* number of bytes */ -+ /* data follows here */ -+} cis_rw_t; -+ -+#define WLC_CIS_DEFAULT 0 /* built-in default */ -+#define WLC_CIS_SROM 1 /* source is sprom */ -+#define WLC_CIS_OTP 2 /* source is otp */ -+ -+/* R_REG and W_REG struct passed through ioctl */ -+typedef struct { -+ uint32 byteoff; /* byte offset of the field in d11regs_t */ -+ uint32 val; /* read/write value of the field */ -+ uint32 size; /* sizeof the field */ -+ uint band; /* band (optional) */ -+} rw_reg_t; -+ -+/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ -+/* PCL - Power Control Loop */ -+/* current gain setting is replaced by user input */ -+#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ -+#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ -+/* current gain setting is maintained */ -+#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ -+ -+typedef struct { -+ uint16 auto_ctrl; /* WL_ATTEN_XX */ -+ uint16 bb; /* Baseband attenuation */ -+ uint16 radio; /* Radio attenuation */ -+ uint16 txctl1; /* Radio TX_CTL1 value */ -+} atten_t; -+ -+/* Per-AC retry parameters */ -+struct wme_tx_params_s { -+ uint8 short_retry; -+ uint8 short_fallback; -+ uint8 long_retry; -+ uint8 long_fallback; -+ uint16 max_rate; /* In units of 512 Kbps */ -+}; -+ -+typedef struct wme_tx_params_s wme_tx_params_t; -+ -+#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) -+ -+/* defines used by poweridx iovar - it controls power in a-band */ -+/* current gain setting is maintained */ -+#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ -+#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ -+#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ -+#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ -+/* value >= 0 causes -+ * - input to be set to that value -+ * - PCL to be off -+ */ -+ -+/* Used to get specific link/ac parameters */ -+typedef struct { -+ int ac; -+ uint8 val; -+ struct ether_addr ea; -+} link_val_t; -+ -+#define BCM_MAC_STATUS_INDICATION (0x40010200L) -+ -+typedef struct { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* length in bytes of this structure */ -+ uint16 cap; /* sta's advertised capabilities */ -+ uint32 flags; /* flags defined below */ -+ uint32 idle; /* time since data pkt rx'd from sta */ -+ struct ether_addr ea; /* Station address */ -+ wl_rateset_t rateset; /* rateset in use */ -+ uint32 in; /* seconds elapsed since associated */ -+ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ -+ uint32 tx_pkts; /* # of packets transmitted */ -+ uint32 tx_failures; /* # of packets failed */ -+ uint32 rx_ucast_pkts; /* # of unicast packets received */ -+ uint32 rx_mcast_pkts; /* # of multicast packets received */ -+ uint32 tx_rate; /* Rate of last successful tx frame */ -+ uint32 rx_rate; /* Rate of last successful rx frame */ -+ uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -+ uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */ -+} sta_info_t; -+ -+#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) -+ -+#define WL_STA_VER 3 -+ -+/* Flags for sta_info_t indicating properties of STA */ -+#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ -+#define WL_STA_WME 0x2 /* WMM association */ -+#define WL_STA_UNUSED 0x4 -+#define WL_STA_AUTHE 0x8 /* Authenticated */ -+#define WL_STA_ASSOC 0x10 /* Associated */ -+#define WL_STA_AUTHO 0x20 /* Authorized */ -+#define WL_STA_WDS 0x40 /* Wireless Distribution System */ -+#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ -+#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ -+#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ -+#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ -+#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ -+#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ -+#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ -+#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */ -+ -+#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ -+ -+/* Values for TX Filter override mode */ -+#define WLC_TXFILTER_OVERRIDE_DISABLED 0 -+#define WLC_TXFILTER_OVERRIDE_ENABLED 1 -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Used to get specific STA parameters */ -+typedef struct { -+ uint32 val; -+ struct ether_addr ea; -+} scb_val_t; -+ -+/* Used by iovar versions of some ioctls, i.e. WLC_SCB_AUTHORIZE et al */ -+typedef struct { -+ uint32 code; -+ scb_val_t ioctl_args; -+} authops_t; -+ -+/* channel encoding */ -+typedef struct channel_info { -+ int hw_channel; -+ int target_channel; -+ int scan_channel; -+} channel_info_t; -+ -+/* For ioctls that take a list of MAC addresses */ -+struct maclist { -+ uint count; /* number of MAC addresses */ -+ struct ether_addr ea[1]; /* variable length array of MAC addresses */ -+}; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* get pkt count struct passed through ioctl */ -+typedef struct get_pktcnt { -+ uint rx_good_pkt; -+ uint rx_bad_pkt; -+ uint tx_good_pkt; -+ uint tx_bad_pkt; -+ uint rx_ocast_good_pkt; /* unicast packets destined for others */ -+} get_pktcnt_t; -+ -+/* NINTENDO2 */ -+#define LQ_IDX_MIN 0 -+#define LQ_IDX_MAX 1 -+#define LQ_IDX_AVG 2 -+#define LQ_IDX_SUM 2 -+#define LQ_IDX_LAST 3 -+#define LQ_STOP_MONITOR 0 -+#define LQ_START_MONITOR 1 -+ -+/* Get averages RSSI, Rx PHY rate and SNR values */ -+typedef struct { -+ int rssi[LQ_IDX_LAST]; /* Array to keep min, max, avg rssi */ -+ int snr[LQ_IDX_LAST]; /* Array to keep min, max, avg snr */ -+ int isvalid; /* Flag indicating whether above data is valid */ -+} wl_lq_t; /* Link Quality */ -+ -+typedef enum wl_wakeup_reason_type { -+ LCD_ON = 1, -+ LCD_OFF, -+ DRC1_WAKE, -+ DRC2_WAKE, -+ REASON_LAST -+} wl_wr_type_t; -+ -+typedef struct { -+/* Unique filter id */ -+ uint32 id; -+ -+/* stores the reason for the last wake up */ -+ uint8 reason; -+} wl_wr_t; -+ -+/* Get MAC specific rate histogram command */ -+typedef struct { -+ struct ether_addr ea; /* MAC Address */ -+ uint8 ac_cat; /* Access Category */ -+ uint8 num_pkts; /* Number of packet entries to be averaged */ -+} wl_mac_ratehisto_cmd_t; /* MAC Specific Rate Histogram command */ -+ -+/* Get MAC rate histogram response */ -+typedef struct { -+ uint32 rate[WLC_MAXRATE + 1]; /* Rates */ -+ uint32 mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX]; /* MCS counts */ -+ uint32 vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX]; /* VHT counts */ -+ uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ -+} wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */ -+ -+/* Values for TX Filter override mode */ -+#define WLC_TXFILTER_OVERRIDE_DISABLED 0 -+#define WLC_TXFILTER_OVERRIDE_ENABLED 1 -+ -+#define WL_IOCTL_ACTION_GET 0x0 -+#define WL_IOCTL_ACTION_SET 0x1 -+#define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e -+#define WL_IOCTL_ACTION_OVL_RSV 0x20 -+#define WL_IOCTL_ACTION_OVL 0x40 -+#define WL_IOCTL_ACTION_MASK 0x7e -+#define WL_IOCTL_ACTION_OVL_SHIFT 1 -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Linux network driver ioctl encoding */ -+typedef struct wl_ioctl { -+ uint cmd; /* common ioctl definition */ -+ void *buf; /* pointer to user buffer */ -+ uint len; /* length of user buffer */ -+ uint8 set; /* 1=set IOCTL; 0=query IOCTL */ -+ uint used; /* bytes read or written (optional) */ -+ uint needed; /* bytes needed (optional) */ -+} wl_ioctl_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+/* reference to wl_ioctl_t struct used by usermode driver */ -+#define ioctl_subtype set /* subtype param */ -+#define ioctl_pid used /* pid param */ -+#define ioctl_status needed /* status param */ -+ -+/* -+ * Structure for passing hardware and software -+ * revision info up from the driver. -+ */ -+typedef struct wlc_rev_info { -+ uint vendorid; /* PCI vendor id */ -+ uint deviceid; /* device id of chip */ -+ uint radiorev; /* radio revision */ -+ uint chiprev; /* chip revision */ -+ uint corerev; /* core revision */ -+ uint boardid; /* board identifier (usu. PCI sub-device id) */ -+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ -+ uint boardrev; /* board revision */ -+ uint driverrev; /* driver version */ -+ uint ucoderev; /* microcode version */ -+ uint bus; /* bus type */ -+ uint chipnum; /* chip number */ -+ uint phytype; /* phy type */ -+ uint phyrev; /* phy revision */ -+ uint anarev; /* anacore rev */ -+ uint chippkg; /* chip package info */ -+} wlc_rev_info_t; -+ -+#define WL_REV_INFO_LEGACY_LENGTH 48 -+ -+#define WL_BRAND_MAX 10 -+typedef struct wl_instance_info { -+ uint instance; -+ char brand[WL_BRAND_MAX]; -+} wl_instance_info_t; -+ -+/* structure to change size of tx fifo */ -+typedef struct wl_txfifo_sz { -+ uint16 magic; -+ uint16 fifo; -+ uint16 size; -+} wl_txfifo_sz_t; -+/* magic pattern used for mismatch driver and wl */ -+#define WL_TXFIFO_SZ_MAGIC 0xa5a5 -+ -+/* Transfer info about an IOVar from the driver */ -+/* Max supported IOV name size in bytes, + 1 for nul termination */ -+#define WLC_IOV_NAME_LEN 30 -+typedef struct wlc_iov_trx_s { -+ uint8 module; -+ uint8 type; -+ char name[WLC_IOV_NAME_LEN]; -+} wlc_iov_trx_t; -+ -+/* check this magic number */ -+#define WLC_IOCTL_MAGIC 0x14e46c77 -+ -+/* bump this number if you change the ioctl interface */ -+#ifdef D11AC_IOTYPES -+#define WLC_IOCTL_VERSION 2 -+#define WLC_IOCTL_VERSION_LEGACY_IOTYPES 1 -+#else -+#define WLC_IOCTL_VERSION 1 -+#endif /* D11AC_IOTYPES */ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -+#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ -+#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ -+#if defined(LCNCONF) || defined(LCN40CONF) -+#define WLC_SAMPLECOLLECT_MAXLEN 8192 /* Max Sample Collect buffer */ -+#else -+#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */ -+#endif -+ -+/* common ioctl definitions */ -+#define WLC_GET_MAGIC 0 -+#define WLC_GET_VERSION 1 -+#define WLC_UP 2 -+#define WLC_DOWN 3 -+#define WLC_GET_LOOP 4 -+#define WLC_SET_LOOP 5 -+#define WLC_DUMP 6 -+#define WLC_GET_MSGLEVEL 7 -+#define WLC_SET_MSGLEVEL 8 -+#define WLC_GET_PROMISC 9 -+#define WLC_SET_PROMISC 10 -+/* #define WLC_OVERLAY_IOCTL 11 */ /* not supported */ -+#define WLC_GET_RATE 12 -+#define WLC_GET_MAX_RATE 13 -+#define WLC_GET_INSTANCE 14 -+/* #define WLC_GET_FRAG 15 */ /* no longer supported */ -+/* #define WLC_SET_FRAG 16 */ /* no longer supported */ -+/* #define WLC_GET_RTS 17 */ /* no longer supported */ -+/* #define WLC_SET_RTS 18 */ /* no longer supported */ -+#define WLC_GET_INFRA 19 -+#define WLC_SET_INFRA 20 -+#define WLC_GET_AUTH 21 -+#define WLC_SET_AUTH 22 -+#define WLC_GET_BSSID 23 -+#define WLC_SET_BSSID 24 -+#define WLC_GET_SSID 25 -+#define WLC_SET_SSID 26 -+#define WLC_RESTART 27 -+#define WLC_TERMINATED 28 -+/* #define WLC_DUMP_SCB 28 */ /* no longer supported */ -+#define WLC_GET_CHANNEL 29 -+#define WLC_SET_CHANNEL 30 -+#define WLC_GET_SRL 31 -+#define WLC_SET_SRL 32 -+#define WLC_GET_LRL 33 -+#define WLC_SET_LRL 34 -+#define WLC_GET_PLCPHDR 35 -+#define WLC_SET_PLCPHDR 36 -+#define WLC_GET_RADIO 37 -+#define WLC_SET_RADIO 38 -+#define WLC_GET_PHYTYPE 39 -+#define WLC_DUMP_RATE 40 -+#define WLC_SET_RATE_PARAMS 41 -+#define WLC_GET_FIXRATE 42 -+#define WLC_SET_FIXRATE 43 -+/* #define WLC_GET_WEP 42 */ /* no longer supported */ -+/* #define WLC_SET_WEP 43 */ /* no longer supported */ -+#define WLC_GET_KEY 44 -+#define WLC_SET_KEY 45 -+#define WLC_GET_REGULATORY 46 -+#define WLC_SET_REGULATORY 47 -+#define WLC_GET_PASSIVE_SCAN 48 -+#define WLC_SET_PASSIVE_SCAN 49 -+#define WLC_SCAN 50 -+#define WLC_SCAN_RESULTS 51 -+#define WLC_DISASSOC 52 -+#define WLC_REASSOC 53 -+#define WLC_GET_ROAM_TRIGGER 54 -+#define WLC_SET_ROAM_TRIGGER 55 -+#define WLC_GET_ROAM_DELTA 56 -+#define WLC_SET_ROAM_DELTA 57 -+#define WLC_GET_ROAM_SCAN_PERIOD 58 -+#define WLC_SET_ROAM_SCAN_PERIOD 59 -+#define WLC_EVM 60 /* diag */ -+#define WLC_GET_TXANT 61 -+#define WLC_SET_TXANT 62 -+#define WLC_GET_ANTDIV 63 -+#define WLC_SET_ANTDIV 64 -+/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ -+/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ -+#define WLC_GET_CLOSED 67 -+#define WLC_SET_CLOSED 68 -+#define WLC_GET_MACLIST 69 -+#define WLC_SET_MACLIST 70 -+#define WLC_GET_RATESET 71 -+#define WLC_SET_RATESET 72 -+/* #define WLC_GET_LOCALE 73 */ /* no longer supported */ -+#define WLC_LONGTRAIN 74 -+#define WLC_GET_BCNPRD 75 -+#define WLC_SET_BCNPRD 76 -+#define WLC_GET_DTIMPRD 77 -+#define WLC_SET_DTIMPRD 78 -+#define WLC_GET_SROM 79 -+#define WLC_SET_SROM 80 -+#define WLC_GET_WEP_RESTRICT 81 -+#define WLC_SET_WEP_RESTRICT 82 -+#define WLC_GET_COUNTRY 83 -+#define WLC_SET_COUNTRY 84 -+#define WLC_GET_PM 85 -+#define WLC_SET_PM 86 -+#define WLC_GET_WAKE 87 -+#define WLC_SET_WAKE 88 -+/* #define WLC_GET_D11CNTS 89 */ /* -> "counters" iovar */ -+#define WLC_GET_FORCELINK 90 /* ndis only */ -+#define WLC_SET_FORCELINK 91 /* ndis only */ -+#define WLC_FREQ_ACCURACY 92 /* diag */ -+#define WLC_CARRIER_SUPPRESS 93 /* diag */ -+#define WLC_GET_PHYREG 94 -+#define WLC_SET_PHYREG 95 -+#define WLC_GET_RADIOREG 96 -+#define WLC_SET_RADIOREG 97 -+#define WLC_GET_REVINFO 98 -+#define WLC_GET_UCANTDIV 99 -+#define WLC_SET_UCANTDIV 100 -+#define WLC_R_REG 101 -+#define WLC_W_REG 102 -+/* #define WLC_DIAG_LOOPBACK 103 old tray diag */ -+/* #define WLC_RESET_D11CNTS 104 */ /* -> "reset_d11cnts" iovar */ -+#define WLC_GET_MACMODE 105 -+#define WLC_SET_MACMODE 106 -+#define WLC_GET_MONITOR 107 -+#define WLC_SET_MONITOR 108 -+#define WLC_GET_GMODE 109 -+#define WLC_SET_GMODE 110 -+#define WLC_GET_LEGACY_ERP 111 -+#define WLC_SET_LEGACY_ERP 112 -+#define WLC_GET_RX_ANT 113 -+#define WLC_GET_CURR_RATESET 114 /* current rateset */ -+#define WLC_GET_SCANSUPPRESS 115 -+#define WLC_SET_SCANSUPPRESS 116 -+#define WLC_GET_AP 117 -+#define WLC_SET_AP 118 -+#define WLC_GET_EAP_RESTRICT 119 -+#define WLC_SET_EAP_RESTRICT 120 -+#define WLC_SCB_AUTHORIZE 121 -+#define WLC_SCB_DEAUTHORIZE 122 -+#define WLC_GET_WDSLIST 123 -+#define WLC_SET_WDSLIST 124 -+#define WLC_GET_ATIM 125 -+#define WLC_SET_ATIM 126 -+#define WLC_GET_RSSI 127 -+#define WLC_GET_PHYANTDIV 128 -+#define WLC_SET_PHYANTDIV 129 -+#define WLC_AP_RX_ONLY 130 -+#define WLC_GET_TX_PATH_PWR 131 -+#define WLC_SET_TX_PATH_PWR 132 -+#define WLC_GET_WSEC 133 -+#define WLC_SET_WSEC 134 -+#define WLC_GET_PHY_NOISE 135 -+#define WLC_GET_BSS_INFO 136 -+#define WLC_GET_PKTCNTS 137 -+#define WLC_GET_LAZYWDS 138 -+#define WLC_SET_LAZYWDS 139 -+#define WLC_GET_BANDLIST 140 -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WLC_GET_BAND 141 -+#define WLC_SET_BAND 142 -+#define WLC_SCB_DEAUTHENTICATE 143 -+#define WLC_GET_SHORTSLOT 144 -+#define WLC_GET_SHORTSLOT_OVERRIDE 145 -+#define WLC_SET_SHORTSLOT_OVERRIDE 146 -+#define WLC_GET_SHORTSLOT_RESTRICT 147 -+#define WLC_SET_SHORTSLOT_RESTRICT 148 -+#define WLC_GET_GMODE_PROTECTION 149 -+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -+#define WLC_UPGRADE 152 -+/* #define WLC_GET_MRATE 153 */ /* no longer supported */ -+/* #define WLC_SET_MRATE 154 */ /* no longer supported */ -+#define WLC_GET_IGNORE_BCNS 155 -+#define WLC_SET_IGNORE_BCNS 156 -+#define WLC_GET_SCB_TIMEOUT 157 -+#define WLC_SET_SCB_TIMEOUT 158 -+#define WLC_GET_ASSOCLIST 159 -+#define WLC_GET_CLK 160 -+#define WLC_SET_CLK 161 -+#define WLC_GET_UP 162 -+#define WLC_OUT 163 -+#define WLC_GET_WPA_AUTH 164 -+#define WLC_SET_WPA_AUTH 165 -+#define WLC_GET_UCFLAGS 166 -+#define WLC_SET_UCFLAGS 167 -+#define WLC_GET_PWRIDX 168 -+#define WLC_SET_PWRIDX 169 -+#define WLC_GET_TSSI 170 -+#define WLC_GET_SUP_RATESET_OVERRIDE 171 -+#define WLC_SET_SUP_RATESET_OVERRIDE 172 -+/* #define WLC_SET_FAST_TIMER 173 */ /* no longer supported */ -+/* #define WLC_GET_FAST_TIMER 174 */ /* no longer supported */ -+/* #define WLC_SET_SLOW_TIMER 175 */ /* no longer supported */ -+/* #define WLC_GET_SLOW_TIMER 176 */ /* no longer supported */ -+/* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */ -+#define WLC_GET_PROTECTION_CONTROL 178 -+#define WLC_SET_PROTECTION_CONTROL 179 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#define WLC_GET_PHYLIST 180 -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ -+#define WLC_DECRYPT_STATUS 182 /* ndis only */ -+#define WLC_GET_KEY_SEQ 183 -+#define WLC_GET_SCAN_CHANNEL_TIME 184 -+#define WLC_SET_SCAN_CHANNEL_TIME 185 -+#define WLC_GET_SCAN_UNASSOC_TIME 186 -+#define WLC_SET_SCAN_UNASSOC_TIME 187 -+#define WLC_GET_SCAN_HOME_TIME 188 -+#define WLC_SET_SCAN_HOME_TIME 189 -+#define WLC_GET_SCAN_NPROBES 190 -+#define WLC_SET_SCAN_NPROBES 191 -+#define WLC_GET_PRB_RESP_TIMEOUT 192 -+#define WLC_SET_PRB_RESP_TIMEOUT 193 -+#define WLC_GET_ATTEN 194 -+#define WLC_SET_ATTEN 195 -+#define WLC_GET_SHMEM 196 /* diag */ -+#define WLC_SET_SHMEM 197 /* diag */ -+/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ -+/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ -+#define WLC_SET_WSEC_TEST 200 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WLC_TKIP_COUNTERMEASURES 202 -+#define WLC_GET_PIOMODE 203 -+#define WLC_SET_PIOMODE 204 -+#define WLC_SET_ASSOC_PREFER 205 -+#define WLC_GET_ASSOC_PREFER 206 -+#define WLC_SET_ROAM_PREFER 207 -+#define WLC_GET_ROAM_PREFER 208 -+#define WLC_SET_LED 209 -+#define WLC_GET_LED 210 -+#define WLC_GET_INTERFERENCE_MODE 211 -+#define WLC_SET_INTERFERENCE_MODE 212 -+#define WLC_GET_CHANNEL_QA 213 -+#define WLC_START_CHANNEL_QA 214 -+#define WLC_GET_CHANNEL_SEL 215 -+#define WLC_START_CHANNEL_SEL 216 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#define WLC_GET_VALID_CHANNELS 217 -+#define WLC_GET_FAKEFRAG 218 -+#define WLC_SET_FAKEFRAG 219 -+#define WLC_GET_PWROUT_PERCENTAGE 220 -+#define WLC_SET_PWROUT_PERCENTAGE 221 -+#define WLC_SET_BAD_FRAME_PREEMPT 222 -+#define WLC_GET_BAD_FRAME_PREEMPT 223 -+#define WLC_SET_LEAP_LIST 224 -+#define WLC_GET_LEAP_LIST 225 -+#define WLC_GET_CWMIN 226 -+#define WLC_SET_CWMIN 227 -+#define WLC_GET_CWMAX 228 -+#define WLC_SET_CWMAX 229 -+#define WLC_GET_WET 230 -+#define WLC_SET_WET 231 -+#define WLC_GET_PUB 232 -+/* #define WLC_SET_GLACIAL_TIMER 233 */ /* no longer supported */ -+/* #define WLC_GET_GLACIAL_TIMER 234 */ /* no longer supported */ -+#define WLC_GET_KEY_PRIMARY 235 -+#define WLC_SET_KEY_PRIMARY 236 -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+/* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */ -+#define WLC_GET_ACI_ARGS 238 -+#define WLC_SET_ACI_ARGS 239 -+#define WLC_UNSET_CALLBACK 240 -+#define WLC_SET_CALLBACK 241 -+#define WLC_GET_RADAR 242 -+#define WLC_SET_RADAR 243 -+#define WLC_SET_SPECT_MANAGMENT 244 -+#define WLC_GET_SPECT_MANAGMENT 245 -+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ -+#define WLC_WDS_GET_WPA_SUP 247 -+#define WLC_SET_CS_SCAN_TIMER 248 -+#define WLC_GET_CS_SCAN_TIMER 249 -+#define WLC_MEASURE_REQUEST 250 -+#define WLC_INIT 251 -+#define WLC_SEND_QUIET 252 -+#define WLC_KEEPALIVE 253 -+#define WLC_SEND_PWR_CONSTRAINT 254 -+#define WLC_UPGRADE_STATUS 255 -+#define WLC_CURRENT_PWR 256 -+#define WLC_GET_SCAN_PASSIVE_TIME 257 -+#define WLC_SET_SCAN_PASSIVE_TIME 258 -+#define WLC_LEGACY_LINK_BEHAVIOR 259 -+#define WLC_GET_CHANNELS_IN_COUNTRY 260 -+#define WLC_GET_COUNTRY_LIST 261 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#define WLC_GET_VAR 262 /* get value of named variable */ -+#define WLC_SET_VAR 263 /* set named variable to value */ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WLC_NVRAM_GET 264 /* deprecated */ -+#define WLC_NVRAM_SET 265 -+#define WLC_NVRAM_DUMP 266 -+#define WLC_REBOOT 267 -+#define WLC_SET_WSEC_PMK 268 -+#define WLC_GET_AUTH_MODE 269 -+#define WLC_SET_AUTH_MODE 270 -+#define WLC_GET_WAKEENTRY 271 -+#define WLC_SET_WAKEENTRY 272 -+#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ -+#define WLC_NVOTPW 274 -+#define WLC_OTPW 275 -+#define WLC_IOV_BLOCK_GET 276 -+#define WLC_IOV_MODULES_GET 277 -+#define WLC_SOFT_RESET 278 -+#define WLC_GET_ALLOW_MODE 279 -+#define WLC_SET_ALLOW_MODE 280 -+#define WLC_GET_DESIRED_BSSID 281 -+#define WLC_SET_DESIRED_BSSID 282 -+#define WLC_DISASSOC_MYAP 283 -+#define WLC_GET_NBANDS 284 /* for Dongle EXT_STA support */ -+#define WLC_GET_BANDSTATES 285 /* for Dongle EXT_STA support */ -+#define WLC_GET_WLC_BSS_INFO 286 /* for Dongle EXT_STA support */ -+#define WLC_GET_ASSOC_INFO 287 /* for Dongle EXT_STA support */ -+#define WLC_GET_OID_PHY 288 /* for Dongle EXT_STA support */ -+#define WLC_SET_OID_PHY 289 /* for Dongle EXT_STA support */ -+#define WLC_SET_ASSOC_TIME 290 /* for Dongle EXT_STA support */ -+#define WLC_GET_DESIRED_SSID 291 /* for Dongle EXT_STA support */ -+#define WLC_GET_CHANSPEC 292 /* for Dongle EXT_STA support */ -+#define WLC_GET_ASSOC_STATE 293 /* for Dongle EXT_STA support */ -+#define WLC_SET_PHY_STATE 294 /* for Dongle EXT_STA support */ -+#define WLC_GET_SCAN_PENDING 295 /* for Dongle EXT_STA support */ -+#define WLC_GET_SCANREQ_PENDING 296 /* for Dongle EXT_STA support */ -+#define WLC_GET_PREV_ROAM_REASON 297 /* for Dongle EXT_STA support */ -+#define WLC_SET_PREV_ROAM_REASON 298 /* for Dongle EXT_STA support */ -+#define WLC_GET_BANDSTATES_PI 299 /* for Dongle EXT_STA support */ -+#define WLC_GET_PHY_STATE 300 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_WPA_RSN 301 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_WPA2_RSN 302 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_BCN_TS 303 /* for Dongle EXT_STA support */ -+#define WLC_GET_INT_DISASSOC 304 /* for Dongle EXT_STA support */ -+#define WLC_SET_NUM_PEERS 305 /* for Dongle EXT_STA support */ -+#define WLC_GET_NUM_BSS 306 /* for Dongle EXT_STA support */ -+#define WLC_PHY_SAMPLE_COLLECT 307 /* phy sample collect mode */ -+/* #define WLC_UM_PRIV 308 */ /* Deprecated: usermode driver */ -+#define WLC_GET_CMD 309 -+/* #define WLC_LAST 310 */ /* Never used - can be reused */ -+#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 /* set inter mode override */ -+#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 /* get inter mode override */ -+/* #define WLC_GET_WAI_RESTRICT 313 */ /* for WAPI, deprecated use iovar instead */ -+/* #define WLC_SET_WAI_RESTRICT 314 */ /* for WAPI, deprecated use iovar instead */ -+/* #define WLC_SET_WAI_REKEY 315 */ /* for WAPI, deprecated use iovar instead */ -+#define WLC_SET_NAT_CONFIG 316 /* for configuring NAT filter driver */ -+#define WLC_GET_NAT_STATE 317 -+#define WLC_LAST 318 -+ -+#ifndef EPICTRL_COOKIE -+#define EPICTRL_COOKIE 0xABADCEDE -+#endif -+ -+/* vx wlc ioctl's offset */ -+#define CMN_IOCTL_OFF 0x180 -+ -+/* -+ * custom OID support -+ * -+ * 0xFF - implementation specific OID -+ * 0xE4 - first byte of Broadcom PCI vendor ID -+ * 0x14 - second byte of Broadcom PCI vendor ID -+ * 0xXX - the custom OID number -+ */ -+ -+/* begin 0x1f values beyond the start of the ET driver range. */ -+#define WL_OID_BASE 0xFFE41420 -+ -+/* NDIS overrides */ -+#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -+#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) -+#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) -+#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) -+#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) -+#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) -+#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) -+ -+/* EXT_STA Dongle suuport */ -+#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) -+#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) -+#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) -+#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) -+#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) -+#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) -+#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) -+#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) -+#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) -+#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) -+#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) -+#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) -+#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) -+#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) -+#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) -+ -+/* NAT filter driver support */ -+#define OID_NAT_SET_CONFIG (WL_OID_BASE + WLC_SET_NAT_CONFIG) -+#define OID_NAT_GET_STATE (WL_OID_BASE + WLC_GET_NAT_STATE) -+ -+#define WL_DECRYPT_STATUS_SUCCESS 1 -+#define WL_DECRYPT_STATUS_FAILURE 2 -+#define WL_DECRYPT_STATUS_UNKNOWN 3 -+ -+/* allows user-mode app to poll the status of USB image upgrade */ -+#define WLC_UPGRADE_SUCCESS 0 -+#define WLC_UPGRADE_PENDING 1 -+ -+#ifdef CONFIG_USBRNDIS_RETAIL -+/* struct passed in for WLC_NDCONFIG_ITEM */ -+typedef struct { -+ char *name; -+ void *param; -+} ndconfig_item_t; -+#endif -+ -+ -+/* WLC_GET_AUTH, WLC_SET_AUTH values */ -+#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ -+#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ -+#ifdef BCM4330_CHIP -+#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ -+#else -+/* BCM4334(Phoenex branch) value changed to 3 */ -+#define WL_AUTH_OPEN_SHARED 3 /* try open, then shared if open failed w/rc 13 */ -+#endif -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ -+#define WL_RADIO_SW_DISABLE (1<<0) -+#define WL_RADIO_HW_DISABLE (1<<1) -+#define WL_RADIO_MPC_DISABLE (1<<2) -+#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ -+ -+#define WL_SPURAVOID_OFF 0 -+#define WL_SPURAVOID_ON1 1 -+#define WL_SPURAVOID_ON2 2 -+ -+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ -+#define WL_TXPWR_OVERRIDE (1U<<31) -+#define WL_TXPWR_NEG (1U<<30) -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */ -+ -+#define WL_PHY_PAVAR_VER 1 /* pavars version */ -+ -+typedef struct wl_po { -+ uint16 phy_type; /* Phy type */ -+ uint16 band; -+ uint16 cckpo; -+ uint32 ofdmpo; -+ uint16 mcspo[8]; -+} wl_po_t; -+ -+/* a large TX Power as an init value to factor out of MIN() calculations, -+ * keep low enough to fit in an int8, units are .25 dBm -+ */ -+#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ -+ -+/* "diag" iovar argument and error code */ -+#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ -+#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */ -+#define WL_DIAG_MEMORY 3 /* d11 memory test */ -+#define WL_DIAG_LED 4 /* LED test */ -+#define WL_DIAG_REG 5 /* d11/phy register test */ -+#define WL_DIAG_SROM 6 /* srom read/crc test */ -+#define WL_DIAG_DMA 7 /* DMA test */ -+#define WL_DIAG_LOOPBACK_EXT 8 /* enhenced d11 loopback data test */ -+ -+#define WL_DIAGERR_SUCCESS 0 -+#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ -+#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ -+#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ -+#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ -+#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ -+#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ -+#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ -+#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ -+#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ -+#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ -+ -+#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */ -+#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */ -+ -+/* band types */ -+#define WLC_BAND_AUTO 0 /* auto-select */ -+#define WLC_BAND_5G 1 /* 5 Ghz */ -+#define WLC_BAND_2G 2 /* 2.4 Ghz */ -+#define WLC_BAND_ALL 3 /* all bands */ -+ -+/* band range returned by band_range iovar */ -+#define WL_CHAN_FREQ_RANGE_2G 0 -+#define WL_CHAN_FREQ_RANGE_5GL 1 -+#define WL_CHAN_FREQ_RANGE_5GM 2 -+#define WL_CHAN_FREQ_RANGE_5GH 3 -+ -+#define WL_CHAN_FREQ_RANGE_5G_BAND0 1 -+#define WL_CHAN_FREQ_RANGE_5G_BAND1 2 -+#define WL_CHAN_FREQ_RANGE_5G_BAND2 3 -+#define WL_CHAN_FREQ_RANGE_5G_BAND3 4 -+ -+#define WL_CHAN_FREQ_RANGE_5G_4BAND 5 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* phy types (returned by WLC_GET_PHYTPE) */ -+#define WLC_PHY_TYPE_A 0 -+#define WLC_PHY_TYPE_B 1 -+#define WLC_PHY_TYPE_G 2 -+#define WLC_PHY_TYPE_N 4 -+#define WLC_PHY_TYPE_LP 5 -+#define WLC_PHY_TYPE_SSN 6 -+#define WLC_PHY_TYPE_HT 7 -+#define WLC_PHY_TYPE_LCN 8 -+#define WLC_PHY_TYPE_LCN40 10 -+#define WLC_PHY_TYPE_AC 11 -+#define WLC_PHY_TYPE_NULL 0xf -+ -+/* Values for PM */ -+#define PM_OFF 0 -+#define PM_MAX 1 -+#define PM_FAST 2 -+#define PM_FORCE_OFF 3 /* use this bit to force PM off even bt is active */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* MAC list modes */ -+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ -+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ -+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ -+ -+/* -+ * 54g modes (basic bits may still be overridden) -+ * -+ * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 -+ * Preamble: Long -+ * Shortslot: Off -+ * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 -+ * Extended Rateset: 6, 9, 12, 48 -+ * Preamble: Long -+ * Shortslot: Auto -+ * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 -+ * Extended Rateset: 6b, 9, 12b, 48 -+ * Preamble: Short required -+ * Shortslot: Auto -+ * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 -+ * Extended Rateset: 6, 9, 12, 48 -+ * Preamble: Long -+ * Shortslot: On -+ * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 -+ * Preamble: Short required -+ * Shortslot: On and required -+ * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b -+ * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 -+ * Preamble: Long -+ * Shortslot: Auto -+ */ -+#define GMODE_LEGACY_B 0 -+#define GMODE_AUTO 1 -+#define GMODE_ONLY 2 -+#define GMODE_B_DEFERRED 3 -+#define GMODE_PERFORMANCE 4 -+#define GMODE_LRS 5 -+#define GMODE_MAX 6 -+ -+/* values for PLCPHdr_override */ -+#define WLC_PLCP_AUTO -1 -+#define WLC_PLCP_SHORT 0 -+#define WLC_PLCP_LONG 1 -+ -+/* values for g_protection_override and n_protection_override */ -+#define WLC_PROTECTION_AUTO -1 -+#define WLC_PROTECTION_OFF 0 -+#define WLC_PROTECTION_ON 1 -+#define WLC_PROTECTION_MMHDR_ONLY 2 -+#define WLC_PROTECTION_CTS_ONLY 3 -+ -+/* values for g_protection_control and n_protection_control */ -+#define WLC_PROTECTION_CTL_OFF 0 -+#define WLC_PROTECTION_CTL_LOCAL 1 -+#define WLC_PROTECTION_CTL_OVERLAP 2 -+ -+/* values for n_protection */ -+#define WLC_N_PROTECTION_OFF 0 -+#define WLC_N_PROTECTION_OPTIONAL 1 -+#define WLC_N_PROTECTION_20IN40 2 -+#define WLC_N_PROTECTION_MIXEDMODE 3 -+ -+/* values for n_preamble_type */ -+#define WLC_N_PREAMBLE_MIXEDMODE 0 -+#define WLC_N_PREAMBLE_GF 1 -+#define WLC_N_PREAMBLE_GF_BRCM 2 -+ -+/* values for band specific 40MHz capabilities (deprecated) */ -+#define WLC_N_BW_20ALL 0 -+#define WLC_N_BW_40ALL 1 -+#define WLC_N_BW_20IN2G_40IN5G 2 -+ -+#define WLC_BW_20MHZ_BIT (1<<0) -+#define WLC_BW_40MHZ_BIT (1<<1) -+#define WLC_BW_80MHZ_BIT (1<<2) -+ -+/* Bandwidth capabilities */ -+#define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_UNRESTRICTED 0xFF -+ -+#define WL_BW_CAP_20MHZ(bw_cap) (((bw_cap) & WLC_BW_20MHZ_BIT) ? TRUE : FALSE) -+#define WL_BW_CAP_40MHZ(bw_cap) (((bw_cap) & WLC_BW_40MHZ_BIT) ? TRUE : FALSE) -+#define WL_BW_CAP_80MHZ(bw_cap) (((bw_cap) & WLC_BW_80MHZ_BIT) ? TRUE : FALSE) -+ -+/* values to force tx/rx chain */ -+#define WLC_N_TXRX_CHAIN0 0 -+#define WLC_N_TXRX_CHAIN1 1 -+ -+/* bitflags for SGI support (sgi_rx iovar) */ -+#define WLC_N_SGI_20 0x01 -+#define WLC_N_SGI_40 0x02 -+#define WLC_VHT_SGI_80 0x04 -+ -+/* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */ -+#define WLC_SGI_ALL 0x02 -+ -+#define LISTEN_INTERVAL 10 -+/* interference mitigation options */ -+#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */ -+#define INTERFERE_NONE 0 /* off */ -+#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */ -+#define WLAN_MANUAL 2 /* ACI: no auto detection */ -+#define WLAN_AUTO 3 /* ACI: auto detect */ -+#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */ -+#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */ -+ -+/* AP environment */ -+#define AP_ENV_DETECT_NOT_USED 0 /* We aren't using AP environment detection */ -+#define AP_ENV_DENSE 1 /* "Corporate" or other AP dense environment */ -+#define AP_ENV_SPARSE 2 /* "Home" or other sparse environment */ -+#define AP_ENV_INDETERMINATE 3 /* AP environment hasn't been identified */ -+ -+typedef struct wl_aci_args { -+ int enter_aci_thresh; /* Trigger level to start detecting ACI */ -+ int exit_aci_thresh; /* Trigger level to exit ACI mode */ -+ int usec_spin; /* microsecs to delay between rssi samples */ -+ int glitch_delay; /* interval between ACI scans when glitch count is consistently high */ -+ uint16 nphy_adcpwr_enter_thresh; /* ADC power to enter ACI mitigation mode */ -+ uint16 nphy_adcpwr_exit_thresh; /* ADC power to exit ACI mitigation mode */ -+ uint16 nphy_repeat_ctr; /* Number of tries per channel to compute power */ -+ uint16 nphy_num_samples; /* Number of samples to compute power on one channel */ -+ uint16 nphy_undetect_window_sz; /* num of undetects to exit ACI Mitigation mode */ -+ uint16 nphy_b_energy_lo_aci; /* low ACI power energy threshold for bphy */ -+ uint16 nphy_b_energy_md_aci; /* mid ACI power energy threshold for bphy */ -+ uint16 nphy_b_energy_hi_aci; /* high ACI power energy threshold for bphy */ -+ uint16 nphy_noise_noassoc_glitch_th_up; /* wl interference 4 */ -+ uint16 nphy_noise_noassoc_glitch_th_dn; -+ uint16 nphy_noise_assoc_glitch_th_up; -+ uint16 nphy_noise_assoc_glitch_th_dn; -+ uint16 nphy_noise_assoc_aci_glitch_th_up; -+ uint16 nphy_noise_assoc_aci_glitch_th_dn; -+ uint16 nphy_noise_assoc_enter_th; -+ uint16 nphy_noise_noassoc_enter_th; -+ uint16 nphy_noise_assoc_rx_glitch_badplcp_enter_th; -+ uint16 nphy_noise_noassoc_crsidx_incr; -+ uint16 nphy_noise_assoc_crsidx_incr; -+ uint16 nphy_noise_crsidx_decr; -+} wl_aci_args_t; -+ -+#define TRIGGER_NOW 0 -+#define TRIGGER_CRS 0x01 -+#define TRIGGER_CRSDEASSERT 0x02 -+#define TRIGGER_GOODFCS 0x04 -+#define TRIGGER_BADFCS 0x08 -+#define TRIGGER_BADPLCP 0x10 -+#define TRIGGER_CRSGLITCH 0x20 -+#define WL_ACI_ARGS_LEGACY_LENGTH 16 /* bytes of pre NPHY aci args */ -+#define WL_SAMPLECOLLECT_T_VERSION 2 /* version of wl_samplecollect_args_t struct */ -+typedef struct wl_samplecollect_args { -+ /* version 0 fields */ -+ uint8 coll_us; -+ int cores; -+ /* add'l version 1 fields */ -+ uint16 version; /* see definition of WL_SAMPLECOLLECT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ int8 trigger; -+ uint16 timeout; -+ uint16 mode; -+ uint32 pre_dur; -+ uint32 post_dur; -+ uint8 gpio_sel; -+ bool downsamp; -+ bool be_deaf; -+ bool agc; /* loop from init gain and going down */ -+ bool filter; /* override high pass corners to lowest */ -+ /* add'l version 2 fields */ -+ uint8 trigger_state; -+ uint8 module_sel1; -+ uint8 module_sel2; -+ uint16 nsamps; -+} wl_samplecollect_args_t; -+ -+#define WL_SAMPLEDATA_HEADER_TYPE 1 -+#define WL_SAMPLEDATA_HEADER_SIZE 80 /* sample collect header size (bytes) */ -+#define WL_SAMPLEDATA_TYPE 2 -+#define WL_SAMPLEDATA_SEQ 0xff /* sequence # */ -+#define WL_SAMPLEDATA_MORE_DATA 0x100 /* more data mask */ -+#define WL_SAMPLEDATA_T_VERSION 1 /* version of wl_samplecollect_args_t struct */ -+/* version for unpacked sample data, int16 {(I,Q),Core(0..N)} */ -+#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 -+ -+typedef struct wl_sampledata { -+ uint16 version; /* structure version */ -+ uint16 size; /* size of structure */ -+ uint16 tag; /* Header/Data */ -+ uint16 length; /* data length */ -+ uint32 flag; /* bit def */ -+} wl_sampledata_t; -+ -+/* wl_radar_args_t */ -+typedef struct { -+ int npulses; /* required number of pulses at n * t_int */ -+ int ncontig; /* required number of pulses at t_int */ -+ int min_pw; /* minimum pulse width (20 MHz clocks) */ -+ int max_pw; /* maximum pulse width (20 MHz clocks) */ -+ uint16 thresh0; /* Radar detection, thresh 0 */ -+ uint16 thresh1; /* Radar detection, thresh 1 */ -+ uint16 blank; /* Radar detection, blank control */ -+ uint16 fmdemodcfg; /* Radar detection, fmdemod config */ -+ int npulses_lp; /* Radar detection, minimum long pulses */ -+ int min_pw_lp; /* Minimum pulsewidth for long pulses */ -+ int max_pw_lp; /* Maximum pulsewidth for long pulses */ -+ int min_fm_lp; /* Minimum fm for long pulses */ -+ int max_span_lp; /* Maximum deltat for long pulses */ -+ int min_deltat; /* Minimum spacing between pulses */ -+ int max_deltat; /* Maximum spacing between pulses */ -+ uint16 autocorr; /* Radar detection, autocorr on or off */ -+ uint16 st_level_time; /* Radar detection, start_timing level */ -+ uint16 t2_min; /* minimum clocks needed to remain in state 2 */ -+ uint32 version; /* version */ -+ uint32 fra_pulse_err; /* sample error margin for detecting French radar pulsed */ -+ int npulses_fra; /* Radar detection, minimum French pulses set */ -+ int npulses_stg2; /* Radar detection, minimum staggered-2 pulses set */ -+ int npulses_stg3; /* Radar detection, minimum staggered-3 pulses set */ -+ uint16 percal_mask; /* defines which period cal is masked from radar detection */ -+ int quant; /* quantization resolution to pulse positions */ -+ uint32 min_burst_intv_lp; /* minimum burst to burst interval for bin3 radar */ -+ uint32 max_burst_intv_lp; /* maximum burst to burst interval for bin3 radar */ -+ int nskip_rst_lp; /* number of skipped pulses before resetting lp buffer */ -+ int max_pw_tol; /* maximum tollerance allowed in detected pulse width for radar detection */ -+ uint16 feature_mask; /* 16-bit mask to specify enabled features */ -+} wl_radar_args_t; -+ -+#define WL_RADAR_ARGS_VERSION 2 -+ -+typedef struct { -+ uint32 version; /* version */ -+ uint16 thresh0_20_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 20MHz */ -+ uint16 thresh1_20_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */ -+ uint16 thresh0_40_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */ -+ uint16 thresh1_40_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */ -+ uint16 thresh0_80_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 80MHz */ -+ uint16 thresh1_80_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 80MHz */ -+ uint16 thresh0_160_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 160MHz */ -+ uint16 thresh1_160_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 160MHz */ -+ uint16 thresh0_20_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */ -+ uint16 thresh1_20_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */ -+ uint16 thresh0_40_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */ -+ uint16 thresh1_40_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */ -+ uint16 thresh0_80_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 80MHz */ -+ uint16 thresh1_80_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 80MHz */ -+ uint16 thresh0_160_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 160MHz */ -+ uint16 thresh1_160_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 160MHz */ -+} wl_radar_thr_t; -+ -+#define WL_RADAR_THR_VERSION 2 -+#define WL_THRESHOLD_LO_BAND 70 /* range from 5250MHz - 5350MHz */ -+ -+/* radar iovar SET defines */ -+#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ -+#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ -+#define WL_RADAR_SIMULATED 2 /* force radar detector to declare -+ * detection once -+ */ -+#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */ -+#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ -+#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ -+#define WL_ANT_IDX_1 0 /* antenna index 1 */ -+#define WL_ANT_IDX_2 1 /* antenna index 2 */ -+ -+#ifndef WL_RSSI_ANT_MAX -+#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ -+#elif WL_RSSI_ANT_MAX != 4 -+#error "WL_RSSI_ANT_MAX does not match" -+#endif -+ -+/* RSSI per antenna */ -+typedef struct { -+ uint32 version; /* version field */ -+ uint32 count; /* number of valid antenna rssi */ -+ int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */ -+} wl_rssi_ant_t; -+ -+/* dfs_status iovar-related defines */ -+ -+/* cac - channel availability check, -+ * ism - in-service monitoring -+ * csa - channel switching announcement -+ */ -+ -+/* cac state values */ -+#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ -+#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ -+#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ -+#define WL_DFS_CACSTATE_CSA 3 /* csa */ -+#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ -+#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ -+#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ -+#define WL_DFS_CACSTATES 7 /* this many states exist */ -+ -+/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ -+typedef struct { -+ uint state; /* noted by WL_DFS_CACSTATE_XX. */ -+ uint duration; /* time spent in ms in state. */ -+ /* as dfs enters ISM state, it removes the operational channel from quiet channel -+ * list and notes the channel in channel_cleared. set to 0 if no channel is cleared -+ */ -+ chanspec_t chanspec_cleared; -+ /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ -+ uint16 pad; -+} wl_dfs_status_t; -+ -+#define NUM_PWRCTRL_RATES 12 -+ -+typedef struct { -+ uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */ -+ uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */ -+ uint8 txpwr_local_max; /* local max according to the AP */ -+ uint8 txpwr_local_constraint; /* local constraint according to the AP */ -+ uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */ -+ uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */ -+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ -+ uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */ -+ uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */ -+ uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */ -+ uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */ -+ int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -+} tx_power_legacy_t; -+ -+#define WL_TX_POWER_RATES_LEGACY 45 -+#define WL_TX_POWER_MCS20_FIRST 12 -+#define WL_TX_POWER_MCS20_NUM 16 -+#define WL_TX_POWER_MCS40_FIRST 28 -+#define WL_TX_POWER_MCS40_NUM 17 -+ -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF -+ * chain without adjustment -+ */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */ -+ uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */ -+ uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */ -+ uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */ -+} tx_power_legacy2_t; -+ -+/* TX Power index defines */ -+#define WL_NUM_RATES_CCK 4 /* 1, 2, 5.5, 11 Mbps */ -+#define WL_NUM_RATES_OFDM 8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */ -+#define WL_NUM_RATES_MCS_1STREAM 8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */ -+#define WL_NUM_RATES_EXTRA_VHT 2 /* Additional VHT 11AC rates */ -+#define WL_NUM_RATES_VHT 10 -+#define WL_NUM_RATES_MCS32 1 -+ -+#define WLC_NUM_RATES_CCK WL_NUM_RATES_CCK -+#define WLC_NUM_RATES_OFDM WL_NUM_RATES_OFDM -+#define WLC_NUM_RATES_MCS_1_STREAM WL_NUM_RATES_MCS_1STREAM -+#define WLC_NUM_RATES_MCS_2_STREAM WL_NUM_RATES_MCS_1STREAM -+#define WLC_NUM_RATES_MCS32 WL_NUM_RATES_MCS32 -+#define WL_TX_POWER_CCK_NUM WL_NUM_RATES_CCK -+#define WL_TX_POWER_OFDM_NUM WL_NUM_RATES_OFDM -+#define WL_TX_POWER_MCS_1_STREAM_NUM WL_NUM_RATES_MCS_1STREAM -+#define WL_TX_POWER_MCS_2_STREAM_NUM WL_NUM_RATES_MCS_1STREAM -+#define WL_TX_POWER_MCS_32_NUM WL_NUM_RATES_MCS32 -+ -+#define WL_NUM_2x2_ELEMENTS 4 -+#define WL_NUM_3x3_ELEMENTS 6 -+ -+typedef struct txppr { -+ /* start of 20MHz tx power limits */ -+ uint8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 40MHz tx power limits */ -+ uint8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 20in40MHz tx power limits */ -+ uint8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */ -+ uint8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 80MHz tx power limits */ -+ uint8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 20in80MHz tx power limits */ -+ uint8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 40in80MHz tx power limits */ -+ uint8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */ -+ uint8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ -+} txppr_t; -+ -+/* 20MHz */ -+#define WL_TX_POWER_CCK_FIRST OFFSETOF(txppr_t, b20_1x1dsss) -+#define WL_TX_POWER_OFDM20_FIRST OFFSETOF(txppr_t, b20_1x1ofdm) -+#define WL_TX_POWER_MCS20_SISO_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) -+#define WL_TX_POWER_20_S1x1_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2dsss) -+#define WL_TX_POWER_OFDM20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) -+#define WL_TX_POWER_20_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS20_STBC_FIRST OFFSETOF(txppr_t, b20_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS20_SDM_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) -+#define WL_TX_POWER_20_S2x2_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3dsss) -+#define WL_TX_POWER_OFDM20_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_ofdm) -+#define WL_TX_POWER_20_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_mcs0) -+#define WL_TX_POWER_20_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3stbc_mcs0) -+#define WL_TX_POWER_20_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3sdm_mcs8) -+#define WL_TX_POWER_20_S3x3_FIRST OFFSETOF(txppr_t, b20_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20_S1X1_VHT OFFSETOF(txppr_t, b20_1x1vht) -+#define WL_TX_POWER_20_S1X2_CDD_VHT OFFSETOF(txppr_t, b20_1x2cdd_vht) -+#define WL_TX_POWER_20_S2X2_STBC_VHT OFFSETOF(txppr_t, b20_2x2stbc_vht) -+#define WL_TX_POWER_20_S2X2_VHT OFFSETOF(txppr_t, b20_2x2sdm_vht) -+#define WL_TX_POWER_20_S1X3_CDD_VHT OFFSETOF(txppr_t, b20_1x3cdd_vht) -+#define WL_TX_POWER_20_S2X3_STBC_VHT OFFSETOF(txppr_t, b20_2x3stbc_vht) -+#define WL_TX_POWER_20_S2X3_VHT OFFSETOF(txppr_t, b20_2x3sdm_vht) -+#define WL_TX_POWER_20_S3X3_VHT OFFSETOF(txppr_t, b20_3x3sdm_vht) -+ -+/* 40MHz */ -+#define WL_TX_POWER_40_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40_dummy1x1dsss) -+#define WL_TX_POWER_OFDM40_FIRST OFFSETOF(txppr_t, b40_1x1ofdm) -+#define WL_TX_POWER_MCS40_SISO_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) -+#define WL_TX_POWER_40_S1x1_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) -+ -+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40_dummy1x2dsss) -+#define WL_TX_POWER_OFDM40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) -+#define WL_TX_POWER_40_S1x2_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS40_STBC_FIRST OFFSETOF(txppr_t, b40_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS40_SDM_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) -+#define WL_TX_POWER_40_S2x2_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_dummy1x3dsss) -+#define WL_TX_POWER_OFDM40_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_ofdm) -+#define WL_TX_POWER_40_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_mcs0) -+#define WL_TX_POWER_40_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3stbc_mcs0) -+#define WL_TX_POWER_40_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3sdm_mcs8) -+#define WL_TX_POWER_40_S3x3_FIRST OFFSETOF(txppr_t, b40_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_40_S1X1_VHT OFFSETOF(txppr_t, b40_1x1vht) -+#define WL_TX_POWER_40_S1X2_CDD_VHT OFFSETOF(txppr_t, b40_1x2cdd_vht) -+#define WL_TX_POWER_40_S2X2_STBC_VHT OFFSETOF(txppr_t, b40_2x2stbc_vht) -+#define WL_TX_POWER_40_S2X2_VHT OFFSETOF(txppr_t, b40_2x2sdm_vht) -+#define WL_TX_POWER_40_S1X3_CDD_VHT OFFSETOF(txppr_t, b40_1x3cdd_vht) -+#define WL_TX_POWER_40_S2X3_STBC_VHT OFFSETOF(txppr_t, b40_2x3stbc_vht) -+#define WL_TX_POWER_40_S2X3_VHT OFFSETOF(txppr_t, b40_2x3sdm_vht) -+#define WL_TX_POWER_40_S3X3_VHT OFFSETOF(txppr_t, b40_3x3sdm_vht) -+ -+/* 20 in 40MHz */ -+#define WL_TX_POWER_20UL_CCK_FIRST OFFSETOF(txppr_t, b20in40_1x1dsss) -+#define WL_TX_POWER_20UL_OFDM_FIRST OFFSETOF(txppr_t, b20in40_1x1ofdm) -+#define WL_TX_POWER_20UL_S1x1_FIRST OFFSETOF(txppr_t, b20in40_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2dsss) -+#define WL_TX_POWER_20UL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_ofdm) -+#define WL_TX_POWER_20UL_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_mcs0) -+#define WL_TX_POWER_20UL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2stbc_mcs0) -+#define WL_TX_POWER_20UL_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3dsss) -+#define WL_TX_POWER_20UL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_ofdm) -+#define WL_TX_POWER_20UL_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_mcs0) -+#define WL_TX_POWER_20UL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3stbc_mcs0) -+#define WL_TX_POWER_20UL_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3sdm_mcs8) -+#define WL_TX_POWER_20UL_S3x3_FIRST OFFSETOF(txppr_t, b20in40_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20UL_S1X1_VHT OFFSETOF(txppr_t, b20in40_1x1vht) -+#define WL_TX_POWER_20UL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in40_1x2cdd_vht) -+#define WL_TX_POWER_20UL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in40_2x2stbc_vht) -+#define WL_TX_POWER_20UL_S2X2_VHT OFFSETOF(txppr_t, b20in40_2x2sdm_vht) -+#define WL_TX_POWER_20UL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in40_1x3cdd_vht) -+#define WL_TX_POWER_20UL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in40_2x3stbc_vht) -+#define WL_TX_POWER_20UL_S2X3_VHT OFFSETOF(txppr_t, b20in40_2x3sdm_vht) -+#define WL_TX_POWER_20UL_S3X3_VHT OFFSETOF(txppr_t, b20in40_3x3sdm_vht) -+ -+/* 80MHz */ -+#define WL_TX_POWER_80_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b80_dummy1x1dsss) -+#define WL_TX_POWER_OFDM80_FIRST OFFSETOF(txppr_t, b80_1x1ofdm) -+#define WL_TX_POWER_MCS80_SISO_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) -+#define WL_TX_POWER_80_S1x1_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) -+ -+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b80_dummy1x2dsss) -+#define WL_TX_POWER_OFDM80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) -+#define WL_TX_POWER_80_S1x2_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS80_STBC_FIRST OFFSETOF(txppr_t, b80_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS80_SDM_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) -+#define WL_TX_POWER_80_S2x2_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_dummy1x3dsss) -+#define WL_TX_POWER_OFDM80_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_ofdm) -+#define WL_TX_POWER_80_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_mcs0) -+#define WL_TX_POWER_80_STBC_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3stbc_mcs0) -+#define WL_TX_POWER_80_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3sdm_mcs8) -+#define WL_TX_POWER_80_S3x3_FIRST OFFSETOF(txppr_t, b80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_80_S1X1_VHT OFFSETOF(txppr_t, b80_1x1vht) -+#define WL_TX_POWER_80_S1X2_CDD_VHT OFFSETOF(txppr_t, b80_1x2cdd_vht) -+#define WL_TX_POWER_80_S2X2_STBC_VHT OFFSETOF(txppr_t, b80_2x2stbc_vht) -+#define WL_TX_POWER_80_S2X2_VHT OFFSETOF(txppr_t, b80_2x2sdm_vht) -+#define WL_TX_POWER_80_S1X3_CDD_VHT OFFSETOF(txppr_t, b80_1x3cdd_vht) -+#define WL_TX_POWER_80_S2X3_STBC_VHT OFFSETOF(txppr_t, b80_2x3stbc_vht) -+#define WL_TX_POWER_80_S2X3_VHT OFFSETOF(txppr_t, b80_2x3sdm_vht) -+#define WL_TX_POWER_80_S3X3_VHT OFFSETOF(txppr_t, b80_3x3sdm_vht) -+ -+/* 20 in 80MHz */ -+#define WL_TX_POWER_20UUL_CCK_FIRST OFFSETOF(txppr_t, b20in80_1x1dsss) -+#define WL_TX_POWER_20UUL_OFDM_FIRST OFFSETOF(txppr_t, b20in80_1x1ofdm) -+#define WL_TX_POWER_20UUL_S1x1_FIRST OFFSETOF(txppr_t, b20in80_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_20UU_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2dsss) -+#define WL_TX_POWER_20UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_ofdm) -+#define WL_TX_POWER_20UUL_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_mcs0) -+#define WL_TX_POWER_20UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2stbc_mcs0) -+#define WL_TX_POWER_20UUL_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_20UU_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3dsss) -+#define WL_TX_POWER_20UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_ofdm) -+#define WL_TX_POWER_20UUL_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_mcs0) -+#define WL_TX_POWER_20UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3stbc_mcs0) -+#define WL_TX_POWER_20UUL_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3sdm_mcs8) -+#define WL_TX_POWER_20UUL_S3x3_FIRST OFFSETOF(txppr_t, b20in80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20UUL_S1X1_VHT OFFSETOF(txppr_t, b20in80_1x1vht) -+#define WL_TX_POWER_20UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in80_1x2cdd_vht) -+#define WL_TX_POWER_20UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in80_2x2stbc_vht) -+#define WL_TX_POWER_20UUL_S2X2_VHT OFFSETOF(txppr_t, b20in80_2x2sdm_vht) -+#define WL_TX_POWER_20UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in80_1x3cdd_vht) -+#define WL_TX_POWER_20UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in80_2x3stbc_vht) -+#define WL_TX_POWER_20UUL_S2X3_VHT OFFSETOF(txppr_t, b20in80_2x3sdm_vht) -+#define WL_TX_POWER_20UUL_S3X3_VHT OFFSETOF(txppr_t, b20in80_3x3sdm_vht) -+ -+/* 40 in 80MHz */ -+#define WL_TX_POWER_40UUL_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40in80_dummy1x1dsss) -+#define WL_TX_POWER_40UUL_OFDM_FIRST OFFSETOF(txppr_t, b40in80_1x1ofdm) -+#define WL_TX_POWER_40UUL_S1x1_FIRST OFFSETOF(txppr_t, b40in80_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40in80_dummy1x2dsss) -+#define WL_TX_POWER_40UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_ofdm) -+#define WL_TX_POWER_40UUL_S1x2_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_mcs0) -+#define WL_TX_POWER_40UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2stbc_mcs0) -+#define WL_TX_POWER_40UUL_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_dummy1x3dsss) -+#define WL_TX_POWER_40UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_ofdm) -+#define WL_TX_POWER_40UUL_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_mcs0) -+#define WL_TX_POWER_40UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3stbc_mcs0) -+#define WL_TX_POWER_40UUL_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3sdm_mcs8) -+#define WL_TX_POWER_40UUL_S3x3_FIRST OFFSETOF(txppr_t, b40in80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_40UUL_S1X1_VHT OFFSETOF(txppr_t, b40in80_1x1vht) -+#define WL_TX_POWER_40UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b40in80_1x2cdd_vht) -+#define WL_TX_POWER_40UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b40in80_2x2stbc_vht) -+#define WL_TX_POWER_40UUL_S2X2_VHT OFFSETOF(txppr_t, b40in80_2x2sdm_vht) -+#define WL_TX_POWER_40UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b40in80_1x3cdd_vht) -+#define WL_TX_POWER_40UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b40in80_2x3stbc_vht) -+#define WL_TX_POWER_40UUL_S2X3_VHT OFFSETOF(txppr_t, b40in80_2x3sdm_vht) -+#define WL_TX_POWER_40UUL_S3X3_VHT OFFSETOF(txppr_t, b40in80_3x3sdm_vht) -+ -+#define WL_TX_POWER_MCS_32 OFFSETOF(txppr_t, mcs32) /* C_CHECK remove later */ -+ -+#define WL_TX_POWER_RATES sizeof(struct txppr) -+ -+/* sslpnphy specifics */ -+#define WL_TX_POWER_MCS20_SISO_FIRST_SSN WL_TX_POWER_MCS20_SISO_FIRST -+#define WL_TX_POWER_MCS40_SISO_FIRST_SSN WL_TX_POWER_MCS40_SISO_FIRST -+ -+/* tx_power_t.flags bits */ -+#define WL_TX_POWER_F_ENABLED 1 -+#define WL_TX_POWER_F_HW 2 -+#define WL_TX_POWER_F_MIMO 4 -+#define WL_TX_POWER_F_SISO 8 -+#define WL_TX_POWER_F_HT 0x10 -+ -+typedef struct { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* length in bytes of this structure */ -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */ -+} wl_txppr_t; -+ -+#define WL_TXPPR_VERSION 0 -+#define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) -+#define TX_POWER_T_VERSION 43 -+ -+/* Defines used with channel_bandwidth for curpower */ -+#define WL_BW_20MHZ 0 -+#define WL_BW_40MHZ 1 -+#define WL_BW_80MHZ 2 -+ -+/* tx_power_t.flags bits */ -+#ifdef PPR_API -+#define WL_TX_POWER2_F_ENABLED 1 -+#define WL_TX_POWER2_F_HW 2 -+#define WL_TX_POWER2_F_MIMO 4 -+#define WL_TX_POWER2_F_SISO 8 -+#define WL_TX_POWER2_F_HT 0x10 -+#else -+#define WL_TX_POWER_F_ENABLED 1 -+#define WL_TX_POWER_F_HW 2 -+#define WL_TX_POWER_F_MIMO 4 -+#define WL_TX_POWER_F_SISO 8 -+#define WL_TX_POWER_F_HT 0x10 -+#endif -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ -+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain -+ * without adjustment -+ */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 tx_power_max[4]; /* Maximum target power among all rates */ -+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ -+ uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */ -+ int8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ -+ int8 target[WL_TX_POWER_RATES]; /* Latest target power */ -+ int8 clm_limits[WL_NUMRATES]; /* regulatory limits - 20, 40 or 80MHz */ -+ int8 clm_limits_subchan1[WL_NUMRATES]; /* regulatory limits - 20in40 or 40in80 */ -+ int8 clm_limits_subchan2[WL_NUMRATES]; /* regulatory limits - 20in80MHz */ -+ int8 sar; /* SAR limit for display by wl executable */ -+ int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */ -+ uint8 version; /* Version of the data format wlu <--> driver */ -+ uint8 display_core; /* Displayed curpower core */ -+#ifdef PPR_API -+} tx_power_new_t; -+#else -+} tx_power_t; -+#endif -+ -+typedef struct tx_inst_power { -+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ -+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -+} tx_inst_power_t; -+ -+ -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ -+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain -+ * without adjustment -+ */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 tx_power_max[4]; /* Maximum target power among all rates */ -+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ -+ txppr_t user_limit; /* User limit */ -+ txppr_t reg_limit; /* Regulatory power limit */ -+ txppr_t board_limit; /* Max power board can support (SROM) */ -+ txppr_t target; /* Latest target power */ -+} wl_txpwr_t; -+ -+#define WL_NUM_TXCHAIN_MAX 4 -+typedef struct wl_txchain_pwr_offsets { -+ int8 offset[WL_NUM_TXCHAIN_MAX]; /* quarter dBm signed offset for each chain */ -+} wl_txchain_pwr_offsets_t; -+ -+/* 802.11h measurement types */ -+#define WLC_MEASURE_TPC 1 -+#define WLC_MEASURE_CHANNEL_BASIC 2 -+#define WLC_MEASURE_CHANNEL_CCA 3 -+#define WLC_MEASURE_CHANNEL_RPI 4 -+ -+/* regulatory enforcement levels */ -+#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ -+#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ -+#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ -+#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ -+/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE -+ * adoption is done regardless of capability spectrum_management -+ */ -+#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ -+ -+#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ -+#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ -+#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ -+#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ -+#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ -+#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ -+#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ -+ -+/* BTC mode used by "btc_mode" iovar */ -+#define WL_BTC_DISABLE 0 /* disable BT coexistence */ -+#define WL_BTC_FULLTDM 1 /* full TDM COEX */ -+#define WL_BTC_ENABLE 1 /* full TDM COEX to maintain backward compatiblity */ -+#define WL_BTC_PREMPT 2 /* full TDM COEX with preemption */ -+#define WL_BTC_LITE 3 /* light weight coex for large isolation platform */ -+#define WL_BTC_PARALLEL 4 /* BT and WLAN run in parallel with separate antenna */ -+#define WL_BTC_HYBRID 5 /* hybrid coex, only ack is allowed to transmit in BT slot */ -+#define WL_BTC_DEFAULT 8 /* set the default mode for the device */ -+#define WL_INF_BTC_DISABLE 0 -+#define WL_INF_BTC_ENABLE 1 -+#define WL_INF_BTC_AUTO 3 -+ -+/* BTC wire used by "btc_wire" iovar */ -+#define WL_BTC_DEFWIRE 0 /* use default wire setting */ -+#define WL_BTC_2WIRE 2 /* use 2-wire BTC */ -+#define WL_BTC_3WIRE 3 /* use 3-wire BTC */ -+#define WL_BTC_4WIRE 4 /* use 4-wire BTC */ -+ -+/* BTC flags: BTC configuration that can be set by host */ -+#define WL_BTC_FLAG_PREMPT (1 << 0) -+#define WL_BTC_FLAG_BT_DEF (1 << 1) -+#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) -+#define WL_BTC_FLAG_SIM_RSP (1 << 3) -+#define WL_BTC_FLAG_PS_PROTECT (1 << 4) -+#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) -+#define WL_BTC_FLAG_ECI (1 << 6) -+#define WL_BTC_FLAG_LIGHT (1 << 7) -+#define WL_BTC_FLAG_PARALLEL (1 << 8) -+ -+/* Message levels */ -+#define WL_ERROR_VAL 0x00000001 -+#define WL_TRACE_VAL 0x00000002 -+#define WL_PRHDRS_VAL 0x00000004 -+#define WL_PRPKT_VAL 0x00000008 -+#define WL_INFORM_VAL 0x00000010 -+#define WL_TMP_VAL 0x00000020 -+#define WL_OID_VAL 0x00000040 -+#define WL_RATE_VAL 0x00000080 -+#define WL_ASSOC_VAL 0x00000100 -+#define WL_PRUSR_VAL 0x00000200 -+#define WL_PS_VAL 0x00000400 -+#define WL_TXPWR_VAL 0x00000800 /* retired in TOT on 6/10/2009 */ -+#define WL_PORT_VAL 0x00001000 -+#define WL_DUAL_VAL 0x00002000 -+#define WL_WSEC_VAL 0x00004000 -+#define WL_WSEC_DUMP_VAL 0x00008000 -+#define WL_LOG_VAL 0x00010000 -+#define WL_NRSSI_VAL 0x00020000 /* retired in TOT on 6/10/2009 */ -+#define WL_LOFT_VAL 0x00040000 /* retired in TOT on 6/10/2009 */ -+#define WL_REGULATORY_VAL 0x00080000 -+#define WL_PHYCAL_VAL 0x00100000 /* retired in TOT on 6/10/2009 */ -+#define WL_RADAR_VAL 0x00200000 /* retired in TOT on 6/10/2009 */ -+#define WL_MPC_VAL 0x00400000 -+#define WL_APSTA_VAL 0x00800000 -+#define WL_DFS_VAL 0x01000000 -+#define WL_BA_VAL 0x02000000 /* retired in TOT on 6/14/2010 */ -+#define WL_ACI_VAL 0x04000000 -+#define WL_MBSS_VAL 0x04000000 -+#define WL_CAC_VAL 0x08000000 -+#define WL_AMSDU_VAL 0x10000000 -+#define WL_AMPDU_VAL 0x20000000 -+#define WL_FFPLD_VAL 0x40000000 -+ -+/* wl_msg_level is full. For new bits take the next one and AND with -+ * wl_msg_level2 in wl_dbg.h -+ */ -+#define WL_DPT_VAL 0x00000001 -+#define WL_SCAN_VAL 0x00000002 -+#define WL_WOWL_VAL 0x00000004 -+#define WL_COEX_VAL 0x00000008 -+#define WL_RTDC_VAL 0x00000010 -+#define WL_PROTO_VAL 0x00000020 -+#define WL_BTA_VAL 0x00000040 -+#define WL_CHANINT_VAL 0x00000080 -+#define WL_THERMAL_VAL 0x00000100 /* retired in TOT on 6/10/2009 */ -+#define WL_P2P_VAL 0x00000200 -+#define WL_ITFR_VAL 0x00000400 -+#define WL_MCHAN_VAL 0x00000800 -+#define WL_TDLS_VAL 0x00001000 -+#define WL_MCNX_VAL 0x00002000 -+#define WL_PROT_VAL 0x00004000 -+#define WL_PSTA_VAL 0x00008000 -+#define WL_TBTT_VAL 0x00010000 -+#define WL_NIC_VAL 0x00020000 -+#define WL_PWRSEL_VAL 0x00040000 -+/* use top-bit for WL_TIME_STAMP_VAL because this is a modifier -+ * rather than a message-type of its own -+ */ -+#define WL_TIMESTAMP_VAL 0x80000000 -+ -+/* max # of leds supported by GPIO (gpio pin# == led index#) */ -+#define WL_LED_NUMGPIO 32 /* gpio 0-31 */ -+ -+/* led per-pin behaviors */ -+#define WL_LED_OFF 0 /* always off */ -+#define WL_LED_ON 1 /* always on */ -+#define WL_LED_ACTIVITY 2 /* activity */ -+#define WL_LED_RADIO 3 /* radio enabled */ -+#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ -+#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ -+#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ -+#define WL_LED_WI1 7 -+#define WL_LED_WI2 8 -+#define WL_LED_WI3 9 -+#define WL_LED_ASSOC 10 /* associated state indicator */ -+#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ -+#define WL_LED_ASSOCACT 12 /* on when associated; blink fast for activity */ -+#define WL_LED_WI4 13 -+#define WL_LED_WI5 14 -+#define WL_LED_BLINKSLOW 15 /* blink slow */ -+#define WL_LED_BLINKMED 16 /* blink med */ -+#define WL_LED_BLINKFAST 17 /* blink fast */ -+#define WL_LED_BLINKCUSTOM 18 /* blink custom */ -+#define WL_LED_BLINKPERIODIC 19 /* blink periodic (custom 1000ms / off 400ms) */ -+#define WL_LED_ASSOC_WITH_SEC 20 /* when connected with security */ -+ /* keep on for 300 sec */ -+#define WL_LED_START_OFF 21 /* off upon boot, could be turned on later */ -+#define WL_LED_NUMBEHAVIOR 22 -+ -+/* led behavior numeric value format */ -+#define WL_LED_BEH_MASK 0x7f /* behavior mask */ -+#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ -+ -+/* maximum channels returned by the get valid channels iovar */ -+#define WL_NUMCHANNELS 64 -+ -+/* max number of chanspecs (used by the iovar to calc. buf space) */ -+#define WL_NUMCHANSPECS 110 -+ -+/* WDS link local endpoint WPA role */ -+#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ -+#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ -+#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ -+ -+/* number of bytes needed to define a 128-bit mask for MAC event reporting */ -+#define WL_EVENTING_MASK_LEN 16 -+ -+/* -+ * Join preference iovar value is an array of tuples. Each tuple has a one-byte type, -+ * a one-byte length, and a variable length value. RSSI type tuple must be present -+ * in the array. -+ * -+ * Types are defined in "join preference types" section. -+ * -+ * Length is the value size in octets. It is reserved for WL_JOIN_PREF_WPA type tuple -+ * and must be set to zero. -+ * -+ * Values are defined below. -+ * -+ * 1. RSSI - 2 octets -+ * offset 0: reserved -+ * offset 1: reserved -+ * -+ * 2. WPA - 2 + 12 * n octets (n is # tuples defined below) -+ * offset 0: reserved -+ * offset 1: # of tuples -+ * offset 2: tuple 1 -+ * offset 14: tuple 2 -+ * ... -+ * offset 2 + 12 * (n - 1) octets: tuple n -+ * -+ * struct wpa_cfg_tuple { -+ * uint8 akm[DOT11_OUI_LEN+1]; akm suite -+ * uint8 ucipher[DOT11_OUI_LEN+1]; unicast cipher suite -+ * uint8 mcipher[DOT11_OUI_LEN+1]; multicast cipher suite -+ * }; -+ * -+ * multicast cipher suite can be specified as a specific cipher suite or WL_WPA_ACP_MCS_ANY. -+ * -+ * 3. BAND - 2 octets -+ * offset 0: reserved -+ * offset 1: see "band preference" and "band types" -+ * -+ * 4. BAND RSSI - 2 octets -+ * offset 0: band types -+ * offset 1: +ve RSSI boost balue in dB -+ */ -+ -+/* join preference types */ -+#define WL_JOIN_PREF_RSSI 1 /* by RSSI */ -+#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers */ -+#define WL_JOIN_PREF_BAND 3 /* by 802.11 band */ -+#define WL_JOIN_PREF_RSSI_DELTA 4 /* by 802.11 band only if RSSI delta condition matches */ -+#define WL_JOIN_PREF_TRANS_PREF 5 /* defined by requesting AP */ -+ -+/* band preference */ -+#define WLJP_BAND_ASSOC_PREF 255 /* use what WLC_SET_ASSOC_PREFER ioctl specifies */ -+ -+/* any multicast cipher suite */ -+#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" -+ -+struct tsinfo_arg { -+ uint8 octets[3]; -+}; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define NFIFO 6 /* # tx/rx fifopairs */ -+ -+#define WL_CNT_T_VERSION 8 /* current version of wl_cnt_t struct */ -+ -+typedef struct { -+ uint16 version; /* see definition of WL_CNT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txerror; /* tx data errors (derived: sum of others) */ -+ uint32 txctl; /* tx management frames */ -+ uint32 txprshort; /* tx short preamble frames */ -+ uint32 txserr; /* tx status errors */ -+ uint32 txnobuf; /* tx out of buffers errors */ -+ uint32 txnoassoc; /* tx discard because we're not associated */ -+ uint32 txrunt; /* tx runt frames */ -+ uint32 txchit; /* tx header cache hit (fastpath) */ -+ uint32 txcmiss; /* tx header cache miss (slowpath) */ -+ -+ /* transmit chip error counters */ -+ uint32 txuflo; /* tx fifo underflows */ -+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ -+ uint32 txphycrs; -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ uint32 rxerror; /* rx data errors (derived: sum of others) */ -+ uint32 rxctl; /* rx management frames */ -+ uint32 rxnobuf; /* rx out of buffers errors */ -+ uint32 rxnondata; /* rx non data frames in the data channel errors */ -+ uint32 rxbadds; /* rx bad DS errors */ -+ uint32 rxbadcm; /* rx bad control or management frames */ -+ uint32 rxfragerr; /* rx fragmentation errors */ -+ uint32 rxrunt; /* rx runt frames */ -+ uint32 rxgiant; /* rx giant frames */ -+ uint32 rxnoscb; /* rx no scb error */ -+ uint32 rxbadproto; /* rx invalid frames */ -+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ -+ uint32 rxbadda; /* rx frames tossed for invalid da */ -+ uint32 rxfilter; /* rx frames filtered out */ -+ -+ /* receive chip error counters */ -+ uint32 rxoflo; /* rx fifo overflow errors */ -+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ -+ -+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ -+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ -+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ -+ -+ /* misc counters */ -+ uint32 dmade; /* tx/rx dma descriptor errors */ -+ uint32 dmada; /* tx/rx dma data errors */ -+ uint32 dmape; /* tx/rx dma descriptor protocol errors */ -+ uint32 reset; /* reset count */ -+ uint32 tbtt; /* cnts the TBTT int's */ -+ uint32 txdmawar; -+ uint32 pkt_callback_reg_fail; /* callbacks register failure */ -+ -+ /* MAC counters: 32-bit version of d11.h's macstat_t */ -+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, -+ * Control Management (includes retransmissions) -+ */ -+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ -+ uint32 txctsfrm; /* number of CTS sent out by the MAC */ -+ uint32 txackfrm; /* number of ACK frames sent out */ -+ uint32 txdnlfrm; /* Not used */ -+ uint32 txbcnfrm; /* beacons transmitted */ -+ uint32 txfunfl[8]; /* per-fifo tx underflows */ -+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS -+ * or BCN) -+ */ -+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for -+ * driver enqueued frames -+ */ -+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ -+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ -+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not -+ * data/control/management -+ */ -+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ -+ uint32 rxbadplcp; /* parity check of the PLCP header failed */ -+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ -+ uint32 rxstrt; /* Number of received frames with a good PLCP -+ * (i.e. passing parity check) -+ */ -+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ -+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ -+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ -+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ -+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ -+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ -+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ -+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ -+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ -+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ -+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ -+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ -+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ -+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC -+ * (unlikely to see these) -+ */ -+ uint32 rxbeaconmbss; /* beacons received from member of BSS */ -+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from -+ * other BSS (WDS FRAME) -+ */ -+ uint32 rxbeaconobss; /* beacons received from other BSS */ -+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames -+ * expecting a response -+ */ -+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ -+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ -+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ -+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ -+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ -+ uint32 pmqovfl; /* Number of PMQ overflows */ -+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into -+ * the PRQ fifo -+ */ -+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ -+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did -+ * not get ACK -+ */ -+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ -+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ -+ * fifo because a probe response could not be sent out within -+ * the time limit defined in M_PRS_MAXTIME -+ */ -+ uint32 rxnack; /* obsolete */ -+ uint32 frmscons; /* obsolete */ -+ uint32 txnack; /* obsolete */ -+ uint32 txglitch_nack; /* obsolete */ -+ uint32 txburst; /* obsolete */ -+ -+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay; /* TKIPReplays */ -+ uint32 ccmpfmterr; /* CCMPFormatErrors */ -+ uint32 ccmpreplay; /* CCMPReplays */ -+ uint32 ccmpundec; /* CCMPDecryptErrors */ -+ uint32 fourwayfail; /* FourWayHandshakeFailures */ -+ uint32 wepundec; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess; /* DecryptSuccessCount */ -+ uint32 tkipicverr; /* TKIPICVErrorCount */ -+ uint32 wepexcluded; /* dot11WEPExcludedCount */ -+ -+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ -+ uint32 psmwds; /* Count PSM watchdogs */ -+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ -+ -+ /* MBSS counters, AP only */ -+ uint32 prq_entries_handled; /* PRQ entries read in */ -+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ -+ uint32 prq_bad_entries; /* which could not be translated to info */ -+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ -+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ -+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ -+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+ -+ /* pkteng rx frame stats */ -+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ -+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ -+ -+ uint32 rfdisable; /* count of radio disables */ -+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ -+ -+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ -+ -+ uint32 txmpdu_sgi; /* count for sgi transmit */ -+ uint32 rxmpdu_sgi; /* count for sgi received */ -+ uint32 txmpdu_stbc; /* count for stbc transmit */ -+ uint32 rxmpdu_stbc; /* count for stbc received */ -+ -+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay_mcst; /* TKIPReplays */ -+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ -+ uint32 ccmpreplay_mcst; /* CCMPReplays */ -+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ -+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ -+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess_mcst; /* DecryptSuccessCount */ -+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ -+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ -+ -+ uint32 dma_hang; /* count for dma hang */ -+ uint32 reinit; /* count for reinit */ -+ -+ uint32 pstatxucast; /* count of ucast frames xmitted on all psta assoc */ -+ uint32 pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ -+ uint32 pstarxucast; /* count of ucast frames received on all psta assoc */ -+ uint32 pstarxbcmc; /* count of bcmc frames received on all psta */ -+ uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */ -+ -+ uint32 cso_passthrough; /* hw cso required but passthrough */ -+} wl_cnt_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+typedef struct { -+ uint16 version; /* see definition of WL_CNT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txerror; /* tx data errors (derived: sum of others) */ -+ uint32 txctl; /* tx management frames */ -+ uint32 txprshort; /* tx short preamble frames */ -+ uint32 txserr; /* tx status errors */ -+ uint32 txnobuf; /* tx out of buffers errors */ -+ uint32 txnoassoc; /* tx discard because we're not associated */ -+ uint32 txrunt; /* tx runt frames */ -+ uint32 txchit; /* tx header cache hit (fastpath) */ -+ uint32 txcmiss; /* tx header cache miss (slowpath) */ -+ -+ /* transmit chip error counters */ -+ uint32 txuflo; /* tx fifo underflows */ -+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ -+ uint32 txphycrs; -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ uint32 rxerror; /* rx data errors (derived: sum of others) */ -+ uint32 rxctl; /* rx management frames */ -+ uint32 rxnobuf; /* rx out of buffers errors */ -+ uint32 rxnondata; /* rx non data frames in the data channel errors */ -+ uint32 rxbadds; /* rx bad DS errors */ -+ uint32 rxbadcm; /* rx bad control or management frames */ -+ uint32 rxfragerr; /* rx fragmentation errors */ -+ uint32 rxrunt; /* rx runt frames */ -+ uint32 rxgiant; /* rx giant frames */ -+ uint32 rxnoscb; /* rx no scb error */ -+ uint32 rxbadproto; /* rx invalid frames */ -+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ -+ uint32 rxbadda; /* rx frames tossed for invalid da */ -+ uint32 rxfilter; /* rx frames filtered out */ -+ -+ /* receive chip error counters */ -+ uint32 rxoflo; /* rx fifo overflow errors */ -+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ -+ -+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ -+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ -+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ -+ -+ /* misc counters */ -+ uint32 dmade; /* tx/rx dma descriptor errors */ -+ uint32 dmada; /* tx/rx dma data errors */ -+ uint32 dmape; /* tx/rx dma descriptor protocol errors */ -+ uint32 reset; /* reset count */ -+ uint32 tbtt; /* cnts the TBTT int's */ -+ uint32 txdmawar; -+ uint32 pkt_callback_reg_fail; /* callbacks register failure */ -+ -+ /* MAC counters: 32-bit version of d11.h's macstat_t */ -+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, -+ * Control Management (includes retransmissions) -+ */ -+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ -+ uint32 txctsfrm; /* number of CTS sent out by the MAC */ -+ uint32 txackfrm; /* number of ACK frames sent out */ -+ uint32 txdnlfrm; /* Not used */ -+ uint32 txbcnfrm; /* beacons transmitted */ -+ uint32 txfunfl[8]; /* per-fifo tx underflows */ -+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS -+ * or BCN) -+ */ -+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for -+ * driver enqueued frames -+ */ -+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ -+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ -+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not -+ * data/control/management -+ */ -+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ -+ uint32 rxbadplcp; /* parity check of the PLCP header failed */ -+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ -+ uint32 rxstrt; /* Number of received frames with a good PLCP -+ * (i.e. passing parity check) -+ */ -+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ -+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ -+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ -+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ -+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ -+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ -+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ -+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ -+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ -+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ -+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ -+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ -+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ -+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC -+ * (unlikely to see these) -+ */ -+ uint32 rxbeaconmbss; /* beacons received from member of BSS */ -+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from -+ * other BSS (WDS FRAME) -+ */ -+ uint32 rxbeaconobss; /* beacons received from other BSS */ -+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames -+ * expecting a response -+ */ -+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ -+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ -+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ -+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ -+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ -+ uint32 pmqovfl; /* Number of PMQ overflows */ -+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into -+ * the PRQ fifo -+ */ -+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ -+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did -+ * not get ACK -+ */ -+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ -+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ -+ * fifo because a probe response could not be sent out within -+ * the time limit defined in M_PRS_MAXTIME -+ */ -+ uint32 rxnack; -+ uint32 frmscons; -+ uint32 txnack; -+ uint32 txglitch_nack; /* obsolete */ -+ uint32 txburst; /* obsolete */ -+ -+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay; /* TKIPReplays */ -+ uint32 ccmpfmterr; /* CCMPFormatErrors */ -+ uint32 ccmpreplay; /* CCMPReplays */ -+ uint32 ccmpundec; /* CCMPDecryptErrors */ -+ uint32 fourwayfail; /* FourWayHandshakeFailures */ -+ uint32 wepundec; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess; /* DecryptSuccessCount */ -+ uint32 tkipicverr; /* TKIPICVErrorCount */ -+ uint32 wepexcluded; /* dot11WEPExcludedCount */ -+ -+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay_mcst; /* TKIPReplays */ -+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ -+ uint32 ccmpreplay_mcst; /* CCMPReplays */ -+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ -+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ -+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess_mcst; /* DecryptSuccessCount */ -+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ -+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ -+ -+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ -+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ -+ uint32 psmwds; /* Count PSM watchdogs */ -+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ -+ -+ /* MBSS counters, AP only */ -+ uint32 prq_entries_handled; /* PRQ entries read in */ -+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ -+ uint32 prq_bad_entries; /* which could not be translated to info */ -+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ -+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ -+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ -+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+ -+ /* pkteng rx frame stats */ -+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ -+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ -+ -+ uint32 rfdisable; /* count of radio disables */ -+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ -+ -+ uint32 txmpdu_sgi; /* count for sgi transmit */ -+ uint32 rxmpdu_sgi; /* count for sgi received */ -+ uint32 txmpdu_stbc; /* count for stbc transmit */ -+ uint32 rxmpdu_stbc; /* count for stbc received */ -+} wl_cnt_ver_six_t; -+ -+#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ -+ -+typedef struct { -+ uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txfail; /* tx failures */ -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+} wl_delta_stats_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ -+ -+typedef struct { -+ uint32 packets; -+ uint32 bytes; -+} wl_traffic_stats_t; -+ -+typedef struct { -+ uint16 version; /* see definition of WL_WME_CNT_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ -+ wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ -+ wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ -+ wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ -+ -+ wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ -+ -+ wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ -+ -+} wl_wme_cnt_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+struct wl_msglevel2 { -+ uint32 low; -+ uint32 high; -+}; -+ -+typedef struct wl_mkeep_alive_pkt { -+ uint16 version; /* Version for mkeep_alive */ -+ uint16 length; /* length of fixed parameters in the structure */ -+ uint32 period_msec; -+ uint16 len_bytes; -+ uint8 keep_alive_id; /* 0 - 3 for N = 4 */ -+ uint8 data[1]; -+} wl_mkeep_alive_pkt_t; -+ -+#define WL_MKEEP_ALIVE_VERSION 1 -+#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data) -+#define WL_MKEEP_ALIVE_PRECISION 500 -+ -+#ifdef WLBA -+ -+#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ -+ -+/* block ack related stats */ -+typedef struct wlc_ba_cnt { -+ uint16 version; /* WLC_BA_CNT_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txpdu; /* pdus sent */ -+ uint32 txsdu; /* sdus sent */ -+ uint32 txfc; /* tx side flow controlled packets */ -+ uint32 txfci; /* tx side flow control initiated */ -+ uint32 txretrans; /* retransmitted pdus */ -+ uint32 txbatimer; /* ba resend due to timer */ -+ uint32 txdrop; /* dropped packets */ -+ uint32 txaddbareq; /* addba req sent */ -+ uint32 txaddbaresp; /* addba resp sent */ -+ uint32 txdelba; /* delba sent */ -+ uint32 txba; /* ba sent */ -+ uint32 txbar; /* bar sent */ -+ uint32 txpad[4]; /* future */ -+ -+ /* receive side counters */ -+ uint32 rxpdu; /* pdus recd */ -+ uint32 rxqed; /* pdus buffered before sending up */ -+ uint32 rxdup; /* duplicate pdus */ -+ uint32 rxnobuf; /* pdus discarded due to no buf */ -+ uint32 rxaddbareq; /* addba req recd */ -+ uint32 rxaddbaresp; /* addba resp recd */ -+ uint32 rxdelba; /* delba recd */ -+ uint32 rxba; /* ba recd */ -+ uint32 rxbar; /* bar recd */ -+ uint32 rxinvba; /* invalid ba recd */ -+ uint32 rxbaholes; /* ba recd with holes */ -+ uint32 rxunexp; /* unexpected packets */ -+ uint32 rxpad[4]; /* future */ -+} wlc_ba_cnt_t; -+#endif /* WLBA */ -+ -+/* structure for per-tid ampdu control */ -+struct ampdu_tid_control { -+ uint8 tid; /* tid */ -+ uint8 enable; /* enable/disable */ -+}; -+ -+/* structure for identifying ea/tid for sending addba/delba */ -+struct ampdu_ea_tid { -+ struct ether_addr ea; /* Station address */ -+ uint8 tid; /* tid */ -+}; -+/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ -+struct ampdu_retry_tid { -+ uint8 tid; /* tid */ -+ uint8 retry; /* retry value */ -+}; -+ -+/* Different discovery modes for dpt */ -+#define DPT_DISCOVERY_MANUAL 0x01 /* manual discovery mode */ -+#define DPT_DISCOVERY_AUTO 0x02 /* auto discovery mode */ -+#define DPT_DISCOVERY_SCAN 0x04 /* scan-based discovery mode */ -+ -+/* different path selection values */ -+#define DPT_PATHSEL_AUTO 0 /* auto mode for path selection */ -+#define DPT_PATHSEL_DIRECT 1 /* always use direct DPT path */ -+#define DPT_PATHSEL_APPATH 2 /* always use AP path */ -+ -+/* different ops for deny list */ -+#define DPT_DENY_LIST_ADD 1 /* add to dpt deny list */ -+#define DPT_DENY_LIST_REMOVE 2 /* remove from dpt deny list */ -+ -+/* different ops for manual end point */ -+#define DPT_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ -+#define DPT_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ -+#define DPT_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ -+ -+/* structure for dpt iovars */ -+typedef struct dpt_iovar { -+ struct ether_addr ea; /* Station address */ -+ uint8 mode; /* mode: depends on iovar */ -+ uint32 pad; /* future */ -+} dpt_iovar_t; -+ -+/* flags to indicate DPT status */ -+#define DPT_STATUS_ACTIVE 0x01 /* link active (though may be suspended) */ -+#define DPT_STATUS_AES 0x02 /* link secured through AES encryption */ -+#define DPT_STATUS_FAILED 0x04 /* DPT link failed */ -+ -+#define DPT_FNAME_LEN 48 /* Max length of friendly name */ -+ -+typedef struct dpt_status { -+ uint8 status; /* flags to indicate status */ -+ uint8 fnlen; /* length of friendly name */ -+ uchar name[DPT_FNAME_LEN]; /* friendly name */ -+ uint32 rssi; /* RSSI of the link */ -+ sta_info_t sta; /* sta info */ -+} dpt_status_t; -+ -+/* structure for dpt list */ -+typedef struct dpt_list { -+ uint32 num; /* number of entries in struct */ -+ dpt_status_t status[1]; /* per station info */ -+} dpt_list_t; -+ -+/* structure for dpt friendly name */ -+typedef struct dpt_fname { -+ uint8 len; /* length of friendly name */ -+ uchar name[DPT_FNAME_LEN]; /* friendly name */ -+} dpt_fname_t; -+ -+#define BDD_FNAME_LEN 32 /* Max length of friendly name */ -+typedef struct bdd_fname { -+ uint8 len; /* length of friendly name */ -+ uchar name[BDD_FNAME_LEN]; /* friendly name */ -+} bdd_fname_t; -+ -+/* structure for addts arguments */ -+/* For ioctls that take a list of TSPEC */ -+struct tslist { -+ int count; /* number of tspecs */ -+ struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ -+}; -+ -+#ifdef WLTDLS -+/* different ops for manual end point */ -+#define TDLS_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ -+#define TDLS_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ -+#define TDLS_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ -+#define TDLS_MANUAL_EP_PM 4 /* put dpt endpoint in PM mode */ -+#define TDLS_MANUAL_EP_WAKE 5 /* wake up dpt endpoint from PM */ -+#define TDLS_MANUAL_EP_DISCOVERY 6 /* discover if endpoint is TDLS capable */ -+#define TDLS_MANUAL_EP_CHSW 7 /* channel switch */ -+ -+/* structure for tdls iovars */ -+typedef struct tdls_iovar { -+ struct ether_addr ea; /* Station address */ -+ uint8 mode; /* mode: depends on iovar */ -+ chanspec_t chanspec; -+ uint32 pad; /* future */ -+} tdls_iovar_t; -+ -+/* modes */ -+#define TDLS_WFD_IE_TX 0 -+#define TDLS_WFD_IE_RX 1 -+#define TDLS_WFD_IE_SIZE 255 -+/* structure for tdls wfd ie */ -+typedef struct tdls_wfd_ie_iovar { -+ struct ether_addr ea; /* Station address */ -+ uint8 mode; -+ uint8 length; -+ uint8 data[TDLS_WFD_IE_SIZE]; -+} tdls_wfd_ie_iovar_t; -+#endif /* WLTDLS */ -+ -+/* structure for addts/delts arguments */ -+typedef struct tspec_arg { -+ uint16 version; /* see definition of TSPEC_ARG_VERSION */ -+ uint16 length; /* length of entire structure */ -+ uint flag; /* bit field */ -+ /* TSPEC Arguments */ -+ struct tsinfo_arg tsinfo; /* TS Info bit field */ -+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ -+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ -+ uint min_srv_interval; /* Minimum Service Interval (us) */ -+ uint max_srv_interval; /* Maximum Service Interval (us) */ -+ uint inactivity_interval; /* Inactivity Interval (us) */ -+ uint suspension_interval; /* Suspension Interval (us) */ -+ uint srv_start_time; /* Service Start Time (us) */ -+ uint min_data_rate; /* Minimum Data Rate (bps) */ -+ uint mean_data_rate; /* Mean Data Rate (bps) */ -+ uint peak_data_rate; /* Peak Data Rate (bps) */ -+ uint max_burst_size; /* Maximum Burst Size (bytes) */ -+ uint delay_bound; /* Delay Bound (us) */ -+ uint min_phy_rate; /* Minimum PHY Rate (bps) */ -+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */ -+ uint16 medium_time; /* Medium Time (32 us/s periods) */ -+ uint8 dialog_token; /* dialog token */ -+} tspec_arg_t; -+ -+/* tspec arg for desired station */ -+typedef struct tspec_per_sta_arg { -+ struct ether_addr ea; -+ struct tspec_arg ts; -+} tspec_per_sta_arg_t; -+ -+/* structure for max bandwidth for each access category */ -+typedef struct wme_max_bandwidth { -+ uint32 ac[AC_COUNT]; /* max bandwidth for each access category */ -+} wme_max_bandwidth_t; -+ -+#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) -+ -+/* current version of wl_tspec_arg_t struct */ -+#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */ -+#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */ -+#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */ -+#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */ -+ -+ -+#define WL_WOWL_KEEPALIVE_MAX_PACKET_SIZE 80 -+#define WLC_WOWL_MAX_KEEPALIVE 2 -+ -+/* define for flag */ -+#define TSPEC_PENDING 0 /* TSPEC pending */ -+#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ -+#define TSPEC_REJECTED 2 /* TSPEC rejected */ -+#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ -+#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ -+ -+ -+/* Software feature flag defines used by wlfeatureflag */ -+#ifdef WLAFTERBURNER -+#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ -+#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ -+#endif /* WLAFTERBURNER */ -+#define WL_SWFL_NOHWRADIO 0x0004 -+#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ -+#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ -+ -+#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ -+ -+/* Packet lifetime configuration per ac */ -+typedef struct wl_lifetime { -+ uint32 ac; /* access class */ -+ uint32 lifetime; /* Packet lifetime value in ms */ -+} wl_lifetime_t; -+ -+/* Channel Switch Announcement param */ -+typedef struct wl_chan_switch { -+ uint8 mode; /* value 0 or 1 */ -+ uint8 count; /* count # of beacons before switching */ -+ chanspec_t chspec; /* chanspec */ -+ uint8 reg; /* regulatory class */ -+} wl_chan_switch_t; -+ -+/* Roaming trigger definitions for WLC_SET_ROAM_TRIGGER. -+ * -+ * (-100 < value < 0) value is used directly as a roaming trigger in dBm -+ * (0 <= value) value specifies a logical roaming trigger level from -+ * the list below -+ * -+ * WLC_GET_ROAM_TRIGGER always returns roaming trigger value in dBm, never -+ * the logical roam trigger value. -+ */ -+#define WLC_ROAM_TRIGGER_DEFAULT 0 /* default roaming trigger */ -+#define WLC_ROAM_TRIGGER_BANDWIDTH 1 /* optimize for bandwidth roaming trigger */ -+#define WLC_ROAM_TRIGGER_DISTANCE 2 /* optimize for distance roaming trigger */ -+#define WLC_ROAM_TRIGGER_AUTO 3 /* auto-detect environment */ -+#define WLC_ROAM_TRIGGER_MAX_VALUE 3 /* max. valid value */ -+ -+#define WLC_ROAM_NEVER_ROAM_TRIGGER (-100) /* Avoid Roaming by setting a large value */ -+ -+/* Preferred Network Offload (PNO, formerly PFN) defines */ -+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ -+ -+enum { -+ PFN_LIST_ORDER, -+ PFN_RSSI -+}; -+ -+enum { -+ DISABLE, -+ ENABLE -+}; -+ -+enum { -+ OFF_ADAPT, -+ SMART_ADAPT, -+ STRICT_ADAPT, -+ SLOW_ADAPT -+}; -+ -+#define SORT_CRITERIA_BIT 0 -+#define AUTO_NET_SWITCH_BIT 1 -+#define ENABLE_BKGRD_SCAN_BIT 2 -+#define IMMEDIATE_SCAN_BIT 3 -+#define AUTO_CONNECT_BIT 4 -+#define ENABLE_BD_SCAN_BIT 5 -+#define ENABLE_ADAPTSCAN_BIT 6 -+#define IMMEDIATE_EVENT_BIT 8 -+#define SUPPRESS_SSID_BIT 9 -+#define ENABLE_NET_OFFLOAD_BIT 10 -+ -+#define SORT_CRITERIA_MASK 0x0001 -+#define AUTO_NET_SWITCH_MASK 0x0002 -+#define ENABLE_BKGRD_SCAN_MASK 0x0004 -+#define IMMEDIATE_SCAN_MASK 0x0008 -+#define AUTO_CONNECT_MASK 0x0010 -+ -+#define ENABLE_BD_SCAN_MASK 0x0020 -+#define ENABLE_ADAPTSCAN_MASK 0x00c0 -+#define IMMEDIATE_EVENT_MASK 0x0100 -+#define SUPPRESS_SSID_MASK 0x0200 -+#define ENABLE_NET_OFFLOAD_MASK 0x0400 -+ -+#define PFN_VERSION 2 -+#define PFN_SCANRESULT_VERSION 1 -+#define MAX_PFN_LIST_COUNT 16 -+ -+#define PFN_COMPLETE 1 -+#define PFN_INCOMPLETE 0 -+ -+#define DEFAULT_BESTN 2 -+#define DEFAULT_MSCAN 0 -+#define DEFAULT_REPEAT 10 -+#define DEFAULT_EXP 2 -+ -+/* PFN network info structure */ -+typedef struct wl_pfn_subnet_info { -+ struct ether_addr BSSID; -+ uint8 channel; /* channel number only */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+} wl_pfn_subnet_info_t; -+ -+typedef struct wl_pfn_net_info { -+ wl_pfn_subnet_info_t pfnsubnet; -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ uint16 timestamp; /* age in seconds */ -+} wl_pfn_net_info_t; -+ -+typedef struct wl_pfn_scanresults { -+ uint32 version; -+ uint32 status; -+ uint32 count; -+ wl_pfn_net_info_t netinfo[1]; -+} wl_pfn_scanresults_t; -+ -+/* PFN data structure */ -+typedef struct wl_pfn_param { -+ int32 version; /* PNO parameters version */ -+ int32 scan_freq; /* Scan frequency */ -+ int32 lost_network_timeout; /* Timeout in sec. to declare -+ * discovered network as lost -+ */ -+ int16 flags; /* Bit field to control features -+ * of PFN such as sort criteria auto -+ * enable switch and background scan -+ */ -+ int16 rssi_margin; /* Margin to avoid jitter for choosing a -+ * PFN based on RSSI sort criteria -+ */ -+ uint8 bestn; /* number of best networks in each scan */ -+ uint8 mscan; /* number of scans recorded */ -+ uint8 repeat; /* Minimum number of scan intervals -+ *before scan frequency changes in adaptive scan -+ */ -+ uint8 exp; /* Exponent of 2 for maximum scan interval */ -+ int32 slow_freq; /* slow scan period */ -+} wl_pfn_param_t; -+ -+typedef struct wl_pfn_bssid { -+ struct ether_addr macaddr; -+ /* Bit4: suppress_lost, Bit3: suppress_found */ -+ uint16 flags; -+} wl_pfn_bssid_t; -+#define WL_PFN_SUPPRESSFOUND_MASK 0x08 -+#define WL_PFN_SUPPRESSLOST_MASK 0x10 -+ -+typedef struct wl_pfn_cfg { -+ uint32 reporttype; -+ int32 channel_num; -+ uint16 channel_list[WL_NUMCHANNELS]; -+} wl_pfn_cfg_t; -+#define WL_PFN_REPORT_ALLNET 0 -+#define WL_PFN_REPORT_SSIDNET 1 -+#define WL_PFN_REPORT_BSSIDNET 2 -+ -+typedef struct wl_pfn { -+ wlc_ssid_t ssid; /* ssid name and its length */ -+ int32 flags; /* bit2: hidden */ -+ int32 infra; /* BSS Vs IBSS */ -+ int32 auth; /* Open Vs Closed */ -+ int32 wpa_auth; /* WPA type */ -+ int32 wsec; /* wsec value */ -+} wl_pfn_t; -+#define WL_PFN_HIDDEN_BIT 2 -+#define PNO_SCAN_MAX_FW 508*1000 /* max time scan time in msec */ -+#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 /* max time scan time in SEC */ -+#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */ -+#define WL_PFN_HIDDEN_MASK 0x4 -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* TCP Checksum Offload defines */ -+#define TOE_TX_CSUM_OL 0x00000001 -+#define TOE_RX_CSUM_OL 0x00000002 -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* TCP Checksum Offload error injection for testing */ -+#define TOE_ERRTEST_TX_CSUM 0x00000001 -+#define TOE_ERRTEST_RX_CSUM 0x00000002 -+#define TOE_ERRTEST_RX_CSUM2 0x00000004 -+ -+struct toe_ol_stats_t { -+ /* Num of tx packets that don't need to be checksummed */ -+ uint32 tx_summed; -+ -+ /* Num of tx packets where checksum is filled by offload engine */ -+ uint32 tx_iph_fill; -+ uint32 tx_tcp_fill; -+ uint32 tx_udp_fill; -+ uint32 tx_icmp_fill; -+ -+ /* Num of rx packets where toe finds out if checksum is good or bad */ -+ uint32 rx_iph_good; -+ uint32 rx_iph_bad; -+ uint32 rx_tcp_good; -+ uint32 rx_tcp_bad; -+ uint32 rx_udp_good; -+ uint32 rx_udp_bad; -+ uint32 rx_icmp_good; -+ uint32 rx_icmp_bad; -+ -+ /* Num of tx packets in which csum error is injected */ -+ uint32 tx_tcp_errinj; -+ uint32 tx_udp_errinj; -+ uint32 tx_icmp_errinj; -+ -+ /* Num of rx packets in which csum error is injected */ -+ uint32 rx_tcp_errinj; -+ uint32 rx_udp_errinj; -+ uint32 rx_icmp_errinj; -+}; -+ -+/* ARP Offload feature flags for arp_ol iovar */ -+#define ARP_OL_AGENT 0x00000001 -+#define ARP_OL_SNOOP 0x00000002 -+#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -+#define ARP_OL_PEER_AUTO_REPLY 0x00000008 -+ -+/* ARP Offload error injection */ -+#define ARP_ERRTEST_REPLY_PEER 0x1 -+#define ARP_ERRTEST_REPLY_HOST 0x2 -+ -+#define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ -+#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ -+ -+/* Arp offload statistic counts */ -+struct arp_ol_stats_t { -+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ -+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ -+ -+ uint32 arp_table_entries; /* ARP table entries */ -+ uint32 arp_table_overflow; /* ARP table additions skipped due to overflow */ -+ -+ uint32 host_request; /* ARP requests from host */ -+ uint32 host_reply; /* ARP replies from host */ -+ uint32 host_service; /* ARP requests from host serviced by ARP Agent */ -+ -+ uint32 peer_request; /* ARP requests received from network */ -+ uint32 peer_request_drop; /* ARP requests from network that were dropped */ -+ uint32 peer_reply; /* ARP replies received from network */ -+ uint32 peer_reply_drop; /* ARP replies from network that were dropped */ -+ uint32 peer_service; /* ARP request from host serviced by ARP Agent */ -+}; -+ -+/* NS offload statistic counts */ -+struct nd_ol_stats_t { -+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ -+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ -+ uint32 peer_request; /* NS requests received from network */ -+ uint32 peer_request_drop; /* NS requests from network that were dropped */ -+ uint32 peer_reply_drop; /* NA replies from network that were dropped */ -+ uint32 peer_service; /* NS request from host serviced by firmware */ -+}; -+ -+/* -+ * Keep-alive packet offloading. -+ */ -+ -+/* NAT keep-alive packets format: specifies the re-transmission period, the packet -+ * length, and packet contents. -+ */ -+typedef struct wl_keep_alive_pkt { -+ uint32 period_msec; /* Retransmission period (0 to disable packet re-transmits) */ -+ uint16 len_bytes; /* Size of packet to transmit (0 to disable packet re-transmits) */ -+ uint8 data[1]; /* Variable length packet to transmit. Contents should include -+ * entire ethernet packet (enet header, IP header, UDP header, -+ * and UDP payload) in network byte order. -+ */ -+} wl_keep_alive_pkt_t; -+ -+#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) -+ -+/* -+ * Dongle pattern matching filter. -+ */ -+ -+/* Packet filter types. Currently, only pattern matching is supported. */ -+typedef enum wl_pkt_filter_type { -+ WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */ -+} wl_pkt_filter_type_t; -+ -+#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t -+ -+/* Pattern matching filter. Specifies an offset within received packets to -+ * start matching, the pattern to match, the size of the pattern, and a bitmask -+ * that indicates which bits within the pattern should be matched. -+ */ -+typedef struct wl_pkt_filter_pattern { -+ uint32 offset; /* Offset within received packet to start pattern matching. -+ * Offset '0' is the first byte of the ethernet header. -+ */ -+ uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ -+ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts -+ * at offset 0. Pattern immediately follows mask. -+ */ -+} wl_pkt_filter_pattern_t; -+ -+/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ -+typedef struct wl_pkt_filter { -+ uint32 id; /* Unique filter id, specified by app. */ -+ uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ -+ uint32 negate_match; /* Negate the result of filter matches */ -+ union { /* Filter definitions */ -+ wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */ -+ } u; -+} wl_pkt_filter_t; -+ -+#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -+#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) -+ -+/* IOVAR "pkt_filter_enable" parameter. */ -+typedef struct wl_pkt_filter_enable { -+ uint32 id; /* Unique filter id */ -+ uint32 enable; /* Enable/disable bool */ -+} wl_pkt_filter_enable_t; -+ -+/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */ -+typedef struct wl_pkt_filter_list { -+ uint32 num; /* Number of installed packet filters */ -+ wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */ -+} wl_pkt_filter_list_t; -+ -+#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) -+ -+/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */ -+typedef struct wl_pkt_filter_stats { -+ uint32 num_pkts_matched; /* # filter matches for specified filter id */ -+ uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */ -+ uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ -+} wl_pkt_filter_stats_t; -+ -+/* Sequential Commands ioctl */ -+typedef struct wl_seq_cmd_ioctl { -+ uint32 cmd; /* common ioctl definition */ -+ uint32 len; /* length of user buffer */ -+} wl_seq_cmd_ioctl_t; -+ -+#define WL_SEQ_CMD_ALIGN_BYTES 4 -+ -+/* These are the set of get IOCTLs that should be allowed when using -+ * IOCTL sequence commands. These are issued implicitly by wl.exe each time -+ * it is invoked. We never want to buffer these, or else wl.exe will stop working. -+ */ -+#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ -+ (((cmd) == WLC_GET_MAGIC) || \ -+ ((cmd) == WLC_GET_VERSION) || \ -+ ((cmd) == WLC_GET_AP) || \ -+ ((cmd) == WLC_GET_INSTANCE)) -+ -+/* -+ * Packet engine interface -+ */ -+ -+#define WL_PKTENG_PER_TX_START 0x01 -+#define WL_PKTENG_PER_TX_STOP 0x02 -+#define WL_PKTENG_PER_RX_START 0x04 -+#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -+#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -+#define WL_PKTENG_PER_RX_STOP 0x08 -+#define WL_PKTENG_PER_MASK 0xff -+ -+#define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */ -+ -+typedef struct wl_pkteng { -+ uint32 flags; -+ uint32 delay; /* Inter-packet delay */ -+ uint32 nframes; /* Number of frames */ -+ uint32 length; /* Packet length */ -+ uint8 seqno; /* Enable/disable sequence no. */ -+ struct ether_addr dest; /* Destination address */ -+ struct ether_addr src; /* Source address */ -+} wl_pkteng_t; -+ -+#define NUM_80211b_RATES 4 -+#define NUM_80211ag_RATES 8 -+#define NUM_80211n_RATES 32 -+#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) -+typedef struct wl_pkteng_stats { -+ uint32 lostfrmcnt; /* RX PER test: no of frames lost (skip seqno) */ -+ int32 rssi; /* RSSI */ -+ int32 snr; /* signal to noise ratio */ -+ uint16 rxpktcnt[NUM_80211_RATES+1]; -+} wl_pkteng_stats_t; -+ -+ -+#define WL_WOWL_MAGIC (1 << 0) /* Wakeup on Magic packet */ -+#define WL_WOWL_NET (1 << 1) /* Wakeup on Netpattern */ -+#define WL_WOWL_DIS (1 << 2) /* Wakeup on loss-of-link due to Disassoc/Deauth */ -+#define WL_WOWL_RETR (1 << 3) /* Wakeup on retrograde TSF */ -+#define WL_WOWL_BCN (1 << 4) /* Wakeup on loss of beacon */ -+#define WL_WOWL_TST (1 << 5) /* Wakeup after test */ -+#define WL_WOWL_M1 (1 << 6) /* Wakeup after PTK refresh */ -+#define WL_WOWL_EAPID (1 << 7) /* Wakeup after receipt of EAP-Identity Req */ -+#define WL_WOWL_PME_GPIO (1 << 8) /* Wakeind via PME(0) or GPIO(1) */ -+#define WL_WOWL_NEEDTKIP1 (1 << 9) /* need tkip phase 1 key to be updated by the driver */ -+#define WL_WOWL_GTK_FAILURE (1 << 10) /* enable wakeup if GTK fails */ -+#define WL_WOWL_EXTMAGPAT (1 << 11) /* support extended magic packets */ -+#define WL_WOWL_ARPOFFLOAD (1 << 12) /* support ARP/NS/keepalive offloading */ -+#define WL_WOWL_WPA2 (1 << 13) /* read protocol version for EAPOL frames */ -+#define WL_WOWL_KEYROT (1 << 14) /* If the bit is set, use key rotaton */ -+#define WL_WOWL_BCAST (1 << 15) /* If the bit is set, frm received was bcast frame */ -+ -+#define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */ -+ -+#define WOWL_PATTEN_TYPE_ARP (1 << 0) /* ARP offload Pattern */ -+#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */ -+ -+typedef struct { -+ uint32 masksize; /* Size of the mask in #of bytes */ -+ uint32 offset; /* Offset to start looking for the packet in # of bytes */ -+ uint32 patternoffset; /* Offset of start of pattern in the structure */ -+ uint32 patternsize; /* Size of the pattern itself in #of bytes */ -+ uint32 id; /* id */ -+ uint32 reasonsize; /* Size of the wakeup reason code */ -+ uint32 flags; /* Flags to tell the pattern type and other properties */ -+ /* Mask follows the structure above */ -+ /* Pattern follows the mask is at 'patternoffset' from the start */ -+} wl_wowl_pattern_t; -+ -+typedef struct { -+ uint count; -+ wl_wowl_pattern_t pattern[1]; -+} wl_wowl_pattern_list_t; -+ -+typedef struct { -+ uint8 pci_wakeind; /* Whether PCI PMECSR PMEStatus bit was set */ -+ uint16 ucode_wakeind; /* What wakeup-event indication was set by ucode */ -+} wl_wowl_wakeind_t; -+ -+ -+/* per AC rate control related data structure */ -+typedef struct wl_txrate_class { -+ uint8 init_rate; -+ uint8 min_rate; -+ uint8 max_rate; -+} wl_txrate_class_t; -+ -+ -+ -+/* Overlap BSS Scan parameters default, minimum, maximum */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 /* unit TU */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 /* unit Sec */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 /* unit Sec */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 /* unit Sec */ -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 /* unit percent */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 /* unit percent */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 /* unit percent */ -+ -+/* structure for Overlap BSS scan arguments */ -+typedef struct wl_obss_scan_arg { -+ int16 passive_dwell; -+ int16 active_dwell; -+ int16 bss_widthscan_interval; -+ int16 passive_total; -+ int16 active_total; -+ int16 chanwidth_transition_delay; -+ int16 activity_threshold; -+} wl_obss_scan_arg_t; -+ -+#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -+#define WL_MIN_NUM_OBSS_SCAN_ARG 7 /* minimum number of arguments required for OBSS Scan */ -+ -+#define WL_COEX_INFO_MASK 0x07 -+#define WL_COEX_INFO_REQ 0x01 -+#define WL_COEX_40MHZ_INTOLERANT 0x02 -+#define WL_COEX_WIDTH20 0x04 -+ -+#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ -+ -+#define MAX_RSSI_LEVELS 8 -+ -+/* RSSI event notification configuration. */ -+typedef struct wl_rssi_event { -+ uint32 rate_limit_msec; /* # of events posted to application will be limited to -+ * one per specified period (0 to disable rate limit). -+ */ -+ uint8 num_rssi_levels; /* Number of entries in rssi_levels[] below */ -+ int8 rssi_levels[MAX_RSSI_LEVELS]; /* Variable number of RSSI levels. An event -+ * will be posted each time the RSSI of received -+ * beacons/packets crosses a level. -+ */ -+} wl_rssi_event_t; -+ -+typedef struct wl_action_obss_coex_req { -+ uint8 info; -+ uint8 num; -+ uint8 ch_list[1]; -+} wl_action_obss_coex_req_t; -+ -+ -+/* IOVar parameter block for small MAC address array with type indicator */ -+#define WL_IOV_MAC_PARAM_LEN 4 -+ -+#define WL_IOV_PKTQ_LOG_PRECS 16 -+ -+typedef struct { -+ uint32 num_addrs; -+ char addr_type[WL_IOV_MAC_PARAM_LEN]; -+ struct ether_addr ea[WL_IOV_MAC_PARAM_LEN]; -+} wl_iov_mac_params_t; -+ -+ -+/* Parameter block for PKTQ_LOG statistics */ -+typedef struct { -+ uint32 requested; /* packets requested to be stored */ -+ uint32 stored; /* packets stored */ -+ uint32 saved; /* packets saved, -+ because a lowest priority queue has given away one packet -+ */ -+ uint32 selfsaved; /* packets saved, -+ because an older packet from the same queue has been dropped -+ */ -+ uint32 full_dropped; /* packets dropped, -+ because pktq is full with higher precedence packets -+ */ -+ uint32 dropped; /* packets dropped because pktq per that precedence is full */ -+ uint32 sacrificed; /* packets dropped, -+ in order to save one from a queue of a highest priority -+ */ -+ uint32 busy; /* packets droped because of hardware/transmission error */ -+ uint32 retry; /* packets re-sent because they were not received */ -+ uint32 ps_retry; /* packets retried again prior to moving power save mode */ -+ uint32 retry_drop; /* packets finally dropped after retry limit */ -+ uint32 max_avail; /* the high-water mark of the queue capacity for packets - -+ goes to zero as queue fills -+ */ -+ uint32 max_used; /* the high-water mark of the queue utilisation for packets - -+ increases with use ('inverse' of max_avail) -+ */ -+ uint32 queue_capacity; /* the maximum capacity of the queue */ -+} pktq_log_counters_v01_t; -+ -+#define sacrified sacrificed -+ -+typedef struct { -+ uint8 num_prec[WL_IOV_MAC_PARAM_LEN]; -+ pktq_log_counters_v01_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; -+ char headings[1]; -+} pktq_log_format_v01_t; -+ -+ -+typedef struct { -+ uint32 version; -+ wl_iov_mac_params_t params; -+ union { -+ pktq_log_format_v01_t v01; -+ } pktq_log; -+} wl_iov_pktq_log_t; -+ -+ -+/* **** EXTLOG **** */ -+#define EXTLOG_CUR_VER 0x0100 -+ -+#define MAX_ARGSTR_LEN 18 /* At least big enough for storing ETHER_ADDR_STR_LEN */ -+ -+/* log modules (bitmap) */ -+#define LOG_MODULE_COMMON 0x0001 -+#define LOG_MODULE_ASSOC 0x0002 -+#define LOG_MODULE_EVENT 0x0004 -+#define LOG_MODULE_MAX 3 /* Update when adding module */ -+ -+/* log levels */ -+#define WL_LOG_LEVEL_DISABLE 0 -+#define WL_LOG_LEVEL_ERR 1 -+#define WL_LOG_LEVEL_WARN 2 -+#define WL_LOG_LEVEL_INFO 3 -+#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO /* Update when adding level */ -+ -+/* flag */ -+#define LOG_FLAG_EVENT 1 -+ -+/* log arg_type */ -+#define LOG_ARGTYPE_NULL 0 -+#define LOG_ARGTYPE_STR 1 /* %s */ -+#define LOG_ARGTYPE_INT 2 /* %d */ -+#define LOG_ARGTYPE_INT_STR 3 /* %d...%s */ -+#define LOG_ARGTYPE_STR_INT 4 /* %s...%d */ -+ -+typedef struct wlc_extlog_cfg { -+ int max_number; -+ uint16 module; /* bitmap */ -+ uint8 level; -+ uint8 flag; -+ uint16 version; -+} wlc_extlog_cfg_t; -+ -+typedef struct log_record { -+ uint32 time; -+ uint16 module; -+ uint16 id; -+ uint8 level; -+ uint8 sub_unit; -+ uint8 seq_num; -+ int32 arg; -+ char str[MAX_ARGSTR_LEN]; -+} log_record_t; -+ -+typedef struct wlc_extlog_req { -+ uint32 from_last; -+ uint32 num; -+} wlc_extlog_req_t; -+ -+typedef struct wlc_extlog_results { -+ uint16 version; -+ uint16 record_len; -+ uint32 num; -+ log_record_t logs[1]; -+} wlc_extlog_results_t; -+ -+typedef struct log_idstr { -+ uint16 id; -+ uint16 flag; -+ uint8 arg_type; -+ const char *fmt_str; -+} log_idstr_t; -+ -+#define FMTSTRF_USER 1 -+ -+/* flat ID definitions -+ * New definitions HAVE TO BE ADDED at the end of the table. Otherwise, it will -+ * affect backward compatibility with pre-existing apps -+ */ -+typedef enum { -+ FMTSTR_DRIVER_UP_ID = 0, -+ FMTSTR_DRIVER_DOWN_ID = 1, -+ FMTSTR_SUSPEND_MAC_FAIL_ID = 2, -+ FMTSTR_NO_PROGRESS_ID = 3, -+ FMTSTR_RFDISABLE_ID = 4, -+ FMTSTR_REG_PRINT_ID = 5, -+ FMTSTR_EXPTIME_ID = 6, -+ FMTSTR_JOIN_START_ID = 7, -+ FMTSTR_JOIN_COMPLETE_ID = 8, -+ FMTSTR_NO_NETWORKS_ID = 9, -+ FMTSTR_SECURITY_MISMATCH_ID = 10, -+ FMTSTR_RATE_MISMATCH_ID = 11, -+ FMTSTR_AP_PRUNED_ID = 12, -+ FMTSTR_KEY_INSERTED_ID = 13, -+ FMTSTR_DEAUTH_ID = 14, -+ FMTSTR_DISASSOC_ID = 15, -+ FMTSTR_LINK_UP_ID = 16, -+ FMTSTR_LINK_DOWN_ID = 17, -+ FMTSTR_RADIO_HW_OFF_ID = 18, -+ FMTSTR_RADIO_HW_ON_ID = 19, -+ FMTSTR_EVENT_DESC_ID = 20, -+ FMTSTR_PNP_SET_POWER_ID = 21, -+ FMTSTR_RADIO_SW_OFF_ID = 22, -+ FMTSTR_RADIO_SW_ON_ID = 23, -+ FMTSTR_PWD_MISMATCH_ID = 24, -+ FMTSTR_FATAL_ERROR_ID = 25, -+ FMTSTR_AUTH_FAIL_ID = 26, -+ FMTSTR_ASSOC_FAIL_ID = 27, -+ FMTSTR_IBSS_FAIL_ID = 28, -+ FMTSTR_EXTAP_FAIL_ID = 29, -+ FMTSTR_MAX_ID -+} log_fmtstr_id_t; -+ -+#ifdef DONGLEOVERLAYS -+typedef struct { -+ uint32 flags_idx; /* lower 8 bits: overlay index; upper 24 bits: flags */ -+ uint32 offset; /* offset into overlay region to write code */ -+ uint32 len; /* overlay code len */ -+ /* overlay code follows this struct */ -+} wl_ioctl_overlay_t; -+ -+#define OVERLAY_IDX_MASK 0x000000ff -+#define OVERLAY_IDX_SHIFT 0 -+#define OVERLAY_FLAGS_MASK 0xffffff00 -+#define OVERLAY_FLAGS_SHIFT 8 -+/* overlay written to device memory immediately after loading the base image */ -+#define OVERLAY_FLAG_POSTLOAD 0x100 -+/* defer overlay download until the device responds w/WLC_E_OVL_DOWNLOAD event */ -+#define OVERLAY_FLAG_DEFER_DL 0x200 -+/* overlay downloaded prior to the host going to sleep */ -+#define OVERLAY_FLAG_PRESLEEP 0x400 -+ -+#define OVERLAY_DOWNLOAD_CHUNKSIZE 1024 -+#endif /* DONGLEOVERLAYS */ -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* no default structure packing */ -+#include -+ -+/* require strict packing */ -+#include -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+/* Structures and constants used for "vndr_ie" IOVar interface */ -+#define VNDR_IE_CMD_LEN 4 /* length of the set command string: -+ * "add", "del" (+ NUL) -+ */ -+ -+/* 802.11 Mgmt Packet flags */ -+#define VNDR_IE_BEACON_FLAG 0x1 -+#define VNDR_IE_PRBRSP_FLAG 0x2 -+#define VNDR_IE_ASSOCRSP_FLAG 0x4 -+#define VNDR_IE_AUTHRSP_FLAG 0x8 -+#define VNDR_IE_PRBREQ_FLAG 0x10 -+#define VNDR_IE_ASSOCREQ_FLAG 0x20 -+#define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */ -+#define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */ -+ -+#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ vndr_ie_t vndr_ie_data; /* vendor IE data */ -+} BWL_POST_PACKED_STRUCT vndr_ie_info_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ int iecount; /* number of entries in the vndr_ie_list[] array */ -+ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ -+} BWL_POST_PACKED_STRUCT vndr_ie_buf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NUL */ -+ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ -+} BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t; -+ -+/* tag_ID/length/value_buffer tuple */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 id; -+ uint8 len; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT tlv_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ tlv_t ie_data; /* IE data */ -+} BWL_POST_PACKED_STRUCT ie_info_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ int iecount; /* number of entries in the ie_list[] array */ -+ ie_info_t ie_list[1]; /* variable size list of ie_info_t structs */ -+} BWL_POST_PACKED_STRUCT ie_buf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char cmd[VNDR_IE_CMD_LEN]; /* ie IOVar set command : "add" + NUL */ -+ ie_buf_t ie_buffer; /* buffer containing IE list information */ -+} BWL_POST_PACKED_STRUCT ie_setbuf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ uint8 id; /* IE type */ -+} BWL_POST_PACKED_STRUCT ie_getbuf_t; -+ -+/* structures used to define format of wps ie data from probe requests */ -+/* passed up to applications via iovar "prbreq_wpsie" */ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { -+ struct ether_addr staAddr; -+ uint16 ieLen; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { -+ sta_prbreq_wps_ie_hdr_t hdr; -+ uint8 ieData[1]; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { -+ uint32 totLen; -+ uint8 ieDataList[1]; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; -+ -+ -+#ifdef WLMEDIA_TXFAILEVENT -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char dest[ETHER_ADDR_LEN]; /* destination MAC */ -+ uint8 prio; /* Packet Priority */ -+ uint8 flags; /* Flags */ -+ uint32 tsf_l; /* TSF timer low */ -+ uint32 tsf_h; /* TSF timer high */ -+ uint16 rates; /* Main Rates */ -+ uint16 txstatus; /* TX Status */ -+} BWL_POST_PACKED_STRUCT txfailinfo_t; -+#endif /* WLMEDIA_TXFAILEVENT */ -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* no strict structure packing */ -+#include -+ -+#ifdef BCMWAPI_WAI -+#define IV_LEN 16 /* XXX, same as SMS4_WPI_PN_LEN */ -+struct wapi_sta_msg_t -+{ -+ uint16 msg_type; -+ uint16 datalen; -+ uint8 vap_mac[6]; -+ uint8 reserve_data1[2]; -+ uint8 sta_mac[6]; -+ uint8 reserve_data2[2]; -+ uint8 gsn[IV_LEN]; -+ uint8 wie[256]; -+}; -+#endif /* BCMWAPI_WAI */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* Global ASSERT Logging */ -+#define ASSERTLOG_CUR_VER 0x0100 -+#define MAX_ASSRTSTR_LEN 64 -+ -+typedef struct assert_record { -+ uint32 time; -+ uint8 seq_num; -+ char str[MAX_ASSRTSTR_LEN]; -+} assert_record_t; -+ -+typedef struct assertlog_results { -+ uint16 version; -+ uint16 record_len; -+ uint32 num; -+ assert_record_t logs[1]; -+} assertlog_results_t; -+ -+#define LOGRRC_FIX_LEN 8 -+#define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) -+ -+ -+/* channel interference measurement (chanim) related defines */ -+ -+/* chanim mode */ -+#define CHANIM_DISABLE 0 /* disabled */ -+#define CHANIM_DETECT 1 /* detection only */ -+#define CHANIM_EXT 2 /* external state machine */ -+#define CHANIM_ACT 3 /* full internal state machine, detect + act */ -+#define CHANIM_MODE_MAX 4 -+ -+/* define for apcs reason code */ -+#define APCS_INIT 0 -+#define APCS_IOCTL 1 -+#define APCS_CHANIM 2 -+#define APCS_CSTIMER 3 -+#define APCS_BTA 4 -+ -+/* number of ACS record entries */ -+#define CHANIM_ACS_RECORD 10 -+ -+/* CHANIM */ -+#define CCASTATS_TXDUR 0 -+#define CCASTATS_INBSS 1 -+#define CCASTATS_OBSS 2 -+#define CCASTATS_NOCTG 3 -+#define CCASTATS_NOPKT 4 -+#define CCASTATS_DOZE 5 -+#define CCASTATS_TXOP 6 -+#define CCASTATS_GDTXDUR 7 -+#define CCASTATS_BDTXDUR 8 -+#define CCASTATS_MAX 9 -+ -+/* chanim acs record */ -+typedef struct { -+ bool valid; -+ uint8 trigger; -+ chanspec_t selected_chspc; -+ int8 bgnoise; -+ uint32 glitch_cnt; -+ uint8 ccastats; -+ uint timestamp; -+} chanim_acs_record_t; -+ -+typedef struct { -+ chanim_acs_record_t acs_record[CHANIM_ACS_RECORD]; -+ uint8 count; -+ uint timestamp; -+} wl_acs_record_t; -+ -+typedef struct chanim_stats { -+ uint32 glitchcnt; /* normalized as per second count */ -+ uint32 badplcp; /* normalized as per second count */ -+ uint8 ccastats[CCASTATS_MAX]; /* normalized as 0-255 */ -+ int8 bgnoise; /* background noise level (in dBm) */ -+ chanspec_t chanspec; -+ uint32 timestamp; -+} chanim_stats_t; -+ -+#define WL_CHANIM_STATS_VERSION 1 -+#define WL_CHANIM_COUNT_ALL 0xff -+#define WL_CHANIM_COUNT_ONE 0x1 -+ -+typedef struct { -+ uint32 buflen; -+ uint32 version; -+ uint32 count; -+ chanim_stats_t stats[1]; -+} wl_chanim_stats_t; -+ -+#define WL_CHANIM_STATS_FIXED_LEN OFFSETOF(wl_chanim_stats_t, stats) -+ -+/* Noise measurement metrics. */ -+#define NOISE_MEASURE_KNOISE 0x1 -+ -+/* scb probe parameter */ -+typedef struct { -+ uint32 scb_timeout; -+ uint32 scb_activity_time; -+ uint32 scb_max_probe; -+} wl_scb_probe_t; -+ -+/* ap tpc modes */ -+#define AP_TPC_OFF 0 -+#define AP_TPC_BSS_PWR 1 /* BSS power control */ -+#define AP_TPC_AP_PWR 2 /* AP power control */ -+#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */ -+#define AP_TPC_MAX_LINK_MARGIN 127 -+ -+/* ap tpc modes */ -+#define AP_TPC_OFF 0 -+#define AP_TPC_BSS_PWR 1 /* BSS power control */ -+#define AP_TPC_AP_PWR 2 /* AP power control */ -+#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */ -+#define AP_TPC_MAX_LINK_MARGIN 127 -+ -+/* structure/defines for selective mgmt frame (smf) stats support */ -+ -+#define SMFS_VERSION 1 -+/* selected mgmt frame (smf) stats element */ -+typedef struct wl_smfs_elem { -+ uint32 count; -+ uint16 code; /* SC or RC code */ -+} wl_smfs_elem_t; -+ -+typedef struct wl_smf_stats { -+ uint32 version; -+ uint16 length; /* reserved for future usage */ -+ uint8 type; -+ uint8 codetype; -+ uint32 ignored_cnt; -+ uint32 malformed_cnt; -+ uint32 count_total; /* count included the interested group */ -+ wl_smfs_elem_t elem[1]; -+} wl_smf_stats_t; -+ -+#define WL_SMFSTATS_FIXED_LEN OFFSETOF(wl_smf_stats_t, elem); -+ -+enum { -+ SMFS_CODETYPE_SC, -+ SMFS_CODETYPE_RC -+}; -+ -+/* reuse two number in the sc/rc space */ -+#define SMFS_CODE_MALFORMED 0xFFFE -+#define SMFS_CODE_IGNORED 0xFFFD -+ -+typedef enum smfs_type { -+ SMFS_TYPE_AUTH, -+ SMFS_TYPE_ASSOC, -+ SMFS_TYPE_REASSOC, -+ SMFS_TYPE_DISASSOC_TX, -+ SMFS_TYPE_DISASSOC_RX, -+ SMFS_TYPE_DEAUTH_TX, -+ SMFS_TYPE_DEAUTH_RX, -+ SMFS_TYPE_MAX -+} smfs_type_t; -+ -+#ifdef PHYMON -+ -+#define PHYMON_VERSION 1 -+ -+typedef struct wl_phycal_core_state { -+ /* Tx IQ/LO calibration coeffs */ -+ int16 tx_iqlocal_a; -+ int16 tx_iqlocal_b; -+ int8 tx_iqlocal_ci; -+ int8 tx_iqlocal_cq; -+ int8 tx_iqlocal_di; -+ int8 tx_iqlocal_dq; -+ int8 tx_iqlocal_ei; -+ int8 tx_iqlocal_eq; -+ int8 tx_iqlocal_fi; -+ int8 tx_iqlocal_fq; -+ -+ /* Rx IQ calibration coeffs */ -+ int16 rx_iqcal_a; -+ int16 rx_iqcal_b; -+ -+ uint8 tx_iqlocal_pwridx; /* Tx Power Index for Tx IQ/LO calibration */ -+ uint32 papd_epsilon_table[64]; /* PAPD epsilon table */ -+ int16 papd_epsilon_offset; /* PAPD epsilon offset */ -+ uint8 curr_tx_pwrindex; /* Tx power index */ -+ int8 idle_tssi; /* Idle TSSI */ -+ int8 est_tx_pwr; /* Estimated Tx Power (dB) */ -+ int8 est_rx_pwr; /* Estimated Rx Power (dB) from RSSI */ -+ uint16 rx_gaininfo; /* Rx gain applied on last Rx pkt */ -+ uint16 init_gaincode; /* initgain required for ACI */ -+ int8 estirr_tx; -+ int8 estirr_rx; -+ -+} wl_phycal_core_state_t; -+ -+typedef struct wl_phycal_state { -+ int version; -+ int8 num_phy_cores; /* number of cores */ -+ int8 curr_temperature; /* on-chip temperature sensor reading */ -+ chanspec_t chspec; /* channspec for this state */ -+ bool aci_state; /* ACI state: ON/OFF */ -+ uint16 crsminpower; /* crsminpower required for ACI */ -+ uint16 crsminpowerl; /* crsminpowerl required for ACI */ -+ uint16 crsminpoweru; /* crsminpoweru required for ACI */ -+ wl_phycal_core_state_t phycal_core[1]; -+} wl_phycal_state_t; -+ -+#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core) -+#endif /* PHYMON */ -+ -+/* discovery state */ -+typedef struct wl_p2p_disc_st { -+ uint8 state; /* see state */ -+ chanspec_t chspec; /* valid in listen state */ -+ uint16 dwell; /* valid in listen state, in ms */ -+} wl_p2p_disc_st_t; -+ -+/* state */ -+#define WL_P2P_DISC_ST_SCAN 0 -+#define WL_P2P_DISC_ST_LISTEN 1 -+#define WL_P2P_DISC_ST_SEARCH 2 -+ -+/* scan request */ -+typedef struct wl_p2p_scan { -+ uint8 type; /* 'S' for WLC_SCAN, 'E' for "escan" */ -+ uint8 reserved[3]; -+ /* scan or escan parms... */ -+} wl_p2p_scan_t; -+ -+/* i/f request */ -+typedef struct wl_p2p_if { -+ struct ether_addr addr; -+ uint8 type; /* see i/f type */ -+ chanspec_t chspec; /* for p2p_ifadd GO */ -+} wl_p2p_if_t; -+ -+/* i/f type */ -+#define WL_P2P_IF_CLIENT 0 -+#define WL_P2P_IF_GO 1 -+#define WL_P2P_IF_DYNBCN_GO 2 -+#define WL_P2P_IF_DEV 3 -+ -+/* i/f query */ -+typedef struct wl_p2p_ifq { -+ uint bsscfgidx; -+ char ifname[BCM_MSG_IFNAME_MAX]; -+} wl_p2p_ifq_t; -+ -+/* OppPS & CTWindow */ -+typedef struct wl_p2p_ops { -+ uint8 ops; /* 0: disable 1: enable */ -+ uint8 ctw; /* >= 10 */ -+} wl_p2p_ops_t; -+ -+/* absence and presence request */ -+typedef struct wl_p2p_sched_desc { -+ uint32 start; -+ uint32 interval; -+ uint32 duration; -+ uint32 count; /* see count */ -+} wl_p2p_sched_desc_t; -+ -+/* count */ -+#define WL_P2P_SCHED_RSVD 0 -+#define WL_P2P_SCHED_REPEAT 255 /* anything > 255 will be treated as 255 */ -+ -+typedef struct wl_p2p_sched { -+ uint8 type; /* see schedule type */ -+ uint8 action; /* see schedule action */ -+ uint8 option; /* see schedule option */ -+ wl_p2p_sched_desc_t desc[1]; -+} wl_p2p_sched_t; -+#define WL_P2P_SCHED_FIXED_LEN 3 -+ -+/* schedule type */ -+#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ -+#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ -+ -+/* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */ -+#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ -+#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ -+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ -+#define WL_P2P_SCHED_ACTION_GOOFF 2 /* turn off GO beacon/prbrsp functions */ -+/* schedule option - WL_P2P_SCHED_TYPE_XXX */ -+#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ -+ -+/* schedule option - WL_P2P_SCHED_TYPE_ABS */ -+#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count */ -+#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ -+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ -+#define WL_P2P_SCHED_OPTION_TSFOFS 2 /* normal start/internal/duration/count with -+ * start being an offset of the 'current' TSF -+ */ -+ -+/* feature flags */ -+#define WL_P2P_FEAT_GO_CSA (1 << 0) /* GO moves with the STA using CSA method */ -+#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) /* GO does not probe respond to non-p2p probe -+ * requests -+ */ -+#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) /* Restrict p2p dev interface from responding */ -+ -+#ifdef WLNIC -+/* nic_cnx iovar */ -+typedef struct wl_nic_cnx { -+ uint8 opcode; -+ struct ether_addr addr; -+ /* the following are valid for WL_NIC_CNX_CONN */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct ether_addr abssid; -+ uint8 join_period; -+} wl_nic_cnx_t; -+ -+/* opcode */ -+#define WL_NIC_CNX_ADD 0 /* add NIC connection */ -+#define WL_NIC_CNX_DEL 1 /* delete NIC connection */ -+#define WL_NIC_CNX_IDX 2 /* query NIC connection index */ -+#define WL_NIC_CNX_CONN 3 /* join/create network */ -+#define WL_NIC_CNX_DIS 4 /* disconnect from network */ -+ -+/* nic_cfg iovar */ -+typedef struct wl_nic_cfg { -+ uint8 version; -+ uint8 beacon_mode; -+ uint16 beacon_interval; -+ uint8 diluted_beacon_period; -+ uint8 repeat_EQC; -+ uint8 scan_length; -+ uint8 scan_interval; -+ uint8 scan_probability; -+ uint8 awake_window_length; -+ int8 TSF_correction; -+ uint8 ASID; -+ uint8 channel_usage_mode; -+} wl_nic_cfg_t; -+ -+/* version */ -+#define WL_NIC_CFG_VER 1 -+ -+/* beacon_mode */ -+#define WL_NIC_BCN_NORM 0 -+#define WL_NIC_BCN_DILUTED 1 -+ -+/* channel_usage_mode */ -+#define WL_NIC_CHAN_STATIC 0 -+#define WL_NIC_CHAN_CYCLE 1 -+ -+/* nic_cfg iovar */ -+typedef struct wl_nic_frm { -+ uint8 type; -+ struct ether_addr da; -+ uint8 body[1]; -+} wl_nic_frm_t; -+ -+/* type */ -+#define WL_NIC_FRM_MYNET 1 -+#define WL_NIC_FRM_ACTION 2 -+ -+/* i/f query */ -+typedef struct wl_nic_ifq { -+ uint bsscfgidx; -+ char ifname[BCM_MSG_IFNAME_MAX]; -+} wl_nic_ifq_t; -+ -+/* data mode */ -+/* nic_dm iovar */ -+typedef struct wl_nic_dm { -+ uint8 enab; -+ chanspec_t chspec; -+} wl_nic_dm_t; -+#endif /* WLNIC */ -+ -+/* RFAWARE def */ -+#define BCM_ACTION_RFAWARE 0x77 -+#define BCM_ACTION_RFAWARE_DCS 0x01 -+ -+/* DCS reason code define */ -+#define BCM_DCS_IOVAR 0x1 -+#define BCM_DCS_UNKNOWN 0xFF -+ -+typedef struct wl_bcmdcs_data { -+ uint reason; -+ chanspec_t chspec; -+} wl_bcmdcs_data_t; -+ -+/* n-mode support capability */ -+/* 2x2 includes both 1x1 & 2x2 devices -+ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and -+ * control it independently -+ */ -+#define WL_11N_2x2 1 -+#define WL_11N_3x3 3 -+#define WL_11N_4x4 4 -+ -+/* define 11n feature disable flags */ -+#define WLFEATURE_DISABLE_11N 0x00000001 -+#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -+#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -+#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -+#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -+#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -+#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -+#define WLFEATURE_DISABLE_11N_GF 0x00000080 -+ -+/* Proxy STA modes */ -+#define PSTA_MODE_DISABLED 0 -+#define PSTA_MODE_PROXY 1 -+#define PSTA_MODE_REPEATER 2 -+ -+ -+/* NAT configuration */ -+typedef struct { -+ uint32 ipaddr; /* interface ip address */ -+ uint32 ipaddr_mask; /* interface ip address mask */ -+ uint32 ipaddr_gateway; /* gateway ip address */ -+ uint8 mac_gateway[6]; /* gateway mac address */ -+ uint32 ipaddr_dns; /* DNS server ip address, valid only for public if */ -+ uint8 mac_dns[6]; /* DNS server mac address, valid only for public if */ -+ uint8 GUID[38]; /* interface GUID */ -+} nat_if_info_t; -+ -+typedef struct { -+ uint op; /* operation code */ -+ bool pub_if; /* set for public if, clear for private if */ -+ nat_if_info_t if_info; /* interface info */ -+} nat_cfg_t; -+ -+/* op code in nat_cfg */ -+#define NAT_OP_ENABLE 1 /* enable NAT on given interface */ -+#define NAT_OP_DISABLE 2 /* disable NAT on given interface */ -+#define NAT_OP_DISABLE_ALL 3 /* disable NAT on all interfaces */ -+ -+/* NAT state */ -+#define NAT_STATE_ENABLED 1 /* NAT is enabled */ -+#define NAT_STATE_DISABLED 2 /* NAT is disabled */ -+ -+typedef struct { -+ int state; /* NAT state returned */ -+} nat_state_t; -+ -+#ifdef PROP_TXSTATUS -+/* Bit definitions for tlv iovar */ -+/* -+ * enable RSSI signals: -+ * WLFC_CTL_TYPE_RSSI -+ */ -+#define WLFC_FLAGS_RSSI_SIGNALS 0x0001 -+ -+/* enable (if/mac_open, if/mac_close,, mac_add, mac_del) signals: -+ * -+ * WLFC_CTL_TYPE_MAC_OPEN -+ * WLFC_CTL_TYPE_MAC_CLOSE -+ * -+ * WLFC_CTL_TYPE_INTERFACE_OPEN -+ * WLFC_CTL_TYPE_INTERFACE_CLOSE -+ * -+ * WLFC_CTL_TYPE_MACDESC_ADD -+ * WLFC_CTL_TYPE_MACDESC_DEL -+ * -+ */ -+#define WLFC_FLAGS_XONXOFF_SIGNALS 0x0002 -+ -+/* enable (status, fifo_credit, mac_credit) signals -+ * WLFC_CTL_TYPE_MAC_REQUEST_CREDIT -+ * WLFC_CTL_TYPE_TXSTATUS -+ * WLFC_CTL_TYPE_FIFO_CREDITBACK -+ */ -+#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 0x0004 -+ -+#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008 -+#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010 -+#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020 -+#define WLFC_FLAGS_HOST_RXRERODER_ACTIVE 0x0040 -+#endif /* PROP_TXSTATUS */ -+ -+#define BTA_STATE_LOG_SZ 64 -+ -+/* BTAMP Statemachine states */ -+enum { -+ HCIReset = 1, -+ HCIReadLocalAMPInfo, -+ HCIReadLocalAMPASSOC, -+ HCIWriteRemoteAMPASSOC, -+ HCICreatePhysicalLink, -+ HCIAcceptPhysicalLinkRequest, -+ HCIDisconnectPhysicalLink, -+ HCICreateLogicalLink, -+ HCIAcceptLogicalLink, -+ HCIDisconnectLogicalLink, -+ HCILogicalLinkCancel, -+ HCIAmpStateChange, -+ HCIWriteLogicalLinkAcceptTimeout -+}; -+ -+typedef struct flush_txfifo { -+ uint32 txfifobmp; -+ uint32 hwtxfifoflush; -+ struct ether_addr ea; -+} flush_txfifo_t; -+ -+#define CHANNEL_5G_LOW_START 36 /* 5G low (36..48) CDD enable/disable bit mask */ -+#define CHANNEL_5G_MID_START 52 /* 5G mid (52..64) CDD enable/disable bit mask */ -+#define CHANNEL_5G_HIGH_START 100 /* 5G high (100..140) CDD enable/disable bit mask */ -+#define CHANNEL_5G_UPPER_START 149 /* 5G upper (149..161) CDD enable/disable bit mask */ -+ -+enum { -+ SPATIAL_MODE_2G_IDX = 0, -+ SPATIAL_MODE_5G_LOW_IDX, -+ SPATIAL_MODE_5G_MID_IDX, -+ SPATIAL_MODE_5G_HIGH_IDX, -+ SPATIAL_MODE_5G_UPPER_IDX, -+ SPATIAL_MODE_MAX_IDX -+}; -+ -+/* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */ -+typedef struct wl_mempool_stats { -+ int num; /* Number of memory pools */ -+ bcm_mp_stats_t s[1]; /* Variable array of memory pool stats. */ -+} wl_mempool_stats_t; -+ -+ -+/* D0 Coalescing */ -+#define IPV4_ARP_FILTER 0x0001 -+#define IPV4_NETBT_FILTER 0x0002 -+#define IPV4_LLMNR_FILTER 0x0004 -+#define IPV4_SSDP_FILTER 0x0008 -+#define IPV4_WSD_FILTER 0x0010 -+#define IPV6_NETBT_FILTER 0x0200 -+#define IPV6_LLMNR_FILTER 0x0400 -+#define IPV6_SSDP_FILTER 0x0800 -+#define IPV6_WSD_FILTER 0x1000 -+ -+/* Network Offload Engine */ -+#define NWOE_OL_ENABLE 0x00000001 -+ -+typedef struct { -+ uint32 ipaddr; -+ uint32 ipaddr_netmask; -+ uint32 ipaddr_gateway; -+} nwoe_ifconfig_t; -+ -+/* -+ * Traffic management structures/defines. -+ */ -+ -+/* Traffic management bandwidth parameters */ -+#define TRF_MGMT_MAX_PRIORITIES 3 -+ -+#define TRF_MGMT_FLAG_ADD_DSCP 0x0001 /* Add DSCP to IP TOS field */ -+#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Only support traffic clasification */ -+#define TRF_MGMT_FLAG_DISABLE_PRIORITY_TAGGING 0x0004 /* Don't override packet's priority */ -+ -+/* Traffic management priority classes */ -+typedef enum trf_mgmt_priority_class { -+ trf_mgmt_priority_low = 0, /* Maps to 802.1p BO */ -+ trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */ -+ trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */ -+ trf_mgmt_priority_invalid = (trf_mgmt_priority_high + 1) -+} trf_mgmt_priority_class_t; -+ -+/* Traffic management configuration parameters */ -+typedef struct trf_mgmt_config { -+ uint32 trf_mgmt_enabled; /* 0 - disabled, 1 - enabled */ -+ uint32 flags; /* See TRF_MGMT_FLAG_xxx defines */ -+ uint32 host_ip_addr; /* My IP address to determine subnet */ -+ uint32 host_subnet_mask; /* My subnet mask */ -+ uint32 downlink_bandwidth; /* In units of kbps */ -+ uint32 uplink_bandwidth; /* In units of kbps */ -+ uint32 min_tx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; /* Minimum guaranteed tx bandwidth */ -+ uint32 min_rx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; /* Minimum guaranteed rx bandwidth */ -+} trf_mgmt_config_t; -+ -+/* Traffic management filter */ -+typedef struct trf_mgmt_filter { -+ struct ether_addr dst_ether_addr; /* His L2 address */ -+ uint32 dst_ip_addr; /* His IP address */ -+ uint16 dst_port; /* His L4 port */ -+ uint16 src_port; /* My L4 port */ -+ uint16 prot; /* L4 protocol (only TCP or UDP) */ -+ uint16 flags; /* TBD. For now, this must be zero. */ -+ trf_mgmt_priority_class_t priority; /* Priority for filtered packets */ -+} trf_mgmt_filter_t; -+ -+/* Traffic management filter list (variable length) */ -+typedef struct trf_mgmt_filter_list { -+ uint32 num_filters; -+ trf_mgmt_filter_t filter[1]; -+} trf_mgmt_filter_list_t; -+ -+/* Traffic management global info used for all queues */ -+typedef struct trf_mgmt_global_info { -+ uint32 maximum_bytes_per_second; -+ uint32 maximum_bytes_per_sampling_period; -+ uint32 total_bytes_consumed_per_second; -+ uint32 total_bytes_consumed_per_sampling_period; -+ uint32 total_unused_bytes_per_sampling_period; -+} trf_mgmt_global_info_t; -+ -+/* Traffic management shaping info per priority queue */ -+typedef struct trf_mgmt_shaping_info { -+ uint32 gauranteed_bandwidth_percentage; -+ uint32 guaranteed_bytes_per_second; -+ uint32 guaranteed_bytes_per_sampling_period; -+ uint32 num_bytes_produced_per_second; -+ uint32 num_bytes_consumed_per_second; -+ uint32 num_queued_packets; /* Number of packets in queue */ -+ uint32 num_queued_bytes; /* Number of bytes in queue */ -+} trf_mgmt_shaping_info_t; -+ -+/* Traffic management shaping info array */ -+typedef struct trf_mgmt_shaping_info_array { -+ trf_mgmt_global_info_t tx_global_shaping_info; -+ trf_mgmt_shaping_info_t tx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; -+ trf_mgmt_global_info_t rx_global_shaping_info; -+ trf_mgmt_shaping_info_t rx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; -+} trf_mgmt_shaping_info_array_t; -+ -+ -+/* Traffic management statistical counters */ -+typedef struct trf_mgmt_stats { -+ uint32 num_processed_packets; /* Number of packets processed */ -+ uint32 num_processed_bytes; /* Number of bytes processed */ -+ uint32 num_discarded_packets; /* Number of packets discarded from queue */ -+} trf_mgmt_stats_t; -+ -+/* Traffic management statisics array */ -+typedef struct trf_mgmt_stats_array { -+ trf_mgmt_stats_t tx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; -+ trf_mgmt_stats_t rx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; -+} trf_mgmt_stats_array_t; -+ -+typedef struct powersel_params { -+ /* LPC Params exposed via IOVAR */ -+ int32 tp_ratio_thresh; /* Throughput ratio threshold */ -+ uint8 rate_stab_thresh; /* Thresh for rate stability based on nupd */ -+ uint8 pwr_stab_thresh; /* Number of successes before power step down */ -+ uint8 pwr_sel_exp_time; /* Time lapse for expiry of database */ -+} powersel_params_t; -+ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#endif /* _wlioctl_h_ */ -diff --git a/drivers/net/wireless/ap6210/linux_osl.c b/drivers/net/wireless/ap6210/linux_osl.c -new file mode 100644 -index 0000000..d74eee3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/linux_osl.c -@@ -0,0 +1,1138 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: linux_osl.c 373382 2012-12-07 07:59:52Z $ -+ */ -+ -+#define LINUX_PORT -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#include -+ -+#define PCI_CFG_RETRY 10 -+ -+#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognize osh */ -+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ -+ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+#define DHD_SKB_HDRSIZE 336 -+#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE) -+#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE) -+#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE) -+ -+#define STATIC_BUF_MAX_NUM 16 -+#define STATIC_BUF_SIZE (PAGE_SIZE*2) -+#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) -+ -+typedef struct bcm_static_buf { -+ struct semaphore static_sem; -+ unsigned char *buf_ptr; -+ unsigned char buf_use[STATIC_BUF_MAX_NUM]; -+} bcm_static_buf_t; -+ -+static bcm_static_buf_t *bcm_static_buf = 0; -+ -+#define STATIC_PKT_MAX_NUM 8 -+#if defined(ENHANCED_STATIC_BUF) -+#define STATIC_PKT_4PAGE_NUM 1 -+#define DHD_SKB_MAX_BUFSIZE DHD_SKB_4PAGE_BUFSIZE -+#else -+#define STATIC_PKT_4PAGE_NUM 0 -+#define DHD_SKB_MAX_BUFSIZE DHD_SKB_2PAGE_BUFSIZE -+#endif /* ENHANCED_STATIC_BUF */ -+ -+typedef struct bcm_static_pkt { -+ struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM]; -+ struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM]; -+#ifdef ENHANCED_STATIC_BUF -+ struct sk_buff *skb_16k; -+#endif -+ struct semaphore osl_pkt_sem; -+ unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM]; -+} bcm_static_pkt_t; -+ -+static bcm_static_pkt_t *bcm_static_skb = 0; -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ -+typedef struct bcm_mem_link { -+ struct bcm_mem_link *prev; -+ struct bcm_mem_link *next; -+ uint size; -+ int line; -+ void *osh; -+ char file[BCM_MEM_FILENAME_LEN]; -+} bcm_mem_link_t; -+ -+struct osl_info { -+ osl_pubinfo_t pub; -+#ifdef CTFPOOL -+ ctfpool_t *ctfpool; -+#endif /* CTFPOOL */ -+ uint magic; -+ void *pdev; -+ atomic_t malloced; -+ uint failed; -+ uint bustype; -+ bcm_mem_link_t *dbgmem_list; -+ spinlock_t dbgmem_lock; -+ spinlock_t pktalloc_lock; -+}; -+ -+/* PCMCIA attribute space access macros */ -+ -+/* Global ASSERT type flag */ -+uint32 g_assert_type = FALSE; -+ -+static int16 linuxbcmerrormap[] = -+{ 0, /* 0 */ -+ -EINVAL, /* BCME_ERROR */ -+ -EINVAL, /* BCME_BADARG */ -+ -EINVAL, /* BCME_BADOPTION */ -+ -EINVAL, /* BCME_NOTUP */ -+ -EINVAL, /* BCME_NOTDOWN */ -+ -EINVAL, /* BCME_NOTAP */ -+ -EINVAL, /* BCME_NOTSTA */ -+ -EINVAL, /* BCME_BADKEYIDX */ -+ -EINVAL, /* BCME_RADIOOFF */ -+ -EINVAL, /* BCME_NOTBANDLOCKED */ -+ -EINVAL, /* BCME_NOCLK */ -+ -EINVAL, /* BCME_BADRATESET */ -+ -EINVAL, /* BCME_BADBAND */ -+ -E2BIG, /* BCME_BUFTOOSHORT */ -+ -E2BIG, /* BCME_BUFTOOLONG */ -+ -EBUSY, /* BCME_BUSY */ -+ -EINVAL, /* BCME_NOTASSOCIATED */ -+ -EINVAL, /* BCME_BADSSIDLEN */ -+ -EINVAL, /* BCME_OUTOFRANGECHAN */ -+ -EINVAL, /* BCME_BADCHAN */ -+ -EFAULT, /* BCME_BADADDR */ -+ -ENOMEM, /* BCME_NORESOURCE */ -+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ -+ -EMSGSIZE, /* BCME_BADLENGTH */ -+ -EINVAL, /* BCME_NOTREADY */ -+ -EPERM, /* BCME_EPERM */ -+ -ENOMEM, /* BCME_NOMEM */ -+ -EINVAL, /* BCME_ASSOCIATED */ -+ -ERANGE, /* BCME_RANGE */ -+ -EINVAL, /* BCME_NOTFOUND */ -+ -EINVAL, /* BCME_WME_NOT_ENABLED */ -+ -EINVAL, /* BCME_TSPEC_NOTFOUND */ -+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */ -+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ -+ -EIO, /* BCME_SDIO_ERROR */ -+ -ENODEV, /* BCME_DONGLE_DOWN */ -+ -EINVAL, /* BCME_VERSION */ -+ -EIO, /* BCME_TXFAIL */ -+ -EIO, /* BCME_RXFAIL */ -+ -ENODEV, /* BCME_NODEVICE */ -+ -EINVAL, /* BCME_NMODE_DISABLED */ -+ -ENODATA, /* BCME_NONRESIDENT */ -+ -+/* When an new error code is added to bcmutils.h, add os -+ * specific error translation here as well -+ */ -+/* check if BCME_LAST changed since the last time this function was updated */ -+#if BCME_LAST != -42 -+#error "You need to add a OS error translation in the linuxbcmerrormap \ -+ for new error code defined in bcmutils.h" -+#endif -+}; -+ -+/* translate bcmerrors into linux errors */ -+int -+osl_error(int bcmerror) -+{ -+ if (bcmerror > 0) -+ bcmerror = 0; -+ else if (bcmerror < BCME_LAST) -+ bcmerror = BCME_ERROR; -+ -+ /* Array bounds covered by ASSERT in osl_attach */ -+ return linuxbcmerrormap[-bcmerror]; -+} -+ -+extern uint8* dhd_os_prealloc(void *osh, int section, int size); -+ -+osl_t * -+osl_attach(void *pdev, uint bustype, bool pkttag) -+{ -+ osl_t *osh; -+ -+ if (!(osh = kmalloc(sizeof(osl_t), GFP_ATOMIC))) -+ return osh; -+ -+ ASSERT(osh); -+ -+ bzero(osh, sizeof(osl_t)); -+ -+ /* Check that error map has the right number of entries in it */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); -+ -+ osh->magic = OS_HANDLE_MAGIC; -+ atomic_set(&osh->malloced, 0); -+ osh->failed = 0; -+ osh->dbgmem_list = NULL; -+ spin_lock_init(&(osh->dbgmem_lock)); -+ osh->pdev = pdev; -+ osh->pub.pkttag = pkttag; -+ osh->bustype = bustype; -+ -+ switch (bustype) { -+ case PCI_BUS: -+ case SI_BUS: -+ case PCMCIA_BUS: -+ osh->pub.mmbus = TRUE; -+ break; -+ case JTAG_BUS: -+ case SDIO_BUS: -+ case USB_BUS: -+ case SPI_BUS: -+ case RPC_BUS: -+ osh->pub.mmbus = FALSE; -+ break; -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+#if defined(CONFIG_DHD_USE_STATIC_BUF) -+ if (!bcm_static_buf) { -+ if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ -+ STATIC_BUF_TOTAL_LEN))) { -+ AP6210_DEBUG("can not alloc static buf!\n"); -+ } -+ else -+ AP6210_DEBUG("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); -+ -+ -+ sema_init(&bcm_static_buf->static_sem, 1); -+ -+ bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; -+ } -+ -+ if (!bcm_static_skb) { -+ int i; -+ void *skb_buff_ptr = 0; -+ bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); -+ skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); -+ -+ bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)* -+ (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM)); -+ for (i = 0; i < (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM); i++) -+ bcm_static_skb->pkt_use[i] = 0; -+ -+ sema_init(&bcm_static_skb->osl_pkt_sem, 1); -+ } -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ -+ spin_lock_init(&(osh->pktalloc_lock)); -+ -+ return osh; -+} -+ -+void -+osl_detach(osl_t *osh) -+{ -+ if (osh == NULL) -+ return; -+ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (bcm_static_buf) { -+ bcm_static_buf = 0; -+ } -+ if (bcm_static_skb) { -+ bcm_static_skb = 0; -+ } -+#endif -+ -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ kfree(osh); -+} -+ -+static struct sk_buff *osl_alloc_skb(unsigned int len) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) -+ return __dev_alloc_skb(len, GFP_ATOMIC); -+#else -+ return dev_alloc_skb(len); -+#endif -+} -+ -+#ifdef CTFPOOL -+ -+#ifdef CTFPOOL_SPINLOCK -+#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_irqsave(&(ctfpool)->lock, flags) -+#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_irqrestore(&(ctfpool)->lock, flags) -+#else -+#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_bh(&(ctfpool)->lock) -+#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_bh(&(ctfpool)->lock) -+#endif /* CTFPOOL_SPINLOCK */ -+/* -+ * Allocate and add an object to packet pool. -+ */ -+void * -+osl_ctfpool_add(osl_t *osh) -+{ -+ struct sk_buff *skb; -+#ifdef CTFPOOL_SPINLOCK -+ unsigned long flags; -+#endif /* CTFPOOL_SPINLOCK */ -+ -+ if ((osh == NULL) || (osh->ctfpool == NULL)) -+ return NULL; -+ -+ CTFPOOL_LOCK(osh->ctfpool, flags); -+ ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); -+ -+ /* No need to allocate more objects */ -+ if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ return NULL; -+ } -+ -+ /* Allocate a new skb and add it to the ctfpool */ -+ skb = osl_alloc_skb(osh->ctfpool->obj_size); -+ if (skb == NULL) { -+ AP6210_DEBUG("%s: skb alloc of len %d failed\n", __FUNCTION__, -+ osh->ctfpool->obj_size); -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ return NULL; -+ } -+ -+ /* Add to ctfpool */ -+ skb->next = (struct sk_buff *)osh->ctfpool->head; -+ osh->ctfpool->head = skb; -+ osh->ctfpool->fast_frees++; -+ osh->ctfpool->curr_obj++; -+ -+ /* Hijack a skb member to store ptr to ctfpool */ -+ CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; -+ -+ /* Use bit flag to indicate skb from fast ctfpool */ -+ PKTFAST(osh, skb) = FASTBUF; -+ -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ -+ return skb; -+} -+ -+/* -+ * Add new objects to the pool. -+ */ -+void -+osl_ctfpool_replenish(osl_t *osh, uint thresh) -+{ -+ if ((osh == NULL) || (osh->ctfpool == NULL)) -+ return; -+ -+ /* Do nothing if no refills are required */ -+ while ((osh->ctfpool->refills > 0) && (thresh--)) { -+ osl_ctfpool_add(osh); -+ osh->ctfpool->refills--; -+ } -+} -+ -+/* -+ * Initialize the packet pool with specified number of objects. -+ */ -+int32 -+osl_ctfpool_init(osl_t *osh, uint numobj, uint size) -+{ -+ osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC); -+ ASSERT(osh->ctfpool); -+ bzero(osh->ctfpool, sizeof(ctfpool_t)); -+ -+ osh->ctfpool->max_obj = numobj; -+ osh->ctfpool->obj_size = size; -+ -+ spin_lock_init(&osh->ctfpool->lock); -+ -+ while (numobj--) { -+ if (!osl_ctfpool_add(osh)) -+ return -1; -+ osh->ctfpool->fast_frees--; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Cleanup the packet pool objects. -+ */ -+void -+osl_ctfpool_cleanup(osl_t *osh) -+{ -+ struct sk_buff *skb, *nskb; -+#ifdef CTFPOOL_SPINLOCK -+ unsigned long flags; -+#endif /* CTFPOOL_SPINLOCK */ -+ -+ if ((osh == NULL) || (osh->ctfpool == NULL)) -+ return; -+ -+ CTFPOOL_LOCK(osh->ctfpool, flags); -+ -+ skb = osh->ctfpool->head; -+ -+ while (skb != NULL) { -+ nskb = skb->next; -+ dev_kfree_skb(skb); -+ skb = nskb; -+ osh->ctfpool->curr_obj--; -+ } -+ -+ ASSERT(osh->ctfpool->curr_obj == 0); -+ osh->ctfpool->head = NULL; -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ -+ kfree(osh->ctfpool); -+ osh->ctfpool = NULL; -+} -+ -+void -+osl_ctfpool_stats(osl_t *osh, void *b) -+{ -+ struct bcmstrbuf *bb; -+ -+ if ((osh == NULL) || (osh->ctfpool == NULL)) -+ return; -+ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (bcm_static_buf) { -+ bcm_static_buf = 0; -+ } -+ if (bcm_static_skb) { -+ bcm_static_skb = 0; -+ } -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ -+ bb = b; -+ -+ ASSERT((osh != NULL) && (bb != NULL)); -+ -+ bcm_bprintf(bb, "max_obj %d obj_size %d curr_obj %d refills %d\n", -+ osh->ctfpool->max_obj, osh->ctfpool->obj_size, -+ osh->ctfpool->curr_obj, osh->ctfpool->refills); -+ bcm_bprintf(bb, "fast_allocs %d fast_frees %d slow_allocs %d\n", -+ osh->ctfpool->fast_allocs, osh->ctfpool->fast_frees, -+ osh->ctfpool->slow_allocs); -+} -+ -+static inline struct sk_buff * -+osl_pktfastget(osl_t *osh, uint len) -+{ -+ struct sk_buff *skb; -+#ifdef CTFPOOL_SPINLOCK -+ unsigned long flags; -+#endif /* CTFPOOL_SPINLOCK */ -+ -+ /* Try to do fast allocate. Return null if ctfpool is not in use -+ * or if there are no items in the ctfpool. -+ */ -+ if (osh->ctfpool == NULL) -+ return NULL; -+ -+ CTFPOOL_LOCK(osh->ctfpool, flags); -+ if (osh->ctfpool->head == NULL) { -+ ASSERT(osh->ctfpool->curr_obj == 0); -+ osh->ctfpool->slow_allocs++; -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ return NULL; -+ } -+ -+ ASSERT(len <= osh->ctfpool->obj_size); -+ -+ /* Get an object from ctfpool */ -+ skb = (struct sk_buff *)osh->ctfpool->head; -+ osh->ctfpool->head = (void *)skb->next; -+ -+ osh->ctfpool->fast_allocs++; -+ osh->ctfpool->curr_obj--; -+ ASSERT(CTFPOOLHEAD(osh, skb) == (struct sock *)osh->ctfpool->head); -+ CTFPOOL_UNLOCK(osh->ctfpool, flags); -+ -+ /* Init skb struct */ -+ skb->next = skb->prev = NULL; -+ skb->data = skb->head + 16; -+ skb->tail = skb->head + 16; -+ -+ skb->len = 0; -+ skb->cloned = 0; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) -+ skb->list = NULL; -+#endif -+ atomic_set(&skb->users, 1); -+ -+ return skb; -+} -+#endif /* CTFPOOL */ -+/* Convert a driver packet to native(OS) packet -+ * In the process, packettag is zeroed out before sending up -+ * IP code depends on skb->cb to be setup correctly with various options -+ * In our case, that means it should be 0 -+ */ -+struct sk_buff * BCMFASTPATH -+osl_pkt_tonative(osl_t *osh, void *pkt) -+{ -+#ifndef WL_UMK -+ struct sk_buff *nskb; -+ unsigned long flags; -+#endif -+ -+ if (osh->pub.pkttag) -+ bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); -+ -+#ifndef WL_UMK -+ /* Decrement the packet counter */ -+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { -+ spin_lock_irqsave(&osh->pktalloc_lock, flags); -+ osh->pub.pktalloced--; -+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags); -+ } -+#endif /* WL_UMK */ -+ return (struct sk_buff *)pkt; -+} -+ -+/* Convert a native(OS) packet to driver packet. -+ * In the process, native packet is destroyed, there is no copying -+ * Also, a packettag is zeroed out -+ */ -+void * BCMFASTPATH -+osl_pkt_frmnative(osl_t *osh, void *pkt) -+{ -+#ifndef WL_UMK -+ struct sk_buff *nskb; -+ unsigned long flags; -+#endif -+ -+ if (osh->pub.pkttag) -+ bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); -+ -+#ifndef WL_UMK -+ /* Increment the packet counter */ -+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { -+ spin_lock_irqsave(&osh->pktalloc_lock, flags); -+ osh->pub.pktalloced++; -+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags); -+ } -+#endif /* WL_UMK */ -+ return (void *)pkt; -+} -+ -+/* Return a new packet. zero out pkttag */ -+void * BCMFASTPATH -+osl_pktget(osl_t *osh, uint len) -+{ -+ struct sk_buff *skb; -+ unsigned long flags; -+ -+#ifdef CTFPOOL -+ /* Allocate from local pool */ -+ skb = osl_pktfastget(osh, len); -+ if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { -+#else /* CTFPOOL */ -+ if ((skb = osl_alloc_skb(len))) { -+#endif /* CTFPOOL */ -+ skb_put(skb, len); -+ skb->priority = 0; -+ -+ -+ spin_lock_irqsave(&osh->pktalloc_lock, flags); -+ osh->pub.pktalloced++; -+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags); -+ } -+ -+ return ((void*) skb); -+} -+ -+#ifdef CTFPOOL -+static inline void -+osl_pktfastfree(osl_t *osh, struct sk_buff *skb) -+{ -+ ctfpool_t *ctfpool; -+#ifdef CTFPOOL_SPINLOCK -+ unsigned long flags; -+#endif /* CTFPOOL_SPINLOCK */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -+ skb->tstamp.tv.sec = 0; -+#else -+ skb->stamp.tv_sec = 0; -+#endif -+ -+ /* We only need to init the fields that we change */ -+ skb->dev = NULL; -+ skb->dst = NULL; -+ memset(skb->cb, 0, sizeof(skb->cb)); -+ skb->ip_summed = 0; -+ skb->destructor = NULL; -+ -+ ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); -+ ASSERT(ctfpool != NULL); -+ -+ /* Add object to the ctfpool */ -+ CTFPOOL_LOCK(ctfpool, flags); -+ skb->next = (struct sk_buff *)ctfpool->head; -+ ctfpool->head = (void *)skb; -+ -+ ctfpool->fast_frees++; -+ ctfpool->curr_obj++; -+ -+ ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); -+ CTFPOOL_UNLOCK(ctfpool, flags); -+} -+#endif /* CTFPOOL */ -+ -+/* Free the driver packet. Free the tag if present */ -+void BCMFASTPATH -+osl_pktfree(osl_t *osh, void *p, bool send) -+{ -+ struct sk_buff *skb, *nskb; -+ unsigned long flags; -+ -+ skb = (struct sk_buff*) p; -+ -+ if (send && osh->pub.tx_fn) -+ osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); -+ -+ PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE); -+ -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ -+ -+ -+#ifdef CTFPOOL -+ if ((PKTISFAST(osh, skb)) && (atomic_read(&skb->users) == 1)) -+ osl_pktfastfree(osh, skb); -+ else { -+#else /* CTFPOOL */ -+ { -+#endif /* CTFPOOL */ -+ -+ if (skb->destructor) -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if -+ * destructor exists -+ */ -+ dev_kfree_skb_any(skb); -+ else -+ /* can free immediately (even in_irq()) if destructor -+ * does not exist -+ */ -+ dev_kfree_skb(skb); -+ } -+ spin_lock_irqsave(&osh->pktalloc_lock, flags); -+ osh->pub.pktalloced--; -+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags); -+ skb = nskb; -+ } -+} -+ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+void* -+osl_pktget_static(osl_t *osh, uint len) -+{ -+ int i = 0; -+ struct sk_buff *skb; -+ -+ -+ if (len > DHD_SKB_MAX_BUFSIZE) { -+ AP6210_DEBUG("osl_pktget_static: Do we really need this big skb??" -+ " len=%d\n", len); -+ return osl_pktget(osh, len); -+ } -+ -+ down(&bcm_static_skb->osl_pkt_sem); -+ -+ if (len <= DHD_SKB_1PAGE_BUFSIZE) { -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (bcm_static_skb->pkt_use[i] == 0) -+ break; -+ } -+ -+ if (i != STATIC_PKT_MAX_NUM) { -+ bcm_static_skb->pkt_use[i] = 1; -+ -+ skb = bcm_static_skb->skb_4k[i]; -+ skb->tail = skb->data + len; -+ skb->len = len; -+ -+ up(&bcm_static_skb->osl_pkt_sem); -+ return skb; -+ } -+ } -+ -+ if (len <= DHD_SKB_2PAGE_BUFSIZE) { -+ -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] -+ == 0) -+ break; -+ } -+ -+ if (i != STATIC_PKT_MAX_NUM) { -+ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 1; -+ skb = bcm_static_skb->skb_8k[i]; -+ skb->tail = skb->data + len; -+ skb->len = len; -+ -+ up(&bcm_static_skb->osl_pkt_sem); -+ return skb; -+ } -+ } -+ -+#if defined(ENHANCED_STATIC_BUF) -+ if (bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] == 0) { -+ bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] = 1; -+ -+ skb = bcm_static_skb->skb_16k; -+ skb->tail = skb->data + len; -+ skb->len = len; -+ -+ up(&bcm_static_skb->osl_pkt_sem); -+ return skb; -+ } -+#endif -+ -+ up(&bcm_static_skb->osl_pkt_sem); -+ AP6210_DEBUG("osl_pktget_static: all static pkt in use!\n"); -+ return osl_pktget(osh, len); -+} -+ -+void -+osl_pktfree_static(osl_t *osh, void *p, bool send) -+{ -+ int i; -+ if (!bcm_static_skb) { -+ osl_pktfree(osh, p, send); -+ return; -+ } -+ -+ down(&bcm_static_skb->osl_pkt_sem); -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (p == bcm_static_skb->skb_4k[i]) { -+ bcm_static_skb->pkt_use[i] = 0; -+ up(&bcm_static_skb->osl_pkt_sem); -+ return; -+ } -+ } -+ -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (p == bcm_static_skb->skb_8k[i]) { -+ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; -+ up(&bcm_static_skb->osl_pkt_sem); -+ return; -+ } -+ } -+#ifdef ENHANCED_STATIC_BUF -+ if (p == bcm_static_skb->skb_16k) { -+ bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM*2] = 0; -+ up(&bcm_static_skb->osl_pkt_sem); -+ return; -+ } -+#endif -+ up(&bcm_static_skb->osl_pkt_sem); -+ -+ osl_pktfree(osh, p, send); -+ return; -+} -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ -+uint32 -+osl_pci_read_config(osl_t *osh, uint offset, uint size) -+{ -+ uint val = 0; -+ uint retry = PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_read_config_dword(osh->pdev, offset, &val); -+ if (val != 0xffffffff) -+ break; -+ } while (retry--); -+ -+ -+ return (val); -+} -+ -+void -+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) -+{ -+ uint retry = PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_write_config_dword(osh->pdev, offset, val); -+ if (offset != PCI_BAR0_WIN) -+ break; -+ if (osl_pci_read_config(osh, offset, size) == val) -+ break; -+ } while (retry--); -+ -+} -+ -+/* return bus # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_bus(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return ((struct pci_dev *)osh->pdev)->bus->number; -+} -+ -+/* return slot # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_slot(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -+} -+ -+/* return the pci device pointed by osh->pdev */ -+struct pci_dev * -+osl_pci_device(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return osh->pdev; -+} -+ -+static void -+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -+{ -+} -+ -+void -+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -+} -+ -+void -+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -+} -+ -+void * -+osl_malloc(osl_t *osh, uint size) -+{ -+ void *addr; -+ -+ /* only ASSERT if osh is defined */ -+ if (osh) -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (bcm_static_buf) -+ { -+ int i = 0; -+ if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) -+ { -+ down(&bcm_static_buf->static_sem); -+ -+ for (i = 0; i < STATIC_BUF_MAX_NUM; i++) -+ { -+ if (bcm_static_buf->buf_use[i] == 0) -+ break; -+ } -+ -+ if (i == STATIC_BUF_MAX_NUM) -+ { -+ up(&bcm_static_buf->static_sem); -+ AP6210_DEBUG("all static buff in use!\n"); -+ goto original; -+ } -+ -+ bcm_static_buf->buf_use[i] = 1; -+ up(&bcm_static_buf->static_sem); -+ -+ bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); -+ if (osh) -+ atomic_add(size, &osh->malloced); -+ -+ return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); -+ } -+ } -+original: -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ -+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -+ if (osh) -+ osh->failed++; -+ return (NULL); -+ } -+ if (osh) -+ atomic_add(size, &osh->malloced); -+ -+ return (addr); -+} -+ -+void -+osl_mfree(osl_t *osh, void *addr, uint size) -+{ -+#ifdef CONFIG_DHD_USE_STATIC_BUF -+ if (bcm_static_buf) -+ { -+ if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr -+ <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) -+ { -+ int buf_idx = 0; -+ -+ buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; -+ -+ down(&bcm_static_buf->static_sem); -+ bcm_static_buf->buf_use[buf_idx] = 0; -+ up(&bcm_static_buf->static_sem); -+ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ atomic_sub(size, &osh->malloced); -+ } -+ return; -+ } -+ } -+#endif /* CONFIG_DHD_USE_STATIC_BUF */ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ atomic_sub(size, &osh->malloced); -+ } -+ kfree(addr); -+} -+ -+uint -+osl_malloced(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (atomic_read(&osh->malloced)); -+} -+ -+uint -+osl_malloc_failed(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->failed); -+} -+ -+ -+uint -+osl_dma_consistent_align(void) -+{ -+ return (PAGE_SIZE); -+} -+ -+void* -+osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap) -+{ -+ uint16 align = (1 << align_bits); -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) -+ size += align; -+ *alloced = size; -+ -+ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -+} -+ -+void -+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -+} -+ -+uint BCMFASTPATH -+osl_dma_map(osl_t *osh, void *va, uint size, int direction) -+{ -+ int dir; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(osh->pdev, va, size, dir)); -+} -+ -+void BCMFASTPATH -+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -+{ -+ int dir; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); -+} -+ -+#if defined(BCMASSERT_LOG) -+void -+osl_assert(const char *exp, const char *file, int line) -+{ -+ char tempbuf[256]; -+ const char *basename; -+ -+ basename = strrchr(file, '/'); -+ /* skip the '/' */ -+ if (basename) -+ basename++; -+ -+ if (!basename) -+ basename = file; -+ -+ snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n", -+ exp, basename, line); -+ -+ AP6210_DEBUG("%s", tempbuf); -+ -+ -+} -+#endif -+ -+void -+osl_delay(uint usec) -+{ -+ uint d; -+ -+ while (usec > 0) { -+ d = MIN(usec, 1000); -+ udelay(d); -+ usec -= d; -+ } -+} -+ -+ -+/* Clone a packet. -+ * The pkttag contents are NOT cloned. -+ */ -+void * -+osl_pktdup(osl_t *osh, void *skb) -+{ -+ void * p; -+ unsigned long irqflags; -+ -+ /* clear the CTFBUF flag if set and map the rest of the buffer -+ * before cloning. -+ */ -+ PKTCTFMAP(osh, skb); -+ -+ if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) -+ return NULL; -+ -+#ifdef CTFPOOL -+ if (PKTISFAST(osh, skb)) { -+ ctfpool_t *ctfpool; -+ -+ /* if the buffer allocated from ctfpool is cloned then -+ * we can't be sure when it will be freed. since there -+ * is a chance that we will be losing a buffer -+ * from our pool, we increment the refill count for the -+ * object to be alloced later. -+ */ -+ ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); -+ ASSERT(ctfpool != NULL); -+ PKTCLRFAST(osh, p); -+ PKTCLRFAST(osh, skb); -+ ctfpool->refills++; -+ } -+#endif /* CTFPOOL */ -+ -+ /* skb_clone copies skb->cb.. we don't want that */ -+ if (osh->pub.pkttag) -+ bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); -+ -+ /* Increment the packet counter */ -+ spin_lock_irqsave(&osh->pktalloc_lock, irqflags); -+ osh->pub.pktalloced++; -+ spin_unlock_irqrestore(&osh->pktalloc_lock, irqflags); -+ return (p); -+} -+ -+ -+/* -+ * OSLREGOPS specifies the use of osl_XXX routines to be used for register access -+ */ -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ */ -+ -+/* Linux Kernel: File Operations: start */ -+void * -+osl_os_open_image(char *filename) -+{ -+ struct file *fp; -+ -+ fp = filp_open(filename, O_RDONLY, 0); -+ /* -+ * 2.6.11 (FC4) supports filp_open() but later revs don't? -+ * Alternative: -+ * fp = open_namei(AT_FDCWD, filename, O_RD, 0); -+ * ??? -+ */ -+ if (IS_ERR(fp)) -+ fp = NULL; -+ -+ return fp; -+} -+ -+int -+osl_os_get_image_block(char *buf, int len, void *image) -+{ -+ struct file *fp = (struct file *)image; -+ int rdlen; -+ -+ if (!image) -+ return 0; -+ -+ rdlen = kernel_read(fp, fp->f_pos, buf, len); -+ if (rdlen > 0) -+ fp->f_pos += rdlen; -+ -+ return rdlen; -+} -+ -+void -+osl_os_close_image(void *image) -+{ -+ if (image) -+ filp_close((struct file *)image, NULL); -+} -+/* Linux Kernel: File Operations: end */ -diff --git a/drivers/net/wireless/ap6210/sbutils.c b/drivers/net/wireless/ap6210/sbutils.c -new file mode 100644 -index 0000000..89f9eb3 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/sbutils.c -@@ -0,0 +1,1003 @@ -+/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: sbutils.c 310902 2012-01-26 19:45:33Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "siutils_priv.h" -+ -+#include -+ -+ -+/* local prototypes */ -+static uint _sb_coreidx(si_info_t *sii, uint32 sba); -+static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, -+ uint ncores); -+static uint32 _sb_coresba(si_info_t *sii); -+static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); -+ -+#define SET_SBREG(sii, r, mask, val) \ -+ W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val))) -+#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) -+ -+/* sonicsrev */ -+#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -+#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) -+ -+#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr)) -+#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v)) -+#define AND_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v))) -+#define OR_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v))) -+ -+static uint32 -+sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr) -+{ -+ uint8 tmp; -+ uint32 val, intr_val = 0; -+ -+ -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if (PCMCIA(sii)) { -+ INTR_OFF(sii, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); -+ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ -+ } -+ -+ val = R_REG(sii->osh, sbr); -+ -+ if (PCMCIA(sii)) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(sii, intr_val); -+ } -+ -+ return (val); -+} -+ -+static void -+sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) -+{ -+ uint8 tmp; -+ volatile uint32 dummy; -+ uint32 intr_val = 0; -+ -+ -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if (PCMCIA(sii)) { -+ INTR_OFF(sii, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); -+ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ -+ } -+ -+ if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { -+ dummy = R_REG(sii->osh, sbr); -+ BCM_REFERENCE(dummy); -+ W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+ dummy = R_REG(sii->osh, sbr); -+ BCM_REFERENCE(dummy); -+ W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -+ } else -+ W_REG(sii->osh, sbr, v); -+ -+ if (PCMCIA(sii)) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(sii, intr_val); -+ } -+} -+ -+uint -+sb_coreid(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -+} -+ -+uint -+sb_intflag(si_t *sih) -+{ -+ si_info_t *sii; -+ void *corereg; -+ sbconfig_t *sb; -+ uint origidx, intflag, intr_val = 0; -+ -+ sii = SI_INFO(sih); -+ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ corereg = si_setcore(sih, CC_CORE_ID, 0); -+ ASSERT(corereg != NULL); -+ sb = REGS2SB(corereg); -+ intflag = R_SBREG(sii, &sb->sbflagst); -+ sb_setcoreidx(sih, origidx); -+ INTR_RESTORE(sii, intr_val); -+ -+ return intflag; -+} -+ -+uint -+sb_flag(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ return R_SBREG(sii, &sb->sbtpsflag) & SBTPS_NUM0_MASK; -+} -+ -+void -+sb_setint(si_t *sih, int siflag) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ uint32 vec; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ if (siflag == -1) -+ vec = 0; -+ else -+ vec = 1 << siflag; -+ W_SBREG(sii, &sb->sbintvec, vec); -+} -+ -+/* return core index of the core with address 'sba' */ -+static uint -+_sb_coreidx(si_info_t *sii, uint32 sba) -+{ -+ uint i; -+ -+ for (i = 0; i < sii->numcores; i ++) -+ if (sba == sii->coresba[i]) -+ return i; -+ return BADIDX; -+} -+ -+/* return core address of the current core */ -+static uint32 -+_sb_coresba(si_info_t *sii) -+{ -+ uint32 sbaddr; -+ -+ -+ switch (BUSTYPE(sii->pub.bustype)) { -+ case SI_BUS: { -+ sbconfig_t *sb = REGS2SB(sii->curmap); -+ sbaddr = sb_base(R_SBREG(sii, &sb->sbadmatch0)); -+ break; -+ } -+ -+ case PCI_BUS: -+ sbaddr = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); -+ break; -+ -+ case PCMCIA_BUS: { -+ uint8 tmp = 0; -+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); -+ sbaddr = (uint32)tmp << 12; -+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); -+ sbaddr |= (uint32)tmp << 16; -+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); -+ sbaddr |= (uint32)tmp << 24; -+ break; -+ } -+ -+ case SPI_BUS: -+ case SDIO_BUS: -+ sbaddr = (uint32)(uintptr)sii->curmap; -+ break; -+ -+ -+ default: -+ sbaddr = BADCOREADDR; -+ break; -+ } -+ -+ return sbaddr; -+} -+ -+uint -+sb_corevendor(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -+} -+ -+uint -+sb_corerev(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ uint sbidh; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ sbidh = R_SBREG(sii, &sb->sbidhigh); -+ -+ return (SBCOREREV(sbidh)); -+} -+ -+/* set core-specific control flags */ -+void -+sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ ASSERT((val & ~mask) == 0); -+ -+ /* mask and set */ -+ w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | -+ (val << SBTML_SICF_SHIFT); -+ W_SBREG(sii, &sb->sbtmstatelow, w); -+} -+ -+/* set/clear core-specific control flags */ -+uint32 -+sb_core_cflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ ASSERT((val & ~mask) == 0); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) | -+ (val << SBTML_SICF_SHIFT); -+ W_SBREG(sii, &sb->sbtmstatelow, w); -+ } -+ -+ /* return the new value -+ * for write operation, the following readback ensures the completion of write opration. -+ */ -+ return (R_SBREG(sii, &sb->sbtmstatelow) >> SBTML_SICF_SHIFT); -+} -+ -+/* set/clear core-specific status flags */ -+uint32 -+sb_core_sflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SISF_CORE_BITS) == 0); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(sii, &sb->sbtmstatehigh) & ~(mask << SBTMH_SISF_SHIFT)) | -+ (val << SBTMH_SISF_SHIFT); -+ W_SBREG(sii, &sb->sbtmstatehigh, w); -+ } -+ -+ /* return the new value */ -+ return (R_SBREG(sii, &sb->sbtmstatehigh) >> SBTMH_SISF_SHIFT); -+} -+ -+bool -+sb_iscoreup(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ return ((R_SBREG(sii, &sb->sbtmstatelow) & -+ (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) == -+ (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); -+} -+ -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ * -+ * When using the silicon backplane, no fidleing with interrupts or core switches are needed. -+ * -+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers -+ * and (on newer pci cores) chipcommon registers. -+ */ -+uint -+sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ uint origidx = 0; -+ uint32 *r = NULL; -+ uint w; -+ uint intr_val = 0; -+ bool fast = FALSE; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SI_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); -+ -+ if (coreidx >= SI_MAXCORES) -+ return 0; -+ -+ if (BUSTYPE(sii->pub.bustype) == SI_BUS) { -+ /* If internal bus, we can always get at everything */ -+ fast = TRUE; -+ /* map if does not exist */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], -+ SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); -+ } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { -+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ -+ -+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { -+ /* Chipc registers are mapped at 12KB */ -+ -+ fast = TRUE; -+ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); -+ } else if (sii->pub.buscoreidx == coreidx) { -+ /* pci registers are at either in the last 2KB of an 8KB window -+ * or, in pcie and pci rev 13 at 8KB -+ */ -+ fast = TRUE; -+ if (SI_FAST(sii)) -+ r = (uint32 *)((char *)sii->curmap + -+ PCI_16KB0_PCIREGS_OFFSET + regoff); -+ else -+ r = (uint32 *)((char *)sii->curmap + -+ ((regoff >= SBCONFIGOFF) ? -+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + -+ regoff); -+ } -+ } -+ -+ if (!fast) { -+ INTR_OFF(sii, intr_val); -+ -+ /* save current core index */ -+ origidx = si_coreidx(&sii->pub); -+ -+ /* switch core */ -+ r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff); -+ } -+ ASSERT(r != NULL); -+ -+ /* mask and set */ -+ if (mask || val) { -+ if (regoff >= SBCONFIGOFF) { -+ w = (R_SBREG(sii, r) & ~mask) | val; -+ W_SBREG(sii, r, w); -+ } else { -+ w = (R_REG(sii->osh, r) & ~mask) | val; -+ W_REG(sii->osh, r, w); -+ } -+ } -+ -+ /* readback */ -+ if (regoff >= SBCONFIGOFF) -+ w = R_SBREG(sii, r); -+ else { -+ if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) && -+ (coreidx == SI_CC_IDX) && -+ (regoff == OFFSETOF(chipcregs_t, watchdog))) { -+ w = val; -+ } else -+ w = R_REG(sii->osh, r); -+ } -+ -+ if (!fast) { -+ /* restore core index */ -+ if (origidx != coreidx) -+ sb_setcoreidx(&sii->pub, origidx); -+ -+ INTR_RESTORE(sii, intr_val); -+ } -+ -+ return (w); -+} -+ -+/* Scan the enumeration space to find all cores starting from the given -+ * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba' -+ * is the default core address at chip POR time and 'regs' is the virtual -+ * address that the default core is mapped at. 'ncores' is the number of -+ * cores expected on bus 'sbba'. It returns the total number of cores -+ * starting from bus 'sbba', inclusive. -+ */ -+#define SB_MAXBUSES 2 -+static uint -+_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores) -+{ -+ uint next; -+ uint ncc = 0; -+ uint i; -+ -+ if (bus >= SB_MAXBUSES) { -+ AP6210_ERR("_sb_scan: bus 0x%08x at level %d is too deep to scan\n", sbba, bus); -+ return 0; -+ } -+ AP6210_DEBUG("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores); -+ -+ /* Scan all cores on the bus starting from core 0. -+ * Core addresses must be contiguous on each bus. -+ */ -+ for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) { -+ sii->coresba[next] = sbba + (i * SI_CORE_SIZE); -+ -+ /* keep and reuse the initial register mapping */ -+ if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && (sii->coresba[next] == sba)) { -+ AP6210_DEBUG("_sb_scan: reuse mapped regs %p for core %u\n", regs, next); -+ sii->regs[next] = regs; -+ } -+ -+ /* change core to 'next' and read its coreid */ -+ sii->curmap = _sb_setcoreidx(sii, next); -+ sii->curidx = next; -+ -+ sii->coreid[next] = sb_coreid(&sii->pub); -+ -+ /* core specific processing... */ -+ /* chipc provides # cores */ -+ if (sii->coreid[next] == CC_CORE_ID) { -+ chipcregs_t *cc = (chipcregs_t *)sii->curmap; -+ uint32 ccrev = sb_corerev(&sii->pub); -+ -+ /* determine numcores - this is the total # cores in the chip */ -+ if (((ccrev == 4) || (ccrev >= 6))) -+ numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> -+ CID_CC_SHIFT; -+ else { -+ /* Older chips */ -+ uint chip = CHIPID(sii->pub.chip); -+ -+ if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ -+ numcores = 6; -+ else if (chip == BCM4704_CHIP_ID) -+ numcores = 9; -+ else if (chip == BCM5365_CHIP_ID) -+ numcores = 7; -+ else { -+ AP6210_ERR("sb_chip2numcores: unsupported chip 0x%x\n", -+ chip); -+ ASSERT(0); -+ numcores = 1; -+ } -+ } -+ AP6210_DEBUG("_sb_scan: there are %u cores in the chip %s\n", numcores, -+ sii->pub.issim ? "QT" : ""); -+ } -+ /* scan bridged SB(s) and add results to the end of the list */ -+ else if (sii->coreid[next] == OCP_CORE_ID) { -+ sbconfig_t *sb = REGS2SB(sii->curmap); -+ uint32 nsbba = R_SBREG(sii, &sb->sbadmatch1); -+ uint nsbcc; -+ -+ sii->numcores = next + 1; -+ -+ if ((nsbba & 0xfff00000) != SI_ENUM_BASE) -+ continue; -+ nsbba &= 0xfffff000; -+ if (_sb_coreidx(sii, nsbba) != BADIDX) -+ continue; -+ -+ nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16; -+ nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc); -+ if (sbba == SI_ENUM_BASE) -+ numcores -= nsbcc; -+ ncc += nsbcc; -+ } -+ } -+ -+ AP6210_DEBUG("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba); -+ -+ sii->numcores = i + ncc; -+ return sii->numcores; -+} -+ -+/* scan the sb enumerated space to identify all cores */ -+void -+sb_scan(si_t *sih, void *regs, uint devid) -+{ -+ si_info_t *sii; -+ uint32 origsba; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ sii->pub.socirev = (R_SBREG(sii, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; -+ -+ /* Save the current core info and validate it later till we know -+ * for sure what is good and what is bad. -+ */ -+ origsba = _sb_coresba(sii); -+ -+ /* scan all SB(s) starting from SI_ENUM_BASE */ -+ sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1); -+} -+ -+/* -+ * This function changes logical "focus" to the indicated core; -+ * must be called with interrupts off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void * -+sb_setcoreidx(si_t *sih, uint coreidx) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ if (coreidx >= sii->numcores) -+ return (NULL); -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); -+ -+ sii->curmap = _sb_setcoreidx(sii, coreidx); -+ sii->curidx = coreidx; -+ -+ return (sii->curmap); -+} -+ -+/* This function changes the logical "focus" to the indicated core. -+ * Return the current core's virtual address. -+ */ -+static void * -+_sb_setcoreidx(si_info_t *sii, uint coreidx) -+{ -+ uint32 sbaddr = sii->coresba[coreidx]; -+ void *regs; -+ -+ switch (BUSTYPE(sii->pub.bustype)) { -+ case SI_BUS: -+ /* map new one */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(sbaddr, SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ regs = sii->regs[coreidx]; -+ break; -+ -+ case PCI_BUS: -+ /* point bar0 window */ -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, sbaddr); -+ regs = sii->curmap; -+ break; -+ -+ case PCMCIA_BUS: { -+ uint8 tmp = (sbaddr >> 12) & 0x0f; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1); -+ tmp = (sbaddr >> 16) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1); -+ tmp = (sbaddr >> 24) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1); -+ regs = sii->curmap; -+ break; -+ } -+ case SPI_BUS: -+ case SDIO_BUS: -+ /* map new one */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = (void *)(uintptr)sbaddr; -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ regs = sii->regs[coreidx]; -+ break; -+ -+ -+ default: -+ ASSERT(0); -+ regs = NULL; -+ break; -+ } -+ -+ return regs; -+} -+ -+/* Return the address of sbadmatch0/1/2/3 register */ -+static volatile uint32 * -+sb_admatch(si_info_t *sii, uint asidx) -+{ -+ sbconfig_t *sb; -+ volatile uint32 *addrm; -+ -+ sb = REGS2SB(sii->curmap); -+ -+ switch (asidx) { -+ case 0: -+ addrm = &sb->sbadmatch0; -+ break; -+ -+ case 1: -+ addrm = &sb->sbadmatch1; -+ break; -+ -+ case 2: -+ addrm = &sb->sbadmatch2; -+ break; -+ -+ case 3: -+ addrm = &sb->sbadmatch3; -+ break; -+ -+ default: -+ AP6210_ERR("%s: Address space index (%d) out of range\n", __FUNCTION__, asidx); -+ return 0; -+ } -+ -+ return (addrm); -+} -+ -+/* Return the number of address spaces in current core */ -+int -+sb_numaddrspaces(si_t *sih) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ sb = REGS2SB(sii->curmap); -+ -+ /* + 1 because of enumeration space */ -+ return ((R_SBREG(sii, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT) + 1; -+} -+ -+/* Return the address of the nth address space in the current core */ -+uint32 -+sb_addrspace(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ return (sb_base(R_SBREG(sii, sb_admatch(sii, asidx)))); -+} -+ -+/* Return the size of the nth address space in the current core */ -+uint32 -+sb_addrspacesize(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx)))); -+} -+ -+ -+/* do buffered registers update */ -+void -+sb_commit(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ -+ sii = SI_INFO(sih); -+ -+ origidx = sii->curidx; -+ ASSERT(GOODIDX(origidx)); -+ -+ INTR_OFF(sii, intr_val); -+ -+ /* switch over to chipcommon core if there is one, else use pci */ -+ if (sii->pub.ccrev != NOREV) { -+ chipcregs_t *ccregs = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ ASSERT(ccregs != NULL); -+ -+ /* do the buffer registers update */ -+ W_REG(sii->osh, &ccregs->broadcastaddress, SB_COMMIT); -+ W_REG(sii->osh, &ccregs->broadcastdata, 0x0); -+ } else -+ ASSERT(0); -+ -+ /* restore core index */ -+ sb_setcoreidx(sih, origidx); -+ INTR_RESTORE(sii, intr_val); -+} -+ -+void -+sb_core_disable(si_t *sih, uint32 bits) -+{ -+ si_info_t *sii; -+ volatile uint32 dummy; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curmap)); -+ sb = REGS2SB(sii->curmap); -+ -+ /* if core is already in reset, just return */ -+ if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET) -+ return; -+ -+ /* if clocks are not enabled, put into reset and return */ -+ if ((R_SBREG(sii, &sb->sbtmstatelow) & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0) -+ goto disable; -+ -+ /* set target reject and spin until busy is clear (preserve core-specific bits) */ -+ OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); -+ dummy = R_SBREG(sii, &sb->sbtmstatelow); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); -+ if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) -+ AP6210_ERR("%s: target state still busy\n", __FUNCTION__); -+ -+ if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { -+ OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); -+ dummy = R_SBREG(sii, &sb->sbimstate); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); -+ } -+ -+ /* set reset and reject while enabling the clocks */ -+ W_SBREG(sii, &sb->sbtmstatelow, -+ (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | -+ SBTML_REJ | SBTML_RESET)); -+ dummy = R_SBREG(sii, &sb->sbtmstatelow); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(10); -+ -+ /* don't forget to clear the initiator reject bit */ -+ if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) -+ AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ); -+ -+disable: -+ /* leave reset and reject asserted */ -+ W_SBREG(sii, &sb->sbtmstatelow, ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); -+ OSL_DELAY(1); -+} -+ -+/* reset and re-enable a core -+ * inputs: -+ * bits - core specific bits that are set during and after reset sequence -+ * resetbits - core specific bits that are set only during reset sequence -+ */ -+void -+sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -+{ -+ si_info_t *sii; -+ sbconfig_t *sb; -+ volatile uint32 dummy; -+ -+ sii = SI_INFO(sih); -+ ASSERT(GOODREGS(sii->curmap)); -+ sb = REGS2SB(sii->curmap); -+ -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ sb_core_disable(sih, (bits | resetbits)); -+ -+ /* -+ * Now do the initialization sequence. -+ */ -+ -+ /* set reset while enabling the clock and forcing them on throughout the core */ -+ W_SBREG(sii, &sb->sbtmstatelow, -+ (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | -+ SBTML_RESET)); -+ dummy = R_SBREG(sii, &sb->sbtmstatelow); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ -+ if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) { -+ W_SBREG(sii, &sb->sbtmstatehigh, 0); -+ } -+ if ((dummy = R_SBREG(sii, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { -+ AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); -+ } -+ -+ /* clear reset and allow it to propagate throughout the core */ -+ W_SBREG(sii, &sb->sbtmstatelow, -+ ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); -+ dummy = R_SBREG(sii, &sb->sbtmstatelow); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ -+ /* leave clock enabled */ -+ W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); -+ dummy = R_SBREG(sii, &sb->sbtmstatelow); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+} -+ -+/* -+ * Set the initiator timeout for the "master core". -+ * The master core is defined to be the core in control -+ * of the chip and so it issues accesses to non-memory -+ * locations (Because of dma *any* core can access memeory). -+ * -+ * The routine uses the bus to decide who is the master: -+ * SI_BUS => mips -+ * JTAG_BUS => chipc -+ * PCI_BUS => pci or pcie -+ * PCMCIA_BUS => pcmcia -+ * SDIO_BUS => pcmcia -+ * -+ * This routine exists so callers can disable initiator -+ * timeouts so accesses to very slow devices like otp -+ * won't cause an abort. The routine allows arbitrary -+ * settings of the service and request timeouts, though. -+ * -+ * Returns the timeout state before changing it or -1 -+ * on error. -+ */ -+ -+#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) -+ -+uint32 -+sb_set_initiator_to(si_t *sih, uint32 to, uint idx) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ uint32 tmp, ret = 0xffffffff; -+ sbconfig_t *sb; -+ -+ sii = SI_INFO(sih); -+ -+ if ((to & ~TO_MASK) != 0) -+ return ret; -+ -+ /* Figure out the master core */ -+ if (idx == BADIDX) { -+ switch (BUSTYPE(sii->pub.bustype)) { -+ case PCI_BUS: -+ idx = sii->pub.buscoreidx; -+ break; -+ case JTAG_BUS: -+ idx = SI_CC_IDX; -+ break; -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0); -+ break; -+ case SI_BUS: -+ idx = si_findcoreidx(sih, MIPS33_CORE_ID, 0); -+ break; -+ default: -+ ASSERT(0); -+ } -+ if (idx == BADIDX) -+ return ret; -+ } -+ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ sb = REGS2SB(sb_setcoreidx(sih, idx)); -+ -+ tmp = R_SBREG(sii, &sb->sbimconfiglow); -+ ret = tmp & TO_MASK; -+ W_SBREG(sii, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); -+ -+ sb_commit(sih); -+ sb_setcoreidx(sih, origidx); -+ INTR_RESTORE(sii, intr_val); -+ return ret; -+} -+ -+uint32 -+sb_base(uint32 admatch) -+{ -+ uint32 base; -+ uint type; -+ -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); -+ -+ base = 0; -+ -+ if (type == 0) { -+ base = admatch & SBAM_BASE0_MASK; -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE1_MASK; -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE2_MASK; -+ } -+ -+ return (base); -+} -+ -+uint32 -+sb_size(uint32 admatch) -+{ -+ uint32 size; -+ uint type; -+ -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); -+ -+ size = 0; -+ -+ if (type == 0) { -+ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); -+ } -+ -+ return (size); -+} -diff --git a/drivers/net/wireless/ap6210/siutils.c b/drivers/net/wireless/ap6210/siutils.c -new file mode 100644 -index 0000000..f917c41 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/siutils.c -@@ -0,0 +1,2472 @@ -+/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: siutils.c 347632 2012-07-27 11:00:35Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "siutils_priv.h" -+ -+#include -+ -+/* local prototypes */ -+static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz); -+static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); -+static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, -+ uint *origidx, void *regs); -+ -+ -+ -+/* global variable to indicate reservation/release of gpio's */ -+static uint32 si_gpioreservation = 0; -+ -+/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ -+ -+int do_4360_pcie2_war = 0; -+ -+/* -+ * Allocate a si handle. -+ * devid - pci device id (used to determine chip#) -+ * osh - opaque OS handle -+ * regs - virtual address of initial core registers -+ * bustype - pci/pcmcia/sb/sdio/etc -+ * vars - pointer to a pointer area for "environment" variables -+ * varsz - pointer to int to return the size of the vars -+ */ -+si_t * -+si_attach(uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz) -+{ -+ si_info_t *sii; -+ -+ /* alloc si_info_t */ -+ if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { -+ AP6210_ERR("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)); -+ return (NULL); -+ } -+ -+ if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { -+ MFREE(osh, sii, sizeof(si_info_t)); -+ return (NULL); -+ } -+ sii->vars = vars ? *vars : NULL; -+ sii->varsz = varsz ? *varsz : 0; -+ -+ return (si_t *)sii; -+} -+ -+/* global kernel resource */ -+static si_info_t ksii; -+ -+static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */ -+ -+/* generic kernel variant of si_attach() */ -+si_t * -+si_kattach(osl_t *osh) -+{ -+ static bool ksii_attached = FALSE; -+ -+ if (!ksii_attached) { -+ void *regs = NULL; -+ regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); -+ -+ if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, -+ SI_BUS, NULL, -+ osh != SI_OSH ? &ksii.vars : NULL, -+ osh != SI_OSH ? &ksii.varsz : NULL) == NULL) { -+ AP6210_ERR("si_kattach: si_doattach failed\n"); -+ REG_UNMAP(regs); -+ return NULL; -+ } -+ REG_UNMAP(regs); -+ -+ /* save ticks normalized to ms for si_watchdog_ms() */ -+ if (PMUCTL_ENAB(&ksii.pub)) { -+ /* based on 32KHz ILP clock */ -+ wd_msticks = 32; -+ } else { -+ wd_msticks = ALP_CLOCK / 1000; -+ } -+ -+ ksii_attached = TRUE; -+ AP6210_DEBUG("si_kattach done. ccrev = %d, wd_msticks = %d\n", -+ ksii.pub.ccrev, wd_msticks); -+ } -+ -+ return &ksii.pub; -+} -+ -+ -+static bool -+si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) -+{ -+ /* need to set memseg flag for CF card first before any sb registers access */ -+ if (BUSTYPE(bustype) == PCMCIA_BUS) -+ sii->memseg = TRUE; -+ -+ -+ if (BUSTYPE(bustype) == SDIO_BUS) { -+ int err; -+ uint8 clkset; -+ -+ /* Try forcing SDIO core to do ALPAvail request only */ -+ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); -+ if (!err) { -+ uint8 clkval; -+ -+ /* If register supported, wait for ALPAvail and then force ALP */ -+ clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); -+ if ((clkval & ~SBSDIO_AVBITS) == clkset) { -+ SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, -+ SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), -+ PMU_MAX_TRANSITION_DLY); -+ if (!SBSDIO_ALPAV(clkval)) { -+ AP6210_ERR("timeout on ALPAV wait, clkval 0x%02x\n", -+ clkval); -+ return FALSE; -+ } -+ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, -+ clkset, &err); -+ OSL_DELAY(65); -+ } -+ } -+ -+ /* Also, disable the extra SDIO pull-ups */ -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); -+ } -+ -+ -+ return TRUE; -+} -+ -+static bool -+si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, -+ uint *origidx, void *regs) -+{ -+ bool pci, pcie, pcie_gen2 = FALSE; -+ uint i; -+ uint pciidx, pcieidx, pcirev, pcierev; -+ -+ cc = si_setcoreidx(&sii->pub, SI_CC_IDX); -+ ASSERT((uintptr)cc); -+ -+ /* get chipcommon rev */ -+ sii->pub.ccrev = (int)si_corerev(&sii->pub); -+ -+ /* get chipcommon chipstatus */ -+ if (sii->pub.ccrev >= 11) -+ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); -+ -+ /* get chipcommon capabilites */ -+ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); -+ /* get chipcommon extended capabilities */ -+ -+ if (sii->pub.ccrev >= 35) -+ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); -+ -+ /* get pmu rev and caps */ -+ if (sii->pub.cccaps & CC_CAP_PMU) { -+ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); -+ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; -+ } -+ -+ AP6210_DEBUG("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", -+ sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, -+ sii->pub.pmucaps); -+ -+ /* figure out bus/orignal core idx */ -+ sii->pub.buscoretype = NODEV_CORE_ID; -+ sii->pub.buscorerev = (uint)NOREV; -+ sii->pub.buscoreidx = BADIDX; -+ -+ pci = pcie = FALSE; -+ pcirev = pcierev = (uint)NOREV; -+ pciidx = pcieidx = BADIDX; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ uint cid, crev; -+ -+ si_setcoreidx(&sii->pub, i); -+ cid = si_coreid(&sii->pub); -+ crev = si_corerev(&sii->pub); -+ -+ /* Display cores found */ -+ AP6210_DEBUG("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", -+ i, cid, crev, sii->coresba[i], sii->regs[i]); -+ -+ if (BUSTYPE(bustype) == PCI_BUS) { -+ if (cid == PCI_CORE_ID) { -+ pciidx = i; -+ pcirev = crev; -+ pci = TRUE; -+ } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) { -+ pcieidx = i; -+ pcierev = crev; -+ pcie = TRUE; -+ if (cid == PCIE2_CORE_ID) -+ pcie_gen2 = TRUE; -+ } -+ } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && -+ (cid == PCMCIA_CORE_ID)) { -+ sii->pub.buscorerev = crev; -+ sii->pub.buscoretype = cid; -+ sii->pub.buscoreidx = i; -+ } -+ else if (((BUSTYPE(bustype) == SDIO_BUS) || -+ (BUSTYPE(bustype) == SPI_BUS)) && -+ ((cid == PCMCIA_CORE_ID) || -+ (cid == SDIOD_CORE_ID))) { -+ sii->pub.buscorerev = crev; -+ sii->pub.buscoretype = cid; -+ sii->pub.buscoreidx = i; -+ } -+ -+ /* find the core idx before entering this func. */ -+ if ((savewin && (savewin == sii->coresba[i])) || -+ (regs == sii->regs[i])) -+ *origidx = i; -+ } -+ -+ if (pci) { -+ sii->pub.buscoretype = PCI_CORE_ID; -+ sii->pub.buscorerev = pcirev; -+ sii->pub.buscoreidx = pciidx; -+ } else if (pcie) { -+ if (pcie_gen2) -+ sii->pub.buscoretype = PCIE2_CORE_ID; -+ else -+ sii->pub.buscoretype = PCIE_CORE_ID; -+ sii->pub.buscorerev = pcierev; -+ sii->pub.buscoreidx = pcieidx; -+ } -+ -+ AP6210_DEBUG("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, -+ sii->pub.buscorerev); -+ -+ if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) && -+ (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3)) -+ OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL); -+ -+ -+ /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was -+ * already running. -+ */ -+ if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) { -+ if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || -+ si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) -+ si_core_disable(&sii->pub, 0); -+ } -+ -+ /* return to the original core */ -+ si_setcoreidx(&sii->pub, *origidx); -+ -+ return TRUE; -+} -+ -+ -+ -+ -+static si_info_t * -+si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz) -+{ -+ struct si_pub *sih = &sii->pub; -+ uint32 w, savewin; -+ chipcregs_t *cc; -+ char *pvars = NULL; -+ uint origidx; -+ -+ ASSERT(GOODREGS(regs)); -+ -+ bzero((uchar*)sii, sizeof(si_info_t)); -+ -+ savewin = 0; -+ -+ sih->buscoreidx = BADIDX; -+ -+ sii->curmap = regs; -+ sii->sdh = sdh; -+ sii->osh = osh; -+ -+ -+ -+ /* find Chipcommon address */ -+ if (bustype == PCI_BUS) { -+ savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); -+ if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) -+ savewin = SI_ENUM_BASE; -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); -+ if (!regs) -+ return NULL; -+ cc = (chipcregs_t *)regs; -+ } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { -+ cc = (chipcregs_t *)sii->curmap; -+ } else { -+ cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); -+ } -+ -+ sih->bustype = bustype; -+ if (bustype != BUSTYPE(bustype)) { -+ AP6210_ERR("si_doattach: bus type %d does not match configured bus type %d\n", -+ bustype, BUSTYPE(bustype)); -+ return NULL; -+ } -+ -+ /* bus/core/clk setup for register access */ -+ if (!si_buscore_prep(sii, bustype, devid, sdh)) { -+ AP6210_ERR("si_doattach: si_core_clk_prep failed %d\n", bustype); -+ return NULL; -+ } -+ -+ /* ChipID recognition. -+ * We assume we can read chipid at offset 0 from the regs arg. -+ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), -+ * some way of recognizing them needs to be added here. -+ */ -+ if (!cc) { -+ AP6210_ERR("%s: chipcommon register space is null \n", __FUNCTION__); -+ return NULL; -+ } -+ w = R_REG(osh, &cc->chipid); -+ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; -+ /* Might as wll fill in chip id rev & pkg */ -+ sih->chip = w & CID_ID_MASK; -+ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; -+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ -+#if defined(HW_OOB) -+ bcmsdh_config_hw_oob_intr(sdh, sih->chip); -+#endif -+ -+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) && -+ (sih->chippkg != BCM4329_289PIN_PKG_ID)) { -+ sih->chippkg = BCM4329_182PIN_PKG_ID; -+ } -+ sih->issim = IS_SIM(sih->chippkg); -+ -+ /* scan for cores */ -+ if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { -+ AP6210_DEBUG("Found chip type SB (0x%08x)\n", w); -+ sb_scan(&sii->pub, regs, devid); -+ } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { -+ AP6210_DEBUG("Found chip type AI (0x%08x)\n", w); -+ /* pass chipc address instead of original core base */ -+ ai_scan(&sii->pub, (void *)(uintptr)cc, devid); -+ } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) { -+ AP6210_DEBUG("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip); -+ /* pass chipc address instead of original core base */ -+ ub_scan(&sii->pub, (void *)(uintptr)cc, devid); -+ } else { -+ AP6210_ERR("Found chip of unknown type (0x%08x)\n", w); -+ return NULL; -+ } -+ /* no cores found, bail out */ -+ if (sii->numcores == 0) { -+ AP6210_ERR("si_doattach: could not find any cores\n"); -+ return NULL; -+ } -+ /* bus/core/clk setup */ -+ origidx = SI_CC_IDX; -+ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { -+ AP6210_ERR("si_doattach: si_buscore_setup failed\n"); -+ goto exit; -+ } -+ -+ if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) -+ >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT | -+ CST4322_SPROM_PRESENT))) { -+ AP6210_ERR("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__); -+ return NULL; -+ } -+ -+ /* assume current core is CC */ -+ if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID || -+ CHIPID(sih->chip) == BCM43235_CHIP_ID || -+ CHIPID(sih->chip) == BCM43234_CHIP_ID || -+ CHIPID(sih->chip) == BCM43238_CHIP_ID) && -+ (CHIPREV(sii->pub.chiprev) <= 2))) { -+ -+ if ((cc->chipstatus & CST43236_BP_CLK) != 0) { -+ uint clkdiv; -+ clkdiv = R_REG(osh, &cc->clkdiv); -+ /* otp_clk_div is even number, 120/14 < 9mhz */ -+ clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); -+ W_REG(osh, &cc->clkdiv, clkdiv); -+ AP6210_ERR("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv); -+ } -+ OSL_DELAY(10); -+ } -+ -+ if (bustype == PCI_BUS) { -+ -+ } -+ -+ pvars = NULL; -+ BCM_REFERENCE(pvars); -+ -+ -+ -+ if (sii->pub.ccrev >= 20) { -+ uint32 gpiopullup = 0, gpiopulldown = 0; -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ ASSERT(cc != NULL); -+ -+ /* 4314/43142 has pin muxing, don't clear gpio bits */ -+ if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) || -+ (CHIPID(sih->chip) == BCM43142_CHIP_ID)) { -+ gpiopullup |= 0x402e0; -+ gpiopulldown |= 0x20500; -+ } -+ -+ W_REG(osh, &cc->gpiopullup, gpiopullup); -+ W_REG(osh, &cc->gpiopulldown, gpiopulldown); -+ si_setcoreidx(sih, origidx); -+ } -+ -+ -+ /* clear any previous epidiag-induced target abort */ -+ ASSERT(!si_taclear(sih, FALSE)); -+ -+ return (sii); -+ -+exit: -+ -+ return NULL; -+} -+ -+/* may be called with core in reset */ -+void -+si_detach(si_t *sih) -+{ -+ si_info_t *sii; -+ uint idx; -+ -+ -+ sii = SI_INFO(sih); -+ -+ if (sii == NULL) -+ return; -+ -+ if (BUSTYPE(sih->bustype) == SI_BUS) -+ for (idx = 0; idx < SI_MAXCORES; idx++) -+ if (sii->regs[idx]) { -+ REG_UNMAP(sii->regs[idx]); -+ sii->regs[idx] = NULL; -+ } -+ -+ -+ -+#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) -+ if (sii != &ksii) -+#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ -+ MFREE(sii->osh, sii, sizeof(si_info_t)); -+} -+ -+void * -+si_osh(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->osh; -+} -+ -+void -+si_setosh(si_t *sih, osl_t *osh) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ if (sii->osh != NULL) { -+ AP6210_ERR("osh is already set....\n"); -+ ASSERT(!sii->osh); -+ } -+ sii->osh = osh; -+} -+ -+/* register driver interrupt disabling and restoring callback functions */ -+void -+si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, -+ void *intrsenabled_fn, void *intr_arg) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ sii->intr_arg = intr_arg; -+ sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn; -+ sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn; -+ sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn; -+ /* save current core id. when this function called, the current core -+ * must be the core which provides driver functions(il, et, wl, etc.) -+ */ -+ sii->dev_coreid = sii->coreid[sii->curidx]; -+} -+ -+void -+si_deregister_intr_callback(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ sii->intrsoff_fn = NULL; -+} -+ -+uint -+si_intflag(si_t *sih) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_intflag(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return R_REG(sii->osh, ((uint32 *)(uintptr) -+ (sii->oob_router + OOB_STATUSA))); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+uint -+si_flag(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_flag(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_flag(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_flag(sih); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+void -+si_setint(si_t *sih, int siflag) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ sb_setint(sih, siflag); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ ai_setint(sih, siflag); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ ub_setint(sih, siflag); -+ else -+ ASSERT(0); -+} -+ -+uint -+si_coreid(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->coreid[sii->curidx]; -+} -+ -+uint -+si_coreidx(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->curidx; -+} -+ -+/* return the core-type instantiation # of the current core */ -+uint -+si_coreunit(si_t *sih) -+{ -+ si_info_t *sii; -+ uint idx; -+ uint coreid; -+ uint coreunit; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ coreunit = 0; -+ -+ idx = sii->curidx; -+ -+ ASSERT(GOODREGS(sii->curmap)); -+ coreid = si_coreid(sih); -+ -+ /* count the cores of our type */ -+ for (i = 0; i < idx; i++) -+ if (sii->coreid[i] == coreid) -+ coreunit++; -+ -+ return (coreunit); -+} -+ -+uint -+si_corevendor(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_corevendor(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_corevendor(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_corevendor(sih); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+bool -+si_backplane64(si_t *sih) -+{ -+ return ((sih->cccaps & CC_CAP_BKPLN64) != 0); -+} -+ -+uint -+si_corerev(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_corerev(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_corerev(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_corerev(sih); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+/* return index of coreid or BADIDX if not found */ -+uint -+si_findcoreidx(si_t *sih, uint coreid, uint coreunit) -+{ -+ si_info_t *sii; -+ uint found; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ -+ found = 0; -+ -+ for (i = 0; i < sii->numcores; i++) -+ if (sii->coreid[i] == coreid) { -+ if (found == coreunit) -+ return (i); -+ found++; -+ } -+ -+ return (BADIDX); -+} -+ -+/* return list of found cores */ -+uint -+si_corelist(si_t *sih, uint coreid[]) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); -+ return (sii->numcores); -+} -+ -+/* return current register mapping */ -+void * -+si_coreregs(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ ASSERT(GOODREGS(sii->curmap)); -+ -+ return (sii->curmap); -+} -+ -+/* -+ * This function changes logical "focus" to the indicated core; -+ * must be called with interrupts off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void * -+si_setcore(si_t *sih, uint coreid, uint coreunit) -+{ -+ uint idx; -+ -+ idx = si_findcoreidx(sih, coreid, coreunit); -+ if (!GOODIDX(idx)) -+ return (NULL); -+ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_setcoreidx(sih, idx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_setcoreidx(sih, idx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_setcoreidx(sih, idx); -+ else { -+ ASSERT(0); -+ return NULL; -+ } -+} -+ -+void * -+si_setcoreidx(si_t *sih, uint coreidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_setcoreidx(sih, coreidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_setcoreidx(sih, coreidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_setcoreidx(sih, coreidx); -+ else { -+ ASSERT(0); -+ return NULL; -+ } -+} -+ -+/* Turn off interrupt as required by sb_setcore, before switch core */ -+void * -+si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) -+{ -+ void *cc; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ if (SI_FAST(sii)) { -+ /* Overloading the origidx variable to remember the coreid, -+ * this works because the core ids cannot be confused with -+ * core indices. -+ */ -+ *origidx = coreid; -+ if (coreid == CC_CORE_ID) -+ return (void *)CCREGS_FAST(sii); -+ else if (coreid == sih->buscoretype) -+ return (void *)PCIEREGS(sii); -+ } -+ INTR_OFF(sii, *intr_val); -+ *origidx = sii->curidx; -+ cc = si_setcore(sih, coreid, 0); -+ ASSERT(cc != NULL); -+ -+ return cc; -+} -+ -+/* restore coreidx and restore interrupt */ -+void -+si_restore_core(si_t *sih, uint coreid, uint intr_val) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) -+ return; -+ -+ si_setcoreidx(sih, coreid); -+ INTR_RESTORE(sii, intr_val); -+} -+ -+int -+si_numaddrspaces(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_numaddrspaces(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_numaddrspaces(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_numaddrspaces(sih); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+uint32 -+si_addrspace(si_t *sih, uint asidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_addrspace(sih, asidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_addrspace(sih, asidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_addrspace(sih, asidx); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+uint32 -+si_addrspacesize(si_t *sih, uint asidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_addrspacesize(sih, asidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_addrspacesize(sih, asidx); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_addrspacesize(sih, asidx); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+void -+si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) -+{ -+ /* Only supported for SOCI_AI */ -+ if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ ai_coreaddrspaceX(sih, asidx, addr, size); -+ else -+ *size = 0; -+} -+ -+uint32 -+si_core_cflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_core_cflags(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_core_cflags(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_core_cflags(sih, mask, val); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+void -+si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ sb_core_cflags_wo(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ ai_core_cflags_wo(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ ub_core_cflags_wo(sih, mask, val); -+ else -+ ASSERT(0); -+} -+ -+uint32 -+si_core_sflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_core_sflags(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_core_sflags(sih, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_core_sflags(sih, mask, val); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+bool -+si_iscoreup(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_iscoreup(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_iscoreup(sih); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_iscoreup(sih); -+ else { -+ ASSERT(0); -+ return FALSE; -+ } -+} -+ -+uint -+si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -+{ -+ /* only for AI back plane chips */ -+ if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return (ai_wrap_reg(sih, offset, mask, val)); -+ return 0; -+} -+ -+uint -+si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ return sb_corereg(sih, coreidx, regoff, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ return ai_corereg(sih, coreidx, regoff, mask, val); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ return ub_corereg(sih, coreidx, regoff, mask, val); -+ else { -+ ASSERT(0); -+ return 0; -+ } -+} -+ -+void -+si_core_disable(si_t *sih, uint32 bits) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ sb_core_disable(sih, bits); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ ai_core_disable(sih, bits); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ ub_core_disable(sih, bits); -+} -+ -+void -+si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) -+ sb_core_reset(sih, bits, resetbits); -+ else if (CHIPTYPE(sih->socitype) == SOCI_AI) -+ ai_core_reset(sih, bits, resetbits); -+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) -+ ub_core_reset(sih, bits, resetbits); -+} -+ -+/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ -+int -+si_corebist(si_t *sih) -+{ -+ uint32 cflags; -+ int result = 0; -+ -+ /* Read core control flags */ -+ cflags = si_core_cflags(sih, 0, 0); -+ -+ /* Set bist & fgc */ -+ si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC)); -+ -+ /* Wait for bist done */ -+ SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); -+ -+ if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) -+ result = BCME_ERROR; -+ -+ /* Reset core control flags */ -+ si_core_cflags(sih, 0xffff, cflags); -+ -+ return result; -+} -+ -+static uint32 -+factor6(uint32 x) -+{ -+ switch (x) { -+ case CC_F6_2: return 2; -+ case CC_F6_3: return 3; -+ case CC_F6_4: return 4; -+ case CC_F6_5: return 5; -+ case CC_F6_6: return 6; -+ case CC_F6_7: return 7; -+ default: return 0; -+ } -+} -+ -+/* calculate the speed the SI would run at given a set of clockcontrol values */ -+uint32 -+si_clock_rate(uint32 pll_type, uint32 n, uint32 m) -+{ -+ uint32 n1, n2, clock, m1, m2, m3, mc; -+ -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; -+ -+ if (pll_type == PLL_TYPE6) { -+ if (m & CC_T6_MMASK) -+ return CC_T6_M1; -+ else -+ return CC_T6_M0; -+ } else if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ ASSERT((n1 >= 2) && (n1 <= 7)); -+ ASSERT((n2 >= 5) && (n2 <= 23)); -+ } else if (pll_type == PLL_TYPE5) { -+ return (100000000); -+ } else -+ ASSERT(0); -+ /* PLL types 3 and 7 use BASE2 (25Mhz) */ -+ if ((pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE7)) { -+ clock = CC_CLOCK_BASE2 * n1 * n2; -+ } else -+ clock = CC_CLOCK_BASE1 * n1 * n2; -+ -+ if (clock == 0) -+ return 0; -+ -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ m1 = factor6(m1); -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) -+ m2 += CC_F5_BIAS; -+ else -+ m2 = factor6(m2); -+ m3 = factor6(m3); -+ -+ switch (mc) { -+ case CC_MC_BYPASS: return (clock); -+ case CC_MC_M1: return (clock / m1); -+ case CC_MC_M1M2: return (clock / (m1 * m2)); -+ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); -+ case CC_MC_M1M3: return (clock / (m1 * m3)); -+ default: return (0); -+ } -+ } else { -+ ASSERT(pll_type == PLL_TYPE2); -+ -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ ASSERT((m1 >= 2) && (m1 <= 7)); -+ ASSERT((m2 >= 3) && (m2 <= 10)); -+ ASSERT((m3 >= 2) && (m3 <= 7)); -+ -+ if ((mc & CC_T2MC_M1BYP) == 0) -+ clock /= m1; -+ if ((mc & CC_T2MC_M2BYP) == 0) -+ clock /= m2; -+ if ((mc & CC_T2MC_M3BYP) == 0) -+ clock /= m3; -+ -+ return (clock); -+ } -+} -+ -+ -+/* set chip watchdog reset timer to fire in 'ticks' */ -+void -+si_watchdog(si_t *sih, uint ticks) -+{ -+ uint nb, maxt; -+ -+ if (PMUCTL_ENAB(sih)) { -+ -+ if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && -+ (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { -+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); -+ si_setcore(sih, USB20D_CORE_ID, 0); -+ si_core_disable(sih, 1); -+ si_setcore(sih, CC_CORE_ID, 0); -+ } -+ -+ nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); -+ /* The mips compiler uses the sllv instruction, -+ * so we specially handle the 32-bit case. -+ */ -+ if (nb == 32) -+ maxt = 0xffffffff; -+ else -+ maxt = ((1 << nb) - 1); -+ -+ if (ticks == 1) -+ ticks = 2; -+ else if (ticks > maxt) -+ ticks = maxt; -+ -+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks); -+ } else { -+ maxt = (1 << 28) - 1; -+ if (ticks > maxt) -+ ticks = maxt; -+ -+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); -+ } -+} -+ -+/* trigger watchdog reset after ms milliseconds */ -+void -+si_watchdog_ms(si_t *sih, uint32 ms) -+{ -+ si_watchdog(sih, wd_msticks * ms); -+} -+ -+uint32 si_watchdog_msticks(void) -+{ -+ return wd_msticks; -+} -+ -+bool -+si_taclear(si_t *sih, bool details) -+{ -+ return FALSE; -+} -+ -+ -+ -+/* return the slow clock source - LPO, XTAL, or PCI */ -+static uint -+si_slowclk_src(si_info_t *sii) -+{ -+ chipcregs_t *cc; -+ -+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); -+ -+ if (sii->pub.ccrev < 6) { -+ if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) && -+ (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) & -+ PCI_CFG_GPIO_SCS)) -+ return (SCC_SS_PCI); -+ else -+ return (SCC_SS_XTAL); -+ } else if (sii->pub.ccrev < 10) { -+ cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); -+ return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); -+ } else /* Insta-clock */ -+ return (SCC_SS_XTAL); -+} -+ -+/* return the ILP (slowclock) min or max frequency */ -+static uint -+si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) -+{ -+ uint32 slowclk; -+ uint div; -+ -+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); -+ -+ /* shouldn't be here unless we've established the chip has dynamic clk control */ -+ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); -+ -+ slowclk = si_slowclk_src(sii); -+ if (sii->pub.ccrev < 6) { -+ if (slowclk == SCC_SS_PCI) -+ return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64)); -+ else -+ return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32)); -+ } else if (sii->pub.ccrev < 10) { -+ div = 4 * -+ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); -+ if (slowclk == SCC_SS_LPO) -+ return (max_freq ? LPOMAXFREQ : LPOMINFREQ); -+ else if (slowclk == SCC_SS_XTAL) -+ return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div)); -+ else if (slowclk == SCC_SS_PCI) -+ return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div)); -+ else -+ ASSERT(0); -+ } else { -+ /* Chipc rev 10 is InstaClock */ -+ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; -+ div = 4 * (div + 1); -+ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div)); -+ } -+ return (0); -+} -+ -+static void -+si_clkctl_setdelay(si_info_t *sii, void *chipcregs) -+{ -+ chipcregs_t *cc = (chipcregs_t *)chipcregs; -+ uint slowmaxfreq, pll_delay, slowclk; -+ uint pll_on_delay, fref_sel_delay; -+ -+ pll_delay = PLL_DELAY; -+ -+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay -+ * since the xtal will also be powered down by dynamic clk control logic. -+ */ -+ -+ slowclk = si_slowclk_src(sii); -+ if (slowclk != SCC_SS_XTAL) -+ pll_delay += XTAL_ON_DELAY; -+ -+ /* Starting with 4318 it is ILP that is used for the delays */ -+ slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc); -+ -+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; -+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; -+ -+ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); -+ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); -+} -+ -+/* initialize power control delay registers */ -+void -+si_clkctl_init(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx = 0; -+ chipcregs_t *cc; -+ bool fast; -+ -+ if (!CCCTL_ENAB(sih)) -+ return; -+ -+ sii = SI_INFO(sih); -+ fast = SI_FAST(sii); -+ if (!fast) { -+ origidx = sii->curidx; -+ if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) -+ return; -+ } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) -+ return; -+ ASSERT(cc != NULL); -+ -+ /* set all Instaclk chip ILP to 1 MHz */ -+ if (sih->ccrev >= 10) -+ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, -+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); -+ -+ si_clkctl_setdelay(sii, (void *)(uintptr)cc); -+ -+ if (!fast) -+ si_setcoreidx(sih, origidx); -+} -+ -+ -+/* change logical "focus" to the gpio core for optimized access */ -+void * -+si_gpiosetcore(si_t *sih) -+{ -+ return (si_setcoreidx(sih, SI_CC_IDX)); -+} -+ -+/* -+ * mask & set gpiocontrol bits. -+ * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin. -+ * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated -+ * to some chip-specific purpose. -+ */ -+uint32 -+si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ regoff = 0; -+ -+ /* gpios could be shared on router platforms -+ * ignore reservation if it's high priority (e.g., test apps) -+ */ -+ if ((priority != GPIO_HI_PRIORITY) && -+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpiocontrol); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* mask&set gpio output enable bits */ -+uint32 -+si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ regoff = 0; -+ -+ /* gpios could be shared on router platforms -+ * ignore reservation if it's high priority (e.g., test apps) -+ */ -+ if ((priority != GPIO_HI_PRIORITY) && -+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpioouten); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* mask&set gpio output bits */ -+uint32 -+si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ regoff = 0; -+ -+ /* gpios could be shared on router platforms -+ * ignore reservation if it's high priority (e.g., test apps) -+ */ -+ if ((priority != GPIO_HI_PRIORITY) && -+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpioout); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* reserve one gpio */ -+uint32 -+si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) -+{ -+ /* only cores on SI_BUS share GPIO's and only applcation users need to -+ * reserve/release GPIO -+ */ -+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); -+ return 0xffffffff; -+ } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return 0xffffffff; -+ } -+ -+ /* already reserved */ -+ if (si_gpioreservation & gpio_bitmask) -+ return 0xffffffff; -+ /* set reservation */ -+ si_gpioreservation |= gpio_bitmask; -+ -+ return si_gpioreservation; -+} -+ -+/* release one gpio */ -+/* -+ * releasing the gpio doesn't change the current value on the GPIO last write value -+ * persists till some one overwrites it -+ */ -+ -+uint32 -+si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) -+{ -+ /* only cores on SI_BUS share GPIO's and only applcation users need to -+ * reserve/release GPIO -+ */ -+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); -+ return 0xffffffff; -+ } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return 0xffffffff; -+ } -+ -+ /* already released */ -+ if (!(si_gpioreservation & gpio_bitmask)) -+ return 0xffffffff; -+ -+ /* clear reservation */ -+ si_gpioreservation &= ~gpio_bitmask; -+ -+ return si_gpioreservation; -+} -+ -+/* return the current gpioin register value */ -+uint32 -+si_gpioin(si_t *sih) -+{ -+ uint regoff; -+ -+ regoff = OFFSETOF(chipcregs_t, gpioin); -+ return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); -+} -+ -+/* mask&set gpio interrupt polarity bits */ -+uint32 -+si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* mask&set gpio interrupt mask bits */ -+uint32 -+si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpiointmask); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* assign the gpio to an led */ -+uint32 -+si_gpioled(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (sih->ccrev < 16) -+ return 0xffffffff; -+ -+ /* gpio led powersave reg */ -+ return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); -+} -+ -+/* mask&set gpio timer val */ -+uint32 -+si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) -+{ -+ if (sih->ccrev < 16) -+ return 0xffffffff; -+ -+ return (si_corereg(sih, SI_CC_IDX, -+ OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); -+} -+ -+uint32 -+si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) -+{ -+ uint offs; -+ -+ if (sih->ccrev < 20) -+ return 0xffffffff; -+ -+ offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup)); -+ return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -+} -+ -+uint32 -+si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) -+{ -+ uint offs; -+ -+ if (sih->ccrev < 11) -+ return 0xffffffff; -+ -+ if (regtype == GPIO_REGEVT) -+ offs = OFFSETOF(chipcregs_t, gpioevent); -+ else if (regtype == GPIO_REGEVT_INTMSK) -+ offs = OFFSETOF(chipcregs_t, gpioeventintmask); -+ else if (regtype == GPIO_REGEVT_INTPOL) -+ offs = OFFSETOF(chipcregs_t, gpioeventintpolarity); -+ else -+ return 0xffffffff; -+ -+ return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); -+} -+ -+void * -+si_gpio_handler_register(si_t *sih, uint32 event, -+ bool level, gpio_handler_t cb, void *arg) -+{ -+ si_info_t *sii; -+ gpioh_item_t *gi; -+ -+ ASSERT(event); -+ ASSERT(cb != NULL); -+ -+ sii = SI_INFO(sih); -+ if (sih->ccrev < 11) -+ return NULL; -+ -+ if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL) -+ return NULL; -+ -+ bzero(gi, sizeof(gpioh_item_t)); -+ gi->event = event; -+ gi->handler = cb; -+ gi->arg = arg; -+ gi->level = level; -+ -+ gi->next = sii->gpioh_head; -+ sii->gpioh_head = gi; -+ -+ return (void *)(gi); -+} -+ -+void -+si_gpio_handler_unregister(si_t *sih, void *gpioh) -+{ -+ si_info_t *sii; -+ gpioh_item_t *p, *n; -+ -+ sii = SI_INFO(sih); -+ if (sih->ccrev < 11) -+ return; -+ -+ ASSERT(sii->gpioh_head != NULL); -+ if ((void*)sii->gpioh_head == gpioh) { -+ sii->gpioh_head = sii->gpioh_head->next; -+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); -+ return; -+ } else { -+ p = sii->gpioh_head; -+ n = p->next; -+ while (n) { -+ if ((void*)n == gpioh) { -+ p->next = n->next; -+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); -+ return; -+ } -+ p = n; -+ n = n->next; -+ } -+ } -+ -+ ASSERT(0); /* Not found in list */ -+} -+ -+void -+si_gpio_handler_process(si_t *sih) -+{ -+ si_info_t *sii; -+ gpioh_item_t *h; -+ uint32 level = si_gpioin(sih); -+ uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0); -+ uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0); -+ uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0); -+ -+ sii = SI_INFO(sih); -+ for (h = sii->gpioh_head; h != NULL; h = h->next) { -+ if (h->handler) { -+ uint32 status = (h->level ? level : edge) & h->event; -+ uint32 polarity = (h->level ? levelp : edgep) & h->event; -+ -+ /* polarity bitval is opposite of status bitval */ -+ if (status ^ polarity) -+ h->handler(status, h->arg); -+ } -+ } -+ -+ si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */ -+} -+ -+uint32 -+si_gpio_int_enable(si_t *sih, bool enable) -+{ -+ uint offs; -+ -+ if (sih->ccrev < 11) -+ return 0xffffffff; -+ -+ offs = OFFSETOF(chipcregs_t, intmask); -+ return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0))); -+} -+ -+ -+/* Return the size of the specified SOCRAM bank */ -+static uint -+socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type) -+{ -+ uint banksize, bankinfo; -+ uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); -+ -+ ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); -+ -+ W_REG(sii->osh, ®s->bankidx, bankidx); -+ bankinfo = R_REG(sii->osh, ®s->bankinfo); -+ banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1); -+ return banksize; -+} -+ -+void -+si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ sbsocramregs_t *regs; -+ bool wasup; -+ uint corerev; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ if (!set) -+ *enable = *protect = *remap = 0; -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ -+ corerev = si_corerev(sih); -+ if (corerev >= 10) { -+ uint32 extcinfo; -+ uint8 nb; -+ uint8 i; -+ uint32 bankidx, bankinfo; -+ -+ extcinfo = R_REG(sii->osh, ®s->extracoreinfo); -+ nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); -+ for (i = 0; i < nb; i++) { -+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); -+ W_REG(sii->osh, ®s->bankidx, bankidx); -+ bankinfo = R_REG(sii->osh, ®s->bankinfo); -+ if (set) { -+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK; -+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK; -+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK; -+ if (*enable) { -+ bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT); -+ if (*protect) -+ bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT); -+ if ((corerev >= 16) && *remap) -+ bankinfo |= -+ (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT); -+ } -+ W_REG(sii->osh, ®s->bankinfo, bankinfo); -+ } -+ else if (i == 0) { -+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) { -+ *enable = 1; -+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK) -+ *protect = 1; -+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) -+ *remap = 1; -+ } -+ } -+ } -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+} -+ -+bool -+si_socdevram_remap_isenb(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ sbsocramregs_t *regs; -+ bool wasup, remap = FALSE; -+ uint corerev; -+ uint32 extcinfo; -+ uint8 nb; -+ uint8 i; -+ uint32 bankidx, bankinfo; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ -+ corerev = si_corerev(sih); -+ if (corerev >= 16) { -+ extcinfo = R_REG(sii->osh, ®s->extracoreinfo); -+ nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); -+ for (i = 0; i < nb; i++) { -+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); -+ W_REG(sii->osh, ®s->bankidx, bankidx); -+ bankinfo = R_REG(sii->osh, ®s->bankinfo); -+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { -+ remap = TRUE; -+ break; -+ } -+ } -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ return remap; -+} -+ -+bool -+si_socdevram_pkg(si_t *sih) -+{ -+ if (si_socdevram_size(sih) > 0) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+uint32 -+si_socdevram_size(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ uint32 memsize = 0; -+ sbsocramregs_t *regs; -+ bool wasup; -+ uint corerev; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ -+ corerev = si_corerev(sih); -+ if (corerev >= 10) { -+ uint32 extcinfo; -+ uint8 nb; -+ uint8 i; -+ -+ extcinfo = R_REG(sii->osh, ®s->extracoreinfo); -+ nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); -+ for (i = 0; i < nb; i++) -+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ -+ return memsize; -+} -+ -+uint32 -+si_socdevram_remap_size(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ uint32 memsize = 0, banksz; -+ sbsocramregs_t *regs; -+ bool wasup; -+ uint corerev; -+ uint32 extcinfo; -+ uint8 nb; -+ uint8 i; -+ uint32 bankidx, bankinfo; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ -+ corerev = si_corerev(sih); -+ if (corerev >= 16) { -+ extcinfo = R_REG(sii->osh, ®s->extracoreinfo); -+ nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); -+ -+ /* -+ * FIX: A0 Issue: Max addressable is 512KB, instead 640KB -+ * Only four banks are accessible to ARM -+ */ -+ if ((corerev == 16) && (nb == 5)) -+ nb = 4; -+ -+ for (i = 0; i < nb; i++) { -+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); -+ W_REG(sii->osh, ®s->bankidx, bankidx); -+ bankinfo = R_REG(sii->osh, ®s->bankinfo); -+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { -+ banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); -+ memsize += banksz; -+ } else { -+ /* Account only consecutive banks for now */ -+ break; -+ } -+ } -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ -+ return memsize; -+} -+ -+/* Return the RAM size of the SOCRAM core */ -+uint32 -+si_socram_size(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ -+ sbsocramregs_t *regs; -+ bool wasup; -+ uint corerev; -+ uint32 coreinfo; -+ uint memsize = 0; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ corerev = si_corerev(sih); -+ coreinfo = R_REG(sii->osh, ®s->coreinfo); -+ -+ /* Calculate size from coreinfo based on rev */ -+ if (corerev == 0) -+ memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); -+ else if (corerev < 3) { -+ memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); -+ memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ } else if ((corerev <= 7) || (corerev == 12)) { -+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ uint bsz = (coreinfo & SRCI_SRBSZ_MASK); -+ uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; -+ if (lss != 0) -+ nb --; -+ memsize = nb * (1 << (bsz + SR_BSZ_BASE)); -+ if (lss != 0) -+ memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); -+ } else { -+ uint8 i; -+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ for (i = 0; i < nb; i++) -+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ -+ return memsize; -+} -+ -+ -+/* Return the TCM-RAM size of the ARMCR4 core. */ -+uint32 -+si_tcm_size(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ uint8 *regs; -+ bool wasup; -+ uint32 corecap; -+ uint memsize = 0; -+ uint32 nab = 0; -+ uint32 nbb = 0; -+ uint32 totb = 0; -+ uint32 bxinfo = 0; -+ uint32 idx = 0; -+ uint32 *arm_cap_reg; -+ uint32 *arm_bidx; -+ uint32 *arm_binfo; -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to CR4 core */ -+ if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size. If in reset, come out of reset, -+ * but remain in halt -+ */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT); -+ -+ arm_cap_reg = (uint32 *)(regs + SI_CR4_CAP); -+ corecap = R_REG(sii->osh, arm_cap_reg); -+ -+ nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT; -+ nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT; -+ totb = nab + nbb; -+ -+ arm_bidx = (uint32 *)(regs + SI_CR4_BANKIDX); -+ arm_binfo = (uint32 *)(regs + SI_CR4_BANKINFO); -+ for (idx = 0; idx < totb; idx++) { -+ W_REG(sii->osh, arm_bidx, idx); -+ -+ bxinfo = R_REG(sii->osh, arm_binfo); -+ memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT; -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ -+ return memsize; -+} -+ -+uint32 -+si_socram_srmem_size(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ -+ sbsocramregs_t *regs; -+ bool wasup; -+ uint corerev; -+ uint32 coreinfo; -+ uint memsize = 0; -+ -+ if ((CHIPID(sih->chip) == BCM4334_CHIP_ID) && (CHIPREV(sih->chiprev) < 2)) { -+ return (32 * 1024); -+ } -+ -+ sii = SI_INFO(sih); -+ -+ /* Block ints and save current core */ -+ INTR_OFF(sii, intr_val); -+ origidx = si_coreidx(sih); -+ -+ /* Switch to SOCRAM core */ -+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) -+ goto done; -+ -+ /* Get info for determining size */ -+ if (!(wasup = si_iscoreup(sih))) -+ si_core_reset(sih, 0, 0); -+ corerev = si_corerev(sih); -+ coreinfo = R_REG(sii->osh, ®s->coreinfo); -+ -+ /* Calculate size from coreinfo based on rev */ -+ if (corerev >= 16) { -+ uint8 i; -+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; -+ for (i = 0; i < nb; i++) { -+ W_REG(sii->osh, ®s->bankidx, i); -+ if (R_REG(sii->osh, ®s->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK) -+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); -+ } -+ } -+ -+ /* Return to previous state and core */ -+ if (!wasup) -+ si_core_disable(sih, 0); -+ si_setcoreidx(sih, origidx); -+ -+done: -+ INTR_RESTORE(sii, intr_val); -+ -+ return memsize; -+} -+ -+ -+void -+si_btcgpiowar(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx; -+ uint intr_val = 0; -+ chipcregs_t *cc; -+ -+ sii = SI_INFO(sih); -+ -+ /* Make sure that there is ChipCommon core present && -+ * UART_TX is strapped to 1 -+ */ -+ if (!(sih->cccaps & CC_CAP_UARTGPIO)) -+ return; -+ -+ /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */ -+ INTR_OFF(sii, intr_val); -+ -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ ASSERT(cc != NULL); -+ -+ W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04); -+ -+ /* restore the original index */ -+ si_setcoreidx(sih, origidx); -+ -+ INTR_RESTORE(sii, intr_val); -+} -+ -+void -+si_chipcontrl_btshd0_4331(si_t *sih, bool on) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 val; -+ uint intr_val = 0; -+ -+ sii = SI_INFO(sih); -+ -+ INTR_OFF(sii, intr_val); -+ -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ val = R_REG(sii->osh, &cc->chipcontrol); -+ -+ /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */ -+ if (on) { -+ /* Enable bt_shd0 on gpio4: */ -+ val |= (CCTRL4331_BT_SHD0_ON_GPIO4); -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } else { -+ val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4); -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } -+ -+ /* restore the original index */ -+ si_setcoreidx(sih, origidx); -+ -+ INTR_RESTORE(sii, intr_val); -+} -+ -+void -+si_chipcontrl_restore(si_t *sih, uint32 val) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ si_setcoreidx(sih, origidx); -+} -+ -+uint32 -+si_chipcontrl_read(si_t *sih) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 val; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ val = R_REG(sii->osh, &cc->chipcontrol); -+ si_setcoreidx(sih, origidx); -+ return val; -+} -+ -+void -+si_chipcontrl_epa4331(si_t *sih, bool on) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 val; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ val = R_REG(sii->osh, &cc->chipcontrol); -+ -+ if (on) { -+ if (sih->chippkg == 9 || sih->chippkg == 0xb) { -+ val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); -+ /* Ext PA Controls for 4331 12x9 Package */ -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } else { -+ /* Ext PA Controls for 4331 12x12 Package */ -+ if (sih->chiprev > 0) { -+ W_REG(sii->osh, &cc->chipcontrol, val | -+ (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2)); -+ } else { -+ W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN)); -+ } -+ } -+ } else { -+ val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5); -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } -+ -+ si_setcoreidx(sih, origidx); -+} -+ -+/* switch muxed pins, on: SROM, off: FEMCTRL */ -+void -+si_chipcontrl_srom4360(si_t *sih, bool on) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 val; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ val = R_REG(sii->osh, &cc->chipcontrol); -+ -+ if (on) { -+ val &= ~(CCTRL4360_SECI_MODE | -+ CCTRL4360_BTSWCTRL_MODE | -+ CCTRL4360_EXTRA_FEMCTRL_MODE | -+ CCTRL4360_BT_LGCY_MODE | -+ CCTRL4360_CORE2FEMCTRL4_ON); -+ -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } else { -+ } -+ -+ si_setcoreidx(sih, origidx); -+} -+ -+void -+si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 val; -+ bool sel_chip; -+ -+ sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) || -+ (CHIPID(sih->chip) == BCM43431_CHIP_ID); -+ sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb)); -+ -+ if (!sel_chip) -+ return; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ val = R_REG(sii->osh, &cc->chipcontrol); -+ -+ if (enter_wowl) { -+ val |= CCTRL4331_EXTPA_EN; -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } else { -+ val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); -+ W_REG(sii->osh, &cc->chipcontrol, val); -+ } -+ si_setcoreidx(sih, origidx); -+} -+ -+uint -+si_pll_reset(si_t *sih) -+{ -+ uint err = 0; -+ -+ return (err); -+} -+ -+/* Enable BT-COEX & Ex-PA for 4313 */ -+void -+si_epa_4313war(si_t *sih) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ /* EPA Fix */ -+ W_REG(sii->osh, &cc->gpiocontrol, -+ R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); -+ -+ si_setcoreidx(sih, origidx); -+} -+ -+void -+si_clk_pmu_htavail_set(si_t *sih, bool set_clear) -+{ -+} -+ -+/* WL/BT control for 4313 btcombo boards >= P250 */ -+void -+si_btcombo_p250_4313_war(si_t *sih) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ W_REG(sii->osh, &cc->gpiocontrol, -+ R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK); -+ -+ W_REG(sii->osh, &cc->gpioouten, -+ R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK); -+ -+ si_setcoreidx(sih, origidx); -+} -+void -+si_btc_enable_chipcontrol(si_t *sih) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ /* BT fix */ -+ W_REG(sii->osh, &cc->chipcontrol, -+ R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK); -+ -+ si_setcoreidx(sih, origidx); -+} -+void -+si_btcombo_43228_war(si_t *sih) -+{ -+ si_info_t *sii; -+ chipcregs_t *cc; -+ uint origidx; -+ -+ sii = SI_INFO(sih); -+ origidx = si_coreidx(sih); -+ -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ -+ W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK); -+ W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK); -+ -+ si_setcoreidx(sih, origidx); -+} -+ -+/* check if the device is removed */ -+bool -+si_deviceremoved(si_t *sih) -+{ -+ uint32 w; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case PCI_BUS: -+ ASSERT(sii->osh != NULL); -+ w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32)); -+ if ((w & 0xFFFF) != VENDOR_BROADCOM) -+ return TRUE; -+ break; -+ } -+ return FALSE; -+} -+ -+bool -+si_is_sprom_available(si_t *sih) -+{ -+ if (sih->ccrev >= 31) { -+ si_info_t *sii; -+ uint origidx; -+ chipcregs_t *cc; -+ uint32 sromctrl; -+ -+ if ((sih->cccaps & CC_CAP_SROM) == 0) -+ return FALSE; -+ -+ sii = SI_INFO(sih); -+ origidx = sii->curidx; -+ cc = si_setcoreidx(sih, SI_CC_IDX); -+ sromctrl = R_REG(sii->osh, &cc->sromcontrol); -+ si_setcoreidx(sih, origidx); -+ return (sromctrl & SRC_PRESENT); -+ } -+ -+ switch (CHIPID(sih->chip)) { -+ case BCM4312_CHIP_ID: -+ return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL); -+ case BCM4325_CHIP_ID: -+ return (sih->chipst & CST4325_SPROM_SEL) != 0; -+ case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: -+ case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: -+ case BCM4342_CHIP_ID: { -+ uint32 spromotp; -+ spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> -+ CST4322_SPROM_OTP_SEL_SHIFT; -+ return (spromotp & CST4322_SPROM_PRESENT) != 0; -+ } -+ case BCM4329_CHIP_ID: -+ return (sih->chipst & CST4329_SPROM_SEL) != 0; -+ case BCM4315_CHIP_ID: -+ return (sih->chipst & CST4315_SPROM_SEL) != 0; -+ case BCM4319_CHIP_ID: -+ return (sih->chipst & CST4319_SPROM_SEL) != 0; -+ case BCM4336_CHIP_ID: -+ case BCM43362_CHIP_ID: -+ return (sih->chipst & CST4336_SPROM_PRESENT) != 0; -+ case BCM4330_CHIP_ID: -+ return (sih->chipst & CST4330_SPROM_PRESENT) != 0; -+ case BCM4313_CHIP_ID: -+ return (sih->chipst & CST4313_SPROM_PRESENT) != 0; -+ case BCM4331_CHIP_ID: -+ case BCM43431_CHIP_ID: -+ return (sih->chipst & CST4331_SPROM_PRESENT) != 0; -+ case BCM43239_CHIP_ID: -+ return ((sih->chipst & CST43239_SPROM_MASK) && -+ !(sih->chipst & CST43239_SFLASH_MASK)); -+ case BCM4324_CHIP_ID: -+ return ((sih->chipst & CST4324_SPROM_MASK) && -+ !(sih->chipst & CST4324_SFLASH_MASK)); -+ case BCM4335_CHIP_ID: -+ return ((sih->chipst & CST4335_SPROM_MASK) && -+ !(sih->chipst & CST4335_SFLASH_MASK)); -+ case BCM43131_CHIP_ID: -+ case BCM43217_CHIP_ID: -+ case BCM43227_CHIP_ID: -+ case BCM43228_CHIP_ID: -+ case BCM43428_CHIP_ID: -+ return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT; -+ default: -+ return TRUE; -+ } -+} -+ -+ -+uint32 si_get_sromctl(si_t *sih) -+{ -+ chipcregs_t *cc; -+ uint origidx; -+ uint32 sromctl; -+ osl_t *osh; -+ -+ osh = si_osh(sih); -+ origidx = si_coreidx(sih); -+ cc = si_setcoreidx(sih, SI_CC_IDX); -+ ASSERT((uintptr)cc); -+ -+ sromctl = R_REG(osh, &cc->sromcontrol); -+ -+ /* return to the original core */ -+ si_setcoreidx(sih, origidx); -+ return sromctl; -+} -+ -+int si_set_sromctl(si_t *sih, uint32 value) -+{ -+ chipcregs_t *cc; -+ uint origidx; -+ osl_t *osh; -+ -+ osh = si_osh(sih); -+ origidx = si_coreidx(sih); -+ cc = si_setcoreidx(sih, SI_CC_IDX); -+ ASSERT((uintptr)cc); -+ -+ /* get chipcommon rev */ -+ if (si_corerev(sih) < 32) -+ return BCME_UNSUPPORTED; -+ -+ W_REG(osh, &cc->sromcontrol, value); -+ -+ /* return to the original core */ -+ si_setcoreidx(sih, origidx); -+ return BCME_OK; -+ -+} -diff --git a/drivers/net/wireless/ap6210/siutils_priv.h b/drivers/net/wireless/ap6210/siutils_priv.h -new file mode 100644 -index 0000000..34fc3fa ---- /dev/null -+++ b/drivers/net/wireless/ap6210/siutils_priv.h -@@ -0,0 +1,236 @@ -+/* -+ * Include file private to the SOC Interconnect support files. -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: siutils_priv.h 309193 2012-01-19 00:03:57Z $ -+ */ -+ -+#ifndef _siutils_priv_h_ -+#define _siutils_priv_h_ -+ -+#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) -+ -+typedef uint32 (*si_intrsoff_t)(void *intr_arg); -+typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); -+typedef bool (*si_intrsenabled_t)(void *intr_arg); -+ -+typedef struct gpioh_item { -+ void *arg; -+ bool level; -+ gpio_handler_t handler; -+ uint32 event; -+ struct gpioh_item *next; -+} gpioh_item_t; -+ -+/* misc si info needed by some of the routines */ -+typedef struct si_info { -+ struct si_pub pub; /* back plane public state (must be first field) */ -+ -+ void *osh; /* osl os handle */ -+ void *sdh; /* bcmsdh handle */ -+ -+ uint dev_coreid; /* the core provides driver functions */ -+ void *intr_arg; /* interrupt callback function arg */ -+ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ -+ si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ -+ si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ -+ -+ void *pch; /* PCI/E core handle */ -+ -+ gpioh_item_t *gpioh_head; /* GPIO event handlers list */ -+ -+ bool memseg; /* flag to toggle MEM_SEG register */ -+ -+ char *vars; -+ uint varsz; -+ -+ void *curmap; /* current regs va */ -+ void *regs[SI_MAXCORES]; /* other regs va */ -+ -+ uint curidx; /* current core index */ -+ uint numcores; /* # discovered cores */ -+ uint coreid[SI_MAXCORES]; /* id of each core */ -+ uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ -+ void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ -+ uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ -+ uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ -+ uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ -+ -+ void *curwrap; /* current wrapper va */ -+ void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ -+ uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ -+ -+ uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ -+ uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ -+ uint32 oob_router; /* oob router registers for axi */ -+} si_info_t; -+ -+#define SI_INFO(sih) (si_info_t *)(uintptr)sih -+ -+#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ -+ ISALIGNED((x), SI_CORE_SIZE)) -+#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) -+#define BADCOREADDR 0 -+#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -+#define NOREV -1 /* Invalid rev */ -+ -+#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCI_CORE_ID)) -+ -+#define PCIE_GEN1(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCIE_CORE_ID)) -+ -+#define PCIE_GEN2(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCIE2_CORE_ID)) -+ -+#define PCIE(si) (PCIE_GEN1(si) || PCIE_GEN2(si)) -+ -+#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) -+ -+/* Newer chips can access PCI/PCIE and CC core without requiring to change -+ * PCI BAR0 WIN -+ */ -+#define SI_FAST(si) (PCIE(si) || (PCI(si) && ((si)->pub.buscorerev >= 13))) -+ -+#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -+#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) -+ -+/* -+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ -+ * after core switching to avoid invalid register accesss inside ISR. -+ */ -+#define INTR_OFF(si, intr_val) \ -+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -+#define INTR_RESTORE(si, intr_val) \ -+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } -+ -+/* dynamic clock control defines */ -+#define LPOMINFREQ 25000 /* low power oscillator min */ -+#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -+#define PCIMINFREQ 25000000 /* 25 MHz */ -+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ -+ -+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -+ -+#define PCI_FORCEHT(si) \ -+ (((PCIE_GEN1(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ -+ ((PCI(si) || PCIE_GEN1(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \ -+ (PCIE_GEN1(si) && (si->pub.chip == BCM4716_CHIP_ID)) || \ -+ (PCIE_GEN1(si) && (si->pub.chip == BCM4748_CHIP_ID))) -+ -+/* GPIO Based LED powersave defines */ -+#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -+#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ -+ -+#ifndef DEFAULT_GPIOTIMERVAL -+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -+#endif -+ -+/* Silicon Backplane externs */ -+extern void sb_scan(si_t *sih, void *regs, uint devid); -+extern uint sb_coreid(si_t *sih); -+extern uint sb_intflag(si_t *sih); -+extern uint sb_flag(si_t *sih); -+extern void sb_setint(si_t *sih, int siflag); -+extern uint sb_corevendor(si_t *sih); -+extern uint sb_corerev(si_t *sih); -+extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -+extern bool sb_iscoreup(si_t *sih); -+extern void *sb_setcoreidx(si_t *sih, uint coreidx); -+extern uint32 sb_core_cflags(si_t *sih, uint32 mask, uint32 val); -+extern void sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -+extern uint32 sb_core_sflags(si_t *sih, uint32 mask, uint32 val); -+extern void sb_commit(si_t *sih); -+extern uint32 sb_base(uint32 admatch); -+extern uint32 sb_size(uint32 admatch); -+extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -+extern void sb_core_disable(si_t *sih, uint32 bits); -+extern uint32 sb_addrspace(si_t *sih, uint asidx); -+extern uint32 sb_addrspacesize(si_t *sih, uint asidx); -+extern int sb_numaddrspaces(si_t *sih); -+ -+extern uint32 sb_set_initiator_to(si_t *sih, uint32 to, uint idx); -+ -+extern bool sb_taclear(si_t *sih, bool details); -+ -+ -+/* Wake-on-wireless-LAN (WOWL) */ -+extern bool sb_pci_pmecap(si_t *sih); -+struct osl_info; -+extern bool sb_pci_fastpmecap(struct osl_info *osh); -+extern bool sb_pci_pmeclr(si_t *sih); -+extern void sb_pci_pmeen(si_t *sih); -+extern uint sb_pcie_readreg(void *sih, uint addrtype, uint offset); -+ -+/* AMBA Interconnect exported externs */ -+extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, -+ void *sdh, char **vars, uint *varsz); -+extern si_t *ai_kattach(osl_t *osh); -+extern void ai_scan(si_t *sih, void *regs, uint devid); -+ -+extern uint ai_flag(si_t *sih); -+extern void ai_setint(si_t *sih, int siflag); -+extern uint ai_coreidx(si_t *sih); -+extern uint ai_corevendor(si_t *sih); -+extern uint ai_corerev(si_t *sih); -+extern bool ai_iscoreup(si_t *sih); -+extern void *ai_setcoreidx(si_t *sih, uint coreidx); -+extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); -+extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -+extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); -+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -+extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -+extern void ai_core_disable(si_t *sih, uint32 bits); -+extern int ai_numaddrspaces(si_t *sih); -+extern uint32 ai_addrspace(si_t *sih, uint asidx); -+extern uint32 ai_addrspacesize(si_t *sih, uint asidx); -+extern void ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); -+extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -+ -+ -+ -+#define ub_scan(a, b, c) do {} while (0) -+#define ub_flag(a) (0) -+#define ub_setint(a, b) do {} while (0) -+#define ub_coreidx(a) (0) -+#define ub_corevendor(a) (0) -+#define ub_corerev(a) (0) -+#define ub_iscoreup(a) (0) -+#define ub_setcoreidx(a, b) (0) -+#define ub_core_cflags(a, b, c) (0) -+#define ub_core_cflags_wo(a, b, c) do {} while (0) -+#define ub_core_sflags(a, b, c) (0) -+#define ub_corereg(a, b, c, d, e) (0) -+#define ub_core_reset(a, b, c) do {} while (0) -+#define ub_core_disable(a, b) do {} while (0) -+#define ub_numaddrspaces(a) (0) -+#define ub_addrspace(a, b) (0) -+#define ub_addrspacesize(a, b) (0) -+#define ub_view(a, b) do {} while (0) -+#define ub_dumpregs(a, b) do {} while (0) -+ -+#endif /* _siutils_priv_h_ */ -diff --git a/drivers/net/wireless/ap6210/uamp_api.h b/drivers/net/wireless/ap6210/uamp_api.h -new file mode 100644 -index 0000000..673dce0 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/uamp_api.h -@@ -0,0 +1,176 @@ -+/* -+ * Name: uamp_api.h -+ * -+ * Description: Universal AMP API -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: uamp_api.h 294267 2011-11-04 23:41:52Z $ -+ * -+ */ -+#ifndef UAMP_API_H -+#define UAMP_API_H -+ -+ -+#include "typedefs.h" -+ -+ -+/***************************************************************************** -+** Constant and Type Definitions -+****************************************************************************** -+*/ -+ -+#define BT_API -+ -+/* Types. */ -+typedef bool BOOLEAN; -+typedef uint8 UINT8; -+typedef uint16 UINT16; -+ -+ -+/* UAMP identifiers */ -+#define UAMP_ID_1 1 -+#define UAMP_ID_2 2 -+typedef UINT8 tUAMP_ID; -+ -+/* UAMP event ids (used by UAMP_CBACK) */ -+#define UAMP_EVT_RX_READY 0 /* Data from AMP controller is ready to be read */ -+#define UAMP_EVT_CTLR_REMOVED 1 /* Controller removed */ -+#define UAMP_EVT_CTLR_READY 2 /* Controller added/ready */ -+typedef UINT8 tUAMP_EVT; -+ -+ -+/* UAMP Channels */ -+#define UAMP_CH_HCI_CMD 0 /* HCI Command channel */ -+#define UAMP_CH_HCI_EVT 1 /* HCI Event channel */ -+#define UAMP_CH_HCI_DATA 2 /* HCI ACL Data channel */ -+typedef UINT8 tUAMP_CH; -+ -+/* tUAMP_EVT_DATA: union for event-specific data, used by UAMP_CBACK */ -+typedef union { -+ tUAMP_CH channel; /* UAMP_EVT_RX_READY: channel for which rx occured */ -+} tUAMP_EVT_DATA; -+ -+ -+/***************************************************************************** -+** -+** Function: UAMP_CBACK -+** -+** Description: Callback for events. Register callback using UAMP_Init. -+** -+** Parameters amp_id: AMP device identifier that generated the event -+** amp_evt: event id -+** p_amp_evt_data: pointer to event-specific data -+** -+****************************************************************************** -+*/ -+typedef void (*tUAMP_CBACK)(tUAMP_ID amp_id, tUAMP_EVT amp_evt, tUAMP_EVT_DATA *p_amp_evt_data); -+ -+/***************************************************************************** -+** external function declarations -+****************************************************************************** -+*/ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+/***************************************************************************** -+** -+** Function: UAMP_Init -+** -+** Description: Initialize UAMP driver -+** -+** Parameters p_cback: Callback function for UAMP event notification -+** -+****************************************************************************** -+*/ -+BT_API BOOLEAN UAMP_Init(tUAMP_CBACK p_cback); -+ -+ -+/***************************************************************************** -+** -+** Function: UAMP_Open -+** -+** Description: Open connection to local AMP device. -+** -+** Parameters app_id: Application specific AMP identifer. This value -+** will be included in AMP messages sent to the -+** BTU task, to identify source of the message -+** -+****************************************************************************** -+*/ -+BT_API BOOLEAN UAMP_Open(tUAMP_ID amp_id); -+ -+/***************************************************************************** -+** -+** Function: UAMP_Close -+** -+** Description: Close connection to local AMP device. -+** -+** Parameters app_id: Application specific AMP identifer. -+** -+****************************************************************************** -+*/ -+BT_API void UAMP_Close(tUAMP_ID amp_id); -+ -+ -+/***************************************************************************** -+** -+** Function: UAMP_Write -+** -+** Description: Send buffer to AMP device. Frees GKI buffer when done. -+** -+** -+** Parameters: app_id: AMP identifer. -+** p_buf: pointer to buffer to write -+** num_bytes: number of bytes to write -+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_CMD -+** -+** Returns: number of bytes written -+** -+****************************************************************************** -+*/ -+BT_API UINT16 UAMP_Write(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 num_bytes, tUAMP_CH channel); -+ -+/***************************************************************************** -+** -+** Function: UAMP_Read -+** -+** Description: Read incoming data from AMP. Call after receiving a -+** UAMP_EVT_RX_READY callback event. -+** -+** Parameters: app_id: AMP identifer. -+** p_buf: pointer to buffer for holding incoming AMP data -+** buf_size: size of p_buf -+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_EVT -+** -+** Returns: number of bytes read -+** -+****************************************************************************** -+*/ -+BT_API UINT16 UAMP_Read(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 buf_size, tUAMP_CH channel); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* UAMP_API_H */ -diff --git a/drivers/net/wireless/ap6210/wl_android.c b/drivers/net/wireless/ap6210/wl_android.c -new file mode 100644 -index 0000000..7e8b724 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_android.c -@@ -0,0 +1,1448 @@ -+/* -+ * Linux cfg80211 driver - Android related functions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_android.c 372668 2012-12-04 14:07:12Z $ -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef WL_CFG80211 -+#include -+#endif -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -+#include -+#else -+#include -+#endif -+#endif /* CONFIG_WIFI_CONTROL_FUNC */ -+ -+#include -+ -+#ifndef WL_CFG80211 -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+#endif -+ -+/* -+ * Android private command strings, PLEASE define new private commands here -+ * so they can be updated easily in the future (if needed) -+ */ -+ -+#define CMD_START "START" -+#define CMD_STOP "STOP" -+#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -+#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -+#define CMD_RSSI "RSSI" -+#define CMD_LINKSPEED "LINKSPEED" -+#define CMD_RXFILTER_START "RXFILTER-START" -+#define CMD_RXFILTER_STOP "RXFILTER-STOP" -+#define CMD_RXFILTER_ADD "RXFILTER-ADD" -+#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -+#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -+#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -+#define CMD_BTCOEXMODE "BTCOEXMODE" -+#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -+#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" -+#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -+#define CMD_SETFWPATH "SETFWPATH" -+#define CMD_SETBAND "SETBAND" -+#define CMD_GETBAND "GETBAND" -+#define CMD_COUNTRY "COUNTRY" -+#define CMD_P2P_SET_NOA "P2P_SET_NOA" -+#if !defined WL_ENABLE_P2P_IF -+#define CMD_P2P_GET_NOA "P2P_GET_NOA" -+#endif -+#define CMD_P2P_SD_OFFLOAD "P2P_SD_" -+#define CMD_P2P_SET_PS "P2P_SET_PS" -+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -+#define CMD_SETROAMMODE "SETROAMMODE" -+ -+ -+/* CCX Private Commands */ -+ -+#ifdef PNO_SUPPORT -+#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -+#define CMD_PNOSETUP_SET "PNOSETUP " -+#define CMD_PNOENABLE_SET "PNOFORCE" -+#define CMD_PNODEBUG_SET "PNODEBUG" -+ -+#define PNO_TLV_PREFIX 'S' -+#define PNO_TLV_VERSION '1' -+#define PNO_TLV_SUBVERSION '2' -+#define PNO_TLV_RESERVED '0' -+#define PNO_TLV_TYPE_SSID_IE 'S' -+#define PNO_TLV_TYPE_TIME 'T' -+#define PNO_TLV_FREQ_REPEAT 'R' -+#define PNO_TLV_FREQ_EXPO_MAX 'M' -+ -+typedef struct cmd_tlv { -+ char prefix; -+ char version; -+ char subver; -+ char reserved; -+} cmd_tlv_t; -+#endif /* PNO_SUPPORT */ -+ -+#define CMD_OKC_SET_PMK "SET_PMK" -+#define CMD_OKC_ENABLE "OKC_ENABLE" -+ -+ -+typedef struct android_wifi_priv_cmd { -+ char *buf; -+ int used_len; -+ int total_len; -+} android_wifi_priv_cmd; -+ -+/** -+ * Extern function declarations (TODO: move them to dhd_linux.h) -+ */ -+void dhd_customer_gpio_wlan_ctrl(int onoff); -+int dhd_dev_reset(struct net_device *dev, uint8 flag); -+int dhd_dev_init_ioctl(struct net_device *dev); -+#ifdef WL_CFG80211 -+int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); -+int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command); -+#else -+int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) -+{ return 0; } -+int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) -+{ return 0; } -+int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len) -+{ return 0; } -+int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) -+{ return 0; } -+#endif /* WL_CFG80211 */ -+ -+extern int dhd_os_check_wakelock(void *dhdp); -+extern int dhd_os_check_if_up(void *dhdp); -+extern void *bcmsdh_get_drvdata(void); -+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) -+extern int dhd_wlfc_init(dhd_pub_t *dhd); -+extern void dhd_wlfc_deinit(dhd_pub_t *dhd); -+#endif -+ -+extern bool ap_fw_loaded; -+extern char iface_name[IFNAMSIZ]; -+ -+#define WIFI_TURNOFF_DELAY 0 -+/** -+ * Local (static) functions and variables -+ */ -+ -+/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first -+ * time (only) in dhd_open, subsequential wifi on will be handled by -+ * wl_android_wifi_on -+ */ -+static int g_wifi_on = TRUE; -+ -+/** -+ * Local (static) function definitions -+ */ -+static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len) -+{ -+ int link_speed; -+ int bytes_written; -+ int error; -+ -+ error = wldev_get_link_speed(net, &link_speed); -+ if (error) -+ return -1; -+ -+ /* Convert Kbps to Android Mbps */ -+ link_speed = link_speed / 1000; -+ bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); -+ AP6210_DEBUG("%s: command result is %s\n", __FUNCTION__, command); -+ return bytes_written; -+} -+ -+static int wl_android_get_rssi(struct net_device *net, char *command, int total_len) -+{ -+ wlc_ssid_t ssid = {0}; -+ int rssi; -+ int bytes_written = 0; -+ int error; -+ -+ error = wldev_get_rssi(net, &rssi); -+ if (error) -+ return -1; -+#if defined(RSSIOFFSET) -+ rssi = wl_update_rssi_offset(rssi); -+#endif -+ -+ error = wldev_get_ssid(net, &ssid); -+ if (error) -+ return -1; -+ if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { -+ AP6210_ERR("%s: wldev_get_ssid failed\n", __FUNCTION__); -+ } else { -+ memcpy(command, ssid.SSID, ssid.SSID_len); -+ bytes_written = ssid.SSID_len; -+ } -+ bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi); -+ AP6210_DEBUG("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written); -+ return bytes_written; -+} -+ -+static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len) -+{ -+ int suspend_flag; -+ int ret_now; -+ int ret = 0; -+ -+ suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; -+ -+ if (suspend_flag != 0) -+ suspend_flag = 1; -+ ret_now = net_os_set_suspend_disable(dev, suspend_flag); -+ -+ if (ret_now != suspend_flag) { -+ if (!(ret = net_os_set_suspend(dev, ret_now, 1))) -+ AP6210_DEBUG("%s: Suspend Flag %d -> %d\n", -+ __FUNCTION__, ret_now, suspend_flag); -+ else -+ AP6210_ERR("%s: failed %d\n", __FUNCTION__, ret); -+ } -+ return ret; -+} -+ -+static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len) -+{ -+ int ret = 0; -+ -+#if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND) -+ int suspend_flag; -+ -+ suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0'; -+ -+ if (suspend_flag != 0) -+ suspend_flag = 1; -+ -+ if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) -+ AP6210_DEBUG("%s: Suspend Mode %d\n",__FUNCTION__,suspend_flag); -+ else -+ AP6210_ERR("%s: failed %d\n",__FUNCTION__,ret); -+#endif -+ return ret; -+} -+ -+static int wl_android_get_band(struct net_device *dev, char *command, int total_len) -+{ -+ uint band; -+ int bytes_written; -+ int error; -+ -+ error = wldev_get_band(dev, &band); -+ if (error) -+ return -1; -+ bytes_written = snprintf(command, total_len, "Band %d", band); -+ return bytes_written; -+} -+ -+#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) -+static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) -+{ -+ wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; -+ int res = -1; -+ int nssid = 0; -+ cmd_tlv_t *cmd_tlv_temp; -+ char *str_ptr; -+ int tlv_size_left; -+ int pno_time = 0; -+ int pno_repeat = 0; -+ int pno_freq_expo_max = 0; -+ -+#ifdef PNO_SET_DEBUG -+ int i; -+ char pno_in_example[] = { -+ 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', -+ 'S', '1', '2', '0', -+ 'S', -+ 0x05, -+ 'd', 'l', 'i', 'n', 'k', -+ 'S', -+ 0x04, -+ 'G', 'O', 'O', 'G', -+ 'T', -+ '0', 'B', -+ 'R', -+ '2', -+ 'M', -+ '2', -+ 0x00 -+ }; -+#endif /* PNO_SET_DEBUG */ -+ -+ AP6210_DEBUG("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len); -+ -+ if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { -+ AP6210_ERR("%s argument=%d less min size\n", __FUNCTION__, total_len); -+ goto exit_proc; -+ } -+ -+ -+#ifdef PNO_SET_DEBUG -+ memcpy(command, pno_in_example, sizeof(pno_in_example)); -+ for (i = 0; i < sizeof(pno_in_example); i++) -+ AP6210_DUMP("%02X ", command[i]); -+ AP6210_DUMP("\n"); -+ total_len = sizeof(pno_in_example); -+#endif -+ -+ str_ptr = command + strlen(CMD_PNOSETUP_SET); -+ tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); -+ -+ cmd_tlv_temp = (cmd_tlv_t *)str_ptr; -+ memset(ssids_local, 0, sizeof(ssids_local)); -+ -+ if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && -+ (cmd_tlv_temp->version == PNO_TLV_VERSION) && -+ (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { -+ -+ str_ptr += sizeof(cmd_tlv_t); -+ tlv_size_left -= sizeof(cmd_tlv_t); -+ -+ if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, -+ MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { -+ AP6210_ERR("SSID is not presented or corrupted ret=%d\n", nssid); -+ goto exit_proc; -+ } else { -+ if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { -+ AP6210_ERR("%s scan duration corrupted field size %d\n", -+ __FUNCTION__, tlv_size_left); -+ goto exit_proc; -+ } -+ str_ptr++; -+ pno_time = simple_strtoul(str_ptr, &str_ptr, 16); -+ AP6210_DEBUG("%s: pno_time=%d\n", __FUNCTION__, pno_time); -+ -+ if (str_ptr[0] != 0) { -+ if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { -+ AP6210_ERR("%s pno repeat : corrupted field\n", -+ __FUNCTION__); -+ goto exit_proc; -+ } -+ str_ptr++; -+ pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); -+ AP6210_DEBUG("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat); -+ if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { -+ AP6210_ERR("%s FREQ_EXPO_MAX corrupted field size\n", -+ __FUNCTION__); -+ goto exit_proc; -+ } -+ str_ptr++; -+ pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); -+ AP6210_DEBUG("%s: pno_freq_expo_max=%d\n", -+ __FUNCTION__, pno_freq_expo_max); -+ } -+ } -+ } else { -+ AP6210_ERR("%s get wrong TLV command\n", __FUNCTION__); -+ goto exit_proc; -+ } -+ -+ res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); -+ -+exit_proc: -+ return res; -+} -+#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */ -+ -+static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len) -+{ -+ int ret; -+ int bytes_written = 0; -+ -+ ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command); -+ if (ret) -+ return 0; -+ bytes_written = sizeof(struct ether_addr); -+ return bytes_written; -+} -+ -+/** -+ * Global function definitions (declared in wl_android.h) -+ */ -+ -+int wl_android_wifi_on(struct net_device *dev) -+{ -+ int ret = 0; -+ int retry = POWERUP_MAX_RETRY; -+ -+ AP6210_DEBUG("%s in\n", __FUNCTION__); -+ if (!dev) { -+ AP6210_ERR("%s: dev is null\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dhd_net_if_lock(dev); -+ if (!g_wifi_on) { -+ do { -+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); -+ ret = sdioh_start(NULL, 0); -+ if (ret == 0) -+ break; -+ AP6210_ERR("failed to power up wifi chip, retry again (%d left) **\n\n", -+ retry+1); -+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); -+ } while (retry-- >= 0); -+ if (ret != 0) { -+ AP6210_ERR("failed to power up wifi chip, max retry reached **\n\n"); -+ goto exit; -+ } -+ ret = dhd_dev_reset(dev, FALSE); -+ if (ret) -+ goto err; -+ sdioh_start(NULL, 1); -+ if (!ret) { -+ if (dhd_dev_init_ioctl(dev) < 0) { -+ ret = -EFAULT; -+ goto err; -+ } -+ } -+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) -+ dhd_wlfc_init(bcmsdh_get_drvdata()); -+#endif -+ g_wifi_on = TRUE; -+ } -+ -+exit: -+ dhd_net_if_unlock(dev); -+ AP6210_DEBUG("%s: Success\n", __FUNCTION__); -+ return ret; -+err: -+ dhd_dev_reset(dev, TRUE); -+ sdioh_stop(NULL); -+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); -+ dhd_net_if_unlock(dev); -+ AP6210_DEBUG("%s: Failed\n", __FUNCTION__); -+ -+ return ret; -+} -+ -+int wl_android_wifi_off(struct net_device *dev) -+{ -+ int ret = 0; -+ -+ AP6210_DEBUG("%s in\n", __FUNCTION__); -+ if (!dev) { -+ AP6210_DEBUG("%s: dev is null\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ dhd_net_if_lock(dev); -+ if (g_wifi_on) { -+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) -+ dhd_wlfc_deinit(bcmsdh_get_drvdata()); -+#endif -+ ret = dhd_dev_reset(dev, TRUE); -+ sdioh_stop(NULL); -+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); -+ g_wifi_on = FALSE; -+ } -+ dhd_net_if_unlock(dev); -+ -+ return ret; -+} -+ -+static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len) -+{ -+ if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN) -+ return -1; -+ bcm_strncpy_s(fw_path, sizeof(fw_path), -+ command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1); -+ if (strstr(fw_path, "apsta") != NULL) { -+ AP6210_DEBUG("GOT APSTA FIRMWARE\n"); -+ ap_fw_loaded = TRUE; -+ } else { -+ AP6210_DEBUG("GOT STA FIRMWARE\n"); -+ ap_fw_loaded = FALSE; -+ } -+ return 0; -+} -+ -+static int -+wl_android_set_pmk(struct net_device *dev, char *command, int total_len) -+{ -+ uchar pmk[33]; -+ int error = 0; -+ char smbuf[WLC_IOCTL_SMLEN]; -+#ifdef OKC_DEBUG -+ int i = 0; -+#endif -+ -+ bzero(pmk, sizeof(pmk)); -+ memcpy((char *)pmk, command + strlen("SET_PMK "), 32); -+ error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL); -+ if (error) { -+ AP6210_ERR("Failed to set PMK for OKC, error = %d\n", error); -+ } -+#ifdef OKC_DEBUG -+ AP6210_ERR("PMK is "); -+ for (i = 0; i < 32; i++) -+ AP6210_ERR("%02X ", pmk[i]); -+ -+ AP6210_ERR("\n"); -+#endif -+ return error; -+} -+ -+static int -+wl_android_okc_enable(struct net_device *dev, char *command, int total_len) -+{ -+ int error = 0; -+ char okc_enable = 0; -+ -+ okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0'; -+ error = wldev_iovar_setint(dev, "okc_enable", okc_enable); -+ if (error) { -+ AP6210_ERR("Failed to %s OKC, error = %d\n", -+ okc_enable ? "enable" : "disable", error); -+ } -+ -+ return error; -+} -+ -+int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len) -+{ -+ int error = 0; -+ int mode = 0; -+ -+ if (sscanf(command, "%*s %d", &mode) != 1) { -+ AP6210_ERR("%s: Failed to get Parameter\n", __FUNCTION__); -+ return -1; -+ } -+ -+ error = wldev_iovar_setint(dev, "roam_off", mode); -+ if (error) { -+ AP6210_ERR("%s: Failed to set roaming Mode %d, error = %d\n", -+ __FUNCTION__, mode, error); -+ return -1; -+ } -+ else -+ AP6210_ERR("%s: succeeded to set roaming Mode %d, error = %d\n", -+ __FUNCTION__, mode, error); -+ return 0; -+} -+ -+int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) -+{ -+#define PRIVATE_COMMAND_MAX_LEN 8192 -+ int ret = 0; -+ char *command = NULL; -+ int bytes_written = 0; -+ android_wifi_priv_cmd priv_cmd; -+ -+ net_os_wake_lock(net); -+ -+ if (!ifr->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) -+ { -+ AP6210_ERR("%s: too long priavte command\n", __FUNCTION__); -+ ret = -EINVAL; -+ } -+ command = kmalloc(priv_cmd.total_len, GFP_KERNEL); -+ if (!command) -+ { -+ AP6210_ERR("%s: failed to allocate memory\n", __FUNCTION__); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { -+ ret = -EFAULT; -+ goto exit; -+ } -+ -+ AP6210_DEBUG("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name); -+ -+ if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { -+ AP6210_DEBUG("%s, Received regular START command\n", __FUNCTION__); -+ bytes_written = wl_android_wifi_on(net); -+ } -+ else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { -+ bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len); -+ } -+ -+ if (!g_wifi_on) { -+ AP6210_ERR("%s: Ignore private cmd \"%s\" - iface %s is down\n", -+ __FUNCTION__, command, ifr->ifr_name); -+ ret = 0; -+ goto exit; -+ } -+ -+ if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) { -+ bytes_written = wl_android_wifi_off(net); -+ } -+ else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) { -+ /* TBD: SCAN-ACTIVE */ -+ } -+ else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) { -+ /* TBD: SCAN-PASSIVE */ -+ } -+ else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) { -+ bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len); -+ } -+ else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { -+ bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len); -+ } -+#ifdef PKT_FILTER_SUPPORT -+ else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) { -+ bytes_written = net_os_enable_packet_filter(net, 1); -+ } -+ else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) { -+ bytes_written = net_os_enable_packet_filter(net, 0); -+ } -+ else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) { -+ int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; -+ bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); -+ } -+ else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) { -+ int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; -+ bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); -+ } -+#endif /* PKT_FILTER_SUPPORT */ -+ else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) { -+ /* TBD: BTCOEXSCAN-START */ -+ } -+ else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) { -+ /* TBD: BTCOEXSCAN-STOP */ -+ } -+ else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { -+#ifdef WL_CFG80211 -+ bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); -+#else -+#ifdef PKT_FILTER_SUPPORT -+ uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; -+ -+ if (mode == 1) -+ net_os_enable_packet_filter(net, 0); /* DHCP starts */ -+ else -+ net_os_enable_packet_filter(net, 1); /* DHCP ends */ -+#endif /* PKT_FILTER_SUPPORT */ -+#endif /* WL_CFG80211 */ -+ } -+ else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { -+ bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); -+ } -+ else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { -+ bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len); -+ } -+ else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { -+ uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; -+#ifdef WL_HOST_BAND_MGMT -+ if (wl_cfg80211_set_band(net, band) < 0) { -+ bytes_written = -1; -+ goto exit; -+ } -+ if (band == WLC_BAND_AUTO) -+ bytes_written = wldev_set_band(net, band); -+#else -+ bytes_written = wldev_set_band(net, band); -+#endif /* WL_HOST_BAND_MGMT */ -+ } -+ else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { -+ bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); -+ } -+#ifdef WL_CFG80211 -+ /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */ -+ else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { -+ char *country_code = command + strlen(CMD_COUNTRY) + 1; -+ bytes_written = wldev_set_country(net, country_code); -+ } -+#endif /* WL_CFG80211 */ -+#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) -+ else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { -+ bytes_written = dhd_dev_pno_reset(net); -+ } -+ else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { -+ bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); -+ } -+ else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { -+ uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; -+ bytes_written = dhd_dev_pno_enable(net, pfn_enabled); -+ } -+#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */ -+ else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) { -+ bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); -+ } -+ else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) { -+ int skip = strlen(CMD_P2P_SET_NOA) + 1; -+ bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, -+ priv_cmd.total_len - skip); -+ } -+#if !defined WL_ENABLE_P2P_IF -+ else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { -+ bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); -+ } -+#endif /* WL_ENABLE_P2P_IF */ -+ else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) { -+ int skip = strlen(CMD_P2P_SET_PS) + 1; -+ bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, -+ priv_cmd.total_len - skip); -+ } -+#ifdef WL_CFG80211 -+ else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, -+ strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { -+ int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3; -+ bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, -+ priv_cmd.total_len - skip, *(command + skip - 2) - '0'); -+ } -+#endif /* WL_CFG80211 */ -+ else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0) -+ bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len); -+ else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) -+ bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len); -+ else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0) -+ bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len); -+ else { -+ AP6210_ERR("Unknown PRIVATE command %s - ignored\n", command); -+ snprintf(command, 3, "OK"); -+ bytes_written = strlen("OK"); -+ } -+ -+ if (bytes_written >= 0) { -+ if ((bytes_written == 0) && (priv_cmd.total_len > 0)) -+ command[0] = '\0'; -+ if (bytes_written >= priv_cmd.total_len) { -+ AP6210_ERR("%s: bytes_written = %d\n", __FUNCTION__, bytes_written); -+ bytes_written = priv_cmd.total_len; -+ } else { -+ bytes_written++; -+ } -+ priv_cmd.used_len = bytes_written; -+ if (copy_to_user(priv_cmd.buf, command, bytes_written)) { -+ AP6210_ERR("%s: failed to copy data to user buffer\n", __FUNCTION__); -+ ret = -EFAULT; -+ } -+ } -+ else { -+ ret = bytes_written; -+ } -+ -+exit: -+ net_os_wake_unlock(net); -+ if (command) { -+ kfree(command); -+ } -+ -+ return ret; -+} -+ -+int wl_android_init(void) -+{ -+ int ret = 0; -+ -+ dhd_msg_level |= DHD_ERROR_VAL; -+#ifdef ENABLE_INSMOD_NO_FW_LOAD -+ dhd_download_fw_on_driverload = FALSE; -+#endif /* ENABLE_INSMOD_NO_FW_LOAD */ -+ if (!iface_name[0]) { -+ memset(iface_name, 0, IFNAMSIZ); -+ bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ); -+ } -+ return ret; -+} -+ -+int wl_android_exit(void) -+{ -+ int ret = 0; -+ -+ return ret; -+} -+ -+void wl_android_post_init(void) -+{ -+ if (!dhd_download_fw_on_driverload) { -+ /* Call customer gpio to turn off power with WL_REG_ON signal */ -+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); -+ g_wifi_on = 0; -+ } -+} -+ -+#if defined(RSSIAVG) -+void -+wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -+{ -+ wl_rssi_cache_t *node, *cur, **rssi_head; -+ int i=0; -+ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ node = *rssi_head; -+ -+ for (;node;) { -+ AP6210_DEBUG("%s: Free %d with BSSID %pM\n", -+ __FUNCTION__, i, &node->BSSID); -+ cur = node; -+ node = cur->next; -+ kfree(cur); -+ i++; -+ } -+ *rssi_head = NULL; -+} -+ -+void -+wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -+{ -+ wl_rssi_cache_t *node, *prev, **rssi_head; -+ int i = -1, tmp = 0; -+#if defined(BSSCACHE) -+ int max = BSSCACHE_LEN; -+#else -+ int max = RSSICACHE_LEN; -+#endif -+ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ node = *rssi_head; -+ prev = node; -+ for (;node;) { -+ i++; -+ if (node->dirty >= max || node->dirty >= RSSICACHE_LEN) { -+ if (node == *rssi_head) { -+ tmp = 1; -+ *rssi_head = node->next; -+ } else { -+ tmp = 0; -+ prev->next = node->next; -+ } -+ AP6210_DEBUG("%s: Del %d with BSSID %pM\n", -+ __FUNCTION__, i, &node->BSSID); -+ kfree(node); -+ if (tmp == 1) { -+ node = *rssi_head; -+ prev = node; -+ } else { -+ node = prev->next; -+ } -+ continue; -+ } -+ prev = node; -+ node = node->next; -+ } -+} -+ -+void -+wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -+{ -+ wl_rssi_cache_t *node, **rssi_head; -+ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ -+ /* reset dirty */ -+ node = *rssi_head; -+ for (;node;) { -+ node->dirty += 1; -+ node = node->next; -+ } -+} -+ -+void -+wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net) -+{ -+ wl_rssi_cache_t *node, *prev, **rssi_head; -+ int j, k=0; -+ int rssi, error; -+ struct ether_addr bssid; -+ -+ error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false); -+ if (error) -+ return; -+ error = wldev_get_rssi(net, &rssi); -+ if (error) -+ return; -+ -+ /* update RSSI */ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ node = *rssi_head; -+ for (;node;) { -+ if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) { -+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d\n", -+ __FUNCTION__, k, &bssid, rssi); -+ for(j=0; jRSSI[j] = node->RSSI[j+1]; -+ node->RSSI[j] = rssi; -+ node->dirty = 0; -+ break; -+ } -+ prev = node; -+ node = node->next; -+ k++; -+ } -+} -+ -+void -+wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list) -+{ -+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; -+ wl_bss_info_t *bi = NULL; -+ int i, j, k; -+ -+ if (!ss_list->count) -+ return; -+ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ -+ /* update RSSI */ -+ for (i = 0; i < ss_list->count; i++) { -+ node = *rssi_head; -+ prev = NULL; -+ k = 0; -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; -+ for (;node;) { -+ if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { -+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", -+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID); -+ for(j=0; jRSSI[j] = node->RSSI[j+1]; -+ node->RSSI[j] = dtoh16(bi->RSSI); -+ node->dirty = 0; -+ break; -+ } -+ prev = node; -+ node = node->next; -+ k++; -+ } -+ -+ if (node) -+ continue; -+ -+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); -+ if (!leaf) { -+ AP6210_ERR("%s: Memory alloc failure %d\n", -+ __FUNCTION__, sizeof(wl_rssi_cache_t)); -+ return; -+ } -+ AP6210_DEBUG("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n", -+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID); -+ -+ leaf->next = NULL; -+ leaf->dirty = 0; -+ memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN); -+ for (j=0; jRSSI[j] = dtoh16(bi->RSSI); -+ -+ if (!prev) -+ *rssi_head = leaf; -+ else -+ prev->next = leaf; -+ } -+} -+ -+int16 -+wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr) -+{ -+ wl_rssi_cache_t *node, **rssi_head; -+ int j, rssi_sum, rssi=-200; -+ -+ rssi_head = &rssi_cache_ctrl->m_cache_head; -+ -+ /* reset dirty */ -+ node = *rssi_head; -+ for (;node;) { -+ if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) { -+ rssi_sum = 0; -+ rssi = 0; -+ for (j=0; jRSSI[RSSIAVG_LEN-j-1]; -+ rssi = rssi_sum / j; -+ break; -+ } -+ node = node->next; -+ } -+ if (rssi >= -2) -+ rssi = -2; -+ if (rssi == -200) { -+ AP6210_ERR("%s: BSSID %pM does not in RSSI cache\n", -+ __FUNCTION__, addr); -+ } -+ return (int16)rssi; -+} -+#endif -+ -+#if defined(RSSIOFFSET) -+int -+wl_update_rssi_offset(int rssi) -+{ -+ uint chip, chiprev; -+ -+ chip = dhd_bus_chip_id(bcmsdh_get_drvdata()); -+ chiprev = dhd_bus_chiprev_id(bcmsdh_get_drvdata()); -+ if (chip == BCM4330_CHIP_ID && chiprev == BCM4330B2_CHIP_REV) { -+#if defined(RSSIOFFSET_NEW) -+ int j; -+ for (j=0; j= -2) -+ rssi = -2; -+ return rssi; -+} -+#endif -+ -+#if defined(BSSCACHE) -+#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 -+ -+void -+wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) -+{ -+ wl_bss_cache_t *node, *cur, **bss_head; -+ int i=0; -+ -+ AP6210_DEBUG("%s called\n", __FUNCTION__); -+ -+ bss_head = &bss_cache_ctrl->m_cache_head; -+ node = *bss_head; -+ -+ for (;node;) { -+ AP6210_DEBUG("%s: Free %d with BSSID %pM\n", -+ __FUNCTION__, i, &node->results.bss_info->BSSID); -+ cur = node; -+ node = cur->next; -+ kfree(cur); -+ i++; -+ } -+ *bss_head = NULL; -+} -+ -+void -+wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) -+{ -+ wl_bss_cache_t *node, *prev, **bss_head; -+ int i = -1, tmp = 0; -+ -+ bss_head = &bss_cache_ctrl->m_cache_head; -+ node = *bss_head; -+ prev = node; -+ for (;node;) { -+ i++; -+ if (node->dirty >= BSSCACHE_LEN) { -+ if (node == *bss_head) { -+ tmp = 1; -+ *bss_head = node->next; -+ } else { -+ tmp = 0; -+ prev->next = node->next; -+ } -+ AP6210_DEBUG("%s: Del %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", -+ __FUNCTION__, i, &node->results.bss_info->BSSID, -+ dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID); -+ kfree(node); -+ if (tmp == 1) { -+ node = *bss_head; -+ prev = node; -+ } else { -+ node = prev->next; -+ } -+ continue; -+ } -+ prev = node; -+ node = node->next; -+ } -+} -+ -+void -+wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) -+{ -+ wl_bss_cache_t *node, **bss_head; -+ -+ bss_head = &bss_cache_ctrl->m_cache_head; -+ -+ /* reset dirty */ -+ node = *bss_head; -+ for (;node;) { -+ node->dirty += 1; -+ node = node->next; -+ } -+} -+ -+void -+wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list) -+{ -+ wl_bss_cache_t *node, *prev, *leaf, *tmp, **bss_head; -+ wl_bss_info_t *bi = NULL; -+ int i, k=0; -+ -+ if (!ss_list->count) -+ return; -+ -+ bss_head = &bss_cache_ctrl->m_cache_head; -+ -+ for (i=0; i < ss_list->count; i++) { -+ node = *bss_head; -+ prev = NULL; -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; -+ -+ for (;node;) { -+ if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { -+ tmp = node; -+ leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); -+ if (!leaf) { -+ AP6210_ERR("%s: Memory alloc failure %d and keep old BSS info\n", -+ __FUNCTION__, dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN); -+ break; -+ } -+ -+ memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); -+ leaf->next = node->next; -+ leaf->dirty = 0; -+ leaf->results.count = 1; -+ leaf->results.version = ss_list->version; -+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", -+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID); -+ if (!prev) -+ *bss_head = leaf; -+ else -+ prev->next = leaf; -+ node = leaf; -+ prev = node; -+ -+ kfree(tmp); -+ k++; -+ break; -+ } -+ prev = node; -+ node = node->next; -+ } -+ -+ if (node) -+ continue; -+ -+ leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); -+ if (!leaf) { -+ AP6210_ERR("%s: Memory alloc failure %d\n", __FUNCTION__, -+ dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN); -+ return; -+ } -+ AP6210_DEBUG("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n", -+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID); -+ -+ memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); -+ leaf->next = NULL; -+ leaf->dirty = 0; -+ leaf->results.count = 1; -+ leaf->results.version = ss_list->version; -+ k++; -+ -+ if (!prev) -+ *bss_head = leaf; -+ else -+ prev->next = leaf; -+ } -+} -+ -+void -+wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off) -+{ -+ struct timer_list **timer; -+ -+ timer = &bss_cache_ctrl->m_timer; -+ -+ if (*timer) { -+ if (kick_off) { -+ (*timer)->expires = jiffies + BSSCACHE_TIME * HZ / 1000; -+ add_timer(*timer); -+ AP6210_DEBUG("%s: timer starts\n", __FUNCTION__); -+ } else { -+ del_timer_sync(*timer); -+ AP6210_DEBUG("%s: timer stops\n", __FUNCTION__); -+ } -+ } -+} -+ -+void -+wl_set_bss_cache_timer_flag(ulong data) -+{ -+ wl_bss_cache_ctrl_t *bss_cache_ctrl = (wl_bss_cache_ctrl_t *)data; -+ -+ bss_cache_ctrl->m_timer_expired = 1; -+ AP6210_DEBUG("%s called\n", __FUNCTION__); -+} -+ -+void -+wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) -+{ -+ AP6210_DEBUG("%s:\n", __FUNCTION__); -+ wl_free_bss_cache(bss_cache_ctrl); -+ wl_run_bss_cache_timer(bss_cache_ctrl, 0); -+ if (bss_cache_ctrl->m_timer) { -+ kfree(bss_cache_ctrl->m_timer); -+ } -+} -+ -+void -+wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) -+{ -+ AP6210_DEBUG("%s:\n", __FUNCTION__); -+ bss_cache_ctrl->m_timer_expired = 0; -+ -+ bss_cache_ctrl->m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); -+ if (!bss_cache_ctrl->m_timer) { -+ AP6210_ERR("%s: Memory alloc failure\n", __FUNCTION__ ); -+ return; -+ } -+ init_timer(bss_cache_ctrl->m_timer); -+ bss_cache_ctrl->m_timer->function = (void *)wl_set_bss_cache_timer_flag; -+ bss_cache_ctrl->m_timer->data = (ulong)bss_cache_ctrl; -+} -+#endif -+ -+/** -+ * Functions for Android WiFi card detection -+ */ -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+ -+static int g_wifidev_registered = 0; -+static struct semaphore wifi_control_sem; -+static struct wifi_platform_data *wifi_control_data = NULL; -+static struct resource *wifi_irqres = NULL; -+ -+static int wifi_add_dev(void); -+static void wifi_del_dev(void); -+ -+int wl_android_wifictrl_func_add(void) -+{ -+ int ret = 0; -+ sema_init(&wifi_control_sem, 0); -+ -+ ret = wifi_add_dev(); -+ if (ret) { -+ AP6210_ERR("%s: platform_driver_register failed\n", __FUNCTION__); -+ return ret; -+ } -+ g_wifidev_registered = 1; -+ -+ /* Waiting callback after platform_driver_register is done or exit with error */ -+ if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { -+ ret = -EINVAL; -+ AP6210_ERR("%s: platform_driver_register timeout\n", __FUNCTION__); -+ } -+ -+ return ret; -+} -+ -+void wl_android_wifictrl_func_del(void) -+{ -+ if (g_wifidev_registered) -+ { -+ wifi_del_dev(); -+ g_wifidev_registered = 0; -+ } -+} -+ -+void* wl_android_prealloc(int section, unsigned long size) -+{ -+ void *alloc_ptr = NULL; -+ if (wifi_control_data && wifi_control_data->mem_prealloc) { -+ alloc_ptr = wifi_control_data->mem_prealloc(section, size); -+ if (alloc_ptr) { -+ AP6210_DEBUG("success alloc section %d\n", section); -+ if (size != 0L) -+ bzero(alloc_ptr, size); -+ return alloc_ptr; -+ } -+ } -+ -+ AP6210_ERR("can't alloc section %d\n", section); -+ return NULL; -+} -+ -+int wifi_get_irq_number(unsigned long *irq_flags_ptr) -+{ -+ if (wifi_irqres) { -+ *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; -+ return (int)wifi_irqres->start; -+ } -+#ifdef CUSTOM_OOB_GPIO_NUM -+ return CUSTOM_OOB_GPIO_NUM; -+#else -+ return -1; -+#endif -+} -+ -+int wifi_set_power(int on, unsigned long msec) -+{ -+ AP6210_ERR("%s = %d\n", __FUNCTION__, on); -+ if (wifi_control_data && wifi_control_data->set_power) { -+ wifi_control_data->set_power(on); -+ } -+ if (msec) -+ msleep(msec); -+ return 0; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -+int wifi_get_mac_addr(unsigned char *buf) -+{ -+ AP6210_ERR("%s\n", __FUNCTION__); -+ if (!buf) -+ return -EINVAL; -+ if (wifi_control_data && wifi_control_data->get_mac_addr) { -+ return wifi_control_data->get_mac_addr(buf); -+ } -+ return -EOPNOTSUPP; -+} -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+void *wifi_get_country_code(char *ccode) -+{ -+ AP6210_DEBUG("%s\n", __FUNCTION__); -+ if (!ccode) -+ return NULL; -+ if (wifi_control_data && wifi_control_data->get_country_code) { -+ return wifi_control_data->get_country_code(ccode); -+ } -+ return NULL; -+} -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ -+ -+static int wifi_set_carddetect(int on) -+{ -+ AP6210_ERR("%s = %d\n", __FUNCTION__, on); -+ if (wifi_control_data && wifi_control_data->set_carddetect) { -+ wifi_control_data->set_carddetect(on); -+ } -+ return 0; -+} -+ -+static int wifi_probe(struct platform_device *pdev) -+{ -+ struct wifi_platform_data *wifi_ctrl = -+ (struct wifi_platform_data *)(pdev->dev.platform_data); -+ -+ wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); -+ if (wifi_irqres == NULL) -+ wifi_irqres = platform_get_resource_byname(pdev, -+ IORESOURCE_IRQ, "bcm4329_wlan_irq"); -+ wifi_control_data = wifi_ctrl; -+ wifi_set_power(1, 0); /* Power On */ -+ wifi_set_carddetect(1); /* CardDetect (0->1) */ -+ -+ up(&wifi_control_sem); -+ return 0; -+} -+ -+static int wifi_remove(struct platform_device *pdev) -+{ -+ struct wifi_platform_data *wifi_ctrl = -+ (struct wifi_platform_data *)(pdev->dev.platform_data); -+ -+ AP6210_ERR("## %s\n", __FUNCTION__); -+ wifi_control_data = wifi_ctrl; -+ -+ wifi_set_power(0, WIFI_TURNOFF_DELAY); /* Power Off */ -+ wifi_set_carddetect(0); /* CardDetect (1->0) */ -+ -+ up(&wifi_control_sem); -+ return 0; -+} -+ -+static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ AP6210_DEBUG("##> %s\n", __FUNCTION__); -+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) -+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) -+ return -EBUSY; -+#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */ -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 -+ bcmsdh_oob_intr_set(0); -+#endif /* (OOB_INTR_ONLY) */ -+ return 0; -+} -+ -+static int wifi_resume(struct platform_device *pdev) -+{ -+ AP6210_DEBUG("##> %s\n", __FUNCTION__); -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 -+ if (dhd_os_check_if_up(bcmsdh_get_drvdata())) -+ bcmsdh_oob_intr_set(1); -+#endif /* (OOB_INTR_ONLY) */ -+ return 0; -+} -+ -+static struct platform_driver wifi_device = { -+ .probe = wifi_probe, -+ .remove = wifi_remove, -+ .suspend = wifi_suspend, -+ .resume = wifi_resume, -+ .driver = { -+ .name = "bcmdhd_wlan", -+ } -+}; -+ -+static struct platform_driver wifi_device_legacy = { -+ .probe = wifi_probe, -+ .remove = wifi_remove, -+ .suspend = wifi_suspend, -+ .resume = wifi_resume, -+ .driver = { -+ .name = "bcm4329_wlan", -+ } -+}; -+ -+static int wifi_add_dev(void) -+{ -+ int ret = 0; -+ AP6210_DEBUG("## Calling platform_driver_register\n"); -+ ret = platform_driver_register(&wifi_device); -+ if (ret) -+ return ret; -+ -+ ret = platform_driver_register(&wifi_device_legacy); -+ return ret; -+} -+ -+static void wifi_del_dev(void) -+{ -+ AP6210_DEBUG("## Unregister platform_driver_register\n"); -+ platform_driver_unregister(&wifi_device); -+ platform_driver_unregister(&wifi_device_legacy); -+} -+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -diff --git a/drivers/net/wireless/ap6210/wl_android.h b/drivers/net/wireless/ap6210/wl_android.h -new file mode 100644 -index 0000000..d933e06 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_android.h -@@ -0,0 +1,124 @@ -+/* -+ * Linux cfg80211 driver - Android related functions -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_android.h 367273 2012-11-07 09:58:55Z $ -+ */ -+ -+#include -+#include -+#include -+ -+/* If any feature uses the Generic Netlink Interface, put it here to enable WL_GENL -+ * automatically -+ */ -+ -+/** -+ * Android platform dependent functions, feel free to add Android specific functions here -+ * (save the macros in dhd). Please do NOT declare functions that are NOT exposed to dhd -+ * or cfg, define them as static in wl_android.c -+ */ -+ -+/** -+ * wl_android_init will be called from module init function (dhd_module_init now), similarly -+ * wl_android_exit will be called from module exit function (dhd_module_cleanup now) -+ */ -+int wl_android_init(void); -+int wl_android_exit(void); -+void wl_android_post_init(void); -+int wl_android_wifi_on(struct net_device *dev); -+int wl_android_wifi_off(struct net_device *dev); -+int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); -+ -+#define BSSCACHE -+#define RSSIAVG -+#define RSSIOFFSET -+//#define RSSIOFFSET_NEW -+ -+#if defined(RSSIAVG) -+#define RSSIAVG_LEN 8 -+#define RSSICACHE_LEN 8 -+ -+typedef struct wl_rssi_cache { -+ struct wl_rssi_cache *next; -+ int dirty; -+ struct ether_addr BSSID; -+ int16 RSSI[RSSIAVG_LEN]; -+} wl_rssi_cache_t; -+ -+typedef struct wl_rssi_cache_ctrl { -+ wl_rssi_cache_t *m_cache_head; -+} wl_rssi_cache_ctrl_t; -+ -+void wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); -+void wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); -+void wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); -+void wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list); -+void wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net); -+int16 wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr); -+#endif -+ -+#if defined(RSSIOFFSET) -+#define RSSI_OFFSET 5 -+#define RSSI_MAX -80 -+#define RSSI_MIN -94 -+#define RSSI_INT ((RSSI_MAX-RSSI_MIN)/RSSI_OFFSET) -+#define BCM4330_CHIP_ID 0x4330 -+#define BCM4330B2_CHIP_REV 4 -+int wl_update_rssi_offset(int rssi); -+#endif -+ -+#if defined(BSSCACHE) -+#define BSSCACHE_LEN 8 -+#define BSSCACHE_TIME 15000 -+ -+typedef struct wl_bss_cache { -+ struct wl_bss_cache *next; -+ int dirty; -+ wl_scan_results_t results; -+} wl_bss_cache_t; -+ -+typedef struct wl_bss_cache_ctrl { -+ wl_bss_cache_t *m_cache_head; -+ struct timer_list *m_timer; -+ int m_timer_expired; -+} wl_bss_cache_ctrl_t; -+ -+void wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); -+void wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); -+void wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); -+void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list); -+void wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off); -+void wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl); -+void wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl); -+#endif -+ -+#if defined(CONFIG_WIFI_CONTROL_FUNC) -+int wl_android_wifictrl_func_add(void); -+void wl_android_wifictrl_func_del(void); -+void* wl_android_prealloc(int section, unsigned long size); -+ -+int wifi_get_irq_number(unsigned long *irq_flags_ptr); -+int wifi_set_power(int on, unsigned long msec); -+int wifi_get_mac_addr(unsigned char *buf); -+void *wifi_get_country_code(char *ccode); -+#endif /* CONFIG_WIFI_CONTROL_FUNC */ -diff --git a/drivers/net/wireless/ap6210/wl_cfg80211.c b/drivers/net/wireless/ap6210/wl_cfg80211.c -new file mode 100644 -index 0000000..1ebce14 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_cfg80211.c -@@ -0,0 +1,10129 @@ -+/* -+ * Linux cfg80211 driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfg80211.c 374275 2012-12-12 11:44:18Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#ifdef PROP_TXSTATUS -+#include -+#endif -+#ifdef BCMWAPI_WPI -+/* these items should evetually go into wireless.h of the linux system headfile dir */ -+#ifndef IW_ENCODE_ALG_SM4 -+#define IW_ENCODE_ALG_SM4 0x20 -+#endif -+ -+#ifndef IW_AUTH_WAPI_ENABLED -+#define IW_AUTH_WAPI_ENABLED 0x20 -+#endif -+ -+#ifndef IW_AUTH_WAPI_VERSION_1 -+#define IW_AUTH_WAPI_VERSION_1 0x00000008 -+#endif -+ -+#ifndef IW_AUTH_CIPHER_SMS4 -+#define IW_AUTH_CIPHER_SMS4 0x00000020 -+#endif -+ -+#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK -+#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 -+#endif -+ -+#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT -+#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 -+#endif -+#endif /* BCMWAPI_WPI */ -+ -+#ifdef BCMWAPI_WPI -+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) -+#else /* BCMWAPI_WPI */ -+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -+#endif /* BCMWAPI_WPI */ -+#ifdef WL11U -+#ifndef WL_ENABLE_P2P_IF -+#error "You should enable WL_ENABLE_P2P_IF and Only supported in JB" -+#endif -+#endif /* WL11U */ -+ -+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -+ -+static struct device *cfg80211_parent_dev = NULL; -+struct wl_priv *wlcfg_drv_priv = NULL; -+u32 wl_dbg_level = WL_DBG_ERR; -+ -+#define MAX_WAIT_TIME 1500 -+ -+#ifdef VSDB -+/* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */ -+#define DEFAULT_SLEEP_TIME_VSDB 200 -+#define OFF_CHAN_TIME_THRESHOLD_MS 200 -+ -+/* if sta is connected or connecting, sleep for a while before retry af tx or finding a peer */ -+#define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl) \ -+ do { \ -+ if (wl_get_drv_status(wl, CONNECTED, wl_to_prmry_ndev(wl)) || \ -+ wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) { \ -+ msleep(DEFAULT_SLEEP_TIME_VSDB); \ -+ } \ -+ } while (0) -+#else /* VSDB */ -+/* if not VSDB, do nothing */ -+#define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl) -+#endif /* VSDB */ -+ -+#ifdef WL_CFG80211_SYNC_GON -+#define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) \ -+ (wl_get_drv_status_all(wl, SENDING_ACT_FRM) || \ -+ wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) -+#else -+#define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) wl_get_drv_status_all(wl, SENDING_ACT_FRM) -+#endif /* WL_CFG80211_SYNC_GON */ -+ -+#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL -+ -+ -+#define DNGL_FUNC(func, parameters) func parameters; -+#define COEX_DHCP -+ -+#define WLAN_EID_SSID 0 -+#define CH_MIN_5G_CHANNEL 34 -+#define CH_MIN_2G_CHANNEL 1 -+ -+/* This is to override regulatory domains defined in cfg80211 module (reg.c) -+ * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN -+ * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165). -+ * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels. -+ * All the chnages in world regulatory domain are to be done here. -+ */ -+static const struct ieee80211_regdomain brcm_regdom = { -+ .n_reg_rules = 4, -+ .alpha2 = "99", -+ .reg_rules = { -+ /* IEEE 802.11b/g, channels 1..11 */ -+ REG_RULE(2412-10, 2472+10, 40, 6, 20, 0), -+ /* If any */ -+ /* IEEE 802.11 channel 14 - Only JP enables -+ * this and for 802.11b only -+ */ -+ REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), -+ /* IEEE 802.11a, channel 36..64 */ -+ REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), -+ /* IEEE 802.11a, channel 100..165 */ -+ REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } -+}; -+ -+ -+/* Data Element Definitions */ -+#define WPS_ID_CONFIG_METHODS 0x1008 -+#define WPS_ID_REQ_TYPE 0x103A -+#define WPS_ID_DEVICE_NAME 0x1011 -+#define WPS_ID_VERSION 0x104A -+#define WPS_ID_DEVICE_PWD_ID 0x1012 -+#define WPS_ID_REQ_DEV_TYPE 0x106A -+#define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053 -+#define WPS_ID_PRIM_DEV_TYPE 0x1054 -+ -+/* Device Password ID */ -+#define DEV_PW_DEFAULT 0x0000 -+#define DEV_PW_USER_SPECIFIED 0x0001, -+#define DEV_PW_MACHINE_SPECIFIED 0x0002 -+#define DEV_PW_REKEY 0x0003 -+#define DEV_PW_PUSHBUTTON 0x0004 -+#define DEV_PW_REGISTRAR_SPECIFIED 0x0005 -+ -+/* Config Methods */ -+#define WPS_CONFIG_USBA 0x0001 -+#define WPS_CONFIG_ETHERNET 0x0002 -+#define WPS_CONFIG_LABEL 0x0004 -+#define WPS_CONFIG_DISPLAY 0x0008 -+#define WPS_CONFIG_EXT_NFC_TOKEN 0x0010 -+#define WPS_CONFIG_INT_NFC_TOKEN 0x0020 -+#define WPS_CONFIG_NFC_INTERFACE 0x0040 -+#define WPS_CONFIG_PUSHBUTTON 0x0080 -+#define WPS_CONFIG_KEYPAD 0x0100 -+#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280 -+#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480 -+#define WPS_CONFIG_VIRT_DISPLAY 0x2008 -+#define WPS_CONFIG_PHY_DISPLAY 0x4008 -+ -+#define PM_BLOCK 1 -+#define PM_ENABLE 0 -+/* -+ * cfg80211_ops api/callback list -+ */ -+static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, -+ const struct ether_addr *sa, const struct ether_addr *bssid, -+ u8 **pheader, u32 *body_len, u8 *pbody); -+static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, -+ struct cfg80211_scan_request *request, -+ struct cfg80211_ssid *this_ssid); -+static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, -+ struct cfg80211_scan_request *request); -+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -+static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_ibss_params *params); -+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, -+ struct net_device *dev); -+static s32 wl_cfg80211_get_station(struct wiphy *wiphy, -+ struct net_device *dev, u8 *mac, -+ struct station_info *sinfo); -+static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, -+ struct net_device *dev, bool enabled, -+ s32 timeout); -+static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, -+ u16 reason_code); -+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, -+ enum nl80211_tx_power_setting type, -+ s32 dbm); -+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); -+static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, -+ struct net_device *dev, -+ u8 key_idx, bool unicast, bool multicast); -+static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr, -+ struct key_params *params); -+static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr); -+static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr, -+ void *cookie, void (*callback) (void *cookie, -+ struct key_params *params)); -+static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, -+ struct net_device *dev, u8 key_idx); -+static s32 wl_cfg80211_resume(struct wiphy *wiphy); -+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ -+ 2, 0)) -+static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, -+ struct net_device *dev, u64 cookie); -+static s32 wl_cfg80211_del_station(struct wiphy *wiphy, -+ struct net_device *ndev, u8* mac_addr); -+#endif -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -+static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -+#else -+static s32 wl_cfg80211_suspend(struct wiphy *wiphy); -+#endif -+static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_pmksa *pmksa); -+static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_pmksa *pmksa); -+static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, -+ struct net_device *dev); -+static s32 wl_notify_escan_complete(struct wl_priv *wl, -+ struct net_device *ndev, bool aborted, bool fw_abort); -+/* -+ * event & event Q handlers for cfg80211 interfaces -+ */ -+static s32 wl_create_event_handler(struct wl_priv *wl); -+static void wl_destroy_event_handler(struct wl_priv *wl); -+static s32 wl_event_handler(void *data); -+static void wl_init_eq(struct wl_priv *wl); -+static void wl_flush_eq(struct wl_priv *wl); -+static unsigned long wl_lock_eq(struct wl_priv *wl); -+static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags); -+static void wl_init_eq_lock(struct wl_priv *wl); -+static void wl_init_event_handler(struct wl_priv *wl); -+static struct wl_event_q *wl_deq_event(struct wl_priv *wl); -+static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type, -+ const wl_event_msg_t *msg, void *data); -+static void wl_put_event(struct wl_event_q *e); -+static void wl_wakeup_event(struct wl_priv *wl); -+static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+static s32 wl_notify_connect_status(struct wl_priv *wl, -+ struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+static s32 wl_notify_roaming_status(struct wl_priv *wl, -+ struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data, bool completed); -+static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+#ifdef WL_SCHED_SCAN -+static s32 -+wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+#endif /* WL_SCHED_SCAN */ -+#ifdef PNO_SUPPORT -+static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+#endif /* PNO_SUPPORT */ -+static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info, -+ enum wl_status state, bool set); -+/* -+ * register/deregister parent device -+ */ -+static void wl_cfg80211_clear_parent_dev(void); -+ -+/* -+ * ioctl utilites -+ */ -+ -+/* -+ * cfg80211 set_wiphy_params utilities -+ */ -+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold); -+static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold); -+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l); -+ -+/* -+ * wl profile utilities -+ */ -+static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data, s32 item); -+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item); -+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev); -+ -+/* -+ * cfg80211 connect utilites -+ */ -+static s32 wl_set_wpa_version(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+static s32 wl_set_auth_type(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+static s32 wl_set_set_cipher(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+static s32 wl_set_key_mgmt(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+static s32 wl_set_set_sharedkey(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+#ifdef BCMWAPI_WPI -+static s32 wl_set_set_wapi_ie(struct net_device *dev, -+ struct cfg80211_connect_params *sme); -+#endif -+static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev); -+static void wl_ch_to_chanspec(int ch, -+ struct wl_join_params *join_params, size_t *join_params_size); -+ -+/* -+ * information element utilities -+ */ -+static void wl_rst_ie(struct wl_priv *wl); -+static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v); -+static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size); -+static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size); -+static u32 wl_get_ielen(struct wl_priv *wl); -+ -+#ifdef WL11U -+bcm_tlv_t * -+wl_cfg80211_find_interworking_ie(u8 *parse, u32 len); -+static s32 -+wl_cfg80211_add_iw_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, -+ uint8 ie_id, uint8 *data, uint8 data_len); -+#endif /* WL11U */ -+ -+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev); -+static void wl_free_wdev(struct wl_priv *wl); -+static int -+wl_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); -+ -+static s32 wl_inform_bss(struct wl_priv *wl); -+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done); -+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done); -+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy); -+s32 wl_cfg80211_channel_to_freq(u32 channel); -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+static void wl_cfg80211_work_handler(struct work_struct *work); -+static void wl_cfg80211_scan_supp_timerfunc(ulong data); -+#endif /* DHCP_SCAN_SUPPRESS */ -+ -+static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, const u8 *mac_addr, -+ struct key_params *params); -+/* -+ * key indianess swap utilities -+ */ -+static void swap_key_from_BE(struct wl_wsec_key *key); -+static void swap_key_to_BE(struct wl_wsec_key *key); -+ -+/* -+ * wl_priv memory init/deinit utilities -+ */ -+static s32 wl_init_priv_mem(struct wl_priv *wl); -+static void wl_deinit_priv_mem(struct wl_priv *wl); -+ -+static void wl_delay(u32 ms); -+ -+/* -+ * ibss mode utilities -+ */ -+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev); -+static __used bool wl_is_ibssstarter(struct wl_priv *wl); -+ -+/* -+ * link up/down , default configuration utilities -+ */ -+static s32 __wl_cfg80211_up(struct wl_priv *wl); -+static s32 __wl_cfg80211_down(struct wl_priv *wl); -+static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); -+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev); -+static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e); -+static void wl_link_up(struct wl_priv *wl); -+static void wl_link_down(struct wl_priv *wl); -+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype); -+static void wl_init_conf(struct wl_conf *conf); -+ -+/* -+ * iscan handler -+ */ -+static void wl_iscan_timer(unsigned long data); -+static void wl_term_iscan(struct wl_priv *wl); -+static s32 wl_init_scan(struct wl_priv *wl); -+static s32 wl_iscan_thread(void *data); -+static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, -+ u16 action); -+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request); -+static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan); -+static s32 wl_invoke_iscan(struct wl_priv *wl); -+static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, -+ struct wl_scan_results **bss_list); -+static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted); -+static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan); -+static s32 wl_iscan_done(struct wl_priv *wl); -+static s32 wl_iscan_pending(struct wl_priv *wl); -+static s32 wl_iscan_inprogress(struct wl_priv *wl); -+static s32 wl_iscan_aborted(struct wl_priv *wl); -+ -+/* -+ * find most significant bit set -+ */ -+static __used u32 wl_find_msb(u16 bit16); -+ -+/* -+ * rfkill support -+ */ -+static int wl_setup_rfkill(struct wl_priv *wl, bool setup); -+static int wl_rfkill_set(void *data, bool blocked); -+ -+static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel, -+ int nprobes, int *out_params_size); -+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac); -+ -+/* -+ * Some external functions, TODO: move them to dhd_linux.h -+ */ -+int dhd_add_monitor(char *name, struct net_device **new_ndev); -+int dhd_del_monitor(struct net_device *ndev); -+int dhd_monitor_init(void *dhd_pub); -+int dhd_monitor_uninit(void); -+int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); -+ -+ -+ -+#define CHECK_SYS_UP(wlpriv) \ -+do { \ -+ struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \ -+ if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \ -+ AP6210_DEBUG("device is not ready\n"); \ -+ return -EIO; \ -+ } \ -+} while (0) -+ -+ -+#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \ -+ (akm) == RSN_AKM_UNSPECIFIED || \ -+ (akm) == RSN_AKM_PSK) -+ -+ -+extern int dhd_wait_pend8021x(struct net_device *dev); -+#ifdef PROP_TXSTATUS_VSDB -+extern int disable_proptx; -+extern int dhd_wlfc_init(dhd_pub_t *dhd); -+extern void dhd_wlfc_deinit(dhd_pub_t *dhd); -+#endif /* PROP_TXSTATUS_VSDB */ -+ -+#if (WL_DBG_LEVEL > 0) -+#define WL_DBG_ESTR_MAX 50 -+static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = { -+ "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND", -+ "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC", -+ "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END", -+ "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM", -+ "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH", -+ "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND", -+ "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND", -+ "PFN_NET_LOST", -+ "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START", -+ "IBSS_ASSOC", -+ "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT", -+ "PROBREQ_MSG", -+ "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED", -+ "EXCEEDED_MEDIUM_TIME", "ICV_ERROR", -+ "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE", -+ "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE", -+ "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG", -+ "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND", -+ "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED", -+ "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT", -+ "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE", -+ "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP", -+ "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE" -+}; -+#endif /* WL_DBG_LEVEL */ -+ -+#define CHAN2G(_channel, _freq, _flags) { \ -+ .band = IEEE80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+#define CHAN5G(_channel, _flags) { \ -+ .band = IEEE80211_BAND_5GHZ, \ -+ .center_freq = 5000 + (5 * (_channel)), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2) -+#define RATETAB_ENT(_rateid, _flags) \ -+ { \ -+ .bitrate = RATE_TO_BASE100KBPS(_rateid), \ -+ .hw_value = (_rateid), \ -+ .flags = (_flags), \ -+ } -+ -+static struct ieee80211_rate __wl_rates[] = { -+ RATETAB_ENT(WLC_RATE_1M, 0), -+ RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), -+ RATETAB_ENT(WLC_RATE_6M, 0), -+ RATETAB_ENT(WLC_RATE_9M, 0), -+ RATETAB_ENT(WLC_RATE_12M, 0), -+ RATETAB_ENT(WLC_RATE_18M, 0), -+ RATETAB_ENT(WLC_RATE_24M, 0), -+ RATETAB_ENT(WLC_RATE_36M, 0), -+ RATETAB_ENT(WLC_RATE_48M, 0), -+ RATETAB_ENT(WLC_RATE_54M, 0) -+}; -+ -+#define wl_a_rates (__wl_rates + 4) -+#define wl_a_rates_size 8 -+#define wl_g_rates (__wl_rates + 0) -+#define wl_g_rates_size 12 -+ -+static struct ieee80211_channel __wl_2ghz_channels[] = { -+ CHAN2G(1, 2412, 0), -+ CHAN2G(2, 2417, 0), -+ CHAN2G(3, 2422, 0), -+ CHAN2G(4, 2427, 0), -+ CHAN2G(5, 2432, 0), -+ CHAN2G(6, 2437, 0), -+ CHAN2G(7, 2442, 0), -+ CHAN2G(8, 2447, 0), -+ CHAN2G(9, 2452, 0), -+ CHAN2G(10, 2457, 0), -+ CHAN2G(11, 2462, 0), -+ CHAN2G(12, 2467, 0), -+ CHAN2G(13, 2472, 0), -+ CHAN2G(14, 2484, 0) -+}; -+ -+static struct ieee80211_channel __wl_5ghz_a_channels[] = { -+ CHAN5G(34, 0), CHAN5G(36, 0), -+ CHAN5G(38, 0), CHAN5G(40, 0), -+ CHAN5G(42, 0), CHAN5G(44, 0), -+ CHAN5G(46, 0), CHAN5G(48, 0), -+ CHAN5G(52, 0), CHAN5G(56, 0), -+ CHAN5G(60, 0), CHAN5G(64, 0), -+ CHAN5G(100, 0), CHAN5G(104, 0), -+ CHAN5G(108, 0), CHAN5G(112, 0), -+ CHAN5G(116, 0), CHAN5G(120, 0), -+ CHAN5G(124, 0), CHAN5G(128, 0), -+ CHAN5G(132, 0), CHAN5G(136, 0), -+ CHAN5G(140, 0), CHAN5G(149, 0), -+ CHAN5G(153, 0), CHAN5G(157, 0), -+ CHAN5G(161, 0), CHAN5G(165, 0) -+}; -+ -+static struct ieee80211_supported_band __wl_band_2ghz = { -+ .band = IEEE80211_BAND_2GHZ, -+ .channels = __wl_2ghz_channels, -+ .n_channels = ARRAY_SIZE(__wl_2ghz_channels), -+ .bitrates = wl_g_rates, -+ .n_bitrates = wl_g_rates_size -+}; -+ -+static struct ieee80211_supported_band __wl_band_5ghz_a = { -+ .band = IEEE80211_BAND_5GHZ, -+ .channels = __wl_5ghz_a_channels, -+ .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), -+ .bitrates = wl_a_rates, -+ .n_bitrates = wl_a_rates_size -+}; -+ -+static const u32 __wl_cipher_suites[] = { -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ WLAN_CIPHER_SUITE_AES_CMAC, -+#ifdef BCMWAPI_WPI -+ WLAN_CIPHER_SUITE_SMS4 -+#endif -+}; -+ -+ -+/* IOCtl version read from targeted driver */ -+static int ioctl_version; -+ -+/* Return a new chanspec given a legacy chanspec -+ * Returns INVCHANSPEC on error -+ */ -+static chanspec_t -+wl_chspec_from_legacy(chanspec_t legacy_chspec) -+{ -+ chanspec_t chspec; -+ -+ /* get the channel number */ -+ chspec = LCHSPEC_CHANNEL(legacy_chspec); -+ -+ /* convert the band */ -+ if (LCHSPEC_IS2G(legacy_chspec)) { -+ chspec |= WL_CHANSPEC_BAND_2G; -+ } else { -+ chspec |= WL_CHANSPEC_BAND_5G; -+ } -+ -+ /* convert the bw and sideband */ -+ if (LCHSPEC_IS20(legacy_chspec)) { -+ chspec |= WL_CHANSPEC_BW_20; -+ } else { -+ chspec |= WL_CHANSPEC_BW_40; -+ if (LCHSPEC_CTL_SB(legacy_chspec) == WL_LCHANSPEC_CTL_SB_LOWER) { -+ chspec |= WL_CHANSPEC_CTL_SB_L; -+ } else { -+ chspec |= WL_CHANSPEC_CTL_SB_U; -+ } -+ } -+ -+ if (wf_chspec_malformed(chspec)) { -+ AP6210_ERR("wl_chspec_from_legacy: output chanspec (0x%04X) malformed\n", -+ chspec); -+ return INVCHANSPEC; -+ } -+ -+ return chspec; -+} -+ -+/* Return a legacy chanspec given a new chanspec -+ * Returns INVCHANSPEC on error -+ */ -+static chanspec_t -+wl_chspec_to_legacy(chanspec_t chspec) -+{ -+ chanspec_t lchspec; -+ -+ if (wf_chspec_malformed(chspec)) { -+ AP6210_ERR("wl_chspec_to_legacy: input chanspec (0x%04X) malformed\n", -+ chspec); -+ return INVCHANSPEC; -+ } -+ -+ /* get the channel number */ -+ lchspec = CHSPEC_CHANNEL(chspec); -+ -+ /* convert the band */ -+ if (CHSPEC_IS2G(chspec)) { -+ lchspec |= WL_LCHANSPEC_BAND_2G; -+ } else { -+ lchspec |= WL_LCHANSPEC_BAND_5G; -+ } -+ -+ /* convert the bw and sideband */ -+ if (CHSPEC_IS20(chspec)) { -+ lchspec |= WL_LCHANSPEC_BW_20; -+ lchspec |= WL_LCHANSPEC_CTL_SB_NONE; -+ } else if (CHSPEC_IS40(chspec)) { -+ lchspec |= WL_LCHANSPEC_BW_40; -+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) { -+ lchspec |= WL_LCHANSPEC_CTL_SB_LOWER; -+ } else { -+ lchspec |= WL_LCHANSPEC_CTL_SB_UPPER; -+ } -+ } else { -+ /* cannot express the bandwidth */ -+ char chanbuf[CHANSPEC_STR_LEN]; -+ AP6210_ERR( -+ "wl_chspec_to_legacy: unable to convert chanspec %s (0x%04X) " -+ "to pre-11ac format\n", -+ wf_chspec_ntoa(chspec, chanbuf), chspec); -+ return INVCHANSPEC; -+ } -+ -+ return lchspec; -+} -+ -+/* given a chanspec value, do the endian and chanspec version conversion to -+ * a chanspec_t value -+ * Returns INVCHANSPEC on error -+ */ -+static chanspec_t -+wl_chspec_host_to_driver(chanspec_t chanspec) -+{ -+ if (ioctl_version == 1) { -+ chanspec = wl_chspec_to_legacy(chanspec); -+ if (chanspec == INVCHANSPEC) { -+ return chanspec; -+ } -+ } -+ chanspec = htodchanspec(chanspec); -+ -+ return chanspec; -+} -+ -+/* given a channel value, do the endian and chanspec version conversion to -+ * a chanspec_t value -+ * Returns INVCHANSPEC on error -+ */ -+chanspec_t -+wl_ch_host_to_driver(u16 channel) -+{ -+ -+ chanspec_t chanspec; -+ -+ chanspec = channel & WL_CHANSPEC_CHAN_MASK; -+ -+ if (channel <= CH_MAX_2G_CHANNEL) -+ chanspec |= WL_CHANSPEC_BAND_2G; -+ else -+ chanspec |= WL_CHANSPEC_BAND_5G; -+ -+ chanspec |= WL_CHANSPEC_BW_20; -+ chanspec |= WL_CHANSPEC_CTL_SB_NONE; -+ -+ return wl_chspec_host_to_driver(chanspec); -+} -+ -+/* given a chanspec value from the driver, do the endian and chanspec version conversion to -+ * a chanspec_t value -+ * Returns INVCHANSPEC on error -+ */ -+static chanspec_t -+wl_chspec_driver_to_host(chanspec_t chanspec) -+{ -+ chanspec = dtohchanspec(chanspec); -+ if (ioctl_version == 1) { -+ chanspec = wl_chspec_from_legacy(chanspec); -+ } -+ -+ return chanspec; -+} -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | -+ BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+static void swap_key_from_BE(struct wl_wsec_key *key) -+{ -+ key->index = htod32(key->index); -+ key->len = htod32(key->len); -+ key->algo = htod32(key->algo); -+ key->flags = htod32(key->flags); -+ key->rxiv.hi = htod32(key->rxiv.hi); -+ key->rxiv.lo = htod16(key->rxiv.lo); -+ key->iv_initialized = htod32(key->iv_initialized); -+} -+ -+static void swap_key_to_BE(struct wl_wsec_key *key) -+{ -+ key->index = dtoh32(key->index); -+ key->len = dtoh32(key->len); -+ key->algo = dtoh32(key->algo); -+ key->flags = dtoh32(key->flags); -+ key->rxiv.hi = dtoh32(key->rxiv.hi); -+ key->rxiv.lo = dtoh16(key->rxiv.lo); -+ key->iv_initialized = dtoh32(key->iv_initialized); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) -+/* For debug: Dump the contents of the encoded wps ie buffe */ -+static void -+wl_validate_wps_ie(char *wps_ie, s32 wps_ie_len, bool *pbc) -+{ -+ #define WPS_IE_FIXED_LEN 6 -+ u16 len; -+ u8 *subel = NULL; -+ u16 subelt_id; -+ u16 subelt_len; -+ u16 val; -+ u8 *valptr = (uint8*) &val; -+ if (wps_ie == NULL || wps_ie_len < WPS_IE_FIXED_LEN) { -+ AP6210_ERR("invalid argument : NULL\n")); -+ return; -+ } -+ len = (u16)wps_ie[TLV_LEN_OFF]; -+ -+ if (len > wps_ie_len) { -+ AP6210_ERR("invalid length len %d, wps ie len %d\n", len, wps_ie_len); -+ return; -+ } -+ AP6210_DEBUG("wps_ie len=%d\n", len); -+ len -= 4; /* for the WPS IE's OUI, oui_type fields */ -+ subel = wps_ie + WPS_IE_FIXED_LEN; -+ while (len >= 4) { /* must have attr id, attr len fields */ -+ valptr[0] = *subel++; -+ valptr[1] = *subel++; -+ subelt_id = HTON16(val); -+ -+ valptr[0] = *subel++; -+ valptr[1] = *subel++; -+ subelt_len = HTON16(val); -+ -+ len -= 4; /* for the attr id, attr len fields */ -+ len -= subelt_len; /* for the remaining fields in this attribute */ -+ AP6210_DEBUG(" subel=%p, subelt_id=0x%x subelt_len=%u\n", -+ subel, subelt_id, subelt_len); -+ -+ if (subelt_id == WPS_ID_VERSION) { -+ AP6210_DEBUG(" attr WPS_ID_VERSION: %u\n", *subel); -+ } else if (subelt_id == WPS_ID_REQ_TYPE) { -+ AP6210_DEBUG(" attr WPS_ID_REQ_TYPE: %u\n", *subel); -+ } else if (subelt_id == WPS_ID_CONFIG_METHODS) { -+ valptr[0] = *subel; -+ valptr[1] = *(subel + 1); -+ AP6210_DEBUG(" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)); -+ } else if (subelt_id == WPS_ID_DEVICE_NAME) { -+ char devname[100]; -+ memcpy(devname, subel, subelt_len); -+ devname[subelt_len] = '\0'; -+ AP6210_DEBUG(" attr WPS_ID_DEVICE_NAME: %s (len %u)\n", -+ devname, subelt_len); -+ } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) { -+ valptr[0] = *subel; -+ valptr[1] = *(subel + 1); -+ AP6210_DEBUG(" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)); -+ *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false; -+ } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) { -+ valptr[0] = *subel; -+ valptr[1] = *(subel + 1); -+ AP6210_DEBUG(" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)); -+ valptr[0] = *(subel + 6); -+ valptr[1] = *(subel + 7); -+ AP6210_DEBUG(" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)); -+ } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) { -+ valptr[0] = *subel; -+ valptr[1] = *(subel + 1); -+ AP6210_DEBUG(" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)); -+ valptr[0] = *(subel + 6); -+ valptr[1] = *(subel + 7); -+ AP6210_DEBUG(" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)); -+ } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) { -+ valptr[0] = *subel; -+ valptr[1] = *(subel + 1); -+ AP6210_DEBUG(" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS" -+ ": cat=%u\n", HTON16(val)); -+ } else { -+ AP6210_DEBUG(" unknown attr 0x%x\n", subelt_id); -+ } -+ -+ subel += subelt_len; -+ } -+} -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */ -+ -+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy) -+{ -+ chanspec_t chspec; -+ int err = 0; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *dev = wl_to_prmry_ndev(wl); -+ struct ether_addr bssid; -+ struct wl_bss_info *bss = NULL; -+ -+ if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) { -+ /* STA interface is not associated. So start the new interface on a temp -+ * channel . Later proper channel will be applied by the above framework -+ * via set_channel (cfg80211 API). -+ */ -+ AP6210_DEBUG("Not associated. Return a temp channel. \n"); -+ return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN); -+ } -+ -+ -+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); -+ if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf, -+ WL_EXTRA_BUF_MAX, false))) { -+ AP6210_ERR("Failed to get associated bss info, use temp channel \n"); -+ chspec = wl_ch_host_to_driver(WL_P2P_TEMP_CHAN); -+ } -+ else { -+ bss = (struct wl_bss_info *) (wl->extra_buf + 4); -+ chspec = bss->chanspec; -+ AP6210_DEBUG("Valid BSS Found. chanspec:%d \n", chspec); -+ } -+ return chspec; -+} -+ -+static struct net_device* wl_cfg80211_add_monitor_if(char *name) -+{ -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+ AP6210_DEBUG("wl_cfg80211_add_monitor_if: No more support monitor interface\n"); -+ return ERR_PTR(-EOPNOTSUPP); -+#else -+ struct net_device* ndev = NULL; -+ -+ dhd_add_monitor(name, &ndev); -+ AP6210_DEBUG("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev); -+ return ndev; -+#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */ -+} -+ -+static struct net_device * -+wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, -+ enum nl80211_iftype type, u32 *flags, -+ struct vif_params *params) -+{ -+ s32 err; -+ s32 timeout = -1; -+ s32 wlif_type = -1; -+ s32 mode = 0; -+ s32 val = 0; -+ s32 dhd_mode = 0; -+ chanspec_t chspec; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *_ndev; -+ struct ether_addr primary_mac; -+ int (*net_attach)(void *dhdp, int ifidx); -+ bool rollback_lock = false; -+#ifdef PROP_TXSTATUS_VSDB -+ s32 up = 1; -+ dhd_pub_t *dhd; -+#endif /* PROP_TXSTATUS_VSDB */ -+ -+ if (!wl) -+ return ERR_PTR(-EINVAL); -+ -+#ifdef PROP_TXSTATUS_VSDB -+ dhd = (dhd_pub_t *)(wl->pub); -+#endif /* PROP_TXSTATUS_VSDB */ -+ -+ -+ /* Use primary I/F for sending cmds down to firmware */ -+ _ndev = wl_to_prmry_ndev(wl); -+ -+ AP6210_DEBUG("if name: %s, type: %d\n", name, type); -+ switch (type) { -+ case NL80211_IFTYPE_ADHOC: -+ case NL80211_IFTYPE_AP_VLAN: -+ case NL80211_IFTYPE_WDS: -+ case NL80211_IFTYPE_MESH_POINT: -+ AP6210_ERR("Unsupported interface type\n"); -+ mode = WL_MODE_IBSS; -+ return NULL; -+ case NL80211_IFTYPE_MONITOR: -+ return wl_cfg80211_add_monitor_if(name); -+ case NL80211_IFTYPE_P2P_CLIENT: -+ case NL80211_IFTYPE_STATION: -+ wlif_type = WL_P2P_IF_CLIENT; -+ mode = WL_MODE_BSS; -+ break; -+ case NL80211_IFTYPE_P2P_GO: -+ case NL80211_IFTYPE_AP: -+ wlif_type = WL_P2P_IF_GO; -+ mode = WL_MODE_AP; -+ break; -+ default: -+ AP6210_ERR("Unsupported interface type\n"); -+ return NULL; -+ break; -+ } -+ -+ if (!name) { -+ AP6210_ERR("name is NULL\n"); -+ return NULL; -+ } -+ if (wl->p2p_supported && (wlif_type != -1)) { -+ if (wl_get_p2p_status(wl, IF_DELETING)) { -+ /* wait till IF_DEL is complete -+ * release the lock for the unregister to proceed -+ */ -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = true; -+ } -+ AP6210_DEBUG("%s: Released the lock and wait till IF_DEL is complete\n", -+ __func__); -+ timeout = wait_event_interruptible_timeout(wl->netif_change_event, -+ (wl_get_p2p_status(wl, IF_DELETING) == false), -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ -+ /* put back the rtnl_lock again */ -+ if (rollback_lock) { -+ rtnl_lock(); -+ rollback_lock = false; -+ } -+ if (timeout > 0) { -+ AP6210_ERR("IF DEL is Success\n"); -+ -+ } else { -+ AP6210_ERR("timeount < 0, return -EAGAIN\n"); -+ return ERR_PTR(-EAGAIN); -+ } -+ /* It should be now be safe to put this check here since we are sure -+ * by now netdev_notifier (unregister) would have been called -+ */ -+ if (wl->iface_cnt == IFACE_MAX_CNT) -+ return ERR_PTR(-ENOMEM); -+ } -+ -+#ifdef PROP_TXSTATUS_VSDB -+ if (!dhd) -+ return ERR_PTR(-ENODEV); -+#endif /* PROP_TXSTATUS_VSDB */ -+ if (!wl->p2p) -+ return ERR_PTR(-ENODEV); -+ -+ if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) { -+ p2p_on(wl) = true; -+ wl_cfgp2p_set_firm_p2p(wl); -+ wl_cfgp2p_init_discovery(wl); -+ get_primary_mac(wl, &primary_mac); -+ wl_cfgp2p_generate_bss_mac(&primary_mac, -+ &wl->p2p->dev_addr, &wl->p2p->int_addr); -+ } -+ -+ memset(wl->p2p->vir_ifname, 0, IFNAMSIZ); -+ strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1); -+ -+ wl_notify_escan_complete(wl, _ndev, true, true); -+#ifdef PROP_TXSTATUS_VSDB -+ if (!wl->wlfc_on && !disable_proptx) { -+ dhd->wlfc_enabled = true; -+ dhd_wlfc_init(dhd); -+ err = wldev_ioctl(_ndev, WLC_UP, &up, sizeof(s32), true); -+ if (err < 0) -+ AP6210_ERR("WLC_UP return err:%d\n", err); -+ wl->wlfc_on = true; -+ } -+#endif /* PROP_TXSTATUS_VSDB */ -+ -+ /* In concurrency case, STA may be already associated in a particular channel. -+ * so retrieve the current channel of primary interface and then start the virtual -+ * interface on that. -+ */ -+ chspec = wl_cfg80211_get_shared_freq(wiphy); -+ -+ /* For P2P mode, use P2P-specific driver features to create the -+ * bss: "wl p2p_ifadd" -+ */ -+ wl_set_p2p_status(wl, IF_ADD); -+ if (wlif_type == WL_P2P_IF_GO) -+ wldev_iovar_setint(_ndev, "mpc", 0); -+ err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); -+ -+ if (unlikely(err)) { -+ AP6210_ERR(" virtual iface add failed (%d) \n", err); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ timeout = wait_event_interruptible_timeout(wl->netif_change_event, -+ (wl_get_p2p_status(wl, IF_ADD) == false), -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) { -+ -+ struct wireless_dev *vwdev; -+ vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL); -+ if (unlikely(!vwdev)) { -+ AP6210_ERR("Could not allocate wireless device\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ vwdev->wiphy = wl->wdev->wiphy; -+ AP6210_DEBUG(" virtual interface(%s) is created memalloc done \n", -+ wl->p2p->vir_ifname); -+ vwdev->iftype = type; -+ _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); -+ _ndev->ieee80211_ptr = vwdev; -+ SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy)); -+ vwdev->netdev = _ndev; -+ wl_set_drv_status(wl, READY, _ndev); -+ wl->p2p->vif_created = true; -+ wl_set_mode_by_netdev(wl, _ndev, mode); -+ net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION); -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = true; -+ } -+ if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) { -+ wl_alloc_netinfo(wl, _ndev, vwdev, mode, PM_ENABLE); -+ val = 1; -+ /* Disable firmware roaming for P2P interface */ -+ wldev_iovar_setint(_ndev, "roam_off", val); -+ AP6210_ERR(" virtual interface(%s) is " -+ "created net attach done\n", wl->p2p->vir_ifname); -+ if (mode == WL_MODE_AP) -+ wl_set_drv_status(wl, CONNECTED, _ndev); -+ if (type == NL80211_IFTYPE_P2P_CLIENT) -+ dhd_mode = DHD_FLAG_P2P_GC_MODE; -+ else if (type == NL80211_IFTYPE_P2P_GO) -+ dhd_mode = DHD_FLAG_P2P_GO_MODE; -+ DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode)); -+ } else { -+ /* put back the rtnl_lock again */ -+ if (rollback_lock) -+ rtnl_lock(); -+ goto fail; -+ } -+ /* put back the rtnl_lock again */ -+ if (rollback_lock) -+ rtnl_lock(); -+ return _ndev; -+ -+ } else { -+ wl_clr_p2p_status(wl, IF_ADD); -+ AP6210_ERR(" virtual interface(%s) is not created \n", wl->p2p->vir_ifname); -+ memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); -+ wl->p2p->vif_created = false; -+#ifdef PROP_TXSTATUS_VSDB -+ if (dhd->wlfc_enabled && wl->wlfc_on) { -+ dhd->wlfc_enabled = false; -+ dhd_wlfc_deinit(dhd); -+ wl->wlfc_on = false; -+ } -+#endif /* PROP_TXSTATUS_VSDB */ -+ } -+ } -+fail: -+ if (wlif_type == WL_P2P_IF_GO) -+ wldev_iovar_setint(_ndev, "mpc", 1); -+ return ERR_PTR(-ENODEV); -+} -+ -+static s32 -+wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct ether_addr p2p_mac; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 timeout = -1; -+ s32 ret = 0; -+ AP6210_DEBUG("Enter\n"); -+ -+ if (wl->p2p_net == dev) { -+ /* Since there is no ifidx corresponding to p2p0, cmds to -+ * firmware should be routed through primary I/F -+ */ -+ dev = wl_to_prmry_ndev(wl); -+ } -+ -+ if (wl->p2p_supported) { -+ memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN); -+ -+ /* Clear GO_NEG_PHASE bit to take care of GO-NEG-FAIL cases -+ */ -+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared "); -+ wl_clr_p2p_status(wl, GO_NEG_PHASE); -+ if (wl->p2p->vif_created) { -+ if (wl_get_drv_status(wl, SCANNING, dev)) { -+ wl_notify_escan_complete(wl, dev, true, true); -+ } -+ wldev_iovar_setint(dev, "mpc", 1); -+ -+ /* for GC */ -+ if (wl_get_drv_status(wl, DISCONNECTING, dev) && -+ (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)) { -+ AP6210_ERR("Wait for Link Down event for GC !\n"); -+ wait_for_completion_timeout -+ (&wl->iface_disable, msecs_to_jiffies(500)); -+ } -+ wl_set_p2p_status(wl, IF_DELETING); -+ DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl)); -+ -+ /* for GO */ -+ if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) { -+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, false); -+ /* disable interface before bsscfg free */ -+ ret = wl_cfgp2p_ifdisable(wl, &p2p_mac); -+ /* if fw doesn't support "ifdis", -+ do not wait for link down of ap mode -+ */ -+ if (ret == 0) { -+ AP6210_ERR("Wait for Link Down event for GO !!!\n"); -+ wait_for_completion_timeout(&wl->iface_disable, -+ msecs_to_jiffies(500)); -+ } else { -+ msleep(300); -+ } -+ } -+ wl_cfgp2p_clear_management_ie(wl, wl_cfgp2p_find_idx(wl, dev)); -+ /* delete interface after link down */ -+ ret = wl_cfgp2p_ifdel(wl, &p2p_mac); -+ /* Firmware could not delete the interface so we will not get WLC_E_IF -+ * event for cleaning the dhd virtual nw interace -+ * So lets do it here. Failures from fw will ensure the application to do -+ * ifconfig down and up sequnce, which will reload the fw -+ * however we should cleanup the linux network virtual interfaces -+ */ -+ /* Request framework to RESET and clean up */ -+ if (ret) { -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ AP6210_ERR("Firmware returned an error (%d) from p2p_ifdel" -+ "HANG Notification sent to %s\n", ret, ndev->name); -+ net_os_send_hang_message(ndev); -+ } -+ /* Wait for IF_DEL operation to be finished in firmware */ -+ timeout = wait_event_interruptible_timeout(wl->netif_change_event, -+ (wl->p2p->vif_created == false), -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ if (timeout > 0 && (wl->p2p->vif_created == false)) { -+ AP6210_DEBUG("IFDEL operation done\n"); -+ } else { -+ AP6210_ERR("IFDEL didn't complete properly\n"); -+ } -+ ret = dhd_del_monitor(dev); -+ } -+ } -+ return ret; -+} -+ -+static s32 -+wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, -+ enum nl80211_iftype type, u32 *flags, -+ struct vif_params *params) -+{ -+ s32 ap = 0; -+ s32 infra = 0; -+ s32 wlif_type; -+ s32 mode = 0; -+ chanspec_t chspec; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+ AP6210_DEBUG("Enter type %d\n", type); -+ switch (type) { -+ case NL80211_IFTYPE_MONITOR: -+ case NL80211_IFTYPE_WDS: -+ case NL80211_IFTYPE_MESH_POINT: -+ ap = 1; -+ AP6210_ERR("type (%d) : currently we do not support this type\n", -+ type); -+ break; -+ case NL80211_IFTYPE_ADHOC: -+ mode = WL_MODE_IBSS; -+ break; -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ mode = WL_MODE_BSS; -+ infra = 1; -+ break; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_AP_VLAN: -+ case NL80211_IFTYPE_P2P_GO: -+ mode = WL_MODE_AP; -+ ap = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ if (!dhd) -+ return -EINVAL; -+ if (ap) { -+ wl_set_mode_by_netdev(wl, ndev, mode); -+ if (wl->p2p_supported && wl->p2p->vif_created) { -+ AP6210_DEBUG("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created, -+ p2p_on(wl)); -+ wldev_iovar_setint(ndev, "mpc", 0); -+ wl_notify_escan_complete(wl, ndev, true, true); -+ -+ /* In concurrency case, STA may be already associated in a particular -+ * channel. so retrieve the current channel of primary interface and -+ * then start the virtual interface on that. -+ */ -+ chspec = wl_cfg80211_get_shared_freq(wiphy); -+ -+ wlif_type = WL_P2P_IF_GO; -+ AP6210_ERR("%s : ap (%d), infra (%d), iftype: (%d)\n", -+ ndev->name, ap, infra, type); -+ wl_set_p2p_status(wl, IF_CHANGING); -+ wl_clr_p2p_status(wl, IF_CHANGED); -+ wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); -+ wait_event_interruptible_timeout(wl->netif_change_event, -+ (wl_get_p2p_status(wl, IF_CHANGED) == true), -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ wl_set_mode_by_netdev(wl, ndev, mode); -+ dhd->op_mode &= ~DHD_FLAG_P2P_GC_MODE; -+ dhd->op_mode |= DHD_FLAG_P2P_GO_MODE; -+ wl_clr_p2p_status(wl, IF_CHANGING); -+ wl_clr_p2p_status(wl, IF_CHANGED); -+ if (mode == WL_MODE_AP) -+ wl_set_drv_status(wl, CONNECTED, ndev); -+ } else if (ndev == wl_to_prmry_ndev(wl) && -+ !wl_get_drv_status(wl, AP_CREATED, ndev)) { -+ wl_set_drv_status(wl, AP_CREATING, ndev); -+ if (!wl->ap_info && -+ !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) { -+ AP6210_ERR("struct ap_saved_ie allocation failed\n"); -+ return -ENOMEM; -+ } -+ } else { -+ AP6210_ERR("Cannot change the interface for GO or SOFTAP\n"); -+ return -EINVAL; -+ } -+ } else { -+ AP6210_DEBUG("Change_virtual_iface for transition from GO/AP to client/STA"); -+ } -+ -+ ndev->ieee80211_ptr->iftype = type; -+ return 0; -+} -+ -+s32 -+wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, -+ void* _net_attach) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ s32 ret = BCME_OK; -+ AP6210_DEBUG("Enter"); -+ if (!ndev) { -+ AP6210_ERR("net is NULL\n"); -+ return 0; -+ } -+ if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) { -+ AP6210_DEBUG("IF_ADD event called from dongle, old interface name: %s," -+ "new name: %s\n", ndev->name, wl->p2p->vir_ifname); -+ /* Assign the net device to CONNECT BSSCFG */ -+ strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1); -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = ndev; -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx; -+ wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach; -+ ndev->ifindex = idx; -+ wl_clr_p2p_status(wl, IF_ADD); -+ -+ wake_up_interruptible(&wl->netif_change_event); -+ } else { -+ ret = BCME_NOTREADY; -+ } -+ return ret; -+} -+ -+s32 -+wl_cfg80211_notify_ifdel(void) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ AP6210_DEBUG("Enter \n"); -+ wl_clr_p2p_status(wl, IF_DELETING); -+ wake_up_interruptible(&wl->netif_change_event); -+ return 0; -+} -+ -+s32 -+wl_cfg80211_ifdel_ops(struct net_device *ndev) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ bool rollback_lock = false; -+ s32 index = 0; -+#ifdef PROP_TXSTATUS_VSDB -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+#endif /* PROP_TXSTATUS_VSDB */ -+ if (!ndev || (strlen(ndev->name) == 0)) { -+ AP6210_ERR("net is NULL\n"); -+ return 0; -+ } -+ -+ if (p2p_is_on(wl) && wl->p2p->vif_created && -+ wl_get_p2p_status(wl, IF_DELETING)) { -+ if (wl->scan_request && -+ (wl->escan_info.ndev == ndev)) { -+ /* Abort any pending scan requests */ -+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; -+ if (!rtnl_is_locked()) { -+ rtnl_lock(); -+ rollback_lock = true; -+ } -+ AP6210_DEBUG("ESCAN COMPLETED\n"); -+ wl_notify_escan_complete(wl, ndev, true, false); -+ if (rollback_lock) -+ rtnl_unlock(); -+ } -+ AP6210_ERR("IF_DEL event called from dongle, net %x, vif name: %s\n", -+ (unsigned int)ndev, wl->p2p->vir_ifname); -+ -+ memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); -+ index = wl_cfgp2p_find_idx(wl, ndev); -+ wl_to_p2p_bss_ndev(wl, index) = NULL; -+ wl_to_p2p_bss_bssidx(wl, index) = WL_INVALID; -+ wl->p2p->vif_created = false; -+ -+ AP6210_DEBUG("index : %d\n", index); -+#ifdef PROP_TXSTATUS_VSDB -+ if (dhd->wlfc_enabled && wl->wlfc_on) { -+ dhd->wlfc_enabled = false; -+ dhd_wlfc_deinit(dhd); -+ wl->wlfc_on = false; -+ } -+#endif /* PROP_TXSTATUS_VSDB */ -+ wl_clr_drv_status(wl, CONNECTED, ndev); -+ } -+ /* Wake up any waiting thread */ -+ wake_up_interruptible(&wl->netif_change_event); -+ -+ return 0; -+} -+ -+s32 -+wl_cfg80211_is_progress_ifadd(void) -+{ -+ s32 is_progress = 0; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ if (wl_get_p2p_status(wl, IF_ADD)) -+ is_progress = 1; -+ return is_progress; -+} -+ -+s32 -+wl_cfg80211_is_progress_ifchange(void) -+{ -+ s32 is_progress = 0; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ if (wl_get_p2p_status(wl, IF_CHANGING)) -+ is_progress = 1; -+ return is_progress; -+} -+ -+ -+s32 -+wl_cfg80211_notify_ifchange(void) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ if (wl_get_p2p_status(wl, IF_CHANGING)) { -+ wl_set_p2p_status(wl, IF_CHANGED); -+ wake_up_interruptible(&wl->netif_change_event); -+ } -+ return 0; -+} -+ -+/* Find listen channel */ -+static s32 wl_find_listen_channel(struct wl_priv *wl, -+ u8 *ie, u32 ie_len) -+{ -+ wifi_p2p_ie_t *p2p_ie; -+ u8 *end, *pos; -+ s32 listen_channel; -+ -+ p2p_ie = wl_cfgp2p_find_p2pie(ie, ie_len); -+ -+ if (p2p_ie == NULL) -+ return 0; -+ -+ pos = p2p_ie->subelts; -+ end = p2p_ie->subelts + (p2p_ie->len - 4); -+ -+ AP6210_DEBUG(" found p2p ie ! lenth %d \n", -+ p2p_ie->len); -+ -+ while (pos < end) { -+ uint16 attr_len; -+ if (pos + 2 >= end) { -+ AP6210_DEBUG(" -- Invalid P2P attribute"); -+ return 0; -+ } -+ attr_len = ((uint16) (((pos + 1)[1] << 8) | (pos + 1)[0])); -+ -+ if (pos + 3 + attr_len > end) { -+ AP6210_DEBUG("P2P: Attribute underflow " -+ "(len=%u left=%d)", -+ attr_len, (int) (end - pos - 3)); -+ return 0; -+ } -+ -+ /* if Listen Channel att id is 6 and the vailue is valid, -+ * return the listen channel -+ */ -+ if (pos[0] == 6) { -+ /* listen channel subel length format -+ * 1(id) + 2(len) + 3(country) + 1(op. class) + 1(chan num) -+ */ -+ listen_channel = pos[1 + 2 + 3 + 1]; -+ -+ if (listen_channel == SOCIAL_CHAN_1 || -+ listen_channel == SOCIAL_CHAN_2 || -+ listen_channel == SOCIAL_CHAN_3) { -+ AP6210_DEBUG(" Found my Listen Channel %d \n", listen_channel); -+ return listen_channel; -+ } -+ } -+ pos += 3 + attr_len; -+ } -+ return 0; -+} -+ -+static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request) -+{ -+ u32 n_ssids; -+ u32 n_channels; -+ u16 channel; -+ chanspec_t chanspec; -+ s32 i = 0, j = 0, offset; -+ char *ptr; -+ wlc_ssid_t ssid; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); -+ params->bss_type = DOT11_BSSTYPE_ANY; -+ params->scan_type = 0; -+ params->nprobes = -1; -+ params->active_time = -1; -+ params->passive_time = -1; -+ params->home_time = -1; -+ params->channel_num = 0; -+ memset(¶ms->ssid, 0, sizeof(wlc_ssid_t)); -+ -+ AP6210_DEBUG("Preparing Scan request\n"); -+ AP6210_DEBUG("nprobes=%d\n", params->nprobes); -+ AP6210_DEBUG("active_time=%d\n", params->active_time); -+ AP6210_DEBUG("passive_time=%d\n", params->passive_time); -+ AP6210_DEBUG("home_time=%d\n", params->home_time); -+ AP6210_DEBUG("scan_type=%d\n", params->scan_type); -+ -+ params->nprobes = htod32(params->nprobes); -+ params->active_time = htod32(params->active_time); -+ params->passive_time = htod32(params->passive_time); -+ params->home_time = htod32(params->home_time); -+ -+ /* if request is null just exit so it will be all channel broadcast scan */ -+ if (!request) -+ return; -+ -+ n_ssids = request->n_ssids; -+ n_channels = request->n_channels; -+ -+ /* Copy channel array if applicable */ -+ AP6210_DEBUG("### List of channelspecs to scan ###\n"); -+ if (n_channels > 0) { -+ for (i = 0; i < n_channels; i++) { -+ chanspec = 0; -+ channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq); -+ /* SKIP DFS channels for Secondary interface */ -+ if ((wl->escan_info.ndev != wl_to_prmry_ndev(wl)) && -+ (request->channels[i]->flags & -+ (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))) -+ continue; -+ -+ if (request->channels[i]->band == IEEE80211_BAND_2GHZ) { -+#ifdef WL_HOST_BAND_MGMT -+ if (wl->curr_band == WLC_BAND_5G) { -+ AP6210_DEBUG("In 5G only mode, omit 2G channel:%d\n", channel); -+ continue; -+ } -+#endif /* WL_HOST_BAND_MGMT */ -+ chanspec |= WL_CHANSPEC_BAND_2G; -+ } else { -+#ifdef WL_HOST_BAND_MGMT -+ if (wl->curr_band == WLC_BAND_2G) { -+ AP6210_DEBUG("In 2G only mode, omit 5G channel:%d\n", channel); -+ continue; -+ } -+#endif /* WL_HOST_BAND_MGMT */ -+ chanspec |= WL_CHANSPEC_BAND_5G; -+ } -+ -+ chanspec |= WL_CHANSPEC_BW_20; -+ chanspec |= WL_CHANSPEC_CTL_SB_NONE; -+ -+ params->channel_list[j] = channel; -+ params->channel_list[j] &= WL_CHANSPEC_CHAN_MASK; -+ params->channel_list[j] |= chanspec; -+ AP6210_DEBUG("Chan : %d, Channel spec: %x \n", -+ channel, params->channel_list[j]); -+ params->channel_list[j] = wl_chspec_host_to_driver(params->channel_list[j]); -+ j++; -+ } -+ } else { -+ AP6210_DEBUG("Scanning all channels\n"); -+ } -+ n_channels = j; -+ /* Copy ssid array if applicable */ -+ AP6210_DEBUG("### List of SSIDs to scan ###\n"); -+ if (n_ssids > 0) { -+ offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16); -+ offset = roundup(offset, sizeof(u32)); -+ ptr = (char*)params + offset; -+ for (i = 0; i < n_ssids; i++) { -+ memset(&ssid, 0, sizeof(wlc_ssid_t)); -+ ssid.SSID_len = request->ssids[i].ssid_len; -+ memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len); -+ if (!ssid.SSID_len) -+ AP6210_DEBUG("%d: Broadcast scan\n", i); -+ else -+ AP6210_DEBUG("%d: scan for %s size =%d\n", i, -+ ssid.SSID, ssid.SSID_len); -+ memcpy(ptr, &ssid, sizeof(wlc_ssid_t)); -+ ptr += sizeof(wlc_ssid_t); -+ } -+ } else { -+ AP6210_DEBUG("Broadcast scan\n"); -+ } -+ /* Adding mask to channel numbers */ -+ params->channel_num = -+ htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) | -+ (n_channels & WL_SCAN_PARAMS_COUNT_MASK)); -+ -+ if (n_channels == 1 && wl_get_drv_status_all(wl, CONNECTED)) { -+ params->active_time = WL_SCAN_CONNECT_DWELL_TIME_MS; -+ } -+} -+ -+static s32 -+wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action) -+{ -+ u32 n_channels; -+ u32 n_ssids; -+ s32 params_size = -+ (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); -+ struct wl_iscan_params *params = NULL; -+ s32 err = 0; -+ -+ if (request != NULL) { -+ n_channels = request->n_channels; -+ n_ssids = request->n_ssids; -+ /* Allocate space for populating ssids in wl_iscan_params struct */ -+ if (n_channels % 2) -+ /* If n_channels is odd, add a padd of u16 */ -+ params_size += sizeof(u16) * (n_channels + 1); -+ else -+ params_size += sizeof(u16) * n_channels; -+ -+ /* Allocate space for populating ssids in wl_iscan_params struct */ -+ params_size += sizeof(struct wlc_ssid) * n_ssids; -+ } -+ params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL); -+ if (!params) { -+ err = -ENOMEM; -+ goto done; -+ } -+ wl_scan_prep(¶ms->params, request); -+ -+ params->version = htod32(ISCAN_REQ_VERSION); -+ params->action = htod16(action); -+ params->scan_duration = htod16(0); -+ -+ if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) { -+ AP6210_ERR("ioctl buffer length is not sufficient\n"); -+ err = -ENOMEM; -+ goto done; -+ } -+ err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size, -+ iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL); -+ if (unlikely(err)) { -+ if (err == -EBUSY) { -+ AP6210_ERR("system busy : iscan canceled\n"); -+ } else { -+ AP6210_ERR("error (%d)\n", err); -+ } -+ } -+ -+done: -+ if (params) -+ kfree(params); -+ return err; -+} -+ -+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request) -+{ -+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ s32 passive_scan; -+ s32 err = 0; -+ -+ iscan->state = WL_ISCAN_STATE_SCANING; -+ -+ passive_scan = wl->active_scan ? 0 : 1; -+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, -+ &passive_scan, sizeof(passive_scan), true); -+ if (unlikely(err)) { -+ AP6210_DEBUG("error (%d)\n", err); -+ return err; -+ } -+ wl->iscan_kickstart = true; -+ wl_run_iscan(iscan, request, WL_SCAN_ACTION_START); -+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); -+ iscan->timer_on = 1; -+ -+ return err; -+} -+ -+static s32 -+wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size) -+{ -+ wl_uint32_list_t *list; -+ s32 err = BCME_OK; -+ if (valid_chan_list == NULL || size <= 0) -+ return -ENOMEM; -+ -+ memset(valid_chan_list, 0, size); -+ list = (wl_uint32_list_t *)(void *) valid_chan_list; -+ list->count = htod32(WL_NUMCHANNELS); -+ err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false); -+ if (err != 0) { -+ AP6210_ERR("get channels failed with %d\n", err); -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_run_escan(struct wl_priv *wl, struct net_device *ndev, -+ struct cfg80211_scan_request *request, uint16 action) -+{ -+ s32 err = BCME_OK; -+ u32 n_channels; -+ u32 n_ssids; -+ s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params)); -+ wl_escan_params_t *params = NULL; -+ u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)]; -+ u32 num_chans = 0; -+ s32 channel; -+ s32 n_valid_chan; -+ s32 search_state = WL_P2P_DISC_ST_SCAN; -+ u32 i, j, n_nodfs = 0; -+ u16 *default_chan_list = NULL; -+ wl_uint32_list_t *list; -+ struct net_device *dev = NULL; -+ -+ AP6210_DEBUG("Enter \n"); -+ -+ if (!wl) { -+ err = -EINVAL; -+ goto exit; -+ } -+ if (!wl->p2p_supported || !p2p_scan(wl)) { -+ /* LEGACY SCAN TRIGGER */ -+ AP6210_DEBUG(" LEGACY E-SCAN START\n"); -+ -+ /* if scan request is not empty parse scan request paramters */ -+ if (request != NULL) { -+ n_channels = request->n_channels; -+ n_ssids = request->n_ssids; -+ /* Allocate space for populating ssids in wl_iscan_params struct */ -+ if (n_channels % 2) -+ /* If n_channels is odd, add a padd of u16 */ -+ params_size += sizeof(u16) * (n_channels + 1); -+ else -+ params_size += sizeof(u16) * n_channels; -+ -+ /* Allocate space for populating ssids in wl_iscan_params struct */ -+ params_size += sizeof(struct wlc_ssid) * n_ssids; -+ } -+ params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL); -+ if (params == NULL) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ wl_scan_prep(¶ms->params, request); -+ -+ params->version = htod32(ESCAN_REQ_VERSION); -+ params->action = htod16(action); -+ params->sync_id = htod16(0x1234); -+ if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) { -+ AP6210_ERR("ioctl buffer length not sufficient\n"); -+ kfree(params); -+ err = -ENOMEM; -+ goto exit; -+ } -+ err = wldev_iovar_setbuf(ndev, "escan", params, params_size, -+ wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL); -+ if (unlikely(err)) { -+ if (err == BCME_EPERM) -+ /* Scan Not permitted at this point of time */ -+ AP6210_DEBUG(" Escan not permitted at this time (%d)\n", err); -+ else -+ AP6210_ERR(" Escan set error (%d)\n", err); -+ } -+ kfree(params); -+ } -+ else if (p2p_is_on(wl) && p2p_scan(wl)) { -+ /* P2P SCAN TRIGGER */ -+ s32 _freq = 0; -+ n_nodfs = 0; -+ if (request && request->n_channels) { -+ num_chans = request->n_channels; -+ AP6210_DEBUG(" chann number : %d\n", num_chans); -+ default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list), -+ GFP_KERNEL); -+ if (default_chan_list == NULL) { -+ AP6210_ERR("channel list allocation failed \n"); -+ err = -ENOMEM; -+ goto exit; -+ } -+ if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) { -+ list = (wl_uint32_list_t *) chan_buf; -+ n_valid_chan = dtoh32(list->count); -+ for (i = 0; i < num_chans; i++) -+ { -+#ifdef WL_HOST_BAND_MGMT -+ int channel_band = 0; -+#endif /* WL_HOST_BAND_MGMT */ -+ _freq = request->channels[i]->center_freq; -+ channel = ieee80211_frequency_to_channel(_freq); -+#ifdef WL_HOST_BAND_MGMT -+ channel_band = (channel > CH_MAX_2G_CHANNEL) ? -+ WLC_BAND_5G : WLC_BAND_2G; -+ if ((wl->curr_band != WLC_BAND_AUTO) && -+ (wl->curr_band != channel_band) && -+ !IS_P2P_SOCIAL_CHANNEL(channel)) -+ continue; -+#endif /* WL_HOST_BAND_MGMT */ -+ -+ /* ignore DFS channels */ -+ if (request->channels[i]->flags & -+ (IEEE80211_CHAN_RADAR -+ | IEEE80211_CHAN_PASSIVE_SCAN)) -+ continue; -+ -+ for (j = 0; j < n_valid_chan; j++) { -+ /* allows only supported channel on -+ * current reguatory -+ */ -+ if (channel == (dtoh32(list->element[j]))) -+ default_chan_list[n_nodfs++] = -+ channel; -+ } -+ -+ } -+ } -+ if (num_chans == 3 && ( -+ (default_chan_list[0] == SOCIAL_CHAN_1) && -+ (default_chan_list[1] == SOCIAL_CHAN_2) && -+ (default_chan_list[2] == SOCIAL_CHAN_3))) { -+ /* SOCIAL CHANNELS 1, 6, 11 */ -+ search_state = WL_P2P_DISC_ST_SEARCH; -+ AP6210_DEBUG("P2P SEARCH PHASE START \n"); -+ } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) && -+ (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) { -+ /* If you are already a GO, then do SEARCH only */ -+ AP6210_DEBUG("Already a GO. Do SEARCH Only"); -+ search_state = WL_P2P_DISC_ST_SEARCH; -+ num_chans = n_nodfs; -+ -+ } else { -+ AP6210_DEBUG("P2P SCAN STATE START \n"); -+ num_chans = n_nodfs; -+ } -+ -+ } -+ err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list, -+ search_state, action, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ kfree(default_chan_list); -+ } -+exit: -+ if (unlikely(err)) { -+ /* Don't print Error incase of Scan suppress */ -+ if ((err == BCME_EPERM) && wl->scan_suppressed) -+ AP6210_DEBUG("Escan failed: Scan Suppressed \n"); -+ else -+ AP6210_ERR("error (%d)\n", err); -+ } -+ return err; -+} -+ -+ -+static s32 -+wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, -+ struct cfg80211_scan_request *request) -+{ -+ s32 err = BCME_OK; -+ s32 passive_scan; -+ wl_scan_results_t *results; -+ AP6210_DEBUG("Enter \n"); -+ mutex_lock(&wl->usr_sync); -+ results = (wl_scan_results_t *) wl->escan_info.escan_buf; -+ results->version = 0; -+ results->count = 0; -+ results->buflen = WL_SCAN_RESULTS_FIXED_SIZE; -+ -+ wl->escan_info.ndev = ndev; -+ wl->escan_info.wiphy = wiphy; -+ wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING; -+ passive_scan = wl->active_scan ? 0 : 1; -+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, -+ &passive_scan, sizeof(passive_scan), true); -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ goto exit; -+ } -+ -+ err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START); -+exit: -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+ -+static s32 -+__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, -+ struct cfg80211_scan_request *request, -+ struct cfg80211_ssid *this_ssid) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct cfg80211_ssid *ssids; -+ struct wl_scan_req *sr = wl_to_sr(wl); -+ struct ether_addr primary_mac; -+ s32 passive_scan; -+ bool iscan_req; -+ bool escan_req = false; -+ bool p2p_ssid; -+#ifdef WL11U -+ bcm_tlv_t *interworking_ie; -+ u32 ie_len; -+#endif -+ s32 err = 0; -+ s32 bssidx = -1; -+ s32 i; -+ -+ unsigned long flags; -+ static s32 busy_count = 0; -+ -+ /* If scan req comes for p2p0, send it over primary I/F -+ * Scan results will be delivered corresponding to cfg80211_scan_request -+ */ -+ if (ndev == wl->p2p_net) { -+ ndev = wl_to_prmry_ndev(wl); -+ } -+ -+ if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl)) { -+ AP6210_ERR("Sending Action Frames. Try it again.\n"); -+ return -EAGAIN; -+ } -+ -+ AP6210_DEBUG("Enter wiphy (%p)\n", wiphy); -+ if (wl_get_drv_status_all(wl, SCANNING)) { -+ if (wl->scan_request == NULL) { -+ wl_clr_drv_status_all(wl, SCANNING); -+ AP6210_DEBUG("<<<<<<<<<<>>>>>>>>>>\n"); -+ } else { -+ AP6210_ERR("Scanning already\n"); -+ return -EAGAIN; -+ } -+ } -+ if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) { -+ AP6210_ERR("Scanning being aborted\n"); -+ return -EAGAIN; -+ } -+ if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) { -+ AP6210_ERR("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"); -+ return -EOPNOTSUPP; -+ } -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) { -+ AP6210_DEBUG("Remain_on_channel bit is set, somehow it didn't get cleared\n"); -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ -+ /* Arm scan timeout timer */ -+ mod_timer(&wl->scan_timeout, jiffies + msecs_to_jiffies(WL_SCAN_TIMER_INTERVAL_MS)); -+ iscan_req = false; -+ if (request) { /* scan bss */ -+ ssids = request->ssids; -+ if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) { -+ iscan_req = true; -+ } else if (wl->escan_on) { -+ escan_req = true; -+ p2p_ssid = false; -+ for (i = 0; i < request->n_ssids; i++) { -+ if (ssids[i].ssid_len && -+ IS_P2P_SSID(ssids[i].ssid, ssids[i].ssid_len)) { -+ p2p_ssid = true; -+ break; -+ } -+ } -+ if (p2p_ssid) { -+ if (wl->p2p_supported) { -+ /* p2p scan trigger */ -+ if (p2p_on(wl) == false) { -+ /* p2p on at the first time */ -+ p2p_on(wl) = true; -+ wl_cfgp2p_set_firm_p2p(wl); -+ get_primary_mac(wl, &primary_mac); -+ wl_cfgp2p_generate_bss_mac(&primary_mac, -+ &wl->p2p->dev_addr, &wl->p2p->int_addr); -+ } -+ wl_clr_p2p_status(wl, GO_NEG_PHASE); -+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n"); -+ p2p_scan(wl) = true; -+ } -+ } else { -+ /* legacy scan trigger -+ * So, we have to disable p2p discovery if p2p discovery is on -+ */ -+ if (wl->p2p_supported) { -+ p2p_scan(wl) = false; -+ /* If Netdevice is not equals to primary and p2p is on -+ * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE. -+ */ -+ -+ if (p2p_scan(wl) == false) { -+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) { -+ err = wl_cfgp2p_discover_enable_search(wl, -+ false); -+ if (unlikely(err)) { -+ goto scan_out; -+ } -+ -+ } -+ } -+ } -+ if (!wl->p2p_supported || !p2p_scan(wl)) { -+ bssidx = wl_cfgp2p_find_idx(wl, ndev); -+ -+#ifdef WL11U -+ if ((interworking_ie = wl_cfg80211_find_interworking_ie( -+ (u8 *)request->ie, request->ie_len)) != NULL) { -+ ie_len = interworking_ie->len; -+ -+ err = wl_cfg80211_add_iw_ie(wl, ndev, bssidx, -+ VNDR_IE_CUSTOM_FLAG, interworking_ie->id, -+ interworking_ie->data, interworking_ie->len); -+ -+ if (unlikely(err)) { -+ goto scan_out; -+ } -+ } else if (wl->iw_ie_len != 0) { -+ /* we have to clear IW IE and disable gratuitous APR */ -+ wl_cfg80211_add_iw_ie(wl, ndev, bssidx, -+ VNDR_IE_CUSTOM_FLAG, -+ DOT11_MNG_INTERWORKING_ID, -+ 0, 0); -+ -+ wldev_iovar_setint_bsscfg(ndev, "grat_arp", 0, -+ bssidx); -+ /* we don't care about error */ -+ } -+#endif /* WL11U */ -+ err = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, -+ VNDR_IE_PRBREQ_FLAG, (u8 *)request->ie, -+ request->ie_len); -+ -+ if (unlikely(err)) { -+ goto scan_out; -+ } -+ -+ } -+ } -+ } -+ } else { /* scan in ibss */ -+ /* we don't do iscan in ibss */ -+ ssids = this_ssid; -+ } -+ wl->scan_request = request; -+ wl_set_drv_status(wl, SCANNING, ndev); -+ if (iscan_req) { -+ err = wl_do_iscan(wl, request); -+ if (likely(!err)) -+ goto scan_success; -+ else -+ goto scan_out; -+ } else if (escan_req) { -+ if (wl->p2p_supported) { -+ if (p2p_on(wl) && p2p_scan(wl)) { -+ -+ /* find my listen channel */ -+ wl->afx_hdl->my_listen_chan = -+ wl_find_listen_channel(wl, (u8 *)request->ie, -+ request->ie_len); -+ err = wl_cfgp2p_enable_discovery(wl, ndev, -+ request->ie, request->ie_len); -+ -+ if (unlikely(err)) { -+ goto scan_out; -+ } -+ } -+ } -+ err = wl_do_escan(wl, wiphy, ndev, request); -+ if (likely(!err)) -+ goto scan_success; -+ else -+ goto scan_out; -+ -+ -+ } else { -+ memset(&sr->ssid, 0, sizeof(sr->ssid)); -+ sr->ssid.SSID_len = -+ min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len); -+ if (sr->ssid.SSID_len) { -+ memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); -+ sr->ssid.SSID_len = htod32(sr->ssid.SSID_len); -+ AP6210_DEBUG("Specific scan ssid=\"%s\" len=%d\n", -+ sr->ssid.SSID, sr->ssid.SSID_len); -+ } else { -+ AP6210_DEBUG("Broadcast scan\n"); -+ } -+ AP6210_DEBUG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len); -+ passive_scan = wl->active_scan ? 0 : 1; -+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, -+ &passive_scan, sizeof(passive_scan), true); -+ if (unlikely(err)) { -+ AP6210_DEBUG("WLC_SET_PASSIVE_SCAN error (%d)\n", err); -+ goto scan_out; -+ } -+ err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid, -+ sizeof(sr->ssid), false); -+ if (err) { -+ if (err == -EBUSY) { -+ AP6210_ERR("system busy : scan for \"%s\" " -+ "canceled\n", sr->ssid.SSID); -+ } else { -+ AP6210_ERR("WLC_SCAN error (%d)\n", err); -+ } -+ goto scan_out; -+ } -+ } -+ -+scan_success: -+ -+ busy_count = 0; -+ -+ return 0; -+ -+scan_out: -+ -+ if (err == BCME_BUSY || err == BCME_NOTREADY) { -+ AP6210_ERR("Scan err = (%d), busy?%d", err, -EBUSY); -+ err = -EBUSY; -+ } -+ -+#define SCAN_EBUSY_RETRY_LIMIT 10 -+ if (err == -EBUSY) { -+ if (busy_count++ > SCAN_EBUSY_RETRY_LIMIT) { -+ struct ether_addr bssid; -+ s32 ret = 0; -+ busy_count = 0; -+ AP6210_ERR("Unusual continuous EBUSY error, %d %d %d %d %d %d %d %d %d\n", -+ wl_get_drv_status(wl, SCANNING, ndev), -+ wl_get_drv_status(wl, SCAN_ABORTING, ndev), -+ wl_get_drv_status(wl, CONNECTING, ndev), -+ wl_get_drv_status(wl, CONNECTED, ndev), -+ wl_get_drv_status(wl, DISCONNECTING, ndev), -+ wl_get_drv_status(wl, AP_CREATING, ndev), -+ wl_get_drv_status(wl, AP_CREATED, ndev), -+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev), -+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev)); -+ -+ bzero(&bssid, sizeof(bssid)); -+ if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID, -+ &bssid, ETHER_ADDR_LEN, false)) == 0) -+ AP6210_ERR("FW is connected with " MACDBG "/n", -+ MAC2STRDBG(bssid.octet)); -+ else -+ AP6210_ERR("GET BSSID failed with %d\n", ret); -+ -+ wl_cfg80211_disconnect(wiphy, ndev, DOT11_RC_DISASSOC_LEAVING); -+ } -+ } else { -+ busy_count = 0; -+ } -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ if (timer_pending(&wl->scan_timeout)) -+ del_timer_sync(&wl->scan_timeout); -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ wl->scan_request = NULL; -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ return err; -+} -+ -+static s32 -+wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, -+ struct cfg80211_scan_request *request) -+{ -+ s32 err = 0; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ -+ AP6210_DEBUG("Enter \n"); -+ CHECK_SYS_UP(wl); -+ -+ err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); -+ if (unlikely(err)) { -+ if ((err == BCME_EPERM) && wl->scan_suppressed) -+ AP6210_DEBUG("scan not permitted at this time (%d)\n", err); -+ else -+ AP6210_ERR("scan error (%d)\n", err); -+ return err; -+ } -+ -+ return err; -+} -+ -+static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold) -+{ -+ s32 err = 0; -+ -+ err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold); -+ if (unlikely(err)) { -+ AP6210_ERR("Error (%d)\n", err); -+ return err; -+ } -+ return err; -+} -+ -+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold) -+{ -+ s32 err = 0; -+ -+ err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0); -+ if (unlikely(err)) { -+ AP6210_ERR("Error (%d)\n", err); -+ return err; -+ } -+ return err; -+} -+ -+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) -+{ -+ s32 err = 0; -+ u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL); -+ -+ retry = htod32(retry); -+ err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), true); -+ if (unlikely(err)) { -+ AP6210_ERR("cmd (%d) , error (%d)\n", cmd, err); -+ return err; -+ } -+ return err; -+} -+ -+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ s32 err = 0; -+ -+ CHECK_SYS_UP(wl); -+ AP6210_DEBUG("Enter\n"); -+ if (changed & WIPHY_PARAM_RTS_THRESHOLD && -+ (wl->conf->rts_threshold != wiphy->rts_threshold)) { -+ wl->conf->rts_threshold = wiphy->rts_threshold; -+ err = wl_set_rts(ndev, wl->conf->rts_threshold); -+ if (!err) -+ return err; -+ } -+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD && -+ (wl->conf->frag_threshold != wiphy->frag_threshold)) { -+ wl->conf->frag_threshold = wiphy->frag_threshold; -+ err = wl_set_frag(ndev, wl->conf->frag_threshold); -+ if (!err) -+ return err; -+ } -+ if (changed & WIPHY_PARAM_RETRY_LONG && -+ (wl->conf->retry_long != wiphy->retry_long)) { -+ wl->conf->retry_long = wiphy->retry_long; -+ err = wl_set_retry(ndev, wl->conf->retry_long, true); -+ if (!err) -+ return err; -+ } -+ if (changed & WIPHY_PARAM_RETRY_SHORT && -+ (wl->conf->retry_short != wiphy->retry_short)) { -+ wl->conf->retry_short = wiphy->retry_short; -+ err = wl_set_retry(ndev, wl->conf->retry_short, false); -+ if (!err) { -+ return err; -+ } -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_ibss_params *params) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct cfg80211_bss *bss; -+ struct ieee80211_channel *chan; -+ struct wl_join_params join_params; -+ struct cfg80211_ssid ssid; -+ s32 scan_retry = 0; -+ s32 err = 0; -+ bool rollback_lock = false; -+ -+ AP6210_DEBUG("In\n"); -+ CHECK_SYS_UP(wl); -+ if (params->bssid) { -+ AP6210_ERR("Invalid bssid\n"); -+ return -EOPNOTSUPP; -+ } -+ bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); -+ if (!bss) { -+ memcpy(ssid.ssid, params->ssid, params->ssid_len); -+ ssid.ssid_len = params->ssid_len; -+ do { -+ if (unlikely -+ (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == -+ -EBUSY)) { -+ wl_delay(150); -+ } else { -+ break; -+ } -+ } while (++scan_retry < WL_SCAN_RETRY_MAX); -+ /* to allow scan_inform to propagate to cfg80211 plane */ -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = true; -+ } -+ -+ /* wait 4 secons till scan done.... */ -+ schedule_timeout_interruptible(msecs_to_jiffies(4000)); -+ if (rollback_lock) -+ rtnl_lock(); -+ bss = cfg80211_get_ibss(wiphy, NULL, -+ params->ssid, params->ssid_len); -+ } -+ if (bss) { -+ wl->ibss_starter = false; -+ AP6210_DEBUG("Found IBSS\n"); -+ } else { -+ wl->ibss_starter = true; -+ } -+ chan = params->channel; -+ if (chan) -+ wl->channel = ieee80211_frequency_to_channel(chan->center_freq); -+ /* -+ * Join with specific BSSID and cached SSID -+ * If SSID is zero join based on BSSID only -+ */ -+ memset(&join_params, 0, sizeof(join_params)); -+ memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, -+ params->ssid_len); -+ join_params.ssid.SSID_len = htod32(params->ssid_len); -+ if (params->bssid) -+ memcpy(&join_params.params.bssid, params->bssid, -+ ETHER_ADDR_LEN); -+ else -+ memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN); -+ -+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, -+ sizeof(join_params), true); -+ if (unlikely(err)) { -+ AP6210_ERR("Error (%d)\n", err); -+ return err; -+ } -+ return err; -+} -+ -+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 err = 0; -+ -+ CHECK_SYS_UP(wl); -+ wl_link_down(wl); -+ -+ return err; -+} -+ -+static s32 -+wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_security *sec; -+ s32 val = 0; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) -+ val = WPA_AUTH_PSK | -+ WPA_AUTH_UNSPECIFIED; -+ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) -+ val = WPA2_AUTH_PSK| -+ WPA2_AUTH_UNSPECIFIED; -+ else -+ val = WPA_AUTH_DISABLED; -+ -+ if (is_wps_conn(sme)) -+ val = WPA_AUTH_DISABLED; -+ -+#ifdef BCMWAPI_WPI -+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { -+ AP6210_DEBUG(" * wl_set_wpa_version, set wpa_auth" -+ " to WPA_AUTH_WAPI 0x400"); -+ val = WAPI_AUTH_PSK; /* | WAPI_AUTH_UNSPECIFIED; */ -+ } -+#endif -+ AP6210_DEBUG("setting wpa_auth to 0x%0x\n", val); -+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("set wpa_auth failed (%d)\n", err); -+ return err; -+ } -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ sec->wpa_versions = sme->crypto.wpa_versions; -+ return err; -+} -+ -+#ifdef BCMWAPI_WPI -+static s32 -+wl_set_set_wapi_ie(struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ AP6210_DEBUG(" %s \n", __FUNCTION__); -+ -+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { -+ err = wldev_iovar_setbuf_bsscfg(dev, "wapiie", sme->ie, -+ sme->ie_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ AP6210_ERR("===> set_wapi_ie Error (%d)\n", err); -+ return err; -+ } -+ } else -+ AP6210_DEBUG(" * skip \n"); -+ return err; -+} -+#endif /* BCMWAPI_WPI */ -+ -+static s32 -+wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_security *sec; -+ s32 val = 0; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ switch (sme->auth_type) { -+ case NL80211_AUTHTYPE_OPEN_SYSTEM: -+ val = WL_AUTH_OPEN_SYSTEM; -+ AP6210_DEBUG("open system\n"); -+ break; -+ case NL80211_AUTHTYPE_SHARED_KEY: -+ val = WL_AUTH_SHARED_KEY; -+ AP6210_DEBUG("shared key\n"); -+ break; -+ case NL80211_AUTHTYPE_AUTOMATIC: -+ val = WL_AUTH_OPEN_SHARED; -+ AP6210_DEBUG("automatic\n"); -+ break; -+ default: -+ val = WL_AUTH_OPEN_SHARED; -+ AP6210_ERR("invalid auth type (%d)\n", sme->auth_type); -+ break; -+ } -+ -+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("set auth failed (%d)\n", err); -+ return err; -+ } -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ sec->auth_type = sme->auth_type; -+ return err; -+} -+ -+static s32 -+wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_security *sec; -+ s32 pval = 0; -+ s32 gval = 0; -+ s32 err = 0; -+#ifdef BCMWAPI_WPI -+ s32 val = 0; -+#endif -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ if (sme->crypto.n_ciphers_pairwise) { -+ switch (sme->crypto.ciphers_pairwise[0]) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ case WLAN_CIPHER_SUITE_WEP104: -+ pval = WEP_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ pval = TKIP_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ pval = AES_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ pval = AES_ENABLED; -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ val = SMS4_ENABLED; -+ pval = SMS4_ENABLED; -+ break; -+#endif -+ default: -+ AP6210_ERR("invalid cipher pairwise (%d)\n", -+ sme->crypto.ciphers_pairwise[0]); -+ return -EINVAL; -+ } -+ } -+ if (sme->crypto.cipher_group) { -+ switch (sme->crypto.cipher_group) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ case WLAN_CIPHER_SUITE_WEP104: -+ gval = WEP_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ gval = TKIP_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ gval = AES_ENABLED; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ gval = AES_ENABLED; -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ val = SMS4_ENABLED; -+ gval = SMS4_ENABLED; -+ break; -+#endif -+ default: -+ AP6210_ERR("invalid cipher group (%d)\n", -+ sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ -+ AP6210_DEBUG("pval (%d) gval (%d)\n", pval, gval); -+ -+ if (is_wps_conn(sme)) { -+ if (sme->privacy) -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx); -+#ifdef BCMWAPI_WPI -+ else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_SMS4) { -+ AP6210_DEBUG(" NO, is_wps_conn, WAPI set to SMS4_ENABLED"); -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", val, bssidx); -+ } -+#endif -+ else -+ /* WPS-2.0 allows no security */ -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); -+ } else { -+ AP6210_DEBUG(" NO, is_wps_conn, Set pval | gval to WSEC"); -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", -+ pval | gval, bssidx); -+ } -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; -+ sec->cipher_group = sme->crypto.cipher_group; -+ -+ return err; -+} -+ -+static s32 -+wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_security *sec; -+ s32 val = 0; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ if (sme->crypto.n_akm_suites) { -+ err = wldev_iovar_getint(dev, "wpa_auth", &val); -+ if (unlikely(err)) { -+ AP6210_ERR("could not get wpa_auth (%d)\n", err); -+ return err; -+ } -+ if (val & (WPA_AUTH_PSK | -+ WPA_AUTH_UNSPECIFIED)) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ val = WPA_AUTH_UNSPECIFIED; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ val = WPA_AUTH_PSK; -+ break; -+ default: -+ AP6210_ERR("invalid cipher group (%d)\n", -+ sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } else if (val & (WPA2_AUTH_PSK | -+ WPA2_AUTH_UNSPECIFIED)) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ val = WPA2_AUTH_UNSPECIFIED; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ val = WPA2_AUTH_PSK; -+ break; -+ default: -+ AP6210_ERR("invalid cipher group (%d)\n", -+ sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+#ifdef BCMWAPI_WPI -+ else if (val & (WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED)) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_WAPI_CERT: -+ val = WAPI_AUTH_UNSPECIFIED; -+ break; -+ case WLAN_AKM_SUITE_WAPI_PSK: -+ val = WAPI_AUTH_PSK; -+ break; -+ default: -+ AP6210_ERR("invalid cipher group (%d)\n", -+ sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+#endif -+ AP6210_DEBUG("setting wpa_auth to %d\n", val); -+ -+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("could not set wpa_auth (%d)\n", err); -+ return err; -+ } -+ } -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ sec->wpa_auth = sme->crypto.akm_suites[0]; -+ -+ return err; -+} -+ -+static s32 -+wl_set_set_sharedkey(struct net_device *dev, -+ struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_security *sec; -+ struct wl_wsec_key key; -+ s32 val; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ AP6210_DEBUG("key len (%d)\n", sme->key_len); -+ if (sme->key_len) { -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ AP6210_DEBUG("wpa_versions 0x%x cipher_pairwise 0x%x\n", -+ sec->wpa_versions, sec->cipher_pairwise); -+ if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | -+ NL80211_WPA_VERSION_2 -+#ifdef BCMWAPI_WPI -+ | NL80211_WAPI_VERSION_1 -+#endif -+ )) && -+ (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | -+ WLAN_CIPHER_SUITE_WEP104 -+#ifdef BCMWAPI_WPI -+ | WLAN_CIPHER_SUITE_SMS4 -+#endif -+ ))) -+ { -+ memset(&key, 0, sizeof(key)); -+ key.len = (u32) sme->key_len; -+ key.index = (u32) sme->key_idx; -+ if (unlikely(key.len > sizeof(key.data))) { -+ AP6210_ERR("Too long key length (%u)\n", key.len); -+ return -EINVAL; -+ } -+ memcpy(key.data, sme->key, key.len); -+ key.flags = WL_PRIMARY_KEY; -+ switch (sec->cipher_pairwise) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ key.algo = CRYPTO_ALGO_WEP1; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ key.algo = CRYPTO_ALGO_WEP128; -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ key.algo = CRYPTO_ALGO_SMS4; -+ break; -+#endif -+ default: -+ AP6210_ERR("Invalid algorithm (%d)\n", -+ sme->crypto.ciphers_pairwise[0]); -+ return -EINVAL; -+ } -+ /* Set the new key/index */ -+ AP6210_DEBUG("key length (%d) key index (%d) algo (%d)\n", -+ key.len, key.index, key.algo); -+ AP6210_DEBUG("key \"%s\"\n", key.data); -+ swap_key_from_BE(&key); -+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err); -+ return err; -+ } -+ if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { -+ AP6210_DEBUG("set auth_type to shared key\n"); -+ val = WL_AUTH_SHARED_KEY; /* shared key */ -+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("set auth failed (%d)\n", err); -+ return err; -+ } -+ } -+ } -+ } -+ return err; -+} -+ -+#ifdef ESCAN_RESULT_PATCH -+static u8 connect_req_bssid[6]; -+static u8 broad_bssid[6]; -+#endif -+ -+ -+static s32 -+wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_connect_params *sme) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct ieee80211_channel *chan = sme->channel; -+ wl_extjoin_params_t *ext_join_params; -+ struct wl_join_params join_params; -+ size_t join_params_size; -+ s32 err = 0; -+ wpa_ie_fixed_t *wpa_ie; -+ bcm_tlv_t *wpa2_ie; -+ u8* wpaie = 0; -+ u32 wpaie_len = 0; -+ u32 chan_cnt = 0; -+ struct ether_addr bssid; -+ int ret; -+ -+ AP6210_DEBUG("In\n"); -+ -+ if (unlikely(!sme->ssid)) { -+ AP6210_ERR("Invalid ssid\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ CHECK_SYS_UP(wl); -+ -+ /* -+ * Cancel ongoing scan to sync up with sme state machine of cfg80211. -+ */ -+#if !defined(ESCAN_RESULT_PATCH) -+ if (wl->scan_request) { -+ wl_notify_escan_complete(wl, dev, true, true); -+ } -+#endif -+#ifdef ESCAN_RESULT_PATCH -+ if (sme->bssid) { -+ memcpy(connect_req_bssid, sme->bssid, ETHER_ADDR_LEN); -+ } -+ else { -+ bzero(connect_req_bssid, ETHER_ADDR_LEN); -+ } -+ bzero(broad_bssid, ETHER_ADDR_LEN); -+#endif -+ -+ bzero(&bssid, sizeof(bssid)); -+ if (!wl_get_drv_status(wl, CONNECTED, dev)&& -+ (ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) == 0) { -+ if (!ETHER_ISNULLADDR(&bssid)) { -+ scb_val_t scbval; -+ wl_set_drv_status(wl, DISCONNECTING, dev); -+ scbval.val = DOT11_RC_DISASSOC_LEAVING; -+ memcpy(&scbval.ea, &bssid, ETHER_ADDR_LEN); -+ scbval.val = htod32(scbval.val); -+ -+ AP6210_DEBUG("drv status CONNECTED is not set, but connected in FW!" MACDBG "\n", -+ MAC2STRDBG(bssid.octet)); -+ err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, -+ sizeof(scb_val_t), true); -+ if (unlikely(err)) { -+ wl_clr_drv_status(wl, DISCONNECTING, dev); -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ while (wl_get_drv_status(wl, DISCONNECTING, dev)) { -+ AP6210_ERR("Waiting for disconnection terminated.\n"); -+ msleep(20); -+ } -+ } else -+ AP6210_DEBUG("Currently not associated!\n"); -+ } -+ -+ /* Clean BSSID */ -+ bzero(&bssid, sizeof(bssid)); -+ if (!wl_get_drv_status(wl, DISCONNECTING, dev)) -+ wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID); -+ -+ if (p2p_is_on(wl) && (dev != wl_to_prmry_ndev(wl))) { -+ /* we only allow to connect using virtual interface in case of P2P */ -+ wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), -+ VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len); -+ } else if (dev == wl_to_prmry_ndev(wl)) { -+ /* find the RSN_IE */ -+ if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len, -+ DOT11_MNG_RSN_ID)) != NULL) { -+ AP6210_DEBUG(" WPA2 IE is found\n"); -+ } -+ /* find the WPA_IE */ -+ if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie, -+ sme->ie_len)) != NULL) { -+ AP6210_DEBUG(" WPA IE is found\n"); -+ } -+ if (wpa_ie != NULL || wpa2_ie != NULL) { -+ wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie; -+ wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len; -+ wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN; -+ wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len, -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ } else { -+ wldev_iovar_setbuf(dev, "wpaie", NULL, 0, -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ } -+ -+ err = wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), -+ VNDR_IE_ASSOCREQ_FLAG, (u8 *)sme->ie, sme->ie_len); -+ if (unlikely(err)) { -+ return err; -+ } -+ } -+ -+ if (chan) { -+ wl->channel = ieee80211_frequency_to_channel(chan->center_freq); -+ chan_cnt = 1; -+ AP6210_DEBUG("channel (%d), center_req (%d), %d channels\n", wl->channel, -+ chan->center_freq, chan_cnt); -+ } else -+ wl->channel = 0; -+ -+#ifdef BCMWAPI_WPI -+ AP6210_DEBUG("1. enable wapi auth\n"); -+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { -+ AP6210_DEBUG("2. set wapi ie \n"); -+ err = wl_set_set_wapi_ie(dev, sme); -+ if (unlikely(err)) -+ return err; -+ } else -+ AP6210_DEBUG("2. Not wapi ie \n"); -+#endif -+ AP6210_DEBUG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); -+ AP6210_DEBUG("3. set wapi version \n"); -+ err = wl_set_wpa_version(dev, sme); -+ if (unlikely(err)) { -+ AP6210_ERR("Invalid wpa_version\n"); -+ return err; -+ } -+#ifdef BCMWAPI_WPI -+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) -+ AP6210_DEBUG("4. WAPI Dont Set wl_set_auth_type\n"); -+ else { -+ AP6210_DEBUG("4. wl_set_auth_type\n"); -+#endif -+ err = wl_set_auth_type(dev, sme); -+ if (unlikely(err)) { -+ AP6210_ERR("Invalid auth type\n"); -+ return err; -+ } -+#ifdef BCMWAPI_WPI -+ -+ } -+#endif -+ -+ err = wl_set_set_cipher(dev, sme); -+ if (unlikely(err)) { -+ AP6210_ERR("Invalid ciper\n"); -+ return err; -+ } -+ -+ err = wl_set_key_mgmt(dev, sme); -+ if (unlikely(err)) { -+ AP6210_ERR("Invalid key mgmt\n"); -+ return err; -+ } -+ -+ err = wl_set_set_sharedkey(dev, sme); -+ if (unlikely(err)) { -+ AP6210_ERR("Invalid shared key\n"); -+ return err; -+ } -+ -+ /* -+ * Join with specific BSSID and cached SSID -+ * If SSID is zero join based on BSSID only -+ */ -+ join_params_size = WL_EXTJOIN_PARAMS_FIXED_SIZE + -+ chan_cnt * sizeof(chanspec_t); -+ ext_join_params = (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL); -+ if (ext_join_params == NULL) { -+ err = -ENOMEM; -+ wl_clr_drv_status(wl, CONNECTING, dev); -+ goto exit; -+ } -+ ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len); -+ memcpy(&ext_join_params->ssid.SSID, sme->ssid, ext_join_params->ssid.SSID_len); -+ wl_update_prof(wl, dev, NULL, &ext_join_params->ssid, WL_PROF_SSID); -+ ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len); -+ /* increate dwell time to receive probe response or detect Beacon -+ * from target AP at a noisy air only during connect command -+ */ -+ ext_join_params->scan.active_time = WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS; -+ ext_join_params->scan.passive_time = WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS; -+ /* Set up join scan parameters */ -+ ext_join_params->scan.scan_type = -1; -+ ext_join_params->scan.nprobes -+ = (ext_join_params->scan.active_time/WL_SCAN_JOIN_PROBE_INTERVAL_MS); -+ ext_join_params->scan.home_time = -1; -+ -+ if (sme->bssid) -+ memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN); -+ else -+ memcpy(&ext_join_params->assoc.bssid, ðer_bcast, ETH_ALEN); -+ ext_join_params->assoc.chanspec_num = chan_cnt; -+ if (chan_cnt) { -+ u16 channel, band, bw, ctl_sb; -+ chanspec_t chspec; -+ channel = wl->channel; -+ band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G -+ : WL_CHANSPEC_BAND_5G; -+ bw = WL_CHANSPEC_BW_20; -+ ctl_sb = WL_CHANSPEC_CTL_SB_NONE; -+ chspec = (channel | band | bw | ctl_sb); -+ ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; -+ ext_join_params->assoc.chanspec_list[0] |= chspec; -+ ext_join_params->assoc.chanspec_list[0] = -+ wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]); -+ } -+ ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num); -+ if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { -+ AP6210_DEBUG("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID, -+ ext_join_params->ssid.SSID_len); -+ } -+ wl_set_drv_status(wl, CONNECTING, dev); -+ err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size, -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync); -+ kfree(ext_join_params); -+ if (err) { -+ wl_clr_drv_status(wl, CONNECTING, dev); -+ if (err == BCME_UNSUPPORTED) { -+ AP6210_DEBUG("join iovar is not supported\n"); -+ goto set_ssid; -+ } else -+ AP6210_ERR("error (%d)\n", err); -+ } else -+ goto exit; -+ -+set_ssid: -+ memset(&join_params, 0, sizeof(join_params)); -+ join_params_size = sizeof(join_params.ssid); -+ -+ join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len); -+ memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); -+ join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); -+ wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID); -+ if (sme->bssid) -+ memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN); -+ else -+ memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); -+ -+ wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); -+ AP6210_DEBUG("join_param_size %d\n", join_params_size); -+ -+ if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { -+ AP6210_DEBUG("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, -+ join_params.ssid.SSID_len); -+ } -+ wl_set_drv_status(wl, CONNECTING, dev); -+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true); -+ if (err) { -+ AP6210_ERR("error (%d)\n", err); -+ wl_clr_drv_status(wl, CONNECTING, dev); -+ } -+exit: -+ return err; -+} -+ -+static s32 -+wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, -+ u16 reason_code) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ scb_val_t scbval; -+ bool act = false; -+ s32 err = 0; -+ u8 *curbssid; -+ AP6210_ERR("Reason %d\n", reason_code); -+ CHECK_SYS_UP(wl); -+ act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT); -+ curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID); -+ if (act) { -+ /* -+ * Cancel ongoing scan to sync up with sme state machine of cfg80211. -+ */ -+#if !defined(ESCAN_RESULT_PATCH) -+ /* Let scan aborted by F/W */ -+ if (wl->scan_request) { -+ wl_notify_escan_complete(wl, dev, true, true); -+ } -+#endif /* ESCAN_RESULT_PATCH */ -+ wl_set_drv_status(wl, DISCONNECTING, dev); -+ scbval.val = reason_code; -+ memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); -+ scbval.val = htod32(scbval.val); -+ err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, -+ sizeof(scb_val_t), true); -+ if (unlikely(err)) { -+ wl_clr_drv_status(wl, DISCONNECTING, dev); -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_set_tx_power(struct wiphy *wiphy, -+ enum nl80211_tx_power_setting type, s32 dbm) -+{ -+ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ u16 txpwrmw; -+ s32 err = 0; -+ s32 disable = 0; -+ -+ CHECK_SYS_UP(wl); -+ switch (type) { -+ case NL80211_TX_POWER_AUTOMATIC: -+ break; -+ case NL80211_TX_POWER_LIMITED: -+ if (dbm < 0) { -+ AP6210_ERR("TX_POWER_LIMITTED - dbm is negative\n"); -+ return -EINVAL; -+ } -+ break; -+ case NL80211_TX_POWER_FIXED: -+ if (dbm < 0) { -+ AP6210_ERR("TX_POWER_FIXED - dbm is negative..\n"); -+ return -EINVAL; -+ } -+ break; -+ } -+ /* Make sure radio is off or on as far as software is concerned */ -+ disable = WL_RADIO_SW_DISABLE << 16; -+ disable = htod32(disable); -+ err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_SET_RADIO error (%d)\n", err); -+ return err; -+ } -+ -+ if (dbm > 0xffff) -+ txpwrmw = 0xffff; -+ else -+ txpwrmw = (u16) dbm; -+ err = wldev_iovar_setint(ndev, "qtxpower", -+ (s32) (bcm_mw_to_qdbm(txpwrmw))); -+ if (unlikely(err)) { -+ AP6210_ERR("qtxpower error (%d)\n", err); -+ return err; -+ } -+ wl->conf->tx_power = dbm; -+ -+ return err; -+} -+ -+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ s32 txpwrdbm; -+ u8 result; -+ s32 err = 0; -+ -+ CHECK_SYS_UP(wl); -+ err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm); -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); -+ *dbm = (s32) bcm_qdbm_to_mw(result); -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool unicast, bool multicast) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ u32 index; -+ s32 wsec; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ AP6210_DEBUG("key index (%d)\n", key_idx); -+ CHECK_SYS_UP(wl); -+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_GET_WSEC error (%d)\n", err); -+ return err; -+ } -+ if (wsec & WEP_ENABLED) { -+ /* Just select a new current key */ -+ index = (u32) key_idx; -+ index = htod32(index); -+ err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, -+ sizeof(index), true); -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ } -+ } -+ return err; -+} -+ -+static s32 -+wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, const u8 *mac_addr, struct key_params *params) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct wl_wsec_key key; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ s32 mode = wl_get_mode_by_netdev(wl, dev); -+ memset(&key, 0, sizeof(key)); -+ key.index = (u32) key_idx; -+ -+ if (!ETHER_ISMULTI(mac_addr)) -+ memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN); -+ key.len = (u32) params->key_len; -+ -+ /* check for key index change */ -+ if (key.len == 0) { -+ /* key delete */ -+ swap_key_from_BE(&key); -+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ AP6210_ERR("key delete error (%d)\n", err); -+ return err; -+ } -+ } else { -+ if (key.len > sizeof(key.data)) { -+ AP6210_ERR("Invalid key length (%d)\n", key.len); -+ return -EINVAL; -+ } -+ AP6210_DEBUG("Setting the key index %d\n", key.index); -+ memcpy(key.data, params->key, key.len); -+ -+ if ((mode == WL_MODE_BSS) && -+ (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { -+ u8 keybuf[8]; -+ memcpy(keybuf, &key.data[24], sizeof(keybuf)); -+ memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); -+ memcpy(&key.data[16], keybuf, sizeof(keybuf)); -+ } -+ -+ /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ -+ if (params->seq && params->seq_len == 6) { -+ /* rx iv */ -+ u8 *ivptr; -+ ivptr = (u8 *) params->seq; -+ key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | -+ (ivptr[3] << 8) | ivptr[2]; -+ key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; -+ key.iv_initialized = true; -+ } -+ -+ switch (params->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ key.algo = CRYPTO_ALGO_WEP1; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n"); -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ key.algo = CRYPTO_ALGO_WEP128; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n"); -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ key.algo = CRYPTO_ALGO_TKIP; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n"); -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n"); -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_CCMP\n"); -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ key.algo = CRYPTO_ALGO_SMS4; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_SMS4\n"); -+ break; -+#endif -+ default: -+ AP6210_ERR("Invalid cipher (0x%x)\n", params->cipher); -+ return -EINVAL; -+ } -+ swap_key_from_BE(&key); -+ /* need to guarantee EAPOL 4/4 send out before set key */ -+ dhd_wait_pend8021x(dev); -+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err); -+ return err; -+ } -+ } -+ return err; -+} -+ -+static s32 -+wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr, -+ struct key_params *params) -+{ -+ struct wl_wsec_key key; -+ s32 val = 0; -+ s32 wsec = 0; -+ s32 err = 0; -+ u8 keybuf[8]; -+ s32 bssidx = 0; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 mode = wl_get_mode_by_netdev(wl, dev); -+ AP6210_DEBUG("key index (%d)\n", key_idx); -+ CHECK_SYS_UP(wl); -+ -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ if (mac_addr) { -+ wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); -+ goto exit; -+ } -+ memset(&key, 0, sizeof(key)); -+ -+ key.len = (u32) params->key_len; -+ key.index = (u32) key_idx; -+ -+ if (unlikely(key.len > sizeof(key.data))) { -+ AP6210_ERR("Too long key length (%u)\n", key.len); -+ return -EINVAL; -+ } -+ memcpy(key.data, params->key, key.len); -+ -+ key.flags = WL_PRIMARY_KEY; -+ switch (params->cipher) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ key.algo = CRYPTO_ALGO_WEP1; -+ val = WEP_ENABLED; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n"); -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ key.algo = CRYPTO_ALGO_WEP128; -+ val = WEP_ENABLED; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n"); -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ key.algo = CRYPTO_ALGO_TKIP; -+ val = TKIP_ENABLED; -+ /* wpa_supplicant switches the third and fourth quarters of the TKIP key */ -+ if (mode == WL_MODE_BSS) { -+ bcopy(&key.data[24], keybuf, sizeof(keybuf)); -+ bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); -+ bcopy(keybuf, &key.data[16], sizeof(keybuf)); -+ } -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n"); -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ val = AES_ENABLED; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n"); -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ val = AES_ENABLED; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_CCMP\n"); -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ key.algo = CRYPTO_ALGO_SMS4; -+ val = SMS4_ENABLED; -+ AP6210_DEBUG(" * wl_cfg80211_add_key, set key " -+ " to WLAN_CIPHER_SUITE_SMS4\n"); -+ break; -+#endif /* BCMWAPI_WPI */ -+ default: -+ AP6210_ERR("Invalid cipher (0x%x)\n", params->cipher); -+ return -EINVAL; -+ } -+ -+ /* Set the new key/index */ -+ swap_key_from_BE(&key); -+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf, -+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err); -+ return err; -+ } -+ -+exit: -+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("get wsec error (%d)\n", err); -+ return err; -+ } -+ -+ wsec |= val; -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("set wsec error (%d)\n", err); -+ return err; -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr) -+{ -+ struct wl_wsec_key key; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ AP6210_DEBUG("Enter\n"); -+#ifndef IEEE80211W -+ if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2)) -+ return -EINVAL; -+#endif -+ CHECK_SYS_UP(wl); -+ memset(&key, 0, sizeof(key)); -+ -+ key.flags = WL_PRIMARY_KEY; -+ key.algo = CRYPTO_ALGO_OFF; -+ key.index = (u32) key_idx; -+ -+ AP6210_DEBUG("key index (%d)\n", key_idx); -+ /* Set the new key/index */ -+ swap_key_from_BE(&key); -+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf, -+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (unlikely(err)) { -+ if (err == -EINVAL) { -+ if (key.index >= DOT11_MAX_DEFAULT_KEYS) { -+ /* we ignore this key index in this case */ -+ AP6210_DEBUG("invalid key index (%d)\n", key_idx); -+ } -+ } else { -+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err); -+ } -+ return err; -+ } -+ return err; -+} -+ -+static s32 -+wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, -+ u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, -+ void (*callback) (void *cookie, struct key_params * params)) -+{ -+ struct key_params params; -+ struct wl_wsec_key key; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct wl_security *sec; -+ s32 wsec; -+ s32 err = 0; -+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev); -+ -+ AP6210_DEBUG("key index (%d)\n", key_idx); -+ CHECK_SYS_UP(wl); -+ memset(&key, 0, sizeof(key)); -+ key.index = key_idx; -+ swap_key_to_BE(&key); -+ memset(¶ms, 0, sizeof(params)); -+ params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len); -+ memcpy(params.key, key.data, params.key_len); -+ -+ wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_GET_WSEC error (%d)\n", err); -+ return err; -+ } -+ switch (wsec & ~SES_OW_ENABLED) { -+ case WEP_ENABLED: -+ sec = wl_read_prof(wl, dev, WL_PROF_SEC); -+ if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { -+ params.cipher = WLAN_CIPHER_SUITE_WEP40; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n"); -+ } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) { -+ params.cipher = WLAN_CIPHER_SUITE_WEP104; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n"); -+ } -+ break; -+ case TKIP_ENABLED: -+ params.cipher = WLAN_CIPHER_SUITE_TKIP; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n"); -+ break; -+ case AES_ENABLED: -+ params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; -+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n"); -+ break; -+#ifdef BCMWAPI_WPI -+ case WLAN_CIPHER_SUITE_SMS4: -+ key.algo = CRYPTO_ALGO_SMS4; -+ AP6210_DEBUG(" * wl_cfg80211_add_key, set key" -+ "to WLAN_CIPHER_SUITE_SMS4\n"); -+ break; -+#endif -+ default: -+ AP6210_ERR("Invalid algo (0x%x)\n", wsec); -+ return -EINVAL; -+ } -+ -+ callback(cookie, ¶ms); -+ return err; -+} -+ -+static s32 -+wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, -+ struct net_device *dev, u8 key_idx) -+{ -+ AP6210_DEBUG("Not supported\n"); -+ return -EOPNOTSUPP; -+} -+ -+static s32 -+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, -+ u8 *mac, struct station_info *sinfo) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ scb_val_t scb_val; -+ s32 rssi; -+ s32 rate; -+ s32 err = 0; -+ sta_info_t *sta; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) -+ s8 eabuf[ETHER_ADDR_STR_LEN]; -+#endif -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+ CHECK_SYS_UP(wl); -+ if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) { -+ err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac, -+ ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync); -+ if (err < 0) { -+ AP6210_ERR("GET STA INFO failed, %d\n", err); -+ return err; -+ } -+ sinfo->filled = STATION_INFO_INACTIVE_TIME; -+ sta = (sta_info_t *)wl->ioctl_buf; -+ sta->len = dtoh16(sta->len); -+ sta->cap = dtoh16(sta->cap); -+ sta->flags = dtoh32(sta->flags); -+ sta->idle = dtoh32(sta->idle); -+ sta->in = dtoh32(sta->in); -+ sinfo->inactive_time = sta->idle * 1000; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) -+ if (sta->flags & WL_STA_ASSOC) { -+ sinfo->filled |= STATION_INFO_CONNECTED_TIME; -+ sinfo->connected_time = sta->in; -+ } -+ AP6210_DEBUG("STA %s : idle time : %d sec, connected time :%d ms\n", -+ bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time, -+ sta->idle * 1000); -+#endif -+ } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) { -+ get_pktcnt_t pktcnt; -+ u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID); -+ if (!wl_get_drv_status(wl, CONNECTED, dev) || -+ (dhd_is_associated(dhd, NULL, &err) == FALSE)) { -+ AP6210_ERR("NOT assoc\n"); -+ if (err == -ERESTARTSYS) -+ return err; -+ err = -ENODEV; -+ return err; -+ } -+ if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) { -+ AP6210_ERR("Wrong Mac address: "MACDBG" != "MACDBG"\n", -+ MAC2STRDBG(mac), MAC2STRDBG(curmacp)); -+ } -+ -+ /* Report the current tx rate */ -+ err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false); -+ if (err) { -+ AP6210_ERR("Could not get rate (%d)\n", err); -+ } else { -+ rate = dtoh32(rate); -+ sinfo->filled |= STATION_INFO_TX_BITRATE; -+ sinfo->txrate.legacy = rate * 5; -+ AP6210_DEBUG("Rate %d Mbps\n", (rate / 2)); -+ } -+ -+ memset(&scb_val, 0, sizeof(scb_val)); -+ scb_val.val = 0; -+ err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, -+ sizeof(scb_val_t), false); -+ if (err) { -+ AP6210_ERR("Could not get rssi (%d)\n", err); -+ goto get_station_err; -+ } -+ rssi = dtoh32(scb_val.val); -+#if defined(RSSIOFFSET) -+ rssi = wl_update_rssi_offset(rssi); -+#endif -+ sinfo->filled |= STATION_INFO_SIGNAL; -+ sinfo->signal = rssi; -+ AP6210_DEBUG("RSSI %d dBm\n", rssi); -+ err = wldev_ioctl(dev, WLC_GET_PKTCNTS, &pktcnt, -+ sizeof(pktcnt), false); -+ if (!err) { -+ sinfo->filled |= (STATION_INFO_RX_PACKETS | -+ STATION_INFO_RX_DROP_MISC | -+ STATION_INFO_TX_PACKETS | -+ STATION_INFO_TX_FAILED); -+ sinfo->rx_packets = pktcnt.rx_good_pkt; -+ sinfo->rx_dropped_misc = pktcnt.rx_bad_pkt; -+ sinfo->tx_packets = pktcnt.tx_good_pkt; -+ sinfo->tx_failed = pktcnt.tx_bad_pkt; -+ } -+get_station_err: -+ if (err && (err != -ERESTARTSYS)) { -+ /* Disconnect due to zero BSSID or error to get RSSI */ -+ AP6210_ERR("force cfg80211_disconnected\n"); -+ wl_clr_drv_status(wl, CONNECTED, dev); -+ cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL); -+ wl_link_down(wl); -+ } -+ } -+ -+ return err; -+} -+ -+/* Function to update sta power save mode for Kernel wifi stack */ -+int wl_cfg80211_update_power_mode(struct net_device *dev) -+{ -+ int pm = -1; -+ int err; -+ -+ err = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), false); -+ if (err || (pm == -1)) { -+ AP6210_ERR("error (%d)\n", err); -+ } else { -+ pm = (pm == PM_OFF) ? false : true; -+ AP6210_DEBUG("%s: %d\n", __func__, pm); -+ if (dev->ieee80211_ptr) -+ dev->ieee80211_ptr->ps = pm; -+ } -+ return err; -+} -+ -+static s32 -+wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, -+ bool enabled, s32 timeout) -+{ -+ s32 pm; -+ s32 err = 0; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_info *_net_info = wl_get_netinfo_by_netdev(wl, dev); -+#if !defined(SUPPORT_PM2_ONLY) -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+#endif /* (OEM_ANDROID) */ -+ CHECK_SYS_UP(wl); -+ -+ if (wl->p2p_net == dev || _net_info == NULL) { -+ return err; -+ } -+ AP6210_DEBUG("%s: Enter power save enabled %d\n", dev->name, enabled); -+ -+#if !defined(SUPPORT_PM2_ONLY) -+ /* android has special hooks to change pm when kernel suspended */ -+ pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF; -+#else -+ pm = enabled ? PM_FAST : PM_OFF; -+#endif /* SUPPORT_PM2_ONLY */ -+ -+ if (_net_info->pm_block || wl->vsdb_mode) { -+ /* Do not enable the power save if it is p2p interface or vsdb mode is set */ -+ AP6210_DEBUG("%s:Do not enable the power save for pm_block %d or vsdb_mode %d\n", -+ dev->name, _net_info->pm_block, wl->vsdb_mode); -+ pm = PM_OFF; -+ } -+ pm = htod32(pm); -+ AP6210_DEBUG("%s:power save %s\n", dev->name, (pm ? "enabled" : "disabled")); -+ err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true); -+ if (unlikely(err)) { -+ if (err == -ENODEV) -+ AP6210_DEBUG("net_device is not ready yet\n"); -+ else -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ return err; -+} -+ -+static __used u32 wl_find_msb(u16 bit16) -+{ -+ u32 ret = 0; -+ -+ if (bit16 & 0xff00) { -+ ret += 8; -+ bit16 >>= 8; -+ } -+ -+ if (bit16 & 0xf0) { -+ ret += 4; -+ bit16 >>= 4; -+ } -+ -+ if (bit16 & 0xc) { -+ ret += 2; -+ bit16 >>= 2; -+ } -+ -+ if (bit16 & 2) -+ ret += bit16 & 2; -+ else if (bit16) -+ ret += bit16; -+ -+ return ret; -+} -+ -+static s32 wl_cfg80211_resume(struct wiphy *wiphy) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ s32 err = 0; -+ -+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) { -+ AP6210_DEBUG("device is not ready\n"); -+ return 0; -+ } -+ -+ wl_invoke_iscan(wl); -+ -+ return err; -+} -+ -+static s32 -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -+wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) -+#else -+wl_cfg80211_suspend(struct wiphy *wiphy) -+#endif -+{ -+#ifdef DHD_CLEAR_ON_SUSPEND -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_info *iter, *next; -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ unsigned long flags; -+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) { -+ AP6210_DEBUG("device is not ready : status (%d)\n", -+ (int)wl->status); -+ return 0; -+ } -+ for_each_ndev(wl, iter, next) -+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev); -+ wl_term_iscan(wl); -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ if (wl->scan_request) { -+ cfg80211_scan_done(wl->scan_request, true); -+ wl->scan_request = NULL; -+ } -+ for_each_ndev(wl, iter, next) { -+ wl_clr_drv_status(wl, SCANNING, iter->ndev); -+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev); -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ for_each_ndev(wl, iter, next) { -+ if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) { -+ wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false); -+ } -+ } -+#endif /* DHD_CLEAR_ON_SUSPEND */ -+ return 0; -+} -+ -+static s32 -+wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, -+ s32 err) -+{ -+ int i, j; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct net_device *primary_dev = wl_to_prmry_ndev(wl); -+ -+ if (!pmk_list) { -+ AP6210_DEBUG("pmk_list is NULL\n"); -+ return -EINVAL; -+ } -+ /* pmk list is supported only for STA interface i.e. primary interface -+ * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init -+ */ -+ if (primary_dev != dev) { -+ AP6210_DEBUG("Not supporting Flushing pmklist on virtual" -+ " interfaces than primary interface\n"); -+ return err; -+ } -+ -+ AP6210_DEBUG("No of elements %d\n", pmk_list->pmkids.npmkid); -+ for (i = 0; i < pmk_list->pmkids.npmkid; i++) { -+ AP6210_DEBUG("PMKID[%d]: %pM =\n", i, -+ &pmk_list->pmkids.pmkid[i].BSSID); -+ for (j = 0; j < WPA2_PMKID_LEN; j++) { -+ AP6210_DEBUG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]); -+ } -+ } -+ if (likely(!err)) { -+ err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list, -+ sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, NULL); -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_pmksa *pmksa) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 err = 0; -+ int i; -+ -+ CHECK_SYS_UP(wl); -+ for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) -+ if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, -+ ETHER_ADDR_LEN)) -+ break; -+ if (i < WL_NUM_PMKIDS_MAX) { -+ memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, -+ ETHER_ADDR_LEN); -+ memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, -+ WPA2_PMKID_LEN); -+ if (i == wl->pmk_list->pmkids.npmkid) -+ wl->pmk_list->pmkids.npmkid++; -+ } else { -+ err = -EINVAL; -+ } -+ AP6210_DEBUG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", -+ &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID); -+ for (i = 0; i < WPA2_PMKID_LEN; i++) { -+ AP6210_DEBUG("%02x\n", -+ wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1]. -+ PMKID[i]); -+ } -+ -+ err = wl_update_pmklist(dev, wl->pmk_list, err); -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_pmksa *pmksa) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct _pmkid_list pmkid; -+ s32 err = 0; -+ int i; -+ -+ CHECK_SYS_UP(wl); -+ memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN); -+ memcpy(pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); -+ -+ AP6210_DEBUG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", -+ &pmkid.pmkid[0].BSSID); -+ for (i = 0; i < WPA2_PMKID_LEN; i++) { -+ AP6210_DEBUG("%02x\n", pmkid.pmkid[0].PMKID[i]); -+ } -+ -+ for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) -+ if (!memcmp -+ (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, -+ ETHER_ADDR_LEN)) -+ break; -+ -+ if ((wl->pmk_list->pmkids.npmkid > 0) && -+ (i < wl->pmk_list->pmkids.npmkid)) { -+ memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t)); -+ for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) { -+ memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, -+ &wl->pmk_list->pmkids.pmkid[i + 1].BSSID, -+ ETHER_ADDR_LEN); -+ memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, -+ &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, -+ WPA2_PMKID_LEN); -+ } -+ wl->pmk_list->pmkids.npmkid--; -+ } else { -+ err = -EINVAL; -+ } -+ -+ err = wl_update_pmklist(dev, wl->pmk_list, err); -+ -+ return err; -+ -+} -+ -+static s32 -+wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 err = 0; -+ CHECK_SYS_UP(wl); -+ memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); -+ err = wl_update_pmklist(dev, wl->pmk_list, err); -+ return err; -+ -+} -+ -+static wl_scan_params_t * -+wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size) -+{ -+ wl_scan_params_t *params; -+ int params_size; -+ int num_chans; -+ -+ *out_params_size = 0; -+ -+ /* Our scan params only need space for 1 channel and 0 ssids */ -+ params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16); -+ params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL); -+ if (params == NULL) { -+ AP6210_ERR("%s: mem alloc failed (%d bytes)\n", __func__, params_size); -+ return params; -+ } -+ memset(params, 0, params_size); -+ params->nprobes = nprobes; -+ -+ num_chans = (channel == 0) ? 0 : 1; -+ -+ memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); -+ params->bss_type = DOT11_BSSTYPE_ANY; -+ params->scan_type = DOT11_SCANTYPE_ACTIVE; -+ params->nprobes = htod32(1); -+ params->active_time = htod32(-1); -+ params->passive_time = htod32(-1); -+ params->home_time = htod32(10); -+ if (channel == -1) -+ params->channel_list[0] = htodchanspec(channel); -+ else -+ params->channel_list[0] = wl_ch_host_to_driver(channel); -+ -+ /* Our scan params have 1 channel and 0 ssids */ -+ params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) | -+ (num_chans & WL_SCAN_PARAMS_COUNT_MASK)); -+ -+ *out_params_size = params_size; /* rtn size to the caller */ -+ return params; -+} -+ -+static s32 -+wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, -+ struct ieee80211_channel * channel, -+ enum nl80211_channel_type channel_type, -+ unsigned int duration, u64 *cookie) -+{ -+ s32 target_channel; -+ u32 id; -+ struct ether_addr primary_mac; -+ struct net_device *ndev = NULL; -+ -+ s32 err = BCME_OK; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ -+ AP6210_DEBUG("Enter, ifindex: %d, channel: %d, duration ms (%d) SCANNING ?? %s \n", -+ dev->ifindex, ieee80211_frequency_to_channel(channel->center_freq), -+ duration, (wl_get_drv_status(wl, SCANNING, ndev)) ? "YES":"NO"); -+ -+ if (wl->p2p_net == dev) { -+ ndev = wl_to_prmry_ndev(wl); -+ } else { -+ ndev = dev; -+ } -+ -+ if (!wl->p2p) { -+ AP6210_ERR("wl->p2p is not initialized\n"); -+ err = BCME_ERROR; -+ goto exit; -+ } -+ -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ if (wl_get_drv_status(wl, SCANNING, ndev)) { -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } -+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ -+ target_channel = ieee80211_frequency_to_channel(channel->center_freq); -+ memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel)); -+ wl->remain_on_chan_type = channel_type; -+ id = ++wl->last_roc_id; -+ if (id == 0) -+ id = ++wl->last_roc_id; -+ *cookie = id; -+ -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ if (wl_get_drv_status(wl, SCANNING, ndev)) { -+ struct timer_list *_timer; -+ AP6210_DEBUG("scan is running. go to fake listen state\n"); -+ -+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev); -+ -+ if (timer_pending(&wl->p2p->listen_timer)) { -+ AP6210_DEBUG("cancel current listen timer \n"); -+ del_timer_sync(&wl->p2p->listen_timer); -+ } -+ -+ _timer = &wl->p2p->listen_timer; -+ wl_clr_p2p_status(wl, LISTEN_EXPIRED); -+ -+ INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration, 0); -+ -+ err = BCME_OK; -+ goto exit; -+ } -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ -+#ifdef WL_CFG80211_SYNC_GON -+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) { -+ /* do not enter listen mode again if we are in listen mode already for next af. -+ * remain on channel completion will be returned by waiting next af completion. -+ */ -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev); -+#else -+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev); -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ goto exit; -+ } -+#endif /* WL_CFG80211_SYNC_GON */ -+ if (wl->p2p && !wl->p2p->on) { -+ /* In case of p2p_listen command, supplicant send remain_on_channel -+ * without turning on P2P -+ */ -+ get_primary_mac(wl, &primary_mac); -+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr); -+ p2p_on(wl) = true; -+ } -+ -+ if (p2p_is_on(wl)) { -+ err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0); -+ if (unlikely(err)) { -+ goto exit; -+ } -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev); -+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ err = wl_cfgp2p_discover_listen(wl, target_channel, duration); -+ -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ if (err == BCME_OK) { -+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev); -+ } else { -+ /* if failed, firmware may be internal scanning state. -+ * so other scan request shall not abort it -+ */ -+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev); -+ } -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ /* WAR: set err = ok to prevent cookie mismatch in wpa_supplicant -+ * and expire timer will send a completion to the upper layer -+ */ -+ err = BCME_OK; -+ } -+ -+exit: -+ if (err == BCME_OK) { -+ AP6210_DEBUG("Success\n"); -+ cfg80211_ready_on_channel(dev, *cookie, channel, -+ channel_type, duration, GFP_KERNEL); -+ } else { -+ AP6210_ERR("Fail to Set (err=%d cookie:%llu)\n", err, *cookie); -+ } -+ return err; -+} -+ -+static s32 -+wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, -+ u64 cookie) -+{ -+ s32 err = 0; -+ AP6210_DEBUG(" enter ) netdev_ifidx: %d \n", dev->ifindex); -+ return err; -+} -+ -+static void -+wl_cfg80211_afx_handler(struct work_struct *work) -+{ -+ struct afx_hdl *afx_instance; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ s32 ret = BCME_OK; -+ -+ afx_instance = container_of(work, struct afx_hdl, work); -+ if (afx_instance != NULL && wl->afx_hdl->is_active) { -+ if (wl->afx_hdl->is_listen && wl->afx_hdl->my_listen_chan) { -+ ret = wl_cfgp2p_discover_listen(wl, wl->afx_hdl->my_listen_chan, -+ (100 * (1 + (random32() % 3)))); /* 100ms ~ 300ms */ -+ } else { -+ ret = wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev, -+ wl->afx_hdl->bssidx, wl->afx_hdl->peer_listen_chan); -+ } -+ if (unlikely(ret != BCME_OK)) { -+ AP6210_ERR("ERROR occurred! returned value is (%d)\n", ret); -+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) -+ complete(&wl->act_frm_scan); -+ } -+ } -+} -+ -+static s32 -+wl_cfg80211_af_searching_channel(struct wl_priv *wl, struct net_device *dev) -+{ -+ u32 max_retry = WL_CHANNEL_SYNC_RETRY; -+ -+ if (dev == NULL) -+ return -1; -+ -+ AP6210_DEBUG(" enter ) \n"); -+ -+ wl_set_drv_status(wl, FINDING_COMMON_CHANNEL, dev); -+ wl->afx_hdl->is_active = TRUE; -+ -+ /* Loop to wait until we find a peer's channel or the -+ * pending action frame tx is cancelled. -+ */ -+ while ((wl->afx_hdl->retry < max_retry) && -+ (wl->afx_hdl->peer_chan == WL_INVALID)) { -+ wl->afx_hdl->is_listen = FALSE; -+ wl_set_drv_status(wl, SCANNING, dev); -+ AP6210_DEBUG("Scheduling the action frame for sending.. retry %d\n", -+ wl->afx_hdl->retry); -+ /* search peer on peer's listen channel */ -+ schedule_work(&wl->afx_hdl->work); -+ wait_for_completion_timeout(&wl->act_frm_scan, -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ -+ if ((wl->afx_hdl->peer_chan != WL_INVALID) || -+ !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev))) -+ break; -+ -+ if (wl->afx_hdl->my_listen_chan) { -+ AP6210_DEBUG("Scheduling Listen peer in my listen channel = %d\n", -+ wl->afx_hdl->my_listen_chan); -+ /* listen on my listen channel */ -+ wl->afx_hdl->is_listen = TRUE; -+ schedule_work(&wl->afx_hdl->work); -+ wait_for_completion_timeout(&wl->act_frm_scan, -+ msecs_to_jiffies(MAX_WAIT_TIME)); -+ } -+ if (!wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)) -+ break; -+ wl->afx_hdl->retry++; -+ -+ WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl); -+ } -+ -+ wl->afx_hdl->is_active = FALSE; -+ -+ wl_clr_drv_status(wl, SCANNING, dev); -+ wl_clr_drv_status(wl, FINDING_COMMON_CHANNEL, dev); -+ -+ return (wl->afx_hdl->peer_chan); -+} -+ -+struct p2p_config_af_params { -+ s32 max_tx_retry; /* max tx retry count if tx no ack */ -+ /* To make sure to send successfully action frame, we have to turn off mpc -+ * 0: off, 1: on, (-1): do nothing -+ */ -+ s32 mpc_onoff; -+#ifdef WL_CFG80211_SYNC_GON -+ bool extra_listen; -+#endif -+ bool search_channel; /* 1: search peer's channel to send af */ -+}; -+ -+static s32 -+wl_cfg80211_config_p2p_pub_af_tx(struct wiphy *wiphy, -+ wl_action_frame_t *action_frame, wl_af_params_t *af_params, -+ struct p2p_config_af_params *config_af_params) -+{ -+ s32 err = BCME_OK; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ wifi_p2p_pub_act_frame_t *act_frm = -+ (wifi_p2p_pub_act_frame_t *) (action_frame->data); -+ -+ /* initialize default value */ -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params->extra_listen = true; -+#endif -+ config_af_params->search_channel = false; -+ config_af_params->max_tx_retry = WL_AF_TX_MAX_RETRY; -+ config_af_params->mpc_onoff = -1; -+ -+ switch (act_frm->subtype) { -+ case P2P_PAF_GON_REQ: { -+ AP6210_DEBUG("P2P: GO_NEG_PHASE status set \n"); -+ wl_set_p2p_status(wl, GO_NEG_PHASE); -+ -+ config_af_params->mpc_onoff = 0; -+ config_af_params->search_channel = true; -+ wl->next_af_subtype = act_frm->subtype + 1; -+ -+ /* increase dwell time to wait for RESP frame */ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+ -+ break; -+ } -+ case P2P_PAF_GON_RSP: { -+ wl->next_af_subtype = act_frm->subtype + 1; -+ /* increase dwell time to wait for CONF frame */ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+ break; -+ } -+ case P2P_PAF_GON_CONF: { -+ /* If we reached till GO Neg confirmation reset the filter */ -+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n"); -+ wl_clr_p2p_status(wl, GO_NEG_PHASE); -+ -+ /* turn on mpc again if go nego is done */ -+ config_af_params->mpc_onoff = 1; -+ -+ /* minimize dwell time */ -+ af_params->dwell_time = WL_MIN_DWELL_TIME; -+ -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params->extra_listen = false; -+#endif /* WL_CFG80211_SYNC_GON */ -+ break; -+ } -+ case P2P_PAF_INVITE_REQ: { -+ config_af_params->search_channel = true; -+ wl->next_af_subtype = act_frm->subtype + 1; -+ -+ /* increase dwell time */ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+ break; -+ } -+ case P2P_PAF_INVITE_RSP: -+ /* minimize dwell time */ -+ af_params->dwell_time = WL_MIN_DWELL_TIME; -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params->extra_listen = false; -+#endif /* WL_CFG80211_SYNC_GON */ -+ break; -+ case P2P_PAF_DEVDIS_REQ: { -+ config_af_params->search_channel = true; -+ -+ wl->next_af_subtype = act_frm->subtype + 1; -+ /* maximize dwell time to wait for RESP frame */ -+ af_params->dwell_time = WL_LONG_DWELL_TIME; -+ break; -+ } -+ case P2P_PAF_DEVDIS_RSP: -+ /* minimize dwell time */ -+ af_params->dwell_time = WL_MIN_DWELL_TIME; -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params->extra_listen = false; -+#endif /* WL_CFG80211_SYNC_GON */ -+ break; -+ case P2P_PAF_PROVDIS_REQ: { -+ if (IS_PROV_DISC_WITHOUT_GROUP_ID(&act_frm->elts[0], -+ action_frame->len)) { -+ config_af_params->search_channel = true; -+ } -+ -+ config_af_params->mpc_onoff = 0; -+ wl->next_af_subtype = act_frm->subtype + 1; -+ /* increase dwell time to wait for RESP frame */ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+ break; -+ } -+ case P2P_PAF_PROVDIS_RSP: { -+ wl->next_af_subtype = P2P_PAF_GON_REQ; -+ /* increase dwell time to MED level */ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params->extra_listen = false; -+#endif /* WL_CFG80211_SYNC_GON */ -+ break; -+ } -+ default: -+ AP6210_DEBUG("Unknown p2p pub act frame subtype: %d\n", -+ act_frm->subtype); -+ err = BCME_BADARG; -+ } -+ return err; -+} -+ -+ -+static bool -+wl_cfg80211_send_action_frame(struct wiphy *wiphy, struct net_device *dev, -+ struct net_device *ndev, wl_af_params_t *af_params, -+ wl_action_frame_t *action_frame, u16 action_frame_len, s32 bssidx) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ bool ack = false; -+ u8 category, action; -+ s32 tx_retry; -+ struct p2p_config_af_params config_af_params; -+#ifdef VSDB -+ ulong off_chan_started_jiffies = 0; -+#endif -+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -+ -+ wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len); -+ -+ category = action_frame->data[DOT11_ACTION_CAT_OFF]; -+ action = action_frame->data[DOT11_ACTION_ACT_OFF]; -+ -+ /* initialize variables */ -+ tx_retry = 0; -+ wl->next_af_subtype = P2P_PAF_SUBTYPE_INVALID; -+ config_af_params.max_tx_retry = WL_AF_TX_MAX_RETRY; -+ config_af_params.mpc_onoff = -1; -+ config_af_params.search_channel = false; -+#ifdef WL_CFG80211_SYNC_GON -+ config_af_params.extra_listen = false; -+#endif -+ -+ /* config parameters */ -+ /* Public Action Frame Process - DOT11_ACTION_CAT_PUBLIC */ -+ if (category == DOT11_ACTION_CAT_PUBLIC) { -+ if ((action == P2P_PUB_AF_ACTION) && -+ (action_frame_len >= sizeof(wifi_p2p_pub_act_frame_t))) { -+ /* p2p public action frame process */ -+ if (BCME_OK != wl_cfg80211_config_p2p_pub_af_tx(wiphy, -+ action_frame, af_params, &config_af_params)) { -+ AP6210_DEBUG("Unknown subtype.\n"); -+ } -+ -+ } else if (action_frame_len >= sizeof(wifi_p2psd_gas_pub_act_frame_t)) { -+ /* service discovery process */ -+ if (action == P2PSD_ACTION_ID_GAS_IREQ || -+ action == P2PSD_ACTION_ID_GAS_CREQ) { -+ /* configure service discovery query frame */ -+ -+ config_af_params.search_channel = true; -+ -+ /* save next af suptype to cancel remained dwell time */ -+ wl->next_af_subtype = action + 1; -+ -+ af_params->dwell_time = WL_MED_DWELL_TIME; -+ } else if (action == P2PSD_ACTION_ID_GAS_IRESP || -+ action == P2PSD_ACTION_ID_GAS_CRESP) { -+ /* configure service discovery response frame */ -+ af_params->dwell_time = WL_MIN_DWELL_TIME; -+ } else { -+ AP6210_DEBUG("Unknown action type: %d\n", action); -+ } -+ } else { -+ AP6210_DEBUG("Unknown Frame: category 0x%x, action 0x%x, length %d\n", -+ category, action, action_frame_len); -+ } -+ } else if (category == P2P_AF_CATEGORY) { -+ /* do not configure anything. it will be sent with a default configuration */ -+ } else { -+ AP6210_DEBUG("Unknown Frame: category 0x%x, action 0x%x\n", -+ category, action); -+ if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { -+ wl_clr_drv_status(wl, SENDING_ACT_FRM, dev); -+ return false; -+ } -+ } -+ -+ /* To make sure to send successfully action frame, we have to turn off mpc */ -+ if (config_af_params.mpc_onoff == 0) { -+ wldev_iovar_setint(dev, "mpc", 0); -+ } -+ -+ /* validate channel and p2p ies */ -+ if (config_af_params.search_channel && IS_P2P_SOCIAL(af_params->channel) && -+ wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) { -+ config_af_params.search_channel = true; -+ } else { -+ config_af_params.search_channel = false; -+ } -+ -+#ifdef WL11U -+ if (ndev == wl_to_prmry_ndev(wl)) -+ config_af_params.search_channel = false; -+#endif /* WL11U */ -+ -+#ifdef VSDB -+ /* if connecting on primary iface, sleep for a while before sending af tx for VSDB */ -+ if (wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) { -+ msleep(50); -+ } -+#endif -+ -+ /* if scan is ongoing, abort current scan. */ -+ if (wl_get_drv_status_all(wl, SCANNING)) { -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } -+ -+ /* set status and destination address before sending af */ -+ if (wl->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) { -+ /* set this status to cancel the remained dwell time in rx process */ -+ wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM, dev); -+ } -+ wl_set_drv_status(wl, SENDING_ACT_FRM, dev); -+ memcpy(wl->afx_hdl->tx_dst_addr.octet, -+ af_params->action_frame.da.octet, -+ sizeof(wl->afx_hdl->tx_dst_addr.octet)); -+ -+ /* save af_params for rx process */ -+ wl->afx_hdl->pending_tx_act_frm = af_params; -+ -+ /* search peer's channel */ -+ if (config_af_params.search_channel) { -+ /* initialize afx_hdl */ -+ wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev); -+ wl->afx_hdl->dev = dev; -+ wl->afx_hdl->retry = 0; -+ wl->afx_hdl->peer_chan = WL_INVALID; -+ -+ if (wl_cfg80211_af_searching_channel(wl, dev) == WL_INVALID) { -+ AP6210_ERR("couldn't find peer's channel.\n"); -+ goto exit; -+ } -+ -+ /* Suspend P2P discovery's search-listen to prevent it from -+ * starting a scan or changing the channel. -+ */ -+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); -+/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary */ -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_notify_escan_complete(wl, dev, true, true); -+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ wl_cfgp2p_discover_enable_search(wl, false); -+ -+ /* update channel */ -+ af_params->channel = wl->afx_hdl->peer_chan; -+ } -+ -+#ifdef VSDB -+ off_chan_started_jiffies = jiffies; -+#endif /* VSDB */ -+ -+ /* Now send a tx action frame */ -+ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? false : true; -+ -+ /* if failed, retry it. tx_retry_max value is configure by .... */ -+ while ((ack == false) && (tx_retry++ < config_af_params.max_tx_retry)) { -+#ifdef VSDB -+ if (af_params->channel) { -+ if (jiffies_to_msecs(jiffies - off_chan_started_jiffies) > -+ OFF_CHAN_TIME_THRESHOLD_MS) { -+ WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl); -+ off_chan_started_jiffies = jiffies; -+ } -+ } -+#endif /* VSDB */ -+ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? -+ false : true; -+ } -+ if (ack == false) { -+ AP6210_ERR("Failed to send Action Frame(retry %d)\n", tx_retry); -+ } -+exit: -+ /* Clear SENDING_ACT_FRM after all sending af is done */ -+ wl_clr_drv_status(wl, SENDING_ACT_FRM, dev); -+ -+#ifdef WL_CFG80211_SYNC_GON -+ /* WAR: sometimes dongle does not keep the dwell time of 'actframe'. -+ * if we coundn't get the next action response frame and dongle does not keep -+ * the dwell time, go to listen state again to get next action response frame. -+ */ -+ if (ack && config_af_params.extra_listen && -+ wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM) && -+ wl->af_sent_channel == wl->afx_hdl->my_listen_chan) { -+ s32 extar_listen_time; -+ -+ extar_listen_time = af_params->dwell_time - -+ jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies); -+ -+ if (extar_listen_time > 50) { -+ wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev); -+ AP6210_DEBUG("Wait more time! actual af time:%d," -+ "calculated extar listen:%d\n", -+ af_params->dwell_time, extar_listen_time); -+ if (wl_cfgp2p_discover_listen(wl, wl->af_sent_channel, -+ extar_listen_time + 100) == BCME_OK) { -+ wait_for_completion_timeout(&wl->wait_next_af, -+ msecs_to_jiffies(extar_listen_time + 100 + 300)); -+ } -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev); -+ } -+ } -+#endif /* WL_CFG80211_SYNC_GON */ -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, dev); -+ -+ if (wl->afx_hdl->pending_tx_act_frm) -+ wl->afx_hdl->pending_tx_act_frm = NULL; -+ -+ AP6210_DEBUG("-- sending Action Frame is %s, listen chan: %d\n", -+ (ack) ? "Succeeded!!":"Failed!!", wl->afx_hdl->my_listen_chan); -+ -+ -+ /* if all done, turn mpc on again */ -+ if (config_af_params.mpc_onoff == 1) { -+ wldev_iovar_setint(dev, "mpc", 1); -+ } -+ -+ return ack; -+} -+ -+static s32 -+wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, -+ struct ieee80211_channel *channel, bool offchan, -+ enum nl80211_channel_type channel_type, -+ bool channel_type_valid, unsigned int wait, -+ const u8* buf, size_t len, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) -+ bool no_cck, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) -+ bool dont_wait_for_ack, -+#endif -+ u64 *cookie) -+{ -+ wl_action_frame_t *action_frame; -+ wl_af_params_t *af_params; -+ scb_val_t scb_val; -+ const struct ieee80211_mgmt *mgmt; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct net_device *dev = NULL; -+ s32 err = BCME_OK; -+ s32 bssidx = 0; -+ u32 id; -+ bool ack = false; -+ s8 eabuf[ETHER_ADDR_STR_LEN]; -+ -+ AP6210_DEBUG("Enter \n"); -+ -+ if (ndev == wl->p2p_net) { -+ dev = wl_to_prmry_ndev(wl); -+ } else { -+ /* If TX req is for any valid ifidx. Use as is */ -+ dev = ndev; -+ } -+ -+ /* find bssidx based on ndev */ -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ if (bssidx == -1) { -+ -+ AP6210_ERR("Can not find the bssidx for dev( %p )\n", dev); -+ return -ENODEV; -+ } -+ if (p2p_is_on(wl)) { -+ /* Suspend P2P discovery search-listen to prevent it from changing the -+ * channel. -+ */ -+ if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) { -+ AP6210_ERR("Can not disable discovery mode\n"); -+ return -EFAULT; -+ } -+ } -+ *cookie = 0; -+ id = wl->send_action_id++; -+ if (id == 0) -+ id = wl->send_action_id++; -+ *cookie = id; -+ mgmt = (const struct ieee80211_mgmt *)buf; -+ if (ieee80211_is_mgmt(mgmt->frame_control)) { -+ if (ieee80211_is_probe_resp(mgmt->frame_control)) { -+ s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; -+ s32 ie_len = len - ie_offset; -+ if (dev == wl_to_prmry_ndev(wl)) -+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); -+ wl_cfgp2p_set_management_ie(wl, dev, bssidx, -+ VNDR_IE_PRBRSP_FLAG, (u8 *)(buf + ie_offset), ie_len); -+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); -+ goto exit; -+ } else if (ieee80211_is_disassoc(mgmt->frame_control) || -+ ieee80211_is_deauth(mgmt->frame_control)) { -+ memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN); -+ scb_val.val = mgmt->u.disassoc.reason_code; -+ err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, -+ sizeof(scb_val_t), true); -+ if (err < 0) -+ AP6210_ERR("WLC_SCB_DEAUTHENTICATE_FOR_REASON error %d\n", err); -+ AP6210_DEBUG("Disconnect STA : %s scb_val.val %d\n", -+ bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf), -+ scb_val.val); -+ wl_delay(400); -+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); -+ goto exit; -+ -+ } else if (ieee80211_is_action(mgmt->frame_control)) { -+ /* Abort the dwell time of any previous off-channel -+ * action frame that may be still in effect. Sending -+ * off-channel action frames relies on the driver's -+ * scan engine. If a previous off-channel action frame -+ * tx is still in progress (including the dwell time), -+ * then this new action frame will not be sent out. -+ */ -+/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary. -+ * And previous off-channel action frame must be ended before new af tx. -+ */ -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_notify_escan_complete(wl, dev, true, true); -+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ } -+ -+ } else { -+ AP6210_ERR("Driver only allows MGMT packet type\n"); -+ goto exit; -+ } -+ -+ af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL); -+ -+ if (af_params == NULL) -+ { -+ AP6210_ERR("unable to allocate frame\n"); -+ return -ENOMEM; -+ } -+ -+ action_frame = &af_params->action_frame; -+ -+ /* Add the packet Id */ -+ action_frame->packetId = *cookie; -+ AP6210_DEBUG("action frame %d\n", action_frame->packetId); -+ /* Add BSSID */ -+ memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN); -+ memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN); -+ -+ /* Add the length exepted for 802.11 header */ -+ action_frame->len = len - DOT11_MGMT_HDR_LEN; -+ AP6210_DEBUG("action_frame->len: %d\n", action_frame->len); -+ -+ /* Add the channel */ -+ af_params->channel = -+ ieee80211_frequency_to_channel(channel->center_freq); -+ -+ /* Save listen_chan for searching common channel */ -+ wl->afx_hdl->peer_listen_chan = af_params->channel; -+ AP6210_DEBUG("channel from upper layer %d\n", wl->afx_hdl->peer_listen_chan); -+ -+ /* Add the default dwell time -+ * Dwell time to stay off-channel to wait for a response action frame -+ * after transmitting an GO Negotiation action frame -+ */ -+ af_params->dwell_time = WL_DWELL_TIME; -+ -+ memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len); -+ -+ ack = wl_cfg80211_send_action_frame(wiphy, dev, ndev, af_params, -+ action_frame, action_frame->len, bssidx); -+ -+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL); -+ -+ kfree(af_params); -+exit: -+ return err; -+} -+ -+ -+static void -+wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, -+ u16 frame_type, bool reg) -+{ -+ -+ AP6210_DEBUG("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg); -+ -+ if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) -+ return; -+ -+ return; -+} -+ -+ -+static s32 -+wl_cfg80211_change_bss(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct bss_parameters *params) -+{ -+ if (params->use_cts_prot >= 0) { -+ } -+ -+ if (params->use_short_preamble >= 0) { -+ } -+ -+ if (params->use_short_slot_time >= 0) { -+ } -+ -+ if (params->basic_rates) { -+ } -+ -+ if (params->ap_isolate >= 0) { -+ } -+ -+ if (params->ht_opmode >= 0) { -+ } -+ -+ return 0; -+} -+ -+static s32 -+wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, -+ struct ieee80211_channel *chan, -+ enum nl80211_channel_type channel_type) -+{ -+ s32 _chan; -+ chanspec_t chspec = 0; -+ chanspec_t fw_chspec = 0; -+ u32 bw = WL_CHANSPEC_BW_20; -+ -+ s32 err = BCME_OK; -+ s32 bw_cap = 0; -+ struct { -+ u32 band; -+ u32 bw_cap; -+ } param = {0, 0}; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ -+ if (wl->p2p_net == dev) { -+ dev = wl_to_prmry_ndev(wl); -+ } -+ _chan = ieee80211_frequency_to_channel(chan->center_freq); -+ AP6210_ERR("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n", -+ dev->ifindex, channel_type, _chan); -+ -+ -+ if (chan->band == IEEE80211_BAND_5GHZ) { -+ param.band = WLC_BAND_5G; -+ err = wldev_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), -+ wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync); -+ if (err) { -+ if (err != BCME_UNSUPPORTED) { -+ AP6210_ERR("bw_cap failed, %d\n", err); -+ return err; -+ } else { -+ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); -+ if (err) { -+ AP6210_ERR("error get mimo_bw_cap (%d)\n", err); -+ } -+ if (bw_cap != WLC_N_BW_20ALL) -+ bw = WL_CHANSPEC_BW_40; -+ } -+ } else { -+ if (WL_BW_CAP_80MHZ(wl->ioctl_buf[0])) -+ bw = WL_CHANSPEC_BW_80; -+ else if (WL_BW_CAP_40MHZ(wl->ioctl_buf[0])) -+ bw = WL_CHANSPEC_BW_40; -+ else -+ bw = WL_CHANSPEC_BW_20; -+ -+ } -+ -+ } else if (chan->band == IEEE80211_BAND_2GHZ) -+ bw = WL_CHANSPEC_BW_20; -+set_channel: -+ chspec = wf_channel2chspec(_chan, bw); -+ if (wf_chspec_valid(chspec)) { -+ fw_chspec = wl_chspec_host_to_driver(chspec); -+ if (fw_chspec != INVCHANSPEC) { -+ if ((err = wldev_iovar_setint(dev, "chanspec", -+ fw_chspec)) == BCME_BADCHAN) { -+ if (bw == WL_CHANSPEC_BW_80) -+ goto change_bw; -+ err = wldev_ioctl(dev, WLC_SET_CHANNEL, -+ &_chan, sizeof(_chan), true); -+ if (err < 0) { -+ AP6210_ERR("WLC_SET_CHANNEL error %d" -+ "chip may not be supporting this channel\n", err); -+ } -+ } else if (err) { -+ AP6210_ERR("failed to set chanspec error %d\n", err); -+ } -+ } else { -+ AP6210_ERR("failed to convert host chanspec to fw chanspec\n"); -+ err = BCME_ERROR; -+ } -+ } else { -+change_bw: -+ if (bw == WL_CHANSPEC_BW_80) -+ bw = WL_CHANSPEC_BW_40; -+ else if (bw == WL_CHANSPEC_BW_40) -+ bw = WL_CHANSPEC_BW_20; -+ else -+ bw = 0; -+ if (bw) -+ goto set_channel; -+ AP6210_ERR("Invalid chanspec 0x%x\n", chspec); -+ err = BCME_ERROR; -+ } -+ return err; -+} -+ -+static s32 -+wl_validate_opensecurity(struct net_device *dev, s32 bssidx) -+{ -+ s32 err = BCME_OK; -+ -+ /* set auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "auth", 0, bssidx); -+ if (err < 0) { -+ AP6210_ERR("auth error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set wsec */ -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wsec error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set upper-layer auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", WPA_AUTH_NONE, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wpa_auth error %d\n", err); -+ return BCME_ERROR; -+ } -+ -+ return 0; -+} -+ -+static s32 -+wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) -+{ -+ s32 len = 0; -+ s32 err = BCME_OK; -+ u16 auth = 0; /* d11 open authentication */ -+ u32 wsec; -+ u32 pval = 0; -+ u32 gval = 0; -+ u32 wpa_auth = 0; -+ wpa_suite_mcast_t *mcast; -+ wpa_suite_ucast_t *ucast; -+ wpa_suite_auth_key_mgmt_t *mgmt; -+ -+ u16 suite_count; -+ u8 rsn_cap[2]; -+ u32 wme_bss_disable; -+ -+ if (wpa2ie == NULL) -+ goto exit; -+ -+ AP6210_DEBUG("Enter \n"); -+ len = wpa2ie->len; -+ /* check the mcast cipher */ -+ mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN]; -+ switch (mcast->type) { -+ case WPA_CIPHER_NONE: -+ gval = 0; -+ break; -+ case WPA_CIPHER_WEP_40: -+ case WPA_CIPHER_WEP_104: -+ gval = WEP_ENABLED; -+ break; -+ case WPA_CIPHER_TKIP: -+ gval = TKIP_ENABLED; -+ break; -+ case WPA_CIPHER_AES_CCM: -+ gval = AES_ENABLED; -+ break; -+#ifdef BCMWAPI_WPI -+ case WAPI_CIPHER_SMS4: -+ gval = SMS4_ENABLED; -+ break; -+#endif -+ default: -+ AP6210_ERR("No Security Info\n"); -+ break; -+ } -+ if ((len -= WPA_SUITE_LEN) <= 0) -+ return BCME_BADLEN; -+ -+ /* check the unicast cipher */ -+ ucast = (wpa_suite_ucast_t *)&mcast[1]; -+ suite_count = ltoh16_ua(&ucast->count); -+ switch (ucast->list[0].type) { -+ case WPA_CIPHER_NONE: -+ pval = 0; -+ break; -+ case WPA_CIPHER_WEP_40: -+ case WPA_CIPHER_WEP_104: -+ pval = WEP_ENABLED; -+ break; -+ case WPA_CIPHER_TKIP: -+ pval = TKIP_ENABLED; -+ break; -+ case WPA_CIPHER_AES_CCM: -+ pval = AES_ENABLED; -+ break; -+#ifdef BCMWAPI_WPI -+ case WAPI_CIPHER_SMS4: -+ pval = SMS4_ENABLED; -+ break; -+#endif -+ default: -+ AP6210_ERR("No Security Info\n"); -+ } -+ if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) <= 0) -+ return BCME_BADLEN; -+ -+ /* FOR WPS , set SEC_OW_ENABLED */ -+ wsec = (pval | gval | SES_OW_ENABLED); -+ /* check the AKM */ -+ mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count]; -+ suite_count = ltoh16_ua(&mgmt->count); -+ switch (mgmt->list[0].type) { -+ case RSN_AKM_NONE: -+ wpa_auth = WPA_AUTH_NONE; -+ break; -+ case RSN_AKM_UNSPECIFIED: -+ wpa_auth = WPA2_AUTH_UNSPECIFIED; -+ break; -+ case RSN_AKM_PSK: -+ wpa_auth = WPA2_AUTH_PSK; -+ break; -+ default: -+ AP6210_ERR("No Key Mgmt Info\n"); -+ } -+ -+ if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) { -+ rsn_cap[0] = *(u8 *)&mgmt->list[suite_count]; -+ rsn_cap[1] = *((u8 *)&mgmt->list[suite_count] + 1); -+ -+ if (rsn_cap[0] & (RSN_CAP_16_REPLAY_CNTRS << RSN_CAP_PTK_REPLAY_CNTR_SHIFT)) { -+ wme_bss_disable = 0; -+ } else { -+ wme_bss_disable = 1; -+ } -+ -+ /* set wme_bss_disable to sync RSN Capabilities */ -+ err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wme_bss_disable error %d\n", err); -+ return BCME_ERROR; -+ } -+ } else { -+ AP6210_DEBUG("There is no RSN Capabilities. remained len %d\n", len); -+ } -+ -+ /* set auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); -+ if (err < 0) { -+ AP6210_ERR("auth error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set wsec */ -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wsec error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set upper-layer auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wpa_auth error %d\n", err); -+ return BCME_ERROR; -+ } -+exit: -+ return 0; -+} -+ -+static s32 -+wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx) -+{ -+ wpa_suite_mcast_t *mcast; -+ wpa_suite_ucast_t *ucast; -+ wpa_suite_auth_key_mgmt_t *mgmt; -+ u16 auth = 0; /* d11 open authentication */ -+ u16 count; -+ s32 err = BCME_OK; -+ s32 len = 0; -+ u32 i; -+ u32 wsec; -+ u32 pval = 0; -+ u32 gval = 0; -+ u32 wpa_auth = 0; -+ u32 tmp = 0; -+ -+ if (wpaie == NULL) -+ goto exit; -+ AP6210_DEBUG("Enter \n"); -+ len = wpaie->length; /* value length */ -+ len -= WPA_IE_TAG_FIXED_LEN; -+ /* check for multicast cipher suite */ -+ if (len < WPA_SUITE_LEN) { -+ AP6210_DEBUG("no multicast cipher suite\n"); -+ goto exit; -+ } -+ -+ /* pick up multicast cipher */ -+ mcast = (wpa_suite_mcast_t *)&wpaie[1]; -+ len -= WPA_SUITE_LEN; -+ if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) { -+ if (IS_WPA_CIPHER(mcast->type)) { -+ tmp = 0; -+ switch (mcast->type) { -+ case WPA_CIPHER_NONE: -+ tmp = 0; -+ break; -+ case WPA_CIPHER_WEP_40: -+ case WPA_CIPHER_WEP_104: -+ tmp = WEP_ENABLED; -+ break; -+ case WPA_CIPHER_TKIP: -+ tmp = TKIP_ENABLED; -+ break; -+ case WPA_CIPHER_AES_CCM: -+ tmp = AES_ENABLED; -+ break; -+ default: -+ AP6210_ERR("No Security Info\n"); -+ } -+ gval |= tmp; -+ } -+ } -+ /* Check for unicast suite(s) */ -+ if (len < WPA_IE_SUITE_COUNT_LEN) { -+ AP6210_DEBUG("no unicast suite\n"); -+ goto exit; -+ } -+ /* walk thru unicast cipher list and pick up what we recognize */ -+ ucast = (wpa_suite_ucast_t *)&mcast[1]; -+ count = ltoh16_ua(&ucast->count); -+ len -= WPA_IE_SUITE_COUNT_LEN; -+ for (i = 0; i < count && len >= WPA_SUITE_LEN; -+ i++, len -= WPA_SUITE_LEN) { -+ if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { -+ if (IS_WPA_CIPHER(ucast->list[i].type)) { -+ tmp = 0; -+ switch (ucast->list[i].type) { -+ case WPA_CIPHER_NONE: -+ tmp = 0; -+ break; -+ case WPA_CIPHER_WEP_40: -+ case WPA_CIPHER_WEP_104: -+ tmp = WEP_ENABLED; -+ break; -+ case WPA_CIPHER_TKIP: -+ tmp = TKIP_ENABLED; -+ break; -+ case WPA_CIPHER_AES_CCM: -+ tmp = AES_ENABLED; -+ break; -+ default: -+ AP6210_ERR("No Security Info\n"); -+ } -+ pval |= tmp; -+ } -+ } -+ } -+ len -= (count - i) * WPA_SUITE_LEN; -+ /* Check for auth key management suite(s) */ -+ if (len < WPA_IE_SUITE_COUNT_LEN) { -+ AP6210_DEBUG(" no auth key mgmt suite\n"); -+ goto exit; -+ } -+ /* walk thru auth management suite list and pick up what we recognize */ -+ mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count]; -+ count = ltoh16_ua(&mgmt->count); -+ len -= WPA_IE_SUITE_COUNT_LEN; -+ for (i = 0; i < count && len >= WPA_SUITE_LEN; -+ i++, len -= WPA_SUITE_LEN) { -+ if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) { -+ if (IS_WPA_AKM(mgmt->list[i].type)) { -+ tmp = 0; -+ switch (mgmt->list[i].type) { -+ case RSN_AKM_NONE: -+ tmp = WPA_AUTH_NONE; -+ break; -+ case RSN_AKM_UNSPECIFIED: -+ tmp = WPA_AUTH_UNSPECIFIED; -+ break; -+ case RSN_AKM_PSK: -+ tmp = WPA_AUTH_PSK; -+ break; -+ default: -+ AP6210_ERR("No Key Mgmt Info\n"); -+ } -+ wpa_auth |= tmp; -+ } -+ } -+ -+ } -+ /* FOR WPS , set SEC_OW_ENABLED */ -+ wsec = (pval | gval | SES_OW_ENABLED); -+ /* set auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); -+ if (err < 0) { -+ AP6210_ERR("auth error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set wsec */ -+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wsec error %d\n", err); -+ return BCME_ERROR; -+ } -+ /* set upper-layer auth */ -+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); -+ if (err < 0) { -+ AP6210_ERR("wpa_auth error %d\n", err); -+ return BCME_ERROR; -+ } -+exit: -+ return 0; -+} -+ -+static s32 -+wl_cfg80211_bcn_validate_sec( -+ struct net_device *dev, -+ struct parsed_ies *ies, -+ u32 dev_role, -+ s32 bssidx) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ if (dev_role == NL80211_IFTYPE_P2P_GO && (ies->wpa2_ie)) { -+ /* For P2P GO, the sec type is WPA2-PSK */ -+ AP6210_DEBUG("P2P GO: validating wpa2_ie"); -+ if (wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0) -+ return BCME_ERROR; -+ -+ } else if (dev_role == NL80211_IFTYPE_AP) { -+ -+ AP6210_DEBUG("SoftAP: validating security"); -+ /* If wpa2_ie or wpa_ie is present validate it */ -+ if ((ies->wpa2_ie || ies->wpa_ie) && -+ ((wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0 || -+ wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0))) { -+ wl->ap_info->security_mode = false; -+ return BCME_ERROR; -+ } -+ -+ wl->ap_info->security_mode = true; -+ if (wl->ap_info->rsn_ie) { -+ kfree(wl->ap_info->rsn_ie); -+ wl->ap_info->rsn_ie = NULL; -+ } -+ if (wl->ap_info->wpa_ie) { -+ kfree(wl->ap_info->wpa_ie); -+ wl->ap_info->wpa_ie = NULL; -+ } -+ if (wl->ap_info->wps_ie) { -+ kfree(wl->ap_info->wps_ie); -+ wl->ap_info->wps_ie = NULL; -+ } -+ if (ies->wpa_ie != NULL) { -+ /* WPAIE */ -+ wl->ap_info->rsn_ie = NULL; -+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie, -+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ } else if (ies->wpa2_ie != NULL) { -+ /* RSNIE */ -+ wl->ap_info->wpa_ie = NULL; -+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie, -+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ } -+ -+ if (!ies->wpa2_ie && !ies->wpa_ie) { -+ wl_validate_opensecurity(dev, bssidx); -+ wl->ap_info->security_mode = false; -+ } -+ -+ if (ies->wps_ie) { -+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL); -+ } -+ } -+ -+ return 0; -+ -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+static s32 wl_cfg80211_bcn_set_params( -+ struct cfg80211_ap_settings *info, -+ struct net_device *dev, -+ u32 dev_role, s32 bssidx) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ s32 err = BCME_OK; -+ -+ AP6210_DEBUG("interval (%d) \ndtim_period (%d) \n", -+ info->beacon_interval, info->dtim_period); -+ -+ if (info->beacon_interval) { -+ if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD, -+ &info->beacon_interval, sizeof(s32), true)) < 0) { -+ AP6210_ERR("Beacon Interval Set Error, %d\n", err); -+ return err; -+ } -+ } -+ -+ if (info->dtim_period) { -+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, -+ &info->dtim_period, sizeof(s32), true)) < 0) { -+ AP6210_ERR("DTIM Interval Set Error, %d\n", err); -+ return err; -+ } -+ } -+ -+ if ((info->ssid) && (info->ssid_len > 0) && -+ (info->ssid_len <= 32)) { -+ AP6210_DEBUG("SSID (%s) len:%d \n", info->ssid, info->ssid_len); -+ if (dev_role == NL80211_IFTYPE_AP) { -+ /* Store the hostapd SSID */ -+ memset(wl->hostapd_ssid.SSID, 0x00, 32); -+ memcpy(wl->hostapd_ssid.SSID, info->ssid, info->ssid_len); -+ wl->hostapd_ssid.SSID_len = info->ssid_len; -+ } else { -+ /* P2P GO */ -+ memset(wl->p2p->ssid.SSID, 0x00, 32); -+ memcpy(wl->p2p->ssid.SSID, info->ssid, info->ssid_len); -+ wl->p2p->ssid.SSID_len = info->ssid_len; -+ } -+ } -+ -+ if (info->hidden_ssid) { -+ if ((err = wldev_iovar_setint(dev, "closednet", 1)) < 0) -+ AP6210_ERR("failed to set hidden : %d\n", err); -+ AP6210_DEBUG("hidden_ssid_enum_val: %d \n", info->hidden_ssid); -+ } -+ -+ return err; -+} -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ -+static s32 -+wl_cfg80211_parse_ies(u8 *ptr, u32 len, struct parsed_ies *ies) -+{ -+ s32 err = BCME_OK; -+ -+ memset(ies, 0, sizeof(struct parsed_ies)); -+ -+ /* find the WPSIE */ -+ if ((ies->wps_ie = wl_cfgp2p_find_wpsie(ptr, len)) != NULL) { -+ AP6210_DEBUG("WPSIE in beacon \n"); -+ ies->wps_ie_len = ies->wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN; -+ } else { -+ AP6210_ERR("No WPSIE in beacon \n"); -+ } -+ -+ /* find the RSN_IE */ -+ if ((ies->wpa2_ie = bcm_parse_tlvs(ptr, len, -+ DOT11_MNG_RSN_ID)) != NULL) { -+ AP6210_DEBUG(" WPA2 IE found\n"); -+ ies->wpa2_ie_len = ies->wpa2_ie->len; -+ } -+ -+ /* find the WPA_IE */ -+ if ((ies->wpa_ie = wl_cfgp2p_find_wpaie(ptr, len)) != NULL) { -+ AP6210_DEBUG(" WPA found\n"); -+ ies->wpa_ie_len = ies->wpa_ie->length; -+ } -+ -+ return err; -+ -+} -+ -+static s32 -+wl_cfg80211_bcn_bringup_ap( -+ struct net_device *dev, -+ struct parsed_ies *ies, -+ u32 dev_role, s32 bssidx) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wl_join_params join_params; -+ bool is_bssup = false; -+ s32 infra = 1; -+ s32 join_params_size = 0; -+ s32 ap = 1; -+ s32 err = BCME_OK; -+ -+ AP6210_DEBUG("Enter dev_role: %d\n", dev_role); -+ -+ /* Common code for SoftAP and P2P GO */ -+ wldev_iovar_setint(dev, "mpc", 0); -+ -+ if (dev_role == NL80211_IFTYPE_P2P_GO) { -+ is_bssup = wl_cfgp2p_bss_isup(dev, bssidx); -+ if (!is_bssup && (ies->wpa2_ie != NULL)) { -+ -+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); -+ if (err < 0) { -+ AP6210_ERR("SET INFRA error %d\n", err); -+ goto exit; -+ } -+ -+ err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid, -+ sizeof(wl->p2p->ssid), wl->ioctl_buf, WLC_IOCTL_MAXLEN, -+ bssidx, &wl->ioctl_buf_sync); -+ if (err < 0) { -+ AP6210_ERR("GO SSID setting error %d\n", err); -+ goto exit; -+ } -+ -+ if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) { -+ AP6210_ERR("GO Bring up error %d\n", err); -+ goto exit; -+ } -+ } else -+ AP6210_DEBUG("Bss is already up\n"); -+ } else if ((dev_role == NL80211_IFTYPE_AP) && -+ (wl_get_drv_status(wl, AP_CREATING, dev))) { -+ /* Device role SoftAP */ -+ err = wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true); -+ if (err < 0) { -+ AP6210_ERR("WLC_DOWN error %d\n", err); -+ goto exit; -+ } -+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); -+ if (err < 0) { -+ AP6210_ERR("SET INFRA error %d\n", err); -+ goto exit; -+ } -+ if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { -+ AP6210_ERR("setting AP mode failed %d \n", err); -+ goto exit; -+ } -+ -+ err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_UP error (%d)\n", err); -+ goto exit; -+ } -+ -+ memset(&join_params, 0, sizeof(join_params)); -+ /* join parameters starts with ssid */ -+ join_params_size = sizeof(join_params.ssid); -+ memcpy(join_params.ssid.SSID, wl->hostapd_ssid.SSID, -+ wl->hostapd_ssid.SSID_len); -+ join_params.ssid.SSID_len = htod32(wl->hostapd_ssid.SSID_len); -+ -+ /* create softap */ -+ if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, -+ join_params_size, true)) == 0) { -+ AP6210_DEBUG("SoftAP set SSID (%s) success\n", join_params.ssid.SSID); -+ wl_clr_drv_status(wl, AP_CREATING, dev); -+ wl_set_drv_status(wl, AP_CREATED, dev); -+ } -+ } -+ -+ -+exit: -+ return err; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+s32 -+wl_cfg80211_parse_set_ies( -+ struct net_device *dev, -+ struct cfg80211_beacon_data *info, -+ struct parsed_ies *ies, -+ u32 dev_role, -+ s32 bssidx) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct parsed_ies prb_ies; -+ s32 err = BCME_OK; -+ -+ memset(ies, 0, sizeof(struct parsed_ies)); -+ memset(&prb_ies, 0, sizeof(struct parsed_ies)); -+ -+ /* Parse Beacon IEs */ -+ if (wl_cfg80211_parse_ies((u8 *)info->tail, -+ info->tail_len, ies) < 0) { -+ AP6210_ERR("Beacon get IEs failed \n"); -+ err = -EINVAL; -+ goto fail; -+ } -+ -+ /* Set Beacon IEs to FW */ -+ if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, -+ VNDR_IE_BEACON_FLAG, (u8 *)info->tail, -+ info->tail_len)) < 0) { -+ AP6210_ERR("Set Beacon IE Failed \n"); -+ } else { -+ AP6210_DEBUG("Applied Vndr IEs for Beacon \n"); -+ } -+ -+ /* Parse Probe Response IEs */ -+ if (wl_cfg80211_parse_ies((u8 *)info->proberesp_ies, -+ info->proberesp_ies_len, &prb_ies) < 0) { -+ AP6210_ERR("PRB RESP get IEs failed \n"); -+ err = -EINVAL; -+ goto fail; -+ } -+ -+ /* Set Probe Response IEs to FW */ -+ if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, -+ VNDR_IE_PRBRSP_FLAG, (u8 *)info->proberesp_ies, -+ info->proberesp_ies_len)) < 0) { -+ AP6210_ERR("Set Probe Resp IE Failed \n"); -+ } else { -+ AP6210_DEBUG("Applied Vndr IEs for Probe Resp \n"); -+ } -+ -+fail: -+ -+ return err; -+} -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ -+static s32 wl_cfg80211_hostapd_sec( -+ struct net_device *dev, -+ struct parsed_ies *ies, -+ s32 bssidx) -+{ -+ bool update_bss = 0; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ -+ if (ies->wps_ie) { -+ if (wl->ap_info->wps_ie && -+ memcmp(wl->ap_info->wps_ie, ies->wps_ie, ies->wps_ie_len)) { -+ AP6210_DEBUG(" WPS IE is changed\n"); -+ kfree(wl->ap_info->wps_ie); -+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL); -+ } else if (wl->ap_info->wps_ie == NULL) { -+ AP6210_DEBUG(" WPS IE is added\n"); -+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL); -+ } -+ if ((ies->wpa_ie != NULL || ies->wpa2_ie != NULL)) { -+ if (!wl->ap_info->security_mode) { -+ /* change from open mode to security mode */ -+ update_bss = true; -+ if (ies->wpa_ie != NULL) { -+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie, -+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ } else { -+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie, -+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ } -+ } else if (wl->ap_info->wpa_ie) { -+ /* change from WPA2 mode to WPA mode */ -+ if (ies->wpa_ie != NULL) { -+ update_bss = true; -+ kfree(wl->ap_info->rsn_ie); -+ wl->ap_info->rsn_ie = NULL; -+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie, -+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ } else if (memcmp(wl->ap_info->rsn_ie, -+ ies->wpa2_ie, ies->wpa2_ie->len -+ + WPA_RSN_IE_TAG_FIXED_LEN)) { -+ update_bss = true; -+ kfree(wl->ap_info->rsn_ie); -+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie, -+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN, -+ GFP_KERNEL); -+ wl->ap_info->wpa_ie = NULL; -+ } -+ } -+ if (update_bss) { -+ wl->ap_info->security_mode = true; -+ wl_cfgp2p_bss(wl, dev, bssidx, 0); -+ if (wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0 || -+ wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0) { -+ return BCME_ERROR; -+ } -+ wl_cfgp2p_bss(wl, dev, bssidx, 1); -+ } -+ } -+ } else { -+ AP6210_ERR("No WPSIE in beacon \n"); -+ } -+ return 0; -+} -+ -+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ -+ 2, 0)) -+static s32 -+wl_cfg80211_del_station( -+ struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8* mac_addr) -+{ -+ struct net_device *dev; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ scb_val_t scb_val; -+ s8 eabuf[ETHER_ADDR_STR_LEN]; -+ -+ AP6210_DEBUG("Entry\n"); -+ if (mac_addr == NULL) { -+ AP6210_DEBUG("mac_addr is NULL ignore it\n"); -+ return 0; -+ } -+ -+ if (ndev == wl->p2p_net) { -+ dev = wl_to_prmry_ndev(wl); -+ } else { -+ dev = ndev; -+ } -+ -+ if (p2p_is_on(wl)) { -+ /* Suspend P2P discovery search-listen to prevent it from changing the -+ * channel. -+ */ -+ if ((wl_cfgp2p_discover_enable_search(wl, false)) < 0) { -+ AP6210_ERR("Can not disable discovery mode\n"); -+ return -EFAULT; -+ } -+ } -+ -+ memcpy(scb_val.ea.octet, mac_addr, ETHER_ADDR_LEN); -+ scb_val.val = DOT11_RC_DEAUTH_LEAVING; -+ if (wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, -+ sizeof(scb_val_t), true)) -+ AP6210_ERR("WLC_SCB_DEAUTHENTICATE_FOR_REASON failed\n"); -+ AP6210_DEBUG("Disconnect STA : %s scb_val.val %d\n", -+ bcm_ether_ntoa((const struct ether_addr *)mac_addr, eabuf), -+ scb_val.val); -+ wl_delay(400); -+ return 0; -+} -+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+static s32 -+wl_cfg80211_start_ap( -+ struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_ap_settings *info) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 err = BCME_OK; -+ struct parsed_ies ies; -+ s32 bssidx = 0; -+ u32 dev_role = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (dev == wl_to_prmry_ndev(wl)) { -+ AP6210_DEBUG("Start AP req on primary iface: Softap\n"); -+ dev_role = NL80211_IFTYPE_AP; -+ } else if (dev == wl->p2p_net) { -+ /* Group Add request on p2p0 */ -+ AP6210_DEBUG("Start AP req on P2P iface: GO\n"); -+ dev = wl_to_prmry_ndev(wl); -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ if (p2p_is_on(wl) && -+ (bssidx == wl_to_p2p_bss_bssidx(wl, -+ P2PAPI_BSSCFG_CONNECTION))) { -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ AP6210_DEBUG("Start AP req on P2P connection iface\n"); -+ } -+ -+ if ((err = wl_cfg80211_bcn_set_params(info, dev, -+ dev_role, bssidx)) < 0) { -+ AP6210_ERR("Beacon params set failed \n"); -+ goto fail; -+ } -+ -+ /* Set IEs to FW */ -+ if ((err = wl_cfg80211_parse_set_ies(dev, &info->beacon, -+ &ies, dev_role, bssidx) < 0)) { -+ AP6210_ERR("Set IEs failed \n"); -+ goto fail; -+ } -+ -+ if ((wl_cfg80211_bcn_validate_sec(dev, &ies, -+ dev_role, bssidx)) < 0) -+ { -+ AP6210_ERR("Beacon set security failed \n"); -+ goto fail; -+ } -+ -+ if ((err = wl_cfg80211_bcn_bringup_ap(dev, &ies, -+ dev_role, bssidx)) < 0) { -+ AP6210_ERR("Beacon bring up AP/GO failed \n"); -+ goto fail; -+ } -+ -+ AP6210_DEBUG("** AP/GO Created **\n"); -+ -+fail: -+ if (err) { -+ AP6210_ERR("ADD/SET beacon failed\n"); -+ wldev_iovar_setint(dev, "mpc", 1); -+ } -+ -+ return err; -+} -+ -+static s32 -+wl_cfg80211_stop_ap( -+ struct wiphy *wiphy, -+ struct net_device *dev) -+{ -+ int err = 0; -+ u32 dev_role = 0; -+ int infra = 0; -+ int ap = 0; -+ s32 bssidx = 0; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ -+ AP6210_DEBUG("Enter \n"); -+ if (dev == wl_to_prmry_ndev(wl)) { -+ dev_role = NL80211_IFTYPE_AP; -+ } else if (dev == wl->p2p_net) { -+ /* Group Add request on p2p0 */ -+ dev = wl_to_prmry_ndev(wl); -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ if (p2p_is_on(wl) && -+ (bssidx == wl_to_p2p_bss_bssidx(wl, -+ P2PAPI_BSSCFG_CONNECTION))) { -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ if (dev_role == NL80211_IFTYPE_AP) { -+ /* SoftAp on primary Interface. -+ * Shut down AP and turn on MPC -+ */ -+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); -+ if (err < 0) { -+ AP6210_ERR("SET INFRA error %d\n", err); -+ err = -ENOTSUPP; -+ goto exit; -+ } -+ if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { -+ AP6210_ERR("setting AP mode failed %d \n", err); -+ err = -ENOTSUPP; -+ goto exit; -+ } -+ -+ err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_UP error (%d)\n", err); -+ err = -EINVAL; -+ goto exit; -+ } -+ -+ wl_clr_drv_status(wl, AP_CREATED, dev); -+ /* Turn on the MPC */ -+ wldev_iovar_setint(dev, "mpc", 1); -+ } else { -+ AP6210_DEBUG("Stopping P2P GO \n"); -+ } -+ -+exit: -+ return err; -+} -+ -+static s32 -+wl_cfg80211_change_beacon( -+ struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_beacon_data *info) -+{ -+ s32 err = BCME_OK; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct parsed_ies ies; -+ u32 dev_role = 0; -+ s32 bssidx = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ -+ if (dev == wl_to_prmry_ndev(wl)) { -+ dev_role = NL80211_IFTYPE_AP; -+ } else if (dev == wl->p2p_net) { -+ /* Group Add request on p2p0 */ -+ dev = wl_to_prmry_ndev(wl); -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ if (p2p_is_on(wl) && -+ (bssidx == wl_to_p2p_bss_bssidx(wl, -+ P2PAPI_BSSCFG_CONNECTION))) { -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ /* Set IEs to FW */ -+ if ((err = wl_cfg80211_parse_set_ies(dev, info, -+ &ies, dev_role, bssidx) < 0)) { -+ AP6210_ERR("Set IEs failed \n"); -+ goto fail; -+ } -+ -+ if (dev_role == NL80211_IFTYPE_AP) { -+ if (wl_cfg80211_hostapd_sec(dev, &ies, bssidx) < 0) { -+ AP6210_ERR("Hostapd update sec failed \n"); -+ err = -EINVAL; -+ goto fail; -+ } -+ } -+ -+fail: -+ return err; -+} -+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */ -+static s32 -+wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, -+ struct beacon_parameters *info) -+{ -+ s32 err = BCME_OK; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ s32 ie_offset = 0; -+ s32 bssidx = 0; -+ u32 dev_role = NL80211_IFTYPE_AP; -+ struct parsed_ies ies; -+ bcm_tlv_t *ssid_ie; -+ bool pbc = 0; -+ -+ AP6210_DEBUG("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n", -+ info->interval, info->dtim_period, info->head_len, info->tail_len); -+ -+ if (dev == wl_to_prmry_ndev(wl)) { -+ dev_role = NL80211_IFTYPE_AP; -+ } else if (dev == wl->p2p_net) { -+ /* Group Add request on p2p0 */ -+ dev = wl_to_prmry_ndev(wl); -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ bssidx = wl_cfgp2p_find_idx(wl, dev); -+ if (p2p_is_on(wl) && -+ (bssidx == wl_to_p2p_bss_bssidx(wl, -+ P2PAPI_BSSCFG_CONNECTION))) { -+ dev_role = NL80211_IFTYPE_P2P_GO; -+ } -+ -+ ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; -+ /* find the SSID */ -+ if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset], -+ info->head_len - ie_offset, -+ DOT11_MNG_SSID_ID)) != NULL) { -+ if (dev_role == NL80211_IFTYPE_AP) { -+ /* Store the hostapd SSID */ -+ memset(&wl->hostapd_ssid.SSID[0], 0x00, 32); -+ memcpy(&wl->hostapd_ssid.SSID[0], ssid_ie->data, ssid_ie->len); -+ wl->hostapd_ssid.SSID_len = ssid_ie->len; -+ } else { -+ /* P2P GO */ -+ memset(&wl->p2p->ssid.SSID[0], 0x00, 32); -+ memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len); -+ wl->p2p->ssid.SSID_len = ssid_ie->len; -+ } -+ } -+ -+ if (wl_cfg80211_parse_ies((u8 *)info->tail, -+ info->tail_len, &ies) < 0) { -+ AP6210_ERR("Beacon get IEs failed \n"); -+ err = -EINVAL; -+ goto fail; -+ } -+ -+ if (wl_cfgp2p_set_management_ie(wl, dev, bssidx, -+ VNDR_IE_BEACON_FLAG, (u8 *)info->tail, -+ info->tail_len) < 0) { -+ AP6210_ERR("Beacon set IEs failed \n"); -+ goto fail; -+ } else { -+ AP6210_DEBUG("Applied Vndr IEs for Beacon \n"); -+ } -+ if (!wl_cfgp2p_bss_isup(dev, bssidx) && -+ (wl_cfg80211_bcn_validate_sec(dev, &ies, dev_role, bssidx) < 0)) -+ { -+ AP6210_ERR("Beacon set security failed \n"); -+ goto fail; -+ } -+ -+ /* Set BI and DTIM period */ -+ if (info->interval) { -+ if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD, -+ &info->interval, sizeof(s32), true)) < 0) { -+ AP6210_ERR("Beacon Interval Set Error, %d\n", err); -+ return err; -+ } -+ } -+ if (info->dtim_period) { -+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, -+ &info->dtim_period, sizeof(s32), true)) < 0) { -+ AP6210_ERR("DTIM Interval Set Error, %d\n", err); -+ return err; -+ } -+ } -+ -+ if (wl_cfg80211_bcn_bringup_ap(dev, &ies, dev_role, bssidx) < 0) { -+ AP6210_ERR("Beacon bring up AP/GO failed \n"); -+ goto fail; -+ } -+ -+ if (wl_get_drv_status(wl, AP_CREATED, dev)) { -+ /* Soft AP already running. Update changed params */ -+ if (wl_cfg80211_hostapd_sec(dev, &ies, bssidx) < 0) { -+ AP6210_ERR("Hostapd update sec failed \n"); -+ err = -EINVAL; -+ goto fail; -+ } -+ } -+ -+ /* Enable Probe Req filter */ -+ if (((dev_role == NL80211_IFTYPE_P2P_GO) || -+ (dev_role == NL80211_IFTYPE_AP)) && (ies.wps_ie != NULL)) { -+ wl_validate_wps_ie((char *) ies.wps_ie, ies.wps_ie_len, &pbc); -+ if (pbc) -+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, true); -+ } -+ -+ AP6210_DEBUG("** ADD/SET beacon done **\n"); -+ -+fail: -+ if (err) { -+ AP6210_ERR("ADD/SET beacon failed\n"); -+ wldev_iovar_setint(dev, "mpc", 1); -+ } -+ return err; -+ -+} -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */ -+ -+#ifdef WL_SCHED_SCAN -+#define PNO_TIME 30 -+#define PNO_REPEAT 4 -+#define PNO_FREQ_EXPO_MAX 2 -+int wl_cfg80211_sched_scan_start(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_sched_scan_request *request) -+{ -+ ushort pno_time = PNO_TIME; -+ int pno_repeat = PNO_REPEAT; -+ int pno_freq_expo_max = PNO_FREQ_EXPO_MAX; -+ wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ struct cfg80211_ssid *ssid = NULL; -+ int ssid_count = 0; -+ int i; -+ int ret = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ AP6210_DEBUG(">>> SCHED SCAN START\n"); -+ AP6210_DEBUG("Enter n_match_sets:%d n_ssids:%d \n", -+ request->n_match_sets, request->n_ssids); -+ AP6210_DEBUG("ssids:%d pno_time:%d pno_repeat:%d pno_freq:%d \n", -+ request->n_ssids, pno_time, pno_repeat, pno_freq_expo_max); -+ -+ -+ if (!request || !request->n_ssids || !request->n_match_sets) { -+ AP6210_ERR("Invalid sched scan req!! n_ssids:%d \n", request->n_ssids); -+ return -EINVAL; -+ } -+ -+ memset(&ssids_local, 0, sizeof(ssids_local)); -+ -+ if (request->n_match_sets > 0) { -+ for (i = 0; i < request->n_match_sets; i++) { -+ ssid = &request->match_sets[i].ssid; -+ memcpy(ssids_local[i].SSID, ssid->ssid, ssid->ssid_len); -+ ssids_local[i].SSID_len = ssid->ssid_len; -+ AP6210_DEBUG(">>> PNO filter set for ssid (%s) \n", ssid->ssid); -+ ssid_count++; -+ } -+ } -+ -+ if (request->n_ssids > 0) { -+ for (i = 0; i < request->n_ssids; i++) { -+ /* Active scan req for ssids */ -+ AP6210_DEBUG(">>> Active scan req for ssid (%s) \n", request->ssids[i].ssid); -+ -+ /* match_set ssids is a supert set of n_ssid list, so we need -+ * not add these set seperately -+ */ -+ } -+ } -+ -+ if (ssid_count) { -+ if ((ret = dhd_dev_pno_set(dev, ssids_local, request->n_match_sets, -+ pno_time, pno_repeat, pno_freq_expo_max)) < 0) { -+ AP6210_ERR("PNO setup failed!! ret=%d \n", ret); -+ return -EINVAL; -+ } -+ -+ /* Enable the PNO */ -+ if (dhd_dev_pno_enable(dev, 1) < 0) { -+ AP6210_ERR("PNO enable failed!! ret=%d \n", ret); -+ return -EINVAL; -+ } -+ wl->sched_scan_req = request; -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) -+{ -+ struct wl_priv *wl = wiphy_priv(wiphy); -+ -+ AP6210_DEBUG("Enter \n"); -+ AP6210_DEBUG(">>> SCHED SCAN STOP\n"); -+ -+ if (dhd_dev_pno_enable(dev, 0) < 0) -+ AP6210_ERR("PNO disable failed"); -+ -+ if (dhd_dev_pno_reset(dev) < 0) -+ AP6210_ERR("PNO reset failed"); -+ -+ if (wl->scan_request && wl->sched_scan_running) { -+ AP6210_DEBUG(">>> Sched scan running. Aborting it..\n"); -+ wl_notify_escan_complete(wl, dev, true, true); -+ } -+ -+ wl->sched_scan_req = NULL; -+ wl->sched_scan_running = FALSE; -+ -+ return 0; -+} -+#endif /* WL_SCHED_SCAN */ -+ -+static struct cfg80211_ops wl_cfg80211_ops = { -+ .add_virtual_intf = wl_cfg80211_add_virtual_iface, -+ .del_virtual_intf = wl_cfg80211_del_virtual_iface, -+ .change_virtual_intf = wl_cfg80211_change_virtual_iface, -+ .scan = wl_cfg80211_scan, -+ .set_wiphy_params = wl_cfg80211_set_wiphy_params, -+ .join_ibss = wl_cfg80211_join_ibss, -+ .leave_ibss = wl_cfg80211_leave_ibss, -+ .get_station = wl_cfg80211_get_station, -+ .set_tx_power = wl_cfg80211_set_tx_power, -+ .get_tx_power = wl_cfg80211_get_tx_power, -+ .add_key = wl_cfg80211_add_key, -+ .del_key = wl_cfg80211_del_key, -+ .get_key = wl_cfg80211_get_key, -+ .set_default_key = wl_cfg80211_config_default_key, -+ .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key, -+ .set_power_mgmt = wl_cfg80211_set_power_mgmt, -+ .connect = wl_cfg80211_connect, -+ .disconnect = wl_cfg80211_disconnect, -+ .suspend = wl_cfg80211_suspend, -+ .resume = wl_cfg80211_resume, -+ .set_pmksa = wl_cfg80211_set_pmksa, -+ .del_pmksa = wl_cfg80211_del_pmksa, -+ .flush_pmksa = wl_cfg80211_flush_pmksa, -+ .remain_on_channel = wl_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = wl_cfg80211_mgmt_tx, -+ .mgmt_frame_register = wl_cfg80211_mgmt_frame_register, -+ .change_bss = wl_cfg80211_change_bss, -+ .set_channel = wl_cfg80211_set_channel, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) -+ .set_beacon = wl_cfg80211_add_set_beacon, -+ .add_beacon = wl_cfg80211_add_set_beacon, -+#else -+ .change_beacon = wl_cfg80211_change_beacon, -+ .start_ap = wl_cfg80211_start_ap, -+ .stop_ap = wl_cfg80211_stop_ap, -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */ -+#ifdef WL_SCHED_SCAN -+ .sched_scan_start = wl_cfg80211_sched_scan_start, -+ .sched_scan_stop = wl_cfg80211_sched_scan_stop, -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ -+ 2, 0)) -+ .del_station = wl_cfg80211_del_station, -+ .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait, -+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VERSION >= (3,2,0) */ -+}; -+ -+s32 wl_mode_to_nl80211_iftype(s32 mode) -+{ -+ s32 err = 0; -+ -+ switch (mode) { -+ case WL_MODE_BSS: -+ return NL80211_IFTYPE_STATION; -+ case WL_MODE_IBSS: -+ return NL80211_IFTYPE_ADHOC; -+ case WL_MODE_AP: -+ return NL80211_IFTYPE_AP; -+ default: -+ return NL80211_IFTYPE_UNSPECIFIED; -+ } -+ -+ return err; -+} -+ -+static int -+wl_cfg80211_reg_notifier( -+ struct wiphy *wiphy, -+ struct regulatory_request *request) -+{ -+ struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy); -+ wl_country_t cspec = {{0}, 0, {0} }; -+ int ret = 0; -+ -+ if (!request || !wl) { -+ AP6210_ERR("Invalid arg\n"); -+ return -EINVAL; -+ } -+ -+ AP6210_DEBUG("ccode: %c%c Initiator: %d\n", -+ request->alpha2[0], request->alpha2[1], request->initiator); -+ -+ /* We support only REGDOM_SET_BY_USER as of now */ -+ if (request->initiator != NL80211_REGDOM_SET_BY_USER) { -+ AP6210_ERR("reg_notifier for intiator:%d not supported \n", -+ request->initiator); -+ return -ENOTSUPP; -+ } -+ -+ if (request->alpha2[0] == '0' && request->alpha2[1] == '0') { -+ /* world domain */ -+ AP6210_ERR("World domain. Setting XY/4 \n"); -+ strncpy(cspec.country_abbrev, "XY", strlen("XY")); -+ cspec.rev = 4; -+ } else { -+ memcpy(cspec.country_abbrev, request->alpha2, 2); -+ cspec.country_abbrev[3] = '\0'; -+ cspec.rev = -1; /* Unspecified */ -+ } -+ -+ if ((ret = wldev_iovar_setbuf(wl_to_prmry_ndev(wl), "country", (char *)&cspec, -+ sizeof(cspec), wl->ioctl_buf, WLC_IOCTL_SMLEN, NULL)) < 0) { -+ AP6210_ERR("set country Failed :%d\n", ret); -+ goto exit; -+ } -+ -+ if ((ret = wl_update_wiphybands(wl, false)) < 0) { -+ AP6210_ERR("wl_update_wiphybands failed\n"); -+ goto exit; -+ } -+ -+ AP6210_DEBUG("%s: set country '%s/%d' done\n", -+ __FUNCTION__, cspec.country_abbrev, cspec.rev); -+ -+exit: -+ return ret; -+} -+ -+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev) -+{ -+ s32 err = 0; -+ wdev->wiphy = -+ wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv)); -+ if (unlikely(!wdev->wiphy)) { -+ AP6210_ERR("Couldn not allocate wiphy device\n"); -+ err = -ENOMEM; -+ return err; -+ } -+ set_wiphy_dev(wdev->wiphy, sdiofunc_dev); -+ wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX; -+ /* Report how many SSIDs Driver can support per Scan request */ -+ wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX; -+ wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; -+#ifdef WL_SCHED_SCAN -+ wdev->wiphy->max_sched_scan_ssids = MAX_PFN_LIST_COUNT; -+ wdev->wiphy->max_match_sets = MAX_PFN_LIST_COUNT; -+ wdev->wiphy->max_sched_scan_ie_len = WL_SCAN_IE_LEN_MAX; -+ wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; -+#endif /* WL_SCHED_SCAN */ -+ wdev->wiphy->interface_modes = -+ BIT(NL80211_IFTYPE_STATION) -+#if !(defined(WLP2P) && defined(WL_ENABLE_P2P_IF)) -+ | BIT(NL80211_IFTYPE_MONITOR) -+#endif -+ | BIT(NL80211_IFTYPE_AP); -+ -+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; -+ -+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ wdev->wiphy->cipher_suites = __wl_cipher_suites; -+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); -+ wdev->wiphy->max_remain_on_channel_duration = 5000; -+ wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes; -+#ifndef WL_POWERSAVE_DISABLED -+ wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; -+#else -+ wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -+#endif /* !WL_POWERSAVE_DISABLED */ -+ wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK | -+ WIPHY_FLAG_4ADDR_AP | -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39) -+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS | -+#endif -+ WIPHY_FLAG_4ADDR_STATION; -+ /* If driver advertises FW_ROAM, the supplicant wouldn't -+ * send the BSSID & Freq in the connect command allowing the -+ * the driver to choose the AP to connect to. But unless we -+ * support ROAM_CACHE in firware this will delay the ASSOC as -+ * as the FW need to do a full scan before attempting to connect -+ * So that feature will just increase assoc. The better approach -+ * to let Supplicant to provide channel info and FW letter may roam -+ * if needed so DON'T advertise that featur eto Supplicant. -+ */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) -+ /* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) -+ wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | -+ WIPHY_FLAG_OFFCHAN_TX; -+#endif -+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ -+ 4, 0)) -+ /* From 3.4 kernel ownards AP_SME flag can be advertised -+ * to remove the patch from supplicant -+ */ -+ wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; -+#endif -+ -+ wdev->wiphy->reg_notifier = wl_cfg80211_reg_notifier; -+ -+ AP6210_DEBUG("Registering custom regulatory)\n"); -+ wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; -+ wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); -+ /* Now we can register wiphy with cfg80211 module */ -+ err = wiphy_register(wdev->wiphy); -+ if (unlikely(err < 0)) { -+ AP6210_ERR("Couldn not register wiphy device (%d)\n", err); -+ wiphy_free(wdev->wiphy); -+ } -+ return err; -+} -+ -+static void wl_free_wdev(struct wl_priv *wl) -+{ -+ struct wireless_dev *wdev = wl->wdev; -+ struct wiphy *wiphy; -+ if (!wdev) { -+ AP6210_ERR("wdev is invalid\n"); -+ return; -+ } -+ wiphy = wdev->wiphy; -+ wiphy_unregister(wdev->wiphy); -+ wdev->wiphy->dev.parent = NULL; -+ -+ wl_delete_all_netinfo(wl); -+ wiphy_free(wiphy); -+ /* PLEASE do NOT call any function after wiphy_free, the driver's private structure "wl", -+ * which is the private part of wiphy, has been freed in wiphy_free !!!!!!!!!!! -+ */ -+} -+ -+#if defined(RSSIAVG) -+static wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; -+#endif -+#if defined(BSSCACHE) -+static wl_bss_cache_ctrl_t g_bss_cache_ctrl; -+#endif -+ -+static s32 wl_inform_bss(struct wl_priv *wl) -+{ -+ struct wl_scan_results *bss_list; -+ struct wl_bss_info *bi = NULL; /* must be initialized */ -+ s32 err = 0; -+ s32 i; -+#if defined(RSSIAVG) -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+#endif -+#if defined(BSSCACHE) -+ wl_bss_cache_t *node; -+#endif -+ -+ bss_list = wl->bss_list; -+#if defined(BSSCACHE) -+ if (g_bss_cache_ctrl.m_timer_expired || (p2p_is_on(wl) && p2p_scan(wl))) { -+#if defined(RSSIAVG) -+ wl_free_rssi_cache(&g_rssi_cache_ctrl); -+#endif -+ wl_free_bss_cache(&g_bss_cache_ctrl); -+ g_bss_cache_ctrl.m_timer_expired ^= 1; -+ } -+ wl_update_bss_cache(&g_bss_cache_ctrl, bss_list); -+ wl_delete_dirty_bss_cache(&g_bss_cache_ctrl); -+ wl_reset_bss_cache(&g_bss_cache_ctrl); -+#endif -+ -+#if defined(RSSIAVG) -+#if defined(BSSCACHE) -+ node = g_bss_cache_ctrl.m_cache_head; -+ for (;node;) { -+ wl_update_rssi_cache(&g_rssi_cache_ctrl, &node->results); -+ node = node->next; -+ } -+#else -+ wl_update_rssi_cache(&g_rssi_cache_ctrl, bss_list); -+#endif -+ if (!in_atomic()) -+ wl_update_connected_rssi_cache(&g_rssi_cache_ctrl, ndev); -+ wl_delete_dirty_rssi_cache(&g_rssi_cache_ctrl); -+ wl_reset_rssi_cache(&g_rssi_cache_ctrl); -+#endif -+ -+ AP6210_DEBUG("scanned AP count (%d)\n", bss_list->count); -+ -+#if defined(BSSCACHE) -+ node = g_bss_cache_ctrl.m_cache_head; -+ for (i=0; node && iresults.bss_info; -+ err = wl_inform_single_bss(wl, bi, 0); -+ if (unlikely(err)) -+ break; -+ node = node->next; -+ } -+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); -+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 1); -+#else -+ bi = next_bss(bss_list, bi); -+ for_each_bss(bss_list, bi, i) { -+ err = wl_inform_single_bss(wl, bi, 0); -+ if (unlikely(err)) -+ break; -+ } -+#endif -+ return err; -+} -+ -+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done) -+{ -+ struct wiphy *wiphy = wl_to_wiphy(wl); -+ struct ieee80211_mgmt *mgmt; -+ struct ieee80211_channel *channel; -+ struct ieee80211_supported_band *band; -+ struct wl_cfg80211_bss_info *notif_bss_info; -+ struct wl_scan_req *sr = wl_to_sr(wl); -+ struct beacon_proberesp *beacon_proberesp; -+ struct cfg80211_bss *cbss = NULL; -+ s32 mgmt_type; -+ s32 signal; -+ u32 freq; -+ s32 err = 0; -+ gfp_t aflags; -+ u8 *ie_offset = NULL; -+ -+ if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { -+ AP6210_DEBUG("Beacon is larger than buffer. Discarding\n"); -+ return err; -+ } -+ aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; -+ notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) -+ - sizeof(u8) + WL_BSS_INFO_MAX, aflags); -+ if (unlikely(!notif_bss_info)) { -+ AP6210_ERR("notif_bss_info alloc failed\n"); -+ return -ENOMEM; -+ } -+ mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf; -+ notif_bss_info->channel = -+ bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec)); -+ -+ if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) -+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; -+ else -+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; -+ if (!band) { -+ AP6210_ERR("No valid band"); -+ kfree(notif_bss_info); -+ return -EINVAL; -+ } -+ notif_bss_info->rssi = dtoh16(bi->RSSI); -+#if defined(RSSIAVG) -+ notif_bss_info->rssi = wl_get_avg_rssi(&g_rssi_cache_ctrl, &bi->BSSID); -+#endif -+#if defined(RSSIOFFSET) -+ notif_bss_info->rssi = wl_update_rssi_offset(notif_bss_info->rssi); -+#endif -+ memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); -+ mgmt_type = wl->active_scan ? -+ IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON; -+ if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) { -+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type); -+ } -+ beacon_proberesp = wl->active_scan ? -+ (struct beacon_proberesp *)&mgmt->u.probe_resp : -+ (struct beacon_proberesp *)&mgmt->u.beacon; -+ beacon_proberesp->timestamp = 0; -+ beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period); -+ beacon_proberesp->capab_info = cpu_to_le16(bi->capability); -+ wl_rst_ie(wl); -+ -+ ie_offset = ((u8 *) bi) + bi->ie_offset; -+ -+ if (is_roam_done && ((int)(*(ie_offset)) == WLAN_EID_SSID && -+ ((int)(*(ie_offset+1)) == 0 || (int)(*(ie_offset+2)) == 0))) { -+ u8 *ie_new_offset = NULL; -+ uint8 ie_new_length; -+ -+ AP6210_ERR("WAR trace: Changing the SSID Info, from beacon %d\n", -+ bi->flags & WL_BSS_FLAGS_FROM_BEACON); -+ -+ ie_new_offset = (u8 *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); -+ if (ie_new_offset) { -+ *(ie_new_offset) = WLAN_EID_SSID; -+ *(ie_new_offset+1) = bi->SSID_len; -+ memcpy(ie_new_offset+2, bi->SSID, bi->SSID_len); -+ ie_new_length = bi->ie_length - *(ie_offset+1) + bi->SSID_len; -+ -+ /* Copy the remaining IE apart from SSID IE from bi */ -+ memcpy(ie_new_offset+2 + bi->SSID_len, -+ ie_offset+2 + *(ie_offset+1), -+ bi->ie_length - 2 - *(ie_offset+1)); -+ wl_mrg_ie(wl, ie_new_offset, ie_new_length); -+ kfree(ie_new_offset); -+ } else { -+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); -+ } -+ } else { -+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); -+ } -+ -+ wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - -+ offsetof(struct wl_cfg80211_bss_info, frame_buf)); -+ notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, -+ u.beacon.variable) + wl_get_ielen(wl); -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) -+ freq = ieee80211_channel_to_frequency(notif_bss_info->channel); -+ (void)band->band; -+#else -+ freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band); -+#endif -+ if (freq == 0) { -+ AP6210_ERR("Invalid channel, fail to chcnage channel to freq\n"); -+ kfree(notif_bss_info); -+ return -EINVAL; -+ } -+ channel = ieee80211_get_channel(wiphy, freq); -+ if (unlikely(!channel)) { -+ AP6210_ERR("ieee80211_get_channel error\n"); -+ kfree(notif_bss_info); -+ return -EINVAL; -+ } -+ AP6210_DEBUG("BSSID %pM, channel %d, rssi %d, capability 0x04%x, mgmt_type %d, " -+ "frame_len %d, SSID \"%s\"\n", &bi->BSSID, notif_bss_info->channel, -+ notif_bss_info->rssi, mgmt->u.beacon.capab_info, mgmt_type, -+ notif_bss_info->frame_len, bi->SSID); -+ -+ signal = notif_bss_info->rssi * 100; -+ if (!mgmt->u.probe_resp.timestamp) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) -+ struct timespec ts; -+ get_monotonic_boottime(&ts); -+ mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) -+ + ts.tv_nsec / 1000; -+#else -+ struct timeval tv; -+ do_gettimeofday(&tv); -+ mgmt->u.probe_resp.timestamp = ((u64)tv.tv_sec*1000000) -+ + tv.tv_usec; -+#endif -+ } -+ -+ cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, -+ le16_to_cpu(notif_bss_info->frame_len), signal, aflags); -+ if (unlikely(!cbss)) { -+ AP6210_ERR("cfg80211_inform_bss_frame error\n"); -+ kfree(notif_bss_info); -+ return -EINVAL; -+ } -+ -+ cfg80211_put_bss(cbss); -+ kfree(notif_bss_info); -+ return err; -+} -+ -+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev) -+{ -+ u32 event = ntoh32(e->event_type); -+ u32 status = ntoh32(e->status); -+ u16 flags = ntoh16(e->flags); -+ -+ AP6210_DEBUG("event %d, status %d flags %x\n", event, status, flags); -+ if (event == WLC_E_SET_SSID) { -+ if (status == WLC_E_STATUS_SUCCESS) { -+ if (!wl_is_ibssmode(wl, ndev)) -+ return true; -+ } -+ } else if (event == WLC_E_LINK) { -+ if (flags & WLC_EVENT_MSG_LINK) -+ return true; -+ } -+ -+ AP6210_DEBUG("wl_is_linkup false\n"); -+ return false; -+} -+ -+static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) -+{ -+ u32 event = ntoh32(e->event_type); -+ u16 flags = ntoh16(e->flags); -+ -+ if (event == WLC_E_DEAUTH_IND || -+ event == WLC_E_DISASSOC_IND || -+ event == WLC_E_DISASSOC || -+ event == WLC_E_DEAUTH) { -+#if (WL_DBG_LEVEL > 0) -+ AP6210_ERR("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]); -+#endif /* (WL_DBG_LEVEL > 0) */ -+ return true; -+ } else if (event == WLC_E_LINK) { -+ if (!(flags & WLC_EVENT_MSG_LINK)) { -+#if (WL_DBG_LEVEL > 0) -+ AP6210_ERR("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]); -+#endif /* (WL_DBG_LEVEL > 0) */ -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) -+{ -+ u32 event = ntoh32(e->event_type); -+ u32 status = ntoh32(e->status); -+ -+ if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) -+ return true; -+ if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) -+ return true; -+ -+ return false; -+} -+ -+/* The mainline kernel >= 3.2.0 has support for indicating new/del station -+ * to AP/P2P GO via events. If this change is backported to kernel for which -+ * this driver is being built, then define WL_CFG80211_STA_EVENT. You -+ * should use this new/del sta event mechanism for BRCM supplicant >= 22. -+ */ -+static s32 -+wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ s32 err = 0; -+ u32 event = ntoh32(e->event_type); -+ u32 reason = ntoh32(e->reason); -+ u32 len = ntoh32(e->datalen); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) -+ bool isfree = false; -+ u8 *mgmt_frame; -+ u8 bsscfgidx = e->bsscfgidx; -+ s32 freq; -+ s32 channel; -+ u8 *body = NULL; -+ u16 fc = 0; -+ -+ struct ieee80211_supported_band *band; -+ struct ether_addr da; -+ struct ether_addr bssid; -+ struct wiphy *wiphy = wl_to_wiphy(wl); -+ channel_info_t ci; -+#else -+ struct station_info sinfo; -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !WL_CFG80211_STA_EVENT */ -+ -+ AP6210_DEBUG("event %d status %d reason %d\n", event, ntoh32(e->status), reason); -+ /* if link down, bsscfg is disabled. */ -+ if (event == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS && -+ wl_get_p2p_status(wl, IF_DELETING) && (ndev != wl_to_prmry_ndev(wl))) { -+ wl_add_remove_eventmsg(ndev, WLC_E_PROBREQ_MSG, false); -+ AP6210_DEBUG("AP mode link down !! \n"); -+ complete(&wl->iface_disable); -+ return 0; -+ } -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT) -+ AP6210_DEBUG("Enter \n"); -+ if (!len && (event == WLC_E_DEAUTH)) { -+ len = 2; /* reason code field */ -+ data = &reason; -+ } -+ if (len) { -+ body = kzalloc(len, GFP_KERNEL); -+ -+ if (body == NULL) { -+ AP6210_ERR("wl_notify_connect_status: Failed to allocate body\n"); -+ return WL_INVALID; -+ } -+ } -+ memset(&bssid, 0, ETHER_ADDR_LEN); -+ AP6210_DEBUG("Enter event %d ndev %p\n", event, ndev); -+ if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) { -+ kfree(body); -+ return WL_INVALID; -+ } -+ if (len) -+ memcpy(body, data, len); -+ -+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", -+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync); -+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); -+ err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); -+ switch (event) { -+ case WLC_E_ASSOC_IND: -+ fc = FC_ASSOC_REQ; -+ break; -+ case WLC_E_REASSOC_IND: -+ fc = FC_REASSOC_REQ; -+ break; -+ case WLC_E_DISASSOC_IND: -+ fc = FC_DISASSOC; -+ break; -+ case WLC_E_DEAUTH_IND: -+ fc = FC_DISASSOC; -+ break; -+ case WLC_E_DEAUTH: -+ fc = FC_DISASSOC; -+ break; -+ default: -+ fc = 0; -+ goto exit; -+ } -+ if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) { -+ kfree(body); -+ return err; -+ } -+ -+ channel = dtoh32(ci.hw_channel); -+ if (channel <= CH_MAX_2G_CHANNEL) -+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; -+ else -+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; -+ if (!band) { -+ AP6210_ERR("No valid band"); -+ if (body) -+ kfree(body); -+ return -EINVAL; -+ } -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) -+ freq = ieee80211_channel_to_frequency(channel); -+ (void)band->band; -+#else -+ freq = ieee80211_channel_to_frequency(channel, band->band); -+#endif -+ -+ err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid, -+ &mgmt_frame, &len, body); -+ if (err < 0) -+ goto exit; -+ isfree = true; -+ -+ if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); -+#else -+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ } else if (event == WLC_E_DISASSOC_IND) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); -+#else -+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC); -+#else -+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ } -+ -+exit: -+ if (isfree) -+ kfree(mgmt_frame); -+ if (body) -+ kfree(body); -+ return err; -+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */ -+ sinfo.filled = 0; -+ if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) && -+ reason == DOT11_SC_SUCCESS) { -+ sinfo.filled = STATION_INFO_ASSOC_REQ_IES; -+ if (!data) { -+ AP6210_ERR("No IEs present in ASSOC/REASSOC_IND"); -+ return -EINVAL; -+ } -+ sinfo.assoc_req_ies = data; -+ sinfo.assoc_req_ies_len = len; -+ cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC); -+ } else if (event == WLC_E_DISASSOC_IND) { -+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); -+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { -+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); -+ } -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */ -+ return err; -+} -+ -+static s32 -+wl_get_auth_assoc_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e) -+{ -+ u32 reason = ntoh32(e->reason); -+ u32 event = ntoh32(e->event_type); -+ struct wl_security *sec = wl_read_prof(wl, ndev, WL_PROF_SEC); -+ AP6210_DEBUG("event type : %d, reason : %d\n", event, reason); -+ if (sec) { -+ switch (event) { -+ case WLC_E_ASSOC: -+ case WLC_E_AUTH: -+ sec->auth_assoc_res_status = reason; -+ default: -+ break; -+ } -+ } else -+ AP6210_ERR("sec is NULL\n"); -+ return 0; -+} -+ -+static s32 -+wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ bool act; -+ s32 err = 0; -+ u32 event = ntoh32(e->event_type); -+ -+ if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { -+ wl_notify_connect_status_ap(wl, ndev, e, data); -+ } else { -+ AP6210_DEBUG("wl_notify_connect_status : event %d status : %d ndev %p\n", -+ ntoh32(e->event_type), ntoh32(e->status), ndev); -+ if (event == WLC_E_ASSOC || event == WLC_E_AUTH) { -+ wl_get_auth_assoc_status(wl, ndev, e); -+ return err; -+ } -+ if (wl_is_linkup(wl, e, ndev)) { -+ wl_link_up(wl); -+ act = true; -+ if (wl_is_ibssmode(wl, ndev)) { -+ AP6210_DEBUG("cfg80211_ibss_joined\n"); -+ cfg80211_ibss_joined(ndev, (s8 *)&e->addr, -+ GFP_KERNEL); -+ AP6210_DEBUG("joined in IBSS network\n"); -+ } else { -+ if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) { -+ AP6210_DEBUG("wl_bss_connect_done succeeded with " MACDBG "\n", -+ MAC2STRDBG((u8*)(&e->addr))); -+ wl_bss_connect_done(wl, ndev, e, data, true); -+ AP6210_DEBUG("joined in BSS network \"%s\"\n", -+ ((struct wlc_ssid *) -+ wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID); -+ } -+ } -+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); -+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); -+ -+ } else if (wl_is_linkdown(wl, e)) { -+ if (wl->scan_request) { -+ if (wl->escan_on) { -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } else { -+ del_timer_sync(&wl->scan_timeout); -+ wl_iscan_aborted(wl); -+ } -+ } -+ if (wl_get_drv_status(wl, CONNECTED, ndev)) { -+ scb_val_t scbval; -+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); -+ s32 reason = 0; -+ if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) -+ reason = ntoh32(e->reason); -+ /* WLAN_REASON_UNSPECIFIED is used for hang up event in Android */ -+ reason = (reason == WLAN_REASON_UNSPECIFIED)? 0 : reason; -+ -+ AP6210_DEBUG("link down if %s may call cfg80211_disconnected. " -+ "event : %d, reason=%d from " MACDBG "\n", -+ ndev->name, event, ntoh32(e->reason), -+ MAC2STRDBG((u8*)(&e->addr))); -+ if (memcmp(curbssid, &e->addr, ETHER_ADDR_LEN) != 0) { -+ AP6210_ERR("BSSID of event is not the connected BSSID" -+ "(ignore it) cur: " MACDBG " event: " MACDBG"\n", -+ MAC2STRDBG(curbssid), MAC2STRDBG((u8*)(&e->addr))); -+ return 0; -+ } -+ wl_clr_drv_status(wl, CONNECTED, ndev); -+ if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) { -+ /* To make sure disconnect, explictly send dissassoc -+ * for BSSID 00:00:00:00:00:00 issue -+ */ -+ scbval.val = WLAN_REASON_DEAUTH_LEAVING; -+ -+ memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); -+ scbval.val = htod32(scbval.val); -+ err = wldev_ioctl(ndev, WLC_DISASSOC, &scbval, -+ sizeof(scb_val_t), true); -+ if (err < 0) { -+ AP6210_ERR("WLC_DISASSOC error %d\n", err); -+ err = 0; -+ } -+ cfg80211_disconnected(ndev, reason, NULL, 0, GFP_KERNEL); -+ wl_link_down(wl); -+ wl_init_prof(wl, ndev); -+ } -+ } -+ else if (wl_get_drv_status(wl, CONNECTING, ndev)) { -+ AP6210_DEBUG("link down, during connecting\n"); -+#ifdef ESCAN_RESULT_PATCH -+ if ((memcmp(connect_req_bssid, broad_bssid, ETHER_ADDR_LEN) == 0) || -+ (memcmp(&e->addr, broad_bssid, ETHER_ADDR_LEN) == 0) || -+ (memcmp(&e->addr, connect_req_bssid, ETHER_ADDR_LEN) == 0)) -+ /* In case this event comes while associating another AP */ -+#endif /* ESCAN_RESULT_PATCH */ -+ wl_bss_connect_done(wl, ndev, e, data, false); -+ } -+ wl_clr_drv_status(wl, DISCONNECTING, ndev); -+ -+ /* if link down, bsscfg is diabled */ -+ if (ndev != wl_to_prmry_ndev(wl)) -+ complete(&wl->iface_disable); -+ -+ } else if (wl_is_nonetwork(wl, e)) { -+ AP6210_DEBUG("connect failed event=%d e->status %d e->reason %d \n", -+ event, (int)ntoh32(e->status), (int)ntoh32(e->reason)); -+ /* Clean up any pending scan request */ -+ if (wl->scan_request) { -+ if (wl->escan_on) { -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } else { -+ del_timer_sync(&wl->scan_timeout); -+ wl_iscan_aborted(wl); -+ } -+ } -+ if (wl_get_drv_status(wl, CONNECTING, ndev)) -+ wl_bss_connect_done(wl, ndev, e, data, false); -+ } else { -+ AP6210_DEBUG("%s nothing\n", __FUNCTION__); -+ } -+ } -+ return err; -+} -+ -+static s32 -+wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ bool act; -+ s32 err = 0; -+ u32 event = be32_to_cpu(e->event_type); -+ u32 status = be32_to_cpu(e->status); -+ AP6210_DEBUG("Enter \n"); -+ if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) { -+ if (wl_get_drv_status(wl, CONNECTED, ndev)) -+ wl_bss_roaming_done(wl, ndev, e, data); -+ else -+ wl_bss_connect_done(wl, ndev, e, data, true); -+ act = true; -+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); -+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); -+ } -+ return err; -+} -+ -+static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev) -+{ -+ wl_assoc_info_t assoc_info; -+ struct wl_connect_info *conn_info = wl_to_conn(wl); -+ s32 err = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ err = wldev_iovar_getbuf(ndev, "assoc_info", NULL, 0, wl->extra_buf, -+ WL_ASSOC_INFO_MAX, NULL); -+ if (unlikely(err)) { -+ AP6210_ERR("could not get assoc info (%d)\n", err); -+ return err; -+ } -+ memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t)); -+ assoc_info.req_len = htod32(assoc_info.req_len); -+ assoc_info.resp_len = htod32(assoc_info.resp_len); -+ assoc_info.flags = htod32(assoc_info.flags); -+ if (conn_info->req_ie_len) { -+ conn_info->req_ie_len = 0; -+ bzero(conn_info->req_ie, sizeof(conn_info->req_ie)); -+ } -+ if (conn_info->resp_ie_len) { -+ conn_info->resp_ie_len = 0; -+ bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie)); -+ } -+ if (assoc_info.req_len) { -+ err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, wl->extra_buf, -+ WL_ASSOC_INFO_MAX, NULL); -+ if (unlikely(err)) { -+ AP6210_ERR("could not get assoc req (%d)\n", err); -+ return err; -+ } -+ conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req); -+ if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) { -+ conn_info->req_ie_len -= ETHER_ADDR_LEN; -+ } -+ if (conn_info->req_ie_len <= MAX_REQ_LINE) -+ memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len); -+ else { -+ AP6210_ERR("%s IE size %d above max %d size \n", -+ __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE); -+ return err; -+ } -+ } else { -+ conn_info->req_ie_len = 0; -+ } -+ if (assoc_info.resp_len) { -+ err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, wl->extra_buf, -+ WL_ASSOC_INFO_MAX, NULL); -+ if (unlikely(err)) { -+ AP6210_ERR("could not get assoc resp (%d)\n", err); -+ return err; -+ } -+ conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp); -+ if (conn_info->resp_ie_len <= MAX_REQ_LINE) -+ memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len); -+ else { -+ AP6210_ERR("%s IE size %d above max %d size \n", -+ __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE); -+ return err; -+ } -+ } else { -+ conn_info->resp_ie_len = 0; -+ } -+ AP6210_DEBUG("req len (%d) resp len (%d)\n", conn_info->req_ie_len, -+ conn_info->resp_ie_len); -+ -+ return err; -+} -+ -+static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, -+ size_t *join_params_size) -+{ -+ chanspec_t chanspec = 0; -+ if (ch != 0) { -+ join_params->params.chanspec_num = 1; -+ join_params->params.chanspec_list[0] = ch; -+ -+ if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL) -+ chanspec |= WL_CHANSPEC_BAND_2G; -+ else -+ chanspec |= WL_CHANSPEC_BAND_5G; -+ -+ chanspec |= WL_CHANSPEC_BW_20; -+ chanspec |= WL_CHANSPEC_CTL_SB_NONE; -+ -+ *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + -+ join_params->params.chanspec_num * sizeof(chanspec_t); -+ -+ join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; -+ join_params->params.chanspec_list[0] |= chanspec; -+ join_params->params.chanspec_list[0] = -+ wl_chspec_host_to_driver(join_params->params.chanspec_list[0]); -+ -+ join_params->params.chanspec_num = -+ htod32(join_params->params.chanspec_num); -+ AP6210_DEBUG("join_params->params.chanspec_list[0]= %X, %d channels\n", -+ join_params->params.chanspec_list[0], -+ join_params->params.chanspec_num); -+ } -+} -+ -+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done) -+{ -+ struct cfg80211_bss *bss; -+ struct wl_bss_info *bi; -+ struct wlc_ssid *ssid; -+ struct bcm_tlv *tim; -+ s32 beacon_interval; -+ s32 dtim_period; -+ size_t ie_len; -+ u8 *ie; -+ u8 *ssidie; -+ u8 *curbssid; -+ s32 err = 0; -+ struct wiphy *wiphy; -+ -+ wiphy = wl_to_wiphy(wl); -+ -+ if (wl_is_ibssmode(wl, ndev)) -+ return err; -+ -+ ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID); -+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); -+ bss = cfg80211_get_bss(wiphy, NULL, curbssid, -+ ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, -+ WLAN_CAPABILITY_ESS); -+ -+ mutex_lock(&wl->usr_sync); -+ if (!bss) { -+ AP6210_DEBUG("Could not find the AP\n"); -+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); -+ err = wldev_ioctl(ndev, WLC_GET_BSS_INFO, -+ wl->extra_buf, WL_EXTRA_BUF_MAX, false); -+ if (unlikely(err)) { -+ AP6210_ERR("Could not get bss info %d\n", err); -+ goto update_bss_info_out; -+ } -+ bi = (struct wl_bss_info *)(wl->extra_buf + 4); -+ if (memcmp(bi->BSSID.octet, curbssid, ETHER_ADDR_LEN)) { -+ err = -EIO; -+ goto update_bss_info_out; -+ } -+ -+ ie = ((u8 *)bi) + bi->ie_offset; -+ ie_len = bi->ie_length; -+ ssidie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ie, ie_len); -+ if (ssidie && ssidie[1] == bi->SSID_len && !ssidie[2] && bi->SSID[0]) -+ memcpy(ssidie + 2, bi->SSID, bi->SSID_len); -+ -+ err = wl_inform_single_bss(wl, bi, is_roam_done); -+ if (unlikely(err)) -+ goto update_bss_info_out; -+ -+ ie = ((u8 *)bi) + bi->ie_offset; -+ ie_len = bi->ie_length; -+ beacon_interval = cpu_to_le16(bi->beacon_period); -+ } else { -+ AP6210_DEBUG("Found the AP in the list - BSSID %pM\n", bss->bssid); -+ ie = bss->information_elements; -+ ie_len = bss->len_information_elements; -+ beacon_interval = bss->beacon_interval; -+ cfg80211_put_bss(bss); -+ } -+ -+ tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); -+ if (tim) { -+ dtim_period = tim->data[1]; -+ } else { -+ /* -+ * active scan was done so we could not get dtim -+ * information out of probe response. -+ * so we speficially query dtim information. -+ */ -+ err = wldev_ioctl(ndev, WLC_GET_DTIMPRD, -+ &dtim_period, sizeof(dtim_period), false); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_GET_DTIMPRD error (%d)\n", err); -+ goto update_bss_info_out; -+ } -+ } -+ -+ wl_update_prof(wl, ndev, NULL, &beacon_interval, WL_PROF_BEACONINT); -+ wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD); -+ -+update_bss_info_out: -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+ -+static s32 -+wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ struct wl_connect_info *conn_info = wl_to_conn(wl); -+ s32 err = 0; -+ u8 *curbssid; -+ -+ wl_get_assoc_ies(wl, ndev); -+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); -+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); -+ wl_update_bss_info(wl, ndev, 1); -+ wl_update_pmklist(ndev, wl->pmk_list, err); -+ AP6210_DEBUG("wl_bss_roaming_done succeeded to " MACDBG "\n", -+ MAC2STRDBG((u8*)(&e->addr))); -+ -+ cfg80211_roamed(ndev, -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) -+ NULL, /* struct cfg80211_bss *bss */ -+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -+ NULL, -+#endif -+ curbssid, -+ conn_info->req_ie, conn_info->req_ie_len, -+ conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); -+ AP6210_DEBUG("Report roaming result\n"); -+ -+ wl_set_drv_status(wl, CONNECTED, ndev); -+ -+ return err; -+} -+ -+static s32 -+wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data, bool completed) -+{ -+ struct wl_connect_info *conn_info = wl_to_conn(wl); -+ struct wl_security *sec = wl_read_prof(wl, ndev, WL_PROF_SEC); -+ s32 err = 0; -+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); -+ if (!sec) { -+ AP6210_ERR("sec is NULL\n"); -+ return -ENODEV; -+ } -+ AP6210_DEBUG(" enter\n"); -+#ifdef ESCAN_RESULT_PATCH -+ if (wl_get_drv_status(wl, CONNECTED, ndev)) { -+ if (memcmp(curbssid, connect_req_bssid, ETHER_ADDR_LEN) == 0) { -+ AP6210_DEBUG(" Connected event of connected device e=%d s=%d, ignore it\n", -+ ntoh32(e->event_type), ntoh32(e->status)); -+ return err; -+ } -+ } -+ if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 && -+ memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) { -+ AP6210_DEBUG("copy bssid\n"); -+ memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN); -+ } -+ -+#else -+ if (wl->scan_request) { -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } -+#endif /* ESCAN_RESULT_PATCH */ -+ if (wl_get_drv_status(wl, CONNECTING, ndev)) { -+ wl_clr_drv_status(wl, CONNECTING, ndev); -+ if (completed) { -+ wl_get_assoc_ies(wl, ndev); -+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); -+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); -+ wl_update_bss_info(wl, ndev, 0); -+ wl_update_pmklist(ndev, wl->pmk_list, err); -+ wl_set_drv_status(wl, CONNECTED, ndev); -+ } -+ cfg80211_connect_result(ndev, -+ curbssid, -+ conn_info->req_ie, -+ conn_info->req_ie_len, -+ conn_info->resp_ie, -+ conn_info->resp_ie_len, -+ completed ? WLAN_STATUS_SUCCESS : -+ (sec->auth_assoc_res_status) ? -+ sec->auth_assoc_res_status : -+ WLAN_STATUS_UNSPECIFIED_FAILURE, -+ GFP_KERNEL); -+ if (completed) -+ AP6210_DEBUG("Report connect result - connection succeeded\n"); -+ else -+ AP6210_ERR("Report connect result - connection failed\n"); -+ } -+ return err; -+} -+ -+static s32 -+wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ u16 flags = ntoh16(e->flags); -+ enum nl80211_key_type key_type; -+ -+ mutex_lock(&wl->usr_sync); -+ if (flags & WLC_EVENT_MSG_GROUP) -+ key_type = NL80211_KEYTYPE_GROUP; -+ else -+ key_type = NL80211_KEYTYPE_PAIRWISE; -+ -+ cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, -+ NULL, GFP_KERNEL); -+ mutex_unlock(&wl->usr_sync); -+ -+ return 0; -+} -+ -+#ifdef PNO_SUPPORT -+static s32 -+wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ AP6210_ERR(">>> PNO Event\n"); -+ -+#ifndef WL_SCHED_SCAN -+ mutex_lock(&wl->usr_sync); -+ /* TODO: Use cfg80211_sched_scan_results(wiphy); */ -+ cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); -+ mutex_unlock(&wl->usr_sync); -+#else -+ /* If cfg80211 scheduled scan is supported, report the pno results via sched -+ * scan results -+ */ -+ wl_notify_sched_scan_results(wl, ndev, e, data); -+#endif /* WL_SCHED_SCAN */ -+ return 0; -+} -+#endif /* PNO_SUPPORT */ -+ -+static s32 -+wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ struct channel_info channel_inform; -+ struct wl_scan_results *bss_list; -+ u32 len = WL_SCAN_BUF_MAX; -+ s32 err = 0; -+ unsigned long flags; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (!wl_get_drv_status(wl, SCANNING, ndev)) { -+ AP6210_ERR("scan is not ready \n"); -+ return err; -+ } -+ if (wl->iscan_on && wl->iscan_kickstart) -+ return wl_wakeup_iscan(wl_to_iscan(wl)); -+ -+ mutex_lock(&wl->usr_sync); -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, -+ sizeof(channel_inform), false); -+ if (unlikely(err)) { -+ AP6210_ERR("scan busy (%d)\n", err); -+ goto scan_done_out; -+ } -+ channel_inform.scan_channel = dtoh32(channel_inform.scan_channel); -+ if (unlikely(channel_inform.scan_channel)) { -+ -+ AP6210_DEBUG("channel_inform.scan_channel (%d)\n", -+ channel_inform.scan_channel); -+ } -+ wl->bss_list = wl->scan_results; -+ bss_list = wl->bss_list; -+ memset(bss_list, 0, len); -+ bss_list->buflen = htod32(len); -+ err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false); -+ if (unlikely(err) && unlikely(!wl->scan_suppressed)) { -+ AP6210_ERR("%s Scan_results error (%d)\n", ndev->name, err); -+ err = -EINVAL; -+ goto scan_done_out; -+ } -+ bss_list->buflen = dtoh32(bss_list->buflen); -+ bss_list->version = dtoh32(bss_list->version); -+ bss_list->count = dtoh32(bss_list->count); -+ -+ err = wl_inform_bss(wl); -+ -+scan_done_out: -+ del_timer_sync(&wl->scan_timeout); -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ if (wl->scan_request) { -+ cfg80211_scan_done(wl->scan_request, false); -+ wl->scan_request = NULL; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ AP6210_DEBUG("cfg80211_scan_done\n"); -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+static s32 -+wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, -+ const struct ether_addr *sa, const struct ether_addr *bssid, -+ u8 **pheader, u32 *body_len, u8 *pbody) -+{ -+ struct dot11_management_header *hdr; -+ u32 totlen = 0; -+ s32 err = 0; -+ u8 *offset; -+ u32 prebody_len = *body_len; -+ switch (fc) { -+ case FC_ASSOC_REQ: -+ /* capability , listen interval */ -+ totlen = DOT11_ASSOC_REQ_FIXED_LEN; -+ *body_len += DOT11_ASSOC_REQ_FIXED_LEN; -+ break; -+ -+ case FC_REASSOC_REQ: -+ /* capability, listen inteval, ap address */ -+ totlen = DOT11_REASSOC_REQ_FIXED_LEN; -+ *body_len += DOT11_REASSOC_REQ_FIXED_LEN; -+ break; -+ } -+ totlen += DOT11_MGMT_HDR_LEN + prebody_len; -+ *pheader = kzalloc(totlen, GFP_KERNEL); -+ if (*pheader == NULL) { -+ AP6210_ERR("memory alloc failed \n"); -+ return -ENOMEM; -+ } -+ hdr = (struct dot11_management_header *) (*pheader); -+ hdr->fc = htol16(fc); -+ hdr->durid = 0; -+ hdr->seq = 0; -+ offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len); -+ bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN); -+ bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN); -+ bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN); -+ if ((pbody != NULL) && prebody_len) -+ bcopy((const char*)pbody, offset, prebody_len); -+ *body_len = totlen; -+ return err; -+} -+ -+ -+void -+wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev) -+{ -+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM) && -+ (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) || -+ wl_get_p2p_status(wl, ACTION_TX_NOACK))) { -+ AP6210_DEBUG("*** Wake UP ** abort actframe iovar\n"); -+ /* if channel is not zero, "actfame" uses off channel scan. -+ * So abort scan for off channel completion. -+ */ -+ if (wl->af_sent_channel) -+ /* wl_cfg80211_scan_abort(wl, ndev); */ -+ wl_notify_escan_complete(wl, -+ (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true); -+ } -+#ifdef WL_CFG80211_SYNC_GON -+ else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) { -+ AP6210_DEBUG("*** Wake UP ** abort listen for next af frame\n"); -+ /* So abort scan to cancel listen */ -+ wl_notify_escan_complete(wl, -+ (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true); -+ } -+#endif /* WL_CFG80211_SYNC_GON */ -+} -+ -+static s32 -+wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ struct ieee80211_supported_band *band; -+ struct wiphy *wiphy = wl_to_wiphy(wl); -+ struct ether_addr da; -+ struct ether_addr bssid; -+ bool isfree = false; -+ s32 err = 0; -+ s32 freq; -+ struct net_device *dev = NULL; -+ wifi_p2p_pub_act_frame_t *act_frm = NULL; -+ wifi_p2p_action_frame_t *p2p_act_frm = NULL; -+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL; -+ wl_event_rx_frame_data_t *rxframe = -+ (wl_event_rx_frame_data_t*)data; -+ u32 event = ntoh32(e->event_type); -+ u8 *mgmt_frame; -+ u8 bsscfgidx = e->bsscfgidx; -+ u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t); -+ u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK)); -+ -+ memset(&bssid, 0, ETHER_ADDR_LEN); -+ -+ if (wl->p2p_net == ndev) { -+ dev = wl_to_prmry_ndev(wl); -+ } else { -+ dev = ndev; -+ } -+ -+ if (channel <= CH_MAX_2G_CHANNEL) -+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; -+ else -+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; -+ if (!band) { -+ AP6210_ERR("No valid band"); -+ return -EINVAL; -+ } -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) -+ freq = ieee80211_channel_to_frequency(channel); -+ (void)band->band; -+#else -+ freq = ieee80211_channel_to_frequency(channel, band->band); -+#endif -+ if (event == WLC_E_ACTION_FRAME_RX) { -+ wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr", -+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync); -+ -+ err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); -+ if (err < 0) -+ AP6210_ERR("WLC_GET_BSSID error %d\n", err); -+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); -+ err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid, -+ &mgmt_frame, &mgmt_frame_len, -+ (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1)); -+ if (err < 0) { -+ AP6210_ERR("%s: Error in receiving action frame len %d channel %d freq %d\n", -+ __func__, mgmt_frame_len, channel, freq); -+ goto exit; -+ } -+ isfree = true; -+ if (wl_cfgp2p_is_pub_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], -+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { -+ act_frm = (wifi_p2p_pub_act_frame_t *) -+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]); -+ } else if (wl_cfgp2p_is_p2p_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], -+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { -+ p2p_act_frm = (wifi_p2p_action_frame_t *) -+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]); -+ (void) p2p_act_frm; -+ } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], -+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { -+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) -+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]); -+ if (sd_act_frm && wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) { -+ if (wl->next_af_subtype == sd_act_frm->action) { -+ AP6210_DEBUG("We got a right next frame of SD!(%d)\n", -+ sd_act_frm->action); -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, -+ (ndev == wl->p2p_net) ? -+ wl_to_prmry_ndev(wl) : ndev); -+ -+ /* Stop waiting for next AF. */ -+ wl_stop_wait_next_action_frame(wl, ndev); -+ } -+ } -+ (void) sd_act_frm; -+ } else { -+ /* -+ * if we got normal action frame and ndev is p2p0, -+ * we have to change ndev from p2p0 to wlan0 -+ */ -+ if (wl->p2p_net == ndev) -+ ndev = wl_to_prmry_ndev(wl); -+ } -+ -+ if (act_frm) { -+ -+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) { -+ if (wl->next_af_subtype == act_frm->subtype) { -+ AP6210_DEBUG("We got a right next frame!(%d)\n", -+ act_frm->subtype); -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, -+ (ndev == wl->p2p_net) ? -+ wl_to_prmry_ndev(wl) : ndev); -+ -+ /* Stop waiting for next AF. */ -+ wl_stop_wait_next_action_frame(wl, ndev); -+ } -+ } -+ } -+ -+ wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN], -+ mgmt_frame_len - DOT11_MGMT_HDR_LEN); -+ /* -+ * After complete GO Negotiation, roll back to mpc mode -+ */ -+ if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) || -+ (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) { -+ wldev_iovar_setint(dev, "mpc", 1); -+ } -+ if (act_frm && (act_frm->subtype == P2P_PAF_GON_CONF)) { -+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n"); -+ wl_clr_p2p_status(wl, GO_NEG_PHASE); -+ } -+ } else { -+ mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1); -+ -+ /* wpa supplicant use probe request event for restarting another GON Req. -+ * but it makes GON Req repetition. -+ * so if src addr of prb req is same as my target device, -+ * do not send probe request event during sending action frame. -+ */ -+ if (event == WLC_E_P2P_PROBREQ_MSG) { -+ AP6210_DEBUG(" Event %s\n", (event == WLC_E_P2P_PROBREQ_MSG) ? -+ "WLC_E_P2P_PROBREQ_MSG":"WLC_E_PROBREQ_MSG"); -+ -+ -+ /* Filter any P2P probe reqs arriving during the -+ * GO-NEG Phase -+ */ -+ if (wl->p2p && -+ wl_get_p2p_status(wl, GO_NEG_PHASE)) { -+ AP6210_DEBUG("Filtering P2P probe_req while " -+ "being in GO-Neg state\n"); -+ return 0; -+ } -+ } -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); -+#else -+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ -+ -+ AP6210_DEBUG("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__, -+ mgmt_frame_len, ntoh32(e->datalen), channel, freq); -+exit: -+ if (isfree) -+ kfree(mgmt_frame); -+ return 0; -+} -+ -+#ifdef WL_SCHED_SCAN -+/* If target scan is not reliable, set the below define to "1" to do a -+ * full escan -+ */ -+#define FULL_ESCAN_ON_PFN_NET_FOUND 0 -+static s32 -+wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ wl_pfn_net_info_t *netinfo, *pnetinfo; -+ struct cfg80211_scan_request request; -+ struct wiphy *wiphy = wl_to_wiphy(wl); -+ int err = 0; -+ struct cfg80211_ssid ssid[MAX_PFN_LIST_COUNT]; -+ struct ieee80211_channel *channel = NULL; -+ int channel_req = 0; -+ int band = 0; -+ struct wl_pfn_scanresults *pfn_result = (struct wl_pfn_scanresults *)data; -+ -+ AP6210_DEBUG("Enter\n"); -+ -+ if (e->event_type == WLC_E_PFN_NET_LOST) { -+ AP6210_DEBUG("PFN NET LOST event. Do Nothing \n"); -+ return 0; -+ } -+ AP6210_DEBUG(">>> PFN NET FOUND event. count:%d \n", pfn_result->count); -+ if (pfn_result->count > 0) { -+ int i; -+ -+ memset(&request, 0x00, sizeof(struct cfg80211_scan_request)); -+ memset(&ssid, 0x00, sizeof(ssid)); -+ request.wiphy = wiphy; -+ -+ pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) -+ - sizeof(wl_pfn_net_info_t)); -+ channel = (struct ieee80211_channel *)kzalloc( -+ (sizeof(struct ieee80211_channel) * MAX_PFN_LIST_COUNT), -+ GFP_KERNEL); -+ if (!channel) { -+ AP6210_ERR("No memory"); -+ err = -ENOMEM; -+ goto out_err; -+ } -+ -+ for (i = 0; i < pfn_result->count; i++) { -+ netinfo = &pnetinfo[i]; -+ if (!netinfo) { -+ AP6210_ERR("Invalid netinfo ptr. index:%d", i); -+ err = -EINVAL; -+ goto out_err; -+ } -+ AP6210_DEBUG(">>> SSID:%s Channel:%d \n", -+ netinfo->pfnsubnet.SSID, netinfo->pfnsubnet.channel); -+ /* PFN result doesn't have all the info which are required by the supplicant -+ * (For e.g IEs) Do a target Escan so that sched scan results are reported -+ * via wl_inform_single_bss in the required format. Escan does require the -+ * scan request in the form of cfg80211_scan_request. For timebeing, create -+ * cfg80211_scan_request one out of the received PNO event. -+ */ -+ memcpy(ssid[i].ssid, netinfo->pfnsubnet.SSID, -+ netinfo->pfnsubnet.SSID_len); -+ ssid[i].ssid_len = netinfo->pfnsubnet.SSID_len; -+ request.n_ssids++; -+ -+ channel_req = netinfo->pfnsubnet.channel; -+ band = (channel_req <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ -+ : NL80211_BAND_5GHZ; -+ channel[i].center_freq = ieee80211_channel_to_frequency(channel_req, band); -+ channel[i].band = band; -+ channel[i].flags |= IEEE80211_CHAN_NO_HT40; -+ request.channels[i] = &channel[i]; -+ request.n_channels++; -+ } -+ -+ /* assign parsed ssid array */ -+ if (request.n_ssids) -+ request.ssids = &ssid[0]; -+ -+ if (wl_get_drv_status_all(wl, SCANNING)) { -+ /* Abort any on-going scan */ -+ wl_notify_escan_complete(wl, ndev, true, true); -+ } -+ -+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) { -+ AP6210_DEBUG(">>> P2P discovery was ON. Disabling it\n"); -+ err = wl_cfgp2p_discover_enable_search(wl, false); -+ if (unlikely(err)) { -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ goto out_err; -+ } -+ } -+ -+ wl_set_drv_status(wl, SCANNING, ndev); -+#if FULL_ESCAN_ON_PFN_NET_FOUND -+ AP6210_DEBUG(">>> Doing Full ESCAN on PNO event\n"); -+ err = wl_do_escan(wl, wiphy, ndev, NULL); -+#else -+ AP6210_DEBUG(">>> Doing targeted ESCAN on PNO event\n"); -+ err = wl_do_escan(wl, wiphy, ndev, &request); -+#endif -+ if (err) { -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ goto out_err; -+ } -+ wl->sched_scan_running = TRUE; -+ } -+ else { -+ AP6210_ERR("FALSE PNO Event. (pfn_count == 0) \n"); -+ } -+out_err: -+ if (channel) -+ kfree(channel); -+ return err; -+} -+#endif /* WL_SCHED_SCAN */ -+ -+static void wl_init_conf(struct wl_conf *conf) -+{ -+ AP6210_DEBUG("Enter \n"); -+ conf->frag_threshold = (u32)-1; -+ conf->rts_threshold = (u32)-1; -+ conf->retry_short = (u32)-1; -+ conf->retry_long = (u32)-1; -+ conf->tx_power = -1; -+} -+ -+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev) -+{ -+ unsigned long flags; -+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); -+ -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ memset(profile, 0, sizeof(struct wl_profile)); -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+} -+ -+static void wl_init_event_handler(struct wl_priv *wl) -+{ -+ memset(wl->evt_handler, 0, sizeof(wl->evt_handler)); -+ -+ wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status; -+ wl->evt_handler[WLC_E_AUTH] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_ASSOC] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status; -+ wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status; -+ wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status; -+ wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame; -+ wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame; -+ wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame; -+ wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete; -+ wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete; -+ wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete; -+#ifdef PNO_SUPPORT -+ wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status; -+#endif /* PNO_SUPPORT */ -+} -+ -+static s32 wl_init_priv_mem(struct wl_priv *wl) -+{ -+ AP6210_DEBUG("Enter \n"); -+ wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); -+ if (unlikely(!wl->scan_results)) { -+ AP6210_ERR("Scan results alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL); -+ if (unlikely(!wl->conf)) { -+ AP6210_ERR("wl_conf alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->scan_req_int = -+ (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); -+ if (unlikely(!wl->scan_req_int)) { -+ AP6210_ERR("Scan req alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); -+ if (unlikely(!wl->ioctl_buf)) { -+ AP6210_ERR("Ioctl buf alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); -+ if (unlikely(!wl->escan_ioctl_buf)) { -+ AP6210_ERR("Ioctl buf alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); -+ if (unlikely(!wl->extra_buf)) { -+ AP6210_ERR("Extra buf alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL); -+ if (unlikely(!wl->iscan)) { -+ AP6210_ERR("Iscan buf alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); -+ if (unlikely(!wl->pmk_list)) { -+ AP6210_ERR("pmk list alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->sta_info = (void *)kzalloc(sizeof(*wl->sta_info), GFP_KERNEL); -+ if (unlikely(!wl->sta_info)) { -+ AP6210_ERR("sta info alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ -+#if defined(STATIC_WL_PRIV_STRUCT) -+ wl->conn_info = (void *)kzalloc(sizeof(*wl->conn_info), GFP_KERNEL); -+ if (unlikely(!wl->conn_info)) { -+ AP6210_ERR("wl->conn_info alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->ie = (void *)kzalloc(sizeof(*wl->ie), GFP_KERNEL); -+ if (unlikely(!wl->ie)) { -+ AP6210_ERR("wl->ie alloc failed\n"); -+ goto init_priv_mem_out; -+ } -+ wl->escan_info.escan_buf = dhd_os_prealloc(NULL, DHD_PREALLOC_WIPHY_ESCAN0, 0); -+ bzero(wl->escan_info.escan_buf, ESCAN_BUF_SIZE); -+#endif /* STATIC_WL_PRIV_STRUCT */ -+ wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL); -+ if (unlikely(!wl->afx_hdl)) { -+ AP6210_ERR("afx hdl alloc failed\n"); -+ goto init_priv_mem_out; -+ } else { -+ init_completion(&wl->act_frm_scan); -+ init_completion(&wl->wait_next_af); -+ -+ INIT_WORK(&wl->afx_hdl->work, wl_cfg80211_afx_handler); -+ } -+ return 0; -+ -+init_priv_mem_out: -+ wl_deinit_priv_mem(wl); -+ -+ return -ENOMEM; -+} -+ -+static void wl_deinit_priv_mem(struct wl_priv *wl) -+{ -+ kfree(wl->scan_results); -+ wl->scan_results = NULL; -+ kfree(wl->conf); -+ wl->conf = NULL; -+ kfree(wl->scan_req_int); -+ wl->scan_req_int = NULL; -+ kfree(wl->ioctl_buf); -+ wl->ioctl_buf = NULL; -+ kfree(wl->escan_ioctl_buf); -+ wl->escan_ioctl_buf = NULL; -+ kfree(wl->extra_buf); -+ wl->extra_buf = NULL; -+ kfree(wl->iscan); -+ wl->iscan = NULL; -+ kfree(wl->pmk_list); -+ wl->pmk_list = NULL; -+ kfree(wl->sta_info); -+ wl->sta_info = NULL; -+#if defined(STATIC_WL_PRIV_STRUCT) -+ kfree(wl->conn_info); -+ wl->conn_info = NULL; -+ kfree(wl->ie); -+ wl->ie = NULL; -+ wl->escan_info.escan_buf = NULL; -+#endif /* STATIC_WL_PRIV_STRUCT */ -+ if (wl->afx_hdl) { -+ cancel_work_sync(&wl->afx_hdl->work); -+ kfree(wl->afx_hdl); -+ wl->afx_hdl = NULL; -+ } -+ -+ if (wl->ap_info) { -+ kfree(wl->ap_info->wpa_ie); -+ kfree(wl->ap_info->rsn_ie); -+ kfree(wl->ap_info->wps_ie); -+ kfree(wl->ap_info); -+ wl->ap_info = NULL; -+ } -+} -+ -+static s32 wl_create_event_handler(struct wl_priv *wl) -+{ -+ int ret = 0; -+ AP6210_DEBUG("Enter \n"); -+ -+ /* Do not use DHD in cfg driver */ -+ wl->event_tsk.thr_pid = -1; -+ -+#ifdef USE_KTHREAD_API -+ PROC_START2(wl_event_handler, wl, &wl->event_tsk, 0, "wl_event_handler"); -+#else -+ PROC_START(wl_event_handler, wl, &wl->event_tsk, 0); -+#endif -+ if (wl->event_tsk.thr_pid < 0) -+ ret = -ENOMEM; -+ return ret; -+} -+ -+static void wl_destroy_event_handler(struct wl_priv *wl) -+{ -+ if (wl->event_tsk.thr_pid >= 0) -+ PROC_STOP(&wl->event_tsk); -+} -+ -+static void wl_term_iscan(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); -+ AP6210_DEBUG("In\n"); -+ if (wl->iscan_on && iscan->tsk) { -+ iscan->state = WL_ISCAN_STATE_IDLE; -+ AP6210_DEBUG("SIGTERM\n"); -+ send_sig(SIGTERM, iscan->tsk, 1); -+ AP6210_DEBUG("kthread_stop\n"); -+ kthread_stop(iscan->tsk); -+ iscan->tsk = NULL; -+ } -+} -+ -+static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) -+{ -+ struct wl_priv *wl = iscan_to_wl(iscan); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ unsigned long flags; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (!wl_get_drv_status(wl, SCANNING, ndev)) { -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ AP6210_ERR("Scan complete while device not scanning\n"); -+ return; -+ } -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ wl_clr_drv_status(wl, SCANNING, ndev); -+ if (likely(wl->scan_request)) { -+ cfg80211_scan_done(wl->scan_request, aborted); -+ wl->scan_request = NULL; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ wl->iscan_kickstart = false; -+} -+ -+static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) -+{ -+ if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { -+ AP6210_DEBUG("wake up iscan\n"); -+ up(&iscan->sync); -+ return 0; -+ } -+ -+ return -EIO; -+} -+ -+static s32 -+wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, -+ struct wl_scan_results **bss_list) -+{ -+ struct wl_iscan_results list; -+ struct wl_scan_results *results; -+ struct wl_iscan_results *list_buf; -+ s32 err = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); -+ list_buf = (struct wl_iscan_results *)iscan->scan_buf; -+ results = &list_buf->results; -+ results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; -+ results->version = 0; -+ results->count = 0; -+ -+ memset(&list, 0, sizeof(list)); -+ list.results.buflen = htod32(WL_ISCAN_BUF_MAX); -+ err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list, -+ WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, -+ WL_ISCAN_BUF_MAX, NULL); -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ return err; -+ } -+ results->buflen = dtoh32(results->buflen); -+ results->version = dtoh32(results->version); -+ results->count = dtoh32(results->count); -+ AP6210_DEBUG("results->count = %d\n", results->count); -+ AP6210_DEBUG("results->buflen = %d\n", results->buflen); -+ *status = dtoh32(list_buf->status); -+ *bss_list = results; -+ -+ return err; -+} -+ -+static s32 wl_iscan_done(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl->iscan; -+ s32 err = 0; -+ -+ iscan->state = WL_ISCAN_STATE_IDLE; -+ mutex_lock(&wl->usr_sync); -+ wl_inform_bss(wl); -+ wl_notify_iscan_complete(iscan, false); -+ mutex_unlock(&wl->usr_sync); -+ -+ return err; -+} -+ -+static s32 wl_iscan_pending(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl->iscan; -+ s32 err = 0; -+ -+ /* Reschedule the timer */ -+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); -+ iscan->timer_on = 1; -+ -+ return err; -+} -+ -+static s32 wl_iscan_inprogress(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl->iscan; -+ s32 err = 0; -+ -+ mutex_lock(&wl->usr_sync); -+ wl_inform_bss(wl); -+ wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -+ mutex_unlock(&wl->usr_sync); -+ /* Reschedule the timer */ -+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); -+ iscan->timer_on = 1; -+ -+ return err; -+} -+ -+static s32 wl_iscan_aborted(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl->iscan; -+ s32 err = 0; -+ -+ iscan->state = WL_ISCAN_STATE_IDLE; -+ mutex_lock(&wl->usr_sync); -+ wl_notify_iscan_complete(iscan, true); -+ mutex_unlock(&wl->usr_sync); -+ -+ return err; -+} -+ -+static s32 wl_iscan_thread(void *data) -+{ -+ struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; -+ struct wl_priv *wl = iscan_to_wl(iscan); -+ u32 status; -+ int err = 0; -+ -+ allow_signal(SIGTERM); -+ status = WL_SCAN_RESULTS_PARTIAL; -+ while (likely(!down_interruptible(&iscan->sync))) { -+ if (kthread_should_stop()) -+ break; -+ if (iscan->timer_on) { -+ del_timer_sync(&iscan->timer); -+ iscan->timer_on = 0; -+ } -+ mutex_lock(&wl->usr_sync); -+ err = wl_get_iscan_results(iscan, &status, &wl->bss_list); -+ if (unlikely(err)) { -+ status = WL_SCAN_RESULTS_ABORTED; -+ AP6210_ERR("Abort iscan\n"); -+ } -+ mutex_unlock(&wl->usr_sync); -+ iscan->iscan_handler[status] (wl); -+ } -+ if (iscan->timer_on) { -+ del_timer_sync(&iscan->timer); -+ iscan->timer_on = 0; -+ } -+ AP6210_DEBUG("%s was terminated\n", __func__); -+ -+ return 0; -+} -+ -+static void wl_scan_timeout(unsigned long data) -+{ -+ wl_event_msg_t msg; -+ struct wl_priv *wl = (struct wl_priv *)data; -+ -+ if (!(wl->scan_request)) { -+ AP6210_ERR("timer expired but no scan request\n"); -+ return; -+ } -+ bzero(&msg, sizeof(wl_event_msg_t)); -+ AP6210_ERR("timer expired\n"); -+ if (wl->escan_on) { -+ msg.event_type = hton32(WLC_E_ESCAN_RESULT); -+ msg.status = hton32(WLC_E_STATUS_TIMEOUT); -+ msg.reason = 0xFFFFFFFF; -+ wl_cfg80211_event(wl_to_prmry_ndev(wl), &msg, NULL); -+ } else { -+ AP6210_ERR("SCAN Timeout(ISCAN)\n"); -+ wl_notify_iscan_complete(wl_to_iscan(wl), true); -+ } -+} -+static void wl_iscan_timer(unsigned long data) -+{ -+ struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; -+ -+ if (iscan) { -+ iscan->timer_on = 0; -+ AP6210_DEBUG("timer expired\n"); -+ wl_wakeup_iscan(iscan); -+ } -+} -+ -+static s32 wl_invoke_iscan(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); -+ int err = 0; -+ -+ if (wl->iscan_on && !iscan->tsk) { -+ iscan->state = WL_ISCAN_STATE_IDLE; -+ sema_init(&iscan->sync, 0); -+ iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); -+ if (IS_ERR(iscan->tsk)) { -+ AP6210_ERR("Could not create iscan thread\n"); -+ iscan->tsk = NULL; -+ return -ENOMEM; -+ } -+ } -+ -+ return err; -+} -+ -+static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan) -+{ -+ memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler)); -+ iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done; -+ iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress; -+ iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending; -+ iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted; -+ iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted; -+} -+ -+static s32 -+wl_cfg80211_netdev_notifier_call(struct notifier_block * nb, -+ unsigned long state, -+ void *ndev) -+{ -+ struct net_device *dev = ndev; -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ int refcnt = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (!wdev || !wl || dev == wl_to_prmry_ndev(wl)) -+ return NOTIFY_DONE; -+ switch (state) { -+ case NETDEV_DOWN: -+ while (work_pending(&wdev->cleanup_work) && refcnt < 100) { -+ if (refcnt%5 == 0) -+ AP6210_ERR("%s : [NETDEV_DOWN] work_pending (%d th)\n", -+ __FUNCTION__, refcnt); -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(100); -+ set_current_state(TASK_RUNNING); -+ refcnt++; -+ } -+ break; -+ -+ case NETDEV_UNREGISTER: -+ /* after calling list_del_rcu(&wdev->list) */ -+ wl_dealloc_netinfo(wl, ndev); -+ break; -+ case NETDEV_GOING_DOWN: -+ /* At NETDEV_DOWN state, wdev_cleanup_work work will be called. -+ * In front of door, the function checks -+ * whether current scan is working or not. -+ * If the scanning is still working, wdev_cleanup_work call WARN_ON and -+ * make the scan done forcibly. -+ */ -+ if (wl_get_drv_status(wl, SCANNING, dev)) { -+ if (wl->escan_on) { -+ wl_notify_escan_complete(wl, dev, true, true); -+ } -+ } -+ break; -+ } -+ return NOTIFY_DONE; -+} -+static struct notifier_block wl_cfg80211_netdev_notifier = { -+ .notifier_call = wl_cfg80211_netdev_notifier_call, -+}; -+ -+static s32 wl_notify_escan_complete(struct wl_priv *wl, -+ struct net_device *ndev, -+ bool aborted, bool fw_abort) -+{ -+ wl_scan_params_t *params = NULL; -+ s32 params_size = 0; -+ s32 err = BCME_OK; -+ unsigned long flags; -+ struct net_device *dev; -+ -+ AP6210_DEBUG("Enter \n"); -+ -+ if (wl->escan_info.ndev != ndev) -+ { -+ AP6210_ERR("ndev is different %p %p\n", wl->escan_info.ndev, ndev); -+ return err; -+ } -+ -+ if (wl->scan_request) { -+ if (wl->scan_request->dev == wl->p2p_net) -+ dev = wl_to_prmry_ndev(wl); -+ else -+ dev = wl->scan_request->dev; -+ } -+ else { -+ AP6210_DEBUG("wl->scan_request is NULL may be internal scan." -+ "doing scan_abort for ndev %p primary %p p2p_net %p", -+ ndev, wl_to_prmry_ndev(wl), wl->p2p_net); -+ dev = ndev; -+ } -+ if (fw_abort && !in_atomic()) { -+ /* Our scan params only need space for 1 channel and 0 ssids */ -+ params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size); -+ if (params == NULL) { -+ AP6210_ERR("scan params allocation failed \n"); -+ err = -ENOMEM; -+ } else { -+ /* Do a scan abort to stop the driver's scan engine */ -+ err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true); -+ if (err < 0) { -+ AP6210_ERR("scan abort failed \n"); -+ } -+ } -+ } -+ if (timer_pending(&wl->scan_timeout)) -+ del_timer_sync(&wl->scan_timeout); -+#if defined(ESCAN_RESULT_PATCH) -+ if (likely(wl->scan_request)) { -+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; -+ wl_inform_bss(wl); -+ } -+#endif /* ESCAN_RESULT_PATCH */ -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+#ifdef WL_SCHED_SCAN -+ if (wl->sched_scan_req && !wl->scan_request) { -+ AP6210_DEBUG(">>> REPORTING SCHED SCAN RESULTS \n"); -+ if (aborted) -+ cfg80211_sched_scan_stopped(wl->sched_scan_req->wiphy); -+ else -+ cfg80211_sched_scan_results(wl->sched_scan_req->wiphy); -+ wl->sched_scan_running = FALSE; -+ wl->sched_scan_req = NULL; -+ } -+#endif /* WL_SCHED_SCAN */ -+ if (likely(wl->scan_request)) { -+ cfg80211_scan_done(wl->scan_request, aborted); -+ wl->scan_request = NULL; -+ } -+ if (p2p_is_on(wl)) -+ wl_clr_p2p_status(wl, SCANNING); -+ wl_clr_drv_status(wl, SCANNING, dev); -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ if (params) -+ kfree(params); -+ -+ return err; -+} -+ -+static s32 wl_escan_handler(struct wl_priv *wl, -+ struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ s32 err = BCME_OK; -+ s32 status = ntoh32(e->status); -+ wl_bss_info_t *bi; -+ wl_escan_result_t *escan_result; -+ wl_bss_info_t *bss = NULL; -+ wl_scan_results_t *list; -+ wifi_p2p_ie_t * p2p_ie; -+ u32 bi_length; -+ u32 i; -+ u8 *p2p_dev_addr = NULL; -+ -+ AP6210_DEBUG(" enter event type : %d, status : %d \n", -+ ntoh32(e->event_type), ntoh32(e->status)); -+ -+ mutex_lock(&wl->usr_sync); -+ /* P2P SCAN is coming from primary interface */ -+ if (wl_get_p2p_status(wl, SCANNING)) { -+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) -+ ndev = wl->afx_hdl->dev; -+ else -+ ndev = wl->escan_info.ndev; -+ -+ } -+ if (!ndev || !wl->escan_on || -+ (!wl_get_drv_status(wl, SCANNING, ndev) && -+ !wl->sched_scan_running)) { -+ AP6210_ERR("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n", -+ ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev)); -+ goto exit; -+ } -+ if (status == WLC_E_STATUS_PARTIAL) { -+ AP6210_DEBUG("WLC_E_STATUS_PARTIAL \n"); -+ escan_result = (wl_escan_result_t *) data; -+ if (!escan_result) { -+ AP6210_ERR("Invalid escan result (NULL pointer)\n"); -+ goto exit; -+ } -+ if (dtoh16(escan_result->bss_count) != 1) { -+ AP6210_ERR("Invalid bss_count %d: ignoring\n", escan_result->bss_count); -+ goto exit; -+ } -+ bi = escan_result->bss_info; -+ if (!bi) { -+ AP6210_ERR("Invalid escan bss info (NULL pointer)\n"); -+ goto exit; -+ } -+ bi_length = dtoh32(bi->length); -+ if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) { -+ AP6210_ERR("Invalid bss_info length %d: ignoring\n", bi_length); -+ goto exit; -+ } -+ -+ if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) { -+ if (dtoh16(bi->capability) & DOT11_CAP_IBSS) { -+ AP6210_DEBUG("Ignoring IBSS result\n"); -+ goto exit; -+ } -+ } -+ -+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { -+ p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length); -+ if (p2p_dev_addr && !memcmp(p2p_dev_addr, -+ wl->afx_hdl->tx_dst_addr.octet, ETHER_ADDR_LEN)) { -+ s32 channel = CHSPEC_CHANNEL( -+ wl_chspec_driver_to_host(bi->chanspec)); -+ AP6210_DEBUG("ACTION FRAME SCAN : Peer " MACDBG " found, channel : %d\n", -+ MAC2STRDBG(wl->afx_hdl->tx_dst_addr.octet), channel); -+ wl_clr_p2p_status(wl, SCANNING); -+ wl->afx_hdl->peer_chan = channel; -+ complete(&wl->act_frm_scan); -+ goto exit; -+ } -+ -+ } else { -+ int cur_len = WL_SCAN_RESULTS_FIXED_SIZE; -+ list = (wl_scan_results_t *)wl->escan_info.escan_buf; -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+ if (wl->p2p_net && wl->scan_request && -+ wl->scan_request->dev == wl->p2p_net) -+#else -+ if (p2p_is_on(wl) && p2p_scan(wl)) -+#endif -+ { -+#ifdef WL_HOST_BAND_MGMT -+ s32 channel = 0; -+ s32 channel_band = 0; -+#endif /* WL_HOST_BAND_MGMT */ -+ /* p2p scan && allow only probe response */ -+ if (bi->flags & WL_BSS_FLAGS_FROM_BEACON) -+ goto exit; -+ if ((p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, -+ bi->ie_length)) == NULL) { -+ AP6210_ERR("Couldn't find P2PIE in probe" -+ " response/beacon\n"); -+ goto exit; -+ } -+#ifdef WL_HOST_BAND_MGMT -+ channel = CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec)); -+ channel_band = (channel > CH_MAX_2G_CHANNEL) ? -+ WLC_BAND_5G : WLC_BAND_2G; -+ -+ -+ if ((wl->curr_band == WLC_BAND_5G) && -+ (channel_band == WLC_BAND_2G)) { -+ /* Avoid sending the GO results in band conflict */ -+ if (wl_cfgp2p_retreive_p2pattrib(p2p_ie, -+ P2P_SEID_GROUP_ID) != NULL) -+ goto exit; -+ } -+#endif /* WL_HOST_BAND_MGMT */ -+ } -+ for (i = 0; i < list->count; i++) { -+ bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length)) -+ : list->bss_info; -+ -+ if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) && -+ (CHSPEC_BAND(wl_chspec_driver_to_host(bi->chanspec)) -+ == CHSPEC_BAND(wl_chspec_driver_to_host(bss->chanspec))) && -+ bi->SSID_len == bss->SSID_len && -+ !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) { -+ -+ /* do not allow beacon data to update -+ *the data recd from a probe response -+ */ -+ if (!(bss->flags & WL_BSS_FLAGS_FROM_BEACON) && -+ (bi->flags & WL_BSS_FLAGS_FROM_BEACON)) -+ goto exit; -+ -+ AP6210_DEBUG("%s("MACDBG"), i=%d prev: RSSI %d" -+ " flags 0x%x, new: RSSI %d flags 0x%x\n", -+ bss->SSID, MAC2STRDBG(bi->BSSID.octet), i, -+ bss->RSSI, bss->flags, bi->RSSI, bi->flags); -+ -+ if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == -+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL)) { -+ /* preserve max RSSI if the measurements are -+ * both on-channel or both off-channel -+ */ -+ AP6210_DEBUG("%s("MACDBG"), same onchan" -+ ", RSSI: prev %d new %d\n", -+ bss->SSID, MAC2STRDBG(bi->BSSID.octet), -+ bss->RSSI, bi->RSSI); -+ bi->RSSI = MAX(bss->RSSI, bi->RSSI); -+ } else if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) && -+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == 0) { -+ /* preserve the on-channel rssi measurement -+ * if the new measurement is off channel -+ */ -+ AP6210_DEBUG("%s("MACDBG"), prev onchan" -+ ", RSSI: prev %d new %d\n", -+ bss->SSID, MAC2STRDBG(bi->BSSID.octet), -+ bss->RSSI, bi->RSSI); -+ bi->RSSI = bss->RSSI; -+ bi->flags |= WL_BSS_FLAGS_RSSI_ONCHANNEL; -+ } -+ if (dtoh32(bss->length) != bi_length) { -+ u32 prev_len = dtoh32(bss->length); -+ -+ AP6210_DEBUG("bss info replacement" -+ " is occured(bcast:%d->probresp%d)\n", -+ bss->ie_length, bi->ie_length); -+ AP6210_DEBUG("%s("MACDBG"), replacement!(%d -> %d)\n", -+ bss->SSID, MAC2STRDBG(bi->BSSID.octet), -+ prev_len, bi_length); -+ -+ if (list->buflen - prev_len + bi_length -+ > ESCAN_BUF_SIZE) { -+ AP6210_ERR("Buffer is too small: keep the" -+ " previous result of this AP\n"); -+ /* Only update RSSI */ -+ bss->RSSI = bi->RSSI; -+ bss->flags |= (bi->flags -+ & WL_BSS_FLAGS_RSSI_ONCHANNEL); -+ goto exit; -+ } -+ -+ if (i < list->count - 1) { -+ /* memory copy required by this case only */ -+ memmove((u8 *)bss + bi_length, -+ (u8 *)bss + prev_len, -+ list->buflen - cur_len - prev_len); -+ } -+ list->buflen -= prev_len; -+ list->buflen += bi_length; -+ } -+ list->version = dtoh32(bi->version); -+ memcpy((u8 *)bss, (u8 *)bi, bi_length); -+ goto exit; -+ } -+ cur_len += dtoh32(bss->length); -+ } -+ if (bi_length > ESCAN_BUF_SIZE - list->buflen) { -+ AP6210_ERR("Buffer is too small: ignoring\n"); -+ goto exit; -+ } -+ if (strlen(bi->SSID) == 0) { // terence: fix for hidden SSID -+ AP6210_DEBUG("Skip hidden SSID %pM\n", &bi->BSSID); -+ goto exit; -+ } -+ memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length); -+ list->version = dtoh32(bi->version); -+ list->buflen += bi_length; -+ list->count++; -+ } -+ -+ } -+ else if (status == WLC_E_STATUS_SUCCESS) { -+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; -+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { -+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n"); -+ wl_clr_p2p_status(wl, SCANNING); -+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); -+ if (wl->afx_hdl->peer_chan == WL_INVALID) -+ complete(&wl->act_frm_scan); -+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { -+ AP6210_DEBUG("ESCAN COMPLETED\n"); -+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; -+ wl_inform_bss(wl); -+ wl_notify_escan_complete(wl, ndev, false, false); -+ } -+ } -+ else if (status == WLC_E_STATUS_ABORT) { -+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; -+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { -+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n"); -+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); -+ wl_clr_p2p_status(wl, SCANNING); -+ if (wl->afx_hdl->peer_chan == WL_INVALID) -+ complete(&wl->act_frm_scan); -+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { -+ AP6210_DEBUG("ESCAN ABORTED\n"); -+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; -+ wl_inform_bss(wl); -+ wl_notify_escan_complete(wl, ndev, true, false); -+ } -+ } -+ else if (status == WLC_E_STATUS_NEWSCAN) -+ { -+ escan_result = (wl_escan_result_t *) data; -+ AP6210_ERR("WLC_E_STATUS_NEWSCAN : scan_request[%p]\n", wl->scan_request); -+ AP6210_ERR("sync_id[%d], bss_count[%d]\n", escan_result->sync_id, -+ escan_result->bss_count); -+ } else if (status == WLC_E_STATUS_TIMEOUT) { -+ AP6210_ERR("WLC_E_STATUS_TIMEOUT : scan_request[%p]\n", wl->scan_request); -+ AP6210_ERR("escan_on[%d], reason[0x%x]\n", wl->escan_on, e->reason); -+ if (e->reason == 0xFFFFFFFF) { -+ wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true); -+ } -+ } else { -+ AP6210_ERR("unexpected Escan Event %d : abort\n", status); -+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; -+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { -+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n"); -+ wl_clr_p2p_status(wl, SCANNING); -+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); -+ if (wl->afx_hdl->peer_chan == WL_INVALID) -+ complete(&wl->act_frm_scan); -+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { -+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; -+ wl_inform_bss(wl); -+ wl_notify_escan_complete(wl, ndev, true, false); -+ } -+ } -+exit: -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+static void wl_cfg80211_concurrent_roam(struct wl_priv *wl, int enable) -+{ -+ u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED); -+ struct net_info *iter, *next; -+ int err; -+ -+ if (!wl->roamoff_on_concurrent) -+ return; -+ if (enable && connected_cnt > 1) { -+ for_each_ndev(wl, iter, next) { -+ /* Save the current roam setting */ -+ if ((err = wldev_iovar_getint(iter->ndev, "roam_off", -+ (s32 *)&iter->roam_off)) != BCME_OK) { -+ AP6210_ERR("%s:Failed to get current roam setting err %d\n", -+ iter->ndev->name, err); -+ continue; -+ } -+ if ((err = wldev_iovar_setint(iter->ndev, "roam_off", 1)) != BCME_OK) { -+ AP6210_ERR(" %s:failed to set roam_off : %d\n", -+ iter->ndev->name, err); -+ } -+ } -+ } -+ else if (!enable) { -+ for_each_ndev(wl, iter, next) { -+ if (iter->roam_off != WL_INVALID) { -+ if ((err = wldev_iovar_setint(iter->ndev, "roam_off", -+ iter->roam_off)) == BCME_OK) -+ iter->roam_off = WL_INVALID; -+ else { -+ AP6210_ERR(" %s:failed to set roam_off : %d\n", -+ iter->ndev->name, err); -+ } -+ } -+ } -+ } -+ return; -+} -+ -+static void wl_cfg80211_determine_vsdb_mode(struct wl_priv *wl) -+{ -+ struct net_info *iter, *next; -+ u32 chan = 0; -+ u32 chanspec = 0; -+ u32 prev_chan = 0; -+ u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED); -+ wl->vsdb_mode = false; -+ -+ if (connected_cnt <= 1) { -+ return; -+ } -+ for_each_ndev(wl, iter, next) { -+ chanspec = 0; -+ chan = 0; -+ if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) { -+ if (wldev_iovar_getint(iter->ndev, "chanspec", -+ (s32 *)&chanspec) == BCME_OK) { -+ chan = CHSPEC_CHANNEL(chanspec); -+ if (CHSPEC_IS40(chanspec)) { -+ if (CHSPEC_SB_UPPER(chanspec)) -+ chan += CH_10MHZ_APART; -+ else -+ chan -= CH_10MHZ_APART; -+ } -+ wl_update_prof(wl, iter->ndev, NULL, -+ &chan, WL_PROF_CHAN); -+ } -+ if (!prev_chan && chan) -+ prev_chan = chan; -+ else if (prev_chan && (prev_chan != chan)) -+ wl->vsdb_mode = true; -+ } -+ } -+ return; -+} -+static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info, -+ enum wl_status state, bool set) -+{ -+ s32 pm = PM_FAST; -+ s32 err = BCME_OK; -+ u32 chan = 0; -+ struct net_info *iter, *next; -+ struct net_device *primary_dev = wl_to_prmry_ndev(wl); -+ AP6210_DEBUG("Enter state %d set %d _net_info->pm_restore %d iface %s\n", -+ state, set, _net_info->pm_restore, _net_info->ndev->name); -+ -+ if (state != WL_STATUS_CONNECTED) -+ return 0; -+ -+ if (set) { -+ wl_cfg80211_concurrent_roam(wl, 1); -+ -+ if (wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) { -+ pm = PM_OFF; -+ AP6210_DEBUG("%s:AP power save %s\n", _net_info->ndev->name, -+ pm ? "enabled" : "disabled"); -+ if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM, -+ &pm, sizeof(pm), true)) != 0) { -+ if (err == -ENODEV) -+ AP6210_DEBUG("%s:net_device is not ready\n", -+ _net_info->ndev->name); -+ else -+ AP6210_ERR("%s:error (%d)\n", _net_info->ndev->name, err); -+ } -+ if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false)) -+ AP6210_ERR(" failed to unset WLC_E_P2P_PROPREQ_MSG\n"); -+ return 0; -+ } -+ wl_cfg80211_determine_vsdb_mode(wl); -+ pm = PM_OFF; -+ for_each_ndev(wl, iter, next) { -+ if ((!wl->vsdb_mode) && (iter->ndev != _net_info->ndev)) { -+ /* Do not touch the other interfaces power save -+ * if we are not in vsdb mode -+ */ -+ continue; -+ } -+ /* Save the current power mode */ -+ iter->pm_restore = true; -+ err = wldev_ioctl(iter->ndev, WLC_GET_PM, &iter->pm, -+ sizeof(iter->pm), false); -+ AP6210_DEBUG("%s:power save %s\n", iter->ndev->name, -+ iter->pm ? "enabled" : "disabled"); -+ if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, -+ sizeof(pm), true)) != 0) { -+ if (err == -ENODEV) -+ AP6210_DEBUG("%s:netdev not ready\n", iter->ndev->name); -+ else -+ AP6210_ERR("%s:error (%d)\n", iter->ndev->name, err); -+ iter->ndev->ieee80211_ptr->ps = pm ? true: false; -+ } -+ } -+ } -+ else { /* clear */ -+ chan = 0; -+ /* clear chan information when the net device is disconnected */ -+ wl_update_prof(wl, _net_info->ndev, NULL, &chan, WL_PROF_CHAN); -+ wl_cfg80211_determine_vsdb_mode(wl); -+ for_each_ndev(wl, iter, next) { -+ if (iter->pm_restore) { -+ AP6210_DEBUG("%s:restoring power save %s\n", -+ iter->ndev->name, (iter->pm ? "enabled" : "disabled")); -+ err = wldev_ioctl(iter->ndev, -+ WLC_SET_PM, &iter->pm, sizeof(iter->pm), true); -+ if (unlikely(err)) { -+ if (err == -ENODEV) -+ AP6210_DEBUG("%s:netdev not ready\n", iter->ndev->name); -+ else -+ AP6210_ERR("%s:error(%d)\n", iter->ndev->name, err); -+ break; -+ } -+ iter->pm_restore = 0; -+ } -+ } -+ wl_cfg80211_concurrent_roam(wl, 0); -+ } -+ return err; -+} -+ -+static s32 wl_init_scan(struct wl_priv *wl) -+{ -+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); -+ int err = 0; -+ -+ if (wl->iscan_on) { -+ iscan->dev = wl_to_prmry_ndev(wl); -+ iscan->state = WL_ISCAN_STATE_IDLE; -+ wl_init_iscan_handler(iscan); -+ iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; -+ init_timer(&iscan->timer); -+ iscan->timer.data = (unsigned long) iscan; -+ iscan->timer.function = wl_iscan_timer; -+ sema_init(&iscan->sync, 0); -+ iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); -+ if (IS_ERR(iscan->tsk)) { -+ AP6210_ERR("Could not create iscan thread\n"); -+ iscan->tsk = NULL; -+ return -ENOMEM; -+ } -+ iscan->data = wl; -+ } else if (wl->escan_on) { -+ wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler; -+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; -+ } -+ /* Init scan_timeout timer */ -+ init_timer(&wl->scan_timeout); -+ wl->scan_timeout.data = (unsigned long) wl; -+ wl->scan_timeout.function = wl_scan_timeout; -+ -+ return err; -+} -+ -+static s32 wl_init_priv(struct wl_priv *wl) -+{ -+ struct wiphy *wiphy = wl_to_wiphy(wl); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ s32 err = 0; -+ -+ wl->scan_request = NULL; -+ wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); -+ wl->iscan_on = false; -+ wl->escan_on = true; -+ wl->roam_on = false; -+ wl->iscan_kickstart = false; -+ wl->active_scan = true; -+ wl->rf_blocked = false; -+ wl->vsdb_mode = false; -+ wl->wlfc_on = false; -+ wl->roamoff_on_concurrent = true; -+ /* register interested state */ -+ set_bit(WL_STATUS_CONNECTED, &wl->interrested_state); -+ spin_lock_init(&wl->cfgdrv_lock); -+ mutex_init(&wl->ioctl_buf_sync); -+ init_waitqueue_head(&wl->netif_change_event); -+ init_completion(&wl->send_af_done); -+ init_completion(&wl->iface_disable); -+ wl_init_eq(wl); -+ err = wl_init_priv_mem(wl); -+ if (err) -+ return err; -+ if (wl_create_event_handler(wl)) -+ return -ENOMEM; -+ wl_init_event_handler(wl); -+ mutex_init(&wl->usr_sync); -+ mutex_init(&wl->event_sync); -+ err = wl_init_scan(wl); -+ if (err) -+ return err; -+ wl_init_conf(wl->conf); -+ wl_init_prof(wl, ndev); -+ wl_link_down(wl); -+ DNGL_FUNC(dhd_cfg80211_init, (wl)); -+ -+ return err; -+} -+ -+static void wl_deinit_priv(struct wl_priv *wl) -+{ -+ DNGL_FUNC(dhd_cfg80211_deinit, (wl)); -+ wl_destroy_event_handler(wl); -+ wl_flush_eq(wl); -+ wl_link_down(wl); -+ del_timer_sync(&wl->scan_timeout); -+ wl_term_iscan(wl); -+ wl_deinit_priv_mem(wl); -+ unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier); -+} -+ -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+static s32 wl_cfg80211_attach_p2p(void) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ AP6210_DEBUG("Enter \n"); -+ -+ if (wl_cfgp2p_register_ndev(wl) < 0) { -+ AP6210_ERR("%s: P2P attach failed. \n", __func__); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static s32 wl_cfg80211_detach_p2p(void) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct wireless_dev *wdev = wl->p2p_wdev; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (!wdev || !wl) { -+ AP6210_ERR("Invalid Ptr\n"); -+ return -EINVAL; -+ } -+ -+ wl_cfgp2p_unregister_ndev(wl); -+ -+ wl->p2p_wdev = NULL; -+ wl->p2p_net = NULL; -+ AP6210_DEBUG("Freeing 0x%08x \n", (unsigned int)wdev); -+ kfree(wdev); -+ -+ return 0; -+} -+#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */ -+ -+s32 wl_cfg80211_attach_post(struct net_device *ndev) -+{ -+ struct wl_priv * wl = NULL; -+ s32 err = 0; -+ AP6210_DEBUG("In\n"); -+ if (unlikely(!ndev)) { -+ AP6210_ERR("ndev is invaild\n"); -+ return -ENODEV; -+ } -+ wl = wlcfg_drv_priv; -+ if (unlikely(!wl)) { -+ AP6210_ERR("wl is invaild\n"); -+ return -EINVAL; -+ } -+ if (!wl_get_drv_status(wl, READY, ndev)) { -+ if (wl->wdev && -+ wl_cfgp2p_supported(wl, ndev)) { -+#if !defined(WL_ENABLE_P2P_IF) -+ wl->wdev->wiphy->interface_modes |= -+ (BIT(NL80211_IFTYPE_P2P_CLIENT)| -+ BIT(NL80211_IFTYPE_P2P_GO)); -+#endif -+ if ((err = wl_cfgp2p_init_priv(wl)) != 0) -+ goto fail; -+ -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+ if (wl->p2p_net) { -+ /* Update MAC addr for p2p0 interface here. */ -+ memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN); -+ wl->p2p_net->dev_addr[0] |= 0x02; -+ AP6210_ERR("%s: p2p_dev_addr="MACDBG "\n", -+ wl->p2p_net->name, -+ MAC2STRDBG(wl->p2p_net->dev_addr)); -+ } else { -+ AP6210_ERR("p2p_net not yet populated." -+ " Couldn't update the MAC Address for p2p0 \n"); -+ return -ENODEV; -+ } -+#endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */ -+ -+ wl->p2p_supported = true; -+ } -+ } -+ wl_set_drv_status(wl, READY, ndev); -+fail: -+ return err; -+} -+ -+s32 wl_cfg80211_attach(struct net_device *ndev, void *data) -+{ -+ struct wireless_dev *wdev; -+ struct wl_priv *wl; -+ s32 err = 0; -+ struct device *dev; -+ -+ AP6210_DEBUG("In\n"); -+ if (!ndev) { -+ AP6210_ERR("ndev is invaild\n"); -+ return -ENODEV; -+ } -+ AP6210_DEBUG("func %p\n", wl_cfg80211_get_parent_dev()); -+ dev = wl_cfg80211_get_parent_dev(); -+ -+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); -+ if (unlikely(!wdev)) { -+ AP6210_ERR("Could not allocate wireless device\n"); -+ return -ENOMEM; -+ } -+ err = wl_setup_wiphy(wdev, dev); -+ if (unlikely(err)) { -+ kfree(wdev); -+ return -ENOMEM; -+ } -+ wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); -+ wl = (struct wl_priv *)wiphy_priv(wdev->wiphy); -+ wl->wdev = wdev; -+ wl->pub = data; -+ INIT_LIST_HEAD(&wl->net_list); -+ ndev->ieee80211_ptr = wdev; -+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); -+ wdev->netdev = ndev; -+ wl->state_notifier = wl_notifier_change_state; -+ err = wl_alloc_netinfo(wl, ndev, wdev, WL_MODE_BSS, PM_ENABLE); -+ if (err) { -+ AP6210_ERR("Failed to alloc net_info (%d)\n", err); -+ goto cfg80211_attach_out; -+ } -+ err = wl_init_priv(wl); -+ if (err) { -+ AP6210_ERR("Failed to init iwm_priv (%d)\n", err); -+ goto cfg80211_attach_out; -+ } -+ -+ err = wl_setup_rfkill(wl, TRUE); -+ if (err) { -+ AP6210_ERR("Failed to setup rfkill %d\n", err); -+ goto cfg80211_attach_out; -+ } -+ err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier); -+ if (err) { -+ AP6210_ERR("Failed to register notifierl %d\n", err); -+ goto cfg80211_attach_out; -+ } -+#if defined(COEX_DHCP) -+ if (wl_cfg80211_btcoex_init(wl)) -+ goto cfg80211_attach_out; -+#endif -+#if defined(BSSCACHE) -+ wl_init_bss_cache_ctrl(&g_bss_cache_ctrl); -+#endif -+ -+ wlcfg_drv_priv = wl; -+ -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+ err = wl_cfg80211_attach_p2p(); -+ if (err) -+ goto cfg80211_attach_out; -+#endif -+ -+ return err; -+ -+cfg80211_attach_out: -+ err = wl_setup_rfkill(wl, FALSE); -+ wl_free_wdev(wl); -+ return err; -+} -+ -+void wl_cfg80211_detach(void *para) -+{ -+ struct wl_priv *wl; -+ -+ (void)para; -+ wl = wlcfg_drv_priv; -+ -+ AP6210_DEBUG("In\n"); -+ -+#if defined(COEX_DHCP) -+ wl_cfg80211_btcoex_deinit(wl); -+#endif -+ -+ wl_setup_rfkill(wl, FALSE); -+ if (wl->p2p_supported) { -+ if (timer_pending(&wl->p2p->listen_timer)) -+ del_timer_sync(&wl->p2p->listen_timer); -+ wl_cfgp2p_deinit_priv(wl); -+ } -+ -+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) -+ wl_cfg80211_detach_p2p(); -+#endif -+ wl_deinit_priv(wl); -+ wlcfg_drv_priv = NULL; -+ wl_cfg80211_clear_parent_dev(); -+ wl_free_wdev(wl); -+#if defined(RSSIAVG) -+ wl_free_rssi_cache(&g_rssi_cache_ctrl); -+#endif -+#if defined(BSSCACHE) -+ wl_release_bss_cache_ctrl(&g_bss_cache_ctrl); -+#endif -+ /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl", -+ * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!! -+ */ -+} -+ -+static void wl_wakeup_event(struct wl_priv *wl) -+{ -+ if (wl->event_tsk.thr_pid >= 0) { -+ DHD_OS_WAKE_LOCK(wl->pub); -+ up(&wl->event_tsk.sema); -+ } -+} -+ -+static int wl_is_p2p_event(struct wl_event_q *e) -+{ -+ switch (e->etype) { -+ /* We have to seperate out the P2P events received -+ * on primary interface so that it can be send up -+ * via p2p0 interface. -+ */ -+ case WLC_E_P2P_PROBREQ_MSG: -+ case WLC_E_P2P_DISC_LISTEN_COMPLETE: -+ case WLC_E_ACTION_FRAME_RX: -+ case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE: -+ case WLC_E_ACTION_FRAME_COMPLETE: -+ -+ if (e->emsg.ifidx != 0) { -+ AP6210_DEBUG("P2P Event on Virtual I/F (ifidx:%d) \n", -+ e->emsg.ifidx); -+ /* We are only bothered about the P2P events received -+ * on primary interface. For rest of them return false -+ * so that it is sent over the interface corresponding -+ * to the ifidx. -+ */ -+ return FALSE; -+ } else { -+ AP6210_DEBUG("P2P Event on Primary I/F (ifidx:%d)." -+ " Sent it to p2p0 \n", e->emsg.ifidx); -+ return TRUE; -+ } -+ break; -+ -+ default: -+ AP6210_DEBUG("NON-P2P Event %d on ifidx (ifidx:%d) \n", -+ e->etype, e->emsg.ifidx); -+ return FALSE; -+ } -+} -+ -+static s32 wl_event_handler(void *data) -+{ -+ struct net_device *netdev; -+ struct wl_priv *wl = NULL; -+ struct wl_event_q *e; -+ tsk_ctl_t *tsk = (tsk_ctl_t *)data; -+ -+ wl = (struct wl_priv *)tsk->parent; -+#ifndef USE_KTHREAD_API -+ DAEMONIZE("dhd_cfg80211_event"); -+ complete(&tsk->completed); -+#else -+ AP6210_ERR("tsk Enter, tsk = 0x%08x\n", (unsigned int)tsk); -+#endif -+ -+ while (down_interruptible (&tsk->sema) == 0) { -+ SMP_RD_BARRIER_DEPENDS(); -+ if (tsk->terminated) -+ break; -+ while ((e = wl_deq_event(wl))) { -+ AP6210_DEBUG("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx); -+ /* All P2P device address related events comes on primary interface since -+ * there is no corresponding bsscfg for P2P interface. Map it to p2p0 -+ * interface. -+ */ -+ if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) { -+ netdev = wl->p2p_net; -+ } else { -+ netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx); -+ } -+ if (!netdev) -+ netdev = wl_to_prmry_ndev(wl); -+ if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) { -+ wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata); -+ } else { -+ AP6210_DEBUG("Unknown Event (%d): ignoring\n", e->etype); -+ } -+ wl_put_event(e); -+ } -+ DHD_OS_WAKE_UNLOCK(wl->pub); -+ } -+ AP6210_ERR("%s was terminated\n", __func__); -+ complete_and_exit(&tsk->completed, 0); -+ return 0; -+} -+ -+void -+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) -+{ -+ u32 event_type = ntoh32(e->event_type); -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+#if (WL_DBG_LEVEL > 0) -+ s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ? -+ wl_dbg_estr[event_type] : (s8 *) "Unknown"; -+ AP6210_DEBUG("event_type (%d):" "WLC_E_" "%s\n", event_type, estr); -+#endif /* (WL_DBG_LEVEL > 0) */ -+ -+ if (event_type == WLC_E_PFN_NET_FOUND) { -+ AP6210_DEBUG(" PNOEVENT: PNO_NET_FOUND\n"); -+ } -+ else if (event_type == WLC_E_PFN_NET_LOST) { -+ AP6210_DEBUG(" PNOEVENT: PNO_NET_LOST\n"); -+ } -+ -+ if (likely(!wl_enq_event(wl, ndev, event_type, e, data))) -+ wl_wakeup_event(wl); -+} -+ -+static void wl_init_eq(struct wl_priv *wl) -+{ -+ wl_init_eq_lock(wl); -+ INIT_LIST_HEAD(&wl->eq_list); -+} -+ -+static void wl_flush_eq(struct wl_priv *wl) -+{ -+ struct wl_event_q *e; -+ unsigned long flags; -+ -+ flags = wl_lock_eq(wl); -+ while (!list_empty(&wl->eq_list)) { -+ e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); -+ list_del(&e->eq_list); -+ kfree(e); -+ } -+ wl_unlock_eq(wl, flags); -+} -+ -+/* -+* retrieve first queued event from head -+*/ -+ -+static struct wl_event_q *wl_deq_event(struct wl_priv *wl) -+{ -+ struct wl_event_q *e = NULL; -+ unsigned long flags; -+ -+ flags = wl_lock_eq(wl); -+ if (likely(!list_empty(&wl->eq_list))) { -+ e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); -+ list_del(&e->eq_list); -+ } -+ wl_unlock_eq(wl, flags); -+ -+ return e; -+} -+ -+/* -+ * push event to tail of the queue -+ */ -+ -+static s32 -+wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg, -+ void *data) -+{ -+ struct wl_event_q *e; -+ s32 err = 0; -+ uint32 evtq_size; -+ uint32 data_len; -+ unsigned long flags; -+ gfp_t aflags; -+ -+ data_len = 0; -+ if (data) -+ data_len = ntoh32(msg->datalen); -+ evtq_size = sizeof(struct wl_event_q) + data_len; -+ aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; -+ e = kzalloc(evtq_size, aflags); -+ if (unlikely(!e)) { -+ AP6210_ERR("event alloc failed\n"); -+ return -ENOMEM; -+ } -+ e->etype = event; -+ memcpy(&e->emsg, msg, sizeof(wl_event_msg_t)); -+ if (data) -+ memcpy(e->edata, data, data_len); -+ flags = wl_lock_eq(wl); -+ list_add_tail(&e->eq_list, &wl->eq_list); -+ wl_unlock_eq(wl, flags); -+ -+ return err; -+} -+ -+static void wl_put_event(struct wl_event_q *e) -+{ -+ kfree(e); -+} -+ -+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype) -+{ -+ s32 infra = 0; -+ s32 err = 0; -+ s32 mode = 0; -+ switch (iftype) { -+ case NL80211_IFTYPE_MONITOR: -+ case NL80211_IFTYPE_WDS: -+ AP6210_ERR("type (%d) : currently we do not support this mode\n", -+ iftype); -+ err = -EINVAL; -+ return err; -+ case NL80211_IFTYPE_ADHOC: -+ mode = WL_MODE_IBSS; -+ break; -+ case NL80211_IFTYPE_STATION: -+ case NL80211_IFTYPE_P2P_CLIENT: -+ mode = WL_MODE_BSS; -+ infra = 1; -+ break; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+ mode = WL_MODE_AP; -+ infra = 1; -+ break; -+ default: -+ err = -EINVAL; -+ AP6210_ERR("invalid type (%d)\n", iftype); -+ return err; -+ } -+ infra = htod32(infra); -+ err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true); -+ if (unlikely(err)) { -+ AP6210_ERR("WLC_SET_INFRA error (%d)\n", err); -+ return err; -+ } -+ -+ wl_set_mode_by_netdev(wl, ndev, mode); -+ -+ return 0; -+} -+ -+void wl_cfg80211_add_to_eventbuffer(struct wl_eventmsg_buf *ev, u16 event, bool set) -+{ -+ if (!ev || (event > WLC_E_LAST)) -+ return; -+ -+ if (ev->num < MAX_EVENT_BUF_NUM) { -+ ev->event[ev->num].type = event; -+ ev->event[ev->num].set = set; -+ ev->num++; -+ } else { -+ AP6210_ERR("evenbuffer doesn't support > %u events. Update" -+ " the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM); -+ ASSERT(0); -+ } -+} -+ -+s32 wl_cfg80211_apply_eventbuffer( -+ struct net_device *ndev, -+ struct wl_priv *wl, -+ wl_eventmsg_buf_t *ev) -+{ -+ char eventmask[WL_EVENTING_MASK_LEN]; -+ int i, ret = 0; -+ s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; -+ -+ if (!ev || (!ev->num)) -+ return -EINVAL; -+ -+ mutex_lock(&wl->event_sync); -+ -+ /* Read event_msgs mask */ -+ bcm_mkiovar("event_msgs", NULL, 0, iovbuf, -+ sizeof(iovbuf)); -+ ret = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false); -+ if (unlikely(ret)) { -+ AP6210_ERR("Get event_msgs error (%d)\n", ret); -+ goto exit; -+ } -+ memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); -+ -+ /* apply the set bits */ -+ for (i = 0; i < ev->num; i++) { -+ if (ev->event[i].set) -+ setbit(eventmask, ev->event[i].type); -+ else -+ clrbit(eventmask, ev->event[i].type); -+ } -+ -+ /* Write updated Event mask */ -+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, -+ sizeof(iovbuf)); -+ ret = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true); -+ if (unlikely(ret)) { -+ AP6210_ERR("Set event_msgs error (%d)\n", ret); -+ } -+ -+exit: -+ mutex_unlock(&wl->event_sync); -+ return ret; -+} -+ -+s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add) -+{ -+ s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; -+ s8 eventmask[WL_EVENTING_MASK_LEN]; -+ s32 err = 0; -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ if (!ndev || !wl) -+ return -ENODEV; -+ -+ mutex_lock(&wl->event_sync); -+ -+ /* Setup event_msgs */ -+ bcm_mkiovar("event_msgs", NULL, 0, iovbuf, -+ sizeof(iovbuf)); -+ err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false); -+ if (unlikely(err)) { -+ AP6210_ERR("Get event_msgs error (%d)\n", err); -+ goto eventmsg_out; -+ } -+ memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); -+ if (add) { -+ setbit(eventmask, event); -+ } else { -+ clrbit(eventmask, event); -+ } -+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, -+ sizeof(iovbuf)); -+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true); -+ if (unlikely(err)) { -+ AP6210_ERR("Set event_msgs error (%d)\n", err); -+ goto eventmsg_out; -+ } -+ -+eventmsg_out: -+ mutex_unlock(&wl->event_sync); -+ return err; -+} -+ -+static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap) -+{ -+ struct net_device *dev = wl_to_prmry_ndev(wl); -+ struct ieee80211_channel *band_chan_arr = NULL; -+ wl_uint32_list_t *list; -+ u32 i, j, index, n_2g, n_5g, band, channel, array_size; -+ u32 *n_cnt = NULL; -+ chanspec_t c = 0; -+ s32 err = BCME_OK; -+ bool update; -+ bool ht40_allowed; -+ u8 *pbuf = NULL; -+ -+#define LOCAL_BUF_LEN 1024 -+ pbuf = kzalloc(LOCAL_BUF_LEN, GFP_KERNEL); -+ -+ if (pbuf == NULL) { -+ AP6210_ERR("failed to allocate local buf\n"); -+ return -ENOMEM; -+ } -+ list = (wl_uint32_list_t *)(void *) pbuf; -+ list->count = htod32(WL_NUMCHANSPECS); -+ -+ -+ err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL, -+ 0, pbuf, LOCAL_BUF_LEN, 0, &wl->ioctl_buf_sync); -+ if (err != 0) { -+ AP6210_ERR("get chanspecs failed with %d\n", err); -+ kfree(pbuf); -+ return err; -+ } -+#undef LOCAL_BUF_LEN -+ -+ list = (wl_uint32_list_t *)(void *)pbuf; -+ band = array_size = n_2g = n_5g = 0; -+ for (i = 0; i < dtoh32(list->count); i++) { -+ index = 0; -+ update = false; -+ ht40_allowed = false; -+ c = (chanspec_t)dtoh32(list->element[i]); -+ c = wl_chspec_driver_to_host(c); -+ channel = CHSPEC_CHANNEL(c); -+ if (CHSPEC_IS40(c)) { -+ if (CHSPEC_SB_UPPER(c)) -+ channel += CH_10MHZ_APART; -+ else -+ channel -= CH_10MHZ_APART; -+ } else if (CHSPEC_IS80(c)) { -+ AP6210_DEBUG("HT80 center channel : %d\n", channel); -+ continue; -+ } -+ if (CHSPEC_IS2G(c) && (channel >= CH_MIN_2G_CHANNEL) && -+ (channel <= CH_MAX_2G_CHANNEL)) { -+ band_chan_arr = __wl_2ghz_channels; -+ array_size = ARRAYSIZE(__wl_2ghz_channels); -+ n_cnt = &n_2g; -+ band = IEEE80211_BAND_2GHZ; -+ ht40_allowed = (bw_cap == WLC_N_BW_40ALL)? true : false; -+ } else if (CHSPEC_IS5G(c) && channel >= CH_MIN_5G_CHANNEL) { -+ band_chan_arr = __wl_5ghz_a_channels; -+ array_size = ARRAYSIZE(__wl_5ghz_a_channels); -+ n_cnt = &n_5g; -+ band = IEEE80211_BAND_5GHZ; -+ ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true; -+ } else { -+ AP6210_ERR("Invalid channel Sepc. 0x%x.\n", c); -+ continue; -+ } -+ if (!ht40_allowed && CHSPEC_IS40(c)) -+ continue; -+ for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { -+ if (band_chan_arr[j].hw_value == channel) { -+ update = true; -+ break; -+ } -+ } -+ if (update) -+ index = j; -+ else -+ index = *n_cnt; -+ if (index < array_size) { -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) -+ band_chan_arr[index].center_freq = -+ ieee80211_channel_to_frequency(channel); -+#else -+ band_chan_arr[index].center_freq = -+ ieee80211_channel_to_frequency(channel, band); -+#endif -+ band_chan_arr[index].hw_value = channel; -+ -+ if (CHSPEC_IS40(c) && ht40_allowed) { -+ /* assuming the order is HT20, HT40 Upper, -+ HT40 lower from chanspecs -+ */ -+ u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; -+ if (CHSPEC_SB_UPPER(c)) { -+ if (ht40_flag == IEEE80211_CHAN_NO_HT40) -+ band_chan_arr[index].flags &= -+ ~IEEE80211_CHAN_NO_HT40; -+ band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS; -+ } else { -+ /* It should be one of -+ IEEE80211_CHAN_NO_HT40 or IEEE80211_CHAN_NO_HT40PLUS -+ */ -+ band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40; -+ if (ht40_flag == IEEE80211_CHAN_NO_HT40) -+ band_chan_arr[index].flags |= -+ IEEE80211_CHAN_NO_HT40MINUS; -+ } -+ } else { -+ band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40; -+ if (band == IEEE80211_BAND_2GHZ) -+ channel |= WL_CHANSPEC_BAND_2G; -+ else -+ channel |= WL_CHANSPEC_BAND_5G; -+ channel |= WL_CHANSPEC_BW_20; -+ channel = wl_chspec_host_to_driver(channel); -+ err = wldev_iovar_getint(dev, "per_chan_info", &channel); -+ if (!err) { -+ if (channel & WL_CHAN_RADAR) -+ band_chan_arr[index].flags |= -+ (IEEE80211_CHAN_RADAR | -+ IEEE80211_CHAN_NO_IBSS); -+ if (channel & WL_CHAN_PASSIVE) -+ band_chan_arr[index].flags |= -+ IEEE80211_CHAN_PASSIVE_SCAN; -+ } -+ } -+ if (!update) -+ (*n_cnt)++; -+ } -+ -+ } -+ __wl_band_2ghz.n_channels = n_2g; -+ __wl_band_5ghz_a.n_channels = n_5g; -+ kfree(pbuf); -+ return err; -+} -+ -+s32 wl_update_wiphybands(struct wl_priv *wl, bool notify) -+{ -+ struct wiphy *wiphy; -+ struct net_device *dev; -+ u32 bandlist[3]; -+ u32 nband = 0; -+ u32 i = 0; -+ s32 err = 0; -+ s32 index = 0; -+ s32 nmode = 0; -+ bool rollback_lock = false; -+ s32 bw_cap = 0; -+ s32 cur_band = -1; -+ struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS] = {NULL, }; -+ -+ if (wl == NULL) { -+ wl = wlcfg_drv_priv; -+ mutex_lock(&wl->usr_sync); -+ rollback_lock = true; -+ } -+ dev = wl_to_prmry_ndev(wl); -+ -+ memset(bandlist, 0, sizeof(bandlist)); -+ err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist, -+ sizeof(bandlist), false); -+ if (unlikely(err)) { -+ AP6210_ERR("error read bandlist (%d)\n", err); -+ goto end_bands; -+ } -+ -+ wiphy = wl_to_wiphy(wl); -+ -+ err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band, -+ sizeof(s32), false); -+ if (unlikely(err)) { -+ AP6210_ERR("error (%d)\n", err); -+ goto end_bands; -+ } -+ -+ err = wldev_iovar_getint(dev, "nmode", &nmode); -+ if (unlikely(err)) { -+ AP6210_ERR("error reading nmode (%d)\n", err); -+ } else { -+ /* For nmodeonly check bw cap */ -+ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); -+ if (unlikely(err)) { -+ AP6210_ERR("error get mimo_bw_cap (%d)\n", err); -+ } -+ } -+ -+ err = wl_construct_reginfo(wl, bw_cap); -+ if (err) { -+ AP6210_ERR("wl_construct_reginfo() fails err=%d\n", err); -+ if (err != BCME_UNSUPPORTED) -+ goto end_bands; -+ err = 0; -+ } -+ -+ nband = bandlist[0]; -+ -+ for (i = 1; i <= nband && i < ARRAYSIZE(bandlist); i++) { -+ index = -1; -+ if (bandlist[i] == WLC_BAND_5G && __wl_band_5ghz_a.n_channels > 0) { -+ bands[IEEE80211_BAND_5GHZ] = -+ &__wl_band_5ghz_a; -+ index = IEEE80211_BAND_5GHZ; -+ if (bw_cap == WLC_N_BW_40ALL || bw_cap == WLC_N_BW_20IN2G_40IN5G) -+ bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; -+ } -+ else if (bandlist[i] == WLC_BAND_2G && __wl_band_2ghz.n_channels > 0) { -+ bands[IEEE80211_BAND_2GHZ] = -+ &__wl_band_2ghz; -+ index = IEEE80211_BAND_2GHZ; -+ if (bw_cap == WLC_N_BW_40ALL) -+ bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; -+ } -+ -+ if ((index >= 0) && nmode) { -+ bands[index]->ht_cap.cap |= -+ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40); -+ bands[index]->ht_cap.ht_supported = TRUE; -+ bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; -+ bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; -+ /* An HT shall support all EQM rates for one spatial stream */ -+ bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; -+ } -+ -+ } -+ -+ wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ]; -+ wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ]; -+ -+ if (notify) -+ wiphy_apply_custom_regulatory(wiphy, &brcm_regdom); -+ -+end_bands: -+ if (rollback_lock) -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+ -+static s32 __wl_cfg80211_up(struct wl_priv *wl) -+{ -+ s32 err = 0; -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ struct wireless_dev *wdev = ndev->ieee80211_ptr; -+ -+ AP6210_DEBUG("In\n"); -+ -+ err = dhd_config_dongle(wl, false); -+ if (unlikely(err)) -+ return err; -+ -+ err = wl_config_ifmode(wl, ndev, wdev->iftype); -+ if (unlikely(err && err != -EINPROGRESS)) { -+ AP6210_ERR("wl_config_ifmode failed\n"); -+ } -+ err = wl_update_wiphybands(wl, true); -+ if (unlikely(err)) { -+ AP6210_ERR("wl_update_wiphybands failed\n"); -+ } -+ -+ err = dhd_monitor_init(wl->pub); -+ err = wl_invoke_iscan(wl); -+ -+#ifdef WL_HOST_BAND_MGMT -+ /* By default the curr_band is initialized to BAND_AUTO */ -+ if (wl_cfg80211_set_band(ndev, WLC_BAND_AUTO) < 0) { -+ AP6210_ERR("roam_band set failed\n"); -+ err = -1; -+ } -+#endif /* WL_HOST_BAND_MGMT */ -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+ /* wlan scan_supp timer and work thread info */ -+ init_timer(&wl->scan_supp_timer); -+ wl->scan_supp_timer.data = (ulong)wl; -+ wl->scan_supp_timer.function = wl_cfg80211_scan_supp_timerfunc; -+ INIT_WORK(&wl->wlan_work, wl_cfg80211_work_handler); -+#endif /* DHCP_SCAN_SUPPRESS */ -+ -+ wl_set_drv_status(wl, READY, ndev); -+ return err; -+} -+ -+static s32 __wl_cfg80211_down(struct wl_priv *wl) -+{ -+ s32 err = 0; -+ unsigned long flags; -+ struct net_info *iter, *next; -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ struct net_device *p2p_net = wl->p2p_net; -+ u32 bssidx = wl_cfgp2p_find_idx(wl, ndev); -+ AP6210_DEBUG("In\n"); -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+ /* Force clear of scan_suppress */ -+ if (wl->scan_suppressed) -+ wl_cfg80211_scan_suppress(ndev, 0); -+ if (timer_pending(&wl->scan_supp_timer)) -+ del_timer_sync(&wl->scan_supp_timer); -+ cancel_work_sync(&wl->wlan_work); -+#endif /* DHCP_SCAN_SUPPRESS */ -+ -+ /* If BSS is operational (e.g SoftAp), bring it down */ -+ if (wl_cfgp2p_bss_isup(ndev, bssidx)) { -+ if (wl_cfgp2p_bss(wl, ndev, bssidx, 0) < 0) -+ AP6210_ERR("BSS down failed \n"); -+ } -+ -+ /* Check if cfg80211 interface is already down */ -+ if (!wl_get_drv_status(wl, READY, ndev)) -+ return err; /* it is even not ready */ -+ -+ for_each_ndev(wl, iter, next) -+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev); -+ -+ wl_term_iscan(wl); -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ if (wl->scan_request) { -+ cfg80211_scan_done(wl->scan_request, true); -+ wl->scan_request = NULL; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ -+ for_each_ndev(wl, iter, next) { -+ wl_clr_drv_status(wl, READY, iter->ndev); -+ wl_clr_drv_status(wl, SCANNING, iter->ndev); -+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev); -+ wl_clr_drv_status(wl, CONNECTING, iter->ndev); -+ wl_clr_drv_status(wl, CONNECTED, iter->ndev); -+ wl_clr_drv_status(wl, DISCONNECTING, iter->ndev); -+ wl_clr_drv_status(wl, AP_CREATED, iter->ndev); -+ wl_clr_drv_status(wl, AP_CREATING, iter->ndev); -+ } -+ wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype = -+ NL80211_IFTYPE_STATION; -+ if (p2p_net) -+ dev_close(p2p_net); -+ DNGL_FUNC(dhd_cfg80211_down, (wl)); -+ wl_flush_eq(wl); -+ wl_link_down(wl); -+ if (wl->p2p_supported) -+ wl_cfgp2p_down(wl); -+ dhd_monitor_uninit(); -+ -+ return err; -+} -+ -+s32 wl_cfg80211_up(void *para) -+{ -+ struct wl_priv *wl; -+ s32 err = 0; -+ int val = 1; -+ dhd_pub_t *dhd; -+ -+ (void)para; -+ AP6210_DEBUG("In\n"); -+ wl = wlcfg_drv_priv; -+ -+ if ((err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_VERSION, &val, -+ sizeof(int), false) < 0)) { -+ AP6210_ERR("WLC_GET_VERSION failed, err=%d\n", err); -+ return err; -+ } -+ val = dtoh32(val); -+ if (val != WLC_IOCTL_VERSION && val != 1) { -+ AP6210_ERR("Version mismatch, please upgrade. Got %d, expected %d or 1\n", -+ val, WLC_IOCTL_VERSION); -+ return BCME_VERSION; -+ } -+ ioctl_version = val; -+ AP6210_DEBUG("WLC_GET_VERSION=%d\n", ioctl_version); -+ -+ mutex_lock(&wl->usr_sync); -+ dhd = (dhd_pub_t *)(wl->pub); -+ if (!(dhd->op_mode & DHD_FLAG_HOSTAP_MODE)) { -+ err = wl_cfg80211_attach_post(wl_to_prmry_ndev(wl)); -+ if (unlikely(err)) -+ return err; -+ } -+ err = __wl_cfg80211_up(wl); -+ if (unlikely(err)) -+ AP6210_ERR("__wl_cfg80211_up failed\n"); -+ mutex_unlock(&wl->usr_sync); -+ return err; -+} -+ -+/* Private Event to Supplicant with indication that chip hangs */ -+int wl_cfg80211_hang(struct net_device *dev, u16 reason) -+{ -+ struct wl_priv *wl; -+ wl = wlcfg_drv_priv; -+ -+ AP6210_ERR("In : chip crash eventing\n"); -+ cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL); -+#if defined(RSSIAVG) -+ wl_free_rssi_cache(&g_rssi_cache_ctrl); -+#endif -+#if defined(BSSCACHE) -+ wl_free_bss_cache(&g_bss_cache_ctrl); -+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); -+#endif -+ if (wl != NULL) { -+ wl_link_down(wl); -+ } -+ return 0; -+} -+ -+s32 wl_cfg80211_down(void *para) -+{ -+ struct wl_priv *wl; -+ s32 err = 0; -+ -+ (void)para; -+ AP6210_DEBUG("In\n"); -+ wl = wlcfg_drv_priv; -+ mutex_lock(&wl->usr_sync); -+#if defined(RSSIAVG) -+ wl_free_rssi_cache(&g_rssi_cache_ctrl); -+#endif -+#if defined(BSSCACHE) -+ wl_free_bss_cache(&g_bss_cache_ctrl); -+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); -+#endif -+ err = __wl_cfg80211_down(wl); -+ mutex_unlock(&wl->usr_sync); -+ -+ return err; -+} -+ -+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item) -+{ -+ unsigned long flags; -+ void *rptr = NULL; -+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); -+ -+ if (!profile) -+ return NULL; -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ switch (item) { -+ case WL_PROF_SEC: -+ rptr = &profile->sec; -+ break; -+ case WL_PROF_ACT: -+ rptr = &profile->active; -+ break; -+ case WL_PROF_BSSID: -+ rptr = profile->bssid; -+ break; -+ case WL_PROF_SSID: -+ rptr = &profile->ssid; -+ break; -+ case WL_PROF_CHAN: -+ rptr = &profile->channel; -+ break; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ if (!rptr) -+ AP6210_ERR("invalid item (%d)\n", item); -+ return rptr; -+} -+ -+static s32 -+wl_update_prof(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data, s32 item) -+{ -+ s32 err = 0; -+ struct wlc_ssid *ssid; -+ unsigned long flags; -+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev); -+ -+ if (!profile) -+ return WL_INVALID; -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ switch (item) { -+ case WL_PROF_SSID: -+ ssid = (wlc_ssid_t *) data; -+ memset(profile->ssid.SSID, 0, -+ sizeof(profile->ssid.SSID)); -+ memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len); -+ profile->ssid.SSID_len = ssid->SSID_len; -+ break; -+ case WL_PROF_BSSID: -+ if (data) -+ memcpy(profile->bssid, data, ETHER_ADDR_LEN); -+ else -+ memset(profile->bssid, 0, ETHER_ADDR_LEN); -+ break; -+ case WL_PROF_SEC: -+ memcpy(&profile->sec, data, sizeof(profile->sec)); -+ break; -+ case WL_PROF_ACT: -+ profile->active = *(bool *)data; -+ break; -+ case WL_PROF_BEACONINT: -+ profile->beacon_interval = *(u16 *)data; -+ break; -+ case WL_PROF_DTIMPERIOD: -+ profile->dtim_period = *(u8 *)data; -+ break; -+ case WL_PROF_CHAN: -+ profile->channel = *(u32*)data; -+ default: -+ err = -EOPNOTSUPP; -+ break; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ -+ if (err == EOPNOTSUPP) -+ AP6210_ERR("unsupported item (%d)\n", item); -+ -+ return err; -+} -+ -+void wl_cfg80211_dbg_level(u32 level) -+{ -+ /* -+ * prohibit to change debug level -+ * by insmod parameter. -+ * eventually debug level will be configured -+ * in compile time by using CONFIG_XXX -+ */ -+ /* wl_dbg_level = level; */ -+} -+ -+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev) -+{ -+ return wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS; -+} -+ -+static __used bool wl_is_ibssstarter(struct wl_priv *wl) -+{ -+ return wl->ibss_starter; -+} -+ -+static void wl_rst_ie(struct wl_priv *wl) -+{ -+ struct wl_ie *ie = wl_to_ie(wl); -+ -+ ie->offset = 0; -+} -+ -+static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) -+{ -+ struct wl_ie *ie = wl_to_ie(wl); -+ s32 err = 0; -+ -+ if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) { -+ AP6210_ERR("ei crosses buffer boundary\n"); -+ return -ENOSPC; -+ } -+ ie->buf[ie->offset] = t; -+ ie->buf[ie->offset + 1] = l; -+ memcpy(&ie->buf[ie->offset + 2], v, l); -+ ie->offset += l + 2; -+ -+ return err; -+} -+ -+static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size) -+{ -+ struct wl_ie *ie = wl_to_ie(wl); -+ s32 err = 0; -+ -+ if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) { -+ AP6210_ERR("ei_stream crosses buffer boundary\n"); -+ return -ENOSPC; -+ } -+ memcpy(&ie->buf[ie->offset], ie_stream, ie_size); -+ ie->offset += ie_size; -+ -+ return err; -+} -+ -+static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size) -+{ -+ struct wl_ie *ie = wl_to_ie(wl); -+ s32 err = 0; -+ -+ if (unlikely(ie->offset > dst_size)) { -+ AP6210_ERR("dst_size is not enough\n"); -+ return -ENOSPC; -+ } -+ memcpy(dst, &ie->buf[0], ie->offset); -+ -+ return err; -+} -+ -+static u32 wl_get_ielen(struct wl_priv *wl) -+{ -+ struct wl_ie *ie = wl_to_ie(wl); -+ -+ return ie->offset; -+} -+ -+static void wl_link_up(struct wl_priv *wl) -+{ -+ wl->link_up = true; -+} -+ -+static void wl_link_down(struct wl_priv *wl) -+{ -+ struct wl_connect_info *conn_info = wl_to_conn(wl); -+ -+ AP6210_DEBUG("In\n"); -+ wl->link_up = false; -+ conn_info->req_ie_len = 0; -+ conn_info->resp_ie_len = 0; -+} -+ -+static unsigned long wl_lock_eq(struct wl_priv *wl) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&wl->eq_lock, flags); -+ return flags; -+} -+ -+static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags) -+{ -+ spin_unlock_irqrestore(&wl->eq_lock, flags); -+} -+ -+static void wl_init_eq_lock(struct wl_priv *wl) -+{ -+ spin_lock_init(&wl->eq_lock); -+} -+ -+static void wl_delay(u32 ms) -+{ -+ if (in_atomic() || (ms < jiffies_to_msecs(1))) { -+ mdelay(ms); -+ } else { -+ msleep(ms); -+ } -+} -+ -+s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ struct ether_addr p2pif_addr; -+ struct ether_addr primary_mac; -+ if (!wl->p2p) -+ return -1; -+ if (!p2p_is_on(wl)) { -+ get_primary_mac(wl, &primary_mac); -+ wl_cfgp2p_generate_bss_mac(&primary_mac, p2pdev_addr, &p2pif_addr); -+ } else { -+ memcpy(p2pdev_addr->octet, -+ wl->p2p->dev_addr.octet, ETHER_ADDR_LEN); -+ } -+ -+ -+ return 0; -+} -+s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) -+{ -+ struct wl_priv *wl; -+ -+ wl = wlcfg_drv_priv; -+ -+ return wl_cfgp2p_set_p2p_noa(wl, net, buf, len); -+} -+ -+s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len) -+{ -+ struct wl_priv *wl; -+ wl = wlcfg_drv_priv; -+ -+ return wl_cfgp2p_get_p2p_noa(wl, net, buf, len); -+} -+ -+s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) -+{ -+ struct wl_priv *wl; -+ wl = wlcfg_drv_priv; -+ -+ return wl_cfgp2p_set_p2p_ps(wl, net, buf, len); -+} -+ -+s32 wl_cfg80211_channel_to_freq(u32 channel) -+{ -+ int freq = 0; -+ -+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) -+ freq = ieee80211_channel_to_frequency(channel); -+#else -+ { -+ u16 band = 0; -+ if (channel <= CH_MAX_2G_CHANNEL) -+ band = IEEE80211_BAND_2GHZ; -+ else -+ band = IEEE80211_BAND_5GHZ; -+ freq = ieee80211_channel_to_frequency(channel, band); -+ } -+#endif -+ return freq; -+} -+ -+s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, -+ enum wl_management_type type) -+{ -+ struct wl_priv *wl; -+ struct net_device *ndev = NULL; -+ struct ether_addr primary_mac; -+ s32 ret = 0; -+ s32 bssidx = 0; -+ s32 pktflag = 0; -+ wl = wlcfg_drv_priv; -+ -+ if (wl_get_drv_status(wl, AP_CREATING, net) || -+ wl_get_drv_status(wl, AP_CREATED, net)) { -+ ndev = net; -+ bssidx = 0; -+ } else if (wl->p2p) { -+ if (net == wl->p2p_net) { -+ net = wl_to_prmry_ndev(wl); -+ } -+ if (!wl->p2p->on) { -+ get_primary_mac(wl, &primary_mac); -+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, -+ &wl->p2p->int_addr); -+ /* In case of p2p_listen command, supplicant send remain_on_channel -+ * without turning on P2P -+ */ -+ -+ p2p_on(wl) = true; -+ ret = wl_cfgp2p_enable_discovery(wl, net, NULL, 0); -+ -+ if (unlikely(ret)) { -+ goto exit; -+ } -+ } -+ if (net != wl_to_prmry_ndev(wl)) { -+ if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) { -+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); -+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION); -+ } -+ } else { -+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); -+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); -+ } -+ } -+ if (ndev != NULL) { -+ switch (type) { -+ case WL_BEACON: -+ pktflag = VNDR_IE_BEACON_FLAG; -+ break; -+ case WL_PROBE_RESP: -+ pktflag = VNDR_IE_PRBRSP_FLAG; -+ break; -+ case WL_ASSOC_RESP: -+ pktflag = VNDR_IE_ASSOCRSP_FLAG; -+ break; -+ } -+ if (pktflag) -+ ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len); -+ } -+exit: -+ return ret; -+} -+ -+static const struct rfkill_ops wl_rfkill_ops = { -+ .set_block = wl_rfkill_set -+}; -+ -+static int wl_rfkill_set(void *data, bool blocked) -+{ -+ struct wl_priv *wl = (struct wl_priv *)data; -+ -+ AP6210_DEBUG("Enter \n"); -+ AP6210_DEBUG("RF %s\n", blocked ? "blocked" : "unblocked"); -+ -+ if (!wl) -+ return -EINVAL; -+ -+ wl->rf_blocked = blocked; -+ -+ return 0; -+} -+ -+static int wl_setup_rfkill(struct wl_priv *wl, bool setup) -+{ -+ s32 err = 0; -+ -+ AP6210_DEBUG("Enter \n"); -+ if (!wl) -+ return -EINVAL; -+ if (setup) { -+ wl->rfkill = rfkill_alloc("brcmfmac-wifi", -+ wl_cfg80211_get_parent_dev(), -+ RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl); -+ -+ if (!wl->rfkill) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ err = rfkill_register(wl->rfkill); -+ -+ if (err) -+ rfkill_destroy(wl->rfkill); -+ } else { -+ if (!wl->rfkill) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ rfkill_unregister(wl->rfkill); -+ rfkill_destroy(wl->rfkill); -+ } -+ -+err_out: -+ return err; -+} -+ -+struct device *wl_cfg80211_get_parent_dev(void) -+{ -+ return cfg80211_parent_dev; -+} -+ -+void wl_cfg80211_set_parent_dev(void *dev) -+{ -+ cfg80211_parent_dev = dev; -+} -+ -+static void wl_cfg80211_clear_parent_dev(void) -+{ -+ cfg80211_parent_dev = NULL; -+} -+ -+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac) -+{ -+ wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL, -+ 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, 0, &wl->ioctl_buf_sync); -+ memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN); -+} -+ -+int wl_cfg80211_do_driver_init(struct net_device *net) -+{ -+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); -+ -+ if (!wl || !wl->wdev) -+ return -EINVAL; -+ -+ if (dhd_do_driver_init(wl->wdev->netdev) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+void wl_cfg80211_enable_trace(u32 level) -+{ -+ wl_dbg_level = level; -+ AP6210_DEBUG("%s: wl_dbg_level = 0x%x\n", __FUNCTION__, wl_dbg_level); -+} -+ -+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ -+ 2, 0)) -+static s32 -+wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, -+ struct net_device *dev, u64 cookie) -+{ -+ /* CFG80211 checks for tx_cancel_wait callback when ATTR_DURATION -+ * is passed with CMD_FRAME. This callback is supposed to cancel -+ * the OFFCHANNEL Wait. Since we are already taking care of that -+ * with the tx_mgmt logic, do nothing here. -+ */ -+ -+ return 0; -+} -+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL >= 3.2.0 */ -+ -+#ifdef WL11U -+bcm_tlv_t * -+wl_cfg80211_find_interworking_ie(u8 *parse, u32 len) -+{ -+ bcm_tlv_t *ie; -+ -+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_INTERWORKING_ID))) { -+ return (bcm_tlv_t *)ie; -+ } -+ return NULL; -+} -+ -+static s32 -+wl_cfg80211_add_iw_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, -+ uint8 ie_id, uint8 *data, uint8 data_len) -+{ -+ s32 err = BCME_OK; -+ s32 buf_len; -+ s32 iecount; -+ ie_setbuf_t *ie_setbuf; -+ -+ if (ie_id != DOT11_MNG_INTERWORKING_ID) -+ return BCME_UNSUPPORTED; -+ -+ /* Validate the pktflag parameter */ -+ if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG | -+ VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG | -+ VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG| -+ VNDR_IE_CUSTOM_FLAG))) { -+ AP6210_ERR("cfg80211 Add IE: Invalid packet flag 0x%x\n", pktflag); -+ return -1; -+ } -+ -+ /* use VNDR_IE_CUSTOM_FLAG flags for none vendor IE . currently fixed value */ -+ pktflag = htod32(pktflag); -+ -+ buf_len = sizeof(ie_setbuf_t) + data_len - 1; -+ ie_setbuf = (ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL); -+ -+ if (!ie_setbuf) { -+ AP6210_ERR("Error allocating buffer for IE\n"); -+ return -ENOMEM; -+ } -+ -+ if (wl->iw_ie_len == data_len && !memcmp(wl->iw_ie, data, data_len)) { -+ AP6210_ERR("Previous IW IE is equals to current IE\n"); -+ return err; -+ } -+ -+ strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1); -+ ie_setbuf->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; -+ -+ /* Buffer contains only 1 IE */ -+ iecount = htod32(1); -+ memcpy((void *)&ie_setbuf->ie_buffer.iecount, &iecount, sizeof(int)); -+ memcpy((void *)&ie_setbuf->ie_buffer.ie_list[0].pktflag, &pktflag, sizeof(uint32)); -+ -+ /* Now, add the IE to the buffer */ -+ ie_setbuf->ie_buffer.ie_list[0].ie_data.id = ie_id; -+ -+ /* if already set with previous values, delete it first */ -+ if (wl->iw_ie_len != 0) { -+ AP6210_DEBUG("Different IW_IE was already set. clear first\n"); -+ -+ ie_setbuf->ie_buffer.ie_list[0].ie_data.len = 0; -+ -+ err = wldev_iovar_setbuf_bsscfg(ndev, "ie", ie_setbuf, buf_len, -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ -+ if (err != BCME_OK) -+ return err; -+ } -+ -+ ie_setbuf->ie_buffer.ie_list[0].ie_data.len = data_len; -+ memcpy((uchar *)&ie_setbuf->ie_buffer.ie_list[0].ie_data.data[0], data, data_len); -+ -+ err = wldev_iovar_setbuf_bsscfg(ndev, "ie", ie_setbuf, buf_len, -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ -+ if (err == BCME_OK) { -+ memcpy(wl->iw_ie, data, data_len); -+ wl->iw_ie_len = data_len; -+ wl->wl11u = TRUE; -+ -+ err = wldev_iovar_setint_bsscfg(ndev, "grat_arp", 1, bssidx); -+ } -+ -+ kfree(ie_setbuf); -+ return err; -+} -+#endif /* WL11U */ -+ -+#ifdef WL_HOST_BAND_MGMT -+s32 -+wl_cfg80211_set_band(struct net_device *ndev, int band) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ int ret = 0; -+ char ioctl_buf[50]; -+ -+ if ((band < WLC_BAND_AUTO) || (band > WLC_BAND_2G)) { -+ AP6210_ERR("Invalid band\n"); -+ return -EINVAL; -+ } -+ -+ if ((ret = wldev_iovar_setbuf(ndev, "roam_band", &band, -+ sizeof(int), ioctl_buf, sizeof(ioctl_buf), NULL)) < 0) { -+ AP6210_ERR("seting roam_band failed code=%d\n", ret); -+ return ret; -+ } -+ -+ AP6210_DEBUG("Setting band to %d\n", band); -+ wl->curr_band = band; -+ -+ return 0; -+} -+#endif /* WL_HOST_BAND_MGMT */ -+ -+#if defined(DHCP_SCAN_SUPPRESS) -+static void wl_cfg80211_scan_supp_timerfunc(ulong data) -+{ -+ struct wl_priv *wl = (struct wl_priv *)data; -+ -+ AP6210_DEBUG("Enter \n"); -+ schedule_work(&wl->wlan_work); -+} -+ -+static void wl_cfg80211_work_handler(struct work_struct *work) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ -+ wl = container_of(work, struct wl_priv, wlan_work); -+ -+ if (!wl) { -+ AP6210_ERR("wl_priv ptr NULL\n"); -+ return; -+ } -+ -+ if (wl->scan_suppressed) { -+ /* There is pending scan_suppress. Clean it */ -+ AP6210_ERR("Clean up from timer after %d msec\n", WL_SCAN_SUPPRESS_TIMEOUT); -+ wl_cfg80211_scan_suppress(wl_to_prmry_ndev(wl), 0); -+ } -+} -+ -+int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress) -+{ -+ struct wl_priv *wl = wlcfg_drv_priv; -+ int ret = 0; -+ -+ if (!dev || !wl || ((suppress != 0) && (suppress != 1))) -+ return -EINVAL; -+ -+ if (suppress == wl->scan_suppressed) { -+ AP6210_DEBUG("No change in scan_suppress state. Ignoring cmd..\n"); -+ return 0; -+ } -+ -+ if (timer_pending(&wl->scan_supp_timer)) -+ del_timer_sync(&wl->scan_supp_timer); -+ -+ if ((ret = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, -+ &suppress, sizeof(int), true)) < 0) { -+ AP6210_ERR("Scan suppress setting failed ret:%d \n", ret); -+ } else { -+ AP6210_DEBUG("Scan suppress %s \n", suppress ? "Enabled" : "Disabled"); -+ wl->scan_suppressed = suppress; -+ } -+ -+ /* If scan_suppress is set, Start a timer to monitor it (just incase) */ -+ if (wl->scan_suppressed) { -+ if (ret) { -+ AP6210_ERR("Retry scan_suppress reset at a later time \n"); -+ mod_timer(&wl->scan_supp_timer, -+ jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_RETRY)); -+ } else { -+ AP6210_DEBUG("Start wlan_timer to clear of scan_suppress \n"); -+ mod_timer(&wl->scan_supp_timer, -+ jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_TIMEOUT)); -+ } -+ } -+ -+ return ret; -+} -+#endif /* DHCP_SCAN_SUPPRESS */ -diff --git a/drivers/net/wireless/ap6210/wl_cfg80211.h b/drivers/net/wireless/ap6210/wl_cfg80211.h -new file mode 100644 -index 0000000..01dd136 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_cfg80211.h -@@ -0,0 +1,791 @@ -+/* -+ * Linux cfg80211 driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfg80211.h 374275 2012-12-12 11:44:18Z $ -+ */ -+ -+#ifndef _wl_cfg80211_h_ -+#define _wl_cfg80211_h_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+struct wl_conf; -+struct wl_iface; -+struct wl_priv; -+struct wl_security; -+struct wl_ibss; -+ -+ -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+ -+#define WL_DBG_NONE 0 -+#define WL_DBG_P2P_ACTION (1 << 5) -+#define WL_DBG_TRACE (1 << 4) -+#define WL_DBG_SCAN (1 << 3) -+#define WL_DBG_DBG (1 << 2) -+#define WL_DBG_INFO (1 << 1) -+#define WL_DBG_ERR (1 << 0) -+ -+/* 0 invalidates all debug messages. default is 1 */ -+#define WL_DBG_LEVEL 0xFF -+ -+#define WL_SCAN_RETRY_MAX 3 -+#define WL_NUM_PMKIDS_MAX MAXPMKID -+#define WL_SCAN_BUF_MAX (1024 * 8) -+#define WL_TLV_INFO_MAX 1500 -+#define WL_SCAN_IE_LEN_MAX 2048 -+#define WL_BSS_INFO_MAX 2048 -+#define WL_ASSOC_INFO_MAX 512 -+#define WL_IOCTL_LEN_MAX 1024 -+#define WL_EXTRA_BUF_MAX 2048 -+#define WL_ISCAN_BUF_MAX 2048 -+#define WL_ISCAN_TIMER_INTERVAL_MS 3000 -+#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1) -+#define WL_AP_MAX 256 -+#define WL_FILE_NAME_MAX 256 -+#define WL_DWELL_TIME 200 -+#define WL_MED_DWELL_TIME 400 -+#define WL_MIN_DWELL_TIME 100 -+#define WL_LONG_DWELL_TIME 1000 -+#define IFACE_MAX_CNT 2 -+#define WL_SCAN_CONNECT_DWELL_TIME_MS 200 -+#define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20 -+#define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320 -+#define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 -+#define WL_AF_TX_MAX_RETRY 5 -+ -+#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */ -+#define WL_CHANNEL_SYNC_RETRY 5 -+#define WL_INVALID -1 -+ -+/* Bring down SCB Timeout to 20secs from 60secs default */ -+#ifndef WL_SCB_TIMEOUT -+#define WL_SCB_TIMEOUT 20 -+#endif -+ -+/* SCAN_SUPPRESS timer values in ms */ -+#define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */ -+#define WL_SCAN_SUPPRESS_RETRY 3000 -+ -+/* driver status */ -+enum wl_status { -+ WL_STATUS_READY = 0, -+ WL_STATUS_SCANNING, -+ WL_STATUS_SCAN_ABORTING, -+ WL_STATUS_CONNECTING, -+ WL_STATUS_CONNECTED, -+ WL_STATUS_DISCONNECTING, -+ WL_STATUS_AP_CREATING, -+ WL_STATUS_AP_CREATED, -+ /* whole sending action frame procedure: -+ * includes a) 'finding common channel' for public action request frame -+ * and b) 'sending af via 'actframe' iovar' -+ */ -+ WL_STATUS_SENDING_ACT_FRM, -+ /* find a peer to go to a common channel before sending public action req frame */ -+ WL_STATUS_FINDING_COMMON_CHANNEL, -+ /* waiting for next af to sync time of supplicant. -+ * it includes SENDING_ACT_FRM and WAITING_NEXT_ACT_FRM_LISTEN -+ */ -+ WL_STATUS_WAITING_NEXT_ACT_FRM, -+#ifdef WL_CFG80211_SYNC_GON -+ /* go to listen state to wait for next af after SENDING_ACT_FRM */ -+ WL_STATUS_WAITING_NEXT_ACT_FRM_LISTEN, -+#endif /* WL_CFG80211_SYNC_GON */ -+ /* it will be set when upper layer requests listen and succeed in setting listen mode. -+ * if set, other scan request can abort current listen state -+ */ -+ WL_STATUS_REMAINING_ON_CHANNEL, -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ /* it's fake listen state to keep current scan state. -+ * it will be set when upper layer requests listen but scan is running. then just run -+ * a expire timer without actual listen state. -+ * if set, other scan request does not need to abort scan. -+ */ -+ WL_STATUS_FAKE_REMAINING_ON_CHANNEL -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+}; -+ -+/* wi-fi mode */ -+enum wl_mode { -+ WL_MODE_BSS, -+ WL_MODE_IBSS, -+ WL_MODE_AP -+}; -+ -+/* driver profile list */ -+enum wl_prof_list { -+ WL_PROF_MODE, -+ WL_PROF_SSID, -+ WL_PROF_SEC, -+ WL_PROF_IBSS, -+ WL_PROF_BAND, -+ WL_PROF_CHAN, -+ WL_PROF_BSSID, -+ WL_PROF_ACT, -+ WL_PROF_BEACONINT, -+ WL_PROF_DTIMPERIOD -+}; -+ -+/* driver iscan state */ -+enum wl_iscan_state { -+ WL_ISCAN_STATE_IDLE, -+ WL_ISCAN_STATE_SCANING -+}; -+ -+/* donlge escan state */ -+enum wl_escan_state { -+ WL_ESCAN_STATE_IDLE, -+ WL_ESCAN_STATE_SCANING -+}; -+/* fw downloading status */ -+enum wl_fw_status { -+ WL_FW_LOADING_DONE, -+ WL_NVRAM_LOADING_DONE -+}; -+ -+enum wl_management_type { -+ WL_BEACON = 0x1, -+ WL_PROBE_RESP = 0x2, -+ WL_ASSOC_RESP = 0x4 -+}; -+/* beacon / probe_response */ -+struct beacon_proberesp { -+ __le64 timestamp; -+ __le16 beacon_int; -+ __le16 capab_info; -+ u8 variable[0]; -+} __attribute__ ((packed)); -+ -+/* driver configuration */ -+struct wl_conf { -+ u32 frag_threshold; -+ u32 rts_threshold; -+ u32 retry_short; -+ u32 retry_long; -+ s32 tx_power; -+ struct ieee80211_channel channel; -+}; -+ -+typedef s32(*EVENT_HANDLER) (struct wl_priv *wl, -+ struct net_device *ndev, const wl_event_msg_t *e, void *data); -+ -+/* bss inform structure for cfg80211 interface */ -+struct wl_cfg80211_bss_info { -+ u16 band; -+ u16 channel; -+ s16 rssi; -+ u16 frame_len; -+ u8 frame_buf[1]; -+}; -+ -+/* basic structure of scan request */ -+struct wl_scan_req { -+ struct wlc_ssid ssid; -+}; -+ -+/* basic structure of information element */ -+struct wl_ie { -+ u16 offset; -+ u8 buf[WL_TLV_INFO_MAX]; -+}; -+ -+/* event queue for cfg80211 main event */ -+struct wl_event_q { -+ struct list_head eq_list; -+ u32 etype; -+ wl_event_msg_t emsg; -+ s8 edata[1]; -+}; -+ -+/* security information with currently associated ap */ -+struct wl_security { -+ u32 wpa_versions; -+ u32 auth_type; -+ u32 cipher_pairwise; -+ u32 cipher_group; -+ u32 wpa_auth; -+ u32 auth_assoc_res_status; -+}; -+ -+/* ibss information for currently joined ibss network */ -+struct wl_ibss { -+ u8 beacon_interval; /* in millisecond */ -+ u8 atim; /* in millisecond */ -+ s8 join_only; -+ u8 band; -+ u8 channel; -+}; -+ -+/* wl driver profile */ -+struct wl_profile { -+ u32 mode; -+ s32 band; -+ u32 channel; -+ struct wlc_ssid ssid; -+ struct wl_security sec; -+ struct wl_ibss ibss; -+ u8 bssid[ETHER_ADDR_LEN]; -+ u16 beacon_interval; -+ u8 dtim_period; -+ bool active; -+}; -+ -+struct net_info { -+ struct net_device *ndev; -+ struct wireless_dev *wdev; -+ struct wl_profile profile; -+ s32 mode; -+ s32 roam_off; -+ unsigned long sme_state; -+ bool pm_restore; -+ bool pm_block; -+ s32 pm; -+ struct list_head list; /* list of all net_info structure */ -+}; -+typedef s32(*ISCAN_HANDLER) (struct wl_priv *wl); -+ -+/* iscan controller */ -+struct wl_iscan_ctrl { -+ struct net_device *dev; -+ struct timer_list timer; -+ u32 timer_ms; -+ u32 timer_on; -+ s32 state; -+ struct task_struct *tsk; -+ struct semaphore sync; -+ ISCAN_HANDLER iscan_handler[WL_SCAN_ERSULTS_LAST]; -+ void *data; -+ s8 ioctl_buf[WLC_IOCTL_SMLEN]; -+ s8 scan_buf[WL_ISCAN_BUF_MAX]; -+}; -+ -+/* association inform */ -+#define MAX_REQ_LINE 1024 -+struct wl_connect_info { -+ u8 req_ie[MAX_REQ_LINE]; -+ s32 req_ie_len; -+ u8 resp_ie[MAX_REQ_LINE]; -+ s32 resp_ie_len; -+}; -+ -+/* firmware /nvram downloading controller */ -+struct wl_fw_ctrl { -+ const struct firmware *fw_entry; -+ unsigned long status; -+ u32 ptr; -+ s8 fw_name[WL_FILE_NAME_MAX]; -+ s8 nvram_name[WL_FILE_NAME_MAX]; -+}; -+ -+/* assoc ie length */ -+struct wl_assoc_ielen { -+ u32 req_len; -+ u32 resp_len; -+}; -+ -+/* wpa2 pmk list */ -+struct wl_pmk_list { -+ pmkid_list_t pmkids; -+ pmkid_t foo[MAXPMKID - 1]; -+}; -+ -+ -+#define ESCAN_BUF_SIZE (64 * 1024) -+ -+struct escan_info { -+ u32 escan_state; -+#if defined(STATIC_WL_PRIV_STRUCT) -+#ifndef CONFIG_DHD_USE_STATIC_BUF -+#error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF -+#endif -+ u8 *escan_buf; -+#else -+ u8 escan_buf[ESCAN_BUF_SIZE]; -+#endif /* STATIC_WL_PRIV_STRUCT */ -+ struct wiphy *wiphy; -+ struct net_device *ndev; -+}; -+ -+struct ap_info { -+/* Structure to hold WPS, WPA IEs for a AP */ -+ u8 probe_res_ie[VNDR_IES_MAX_BUF_LEN]; -+ u8 beacon_ie[VNDR_IES_MAX_BUF_LEN]; -+ u32 probe_res_ie_len; -+ u32 beacon_ie_len; -+ u8 *wpa_ie; -+ u8 *rsn_ie; -+ u8 *wps_ie; -+ bool security_mode; -+}; -+struct btcoex_info { -+ struct timer_list timer; -+ u32 timer_ms; -+ u32 timer_on; -+ u32 ts_dhcp_start; /* ms ts ecord time stats */ -+ u32 ts_dhcp_ok; /* ms ts ecord time stats */ -+ bool dhcp_done; /* flag, indicates that host done with -+ * dhcp before t1/t2 expiration -+ */ -+ s32 bt_state; -+ struct work_struct work; -+ struct net_device *dev; -+}; -+ -+struct sta_info { -+ /* Structure to hold WPS IE for a STA */ -+ u8 probe_req_ie[VNDR_IES_BUF_LEN]; -+ u8 assoc_req_ie[VNDR_IES_BUF_LEN]; -+ u32 probe_req_ie_len; -+ u32 assoc_req_ie_len; -+}; -+ -+struct afx_hdl { -+ wl_af_params_t *pending_tx_act_frm; -+ struct ether_addr tx_dst_addr; -+ struct net_device *dev; -+ struct work_struct work; -+ u32 bssidx; -+ u32 retry; -+ s32 peer_chan; -+ s32 peer_listen_chan; /* search channel: configured by upper layer */ -+ s32 my_listen_chan; /* listen chanel: extract it from prb req or gon req */ -+ bool is_listen; -+ bool ack_recv; -+ bool is_active; -+}; -+ -+struct parsed_ies { -+ wpa_ie_fixed_t *wps_ie; -+ u32 wps_ie_len; -+ wpa_ie_fixed_t *wpa_ie; -+ u32 wpa_ie_len; -+ bcm_tlv_t *wpa2_ie; -+ u32 wpa2_ie_len; -+}; -+ -+ -+#ifdef WL11U -+/* Max length of Interworking element */ -+#define IW_IES_MAX_BUF_LEN 9 -+#endif -+ -+#define MAX_EVENT_BUF_NUM 16 -+typedef struct wl_eventmsg_buf { -+ u16 num; -+ struct { -+ u16 type; -+ bool set; -+ } event [MAX_EVENT_BUF_NUM]; -+} wl_eventmsg_buf_t; -+ -+/* private data of cfg80211 interface */ -+struct wl_priv { -+ struct wireless_dev *wdev; /* representing wl cfg80211 device */ -+ -+ struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */ -+ struct net_device *p2p_net; /* reference to p2p0 interface */ -+ -+ struct wl_conf *conf; -+ struct cfg80211_scan_request *scan_request; /* scan request object */ -+ EVENT_HANDLER evt_handler[WLC_E_LAST]; -+ struct list_head eq_list; /* used for event queue */ -+ struct list_head net_list; /* used for struct net_info */ -+ spinlock_t eq_lock; /* for event queue synchronization */ -+ spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */ -+ struct completion act_frm_scan; -+ struct completion iface_disable; -+ struct completion wait_next_af; -+ struct mutex usr_sync; /* maily for up/down synchronization */ -+ struct wl_scan_results *bss_list; -+ struct wl_scan_results *scan_results; -+ -+ /* scan request object for internal purpose */ -+ struct wl_scan_req *scan_req_int; -+ /* information element object for internal purpose */ -+#if defined(STATIC_WL_PRIV_STRUCT) -+ struct wl_ie *ie; -+#else -+ struct wl_ie ie; -+#endif -+ struct wl_iscan_ctrl *iscan; /* iscan controller */ -+ -+ /* association information container */ -+#if defined(STATIC_WL_PRIV_STRUCT) -+ struct wl_connect_info *conn_info; -+#else -+ struct wl_connect_info conn_info; -+#endif -+ -+ struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ -+ tsk_ctl_t event_tsk; /* task of main event handler thread */ -+ void *pub; -+ u32 iface_cnt; -+ u32 channel; /* current channel */ -+ u32 af_sent_channel; /* channel action frame is sent */ -+ /* next af subtype to cancel the remained dwell time in rx process */ -+ u8 next_af_subtype; -+#ifdef WL_CFG80211_SYNC_GON -+ ulong af_tx_sent_jiffies; -+#endif /* WL_CFG80211_SYNC_GON */ -+ bool iscan_on; /* iscan on/off switch */ -+ bool iscan_kickstart; /* indicate iscan already started */ -+ bool escan_on; /* escan on/off switch */ -+ struct escan_info escan_info; /* escan information */ -+ bool active_scan; /* current scan mode */ -+ bool ibss_starter; /* indicates this sta is ibss starter */ -+ bool link_up; /* link/connection up flag */ -+ -+ /* indicate whether chip to support power save mode */ -+ bool pwr_save; -+ bool roam_on; /* on/off switch for self-roaming */ -+ bool scan_tried; /* indicates if first scan attempted */ -+ bool wlfc_on; -+ bool vsdb_mode; -+ bool roamoff_on_concurrent; -+ u8 *ioctl_buf; /* ioctl buffer */ -+ struct mutex ioctl_buf_sync; -+ u8 *escan_ioctl_buf; -+ u8 *extra_buf; /* maily to grab assoc information */ -+ struct dentry *debugfsdir; -+ struct rfkill *rfkill; -+ bool rf_blocked; -+ struct ieee80211_channel remain_on_chan; -+ enum nl80211_channel_type remain_on_chan_type; -+ u64 send_action_id; -+ u64 last_roc_id; -+ wait_queue_head_t netif_change_event; -+ struct completion send_af_done; -+ struct afx_hdl *afx_hdl; -+ struct ap_info *ap_info; -+ struct sta_info *sta_info; -+ struct p2p_info *p2p; -+ bool p2p_supported; -+ struct btcoex_info *btcoex_info; -+ struct timer_list scan_timeout; /* Timer for catch scan event timeout */ -+ s32(*state_notifier) (struct wl_priv *wl, -+ struct net_info *_net_info, enum wl_status state, bool set); -+ unsigned long interrested_state; -+ wlc_ssid_t hostapd_ssid; -+#ifdef WL11U -+ bool wl11u; -+ u8 iw_ie[IW_IES_MAX_BUF_LEN]; -+ u32 iw_ie_len; -+#endif /* WL11U */ -+ bool sched_scan_running; /* scheduled scan req status */ -+#ifdef WL_SCHED_SCAN -+ struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ -+#endif /* WL_SCHED_SCAN */ -+#ifdef WL_HOST_BAND_MGMT -+ u8 curr_band; -+#endif /* WL_HOST_BAND_MGMT */ -+ bool scan_suppressed; -+ struct timer_list scan_supp_timer; -+ struct work_struct wlan_work; -+ struct mutex event_sync; /* maily for up/down synchronization */ -+}; -+ -+ -+static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss) -+{ -+ return bss = bss ? -+ (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info; -+} -+static inline s32 -+wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev, -+ struct wireless_dev * wdev, s32 mode, bool pm_block) -+{ -+ struct net_info *_net_info; -+ s32 err = 0; -+ if (wl->iface_cnt == IFACE_MAX_CNT) -+ return -ENOMEM; -+ _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL); -+ if (!_net_info) -+ err = -ENOMEM; -+ else { -+ _net_info->mode = mode; -+ _net_info->ndev = ndev; -+ _net_info->wdev = wdev; -+ _net_info->pm_restore = 0; -+ _net_info->pm = 0; -+ _net_info->pm_block = pm_block; -+ _net_info->roam_off = WL_INVALID; -+ wl->iface_cnt++; -+ list_add(&_net_info->list, &wl->net_list); -+ } -+ return err; -+} -+static inline void -+wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) { -+ list_del(&_net_info->list); -+ wl->iface_cnt--; -+ if (_net_info->wdev) { -+ kfree(_net_info->wdev); -+ ndev->ieee80211_ptr = NULL; -+ } -+ kfree(_net_info); -+ } -+ } -+ -+} -+static inline void -+wl_delete_all_netinfo(struct wl_priv *wl) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ list_del(&_net_info->list); -+ if (_net_info->wdev) -+ kfree(_net_info->wdev); -+ kfree(_net_info); -+ } -+ wl->iface_cnt = 0; -+} -+static inline u32 -+wl_get_status_all(struct wl_priv *wl, s32 status) -+ -+{ -+ struct net_info *_net_info, *next; -+ u32 cnt = 0; -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (_net_info->ndev && -+ test_bit(status, &_net_info->sme_state)) -+ cnt++; -+ } -+ return cnt; -+} -+static inline void -+wl_set_status_all(struct wl_priv *wl, s32 status, u32 op) -+{ -+ struct net_info *_net_info, *next; -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ switch (op) { -+ case 1: -+ return; /* set all status is not allowed */ -+ case 2: -+ clear_bit(status, &_net_info->sme_state); -+ if (wl->state_notifier && -+ test_bit(status, &(wl->interrested_state))) -+ wl->state_notifier(wl, _net_info, status, false); -+ break; -+ case 4: -+ return; /* change all status is not allowed */ -+ default: -+ return; /* unknown operation */ -+ } -+ } -+} -+static inline void -+wl_set_status_by_netdev(struct wl_priv *wl, s32 status, -+ struct net_device *ndev, u32 op) -+{ -+ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) { -+ switch (op) { -+ case 1: -+ set_bit(status, &_net_info->sme_state); -+ if (wl->state_notifier && -+ test_bit(status, &(wl->interrested_state))) -+ wl->state_notifier(wl, _net_info, status, true); -+ break; -+ case 2: -+ clear_bit(status, &_net_info->sme_state); -+ if (wl->state_notifier && -+ test_bit(status, &(wl->interrested_state))) -+ wl->state_notifier(wl, _net_info, status, false); -+ break; -+ case 4: -+ change_bit(status, &_net_info->sme_state); -+ break; -+ } -+ } -+ -+ } -+ -+} -+ -+static inline u32 -+wl_get_status_by_netdev(struct wl_priv *wl, s32 status, -+ struct net_device *ndev) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) -+ return test_bit(status, &_net_info->sme_state); -+ } -+ return 0; -+} -+ -+static inline s32 -+wl_get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) -+ return _net_info->mode; -+ } -+ return -1; -+} -+ -+ -+static inline void -+wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev, -+ s32 mode) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) -+ _net_info->mode = mode; -+ } -+} -+static inline struct wl_profile * -+wl_get_profile_by_netdev(struct wl_priv *wl, struct net_device *ndev) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) -+ return &_net_info->profile; -+ } -+ return NULL; -+} -+static inline struct net_info * -+wl_get_netinfo_by_netdev(struct wl_priv *wl, struct net_device *ndev) -+{ -+ struct net_info *_net_info, *next; -+ -+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) { -+ if (ndev && (_net_info->ndev == ndev)) -+ return _net_info; -+ } -+ return NULL; -+} -+#define wl_to_wiphy(w) (w->wdev->wiphy) -+#define wl_to_prmry_ndev(w) (w->wdev->netdev) -+#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) -+#define wl_to_sr(w) (w->scan_req_int) -+#if defined(STATIC_WL_PRIV_STRUCT) -+#define wl_to_ie(w) (w->ie) -+#define wl_to_conn(w) (w->conn_info) -+#else -+#define wl_to_ie(w) (&w->ie) -+#define wl_to_conn(w) (&w->conn_info) -+#endif -+#define iscan_to_wl(i) ((struct wl_priv *)(i->data)) -+#define wl_to_iscan(w) (w->iscan) -+#define wiphy_from_scan(w) (w->escan_info.wiphy) -+#define wl_get_drv_status_all(wl, stat) \ -+ (wl_get_status_all(wl, WL_STATUS_ ## stat)) -+#define wl_get_drv_status(wl, stat, ndev) \ -+ (wl_get_status_by_netdev(wl, WL_STATUS_ ## stat, ndev)) -+#define wl_set_drv_status(wl, stat, ndev) \ -+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 1)) -+#define wl_clr_drv_status(wl, stat, ndev) \ -+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 2)) -+#define wl_clr_drv_status_all(wl, stat) \ -+ (wl_set_status_all(wl, WL_STATUS_ ## stat, 2)) -+#define wl_chg_drv_status(wl, stat, ndev) \ -+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 4)) -+ -+#define for_each_bss(list, bss, __i) \ -+ for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss)) -+ -+#define for_each_ndev(wl, iter, next) \ -+ list_for_each_entry_safe(iter, next, &wl->net_list, list) -+ -+ -+/* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0. -+ * In addtion to that, wpa_version is WPA_VERSION_1 -+ */ -+#define is_wps_conn(_sme) \ -+ ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \ -+ (!_sme->crypto.n_ciphers_pairwise) && \ -+ (!_sme->crypto.cipher_group)) -+extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data); -+extern s32 wl_cfg80211_attach_post(struct net_device *ndev); -+extern void wl_cfg80211_detach(void *para); -+ -+extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, -+ void *data); -+void wl_cfg80211_set_parent_dev(void *dev); -+struct device *wl_cfg80211_get_parent_dev(void); -+ -+extern s32 wl_cfg80211_up(void *para); -+extern s32 wl_cfg80211_down(void *para); -+extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, -+ void* _net_attach); -+extern s32 wl_cfg80211_ifdel_ops(struct net_device *net); -+extern s32 wl_cfg80211_notify_ifdel(void); -+extern s32 wl_cfg80211_is_progress_ifadd(void); -+extern s32 wl_cfg80211_is_progress_ifchange(void); -+extern s32 wl_cfg80211_is_progress_ifadd(void); -+extern s32 wl_cfg80211_notify_ifchange(void); -+extern void wl_cfg80211_dbg_level(u32 level); -+extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); -+extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len); -+extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len); -+extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, -+ enum wl_management_type type); -+extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); -+extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); -+extern s32 wl_mode_to_nl80211_iftype(s32 mode); -+int wl_cfg80211_do_driver_init(struct net_device *net); -+void wl_cfg80211_enable_trace(u32 level); -+extern s32 wl_update_wiphybands(struct wl_priv *wl, bool notify); -+extern s32 wl_cfg80211_if_is_group_owner(void); -+extern chanspec_t wl_ch_host_to_driver(u16 channel); -+extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); -+extern void wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev); -+extern s32 wl_cfg80211_set_band(struct net_device *ndev, int band); -+extern int wl_cfg80211_update_power_mode(struct net_device *dev); -+#if defined(DHCP_SCAN_SUPPRESS) -+extern int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress); -+#endif /* OEM_ANDROID */ -+extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set); -+extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev, -+ struct wl_priv *wl, wl_eventmsg_buf_t *ev); -+#endif /* _wl_cfg80211_h_ */ -diff --git a/drivers/net/wireless/ap6210/wl_cfgp2p.c b/drivers/net/wireless/ap6210/wl_cfgp2p.c -new file mode 100644 -index 0000000..eb7df08 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_cfgp2p.c -@@ -0,0 +1,2393 @@ -+/* -+ * Linux cfgp2p driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfgp2p.c 372668 2012-12-04 14:07:12Z $ -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+static s8 scanparambuf[WLC_IOCTL_SMLEN]; -+static s8 g_mgmt_ie_buf[2048]; -+static bool -+wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type); -+ -+static u32 -+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, -+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd); -+ -+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev); -+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd); -+static int wl_cfgp2p_if_open(struct net_device *net); -+static int wl_cfgp2p_if_stop(struct net_device *net); -+static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, -+ bool notify); -+ -+static const struct net_device_ops wl_cfgp2p_if_ops = { -+ .ndo_open = wl_cfgp2p_if_open, -+ .ndo_stop = wl_cfgp2p_if_stop, -+ .ndo_do_ioctl = wl_cfgp2p_do_ioctl, -+ .ndo_start_xmit = wl_cfgp2p_start_xmit, -+}; -+ -+bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len) -+{ -+ wifi_p2p_pub_act_frame_t *pact_frm; -+ -+ if (frame == NULL) -+ return false; -+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame; -+ if (frame_len < sizeof(wifi_p2p_pub_act_frame_t) -1) -+ return false; -+ -+ if (pact_frm->category == P2P_PUB_AF_CATEGORY && -+ pact_frm->action == P2P_PUB_AF_ACTION && -+ pact_frm->oui_type == P2P_VER && -+ memcmp(pact_frm->oui, P2P_OUI, sizeof(pact_frm->oui)) == 0) { -+ return true; -+ } -+ -+ return false; -+} -+ -+bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len) -+{ -+ wifi_p2p_action_frame_t *act_frm; -+ -+ if (frame == NULL) -+ return false; -+ act_frm = (wifi_p2p_action_frame_t *)frame; -+ if (frame_len < sizeof(wifi_p2p_action_frame_t) -1) -+ return false; -+ -+ if (act_frm->category == P2P_AF_CATEGORY && -+ act_frm->type == P2P_VER && -+ memcmp(act_frm->OUI, P2P_OUI, DOT11_OUI_LEN) == 0) { -+ return true; -+ } -+ -+ return false; -+} -+ -+/* -+* Currently Action frame just pass to P2P interface regardless real dst. -+* but GAS Action can be used for Hotspot2.0 as well -+* Need to distingush that it's for P2P or HS20 -+*/ -+#ifdef WL11U -+#define GAS_RESP_LEN 2 -+#define DOUBLE_TLV_BODY_OFF 4 -+#define GAS_RESP_OFFSET 4 -+#define GAS_CRESP_OFFSET 5 -+ -+bool wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len) -+{ -+ bcm_tlv_t *ie = (bcm_tlv_t *)data; -+ u8 *frame = NULL; -+ u16 id, flen; -+ -+ /* Skipped first ANQP Element, if frame has anqp elemnt */ -+ ie = bcm_parse_tlvs(ie, (int)len, DOT11_MNG_ADVERTISEMENT_ID); -+ -+ if (ie == NULL) -+ return false; -+ -+ frame = (uint8 *)ie + ie->len + TLV_HDR_LEN + GAS_RESP_LEN; -+ id = ((u16) (((frame)[1] << 8) | (frame)[0])); -+ flen = ((u16) (((frame)[3] << 8) | (frame)[2])); -+ -+ /* If the contents match the OUI and the type */ -+ if (flen >= WFA_OUI_LEN + 1 && -+ id == P2PSD_GAS_NQP_INFOID && -+ !bcmp(&frame[DOUBLE_TLV_BODY_OFF], (const uint8*)WFA_OUI, WFA_OUI_LEN) && -+ subtype == frame[DOUBLE_TLV_BODY_OFF+WFA_OUI_LEN]) { -+ return true; -+ } -+ -+ return false; -+} -+#endif /* WL11U */ -+ -+bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len) -+{ -+ -+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm; -+ -+ if (frame == NULL) -+ return false; -+ -+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; -+ if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1) -+ return false; -+ if (sd_act_frm->category != P2PSD_ACTION_CATEGORY) -+ return false; -+ -+#ifdef WL11U -+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP) -+ return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE, -+ (u8 *)sd_act_frm->query_data + GAS_RESP_OFFSET, -+ frame_len); -+ -+ else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP) -+ return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE, -+ (u8 *)sd_act_frm->query_data + GAS_CRESP_OFFSET, -+ frame_len); -+ else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ || -+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ) -+ return true; -+ else -+ return false; -+#else -+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ || -+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP || -+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ || -+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP) -+ return true; -+ else -+ return false; -+#endif /* WLC11U */ -+} -+void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) -+{ -+ wifi_p2p_pub_act_frame_t *pact_frm; -+ wifi_p2p_action_frame_t *act_frm; -+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm; -+ if (!frame || frame_len <= 2) -+ return; -+ -+ if (wl_cfgp2p_is_pub_action(frame, frame_len)) { -+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame; -+ switch (pact_frm->subtype) { -+ case P2P_PAF_GON_REQ: -+ AP6210_DEBUG("%s P2P Group Owner Negotiation Req Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_GON_RSP: -+ AP6210_DEBUG("%s P2P Group Owner Negotiation Rsp Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_GON_CONF: -+ AP6210_DEBUG("%s P2P Group Owner Negotiation Confirm Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_INVITE_REQ: -+ AP6210_DEBUG("%s P2P Invitation Request Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_INVITE_RSP: -+ AP6210_DEBUG("%s P2P Invitation Response Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_DEVDIS_REQ: -+ AP6210_DEBUG("%s P2P Device Discoverability Request Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_DEVDIS_RSP: -+ AP6210_DEBUG("%s P2P Device Discoverability Response Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_PROVDIS_REQ: -+ AP6210_DEBUG("%s P2P Provision Discovery Request Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_PAF_PROVDIS_RSP: -+ AP6210_DEBUG("%s P2P Provision Discovery Response Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ default: -+ AP6210_DEBUG("%s Unknown P2P Public Action Frame\n", -+ (tx)? "TX": "RX"); -+ -+ } -+ -+ } else if (wl_cfgp2p_is_p2p_action(frame, frame_len)) { -+ act_frm = (wifi_p2p_action_frame_t *)frame; -+ switch (act_frm->subtype) { -+ case P2P_AF_NOTICE_OF_ABSENCE: -+ AP6210_DEBUG("%s P2P Notice of Absence Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_AF_PRESENCE_REQ: -+ AP6210_DEBUG("%s P2P Presence Request Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_AF_PRESENCE_RSP: -+ AP6210_DEBUG("%s P2P Presence Response Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ case P2P_AF_GO_DISC_REQ: -+ AP6210_DEBUG("%s P2P Discoverability Request Frame\n", -+ (tx)? "TX": "RX"); -+ break; -+ default: -+ AP6210_DEBUG("%s Unknown P2P Action Frame\n", -+ (tx)? "TX": "RX"); -+ } -+ -+ } else if (wl_cfgp2p_is_gas_action(frame, frame_len)) { -+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; -+ switch (sd_act_frm->action) { -+ case P2PSD_ACTION_ID_GAS_IREQ: -+ AP6210_DEBUG("%s P2P GAS Initial Request\n", -+ (tx)? "TX" : "RX"); -+ break; -+ case P2PSD_ACTION_ID_GAS_IRESP: -+ AP6210_DEBUG("%s P2P GAS Initial Response\n", -+ (tx)? "TX" : "RX"); -+ break; -+ case P2PSD_ACTION_ID_GAS_CREQ: -+ AP6210_DEBUG("%s P2P GAS Comback Request\n", -+ (tx)? "TX" : "RX"); -+ break; -+ case P2PSD_ACTION_ID_GAS_CRESP: -+ AP6210_DEBUG("%s P2P GAS Comback Response\n", -+ (tx)? "TX" : "RX"); -+ break; -+ default: -+ AP6210_DEBUG("%s Unknown P2P GAS Frame\n", -+ (tx)? "TX" : "RX"); -+ } -+ -+ -+ } -+} -+ -+/* -+ * Initialize variables related to P2P -+ * -+ */ -+s32 -+wl_cfgp2p_init_priv(struct wl_priv *wl) -+{ -+ if (!(wl->p2p = kzalloc(sizeof(struct p2p_info), GFP_KERNEL))) { -+ AP6210_ERR("struct p2p_info allocation failed\n"); -+ return -ENOMEM; -+ } -+#define INIT_IE(IE_TYPE, BSS_TYPE) \ -+ do { \ -+ memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \ -+ sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \ -+ wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \ -+ } while (0); -+ -+ INIT_IE(probe_req, P2PAPI_BSSCFG_PRIMARY); -+ INIT_IE(probe_res, P2PAPI_BSSCFG_PRIMARY); -+ INIT_IE(assoc_req, P2PAPI_BSSCFG_PRIMARY); -+ INIT_IE(assoc_res, P2PAPI_BSSCFG_PRIMARY); -+ INIT_IE(beacon, P2PAPI_BSSCFG_PRIMARY); -+ INIT_IE(probe_req, P2PAPI_BSSCFG_DEVICE); -+ INIT_IE(probe_res, P2PAPI_BSSCFG_DEVICE); -+ INIT_IE(assoc_req, P2PAPI_BSSCFG_DEVICE); -+ INIT_IE(assoc_res, P2PAPI_BSSCFG_DEVICE); -+ INIT_IE(beacon, P2PAPI_BSSCFG_DEVICE); -+ INIT_IE(probe_req, P2PAPI_BSSCFG_CONNECTION); -+ INIT_IE(probe_res, P2PAPI_BSSCFG_CONNECTION); -+ INIT_IE(assoc_req, P2PAPI_BSSCFG_CONNECTION); -+ INIT_IE(assoc_res, P2PAPI_BSSCFG_CONNECTION); -+ INIT_IE(beacon, P2PAPI_BSSCFG_CONNECTION); -+#undef INIT_IE -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY) = wl_to_prmry_ndev(wl); -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY) = 0; -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL; -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0; -+ return BCME_OK; -+ -+} -+/* -+ * Deinitialize variables related to P2P -+ * -+ */ -+void -+wl_cfgp2p_deinit_priv(struct wl_priv *wl) -+{ -+ AP6210_DEBUG("In\n"); -+ if (wl->p2p) { -+ kfree(wl->p2p); -+ wl->p2p = NULL; -+ } -+ wl->p2p_supported = 0; -+} -+/* -+ * Set P2P functions into firmware -+ */ -+s32 -+wl_cfgp2p_set_firm_p2p(struct wl_priv *wl) -+{ -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } }; -+ s32 ret = BCME_OK; -+ s32 val = 0; -+ /* Do we have to check whether APSTA is enabled or not ? */ -+ wldev_iovar_getint(ndev, "apsta", &val); -+ if (val == 0) { -+ val = 1; -+ ret = wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true); -+ if (ret < 0) { -+ AP6210_ERR("WLC_DOWN error %d\n", ret); -+ return ret; -+ } -+ wldev_iovar_setint(ndev, "apsta", val); -+ ret = wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), true); -+ if (ret < 0) { -+ AP6210_ERR("WLC_UP error %d\n", ret); -+ return ret; -+ } -+ } -+ -+ /* In case of COB type, firmware has default mac address -+ * After Initializing firmware, we have to set current mac address to -+ * firmware for P2P device address -+ */ -+ ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr, -+ sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync); -+ if (ret && ret != BCME_UNSUPPORTED) { -+ AP6210_ERR("failed to update device address ret %d\n", ret); -+ } -+ return ret; -+} -+ -+/* Create a new P2P BSS. -+ * Parameters: -+ * @mac : MAC address of the BSS to create -+ * @if_type : interface type: WL_P2P_IF_GO or WL_P2P_IF_CLIENT -+ * @chspec : chspec to use if creating a GO BSS. -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, -+ chanspec_t chspec) -+{ -+ wl_p2p_if_t ifreq; -+ s32 err; -+ u32 scb_timeout = WL_SCB_TIMEOUT; -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ -+ ifreq.type = if_type; -+ ifreq.chspec = chspec; -+ memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); -+ -+ AP6210_DEBUG("---wl p2p_ifadd "MACDBG" %s %u\n", -+ MAC2STRDBG(ifreq.addr.octet), -+ (if_type == WL_P2P_IF_GO) ? "go" : "client", -+ (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT); -+ -+ err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ -+ if (unlikely(err < 0)) -+ AP6210_DEBUG("'wl p2p_ifadd' error %d\n", err); -+ else if (if_type == WL_P2P_IF_GO) { -+ err = wldev_ioctl(ndev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); -+ if (unlikely(err < 0)) -+ AP6210_DEBUG("'wl scb_timeout' error %d\n", err); -+ } -+ return err; -+} -+ -+/* Disable a P2P BSS. -+ * Parameters: -+ * @mac : MAC address of the BSS to create -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac) -+{ -+ s32 ret; -+ struct net_device *netdev = wl_to_prmry_ndev(wl); -+ -+ AP6210_DEBUG("------primary idx %d : wl p2p_ifdis "MACDBG"\n", -+ netdev->ifindex, MAC2STRDBG(mac->octet)); -+ ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ if (unlikely(ret < 0)) { -+ AP6210_DEBUG("'wl p2p_ifdis' error %d\n", ret); -+ } -+ return ret; -+} -+ -+/* Delete a P2P BSS. -+ * Parameters: -+ * @mac : MAC address of the BSS to create -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac) -+{ -+ s32 ret; -+ struct net_device *netdev = wl_to_prmry_ndev(wl); -+ -+ AP6210_DEBUG("------primary idx %d : wl p2p_ifdel "MACDBG"\n", -+ netdev->ifindex, MAC2STRDBG(mac->octet)); -+ ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ if (unlikely(ret < 0)) { -+ AP6210_DEBUG("'wl p2p_ifdel' error %d\n", ret); -+ } -+ return ret; -+} -+ -+/* Change a P2P Role. -+ * Parameters: -+ * @mac : MAC address of the BSS to change a role -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, -+ chanspec_t chspec) -+{ -+ wl_p2p_if_t ifreq; -+ s32 err; -+ u32 scb_timeout = WL_SCB_TIMEOUT; -+ -+ struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); -+ -+ ifreq.type = if_type; -+ ifreq.chspec = chspec; -+ memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); -+ -+ AP6210_DEBUG("---wl p2p_ifchange "MACDBG" %s %u" -+ " chanspec 0x%04x\n", MAC2STRDBG(ifreq.addr.octet), -+ (if_type == WL_P2P_IF_GO) ? "go" : "client", -+ (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT, -+ ifreq.chspec); -+ -+ err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ -+ if (unlikely(err < 0)) { -+ AP6210_DEBUG("'wl p2p_ifupd' error %d\n", err); -+ } else if (if_type == WL_P2P_IF_GO) { -+ err = wldev_ioctl(netdev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true); -+ if (unlikely(err < 0)) -+ AP6210_DEBUG("'wl scb_timeout' error %d\n", err); -+ } -+ return err; -+} -+ -+ -+/* Get the index of a created P2P BSS. -+ * Parameters: -+ * @mac : MAC address of the created BSS -+ * @index : output: index of created BSS -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index) -+{ -+ s32 ret; -+ u8 getbuf[64]; -+ struct net_device *dev = wl_to_prmry_ndev(wl); -+ -+ AP6210_DEBUG("---wl p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet)); -+ -+ ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf, -+ sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL); -+ -+ if (ret == 0) { -+ memcpy(index, getbuf, sizeof(s32)); -+ AP6210_DEBUG("---wl p2p_if ==> %d\n", *index); -+ } -+ -+ return ret; -+} -+ -+static s32 -+wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on) -+{ -+ s32 ret = BCME_OK; -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ AP6210_DEBUG("enter\n"); -+ -+ ret = wldev_iovar_setint(ndev, "p2p_disc", on); -+ -+ if (unlikely(ret < 0)) { -+ AP6210_ERR("p2p_disc %d error %d\n", on, ret); -+ } -+ -+ return ret; -+} -+ -+/* Set the WL driver's P2P mode. -+ * Parameters : -+ * @mode : is one of WL_P2P_DISC_ST_{SCAN,LISTEN,SEARCH}. -+ * @channel : the channel to listen -+ * @listen_ms : the time (milli seconds) to wait -+ * @bssidx : bss index for BSSCFG -+ * Returns 0 if success -+ */ -+ -+s32 -+wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms, int bssidx) -+{ -+ wl_p2p_disc_st_t discovery_mode; -+ s32 ret; -+ struct net_device *dev; -+ AP6210_DEBUG("enter\n"); -+ -+ if (unlikely(bssidx == WL_INVALID || bssidx >= P2PAPI_BSSCFG_MAX)) { -+ AP6210_ERR(" %d index out of range\n", bssidx); -+ return -1; -+ } -+ -+ dev = wl_to_p2p_bss_ndev(wl, bssidx); -+ if (unlikely(dev == NULL)) { -+ AP6210_ERR("bssidx %d is not assigned\n", bssidx); -+ return BCME_NOTFOUND; -+ } -+ -+ /* Put the WL driver into P2P Listen Mode to respond to P2P probe reqs */ -+ discovery_mode.state = mode; -+ discovery_mode.chspec = wl_ch_host_to_driver(channel); -+ discovery_mode.dwell = listen_ms; -+ ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode, -+ sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN, -+ bssidx, &wl->ioctl_buf_sync); -+ -+ return ret; -+} -+ -+/* Get the index of the P2P Discovery BSS */ -+static s32 -+wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index) -+{ -+ s32 ret; -+ struct net_device *dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); -+ -+ ret = wldev_iovar_getint(dev, "p2p_dev", index); -+ AP6210_DEBUG("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret); -+ -+ if (unlikely(ret < 0)) { -+ AP6210_ERR("'p2p_dev' error %d\n", ret); -+ return ret; -+ } -+ return ret; -+} -+ -+s32 -+wl_cfgp2p_init_discovery(struct wl_priv *wl) -+{ -+ -+ s32 index = 0; -+ s32 ret = BCME_OK; -+ -+ AP6210_DEBUG("enter\n"); -+ -+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) != 0) { -+ AP6210_ERR("do nothing, already initialized\n"); -+ return ret; -+ } -+ -+ ret = wl_cfgp2p_set_discovery(wl, 1); -+ if (ret < 0) { -+ AP6210_ERR("set discover error\n"); -+ return ret; -+ } -+ /* Enable P2P Discovery in the WL Driver */ -+ ret = wl_cfgp2p_get_disc_idx(wl, &index); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = index; -+ -+ /* Set the initial discovery state to SCAN */ -+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ -+ if (unlikely(ret != 0)) { -+ AP6210_ERR("unable to set WL_P2P_DISC_ST_SCAN\n"); -+ wl_cfgp2p_set_discovery(wl, 0); -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; -+ return 0; -+ } -+ return ret; -+} -+ -+/* Deinitialize P2P Discovery -+ * Parameters : -+ * @wl : wl_private data -+ * Returns 0 if succes -+ */ -+static s32 -+wl_cfgp2p_deinit_discovery(struct wl_priv *wl) -+{ -+ s32 ret = BCME_OK; -+ AP6210_DEBUG("enter\n"); -+ -+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) { -+ AP6210_ERR("do nothing, not initialized\n"); -+ return -1; -+ } -+ /* Set the discovery state to SCAN */ -+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ /* Disable P2P discovery in the WL driver (deletes the discovery BSSCFG) */ -+ ret = wl_cfgp2p_set_discovery(wl, 0); -+ -+ /* Clear our saved WPS and P2P IEs for the discovery BSS. The driver -+ * deleted these IEs when wl_cfgp2p_set_discovery() deleted the discovery -+ * BSS. -+ */ -+ -+ /* Clear the saved bsscfg index of the discovery BSSCFG to indicate we -+ * have no discovery BSS. -+ */ -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = WL_INVALID; -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; -+ -+ return ret; -+ -+} -+/* Enable P2P Discovery -+ * Parameters: -+ * @wl : wl_private data -+ * @ie : probe request ie (WPS IE + P2P IE) -+ * @ie_len : probe request ie length -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, -+ const u8 *ie, u32 ie_len) -+{ -+ s32 ret = BCME_OK; -+ s32 bssidx = (wl_to_prmry_ndev(wl) == dev) ? -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) : wl_cfgp2p_find_idx(wl, dev); -+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) { -+ AP6210_DEBUG(" DISCOVERY is already initialized, we have nothing to do\n"); -+ goto set_ie; -+ } -+ -+ wl_set_p2p_status(wl, DISCOVERY_ON); -+ -+ AP6210_DEBUG("enter\n"); -+ -+ ret = wl_cfgp2p_init_discovery(wl); -+ if (unlikely(ret < 0)) { -+ AP6210_ERR(" init discovery error %d\n", ret); -+ goto exit; -+ } -+ /* Set wsec to any non-zero value in the discovery bsscfg to ensure our -+ * P2P probe responses have the privacy bit set in the 802.11 WPA IE. -+ * Some peer devices may not initiate WPS with us if this bit is not set. -+ */ -+ ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), -+ "wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ if (unlikely(ret < 0)) { -+ AP6210_ERR(" wsec error %d\n", ret); -+ } -+set_ie: -+ if (ie_len) { -+ ret = wl_cfgp2p_set_management_ie(wl, dev, -+ bssidx, -+ VNDR_IE_PRBREQ_FLAG, ie, ie_len); -+ -+ if (unlikely(ret < 0)) { -+ AP6210_ERR("set probreq ie occurs error %d\n", ret); -+ goto exit; -+ } -+ } -+exit: -+ return ret; -+} -+ -+/* Disable P2P Discovery -+ * Parameters: -+ * @wl : wl_private_data -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_disable_discovery(struct wl_priv *wl) -+{ -+ s32 ret = BCME_OK; -+ AP6210_DEBUG(" enter\n"); -+ wl_clr_p2p_status(wl, DISCOVERY_ON); -+ -+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) { -+ AP6210_ERR(" do nothing, not initialized\n"); -+ goto exit; -+ } -+ -+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ -+ if (unlikely(ret < 0)) { -+ -+ AP6210_ERR("unable to set WL_P2P_DISC_ST_SCAN\n"); -+ } -+ /* Do a scan abort to stop the driver's scan engine in case it is still -+ * waiting out an action frame tx dwell time. -+ */ -+ wl_clr_p2p_status(wl, DISCOVERY_ON); -+ ret = wl_cfgp2p_deinit_discovery(wl); -+ -+exit: -+ return ret; -+} -+ -+s32 -+wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, -+ u32 num_chans, u16 *channels, -+ s32 search_state, u16 action, u32 bssidx) -+{ -+ s32 ret = BCME_OK; -+ s32 memsize; -+ s32 eparams_size; -+ u32 i; -+ s8 *memblk; -+ wl_p2p_scan_t *p2p_params; -+ wl_escan_params_t *eparams; -+ wlc_ssid_t ssid; -+ /* Scan parameters */ -+#define P2PAPI_SCAN_NPROBES 1 -+#define P2PAPI_SCAN_DWELL_TIME_MS 80 -+#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40 -+#define P2PAPI_SCAN_HOME_TIME_MS 60 -+#define P2PAPI_SCAN_NPROBS_TIME_MS 30 -+#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100 -+ -+ struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); -+ /* Allocate scan params which need space for 3 channels and 0 ssids */ -+ eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE + -+ OFFSETOF(wl_escan_params_t, params)) + -+ num_chans * sizeof(eparams->params.channel_list[0]); -+ -+ memsize = sizeof(wl_p2p_scan_t) + eparams_size; -+ memblk = scanparambuf; -+ if (memsize > sizeof(scanparambuf)) { -+ AP6210_ERR(" scanpar buf too small (%u > %u)\n", -+ memsize, sizeof(scanparambuf)); -+ return -1; -+ } -+ memset(memblk, 0, memsize); -+ memset(wl->ioctl_buf, 0, WLC_IOCTL_MAXLEN); -+ if (search_state == WL_P2P_DISC_ST_SEARCH) { -+ /* -+ * If we in SEARCH STATE, we don't need to set SSID explictly -+ * because dongle use P2P WILDCARD internally by default -+ */ -+ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx); -+ ssid.SSID_len = htod32(0); -+ -+ } else if (search_state == WL_P2P_DISC_ST_SCAN) { -+ /* SCAN STATE 802.11 SCAN -+ * WFD Supplicant has p2p_find command with (type=progressive, type= full) -+ * So if P2P_find command with type=progressive, -+ * we have to set ssid to P2P WILDCARD because -+ * we just do broadcast scan unless setting SSID -+ */ -+ strncpy(ssid.SSID, WL_P2P_WILDCARD_SSID, sizeof(ssid.SSID) - 1); -+ ssid.SSID[sizeof(ssid.SSID) - 1] = 0; -+ ssid.SSID_len = htod32(WL_P2P_WILDCARD_SSID_LEN); -+ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx); -+ } -+ else { -+ AP6210_ERR(" invalid search state %d\n", search_state); -+ return -1; -+ } -+ -+ -+ /* Fill in the P2P scan structure at the start of the iovar param block */ -+ p2p_params = (wl_p2p_scan_t*) memblk; -+ p2p_params->type = 'E'; -+ /* Fill in the Scan structure that follows the P2P scan structure */ -+ eparams = (wl_escan_params_t*) (p2p_params + 1); -+ eparams->params.bss_type = DOT11_BSSTYPE_ANY; -+ if (active) -+ eparams->params.scan_type = DOT11_SCANTYPE_ACTIVE; -+ else -+ eparams->params.scan_type = DOT11_SCANTYPE_PASSIVE; -+ -+ memcpy(&eparams->params.bssid, ðer_bcast, ETHER_ADDR_LEN); -+ if (ssid.SSID_len) -+ memcpy(&eparams->params.ssid, &ssid, sizeof(wlc_ssid_t)); -+ -+ eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS); -+ -+ /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by -+ * the supplicant -+ */ -+ if ((num_chans == SOCIAL_CHAN_CNT) || (num_chans == SOCIAL_CHAN_CNT + 1)) -+ eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS); -+ else if (num_chans == AF_PEER_SEARCH_CNT) -+ eparams->params.active_time = htod32(P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS); -+ else if (wl_get_drv_status_all(wl, CONNECTED)) -+ eparams->params.active_time = -1; -+ else -+ eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS); -+ eparams->params.nprobes = htod32((eparams->params.active_time / -+ P2PAPI_SCAN_NPROBS_TIME_MS)); -+ -+ /* Override scan params to find a peer for a connection */ -+ if (num_chans == 1) { -+ eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS); -+ eparams->params.nprobes = htod32(eparams->params.active_time / -+ WL_SCAN_JOIN_PROBE_INTERVAL_MS); -+ } -+ -+ if (eparams->params.nprobes <= 0) -+ eparams->params.nprobes = 1; -+ AP6210_DEBUG("nprobes # %d, active_time %d\n", -+ eparams->params.nprobes, eparams->params.active_time); -+ eparams->params.passive_time = htod32(-1); -+ eparams->params.channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) | -+ (num_chans & WL_SCAN_PARAMS_COUNT_MASK)); -+ -+ for (i = 0; i < num_chans; i++) { -+ eparams->params.channel_list[i] = wl_ch_host_to_driver(channels[i]); -+ } -+ eparams->version = htod32(ESCAN_REQ_VERSION); -+ eparams->action = htod16(action); -+ eparams->sync_id = htod16(0x1234); -+ AP6210_DEBUG("SCAN CHANNELS : "); -+ -+ for (i = 0; i < num_chans; i++) { -+ if (i == 0) AP6210_DEBUG("%d", channels[i]); -+ else AP6210_DEBUG(",%d", channels[i]); -+ } -+ -+ AP6210_DEBUG("\n"); -+ -+ ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan", -+ memblk, memsize, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ if (ret == BCME_OK) -+ wl_set_p2p_status(wl, SCANNING); -+ return ret; -+} -+ -+/* search function to reach at common channel to send action frame -+ * Parameters: -+ * @wl : wl_private data -+ * @ndev : net device for bssidx -+ * @bssidx : bssidx for BSS -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, -+ s32 bssidx, s32 channel) -+{ -+ s32 ret = 0; -+ u32 chan_cnt = 0; -+ u16 *default_chan_list = NULL; -+ if (!p2p_is_on(wl) || ndev == NULL || bssidx == WL_INVALID) -+ return -BCME_ERROR; -+ AP6210_DEBUG(" Enter\n"); -+ if (bssidx == P2PAPI_BSSCFG_PRIMARY) -+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); -+ if (channel) -+ chan_cnt = AF_PEER_SEARCH_CNT; -+ else -+ chan_cnt = SOCIAL_CHAN_CNT; -+ default_chan_list = kzalloc(chan_cnt * sizeof(*default_chan_list), GFP_KERNEL); -+ if (default_chan_list == NULL) { -+ AP6210_ERR("channel list allocation failed \n"); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ if (channel) { -+ u32 i; -+ /* insert same channel to the chan_list */ -+ for (i = 0; i < chan_cnt; i++) { -+ default_chan_list[i] = channel; -+ } -+ } else { -+ default_chan_list[0] = SOCIAL_CHAN_1; -+ default_chan_list[1] = SOCIAL_CHAN_2; -+ default_chan_list[2] = SOCIAL_CHAN_3; -+ } -+ ret = wl_cfgp2p_escan(wl, ndev, true, chan_cnt, -+ default_chan_list, WL_P2P_DISC_ST_SEARCH, -+ WL_SCAN_ACTION_START, bssidx); -+ kfree(default_chan_list); -+exit: -+ return ret; -+} -+ -+/* Check whether pointed-to IE looks like WPA. */ -+#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ -+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE) -+/* Check whether pointed-to IE looks like WPS. */ -+#define wl_cfgp2p_is_wps_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ -+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE) -+/* Check whether the given IE looks like WFA P2P IE. */ -+#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ -+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P) -+/* Check whether the given IE looks like WFA WFDisplay IE. */ -+#define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */ -+#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ -+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD) -+ -+static s32 -+wl_cfgp2p_parse_vndr_ies(u8 *parse, u32 len, -+ struct parsed_vndr_ies *vndr_ies) -+{ -+ s32 err = BCME_OK; -+ vndr_ie_t *vndrie; -+ bcm_tlv_t *ie; -+ struct parsed_vndr_ie_info *parsed_info; -+ u32 count = 0; -+ s32 remained_len; -+ -+ remained_len = (s32)len; -+ memset(vndr_ies, 0, sizeof(*vndr_ies)); -+ -+ AP6210_DEBUG("---> len %d\n", len); -+ ie = (bcm_tlv_t *) parse; -+ if (!bcm_valid_tlv(ie, remained_len)) -+ ie = NULL; -+ while (ie) { -+ if (count >= MAX_VNDR_IE_NUMBER) -+ break; -+ if (ie->id == DOT11_MNG_VS_ID) { -+ vndrie = (vndr_ie_t *) ie; -+ /* len should be bigger than OUI length + one data length at least */ -+ if (vndrie->len < (VNDR_IE_MIN_LEN + 1)) { -+ AP6210_ERR("%s: invalid vndr ie. length is too small %d\n", -+ __FUNCTION__, vndrie->len); -+ goto end; -+ } -+ /* if wpa or wme ie, do not add ie */ -+ if (!bcmp(vndrie->oui, (u8*)WPA_OUI, WPA_OUI_LEN) && -+ ((vndrie->data[0] == WPA_OUI_TYPE) || -+ (vndrie->data[0] == WME_OUI_TYPE))) { -+ AP6210_DEBUG("Found WPA/WME oui. Do not add it\n"); -+ goto end; -+ } -+ -+ parsed_info = &vndr_ies->ie_info[count++]; -+ -+ /* save vndr ie information */ -+ parsed_info->ie_ptr = (char *)vndrie; -+ parsed_info->ie_len = (vndrie->len + TLV_HDR_LEN); -+ memcpy(&parsed_info->vndrie, vndrie, sizeof(vndr_ie_t)); -+ -+ vndr_ies->count = count; -+ -+ AP6210_DEBUG("\t ** OUI %02x %02x %02x, type 0x%02x \n", -+ parsed_info->vndrie.oui[0], parsed_info->vndrie.oui[1], -+ parsed_info->vndrie.oui[2], parsed_info->vndrie.data[0]); -+ } -+end: -+ ie = bcm_next_tlv(ie, &remained_len); -+ } -+ return err; -+} -+ -+ -+/* Delete and Set a management vndr ie to firmware -+ * Parameters: -+ * @wl : wl_private data -+ * @ndev : net device for bssidx -+ * @bssidx : bssidx for BSS -+ * @pktflag : packet flag for IE (VNDR_IE_PRBREQ_FLAG,VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG, -+ * VNDR_IE_ASSOCREQ_FLAG) -+ * @ie : VNDR IE (such as P2P IE , WPS IE) -+ * @ie_len : VNDR IE Length -+ * Returns 0 if success. -+ */ -+ -+s32 -+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, -+ s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len) -+{ -+ s32 ret = BCME_OK; -+ u8 *curr_ie_buf = NULL; -+ u8 *mgmt_ie_buf = NULL; -+ u32 mgmt_ie_buf_len = 0; -+ u32 *mgmt_ie_len = 0; -+ u32 del_add_ie_buf_len = 0; -+ u32 total_ie_buf_len = 0; -+ u32 parsed_ie_buf_len = 0; -+ struct parsed_vndr_ies old_vndr_ies; -+ struct parsed_vndr_ies new_vndr_ies; -+ s32 i; -+ u8 *ptr; -+ s32 remained_buf_len; -+ -+#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie) -+#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len) -+ memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf)); -+ curr_ie_buf = g_mgmt_ie_buf; -+ AP6210_DEBUG(" bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); -+ if (wl->p2p != NULL) { -+ switch (pktflag) { -+ case VNDR_IE_PRBREQ_FLAG : -+ mgmt_ie_buf = IE_TYPE(probe_req, bssidx); -+ mgmt_ie_len = &IE_TYPE_LEN(probe_req, bssidx); -+ mgmt_ie_buf_len = sizeof(IE_TYPE(probe_req, bssidx)); -+ break; -+ case VNDR_IE_PRBRSP_FLAG : -+ mgmt_ie_buf = IE_TYPE(probe_res, bssidx); -+ mgmt_ie_len = &IE_TYPE_LEN(probe_res, bssidx); -+ mgmt_ie_buf_len = sizeof(IE_TYPE(probe_res, bssidx)); -+ break; -+ case VNDR_IE_ASSOCREQ_FLAG : -+ mgmt_ie_buf = IE_TYPE(assoc_req, bssidx); -+ mgmt_ie_len = &IE_TYPE_LEN(assoc_req, bssidx); -+ mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_req, bssidx)); -+ break; -+ case VNDR_IE_ASSOCRSP_FLAG : -+ mgmt_ie_buf = IE_TYPE(assoc_res, bssidx); -+ mgmt_ie_len = &IE_TYPE_LEN(assoc_res, bssidx); -+ mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_res, bssidx)); -+ break; -+ case VNDR_IE_BEACON_FLAG : -+ mgmt_ie_buf = IE_TYPE(beacon, bssidx); -+ mgmt_ie_len = &IE_TYPE_LEN(beacon, bssidx); -+ mgmt_ie_buf_len = sizeof(IE_TYPE(beacon, bssidx)); -+ break; -+ default: -+ mgmt_ie_buf = NULL; -+ mgmt_ie_len = NULL; -+ AP6210_ERR("not suitable type\n"); -+ return -1; -+ } -+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { -+ switch (pktflag) { -+ case VNDR_IE_PRBRSP_FLAG : -+ mgmt_ie_buf = wl->ap_info->probe_res_ie; -+ mgmt_ie_len = &wl->ap_info->probe_res_ie_len; -+ mgmt_ie_buf_len = sizeof(wl->ap_info->probe_res_ie); -+ break; -+ case VNDR_IE_BEACON_FLAG : -+ mgmt_ie_buf = wl->ap_info->beacon_ie; -+ mgmt_ie_len = &wl->ap_info->beacon_ie_len; -+ mgmt_ie_buf_len = sizeof(wl->ap_info->beacon_ie); -+ break; -+ default: -+ mgmt_ie_buf = NULL; -+ mgmt_ie_len = NULL; -+ AP6210_ERR("not suitable type\n"); -+ return -1; -+ } -+ bssidx = 0; -+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) { -+ switch (pktflag) { -+ case VNDR_IE_PRBREQ_FLAG : -+ mgmt_ie_buf = wl->sta_info->probe_req_ie; -+ mgmt_ie_len = &wl->sta_info->probe_req_ie_len; -+ mgmt_ie_buf_len = sizeof(wl->sta_info->probe_req_ie); -+ break; -+ case VNDR_IE_ASSOCREQ_FLAG : -+ mgmt_ie_buf = wl->sta_info->assoc_req_ie; -+ mgmt_ie_len = &wl->sta_info->assoc_req_ie_len; -+ mgmt_ie_buf_len = sizeof(wl->sta_info->assoc_req_ie); -+ break; -+ default: -+ mgmt_ie_buf = NULL; -+ mgmt_ie_len = NULL; -+ AP6210_ERR("not suitable type\n"); -+ return -1; -+ } -+ bssidx = 0; -+ } else { -+ AP6210_ERR("not suitable type\n"); -+ return -1; -+ } -+ -+ if (vndr_ie_len > mgmt_ie_buf_len) { -+ AP6210_ERR("extra IE size too big\n"); -+ ret = -ENOMEM; -+ } else { -+ /* parse and save new vndr_ie in curr_ie_buff before comparing it */ -+ if (vndr_ie && vndr_ie_len && curr_ie_buf) { -+ ptr = curr_ie_buf; -+ -+ wl_cfgp2p_parse_vndr_ies((u8*)vndr_ie, -+ vndr_ie_len, &new_vndr_ies); -+ -+ for (i = 0; i < new_vndr_ies.count; i++) { -+ struct parsed_vndr_ie_info *vndrie_info = -+ &new_vndr_ies.ie_info[i]; -+ -+ memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr, -+ vndrie_info->ie_len); -+ parsed_ie_buf_len += vndrie_info->ie_len; -+ } -+ } -+ -+ if (mgmt_ie_buf != NULL) { -+ if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) && -+ (memcmp(mgmt_ie_buf, curr_ie_buf, parsed_ie_buf_len) == 0)) { -+ AP6210_DEBUG("Previous mgmt IE is equals to current IE"); -+ goto exit; -+ } -+ -+ /* parse old vndr_ie */ -+ wl_cfgp2p_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, -+ &old_vndr_ies); -+ -+ /* make a command to delete old ie */ -+ for (i = 0; i < old_vndr_ies.count; i++) { -+ struct parsed_vndr_ie_info *vndrie_info = -+ &old_vndr_ies.ie_info[i]; -+ -+ AP6210_DEBUG("DELETED ID : %d, Len: %d , OUI:%02x:%02x:%02x\n", -+ vndrie_info->vndrie.id, vndrie_info->vndrie.len, -+ vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1], -+ vndrie_info->vndrie.oui[2]); -+ -+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, -+ bssidx, pktflag, vndrie_info->vndrie.oui, -+ vndrie_info->vndrie.id, -+ vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN, -+ vndrie_info->ie_len - VNDR_IE_FIXED_LEN, -+ "del"); -+ -+ curr_ie_buf += del_add_ie_buf_len; -+ total_ie_buf_len += del_add_ie_buf_len; -+ } -+ } -+ -+ *mgmt_ie_len = 0; -+ /* Add if there is any extra IE */ -+ if (mgmt_ie_buf && parsed_ie_buf_len) { -+ ptr = mgmt_ie_buf; -+ -+ remained_buf_len = mgmt_ie_buf_len; -+ -+ /* make a command to add new ie */ -+ for (i = 0; i < new_vndr_ies.count; i++) { -+ struct parsed_vndr_ie_info *vndrie_info = -+ &new_vndr_ies.ie_info[i]; -+ -+ AP6210_DEBUG("ADDED ID : %d, Len: %d(%d), OUI:%02x:%02x:%02x\n", -+ vndrie_info->vndrie.id, vndrie_info->vndrie.len, -+ vndrie_info->ie_len - 2, -+ vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1], -+ vndrie_info->vndrie.oui[2]); -+ -+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, -+ bssidx, pktflag, vndrie_info->vndrie.oui, -+ vndrie_info->vndrie.id, -+ vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN, -+ vndrie_info->ie_len - VNDR_IE_FIXED_LEN, -+ "add"); -+ -+ /* verify remained buf size before copy data */ -+ if (remained_buf_len >= vndrie_info->ie_len) { -+ remained_buf_len -= vndrie_info->ie_len; -+ } else { -+ AP6210_ERR("no space in mgmt_ie_buf: pktflag = %d, " -+ "found vndr ies # = %d(cur %d), remained len %d, " -+ "cur mgmt_ie_len %d, new ie len = %d\n", -+ pktflag, new_vndr_ies.count, i, remained_buf_len, -+ *mgmt_ie_len, vndrie_info->ie_len); -+ break; -+ } -+ -+ /* save the parsed IE in wl struct */ -+ memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr, -+ vndrie_info->ie_len); -+ *mgmt_ie_len += vndrie_info->ie_len; -+ -+ curr_ie_buf += del_add_ie_buf_len; -+ total_ie_buf_len += del_add_ie_buf_len; -+ } -+ } -+ if (total_ie_buf_len) { -+ ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf, -+ total_ie_buf_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN, -+ bssidx, &wl->ioctl_buf_sync); -+ if (ret) -+ AP6210_ERR("vndr ie set error : %d\n", ret); -+ } -+ } -+#undef IE_TYPE -+#undef IE_TYPE_LEN -+exit: -+ return ret; -+} -+ -+/* Clear the manament IE buffer of BSSCFG -+ * Parameters: -+ * @wl : wl_private data -+ * @bssidx : bssidx for BSS -+ * -+ * Returns 0 if success. -+ */ -+s32 -+wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx) -+{ -+ s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG, -+ VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG}; -+ s32 index = -1; -+ struct net_device *ndev = wl_cfgp2p_find_ndev(wl, bssidx); -+#define INIT_IE(IE_TYPE, BSS_TYPE) \ -+ do { \ -+ memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \ -+ sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \ -+ wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \ -+ } while (0); -+ -+ if (bssidx < 0 || ndev == NULL) { -+ AP6210_ERR("invalid %s\n", (bssidx < 0) ? "bssidx" : "ndev"); -+ return BCME_BADARG; -+ } -+ for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) { -+ /* clean up vndr ies in dongle */ -+ wl_cfgp2p_set_management_ie(wl, ndev, bssidx, vndrie_flag[index], NULL, 0); -+ } -+ INIT_IE(probe_req, bssidx); -+ INIT_IE(probe_res, bssidx); -+ INIT_IE(assoc_req, bssidx); -+ INIT_IE(assoc_res, bssidx); -+ INIT_IE(beacon, bssidx); -+ return BCME_OK; -+} -+ -+ -+/* Is any of the tlvs the expected entry? If -+ * not update the tlvs buffer pointer/length. -+ */ -+static bool -+wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type) -+{ -+ /* If the contents match the OUI and the type */ -+ if (ie[TLV_LEN_OFF] >= oui_len + 1 && -+ !bcmp(&ie[TLV_BODY_OFF], oui, oui_len) && -+ type == ie[TLV_BODY_OFF + oui_len]) { -+ return TRUE; -+ } -+ -+ if (tlvs == NULL) -+ return FALSE; -+ /* point to the next ie */ -+ ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN; -+ /* calculate the length of the rest of the buffer */ -+ *tlvs_len -= (int)(ie - *tlvs); -+ /* update the pointer to the start of the buffer */ -+ *tlvs = ie; -+ -+ return FALSE; -+} -+ -+wpa_ie_fixed_t * -+wl_cfgp2p_find_wpaie(u8 *parse, u32 len) -+{ -+ bcm_tlv_t *ie; -+ -+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) { -+ if (wl_cfgp2p_is_wpa_ie((u8*)ie, &parse, &len)) { -+ return (wpa_ie_fixed_t *)ie; -+ } -+ } -+ return NULL; -+} -+ -+wpa_ie_fixed_t * -+wl_cfgp2p_find_wpsie(u8 *parse, u32 len) -+{ -+ bcm_tlv_t *ie; -+ -+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) { -+ if (wl_cfgp2p_is_wps_ie((u8*)ie, &parse, &len)) { -+ return (wpa_ie_fixed_t *)ie; -+ } -+ } -+ return NULL; -+} -+ -+wifi_p2p_ie_t * -+wl_cfgp2p_find_p2pie(u8 *parse, u32 len) -+{ -+ bcm_tlv_t *ie; -+ -+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { -+ if (wl_cfgp2p_is_p2p_ie((uint8*)ie, &parse, &len)) { -+ return (wifi_p2p_ie_t *)ie; -+ } -+ } -+ return NULL; -+} -+ -+wifi_wfd_ie_t * -+wl_cfgp2p_find_wfdie(u8 *parse, u32 len) -+{ -+ bcm_tlv_t *ie; -+ -+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { -+ if (wl_cfgp2p_is_wfd_ie((uint8*)ie, &parse, &len)) { -+ return (wifi_wfd_ie_t *)ie; -+ } -+ } -+ return NULL; -+} -+static u32 -+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, -+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd) -+{ -+ vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */ -+ s32 iecount; -+ u32 data_offset; -+ -+ /* Validate the pktflag parameter */ -+ if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG | -+ VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG | -+ VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG))) { -+ AP6210_ERR("p2pwl_vndr_ie: Invalid packet flag 0x%x\n", pktflag); -+ return -1; -+ } -+ -+ /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ -+ strncpy(hdr.cmd, add_del_cmd, VNDR_IE_CMD_LEN - 1); -+ hdr.cmd[VNDR_IE_CMD_LEN - 1] = '\0'; -+ -+ /* Set the IE count - the buffer contains only 1 IE */ -+ iecount = htod32(1); -+ memcpy((void *)&hdr.vndr_ie_buffer.iecount, &iecount, sizeof(s32)); -+ -+ /* Copy packet flags that indicate which packets will contain this IE */ -+ pktflag = htod32(pktflag); -+ memcpy((void *)&hdr.vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag, -+ sizeof(u32)); -+ -+ /* Add the IE ID to the buffer */ -+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id; -+ -+ /* Add the IE length to the buffer */ -+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = -+ (uint8) VNDR_IE_MIN_LEN + datalen; -+ -+ /* Add the IE OUI to the buffer */ -+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] = oui[0]; -+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[1] = oui[1]; -+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[2] = oui[2]; -+ -+ /* Copy the aligned temporary vndr_ie buffer header to the IE buffer */ -+ memcpy(iebuf, &hdr, sizeof(hdr) - 1); -+ -+ /* Copy the IE data to the IE buffer */ -+ data_offset = -+ (u8*)&hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] - -+ (u8*)&hdr; -+ memcpy(iebuf + data_offset, data, datalen); -+ return data_offset + datalen; -+ -+} -+ -+/* -+ * Search the bssidx based on dev argument -+ * Parameters: -+ * @wl : wl_private data -+ * @ndev : net device to search bssidx -+ * Returns bssidx for ndev -+ */ -+s32 -+wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev) -+{ -+ u32 i; -+ s32 index = -1; -+ -+ if (ndev == NULL) { -+ AP6210_ERR(" ndev is NULL\n"); -+ goto exit; -+ } -+ if (!wl->p2p_supported) { -+ return P2PAPI_BSSCFG_PRIMARY; -+ } -+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { -+ if (ndev == wl_to_p2p_bss_ndev(wl, i)) { -+ index = wl_to_p2p_bss_bssidx(wl, i); -+ break; -+ } -+ } -+ if (index == -1) -+ return P2PAPI_BSSCFG_PRIMARY; -+exit: -+ return index; -+} -+ -+struct net_device * -+wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx) -+{ -+ u32 i; -+ struct net_device *ndev = NULL; -+ if (bssidx < 0) { -+ AP6210_ERR(" bsscfg idx is invalid\n"); -+ goto exit; -+ } -+ -+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { -+ if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) { -+ ndev = wl_to_p2p_bss_ndev(wl, i); -+ break; -+ } -+ } -+ -+exit: -+ return ndev; -+} -+ -+/* -+ * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE -+ */ -+s32 -+wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ s32 ret = BCME_OK; -+ struct net_device *netdev; -+ if (!wl || !wl->p2p) -+ return BCME_ERROR; -+ if (wl->p2p_net == ndev) { -+ netdev = wl_to_prmry_ndev(wl); -+ } else { -+ netdev = ndev; -+ } -+ AP6210_DEBUG(" Enter\n"); -+ if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) { -+ wl_set_p2p_status(wl, LISTEN_EXPIRED); -+ if (timer_pending(&wl->p2p->listen_timer)) { -+ del_timer_sync(&wl->p2p->listen_timer); -+ } -+ -+ if (wl->afx_hdl->is_listen == TRUE && -+ wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { -+ AP6210_DEBUG("Listen DONE for action frame\n"); -+ complete(&wl->act_frm_scan); -+ } -+#ifdef WL_CFG80211_SYNC_GON -+ else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) { -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, netdev); -+ AP6210_DEBUG("Listen DONE and wake up wait_next_af !!(%d)\n", -+ jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies)); -+ -+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) -+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, netdev); -+ -+ complete(&wl->wait_next_af); -+ } -+#endif /* WL_CFG80211_SYNC_GON */ -+ -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) { -+#else -+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL) || -+ wl_get_drv_status_all(wl, FAKE_REMAINING_ON_CHANNEL)) { -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ AP6210_DEBUG("Listen DONE for ramain on channel expired\n"); -+ wl_clr_drv_status(wl, REMAINING_ON_CHANNEL, netdev); -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, netdev); -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ if (ndev && (ndev->ieee80211_ptr != NULL)) { -+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, -+ &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL); -+ } -+ } -+ if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl), -+ WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) { -+ AP6210_ERR(" failed to unset WLC_E_P2P_PROPREQ_MSG\n"); -+ } -+ } else -+ wl_clr_p2p_status(wl, LISTEN_EXPIRED); -+ -+ return ret; -+ -+} -+ -+/* -+ * Timer expire callback function for LISTEN -+ * We can't report cfg80211_remain_on_channel_expired from Timer ISR context, -+ * so lets do it from thread context. -+ */ -+void -+wl_cfgp2p_listen_expired(unsigned long data) -+{ -+ wl_event_msg_t msg; -+ struct wl_priv *wl = (struct wl_priv *) data; -+ AP6210_DEBUG(" Enter\n"); -+ bzero(&msg, sizeof(wl_event_msg_t)); -+ msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE); -+ wl_cfg80211_event(wl->p2p_net ? wl->p2p_net : -+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL); -+} -+/* -+ * Routine for cancelling the P2P LISTEN -+ */ -+static s32 -+wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, -+ bool notify) -+{ -+ AP6210_DEBUG("Enter \n"); -+ /* Irrespective of whether timer is running or not, reset -+ * the LISTEN state. -+ */ -+ if (timer_pending(&wl->p2p->listen_timer)) { -+ del_timer_sync(&wl->p2p->listen_timer); -+ if (notify) -+ if (ndev && ndev->ieee80211_ptr) { -+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, -+ &wl->remain_on_chan, wl->remain_on_chan_type, -+ GFP_KERNEL); -+ } -+ } -+ return 0; -+} -+/* -+ * Do a P2P Listen on the given channel for the given duration. -+ * A listen consists of sitting idle and responding to P2P probe requests -+ * with a P2P probe response. -+ * -+ * This fn assumes dongle p2p device discovery is already enabled. -+ * Parameters : -+ * @wl : wl_private data -+ * @channel : channel to listen -+ * @duration_ms : the time (milli seconds) to wait -+ */ -+s32 -+wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms) -+{ -+#define EXTRA_DELAY_TIME 100 -+ s32 ret = BCME_OK; -+ struct timer_list *_timer; -+ s32 extra_delay; -+ struct net_device *netdev = wl_to_prmry_ndev(wl); -+ -+ AP6210_DEBUG(" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms); -+ if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) { -+ -+ AP6210_ERR(" Discovery is not set, so we have noting to do\n"); -+ -+ ret = BCME_NOTREADY; -+ goto exit; -+ } -+ if (timer_pending(&wl->p2p->listen_timer)) { -+ AP6210_DEBUG("previous LISTEN is not completed yet\n"); -+ goto exit; -+ -+ } -+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ else -+ wl_clr_p2p_status(wl, LISTEN_EXPIRED); -+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) { -+ AP6210_ERR(" failed to set WLC_E_P2P_PROPREQ_MSG\n"); -+ } -+ -+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ _timer = &wl->p2p->listen_timer; -+ -+ /* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle , -+ * otherwise we will wait up to duration_ms + 100ms + duration / 10 -+ */ -+ if (ret == BCME_OK) { -+ extra_delay = EXTRA_DELAY_TIME + (duration_ms / 10); -+ } else { -+ /* if failed to set listen, it doesn't need to wait whole duration. */ -+ duration_ms = 100 + duration_ms / 20; -+ extra_delay = 0; -+ } -+ -+ INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, extra_delay); -+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -+ wl_clr_p2p_status(wl, LISTEN_EXPIRED); -+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ -+ -+#undef EXTRA_DELAY_TIME -+exit: -+ return ret; -+} -+ -+ -+s32 -+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable) -+{ -+ s32 ret = BCME_OK; -+ AP6210_DEBUG(" Enter\n"); -+ if (!wl_get_p2p_status(wl, DISCOVERY_ON)) { -+ -+ AP6210_DEBUG(" do nothing, discovery is off\n"); -+ return ret; -+ } -+ if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) { -+ AP6210_DEBUG("already : %d\n", enable); -+ return ret; -+ } -+ -+ wl_chg_p2p_status(wl, SEARCH_ENABLED); -+ /* When disabling Search, reset the WL driver's p2p discovery state to -+ * WL_P2P_DISC_ST_SCAN. -+ */ -+ if (!enable) { -+ wl_clr_p2p_status(wl, SCANNING); -+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, -+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); -+ } -+ -+ return ret; -+} -+ -+/* -+ * Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE -+ */ -+s32 -+wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data) -+{ -+ s32 ret = BCME_OK; -+ u32 event_type = ntoh32(e->event_type); -+ u32 status = ntoh32(e->status); -+ AP6210_DEBUG(" Enter\n"); -+ if (event_type == WLC_E_ACTION_FRAME_COMPLETE) { -+ -+ AP6210_DEBUG(" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status); -+ if (status == WLC_E_STATUS_SUCCESS) { -+ wl_set_p2p_status(wl, ACTION_TX_COMPLETED); -+ AP6210_DEBUG("WLC_E_ACTION_FRAME_COMPLETE : ACK\n"); -+ } -+ else { -+ wl_set_p2p_status(wl, ACTION_TX_NOACK); -+ AP6210_DEBUG("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"); -+ wl_stop_wait_next_action_frame(wl, ndev); -+ } -+ } else { -+ AP6210_DEBUG(" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received," -+ "status : %d\n", status); -+ -+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) -+ complete(&wl->send_af_done); -+ } -+ return ret; -+} -+/* Send an action frame immediately without doing channel synchronization. -+ * -+ * This function does not wait for a completion event before returning. -+ * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action -+ * frame is transmitted. -+ * The WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE event will be received when an -+ * 802.11 ack has been received for the sent action frame. -+ */ -+s32 -+wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev, -+ wl_af_params_t *af_params, s32 bssidx) -+{ -+ s32 ret = BCME_OK; -+ s32 timeout = 0; -+ wl_eventmsg_buf_t buf; -+ -+ -+ AP6210_DEBUG("\n"); -+ AP6210_DEBUG("channel : %u , dwell time : %u\n", -+ af_params->channel, af_params->dwell_time); -+ -+ wl_clr_p2p_status(wl, ACTION_TX_COMPLETED); -+ wl_clr_p2p_status(wl, ACTION_TX_NOACK); -+ -+ bzero(&buf, sizeof(wl_eventmsg_buf_t)); -+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, true); -+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, true); -+ if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) -+ return ret; -+ -+#define MAX_WAIT_TIME 2000 -+ if (bssidx == P2PAPI_BSSCFG_PRIMARY) -+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); -+ -+ wl->af_sent_channel = af_params->channel; -+#ifdef WL_CFG80211_SYNC_GON -+ wl->af_tx_sent_jiffies = jiffies; -+#endif /* WL_CFG80211_SYNC_GON */ -+ -+ ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); -+ -+ if (ret < 0) { -+ AP6210_ERR(" sending action frame is failed\n"); -+ goto exit; -+ } -+ -+ timeout = wait_for_completion_timeout(&wl->send_af_done, msecs_to_jiffies(MAX_WAIT_TIME)); -+ -+ if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) { -+ AP6210_DEBUG("tx action frame operation is completed\n"); -+ ret = BCME_OK; -+ } else { -+ ret = BCME_ERROR; -+ AP6210_DEBUG("tx action frame operation is failed\n"); -+ } -+ /* clear status bit for action tx */ -+ wl_clr_p2p_status(wl, ACTION_TX_COMPLETED); -+ wl_clr_p2p_status(wl, ACTION_TX_NOACK); -+ -+exit: -+ AP6210_DEBUG(" via act frame iovar : status = %d\n", ret); -+ -+ bzero(&buf, sizeof(wl_eventmsg_buf_t)); -+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, false); -+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, false); -+ if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) -+ AP6210_ERR("TX frame events revert back failed \n"); -+ -+#undef MAX_WAIT_TIME -+ return ret; -+} -+ -+/* Generate our P2P Device Address and P2P Interface Address from our primary -+ * MAC address. -+ */ -+void -+wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, -+ struct ether_addr *out_dev_addr, struct ether_addr *out_int_addr) -+{ -+ memset(out_dev_addr, 0, sizeof(*out_dev_addr)); -+ memset(out_int_addr, 0, sizeof(*out_int_addr)); -+ -+ /* Generate the P2P Device Address. This consists of the device's -+ * primary MAC address with the locally administered bit set. -+ */ -+ memcpy(out_dev_addr, primary_addr, sizeof(*out_dev_addr)); -+ out_dev_addr->octet[0] |= 0x02; -+ -+ /* Generate the P2P Interface Address. If the discovery and connection -+ * BSSCFGs need to simultaneously co-exist, then this address must be -+ * different from the P2P Device Address. -+ */ -+ memcpy(out_int_addr, out_dev_addr, sizeof(*out_int_addr)); -+ out_int_addr->octet[4] ^= 0x80; -+ -+} -+ -+/* P2P IF Address change to Virtual Interface MAC Address */ -+void -+wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id) -+{ -+ wifi_p2p_ie_t *ie = (wifi_p2p_ie_t*) buf; -+ u16 len = ie->len; -+ u8 *subel; -+ u8 subelt_id; -+ u16 subelt_len; -+ AP6210_DEBUG(" Enter\n"); -+ -+ /* Point subel to the P2P IE's subelt field. -+ * Subtract the preceding fields (id, len, OUI, oui_type) from the length. -+ */ -+ subel = ie->subelts; -+ len -= 4; /* exclude OUI + OUI_TYPE */ -+ -+ while (len >= 3) { -+ /* attribute id */ -+ subelt_id = *subel; -+ subel += 1; -+ len -= 1; -+ -+ /* 2-byte little endian */ -+ subelt_len = *subel++; -+ subelt_len |= *subel++ << 8; -+ -+ len -= 2; -+ len -= subelt_len; /* for the remaining subelt fields */ -+ -+ if (subelt_id == element_id) { -+ if (subelt_id == P2P_SEID_INTINTADDR) { -+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); -+ AP6210_DEBUG("Intended P2P Interface Address ATTR FOUND\n"); -+ } else if (subelt_id == P2P_SEID_DEV_ID) { -+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); -+ AP6210_DEBUG("Device ID ATTR FOUND\n"); -+ } else if (subelt_id == P2P_SEID_DEV_INFO) { -+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); -+ AP6210_DEBUG("Device INFO ATTR FOUND\n"); -+ } else if (subelt_id == P2P_SEID_GROUP_ID) { -+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN); -+ AP6210_DEBUG("GROUP ID ATTR FOUND\n"); -+ } return; -+ } else { -+ AP6210_DEBUG("OTHER id : %d\n", subelt_id); -+ } -+ subel += subelt_len; -+ } -+} -+/* -+ * Check if a BSS is up. -+ * This is a common implementation called by most OSL implementations of -+ * p2posl_bss_isup(). DO NOT call this function directly from the -+ * common code -- call p2posl_bss_isup() instead to allow the OSL to -+ * override the common implementation if necessary. -+ */ -+bool -+wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx) -+{ -+ s32 result, val; -+ bool isup = false; -+ s8 getbuf[64]; -+ -+ /* Check if the BSS is up */ -+ *(int*)getbuf = -1; -+ result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx, -+ sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0, NULL); -+ if (result != 0) { -+ AP6210_ERR("'wl bss -C %d' failed: %d\n", bsscfg_idx, result); -+ AP6210_ERR("NOTE: this ioctl error is normal " -+ "when the BSS has not been created yet.\n"); -+ } else { -+ val = *(int*)getbuf; -+ val = dtoh32(val); -+ AP6210_DEBUG("---wl bss -C %d ==> %d\n", bsscfg_idx, val); -+ isup = (val ? TRUE : FALSE); -+ } -+ return isup; -+} -+ -+ -+/* Bring up or down a BSS */ -+s32 -+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up) -+{ -+ s32 ret = BCME_OK; -+ s32 val = up ? 1 : 0; -+ -+ struct { -+ s32 cfg; -+ s32 val; -+ } bss_setbuf; -+ -+ bss_setbuf.cfg = htod32(bsscfg_idx); -+ bss_setbuf.val = htod32(val); -+ AP6210_DEBUG("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down"); -+ ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ -+ if (ret != 0) { -+ AP6210_ERR("'bss %d' failed with %d\n", up, ret); -+ } -+ -+ return ret; -+} -+ -+/* Check if 'p2p' is supported in the driver */ -+s32 -+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev) -+{ -+ s32 ret = BCME_OK; -+ s32 p2p_supported = 0; -+ ret = wldev_iovar_getint(ndev, "p2p", -+ &p2p_supported); -+ if (ret < 0) { -+ AP6210_ERR("wl p2p error %d\n", ret); -+ return 0; -+ } -+ if (p2p_supported == 1) { -+ AP6210_DEBUG("p2p is supported\n"); -+ } else { -+ AP6210_DEBUG("p2p is unsupported\n"); -+ p2p_supported = 0; -+ } -+ return p2p_supported; -+} -+ -+/* Cleanup P2P resources */ -+s32 -+wl_cfgp2p_down(struct wl_priv *wl) -+{ -+ s32 i = 0, index = -1; -+ wl_cfgp2p_cancel_listen(wl, -+ wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE); -+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { -+ index = wl_to_p2p_bss_bssidx(wl, i); -+ if (index != WL_INVALID) -+ wl_cfgp2p_clear_management_ie(wl, index); -+ } -+ wl_cfgp2p_deinit_priv(wl); -+ return 0; -+} -+ -+s32 -+wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) -+{ -+ s32 ret = -1; -+ int count, start, duration; -+ wl_p2p_sched_t dongle_noa; -+ -+ AP6210_DEBUG(" Enter\n"); -+ -+ memset(&dongle_noa, 0, sizeof(dongle_noa)); -+ -+ if (wl->p2p && wl->p2p->vif_created) { -+ -+ wl->p2p->noa.desc[0].start = 0; -+ -+ sscanf(buf, "%10d %10d %10d", &count, &start, &duration); -+ AP6210_DEBUG("set_p2p_noa count %d start %d duration %d\n", -+ count, start, duration); -+ if (count != -1) -+ wl->p2p->noa.desc[0].count = count; -+ -+ /* supplicant gives interval as start */ -+ if (start != -1) -+ wl->p2p->noa.desc[0].interval = start; -+ -+ if (duration != -1) -+ wl->p2p->noa.desc[0].duration = duration; -+ -+ if (wl->p2p->noa.desc[0].count != 255) { -+ wl->p2p->noa.desc[0].start = 200; -+ dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS; -+ dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF; -+ dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS; -+ } -+ else { -+ /* Continuous NoA interval. */ -+ dongle_noa.action = WL_P2P_SCHED_ACTION_NONE; -+ dongle_noa.type = WL_P2P_SCHED_TYPE_ABS; -+ if ((wl->p2p->noa.desc[0].interval == 102) || -+ (wl->p2p->noa.desc[0].interval == 100)) { -+ wl->p2p->noa.desc[0].start = 100 - -+ wl->p2p->noa.desc[0].duration; -+ dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT; -+ } -+ else { -+ dongle_noa.option = WL_P2P_SCHED_OPTION_NORMAL; -+ } -+ } -+ /* Put the noa descriptor in dongle format for dongle */ -+ dongle_noa.desc[0].count = htod32(wl->p2p->noa.desc[0].count); -+ if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) { -+ dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start); -+ dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration); -+ } -+ else { -+ dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start*1000); -+ dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration*1000); -+ } -+ dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000); -+ -+ ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), -+ "p2p_noa", &dongle_noa, sizeof(dongle_noa), wl->ioctl_buf, WLC_IOCTL_MAXLEN, -+ &wl->ioctl_buf_sync); -+ -+ if (ret < 0) { -+ AP6210_ERR("fw set p2p_noa failed %d\n", ret); -+ } -+ } -+ else { -+ AP6210_ERR("ERROR: set_noa in non-p2p mode\n"); -+ } -+ return ret; -+} -+s32 -+wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len) -+{ -+ -+ wifi_p2p_noa_desc_t *noa_desc; -+ int len = 0, i; -+ char _buf[200]; -+ -+ AP6210_DEBUG(" Enter\n"); -+ buf[0] = '\0'; -+ if (wl->p2p && wl->p2p->vif_created) { -+ if (wl->p2p->noa.desc[0].count || wl->p2p->ops.ops) { -+ _buf[0] = 1; /* noa index */ -+ _buf[1] = (wl->p2p->ops.ops ? 0x80: 0) | -+ (wl->p2p->ops.ctw & 0x7f); /* ops + ctw */ -+ len += 2; -+ if (wl->p2p->noa.desc[0].count) { -+ noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len]; -+ noa_desc->cnt_type = wl->p2p->noa.desc[0].count; -+ noa_desc->duration = wl->p2p->noa.desc[0].duration; -+ noa_desc->interval = wl->p2p->noa.desc[0].interval; -+ noa_desc->start = wl->p2p->noa.desc[0].start; -+ len += sizeof(wifi_p2p_noa_desc_t); -+ } -+ if (buf_len <= len * 2) { -+ AP6210_ERR("ERROR: buf_len %d in not enough for" -+ "returning noa in string format\n", buf_len); -+ return -1; -+ } -+ /* We have to convert the buffer data into ASCII strings */ -+ for (i = 0; i < len; i++) { -+ snprintf(buf, 3, "%02x", _buf[i]); -+ buf += 2; -+ } -+ buf[i*2] = '\0'; -+ } -+ } -+ else { -+ AP6210_ERR("ERROR: get_noa in non-p2p mode\n"); -+ return -1; -+ } -+ return len * 2; -+} -+s32 -+wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) -+{ -+ int ps, ctw; -+ int ret = -1; -+ s32 legacy_ps; -+ -+ AP6210_DEBUG(" Enter\n"); -+ if (wl->p2p && wl->p2p->vif_created) { -+ sscanf(buf, "%10d %10d %10d", &legacy_ps, &ps, &ctw); -+ AP6210_DEBUG(" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw); -+ if (ctw != -1) { -+ wl->p2p->ops.ctw = ctw; -+ ret = 0; -+ } -+ if (ps != -1) { -+ wl->p2p->ops.ops = ps; -+ ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), -+ "p2p_ops", &wl->p2p->ops, sizeof(wl->p2p->ops), -+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); -+ if (ret < 0) { -+ AP6210_ERR("fw set p2p_ops failed %d\n", ret); -+ } -+ } -+ -+ if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) { -+#if !defined(SUPPORT_PM2_ONLY) -+ if (legacy_ps == PM_MAX) -+ legacy_ps = PM_FAST; -+#endif /* SUPPORT_PM2_ONLY */ -+ -+ ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), -+ WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true); -+ if (unlikely(ret)) { -+ AP6210_ERR("error (%d)\n", ret); -+ } else { -+ wl_cfg80211_update_power_mode(ndev); -+ } -+ } -+ else -+ AP6210_ERR("ilegal setting\n"); -+ } -+ else { -+ AP6210_ERR("ERROR: set_p2p_ps in non-p2p mode\n"); -+ ret = -1; -+ } -+ return ret; -+} -+ -+u8 * -+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id) -+{ -+ wifi_p2p_ie_t *ie = NULL; -+ u16 len = 0; -+ u8 *subel; -+ u8 subelt_id; -+ u16 subelt_len; -+ -+ if (!buf) { -+ AP6210_ERR("P2P IE not present"); -+ return 0; -+ } -+ -+ ie = (wifi_p2p_ie_t*) buf; -+ len = ie->len; -+ -+ /* Point subel to the P2P IE's subelt field. -+ * Subtract the preceding fields (id, len, OUI, oui_type) from the length. -+ */ -+ subel = ie->subelts; -+ len -= 4; /* exclude OUI + OUI_TYPE */ -+ -+ while (len >= 3) { -+ /* attribute id */ -+ subelt_id = *subel; -+ subel += 1; -+ len -= 1; -+ -+ /* 2-byte little endian */ -+ subelt_len = *subel++; -+ subelt_len |= *subel++ << 8; -+ -+ len -= 2; -+ len -= subelt_len; /* for the remaining subelt fields */ -+ -+ if (subelt_id == element_id) { -+ /* This will point to start of subelement attrib after -+ * attribute id & len -+ */ -+ return subel; -+ } -+ -+ /* Go to next subelement */ -+ subel += subelt_len; -+ } -+ -+ /* Not Found */ -+ return NULL; -+} -+ -+#define P2P_GROUP_CAPAB_GO_BIT 0x01 -+u8 * -+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length) -+{ -+ wifi_p2p_ie_t * p2p_ie = NULL; -+ u8 *capability = NULL; -+ bool p2p_go = 0; -+ u8 *ptr = NULL; -+ -+ if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) { -+ AP6210_ERR("P2P IE not found"); -+ return NULL; -+ } -+ -+ if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) { -+ AP6210_ERR("P2P Capability attribute not found"); -+ return NULL; -+ } -+ -+ /* Check Group capability for Group Owner bit */ -+ p2p_go = capability[1] & P2P_GROUP_CAPAB_GO_BIT; -+ if (!p2p_go) { -+ return bi->BSSID.octet; -+ } -+ -+ /* In probe responses, DEVICE INFO attribute will be present */ -+ if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) { -+ /* If DEVICE_INFO is not found, this might be a beacon frame. -+ * check for DEVICE_ID in the beacon frame. -+ */ -+ ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID); -+ } -+ -+ if (!ptr) -+ AP6210_ERR(" Both DEVICE_ID & DEVICE_INFO attribute not present in P2P IE "); -+ -+ return ptr; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -+static void -+wl_cfgp2p_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -+{ -+ snprintf(info->driver, sizeof(info->driver), "p2p"); -+ snprintf(info->version, sizeof(info->version), "%lu", (unsigned long)(0)); -+} -+ -+struct ethtool_ops cfgp2p_ethtool_ops = { -+ .get_drvinfo = wl_cfgp2p_ethtool_get_drvinfo -+}; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -+ -+s32 -+wl_cfgp2p_register_ndev(struct wl_priv *wl) -+{ -+ int ret = 0; -+ struct net_device* net = NULL; -+ struct wireless_dev *wdev = NULL; -+ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 }; -+ -+ if (wl->p2p_net) { -+ AP6210_ERR("p2p_net defined already.\n"); -+ return -EINVAL; -+ } -+ -+ /* Allocate etherdev, including space for private structure */ -+ if (!(net = alloc_etherdev(sizeof(struct wl_priv *)))) { -+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); -+ if (unlikely(!wdev)) { -+ AP6210_ERR("Could not allocate wireless device\n"); -+ free_netdev(net); -+ return -ENOMEM; -+ } -+ -+ strncpy(net->name, "p2p%d", sizeof(net->name) - 1); -+ net->name[IFNAMSIZ - 1] = '\0'; -+ -+ /* Copy the reference to wl_priv */ -+ memcpy((void *)netdev_priv(net), &wl, sizeof(struct wl_priv *)); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) -+ ASSERT(!net->open); -+ net->do_ioctl = wl_cfgp2p_do_ioctl; -+ net->hard_start_xmit = wl_cfgp2p_start_xmit; -+ net->open = wl_cfgp2p_if_open; -+ net->stop = wl_cfgp2p_if_stop; -+#else -+ ASSERT(!net->netdev_ops); -+ net->netdev_ops = &wl_cfgp2p_if_ops; -+#endif -+ -+ /* Register with a dummy MAC addr */ -+ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); -+ -+ wdev->wiphy = wl->wdev->wiphy; -+ -+ wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); -+ -+ net->ieee80211_ptr = wdev; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) -+ net->ethtool_ops = &cfgp2p_ethtool_ops; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -+ -+ SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy)); -+ -+ /* Associate p2p0 network interface with new wdev */ -+ wdev->netdev = net; -+ -+ ret = register_netdev(net); -+ if (ret) { -+ AP6210_ERR(" register_netdevice failed (%d)\n", ret); -+ free_netdev(net); -+ kfree(wdev); -+ return -ENODEV; -+ } -+ -+ /* store p2p net ptr for further reference. Note that iflist won't have this -+ * entry as there corresponding firmware interface is a "Hidden" interface. -+ */ -+ wl->p2p_wdev = wdev; -+ wl->p2p_net = net; -+ -+ AP6210_DEBUG("%s: P2P Interface Registered\n", net->name); -+ -+ return ret; -+} -+ -+s32 -+wl_cfgp2p_unregister_ndev(struct wl_priv *wl) -+{ -+ -+ if (!wl || !wl->p2p_net) { -+ AP6210_ERR("Invalid Ptr\n"); -+ return -EINVAL; -+ } -+ -+ unregister_netdev(wl->p2p_net); -+ free_netdev(wl->p2p_net); -+ -+ return 0; -+} -+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) -+{ -+ if (skb) -+ { -+ AP6210_DEBUG("(%s) is not used for data operations.Droping the packet.\n", -+ ndev->name); -+ dev_kfree_skb_any(skb); -+ } -+ -+ return 0; -+} -+ -+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd) -+{ -+ int ret = 0; -+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); -+ struct net_device *ndev = wl_to_prmry_ndev(wl); -+ -+ /* There is no ifidx corresponding to p2p0 in our firmware. So we should -+ * not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs. -+ * For Android PRIV CMD handling map it to primary I/F -+ */ -+ if (cmd == SIOCDEVPRIVATE+1) { -+ ret = wl_android_priv_cmd(ndev, ifr, cmd); -+ -+ } else { -+ AP6210_ERR("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n", -+ __FUNCTION__, cmd); -+ return -1; -+ } -+ -+ return ret; -+} -+ -+static int wl_cfgp2p_if_open(struct net_device *net) -+{ -+ extern struct wl_priv *wlcfg_drv_priv; -+ struct wireless_dev *wdev = net->ieee80211_ptr; -+ struct wl_priv *wl = NULL; -+ wl = wlcfg_drv_priv; -+ if (!wdev || !wl || !wl->p2p) -+ return -EINVAL; -+ AP6210_DEBUG("Enter\n"); -+ /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now, -+ * do it here. This will make sure that in concurrent mode, supplicant -+ * is not dependent on a particular order of interface initialization. -+ * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N -+ * -iwlan0. -+ */ -+ wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT) -+ | BIT(NL80211_IFTYPE_P2P_GO)); -+ wl_cfg80211_do_driver_init(net); -+ -+ return 0; -+} -+ -+static int wl_cfgp2p_if_stop(struct net_device *net) -+{ -+ extern struct wl_priv *wlcfg_drv_priv; -+ struct wl_priv *wl = NULL; -+ unsigned long flags; -+ struct wireless_dev *wdev = net->ieee80211_ptr; -+ int clear_flag = 0; -+ if (!wdev) -+ return -EINVAL; -+ -+ AP6210_DEBUG("Enter\n"); -+ wl = wlcfg_drv_priv; -+ if (!wl) -+ return -EINVAL; -+ spin_lock_irqsave(&wl->cfgdrv_lock, flags); -+ if (wl->scan_request && wl->scan_request->dev == net) { -+ cfg80211_scan_done(wl->scan_request, true); -+ wl->scan_request = NULL; -+ clear_flag = 1; -+ } -+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); -+ if (clear_flag) -+ wl_clr_drv_status(wl, SCANNING, net); -+ wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes) -+ & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| -+ BIT(NL80211_IFTYPE_P2P_GO))); -+ return 0; -+} -+ -+bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops) -+{ -+ return (if_ops == &wl_cfgp2p_if_ops); -+} -diff --git a/drivers/net/wireless/ap6210/wl_cfgp2p.h b/drivers/net/wireless/ap6210/wl_cfgp2p.h -new file mode 100644 -index 0000000..d3552d6 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_cfgp2p.h -@@ -0,0 +1,311 @@ -+/* -+ * Linux cfgp2p driver -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_cfgp2p.h 368091 2012-11-12 04:28:31Z $ -+ */ -+#ifndef _wl_cfgp2p_h_ -+#define _wl_cfgp2p_h_ -+#include -+#include -+ -+struct wl_priv; -+extern u32 wl_dbg_level; -+ -+typedef struct wifi_p2p_ie wifi_wfd_ie_t; -+/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not -+ * confuse this with a bsscfg index. This value is an index into the -+ * saved_ie[] array of structures which in turn contains a bsscfg index field. -+ */ -+typedef enum { -+ P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */ -+ P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */ -+ P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */ -+ P2PAPI_BSSCFG_MAX -+} p2p_bsscfg_type_t; -+ -+/* vendor ies max buffer length for probe response or beacon */ -+#define VNDR_IES_MAX_BUF_LEN 1400 -+/* normal vendor ies buffer length */ -+#define VNDR_IES_BUF_LEN 512 -+ -+/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */ -+struct p2p_saved_ie { -+ u8 p2p_probe_req_ie[VNDR_IES_BUF_LEN]; -+ u8 p2p_probe_res_ie[VNDR_IES_MAX_BUF_LEN]; -+ u8 p2p_assoc_req_ie[VNDR_IES_BUF_LEN]; -+ u8 p2p_assoc_res_ie[VNDR_IES_BUF_LEN]; -+ u8 p2p_beacon_ie[VNDR_IES_MAX_BUF_LEN]; -+ u32 p2p_probe_req_ie_len; -+ u32 p2p_probe_res_ie_len; -+ u32 p2p_assoc_req_ie_len; -+ u32 p2p_assoc_res_ie_len; -+ u32 p2p_beacon_ie_len; -+}; -+ -+struct p2p_bss { -+ u32 bssidx; -+ struct net_device *dev; -+ struct p2p_saved_ie saved_ie; -+ void *private_data; -+}; -+ -+struct p2p_info { -+ bool on; /* p2p on/off switch */ -+ bool scan; -+ bool vif_created; -+ s8 vir_ifname[IFNAMSIZ]; -+ unsigned long status; -+ struct ether_addr dev_addr; -+ struct ether_addr int_addr; -+ struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX]; -+ struct timer_list listen_timer; -+ wl_p2p_sched_t noa; -+ wl_p2p_ops_t ops; -+ wlc_ssid_t ssid; -+}; -+ -+#define MAX_VNDR_IE_NUMBER 5 -+ -+struct parsed_vndr_ie_info { -+ char *ie_ptr; -+ u32 ie_len; /* total length including id & length field */ -+ vndr_ie_t vndrie; -+}; -+ -+struct parsed_vndr_ies { -+ u32 count; -+ struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER]; -+}; -+ -+/* dongle status */ -+enum wl_cfgp2p_status { -+ WLP2P_STATUS_DISCOVERY_ON = 0, -+ WLP2P_STATUS_SEARCH_ENABLED, -+ WLP2P_STATUS_IF_ADD, -+ WLP2P_STATUS_IF_DEL, -+ WLP2P_STATUS_IF_DELETING, -+ WLP2P_STATUS_IF_CHANGING, -+ WLP2P_STATUS_IF_CHANGED, -+ WLP2P_STATUS_LISTEN_EXPIRED, -+ WLP2P_STATUS_ACTION_TX_COMPLETED, -+ WLP2P_STATUS_ACTION_TX_NOACK, -+ WLP2P_STATUS_SCANNING, -+ WLP2P_STATUS_GO_NEG_PHASE, -+ WLP2P_STATUS_DISC_IN_PROGRESS -+}; -+ -+ -+#define wl_to_p2p_bss_ndev(wl, type) ((wl)->p2p->bss_idx[type].dev) -+#define wl_to_p2p_bss_bssidx(wl, type) ((wl)->p2p->bss_idx[type].bssidx) -+#define wl_to_p2p_bss_saved_ie(wl, type) ((wl)->p2p->bss_idx[type].saved_ie) -+#define wl_to_p2p_bss_private(wl, type) ((wl)->p2p->bss_idx[type].private_data) -+#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type]) -+#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \ -+ &(wl)->p2p->status)) -+#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : set_bit(WLP2P_STATUS_ ## stat, \ -+ &(wl)->p2p->status)) -+#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : clear_bit(WLP2P_STATUS_ ## stat, \ -+ &(wl)->p2p->status)) -+#define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \ -+ &(wl)->p2p->status)) -+#define p2p_on(wl) ((wl)->p2p->on) -+#define p2p_scan(wl) ((wl)->p2p->scan) -+#define p2p_is_on(wl) ((wl)->p2p && (wl)->p2p->on) -+ -+/* dword align allocation */ -+#define WLC_IOCTL_MAXLEN 8192 -+ -+#define INIT_TIMER(timer, func, duration, extra_delay) \ -+ do { \ -+ init_timer(timer); \ -+ timer->function = func; \ -+ timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \ -+ timer->data = (unsigned long) wl; \ -+ add_timer(timer); \ -+ } while (0); -+extern void -+wl_cfgp2p_listen_expired(unsigned long data); -+extern bool -+wl_cfgp2p_is_pub_action(void *frame, u32 frame_len); -+extern bool -+wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len); -+extern bool -+wl_cfgp2p_is_gas_action(void *frame, u32 frame_len); -+extern void -+wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len); -+extern s32 -+wl_cfgp2p_init_priv(struct wl_priv *wl); -+extern void -+wl_cfgp2p_deinit_priv(struct wl_priv *wl); -+extern s32 -+wl_cfgp2p_set_firm_p2p(struct wl_priv *wl); -+extern s32 -+wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, -+ u32 channel, u16 listen_ms, int bssidx); -+extern s32 -+wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, -+ chanspec_t chspec); -+extern s32 -+wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac); -+extern s32 -+wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac); -+extern s32 -+wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, chanspec_t chspec); -+ -+extern s32 -+wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index); -+ -+extern s32 -+wl_cfgp2p_init_discovery(struct wl_priv *wl); -+extern s32 -+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len); -+extern s32 -+wl_cfgp2p_disable_discovery(struct wl_priv *wl); -+extern s32 -+wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans, -+ u16 *channels, -+ s32 search_state, u16 action, u32 bssidx); -+ -+extern s32 -+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, -+ s32 bssidx, s32 channel); -+ -+extern wpa_ie_fixed_t * -+wl_cfgp2p_find_wpaie(u8 *parse, u32 len); -+ -+extern wpa_ie_fixed_t * -+wl_cfgp2p_find_wpsie(u8 *parse, u32 len); -+ -+extern wifi_p2p_ie_t * -+wl_cfgp2p_find_p2pie(u8 *parse, u32 len); -+ -+extern wifi_wfd_ie_t * -+wl_cfgp2p_find_wfdie(u8 *parse, u32 len); -+extern s32 -+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, -+ s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len); -+extern s32 -+wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx); -+ -+extern s32 -+wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev); -+extern struct net_device * -+wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx); -+ -+ -+extern s32 -+wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+extern s32 -+wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms); -+ -+extern s32 -+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable); -+ -+extern s32 -+wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, -+ const wl_event_msg_t *e, void *data); -+extern s32 -+wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev, -+ wl_af_params_t *af_params, s32 bssidx); -+ -+extern void -+wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, struct ether_addr *out_dev_addr, -+ struct ether_addr *out_int_addr); -+ -+extern void -+wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id); -+extern bool -+wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx); -+ -+extern s32 -+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up); -+ -+ -+extern s32 -+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev); -+ -+extern s32 -+wl_cfgp2p_down(struct wl_priv *wl); -+ -+extern s32 -+wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); -+ -+extern s32 -+wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); -+ -+extern s32 -+wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len); -+ -+extern u8 * -+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id); -+ -+extern u8 * -+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length); -+ -+extern s32 -+wl_cfgp2p_register_ndev(struct wl_priv *wl); -+ -+extern s32 -+wl_cfgp2p_unregister_ndev(struct wl_priv *wl); -+ -+extern bool -+wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops); -+ -+/* WiFi Direct */ -+#define SOCIAL_CHAN_1 1 -+#define SOCIAL_CHAN_2 6 -+#define SOCIAL_CHAN_3 11 -+#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \ -+ (channel == SOCIAL_CHAN_2) || \ -+ (channel == SOCIAL_CHAN_3)) -+#define SOCIAL_CHAN_CNT 3 -+#define AF_PEER_SEARCH_CNT 2 -+#define WL_P2P_WILDCARD_SSID "DIRECT-" -+#define WL_P2P_WILDCARD_SSID_LEN 7 -+#define WL_P2P_INTERFACE_PREFIX "p2p" -+#define WL_P2P_TEMP_CHAN 11 -+ -+/* If the provision discovery is for JOIN operations, -+ * then we need not do an internal scan to find GO. -+ */ -+#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) \ -+ (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL) -+ -+#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \ -+ ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \ -+ (frame->action == P2PSD_ACTION_ID_GAS_CREQ))) -+#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) \ -+ (wl_cfgp2p_is_pub_action(frame, len) && \ -+ ((frame->subtype == P2P_PAF_GON_REQ) || \ -+ (frame->subtype == P2P_PAF_INVITE_REQ) || \ -+ ((frame->subtype == P2P_PAF_PROVDIS_REQ) && \ -+ IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len)))) -+#define IS_P2P_PUB_ACT_RSP_SUBTYPE(subtype) ((subtype == P2P_PAF_GON_RSP) || \ -+ ((subtype == P2P_PAF_GON_CONF) || \ -+ (subtype == P2P_PAF_INVITE_RSP) || \ -+ (subtype == P2P_PAF_PROVDIS_RSP))) -+#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3)) -+#define IS_P2P_SSID(ssid, len) (!memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) && \ -+ (len == WL_P2P_WILDCARD_SSID_LEN)) -+#endif /* _wl_cfgp2p_h_ */ -diff --git a/drivers/net/wireless/ap6210/wl_iw.c b/drivers/net/wireless/ap6210/wl_iw.c -new file mode 100644 -index 0000000..8e067f4 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_iw.c -@@ -0,0 +1,3622 @@ -+/* -+ * Linux Wireless Extensions support -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_iw.c 352251 2012-08-22 06:08:38Z $ -+ */ -+ -+#if defined(USE_IW) -+#define LINUX_PORT -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+typedef const struct si_pub si_t; -+#include -+ -+ -+#include -+ -+#include -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+#include -+#endif -+#if defined(SOFTAP) -+struct net_device *ap_net_dev = NULL; -+tsk_ctl_t ap_eth_ctl; /* apsta AP netdev waiter thread */ -+#endif /* SOFTAP */ -+ -+extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, -+ uint32 reason, char* stringBuf, uint buflen); -+ -+uint iw_msg_level = WL_ERROR_VAL; -+ -+#define MAX_WLIW_IOCTL_LEN 1024 -+ -+/* IOCTL swapping mode for Big Endian host with Little Endian dongle. Default to off */ -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+ -+extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -+extern int dhd_wait_pend8021x(struct net_device *dev); -+ -+#if WIRELESS_EXT < 19 -+#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -+#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -+#endif /* WIRELESS_EXT < 19 */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#define DAEMONIZE(a) daemonize(a); \ -+ allow_signal(SIGKILL); \ -+ allow_signal(SIGTERM); -+#else /* Linux 2.4 (w/o preemption patch) */ -+#define RAISE_RX_SOFTIRQ() \ -+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -+#define DAEMONIZE(a) daemonize(); \ -+ do { if (a) \ -+ strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ -+ } while (0); -+#endif /* LINUX_VERSION_CODE */ -+ -+#define ISCAN_STATE_IDLE 0 -+#define ISCAN_STATE_SCANING 1 -+ -+/* the buf lengh can be WLC_IOCTL_MAXLEN (8K) to reduce iteration */ -+#define WLC_IW_ISCAN_MAXLEN 2048 -+typedef struct iscan_buf { -+ struct iscan_buf * next; -+ char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -+} iscan_buf_t; -+ -+typedef struct iscan_info { -+ struct net_device *dev; -+ struct timer_list timer; -+ uint32 timer_ms; -+ uint32 timer_on; -+ int iscan_state; -+ iscan_buf_t * list_hdr; -+ iscan_buf_t * list_cur; -+ -+ /* Thread to work on iscan */ -+ long sysioc_pid; -+ struct semaphore sysioc_sem; -+ struct completion sysioc_exited; -+ -+ -+ char ioctlbuf[WLC_IOCTL_SMLEN]; -+} iscan_info_t; -+iscan_info_t *g_iscan = NULL; -+static void wl_iw_timerfunc(ulong data); -+static void wl_iw_set_event_mask(struct net_device *dev); -+static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -+ -+/* priv_link becomes netdev->priv and is the link between netdev and wlif struct */ -+typedef struct priv_link { -+ wl_iw_t *wliw; -+} priv_link_t; -+ -+/* dev to priv_link */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -+#define WL_DEV_LINK(dev) (priv_link_t*)(dev->priv) -+#else -+#define WL_DEV_LINK(dev) (priv_link_t*)netdev_priv(dev) -+#endif -+ -+/* dev to wl_iw_t */ -+#define IW_DEV_IF(dev) ((wl_iw_t*)(WL_DEV_LINK(dev))->wliw) -+ -+static void swap_key_from_BE( -+ wl_wsec_key_t *key -+) -+{ -+ key->index = htod32(key->index); -+ key->len = htod32(key->len); -+ key->algo = htod32(key->algo); -+ key->flags = htod32(key->flags); -+ key->rxiv.hi = htod32(key->rxiv.hi); -+ key->rxiv.lo = htod16(key->rxiv.lo); -+ key->iv_initialized = htod32(key->iv_initialized); -+} -+ -+static void swap_key_to_BE( -+ wl_wsec_key_t *key -+) -+{ -+ key->index = dtoh32(key->index); -+ key->len = dtoh32(key->len); -+ key->algo = dtoh32(key->algo); -+ key->flags = dtoh32(key->flags); -+ key->rxiv.hi = dtoh32(key->rxiv.hi); -+ key->rxiv.lo = dtoh16(key->rxiv.lo); -+ key->iv_initialized = dtoh32(key->iv_initialized); -+} -+ -+static int -+dev_wlc_ioctl( -+ struct net_device *dev, -+ int cmd, -+ void *arg, -+ int len -+) -+{ -+ struct ifreq ifr; -+ wl_ioctl_t ioc; -+ mm_segment_t fs; -+ int ret; -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = cmd; -+ ioc.buf = arg; -+ ioc.len = len; -+ -+ strcpy(ifr.ifr_name, dev->name); -+ ifr.ifr_data = (caddr_t) &ioc; -+ -+#ifndef LINUX_HYBRID -+ /* Causes an extraneous 'up'. If specific ioctls are failing due -+ to device down, then we can investigate those ioctls. -+ */ -+ dev_open(dev); -+#endif -+ -+ fs = get_fs(); -+ set_fs(get_ds()); -+#if defined(WL_USE_NETDEV_OPS) -+ ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -+#else -+ ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -+#endif -+ set_fs(fs); -+ -+ return ret; -+} -+ -+/* -+set named driver variable to int value and return error indication -+calling example: dev_wlc_intvar_set(dev, "arate", rate) -+*/ -+ -+static int -+dev_wlc_intvar_set( -+ struct net_device *dev, -+ char *name, -+ int val) -+{ -+ char buf[WLC_IOCTL_SMLEN]; -+ uint len; -+ -+ val = htod32(val); -+ len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); -+ ASSERT(len); -+ -+ return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len)); -+} -+ -+static int -+dev_iw_iovar_setbuf( -+ struct net_device *dev, -+ char *iovar, -+ void *param, -+ int paramlen, -+ void *bufptr, -+ int buflen) -+{ -+ int iolen; -+ -+ iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); -+ ASSERT(iolen); -+ BCM_REFERENCE(iolen); -+ -+ return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen)); -+} -+ -+static int -+dev_iw_iovar_getbuf( -+ struct net_device *dev, -+ char *iovar, -+ void *param, -+ int paramlen, -+ void *bufptr, -+ int buflen) -+{ -+ int iolen; -+ -+ iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); -+ ASSERT(iolen); -+ BCM_REFERENCE(iolen); -+ -+ return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen)); -+} -+ -+#if WIRELESS_EXT > 17 -+static int -+dev_wlc_bufvar_set( -+ struct net_device *dev, -+ char *name, -+ char *buf, int len) -+{ -+ char *ioctlbuf; -+ uint buflen; -+ int error; -+ -+ ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL); -+ if (!ioctlbuf) -+ return -ENOMEM; -+ -+ buflen = bcm_mkiovar(name, buf, len, ioctlbuf, MAX_WLIW_IOCTL_LEN); -+ ASSERT(buflen); -+ error = dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen); -+ -+ kfree(ioctlbuf); -+ return error; -+} -+#endif /* WIRELESS_EXT > 17 */ -+ -+/* -+get named driver variable to int value and return error indication -+calling example: dev_wlc_bufvar_get(dev, "arate", &rate) -+*/ -+ -+static int -+dev_wlc_bufvar_get( -+ struct net_device *dev, -+ char *name, -+ char *buf, int buflen) -+{ -+ char *ioctlbuf; -+ int error; -+ -+ uint len; -+ -+ ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL); -+ if (!ioctlbuf) -+ return -ENOMEM; -+ len = bcm_mkiovar(name, NULL, 0, ioctlbuf, MAX_WLIW_IOCTL_LEN); -+ ASSERT(len); -+ BCM_REFERENCE(len); -+ error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); -+ if (!error) -+ bcopy(ioctlbuf, buf, buflen); -+ -+ kfree(ioctlbuf); -+ return (error); -+} -+ -+/* -+get named driver variable to int value and return error indication -+calling example: dev_wlc_intvar_get(dev, "arate", &rate) -+*/ -+ -+static int -+dev_wlc_intvar_get( -+ struct net_device *dev, -+ char *name, -+ int *retval) -+{ -+ union { -+ char buf[WLC_IOCTL_SMLEN]; -+ int val; -+ } var; -+ int error; -+ -+ uint len; -+ uint data_null; -+ -+ len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); -+ ASSERT(len); -+ error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); -+ -+ *retval = dtoh32(var.val); -+ -+ return (error); -+} -+ -+/* Maintain backward compatibility */ -+#if WIRELESS_EXT < 13 -+struct iw_request_info -+{ -+ __u16 cmd; /* Wireless Extension command */ -+ __u16 flags; /* More to come ;-) */ -+}; -+ -+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, -+ void *wrqu, char *extra); -+#endif /* WIRELESS_EXT < 13 */ -+ -+#if WIRELESS_EXT > 12 -+static int -+wl_iw_set_leddc( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *wrqu, -+ char *extra -+) -+{ -+ int dc = *(int *)extra; -+ int error; -+ -+ error = dev_wlc_intvar_set(dev, "leddc", dc); -+ return error; -+} -+ -+static int -+wl_iw_set_vlanmode( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *wrqu, -+ char *extra -+) -+{ -+ int mode = *(int *)extra; -+ int error; -+ -+ mode = htod32(mode); -+ error = dev_wlc_intvar_set(dev, "vlan_mode", mode); -+ return error; -+} -+ -+static int -+wl_iw_set_pm( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *wrqu, -+ char *extra -+) -+{ -+ int pm = *(int *)extra; -+ int error; -+ -+ pm = htod32(pm); -+ error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); -+ return error; -+} -+#endif /* WIRELESS_EXT > 12 */ -+ -+int -+wl_iw_send_priv_event( -+ struct net_device *dev, -+ char *flag -+) -+{ -+ union iwreq_data wrqu; -+ char extra[IW_CUSTOM_MAX + 1]; -+ int cmd; -+ -+ cmd = IWEVCUSTOM; -+ memset(&wrqu, 0, sizeof(wrqu)); -+ if (strlen(flag) > sizeof(extra)) -+ return -1; -+ -+ strcpy(extra, flag); -+ wrqu.data.length = strlen(extra); -+ wireless_send_event(dev, cmd, &wrqu, extra); -+ AP6210_DEBUG("Send IWEVCUSTOM Event as %s\n", extra); -+ -+ return 0; -+} -+ -+static int -+wl_iw_config_commit( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ void *zwrq, -+ char *extra -+) -+{ -+ wlc_ssid_t ssid; -+ int error; -+ struct sockaddr bssid; -+ -+ AP6210_DEBUG("%s: SIOCSIWCOMMIT\n", dev->name); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) -+ return error; -+ -+ ssid.SSID_len = dtoh32(ssid.SSID_len); -+ -+ if (!ssid.SSID_len) -+ return 0; -+ -+ bzero(&bssid, sizeof(struct sockaddr)); -+ if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { -+ AP6210_ERR("%s: WLC_REASSOC failed (%d)\n", __FUNCTION__, error); -+ return error; -+ } -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_name( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *cwrq, -+ char *extra -+) -+{ -+ int phytype, err; -+ uint band[3]; -+ char cap[5]; -+ -+ AP6210_DEBUG("%s: SIOCGIWNAME\n", dev->name); -+ -+ cap[0] = 0; -+ if ((err = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))) < 0) -+ goto done; -+ if ((err = dev_wlc_ioctl(dev, WLC_GET_BANDLIST, band, sizeof(band))) < 0) -+ goto done; -+ -+ band[0] = dtoh32(band[0]); -+ switch (phytype) { -+ case WLC_PHY_TYPE_A: -+ strcpy(cap, "a"); -+ break; -+ case WLC_PHY_TYPE_B: -+ strcpy(cap, "b"); -+ break; -+ case WLC_PHY_TYPE_LP: -+ case WLC_PHY_TYPE_G: -+ if (band[0] >= 2) -+ strcpy(cap, "abg"); -+ else -+ strcpy(cap, "bg"); -+ break; -+ case WLC_PHY_TYPE_N: -+ if (band[0] >= 2) -+ strcpy(cap, "abgn"); -+ else -+ strcpy(cap, "bgn"); -+ break; -+ } -+done: -+ snprintf(cwrq->name, IFNAMSIZ, "IEEE 802.11%s", cap); -+ return 0; -+} -+ -+static int -+wl_iw_set_freq( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_freq *fwrq, -+ char *extra -+) -+{ -+ int error, chan; -+ uint sf = 0; -+ -+ AP6210_DEBUG("%s: SIOCSIWFREQ\n", dev->name); -+ -+ /* Setting by channel number */ -+ if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { -+ chan = fwrq->m; -+ } -+ -+ /* Setting by frequency */ -+ else { -+ /* Convert to MHz as best we can */ -+ if (fwrq->e >= 6) { -+ fwrq->e -= 6; -+ while (fwrq->e--) -+ fwrq->m *= 10; -+ } else if (fwrq->e < 6) { -+ while (fwrq->e++ < 6) -+ fwrq->m /= 10; -+ } -+ /* handle 4.9GHz frequencies as Japan 4 GHz based channelization */ -+ if (fwrq->m > 4000 && fwrq->m < 5000) -+ sf = WF_CHAN_FACTOR_4_G; /* start factor for 4 GHz */ -+ -+ chan = wf_mhz2channel(fwrq->m, sf); -+ } -+ chan = htod32(chan); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) -+ return error; -+ -+ /* -EINPROGRESS: Call commit handler */ -+ return -EINPROGRESS; -+} -+ -+static int -+wl_iw_get_freq( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_freq *fwrq, -+ char *extra -+) -+{ -+ channel_info_t ci; -+ int error; -+ -+ AP6210_DEBUG("%s: SIOCGIWFREQ\n", dev->name); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) -+ return error; -+ -+ /* Return radio channel in channel form */ -+ fwrq->m = dtoh32(ci.hw_channel); -+ fwrq->e = dtoh32(0); -+ return 0; -+} -+ -+static int -+wl_iw_set_mode( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ __u32 *uwrq, -+ char *extra -+) -+{ -+ int infra = 0, ap = 0, error = 0; -+ -+ AP6210_DEBUG("%s: SIOCSIWMODE\n", dev->name); -+ -+ switch (*uwrq) { -+ case IW_MODE_MASTER: -+ infra = ap = 1; -+ break; -+ case IW_MODE_ADHOC: -+ case IW_MODE_AUTO: -+ break; -+ case IW_MODE_INFRA: -+ infra = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ infra = htod32(infra); -+ ap = htod32(ap); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || -+ (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) -+ return error; -+ -+ /* -EINPROGRESS: Call commit handler */ -+ return -EINPROGRESS; -+} -+ -+static int -+wl_iw_get_mode( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ __u32 *uwrq, -+ char *extra -+) -+{ -+ int error, infra = 0, ap = 0; -+ -+ AP6210_DEBUG("%s: SIOCGIWMODE\n", dev->name); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || -+ (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) -+ return error; -+ -+ infra = dtoh32(infra); -+ ap = dtoh32(ap); -+ *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_range( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ struct iw_range *range = (struct iw_range *) extra; -+ static int channels[MAXCHANNEL+1]; -+ wl_uint32_list_t *list = (wl_uint32_list_t *) channels; -+ wl_rateset_t rateset; -+ int error, i, k; -+ uint sf, ch; -+ -+ int phytype; -+ int bw_cap = 0, sgi_tx = 0, nmode = 0; -+ channel_info_t ci; -+ uint8 nrate_list2copy = 0; -+ uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, -+ {14, 29, 43, 58, 87, 116, 130, 144}, -+ {27, 54, 81, 108, 162, 216, 243, 270}, -+ {30, 60, 90, 120, 180, 240, 270, 300}}; -+ -+ AP6210_DEBUG("%s: SIOCGIWRANGE\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ dwrq->length = sizeof(struct iw_range); -+ memset(range, 0, sizeof(*range)); -+ -+ /* We don't use nwids */ -+ range->min_nwid = range->max_nwid = 0; -+ -+ /* Set available channels/frequencies */ -+ list->count = htod32(MAXCHANNEL); -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels)))) -+ return error; -+ for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { -+ range->freq[i].i = dtoh32(list->element[i]); -+ -+ ch = dtoh32(list->element[i]); -+ if (ch <= CH_MAX_2G_CHANNEL) -+ sf = WF_CHAN_FACTOR_2_4_G; -+ else -+ sf = WF_CHAN_FACTOR_5_G; -+ -+ range->freq[i].m = wf_channel2mhz(ch, sf); -+ range->freq[i].e = 6; -+ } -+ range->num_frequency = range->num_channels = i; -+ -+ /* Link quality (use NDIS cutoffs) */ -+ range->max_qual.qual = 5; -+ /* Signal level (use RSSI) */ -+ range->max_qual.level = 0x100 - 200; /* -200 dBm */ -+ /* Noise level (use noise) */ -+ range->max_qual.noise = 0x100 - 200; /* -200 dBm */ -+ /* Signal level threshold range (?) */ -+ range->sensitivity = 65535; -+ -+#if WIRELESS_EXT > 11 -+ /* Link quality (use NDIS cutoffs) */ -+ range->avg_qual.qual = 3; -+ /* Signal level (use RSSI) */ -+ range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; -+ /* Noise level (use noise) */ -+ range->avg_qual.noise = 0x100 - 75; /* -75 dBm */ -+#endif /* WIRELESS_EXT > 11 */ -+ -+ /* Set available bitrates */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) -+ return error; -+ rateset.count = dtoh32(rateset.count); -+ range->num_bitrates = rateset.count; -+ for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) -+ range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; /* convert to bps */ -+ dev_wlc_intvar_get(dev, "nmode", &nmode); -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)))) -+ return error; -+ -+ if (nmode == 1 && ((phytype == WLC_PHY_TYPE_SSN) || (phytype == WLC_PHY_TYPE_LCN) || -+ (phytype == WLC_PHY_TYPE_LCN40))) { -+ dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); -+ dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); -+ dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); -+ ci.hw_channel = dtoh32(ci.hw_channel); -+ -+ if (bw_cap == 0 || -+ (bw_cap == 2 && ci.hw_channel <= 14)) { -+ if (sgi_tx == 0) -+ nrate_list2copy = 0; -+ else -+ nrate_list2copy = 1; -+ } -+ if (bw_cap == 1 || -+ (bw_cap == 2 && ci.hw_channel >= 36)) { -+ if (sgi_tx == 0) -+ nrate_list2copy = 2; -+ else -+ nrate_list2copy = 3; -+ } -+ range->num_bitrates += 8; -+ for (k = 0; i < range->num_bitrates; k++, i++) { -+ /* convert to bps */ -+ range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; -+ } -+ } -+ -+ /* Set an indication of the max TCP throughput -+ * in bit/s that we can expect using this interface. -+ * May be use for QoS stuff... Jean II -+ */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) -+ return error; -+ i = dtoh32(i); -+ if (i == WLC_PHY_TYPE_A) -+ range->throughput = 24000000; /* 24 Mbits/s */ -+ else -+ range->throughput = 1500000; /* 1.5 Mbits/s */ -+ -+ /* RTS and fragmentation thresholds */ -+ range->min_rts = 0; -+ range->max_rts = 2347; -+ range->min_frag = 256; -+ range->max_frag = 2346; -+ -+ range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; -+ range->num_encoding_sizes = 4; -+ range->encoding_size[0] = WEP1_KEY_SIZE; -+ range->encoding_size[1] = WEP128_KEY_SIZE; -+#if WIRELESS_EXT > 17 -+ range->encoding_size[2] = TKIP_KEY_SIZE; -+#else -+ range->encoding_size[2] = 0; -+#endif -+ range->encoding_size[3] = AES_KEY_SIZE; -+ -+ /* Do not support power micro-management */ -+ range->min_pmp = 0; -+ range->max_pmp = 0; -+ range->min_pmt = 0; -+ range->max_pmt = 0; -+ range->pmp_flags = 0; -+ range->pm_capa = 0; -+ -+ /* Transmit Power - values are in mW */ -+ range->num_txpower = 2; -+ range->txpower[0] = 1; -+ range->txpower[1] = 255; -+ range->txpower_capa = IW_TXPOW_MWATT; -+ -+#if WIRELESS_EXT > 10 -+ range->we_version_compiled = WIRELESS_EXT; -+ range->we_version_source = 19; -+ -+ /* Only support retry limits */ -+ range->retry_capa = IW_RETRY_LIMIT; -+ range->retry_flags = IW_RETRY_LIMIT; -+ range->r_time_flags = 0; -+ /* SRL and LRL limits */ -+ range->min_retry = 1; -+ range->max_retry = 255; -+ /* Retry lifetime limits unsupported */ -+ range->min_r_time = 0; -+ range->max_r_time = 0; -+#endif /* WIRELESS_EXT > 10 */ -+ -+#if WIRELESS_EXT > 17 -+ range->enc_capa = IW_ENC_CAPA_WPA; -+ range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; -+ range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; -+ range->enc_capa |= IW_ENC_CAPA_WPA2; -+#if (defined(BCMSUP_PSK) && defined(WLFBT)) -+ /* Tell the host (e.g. wpa_supplicant) to let us do the handshake */ -+ range->enc_capa |= IW_ENC_CAPA_4WAY_HANDSHAKE; -+#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */ -+ -+ /* Event capability (kernel) */ -+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa); -+ /* Event capability (driver) */ -+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); -+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); -+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); -+ IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); -+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE); -+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE); -+ IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -+ -+#if WIRELESS_EXT >= 22 && defined(IW_SCAN_CAPA_ESSID) -+ /* FC7 wireless.h defines EXT 22 but doesn't define scan_capa bits */ -+ range->scan_capa = IW_SCAN_CAPA_ESSID; -+#endif -+#endif /* WIRELESS_EXT > 17 */ -+ -+ return 0; -+} -+ -+static int -+rssi_to_qual(int rssi) -+{ -+ if (rssi <= WL_IW_RSSI_NO_SIGNAL) -+ return 0; -+ else if (rssi <= WL_IW_RSSI_VERY_LOW) -+ return 1; -+ else if (rssi <= WL_IW_RSSI_LOW) -+ return 2; -+ else if (rssi <= WL_IW_RSSI_GOOD) -+ return 3; -+ else if (rssi <= WL_IW_RSSI_VERY_GOOD) -+ return 4; -+ else -+ return 5; -+} -+ -+static int -+wl_iw_set_spy( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ struct sockaddr *addr = (struct sockaddr *) extra; -+ int i; -+ -+ AP6210_DEBUG("%s: SIOCSIWSPY\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); -+ for (i = 0; i < iw->spy_num; i++) -+ memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); -+ memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_spy( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ struct sockaddr *addr = (struct sockaddr *) extra; -+ struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; -+ int i; -+ -+ AP6210_DEBUG("%s: SIOCGIWSPY\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ dwrq->length = iw->spy_num; -+ for (i = 0; i < iw->spy_num; i++) { -+ memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); -+ addr[i].sa_family = AF_UNIX; -+ memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); -+ iw->spy_qual[i].updated = 0; -+ } -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_wap( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct sockaddr *awrq, -+ char *extra -+) -+{ -+ int error = -EINVAL; -+ -+ AP6210_DEBUG("%s: SIOCSIWAP\n", dev->name); -+ -+ if (awrq->sa_family != ARPHRD_ETHER) { -+ AP6210_ERR("%s: Invalid Header...sa_family\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ -+ /* Ignore "auto" or "off" */ -+ if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { -+ scb_val_t scbval; -+ bzero(&scbval, sizeof(scb_val_t)); -+ if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) { -+ AP6210_ERR("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error); -+ } -+ return 0; -+ } -+ /* WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data), -+ * eabuf))); -+ */ -+ /* Reassociate to the specified AP */ -+ if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) { -+ AP6210_ERR("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error); -+ return error; -+ } -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_wap( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct sockaddr *awrq, -+ char *extra -+) -+{ -+ AP6210_DEBUG("%s: SIOCGIWAP\n", dev->name); -+ -+ awrq->sa_family = ARPHRD_ETHER; -+ memset(awrq->sa_data, 0, ETHER_ADDR_LEN); -+ -+ /* Ignore error (may be down or disassociated) */ -+ (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); -+ -+ return 0; -+} -+ -+#if WIRELESS_EXT > 17 -+static int -+wl_iw_mlme( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct sockaddr *awrq, -+ char *extra -+) -+{ -+ struct iw_mlme *mlme; -+ scb_val_t scbval; -+ int error = -EINVAL; -+ -+ AP6210_DEBUG("%s: SIOCSIWMLME\n", dev->name); -+ -+ mlme = (struct iw_mlme *)extra; -+ if (mlme == NULL) { -+ AP6210_ERR("Invalid ioctl data.\n"); -+ return error; -+ } -+ -+ scbval.val = mlme->reason_code; -+ bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); -+ -+ if (mlme->cmd == IW_MLME_DISASSOC) { -+ scbval.val = htod32(scbval.val); -+ error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); -+ } -+ else if (mlme->cmd == IW_MLME_DEAUTH) { -+ scbval.val = htod32(scbval.val); -+ error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, -+ sizeof(scb_val_t)); -+ } -+ else { -+ AP6210_ERR("%s: Invalid ioctl data.\n", __FUNCTION__); -+ return error; -+ } -+ -+ return error; -+} -+#endif /* WIRELESS_EXT > 17 */ -+ -+static int -+wl_iw_get_aplist( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_scan_results_t *list; -+ struct sockaddr *addr = (struct sockaddr *) extra; -+ struct iw_quality qual[IW_MAX_AP]; -+ wl_bss_info_t *bi = NULL; -+ int error, i; -+ uint buflen = dwrq->length; -+ -+ AP6210_DEBUG("%s: SIOCGIWAPLIST\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ /* Get scan results (too large to put on the stack) */ -+ list = kmalloc(buflen, GFP_KERNEL); -+ if (!list) -+ return -ENOMEM; -+ memset(list, 0, buflen); -+ list->buflen = htod32(buflen); -+ if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { -+ AP6210_ERR("%d: Scan results error %d\n", __LINE__, error); -+ kfree(list); -+ return error; -+ } -+ list->buflen = dtoh32(list->buflen); -+ list->version = dtoh32(list->version); -+ list->count = dtoh32(list->count); -+ ASSERT(list->version == WL_BSS_INFO_VERSION); -+ -+ for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; -+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + -+ buflen)); -+ -+ /* Infrastructure only */ -+ if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) -+ continue; -+ -+ /* BSSID */ -+ memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); -+ addr[dwrq->length].sa_family = ARPHRD_ETHER; -+ qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); -+ qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); -+ qual[dwrq->length].noise = 0x100 + bi->phy_noise; -+ -+ /* Updated qual, level, and noise */ -+#if WIRELESS_EXT > 18 -+ qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -+#else -+ qual[dwrq->length].updated = 7; -+#endif /* WIRELESS_EXT > 18 */ -+ -+ dwrq->length++; -+ } -+ -+ kfree(list); -+ -+ if (dwrq->length) { -+ memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); -+ /* Provided qual */ -+ dwrq->flags = 1; -+ } -+ -+ return 0; -+} -+ -+static int -+wl_iw_iscan_get_aplist( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_scan_results_t *list; -+ iscan_buf_t * buf; -+ iscan_info_t *iscan = g_iscan; -+ -+ struct sockaddr *addr = (struct sockaddr *) extra; -+ struct iw_quality qual[IW_MAX_AP]; -+ wl_bss_info_t *bi = NULL; -+ int i; -+ -+ AP6210_DEBUG("%s: SIOCGIWAPLIST\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ if ((!iscan) || (iscan->sysioc_pid < 0)) { -+ return wl_iw_get_aplist(dev, info, dwrq, extra); -+ } -+ -+ buf = iscan->list_hdr; -+ /* Get scan results (too large to put on the stack) */ -+ while (buf) { -+ list = &((wl_iscan_results_t*)buf->iscan_buf)->results; -+ ASSERT(list->version == WL_BSS_INFO_VERSION); -+ -+ bi = NULL; -+ for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; -+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + -+ WLC_IW_ISCAN_MAXLEN)); -+ -+ /* Infrastructure only */ -+ if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) -+ continue; -+ -+ /* BSSID */ -+ memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); -+ addr[dwrq->length].sa_family = ARPHRD_ETHER; -+ qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); -+ qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); -+ qual[dwrq->length].noise = 0x100 + bi->phy_noise; -+ -+ /* Updated qual, level, and noise */ -+#if WIRELESS_EXT > 18 -+ qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -+#else -+ qual[dwrq->length].updated = 7; -+#endif /* WIRELESS_EXT > 18 */ -+ -+ dwrq->length++; -+ } -+ buf = buf->next; -+ } -+ if (dwrq->length) { -+ memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); -+ /* Provided qual */ -+ dwrq->flags = 1; -+ } -+ -+ return 0; -+} -+ -+#if WIRELESS_EXT > 13 -+static int -+wl_iw_set_scan( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *wrqu, -+ char *extra -+) -+{ -+ wlc_ssid_t ssid; -+ -+ AP6210_DEBUG("%s: SIOCSIWSCAN\n", dev->name); -+ -+ /* default Broadcast scan */ -+ memset(&ssid, 0, sizeof(ssid)); -+ -+#if WIRELESS_EXT > 17 -+ /* check for given essid */ -+ if (wrqu->data.length == sizeof(struct iw_scan_req)) { -+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { -+ struct iw_scan_req *req = (struct iw_scan_req *)extra; -+ ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); -+ memcpy(ssid.SSID, req->essid, ssid.SSID_len); -+ ssid.SSID_len = htod32(ssid.SSID_len); -+ } -+ } -+#endif -+ /* Ignore error (most likely scan in progress) */ -+ (void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid)); -+ -+ return 0; -+} -+ -+static int -+wl_iw_iscan_set_scan( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ union iwreq_data *wrqu, -+ char *extra -+) -+{ -+ wlc_ssid_t ssid; -+ iscan_info_t *iscan = g_iscan; -+ -+ AP6210_DEBUG("%s: SIOCSIWSCAN\n", dev->name); -+ -+ /* use backup if our thread is not successful */ -+ if ((!iscan) || (iscan->sysioc_pid < 0)) { -+ return wl_iw_set_scan(dev, info, wrqu, extra); -+ } -+ if (iscan->iscan_state == ISCAN_STATE_SCANING) { -+ return 0; -+ } -+ -+ /* default Broadcast scan */ -+ memset(&ssid, 0, sizeof(ssid)); -+ -+#if WIRELESS_EXT > 17 -+ /* check for given essid */ -+ if (wrqu->data.length == sizeof(struct iw_scan_req)) { -+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { -+ struct iw_scan_req *req = (struct iw_scan_req *)extra; -+ ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); -+ memcpy(ssid.SSID, req->essid, ssid.SSID_len); -+ ssid.SSID_len = htod32(ssid.SSID_len); -+ } -+ } -+#endif -+ -+ iscan->list_cur = iscan->list_hdr; -+ iscan->iscan_state = ISCAN_STATE_SCANING; -+ -+ -+ wl_iw_set_event_mask(dev); -+ wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); -+ -+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); -+ add_timer(&iscan->timer); -+ iscan->timer_on = 1; -+ -+ return 0; -+} -+ -+#if WIRELESS_EXT > 17 -+static bool -+ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) -+{ -+/* Is this body of this tlvs entry a WPA entry? If */ -+/* not update the tlvs buffer pointer/length */ -+ uint8 *ie = *wpaie; -+ -+ /* If the contents match the WPA_OUI and type=1 */ -+ if ((ie[1] >= 6) && -+ !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { -+ return TRUE; -+ } -+ -+ /* point to the next ie */ -+ ie += ie[1] + 2; -+ /* calculate the length of the rest of the buffer */ -+ *tlvs_len -= (int)(ie - *tlvs); -+ /* update the pointer to the start of the buffer */ -+ *tlvs = ie; -+ return FALSE; -+} -+ -+static bool -+ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) -+{ -+/* Is this body of this tlvs entry a WPS entry? If */ -+/* not update the tlvs buffer pointer/length */ -+ uint8 *ie = *wpsie; -+ -+ /* If the contents match the WPA_OUI and type=4 */ -+ if ((ie[1] >= 4) && -+ !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { -+ return TRUE; -+ } -+ -+ /* point to the next ie */ -+ ie += ie[1] + 2; -+ /* calculate the length of the rest of the buffer */ -+ *tlvs_len -= (int)(ie - *tlvs); -+ /* update the pointer to the start of the buffer */ -+ *tlvs = ie; -+ return FALSE; -+} -+#endif /* WIRELESS_EXT > 17 */ -+ -+ -+static int -+wl_iw_handle_scanresults_ies(char **event_p, char *end, -+ struct iw_request_info *info, wl_bss_info_t *bi) -+{ -+#if WIRELESS_EXT > 17 -+ struct iw_event iwe; -+ char *event; -+ -+ event = *event_p; -+ if (bi->ie_length) { -+ /* look for wpa/rsn ies in the ie list... */ -+ bcm_tlv_t *ie; -+ uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -+ int ptr_len = bi->ie_length; -+ -+ if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.length = ie->len + 2; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -+ } -+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -+ -+#if defined(WLFBT) -+ if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_MDIE_ID))) { -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.length = ie->len + 2; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -+ } -+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -+#endif /* WLFBT */ -+ -+ while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { -+ /* look for WPS IE */ -+ if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.length = ie->len + 2; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -+ break; -+ } -+ } -+ -+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); -+ ptr_len = bi->ie_length; -+ while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { -+ if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.length = ie->len + 2; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); -+ break; -+ } -+ } -+ -+ *event_p = event; -+ } -+ -+#endif /* WIRELESS_EXT > 17 */ -+ return 0; -+} -+static int -+wl_iw_get_scan( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ channel_info_t ci; -+ wl_scan_results_t *list; -+ struct iw_event iwe; -+ wl_bss_info_t *bi = NULL; -+ int error, i, j; -+ char *event = extra, *end = extra + dwrq->length, *value; -+ uint buflen = dwrq->length; -+ -+ AP6210_DEBUG("%s: SIOCGIWSCAN\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ /* Check for scan in progress */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) -+ return error; -+ ci.scan_channel = dtoh32(ci.scan_channel); -+ if (ci.scan_channel) -+ return -EAGAIN; -+ -+ /* Get scan results (too large to put on the stack) */ -+ list = kmalloc(buflen, GFP_KERNEL); -+ if (!list) -+ return -ENOMEM; -+ memset(list, 0, buflen); -+ list->buflen = htod32(buflen); -+ if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { -+ kfree(list); -+ return error; -+ } -+ list->buflen = dtoh32(list->buflen); -+ list->version = dtoh32(list->version); -+ list->count = dtoh32(list->count); -+ -+ ASSERT(list->version == WL_BSS_INFO_VERSION); -+ -+ for (i = 0; i < list->count && i < IW_MAX_AP; i++) { -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; -+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + -+ buflen)); -+ -+ /* First entry must be the BSSID */ -+ iwe.cmd = SIOCGIWAP; -+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; -+ memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); -+ -+ /* SSID */ -+ iwe.u.data.length = dtoh32(bi->SSID_len); -+ iwe.cmd = SIOCGIWESSID; -+ iwe.u.data.flags = 1; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); -+ -+ /* Mode */ -+ if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { -+ iwe.cmd = SIOCGIWMODE; -+ if (dtoh16(bi->capability) & DOT11_CAP_ESS) -+ iwe.u.mode = IW_MODE_INFRA; -+ else -+ iwe.u.mode = IW_MODE_ADHOC; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); -+ } -+ -+ /* Channel */ -+ iwe.cmd = SIOCGIWFREQ; -+ iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), -+ CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? -+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); -+ iwe.u.freq.e = 6; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); -+ -+ /* Channel quality */ -+ iwe.cmd = IWEVQUAL; -+ iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); -+ iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); -+ iwe.u.qual.noise = 0x100 + bi->phy_noise; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); -+ -+ /* WPA, WPA2, WPS, WAPI IEs */ -+ wl_iw_handle_scanresults_ies(&event, end, info, bi); -+ -+ /* Encryption */ -+ iwe.cmd = SIOCGIWENCODE; -+ if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) -+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; -+ else -+ iwe.u.data.flags = IW_ENCODE_DISABLED; -+ iwe.u.data.length = 0; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); -+ -+ /* Rates */ -+ if (bi->rateset.count) { -+ value = event + IW_EV_LCP_LEN; -+ iwe.cmd = SIOCGIWRATE; -+ /* Those two flags are ignored... */ -+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; -+ for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { -+ iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; -+ value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, -+ IW_EV_PARAM_LEN); -+ } -+ event = value; -+ } -+ } -+ -+ kfree(list); -+ -+ dwrq->length = event - extra; -+ dwrq->flags = 0; /* todo */ -+ -+ return 0; -+} -+ -+static int -+wl_iw_iscan_get_scan( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_scan_results_t *list; -+ struct iw_event iwe; -+ wl_bss_info_t *bi = NULL; -+ int ii, j; -+ int apcnt; -+ char *event = extra, *end = extra + dwrq->length, *value; -+ iscan_info_t *iscan = g_iscan; -+ iscan_buf_t * p_buf; -+ -+ AP6210_DEBUG("%s: SIOCGIWSCAN\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ /* use backup if our thread is not successful */ -+ if ((!iscan) || (iscan->sysioc_pid < 0)) { -+ return wl_iw_get_scan(dev, info, dwrq, extra); -+ } -+ -+ /* Check for scan in progress */ -+ if (iscan->iscan_state == ISCAN_STATE_SCANING) -+ return -EAGAIN; -+ -+ apcnt = 0; -+ p_buf = iscan->list_hdr; -+ /* Get scan results */ -+ while (p_buf != iscan->list_cur) { -+ list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; -+ -+ if (list->version != WL_BSS_INFO_VERSION) { -+ AP6210_ERR("list->version %d != WL_BSS_INFO_VERSION\n", list->version); -+ } -+ -+ bi = NULL; -+ for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { -+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; -+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + -+ WLC_IW_ISCAN_MAXLEN)); -+ -+ /* overflow check cover fields before wpa IEs */ -+ if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN + -+ IW_EV_QUAL_LEN >= end) -+ return -E2BIG; -+ /* First entry must be the BSSID */ -+ iwe.cmd = SIOCGIWAP; -+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; -+ memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); -+ -+ /* SSID */ -+ iwe.u.data.length = dtoh32(bi->SSID_len); -+ iwe.cmd = SIOCGIWESSID; -+ iwe.u.data.flags = 1; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); -+ -+ /* Mode */ -+ if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { -+ iwe.cmd = SIOCGIWMODE; -+ if (dtoh16(bi->capability) & DOT11_CAP_ESS) -+ iwe.u.mode = IW_MODE_INFRA; -+ else -+ iwe.u.mode = IW_MODE_ADHOC; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); -+ } -+ -+ /* Channel */ -+ iwe.cmd = SIOCGIWFREQ; -+ iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), -+ CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? -+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); -+ iwe.u.freq.e = 6; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); -+ -+ /* Channel quality */ -+ iwe.cmd = IWEVQUAL; -+ iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); -+ iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); -+ iwe.u.qual.noise = 0x100 + bi->phy_noise; -+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); -+ -+ /* WPA, WPA2, WPS, WAPI IEs */ -+ wl_iw_handle_scanresults_ies(&event, end, info, bi); -+ -+ /* Encryption */ -+ iwe.cmd = SIOCGIWENCODE; -+ if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) -+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; -+ else -+ iwe.u.data.flags = IW_ENCODE_DISABLED; -+ iwe.u.data.length = 0; -+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); -+ -+ /* Rates */ -+ if (bi->rateset.count <= sizeof(bi->rateset.rates)) { -+ if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) -+ return -E2BIG; -+ -+ value = event + IW_EV_LCP_LEN; -+ iwe.cmd = SIOCGIWRATE; -+ /* Those two flags are ignored... */ -+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; -+ for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { -+ iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; -+ value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, -+ IW_EV_PARAM_LEN); -+ } -+ event = value; -+ } -+ } -+ p_buf = p_buf->next; -+ } /* while (p_buf) */ -+ -+ dwrq->length = event - extra; -+ dwrq->flags = 0; /* todo */ -+ -+ return 0; -+} -+ -+#endif /* WIRELESS_EXT > 13 */ -+ -+ -+static int -+wl_iw_set_essid( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wlc_ssid_t ssid; -+ int error; -+ -+ AP6210_DEBUG("%s: SIOCSIWESSID\n", dev->name); -+ -+ /* default Broadcast SSID */ -+ memset(&ssid, 0, sizeof(ssid)); -+ if (dwrq->length && extra) { -+#if WIRELESS_EXT > 20 -+ ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length); -+#else -+ ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length-1); -+#endif -+ memcpy(ssid.SSID, extra, ssid.SSID_len); -+ ssid.SSID_len = htod32(ssid.SSID_len); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)))) -+ return error; -+ } -+ /* If essid null then it is "iwconfig essid off" command */ -+ else { -+ scb_val_t scbval; -+ bzero(&scbval, sizeof(scb_val_t)); -+ if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) -+ return error; -+ } -+ return 0; -+} -+ -+static int -+wl_iw_get_essid( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wlc_ssid_t ssid; -+ int error; -+ -+ AP6210_DEBUG("%s: SIOCGIWESSID\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { -+ AP6210_ERR("Error getting the SSID\n"); -+ return error; -+ } -+ -+ ssid.SSID_len = dtoh32(ssid.SSID_len); -+ -+ /* Get the current SSID */ -+ memcpy(extra, ssid.SSID, ssid.SSID_len); -+ -+ dwrq->length = ssid.SSID_len; -+ -+ dwrq->flags = 1; /* active */ -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_nick( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ AP6210_DEBUG("%s: SIOCSIWNICKN\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ /* Check the size of the string */ -+ if (dwrq->length > sizeof(iw->nickname)) -+ return -E2BIG; -+ -+ memcpy(iw->nickname, extra, dwrq->length); -+ iw->nickname[dwrq->length - 1] = '\0'; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_nick( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ AP6210_DEBUG("%s: SIOCGIWNICKN\n", dev->name); -+ -+ if (!extra) -+ return -EINVAL; -+ -+ strcpy(extra, iw->nickname); -+ dwrq->length = strlen(extra) + 1; -+ -+ return 0; -+} -+ -+static int wl_iw_set_rate( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ wl_rateset_t rateset; -+ int error, rate, i, error_bg, error_a; -+ -+ AP6210_DEBUG("%s: SIOCSIWRATE\n", dev->name); -+ -+ /* Get current rateset */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) -+ return error; -+ -+ rateset.count = dtoh32(rateset.count); -+ -+ if (vwrq->value < 0) { -+ /* Select maximum rate */ -+ rate = rateset.rates[rateset.count - 1] & 0x7f; -+ } else if (vwrq->value < rateset.count) { -+ /* Select rate by rateset index */ -+ rate = rateset.rates[vwrq->value] & 0x7f; -+ } else { -+ /* Specified rate in bps */ -+ rate = vwrq->value / 500000; -+ } -+ -+ if (vwrq->fixed) { -+ /* -+ Set rate override, -+ Since the is a/b/g-blind, both a/bg_rate are enforced. -+ */ -+ error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); -+ error_a = dev_wlc_intvar_set(dev, "a_rate", rate); -+ -+ if (error_bg && error_a) -+ return (error_bg | error_a); -+ } else { -+ /* -+ clear rate override -+ Since the is a/b/g-blind, both a/bg_rate are enforced. -+ */ -+ /* 0 is for clearing rate override */ -+ error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); -+ /* 0 is for clearing rate override */ -+ error_a = dev_wlc_intvar_set(dev, "a_rate", 0); -+ -+ if (error_bg && error_a) -+ return (error_bg | error_a); -+ -+ /* Remove rates above selected rate */ -+ for (i = 0; i < rateset.count; i++) -+ if ((rateset.rates[i] & 0x7f) > rate) -+ break; -+ rateset.count = htod32(i); -+ -+ /* Set current rateset */ -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) -+ return error; -+ } -+ -+ return 0; -+} -+ -+static int wl_iw_get_rate( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, rate; -+ -+ AP6210_DEBUG("%s: SIOCGIWRATE\n", dev->name); -+ -+ /* Report the current tx rate */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) -+ return error; -+ rate = dtoh32(rate); -+ vwrq->value = rate * 500000; -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_rts( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, rts; -+ -+ AP6210_DEBUG("%s: SIOCSIWRTS\n", dev->name); -+ -+ if (vwrq->disabled) -+ rts = DOT11_DEFAULT_RTS_LEN; -+ else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) -+ return -EINVAL; -+ else -+ rts = vwrq->value; -+ -+ if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) -+ return error; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_rts( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, rts; -+ -+ AP6210_DEBUG("%s: SIOCGIWRTS\n", dev->name); -+ -+ if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) -+ return error; -+ -+ vwrq->value = rts; -+ vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); -+ vwrq->fixed = 1; -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_frag( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, frag; -+ -+ AP6210_DEBUG("%s: SIOCSIWFRAG\n", dev->name); -+ -+ if (vwrq->disabled) -+ frag = DOT11_DEFAULT_FRAG_LEN; -+ else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) -+ return -EINVAL; -+ else -+ frag = vwrq->value; -+ -+ if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) -+ return error; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_frag( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, fragthreshold; -+ -+ AP6210_DEBUG("%s: SIOCGIWFRAG\n", dev->name); -+ -+ if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) -+ return error; -+ -+ vwrq->value = fragthreshold; -+ vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); -+ vwrq->fixed = 1; -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_txpow( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, disable; -+ uint16 txpwrmw; -+ AP6210_DEBUG("%s: SIOCSIWTXPOW\n", dev->name); -+ -+ /* Make sure radio is off or on as far as software is concerned */ -+ disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; -+ disable += WL_RADIO_SW_DISABLE << 16; -+ -+ disable = htod32(disable); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) -+ return error; -+ -+ /* If Radio is off, nothing more to do */ -+ if (disable & WL_RADIO_SW_DISABLE) -+ return 0; -+ -+ /* Only handle mW */ -+ if (!(vwrq->flags & IW_TXPOW_MWATT)) -+ return -EINVAL; -+ -+ /* Value < 0 means just "on" or "off" */ -+ if (vwrq->value < 0) -+ return 0; -+ -+ if (vwrq->value > 0xffff) txpwrmw = 0xffff; -+ else txpwrmw = (uint16)vwrq->value; -+ -+ -+ error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); -+ return error; -+} -+ -+static int -+wl_iw_get_txpow( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, disable, txpwrdbm; -+ uint8 result; -+ -+ AP6210_DEBUG("%s: SIOCGIWTXPOW\n", dev->name); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || -+ (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) -+ return error; -+ -+ disable = dtoh32(disable); -+ result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); -+ vwrq->value = (int32)bcm_qdbm_to_mw(result); -+ vwrq->fixed = 0; -+ vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; -+ vwrq->flags = IW_TXPOW_MWATT; -+ -+ return 0; -+} -+ -+#if WIRELESS_EXT > 10 -+static int -+wl_iw_set_retry( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, lrl, srl; -+ -+ AP6210_DEBUG("%s: SIOCSIWRETRY\n", dev->name); -+ -+ /* Do not handle "off" or "lifetime" */ -+ if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) -+ return -EINVAL; -+ -+ /* Handle "[min|max] limit" */ -+ if (vwrq->flags & IW_RETRY_LIMIT) { -+ /* "max limit" or just "limit" */ -+#if WIRELESS_EXT > 20 -+ if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || -+ !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { -+#else -+ if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { -+#endif /* WIRELESS_EXT > 20 */ -+ -+ lrl = htod32(vwrq->value); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) -+ return error; -+ } -+ /* "min limit" or just "limit" */ -+#if WIRELESS_EXT > 20 -+ if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || -+ !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { -+#else -+ if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { -+#endif /* WIRELESS_EXT > 20 */ -+ -+ srl = htod32(vwrq->value); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) -+ return error; -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_retry( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, lrl, srl; -+ -+ AP6210_DEBUG("%s: SIOCGIWRETRY\n", dev->name); -+ -+ vwrq->disabled = 0; /* Can't be disabled */ -+ -+ /* Do not handle lifetime queries */ -+ if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) -+ return -EINVAL; -+ -+ /* Get retry limits */ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || -+ (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) -+ return error; -+ -+ lrl = dtoh32(lrl); -+ srl = dtoh32(srl); -+ -+ /* Note : by default, display the min retry number */ -+ if (vwrq->flags & IW_RETRY_MAX) { -+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; -+ vwrq->value = lrl; -+ } else { -+ vwrq->flags = IW_RETRY_LIMIT; -+ vwrq->value = srl; -+ if (srl != lrl) -+ vwrq->flags |= IW_RETRY_MIN; -+ } -+ -+ return 0; -+} -+#endif /* WIRELESS_EXT > 10 */ -+ -+static int -+wl_iw_set_encode( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_wsec_key_t key; -+ int error, val, wsec; -+ -+ AP6210_DEBUG("%s: SIOCSIWENCODE\n", dev->name); -+ -+ memset(&key, 0, sizeof(key)); -+ -+ if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { -+ /* Find the current key */ -+ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { -+ val = htod32(key.index); -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) -+ return error; -+ val = dtoh32(val); -+ if (val) -+ break; -+ } -+ /* Default to 0 */ -+ if (key.index == DOT11_MAX_DEFAULT_KEYS) -+ key.index = 0; -+ } else { -+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; -+ if (key.index >= DOT11_MAX_DEFAULT_KEYS) -+ return -EINVAL; -+ } -+ -+ /* Interpret "off" to mean no encryption */ -+ wsec = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; -+ -+ if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) -+ return error; -+ -+ /* Old API used to pass a NULL pointer instead of IW_ENCODE_NOKEY */ -+ if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { -+ /* Just select a new current key */ -+ val = htod32(key.index); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) -+ return error; -+ } else { -+ key.len = dwrq->length; -+ -+ if (dwrq->length > sizeof(key.data)) -+ return -EINVAL; -+ -+ memcpy(key.data, extra, dwrq->length); -+ -+ key.flags = WL_PRIMARY_KEY; -+ switch (key.len) { -+ case WEP1_KEY_SIZE: -+ key.algo = CRYPTO_ALGO_WEP1; -+ break; -+ case WEP128_KEY_SIZE: -+ key.algo = CRYPTO_ALGO_WEP128; -+ break; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -+ case TKIP_KEY_SIZE: -+ key.algo = CRYPTO_ALGO_TKIP; -+ break; -+#endif -+ case AES_KEY_SIZE: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Set the new key/index */ -+ swap_key_from_BE(&key); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) -+ return error; -+ } -+ -+ /* Interpret "restricted" to mean shared key authentication */ -+ val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; -+ val = htod32(val); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) -+ return error; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_encode( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_wsec_key_t key; -+ int error, val, wsec, auth; -+ -+ AP6210_DEBUG("%s: SIOCGIWENCODE\n", dev->name); -+ -+ /* assure default values of zero for things we don't touch */ -+ bzero(&key, sizeof(wl_wsec_key_t)); -+ -+ if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { -+ /* Find the current key */ -+ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { -+ val = key.index; -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) -+ return error; -+ val = dtoh32(val); -+ if (val) -+ break; -+ } -+ } else -+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; -+ -+ if (key.index >= DOT11_MAX_DEFAULT_KEYS) -+ key.index = 0; -+ -+ /* Get info */ -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || -+ (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) -+ return error; -+ -+ swap_key_to_BE(&key); -+ -+ wsec = dtoh32(wsec); -+ auth = dtoh32(auth); -+ /* Get key length */ -+ dwrq->length = MIN(IW_ENCODING_TOKEN_MAX, key.len); -+ -+ /* Get flags */ -+ dwrq->flags = key.index + 1; -+ if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { -+ /* Interpret "off" to mean no encryption */ -+ dwrq->flags |= IW_ENCODE_DISABLED; -+ } -+ if (auth) { -+ /* Interpret "restricted" to mean shared key authentication */ -+ dwrq->flags |= IW_ENCODE_RESTRICTED; -+ } -+ -+ /* Get key */ -+ if (dwrq->length && extra) -+ memcpy(extra, key.data, dwrq->length); -+ -+ return 0; -+} -+ -+static int -+wl_iw_set_power( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, pm; -+ -+ AP6210_DEBUG("%s: SIOCSIWPOWER\n", dev->name); -+ -+ pm = vwrq->disabled ? PM_OFF : PM_MAX; -+ -+ pm = htod32(pm); -+ if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) -+ return error; -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_power( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error, pm; -+ -+ AP6210_DEBUG("%s: SIOCGIWPOWER\n", dev->name); -+ -+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) -+ return error; -+ -+ pm = dtoh32(pm); -+ vwrq->disabled = pm ? 0 : 1; -+ vwrq->flags = IW_POWER_ALL_R; -+ -+ return 0; -+} -+ -+#if WIRELESS_EXT > 17 -+static int -+wl_iw_set_wpaie( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *iwp, -+ char *extra -+) -+{ -+ dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); -+ -+ return 0; -+} -+ -+static int -+wl_iw_get_wpaie( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *iwp, -+ char *extra -+) -+{ -+ AP6210_DEBUG("%s: SIOCGIWGENIE\n", dev->name); -+ iwp->length = 64; -+ dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); -+ return 0; -+} -+ -+static int -+wl_iw_set_encodeext( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *dwrq, -+ char *extra -+) -+{ -+ wl_wsec_key_t key; -+ int error; -+ struct iw_encode_ext *iwe; -+ -+ AP6210_DEBUG("%s: SIOCSIWENCODEEXT\n", dev->name); -+ -+ memset(&key, 0, sizeof(key)); -+ iwe = (struct iw_encode_ext *)extra; -+ -+ /* disable encryption completely */ -+ if (dwrq->flags & IW_ENCODE_DISABLED) { -+ -+ } -+ -+ /* get the key index */ -+ key.index = 0; -+ if (dwrq->flags & IW_ENCODE_INDEX) -+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; -+ -+ key.len = iwe->key_len; -+ -+ /* Instead of bcast for ea address for default wep keys, driver needs it to be Null */ -+ if (!ETHER_ISMULTI(iwe->addr.sa_data)) -+ bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); -+ -+ /* check for key index change */ -+ if (key.len == 0) { -+ if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ AP6210_DEBUG("Changing the the primary Key to %d\n", key.index); -+ /* change the key index .... */ -+ key.index = htod32(key.index); -+ error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, -+ &key.index, sizeof(key.index)); -+ if (error) -+ return error; -+ } -+ /* key delete */ -+ else { -+ swap_key_from_BE(&key); -+ error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); -+ if (error) -+ return error; -+ } -+ } -+#if (defined(BCMSUP_PSK) && defined(WLFBT)) -+ /* This case is used to allow an external 802.1x supplicant -+ * to pass the PMK to the in-driver supplicant for use in -+ * the 4-way handshake. -+ */ -+ else if (iwe->alg == IW_ENCODE_ALG_PMK) { -+ int j; -+ wsec_pmk_t pmk; -+ char keystring[WSEC_MAX_PSK_LEN + 1]; -+ char* charptr = keystring; -+ uint len; -+ -+ /* copy the raw hex key to the appropriate format */ -+ for (j = 0; j < (WSEC_MAX_PSK_LEN / 2); j++) { -+ sprintf(charptr, "%02x", iwe->key[j]); -+ charptr += 2; -+ } -+ len = strlen(keystring); -+ pmk.key_len = htod16(len); -+ bcopy(keystring, pmk.key, len); -+ pmk.flags = htod16(WSEC_PASSPHRASE); -+ -+ error = dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk)); -+ if (error) -+ return error; -+ } -+#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */ -+ -+ else { -+ if (iwe->key_len > sizeof(key.data)) -+ return -EINVAL; -+ -+ AP6210_DEBUG("Setting the key index %d\n", key.index); -+ if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ AP6210_DEBUG("key is a Primary Key\n"); -+ key.flags = WL_PRIMARY_KEY; -+ } -+ -+ bcopy((void *)iwe->key, key.data, iwe->key_len); -+ -+ if (iwe->alg == IW_ENCODE_ALG_TKIP) { -+ uint8 keybuf[8]; -+ bcopy(&key.data[24], keybuf, sizeof(keybuf)); -+ bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); -+ bcopy(keybuf, &key.data[16], sizeof(keybuf)); -+ } -+ -+ /* rx iv */ -+ if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ uchar *ivptr; -+ ivptr = (uchar *)iwe->rx_seq; -+ key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | -+ (ivptr[3] << 8) | ivptr[2]; -+ key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; -+ key.iv_initialized = TRUE; -+ } -+ -+ switch (iwe->alg) { -+ case IW_ENCODE_ALG_NONE: -+ key.algo = CRYPTO_ALGO_OFF; -+ break; -+ case IW_ENCODE_ALG_WEP: -+ if (iwe->key_len == WEP1_KEY_SIZE) -+ key.algo = CRYPTO_ALGO_WEP1; -+ else -+ key.algo = CRYPTO_ALGO_WEP128; -+ break; -+ case IW_ENCODE_ALG_TKIP: -+ key.algo = CRYPTO_ALGO_TKIP; -+ break; -+ case IW_ENCODE_ALG_CCMP: -+ key.algo = CRYPTO_ALGO_AES_CCM; -+ break; -+ default: -+ break; -+ } -+ swap_key_from_BE(&key); -+ -+ dhd_wait_pend8021x(dev); -+ -+ error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); -+ if (error) -+ return error; -+ } -+ return 0; -+} -+ -+ -+#if WIRELESS_EXT > 17 -+struct { -+ pmkid_list_t pmkids; -+ pmkid_t foo[MAXPMKID-1]; -+} pmkid_list; -+static int -+wl_iw_set_pmksa( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ struct iw_pmksa *iwpmksa; -+ uint i; -+ char eabuf[ETHER_ADDR_STR_LEN]; -+ pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; -+ -+ AP6210_DEBUG("%s: SIOCSIWPMKSA\n", dev->name); -+ iwpmksa = (struct iw_pmksa *)extra; -+ bzero((char *)eabuf, ETHER_ADDR_STR_LEN); -+ if (iwpmksa->cmd == IW_PMKSA_FLUSH) { -+ AP6210_DEBUG("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"); -+ bzero((char *)&pmkid_list, sizeof(pmkid_list)); -+ } -+ if (iwpmksa->cmd == IW_PMKSA_REMOVE) { -+ pmkid_list_t pmkid, *pmkidptr; -+ pmkidptr = &pmkid; -+ bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN); -+ bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); -+ { -+ uint j; -+ AP6210_DEBUG("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", -+ bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, -+ eabuf)); -+ for (j = 0; j < WPA2_PMKID_LEN; j++) -+ AP6210_DUMP("%02x ", pmkidptr->pmkid[0].PMKID[j]); -+ AP6210_DUMP("\n"); -+ } -+ for (i = 0; i < pmkid_list.pmkids.npmkid; i++) -+ if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, -+ ETHER_ADDR_LEN)) -+ break; -+ for (; i < pmkid_list.pmkids.npmkid; i++) { -+ bcopy(&pmkid_array[i+1].BSSID, -+ &pmkid_array[i].BSSID, -+ ETHER_ADDR_LEN); -+ bcopy(&pmkid_array[i+1].PMKID, -+ &pmkid_array[i].PMKID, -+ WPA2_PMKID_LEN); -+ } -+ pmkid_list.pmkids.npmkid--; -+ } -+ if (iwpmksa->cmd == IW_PMKSA_ADD) { -+ bcopy(&iwpmksa->bssid.sa_data[0], -+ &pmkid_array[pmkid_list.pmkids.npmkid].BSSID, -+ ETHER_ADDR_LEN); -+ bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmkid_list.pmkids.npmkid].PMKID, -+ WPA2_PMKID_LEN); -+ { -+ uint j; -+ uint k; -+ k = pmkid_list.pmkids.npmkid; -+ BCM_REFERENCE(k); -+ AP6210_DEBUG("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", -+ bcm_ether_ntoa(&pmkid_array[k].BSSID, -+ eabuf)); -+ for (j = 0; j < WPA2_PMKID_LEN; j++) -+ AP6210_DUMP("%02x ", pmkid_array[k].PMKID[j]); -+ AP6210_DUMP("\n"); -+ } -+ pmkid_list.pmkids.npmkid++; -+ } -+ AP6210_DEBUG("PRINTING pmkid LIST - No of elements %d\n", pmkid_list.pmkids.npmkid); -+ for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { -+ uint j; -+ AP6210_DEBUG("PMKID[%d]: %s = ", i, -+ bcm_ether_ntoa(&pmkid_array[i].BSSID, -+ eabuf)); -+ for (j = 0; j < WPA2_PMKID_LEN; j++) -+ AP6210_DUMP("%02x ", pmkid_array[i].PMKID[j]); -+ AP6210_DEBUG("\n"); -+ } -+ AP6210_DEBUG("\n"); -+ dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list)); -+ return 0; -+} -+#endif /* WIRELESS_EXT > 17 */ -+ -+static int -+wl_iw_get_encodeext( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ AP6210_DEBUG("%s: SIOCGIWENCODEEXT\n", dev->name); -+ return 0; -+} -+ -+static int -+wl_iw_set_wpaauth( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error = 0; -+ int paramid; -+ int paramval; -+ uint32 cipher_combined; -+ int val = 0; -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ -+ AP6210_DEBUG("%s: SIOCSIWAUTH\n", dev->name); -+ -+ paramid = vwrq->flags & IW_AUTH_INDEX; -+ paramval = vwrq->value; -+ -+ AP6210_DEBUG("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", -+ dev->name, paramid, paramval); -+ -+ switch (paramid) { -+ -+ case IW_AUTH_WPA_VERSION: -+ /* supported wpa version disabled or wpa or wpa2 */ -+ if (paramval & IW_AUTH_WPA_VERSION_DISABLED) -+ val = WPA_AUTH_DISABLED; -+ else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) -+ val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; -+ else if (paramval & IW_AUTH_WPA_VERSION_WPA2) -+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; -+ AP6210_DEBUG("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val); -+ if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) -+ return error; -+ break; -+ -+ case IW_AUTH_CIPHER_PAIRWISE: -+ case IW_AUTH_CIPHER_GROUP: -+ -+ if (paramid == IW_AUTH_CIPHER_PAIRWISE) { -+ iw->pwsec = paramval; -+ } -+ else { -+ iw->gwsec = paramval; -+ } -+ -+ if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) -+ return error; -+ -+ cipher_combined = iw->gwsec | iw->pwsec; -+ val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED); -+ if (cipher_combined & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) -+ val |= WEP_ENABLED; -+ if (cipher_combined & IW_AUTH_CIPHER_TKIP) -+ val |= TKIP_ENABLED; -+ if (cipher_combined & IW_AUTH_CIPHER_CCMP) -+ val |= AES_ENABLED; -+ -+ if (iw->privacy_invoked && !val) { -+ AP6210_DEBUG("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " -+ "we're a WPS enrollee\n", dev->name, __FUNCTION__); -+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { -+ AP6210_DEBUG("Failed to set iovar is_WPS_enrollee\n"); -+ return error; -+ } -+ } else if (val) { -+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { -+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n"); -+ return error; -+ } -+ } -+ -+ if ((error = dev_wlc_intvar_set(dev, "wsec", val))) -+ return error; -+#ifdef WLFBT -+ if ((paramid == IW_AUTH_CIPHER_PAIRWISE) && (val | AES_ENABLED)) { -+ if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 1))) -+ return error; -+ } -+ else if (val == 0) { -+ if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 0))) -+ return error; -+ } -+#endif /* WLFBT */ -+ break; -+ -+ case IW_AUTH_KEY_MGMT: -+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) -+ return error; -+ -+ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { -+ if (paramval & IW_AUTH_KEY_MGMT_PSK) -+ val = WPA_AUTH_PSK; -+ else -+ val = WPA_AUTH_UNSPECIFIED; -+ } -+ else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { -+ if (paramval & IW_AUTH_KEY_MGMT_PSK) -+ val = WPA2_AUTH_PSK; -+ else -+ val = WPA2_AUTH_UNSPECIFIED; -+ } -+ AP6210_DEBUG("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val); -+ if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) -+ return error; -+ break; -+ -+ case IW_AUTH_TKIP_COUNTERMEASURES: -+ dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)¶mval, 1); -+ break; -+ -+ case IW_AUTH_80211_AUTH_ALG: -+ /* open shared */ -+ AP6210_ERR("Setting the D11auth %d\n", paramval); -+ if (paramval & IW_AUTH_ALG_OPEN_SYSTEM) -+ val = 0; -+ else if (paramval & IW_AUTH_ALG_SHARED_KEY) -+ val = 1; -+ else -+ error = 1; -+ if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) -+ return error; -+ break; -+ -+ case IW_AUTH_WPA_ENABLED: -+ if (paramval == 0) { -+ val = 0; -+ AP6210_DEBUG("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val); -+ error = dev_wlc_intvar_set(dev, "wpa_auth", val); -+ return error; -+ } -+ else { -+ /* If WPA is enabled, wpa_auth is set elsewhere */ -+ } -+ break; -+ -+ case IW_AUTH_DROP_UNENCRYPTED: -+ dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)¶mval, 1); -+ break; -+ -+ case IW_AUTH_RX_UNENCRYPTED_EAPOL: -+ dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); -+ break; -+ -+#if WIRELESS_EXT > 17 -+ -+ case IW_AUTH_ROAMING_CONTROL: -+ AP6210_DEBUG("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__); -+ /* driver control or user space app control */ -+ break; -+ -+ case IW_AUTH_PRIVACY_INVOKED: { -+ int wsec; -+ -+ if (paramval == 0) { -+ iw->privacy_invoked = FALSE; -+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { -+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n"); -+ return error; -+ } -+ } else { -+ iw->privacy_invoked = TRUE; -+ if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) -+ return error; -+ -+ if (!WSEC_ENABLED(wsec)) { -+ /* if privacy is true, but wsec is false, we are a WPS enrollee */ -+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { -+ AP6210_DEBUG("Failed to set iovar is_WPS_enrollee\n"); -+ return error; -+ } -+ } else { -+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { -+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n"); -+ return error; -+ } -+ } -+ } -+ break; -+ } -+ -+ -+#endif /* WIRELESS_EXT > 17 */ -+ -+ -+ default: -+ break; -+ } -+ return 0; -+} -+#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) -+ -+static int -+wl_iw_get_wpaauth( -+ struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_param *vwrq, -+ char *extra -+) -+{ -+ int error; -+ int paramid; -+ int paramval = 0; -+ int val; -+ wl_iw_t *iw = IW_DEV_IF(dev); -+ -+ AP6210_DEBUG("%s: SIOCGIWAUTH\n", dev->name); -+ -+ paramid = vwrq->flags & IW_AUTH_INDEX; -+ -+ switch (paramid) { -+ case IW_AUTH_WPA_VERSION: -+ /* supported wpa version disabled or wpa or wpa2 */ -+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) -+ return error; -+ if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) -+ paramval = IW_AUTH_WPA_VERSION_DISABLED; -+ else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) -+ paramval = IW_AUTH_WPA_VERSION_WPA; -+ else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) -+ paramval = IW_AUTH_WPA_VERSION_WPA2; -+ break; -+ -+ case IW_AUTH_CIPHER_PAIRWISE: -+ paramval = iw->pwsec; -+ break; -+ -+ case IW_AUTH_CIPHER_GROUP: -+ paramval = iw->gwsec; -+ break; -+ -+ case IW_AUTH_KEY_MGMT: -+ /* psk, 1x */ -+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) -+ return error; -+ if (VAL_PSK(val)) -+ paramval = IW_AUTH_KEY_MGMT_PSK; -+ else -+ paramval = IW_AUTH_KEY_MGMT_802_1X; -+ -+ break; -+ case IW_AUTH_TKIP_COUNTERMEASURES: -+ dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)¶mval, 1); -+ break; -+ -+ case IW_AUTH_DROP_UNENCRYPTED: -+ dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)¶mval, 1); -+ break; -+ -+ case IW_AUTH_RX_UNENCRYPTED_EAPOL: -+ dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); -+ break; -+ -+ case IW_AUTH_80211_AUTH_ALG: -+ /* open, shared, leap */ -+ if ((error = dev_wlc_intvar_get(dev, "auth", &val))) -+ return error; -+ if (!val) -+ paramval = IW_AUTH_ALG_OPEN_SYSTEM; -+ else -+ paramval = IW_AUTH_ALG_SHARED_KEY; -+ break; -+ case IW_AUTH_WPA_ENABLED: -+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) -+ return error; -+ if (val) -+ paramval = TRUE; -+ else -+ paramval = FALSE; -+ break; -+ -+#if WIRELESS_EXT > 17 -+ -+ case IW_AUTH_ROAMING_CONTROL: -+ AP6210_ERR("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__); -+ /* driver control or user space app control */ -+ break; -+ -+ case IW_AUTH_PRIVACY_INVOKED: -+ paramval = iw->privacy_invoked; -+ break; -+ -+#endif /* WIRELESS_EXT > 17 */ -+ } -+ vwrq->value = paramval; -+ return 0; -+} -+#endif /* WIRELESS_EXT > 17 */ -+ -+static const iw_handler wl_iw_handler[] = -+{ -+ (iw_handler) wl_iw_config_commit, /* SIOCSIWCOMMIT */ -+ (iw_handler) wl_iw_get_name, /* SIOCGIWNAME */ -+ (iw_handler) NULL, /* SIOCSIWNWID */ -+ (iw_handler) NULL, /* SIOCGIWNWID */ -+ (iw_handler) wl_iw_set_freq, /* SIOCSIWFREQ */ -+ (iw_handler) wl_iw_get_freq, /* SIOCGIWFREQ */ -+ (iw_handler) wl_iw_set_mode, /* SIOCSIWMODE */ -+ (iw_handler) wl_iw_get_mode, /* SIOCGIWMODE */ -+ (iw_handler) NULL, /* SIOCSIWSENS */ -+ (iw_handler) NULL, /* SIOCGIWSENS */ -+ (iw_handler) NULL, /* SIOCSIWRANGE */ -+ (iw_handler) wl_iw_get_range, /* SIOCGIWRANGE */ -+ (iw_handler) NULL, /* SIOCSIWPRIV */ -+ (iw_handler) NULL, /* SIOCGIWPRIV */ -+ (iw_handler) NULL, /* SIOCSIWSTATS */ -+ (iw_handler) NULL, /* SIOCGIWSTATS */ -+ (iw_handler) wl_iw_set_spy, /* SIOCSIWSPY */ -+ (iw_handler) wl_iw_get_spy, /* SIOCGIWSPY */ -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) wl_iw_set_wap, /* SIOCSIWAP */ -+ (iw_handler) wl_iw_get_wap, /* SIOCGIWAP */ -+#if WIRELESS_EXT > 17 -+ (iw_handler) wl_iw_mlme, /* SIOCSIWMLME */ -+#else -+ (iw_handler) NULL, /* -- hole -- */ -+#endif -+ (iw_handler) wl_iw_iscan_get_aplist, /* SIOCGIWAPLIST */ -+#if WIRELESS_EXT > 13 -+ (iw_handler) wl_iw_iscan_set_scan, /* SIOCSIWSCAN */ -+ (iw_handler) wl_iw_iscan_get_scan, /* SIOCGIWSCAN */ -+#else /* WIRELESS_EXT > 13 */ -+ (iw_handler) NULL, /* SIOCSIWSCAN */ -+ (iw_handler) NULL, /* SIOCGIWSCAN */ -+#endif /* WIRELESS_EXT > 13 */ -+ (iw_handler) wl_iw_set_essid, /* SIOCSIWESSID */ -+ (iw_handler) wl_iw_get_essid, /* SIOCGIWESSID */ -+ (iw_handler) wl_iw_set_nick, /* SIOCSIWNICKN */ -+ (iw_handler) wl_iw_get_nick, /* SIOCGIWNICKN */ -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) wl_iw_set_rate, /* SIOCSIWRATE */ -+ (iw_handler) wl_iw_get_rate, /* SIOCGIWRATE */ -+ (iw_handler) wl_iw_set_rts, /* SIOCSIWRTS */ -+ (iw_handler) wl_iw_get_rts, /* SIOCGIWRTS */ -+ (iw_handler) wl_iw_set_frag, /* SIOCSIWFRAG */ -+ (iw_handler) wl_iw_get_frag, /* SIOCGIWFRAG */ -+ (iw_handler) wl_iw_set_txpow, /* SIOCSIWTXPOW */ -+ (iw_handler) wl_iw_get_txpow, /* SIOCGIWTXPOW */ -+#if WIRELESS_EXT > 10 -+ (iw_handler) wl_iw_set_retry, /* SIOCSIWRETRY */ -+ (iw_handler) wl_iw_get_retry, /* SIOCGIWRETRY */ -+#endif /* WIRELESS_EXT > 10 */ -+ (iw_handler) wl_iw_set_encode, /* SIOCSIWENCODE */ -+ (iw_handler) wl_iw_get_encode, /* SIOCGIWENCODE */ -+ (iw_handler) wl_iw_set_power, /* SIOCSIWPOWER */ -+ (iw_handler) wl_iw_get_power, /* SIOCGIWPOWER */ -+#if WIRELESS_EXT > 17 -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) NULL, /* -- hole -- */ -+ (iw_handler) wl_iw_set_wpaie, /* SIOCSIWGENIE */ -+ (iw_handler) wl_iw_get_wpaie, /* SIOCGIWGENIE */ -+ (iw_handler) wl_iw_set_wpaauth, /* SIOCSIWAUTH */ -+ (iw_handler) wl_iw_get_wpaauth, /* SIOCGIWAUTH */ -+ (iw_handler) wl_iw_set_encodeext, /* SIOCSIWENCODEEXT */ -+ (iw_handler) wl_iw_get_encodeext, /* SIOCGIWENCODEEXT */ -+ (iw_handler) wl_iw_set_pmksa, /* SIOCSIWPMKSA */ -+#endif /* WIRELESS_EXT > 17 */ -+}; -+ -+#if WIRELESS_EXT > 12 -+enum { -+ WL_IW_SET_LEDDC = SIOCIWFIRSTPRIV, -+ WL_IW_SET_VLANMODE, -+ WL_IW_SET_PM -+}; -+ -+static iw_handler wl_iw_priv_handler[] = { -+ wl_iw_set_leddc, -+ wl_iw_set_vlanmode, -+ wl_iw_set_pm -+}; -+ -+static struct iw_priv_args wl_iw_priv_args[] = { -+ { -+ WL_IW_SET_LEDDC, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ 0, -+ "set_leddc" -+ }, -+ { -+ WL_IW_SET_VLANMODE, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ 0, -+ "set_vlanmode" -+ }, -+ { -+ WL_IW_SET_PM, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ 0, -+ "set_pm" -+ } -+}; -+ -+const struct iw_handler_def wl_iw_handler_def = -+{ -+ .num_standard = ARRAYSIZE(wl_iw_handler), -+ .num_private = ARRAY_SIZE(wl_iw_priv_handler), -+ .num_private_args = ARRAY_SIZE(wl_iw_priv_args), -+ .standard = (iw_handler *) wl_iw_handler, -+ .private = wl_iw_priv_handler, -+ .private_args = wl_iw_priv_args, -+#if WIRELESS_EXT >= 19 -+ get_wireless_stats: dhd_get_wireless_stats, -+#endif /* WIRELESS_EXT >= 19 */ -+ }; -+#endif /* WIRELESS_EXT > 12 */ -+ -+int -+wl_iw_ioctl( -+ struct net_device *dev, -+ struct ifreq *rq, -+ int cmd -+) -+{ -+ struct iwreq *wrq = (struct iwreq *) rq; -+ struct iw_request_info info; -+ iw_handler handler; -+ char *extra = NULL; -+ size_t token_size = 1; -+ int max_tokens = 0, ret = 0; -+ -+ if (cmd < SIOCIWFIRST || -+ IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) || -+ !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) -+ return -EOPNOTSUPP; -+ -+ switch (cmd) { -+ -+ case SIOCSIWESSID: -+ case SIOCGIWESSID: -+ case SIOCSIWNICKN: -+ case SIOCGIWNICKN: -+ max_tokens = IW_ESSID_MAX_SIZE + 1; -+ break; -+ -+ case SIOCSIWENCODE: -+ case SIOCGIWENCODE: -+#if WIRELESS_EXT > 17 -+ case SIOCSIWENCODEEXT: -+ case SIOCGIWENCODEEXT: -+#endif -+ max_tokens = IW_ENCODING_TOKEN_MAX; -+ break; -+ -+ case SIOCGIWRANGE: -+ max_tokens = sizeof(struct iw_range); -+ break; -+ -+ case SIOCGIWAPLIST: -+ token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); -+ max_tokens = IW_MAX_AP; -+ break; -+ -+#if WIRELESS_EXT > 13 -+ case SIOCGIWSCAN: -+ if (g_iscan) -+ max_tokens = wrq->u.data.length; -+ else -+ max_tokens = IW_SCAN_MAX_DATA; -+ break; -+#endif /* WIRELESS_EXT > 13 */ -+ -+ case SIOCSIWSPY: -+ token_size = sizeof(struct sockaddr); -+ max_tokens = IW_MAX_SPY; -+ break; -+ -+ case SIOCGIWSPY: -+ token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); -+ max_tokens = IW_MAX_SPY; -+ break; -+ default: -+ break; -+ } -+ -+ if (max_tokens && wrq->u.data.pointer) { -+ if (wrq->u.data.length > max_tokens) -+ return -E2BIG; -+ -+ if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) -+ return -ENOMEM; -+ -+ if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) { -+ kfree(extra); -+ return -EFAULT; -+ } -+ } -+ -+ info.cmd = cmd; -+ info.flags = 0; -+ -+ ret = handler(dev, &info, &wrq->u, extra); -+ -+ if (extra) { -+ if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) { -+ kfree(extra); -+ return -EFAULT; -+ } -+ -+ kfree(extra); -+ } -+ -+ return ret; -+} -+ -+/* Convert a connection status event into a connection status string. -+ * Returns TRUE if a matching connection status string was found. -+ */ -+bool -+wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, -+ char* stringBuf, uint buflen) -+{ -+ typedef struct conn_fail_event_map_t { -+ uint32 inEvent; /* input: event type to match */ -+ uint32 inStatus; /* input: event status code to match */ -+ uint32 inReason; /* input: event reason code to match */ -+ const char* outName; /* output: failure type */ -+ const char* outCause; /* output: failure cause */ -+ } conn_fail_event_map_t; -+ -+ /* Map of WLC_E events to connection failure strings */ -+# define WL_IW_DONT_CARE 9999 -+ const conn_fail_event_map_t event_map [] = { -+ /* inEvent inStatus inReason */ -+ /* outName outCause */ -+ {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, -+ "Conn", "Success"}, -+ {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, -+ "Conn", "NoNetworks"}, -+ {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, -+ "Conn", "ConfigMismatch"}, -+ {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, -+ "Conn", "EncrypMismatch"}, -+ {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, -+ "Conn", "RsnMismatch"}, -+ {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, -+ "Conn", "AuthTimeout"}, -+ {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, -+ "Conn", "AuthFail"}, -+ {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, -+ "Conn", "AuthNoAck"}, -+ {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, -+ "Conn", "ReassocFail"}, -+ {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, -+ "Conn", "ReassocTimeout"}, -+ {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, -+ "Conn", "ReassocAbort"}, -+ {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, -+ "Sup", "ConnSuccess"}, -+ {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, -+ "Sup", "WpaHandshakeFail"}, -+ {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, -+ "Conn", "Deauth"}, -+ {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, -+ "Conn", "DisassocInd"}, -+ {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, -+ "Conn", "Disassoc"} -+ }; -+ -+ const char* name = ""; -+ const char* cause = NULL; -+ int i; -+ -+ /* Search the event map table for a matching event */ -+ for (i = 0; i < sizeof(event_map)/sizeof(event_map[0]); i++) { -+ const conn_fail_event_map_t* row = &event_map[i]; -+ if (row->inEvent == event_type && -+ (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) && -+ (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) { -+ name = row->outName; -+ cause = row->outCause; -+ break; -+ } -+ } -+ -+ /* If found, generate a connection failure string and return TRUE */ -+ if (cause) { -+ memset(stringBuf, 0, buflen); -+ snprintf(stringBuf, buflen, "%s %s %02d %02d", -+ name, cause, status, reason); -+ AP6210_DEBUG("Connection status: %s\n", stringBuf); -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+#if (WIRELESS_EXT > 14) -+/* Check if we have received an event that indicates connection failure -+ * If so, generate a connection failure report string. -+ * The caller supplies a buffer to hold the generated string. -+ */ -+static bool -+wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) -+{ -+ uint32 event = ntoh32(e->event_type); -+ uint32 status = ntoh32(e->status); -+ uint32 reason = ntoh32(e->reason); -+ -+ if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { -+ return TRUE; -+ } else -+ { -+ return FALSE; -+ } -+} -+#endif /* WIRELESS_EXT > 14 */ -+ -+#ifndef IW_CUSTOM_MAX -+#define IW_CUSTOM_MAX 256 /* size of extra buffer used for translation of events */ -+#endif /* IW_CUSTOM_MAX */ -+ -+void -+wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) -+{ -+#if WIRELESS_EXT > 13 -+ union iwreq_data wrqu; -+ char extra[IW_CUSTOM_MAX + 1]; -+ int cmd = 0; -+ uint32 event_type = ntoh32(e->event_type); -+ uint16 flags = ntoh16(e->flags); -+ uint32 datalen = ntoh32(e->datalen); -+ uint32 status = ntoh32(e->status); -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ memset(extra, 0, sizeof(extra)); -+ -+ memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); -+ wrqu.addr.sa_family = ARPHRD_ETHER; -+ -+ switch (event_type) { -+ case WLC_E_TXFAIL: -+ cmd = IWEVTXDROP; -+ break; -+#if WIRELESS_EXT > 14 -+ case WLC_E_JOIN: -+ case WLC_E_ASSOC_IND: -+ case WLC_E_REASSOC_IND: -+ cmd = IWEVREGISTERED; -+ break; -+ case WLC_E_DEAUTH_IND: -+ case WLC_E_DISASSOC_IND: -+ cmd = SIOCGIWAP; -+ wrqu.data.length = strlen(extra); -+ bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); -+ bzero(&extra, ETHER_ADDR_LEN); -+ break; -+ -+ case WLC_E_LINK: -+ case WLC_E_NDIS_LINK: -+ cmd = SIOCGIWAP; -+ wrqu.data.length = strlen(extra); -+ if (!(flags & WLC_EVENT_MSG_LINK)) { -+ bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); -+ bzero(&extra, ETHER_ADDR_LEN); -+ } -+ break; -+ case WLC_E_ACTION_FRAME: -+ cmd = IWEVCUSTOM; -+ if (datalen + 1 <= sizeof(extra)) { -+ wrqu.data.length = datalen + 1; -+ extra[0] = WLC_E_ACTION_FRAME; -+ memcpy(&extra[1], data, datalen); -+ AP6210_DEBUG("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length); -+ } -+ break; -+ -+ case WLC_E_ACTION_FRAME_COMPLETE: -+ cmd = IWEVCUSTOM; -+ if (sizeof(status) + 1 <= sizeof(extra)) { -+ wrqu.data.length = sizeof(status) + 1; -+ extra[0] = WLC_E_ACTION_FRAME_COMPLETE; -+ memcpy(&extra[1], &status, sizeof(status)); -+ AP6210_DEBUG("wl_iw_event status %d \n", status); -+ } -+ break; -+#endif /* WIRELESS_EXT > 14 */ -+#if WIRELESS_EXT > 17 -+ case WLC_E_MIC_ERROR: { -+ struct iw_michaelmicfailure *micerrevt = (struct iw_michaelmicfailure *)&extra; -+ cmd = IWEVMICHAELMICFAILURE; -+ wrqu.data.length = sizeof(struct iw_michaelmicfailure); -+ if (flags & WLC_EVENT_MSG_GROUP) -+ micerrevt->flags |= IW_MICFAILURE_GROUP; -+ else -+ micerrevt->flags |= IW_MICFAILURE_PAIRWISE; -+ memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN); -+ micerrevt->src_addr.sa_family = ARPHRD_ETHER; -+ -+ break; -+ } -+ -+ case WLC_E_ASSOC_REQ_IE: -+ cmd = IWEVASSOCREQIE; -+ wrqu.data.length = datalen; -+ if (datalen < sizeof(extra)) -+ memcpy(extra, data, datalen); -+ break; -+ -+ case WLC_E_ASSOC_RESP_IE: -+ cmd = IWEVASSOCRESPIE; -+ wrqu.data.length = datalen; -+ if (datalen < sizeof(extra)) -+ memcpy(extra, data, datalen); -+ break; -+ -+ case WLC_E_PMKID_CACHE: { -+ struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; -+ pmkid_cand_list_t *pmkcandlist; -+ pmkid_cand_t *pmkidcand; -+ int count; -+ -+ if (data == NULL) -+ break; -+ -+ cmd = IWEVPMKIDCAND; -+ pmkcandlist = data; -+ count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); -+ wrqu.data.length = sizeof(struct iw_pmkid_cand); -+ pmkidcand = pmkcandlist->pmkid_cand; -+ while (count) { -+ bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); -+ if (pmkidcand->preauth) -+ iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; -+ bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, -+ ETHER_ADDR_LEN); -+ wireless_send_event(dev, cmd, &wrqu, extra); -+ pmkidcand++; -+ count--; -+ } -+ break; -+ } -+#endif /* WIRELESS_EXT > 17 */ -+ -+ case WLC_E_SCAN_COMPLETE: -+#if WIRELESS_EXT > 14 -+ cmd = SIOCGIWSCAN; -+#endif -+ AP6210_DEBUG("event WLC_E_SCAN_COMPLETE\n"); -+ if ((g_iscan) && (g_iscan->sysioc_pid >= 0) && -+ (g_iscan->iscan_state != ISCAN_STATE_IDLE)) -+ up(&g_iscan->sysioc_sem); -+ break; -+ -+ default: -+ /* Cannot translate event */ -+ break; -+ } -+ -+ if (cmd) { -+ if (cmd == SIOCGIWSCAN) -+ wireless_send_event(dev, cmd, &wrqu, NULL); -+ else -+ wireless_send_event(dev, cmd, &wrqu, extra); -+ } -+ -+#if WIRELESS_EXT > 14 -+ /* Look for WLC events that indicate a connection failure. -+ * If found, generate an IWEVCUSTOM event. -+ */ -+ memset(extra, 0, sizeof(extra)); -+ if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { -+ cmd = IWEVCUSTOM; -+ wrqu.data.length = strlen(extra); -+ wireless_send_event(dev, cmd, &wrqu, extra); -+ } -+#endif /* WIRELESS_EXT > 14 */ -+ -+#endif /* WIRELESS_EXT > 13 */ -+} -+ -+int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) -+{ -+ int res = 0; -+ wl_cnt_t cnt; -+ int phy_noise; -+ int rssi; -+ scb_val_t scb_val; -+ -+ phy_noise = 0; -+ if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise)))) -+ goto done; -+ -+ phy_noise = dtoh32(phy_noise); -+ AP6210_DEBUG("wl_iw_get_wireless_stats phy noise=%d\n *****", phy_noise); -+ -+ scb_val.val = 0; -+ if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) -+ goto done; -+ -+ rssi = dtoh32(scb_val.val); -+ AP6210_DEBUG("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi); -+ if (rssi <= WL_IW_RSSI_NO_SIGNAL) -+ wstats->qual.qual = 0; -+ else if (rssi <= WL_IW_RSSI_VERY_LOW) -+ wstats->qual.qual = 1; -+ else if (rssi <= WL_IW_RSSI_LOW) -+ wstats->qual.qual = 2; -+ else if (rssi <= WL_IW_RSSI_GOOD) -+ wstats->qual.qual = 3; -+ else if (rssi <= WL_IW_RSSI_VERY_GOOD) -+ wstats->qual.qual = 4; -+ else -+ wstats->qual.qual = 5; -+ -+ /* Wraps to 0 if RSSI is 0 */ -+ wstats->qual.level = 0x100 + rssi; -+ wstats->qual.noise = 0x100 + phy_noise; -+#if WIRELESS_EXT > 18 -+ wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM); -+#else -+ wstats->qual.updated |= 7; -+#endif /* WIRELESS_EXT > 18 */ -+ -+#if WIRELESS_EXT > 11 -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters=%d\n *****", (int)sizeof(wl_cnt_t)); -+ -+ memset(&cnt, 0, sizeof(wl_cnt_t)); -+ res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); -+ if (res) -+ { -+ AP6210_ERR("wl_iw_get_wireless_stats counters failed error=%d ****** \n", res); -+ goto done; -+ } -+ -+ cnt.version = dtoh16(cnt.version); -+ if (cnt.version != WL_CNT_T_VERSION) { -+ AP6210_DEBUG("\tIncorrect version of counters struct: expected %d; got %d\n", -+ WL_CNT_T_VERSION, cnt.version); -+ goto done; -+ } -+ -+ wstats->discard.nwid = 0; -+ wstats->discard.code = dtoh32(cnt.rxundec); -+ wstats->discard.fragment = dtoh32(cnt.rxfragerr); -+ wstats->discard.retries = dtoh32(cnt.txfail); -+ wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); -+ wstats->miss.beacon = 0; -+ -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", -+ dtoh32(cnt.txframe), dtoh32(cnt.txbyte)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt)); -+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant)); -+ -+#endif /* WIRELESS_EXT > 11 */ -+ -+done: -+ return res; -+} -+ -+static void -+wl_iw_timerfunc(ulong data) -+{ -+ iscan_info_t *iscan = (iscan_info_t *)data; -+ iscan->timer_on = 0; -+ if (iscan->iscan_state != ISCAN_STATE_IDLE) { -+ AP6210_DEBUG("timer trigger\n"); -+ up(&iscan->sysioc_sem); -+ } -+} -+ -+static void -+wl_iw_set_event_mask(struct net_device *dev) -+{ -+ char eventmask[WL_EVENTING_MASK_LEN]; -+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -+ -+ dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); -+ bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); -+ setbit(eventmask, WLC_E_SCAN_COMPLETE); -+ dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, -+ iovbuf, sizeof(iovbuf)); -+ -+} -+ -+static int -+wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -+{ -+ int err = 0; -+ -+ memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); -+ params->bss_type = DOT11_BSSTYPE_ANY; -+ params->scan_type = 0; -+ params->nprobes = -1; -+ params->active_time = -1; -+ params->passive_time = -1; -+ params->home_time = -1; -+ params->channel_num = 0; -+ -+ params->nprobes = htod32(params->nprobes); -+ params->active_time = htod32(params->active_time); -+ params->passive_time = htod32(params->passive_time); -+ params->home_time = htod32(params->home_time); -+ if (ssid && ssid->SSID_len) -+ memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); -+ -+ return err; -+} -+ -+static int -+wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) -+{ -+ int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); -+ wl_iscan_params_t *params; -+ int err = 0; -+ -+ if (ssid && ssid->SSID_len) { -+ params_size += sizeof(wlc_ssid_t); -+ } -+ params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); -+ if (params == NULL) { -+ return -ENOMEM; -+ } -+ memset(params, 0, params_size); -+ ASSERT(params_size < WLC_IOCTL_SMLEN); -+ -+ err = wl_iw_iscan_prep(¶ms->params, ssid); -+ -+ if (!err) { -+ params->version = htod32(ISCAN_REQ_VERSION); -+ params->action = htod16(action); -+ params->scan_duration = htod16(0); -+ -+ /* params_size += OFFSETOF(wl_iscan_params_t, params); */ -+ (void) dev_iw_iovar_setbuf(iscan->dev, "iscan", params, params_size, -+ iscan->ioctlbuf, WLC_IOCTL_SMLEN); -+ } -+ -+ kfree(params); -+ return err; -+} -+ -+static uint32 -+wl_iw_iscan_get(iscan_info_t *iscan) -+{ -+ iscan_buf_t * buf; -+ iscan_buf_t * ptr; -+ wl_iscan_results_t * list_buf; -+ wl_iscan_results_t list; -+ wl_scan_results_t *results; -+ uint32 status; -+ -+ /* buffers are allocated on demand */ -+ if (iscan->list_cur) { -+ buf = iscan->list_cur; -+ iscan->list_cur = buf->next; -+ } -+ else { -+ buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); -+ if (!buf) -+ return WL_SCAN_RESULTS_ABORTED; -+ buf->next = NULL; -+ if (!iscan->list_hdr) -+ iscan->list_hdr = buf; -+ else { -+ ptr = iscan->list_hdr; -+ while (ptr->next) { -+ ptr = ptr->next; -+ } -+ ptr->next = buf; -+ } -+ } -+ memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); -+ list_buf = (wl_iscan_results_t*)buf->iscan_buf; -+ results = &list_buf->results; -+ results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; -+ results->version = 0; -+ results->count = 0; -+ -+ memset(&list, 0, sizeof(list)); -+ list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); -+ (void) dev_iw_iovar_getbuf( -+ iscan->dev, -+ "iscanresults", -+ &list, -+ WL_ISCAN_RESULTS_FIXED_SIZE, -+ buf->iscan_buf, -+ WLC_IW_ISCAN_MAXLEN); -+ results->buflen = dtoh32(results->buflen); -+ results->version = dtoh32(results->version); -+ results->count = dtoh32(results->count); -+ AP6210_DEBUG("results->count = %d\n", results->count); -+ -+ AP6210_DEBUG("results->buflen = %d\n", results->buflen); -+ status = dtoh32(list_buf->status); -+ return status; -+} -+ -+static void wl_iw_send_scan_complete(iscan_info_t *iscan) -+{ -+ union iwreq_data wrqu; -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ /* wext expects to get no data for SIOCGIWSCAN Event */ -+ wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); -+} -+ -+static int -+_iscan_sysioc_thread(void *data) -+{ -+ uint32 status; -+ iscan_info_t *iscan = (iscan_info_t *)data; -+ -+ DAEMONIZE("iscan_sysioc"); -+ -+ status = WL_SCAN_RESULTS_PARTIAL; -+ while (down_interruptible(&iscan->sysioc_sem) == 0) { -+ if (iscan->timer_on) { -+ del_timer(&iscan->timer); -+ iscan->timer_on = 0; -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ rtnl_lock(); -+#endif -+ status = wl_iw_iscan_get(iscan); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ rtnl_unlock(); -+#endif -+ -+ switch (status) { -+ case WL_SCAN_RESULTS_PARTIAL: -+ AP6210_DEBUG("iscanresults incomplete\n"); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ rtnl_lock(); -+#endif -+ /* make sure our buffer size is enough before going next round */ -+ wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+ rtnl_unlock(); -+#endif -+ /* Reschedule the timer */ -+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); -+ add_timer(&iscan->timer); -+ iscan->timer_on = 1; -+ break; -+ case WL_SCAN_RESULTS_SUCCESS: -+ AP6210_DEBUG("iscanresults complete\n"); -+ iscan->iscan_state = ISCAN_STATE_IDLE; -+ wl_iw_send_scan_complete(iscan); -+ break; -+ case WL_SCAN_RESULTS_PENDING: -+ AP6210_DEBUG("iscanresults pending\n"); -+ /* Reschedule the timer */ -+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); -+ add_timer(&iscan->timer); -+ iscan->timer_on = 1; -+ break; -+ case WL_SCAN_RESULTS_ABORTED: -+ AP6210_DEBUG("iscanresults aborted\n"); -+ iscan->iscan_state = ISCAN_STATE_IDLE; -+ wl_iw_send_scan_complete(iscan); -+ break; -+ default: -+ AP6210_DEBUG("iscanresults returned unknown status %d\n", status); -+ break; -+ } -+ } -+ complete_and_exit(&iscan->sysioc_exited, 0); -+} -+ -+int -+wl_iw_attach(struct net_device *dev, void * dhdp) -+{ -+ iscan_info_t *iscan = NULL; -+ -+ if (!dev) -+ return 0; -+ -+ iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); -+ if (!iscan) -+ return -ENOMEM; -+ memset(iscan, 0, sizeof(iscan_info_t)); -+ iscan->sysioc_pid = -1; -+ /* we only care about main interface so save a global here */ -+ g_iscan = iscan; -+ iscan->dev = dev; -+ iscan->iscan_state = ISCAN_STATE_IDLE; -+ -+ -+ /* Set up the timer */ -+ iscan->timer_ms = 2000; -+ init_timer(&iscan->timer); -+ iscan->timer.data = (ulong)iscan; -+ iscan->timer.function = wl_iw_timerfunc; -+ -+ sema_init(&iscan->sysioc_sem, 0); -+ init_completion(&iscan->sysioc_exited); -+ iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); -+ if (iscan->sysioc_pid < 0) -+ return -ENOMEM; -+ return 0; -+} -+ -+void wl_iw_detach(void) -+{ -+ iscan_buf_t *buf; -+ iscan_info_t *iscan = g_iscan; -+ if (!iscan) -+ return; -+ if (iscan->sysioc_pid >= 0) { -+ KILL_PROC(iscan->sysioc_pid, SIGTERM); -+ wait_for_completion(&iscan->sysioc_exited); -+ } -+ -+ while (iscan->list_hdr) { -+ buf = iscan->list_hdr->next; -+ kfree(iscan->list_hdr); -+ iscan->list_hdr = buf; -+ } -+ kfree(iscan); -+ g_iscan = NULL; -+} -+ -+#endif /* USE_IW */ -diff --git a/drivers/net/wireless/ap6210/wl_iw.h b/drivers/net/wireless/ap6210/wl_iw.h -new file mode 100644 -index 0000000..c675a56 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_iw.h -@@ -0,0 +1,161 @@ -+/* -+ * Linux Wireless Extensions support -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wl_iw.h 291086 2011-10-21 01:17:24Z $ -+ */ -+ -+#ifndef _wl_iw_h_ -+#define _wl_iw_h_ -+ -+#include -+ -+#include -+#include -+#include -+ -+#define WL_SCAN_PARAMS_SSID_MAX 10 -+#define GET_SSID "SSID=" -+#define GET_CHANNEL "CH=" -+#define GET_NPROBE "NPROBE=" -+#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -+#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -+#define GET_HOME_DWELL "HOME=" -+#define GET_SCAN_TYPE "TYPE=" -+ -+#define BAND_GET_CMD "GETBAND" -+#define BAND_SET_CMD "SETBAND" -+#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -+#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -+#define SETSUSPEND_CMD "SETSUSPENDOPT" -+#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" -+/* Lin - Is the extra space needed? */ -+#define PNOSETUP_SET_CMD "PNOSETUP " /* TLV command has extra end space */ -+#define PNOENABLE_SET_CMD "PNOFORCE" -+#define PNODEBUG_SET_CMD "PNODEBUG" -+#define TXPOWER_SET_CMD "TXPOWER" -+ -+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" -+ -+/* Structure to keep global parameters */ -+typedef struct wl_iw_extra_params { -+ int target_channel; /* target channel */ -+} wl_iw_extra_params_t; -+ -+struct cntry_locales_custom { -+ char iso_abbrev[WLC_CNTRY_BUF_SZ]; /* ISO 3166-1 country abbreviation */ -+ char custom_locale[WLC_CNTRY_BUF_SZ]; /* Custom firmware locale */ -+ int32 custom_locale_rev; /* Custom local revisin default -1 */ -+}; -+/* ============================================== */ -+/* Defines from wlc_pub.h */ -+#define WL_IW_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ -+#define WL_IW_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ -+#define WL_IW_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ -+#define WL_IW_RSSI_LOW -70 /* Low quality cutoffs */ -+#define WL_IW_RSSI_GOOD -68 /* Good quality cutoffs */ -+#define WL_IW_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ -+#define WL_IW_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ -+#define WL_IW_RSSI_INVALID 0 /* invalid RSSI value */ -+#define MAX_WX_STRING 80 -+#define SSID_FMT_BUF_LEN ((4 * 32) + 1) -+#define isprint(c) bcm_isprint(c) -+#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -+#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -+#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -+#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -+#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -+#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -+#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) -+ -+#define G_SCAN_RESULTS 8*1024 -+#define WE_ADD_EVENT_FIX 0x80 -+#define G_WLAN_SET_ON 0 -+#define G_WLAN_SET_OFF 1 -+ -+ -+typedef struct wl_iw { -+ char nickname[IW_ESSID_MAX_SIZE]; -+ -+ struct iw_statistics wstats; -+ -+ int spy_num; -+ uint32 pwsec; /* pairwise wsec setting */ -+ uint32 gwsec; /* group wsec setting */ -+ bool privacy_invoked; /* IW_AUTH_PRIVACY_INVOKED setting */ -+ struct ether_addr spy_addr[IW_MAX_SPY]; -+ struct iw_quality spy_qual[IW_MAX_SPY]; -+ void *wlinfo; -+} wl_iw_t; -+ -+struct wl_ctrl { -+ struct timer_list *timer; -+ struct net_device *dev; -+ long sysioc_pid; -+ struct semaphore sysioc_sem; -+ struct completion sysioc_exited; -+}; -+ -+ -+#if WIRELESS_EXT > 12 -+#include -+extern const struct iw_handler_def wl_iw_handler_def; -+#endif /* WIRELESS_EXT > 12 */ -+ -+extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -+extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data); -+extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); -+int wl_iw_attach(struct net_device *dev, void * dhdp); -+int wl_iw_send_priv_event(struct net_device *dev, char *flag); -+ -+void wl_iw_detach(void); -+ -+#define CSCAN_COMMAND "CSCAN " -+#define CSCAN_TLV_PREFIX 'S' -+#define CSCAN_TLV_VERSION 1 -+#define CSCAN_TLV_SUBVERSION 0 -+#define CSCAN_TLV_TYPE_SSID_IE 'S' -+#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' -+#define CSCAN_TLV_TYPE_NPROBE_IE 'N' -+#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' -+#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' -+#define CSCAN_TLV_TYPE_HOME_IE 'H' -+#define CSCAN_TLV_TYPE_STYPE_IE 'T' -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ -+ iwe_stream_add_event(info, stream, ends, iwe, extra) -+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ -+ iwe_stream_add_value(info, event, value, ends, iwe, event_len) -+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ -+ iwe_stream_add_point(info, stream, ends, iwe, extra) -+#else -+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ -+ iwe_stream_add_event(stream, ends, iwe, extra) -+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ -+ iwe_stream_add_value(event, value, ends, iwe, event_len) -+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ -+ iwe_stream_add_point(stream, ends, iwe, extra) -+#endif -+ -+#endif /* _wl_iw_h_ */ -diff --git a/drivers/net/wireless/ap6210/wl_linux_mon.c b/drivers/net/wireless/ap6210/wl_linux_mon.c -new file mode 100644 -index 0000000..3210664 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wl_linux_mon.c -@@ -0,0 +1,422 @@ -+/* -+ * Broadcom Dongle Host Driver (DHD), Linux monitor network interface -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: dhd_linux_mon.c 280623 2011-08-30 14:49:39Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+typedef enum monitor_states -+{ -+ MONITOR_STATE_DEINIT = 0x0, -+ MONITOR_STATE_INIT = 0x1, -+ MONITOR_STATE_INTERFACE_ADDED = 0x2, -+ MONITOR_STATE_INTERFACE_DELETED = 0x4 -+} monitor_states_t; -+int dhd_add_monitor(char *name, struct net_device **new_ndev); -+extern int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); -+int dhd_del_monitor(struct net_device *ndev); -+int dhd_monitor_init(void *dhd_pub); -+int dhd_monitor_uninit(void); -+ -+/** -+ * Local declarations and defintions (not exposed) -+ */ -+#ifndef DHD_MAX_IFS -+#define DHD_MAX_IFS 16 -+#endif -+ -+typedef struct monitor_interface { -+ int radiotap_enabled; -+ struct net_device* real_ndev; /* The real interface that the monitor is on */ -+ struct net_device* mon_ndev; -+} monitor_interface; -+ -+typedef struct dhd_linux_monitor { -+ void *dhd_pub; -+ monitor_states_t monitor_state; -+ monitor_interface mon_if[DHD_MAX_IFS]; -+ struct mutex lock; /* lock to protect mon_if */ -+} dhd_linux_monitor_t; -+ -+static dhd_linux_monitor_t g_monitor; -+ -+static struct net_device* lookup_real_netdev(char *name); -+static monitor_interface* ndev_to_monif(struct net_device *ndev); -+static int dhd_mon_if_open(struct net_device *ndev); -+static int dhd_mon_if_stop(struct net_device *ndev); -+static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev); -+static void dhd_mon_if_set_multicast_list(struct net_device *ndev); -+static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr); -+ -+static const struct net_device_ops dhd_mon_if_ops = { -+ .ndo_open = dhd_mon_if_open, -+ .ndo_stop = dhd_mon_if_stop, -+ .ndo_start_xmit = dhd_mon_if_subif_start_xmit, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) -+ .ndo_set_rx_mode = dhd_mon_if_set_multicast_list, -+#else -+ .ndo_set_multicast_list = dhd_mon_if_set_multicast_list, -+#endif -+ .ndo_set_mac_address = dhd_mon_if_change_mac, -+}; -+ -+/** -+ * Local static function defintions -+ */ -+ -+/* Look up dhd's net device table to find a match (e.g. interface "eth0" is a match for "mon.eth0" -+ * "p2p-eth0-0" is a match for "mon.p2p-eth0-0") -+ */ -+static struct net_device* lookup_real_netdev(char *name) -+{ -+ struct net_device *ndev_found = NULL; -+ -+ int i; -+ int len = 0; -+ int last_name_len = 0; -+ struct net_device *ndev; -+ -+ /* We need to find interface "p2p-p2p-0" corresponding to monitor interface "mon-p2p-0", -+ * Once mon iface name reaches IFNAMSIZ, it is reset to p2p0-0 and corresponding mon -+ * iface would be mon-p2p0-0. -+ */ -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ ndev = dhd_idx2net(g_monitor.dhd_pub, i); -+ -+ /* Skip "p2p" and look for "-p2p0-x" in monitor interface name. If it -+ * it matches, then this netdev is the corresponding real_netdev. -+ */ -+ if (ndev && strstr(ndev->name, "p2p-p2p0")) { -+ len = strlen("p2p"); -+ } else { -+ /* if p2p- is not present, then the IFNAMSIZ have reached and name -+ * would have got reset. In this casse,look for p2p0-x in mon-p2p0-x -+ */ -+ len = 0; -+ } -+ if (ndev && strstr(name, (ndev->name + len))) { -+ if (strlen(ndev->name) > last_name_len) { -+ ndev_found = ndev; -+ last_name_len = strlen(ndev->name); -+ } -+ } -+ } -+ -+ return ndev_found; -+} -+ -+static monitor_interface* ndev_to_monif(struct net_device *ndev) -+{ -+ int i; -+ -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (g_monitor.mon_if[i].mon_ndev == ndev) -+ return &g_monitor.mon_if[i]; -+ } -+ -+ return NULL; -+} -+ -+static int dhd_mon_if_open(struct net_device *ndev) -+{ -+ int ret = 0; -+ -+ AP6210_DEBUG("enter\n"); -+ return ret; -+} -+ -+static int dhd_mon_if_stop(struct net_device *ndev) -+{ -+ int ret = 0; -+ -+ AP6210_DEBUG("enter\n"); -+ return ret; -+} -+ -+static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev) -+{ -+ int ret = 0; -+ int rtap_len; -+ int qos_len = 0; -+ int dot11_hdr_len = 24; -+ int snap_len = 6; -+ unsigned char *pdata; -+ unsigned short frame_ctl; -+ unsigned char src_mac_addr[6]; -+ unsigned char dst_mac_addr[6]; -+ struct ieee80211_hdr *dot11_hdr; -+ struct ieee80211_radiotap_header *rtap_hdr; -+ monitor_interface* mon_if; -+ -+ AP6210_DEBUG("enter\n"); -+ -+ mon_if = ndev_to_monif(ndev); -+ if (mon_if == NULL || mon_if->real_ndev == NULL) { -+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n"); -+ goto fail; -+ } -+ -+ if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) -+ goto fail; -+ -+ rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; -+ if (unlikely(rtap_hdr->it_version)) -+ goto fail; -+ -+ rtap_len = ieee80211_get_radiotap_len(skb->data); -+ if (unlikely(skb->len < rtap_len)) -+ goto fail; -+ -+ AP6210_DEBUG("radiotap len (should be 14): %d\n", rtap_len); -+ -+ /* Skip the ratio tap header */ -+ skb_pull(skb, rtap_len); -+ -+ dot11_hdr = (struct ieee80211_hdr *)skb->data; -+ frame_ctl = le16_to_cpu(dot11_hdr->frame_control); -+ /* Check if the QoS bit is set */ -+ if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { -+ /* Check if this ia a Wireless Distribution System (WDS) frame -+ * which has 4 MAC addresses -+ */ -+ if (dot11_hdr->frame_control & 0x0080) -+ qos_len = 2; -+ if ((dot11_hdr->frame_control & 0x0300) == 0x0300) -+ dot11_hdr_len += 6; -+ -+ memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr)); -+ memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr)); -+ -+ /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for -+ * for two MAC addresses -+ */ -+ skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2); -+ pdata = (unsigned char*)skb->data; -+ memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr)); -+ memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr)); -+ PKTSETPRIO(skb, 0); -+ -+ AP6210_DEBUG("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name); -+ -+ /* Use the real net device to transmit the packet */ -+ ret = dhd_start_xmit(skb, mon_if->real_ndev); -+ -+ return ret; -+ } -+fail: -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+static void dhd_mon_if_set_multicast_list(struct net_device *ndev) -+{ -+ monitor_interface* mon_if; -+ -+ mon_if = ndev_to_monif(ndev); -+ if (mon_if == NULL || mon_if->real_ndev == NULL) { -+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n"); -+ } else { -+ AP6210_DEBUG("enter, if name: %s, matched if name %s\n", -+ ndev->name, mon_if->real_ndev->name); -+ } -+} -+ -+static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr) -+{ -+ int ret = 0; -+ monitor_interface* mon_if; -+ -+ mon_if = ndev_to_monif(ndev); -+ if (mon_if == NULL || mon_if->real_ndev == NULL) { -+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n"); -+ } else { -+ AP6210_DEBUG("enter, if name: %s, matched if name %s\n", -+ ndev->name, mon_if->real_ndev->name); -+ } -+ return ret; -+} -+ -+/** -+ * Global function definitions (declared in dhd_linux_mon.h) -+ */ -+ -+int dhd_add_monitor(char *name, struct net_device **new_ndev) -+{ -+ int i; -+ int idx = -1; -+ int ret = 0; -+ struct net_device* ndev = NULL; -+ dhd_linux_monitor_t **dhd_mon; -+ -+ mutex_lock(&g_monitor.lock); -+ -+ AP6210_DEBUG("enter, if name: %s\n", name); -+ if (!name || !new_ndev) { -+ AP6210_DEBUG("invalid parameters\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* -+ * Find a vacancy -+ */ -+ for (i = 0; i < DHD_MAX_IFS; i++) -+ if (g_monitor.mon_if[i].mon_ndev == NULL) { -+ idx = i; -+ break; -+ } -+ if (idx == -1) { -+ AP6210_DEBUG("exceeds maximum interfaces\n"); -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ ndev = alloc_etherdev(sizeof(dhd_linux_monitor_t*)); -+ if (!ndev) { -+ AP6210_DEBUG("failed to allocate memory\n"); -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ndev->type = ARPHRD_IEEE80211_RADIOTAP; -+ strncpy(ndev->name, name, IFNAMSIZ); -+ ndev->name[IFNAMSIZ - 1] = 0; -+ ndev->netdev_ops = &dhd_mon_if_ops; -+ -+ ret = register_netdevice(ndev); -+ if (ret) { -+ AP6210_DEBUG(" register_netdevice failed (%d)\n", ret); -+ goto out; -+ } -+ -+ *new_ndev = ndev; -+ g_monitor.mon_if[idx].radiotap_enabled = TRUE; -+ g_monitor.mon_if[idx].mon_ndev = ndev; -+ g_monitor.mon_if[idx].real_ndev = lookup_real_netdev(name); -+ dhd_mon = (dhd_linux_monitor_t **)netdev_priv(ndev); -+ *dhd_mon = &g_monitor; -+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_ADDED; -+ AP6210_DEBUG("net device returned: 0x%p\n", ndev); -+ AP6210_DEBUG("found a matched net device, name %s\n", g_monitor.mon_if[idx].real_ndev->name); -+ -+out: -+ if (ret && ndev) -+ free_netdev(ndev); -+ -+ mutex_unlock(&g_monitor.lock); -+ return ret; -+ -+} -+ -+int dhd_del_monitor(struct net_device *ndev) -+{ -+ int i; -+ bool rollback_lock = false; -+ if (!ndev) -+ return -EINVAL; -+ mutex_lock(&g_monitor.lock); -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ if (g_monitor.mon_if[i].mon_ndev == ndev || -+ g_monitor.mon_if[i].real_ndev == ndev) { -+ g_monitor.mon_if[i].real_ndev = NULL; -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = true; -+ } -+ unregister_netdev(g_monitor.mon_if[i].mon_ndev); -+ free_netdev(g_monitor.mon_if[i].mon_ndev); -+ g_monitor.mon_if[i].mon_ndev = NULL; -+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_DELETED; -+ break; -+ } -+ } -+ if (rollback_lock) { -+ rtnl_lock(); -+ rollback_lock = false; -+ } -+ -+ if (g_monitor.monitor_state != -+ MONITOR_STATE_INTERFACE_DELETED) -+ AP6210_DEBUG("interface not found in monitor IF array, is this a monitor IF? 0x%p\n", -+ ndev); -+ mutex_unlock(&g_monitor.lock); -+ -+ return 0; -+} -+ -+int dhd_monitor_init(void *dhd_pub) -+{ -+ if (g_monitor.monitor_state == MONITOR_STATE_DEINIT) { -+ g_monitor.dhd_pub = dhd_pub; -+ mutex_init(&g_monitor.lock); -+ g_monitor.monitor_state = MONITOR_STATE_INIT; -+ } -+ return 0; -+} -+ -+int dhd_monitor_uninit(void) -+{ -+ int i; -+ struct net_device *ndev; -+ bool rollback_lock = false; -+ mutex_lock(&g_monitor.lock); -+ if (g_monitor.monitor_state != MONITOR_STATE_DEINIT) { -+ for (i = 0; i < DHD_MAX_IFS; i++) { -+ ndev = g_monitor.mon_if[i].mon_ndev; -+ if (ndev) { -+ if (rtnl_is_locked()) { -+ rtnl_unlock(); -+ rollback_lock = true; -+ } -+ unregister_netdev(ndev); -+ free_netdev(ndev); -+ g_monitor.mon_if[i].real_ndev = NULL; -+ g_monitor.mon_if[i].mon_ndev = NULL; -+ if (rollback_lock) { -+ rtnl_lock(); -+ rollback_lock = false; -+ } -+ } -+ } -+ g_monitor.monitor_state = MONITOR_STATE_DEINIT; -+ } -+ mutex_unlock(&g_monitor.lock); -+ return 0; -+} -diff --git a/drivers/net/wireless/ap6210/wldev_common.c b/drivers/net/wireless/ap6210/wldev_common.c -new file mode 100644 -index 0000000..596e448 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wldev_common.c -@@ -0,0 +1,374 @@ -+/* -+ * Common function shared by Linux WEXT, cfg80211 and p2p drivers -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wldev_common.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+ -+#define htod32(i) i -+#define htod16(i) i -+#define dtoh32(i) i -+#define dtoh16(i) i -+#define htodchanspec(i) i -+#define dtohchanspec(i) i -+ -+extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd); -+ -+s32 wldev_ioctl( -+ struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set) -+{ -+ s32 ret = 0; -+ struct wl_ioctl ioc; -+ -+ -+ memset(&ioc, 0, sizeof(ioc)); -+ ioc.cmd = cmd; -+ ioc.buf = arg; -+ ioc.len = len; -+ ioc.set = set; -+ -+ ret = dhd_ioctl_entry_local(dev, &ioc, cmd); -+ -+ return ret; -+} -+ -+/* Format a iovar buffer, not bsscfg indexed. The bsscfg index will be -+ * taken care of in dhd_ioctl_entry. Internal use only, not exposed to -+ * wl_iw, wl_cfg80211 and wl_cfgp2p -+ */ -+static s32 wldev_mkiovar( -+ s8 *iovar_name, s8 *param, s32 paramlen, -+ s8 *iovar_buf, u32 buflen) -+{ -+ s32 iolen = 0; -+ -+ iolen = bcm_mkiovar(iovar_name, param, paramlen, iovar_buf, buflen); -+ return iolen; -+} -+ -+s32 wldev_iovar_getbuf( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -+{ -+ s32 ret = 0; -+ if (buf_sync) { -+ mutex_lock(buf_sync); -+ } -+ wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); -+ ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); -+ if (buf_sync) -+ mutex_unlock(buf_sync); -+ return ret; -+} -+ -+ -+s32 wldev_iovar_setbuf( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -+{ -+ s32 ret = 0; -+ s32 iovar_len; -+ if (buf_sync) { -+ mutex_lock(buf_sync); -+ } -+ iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); -+ if (iovar_len > 0) -+ ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); -+ else -+ ret = BCME_BUFTOOSHORT; -+ if (buf_sync) -+ mutex_unlock(buf_sync); -+ return ret; -+} -+ -+s32 wldev_iovar_setint( -+ struct net_device *dev, s8 *iovar, s32 val) -+{ -+ s8 iovar_buf[WLC_IOCTL_SMLEN]; -+ -+ val = htod32(val); -+ memset(iovar_buf, 0, sizeof(iovar_buf)); -+ return wldev_iovar_setbuf(dev, iovar, &val, sizeof(val), iovar_buf, -+ sizeof(iovar_buf), NULL); -+} -+ -+ -+s32 wldev_iovar_getint( -+ struct net_device *dev, s8 *iovar, s32 *pval) -+{ -+ s8 iovar_buf[WLC_IOCTL_SMLEN]; -+ s32 err; -+ -+ memset(iovar_buf, 0, sizeof(iovar_buf)); -+ err = wldev_iovar_getbuf(dev, iovar, pval, sizeof(*pval), iovar_buf, -+ sizeof(iovar_buf), NULL); -+ if (err == 0) -+ { -+ memcpy(pval, iovar_buf, sizeof(*pval)); -+ *pval = dtoh32(*pval); -+ } -+ return err; -+} -+ -+/** Format a bsscfg indexed iovar buffer. The bsscfg index will be -+ * taken care of in dhd_ioctl_entry. Internal use only, not exposed to -+ * wl_iw, wl_cfg80211 and wl_cfgp2p -+ */ -+s32 wldev_mkiovar_bsscfg( -+ const s8 *iovar_name, s8 *param, s32 paramlen, -+ s8 *iovar_buf, s32 buflen, s32 bssidx) -+{ -+ const s8 *prefix = "bsscfg:"; -+ s8 *p; -+ u32 prefixlen; -+ u32 namelen; -+ u32 iolen; -+ -+ if (bssidx == 0) { -+ return wldev_mkiovar((s8*)iovar_name, (s8 *)param, paramlen, -+ (s8 *) iovar_buf, buflen); -+ } -+ -+ prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */ -+ namelen = (u32) strlen(iovar_name) + 1; /* lengh of iovar name + null */ -+ iolen = prefixlen + namelen + sizeof(u32) + paramlen; -+ -+ if (buflen < 0 || iolen > (u32)buflen) -+ { -+ AP6210_ERR("%s: buffer is too short\n", __FUNCTION__); -+ return BCME_BUFTOOSHORT; -+ } -+ -+ p = (s8 *)iovar_buf; -+ -+ /* copy prefix, no null */ -+ memcpy(p, prefix, prefixlen); -+ p += prefixlen; -+ -+ /* copy iovar name including null */ -+ memcpy(p, iovar_name, namelen); -+ p += namelen; -+ -+ /* bss config index as first param */ -+ bssidx = htod32(bssidx); -+ memcpy(p, &bssidx, sizeof(u32)); -+ p += sizeof(u32); -+ -+ /* parameter buffer follows */ -+ if (paramlen) -+ memcpy(p, param, paramlen); -+ -+ return iolen; -+ -+} -+ -+s32 wldev_iovar_getbuf_bsscfg( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -+{ -+ s32 ret = 0; -+ if (buf_sync) { -+ mutex_lock(buf_sync); -+ } -+ -+ wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); -+ ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); -+ if (buf_sync) { -+ mutex_unlock(buf_sync); -+ } -+ return ret; -+ -+} -+ -+s32 wldev_iovar_setbuf_bsscfg( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -+{ -+ s32 ret = 0; -+ s32 iovar_len; -+ if (buf_sync) { -+ mutex_lock(buf_sync); -+ } -+ iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); -+ if (iovar_len > 0) -+ ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); -+ else { -+ ret = BCME_BUFTOOSHORT; -+ } -+ -+ if (buf_sync) { -+ mutex_unlock(buf_sync); -+ } -+ return ret; -+} -+ -+s32 wldev_iovar_setint_bsscfg( -+ struct net_device *dev, s8 *iovar, s32 val, s32 bssidx) -+{ -+ s8 iovar_buf[WLC_IOCTL_SMLEN]; -+ -+ val = htod32(val); -+ memset(iovar_buf, 0, sizeof(iovar_buf)); -+ return wldev_iovar_setbuf_bsscfg(dev, iovar, &val, sizeof(val), iovar_buf, -+ sizeof(iovar_buf), bssidx, NULL); -+} -+ -+ -+s32 wldev_iovar_getint_bsscfg( -+ struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx) -+{ -+ s8 iovar_buf[WLC_IOCTL_SMLEN]; -+ s32 err; -+ -+ memset(iovar_buf, 0, sizeof(iovar_buf)); -+ err = wldev_iovar_getbuf_bsscfg(dev, iovar, pval, sizeof(*pval), iovar_buf, -+ sizeof(iovar_buf), bssidx, NULL); -+ if (err == 0) -+ { -+ memcpy(pval, iovar_buf, sizeof(*pval)); -+ *pval = dtoh32(*pval); -+ } -+ return err; -+} -+ -+int wldev_get_link_speed( -+ struct net_device *dev, int *plink_speed) -+{ -+ int error; -+ -+ if (!plink_speed) -+ return -ENOMEM; -+ error = wldev_ioctl(dev, WLC_GET_RATE, plink_speed, sizeof(int), 0); -+ if (unlikely(error)) -+ return error; -+ -+ /* Convert internal 500Kbps to Kbps */ -+ *plink_speed *= 500; -+ return error; -+} -+ -+int wldev_get_rssi( -+ struct net_device *dev, int *prssi) -+{ -+ scb_val_t scb_val; -+ int error; -+ -+ if (!prssi) -+ return -ENOMEM; -+ bzero(&scb_val, sizeof(scb_val_t)); -+ -+ error = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0); -+ if (unlikely(error)) -+ return error; -+ -+ *prssi = dtoh32(scb_val.val); -+ return error; -+} -+ -+int wldev_get_ssid( -+ struct net_device *dev, wlc_ssid_t *pssid) -+{ -+ int error; -+ -+ if (!pssid) -+ return -ENOMEM; -+ error = wldev_ioctl(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t), 0); -+ if (unlikely(error)) -+ return error; -+ pssid->SSID_len = dtoh32(pssid->SSID_len); -+ return error; -+} -+ -+int wldev_get_band( -+ struct net_device *dev, uint *pband) -+{ -+ int error; -+ -+ error = wldev_ioctl(dev, WLC_GET_BAND, pband, sizeof(uint), 0); -+ return error; -+} -+ -+int wldev_set_band( -+ struct net_device *dev, uint band) -+{ -+ int error = -1; -+ -+ if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { -+ error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true); -+ if (!error) -+ dhd_bus_band_set(dev, band); -+ } -+ return error; -+} -+ -+int wldev_set_country( -+ struct net_device *dev, char *country_code) -+{ -+ int error = -1; -+ wl_country_t cspec = {{0}, 0, {0}}; -+ scb_val_t scbval; -+ char smbuf[WLC_IOCTL_SMLEN]; -+ -+ if (!country_code) -+ return error; -+ -+ error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), -+ smbuf, sizeof(smbuf), NULL); -+ if (error < 0) -+ AP6210_ERR("%s: get country failed = %d\n", __FUNCTION__, error); -+ -+ if ((error < 0) || -+ (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) { -+ bzero(&scbval, sizeof(scb_val_t)); -+ error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true); -+ if (error < 0) { -+ AP6210_ERR("%s: set country failed due to Disassoc error %d\n", -+ __FUNCTION__, error); -+ return error; -+ } -+ cspec.rev = -1; -+ memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); -+ memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); -+ get_customized_country_code((char *)&cspec.country_abbrev, &cspec); -+ error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec), -+ smbuf, sizeof(smbuf), NULL); -+ if (error < 0) { -+ AP6210_ERR("%s: set country for %s as %s rev %d failed\n", -+ __FUNCTION__, country_code, cspec.ccode, cspec.rev); -+ return error; -+ } -+ dhd_bus_country_set(dev, &cspec); -+ AP6210_ERR("%s: set country for %s as %s rev %d\n", -+ __FUNCTION__, country_code, cspec.ccode, cspec.rev); -+ } -+ return 0; -+} -diff --git a/drivers/net/wireless/ap6210/wldev_common.h b/drivers/net/wireless/ap6210/wldev_common.h -new file mode 100644 -index 0000000..f9bf425 ---- /dev/null -+++ b/drivers/net/wireless/ap6210/wldev_common.h -@@ -0,0 +1,111 @@ -+/* -+ * Common function shared by Linux WEXT, cfg80211 and p2p drivers -+ * -+ * Copyright (C) 1999-2012, Broadcom Corporation -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2 (the "GPL"), -+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the -+ * following added to such license: -+ * -+ * As a special exception, the copyright holders of this software give you -+ * permission to link this software with independent modules, and to copy and -+ * distribute the resulting executable under terms of your choice, provided that -+ * you also meet, for each linked independent module, the terms and conditions of -+ * the license of that module. An independent module is a module which is not -+ * derived from this software. The special exception does not apply to any -+ * modifications of the software. -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a license -+ * other than the GPL, without Broadcom's express prior written consent. -+ * -+ * $Id: wldev_common.h,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ -+ */ -+#ifndef __WLDEV_COMMON_H__ -+#define __WLDEV_COMMON_H__ -+ -+#include -+ -+/* wl_dev_ioctl - get/set IOCTLs, will call net_device's do_ioctl (or -+ * netdev_ops->ndo_do_ioctl in new kernels) -+ * @dev: the net_device handle -+ */ -+s32 wldev_ioctl( -+ struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set); -+ -+/** Retrieve named IOVARs, this function calls wl_dev_ioctl with -+ * WLC_GET_VAR IOCTL code -+ */ -+s32 wldev_iovar_getbuf( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync); -+ -+/** Set named IOVARs, this function calls wl_dev_ioctl with -+ * WLC_SET_VAR IOCTL code -+ */ -+s32 wldev_iovar_setbuf( -+ struct net_device *dev, s8 *iovar_name, -+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync); -+ -+s32 wldev_iovar_setint( -+ struct net_device *dev, s8 *iovar, s32 val); -+ -+s32 wldev_iovar_getint( -+ struct net_device *dev, s8 *iovar, s32 *pval); -+ -+/** The following function can be implemented if there is a need for bsscfg -+ * indexed IOVARs -+ */ -+ -+s32 wldev_mkiovar_bsscfg( -+ const s8 *iovar_name, s8 *param, s32 paramlen, -+ s8 *iovar_buf, s32 buflen, s32 bssidx); -+ -+/** Retrieve named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with -+ * WLC_GET_VAR IOCTL code -+ */ -+s32 wldev_iovar_getbuf_bsscfg( -+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen, -+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync); -+ -+/** Set named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with -+ * WLC_SET_VAR IOCTL code -+ */ -+s32 wldev_iovar_setbuf_bsscfg( -+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen, -+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync); -+ -+s32 wldev_iovar_getint_bsscfg( -+ struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx); -+ -+s32 wldev_iovar_setint_bsscfg( -+ struct net_device *dev, s8 *iovar, s32 val, s32 bssidx); -+ -+extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); -+extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); -+extern void dhd_bus_band_set(struct net_device *dev, uint band); -+extern int wldev_set_country(struct net_device *dev, char *country_code); -+extern int net_os_wake_lock(struct net_device *dev); -+extern int net_os_wake_unlock(struct net_device *dev); -+extern int net_os_wake_lock_timeout(struct net_device *dev); -+extern int net_os_wake_lock_timeout_enable(struct net_device *dev, int val); -+extern int net_os_set_dtim_skip(struct net_device *dev, int val); -+extern int net_os_set_suspend_disable(struct net_device *dev, int val); -+extern int net_os_set_suspend(struct net_device *dev, int val, int force); -+extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, -+ int max, int *bytes_left); -+ -+/* Get the link speed from dongle, speed is in kpbs */ -+int wldev_get_link_speed(struct net_device *dev, int *plink_speed); -+ -+int wldev_get_rssi(struct net_device *dev, int *prssi); -+ -+int wldev_get_ssid(struct net_device *dev, wlc_ssid_t *pssid); -+ -+int wldev_get_band(struct net_device *dev, uint *pband); -+ -+int wldev_set_band(struct net_device *dev, uint band); -+ -+#endif /* __WLDEV_COMMON_H__ */ -diff --git a/firmware/Makefile b/firmware/Makefile -index 0d15a3d..934cd24 100644 ---- a/firmware/Makefile -+++ b/firmware/Makefile -@@ -109,6 +109,10 @@ fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ - fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \ - kaweth/new_code_fix.bin \ - kaweth/trigger_code_fix.bin -+fw-shipped-$(CONFIG_AP6210) += ap6210/bcm20710a1.hcd ap6210/fw_bcm40181a2.bin \ -+ ap6210/fw_bcm40181a2_apsta.bin \ -+ ap6210/fw_bcm40181a2_p2p.bin \ -+ ap6210/nvram_ap6210.txt - ifdef CONFIG_FIRMWARE_IN_KERNEL - fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw - fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw -diff --git a/firmware/ap6210/bcm20710a1.hcd.ihex b/firmware/ap6210/bcm20710a1.hcd.ihex -new file mode 100644 -index 0000000..28e8935 ---- /dev/null -+++ b/firmware/ap6210/bcm20710a1.hcd.ihex -@@ -0,0 +1,1665 @@ -+:100000004CFC2C00000900010800EEC4EC420790F3 -+:100010006524FD0400FFFFFFFF4006000000A00272 -+:100020007020020A00280009000000000000004CB7 -+:10003000FCFF2800090041290042434D323037308F -+:100040003241312047656E657269632055415254D3 -+:1000500020436C61737320312040203236204D489C -+:100060007A0069020000005D0C000A64E6B000003E -+:100070008898425A33435F09003C28010004000479 -+:10008000F70C0A6F0098160800C600F3025D0066C0 -+:10009000033000C900E10268005C033600C300E2DF -+:1000A000026A0053033C00C200E1026C004E0341AF -+:1000B00000C500D60272004A034300C300CE027995 -+:1000C0000042034800C500C00283003A034E00C846 -+:1000D00000BF0282003B034E00C900BC028400370F -+:1000E0000352000808070707070707060606060564 -+:1000F00005050502C0680194FC0E00FFFF000066C4 -+:1001000002000030FC0E00FFFF0F0063040000003F -+:10011000FD0E00FFFF0F006802000088FC0E00FFCC -+:10012000FF0000000400002CFC0E00FFFF0000494F -+:10013000044CFCFF23010900000070FC0E00FFFFCF -+:1001400000000B09000074FC0E00FFFF00002E01F0 -+:100150000000D8FF0E00FFFF000062190000D0FC75 -+:100160000E00FFFF000020C90000C8FC0E00FFFFCA -+:10017000000038850000DCFC0E00FFFF00001CC8FA -+:100180000000CCFD0E00FFFF0000048000005CFCBE -+:100190000E00FFFF00000200000020FC0E00FFFF29 -+:1001A000000019210000E0FC0E00008000000000AB -+:1001B0000000C0FC0E00FFFF000022000000948F32 -+:1001C0000800FFFFFFFF00120012988F0800FFFFDA -+:1001D0000000001200009C8F080000FFFFFF0009D4 -+:1001E0000909CCFC0E00FFFF00002B450000780041 -+:1001F0000F00FFFFFFFF0D08090968000F00FF0057 -+:10020000FFFF0D000D0D6C000F00FF00FFFF0D0044 -+:100210000D0D90000F00000000FF000000800C0199 -+:100220000F000000FFFF0000080888000F00F0002A -+:100230000000804CFCFF1E0209000000002C010F92 -+:1002400000FF0000000700000024010F0000000074 -+:10025000FF0000000530010F0000FF000000080053 -+:100260000020010F00000000FF00000006D07B000E -+:1002700001040A08FC0E00FFFF00002E3600000CEF -+:10028000FC0E00FFFF00002CAE000010FC0E00FF73 -+:10029000FF00002AAC000014FC0E00FFFF0000A2CB -+:1002A00022000018FC0E00FFFF00001D2000001CB3 -+:1002B000FC0E00FFFF00000D15000020FC0E00FFEB -+:1002C000FF0000858D000024FC0E00FFFF0000836E -+:1002D00011000028FC0E00FFFF0000000100009844 -+:1002E000FF0E00FFFF00003E410000C31600126930 -+:1002F0001419310870047836042430607180764A0D -+:100300003108290A6F210002301905CB000000BA1C -+:10031000147F7100A700000092000000001400008C -+:1003200000000000000000000A0800F40A080000B5 -+:1003300001000058014CFCFF19030900001FCF0900 -+:1003400000100F0C6EF0B009F060D1090001040339 -+:10035000036B1420206B1A2400FF0108080A1306FF -+:1003600011020FFE0DFA0BF609F207EE050A13064D -+:1003700011020FFE0DFA0BF609F207EE050301005C -+:100380000182D600040602020A233C5A6E7D8000D8 -+:100390008000800080008000800080028002800257 -+:1003A00080028002800214FF20880AFF61000000A2 -+:1003B0000000000000000000000014FF20820AFF7F -+:1003C000610000000000000000000000000014FFB9 -+:1003D00020000AFF61000000000000000000000093 -+:1003E000000014FF20080AFF610000000000000068 -+:1003F00000000000000014FF200B0AFF6100000055 -+:100400000000000000000000000014FF20100AFFA0 -+:10041000610000000000000000000000000040FF3C -+:10042000FF68027B0000000040FFFF68027B0000C5 -+:10043000000040FFFF68024CFCFF140409007B0031 -+:1004400000000040FFFF68027B0000000040FFFF4B -+:1004500069027B0000000040FFFF69027B00000092 -+:100460000082D600FF0602020A233C5A6E7D8000FD -+:100470008000800080008000800080028002800276 -+:1004800080028002800214FF19880AFF2000000009 -+:100490000000000000000000000014FF19820AFFA5 -+:1004A000430000000000000000000000000014FFF6 -+:1004B00019000AFF660000000000000000000000B4 -+:1004C000000014FF19080AFF660000000000000089 -+:1004D00000000000000014FF190B0AFF4300000099 -+:1004E0000000000000000000000014FF19100AFFC7 -+:1004F000200000000000000000000000000041009B -+:100500000000007B0000000041000000007B0000B4 -+:10051000000041000000007B0000000041000000DE -+:10052000007B0000000041000000007B0000000094 -+:1005300041000000007B0000004CFCFF0F0509009B -+:100540000086120004130040080000401300010060 -+:100550000180FF000113C15E007CCB1E85B47CCB03 -+:100560001E85B42604B104B204B304B404B504B6C1 -+:1005700004B704B804B904BA04BB04BC04BD04BE87 -+:1005800004BF04C004C104C204C304C404C504C637 -+:1005900004C704C804C904CA04CB04CC04CD04CEE7 -+:1005A00004CF04D004D104D204D304D404D504D697 -+:1005B00004D704D8280C000B04000E4C09000B04CF -+:1005C00000E44C09000B0400524E0900082500000D -+:1005D000B0DB010078F01EFC1600F0630900281C57 -+:1005E000FEF733FF281C5F3000210170391C321DDB -+:1005F00087F7D7FB080F000184E0000030BD00B58D -+:100600000000000000000817000288E0000087F0EA -+:1006100048F908001C53090000F002F800BD000072 -+:10062000081D0003C46200008FF059FB0E007A59C8 -+:10063000090001B4FFF769FF01BC704CFCFF0A061A -+:100640000900F7A9FC000008150004586600008F97 -+:10065000F08CF9060074590900FFF796FF30BD0BC6 -+:1006600004001A5B09000B0400445B090008150034 -+:1006700005C08400008DF000FE0600C4600900FF84 -+:10068000F7A6FF30BD082D0006B47702006EF08992 -+:10069000FC1E00CA60090002B461684907C90F3036 -+:1006A0001C91F7F5FC02BC002902D0F06991F76AB1 -+:1006B000FB91F76CFB080F000724B500000FE0C0AA -+:1006C00046000000000000080F0008C44F000010A2 -+:1006D000E0C046000000000000086700091CF003AD -+:1006E0000057F064F85800E860090070B5061C0C6B -+:1006F0001C151C002B21D104A8008840281DD10501 -+:10070000A80088202819D15A2917D8081C15D00408 -+:10071000F0BEF8002811D1032D0FD02204121408C6 -+:10072000210748002304F0BBF8002806D1221C2929 -+:100730001C301CA9F733F8012000E000204CFCFF1E -+:100740000507090070BD18650800080F000A9880A9 -+:1007500000005808042B0000000000000817000BE0 -+:10076000680C040055F06AFA08004061090000F0C6 -+:1007700002F870BD00000819000C64D4000088F075 -+:10078000EEFE0A0044620900281CFEF7E3FF77F73B -+:1007900020F90813000D08D6000088F021FE04009F -+:1007A0004E62090077F7DEF9080F000E80DA0000CC -+:1007B000C046C0460000000000000815000F24528B -+:1007C000000091F015F806005262090000F001F8EF -+:1007D000F0BD0B0400B463090008190010845C022A -+:1007E0000070F0BFFB0A00066409009B005859EF37 -+:1007F000188FF73CFC0817001164F8000086F0D44D -+:10080000FD08001064090000F002F8F0BD000008C7 -+:100810001700123CF5000086F0D4FF0800E86409D8 -+:100820000000F002F830BD0000082F0013C4F601EC -+:100830000076F04EFF200064650900054B30B44C93 -+:10084000FCFF00080900054CE57949190C06211642 -+:1008500030BC195489F7A7F8C046903408008C03BF -+:10086000080008170014487C02006EF09CFC080089 -+:100870008465090000F002F870BD0000082B001527 -+:10088000D4BA00008AF092FD1C00FC6509000AB48D -+:10089000201C311C00F009F80ABC012803D0042BED -+:1008A00001D175F762FA75F763FA081F00162CF08C -+:1008B000000087F001FB10003266090001B483F7E5 -+:1008C0003FFC01BC00F024F878F7F7FC082500177E -+:1008D000E4A203005CF0ADF91600426609000028AE -+:1008E00006D100F007F8002802D10120A3F774FE1A -+:1008F000A3F74AFE08170018C06A02006FF0EAFD6D -+:1009000008009866090000F002F830BD00000823D6 -+:100910000019C47202006FF088FA1400D867090049 -+:1009200008B4301C0122012300F004F808BC90F741 -+:1009300071FD0000920600A3008000141908170042 -+:100940001A4CFCFFFB0809002848020072F09AF8D4 -+:1009500008006069090000F069FA8DF7BDFF08170B -+:10096000001BB473020070F0FAFC0800AC7D0900B3 -+:10097000FFF75DFE8FF791FB080F001C34C40100E8 -+:10098000C046201C0000000000000817001D24477E -+:10099000020072F020F908006869090000F0F7F918 -+:1009A0008DF7EFFE0817001E6847020072F002F98B -+:1009B00008007069090000F009FA8DF707FF0817B1 -+:1009C000001F0C4D020071F034FE08007869090028 -+:1009D00000F099FA8EF7DEF908170020404D02006A -+:1009E00071F01EFE08008069090000F0AFFA8EF772 -+:1009F000F8F9081700217C4D020071F004FE080090 -+:100A00008869090000F007FC8EF70CFA081700222D -+:100A10007854020072F088FC08008C7D0900FFF712 -+:100A200058FD8DF783FB081700230C57020072F066 -+:100A300042FB0800947D0900FFF7B4FD8DF706FD29 -+:100A40000819004CFCFFF6090900244472010080DB -+:100A5000F0A3FF0A008E810900FFF7F5FF7FF75A28 -+:100A6000F80000081700254C58020072F0A6FA089A -+:100A7000009C7D0900FFF724FF8DF76DFE0817002D -+:100A8000265C46020073F0AAFB0800B47D0900FE54 -+:100A9000F774FE8CF75FFC081700270865010080DB -+:100AA000F042FA08009069090000F0FDFD7FF7D2DE -+:100AB000FD0817002834AE01007DF076FA08002406 -+:100AC00083090002B0FFF757FF70BD08170029081F -+:100AD0006E000090F0CCFF0800A47D0900FFF7F93C -+:100AE000FD6FF76AF8087F012AA444000094F04AD9 -+:100AF000F870013C85090000B528490B6826490BB0 -+:100B00006024490B6822490B601E490B682D490B74 -+:100B100060434B43490B6034490B680120C0030319 -+:100B2000430B6040490B78002B04D02F490B6840E1 -+:100B30000303430B602D4A13685B085B0013603AA4 -+:100B40004B3B4A13604CFCFFF10A0900B0F7E6FE8C -+:100B5000B1F70FFBB1F75EFEB2F704F80D2136488E -+:100B600001F0A5FE364A9068002803D099F70FF8E7 -+:100B7000B0F7ABFD2448244A11684160244A60E084 -+:100B8000C046C0B00800FFF2011A48A50900848FD2 -+:100B9000B002D08B0E00A0800E004CA50900148B73 -+:100BA0000E0050A509006CE5050054A509008C1540 -+:100BB000080023840900538409002D850900A984B5 -+:100BC0000900158509005C000F0094830E00FF00EA -+:100BD000FFFF608B0E0040230001E08A0E00E02C36 -+:100BE0000800A4860E0088B2080005000080850079 -+:100BF00000801C800E0014800E00848F0800048387 -+:100C00000E00108B0E00C8FC0E00C42C0800CC2C6B -+:100C10000800D02C0800C82C0800D42C0800D4FFF1 -+:100C20000E00BC8B0E00AD020000CC8B0E001CCD64 -+:100C3000080010325476D48B0E00009D0800ECCCD6 -+:100C4000080011684161054CFCFFEC0B09004A11DA -+:100C5000688160054A13680360044A1368044A13F4 -+:100C60006000BDC046D02C0800C82C0800D42C0859 -+:100C700000D4FF0E000861002B0044000093F094A4 -+:100C8000FF52002C83090010B5A448002383700490 -+:100C900023437001230370A14BA2480360A24BA21F -+:100CA0004C2360A24C2368A24C2360A24C2368A270 -+:100CB0004C23602C22A249A248BCF711FBA148A1F9 -+:100CC0004C2060A149C160A1494162A1490161A1D3 -+:100CD0004B8361A14BC36110BD080F002CD0B80439 -+:100CE00000A5F809E00000000000000817002D2012 -+:100CF000BA04004DF09CF808005C8B0900FFF7D4A3 -+:100D0000FF30BD00000817002E3069040052F020AB -+:100D1000FA0800748D0900FFF7C4FFADF7F8FD086D -+:100D200019002F545D040053F012F80A007C8D095D -+:100D300000B4F770F8FFF7B2FF30BD08190030E0DB -+:100D4000A504004EF0D1FB0A004CFCFFE70C0900A3 -+:100D5000868D090000F003F803B0F0BD000008170D -+:100D60000031E882040050F0A0FD08002C8E09003C -+:100D700000F002F830BD000008170032B0B10400E6 -+:100D80004DF0BAFE0800288F090000F002F830BDCF -+:100D90000000082B0033DCC004004CF086FF1C0070 -+:100DA000EC8F0900FF233D3343430448C0189F30B4 -+:100DB0000078002800D101207047C046349D08000B -+:100DC000081B003494AC04004EF0C2F90C001C90D7 -+:100DD0000900201C00F003F8B1F73AFE0000081BE0 -+:100DE0000035ACAC04004EF002FA0C00B4900900DF -+:100DF000201C00F003F8B1F7FAFD000008230036CC -+:100E00003CC104004CF064FF14000890090029184C -+:100E10007F231B02FF339D4200D35D1EFF23B3F7E8 -+:100E200092F808170037981B030067F004FB0800CE -+:100E3000A4910900FFF7D2FF30BD0000082B003855 -+:100E40001C7B040051F05EFB1C00DC4CFCFFE20D3F -+:100E5000090091090004910FB4301CFFF7E3FF0172 -+:100E60002802D10FBC05B0F0BD0FBC062DAEF79423 -+:100E7000FC081F003918AC04004EF02AFB1000706B -+:100E800092090003D1FFF7C1FFB1F7D2FCB1F7D14E -+:100E9000FC0000080F003A1C730400C046C0460066 -+:100EA00000000000000817003B807A040051F0ACFD -+:100EB000FC0800DC9309000420AEF75AFF10BD08BF -+:100EC00017003C9882040051F0A4F80800E493094C -+:100ED00000FFF7CAFF30BD00000817003D6CA804F2 -+:100EE000004EF072FE080054950900FFF74AFFF02B -+:100EF000BD00000815003E94A304004FF07EFA06E2 -+:100F00000094980900FFF7E8FF10BD080F003F0CA0 -+:100F1000A3040000F01DF8000000000000082300FA -+:100F2000404894000090F027FA14009A98090001B4 -+:100F30002B02D10020287001E06FF7DCFD62686FA2 -+:100F4000F718FE081D0041A4CC04004CF04CFCFF37 -+:100F5000DD0E090003FE0E00AE9809002878B2F7F6 -+:100F600079F9201C00F001F830BD080F0042C4A937 -+:100F700004005E4A2068000000000000080F0043E3 -+:100F8000A4630400FE23F533000000000000081FE6 -+:100F90000044D472000092F0FCFA1000D0980900CE -+:100FA000301C049900F004F8009988426DF7FCFCAD -+:100FB000081700459897040050F0C8F808002C99CD -+:100FC0000900FFF79FFEF0BD000008170046E49DF2 -+:100FD00004004FF094FF0800109D090000F002F893 -+:100FE000F0BD000008150047D099010080F0E8FA34 -+:100FF0000600A49F0900FFF7B2FF00BD08150048D6 -+:1010000068E901007BF01FFB0600AA9F0900FFF7BB -+:10101000C2FF00BD08210049A4E901007BF004FBE8 -+:101020001200B09F09000FB4301CFFF7C6FF0FBCC1 -+:101030000A22311C84F7F3FC080F004AC889030018 -+:10104000402303600000000000000819004B884C9A -+:10105000FCFED80F090085030061F01BFD0A00C2E9 -+:101060009F090000F003F89EF743FB000008BF0053 -+:101070004C5464020073F01EFEB00094A0090000FE -+:10108000B51E4B1A680D2A2ED0092A04D108430434 -+:10109000D09EF760FB01E00C2A04D11F490B6800C9 -+:1010A00020186028E0072A26D09BF712FF13490B6F -+:1010B00068012B12D112490B681B010ED41A490B7F -+:1010C00068002B0AD00E480368DB0102D5124908DC -+:1010D0006806E010490B68580002E000280BD002B7 -+:1010E000E00E490B68186001209EF731FE0F490B96 -+:1010F00068202003430B6000BDC046B0C808004014 -+:101100001B0800B45F0800400B080023C30800D48C -+:10111000CA0800F40A08000C0B0800E40A0800E4FE -+:10112000CA080053860300E4C7080020040E000824 -+:101130001B004DD06C020073F0A6FA0C0020A2092F -+:1011400000019800F003F802B0F0BD0000FE0000BE -+:101150004CFCFF004B0900F0B5484C484B49480394 -+:1011600060494B4948036001F0F4FE00F098FB0031 -+:10117000F0AEF900F058FB00F0B6FA00F0C8FA0340 -+:10118000F06FFE424A151CE435424B2B60424E3351 -+:101190006802263343404E33604048036880218B09 -+:1011A00043036000233E4E33703E490B1C23333D06 -+:1011B0004E33603D4B3E4E33603E4B3E4E33600BF4 -+:1011C0001C12333D4E33603D4B3E4E33603E483E35 -+:1011D0004B3F4E3360031C0E333E4E336012233DB3 -+:1011E0004E33700B1C11333C4E33603C4B3D4E3341 -+:1011F000603D4B3D4E33603D4E31603D4B3E4E3386 -+:10120000603E4E33683E4E33603E4B3E4E33603E52 -+:101210004B6B673E4B061C071DC8C40E363D4FC8BE -+:10122000C4991C0E30061CC2C43B4BD36200233A47 -+:101230004E336004F034FE394B6B65E4209EF73D7D -+:10124000FB0007000F042805D13F20C043354A505A -+:1012500073004CFCFFFB4B09000A907300233349D9 -+:101260000B703348E862F0BC08BC184700B5314841 -+:101270003249086032480749C86400F024F900BDCB -+:10128000C04614A4090091520900BCC80800955238 -+:101290000900F0C40800A0190800455309006C01BA -+:1012A0000F0040150800FD0708001E4500006CA453 -+:1012B000090020C9000070A409001CC8000074A423 -+:1012C000090078A40900388500007CA409005E04A8 -+:1012D000000044050000881308008C1308009013D8 -+:1012E0000800781308000EC90000801308000AC81F -+:1012F00000007C1308008413080026850000741386 -+:101300000800D8FF0E0080A409006216000084A423 -+:101310000900F95809004205000062190000819295 -+:10132000090068A409004D650900B8130800BAA5B2 -+:101330000900599E0900014B0900900008007963DB -+:10134000090070B500200F49104B4B6114E06B0988 -+:101350009C00EB064CFCFFF64C0900DB0E01259DC2 -+:10136000400B592B430B5143004C69C50052195295 -+:1013700068012632432725AD03AA1A1A5301300506 -+:101380004AC3009D58922DE5D370BDC0464C1B0842 -+:1013900000ACA509000CA3090000207047002070D4 -+:1013A00047002801D0002000E00120704700207095 -+:1013B0004710B5037814490B700620A9F75FFD04A8 -+:1013C0001E10D00E230370042343700023437101C9 -+:1013D000238370F723C370FC230371A9F779FD20E1 -+:1013E0001CA9F750FD012010BC08BC1847810589D5 -+:1013F0000D030AFC201840FC2803D1F72901D10372 -+:101400004800E000207047C046BAA509004D4D09CC -+:101410000004280AD106480378002B06D0054803AB -+:10142000785B065B0E0370012000E000207047C06F -+:1014300046BAA5090039C3080030B50124827812E4 -+:1014400002437813439A05920D1B0AFC252B400C8E -+:101450002B2DD0FC2B244CFCFFF14D0900D11C2A74 -+:101460001CD0B52A0DD0B62A0FD0C22A10D0C32A5C -+:1014700011D0E62A02D0F52A1AD112E003F04CFC72 -+:1014800017E001F05FFE012016E001F091FEFAE79F -+:1014900001F0C0FEF7E701F006FFF4E705F088F978 -+:1014A000F1E703F0AFF9EEE7202B04D0042B02D1D3 -+:1014B0000024201C00E0002030BC08BC1847024873 -+:1014C000024908607047C046D54D090018C9080098 -+:1014D000002070470148024988607047654E090046 -+:1014E000201A080072487349C8607047F0B583B08D -+:1014F000041C012906D164300023C372251C9435D5 -+:10150000AB73EB736C4803689B079B0F032B02D0F4 -+:1015100071F722FAC8E00023A381E07B484000D1A4 -+:10152000B6E070F7BDFC002803D1644803691B01D5 -+:1015300001D5012100E00021271C64373E1CFB6817 -+:1015400080208343C8010343F3600C365C4A107863 -+:10155000431006D0C3071B0E4CFCFFEC4E090031B4 -+:10156000688020814319433160564803691B01029A -+:10157000D4381C94F79AF9BB69002B02D03B681B46 -+:10158000063BD4338868460380E37B012B0DD025CE -+:101590001C94356B7B002B10D02B88042B0DD3EBC8 -+:1015A0007C022B0AD3AB7D002B07D1A72303201885 -+:1015B00055009B78208343002106E00121E9740057 -+:1015C0009B78208343082003431F208002834388A5 -+:1015D00002034300931B041B0C3C4A1360012030A0 -+:1015E00072384A13691B0152D400984006010F005B -+:1015F000231A1C012094F77AFB45E0E07B002802C7 -+:10160000D1A72301221A55012804D1E37C042B0120 -+:10161000D072F76DFCF37A002B06D00023F37233FF -+:101620006801204002434033600121B172251C94BF -+:1016300035A97323480369DB0002D5201C87F77D99 -+:10164000FD338821490B60B0884860381C70F79DD5 -+:10165000FC30684006030F1D48C04CFCFFE74F09F3 -+:10166000005C3072431EA381E37B002B0FD101216C -+:10167000387F8140194A1068084008D1E37C042B68 -+:1016800005D016480378AB7516480378EB750E48FD -+:1016900003691B010FD5201C94F7D3FE0BE0271C18 -+:1016A00064373B727B7270F72BFC636C002B02D0AB -+:1016B0005A231B5BA38103B0F0BC08BC1847814EC2 -+:1016C000090000020800188B0E0054200800DCC836 -+:1016D0000800CC8A0E009EBB0500B4010800F5018D -+:1016E0000800F601080030B50D1C041C75F777FEE4 -+:1016F0006B075B0F012B05D1E37B002B02D1A07B95 -+:101700009CF7B6FD30BC08BC184700B52C22044934 -+:101710000548BFF774FC034804494161044B186055 -+:1017200000BD0CBD050088A409006D500900E4024D -+:10173000080010B53F4C3F4B1C602C223F49201C39 -+:10174000BFF75DFC3E48606210BDF0B5041C051C8F -+:10175000876A28353B4B4233187800284CFCFFE25F -+:1017600050090066D1201C012172F7D1F9061E4BE9 -+:10177000DD022804DB201C77F74BFA002859D161E1 -+:101780008C8B1F9E4223DA304A13689C420BD0395F -+:101790001CAB310878013800D30870731C59102035 -+:1017A0001C76F7D8FF30E0731C5810E37B002B0544 -+:1017B000D07B6C002B02D06B7F002B25D02F89B8FB -+:1017C0004222D36A89002A06D1A389002B03D120A3 -+:1017D0001C71F7DFFD18E0BA4200DA3A1C904201B2 -+:1017E000D90C2310E04B23A27C1B5D9A420CD10242 -+:1017F000280AD36B7F002B05D01448037899420147 -+:10180000D9282300E03823A374211C4D3108780027 -+:10181000280FD00238087000060BD1E37B012B02A1 -+:10182000D0237D0C2B05D0321C201C0523022177F0 -+:10183000F734F9F0BC08BC1847B4A4090000030849 -+:101840000074BD0500D15009006C210800F40208A5 -+:101850000000B52C2216491748BFF7D4FB154CFCE5 -+:10186000FFDD51090048164B18601649016100BDA3 -+:1018700030B50D1C041C78F71CF8022D09D16B2320 -+:10188000185D002805D0201C87F705FB201C87F772 -+:101890003DFB30BC08BC184700B5011C6831CB7853 -+:1018A000002B07D04B7A002B04D18B78002B01D072 -+:1018B00087F714FB00BDC0462CBE0500E0A409005C -+:1018C00030030800E951090000B57CF752FA00BD69 -+:1018D00000B52C220B490C48BFF798FB0A4B0B486C -+:1018E000036000BD0A49CB6ADB0007D5094AD388EB -+:1018F0005B00418C8B4201DC012100E000215A3069 -+:1019000001707047B0CB05000CA50900F403080076 -+:1019100054200800942008000020704730B5041CB3 -+:1019200000292BD0012925D140051BD426E0174DD5 -+:10193000291C1748B7F7C7FF2988281C262902D178 -+:1019400003F04BFD0EE0042902D17CF712FA09E006 -+:101950000F2902D104F032FB04E089000D4A8958B6 -+:101960004CFC48D8520900C6F7EDFA0A48B7F7C64A -+:10197000FF0028DFD00A4B1C4003E0022901D17B85 -+:10198000F7CBFF201C30BC08BC18470548064908A7 -+:10199000607047F4440800284508009CBE0500FF1D -+:1019A000FBFFFF95520900F0C408004CFCFF2453D4 -+:1019B000090000B5431E04490B6004490B78032B52 -+:1019C00001D1BFF7E8FF00BDC046E08A0E0038082D -+:1019D0000800F0B587B0061C0491081C0021039193 -+:1019E000A34C2064211C4431009100238B70A0483B -+:1019F0008568002D00D16EE2AB7D002B09D001225D -+:101A000003920023AB756361237810208343237016 -+:101A100006E06069002803D0012E01D970F701FFAC -+:101A200022691D27FF03002A50D0607A012803D1C4 -+:101A30009389002B4AD047E08F4B1B5C002B43D18E -+:101A4000BB68DB0742D4137D092B3DD204281AD191 -+:101A5000012E18D1967562612378102003432370FC -+:101A600023683B6085490B687233187802282DD0B3 -+:101A7000002382490B608249086882490B68036031 -+:101A80000B68036022E002280AD1012E08D1967566 -+:101A90006261237810200343237023683B6015E0C4 -+:101AA000032803D179498B78022B0FD0064CFCFF19 -+:101AB0001F5409002801D0032805D1012E03D1BBF2 -+:101AC000689B0600D5C0E1122803D0102801D07011 -+:101AD000F72BFE6A4B985D029000287DD00123DB36 -+:101AE00007334301936B4B6C490868986301236B80 -+:101AF000490B606B490B689B0C9B040B600B68697E -+:101B0000490868034366490B6001230099CB70665E -+:101B1000490B6866490B6066490B6866490B60288B -+:101B20007C1A281DD164490B6864490B6064490B19 -+:101B30006864490B6064490B6864490B6064490B35 -+:101B40006864490B6064490B6864490B6064490B25 -+:101B50006850490B60634908686349086063492D10 -+:101B6000E063490B6855490B6062490B6855490BA6 -+:101B70006061490B6855490B6060490B6855490B1A -+:101B8000605F490B6855490B6019280ED1FF20177B -+:101B9000302B562A3309DD5B490B683E490B605AEE -+:101BA00049086851490860594908E059490B684C8F -+:101BB000FCFF1A55090039490B60584908684C491F -+:101BC00008605749086857490860A87B231804280B -+:101BD00001D3187800E0205C6F2290431870C2E0B7 -+:101BE000A87B225C0F218A433107090F0A43225444 -+:101BF00023180428049802D38107101C01E08107F0 -+:101C00001878490E6022904308431870234B4649C8 -+:101C100008689863009AD378002B00D1A1E022498C -+:101C20000B689B0C9B040B600B68404908680343DE -+:101C30001D490B600023D3703D490B681D490B60A3 -+:101C40003C490B681D490B603B490B681D490B6003 -+:101C50003A490B6821490B6039490B681B490B60F5 -+:101C600038490B681B490B6037490B681D490B60ED -+:101C700036490B6809490B6035496BE0642C080054 -+:101C80006C210800ECBB0500DC02080060000F00BE -+:101C9000AC2C080044020800882B08002CFC0E0025 -+:101CA00060020800E08A0E00B88A0E005C0208009C -+:101CB0006C4CFCFF15560900130800D8FC0E007090 -+:101CC000130800E0FC0E006CA40900CCFC0E0074AC -+:101CD000A40900DCFC0E0070A40900D0FC0E007CFE -+:101CE000A40900C8FC0E0078A40900D4FF0E002C43 -+:101CF000A4090030A4090030FC0E0034A4090078C7 -+:101D00001308007C13080080130800741308008473 -+:101D100013080014A4090018A409001CA409002039 -+:101D2000A4090024A4090028A40900D8FF0E00B8C3 -+:101D30002C080048020800BC2C0800C02C0800C475 -+:101D40002C0800C82C0800CC2C0800D02C0800D48B -+:101D50002C0800D82C0800DC2C08000868934908DF -+:101D60006093490B6893490B6000210191286882B8 -+:101D70006A281C0021C6F7EDF8002810D026231A87 -+:101D80005C002A0CD08368002B09D002980028043C -+:101D9000D0802301981843019001E0012200E00067 -+:101DA00022237880208343D0010343237020200422 -+:101DB0009908404CFCFF1057090001D00120C003D6 -+:101DC0007F4908600499090704D47D490B68802085 -+:101DD00083430B600499880801214140A278802048 -+:101DE0008243C8010243A2702868826A281C03212A -+:101DF000C6F7B3F874490B78012B01D077F753F885 -+:101E000005A9714A13687020034018099CF7A0F8CF -+:101E10002369002B14D0637A032B11D188F701FCBE -+:101E2000002806D16A480368032B02D00368062BFA -+:101E300006D12B7C122B03D101230098837058E02C -+:101E400005988007800F06D003280ED1069B6049B5 -+:101E50000888834209D30398012800D1656170F78F -+:101E60006EFC012300994B7043E00820B860A87B0A -+:101E7000786223683B603B1C1833221D0392920753 -+:101E8000920F02D1039909680FE00399891A03910F -+:101E9000D2000968D140049120218A1A0399496827 -+:101EA000914001B40598014301BC1960BA69331C23 -+:101EB000103B042B0D4CFCFF0B580900D2474B1371 -+:101EC00040FF22013282401343BB61102E07D144F0 -+:101ED0004908684449086002E040481040B8610180 -+:101EE00098002800D07861E5602672002300990BE5 -+:101EF000704B70281C8CF7B5FC012007B0F0BC08B3 -+:101F0000BC1847394B3949087A185C39490B6800C5 -+:101F10002814D00120800303430B60364A1368362F -+:101F2000480340364A117849020B43354A1360355D -+:101F30004A1368302083431020184308E0324803D6 -+:101F4000400B602C490B682E490B602E4908682F06 -+:101F5000490860704710B5254C234B607A185C0027 -+:101F60002802D070F75FFF15E06069002801D0708B -+:101F7000F769FC27490868637A012B01D1254A00DB -+:101F8000E0254A13680360116801600023234A13A7 -+:101F90006070F774FE002322490B60E360236163E5 -+:101FA0007244340120207010BD002803D10348037F -+:101FB000680348036000204CFC7206590900704712 -+:101FC00030FC0E0080A40900D8FF0E00648B0E00C8 -+:101FD000A4860E00D4C1080024860E001C840E00C6 -+:101FE000E4B60800FFF0FFFF9406080064FC0E0052 -+:101FF000ECBB0500642C0800808B0E00B02C0800A0 -+:10200000FFC1FFFF9013080088FC0E00B42C0800ED -+:10201000FFBFFFFFCCFD0E00AC2C08004002080003 -+:102020004402080060000F0018800E004CFCFF887E -+:1020300059090070B582B0061C654801688906021E -+:10204000D5022072F71FFC624C2568A3682360004C -+:102050002D26D0002E18D19EF7F4F9002814D0C3F5 -+:102060000703D52A68916900290BD1430703D52AB4 -+:1020700068D169002905D1830706D52A68116A004D -+:102080002902D0281CC5F76CFF9EF7F8F9011C2A1D -+:10209000685269002A04D0002802D0281CC5F75DC8 -+:1020A000FFA0680026A84218D0002D21D02A68126F -+:1020B00069002A03D0281C0521C5F74FFFAE8123F4 -+:1020C000699D4200D126612B7D092B11D3281C73F9 -+:1020D000F7E8FD281C73F76DF90AE0002808D063C3 -+:1020E00069984205D166613B4800220121B7F71D7E -+:1020F000FF3A48C16E002904D0A368002B01D1C566 -+:10210000F72FFF70F7B6FBA06800284BD08681033D -+:102110007D092B20D26369984205D166612E480063 -+:10212000220121B7F702FFA068A84206D1014CFCAA -+:10213000FF835A0900684968002902D00523037506 -+:1021400008E0017D032901D0042905D1016849680F -+:10215000002901D0C5F708FFA068022303750168B4 -+:102160000A69002A02D00221C5F7FBFEA068807B25 -+:102170001D4A136870210B401909884216D169461F -+:102180009BF7EAFE70F760FC002801D0174800E0DA -+:102190001748028800998907890F04D0032905D1BF -+:1021A000019B934202D33F2301201855A0688CF76E -+:1021B000E0F901208CF7F0F9A66066603C342671E6 -+:1021C0006671012002B070BC08BC18470948044978 -+:1021D00088617047C046C4C408006C2108000C2DFB -+:1021E0000800201A080024860E0066020800640217 -+:1021F0000800895909009F48A0498865704700B5C3 -+:102200009F4A9007800F01D1116808E0121AC000A0 -+:102210001368C3402021081A516881401943C90F2F -+:1022200098480170984A1068002817D0974A0260B1 -+:102230004CFCFF7E5B0900974A8260974AC26001AE -+:1022400023964A13700023964A1360964A136096A9 -+:102250004A1360012902D100F007F802E04068C586 -+:10226000F785FE08BC1847000000B500F003F80829 -+:10227000BC1847000010B564238C48037000238C01 -+:102280004803608C4803608C4C236000F04FF87D5D -+:102290004A9007800F01D1116808E0121AC000139C -+:1022A00068C3402021081A51688140194301204029 -+:1022B00007014015D081490B68001403430B60806F -+:1022C000490B68804803400B6004390B680120808B -+:1022D0000303430B607C4B7D490B6003037C490B7C -+:1022E00060684A9007800F01D1116808E0121AC097 -+:1022F000001368C3402021081A516881401943C95E -+:102300000011D5744C2368002B02D0201CB7F705B0 -+:10231000FC7149201C00231A1CB7F7E0FB6F480131 -+:1023200068201CB7F7E6FB8EF762FA10BD10B56C9B -+:102330004C234CFCFF795C090068012423436A4C60 -+:10234000236001239B03694C2360504A9007800F50 -+:1023500001D1116808E0121AC0001368C34020219F -+:10236000081A516881401943090105D55E48036880 -+:10237000022003435C4803605D4800218160F42132 -+:10238000C16020210161E8218161E92141611021C1 -+:1023900041624021C161016205239B04036010BDBD -+:1023A000F0B582B0071C01910C1C002200920123A1 -+:1023B0005B0250490B604E490E68360C3604211CF6 -+:1023C000242903D0151C25291CD102E008240A2148 -+:1023D0000AE070300078022802D10824464801E063 -+:1023E000012446480278012123010D031D431307F0 -+:1023F0001B0D1E43FB7B002B00D1E4E00123DB031C -+:102400001E43E0E0019B5B003D481C5A3D498C4265 -+:1024100011D18023DA5D3C48135C1B013B4818183E -+:102420008388002B07D0374C1034837A012B06D1D8 -+:10243000344C20344CFCFF745D090003E0002C0197 -+:10244000D1251CC3E0381C8CF79CFB002800D04031 -+:102450002431480368002B07D0602C01D1E02464AC -+:10246000E0702C08D1D02460E00198042801D0024B -+:102470002801D101252D04302C4FD17023D85D00C7 -+:10248000284BD0214C703450E0C0464D5B0900A071 -+:10249000190800C005080030C8080044060800B14B -+:1024A0005B0900E15C0900155F0900B8050800340C -+:1024B000C8080038C808003CC80800D0050800401B -+:1024C000C8080048C808004CC808009C800E0010CE -+:1024D000800E00FFBFFFFFFF030000BC820E001054 -+:1024E000000C0068500800673D0200D40508007029 -+:1024F000010F005C000F0074820E000C800E00982B -+:1025000006080090060800D8050800100100009099 -+:1025100005080024500800D4C40800502C05D13B05 -+:102520006FDB0502D501235B041D432543FF231107 -+:102530003370339C42034CFCFF6F5E0900D02309CB -+:102540005D48C15C0091302C0BD17023D85D002810 -+:1025500007D1381C2830037D807A19180906090E26 -+:102560000091009803031D43FB7B002B02D0012345 -+:10257000DB031E43FB7C032B04D1788CC306180FAE -+:1025800003021E43402C25D14C480378002B06D073 -+:10259000381C8DF774FE03071B0A1D431AE0012344 -+:1025A000DB041D43B87B9BF7FFFC4008444A1060E6 -+:1025B000444A11689BF793FC434A1060434A1368EE -+:1025C000984204D2381C8DF73AFE002802D001232D -+:1025D0003A4803703E480560466002B0F0BC08BC53 -+:1025E0001847F0B582B00F1C051C00220092019024 -+:1025F0008CF7CBFA364E002844D034682F48017847 -+:1026000000291AD1A87B9BF7CFFC40082C4A106008 -+:102610002C4A11689BF763FC2B4A10602B4A136805 -+:10262000984204D2281C8DF70AFE00281BD00123F3 -+:1026300022480370274B1C404CFCFF6A5F090015C1 -+:10264000E06B6E1B0612D4012910D1281C8DF7FAFD -+:10265000FD00280BD1A87B9BF7AAFC41081A4A1160 -+:10266000600023174A13700123DB041C4314480342 -+:1026700078002B03D001988CF734FF0090174B1C87 -+:1026800040009803071B0A1C433460042F01D0024A -+:102690002F05D13368012109040B43012107E01004 -+:1026A000480378002B06D033680E490B40002133D5 -+:1026B000600B48017002B0F0BC08BC184724060843 -+:1026C00000B805080038C8080034C808003CC8082D -+:1026D00000CC05080070820E00FFFFF7FFFFFF0F20 -+:1026E000FF45C80800FFFFFEFF30B5041CC37C0394 -+:1026F0002B27D1037D0C2B24D11830437B002B20BA -+:10270000D121490B699C4202D18B68002B13D04127 -+:102710008900680B1858010509A07B9BF748FC85C8 -+:102720004201D3281A03E0431B01200007C01A838B -+:102730001F1648834205D3201C734CFC6365600957 -+:1027400000F7C8FA201C72F756FF237D022B03D036 -+:10275000032B01D0042B07D10F480379002B16D08F -+:10276000201C70F79FFD12E00C480369002B02D07B -+:10277000201C70F734F806494123585C012804D026 -+:10278000002804D10B689C4201D172F7C2FA30BD17 -+:102790006C210800FBFFFF07A42C0800642C080034 -+:1027A0004CFCFF4861090070B5041C002538484303 -+:1027B0006912219B0708D5364A1068364A106050C6 -+:1027C000304079122800D8011C43209DF76CF83264 -+:1027D0004BA360324B2361201C0830AAF70DFF2168 -+:1027E00068086063681D60AAF776FF201C1030AA95 -+:1027F000F703FF216808600420AAF785FF606106DF -+:102800002801DAAAF768FF201C0830AAF7F5FE2194 -+:102810006808606368002018600420AAF774FFE06D -+:1028200060201C1030AAF7E8FE2168086063680089 -+:102830002018600420AAF767FF6061E368C61A30B9 -+:102840001CAAF7B7FF042817DD01350C2D14D03072 -+:102850001C042E08DDAAF7ADFF8100081A216908C3 -+:102860001802382061CFE7AAF7A4FF8100081AA157 -+:1028700068081A0230A060C6E7A16820690B1AE355 -+:10288000614018C30F18184310236270BDC046186A -+:102890001B0800D4CC080034A70900FF0300000186 -+:1028A000FCFF4CFC0543620900FF4CFCFF58620929 -+:1028B00000F0B5444D2B68987B9BF73BFB46082BFB -+:1028C00068996C301C9BF7D0FA041C2868011C9492 -+:1028D000314A88002A10D094420ED9037D0B2B0B6D -+:1028E000D00D2B09D070F79FFB2B686433197F0143 -+:1028F0002000037BF771F864E00B7D002B06D0CB42 -+:1029000088F31A1B041B0C9C4200D81C1CC36F6468 -+:1029100030002B06D00B89F31A1B041B0C9C4200C1 -+:10292000D81C1C8A88B31A1A04120C944200D814BA -+:102930001C0B881F1FBA4204D3CB7C022B01D3008F -+:1029400023CB74214E33889C4204D80020BA422EF7 -+:10295000D303202CE073889C4201D8042228E0B3E2 -+:10296000889C420BD9007F74F7C1FE002814D00365 -+:102970007C112B11D115494B889C4203D8296894AE -+:1029800031052215E08B889C420DD82968943106C8 -+:10299000224A745E2383740CE0F3889C4203D82996 -+:1029A000689431062204E029689431074CFCA15355 -+:1029B0006309002200E0021C4A740B7E012B04D143 -+:1029C000531F012B01D804234B74F0BDB421080020 -+:1029D00034020800EC02080010B5A3F7D3FB0B4942 -+:1029E0004B699B070FD50A48036801200343084839 -+:1029F00003600A249BF750FD013CFBD104480368A7 -+:102A00005B085B00036010BC08BC1847181B08007B -+:102A1000F0FC0E0010B5094C2C220949201CBEF711 -+:102A2000E1FA0849E160084B1C6010BDC27B4A40D6 -+:102A300002D0838C05490B607047C04638A7090057 -+:102A400034CC0500CD63090010040800CC8A0E00C8 -+:102A50004CFCD418640900F0B581B0041C002100BE -+:102A600091C56D8726F600002D04D1301C9BF7A67A -+:102A7000F8051E03D0301C9BF7A1F80090264F3BB1 -+:102A800068002B08D1301C08309BF798F83860316B -+:102A90001C0831BEF7B8FD20480368002B0DD1306B -+:102AA0001C08309BF78BF81C4A1060311C0831BEA3 -+:102AB000F7AAFD19480368002B07D03B68002B04D8 -+:102AC000D0002D02D00098002817D1E02300201854 -+:102AD00051E565E4210B59DB0208D4635810480323 -+:102AE000430B515022206807217DF7D6FA0D480389 -+:102AF00068002B0DD19BF76EF80AE0E5656060E495 -+:102B0000221359064883431351206807217DF7E5B6 -+:102B1000FA002001B0F0BD444408009C44080000C5 -+:102B2000001000600308004CFC78F064090030B528 -+:102B3000E4221358012109058B431350051C79F732 -+:102B40002AFA0024002800D0EC65E86D002802D0A5 -+:102B50009BF75BF8EC656868002802D09BF755F896 -+:102B60006C60074D2868002802D09BF74EF82C6057 -+:102B7000054D2868002802D09BF747F82C6030BD2F -+:102B8000C046444408009C44080000231360012808 -+:102B900005D10123DB040B6007239B0313607047FF -+:102BA00000004CFC748C650900B0B503685B01192A -+:102BB00048C21880270F404906490E906800282710 -+:102BC000D00568281C041C002F06D0437B8B4201D3 -+:102BD000D0002300E0012306E0037B5B088B420169 -+:102BE000D0002300E00123002B0FD0A84205D11311 -+:102BF0007C002B02D1D37F022B0AD0111C08319B01 -+:102C0000F7BCFD201C9AF7AAFF02E00068A842D991 -+:102C1000D1B0BDC0467C2908004CFC1E18660900D6 -+:102C200010B5002907D0041C70F798F9201C6EF726 -+:102C300003F9012000E0081C10BD4CFC4458660953 -+:102C40000000B50D48B6F707FE00BD30B5051C0005 -+:102C5000240A49A300C818C378AB4204D1A300C812 -+:102C6000180421BEF7A5FC0134082CF1D330BD00B7 -+:102C7000B50068FFF7EAFF00BDB8520800504708EA -+:102C8000004CFCFFA066090030B5104D0D24281C37 -+:102C90000022111C90F720FA281C90F713FA203517 -+:102CA000013CF4D130236343094818182C23195CE4 -+:102CB000022904D1406A002801D09AF77BFF013431 -+:102CC000022CEFD390F7C8F930BDC0467C2908002C -+:102CD00080590800F0B582B0051C0E1C041CB034ED -+:102CE0006946207B9BF7D3F82C482D4A1178431A6C -+:102CF000F6000198991940182A4B984201D30320F5 -+:102D000005E00121284B984200D30221081C0099BC -+:102D100043185808031D5808860176092188301C7D -+:102D20009BF76AF86788391C77F7E6FA381A430880 -+:102D3000AB80831958014009A0601422291C1B484C -+:102D400003F0A8FD02B0F0BD10B5041C18490868D6 -+:102D50000007000F01280BD80B683F20000203403A -+:102D6000190A144A906EFFF7B5FF134A9378A374BB -+:102D700010BC08BC184710B5041CB3F7B7F80F49CE -+:102D80008B78004CFC419B6709002B07D1A37C0B7F -+:102D9000498878834202D0201CB3F787FE10BC0814 -+:102DA000BC18470E02000038A40900A903000071F6 -+:102DB00002000000980E00A88B0E0038B0080074C6 -+:102DC000150800AC2108004CFCFFEC670900F0B5C9 -+:102DD00084B0061C181C01AB07C300252C1C03F093 -+:102DE0005EFD00902F1C0199002918D0F37F022B63 -+:102DF00015D1337C351C002B01D00C3500E0083593 -+:102E00002A68101E00D01068002A07D0116891426D -+:102E100001D12C6001E00B6813600C6014E0357484 -+:102E200012E00A6801928A4201D1F76001E013685A -+:102E30000B6001990F60002C04D02368136022609E -+:102E4000141C01E0141C1260F1680029E9D115E09E -+:102E50001A680193111C9A4201D1B76004E013680B -+:102E600001B40298036001BC0F60002C04D02368F9 -+:102E700013602260141C01E0141C1260B368002B64 -+:102E8000E6D1002D0BD02A68002A05D01368036014 -+:102E90002B681860286007E02860006004E0F37F7A -+:102EA000022B01D10323F377009803F000FD12E019 -+:102EB0002068051CA04201D1002401E003682360C2 -+:102EC0002F600399002904D0024CFC7DE7680900BB -+:102ED0009900229CF731FE01E09AF726FE002CEAC9 -+:102EE000D104B0F0BD0A480B4908600B480B4908F3 -+:102EF000600B480C4908600C4B0C490B600C4B0DE7 -+:102F0000490B600D4B0D490B600D4B0E490B60706A -+:102F100047C970090064C80800236F090068C80821 -+:102F200000E975090080C80800196A090054C8083A -+:102F300000096D090070C808006976090078C808A2 -+:102F40000064A30900B00608004CFCFF9869090062 -+:102F500070B5051C7CF755F8011C041CEA691204C5 -+:102F6000D20F2273032363730C34414B186800099A -+:102F70000226800706D5F42043599B0702D5A67088 -+:102F80003C480660F4204359DB0601D4002A01D1F5 -+:102F9000002000E038484860281C90F7E6FC002339 -+:102FA000364A137070BD30B5041C0D1C7CF729F82F -+:102FB00033494B681A7BD207D20F02730523437340 -+:102FC0008573304A4260011C201C90F7CEFC30BD56 -+:102FD00010B5041C0321FFF7E6FF294A5368987BCC -+:102FE000244A1060201C8DF7D0FF10BC08BC184785 -+:102FF00070B5041C7CF705F8011CE2691204D20FBD -+:10300000027304234373F8231D59837B0126B343C2 -+:1030100035402B438373F8263559AD07ED0F022653 -+:10302000B3436D002B4383730C30002A0CD1164A36 -+:10303000537815785B199578EB18D578EB181579D6 -+:10304000EB185279D31800E00023C34CFCFF936ABD -+:103050000900700F484860201C90F78AFC70BD0082 -+:10306000B5094A5168897B8B07DA0FC907C90F8DEB -+:10307000F7CCFF00BDC046641B080088500800D391 -+:103080004902005CC80800F44408008B710900E89C -+:10309000500800094A020010B5041C6D4A1068C0AF -+:1030A0000702D4112323702BE008790002C97808A5 -+:1030B00043012178F76FF8002803D0F8221158490E -+:1030C0000701D51223EEE7C169090403D4F4210BEB -+:1030D000589B060DD55F4B19684906490FF422121B -+:1030E000589207920F914203D15B490B78002B0154 -+:1030F000D00C23D7E701230B7028342370FFF72B64 -+:10310000FF10BD30B5051C0C1C031C283301201812 -+:103110007001F0F4FA002801D10C2022E02079009F -+:1031200002E1780843012178F735F800280BD0F840 -+:10313000221158490701D40B2013E0F43003685BD7 -+:103140000601D40E200DE04249086840064CFCFF01 -+:103150008E6B0900400F022808D1414A1188601D7A -+:1031600001F040FA002801D10D20287030BD30B5A3 -+:103170008A7B002A01D1122340E0374CCB782068AB -+:103180000225002B06D0012318432060364803682F -+:103190002B4305E001239843206032480368AB438A -+:1031A000036031480B7903704B7943708B798370DE -+:1031B0002F48CB79202B02D12E4B186002E02D48EE -+:1031C000402BF9D0487A00020B7A184340102A4B62 -+:1031D0001860C0006080C87A00028B7A1843204BC8 -+:1031E0001880487B00020B7B1843244B188024482E -+:1031F0000280CB7B244803700B7C2348037030BDD6 -+:10320000164A1168C907C90F817317490B78C37330 -+:103210004B7803748B784374164A1168090A8174D9 -+:10322000164A11684900C174090A01750D4A1188CE -+:103230004175090A8175114A1188C175090A01761B -+:1032400010490B8843760F490B7883760F490B4C56 -+:10325000FCFF896C090078C3760E23C3707047C0E9 -+:1032600046641B08005CC8080060A40900301B0805 -+:1032700000A80608001E200000940608003A40003E -+:10328000009006080062A4090064A4090065A7096B -+:103290000066A7090010B5041CFF20052193F779EB -+:1032A000FF002806D016238370C470210A01719391 -+:1032B000F7FBFE10BD10B5041CFF20052193F76934 -+:1032C000FF002806D018238370C470210A0171936F -+:1032D000F7EBFE10BD10B50024201C00F0F0FB0140 -+:1032E00034042CF9D31821AB48BEF754F901F04C43 -+:1032F000F8A9480268D10708D55106490F022904E8 -+:10330000D1A64A116872230B4313600023A4490B12 -+:1033100070A4490B704088C010A3490860A3490BF2 -+:103320007010BC08BC184730B5051C00244E236340 -+:10333000439F481818811C281C062203F0B5FA0088 -+:103340002803D1201C00F0BBFB02E00134042CED6B -+:10335000D34CFCFF846D090030BD00B500214E2028 -+:103360004843954A8218507800021278104302D0E0 -+:103370008DF7D8FC07E001310429F0D300238F49F1 -+:103380000B708DF708FE00BDF0B5061C0425002467 -+:10339000894F4E206043C019811C301C2830062202 -+:1033A00003F086FA002801D1251C02E00134042C28 -+:1033B000EED3042D0DD100244E206043C11948786E -+:1033C00000020978084301D1251C02E00134042CD5 -+:1033D000F2D3042D18D24E236B43DC19311C283153 -+:1033E000A01C0622BDF7B8FD5C20805B2070000A9F -+:1033F0006070311C201C083000F0F6F9311C2831B7 -+:103400006F480622BDF7A8FDF0BDF0B5041C0F1CE7 -+:1034100000264E207043684BC518A91C381C062294 -+:1034200003F046FA002803D00136042EF1D326E03B -+:10343000201C78F77EFA291C0831201C00F085FA40 -+:10344000E0690F21C9050843E061201C0F230386B2 -+:103450003030864CFCFF7F6E09008D69780C022AA3 -+:10346000781443A64205D0584A0121B14013688B15 -+:10347000431360554A0123A3401168194311608426 -+:1034800085012000E00020F0BD10B582B006224F7B -+:10349000496846BDF764FD0024694606236343403E -+:1034A000481818062203F007FA002801D00120036B -+:1034B000E00134042CF0D3002002B010BDF0B5823E -+:1034C000B0071C062243496846BDF749FD00243475 -+:1034D0004E0622151C65436946A81903F0ECF90055 -+:1034E0002806D1391CA8190622BDF739FD01200391 -+:1034F000E00134042CEBD3002002B0F0BDF0B504A1 -+:103500001C0E1C171C344DFF2001302058002801D0 -+:10351000D0B6F794FAF8210859C00700D491E0001A -+:103520002E00D18EE0002F00D1A5E00859800700C1 -+:10353000D4A1E0201C6DF7C3FCE069F8218843406A -+:10354000210843E061F822105904229043F8221028 -+:1035500051201C90F74CFCFF7A6F09007DFD20681C -+:1035600000216DF7EBFC164A1378002B0AD0E069B6 -+:1035700000043CD41B4880791B4A1178014001D1DA -+:10358000002832D1261C5C36318800231A1C181CF6 -+:1035900094F7A2F83088FFF798FE00232B700848B4 -+:1035A00003701048037022E0C046BBA50900641BED -+:1035B0000800301B08005CC808005DC808009006C1 -+:1035C000080065A70900D3A50900BFC10800B7C15D -+:1035D0000800D020080054A309005CA3090064A7D8 -+:1035E000090038A5090066A7090001232B70201CDB -+:1035F00028308DF787FBE069000414D48DF7A4FB15 -+:103600008DF774FE012801D18DF793FB982108599D -+:10361000C00008D5E06C032189068843E064201CC3 -+:10362000012181F77FF80023B9490B70A36B1B07B9 -+:103630002FD5E06900042CD4B6494B681B0528D56A -+:10364000201C01218DF739FE23E0B249086880076C -+:1036500015D5F8221059084CFCFF75700900210897 -+:103660004310518021E069000400D44900AC4A11A4 -+:10367000600120000778F716FE002E0DD1201C8D6A -+:10368000F7C2FC09E0E069000403D5201C8DF76E49 -+:10369000FD02E00123A34803700120F0BC08BC1820 -+:1036A0004700B5FC300068002801D0B6F7CEF9001D -+:1036B000BD70B59D4D03685B019C49CE18041CFF8D -+:1036C000F76DFEE069000403D4201C00218DF7F89B -+:1036D000FD20687CF7AFFC201CFFF7E2FFE06900EB -+:1036E00006C00E0A2817D1012120688140904803A6 -+:1036F000688B430360201C74F7C1FCE069F82188E3 -+:103700004340210843E061206883F7E4FF201CA0C8 -+:1037100030042103F0DFF8211C301C01228FF7DC7C -+:10372000FCE069F821884318210843E061F821088A -+:10373000590721084340218843F821085120680196 -+:10374000218140CA437B490B6813400B606DF70E23 -+:10375000FBE069000402D42B784CFCFF7071090077 -+:10376000012B04D05C342088FFF7A6FD01E0002384 -+:103770002B70012070BC08BC184700B5011C1D202F -+:1037800078F708FE08BC18470000F0B5071C0024B5 -+:103790006B4E0622151C6543391CA81903F096F8D8 -+:1037A000002805D1A8190621BDF706FF012003E076 -+:1037B0000134042CECD30020F0BD70B5061C0025AC -+:1037C0004E236B435F481C18A11C301C062203F0DB -+:1037D0007DF8002803D00135042DF1D310E0221C20 -+:1037E00025329107890F01D1106808E0521AC900EB -+:1037F0001368CB402020411A50688840184300E0ED -+:10380000002070BDF0B5002900D1ABE0041C00D150 -+:10381000A8E0C8694005400F2070C8698004400FC7 -+:103820006070486BA21C93079B0F01D1106006E0EB -+:103830001070000A5070000A9070000AD070886BF7 -+:10384000A21D93079B0F01D1106006E01070000AC3 -+:103850005070000A9070000AD070C84CFCFF6B7268 -+:1038600009006B221C0A3293079B0F01D1106006DE -+:10387000E01070000A5070000A9070000AD07008C2 -+:103880006C221C0E3293079B0F01D1106006E010D2 -+:1038900070000A5070000A9070000AD0700D1C5021 -+:1038A000352888A074000AE074AB782375EB786340 -+:1038B00075CB7BA3758B7EE375CB7E237624480383 -+:1038C00078637698204058400FA076E889E076002B -+:1038D0000A20770F1C9C37B86D221C1D3293079B62 -+:1038E0000F01D1106006E01070000A5070000A90BD -+:1038F00070000AD070261C2036C86C4001C00F70C2 -+:1039000070C86C0001C00FB070C86CC000C00FF070 -+:1039100070C86C8000C00F30711022291C103170EB -+:103920001D17E05CC80800181B0800641B0800D4C1 -+:103930005008005DC8080064A709007C290800E45D -+:10394000C70800B4C40800BBA50900D3A509003C02 -+:10395000A40900BDF712FB1022291C20314CFCFFEA -+:1039600066730900301C1530BDF70BFB4534F87841 -+:103970002070F0BDF0B5002800D1B8E00C1C00D1DB -+:10398000B5E04978CB0022785207520F1343C26941 -+:103990003F2109028A439906890C0A43C261A31C8C -+:1039A0009A07920F01D1196808E09B1AD2001D688E -+:1039B000D54020218A1A5968914029434163A31DAB -+:1039C0009A07920F01D1196808E09B1AD2001D686E -+:1039D000D54020218A1A5968914029438163231CCC -+:1039E0000A339A07920F01D1196808E09B1AD20096 -+:1039F0001D68D54020218A1A596891402943C16326 -+:103A0000231C0E339A07920F01D1196808E09B1A04 -+:103A1000D2001D68D54020218A1A59689140294357 -+:103A20000164061C5036E17C0902A27C11433180FE -+:103A3000637DF370237DB370A37DC373E37D8376D1 -+:103A4000237EC376A37E98210A58D200D208191C7F -+:103A50001D2349070A4398210A50217F0902E24C9D -+:103A6000FCFF617409007E1143F181071C9C372221 -+:103A70001C1D329107890F01D1156808E0521AC93F -+:103A8000001368CB402025691A55688D401D43BD41 -+:103A900065251C20356B78002B04D0C16C01229267 -+:103AA000061143C164AB78002B04D0C16C0122D253 -+:103AB000061143C164EB78002B04D0C16C012212C3 -+:103AC000071143C1642B79002B04D0C16C01225231 -+:103AD000071143C1641022691D301C1030BDF7541A -+:103AE000FA1022291C1531301C2030BDF74DFA4543 -+:103AF000342078F870F0BD10B5042810D24E214162 -+:103B00004334484418002020706070A01C0621BD7A -+:103B1000F75DFD314A1188201C0830BDF757FD10B4 -+:103B2000BD70B5FF230133C458002C03D0201CB551 -+:103B3000F79AFF0CE0061CC518142099F7EDFF0456 -+:103B40001E0ED02860321C25490023B5F76DFF24D6 -+:103B50004A11682448BDF754FE011C201CB5F76FBC -+:103B6000FF4CFCFF5C75090070BD10B5041E13D03E -+:103B7000F830006840070FD5201C28308DF7D7F8A3 -+:103B80001B490B68FF2B01D08DF7F3F8E069F82192 -+:103B9000884340210843E06110BD10B5041CFFF7C5 -+:103BA000E4FF13225C23195B002093F74EFCE069CD -+:103BB0000006C00E0A2803D10A21201C79F785F8D7 -+:103BC000201C7FF75AF8201C7FF785F9201C7FF70F -+:103BD00071F8206877F7CDFC10BDC046D3A5090069 -+:103BE0003EA40900F345020040A40900D4300000BF -+:103BF0008C06080010B5AC4AAC4900780302AC4C06 -+:103C000020680004184308601078C302086818434D -+:103C100008606068000423681B0C184348605078F3 -+:103C200088600020C860012010BC08BC184710B58F -+:103C3000041C00290AD18DF7F3FD70342078042884 -+:103C400015D19C484379012B11D10EE0022906D1F0 -+:103C50005030407F76F71DFD0023A38107E0052942 -+:103C600005D1004CFCFF57760900F0E7F800280169 -+:103C7000D18DF7B9FB10BC08BC184770B5904D2B1F -+:103C800068FF2B56D1002077F7E0FA2860FF285014 -+:103C9000D001238B4803608B4803708B4C0323E3D4 -+:103CA000748B480168201C6FF71DF92523237402CB -+:103CB0002363743323A374201C7030042303700027 -+:103CC00023437023632384824803685B0063842456 -+:103CD0002000230355E3818EF771F8286877F77386 -+:103CE000FD7D4E30607368802003437360286877E1 -+:103CF000F7F2FC211C503103680B77C269C86807D2 -+:103D000026B0433240104301225202104380221059 -+:103D100043C8600023CB750B6813430B6001238BF2 -+:103D20007702234B776D496D488DF7A8FB201C6FF8 -+:103D3000F75CF8012070BC08BC184770B5061C047D -+:103D40001C0023674803605F480378002B04D140C0 -+:103D5000235C490B60980527E04B0704D57034209D -+:103D600078042867D14CFCFF5277090044E08B07A8 -+:103D700024D5351C70352B78022B5FD169785648D5 -+:103D800002685A4803684B43301C934213D95300CE -+:103D9000638418360123737304232B703323A374B5 -+:103DA00000236B706FF7C2FA2023474E3360D805AB -+:103DB00078F791FA42E0013169701EE0CB073DD5FA -+:103DC000351C70352878022838D315D0042817D32D -+:103DD00034D147490868430E47490B6047488DF77F -+:103DE00044FB02232B704823A37440490B685B00FB -+:103DF0006384183401236373301C6FF797FA1DE056 -+:103E0000102331480360180678F765FA33480368D1 -+:103E10005B00638418340123637304232B70002335 -+:103E20006B70301C6FF7E0F835493548062202F018 -+:103E300062FD002802D133486FF7D6F870BC08BC89 -+:103E4000184731498868002805D0007C24380128AB -+:103E500001D8012000E00020704700B51D211C485A -+:103E600002F051FD1921274CFCFF4D780900480252 -+:103E7000F04DFDFF23274A1360144A1360002326E8 -+:103E80004A1370FF23254A13608DF7B4FA00BD1062 -+:103E9000B583B0041C0C22E92109036846BDF782F2 -+:103EA000F8694600200A7801312254174B1A540150 -+:103EB000300628F7D34B78A37103B010BD65A7096E -+:103EC00000B8890E0038800E00A42C08008C06086B -+:103ED00000D4500800BEC10800F0500800B0060829 -+:103EE000009006080000820E00D850080064000808 -+:103EF0000018800E009806080098830E00E4500811 -+:103F000000E05008000BA70900E8500800645108C1 -+:103F1000006C21080088060800BFC1080050A409F1 -+:103F20000000B5002346490B7046490B7046486FA8 -+:103F3000F79DF846490868FF2804D077F724FBFF6F -+:103F40002342490B60012342480360424803780141 -+:103F50002B04D18DF782FE00233E490B7000BD106B -+:103F6000B5041C70342378022B4CFCFF48790900FF -+:103F700024D13B4B1968043B1A68CB0717D4530371 -+:103F800015D54B0313D50723DB040B400FD1530684 -+:103F90001A0F032A0BD18B05DA0E082A01D00C2A3E -+:103FA00005D13048FFF777FF0323237006E0CB07E6 -+:103FB00004D46378013363706FF7BFF910BC08BC99 -+:103FC000184730B582B0041C27490B7E002B39D12D -+:103FD00026490B68702003401D09A37BAB4231D0FA -+:103FE00023490B68FE20034000D00123002B26D17B -+:103FF0000020B2F7D5FE002821D11E490B689B0690 -+:104000001DD48BF70BFE002819D16946281C9AF79E -+:1040100070F868466FF7F7FE68469AF79DF800203B -+:104020009AF7FDF81448002343628362009B9B08C3 -+:104030009B00416B59180B011B09436302E0A07BF5 -+:104040009AF7EDF802B030BD5CC80800BEC10800A8 -+:10405000F05008008C060800D4500800BFC10800CA -+:104060002C8B0E0038A509002C2D084CFCFF437A40 -+:1040700009000024860E00B4C4080008800E006CFD -+:10408000210800037B0C30FF2B04D14378202B0147 -+:10409000D1002000E001207047F0B582B00C1C0177 -+:1040A000D10420A3E0051C52480268002A08D02849 -+:1040B0001CC3F715FF002803D0FF300006000E9543 -+:1040C000E0F82148590007800F01282DD1E8690048 -+:1040D000042AD4237B5B0827D0474908688007233C -+:1040E000D5201CFFF7CEFF00281ED0281C28308DBD -+:1040F000F73DF9F822505902229043F822505120FE -+:104100001C99F735FD0821281C7EF789FC8CF77077 -+:10411000FF0123394A1370394A1168281C8CF7575C -+:10412000FF281C8DF793F8BBE72F687B0135481EED -+:1041300018F37F012B55D0237B5B080ED1637B05E1 -+:104140002B02D1304900910DE030490091042B0938 -+:10415000D0DB002E48C218009204E0201C0C307AFC -+:10416000F75AFD009000990B79637700234CFCFF10 -+:104170003E7B0900236002F0BCFB01900099486877 -+:1041800040010BD4B068002805D003682360B368F1 -+:104190001C60B46011E0B46024600EE0F068002898 -+:1041A00005D003682360F3681C60F46001E0F460EC -+:1041B0002460211C281C90F78CF80123BB40164971 -+:1041C000086818430860019802F09BFBE869000644 -+:1041D000C00E0A2803D1381C73F7A5FF09E0082890 -+:1041E00007D1381C6CF758FE03E0201C99F7C3FC7C -+:1041F0005AE7002002B0F0BDC046BCC80800641BEE -+:104200000800BFC10800885008007C29080044A3AA -+:1042100009004CA309006CCF05007429080070B593 -+:1042200082B0002301935F490868202800D1B6E0DE -+:1042300010285AD15D49086877F75FFA051C5B4E74 -+:10424000301C76F782FF002811D0041CF822135886 -+:1042500001221343F8221350EB69C06907210B4078 -+:1042600088431843E061286877F798F90CE02C4CF4 -+:10427000FCFF397C09001C311C281C28300622BC9C -+:10428000F79FFEF820435902208343F82043513121 -+:104290001C201C8CF7E5FD002805D0F820035901EF -+:1042A000200343F8200351201CFFF756FC02F024A2 -+:1042B000FB012321688B40404A11681943116002B9 -+:1042C000F023FB20686CF7F9FCE369F820834310C6 -+:1042D000200343E361206801216CF75DFE201C8F01 -+:1042E000F799FE201CFEF7C6FEFF233148036059F4 -+:1042F000E0FF23013398424AD12E4876F729FF0484 -+:104300001E50D077F795FBE369012000068343F840 -+:1043100020834310200343E361E36C5B005B08E30D -+:1043200064EC210B59000683430B51201C00217BB8 -+:10433000F70DFC201C00217BF764FC6B4601AA21D1 -+:104340001C4C31201C283096F764FA002806D00156 -+:104350009B002B03D0201C7BF75CF803E0211C00A2 -+:104360002078F73EF8FF23124803601448036801E1 -+:104370002B4CFC5C347D090018D1E3691B0415D477 -+:1043800011480368002B03D1104803680E480360EE -+:104390008CF700FD0AE0402802D18DF7D8FC05E03B -+:1043A00001235B02984201D18DF769FC012002B024 -+:1043B00070BDC046D45008008C060800E8500800C4 -+:1043C000B4C4080088C808008850080048A4090040 -+:1043D0004CFCFFBC7D09009F480023036083607094 -+:1043E0004770B59D490B68180A9D4A402803D19C27 -+:1043F00049D1609C4906E09C490143D16003021900 -+:10440000189B4BC9189B4D29609B4C9B4963685B6B -+:104410000E2468E407E40F634009D0402807D17FE9 -+:104420002464020B68964D2B400125ED0406E0FD47 -+:104430002424020B68924D2B400325AD040B600B26 -+:10444000682B430B6000238E4E336003040B21095D -+:104450000459182143032631438B4E31600F30102D -+:104460006070BD10B57C4A1368002B05D061210136 -+:10447000220A546EF75BFF05E0041C6EF7B5FD20C1 -+:104480001C00F0B0F810BC08BC184710B5041C7E26 -+:1044900048416A002902D1836A022B09D903290401 -+:1044A000D1836AFF203630834202D2201C6EF7F798 -+:1044B000FF60237648195D405C80210143754A11F5 -+:1044C000606D480368744A136043681720800603D0 -+:1044D00043534CFCFFB77E090060FFF785FFA37BC9 -+:1044E000704A136000236F4A1360082113206DF790 -+:1044F00067FE10BD30B5041C002927D1FFF7C9FFA6 -+:104500006A4D61342178694A0023D056012907D1C8 -+:104510007DF7B5FF0006010C2868654A104006E0EB -+:104520007DF7ADFF0006000E2968090A090208435D -+:1045300028604A4A11685F484143494A1068000AA6 -+:104540000430BDF76CF95C4A106014E0022907D111 -+:1045500001235A490B604034607F76F7A5F80AE0E2 -+:10456000052908D1002355490B60FFF76EFC002890 -+:1045700001D18CF740FF30BC08BC184700B5374A62 -+:10458000011C1368002B0DD09368002B0AD193896E -+:10459000936060310A780023022A00D2531C0B700A -+:1045A0006EF7C8FE08BC184700002C49037D022B9B -+:1045B00007D10868431E00D30B608868431E00D3F0 -+:1045C0008B60704710B5037D092B0CD13D4C3D4AE3 -+:1045D000106877F74CFC70B27F090000F92060602A -+:1045E000688021884360603A4AD078206210BC0815 -+:1045F000BC184770B583B00024364E4E256543ABDA -+:1046000019991C3548062202F07DF9002803D001D3 -+:1046100034042CF1D305E0A9194878000209780880 -+:104620004300E0002001A9C8700821000A02AA1076 -+:1046300070012301A883706846831D2848032293D4 -+:10464000F70DF803B070BD4CFCFF1E800900F0B5FB -+:10465000061C0F1C054C6368FF2B45D1012076F723 -+:1046600003FE6060FF283FD100207FE04CA40900DA -+:1046700094060800C8890E0040C07DC0447E00003A -+:1046800000D07DC0043E00008C800E0040A50900D3 -+:10469000B88A0E00FFFFC3FF94830E0098830E00BC -+:1046A0006C210800A8060800A4860E0040820E00B7 -+:1046B00000830E00F8800E0004830E0092030800B1 -+:1046C000FF00FFFF710200009C830E00F0FC0E0053 -+:1046D00000820E0050A409000BA70900D3A5090011 -+:1046E000B7C10800B6FC00002A4D0123EB74216914 -+:1046F000281C6EF706FC2760A389A360264979432E -+:1047000026480068000A0430BDF790F82449086084 -+:1047100024232B7402236B743123AB74281C603068 -+:10472000002303700123437000238370C3702B6246 -+:104730005D2002234355606877F754F8A87301237E -+:10474000EB73184F391C301C8C4CFC791981090013 -+:10475000F7A7FE606877F749F8391C6EF74AFA3117 -+:104760001C13480622BCF729FC2169281C6EF7DBC4 -+:10477000FB0120F0BD09480368002B00D001230095 -+:104780002B09D0007D002806D0072801D00020008A -+:10479000E00120002800D00120704764510800711A -+:1047A000020000940608009C830E0040A509000B3F -+:1047B000A7090000B5F8210B585B0702D40421803B -+:1047C000F720FB00BD4CFCFF9881090030B5051CAB -+:1047D000041C08790002C9780843012176F715FD09 -+:1047E000002802D112232B700EE00834F42109585E -+:1047F0004907490F00D00121A1715C300088E071A8 -+:10480000000A20720323EB7030BD000070B582B047 -+:10481000051C0024200123181B0145481E18F821FF -+:10482000885940071AD4306876F7DEFF69688842F5 -+:1048300014D1301C77F704F900280FD03D4B69469E -+:104840000B8002238B705C23985BC870000A01A95F -+:104850000870394A6946301C81F78AF801340B2CFC -+:10486000D8D30123354A1376686872F732FE686838 -+:1048700073F746FB6868B2F773F9696830486EF7FA -+:1048800028FE69682F486EF724FE69682E486EF787 -+:1048900020FE69682D486EF71CFE6C68002C45D11F -+:1048A0000C2363432A481D18A87A022831D3042810 -+:1048B0000ED32ED1281C82F704FF061C288000236B -+:1048C0006B72E87976F7184CFC9593820900FFA08B -+:1048D0003006810C3028E0281C82F7F6FE28800084 -+:1048E000236B72EB7999005B189B011B495E1831B1 -+:1048F0001CB831487100230B71C436B379002B15F5 -+:10490000D073792B80B3796B8033796B72281C82DA -+:10491000F7DBFE7071301D07E0002807D0281C82ED -+:10492000F7D3FE2880281C09300023037001340EC1 -+:104930002CB9D302B070BD88380800530C00004376 -+:10494000720100CC2F0800B42E0800682E08001C4D -+:104950002E0800D037080040490800140B08004C0E -+:10496000FCFF7E830900F0B5051C13235B049F4FF9 -+:104970003B60082105206DF706FC9D4F3B689D4874 -+:1049800003403B603B68C00703433B608B4F3B6881 -+:1049900002273B43894F3B60974C98482062012394 -+:1049A000974F3B60974FB868606278686065A86908 -+:1049B0002430C17880220A43934F3A60934E837823 -+:1049C000B07B002B0ED1924D0021B0F72FF9B169C9 -+:1049D000081C243042781302007B18430022B0F7F1 -+:1049E0003CFB09E00121B0F721F98A4D8A4A13689E -+:1049F0000120400603431360884805608848838A85 -+:104A00008848036000232360F0BD05238381836908 -+:104A10002633187801280FD10021CB4382490B603F -+:104A200000234B607D490B68802003430B607A496B -+:104A30000B68800403430B60704700B5C369002B0B -+:104A400023D013235B04694A13605F4A13685D4AED -+:104A500013605B4A1368594A1360554A1368644AE5 -+:104A6000134CFCC779840900607248724A1168418E -+:104A700060724A11684161714A11688160714A131C -+:104A8000680360704A1368704A136061486EF70FDC -+:104A9000FB08BC1847000030B5052383816C4A1120 -+:104AA0006806220A40062A02D181692A3108E08B71 -+:104AB0000702D481692C3103E04B0704D481692EAD -+:104AC000310B8801330B8013235B0449490B605081 -+:104AD00049CB69002B12D1524C2568C37B012B0CAA -+:104AE000D12368802083432360022099F747FC800C -+:104AF000231D43A06899040843A060256030BC08CA -+:104B0000BC184713235B043A4803604148C369005B -+:104B10002B02D1434803680360704700B5002901A8 -+:104B2000D1FFF724FF08BC184700004CFCFFAC86FF -+:104B30000900F0B581B0051C0C1C08790002C97889 -+:104B4000084352D00020ADF798FBFF2801D109237C -+:104B50004CE0071CADF752FB0023038121790902C9 -+:104B6000E27811438186C186051C83F79BF82E1CD1 -+:104B7000B03673885808E8806379252B0ED23948FF -+:104B800000900521BCF763FC6179C8084907490F0B -+:104B900001228A40009B195C11431954B07BFF230A -+:104BA0003D334343314819180091281CAFF74EFD9F -+:104BB0002F4885662521281CFDF7DBFF307B00216F -+:104BC000AFF783FF0523AB80381CAFF7CEFD00990C -+:104BD0009E3101200870381C002100F035F8A279C0 -+:104BE000E179381C00F005F801E012232B7001B0C8 -+:104BF000F0BDF0B50C1C171CADF700FB061C201D0A -+:104C0000B4F7DFFB051E1ED0B18D0B051B0D012077 -+:104C100040031843210408432B1CA907890F01D125 -+:104C2000186006E01870000A5870000A984CFCFFE3 -+:104C3000A787090070000AD8703A06120E210409ED -+:104C40000C281D91F75BF9281CB2F74AFFF0BD3024 -+:104C5000B50C1CFF233D3343430548C51801F074D0 -+:104C6000FDA2352C8001F078FD30BDC046F44E0821 -+:104C700000349D080038B0080000B5C37B012B0547 -+:104C8000D1AC490B78002B01D101230B70B2F7593D -+:104C9000FA08BC1847000000B52C22A749A748BC59 -+:104CA000F7B7F8A648A64B1860A6494160A6498107 -+:104CB00061A649C16100BD00B5017D032901D00491 -+:104CC0002902D1B2F7A2FA09E0037D062B02D10036 -+:104CD000F008F803E0092B01D1B2F7C8FA08BC18B4 -+:104CE00047000070B582B0051C041C8034E37A00D4 -+:104CF0002B08D0036DBE3319780820AEF707FD00EE -+:104D000023A376E3726378032B28D0A87B99F72B33 -+:104D1000F84008218C431A1E04360C618C00291DB2 -+:104D2000D08E421BD36078012806D1688CBCF74C2A -+:104D3000FCFFA2880900D4FC062803D13E2002E033 -+:104D4000042803D008202B6DAF3318700323637041 -+:104D5000281C6EF786F82B6DBE3319780520AEF748 -+:104D6000D9FC31E06068002808D00090002301934E -+:104D70006946A87B99F74DF9002363606378032B9C -+:104D800011D0FF201930285A864209D8A87B85F710 -+:104D90006DFB002804D1281CB2F7A7FD002802D023 -+:104DA0006D49C8780CE06378002B07D16B4BA87B6A -+:104DB000185C032802D26849887801E0664948787F -+:104DC000A874281CB2F783FC02B070BD70B5041C37 -+:104DD0000E1C5A4D2878002802D0013828702878F7 -+:104DE000012804D85E4A13685E490B40136000280E -+:104DF00016D0201C9830C378002B02D18188CA06B7 -+:104E00000ED58379002B11D0311C201CB0F7D1F9BD -+:104E10002B78012B0AD9311C201CB0F79DF905E035 -+:104E2000201CAFF762FE201CB2F70BFC70BDF0B582 -+:104E3000814CFCFF9D890900B0041C051C803500D5 -+:104E400027AF81EF76FF230533C618F37D0133F3D7 -+:104E500075C37B012B13D17378002B19D144480300 -+:104E6000689B0715D5A07B98F785FF80084100A0B7 -+:104E70006981420DD098F719FF4000686008E00191 -+:104E800023737036480378A3740123DB07B361B73B -+:104E900070374800680090830722D535490B685B5E -+:104EA0000602D40098430710D5A07B98F763FF4013 -+:104EB0000828846B78012B08D102236B70236D586E -+:104EC0008900016884201CB2F7AAFAF37D012B0740 -+:104ED000D17DF709FA011C201CAEF7A0FC01F0E51A -+:104EE000F97DF701FAB074009906220A40062A1EDD -+:104EF000D1236DBE33187885F7EDFA201C00F0BF82 -+:104F0000F8F078012804D81B4980000B5C01330BB2 -+:104F100054E37B0099201C002B02D1FFF75AFF01BC -+:104F2000E000F06DF8201CAFF7E3FDAF7234E0B79E -+:104F3000758B074CFCC8988A09002AD5A87A1049B5 -+:104F40000B78984225D21EE0C046FDCC080078E4DC -+:104F5000050080A50900781508002B8809009B89A9 -+:104F60000900ED87090074150800E3C008001C80E3 -+:104F70000E00FFBFFFFFBC8B0E0040150800ECB019 -+:104F800008001CCD0800E37B002B02D00130A87282 -+:104F900006E02B7E002B00D02F76201CB2F758FBAA -+:104FA00001B0F0BC08BC18470000F0B5061E20D0C8 -+:104FB0000768002F1DD0407CADF72EF9051C707CD2 -+:104FC000182141430C484418786890F7CDFD98F7B4 -+:104FD0004EFD381C98F705FD00233360217A01311E -+:104FE0002172217A05480278A88D90F702FD0023EE -+:104FF0002372F0BDC046F4B008007C1508004CFCDC -+:10500000FF648B090070B5051C0E1C041C8034A3C2 -+:105010007F002B1ED0B0F7D3F8184A537C012B0920 -+:10502000D9E37E002B02D1A08BC10603D5311C2809 -+:105030001CB0F798F8CD23585D00280AD0FF23054F -+:1050400033E818837D002B04D04378002B01D10175 -+:105050002383700B490B681B070FD56378022B0C59 -+:10506000D1FF201630285C002807D0A0898004805A -+:105070000E0023002800D10123237670BDECCC085C -+:1050800000E02C0800F0B5041C051C3A480668989E -+:1050900035A8880712F306D90FE9707307D90F03F3 -+:1050A00007DA0F002F04D0344803685B0300D511E2 -+:1050B0001CFF231533E0184378002B03D10029018E -+:1050C000D0012343708A4216D0AB79002B15D10052 -+:1050D0002F08D0D0231859C168C91BC16002D483DE -+:1050E00068DB1983600122AA71201CB2F7EDFB2056 -+:1050F0001CAFF7E0FB01E0002383713307DA0FA850 -+:105100004CFCFF5F8C0900884307D90F8A4234D1D9 -+:105110001C4F397C0A0702D5B304990E2DD1184AC9 -+:1051200013689B0303D5B3079B0F032B25D00421E2 -+:105130004840A880251C5035AE87B304980E1CD07B -+:1051400020221149BB68181D01F004FBCC342078E3 -+:10515000800712D50D490B68012080030340580BCE -+:105160000BD02B68BE331878ADF759F8AF303D211E -+:105170000170012028870023AB87F0BDA88B0E00AB -+:10518000E02C0800ECCC080080980E00BC8B0E00D0 -+:1051900010B51F4C2068002805D08008800098F7C3 -+:1051A00023FC0023236010BDF0B5051CC668B4695C -+:1051B000002C16D0B0F797F9002812D1154F3A1CE1 -+:1051C000211C1331E01CB0F76FF8381C00F00AF80E -+:1051D0000023AB60EB60A008800098F705FC00237B -+:1051E000B361F0BD00B582B0262369460B80019003 -+:1051F000081C76F789FF02B000BD00B54368002B9C -+:1052000004D04CFC1E5A8D09001022044800219243 -+:10521000F768F900BDC046E49C08001CA709001708 -+:105220002000004CFCA0908D0900F0B583B00291E5 -+:10523000FF233D3343432248C618356D01F08BFAF6 -+:10524000371C90372C1CB0348E239A5B02998A1A33 -+:105250001204120C638853433A6FD2185101490962 -+:10526000019101F080FAF37B012B0ED16B8B5B0077 -+:105270000093288B4000019A101841014909181C1D -+:10528000BCF725FAA0800098E080281C82F714FD66 -+:10529000F37B002B0ED1E68870086883A188019803 -+:1052A00098F703FDE288011C101CBCF710FA301AB5 -+:1052B000400828830298431E3B800123BB7203B041 -+:1052C000F0BD349D08004CFCF8348E0900F0B58127 -+:1052D000B00090ACF79CFF041C0027364E336BDB0C -+:1052E000071FD5B4421DD0251C2C354223A97D9A19 -+:1052F0005D914216D1291C1031301C3C3006220130 -+:10530000F039FA00280DD101F025FA051CBE36301F -+:105310007800F036F8281C01F025FA3078AFF75203 -+:10532000FA03E0C03601370F2FD8DB0098B2F7A39D -+:10533000FB251C0123EB852C35201C80F78BFE0000 -+:10534000980021AEF78BF81C4A13681021DB060386 -+:10535000D5A971201CB3F717FA201CB1F7D5FBBEF5 -+:10536000342178FF223D325143144BC9187F23FF6B -+:105370002023300B54A623FF2017300B5401B0F02C -+:10538000BD10B5FF233D3343430C48C418201C8097 -+:10539000304178012907D1418C608CBCF7A3F90614 -+:1053A0002803D13E2002E0042903D00820236DAF5A -+:1053B00033187010BD2890080040150800349D086F -+:1053C000004CFCC0308F0900F0B5061C046D2B4862 -+:1053D00003689E4201D1B0F7EBF8301CAFF727FF0E -+:1053E000351C8035288901380ED32881288904236B -+:1053F0006B70002808D1301C6DF735FDBE34217864 -+:105400000520AEF789F938E0687800281FD1B07B15 -+:1054100098F7AFFC4008B034A16898F745FC012329 -+:105420009B0698420CD267883B1859014909381CE1 -+:10543000BCF730F97843A168081840014009A06022 -+:10544000A06800236B700223F374B06112E002289D -+:1054500010D1AB7E002B0DD0E889298A431A18049D -+:10546000000C074B984205D2EB7A002B02D1301C7E -+:10547000B2F77FF8301C6DF798FEF0BD6C21080084 -+:10548000FF7F00004CFC9028900900F0B5051C1F20 -+:1054900049FF230533C418E378980000230B5443D5 -+:1054A00018581C00230370AF692B6D1889421C2605 -+:1054B0007C688C5043B04063681B18580140093821 -+:1054C0001A01239B06984220D2B31D20789840A34E -+:1054D00068D901EB7B002B00D15143E26882420086 -+:1054E000D3101CBCF7BCF8011C802800D980219F78 -+:1054F000352970074803789E4202D2701C2074043C -+:10550000E000230434191C381C0BC4F0BDC046EC69 -+:10551000B008006F1508004CFCE8C0900900F0B519 -+:10552000061C071C9C373888102101401D490BD0F0 -+:105530001D4BF518EB7898000A5C9301AA68D21805 -+:10554000AA604318597811E0174BF518EB789800CA -+:105550004118487800280DD08C780978614389017A -+:10556000BCF77BF8A9680918A960211C8B01E868C1 -+:10557000C018E8602B7C002B11D1E86800280ED001 -+:10558000AB68D901F37B002B03D1336D1A8901324B -+:105590005143BCF762F8802800D98020F870F0BD34 -+:1055A000C046ECB0080004010000F0B50D1C114C21 -+:1055B00020600B68DB0701D598F758FB0F4E0020E1 -+:1055C000706637680E483840306098F764FE98F788 -+:1055D00062FE2868E0606868A0600220706698F744 -+:1055E0005AFE98F758FE98F756FE37600020E060A4 -+:1055F000A060F0BDC04600820E001C800E00FFFFC0 -+:10560000FFFD4CFC34AC91090000B54068084A131A -+:10561000681979002909D1074A13681B0605D400C7 -+:105620002801D098F7BBF9012000E0002000BDC0A0 -+:1056300046C04F0800E02C08004CFC7CF8910900A3 -+:1056400030B5041C80304378002B1BD10323E37456 -+:10565000252101230B55837E002B07D0236DD98B89 -+:1056600009014184A36903840123C372618CA06989 -+:1056700074F772FD238C984204D02084216DB031E0 -+:1056800088800880FF230133E158E518A06998F766 -+:10569000E3FA216DB2310A88011C101CBBF7D2FF5E -+:1056A000011C201CB2F726F8A3692B60201CAFF761 -+:1056B00034FF00236B7130BD4CFCFF80920900F079 -+:1056C000B581B02F4806682F4805682F4803780039 -+:1056D0002B52D12E480368AB4203D12D480368B347 -+:1056E000424AD02C4C2D4FFE20284007D1002D03DC -+:1056F000D02B480368DB0301D5002E1CD063681B48 -+:10570000071B0F022B02D0022098F739FE25480014 -+:1057100078606324480078A06366F7B7FF01F00D56 -+:10572000F8822141432068642250436430BBF785EE -+:10573000FF431C3B6018E063681B0702D000209801 -+:10574000F71EFE00206063A063184A1368009317D9 -+:105750004A1088392109014143181CBBF76EFF38F4 -+:105760006014490098BBF769FF134908603868A0C6 -+:105770006107490D6007490E6001B0F0BC08BC1814 -+:1057800047C04614CD0800B4C4080008C30800B8D8 -+:10579000CA080068A409000C000F00DC5E0800FCC9 -+:1057A0000A080009C308000AC30800C02D0800E861 -+:1057B0000A080020CF01009C000F4CFC657B930978 -+:1057C000000030B5041C13490B685D78B0F75DFF2D -+:1057D000022C01D0042C16D1281C203081F7A9FE00 -+:1057E000042C07D10D4800231A1C191C91F745FE03 -+:1057F000022102E0022C03D10821281CADF705FE8E -+:10580000281CACF782FD05490B689879012801D165 -+:10581000ACF7E4FD30BDC49C08000E200000C89C1D -+:1058200008004CFCFFEC930900F0B5041C00216E4D -+:10583000F74CF8002803DA01234E4843716FE00665 -+:105840001C251C7835687A00280DD1A07B98F76359 -+:10585000FA4008236DB833196898F7FFF900280457 -+:10586000DC687A002805D0002E03DD201CB1F7BDCE -+:10587000FE55E0E37B012B03D1002801D101236B0E -+:1058800072A878802101433C4A1160082105206CF0 -+:10589000F7A4FB384A5379002B41D1AFF75BFE37B1 -+:1058A0004F381C052100F040FF03233B74201C00EF -+:1058B000F037F8AFF70CFEEB8A002B0AD1FF201669 -+:1058C00030205C002805D1AFF745FE3B7C08200363 -+:1058D000433B740023AB74FF230533E6180023F326 -+:1058E00075201CB1F788FF264A13780021002B0091 -+:1058F000D101211170F078FF2806D16B7A022B03B9 -+:10590000D1081CF070A3697360012805D8F1708B71 -+:10591000001C48C0187B7C8370201CAEF7ADFFF0E4 -+:10592000BD30B5844CFC71E79409007C18490B78B4 -+:105930008374051C012200216DF769FEAC742C6D87 -+:10594000B223195B0239884200DB081C114941432C -+:10595000E5208000BBF774FEFF210531695C8842B9 -+:1059600000D3081C32342178490701D5012801D819 -+:10597000002800D101200349487430BDA42C080040 -+:10598000A4860E00ECCC08006C150800ECB00800F2 -+:1059900074150800710200004CFCFF5C950900F0D2 -+:1059A000B583B0012100910027C0237B431A481C16 -+:1059B00018206BC00729D5251CBC356B78002B241B -+:1059C000D1261CE38D2C36002B1FD0B379002B027F -+:1059D000D00021009119E0211C0C310F4805220054 -+:1059E000F09EFE002811D00223B371201CB2F72ACA -+:1059F000FE01A9201CB2F712FE01A9A878B1F7ACEC -+:105A0000FE082201A9A878B2F72EFF01370F2FCB8D -+:105A1000D3009803B0F0BD28900800004F08001094 -+:105A2000B5002912D140498B79002B0BD03F490B8F -+:105A300069834207D13E4C2368DB0603D54631011A -+:105A40002008700EE0AFF751FF0BE0022909D101E9 -+:105A50001C48318A880B7E9B18013383814B889BBD -+:105A60001A4B8010BC08BC184730B5314A11680B7E -+:105A700006D90F884218D12F4D2C68ACF798FCC17D -+:105A8000780B028178194302791304194342791380 -+:105A90000619438C4208D12A1F134CFCFF57960964 -+:105AA00000681A0C41780B0200781843824201D03A -+:105AB000002000E0012030BDF0B583B0051C00914E -+:105AC0000026041C58342379002B2CD0012601A871 -+:105AD000B0F723FA071C6379002B13D0E378012B6E -+:105AE00007D13023585DFFF7C3FF002801D1061C02 -+:105AF00019E02835AB79012B04D101A9381CB0F786 -+:105B0000C1F8061C0F480378002B0CD0012F0AD1D6 -+:105B1000029B03208003034001208003834202D1C3 -+:105B2000012300980360301C03B0F0BDC046AC21D7 -+:105B30000800642C080008800E00A88B0E008898CE -+:105B40000E006C9C0800F0B50D1C041C002D14D137 -+:105B50004B488379002B0CD04A480369A34208D1F3 -+:105B6000494A1368DB0604D5031C4633012018702C -+:105B700036E0201CB0F7B5FD32E0FFF754FF022DF0 -+:105B80002ED1414A131C5421085B0004271C5237B4 -+:105B90003988084318644433251C56354CFCFF52A1 -+:105BA000970900A807800F01D12E6808E02D1AC0C0 -+:105BB000002968C1402026301A6E6886400E431EB8 -+:105BC00060A36B002B0CD1A06EC16B91603C304583 -+:105BD0007908212D0200792843D06013680B431304 -+:105BE00060A06E806A9064F0BC08BC1847F0B58273 -+:105BF000B0041C051CB0F75BF858352B79002B312D -+:105C0000D0EB78012B10D1201C28308379012B0B8D -+:105C1000D16B79002B08D1007AFFF72DFF00280304 -+:105C2000D1201C6CF796FC1DE0EB78012B1AD8A64E -+:105C30006E6846B0F775F96B79002B0CD1071C69BB -+:105C400046301C3C300622BBF7C5F8423637706C34 -+:105C5000340120207012E02E231B5D012B02D1693C -+:105C600046B0F713F8A37C0B498878834202D12011 -+:105C70001CB0F768FE201C0121AFF712FF02B0F044 -+:105C8000BC08BC1847AC210800642C080008800E32 -+:105C900000808B0E0074150800034B0448034CFC75 -+:105CA0004B4D98090060044B044803607047C046A0 -+:105CB000BCA3090050150800E8A3090064150800FA -+:105CC00010B5041C6CF749FC201C6DF7ACF84A2396 -+:105CD000002018536523195D0220ADF7FDFCA36E6B -+:105CE000BC3318780021AEF7D9FE10BD4CFC18BCAF -+:105CF00098090000B5011C32310B78FB2213400BD0 -+:105D000070AEF7E5F800BD4CFC50E0980900F0B526 -+:105D1000061C0F1C104D2C68A07B97F7F5FF800820 -+:105D20004300991C608CA26983185801400997F7B9 -+:105D300086FF041C002F0BD0B17B2B68987B6DF77E -+:105D4000BBFF002804D1032C01D8002400E0033C51 -+:105D5000201CF0BDC0466C2108004CFCFF349909A2 -+:105D600000F0B586B0061C4568039581780A0712D5 -+:105D70000F0092C07802908F0943191A790592009A -+:105D8000200490C04A13681879002804D1BE490B3A -+:105D9000681B0600D4C9E10098062800D9CAE105AD -+:105DA00098002808D0122806D0301CAEF783FA00DD -+:105DB0002800D1BAE1BEE1B54C2378B54908798312 -+:105DC0004202D3201CADF772FAB148418800292362 -+:105DD000D00378002B10D06378002B04D0AD489806 -+:105DE000F75DFB002818D000236370A370A84A5009 -+:105DF0008850214143A74805E02378A648002B049A -+:105E0000D15022514398F7FFFA06E098F747FB007C -+:105E10002802D0201CADF74AFA20782923191C410A -+:105E2000430191E11C8807800F01D10A6808E0094D -+:105E30001AC0000B68C3402022101A4A6882401A18 -+:105E4000430198954B0099C95C81548018009903CF -+:105E50002901D0052957D18C4A13681B4CFCFF2F10 -+:105E60009A09000600D44EE1477002998B1F037215 -+:105E7000291C09300622BAF79FFF0635E11C880766 -+:105E8000800F01D10A6808E0091AC0000B68C340FE -+:105E90002022101A4A6882401A4301988018023062 -+:105EA000291C0622BAF788FF0098052817D1063565 -+:105EB000E11C8807800F01D10B6808E0091AC000B7 -+:105EC0000A68C2402023181A4B6883401343019983 -+:105ED000C8180F30029A0C3A291CBAF76DFFE11C62 -+:105EE0008807800F01D10B6808E0091AC0000A6812 -+:105EF000C2402023181A4B68834013430199C818E5 -+:105F00002830F17872688918C9780170FEE0FF07BF -+:105F1000FF0F0098042806D05C4A1368F178706877 -+:105F20000818C078587259490868C379012B18D1EC -+:105F3000391C281CADF7F0FC009A042A05D1ADF7F6 -+:105F40000DFD002800D1E4E04CE0FF2803D1391C0E -+:105F5000281CADF736FDADF716FD002800D14CFC2E -+:105F6000FF2A9B0900D8E040E050490B78002B3C09 -+:105F7000D0009A042A17D14D480490291C103006ED -+:105F80002200F0C9FB002800D0C6E00499887D03F8 -+:105F9000071B0FBB4200D0BFE08023034000D1BBF2 -+:105FA000E04006400E1FE009228356012008568378 -+:105FB0004200DAB1E03E480490291C10300622006D -+:105FC000F0AAFB002806D10499887D03071B0FBBAC -+:105FD0004200D1A1E0291C049810300622BAF7EF44 -+:105FE000FE8023381C18430499887501210491E12F -+:105FF0001C8807800F01D10A6808E0091AC0000B4D -+:1060000068C3402022101A4A6882401A43019880CF -+:10601000184770291C02300622BAF7D1FE20480327 -+:1060200078002B19D0E11C8807800F01D10A68087D -+:10603000E0091AC0000B68C3402022101A4A688287 -+:10604000401A4301998818F17872688918ADF7D71A -+:10605000FD0006000EFF285FD106350298FA3000D9 -+:106060004CFCEF259C090006000E02900098E11CF4 -+:10607000012822D18807800F01D10B6808E0091A96 -+:10608000C0000A68C2402023181A4B68834013439B -+:106090000199C8180021017225E0C04F0800E02CCA -+:1060A00008005DC30800BC9C080093C3080014E30B -+:1060B000050068C30800B8AF08008807800F01D149 -+:1060C0000B6808E0091AC0000A68C2402023181AA9 -+:1060D0004B68834013430199C818029A0272291C25 -+:1060E0000930BAF770FEE11C8807800F01D10B68F8 -+:1060F00008E0091AC0000A68C2402023181A4B6839 -+:10610000834013430199C8182830F17872688918C0 -+:10611000C97801700498002802D0237801332370D5 -+:1061200023780A490879834202D3201CADF7C9F8C5 -+:106130000598122804D1AEF781F9AEF7B6F904E05C -+:106140000398002801D097F71CFC06B0F0BDBC9C5A -+:1061500008004CFCFF189D0900F0B586B0041C0136 -+:106160002203920292002200923249051C08682004 -+:1061700035EB7A012B02D1304A117801E02E4A51D9 -+:1061800078A17406220240062A51D12C4A166832A0 -+:1061900007120F019201070BD529490B68987B0064 -+:1061A0002805D0301CAFF7F0FF0090029000E0030C -+:1061B00090244F019805282BD1EB7A012B28D83356 -+:1061C00006D90F287B414023D1ACF7F0F879680459 -+:1061D00091B968059104A90231062200F09FFA00E6 -+:1061E0002816D10398002813D00298002810D02038 -+:1061F0001CB0F7B5F8009900290AD0201C6CF7A153 -+:10620000F911490B68DB0703D4201C0021AFF75EAE -+:10621000FF0E490B681B060AD50198052801D0031B -+:106220002805D1391C3004000C0022ADF7F4FA0621 -+:10623000B0F0BDC046BC8B0E005C150800A88B0EEC -+:1062400000B89C080080980E0008800E00E02C0822 -+:106250000010B5564CFCFF139E09004C822099F7A4 -+:1062600025FA000600160022A15600290ED0CB10F8 -+:10627000CA1AC310D2187F23DB439A4201DA181CD2 -+:1062800004E07F207F2A01DC1006001601060916B3 -+:106290002170494A1368002B01D14848C17710BDCD -+:1062A00070B5002644480368002B01D184F784FDB3 -+:1062B000434C4449201C0F300522BAF787FD0025C6 -+:1062C0002819C07B97F74AFF36180135052DF7D3FB -+:1062D0003D48C36A5B011CD53C4803685B0518D484 -+:1062E00000253B4803789E4213D001200A2D00D997 -+:1062F000022040194100374885F7D4FC002805D01A -+:10630000291C201C0F3085F7DFFC013E0135252DAF -+:10631000E7D3211C0F313048052200F003FA002892 -+:1063200009D0211C0F312C480522BAF74FFD6369B3 -+:106330000120834363616369DB0707D4FFF732FB06 -+:10634000616901229143104001436161002070BCEA -+:1063500008BC184700B54CFC9A0E9F090075F7035E -+:10636000FB00280BD11F480368002B07D114490BF1 -+:10637000681D490868834201D1012000E000200027 -+:10638000BD00B5B821194800F0D8F900230B4A1315 -+:106390007000BD10B5041C15480368002B0BD020FD -+:1063A0001C002185F794FC1821201C85F790FC4ED9 -+:1063B00021201C85F78CFC10BDC0466CA70900B4D9 -+:1063C000C4080050370800F4460800F44E08005492 -+:1063D00020080020040800A4030800E0340800009E -+:1063E0004F080010CD0800E4C708009034080014DE -+:1063F000CD08004CFCCCCC9F090030B55049086852 -+:10640000504D09280DD14F4A1068411C1820BBF788 -+:1064100034F903234D4A1370AB78834250DAA870E5 -+:106420004EE000234A490B704A4C012801D007284E -+:106430001CD120680022191C99F7BAFB464908684C -+:10644000FF230133984203D20122002199F7B0FBC8 -+:106450009BF782FF2B68DB0102D53F49086802E009 -+:106460003E490B6858003D490B6818602B685B007B -+:1064700002D501233B48037031490868012801D047 -+:10648000072811D120680022012199F791FB20688B -+:106490000122022199F78CFB3349206899F712FCFD -+:1064A0002068012199F7EBFB254803680C2B07D1E5 -+:1064B0002C480378012B01D9012303709EF7A9FE14 -+:1064C00030BD4CFCE044A10900F0B5324A106883AD -+:1064D000025C0F8307DD0F4303DE0FCB780727FF36 -+:1064E00004B8435F07BF0A384310600B795B004F65 -+:1064F00079FF07FF0F3B435B008F79FF07FF0F3BDF -+:10650000433E27B843DF06BF0E38431060CB790106 -+:106510002189048843D907490B0843106083025B33 -+:106520000F9C420AD1002C34D110688307DB0F9DE9 -+:106530004203D14303DB0F9E422BD017480478005F -+:106540002C27D1A00023189B0114481D18D02148E6 -+:1065500059C0041BD5E4214859C004C00E072815B2 -+:10656000D300F06EF8061C281C8EF767F90C4B9AC6 -+:106570008AD0235859000B00031105090D08435810 -+:1065800051281C8DF762FF301C00F062F8013403C3 -+:106590002CD7D3F0BD4C0B0800DEC00800941C08BB -+:1065A00000942008004CFCFF2CA2090070B5051CCB -+:1065B000006813498B7B002B1DD012498B79002B6F -+:1065C00019D0030CDC1D10480440201CB2F776FEE5 -+:1065D000061C08D0221C291CBAF794FB281C97F72C -+:1065E000B5F9301C08E0281C97F7B0F900209CF79B -+:1065F000D8FF032002E0281CB1F7ECF970BDC046BB -+:10660000300B080080150800FCFF000078470000F0 -+:1066100000C09FE51CFF2FE1E05105007847000016 -+:1066200000C09FE51CFF2FE17410050078470000B3 -+:1066300000C09FE51CFF2FE160E8010078470000E3 -+:1066400000C09FE51CFF2FE17CD7040078470000C5 -+:1066500000C09FE51CFF2FE190D7040078470000A1 -+:1066600000C09FE51CFF2FE1FC40050078470000BB -+:1066700000C09FE51CFF2FE1304F05007847000068 -+:1066800000C09FE51CFF2FE1CC5105002300000056 -+:10669000394D090024000000354D09002500000097 -+:1066A0003D4D09003500004CFCFF27A309000049BF -+:1066B0004D090088000000894D09008D000000ADE3 -+:1066C0004D090092000000000000000000000003DF -+:1066D0000000025946020004000100000000000012 -+:1066E00000000000000000000000000000000000AA -+:1066F00000000000000000955102002376090029E7 -+:106700007709003F79090000000000000000000048 -+:106710000000006754020000000000A37F09000091 -+:1067200000000000000000D37E0900497E0900003F -+:106730000000005B7F090000000000897F090087DE -+:106740005102009F9504006D9904007F930400009E -+:10675000000000DD95090000000000A7960400007D -+:106760000000000000000005990400C39304009F8E -+:106770009504006D99040091A2040000000000FD42 -+:10678000960900000000009D97090093A304006192 -+:106790006709008F670900C3930400420500005E8B -+:1067A0000400006204000042054CFC4A22A40900D7 -+:1067B00000006C04000062190000440500006C0435 -+:1067C0000000621900000A00000001002100A086FC -+:1067D00001000C0019000200000000180000FF007A -+:1067E0000000800200008002000090A30900001851 -+:0D67F0000008030000004EFC04FFFFFFFF47 -+:00000001FF -diff --git a/firmware/ap6210/fw_bcm40181a2.bin.ihex b/firmware/ap6210/fw_bcm40181a2.bin.ihex -new file mode 100644 -index 0000000..a8e3092 ---- /dev/null -+++ b/firmware/ap6210/fw_bcm40181a2.bin.ihex -@@ -0,0 +1,13727 @@ -+:100000000000000091EC000055EB000055EB0000F3 -+:1000100055EB000055EB000055EB000055EB0000E0 -+:1000200055EB000055EB000055EB000055EB0000D0 -+:1000300055EB000055EB000055EB000055EB0000C0 -+:1000400055EB000055EB000055EB000055EB0000B0 -+:1000500055EB000055EB000055EB000055EB0000A0 -+:1000600055EB000055EB000055EB000055EB000090 -+:1000700055EB000055EB000055EB000055EB000080 -+:100080000048004791EC0000000000000000000064 -+:100090000000000000000000000000000000000060 -+:1000A0000000000000000000000000000000000050 -+:1000B0000000000000000000000000000000000040 -+:1000C0000000000000000000000000000000000030 -+:1000D0000000000000000000000000000000000020 -+:1000E0000000000000000000000000000000000010 -+:1000F0000000000000000000000000000000000000 -+:10010000D11E8000B5228000BD248000491F8000E0 -+:10011000F9218000A9160100F1208000D120800083 -+:10012000594880006948800015648000E1628000C1 -+:10013000296280003D6580008D628000C56280007C -+:10014000596380005D6580007D6380009D63800051 -+:100150000D668000A961800061618000756080008B -+:1001600095608000DD6380009D65800029668000C9 -+:10017000FD618000B96580001D618000F16580002F -+:100180009D6680006D658000916C8000CD6B800065 -+:10019000316C80008D6B8000556C8000AD6A8000F2 -+:1001A000C16A8000D56A8000496B80001D6A8000AA -+:1001B000FD6A8000AD688000C1698000D168800060 -+:1001C000356B8000B16980004DF10000D166800080 -+:1001D000E16780008D678000CD6780009D688000AA -+:1001E000ED678000BD678000A1678000ED6680003C -+:1001F00009678000616780004D4880001D488000CD -+:1002000085988000DD96800051948000B19B80002D -+:100210003994800005988000199880002D988000FE -+:10022000C59B8000D19A8000899D8000D193800079 -+:10023000D9918000ED9A80002129000099170100D2 -+:1002400079290000C1170100519B8000BD290000E1 -+:1002500049A9800099988000F529000031A8800004 -+:1002600005A7800021A28000BD938000DD9380005F -+:10027000199E80007D93800045988000E59B80005A -+:100280006DA68000C19C8000C59F8000A19D80005C -+:10029000F5988000851701005517010029AA8000F4 -+:1002A000B9A9800075AA8000E1A9800039AA800060 -+:1002B0008DAA80005DAA80000DAA8000C5A98000DB -+:1002C0009DA98000A90C8000850D8000C1068000DA -+:1002D00029088000694680004D468000D94480008E -+:1002E0004146800021448000F54380001544800091 -+:1002F000E1438000E1428000854680007544800033 -+:100300002D448000A9428000F9428000CD43800046 -+:10031000B9458000F544800039458000090080001F -+:100320003D00800049018000D10480000D04800060 -+:10033000910380004D038000E503800035038000B9 -+:100340006503800029028000CD02800051028000F8 -+:1003500085028000F5028000950680003906800045 -+:100360008105800005068000FD048000690F800083 -+:100370002516800015168000451380001513800097 -+:100380002513800009138000351380000D1E8000A6 -+:10039000F91D8000291D80001D1C8000391C800073 -+:1003A0003116800059138000192C0200951380002B -+:1003B000B91C8000C5270000452D0200751D800076 -+:1003C000A90F01003D1D80000D1B8000E910800079 -+:1003D000790F8000A9168000311480002D11800053 -+:1003E000A51E8000B11E8000BD1E8000692B80000C -+:1003F000AD28800011298000892B8000FD2B800012 -+:10040000E128800065288000B52C8000912C8000B8 -+:100410001D2B8000752D8000252C80004D30800024 -+:10042000DD2D800059278000313180002118010026 -+:100430008D268000C5268000E5248000FD268000F2 -+:1004400021258000B12A80006525800025288000B4 -+:100450006129800041298000D92980009D298000E0 -+:1004600081298000893080004D2E8000B12B8000D2 -+:10047000312C8000E12C8000613280002D32800020 -+:10048000C93380004D368000693A8000B535800060 -+:10049000F9348000A93480003D3380009D33800012 -+:1004A000013480003536800031388000353A8000D4 -+:1004B000213A8000AD3280000D338000DD328000B3 -+:1004C000953A8000D937800099368000193780002E -+:1004D000593880004938800019398000313D80004A -+:1004E000D53A8000C93C8000E13B8000513D80004E -+:1004F000D93D8000AD3E8000593F80009941800089 -+:1005000041478000CD5B8000895380002D4D8000E5 -+:10051000A94C8000E14D8000E94F8000B14F800080 -+:10052000C94E80008D4E8000F15180005D528000E8 -+:10053000D15180002D52800001528000C94F8000AF -+:10054000594C80006D4C8000455B8000395680001E -+:10055000155A8000C9588000315A800081578000A8 -+:10056000F95980001D568000AD55800091558000DE -+:100570004D5A80002D558000714B800071548000D1 -+:1005800009548000F54D80001D4C8000F94B80001F -+:10059000094C8000114E800015588000C9110100DF -+:1005A0002D508000E5588000555680007D5A80000F -+:1005B000054F8000354E8000D9558000515880008D -+:1005C0009D57800059518000614D8000B1488000E6 -+:1005D0005D5B800081528000494C80003515010030 -+:1005E000F15B8000E55C8000E15F8000A55E80003B -+:1005F0007D5E80008D5C8000015C8000A15F8000DA -+:10060000895D800005608000395D8000D15E8000DA -+:10061000495E8000ED6C8000656D8000DD6D8000BE -+:100620000D6D8000296D8000896D8000F96C80005F -+:10063000D96C80003D6E8000616F8000756E800017 -+:10064000056E8000A974800055758000D574800007 -+:1006500005748000D17C8000457D8000757C800021 -+:10066000117E8000897E8000E97E8000917D80007F -+:100670003D7E8000517F8000A581800065848000E0 -+:10068000418480008D8380006583800035858000F3 -+:10069000E58480009D848000218580007584800031 -+:1006A000BD8380005D858000BD858000158F800042 -+:1006B000918D8000D58980001986800019AB80005B -+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E -+:1006D000FDB080007DB1800065B080006DAE80000F -+:1006E00085AE8000EDAD800041AF80001DAE800082 -+:1006F00031B180003DB18000B9AE8000F5B180001D -+:1007000079B08000FDAD800009B180008DB080001F -+:1007100049B1800069B180004DAE80003DAE8000DF -+:1007200095AE800029B38000C9AE8000CDAF8000B7 -+:10073000E5AF800025B080008DAF8000B5B28000AD -+:10074000FDB2800019B38000EDB080005DAE800086 -+:100750002DAE800029B28000A9B08000A1B1800038 -+:1007600005B2800039B28000A9AE80007DAF800064 -+:10077000ADB38000A9BD80009DC1800025C7800069 -+:10078000DDC8800065CA8000E1CB8000DDCE80003E -+:1007900019CE800099CE800015CF8000E52C000096 -+:1007A0000DD88000DDD7800091D78000B110010006 -+:1007B000CD2B000069D880007DCF800045D9800016 -+:1007C000FD10010099D1800025110100F9E08000A1 -+:1007D00071F58000152D0000D1DE80008D21010013 -+:1007E00009EA8000A1E4800045200100E1EC8000DE -+:1007F00011E3800039EA800039E3800099E380004A -+:1008000029DF800005220100A120010075220100DE -+:10081000352301007D230100BDEB8000952D0000F4 -+:10082000152E00001922010091220100CD210100A6 -+:10083000E1E18000A9E980007D210100F9200100AB -+:10084000EDF58000D90081009DF68000C5F780009D -+:1008500085FF800045018100D50281004D038100A4 -+:10086000E50081007DF6800081F78000D5F58000ED -+:1008700051F9800031FB8000F1F68000F9F580002D -+:1008800041FF8000D9F98000DDFC8000A9F78000DD -+:10089000C12E000059FB80008DF78000A5F9800073 -+:1008A0008DF9800029F68000A1F880005DF78000B6 -+:1008B00065F6800095FD8000912F0000F502810013 -+:1008C0002D0281008901810005018100A93000000D -+:1008D00099FF800019F7800089F68000C1F680003A -+:1008E0008D10010085F5800005F78000DDF68000A1 -+:1008F000B1F68000AD6A8100BD6A8100DD2F810004 -+:10090000E1578100F56D8200A98D820009258200E2 -+:10091000196E820001AA81005D608200A537820005 -+:10092000ED69810079598200E55882001D598200E5 -+:10093000FD6D8100493A810041BC8200E95A820084 -+:10094000CD608100D59681001D6181002961810003 -+:1009500089BF81001DAB810069320000893200002F -+:10096000D132000005A6810021AD82002958810006 -+:10097000BD3E8100A540810035958100599B8100D5 -+:100980003D3682001D4582000928810099A0810022 -+:10099000D1288100E93B81008D288100416E8200D1 -+:1009A000859B8100295D81006D398200FD398200BF -+:1009B000253A820095698100C97A810091578100AA -+:1009C0005D57810075308200852F82003557810088 -+:1009D000D12F82002157810049578100F5288100DD -+:1009E00095A882002DA2820089D38100D56B810059 -+:1009F0005959810075598100F55A820005AD810071 -+:100A0000F1D2810039378100ED718100C5968100F6 -+:100A10008957820091618200CD618200A9588100CE -+:100A20001D2782004543820001448200156A81002F -+:100A3000614A8100ED4E810071228200055A8100D9 -+:100A40004D8A81007549810071248200B14981007D -+:100A5000B144810075AC8200292B8200595281007B -+:100A6000E12A8200B529820071A7810035A78100A3 -+:100A700001D48100F5BE810055B48100D16A8200A5 -+:100A8000D19C81009D9C8100959B8100B59D81003A -+:100A9000459D8100C59D81006170820009358100FE -+:100AA000A1AB82008DAB820075AB8200F193810017 -+:100AB0009968810015D7810071C182007D2B81006A -+:100AC000E92F81000DB6810025BD82008D4F810088 -+:100AD0000D5081008543820031D78100B1BD820075 -+:100AE00095C182005DB38200B90D01008DD18100F6 -+:100AF000A9368100E9BC820029378100E9368100EE -+:100B0000A1D68100A53B81006DAB810041B0810081 -+:100B100045AE8100DDB1810041BD820095BE8200FD -+:100B2000CD2E82009D6B8100CD458200453981002C -+:100B3000353B8100BD3A8100F1D58100419F8100A4 -+:100B4000119F810071A48200ADD58100C130810068 -+:100B5000A13982004D618100995B8100A5728100FD -+:100B600089DA810061BF81006157820081218200A2 -+:100B7000A9218200D1AD820009BC8200B5A181000B -+:100B80009DCA8100B92F8200D9BB8200113082003A -+:100B90007DAD8200CDA4810099A48100CDAB8200FF -+:100BA00015AB8200C1AA8200B998810081A581009D -+:100BB000D9D08100A9CF8100E93B8200EDCF81002F -+:100BC00065D1810079D1810051D0810065D081004B -+:100BD000E521820011228200D1340000B9480000D2 -+:100BE000FD9C81009145820055AE820041B4810098 -+:100BF00095BD8100F18A8200098B820079D981003C -+:100C00007D618200CDA4820041918100A13F8200DC -+:100C10003594820049948200898982005DC18200F6 -+:100C2000F1C18200D13B8200D5958200E560810050 -+:100C300009208200E5170100BD3B820075A18200FA -+:100C400025A58200253B8200E93A8200753A8200A0 -+:100C5000F1308200B130820071D781004599820065 -+:100C600091D7810089948200DDC18200A96A820047 -+:100C7000256B8200C944810029458100596B8100A0 -+:100C800059498100EDAA810069618200AD2482008A -+:100C900005368100D535810079D08100A5D081004D -+:100CA000715C8100E1AD8100EDD0810049C9810016 -+:100CB0004DD88100893D82004920820065968200DE -+:100CC000F925820089CF8100856A82001593820010 -+:100CD0002D5D8200E9CA81006D4082006130820092 -+:100CE00015488200313C810061D68100114E81009F -+:100CF0000129810041A1810015A681000999820086 -+:100D0000E5C98100B1D7810035C08200294A810040 -+:100D100041AD8100EDBE82002DBE820005BE820085 -+:100D200079BE820055328100A5958100B1598100BC -+:100D3000E54781009152810015638100956481002F -+:100D40008D668100592C8100392C8100212E810073 -+:100D500065358200D5578200352B8200996082006C -+:100D6000016182001D4082001D2082001DD881008B -+:100D7000A9AC8200F1AB8200F52B820041AE82006B -+:100D800011120100356A810009AE8200696D82008E -+:100D9000098C8100D58B8100116F810081908100C9 -+:100DA000296C8200DDA18100E92B8100552F820092 -+:100DB000398C8100A55A8200355C820045BB8200D7 -+:100DC00091BE81002D6E8100115C8200258A810018 -+:100DD0004D93810089388200D5378200555A8100B1 -+:100DE000013882008D038100E9208200E13E82000B -+:100DF000914581002D6D81000D58820021478200B0 -+:100E0000FDCE810011CA81005936820051CB81008C -+:100E100025CB8100912E81002D2F8100B93A8200CF -+:100E2000A10D0100DDA9810031D48100D1B3820080 -+:100E3000ADA98100D53882008DD88100555E820031 -+:100E4000719A81001541820035DA810019258200EE -+:100E50006926820035358100D90D01003D71810080 -+:100E6000012D810009A282000D238200FD71810005 -+:100E7000D960820051728100416182004528810061 -+:100E8000C12382008D6C81006D2382009547810013 -+:100E9000B9D98100B534810075C98100F134810070 -+:100EA0002DBF810059AF8200D93C8100494F81009C -+:100EB000E5AB8100F51501007931810005958200CF -+:100EC0006D638200DD938200A56682000DC88100FB -+:100ED000095E81007D758100156281009159810054 -+:100EE000D575810011498100C1488100B9BF8100D9 -+:100EF000A5458200F5598200F1A9820041A6820031 -+:100F000039588200BD428200BDA782004D22820076 -+:100F100071A78200A5A78200E15C8100ED418200FB -+:100F2000D1A78200D1688100B5CC810015AF8200C5 -+:100F300095418100E1C8810089AA8100E99681007C -+:100F40007D2F810081470000494282005944820080 -+:100F5000F90D010031318200614982004D49820062 -+:100F60000DA58100095E8200253E8200CDCD810065 -+:100F700029B382002151810045B18200A91D820060 -+:100F800079BC8200D1568100599D8100999D8100D4 -+:100F9000191C8200513F82001D308100C9BD8100B3 -+:100FA00015388100794A8100DD9B8100199E8100FE -+:100FB00069618100896E8100B5708100D132820043 -+:100FC000F1578100A93382009D5A81003D3582008E -+:100FD00089338200D96E810045708100FD618100F6 -+:100FE000594B81000D9C8100558B8200F18E82004F -+:100FF000E59A8100BD35820049368100291F8200B3 -+:10100000655C820009150100516F8100299B8100F8 -+:10101000A56D8100B5A28200E1AF8200A9568200D1 -+:10102000894481003D578200E16F8200016F820098 -+:10103000DD728200E53E810095518100FDD4810082 -+:10104000F5BC810081B48100F199810019318100E2 -+:10105000358A8200DDDA8100413D81002D3E81002C -+:10106000E9898200C1D48100FD8D820099B681009A -+:10107000BDA781003D9F82005D0381006D928200CB -+:10108000218B8200599A8100ED278100ED94820026 -+:10109000FD8A81009D8A8100416B8100E16F8100A2 -+:1010A0005D468200A19482009D898200C9928200DF -+:1010B00079998100B1908200219182001D348100D4 -+:1010C00099B28200DD6A82008DC9810059278200B1 -+:1010D00021120100D9908100A56B82006D3C820035 -+:1010E000E56D820005C28200C96A8100ED4582007B -+:1010F000816B8100353F8200FD90820071BC8100D0 -+:10110000F16B81003D4E8200514A82003DA2810078 -+:10111000190E010079738200B97E8200698882000D -+:10112000695A8200DD2E810015138200117381003F -+:10113000698082009D9181005D8B8100816C8200BD -+:101140008D8F81004D8F810009888100BD6D8200E7 -+:10115000018E81001D5E820091718100C127810096 -+:10116000797582002DBE81002D5B8200E9A5820089 -+:10117000B5728200255B0000217D82004D808200D7 -+:101180008D7F820001A08100ED7F82002D418100D2 -+:10119000F98481006185820045728200F9548100E2 -+:1011A000692B820069518100C5558100315681004B -+:1011B000A1A6810071508100392A8200615381000B -+:1011C000C573810035620000F1978100A99B810001 -+:1011D000FD3B820025A08200DD398100715D810028 -+:1011E000BD1401004995810009CC810021A3820032 -+:1011F00045AA8100AD818200916782002962820048 -+:101200007D708200E12F8200E97D000081DB81009A -+:10121000952482006989820089C38200C5C4820046 -+:1012200039180100B1EB820009CB82000DCC82009D -+:1012300059EB820061E9820015F18200E9CD82005C -+:1012400045DF820009F182008DF782008DCA82009D -+:1012500089F38200D5CA8200A1098300C9F7820000 -+:10126000FDEF820099F8820025F9820039FA8200A8 -+:1012700089ED8200ADE08200ADE5820065DA820092 -+:101280007DC582002DE6820065EE820031E4820099 -+:10129000E5F182009DC8820055F3820075150100BA -+:1012A00061C78200CDE182006DE18200A5E282008B -+:1012B00059DF820029F4820009C7820055EF8200BD -+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D -+:1012D0004DE5820005E08200A5F982000DC582007F -+:1012E00089F48200ADA1000085A2000091E6820091 -+:1012F000BDCC8200FDE982008DD182002DF18200FB -+:101300002DF7820095FB820069CE8200A1F0820059 -+:10131000D5F08200F5CC820035A3000081D982008F -+:1013200045C58200FDCB820025CB8200BDEB82004B -+:101330001DDB820015CD820019E78200CDE6820018 -+:101340004DCF82009DCB8200450C8300E50D8300CC -+:10135000590E8300410E8300010B83004D0A830068 -+:10136000D10D8300310C8300590C8300710A830076 -+:10137000650E8300F10D8300410B8300A11E8300E5 -+:10138000B11E8300012B8300F54E8300112B8300D7 -+:10139000B127830099238300014A8300ED4983002C -+:1013A000FD478300CD4C8300BD4C8300714C83000E -+:1013B000D52783004D25830095258300E14C8300CC -+:1013C000414C83000912010065118300E144830050 -+:1013D00021288300BD2883007929830065288300A4 -+:1013E000652B830041458300D5298300491D830077 -+:1013F000A12A83005D30830051488300E5488300C3 -+:1014000029488300F5238300114A8300793483003F -+:1014100091188300A5338300ED3483001D118300F0 -+:101420009D4E8300954D8300B51A8300614783006C -+:101430001D4D8300ED1083000D458300C11E830008 -+:1014400001208300E9218300F1258300F91D830039 -+:10145000F513010059B3000049108300C10F830048 -+:1014600021248300A5248300B94A8300B52F83007B -+:10147000C1458300FD1C8300711D8300F5188300A6 -+:1014800059198300F1198300190F0100492A8300BB -+:1014900011B40000B957830029578300654F8300BA -+:1014A00001608300E559830039518300F54F8300C3 -+:1014B000555483001D5E83002152830065598300CB -+:1014C00079508300714F8300095983003D63830085 -+:1014D000C5578300815C8300B15B8300DD538300CB -+:1014E000115383009D4F830029508300254F8300B3 -+:1014F000D5588300CD62830039608300F95C830096 -+:101500004D6183005D5F83002D548300DD508300B7 -+:1015100039578300A555830091638300A16283003E -+:10152000C15D83002D5E8300455F8300A151830070 -+:101530004D5E8300195B83006D5A8300A9568300BA -+:10154000A5508300095783000D748300DD63830079 -+:10155000297A830001668300B9B28300D5A783008E -+:101560007D848300819383005DB38300A193830016 -+:10157000E9938300E10E010071BA0000B1BA0000E6 -+:10158000717A83005D67830051668300CD708300AC -+:1015900055718300DD7483008DAA830051A88300F8 -+:1015A000A9B183009D918300D184830039BB0000E1 -+:1015B00061848300AD77830081818300158283007D -+:1015C000B1808300E5B583006D7E8300B57983002B -+:1015D0002DBC0000916E8300758F830055878300BA -+:1015E0002913010015C1000025678300C18883000D -+:1015F000D98F8300F5AC8300E97783009D6D83006C -+:10160000A1A78300FD998300C9A4830051C40000F1 -+:10161000558B8300E58A8300CD6A8300F5868300BD -+:10162000596A8300B9AA83001566830051B283000A -+:101630009DB38300D9B6830059B1830091828300A2 -+:10164000D5B0830081868300C97A83000585830035 -+:10165000797C83008965830055A58300C9AF830029 -+:101660008D1501007999830091898300C5B58300A8 -+:101670000DB8830099D483002DC083009DC28300E0 -+:10168000ADC38300A1C68300B1C68300C5C2830079 -+:10169000A9D0830055BF8300F9CF830029BF830001 -+:1016A000C5E18300C1C0830095C083004DD883008D -+:1016B0000DD7830015D88300F1D7830079BD83004F -+:1016C000A1E1830035C28300C5E08300DDE0830033 -+:1016D000C5DC830099DA830001DA83004DB883000A -+:1016E00075C0830019C28300F9C983003DD6830009 -+:1016F00015BE8300C9D683005DBA830029D6830056 -+:1017000031B9830035BC83009DD883005DDC830044 -+:1017100029C18300A9C28300E5C0830025DB8300C3 -+:1017200075C283001DD083005DBC830061C6830049 -+:10173000D5C2830005BC830001C98300B5C88300FE -+:10174000EDC8830055D6830015D98300A5D1830049 -+:10175000F1D5830001D9830081B8830089E083003B -+:10176000E1BC8300A5DB8300EDE1830071C1830050 -+:10177000E9B783006DC783008DC183001DC8830056 -+:10178000B5D1830071DC8300E1C18300A9C183006E -+:1017900019DC830039D883004DCB8300A5B78300C3 -+:1017A00069CB83008DC98300C9D48300A5C500001F -+:1017B00099D68300E5DC83004DD483001DC38300EC -+:1017C00021DD830045D983007DD383003DD2830092 -+:1017D00041DA8300CDD88300D9BF830095BD830053 -+:1017E000EDBD830051C083002DB8830049BB830049 -+:1017F00031BB8300CDDA8300D5D0830049CA830092 -+:101800009DD5830081BF8300D5CF83003DC9830070 -+:10181000DDD18300B9D7830025C78300D1C800007C -+:101820005DBE830021E18300F9E0830071B983008C -+:101830008DE1830025D9830049D78300DDDB830058 -+:10184000A9B9830085BA83000917010059EB830009 -+:10185000C5E7830041E2830025E283006DF5830044 -+:1018600065EB830085F2830089F78300B1F2830082 -+:10187000A9F58300AD008400E100840019FD830018 -+:1018800035EE8300FDF38300D1D1000089FB830096 -+:10189000B9FA830021F98300F1FA8300D9F88300B3 -+:1018A000D9F9830031008400C5FE830049E7830035 -+:1018B000050084004DFF83006DF3830059FE830013 -+:1018C00001FE830025EB83000DEB830031018400D2 -+:1018D00035FD830081EB830059FD830011F88300FF -+:1018E000FDF78300C5ED8300ADED8300A101840009 -+:1018F000E9E78300B1F38300DDF2830025F3830081 -+:10190000F9E68300E5E28300F9120100A5E983000E -+:101910008DF5830051EE830079F8830071E2830036 -+:10192000F1E8830045E6830099F783006DEE8300BC -+:1019300041F48300B9EB830075E78300B1E88300CD -+:10194000BDD3000061F183000518010089EE83001A -+:10195000F5D40000FDE58300A9FD83000D1301000F -+:10196000B5FB8300F1F183002D108400E1158400A4 -+:10197000B1198400C5158400D90F8400CD218400DD -+:10198000491E84004D1F8400E1128400ED0884008C -+:10199000F10184002D0F8400ED238400F51E8400E6 -+:1019A000E520840049208400AD128400F11A8400EF -+:1019B000711F8400C9198400AD188400450B840090 -+:1019C000910B84000D2484008D2384000D18840065 -+:1019D000210684008D168400310384006909840087 -+:1019E000FD158400E902840001028400A909840035 -+:1019F0008D148400811E8400E10B8400751C84001A -+:101A0000AD0A840049108400712084000121840003 -+:101A1000850A8400291D840045078400390C840050 -+:101A200029198400551E840089038400E51D840063 -+:101A30002125840049138400291A8400DD12010045 -+:101A4000ED12840045068400010D84008943840062 -+:101A50006D2A8400014D84001528840069288400C3 -+:101A6000DD0B010009408400112C8400F92784005B -+:101A7000912D8400794C84008934840019338400CA -+:101A80006D2F8400C92D8400F12E84007D2E8400EA -+:101A900065258400DD348400FD2584001929840037 -+:101AA000B5408400D944840079298400B92B84008E -+:101AB0003D45840095328400B9288400D1388400E3 -+:101AC00031488400A93084006D2C8400994384003F -+:101AD000D13284006D338400FD2F84005D45840085 -+:101AE00011348400B54A840075488400C5488400D8 -+:101AF000B1278400314A8400D949840059328400D6 -+:101B0000014C840039388400314D840055448400F0 -+:101B1000D93D840055438400513C840091398400B0 -+:101B20009536840091378400F5368400E1478400BF -+:101B300015478400CD4C8400F52B84002546840095 -+:101B4000E53A8400C937840049428400292A840088 -+:101B5000A53F840059268400952A8400452B8400E3 -+:101B6000C95D8400C1230100A156840095568400FC -+:101B700019578400E956840005578400355F8400B6 -+:101B80001D628400B557840065638400ED628400A3 -+:101B900021638400BD628400194E8400B95384001F -+:101BA000B15D8400B5518400D55F8400F95584008F -+:101BB0006560840059538400E5538400E94D840036 -+:101BC00049240100E15F8400212501005125010025 -+:101BD000B55B840031568400A5638400CD60840029 -+:101BE00091638400ED5084002D5E840031518400A7 -+:101BF000155C840061548400F55E8400F15D84000E -+:101C0000352401007152840059588400815C84009D -+:101C1000715784002557840071588400AD568400A4 -+:101C2000415984006D4F840029508400E1548400A0 -+:101C3000BD6184006D61840005598400A56684003F -+:101C4000D9678400456684000D658400916784002F -+:101C5000B96384005D67840079678400F966840055 -+:101C60002165840021678400C56684008D66840038 -+:101C70006566840011688400516C8400AD6E840038 -+:101C8000016E8400F97084004D7F84007D6C8400B7 -+:101C90002D748400456A84000D7B840001120100CC -+:101CA000156E8400457A8400E56C8400456F8400DD -+:101CB000C17C8400297E8400756D8400956B84004E -+:101CC000B56D84007D7D84005D6B8400D56A8400E1 -+:101CD000816A840085748400B1808400857E8400DC -+:101CE000CD7F84004981840069818400ED8984006E -+:101CF0006D8A8400FD8984008D8984009D8984001B -+:101D0000E9858400F982840025858400518A840055 -+:101D100075858400958484008181840071838400AA -+:101D2000C18984005D898400D58984006D8984001F -+:101D30007D8984000D8A840009868400798C840062 -+:101D40007D8A84000D8B8400499484008D928400E8 -+:101D5000E98D84009D8B8400FD8C84007990840043 -+:101D60000D8C8400458C8400E9A68400A5AD840018 -+:101D700029968400C598840015C1840009A98400AF -+:101D800099C2840045B7840031C18400D1B8840071 -+:101D90008D998400B99A840025AC8400D9BF840051 -+:101DA000C9BE8400A196840025B18400519B8400A3 -+:101DB000919884004D9784001D9784007DA684002F -+:101DC000D1B784002DAB84008595840019B08400C0 -+:101DD000F5AD840029A98400C1A98400219F840055 -+:101DE00025A28400B1AE8400C1AF8400D5A38400D5 -+:101DF00075B7840041A28400E1BC84006DA8840012 -+:101E0000BD9D840095B884005D95840075BE8400F6 -+:101E100051B98400A9958400C5C18400599A8400F1 -+:101E2000419684003DB884009DA88400E5A8840004 -+:101E3000A59B8400F5A684003DAF8400159A84001C -+:101E4000F9988400EDA984006DB18400FDF0840050 -+:101E500025DF840025ED8400E5D08400CDF18400E9 -+:101E600009F2840035F2840055F28400CDF284003A -+:101E7000B1D38400F5D384002DD48400C1D4840070 -+:101E8000A5048500F90585006D0585009904850088 -+:101E90008D04850079D4840045E88400B1C58400B0 -+:101EA00095DF840031DF840075E484001DE0840048 -+:101EB000BDC9840005ED8400A500850091FB840068 -+:101EC000F9ED840091EF84009DFB840081EA840099 -+:101ED00079E28400E1E500006DE60000A1EB8400FA -+:101EE000D1E484009D028500F1E7000015CC840058 -+:101EF0005DFB840081C5840015D5840099D68400DB -+:101F000035E78400B9DF840045F48400B9C7840054 -+:101F100001DF84002D018500E1C7840025D1840004 -+:101F2000B5E60000BDDD84004DF38400E1C9840006 -+:101F300041E084002DCA84009DD4840091E7000014 -+:101F4000D900850079CB840021FC8400B9E88400A5 -+:101F5000B5D8840031FD8400BDFB84001D048500DC -+:101F60005D04850031ED8400450685005DEC84004C -+:101F700025C384001DF38400D9C684002DEC8400A1 -+:101F8000F1C5840059E9840019C884005112010088 -+:101F9000B100850049D3840001C98400E1D28400E6 -+:101FA0008DCB8400DDEB840011F4840009FC8400F7 -+:101FB000D9F3840069C38400A1C884002DEE840095 -+:101FC00071D68400790185004112010025D8840072 -+:101FD000DDF9840009F0840035F784008DE8000005 -+:101FE000D9FC840015D78400DDD584001DDE840073 -+:101FF00001E9000019F1840099F1840049F184009D -+:10200000BDE90000A1F48400F1D084003DCC84003F -+:1020100069D2840089E98400F51D0100C9D38400D8 -+:102020008506850089078500E90685004D0785003E -+:102030001107850025078500710685009506850036 -+:10204000BD06850075078500B10785009D078500E1 -+:10205000A9068500D1068500FD06850039078500A3 -+:10206000610785005D0685001509850079098500F1 -+:10207000350A8500BD0985000D0A850091EA00003A -+:10208000711201004D0A8500A90985002509850006 -+:10209000DD0A85006D0A850081088500C507850079 -+:1020A0000D0B8500590F8500ED118500C9128500C3 -+:1020B00021108500F90D8500D5118500511085008E -+:1020C000AD118500011185006D108500B1D10100B1 -+:1020D000850F850085108500990D850011128500FA -+:1020E0000D22850041178500D917850075208500D0 -+:1020F0007D2C8500352F8500B92285002D25850092 -+:102100009D238500612F8500A5278500C92A8500AC -+:102110006D2985009D22850031228500A52485003A -+:10212000E1238500B12F8500BD2C85005914850061 -+:10213000C9138500A11C8500452C8500A9178500C1 -+:10214000B1208500311A8500FD178500291D850005 -+:1021500021148500AD218500B5308500453185000D -+:1021600035278500D1318500C5148500BD2D85003A -+:102170002D23850059238500891485004D4685004F -+:102180006547850025368500514785003D46850019 -+:102190008D3C8500514A8500994A85007547850028 -+:1021A0001D478500553685005D468500D53B850079 -+:1021B00049498500D53A8500E139850041398500D6 -+:1021C000E53885000937850045358500C93C85001F -+:1021D000754B8500B9458500ED4885002146850091 -+:1021E000213A8500A940850001328500F53285003D -+:1021F000FD378500894E8500DD508500ED50850056 -+:102200005D57850009558500495085005D50850062 -+:10221000D1528500F5528500E54E8500C9558500EF -+:1022200065568500C9508500094F850071D20100AF -+:102230009D5585000D538500A94C8500B957850033 -+:10224000A55785000D518500FD5A8500D5518500A3 -+:10225000A9518500B15285009D53850039558500EF -+:102260009D4E8500C95785006D578500954C8500AA -+:10227000095785008D4F8500DDD20100FD5985008D -+:10228000014D8500ED598500D9598500194C85000F -+:10229000756C8500816E8500516C8500295C850018 -+:1022A000416E8500795E8500210F0100AD6E8500CD -+:1022B000B56C85006D6585001D5F8500196B850017 -+:1022C0008579850071738500B58E8500E19585005F -+:1022D00001828500519085002D828500D190850076 -+:1022E000FD908500BD9285006D8F8500CD928500A3 -+:1022F00055968500C58E8500857285005D8D8500AB -+:1023000001838500C1918500257085000D918500B0 -+:10231000C17685006971850041718500F97F85006E -+:1023200079708500F19385009D958500F574850091 -+:10233000497485006D788500BD728500ED8A850041 -+:10234000C98C850099918500597D8500BD718500F6 -+:10235000758185000D818500A9798500217785002B -+:102360002193850089928500D194850095968500FA -+:1023700065838500D97385006582850021D30100BE -+:102380005975850021768500556F85006D9585000E -+:10239000E583850029848500AD8F8500F16E850079 -+:1023A0009D2E010075280100292E0100A53601008F -+:1023B000F52D01001D2B0100992B0100A531010015 -+:1023C0005D2B01002D2B0100252B0100613C01003C -+:1023D000692E010041370100952801007530010088 -+:1023E000FD310100C52A0100D1280100C13F0100D3 -+:1023F000CD280100C1400100F1420100DD2D0100A6 -+:10240000DD2A01004D2E01009D32010091360100B0 -+:10241000ED2D0100C5280100BD280100613001003B -+:1024200031340100253401005930010055330100D9 -+:10243000813001008D320100152D0100F92B0100C2 -+:10244000D1450100192D0100F92D0100012E0100D7 -+:1024500089300100A53A0100F93A0100B12C0100D0 -+:10246000D52D0100853501009DEB0000D9EB000062 -+:1024700015EC000059EF00009DF40000E12C020073 -+:1024800005F500000DF5000049F8000049F90000CD -+:10249000B1F9000009FB0000452F000011310000D8 -+:1024A000493100006D31000079310000C931000070 -+:1024B000D500010011020100D931000039330000BC -+:1024C00045340000710D0100F93500006D0D01006B -+:1024D000E54F00006D6B00005D750000B19E0000CF -+:1024E0005D0D0100610D0100690D0100650D010028 -+:1024F000F5160100A9C60000450D0100410D0100BF -+:10250000310D0100390D0100D90B0100510D010001 -+:102510004D0D0100550D0100590D01002D0D01005B -+:10252000350D01003D0D0100490D01004DD50000A4 -+:1025300031D5000039D5000041D5000059D5000043 -+:10254000FD0B0100190C0100390C0100F90B010011 -+:10255000F50B0100350C0100150C0100110C0100F8 -+:102560000D0C0100090C0100050C0100010C01001B -+:10257000890C0100950C0100C50C0100E50C01005F -+:10258000E90C0100FD0C0100F90C0100F50C010043 -+:10259000F10C0100ED0C0100990D0100910D0100FD -+:1025A000890D01009D0D0100850D0100790D0100CF -+:1025B0008D0D0100750D01007D0D0100950D0100CF -+:1025C000010D010001000000200000001F000000BC -+:1025D00050000000020000000100000001000000A7 -+:1025E000010000000000000061D401000A0708009B -+:1025F000B533020051FB80006D310000C12E000098 -+:1026000000000000D1F980000000000029FB8000DC -+:1026100000000000000000009C1800409600FFFF32 -+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA -+:10263000FFFFAAAA0300409600000000000000006F -+:10264000000000000000000000000000000000008A -+:10265000000000000000000000000000000000007A -+:10266000000000000000000000000000000000006A -+:10267000000000000000000000000000000000005A -+:10268000000000000000000000000000000000004A -+:10269000000000000000000000000000000000003A -+:1026A000000000000000000000000000000000002A -+:1026B000000000000000000000000000000000001A -+:1026C000000000000000000000000000000000000A -+:1026D00000000000000000000000000000000000FA -+:1026E00000000000000000000000000000000000EA -+:1026F00000000000000000000000000000000000DA -+:1027000000000000000000000000000000000000C9 -+:1027100000000000000000000000000000000000B9 -+:1027200000000000000000000000000000000000A9 -+:102730000000000000000000000000000000000099 -+:102740000000000000000000000000000000000089 -+:102750000000000000000000000000000000000079 -+:102760000000000000000000000000000000000069 -+:102770000000000000000000000000000000000059 -+:102780000000000000000000000000000000000049 -+:102790000000000000000000000000000000000039 -+:1027A0000000000000000000000000000000000029 -+:1027B0000000000000000000000000000000000019 -+:1027C000000000002DE97043994605460E469046EC -+:1027D00020F086FA436831469C69284642464B46BB -+:1027E000A047BDE87083C0462DE9F74F0029054694 -+:1027F00092469B46009153DB438A828A514403FBF5 -+:1028000002F399424CDA806808F038DB002101902D -+:10281000A86808F005DD4369044643F000434FF023 -+:102820000008436124E000989BF8007008EB000664 -+:102830004FF0000903E00136D04517D07F0817F0AC -+:10284000010F0CD0284621463246FEF3EDF630B19A -+:1028500063694FF0FF3023F00043636122E009F128 -+:102860000109B9F1080F08F10108E4D10BF1010BDE -+:10287000D045D8DB6369A86823F000436361002179 -+:1028800008F03EDCA868012108F03ADC2846214621 -+:1028900020F0C2F9A868019908F0C2DC002001E02C -+:1028A0006FF01C00BDE8FE8F407C704713B500F050 -+:1028B0008FD8024608B904460FE000240AE010460B -+:1028C00001A90022FFF344F7019A13782C2B08BFCB -+:1028D000013201341378002BF1D120461CBDC046D3 -+:1028E000B0F8423070B50446C3B142F2197503E046 -+:1028F0000A2003F031DF0A3D236B1B6913F070439C -+:1029000007D0B3F1005F04D0B3F1405F01D0092DCF -+:10291000EED1226B136823F01003136070BDC04624 -+:1029200070B590F878310546FF2B1FD0104C406AE7 -+:10293000E36E9847D4F89C30686A984701280BD812 -+:1029400095F8141241B90B4628460A4A03F030DEC6 -+:10295000012385F8143209E0054B686AD3F89C30EE -+:1029600095F805419847241885F8064170BDC04682 -+:10297000E0A685003D98800010B5084671B191F839 -+:102980000832012B0AD091F875313BB14B691A6AB4 -+:10299000034B02EA03030BB10EF0FEFE10BDC0466E -+:1029A00000FC0101D0F8943110B59942044601D9D8 -+:1029B000002002E00EF0F0FEE08D10BDD0F8801196 -+:1029C00010B5044691B10223C068D4F8842108F000 -+:1029D00005DB074B1B684BB9D4F88011D4F8842170 -+:1029E000E06881EA0202023308F0F8DA10BDC0465E -+:1029F000AC2702002DE9F04190F817320446012B74 -+:102A000077D00123002780F8173243E0A0683146D1 -+:102A100000F082DBD4F8F0301B68984205D92846D4 -+:102A20000021324600F00EDB42E02046FFF778FF3F -+:102A300035690023AB7194F8783131462B7294F8E4 -+:102A4000063184F80731DBB26B72D4F8FC31606A6E -+:102A50000133C4F8FC316A79274BD20982F00102B4 -+:102A60005B6A9847B0B9D4F8F8106B7900293CD06C -+:102A700013F00F0F39D06A782B7843EA02230F3313 -+:102A80001B091A0A0A6918BF0023937194F8783158 -+:102A900013722AE0D4F8F0301B68012B08D904F136 -+:102AA00028052846002100F04FDA06460028ADD15F -+:102AB000002384F81732C4F8F8302FB16269043368 -+:102AC0005364204607F03CDFE28DD4F8C8319A42C7 -+:102AD00003D9206901F0C4DD0BE0D4F8CC319A426F -+:102AE00007D2206901F0AEDD03E00127C4F8F860E9 -+:102AF000D0E7BDE8F081C046E0A685002DE9F041B1 -+:102B00000746884616461D4642F2197403E00A201D -+:102B100003F022DE0A3C79690B6D002B02DA092CE6 -+:102B2000F5D11FE0AB191B0243F00042069BB3F145 -+:102B3000807F04D198F8003043F08073D21842F2BD -+:102B400019740A6503E00A2003F006DE0A3C7B697B -+:102B50001B6D002B02DA092CF5D103E0012088F867 -+:102B6000003000E00020BDE8F081C0460022C36BC9 -+:102B70000BB1013BC363531CDAB21030102AF6D1FB -+:102B80007047C0462DE9F041066805460F4670685B -+:102B90004FF4BC7104F09CD808B9044612E000213F -+:102BA0004FF4BC720446FFF34BF2D5F86031266057 -+:102BB000C4F8603195F86431C4F8687184F8643100 -+:102BC0006B6863602046BDE8F081C04603682DE96C -+:102BD000F74F012A14BF2A25322506460F465868AA -+:102BE0002946914604F0CCD8834640B93368013871 -+:102BF0001B68D3F88C20136D013313656CE007F16B -+:102C00000E0A04695146042201A8FFF3B5F1019BA5 -+:102C100006F1280803F47F421B0643EA02234AF622 -+:102C2000FE12B2EB134F0BBF2C4907F108012046EF -+:102C300020460622FFF3A0F10622A01D4146FFF325 -+:102C40009BF104F10C02B9F1000F0DD02B0A237394 -+:102C500004F10E00557022490622FFF38DF108237E -+:102C600023750623637503E008232373062353703B -+:102C70006419A4F11C05394606222846FFF37CF1AD -+:102C8000002304F8163C023304F8153C41460622A2 -+:102C900005F10800FFF370F107F11801042205F1B6 -+:102CA0000E00FFF369F107F10801062205F1120099 -+:102CB000FFF362F15146042205F11800FFF35CF1C5 -+:102CC000D6F85C3130680133C6F85C315946D6F825 -+:102CD000682125F067DA0120BDE8FE8F2C9E850073 -+:102CE00014D2850010B50368D3F800481B6893F828 -+:102CF000AB306BB1FFF73AFF08E0A16829B10120C2 -+:102D000000F0CAF808B1FFF731FF2468002CF4D1B5 -+:102D1000002010BD7047C046C3682DE9F04106464B -+:102D20000D4658683821174603F0D2DF044610B923 -+:102D30006FF01A002BE000213822FFF381F101230C -+:102D4000294623606360A360062204F10C00FFF3B0 -+:102D500013F16B8E05F10901A3742B7A04F11400B1 -+:102D6000E3742A7AFFF308F16D8D3046A586E78675 -+:102D70002146382221230BF013DE00B907E0F36867 -+:102D800021465868382203F0B3DF4FF0FF30BDE82A -+:102D9000F081C04630B50C4690F8CF1091B0944603 -+:102DA0009E460380194D91B94FF0FF330293039370 -+:102DB000049305930D3300940191069107910891B6 -+:102DC00009910A950B900C930D910E9115E04FF01F -+:102DD000FF33029303930493059300F1D00306930A -+:102DE0004BB2002207930C2300940192089209929F -+:102DF0000A950B900C930D920E927146044A63460D -+:102E0000C06824F079D811B030BDC046F920010067 -+:102E10002C9E85001FB5836D0446012B17D1B0F899 -+:102E2000583113F0010F12D1C36893F8703273B99F -+:102E300002AA01A903AB0FF0E5F9029A3AB12046C4 -+:102E40000199039BFFF7A6FF08B90223A3651FBDE5 -+:102E500010B579B1B0F8583143F00103A0F85831FA -+:102E6000836D022B15D1C3680C21D3F8680151F092 -+:102E70009FDB0EE0B0F8583113F0010F09D023F0BA -+:102E80000103A0F85831836D1BB101238365FFF75F -+:102E9000C1FF002010BDC046012801D0002000E085 -+:102EA0008868704710B50C4641B18B6823B9C06F74 -+:102EB0000968FFF767FEA060A06800E0C06F10BD62 -+:102EC0002DE9F0418C692369994202D100273E46E1 -+:102ED00004E0CE6A0EB9374600E0376863681146F1 -+:102EE000D86803F03BDFA36805461B6893F895306C -+:102EF0001BB1C38A43F08003C382636893F8AB308D -+:102F00008BB120463146FFF7CDFF60B129460AF06C -+:102F10003FD9022807D163682946D868012203F007 -+:102F2000FFDE01200BE0204629460CF039DCA068CA -+:102F300029463A4625F036D9003818BF0120BDE8A9 -+:102F4000F081C04637B5144605461146406FFFF77D -+:102F5000E1FE6368112B08D0122B01D0102B15D184 -+:102F6000A37803F001032B7510E002AA002342F8B6 -+:102F7000043DA86894F82F103CF080D930B18379D3 -+:102F800023B96188C1F3800127F03AD93EBDC0461C -+:102F90002DE9F0470446084615460DF003FF80462C -+:102FA00010B9D4F8109001E0D0F80490A368D9F8D3 -+:102FB00024701B682A6993F895303BB1EB8A13F4AF -+:102FC000006301D001262AE01E460AE0537B127BF3 -+:102FD00043EA022348F66C02934214BF00260126FE -+:102FE000EEB9204629460CF0CDDB636893F8AB3090 -+:102FF000ABB120464146FFF755FF80B1294609F0A5 -+:10300000B9DF042801D0012804D163682946D868B3 -+:10301000002244E0052802D14FF0010801E04FF002 -+:103020000008636893F895301BB116B9AB8A2D334D -+:10303000AB82002F2FD0EEB9FB6913F0010F07D040 -+:10304000637D2BB1204629460CF0A8DC024668B10E -+:10305000B8F1000F0ED1636893F8963053B1D4F8ED -+:10306000840029460EF004F9024618B9636829461F -+:10307000D86814E063682946D86803F0ABDE3B6982 -+:103080000446DB68484639462246984748B1204600 -+:1030900003F0DCDD05E063682946D8683A4603F0B2 -+:1030A0003FDEBDE8F087C0464B6A10B591F843207B -+:1030B00043F480134B62D0F8883002F00702D21834 -+:1030C00092F88030013382F88030D0F888200123D4 -+:1030D00082F88630D0F8881091F8812091F87B3002 -+:1030E0009A4211D291F8802091F87A309A420BD20C -+:1030F00091F8822091F87C309A4205D291F8832091 -+:1031000091F87D309A4201D30DF0F0D8002010BD27 -+:103110001FB5084B02460093074B08460193074B27 -+:103120000749DB6902931268064BFFF3F5F105B01E -+:1031300000BDC046DDD60100A0D601000028020077 -+:10314000AED60100D1D6010010B5436804461B7EFF -+:1031500053B1D0F880000CF049FDA06801F048FEA2 -+:103160006268002382F8203010BDC04610B5806927 -+:10317000FFF7EAFF002010BD70B504466368806861 -+:103180001E7E0EB1002515E001F0F4FC054620B9C5 -+:10319000D4F880000CF058FD05460CF0D5F86368B3 -+:1031A000D3F89C1031B10B7823B1034B3246186829 -+:1031B000FFF33AF5284670BD2428020010B5806858 -+:1031C00001F0FEFD002010BD10B50446FFF7F6FF2C -+:1031D000A06806F083FE10BD61290DDC602940DA8D -+:1031E00054293ED003DC2F293BD0442912E0A1F121 -+:1031F0005C03012B0FD834E0AC2932D005DC7C29EC -+:103200002FD0A1292DD06A2904E0DE2929D0F42964 -+:1032100027D0CD2925D0642911DC632921DA4A2958 -+:103220001FD006DC07291ADB08291ADD3C2918D033 -+:1032300015E0502915D012DBA1F15C030DE0C32984 -+:1032400005DCC2290DDAA1F1A803022B06E0B1F5D5 -+:10325000847F06D003DBA1F58973012B01D90020FF -+:1032600001E06FF01600704731B1036B1B689942A3 -+:1032700002D06FF00C0006E090F82930002B14BF4C -+:1032800000206FF00A00704730B5072A1C469DF8F1 -+:103290000C5001DD496809B9036B1968032906D090 -+:1032A0004B1E012B10D8036B1B6899420CD12DB11A -+:1032B00090F8293013B96FF00A0007E00CB92046E6 -+:1032C00004E00020216001E06FF00C0030BDC0463A -+:1032D0001FB59646BEF1070F1A4601DC002300E039 -+:1032E0005B685F2903930ADC5E2914DA4A2916D049 -+:1032F00002DC3C2913D00CE05C290ADB0FE0AA2990 -+:103300000DD002DCA82904DB0DE0C22907D0C329B7 -+:1033100009D000200EE01946FFF7A6FF0AE00021C1 -+:10332000FFF7A2FF06E000230093114603AB7246AD -+:10333000FFF7AAFF05B000BDC88810F0080018BF4D -+:103340006FF016007047C046D1F8D83270B5054608 -+:10335000188C164610BB8B6D40F2371203EA02023E -+:10336000002A0CBF012411242A6B1368022B07D1F9 -+:1033700095F85C360133DBB2012B98BF44F0200492 -+:10338000537D53B1B06B06F13C0122F063DE20B1F6 -+:1033900095F947360BB144F48064204670BDC046B1 -+:1033A00091F801C030B5BCF1010F45DDCA788B78CA -+:1033B00043EA0223012B3FD1ACF10203032B3EDD94 -+:1033C000ACF10603012B3ADD0B1D1D1D6A781B793C -+:1033D000002043EA0222864600E00130ACF10803F7 -+:1033E000904203EB0E0406D0AEF1040EACF10403E0 -+:1033F0007344042BF1DCC0EB0203A4EB830001282F -+:103400001DDD05EB8203DA789B7843EA022E821EEB -+:10341000002301E00133043A734501D0032AF9DCAB -+:10342000C3EB0E03A2EB8303012B08DD023B06D0A6 -+:10343000C3EB0C034B7002E06FF0160000E00020BD -+:1034400030BDC0462F2A30B50446964602D86FF0EC -+:103450000D0034E0B0F88031056B0B60B0F88231BC -+:10346000AA894B60EB891B0743EA023302688B6031 -+:103470001069BEF13B0FC36BCB6093680B61836A2D -+:103480004B61C36A8B61B2F87A30CB61D4F8843176 -+:103490004B62D2F8B0300B6243688B62836BCB62B5 -+:1034A0000CD92B8900220B636B89BEF13F0F4B6354 -+:1034B0008A6303D9036C1046CB6300E0002030BD63 -+:1034C00010B519B14068302203F012DC10BDC046BF -+:1034D00010B50446D0F860068E46C37A90F80AC04C -+:1034E00093B182894FF6FF739A420DD0837B43B923 -+:1034F0008378012B05D0037B03F0010383F00101E6 -+:1035000000E00021C9B20BE0216B71450ED1837B35 -+:103510002BB98378012B02D091F84C1000E00021E8 -+:103520008C4503D08172206938F0BADE002010BDCE -+:103530004FF0FF33A0F83C3210B5044600F50E7092 -+:10354000063000210C22FEF37BF523685B6B23B968 -+:103550004FF0FF33A4F840320DE04FF00F03A4F812 -+:103560003E324FF0F003A4F840324FF47063A4F8F9 -+:1035700042324FF20003A4F8443210BD70B5044645 -+:10358000D4F8741580680CF069D8D4F8F816D0F126 -+:10359000010538BF0025A0680CF060D800B90135DE -+:1035A000A068D4F8FC160CF059D800B90135D4F84D -+:1035B000E036A068196A0CF051D800B90135D4F88A -+:1035C000E0260023D360A068D4F83C150CF046D860 -+:1035D00000B90135A068D4F894170CF03FD800B9B1 -+:1035E0000135284670BDC04610B5044625F0F2DE10 -+:1035F000204617F00BD810BD2DE9F04F0746106993 -+:10360000A5B0D1F81090884601F124011A900792D4 -+:103610000693189199F80130D2F87CA199F800200E -+:10362000339C42EA0323C3F38102022A7868089399 -+:103630000B9201D0002302E0089DC5F3C013DBB25A -+:1036400041461693FFF3E6F504300A90329888B1AC -+:10365000037A0B2B08D197F8F0375BB197F8F13765 -+:1036600043B18379072B05D832990A9A91F90F3023 -+:10367000D2180A92D7F88831002B1CDA329BD3B1CA -+:103680001B7A022B17D197F8A034A3B91A9DAB6D02 -+:1036900013F0080F0FD132988379292B0BD8032B05 -+:1036A00009D90B2B07D82F99012904D10A9A19910E -+:1036B00008320A9201E000231993D8F81030B8F8C4 -+:1036C0001420A3F1760676329D1FA8F8142000215D -+:1036D0007022C8F8106030460595FEF3B1F41898D2 -+:1036E000036813F4806F01D0828827E00799A64B06 -+:1036F0004A6802EA0303D3B1089A02F0FC03882B5C -+:1037000015D199F8043013F0010F10D1B8F8163024 -+:103710002F9D03F007032E9801EB43016B1E984287 -+:10372000B1F8BE200AD1531CA1F8BE3006E00B99B7 -+:10373000012914D000224FF0100B04E00B9B012B49 -+:103740000DD04FF0000B2E9D05F00F0343EA02133E -+:103750009BB289F816301B0A89F8173001E04FF048 -+:10376000000B3098042807D138461A9932460FF0DA -+:1037700047D8ADF88C0019E02F992E9D4B1E9D4225 -+:10378000B7F8462502D1531CA7F846352E98309934 -+:1037900000F00F0343EA02135B0147F6E07203EA0D -+:1037A000020201F007031A43ADF88C20079A92F841 -+:1037B000DF3023B9089D05F0FC03802B01D14BF0CD -+:1037C000200B724B04EA03031BB1002020942194C8 -+:1037D0001FE00B99012906D9189A1368002B02DB08 -+:1037E00013F0100008D0079C002594F8483003F02F -+:1037F0007F032093219349E0396B644B8A6C02EA82 -+:10380000030343B199F8043013F0010F03D0209261 -+:1038100021920F903BE099F8043013F0010009D099 -+:103820000798002190F848300F9103F07F03209310 -+:1038300021932CE04A6C554B02EA0303002BE6D19E -+:1038400020ABD7F8600100930DF18F0301930DF1C8 -+:103850008E0302930DF18A03039323AA21AB0799E8 -+:103860004FF028DA189A136843F00062189B1A6028 -+:10387000BDF88A3013F0010F03D0189C42F40053B6 -+:1038800023602E9DD5F1010538BF00250F95D7F88F -+:103890006036219A9C7A3B6893F8463013F0030116 -+:1038A00000F0358112F0006F02F07F0104D007298B -+:1038B00006D9202904D02EE0354B5B56002B2ADA9E -+:1038C00012F0804F01D1002A25DB22F4401121F4AF -+:1038D000605112F0006F21911AD0D7F860068378FA -+:1038E000012B15D93B6B93F94D20012A0BD0079D75 -+:1038F0006B6813F0804F0BD0B2F1FF3F08D1037B10 -+:1039000013F0040F04D041F4801343F4805301E01A -+:1039100041EAC4232193209911F0006F01F07F0246 -+:1039200004D0072A06D9202A04D036E0184B9B562B -+:10393000002B32DA219B13F0804F01D1002B2CDBBE -+:1039400021F4401222F4605211F0006F209221D035 -+:10395000D7F860068378012B1CD93B6B93F94D1087 -+:1039600001290BD0079D6B6813F0804F12D0B1F185 -+:10397000FF3F0FD1037B13F0040F0BD042F48013F1 -+:1039800043F4805308E0C046400001807F000008F7 -+:10399000401B860042EAC4232093B7F8283603F47C -+:1039A0004063B3F5406F30D13B6B18690FF0BEF840 -+:1039B000219B00F44070B0F5007F14BF0222032267 -+:1039C00013F0006F03F07F0111D0202902D11546BA -+:1039D00005222EE097F9CA34B3F1FF3F12D10798C0 -+:1039E000436813F4002F23D01546042221E09C4B9A -+:1039F0005B56002BB4BF97F9C93497F9C834B3F1BB -+:103A0000FF3F15D015469AB213E0219B03F07F03C8 -+:103A1000202B04BF4FF000632193209B03F07F0312 -+:103A2000202B04BF4FF00063209302252A4600E0BC -+:103A30001546219B110223F4E06341EA030321931D -+:103A4000209B23F4E06213F0006F14BF41EA0203ED -+:103A500042EA05232092219A209312F0006F06D0AB -+:103A600097F9DC31012B02D142F4000304E097F90D -+:103A7000DC3113B922F400032193209A12F0006F75 -+:103A800006D097F9DC31012B02D142F4000304E0A7 -+:103A900097F9DC3113B922F40003209307993846D3 -+:103AA00012F03ED9219911F0006202D111920E92CA -+:103AB0001DE0D7F8583693F90530022B02D00022CA -+:103AC0000E9207E0C1F30223043B012B8CBF0023BD -+:103AD00001230E9311F4000F05D001F07F03072B93 -+:103AE00003D9202B01D0119001E0042311932099D8 -+:103AF00011F0006201D112921DE011F4000F16D0F6 -+:103B000001F07F03072B14D9202B12D00FE0209B4C -+:103B100022F4E06223F4E06342F4007243F40073A1 -+:103B200002252192209311910E91129103E012909F -+:103B300001E0042412940F9888B11A99219BD1F8BE -+:103B400010231A9801EBC201C1F814332F9C0132E3 -+:103B5000E3B202F03F02C1F81833C0F81023BAF103 -+:103B6000000F36D0FA68DAF80434D2F880410AEB54 -+:103B7000C303C3F80442D2F884013A4AC3F80802E6 -+:103B8000B8F8163003F00703D35C022B11D1DAF832 -+:103B900000100AEBC102C2F80441C2F80801219BDF -+:103BA000013153602F9C01F01F01E3B29360CAF80A -+:103BB0000010DAF80424219B0AEBC201C1F8083492 -+:103BC0002F980132C3B202F03F02C1F80C34CAF898 -+:103BD0000424219911F000642AD011F4000F01F49B -+:103BE000E06312D01B0A043B012B1F4801F07F0247 -+:103BF00005D8142302FB0303D3F80C801AE0142326 -+:103C000002FB0303D3F8088014E01B0A043B012BDA -+:103C1000154801F07F0205D8142302FB0303D3F8F3 -+:103C2000048007E0142302FB03F353F8008001E053 -+:103C300001F07F080B9A022A00D0BAB9B7F83836DB -+:103C40000A98984204DC189A136813F0806F0DD01C -+:103C500099F8043083F0010303F0010307E0C04644 -+:103C6000401B8600C4D285008418860000230D9373 -+:103C70003B6B587D50B1D7F858361B7833B12CB90F -+:103C8000924A01F07F03D356002B0BDB3B6893F87D -+:103C9000463013F0030F2CD05CB3D7F8583693F9A5 -+:103CA000053033B32F9A012A13D9D7F858361B7829 -+:103CB0000BB1162300E03023189C20932193236836 -+:103CC00023F000632360209B43EA05232093219384 -+:103CD0000FE070B1D7F858361B7853B14CB97B4A16 -+:103CE00001F07F030E98D35630EA230028BF01204D -+:103CF0000E90219A12F0006F15D102F07F03022B73 -+:103D000005D0042B03D00B2B01D0162B0BD1069919 -+:103D100039B1022B05D097F95C36013B18BF01235E -+:103D200000E000231193209B13F0006F16D103F0E5 -+:103D30007F03022B05D0042B03D00B2B01D0162BB5 -+:103D40000CD1069C44B1022B06D097F95C36013B9E -+:103D500018BF0123129301E0002012900B99079CD9 -+:103D6000022904BF079BC3F86021636813F4803FF6 -+:103D700040D097F8CE31002B3CD097F8D131002BB2 -+:103D800038D0D7F8583693F90530032B32D0219B21 -+:103D900013F0006F09D103F07F03022B2AD0042B0C -+:103DA00028D00B2B26D0162B24D099F8043013F0F2 -+:103DB000010F1FD1089800F0FC03882B1AD1189925 -+:103DC00001240B684BF4A04B43F480530B60079B1A -+:103DD0001094D3F8F0204FF69F73002A0CBF1822DE -+:103DE0001E2239F8021001EA030343F0200329F8E8 -+:103DF000023001E000201090384621990A9A059B74 -+:103E00000DF17A0419F028DC2346384620990A9AE5 -+:103E100019F022DC062206F136002146FEF3ACF052 -+:103E2000209B13F0006F10D103F07F03022B05D00D -+:103E3000042B03D00B2B01D0162B06D10A99C1F30A -+:103E4000072386F83A1086F83B30189B1A6812F45C -+:103E5000806F13D0219B13F0006F0FD0329C14B1F0 -+:103E6000237A042B0AD1189842F40063036097F870 -+:103E7000C3340D99002B18BF01210D91219911F028 -+:103E8000006F0AD1114A01F07F03D356002B04DAE8 -+:103E9000059A137803F00F0301E0059B1B78089C3B -+:103EA0000C93A42C14D099F8043013F0010F0FD107 -+:103EB000109878B9119A319B38460FF06FDE89F867 -+:103EC0000200C0F30F2089F803001DE0401B8600AC -+:103ED000109A62B1119A384640F62A1319F052D955 -+:103EE000023080B289F80200000A89F80300089BBA -+:103EF000A42B09D199F8023099F8032043EA022350 -+:103F000086F83C301B0A09E099F8043013F0010FE1 -+:103F100001D1109C2CB1002386F83C3086F83D304E -+:103F20000BE02099129A319B38460FF037DE86F865 -+:103F30003C00C0F30F2086F83D001898036813F486 -+:103F4000007F0DD083894BF4005B86F842301B0A5A -+:103F500086F84330C38986F844301B0A86F845301A -+:103F60002E9909B94BF0080B09F104021B9299F83C -+:103F7000043013F0010F14D1189B1A6812F4805FFB -+:103F80000FD197F8D03113B112F0400F09D112F4CC -+:103F9000806F04D1169C14B197F8F8310BB94BF02F -+:103FA000010B0B98022814D197F8CE318BB1B8F1E0 -+:103FB000040F0ED9AB4B30995B5C07EB4303B3F8AE -+:103FC000FE3123B1189A136813F4806F01D04BF4BB -+:103FD000805B3B6B18690EF0A9FD199B00F44060F3 -+:103FE000B0F5406F08BF4BF4807B0BB14BF4004B36 -+:103FF0004FEA1B2386F800B07370329CECB197F83F -+:10400000A034D3B91A98836D13F0080F15D1237A11 -+:104010000B2B08D197F8F0377BB197F8F13763B1E4 -+:10402000A379072B09D832998A79292A05D80B7BDD -+:1040300003F0070343EA021A01E04FF0000A189A5E -+:10404000129C1368494613F0005F18BF4AF0080A33 -+:10405000631EDBB2012B98BF4AF4005A301D0222C6 -+:10406000FDF38AF70023B371F37186F82C3086F8DC -+:104070002D303298002849D097F8A034002B45D134 -+:104080001A998B6D13F0080040D1329B1A7A0B2AD3 -+:104090000BD197F8F037002B38D097F8F137002B79 -+:1040A00034D0329CA379072B30D832998B79292BC5 -+:1040B0002CD8089C09F1180104F44073B3F5407F33 -+:1040C000169B08BF09F11E0103B10231022A11D16A -+:1040D0003246329C2318B3F8BC309375C3F30723E0 -+:1040E000D375831C02320A2B1846F2D106F1200048 -+:1040F000032209E00B2A06F1160002D10231053233 -+:1041000002E0329B93F90E20FDF336F706221B994D -+:1041100006F12600FDF330F79DF88C30002486F878 -+:104120004C309DF88D3086F84D30D7F84C011A99F7 -+:104130004AF0EEDF96F8463096F8472080B243EA20 -+:10414000022343EA00239BB286F846301B0A86F816 -+:10415000473086F84E4086F84F4086F8504086F843 -+:10416000514086F8524086F8534086F8544086F80D -+:10417000554086F8564086F857400D9808B10E9481 -+:1041800003E00E99002900F01D81002221992B46A1 -+:10419000384622F051DE00228046209938462B46D0 -+:1041A00022F04ADE18F000628346099206D12E4BB7 -+:1041B00008F07F029B56002B2ADA36E018F4000F35 -+:1041C00008F4E06310D01B0A043B012B274808F0D9 -+:1041D0007F0204D8142302FB0303DB6814E01423DA -+:1041E00002FB03039B680FE01B0A043B012B1F48E3 -+:1041F00008F07F0204D8142302FB03035B6803E08A -+:10420000142302FB03F31B58023B18BF012302E0F7 -+:10421000931E18BF012343B197F95C36012B04D0DC -+:1042200001234AF4804A139301E0002413941BF005 -+:10423000006F06D10C4B0BF07F029B56002B30DA3F -+:104240003CE01BF4000F0BF4E06316D01B0A043BA8 -+:10425000012B06480BF07F020AD8142302FB03034C -+:10426000DB681AE098E08500401B86008418860011 -+:10427000142302FB03039B680FE01B0A043B012B82 -+:104280009D480BF07F0204D8142302FB03035B68F4 -+:1042900003E0142302FB03F31B58023B18BF012366 -+:1042A00002E0931E18BF012343B197F95C36012B3E -+:1042B00004D001254AF4004A149501E0002014902E -+:1042C0000E993278737821B142EA032343F40063F4 -+:1042D00003E042EA032343F0060333701B0A7370C2 -+:1042E0000E9B06F15802002B0CBF14250E251592CB -+:1042F0001DAC2A4638464146159B19F0ADD92346D8 -+:104300002A463846594619F0A7D92146062206F111 -+:104310002E00FDF331F6139C119D0A9800940024A1 -+:104320000E99219B0195029042460394384619F05C -+:10433000B3D986F86000C0F30F2086F861001499A5 -+:10434000129A0A9B009101920E9902930394209B6A -+:1043500038465A4619F0A0D986F83400C0F30F2029 -+:1043600086F835000E9D06F162004DB16FF03B03FB -+:1043700009F10A01062286F85E3086F85F4008E0FF -+:104380006FF04B0386F85E300E990C2286F85F10B2 -+:104390001B99FDF3F1F5099A52B9584A08F07F03C9 -+:1043A000D356002B04DA159C237803F00F0301E0A9 -+:1043B00096F858300C9D1B0243EA050506F15E098C -+:1043C0000C951BE00E99062206F15800FDF338F615 -+:1043D0000E99102206F15E00FDF332F606F12E0072 -+:1043E0000E990622FDF32CF60E9886F8340086F816 -+:1043F00035008146139014908046834618990B68C7 -+:1044000013F4806F0BD0219A12F0006F07D0D7F809 -+:10441000400107990A9B2AF0B3DF86F833004FEA80 -+:104420001A23F37086F802A00C9A130AB274F3747C -+:10443000209B13F0006F02D097F8C0A40EE003F0A9 -+:104440007F03022B07D0042B05D00B2B03D0163B88 -+:1044500018BF012300E000231FFA83FA18F0006F51 -+:1044600003D097F8C0349D000EE008F07F03022BC4 -+:1044700007D0042B05D00B2B03D0163B18BF01230C -+:1044800000E000239B009DB21BF0006F03D097F863 -+:10449000C0341C010EE00BF07F03022B07D0042B6D -+:1044A00005D00B2B03D0163B18BF012300E00023DF -+:1044B0001B019CB23B6B18690EF038FB45EA0A03FE -+:1044C0002343C0B243EA002333751B0A7375219B53 -+:1044D00013F0006F02D097F8C04413E003F07F039D -+:1044E000022B0DD0042B0BD00B2B09D0B3F11600EF -+:1044F00018BF012005E0C04684188600401B8600D6 -+:10450000002084B2119D6B1EDBB2012B07D83B68E3 -+:1045100044F01004D3F88C209369013393612199FE -+:10452000384615F02BDB44EA000080B23072000AF6 -+:104530007072219938461FF055DEB072C0F30F201B -+:10454000F072209938461FF04DDE3073C0F30F2013 -+:1045500070730D9808B90E9979B1414638461FF02D -+:1045600041DEB073C0F30F20F073594638461FF098 -+:1045700039DE3074C0F30F207074219911F0006F90 -+:104580000CD0119A042A09D10A9A384618F0ACDEE8 -+:1045900086F83E00C0F30F2086F83F00209911F006 -+:1045A000006F0CD0129B042B09D10A9A384618F0E0 -+:1045B0009BDE86F84000C0F30F2086F84100079C80 -+:1045C000636813F0400F00F0CE80169D002D00F0C0 -+:1045D000CA806A4B30981B5C179307EB4303B3F810 -+:1045E000FE31002B00F0BF8018990B6813F4806F28 -+:1045F00040F08D802E9A002A40F08980219C384618 -+:104600002146119A0A9B18F0BDDD8246B9F1000FD0 -+:104610001AD04146139A38460FF082D8149A0446AD -+:10462000594638460FF07CD899F8032099F80230A3 -+:1046300043EA022303EB040896F8352096F8343059 -+:1046400043EA022318181BE0109B13B1804648462A -+:1046500016E02146119A4B4638460FF09FDA209C0F -+:10466000129A21460A9B00EB0A08384618F08ADDA8 -+:1046700021460546129A38464B460FF08FDA40190C -+:104680001FFA88F3B3711B0AF37183B286F82C30DA -+:104690001B0A86F82D30179C07EB4403B3F8FE5134 -+:1046A000CAEB0804A54225D31898036813F0400FFD -+:1046B00002D0309901291DD038462199119AC4EBB6 -+:1046C00005030FF035D8FF2802D84FF4807304E0BB -+:1046D000B7F82A36834228BF034699B2309B07EBCE -+:1046E0004302B2F82C368B4204D0A2F82C1638467E -+:1046F00026F0CCD83B6893F84430002B33D0309C64 -+:10470000032C30D8D7F864011799424628E03B685B -+:1047100093F844303BB3309D032D24D8B9F1000FFA -+:104720000CD0139A384641460EF0FADF99F8032070 -+:1047300099F8023043EA02231A180EE0219C119ADC -+:1047400021460A9B384618F01DDD119A0546214680 -+:1047500038464B460FF022DA4219D7F86401179910 -+:10476000079B3DF02FDD1898036843F08403036036 -+:10477000BDF88C0025B0BDE8F08FC04698E08500FC -+:104780002DE9F0479946536A064613F4007F8846A0 -+:1047900017469DF920A0146902F1240515D0E86898 -+:1047A00083B2000C84F8423084F844001B0A000AEB -+:1047B00084F8433084F845002378607843EA002386 -+:1047C00043F4005323701B0A637033682D6993F818 -+:1047D000443093B1F36A03EB4803B3F91C3063B977 -+:1047E0005DB12B69D3F8D43293F89D30032B04D9F3 -+:1047F000D6F864012B463DF0C5DDB8F1040F22D197 -+:1048000094F84D3094F84C2042EA0324336893F82E -+:104810003830D3B1384612F045D906EB8000D0F8D5 -+:104820004C12D1F85835D1F860055A1CC1F85825FA -+:10483000C369A1F8C8409A4288BFC261D1F8602517 -+:10484000136A013313624FF6FF74B9F1000F05D0FC -+:10485000F26A02EB4802938B534493834FF6FF7343 -+:104860009C4204D03069A821224639F0F3D933693B -+:10487000394603EB8803D8680C4B4A465B6A984775 -+:10488000002810DA0A480CF00FFF0A4A13680133B7 -+:104890001360B9F1000F06D0F26A02EB4802938B65 -+:1048A000CAEB03039383BDE8F087C046E0A685000A -+:1048B000BC568600E827020070B50D46D0F8601699 -+:1048C0000446CB7AAB420CD025B10C31B0F8282687 -+:1048D00015F098D9D4F860362046DD72216BFEF7CA -+:1048E000F7FD002070BDC0462DE9F04F89B00023D0 -+:1048F0000D46179907460492149CDDF854800793DF -+:104900000693DDF848B0DDF84C903AF073DD049A78 -+:10491000824602F001060096386829462246434640 -+:104920001EF0D2DC0590002840F0ED80B5F906308D -+:10493000002B1CDAA9882A895EB1169BCDF800806D -+:1049400003930194CDF8088049003869013123466A -+:1049500009E0169BCDF8009003930194CDF80880F0 -+:10496000386949005B4638F0FBD80590CBE0B9F1D7 -+:10497000030F0DD9042207A85946FDF3FDF2B9F142 -+:10498000070F05D906A80BF104010422FDF3F4F288 -+:10499000049A0799931E1F2B21D8DFE813F02300F8 -+:1049A0002500270029002E00310038003A004B0076 -+:1049B0004D0053005500570059005B005D005F003B -+:1049C000200065006C0074007600870089008D006F -+:1049D0008F00940096009B002000A6009D006FF0C1 -+:1049E00016038FE04A4B09E0494B71E0494B05E063 -+:1049F000002900F38580474B05E0474B1B6879E0B1 -+:104A000000297DDB444B1960444B002239E0444BC4 -+:104A1000F4E719B1434B1B68002B71D0404B0022C7 -+:104A20001960414B1A60414B1A60414B1A60414B6F -+:104A3000013A26E03B4BE1E73A4A1368002B5FDD81 -+:104A4000116060E03C4BD9E73B4B41E03B4BD5E785 -+:104A50003A4B3DE0344BD1E7334B39E0D7F86C3279 -+:104A6000D3F8D8329B6845E0354B1A68354B1B6844 -+:104A700043EA02433EE0324B0A141A60314B01F024 -+:104A8000FF021A603FE0304BB8E72F4B1960002956 -+:104A900039D02E4B002119602D4B4FF0FF321A6098 -+:104AA0002C4B1A602C4B19602C4B11E02C4BA5E7BA -+:104AB000002925DD2A4B0BE02A4B9FE74B1E092BD3 -+:104AC0001ED8284B04E0284B98E7002918DD264B18 -+:104AD000196018E0254B91E79AF8063063B9244B2A -+:104AE0000A1E18BF01221A700DE09AF806301BB991 -+:104AF0001F4B1B78236006E06FF00602059202E070 -+:104B00006FF01C030593059809B0BDE8F08FC0460F -+:104B1000EC270200D8270200E0270200B827020095 -+:104B2000C0270200401E0200D4270200D027020046 -+:104B3000C8270200B42702002C1E0200441E0200F7 -+:104B4000142C0200102C0200BC270200E4270200F3 -+:104B5000281E0200381E0200C4270200DC270200C3 -+:104B6000341E02003C1E0200241E0200CC2702005C -+:104B7000B027020037B5036804465B7E002B40F087 -+:104B8000C480026992F8EA305BB1D36ED3F8202179 -+:104B900040F2044302EA0303B3F5806F40F0B580AE -+:104BA00005E0106E0AF050FE002840F0AE80236849 -+:104BB00093F8203033B9206907F062FE22680123A0 -+:104BC00082F8203023681B6FFBB9206907F0D6FDFF -+:104BD00010F1090F19D12268136F13F0020114D1DB -+:104BE00043F0020313670D4604EB8503D3F84C1220 -+:104BF00041B18B7933B94B7923B18B7C13B120460A -+:104C00003AF03ED90135082DEED123681D6F1DB154 -+:104C1000204612F079D976E0012384F82930204625 -+:104C200021F004D82368596B39B103234FF4807203 -+:104C3000009320462946134605E0032300932046AF -+:104C40004FF480720B461EF0BFDFA0680AF02CDD27 -+:104C5000236801221A7694F89D3173B120460CF036 -+:104C6000C1FDD4F840352046598E23F0DFDE002305 -+:104C700084F89D3120461DF0C3D9B4F85C17204656 -+:104C800021F04CDF206907F0DFFF236893F82F3015 -+:104C90001BB1D4F8340730F03DD8236893F8313095 -+:104CA0007BB1002504EB8503D3F84C1231B18B792D -+:104CB00023B94B7913B1204635F0FADE0135082DC2 -+:104CC000F0D1204615F00EDF204618F0EDFA012550 -+:104CD000D4F8AC114FF448720123A0680AF076DCD6 -+:104CE000204684F8F15125F0D1DD204614F072DF22 -+:104CF000204626F02DD950B1204626F007D920466F -+:104D0000294626F00DDB002001E06FF008003EBDD3 -+:104D1000D0F8403570B55D8E064605F44063B3F5B6 -+:104D2000406F22D1036893F8463013F0030F0BD085 -+:104D300005F47041D0F85C01B1F5805F14BF00212B -+:104D4000012141F0B7DA80B92846FEF36BF2044640 -+:104D50002846FEF367F244F430640E288CBF4FF40B -+:104D600080504FF400500443A5B2326B05F47043F9 -+:104D70005268B3F5805F14BF00230123934205D02E -+:104D8000D6F85C01012140F0B9DD0546D6F85C019A -+:104D9000294641F003DB80B905F47043B3F5805F29 -+:104DA00014BF38233C23F358346BD6F85C013363CB -+:104DB000012140F0A3DD34630546284670BDC0469E -+:104DC00070B50025044680F8E85124F0B7DDE36AA9 -+:104DD0002946986A8022FDF333F1206908F0BAF978 -+:104DE000D4F840012AF09EDCC4F8885670BDC04655 -+:104DF0002DE9F04390F8A03187B00446002B40F035 -+:104E0000ED8003681B7E002B00F0E880012380F812 -+:104E1000A031006907F0E6FE2269074692F8EA3001 -+:104E20005BB1D36ED3F8202140F2044302EA0303BE -+:104E3000B3F5806518BF012503E0106E0AF004FD8C -+:104E40000546002D6FD1D4F8680104214FF0B0DB86 -+:104E5000204621F0A3DE00B90137A94604EB09037F -+:104E6000D3F84C62002E59D096F80680B8F1000FA6 -+:104E700054D1304633F06ADC73793F18002B4DD0A3 -+:104E8000236893F83130002B3FD0D6F8CC3013F0A4 -+:104E9000010F3AD0204631460CF0B4FC23683F188D -+:104EA00093F89530002B39D0D4F86C122046BC31E1 -+:104EB00050F074DC0546002830D02046294622F008 -+:104EC0008BD82B7E13F0020F19D02846022150F008 -+:104ED000B7D8B17CD4F86C32D1F1010138BF0021D0 -+:104EE000082201920291204631460332BC33CDF8AC -+:104EF0000080CDF80C80CDF8108017F00FDED4F8CC -+:104F00006C22012382F8F03008E02046314639F067 -+:104F1000B7DF3F184FF47A6001F01EDC09F1040995 -+:104F2000B9F1200F9AD10025D4F8B434EA18136BE4 -+:104F300013B1506A98473F18343540F2AC439D4254 -+:104F4000F2D194F8F1314BB1A068D4F8AC110AF069 -+:104F500085DB00B90137002384F8F1312046FEF7E4 -+:104F60000DFB236800211976236B4FF0FF32C61921 -+:104F700018690DF0B3FD204615F08ADAD4F878529E -+:104F800007E00023291D606801220093FDF35AF712 -+:104F90002D68002DF5D1236893F82F3073B1631974 -+:104FA000D3F84C1239B18B792BB10B791BB1204658 -+:104FB0000CF028FC36180435202DF0D1D4F87C02F2 -+:104FC00010B10BF03BFE3618206907F0BDFD002341 -+:104FD000801984F8293084F8A03100E0002007B05F -+:104FE000BDE8F0832DE9F04F9BB005462598089267 -+:104FF0000793827AC37A0F4642EA0323269A00F186 -+:105000000C010C3A08980A9113930B92C27D837D90 -+:105010000DF1580943EA0223C3F3C70ABAF10E0F90 -+:1050200094BF002101210F91079918F0C1F8249A2B -+:1050300028460A32114609920F9A50F0B9DB002433 -+:10504000804615AE28462599269A4B461594169407 -+:1050500000961CF0DFDF30B928462599269A4B468A -+:1050600000961EF0D7DFB8F1000F06D0D8F8043054 -+:1050700013F0010F01D00C9427E00B990A9832220B -+:10508000FDF31CF3014620B14078023120F0E2DF4D -+:1050900058B90B990A980122FDF310F3014638B173 -+:1050A0004078023120F0D6DF10B101230C9301E0EB -+:1050B00000200C90B8F1000F07D00C9929B9D8F84E -+:1050C000043043F00103C8F804300A980B99032216 -+:1050D000FDF3F4F2044608B14378A3B92B6893F8C2 -+:1050E0003F3053B1B5F82606C3B2534503D0FEF3A3 -+:1050F00099F0504501D1012300E0002300225FFA1E -+:1051000083FB0D9211E02B6893F83F3043B1B5F863 -+:105110002606FEF387F0A378834201D1012300E045 -+:1051200000235FFA83FBCDF834B0BBF1000F01D14F -+:105130005B4602E03B1E18BF01235FFA83FA2B682F -+:1051400093F8463013F0030002D11090119024E040 -+:1051500095F8723263B9BAF1000F09D0D7F8D4329A -+:10516000DB8813F0200003D110901190129018E00A -+:105170000A990B9A284620F0DFDF0A9911900B9AC2 -+:10518000284620F0A5DF2B68109093F94C0020B141 -+:1051900028460A990B9A1DF0C9DC1290BAF1000F4B -+:1051A00069D02B6893F8463013F0030F63D0109B3F -+:1051B000002B60D0119800285DD019785A782846C5 -+:1051C0000FF0E0DEB5F82696064609F47043B3F515 -+:1051D000005F0CBF38233C23EC58D5F85C016168B4 -+:1051E00040F08CDA10F0080F01D0002104E094F8B0 -+:1051F000EC30191E18BF0121119A137813F0020325 -+:1052000017BF10981A464378C3F3800209F440632D -+:10521000B3F5406F18D1B5F82636B34202D100215C -+:105220000E912EE02B6893F82F30002B40F05B841A -+:105230003046FDF3F7F70446B5F82606FDF3F2F71E -+:10524000844240F0508414E0A9B1A2B106F4406356 -+:10525000B3F5406F0FD12B6893F82F3073B93046F8 -+:10526000FDF3E0F70446B5F82606FDF3DBF78442CC -+:1052700004D10E9605E000220E9202E000230E9368 -+:105280009A462B6B5B7D002B3AD0BBF1000F37D0D9 -+:1052900095F8723233B995F87432002B30D0BAF1E8 -+:1052A000000F2DD195F849365BB1159B002B08DD19 -+:1052B000169B1B7813F0040F03D0D5F8582604234F -+:1052C000136195F8493653B10C9850B9139911F000 -+:1052D000200F0ED1D5F858260423D36009E00C9A8C -+:1052E0003AB1159B002B08DD169B1B7813F0010FBC -+:1052F00003D0D5F8582604231362284625F06CDE27 -+:105300002B6893F8463013F0030F46D0BBF1000F23 -+:1053100043D095F8723233B995F87432002B3CD0F3 -+:10532000BAF1000F39D1B5F8263603F44063B3F56E -+:10533000406F14BF00210121109B13B90C9830B9A4 -+:1053400016E0109A937803F00303032B05D1D5F8E8 -+:10535000582604239361109B53B11098837803F06F -+:105360000303022B04D119B1D5F858260233D362B6 -+:10537000119A7AB1109B6BB111985A78037813F097 -+:10538000020F07D112F0040F04D019B1D5F8582636 -+:105390000423D362284625F0D1DE2B6893F82F3002 -+:1053A000E3B1D5F8FC341B78C3B10D99B1B92846E7 -+:1053B00011992FF01FDA88B128460D992FF01CDBC8 -+:1053C00028462FF00FDBB5F8263603F44063B3F51B -+:1053D000406F03D1284601212FF080DAB8F1000F89 -+:1053E00029D0D8F8F03033B300230B99824A0A98B9 -+:1053F00000931CF087DF41460246284620F0C0D9C2 -+:105400002B6893F8463013F0030F14D0119A2AB189 -+:10541000129B28460093109B41460AE0D8F80430BE -+:1054200013F4803F07D01198119A00904146284606 -+:1054300013461DF0DBDB95F87032002B00F06C8317 -+:105440000FB93E4601E0D7F8DC62BAF1000F00F078 -+:1054500083802B6893F8463013F0030F3DD0BB7C5C -+:1054600043B9B8F1000F08D1284609990F9A50F0B6 -+:10547000B9DA8046B8F1000F2FD01199C9B1D7F829 -+:10548000CC3013F4005F05D0B7F8343543F0200377 -+:10549000A7F83435129A109B009228464146119A7B -+:1054A0001DF0A4DBB7F8343523F02003A7F834351A -+:1054B0000DE0BB7C5BB9D8F8043013F4803F06D014 -+:1054C000119B284641461A4600931DF08FDB284663 -+:1054D0000A990B9A434620F079D9089928461EF07C -+:1054E0005BDA41B238461EF099DA38461EF0EED942 -+:1054F0000899284612F0E4DA0146384611F046DAF7 -+:10550000BB797BB9D7F8E032D7F8D422188A9B8AC6 -+:105510005085938573792BB9BB7C1BB1384601212B -+:1055200035F038DF0023B371F371BC7CA4B996F871 -+:105530008530012B10D186F88540D5F8400126F042 -+:10554000FDDF284639460F22234600940194029439 -+:105550000394049417F0E2DA002F5AD0BB79002BA1 -+:1055600057D1BB7C002B54D0259925988B784A784D -+:105570001B0443EA02230A781343CA78043143EA3E -+:1055800002698B784A781B0443EA022302791343A9 -+:10559000CA7843EA0264F26912B9336A13B935E092 -+:1055A000944204D3944231D1336A99452ED2DDF826 -+:1055B00090E0002300930193029303930493284601 -+:1055C000394616220EF1100317F0A8DA384608996A -+:1055D000079A259B24F0A2DFBBF1000F16D0FB79C0 -+:1055E00063B1BB7C23B107F1BC00FDF3B5F128B971 -+:1055F00007F1BC0104E0C0460FD4010007F1D60159 -+:10560000002228461346009222F02ADDC6F8209098 -+:10561000F461BAF1000F00F01F82BB79002B40F05B -+:105620009681BB7C002B00F0928114AB00932599EE -+:105630003846269A0DF1670316F016DBBDF85010B8 -+:10564000D7F8E462A7F8201595F8EB41002C65D156 -+:1056500000284FD03378022B19D138462146B6F8AE -+:1056600026900BF0DDFDB5F8303885F8324803B1EF -+:10567000F38438461EF0A6DFD7F8E432A6F8269069 -+:105680005B8B002B4AD0384611F062DA46E02B687B -+:105690005B6B4BB195F8FA3133B1B8F1000F14D010 -+:1056A00098F8D2300F2B10D0B27822B12846394664 -+:1056B00023F0D6D832E04FF0FF330093284607F1AD -+:1056C000BC01134622F0CCDC28E095F80D372BB353 -+:1056D000B3785BB1B8F1000F05D0D8F8043023F0EF -+:1056E0000063C8F80430384616F09CDB384623F0D7 -+:1056F000B9DD13E0337A23B1718911B9384623F04B -+:10570000DFDDD7F8E4325B8B43B13378022B05D170 -+:10571000336A012B02D138461EF040DFF3781BB10B -+:105720003846002123F0C0DC737A1BB138460021D3 -+:1057300023F0B2DE2B6B5B7D002B41D0139A284601 -+:10574000C2F3802124F0B2DD169A002A38D0159BCE -+:10575000002B35DDD5F8581691F90130B3F1FF3F34 -+:1057600009D11378C3F340020B78934203D0284643 -+:10577000012120F0FDD8169B1B7813F0040318BFFD -+:10578000012385F8463695F94636012B03D0D5F826 -+:1057900058361B690BB1002300E0012385F842361F -+:1057A000B8F1000F0CD0D8F8043023F00402C8F888 -+:1057B000042095F946361BB942F00403C8F80430BA -+:1057C0002B6893F8463013F0030F36D0109B002B54 -+:1057D00033D0D5F8582692F90630B3F1FF3F27D1E0 -+:1057E000109892F90520837803F003039A4204D0BD -+:1057F00028460B211A4620F0BBD810998B78C3F3AA -+:105800008002D5F85836DB79934203D028460D2123 -+:1058100020F0AED8109A9378C3F30012D5F858361A -+:105820009B7A934209D02846102120F0A1D804E0A9 -+:10583000012B0CBF032300235371D5F85C01B5F88D -+:10584000261640F073DB90B1D5F85C01B5F826164A -+:105850003FF0ACDF2B6B18690DF068F9B5F8263610 -+:10586000834204D1002128460A461EF095DBB8F198 -+:10587000000F3FD0D8F8043013F0400F00F03F8104 -+:105880000A9B0B981893179006E02846214618AA01 -+:1058900017AB1DF063DE40B918981799DD22FCF3B1 -+:1058A0000DF704460028F0D122E1A11C0E79012E4B -+:1058B00040F025818A7995F80C3202F00F0203F04E -+:1058C0000F039A4200F01B8105F500740634204650 -+:1058D0001822FCF351F32B6893F830303BB1D5F824 -+:1058E0003407214600F563701822FCF345F338466F -+:1058F000314602E128460A990B9A10F087DC01280C -+:1059000002D128460EF018DA0E9929B195F86D35B6 -+:1059100013B9284618F0DED8259A079B0092D5F8CF -+:105920004C013946089A49F07DDAD7F8CC3013F4A7 -+:10593000005F00F0F180259B269800930190394686 -+:10594000D5F84C01089A079B4AF0C2D9E4E0BB7C29 -+:10595000002B40F081800C9909B1012102E0139ADB -+:10596000C2F34011CCB2B8F1000F15D0D8F8043012 -+:1059700014B143F0040301E023F00403C8F8043039 -+:105980000B990023664A0A9800931CF0BBDC414641 -+:10599000024628461FF0F4DE2B6B5B7D13B3159B8C -+:1059A000002B11DD169B1B7813F0040F03D0D5F8E4 -+:1059B000582604231361169B1B7813F0020F03D0A3 -+:1059C000D5F85826042353620C9B1BB9D5F85826EA -+:1059D0000433D3611CB9D5F858260423D360284674 -+:1059E00025F0FADA2B6893F8463013F0030F00F035 -+:1059F0009380109840B1837803F00303032B03D105 -+:105A0000D5F85826013393621199C9B1119BB5F8A5 -+:105A100026165A781B7843EA022010F0100F03D1A3 -+:105A2000D5F858260423536310F0020F08D101F46F -+:105A30004063B3F5406F03D1D5F8582604231363B0 -+:105A4000109828B90C9919B1D5F858260423536138 -+:105A5000284625F073DB5FE095F85735002B5BD0C7 -+:105A6000BBF1000F58D0139A12F0020F54D00A98CD -+:105A70000B990022FCF322F6034600284CD028465E -+:105A8000991C5A7839F06EDC0446002844D0837C97 -+:105A9000002B41D10899079A16F0B4DE00283BD0BC -+:105AA000259BD4F8D06226980093249B019003F1A3 -+:105AB0001002284608990123029620F053DC024682 -+:105AC00050BB296BD5F86036503106F138009B7811 -+:105AD0004BF054DA269808990090079A2046259BA7 -+:105AE00034F034DD18E000218A460E91FFF7C9BB7F -+:105AF000022385F80E32384601211CF051D90023CB -+:105B00000B990A98064A00931CF0FCDB41460246BA -+:105B100028461FF035DEEDE61BB0BDE8F08FC0462D -+:105B20000FD401002DE9F04FD2F81080C1B0D8F8A1 -+:105B3000D8A2064609910892DAF82C00DAF830105B -+:105B400000220793FCF3BAF520B1831C109342782E -+:105B50000B9205E0099A099B093210921B7A0B936C -+:105B60002CAF002128223846FCF36AF200212822BB -+:105B700022A8FCF365F2DAF830100122DAF82C00E2 -+:105B8000FCF39CF5DAF8301004463222DAF82C00E7 -+:105B9000FCF394F505463CB16278102A04D8381D10 -+:105BA000A11C2C92FCF3E8F13DB16A78102A04D8CC -+:105BB00023A8A91C2292FCF3DFF1099AD38813F0E1 -+:105BC000010F17D0316B4B7DA3B10A6D2CAC201D9A -+:105BD00054312C92FCF3D0F1D8F8CC3013F4005FA0 -+:105BE00005D0D6F84C014146224649F0E3DF0023B8 -+:105BF000229309E022AB0093099B304603F138025F -+:105C000041462CAB20F022D9B8F86250DAF82C408B -+:105C1000B5F5806FDAF8307059D0B5F5006F04D162 -+:105C20000022934611920C9257E020463946FDF32C -+:105C300051F3119020B143784FF0000B0C930BE01F -+:105C4000204639463022FCF339F5834610B9119AC3 -+:105C50000C9201E043780C93402D09D0802D07D0A1 -+:105C6000102D05D0B5F5807F02D0B5F5007F33D17A -+:105C7000D8F8582040F2371302EA030363B30C9AB2 -+:105C8000BBF1000F08BF1422402D0C922ED14FF013 -+:105C900000094F4616E0162307FB03F303F5B47320 -+:105CA00008EB03040998211D0622FCF349F140B9D1 -+:105CB00040AB03EB890204F10A0342F8B83C09F156 -+:105CC00001090137D8F8CC329F42E4D310E000221A -+:105CD000934611920C9200E045B1D8F8582040F25A -+:105CE000371302EA03030BB118230C934FF000099A -+:105CF00040F2EE5301933FAB0293079B099A002BAE -+:105D000014BF20210021304608F1C20300921CF08C -+:105D100053DB0D9030B930460D99B8F80C2332F0B2 -+:105D2000DDDE83E23F9A304602F5BC630E330A9211 -+:105D30004146099A0E93FDF707FB0A9A1070C0F3CB -+:105D40000F2050709AF8223093709AF82330D37055 -+:105D5000131D3F93079B8BB10AF124042046FCF3EB -+:105D6000FBF510B93F98214602E03F9808F1D601B3 -+:105D70000622FCF301F13F9B06333F933F9A00213B -+:105D80000F921046109B0B9A26F0EED92DAB0121F5 -+:105D90002C9A3F9026F0E8D90C9B3F90002B7CD0AA -+:105DA000BBF1000F11D0B9F1000F03D030465946B6 -+:105DB000FDF7F6FA3F9C5946204617F0A7DC3F90C6 -+:105DC0009BF80130A346637019E0402D09D0802D67 -+:105DD00007D0102D05D0B5F5807F02D0B5F5007F36 -+:105DE0005BD1A649834617F091DC099B3F9003F1F4 -+:105DF0007B02304641460BF1040313F0F5DA402DE7 -+:105E000009D0802D07D0102D05D0B5F5807F02D0A8 -+:105E1000B5F5007F41D1B9F1000F01D14C4626E024 -+:105E20009BF801300BF1020202F80390D7184FEAF9 -+:105E300019237B709BF80130002402338BF801306A -+:105E40003F9B02333F9312AB07EB041053F824102F -+:105E500002301022FCF390F09BF801300134103333 -+:105E60008BF801303F9B10334C453F93EBD1D6F874 -+:105E70006C32D3F8D8325B68022B0ED16CB10022A1 -+:105E800000920192CDF808B09BF801303046023301 -+:105E90000393572113461DF00BDE229A2AB13F9837 -+:105EA000322123AB26F060D93F90DAF82C401CE079 -+:105EB0006278C1F102031B199B18671C83421CD82E -+:105EC000119BA34219D02378012B0BD9302B09D079 -+:105ED00002323F982146FCF34FF03F9B6278023339 -+:105EE0009B183F933B78A21CD41834B1DAF82C10DD -+:105EF000DAF830000B189C42DAD3336893F8463056 -+:105F000013F0030F18D0089A536813F4803F13D08E -+:105F1000326B0DF1DB041368404621466532022BDB -+:105F200014BF0023012326F081D83F982D211A2287 -+:105F3000234626F019D93F9096F8653633B106F519 -+:105F4000CC613F98043117F0E1DB3F90336893F860 -+:105F5000463013F0030F1FD0089A536813F4803FA4 -+:105F60001AD0326B0DF1DB0113684046022B14BFCF -+:105F700000230123653226F059D83F990E9B8B42AE -+:105F800001D2002202E00E9BC1EB030230460DF16C -+:105F9000DB0325F009DF3F9033685B6B4BB3099A55 -+:105FA000D38813F0040F24D00DF1F50034490322F7 -+:105FB000FBF3E2F702238DF8F83000238DF8F93077 -+:105FC00001338DF8FA3096F8FA313BB1099A92F91B -+:105FD0006A30002B02DA96F80A3700E000238DF8C9 -+:105FE000FB303F98DD2107220DF1F50326F0BCD8E8 -+:105FF0003F90B5F5806F02D0B5F5006F06D1D8F8A7 -+:106000002C3543B33F98D8F8281505E00C9B13B303 -+:10601000119A2AB13F98114617F078DB3F901AE0A9 -+:10602000402D18D0802D16D0102D14D0B5F5807FBE -+:1060300011D0B5F5007F0ED03F9C1249204617F0D5 -+:1060400065DB099B3F9003F16B023046414604F14A -+:10605000080313F0C9D96B1E9BB2012B03D9042D81 -+:1060600001D0082D10D1099A506E002838D0B2F80E -+:1060700068100C300C39FDF32DF11BE0CCD28500FB -+:1060800017D40100E2D28500402D09D0802D07D021 -+:10609000102D05D0B5F5807F02D0B5F5007F1FD15A -+:1060A000099B586EE0B1B3F868100C300C393022FF -+:1060B000FCF304F3A0B1D6F86C32D3F8D8325B68A5 -+:1060C000022B0DD14378102B0AD902330022029003 -+:1060D0000393304657210123009201921DF0E8DC22 -+:1060E000D8F8583013F0040F01D004230EE013F059 -+:1060F000020F01D0022309E013F0010F01D00123A8 -+:1061000004E013F4807318BF4FF48073089A13648B -+:10611000336893F8463013F0030F2DD0089A136CB0 -+:10612000013B012B09D8536813F4802F05D0114689 -+:106130003046062224F0B4DD1EE0089A536813F4BA -+:10614000802F19D011463046062224F04DDD30460E -+:1061500016F07ADF012801460ED1D6F8F83742F260 -+:106160000E721B88013B9BB2934202D83046013924 -+:1061700000E0304628F0AADF3F9C0E9BA34201D2EC -+:10618000002302E00E9AC4EB020300932023019344 -+:10619000002123464FF0FF32404639F0C5DF0F9B08 -+:1061A00000273F90C01A03930490414655223B4676 -+:1061B000304600970197029716F0B0DC0A9A3F9B91 -+:1061C000A2F11805C5EB0304DAF834100D9B9C828C -+:1061D00021B17068DAF8382000F08ADD0A9A706818 -+:1061E000C5EB0203E41A214600F072DDCAF8340060 -+:1061F00040B1079BCAF838408AF83C300A992246D9 -+:10620000FBF3BAF6099A3046B2F862300197C3F34D -+:10621000401300930297089B0D99D6F804281FF0AD -+:1062200081DC0D9B002808BF00230D930D9841B021 -+:10623000BDE8F08F2DE9F04F95B0079119690692EE -+:1062400005930A9101F106098A7999F80130064609 -+:1062500042EA0323069A0893C0F87828C3F381051D -+:1062600013465B79127942EA0323099303F003038F -+:10627000022B08D1089C14F4004F04D0D5F101037F -+:1062800038BF002300E00023DBB205990B930B9A83 -+:106290008B8AA3F10A0893001DB918339845C0F200 -+:1062A000A081089B03F0FC07A42F03D0842F01D00A -+:1062B000942F03D1B8F10F0F40F3938199F8043074 -+:1062C00009F1040A13F001030C9303D00024109485 -+:1062D0000D9408E05146304639F020D8011E18BF11 -+:1062E000012110900D9125B1002293460E920F923C -+:1062F00010E009F110043046214638F0EBDF0E9033 -+:1063000010B183460F9505E03046214639F04CD850 -+:1063100083460F9096F8C83123B9326892F82C3032 -+:1063200033B925E030460699059A00230FF068DD61 -+:10633000A42F03D0842F01D0942F01D10D9B53BBE8 -+:10634000802F28D0502F26D0002D40F006840D9CA1 -+:106350000CBB5046FCF3F0F2002800F0FE83BBF1CA -+:10636000000F18D109F11000FCF3E6F298B9F4E33C -+:106370000C9981B90D9B43B192F838305BB155B996 -+:10638000BBF1000F07D1109C2CB9D2F88C20936F71 -+:1063900001339367E1E396F8C8317BB9BBF1000F95 -+:1063A00001D05C4601E0D6F86C4294F8E5302BB1A0 -+:1063B00030460699059AA3680FF022DD012D10D111 -+:1063C000C42F0ED0D42F0CD009F10A00FCF3C4F274 -+:1063D000002840F0C28399F80A3013F0010F40F012 -+:1063E000BC83059930460B69A1F8148006330B6114 -+:1063F00033684946D3F88C20D36C0133D3641FFA39 -+:1064000088F30093069A13AB12F072D830B1336858 -+:10641000D3F88C20D36F0133D3679EE3139A12B164 -+:1064200033689B6A1362012D39D1059A059B106967 -+:10643000998A00F11002059C1A61A1F11003A38250 -+:106440000B9B2BB100F11402A1F114032261A38272 -+:106450000599A42F8C8A0FD113990B699B79002B76 -+:1064600000F07B8391F8DF30002B00F0768330461C -+:10647000089A2FF0DDDD70E3336893F84230002B8B -+:1064800000F06B83842F02D0942F40F06683D6F8FF -+:10649000400113992346009728F0C2DF5DE3069A76 -+:1064A000937DD27D43EA0223C3F3C7030E2BD4BFEF -+:1064B0000023012311930C9B002B62D199F8163015 -+:1064C00099F8172043EA0228139B33B9304609F1A3 -+:1064D0000A01119A4FF06CD91390089C14F4006AC9 -+:1064E00005D0139B1BB1B3F8BC30434525D0139B9B -+:1064F0000BB1A3F8BC80139B8BB142E006EBC20347 -+:1065000003F5F3642046FCF327F270B909F10A00A1 -+:1065100021460622FBF314F5013508B906E01D46B5 -+:1065200096F8E837EAB29342E8D20024BAF1000FB5 -+:106530000CD064B1E388434521D13368D3F88C2073 -+:10654000D2F8BC310133C2F8BC3106E3BCB996F8CD -+:10655000E83709F10A0106EBC30202F5F3640133DF -+:1065600086F8E83706222046FBF306F596F8E8178A -+:106570000A23B1FBF3F202FB131386F8E837A4F801 -+:1065800006800D9961B10E9A52B19BF806303BB965 -+:10659000DBF8E4321B7A1BB15846089910F0B4DEE0 -+:1065A000059B059C1869998A00F118021A619246A8 -+:1065B0000B9AA1F11803A38232B100F11C02A1F1E0 -+:1065C0001C032261A3829246059C0899099BB4F89A -+:1065D000148011F48044C3F3C0150DD0B8F1070F37 -+:1065E00006DC3368D3F88C20536E01335366B4E273 -+:1065F000B02F40F0B28227E0502F00F087800ED8F5 -+:10660000202F00F0768205D8002F00F07282102F24 -+:1066100045D0A2E2302F42D0402F56D09DE2B02F7D -+:106620000ED006D8802F00F09080A02F00F055816A -+:1066300093E2C02F00F0AC81D02F00F07B828CE27F -+:10664000B8F1050F40F38382BBF1000F00F08582A3 -+:106650009BF80630A3B19BF80430002B00F07D823C -+:10666000069ACDF800800195137CD6F8340703F024 -+:106670000803029359464A46534604F06DFE6CE205 -+:10668000D6F8403593F93430002B00F06682584636 -+:10669000494652464346009532F09ADC5DE2B8F135 -+:1066A000050F40F35482BBF1000F00F056829BF8B7 -+:1066B0000630002B40F05182139B58460093494608 -+:1066C0005246434632F042DA47E2336893F8953057 -+:1066D00013B996F872326BB108F118030393304680 -+:1066E0002C2109F10A02234600940194CDF8089068 -+:1066F0001DF0DED9069B0A9C0093D6F84C01494652 -+:1067000052464346019449F00FDB26E2B8F10B0FE5 -+:1067100040F31D82D6F84C015146424649F0BEDC9A -+:10672000D6F868319B79002B00F017820D9900296B -+:1067300000F01382304606990A9A4B46CDF800A025 -+:10674000CDF8048010F042DF07E2B8F10B0F40F300 -+:10675000FE810A9B30460E99069ACDF80090CDF83E -+:1067600004A0CDF80880FEF73DFCD6F868319B798F -+:106770004BB1304606990A9A4B46CDF800A0CDF8A9 -+:10678000048010F023DF96F87232002B2ED19AF895 -+:106790000A3013F0010F29D030465146424617F017 -+:1067A00039D818BB069A937DD27D43EA0223C3F3FE -+:1067B000C7040E2C8CBF0023012363B10AF10C0027 -+:1067C000A8F10C010322FBF379F778B143786BB1A0 -+:1067D0008378A3420AD1336B18690CF0A7F9C0B2D1 -+:1067E000844203D1D6F868014EF0AAD80F9B0BB1B2 -+:1067F0001D4607E0304609F1100138F0D5DD0546A9 -+:10680000002846D0AA79002A43D10AF10C00A8F149 -+:106810000C01D5F8D842D5F8DC72FBF34FF7A2682B -+:1068200081460B2A08D1284606990A9A5346CDF884 -+:10683000008033F08BDE0DE0336893F831304BB1DC -+:106840000F2A07D1284606990A9A5346CDF80080A8 -+:1068500034F04CDAAB7CE3B197F85A30CBB1D6F8D0 -+:106860006801494601224EF013D930B197F85930EA -+:106870001BB9013387F859300BE0D6F86801494657 -+:1068800001224EF005D920B997F859300BB187F89D -+:1068900059000E9C002C00F06081DBF8D8329B6818 -+:1068A0000C2B40F05A815346584606990A9A23F019 -+:1068B00035DE5846002131F0FFDF336893F82F3082 -+:1068C00023B1D6F834072EF025DA46E1DBF8E432BE -+:1068D000584699780AF0A4FC3FE1B8F1010F40F363 -+:1068E0003681BBF1000F00F038819BF80630BAF812 -+:1068F00000505BBB3046139920F06EDB1398037E8B -+:1069000013F0020F14D002214EF09ADB139B1B7E72 -+:1069100013F0080F0CD130465946224609F10A03FC -+:1069200000950194CDF808A0CDF80C800AF0D8FAB3 -+:106930000E99002900F01181DBF8D8329B6813B161 -+:10694000584631F003DF58460321ADE013990B6937 -+:106950005B4540F00281304620F03EDB1398037E19 -+:1069600013F0020F10D012214EF06ADB3046594668 -+:10697000224609F10A0300950194CDF808A0CDF84C -+:106980000C800AF0ADFAAFE010214EF059DBE4E0E4 -+:10699000B8F1010F40F3DB80BBF1000F01D05F467F -+:1069A00004E0109A002A00F0D880174600252C46F3 -+:1069B0003319D3F84C1241B109F11000BC31062251 -+:1069C000FBF3BEF2002808BF01250434202CEFD1D0 -+:1069D000002D00F0C280139BBAF8004033B9304656 -+:1069E00009F10A01119A4EF0E3DE1390139911B1E7 -+:1069F000304620F0F1DABB791398002B57D10028EC -+:106A00003CD012214EF01CDB1398037E13F0010FD3 -+:106A100003D1436813F0005F30D001214EF010DB4A -+:106A2000A4F10D039BB2092B07D83368D3F88C204F -+:106A3000D2F8F8310133C2F8F83197F91030022B4F -+:106A400003D1F8680E2152F08DDD13990B7E13F0FF -+:106A500004020ED100944B683046C3F34073019397 -+:106A6000394609F10A03CDF808A0CDF80C8032F0C0 -+:106A7000B7DC139A536823F0005353600E9B002B2E -+:106A80006BD09BF81230002B67D0DBF8D82253680C -+:106A9000022B02D19368082B5FD8936813B1584634 -+:106AA00031F054DE5846022134F074DC55E0002801 -+:106AB00053D00169B94250D1D0F8F0301BB14368CE -+:106AC00023F400734360139B1B7E13F0010F44D02B -+:106AD0000022304609F10A0300940192CDF808A083 -+:106AE000CDF80C8032F07CDC304613994EF068DE35 -+:106AF00033E0B8F1030F2ADDBBF1000F2DD09BF876 -+:106B0000043053B39BF806303BB309F110000BF18E -+:106B1000BC010622FBF314F2F8B9139BD6F8340734 -+:106B2000019359464A465346CDF8008002950AF033 -+:106B300061FC12E00A99069C0291304613994A467C -+:106B40005346CDF80080019410F038DC05E033683E -+:106B5000D3F88C20136F013313670798059900222F -+:106B600000F0DED815B0BDE8F08FC0462DE9F04F3B -+:106B7000436899B0164689460493918B96F82A305B -+:106B8000126880460292D9F810A00BB9059302E072 -+:106B900096F82220059296F82C00B0B911F4006FF7 -+:106BA00013D0059A09EB4203B3F8AC20B6F87E3057 -+:106BB0009A420AD1D8F80030D3F88C20D2F8BC31F0 -+:106BC0000133C2F8BC3100F065BC9AF80630C1F35D -+:106BD000802B7BBBDAF8E442237A6BB160B9BBF15E -+:106BE000000F09D199F8D230726A134113F0010FE6 -+:106BF00002D1504610F088DBD8F800305B6BCBB187 -+:106C0000237EBBB196F82A30A3B196F828308BB119 -+:106C10000021504621F0BEDEDAF8CC3013F4005FDC -+:106C200008D0B38B13F4005204D1D8F84C0151466C -+:106C300048F0AAD9338C13F0040440F02B84B38BB2 -+:106C400003F4804373634BB9DAF8582040F23713EA -+:106C500002EA03032BB39AF8603013B3059BB463C5 -+:106C60000093404604994A4633464FF051DF08B13D -+:106C700022460EE0736B23B1D9F86C310133C9F8A9 -+:106C80006C31D8F8003093F89530002B00F0028476 -+:106C90000122736B33B1D9F868310133C9F8683117 -+:106CA00000E0002296F82C300BB1002708E005998F -+:106CB00009EB4103B6F87E10B3F8AC70A3F8AC1042 -+:106CC000D8F8000090F8953013B1002A40F0E28324 -+:106CD00096F82C50002D40F00081B6F87E20059BE0 -+:106CE00012F00F0C4FEA830E40F081800EEB090783 -+:106CF000F96E41B104982A4600F012D8FD66C7F833 -+:106D00008C50C7F83051BBF1000F00F0E68073697A -+:106D1000F168FB66D8F800307269DB6903919C6802 -+:106D20001169D368908ACB1892681B189B1A0918AE -+:106D30005B1AA34223DA0498214600F021D8F866B2 -+:106D4000002800F0A7837369006919699C689A8A12 -+:106D5000C4EB0104091BA218FBF30EF17169FA6E72 -+:106D600008698B68C01A13691B181361938A1B1A70 -+:106D700093828B8A049893822A46FFF3D1F7D8F83E -+:106D80000030D8F82828DB6903999B68AA489B1A29 -+:106D90005B1A063BC7F88C3071680822FBF3D0F011 -+:106DA00050B1A64871680622FBF3CAF048B973686F -+:106DB000DB88B3F5407F04D1D9F8043043F00803F1 -+:106DC00003E0D9F8043023F00803C9F804309C48E4 -+:106DD00071680822FBF3B4F0D9F8083010B943F019 -+:106DE000200301E023F02003C9F8083075E00EEB22 -+:106DF0000904E16E11B9D0F88C2017E022F00F02DF -+:106E000027F00F039A4204D107F00F0301339C458A -+:106E100010D02A460498FFF383F7D8F80030E566CF -+:106E2000D3F88C20C4F88C50C4F83051136E013361 -+:106E300013662FE3B068D4F88C309842E9D8049BED -+:106E400009EB0E020090019340468C3273680CF0FF -+:106E5000C7D8049871692A46FFF362F7BBF1000FA7 -+:106E60003BD1E36EC4F88CB07361C4F86CB0736945 -+:106E7000C4F830B11A69998A02F118037360A1F15C -+:106E80001803B36096F829303260F1602BB102F13B -+:106E90001E037360A1F11E03B36096F82A3043B15C -+:106EA0007368059902337360B36886F82210023B59 -+:106EB000B36032681378527843EA0223B383736B6A -+:106EC0005BB1B16B49B191F90E2073689B18736087 -+:106ED00091F90E20B3689B1AB360B36B73B11B7A40 -+:106EE000042B03D1404631464FF0C0DEB36B1B7A12 -+:106EF0000B2B03D1404631464FF0D4DFBBF1000FDE -+:106F000040F02283D8F8003093F89530002B73D0EE -+:106F1000DAF808309B7913F0010F40F0DA826BE069 -+:106F200010F4000F00F4E06310D01B0A043B012BA7 -+:106F3000444A00F07F0004D8142300FB0323DA68DE -+:106F400014E0142300FB03239A680FE01B0A043BA0 -+:106F5000012B3C4A00F07F0004D8142300FB0323DC -+:106F60005A6803E0142300FB03F39A584FF4FA73B2 -+:106F7000B2FBF3F007E000F07F034FF4FA7203FB7B -+:106F800002F3B3FBF2F0C0F307238DF825300DF1C7 -+:106F90001B05C0F307438DF824008DF82630012728 -+:106FA000030E316805F10F0018228DF827308DF897 -+:106FB0002970FAF3E1F796F82F30DBB19DF82B201A -+:106FC0009DF82A3005F1190443EA022343F40073C3 -+:106FD0008DF82A3021461B0A062205F11F008DF884 -+:106FE0002B30FAF3C9F7D8F86C122046BC310622D0 -+:106FF000FAF3C2F7BB4601E04FF0000BD8F80030BF -+:1070000093F8953013B91C461A4602E00DF11B04A3 -+:107010002D2273695B6A13F0400F15D013F0800FB7 -+:1070200000F038820092D8F83C01494632462346A7 -+:1070300029F00EDE88E2C046401E86002CD40100F6 -+:10704000481E86008418860031680DF15A07043105 -+:1070500006223846FAF390F7316815AD0A31062258 -+:107060002846FAF389F731680DF14E0420461031B5 -+:107070000622FAF381F796F829302BB1316812A86D -+:1070800018310622FAF378F7B38B13F4807F03F4F8 -+:10709000007305D1002B14BF23462B46776704E00D -+:1070A00074670BB9356701E012AB33677468BBF1E5 -+:1070B000000F00F0EE803368F3662378AA2B23D10B -+:1070C0006378AA2B20D1A378032B1DD1E378DBB9F9 -+:1070D0002379CBB9637943B9A379E179404641EA91 -+:1070E00003210BF0F1DB50B10EE0F82B0CD1A379AA -+:1070F000E179404641EA03210BF0E6DB20B1A279B9 -+:10710000E37943EA022500E03589D8F8003093F8A6 -+:107110009530D3B1DAF8E0305BB9736BABB9DAF81C -+:10712000582040F2371302EA030373B19AF8603033 -+:107130005BB1059A40460192494652463346009556 -+:107140000DF022DA002840F0A581B36B6BB11B7AF9 -+:10715000012B0AD0032B08D0404604994A463346F7 -+:1071600009F0DEFE002800F09581736F1B7813F0A4 -+:10717000010F08D0D8F80030D3F88C20D2F8D031E5 -+:107180000133C2F8D031B36B33B11B7A022B03D178 -+:10719000404631464FF06ADD726B22B996F82A30CC -+:1071A00023B3144602E0B36B93F90E4096F82A30ED -+:1071B0005BB1336802341A78597842EA012222F02E -+:1071C000800292B21A70120A5A707368581E03E055 -+:1071D00063421B5C00F8013971690A699042F7D279 -+:1071E0008B8A12191B1B0A618B82326096F82F3032 -+:1071F000BBB130684278037800F10A0443EA022305 -+:1072000043F4007303701B0A4370214606221030BA -+:10721000FAF3B2F6D8F86C122046BC310622FAF323 -+:10722000ABF69AF9103093B148F68E039D420ED119 -+:107230003168726BDAF80C001231003A18BF012283 -+:107240000AF1180351F0AEDE002840F02381716985 -+:107250000A698B8A9B18CA68D21A2C2A40F21A81B2 -+:1072600000238DF829308B8A08692D2218180DF11A -+:107270001B01FAF381F6716996F82220CB8A02F09D -+:10728000070223F007031A43CA8296F829200091C7 -+:10729000FAE0D6F814B02378DBF81070AA2BC7EB0D -+:1072A000040529D16378AA2B26D1A378032B23D1F7 -+:1072B000E3780BBB2379FBB9637943B9A379E1790F -+:1072C000404641EA03210BF0FFDA50B114E0F82BFD -+:1072D00012D1A379E179404641EA03210BF0F4DAB7 -+:1072E00050B17269A91F7B18CBF81030938A5B1AD2 -+:1072F00093821369F36628E0DAF8583013F0200F10 -+:107300000FD0204692490822FAF31AF648B972695A -+:10731000281D1169938A09181B1A11619382F1665D -+:1073200013E07269A5F10E00938A11691B1A93820A -+:1073300033890918116103F0FF021B0A43EA022393 -+:10734000F1660B73C3F30F234B73B36B6BB11B7AF3 -+:10735000012B0AD0032B08D0404604994A463346F5 -+:1073600009F0DEFD002800F09580B36B33B11B7A85 -+:10737000022B03D1404631464FF078DC0622716F74 -+:10738000F06EFAF3F9F5F06E06220630316FFAF37B -+:10739000F3F5716996F82220CB8A02F0070223F0F8 -+:1073A00007031A43736FCA821B7813F0010F08D0CA -+:1073B000D8F80030D3F88C20D2F8D0310133C2F89D -+:1073C000D0319AF8613093B199F8183013F0100F5A -+:1073D0000DD1F36E1A7B5B7B43EA022348F68E02E3 -+:1073E000934204D073695B6A13F0100F52D09AF87D -+:1073F0006530BBB199F8183013F0100F12D1F36E4D -+:107400001A7B5B7B43EA022248F6B4039A4209D016 -+:10741000263B9A4206D073695B6A002B02DB13F0AD -+:10742000100F37D09AF8063023B9DAF8E422013386 -+:1074300082F82A3098F83238013388F832389AF9CD -+:107440001030EBB1F16E0B7B4A7B42EA032248F627 -+:107450008E039A4214D10B8A03F0FF021B0A43EAFF -+:107460000223B2680C3A934214D8726BDAF80C001B -+:10747000003A18BF01220AF1180351F093DD48B910 -+:10748000736996F82920009340464946736F1FF0B0 -+:107490007BD959E0D8F80000436BA3B171692D4A3C -+:1074A000CB8AD0F8904003F00703D25C2A4B0498B3 -+:1074B0009B5C04EBC304636EA56E01336366FBF350 -+:1074C000A9F64019A066049871690022FFF328F418 -+:1074D0003AE0D8F8303005991A8940468DF81B20DB -+:1074E000130A120E8DF81C308DF81E200023B2698D -+:1074F0008DF81D30937DD27D43EA0223C3F3C70389 -+:107500008DF81F3009EB410393F8AC30D6F88010AA -+:1075100003F00F0301338DF828301CF03DDA029A96 -+:1075200040B2030E8DF82000911FD6F880008DF830 -+:1075300021308DF822308DF8233015F039FE10F00F -+:10754000006F7FF4EDAC16E519B0BDE8F08FC046D2 -+:10755000F7E38500C4D2850098E085002DE9F04F5F -+:107560000024A7B08DF832408DF83B408DF83840AC -+:107570008DF870408DF83F409A4609939B8A0546E6 -+:10758000212B02911746259412940D940A9224926D -+:107590001B9450D9DAF810901046494615F008FEB1 -+:1075A00009F1060203900492527899F8063043EAF2 -+:1075B0000223ADF82C30C3F38103ADF82E30BDF8B3 -+:1075C0002C30C3F3031203F44073B3F5407F14BFB0 -+:1075D000002301238DF83930BDF82E30ADF830206E -+:1075E000022B0ABFBDF830302346C3F3C0038DF829 -+:1075F0003A303B7903F00303022B08D1BDF92C305C -+:10760000002B04DABDF83030C3F3C00300E00023E0 -+:10761000D9B29DF839009DF83A308DF83B1000281A -+:107620000CBF2222282203B1023201B10432099B8D -+:107630009B8A934206D22B68D3F88C20536E013379 -+:107640005366A5E304990B7903F001038DF83C30F0 -+:1076500020B100231E468DF8403015E0BDF82C30D7 -+:1076600013F4807F01D0043105E013F4007F01D0D2 -+:107670000A3100E01031284637F02CDE031E18BF17 -+:10768000012306468DF840309DF83C303BB9049903 -+:107690002846043137F042DE08B1012400E000241E -+:1076A00095F8C83123B92B6893F82C3033B92FE003 -+:1076B00028463946099A00230EF0A2DB2B6893F87E -+:1076C0003F300BB98DF8403054BBBDF82C3013F46B -+:1076D000807F05D19DF83C3013B19DF840303BBB15 -+:1076E0009DF8393013B19DF83C300BBB2B6893F8F3 -+:1076F0002C30002B00F04C839DF84030002B00F024 -+:107700004783B379002B40F043834FF0010B11E026 -+:107710009DF83C301BB9002C00F03A8300E03CB1EE -+:107720009DF8393023B99DF84030002B00F03083AC -+:107730004FF0000B2B6893F895304BB346B39DF890 -+:107740003C30D6F8DC405BB914F0010F00F0208328 -+:10775000049806F1C20104300622FAF3F1F314E0B2 -+:1077600004980430FBF3E8F020B114F0080F00F0A7 -+:107770000F830DE014F0040F0AD114F0020F00F093 -+:107780000783284604990EF0A7DA002840F000830A -+:10779000099A136906331361938A063B9382049A0C -+:1077A00002F1180305939DF8393013B102F11E035D -+:1077B000059300238DF83D309DF83A306BB3059B5F -+:1077C0005A781B7843EA0221C1F3C0138DF83D308B -+:1077D0007BB126B196F81935002B40F0D98295F887 -+:1077E000CF31002B00F0D482099A536A43F0400352 -+:1077F0005362844B01F007028DF832209A5C824B71 -+:107800009B5C0D93C1F300138DF83830059B023358 -+:1078100005939DF832308DF870309DF83D3023B9D6 -+:10782000099A938A043B938206E002980999FBF334 -+:1078300069F1838A043B8382099A059C938A1269C1 -+:107840000793A41A1B1B514602980693FBF3E2F41C -+:107850000499001B08908B7DCA7D43EA0223ADF892 -+:107860008E30BBF1000F2ED1079B284600933A467D -+:1078700025AB10F03DDE002840F08A82BDF82C30A8 -+:1078800013F4407F3BD1BA7DFB7D049942EA032289 -+:10789000C2F3C70228460A310E2AD4BF00220122B1 -+:1078A0004EF0A0D8259030B92B68D3F88C20D36E39 -+:1078B0000133D3666CE20369D3F8CC30C3F3C01351 -+:1078C0008DF83F301BE0BDF82C3013F4407F16D00C -+:1078D0009DF839309BB9259B8BB9BA7DFB7D284635 -+:1078E00042EA0322C2F3C7020A310E2AD4BF0022A1 -+:1078F00001224EF077D82590002800F04982259B80 -+:107900001C69D4F8DC82BBF1000F23D19DF839301B -+:1079100003BB9DF83C3023B1BDF82C3013F4807FBD -+:1079200011D1A379BDF82C201BB112F4807F0AD0AD -+:1079300010E0A37C02F44072002B14BF4FF40073DC -+:1079400000239A4206D02B68D3F88C20936D013324 -+:1079500093651DE295F82D370AF1240A33B99DF895 -+:107960003F1019B9A3790BB10E4608E028463946F5 -+:107970001CF012D8C0B246B208B18AF80900A37947 -+:10798000FBB99DF83F30E3B9314620461CF046D89C -+:1079900020461BF09BDF3946284610F091D801465F -+:1079A00020460EF0F3DF9DF8403053B1A37C43B185 -+:1079B000E37933B198F805301BB92046012133F043 -+:1079C000E9DC95F82D3733B99DF83F301BB9259B7D -+:1079D000D3F8FC3073B16EB1259AD2F8F810D2F812 -+:1079E000F43043F82160D2F8F830013303F0070394 -+:1079F000C2F8F8309DF8393043B1B4F86200ADF800 -+:107A0000780040E0C4D2850098E08500A3792599EC -+:107A1000002B35D08A8FADF878204A6812F0400FDD -+:107A200020D09DF83A30EBB1049B9B7D13F00F0FF3 -+:107A300018D191F8DF30ABB18B7E13F0010F11D16B -+:107A4000BDF82C3013F4805F0CD012F4003F09D045 -+:107A50000D9A91F8D130134113F0010F02D028464E -+:107A60002DF034DFBDF82C30259913F4805F15BF5D -+:107A70004B684B6843F4003323F400334B6002E05F -+:107A8000898FADF8781095F82D371BB9259BD3F861 -+:107A9000FC3073B16EB1259AD2F8F810D2F8F430F8 -+:107AA00043F82160D2F8F830013303F00703C2F83D -+:107AB000F830259BD3F87C1159B1D1F808360398DA -+:107AC00001EB8302013303F03F03C2F80C06C1F857 -+:107AD0000836A3795BB9A37C4BB19DF83C3033B930 -+:107AE000BBF1000F03D188F806B088F807B09DF805 -+:107AF0003C30FBB1A379002B40F04A81A37C4BB111 -+:107B0000296804984E3110300622FAF319F2002841 -+:107B100000F03E8104980430FAF30EF750B92B6858 -+:107B200093F83E3033B9284604990EF0D5D8002892 -+:107B300040F02E81039ACAF814209DF83C308BB98E -+:107B400099F8022099F80130134399F800201A435C -+:107B500008D0BB7CFA7CD5F86001039943EA022285 -+:107B60004BF022DADAF8142012F0006F26D012F46B -+:107B7000000F02F4E06310D01B0A043B012B96486F -+:107B800002F07F0204D8142302FB0303DA6817E033 -+:107B9000142302FB03039A6812E01B0A043B012B27 -+:107BA0008D4802F07F0204D8142302FB03035A68B5 -+:107BB00006E0142302FB03F31A5801E002F07F02EF -+:107BC000864B1A6099F90330002B07DA2B68D3F83B -+:107BD0008C20D2F8D8320133C2F8D83299F8033069 -+:107BE00003F03003102B07D12B68D3F88C20D2F888 -+:107BF000E0320133C2F8E0329DF83C30002B40F017 -+:107C00009780DAF814102B6811F0006FD3F88C20ED -+:107C100026D011F4000F01F4E06310D01B0A043BDE -+:107C2000012B6D4801F07F0104D8142301FB0303ED -+:107C3000D96817E0142301FB0303996812E01B0ABB -+:107C4000043B012B644801F07F0104D8142301FB9D -+:107C50000303596806E0142301FB03F3195801E0FC -+:107C600001F07F0116293AD00CD80B2925D004D871 -+:107C7000022916D004291AD05AE00C2923D012293F -+:107C800027D055E030293CD004D818292DD02429FC -+:107C900031D04DE0602940D06C2944D0482936D0FD -+:107CA00046E0D2F870320133C2F8703240E0D2F8C8 -+:107CB00074320133C2F874323AE0D2F878320133C8 -+:107CC000C2F8783234E0D2F87C320133C2F87C3228 -+:107CD0002EE0D2F880320133C2F8803228E0D2F8A8 -+:107CE00084320133C2F8843222E0D2F88832013380 -+:107CF000C2F888321CE0D2F88C320133C2F88C32E0 -+:107D000016E0D2F890320133C2F8903210E0D2F887 -+:107D100094320133C2F894320AE0D2F89832013337 -+:107D2000C2F8983204E0D2F89C320133C2F89C3297 -+:107D300025994B6813F4802F0BD09DF83C3043B944 -+:107D4000BBF1000F05D1D5F8400104AA27F098DB5C -+:107D500003E0284604AAFEF709FF049B1B7C13F0EE -+:107D6000010F05D1259AD2F858310133C2F85831A4 -+:107D7000049B1B7C13F0010F05D0259AD2F85C31CF -+:107D80000133C2F85C31259B0398C3F864011FE0FE -+:107D90002868436BBBB19DF83C30A3B90999104AE0 -+:107DA000CB8AD0F8904003F00703D25C0D4B0298C9 -+:107DB0009B5C04EBC304636EA56E01336366FBF347 -+:107DC00029F24019A066029809990022FEF3A8F74B -+:107DD00027B0BDE8F08FC04684188600CC2702008B -+:107DE000C4D2850098E085002DE9F04FADF50F7DF8 -+:107DF000DDF860B28A46594617469946064637F07E -+:107E0000F9DAD0F8D412D0F8D822D0F8DC32D0F891 -+:107E1000E4428046089109920A930B94BBF1000F4B -+:107E200001D1D0F808B000238DF837328B9330465B -+:107E300051463A464B46FBF7CFF9041EC2F2338057 -+:107E400033685B7EEBB9326992F8EA305BB1D36E8E -+:107E5000D3F8202140F2044302EA0303B3F5806023 -+:107E600018BF012005E0106E07F0EEFC003818BFC7 -+:107E7000012030B1B068FBF767F94FF0FF3402F032 -+:107E800012B847B1B9F1030F05D98CA839460422BD -+:107E9000FAF372F001E000238C93BAF1A30F8C9DEA -+:107EA000F168706827D00DDCBAF11C0F07DCBAF15D -+:107EB0001B0F20DAAAF10203012B15D81BE0BAF13F -+:107EC000340F10E040F20B139A4514D005DCBAF1E0 -+:107ED000D60F10D0BAF1FB0F05E0BAF58B7F0AD0B0 -+:107EE00040F21B139A4506D0002F01F09587B9F197 -+:107EF000000F41F3918740F23B132A1E18BF012265 -+:107F00009A4501F2618701A454F82AF0098400001F -+:107F1000138400001D8400008F840000C99D0000B0 -+:107F2000C99D0000C99D0000C99D0000C99D0000B9 -+:107F3000E7840000F5840000C99D0000558500001D -+:107F4000C99D0000CF850000C99D0000C99D0000AB -+:107F5000C99D0000C99D0000DB850000E785000089 -+:107F60000786000023860000558600007986000001 -+:107F7000AB86000019870000979C0000899C0000D8 -+:107F8000D987000019880000D7890000E389000024 -+:107F9000438A00004F8A0000F38A0000FF8A000035 -+:107FA000158B0000218B0000638B0000C99D000031 -+:107FB000C99D0000C99D0000C99D0000858B00007F -+:107FC000418C0000478D0000FB8C0000C99D000023 -+:107FD000C99D0000538D0000958D0000C78D0000E5 -+:107FE000F38D00008F8E0000DD8E00002D8F0000CD -+:107FF000758F0000B38F0000BF8F0000979C0000BA -+:10800000F188000001890000418900007B8900009F -+:10801000C99D0000C99D0000C98F0000D58F0000D8 -+:10802000EB8F000019900000C7900000F79000004F -+:10803000C99D0000979C0000199200004592000025 -+:108040005D9200008D920000A3920000C99D000087 -+:108050006F8B00007B8B0000CD9900000384000033 -+:10806000E7920000F3920000C99D0000C99D000046 -+:10807000C99D0000C99D0000C99D0000979C00009B -+:10808000979C0000979C0000979C0000C99D0000F1 -+:10809000C99D000049930000C99D0000C99D0000D2 -+:1080A000C99D0000C99D0000C99D0000C99D000038 -+:1080B0007D90000089900000118500001D85000062 -+:1080C000BD970000CF9700007D97000087970000C4 -+:1080D000A789000093900000C99D0000C99D000081 -+:1080E000D793000057930000E5930000F993000038 -+:1080F0008794000087940000C99D0000C99D00007E -+:10810000239500004395000059950000C99D00008B -+:10811000C99D0000C99D0000C99D0000C99D0000C7 -+:10812000FD95000011960000979C00004596000008 -+:10813000C5950000C99D0000C99D0000B1960000D2 -+:10814000BF960000D39600000D9400001D9700001C -+:108150002797000031970000C99D0000C99D0000CD -+:10816000E79700001598000023980000C99D0000C3 -+:10817000C99D0000C99D0000C99D0000C99D000067 -+:10818000C99D0000C99D0000C99D0000B584000084 -+:10819000C1840000A98400006984000025960000C5 -+:1081A00031960000C99D0000C99D0000979C000009 -+:1081B000979C0000979C0000039900003D980000E8 -+:1081C000C99D0000C99D0000C99D0000C99D000017 -+:1081D000C99D0000F397000001980000DD960000A3 -+:1081E000C99D0000C99D0000578C0000C99D00007A -+:1081F000C99D0000C99D0000C99D0000C99D0000E7 -+:10820000C99D0000C99D0000C99D00005399000050 -+:108210005D990000979C0000979C0000C99D00009C -+:10822000C99D0000C99D0000C99D0000C99D0000B6 -+:1082300013940000C99D0000C99D0000C99D000065 -+:108240002799000045990000C99D0000C99D0000C4 -+:10825000C99D0000C99D0000979C0000979C0000EC -+:10826000EB990000F5990000C99D0000C99D000030 -+:10827000019A00007D9A0000879A0000978800000C -+:10828000A3880000979A0000AB9A0000199E000096 -+:10829000199E0000938A0000A18A0000C18A000094 -+:1082A000CF8A0000C99D0000C99D0000BD9A000052 -+:1082B000C99D0000C99D0000C59A0000ED9A00000C -+:1082C000C99D0000C99D0000C99D0000C99D000016 -+:1082D000C99D0000C99D0000C99D0000C99D000006 -+:1082E000C99D0000C99D0000C99D0000C99D0000F6 -+:1082F000C99D0000339B0000C99D0000C99D00007E -+:10830000C99D0000C99D0000C99D0000739C00002C -+:10831000C99D0000C99D0000C99D0000699A000028 -+:10832000739A0000FD830000FD830000C99D0000DA -+:10833000C99D0000C99D0000C99D00008D9B0000E3 -+:10834000C99D0000C99D0000C99D0000C99D000095 -+:10835000C99D0000B19B0000B19B0000C99D0000B9 -+:10836000C99D000065910000D1910000DD910000E1 -+:10837000E7910000F99100000B920000C99D0000F8 -+:10838000DB9B0000EB9B0000F99B0000C99D0000F7 -+:10839000C99D0000C99D0000C99D0000C99D000045 -+:1083A000C99D0000C99D0000C99D0000C99D000035 -+:1083B000C99D0000C99D0000C99D0000C99D000025 -+:1083C0004F9C0000619C0000279C0000C99D00009C -+:1083D000C99D0000C99D0000C99D0000C99D000005 -+:1083E000C99D0000C99D0000979C0000979C00005B -+:1083F0008D9D0000A19D0000B59D0000002101F0B1 -+:108400009EBB002401F0B9BAC14B00243B6001F0CF -+:108410004ABD012300243B6001F045BD33685B7E0B -+:10842000002B41F0F38486F89F3186F8A231304664 -+:1084300009F06AF830460EF04BDD30460EF036DEBD -+:108440003268137E002B41F0DF84136F13F0030FAB -+:1084500041F01D8513F0040F41F0D68413F0080F8E -+:1084600001F0DD8401F0D0BC33685D7E002D41F069 -+:10847000CD84012486F8A241304609F045F886F8FB -+:108480009F41304608F072FC2C4601F00CBD0123E0 -+:1084900086F89F3133685C7E002C41F0B584B0686B -+:1084A000FAF752FE01F0FFBC336800241B7E3B60EC -+:1084B00001F0F9BC96F8293000243B6001F0F3BCD0 -+:1084C00031680B7E002B41F0CB844C7E002C41F0B8 -+:1084D000DE8411463069079235F06AD9079A86F82A -+:1084E000292001F0E0BC3368002493F82C303B6075 -+:1084F00001F0D9BC336883F82C2096F82930002B82 -+:1085000001F0828430461BF0EBDA002401F0CBBC92 -+:1085100096F8C83100243B6001F0C5BC86F8C8213C -+:1085200086F8CB21304608F0EFFF96F82930002B73 -+:1085300001F06A8430461BF099DA30461BF0D0DA3D -+:10854000B0688C9907F0C4DD304620F0CBDF002402 -+:1085500001F0A9BC40461AF083D810F0006F2AD071 -+:1085600010F4000F00F4E06310D01B0A043B012B51 -+:10857000684900F07F0004D8142300FB0313DA6875 -+:1085800014E0142300FB03139A680FE01B0A043B5A -+:10859000012B604900F07F0004D8142300FB031373 -+:1085A0005A6803E0142300FB03F35A584FF4FA739C -+:1085B000B2FBF3F007E000F07F034FF4FA7203FB25 -+:1085C00002F3B3FBF2F00024386001F06CBC3368B6 -+:1085D00000245B683B6001F066BC98F81230002410 -+:1085E0003B6001F060BC98F8063013B1002D01F03B -+:1085F0002284D6F840252B1E18BF0123002482F8C0 -+:10860000343001F050BCB8F95E300BB1022004E008 -+:10861000B8F95C30181E18BF01200024386001F042 -+:1086200042BC022D0AD14FF000014FF0010200249C -+:10863000A8F85C10A8F85E2001F035BC2B1E18BF0E -+:108640000123A8F85C3000244FF00003A8F85E3046 -+:1086500001F029BCB8F80630002B01F0E983B9F12C -+:10866000050F41F3F483384608F1BC010622F9F303 -+:1086700083F4002401F017BC98F80440002C41F06A -+:10868000EF83B9F1050F41F3E28308F1BC003946ED -+:108690000622F9F371F496F82930002B01F0B48327 -+:1086A000404620F09DD901F0FEBBB9F1230F41F304 -+:1086B000CE83384600212422F9F3C2F498F80650FC -+:1086C0005DB198F8192008F11A0147F8042B3846D3 -+:1086D000F9F352F4002401F0E6BB98F80740381D86 -+:1086E00054B1089C237A04F109013B60227AF9F322 -+:1086F00043F42C4601F0D7BBD6F84025137A02F19B -+:1087000009013B60127AF9F337F401F0CCBBC046A3 -+:10871000776CE41484188600B9F1030F41F3978352 -+:108720003A68131D9945C1F29283202A03D96FF04C -+:10873000110401F062BB07F1040A3046514636F0DD -+:1087400011DE10B1404541F06A8398F806309BB1C4 -+:10875000404651463A6836F00FDA3046414636F028 -+:108760008FDB98F819303BB13046414636F03CDD9E -+:108770000446002841F0418398F80630002B41F070 -+:108780004383B9F1310F02D819461A4619E07A8DA0 -+:1087900022B1FB6A13B90125FA6200E000253046D8 -+:1087A00007F12C01A9F12C020AF034DC04460DB1CA -+:1087B0000023FB62002C41F0208307F12402A9F181 -+:1087C00024013B683046009201915246414631F007 -+:1087D000CFD8002401F067BB336B18690AF0A6F903 -+:1087E000C0B2386098F807301BB1089991F8323060 -+:1087F00003E0D6F8403593F832300024D6F868010B -+:108800007B60BC608379002B01F0FE824BF09CDF23 -+:10881000C0B2B86001F047BB0E2DCCBF4FF4805200 -+:108820004FF40052E02D03D96FF0120401F0E5BAC5 -+:1088300045F4306342EA03039DB2D6F85C01294651 -+:108840003DF0ACDD18B96FF0130401F0D6BAD6F8DC -+:10885000403532685D86137E002B01F0D58292F898 -+:108860003F40002C41F0D082336B18690AF05EF96A -+:10887000A84201F0C9822946304620F091DA3046FC -+:1088800008F0B0FF3046294620F0D0D8304619F025 -+:10889000B7DB01F008BB96F8683700243B6001F0B5 -+:1088A00002BB642D01F2BE8286F8685730699DF8DC -+:1088B000301235F021D833681B7E002B01F0A482E2 -+:1088C000D6F868319D79002D41F09E82304608F03F -+:1088D00089FF3046D6F85C410DF066D80146204647 -+:1088E0003CF042DF304619F08BDB2C4601F0DBBA5E -+:1088F000D6F86036002493F907303B6001F0D3BA14 -+:10890000304669B211F024D9041EC1F276828C9BE4 -+:10891000D6F86026D37133681B7E002B01F06B8282 -+:10892000304608F05FFF304611F054D93046D6F893 -+:10893000AC1614F005D8304619F062DB01F05BBAD2 -+:108940003368187E30B9D6F8603604469B793B60B0 -+:1089500001F0A9BA336B89A918690AF065FA0446CF -+:1089600028B19DF8243200243B6001F09CBAD6F86F -+:1089700060369B793B6001F096BA6B1C042B01F2C8 -+:108980005182B5F1FF3F01D103238C93D6F86036B5 -+:108990008C9A00249A71336B9DF8301218690AF092 -+:1089A00081FE01F080BA33681B7E002B01F0498202 -+:1089B000B1F8E8339AB24DF6AD639A4201F02F82D6 -+:1089C0004FF6FF739A4201F02A82C2F3401300244B -+:1089D0003B6001F068BAB6F83A3600243B6001F01B -+:1089E00062BA6B1EFE2B01F21D82A9B2A6F83A16DE -+:1089F0003069B6F83C2634F029DEB6F82032B6F8F5 -+:108A00003A2623F00F031343A6F82032B6F8223299 -+:108A1000304623F00F031343A6F82232B6F824326F -+:108A2000002423F00F031343A6F82432B6F82632AD -+:108A300023F00F031343A6F8263212F053D801F0A7 -+:108A400032BAB6F83C3600243B6001F02CBA6B1EFB -+:108A5000FE2B01F2E781AAB2B6F83A16A6F83C2638 -+:108A6000306934F0F3DD3146B1F82022B6F83C36F7 -+:108A700022F4706242EA0322A1F8202206F10803E0 -+:108A800002319942F0D1304612F02CD8002401F086 -+:108A90000ABA336B0024B3F806313B6001F003BA25 -+:108AA00096F82930002B01F0C9816B1EFE2B01F2D4 -+:108AB000B9813046A9B220F023D8002401F0F3B9DF -+:108AC000336B0024B3F808313B6001F0ECB996F841 -+:108AD0002930002B01F0B281A5F1FF03B3F5E06F5F -+:108AE00001F2A0813046A9B21FF0FEDF002401F0A0 -+:108AF000DAB996F95C3600243B6001F0D4B96B1CFE -+:108B0000012B02D9012D41F08D81002486F85C569D -+:108B100001F0C9B9336800241B6F3B6001F0C3B991 -+:108B20002A0C01F07F8122F00303002B41F07A81AF -+:108B3000A9B221F00303002B41F07481D04310EA65 -+:108B4000010441F06F813268136F00EA03030B43A5 -+:108B5000304613670EF0BCD930460EF0A7DA01F0AC -+:108B6000A2B9336B00241B893B6001F09CB998F8D3 -+:108B7000603000243B6001F096B9002488F8602042 -+:108B800001F091B9832D01F2508106EB8503B9F113 -+:108B9000A30FD3F8804241F35A8145AD2846002106 -+:108BA000A422F9F34DF2002C42D0E37947A82B60C0 -+:108BB000226904F114016A60F9F3DEF1237A61930A -+:108BC00096F8A0349BB9D8F8583013F0080F0ED19E -+:108BD000237A0B2B08D196F8F03743B196F8F1378A -+:108BE0002BB1A379072B02D8A379292B03D9629B38 -+:108BF00043F001036293638913F0020F03D0629B79 -+:108C000043F002036293638913F0200F03D0629B49 -+:108C100043F010036293638913F0100F03D0629B3B -+:108C200043F0200362936CA821460622F9F3A4F1D5 -+:108C3000384645A9A422F9F39FF1002401F033B985 -+:108C4000A549012330460097CDF804900293CDF852 -+:108C50000CB000F096BFB9F1070F41F3F880304631 -+:108C600036F08EDD80450BD08C9B032B01F2DD802E -+:108C700008EB83035B6F002B01F0D7809B798C930B -+:108C80008C9B832B01F2D18006EB8303D3F88042C7 -+:108C9000002C01F0CA802369002B01F0C680B8F8CF -+:108CA000623013F0010F08D02046F9F355F620B1D9 -+:108CB000B8F86C30D8F8680003E0B4F8B830D4F8ED -+:108CC000B4008DF818321B0A8DF81932030A8DF89A -+:108CD0001B32030C00248DF81A028DF81C3286A971 -+:108CE000030E082238468DF81D328DF81E428DF88D -+:108CF0001F42F9F341F101F0D6B8336893F83F30E1 -+:108D0000002B41F0B380D6F86801837923B10421A8 -+:108D100007924BF04DDC079A96F8723286F850278E -+:108D200086F85925002B41F06F80D6F85C011AB106 -+:108D300006F5AA610E3102E006F5AA610A313DF09E -+:108D400011DA01F057B896F8503700243B6001F073 -+:108D5000AAB80325304639464A4600230095CDF887 -+:108D600004800BF0BBD8044638B110F1190F01F0A4 -+:108D70004480C6F8245501F040B80223C6F82435D3 -+:108D800096F8F437C6F8285523F0010386F8F4372F -+:108D900001F089B8B9F10B0F41F23E803B680B2B13 -+:108DA000899341F239804B45C8BFCDF82492899B05 -+:108DB00030460C3B8993394689AAD6F8243510F001 -+:108DC000EDDB01F017B896F829303BB933681B6F1B -+:108DD00013F0040F01F0328001F016B898F8064045 -+:108DE000002C41F028803046414636F049D801F049 -+:108DF0005AB833681B7E002B01F02380B9F1050FB0 -+:108E000041F22580B9F10D0F0CD9304607F1080168 -+:108E1000A9F108020AF0FED83D460446002840F0B9 -+:108E2000EC870AE082AC204639460622F9F3A4F02A -+:108E3000002384934FF00E09254698F80640CCB9DC -+:108E40000A9AD2F8901039B1706892F89420FDF324 -+:108E50004FF70A9BC3F890400A9C494684F89490C7 -+:108E60007068FDF335F7C4F8900018B129464A46FA -+:108E7000F9F382F02946404632F028D90A9904468F -+:108E8000D1F89030002B40F0BF8700F0B4BF002332 -+:108E90000093304639464A468BABFAF7F5F904465B -+:108EA000002840F0AA878B99032900F0ED87326BE8 -+:108EB0001368994204D1D2F8F0303B6000F0F3BF60 -+:108EC0005368002B14BF38233C23F358D3F8F030F9 -+:108ED0003B6000F0E8BFC0467B7286000023009331 -+:108EE000304639464A468BABFAF7CEF9044600289D -+:108EF00040F083878C9A02F16403672B00F292871B -+:108F00008B99032904D0336B1B68994240F0CB87BF -+:108F1000002A04DB3046316B32F01CDA0246336B38 -+:108F2000C3F8FC20C3F8F02000F0BDBF002300937D -+:108F3000304639464A468BABFAF7A6F90446002874 -+:108F400040F05B878B99032900F09E87326B136892 -+:108F5000994204D1D2F8F4303B6000F0A4BF5368CA -+:108F6000002B14BF38233C23F358D3F8F4303B6074 -+:108F700000F099BF00230093304639464A468BAB38 -+:108F8000FAF782F90446002840F037878C9A642A61 -+:108F900000F27A878B99032904D0336B1B689942BE -+:108FA00040F08187336BC3F80021C3F8F42000F050 -+:108FB0007ABF0A9A0024D36A3B6000F074BF0A9B10 -+:108FC0000024DD6200F06FBF98F83A3000243B6067 -+:108FD00000F069BFBB49012330460097CDF80490EB -+:108FE0000293CDF80CB000F0CCBDD8F84C2006248C -+:108FF000531C03FB04F39945C0F2298747F8042B5F -+:10900000D8F84C20384602FB04F2D8F85410F8F394 -+:10901000B3F7002400F047BF3B68402B00F2028703 -+:10902000062403FB04F304339945C0F21087D8F8F3 -+:10903000541049B1D8F84C2002FB04F20432FDF37D -+:1090400057F60023C8F84C303968706801FB04F10A -+:109050000431FDF33DF6C8F8540018B96FF01A0456 -+:1090600000F0CBBE57F8042BC8F84C20394602FB61 -+:1090700004F2F8F381F7002400F015BFD8F850305F -+:1090800000243B6000F00FBF0024C8F8505000F0EF -+:109090000ABF98F807301BB1089C04F1380203E0BE -+:1090A000D6F8403503F1380211680B1D9945C0F21E -+:1090B000CE8647F8041B3846111D1268F8F35CF79A -+:1090C000002400F0F0BE78AC282200212046F8F3FE -+:1090D000B7F73046214614F0A9DC789A131D99455C -+:1090E000C0F2B58647F8042B211D3846F8F344F743 -+:1090F000002400F0D8BE3A68131D9945C0F2A78637 -+:10910000102A00F2AA8678AC002128222046F8F323 -+:1091100097F757F8042B201D39467892F8F32CF76F -+:10912000336893F8463013F0030F0ED098F80730E9 -+:1091300004F115001BB1089A02F14D0102E0D6F8C6 -+:1091400040154D311022F8F317F7304678A910F08A -+:109150008BDC0446002840F0508630460DF04AD89B -+:1091600000F0A1BE6DB100243046414623222346C3 -+:109170000094019402940394049413F0CFDC00F063 -+:1091800092BE98F806303BB9D6F8680104214BF03E -+:109190000FDA40462FF0DADAD6F878122B467068EC -+:1091A000043101220095F9F34DF698F8063043B9E1 -+:1091B000404601212A462B4602F0ACFF2C4600F027 -+:1091C00072BE3046414635F05BDE2C4600F06BBE89 -+:1091D000D6F84C3500243B6000F065BE0024C6F88C -+:1091E0004C5500F060BE384606F5AA610622F8F339 -+:1091F000C3F6002400F057BE06F5AA6039460622E1 -+:10920000F8F3BAF6002400F04EBE304641460AF0AC -+:1092100089DF002400F047BE98F8060058B998F896 -+:10922000123043B198F807302BB1089CE38D044607 -+:109230003B6000F038BED6F840350024DB8D3B6043 -+:1092400000F031BE6A1E4FF6FE739A4200F2EA85C4 -+:10925000D6F840350024DD8500F025BE98F80600DC -+:1092600060B998F812304BB198F8073033B10899CB -+:10927000044691F860303B6000F015BED6F84035EA -+:10928000002493F860303B6000F00DBE6B1EFE2B97 -+:1092900000F2C885D6F84035002483F8605000F00D -+:1092A00002BE3A6845F2AB539A420FD106490023F9 -+:1092B00030463B600097CDF804900293CDF80CB097 -+:1092C0000DE0C046AB728600DD7286000023A04927 -+:1092D0000097CDF804900293CDF80CB030463A4692 -+:1092E0004B4600F050BC0B9A002413783B6000F012 -+:1092F000DABD022D00F293850B9B1D7033681B7E37 -+:109300004BB140460DF062DCD8F8E4325B8B13B110 -+:1093100040461BF043D90B9C637E0BB18C9B33B949 -+:109320008C994046003918BF012107F079FF40466B -+:109330001CF05CDB0146404622F000DC404631F088 -+:10934000B7DF002400F0AFBD304639464A46FAF791 -+:1093500079F800F04FBD316891F830300F7E1BB1C5 -+:1093600015B96FF0190400E0002491F8953013B19D -+:10937000002D40F08F85002C40F03F8591F82F3074 -+:10938000934200F0908527B1B0680792F9F7DCFEB0 -+:10939000079A3368304683F82F20414636F0F8D9D3 -+:1093A000326892F8443023B192F82F300BB182F832 -+:1093B0004440304612F004DD002386F8DD3186F8A3 -+:1093C000DE311FB1B068F9F7D7FE0446304608F029 -+:1093D0009BF800F010BD3368002493F82F303B60F9 -+:1093E00000F061BD5B49002230460097CDF8049043 -+:1093F0000292CDF80CB0C5E35649012330460097E0 -+:10940000CDF804900293CDF80CB0BAE304238C930A -+:1094100004E0B9F10B0F40F31A85043798F80630D1 -+:10942000002B30D13B78304613F0010F39463D46D2 -+:1094300018BF08F1BC054CF0B1D9044628B1436807 -+:1094400013F4805F01D04BF02FDF98F81230002B1F -+:1094500000F0DA84002140460A460B4602F05AFE2C -+:1094600054B1BDF830323046019329462A4608F1FE -+:10947000C20300941EF086DD3046414635F000DD23 -+:10948000002400F010BDAAF179033846DDF83092CF -+:10949000012B8CBF01251025F9F34EF2BAF1790F9B -+:1094A00014BF4FF0000B4FF0010B044638B3D6F851 -+:1094B00000058AA94BF00EDE19E0D2F8F030B3B9FE -+:1094C0001369434513D1102D03D1137E13F0020FFE -+:1094D00004E0012D03D1137E13F0010F07D03046B5 -+:1094E00041465B460095CDF804904BF00BDF8AA80F -+:1094F0004BF0F8DD02460028DFD100F085BC304695 -+:1095000039464CF04BD90246002800F07D843046A5 -+:1095100041465B460095CDF804904BF0F3DE00F039 -+:10952000C2BC98F8070028B1089900240B8E3B6054 -+:1095300000F0B9BCD6F8403504461B8E3B6000F005 -+:10954000B2BCD6F8403500241D8600F0ACBCC04645 -+:10955000E3728600E8728600002F00F05D84B9F1A6 -+:109560000C0F1FD13B79391D13F0010440F05484D6 -+:1095700030464CF013D938B1012386F82D374BF023 -+:10958000A3DE386000F08FBC98F8060018B16FF0C9 -+:109590001D0400F032BCD8F8E03204461B693B6081 -+:1095A00000F081BCB9F1040F40F0368498F8060051 -+:1095B000002840F03184D8F8E03204461B693B6053 -+:1095C00000F071BC304620F0B9D93368D3F88C0074 -+:1095D000036C3B60836C7B60D0F8D831BB60D0F803 -+:1095E000B03102699B18B9F1130FFB6040F30C8492 -+:1095F000D0F83C3100243B6100F055BC9D4900226D -+:1096000030460097CDF804900292CDF80CB0B9E244 -+:109610009849012330460097CDF804900293CDF885 -+:109620000CB0AEE2B8F8623000243B6000F03BBC06 -+:109630009149012330460097CDF804900293CDF86C -+:109640000CB09EE2832D40F30284336B3D1D1869FC -+:1096500009F0FCFB089A4FF0000982F861008C9B2E -+:109660003046043B08992A46CDF8009009F0EEDD1B -+:10967000AB6F84333B6098F80630002B00F0C48356 -+:1096800007F11704204649462022F8F3D9F498F848 -+:1096900019202046AA7408F11A01F8F36DF407F1B5 -+:1096A0000C0008F1BC010622F8F366F44C46FAE31C -+:1096B00001233B60336B00241B687B60F3E396F867 -+:1096C0009C310BB9184601E0336B186800243860F0 -+:1096D000E9E33046294612F053DC8BE3B9F1020F7F -+:1096E00040F3B583336B188968B1022801D1653026 -+:1096F0000FE0052801D167300BE0042801D16A3062 -+:1097000007E0072801D1613003E0082814BF3F209B -+:10971000632000231C4638707B70C4E396F8433600 -+:1097200000243B60BFE396F9473600243B60BAE370 -+:109730006B1C012B02D9012D40F07483EAB2316811 -+:1097400086F84726087E48B191F83F40002C40F04B -+:109750005B833046214620F0A9DDA4E351B2B1F18C -+:10976000FF3F03D1044686F843069CE3012914BF5A -+:1097700000230123044686F8433694E396F84836DE -+:1097800000243B608FE396F84836934200F03C8318 -+:10979000336886F8482693F82F30002B00F0348386 -+:1097A00096F82930002B00F02F83304621F0AEDBF5 -+:1097B0003046012121F0B4DD002474E3306B0368EE -+:1097C000022B40F02183437D00243B606BE3336830 -+:1097D00093F83F30002B40F049833046E9B2012234 -+:1097E0001FF0B4D906E3D6F8583600241B783B6046 -+:1097F00059E3D6F85836002493F903303B6052E31E -+:10980000022D00F20F83304604216AB21CF0B0D85A -+:10981000002448E3D6F85836002493F901303B6021 -+:1098200041E36B1C012B02D9012D40F0FB82304635 -+:1098300002216AB21CF09CD8002434E3B9F1270F4E -+:1098400040F30583282278A83946F8F395F3789CED -+:10985000102C00F20883336B5B7D002B00F0FA8242 -+:1098600064B906F5AE600C3021462822F8F3E8F31F -+:1098700019E3C046177386001C73860033686EAC0C -+:1098800093F84630214613F0030317BFD8F8CC30C5 -+:109890001846C3F3003383F0010000227F230093B6 -+:1098A0000190134678A847F027DCD6F860360022EE -+:1098B0009B782046AC4947F061DB789A6E9B9A42D0 -+:1098C00040F0D18206F5AE6028220C302146F8F334 -+:1098D00053F33268137E002B00F0968292F82F30FB -+:1098E000002B00F0918292F83F30002B00F08C8228 -+:1098F000304621F00BDB3046012121F011DD002440 -+:10990000D1E2336B5B7D002B00F0A482B9F1270F0D -+:1099100040F39D8206F5AE6138460C312822F8F3FB -+:109920002BF30024BFE225B1022D02D0012D40F01F -+:109930009182D8F8E832404683F8E05030F046DFB4 -+:109940000024B0E2D8F8E832002493F8E0303B601D -+:10995000A9E2B6F87A3500243B60A4E23368187EA9 -+:10996000002840F07D824FF6FE739D4200F25A823D -+:109970000446A6F87A5596E201344C4502DAE35DD6 -+:10998000002BF9D1032C00F3688288AD002104225A -+:109990002846F8F355F3224639462846F8F308F4EA -+:1099A000D6F85C0129463CF0DDDB0446002840F097 -+:1099B000248230460DF07ADB06F5AA600A3029468B -+:1099C0000322F8F3F5F386F859456CE2B9F1030F79 -+:1099D00040F33D82D6F85C013BF05EDE0422014696 -+:1099E0003846F8F3C9F200245DE2D6F80C350024BD -+:1099F0003B6058E233681B7E002B00F0228229E294 -+:109A0000B9F1030F40F32382A9F1040399083B68DD -+:109A10008B4288BF396000252C460E2C8CBF4FF43A -+:109A200080514FF4005144F430631943D6F85C017F -+:109A300089B23CF0B3DC10B10DAB5C55013501349B -+:109A4000E02CEAD13B68AB4201D3002107E03D6046 -+:109A5000FDE10DAA8A5C07EB81035A600131A9423E -+:109A6000F7D100243D601EE2304639463BF064DF0A -+:109A7000C0E13046394608F0DDFCBBE196F8CE3156 -+:109A800000243B600FE286F8CE21304600210AF028 -+:109A90005FDF002407E23368114683F84120336B0F -+:109AA0000024186909F0A6F9FDE13368002493F851 -+:109AB0004130003B18BF01233B60F4E133680024D0 -+:109AC0003B60F0E1D8F87030B3F1FF3F00F0AD81BA -+:109AD00008EB8303586F002800F0A781C3790024A6 -+:109AE000AB4214BF002301233B60DCE140466FF032 -+:109AF00007040025416FB9B1CA798C9B9A4213D1F2 -+:109B0000D8F87030B3F1FF3F07D008EB83035A6FEA -+:109B10001AB1538923F0020353814B89C8F870505E -+:109B200043F002034B81002401350430042DE1D1C0 -+:109B300061E1B9F1090F40F38A8185E101314945BD -+:109B400000F08581CB5D002BF8D1A6E100230293C4 -+:109B5000304639463A19C4EB09030097CDF8049012 -+:109B6000CDF80CB00FE0C0460C1886003B19C4EBD2 -+:109B700009020093012301920293CDF80CB0304604 -+:109B800039460022134619F00BDC33E198F8063011 -+:109B9000002B40F0598198F81130002B00F05481CF -+:109BA000D8F80C00394698F8072013F0B9FB21E1EA -+:109BB00019F0010440F0308101230293AD49AE4B0E -+:109BC00040F21312924518BF1946304622460097BC -+:109BD000CDF80490CDF80CB0D4E73846B16B4FF413 -+:109BE0008672F8F3C9F100245DE138460899AC2289 -+:109BF000F8F3C2F1002456E1099C099AA36B516B5A -+:109C000047F8043B926B3846F8F3B6F1099B099C80 -+:109C10009A6B5B6CB818BB50216C626C0430F8F323 -+:109C2000ABF100243FE1336893F83F30002B00F0A4 -+:109C3000FF800899002900F0FB80496E002900F0A0 -+:109C4000F78038460822F8F397F100242BE1089AB0 -+:109C5000384602F16B011022F8F38EF1002422E164 -+:109C6000089B384603F17B011022F8F385F10024AC -+:109C700019E133681B7E002B00F0E3803046394643 -+:109C80004A460AF065DFB5E033680121186901F042 -+:109C90000DDB002407E1304651464A463B46F9F7C2 -+:109CA00017FB0446002840F0A880BAF13C0F49D1C8 -+:109CB0003D1D00F0AE807B6813F0006F40F0A9807E -+:109CC00003F07F03022B06D0042B04D00B2B02D011 -+:109CD000162B40F09E806EAC3046214613F0A6DE77 -+:109CE000304621461CF01ED8286810F0006F26D0A0 -+:109CF00010F4000F00F4E06310D01B0A043B012BAA -+:109D00005E4900F07F0204D8142302FB0313D868D5 -+:109D100017E0142302FB0313986812E01B0A043BAC -+:109D2000012B564900F07F0204D8142302FB0313D1 -+:109D3000586806E0142302FB03F3585801E000F0D2 -+:109D40007F002860336B514618698CAB0733009352 -+:109D50004A463B460AF0B4F9BAF13C0F044608D033 -+:109D6000BAF15C0F05D0BAF14A0F02D0BAF15D0F1B -+:109D700041D1002C41D1002F00F095803B68326822 -+:109D8000003B18BF012382F840308CE03C490022A0 -+:109D900030460097CDF804900292CDF80CB0F1E671 -+:109DA0003749012330460097CDF804900293CDF84F -+:109DB0000CB0E6E63349012330460097CDF8049015 -+:109DC0000293CDF80CB0DCE6D6F8680151463A466D -+:109DD0004B46CDF800B04AF0C9DC10F1170F04462D -+:109DE00009D1D6F8340751463A464B46CDF800B073 -+:109DF00029F030D90446002C55D004F12A032A2B2F -+:109E000002D83368DC664EE000244CE06FF00804B2 -+:109E100049E06FF0010446E06FF00104EDE74FF018 -+:109E2000FF34EAE76FF01C04E7E76FF00704E4E7AC -+:109E30006FF01004E1E76FF00604DEE76FF00A044C -+:109E4000DBE76FF00304D8E76FF01604D5E76FF097 -+:109E50000D04D2E76FF00C04CFE76FF00E04CCE7EF -+:109E60006FF00404C9E76FF00B04C6E76FF01B0442 -+:109E7000C3E7C0467ED701002F7386008418860092 -+:109E8000507386005D7386006FF00204B5E76FF0D3 -+:109E90000804B2E76FF01904AFE74C1CBAF5837FF2 -+:109EA0003FF454AE62E620460DF50F7DBDE8F08F1D -+:109EB0002DE9F341089C05460E4617469846009446 -+:109EC00007F0A6FD10F1170F06D1284631463A4695 -+:109ED00043460094FDF788FFBDE8FC812DE9F04181 -+:109EE0000368054693F83F30D0F80C8013B1B0F802 -+:109EF000267602E0FAF70CFF074600222869394669 -+:109F000003F0E2F85621286933F08ADBD5F888316E -+:109F10004000002BC5F8040506DA2869B22133F0A9 -+:109F20007FDB4000C5F80805A221286933F078DB03 -+:109F30004000C5F8EC07284612F03AD895F8CD3124 -+:109F40003BB928694C2133F06BDBC0F3C71085F8AF -+:109F5000CD0128461CF092DDD5F84C0104F02EFD11 -+:109F600028463DF05FDA002605EB8603D3F84C4225 -+:109F70002CB120461EF03EDF20461EF031DD0136BA -+:109F8000082EF1D12B6893F83F309BB1002205EBEE -+:109F90008203D3F84C0250B1037943B1D0F8D432E4 -+:109FA000DB8D1B04C8F888311FF05CD902E0013258 -+:109FB000082AECD12846394609F0AAD82846742147 -+:109FC000B5F87A2522F006D995F8D13142F210720F -+:109FD000002B18BF4FF4BC622846822122F0FAD829 -+:109FE0002B6B95F8D111186909F04AF80122134634 -+:109FF000B5F8781728460AF063DA0123B5F87A171E -+:10A00000002228460AF05CDAD5F8400125F0D8DBBA -+:10A010002846F9F7E9FA2B685B6B5BB1B8F888362C -+:10A02000D5F86C029BB243F00403A8F888360021EF -+:10A0300017F0B6DE2846F9F77BFAD5F8841161B936 -+:10A0400028461CF08DD80404C5F884412846022116 -+:10A050001CF086D82043C5F884012B6893F8A13002 -+:10A06000012B03D1D5F8400126F096DC284617F0E5 -+:10A07000C7DF284608F0B6DBB5F85C1728461CF0A9 -+:10A080004DDD284610F004DA424BEA68002185F8DD -+:10A090004410C2F8DC33012385F8A83185F8AA31D1 -+:10A0A0002B6893F838303BB14A1901314FF0FF3338 -+:10A0B000082982F89538F7D100244FF440763146CC -+:10A0C00028461CF04DD805EB4401B1F8203213F0BE -+:10A0D0000F0F06D123F00F0300F00F021343A1F876 -+:10A0E0002032B1F8202212F0F00F06D100F0F00378 -+:10A0F00022F0F0021343A1F82032B1F8202212F42A -+:10A10000706F06D100F4706322F470621343A1F8FB -+:10A110002032B1F820321A0B06D11B0500F4704230 -+:10A120001B0D1A43A1F8202201340236042CC6D19B -+:10A130002B68284693F94C100BF076DA2A68137EC8 -+:10A1400003B392F82F30EBB1002605EB8603D3F86A -+:10A150004C426CB1A3795BB12B6893F838302BB1CA -+:10A160002846D4F84C15002235F0F2DD0023E371C7 -+:10A170000136082EE9D1002385F87232D5F834076C -+:10A180002AF0C8DDD5F8680104214AF011DABDE8EB -+:10A19000F081C0468096980003681A6819B10123BF -+:10A1A00082F8AA3001E082F8AA1070472DE9F04742 -+:10A1B0001746937AD27A056843EA022A3B79064623 -+:10A1C00003F007044FF0000938E00B6968681A785B -+:10A1D0005B7842EA0328D6F87822936E01339366BF -+:10A1E0000122FCF39DF52B6893F8A130012B03D0DD -+:10A1F000C8F34123032B17E0182304FB0362B2F8D2 -+:10A200008232B2F88612284699420CBFB2F88032E8 -+:10A210004B1CA2F886322146012220F0E5DB09F131 -+:10A2200001031FFA83F9D1450AD02B69022103EB00 -+:10A230008403D868124B9B6B984701460029C4D110 -+:10A240002B6893F8A130012B05D02846214696F9BA -+:10A250002C2020F0C9DBBB7913F0020F0ED00024B4 -+:10A2600006E00120FCF378F2631CDCB20B2C05D075 -+:10A27000EB68D3F8703113F0010FF2D0BDE8F0872E -+:10A28000E0A685002DE9F347D0F80090044601A927 -+:10A29000D9F800054AF01EDF00263AE07B6813F487 -+:10A2A000802F36D063684FF00008FD58AA46D5F8D5 -+:10A2B000F8205FFA88FE32B391781379002918BF2D -+:10A2C00001261BB100231371D3701CE0D9B1D378E0 -+:10A2D0000133D9B2D1707B6813F4807F14BF628ED2 -+:10A2E000A28E6423B2FBF3F291420BD3D4F878220E -+:10A2F0004846D2F8C43051460133C2F8C4307246E1 -+:10A3000023F030DF012608F101080435B8F1080F09 -+:10A31000CDD101A84AF0E6DE07460028BED136B905 -+:10A32000236884F8A3639868A16B05F097D9BDE80A -+:10A33000FC87C0464368F7B5CE5805460027FCB2F7 -+:10A3400028463146224622F0DBD901370123284630 -+:10A350003146224622F040D9082FF0D12A68002346 -+:10A360000093506806F110010122F8F36BF5FEBD71 -+:10A37000D0F8AC037047C046D0F8C0037047C04661 -+:10A38000C0F8C0137047C046D0F8AC331B68DB6917 -+:10A3900018690528A8BF05207047C0462DE9F04F71 -+:10A3A000F3B00890894608999DF8F8010792D1F812 -+:10A3B000B0231C46D9F8D4320690D1F8AC730C9275 -+:10A3C000002148A828226F9115937C9DDDF8F48127 -+:10A3D000F7F336F607980C99037803F0FC03202B6B -+:10A3E00014BF002301230D9391F82F3033B1D7F818 -+:10A3F0006801837913B104214AF0DAD80D9A0AB1C1 -+:10A40000092D00E0032D40F2E58522786378211DB7 -+:10A4100042EA032AA278E37842EA03230E930D9BD3 -+:10A4200023B9043D8B4613950F9304E00A3D04F1D4 -+:10A430000A0B13950F911398012840F2CB859BF8D6 -+:10A44000013002339842C0F2C58548AB00933846CC -+:10A450005946139A002319F059DE002840F045832D -+:10A4600097F838279DF834319A4240F03E8399F8A6 -+:10A4700019309BF801209A4240F03E8309F11A00FE -+:10A480000BF10201F7F35CF5002840F0358398F8F2 -+:10A49000183013F0020F0BD098F8DF3023B1384694 -+:10A4A000414601222BF0CEDC4046FE214AF0C8DDB9 -+:10A4B00099F94820002AC0F21F8398F8183013F049 -+:10A4C000010F00F01983082392FBF3F34344197D35 -+:10A4D000A44B02EA0303002B05DA013B6FEA437346 -+:10A4E0006FEA5373013351FA03F313F0010F00F0D5 -+:10A4F000038319A80021C8F81090A8F800A101381A -+:10A500006D22F7F39DF50024214613E072AA53183B -+:10A5100013F8A43C03F07F026C2A0AD89248835CAB -+:10A520003BB119AB013B9A54835634EA230428BF4C -+:10A5300001240131489B9942E8D3D8F8043023F034 -+:10A5400007023B6BC8F804205B7D23B11CB942F0C5 -+:10A550000103C8F804303B6B5B7D43B11AF4806F94 -+:10A5600005D1D8F8043043F00203C8F804301AF0DB -+:10A57000200405D0D8F8043043F00403C8F80430B0 -+:10A58000159B0021986B0FE0159A531893F83C2007 -+:10A5900012F0800F07D019AB013B02F07F029B5CE9 -+:10A5A000002B00F0A28201318142EDD10C9890F88D -+:10A5B000463013F0030F45D05946139A38461BF026 -+:10A5C0009BDD00260546414638462A46334600961E -+:10A5D00018F00CDBB5B14DA8E91C01301022F7F3DF -+:10A5E000CBF431467B1872A893F8EB24431813F888 -+:10A5F000933C02EA0303934240F077820131102931 -+:10A60000F0D105E00C9991F84730002B40F06D82B5 -+:10A6100038465946139A43461BF0D8D83B22584631 -+:10A620001399F8F34BF0024660B141784B1EDBB250 -+:10A630001E2B07D888F80B1108F58670911C5278EC -+:10A64000F7F39AF4B9F862200023A8F83C20C8F880 -+:10A650004030B9F8623033B1D9F8582040F237139E -+:10A6600002EA030343B9D9F8583013F0400003D18C -+:10A670000646119016905EE0139B58461946CDF899 -+:10A68000C0B16E9326F02EDD119038B14378042BC3 -+:10A6900040F239820020064616904CE070986E9980 -+:10A6A000F8F318F6119050B108F1400300930898A0 -+:10A6B0004946119A08F13C0327F092DD10E0584614 -+:10A6C00013993022F7F3FAF770B1119008F14003B3 -+:10A6D000009308984946119A08F13C0327F08CDC56 -+:10A6E000002840F0108223E0584613994422F7F3E3 -+:10A6F000E5F7119080B108F14003009308984946AE -+:10A70000119A08F13C0327F0D7DB002840F0FB81C9 -+:10A7100001210E4616910EE0D9F8583013F0410F82 -+:10A7200000F0F181119A1646A8F83C20169202E03A -+:10A73000002301261693D8F8043023F4001323F0E5 -+:10A740004003C8F804303B685B6B002B3AD0D9F863 -+:10A75000CC3013F0020F35D11398CDF8C0B16E9004 -+:10A760000BE0C04607000080401B860038462946A3 -+:10A7700070AA6EAB18F0F2DE38B970986E99DD22CF -+:10A78000F7F39CF705460028F0D1404600211BF066 -+:10A79000ADD9BDB1D8F8043043F04003C8F8043057 -+:10A7A00097F8FA3173B14046297A1BF09FD998F88F -+:10A7B000D13013F00F0F05D0D8F8043043F4001354 -+:10A7C000C8F8043000231399304A5846009317F014 -+:10A7D00099DD4146024638461AF0D2DF1AF01005DC -+:10A7E0000DD0D9F8582040F2371302EA030333B9E9 -+:10A7F00012F0400F00F08D81002E40F08A810C99FC -+:10A8000091F8303053B93B6B1B68022B06D197F996 -+:10A810005C361BB914B94FF0130A24E03B6B1B687C -+:10A82000022B08D1089A53782BB11AF4806402D114 -+:10A830004FF0190A17E0384611F074DB0899D1F887 -+:10A84000C033984211D303230093079B002403F1E4 -+:10A850000A0238461721012301940294039419F047 -+:10A8600027D94FF0110A10945AE10C9890F838301B -+:10A8700073B13846494612F079D8D9F85035984224 -+:10A8800006D300214FF0110A109149E148D401008C -+:10A890000C9A92F8463013F0030F27D0D9F85820BD -+:10A8A00040F2371302EA030303B397F8692712F063 -+:10A8B000020F08D0D8F8043013F4803F03D0D8F842 -+:10A8C0004030022B0BD012F0010F0FD0D8F804301B -+:10A8D00013F4803F0AD0D8F84030012B06D1002273 -+:10A8E000384641461346009218F080D9D9F8CC304A -+:10A8F00013F4005F09D0D7F84C0141465A46139B28 -+:10A9000003F0D8FE002840F00481D8F8043013F09A -+:10A91000010F02D0012387F84D36D8F8043013F028 -+:10A92000011F02D1012387F84E36D8F8043013F402 -+:10A93000801F02D0012387F85136D8F8043013F471 -+:10A94000002F09D11598438E03F44063B3F5406F8F -+:10A9500002D1012387F85236D8F8043013F0020FE1 -+:10A9600002D0012387F84F36D8F8043013F0040FD3 -+:10A9700002D1012387F85036D8F8043013F4001FB1 -+:10A9800002D0012387F8FB31D7F8344720462AF05C -+:10A9900091D930B120462AF095D910B120462AF03D -+:10A9A00063D9D8F8043013F0007F1DD0012487F854 -+:10A9B00054460C9991F8463013F0030F14D091F9D6 -+:10A9C0004C308BB10221384618F0CAD8159A538EF4 -+:10A9D00003F44063B3F5406F06D138462AF002D83D -+:10A9E0003846214629F07ADFD8F8043003F40413FE -+:10A9F000B3F5001F02D1012387F853363B6B5B7D13 -+:10AA000013B1384620F0E8DA0C9890F8463013F08D -+:10AA1000030F02D0384620F091DBD8F8403043B91C -+:10AA20003DB1D9F8583013F0010F02D00123C8F816 -+:10AA300040300C99D9F8582091F838301BB9D7F824 -+:10AA40006C32994524D0B9F8620008BB12F0010FAE -+:10AA50001ED0D9F87030B3F1FF3F19D009EB830352 -+:10AA60005C6FACB1217A012901D0032910D1628930 -+:10AA7000E379009204F11402029208F11A020191A2 -+:10AA80000490059003923846494622693CF0F6DC72 -+:10AA9000B8F8D4302BB9D8F8100034F081DDA8F81C -+:10AAA000D400B8F8D4200C98109290F8463013F0E7 -+:10AAB000030F33D0D8F84030013B012B0AD8D8F827 -+:10AAC000043013F4802F05D038464146062220F08A -+:10AAD000E7D823E0D8F8043013F4802F1ED038468E -+:10AAE0004146062220F080D818E000214FF0120ADB -+:10AAF00011911091169113E000224FF00C0A11925F -+:10AB0000109216920CE000234FF00C0A169310934B -+:10AB100006E000204FF00C0A109001E04FF0000A10 -+:10AB20003EAC00212822204634ADF7F389F22846B6 -+:10AB300000212822F7F384F2D7F87C3533B107F5EA -+:10AB4000AE6120460C312822F7F316F21599234600 -+:10AB50003831099138464946099A00951BF076D953 -+:10AB60003E9B03F10804349B0BB10233E418D8F880 -+:10AB700004304846002BB8BF14340421002235F0BD -+:10AB800091DA97F8653604190BB10233E418D8F856 -+:10AB900004300DF5A57013F0400F18BF1A340021D2 -+:10ABA0002022F7F34DF2D8F8043013F4803F05D09B -+:10ABB000D7F8FC3434341B7803B11334D8F8083098 -+:10ABC00013F0400F06D0D7F84C014146524645F0ED -+:10ABD00041DC2418079A09F1C2030A3217920D9A30 -+:10ABE0000A9309F1BC006FAB0B9000900293002A0E -+:10ABF0000CBF102130213846179A0A9B019417F098 -+:10AC0000DBDB1490002800F0E5816F980123041924 -+:10AC100012940370013B43703B6B1B68022B05D100 -+:10AC200097F95C2612B91F3303704270D9F8582087 -+:10AC300040F2371302EA03035BB199F8603043B185 -+:10AC40000378427843EA022343F0100303701B0A9F -+:10AC5000437097F843365BB13B6B5B7D43B1037840 -+:10AC6000427843EA022343F4806303701B0A437073 -+:10AC7000002380F802A0C370109B037110990B0A87 -+:10AC80004371012106303FAB3E9A21F06DDAD8F8CE -+:10AC900004300646002B06DA0C21122207F5037356 -+:10ACA00021F062DA0646349A2AB13046322135ABB9 -+:10ACB00021F05ADA0646D7F8603648AC00229B7875 -+:10ACC0002046099946F05AD9D8F8043013F4803F49 -+:10ACD0003FD03B6B0DF5B5751B6804F11502022BD7 -+:10ACE00014BF002301234846294661AC21F09ED9B8 -+:10ACF0004846214621F0F6D830462D211A222B460F -+:10AD000021F032DA23463D21162221F02DDAD7F840 -+:10AD1000FC3406461B78E3B172AB012203F8012D27 -+:10AD20007F2121F021DAD7F8FC140DF5D574054602 -+:10AD300024310E222046F7F31FF138462146002227 -+:10AD400017F0EEDE28464A210E22234621F00CDAC7 -+:10AD50000646129AB24201D2002002E0129BC6EBD4 -+:10AD600003000423009001934846334600214FF02E -+:10AD7000FF3235F0D9D997F8653604462BB107F57F -+:10AD8000CC61043112F0C2DC0446D8F8043013F070 -+:10AD9000400F08D007F500732046DD211822063346 -+:10ADA00021F0E2D90446D8F8083013F0400F06D05D -+:10ADB000D7F84C0141465246234645F02BDB069816 -+:10ADC0000023D9F808200090019302933846149983 -+:10ADD000D26843461AF0A6DEBAF1000F40F0FA80BE -+:10ADE0001099159AA8F8D41092F860300E989BB27A -+:10ADF000834238BF0346A8F80231022140464AF098 -+:10AE00007FDB404649464AF0C5DAD9F8CC3013F426 -+:10AE1000801F09D03846494611F0A8DD012803D12A -+:10AE20003846494634F002D80C990D9A8B6AC8F816 -+:10AE300024305AB10B980F990622F7F381F028B10C -+:10AE400008981799D9F8082027F0CEDBD9F8082000 -+:10AE50000898179926F0CCDFD9F8CC2012F40053CB -+:10AE60000CBF1C4602243B6893F8463013F0030FD6 -+:10AE700007D012F4805F04D1B8F8063003F0010265 -+:10AE800000E000227F2300930192234648A808F1A6 -+:10AE90004401002246F030D9384641464AF032D9C2 -+:10AEA0000C9890F82F3063B1D8F8E81049B1C06819 -+:10AEB000D8F8EC20FBF31CF70023C8F8EC30C8F8F6 -+:10AEC000E830B9F86230002B33D0D9F8582040F27E -+:10AED000371302EA030363B312F0010F01D1119992 -+:10AEE00039B398F8DE300BB1119AB2B90C9890F8DA -+:10AEF0002F30F3B11199E1B14978C0680231FBF309 -+:10AF0000E7F6C8F8E800A0B1119B5A78194602325A -+:10AF1000C8F8EC20F7F330F00BE00224384608F1D3 -+:10AF20001A010B9A0A9BCDF8008001941DF02AD8D3 -+:10AF3000A246D9F8CC3013F4005F04D0D7F84C0106 -+:10AF4000494644F0FFD938464946012216F0E8DF69 -+:10AF500000231398009302930D9B0490002B0CBFC9 -+:10AF600008220A2238464946179BCDF804A0CDF89E -+:10AF70000CB011F0D3DD169860B3D9F87030B3F18E -+:10AF8000FF3F03D009EB83035B6F13B90DF5CD725F -+:10AF900002E003F5997312E0362313700DF5CD71BD -+:10AFA00026335370023201F110039A42F4D10C9A05 -+:10AFB00092F82F3013B137238DF89A310B46009356 -+:10AFC000F12301933846494608F11A02D8F8E830CF -+:10AFD00020F0FAD973B0BDE8F08FC0462DE9F04FEC -+:10AFE000D0F8ACA3D1B0D0F8B00389469DF86C116D -+:10AFF0000890DAF86801079206911E4683799DF859 -+:10B00000704113B1042149F0D3DA99F8063023B125 -+:10B0100099F80430002B00F09B813278737842EA73 -+:10B020000328B278F37842EA0323079A0993537806 -+:10B030001B0213F4804040F07D81099B012B00F03E -+:10B04000828083460E2545E1DBF8D830002B00F0E6 -+:10B050007F81F3789F0914B30AEB8703D3F88052FA -+:10B06000EDB12B69DBB12B7ACBB14CAC314603226D -+:10B070002046F6F381F705F114012A69E01CF6F386 -+:10B080007BF729690DF12E05204603312A46FDF391 -+:10B0900061F25A9A301D111F2A46FDF38BF2032FDD -+:10B0A00040D809EB87035B6F002B3BD01A695A9895 -+:10B0B0003146143301F02ADF002833D0321D3179B4 -+:10B0C000537841EA03289178D378B8F1010F41EA27 -+:10B0D000032309931FD1032B1DD1B37A06F10A0272 -+:10B0E000102B18D1DBF8D80006F10C010230527891 -+:10B0F000F6F326F7044670B95846414699F94820B8 -+:10B100004AF016DA8BF8DE805846414622464AF06D -+:10B110000FDA25460BE05846012199F9482049F0FD -+:10B1200099DF03E003234FF0010809930F25DBF8B3 -+:10B13000D810089E4A78F0680232FBF3D9F5002354 -+:10B14000CBF8D830C6E0D9F85050D9F84C60D9F8CF -+:10B150005410ADB10C46074609E00799062201F1EB -+:10B160000A002146F6F3ECF6063410B10137B74277 -+:10B17000F3DB012D02D1B74206DB01E0022D01D045 -+:10B18000002512E0B742FBDB03230093079B00245A -+:10B1900003F10A02504617212346019402940394B6 -+:10B1A00018F086DC0125A346AFE0BAF8822144F20C -+:10B1B00021339A4214D00E3B9A4211D007339A425F -+:10B1C0000ED010339A420BD0143B9A4208D007336A -+:10B1D0009A4205D010339A4202D025339A4200D1C8 -+:10B1E0000125079E504606F10A0421462A464AF0E8 -+:10B1F000DFDA014610B150464AF0E2DA0135002D9F -+:10B20000D3DD504621464AF0E3DB8346002800F0B8 -+:10B210009C8049464AF0BED8DBF8042012F4805FD7 -+:10B2200009D0089991F83030002B40F08E8022F43C -+:10B230008053CBF80430504659461BF0CDDEB8F1B0 -+:10B24000000F03D0B8F1010F16D041E0B9F95C301E -+:10B2500099F9482023B9584601214AF069D903E0F9 -+:10B260005846012149F0F6DE9BF8183013F0010F23 -+:10B2700069D000252C4632E0DBF8D81041B1089B9C -+:10B280004A78D8680232FBF333F50023CBF8D83084 -+:10B29000B9F86250002D56D1089E8221F068FBF368 -+:10B2A00017F5044608B945462FE0102303706FF0E8 -+:10B2B0007F0343702946DAF80C30B3F85A26631836 -+:10B2C000013180299A70F6D10025CBF8D84006E0EC -+:10B2D0000D2502E0099903293AD80024ADB9BBF144 -+:10B2E000000F12D09BF8183013F0010F0DD0079EFD -+:10B2F00050464946042206F10A0300950195CDF80F -+:10B3000008800395049511F009DC0999069A4B1CF5 -+:10B31000019300230393079B059203F10A0148461A -+:10B3200009F1BC025B46CDF80080029504941CF044 -+:10B33000F3DC0DE0079A504602F10A014AF02EDADA -+:10B34000834628B180E60D2500E001250024DCE7D6 -+:10B3500051B0BDE8F08FC0467FB5089D9DF82440F0 -+:10B360009DF82860009501940296FFF737FE7FBD97 -+:10B3700002292DE9F0410646D0F8AC5301D0002453 -+:10B3800001E000F575742B68D3F88C205368126CBB -+:10B390009B1822692361C2EB0302A3699A422378B6 -+:10B3A0000ED24BB9E26863699A4205D30123237038 -+:10B3B00063680133636028E0E3680133E36024E0FD -+:10B3C0000027E7600BB3012904D1284602311EF0A3 -+:10B3D00025DE18E0022916D1A868D6F8D01304F0AB -+:10B3E0003DD9D6F8CC3373B12B6893F87430012B68 -+:10B3F00007D02869012132F063D82A68012382F836 -+:10B400007430C6F8CC7300232370BDE8F081C046C9 -+:10B410002DE9F04F97B0DDF894B0D0F8AC6300237D -+:10B42000D0F8B0930C460746594630460392DDF8F3 -+:10B4300088A014931393129333F0DCDF039905462D -+:10B4400001F001030093484621465246239B17F022 -+:10B450003BDF1490002840F00783219A032A0DD97E -+:10B46000042213A82099F6F387F5219B072B05D911 -+:10B47000209A12A8111D0422F6F37EF5139C129A4D -+:10B48000B4F1000818BF4FF00108BBF1000F01D163 -+:10B49000D5F808B003998B1E472B00F2E182DFE854 -+:10B4A00013F0F900FE00010104016A007D008C0028 -+:10B4B000DF028E00DF029700DF0207010A01480069 -+:10B4C00058007F0195010D011F014E015401280212 -+:10B4D000DF029900A000AD00B00033013601FC008E -+:10B4E000DF023E024202DF02DF02DF02DF02DF0292 -+:10B4F000DF02DF02DF02DF02DF02DF02DF02DF0244 -+:10B50000770289028E02E500EF00E202A402DF0268 -+:10B51000DF02B402B702C002C302C602C902CC02F3 -+:10B52000DF02DC02CF02DF02DF02DF02DF021402F1 -+:10B530001B02D9F83430002B00F092820DAC30465B -+:10B5400007F56371224620F077DB50462146102232 -+:10B55000C3E0D9F83430002B00F0828211AC5146A0 -+:10B5600004222046F6F308F5304607F563712246BB -+:10B5700020F07EDB1FE0219A0023052A8DF857304A -+:10B5800040F22781384620990DF1570227F084DADE -+:10B590009DF8573014908AF8003064E251463046E6 -+:10B5A0004AF0FCD80146002800F0268238469AF876 -+:10B5B000062029F06FDC149055E29B4B00E09B4B7A -+:10B5C0000093384629465246239B27F0FFD9F2E7DD -+:10B5D000974BF5E7D6F83407FEF7CEFECAF8000021 -+:10B5E00041E2D6F834572846FEF7CEFE844200F3F7 -+:10B5F0002E8228462146FEF7C3FE34E2D5F85035A8 -+:10B600003BE03368DB691F692B79002B40F06B81CD -+:10B61000BC4200F31C82C5F85045139C18461946DD -+:10B620007318D3F84C2222B1937913B1954218BF05 -+:10B63000013004312029F3D1002800F01482C4EB3A -+:10B64000070393FBF0F000217318D3F84C224AB1A2 -+:10B6500093793BB1954205D0D2F85035834288BFEB -+:10B66000C2F8500504312029EED1FCE196F9A83842 -+:10B67000002B01DA002300E00123CAF80030F2E1D8 -+:10B68000B8F1000F01D0002301E04FF0FF3386F83E -+:10B69000A838E8E195F83C30EFE7AB79EDE785F8BD -+:10B6A0003C80E0E1D6F82837E7E7C6F82847DAE13A -+:10B6B000D7F8BC33E1E7C7F8BC43D4E16A7E049213 -+:10B6C00022B105A805F11A01F6F356F4049B1A1DE0 -+:10B6D000239B93427DDB504604A9F6F34DF4C2E16F -+:10B6E000202C02D96FF01103BCE12399231D99424C -+:10B6F0006FDB2B79002B40F0F68028460AF104011D -+:10B70000224633F039DAAEE195F83A30B5E7AB7955 -+:10B7100085F83A8085F83B80002B00F0A4812B79D6 -+:10B72000002B00F0A0813046294611F0BFDA3046E8 -+:10B730004FF000614FEAC86218F03CDA93E199F8E3 -+:10B740003830003B18BF012397E799F838301C1EAA -+:10B7500018BF0124444500F0868130461FF076DB97 -+:10B7600010B96FF015037DE154B1304601F0C2FE0F -+:10B77000736A23F4C0137362002389F8383072E1CE -+:10B78000736A304643F400237362022389F8383029 -+:10B79000D6F8AC38013B86F8A93805F081FE62E1A5 -+:10B7A000219A032A15D9002C05DB3046214614AA1C -+:10B7B00033F064DD05460DB12B795EE7149B13F180 -+:10B7C0001E0F40F05081CAF800504CE1239B072B1C -+:10B7D00002DC6FF00D0345E1032A01D1002703E0ED -+:10B7E000022A14BF00270127002C2DDB30462146FA -+:10B7F00014AA33F043DD054630BB149B13F11E0F32 -+:10B8000022D1129B002B1FDD87F0010300932A46F3 -+:10B810002B463046139933F0CBD9054650B96FF01B -+:10B820001A03149310E0C046991E8300A91E8300DA -+:10B83000F92A83003046294633F0A4DE149018B16B -+:10B840003046294633F0F8DD129B032B00F00B81C4 -+:10B85000022B00F00881149A3AB112F11E0F40F049 -+:10B860000281002B40F0FF80FCE0002B24DD2B79CF -+:10B87000002B40F0F88033681B6F13F0030F02D0E9 -+:10B880006FF00803EEE0AB7923B13046294633F080 -+:10B89000ABDC90E6D5F8CC3013F4005202D04FF078 -+:10B8A000FF33DFE06B7E304600920192294605F1BE -+:10B8B0001A022EF05DD8D6E06B79002B00F0D38011 -+:10B8C0003046294633F0DCDACDE015B195F9643520 -+:10B8D000D3E6CAF800501FE0F5B1002C1CDB012CA8 -+:10B8E0001ADC2B7913B16FF00403BBE085F86445D3 -+:10B8F000B9E099F818307BB199F82F3063B199F815 -+:10B9000030304BB999F83F3033B9D6F868319B796C -+:10B9100013B9B6F81637B0E66FF00103A2E033684A -+:10B9200093F83030A9E6336893F83030434500F09F -+:10B930009A80304633F024DF0446B8F1000F05D07A -+:10B9400043791BB13046214633F09ADA214630461E -+:10B9500088F0010233F01CDF04461490002840F008 -+:10B9600082803368012283F82F20B8F1000F03D0C2 -+:10B97000D6F8403583F834203368304683F8308079 -+:10B9800010F01EDA86F8DD41304605F0BDFD6AE0B4 -+:10B99000BAF80200F7F360F4E8B99AF80400BAF8CC -+:10B9A00002109AF800209AF801300090284628F0FA -+:10B9B000C3DD00E6D6F83437B3F8A4335DE624B926 -+:10B9C000D6F83437A3F8A4434DE0D6F85C01A1B211 -+:10B9D0003AF0E4DC10B96FF0130343E0D6F83437E3 -+:10B9E000BDF84C10A3F8A4133DE0BBF1000F03D049 -+:10B9F0009BF80430022B02D06FF01D0332E0384672 -+:10BA0000DBF8101027F01CD8D5E597F8F03334E6B2 -+:10BA1000E3B287F8D53387F8F033384626F0D6DE20 -+:10BA200021E0D7F8E83328E6C7F8E8431BE0D7F869 -+:10BA3000EC3322E6C7F8EC4315E097F8D4331CE664 -+:10BA4000D6F86C32D3F8D432DB8D9C4202DD6FF035 -+:10BA50001C0307E0A7F8C84305E0B7F8C8330CE6B5 -+:10BA60006FF016031493149817B0BDE8F08FC0461A -+:10BA70002DE9F0410468074686B020460E46904600 -+:10BA80001D461BF0B3D910B120461BF0A7D90C9B63 -+:10BA90002046029300230393049339460B22434626 -+:10BAA0000096019511F03AD806B0BDE8F081C04685 -+:10BAB00070B5114686B00546164649F06FDE04465D -+:10BAC00008B390F8DF3023B12846214601222AF03E -+:10BAD000B9D9204649F0E8DBE3681BB12846214686 -+:10BAE0003CF0CCD9002203230092019302920392EE -+:10BAF0000492284621690532334611F00FD82846B2 -+:10BB0000214649F05DDE06B070BDC04670B5036BDE -+:10BB1000002680F8D068D0F85C410546186907F027 -+:10BB200005F8014620463AF001DA20B12846012105 -+:10BB3000324618F031DA70BDF0B505688BB00646B4 -+:10BB40000021EF681DF0D6DA304610F01BDFD5F883 -+:10BB5000E4366BB1A868D5F8741503F07FDD0023D7 -+:10BB6000C5F8E43695F8583503F0FD0385F85835E7 -+:10BB7000D5F85C013AF0BAD92A6992F8EA3063B193 -+:10BB8000D36ED3F8202140F2044302EA0303B3F555 -+:10BB9000806F14BF0020012006E0106E03F054FEF9 -+:10BBA000D0F1010038BF002000283CD0284605F025 -+:10BBB00019FE2B6BD5F85C41186906F0B7FF0146FA -+:10BBC00020463AF0B3D930B195F8D0281AB92846B2 -+:10BBD000012118F0E1D9304611F06EDC4FF000433E -+:10BBE000C7F888310F21286931F010DE286940F24A -+:10BBF000FF3131F0F9DD2B6B1B68022B04D1286972 -+:10BC000095F8431631F05EDE284616F02DDC284606 -+:10BC100016F0F6D900232846694600931AF082D818 -+:10BC200028461DF0D7DB0BB0F0BDC0462DE9F04F24 -+:10BC30000668D0F8D022D0F8D81297B00746D0F8CE -+:10BC4000E8B23046069107921DF04CDC069BB068C6 -+:10BC5000196803F003DD384602212CF02DDEF7E1F0 -+:10BC6000D6F8D83603EB82035D686C8E04F470431B -+:10BC7000B3F5805F14BF38233C2356F8039004F4D7 -+:10BC80004063B3F5406F28D1336893F8463013F022 -+:10BC9000030F15D0D6F85C01D9F8041039F02EDD69 -+:10BCA00010F0080F0CD199F8EC304BB1D9F80030F6 -+:10BCB000022B12D1D6F8FC349B7813F0020F0CD073 -+:10BCC0002046F7F3AFF20E2894BF4FF400534FF421 -+:10BCD000805340F4306003439CB2D6F85C012146A7 -+:10BCE0003AF05CDB002800F0AE81688EF7F39AF240 -+:10BCF0000446688EF7F396F244F430640E288CBF45 -+:10BD00004FF480504FF400500443A1B238462BF05A -+:10BD100087DE002800F09781D7F8E832002B78D032 -+:10BD2000D3F8DC30002B74D04FF00001A7F85C1082 -+:10BD300095F8AA004FF00C0800FB08B0EA8814A997 -+:10BD400082F08002C2F3C0121C30F7F3D1F3BDF8C9 -+:10BD500050200DF1540AA7F8622095F8AA00514628 -+:10BD600000FB08B02030F7F321F4159B33BB95F8A6 -+:10BD7000AA1013AC01FB08B1042224312046F6F3CB -+:10BD8000FBF020469A490422F6F3DAF048B995F818 -+:10BD9000A920A2F10803DBB2022B40F254818DF8F6 -+:10BDA0004F2020465146F7F301F4024630B9009087 -+:10BDB000CDF8048095F832300293FAE0159B8D4956 -+:10BDC00013F0040F1CBF43F002031593159B30467C -+:10BDD00013F0020F1CBF43F00103159315AB009342 -+:10BDE0000423019301230293BB68002203931346AB -+:10BDF00017F0D6DA002207230192009395F8AA30B3 -+:10BE00003046029303920492394618322B4610F0C2 -+:10BE100085DEB5F8623013F0100F0FD0BA6D40F226 -+:10BE2000371302EA03034BB9734B1A7832B9012373 -+:10BE30000092019395F832300293FCE02846F6F325 -+:10BE40007BF518B100230222009327E03B6D002B05 -+:10BE500032D0336893F83030002B2DD11C469846F1 -+:10BE600009E0796D284641440622F6F369F008F1AD -+:10BE7000060818B10134FB6C9C42F2D33B6D012BD8 -+:10BE800003D1FB6C9C4206D316E0022B14D1FB6C51 -+:10BE90009C420DD210E0002300930322019295F8FA -+:10BEA0003220039302920493304639461722C7E0AA -+:10BEB000002304220093F1E7336893F8953083B1AF -+:10BEC000D6F84C35012B09D1284606F5AA61062281 -+:10BED000F6F336F0002840F0B68002E0022B00F0C6 -+:10BEE000B28095F9344074B9D6F85C01698E3AF0A5 -+:10BEF000E9D840B105230094019395F832300394BA -+:10BF000002930494D0E7B7F862306BB1BA6D40F297 -+:10BF1000371302EA03033BB1304639462A462BF079 -+:10BF2000A1DF002840F08F80D9F80030022B0AD121 -+:10BF300099F815203AB9FD33009305F1380009A9A5 -+:10BF40000123019214E0336805F1380093F846307C -+:10BF500009A913F0030317BFD7F8CC301A46C3F36F -+:10BF6000003383F001020192FF2300220093134665 -+:10BF700045F0C2D8336B09F1500493F8EC1039B195 -+:10BF80006B8E03F44063B3F5406F14BF1421282176 -+:10BF9000204645F059D8D6F86036002209A8214637 -+:10BFA0009B7844F0EBDF024630B9009009230193FF -+:10BFB00002920392049277E79DF8382096F838377A -+:10BFC0009A4240D195F93430C3B96A8E304602F4B2 -+:10BFD0007042B2F5805F14BF0222012205F13801E0 -+:10BFE0002BF0E4DC024648B90A230090DFE7C046A4 -+:10BFF00058D4010017738600B0270200336893F805 -+:10C00000303053B32946304649F0C8DB014620B3EF -+:10C01000037E13F0020F06D0436813F4805202D15E -+:10C020000D230092C3E7D1F8F030B3B100220F2303 -+:10C0300000920193029203920492304639461732DD -+:10C040002B4610F06BDDD6F8DC36013BC6F8DC364B -+:10C05000D6F8DC26002A7FF403AED6F8DC36FBB136 -+:10C06000069B00219977D6F8DC26D6F8D836013A17 -+:10C0700003EB8203C6F8DC26069A9C685368012B02 -+:10C080000AD0009101910291039104913046394602 -+:10C090002022234610F042DD38462EF011DA35E03A -+:10C0A000D7F8CC3013F4005F06D0FB7923B9D6F86B -+:10C0B0004C01394643F0F8DF0799FA7991F93430A9 -+:10C0C0004AB1002238460121934214BF00230123C4 -+:10C0D0002CF0DAD809E038460121D3F1010338BF4A -+:10C0E0000023009201922CF009DA97F91030022B0C -+:10C0F00003D1F86800214DF035DA96F875323846EC -+:10C1000023F0040386F875322CF0A6D917B0BDE8E9 -+:10C11000F08FC0462DE9F04F9B460568D0F8D0322D -+:10C1200089B003932B68064693F83F308A469046C1 -+:10C13000D0F8D872D0F8D492002B00F08281C37965 -+:10C14000002B00F07E81837C0DF1160013B106F107 -+:10C15000D60100E049460622F5F30EF700242B68CD -+:10C1600085F84A4593F844301BB1D5F8640135F0A1 -+:10C1700067DFB37C2BB1D5F84C013146224605F080 -+:10C1800067F82A6992F8EA305BB1D36ED3F82021C0 -+:10C1900040F2044302EA0303B3F5806418BF0124AC -+:10C1A00005E0106E03F050FB041E18BF0124CCB153 -+:10C1B000002130462FF012DA3046FFF7BDFCB37C89 -+:10C1C0003046D3F1010338BF0023009300210DF165 -+:10C1D00016020823FFF74CFC002130460A4632F0D5 -+:10C1E000CBDC1AE1B37C002B00F08F80D6F8DC3278 -+:10C1F000D3F8901041B193F894206868FAF378F579 -+:10C20000D6F8DC32C3F89040BB6823B10D2B02D0C6 -+:10C2100030462CF09BDAD5F86801042148F0C8D9E3 -+:10C220000DF11601284649F0B9DA002421460746E7 -+:10C2300086F8944030461CF06FDC2146304619F0F9 -+:10C240002DDC304621460FF01FDEBAF1000F45D03D -+:10C2500006F1BC00F6F380F300283FD12B6BB9F850 -+:10C260003240186906F062FC844237D1D5F85C018F -+:10C27000B9F8321039F0AADE30B9D5F85C01B9F856 -+:10C28000321039F01FDF80B1B8F1000F0DD1D5F8B1 -+:10C290005C01B9F8321039F049DE30B9DFF8ACA1F1 -+:10C2A0000123C34685F8D03800E0C24608230DF1CB -+:10C2B00016010193284606F1C2030A4600971BF0B7 -+:10C2C00091DE034658B1BAF1000F08D02846514616 -+:10C2D0005A4618F053D810B9824600E0C2460FB94A -+:10C2E0003C462FE038460E2148F0AADE2B6893F832 -+:10C2F000443023B1D5F86401394635F0B5DE28461F -+:10C3000039461AF069DE00241CE02B6893F895305A -+:10C3100093B1D5F8000507A948F0DCDE06E05368C4 -+:10C3200013F0005F1CBF23F00053536007A848F0D0 -+:10C33000D9DE02460028F2D10124B474304616F04A -+:10C34000B3DEC246304600212FF048D905F5007112 -+:10C35000284606311FF0E2DC2B6893F83F20A2B993 -+:10C3600095F9473685F84226B3F1FF3F08BF85F8B7 -+:10C370004326284619F0B2DA2B6893F8463013F0BA -+:10C38000030F02D0284619F0C5DA06F1BC00F6F317 -+:10C39000E3F2014630B930460DF11602082300944D -+:10C3A000FFF766FB95F872323BB9D5F86C329E42C6 -+:10C3B00003D13046FFF7C0FB05E0304611F07CD8D2 -+:10C3C000304610F0DFDAD9F8641049B16868B9F87E -+:10C3D0006820FAF38DF40023C9F86430A9F86830B6 -+:10C3E00002230DF11602009328463346002117F070 -+:10C3F0002FD93046002117F0FDDA304617F066DA03 -+:10C40000284605F081F8BAF1000F03D02846002134 -+:10C410005A46D047B8F1000F01D0002013E0304653 -+:10C420004146424632F0A8DB414606220398F5F326 -+:10C4300007F606F1BC0041460622F5F301F6404638 -+:10C4400001E04FF0FF3009B0BDE8F08F0DBB0000F8 -+:10C450002DE9F04F062989B007460D4692469B46C6 -+:10C460009DF848900468D0F8D86246D061BBB9F115 -+:10C47000000F03D12046394633F098DB94F872322E -+:10C48000002B3AD0D4F8000507A948F023DE03E0DA -+:10C490001B7E13F0020F30D107A848F023DE0346BD -+:10C4A0000028F5D151E0236B186906F03FFBD7F85F -+:10C4B000D4325B8E834220D0204628F00DD8D4F8A9 -+:10C4C000340728F027DC18E0B368093B012B14D8A7 -+:10C4D0002046114649F062D910B10C2148F0B0DD78 -+:10C4E000022D07D0A068316803F0B8D8052D01D01F -+:10C4F000012D02D14FF0010801E04FF00008139B1D -+:10C500000095CDF804B00293336C20460393736C0E -+:10C5100039460493B9F1000F0CBF07220922534694 -+:10C5200010F0FCDAB8F1000F13D0052D01D0022D68 -+:10C5300007D1B27F337F9A4203D238462DF0C0DF55 -+:10C5400007E03846FFF772FB03E07368032BAAD1BC -+:10C55000D3E709B0BDE8F08F0048704760E70100FD -+:10C560000048704780E8010010B5836F40F2EE226A -+:10C570001C6A044B94219C4208BF4FF4166231F0B0 -+:10C5800069DB10BD50200800816F10B508310446EA -+:10C590002FF06CDEFFF7E0FF014620462FF046DE6D -+:10C5A00010BDC0462DE9F04104460D469046BDF849 -+:10C5B00018E09DF81C701E4633B18368DA6A02EBFE -+:10C5C0004102938BFB1893834FF6FF739E4503D074 -+:10C5D000A821724631F03EDB04EB8503D868084B96 -+:10C5E000414632465B6A9847002807DA36B1A368AD -+:10C5F000DA6A02EB4502938BDB1B9383BDE8F08183 -+:10C60000E0A6850010B507490446406EF6F3E0F158 -+:10C61000034620B9606E0449F6F3DAF10346184682 -+:10C6200010BDC04699D501000AAA860070B50D4616 -+:10C630000669144608460A220021F5F301F56B88C5 -+:10C640001C43F36C6C8013F0200F03D02B8843F451 -+:10C6500080632B80B16F42F250030A8C9A4206D15C -+:10C660004B8C052B03D86B8843F004036B8070BDA3 -+:10C670004FEA810210B513188E468168DB6F52189D -+:10C680008367936B0B6390F8EB3063B190F8E830FD -+:10C690004BB94FF40051006EBEF1000F0CBF0A46BB -+:10C6A0000022FEF3BFF310BDB1F1FF3F2DE9F041D1 -+:10C6B00004460E4605D1836F596A09B90E4600E05B -+:10C6C0009E6994F8E9701FB9204639462FF004DBC3 -+:10C6D000206EFEF307F580B1002504EB8503D868D2 -+:10C6E00010B1254B9B6898470135062DF5D1E368BD -+:10C6F0001BB1204600212FF03BDB94F8E8203AB133 -+:10C70000A3680022DA612046032130F071DC30E0BA -+:10C71000206E46F0040184F8EA20FEF393F3A06F44 -+:10C72000012184F8EA1018B1406A08B106F0D0F887 -+:10C7300020462FF0F5DBE26E206ED2F8E0310121C9 -+:10C7400023F02003C2F8E031F9F326F4002120465B -+:10C750002FF0C2DA204630F03DDD2046012130F0D6 -+:10C7600011D9A2680023D3611FB9204602212FF0FE -+:10C77000B3DABDE8F081C046E0A6850070B50121BE -+:10C78000044631F0ABDA206E03F05CF8204600215D -+:10C790002FF0A2DA204630F0FDDE054630B120460B -+:10C7A000002131F09BDA6FF0080005E020464FF0E1 -+:10C7B000FF31FFF779FF284670BDC04673B50469A5 -+:10C7C000054620460E46FFF7DFFEA36F3146586A46 -+:10C7D00007F0F6FB2A68012382F8743020462FF018 -+:10C7E0007DDCA36F2046998A31F010D8A36F2046D4 -+:10C7F000D98A30F0F9DF204694F886102FF0FED960 -+:10C80000A36F204652219A8B31F024DAA36F502176 -+:10C81000DA8B204631F01EDA20462FF081DC2046EC -+:10C82000FFF7A2FE032300932046042108220023E1 -+:10C8300030F0F0DB20462EF0B1DF7CBD10B504698E -+:10C840004FF440412046002230F0D2DBD4F8F830DB -+:10C850001B691BB120462EF0A1DF02E020462FF01D -+:10C8600059DDE26C206E02F00202002A0CBF114674 -+:10C870004FF400710A460023FEF384F310BDC04656 -+:10C8800070B5836804461B6893F82050F5B9012100 -+:10C8900031F024DA206E02F0D5FF204629462FF031 -+:10C8A0001BDA20462FF036DDA068D0F848381B7818 -+:10C8B0000BB12FF061DBA36F586A05F0FBFFA36893 -+:10C8C00084F85E501A68012382F8203070BDC0469B -+:10C8D00070B5082986B005460C4602DD6FF00100F0 -+:10C8E0002DE1836897491B685869F6F345F0082CD9 -+:10C8F00024D12A6E936913F0005F03D0D36913F03B -+:10C90000010F0BD0EB6C13F0010F0BD02B6D13F05C -+:10C91000800F07D1D36913F0010F03D06B6D13F0B3 -+:10C92000005F05D12B6D13F0800101D10C4612E0A0 -+:10C9300043B2022B40F30181052400E05CB1D5F83D -+:10C94000F8305B68022B06DDAB6D13F0005F02D19F -+:10C950006FF00200F3E00A220DF10E000021F5F362 -+:10C960006FF3D5F8F8304FF000021A8195F8903047 -+:10C970000BB91E4604E0EB6ED3F8203103F001063C -+:10C9800095F8903053B164B9D5F8F8301B68002B96 -+:10C9900000F0888028462FF0BDDC83E0002C00F0FA -+:10C9A0008180BDF80E30D5F8F82043F01003ADF8C3 -+:10C9B0000E305368022B6B6D03D123F000536B656F -+:10C9C00039E043F0005314F0040F6B6503D1138971 -+:10C9D00043F0140313812A6E936913F0005F03D0B0 -+:10C9E000D36913F0010F0BD0EB6C13F0010F12D0D1 -+:10C9F0002B6D13F0800F0ED1D36913F0010F0AD005 -+:10CA00006B6D13F0005F06D0D5F8F820138943F062 -+:10CA1000400313810FE0D5F8F8305B68042B05D193 -+:10CA2000BDF8123043F40053ADF81230D5F8F820B9 -+:10CA300000231361D360D5F8F8205368022B12D17C -+:10CA4000EB6C13F4804FBDF8103008D043F48073C2 -+:10CA5000ADF810303023D3602023136103E023F4BA -+:10CA60008073ADF8103014F0020FD5F8F81003D031 -+:10CA70000B8943F0010304E00A894FF6FE7302EAD2 -+:10CA8000030314F0040F0B81D5F8F81003D00B89C1 -+:10CA900043F0080304E00A894FF6F77302EA030340 -+:10CAA0000B8109E0BDF80E3023F01003ADF80E3015 -+:10CAB0006B6D23F000536B65D5F8F8301C60AB6FDD -+:10CAC000696D586A06F08AF995F890301BB116B175 -+:10CAD000284630F033DF0224BDF80E30284600210E -+:10CAE0001022009430F096DABDF81030284601216B -+:10CAF0004FF48072009430F08DDABDF81230284681 -+:10CB000021464FF40052009430F084DA28462FF08A -+:10CB1000A1D895F8903073B1AB6F1B68A34206D1D2 -+:10CB2000D5F8F8301B6813B128462EF037DE16B161 -+:10CB300028462FF05DDF002001E00124FFE606B06B -+:10CB400070BDC046C65C860070B5054690F8900082 -+:10CB5000002846D0AB6F002185F89010586A05F088 -+:10CB6000BDFEAB681A6992F8EA305BB1D36ED3F8B8 -+:10CB7000202140F2044302EA0303B3F5806018BFAA -+:10CB8000012002E0106E02F05FFE68B10024AB6F7E -+:10CB900085F8EB4085F8EA40586A214605F098FE92 -+:10CBA000A8682FF033D91BE0286EFEF39BF20446F1 -+:10CBB00080B1EB6ED3F8203113F0010F02D028467C -+:10CBC00030F0BCDEAB689868F6F7F8FA0446284601 -+:10CBD00031F0A2D895F8E81011B9284631F07ED886 -+:10CBE000204670BD70B5054690F8900050B3AB6814 -+:10CBF0001A6992F8EA305BB1D36ED3F8202140F283 -+:10CC0000044302EA0303B3F5806418BF012403E080 -+:10CC1000106E02F019FE0446AA6814B100231362D4 -+:10CC20000CE0906802F056DD284621462FF054D8DB -+:10CC300095F8E83013B928462FF06CDBAB6F586AD3 -+:10CC400006F014FB70BDC0460121836F10B580F85B -+:10CC500090100446586A05F041FE204602212FF04C -+:10CC60003BD8A368986802F03FDD002010BDC046A5 -+:10CC70002DE9F3418668062733680DF10204DB696C -+:10CC800005461B6AD0F86C80C6F8AC3830493A4685 -+:10CC90002046F5F371F16B6C2E48214603FB07002B -+:10CCA0003A46F5F369F10423C6F8AC38013B86F83F -+:10CCB000A938A8681EF0CAD808B93C4604E0D6F8DE -+:10CCC000AC389B0001339CB2D5F8B8700026F05DFB -+:10CCD00004F0FF01201880B2421E02F0FF0341EA77 -+:10CCE000032102F48072C4F300231A43330243F495 -+:10CCF000004301369BB2062EA8F840350446A8F83A -+:10CD00002015A8F82C25A8F84035E0D12846982110 -+:10CD10007A7830F09FDFD5F8B83028469A219A7893 -+:10CD200030F098DFD5F8B8302846DC781A789C21A6 -+:10CD300042EA042230F08EDFD5F8B83028465C791C -+:10CD40001A799E2142EA042230F084DFBDE8FC819A -+:10CD500061DB0100301E02002DE9FF410569074635 -+:10CD60009221284630F05CDC400080B2A7F84200F7 -+:10CD700000282FD04FF000080DF101060F2130469A -+:10CD8000154A4346F5F3A0F1686E3146F5F320F6F7 -+:10CD900060B13146686EB7F84240F5F3EDF504EB4B -+:10CDA000480482B22146284630F054DF08F10108D9 -+:10CDB000B8F1770FE0D1686E0849F5F309F648B18C -+:10CDC000686E0649D5F8F840F5F3D6F52081284677 -+:10CDD0002EF040DFBDE8FF81AEAC8600177C8600F8 -+:10CDE0002DE9F041056986B04FF0FF31AC4A80462D -+:10CDF0002846EE6E30F0FCD8D5F8F8302846196891 -+:10CE0000FFF766FDAB6D3BB14FF00303A6F8B436F8 -+:10CE10004FF0FF03A6F8B836EB6C13F0010F27D0E4 -+:10CE2000A04A136823BB012111602B6D286E13F0FB -+:10CE3000800F03D0023102F0BBFD19E002F0B8FD13 -+:10CE40002B6D13F0005F13D12846922130F0E8DB00 -+:10CE5000400080B260B100F1CE042146284630F097 -+:10CE6000DFDB40F040022146284692B230F0F2DE8D -+:10CE70004FF0FF31C6F8281128468B4A30F0B8D859 -+:10CE80008A4C03E00A20F9F367F40A3CD6F828310B -+:10CE900013F0010F01D1092CF4D14046D6F8283106 -+:10CEA000FFF7CCFCD5F8F4302BB92B6E9A6A40F220 -+:10CEB00094539A4213D1286E7D4B826BD318012B69 -+:10CEC00007D94AF6E6039A4203D04AF6E5039A42A6 -+:10CED00005D10823002128220093FDF3D7F7002174 -+:10CEE0000A46286EFDF3B6F7FFF73AFB01462846DF -+:10CEF0002FF09CD92846FFF7BBFE4FF480330093F8 -+:10CF00002846062398210DF10E022FF0CFDCD8F829 -+:10CF1000003093F83830D3B140461DF097DF012838 -+:10CF200015D100231C461F4605930AE04FF4C02389 -+:10CF300000933946284605AA04232FF0DDDC01348E -+:10CF40002437D8F80030DB691B6A9C42EED32846B0 -+:10CF50008021082230F07EDE28465C210A2230F053 -+:10CF600079DE4FF08073534AC6F8003128465249A3 -+:10CF700030F03ED84FF00043C6F8883103F1024349 -+:10CF8000C6F88C314FF48043C6F8283103F540438E -+:10CF900073620121284630F019D8286E02F0A0FCF7 -+:10CFA00083B2A8F818001621A6F8A8362846B5F8C6 -+:10CFB000442030F04FDE2846C021B5F8542030F030 -+:10CFC00049DE2846C221B5F8562030F043DE3B4BFF -+:10CFD0002846C6F86031D6F86031B5F8883044216B -+:10CFE000C6F86431364BB5F88C20C6F86031D6F8F7 -+:10CFF0006031B5F88A30C6F8643130F02BDE28464F -+:10D000004621B5F88E2030F025DEB6F888361B05AF -+:10D010001B0DA6F888364FF00103A6F89C360023B6 -+:10D02000C8F848301C4605EB8403D86810B1254B7E -+:10D030005B6898470134062CF5D1224CE868236DD3 -+:10D040009847E36EE86898474046FFF785FE2B6EE9 -+:10D050009A6B4AF662139A421ED1EB6C13F0010FE1 -+:10D060001AD02B6D13F0800F16D113F0005F13D17F -+:10D070002846922130F0D4DA400080B260B100F14D -+:10D08000CE042146284630F0CBDA40F0400221465B -+:10D09000284692B230F0DEDD06B0BDE8F081C04631 -+:10D0A00004040004F02702000204020449420F00B5 -+:10D0B0001D57FFFF0000024000000640060002006E -+:10D0C00007000200E0A685002DE9F04790F8E9701E -+:10D0D00004460E469046856817B939462EF0FCDDA9 -+:10D0E000A86802F0F7DA06F47041B1F5805F14BF6A -+:10D0F0000021012181462046FFF7BAFAA36F31468D -+:10D10000586A05F00FFDA36F586A05F0EDFB28463D -+:10D11000FFF766FEB8F1000F04D0012120460A4651 -+:10D120002FF0D4DF28463146FFF748FBA868494670 -+:10D1300002F0E4DAD4F8D43043F00403C4F8D43075 -+:10D140000123C4F8D0301FB9204602212EF0C4DDDF -+:10D15000BDE8F087816810B50B680446D3F88C20D1 -+:10D16000D2F8B4300133C2F8B4300A6992F8EA3028 -+:10D1700063B1D36ED3F8202140F2044302EA0303E3 -+:10D18000B3F5806F14BF0020012006E0106E02F09E -+:10D190005BFBD0F1010038BF002020B120464FF0EA -+:10D1A000FF31FFF781FAA0682EF030DEA06819F099 -+:10D1B0008BDC10BDD0F8EC1010B5044631B100681E -+:10D1C0000C22F9F395F50023C4F8EC3010BDC046ED -+:10D1D0002DE9F04FD1F8D43289B0B3F832A0D0F8AD -+:10D1E0004C31804603938B798946D0F80CB0002BE4 -+:10D1F00000F0B58000273E4608EB8603D3F84C527A -+:10D200008DB1AB797BB9EB796BB1D5F8D432588E4F -+:10D21000F6F308F004465046F6F304F0844201D0D9 -+:10D220002F4606E02F460136082EE5D1002F00F0EC -+:10D230009680D7F8D432588EF5F3F4F7044650466A -+:10D24000F5F3F0F7844205D0D7F8D432D9F8D422D8 -+:10D25000DB8DD385404605A904AA18F08BDF39463B -+:10D26000D8F84C0141F0E2DF182300FB03F4D8F8B2 -+:10D270004C0104F13A0142F0C3DC38B9049A059B31 -+:10D28000039839460092019301F0DCFA04F1400161 -+:10D29000D8F84C0142F0B4DCD7F8D4320599DB8DD4 -+:10D2A00040019E02CE42079001D3B04209D321F043 -+:10D2B0007F4323F460038219984201D21046F6E7B7 -+:10D2C000079006AC07AD22462B46049803F0FAFC03 -+:10D2D000384618F0E5D929460346002220461DF0BD -+:10D2E000EDDDD9F8D4327608DB8D29469F02204641 -+:10D2F000334600221DF0FCDD3B46012101E049469A -+:10D300001346DA19B34201F10109F8D306A807A9B7 -+:10D31000002204AC05AD1DF0EBDD20462946069A3F -+:10D32000079B1DF0E5DD059B2046CBF88031049B73 -+:10D330002946CBF88431002304930593069A079B72 -+:10D340001DF0D6DDD8F84C010499059A42F010DFA3 -+:10D35000BB01CBF8883107FB09F3CBF88C3109B05E -+:10D36000BDE8F08F2DE9F34100EB8101D1F84C428B -+:10D37000064690461D469DF8207014B94FF0FF33C5 -+:10D3800019E004F11A0000212022F4F359F60023D9 -+:10D39000637615B9336803F14E054346304621469E -+:10D3A0002A46009730F09ADF034620B930462146DE -+:10D3B00032F0E8D803461846BDE8FC81D1F8CC30FD -+:10D3C00073B543F40053C1F8CC3005460C4632F037 -+:10D3D000D9D80646002840F08880B5F8822144F26A -+:10D3E00021339A421AD00E3B9A4217D007339A4201 -+:10D3F00014D010339A4211D0143B9A420ED0073306 -+:10D400009A420BD010339A4208D025339A4205D065 -+:10D41000AB6B5B7D13B96FF00B0666E02B6B93F87B -+:10D42000EC300BB91E4608E0B5F8263603F440632D -+:10D43000B3F5406F14BF142628262B6893F84630A6 -+:10D4400013F0030305D0D4F8CC30C3F3003383F0DA -+:10D4500001030093284633462146022231F024DAA4 -+:10D460000646002841D1D4F8CC3013F4803F0AD1CD -+:10D47000D5F84C01214641F0E1DFC4F8F00280B953 -+:10D480006FF01A0631E0062204F1BC0004F1C2017B -+:10D49000F4F372F5D4F8D432B5F8262683F8346064 -+:10D4A0005A86A379D3B194F8F532312B11D82B6871 -+:10D4B0001B7E2BB1284694F8F4120D4A1BF0B6DF00 -+:10D4C000D5F84C0194F8F41241F0FCDE322384F8D4 -+:10D4D000F43294F8F53284F8F43206E0D5F84C01D1 -+:10D4E00004F53D7141F0B2DE064630467CBDC046D3 -+:10D4F000329E85002DE9F041054632F041D90026E3 -+:10D500000746AB19D3F84C426CB1A3795BB1BC426E -+:10D5100009D063791BB12846214631F0B1DC284699 -+:10D52000214631F089DF0436202EEAD1BDE8F081B2 -+:10D53000002010607047C04610B505F021F810BDFE -+:10D5400010B504F05DFFC0B210BDC04610B508466E -+:10D55000114604F037FF10BD2DE9F0470446884618 -+:10D560004768002110469146C922F4F369F5204628 -+:10D57000414638F013DF78B997F85037002B00F0A8 -+:10D58000D08707F5AA6138460E3138F061D90646D2 -+:10D59000002800F0C68700E0266908F47043B3F560 -+:10D5A000805F14BF38233C233078FF5804F0D0FF4D -+:10D5B0000446B07804F0B4FF637C5FFA88F513F09A -+:10D5C0000102064602D097F904E106E097F904311A -+:10D5D000182BD4BF9646A3F1180E934B9C4203D14F -+:10D5E00058214FF0520C0BE0904B9C4205D0904BD1 -+:10D5F0009C4202D04FF07F0C01E04FF0580C614686 -+:10D600003B68022B5FD1012D01D8002303E00A2DD6 -+:10D610008CBF02230123E31893F90620854B9C421B -+:10D6200003D10B2D10D14C2240E0834B9C4203D1FF -+:10D630000E2D3BD1362239E0804B9C4202D0804BEC -+:10D640009C4204D10B2D30D00E2D2ED02EE07D4BE0 -+:10D650009C4203D10E2D29D12A2227E07A4B9C42ED -+:10D6600007D1022D01D1582220E00A2D1ED15422CB -+:10D670001CE0764B9C4203D10A2D17D1502215E0B5 -+:10D68000734B9C4203D10E2D10D128220EE0714B1A -+:10D690009C4203D10B2D09D13E2207E06E4B9C42E8 -+:10D6A00004D10C2D02D1442200E04022CEEB020333 -+:10D6B00023EAE3738B42A8BF0B46002202F809302D -+:10D6C0000132042AFAD1654B9C4208D0644B9C423B -+:10D6D00005D0644B9C4202D0634B9C4207D197F922 -+:10D6E0000431182BD4BF4FF0000EA3F1180E3A6886 -+:10D6F000022A40F01081012D01D8032303E00A2DF6 -+:10D700008CBF05230423E31893F90600494B9C4280 -+:10D7100001D10B2D6CE0554B9C4204D1022D00F041 -+:10D720000E810A2DCFE0444B9C4201D10B2D58E0D5 -+:10D73000424B9C4202D0424B9C4201D10B2D11E046 -+:10D740004B4B9C4202D04B4B9C4204D10D2D40F0E0 -+:10D7500007812E2004E1484B9C4206D10B2D00F09E -+:10D76000F2800D2D00F0F380FAE03E4B9C4258D041 -+:10D77000344B9C4204D10B2D40F0F2803E20EFE070 -+:10D78000314B9C4219D0314B9C4206D1022D00F006 -+:10D79000E4800A2D00F0E180E2E0384B9C4206D1A3 -+:10D7A000022D00F0D8800A2D00F0D580D8E0344B4F -+:10D7B0009C4202D0334B9C4206D1022D00F0C9801E -+:10D7C0000A2D00F0C680CBE02F4B9C420CD1022DDD -+:10D7D00000F0BD800A2D00F0BA80032D00F0BF805C -+:10D7E000092D00F0BC80BBE0284B9C4203D10A2DE0 -+:10D7F00000F0A780B4E0164B9C4205D1A5F10C03C4 -+:10D80000012B40F2A280ABE0214B9C4203D10B2DB7 -+:10D8100000F29D80A4E01F4B9C423DD10C2D00F0F6 -+:10D8200096800D2D75E0C046BC108600F010860075 -+:10D8300024118600400986002CDC0100BC0C860007 -+:10D84000D00C8600700D86007C0986009009860049 -+:10D85000840D8600DCDC010094DE0100340D8600BE -+:10D860005C0D860080118600FC0D860080DE0100C4 -+:10D87000E40C86000C0D8600FCE30100CC09860058 -+:10D88000A4098600B8098600F409860018098600F4 -+:10D89000980D8600381186008C4B9C4203D1022DD6 -+:10D8A00055D00A2D26E08A4B9C4231D0894B9C42B0 -+:10D8B00003D10B2D54D1322052E0874B9C4204D12E -+:10D8C0000B2D40D00C2D3AD04AE0844B9C4205D120 -+:10D8D0000C2D44D00D2D43D13A2041E0804B9C4289 -+:10D8E00004D1A5F10B03012B29D939E07D4B9C42D2 -+:10D8F00002D10B2D29D033E07B4B9C4205D10C2D5E -+:10D900002BD00D2D2CD144202AE0784B9C4227D1DE -+:10D910000B2D18D024E0332D01D800200BE03D2D35 -+:10D9200001D8012007E0632D01D8022003E0942DE7 -+:10D930008CBF04200320231893F9060010E04A202E -+:10D940000EE042200CE038200AE03C2008E04020B5 -+:10D9500006E0502004E0482002E04C2000E0462091 -+:10D96000CEEB000323EAE3736345B4BF1846604679 -+:10D97000022A04D199F800309842A8BF1846002224 -+:10D9800009EB02030132082A1871F9D1C0B2CC4662 -+:10D990004A4600210023013182F83430107382F8A6 -+:10D9A0003C3001320829F5D1337F13F0010202D057 -+:10D9B00097F9040106E097F90431182BD4BF1046FB -+:10D9C000A3F118003B68022B01D16B1E0FE0332D31 -+:10D9D00001D800230BE03D2D01D8012307E0632D82 -+:10D9E00001D8022303E0942D8CBF04230323F256B5 -+:10D9F0009B19997B3E4B9E4205D1A5F16403022BF6 -+:10DA000001D83E2110E03B4B49B29E4203D1642D28 -+:10DA100000F05C850BE0384B9E4205D1A5F1640314 -+:10DA2000022B01D83E2108E0344B9E420ED0344BED -+:10DA30009E420BD0334B9E4208D0334B9E4205D0C2 -+:10DA4000324B9E4202D0324B9E4214D1A5F1680364 -+:10DA5000242B10D82B4B9E421BD02B4B9E4218D010 -+:10DA60002B4B9E4215D0264B9E4223D0274B9E42E5 -+:10DA700020D044224A21274B9E420CD1A5F16803B5 -+:10DA8000202B03D98C2D00F03F8549E04422402112 -+:10DA900001E042224A21204B9E420DD1642D06D046 -+:10DAA000A5F168030C2B3BD840223C216CE04022BE -+:10DAB000342101E044210A46184B9E4230D1A5F1A1 -+:10DAC0006403102B2CD85222422160E068098600A2 -+:10DAD000DCDC0100B4DC010010DD010094DE01009B -+:10DAE00014E10100A8DE0100BCDE0100C8DC010079 -+:10DAF000B50886005BE30100D2088600DC058600DD -+:10DB00002E0586004B058600680586008505860083 -+:10DB100033068600F90586006D0686008A068600B3 -+:10DB20009C4B9E421AD1A5F16403082B98BF30216B -+:10DB3000A5F16E0398BF3422162B98BF4621A5F19C -+:10DB40008603022B98BF3E218C2D08BF3622A5F1FB -+:10DB5000950308BF48210F2B98BF44228E4B9E424D -+:10DB600012D1A5F16E03162BA5F1860398BF3A22B8 -+:10DB700098BF4421022B98BF3A2298BF3E218C2D9A -+:10DB800008BF362208BF4821844B9E4202D0844BF6 -+:10DB90009E4204D1A5F18403082B98BF2C22814B0F -+:10DBA0009E4202D1262D08BF2C21C0EB020323EA9E -+:10DBB000E377C0EB010323EAE37E4A4613790021B1 -+:10DBC000137582F8441009F1080301329A42F5D125 -+:10DBD0004B460A4601321F7783F84CE00133082A8E -+:10DBE000F8D1714B9E425BD0704B9E4258D0704B27 -+:10DBF0009E4255D06F4B9E4252D06F4B9E424FD0AB -+:10DC00006E4B9E4236D06E4B9E4249D06D4B9E422B -+:10DC100046D06D4B9E4243D06C4B9E4240D06C4BE5 -+:10DC20009E423DD06B4B9E423AD06B4B9E423DD0C4 -+:10DC30006A4B9E4234D06A4B9E4231D0694B9E4221 -+:10DC40002ED0694B9E422BD0684B9E4228D0684B09 -+:10DC50009E4225D0674B9E4222D0674B9E421FD0EA -+:10DC6000664B9E421CD0664B9E4219D0654B9E422D -+:10DC700016D052E0032D02D14FF03C0E0FE02B1FC7 -+:10DC8000042B0AD9092D00F04384A5F10C03012BC4 -+:10DC900000F217842C2700F015BC4FF0400E4027EF -+:10DCA0004D4B9E4202D04D4B9E4207D1EB1E082B9E -+:10DCB00094BF4FF0400E4FF0000E4027524B9E4253 -+:10DCC00022D1A5F124030C2B03D838274FF0300EB6 -+:10DCD0001AE0A5F13403082B03D84FF0440E774621 -+:10DCE00012E0A5F16403022B03D834274FF03E0E57 -+:10DCF0000AE0A5F16803202B03D844274FF04A0E11 -+:10DD000002E08C2D08BF32274B46002201321F75DE -+:10DD100083F844E00133082AF8D14B460022002161 -+:10DD2000013283F8241083F854100133082AF6D105 -+:10DD30004B460A46013283F82C7083F85CE00133CD -+:10DD4000082AF7D1184B89F864E09E4206D0174B99 -+:10DD50009E425BD0174B9E4270D0CEE0012D00F06A -+:10DD6000A780022D00F09980032D00F0A6802B1FC4 -+:10DD7000042B04D84C273C2338243E21A1E0092D54 -+:10DD800001D14C2750E00A2D00F087800B2D00F0C8 -+:10DD90008F808EE0A2058600BF0586002C078600D6 -+:10DDA000F40486002CE201007E0A86009B0A8600AD -+:10DDB000B80A8600F20A8600BD0B8600980E86001F -+:10DDC00040DC01006AE0010097DC010046DE010052 -+:10DDD00001DF0100E4DE0100630F860014108600FD -+:10DDE000B50E860024DD010041DD0100D2DD010019 -+:10DDF000EFDD01005DDC01007ADC01000CDE0100DA -+:10DE000029DE0100880C8600DC058600012D4FD03C -+:10DE1000022D44D0032D01D14C2743E02B1F042BAE -+:10DE20004BD9092D04D14A2734233024362148E028 -+:10DE30000A2D34D00B2D3CD136273AE0012D01D1EB -+:10DE40002C2736E0022D31D0EB1E052B18D8032DE0 -+:10DE500004D144272C2328242E2132E0042D20D065 -+:10DE6000082D1ED06B1F022B4FF044078CBF0023E0 -+:10DE700038238CBF002434248CBF00213A2120E0B9 -+:10DE8000092D04D142272E232A24302119E00A2DFE -+:10DE90000CD00B2D0DD12A270BE0402709E03E279F -+:10DEA00007E044273623322438210AE03C2700E0EB -+:10DEB000382700231C46194603E04C273823342416 -+:10DEC0003A214A460020042894BF82F84C4082F848 -+:10DED0004C300130177701320828F4D1FCB24A46A1 -+:10DEE0000020032894BF82F85C3082F85C10013077 -+:10DEF00082F82C4001320828F3D1A74B9E4206D06D -+:10DF0000A64B9E420DD0A64B9E4221D062E0032D2F -+:10DF100045D0092D43D02B1F042B38D83024342270 -+:10DF200033E0032D03D14224462248203AE0042D59 -+:10DF300031D06B1F022B03D84C245022522031E0E9 -+:10DF4000082D28D0092D22D13E244222442029E048 -+:10DF5000032D03D12E243022322023E0042D03D1BF -+:10DF60003024322234201DE06B1F022B03D83224D0 -+:10DF700036223A2016E0082D03D1302434223820EE -+:10DF800010E0092D03D12E24322236200AE000228F -+:10DF90001446104606E046244A224C2002E028247B -+:10DFA0002C222E204B460021042994BF83F84C409C -+:10DFB00083F84C20013101330829F5D14B4600216B -+:10DFC000032994BF83F85C2083F85C00013101339E -+:10DFD0000829F5D1734B9E422AD1032D0CD02B1F5B -+:10DFE000042B03D838203C213E2408E0092D03D01F -+:10DFF000002108460C4602E0342038213A244B46E2 -+:10E000000022042A94BF83F84C0083F84C1001329C -+:10E010000133082AF5D14B460022032A94BF83F826 -+:10E020005C1083F85C4001320133082AF5D134E0FA -+:10E030005D4B9E422AD1A5F124030C2B01D8382731 -+:10E0400004E0A5F134030C2B03D83A274FF0340E2B -+:10E0500012E0A5F16403282B03D83C274FF0400EB3 -+:10E060000AE0A5F19503102B8CBF002746278CBF33 -+:10E070004FF0000E4FF0480E4B46002201321F7544 -+:10E0800083F844E00133082AF8D10AE0474B9E4266 -+:10E0900069D0474B9E4200F0DF80464B9E4200F025 -+:10E0A000DB80454B9E4200F0D780444B9E4200F0FF -+:10E0B000D380434B9E4200F0CF80424B9E4200F003 -+:10E0C000CB80414B9E4200F0C780404B9E4200F007 -+:10E0D000C3803F4B9E4200F0BF803E4B9E4200F00B -+:10E0E000BB803D4B9E4200F0B7803C4B9E4200F00F -+:10E0F000B3803B4B9E4200F0AF803A4B9E4200F013 -+:10E10000AB80394B9E4200F0A780384B9E4200F016 -+:10E11000A380374B9E4200F09F80364B9E4200F01A -+:10E120009B80354B9E4200F09780344B9E4200F01E -+:10E13000F481334B9E4200F08F80324B9E4200F0C0 -+:10E140008E80314B9E4200F08780304B9E4200F023 -+:10E1500083802F4B9E427FD02E4B9E427CD02E4BF5 -+:10E160009E4271D0B5E0A5F12403082B02D84FF0F0 -+:10E17000380E67E0A5F12E03022B40F29880A5F13E -+:10E180003403082B01D8382792E0A5F13E03022B77 -+:10E1900044D8342747E0C046D50A8600A00B860045 -+:10E1A000DA0B86004E0C860011058600F905860004 -+:10E1B00049E2010066E20100A9E301001EDF01005F -+:10E1C0004DE0010013E0010098DD0100D8E00100FE -+:10E1D000F0DC0100F6DF0100F5E001008CE3010056 -+:10E1E00075DF010083E2010030E001000CDC01007A -+:10E1F000BCDF01005BE30100DCE3010063DE010042 -+:10E200005EDD01007BDD01003EE30100D9DF01009E -+:10E210003BDF010058DF010016068600A5F164030C -+:10E22000082B03D844274FF0380E49E0A5F16E03C0 -+:10E230001E2B01D832273BE0A5F19503102B36D9D0 -+:10E240004FF0000E77463BE0A5F124030C2B37D8A6 -+:10E2500038274FF0340E33E09E4B9E4201D1242DDF -+:10E260005CE19D4B9E4203D18C2D29D13A2727E0BA -+:10E270009A4B9E4204D1642D1FD08C2D1DD01FE0DF -+:10E28000974B9E4203D1A5F19503102B0DE0954BC2 -+:10E290009E4215D1A5F124030C2B10D9A5F134030E -+:10E2A0000C2B0CD9A5F16403282B08D908E04427CE -+:10E2B0004FF0400E04E0382702E0482700E03C27FA -+:10E2C0004B46002201321F7583F844E00133082ACF -+:10E2D000F8D1854B9E420BD0844B9E4208D0844B94 -+:10E2E0009E4205D0834B9E4202D0834B9E426DD10D -+:10E2F000A5F12403082B0DD87F4B9E4201D13A2073 -+:10E3000006E07E4B9E4202D13420014655E0342087 -+:10E31000382152E0A5F12E03022B08D8774B9E42FC -+:10E3200014BF3821342114BF4220402045E0A5F11C -+:10E330003403082B02D8462144203EE0A5F13E03D9 -+:10E34000022B06D86D4B3A219E4214BF34202C205C -+:10E3500033E0A5F16403082B06D8684B3E209E42AB -+:10E3600014BF44213A2128E0A5F16E031E2B17D8D3 -+:10E37000A5F18603022B09D85F4B9E4201D14420B0 -+:10E3800005E05E4B9E4201D13C2000E048208C2DF0 -+:10E3900010D1594B9E420FD0584B9E420CD009E0F1 -+:10E3A000A5F19503102B8CBF002146218CBF0020C6 -+:10E3B0004A2002E0442100E03C214B460022013289 -+:10E3C000197583F844000133082AF8D14C4B9E425A -+:10E3D00002D04C4B9E421ED1A5F124030C2B01D838 -+:10E3E00038210EE0A5F134030C2B09D9A5F1640303 -+:10E3F000282B05D9A5F19503102B01D9002100E0A8 -+:10E40000402108464B4600220132187583F844101B -+:10E410000133082AF8D14846002202EB090191F89D -+:10E420003C301BB990F84C3081F83C304AB999F82F -+:10E430003D300BB1013204E090F84C30012289F8F4 -+:10E440003D3001320130072AE7D94A46002192F8CF -+:10E4500044301BB992F84C3082F84430013101321B -+:10E460000829F4D14846002202EB090191F8343022 -+:10E470001BB990F8443081F834304AB999F83530F6 -+:10E480000BB1013204E090F84430012289F83530B4 -+:10E4900001320130072AE7D900229CF824301BB949 -+:10E4A0009CF81C308CF824309CF854301BB99CF834 -+:10E4B0004C308CF854300132082A0CF1010CECD1AC -+:10E4C0002FE040274FF0000EFFF7F8BB3822FFF790 -+:10E4D000ABBAC0467BDD01003EE301003BDF01003B -+:10E4E000F6DF01008CE301004B058600680586001D -+:10E4F0008505860033068600A2058600BF058600D6 -+:10E50000A70686005006860036210A46FFF708BB9C -+:10E5100040274FF0380EFFF7C3BB642D3FF4CBAE5E -+:10E52000CEE6BDE8F087C0462DE9F041069D0746DE -+:10E530000E4610461946002A4ED0002B4CD0002D16 -+:10E540004AD0B30A012B3FD914790EF031FEE40909 -+:10E5500001460023384622460FF046D895F8651547 -+:10E56000012911D195F86725531C0F2A85F86735C5 -+:10E5700032D90023C5F86865064685F8653585F803 -+:10E58000661585F8673527E095F8662532B90123C9 -+:10E59000114685F86635C5F8686513E0D5F8683525 -+:10E5A000F11A09D48B12012B06D995F86725531C53 -+:10E5B0000F2A85F8673505D9002385F86735C5F832 -+:10E5C000686519460E1807E0012385F86535013B9B -+:10E5D00085F8673585F866353046BDE8F081C04678 -+:10E5E0002DE9F3410A9D0B9E9846002304463360B3 -+:10E5F00017462B600846D9B18B784A781B0443EA4A -+:10E6000002230A781343CA78043143EA0263336071 -+:10E610008B784A781B0443EA022302791343CA78B1 -+:10E6200043EA02632B60427A037A53EA022001D163 -+:10E630004FF48060296832680EF0A2DE0C9B014620 -+:10E6400000933A4643462046FFF76EFF04463146A4 -+:10E650002846002223461CF04BDC0898099900222A -+:10E6600023461CF045DCBDE8FC81C046F0B50768D8 -+:10E670001C460E4687B019463846154617F07ADD17 -+:10E680002268D6F8A0309A4202D22B68013B2B6058 -+:10E69000D6F8A030002223600C9B384602930D9BD5 -+:10E6A000716E03931346009501940492FFF798FF4F -+:10E6B00007B0F0BD2DE9F04F8A460668002189B009 -+:10E6C000834690461F4689460D460791069105915F -+:10E6D000029103912BE063789D1C029B43B907AB29 -+:10E6E0000093304621462A4602233EF017DD029071 -+:10E6F000B9F1000F08D106AB0093304621462A46F7 -+:10E700000D233EF00BDD8146039B43B905AB00931F -+:10E71000304621462A4610233EF000DD0390C5EB2B -+:10E7200007031B1B03EB080704EB05080125404604 -+:10E730003946F4F3B7F504460028CCD1304607A992 -+:10E740003EF036D8304606A93EF032D8CDB1DAF8E0 -+:10E75000083043F04003CAF80830029B9BB1B9F17E -+:10E76000000F01D1039B73B1DBF810305AF803306E -+:10E770003BB9584651463DF0FFDE10B16FF01A002C -+:10E7800003E0002001E04FF0FF3009B0BDE8F08F5A -+:10E790002DE9704F066886B08B46104619469046A4 -+:10E7A0009A460F9C109D0EF003FD014630460EF078 -+:10E7B000F9DE41468146224630462B4617F002DDFF -+:10E7C0002046294600224B461CF078DB119B304640 -+:10E7D0000293129B0E99039342465346009401956F -+:10E7E000CDF810B0FFF7FCFE06B0BDE8708FC04654 -+:10E7F00043682DE9F04106460C4617460568F3B11B -+:10E8000099421CD12B681B7E73B1284691F8F412F3 -+:10E8100004F1C2021AF00ADE7368212293F8F4129E -+:10E82000284613461AF00CDEF37B022B07D13B6817 -+:10E830002BB9384606F114012422F3F39DF3BDE809 -+:10E84000F081C0462DE9F7430A9C0B9D0F46814697 -+:10E85000164698460094019540F00ED94346484626 -+:10E86000394632460094019540F0F4D901224846D9 -+:10E87000394640F0D7D9B7F8343513F0100F03D02C -+:10E88000484639463EF008D8BDE8FE8370B58B791E -+:10E8900006461546002B2DD0D1F8CC3013F4005F7E -+:10E8A00028D0107828B15378092B02D86FF00100D6 -+:10E8B00024E0D1F8F042237F834204D1E8B1627FA3 -+:10E8C0006B789A4219D020776B786377638843F02E -+:10E8D000020313F0080F63800FD0304621463EF04C -+:10E8E00063DD304621463EF043D9304621463EF0B6 -+:10E8F000BBDE02E04FF0FF3000E0002070BDC046FC -+:10E900002DE9F743D0F8009004460027E31993F867 -+:10E910003B80B8F1FF0F4CD0FD0000262046294671 -+:10E9200041F06ED9002840D020462946002241F00F -+:10E9300085DE4846414601AA30F0A0DC002834D0EC -+:10E94000D0F8F01221B9002E2FD10EF059D92CE0B9 -+:10E95000837933B1D0F8CC3013F4005F01D0037960 -+:10E960001BB34B8813F0080F1FD0032E1DD8DFE810 -+:10E9700006F002060F1620463EF0C8DE15E013F042 -+:10E98000020F12D00B7F83B120463EF0FBD80CE083 -+:10E9900013F0010F09D020463DF0AEDF05E013F083 -+:10E9A000010F02D020463FF035DA01360235042E41 -+:10E9B000B4D10137042FA9D1BDE8FE832DE9F3417D -+:10E9C000D0F8008007463EF021D9AE21404617F02E -+:10E9D000C7DB4000B8641421404617F0C1DB262491 -+:10E9E000A7F84C0021464046284A1AF01FDD214670 -+:10E9F000002340464FF6FF7201341AF021DD322C1D -+:10EA0000F0D126E0294600223846013441F016DED6 -+:10EA100002350C2CF6D118369A2E1BD11DE0294652 -+:10EA200000223846013441F009DE0235042CF6D1CB -+:10EA30000836202E12D114E029460022384601342F -+:10EA400041F0FCDD0235042CF6D10836BA2E09D18E -+:10EA50000BE03A2635460024D4E70026354600244C -+:10EA6000DDE79A2635460024E6E7384620210022D5 -+:10EA700041F0E4DD032310220093404604211346B5 -+:10EA800015F0A2D80020BDE8FC81C046329E85006A -+:10EA9000F0B50E4649691569908A0A68002A01DABC -+:10EAA000821831D44C68131983422DD8B36801F110 -+:10EAB000080C0CEB040705EB020E6BB9184608E0D6 -+:10EAC00010F80E3010F80C20C15D134099421BD194 -+:10EAD0000130A042F4DB19E0012B15D12B18C4EB57 -+:10EAE00003050DE010F80E3010F80C20C15D134046 -+:10EAF000994203D10130A042F4DB07E00EF1010E90 -+:10EB0000AE4501D80020F6E7002000E00120337B6D -+:10EB10000BB180F00100F0BD036870B50446586881 -+:10EB2000A36A0D46164623B99021F8F3D1F0A062EE -+:10EB300070B1A06A0123AA8A03607F3382604660B5 -+:10EB4000C360296910309A4228BF1A46F3F314F2C1 -+:10EB500070BDC04668468369416920300BB52038D6 -+:10EB600003695A4651460EB44A46414606B4C36844 -+:10EB700082684168FEB40368C269EFF303810EB492 -+:10EB80008269EFF3058106B4034801680029FED0CD -+:10EB90006846884714B000BD3CEC00000A490842B2 -+:10EBA00002D062B6C94308400849084202D061B6A3 -+:10EBB000C943084006490840002803D005490A68AF -+:10EBC00002430A607047000000000080000000401F -+:10EBD000FFFF000000E100E00A49084202D072B6DF -+:10EBE000C94308400849084202D071B6C9430840E9 -+:10EBF00006490840002804D005490A68C04302407D -+:10EC00000A6070470000008000000040FFFF000025 -+:10EC100080E100E0024909689022885870470000AE -+:10EC200048EC0000024909689C22885070470000A7 -+:10EC300048EC0000DDBAADBB0000000000000000A1 -+:10EC400000000000000000000000000000000000C4 -+:10EC50000000000000000000024A11681060081C5B -+:10EC6000704700003CEC0000024A11681060081C6C -+:10EC70007047000040EC0000034908600348016849 -+:10EC80000029FED08847FEE734EC000040EC00008D -+:10EC90006348644900220A500168634A0A40634F8E -+:10ECA0000F403F4232D1002398469A46604A0A40BC -+:10ECB0001821CA405F4943585F4C1C405F4DAC422D -+:10ECC00004D180465E4D4519A9460EE05D4DAC422B -+:10ECD0000BD182465A4D4519AB460F241D1C2340CB -+:10ECE000594C25402D0A2B439C460023984501D0C2 -+:10ECF0009A4504D1554BC018013ADCD105E0504685 -+:10ED0000004202D04046004229D1FEE7FC21415892 -+:10ED10000A680F2313400F2BF1D0012B01D00431CF -+:10ED2000F6E708314A4B13404A4CA34206D100F0A3 -+:10ED3000BBF8804600F0C4F88146E9E7464CA342A0 -+:10ED4000E6D10B1F1B68454C23401824E3409C462A -+:10ED500000F0AAF8824600F0B3F88346D8E74049AD -+:10ED6000212242502E4A3F498958FF23194219D087 -+:10ED700051683D4B194215D011683C4B1940D36A7C -+:10ED800010E0A3420ED0C0460CE039498958194220 -+:10ED900008D03849895819409942FAD12B4B11694A -+:10EDA0001942FCD049463F4204D19823CB58102445 -+:10EDB000E34001E0304BCB581C242340002B01D012 -+:10EDC00000F08CF840462D49086048462C49086000 -+:10EDD00050462C49086060462B4908602B490F605B -+:10EDE0002B4D2C490D60043DAD46009DEC43102396 -+:10EDF000DD41AC4201D081B009E0240CA400264DD5 -+:10EE00002C606B461B1B254D2B60043B9D46244804 -+:10EE10002449002204C08142FCD80EF0E5FAFEE746 -+:10EE20000000001814060000F8FF0000000000F0C9 -+:10EE30000000000FFC0F0000F08F0000A082000017 -+:10EE4000000F0000E08000000070000000100000D3 -+:10EE500000FF0F00002A0800000E0800000000FF5D -+:10EE6000E00100000406000000003800FFFF000081 -+:10EE7000180600000C0600000804000048EC000022 -+:10EE80004CEC000050EC000054EC000044EC00009E -+:10EE900000C00300F81E0200001F0200FC1E02005A -+:10EEA000AC270200182C020008680F22043102402F -+:10EEB000052AF9D1014A1040F746000000F0FFFF93 -+:10EEC00008680F2204310240052AF9D1802210423D -+:10EED000F6D0014A1040F74600F0FFFFFEE70000C1 -+:10EEE00010B57146034802F0DFFB40F61100FFF752 -+:10EEF000C3FE10BD8E1F860010B5002128220446D7 -+:10EF0000F3F39EF00A4B23600A4B63600A4BA36045 -+:10EF10000A4BE3600A4B23610A4B63610A4BA3610E -+:10EF20000A4BE3610A4B23620A4B636210BDC04681 -+:10EF300000000000C71D0200C81D0200AC2702002F -+:10EF4000AC270200182C0200182C020021D202006B -+:10EF500024D20200005903002DE9F04399B00CA817 -+:10EF6000FFF7CAFF0C9B0D99DFF8DC91C91A0F9DC2 -+:10EF70000E9BD9F80060ED1A119C109B06F5A05667 -+:10EF80006048E41A76180B9102F08EFB0B9905F598 -+:10EF90007E7376190733361901F57E729B0A019448 -+:10EFA00004F57E740732009307340523A40A920AFD -+:10EFB000039355482B460294DFF8848102F074FBDA -+:10EFC000524BD8F800401968D9F80050C4EB01033F -+:10EFD00003F57E7001F57E7207300194039504F508 -+:10EFE0007E7405F57E75800A073207340735920A6C -+:10EFF0000090A40AAD0A46480294049502F054FB1E -+:10F00000444B45481968D8F80030C91806F57E7396 -+:10F0100001F57E7207339B0A0732920A009333464A -+:10F0200002F042FB3D4B3E48196802F03DFB3D4B70 -+:10F030001F683D4B3A689A4203D03C4802F034FBCB -+:10F0400024E0179705E03268374B9A4205D1331D0B -+:10F050001793179E16AB9E42F5D3354BC7EB0600B0 -+:10F060001A6817ABC7EB0301C3EB0204C6EB02053A -+:10F070000092019102910390049039462D48324646 -+:10F08000059406940795089502F00EFB2A4C20681B -+:10F09000002834D0C588F3F363F52368013D5C890B -+:10F0A0004FF4806104FB05F6443405FB04F406F5D7 -+:10F0B0007E73073393FBF1F3009304F57E730733FC -+:10F0C00093FBF1F302460293294633461B48019411 -+:10F0D00002F0EAFA1A4B0F4A1B681268C6EB0306E5 -+:10F0E0009B181B1B03F57E7106F57E720731890A9A -+:10F0F0000732009113483146920A02F0D5FA19B04E -+:10F10000BDE8F083E11F8600F01F8600C8260000DE -+:10F110002E208600A4260000722086009026000083 -+:10F12000AC208600F82702004B415453C6208600CD -+:10F13000FC270200E9208600BC260000662186002C -+:10F140008826000092218600CC2600000D4B10B5C9 -+:10F150001A680D4CD2F81416D2F8143699420B4B9B -+:10F1600018BFD2F8141622681B68C2EB010098423F -+:10F1700001D2002004E0B0FBF3F003FB0023236086 -+:10F1800010BDC0469C260000E4260000C8250000F3 -+:10F190002DE9F04301688FB0022907461AD15A4B76 -+:10F1A0005A481A6800235361046814F4805F11D030 -+:10F1B000574B584A1960C169043B1960136804230E -+:10F1C000136024F4805343F400530360524802F068 -+:10F1D0006BFA96E03B680C2B14D14C4C236813F46B -+:10F1E000005F0FD023F4005343F400632360676093 -+:10F1F0004A48F96C02F058FA236803F40063002BC4 -+:10F20000FDD17EE03B68103B0F2B02D8F7F3E2F014 -+:10F2100077E03E4B4248D96902F046FABA6C786C06 -+:10F22000BC68FD683968FB6C009201903A463D4825 -+:10F230000294039502F038FA3B4B7E6C1B68F86928 -+:10F24000D7F828E03C6A7D6A9B1B39697A694FEAE6 -+:10F250009309BB6900903548CDF80CE00194029504 -+:10F2600002F022FAB86BFC6B3D6CF96A3A6B7B6B6F -+:10F2700000902F480194029502F016FAF068316868 -+:10F280007268B36800902B4802F00EFAF069316999 -+:10F290007269B3690090284802F006FA04A8FFF7E3 -+:10F2A0002BFE264802F000FA0024A04625461CE06A -+:10F2B000725912F0010F13D0FF2A11D9059B9A42FF -+:10F2C00008D91F4B1B0D1B059A4209D303F5801368 -+:10F2D0009A4205D81B48294602F0E6F908F10108D0 -+:10F2E0000435B8F10F0F02D801344C45E0D1074A7C -+:10F2F00040F203301368576043F480631360FFF7F4 -+:10F30000BBFC0FB0BDE8F0837428020000280200A7 -+:10F31000241000E0281000E0C4E50100C8E5010069 -+:10F32000D4E50100E1E50100F81E020015E6010048 -+:10F3300048E6010077E6010095E60100FC1C860026 -+:10F340009D668000B2E60100F0B51F4E8BB06846A6 -+:10F35000FFF7D2FD3578F5B90698079B1C1A07D040 -+:10F3600029462246F2F36CF606982146F6F358F742 -+:10F370002146164802F098F9154B1D700123337091 -+:10F38000144B1968E9B10B78DBB1134B2A461868A6 -+:10F39000F3F34AF415E0114F3D7895B90898099BAD -+:10F3A0001C1A07D029462246F2F34AF6089821464D -+:10F3B000F6F336F70A48214602F076F90123357054 -+:10F3C0003B700BB0F0BDC0463C280200C9E601000E -+:10F3D0003E280200BC260000242802003D2802002E -+:10F3E000FBE6010010B50446FBF384F60146204617 -+:10F3F00000F034F910BDC04670B50446FBF37AF650 -+:10F400002046FBF3B7F505462046FBF337F500220F -+:10F41000064640F62A012046FBF3F0F60123AB40F6 -+:10F420008269134201D0002500E0013520463146B3 -+:10F43000FBF3F6F6284670BD10B5FFF7DDFF10BDF3 -+:10F440002DE9F04107460C46FBF354F63846FBF332 -+:10F4500015F540F62A01804600223846FBF3CEF629 -+:10F4600083690646456944B14FF4004043F00044C7 -+:10F4700045F00045FFF792FB07E04FF4004023F012 -+:10F48000004425F00045FFF7A7FBB46138467561DD -+:10F490004146FBF3C5F6BDE8F081C0462DE9F041D9 -+:10F4A0000E465021804617461D46F7F311F40446D8 -+:10F4B00018B300215022F2F3C3F540F23C736363AA -+:10F4C000A3F55573E363A3F5737323640C2363649B -+:10F4D00004230020E56026606760C4F80880A36408 -+:10F4E0000749F3F349F2C0B284F84C000138C0B2C6 -+:10F4F000012802D9022384F84C302046BDE8F0816F -+:10F500003E2986000048704718F9010000487047FE -+:10F5100090F901000048704700A60E00D2F80036AE -+:10F5200070B50546C3F38404FFF7ECFF03E083786E -+:10F53000A34204D00C3020B10388002BF7D10388FC -+:10F5400013B92846FFF7E2FF03884FF47A7003FBF4 -+:10F5500000F070BD0123C2F8603610B5D2F86446E1 -+:10F56000FFF7D8FF04F0FF04B0FBF4F34FF47A7018 -+:10F5700003FB00F010BDC0462DE9F0411C460646D5 -+:10F580001546FBF37BF4002107463046FBF348F6B3 -+:10F590000223C0F8583654B1D0F85C3605F03F026B -+:10F5A00023F4FC4343EA4223C0F85C3603E0D0F87E -+:10F5B0005C36C3F3452530463946FBF331F6284621 -+:10F5C000BDE8F0812DE9F041DFF860800646D8F80B -+:10F5D000004034BBFBF352F4214607463046FBF3B0 -+:10F5E0001FF6D0F81456D0F8143604469D4218BFC2 -+:10F5F000D0F8145642F21070F7F3AEF0D4F8142697 -+:10F60000D4F8143630469A4218BFD4F81426394636 -+:10F61000C5EB0203642203FB02F3C8F80030FBF3DE -+:10F62000FFF5024B1868BDE8F081C046842802004F -+:10F6300070B504460D46FBF321F400210646204632 -+:10F64000FBF3EEF5294602462046FFF783FF3146DD -+:10F6500005462046FBF3E4F5284670BD10B5FFF7DC -+:10F66000E7FF10BD70B504460D46FBF307F400211B -+:10F6700006462046FBF3D4F5294602462046FFF70E -+:10F680004DFF314605462046FBF3CAF5284670BDBE -+:10F690002DE9F04F1746C7F820361D46036A85B09E -+:10F6A0000C2BCBBFD2F82836D2F82836C3F3094B3F -+:10F6B000C3F3072B01230024AB4080468946029404 -+:10F6C00003940094F6F30AF30646012212FA04F3B7 -+:10F6D000334207D00092404649463A46F6F3FEF2DE -+:10F6E00026EA000601341F2CEFD1404603A902AAE6 -+:10F6F000F6F31EF3039B00256FEA030A2C46012351 -+:10F70000A34006EA0A021A4208D0404649463A4651 -+:10F71000E3B2FFF7BDFF854238BF054601341F2C19 -+:10F72000EDD10BF10200401905B0BDE8F08FC046E5 -+:10F730002DE9704305468846FBF3A0F3002181467E -+:10F740002846FBF36DF50446284600F0F3F8224600 -+:10F750000646414618232846FFF79AFF0B2302303E -+:10F7600000FB03F0074C49463419B4FBF6F404FBE4 -+:10F7700000F42846FBF354F50A23B4FBF3F4A0B2DB -+:10F78000BDE870833F420F0073B5044616461D4620 -+:10F7900000914FF4CB6200214FF0FF33FBF376F37F -+:10F7A0002046002140F25C6233460095FBF36EF385 -+:10F7B0007CBDC046002270B513460C4604210546A8 -+:10F7C000FFF7E2FF012C20F0F07308BF43F0F07365 -+:10F7D000284604214FF0FF32FFF7D6FF012C03D15A -+:10F7E00049F64040F6F3B8F770BDC04610B50021A9 -+:10F7F000FFF7E0FF10BDC04610B50121FFF7DAFFAB -+:10F8000010BDC04610B508B1F6F366F510BDC04690 -+:10F8100070B5094B06461D6808E030462C68FBF3BE -+:10F8200069F429466A68F7F363F22546002DF4D19E -+:10F83000014B1D6070BDC0466C270000002343666D -+:10F840007047C0467047C0460020704710B5FFF7AC -+:10F85000D3FF10BD10B5FFF7C9FF10BD2DE9F04172 -+:10F8600006460D461446FBF30DF4804618B93046A3 -+:10F870000121FBF345F4304613F032FA074610B984 -+:10F880006FF01D0415E014B96FF0190418E04FF083 -+:10F8900000032B80002404F182013846F2F34AF27F -+:10F8A000C0B2A0402B8801341843052C2880F2D127 -+:10F8B0000024B8F1000F03D130464146FBF320F499 -+:10F8C0002046BDE8F081C04607B54FF0000302A90D -+:10F8D00021F8023D0122FFF7C1FFBDF806000EBD71 -+:10F8E000416E2DE9F041044661B1D0F8C83000EB1B -+:10F8F0008303D3F8D020C36D9A4203D1006E8847AA -+:10F90000064600E000262046616DFFF711FFA56E58 -+:10F9100007465DB1D4F8C83004EB8303D3F8D02098 -+:10F92000E36D9A4202D1206E3146A8473846BDE8C1 -+:10F93000F081C04610B50446FBF3DCF301462046D7 -+:10F94000FFF740FE10BDC04610B50446FBF3D2F3EE -+:10F9500001462046FFF786FE10BDC046416E2DE9E8 -+:10F96000F041044661B1D0F8C83000EB8303D3F80E -+:10F97000D020C36D9A4203D1006E8847064600E04E -+:10F9800000262046616DFFF753FEA56E07465DB168 -+:10F99000D4F8C83004EB8303D3F8D020E36D9A4247 -+:10F9A00002D1206E3146A8473846BDE8F081C046F6 -+:10F9B00043692DE9F743222B06460F4640F3A0800A -+:10F9C000FBF314F4002800F09B80072F00F29880CE -+:10F9D000B268B2F5026F01D101220AE040F60403D9 -+:10F9E0009A4201D0002204E0F3680C2B94BF00225D -+:10F9F00001225FFA82F8B8F1000F0BD130464FF4C4 -+:10FA000000614246D6F8C890FBF3F8F3054600289B -+:10FA100077D006E0D6F8843013F5405571D04FF01A -+:10FA20000009032F03D030460121FBF379F4D5F808 -+:10FA3000303123F00403C5F8303101239F42C5F86B -+:10FA4000303103D9042F01D0083300E00D23C5F86D -+:10FA50003031D5F83031012F23F00103C5F83031B2 -+:10FA600001D9042F36D1FF2400214FF4E27223463E -+:10FA700030460094FBF30AF22223009300214FF456 -+:10FA8000EE7223463046FBF301F228230093002157 -+:10FA90004FF4E67223463046FBF3F8F181230093DE -+:10FAA00000214FF4E87223463046FBF3EFF10123C7 -+:10FAB000009300214FF4A4724FF0FF333046FBF364 -+:10FAC000E5F1304600214FF4A6724FF6FF73009423 -+:10FAD000FBF3DCF1D5F8303123F0700343EA071370 -+:10FAE000C5F83031D5F8303123F00803C5F830318E -+:10FAF000B8F1000F05D130464946FBF391F300E021 -+:10FB000000252846BDE8FE8370B50446FBF36EF37E -+:10FB1000002839D0A268B2F5026F01D101220AE0B3 -+:10FB200040F604039A4201D0002204E0E3680C2B63 -+:10FB300094BF00220122D5B24DB920464FF4006196 -+:10FB40002A46D4F8C860FBF359F3E8B105E0D4F8CD -+:10FB5000843013F5405017D00026D0F8303123F010 -+:10FB60000403C0F8303143F00103C0F83031C3F36F -+:10FB70000213032B03D020460021FBF3D1F31DB960 -+:10FB800020463146FBF34CF370BDC0462DE977416A -+:10FB90000022012113460546F6F352F10024804667 -+:10FBA00021462822234628460094FBF36FF10121C9 -+:10FBB0000646434628464FF0FF32F6F341F1284609 -+:10FBC000214628224FF0FF330096FBF35FF1BDE89A -+:10FBD0007E81C046D0F86C32994201D0002004E00A -+:10FBE0008B79D3F1010038BF002070472DE9F04137 -+:10FBF000002605460446374608E02B68216A9868C7 -+:10FC0000FFF32CF500B90136013718346B689F42B9 -+:10FC1000F3DB3046BDE8F08103682DE9F0411E6852 -+:10FC20000546B7688846144638462969FFF316F535 -+:10FC300044B133681B7E2BB1384629694246012303 -+:10FC4000FFF3C4F4BDE8F08170B505460446002614 -+:10FC50000DE0616949B1236A3BB1182006FB00F051 -+:10FC6000103028180122FFF7D7FF013618346B68CF -+:10FC70009E42EEDB002070BD2DE9F3411F46036874 -+:10FC8000044601910092DDF820801E6809B10D291B -+:10FC900041DD61680022FFF7BFFFE1680025656074 -+:10FCA00031B1236822891B685868F7F321F0E560B9 -+:10FCB000009B2BB1B3F5967F02DA6FF01C002CE0AD -+:10FCC00030464146FFF786FF28B3019969B12368A2 -+:10FCD0001B685868F6F3FCF7E06010B96FF01A0083 -+:10FCE0001BE03946019AF2F347F101A90422C4F856 -+:10FCF000148004F10800F2F33FF1201D694604224C -+:10FD0000F2F33AF1009840B1204661680122FFF712 -+:10FD100083FF002001E06FF00100BDE8FC81C046D8 -+:10FD20002DE9F047154686B00268DDF84080DDF821 -+:10FD300044A005F00103009306465346106842466E -+:10FD4000DDF84C9013F0C0DA0746002840F0A1809F -+:10FD5000022D54D0032D1FD0012D02D06FF01607B5 -+:10FD600097E04146042203A8F2F306F1022208F1CB -+:10FD700004010DF11600F2F3FFF056F8100B49469E -+:10FD8000BDF81640039D2FF035DB214600902A4632 -+:10FD9000304608F106032EE00222414605A8F2F3A0 -+:10FDA000EBF0042208F1040103A8F2F3E5F00222CB -+:10FDB0000DF1160008F10801F2F3DEF0BDF8143081 -+:10FDC000012B02D06FF0240763E098F80A70736883 -+:10FDD0009F425CDA49463068BDF81640039D2FF01B -+:10FDE00009DB182307FB03F3103300902146F018BA -+:10FDF0002A4608F10B03FFF73FFF074649E00E9B39 -+:10FE00001A6873689A4242DA002A40DB4FF0010315 -+:10FE1000ADF8143004924FF00B030DF116012A4691 -+:10FE200008F10200ADF81630F2F3A6F005A92A4653 -+:10FE30004046F2F3A1F004991824013101FB04615A -+:10FE40002A4608F10800F2F397F0012204A908F10C -+:10FE50000A00F2F391F00499042201FB046108F115 -+:10FE600004001431F2F388F0049B013303FB04F324 -+:10FE70009A5B991902F10B039A4502D26FF00D07B4 -+:10FE800007E008F10B004968F2F376F001E06FF04B -+:10FE90000107384606B0BDE8F087C046F7B50168EF -+:10FEA00005460E6896F87032002B2CD002894769FF -+:10FEB0003AB9304607F1BC011346009218F0D0D889 -+:10FEC00021E0898970688918F6F35AF72A68044690 -+:10FED00018B993680133936015E09289A38A006989 -+:10FEE0009B1A8018A382E9682A892061F2F344F002 -+:10FEF00004F124025389304643F0400353812146E4 -+:10FF0000BA6818F04FD9FEBD13B54FF0000310F0DA -+:10FF10000104ADF8063006D0002904DD10F8013BDD -+:10FF200001398DF8073010F0030F05D0012903DDEA -+:10FF300030F8022B023913E0002211E00368D218D6 -+:10FF4000436828BF0132D218836828BF0132D21813 -+:10FF5000C36828BF0132D21828BF013210301039CF -+:10FF600031F00F03EAD113041B0C03EB124203E040 -+:10FF700030F8023C0239D218034602300129F7DC7E -+:10FF800004BF1B788DF80630BDF80630D3181A046C -+:10FF9000120C02EB134213041B0C03EB124024B1AE -+:10FFA000030243EA10231804000C1CBD10B5FFF730 -+:10FFB000ABFF02E003041B0C9818020CFAD1C043FB -+:10FFC00080B210BD2DE9F041BDF818500C4629460D -+:10FFD00016469846FFF798FF3204120C02EB1442C3 -+:10FFE0002404240C121905F0FF0302EB16421B0235 -+:10FFF00002EB082243EA1523D218101802E003048A -+:020000021000EC -+:100000001B0C9818020CFAD1C04380B2BDE8F081F5 -+:100010002DE9F0418D8A16460D2D1F460C6952DDE3 -+:10002000A38904F10C0003F0FF021B0A43EA022338 -+:10003000B3F5C06F0BD2152D45DD254804F10E0137 -+:100040000622F1F37DF700283DD104F11400038866 -+:1000500003F0FF021B0A43EA0223B3F5014F0AD162 -+:100060000430821C63199A422DD8038803F0FF02E2 -+:100070001B0A43EA0223B3F5006F24D1811CC4EBB1 -+:100080000103C3EB0504132C1DDD82781309042B37 -+:1000900019D102F00F039A00132A14D9A24212DCDC -+:1000A0008A78CB7843EA0223A34201DA1C4600E0B7 -+:1000B00009DC8A79CB7943EA02239804800C10B9D1 -+:1000C00031603C6001E04FF0FF30BDE8F081C04698 -+:1000D00035FA01002DE9F043436887B013F0020FB1 -+:1000E0000546884600F08F8005AA04ABFFF790FF15 -+:1000F0000028C0F288800598037803F00F039E0063 -+:100100003146FFF753FF48B1B8F8163023F010031B -+:10011000A8F816302B6A01332B6274E0EB69059F57 -+:100120000133EB6197F80990B9F1060F24D107F17B -+:100130000C01042202A8049CF1F31EF70599042285 -+:100140001031A41B03A8F1F317F7A4B2B819029950 -+:10015000039A4B460094FFF735FF48B1B8F81630C4 -+:1001600023F01003A8F81630AB6A0133AB624AE003 -+:100170006B6A01336B623EE0B9F1110F24D107F1D4 -+:100180000C01042203A8049CF1F3F6F6059904225D -+:100190001031A41B02A8F1F3EFF6A4B2B819039929 -+:1001A000029A4B460094FFF70DFF48B1B8F816309D -+:1001B00023F01003A8F816302B6B01332B6322E0D9 -+:1001C000EB6A0133EB6216E0B9F1010F13D1049928 -+:1001D000B819891B89B2FFF7E9FE48B1B8F81630A3 -+:1001E00023F01003A8F81630AB6B0133AB630AE0C1 -+:1001F0006B6B01336B63B8F81630002043F01003CB -+:10020000A8F8163001E04FF0FF3007B0BDE8F083EA -+:100210002DE9F043436887B013F0010F804600F0EA -+:100220008780CB8A13F0080F03D183680133836082 -+:100230007EE005AA04ABFFF7EBFE002878DB059A09 -+:1002400000271378977203F00F039E00D772314690 -+:100250000598FFF7ABFE059B9872C0F30F20D8728C -+:10026000D8F80C3005990133C8F80C3091F8099092 -+:10027000B9F1060F21D18D19049C0C3104222F7481 -+:100280006F7402A8F1F378F6059904221031A41BCB -+:1002900003A8F1F371F6A4B24B4628460299039ADB -+:1002A0000094FFF78FFE2874C0F30F206874D8F80D -+:1002B00010300133C8F810303AE0B9F1110F22D1F3 -+:1002C0008D19049CAF71EF71059904220C3103A8BC -+:1002D000F1F352F6059904221031A41B02A8F1F3A0 -+:1002E0004BF6A4B24B4628460399029A0094FFF7B6 -+:1002F00069FEA871C0F30F20E871D8F814300133FB -+:10030000C8F8143014E0B9F1010F11D18C19049917 -+:100310002046891BA770E77089B2FFF747FEA070DF -+:10032000C0F30F20E070D8F818300133C8F8183047 -+:1003300007B0BDE8F083C0462DE9F34114460A9F9B -+:100340000268DDF82C8004F0010300930546434663 -+:1003500010683A4612F0B8DF064618BB052C04D8E0 -+:10036000DFE804F00A061403030D6FF0160619E027 -+:10037000281D3946042213E06B683B6012E005F14A -+:10038000080000214C22F1F35BF60BE0B8F14B0FB3 -+:1003900002D86FF00D0605E0384605F108014C2241 -+:1003A000F1F3EAF53046BDE8FC81C04610B58C6B30 -+:1003B00000200BE00B1893F83C30064A03F07F0353 -+:1003C000D356002B01DA012003E00130A042F1D125 -+:1003D000002010BD401B86002DE9F84F02298346FE -+:1003E0000E4690469A4614BF4FF0FF37002714BFC1 -+:1003F000002401244FF000092EE0022E14BF4FF01C -+:10040000FF3300239F4211D0022E08D1B8F1040F10 -+:1004100007D0B8F1060F04D0B8F1080F01D00422BC -+:1004200000E00022C7EB0403934214DD0E2CCCBF86 -+:100430004FF480534FF4005344F4306213439DB2A1 -+:10044000DBF85C01294635F0A9DF20B12AF8195004 -+:10045000274609F101090134022E0CBF0E230023A7 -+:100460009C4202DCB9F11F0FC7D90A9BC3F8009068 -+:10047000BDE8F88F2DE9F04F88469BB0402100275A -+:10048000DDF890B09DF894900646C0F82077C0F84B -+:100490001C1740689A46F6F31BF40446C6F8180782 -+:1004A00010B96FF0150473E0D8F800306BB9203341 -+:1004B000C6F82037336B30461A8906F5E46300939B -+:1004C00059462346FFF788FF1FE0202B6CD845468E -+:1004D00017E0AC88D6F85C01214635F05FDF0028D4 -+:1004E00062D01FB12B78E2B29A425DD9D6F820379C -+:1004F000D6F81827013722F813400133C6F8203701 -+:100500000435D8F800309F42E3D3D6F82037002BCB -+:100510004AD070681021F6F3DBF30746002835D087 -+:10052000279B002411AD446083600473214606605C -+:1005300080F80DB080F80E9024222846F1F380F563 -+:10054000A24514BF0023012301934FF0FF33029310 -+:10055000039304930593D6F8183730460693D6F8DC -+:10056000203702210793144B144A0A9303230C9358 -+:100570000123089409940D940E9400950B9716F09E -+:10058000BBDC044698B9269B7B6010E06FF01A0430 -+:10059000D6F8181759B17068D6F81C27F6F3A8F3E7 -+:1005A0000023C6F8183702E06FF00104F0E7204698 -+:1005B0001BB0BDE8F08FC046410B01002C9E8500AA -+:1005C00030B590F8143789B00446002B3ED0D0F8EF -+:1005D00068319D79002D62D1036880F814571B7E25 -+:1005E000002B5CD0B0F81637002B58D0036B18697D -+:1005F00002F09CFAB4F81617884250D0204618F042 -+:10060000CFDB204601F0EEF82046B4F8161718F0BC -+:100610000DDA236893F82F306BB1D4F86C32204692 -+:10062000D3F8D412383113F0B9D80146C4F8AC0667 -+:1006300020460CF051D920461AF068DC20462946A5 -+:100640001AF06EDE204611F0DBDC28E003681B7E2A -+:100650002BB3D0F868319B790BBBD0F8000507A904 -+:1006600044F038DD03E02B7E13F0020F17D107A80A -+:1006700044F038DD05460028F5D1236B05901B6852 -+:1006800005A90093032301930290039001222046C1 -+:100690002B46FFF7EFFE10B9012384F8143709B099 -+:1006A00030BDC0462DE9F74F0192D0F800A090F878 -+:1006B0000D801F460C464FF0000BE5E0072200219D -+:1006C0002046F1F3BDF40C9AB8F1020F12F81B00AA -+:1006D000207001D0022308E0042F05D0062F03D09C -+:1006E000082F01D0434600E00023C3EB0002B8F11D -+:1006F000020F14BF002301239A4210DBB8F1020F4E -+:1007000001D0022108E0042F05D0062F03D0082FC6 -+:1007100001D0414600E00021C1EB00060FE0B8F136 -+:10072000020F14BF0026012606E0DAF85C0131460C -+:1007300035F0F2DD18B9013623789E42F5D9B8F1CB -+:10074000020F207802D0002202230BE0042F07D0F2 -+:10075000062F00F0A680082F00F0A3804346A1E0FA -+:100760000E2200231B1893420FDCB8F1020F01D0B8 -+:10077000022108E0042F05D0062F03D0082F01D056 -+:10078000414600E000210D180FE0B8F1020F0CBF48 -+:100790000E25002506E0DAF85C01294635F0BCDDBF -+:1007A00018B9013D23789D42F5D24FF0000963E06E -+:1007B00002EB89039968CB88B1F832E013F020038B -+:1007C0005FFA8EF00DD00EF44072B2F5807F02D148 -+:1007D000821C023806E0B2F5007F02D1821E023090 -+:1007E00000E00246B04201D3A84203D9B24241D34D -+:1007F000AA423FD8B3B1B04214D3A84212D80EF4E3 -+:100800004073B3F5807F05D12379FF2B0AD00133E4 -+:10081000237107E0B3F5007F04D16379FF2B01D08A -+:1008200001336371CB8813F0200F0BD0B24209D390 -+:10083000AA4207D8824205D0A379FF2B1AD00133F0 -+:10084000A37117E023780E2B0FD85046FFF7AEFDAB -+:1008500028B1E378FF2B0DD00133E3700AE0A378D1 -+:10086000FF2B07D00133A37004E06378FF2B01D086 -+:100870000133637009F10109DAF818251368994505 -+:1008800096D30BF1010B07340D9B9B4504DA019ABB -+:1008900013689B45FFF612AF019BC3F800B0BDE89B -+:1008A000FE8F00230E225DE72DE9F84F5FFA83FCEF -+:1008B0001E4603F44073B3F5007F14BF4FF00009E8 -+:1008C0004FF0010905468A4693460CF10200ACF14F -+:1008D0000203B9F1000F02D08646984601E09E4619 -+:1008E00080460027394629E011F80A40ACF105039B -+:1008F0009C4221DB0CF105039C421DDC0AEB01004C -+:1009000082783AB9C3782BB903791BB943790BB90B -+:1009100083798BB1744506D1837993B9B9F1000F0E -+:1009200008D0037907E044450BD152B9C37843B9E5 -+:10093000037933B9437923B9013707315F45D3DBF5 -+:100940001BE0BEF10E0FD4BF4FF400534FF48053A1 -+:100950004EF4306213439CB2D5F8FC341B7893B14B -+:100960002846002124F048D8284624F03BD80AE045 -+:100970002846012124F040D804E0D5F8FC341B7847 -+:10098000002BF5D134462046BDE8F88F2DE9F04F15 -+:10099000D0F8008090F80DA0D8F83010DDB00989AB -+:1009A000814614464FF0000B5B9300E004210022C7 -+:1009B0005B98964608E01EF804300EF1070E052BF2 -+:1009C00001D9934602E001328242F4DB082900F2A9 -+:1009D000B08001A252F821F0FD090100330B0100A3 -+:1009E000030A0100330B0100AF0A0100330B0100C1 -+:1009F000330B0100330B0100AD0901004FF6FF7608 -+:100A00001AE00025AE464FF6FF7612E00EEB0B0221 -+:100A100092FBF0F300FB1323072203FB02F16218A1 -+:100A2000937823B9D378B3423CBF655C1E460EF180 -+:100A3000010E8645EADB15B90025AC4621E00E2DF6 -+:100A400094BF4FF400524FF4805245F4306343EAB0 -+:100A500002006FE00CEB0B0292FBF0F300FB1323A0 -+:100A6000072203FB02FE04EB0E0359789A78DB7829 -+:100A70005218D218B242BCBF14F80E5096B20CF104 -+:100A8000010C8445E6DB3DB99BFBF0F300FB13B39F -+:100A9000072203FB02F31D5D0E2D94BF4FF400539C -+:100AA0004FF4805345EA030343F4306042E0BAF167 -+:100AB000020F3ED15AAB00930024404651465246A5 -+:100AC0004AAB5A94FFF788FCD8F818771FB3D8F8C8 -+:100AD000206706B35A99254610E000243AAB37F850 -+:100AE0001520E05A904205D15CAA02EB410323F89D -+:100AF000480C01310234402CF0D10135B542ECDB19 -+:100B000020230E485B935A9100F0CEFD4AAB009330 -+:100B10005A9B02AC04E020233AAA5B9302AC0092F9 -+:100B20000193214648465BAA0223FFF7BBFD022141 -+:100B30003DE700205DB0BDE8F08FC046B4FA01008B -+:100B4000F0B50546BDB004680E4609B108292DD19F -+:100B50002023D4F818273B93236B03AF1B89009203 -+:100B6000D4F82027394601923BAAFFF79BFD6B7B07 -+:100B7000022B13D1D4F8FC341B787BB1D4F8343772 -+:100B8000B3F8A4E30EF44063B3F5406F06D12046FA -+:100B900039463B9A7346FFF787FE05E02846002159 -+:100BA00003AA3B9BFFF7F2FEA4F816076B6813B18C -+:100BB000A86831469847D4F81817D4F81C276068FD -+:100BC000F6F396F00023C4F818376068294610221F -+:100BD000F6F38EF03DB0F0BD7047C04610B5C3F8D7 -+:100BE000A010082019461C4631F03ADE84F8A40013 -+:100BF00010BDC0467047C0460020704700207047B7 -+:100C0000002070477047C0467047C0467047C046D6 -+:100C1000002070477047C04603680246D3F86C3224 -+:100C2000D3F8E432987818B1938A181E18BF0120BF -+:100C30007047C0467047C0467047C04670B5037DD8 -+:100C400004469BB1457D8DB9C068A169FEF306F5E8 -+:100C500001236375E36906460BB1A0689847D6F196 -+:100C6000010038BF00206575257500E0002070BDCB -+:100C70000846002110B5016141810172017306220D -+:100C8000F1F3DEF110BDC04610B50068F4F7B0F81E -+:100C900010BDC04690F832007047C0460246086852 -+:100CA000430D5B056BB922F07F4323F46003520DC3 -+:100CB00083422CBF4FF40013002352059B180343BB -+:100CC0000B60704770B510600D461C46084619460B -+:100CD0001646FFF7E3FF2368AB4202D233680133C5 -+:100CE000336070BD002070477047C04600207047D9 -+:100CF000002070477047C0467047C0467047C046E6 -+:100D000030B50568B5B061B10DF107040171C922B4 -+:100D100000212046F1F394F12B6B2146186902F073 -+:100D20001BFF35B030BDC046406B70477047C046B2 -+:100D3000002070477047C046002070477047C0468B -+:100D4000002070477047C046002070477047C0467B -+:100D50007047C0467047C0467047C0460020704785 -+:100D60007047C0467047C046002070477047C04675 -+:100D70007047C0467047C0467047C0464FF0FF30CE -+:100D80007047C0467047C04600207047002070473B -+:100D90007047C0467047C0467047C0460020704745 -+:100DA0007047C04603490A6812B100230B60104621 -+:100DB0007047C046E82B020070B515460C464E6CD5 -+:100DC00018F00CD9024628B915F4001F02D0636C44 -+:100DD0006664A364104670BD73B500EB420440F630 -+:100DE0002A15B4F82C66A4F82C56069D009503F03D -+:100DF0008FDCA4F82C667CBD10B511F0F7DC024640 -+:100E000040B1416A11F4002F04D1036813B141F4D9 -+:100E100000234362104610BD2DE9F3411E460368CE -+:100E200004461B7E0F469046002B4BD090F875323F -+:100E3000002B47D10D682846FFF776FF016902466F -+:100E40008B79B3B1837E13F0010F12D0D1F8CC307F -+:100E500013F4806F0DD1B4F8263603F47043B3F564 -+:100E6000805F14BF40234423CB5813B193F8DF3085 -+:100E700043BB5168002925DB164B01EA03030BB97C -+:100E8000184602E0EB8A03F0070011F0400F19D07A -+:100E9000114B02A91B5C204641F8043D336009F068 -+:100EA000EFDDB0F1FF3F0DD0019A3368934209D0D6 -+:100EB0000A4B32609A5CEB8A02F0070223F00703C8 -+:100EC0001A43EA82204639464246334614F06CD82B -+:100ED000BDE8FC8140000180C4D28500301E0200C4 -+:100EE000F0B585B00A9C0D4600940B9C1F460194FA -+:100EF0000C9C064602940D9C039428F02FDBAB79E2 -+:100F000043B13946304644F063DD014610B1304606 -+:100F100044F056DC05B0F0BD10B520F00BDE10BD7E -+:100F20002DE9FF4107461D469E6B146945F0C8DB5D -+:100F30008046002834D1337A022B31D1A3797BB398 -+:100F4000B5F8683063B3A26D40F2371302EA0303C9 -+:100F500033B394F884301BBBD4F888303A6853B963 -+:100F6000D2F88C30D3F8E4210132C3F8E4213C23D9 -+:100F7000C4F8883009E0D2F88C30D3F8E42101328B -+:100F8000C3F8E421012384F89430002394F9482025 -+:100F9000384600930293296F1133019644F068DFBD -+:100FA000404604B0BDE8F0812DE9F74F80460E467B -+:100FB00093461F46002B5FD001295DD14FF4C073CB -+:100FC0000193FAF397F04FF440718246F5F380F6FF -+:100FD000044610B94FF0FF3555E000214FF4407240 -+:100FE000F1F32EF040463146224601ABF0F3BEF657 -+:100FF00010F11E0F3AD1019B4FF0FF325D004A23E2 -+:1010000023700B23637015332371042363716FF016 -+:101010002F03A371923323726FF0560363724FF064 -+:1010200002096319A270E27084F8079003F8022C99 -+:1010300003F8012C07F10C039D4202DC6FF00E0552 -+:101040000DE059463A4604F10A00F0F395F795FB96 -+:10105000F9F340463146224611F074FE05465046EB -+:1010600021464FF44072F5F343F60CE0504621461A -+:101070004FF44072F5F33CF6404631465A463B4643 -+:10108000EFF3A0F705462846BDE8FE8F70B504468D -+:101090001E46FEF39FF3054640B1636893F8AB30FC -+:1010A00023B1E06F3146F1F76DFDA860284670BDB1 -+:1010B0002DE9F0411F4603680C461B68164693F85D -+:1010C000953005460969A28A1BB1E38A13F0800FA7 -+:1010D00009D0152A07DD08480E310622F0F330F753 -+:1010E00008B9013805E02846214632463B46FCF364 -+:1010F000A5F4BDE8F081C046BAD4010010B59E4603 -+:10110000D0F8683103B19B68054C23607346FCF34B -+:10111000F3F1B0F1FF3F01D10023236010BDC046C1 -+:10112000E82B02002DE9F04F87B0DDF854808946A6 -+:1011300015469A46129FDDF84CB00446B8F1000FF0 -+:1011400006D0D8F8081019B10120F1F7A5FE044621 -+:1011500014B96FF0160632E0226805F0010300931F -+:10116000106849463A465B4612F0AED8064630BB98 -+:10117000112D02D0132D09D00FE03846F1F3ECF316 -+:10118000E8B904F5B8703946062203E004F5B670F4 -+:1011900039460422F0F3F0F611E0109B204600934C -+:1011A000119B49460193149B2A4604935346029788 -+:1011B000CDF80CB0CDF81480FCF3C2F006463046F2 -+:1011C00007B0BDE8F08FC04670B50546D0F8B40052 -+:1011D00058B103784BB1F1F767FB044630B9D5F845 -+:1011E000B4000121F1F31AF500E001242846F3F3DD -+:1011F000DBF724B9D5F8B4002146F1F30FF570BD43 -+:1012000010B5FFF735FD10BD10B5FAF7B1F810BDF8 -+:10121000B0F8543810B50BB119F03ED910BDC04626 -+:1012200010B5044638B102682AB121B992F80B37DB -+:101230000BB182F80B17204617F090DF10BDC046A7 -+:1012400010B521B11AB1536E0BB13DF037DE10BDB0 -+:1012500010B50C4651B1002381F8653581F866352B -+:1012600081F86735C1F868353DF0A2DE10BDC04693 -+:10127000036A10B50C46002B2CD0036809691B6863 -+:10128000B4F814E093F895302BB1E38A13F0800F93 -+:1012900001D11E2200E00C2202F10B039E4519D35E -+:1012A0008B188A5C591C5B7803EB02239BB2B3F565 -+:1012B000006F0FD14B784A1C1B09042B0AD1537ABB -+:1012C000012B07D1436A01334362C3680133C36012 -+:1012D000002002E021463FF03BDD10BD036810B561 -+:1012E0001A68536B2BB192F8443013B130F0AEDF73 -+:1012F00000E0002010BDC04610B50C462DF0C0D94E -+:1013000018B994F8F53284F8F43210BD70B50122A2 -+:1013100005460C46D1F84C152EF01ADD284621461C -+:101320002DF0EAD870BDC0460C2A2DE9F0410446E4 -+:101330000F46154651D80122AA4041F2485302EA0D -+:101340000303002B49D0D0F8B4364BB1D3F8D832D0 -+:1013500033B15B68012B40D0032B3ED0022B3CD035 -+:10136000204615F043DD002837D1D4F868315B6999 -+:10137000012B32D0D4F81808FEF3F6F0064628B157 -+:10138000D4F86801092143F013D91AE0082D01D0DF -+:101390000C2D04D1D4F868319B7923BB11E0D4F82B -+:1013A0006801837913B3D4F82835022B04D094F85C -+:1013B000F43713F0010F16D0092143F0F9D8304665 -+:1013C00015E0082D12D1204639460222002325F0CF -+:1013D0003BD958B14FF0FF3009E0204639462A4644 -+:1013E00029F0E6DC03E06FF0180000E00020BDE823 -+:1013F000F081C0462DE9F04F85B005469B468846F2 -+:1014000091460F9F9DF840A0F8F7B2FFD5F8B06362 -+:1014100004460AF087DDD5F8C03398420CD3032385 -+:10142000009300230193029303932046172109F1AF -+:101430000A02013312F03CDB96F8463013F0030F3A -+:1014400019D0D8F8582040F2371302EA030393B1B9 -+:1014500094F8693713F0010F0DD07B6813F4803FC7 -+:1014600009D03B6C012B06D1002220463946134699 -+:10147000009211F0BBDB094C7F2323600E9B2846B2 -+:10148000009341465B464A460197CDF808A0F8F71D -+:1014900085FF0023236005B0BDE8F08F0C2C02000F -+:1014A00010B50446F5F346F0B0F5C05F05DD204603 -+:1014B00043F006DE204643F003DE10BD2DE9F04187 -+:1014C000074619F0DFDF0026BB19D3F84C42B4B150 -+:1014D000D4F88C509DB9A3798BB1A36D13F0020F92 -+:1014E0000DD094F8843053B1F5F38CF0D4F890100B -+:1014F00027F042DF18B1C4F8885084F884500436CD -+:10150000202EE1D1BDE8F08170B590F8A1310546FB -+:1015100063B903681B6F4BB1D0F81C48F5F372F048 -+:10152000D5F82038E41A2418C5F81C48284614F0C9 -+:10153000BBDB70BD10B588B00A9C00940B9C019475 -+:101540000C9C02940D9C03940E9C04940F9C059497 -+:10155000109C0694119C0794F3F3C2F1044B0421F0 -+:10156000D3F88C300A4604469847204608B010BD90 -+:10157000E0A6850070B504460D461EF04BD92946FD -+:1015800006462046F8F708FE304670BD2DE9F041CA -+:101590000546D5F8D8320E465B681746012B006821 -+:1015A000D5F8DC4202D14FF0000805E0042914BF51 -+:1015B0004FF000084FF001080368DB691A6D636A99 -+:1015C000934238BF62624EB9D4F8901031B140688E -+:1015D00094F89420F5F38CF3C4F8906028463146D3 -+:1015E0003A4625F0F5D8B8F1000F01D00023636228 -+:1015F000BDE8F0812DE9F04385B00C9F0546984683 -+:10160000D7F80090D2F8D462144600970AF0F0DCC4 -+:10161000296891F8463013F0030F3FD0D4F8CC205E -+:1016200012F4805F3AD196F93430002B36D14B6BEF -+:10163000002B33D012F0020F30D13B680DF10900BE -+:101640001849032208EB0304F0F396F495F8FA31F5 -+:1016500033B196F96A30002B02DA95F80A0700E0F8 -+:10166000002008EB0901A14201D2002100E0091B82 -+:1016700002238DF80C3000238DF80D3001338DF8E6 -+:101680000E300DF109038DF80F000093204607235B -+:10169000DD221AF07BDD3B6809333B6005B0BDE815 -+:1016A000F083C046C1D401000FB430B5104BADF586 -+:1016B000037D9E4501D1002513E002A887AB0538C4 -+:1016C00040F20121869A8193F0F3F0F5002405465B -+:1016D00005E002AB053BE05CF5F332F20134AC42CD -+:1016E000F7DB28460DF5037DBDE8304004B07047B8 -+:1016F000DB62820010B502490248FFF7D5FF10BD3A -+:10170000CCFB0100E3FB0100C36970B513F4006F6B -+:101710000E460546016915D00368D3F88C20936BFB -+:101720005C1C4FF47A739463B4FBF3F202FB134333 -+:1017300023B90748C96B2246FFF7B6FFEB6923F4CC -+:101740000063EB61284631462CF03CDB70BDC0469F -+:101750007CDB010010B590F81632044663B1084BEB -+:101760001B684BB1D0F88011D0F884210223C068E7 -+:1017700081EA0202F9F332F42046F7F36FF610BD66 -+:10178000AC27020010B50446F7F3B8F7002384F83D -+:10179000173284F8183210BD10B5074C2378012B8E -+:1017A00009D0064B1B78012B05D001232370F8F3D9 -+:1017B00073F70023237010BD002C0200EC2B0200F5 -+:1017C00070B50546F1F7EEF80128014607DD044C37 -+:1017D000012328462370F8F3EDF50023237070BD34 -+:1017E000EC2B020010B5064902690B782BB1D2F838 -+:1017F000D03013B100230B7001E018F051DD10BDA3 -+:10180000F42B020010B58B7913B1044B01221A702E -+:101810002DF0B6DB014B00221A7010BDF42B020034 -+:1018200070B5044C8568A54201D1002001E0F0F3B9 -+:1018300009F770BD0800002070B505460E461AF085 -+:101840002BDD0446C0B13146284640F26C521AF0F6 -+:1018500035DE064620B9284621461AF091DD0AE019 -+:10186000214640F26552F0F387F32846214640F2C4 -+:101870006552F5F33DF23446204670BD2DE9F04146 -+:101880008AB088460023159917460546129C09938D -+:101890002DF0B0DD07F001030093414606462246D5 -+:1018A0002868139B11F010DD8046002840F0AA80C4 -+:1018B000119B032B04D909A810990422F0F35CF3BF -+:1018C0000D2F08D8DFE807F00A0F07071722363C6C -+:1018D0004B07074E93976FF0160892E0284608F0E2 -+:1018E0002DDA40B22AE02846099908F051DA00289A -+:1018F00000F0858085E0B6F95E300BB102201DE076 -+:10190000B6F95C30181E18BF012017E0099B022BA6 -+:1019100006D14FF00003A6F85C304FF0010306E05B -+:10192000003B18BF0123A6F85C304FF00003A6F877 -+:101930005E3066E0D5F83407F8F71EFD206060E001 -+:10194000099BD5F834070393F8F71EFD039B8342E8 -+:1019500055DCD5F834070999F8F712FD51E0B5F8D0 -+:10196000BE3846E02B6893F8A030002B3FD00DF135 -+:101970001608264906224046F0F3FEF221460422CC -+:1019800008A8F0F3F9F2211D042207A8F0F3F4F2FD -+:10199000404604F108010622F0F3EEF2079F57B922 -+:1019A000D5F86821937993B95369012B0FD02B682F -+:1019B00093F83F305BB904F1100301932846314698 -+:1019C000089A3B46CDF8008015F084DC0DE02B68CA -+:1019D0001B7E13B96FF0030813E0284631460DF162 -+:1019E000160204F1100315F061DC804609E095F859 -+:1019F000C334236005E0099B85F8C33401E06FF030 -+:101A00001C0840460AB0BDE8F081C0462C9E850007 -+:101A10002DE9F04790B0DDF860A00C461E46514617 -+:101A20000023054617460F932DF0E4DC8046D0F8DE -+:101A3000DC9277B1032E04D90FA839460422F0F3C3 -+:101A40009BF237B1032E04D90FA839460422F0F3D4 -+:101A500093F2352C6BD010DC162C00F07C8105DC69 -+:101A60000B2C21D0152C00F065811AE01C2C00F005 -+:101A700086812F2C00F0288113E0382C00F0E580BF -+:101A800006DC362C00F09880372C00F0B58008E09A -+:101A90009F2C00F07A81A52C00F03F81392C00F0BA -+:101AA000F5806FF01604A1E12B6893F8A030002BAD -+:101AB0003DD00DF12606A24906223046F0F35CF235 -+:101AC000394604220DA8F0F357F2391D04220CA860 -+:101AD000F0F352F2304607F108010622F0F34CF21F -+:101AE0000C9C54B9D5F8682193798BB95369012BB3 -+:101AF0000ED02B6893F83F3053B907F110030193D0 -+:101B0000284641460D9A2346009615F0E3DB0CE08B -+:101B10002B681B7E002B00F05D81284641460DF1AD -+:101B2000260207F1100315F0C1DB04465EE12B68C5 -+:101B30001B7E002B00F04E81052E40F24E810D2EB3 -+:101B40000BD9284607F10801A6F1080201F062DA74 -+:101B50000446002840F04A8109E005AC3946204699 -+:101B60000622F0F309F2002307930E26274698F881 -+:101B70000640B4B9D9F8901031B1686899F894204A -+:101B8000F5F3B6F0C9F8904089F89460686831467A -+:101B9000F5F39EF0C9F8900018B139463246F0F3DB -+:101BA000EBF14046394629F091DAD9F890300446F5 -+:101BB000002B40F01A8119E1002300932846394692 -+:101BC00032460EABF1F760FB0446002840F00E8170 -+:101BD0000E99032900F004812A6B1368994202D1FF -+:101BE000D2F8F03050E05368002B14BF38233C2368 -+:101BF000EB58D3F8F03047E00023009328463946ED -+:101C000032460EABF1F740FB0446002840F0EE8070 -+:101C10000F9A02F16403672B02D96FF01C04E5E010 -+:101C20000E99032904D02B6B1B68994240F0DE808B -+:101C3000002A04DB2846296B29F08CDB02462B6B3B -+:101C4000C3F8FC20C3F8F020D0E00023009328461E -+:101C5000394632460EABF1F717FB0446002840F038 -+:101C6000C5800E99032900F0BB802A6B1368994246 -+:101C700002D1D2F8F43007E05368002B14BF3823A8 -+:101C80003C23EB58D3F8F4303B60AFE000230093E3 -+:101C90002846394632460EABF1F7F6FA04460028DC -+:101CA00040F0A4800F9A642A00F29A800E990329CA -+:101CB00004D02B6B1B68994240F098802B6BC3F8C3 -+:101CC0000021C3F8F42091E02B680F9C93F83F307B -+:101CD00013B16FF01B0489E0D5F86801837913B163 -+:101CE000042142F065DC95F87232221E18BF0122F1 -+:101CF00085F8502785F85925002B76D12AB105F5AE -+:101D0000AA61D5F85C010E3104E005F5AA61D5F8A9 -+:101D10005C010A3134F026DA07E70123002202933E -+:101D200028460849134600970196CDF80CA011F0FB -+:101D300037DBFAE6B8F95E3033B1022009E0C0467D -+:101D40002C9E85001C738600B8F95C30181E18BFE5 -+:101D50000120386049E00F9B022B06D14FF00003B1 -+:101D6000A8F85C304FF0010306E0003B18BF0123E8 -+:101D7000A8F85C304FF00003A8F85E3035E02B681F -+:101D800001211869F9F392F22FE0331F0622B3FB09 -+:101D9000F2F33B60D5F8000500230BA90F9343F045 -+:101DA00099D910E00B7E13F0020F0CD00F9B5C1C36 -+:101DB0000F943B68A34210D3B81E062204FB020016 -+:101DC0001A31F0F3D9F00BA843F08CD90146002862 -+:101DD000E8D108E06FF0030408E06FF00D0405E0BF -+:101DE0006FF0020402E00F9B3B600024204610B01D -+:101DF000BDE8F0872DE9F04F056889B082460C46B2 -+:101E00001E4628460023179907939346DDF848801D -+:101E10002DF0F0DA139B032B04D907A841460422C6 -+:101E2000F0F3AAF0BBF10D0F56D12846414698F8C1 -+:101E3000066098F8087098F809402DF06FDA10B134 -+:101E40006FF00107F1E098F80630003E18BF012658 -+:101E5000022B14BF4FF400594FF4811947EA0427AD -+:101E60006EB13846F1F3F8F1002840F0E080D5F883 -+:101E70005C01394634F092DA002800F0D880284618 -+:101E80002DF070DBB0F1FF3F014600F0D280284614 -+:101E90004A46434600962CF08BDE0446002800F0AC -+:101EA000C88028462146FBF789FA20B128462146FA -+:101EB0002DF0C2DABDE0002E00F0B9803946284688 -+:101EC000A2683BF0CDD90746002800F0AE80284636 -+:101ED00021462DF0B1DA12E0139B50460193149B7A -+:101EE00021460293159B5A460393169BCDF800801A -+:101EF0000493179B059333463AF03ADF074617F1F0 -+:101F0000170F40F09280DAF80060002330461799EE -+:101F100006932DF06FDA139B0446032B04D906A811 -+:101F200041460422F0F328F0BBF11B0F7DD130466F -+:101F3000414698F8065098F8089098F809702DF0E6 -+:101F4000EDD9034620B1A04202D06FF0010373E047 -+:101F5000B5F1000A18BF4FF0010ABAF1000F0BD01B -+:101F6000032D0BD09A68304649EA07213BF078D917 -+:101F70000346002860D111E0032D0FD130462146E1 -+:101F80002CF070DF012394F94810304600934FF491 -+:101F90008802013BFBF7E6F903464DE0D4F8CC306C -+:101FA000304643F40003C4F8CC3021462CF05ADF0D -+:101FB000A37913B1322384F8F43294F8F41231295E -+:101FC0000FD833681B7E1BB130461D4A17F02EDA3E -+:101FD000D6F84C0194F8F4123DF074D9322384F809 -+:101FE000F4324146062204F1C200EFF3C5F784F84B -+:101FF00006A030462146FBF7E1F9054640B1D4F88A -+:10200000CC3023F40003C4F8CC304FF0FF3313E09E -+:1020100030460321A26811F087D8D4F8CC3023F4DD -+:102020000003C4F8CC302B4606E03B4604E0002712 -+:10203000FBE74FF0FF37F8E7184609B0BDE8F08F2F -+:10204000329E85002DE9F04704468946FCF3F4F7FB -+:10205000F4F3D8F294F854318046012B1ED825466B -+:10206000002717E06E69B379022B11D1B4F86C30F8 -+:1020700013F4807F0CD0204649464246F0F74CFED0 -+:1020800030B90423B37194F8CD30013B84F8CD30DE -+:1020900001370435B4F910309F42E3DBBDE8F08727 -+:1020A00030B54FF0000E044691B08C461546704690 -+:1020B00009E023185A690EF1010ED1794DF800108C -+:1020C000536B0430D371B4F910309E45F1DB2046D8 -+:1020D00061462A46FCF3A4F10020014606E063189D -+:1020E0005A695DF801300130D3710431B4F9103010 -+:1020F0009842F4DB11B030BD2DE9F0410C290446C3 -+:102100000D46164690F853710DD100210122FCF3C3 -+:1021100087F1204600210122FCF33EF1002384F8E0 -+:10212000CE3084F8CD30A36E2046B3F1FF3F08BF18 -+:1021300084F8563129463246FCF392F2B4F86C30FA -+:1021400003F0C003C02B16D1D4F85C319BB194F8D6 -+:102150005331BB420FD9E368A1689868FDF37EF262 -+:10216000E368A1689868D4F85C210123FDF32EF29E -+:102170004FF0FF33A366BDE8F081C046836E10B513 -+:10218000B3F1FF3F01D0FBF39FF510BD2DE9F04106 -+:1021900004460D46866EFCF3C5F6074690B9042248 -+:1021A00004F5AE7005F11401EFF3E6F6D4F85C31F6 -+:1021B0004FF47A7203FB02F3B6F1FF3FC4F85C31CF -+:1021C00008BFA6663846BDE8F081C0460E2937B57F -+:1021D00005468E4614460BD00F2910D1114601A892 -+:1021E0000422EFF3C9F628460199F0F731FE08E022 -+:1021F000B0F85831002003F00103136001E0FCF354 -+:10220000E9F13EBD70B514460546FCF39FF1236825 -+:102210000BB10223AB6570BD70B50D460446FBF3F0 -+:10222000FDF7014610BBA36DEDB1FBB9D4F8542105 -+:102230000F4B02EA03037BB194F85431022B04D113 -+:1022400094F8573113F0010F05E0012B07D194F8F2 -+:10225000573113F0020F02D16FF0010300E00023A9 -+:1022600084F8563102E00BB184F85601084670BD7F -+:10227000FF0000FF10B50446FBF362F7002384F86B -+:102280005731A4F85831C4F85C3184F8563110BD88 -+:102290002DE9F041A2B0882205460C4690F8558100 -+:1022A00090F8567190F854616846EFF365F6284649 -+:1022B0002146FBF3AFF60246002836D1009B85F895 -+:1022C00056719E4285F854612CD01BB995F8573150 -+:1022D00073B112E0022B04D195F8573113F0010FBE -+:1022E00005E0012B07D195F8573113F0020F02D109 -+:1022F0006FF0010314E096B90DE0012E02D113F046 -+:10230000010F05E0022E05D195F8573113F0020FA9 -+:1023100005D107E036B995F85531434502D200237F -+:1023200085F85631009B85F85431104622B0BDE83F -+:10233000F081C0462DE9F04104460E46154690F85E -+:102340005671FBF363F48646A0B92A4601460DE0B8 -+:102350007318DB88083113F0100F06D194F8573149 -+:1023600043F0010384F8573102E0083A072AEFD816 -+:1023700084F856717046BDE8F081C0462DE9F04101 -+:1023800004460D46164690F85671FBF3DBF386467D -+:1023900098B9294632460CE04B6A13F0100F06D16B -+:1023A00094F8573143F0020384F8573103E0383A88 -+:1023B0003831372AF0D884F856717046BDE8F0817C -+:1023C000002070472DE9F0410B4C07460E460025D2 -+:1023D0000BE038462146EFF3A1F620B923799E425F -+:1023E00001D1A06806E001350C34044B1B689D4206 -+:1023F000EFD30020BDE8F08120FC0100F02B0200AB -+:1024000070B50D4600240AE00849284601EBC401D6 -+:102410000422EFF395F508B9013005E00134044BCF -+:102420001B689C42F0D3002070BDC04620FC010018 -+:10243000F82B020010B5034C216033F0F9DA0023C9 -+:10244000236010BD082C02002DE9F0412A4B0646FE -+:10245000D3F800800F4600250BE0284B304603EBF5 -+:10246000C5042146EFF35AF610B9E3789F4241D0F4 -+:1024700001354545F1D1224B0025D3F800800FE00E -+:10248000204B304603EBC5042146EFF347F630B945 -+:10249000E3789F4203D11C4B01221A7010E00135F2 -+:1024A0004545EDD117BB194B3D46D3F800800AE0F6 -+:1024B000174B304603EBC5042146EFF32FF608B95E -+:1024C000201D17E001354545F2D1124B124DD3F8CE -+:1024D0000080002408E029463046EFF31FF604355B -+:1024E00008B90E4806E001344445F4D13046394677 -+:1024F00032F074DEBDE8F081042C0200E3FB010041 -+:102500009421020018FC010098210200F82B02001F -+:1025100020FC0100FC2B020018FC0100CA0286000E -+:1025200010B5084B02461B783BB1074B1B6898421D -+:1025300003D2064B53F8200010B9104632F026DFC4 -+:1025400010BDC046982102007C200200781F0200C6 -+:1025500010B5084B02461B783BB1074B1B689842ED -+:1025600003D2064B53F8200010B9104633F006DBB7 -+:1025700010BDC04698210200802002008420020085 -+:102580002DE9F04F234B8FB01C68234B82468946C0 -+:10259000D3F800B00CB9204638E0036BA168186985 -+:1025A00007AA00F0FFFD00261C4DB0462BE0A368F3 -+:1025B0006F1F012B03D12878FFF702FF03E015F806 -+:1025C000010CFFF7C5FF694633F00EDC002107ABB5 -+:1025D0001DF80120CB5C1A420FD05046394632F02C -+:1025E000E5DD40B1B9F1000F05D009EB86003946B1 -+:1025F0000422EFF3DDF5013602E001311C29E6D1BA -+:1026000008F101080835D845D1D130460FB0BDE8F2 -+:10261000F08FC046082C0200F82B020025FC0100B8 -+:10262000012902D14FF6FF7010E0D0F8BC304FF016 -+:102630000002082BD0F8B03008BF41F40071A3F8B5 -+:10264000D813B3F8DA33A0F8202698B27047C04602 -+:10265000D0F8B030A3F8D813A3F8DA237047C046F7 -+:10266000D0F8B0300021A3F8D8134FF0010230B5F4 -+:10267000B3F8DA434FF00205A3F8D823B3F8DA230E -+:10268000A3F8D853B3F8DA3392B29BB2A0F820166D -+:10269000C4F3031040EA047042EA032240EA023025 -+:1026A00030BDC04670B505460E461446FFF7B8FF6C -+:1026B000314600EA04022846FFF7CAFF70BDC04653 -+:1026C00070B505460E461446FFF7AAFF40EA04021D -+:1026D0003146284692B2FFF7BBFF70BD2DE9F041AD -+:1026E0001546064688461C46FFF79AFF2C4020EA0E -+:1026F000050222433046414692B2FFF7A9FFBDE8EA -+:10270000F081C0462DE9F0411C46069B9046198099 -+:10271000079D0E46FFF784FF089B28801E802B88AC -+:1027200004EA080423EA0803099A23431380BDE856 -+:10273000F081C046D0F8B0304FF00002A3F8FC138F -+:10274000A0F82026B3F8FE0380B27047D0F8B0306E -+:1027500041EA0242C3F8FC237047C046D0F8B030CB -+:10276000A3F8FC13B3F8FE130A40A3F8FE234FF0BE -+:102770000003A0F82036704710B5D0F8B040A4F898 -+:10278000FC13B4F8FE339BB21A434FF00003A4F8D5 -+:10279000FE23A0F8203610BD10B5D0F8B04013408D -+:1027A000A4F8FC13B4F8FE1389B221EA02010B432A -+:1027B000A4F8FE334FF00003A0F8203610BDC04649 -+:1027C0002DE9F04106460C462CE0254635F8023B43 -+:1027D000571E990403F44043890CB3F5804F11D080 -+:1027E00001DC3BB11CE0B3F5004F10D0B3F5404F16 -+:1027F00012D015E03046628835F8023FFFF7CCFF73 -+:10280000013F0DE030466288FFF7A0FF08E0304648 -+:102810006288FFF7A3FF03E030466288FFF7ACFF52 -+:10282000AC1C7A1E002AD0DCBDE8F0812DE9F04115 -+:102830001C46069B90461980079D0E46FFF77AFFBF -+:10284000089B28801E802B8804EA080423EA0803DA -+:10285000099A23431380BDE8F081C04600234FF05E -+:10286000FF3280F8E33041F21A03C25403F59B7340 -+:10287000C254704710B531B140F23B414FF6F87287 -+:10288000FFF76CFF03E002490422FFF799FF10BD38 -+:102890002E03020060B1B0F8DE00B0F5006F05D085 -+:1028A000B0F5406F04D1A0F5386002E0402000E0B0 -+:1028B00000207047012380F8E130704780F824162B -+:1028C0007047C04690F924067047C0467047C0461E -+:1028D00010B1C06900B141777047C04610B1C069FE -+:1028E00000B101777047C04610B590F8E330044658 -+:1028F000002B49D14FF064014FF44872A0F88428AE -+:10290000A0F87C18A0F87E18C0F880381A46A318E2 -+:1029100002324FF06401102AA3F88618F7D14FF065 -+:102920000003A4F82E38A4F8AC37A4F8AE374FF063 -+:102930000A034FF00A02A4F83E38A4F83C38A4F881 -+:102940004038636A4FF01401A4F83228A4F84428F0 -+:10295000A4F83428A4F84628A4F82A28A4F828289B -+:10296000A4F82C28A4F89027A4F892274FF050023E -+:10297000A4F83018A4F89427A4F842180BB1204604 -+:102980009847012384F8E33010BDC04610B5FFF727 -+:1029900067FE10BD2DE9F84F0C46D1F810A00D6868 -+:1029A0009B468968E368064643EA812311469AB24A -+:1029B000BDF82880FFF7CAFE0027B9461EE0BAF12D -+:1029C000200F0BD159F8052030465946120CFFF75D -+:1029D000BDFE39F80520304641460AE0BAF1100F35 -+:1029E00004D135F817203046414602E07A5D304682 -+:1029F0004146FFF7ABFE013709F1040963689F42C6 -+:102A0000DDD3BDE8F88FC0462DE9F74F0D460193A1 -+:102A1000D1F810B00E68EB688968074643EA812355 -+:102A200011469AB2BDF83090FFF790FE4FF00008C3 -+:102A3000C24626E0BBF1200F0FD149463846FFF7CA -+:102A400079FE019904464AF806003846FFF772FEFF -+:102A500044EA00444AF806400FE0BBF1100F06D1EB -+:102A600038464946FFF766FE26F8180005E0384666 -+:102A70004946FFF75FFE08F8060008F101080AF171 -+:102A8000040A6B689845D5D3BDE8FE8F7FB50293E5 -+:102A9000089B03910593099B0192049301A90A9B4A -+:102AA000984707B000BDC0467FB50293089B0391CD -+:102AB0000593099B0192049301A90A9B984707B0CB -+:102AC00000BDC0460B46D0F8F81012B141EA03032E -+:102AD00001E021EA0303C0F8F830704700B5D0F8F0 -+:102AE000F8308E4621B143F01003C0F8F83012E000 -+:102AF00023F0100312F0010FC0F8F8300BD041F2B0 -+:102B0000D413C258C369196A986E814294BF714642 -+:102B1000091AC2F8901000BD00207047A0F8DE101E -+:102B20007047C046A0F8DA107047C046B0F8DA0027 -+:102B30007047C04640F6C313984201D800200BE00E -+:102B400041F2C843984201D8012005E041F24463B4 -+:102B500098428CBF032002207047C0467047C04691 -+:102B600000B5002286460748910030F822307345B0 -+:102B700002D10B18588803E001320E2AF3D100204D -+:102B800000BDC046A8FC010010B5C8B2FFF7E8FFC1 -+:102B9000FFF7D0FF10BDC04610B541F22823C45C3A -+:102BA0004FF0000C134B3CF803E0BEF10E0F8CBF4E -+:102BB0004FF480524FF400524EF4306342EA030067 -+:102BC0002CB1BEF1940F02D9BEF1A50F0AD902298A -+:102BD00003D1BEF10E0F0BD904E0012902D1BEF1E1 -+:102BE0000E0F05D80CF1040CBCF1380FDAD1FF2020 -+:102BF00010BDC046A8FC010010B590F8B2321446D2 -+:102C00000B6090F82B3653B190F8F83690F92A26DD -+:102C100023B1534243F080430B6000E00A6014B1DB -+:102C200090F8F7362370002010BDC04610B58646D8 -+:102C30001C4641F21B031EF8033002989B000E292C -+:102C4000137008D80028ACBF0EEB00030EF1000390 -+:102C500093F81E3127E07F23237030EA200028BF3D -+:102C600004200022114BD35A994202D00432382A50 -+:102C7000F8D1A1F122031E2B04D80EEB000393F828 -+:102C800083312370A1F16403282B04D80EEB0003D9 -+:102C900093F8E8312370A1F19503102B04D80EEBC3 -+:102CA000000393F84D32237010BDC046A8FC01000C -+:102CB0002DE9FF4700250746884691469A46FF269C -+:102CC0002C461EE0009341460DF10E020DF10F035C -+:102CD0003846FFF7ABFF41F2E623FA5C9DF80F1090 -+:102CE00053B2994201DC002302E0C2EB0103DBB2E4 -+:102CF0008DF80F30AB4228BF1D46B34238BF1E4689 -+:102D00000134142CE3B2DDD189F800508AF8006058 -+:102D1000BDE8FF877047C04690F829067047C04657 -+:102D2000B0F8DA3003F47043B3F5805F09D1032AB9 -+:102D300018DDA2F16503032B14D9A2F1C9030F2BEF -+:102D400010D9132A0EDCA2F13403642B0AD9A2F1A4 -+:102D5000A9031F2B06D9A2F1D103072B94BF002092 -+:102D6000012000E00020704770B590F8DA5004466A -+:102D70002846FFF7F5FEB4F8DA3003F47043B3F5F4 -+:102D8000005F01D0002004E02B1903F59A530F33A4 -+:102D9000187940B270BDC04600B54FF0000E00EB90 -+:102DA0000E021EF801300EF1010EBEF1040F82F882 -+:102DB0002C36F4D14FF0000E01EB0E0200EB0E03A7 -+:102DC00012790EF1010EBEF1080F83F83026F3D10F -+:102DD00000BDC04680F8E0107047C046C3699961E5 -+:102DE0007047C04680F8D5104176704780F8D910FA -+:102DF0007047C0467047C04690F81A067047C046F4 -+:102E000041F22403C35C33B141F21C2380F81A164B -+:102E100080F81B16C154704790F8D83013B10023C6 -+:102E200080F8D83000207047C369012093F88130C2 -+:102E30000B70704722B10023C0F8E83FA0F8EC3FC8 -+:102E400000F58153012019607047C0460022C16916 -+:102E500010460B1893F982300130D2180828F8D1A7 -+:102E600092FBF0F040B270477047C0466FF016001A -+:102E70007047C04670B541F21E23C35C04468B42C6 -+:102E80000D46164603D0D0F8883003B1984704F5B4 -+:102E900091531E8041F21E23E55470BD0021C36989 -+:102EA000CB180131082983F88220F8D10021C369A9 -+:102EB0006FF05B02CB180131082983F88220F6D12C -+:102EC000C2690023C2F88C30D36E032B08D1D0F82E -+:102ED000F83F13F0010F03D0136A0833C0F8F03F36 -+:102EE00000F58A531233002204E0002241F2D2138B -+:102EF000C25470474FF6A47101321980198402330D -+:102F0000102AF7D1F1E7C04649F675334B6000232C -+:102F10000B60F0B50C469842ACBF01214FF0FF3179 -+:102F200003F5340301FB03F103F53403081890FBA8 -+:102F3000F3F202FB1303581A03D4C31301335B10DB -+:102F400004E04342DB1301335B105B425A2BD4BFD6 -+:102F50000023012313B1A0F5340014E0002803DBA3 -+:102F6000C31301335B1004E04342DB1301335B10F6 -+:102F70005B4213F15A0FACBF002301230BB90126AA -+:102F800003E000F534004FF0FF364FF0000EF4463A -+:102F90007546604561682268144F0BDD41FA0EF3F7 -+:102FA0009B18236042FA0EF3C3EB01036360EB59F5 -+:102FB0009C440BE041FA0EF3C3EB0203236042FA98 -+:102FC0000EF35B186360EB59C3EB0C0C0EF1010EB2 -+:102FD0000435BEF1120FDCD1636806FB03F36360B6 -+:102FE000236806FB03F32360F0BDC046F4FC010038 -+:102FF00080EAE071A1EBE0710022D0B251FA00F357 -+:103000000132002BF9DC70470146002000B58646EE -+:103010004FF0804343FA0EF31A188A424FEA5000E9 -+:1030200002D8891A43EA00000EF1020EBEF1200F09 -+:10303000EED1884238BF013000BDC046C36983F875 -+:103040009010C36983F89120C36983F89210C36913 -+:1030500083F893207047C046C36983F89210704785 -+:1030600041F21633C256013BC0568242B4BF012022 -+:10307000022070470048704750FD01000020704753 -+:103080007047C046084670470020704741F2D81389 -+:10309000C05803E0C3888B4202D000680028F9D1F1 -+:1030A0007047C04610B5B0F8DA10FFF7EFFF10BD5B -+:1030B000C3699B6913F0005F09D0D0F8B0304FF0BE -+:1030C0000302A3F8B4264FF0FF02A3F8B826704716 -+:1030D000D0F8F83013F0060F0CBF00200120704725 -+:1030E0002DE9F0410F46B0F8DA10044615461E46A9 -+:1030F000FFF74AFD40B9B4F9FC302B60B4F9FE305B -+:103100003360B4F900313B60BDE8F081D0F8A8002D -+:103110007047C04670B541F2D813C15805460AE061 -+:103120000B6841F2D8142B51EB694FF43D7298684B -+:10313000F3F3DEF529590029F2D141F2D81305F550 -+:1031400090523032E950043BEA504FF6CE70F033E3 -+:10315000E852C2F8901070BD10B590F8E93094B004 -+:1031600043F0010380F8E93004460021302201A831 -+:10317000EEF366F7002110220DA8EEF361F70021AF -+:10318000042213A8EEF35CF711A800210822EEF345 -+:1031900057F794F8E930002023F0010384F8E93070 -+:1031A00014B010BD70B506460D46104614460021F9 -+:1031B0001C22EEF345F700200F4BC25A41F22823A0 -+:1031C000F35C1BB1942A01D9A52A10D9022D02D192 -+:1031D0000E2A04D90BE0012D09D10E2A07D9D108F6 -+:1031E00002F0070301229A40635C134363540430E6 -+:1031F0003828E1D170BDC046A8FC010010B50C46CE -+:10320000002103F025F82070012010BD10B5002129 -+:1032100003F01EF840B210BD41F2D41310B5C458EB -+:10322000F433C15819B1C36918693DF095DA002328 -+:103230006370A37010BDC04610B59E462BB941F215 -+:103240000723C35C704613600FE041B1012906D02B -+:10325000022904D0032902D06FF01C0005E041F2DE -+:103260000723C154FFF7D8FF002010BD41F2C82347 -+:10327000C15810B509B9084607E0C36918693DF09F -+:103280006BDAD0F1010038BF002010BD10B541F25B -+:10329000F423C35C0BB104F097FD10BD10B503F02F -+:1032A000B5FB10BDC36970B5DC681B6D054613F036 -+:1032B000010F0E4608D02046F7F3FAF520B1EB696E -+:1032C0009B6913F0005F12D1EA69136D13F0010FCF -+:1032D0003BD0536D13F0800F37D1D068F7F386F7EA -+:1032E000002832D0EB699B6913F0005F2DD0D5F830 -+:1032F000F83013F0020F28D1EEB106F47043B3F5A5 -+:10330000005F18D163691149232BB4BF00230C233C -+:10331000F2B2B8BF0F2120469A400123F7F3D0F54F -+:1033200063690B49222B2046D8BF7021CCBF4FF4D4 -+:103330000072102206E0636904492046222BD8BFA0 -+:103340000F2100220123F7F3BBF570BD00F05555A6 -+:10335000000E5555D0F8B030C269D3F82031136D46 -+:1033600070B513F0010F04460D4608D0D068F7F38E -+:103370009FF520B1E3699B6913F0005F11D1E26909 -+:10338000136D13F0010F18D0536D13F0800F14D18B -+:10339000D068F7F32BF780B1E3699B6913F0005F06 -+:1033A0000BD025B920462946FFF77CFF0AE02046CE -+:1033B000B4F8DA10FFF776FF00E01DB104492046AB -+:1033C000062202E0034920460E22FFF7F9F970BDFC -+:1033D000360302008CFC010010B514299E46D0F87B -+:1033E000A82004D015290CD06FF016000CE092F93B -+:1033F0001A3002A941F8043F70460422EEF3BCF5EE -+:1034000001E0039B9376002010BDC04610B590F8F4 -+:103410001A360C462BB10231224601F091FDA378F9 -+:10342000637010BD10B5012103F072FA10BDC046E3 -+:103430002DE9F0418A79CB790D4642EA03216B7977 -+:103440002A79074642EA0328C3695B690A2B07D930 -+:10345000EB7C1B0213F4807002D10123EB7735E083 -+:103460002A7A6B7A384601F0FF0442EA0326FFF716 -+:103470004DFE7F2C1B4AC8BFA4F58074B30AD356F7 -+:1034800090F85F00E21818F4006F14BF41F23B336C -+:1034900041F23A33FB56D11843B2C918AA7DEB7DED -+:1034A0007F2942EA0322C2F3C702C8BFA1F5807197 -+:1034B0000E2AD4BF4FF400534FF4805342F43062CD -+:1034C000384649B243EA0202FFF7DCFD6A79C1B22D -+:1034D0002977384649B2C2F3801201F00DFBBDE8EE -+:1034E000F081C0461A22020010B590F8E9309646E5 -+:1034F00053B313F0010F19D0D0F8F0308B420FD135 -+:10350000C369D3F88C209B1883F882E0C269D2F893 -+:103510008C30072B01D1002300E00133C2F88C303E -+:1035200090F8E93023F0010380F8E93090F8E930B1 -+:1035300013F0020F08D023F0020380F8E930C369CA -+:10354000724618693DF01CD910BDC04690F8E930AC -+:1035500010B5ABB9012902D0022902D003E0C0F8AE -+:10356000F02080F8E910C3691B6AC0F8EC3041F222 -+:103570000503C35C23B111466FF05E02FFF7B4FF91 -+:1035800010BDC04637B5044602F01CFFE3691A6A55 -+:1035900001321A6294F8E830002B77D041F262339E -+:1035A000E35A1BB1A4F86E38A4F8703841F26633C0 -+:1035B000E35A1BB1A4F86838A4F8643841F26433C4 -+:1035C000E35A1BB1A4F86238A4F86638E369196AB3 -+:1035D0001A6EB1FBF2F302FB131323B92046B4F8C1 -+:1035E000DA10FFF75FFED4F8F83013F00E0F05D1B4 -+:1035F0002046012194F8DA20FFF7A8FF94F8E9307B -+:103600004BB1E369D4F8EC201B6A9B1A052B02D955 -+:10361000002384F8E93041F22805615929B1E369B2 -+:103620001A6A1B6E521A9A420BD3D4F8F83013F070 -+:10363000020F06D12046FFF76FFA10B1E3691B6A4B -+:103640006351D4F8F83013F00F0F1FD1D4F88C3039 -+:103650000BB120469847E36918693DF005D868B179 -+:10366000E36901A918690DF107023DF007D820466A -+:103670009DF80710BDF80420FFF7FCFBD4F8F830E4 -+:1036800013F00F0F02D1204603F0C0F900203EBD19 -+:1036900010B50446FFF74AFA0221C2B22046FFF7EE -+:1036A00055FF10BDC36973B5012983F88110044625 -+:1036B0000D46C36906D9186901220323009300212E -+:1036C000134605E0186900210323009301220B46ED -+:1036D0003CF0FADFE269537F002B30D0D4F8B030F1 -+:1036E000D3F8203183F0010313F0010602D11069F1 -+:1036F0003DF050D8012D0FD90222134620464FF439 -+:103700008261FFF749F820464FF482610122022DC1 -+:1037100014BF002301230BE020464FF482610222F4 -+:103720000023FFF739F820464FF4826101222B462F -+:10373000FFF732F81EB9E36918693DF017D87CBD70 -+:10374000C36970B547F67F750446582118692A4643 -+:103750003CF0EEDFE3695A2118692A463CF0E8DFC5 -+:10376000E369702118692A463CF0E2DFE3697221BF -+:1037700018692A463CF0DCDF70BDC046F7B5C26967 -+:103780000546537F002B62D090F81A36002B45D0A7 -+:10379000106928213F223CF0CBDFEB692421186916 -+:1037A00010223CF0C5DFEB6995F82926186926211F -+:1037B00012013CF0BDDFEB6932211869B5F8FC2637 -+:1037C0003CF0B6DF2E460027EB691869204BF95C08 -+:1037D0003CF086DFEB6996F914250446A11D1869B3 -+:1037E00092B23CF0A5DF96F914250223E96992FB19 -+:1037F000F3F25242086992B204F10E0101373CF033 -+:1038000097DF0136082FDFD1EA690323009310699F -+:103810008022012113463CF057DF18E001460420C6 -+:1038200091F914350822073393FBF2F3DB000130E2 -+:1038300081F8143501310C28F2D195F91425EB6982 -+:10384000073218694E21C2F3CF023CF071DFFEBD92 -+:103850002503020010B5012102F0B6FC40B210BDF4 -+:1038600010B500210446621801317F23652982F8D2 -+:103870009136F8D12046FFF7EDFF2046FFF7C6FC52 -+:1038800010BDC0462DE9F04FB0F8DA30A5B003F412 -+:103890007041B1F5805F14BF022201220592D0F879 -+:1038A000A83004460693C3695A6C40F239539A42D1 -+:1038B00004D052339A4201D0002304E0B1F5805F76 -+:1038C00014BF00230123DBB2002165220DF1290082 -+:1038D0000893EEF3B5F3B4F8DAA00AF44073B3F545 -+:1038E000407F02D15FFA8AF810E0B3F5007F5FFAFB -+:1038F0008AF104D1DD2904D801F1020806E0022989 -+:1039000002D84FF0000801E0A1F102082046059915 -+:10391000FFF7A6FF2046FFF727FA4FF0000BC0B2D3 -+:10392000FF255E4607900395CDF810B070E0204665 -+:1039300051462A46FFF7F4F9002867D005EB040941 -+:1039400099F8B26224AA571907F8676C94F8AC305A -+:1039500043B1059A204641462B46FFF78FFB3018AE -+:1039600007F8670C41460DF18E020DF18F032046DA -+:103970000095FFF75BF999F82C269DF88F309A4255 -+:1039800034BF1146194641F2E623E25C53B2994234 -+:1039900001DC002002E0C2EB0103D8B224AB5919CC -+:1039A00011F8673C984234BF02461A4601F8672C6A -+:1039B00094F8E030642B06D803FB02F3642293FBF7 -+:1039C000F2F301F8673C11F8673C9DF88E20079EE2 -+:1039D0009A4238BF1A462B1993F891368DF88F000A -+:1039E000934294BFC6EB0306C6EB0206049AF3B2F9 -+:1039F0005B4588BF2A46049201F8673C039D5B45FE -+:103A000028BF9B46AB4238BF1D460395099E013631 -+:103A10000996099A142AD5B289D104F5A260002129 -+:103A20005132EEF30DF3039B049D84F8293684F89C -+:103A30002A360023184684F818B684F8F83684F835 -+:103A4000195616E024AE731813F8672C94F81A363A -+:103A5000091981F875250BB1089B1BB194F818362C -+:103A60009B1A03E094F82936C3EB020381F8103562 -+:103A700001301428C1B2E5D121460020069D91F9FC -+:103A80001035B5F9E623D218431CD8B281F81025B9 -+:103A900001310428F2D1E36A0BB12046984725B0E2 -+:103AA000BDE8F08F70B505460E462C46FFF774F959 -+:103AB000294600203218137D03B91379013081F8AB -+:103AC000383601310828F5D10021721892F84430B7 -+:103AD00003B91379013184F8483601340829F4D147 -+:103AE000EB6918693CF056DE2846FFF7CBFEEB6920 -+:103AF00018693CF03BDE70BD7F2970B5044601D9E2 -+:103B0000052028E0002213190132652A83F8B21239 -+:103B1000F9D10023E26984F8F736137FD3B1D4F8E2 -+:103B2000F83013F0020F15D1D4F8B030D3F82031AB -+:103B300083F0010313F0010502D110693CF02ADE85 -+:103B40002046FFF79FFE2DB9E36918693CF00EDEB1 -+:103B5000284600E0002070BD70B5054600F52C70C9 -+:103B6000042202300C46EEF307F205F52C70211DFD -+:103B700008220630EEF300F205F52E70082206301A -+:103B800004F10C01EEF3F8F105F538700822063067 -+:103B900004F13401EEF3F0F105F53A700822063035 -+:103BA00004F13C01EEF3E8F105F53070082206302F -+:103BB00004F11401EEF3E0F105F53270082206304D -+:103BC00004F11C01EEF3D8F105F53470082206303B -+:103BD00004F12401EEF3D0F105F536700822063029 -+:103BE00004F12C01EEF3C8F105F53C700822063013 -+:103BF00004F14401EEF3C0F105F53E7004F14C010F -+:103C000008220630EEF3B8F105F5407008220630C0 -+:103C100004F15401EEF3B0F105F5427006300822CC -+:103C200004F15C01EEF3A8F194F8643085F81633E2 -+:103C3000D5F8B030D3F8203113F0010309D11C4678 -+:103C40002846FFF71FFE54B1EB6918693CF08EDD82 -+:103C500005E0EB69012418693CF09CDDF0E770BDDC -+:103C60002DE9F0410F460546FFF710FA07F47043BF -+:103C7000B3F5805FEB69FAB208BF42F48072044684 -+:103C8000A02118693CF054DDAE6A2CB104F517721E -+:103C900041F2D413EA5005E005F59053303341F278 -+:103CA000D412AB5016B128463946B0472CB341F276 -+:103CB000D413EA58537873B1EB6941F2C8242959F7 -+:103CC00018693CF049DDEB6900221869295913464F -+:103CD0003CF0C0DC11E041F20723EB5C6BB1032B3D -+:103CE0000BD0E969D2F890200B6A9B1A8A6E934236 -+:103CF00003D328460221FFF7D5F928463946FFF7B6 -+:103D0000D1FABDE8F081C046E02910B50B46044663 -+:103D100002DD6FF0120012E043F430630E29D4BFCD -+:103D20004FF400514FF48051194389B2FFF798FFC7 -+:103D30000123204684F8D83008F092FF002010BDFF -+:103D400070B50C460546FFF767F844B9284605F0FC -+:103D5000D9FE28464FF4404106F0AEF910E0214666 -+:103D600028460022FFF7D0FF044648B928462146DE -+:103D70007022234605F04AFB28465E2106F0EEFD40 -+:103D8000204670BD2DE9F0410D460446FFF744F88A -+:103D900045B92046294602F0B3FC2F4641F2D42310 -+:103DA000E55213E0204629460122FFF7ADFF074602 -+:103DB00060B941F2D426A35B23B920460A21FEF75D -+:103DC000B9FCA0532046294602F09AFC3846BDE8CB -+:103DD000F081C04670B50E460546D0F8B040FFF7FA -+:103DE0001BF83EBB41F2D6240A2128462A5BFEF787 -+:103DF000ADFC284640F24B413246FEF7A7FC284670 -+:103E0000314602F0DDFBEB692E531B6D13F0020F00 -+:103E100056D041F2D823D5F8B020EB5A4FF47A703F -+:103E2000A2F89C3441F2DC23EB5AA2F89E34F2F360 -+:103E300093F445E0EB691B6D13F0020F1FD0D5F82A -+:103E4000B01041F2D822B1F89C344FF47A709BB292 -+:103E5000AB50B1F89E3404329BB2AB50B4F89C34F2 -+:103E600023F400731B041B0CA4F89C34B4F89E3498 -+:103E70009BB243F40073A4F89E34F2F36DF4314620 -+:103E800028460122FFF740FF0646C8B941F2D62472 -+:103E90002B5B5BB90A212846FEF74CFC40F24B41F4 -+:103EA00028534FF6FF722846FEF750FC28460121A2 -+:103EB00002F086FB28460A214FF49472FEF75CFC60 -+:103EC000304670BD2DE9F0418AB005AED0F8B07033 -+:103ED00005468846142238493046EEF34DF0142248 -+:103EE00036496846EEF348F0EB6900216C461869E4 -+:103EF000142288450CBF234633463CF023DC4FF0A8 -+:103F00000003A7F86835B8F1000F4FF48073A7F8E5 -+:103F1000C0370CBF40234123A7F80C3541F60223DC -+:103F2000A7F814354FF00003A7F80835A7F80A35AD -+:103F3000A7F84C354FF01403A7F86A3540F626036E -+:103F4000A7F868354FF00003A7F800354FF0D0030D -+:103F5000A7F80235B7F802350CBFFA251E25002454 -+:103F600002E00A20F2F3F8F3AC420ADAB7F80E35B1 -+:103F7000013413F0800FF4D103E00A20F2F3ECF3E4 -+:103F800000E0002401340B2C09D0B7F80E3513F4EF -+:103F9000806FF2D003E00A20F2F3DEF300E00024A9 -+:103FA00001340B2C04D0B7F8903613F4807FF2D193 -+:103FB0000AB0BDE8F081C046E0FC01003CFD010014 -+:103FC00070B590F8E2200446002A6CD1012380F8F5 -+:103FD000E230D0F8B030A0F8DA10D3F8203100F594 -+:103FE00081531A60D0F8F82012F0020F06D190F831 -+:103FF000803E1BB942F02003C0F8F830256A002D3E -+:1040000051D001212046FEF735FCB4F8DA30B4F87F -+:10401000DE2003F44061914203D0E36918693CF06B -+:1040200035DB012141F2CD23E1542046FFF792F91F -+:104030002046A847002384F8E1302046FFF79EFB86 -+:10404000E369204693F88110FFF72CFBE26992F8B0 -+:104050008030012BB4F8DA300BD103F47043B3F5A0 -+:10406000005F01D1936F0BE0D36F012B88BF00235A -+:1040700006E003F47043B3F5005F0CBF136F536F9A -+:10408000D366E3690022D96E2046FEF7D3FE0023F3 -+:1040900084F8E230E369922118693CF02BDB41F2AD -+:1040A00022234000E05270BDC36910B518693CF08E -+:1040B0002BDB10BDC36910B518693CF02FDB10BDB8 -+:1040C000F7B5089F04460D461E463BB1032A05D9A5 -+:1040D000684619460422EDF34FF701E000230093F0 -+:1040E000A82D009900F0FB8015DC5C2D00F0AE805F -+:1040F00008DC3C2D00F0A0804A2D00F093801B2DA1 -+:104100002AD020E05E2D30D0C0F2A8805F2D3DD0B7 -+:10411000872D1BD017E0C32D75D006DCAA2D49D002 -+:104120007BDBC22D00F0DB800DE0D42D00F0AB80F6 -+:1041300003DCD32D00F09B8005E0A5F59A73033BCB -+:10414000012B40F2D2806FF01605CFE02046FEF73B -+:104150007DFE40B23060C8E0E3691D7F002D40F075 -+:10416000B8802046FEF77AFBC0E001233B70E3698C -+:104170005B7F002B00F0B0802046FFF79BFF2046BE -+:10418000BDF80010FEF7D6FA30600FE001233B7057 -+:10419000E3695B7F002B00F09F802046FFF78AFFDA -+:1041A000009A204691B2120CFEF7D0FA2046FFF793 -+:1041B0007BFF9AE0E269537F002B00F08D8010694D -+:1041C0003CF0E8DA00252046FFF774FF3560D4F8AC -+:1041D000BC30082B13D10DF1060220460DF107016A -+:1041E0008DF807508DF8065000F0AAFE9DF90720C3 -+:1041F0009DF9063092B29BB243EA02233360204617 -+:10420000FFF752FF60E0E3691B7F002B6AD0338821 -+:10421000022B64D96FF0010568E0E3691B7F002B76 -+:1042200060D05CE0E3691B7F002B52D1236B002B35 -+:104230005BD02046984718E0E3691B7F002B48D1EC -+:1042400020467268B368FFF7C5FD0EE0E3691B7F87 -+:10425000002B3ED12046FFF773FD06E0E3691B7F8C -+:10426000002B36D12046FFF78DFD05463EE0E36981 -+:10427000DA6E3260D4F8F83F13F0010F35D042F017 -+:104280008003336031E0042902D96FF01C052DE072 -+:10429000E269D36E8B4228D0137FD1662BB31069AD -+:1042A0003CF078DA009B23B1204600210122FEF782 -+:1042B000C1FDE36901222046D96EFEF7BBFD00284F -+:1042C00014BF00256FF00205E36918693CF04EDA6F -+:1042D0000CE06FF0040509E06FF00A0506E06FF0EE -+:1042E0000C0503E06FF0030500E000252846FEBD45 -+:1042F0002DE9F04389B09946109B0026032B074611 -+:104300000C46DDF84480139D079604D907A849465A -+:104310000422EDF331F6079940F286230A1E18BFF6 -+:1043200001229C4200F013812CD80C3B9C427CD093 -+:104330000FD8532C08D8522C80F04081502C00F01C -+:104340003D81512C6AD02DE140F26A239C4250D02D -+:1043500028E1B4F5207F00F0E48009D840F27B2307 -+:104360009C4200F0A48003339C4200F0D58019E108 -+:10437000B4F5217F00F0E48040F285239C4200F0F8 -+:10438000DB800FE140F2D6239C4200F0178114D865 -+:10439000413B9C423ED006D8043B9C4234D0023381 -+:1043A0009C4234D0FEE0B4F5277F00F0D78040F285 -+:1043B0009D239C4200F0D680F4E040F2DD239C4235 -+:1043C00000F0EB8008D8033B9C4200F0D180B4F5AC -+:1043D000377F00F0D680E5E0B4F53D7F00F0F38054 -+:1043E000C0F0E080A4F53E73063B012B00F2DA80BA -+:1043F000E9E03846FFF75EFE38464146FFF706F82B -+:104400003846FFF751FE50E041F2623304E041F2DA -+:10441000643301E041F26633F95246E00123009330 -+:1044200038464346FEF722FDCFE0FA69137F13B901 -+:104430006FF00300C9E0D7F8B030D3F8203183F033 -+:10444000010313F0010902D110693CF0A3D93846E9 -+:10445000FEF72EFE3846FFF72DFE41F2E61341F23D -+:10446000E910F95C385C0133FA5C013317F803E0BA -+:10447000009041F2EA103D5C01303C5C1630385C43 -+:10448000734603903846019502940496FEF764FE45 -+:10449000C8F800003846FFF707FEB9F1000F40F0FA -+:1044A0008D80FB6918693CF061D930468DE0C1F31D -+:1044B000036CBCF1010F00F28380C1F3015EBEF119 -+:1044C000010F7DD8C1F38155032D79D0C1F3034489 -+:1044D000012C75D8C1F30722A2F10A03DBB2052B28 -+:1044E0006ED8C8B2012801D9032869D10E2A28BF85 -+:1044F0000E2241F2E613FA540133F8540133FC540E -+:10450000013307F803E00133FD54013307F803C01A -+:104510000A0F1633FA54C8E708A9012341F8043DED -+:1045200007E0B7F8DA103846FEF72EFB08A941F885 -+:10453000040D40462A462DE041F21B03F954B4E72E -+:1045400041F21B03FB5C08A941F8043D17E0D7F8D2 -+:10455000F830C3F30013C8F80030A6E738464246E7 -+:10456000334602E0384642460123FEF765FE9CE7EB -+:104570000121384601F03AFF08A941F8046D404690 -+:1045800007E007AC38463146224601F093FF40462B -+:1045900021460422EDF3F0F487E73846324601F075 -+:1045A00089FF82E701910292384621464A464346F6 -+:1045B0000095FEF711FF10F1170F04D0002004E062 -+:1045C0006FF01C0001E06FF0160009B0BDE8F08349 -+:1045D0002DE9F04391460A6801230B7342F008036A -+:1045E0000B60B0F9FA3685B0B3F1FF3F04BF42F07B -+:1045F00009030B6090F81A3605460C461BB10B6890 -+:1046000043F002030B602F4626464FF0000897F850 -+:10461000B2322846B37749460DF10E030DF10F0271 -+:10462000CDF80080FEF702FB9DF80E3008F101087E -+:1046300086F8B03197F87535013786F8793201364A -+:10464000B8F1140FE3D195F81A3633B3EB691B7F39 -+:104650001BB32846FFF72EFD95F818362846A3759C -+:1046600095F81836E37595F81936A37695F8193646 -+:10467000E37600F05BFC236810B143F0030301E034 -+:1046800023F003032846236004F10D0104F1150211 -+:1046900000F056FC2846FFF707FD05B0BDE8F083A3 -+:1046A00010B5054B1B78012B03D1013B18461B703D -+:1046B00001E014F00BFE10BD3C28020010B5054BC4 -+:1046C0001B78012B03D1013B18461B7001E014F04D -+:1046D00023FE10BD3C2802002DE9F04105460E46A0 -+:1046E00017461C46FFF7EAFF30B1234628463146FD -+:1046F0003A4614F04BFE04462046BDE8F081C04621 -+:1047000010B50023FFF7E8FF10BDC04610B51446F2 -+:10471000FFF7D4FF20B100210A46EEF319F004465A -+:10472000204610BD10B50022FFF7F0FF10BDC046B7 -+:104730001FB5079B0C890093089B11460193099BA9 -+:10474000224602930A9B03930069069B28F02EDD04 -+:1047500004B010BD00B5B0FBF1FE01FB1E0001F07E -+:10476000010C0CEB51010BE0884228BFC1EB0003A8 -+:104770004FEA4E0E26BF0CEB43000EF1010E400037 -+:10478000531EDAB2FF2AEFD1884228BF0EF1010E84 -+:10479000704600BD00FB01F19202800103FB002086 -+:1047A00001F5004101EB4000490090FBF1F070473A -+:1047B000D0F8A8304FF001025A8670472DE9F04733 -+:1047C00098469DF820308A4691469DF82470B3B1F2 -+:1047D00000246FF000462546204651464A4643468F -+:1047E000FFF7D8FFB04204DA6B1CDDB2BD421AD02D -+:1047F00006460134802CEFD16FF0004013E07F2497 -+:104800004FF0FF361D46204651464A464346FFF7C5 -+:10481000C1FFB04204DD6B1CDDB2BD4203D00646D1 -+:10482000013CF0D22046BDE8F087C04610B5B0F894 -+:10483000DA300446DAB203F47043B3F5005FD0F81F -+:10484000A81003D1531893F8E72486E0702A5ED0AD -+:104850001CD8382A49D00CD82C2A3DD004D8242A78 -+:1048600034D0282A35D02FE0302A38D0342A39D015 -+:104870002AE0642A42D004D83C2A39D0402A3AD0CF -+:1048800022E0682A3DD06C2A3ED01DE0882A50D014 -+:104890000CD87C2A44D004D8742A3BD0782A3CD047 -+:1048A00012E0802A3FD0842A40D00DE0992A49D0D6 -+:1048B00004D88C2A40D0952A41D005E0A12A47D0BF -+:1048C000A52A48D09D2A40D0002246E091F8F6243F -+:1048D00043E091F8F72440E091F8F8243DE091F8A6 -+:1048E000F9243AE091F8FA2437E091F8FB2434E017 -+:1048F00091F8FC2431E091F8FD242EE091F8FE249B -+:104900002BE091F8FF2428E091F8002525E091F8AC -+:10491000012522E091F802251FE091F803251CE013 -+:1049200091F8042519E091F8052516E091F806257F -+:1049300013E091F8072510E091F808250DE091F8B3 -+:1049400009250AE091F80A2507E091F80B2504E013 -+:1049500091F80C2501E091F80D25D1F8E40494F8C4 -+:104960002A36C01A801840B210BDC04608467047AB -+:1049700049B24B1C5B104910C3F10803083141EAEE -+:10498000031188B27047C046B0F8DA3003F47043C0 -+:10499000B3F5005FD0F8A82005D192F83C05FF28B8 -+:1049A00001D0C0B200E000207047C04670B5054697 -+:1049B000D0F8A840FFF7E8FF10B994F8460540B1D9 -+:1049C000B5F8DA3003F47043B3F5005F14BF00208C -+:1049D000012070BD10B50C468EB0D0F8A8109646D8 -+:1049E000002000220DF10603C25401303228F8D114 -+:1049F000BEF1FF3F91F8E93306D114B1B1F93EE5BC -+:104A000003E0B1F940E514E09CB1A02B09D00023EC -+:104A10008DF806308DF807308DF808308DF80930A4 -+:104A200004E000238DF806308DF808308DF80A3048 -+:104A300033E0A02B17D001238DF81A308DF81B30EE -+:104A40006FF0010300228DF81E308DF81F30013306 -+:104A50008DF81C208DF81D208DF820208DF8213038 -+:104A60008DF8242019E002238DF81A306FF003032B -+:104A70008DF81E30023300228DF81F308DF8203063 -+:104A80008DF8213006338DF81B208DF81C208DF811 -+:104A90001D208DF824208DF832300EAA02EB0E0373 -+:104AA00013F9320C0EB010BD30B5C46900F5805357 -+:104AB000226A1B68D0F8A8509A4202D3C3EB0201C5 -+:104AC00001E0DB43991895F8BC2290F8DA309A425D -+:104AD00001D0012004E0A36E994234BF00200120E0 -+:104AE00030BDC0467047C046D0F8A83093F80604E1 -+:104AF000002808BF1020704700B5D0F8A8008E46E7 -+:104B0000D0F8D4240EF0FF0343EA0223110EC0F8BC -+:104B1000D434D0F8D8347F29C8BFA1F5807173444C -+:104B20005B1AC0F8D8349B10C0F8DC3400BDC04616 -+:104B3000844610221B4810B5964600244EF34603C7 -+:104B40005FFA83FE10EA0C0F4FFA8EF104D0884012 -+:104B50000EEB0203DAB203E0C840CEEB0203DAB296 -+:104B60000134042CEAD110EA0C0FD3B201D1013B7D -+:104B7000DAB251B2032301FB03F30329DAB20EDDEB -+:104B8000CB1E2CFA03F00D2801D9D31C06E00A280D -+:104B900001D9931C02E0082801D9531CDAB250B2A3 -+:104BA00010BDC0460000FFFFD0F8A820002382F807 -+:104BB000903382F8913382F8923382F8933382F8FB -+:104BC000943370477047C04670B540F22341D0F827 -+:104BD000A8500446FDF7AEFDC0B2A5F864034FF43B -+:104BE000AA612046FDF7A6FD8005800DA5F86803A3 -+:104BF00040F234412046FDF79DFDC0B27F28C8BF7A -+:104C0000A0F58073A5F8660340F23241C8BFA5F84D -+:104C100066332046FDF78EFDC0B27F28C4BFA0F5E5 -+:104C2000807398B285F8BC0370BDC0462DE9F0478B -+:104C3000884640F2B76104469146FDF77BFD40F29D -+:104C4000B66105462046FDF775FD40F2B5610646A2 -+:104C50002046FDF76FFD40F2B46107462046FDF7A0 -+:104C600069FD4FF0000C6246644650FA04F313F0FD -+:104C7000010101D0012103E00CF101035FFA83FC83 -+:104C8000531CDAB2102A12D001340029EDD00EE004 -+:104C9000A2F1100357FA03F313F0010F01D0012121 -+:104CA00003E00CF101035FFA83FC531CDAB21F2A04 -+:104CB00011D80029ECD00EE0A2F1200356FA03F33C -+:104CC00013F0010F01D0012103E00CF101035FFAA1 -+:104CD00083FC531CDAB22F2A11D80029ECD00EE045 -+:104CE000A2F1300355FA03F313F0010F01D00121B3 -+:104CF00003E00CF101035FFA83FC531CDAB23F2A94 -+:104D000001D80029ECD04FF03F0E00220F2455FAB5 -+:104D100004F313F0010101D0012103E00EF1FF3390 -+:104D20005FFA83FE531CDAB2102A12D0013C00292C -+:104D3000EDD00EE0C2F11F0356FA03F313F0010F9A -+:104D400001D0012103E00EF1FF335FFA83FE531C13 -+:104D5000DAB21F2A11D80029ECD00EE0C2F12F03DD -+:104D600057FA03F313F0010F01D0012103E00EF114 -+:104D7000FF335FFA83FE531CDAB22F2A11D80029C1 -+:104D8000ECD00EE0C2F13F0350FA03F313F0010F31 -+:104D900001D0012103E00EF1FF335FFA83FE531CC3 -+:104DA000DAB23F2A01D80029ECD088F800E089F86F -+:104DB00000C0BDE8F087C04670B50D4640F23941ED -+:104DC0000646FDF7B7FCC0F3C210E88040F2B541DB -+:104DD0003046FDF7AFFC40F2FB4104463046FDF79C -+:104DE000A9FC04F0FF03C0B2C4F307242B806C803D -+:104DF000A88070BD2DE9F047B0F8DA30074603F41B -+:104E00007043B3F5805FD0F8A82009D1B2F89205BD -+:104E100003B2B3F1FF3F0CBF4FF4C87080B24CE057 -+:104E2000B2F8904523B2B3F1FF3F01D0A0B244E005 -+:104E300040F2A541FDF77EFC40F2A541814638468F -+:104E4000FDF778FC40F20D4106463846FDF772FC4E -+:104E500040F20D4104463846FDF76CFC40F2A24199 -+:104E600005463846FDF766FC40F2A24180463846CA -+:104E7000FDF760FCC6F30236012313FA06F6C0F311 -+:104E80000220C5F3022513FA05F58340E4B25FFA68 -+:104E900089F94C44B6B2A419ADB29BB25FFA88F856 -+:104EA0006419434404EB430464005034A4B2B4F5E1 -+:104EB000C86F2CBF20464FF4C860BDE8F087C046DD -+:104EC00010B540F2FB41FDF735FCC0F3062010BDE4 -+:104ED00070B540F2A4410446D0F8A850FDF72AFC72 -+:104EE000C0F38130032814D141F22403E35C83B181 -+:104EF000204640F27341FDF71DFC95F96635C0056B -+:104F0000C00D013303FB00F3022293FBF2F3D8B28E -+:104F100001E095F8C10240B270BDC04610B540F244 -+:104F2000A441FDF707FC00F4404010BD10B5FFF7A9 -+:104F3000F5FFB0F5404F14BF0020012010BDC04662 -+:104F400070B5002313700B7041F22403C35C044658 -+:104F50000D4616461BB340F2AB41FDF7EBFB10F4D8 -+:104F6000004F03D0204640F2AB410AE0204640F219 -+:104F70003C61FDF7DFFB10F4004F07D0204640F204 -+:104F80003C61FDF7D7FBC0F3470028702046FFF7D0 -+:104F9000CDFF08B194F810052B781B18337070BD45 -+:104FA0002DE9F04140F2FF340E4605469046334667 -+:104FB000224640F24561FDF7EFFB28462246434674 -+:104FC00040F24661FDF7E8FB28462246334640F2B0 -+:104FD0004761FDF7E1FB2846224643464FF4C9618D -+:104FE000FDF7DAFB28462246334640F24961FDF7D9 -+:104FF000D3FB284640F24A6122464346FDF7CCFBEC -+:10500000BDE8F08170B5002914BF4FF48073002310 -+:1050100004460D1E18BF01254FF480724FF49661AF -+:10502000FDF7BAFB0122204640F24C412B46FDF72A -+:10503000B3FB2B0320464FF496614FF4805203F4E8 -+:105040007043FDF7A9FB6B0320464FF496614FF4C4 -+:10505000005203F46043FDF79FFB6B0120229BB2DB -+:1050600020464FF49661FDF797FB6B0203F47E43F5 -+:10507000204640F2AE414FF40072FDF78DFBB4F8CC -+:10508000DA3003F47043B3F5005F11D1AB02204670 -+:105090004FF496614FF4806203F47C43FDF77CFB90 -+:1050A000EB009BB2204640F2E5410822FDF774FB7D -+:1050B00070BDC04670B50C02A4B20546234640F24E -+:1050C000FB414FF4FE42FDF767FB284640F2FD41ED -+:1050D0004FF4FE422346FDF75FFB70BD70B500291B -+:1050E00014BF802300230C1E18BF012480224FF41C -+:1050F00096610546FDF750FBA303A40128464FF433 -+:1051000096614FF4804203F44043A4B2FDF744FBA0 -+:10511000284640F23B4140222346FDF73DFB70BD4F -+:1051200070B540F239440D4621460646FDF702FBB4 -+:1051300040F67F4300EA030343EAC51330462146A5 -+:1051400040F6FF729BB2FDF727FB70BD2DE970435F -+:105150000C460646FFF7B4FE628823884FF6FF79B7 -+:1051600043EA022305464A46304640F2B5419BB227 -+:10517000FDF712FB2D02A388ADB247F6FF7830464B -+:10518000424645EA030340F2FB41FDF705FB628816 -+:105190002388304643EA022340F2FC414A469BB250 -+:1051A000FDF7FAFAA3883046424645EA030340F287 -+:1051B000FD41FDF7F1FA3046E188FFF7B1FF3046D7 -+:1051C0000121FFF78BFFBDE87083C04610B502498F -+:1051D0000C22FDF7F5FA10BD380D02002DE9F0475D -+:1051E0009846BDF82CA0BDF824308946BDF82010A3 -+:1051F0000AF00304164603F00F03BDF8282044EA22 -+:10520000032301F00F0102F0030243EA013343EAF2 -+:10521000821343EA021343EA840340F2B6414FF695 -+:10522000FF720746BDF83050FDF7B6FA0F2208EAC4 -+:105230000203384640F2B741FDF7AEFA4FEACA23FF -+:105240009CB22346384640F2B1414FF460522D03E0 -+:10525000FDF7A2FAADB2062238462049FDF7B0FAB2 -+:105260007602384640F2AE414FF470422B46FDF7CD -+:1052700093FA384640F2B1414FF4007206F47E438F -+:10528000FDF78AFAD9F1010338BF0023012238461D -+:1052900040F24D41FDF780FAB7F8DA3003F470437D -+:1052A000B3F5005F10D1384640F2B1414FF4C0521F -+:1052B0002346FDF771FA4FEACA039BB2384640F223 -+:1052C000E6411822FDF768FA384640F2AE414FF445 -+:1052D00070422B46FDF760FABDE8F087A209020094 -+:1052E00010B5044686B021B90D490E22FDF768FAC3 -+:1052F00014E00C490922FDF763FA0021032206237A -+:10530000009302920423039220460A4604910193DB -+:10531000FFF764FF20460121FFF774FE06B010BDC1 -+:10532000420702005E07020010B5D0F8A830D3F89B -+:10533000741529B1C3694FF420729868F1F3D8F459 -+:1053400010BDC0462DE9F041D0F8A8300646D3F88C -+:105350007C55D3F8787500240DE0142302FB03F389 -+:10536000EA1811695268F06902FB01F28068E95895 -+:10537000D208F1F3BDF4E2B20134BA42EDD3BDE894 -+:10538000F081C04670B5D0F8A8500446D5F87C35F9 -+:105390006BB10121FFF7D6FFE369D5F878451422F8 -+:1053A0009868D5F87C1504FB02F2F1F3A1F470BD06 -+:1053B00041F2F023C15810B5044629B1C36942F641 -+:1053C00008529868F1F394F42046FFF7ADFF2046A9 -+:1053D000FFF7D8FFE369D4F8A81098684FF4B962D2 -+:1053E000F1F386F410BDC04610B54FF48052044668 -+:1053F000002340F2C961FDF7CFF9D4F8A820B2F834 -+:10540000C234EBB192F8E933A02B04D1204640F22C -+:105410008961232203E0204640F289613022FDF7B2 -+:1054200095F9D4F8A830B3F8C234022B0ED14FF45A -+:105430008052204640F2C9611346FDF7ADF905E000 -+:10544000204640F289612322FDF780F9042220469C -+:105450002749FDF7B5F90022204640F27961FDF7B2 -+:1054600075F9082220462349FDF7AAF9D4F8A83097 -+:105470002046B3F8C2244FF4D961FDF767F906223C -+:1054800020461D49FDF79CF9D4F8A8304FF48072EE -+:10549000B3F8C23420461A41013A4FF4D06192B2B7 -+:1054A000FDF754F9D4F8A8304FF4A072B3F8C23421 -+:1054B00020461A41013A92B240F28161FDF746F965 -+:1054C000D4F8A830B3F8C224012A04D0022A14BFA9 -+:1054D0003422082200E01822204640F27F61FDF7C6 -+:1054E00035F9204605490E22FDF76AF910BDC04680 -+:1054F000440B02004C0B02002E0C02003A0C02007E -+:105500002DE9F04740F23C4631460446FDF712F9DA -+:1055100040F23B48824641462046FDF70BF94AF0EF -+:10552000010281463146204692B2FDF70FF949F05B -+:105530000102204641464FF6FE7592B2FDF706F98C -+:10554000204631460AEA0502FDF700F920464146A9 -+:1055500009EA0502FDF7FAF8204631465246FDF702 -+:10556000F5F8204641464A46FDF7F0F8BDE8F087D9 -+:10557000802270B513460C4640F2D1610546FDF716 -+:105580000BF90CB1012C05D128464FF4DA610F223A -+:10559000FDF7DCF82846FFF7B3FF70BD2DE9704337 -+:1055A0000E46B0F8DA10054601F47041B1F5005F1F -+:1055B00014BFA521892199469046FDF731F8B5F829 -+:1055C000DA10044601F47041B1F5005F14BFA52163 -+:1055D00089212846FDF724F804F00F04C0F30310D6 -+:1055E000241A3470B5F8DA10284601F47041B1F588 -+:1055F000005F14BFA6218A21FDF712F8B5F8DA1072 -+:10560000044601F47041B1F5005F14BFA6218A2160 -+:105610002846FDF705F804F00F04C0F30310241A20 -+:1056200088F80040B5F8DA10284601F47041B1F569 -+:10563000005F14BFA7218B21FCF7F2FFB5F8DA1049 -+:10564000044601F47041B1F5005F14BFA7218B211E -+:105650002846FCF7E5FF04F00F04C0F30310241AFA -+:1056600089F80040B5F8DA10284601F47041B1F528 -+:10567000005F14BFA8218C21FCF7D2FFB5F8DA1027 -+:10568000044601F470412846B1F5005F14BFA8211B -+:105690008C21FCF7C5FF04F00F04C0F30310069B38 -+:1056A000241A1C70BDE87083B0F8DA1010B501F44C -+:1056B00070410446B1F5005F14BFA52189218822FD -+:1056C000FCF7C6FFB4F8DA10204601F47041B1F5DA -+:1056D000005F14BFA6218A218822FCF7B9FFB4F825 -+:1056E000DA10204601F47041B1F5005F14BFA72124 -+:1056F0008B218822FCF7ACFFB4F8DA10204601F4C5 -+:105700007041B1F5005F14BFA8218C218822FCF7FD -+:105710009FFF10BD10B5D0F8A830044693F8E933C8 -+:10572000A02B03D110490422FDF74AF8204600229D -+:105730004FF48E71FCF78CFF204618220B49FDF7C1 -+:105740003FF841F2EE23E35A2046FF2240F2346153 -+:10575000002B08BF0C23FDF71FF82046044909223F -+:10576000FDF72EF810BDC046580D0200600D020076 -+:10577000900D020070B504220D4607490646FDF75C -+:105780001FF80024054B625BE15A30460234FCF7F7 -+:105790005FFF302CF6D170BDD60B0200D2040200A0 -+:1057A0002DE97043054698461646B0F8DA40FFF7F3 -+:1057B000DFF804F47044B4F5005F14BFA524892415 -+:1057C0000246214628469DF81890FCF741FF3146D5 -+:1057D0002846FFF7CDF8B5F8DA40024604F47044E5 -+:1057E000B4F5005F14BFA6248A2428462146FCF79E -+:1057F0002FFF41462846FFF7BBF8B5F8DA400246CE -+:1058000004F47044B4F5005F14BFA7248B24284629 -+:105810002146FCF71DFF49462846FFF7A9F8B5F8D1 -+:10582000DA40024604F47044B4F5005F14BFA824C3 -+:105830008C2428462146FCF70BFFBDE87083C04648 -+:1058400070B505460E460024074BA25BE15A284678 -+:105850000234FCF7FDFE182CF6D1284603492246F7 -+:10586000FCF7AEFF70BDC046800B0200880C020042 -+:1058700070B506220E4644490446FCF7A1FF0025F8 -+:10588000424B2046E95AFCF7CBFEA8530235182DAF -+:10589000F6D1072101222046FCF7DAFE1022FF2173 -+:1058A00013462046FCF71AFF04221346204640F216 -+:1058B0001F11FCF713FF0C2220463549FCF780FF2F -+:1058C00001223A2113462046FCF708FF04223A2120 -+:1058D00013462046FCF702FF0822134620464FF4E9 -+:1058E0008D71FCF7FBFE0822052113462046FCF7CC -+:1058F000F5FE0122134620464FF48D71FCF7EEFEB3 -+:10590000122220462349FCF75BFF20228221134606 -+:105910002046FCF7E3FEB4F8DA3003F47043B3F545 -+:10592000005F02D000252E4608E0D4F8A8309A7A0D -+:10593000D97A42F400721D7B42EA01160122204608 -+:1059400013464FF49B61FCF727FF2046B3004FF44A -+:105950009B6140F6FC72FCF71FFF022220461346B3 -+:105960004FF49B61FCF718FF2B0320464FF49B611B -+:105970004FF4E04203F47043FCF70EFF2046064963 -+:105980000622FCF71DFF70BD16080200800B020006 -+:10599000AE090200C6090200EA0902002DE9F74F2C -+:1059A000D0F8A830814693F80B809C7A1A7E1F7B32 -+:1059B0004FEA081844F4007493F817B09E7D44EA47 -+:1059C0000804009293F814A0DD7C44EA07345B7D60 -+:1059D00047F2FF38A4B2092223490193FCF7F0FEF5 -+:1059E00048464246234640F2DB41FCF7D5FE484696 -+:1059F0004246234640F2DC41FCF7CEFE4846424692 -+:105A0000234640F20A41FCF7C7FE4FEA0A1A019BFF -+:105A100045F4007545EA0A0545EA0335484642461D -+:105A2000ABB240F20B41FCF7B7FE4FEA0B1B009AFA -+:105A300046F4007646EA0B0646EA023648464246F7 -+:105A4000B3B240F20C41FCF7A7FE20224846822167 -+:105A50001346FCF743FE012248467C211346FCF71F -+:105A60003DFEBDE8FE8FC046C40B0200012970B5A3 -+:105A700005460C4616D106222949FCF7A1FE284608 -+:105A80003A2122462346FCF729FE082228461346DF -+:105A90004FF48D71FCF722FE28467F210022FCF78F -+:105AA000D7FD33E079B91F490622FCF789FE284665 -+:105AB0003A2101222346FCF711FE082228464FF422 -+:105AC0008D71134620E0022920D1B0F8DA3003F4BA -+:105AD0007043B3F5005F02D17D21032201E07D21F7 -+:105AE0002246FCF7B5FD284628210F220123FCF7AA -+:105AF000F5FD8022134628464FF48971FCF7EEFD30 -+:105B00002846052107220223FCF7E8FD284640F23B -+:105B100037614FF440420023FCF73EFE70BDC046A3 -+:105B2000AE060200560C02002DE9F047C369D0F81A -+:105B3000A8501B6D0C4613F4805F40F2234114BF44 -+:105B40004FF006094FF00909064695F844A3FCF703 -+:105B5000F1FD40F2344107463046FCF7EBFD2046AC -+:105B6000FEF7E6FF95F84433C1B2B5F8642395F823 -+:105B700048030BB9012092E007F0FF07C0EB0103D7 -+:105B8000C2EB07029B1A5FFA83F84FFA88F4002CE5 -+:105B90001DDAF36930461B6D03F48053002B0CBFF4 -+:105BA0000B21042114BF0322082263429A42A8BF9A -+:105BB0001A46B5F8683301FB02324FF4AA6192B27B -+:105BC000FCF7C4FD14F1030F06DAFB1C05E0032CFF -+:105BD00002DDFB1E9BB200E0BBB2B5F8640319B254 -+:105BE00002B2D31C994201DDC31C03E09142ACBF59 -+:105BF0000B4613469CB2BAF1000F13D023B2BB423E -+:105C000010D02346304640F22341FF22FCF7C4FD6A -+:105C1000304624490422FCF7D3FD1420F0F39CF510 -+:105C2000002700E00127B5F866434FFA88F220B25A -+:105C3000C9EB000352429A42B8BFC9EB040391B2C8 -+:105C4000B8BF99B20AB200F109039A42C4BF04F185 -+:105C5000090399B2B6F8DA3003F47043B3F5005F84 -+:105C60000CBF95F94B3395F94C335B189BB2BAF1E5 -+:105C7000000F05D0304640F23441FF22FCF78CFD86 -+:105C8000304640F22341FCF755FD95F8BC33C0B2D5 -+:105C900085F8BD0385F8BE0385F8BF333846BDE8F7 -+:105CA000F087C0465C0B020070B5D0F8A8500446DF -+:105CB000FF22B5F8663340F23441FCF76DFDB5F8CC -+:105CC00064332046FF2240F22341FCF765FD204665 -+:105CD000B5F868234FF4AA61FCF738FD2046044963 -+:105CE0000422FCF76DFD1420F0F336F570BDC046BC -+:105CF0008A050200082270B5134605465721FCF7B5 -+:105D0000EDFC56212846FCF78BFC00F0F8045621E8 -+:105D100022462846FCF79CFC0120F0F31DF5562195 -+:105D200044F003022846FCF793FC0120F0F314F53D -+:105D3000562144F007022846FCF78AFC4FF496707F -+:105D4000F0F30AF52846572108220023FCF7C6FC89 -+:105D500070BDC0462DE9F04140F24A4631468046CA -+:105D6000FCF7E8FC40F04404A4B24FF6BF7540468F -+:105D70003146224604EA0505FCF7E8FC31462A468E -+:105D80004046FCF7E3FC25F004050420F0F3E4F4BE -+:105D9000404631462A46FCF7D9FCBDE8F081C046B2 -+:105DA0002DE9F04706460C461546384906221F469F -+:105DB000DDF82090BDF82480FCF702FD304640F26B -+:105DC00082414FF6FF722346FCF7E6FC304640F274 -+:105DD0008141FF222B46FCF7DFFC3FB9304640F201 -+:105DE00081414FF480723B46FCF7D6FC304628498F -+:105DF0000322FCF7E5FC0A2308FB03F5002407E077 -+:105E0000AC4201DD002439E06420F0F3A5F4013454 -+:105E1000304640F28141FCF78DFC10F4007FEFD159 -+:105E200040F283413046FCF785FC40F28441044651 -+:105E30003046FCF77FFC40EA0440C9F8000040F21D -+:105E400085413046FCF776FC40F2864104463046F8 -+:105E5000FCF770FC40EA0440C9F8040040F28741B6 -+:105E60003046FCF767FC4FF4916104463046FCF77E -+:105E700061FC40EA0440C9F80800012430460549A5 -+:105E80000622FCF79DFC2046BDE8F087980702003B -+:105E9000F40502002A06020070B50546002407E05A -+:105EA0006420F0F359F4013441F289339C4207D065 -+:105EB000284640F25141FCF73DFC10F4404FEFD131 -+:105EC000284640F25141FCF735FC10F4404F14BF16 -+:105ED0000020012070BDC04610B540F24C414FF685 -+:105EE000FC72FCF73BFC10BDC36970B504460D465F -+:105EF00018698E2116463AF0FDDBE3694119490025 -+:105F0000186932463AF014DC70BDC046C36970B5FA -+:105F100004460D4618698E213AF0ECDBE36941191D -+:105F2000490018693AF0E6DB70BDC0462DE9F04142 -+:105F30000C46272180461646FFF7E8FF10F00103C4 -+:105F400002D101271D4605E04FF6F07500EA050570 -+:105F50004FF6F07728214046FFF7D8FF3840A84297 -+:105F600001D1012009E0013C631C002B02DD14205B -+:105F7000F0F3F2F3002CEDDC002006B13460BDE854 -+:105F8000F081C0462DE9F0410646D0F8A850FEF752 -+:105F9000C5FFB0F5404F46D1F369E02118693AF0EA -+:105FA000A9DBEC8D8046C4EB000440F2A5413046ED -+:105FB000FCF7C0FB0123C0F30227BB40A4B29C4204 -+:105FC00031DD95F8C134A5F82E80BB4208D90137E0 -+:105FD000304640F2A5414FF4E0623B02FCF7DCFBA7 -+:105FE0003046FEF775FF40B280B22886B6F8DA3048 -+:105FF0006F8603F47043B3F5005F0CBF85F854045B -+:1060000085F85504D6F8A8202B8E92F966255B00FA -+:10601000013293FBF2F3304640F2A44140F2FF120A -+:106020009BB2FCF7B9FBBDE8F081C0462DE9F04F0B -+:10603000044685B00D46D0F8A860FFF7A3FFD4F85A -+:10604000B030D3F8203183F0010313F00103039340 -+:1060500003D1E36918693AF09DDB07212046FCF77C -+:10606000DFFAFF2101902046FCF7DAFA40F21F1117 -+:1060700002902046FCF7D4FA40F23B41834620468A -+:10608000FCF758FB40F23C4182462046FCF752FBAD -+:1060900040F2D74181462046FCF74CFB4FF49B6110 -+:1060A00080462046FCF746FB0F224649074620461D -+:1060B000FCF786FB0122072113462046FCF70EFB66 -+:1060C0001022FF2113462046FCF708FB042213464A -+:1060D00040F21F112046FCF701FB0A20F0F33CF3CD -+:1060E000202220464FF49A611346FCF755FB0A2004 -+:1060F000F0F332F3012D21D140F276412046FCF736 -+:1061000019FB40F27741C5052046FCF713FBC0059B -+:10611000C00DED0DFF288ABFA0F5007302469AB2AC -+:10612000FF2D88BFA5F50073A6F86E058CBF98B249 -+:106130002846C0EB0203A6F86C550AE0204640F260 -+:106140007541FCF7F7FAC005C00DFF2803D9A0F58B -+:1061500000739DB200E00546019B2046DAB207219C -+:10616000FCF776FA029B2046DAB2FF21FCF770FAC0 -+:10617000204640F21F115FFA8BF2FCF769FA2046C5 -+:1061800040F23B415246FCF7E1FA204640F23C41E6 -+:106190004A46FCF7DBFA204640F2D7414246FCF77C -+:1061A000D5FA20464FF49B613A46FCF7CFFA039BA1 -+:1061B0001BB9E36918693AF0D9DA28B205B0BDE82D -+:1061C000F08FC046F807020070B5D0F8A83001295A -+:1061D000D3F8DC63D3F8D853D3F8E04304D10131CA -+:1061E000FFF724FF02B20AE040F27541FCF7A2FA81 -+:1061F000C005C00DFF288CBFA0F500720246631FCA -+:1062000001209840801905FB1200231F184140B25D -+:1062100070BDC04610B50129D0F8A83003D1FFF7F2 -+:1062200005FF00B212E0B3F86C25B3F86E35FF2B12 -+:1062300086BFA3F5007399B21946FF2A86BFA2F55F -+:1062400000739BB21346C3EB010318B210BDC046E6 -+:1062500070B5D0F8A830D3F8D443D3F8D053D3F8DE -+:10626000CC63FFF7D7FF621E0123934000B25B1996 -+:1062700006FB1030204140B270BDC0462DE9F04110 -+:10628000B0F8DA20074602F47043B3F5005FD0F8A7 -+:10629000A85004D1B5F85463B5F8844513E0D3B2DF -+:1062A000942B03D9B5F88645022308E0632B03D964 -+:1062B000B5F88845012302E0B5F88A45002305EBCF -+:1062C0004303B3F85663FF2E1ED001213846FFF773 -+:1062D000BFFF40B2193804FB00F000B20028CCBF69 -+:1062E00000F5FA73A0F5FA734FF47A7293FBF2F3A8 -+:1062F00098B28419A4B2384640F23441FF222346B2 -+:10630000FCF74AFAA5F86643BDE8F08170B505468A -+:10631000D0F8A8600C4689B340F2DA6142F2080274 -+:10632000FCF72AFA284640F2A6510522FCF70EFA9D -+:10633000284640F2A251C322FCF708FA284640F250 -+:10634000A5510722FCF702FA284640F283514FF488 -+:106350004872FCF7FBF9284640F284510022FCF712 -+:10636000F5F9284640F285514FF40072FCF7EEF93A -+:10637000284640F286510022FCF7E8F928462721FA -+:10638000FFF7C4FD1CB140F001039CB203E04FF6DF -+:10639000FE7400EA040496F894332846F31893F840 -+:1063A0009523052302FB03F22621042A98BF1A46EF -+:1063B000FFF79AFD04F110022846272192B2FFF759 -+:1063C00093FD70BD70B5D0F8A850044695F84233DF -+:1063D0005BB10021FFF79AFF204619210022FFF749 -+:1063E000A5FD10B9012385F8453370BD70B5D0F80F -+:1063F000A840054694F8423393B990F8E93013F079 -+:10640000010F1CBF23F0010380F8E93090F8E93058 -+:1064100013F0020F2DD023F0020380F8E93028E0BA -+:1064200094F847330BB1012303E0D1F1010338BFE6 -+:10643000002384F84733E1B100230126C4F86C330C -+:1064400084F8453384F846632846FFF7BBFF94F889 -+:106450004333003B18BF012384F8443313B128466B -+:10646000FFF722FC2846FEF79FFB28463146FFF740 -+:106470004DFF70BD70B5D0F8A83000260C4683F8EB -+:10648000466331460546FFF741FF14B12846FFF742 -+:106490000BFC03222846134640F67A01FCF77CF9F0 -+:1064A000284640F2DA6142F208023346FCF774F9FA -+:1064B00070BDC04670B50546D0F8A84016467AB102 -+:1064C00094F8433394F842438C2144EA4304C3696B -+:1064D000146018693AF00ED944EA004434600FE0C1 -+:1064E000CB080DD101F0010384F84233C1F340031E -+:1064F00084F8433394F8423313B90121FFF7BAFF0C -+:1065000070BDC04610B500210446FFF7B3FF20461A -+:10651000FEF74AFB10BDC04610B50122044640F606 -+:106520000501FCF729F920460722052340F22F41F7 -+:10653000FCF732F920463021F8234FF4FF62FCF7D4 -+:106540002BF90623204630210722FCF725F92046A7 -+:1065500040F2144141F61062FCF7F8F8204640F290 -+:1065600015414FF4C862FCF7F1F8204640F2DF41D4 -+:106570004FF47F424FF47743FCF70EF92046FFF7C4 -+:10658000E9FB204602492D22FCF71AF910BDC0464E -+:10659000680E0200002914BF0223002310B5002A50 -+:1065A00018BF43F001030446032240F24D41FCF7BB -+:1065B000F3F8204640F24C410322FCF7DDF810BD11 -+:1065C00010B5044611B91049132219E012220F49DF -+:1065D000FCF7F6F8012100222046FFF7DBFF2046FA -+:1065E0000B490622FCF7ECF8B4F8DA3003F47043F8 -+:1065F000B3F5005F07BF20460649204606491E2224 -+:10660000FCF7DEF810BDC04692080200B808020090 -+:10661000DC080200660A0200E80802002DE9F041E9 -+:1066200004460D46164640F2DA6148F280021F46E3 -+:106630009DF81880FCF7A0F82046FEF7B7F9B8B12E -+:1066400040F652112046FCF775F8FF22C3B240F61F -+:1066500048112046FCF7A0F840F653112046FCF7FD -+:1066600069F840F64911C3B2FF222046FCF794F8BE -+:10667000D4F8A83093F8463573B140F2EB41204688 -+:10668000FCF758F8C0F3402340F2EB4120464FF4AA -+:1066900080629B02FCF780F86B1EFF22204640F2CE -+:1066A00042619BB24FF6FF75FCF776F8AE4201D01F -+:1066B000731E9EB220464FF4C8612A463346FCF74B -+:1066C0006BF8204640F241612A463B46FCF764F8ED -+:1066D000B8F1000F05D0204608490422FCF770F8F5 -+:1066E00009E0204640F23F610122FCF72FF82046E6 -+:1066F0000121FFF765FFBDE8F081C046DE0B020017 -+:106700002DE9F0410C4640F23B410546FCF712F8FA -+:1067100040F23C4107462846FCF70CF8064674B1A7 -+:106720000E2228460F49FCF74BF828460121FFF7B7 -+:1067300047FF28460C490722FCF742F810E028469C -+:106740000A490422FCF73CF8284640F23B413A460D -+:10675000FBF7FCFF284640F23C413246FBF7F6FFD0 -+:10676000BDE8F08186090200980B0200500D02007E -+:106770002DE9F04F0546C5B001910092FDF79AFC56 -+:10678000EB694FF0805118690A4639F093DF052014 -+:10679000EFF3E2F7002328464FF489614FF480427B -+:1067A000FBF7FAFF284640F255414FF4A842FBF7A9 -+:1067B000CDFF284640F25641FBF7BCFF00F00F002A -+:1067C000052809D14FF4A842284640F25541FBF76D -+:1067D000BDFF4FF4807207E045F20142284640F2C7 -+:1067E0005541FBF7B3FFFE22803A521022EAE272D3 -+:1067F000102AA8BF10225100002301F18006C2EB2D -+:10680000060B1F46994698469A464393429340E0AA -+:1068100040F256412846FBF78DFF40F25741C0F346 -+:106820000B142846FBF786FF5E4544EA003021DC66 -+:10683000BAF17F0F1EDC8104890CB1F5005FC8BF7F -+:10684000A1F5804101F50063B3F5805F23D802AB69 -+:1068500023F8191044AB03EB880252F8083C0AF104 -+:10686000010ACB1842F8083C08EB090383F0400901 -+:1068700088F00108C0F3033303F00C0343EA071365 -+:1068800016F0010F9FB203D007F0FF03402B02D197 -+:10689000013E002EBCDCEB69002218694FF08051EC -+:1068A00039F008DF2846FDF7FFFB429B9B1142931E -+:1068B000439B9B11BAF1800F43931DD0002022E02F -+:1068C00041EA801202AB33F9123001315B1B4029DF -+:1068D00003FB0344F4D1013002280FD1009AA3092D -+:1068E0001460019A1360A3F53A63084A183B934277 -+:1068F0008CBF0020012006E00020044642AB53F884 -+:1069000020500021DCE745B0BDE8F08F48F4FF0FD0 -+:1069100070B504460D46FDF7CDFB20226B012046E5 -+:106920004FF49661FBF738FF0023204640F2B14157 -+:106930004FF40072FBF730FFB4F8DA3003F4704321 -+:10694000B3F5005F02D04FF0000E04E0D5F1010E68 -+:1069500038BF4FF0000E002D0CBF2023002343EA68 -+:106960008E13204660224FF48261FBF715FF20460C -+:106970004FF482618022EB01FBF70EFF2046FDF70A -+:1069800093FB70BD2DE9F047044688461746D0F8C2 -+:10699000A890FCF78DFB20460121FFF7B9FF0025E9 -+:1069A0002E460CE0012100222046FDF78BFA3846E6 -+:1069B000EFF3D2F62046FEF78BFA40B285B2F3B27F -+:1069C00001364345EED320460021FFF7A1FF89F8A9 -+:1069D000C052BDE8F087C04670B505460846FEF7D0 -+:1069E000A7F8EB69A02144B2186939F083DE9D3C19 -+:1069F000A4B26FF0610324B29C42B8BF1C46C1B27E -+:106A000062B22846FCF770FD70BDC04673B5D0F881 -+:106A1000A840064694F84233002B00F0DC8094F83E -+:106A20004633002B00F0D780D0F8B030D3F82031B7 -+:106A300013F0010F00F0CF8000230093019394F82E -+:106A40004553002D40F0AA8029462A46FFF76EFAEA -+:106A5000002800F0A380304601A96A46FFF788FEAF -+:106A6000002800F09B80009BC4F86C3394F84633F8 -+:106A7000012B40F0938094F891030199AC46AE4607 -+:106A80001FE045B204EB8502D2F87033994201D37E -+:106A9000002203E0C2F870131946012204EB8503BB -+:106AA000D3F870339C440EF101035FFA83FE431C5C -+:106AB000D8B243B2072BC8BF002012B1019101998F -+:106AC00019E094F990334FFA8EF29A42D9DBF5E748 -+:106AD00043B204EB8303D3F87023C3F87013431C51 -+:106AE000D8B243B2072BC8BF00200EF101038C447B -+:106AF0005FFA83FE11464FFA8EF3072BE8DD019112 -+:106B000094F8902353B2072B05DC002384F89233CA -+:106B1000531C84F8903394F99033082B3ED194F8A9 -+:106B20009433E31893F8972393F8995394F8923396 -+:106B3000FC2B02D8013384F8923394F892339342B9 -+:106B40002CD194F89133013384F891335BB2072B45 -+:106B500002DD002384F8913394F890333046023BF1 -+:106B600084F890336146FEF7DFFF18B93046FEF730 -+:106B70001BF810E094F89333FC2B02D8013384F80F -+:106B8000933394F89333AB4205D194F8943313B90B -+:106B9000013384F89433002384F8923394F8461335 -+:106BA0000023012984F8453303D13046FFF7AEFBBB -+:106BB00003E030461946FFF75DFC3046D4F86C130D -+:106BC000FFF70AFF002384F8473394F89C3313B986 -+:106BD000013384F89C337CBD2DE9F04F0746D0F893 -+:106BE000A800E1B00B9041F22403FB5C0C46002BA3 -+:106BF00000F09C82FB696A21186939F07BDD400056 -+:106C00001FFA80FBBBF1000F00F090823846FEF7C0 -+:106C100085F9FB69024610B91869594684E218697A -+:106C2000594639F067DD012800F080820BF1060338 -+:106C30009BB20C930BF13A039BB20D930BF16E03D5 -+:106C40009BB20E930BF1AA039BB20F93002C00F0A2 -+:106C50005A82384640F2F941FBF76CFD10F0080FFC -+:106C600040F064824CAD38ACAB1C0193A31C039381 -+:106C70003846002340F2764140F2FF12009502941C -+:106C8000FBF7D4FD2B1D0093AB1D0193231D029335 -+:106C9000A31D03933846002340F2774140F2FF12D0 -+:106CA000FBF7C4FD05F10803009305F10A03019306 -+:106CB00004F10803029304F10A030393384640F2F7 -+:106CC000AA4148F2FF1248F27F03FBF7AFFD05F13E -+:106CD0000C03009305F10E03019304F10C0316223B -+:106CE000029304F10E0303933846134640F23B41EE -+:106CF000FBF79CFD05F11003009305F112030193CE -+:106D000004F11003029304F1120346220393384660 -+:106D1000002340F23C41FBF789FDB7F8DA3005F17A -+:106D2000140E03F47043B3F5005F05F11C030A93DE -+:106D300005F11E03099304F11C03089304F11E03DB -+:106D4000079305F12003069304F1200305F11602D1 -+:106D500004F1140104F1160005F1180605F11A08F2 -+:106D600004F1180904F11A0A05F12205059304F14A -+:106D7000220437D1019241F22B0213460291039073 -+:106D800040F24C413846CDF800E0FBF74FFD384665 -+:106D900040F24D4144F22B0244F20A030096CDF832 -+:106DA0000480CDF80890CDF80CA0FBF73FFD089AC1 -+:106DB0000A980999079B0292072200900191039378 -+:106DC0003846134640F2F941FBF730FD0698059925 -+:106DD000072200900291384640F2FA41134601958D -+:106DE000039436E0019241F22B0213460291039084 -+:106DF00040F24C413846CDF800E0FBF717FD38462D -+:106E000040F24D4144F22B0244F222030096CDF8A9 -+:106E10000480CDF80890CDF80CA0FBF707FD0A9A86 -+:106E2000099B089807990092072201930290134644 -+:106E30000391384640F2F941FBF7F8FC069A059BAE -+:106E40000092029301950394384640F2FA410722DA -+:106E5000002324ACFBF7EAFCA31C019310AB012236 -+:106E600002930DF142030721039338461346009421 -+:106E7000FBF748FC231D0093A31D019311AB1022C7 -+:106E800002930DF14603FF21039338461346FBF7A7 -+:106E900039FC04F10803009304F10A03019312ABD7 -+:106EA000042202930DF14A034CAE03933846134675 -+:106EB00040F21F11FBF726FC06F1240338AD0093C6 -+:106EC00006F12603019305F1240340F644020293E0 -+:106ED00005F1260303933846134640F63811FBF7B5 -+:106EE000A5FC06F12803009306F12A03019305F19E -+:106EF0002803029305F12A030393384640F639111B -+:106F000040F6440240F60403FBF790FC04F10C0346 -+:106F1000009304F10E03019313AB012202930DF1D0 -+:106F20004E033A21039338461346FBF7EBFB04F17B -+:106F30001003009304F11203019314AB082202938F -+:106F40000DF152030393384613464FF48D71FBF74E -+:106F5000D9FB04F11403009304F11603019315AB5C -+:106F6000082202930DF15603052103933846134678 -+:106F7000FBF7C8FB04F11803009304F11A03019313 -+:106F800016AB042202930DF15A033A2103933846BB -+:106F90001346FBF7B7FB04F11C03009304F11E0337 -+:106FA000019317AB012202930DF15E030393384660 -+:106FB00013464FF48D71FBF7A5FB06F12C030093EC -+:106FC00006F12E03019305F12C03029305F12E0324 -+:106FD0000393384640F2D74147F2CB0242F24B03CB -+:106FE000FBF724FC04F12003009318AB202202934A -+:106FF0000DF1620382212234039338461346019433 -+:10700000FBF780FB0B98037B827AC17A1B0342F467 -+:10701000007242EA011243F0030343EA820306F1DD -+:107020003002009205F13002323602923235384693 -+:107030004FF49B6147F6FF729BB201960395FBF7F5 -+:10704000F5FBDDF83090DDF834800026FB694CACB0 -+:10705000325B1869494639F06BDBFB6938AD725B0E -+:107060001869414639F064DBFB69A419186909F114 -+:107070000201628839F05CDBFB69AD1908F102019D -+:1070800018696A88043639F053DB342E09F1040993 -+:1070900008F10408DAD1DDF83890DDF83C800026EC -+:1070A000FB6924AC325B1869494639F041DBFB6966 -+:1070B00010AD725B1869414639F03ADBFB69A419DF -+:1070C000186909F10201628839F032DBFB69AD19F8 -+:1070D00008F1020118696A88043639F029DB242E88 -+:1070E00009F1040908F10408DAD1FB690BF1020186 -+:1070F00018690D2239F01CDBFB690BF104011869DA -+:10710000092239F015DBFB690B991A6A18690B9B88 -+:10711000C1F83824B3F83C240BF1E60139F008DB60 -+:10712000FB6959461869012239F002DB61B0BDE8FC -+:10713000F08FC0462DE9F04F8DB007460F220E4666 -+:107140000DF12100B249EAF317F7D7F8A880002221 -+:10715000B04D14016359B34203D001320E2AF7D166 -+:1071600075E3384691210022FBF772FA3846382140 -+:107170000722FBF76DFA0A2238468821FBF768FAE6 -+:10718000D7F8A83093F882251AB138468821FBF742 -+:107190005FFA64192A213846227AFBF759FA30211E -+:1071A00003223846637AFBF799FA91210322384685 -+:1071B000A37AFBF793FAE37A38210F223846FBF7DC -+:1071C0008DFA912100223846FBF742FA3821072236 -+:1071D0003846FBF73DFA237B30210C229B003846D2 -+:1071E000FBF77CFA5E210F223846637BFBF776FAC9 -+:1071F000A37B5E211B01F0223846FBF76FFA6C215E -+:107200003846E27BFBF724FA384638210822FBF7A0 -+:107210001FFA384691210322FBF71AFA0CA98B19A1 -+:1072200013F8102C38465E21FBF712FA012238467B -+:107230007E21FBF70DFA98F8EE231AB13846382173 -+:10724000FBF706FA0722134638462A21FBF746FACF -+:1072500038462C210022FBF7FBF938462A210C2264 -+:10726000FBF7F6F9012238462C21FBF7F1F9D7F8A4 -+:10727000A82092F852352BB338465E2192F8532558 -+:10728000FBF7E6F9D7F8A830384693F854252A21B9 -+:10729000FBF7DEF9D7F8A830384693F855252B21AF -+:1072A000FBF7D6F9D7F8A830384693F856252C21A5 -+:1072B000FBF7CEF9D7F8A83038462D2193F857259B -+:1072C000FBF7C6F9B7F8DA3003F47043B3F5805F23 -+:1072D00004D13846BF21EE22FBF7BAF90222134649 -+:1072E000384640F21F11FBF7F9F90422F721134643 -+:1072F0003846FBF7F3F9F121032200233846FBF768 -+:10730000EDF9F221F82290233846FBF7E7F9A223A2 -+:10731000F321FF223846FBF7E1F9B7F8DA3003F43E -+:107320007043B3F5005F04D1D7F8A83093F818354F -+:1073300006E0B3F5805F06D1D7F8A83093F8193589 -+:10734000012B00F07B82042238469D210023FBF7AD -+:10735000C5F90022079244213846FBF761F940F253 -+:107360002B1101903846FBF75BF94421029007226C -+:107370003846FBF7A5F9384640F22B110E22FBF7F1 -+:107380009FF941F2080357F803A0079B0BB9554634 -+:1073900001E04FEA4A05204B9A4502D84FF0010917 -+:1073A00006E01E4B9A4594BF4FF002094FF00409C6 -+:1073B000B7F8DA3003F47043B3F5005F03D000216F -+:1073C0000591069106E06268032302FB03F2059231 -+:1073D0006A000692124C102221465046FDF7BAF977 -+:1073E000102221462846FDF7B5F91022049009FB2A -+:1073F00004F15046FDF7AEF9B7F8DA30039003F424 -+:107400007043B3F5005F0DD04FF0000B10E0C046A5 -+:10741000C80602001424020080BA8C01007519030A -+:1074200040420F00059802211022FDF793F9834690 -+:107430004F2102223846FBF70BF9CD4B4FEACA0524 -+:1074400009FB03F3B5FBF3F301335B08013B5FFA80 -+:1074500083F85221072238464FEA9803FBF73EF99A -+:1074600008F101065321602238464FEA4813FBF722 -+:1074700035F909FB06F3BF4CB5FBF3F5BE4B2C19F0 -+:10748000B4FBF3F4013CE4B2512122463846FBF749 -+:10749000DFF8039B10221D0158462946FDF75AF9D3 -+:1074A000013406FB04F600FB06F000280BDB58460F -+:1074B00029461022FDF74EF900FB06F0C0130130FB -+:1074C0004010441E0EE0584629461022FDF742F9AE -+:1074D0006FEA080303FB04F300FB03F0C013013061 -+:1074E0006FEA6004C4F3072353210F223846FBF7E9 -+:1074F000F5F85421E2B23846FBF7AAF806999F4BFB -+:107500000A22B1FBF3F30599384601FB02F2B2FB04 -+:10751000F3F803FB1822590802F0010401EB0454AC -+:107520005208B4FBF3F49B0803EB0253B3FBF1F3F3 -+:10753000E41845211F22C8F30713FBF7CFF84FEAE1 -+:107540000813462138464FF4F87203F0F003FBF7B6 -+:10755000C5F8C4F3074346210F223846FBF7BEF8AF -+:107560004721C4F307223846FBF772F84821E2B2FC -+:107570003846FBF76DF8079A41F29416002A08BFC7 -+:107580004FF4FA56A6F5D8760CBF4FF482794FF433 -+:10759000E1794FF4F572033E96FBF2F606FB02F535 -+:1075A00005F52A754FF425636D02B5FBF3F540F23E -+:1075B0007C6405FB04F4A4F55834A4F5C064B4FB62 -+:1075C000F2F4640AC4F3820242EAC6023846422157 -+:1075D00092B2A4B2FBF73CF804F0030204F01F04DB -+:1075E00044EA421238464321FBF732F84FEA492475 -+:1075F0004FF48773B4FBF3F404FB05F4604B640AA7 -+:10760000604AB3FBF4F39A184FF41243B2FBF3F25F -+:107610005D4B02F00F02B3FBF4F3A3F54C23A3F58B -+:1076200000631B0C42EA03123846402192B2FBF77A -+:107630000FF84FF02552554BB2FBF4F2B3FBF4F3C5 -+:10764000A2F546324FF4B841A2F50072A3F56E33AD -+:10765000B2FBF1F2A3F50073B3FBF1F302F00F02FA -+:1076600042EA03123846412192B20BF17444FAF710 -+:10767000EFFF04F590044FF4966394FBF3F4292391 -+:1076800004FB03F44FF45C7308FB03F840F22B5344 -+:1076900006FB03F606F5E46109FB08F00C31102245 -+:1076A000FDF758F804F5D81400EB640090FBF4F0F3 -+:1076B000C0B23C2894BF0025012515B14308043B06 -+:1076C00000E0031FDCB23C213F2223463846FBF793 -+:1076D00005F8AB013C2140223846FAF7FFFFB7F826 -+:1076E000DA3004F1040603F47043B3F5005F05F1EA -+:1076F000010404D1D7F8A83093F8273506E0B3F594 -+:10770000805F19D1D7F8A83093F82835012B13D111 -+:10771000049B40F245105946102203FB00F0FDF790 -+:1077200019F804FB06F39E2100FB03F4C02238463F -+:107730004023FAF7D3FF0BE00499962001FB00F0F9 -+:1077400010225946FDF706F804FB06F300FB03F48C -+:10775000B4F5160FD4BF002501256B1C032203FBD3 -+:1077600002F394FBF3F0B0F5003F11D5002315E0D0 -+:10777000404B4C003F420F0040420F00A0860100EA -+:10778000000068600021F6FF000084A30000302A9A -+:10779000A0F5C033DB130133C3F347033D213F2280 -+:1077A0003846FAF79BFFAB013D2140223846FAF7F5 -+:1077B00095FF284B9A4504D9202238465721134675 -+:1077C00003E03846572120220023FAF787FF224B97 -+:1077D0009A4504D9102238465721134603E038460B -+:1077E000572110220023FAF779FF049AB2F5341FCB -+:1077F00005DD38464A210222FAF762FF04E03846E6 -+:107800004A21FD22FAF74EFF0C2244211346384646 -+:10781000FAF764FF0120EEF39FF73846FEF76AFAA5 -+:10782000019B38464421DAB2FAF712FF029B384630 -+:1078300040F22B11DAB2FAF70BFF08E004229D2187 -+:1078400038461346FAF74AFF0121079183E50DB048 -+:10785000BDE8F08F80BA8C010075190341F208036E -+:107860002DE9F047C4588A4B4FF48475B4FBF3F408 -+:1078700004FB05F41A235721B4FBF3F40646FAF788 -+:10788000CFFE172181463046FAF7CAFE182130464E -+:10789000FAF7C6FE40F20511FB2207463046FAF71A -+:1078A00001FF304604214022FAF70AFF30464FF428 -+:1078B00090711022FAF704FF304657210222FAF79E -+:1078C000FFFE304640F205110422FAF7F9FE304679 -+:1078D0004FF483712A22FAF7BBFEA4B2304640F27D -+:1078E00007116E22FAF7B4FEE2B230462946FAF7E3 -+:1078F000AFFEC4F30422304640F20911FAF7A8FEA5 -+:10790000304640F20511FD22FAF7CCFE30464FF426 -+:1079100083710122FAF7D4FE3220EEF31DF75D4C9D -+:1079200003E00A20EEF318F70A3C30464FF4857165 -+:10793000FAF776FE10F0010F01D1092CF1D1304693 -+:107940004FF48571FAF76CFE10F0010F08D1FAB20E -+:1079500030461821FAF7B4FE4FF00B0847460CE00A -+:10796000304640F20F11FAF75BFE00F01F071D2FA3 -+:107970008CBF4FF00B0807F1020819213046FAF7C7 -+:107980004FFE4FF48371FE2205463046FAF78AFE19 -+:10799000304640F20511FB22FAF784FE304640F2F1 -+:1079A00005110422FAF78CFE304640F2051102223E -+:1079B000FAF786FE30464FF483710122FAF780FE13 -+:1079C0003220EEF3C9F6334C03E00A20EEF3C4F69E -+:1079D0000A3C30464FF48571FAF722FE10F0010F91 -+:1079E00001D1092CF1D130464FF48571FAF718FE18 -+:1079F00010F0010F06D1EAB230461921FAF728FE3D -+:107A0000092506E030464FF48871FAF709FE00F0C8 -+:107A10001F053046FE224FF483716C01FAF742FED7 -+:107A200044EA85243046FB2240F20511FAF73AFE7B -+:107A30002C43304657215FFA89F2FAF709FE3046A7 -+:107A4000224640F63311FAF781FE2246BC02304648 -+:107A500044EA471440F63411FAF778FE304645EA16 -+:107A6000040240F63511FAF771FE304644EA070287 -+:107A700040F63611FAF76AFE48EA4812D205304657 -+:107A800040F63711D20DFAF761FEBDE8F087C04627 -+:107A900040420F008996980070B55B210446FD2294 -+:107AA000FAF700FE204604214022FAF709FE20469C -+:107AB0004FF490711022FAF703FE204678218022BD -+:107AC000FAF7FEFD204640F229110222FAF7F8FDEE -+:107AD000204657210122FAF7F3FD20465B210222BE -+:107AE000FAF7EEFD41F28830EEF336F6154D03E07D -+:107AF0000A20EEF331F60A3D5C212046FAF790FDAC -+:107B000010F0200F01D1092DF2D15C212046FAF7A7 -+:107B100087FD10F0200F03D020465C21FAF780FD8E -+:107B200020465B21FD22FAF7BDFD20465721FE22AB -+:107B3000FAF7B8FD204640F22911FD22FAF7B2FD0E -+:107B400070BDC0468996980070B504460E46002563 -+:107B50006E4B2046E95AFAF763FDA8530235302DE3 -+:107B6000F6D1182220466A49FAF72AFE3A21FB226A -+:107B70002046FAF797FD012220464FF48D71FAF75F -+:107B80009FFD362101222046FAF79AFD10224FF47C -+:107B90008D712046FAF794FD1420EEF3DDF53A21BD -+:107BA00001222046FAF78CFD1420EEF3D5F5B4F847 -+:107BB000DA3003F47043B3F5005F03D120463A2175 -+:107BC000012208E020463A2101220023FAF786FD2F -+:107BD0002046CA2104221346FAF780FD08222046D7 -+:107BE0004FF48D71FAF76CFD25210E222046FAF72D -+:107BF0002FFD252101222046FAF762FDB4F8DA3084 -+:107C000003F47043B3F5805F04D1204628211E227F -+:107C1000082303E0204628211E220C23FAF75EFDEC -+:107C20001420EEF399F5052108222046FAF710FDFD -+:107C300080224FF489712046FAF742FD1420EEF3BA -+:107C40008BF5FF2110222046FAF73AFD442240F23C -+:107C50001F112046FAF734FD1420EEF37DF50B21B9 -+:107C600007222046FAF72CFD102240F2131120467D -+:107C7000FAF726FD1420EEF36FF5072101222046C6 -+:107C8000FAF7E6FC1420EEF367F502230322204600 -+:107C9000FC21FAF723FDFD212046A622FAF7D8FCA5 -+:107CA000442240F21F112046FAF70AFD1420EEF399 -+:107CB00053F5FF2110222046FAF702FD1420EEF3BF -+:107CC0004BF5B4F8DA3003F47043B3F5805F03D1B9 -+:107CD00010492046082202E00F4920460622FAF702 -+:107CE0006FFD20465921CC22FAF7B2FC20465C21D8 -+:107CF0002E22FAF7ADFC20467821D722FAF7A8FC0D -+:107D0000204692211522FAF7A3FC70BDD20402008E -+:107D1000360A0200040B0200140B02002DE9F04F9A -+:107D200004468BB0894609B98B4608E040F2D7413A -+:107D3000FAF700FD01A983462046FDF799FD2022B0 -+:107D400013464FF49A612046FAF726FD6420EEF3BD -+:107D500003F540F276412046FAF7ECFC40F2A641EA -+:107D600080462046FAF7E6FC09A9824608AA204682 -+:107D700007ABFBF7B5F9099F089E079DB9F1000F06 -+:107D800009D0204601A9FDF75BFD204640F2D7410E -+:107D90005A46FAF7DBFC4FEAC850C00D4FEACA5307 -+:107DA00080F48070DB0D00F5FE70033083F4807387 -+:107DB000C01A8010394632462B46FCF7EBFC4000D7 -+:107DC0000BB0BDE8F08FC046F0B5D0F8A85085B034 -+:107DD00095F858340646002B7BD00023019302937C -+:107DE0000393FDF775F8C7B20FB17F2F71D101ABC7 -+:107DF00002AA304603A9FBF773F940F23E61304610 -+:107E0000FAF798FC40F2A641C4053046FAF792FC16 -+:107E1000C005C00DE40DFF288ABFA0F5807300F5F2 -+:107E200080729AB2FF2C84BFA4F5807398B2C2F519 -+:107E3000FE7398BF04F5807003331B18C3F38F00E3 -+:107E4000C7B995F856340133DBB2042B85F85634A4 -+:107E50003FD985F85674029A019B0399FCF79AFC66 -+:107E6000D5F848244310043B9342B8BF1346C5F8E5 -+:107E700044341AE07F2F2CD195F857340133DBB20C -+:107E8000042B85F8573424D9002385F85734029AF7 -+:107E9000019B0399FCF77EFCD5F84424431004337E -+:107EA0009342A8BF1346C5F84834D6F8A8109BB231 -+:107EB000D1F8442430469342A8BF1346D1F8482451 -+:107EC00040F2A7419342B8BF13469BB2FF22FAF794 -+:107ED00063FC05B0F0BDC0462DE9F04F474B87B0BD -+:107EE00003AC80460D4693E8070084E8070040F2A3 -+:107EF00045614046D8F8A8B0FAF71CFC40F246614C -+:107F000087054046FAF716FC3D498605062240469D -+:107F1000FAF756FC00210A464046FDF741F84FF4B7 -+:107F2000FA730193404629462022A3F5FA73009480 -+:107F3000FDF736FFBF0DB60D8246002849D0049DDF -+:107F4000DDF81490039C09EB0503012B02D84FF0D8 -+:107F5000000A3EE02046FBF74BF806464846FBF792 -+:107F600047F8A6F114031AB2002A06DB35FA02F12B -+:107F70003FD0013235FA02F206E0534215FA03F11E -+:107F800037D0D24315FA02F233B2C3F11E0314FA0A -+:107F900003F3C3EB0204A0F10B031BB2002B0A4650 -+:107FA00002DB35FA03F102E05B4215FA03F120D05F -+:107FB00003B2C3F11F0309FA03F394FBF2F493FB3A -+:107FC000F1F004FB1400FBF71FF8A7058605BF0DB1 -+:107FD000B60D404639463246FCF7E2FF40460949B5 -+:107FE0000622FAF7EDFB5046ABF8B872ABF8BA626E -+:107FF00000E0002007B0BDE8F08FC046BC060200DC -+:10800000C20E0200DC0E020070B504460D46C9B176 -+:1080100004221249FAF7D4FBD4F8A83093F8E933D4 -+:10802000A02B05D1204640F64A1140F24F1203E042 -+:10803000204640F64A11A722FAF788FB0849204655 -+:108040000E2201E007490A22FAF7BAFBE369291E6A -+:1080500018BF0121186938F0A7DB70BDBE0D020002 -+:10806000A20D0200D80D020070B50C46062226496A -+:10807000E4B20546D0F8A860FAF7A2FB0C2C01D8B0 -+:10808000002405E041F25013EB561C1E18BF0124DA -+:1080900096F81A35002B31D0284640F64211FAF7EF -+:1080A00049FB14B10F280BD100E0A8B9D5F8F8307E -+:1080B00013F0060F22D196F82C30A3421ED05CB1EB -+:1080C000EB690122D8689968EDF398F728460121F9 -+:1080D000FFF79AFF01230AE0EB690022D86899684C -+:1080E000EDF38CF728460021FFF78EFF002386F87A -+:1080F0002C30284605490C22FAF762FB2846044931 -+:108100000422FAF75DFB70BDB6070200700702009B -+:108110008807020070B50D46B0F8DA101646D0F8A0 -+:10812000A840FAF731FD28B994F84C342B7094F834 -+:108130004D3401E000232B70337070BD2DE9F04702 -+:108140004FF0000886B0054602ABCDF81080CDF8A0 -+:108150000C80CDF8088003AA8A4604A9D0F8A8901C -+:10816000FAF7BEFF28460DF117010DF11602FFF7D1 -+:10817000D1FF9DF8173004990193039A029B0124C3 -+:1081800028460094FCF71AFB9DF816300746019329 -+:108190002846029B0499039ACDF80080FCF70EFB59 -+:1081A00099F8E83306460BB39DF81700B5F902219C -+:1081B000B5F90431B5F906110190284603920293EE -+:1081C00004910094FCF7FAFA9DF8163004460193E6 -+:1081D00028460499039A029BCDF80080FCF7EEFA3A -+:1081E000A742B8BF27468642A8BF0646BAF1010F8C -+:1081F00002D0BAF1030F02D17B10C9F84434AAF1BE -+:108200000203DBB2012B02D87310C9F8483406B060 -+:10821000BDE8F08707B540F25643009340F255425F -+:108220000133FAF7F1FB0EBD2DE9F04340F2DF41D7 -+:1082300089B0D0F8A8400546FAF77CFAC3B27F2B84 -+:10824000A4F84C30C0F30720C4BFA3F58073A4F892 -+:108250004C307F28C8BFA0F58073A4F84E0001AF52 -+:10826000C8BFA4F84E301123039320262A330DF102 -+:1082700018094FF00208284639460493CDF80490B7 -+:10828000CDF808800596FFF7C5FF069B3F2B01D967 -+:10829000803B0693069B2365079B3F2B01D9803BC0 -+:1082A0000793079B40F2344163652846FAF742FA88 -+:1082B000C0B27F28C4BFA0F5807398B284F858007C -+:1082C00040F224412846FAF735FAC0F30720A4F813 -+:1082D0005A0040F225412846FAF72CFA0D23C0B285 -+:1082E000A4F85C00039328460F3339460493CDF875 -+:1082F0000490CDF808800596FFF78CFF069B236459 -+:10830000079B636409B0BDE8F083C0462DE9F041E6 -+:10831000B2F1FF3F8AB0064688461746D0F8A8500B -+:1083200002D1FCF7E1FB47B295F966355FFA88F4B4 -+:10833000013394FBF3F407230393193305930123CB -+:10834000E4B2029301AD07AB0193304604F5A0738C -+:1083500029460493FFF75EFF079BC034C3F307531E -+:108360000793304606AB294601930494FFF752FF6A -+:10837000002107980DF126020DF12203F0F31AF007 -+:108380000021402008AB09AAF0F314F0BDF9223017 -+:10839000BDF920108B4209DABDF92400C91AF0F3A7 -+:1083A000BBF0BDF82240ADF8240009E0BDF926007D -+:1083B000C1EB0301F0F3B0F0BDF82040ADF82600AA -+:1083C000BDF92600BDF92410F0F3B0F023B2032B61 -+:1083D00080B201DD231F01E0C4F104039AB212B29E -+:1083E00008FA02F103B2052003FB0010911E0123DD -+:1083F0008B40013AC018104107FB00F0C0F3CF00DA -+:108400000AB0BDE8F081C04670B5182386B0D0F838 -+:10841000A840039300238022049340F27666203321 -+:1084200005460593314613460292FAF7B5F904F171 -+:108430009C03284601A90193FFF7ECFE40F271610D -+:108440002846FAF777F940F27361A4F89C022846AF -+:10845000FAF770F940F27461A4F89E022846FAF720 -+:1084600069F940F27561A4F8A2022846FAF762F9A8 -+:1084700040F27961A4F8A0022846FAF75BF9314688 -+:10848000A4F8A4022846FAF755F940F2DA61A4F8F4 -+:10849000A6022846FAF74EF940F22551A4F8A802A0 -+:1084A0002846FAF747F994F86735A4F8AA0284F841 -+:1084B000AC324FF48F612846FAF73CF94FF49A61D9 -+:1084C000A4F8AE022846FAF735F940F22451A4F890 -+:1084D000B0022846FAF72EF9B4F86835C0F3C03078 -+:1084E000A4F8B43294F80734A4F8B20284F8B6328F -+:1084F00094F8083484F8B73206B070BD7FB5002315 -+:108500000293103304930DF116030093012301939A -+:10851000694654330393FFF77DFEBDF8160007B09C -+:1085200000BDC0462DE9F84FD0F8A860074696F880 -+:1085300046355BB9FFF7E2FF40F3072340B21FFA6D -+:1085400083F81FFA80F9C246CB4607E0B6F84A85A1 -+:10855000B6F84C95B6F84EA5B6F850B5B7F8DA307F -+:10856000384603F47043B3F5005F0CBFB6F866609D -+:10857000B6F868604FF0FF320121FCF72BFA36B2F3 -+:108580000121324684B23846FCF724FA0021241A2D -+:108590004FF0FF323846FCF71DFA0121324685B212 -+:1085A0003846FCF717FAA4B2C4EB0806B6B2C4EB1F -+:1085B00009042D1AFF2238463346A4B240F6521160 -+:1085C000FAF7EAF83846FF22234640F65311FAF745 -+:1085D000E3F83846FF22334640F65611FAF7DCF846 -+:1085E000ADB23846FF22234640F65711FAF7D4F8C9 -+:1085F000C5EB0A033846FF2240F648119BB2C5EB93 -+:108600000B05FAF7C9F8384640F64911FF22ABB21C -+:10861000FAF7C2F8BDE8F88F2DE9F04F93B00DF1ED -+:1086200026080C46D0F8A8503B49064693464046DB -+:10863000222201AFE9F3A0F4384638492222E9F3B7 -+:108640009BF4BCB10022304640F60F11FAF77EF8D9 -+:1086500095F8E933324AA02B324B14BF052403248A -+:1086600014BF1046184614BF4FF0100A4FF0110AFD -+:10867000B94616E0012230464FF41161FAF766F868 -+:1086800095F8E933284AA02B284B14BF0E240A245E -+:1086900014BF1046184614BF4FF0100A4FF0110ACD -+:1086A000C1460022114604E00B5A013224319B4599 -+:1086B00006D0A2421FFA82F8F6D14FF6FF7416E0F8 -+:1086C0000FFA88F2242302FB03070024254607E063 -+:1086D00035F80910304637F81420FAF737F8023524 -+:1086E00001340AF101039C42F2D11FFA88F43046AA -+:1086F000FCF74AF910B13046FFF714FF3046FCF79B -+:1087000065FD20B2B0F1FF3F0CBF4FF0FF300020FD -+:1087100013B0BDE8F08FC046E20A0200680802000C -+:10872000F826020040220200F4240200AC220200DB -+:108730002DE9F0438BB006460F4691460DF1060039 -+:108740001D492222E9F318F4D6F8A83093F8E9334A -+:10875000A02B14BF4FF010084FF0110817B93D4679 -+:108760003C4619E000252C4609E00DF10603E15ACC -+:108770003046F9F7DFFF013524F80900023445459A -+:10878000F3D10BE00DF10603E15A34F8092030462D -+:10879000F9F7DCFF013502344545F3D13046FCF7EB -+:1087A000F3F810B13046FFF7BDFE17B93046FCF7BD -+:1087B0000DFD0BB0BDE8F0830C0C020030B587B0A6 -+:1087C00005AB0093022301930023029350330C4620 -+:1087D00003936946102315460493FFF71BFDBDF86C -+:1087E00014302380BDF816302B8007B030BDC04652 -+:1087F0007FB50DF11603009301230193013B029312 -+:1088000057330393694610230493FFF703FDBDF824 -+:108810001600000A07B000BD07B540F256430093AA -+:1088200040F255420133FAF7B5F80EBDF0B5B0F895 -+:10883000DA30D0F8A85003F47043B3F5005F0CBFF2 -+:1088400095F8403395F8413387B085F8423395F871 -+:108850004233064685F84333B0F8DA3003F4704308 -+:10886000B3F5005F14D195F8492353B2002B02DD14 -+:1088700085F8482309E0C3691B6D13F4805F01D0BC -+:10888000342300E0302385F8483395F85C3313E057 -+:1088900095F84A2353B2002B02DD85F8482309E0FE -+:1088A000C3691B6D13F0805F01D0342300E03023D7 -+:1088B00085F8483395F85D335BB2002B4CDD03221D -+:1088C000022BA8BF022303FB02F340F2DF41304634 -+:1088D000DFB2F9F72FFFC1B27F29C0F30720C4BF71 -+:1088E000A1F5807399B203B27F2BC8BFA0F5807346 -+:1088F0007AB2C8BF98B292B2C2EB0003C2EB0102D7 -+:10890000DBB202F0FF0242EA0322304640F2DF41CE -+:10891000F9F71CFF0DF116030093022301930F33A7 -+:1089200002930F2303933046082369460493FFF70D -+:1089300071FC9DF81630FAB29B1A8DF816309DF82E -+:10894000173030469B1A69468DF81730FFF764FFE1 -+:1089500030466C46FDF7FEF94FF0FF3385F89A3349 -+:1089600095F84D33002285F8472385F89C23BBB149 -+:1089700085F8422385F84323304640F22341FF32F5 -+:10898000B5F85033F9F708FF30464FF4AA61B5F84F -+:108990006023F9F7DBFE304604490422F9F710FFA3 -+:1089A0003046FCF711F907B0F0BDC046EC0D0200EF -+:1089B0002DE9F04FC3690C464FF08051BBB005461E -+:1089C000D0F8A870164618690A4637F073DE0520FD -+:1089D000EDF3C2F628464FF489614FF4804200233C -+:1089E000F9F7DAFE0122284640F20A511346F9F758 -+:1089F000D3FE0DF1E70334930123359310333693FF -+:108A00000F2337932846082334A93893FFF702FC35 -+:108A10000CB1314612E0B5F8DA3003F47043B3F527 -+:108A2000005F40F03E81EB6997F8BF641B6D13F463 -+:108A3000805F0CBF08210621FF2E00D10E469DF855 -+:108A4000E720032306FB13238DF8E6300DF1E60340 -+:108A500034932846102334A93793FFF7DDFE7300C3 -+:108A6000FE229BB2284640F20A51F9F795FE97F88C -+:108A7000C044FF2C00F0EA80002C00F0C980102CCC -+:108A800028BF1024C4F12403D9B272B24BB29A4267 -+:108A900001DDCEB202E0002E08BF012670B2A04276 -+:108AA000019002DC5FFA86F902E0631C5FFA83F949 -+:108AB00004F1010BC9EB0B035FFA83F80D23369326 -+:108AC000133338934FFA89F35B004FFA88F204931B -+:108AD00009AB03EBC203570003937B1CDBB2079384 -+:108AE0006300013305934FEA4B03029206934FF064 -+:108AF000000A0198049AA042CABF73B2CDF8DCB054 -+:108B00003793379B34A953445B003793039B284624 -+:108B100035923493FFF77EFB07990AE03AA800EB01 -+:108B2000810353F8C42C42F0800243F8C42C8B1C00 -+:108B3000D9B2059A9142F1DD002111E03AAB03EB85 -+:108B4000810203EB870353F8C43C3AA842F8C43CC3 -+:108B500000EB870353F8C03C42F8C03C8B1CD9B2F1 -+:108B6000B942EBDB069A09AB349328464FEA4A0335 -+:108B700034A90AF1250A35923793FFF74DFEBAF171 -+:108B80004A0FB6D1019B4FFA88F2A342C4BF73B219 -+:108B900037934FFA89F335930DF1AE0303EB42039C -+:108BA000D8BFCDF8DCB034931023389328460E2379 -+:108BB00034A93693FFF72EFB0CE03AAE06EB4803E0 -+:108BC00033F83A2C42F4006223F83A2C08F10103FE -+:108BD0005FFA83F8A045F0D9002109E0029E3AA887 -+:108BE00000EB430200EB460333F83A3C22F83A3CF0 -+:108BF0000298CBB201318342F0DB0DF1AE03349326 -+:108C00002846002334A9CDF8D4B03793FFF704FEEB -+:108C100001221346284640F20E51F9F7BDFD4FF4EC -+:108C20007E4263021340284640F20E51F9F7B4FD2C -+:108C3000284640F20F517F222346F9F7ADFD284622 -+:108C400040F20F514FF47E52E3011BE0284640F200 -+:108C50000E5101220023F9F79FFD284640F20E51E4 -+:108C60004FF47E420023F9F797FD284640F20F515A -+:108C70007F220023F9F790FD284640F20F514FF470 -+:108C80007E520023F9F788FDEB694FF08051186997 -+:108C9000002237F00FDD2846FDF75CF83BB0BDE859 -+:108CA000F08F2146CAE6C0462DE9F041D0F8A86011 -+:108CB0000746D6F87C45002505E021463846FFF7F3 -+:108CC000ABFD01351434D6F878359D42F5D3BDE8B7 -+:108CD000F081C046F0B5C369D0F8A85087B0074608 -+:108CE00080219868EDF3F4F7044600286DD0B5F8BC -+:108CF0001C34002603F4807C03F4007E30464FF0E1 -+:108D0000000316F0100206F00101035316D0BEF165 -+:108D1000000F03D0D5F81C34C3F3802116F0080FE0 -+:108D200002D095F81A3408E0D5F8183416F0200F60 -+:108D300014BFC3F3072303F0FF030353BCF1000F79 -+:108D400000D062BB16F0040F09D016F0020F025BD0 -+:108D500002D0D5F80C340EE0D5F80C3418E016F03B -+:108D6000200F06F002030CD0025B13B1D5F81034CB -+:108D700001E0D5F8143409B11B0E0EE0C3F307432C -+:108D80000BE0025B13B1D5F8103401E0D5F81434D0 -+:108D900011B1C3F3072300E0DBB2134303530136E1 -+:108DA0000230402EABD10F230393002304933846A7 -+:108DB000103301A9059302960194FFF72DFDFB697D -+:108DC000214698688022EDF393F707B0F0BDC046C6 -+:108DD0002DE9F041002486B00594D0F8A88006461D -+:108DE000FBF782FE072302931933049307460123FE -+:108DF0002546019316E00BB90C4603E011F0010F74 -+:108E00000FD14C0830467AB2FFF780FA06AB43F830 -+:108E1000040D0093304604F5107369460393FFF781 -+:108E2000FBFC0135802DE9B298F96635E3D17BB1C1 -+:108E300001230193402405AB0093304604F51073E1 -+:108E400069460393FFF7E8FC631CDCB2802CF2D187 -+:108E500006B0BDE8F081C0462DE9F04FB0F8DA3039 -+:108E600089B003F47043B3F5005F07468B46D0F832 -+:108E7000A85002D1B5F8C42304E0B3F5805F08D14F -+:108E8000B5F8C62313B2B3F1FF3F02D01FFA82FA3E -+:108E900001E04FF0700A072304931933069301236E -+:108EA0004FF00009039307AB0293C846CDF8049036 -+:108EB000019B18F0010F0BEB0306F378009303D02E -+:108EC00095F96635002B59D1B7F8DA3003F47043C1 -+:108ED000B3F5005F03D0019B13F80B9012E0B5F8D7 -+:108EE000402413B2B3F1FF3F18BF1FFA82F9B5F85F -+:108EF0003E2408BF4FF00F0913B2B3F1FF3F1CBF70 -+:108F000092B20092B37872781B0443EA022343EAD8 -+:108F10000A6343EA0903079395F9663502AC013306 -+:108F2000B8FBF3F3C033384621460593FFF774FCD2 -+:108F300007AB029395F9663538460133B8FBF3F376 -+:108F400003F5A07321460593FFF764F93279009B7E -+:108F5000120542EA0372079B384623F07F4323F44D -+:108F600070031A43079295F9663521460133B8FB21 -+:108F7000F3F303F5A0730593FFF74EFC019B08F193 -+:108F800001080533B8F1800F019391D195F9663549 -+:108F9000002B36D05E4608F1800896F8423196F8EC -+:108FA00041211B0443EA022302AC43EA0A6343EA79 -+:108FB00009033846214608F180050793CDF814804F -+:108FC000FFF72AFC07AB3846214602930595FFF7C9 -+:108FD00021F996F84421009B120542EA0372079B8F -+:108FE000384623F07F4323F470031A43214608F1E7 -+:108FF0000108079205950536FFF70EFCB8F5A07F2E -+:10900000CBD109B0BDE8F08F10B5B0F8DA30D0F8A8 -+:10901000A82003F47043B3F5005F03D1D2F87415B0 -+:10902000FFF71AFF10BDC0462DE9F043054687B093 -+:10903000D0F8A890002940D0072399F8C272029373 -+:1090400019330493012301934FF0000805AB0093FB -+:109050002AE007F1C003284669460393FFF7DAF8D0 -+:1090600006F1C003284669460393FFF7D5FB07F5D1 -+:10907000A073284669460393FFF7CCF806F5A07362 -+:10908000284669460393FFF7C7FB07F51073284688 -+:1090900069460393FFF7BEF806F510732846694644 -+:1090A0006C460393FFF7B8FB99F8C2325FFA88F673 -+:1090B000B34208F10108CCD20CE0B0F8DA3003F486 -+:1090C0007043B3F5005F02D10449FFF7C5FE28469F -+:1090D000FFF77EFE07B0BDE8F083C04684C90200FA -+:1090E0002DE9F041D0F8A84086B094F907144FF06C -+:1090F000FF3289B20646FFF709F994F9673505464C -+:10910000022B01D0002007E094F90814304689B200 -+:109110004FF0FF32FFF7FAF8072302931933049355 -+:109120000123C0EB05070193304605ABB4F8681581 -+:109130004FF0FF320093FFF7E9F84FF000084FF0CF -+:109140000003C019A4F86A3548BFA4F86A0521E0F5 -+:1091500094F8662512B111F0010F19D1B4F86835F1 -+:10916000B4F96A558B4253B238BFED1B013391FB02 -+:10917000F3F3DBB203F5107330464FF0FF32039385 -+:10918000FFF7C4F8401B059069463046FFF744FBE3 -+:1091900008F10108B8F1800F5FFA88F1D8D194F98D -+:1091A00066357BB10123019305AB0093402404F5A0 -+:1091B0001073304669460393FFF72EFB631CDCB245 -+:1091C000802CF4D106B0BDE8F081C04630B518233C -+:1091D00087B0D0F8A8400393083305936033029317 -+:1091E00000230546049301A904F19C030193FFF7B2 -+:1091F00013FB2846B4F89C2240F27161F9F7A6FAF5 -+:109200002846B4F89E2240F27361F9F79FFA284687 -+:10921000B4F8A22240F27461F9F798FA2846B4F83B -+:10922000A02240F27561F9F791FA2846B4F8A42219 -+:1092300040F27961F9F78AFA2846B4F8A62240F29A -+:109240007661F9F783FA2846B4F8A82240F2DA6189 -+:10925000F9F77CFA2846B4F8AA2240F22551F9F72A -+:1092600075FA2846B4F8AE224FF48F61F9F76EFA1A -+:109270002846B4F8B0224FF49A61F9F767FAB4F8C7 -+:10928000B2324FF40042DB032846134040F224512F -+:10929000F9F782FA94F8AC32284684F86735B4F8C6 -+:1092A000B432A4F8683594F8B63284F8073494F8E8 -+:1092B000B73284F80834FFF713FF07B030BDC0465B -+:1092C0002DE9F04F8DB0039202930BAB0646D0F818 -+:1092D000A8708B4600930DF12F010DF12D030DF1B8 -+:1092E0002E02FCF75BF930460DF12A010AAAFFF7BE -+:1092F00065FA3046FFF702F90723069319330893FE -+:1093000009AB04934FF000080123059381464FF405 -+:1093100050735D46C246079338E097F8662522B140 -+:109320000AEB0B0313F0010F2DD153B2013304AC40 -+:10933000B5FBF3F303F5A073304621460793FEF720 -+:1093400069FF099BBDF828201B0D92051B05920D96 -+:109350001A43BDF82A3030469B059B0D42EA83280C -+:109360002146CDF82480FFF757FACDF8249097F9DD -+:10937000663530460133B5FBF3F303F5E073214660 -+:109380000793FFF749FA01350AF1010A039A95425A -+:10939000C3D997F96635C3B17F2A16D14FF4C0758A -+:1093A00004AC304621460795CDF82480FFF734FA07 -+:1093B00005F18003304621460135CDF8249007930E -+:1093C000FFF72AFAB5F5E07FEAD1029A07EB4203EC -+:1093D000BDF82A20A3F86C20BDF82820A3F87890C7 -+:1093E000A3F872209DF82F3087F87E309DF82E303C -+:1093F00087F87F309DF82D3087F880309DF82C302D -+:1094000087F881300DB0BDE8F08FC0462DE9F04FF0 -+:109410008DB00393C369D0F8A86005460C469868E0 -+:109420004FF480619346EDF353F40746002800F0B3 -+:109430008A80C5F8FC4F28460121FDF769FA96F8A5 -+:109440002C3043B1284641490622F9F7B9F928469C -+:109450000021FEF7D9FDA4B101203D4984EAE47260 -+:10946000A2EBE47200FB01F1B1FBF2F39EB202FB4E -+:1094700006F2431C8A4298B2EFD1B6F5807F01D93B -+:109480005AE00226242304FB03F349F6404293FBEF -+:10949000F2F300241B04642293FBF2FAA146A046D7 -+:1094A0002EE048460AA9F9F72FFD0B9B03FB0BF3AF -+:1094B000002B04DBDB130133C3F3490206E05B42FC -+:1094C000DB1301335B105B429A05920D0A9B03FB91 -+:1094D0000BF3002B04DBDB130133C3F3490306E07A -+:1094E0005B42DB1301335B105B429B059B0D43EA40 -+:1094F000822347F82830631CD1449CB208F101084C -+:10950000B442CED1062228461249F9F759F915235B -+:10951000079300240B33284605A90993059706965F -+:109520000894FFF779F9039B2846009331464FF6DC -+:10953000FF722346FDF772F8EB69394698684FF4DD -+:109540008062EDF3D5F30DB0BDE8F08FCE070200D9 -+:10955000005A6202C207020030B587B005AB009323 -+:1095600001230193173302930833002204934FF42D -+:109570000023054603920593144628466946FFF7E3 -+:109580004BF9039B01330393631CDCB2802CF4D1B1 -+:1095900007B030BDF0B5D0F8A83087B093F89A2561 -+:1095A0000746002A2DD1324B324D1E68144605E085 -+:1095B00029463846FFF730F901341435B442F7D163 -+:1095C0002D4A002453683846019310230293082340 -+:1095D00004931368694600930394FFF71DF9FB6930 -+:1095E0001B6B082B0DD1254A3846536869460193F9 -+:1095F000122302930E330493136803940093FFF72E -+:109600000BF9102304930DF1160300934FF072032E -+:1096100008260125ADF81630384600236946039325 -+:1096200002960195FFF7F8F84FF082033846694635 -+:10963000ADF816300395FFF7EFF84FF006036946D3 -+:109640003846ADF816300396FFF7E6F83846FFF7D0 -+:10965000DBFC3846FFF728FB3846FFF73BFB384674 -+:10966000FFF7B6FB38466C46FFF776FF07B0F0BD54 -+:10967000F8100200D4150200181D0200F41C0200AC -+:1096800070B5B0F8DA30054603F47043B3F5005F07 -+:10969000D0F8A8200CD192F9F133B3F1FF3F37D1C4 -+:1096A000B2F9F833B3F1FF3F32D1B2F92C352CE0E7 -+:1096B000B3F5805F35D192F95B35B3F1FF3F27D128 -+:1096C00092F9F333B3F1FF3F22D192F95C35B3F154 -+:1096D000FF3F1DD1B2F90034B3F1FF3F18D1B2F909 -+:1096E0003035B3F1FF3F13D1B2F90234B3F1FF3F8C -+:1096F0000ED1B2F93435B3F1FF3F09D1B2F90434D8 -+:10970000B3F1FF3F04D1B2F93835B3F1FF3F08D0D0 -+:10971000012482F86645102228464FF49A611346C8 -+:1097200007E0002482F8664528464FF49A6110222B -+:109730002346F9F731F84FF48F6103222346284678 -+:10974000F9F72AF82846FFF725FF2846FBF7E2FF3E -+:109750002846FCF7E1FE2846FFF768F870BDC046D2 -+:1097600010B5002388B00593103307930DF106035D -+:10977000039301230446ADF80610049303A9543360 -+:109780000693FFF749F82046FBF7FEF810B1204694 -+:10979000FEF7C8FE08B010BD2DE9F041D0F8A87062 -+:1097A0000646002419E0B6F8DA3003F47043B3F546 -+:1097B000805F07D1A218137923B1890492783046CB -+:1097C000890C07E06B4BE21853792BB18904D278EE -+:1097D0003046890CF8F73CFF0634664A4FF6FF73B3 -+:1097E000A15A9942DFD1304673210022F8F730FFA9 -+:1097F000304632216A22F8F72BFF192230463321F6 -+:10980000F8F726FF97F8EC231AB130463321F8F722 -+:109810001FFFC2216F223046F8F71AFF9021102255 -+:109820003046F8F715FF102100223046F8F710FFF8 -+:109830009B2107223046F8F70BFF1D2102223046FC -+:10984000F8F706FF1E2106223046F8F701FF3046E2 -+:1098500040F2EA4144F28862F8F778FFB6F8DA306D -+:1098600003F47043B3F5005F0DD197F8E933B6F810 -+:10987000DE1FA02B14BF022204220BB2B3F1FF3F64 -+:109880000DD0CAB20BE0B3F5805F07D1B6F8E02F78 -+:1098900013B2B3F1FF3F01D0D2B200E0022253B2C3 -+:1098A0001FFA83F807224346304640F2EB41F8F7AF -+:1098B00073FFB6F8DA3003F47043B3F5005F05D0F8 -+:1098C000B3F5805F04D197F83B350BB9002400E075 -+:1098D00001242346254624010F22A4B2304640F23B -+:1098E000F241F8F759FFF0222346304640F2F241A8 -+:1098F000F8F752FF0F22304640F2F1412B46F8F7BD -+:109900004BFFF0222346304640F2F141F8F744FF86 -+:109910004FEA0823304640F2F2414FF4E06203F48C -+:109920007F43F8F739FFB6F8DA30304603F4704376 -+:10993000B3F5805F0CBF03F53B7341F2EA23F45AA1 -+:1099400040F2EB41630203F47E434FF40072F8F7F8 -+:1099500023FFB6F8DA3003F47043B3F5805F0BD021 -+:1099600041F23433F25A13B2B3F1FF3F04D0930201 -+:1099700003E0C046EC260200A3024FF4806203F429 -+:109980007C43304640F2EB41F8F706FF40F2EB41F2 -+:109990003046D6F8A840F8F7CDFEC0F3802084F812 -+:1099A000470540F2EB413046D6F8A840F8F7C2FE32 -+:1099B000C0F3402084F84805D6F8A820304692F835 -+:1099C000481592F847355B1A18BF012382F84635CF -+:1099D000FAF7ECFF830203F47C43304640F646116D -+:1099E0004FF48062F8F7D8FE304643490622F8F774 -+:1099F000E7FE41F21D23F35C2BB10F2230467721A5 -+:109A00001346F8F76BFE30460021FFF7A9FE97F8E2 -+:109A10009A352BB93046FEF73FF83046FDF71EFF6A -+:109A2000F3697A21186936F065DE97F8EC23400077 -+:109A300084B22AB124B1F369A11C186936F078DE2A -+:109A400097F8ED232AB124B1F3692146186936F05D -+:109A50006FDE97F8BB34DBB104221346304640F288 -+:109A60001D11F8F73BFE30469F213F2297F8BC348A -+:109A7000F8F734FE30469E213F2297F8BD34F8F7C0 -+:109A80002DFE304677210F2297F8BE34F8F726FED8 -+:109A9000B6F8DA3003F47043B3F5805F29D197F953 -+:109AA000583533B3B42124223046F8F7D1FDB7211D -+:109AB00024223046F8F7CCFD0322B8213046F8F7CF -+:109AC000C7FD97F95825022A07D13046B821F8F783 -+:109AD000BFFD3046B521012209E0032A09D13046F5 -+:109AE000B821013AF8F7B4FD3046B5210022F8F765 -+:109AF000AFFDBDE8F081C046C604020010B5FFF717 -+:109B00004BFE10BD70B50026D0F8A850C0F8FC6F11 -+:109B100095F82C3004463BB12A490622F8F750FE4E -+:109B200020460121FEF770FA204640F24461F8F722 -+:109B300001FE10F0010309D020463146FCF740FD3C -+:109B40000222204640F23F61134607E010F0020F68 -+:109B500006D0204640F253414FF40042F8F71CFE75 -+:109B6000204619490922F8F72BFE20460021FCF770 -+:109B7000CFFE2046FAF71AFF30B12046FEF7BEFCB2 -+:109B800001462046FFF7ECFD95F8473520469B023D -+:109B900003F47C4340F2EB414FF48062F8F7FCFDA4 -+:109BA000B5F84E356BB1204640F64811FF22F8F764 -+:109BB000F3FD204640F64911FF22B5F85035F8F77D -+:109BC000EBFD70BDE60B0200F20B020070B50C4617 -+:109BD00088B00546F9F720F944B92846FFF792FF07 -+:109BE00028462146FCF794FE204622E028462146DE -+:109BF0000122FAF789F8064608B1012019E0284643 -+:109C00000121FCF785FE0C4B40240393152305939B -+:109C10002846102303A9079304940696FEF7FCFD3B -+:109C2000284621464FF6FF7233460096FCF7F6FCB5 -+:109C3000304608B070BDC0469A21020070B50023BE -+:109C400086B002931033049305AB009302230446BD -+:109C5000ADF8141001930D464E3369461646ADF823 -+:109C600016200393FEF7D8FD2046FAF79FFE78B33F -+:109C7000204640F6461140F2FF322B46F8F78CFDA5 -+:109C8000204640F6471140F2FF323346F8F784FD94 -+:109C900020464FF4156140F2FF322B46F8F77CFD69 -+:109CA000204640F6511140F2FF323346F8F774FD7A -+:109CB000204640F6541140F2FF322B46F8F76CFD77 -+:109CC000204640F6551140F2FF323346F8F764FD66 -+:109CD00006B070BD2DE9F04F8DB004910392D0F81D -+:109CE000A860074606EB4303B3F872B0B3F86C10F4 -+:109CF000B3F878905A460591FFF7A0FF38464946D9 -+:109D0000FFF72EFD0723089319330A934FF000083D -+:109D10000123049D0793C2460BAB069337E096F8E8 -+:109D200066252AB104990AEB010313F0010F2BD128 -+:109D300053B2013306ACB5FBF3F303F5A073384619 -+:109D400021460993FEF766FA0B9B05994FEA8B5261 -+:109D50001B0D1B05920D1A438B059B0D42EA8328B0 -+:109D600038462146CDF82C80FEF756FD96F966352B -+:109D700038460133B5FBF3F303F5E073214609934D -+:109D8000CDF82C90FEF748FD01350AF1010A039A3F -+:109D90009542C4D996F96635C3B17F2A16D14FF4DE -+:109DA000C07506AC384621460995CDF82C80FEF7E3 -+:109DB00033FD05F18003384621460135CDF82C905E -+:109DC0000993FEF729FDB5F5E07FEAD196F8810009 -+:109DD00096F87E1096F87F2096F8803000903846EE -+:109DE000FBF7DEFC0DB0BDE8F08FC04670B500217A -+:109DF0000446D0F8A8500B467F22FFF76BFF2046A1 -+:109E0000FFF7E4F92046B5F8B812B5F8BA22FBF727 -+:109E1000C7F8204640F2D16104220023F8F7BCFCC9 -+:109E200070BDC04670B50446D0F8A8300D4699B153 -+:109E300093F8BC3233B3FFF7D9FF20460422002346 -+:109E400040F2D161F8F7A8FC8022204640F276610A -+:109E50001346F8F7A1FC15E00422134640F2D16145 -+:109E6000F8F79AFC8022204640F276612B46F8F7FC -+:109E700093FC20462946FFF773FC204629462A46D4 -+:109E8000FFF7DCFE70BDC04630B500238BB00893F1 -+:109E9000079306930733054603930A4609B90491CD -+:109EA00002E04FF4307304932023059309AB019330 -+:109EB000012302933AB9284608A907AA06ABF9F785 -+:109EC0000FF9002409E0B5F902310793B5F904311F -+:109ED0000693B5F906310893F3E70899069B2046E7 -+:109EE000079AFAF757FC01A909902846FEF794FC57 -+:109EF000049B01340133802C0493EED10BB030BDB0 -+:109F0000F0B5284B8BB005AC05460F460FCB84E867 -+:109F10000F0041F22403EB5CD5F8A8601BB196F862 -+:109F2000E034002B3BD028461F490822F8F748FCB4 -+:109F3000072302931933049304230193009403F538 -+:109F40004F7301240393284686F86A406946FEF75A -+:109F500063FC0023099309AB019400934FF45174FF -+:109F6000284669460394FEF757FC013440F25E33FD -+:109F70009C42F5D128460D491222F8F721FC7B00BE -+:109F80009BB2284640F2A94140F2FF12F8F704FCC8 -+:109F9000284640F2A36110220023F8F7FDFB0BB026 -+:109FA000F0BDC04668050200620C020054090200C0 -+:109FB00030B5D0F8A8509BB004460022A31893F9FE -+:109FC000103501A95B4241F822300132142AF5D143 -+:109FD00095F86A3063B907331793193319931591BC -+:109FE00003F54873204615A916921893FEF714FC42 -+:109FF000D4F8A81094F82936D1F844242046934286 -+:10A00000A8BF1346D1F8482440F2A7419342B8BFF5 -+:10A0100013469BB2FF22F8F7BFFB95F8E833F3B184 -+:10A02000B5F8E62394F8293620469B1A1B024FF414 -+:10A030007F42134040F2D141F8F7AEFB94F8292655 -+:10A0400095F825352046C3EB420395F8E62340F208 -+:10A05000D1419B1A5BB2FF229BB2F8F79DFB2046D1 -+:10A06000FAF7A6FB1BB030BD70B5C6B001ACD0F896 -+:10A07000A8500646002120464FF48072E7F3E0F72F -+:10A080000723439319334593419495F86A3043B9B4 -+:10A090001E33429330464FF4507341A94493FEF768 -+:10A0A000BBFB402342933046DB1841A94493FEF7A3 -+:10A0B000B3FB46B070BDC0462DE9F04106460C46E4 -+:10A0C000FAF72CFF214605463046FAF74FFC2946A1 -+:10A0D00004463046FAF74AFC4022B4F5404F0CBF24 -+:10A0E00013460023054640F2DA613046D6F8A870E0 -+:10A0F000F8F752FB1022B4F5404F14BF134600236B -+:10A10000304640F2A361F8F747FB0122B4F5404F17 -+:10A1100014BF00230123304640F26E41F8F73CFBA8 -+:10A12000A54200F09580B5F5404F02D13046FFF7CB -+:10A130009BFFB4F5404F3CD13046FFF739FFD6F8CE -+:10A14000A8203B8E92F966255B00013293FBF2F367 -+:10A15000304640F2A44140F2FF129BB2F8F71CFBDC -+:10A160007B8E30461B0240F2A5414FF4E06203F4BF -+:10A170007F43F8F711FB04223046002340F21F1101 -+:10A18000F8F7ACFAF369E021186936F0B3DA002188 -+:10A19000F8853046FAF7A2FF4FF0FF3387F83430E6 -+:10A1A000304640F2A9414FF400420133F8F7F4FA87 -+:10A1B00003E030460121FAF791FF304640F2A44116 -+:10A1C0004FF460422346F8F7E7FAB4F5404F0FD159 -+:10A1D0003046FAF7EBFB40F2A44100280CBF4FF4E5 -+:10A1E000005300234FF400523046F8F7D5FA15E03B -+:10A1F0004EF201039C4211D13046FAF717FB01469B -+:10A200003046FFF77DFE304640F2A941F8F792FA5A -+:10A210000223C0B290FBF3F087F8C10297F96735CB -+:10A22000012B0DDD40F2A4413046F8F783FAC0F36C -+:10A23000803340F2255130464FF40042DB0305E005 -+:10A24000304640F225514FF400420023F8F7A4FABB -+:10A25000BDE8F08170B50023D0F8A82080F82B3637 -+:10A2600092F8E03405468BB190F92A16D2F84834BA -+:10A27000994203DBD2F81035994207DA4EF2010118 -+:10A28000FFF71AFF012385F82B3612E041F2240371 -+:10A29000EB5C73B12846FAF741FE002104462846DC -+:10A2A000FFF70AFF2846FFF783FE28462146FFF7FF -+:10A2B00003FF70BD30B5072389B0D0F8A8400393E1 -+:10A2C0001933059306AB0193012302930546013B25 -+:10A2D000049308E0284601A9FEF79EFA049B013387 -+:10A2E0000493069B01330693069B7F2BF2D94FF410 -+:10A2F00030730493A3F5307308E0284601A9FEF7F4 -+:10A300008BFA049B01330493069B01330693069B4F -+:10A310007F2BF2D9092228465B49F8F751FA01212F -+:10A320002846FBF7A3FB242228465849F8F748FAA9 -+:10A330002846FAF75FFDC0F34F00E62801DDFF2352 -+:10A3400005E02846FAF756FD4008193083B2FF228F -+:10A3500040F2A5412846F8F71FFA2846FFF784FE89 -+:10A36000B4F8E623B4F8E433284603EB42039B0138 -+:10A370009BB24FF49A6147F6C072F8F70DFA0922C2 -+:10A3800028464349F8F71CFAB5F8DA30282103F4D7 -+:10A3900070431E22B3F5005F14BF18231C23284608 -+:10A3A000F8F79CF901223A2113462846F8F796F966 -+:10A3B0000822134628464FF48D71F8F78FF92521AE -+:10A3C0000C222846F8F744F9B5F8DA3003F4704364 -+:10A3D000B3F5005F04D1022228463A21134603E078 -+:10A3E00028463A2102220023F8F778F9082213467A -+:10A3F00028460521F8F772F9284606222549F8F77C -+:10A40000DFF947F20802284640F2D7414FF40053E3 -+:10A41000F8F7C2F92846FAF7EDFC102305930DF181 -+:10A420001E03019301230824ADF81E000293284661 -+:10A43000053301A904930394FEF7EEF928460F2291 -+:10A440001549F8F7BDF928463521FF220023F8F712 -+:10A4500045F92846362103220023F8F73FF928461C -+:10A46000224623464FF48D71F8F738F94FF4806295 -+:10A47000284640F2A4411346F8F78EF92846FBF728 -+:10A480008DFA09B030BDC046C60D02009A05020023 -+:10A49000A4070200F40D0200000E02007FB50902BD -+:10A4A00006AB23F8021D009301230193013B0293A5 -+:10A4B00057330393694610230493FEF7ADF907B0B1 -+:10A4C00000BDC0462DE9F041D0F8A8308AB083F82D -+:10A4D000341083F8C11293F9663506460F466BB106 -+:10A4E00011F0010304D04FF48F610C22082302E025 -+:10A4F0004FF48F610C22F8F74FF97F08072303937D -+:10A5000001AC07F5A07320254FF0010804933046F5 -+:10A5100009AB214601930595CDF80880FDF77AFE39 -+:10A5200007F1C003049330460DEB05032146019368 -+:10A530000595FDF76FFE089B304603F0FF02ADF86E -+:10A540001820C3F30722C3F30743ADF81C30099B5F -+:10A5500006A9C3F30273ADF81A20ADF81E30FAF75E -+:10A56000F5FD09993046C1F30751FFF797FF3046D3 -+:10A570004146FAF7B3FD0AB0BDE8F0812DE9F04F8E -+:10A5800091B0BDF8783002AC0193BDF87C3007463D -+:10A590000093534B9DF880601D460FCD0FC495E886 -+:10A5A0000F009DF8748084E80F0038464D4904225E -+:10A5B000BDF87090BDF884A0BDF888B0F8F700F938 -+:10A5C000384640F2A36102227300F8F7E5F8B8F1CB -+:10A5D000000F18D010AB4FF4002243F8042D0A935B -+:10A5E00001230B9317330C9308330E9300230D9321 -+:10A5F0001C4638460AA9FEF70FF90D9B01340133BA -+:10A60000402C0D93F5D1032409FB04F43846FAF7E6 -+:10A61000EBFE0134384640F2A1615246F8F796F855 -+:10A62000A4B2384640F2A2615A46F8F78FF82246A3 -+:10A63000384640F27E61F8F789F838462A49042204 -+:10A64000F8F7BEF80134142304FB03F4013CA2B272 -+:10A6500038464FF4C861F8F779F80022384640F2DE -+:10A660007761F8F773F808230B930D330C930B33D2 -+:10A6700000240E93384602AB0AA90A930D94FEF704 -+:10A68000CBF8384640F27B61019AF8F75FF838461C -+:10A6900040F27C61009AF8F759F82246384640F2B9 -+:10A6A0007D61F8F753F821463846FFF7F7FE384644 -+:10A6B0000E490422F8F784F80D4C03E00A20ECF36D -+:10A6C0004BF00A3C384640F27661F8F733F810F068 -+:10A6D000010F01D0092CF1D111B0BDE8F08FC046B7 -+:10A6E000B80C0200780B02008A0802001E0E02005D -+:10A6F00049420F002DE9F043D0F8A8908BB00646F0 -+:10A700008846052503270F2DA8BF0F250024ABB2CF -+:10A71000019330460121224623460094029403947B -+:10A720000494FAF75BFDDB2302934FF4AF630493C9 -+:10A730004FF482430593A3F58143012207933046EA -+:10A740002146234600940194039206940894FFF74F -+:10A7500015FFB8F1000F1DD140F2BA613046F7F78E -+:10A76000E9FF40F2BB6104B23046F7F7E3FFA40112 -+:10A77000A4B244F3891404FB04F440F3090000FB81 -+:10A780000043B3F5005F01DAED1B03E0B3F5804F42 -+:10A7900004DBED1917B17B1EDFB2B4E7092D01DD33 -+:10A7A000092501E025EAE5752846C9F838500BB0BF -+:10A7B000BDE8F0832DE9F043D0F8A8608DB096F99C -+:10A7C000663507468846CCB2D3B1634B01EA030332 -+:10A7D000002B05DA013B6FEAC3736FEAD3730133D1 -+:10A7E000012B04D14FF48F610C22073303E04FF4A7 -+:10A7F0008F610C220023F7F7CFFF022398FBF3F8B9 -+:10A80000072386F8344086F8C14201AD039308F56A -+:10A81000A07320244FF00109049338460BAB29465E -+:10A8200001930594CDF80890FDF7F4FC08F1C003FE -+:10A83000049338460AAB294601930594FDF7EAFCD8 -+:10A840000A9B384603F0FF02ADF81820C3F3072235 -+:10A85000C3F30743ADF81C300B9B06A9C3F3027387 -+:10A86000ADF81E30ADF81A20FAF770FC9DF82B10E9 -+:10A87000384601F07F01FAF71DFC0B993846C1F309 -+:10A880000751FFF70BFE38464946FAF727FC0B9AAB -+:10A890003846C2F389219205920DFFF7CFF908F5EA -+:10A8A000E0730493384609AB29460193FDF7B2FCE7 -+:10A8B0003846BDF82410FEF753FF08F510730493D3 -+:10A8C00038460DEB040329460193FDF7A3FC089BD2 -+:10A8D0003846DB009BB240F2A66141F6FF72F7F703 -+:10A8E0005BFF96F967354B4532DD40F2255138461E -+:10A8F000F7F720FF4FF48072C3B29845D4BF00240D -+:10A90000012438469845CCBF1346002340F2255118 -+:10A91000F7F742FF6302384640F225514FF40072C8 -+:10A9200003F47E43F7F738FFA302384640F225517F -+:10A930004FF4806203F47C43E402F7F72DFF3846BE -+:10A9400040F225514FF4006204F47843F7F724FFF6 -+:10A950000DB0BDE8F083C0460100008070B504462C -+:10A960000D460021FFF7A8FB20462946FFF722FFEE -+:10A9700070BDC0462DE9F04F89B0054600920191A7 -+:10A98000FAF7CCFA40F23B4103902846F7F7D2FEA3 -+:10A9900004A902902846FAF70FFA00244FF47A70BF -+:10A9A0000134EBF3D9F6022CF8D141F2F023EA5846 -+:10A9B00092F820301F1E18BF012792F821300BB1EA -+:10A9C0007B1C9FB292F822300BB17B1C9FB292F895 -+:10A9D00023300BB17B1C9FB24FF00009C8464FF0EB -+:10A9E000140ABCE0D5F8B030D3F8203183F001036D -+:10A9F00013F0010403D1EB69186935F0CBDE28466A -+:10AA0000F8F756FB41F2F023EB58284603EB4803D6 -+:10AA1000998CFFF7A3FF28465146FFF73FFD1CB96D -+:10AA2000EB69186935F0A2DE4FF40042284640F287 -+:10AA3000A4411346F7F7B0FE002441F288300134F8 -+:10AA4000EBF38AF6032CF8D1284640F2A641F7F73B -+:10AA500071FEC005C00DFF2886BFA0F580731FFAE8 -+:10AA600083FB00F5807B00263446284640F23E6199 -+:10AA7000F7F760FE631CC005C00D9CB23618102CA1 -+:10AA8000F3D1C6F30F13FF2B8CBFA3F5807303F52F -+:10AA90008073504600210DF11E029EB20DF11A0383 -+:10AAA000EDF388F441F2F023EB580021434493F88E -+:10AAB000200007AA06ABEDF37DF4BDF91A30BDF90D -+:10AAC00018108B4209DABDF91C00C91AEDF324F500 -+:10AAD000BDF81A40ADF81C0009E0BDF91E00C1EB3D -+:10AAE0000301EDF319F5BDF81840ADF81E00BDF9EE -+:10AAF0001C10BDF91E00EDF319F523B2032B81B232 -+:10AB000001DD231F01E0C4F1040398B200B2431E2B -+:10AB100001229A4009B2052301FB032353FA00F0F6 -+:10AB200000F10C03182B16D841F2F023EB58019AD0 -+:10AB300003EB88031B69C31802F809304FEA9B0333 -+:10AB4000C3F17F03009A03EB960302F8093009F181 -+:10AB500001031FFA83F908F101031FFA83F8B845CE -+:10AB6000FFF440AF0AF101035FFA83FABAF1640F10 -+:10AB700002D84FF00008F2E7029B2846C3F3801189 -+:10AB8000FAF7ACFA284604A9FAF7E0FA284603993E -+:10AB9000FFF792FA484609B0BDE8F08F2DE9F04F73 -+:10ABA0001E46C369A9B0D0F8A88004460F4698682D -+:10ABB0004FF483711546ECF38BF00790002800F0FA -+:10ABC000EF81022E0FD016E00E4694F8DA3011F81D -+:10ABD0000629013D9A420BD17188B2882046FAF7C6 -+:10ABE000DFF90126CCE1062305FB03F3063BF91848 -+:10ABF000002DE9D1C3E1012E40F0C1812046FAF7D2 -+:10AC00008DF9002108902046FFF756FA0025934B56 -+:10AC10002046E95AF7F704FD1AABE8520235182D21 -+:10AC2000F5D140F231612046F7F784FD15220B90F3 -+:10AC300040F231612046F7F79FFD40F24C4120463B -+:10AC4000F7F778FD40F24D410C902046F7F772FD82 -+:10AC50004FF496610D902046F7F76CFD40F2B1413C -+:10AC60000E902046F7F766FD40F2F9410F9020461E -+:10AC7000F7F760FD40F2FA4110902046F7F75AFDD1 -+:10AC800040F6381111902046F7F754FD40F639117F -+:10AC900012902046F7F74EFD40F23B4114902046BB -+:10ACA000F7F748FD40F23C4115902046F7F742FD8A -+:10ACB00040F2DA6116902046F7F73CFD40F2DB6186 -+:10ACC00018902046F7F736FD40F2B741199020461C -+:10ACD000F7F730FD40F23B4113902046F7F72AFD8D -+:10ACE000C0F380100A9008B9099007E0204626A911 -+:10ACF000FAF762F898F8C182CDF82480204632999C -+:10AD0000FFF72CFE062220465549F7F759FDB4F807 -+:10AD1000DA3003F47043B3F5005F04D12046982184 -+:10AD20000322F7F795FC20464E491922F7F748FD14 -+:10AD300020464D491822F7F743FDB4F8DA304FF0BA -+:10AD4000030B03F47043B3F5005F14BF0423002327 -+:10AD5000179322E11FFA88F300931FFA89F3002664 -+:10AD600001931FFA8BF3324602932046179B31461C -+:10AD700003960496FAF732FA20460121FAF742F9CF -+:10AD80003346204639493C22FEF740FB20464FF42B -+:10AD900089713246F7F75CFC20AB00934FF4FA7AE6 -+:10ADA00020464FF4806120223346CDF804A0FAF704 -+:10ADB000F7FF054620B92E48F6F776FC2F4636E019 -+:10ADC0003346204629497822FEF720FB20464FF4DF -+:10ADD00089713246F7F73CFC23AB009320464FF4D1 -+:10ADE000806120223346CDF804A0FAF7D9FF18B9C4 -+:10ADF0002048F6F759FC1AE0219A24982299B0EBE2 -+:10AE0000420F0ED993009B1898420AD2259AB2EBB2 -+:10AE1000410F06D98B005B189A422CBF00270127EF -+:10AE200000E00027B8F1010801D3002F92D0B9F15A -+:10AE3000010902D3002F00F0AC80BBF1010B02D35B -+:10AE4000002F00F0AA80204640F2D16104220023A6 -+:10AE5000F7F7A2FC87B93E4614E0C046020502009F -+:10AE60001A05020026050200FA05020080841E0071 -+:10AE7000EC0602000607020020464FF48061FDF751 -+:10AE80002BF806462046FEF73DFE204640F2316193 -+:10AE90000B9AF7F75BFC204640F24C410C9AF7F70F -+:10AEA00055FC204640F24D410D9AF7F74FFC2046E5 -+:10AEB0004FF496610E9AF7F749FC204640F2B141F3 -+:10AEC0000F9AF7F743FC204640F2F941109AF7F742 -+:10AED0003DFC204640F2FA41119AF7F737FC204634 -+:10AEE00040F63811129AF7F731FC204640F6391136 -+:10AEF000149AF7F72BFC204640F23B41159AF7F7DE -+:10AF000025FC204640F23C41169AF7F71FFC2046EC -+:10AF100040F2DA61189AF7F719FC204640F2DB613B -+:10AF2000199AF7F713FC204640F2B741139AF7F746 -+:10AF30000DFC204640F24C4104220023F7F72CFC84 -+:10AF40000025194B2046E95A1AABEA5A0235F7F7A1 -+:10AF50007FFB182DF5D10A9B23B120460999FFF7F5 -+:10AF6000FDFC03E020460A99FAF7B8F82046089954 -+:10AF7000FFF7A2F820460021FAF744F800E0002687 -+:10AF8000E369079998684FF48372EBF3B1F63046A2 -+:10AF900006E000274FF00608DCE64FF00409F8E76A -+:10AFA00029B0BDE8F08FC046020502002DE9F04F40 -+:10AFB000B3B00F939DF8F8409DF8F4300D940E93C4 -+:10AFC0009DF800419DF8FC300B940C93012405463C -+:10AFD0001646D0F8A89088469DF8F0B0BDF80471E8 -+:10AFE0008DF8C7408DF8C640FDF702FC40F2D7410E -+:10AFF00012902846F7F79EFB40F2D7411090284662 -+:10B00000F7F798FB3449119006222846F7F7D8FB4A -+:10B01000284632490F22F7F7D3FB284621461AAAC1 -+:10B02000FDF786FB284621460022FDF7F5FABBF125 -+:10B03000000F02D00023199318E028462146FBF7A1 -+:10B0400067FCD5F8B030D3F8203183F0010313F05A -+:10B05000010319930AD1EB69B821186942F2107201 -+:10B0600035F066DBEB69186935F094DB2846012181 -+:10B07000F9F7C8FF28460121FBF7A2FA284601216B -+:10B08000FAF72EF940F2EA412846F7F753FB40F26F -+:10B09000EB4117902846F7F74DFB40F2EB41189033 -+:10B0A0002846F7F747FB00F0070340F2EB4128463C -+:10B0B0003822DB00F7F770FB28462DA999F8C1A2CA -+:10B0C000F9F77AFE86B1337A53B12846717AFFF7E1 -+:10B0D00045FC96F809A007E0F6090200A60B02005D -+:10B0E00028463146FAF732F840F29C412846F7F7F5 -+:10B0F00021FB40F2316113902846F7F71BFB40F229 -+:10B10000D66115902846F7F715FB40F2DA611490E6 -+:10B110002846F7F70FFB002116902846FAF728FA81 -+:10B12000284688490722F7F74BFB2FAB23930123CF -+:10B1300024930633259376B199F96625737A013203 -+:10B1400093FBF2F303F5107326932846202323A9DB -+:10B150002793FDF75FF82F9A2846D2002F9240F2EE -+:10B16000716192B2F7F7F2FA284677490C22F7F7A5 -+:10B1700027FB0024754B284633F81410F7F750FAD4 -+:10B180000DF1A203E0540134122CF3D1072228461A -+:10B190004FF48B71F7F75CFAB5F8DA3003F47043CB -+:10B1A000B3F5005F05D1284640F22D110122F7F7D3 -+:10B1B0004FFA072228464FF49671F7F749FAB5F887 -+:10B1C000DA3003F47043B3F5005F14D128466A21E6 -+:10B1D000C222F7F73DFA284698210C22F7F738FAF1 -+:10B1E000284640F22F110322F7F732FA284697211A -+:10B1F000F922F7F72DFA0B2107222846F7F728FA4C -+:10B200001022284640F21311F7F722FA1D210122DD -+:10B210002846F7F71DFA012228464FF48A71F7F7FE -+:10B2200017FAB5F8DA3003F47043B3F5005F04D1D0 -+:10B2300028462E211022F7F70BFA082228464FF451 -+:10B240009571F7F705FA092102222846F7F700FA67 -+:10B2500004221346284640F21F11F7F73FFAFF2158 -+:10B26000102200232846F7F739FA0721012200238C -+:10B270002846F7F733FA0521082200232846F7F776 -+:10B280002DFA4FF400421346284640F2DA61F7F7F0 -+:10B2900083FA41460F9A53462846FFF72BFA0024BB -+:10B2A00080B2012101902246284623460094029450 -+:10B2B00003940494F9F792FF0E9BA74208BF4FF442 -+:10B2C000824700930D9B284601930C9B41460293B5 -+:10B2D0000B9B224603934FF4AF630493A3F59F6344 -+:10B2E00007935B46059706940894FFF747F90DF11D -+:10B2F000C60228460DF1C701F9F798FC9DF8C62053 -+:10B300003F2A53D89DF9C730A3424FDB3F2B4DDC7A -+:10B3100052B29A424ADCB8F1000F27D123AC18236D -+:10B3200021462593284630AB26922393FCF772FFE3 -+:10B330009DF9C73021462846309E2693FCF76AFFC8 -+:10B3400044460EE0020A0200200D0200260E020012 -+:10B3500030AB284623A9269430962393FDF75CFA58 -+:10B3600001349DF9C62063B29A42F1DC182323AC64 -+:10B37000259326332693284630AB21462393FCF7AA -+:10B3800049FF3F23284621462693FDF745FA01232E -+:10B39000284621462693FCF73DFF002328462146F8 -+:10B3A0002693FDF739FA2846FDF72EF8284640F295 -+:10B3B000EA41179AF7F7CAF9284640F2EB41189A82 -+:10B3C000F7F7C4F92846D72102220023F7F786F9B8 -+:10B3D000082213462846D721F7F780F9002328468C -+:10B3E0004FF494710822F7F779F928464FF48B71DE -+:10B3F0000022F7F72DF9284640F29C41139AF7F7FF -+:10B40000A5F9284640F23161159AF7F79FF92846C9 -+:10B4100040F2D661149AF7F799F9169C284644F041 -+:10B42000010292B240F2DA61F7F790F92846012161 -+:10B43000FAF79EF8109C082204EA0203284640F21C -+:10B44000D741F7F7A9F9119C4FF4E04204EA02034F -+:10B45000284640F2D741F7F79FF92846FAF73CFD16 -+:10B460000024234B284633F814100DF1A203E25CAC -+:10B470000134F7F7EDF8122CF3D14FF400620023FA -+:10B48000284640F24C41F7F787F928460021FBF7A0 -+:10B4900097F828460021F9F7B5FD284640F23B41D0 -+:10B4A00001220023F7F778F900234FF400622846C1 -+:10B4B00040F63811F7F770F928460021FBF728FA13 -+:10B4C000284600211AAAFDF733F9284609490F2218 -+:10B4D000F7F776F9199B1BB9EB69186935F046D96E -+:10B4E00028461299FEF7DAFF33B0BDE8F08FC04668 -+:10B4F000260E0200C40A02002DE9F04FD0F8A83051 -+:10B5000091B093F8F49318230C930FAB0A93202374 -+:10B510000E93012317460B9301FB01FB3E330521DC -+:10B5200000228046B9F1FF0F08BF4FF001090D93CB -+:10B530000791099206230024039347F6FF733A46C6 -+:10B540000125059340462346214600940194029428 -+:10B550000495FFF72BFD40460AA9FCF75BFE0F9A06 -+:10B5600042F30B3303FB03F342F30B0202FB023201 -+:10B570007B7A5A45069303D307990894CEB206E026 -+:10B58000B9F1000F4DD1079908954B42DEB273B265 -+:10B5900006999DB26B189CB24FF0000A06990AEB0F -+:10B5A000010308999BB221B15A4506D99B1B7B72B6 -+:10B5B0002DE0089B0BB95A4529D322B27F2A26DCFD -+:10B5C0000AEB0503002A1FFA83FA20DB06237C72AC -+:10B5D000039301230021049347F6FF733A46059332 -+:10B5E00040460B46009101910291FFF7DFFC404677 -+:10B5F0000AA9FCF70FFE0F9A42F30B3303FB03F388 -+:10B6000042F30B0202FB023263199CB2C6E70799B0 -+:10B61000099A41F346030132DBB2032A07930992E8 -+:10B6200088D111B0BDE8F08F2DE9F04F8DB0DDF875 -+:10B6300058A01F460123834616468AF808304FF06B -+:10B6400000094FF0640808EB09030021C3F34F051C -+:10B65000DB238AF8095001245246039358460B46CF -+:10B6600000910191029105910494FFF79FFC18232A -+:10B670000893273309930BAB06935846202306A95A -+:10B680000A930794FCF7C6FD0B9B43F30B3202FBB6 -+:10B6900002F243F30B0303FB03231A464FEAE27360 -+:10B6A000BB4202D803D1B24201D9A94600E0A84664 -+:10B6B0000B484FF0FF31801941EB07018B4202D854 -+:10B6C00006D1824204D99F4206D801D1964203D8BE -+:10B6D000C9EB0803012BB6DC28460DB0BDE8F08F9E -+:10B6E00030F8FFFFF7B50546D0F8A87090F8DA00FB -+:10B6F0000E46F7F735FA40F6B41398420446B5F80B -+:10B70000DA2001D11E480AE0D3B2012B02D14FF456 -+:10B71000523004E00302A3F5C420A0F580600022AB -+:10B720004FF47A71F9F716F8A0FB0023284600962B -+:10B73000FFF77AFFA0F128039BB21D2B1BD9272806 -+:10B7400002D84FF434300BE040F6B4139C4202D1DF -+:10B750004FF4703004E02302A3F5BE20A0F5007082 -+:10B7600000224FF47A71F8F7F5FFA0FB002328467A -+:10B770000096FFF759FF031F87F8C232FEBDC0468F -+:10B78000008E03002DE9F04390F8DA30D0F8A8607D -+:10B790008BB086F8BC32D0F8B0300546D3F82031F3 -+:10B7A00083F0010313F001090AD1C369B8211869B4 -+:10B7B00042F2107234F0BCDFEB69186934F0EADF52 -+:10B7C00040F2A5412846F6F7B5FF04462846F9F7AA -+:10B7D000A5FB002180462846FEF76EFC4FF4404151 -+:10B7E0002846FEF769FC2846FEF73EFCD5F8A8205F -+:10B7F0002846D2F84434D2F84824402BA8BF40232E -+:10B800009342B8BF134640F2A741FF229BB2F6F71E -+:10B81000C3FF0023284640F2A5414FF4E062F6F74B -+:10B82000BBFF4FF47A7232212846FBF7ABF80121B7 -+:10B83000284696F8C072FBF76BF82846F7F738FCF5 -+:10B840004FF4E06204EA0203284640F2A541F6F70D -+:10B85000A3FF00212846FEF72FFC96F8C4420DF105 -+:10B860001E0E012C35D171462846FFF73BFF2846B6 -+:10B870002146FDF7D9FBD5F8A8202846D2F8443454 -+:10B88000D2F848243E2BA8BF3E239342B8BF1346AC -+:10B8900040F2A741FF229BB2F6F77EFF0023284625 -+:10B8A00040F2A5414FF4E062F6F776FF28463221D8 -+:10B8B0004FF47A72FBF766F896F8C032DBB996F867 -+:10B8C000C2322846043386F8C2322146FDF7ACFB6B -+:10B8D00011E000210122DB238DF82620039304923E -+:10B8E000284672460B468DF827700091019102910F -+:10B8F0000591FFF75BFB28464146FEF7DDFB284636 -+:10B9000008490422F6F75CFFB9F1000F03D1EB6997 -+:10B91000186934F02BDF28460021FAF7F9FF0BB045 -+:10B92000BDE8F083800C02002DE9F04F044695B08D -+:10B93000D0F8A86040F2E7300F46EAF30DF7072190 -+:10B940002046F6F76DFEC0B20390FF212046F6F7C1 -+:10B9500067FEC0B2049040F21F112046F6F760FE69 -+:10B96000C0B2059005212046F6F75AFE25215FFA60 -+:10B9700080FB2046F6F754FE4FF489715FFA80FA97 -+:10B980002046F6F74DFE00250190864B2046E95AE9 -+:10B99000F6F7D0FE07ABE85202351C2DF5D1D4F8EE -+:10B9A000B030D3F8203183F0010313F00103029388 -+:10B9B00003D1E369186934F0EDDE40F2A44120467A -+:10B9C000F6F72EFE002181462046FEF775FB7F210B -+:10B9D000204696F8C182FEF7C1FF012207211346D7 -+:10B9E0002046F6F77BFE1022FF2113462046F6F78D -+:10B9F00075FE04221346204640F21F11F6F76EFE34 -+:10BA0000362220466849F6F7DBFE2046F9F7F2F9C0 -+:10BA1000C0F34F00E62801DDFF2305E02046F9F7DB -+:10BA2000E9F94008193083B2FF22204640F2A541CF -+:10BA3000F6F7B2FE25210C222046F6F709FE082271 -+:10BA4000134605212046F6F749FE092257492046AC -+:10BA5000F6F7B6FE2046F9F7CDF91023129301232D -+:10BA6000ADF84E0008260F9306250DF14E03204633 -+:10BA70000EA910960E931195FCF7CEFE012F0CD156 -+:10BA80002A4620464A49F6F79BFE2022204682217C -+:10BA90001346F6F723FE042506E02A4620464549CC -+:10BAA000F6F78EFE07260A250122134620464FF49C -+:10BAB0009B61F6F771FE45F4007343EA06139B00A1 -+:10BAC00020464FF49B6140F6FC72F6F765FE0222B9 -+:10BAD000134620464FF49B61F6F75EFE20464FF476 -+:10BAE0009B614FF4E0424FF40053F6F755FE2022DD -+:10BAF000134620464FF49A61F6F74EFE01210022CC -+:10BB00002046F8F7DFF9204640F27641F6F712FEBC -+:10BB100010F4004F02D10A20EAF31EF62046072156 -+:10BB2000039AF6F795FD2046FF21049AF6F790FD5B -+:10BB3000204640F21F11059AF6F78AFD204605219E -+:10BB40005A46F6F785FD204625215246F6F780FD38 -+:10BB5000019B20464FF48971DAB2F6F779FD002592 -+:10BB6000104B2046E95A07ABEA5A0235F6F7EEFDCC -+:10BB70001C2DF5D120464FFA88F1FEF7EFFE204646 -+:10BB800040F2A4414A46F6F763FD029B1BB9E36904 -+:10BB9000186934F0EBDD40F2E730EAF3DDF515B07B -+:10BBA000BDE8F08F1A0A020036060200780502008E -+:10BBB000A2060200740C02002DE9F04FBDB007464A -+:10BBC0000C469146002116220DF15E000493E6F327 -+:10BBD00037F2A8490E220DF19E00E6F3CDF1A649F9 -+:10BBE0000E2224A8E6F3C8F148F2670148F2452284 -+:10BBF000ADF8EA10ADF8E820A04908220DF1C60022 -+:10BC0000E6F3BAF19E490E220DF18200E6F3B4F19B -+:10BC10009C4908220DF1BE00E6F3AEF19A490E22CE -+:10BC20001DA8E6F3A9F147F69733002108220DF18C -+:10BC3000B600ADF8E630ADF8E430E6F301F2FB69AA -+:10BC400030219868D7F8A880EBF342F005900028DF -+:10BC500000F0AB8240F2DB613846F6F76BFD40F254 -+:10BC6000DA610B903846F6F765FD88490A900422A0 -+:10BC70003846F6F7A5FDB9F1070F0BD8DFE809F054 -+:10BC800011040A0A0A22352D1DAA069224AB0DF1D1 -+:10BC90005E0214E00DF18202002306921A46079319 -+:10BCA00019E000210A460B4638460091F9F778FD65 -+:10BCB0000DF1820106910DF15E020DF19E03072147 -+:10BCC00007933EE00DF1E6030DF1EA01069308F15A -+:10BCD0008202079101230E9334E039A906913AAB11 -+:10BCE00008F18202012107932BE03BAB00930DF199 -+:10BCF000EF010DF1EE020DF1ED033846F9F74EFCC0 -+:10BD00009DF8EF209DF8EE300DF1BE0143EA0223CD -+:10BD10004FF00002ADF86C30ADF86E209DF8EC30BD -+:10BD20009DF8ED20069143EA0223ADF870304FF004 -+:10BD30000003ADF872300DF1C6030DF15E020793FA -+:10BD400004210E911023009330330193504B0021B6 -+:10BD5000029338460B23F6F7A7FE05224D493846D5 -+:10BD6000F6F72EFD3846F9F7D9F84FF4805213460E -+:10BD7000089040F2A4413846F6F70EFD00213846FF -+:10BD8000FEF79AF940F2DB413846F6F7D3FC424918 -+:10BD9000062209903846F6F713FDB7F8DA3003F4B7 -+:10BDA0007043B3F5005F07BF38463C4938463C490D -+:10BDB0001222F6F705FD40F2D7413846F6F7BAFCF5 -+:10BDC000059911903846FBF7BFFE384640F23B41DB -+:10BDD000F6F7B0FCC0F380100C9020B138460DF19E -+:10BDE000B601F8F7E9FF64B90C9A22B93846B8F8F9 -+:10BDF0003010FEF7B3FD0DF1CE0438462146F8F7BA -+:10BE0000DBFF638822881B0143EA0223A2882146C4 -+:10BE100013439EB2B7F8DA30082203F470430DF1F1 -+:10BE2000D600B3F5805F14BF00250125E6F3A4F02A -+:10BE30000A222BA80021E6F303F11A4B002233F863 -+:10BE40001540104633E0184B53F82530C1180B88C5 -+:10BE50001230B3422AD14B882BA8ADF8D6308A884D -+:10BE6000ADF8D82031F8063F0A22ADF8DA30E6F313 -+:10BE700083F01EE078090200CE0E020022080200C4 -+:10BE800058050200BC0A02005A080200900702008E -+:10BE900019880100D806020024090200FC0C0200E7 -+:10BEA00030090200720C0200F80C02000132A242BA -+:10BEB000C9D138460DF1D601F9F748F9002404221A -+:10BEC00038463749374DF6F77BFC10260A233846AB -+:10BED0002146354A009601940295F6F7E5FD2023A8 -+:10BEE000019338460A2321462F4A00960295F6F719 -+:10BEF000DBFD40F25341384640F2A472F6F726FCCF -+:10BF0000B8F8C81340F6A663A14208BF1946B9F1B4 -+:10BF1000050F01D14B4299B2D7F8FC3F0CB22BB1BF -+:10BF20003846FDF7EFFD0520EAF316F44FF47A7179 -+:10BF300001235822384604FB01F1FDF767FA40F26D -+:10BF4000DA614FF6FF723846F6F700FCB7F8DA30E0 -+:10BF5000384603F47043B3F5005F0CBF98F895952D -+:10BF600098F89695F8F7B4FF0021C0B2FF228B46EF -+:10BF700010900D910F929AE04FF000030799ADF8E1 -+:10BF8000E0303BF80130C3F30324B9F1000F1AD0BD -+:10BF9000042C0BD00F9A042A13D110990EE0C0463E -+:10BFA000A20A020019880100640B0200109901EB3B -+:10BFB0000903D9B211F0800F18BF7F213846FEF770 -+:10BFC00081FAE2B20F92069B3CA93BF8032001EBF9 -+:10BFD000440333F8441C21B102F0FF0343EA012378 -+:10BFE0009AB2384640F25241F6F7B0FBE31E1FFA10 -+:10BFF00083FABAF1010F16D86D4B10254524029330 -+:10C00000384600210DF1E202012300950194F6F774 -+:10C010003DFD684B38460293002138AA0123009564 -+:10C020000194F6F741FD079B384640F251413BF839 -+:10C030000320F6F78BFB3846F9F72EFF00287CD05B -+:10C040005B4A602112AC10250B2301910292002162 -+:10C05000384622460095574EF6F718FD40230193C7 -+:10C0600000210B233846224600950296F6F71CFD68 -+:10C07000BAF1010F0AD845230193384600210DF18A -+:10C08000E202012300950296F6F70EFD484960236F -+:10C090000193029108F18202384600210B2300959A -+:10C0A000F6F7F4FC0D9A0BF1020B01320D920D9B89 -+:10C0B0000E998B427FF460AF602301933C4B08F1F3 -+:10C0C0008206102402933846002132460B23394D54 -+:10C0D0000094F6F7DBFC4FF001025023A8F89820FB -+:10C0E0003846019300213246042300940295F6F766 -+:10C0F000DBFC552301933846002108F18C02022312 -+:10C1000000940295F6F7D0FC3846F8F74FFCA0B142 -+:10C1100038A90DF1DE023846FCF750FB3846FCF733 -+:10C12000EDF9BDF8E0100446BDF8DE203846FDF715 -+:10C1300085FD38462146FDF713FB049B13B93846AD -+:10C14000FDF7E0FC38460599F9F714FB384640F254 -+:10C15000D741119AF6F7FAFAFB69059998683022E7 -+:10C16000EAF3C6F5384640F2DB41099AF6F7EEFAF3 -+:10C1700040F2534138460022F6F7E8FA0C9921B113 -+:10C1800038460DF1B601F8F7E1FF38460899FDF79A -+:10C1900093FF384640F2DA610A9AF6F7D7FA384642 -+:10C1A00040F2DB610B9AF6F7D1FA3DB0BDE8F08FB3 -+:10C1B00015820100198801002DE9F0470546D0F8E5 -+:10C1C000A8404FEA0118F8F783FE40F2D74147B282 -+:10C1D0002846F6F7AFFA94F925258146B2F1FF3FDC -+:10C1E00011D0042392FBF3F3984505DA284640F278 -+:10C1F000D7414022002304E04022284640F2D741A4 -+:10C200001346F6F7C9FAD5F8FC3F53B12846FDF7B7 -+:10C2100079FC0520EAF3A0F21C492846702200238D -+:10C2200002E01A4928467022FDF7F0F82846394600 -+:10C23000FEF794FB002601212846FBF76FFD04233F -+:10C24000C8EB00047A1E94FBF3F3D2187F2AA8BF30 -+:10C250007F2222EAE277284639460434FEF77EFB45 -+:10C26000082C03D90A2E01D00136E4E72846FDF751 -+:10C2700049FC284640F2D7414A46F6F767FA284675 -+:10C28000F8F726FE40B2BDE8F087C04600093D0041 -+:10C290002DE9F04391B08046D0F8A860F8F718FE79 -+:10C2A0001C23B8F8DA208DF83B3001238DF83A30A2 -+:10C2B00002F47043B3F5805F5FFA80F907D1D3B21F -+:10C2C000402B01D81B2300E02D238DF83B30B8F81C -+:10C2D000DA2002F47043B3F5005F33D1B6F82A25B3 -+:10C2E00013B2B3F1FF3F04D04FF6FF73002A08BF2B -+:10C2F0001A46B6F8F6130BB2B3F1FF3F02D14FF472 -+:10C30000917104E04FF6FF73002908BF1946B6F893 -+:10C310002C5596F8F0032BB2B3F1FF3F04D04FF643 -+:10C32000FF73002D08BF1D46B6F8F84323B2B3F1E2 -+:10C33000FF3F04D04FF6FF73002C08BF1C4696F851 -+:10C34000F1739FE0D3B2402B33D8B6F82E2513B249 -+:10C35000B3F1FF3F04D04FF6FF73002A08BF1A461F -+:10C36000B6F8FA130BB2B3F1FF3F02D14FF491715B -+:10C3700004E04FF6FF73002908BF1946B6F83055A0 -+:10C3800096F859052BB2B3F1FF3F04D04FF6FF7377 -+:10C39000002D08BF1D46B6F8004423B2B3F1FF3F9D -+:10C3A00004D04FF6FF73002C08BF1C4696F85B754F -+:10C3B00068E08C2B33D8B6F8322513B2B3F1FF3FC7 -+:10C3C00004D04FF6FF73002A08BF1A46B6F8FC13D4 -+:10C3D0000BB2B3F1FF3F02D14FF4917104E04FF67D -+:10C3E000FF73002908BF1946B6F8345596F8F203D2 -+:10C3F0002BB2B3F1FF3F04D04FF6FF73002D08BFFF -+:10C400001D46B6F8024423B2B3F1FF3F04D04FF605 -+:10C41000FF73002C08BF1C4696F8F37332E0B6F8A1 -+:10C42000362513B2B3F1FF3F04D04FF6FF73002A55 -+:10C4300008BF1A46B6F8FE130BB2B3F1FF3F02D1A4 -+:10C440004FF4917104E04FF6FF73002908BF1946BD -+:10C45000B6F8385596F85A052BB2B3F1FF3F04D021 -+:10C460004FF6FF73002D08BF1D46B6F8044423B2F3 -+:10C47000B3F1FF3F04D04FF6FF73002C08BF1C46FA -+:10C4800096F85C7513B2B3F1FF3F04D040461946ED -+:10C49000FFF792FE0DE009B2B1F1FF3F07D0404631 -+:10C4A0000DF13202FFF728F89DF83B3007E0FF2836 -+:10C4B00002D086F8070404E09DF83B300BB186F803 -+:10C4C000073429B2B1F1FF3F05D04046FFF774FEB3 -+:10C4D00086F8080411E021B2B1F1FF3F09D04046CF -+:10C4E0000DF13202FFF708F89DF83B3086F808346A -+:10C4F00003E0FF2F18BF86F8087496F9EF33B3F105 -+:10C50000FF3F1CBF4FF0FF3386F8083496F808044D -+:10C5100041B2B1F1FF3F76D096F8072453B2994269 -+:10C52000D8BF86F8082496F80834D8BF86F80704E0 -+:10C5300000248DF83B30DB2301250393404623463E -+:10C5400021460DF132020495009401940294059461 -+:10C55000FEF72CFD18230993083308950B93254605 -+:10C5600007AC0FAB4046214607930A95FBF752FEF6 -+:10C5700005F140034046214601350A93FCF74CF98A -+:10C58000402DEDD196F9072496F908349B18022224 -+:10C5900093FBF2F3A6F86835B8F8DA2002F470439A -+:10C5A000B3F5005F02D1B6F85E3583B9D3B2402B44 -+:10C5B00005D8B6F8602512B1A6F8682509E08C2BDD -+:10C5C00002D8B6F8623513B9B6F864350BB1A6F8DF -+:10C5D0006835404640F224514FF400420023F6F7FC -+:10C5E000DBF896F96625B6F86835013293FBF2F36D -+:10C5F0009BB2404640F22551FF22F6F7CDF80223C8 -+:10C6000086F8673529E0012386F86735404640F211 -+:10C610002551FF227E33F6F7BFF8404640F2255100 -+:10C620004FF480720023F6F7B7F8404640F22551E8 -+:10C630004FF400720023F6F7AFF8404640F2255160 -+:10C640004FF480620023F6F7A7F8404640F22551E8 -+:10C650004FF400620023F6F79FF84FF00003A6F8AE -+:10C660006A35404640F2255196F96645F6F762F87C -+:10C670000134C0B204FB00F496F96635A6F86845AB -+:10C6800013B14046FCF72CFD96F8EF330DF1320262 -+:10C69000FF2B08BF96F8073400218DF83B30DB23D1 -+:10C6A00003930123049340460B46009101910291AC -+:10C6B0000591FEF77BFC40464946FEF74FF94046A0 -+:10C6C00040F27161F6F736F8B6F96A3540F27161F9 -+:10C6D000A0EBC30292B24046F6F738F84046FBF7AB -+:10C6E00093FE11B0BDE8F08370B58E46BEF1FF3FFA -+:10C6F0000546144619469DF9106002D006EB0E015E -+:10C700000DE022B990F82916FFF756FD02E0B2F1CC -+:10C71000FF3F04D021462846FFF74EFD81192846E9 -+:10C72000FEF71CF970BDC0462DE9F04F87B00446F6 -+:10C73000F8F7F4FB04A981462046D4F8A850F8F78E -+:10C740003BFB2046F8F7BCFB40F2D741834620462E -+:10C75000F5F7F0FF03902046FCF74AF88246B9F15E -+:10C76000000F02D0FF23029304E02046F8F7B0FB4D -+:10C7700040B20290B4F8DA304FF02A0803F4704364 -+:10C78000B3F5005F0CBF95F81E1595F81F152046F0 -+:10C790004FB239460F223C23CDF80080FFF7A4FFAB -+:10C7A00095F84665002E00F09080204640F2EB415F -+:10C7B000F5F7C0FF1221C0F3402301222046F5F710 -+:10C7C0008DFF6A780021521A18BF01220B462046BD -+:10C7D000FFF7F2F92046FBF791FE40F3072340B242 -+:10C7E000A5F84A35A5F84C0540F2EB412046F5F78F -+:10C7F000A1FFC0F380235B02204640F2EB414FF4DF -+:10C800000072F5F7C9FF002107220B462046FFF70B -+:10C81000D3F92046FBF772FE40F3072340B2A5F898 -+:10C820004E35A5F85005FF222046B5F84A3540F6AA -+:10C830005211F5F7B1FF2046FF22B5F84C3540F60E -+:10C840005311F5F7A9FF2046FF22B5F84A3540F607 -+:10C850005611F5F7A1FF2046FF22B5F84C3540F6FA -+:10C860005711F5F799FF2046FF22B5F84E3540F6EF -+:10C870004811F5F791FFFF222046B5F8503540F6F4 -+:10C880004911F5F789FF95F84A3595F84C1520467A -+:10C8900041EA0321FCF764FF95F8473520469B02E7 -+:10C8A00040F2EB414FF4806203F47C43F5F774FFF0 -+:10C8B00095F8483520465B0240F2EB414FF4007298 -+:10C8C00003F47E43F5F768FF10E0204639460F2257 -+:10C8D0003C23CDF80080FFF707FF6A7820463146F9 -+:10C8E000003A18BF01223346FFF766F92046F8F7F1 -+:10C8F0004BF810B12046FBF715FE00217F220B46B6 -+:10C900002046FCF7DDFC20465146FDF7C7FD2046DA -+:10C910005946F8F7CFFB204604A9F8F717FC204644 -+:10C9200040F2D741039AF5F711FFB9F1000F04D097 -+:10C9300020464946FDF7C0FB03E020460299FEF77A -+:10C940000DF807B0BDE8F08F2DE9F04F89B004462F -+:10C95000D0F8A870F8F7E2FA04902046F8F7B8FA91 -+:10C960004FF489715FFA80FA2046F5F759FE0721E6 -+:10C9700005902046F5F754FEFF2101902046F5F77B -+:10C980004FFE40F21F1102902046F5F749FE40F29B -+:10C99000AB4103902046F5F7CDFED4F8B030D3F884 -+:10C9A000203183F0010313F0010B03D1E36918690F -+:10C9B00033F0F0DE00212046FDF77EFB2046F6F73F -+:10C9C00077FB40F23B412046F5F7B4FE0DF1180924 -+:10C9D000494680462046F8F7EFF920460121F8F74E -+:10C9E0007DFB20467F21FDF7B9FF0122134620463B -+:10C9F0000721F5F773FE102213462046FF21F5F7B5 -+:10CA00006DFE0422134640F21F112046F5F766FE24 -+:10CA10002046FDF74FFC06224B492046F5F7D0FE95 -+:10CA20002046FBF7E5FE002106462046FDF736FDD1 -+:10CA3000002220460121F7F745FA40F2AB4120469B -+:10CA4000F5F778FE40F23E612046F5F773FEC50526 -+:10CA5000ED0D2B46204640F2A64140F2FF12F5F7BD -+:10CA60009BFE97F8E8330BB3204638490922F5F7C7 -+:10CA7000A7FE002220460121F7F724FA40F2AB413D -+:10CA80002046F5F757FE40F23E612046F5F752FE8C -+:10CA9000C30540F29A41204640F2FF12DB0DF5F744 -+:10CAA0007BFE20462A490922F5F78AFE2B462046BE -+:10CAB00040F2A64140F2FF12F5F76EFE00234FF45C -+:10CAC0008052204640F24C41F5F766FE2046314642 -+:10CAD000FDF7E4FC2046C8F38011F8F7FFFA204682 -+:10CAE0004946F8F733FB20465146FDF737FF20460D -+:10CAF0000499FDF7E1FA20464FF48971059AF5F79C -+:10CB0000A7FD019D012205EA020320460721F5F752 -+:10CB1000E5FD029D102205EA02032046FF21F5F7FC -+:10CB2000DDFD039D0422204640F21F1105EA0203A9 -+:10CB3000F5F7D4FDBBF1000F03D1E369186933F0B9 -+:10CB400015DE09B0BDE8F08FD80C0200E205020046 -+:10CB5000E40C02002DE9F3410446F8F7DFF9E3693C -+:10CB6000D4F8A8501A6A04F580531A6094F8DA30A1 -+:10CB7000002685F8BC3241F20403E654D4F8B03004 -+:10CB80008046D3F8203183F0010313F001070AD166 -+:10CB9000E369B821186942F2107233F0C9DDE36924 -+:10CBA000186933F0F7DD20460121F9F7B1FE0F22B5 -+:10CBB00023492046F5F704FE2046F8F775FD204688 -+:10CBC0003146FCF7CDFD204631463246FDF736F8BA -+:10CBD0002046F6F76DFA41F22403E35C6BB1204680 -+:10CBE000FFF7B2FE20463146FDF74EF995F8E833DF -+:10CBF0001BB120460121FDF747F92046FFF794FDC0 -+:10CC000000217F230A46009320460123FDF7C6FF3B -+:10CC10004FF0FF3385F8073485F808342046FFF7D6 -+:10CC200037FB20464146FDF747FA20460021F9F739 -+:10CC30006FFE1FB9E369186933F098DDBDE8FC8128 -+:10CC4000DA070200082910B503D00A2904D0022906 -+:10CC500004D1FFF77FFF01E0FEF794FD10BDC04651 -+:10CC600010B50446F6F724FA20460021FDF724FA11 -+:10CC700020460821FFF7E6FF10BDC04670B541F21F -+:10CC80000403C35C0446D0F8A85013B9F7F70CFFAF -+:10CC9000F0B1D4F8F83013F0070F06D194F8F5305E -+:10CCA0001BB920460921FFF7CDFFD4F8F82012F078 -+:10CCB0000F0F0DD141F20C03E3564BB912F0800F68 -+:10CCC00006D194F8F5301BB920460221FFF7BAFFD0 -+:10CCD000D4F8F83013F00E0F02D12046F9F752F9CC -+:10CCE000D4F8F83013F0060F3ED1D5F8340448B329 -+:10CCF000E169D5F838240B6A9B1A834234D308695A -+:10CD00006A2133F0F7DC400081B2B1B1E369186900 -+:10CD100033F0F0DC88B940F276412046F5F70AFDA1 -+:10CD2000C005C00DA5F86C0540F277412046F5F727 -+:10CD300001FDC005C00DA5F86E0520460021F9F7DC -+:10CD40004BFF11E040F276412046F5F7F3FCC005B9 -+:10CD5000C00DA5F86C0540F277412046F5F7EAFCD6 -+:10CD6000C005C00DA5F86E052046F8F7D7F8B0F558 -+:10CD7000404F0CD02046F8F7ABF8C0B220B10023EA -+:10CD80007F2885F8563402D0002385F8573470BDCB -+:10CD90002DE9F047CCB20746D0F8A8602046894676 -+:10CDA000F5F7DEFE494680463846F5F7BBFE3846C5 -+:10CDB000B7F8DA10FBF758F9042238465B49F5F763 -+:10CDC000FFFC21463846FAF7B5F90A20E9F3C4F426 -+:10CDD0004FF4004213464FF489613846F5F7DCFC06 -+:10CDE0003846F8F78DFB052100224FEA4800F7F797 -+:10CDF000B1FC0022054641464FF42010F7F7AAFC8B -+:10CE000040F257610446AAB23846F5F79FFC38460F -+:10CE10004FF4CB61A2B2F5F799FC4FF4007338469A -+:10CE20004FF489614FF44072F5F7B6FC97F8DA30A9 -+:10CE30000E2B01D11E2206E0B6F8622013B2B3F128 -+:10CE4000FF3F08BF1522A6F840253846002112B240 -+:10CE5000FBF7E2FB20B1384600211422FBF7DCFB94 -+:10CE600097F8DA3038220E2B0CBF182300233846EF -+:10CE700040F2EB41F5F790FCB7F8DA30384603F4AE -+:10CE80007043B3F5005F0CBFB6F86620B6F86820B3 -+:10CE9000012113B2B3F1FF3F08BF0222A6F83E25DD -+:10CEA00012B2FBF7B9FB182238462149F5F788FC86 -+:10CEB0003846F6F70DF996F8BC2298B10E2AB7F865 -+:10CEC000DA3003D9DBB20E2B03D805E0DBB20E2B30 -+:10CED00002D83846012101E0384600214A46FCF7D5 -+:10CEE000A1FF21E097F8DA309A4201D1012A04D15A -+:10CEF00038460821FFF7A6FE02E03846FCF776FF29 -+:10CF000000210A463846FBF753FD3846F9F7B6F9D3 -+:10CF100038460121F9F76AFA41F22403FB5C1BB1A0 -+:10CF200038460321FBF70AF9BDE8F08792050200B5 -+:10CF30002A080200D0F8B03073B5D3F82031044687 -+:10CF400083F0010313F00106D0F8A85003D1C369A0 -+:10CF5000186933F01FDC41F22403E25C42BBB4F8F1 -+:10CF6000DA3003F47043B3F5005F08D14FF00403E7 -+:10CF7000ADF800304FF00C03ADF8023007E04FF091 -+:10CF8000FF03ADF80030ADF802304FF0F00320465B -+:10CF90006946ADF80430ADF80620F8F7D7F820461A -+:10CFA0009621FDF77BFA20460121FEF7BDFC56E0F5 -+:10CFB0002046FFF7C9FC2046FDF756F82046002121 -+:10CFC000FCF762FF204635490F22F5F7F9FB95F88B -+:10CFD000E833DBB120460121FCF756FF95F92435F3 -+:10CFE000204640F2D141FF229BB2F5F7D5FB95F8E0 -+:10CFF0002535204640F2D1414FF47F421B02F5F720 -+:10D00000CBFB204626490C22F5F7DAFB0522204609 -+:10D010002449F5F7D5FBD4F8A8202046D2F84434AB -+:10D02000D2F848243C2BA8BF3C239342B8BF1346F8 -+:10D0300040F2A741FF229BB2F5F7AEFBB4F8DA301D -+:10D04000204603F47043B3F5005F0CBF95F85434E9 -+:10D0500095F855344FF440412B86FDF72DF840F2FA -+:10D0600076412046F5F766FBC005C00DA5F86C05B6 -+:10D0700040F277412046F5F75DFBD5F83434C00522 -+:10D08000C00DA5F86E051BB120460121F9F7A4FDDE -+:10D090001EB9E369186933F069DB7CBD4A0E0200F2 -+:10D0A0002A070200100A02002DE9F041D0F8A8601A -+:10D0B000012386F86130013B86F8C033B0F8DA30DE -+:10D0C000074603F47043B3F5005F02D196F8C1330D -+:10D0D00004E0B3F5805F06D196F8C233022B02D18B -+:10D0E000012386F8C033B7F8DA30384603F47043CA -+:10D0F000B3F5805F0CBF96F8EB3396F8EA33002463 -+:10D1000086F8E933738B0125A6F8BE320422234941 -+:10D11000347086F8C24286F8C34286F8C44286F864 -+:10D120006755F5F74DFB38462946F8F721FA0422F2 -+:10D130001B493846F5F744FB3846FCF7A1FA384658 -+:10D14000FCF7DCFC3846FFF7F5FE86F82C40B7F814 -+:10D15000DA103846F6F784FD3846FBF765F84FF4E9 -+:10D16000804213464FF489613846F5F715FB642079 -+:10D17000E9F3F2F2234638464FF489614FF48042D6 -+:10D18000F5F70AFB38464FF44041FCF795FF41F2B2 -+:10D190008833F38686F89A55BDE8F08122070200AD -+:10D1A000040C020010B58068F2F36AF210BDC046AC -+:10D1B00010B5437902790C4642EA032E0EF00303C0 -+:10D1C000012B0AD0022B0ED013B14FF400702EE0C9 -+:10D1D0000A780523B2FBF3F029E00B78144A03F038 -+:10D1E0000703D05C23E00978E378227911F0800FFF -+:10D1F00043EA022201F07F0343F0006002D040F4D2 -+:10D20000806006E01EF0200F1CBF20F4E06343F4B2 -+:10D21000407012F0800F18BF40F4000012F0400F71 -+:10D2200018BF40F48000C2F3011340EA035010BD60 -+:10D2300050FD010070B585680446D4F8F811A8685F -+:10D24000F2F30CF24FF0FF3384F8E231A36123686C -+:10D2500000229A712B6B064602211869F5F732FC01 -+:10D26000204636F00FDDD6F1010038BF002070BD3A -+:10D2700070B50D460968044671B1D1F87C1129B129 -+:10D28000036840F20C72D868E9F332F52368296824 -+:10D29000D8686269E9F32CF523682946D86810221A -+:10D2A000E9F326F570BDC04637B5054601A9D0F8AB -+:10D2B000000537F00FDF09E02846214638F06AD92B -+:10D2C000636C1BB92846214638F07ADA01A837F09A -+:10D2D00009DF04460028EFD13EBDC046036870B5A3 -+:10D2E00010210546D868E9F3F3F408B9064615E0BD -+:10D2F0002B6806466969D868E9F3EAF404463060A9 -+:10D3000028B931462846FFF7B3FF264606E000233A -+:10D31000C0F87C313146284637F0BCDD304670BD60 -+:10D320002DE9F3470D469246002853D0002951D0ED -+:10D330000B88D0F80490D0F89843D0F89463002B71 -+:10D340004BD00027E780A7804B880A8813F001089C -+:10D3500024D0402A14D1043120463B4600973BF0AC -+:10D36000DBDFB8423BDBB6F8023113F0400F34D0BC -+:10D37000BAF1000F31D0D9F80C003AF06FDF0BE0B2 -+:10D38000A2F108039BB2372B29D804F1080004311D -+:10D39000E4F3F2F52D88A580384622E0202A19D83A -+:10D3A000043104F14800E4F3E7F5A4F804802D8883 -+:10D3B0000123E580C6F8CC30B6F8023113F0400FF7 -+:10D3C0000BD0BAF1000F08D0D9F80C003AF046DFC4 -+:10D3D000404606E06FF0010003E0002001E04FF05E -+:10D3E000FF30BDE8FC87C04610B50DF09DFD04463A -+:10D3F000F1F7AAFF2046E8F3BDF710BDAAAA030083 -+:10D400001958000040960000904C00001472000073 -+:10D41000101800000FAC000050F2000050F20100A4 -+:10D420000050F20200000050F2020100AAAA03001C -+:10D43000195800000000000050F2040000147200AF -+:10D44000000FAC000050F200001018000050F20075 -+:10D45000000FAC0000409600000000000000101813 -+:10D4600000696C306D6163616464723D30303A31E3 -+:10D47000313A32323A33333A34343A353500626F26 -+:10D48000617264747970653D3078666666660062C4 -+:10D490006F6172647265763D3078313000626F6121 -+:10D4A0007264666C6167733D38006161303D3300C2 -+:10D4B00073726F6D7265763D3200AAAA0300195827 -+:10D4C000000050F200000000594D80009557800088 -+:10D4D00049588000315680000D5A8000C1588000A4 -+:10D4E000295A8000455A8000795780004D568000A7 -+:10D4F000755A800025558000F15980000D58800034 -+:10D5000069548000C14E8000E9518000555280006E -+:10D51000C9518000DD58800051518000D1558000F4 -+:10D52000A555800015568000E14F80008955800088 -+:10D53000FD4E800025508000C9110100ED4D800096 -+:10D54000854E8000A94F8000D94D8000094E800093 -+:10D55000514C8000654C800000000000000000007D -+:10D5600000000000C14F800025528000F95180006A -+:10D57000E12800002800000073645F6C6576656C2C -+:10D580005F74726967676572007370695F70755F59 -+:10D59000656E6162006172705F6D61636164647287 -+:10D5A000006172705F72656D6F7465697000000074 -+:10D5B000F83B86000000000007000000FF3B8600EB -+:10D5C00001000000070000000B3C86000200000084 -+:10D5D000000000001B3C8600030000000700000064 -+:10D5E000263C86000400000000000000373C860056 -+:10D5F0000500000008003000413C860006000000E5 -+:10D600000000000095D501000800000006000000A1 -+:10D61000A1D5010009000000070000000000000083 -+:10D62000000000000000000070666E5F737573708C -+:10D63000656E640058408600000000000800140079 -+:10D6400060408600010000000800880068408600F5 -+:10D65000020000000800380070408600030000004F -+:10D66000080008007E408600040000000100000061 -+:10D670008240860005000000000000008B4086000C -+:10D68000060000000800380028D60100070000004E -+:10D690000100000000000000000000000000000089 -+:10D6A000352E39302E3139352E38392E3600776CFB -+:10D6B00025643A2025732025732076657273696F7F -+:10D6C0006E20257320465749442030312D25780A95 -+:10D6D0000041707220323220323031330031343A1E -+:10D6E00035303A3030000000DA4386000000000098 -+:10D6F00008000000E3438600010000000100000074 -+:10D700000000000000000000000000005C782530F0 -+:10D71000325800253034780A007478636861696E85 -+:10D72000007278636861696E00776C635F696F7619 -+:10D730006172733200727373695F6F6666736574CA -+:10D740000064796E74785F7164626D5F6F76657284 -+:10D75000726964650064796E74785F726174655F84 -+:10D76000616C6C00505A443A2025643E2564206F59 -+:10D77000722025643E256420613D25640A006F7493 -+:10D780007077006164640064656C006C6F775F7231 -+:10D790007373695F74726967676572006C6F775F36 -+:10D7A000727373695F6475726174696F6E0074631C -+:10D7B0005F656E61626C650074635F706572696F4E -+:10D7C000640074635F68695F776D0074635F6C6F9A -+:10D7D0005F776D0074635F73746174757300617358 -+:10D7E000736F635F73746174650064796E7478003D -+:10D7F00074785F737461745F63686B0074785F73CF -+:10D800007461745F63686B5F7072640074785F73D7 -+:10D810007461745F63686B5F726174696F007478C0 -+:10D820005F737461745F63686B5F6E756D007278AF -+:10D830005F726174650069735F5750535F656E7204 -+:10D840006F6C6C65650069735F7770735F656E728E -+:10D850006F6C6C65650002000000000035D70100A8 -+:10D8600001000000060000008BD70100020000004C -+:10D87000060000009CD70100030000000600000025 -+:10D88000AED701000400000006000000B8D7010078 -+:10D890000500000006000000C2D7010006000000DD -+:10D8A00006000000CBD701000700000006000000C2 -+:10D8B000D4D701000800000006000000DED70100F8 -+:10D8C0000900000006000000EAD701000A0000007D -+:10D8D00006000000F0D701000B0000000600000069 -+:10D8E000FCD701000C000000060000000CD801006D -+:10D8F0000D000000060000001ED801000E00000010 -+:10D90000060000002ED801000F00000006000000F5 -+:10D9100036D80100100000000100000046D80100C8 -+:10D9200010000000010000000000000000000000E6 -+:10D930000000000005A58100FDA581000000000099 -+:10D94000000000000DCD820089E68200F5CB820048 -+:10D95000EDCC820067898600000080000100000095 -+:10D96000458B860001000000080002004F8B8600F6 -+:10D970001D000000080002005C8B86000F00000004 -+:10D98000030000006A8B8600100080000700000082 -+:10D990007A8B860002000000080007008B8B86004F -+:10D9A00003000000080007009C8B86000400800034 -+:10D9B00001000000AE8B860006000000020000009F -+:10D9C000B98B86000C00000002000000C88B8600A6 -+:10D9D00021008000030000000000000000000000A3 -+:10D9E000000000004CDB01001000000006000000F9 -+:10D9F000529B860001000000010000005D9B860034 -+:10DA000002002000070000006F9B8600030040001A -+:10DA1000080007007C9B860004004000080004000A -+:10DA20008B9B860005004000080004009A9B86003E -+:10DA300006000000080004004FDB01000D0010008C -+:10DA400007000000A79B86000E00200007000000D2 -+:10DA5000B49B86000700100007000000BF9B8600F3 -+:10DA6000080000000800100058DB01000900000059 -+:10DA700006000000C99B860024000000060000008C -+:10DA80005CDB01000A00000006000000AB728600AB -+:10DA90000F00000001000000D59B86000B008000F5 -+:10DAA00001000000DA9B86000C0000000500000069 -+:10DAB000E59B86001D00000003000000FA9B860025 -+:10DAC0001E00000007000000139C86001F000000DD -+:10DAD00007000000259C86002100000005000000D2 -+:10DAE0003B9C86002000000003000000499C86004B -+:10DAF00011008000010000004F9C860018004000CB -+:10DB000008000600539C8600190000000500000074 -+:10DB1000619C86001A000000010000006C9C8600D9 -+:10DB20001B00400001000000000000000000000099 -+:10DB3000000000000050F20201010000013200006C -+:10DB400027A4000041325E0061212F006170006D4A -+:10DB500061786173736F63006273730073736964D8 -+:10DB600000092F160E0E057573696E6720703270EE -+:10DB7000206D6963726F636F64650A00776C25645A -+:10DB80003A205048595458206572726F72282564A3 -+:10DB9000290A000091BA8600000080000100000000 -+:10DBA00030BB860002000000080044003ABB86003B -+:10DBB000030000000800440044BB8600040000008D -+:10DBC000080000004FBB860005000000080044006C -+:10DBD00059BB8600060000000800000067BB8600F5 -+:10DBE0000700000008004C0074BB8600080000001D -+:10DBF00008004C0081BB8600090080000200000084 -+:10DC000000000000000000000000000054545454C4 -+:10DC10005400000000000000000050505050500020 -+:10DC200000000000000000002300000003000000CE -+:10DC300000084C4C4C4C4C4C1414140000010000D7 -+:10DC400064646464646464646464646464000000C0 -+:10DC5000000000000000000000000000013C424203 -+:10DC6000424242424242423C0000000000000000AA -+:10DC700000000000000000000000344A4E4E4E4EEE -+:10DC80004E4E4E4A38000000000000000000000028 -+:10DC9000000000000000004C4C4C4C4C4C4C4C4CD8 -+:10DCA0004C4C4C4C00000040404040404040000084 -+:10DCB00000000001030000000001424242324242E3 -+:10DCC0001414140000000000030000000008444485 -+:10DCD0004438444414141400000000000300000001 -+:10DCE00000013E3E42343E42141414000000000085 -+:10DCF00054545400540000000000000000000000D4 -+:10DD000000000000000000000000000023000000F0 -+:10DD1000030000000001444444384440141414003B -+:10DD200000000000484A4A4A4A4A4A4A4A4A4A4A7D -+:10DD300048000000343434343434343434000000C7 -+:10DD4000004E4E4E4E4E4E4E4E4E4E4E4E4E0000DD -+:10DD50000000000000000000000000000008545413 -+:10DD6000540054000000000000000000505050001B -+:10DD700050000000000000000000233A3E3800423E -+:10DD80000000000000000000000000000000000093 -+:10DD9000000000000000000A000000006400000015 -+:10DDA000000000000000000000005800000000001B -+:10DDB00000000000013242424242424242424232AC -+:10DDC00042420000000000000000000000000000CF -+:10DDD000000836444444444444444444364A4000E1 -+:10DDE0000000000000000000000000000000082EFD -+:10DDF0004444444444444444442E463A0000000011 -+:10DE00000000000000000000000000083C3E3E3E14 -+:10DE10003E3E3E3E3E3E3C3E3E00000000000000D6 -+:10DE2000000000000000000008344444444444441E -+:10DE3000444444384440000000000000000000005A -+:10DE40000000000000085C5C5C5C5C5C5C5C5C5C32 -+:10DE50005C5C5C00005050505050505050500000DE -+:10DE6000000001383E383E42000000000000000083 -+:10DE70000000000000000000000000000000000A98 -+:10DE80000100000000014E4E4E344C381E1E1E0094 -+:10DE90000000000003000000000142444230443012 -+:10DEA00014141400000000000300000000013E3EB6 -+:10DEB0003E3C3E3E1414140000000000030000002D -+:10DEC0000001444444364C3814141400000000008F -+:10DED0000300000000013E3E30363A2C14141400BA -+:10DEE000000000004242424242424242424242421A -+:10DEF000420000002E343434343434343400000012 -+:10DF0000004A4A4A4A4A4A4A4A4A4A4A4A4A00004F -+:10DF1000002E34343434343434340000000054548B -+:10DF20005400540000000000000000004848480071 -+:10DF300048000000000000000000233E3E3E4A0072 -+:10DF40000000000000000000002828284000000019 -+:10DF500000000000000000004644444A00000000A9 -+:10DF600000000000000000000000000000000000B1 -+:10DF7000000000000A545454005400000000000047 -+:10DF80000000004848480048000000000000000071 -+:10DF900000230000030000000000424242424242CF -+:10DFA00014141400000000000300000000003E3EB6 -+:10DFB0003E3E3E3E141414000000000054545454DD -+:10DFC0000000000000000000000050505050000011 -+:10DFD0000000000000000000233844444A4A0000CA -+:10DFE0000000000000000000000000000000000031 -+:10DFF00000000000000A00000000340000000000E3 -+:10E0000000000000000000003400000000000000DC -+:10E01000000000545454545400000000000000005C -+:10E020000048484848480000000000000000002365 -+:10E03000545454545400000000000000000050509C -+:10E04000505050000000000000000000235C5C5CA9 -+:10E050000050000000000000000000504850004444 -+:10E06000000000000000000000234C4C4C4C4C4CC5 -+:10E070004C4C4C4C4C4C4C0000000000000000008C -+:10E0800000000000000009000100000000013E3E09 -+:10E090003E323E361414140000000000010000005F -+:10E0A00000013E3E3E343E381414140000000000CF -+:10E0B0000100000000014242423C423C1E1E1E0084 -+:10E0C000000000000100000000014E4E4E364C38AA -+:10E0D0001E1E1E0000000000545454545400000042 -+:10E0E00000000000000048484848480000000000C8 -+:10E0F0000000000023000000006400000000000099 -+:10E1000000000000000000580000000000000000B7 -+:10E1100000010000030000000000464646484A484F -+:10E120001717170000000000610A86007E0A8600AB -+:10E130009B0A86000F0B8600490B8600660B860043 -+:10E14000630F8600240E8600410E860014108600A0 -+:10E150006B108600311086009C108600D01086005F -+:10E160000411860060118600B1118600830B8600C1 -+:10E17000A00B86000C0F8600F70B8600CE118600E0 -+:10E18000310C86006B0C860094118600DA0B860039 -+:10E190005E0E86004E0C8600290F8600B80A8600A7 -+:10E1A000D50A8600F20A86007B0E86004E10860095 -+:10E1B000BD0B8600980E86009D0F8600B50E86006A -+:10E1C000880C8600D20E8600140C8600290F86006B -+:10E1D000BA0F86002C0B8600440A8600800F86004A -+:10E1E000460F8600EF0E8600B5DD0100D2DD01008E -+:10E1F000EFDD01005DDC010024DD01000CDE01002B -+:10E2000001DF010046DE010097DC01006AE0010049 -+:10E2100040DC01007ADC010041DD010029DE010063 -+:10E22000E4DE010021E3010004E30100383838385E -+:10E2300038000000000000000000343434343400A2 -+:10E240000000000000000000003A3A3A3A460000A0 -+:10E2500000000000000000000000000000000000BE -+:10E26000000000000008384444444A000000000058 -+:10E27000000000000000000000000000000000009E -+:10E2800000002A0000000054000000000000000010 -+:10E290000000000000440000000000000000000139 -+:10E2A00018098600C00D8600E80D8600200D860046 -+:10E2B000AC0D8600DCDC01009CE00100C8E301003D -+:10E2C000A8DF010088E0010094DF0100B4DC010058 -+:10E2D00010DD010094DE0100B0E0010014E1010056 -+:10E2E000A8DE0100FCE3010080DE010078E301000C -+:10E2F00010E40100C4E00100BCDE0100D0DE01003A -+:10E30000C8DC010038444444444444444444384450 -+:10E31000440000002C3838383838303434000000DD -+:10E3200000343A3A3A3A3A3A3A3A3A3A2C2C00001D -+:10E3300000323C3C3C3C3C000000000000003E48F9 -+:10E3400048424600000000000000000000000000FD -+:10E35000000000000000000000000A0038383E42C3 -+:10E3600000000000000000000000000000000000AD -+:10E37000000000000000000A030000000000444408 -+:10E38000444C4C4C17171700000000003232323852 -+:10E39000000000000000000000003838383800009D -+:10E3A0000000000000000000004C0000004C0000D5 -+:10E3B00000000000000000500000005000000000BD -+:10E3C00000000000000100000300000000004242C5 -+:10E3D00042424242171717000000000054545400F4 -+:10E3E000000000000000000000005050500000003D -+:10E3F00000000000000000002300000003000000F7 -+:10E400000001444444344444141414000000000047 -+:10E410000300000000006464646464642424240035 -+:10E42000000100003CE486000000800001000000C4 -+:10E4300084E5860001000000080024008DE58600C8 -+:10E44000020000000100000096E5860003000000C5 -+:10E45000030000009EE586000400000008000000A4 -+:10E46000A7E586000500000008000200B1E586006F -+:10E470000600000008000800BBE586000700000059 -+:10E4800008000600C5E58600080000000800060038 -+:10E49000CCE586000900000008000200D4E58600F3 -+:10E4A0000A00000008000300DCE586000B00000005 -+:10E4B00007000000E9E586000C00000008000600E7 -+:10E4C000EDE401000D00000008000700F7E4010082 -+:10E4D0000E0000000100000000000000000000002D -+:10E4E000000000006368616E7370656300703270D5 -+:10E4F0005F6966757064007032705F646566696537 -+:10E5000000000000C8E686000000000008000C00C3 -+:10E51000D7E686000100000007000400E9E6860057 -+:10E520000200000008000800FBE68600030000006F -+:10E53000070004000BE786000400000008001C0030 -+:10E540001BE786000500000008000C002CE7860091 -+:10E55000060000000700040043E7860007000000F3 -+:10E560000700040094E50100080000000700040013 -+:10E57000A4E501000900000007000400B8E501005F -+:10E580000A000000080090000000000000000000E9 -+:10E5900000000000706B745F66696C7465725F697F -+:10E5A000636D7000706B745F66696C7465725F692F -+:10E5B000636D705F636E740077616B655F7061633C -+:10E5C0006B6574005365742042525054206174206E -+:10E5D00025780A000A465749442030312D25780A0B -+:10E5E000000A54524150202578282578293A207075 -+:10E5F000632025782C206C722025782C20737020C5 -+:10E6000025782C207073722025782C2078707372F6 -+:10E610002025780A00202072302025782C207231A5 -+:10E620002025782C2072322025782C20723320254A -+:10E63000782C2072342025782C2072352025782CD7 -+:10E640002072362025780A00202072372025782C69 -+:10E650002072382025782C2072392025782C2072C1 -+:10E6600031302025782C207231312025782C2072F1 -+:10E6700031322025780A000A20202073702B3020A8 -+:10E6800025303878202530387820253038782025F6 -+:10E690003038780A00202073702B31302025303834 -+:10E6A0007820253038782025303878202530387883 -+:10E6B0000A0073702B257820253038780A006465AD -+:10E6C00061646D616E5F746F007265636C61696D2A -+:10E6D0002073656374696F6E20313A2052657475DA -+:10E6E000726E656420256420627974657320746F8E -+:10E6F0002074686520686561700A007265636C61EA -+:10E70000696D2073656374696F6E20303A205265BD -+:10E710007475726E65642025642062797465732057 -+:10E72000746F2074686520686561700A0072616D9D -+:10E730007374627964697300706125643D30782573 -+:10E74000257800706425643D3078252578006E7644 -+:10E7500072616D5F6F7665727269646500000000BA -+:10E7600086060200D0090000800602003E3E00003E -+:10E77000820602003E020000000702003C0000008A -+:10E780008406020012020000600104000300010080 -+:10E7900064010200C00000006001040003000100E9 -+:10E7A000660102000A00000060010400040001008C -+:10E7B0006401020014000000600104000700010071 -+:10E7C00064010200830100006001040025000100D3 -+:10E7D00064010200F40100006001040096050100DC -+:10E7E000660102002B04000060010400970501008F -+:10E7F000640102000001000060010400D701010073 -+:10E80000640102003C00000060010400DC01010022 -+:10E81000660102003400000060010400E201010012 -+:10E82000640102003000000060010400E701010003 -+:10E83000660102002C00000060010400ED010100EF -+:10E84000640102002C00000060010400F2010100DC -+:10E85000660102002800000060010400F8010100C8 -+:10E86000640102002800000060010400FD010100B5 -+:10E870006601020028000000FFFF00000000000009 -+:10E880006001040005000103640104000000190098 -+:10E89000240104000400000028010400000000001E -+:10E8A0002C01040000000000300104000000000002 -+:10E8B000340104000A04700034010400EFBED400E7 -+:10E8C00034010400050000FF3401040001FF02FFD1 -+:10E8D0003001040018000000340104000A04E000C4 -+:10E8E00034010400EFBE480034010400050000FFBD -+:10E8F0003401040001FF02FF34010400001018017C -+:10E9000034010400020300103401040018F1F2F392 -+:10E9100034010400BBCC0000300104006806000094 -+:10E92000340104001404700034010400EFBE5801E7 -+:10E9300034010400000000FF3401040001FF02FF65 -+:10E94000340104000010180134010400020303091B -+:10E9500034010400BF000010340104000000000076 -+:10E960003001040038000000340104000000000001 -+:10E970003001040088060000340104001404800003 -+:10E9800034010400EFBE1802340104000000030942 -+:10E9900034010400BF00000334010400000102033D -+:10E9A00034010400040500013401040002030405DD -+:10E9B0003401040000000000300104005800000091 -+:10E9C00034010400000000003001040038000000A1 -+:10E9D000340104000F2000073401040000009400FB -+:10E9E000340104000000009034010400747576774F -+:10E9F00034010400000000003401040000000500A0 -+:10EA000034010400FFFFFFFF300104006802000032 -+:10EA1000340104006E84330034010400DCBA500079 -+:10EA200034010400D40000AB34010400BADABADACD -+:10EA300034010400001018F134010400F2F3001056 -+:10EA40003401040018F1F2F3340104001000000056 -+:10EA500034010400000000003401040000000A003A -+:10EA6000340104000100000E340104004252434D01 -+:10EA7000340104005F54455334010400545F535380 -+:10EA800034010400494401043401040082848B965B -+:10EA900034010400030101063401040002000000F7 -+:10EAA0003001040068000000340104000A04280258 -+:10EAB00034010400DCBA8000340104000000FFFFD0 -+:10EAC00034010400FFFFFFFF34010400001018F1BF -+:10EAD00034010400F2F300103401040018F1F2F3E1 -+:10EAE00034010400D0AF0000340104000000000035 -+:10EAF0003401040000000001340104000200000E93 -+:10EB0000340104004252434D340104005F54455324 -+:10EB100034010400545F5353340104004944010498 -+:10EB20003401040082848B96340104000301010641 -+:10EB300034010400020100003001040068040000F8 -+:10EB4000340104000A04280234010400DCBA800005 -+:10EB5000340104000000FFFF34010400FFFFFFFF49 -+:10EB600034010400001018F134010400F2F3001025 -+:10EB70003401040018F1F2F334010400D0AF0000B6 -+:10EB80003401040000000000340104000000000112 -+:10EB9000340104000200000E340104004252434DCF -+:10EBA000340104005F54455334010400545F53534F -+:10EBB00034010400494401043401040082848B962A -+:10EBC00034010400030101063401040002010000C5 -+:10EBD0000001040000000001900402000000000099 -+:10EBE000A0040200F1F30000B0040200EFFD0000F9 -+:10EBF000A8040200FFFF0000A804020000000000BB -+:10EC0000AA04020000000000A4040200CF1A0000C1 -+:10EC1000AC04020000000000BC0402000000000080 -+:10EC2000A6040200D7020000B6040200FFFD0000A7 -+:10EC3000AE040200FFFF0000060402000100000015 -+:10EC400006040200000000000C040200180000008E -+:10EC5000060402000000000048040200000C00004E -+:10EC600002040200A00700000205020000000000EC -+:10EC70000005020000400000020502000400000040 -+:10EC8000000502000040000002050200080000002C -+:10EC90000005020000400000020502000C00000018 -+:10ECA000000502000040000002050200C000000054 -+:10ECB00080050200FFFF000082050200FFFF000048 -+:10ECC00084050200FFFF000086050200FFFF000030 -+:10ECD00088050200FFFF00009C050200F0FF000015 -+:10ECE000400502000080000020050200060F000021 -+:10ECF0004005020000800000400502000081000085 -+:10ED000020050200101D00004005020000810000E7 -+:10ED10004005020000820000200502001E280000BD -+:10ED20004005020000820000400502000083000050 -+:10ED30002005020029310000400502000083000088 -+:10ED4000400502000084000020050200323F000060 -+:10ED5000400502000084000040050200008500001C -+:10ED6000200502004041000040050200008500002F -+:10ED700012060200010000002E060200CDCC0000A9 -+:10ED8000300602000C0000000006020004800000B3 -+:10ED900096060200080000009A060200E400000047 -+:10EDA00088060200000000009C060200020000002D -+:10EDB00088060200001000009C060200020000000D -+:10EDC00088060200002000009C06020002000000ED -+:10EDD00088060200003000009C06020002000000CD -+:10EDE000880602000B0F00009E06020007000000CC -+:10EDF000100502000B00000050040200014E00004C -+:10EE0000520402005B010000E404020090000000D4 -+:10EE100004040200B400000054050200FF3F00009B -+:10EE2000600104000400010364010400000000000C -+:10EE300064010400B40000006401040047004700BE -+:10EE40006401040000006400640104003009400013 -+:10EE5000600104000D0001036401040002000200CF -+:10EE6000640104000100800064010400050000004A -+:10EE70006401040000008000640104006400640078 -+:10EE8000640104000E004700640104000005000056 -+:10EE90006001040015000103640104000000420841 -+:10EEA00064010400E00B0700640104000A00000094 -+:10EEB000600104001A0001036401040000C0660B35 -+:10EEC000600104001D00010364010400102700001C -+:10EED0006401040000007A036001040020000103C3 -+:10EEE00064010400060010276001040023000103F0 -+:10EEF000640104000000F606640104000000AA0A90 -+:10EF00006401040000003200640104000A0E0B09D1 -+:10EF1000640104000E020000640104000000520AB3 -+:10EF20006401040000003F0164010400FFFF000CC5 -+:10EF30006401040032046E06640104000200F20958 -+:10EF4000600104002E000103640104000000008041 -+:10EF50006001040032000103640104000000320B70 -+:10EF60006001040034000103640104000000CC05CA -+:10EF70006001040058000103640104004252434D43 -+:10EF8000640104005F54455364010400545F53530B -+:10EF900064010400494400006001040060000103B2 -+:10EFA0006401040039000000640104005000000006 -+:10EFB00064010400C000000060010400700001034F -+:10EFC00064010400AA03AA0364010400AA03AA03BB -+:10EFD00064010400AA03AA0364010400AA03AA03AB -+:10EFE00064010400EC03D60364010400C003AA0317 -+:10EFF00064010400F703E10364010400CB03B503DB -+:10F0000064010400AA03AA0364010400AA03AA037A -+:10F0100064010400AA03AA0364010400AA03AA036A -+:10F0200064010400EC03D60364010400C003AA03D6 -+:10F0300064010400F703E10364010400CB03B5039A -+:10F0400064010400020402046401040002040204D6 -+:10F05000640104000E0402046401040002041A04A2 -+:10F0600064010400020402046401040002040204B6 -+:10F070006401040002040204640104002604020482 -+:10F080006401040002040204640104000204020496 -+:10F09000640104000E0402046401040002041A0462 -+:10F0A0006401040002040204640104000204020476 -+:10F0B0006401040002040204640104002604020442 -+:10F0C0006401040000001F0064010400FF031F002E -+:10F0D000640104000200000064010400020000005A -+:10F0E00060010400980001036401040000001F0097 -+:10F0F00064010400FF031F0064010400010000001C -+:10F10000640104000100000060010400A00001038C -+:10F110006401040000001F0064010400FF031F00DD -+:10F12000640104000100000064010400010000000B -+:10F1300060010400A80001036401040000001F0036 -+:10F1400064010400FF031F006401040001000000CB -+:10F15000640104000100000060010400B800010324 -+:10F1600064010400E700EC006401040000007B007F -+:10F17000640104007E00000064010400000000003F -+:10F180006401040000004F51640104003F000000CE -+:10F19000640104000000001060010400C0000103CD -+:10F1A0006401040037243724640104003724372421 -+:10F1B0006001040093010103640104000F0040009A -+:10F1C00064010400E60600006001040097010103E9 -+:10F1D000640104001A08000060010400A00101039A -+:10F1E00064010400FFFFFFFF64010400FFFFFFFF55 -+:10F1F00064010400FFFFFFFF64010400FFFFFFFF45 -+:10F2000064010400FFFFFFFF64010400FFFFFFFF34 -+:10F2100064010400FFFFFFFF64010400FFFFFFFF24 -+:10F2200060010400BC01010364010400000005004A -+:10F2300060010400C5010103640104000000100323 -+:10F2400064010400E000FFFF640104000309BF0043 -+:10F25000640104000000030964010400BF00001001 -+:10F26000640104000309BF006401040000030000FE -+:10F2700060010400CD01010364010400FFFFFFFFF2 -+:10F2800064010400FFFFFFFF64010400FFFFFFFFB4 -+:10F2900064010400FFFFFFFF64010400FFFFFFFFA4 -+:10F2A00064010400FFFFFFFF64010400FFFFFFFF94 -+:10F2B00064010400FFFFFFFF640104002000CB0194 -+:10F2C0006401040000005400640104000000AB0865 -+:10F2D00064010400000010046401040084000200C2 -+:10F2E000640104000000140064010400CF01020066 -+:10F2F000640104004400000064010400AF0802003F -+:10F3000064010400100464006401040002020000AF -+:10F31000640104001000CA016401040002003C0002 -+:10F32000640104000000AA08640104000200100443 -+:10F330006401040054000208640104000000080095 -+:10F3400064010400CE0100006401040034000000E8 -+:10F3500064010400AE0800006401040010044400CD -+:10F3600064010400020A0000640104000800C901ED -+:10F370006401040002003000640104000000A908D8 -+:10F380006401040002001004640104003C00021047 -+:10F39000640104000000040064010400CD010000C9 -+:10F3A000640104002C00000064010400AD080000AA -+:10F3B000640104001004340064010400021200001F -+:10F3C000640104000400C8016401040000002C0072 -+:10F3D000640104000000A808640104000000100497 -+:10F3E0006401040030000219640104000000000000 -+:10F3F00064010400CC010200640104002C00000040 -+:10F4000064010400AC080200640104001004300030 -+:10F4100064010400021A000064010400C0000A0430 -+:10F420006401040070000000640104003A010A0451 -+:10F430006401040028022CC064010400F2020A04E2 -+:10F440006401040000000001640104006000140471 -+:10F450006401040038000000640104000201140487 -+:10F460006401040014012CC064010400DE011404D2 -+:10F4700064010400000080006401040022003704DD -+:10F48000640104001500000064010400DF0037047B -+:10F490006401040065002CC0640104002E013704DF -+:10F4A0006401040000002F006401040011006E8458 -+:10F4B000640104000B00000064010400D4006E84A9 -+:10F4C0006401040033002CC064010400FC006E845D -+:10F4D00064010400000018006401040002008A9D19 -+:10F4E00064010400FB00020864010400C54EFA0038 -+:10F4F00064010400020A833464010400FE00021067 -+:10F50000640104006227F900640104000212421A37 -+:10F5100064010400FD00021964010400B113F80045 -+:10F5200064010400021A811164010400FC00021C41 -+:10F5300064010400C10FFC00600104007B030103AF -+:10F540006401040007001400640104001E000000B0 -+:10F55000600104008303010364010400000000F063 -+:10F5600064010400C3301092640104005031802211 -+:10F5700064010400C330000060010400880301033B -+:10F580006401040000001004600104008C03010306 -+:10F590006401040080000000600104008E03010388 -+:10F5A0006401040005000000600104000B04010375 -+:10F5B0006401040000000702600104001404010358 -+:10F5C000640104000100000060010400160401034E -+:10F5D000640104000C0000006001040053050103F5 -+:10F5E00064010400000018006001040055050103D7 -+:10F5F00064010400983A983A64010400A60E64007D -+:10F60000640104000000F40164010400050000002E -+:10F6100064010400A861A8616401040030751E0043 -+:10F62000600104005D0501036401040050C3000093 -+:10F63000600104005F05010364010400000014057B -+:10F640006401040050C3000060010400630501036D -+:10F6500064010400204E00006401040000000F005B -+:10F6600064010400F4010400600104006905010361 -+:10F670006401040000003100640104000000030084 -+:10F68000640104000100070064010400C8AF000029 -+:10F690006401040088130000640104002C17FF00BB -+:10F6A00060010400700501036401040000002C01E6 -+:10F6B000640104000000A00F600104007305010351 -+:10F6C00064010400000003006401040000002C0138 -+:10F6D00064010400C00000006401040088130000FD -+:10F6E000640104006400000064010400DC05401FA4 -+:10F6F000600104007A0501036401040001000100B7 -+:10F700006401040002000000600104007D050103A3 -+:10F710006401040002000000640104000000409C39 -+:10F7200064010400204E000064010400B80B0000D6 -+:10F730006001040082050103640104000000204E02 -+:10F74000640104000000050064010400DC053F00C2 -+:10F7500064010400710200006401040030750000BF -+:10F76000600104008A05010364010400C409A00FBC -+:10F77000600104008D050103640104000A00D00744 -+:10F78000600104008F05010364010400204E204E37 -+:10F79000600104009505010364010400BE0000003F -+:10F7A00060010400B105010364010400E8030000E6 -+:10F7B00060010400ED050103640104000000000085 -+:10F7C00060010400F60501036401040088130000D1 -+:10F7D0006001040003000200640104001F00000037 -+:10F7E000600104000400020064010400FF03000043 -+:10F7F0006001040005000200640104001F00000015 -+:10F80000600104000600020064010400070000001B -+:10F81000600104000700020064010400040000000D -+:10F82000600104000800020064010400FFFF000002 -+:10F8300060010400090002006401040000000000EF -+:10F84000600104000A0002006401040000000000DE -+:10F85000600104000B0002006401040000000000CD -+:10F86000600104000C0002006401040000000000BC -+:10F87000600104000D0002006401040000000000AB -+:10F88000600104000E00020064010400000000009A -+:10F89000600104000F000200640104000000000089 -+:10F8A0006001040010000200640104001F00000059 -+:10F8B0006001040011000200640104000000000067 -+:10F8C0006001040012000200640104000000000056 -+:10F8D0006001040013000200640104000000000045 -+:10F8E0006001040015000200640104000000000033 -+:10F8F0006001040016000200640104000000000022 -+:10F90000FFFF000000000000636275636B5F7377A8 -+:10F910006672657100000000E02E010101500000D8 -+:10F9200000000000C832020101490000899DD80092 -+:10F930004038030101420000AAAAAA00003C0401C9 -+:10F94000013E000000008000483F05010139000031 -+:10F95000D05E4200A0410601013900004992240016 -+:10F96000004B07010132000000000000584D080163 -+:10F9700001300000071F7C00204E0901013000000B -+:10F9800000000000A8610A0101260000666666000A -+:10F9900090650B0101240000C44EEC0030750C0191 -+:10F9A000012000000000000018920D020133000049 -+:10F9B000F93E560000960E020132000000000000E1 -+:10F9C000409C0F02013000000000000080BB1002CC -+:10F9D00001280000000000000000000000000000FE -+:10F9E0000000000009FA0100000000000800080003 -+:10F9F00008FA01000100000008000B0000000000F0 -+:10FA000000000000000000006D6B6565705F616CB8 -+:10FA100069766500746F655F6F6C00746F655F7306 -+:10FA20007461747300746F655F73746174735F6382 -+:10FA30006C65617200AAAA030000000014FA0100BC -+:10FA400000000000070000001BFA01000100000098 -+:10FA500008004C0025FA0100020000000000000030 -+:10FA6000000000000000000000000000D58D8600AE -+:10FA70000C00800001000000A98E86000B00000031 -+:10FA800001000000B58E86000300000005000000A4 -+:10FA9000C18E86000400000007000000D08E8600A2 -+:10FAA00005008000010000000000000000000000D0 -+:10FAB000000000005B574C414E5D636F756E742013 -+:10FAC0003D2025640A000000D550830021578300A3 -+:10FAD0000000000000000000627461006274616D4B -+:10FAE00070006274616D705F666C61677300627450 -+:10FAF000616D705F6368616E006274616D705F312B -+:10FB0000316E5F737570706F7274006274616D70C6 -+:10FB10005F6662006274616D705F73746174656CBE -+:10FB20006F6700414D502D253032782D25303278C9 -+:10FB30002D253032782D253032782D253032782D14 -+:10FB400025303278000000007DC5860000000000EE -+:10FB50000800240084C586000100000008000000A1 -+:10FB600093C586000200000008000C00A4C58600B2 -+:10FB7000030000000800E402AFC586000400000096 -+:10FB800007000000C0C58600050000000800240032 -+:10FB9000C9C586000600000001000000D1C586002E -+:10FBA0000700000007000000DBC586000800000019 -+:10FBB0000100000049C586000900000001000000A6 -+:10FBC000000000000000000000000000776C635F90 -+:10FBD00061757468656E74696361746F725F646F78 -+:10FBE000776E0025733A2063616C6C65640A00705F -+:10FBF000617463685F696F76617273006F747072AD -+:10FC00006177006175746800666162696400616DA6 -+:10FC10007064755F727473005856000243004000B0 -+:10FC2000207986000000004003000000FCFB01007A -+:10FC300007000800080000003D7D860001000880E4 -+:10FC40000800000003FC0100020000400600000064 -+:10FC50004FDB0100030010000700000008FC01005A -+:10FC60000400000005000000647D8600050000001F -+:10FC700008001C000EFC010006000000010000004E -+:10FC80000000000000000000000000004D84FF8321 -+:10FC90004CC4001FB784FF80B184FFDFB0C40808E4 -+:10FCA000FA84F7FFF9C4080001006C090200710929 -+:10FCB0000300760904007B09050080090600850918 -+:10FCC00007008A0908008F09090094090A009909A8 -+:10FCD0000B009E090C00A3090D00A8090E00B40931 -+:10FCE000CC0102000000D400000000000000000170 -+:10FCF0000000000000002D00A7901A0047090E0028 -+:10FD0000012007008B93030038CA01002AE5000098 -+:10FD1000977200004C390000A61C0000530E000032 -+:10FD20002907000095030000CA010000E50000005B -+:10FD300073000000390000001D0000006E840B00FD -+:10FD40000000D400000000000000000100000000DE -+:10FD50006030180C6C482412776C25643A20536389 -+:10FD6000616E20696E2070726F67726573732C20EC -+:10FD7000736B697070696E67207478706F776572E5 -+:10FD800020636F6E74726F6C0A00706F77657220FB -+:10FD900061646A210A002E6661622E0025732E6658 -+:10FDA00061622E25640063636B6277323032677064 -+:10FDB0006F0063636B62773230756C3267706F000F -+:10FDC0006C65676F66646D627732303267706F00A2 -+:10FDD0006C65676F66646D62773230756C32677020 -+:10FDE0006F006D6373627732303267706F006D63DE -+:10FDF0007362773230756C3267706F006D63736257 -+:10FE00007734303267706F006C65676F66646D625F -+:10FE100077323035676C706F006C65676F66646D44 -+:10FE200062773230756C35676C706F006C65676F28 -+:10FE300066646D6277323035676D706F006C656730 -+:10FE40006F66646D62773230756C35676D706F0008 -+:10FE50006C65676F66646D62773230356768706FA6 -+:10FE6000006C65676F66646D62773230756C3567FC -+:10FE700068706F006D63736277323035676C706FD6 -+:10FE8000006D637362773230756C35676C706F002C -+:10FE90006D63736277343035676C706F006D6373B8 -+:10FEA0006277323035676D706F006D6373627732E1 -+:10FEB00030756C35676D706F006D637362773430C9 -+:10FEC00035676D706F006D637362773230356768C8 -+:10FED000706F006D637362773230756C3567687070 -+:10FEE0006F006D637362773430356768706F006DD3 -+:10FEF00063733332706F006C65676F66646D3430A6 -+:10FF0000647570706F00616E7473776974636800F4 -+:10FF1000616135670074737369706F733267006570 -+:10FF2000787470616761696E3267007064657472BD -+:10FF3000616E6765326700747269736F3267006162 -+:10FF40006E74737763746C32670074737369706F67 -+:10FF50007335670065787470616761696E35670035 -+:10FF60007064657472616E67653567007472697379 -+:10FF70006F356700616E74737763746C35670070FA -+:10FF80006132677730613300706132677731613396 -+:10FF9000006D61787032676130006D617870326732 -+:10FFA00061310070613267773061300070613267B3 -+:10FFB0007730613100706132677731613000706194 -+:10FFC00032677731613100706132677732613000BA -+:10FFD0007061326777326131006D61787035676CBE -+:10FFE0006130006D61787035676C6131007061352A -+:10FFF000676C7730613000706135676C77306131E4 -+:020000022000DC -+:1000000000706135676C7731613000706135676C05 -+:100010007731613100706135676C77326130007023 -+:100020006135676C77326131006D61787035676179 -+:1000300030006D61787035676131007061356777C8 -+:100040003061300070613567773061310070613543 -+:1000500067773161300070613567773161310070E9 -+:1000600061356777326130007061356777326131B1 -+:10007000006D6178703567686130006D617870354A -+:100080006768613100706135676877306130007092 -+:100090006135676877306131007061356768773145 -+:1000A00061300070613567687731613100706135AA -+:1000B0006768773261300070613567687732613127 -+:1000C000006D61787035676133006D6178703567F8 -+:1000D0006C61330070613567773061330070613572 -+:1000E000676C773061330070613567773161330059 -+:1000F000706135676C7731613300706135677732D5 -+:10010000613300706135676C773261330062773438 -+:1001100030706F00636464706F0073746263706F3B -+:10012000006277647570706F00747870696432670C -+:100130006130007478706964326761310069747489 -+:100140003267613000697474326761310063636BD8 -+:100150003267706F006F66646D3267706F006D6339 -+:10016000733267706F30006D63733267706F310088 -+:100170006D63733267706F32006D63733267706FD7 -+:1001800033006D63733267706F34006D6373326771 -+:10019000706F35006D63733267706F36006D637317 -+:1001A0003267706F3700747870696435676C6130DE -+:1001B00000747870696435676C6131006F66646DD6 -+:1001C00035676C706F006D637335676C706F3000EE -+:1001D0006D637335676C706F31006D637335676C79 -+:1001E000706F32006D637335676C706F33006D63D1 -+:1001F0007335676C706F34006D637335676C706F47 -+:1002000035006D637335676C706F36006D637335E1 -+:10021000676C706F3700747870696435676130009F -+:100220007478706964356761310069747435676129 -+:10023000300069747435676131006F66646D3567CD -+:10024000706F006D63733567706F30006D63733569 -+:1002500067706F31006D63733567706F32006D6367 -+:10026000733567706F33006D63733567706F34007B -+:100270006D63733567706F35006D63733567706FCD -+:1002800036006D63733567706F370074787069641A -+:10029000356768613000747870696435676861310A -+:1002A000006F66646D356768706F006D63733567E6 -+:1002B00068706F30006D6373356768706F31006D03 -+:1002C0006373356768706F32006D6373356768708C -+:1002D0006F33006D6373356768706F34006D6373DF -+:1002E000356768706F35006D6373356768706F369A -+:1002F000006D6373356768706F3700656C6E6132CF -+:100300006700656C6E6135670074656D706F666659 -+:100310007365740070687963616C5F74656D706497 -+:10032000656C7461000C1218243048606C003CC489 -+:1003300007003BC407004C84FFE0B084F7F7F98462 -+:10034000F7FF000008040200350108300800030030 -+:100350001204020043010000010000001C0402001E -+:1003600048010800030000002C04020049010800B5 -+:1003700003000000390402004A01080003000000E5 -+:10038000470402004E01080003000000520402006E -+:100390003D014000070007005E0402007A010004EE -+:1003A000070000006C0402003F010000060000008E -+:1003B00077040200400100000200000082040200F5 -+:1003C0007C010000020000008F04020042010000D6 -+:1003D000070000009B040200280008000300000042 -+:1003E000AC0402002900000001000000B904020072 -+:1003F0007F0100000200000000000000000000007B -+:1004000000000000706879007478696E737470770A -+:1004100072007068795F6D75746564007068795FEB -+:10042000676C697463687468727368007068795F78 -+:100430006E6F6973655F7570007068795F6E6F6964 -+:1004400073655F64776E007068795F706572636171 -+:100450006C007068795F7278697165737400706898 -+:10046000796E6F6973655F73726F6D006E756D5F26 -+:1004700073747265616D0062616E645F72616E6754 -+:10048000650073756262616E643567766572006DD2 -+:10049000696E5F7478706F776572007068795F6FEE -+:1004A000636C736364656E61626C65007068795F2C -+:1004B0007278616E7473656C007068795F637273D3 -+:1004C0005F7761720000EB04C00100006A04FFFF67 -+:1004D000190036001A013A00250028000500120113 -+:1004E000FF001F010B0013010700FC00FD00FF00CF -+:1004F000C000CA00C5001200570059005C00780017 -+:100500009200980016012C016A000B001B001301D9 -+:100510001D0014012E002A011201F904010001003E -+:10052000FA04010000004C04001800184D0400609B -+:1005300000603809FF01FF013909FF019E003B04FB -+:10054000030003003C0403000000DA46FFFFDBC6A3 -+:100550000300D10604000400977A977A977A977A75 -+:10056000877A877A977B000006000000060000006B -+:1005700006000000060000003809040004003909E4 -+:1005800004000400A404001000104AC444004A44BB -+:1005900080004AC444004A448000A4040040000093 -+:1005A000A40400800080D00420000000A404FF0107 -+:1005B0000000A504FF00FF00A50400700050A50482 -+:1005C000000700000D04FF0040000D0400070004B8 -+:1005D000A204FF004000A20400070004A804FF00DA -+:1005E0000100D70401000100D704400000003706D5 -+:1005F00000C00080810400020002B704007F006C8C -+:10060000B10400200000390900020000380900028E -+:100610000002B00408000800B0040008000839090E -+:10062000000800003809000800081004080008004D -+:10063000DA062000000003050100000003050400A5 -+:100640000000A40400400000A40400800000D004C6 -+:1006500020000000A504FF00FF00A504007000506A -+:10066000A504000700000D04FF0040000D04000772 -+:100670000006A204FF004000A20400070006D904FF -+:1006800070002000D90400070003D9040070001096 -+:10069000DA0400100000DA0400200020A604008024 -+:1006A0000080D70408000800D70400700010D904A7 -+:1006B00004000000D9040800080000000000000049 -+:1006C0000000000000000000FFEEDDCCBB99887741 -+:1006D0006655443322110000DA46FFFF0305080087 -+:1006E000080025642009202564200A004572726FE5 -+:1006F000722067657474696E67206C6F772069710A -+:10070000206573740A004572726F72206765747495 -+:10071000696E672068696768206971206573740A6B -+:1007200000004AC480004A847F00D0040200000018 -+:10073000D204FF000000D20400FF0000D004080033 -+:1007400000004C04000800084D0400200000B00424 -+:1007500000010001B644FFFFB7040F000F004C0476 -+:10076000000800084D0400200020B0040001000132 -+:100770003B04010001003C04010001003C040100B5 -+:1007800000003B04010000004AC444004A448000C9 -+:10079000DAC64000DBC60300DA06200020001004A1 -+:1007A00008000000A60400800080A604FF01FF00EE -+:1007B0009A04FF01FF008007000400048007000284 -+:1007C0000002D60603000000DA06080008004249CD -+:1007D00002003B4900003C49000076068000000012 -+:1007E000DA06010000006C08040000006C084000FC -+:1007F00000006C0800040000D70408000000D804C2 -+:1008000001000000D804020000003B0404000400C2 -+:100810003C04040000003B04040004003C04040009 -+:10082000000084806782568034823B04010001000E -+:100830003C04010001003C04010000003B040100F5 -+:1008400000003B04020002003C04020002003C04E1 -+:10085000020000003B0402000000977A977A977A22 -+:10086000977A877A877A977B0F0900090109060929 -+:10087000070908090209030909090A090B090409FA -+:1008800005090C090D090E09110987466000424649 -+:1008900007003B84EDFF3C04020002004C84D0EFD3 -+:1008A0004D84D7BF4D04040004004D040300010033 -+:1008B000F984F8FFFA84F8FF3B04020002003C04CC -+:1008C000020000003B04100010003C044000000047 -+:1008D0004C04001000104D04004000404D04040082 -+:1008E00000004C04040004004C04080008004D04FF -+:1008F000080000004C04200020004D0420002000CF -+:10090000F90402000200FA0402000000F9040400E5 -+:100910000400FA0404000000F90401000100FA04D4 -+:1009200001000000DB04FF03A602DB0400700020CE -+:100930009A05FF0326009B05FF03A5009C05FF0306 -+:10094000A6009C0500FC00289D05003C001C9D05A0 -+:10095000FF03A800A40400800080A404004000401D -+:10096000A40400200020B004800000003B044000EC -+:100970000000A904008000802184238434838480C3 -+:100980006782568034823B04020002003C0402006D -+:1009900000003B04100010003C04400000004B44E9 -+:1009A000FFFFB10400040000B1040080000038091A -+:1009B00040004000380904000400390940000000EC -+:1009C000390904000400D70402000200D7048000A3 -+:1009D0000000D70401000100D70440004000D70404 -+:1009E00008000800D70400700020DA06400040002C -+:1009F000A40400200000D70408000800D7040070F9 -+:100A0000002031C61500D60603000000DAC68F00AC -+:100A1000100480000000A8440A000305A404D004C8 -+:100A2000D904DA04A60438093909D804D004D70453 -+:100A3000A5040D04A2044C04001000104D04004055 -+:100A400000404C04000800084D04002000003B0456 -+:100A5000020002003C04020000003B04010001000F -+:100A60003C04010000004C04080008004D0408008C -+:100A700008004C04200020004D0420000000F90470 -+:100A800002000200FA0402000200F904040004005B -+:100A9000FA0404000400F90401000100FA04010052 -+:100AA00001005344A90A3D49C000000000000000B5 -+:100AB000000000000000000000000000977A877A24 -+:100AC000877A977B760680008000DA0601000100B5 -+:100AD0006C08040004006C08400040006C0800042E -+:100AE000000410091E091F092409250926092009E7 -+:100AF000210927092809290922092309300931096F -+:100B000032091209D7440000D70401000100D704BC -+:100B100040000000D70401000100D704400040005D -+:100B20001004020000001004010000001004020084 -+:100B30000000100401000100100402000200100473 -+:100B4000010000007A46030073467017744644049F -+:100B500075463F00704681068C4649004AC44400F1 -+:100B60004A448000004001400240034004400540E8 -+:100B700006400740075B0780A3C60100A386FEFF6F -+:100B80000700FF001F013A001A01050082008600DD -+:100B90002E0113017D002800340600FF0000DAC694 -+:100BA00080000AC02802760680000000DA060100F4 -+:100BB00000006C08040000006C08400000006C0895 -+:100BC00000040000D80401000000D8040200000066 -+:100BD000D704080000004C84FFE73B840C005384DA -+:100BE000FF7F53C40080424907003B4917203C491E -+:100BF000C527D60603000100DA0608000000DA0661 -+:100C0000800000000A46A0006A4419000F0900098C -+:100C100001090609070908090209030909090A095E -+:100C20000B09040905090C090D090E091109C9462A -+:100C300000068046FF0081463F01CE460000CB46BD -+:100C40000000CC460000CD4600009D46FF07A446AC -+:100C50000000A5460000D90404000400D9040800DF -+:100C60000000A40400400040A40400400000DAC6D4 -+:100C700040000100D70408000800D70400700030CD -+:100C80004AC444004A4480003B0404000000380980 -+:100C900040000000380904000000D70402000000F2 -+:100CA000D70401000000D70408000000D8040100A8 -+:100CB0000000D8040200000000FC070069A5050040 -+:100CC000FF010000695D0A0000040800975E0A0049 -+:100CD0000102000097A60500D70401000100D70417 -+:100CE00040004000D70401000000D90401000100C9 -+:100CF000D904020000000000AA0A02009A05FF03BE -+:100D000026009B05FF0389009C05FF038A009C05C4 -+:100D100000FC00209D05003C002C9D05FF038C007D -+:100D20003B04010001003C040100000038090008F8 -+:100D30000008390900080008DA0600800080D306A0 -+:100D400000800080D30600800000DA0600800000EA -+:100D50000A80D7FDDA867FFFD7C6010031C60018AA -+:100D60003B4400003C4400004C440000E6440000CA -+:100D7000F9440000B044000038490000B0440000CD -+:100D80004E44000067C503004AC444004A44800042 -+:100D90004804000300010806FF0017000406FF07CF -+:100DA000EA0342490F004249000042490F004A4409 -+:100DB00084004A448000D3462222D34620223B4965 -+:100DC00017203C49C5270305010000000305040066 -+:100DD00000000305100010004249000042490F00C6 -+:100DE000424900003B4917003C49C5074AC444003A -+:100DF0004A448000D70408000000D7040070002097 -+:100E0000380904000400390904000400A404001097 -+:100E10000010D70404000400D704000F00008B4624 -+:100E200000007646A1B816012D012C016A00980039 -+:100E300097002F010B0013011D0014012E002A0141 -+:100E400009001F010700FF000500D0040100000099 -+:100E5000D304FF000000D30400FF0000D004100002 -+:100E60000000D004040000003A0980008000230440 -+:100E7000FF0049003404FF00FCFF1604FF00A4FF3C -+:100E8000160400FF009F240400FF002A230400FF33 -+:100E9000002D2504FF000F000005FF000F000005D6 -+:100EA00000FF000F2004FF000A00340400070001C7 -+:100EB0003204FF00BF00320400FF00B8FF0400FC52 -+:100EC0000018D106040000004B06400040002184B9 -+:100ED0002384348384806782568034824B060100E9 -+:100EE00001004B06080008005F36291F5F36291FE6 -+:100EF0005F36291F5F36291F000000000000000038 -+:100F000000000000000000000000000000000000E1 -+:100F100000000000000000000400000000000000CD -+:100F200004000000080000000100000005000000AF -+:100F3000090000000D0000004D0000008D000000C1 -+:100F40000D0000004D0000008D000000CD000000ED -+:100F50005200000092000000D2000000D600000005 -+:100F600016010000160500001609000056090000D1 -+:100F7000560D000056110000961100009651000019 -+:100F80009691000096D1000096110100000000002B -+:100F90000000000000000000000000000000000051 -+:100FA0000000000004000000000000000400000039 -+:100FB000080000000100000005000000090000001A -+:100FC0000D0000004D0000008D0000000D0000002D -+:100FD0004D0000008D000000CD0000005200000018 -+:100FE00092000000D2000000D600000016010000B0 -+:100FF000160500001609000056090000560D0000F5 -+:1010000056110000565100005691000056D10000C4 -+:1010100056110100565101005691010056D10100B0 -+:1010200000000000000000000000000000000000C0 -+:1010300000000000000000000000000000000000B0 -+:1010400000000000000000000000000000000000A0 -+:101050000000000000000000000000000000000090 -+:101060000000000000000000000000000000000080 -+:1010700000000000000000000A0009000600050052 -+:101080000A000900060005000A0009000600050024 -+:101090000A000900060005000A0009000600050014 -+:1010A0000A000900060005000A0009000600050004 -+:1010B0000A000900060005000A00090006000500F4 -+:1010C0000A000900060005000A00090006000500E4 -+:1010D0000A000900060005000A00090006000500D4 -+:1010E0000A000900060005000A00090006000500C4 -+:1010F0000A000900060005000E00000000020003BF -+:10110000000400060008000B00100110021003107C -+:10111000041005100610071007170720072D0740B9 -+:1011200000000000000000000000000000000000BF -+:1011300000000000000000000000000000020003AA -+:10114000000400060008000B00100110021003103C -+:10115000041005100610071007170720072D074079 -+:10116000000000000000000000000000000000007F -+:10117000000000000000000000000000000000006F -+:10118000000000000000000000000000000000005F -+:10119000000000000000000000000000000000004F -+:1011A00000000000000000000000004000000000FF -+:1011B000000000000000000000000000000000002F -+:1011C000000000000000000000000000000000001F -+:1011D000000000000000000000000000000000000F -+:1011E00000000000000000000000000000000000FF -+:1011F00000000000000000000000000000000000EF -+:1012000000000000000000000000000000000000DE -+:1012100000000000000000000000000000000000CE -+:1012200000000000000000000000000000000000BE -+:1012300000000000000000000000000000000000AE -+:10124000000000000000000000000000000000009E -+:1012500000000000F8410100F8210000FB2100001F -+:10126000FB410000DBFE01007B2100003321000078 -+:10127000EB400000A3FE01004B0200004D014D01B8 -+:101280004D014D014D014D014D014D014D014D01EE -+:101290004D014D014D014D014D014D014D014D01DE -+:1012A0004D014D014D014D014D014D014D014D01CE -+:1012B0004D014D014D014D014D014D014D014D01BE -+:1012C0004D014D014D014D014D014D014D014D01AE -+:1012D0004D014D014D014D014D014D014D014D019E -+:1012E0004D014D014D014D014D014D014D014D018E -+:1012F0004D014D014D014D014D014D01090F1418D6 -+:10130000FE070B0FFBFE0105080B0E111417000062 -+:1013100000000000000306090C0F1200000000008E -+:1013200000000000000306090C0F1215181B000036 -+:101330000000000003EB000001001000100020007E -+:101340000100300010004000220050002201600027 -+:101350002202700022038000220490002205A000D7 -+:101360002206B0002207C0002208D0002209F000A7 -+:10137000220A1000220B2000220C3000220D400017 -+:10138000220E5000220F600000000000000000004C -+:10139000000000000000000000000000000000004D -+:1013A0000000000000000000040000000000000039 -+:1013B000040000000800000001000000050000001B -+:1013C000090000000D0000004D0000008D0000002D -+:1013D0000D0000004D0000008D000000CD00000059 -+:1013E0004F0000008F000000CF000000D30000007D -+:1013F0001301000013050000130900005309000049 -+:10140000530D000053110000931100009351000090 -+:101410009391000093D1000093110100000000009F -+:1014200000000000000000000000000000000000BC -+:1014300000000000040000000000000004000000A4 -+:101440000800000001000000050000000900000085 -+:101450000D0000004D0000008D0000000D00000098 -+:101460004D0000008D000000CD0000004F00000086 -+:101470008F000000CF000000D30000001301000027 -+:10148000130500001309000053090000530D00006C -+:1014900053110000535100005391000053D100003C -+:1014A00053110100535101005391010053D1010028 -+:1014B000000000000000000000000000000000002C -+:1014C000000000000000000000000000000000001C -+:1014D000000000000000000000000000000000000C -+:1014E00000000000000000000000000000000000FC -+:1014F00000000000000000000000000000000000EC -+:1015000000000000000000000104020403040404C1 -+:10151000050406040704080409040A048B058C0565 -+:101520008D058E058F059000910092009301940126 -+:10153000950196019701980199019A019B019C01DF -+:101540009D019E019F01A001A101A201A301A4018F -+:10155000A5010000010101010101010101010101D9 -+:10156000010101010101010101010101010101016B -+:101570000101020301030201010101010101010155 -+:10158000010101010101010101010101010101014B -+:10159000010101010101010101010101010101013B -+:1015A000010101010101010101010101010101012B -+:1015B0000101020301030201010101010101010115 -+:1015C000010101010101010101010101010101010B -+:1015D000010101017C120200400000000200000035 -+:1015E0000000000010000000D411020040000000C4 -+:1015F0000100000000000000100000005412020072 -+:101600000A0000000B0000000000000020000000A5 -+:1016100038130200140000000C000000000000005D -+:1016200020000000A41A0200940000000D00000039 -+:101630000000000020000000081502002600000045 -+:101640000E000000000000001000000078100200F2 -+:10165000400000000F00000000000000100000002B -+:10166000081D020010000000100000000000000033 -+:1016700008000000FC1202003C0000001100000005 -+:101680000000000008000000881302006000000055 -+:1016900012000000000000002000000054150200AD -+:1016A000800000001400000000000000080000009E -+:1016B000EC1602009A000000170000000000000075 -+:1016C00010000000FC1002006C0000000000000090 -+:1016D000000000001000000020180200A000000020 -+:1016E0001800000000000000200000001A00340074 -+:1016F0004E0068009C00D000EA000401340068003D -+:101700009C00D0003801A001D40108024E009C00CA -+:10171000EA003801D4017002BE020C036800D00058 -+:101720003801A00170024003A803100418009C00B7 -+:10173000D0000401EA0038018601D0000401040150 -+:1017400038016C016C01A001380186018601D401C9 -+:10175000220222027002040138016C0138016C017E -+:10176000A001D401A001D401080208023C028601B4 -+:10177000D4012202D40122027002BE027002BE0213 -+:101780000C030C035A0336006C00A200D80044017D -+:10179000B001E6011C026C00D8004401B0018802CF -+:1017A0006003CC033804A2004401E6018802CC03A4 -+:1017B0001005B2055406D800B00188026003100578 -+:1017C000C0069807700818004401B0011C02E60129 -+:1017D00088022A03B0011C021C028802F402F402EF -+:1017E000600388022A032A03CC036E046E041005EA -+:1017F0001C028802F4028802F4026003CC03600336 -+:10180000CC0338043804A4042A03CC036E04CC03AC -+:101810006E041005B2051005B20554065406F6060E -+:101820000000080000000800000008000000080098 -+:101830000000080000000800000008000000080088 -+:101840000000080000000800000008000000080078 -+:101850000000080000000800000008000000080068 -+:101860000000080000000800000008000000080058 -+:101870000000080000000800000008000000080048 -+:101880000000080000000800000008000000080038 -+:101890000000080000000800000008000000080028 -+:1018A0000000080000000800000008000000080018 -+:1018B0000000080000000800000008000000080008 -+:1018C00000000800000008000000080000000800F8 -+:1018D00000000800000008000000080000000800E8 -+:1018E00000000800000008000000080000000800D8 -+:1018F00000000800000008000000080000000800C8 -+:1019000000000800000008000000080000000800B7 -+:1019100000000800000008000000080000000800A7 -+:101920000000080000000800000008000000080097 -+:101930000000080000000800000008000000080087 -+:101940000000080000000800000008000000080077 -+:101950000000080000000800000008000000080067 -+:101960000000080000000800000008000000080057 -+:101970000000080000000800000008000000080047 -+:101980000000080000000800000008000000080037 -+:101990000000080000000800000008000000080027 -+:1019A0000000080000000800000008000000080017 -+:1019B0000000080000000800000008000000080007 -+:1019C00000000800000008000000080000000800F7 -+:1019D00000000800000008000000080000000800E7 -+:1019E00000000800000008000000080000000800D7 -+:1019F00000000800000008000000080000000800C7 -+:101A000000000800000008000000080000000800B6 -+:101A100000000800000008000000080000000800A6 -+:101A20000000080000000800000008000000080096 -+:101A30000000080000000800000008000000080086 -+:101A40000000080000000800000008000000080076 -+:101A50000000080000000800000008000000080066 -+:101A60000000080000000800000008000000080056 -+:101A70000000080000000800000008000000080046 -+:101A80000000080000000800000008000000080036 -+:101A90000000080000000800000008000000080026 -+:101AA0000500000000000000000000000000001021 -+:101AB00000000000000000200000000000000030D6 -+:101AC0000000000000000040000000000000005086 -+:101AD0000000000000000060000000000000007036 -+:101AE00000000000000000800000000000000090E6 -+:101AF00008000000000000A008000000000000B086 -+:101B000008000000000000C008000000000000D035 -+:101B100008000000000000E008000000000000F0E5 -+:101B20000800000000000000090000000000001094 -+:101B30000900000000000020190000000000003033 -+:101B400019000000000000401900000000000050D3 -+:101B50001900000000000060190000000000007083 -+:101B60001900000000000080190000000000009033 -+:101B700019000000000000A019000000000000B0E3 -+:101B800019000000000000C019000000000000D093 -+:101B900019000000000000E019000000000000F043 -+:101BA00019000000000000001A00000000000010F2 -+:101BB0001A000000000000201A00000000000030A1 -+:101BC0001A000000000000401A0000000000005051 -+:101BD0000200000000000060020000000000007031 -+:101BE00002000000000000800200000000000090E1 -+:101BF00002000000000000A002000000000000B091 -+:101C000002000000000000C00A000000000000D038 -+:101C10000A000000000000E00A000000000000F0E0 -+:101C20000A000000000000000B000000000000108F -+:101C30000B000000000000200B000000000000303E -+:101C40000B000000000000400B00000000000050EE -+:101C50001B000000000000601B000000000000707E -+:101C60001B000000000000801B000000000000902E -+:101C70001B000000000000A01B000000000000B0DE -+:101C80001B000000000000C01B000000000000D08E -+:101C90001B000000000000E01B000000000000F03E -+:101CA0001B000000000000001C00000000000010ED -+:101CB0001C000000000000201C000000000000309C -+:101CC0001C000000000000401C000000000000504C -+:101CD0001C000000000000601C00000000000070FC -+:101CE0001C000000000000801C00000000000090AC -+:101CF0001C000000F80E020060000000120000004E -+:101D000000000000200000005F36291F5F36291FF9 -+:101D10005F36291F5F36291FE80E02001000000001 -+:101D200010000000000000000800000090E886009D -+:101D30000000800001000000000000000000000022 -+:101D4000000000007363616E0000000044EB860039 -+:101D50000100204005000000A2A5860002002040EE -+:101D60000500000090A5860003002040050000004B -+:101D70007EA58600040020400500000075998600BD -+:101D80000500104005000000EBE88600060020403A -+:101D9000020000004CEB86000C0000000100000077 -+:101DA0005EEB860007002000080000000000000035 -+:101DB00000000000000000006E6F63726300534477 -+:101DC000494F0043444300000D1680008D138000EE -+:101DD00025118000291480001D138000A1168000A9 -+:101DE000A90F0100011380002D13800000000000E6 -+:101DF0001D168000E9270000776C0000000000003D -+:101E00000000000000000000F025000000000000BD -+:101E100000000000000000000000000000000000C2 -+:101E20000000000005000000FFFFFFFF140000009D -+:101E30000100050605000000FFFFFFFF0500000090 -+:101E400005000000050000000E0E0E0E0E02090D2A -+:101E50000A080D01090D0A080D01090D0A080D01F6 -+:101E6000090D0A080D01090E0A090E060A0E0B09D2 -+:101E70000E02093A160E0E05093A160E0E050A0E46 -+:101E80000B090E050A0E0B090E020A0E0B090E02B3 -+:101E900014C0C015110514C0C015110514C0C0151B -+:101EA000110514C0C015110514C0C0151105093A5B -+:101EB000160E0E0514C0C015110514C0C01511056D -+:101EC000093A160E0E05093A160E0E05093A160EB7 -+:101ED0000E0514C0C0151105093A160E0E05093A73 -+:101EE000160E0E05093A160E0E0509B21C0E0E0549 -+:101EF00012B11911110800000000000000000000DC -+:101F00000000000065660200416602002D660200C6 -+:101F100055AA80000000000021AA800085AA800048 -+:101F200031AA80006DAA8000C993800095A9800025 -+:101F3000BDA98000D5938000B59380007593800083 -+:101F4000D191800000000000B1A98000736470632B -+:101F50006D6465760000000000000000041F0200B0 -+:101F60000000000000000000000000000000000071 -+:101F70000000000000000000000000000000000061 -+:101F80000000000000000000000000000000000051 -+:101F90000000000000000000000000000000000041 -+:101FA0000000000000000000000000000000000031 -+:101FB0000000000000000000000000000000000021 -+:101FC0000000000000000000000000000000000011 -+:101FD0000000000000000000000000000000000001 -+:101FE00000000000000000000000000000000000F1 -+:101FF00000000000000000000000000000000000E1 -+:1020000000000000000000000000000000000000D0 -+:1020100000000000000000000000000000000000C0 -+:1020200000000000000000000000000000000000B0 -+:1020300000000000000000000000000000000000A0 -+:102040000000000000000000000000000000000090 -+:102050000000000000000000000000000000000080 -+:102060000000000000000000000000000000000070 -+:10207000000000000000000004E301004100000037 -+:10208000440000000000000000000000000000000C -+:102090000000000000000000000000000000000040 -+:1020A0000000000000000000000000000000000030 -+:1020B0000000000000000000000000000000000020 -+:1020C0000000000000000000000000000000000010 -+:1020D0000000000000000000000000000000000000 -+:1020E00000000000000000000000000000000000F0 -+:1020F00000000000000000000000000000000000E0 -+:1021000000000000000000000000000000000000CF -+:1021100000000000000000000000000000000000BF -+:1021200000000000000000000000000000000000AF -+:10213000000000000000000000000000000000009F -+:10214000000000000000000000000000000000008F -+:10215000000000000000000000000000000000007F -+:10216000000000000000000000000000000000006F -+:10217000000000000000000000000000000000005F -+:10218000000000000000000000000000000000004F -+:10219000C8DC0100010000000100F918010DE40095 -+:1021A000F4DEF106FC0F27FAFF1DF01018090AF201 -+:1021B00010E01714041114F1FAF2DBF7FCE2FBE172 -+:1021C000EE130DFF1CE91A17180300DAE803E617EF -+:1021D000E4E9F3FF121305E104E225F706F2ECF15E -+:1021E000FC11E914F0E0F6F2E8091010011DD9FA2B -+:1021F000040F0F060CDE1C00FF0D07181AF60EE484 -+:10220000160FF905EC181B0A1EFF0026E2FFE50A6F -+:1022100014180705EA0FF2E4E6F6080808080808AB -+:1022200008090A0808070701020202020202020264 -+:102230000202020202020202020201010000000088 -+:1022400000000000C5011DFFE0FFC0FFE0FF00002F -+:10225000000000FF000000006B0382FEE7FFCCFFE0 -+:10226000E7FF080002000000D7010BFFEEFFDCFFD4 -+:10227000EEFFA7033CFEECFF1700ECFF720385FEA8 -+:10228000AEFEF801AEFE070004000000980160FFFA -+:10229000CBFF96FFCBFF9C0345FE2500C1FF250029 -+:1022A000B10316FEE4FEA501E4FE070014000100E0 -+:1022B000BF0131FFF20049FEF200870361FE33FFE8 -+:1022C000620133FF800378FEDAFEE900DAFE0800DF -+:1022D00015000100BF0131FF18010EFE1801870330 -+:1022E00061FE16FF7C0116FF800378FE8FFF9300CE -+:1022F0008FFF090016000100BF0131FF620055FF8A -+:102300006200870361FE1FFF6B011FFF79037EFEE2 -+:10231000F4FE5D00F4FE080017000100BC0131FF6F -+:10232000740042FF7400870361FE52FF020152FFF6 -+:10233000800378FE7FFFF1FF7FFF08001800010097 -+:10234000B40131FFDFFF1D00DFFF880361FE87FF5F -+:1023500090FF87FF7F0378FECDFEF401CDFE0800DD -+:1023600019000100AD0131FFB8FF3E00B8FF820344 -+:1023700061FEAAFFB1FFAAFF7F0378FEC7FEFE0140 -+:10238000C7FE08001A000100930154FFD9FF0C009A -+:10239000D9FF1B03C7FE4CFF38004CFF3303B8FEC8 -+:1023A00080FF280080FF08001B000100890154FF06 -+:1023B000CFFF1300CFFF1703C7FE00FF500000FF41 -+:1023C0002E03BDFE8BFF25008BFF08001E000100C1 -+:1023D000BB0119FFC3FF1D00C3FF6B0361FE66FF56 -+:1023E000480066FF7C0378FE56FF4F0056FF08004A -+:1023F0002C000100BF0131FFE00071FEE000870307 -+:1024000061FE8BFFC4008BFF800378FEB2FEC0002C -+:10241000B2FE0800010000006C0900000B0A000772 -+:102420000A88888002000000710900000B0A00077A -+:102430000A88888003000000760900000B0A000764 -+:102440000A888880040000007B0900000B0A00074E -+:102450000A88888005000000800900000B0A000738 -+:102460000A88888006000000850900000B0A000722 -+:102470000A888880070000008A0900000B0A00070C -+:102480000A888880080000008F0900000B0A0007F6 -+:102490000A88888009000000940900000B0A0007E0 -+:1024A0000A8888800A000000990900000B0A0007CA -+:1024B0000A8888800B0000009E0900000B0A0007B4 -+:1024C0000A8888800C000000A30900000B0A00079E -+:1024D0000A8888800D000000A80900000B0A000788 -+:1024E0000A8888800E000000B40900000B0A00076B -+:1024F0000A888880000001009F0152074000800088 -+:102500004000180378064000800040000A032E06B1 -+:1025100040008000400008000100010092013707E0 -+:1025200003013B0003019F02020744003600440000 -+:10253000600247075D00A7005D000800020001007F -+:102540009F01520740008000400018037806C00039 -+:102550008001C0000A032E064000800040000800F1 -+:10256000030001002E013107810002018100920267 -+:10257000B806CD009A01CD00F202E006AA0054018F -+:10258000AA0008001400010068015CFFF200C6FE0A -+:10259000F200F002B8FE33FFCB0033FFFF02E0FE93 -+:1025A00003FF49FF03FF08001500010068015CFFFD -+:1025B000950052FF9500F002B8FE33FFA40033FFF0 -+:1025C000FF02E0FE00FFEFFE00FF08001600010022 -+:1025D00068015CFF62009CFF6200F002B8FE33FFFE -+:1025E0007C0033FFFF02E0FE00FFA0FE00FF0800BA -+:1025F000170001005E015CFF8CFF52008CFFF002AF -+:10260000B8FE33FF280033FFFF02E0FE7FFF15FF17 -+:102610007FFF08001800010045015CFFE0FFD8FFC4 -+:10262000E0FFF402B8FE00FF29FE00FFFE02E0FE1C -+:10263000FAFEAA00FAFE0800190001002B015CFF57 -+:10264000CDFFC0FFCDFFE002B8FE00FF29FE00FF76 -+:10265000FD02E0FEFAFEAA00FAFE08001A000100E0 -+:10266000150197FFD9FF8BFFA8FF7D022EFFC0FF4A -+:1026700040FF70FF660248FF80FF80FEE0FE08001A -+:102680001B000100F50097FFCFFF6DFF92FF720264 -+:102690002EFF5EFF1BFE95FE650248FFC2FF46FF50 -+:1026A00075FF08001E0001002E0131FFC3FF86FFE9 -+:1026B000C3FF9202B8FE33FF66FE33FFF202E0FE74 -+:1026C00056FFACFE56FF08002800010068015CFFC1 -+:1026D000F200C6FEF200F002B8FECD0035FFCD00DC -+:1026E000FF02E0FEFF017201FF0108000501000882 -+:1026F0000001FFFF0000000000000000A200000039 -+:1027000000FF00FF00000000000000FF00000000CC -+:102710007802A0FE80FF00FF80FF0800010000009B -+:10272000760179FFF0FFE0FFF0FF1F0374FECEFF9C -+:10273000E0FFCEFFEE022BFE2CFF32002CFF080044 -+:1027400002000000770116FFDBFFB4FFDBFF1F0371 -+:1027500074FEE0FFECFFE0FFEC02F2FE80FF1E00E3 -+:1027600080FF080003000000770116FFDBFFB4FFC5 -+:10277000DBFF1F0374FEE0FFECFFE0FFEC02F2FE64 -+:102780006CFF23006CFF0800040000003301AEFF63 -+:10279000CBFF96FFCBFF0B0385FECBFF0A00CBFFE1 -+:1027A000FD022BFE2CFFCA002CFF080000000000D9 -+:1027B0000000000000000000000000000000000019 -+:1027C0000000000000000000000000000000000009 -+:1027D00000000000000000000000000000000000F9 -+:1027E00000000000000000000000000000000000E9 -+:1027F00000000000000000000000000000000000D9 -+:1028000000000000000000000000000000000000C8 -+:1028100000000000000000000000000000000000B8 -+:1028200000000000000000000000000000000000A8 -+:102830000000000000000000000000000000000098 -+:102840000000000000000000000000000000000088 -+:102850000000000000000000000000000000000078 -+:102860000000000000000000000000000000000068 -+:102870000000000000000000000000000000000058 -+:102880000000000000000000000000000000000048 -+:102890000000000000000000000000000000000038 -+:1028A0000000000000000000000000000000000028 -+:1028B0000000000000000000000000000000000018 -+:1028C0000000000000000000000000000000000008 -+:1028D00000000000000000000000000000000000F8 -+:1028E00000000000000000000000000000000000E8 -+:1028F00000000000000000000000000000000000D8 -+:1029000000000000000000000000000000000000C7 -+:1029100000000000000000000000000000000000B7 -+:1029200000000000000000000000000000000000A7 -+:102930000000000000000000000000000000000097 -+:102940000000000000000000000000000000000087 -+:102950000000000000000000000000000000000077 -+:102960000000000000000000000000000000000067 -+:102970000000000000000000000000000000000057 -+:102980000000000000000000000000000000000047 -+:102990000000000000000000000000000000000037 -+:1029A0000000000000000000000000000000000027 -+:1029B0000000000000000000000000000000000017 -+:1029C0000000000000000000000000000000000007 -+:1029D00000000000000000000000000000000000F7 -+:1029E00000000000000000000000000000000000E7 -+:1029F00000000000000000000000000000000000D7 -+:102A000000000000000000000000000000000000C6 -+:102A100000000000000000000000000000000000B6 -+:102A200000000000000000000000000000000000A6 -+:102A30000000000000000000000000000000000096 -+:102A40000000000000000000000000000000000086 -+:102A50000000000000000000000000000000000076 -+:102A60000000000000000000000000000000000066 -+:102A70000000000000000000000000000000000056 -+:102A80000000000000000000000000000000000046 -+:102A90000000000000000000000000000000000036 -+:102AA0000000000000000000000000000000000026 -+:102AB0000000000000000000000000000000000016 -+:102AC0000000000000000000000000000000000006 -+:102AD00000000000000000000000000000000000F6 -+:102AE00000000000000000000000000000000000E6 -+:102AF00000000000000000000000000000000000D6 -+:102B000000000000000000000000000000000000C5 -+:102B100000000000000000000000000000000000B5 -+:102B200000000000000000000000000000000000A5 -+:102B30000000000000000000000000000000000095 -+:102B40000000000000000000000000000000000085 -+:102B50000000000000000000000000000000000075 -+:102B60000000000000000000000000000000000065 -+:102B70000000000000000000000000000000000055 -+:102B80000000000000000000000000000000000045 -+:102B90000000000000000000000000000000000035 -+:102BA0000000000000000000000000000000000025 -+:102BB0000000000000000000000000000000000015 -+:102BC0000000000000000000000000000000000005 -+:102BD00000000000000000000000000000000000F5 -+:102BE00000000000000000000000000000000000E5 -+:102BF00000000000000000000000000000000000D5 -+:102C000000000000000000000000000000000000C4 -+:102C1000000000000000000083682DE9F0415B69BE -+:102C20000546152B0F460AD0182B08D01B2B06D0B3 -+:102C3000242B01D0272B04D12B8A7F2B05D80C23E2 -+:102C400004E0172B01D0182B01DD1423AB624FF0E9 -+:102C500004430022BB6100E00132BB69002B03DAB0 -+:102C60001D4B9A42F8D134E01C4B9A4231D8AE6ADF -+:102C70003C69331DAB83AC61A868298ADEF346F357 -+:102C8000022390FBF3F014F4807F68840AD0284676 -+:102C900039463246DEF352F3C0F30F1083B2E883B5 -+:102CA0002B8403E0AB8B2B846B8CEB83AB6913F42D -+:102CB000007F0AD0AA6A284639460132DEF33EF385 -+:102CC000C0F30F1083B2688400E02B8CAB842B8A96 -+:102CD000EB84BDE8F081C046809698007F9698000E -+:102CE00070B50446DEF33CF1002144220546DFF3D3 -+:102CF000A7F16369152B2B6001D0162B01D9104B5E -+:102D00006B60686808B9054617E0AC602046E8F3D8 -+:102D1000F1F1E8602046E8F3B5F1064618B920461F -+:102D20000121E8F3EDF16B6820469B689847054662 -+:102D30001EB920463146E8F3E3F1284670BDC0468F -+:102D4000C81D02002DE9F0470546884691469A467F -+:102D5000E8F398F1074618B928460121E8F3D0F1C5 -+:102D60002846E8F38FF1D0B12846E8F381F1B0B9F5 -+:102D70002846FFF7B5FF064610B94FF0FF3410E0C4 -+:102D80002846ECF763FD736830465C6941464A4665 -+:102D90005346A04704462846ECF75CFD01E06FF07F -+:102DA00018041FB928463946E8F3AAF12046BDE8C1 -+:102DB000F087C0460523C0F894310223C0F898314B -+:102DC0001E33C0F89C31234B4FF010021B68002BC0 -+:102DD0000CBF07230023C0F8A0314FF00103C0F857 -+:102DE000AC3103F16303C0F8B0314FF00603C0F813 -+:102DF000C03140F23C73C0F8C4314FF00803C0F852 -+:102E0000C83103F10D03C0F8A421C0F8B821C0F8FF -+:102E1000BC21C0F8CC31C0F8D02101D1032302E09D -+:102E20000D4B1B68013BC0F8D4311C230422C0F8B1 -+:102E3000DC310C23C0F8E0319B18C0F8E4310623E4 -+:102E4000C0F8EC310023C0F8D821C0F8E821C0F860 -+:102E5000F0317047EC260000D4250000D0F81012A5 -+:102E600070B5044609B90D460CE08068DFF39CF6A6 -+:102E7000D4F810120546E822A068E3F339F70023DE -+:102E8000C4F81032284670BD70B50024054680F89D -+:102E90007541006903F04AFC2846E6F30DF7E8683F -+:102EA0002146E7F3C7F7D5F8900128B1E3F306F21E -+:102EB000D5F89001E3F34CF2D5F88C0128B1E3F397 -+:102EC000FDF1D5F88C01E3F343F2E86805F0CAFCA4 -+:102ED000D5F8103223B11B7813B12846FFF7BEFF97 -+:102EE000A86829464FF40772E3F302F770BDC046A5 -+:102EF0001FB5044606238068E8210393E3F3E8F650 -+:102F0000C4F8100210B94FF0FF300CE00021E822A5 -+:102F1000DFF396F000230093A068D4F8101203AA00 -+:102F20001C33DFF3D9F604B010BDC0462DE9F047DD -+:102F30008AB01F46129D9C4B08461D601146904664 -+:102F4000E6F33CF6002800F02A8138464FF407717A -+:102F5000E3F3BEF60446002800F0218100214FF47F -+:102F600007720646DFF36CF0A76065612046FFF745 -+:102F700021FF8E4B1B68C4F80C320BB99A4605E052 -+:102F80001B78B3F1000A18BF4FF0010A884B04F117 -+:102F900028001A680121002A14BF31221122DFF310 -+:102FA0006DF70023009301930293404639462A4669 -+:102FB000139B05F095FDE060002800F0EA80E7F340 -+:102FC00051F72060E068E7F36BF7656960606B6854 -+:102FD000784A83F00103784903F00103002B0CBF0A -+:102FE00088469046226884F8763140F629039A4252 -+:102FF000D4F80890D4F80CC00AD120B905F5007EA9 -+:1030000005F5047508E005F5007E05F5087503E093 -+:1030100005F5007E05F50475D4F8B831D4F8BC2167 -+:10302000D4F8C411D4F8C00101934FF0FF330493D6 -+:1030300009330693002302920391059007934846B3 -+:103040004146624673460095EEF774FA60620028C6 -+:1030500000F09F80D4F80C12C1B10B78B3B1E1F34A -+:10306000C7F556492246D4F80C02DFF389F5D4F8A7 -+:103070000C0253492246DFF3BDF5BAF1000F05D02B -+:103080002046FFF735FF002840F0838001210A46E3 -+:10309000606AE1F3B5F520460021E2683B4603F0A3 -+:1030A00051FB2061002874D000210B462046454A80 -+:1030B000E3F370F10023C4F8900184F879314248B9 -+:1030C000E4F3D4F518B3DFF303F2012383403F4860 -+:1030D000C4F88031E4F3CAF510B1DFF3F9F108B1B7 -+:1030E000D4F88001C4F8840139490020DFF344F4A6 -+:1030F000030CA4F888319BB2A4F88A013BB10021EB -+:103100002046344A0B46E3F345F1C4F88C01002015 -+:103110003149DFF331F4012809D184F816022F492F -+:103120000138DFF329F4012804BF2D4B1860204635 -+:10313000E6F3A4F320B30025C4F8A051284629499A -+:10314000DFF31AF428B1012384F8F9312648EEF7A9 -+:10315000ABFA28462549DFF30FF488B12349284606 -+:10316000DFF30AF44FF0807300F00F000AA901F8B2 -+:10317000010D4FF44072009320460F23DFF7BEFC91 -+:103180001B481C492246E3F3B5F41B48EBF76CFDE2 -+:1031900006E0A06821464FF40772E3F3A9F5002684 -+:1031A00030460AB0BDE8F087F4260000BC260000D7 -+:1031B000EC260000AE278600B6278600DD9B800047 -+:1031C0007929000065A68000052886000E28860063 -+:1031D00017288600499B80001F28860078D50100AB -+:1031E000AC2702002A2886003428860089D50100F1 -+:1031F0004D288600E59A8000D596800010B50446DB -+:1032000060B1036806491868224600F09DDE236815 -+:10321000214658684FF4BC72E3F36AF510BDC0460E -+:10322000853B86007FB505464FF4BC714068E3F3EB -+:103230004FF508B9064619E000214FF4BC72064666 -+:10324000DEF3FEF60B4B356000930B4B002401932D -+:103250002868334609490A4A0294039400F03CDE88 -+:103260004FF49663C6F8603186F86441304604B086 -+:1032700070BDC04625110100E52C0000B0D501004D -+:10328000853B860070B5044608B906462AE0816889 -+:1032900009B90E460CE0C3689868ECF3DFF1E36807 -+:1032A000D0F1010638BF0026A1689868ECF3E8F178 -+:1032B000616F0025A56529B1E368A26F5868E3F343 -+:1032C00017F565672046EEF7D5FFE36806491868ED -+:1032D000224600F039DEE368214658684FF4B072A8 -+:1032E000E3F306F5304670BDEB3D860030B54FF494 -+:1032F000B07185B005464068E3F3EAF40446E0B1F6 -+:1033000000214FF4B072DEF39BF6E560C5F8184873 -+:10331000A8680D4922460023ECF3CEF1A06060B10D -+:103320000A4B2868009300230193029303930849F2 -+:10333000084A234600F0D0DD18B12046FFF7A2FF6F -+:103340000024204605B030BD152E0000D9E18000D4 -+:1033500034D60100EB3D8600034B012210B51A70F4 -+:10336000EBF7F2FF10BDC0463C28020070B50446E2 -+:10337000D0F884000D4608B102F0D8FCD4F88000E3 -+:1033800008B105F0E5FBE06F08B1FFF737FFA06F6C -+:1033900008B105F06BFC606F08B1FFF773FFA06820 -+:1033A00008B100F0CDFB284621468C22E3F3A0F4BF -+:1033B00070BDC0462DE9F04F064689B00D4600208D -+:1033C0008C2191469846139FE3F382F4044600282B -+:1033D00077D000218C22DEF333F62760304605F0EB -+:1033E000B1F807AB0190059383464FF0000A2046E1 -+:1033F00041F2E44142463B460295CDF800A0CDF8AB -+:103400000C90049400F06EFD054600285BD0A0608F -+:1034100002F066DB2B696060E3602F4B1021A36430 -+:103420002E4A3B46266164643046DEF34DF62B6936 -+:1034300039461B6E2A489A6B2A4BEEF735F93A4605 -+:1034400050461299284B0096CDF8049002F0ECFDFE -+:103450000746002837D16368012683F87860362153 -+:103460003246D5F87C0223F08FD9204B2846E363FF -+:10347000FFF73CFF606730B36368284683F8A460B9 -+:1034800005F006FCA067F0B12846FFF7CBFEE06729 -+:10349000C8B1284605F088FBC4F8800098B12846DA -+:1034A00002F072FCC4F8840068B1114B01970093DC -+:1034B0000297039728680F490F4A234600F00CDD56 -+:1034C00008B9204604E020465946FFF74FFF002088 -+:1034D00009B0BDE8F08FC04655F78000FB4186007B -+:1034E00008B10200A0D6010029FB8000EFBEAD0D9F -+:1034F00099F88000E8D60100C542860041F2E44315 -+:10350000984201D00020AFE044F22033994200F00D -+:10351000AA800533994200F0A680223B994200F030 -+:10352000A2801E33994200F09E800333994200F03E -+:103530009A800C3B994200F096800133994200F04A -+:1035400092800133994200F08E80093B994200F04D -+:103550008A800233994200F08680013B994200F054 -+:103560008280023399427ED0013399427BD001336D -+:10357000994278D00533994275D00133994272D07F -+:10358000013399426FD001F53C43D8339BB2022BF3 -+:1035900069D94BF6D543CB189BB2022B63D944F2C1 -+:1035A000413399425FD0013B99425CD001F53C43E5 -+:1035B000B0339BB2022B56D944F25333994252D0C6 -+:1035C000043399424FD04AF69D1399424BD044F2AE -+:1035D0005433994247D0253B994244D0013B99420C -+:1035E00041D0063399423ED0013399423BD001335A -+:1035F000994238D04BF6C943CB189BB2022B32D933 -+:1036000044F2167399422ED0113399422BD0A3F570 -+:103610007973994227D001F53C43A0339BB2012B2B -+:1036200021D901F53C43BA339BB2022B1BD94BF68F -+:10363000CF43CB189BB2012B15D94BF6AB43CB181C -+:103640009BB2012B0FD901F53C43A8339BB2012B50 -+:1036500009D944F26333994205D00D33994214BF1E -+:103660000020012000E001207047C0462DE9F84FFE -+:1036700000264FF0010842F601334FF0FF344FF0BF -+:10368000640B0746A0F8283680F8474680F8C44403 -+:103690000221224680F8288080F868B780F84266C8 -+:1036A00080F84C8680F8436680F8498680F8466644 -+:1036B00002F05ED938464146324602F059D90C2113 -+:1036C0002246384602F054D90B213846324602F0E1 -+:1036D0004FD90E212246384602F04AD90D213846EC -+:1036E000324602F045D90F212246384602F040D931 -+:1036F00004210222384602F03BD9D7F860364FF059 -+:10370000030987F8488683F80690D7F860364FF0AB -+:10371000020A83F8079040F62A13A7F82A36A7F87A -+:103720002C369BB2A7F82E3640F62A13A7F830366F -+:10373000A7F83236A7F83436A7F8363640F62B13FA -+:10374000A7F838363B68A7F87A6583F895604FF09C -+:103750000703A7F83A364FF00403A7F83C360F23C7 -+:1037600087F80C37D7F89034A7F83E96C7F8803220 -+:10377000A7F840A6A7F87C68A7F87EB887F8EA61A2 -+:1037800087F8EB6187F81E6287F8EE6187F8EC61D5 -+:1037900087F8FA8187F80B6787F8A0649E71D7F8DD -+:1037A00094340B22C7F8843283F80680D7F8983413 -+:1037B0003146C7F8883283F806A0D7F89C343546DE -+:1037C000C7F88C3283F806903B6887F8506783F817 -+:1037D0004D805C633B6807F5CC6483F842803B68AE -+:1037E000043483F843603B6887F8CF6183F839601D -+:1037F0003B68204683F8AA803B6887F8DF6187F83A -+:10380000E081C7F8E46187F8E161DE66DEF318F471 -+:103810006FF0220387F864362C3387F865364A4602 -+:1038200004EB0A001A49DEF3A7F33B6887F869A6A0 -+:1038300087F8568587F8578583F84C603A6887F88B -+:103840009267A7F89067A7F88CB892F8463013F003 -+:10385000030F0CD092F94C304BB1D7F8FC04243054 -+:10386000F1F3F6F4D7F8FC043230F1F3F1F44FF44D -+:103870004873A7F85C373B68012287F8252883F84E -+:10388000A2203A684FF0FF3382F8B530BDE8F88FD8 -+:103890000FD40100836B70B5002483F84C40C36BD8 -+:1038A000012583F84C500646816BDFF711FEF16B62 -+:1038B0003046DFF70DFE21463046F6F349F2B36B92 -+:1038C000304683F84D40F36B294683F84D40D6F8D7 -+:1038D00060364FF0FF34DD72D6F860369C81F6F327 -+:1038E00037F2D6F860369B78AB4214D9B36B83F8C5 -+:1038F0004D40F26B4FF0FF3382F84D3096F8CB34E9 -+:1039000096F8CC2443EA022343F0800386F8CB34B4 -+:103910001B0A86F8CC3470BDD0F8AC1110B5044643 -+:1039200029B18068EBF3ACF60023C4F8AC31D4F8CD -+:10393000C41129B1A068EBF3A3F60023C4F8C43185 -+:10394000D4F8741529B1A068EBF39AF60023C4F8F3 -+:103950007435D4F8F81629B1A068EBF391F600237A -+:10396000C4F8F836D4F8FC1629B1A068EBF388F651 -+:103970000023C4F8FC36D4F8E036196A31B1A068E7 -+:10398000EBF37EF6D4F8E02600231362D4F83C155E -+:1039900029B1A068EBF374F60023C4F83C35D4F8E1 -+:1039A000941729B1A068EBF36BF60023C4F89437A1 -+:1039B000D4F8B01829B1A068EBF362F60023C4F87C -+:1039C000B03810BD70B505462D4980682A460023E1 -+:1039D000EBF372F6C5F8AC0100284ED0A86829496F -+:1039E0002A460023EBF368F6C5F8C401002844D04A -+:1039F000A86825492A460023EBF35EF6C5F874054E -+:103A000000283AD0A86821492A460023EBF354F64F -+:103A1000C5F8F806002830D0A8681D492A460023BA -+:103A2000EBF34AF6C5F8FC0638B3A86819492A46EC -+:103A30000023D5F8E046EBF33FF62062E8B1A86832 -+:103A400015492A460023EBF337F6C5F83C05A0B12B -+:103A5000A86812492A460023EBF32EF6C5F894070E -+:103A600058B1A8680E492A460023EBF325F6C5F89D -+:103A7000B008003818BF012000E0002070BDC0462B -+:103A80003DAA81003D708100253E81009591810015 -+:103A9000858F8100256E810089598100396B8100F5 -+:103AA000496F810010B50446006805F0B3FED4F8F4 -+:103AB000583113B10023C4F85831D4F83C0120B177 -+:103AC00005F00EF90023C4F83C31D4F8400120B1D0 -+:103AD00001F080F80023C4F84031D4F84C0120B143 -+:103AE00002F09AF80023C4F84C31D4F8540120B104 -+:103AF00005F070FA0023C4F85431D4F8600120B105 -+:103B000007F000F80023C4F86031D4F8383113B15D -+:103B10000023C4F83831D4F8640120B101F0FEFE6E -+:103B20000023C4F86431D4F8000520B107F026F969 -+:103B30000023C4F80035204605F0D2FA10BDC04677 -+:103B40002DE9F041054608B9074695E001F046FB2E -+:103B50000746284602F06AD800B90137D5F8F016B2 -+:103B600049B16868D5F8F426E3F3C2F00023C5F83C -+:103B7000F436C5F8F0362846D5F81815F8F38AF764 -+:103B80002846D5F8D816F8F385F7D5F82015284635 -+:103B9000F8F380F7D5F82C1521B168684FF49662D8 -+:103BA000E3F3A6F0D5F87C0220B105F051FA00232A -+:103BB000C5F87C3200242B19D3F84C1211B12846D9 -+:103BC0001BF03ADC0434202CF5D10121284631F0D9 -+:103BD000C9DD284601F078FE2E6BB16911B1284687 -+:103BE00031F054D80024B461D5F85C0101F05EFFD7 -+:103BF0002846FFF791FE2846FFF754FF2846D5F8E0 -+:103C00002C18DFF75DFCC5F82C48D5F8B84404E063 -+:103C100068681022E468E3F36BF02146002CF7D1CA -+:103C2000C5F8B844286816492A4600F08DD9D5F859 -+:103C3000340718B101F010F9C5F83447D5F8680118 -+:103C400018B106F0C5FFC5F86841D5F8181759B185 -+:103C50006868D5F81C27E3F34BF0C5F8184703E074 -+:103C60002846696807F0B0D8D5F87822002AF7D13D -+:103C70002846696800F034FD3846BDE8F081C0464A -+:103C8000BB5C8600036870B55E6905461449304622 -+:103C9000DEF372F6C0B218B930461249DEF36CF6A4 -+:103CA00040B2431E0E2B0ED8012803D1D5F8603642 -+:103CB000002204E0022806D1D5F8603601229A716C -+:103CC000D5F86036DA71084930462C6BDEF354F6CD -+:103CD00084F804012846EFF3EFF1012070BDC046DF -+:103CE000C65C8600CB5C86000E5D8600036870B5FE -+:103CF0001B490546D0F860465869DEF33DF6207052 -+:103D00002B6818495869D5F86046DEF335F6E0703F -+:103D1000D5F8602613780BB10F2B01D10123137056 -+:103D2000D5F8603601211A785A70D5F860462046D9 -+:103D3000DEF3DEF3A070D5F86026D3780BB10F2B3D -+:103D400001D10123D370D5F860360121DA781A71D8 -+:103D5000D5F86046E01CDEF3CBF3607170BDC04661 -+:103D600019D7010021D7010070B50446214600682B -+:103D700007F012F8C4F8000508B929305EE02068A1 -+:103D800005F050FD2068214601F08AF8C4F8340798 -+:103D900008B92A3052E02A4B2046C4F8583104F0C2 -+:103DA000B9FFC4F83C0108B9313047E0204600F0C3 -+:103DB0004BFFC4F8400108B932303FE0204606F01E -+:103DC000B3FEC4F8600108B9353037E020682146F9 -+:103DD000A2681C4B05F058F9C4F87C0208B93930C8 -+:103DE0002CE0204601F0EAFDC4F8640108B93C303B -+:103DF00024E0154B0125C4F838310023A4F83038ED -+:103E000084F8883884F88A3884F88958204601F084 -+:103E100013FFC4F84C0108B93F300FE02368214676 -+:103E200083F83A50236883F8A950206805F062F9B6 -+:103E300008B1452002E0236883F8A05070BDC04659 -+:103E4000EFBEADDE9D6D8100EFBEAD0DF0B5D0F8DB -+:103E500040750021AC2287B006463846DEF3F0F00C -+:103E60004FF06403FB85032387F8603000220123B1 -+:103E7000D6F85C014FF42C5121F0D4DFFF2804D197 -+:103E8000336B18691968EEF787FE31687886A6F8F3 -+:103E9000260691F84640336B00F44065FF201A89EE -+:103EA00000211B68B5F5406F14BF1425282501902B -+:103EB00004F00304D6F8600600910294039580781C -+:103EC000049007F138002DF0D9D8336893F84630C4 -+:103ED00013F0030F03D0FB8843F02003FB8007B0EF -+:103EE000F0BDC0462DE9F04F8DB01A9F9A460023D1 -+:103EF00007910B930646934610461799189A199BFB -+:103F00009DF85890009709F08DF9044610B11E23D2 -+:103F10000B937FE3FFF720FA179851460BAA00F0A6 -+:103F20000DFD0546002800F07583179AD0F860361D -+:103F300042604FF0FF32D0F8008083F81C21836B81 -+:103F4000C8F804A00363436B8660C362179BC0F884 -+:103F50007871C8F80C30B54B88F82190C8F8B030AB -+:103F6000032380F86937C0F8CC2880F89D4151467A -+:103F7000FFF77CFB2846F7F323F7284605F0D4F833 -+:103F80000446002840F04F8328463146179A53468E -+:103F900006F03EFEC5F8680108B91F23D3E2A44B22 -+:103FA0000194009302940394A249A34A2B462868E3 -+:103FB000FFF392F7A14B0194009302940394A0495C -+:103FC000A04A2B462868FFF387F7189A199B179E7B -+:103FD00002920393284607995A465346CDF800901B -+:103FE0000196049701F04AFA04460B90002840F02D -+:103FF0001A832B69186EEBF767FCA5F8BE082846F4 -+:10400000F5F38EF508B914239DE2264631460AAA37 -+:104010002846F7F311F231462846BDF8282001362C -+:10402000F7F314F2062EF1D1012488F89A4005F531 -+:10403000BE72286908F1140118F054DC8249D8F8DE -+:104040001400DEF399F481498146D8F81400DEF3B8 -+:1040500093F47F49A5F86208D8F81400DEF38CF4D5 -+:10406000B5F86228A5F86408A5F87827A5F87A07B6 -+:104070007849D8F81400DEF37FF47749A5F854089E -+:10408000D8F81400DEF378F485F856087349D8F8A8 -+:104090001400DEF371F485F858087149D8F814005B -+:1040A000DEF36AF485F85A086E49D8F81400DEF396 -+:1040B00063F485F857086C49D8F81400DEF35CF413 -+:1040C00085F859086949D8F81400DEF355F485F8E5 -+:1040D0005B086749D8F81400DEF34EF485F85C08F5 -+:1040E0006449D8F81400DEF347F485F85E086249A5 -+:1040F000D8F81400DEF340F485F860085F49D8F87A -+:104100001400DEF339F485F85D085D49D8F8140031 -+:10411000DEF332F485F85F085A49D8F81400DEF36C -+:104120002BF485F861082846FFF7E0FDD5F86026F6 -+:104130002B6B85F8F04785F8F14718691178D2782C -+:10414000EEF77CFF2869EA6AD0F8A03005F5CB7459 -+:104150005360D0F8A43021469360D0F8A830D360E3 -+:10416000D0F8AC301361D0F8B0305361D0F8B4302F -+:10417000936118F0E7DC08F14E0021463246DDF38A -+:10418000FBF6B5F8822144F221339A4217D00E3B58 -+:104190009A4214D007339A4211D010339A420ED06B -+:1041A000143B9A420BD007339A4208D010339A42FC -+:1041B00005D025339A4214BF0024012400E00124D5 -+:1041C00005EB84039B6B28462B63FFF75BFD08B967 -+:1041D0001823B8E1296B4FF00F0340F2FF36A1F826 -+:1041E000063101F1FC0201F58073A1F8086128464F -+:1041F00000F0B4FE2A6BD2F8FC30C2F8F830C2F8F6 -+:10420000F030D2F80031C2F8F4301368022B07D135 -+:10421000013B53752B6B284603215A7D01F0A8DB27 -+:1042200019F0010F30D000222FE0C0465F7D5A0503 -+:1042300079DB810078D48500BB5C8600E94800000A -+:104240005CD8010029D70100D6688600E2688600A4 -+:10425000F5688600076986001C6986002B69860060 -+:104260003A698600496986005A6986006B6986004A -+:104270007C6986008A69860098698600A66986003E -+:10428000B6698600C6698600012288F846200A21A0 -+:10429000284601F06DDB296B28461C31F9F3C6F383 -+:1042A0007F23296B00932B68002293F8463001F19D -+:1042B0001C0003F003030193503113462CF01CDF64 -+:1042C000B4F1FF3F3FF45DAF2846F5F383F44FF4BC -+:1042D000D163C5F874382846FFF746FD04460B90B5 -+:1042E000002840F0A0812869214619F00FDB2869D9 -+:1042F00098F83A1018F052DF28465146FFF762FB53 -+:1043000008B920231FE1284601F0DAFBC5F85C015B -+:1043100008B9212317E12846FFF798FD2146AD4A49 -+:10432000AD4B28460094019506F008FDAB4B6E4658 -+:104330001A1D07CA1B6886E80700072128462A4677 -+:1043400006F094DC04212846A54AA64B009401956A -+:1043500006F0F4FC0028C5F88C0701DA2223F2E00D -+:104360002846179906F006DD08B96423EBE0C5F886 -+:1043700004084FF0FF3728469B499C4A9C4B009706 -+:10438000FEF342F6C5F82C08002800F04C812846C0 -+:1043900001F0A4FA044608B12323D4E02B684FF0BF -+:1043A000060293F8A130A8F86420012B04BF402333 -+:1043B000A8F86430D8F88C304FF006064FF4397204 -+:1043C0001E805A80D8F890304FF0C4024FF001069A -+:1043D00005F5007128461E805A80063107F09EDCE4 -+:1043E000D5F83C010CF028DD08B185F8CF61022337 -+:1043F00085F8C0341C3385F8CB3410222B6B85F83C -+:10440000CC245B89022B02D81C2385F8CB342846A8 -+:10441000214685F8CA7485F8C97485F8C874F6F31E -+:104420003BF12B68284683F8B4402146C5F8D47187 -+:10443000F1F34AF185F8DC412846FFF72BFA19F031 -+:10444000080F18BF85F8DC4119F0100F03D028467B -+:104450002146F1F339F119F0020F13D0AB6B83F859 -+:104460004D40EB6B83F84D4095F8CB3495F8CC2458 -+:1044700043EA022323F080039BB285F8CB341B0A66 -+:1044800085F8CC3419F0040F03D028462146F5F303 -+:104490007FF419F0800F0DD095F8CB3495F8CC242B -+:1044A00043EA022323F010039BB285F8CB341B0AA6 -+:1044B00085F8CC342B6893F842308BB119F0600F3B -+:1044C0000ED019F0200F0CBFFF21002119F0400F72 -+:1044D000284649B214BF00226FF0000200F068FBCA -+:1044E00006220DF122004349DDF346F5B5F882219D -+:1044F00044F221339A4217D00E3B9A4214D007332C -+:104500009A4211D010339A420ED0143B9A420BD0EB -+:1045100007339A4208D010339A4205D025339A4285 -+:1045200014BF0027012700E0012705EB8706B46BC5 -+:104530000DF122012846224630F06ADBB16BA06102 -+:10454000886910B937230B936DE04430503128222D -+:10455000DDF312F5B36BB7F1FF3F9B699F62BFD0EC -+:10456000D8F85C30179E43F00403C8F85C30224B47 -+:10457000F560B3602846ECF7C7FF1B9A0AB1002329 -+:1045800013602B681D495869DEF322F230B1002117 -+:104590000A46DEF3DDF01A4BC0B218602B681949E9 -+:1045A0005869DEF315F230B100210A46DEF3D0F08F -+:1045B000154BC0B218602B6814495869DEF308F235 -+:1045C00030B100210A46DEF3C3F0114BC0B21860CF -+:1045D00028462CE039AE820001AE820034D90100B9 -+:1045E000D5A18100ADA181002D57810041578100E7 -+:1045F0001957810056D80100B542820035D7010015 -+:10460000EC27020041D70100102C020055D7010011 -+:10461000142C02001B9B0BB9184608E00B9B1B9E39 -+:104620000020336003E02846FFF78AFAF2E70DB076 -+:10463000BDE8F08F20230360436040F23C73836049 -+:10464000092330B50361836107330362303383622A -+:104650000F230822036340F29E3304240125002126 -+:1046600042618263C3640322A3F56773C460C561BA -+:104670004462C46244630164456402654166436503 -+:104680008465C265036630BD70B505460C4631B31E -+:10469000496D11B1C022E2F32BF3D4F88C1039B17B -+:1046A00028464FF43972E2F323F30023C4F88C3028 -+:1046B000D4F8901031B12846C422E2F319F3002354 -+:1046C000C4F89030E16929B128466822E2F310F37A -+:1046D0000023E36128462146B822E2F309F370BDC6 -+:1046E00070B50D460446002800F0E580D0F8181596 -+:1046F00039B128464FF48472E2F3FAF20023C4F889 -+:104700001835D4F8201539B128464FF48472E2F3F5 -+:10471000EFF20023C4F82035D4F8B41439B1284698 -+:1047200040F2AC42E2F3E4F20023C4F8B434D4F82B -+:10473000401531B12846AC22E2F3DAF20023C4F886 -+:104740004035D4F86C1229B1284607F019DE002351 -+:10475000C4F86C32D4F8FC1431B128464022E2F39C -+:10476000C7F20023C4F8FC34D4F8841671B123686E -+:1047700063B1DB6953B19B690C22013303FB02F285 -+:104780002846E2F3B5F20023C4F88436D4F8BC140A -+:1047900019B12846B422E2F3ABF2D4F8901421B157 -+:1047A00028464FF4AE62E2F3A3F2D4F8581631B1C2 -+:1047B00028463822E2F39CF20023C4F85836D4F895 -+:1047C000601639B128464FF49072E2F391F200235B -+:1047D000C4F86036D4F8F81731B128460622E2F35F -+:1047E00087F20023C4F8F837D4F8D81639B1284630 -+:1047F0004FF48472E2F37CF20023C4F8D836D4F884 -+:10480000E01631B128462422E2F372F20023C4F804 -+:10481000E036D4F8EC1631B128466822E2F368F2AB -+:104820000023C4F8EC36D4F8441731B12846EC2202 -+:10483000E2F35EF20023C4F84437A16B21B12846AD -+:104840004FF40672E2F354F2616B79B1896A31B1C7 -+:1048500080222846E2F34CF2626B002393622846E2 -+:10486000616B2C22E2F344F200236363216821B1DF -+:104870002846FFF709FF002323602369ABB1D3F873 -+:10488000F81028461822E2F333F223690026D96F84 -+:10489000C3F8F86019B128465822E2F329F22846F5 -+:1048A0002169FC22E2F324F226612846214640F6E3 -+:1048B000D402E2F31DF270BD2DE9F0411646B82294 -+:1048C00007460D4607F0FADD044610B940F2E93319 -+:1048D0002BE038462946682207F0F0DDE06110B988 -+:1048E00040F2044321E0FFF7A5FE38462946C022E6 -+:1048F00007F0E4DD606510B940F2EB3315E03846AF -+:1049000029464FF4397207F0D9DDC4F88C0010B98C -+:104910004FF47B7309E038462946C42207F0CEDD08 -+:10492000C4F8900038B940F2ED3321463360384680 -+:10493000FFF7AAFE00242046BDE8F0812DE9F041F2 -+:10494000174640F6D40280460E4607F0B7DD05460E -+:1049500000283BD02623C0F82838314640463A4646 -+:10496000FFF7AAFF2860002800F018818F4B056030 -+:104970001B683146C0F89C30FC22404607F09EDDA3 -+:104980000446286110B940F2ED3306E185603146F6 -+:104990004046182207F092DDC4F8F800B0B1404656 -+:1049A000314658222C6907F089DDE06770B12B6928 -+:1049B0004046DA6F31462C32C3F880204FF48472BF -+:1049C00007F07CDDC5F8180518B105E040F2EE33BC -+:1049D000E3E040F2EF33E0E0404631464FF48472CA -+:1049E00007F06CDDC5F8200510B94FF47C73D4E0F6 -+:1049F0004046314640F2AC4207F060DDC5F8B404F1 -+:104A000010B940F2F133C8E040463146AC2207F01D -+:104A100055DDC5F8400510B940F2F233BDE031462E -+:104A20004046ECF709FF0146C5F86C0210B940F2A8 -+:104A3000F333B2E028461AF091D84046314640227E -+:104A400007F03CDDC5F8FC0410B94FF47D73A4E019 -+:104A50002B680C22DB6940469B693146013303FB1E -+:104A600002F207F02BDDC5F8840610B940F2F533E9 -+:104A700093E040463146B42207F020DDC5F8BC047F -+:104A800010B940F2F63388E0404631464FF4AE624A -+:104A900007F014DDC5F8900410B940F2F7337CE05C -+:104AA0002A464FF4AE71D5F89034CB1801F5AE71AB -+:104AB000C2F894340432B1F5AE6FF4D140463146B9 -+:104AC000382207F0FBDCC5F8580610B94FF47E73A6 -+:104AD00063E0404631464FF4907207F0EFDCC5F8D2 -+:104AE000600638B140463146062207F0E7DCC5F8DB -+:104AF000F80710B940F2F9334FE0404631464FF421 -+:104B0000847207F0DBDCC5F8D80610B940F2FA333E -+:104B100043E040463146242207F0D0DCC5F8E006E9 -+:104B200010B940F2FD3338E040463146682207F0C4 -+:104B3000C5DCC5F8EC0610B940F2FE332DE0404666 -+:104B40003146EC2207F0BADCC5F8440710B940F250 -+:104B5000FF3322E0404631464FF4067207F0AEDCE8 -+:104B6000A86358B100F58673EB63404631462C22AA -+:104B700007F0A4DC0446686318B105E040F2014385 -+:104B80000BE040F2024308E040463146802207F045 -+:104B900095DCA06238B940F203433B6028464146A9 -+:104BA000FFF79EFD00252846BDE8F081BC260000E9 -+:104BB000D0F84031B1F1FF3F18BF83F89C13B2F138 -+:104BC000FF3F83F89E1383F89F2318BF83F89D232C -+:104BD0007047C04670B50446002831D000256319DF -+:104BE000D3F8501221B12368F4225868E2F380F020 -+:104BF0000435282DF3D1A16B69B194F8A3331BB10F -+:104C000023689868EAF32AF52368A16B9868EAF3A9 -+:104C100037F50023A363D4F8781221B12368E82282 -+:104C20005868E2F365F02368064918682246FFF3E6 -+:104C30008BF12368214658684FF46A72E2F358F00A -+:104C400070BDC046678986002DE9F0434FF46A7154 -+:104C500085B006464068E2F33BF0054608B9814658 -+:104C6000CFE000214FF46A728146DDF3E9F12E6056 -+:104C70007068E821E2F32CF0C9F87802002800F00F -+:104C8000B1800021E822DDF3DBF1002101236A1865 -+:104C9000C91808299372F9D1013B2B746B742B73DB -+:104CA000EB721A460121AB185218082A83F89413A4 -+:104CB000F8D11023EB74062385F827304FF0FF332B -+:104CC00085F82830213385F8A233052385F829306B -+:104CD0004FF47A736B864FF0C803AB86002385F8D8 -+:104CE0002A30023385F82B302B682A75A9741B688B -+:104CF0002A4693F8A1308B4218BF032385F82C3045 -+:104D00004FF0FF3385F89E3385F89F334FF40063EF -+:104D1000EB63012385F82D3004336B750223AB75EB -+:104D20006B7DD375AB7DD377013205F108039A42D1 -+:104D3000F6D100244FF0010895F82910284685F88F -+:104D40002E4085F82F8007F09DDE284686F8C38424 -+:104D500009F0B8DC042130462C4A2D4B0094019513 -+:104D600005F0ECFFA04268603CDB2A4B3068009302 -+:104D7000294B2A4901932A4B2A4A03932B46029432 -+:104D8000FFF3AAF0074668BBB06827492A463B46AE -+:104D9000EAF392F4A86328B3244C85F87C82231D9F -+:104DA00093E807006B4683E807002A4623683046ED -+:104DB000062105F05BDF4FF0FF3385F8A133336840 -+:104DC000284693F842100AF0DDDCC823C5F8E0322B -+:104DD000284609F0BDDE28464146ECF7CBFB85F8B6 -+:104DE000A3730EE0D5F8781219B17068E822E1F3E8 -+:104DF0007FF7706829464FF46A72E1F379F74FF054 -+:104E00000009484605B0BDE8F083C04695CB820056 -+:104E10001DCB820045CF820011E7820054D90100EA -+:104E200079D982006789860085A2000044D90100F3 -+:104E300070B5182686B00C46324668460549DDF343 -+:104E40009BF02046694632466D46DDF395F006B08C -+:104E500070BDC04634DB010070B5D0F8AC530446D9 -+:104E6000D0F8B063284603F09DFFD4F8D013A868AB -+:104E7000EAF3F4F3A868D4F8D013EAF301F40023BA -+:104E80002246C4F8D03330460449FFF35DF0F068A1 -+:104E900021464FF47E72E1F32BF770BDAB9986008B -+:104EA0002DE9FF413C23C1F824370523C1F82837F9 -+:104EB00007460D46C0684FF47E71E1F309F70446DA -+:104EC00000283DD000214FF47E724FF00008DDF342 -+:104ED000B7F0C4F8AC53C4F8B07384F8018020462E -+:104EE000E5F752FAC4F8C003284603F071FF0646FE -+:104EF00038B1F86821464FF47E72E1F3F9F6404686 -+:104F00001FE0204604F56371FFF792FFA8680E4981 -+:104F100022463346EAF3D0F3C4F8D00380B12046EA -+:104F20000DF054DC094B38460093094B09490193B5 -+:104F3000094A234602960396FEF3CEF7204600E088 -+:104F4000002004B0BDE8F0818D25830011B400007D -+:104F5000190F0100E4D90100AB99860010B5044691 -+:104F60000846B0F80CE0194642F256039E4506D8B2 -+:104F7000013B9E452ED2053B9E4509D02AE042F2D8 -+:104F800060039E451BD04EF2F5439E451CD021E0A8 -+:104F9000C389012B04D16FF03B0313604B3303E053 -+:104FA0006FF0450313605A330B602368D3F88030E9 -+:104FB00013F4805F13D01368023B13600FE06FF0AF -+:104FC0004A0313605A3309E06FF09503136003F549 -+:104FD000967303E06FF04A0313605F330B6010BDFC -+:104FE00070B504460025E06820B1054B1B68984762 -+:104FF0000023E36001350434062DF4D170BDC046B2 -+:10500000E0A685000D4B82685362002380F886304D -+:105010004FF00303A0F88C304FF00203A0F88E305D -+:105020004FF00703A0F888304FF00403A0F88A304F -+:1050300042F60133A0F89C307047C04664A8E7BE32 -+:10504000426C1F2A01D9002004E04FF00073134185 -+:1050500003F001007047C046026EB0F84A1010B568 -+:10506000946AB9B1FF2901D8012014E00B0B013B70 -+:10507000012B0FD8C1F30323092B0BD853B1C1F374 -+:105080000313092B06D801F00F03092B8CBF002056 -+:10509000012000E00020D26A41F2E4439A4210D19C -+:1050A000A4F58263073B012B01D83F2907E040F2BA -+:1050B0000C439C4204D015339C4202D1502900D8A5 -+:1050C000002010BD00B58E46C16E4FF0407394466F -+:1050D0007046C1F8603115E00379C2781B0443EAD9 -+:1050E000026382791343427943EA0223C1F86431AF -+:1050F000437802781B0243EA024382780730134365 -+:10510000C1F86431CEEB00036345E5D300BDC04672 -+:10511000C16E4FF48030C1F860011D4AD1F8603192 -+:1051200010B5D1F86441C1F86001D1F86031C1F81F -+:105130006421C1F86001D1F86031D1F86431934243 -+:1051400024D1144AC1F86001D1F86031C1F864215A -+:10515000C1F86001D1F86031D1F86431934215D1C2 -+:10516000C1F86001D1F860310023C1F86441C1F891 -+:105170008C31D1F82001084B984201D1012006E082 -+:10518000064B984214BF0020012000E0002010BD13 -+:10519000AA5555AA55AAAA55000400040004008483 -+:1051A000D0F8501810B5044641B1D0F84C284068EA -+:1051B0009200E1F39DF50023C4F85038D4F8481864 -+:1051C00059B16068DDF3F0F46068D4F84818E8225B -+:1051D000E1F38EF50023C4F8483810BD70B50469BA -+:1051E0000646206E08B1EAF729FB2046FFF7F8FED5 -+:1051F000A56F686A18B104F035F800236B62606F20 -+:1052000003F0C2FF206F05F05BFC616E29B12068DE -+:10521000A26EE1F36DF500236366206E18B103F012 -+:1052200021FB002323662046E7F7C4FF3046FFF743 -+:10523000B7FF002070BDC0462DE9F04F0368076935 -+:105240008FB00890DE691446FB6B0CA80821704AE9 -+:10525000DCF33AF7FB68002B40F0CE80F96E386E35 -+:1052600001F50071D7F800B0DFF31EF3BB6801460B -+:105270009868EAF3B7F1002800F0C680D7F860E03C -+:105280000CB9A44602E0FB6E03F5007CFB6E03F54F -+:10529000087504B13468B168BB687268F068D3F807 -+:1052A000283803915B490DF130094FF0FF38029225 -+:1052B0000590724606930791634649465846009505 -+:1052C0000194CDF81080ECF735F93168F8603A6E4A -+:1052D000FB6E01914F4900240546079103F51073B9 -+:1052E00049465846009402940394CDF810800594E2 -+:1052F0000694ECF71FF9316838613A6EFB6E019144 -+:1053000044490990079103F5207349465846009493 -+:1053100002940394CDF8108005940694ECF70AF9F2 -+:10532000316878613A6EFB6E01913A490A900791B3 -+:1053300003F5307349465846009402940394CDF81F -+:10534000108005940694ECF7F5F83168B8613A6E70 -+:10535000FB6E01912F490B90079103F5407349466D -+:105360005846009402940394CDF810800594069456 -+:10537000ECF7E0F83168F8613A6EFB6E019125496F -+:105380008246079103F550734946584600940294AB -+:105390000394CDF8108005940694ECF7CBF8099AA5 -+:1053A000A54214BF002501250A9BA24208BF45F073 -+:1053B00001050B99A34208BF45F00105A14208BFB2 -+:1053C00045F00105A24508BF45F001053862A0423D -+:1053D00014BF284645F00100B0B90F4B3C46D3F846 -+:1053E00084600546E06818B10C49B047C4F8A000D5 -+:1053F00001350434062DF5D1B96F08980831002223 -+:10540000E7F714F9012000E000200FB0BDE8F08FAD -+:10541000FB41860014260000E0A68500C326860016 -+:105420001FB5022303930C330446C0F84C383821CF -+:105430004068E1F34DF4C4F85008D0B1D4F84C28DA -+:1054400000219200DCF3FCF56068E821E1F340F410 -+:10545000C4F8480868B10021E822DCF3F1F5012323 -+:1054600000936068D4F8481803AAB333DDF334F42A -+:1054700001E04FF0FF3004B010BDC0462DE9F04F01 -+:10548000056997B0DDF884A014469B469DF88020FE -+:10549000EB63EB6FA860AB672A710746C5F800A005 -+:1054A00028460E46FFF7AEFD249B05F1640205F188 -+:1054B000680100930192029120465146229A239B53 -+:1054C00003F00EFB2866002800F0D581D5F8648033 -+:1054D00095494046DDF37CF220B100210A46DDF318 -+:1054E00037F186B240469149DDF372F248B10021AE -+:1054F0000A46DDF32DF14FF6FF7380B2984218BFD4 -+:10550000044630462146FDF7F9FF08B90C30B7E1F3 -+:1055100040F612010022A5F84060A5F84240286E2E -+:10552000E5F36CF6E866286EE5F3BAF4D5F86C900E -+:105530006864C7F80C902846FFF782FD08B90D3063 -+:105540009EE1286EEAF77EF92846002116F0C4DBBA -+:1055500028464FF0FF31E7F7A7F82846FFF7D8FDB8 -+:1055600008B90E308CE140467149DDF305F2FF28A1 -+:1055700008BF0120A5F84A002846FFF76DFD08B9CD -+:105580000F307DE16B494046DDF3F6F16A4985F85D -+:1055900048004046DDF3F0F16849E8644046DDF339 -+:1055A000EBF1296E2865CA6A41F26B039A420AD16F -+:1055B0008B6A4E2B07D1B5F84A30402B03D9EB6CE0 -+:1055C00043F00203EB64EB6C13F0200F04D00121D5 -+:1055D00028460A4617F036DFB5F840200123A7F821 -+:1055E0008021C5F89830B5F842303A68A7F8823182 -+:1055F0002B6E284613616B6C936095F8483082F8E7 -+:105600007C303A68B5F84A30B968A2F87A30EB6C69 -+:10561000C2F880302B6DC2F88430D5F898305362D0 -+:105620003A4605F057FA286708B9193028E12B6E79 -+:10563000CDF810A005932B6FCDF81CB0B5F8402025 -+:1056400006936B6CADF8302008932A6EB5F84230A3 -+:10565000CDF82C80ADF83230936B04A80D93D36B4A -+:105660000E93136C0F9395F848301093936A11932F -+:10567000B5F84A301293D36A1393EB6C14932B6DE5 -+:10568000159353680993D3680A9303F085FD6867FF -+:1056900008B91030F4E0B5F8421044F221339942D1 -+:1056A00017D00E3B994214D00733994211D01033D2 -+:1056B00099420ED0143B99420BD00733994208D03F -+:1056C0001033994205D02533994214BF0026012694 -+:1056D00000E0012631462846E6F7CAFFAA6F002EF1 -+:1056E0000CBF02230123136056603A6B286E1360CF -+:1056F0005660FC6AE5F3C2F32060D9F85C31696C4E -+:105700000F4A6B65AB65062301FB0323AC6FC5F83D -+:10571000B830686F49462268434603F0D5FE6062A0 -+:1057200080B91130ACE0C046D1AD86004837860064 -+:1057300084AE8600E5AE8600863786009E798600B8 -+:10574000301E0200AB6F696D586AEDF747FBAB6F17 -+:1057500003F1220203F11C01586A009203F11E02B8 -+:10576000203303F0F9FCAC6F606A03F005FD84F8A8 -+:105770002800AB6F3C6B586A03F0FEFC2075AC6FE1 -+:10578000606A03F0FDFCA96FA061CB8B032B01D0F5 -+:10579000122075E03B6B4A6A38461A618A8B1A817F -+:1057A000CA8B5A810A8C9A814A8CDA8140F2FF3284 -+:1057B0004FF00F03CA828B8201223146FFF73CFD76 -+:1057C00008B913305CE0B6F1FF3F3FF464AFAB6F54 -+:1057D0003A68586A92F89910EDF704FB00212846C0 -+:1057E00016F062DF08212846E7F772F8284618F01D -+:1057F00093DA286E2449254A00230097E5F3BAF48A -+:105800002846002118F06ADA2846E6F7FBFE08B9B8 -+:10581000153035E005F1DC042146DCF3CDF62046F9 -+:10582000DDF38AF048BB2046DDF396F0044620BB4A -+:10583000284616F099D8AB681B68D3F89C00F0B1E5 -+:105840000378E3B112492A46DDF39AF1AB681149B6 -+:105850001B682A46D3F89C00DDF3CCF1A868FFF75B -+:10586000DFFDE86858B1AB681B68D3F89C10DFF324 -+:10587000BFF1204604E00B2002E0162000E00020EB -+:1058800017B0BDE8F08FC04669C1830085C18300B1 -+:1058900025C0830049C0830010B590F85E300446EF -+:1058A0005BB90648EBF700FF054B20461A6805492F -+:1058B000FFF708FC012384F85E3010BD67DB0100B0 -+:1058C000FC580300A4D2020010B5044619F058DFBA -+:1058D00001220146204619F0CBDF10BD37B5054641 -+:1058E00019F04EDF0023C5F84C0280F848302A68D2 -+:1058F000044692F82F10284600914E32214618F0A7 -+:10590000EDDC30B12846214619F096DD4FF0FF302E -+:1059100003E02846214619F035DE3EBD37B5044682 -+:10592000002847D0D0F8201131B103689868E9F316 -+:10593000A7F60023C4F820312268136893F82F30AB -+:105940003BB3D2F8000501A92FF0C4DB13E0536884 -+:1059500013F0400F0FD0D4F82C31D51807E00B68A6 -+:105960004822C5F8103123685868E1F3C1F1D5F831 -+:1059700010110029F3D101A82FF0B4DB0246002852 -+:10598000E5D106E00B684068C4F840314822E1F3F5 -+:10599000AFF1D4F8401120680029F3D1064922461E -+:1059A0000068FEF3D1F22368214658684FF4A472D0 -+:1059B000E1F39EF13EBDC04691BA8600F0B54FF4CA -+:1059C000A47185B005464068E1F382F1064608B946 -+:1059D000074655E000214FF4A4720746DCF330F38C -+:1059E000294B35600093294B29490193294B002409 -+:1059F00003932868284A33460294FEF36DF2314639 -+:105A00002A6B1368022B03D1537D0BB9163300E0C8 -+:105A1000302301340B744431042CF1D1A8681F49A0 -+:105A20002A460023E9F348F60446C6F8200130B9B7 -+:105A3000686831464FF4A472E1F35AF11FE04FF465 -+:105A40009673C6F81C3145F27353A6F838314FF0FF -+:105A50004603A6F83A31124B0024C6F840412846C6 -+:105A600000934FF48A710F4A0F4B019505F066F9C8 -+:105A7000A042C6F82C0103DA3046FFF74FFF274655 -+:105A8000384605B0F0BDC046F90C8400DD120100B7 -+:105A900094DB01007D0A840091BA86003D068400F3 -+:105AA000D9128400E5128400A512840010B50146C5 -+:105AB00020B10368B022D868E1F31AF110BDC046E6 -+:105AC0002DE9F34107680546B021F868E1F300F1DC -+:105AD000064608B980468BE00021B02201AC804622 -+:105AE000DCF3AEF20422002137607560C5F85C611A -+:105AF0002046DCF3A5F22A6892F87C30012B07D906 -+:105B00003D495069DCF364F7014690B120460AE054 -+:105B100050693A49DCF330F70928034609D8384977 -+:105B2000204601EB83010322DCF342F300238DF8CE -+:105B3000073001AC0322214606F10800DCF338F3FC -+:105B40000023F3722B682F495869DCF315F7396984 -+:105B5000F060CA6A41F26B039A420CD18B6A8B2BBC -+:105B600009D1022807D1204627490422DCF300F39B -+:105B700008B90323F360396941F26B03CA6A9A4298 -+:105B80000DD18B6A932B0AD101A820490422DCF3A2 -+:105B9000EFF220B9F368042B01D10233F36001AFB7 -+:105BA000284639461FF054DE044650B91849384695 -+:105BB0000322DCF3FDF2284639468DF807401FF03A -+:105BC00047DE05F5AA60394603220A30DCF3F0F21D -+:105BD000002405F5AA600F4985F85D450E300322C3 -+:105BE000DCF3E6F285F861453046394620F0BADA52 -+:105BF0004046BDE8FC81C046B3C48600B9C48600F7 -+:105C0000CE028600BCC48600C3C4860071C2860072 -+:105C1000C6C48600CAC4860070B50568044622461C -+:105C200028680449FEF390F1686821465022E1F3A8 -+:105C30005FF070BD3CE486002DE9FF410546502130 -+:105C40004068E1F345F0064608B904465AE00021F1 -+:105C500050220446DCF3F4F1FF210422356006F102 -+:105C60003B00DCF3EDF1284619F08ADD002790F8BF -+:105C7000483080F8387586F83B3096F840304FF061 -+:105C8000FF3843F00803202186F840301F4AC6F849 -+:105C9000488006F11800DCF317F27061304626F0F8 -+:105CA000B5DF042128461A4A1A4B0097019605F0E1 -+:105CB00045F8B84230611FDB174B02970093174B32 -+:105CC00017490193174B184A039328683346FEF38C -+:105CD00003F188B9012586F83A50304629F00ADAEE -+:105CE00018B13046294627F0FFD9A37BA4F84C8091 -+:105CF00043F00203A37305E0686831465022E0F3E5 -+:105D0000F7F70024204604B0BDE8F08140E48600A7 -+:105D10001DDF8400F9DE8400F51D01001DED840007 -+:105D200024E40100DDD084003CE4860070B5054623 -+:105D3000002826D00368134918682A46FEF304F1A8 -+:105D40006B6905E01C68596828462AF0E7DD2346A0 -+:105D5000002BF7D12B6905E01C68596828462AF00A -+:105D6000DDDD2346002BF7D1A96A21B12B689022F3 -+:105D70005868E0F3BDF72B68294658682C22E0F3F9 -+:105D8000B7F770BD91E6860030B52C21044685B08A -+:105D90004068E0F39DF708B9054618E000212C2281 -+:105DA0000546DCF34DF10823AB610A4B2C600093F0 -+:105DB0000023019302930393074A2B462068074967 -+:105DC000FEF38AF02268012382F896302B71284670 -+:105DD00005B030BD050B850091E6860004E50100A5 -+:105DE0002DE9F047154680460F461E46E5F346F07E -+:105DF000002181464046E5F313F200220446114695 -+:105E00000F480B185B6873B90C3302FB03F31D508A -+:105E10001A18636A576096600A4A45EA03031360DA -+:105E20006362012404E001320C31052AE8D1002428 -+:105E300040464946E5F3F4F12046BDE8F087C04608 -+:105E40003C260000782600002DE9F04705468846EC -+:105E5000E5F350F100212846E5F3E2F10646284635 -+:105E60006C69AF69E9F7E8FA0A2C814616D90F2C5C -+:105E700019D02846E9F768FD142C054603D9B36804 -+:105E800023F00803B360B36843F00103B36003D9A0 -+:105E9000B36843F00803B360012211E0022C02D87A -+:105EA000174D30220CE02846E9F758FDD6F8A4300B -+:105EB000054623F0FF0343F00203C6F8A430022294 -+:105EC000B36813F0010F07D107F01803082B14BFB4 -+:105ED0004FF4E115B5FBF2F507F0030700240BE0E2 -+:105EE00006F54073B8F1000F05D003EB04204946D6 -+:105EF0002A460023C0470134BC42F1DBBDE8F087ED -+:105F000000C63E0537B5134B1546136001E0114B33 -+:105F100013600432ADF17C039A42F8D3033020F0D1 -+:105F200003000D4BC0EB01041C600C4B00211960F9 -+:105F30000B4B05F5A05219600A4B083C19600A4B3F -+:105F400041601D60094B1A60094B1960094B0460E0 -+:105F500058603EBD4B415453C826000088260000BF -+:105F6000A4260000CC260000F8270200FC2702002F -+:105F700090260000C0260000436910B5142B01DDF7 -+:105F800002F09CFB10BDC0461FB5E8200021E0F3E5 -+:105F90003DF20C4C2060A0B10021E822DCF350F06F -+:105FA00004AA012342F8043D013B0093064B2168FB -+:105FB000186840F23C73DCF38FF620680E21DCF3A6 -+:105FC000D5F61FBDBC26000024280200B1F5E06F05 -+:105FD00073B505460C46164606D1036900910021AB -+:105FE00001911C680A460CE00D4B00221868E5F38D -+:105FF00005F1014680B12B690022009401921C68D2 -+:1060000028463346A04738B1064AA86113680020E5 -+:106010002B626E61156001E04FF0FF307CBDC04621 -+:106020008C260000202802002DE9F04710200E46A3 -+:10603000002117469946E0F3E9F1044610B96FF0E4 -+:106040001A001EE0104D2868E4F318F7099B8046FB -+:1060500023B9286831463A46E5F3D0F02868E4F3DE -+:1060600089F701238340094AE360089BC4F8049040 -+:10607000A36013682868236041461460E5F3D0F0FC -+:106080000020BDE8F087C0468C260000982600005E -+:1060900007B50021E5F3C4F0074B4FF40061186029 -+:1060A000064B00F57060186000200246044B00901B -+:1060B0000190FFF7B9FF0EBD9C260000F4270200F7 -+:1060C0006D60800037B5234B234C02AD00211C22AC -+:1060D00045F8043D2046DBF3B3F7012323601F4B53 -+:1060E000A5F5A0551B6843F8044C00F00DF92946AE -+:1060F0002A461B48FFF706FFE0F344F300F042F89E -+:10610000002002F01FFA174B174C186002F0BCFC7D -+:106110002060FFF7BDFF206800F01EF9E9F716F8D0 -+:10612000206800F0A5F8002210481149E0F3E2F4DD -+:10613000002210481049E0F3DDF410490022104815 -+:10614000E0F3D8F42068FFF717FFFFF71DFF206882 -+:106150003EBDC046ADDEADDE00280200F81E0200E6 -+:1061600000590300242802008C260000D81F860056 -+:1061700059EF0000DB1F8600656580008D608000A0 -+:10618000DE1F860070B5A4200021E0F33FF1124D20 -+:10619000286080B10021A422DBF352F74FF4806025 -+:1061A00000212C68E0F332F1A060286884682CB9E3 -+:1061B000E0F392F02C604FF0FF300CE04FF480627F -+:1061C000C2608460446100212046DBF339F72A680D -+:1061D000024B00201A6070BD38280200D42600004F -+:1061E00070B51C4D06462B6833B91B4C23680BB9A0 -+:1061F000FFF7C8FF23682B60164C184B20685861C6 -+:1062000030B3002505604560336CC0F89C500E3BF0 -+:10621000012B03D930461249FFF716FE114A936845 -+:1062200013B12368C3F89C20246807E0D4F89C00CD -+:1062300018B1A368595DE0F349F4013523699D4223 -+:10624000F4D3094809492246E0F354F4014B186895 -+:1062500070BDC046D4260000382802000028020085 -+:106260009562020028280200BD218600A5688000F2 -+:1062700010B54022002305490446FFF7B1FD044B49 -+:1062800000229A602046FFF7ABFF10BDA96980008D -+:106290002828020070B51B4DAE68002E31D11409BC -+:1062A0002C60AB8104F561444FF4E13394FBF3F4CB -+:1062B000A8606960284603218022E0F3FDF32846A8 -+:1062C0003146E2B2E0F3F8F3284601212212E0F36E -+:1062D000F3F303210A462846E0F3EEF301210A46D0 -+:1062E0002846E0F3E9F3284604210822E0F3E4F32A -+:1062F000284602210122E0F3DFF34FF47A70E0F345 -+:106300002BF270BD28280200104A0721136843F0C1 -+:1063100010031360136843F008031360136823F439 -+:1063200000731360E832136843F0807343F48033E2 -+:106330001360074B00221960043B1A6008331A6887 -+:106340001960044B20221A607047C04614ED00E02B -+:10635000241000E000E400E02DE9F041054600F0E3 -+:10636000ADF82A48E8F778FC2846E9F73BF8284BCF -+:10637000284AC318B3FBF2F3274A28461360E9F70B -+:10638000D9FA00F5787007304FF47A73B0FBF3F068 -+:10639000224B234A18602B6A2249002BCCBF6FF096 -+:1063A0007F4340F2FF3313601D4A1F4F1368B3FB56 -+:1063B000F0F31360284620220023FFF711FD002090 -+:1063C0001A49DCF3D9F204463860E8B12846E9F707 -+:1063D00009F8B4FBF0F0861E002E15DD144C0021E8 -+:1063E00034222046DBF32CF6124B4FF47A71A36073 -+:1063F0006560204606FB01F10122DFF3FBF618B1D0 -+:1064000028463968DEF306F2BDE8F08191F100001C -+:106410003F420F0040420F00D0250000C825000079 -+:10642000CC25000001678000E8260000BEE60100E0 -+:1064300040280200E56680002DE9F04707461E4629 -+:1064400015460C46E4F356F63846E4F317F52946AC -+:10645000324681463846E4F3D1F63846E4F38AF50D -+:1064600040F62A01064600223846E4F3C7F6054600 -+:106470008CB1012414FA06F3826932EA030802D1CE -+:106480002046E8F7A9FB701C14FA00F0E8F786FB39 -+:10649000C5F818800CE00124701C14FA00F0E8F72D -+:1064A0009BFB2046B440E8F779FBAB691C43AC6129 -+:1064B00038464946E4F3B4F6BDE8F0872DE9F047E5 -+:1064C0000746E4F317F6384640F60E010022E4F3DF -+:1064D00095F60446002831D0D0F80080056838468B -+:1064E000E4F3DEF40428064604D827D1C5F30243BA -+:1064F000032B23D100204849DCF33EF2F0B9474991 -+:10650000C8F3031212E0013A072E22610AD90C2EB9 -+:1065100008D0236C13F4806F02D013F4006F01D104 -+:1065200008B903E0012041F004516161002AEAD179 -+:10653000D4F8E83123F01003C4F8E831002240F623 -+:106540002A013846E4F35AF6354C20603846E4F325 -+:10655000A7F4344B22681860136843F6A12443F073 -+:1065600080731360136843F0020313600023C2F8C2 -+:10657000E03103E00A20E0F3EFF00A3CDFF8A090FE -+:10658000D9F80030D3F8E03113F4003F01D1092CE1 -+:10659000F0D100210B4638464FF40062FFF74CFF64 -+:1065A00000210B46384640F61202FFF745FF002156 -+:1065B0000B46384640F62902FFF73EFF38460121D8 -+:1065C000E8F73EFF00201849DCF3D6F1E0B1384689 -+:1065D000E4F354F440F62A01804600223846E4F3FE -+:1065E0000DF646690446D0F898503846E4F346F470 -+:1065F0000123834045F00105334363613846C4F805 -+:1066000098504146E4F30CF6D9F80020136A43F0A1 -+:1066100003031362BDE8F0872DE70100FF7F01004F -+:106620007428020078280200BEE6010010B58469D3 -+:10663000A068FCF729FCE068E9F7E4F8002010BD49 -+:1066400010B584690021342204F11C00DBF3F8F456 -+:10665000034BA06863622462EBF794F8002010BD3E -+:1066600005AA80002DE9F347DFF8AC809946D8F8F9 -+:1066700000300546072B0F46924643DC01F062FFCF -+:1066800050210646E0F324F3044600283AD00021C6 -+:106690005022DBF3D5F4D8F8003065602360A4F80D -+:1066A00014902761E660204641F2E4414A463346B1 -+:1066B0000097CDF804A0FCF739FCA06010B30020CF -+:1066C0000A990B9A114B0095CDF804A0FFF7ACFC8A -+:1066D00018B1A068FCF7D8FB14E0A068E2F3B4F6A8 -+:1066E0000B49A061D8F800202846DBF3FDF40948E7 -+:1066F0002946EAF7D9FFD8F8003020460133C8F818 -+:10670000003000E00020BDE8FC87C04631AA8000D0 -+:106710005CB102003CB102007C280200014610B5C9 -+:1067200050228068E0F3E4F210BDC046C36B10B5A0 -+:106730001BB100225A62836B5A62C068FFF7EEFFFA -+:1067400010BDC0462DE9F041184E1C46337807466F -+:10675000072B904626D820464C21E0F3B9F2054697 -+:1067600000B300214C22DBF36BF46C602F60C5F8A2 -+:1067700008803378204685F8443001333370022393 -+:10678000AB640821E0F3A4F20446286420B10021A0 -+:106790000822DBF355F406E029464C22E0F3A8F288 -+:1067A000254600E000252846BDE8F081802802004B -+:1067B0002DE9F04FD1F8FC3091B00F93054603F569 -+:1067C0006063079335E10FAF0E2200232846394658 -+:1067D000D9F37AF60F28044600F0368100222846C5 -+:1067E00039461346D9F370F610F00E0640F02681B4 -+:1067F00040F23B43B3EB145FC4F30B21C0F3041826 -+:1068000004D140F6FF73994200F01381C0F3442293 -+:106810000992002A00F00D81C0F3C443C0F3843B09 -+:1068200013EB0B02089319D140F26733994240F001 -+:1068300000810EAB01930DAB02930CAB03930BAB3A -+:1068400004932846394613460092D9F3DBF5002815 -+:1068500000F0EF800E9BC5F85433EAE0D5F8CCA0E9 -+:1068600005EB8A03C3F8D4423446C3F81403C3F8D3 -+:10687000D0100BE00122284631461346D9F324F606 -+:1068800000F00E00022840F0D980013444450FAEDC -+:10689000F0D1002213460DF138090DF134080CAF88 -+:1068A0000BAC284631460092CDF80490CDF8088014 -+:1068B00003970494D9F3A6F50246E8B94023009360 -+:1068C000284631461346CDF80490CDF8088003974A -+:1068D0000494D9F397F510B14FF001080EE00D9B29 -+:1068E000002B40F0AB800B9B002B40F0A7800C9B53 -+:1068F000B3F5805F40F0A2804FF000080E9A05EBE0 -+:106900008A03C3F810210C9A0124C3F8D0210EABDE -+:1069100001930DAB02930CAB03930BAB00220493DA -+:1069200028460FA923460092D9F36CF508B9012730 -+:1069300027E0012C40F086800C99B1F5805F40F093 -+:1069400081800E9B05EB8A02C2F89031C2F81012CA -+:1069500078E00024002300930EAB01930DAB02936B -+:106960000CAB03930BAB049328460FA93A4623467E -+:10697000661CD9F347F508B13446EBE7002E5DD02D -+:106980000137099A9742E4D100241FE0C023009305 -+:106990000EAB01930DAB02930CAB03930BAB0493C3 -+:1069A00028460FA922460023D9F32CF5002845D00C -+:1069B0000B9B002B42D10C9BB3F5805F3ED124B9D9 -+:1069C0000E9B05EB8A02C2F8943201345C45DDD19E -+:1069D000002423E0802300930EAB01930DAB0293C0 -+:1069E0000CAB03930BAB049328460FA9012F0CBFEC -+:1069F0002246621C0023D9F305F5F8B10B9BEBB9D5 -+:106A00000C9BB3F5805F19D1BBF1000F05D124B900 -+:106A10000E9B05EB8A02C2F894320134089B9C421B -+:106A2000D8D1B8F1000F04D1D5F8CC300133C5F876 -+:106A3000CC300F9B079A9342FFF4C5AE0023C5F8F4 -+:106A4000CC3001E0013462E711B0BDE8F08FC04600 -+:106A500082604160016070470EB4F3B581680646FC -+:106A6000012901D8002044E008AB4068079A01934F -+:106A7000DBF31CF4B0F1FF3F074603D0B368023BE1 -+:106A8000984203DD00231846B36032E070683D2170 -+:106A9000DBF33AF330B373683568C3EB00041EE0F0 -+:106AA00028462246DBF34CF2A8B92B5D3D2B12D1D0 -+:106AB0002846DBF355F37268441CBA1829190132D1 -+:106AC0002846521ADBF38EF273681B1B7360B3689F -+:106AD0001B19B36006E015F8013B002BFBD1716870 -+:106AE0008D42DDD3B368781C1B1AB36073681B1822 -+:106AF0007360BDE8FC4003B07047C0462DE9F0412B -+:106B0000C1EB0204012C0E461F46DDF8188010DD93 -+:106B10002146E0F3DDF0054610B96FF01A000DE0F4 -+:106B200031462246DBF328F200203D60C8F80040E1 -+:106B300004E000233B60C8F800301846BDE8F0814F -+:106B40002DE9F04FA5B008914FF4805109900792BC -+:106B50000693E0F3BDF00A9018B96FF0010401F05C -+:106B600029B921A80A994FF48052FFF771FF4FF419 -+:106B700080520A980021DBF363F200234FF0FF32CA -+:106B80008DF844300B930D930E9201F0DEB80D9BFF -+:106B9000089A002152F8239001230C910F930F9B28 -+:106BA00019F8012073B1531EDBB2FD2B01F101086E -+:106BB00098BF19F808B016468CBF4FF0000B08F1CB -+:106BC00001080CE002F1FF33DBB2FE2B93462CBF31 -+:106BD0001646802628BF4FF0000B01F101080BEB91 -+:106BE0000803B3F5607F81F2AD80202E2AD005D84E -+:106BF000152E0AD01B2E6DD001F078B8222E3AD077 -+:106C000036D3802E72D001F071B808EB09035A78A0 -+:106C100019F8083003EB0223072B13DD09F10204F6 -+:106C2000444421AD874922462846FFF715FF2046F8 -+:106C3000DBF396F209F1030200EB080382492846D0 -+:106C4000D2184FE008EB0904637819F8082021AD49 -+:106C500002EB032228467D49FFF7FEFEE378A27887 -+:106C600028467B4902EB0322FFF7F6FE01F03EB80F -+:106C700019F8082003E00C9B0C2B03D100220C9286 -+:106C800001F036B89DF84430002B41F0318019F8FE -+:106C90000830042B41F02C8009F1020404EB0805B4 -+:106CA0002846DBF359F6002841F0228014F808301A -+:106CB00013F0010F41F01C80284611A9DBF394F476 -+:106CC0000E9BB3F1FF3F41F0138008EB09039A7963 -+:106CD000DB790DE108EB0903DC799A795D4921A89C -+:106CE00042EA0422FFF7B8FE01F002B819F80830B2 -+:106CF000822B00F2FD87DFE813F09200B300380129 -+:106D00003B02D4021102CB01DA014701EA02FB0285 -+:106D100010031703FB077F020302FB073603570329 -+:106D200097007A037F0390039503F700E903FB07BD -+:106D3000770107047F01FB07FB07FB071004220410 -+:106D4000270472045305FB07FB0721068D0088000A -+:106D50008300AE06D306DA06E106FB0726037101BF -+:106D6000FB07FB070001F007E806FB07FB07FB0733 -+:106D7000FB07FB07FB07FB07FB0787011307280738 -+:106D8000490764077F079907B307CD07D407FB07B7 -+:106D90008E01FB07FB07FB07FB07FB07FB07FB0756 -+:106DA000FB07FB07FB07FB07FB07FB07FB07FB07D3 -+:106DB000FB07FB07FB07FB07FB07FB07FB07FB07C3 -+:106DC000FB07FB07FB07FB07FB07FB07FB07FB07B3 -+:106DD000FB07FB07FB07FB07FB07FB07FB07FB07A3 -+:106DE000FB07FB07FB07FB07FB07FB07FB07FB0793 -+:106DF000FB07FB07FB07FB07FB07FB07FB07DE07A0 -+:106E000009EB0804002500F00BBE09EB080400257F -+:106E100000F0F4BD09EB0804002500F0DEBD0E49CA -+:106E200008EB090321A8DDE008EB0901CA780B791A -+:106E3000120442EA03624B7821A81A438B7807496F -+:106E40007EE2C04640B202009CB40200FEB10200E5 -+:106E500093B5020062B80200D9B3020075B1020016 -+:106E600008EB0904A378627821AE02EB0322AE4955 -+:106E70003046FFF7F1FD2379E2783046AB4902EB6B -+:106E80000322FFF7E9FDBBF1060F40F23187A3793A -+:106E900062793046A64902EB0322FFF7DDFDBBF124 -+:106EA000080F40F22587237AE2793046A14902EBA8 -+:106EB0000322FFF7D1FDBBF10A0F40F2198709F158 -+:106EC0000A0409F1090514F8083015F808209A4950 -+:106ED00002EB03223046FFF7BFFD14F8083015F827 -+:106EE0000820964930464CE008EB09039A785B7815 -+:106EF00003EB02220E9200F0FBBE0623904ABBFB7E -+:106F0000F3F309EB08074FF0000A137027E019ADFF -+:106F1000534610218B4A1DAE2846DBF3D5F053466D -+:106F20001021894A3046DBF3CFF0BB787A7821AC68 -+:106F300042EA032229462046FFF78EFD7A79BB7983 -+:106F4000120442EA0362FB7820461A433B79314639 -+:106F500042EA0322FFF780FD0AF1010A0637784B67 -+:106F60001B789A45D3DB00F0C3BEBBF1020F21A80A -+:106F700008EB090202D175495278B3E69378734958 -+:106F8000527802EB0322ADE608EB0904A27863789D -+:106F9000BBF1040F03EB022505D92379E2781B0628 -+:106FA00003EB02431D4321AE304669492A46FFF7F1 -+:106FB00053FDBBF1060F40F29B86A2796379BBF1CA -+:106FC000080F03EB022505D9237AE2791B0603EBB0 -+:106FD00002431D435F4930462A4683E65E4908EB7B -+:106FE000090321A85A787DE608EB09039C785A78B2 -+:106FF000524921A800F05BBE0BF101035FFA83FB4D -+:1070000000230F9300F074BE08EB09039C785A78B4 -+:10701000524921A864E64A4B4FEADB0209EB080714 -+:107020004FF0000A1A702DE01DAD53461021454A5D -+:1070300019AE2846DBF348F053461021424A304649 -+:10704000DBF342F0FA783B79120442EA03627B7880 -+:1070500021AC1A43BB78294642EA03222046FFF7B7 -+:10706000FBFCFA793B7A120442EA03627B79204600 -+:107070001A43BB79314642EA0322FFF7EDFC0AF1DD -+:10708000010A08372E4B1B789A45CDDB00F030BE45 -+:1070900021AD08EB0904284631496278FFF7DCFC92 -+:1070A000BBF1020F40F224862E49284659E121AD5A -+:1070B00008EB0904002228462B496378FFF7CCFC33 -+:1070C000BBF1020F40F20F86012228462649A37821 -+:1070D000FFF7C2FCBBF1030F00F005860222284631 -+:1070E0002149E378FFF7B8FCBBF1040F00F0FB8502 -+:1070F00028461D4903222379FFF7AEFC00F0F3BDBB -+:1071000021AC08EB090517496A782046FFF7A4FC73 -+:107110001549AB782046012200F0DCBD134908EB8D -+:10712000090321A85EE7C046B4B6020075B70200A5 -+:10713000BEB502000AB2020021B3020021B2020071 -+:107140008128020038E7010043E7010056B302003E -+:1071500037B7020082B2020054B40200CAB702007C -+:1071600081B10200ACB7020081B4020045B8020050 -+:10717000ABF10203082B00F2BB85DFE813F0090036 -+:10718000B905B905B905B9052B001C0015000E009D -+:10719000A74908EB090321A824E708EB090321A864 -+:1071A000A4495A7AFFF758FC08EB090321A8A04923 -+:1071B0001A7AFFF751FC09F1070521AC9E4915F831 -+:1071C00008202046FFF748FC20469C4915F8082077 -+:1071D000FFF742FC9A4D09EB0804A3786278294630 -+:1071E00002EB032221A8FFF737FC964B0935023446 -+:1071F0009D42F2D100F07CBDBBF1140F19D0BBF160 -+:10720000170F04D0BBF1130F1AD000F071BD21ACE1 -+:1072100008EB09058C49AA7D2046FFF71DFC8B4928 -+:107220006A7D2046FFF718FC204689492A7DFFF732 -+:1072300013FC08EB090321A88649DA7CFFF70CFC54 -+:10724000854D09EB0804A3786278294602EB0322F6 -+:1072500021A8FFF701FC814B093502349D42F2D190 -+:1072600009EB08057E4E2C46237AE279314602EB83 -+:10727000032221A8FFF7F0FB7A4B0B3602349E4223 -+:10728000F2D1794CAB7B6A7B214602EB032221A829 -+:10729000FFF7E2FB754B0B3402359C42F2D100F054 -+:1072A00027BD08EB0901C8784A788B7800900879E7 -+:1072B00001904879029088790390C8790490097AFE -+:1072C00021A805916A49FFF7C7FB00F011BD09EB42 -+:1072D000080400256378FF2B04D021A865492A46BD -+:1072E000FFF7BAFB01350134042DF3D100F000BDE6 -+:1072F00008EB09035A780AB19B7823B921A85E49A3 -+:10730000FFF7AAFB03E021A85C49FFF7A5FB08EB08 -+:1073100009035B49DA7821A8E4E408EB09039C78C7 -+:107320005A78584921A8DBE408EB0901CA780B799F -+:10733000120442EA03624B7821A81A438B7852491F -+:1073400042EA0322CEE421AD08EB090428464F4966 -+:107350006278FFF781FBBBF1020F40F2C9844C4910 -+:107360002846A278BEE409F1010515F8082021ACF1 -+:10737000484902F00F022046FFF76EFB15F808207F -+:107380004549120909F102052046FFF765FB15F88A -+:107390000820424902F007022046FFF75DFB15F87E -+:1073A00008203F4920461FE009F1010515F8082093 -+:1073B00021AC3C4902F00F022046FFF74DFB15F8C7 -+:1073C00008203949120909F102052046FFF744FB5C -+:1073D00015F80820354902F007022046FFF73CFB6C -+:1073E00015F8082032492046C2F3C1027AE4314937 -+:1073F00008EB090321A8F5E521AC08EB09052E49A6 -+:107400006A782046FFF728FB2C49AA782046FFF728 -+:1074100023FB2B49EA78204664E42A4908EB090358 -+:1074200021A8DFE5284908EB090321A8DAE5C046D1 -+:10743000ECB60200ADB602009FB50200E3B1020057 -+:1074400022B402003DB40200D4B10200EDB2020049 -+:1074500049B30200F1B1020002B602001DB60200FB -+:10746000EEB302000FB40200F9B602001AB7020030 -+:1074700050B7020097B1020025B802003AB80200E6 -+:1074800058B802005DB4020004B80200B6B70200AA -+:10749000E4B3020068B102003DB40200B3B10200DF -+:1074A00047B7020091B7020075B20200F7B70200B9 -+:1074B000C1B7020010B8020068B40200A4B602000E -+:1074C0004AB4020046B502000AB3020009F1010401 -+:1074D00004EB08052846DBF33FF2002840F008845F -+:1074E00014F8083013F0010F40F00284284611A967 -+:1074F000DBF37AF00E9BB3F1FF3F40F0F98308EB2A -+:1075000009035A799B79F3E408EB09039A785C78CC -+:107510008C49120621A8FFF7E3BB08EB090421AD53 -+:10752000894962782846FFF797FA8849A278284661 -+:10753000FFF792FA2379E2788549284621E58549C3 -+:1075400008EB090321A84DE508EB0906B378747828 -+:1075500021AD04EB0324A4B2E20A7F492846FFF7D9 -+:107560007BFA7E49C4F302222846FFF775FA7C496C -+:10757000C4F3C4022846FFF76FFA7A49C4F3410204 -+:107580002846FFF769FA2846774904F00102FFF719 -+:1075900063FABBF1040F40F2AB833379F47873499B -+:1075A00004EB0324A4B2E20A2846FFF755FA704917 -+:1075B000C4F302222846FFF74FFA6E49C4F3C4020F -+:1075C0002846FFF749FA6C49C4F341022846FFF701 -+:1075D00043FA6A49284604F00102FFF783BB08EB2F -+:1075E000090621AF664972783846FFF735FA4FF041 -+:1075F000000A6449B2783846FFF72EFACDF800A0A9 -+:107600003279F378604903EB022301930222534657 -+:107610003846FFF721FACDF800A0B27973795A49BC -+:1076200003EB02230193022201233846FFF714FAE9 -+:10763000CDF800A0327AF379384603EB0223022218 -+:10764000019351491346FFF707FABBF11E0F40F2B1 -+:107650004F834E49727A3846FFF7FEF94C49B27AA9 -+:107660003846FFF7F9F94B49F27A3846FFF7F4F953 -+:107670004949327B3846FFF7EFF9CDF800A0B27BDD -+:10768000737B414903EB022301930522534638469D -+:10769000FFF7E2F9CDF800A0327CF37B3A4903EB27 -+:1076A00002230193052201233846FFF7D5F9CDF8CF -+:1076B00000A0B27C737C344903EB022301930522C2 -+:1076C00002233846FFF7C8F9CDF800A0CDF804A092 -+:1076D000327DF37C314903EB0223029305226C23B4 -+:1076E00001253846FFF7B8F90095CDF804A0B27D22 -+:1076F000737D2A4903EB0223029305226C2338464B -+:107700000224FFF7A9F90094CDF804A0327EF37D9E -+:10771000224903EB0223029305226C233846FFF72C -+:107720009BF9CDF800A0CDF804A0B27E737E384658 -+:1077300003EB02230293194905226823FFF78CF912 -+:107740000095DFE0D7B5020086B5020050B5020013 -+:1077500077B502002BB70200E7B7020093B2020030 -+:10776000A0B2020071B80200A4B1020046B6020045 -+:107770008EB80200C1B802008BB40200D8B7020074 -+:10778000E3B102005DB5020080B702002AB6020034 -+:107790002FB30200E4B5020048B202000FB40200A9 -+:1077A00008EB090621AFAF4972783846FFF754F964 -+:1077B0004FF0010AAC49B2783846FFF74DF9CDF8E1 -+:1077C00000A03279F378A94903EB02230193022246 -+:1077D00000233846FFF740F9CDF800A0B27973795D -+:1077E000A24903EB02230193022253463846FFF7D6 -+:1077F00033F9CDF800A0327AF379384603EB02234F -+:107800000222019399491346FFF726F9BBF11E0F97 -+:1078100040F26E829649727A3846FFF71DF9954913 -+:10782000B27A3846FFF718F99349F27A3846FFF7EB -+:1078300013F99249327B3846FFF70EF9CDF800A0D4 -+:10784000B27B737B894903EB02230193052200235A -+:107850003846FFF701F9CDF800A0327CF37B83496D -+:1078600003EB02230193052253463846FFF7F4F851 -+:10787000CDF800A0B27C737C7C4903EB022301931A -+:107880000522022300253846FFF7E6F80095CDF8DB -+:1078900004A0327DF37C7A4903EB02230293052294 -+:1078A0006C233846FFF7D8F8CDF800A0CDF804A037 -+:1078B000B27D737D724903EB0223029305226C2390 -+:1078C00038460224FFF7C8F80094CDF804A0327EB1 -+:1078D000F37D6B4903EB0223029305226C233846A8 -+:1078E000FFF7BAF80095CDF804A0B27E737E384653 -+:1078F00003EB02230293624905226823FFF7ACF8E9 -+:10790000CDF800A0CDF804A0327FF37E384603EB1B -+:1079100002230293052268235949FFF79DF800943A -+:10792000CDF804A0B27F737F384603EB02230293A5 -+:10793000534905226823FFF78FF8D9E108EB0904C2 -+:10794000A378627821AD02EB03224E492846FFF767 -+:1079500083F86279A379120402EB0362E378284684 -+:10796000D2182379484902EB0322FFF775F8BBF1DF -+:10797000120F40F2BD81627AA37A120402EB036215 -+:10798000E3794249D218237A284602EB0322FFF713 -+:1079900063F8627BA37B120402EB0362E37A28465E -+:1079A000D218237B3A4902EB0322FFF755F8627C99 -+:1079B000A37C120402EB0362E37BD218237CABE0CE -+:1079C000A278637821A803EB0223009331492B4668 -+:1079D0000222FFF741F801350234B5EB5B0FEFDD12 -+:1079E00086E1A278637821A803EB0223009329495A -+:1079F0002B460522FFF730F801350234B5EB5B0F5B -+:107A0000EFDD75E10095A278637821A803EB0223EE -+:107A10000193214905226C23FFF71EF8013502343A -+:107A20004FEA9B06B542EDDD002411E008EB5B0355 -+:107A30004B44009403EB44039A785B7821A803EB52 -+:107A400002230193144905226823FFF705F8013446 -+:107A5000B442EBDD4CE108EB09039C785A780F49FE -+:107A600021A824E1FCB202006AB5020080B702003E -+:107A700038B602003CB30200F3B5020057B2020070 -+:107A80000FB402004BB802009EB70200C9B5020055 -+:107A900066B2020030B2020056B60200ABB4020079 -+:107AA00008EB09039C785A78934921A8FFE008EB7A -+:107AB00009039C785A78914921A8F8E008EB09035A -+:107AC0009C785A788E4921A8F1E008EB0904E27805 -+:107AD0002379120402EB0362637821ADD218A378F4 -+:107AE000884902EB03222846FEF7B6FFE279237AA3 -+:107AF000120402EB036263792846D218A379824903 -+:107B000002EB0322FEF7A8FFE27A237B120402EBCA -+:107B10000362637AD218A37A7C492846FFF731BA08 -+:107B200008EB0904A378627821AD2846784902EB76 -+:107B30000322FEF791FFBBF1040F40F2D9802379B5 -+:107B4000E27874492846FFF71CBA08EB0904E2788A -+:107B50002379120402EB0362637821ADD218A37873 -+:107B600028466D4902EB0322FEF776FFBBF1060FB4 -+:107B700040F2BE80E279237A120402EB0362637959 -+:107B80006649D218A3792846FFF7FBB9644E09EB82 -+:107B900008040225AB45C0F2AB80E27823791204D9 -+:107BA00002EB036263783146D218A37821A802EB76 -+:107BB00003220435FEF750FF043418361A2DE9D19C -+:107BC00096E0584E09EB08040225AB45C0F29080C0 -+:107BD000E2782379120402EB036263783146D2180B -+:107BE000A37821A802EB03220435FEF735FF043405 -+:107BF00013360E2DE9D17BE04B4E09EB080402252C -+:107C0000AB4575DBE2782379120402EB03626378FB -+:107C10003146D218A37821A802EB03220435FEF7DF -+:107C20001BFF043414360E2DEAD161E03F4E09EB00 -+:107C300008040225AB455BDBE2782379120402EBF2 -+:107C4000036263783146D218A37821A802EB03229D -+:107C50000435FEF701FF043414360E2DEAD147E057 -+:107C6000334E09EB08040225AB4541DBE27823796A -+:107C7000120402EB036263783146D218A37821A87C -+:107C800002EB03220435FEF7E7FE043414360E2D12 -+:107C9000EAD12DE008EB09039C785A78254921A800 -+:107CA00005E008EB09039C785A78234921A802EBE8 -+:107CB0000422FFF717B808EB0901CB780A791B04F7 -+:107CC00003EB02634A788C789B181C4921A8012297 -+:107CD00003EB0423FEF7C0FE0AE0194908EB090391 -+:107CE00021A8FFF77FB901220B9201E0FF2E29D0D6 -+:107CF0000BEB0801FEF753BF19B802008BB102006D -+:107D00001DB60200C9B5020066B2020072B40200DC -+:107D10009BB80200AEB80200C0B60200D6B60200A0 -+:107D2000B6B4020064B30200B1B202009DB3020017 -+:107D300068B6020014B30200C0B102001AB7020014 -+:107D4000ACB502000D9B01330D930D9A079B9A422F -+:107D50007EF41DAF0E9AB2F1FF3F03D021A8174960 -+:107D6000FEF77AFE9DF8443023B121A8144911AAE8 -+:107D7000FEF772FE00201349DAF32AF638B90B9B9E -+:107D80002BB91A4621A81049FF33FEF765FE229A47 -+:107D9000002302F8013B2E9B0A9900930998069B49 -+:107DA0002292FEF7ABFE0A9904464FF480520998DE -+:107DB000DEF39EF7204625B0BDE8F08F82B80200C2 -+:107DC0002FB802000E5D860081B402002DE9F04F4D -+:107DD0009A468FB000230D936D4B06461C7889465A -+:107DE0000592002C40F0C180142208A82146DAF345 -+:107DF00027F17369232B05DC01224FF0040B069455 -+:107E0000079214E01C222346304621460094E3F3F7 -+:107E10003DF00028ACBF03230123ACBF00220122A8 -+:107E200007930692ACBF4FF00C0B4FF0020B30469D -+:107E3000E2F3E0F70128054602D0022806D013E05D -+:107E400030464946DAF330F040000CE03046FAF7AD -+:107E500047FF044640B1D9F3D5F710F4807F03D033 -+:107E60002046D9F3C5F70D900D99002900F08480C4 -+:107E70004846DEF32DF7044610B96FF01A0083E090 -+:107E8000012D0746DDF8348003D0022D0ED00025E9 -+:107E90001CE0002102900091CDF80480039130464F -+:107EA000059A4B46D9F3FAF705460DE00EAB4FEABB -+:107EB000580243F8042D304601212246D9F356F7E3 -+:107EC0000D9B05465B000D93002D45D123884FF691 -+:107ED000FD72013B9BB2934205D94846214642467A -+:107EE000DEF306F74AE0069B1BB104EB4B03089355 -+:107EF00015E0638804EB0B01227901EB132303EBFC -+:107F00000223A3F580530993E3880891CB18A3F5C6 -+:107F100080530A932389C918A1F580510B91DDB9CB -+:107F2000189A4846009208A9079A5346FEF708FE99 -+:107F300090B91849DAF320F538B1189B3046DAF8D1 -+:107F400000101A6800F024FB06E0189B3046DAF8AF -+:107F500000101A6800F004FB27B148463946424633 -+:107F6000DEF3C6F60A4B01221A700023189A18464F -+:107F7000CAF80030136007E00D468846064B00271C -+:107F8000089301230793CAE70FB0BDE8F08FC046FE -+:107F9000402700004EE7010019B2020013B5049C0F -+:107FA0009E4605994CB141B1002323600B600091BE -+:107FB00023467146FFF70AFF00E000201CBDC046C3 -+:107FC000094A13888B4201D1002206E093888B4234 -+:107FD00002D04FF0FF3005E00122034B03EB820398 -+:107FE00093F902007047C0461CB902002DE9F04128 -+:107FF000074614461E46002B7ED0E7F783FA054657 -+:1080000002E0B34205D00C35002D75D02B88002B33 -+:10801000F7D12B88002B6FD0D4F80036AA78C3F3A1 -+:108020008403934268D0D4F81836642023F0C073D8 -+:10803000C4F81836D4F81C3643F6A12623F0C073D2 -+:10804000C4F81C36DEF388F303E00A20DEF384F381 -+:108050000A3ED4F8E03113F4003F01D0092EF4D1E8 -+:108060000023C4F86036EA782B79D4F864161B062E -+:10807000120502F4700203F07063134321F07F6174 -+:108080000B43C4F864360223C4F86036D4F864366F -+:108090006A7923F0FE5323F4781343EA025343F43E -+:1080A0008023C4F864360323C4F86036D4F8642609 -+:1080B000AB6802F07F4223F07F431343C4F8643679 -+:1080C0003B6A012B05DDD4F8003643F48063C4F825 -+:1080D0000036AA782988D4F8000692004FF68373F8 -+:1080E0007F3102F07C0200EA0303C9111A4301390F -+:1080F00042EA0142C4F80026BDE8F081036A70B587 -+:10810000092B054601DC00242CE0E2F3B7F6002140 -+:1081100006462846E3F384F0D0F80836044613F404 -+:10812000807001D1044619E04FF00043C4F86C366A -+:108130004FF47A70DEF310F3D4F86C360022DB04CF -+:10814000DB0C5B03C4F86C2603F54243064A03F5D7 -+:10815000A873B3FBF2F3642203FB02F42846314612 -+:10816000E3F35EF0204670BDA086010070B50446C2 -+:10817000E2F384F6002105462046E3F351F0236A3A -+:10818000012B04D1D0F8003623F4007304E005DDA0 -+:10819000D0F8003643F40073C0F800362046294674 -+:1081A000E3F33EF070BDC0462DE9F04104461646AB -+:1081B0000D46E2F363F6002180462046E3F330F0FB -+:1081C0002946024633462046FFF710FF2046414627 -+:1081D000E3F326F0BDE8F0812DE9F043002485B0FB -+:1081E000074603940294E2F349F621468146384655 -+:1081F000E3F316F07B6A4E4A0546C3F3042605E016 -+:10820000137AC5F82036D368C5F82836494B083AA2 -+:108210009A42F5D14FF0000820E008216846464A0E -+:108220004346D9F351F700206946DAF3D1F398B108 -+:1082300000210A46DAF38CF23B6A0C2B08DDB0F51C -+:10824000803F05D200F0FF02C0F3072342EA03405B -+:10825000C5F82086C5F8280608F10108B045DCD12C -+:10826000364C28E0E36A13B13846984710B3002132 -+:108270001EE001238B40226A134218D0C5F8201655 -+:1082800094F924302BB1012B05D0B3F1FF3F07D077 -+:108290000DE0A36A09E0D5F82436A26A134304E08E -+:1082A000D5F82436A26A23EA0203C5F82436013140 -+:1082B000B142DED1103C224B9C42D3D1002614E0C7 -+:1082C000082168461F4A3346D9F3FEF60020694666 -+:1082D0006C46DAF37DF338B10021C5F820660A4612 -+:1082E000DAF336F2C5F8240601364645E8D103A98B -+:1082F00002AA3846DDF31CF5029B039941EA03020A -+:10830000D5F81C3642EA0303C5F81C360AB1C5F895 -+:108310001C2609B1C5F818164FF4FA600292DEF374 -+:108320001BF238464946E2F37BF705B0BDE8F0831F -+:1083300014B90200F4B8020051368600D4B8020025 -+:10834000A4B80200563686002DE9F04385B00546F4 -+:10835000E2F394F5002181462846E2F361F72B6AA7 -+:108360008046042B6B6A01DDDF0E01E0C3F3436737 -+:10837000002614E0102168460D4A3346D9F3A4F6CE -+:10838000002069466C46DAF323F338B100210A462F -+:10839000DAF3DEF1C8F85066C8F854060136BE427A -+:1083A000E8D128464946E2F33BF705B0BDE8F08343 -+:1083B0005B3686002DE9F043036A85B0042B436ADF -+:1083C0000546CCBFC3F38458C3F34358E2F356F5D4 -+:1083D000002181462846E2F323F70026074615E0F0 -+:1083E000102168460E4A3346D9F36EF600206946DE -+:1083F0006C46DAF3EDF238B100210A46DAF3A8F15F -+:10840000C7F85866C7F85C06731CDEB24645E7D16C -+:1084100028464946E2F304F705B0BDE8F083C046BC -+:1084200063368600F7B5053A06461F46062A2BD85E -+:10843000DFE802F00A0C12040E2A060005250CE003 -+:108440001125032402230AE0012502E0052500E0AE -+:1084500011250F24042302E000251F240323009389 -+:1084600000214FF4CB624FF0FF333046E2F30EF5BC -+:1084700004EA0703AB4030460093002140F25C62FF -+:1084800014FA05F3E2F302F5FEBDC0462DE9F04112 -+:1084900005460E4600201749DAF36EF2164984B2FB -+:1084A0000020DAF369F240F2DC51002C18BF2146BB -+:1084B000C7B22846FFF784FDC0B210F0800F0CD180 -+:1084C000C4B23146284607222346FFF7ABFF2846B1 -+:1084D000314608222346FFF7A5FF2FB12846314633 -+:1084E0003A460123E7F748F828463146FFF762FF8E -+:1084F000BDE8F0816F36860008F9010070B50546C9 -+:108500000C46FFF721FF002221462846DDF364F5E3 -+:108510002846E2F3B3F40A4904460020DAF32CF2C9 -+:108520004FF4002210F001034FF00001284618BF5D -+:108530001346DDF385F428462146E2F371F670BD5B -+:108540007836860070B5002105461020DDF35EF711 -+:10855000002110220446D9F373F52046656070BDF2 -+:1085600070B50C461546E2F3C5F51021DEF3B0F305 -+:1085700010B96FF01A0008E0044A10234360136832 -+:10858000C460036085601060002070BD6C2700002F -+:1085900070B515460C46E2F3ADF51021DEF398F305 -+:1085A000024610B96FF01A0010E01023436008492A -+:1085B000002303600B68C46085601BB9086018461F -+:1085C00004E0034618680028FBD11A6070BDC0465D -+:1085D0006C27000070B50C461546E2F38BF51021B0 -+:1085E000DEF376F310B96FF01A0008E0044A1023A6 -+:1085F00043601368C460036085601060002070BD34 -+:108600006C270000064B10B51B683BB9054B196879 -+:1086100021B1054B1A680AB1FFF7DCFF002010BD3D -+:108620006C270000FC1E0200001F020001207047A2 -+:108630000020704710B50020DAF39EF110BDC0464F -+:1086400010B50B490446FFF7F5FF80B278B9E06F2B -+:108650000749DAF391F180B248B9E06F0549DAF3DE -+:108660008BF14FF6FF7380B2002808BF184610BD8B -+:10867000483786004E37860041F2E44370B5C36246 -+:1086800004460D4629B108460949DAF375F1A0629E -+:1086900040B900200749DAF36FF1A06210B94FF634 -+:1086A000FF73A36228460449DAF366F1206370BDC4 -+:1086B000543786005B37860086378600836973B53A -+:1086C00013F0005F04466FD08268B2F5026F01D1EB -+:1086D00001220AE040F604039A4201D0002204E09D -+:1086E000C3680C2B94BF002201224FF00003D5B2C7 -+:1086F000ADF8063055B920464FF400612A46D4F84B -+:10870000C860E2F37BF500284ED005E0D4F8843051 -+:1087100013F5405048D000266369222B03DC002368 -+:10872000C0F8683100E00023C0F86431C0F860315F -+:108730006369222B03DC1F4BC0F8443105E00123A1 -+:10874000C0F84831FE33C0F84C316369222B07DC96 -+:108750000023C0F88031C0F87C31C0F8783104E0E3 -+:108760000023C0F87431C0F870311DB9204631467D -+:10877000E2F356F520460DF10601FFF759FF0546D5 -+:10878000A8B9BDF8063093B163690B49222B204686 -+:10879000D8BF4FF48021CCBF40224FF480222B461B -+:1087A000E2F38EF3284603E04FF0FF3000E00020B4 -+:1087B0007CBDC0460000FBBF400055552DE9F04789 -+:1087C000002104461F46DDF82080DDF82490E2F306 -+:1087D00027F505462046E2F363F360610A28C4BF2B -+:1087E000EB6A63646B68A3616369222BC4BFD5F82D -+:1087F000AC30E361A36913F0805F05D0D5F804368F -+:10880000636203F0FF0323624FF4E063A3604FF061 -+:10881000FF33E360254612330026236116E031461C -+:108820002046E2F3FDF42046E2F31CF32046E2F397 -+:1088300037F31FB1D5F810319F4203D0D5F88830F7 -+:10884000994501D1C8F8006001360435D4F8CC3020 -+:108850009E42E4D32046D8F80010E2F3E1F4012070 -+:10886000BDE8F08730B585B00190002504A840F838 -+:10887000045D01A90422D9F37FF3019CD4B12246FF -+:108880002946D2F8883013B10023C2F8883001316C -+:1088900004321029F5D10398D9F30CF30398E6F7C5 -+:1088A000B7FF054B9C4205D0606D21464FF45672D0 -+:1088B000DEF31EF205B030BD8C2802002DE9FF4723 -+:1088C0000C9E1446DDF834808A464FF4567200211F -+:1088D00005461F46DDF83890012E08BF0026D9F363 -+:1088E000AFF311232B61C5F88470C5F858806C650F -+:1088F0006E60002E40F0B98028463146524643460D -+:10890000FFF794FE002800F0B0804FF0C0542268BA -+:108910002846130F2B6013041B0CAB63C2F30343F5 -+:10892000C2F303522A640E3A012A8CBF00220122AC -+:10893000EB6385F8482021465246FDF739FFD5F80C -+:10894000CC30002B00F0918004AB43F8046D009311 -+:1089500028462146324633460197FFF72FFF00286D -+:1089600000F083802846FFF74DFE0F9A6B6D284676 -+:10897000019231463A46CDF80090FFF70FFB0028F0 -+:1089800073D1B9F1000F01D14E4601E0D9F8006072 -+:1089900028463146FFF770FE364B1C78002C30D14C -+:1089A0006B69132B0BDD4FF4006128462246E2F37E -+:1089B00025F48465C46503992846E2F331F428461A -+:1089C000696DFFF7D3FB2846696DFFF797FD3046C9 -+:1089D0002949D9F3D1F7024620B92846696DFFF736 -+:1089E0008DFB02462846696DFFF7DEFB2846696D60 -+:1089F000FFF7F2FB2846696DFFF748FD1D4B01228A -+:108A00001A706B690F2B0FDD1C493046D9F3B4F790 -+:108A10001B4B0021002808BF1846009088222846DA -+:108A20004FF0FF33E2F332F230461649D9F3D0F774 -+:108A300038B114493046D9F39FF701462846E7F785 -+:108A4000A5F86B69142B11DD00242146082223466A -+:108A500028460094E2F31AF2214640F0040308226B -+:108A600028460093E2F312F200E00025284604B005 -+:108A7000BDE8F087E42B0200E2388600EB38860080 -+:108A80005A000A00F13886001FB5104C864621783E -+:108A9000C9B90F4A0F4B002808BF024608BF03465A -+:108AA00000910191029303920B4844F210717246B7 -+:108AB0004FF0C053FFF702FF00B905E0074A20233B -+:108AC000136001232370044804B010BD88280200FD -+:108AD0000C290200082902008C28020074270000DB -+:108AE0002DE9FF4781460D4608464FF456719246E0 -+:108AF0001E460D9FDDF83880DEF3EAF0044610B321 -+:108B00000C9B494601932A46534600960297CDF89E -+:108B10000C80FFF7D3FE064638B9284621464FF4AD -+:108B20005672DEF3E5F030460EE00FB93B4600E04A -+:108B30003B68E367B8F1000F01D1434601E0D8F884 -+:108B40000030C4F88030204604B0BDE8F087C0464D -+:108B500070B5044628B30368124918682246FBF32F -+:108B6000F3F12546002610E0296A29B123689868A8 -+:108B7000E6F386F500232B62E96921B123682A8B8D -+:108B80005868DEF3B5F00136183561688E42EBDBCC -+:108B9000182201FB02F22368214658681032DEF3E6 -+:108BA000A7F070BD08FA01002DE9F043036885B015 -+:108BB00081467021D868DEF38BF0044608B906467A -+:108BC00048E0002170220646D9F33AF2042363609C -+:108BD00027464FF0B40325464FF00008C4F8009034 -+:108BE000A38112E0182208FB02F210322C61D9F89E -+:108BF00008001A49A2180023E6F35EF5286218352A -+:108C000008B905461CE008F1010863689845E9DBEE -+:108C1000134BD9F8000000930023019302930393B0 -+:108C20001049114A2346FBF357F113E0396A29B181 -+:108C300023689868E6F324F500233B620135183772 -+:108C400063689D42F2DB2368214658687022DEF398 -+:108C50004FF00026304605B0BDE8F0839DFE0000D1 -+:108C600021FD0000E4F9010009FA010010B50446F5 -+:108C700058B10368054918682246FBF365F123687B -+:108C8000214658685422DEF333F010BD2B7A86005B -+:108C900030B55421044685B04068DEF319F008B9B8 -+:108CA000054611E0002154220546D9F3C9F1084BCD -+:108CB0002C600093002301930293039320680549DD -+:108CC000054A2B46FBF308F1284605B030BDC046E7 -+:108CD000390301003CFA01002B7A8600002070471E -+:108CE00010B5044698B107F0ADDE09496068224628 -+:108CF000FBF32AF1E16E21B163683C22D868DDF311 -+:108D0000F7F763682146D8687022DDF3F1F710BDEC -+:108D1000D58D86007FB5054670214068DDF3D8F714 -+:108D2000064608B9044631E0002170220446D9F312 -+:108D300087F12B683560736068683C21DDF3C8F704 -+:108D4000E066F8B100213C22D9F37AF1114B1249C7 -+:108D50000093002301930293104B114A0393706810 -+:108D60003346FBF3B9F068B94FF001037382B38265 -+:108D700030462946FFF7B2FF002803DB304607F0F4 -+:108D80005DDF03E03046FFF7ABFF0024204604B070 -+:108D900070BDC046390B83006CFA0100290C8300BA -+:108DA000D58D860070B5D0F8305704466DB10749AF -+:108DB00022460068FBF3C8F0606829464FF40A6257 -+:108DC000DDF396F70023C4F8303770BD529E86005D -+:108DD0002DE9FF4106464FF40A614068DDF378F75C -+:108DE000074618B9C6F830070138E1E000214FF412 -+:108DF0000A62D9F325F107F120033B6033680822AA -+:108E000000247A613C61DC211A6630466A4A6B4B69 -+:108E10000094019601F092FFA042B86105DA304655 -+:108E2000FFF7C0FF6FF00100C2E0A6462546644B85 -+:108E300000221EF0010FEA501FD0624B19780D2955 -+:108E400002DD4FF4004C03E04A1C012303FA02FC4C -+:108E50005C4BD8780D2802DD4FF4004403E0421C3F -+:108E6000012313FA02F4012313FA00F28B401A4390 -+:108E700042EA0C02524B2243EA501EF0020F24D069 -+:108E80004F4B55F803804F4B58780D2802DD4FF4B7 -+:108E9000004C03E0421C012303FA02FC494B997881 -+:108EA0000D2902DD4FF4004403E04A1C012313FAAC -+:108EB00002F4012313FA01F283401A4342EA0C023E -+:108EC00022433F4B42EA0802EA501EF0040F24D02E -+:108ED0003B4B55F803803B4B18790D2802DD4FF4CE -+:108EE000004C03E0421C012303FA02FC354B597984 -+:108EF0000D2902DD4FF4004403E04A1C012313FA5C -+:108F000002F4012313FA01F283401A4342EA0C02ED -+:108F100022432B4B42EA0802EA501EF0080F24D0ED -+:108F2000274B55F80380274B98790D2802DD4FF425 -+:108F3000004C03E0421C012303FA02FC214BD979C7 -+:108F40000D2902DD4FF4004403E04A1C012313FA0B -+:108F500002F4012313FA01F283401A4342EA0C029D -+:108F60002243174B42EA0802EA500EF1010E043583 -+:108F7000BEF1100F7FF45BAF134B0025134C03932E -+:108F80002946134A33463068009501950295FAF355 -+:108F9000A3F7231D93E807006B4683E807003046DC -+:108FA00023680321324601F061DEC6F83077284697 -+:108FB00004B0BDE8F081C04601578300A15683008C -+:108FC0008427000090E085009D508300C8FA0100CE -+:108FD000529E86002DE9F041066805461B4930681F -+:108FE0002A46FAF3B1F72C460027D4F8081121B12C -+:108FF0007068B4F81021DDF37BF6D4F80C1121B1C0 -+:109000007068B4F81221DDF373F601374034042F91 -+:10901000EBD1D5F80C1221B17068B5F81022DDF350 -+:1090200067F6D5F81C1211B1B068E6F329F3D5F84C -+:10903000201219B170683A46DDF35AF67068294675 -+:109040004FF42372DDF354F6BDE8F081D8FA010045 -+:1090500010B50446E7F7F2FDA16961B1237D23B1A4 -+:10906000E068E6F3FBF200232375E068A169E6F30C -+:1090700007F30023A36123692146D8682C22DDF37E -+:1090800037F6002010BDC0462DE9F041074688465E -+:10909000C0682C2114461E46DDF31AF608B90546B1 -+:1090A00019E0054600212C22D8F3CAF7EC602046CF -+:1090B000EE61C5F808802F6108492A460023E6F3CF -+:1090C000FBF20446A86130B92B692946D8682C22E6 -+:1090D000DDF30EF625462846BDE8F0813D668400A6 -+:1090E00010B5034900220068FAF32EF7002010BDE6 -+:1090F00049C586001FB5094A0B460092002201921D -+:10910000029203920649074AFAF3E6F6002814BFD2 -+:109110004FF0FF30002005B000BDC0460968840054 -+:1091200048FB010049C586001FB5084A0346009266 -+:1091300000220192029203920549064A0068FAF35E -+:10914000CBF6003818BF012005B000BD7D18010026 -+:1091500020FC0100EFFB010010B5B0F8BC400C8012 -+:10916000B0F8C0101180B0F8C6201A8090F8C8205E -+:10917000029B01201A8010BD90F8D4007047C046B1 -+:10918000D0F8CC007047C04610B5014618B18068D1 -+:109190009822DDF3ADF510BD70B598210446006846 -+:1091A000DDF396F508B9054633E00021982205461F -+:1091B000D8F346F72368AB606368EB60A3682B6164 -+:1091C000E3686B6023696B61238CAB84638CEB84F5 -+:1091D000636AAB62A36AEB62E36A2B63236B6B6324 -+:1091E000636B6B64A36BAB64E36BEB64236C2B6509 -+:1091F000636C6B656369AB65A369EB650F232B66D5 -+:109200002D336B663C33AB660323EB66002385F896 -+:109210009430284670BDC04670B501210446E9F778 -+:1092200029FB2046E9F7B2FBC0F30F33A4F8C630A0 -+:10923000B4F8C620030F84F8C83042F2640300F08B -+:109240000F009A4284F8C90005D002339A4202D036 -+:109250004FF0FF3500E0002520460021EAF77AF8BC -+:10926000284670BD70B5044600282DD0D0F8E430F3 -+:109270005D1EC0F8E4503DBB41F2C826815921B1C2 -+:10928000C3691869F3F78EFFA55141F2DD13E55468 -+:109290002046E9F73FFFE1690A68A24203D1D4F80A -+:1092A000B4300B6005E0D2F8B430A34208BFC2F876 -+:1092B000B450E36E0BB120469847E36921469868A5 -+:1092C00041F26832DDF314F570BDC04670B5D0F8D8 -+:1092D000B8400E46E9B10846D8F342F70546C0B19A -+:1092E0000FE0204631462A46D8F32AF628B9635DB6 -+:1092F0003D2B02D1631C58190CE014F8013B002BE4 -+:10930000FBD114B12378002BEBD13046DEF3AEF461 -+:1093100000E0002070BDC0462DE9F34141F2383530 -+:10932000435B064688462BB30846D8F319F7044634 -+:109330001448D8F315F724181034F369A7B29868C5 -+:109340003946DDF3C5F4044608B9054617E0735BFA -+:109350000D4A009339464346D8F3B6F621463046C7 -+:10936000EBF79EF9F3690546214698683A46DDF326 -+:10937000BFF425B930464146EBF792F90546284639 -+:10938000BDE8FC8196FD01009CFD01002DE9F04F38 -+:1093900041F2383B85B0039330F80B3006468946DE -+:1093A0009246D0F8B880002B38D00846D8F3D8F6CB -+:1093B00004462448D8F3D4F62418F3691034A7B22D -+:1093C00098683946DDF384F4054608B9044634E06C -+:1093D00036F80B30394600931B4A4B46D8F374F6E7 -+:1093E00030462946EBF76AF9834668B1404629467C -+:1093F000D9F75CFA40B1504506DD40462946524651 -+:10940000D9F3C8F2044600E0039CF3692946986842 -+:109410003A46DDF36DF4BBF1000F0ED140464946EC -+:10942000D9F744FA40B1504506DD40464946524618 -+:10943000D9F3B0F2044600E0039C204605B0BDE835 -+:10944000F08FC04696FD01009CFD010070B590F8BC -+:10945000C43001229A401A49013A0446D5B2EBF7CA -+:1094600061F941F21202C0B2A0540138C0B2FD2825 -+:1094700001D97323A354A25C41F21303E2542046A2 -+:109480001049EBF74FF941F21402C0B2A05408B1F1 -+:109490000F2801D10523A35441F21203E25C0233E9 -+:1094A000E35CD21A41F21503E25400220133E25484 -+:1094B0000233E25445EA0512013BE25470BDC04656 -+:1094C00075B902004FB902002DE9F84F8846002116 -+:1094D000846807469246C0680A469B46E1F3BAF4A0 -+:1094E00010F0080F814615D03E689EB130465146B7 -+:1094F00000F084FA002800F07481F369D6F8CC10EB -+:10950000186927F0CDD8D6F8E43030460133C6F8D4 -+:10951000E4306DE1204641F26831DDF3D9F30546D0 -+:10952000002800F05C81002141F268320646D8F341 -+:1095300087F5012105F59053303341F2D41285F8B7 -+:10954000E110AB50FA6C41F26B039A42C5F8B0805F -+:10955000EF6105D17B6C932B02D1A5F8221603E0B5 -+:109560004FF01802A5F822266423002185F8E03088 -+:1095700041F218230422E9540133EA540133E95437 -+:109580000133BAF1020FC5F8B8B0EA5406D119F0A8 -+:10959000010F1CBF4FF40053C5F8CC30EB69D5F870 -+:1095A000CC10186927F07CD8D5F8B030B3F8E03388 -+:1095B0009CB2EB69D868E6F787F941F23833E85294 -+:1095C000C4F30323C5F8BC3004F00F03C5F8C03062 -+:1095D000EB699A6A874BD318012B06D94AF6E60342 -+:1095E0009A4202D0043B9A4207D1EB69DB6A023B04 -+:1095F000012B02D80923C5F8C030D5F8BC30092B9F -+:1096000007D10423C5F8BC30D5F8C0301033C5F8F5 -+:10961000C030012385F8C430230BC5F8D030D5F80D -+:10962000BC30022B0CD9042B0AD0052B08D0062BFA -+:1096300006D0082B04D00A2B02D0072B40F0D18093 -+:109640003C23C5F8F43F0023C5F8F83F4FF400630E -+:10965000A5F8DE3042F6013241F62433BAF1020FAA -+:1096600008BF1346A5F8DA3095F8DA30284685F8B1 -+:1096700000376149EBF722F890B15F492846EC6961 -+:10968000EBF750F85C4920672846EC69EBF74AF89D -+:10969000EA69BAF1020F60670CBF136F536FD366AC -+:1096A0000A2241F2E613EA5403210133E95401236B -+:1096B000002485F8E83005F59053013A1C7041F21A -+:1096C0001B03EA54EB6985F8E94585F8EE4585F812 -+:1096D000F34585F8F84585F8FD45284683F893104D -+:1096E000FFF7B4FE41F21903EC544FF6CE7241F28B -+:1096F000C423EA5285F8F440621901347F23652CB3 -+:1097000082F82C3682F8913682F8B232F4D14FF0DA -+:10971000FF33A5F8FA36002385F8AC3028465146C9 -+:1097200001F03AF900285CD02846E9F797F8284676 -+:10973000FFF772FD0446002853D13049062228461F -+:10974000EAF7E4FF41F2E623E8542D4901222846D6 -+:10975000EAF7DCFF41F2F423E8542A49224628467E -+:10976000EAF7D4FF41F23A33E85427492846072262 -+:10977000EAF7CCFF41F23B33E8542246284623491E -+:10978000EAF7BEFF631903F5985301343833182CF8 -+:109790001871F2D10024224628461D49EAF7B0FF8D -+:1097A000631903F59A53013410330E2C1871F2D15A -+:1097B000D5F8E430EA690133C5F8E4301368D068BD -+:1097C000C5F8B4303D60FEF779FF05F1B803C5F880 -+:1097D000B830284605F1BC011C22D8F3CDF3284649 -+:1097E00006E0B868314641F26832DDF381F20020CC -+:1097F000BDE8F88F1D57FFFF80B9020024B90200B1 -+:1098000043B9020036B9020060B902006EB9020025 -+:109810002FB9020010B502490268FAF395F310BDA2 -+:10982000040402001FB5094B09490093002301936A -+:1098300002930393074A0368FAF34EF3002814BF18 -+:109840004FF0FF30002005B000BDC0463147010099 -+:1098500044030200040402002DE9F0410025804683 -+:109860000F4616462C4607E004EB0800E1190522D6 -+:10987000D8F382F301350534B542F5D1BDE8F08166 -+:10988000022970B505460C460AD0032911D00129DA -+:1098900016D106220B49E8F793FFEA69002305E099 -+:1098A00006220949E8F78CFFEA69012382F8813032 -+:1098B00006E006490622E8F783FFEB6983F881405A -+:1098C00070BDC046200B02002C0B0200380B0200BA -+:1098D00070B5D0F8A840002394F8C113C4F87435CB -+:1098E0000F4A104B022914BF15461D46C3694FF499 -+:1098F00020719868DDF3ECF1C4F8740578B180222A -+:109900002946FFF7A9FF94F83A35022B06D1D4F87F -+:1099100074050549A0301522FFF79EFF012070BD98 -+:1099200084C90200A8C4020048CC02002DE9F04717 -+:10993000D0F8A8308146D3F87C55D3F878A54FF0FD -+:10994000000817E0142403FB04F42B191A695B6860 -+:109950002F5903FB02F3DE08D9F81C303146986812 -+:10996000DDF3B6F108F10108285140B1394632461D -+:10997000D8F302F35FFA88F35345E3D30120BDE83F -+:10998000F087C0462DE9F041194BD0F8A8501A686D -+:10999000C369002614210746C5F87C65C5F87825FB -+:1099A000986802FB01F1DDF393F10446C5F87C05EC -+:1099B000E0B1B0460FE0FB6906EB04001B6D08F157 -+:1099C000010813F4805F14BF0A490B49142271186F -+:1099D000D8F3D2F21436D5F878359845EBD338461B -+:1099E0000121FFF7A3FF003818BF0120BDE8F08177 -+:1099F000A01A0200C4C2020084D102002DE9F04185 -+:109A0000884686B07A490546D0F8A860EAF78AFE0B -+:109A1000784930722846EAF785FE77497072284601 -+:109A2000EAF780FE7549A5F8FC002846EAF77AFEB9 -+:109A30007349A5F8FE002846EAF774FE7149A5F8B7 -+:109A400000012846EAF73AFE38B128466D49EAF7A0 -+:109A500069FE10B1012386F8E83396F8E8330BB3BA -+:109A600068492846EAF75EFE6749A5F802012846DC -+:109A7000EAF758FE6549A5F804012846EAF752FEC0 -+:109A80006349A5F806012846EAF74CFE614986F8C5 -+:109A900024052846EAF746FE002241F21B0386F819 -+:109AA0002505EA545C492846EAF73CFE5B49C6F8BE -+:109AB000340414222846EAF729FE5949A6F83C0442 -+:109AC0005A222846EAF722FE564986F8540408220C -+:109AD0002846EAF71BFE544986F84C040322284620 -+:109AE000EAF714FE514986F84D0408222846EAF7A1 -+:109AF0000DFE4F4986F84E0403222846EAF706FE7B -+:109B00004C4986F84F0408222846EAF7FFFD4A49E7 -+:109B100086F8500403222846EAF7F8FD474986F8FC -+:109B2000510408222846EAF7F1FD032286F8520480 -+:109B300043492846EAF7EAFD424986F85304284695 -+:109B4000EAF7F0FD404986F8580402222846EAF771 -+:109B5000DDFD3E4986F8C1042846EAF7AFFD28B18D -+:109B600028463A49EAF7DEFDF07400E0F074284632 -+:109B70003749EAF7A3FD28B128463549EAF7D2FD6F -+:109B8000307501E00823337528463249EAF796FD1F -+:109B900028B128462F49EAF7C5FD707501E0022378 -+:109BA000737528462C49EAF789FD28B128462A49C9 -+:109BB000EAF7B8FDB07501E00423B37528462749DC -+:109BC000EAF77CFD28B128462449EAF7ABFDF07599 -+:109BD00001E00823F37528462149EAF76FFD0028C4 -+:109BE00040D028461E49EAF79DFD30763CE0C0464D -+:109BF00045C10200E3C002002ABE020030BE0200DE -+:109C000036BE0200C3C00200E2BD0200CDBC0200AD -+:109C1000D5BA0200EABA02009AC202006BBD020085 -+:109C2000A6C102001DC202007EBF0200EBC10200FD -+:109C3000ABB90200FCC10200BCB90200DAC10200EB -+:109C4000B3C202009ABC02000BBB02001ABC0200A5 -+:109C500007BC020065C0020015C202000DC202006E -+:109C60003DC1020002233376B7492846EAF75AFD80 -+:109C7000B649B0722846EAF755FDB549F072284654 -+:109C8000EAF750FDB17AF27AC3B230737173B273EE -+:109C9000F37331747274B374AE492846EAF742FD27 -+:109CA000B5F8FC2041F21A33EA5205F599531A80AF -+:109CB000B5F8FE2041F21C33EA520633EA52B5F8F9 -+:109CC0000021043BC7B2EA52063385F81A71EA5202 -+:109CD0002846A149EAF726FD002480B22A1900F09F -+:109CE0000F030134A7EB43030009042C82F81E3153 -+:109CF000F4D128469949EAF715FD2A1900F00F0317 -+:109D00000134A7EB430300090C2C82F81E31F4D177 -+:109D100093492846EAF706FD924904462846EAF7A1 -+:109D200001FD80B240EA0441716014202A1801F05C -+:109D30000F030130A7EB430309091C2882F81631F1 -+:109D4000F4D189492846EAF7EDFC88497083284612 -+:109D5000EAF7E8FC864930772846EAF7E3FC8549CC -+:109D600070772846EAF7DEFC8349B0772846EAF7A1 -+:109D7000D9FC8249F0772846EAF7D4FC804986F876 -+:109D800022002846EAF7CEFC7E4986F821002846C4 -+:109D9000EAF7C8FC7C4986F8E0042846EAF7C2FCEA -+:109DA0000127C6F8E40401AC784920463A46D8F3C6 -+:109DB0009BF1D5F8B8002146D8F30AF630B100215E -+:109DC0000A46D8F3C5F4F31983F8E70401370F2FD7 -+:109DD000E9D16F492846EAF7A5FC6E4986F8F604F2 -+:109DE0002846EAF79FFC6C4986F8F7042846EAF70C -+:109DF00099FC6A4986F8F8042846EAF793FC684912 -+:109E000086F8F9042846EAF78DFC664986F8FA04D4 -+:109E10002846EAF787FC644986F8FB042846EAF7F7 -+:109E200081FC624986F8FC042846EAF77BFC60491D -+:109E300086F8FD042846EAF775FC5E4986F8FE04BC -+:109E40002846EAF76FFC5C4986F8FF042846EAF7E3 -+:109E500069FC5A4986F800052846EAF763FC584928 -+:109E600086F801052846EAF75DFC564986F80205A2 -+:109E70002846EAF757FC544986F803052846EAF7CE -+:109E800051FC524986F804052846EAF74BFC504934 -+:109E900086F805052846EAF745FC4E4986F806058A -+:109EA0002846EAF73FFC4C4986F807052846EAF7BA -+:109EB00039FC4A4986F808052846EAF733FC484940 -+:109EC00086F809052846EAF72DFC464986F80A0572 -+:109ED0002846EAF727FC444986F80B052846EAF7A6 -+:109EE00021FC424986F80C052846EAF71BFC40494C -+:109EF00086F80D052846EAF715FC3E49A6F8140534 -+:109F00002846EAF70FFC4FF00042A6F816053A493A -+:109F10002846EAF7FBFB3949C6F810052846EAF758 -+:109F200001FC374986F824002846EAF7FBFB35494F -+:109F300086F823002846EAF7F5FB334986F8200027 -+:109F40002846EAF7EFFB61E0E7B902000CBF020028 -+:109F5000C5BD0200F2BD020077BD020044BC020094 -+:109F600096B902008DB902008DBE0200DDB9020073 -+:109F7000F6BF020001C00200CDB90200B2BC02006F -+:109F8000E3BC0200B9BE0200FFBE020033BC020007 -+:109F90003CBE02008CBF02009DBF0200B7BF0200A2 -+:109FA000FEC002000FC102002BC202004CC2020020 -+:109FB0006FBE02009ABE0200C7BE020020C10200AE -+:109FC0000CC0020056C1020068C102007AC1020042 -+:109FD0006DC202007FC2020031BA02005BBA020009 -+:109FE00074BB02009DBB020088BC0200A9BA02003B -+:109FF000FCBA020034BD020059BB0200B1C102002C -+:10A00000BDC102005DC2020046C00200B94985F828 -+:10A0100026062846EAF786FBB74986F8C103284694 -+:10A02000EAF780FBB54986F8C2032846EAF77AFBCF -+:10A0300086F8C30395F8261611B12846FFF720FCD1 -+:10A040004FF0FF32AE492846EAF760FB80B210F4C9 -+:10A05000004F18BF4FF0FF324FF0FF33A6F86200F9 -+:10A06000A6F8663018BFA6F86220A6F86830284621 -+:10A07000A449EAF723FB58B12846A249EAF752FB64 -+:10A0800080B210F4004F04BFA6F86600A6F868007E -+:10A0900028469D49EAF712FB48B128469A49EAF753 -+:10A0A00041FB80B210F4004F08BFA6F866002846B6 -+:10A0B0009649EAF703FB48B128469449EAF732FB90 -+:10A0C00080B210F4004F08BFA6F8680090494FF026 -+:10A0D000FF322846EAF71AFB4FF0FF32A6F8C40316 -+:10A0E0008C492846EAF712FB8B49A6F8C603284696 -+:10A0F000EAF718FB8949A6F8C8034FF4CF7228463F -+:10A10000EAF704FB8649C6F8CC0347F69A6228466C -+:10A11000EAF7FCFA8349C6F8D0030A222846EAF790 -+:10A12000F5FA8149C6F8D40308222846EAF7EEFA80 -+:10A130007E49C6F8D80341F26E022846EAF7E6FAED -+:10A140000A22C6F8DC037A492846EAF7DFFA794999 -+:10A15000C6F8E0032846EAF7E5FA7749A6F8E403EB -+:10A160002846EAF7DFFA96F8E83380B2A6F8E60365 -+:10A170002BB103B2002BC4BF0022A6F8E623502265 -+:10A180006E492846EAF7C2FA6D4986F8EA0328467E -+:10A19000EAF7C8FA6B4986F8EC032846EAF7C2FAF0 -+:10A1A000694986F8ED032846EAF7BCFA674986F85C -+:10A1B000EE034FF0FF322846EAF7A8FA644986F822 -+:10A1C000F0034FF0FF322846EAF7A0FA4FF0FF34D1 -+:10A1D00086F8F1035F49224686F8EF432846EAF7FE -+:10A1E00095FA5D4986F8F20322462846EAF78EFA88 -+:10A1F0005A4986F8590522462846EAF787FA584907 -+:10A2000086F85A0522462846EAF780FA554986F824 -+:10A21000F30322462846EAF779FA534986F85B05A4 -+:10A2200022462846EAF772FA504986F85C0522462B -+:10A230002846EAF76BFA4E4986F8F4032246284688 -+:10A24000EAF764FA4B4985F8DA0522462846EAF728 -+:10A250005DFA4949A6F8F60322462846EAF756FA77 -+:10A260004649A6F8F80322462846EAF74FFA444939 -+:10A27000A6F8FA0322462846EAF748FA4149A6F822 -+:10A28000FC0322462846EAF741FA3F49A6F8FE03B6 -+:10A2900022462846EAF73AFA3C49A6F80004224644 -+:10A2A0002846EAF733FA3A49A6F802042246284635 -+:10A2B000EAF72CFA0022A6F8040436492846EAF701 -+:10A2C00025FA0022A6F85E0533492846EAF71EFA69 -+:10A2D0000022A6F8600531492846EAF717FA00225D -+:10A2E000A6F862052E492846EAF710FA2D49A6F885 -+:10A2F000640559E04FBA020043BA0200A7C0020049 -+:10A300008DBD02004BC0020094C10200C0BB020020 -+:10A31000D2BB020067BF020035BB02005BC0020077 -+:10A32000A0BA0200BEBD0200D9BB02004DC10200AE -+:10A33000EBBD02009AC002007FBD0200BCBC02005F -+:10A34000AEBF020010BA0200DCBF020095BA0200E4 -+:10A3500002BD020032C1020039C0020090BB0200FF -+:10A36000A6BC02003EBB0200BBBA0200F0BB02006A -+:10A37000EBBE02001FBE0200C9BA02006DC002009F -+:10A38000B3BD02004CBB0200F4BC020016BF0200C9 -+:10A390005CBC02007AC002006EBF020059BF02001E -+:10A3A000D3C00200C6BC02002846EAF7BBF9B8F1E8 -+:10A3B000020F86F8060414D12846A449EAF77EF96C -+:10A3C000002800F0A382344600273A4628469F49D9 -+:10A3D000EAF796F90137C4F80C040434052FF4D1D8 -+:10A3E00016E0B8F1010F13D128469949EAF766F94A -+:10A3F000002800F08B82344600273A4628469449CC -+:10A40000EAF77EF90137C4F820040434052FF4D1AB -+:10A4100090494FF0FF322846EAF778F98E49A6F8BE -+:10A420003E044FF0FF322846EAF770F98B49A6F850 -+:10A4300040044FF0FF322846EAF768F98849A5F84A -+:10A44000DE0F2846EAF73AF930B128468449EAF7A0 -+:10A4500069F941F2EA23E852824928464FF0FF3277 -+:10A46000EAF754F941F23433E8527F492846EAF7D3 -+:10A4700025F930B128467C49EAF754F941F2EE2338 -+:10A48000E852284679490022EAF740F9C0B286F836 -+:10A490004D0358B176492846EAF744F97549C6F89C -+:10A4A00050032846EAF73EF9C6F860032846724989 -+:10A4B000EAF704F928B3D5F8B8006F49D8F7F6F9E8 -+:10A4C00006281ED1344600273A466B49D5F8B80015 -+:10A4D000D8F360F284F895037A1C6749D5F8B80080 -+:10A4E000D8F358F284F89703BA1CD5F8B80062493B -+:10A4F000D8F350F2033784F899030134062FE3D1DF -+:10A5000011E0012386F89533313386F896330E3304 -+:10A5100086F8973386F89833042386F899334FF0FA -+:10A52000FF3386F89A3355492846FF22EAF7EEF8BA -+:10A530004FF0FF03A6F85403A6F85633A6F8583395 -+:10A54000A6F85A3328464E49EAF7B8F828B3D5F8A2 -+:10A55000B8004B49D8F7AAF934460328B4BF80465F -+:10A560004FF00308002707E03A4628464449EAF737 -+:10A57000C7F80137A4F8540302344745F4DB06EB6F -+:10A58000470303F55473063304E0B6F85623013746 -+:10A5900023F8022C0233022FF7DD01223949284625 -+:10A5A000EAF7B4F8384986F840032846EAF7BAF8DB -+:10A5B000012286F84B0335492846EAF7A7F83449C3 -+:10A5C00086F841032846EAF7ADF8324986F84C038D -+:10A5D0004FF0FF322846EAF799F82F4986F84903E9 -+:10A5E0004FF0FF322846EAF791F82C4986F84A03E3 -+:10A5F0004FF0FF322846EAF789F8294986F85C03CC -+:10A600004FF0FF322846EAF781F8264986F85D03C5 -+:10A610002846EAF753F8002846D0012421490022B1 -+:10A6200086F8BB442846EAF76BF81E4986F8BC0456 -+:10A6300022462846EAF764F81A4986F8BD04022241 -+:10A640002846EAF75DF886F8BE042FE0E3BB020077 -+:10A65000EFBA02001ABD0200CCC002000CBE02001C -+:10A660000EBD02003CC202001EC0020066BB02001A -+:10A67000C8BF020050BD0200AFBB020037BF0200DE -+:10A68000A3C20200EAC002006ABC020016BB0200BC -+:10A6900022BF020079BA0200FBBD0200E5BF020042 -+:10A6A0004DBE020091C2020086F8BB04FF22994908 -+:10A6B0002846EAF72BF8FF2286F8BF049649284679 -+:10A6C000EAF724F8954986F8C0042846EAF72AF8FC -+:10A6D0000022A6F8C20492492846EAF717F8002299 -+:10A6E00086F818058F492846EAF710F8C0B286F8B0 -+:10A6F0001A05EB69DB685B6C03F00703052B03D9D4 -+:10A7000010B1002386F81A35874900222846E9F758 -+:10A71000FDFF864986F81C0500222846E9F7F6FF6A -+:10A72000834986F81D054FF0FF322846E9F7EEFF12 -+:10A73000804986F81E0500222846E9F7E7FF7E4992 -+:10A7400086F895054FF0FF322846E9F7DFFF7B4991 -+:10A75000A6F8200501222846E9F7D8FF784986F8AF -+:10A7600027054FF0FF322846E9F7D0FF7549A6F8D4 -+:10A770002A054FF0FF322846E9F7C8FF7249A6F8CC -+:10A780002C0500222846E9F7C1FF704986F83A05F2 -+:10A7900000222846E9F7BAFF6D4986F83B054FF0DD -+:10A7A000FF322846E9F7B2FF6A4986F83C05284699 -+:10A7B000E9F784FF30B128466649E9F7B3FF86F828 -+:10A7C000420503E04FF0FF3386F8423528466249E0 -+:10A7D000E9F774FF30B128465F49E9F7A3FFA6F80F -+:10A7E000440503E04FF0FF33A6F844355B492846A3 -+:10A7F0004FF0FF32E9F78AFF5949A6F8900528463D -+:10A80000E9F75CFF30B301245549002286F8524530 -+:10A810002846E9F775FF524986F85305224628462F -+:10A82000E9F76EFF4E4986F8540502222846E9F7FB -+:10A8300067FF4B4986F8550503222846E9F760FF74 -+:10A84000474986F8560504222846E9F759FF86F855 -+:10A85000570501E086F8520542494FF0FF3228467D -+:10A86000E9F754FF404986F858054FF0FF32284673 -+:10A87000E9F74CFF3D4986F859054FF0FF3228466D -+:10A88000E9F744FF3A4986F85A0500222846E9F7D5 -+:10A890003DFF384986F8700500222846E9F736FF63 -+:10A8A000032286F8800534492846E9F72FFF33490B -+:10A8B00086F881052846E9F735FF314986F8820593 -+:10A8C0002846E9F72FFF2F49A6F884052846E9F71F -+:10A8D00029FF2D49A6F886052846E9F723FF2B49CD -+:10A8E000A6F888052846E9F71DFF2949A6F88A0534 -+:10A8F0002846E9F717FF2749C6F88C0500222846A5 -+:10A90000E9F704FF86F89405012000E0002006B076 -+:10A91000BDE8F08145C102008CC10200DABA020034 -+:10A920001DBA0200CFBD02005EBE0200B2C002002E -+:10A93000ACBE020003BA0200FABB0200F1B9020089 -+:10A940002ABB020081BE020086BB02009FB9020042 -+:10A950009CBD0200D6BC02006DBA02000FBC020012 -+:10A960008ABA0200A6BD020039C0020090BB0200F4 -+:10A9700043BD02004DBC020022BC02007FBC0200AD -+:10A9800028C0020088C00200D9BE020047BF0200F2 -+:10A9900022BD0200CBC10200C36970B504460E4659 -+:10A9A00098684FF4B961DCF393F1C4F8A80000286B -+:10A9B0005CD000214FF4B962D7F342F3E369D4F8D5 -+:10A9C000A8501B6D13F4803F05D1012241F22403EE -+:10A9D00084F81A26E254E369D868E4F7B5FF41F237 -+:10A9E0000803E0500023EB63214B20462362214BF8 -+:10A9F00031466362204BA362204BE362204BA36786 -+:10AA0000204BE367204BC4F89030204BC4F88430CF -+:10AA10001F4B23631F4B63631F4BE3631F4B636435 -+:10AA20001F4B63651F4BA3651F4BC4F88C301F4B36 -+:10AA3000C4F888301E4BE3661E4BC4F89C301E4B96 -+:10AA4000C4F8A0301D4BC4F8A430FEF7D7FF68B19E -+:10AA50002046EBF757FD2046FEF73AFF30B120467F -+:10AA6000FEF790FF003818BF012000E0002070BD05 -+:10AA7000A9D00100E54A010091CD010055A20100D5 -+:10AA8000B9A001001D4F010075A901005DA90100D9 -+:10AA9000CD9B0100BD8701003D9C0100FD840100AC -+:10AAA0009D550100A15701007DCC0100C54B01005F -+:10AAB000B1530100198801001582010045CC010045 -+:10AAC00010B5014620B103680C221868DCF310F1C0 -+:10AAD00010BDC0462DE9F04105460F4600680C2127 -+:10AAE0001646DCF3F5F008B9044607E004460021F9 -+:10AAF0000C22D7F3A5F225606660A7602046BDE86A -+:10AB0000F081C04610B5044650B10649224640685F -+:10AB1000F9F31AF263682146D8688822DCF3E8F07A -+:10AB200010BDC04603E88600F0B5882185B0054613 -+:10AB30004068DCF3CDF0074608B904463BE000214D -+:10AB400088220446D7F37CF22B683D607B600026A8 -+:10AB500004212846194A1A4B0096019700F0EEF896 -+:10AB6000B042B86021DB174B019600930296039622 -+:10AB700078681549154A3B46F9F3AEF1A8B91E238A -+:10AB80007B610423FB7302233B74083301227B7433 -+:10AB90004FF6AF7384F82000FA773A73BA61A07465 -+:10ABA0006073A073BB83BA7705E068683946882272 -+:10ABB000DCF39EF00024204605B0F0BD5123850053 -+:10ABC00025238500811485002C1D020003E88600E2 -+:10ABD00070B50468CCB1D4F8F811A56829B1A8689B -+:10ABE000E4F34EF50023C4F8F831084928682246FA -+:10ABF000F9F3AAF1216819B168681C22DCF378F036 -+:10AC0000686821466269DCF373F070BD441D020080 -+:10AC10002DE9FF4740F2C45681468A461046314628 -+:10AC200017469846DCF354F00446002879D00021FA -+:10AC30003246D7F305F238461C21DCF349F00546CD -+:10AC4000206030B9384621463246DCF351F02846C0 -+:10AC500067E000211C22D7F3F3F122684FF0FF33A5 -+:10AC6000A36100254FF014036661C4F80890E76003 -+:10AC7000C4F804809571A4F808324FF02803A4F8B2 -+:10AC800006324FF02D03A4F804324FF0FA03A4F873 -+:10AC90000A320223146084F80C324FF06403A4F8E3 -+:10ACA0003E3284F80D5250461F4922462B46E4F3AB -+:10ACB00003F5C4F8F80108B30523C4F81C32373390 -+:10ACC000C4F8283204F51072184BC4F81822C4F8DE -+:10ACD000142204F53D72C4F82422C4F82022009303 -+:10ACE000134BD9F8000003931249134A23460195E8 -+:10ACF0000295F9F3F1F008B9206812E0D4F8F811E0 -+:10AD000011B15046E4F3BCF4216819B138461C2255 -+:10AD1000DBF3EEF73846214640F2C452DBF3E8F7A6 -+:10AD2000002004B0BDE8F087C13C8500F537850000 -+:10AD300035D201004C1D0200441D020070B5D0F850 -+:10AD400000451E46A3698E460F2B154602D94FF0CB -+:10AD5000FF3011E01801E1690133A361049B42183F -+:10AD60009360059B5660D36062694550D31C734461 -+:10AD700023F003036361104670BDC04610B5014661 -+:10AD800040B190F820200368D200D86802F5927292 -+:10AD9000DBF3AEF710BDC046C36908221B692DE97D -+:10ADA000F041073393FBF2F3DFB2FB0003F5927639 -+:10ADB00005463146C068DBF38BF708B9044614E05A -+:10ADC000044632460021D7F33BF104F12403E3614A -+:10ADD000FAB204F59273E36003EB820323614FF44C -+:10ADE0000373256084F8207063612046BDE8F0811C -+:10ADF0007047C0462DE9F04F3B4F89B038683B495A -+:10AE0000D7F3BAF50128DFF81881DFF8189157D089 -+:10AE1000DFF800C1364EDCF8001000220091354901 -+:10AE200013680968344D354C0291316834480193F8 -+:10AE300004912B68216803930691036831490593B7 -+:10AE40000B68DFF8D4E007932A4B02602E481A60A3 -+:10AE50000A602E4B08F10401D7F800A0DEF800B01C -+:10AE60003A60CEF80020CCF8002032602260091A47 -+:10AE7000013A2B60D7F3D4F5254B9842FCD11A4BFD -+:10AE80000099C3F800A0234B1960234B0021C3F89D -+:10AE900000B00A68214B1A60019A164B0A600299A9 -+:10AEA000039A1960144B04991A60114B059A1960A2 -+:10AEB000134B06991A60114B079A1960114B1A60CF -+:10AEC00098F81B3089F8003098F81C3089F8013068 -+:10AED00098F81D3089F8023098F81E3089F8033050 -+:10AEE00009B0BDE8F08FC046FC1E0200B81D02008C -+:10AEF00044EC000048EC000034EC000050EC000092 -+:10AF00004CEC000054EC000000000000DDBAADBBCA -+:10AF1000E320BBDE001F0200F81E020038EC000038 -+:10AF2000005903001C2802002DE9F04F91B0FFF7F3 -+:10AF300061FF684B1B68043B012B03D8664B186804 -+:10AF4000FFF756FFFBF7BEF800210746E0F3AEF12E -+:10AF500038460021E0F364F128B1036A002BBCBF3E -+:10AF60004FF0004303620EA90822B86BD7F3F6F244 -+:10AF7000FA6B0B9038460C92E4F7E6FC574E00F55E -+:10AF8000424000F5A870B0FBF6F00D903846E4F7AB -+:10AF9000DBFC04463846E4F7D7FC00F54248384667 -+:10AFA000E4F7DCFC00F5424A3846E4F7D7FC04F548 -+:10AFB000424408F5A87804F5A874B8FBF6F808FB35 -+:10AFC000164804463846E4F7C9FC00F542453846C1 -+:10AFD000E4F708FA00F542493846E4F703FA04F5C5 -+:10AFE000424405F5A87504F5A874B5FBF6F505FB14 -+:10AFF000164504463846E4F7F5F9394A00F542406B -+:10B00000019204F542440B9A00F5A870B0FBF6F0EB -+:10B010000AF5A87A09F5A87904F5A874BAFBF6FA36 -+:10B02000B9FBF6F9029200FB16460C9ADFF8D4B091 -+:10B0300003920D9A2B4B04922B492C4AB8FBFBF838 -+:10B04000B5FBFBF5B6FBFBF629480093CDF8148061 -+:10B05000CDF818A00795CDF820900996E6F724FBC7 -+:10B06000244840F60D0144F2F432FAF7AFFF48B13C -+:10B07000204840F6290144F2F432FAF7A7FF08B15C -+:10B08000002403E01C4A1D4B1A4C1A603846FDF799 -+:10B09000D7FA44F218334FF6FF72904214BF0246BB -+:10B0A0001A4640F612011648FAF790FF144B002892 -+:10B0B0000CBF194600214CB141B1104B20461B6812 -+:10B0C0005B689847236920465B689847384611B00B -+:10B0D000BDE8F08F54EC000050EC000040420F003F -+:10B0E000A0D60100ABFF8600BE1D0200C31D0200FA -+:10B0F000E8D102004C1F0200281F0200F8260000C1 -+:10B10000F81D0200A0860100776C25643A20427287 -+:10B110006F6164636F6D2042434D25642038303287 -+:10B120002E313120576972656C65737320436F6EE1 -+:10B1300074726F6C6C65722025730A0025733A2057 -+:10B1400042726F6164636F6D20534450434D4420DD -+:10B15000434443206472697665720A0073647063C5 -+:10B160006D6463646325640072737369736D663222 -+:10B17000673D2564007874616C667265713D256475 -+:10B1800000616132673D3078257800627734307035 -+:10B190006F3D30782578006C6564626825643D30C9 -+:10B1A0007825780074737369706F7332673D3078F7 -+:10B1B0002578007273736973617632673D25640088 -+:10B1C0006C65676F66646D3430647570706F3D30A8 -+:10B1D0007825780070613168696D61787077723DAB -+:10B1E0002564006D617870326761303D3078257874 -+:10B1F000007061316974737369743D2564006D6119 -+:10B200006E6669643D307825780073756276656E88 -+:10B210006469643D30782578002004D0023643FF0D -+:10B22000FF626F617264747970653D3078257800D3 -+:10B230006D6373256467706F25643D3078257800F1 -+:10B240006D616E663D2573006D61787035676C6168 -+:10B25000303D30782578006D61787035676C6131EC -+:10B260003D30782578006F66646D35676C706F3D92 -+:10B27000307825780072737369736D6335673D2587 -+:10B280006400626F617264666C616773323D30782E -+:10B29000257800747269736F32673D3078257800C5 -+:10B2A0007064657472616E676532673D30782578C9 -+:10B2B000006D63736277323035676C706F3D307844 -+:10B2C00025780000006D637362773230756C3567E6 -+:10B2D0006C706F3D30782578006D63736277343021 -+:10B2E00035676C706F3D30782578000000706131F3 -+:10B2F0006C6F6D61787077723D2564006D61787058 -+:10B30000326761313D30782578007278706F35672B -+:10B310003D2564006D63733332706F3D307825785E -+:10B320000073756264657669643D307825780069DC -+:10B330007474356761303D307825780069747435F0 -+:10B340006761313D30782578007061316D617870CA -+:10B3500077723D256400626F6172647265763D307C -+:10B36000782578006D6373627732303267706F3D95 -+:10B37000307825780000006D637362773230756C29 -+:10B380003267706F3D30782578006D637362773473 -+:10B39000303267706F3D307825780000006D637340 -+:10B3A0006277323035676D706F3D307825780000F8 -+:10B3B000006D637362773230756C35676D706F3D09 -+:10B3C00030782578006D63736277343035676D703F -+:10B3D0006F3D3078257800000073726F6D7265766E -+:10B3E0003D2564007770736C65643D256400706171 -+:10B3F000316C6F62303D2564007061316C6F623179 -+:10B400003D2564007061316C6F62323D25640070CF -+:10B410006125646725637725646125643D3078255F -+:10B42000780070613062303D2564007061306231B7 -+:10B430003D25640070613062323D25640072737393 -+:10B4400069736D6332673D2564007472693567689E -+:10B450003D25640075736266733D25640063636B0C -+:10B46000706F3D307825780074726935676C3D25C2 -+:10B4700064006F66646D356768706F3D307825785D -+:10B4800000616725643D30782578006578747061C7 -+:10B490006761696E35673D307825780070726F643A -+:10B4A0007563746E616D653D257300636464706FD0 -+:10B4B0003D30782578006C65676F66646D62773221 -+:10B4C0003035676C706F3D307825780000006C6512 -+:10B4D000676F66646D62773230756C35676C706F5C -+:10B4E0003D30782578006C65676F66646D627732F1 -+:10B4F0003035676D706F3D307825780000006C65E1 -+:10B50000676F66646D62773230756C35676D706F2A -+:10B510003D30782578006C65676F66646D627732C0 -+:10B5200030356768706F3D307825780000006C65B5 -+:10B53000676F66646D62773230756C356768706FFF -+:10B540003D30782578007278706F32673D25640051 -+:10B550007278636861696E3D30782578006974742B -+:10B56000326761303D3078257800697474326761E4 -+:10B57000313D3078257800616E7473776974636843 -+:10B580003D30782578007478636861696E3D307865 -+:10B5900025780070726F6469643D3078257800709A -+:10B5A00061306974737369743D25640063636B640F -+:10B5B000696766696C74747970653D2564006368B9 -+:10B5C00069707265763D2564006F66646D356770DD -+:10B5D0006F3D30782578006C656464633D30782574 -+:10B5E000303478006D61787035676861303D30784F -+:10B5F0002578006D61787035676861313D30782558 -+:10B60000780070613162303D2564007061316231D3 -+:10B610003D25640070613162323D256400627764CB -+:10B620007570706F3D30782578006D617870356782 -+:10B6300061303D30782578006D6178703567613113 -+:10B640003D3078257800616E74737763746C35676C -+:10B650003D30782578006D63732564672563706FCE -+:10B6600025643D30782578006D637362773230351C -+:10B670006768706F3D307825780000006D637362F5 -+:10B68000773230756C356768706F3D30782578009B -+:10B690006D637362773430356768706F3D3078253D -+:10B6A0007800000074726935673D2564006F706F23 -+:10B6B0003D25640076656E6469643D3078257800C8 -+:10B6C0006C65676F66646D627732303267706F3DAC -+:10B6D0003078257800006C65676F66646D6277323C -+:10B6E00030756C3267706F3D307825787061306DE1 -+:10B6F00061787077723D25640070613168696230ED -+:10B700003D256400706131686962313D25640070D7 -+:10B710006131686962323D256400637573746F6DD1 -+:10B7200076617225643D30782578007265677265B0 -+:10B73000763D3078257800626F617264666C61676F -+:10B74000733D307825780062786132673D2564006A -+:10B750006F656D3D2530327825303278253032786E -+:10B7600025303278253032782530327825303278DD -+:10B77000253032780064657669643D30782578003C -+:10B7800070612564677725646125643D307825788C -+:10B790000072737369736D6635673D2564006F666B -+:10B7A000646D3267706F3D30782578006161356770 -+:10B7B0003D30782578007770736770696F3D256438 -+:10B7C0000062786135673D25640075736265706E4F -+:10B7D000756D3D307825780074737369706F7335BB -+:10B7E000673D3078257800616E74737763746C32CE -+:10B7F000673D3078257800727373697361763567B9 -+:10B800003D2564006F66646D706F3D30782578006B -+:10B8100074726932673D25640073746263706F3DB2 -+:10B82000307825780063636F64653D307830006D53 -+:10B830006163616464723D25730063636F64653D99 -+:10B84000256325630063633D25640063636B326792 -+:10B85000706F3D30782578006363746C3D307825D7 -+:10B86000780072656777696E646F77737A3D2564D7 -+:10B870000065787470616761696E32673D30782564 -+:10B880007800626F6172646E756D3D25640074723C -+:10B8900069736F35673D307825780063636B627735 -+:10B8A00032303267706F3D30782578000000636376 -+:10B8B0006B62773230756C3267706F3D3078257807 -+:10B8C000007064657472616E676535673D30782518 -+:10B8D0007800000080000000FF0000000C00000065 -+:10B8E0000000000000040000FF0000000C00000049 -+:10B8F0000000000000000800FF0000000E00000033 -+:10B90000000000000200000001000400030000002D -+:10B91000010002000A00000002006000DC050000D7 -+:10B9200008071700747870777262636B6F66003275 -+:10B93000675F6367610072737369636F72726E6FC2 -+:10B94000726D00747373696C696D75636F640074F4 -+:10B95000656D70735F687973746572657369730080 -+:10B9600072737369636F7272617474656E003567A8 -+:10B970005F6367610074656D7074687265736800F9 -+:10B98000696E746572666572656E6365006D63737A -+:10B990003267706F30006D63733267706F3100749F -+:10B9A000786761696E74626C356700747373696F70 -+:10B9B00066667365746D696E35676C007473736960 -+:10B9C0006F66667365746D696E35676D0074656D5D -+:10B9D0007073656E73655F736C6F7065006D656124 -+:10B9E00073706F7765720072737369736D66326717 -+:10B9F00000706C6C646F75626C65725F6D6F64650E -+:10BA000032670069716C6F7374316F6666326700FC -+:10BA100072667265673033335F63636B00706C6CA2 -+:10BA2000646F75626C65725F656E61626C653267CA -+:10BA3000006F70656E6C706761696E696478613102 -+:10BA400034300065787470616761696E35670065D0 -+:10BA5000787470616761696E3267006F70656E6CD3 -+:10BA6000706761696E69647861313439007478692E -+:10BA7000716C6F7061673267006E6F6973655F63C9 -+:10BA8000616C5F7265665F3267006C6F67656E5FE1 -+:10BA90006D6F646500706163616C69647832670022 -+:10BAA00074656D705F616464006F70656E6C706763 -+:10BAB00061696E6964786131363500706163616C0B -+:10BAC000696478356768693100706163616C6174BD -+:10BAD0006832673100706D696E00706163616C700F -+:10BAE000756C7365776964746800706D6178007354 -+:10BAF000776374726C6D61705F3567006F70656E2F -+:10BB00006C7074656D70636F727200747373696DBD -+:10BB100061786E7074006E6F6973655F63616C5FEE -+:10BB2000656E61626C655F356700706163616C7042 -+:10BB30007772326700747869716C6F746600706137 -+:10BB400063616C69647835676C6F31007061636143 -+:10BB50006C61746835676869006F70656E6C7070D1 -+:10BB600077726C696D006E6F6973655F63616C5F9E -+:10BB7000646267006F70656E6C706761696E69649E -+:10BB800078613135330074786761696E74626C0076 -+:10BB9000706163616C69647835676869006F7065AE -+:10BBA0006E6C706761696E69647861313537006EFB -+:10BBB0006F6973655F63616C5F7570646174650064 -+:10BBC0006F66646D64696766696C747479706535F5 -+:10BBD000670070616763326700766261745F6D75DC -+:10BBE0006C740073776374726C6D61705F326700A0 -+:10BBF000706163616C616C696D0069716C6F636128 -+:10BC00006C70777232670076626174736D63006185 -+:10BC10006463726673657132670076626174736D16 -+:10BC2000660072786761696E6261636B6F666676E3 -+:10BC3000616C006F70656E6C706761696E696478C5 -+:10BC4000622564006F66646D3267706F007278679A -+:10BC500061696E74626C776C6267610070616361C8 -+:10BC60006C6174683567686931006E6F6973655F10 -+:10BC700063616C5F706F5F626961735F32670072EE -+:10BC800066726567303838006F70656E6C7067611A -+:10BC9000696E696478613136310064796E707772EB -+:10BCA0006C696D656E00706163616C69647835679D -+:10BCB000310074656D70636F7272780064616372D5 -+:10BCC0006174653267007061726670730070613014 -+:10BCD00062325F6C6F00747869716C6F706170753F -+:10BCE00032670074656D7073656E73655F6F707435 -+:10BCF000696F6E00706163616C61746835676C6F49 -+:10BD00003100706163616C69647832673100747806 -+:10BD1000616C706662797032670064616367633278 -+:10BD20006700756E6D6F645F727373695F6F6666CF -+:10BD3000736574006F70656E6C70766F6C74636F92 -+:10BD400072720072786761696E74626C31303000B3 -+:10BD50006E6F6973655F63616C5F6E665F7375625A -+:10BD60007374726163745F76616C00747373697469 -+:10BD70007864656C61790063636B3267706F006330 -+:10BD8000636B507772496478436F72720063636BC0 -+:10BD900064696766696C7474797065006C6F63635D -+:10BDA0006D6F646531006C6F696461636D6F6465AC -+:10BDB000356700706163616C617468356700746534 -+:10BDC0006D705F71007273736973617632670073AF -+:10BDD00070757261766F69645F656E61626C653201 -+:10BDE000670070613062315F6C6F00766261745F12 -+:10BDF00071006D61787032676130006E6F697365D4 -+:10BE00005F63616C5F7265665F3567006F66646D66 -+:10BE1000616E616C6F6766696C746277326700701F -+:10BE20006163616C61746832670070613062300018 -+:10BE30007061306231007061306232006F70656E27 -+:10BE40006C706761696E696478613336006E6F6922 -+:10BE500073655F63616C5F61646A5F356700697118 -+:10BE60006C6F63616C69647832676F666673006FCC -+:10BE700070656E6C706761696E69647861313030CD -+:10BE800000706163616C7077723267310072617744 -+:10BE900074656D7073656E7365006F70656E6C7040 -+:10BEA0006761696E696478613130340069716C6F03 -+:10BEB00063616C6964783267006F70656E6C707076 -+:10BEC00077726374726C006F70656E6C7067616915 -+:10BED0006E696478613130380072786761696E74B8 -+:10BEE000656D70636F727235676D0074785F746F23 -+:10BEF0006E655F706F7765725F696E646578006FFD -+:10BF000070656E6C707265667077720072737369BB -+:10BF1000736D63326700706163616C61746835676B -+:10BF200031006E6F6973655F63616C5F706F5F6234 -+:10BF30006961735F3567006E6F6973655F63616C1C -+:10BF40005F706F5F32670072786761696E74656DEC -+:10BF500070636F727235676C00706163616C6964E5 -+:10BF600078356731746800706167633567007061A8 -+:10BF700063616C69647835676C6F317468007473E1 -+:10BF800073696F66667365746D696E006F70656E58 -+:10BF90006C706761696E696478613430006F7065D8 -+:10BFA0006E6C706761696E696478613434007266C2 -+:10BFB000726567303333006F70656E6C70676169EE -+:10BFC0006E696478613438006E6F6973655F6361B0 -+:10BFD0006C5F686967685F6761696E007266726549 -+:10BFE00067303338006E6F6973655F63616C5F61E2 -+:10BFF000646A5F3267006D656173706F7765723177 -+:10C00000006D656173706F77657232006F70656E79 -+:10C010006C706761696E6964786131313600627095 -+:10C0200068797363616C650072786761696E7465C5 -+:10C030006D70636F7272326700706163616C696406 -+:10C040007835676C6F0061613267006F66646D649C -+:10C05000696766696C74747970650074656D705F8A -+:10C060006D756C74007662617473617600706163E3 -+:10C07000616C61746835676C6F00706163616C69D5 -+:10C08000647832673174680072786761696E7465CC -+:10C090006D70636F72723567680063636B5077729F -+:10C0A0004F6666736574007478707772696E646544 -+:10C0B000780069716C6F63616C69647835676F666D -+:10C0C00066730070613062305F6C6F00676D67632C -+:10C0D000326700706163616C6964783567686931E3 -+:10C0E0007468007278706F3267006E6F6973655F95 -+:10C0F00063616C5F656E61626C655F3267006F7073 -+:10C10000656E6C706761696E696478613532006F65 -+:10C1100070656E6C706761696E6964786135360050 -+:10C120006F70656E6C706761696E696478613131DA -+:10C130003200706163616C69647835670074656DA5 -+:10C140007073617600747269736F32670076626132 -+:10C15000745F616464006F70656E6C706761696EB6 -+:10C1600069647861313230006F70656E6C70676140 -+:10C17000696E69647861313234006F70656E6C701D -+:10C180006761696E6964786131323800747269641C -+:10C19000783267006F66646D64696766696C747491 -+:10C1A000797065326700696E69747869647832679E -+:10C1B0000068775F697163616C5F656E00697163C8 -+:10C1C000616C5F7377705F646973006D75785F672A -+:10C1D00061696E5F7461626C6500747373696F6628 -+:10C1E000667365746D617835676800747373696F21 -+:10C1F00066667365746D617835676C007473736916 -+:10C200006F66667365746D617835676D0074656D12 -+:10C2100070736D630074656D70736D660074737315 -+:10C22000696F66667365746D6178006F70656E6CBA -+:10C23000706761696E696478613630007478616C2A -+:10C24000706662797032675F63636B006F70656EF2 -+:10C250006C706761696E6964786136340066726516 -+:10C26000716F66667365745F636F7272006F70657D -+:10C270006E6C706761696E69647861313332006F2A -+:10C2800070656E6C706761696E69647861313336B0 -+:10C29000007874616C6D6F646500747373697469A0 -+:10C2A0006D65006E6F6973655F63616C5F706F5F72 -+:10C2B000356700747373696F66667365746D696E54 -+:10C2C00035676800B8C70200600000001200000077 -+:10C2D000000000002000000028C702002600000027 -+:10C2E0000E0000000000000010000000B4CC0200AE -+:10C2F000980000000D000000000000002000000079 -+:10C3000074C702004400000011000000000000009B -+:10C310000800000074D102001000000010000000AE -+:10C3200000000000080000000000000040000000C5 -+:10C3300080000000C00000000100000005000000B7 -+:10C3400002000000060000000A0000004A00000091 -+:10C350008A000000CA0000000A0100004A01000033 -+:10C360008A0100008A0500008A0900008A0D000089 -+:10C370008A1100008A5100008A9100008AD10000D1 -+:10C380008A1101008A5101008A9101008900000090 -+:10C390008AD101008A1102000000000000000000A4 -+:10C3A000000000000000000000000000000000008D -+:10C3B000000000000000000000000000000000007D -+:10C3C000000000000000000000000000000000006D -+:10C3D000000000000000000000000000000000005D -+:10C3E000000000000000000000000000000000004D -+:10C3F000000000000000000000000000000000003D -+:10C40000000000000000000000000000000000002C -+:10C41000000000000000000000000000000000001C -+:10C42000000000000000000000000000000000000C -+:10C4300000000000000000000000000000000000FC -+:10C4400000000000000000000000000000000000EC -+:10C4500000000000000000000000000000000000DC -+:10C4600000000000000000000000000000000000CC -+:10C4700000000000000000000000000000000000BC -+:10C4800000000000000000000000000000000000AC -+:10C49000000000000000000000000000000000009C -+:10C4A000000000000000000003001300410300131F -+:10C4B000004003001200410300120040030011007D -+:10C4C0004103001100400300100041030010004030 -+:10C4D000030010003E030010003C030010003A036C -+:10C4E000000F003D03000F003B03000E003D030062 -+:10C4F0000E003C03000E003A03000D003C03000D4B -+:10C50000003B03000C003E03000C003C03000C0049 -+:10C510003A03000B003E03000B003C03000B003B02 -+:10C5200003000B003903000A003D03000A003B032F -+:10C53000000A0039030009003E030009003C030023 -+:10C5400009003A0300090039030008003E0300080F -+:10C55000003C030008003A0300080039030008000B -+:10C5600037030007003D030007003C030007003AC3 -+:10C5700003000700380300070037030006003E03EE -+:10C580000006003C030006003A03000600390300E1 -+:10C5900006003703000600360300060034030005DA -+:10C5A000003D030005003B030005003903000500C2 -+:10C5B000380300050036030005003503000500338D -+:10C5C000030004003E030004003C030004003A039F -+:10C5D00000040039030004003703000400360300A0 -+:10C5E000040034030004003303000400310300049A -+:10C5F0000030030004002E030003003C030003008E -+:10C600003A03000300390300030037030003003638 -+:10C61000030003003403000300330300030031036D -+:10C6200000030030030003002E030003002D03006D -+:10C6300003002C030003002B030003002903000266 -+:10C64000003D030002003B0300020039030002002A -+:10C6500038030002003603000200350300020033F5 -+:10C6600003000200320300020030030002002F0327 -+:10C670000002002E030002002C030002002B030026 -+:10C6800002002A030002002903000200270300021F -+:10C69000002603000200250300020024030002001C -+:10C6A00023030002002203000200210300020020F5 -+:10C6B000030001003F030001003D030001003B03B4 -+:10C6C00000010039030001003803000100360300B7 -+:10C6D00001003503000100330300010032030001B3 -+:10C6E0000030030001002F030001002E03000100B1 -+:10C6F0002C030001002B030001002A030001002984 -+:10C7000003000100270300010026030001002503A8 -+:10C7100000010024030001002303000100220300A4 -+:10C7200001002103000100200004000400040004B3 -+:10C7300000040004000400040004000400040104D8 -+:10C7400080048204830484040004000400040004C0 -+:10C7500000040004000400040004010480048204B6 -+:10C760008304840485048604050506050705080579 -+:10C7700009050A05090C12181818090C12181818BE -+:10C7800000000C076F7A060C0F7B7E0105080B0E6C -+:10C79000110000000000000000000306090C0F1249 -+:10C7A000000000000000000000000306090C00006B -+:10C7B0000000000000000000000000000400000075 -+:10C7C0004000000080000000C000000001000000E8 -+:10C7D000050000004500000085000000C5000000C5 -+:10C7E00005010000450100008501000085050000ED -+:10C7F00085090000850D000089090000890D0000F1 -+:10C8000089110000895100008991000089D1000040 -+:10C8100089110100854D0000858D000085CD000047 -+:10C820008951010089910100000000000000000012 -+:10C8300000000000000000000000000000000000F8 -+:10C8400000000000000000000000000000000000E8 -+:10C8500000000000000000000000000000000000D8 -+:10C8600000000000000000000000000000000000C8 -+:10C8700000000000000000000000000000000000B8 -+:10C8800000000000000000000000000000000000A8 -+:10C890000000000000000000000000000000000098 -+:10C8A0000000000000000000000000000000000088 -+:10C8B0000000000000000000000000000000000078 -+:10C8C0000000000000000000000000000000000068 -+:10C8D0000000000000000000000000000000000058 -+:10C8E0000000000000000000000000000000000048 -+:10C8F0000000000000000000000000000000000038 -+:10C900000000000000000000000000000000000027 -+:10C910000000000000000000000000000000000017 -+:10C920000000000000000000000000000000000007 -+:10C9300000000000000000008000800080008000F7 -+:10C9400080008000800080008000810082008300E1 -+:10C9500084008500040105018000800080008000C3 -+:10C9600080008000800081008200830084008500B8 -+:10C9700004010501060107011901870188018901E8 -+:10C980008A018B0107001F004807001F00460700AF -+:10C990001F004407001E004307001D004407001C41 -+:10C9A000004407001B004507001A00460700190055 -+:10C9B0004607001800470700170048070017004601 -+:10C9C0000700160047070015004807001500460736 -+:10C9D000001500440700150042070015004007003D -+:10C9E00015003F0700140040070013004107001323 -+:10C9F000004007001200410700120040070011002C -+:10CA000041070011004007001000410700100040DE -+:10CA1000070010003E070010003C070010003A0716 -+:10CA2000000F003D07000F003B07000E003D070010 -+:10CA30000E003C07000E003A07000D003C07000DF9 -+:10CA4000003B07000C003E07000C003C07000C00F8 -+:10CA50003A07000B003E07000B003C07000B003BB1 -+:10CA600007000B003907000A003D07000A003B07DA -+:10CA7000000A0039070009003E070009003C0700D2 -+:10CA800009003A0700090039070008003E070008BE -+:10CA9000003C070008003A070008003907000800BA -+:10CAA00037070007003D070007003C070007003A72 -+:10CAB00007000700380700070037070006003E0799 -+:10CAC0000006003C070006003A0700060039070090 -+:10CAD0000600370700060036070006003407000589 -+:10CAE000003D070005003B07000500390700050071 -+:10CAF000380700050036070005003507000500333C -+:10CB0000070004003E070004003C070004003A0749 -+:10CB1000000400390700040037070004003607004E -+:10CB20000400340700040033070004003107000448 -+:10CB30000030070004002E070003003C070003003C -+:10CB40003A070003003907000300370700030036E7 -+:10CB50000700030034070003003307000300310718 -+:10CB600000030030070003002E070003002D07001C -+:10CB700003002C070003002B070003002907000215 -+:10CB8000003D070002003B070002003907000200D9 -+:10CB900038070002003607000200350700020033A4 -+:10CBA00007000200320700020030070002002F07D2 -+:10CBB0000002002E070002002C070002002B0700D5 -+:10CBC00002002A07000200290700020027070002CE -+:10CBD00000260700020025070002002407000200CB -+:10CBE00023070002002207000200210700020020A4 -+:10CBF000070001003F070001003D070001003B075F -+:10CC000000010039090C12181818090C121818180C -+:10CC100000000C076F7A060C0F7B7E0105080B0ED7 -+:10CC2000110000000000000000000306090C0F12B4 -+:10CC3000000000000000000000000306090C0000D6 -+:10CC4000000000000000000007001000390700107D -+:10CC500000380700100036070010003407001000ED -+:10CC60003307001000310700100030070010002FBC -+:10CC7000070010002D070010002C070010002B07E4 -+:10CC80000010002A070010002807001000270700E6 -+:10CC900010002607001000250700100024070010D0 -+:10CCA00000230700100022070010002107001000D9 -+:10CCB0002000000000000000400000000000000014 -+:10CCC00040000000000000004000000000000000E4 -+:10CCD00040000000000000004000000000000000D4 -+:10CCE00040000000000000004000000000000000C4 -+:10CCF00040000000000000004000000000000000B4 -+:10CD00004000000000000000400000000000001093 -+:10CD1000400000000000000048000000000000206B -+:10CD20004800000000000030480000000000004003 -+:10CD300048000000000000504800000000000060B3 -+:10CD4000480000000000005050000000000000609B -+:10CD50005000000000000070500000000000008043 -+:10CD6000500000000000009050000000000000A0F3 -+:10CD700050000000000000B050000000000000C0A3 -+:10CD800050000000000000D050000000000000E053 -+:10CD900050000000000000F050000000000000E023 -+:10CDA00058000000000000005900000000000010C2 -+:10CDB0005900000000000020590000000000003071 -+:10CDC0005900000000000040590000000000005021 -+:10CDD0005900000000000060590000000000000041 -+:10CDE00040000000000000004000000000000000C3 -+:10CDF00040000000000000004000000000000000B3 -+:10CE000040000000000000004000000000000000A2 -+:10CE10004000000000000000400000000000000092 -+:10CE20004000000000000010400000000000000072 -+:10CE30004800000000000020480000000000003012 -+:10CE400048000000000000404800000000000050C2 -+:10CE50004800000000000060480000000000005092 -+:10CE60005000000000000060500000000000007052 -+:10CE70005000000000000080500000000000009002 -+:10CE800050000000000000A050000000000000B0B2 -+:10CE900050000000000000C050000000000000D062 -+:10CEA00050000000000000E050000000000000F012 -+:10CEB00050000000000000705100000000000080E1 -+:10CEC0005100000000000090510000000000002010 -+:10CED0005900000000000030590000000000004030 -+:10CEE00059000000000000505900000000000060E0 -+:10CEF00059000000000000A059000000000000B030 -+:10CF000059000000000000000000000000000000C8 -+:10CF10000000000000000000080000000000000009 -+:10CF200008000000000000000800000000000000F1 -+:10CF300008000000000000000800000000000000E1 -+:10CF400008000000000000000800000000000000D1 -+:10CF500008000000000000000800000000000010B1 -+:10CF60000800000000000020080000000000003061 -+:10CF70000800000000000040080000000000005011 -+:10CF800008000000000000401000000000000050F9 -+:10CF900010000000000000601000000000000070A1 -+:10CFA0001000000000000080100000000000007071 -+:10CFB0001800000000000080180000000000009031 -+:10CFC00018000000000000A018000000000000B0E1 -+:10CFD00018000000000000C018000000000000D091 -+:10CFE00018000000000000E018000000000000F041 -+:10CFF00018000000000000001900000000000010F0 -+:10D00000190000000000002019000000000000309E -+:10D01000190000000000004019000000000000504E -+:10D0200019000000000000601900000000000070FE -+:10D03000190000000000008019000000000000003E -+:10D0400008000000000000000800000000000000D0 -+:10D0500008000000000000000800000000000000C0 -+:10D0600008000000000000000800000000000000B0 -+:10D070000800000000000010080000000000002070 -+:10D080000800000000000030080000000000004020 -+:10D0900008000000000000500800000000000040F0 -+:10D0A00010000000000000501000000000000060B0 -+:10D0B0001000000000000070100000000000009050 -+:10D0C0001100000000000070180000000000008047 -+:10D0D000180000000000009018000000000000A0F0 -+:10D0E00018000000000000B018000000000000C0A0 -+:10D0F00018000000000000D018000000000000E050 -+:10D1000018000000000000F01800000000000000FF -+:10D1100019000000000000101900000000000020AD -+:10D12000190000000000003019000000000000405D -+:10D13000190000000000005019000000000000600D -+:10D1400019000000000000701900000000000080BD -+:10D1500019000000000000A019000000000000B04D -+:10D1600019000000000000000000000000000000A6 -+:10D17000000000005F36291F5F36291F5F36291F18 -+:10D180005F36291F28C30200600000001200000063 -+:10D19000000000002000000038C902002600000046 -+:10D1A0000E000000000000001000000014CF02007C -+:10D1B000980000000D0000000000000020000000AA -+:10D1C00004CC020044000000110000000000000038 -+:10D1D0000800000074D102001000000010000000E0 -+:10D1E00000000000080000000A5254452028257362 -+:10D1F0002D25732573257329202573206F6E2042FA -+:10D20000434D25732072256420402025642E25641B -+:10D210002F25642E25642F25642E25644D487A0A17 -+:10D22000000000002DE9FF4106460D460846FC219E -+:10D2300017469846D9F34CF5044608B91E302DE040 -+:10D240000021FC22D4F3FCF60A9B04F1640204F1F1 -+:10D250006801009301920291304629463A464346BE -+:10D26000FBF73EFC206608B90B2017E040F61201E0 -+:10D270000022DDF3C3F700210A46E0662560206E38 -+:10D28000DDF3E0F52046F8F707FB206EFBF7EAFA3E -+:10D2900028462146FC22D9F32BF5002004B0BDE836 -+:10D2A000F081C04601BC600300104E03BFDE02F0F7 -+:10D2B0000C0E0280C12700000403BFDE02F00D6FD8 -+:10D2C000035B5E02F0000601BC6013001043000126 -+:10D2D0005E02F0000000025E02F0117A00025E02BF -+:10D2E000F0118F020200BF00007302045EFF000015 -+:10D2F0000E006B446557800E01846002F7F7BF0192 -+:10D30000BC6003000AAE00025E02F00F960202DE6D -+:10D31000FF000013006B44655620130182E002F702 -+:10D32000F7BF03BFDE02F005A200682B6F000018F4 -+:10D330000280DEFF000073006B44655B6073018454 -+:10D34000E006F577AB00025E02F0112F020480C701 -+:10D3500000001A028180C700001C01806002F7F7FC -+:10D36000BF01BC6003000AE200682B070000270031 -+:10D37000E844655837A1006DDE8557402300682BCF -+:10D380004300002700E844655A17A1006DDE855769 -+:10D39000402503BFDE02F0002701BC6003000AC283 -+:10D3A00001BC6003000AC101BC6003000AD001BCDB -+:10D3B0006003000AC80202DEB300002A0200420332 -+:10D3C00000002A00025E02F00B1602845EB3000029 -+:10D3D000730068AB0F0000730283DEB700002E02FB -+:10D3E0000180C700004800B02ACB0017A202802BA2 -+:10D3F000F300003500B02B230017A1006DDE855C23 -+:10D40000E06400685E8700003500682C0700003586 -+:10D4100000B02C070017A200682B0B00003A00E8B0 -+:10D4200044655857A1006DDE86F4406400E05E85D7 -+:10D4300055F7A1006DDE86F440640202DEBB0000F9 -+:10D440004800682ABB00004800E8446556D7A100A0 -+:10D45000E02ABB0157A2006EDE86F440420182E062 -+:10D4600002F5D7AE01BC6003000AAE03BFDE02F0D6 -+:10D47000004800E82ABAF437A100902ABB0037A27E -+:10D48000006E2ABEF4404600B02ABF0017A2006911 -+:10D49000DE86F4404803BFDE02F000640283DEB79C -+:10D4A00000005C028881AB00005A02035EB70000F6 -+:10D4B00073020480C700004D02005EFF00005A02A4 -+:10D4C0008080BF00005A0204DEB700005100682BC4 -+:10D4D0001708607303BFDE02F0005A028400C70021 -+:10D4E0000053028600C700005500682B0B00005A4D -+:10D4F00002812C4700005A00E844655737A1006DAF -+:10D50000DE8558005A006CC46557607300B04467EC -+:10D51000000ABB02845EB700007300025E02F011D5 -+:10D520004903BFDE02F0007301BC63FF1FF7A100D7 -+:10D53000684586F4205A0203C57300006402845EC5 -+:10D54000B7000064020100C7000073006B44655718 -+:10D5500080730020E3FE1460730282DEBB00007360 -+:10D5600002022C470000670282DEBB00006703BF97 -+:10D57000DE02F0005A028881AB0000730282DEB343 -+:10D58000000073028080BF0000730284DEAF0000E1 -+:10D590007302825EBB00007303A0DE02F0006F0224 -+:10D5A00000420300006F00025E02F00B1601836070 -+:10D5B00002F5B7AD0184E006F577AB01BC6003006E -+:10D5C0000AC300B04467000AC4018060020D906C79 -+:10D5D00003595E02F0007503D85E02F0007603D8AE -+:10D5E000DE02F0007701BC618300112900B0007BEE -+:10D5F00000112B01BC630300112303125E02F00A29 -+:10D600008F03975E02F00B2703D05E02F002F40353 -+:10D61000D0DE02F0051003D5DE02F00A4C03915E65 -+:10D6200002F005760396DE02F00A470288C1730015 -+:10D63000009E03C45E02F006E703C75E02F0071611 -+:10D6400003DCDE02F011CF03AA5E02F00759038665 -+:10D65000DE02F00A870287C037000A8703835E0272 -+:10D66000F008AB0391DE02F005F803C2DE02F00A17 -+:10D67000EC00025E02F00F9500025E02F0117A03E8 -+:10D68000D4DE02F0068103A3DE02F0000200025E97 -+:10D6900002F00C6300025E02F00EC403A25E02F010 -+:10D6A000009B03565E02F000980186600609104850 -+:10D6B000031F5E02F00098006A5E2300009700B02E -+:10D6C000002700178800E85E2300378803A65E0263 -+:10D6D000F0010500025E02F00F5D0028600E08E117 -+:10D6E0002803C4DE02F00B5E0020C20300213003D9 -+:10D6F000BFDE02F0017D03815E02F000A00300DEC8 -+:10D7000002F000820188E0020B905C03BFDE02F0B1 -+:10D7100002F1028740630000A20282C1070000A359 -+:10D7200001866006F43018028640630000A500B050 -+:10D730005E870017A10002DE02F00000028740634E -+:10D740000000A800B05E8B0010190186E006F430DE -+:10D75000180281DEAF0000AD0286C0630000AC009D -+:10D76000B05E870017A10002DE02F0000001BC607D -+:10D77000030280060280DE070000B901DA6002F0D1 -+:10D78000178002085E070000C901BC60031E17A1D4 -+:10D7900000E05E02F4306501BC60031C17A100E0EC -+:10D7A0005E02F4306401BC600300281803BFDE028F -+:10D7B000F000CF01105E030017A100885E870037DC -+:10D7C000A200E05E86F457A100E0015AF430630243 -+:10D7D0008600C30000C200B0560B00106200B054B7 -+:10D7E0000300106201BC600300281803BFDE02F0D2 -+:10D7F00000D100B0418F0010620109DE030017A1C3 -+:10D8000000885E870057A100E05E850597A100E0D3 -+:10D810005E8703C00601BC600300481803BFDE0238 -+:10D82000F000D101BC60070217A100E05E02F430F5 -+:10D830006501BC60070017A100E05E02F4306401DE -+:10D84000BC600318000601BC600300081800B05A51 -+:10D850000300106200B0580300106301050143008B -+:10D8600017A10088001AF420060002DE02F0000072 -+:10D8700001BC600306379201BC63FF1FF0C301BC0B -+:10D8800060031890E301BC63FF1FF0C501BC63FF98 -+:10D890001FF0C601BC63FF1FF0C700B02C5B001077 -+:10D8A000E500B02C5F0010E600B02C630010E7022A -+:10D8B00080AC470000E701BC600300101000B040DE -+:10D8C0004300180000B040470010E501BC600300B1 -+:10D8D000301000B0404300180000B040470010E690 -+:10D8E00001BC600300501000B0404300180000B0BD -+:10D8F00040470010E701BC63FF1FF0C40002DE02D6 -+:10D90000F0000000E840330097A100B0400B001782 -+:10D91000A3006D5E86F460EE00905E8F0037A30377 -+:10D92000BFDE02F000EF00905E870037A301BC600D -+:10D930001F1417A100E05E8EF437A301F041970099 -+:10D9400017A1006DDE86F461030287C1970000F71E -+:10D9500001385A030017A1013C5A030017A203BF64 -+:10D96000DE02F000F9013C5A030017A101385A0702 -+:10D970000017A200685E86F480FE00D85E8B003738 -+:10D98000A200E14196F4506500E1C19700306503C3 -+:10D99000BFDE02F000F100D85E8B0037A200E1414B -+:10D9A00096F457A100E1DE870037A101F05E870001 -+:10D9B00017A1006EDE86F4610401BC63FF1FF7A4AB -+:10D9C0000002DE02F000000020E38E090002031EC8 -+:10D9D000DE02F0010B039F5E02F0010B01BC60430D -+:10D9E0000117A100A84122F4304803BFDE02F00075 -+:10D9F0000200689B6F0000990208411F00010801A6 -+:10DA0000816005620B1000025E02F00B1600B00090 -+:10DA1000AB00108600B0016300108A00025E02F0C5 -+:10DA20000D9601BC600304179200B0003B00111D6D -+:10DA30000190600609104803A1DE02F00122018175 -+:10DA4000E00609104801BC600300904201BC60037D -+:10DA500000112D039EDE02F0012501846002F29781 -+:10DA60009400B0451700178F00B05E1700179002A2 -+:10DA700000441F00012001856002091048018160F7 -+:10DA80000700104701F0DE0F0037A100A044B6F4F4 -+:10DA90003145039EDE02F0012501BC613712B080E2 -+:10DAA00003BFDE02F0000200A044B42A314501BCED -+:10DAB000612712708003BFDE02F000020020E082C6 -+:10DAC000090002010CDE530017A101885E870010D7 -+:10DAD0004701BC60030050420108411F0017A1012B -+:10DAE0008CDE86F2979403BFDE02F000020002DEB5 -+:10DAF00002F000000020E07E09000200025E02F059 -+:10DB00000F670283C21F000002020280F300013A85 -+:10DB100000B044670017A1017C5E862357A30283EF -+:10DB20005EFF00013900E000FAF46830018360060E -+:10DB3000F7F7BF006BDE8D06013E0206D003000141 -+:10DB40004200E950862337A100E8D08A2357A2007B -+:10DB500069DE8B00014200025E02F00B160191604B -+:10DB60001684F42700E020C300883003BFDE02F0F3 -+:10DB700002CC00025E02F002CF020400BF00014AA4 -+:10DB800003945E02F000020020C28F02000200A097 -+:10DB9000428F01F78000685E002DC00200025E0225 -+:10DBA000F00B1603BFDE02F000040201C28F00007A -+:10DBB00002011400630017A100685E870060020084 -+:10DBC000025E02F00B160194600F00001800025E66 -+:10DBD00002F0015103BFDE02F000040114006300F3 -+:10DBE00017A100B05E870010A501BC601311106082 -+:10DBF00000685E8700015800E0418306D06000E8BD -+:10DC00005E870037A103BFDE02F00154028050C3DB -+:10DC1000000162018760040310A000B000630010DF -+:10DC2000B400B042D3001800008841830030B60130 -+:10DC3000BC60030B10B500B0006300B0B40317DE86 -+:10DC400002F0015F0397DE02F0016001806006864A -+:10DC500014300002DE02F000000020E01280417C5F -+:10DC6000018760040310A000B000630010B401BC81 -+:10DC700060030E10B500B0006300F0B401BC605743 -+:10DC80000490B600B000630010B401BC600302D081 -+:10DC9000B50207500B00017901BC600303D0B50148 -+:10DCA0008E6002F297940204500B0001720204D0BD -+:10DCB0000B00017201866006F2979400E042D700E3 -+:10DCC000D0B500A0500B1117A10068DE87110178B4 -+:10DCD0000186E006F2979400E042D70050B50207B3 -+:10DCE000D00B00017800E042D70090B500B042D7D9 -+:10DCF0000011E100B0006300B0B40317DE02F001D0 -+:10DD00007A0397DE02F0017B0002DE02F0000000E1 -+:10DD10006820DF000180006CC46506E00401BC607F -+:10DD200003000837006820D7000183006CC4650633 -+:10DD3000C00401BC60030008350020E0BE090002F9 -+:10DD400003905E02F0000403A25E02F001BE020234 -+:10DD500000BF0001880203C5730001B100682F6B8A -+:10DD600000018C00E844657B57A1006D5E857B2136 -+:10DD7000B101BC6003000BDA00682D9B0001B10209 -+:10DD800082C1070001B1028042030001B10285C5D2 -+:10DD9000230001B1028640370001B10181E006F5A0 -+:10DDA00077AB00B02D9F0017A101BC602F1077A2A8 -+:10DDB00001BC60030017A300025E02F0131200B062 -+:10DDC0002DA30017A101BC602F1777A201BC60032F -+:10DDD0000017A300025E02F0132001BC60131A17A3 -+:10DDE000A100025E02F000A200B040670417A2008A -+:10DDF000025E02F000A800E0446700D7A1006CC4F6 -+:10DE000066F4219F01BC60130ED7A100025E02F0F0 -+:10DE100000A200A040673FF7A201BC601314D7A185 -+:10DE200001BC62030017A300B05E8AF477A200026F -+:10DE30005E02F000A800B02D9F0017A101BC602F6A -+:10DE40000D37A201BC60030017A300025E02F013AD -+:10DE50001200B02DA30017A101BC602F13B7A201BF -+:10DE6000BC60030017A300025E02F013200181E0F2 -+:10DE700002F577AB01BC6003000B6600025E02F0A6 -+:10DE80000E74020200BF0001BD0284DEAF0001B8C3 -+:10DE900002035EB70001BD00025E02F010FB020348 -+:10DEA0005EB70001BD03BFDE02F0000202035EB7F1 -+:10DEB0000001BB020480C70001BD02805EFF0001BB -+:10DEC000BD00025E02F010BC03BFDE02F0000200E3 -+:10DED000025E02F00F670200421F0001D600684296 -+:10DEE000F30001C1006D42F30041D601140063004C -+:10DEF00017A100B05E870017A203A25E02F001CA5C -+:10DF00000183E0020D906C03145E02F001D8006EF4 -+:10DF1000C4568061D8028145230001D8006E5E8717 -+:10DF20000061D601BC60030077A200886006F45748 -+:10DF3000A300885E8B01001800E85E8B0037A2000A -+:10DF400020C28EF461D0006ADE86F441CA03BFDECF -+:10DF500002F001D6020400BF00020200900063013B -+:10DF60000165008085970217A100E064820DA1661B -+:10DF700000025E02F00F1D03BFDE02F0020201820A -+:10DF8000600209104803BFDE02F0000201BC60031A -+:10DF900000111500B0017F0017A6031F5E02F001FB -+:10DFA000E7020300C30001DD0020C28F0201E1038C -+:10DFB000255E02F001E70020C28F0201E1006881C6 -+:10DFC00053FFE00403BFDE02F001E301946013009D -+:10DFD000001803BFDE02F00202039EDE02F001E63B -+:10DFE0000068DE980BC1E60201411F000CB40185F8 -+:10DFF000600209104800685E980BC1EB00695E9FE3 -+:10E000000062070298428F0001EB03BFDE02F002BC -+:10E01000070201411F000CB4020400BF0001F2021C -+:10E0200018428F000CB400025E02F00EFF00025E88 -+:10E0300002F00F1D0194058700001803BFDE02F0F7 -+:10E040000202020013BB0001FB0200156B0001FE7F -+:10E0500000B013470017A10068DE84A7A1FB00B041 -+:10E06000134B0017A10068DE84A7C1FB00B0134F5B -+:10E070000017A10068DE84A7E1FB029E1397000150 -+:10E08000FE0201C28F0002000194600F000018031D -+:10E09000BFDE02F002020201C28F000200018060B6 -+:10E0A000060D906C0200C28F000CB4019460070052 -+:10E0B000001800025E02F00151020400BF000237A6 -+:10E0C000028500630002370183E0060D906C03BFF8 -+:10E0D000DE02F0023701BC60031810600129500B0A -+:10E0E00000179200B0017B001065006800EB000291 -+:10E0F0001000885A130117A100E84466F437A10004 -+:10E100006EDE8407421000E0029B0020A603BFDE03 -+:10E1100002F0067A019060120910480194601F0015 -+:10E12000001801085A0F00178101885E0681540A01 -+:10E1300001345A0F00178000025E02F000AF00B0F9 -+:10E14000017B00106500B056230017A100E05E8639 -+:10E15000A097A100E85E8400F40300E85E8400F468 -+:10E160001600B05A0300141300B05A07001414002C -+:10E17000B05A0B0014150068DE0700422800E800C2 -+:10E18000970057A101BC5E86F0141B017C5E8700DE -+:10E19000F41C00B0206300178100025E02F00D9AAB -+:10E1A00000B0017B00106501085A0F00178100B014 -+:10E1B0005E8700141E03BFDE02F0022B00B056176C -+:10E1C00000141B00B0561B00141C00B054130014A4 -+:10E1D0001E00B05013001086006D00A700823101B0 -+:10E1E00090016300108A00B0418F00106200025E4F -+:10E1F00002F0119C00B0422B00140601BC60031811 -+:10E2000017A1006DC18C20023401BC60030297A1EC -+:10E2100000E05E840377A100E05E86B0111D03BFBD -+:10E22000DE02F002AB020300C7000247020CD0037B -+:10E23000000247011400630017A102850063000279 -+:10E24000470080DE8701F7A201BC601B0257A200D5 -+:10E25000E05E8A0DB06500B041970014320080DEA8 -+:10E260008700B7A201BC60171FD7A200E05E8A0D2D -+:10E27000B06400B041930014330068D81300025218 -+:10E2800002005A1B0002490180600684F42703BF84 -+:10E29000DE02F005A20201D00300024900B0509B4B -+:10E2A00000142F0281D0C70002C900025E02F002F2 -+:10E2B000CF010BD0030017A1013C502B0017A20186 -+:10E2C0008C5E86F457A1014801430017A200685EE6 -+:10E2D00086F442520191601284F42703BFDE02F0FB -+:10E2E00002CC00025E02F0016300B0501300108601 -+:10E2F00000B0501700108A00682FC300025D029121 -+:10E30000D01700025B0291D01B00025B0291D01F6C -+:10E3100000025B0291D02300025B03BFDE02F00229 -+:10E320005D0191600284F42703BFDE02F002CC039A -+:10E33000A25E02F0028A020CD003000279020300FE -+:10E34000C700027800B050CB00106500025E02F0FA -+:10E350001235020350C700026601BC60230097A17A -+:10E3600000A85002F4340003BFDE02F0027D020474 -+:10E3700081AB000268006D4246C0800400B05A13B1 -+:10E3800000178000025E02F000B900B0540F0014C4 -+:10E390001E00B05A070017A100B05A1300178001E1 -+:10E3A000875A16F0178000B0418F00106500025E9A -+:10E3B00002F011A500E05E86A0740302875E0300F0 -+:10E3C00002770109DE030017A300E05E8B0077A24D -+:10E3D00000E05E8AF477A200885E8B0037A100E03F -+:10E3E0005E86F4508903BFDE02F0027D006D424A72 -+:10E3F000848004010650070017A1028CD00300029C -+:10E400007C00685E8700027D0182DE8686343101F1 -+:10E410008260028634310020D00304028300B050B1 -+:10E420004F0011F200B050530011F300B0505700EC -+:10E4300011F401BC60030091F003945E02F0028AC3 -+:10E44000020650030002860287DEAF00028A0281C4 -+:10E4500050030004F10202D0C70002890208502BC9 -+:10E4600000028A0285D003000508019060128634FC -+:10E470003103A25E02F0029700B0500F00111602A5 -+:10E4800002D0C700028F00B0505B0011160282D08C -+:10E4900003000297028147C30002900280504F00A0 -+:10E4A0000295002047C73F82970020C7DB00C2CB00 -+:10E4B00003BFDE02F0029703A55E02F0029702801E -+:10E4C000C7DF0002CB028850C70002B10129500B00 -+:10E4D000001792020300C70002A4020CD00300023E -+:10E4E000A4028350C70002A400B050CB0010650105 -+:10E4F000385A1300178001825A17005781010E5AAB -+:10E50000130017A1018E5E86F037810202D0C7008A -+:10E5100002B100B0501B00108A03BFDE02F002B14E -+:10E520000282D0C70002AB013850270017800108D3 -+:10E530005013001781010250130017A101825E865B -+:10E54000F0378100B0507F00108903BFDE02F00277 -+:10E55000B10138506F0017800108502B001781015E -+:10E5600006D0070017A101825E86F0378100B05007 -+:10E570001B00108A00B0508300108900025E02F078 -+:10E5800000AF00025E02F00D8D0102421B001781F8 -+:10E5900001825E0503178100025E02F00D9A00E021 -+:10E5A0005E840117A101D9DE8700108301BC6137A9 -+:10E5B00003B79100685E4B0282DF020400BF0002D5 -+:10E5C000BD028750030002BD03945E02F002BE0349 -+:10E5D000225E02F002C001BC610300308003BFDE96 -+:10E5E00002F0000201BC613303B791032BDE02F09D -+:10E5F00002C6009000630097A100E06482F43065D9 -+:10E60000006E5A130022C60188E006F237910068B6 -+:10E61000DE4B0482C801BC61BB03B79103BFDE02BD -+:10E62000F002DF0191600E84F42703BFDE02F002E6 -+:10E63000CC0191600684F42701BC60030010B40192 -+:10E6400081E00686343103BFDE02F005A2011C50D2 -+:10E650008F0017A100E0015EF43065010C5A4700FD -+:10E6600017A10080DE870197A200E0015E0DB06572 -+:10E6700002805A7F0002DE02815A7F0002DA020322 -+:10E68000DA7F0002DE00685A870002DE008860063A -+:10E69000F437A1002019FAF422DE00025E02F00B2A -+:10E6A000160191601E84F42700015E02F000000351 -+:10E6B000BFDE02F002CC0002DE02F0000003C4DE86 -+:10E6C00002F00B5E020650030002E70207DEAF0015 -+:10E6D00002E701BC6103003791020750030002E525 -+:10E6E00001BC620300F79100E0010B00204203BF70 -+:10E6F000DE02F002E801BC600300204200B05E4789 -+:10E70000001080020400BF0002F000B0058B001072 -+:10E7100064006E45170000020068DE4B0282EF00C5 -+:10E72000A044B42A314503BFDE02F0000200025EBD -+:10E7300002F00DA70068C51700000203D05E02F0CA -+:10E7400002F400025E02F00DA703BFDE02F0000239 -+:10E7500001836002F7F7BF01BC600300900400A8CA -+:10E76000412330104801BC620F0011E001816002BA -+:10E77000F5D7AE020200BF0003050068DE4B0202BF -+:10E78000FC00025E02F0130C0068DE4B062305025B -+:10E79000045EB30003050200456F00030500E84472 -+:10E7A000655737A100E82AB6F437A100695E8708EB -+:10E7B00023050183E0022B915C020701AB000305F6 -+:10E7C0000180E00209D04E0187E002F577AB0068D6 -+:10E7D000810B00230800B044670000430182E0067B -+:10E7E000091048018160020D906C01826006289139 -+:10E7F000440188E0020B905C00025E02F00F95017C -+:10E8000085E002F7F7BF0288421B0003100185E094 -+:10E8100006F7F7BF035B5E02F0031201BC60130052 -+:10E82000104301BC600300108501BC60030010B8F8 -+:10E83000008850770090B90208502B000319013866 -+:10E8400050730017A1017C506EF437A100885E87D9 -+:10E850000090B9020047A300031D01BC6003001132 -+:10E86000EA009042E70091EB00B047A300D1E80234 -+:10E870000047B300031F01B0E08E3D91EC01D2E0F0 -+:10E880000210908403A95E02F0041601BC6003002C -+:10E89000108400E001C30020700320DE02F0037347 -+:10E8A00001816006F5B7AD0068DE4B04A3370203B3 -+:10E8B000DEBB00032900E02C9300106503BFDE02DD -+:10E8C000F0032A01BC602301D06500A05E7FFE102A -+:10E8D000EC00B05A030010ED00B05A070010EE0033 -+:10E8E000B05A0B0010EF00B05A0F0010F001BC63DB -+:10E8F000FF1EF08401BC600300308501BC60030092 -+:10E9000010B401BC600301D0A601BC60030450B583 -+:10E9100001BC602304D0B400E002AF0020AB03BF11 -+:10E92000DE02F003BB0068DE4B05233D01BC600343 -+:10E930000010B401BC60071350A601BC600302D0F4 -+:10E94000B501BC602304D0B403BFDE02F00347006E -+:10E9500068DE4B0243540285C38F00034000E05E33 -+:10E960002700378901DA5E270010EE01BC63FF1F24 -+:10E97000F0CE01BC60030010B401BC600300D0A65F -+:10E9800001BC600303D0B501BC602304D0B400E037 -+:10E9900001D300207401BC61FF1FF08401BC60033F -+:10E9A000001085018460070011E00282DEB30004DC -+:10E9B000D802045EB30004D80183E00609104800C1 -+:10E9C000B0412300180001BC600306B78E0181E04E -+:10E9D00006F5D7AE00B054130017A100E05E840125 -+:10E9E00017A100885E8700708303BFDE02F004D8A1 -+:10E9F00001BC60031FF0840103DE530017A200680E -+:10EA0000121B00035900B0121B0017A2009019FA44 -+:10EA1000F457A202005EFF00035B01BC60030037F5 -+:10EA2000A200682B6F00035D01BC60030037A201E8 -+:10EA3000865E8A1C70E3006AC39300036700E843A4 -+:10EA40009000D0E40202421B0003650090001B000E -+:10EA500037A10020421B00436400B020B30017A17F -+:10EA600000E04392F430E40069C39300036701BC03 -+:10EA700060030010E400682B6F00036900E043911D -+:10EA80005C30E401BC60030010B401BC6003001002 -+:10EA9000A601BC60030210B501BC602304D0B40021 -+:10EAA000685E4B06A37100E001CB00207201BC60E0 -+:10EAB0000300083803BFDE02F003BB00E001CF0013 -+:10EAC000207303BFDE02F003BB03205E02F003C22B -+:10EAD0000181E00209104800E001D7002075031E03 -+:10EAE000DE02F003A201BC60030017A2006A5E23ED -+:10EAF00000037B0102428F0017A201855E8A091084 -+:10EB0000480180E0061030810284DE530003820059 -+:10EB1000B000770017A100E05E840437A100885E92 -+:10EB2000870057A100E05E870D57A103BFDE02F00A -+:10EB3000038301BC60030D57A1006800270003A2F6 -+:10EB400000E05E8401F7A101BC60230150650088EC -+:10EB500041970030B601BC60030010B400905E879E -+:10EB60000050A601BC60030110B501BC602300B0D9 -+:10EB7000B40317DE02F0038B0397DE02F0038C0070 -+:10EB800020DE870043950020DE8700239201B85ED7 -+:10EB900022D0168001805E8AD0368103BFDE02F06B -+:10EBA000039B01BC5E22D0168001845E8AD0368130 -+:10EBB00003BFDE02F0039B0020DE8700239901B82B -+:10EBC0005E22D0368101805E8AD0568203BFDE028B -+:10EBD000F0039B01BC5E22D0368101845E8AD05650 -+:10EBE0008201886002F430A800B05A030010B0001F -+:10EBF000B05A070010B1028042A300039E00E04219 -+:10EC0000A30090A800B05A0B0010B000B05A0F003B -+:10EC100010B10187600610908400E05E27003789FC -+:10EC200001DA5E270010EE01BC60030010B401BCE5 -+:10EC300060030350A600B000330010B50284DE5319 -+:10EC40000003AC00E0606803B0A600E04298043026 -+:10EC5000A600B000370010B501BC602304D0B40199 -+:10EC6000846006F2979401866002091048039EDED4 -+:10EC700002F003B60280441F0003B900B05E3F00FB -+:10EC8000114501BC600300178F00B05E430017857B -+:10EC900000B05E0F00179003BFDE02F003B900B0B2 -+:10ECA0005E0F0017850280441F0003B900A044B620 -+:10ECB000F0B14501BC600301104201836006F29788 -+:10ECC00094018460070011E003A05E02F004D60204 -+:10ECD000065EAF0004D80186E006F577AB01BC60A4 -+:10ECE0000300108000025E02F00B1C03BFDE02F086 -+:10ECF00005F803A15E02F0043D011400630017A1B2 -+:10ED00000068DE8700E3C70181600609104803BF81 -+:10ED1000DE02F0043D01816006F5D7AE011C508F84 -+:10ED20000017A100E0015EF43064010C58470004B4 -+:10ED3000870206508F0003D100B044670010F30033 -+:10ED4000B0446B0010F401BC63FF1FF0D301BC633F -+:10ED5000FF1FF0D400B042170310850020600E861C -+:10ED600023F5018760040310A000B000630010B415 -+:10ED700001BC60030B10B500B0006300F0B40203E7 -+:10ED800000C70003E3020CD0030003E3028050C776 -+:10ED90000003DB00B054130017A100E05E8680740E -+:10EDA0001A00B0506B0010E400B04213021084024D -+:10EDB00009502B0003E300B0421300308401D2E07D -+:10EDC0003AA030E0028050C70003E901D2E052A02F -+:10EDD00030E003BFDE02F003E90202D0C70003E91E -+:10EDE00000B0505F0010E000B050630010E100B0D0 -+:10EDF00050670010E200B0506B0010E400B0421306 -+:10EE000002F084020050C70003F000B0006300105D -+:10EE1000B401BC60030210B500B0006304D0B401BB -+:10EE20008460070011E001BC600300178E03BFDEA1 -+:10EE300002F004DA00E001C700207100B0006300B6 -+:10EE400010B401BC600302D0B500B0006304D0B4BC -+:10EE500003BFDE02F0046D01856006F7F7BF010312 -+:10EE600050030017A100B85E870037A101875E86B6 -+:10EE7000101080020CD00300043C020300C7000401 -+:10EE80000C00B050CB00106501BC6003001685007B -+:10EE9000E05A3300368C020350C700040100E05AE8 -+:10EEA0002700368903BFDE02F0043D01BC60030089 -+:10EEB00017B200B05A0B000B2501385A130017A1E6 -+:10EEC00001BC5A06F430E0013C5A130017A1017C42 -+:10EED0005A06F430E10181E0061090840185E007D4 -+:10EEE0000010E30185E0070010C30282D0C70004D0 -+:10EEF0001103BFDE02F004140202D0C700041600A2 -+:10EF0000B02A4B0017A101B8506EF430E000B050A9 -+:10EF1000730017A101B82A4EF430E10282421300B7 -+:10EF2000041400B0507B0010E400B04213021084BF -+:10EF30000185E0061C30E100B042130070840187B7 -+:10EF400060040310A0020300C700042B00B050CBE4 -+:10EF5000001065006D5ECAD1C41C0185E002187006 -+:10EF6000C300E05ECB00368E01BC601B09D065009B -+:10EF7000E04196F6506500B050970016800068DEBC -+:10EF8000CB00042301BC60230150B800682C97001B -+:10EF9000242903BFDE02F0043500B05ECB0010B5BB -+:10EFA00000B000630870B4028342D300042501BCA2 -+:10EFB00060030170B80068AC9700243501BC6003A1 -+:10EFC0000170B802BC506700043403BFDE02F004D5 -+:10EFD00033010CD0030017A103A95E02F004300135 -+:10EFE000BC60230150B800685E8700643303BFDE55 -+:10EFF00002F0043501BC60030170B800685E870050 -+:10F00000443501BC60030170B80181E0021710B8FB -+:10F0100001BC600300F0A501BC60030E10B500B098 -+:10F0200000630010B400B0006300F0B400B042D33D -+:10F03000001800018860080310B4018160060D907B -+:10F040006C03BFDE02F0046D0202D0C7000443006F -+:10F05000B0506F0010E000B050730010E100B050ED -+:10F06000770010E20282421300044200B0507B009D -+:10F0700010E400B0421302F08400E05E9F0037A766 -+:10F0800003A15E02F0044C01BC60030017A70187D6 -+:10F0900060040310A000B000630010B401BC600362 -+:10F0A0000E10B500B0006300F0B4018860080310D2 -+:10F0B000B403BFDE02F0046200B0017B0010650003 -+:10F0C000B05A030010E501BC63FF1FF0C500B05A41 -+:10F0D000070010E601BC63FF1FF0C600B05A0B002A -+:10F0E00010E701BC63FF1FF0C70068A0670004556C -+:10F0F00000E05E2700378900682067000459018519 -+:10F10000E0070010E30185E0070010C300B04213E0 -+:10F1100001108401DA5E270010EE0187600610906E -+:10F120008400B042131C108401BC60030010B400C2 -+:10F13000E0606803B0A600B000970010B501BC60A5 -+:10F140002304D0B4018460070011E003BFDE02F0A5 -+:10F1500004C601085E4B0017A100685E8700246D9D -+:10F160000202500300046C029E509F0004690201D9 -+:10F17000D00300046900E05E2700378901585E274C -+:10F1800000142D01DA50B70010EE018760061090D0 -+:10F190008403BFDE02F0046D01BC600300142D0186 -+:10F1A00004C1070017A10068121F00047200B0120A -+:10F1B0001F0017A1009019FAF437A103BFDE02F077 -+:10F1C000047403225E02F004740103DE530017A1ED -+:10F1D00000B05E870017A202005EFF00047701BC4A -+:10F1E00060030037A200682B6F00047901BC600344 -+:10F1F0000037A202885E4B00047C00685E4B0684E8 -+:10F200007C01BC60030017A20068921F00047E010D -+:10F2100083DE86F297940183DE8684F4270281C21E -+:10F220001300048401865E8B0010E30186600700F2 -+:10F2300010C30181E00610908403BFDE02F0048653 -+:10F2400001865E8A1C70E3018660061870C302B8EE -+:10F2500047A70004C202A047B70004C403A95E0286 -+:10F26000F0048E01085E4B0017A100685E87002441 -+:10F27000C3021E509F00048E0185E0061C70E3014E -+:10F2800085E0061870C3011400630017A10068DE52 -+:10F290008700849700B001530017A20068DE8BFF3F -+:10F2A000E493006842470024940068DE8A84C4978F -+:10F2B000018560020910480186E0021C70E30186A6 -+:10F2C000E0061870C3011050070017A600685E9B87 -+:10F2D0000004C301BC60030011E4013A50070017A9 -+:10F2E0008000885E0300778000E000AEF0106400CC -+:10F2F00068DE9B0044A80207D0030004A201BC60A2 -+:10F300002B12B7A200E05E000B37A300025E02F0F2 -+:10F310000DE801BC602307978100E0418301706321 -+:10F3200000E0418F00B06500025E02F00DBD01BC3F -+:10F33000602307506401BC60470017A200025E0210 -+:10F34000F00E1000685E9B0044C401A46046F47196 -+:10F35000E00068DE9B00C4B601BC611300B7A102E7 -+:10F360000600F30004AF01BC601300B7A10192C214 -+:10F370001AF437A203295E02F004B401BC60030052 -+:10F3800011EE009042E70091EF0192E00EF437A2F7 -+:10F3900000B05E8B0011EC03BFDE02F004C4006815 -+:10F3A0005E9B0064BB00685E9B00A4BB00B0502F56 -+:10F3B0000011E200B050330011E203BFDE02F0049E -+:10F3C000C4018760023D11E80068DE9B00A4BE0115 -+:10F3D0008760063D11E801BC60030011EA0090421D -+:10F3E000E70091EB0192C21B00B7A201B85E8A3D13 -+:10F3F00011E803BFDE02F004C4018460070011E0DD -+:10F4000001BC600300112D00B0448300142C03A341 -+:10F41000DE02F004D901BC600300178E00685E4B69 -+:10F4200005A4CA020050030004D30183E0060910BA -+:10F430004800B0412300180001BC600304B78E03EC -+:10F44000A95E02F004D800685E4B0424D801BC60B9 -+:10F450000306378E00685E4B05A4D801BC60030626 -+:10F46000B78E03BFDE02F004D801816006F577ABEA -+:10F4700000B05E0F00178500025E02F00DA701BC10 -+:10F48000600300178C01BC600300178D0323DE02AC -+:10F49000F004DA0187E0061070830185E002F5B719 -+:10F4A000AD03295E02F004EE020300C70004E90088 -+:10F4B000B050CB0010650282D0C70004E100E05AD2 -+:10F4C0002300368803BFDE02F004E200E05A270082 -+:10F4D000368900682C970024E900E05ECB0037B243 -+:10F4E000010A5ECB0017A100E050CAF4306500D0DD -+:10F4F0006006F657A200205A1AF444E903BFDE0260 -+:10F50000F004E300025E02F00F9503D5DE02F00A7C -+:10F510004C03D6DE02F00A640350DE02F004E90375 -+:10F52000BFDE02F0051002055EAF0004F00187E0C7 -+:10F530000626713303BFDE02F000020190600A86E6 -+:10F5400034310282D0C70004FA013C5027001780F2 -+:10F550000109502B001781010750070017A10182F4 -+:10F560005E86F0378100B0501F00108A00B0500F47 -+:10F5700000111603BFDE02F005000138505F0017CE -+:10F5800080010A502B0017810107D0070017A10145 -+:10F59000825E86F0378100B0502300108A00B050A0 -+:10F5A0005B001116020300C7000505020CD0030022 -+:10F5B000050502085E07000505013854070017809D -+:10F5C0000190422AA1308A028050C700050E01BC7A -+:10F5D000600305B79203BFDE02F0028F0190600660 -+:10F5E000863431020300C70004F2020CD003000489 -+:10F5F000F200B0001F0017A100E05E8680741A03BD -+:10F60000BFDE02F004F201BC600306379203BFDEE6 -+:10F6100002F0028F02055EFF00051F01856002F700 -+:10F62000F7BF032BDE02F0051F020000F3000516F2 -+:10F6300000E8002300514201BC600A2851420394B3 -+:10F640005E02F0051B00B0058B00106400685803D3 -+:10F6500000051B00B0446700111200B058030011F0 -+:10F66000150068451F00051F03A25E02F0051F017B -+:10F6700085E006F577AB00025E02F00ED70201C20C -+:10F68000E3000549020300C700052400682C970029 -+:10F690002534006E4246F6453403BFDE02F00526EF -+:10F6A000006E4247002534020300C70005310355B0 -+:10F6B000DE02F00526018060028614300138508396 -+:10F6C0000017A100B050CB001065006DDA32F42AAB -+:10F6D0004C00A84123141048011400630010650079 -+:10F6E000E041970ED06500E05A0300368001BC620D -+:10F6F0001F0011E003BFDE02F000040181E0068676 -+:10F7000034310191600E84F42703BFDE02F0054915 -+:10F71000013C50670017A101AC5E861750BA01BCCE -+:10F7200060030190B8020300C70005430068AC976E -+:10F7300000253E0181E0021710B803D5DE02F00A71 -+:10F740004C03D6DE02F00A640350DE02F0053A03F1 -+:10F75000BFDE02F0054900E82C97002B2500B05EC3 -+:10F76000CB0010B500B000630870B4028342D30030 -+:10F77000054103BFDE02F005440186E0040310A04A -+:10F7800000025E02F0015A03D5DE02F00A4C03D6F5 -+:10F79000DE02F00A640350DE02F0054503BFDE021C -+:10F7A000F0031001BC600300F0A50182E002091023 -+:10F7B0004801BC621F0011E001BC60030011EC01B4 -+:10F7C000BC600F0011E80285500B000550018260FB -+:10F7D0000209104803A0DE02F0055403D5DE02F052 -+:10F7E0000A4C03D6DE02F00A6403205E02F00556DE -+:10F7F0000188600209104803BFDE02F0000401BC6A -+:10F8000060030037A100025E02F00C5303A3DE0286 -+:10F81000F00004020050C700056201BC6003001044 -+:10F820008001826006091048018060028634310040 -+:10F8300068921F0005600104C1070017A10183DE63 -+:10F8400086F2979400E001CB00207203BFDE02F045 -+:10F85000017D00B0010B0017A1006DDE840805A238 -+:10F8600000E844640877A1006E5E840825A2018741 -+:10F87000E006F577AB020200BF000575028881AB98 -+:10F88000000575028400C70005750129500B00179B -+:10F89000A10068DE870205750282DEBB00057502E5 -+:10F8A00003C5730005740283DEB30005740282DEB3 -+:10F8B000BB00057100682B07000575006DDE2F0188 -+:10F8C000E5750182E006F7F7BF00E04465564AB1EE -+:10F8D00003BFDE02F0000403BFDE02F005A20282D5 -+:10F8E0005EAF00058501826006F577AB00B0446726 -+:10F8F00000082300B0014B0017A20208421B0005BC -+:10F900007C00B0016B0017A200685E8B00058200CE -+:10F9100090452B0097A10080DE86F457A1006E2051 -+:10F92000D60DA58200B041B700083500E020D623EF -+:10F9300028360185E002F5B7AD02055EAF0005850A -+:10F9400001BC610300113300E844650477A500B0F1 -+:10F950004467000BDA006D5E97010080020200BF71 -+:10F960000005940068DE4B06A58B0184E002F7F7E2 -+:10F97000BF0068DE4B04058E0282DEB300058E01F7 -+:10F98000BC6003000B1202045EB30005910068DE48 -+:10F990004B06259100025E02F0112300025E02F088 -+:10F9A0000F9603A3DE02F005940183E002F597AC05 -+:10F9B00001BC60131497A100025E02F000A201BC1A -+:10F9C00063830017A100A04066F437A20068DE8AB6 -+:10F9D000F425A001BC60130E77A100025E02F000C6 -+:10F9E000A200A040673FF7A200985E8B0037A200FC -+:10F9F000685E8B00059F0068DE8B0FE5A001BC6090 -+:10FA00002300104301826002F577AB03D15E02F060 -+:10FA10000002020050C30005F10325DE02F005A636 -+:10FA20000183600684F42703BFDE02F005D8020CD0 -+:10FA3000D0030005D6020300C70005C5011400630A -+:10FA40000017A1006DDE870085D601BC600300179A -+:10FA50008000B050CB00106500B050CF00106401A2 -+:10FA60008160060D906C0182600686343100B05AC8 -+:10FA7000230017A101BC600300168801BC5A2AF4B8 -+:10FA800037A101BC600300168A00B05E8700148FA6 -+:10FA900000B05A270017A101BC600300168901BC01 -+:10FAA0005A2EF437A101BC600300168B00B05E87AC -+:10FAB00000149000B05A1B00148D00B05A1F00149F -+:10FAC0008E01BC60030016040068DE030005C2025C -+:10FAD0000350C70005C10100509F00178001805EE0 -+:10FAE0000291B48D01BC5E0292149001BC600300CF -+:10FAF000378000025E02F0128100B05E0300148CB9 -+:10FB000003BFDE02F005D10068C2470005CA0181CB -+:10FB1000E0068634310191600E84F42701BC600355 -+:10FB200000143003BFDE02F0000200B0509F001747 -+:10FB3000A100025E02F0015900B05E8700142701A7 -+:10FB400086E0040310A000B04283001800010CD02E -+:10FB5000030017A10068DE870065C5010250C700D9 -+:10FB600017A101805E8684F427018AE00E84F427C1 -+:10FB700000B050BF00142603BFDE02F005D8018696 -+:10FB8000E0040310A00200509F0005D80286C107C0 -+:10FB90000005EC03295E02F005DD00B052330014CD -+:10FBA0002D00B052370017A1019E5E8684F4270015 -+:10FBB000B0509F0017A10180DE86F437A100B0503D -+:10FBC000BB00108F00B050B700108E00B0509B00EB -+:10FBD000108D01806006F4308C020250C70005EBE6 -+:10FBE00000B0524300108F00B0523F00108E00B0A2 -+:10FBF000523B00108D011A52370017A10198DE8781 -+:10FC00000437A101B85E8691B08C0182600286340F -+:10FC100031018160020D906C0325DE02F005EF01D9 -+:10FC20009C600284F42703BFDE02F005F3028550D6 -+:10FC30000B0005F100A850C70D143101BC60030092 -+:10FC4000143001816002F5D7AE0183600284F4278D -+:10FC50000185E00209104801BC600300142E03A2D4 -+:10FC60005E02F0017D03BFDE02F000040323DE022A -+:10FC7000F0065C03A35E02F0065C03A2DE02F0065F -+:10FC80005C01816006F577AB03AA5E02F0065C01B9 -+:10FC900083E0020910480351DE02F0061B02045EF5 -+:10FCA000B300060801846002F597AC0183E0020905 -+:10FCB000104800B02B5F0017A1006D2B0EF420023E -+:10FCC00000E0027B00209E01BC6003000AC300022A -+:10FCD0005E02F0112603BFDE02F000020203DEB373 -+:10FCE0000006180183E002F597AC00E02A9B002A89 -+:10FCF000A602015EBB00061800B02A9F0017A100F3 -+:10FD00006D2A9AF4261301BC6003000AA600E002E3 -+:10FD10007F00209F03A95E02F006160191601A84FD -+:10FD2000F42703BFDE02F002CC01BC63FF1FF7A182 -+:10FD300000025E02F00C5303295E02F006180191E6 -+:10FD4000601A84F42703BFDE02F0061800E0026B9D -+:10FD500000209A0180E006F577AB03BFDE02F006D3 -+:10FD6000200301DE02F0061E00685E4F06261E011B -+:10FD7000BC60030017A803A45E02F0062003C1DEE6 -+:10FD800002F0065F01846002091048020400BF000F -+:10FD9000062501BC6003001115011400630017A1C2 -+:10FDA00000E06602F4306500025E02F00DAC0182F4 -+:10FDB000600209104803A95E02F0064000685E3B3D -+:10FDC00004A63001F0DE1700378500A05E16F0971C -+:10FDD0008500685E3B0626300201500300062F02B4 -+:10FDE0008780BF00062F0185E0060910480280D0F9 -+:10FDF0000300064000B05E1B0017A300B0008B009C -+:10FE000017A4020400BF000636006E419730663624 -+:10FE100001185A030017A3011A5A030017A4006817 -+:10FE2000C18318063900E002930020A403BFDE025C -+:10FE3000F0063B006D5E2EF4863B0182E0068634C0 -+:10FE40003100E05E3300378C0068DE32F4663E003D -+:10FE5000B05E0F001785006DDE2EF4664C03BFDE2A -+:10FE600002F0065700B05E1F0017A300B0008F001D -+:10FE700017A4020400BF000646006E419730664694 -+:10FE8000011C5A030017A3011E5A030017A4006D9A -+:10FE90005E2EF486480182E00686343100E05E374B -+:10FEA00000378D0068DE36F4664B00B05E0F001739 -+:10FEB00085006D5E2EF466570185E0020910480347 -+:10FEC000D1DE02F0064E00025E02F00DA70068418E -+:10FED0008318067A020300C7000655020CD00300FF -+:10FEE0000655028350C70006550068DE4B05A6552F -+:10FEF00003BFDE02F011FF0181E00686343103BF4B -+:10FF0000DE02F005A200025E02F00DA70181600290 -+:10FF100009104803295E02F0065C028300C7001145 -+:10FF2000FF03BFDE02F005A203D1DE02F0065D038F -+:10FF3000A5DE02F005A203BFDE02F00004020650B7 -+:10FF40000300066500B001030017A1006D810AF4EB -+:10FF5000266500E844640877A1006E5E8408266583 -+:10FF60000187E006F577AB01085E4B0017A100683A -+:10FF70005E8700266800B05E0F00178500025E02F3 -+:10FF8000F00DA700685E3B06266E01BC60030017FB -+:10FF90008C0200D00300067301BC600300178D03C0 -+:10FFA000BFDE02F0067301BC600300178C02030081 -+:10FFB000C700017D020CD00300017D019C6002841A -+:10FFC000F42703BFDE02F0017D0068418318067943 -+:10FFD0000180600684F42703295E02F005A20182F5 -+:10FFE0006006863431028300C70011FF03BFDE02C2 -+:10FFF000F005A200E002970020A50181600209102F -+:020000023000CC -+:100000004801BC600300081900E0017B00A05E010C -+:10001000BC601310D7A1006D017AF4200401BC600C -+:100020001309405E03BFDE02F0000400025E02F02E -+:100030000B160338DE02F00004039EDE02F000041B -+:1000400000E8444C00F7A100E85E840117A1006AB3 -+:10005000DE8401068A00E85E8401118701BC60032A -+:1000600000118801A5E02230118001BC600300115D -+:100070001301BC600300111400B044670017A10015 -+:10008000B0446B0017A200B05E8700110400B05EA0 -+:100090008B00110503B8DE02F0068C03BFDE02F010 -+:1000A000000401BC600304B79201BC60030417A103 -+:1000B00001BC63FF1FF0CB01BC63FF1FF0CC01BC90 -+:1000C00063FF1FF0CD01BC63FF1FF0CE01BC63FFD7 -+:1000D0001FF0CF01BC63FF1FF0D000B0521700101B -+:1000E000E801BC63FF1FF0C800B0521B0010E9011B -+:1000F000BC63FF1FF0C900B0521F0010EA01BC63CF -+:10010000FF1FF0CA01BC60030010E4028600C300B8 -+:1001100006AD00B0540F0017A20069DE8A9086A5D4 -+:1001200000E85212F450E40068A0630006AD01BC80 -+:1001300060030010E400B054270010E000B0542F1A -+:100140000010E103BFDE02F006B603A4DE02F008F1 -+:10015000AB03A9DE02F008AB01BC600301D7A1022A -+:100160000600C30006AF0280DE5F0006B400B05494 -+:10017000070010E0006820630006B201D2DE86A00E -+:1001800030E000B0540B0010E103BFDE02F006B611 -+:1001900001BC5E869010E001BC601F0010E101BC54 -+:1001A00060030010E200B052230010E501BC63FFC1 -+:1001B0001FF0C500B052270010E601BC63FF1FF01E -+:1001C000C600B0522B0010E701BC63FF1FF0C70050 -+:1001D000B0004700108601082063001781013852E3 -+:1001E000030017800102C0270017A600025E02F07C -+:1001F0001198006820630046C400B05407001780BF -+:1002000000025E02F00D8D006820630026CD0068BC -+:10021000A0630006C8021A54070006CD006800A7B4 -+:100220000106CB0103C0270017A103BFDE02F006C1 -+:10023000CC0106C03B0017A101825E8610D0860368 -+:10024000A9DE02F008EB00685E4F0426DF01BC6304 -+:10025000FF1FF0C300685E4F05A6D501BC60031AFE -+:1002600090E301BC600306B79200685E4F0526DF8D -+:1002700003BFDE02F006D901BC6003063792029884 -+:1002800044070009C0028046070009C001BC6003A2 -+:100290001890E300B0206300178100025E02F00DA9 -+:1002A0009A00E85E8400D7A1006A5E869086DF002F -+:1002B000E85212F430E403BFDE02F006E201BC6053 -+:1002C000030010E40338DE02F006E20187E0061CBA -+:1002D00090E40190600A09104801BC610304379161 -+:1002E00000685E4F05A9C003835E02F008AB03BF40 -+:1002F000DE02F0000201866002F7F7BF0182E00231 -+:10030000F5B7AD0185E002F5B7AD02044163000623 -+:10031000F2018460020B105802055EAF0006EE0188 -+:1003200087E006267133020400BF0006F10185E074 -+:1003300002F577AB00025E02F00ED703BFDE02F0DB -+:1003400000020283C0370006FA006CC4656C26FB0D -+:1003500001BC601B1A77A100025E02F000A20180BE -+:10036000E0060337A200025E02F000A80180E0026E -+:10037000F457A200025E02F000A800E044656C4B56 -+:10038000610285C52300070A018460060B1058022C -+:1003900000DEFF0007010180E002F7F7BF00682BD5 -+:1003A0006F00070100E044655B4ADB0207AC0F0009 -+:1003B000070A0280456F00070A01BC63FF1FF7A10F -+:1003C0000068DE862C270A01BC60130217A1000218 -+:1003D0005E02F000A201882C0E0337A200025E022A -+:1003E000F000A801BC6003000B0302055EAF00072C -+:1003F0000C01BC6103001133020580BF000712012C -+:10040000BC60131157A100025E02F000A2019660C9 -+:100410000E03301900B040670017A200025E02F020 -+:1004200000A80283C03700000400E0021F002087FC -+:100430000182600628914403BFDE02F000040281BD -+:100440004013000002020042030007190184600209 -+:10045000F597AC01BC600300108003A3DE02F00737 -+:100460001C0190600209104800B0446700179E000C -+:10047000B0446B00179D00B0446F00179C00B0445F -+:100480007300179B0068DE7A23271C00E00223001C -+:1004900020880115403B00179700B001430017A1C9 -+:1004A00001C9DE8405280501BC6003107795019120 -+:1004B000E0020D906C0286403700072A00E002BB84 -+:1004C0000020AE03BFDE02F00A8A01BC6003001404 -+:1004D0008001BC600300148101B8600A049024010B -+:1004E000BC600304082B01BC600300482A01BC6007 -+:1004F0000300D02A01B3600700100401BC600300B0 -+:10050000080E01BC600300080F01BC600300081066 -+:1005100001BC60030008110183E002F5D7AE028739 -+:10052000C037000A8600025E02F0117A00025E0205 -+:10053000F00F9503435E02F00736006D403300CAAA -+:10054000F700685E5F00474E00685E5F00274B0063 -+:100550006800A700C740006800A701074000688046 -+:10056000A700A74100E0446690283701BC62C300A1 -+:1005700017A102805203000744019652030017A1FD -+:100580000080DE8690379A0203520300074900E09C -+:100590005E6A90379A0207D20300074900E85E6B53 -+:1005A00000379A029E5E6B000AF703BFDE02F00777 -+:1005B000530152D2030017A10185D206F4379A03E2 -+:1005C000BFDE02F00753013C52030017A101BC52E9 -+:1005D00006F4379A006E5E680BAAF700682FC30016 -+:1005E0000753028E5207000AF70204C03B00075D62 -+:1005F0000181E0060D906C02874037000A8A0002F4 -+:100600005E02F0117A00025E02F00F950287C0AF21 -+:100610000007550287C0AF000A86015840AF001797 -+:100620009A01BC603F1E17A1006DDE6AF42A8603A2 -+:100630005B5E02F0075F01BC601300104300B04135 -+:100640002328104801806002F297940184E0020997 -+:100650001048015840AF00102A006840AB002A86BD -+:1006600001BB5E5600900402035E5700076E020055 -+:1006700047A300076B01BC621E3C11E001BC600394 -+:100680000011EA00B05E6B0011EB0198601E3D1195 -+:10069000E8020047B300076E00B05E6B0011EF0187 -+:1006A000B0E0CE3D91EC03835E02F0077200025E83 -+:1006B00002F0117A00025E02F00F95006D403304E3 -+:1006C000C76E03AADE02F0078E01BC63FF1FE4863B -+:1006D00001BC601B19D06401BC600300B7A101BC60 -+:1006E00063FF1FE66D00E04186F4306501BC63FFE7 -+:1006F0001FF60000E05E870077A100025E02F00CAA -+:10070000AE0200C077000784012940770017A200DD -+:100710006D5E8B04C78200E85E8B04D60001BC606E -+:100720001B0FF06300E0418EC01063010C56030004 -+:1007300004860068DE8701678400B05E8B00066D6A -+:10074000006DDE8701C78700E0419300306403BF7E -+:10075000DE02F0077703B05E02F0078D01836002CE -+:100760000D906C00681B3BFFE78E01BC601B0FF017 -+:100770006500E04194D9D06502005A0300078E015C -+:100780008360060D906C0020402F08A79001BC608C -+:100790000300048601BC60030008020188E00F002A -+:1007A0000803006D40330208A50129520F0017937A -+:1007B0000109520F0017AA01966002F2979400E017 -+:1007C000418701F06501BC600F0017A10028DE869B -+:1007D00090679C01866006F2979400E04197007054 -+:1007E0006500E020AF00C82B01065E530017A20091 -+:1007F000A05E4F0477A10068DE870447AA0186E067 -+:1008000006F2979400B85E8B0037A200B05A03003E -+:1008100017A0020ADA030007A401876006F2979482 -+:100820000284C03B0007AA0203DA030007AA03AB55 -+:100830005E02F007A8020441070007AA01806005D4 -+:1008400000680301065E530017A20182DE8A009051 -+:100850000403AADE02F007DB03AB5E02F007C50269 -+:1008600087D2130007DB00B0521300118601A5E008 -+:100870000A301180018460020D906C01BC63FF1F7F -+:10088000F79900B01B430017A20068DEAB0027B742 -+:1008900000A05E4FFF77A10068DE870727C303BF74 -+:1008A000DE02F007B90284520F0007C30204D20F20 -+:1008B0000007BC03B15E02F007C200B01B3F001787 -+:1008C000A203BFDE02F007BD03B35E02F007C2025F -+:1008D0000052170007C300685E8BFFE7C300E0010A -+:1008E0005EF4506502015A470007C300B019B70013 -+:1008F0001799018460060D906C020052170007DB07 -+:1009000003315E02F007DB01866002301180018056 -+:10091000E001620B10020052170007C90202AB4F40 -+:100920000007D60068DE5F0007D600B02BB70017BF -+:10093000A100682ABB0007D600B02BB30017A200A5 -+:100940006DAABAF447D60068DEAB0047D2006D2B23 -+:10095000BAF427D100B02C6B000B190184E006F724 -+:10096000F7BF0068DE4F0287D600025E02F0130C6C -+:100970000206DEFF0007D600E02BE7002AF9006838 -+:10098000DE5F0007D90068DEAB0047D90180E005D3 -+:10099000620B1000682B6F0007DB0180E006F7F7A1 -+:1009A000BF0207520F000856028047A300085302F7 -+:1009B0008047B300085300E020AF00882B00E820F8 -+:1009C000AB00882A01BC60030011E401BC63FF1F77 -+:1009D000F7A501BC600303D1E102065E530007E501 -+:1009E00001BC60030491E10206DE530007E900E068 -+:1009F00047870051E10207D20F0007E900E047876F -+:100A00000091E1006D403302C8A500685E4F058784 -+:100A1000EC0068DEAB00485603AB5E02F007EF0265 -+:100A2000005217000856020580F30007F500681908 -+:100A3000B7FFE7F200B019B70017A500E05E970016 -+:100A400097A50068DE97FFE7F50280521700085669 -+:100A5000020700BF00085601BC601F1417A20090D7 -+:100A6000478700306500E04196F4506500E0478715 -+:100A700001082103835E02F007FD00025E02F0110F -+:100A80007A00025E02F00F95006D40310427F900F4 -+:100A90006D40310428A501BC600B1D57A10068DE24 -+:100AA00097FFE80D010F5A070017A5031EDE02F09D -+:100AB000080D0200521700080D032C5E02F00856C4 -+:100AC00000685E67FFE80D00E05E6700979900E050 -+:100AD0005E66F43064012A58030017990100DE971E -+:100AE0000017A500E05E66F4B79900E05E67003786 -+:100AF00099011558030017A603BFDE02F0081D0078 -+:100B0000E05E96F43064012A5803001799020580CC -+:100B1000F300081C0182E002F3379902005217002B -+:100B2000081C0116D8030017A6010F5A070017A4C6 -+:100B3000010CD8030017A10068DE92F4281800E029 -+:100B40005E6702179903BFDE02F00821010DD8038A -+:100B50000017A10068DE92F4285600E05E670417D3 -+:100B60009903BFDE02F00821011058030017A60008 -+:100B700068DE9B00C8210181DA030017A100B85E7E -+:100B800086C017A10281DE8700085600885E6700D4 -+:100B9000778000E000AEF0106401AADE6500480234 -+:100BA0000068DE9B00483B0207818700082E006D2D -+:100BB000DE030C082E0285520F00082E0298523BCD -+:100BC00000082E0181E00500680300E05E000B379D -+:100BD000A300E05E8F0097A300E041870077A200AA -+:100BE000025E02F00DE800E820AB01082A01BC60BB -+:100BF0002307978100885E970077A100E85E86F45E -+:100C0000B06301BC60070E17A100E0418EF43063B1 -+:100C100000B056170017A100B0561B0017A20068BD -+:100C2000DE86D048560068DE8AD0685600025E0232 -+:100C3000F00DBD01BC602307506401BC624F00177A -+:100C4000A200025E02F00E1000685E9B0048530195 -+:100C5000BC621EF471E00068DE9B00C84601BC6106 -+:100C60001300B7A1020600F300084201BC601300A4 -+:100C7000B7A101BC60030011EE00B05E6B0011EF84 -+:100C80000192E00EF431EC03BFDE02F0085300687D -+:100C90005E9B0068480068DE9B00A85301986006D0 -+:100CA0003D11E800E020AF00882B00E820AB008871 -+:100CB0002A01BC60030011EA0068DE5F00484E00B4 -+:100CC000B05E6B0011EB0192DE5E3D11E8018760C2 -+:100CD000023D11E80068DE9B00A852018760063DD6 -+:100CE00011E8019860163D11E80181E00500480215 -+:100CF00001AADE6500480203BFDE02F0085B01BC0A -+:100D0000620F0011E001BC60030011E40181E00109 -+:100D100000680301BC600F0011E801BC6003001112 -+:100D2000EC0200200F00086200E020AAF3482A002D -+:100D3000B020AF00102500E820AA04A82A006AA06D -+:100D4000AB01C86201B860060490240182E006F29B -+:100D500097940188600A00900401BC60031877959D -+:100D600003A0DE02F0086F00685E4F06A874013829 -+:100D7000520300178000B05E5F0017810203DEB7E8 -+:100D800000086E00685E0700086D01BC6003017713 -+:100D90008001BC600300378103BFDE02F0086E01F2 -+:100DA000BC600301578000025E02F000AF0068DE05 -+:100DB000AB00487400A05E4F0477A100685E870016 -+:100DC0004A3500685E87044A3503BFDE02F00BE94E -+:100DD0000386DE02F00A870287C037000A86000217 -+:100DE0005E02F0117A00025E02F00F9503035E02CC -+:100DF000F0087403A9DE02F0088000025E02F01120 -+:100E00007A00025E02F00F950207403700087A036D -+:100E100086DE02F00A870287C037000A8600025E7B -+:100E200002F00C60006E40300208AB0301DE02F0FD -+:100E300008AB0068DEAB000892032B5E02F0088668 -+:100E400000E0022B00208A03BFDE02F0088A028045 -+:100E5000521700088900E0024300209003BFDE0221 -+:100E6000F0088A00E0025700209500685E4F040BEE -+:100E70006900685E4F028B6900685E4F0209C70017 -+:100E8000685E4F048A2E00685E4F050BDA00685ECC -+:100E90004F060BDA00685E4F068BE303BFDE02F0FD -+:100EA0000BE90068DEAB0028A3032B5E02F0089676 -+:100EB00000E0022F00208B03BFDE02F0089A0280C0 -+:100EC000521700089900E0024700209103BFDE029C -+:100ED000F0089A00E0025B00209600685E4F06A9C9 -+:100EE0009B00685E4F042C0100685E4F04AC01005B -+:100EF000685E4F05AA3B00685E4F06299B00685E4E -+:100F00004F052BD800A05E4FFF77A100685E8707D2 -+:100F10002BF403BFDE02F009C000E00213002084BE -+:100F200003BFDE02F009C400E0020F00208301BC11 -+:100F300060030011EC01BC600F0011E80284C03BAB -+:100F40000008560184E00609104803BFDE02F008DD -+:100F5000560200C09300000203A35E02F008AF0334 -+:100F6000C35E02F008AE03BFDE02F00AF300025EC9 -+:100F700002F0117A00025E02F00F950207C0AF0086 -+:100F800008B3020740370008AF0107C0AF0017A140 -+:100F900000B85E870037A101825E860D906C00B0BC -+:100FA000447F000804018360020910480287C037AB -+:100FB000000A860386DE02F00A8700025E02F01154 -+:100FC0007A00025E02F00F9503435E02F008B80259 -+:100FD00087C037000A860301DE02F008D303305EC3 -+:100FE00002F008D301BC601B1F506500E04194DF94 -+:100FF0003065012D406B0017A200885E8B0137A27F -+:101000000138402B001680028840270008C7018461 -+:101010006006D0168000B05A02F456800205C02740 -+:101020000008CA0187E006D0168001BC601B0DD7FE -+:10103000A100025E02F000A200B04067001681012C -+:10104000BC601B0DF7A100025E02F000A200B040E0 -+:101050006700168200E01BE70066F900691BE701E4 -+:1010600088D301BC60030006F90280200F0008D578 -+:10107000006E40300209960381DE02F008DF00E0D6 -+:10108000021700208503A9DE02F008DB0184E006D8 -+:101090000910480180E0020910480184E002F7F7D6 -+:1010A000BF0386DE02F00A87018060050048020166 -+:1010B000806006F2979403BFDE02F009620183604C -+:1010C00002F7F7BF0386DE02F00A87032B5E02F009 -+:1010D000090503A9DE02F008E80068DEAB00490557 -+:1010E00000B0523B00179F00B0523B0017BE01BC3E -+:1010F000600300280E03BFDE02F0090502875E537D -+:1011000000091203A0DE02F008F403BFDE02F006BD -+:10111000920182E0060D906C0190600A091048006F -+:10112000B0523B00179F00B0523B0017BE019E5EBD -+:101130008300B0EB0106520F0017A100B85E8700D4 -+:1011400037A10182DE86F577AB01BC6103003080F8 -+:1011500000E8523AF3F7A2006BD23AF3E8F700E85E -+:101160005E7E91D7A200905E8B0097A101BC6023A8 -+:1011700001D064006B523AF3E90201185E87001750 -+:10118000A2010A5E870017A300886006F457A20038 -+:10119000E04192F4706400B05802F45600006BDE37 -+:1011A000FA91C90500B0523B0017BE03BFDE02F042 -+:1011B000090500025E02F011EA00B0203B00280E93 -+:1011C00000B0523B00179F0320DE02F00912020715 -+:1011D0005E530009090180E00209104803BFDE02E6 -+:1011E000F009120068DE5F00090F021A54070009B7 -+:1011F0000D0103C0270017A101825E8610D0860171 -+:1012000002C0270017A100E0422AF4308A0180E0E2 -+:101210000500480203A9DE02F0091200B05E470093 -+:10122000108001085E4F0017A100685E8700293614 -+:1012300003AB5E02F0093A0200521700092500686C -+:10124000DEAB00491800E0025300209402865E5392 -+:101250000009620284520F000AF70284D20F0009CB -+:101260001D03AC5E02F0092303BFDE02F0092E036A -+:101270002C5E02F0092E00685E4F0409230106D29D -+:101280000F0017A10080921B0197A200E0015E0DE4 -+:10129000B0640181DE86C3F61F00685E4F020962FA -+:1012A00003BFDE02F00952031EDE02F0092B0331F8 -+:1012B0005E02F0092B0068DEAB00492B0080921B18 -+:1012C0000197A200E0015E0DB0640181E002C3F667 -+:1012D0001F0068DEAB00493000E0023F00208F03B2 -+:1012E000BFDE02F0093300685EAB00493302805272 -+:1012F0002F0009620202410700093300685E4F04B3 -+:10130000096200685E4F0289620284410700096237 -+:1013100001806006F2979403BFDE02F00962032B9E -+:101320005E02F0096200685E4F05A95200685E4FD8 -+:1013300005295203BFDE02F009620068DEAB0049F6 -+:101340004201BC6003000ABD01826002F5D7AE0213 -+:10135000805EFF00094000682B6F00094200E044F6 -+:10136000655B4ADB00682B8BFFC94200E02B8B00DA -+:101370002AE202065E5300094500E002630020985D -+:1013800003BFDE02F009620323DE02F0094D0129EA -+:10139000500B0017A30068DE8F05294D0187E0027E -+:1013A0001070830184600209104800B05E87001746 -+:1013B000A1006EE00300294C03D1DE02F0094D00CC -+:1013C00068DEAB00494F00E0022700208900685E1C -+:1013D0004F00096200685E4F01096200685E4F05B8 -+:1013E0008962028047C70009940329DE02F0095888 -+:1013F0000102DEAF0017A10106520F0017A200384C -+:101400005E86F449620182DE8AF577AB00B0522332 -+:101410000011F200B052270011F300B0522B00115E -+:10142000F40106520F0017A100E05E870031F500BD -+:10143000B0005B0011F000B047C30018000134C7D2 -+:10144000C70017A1006EDE8402A96201BC60030818 -+:1014500010420283C1070009660301DE02F009653C -+:1014600003B55E02F0096602805E53000AF700B021 -+:1014700040330017A10108A00F0017A200685E8B7F -+:1014800000696E00E840310577A10281200F000954 -+:101490006E00B020AF0017A10280A00F00096E00FF -+:1014A000B05E630017A1006E5E8402099600B05E14 -+:1014B000870007FA018160010048020202C01300A0 -+:1014C000097400E05E840347FA0181600500480268 -+:1014D0000201200F00098F01035E530017A101874D -+:1014E000DE850048020386DE02F00A8700025E0203 -+:1014F000F0117A00025E02F00F9503855E02F0099A -+:1015000077018E60023D11E80107C7830017A10132 -+:10151000825E850048020201A00F0009810103C715 -+:10152000970017A101825E8500680300B0204B0080 -+:1015300017A1018E5E850068030207C0AF000C444E -+:1015400001BC60030011EC01BC600F0011E80184D4 -+:10155000600500680300B040270007FC00B0402B86 -+:101560000007FD00B0406B0007FE00B0406F0007B1 -+:10157000FF0184600500680300025E02F00C600158 -+:10158000BC63FF1FD7A800025E02F00DAC00025E34 -+:1015900002F00C4401A8600A0090040201200F0030 -+:1015A00011D500A8401300500403BFDE02F005F877 -+:1015B00000E002870020A103BFDE02F0099700E0EF -+:1015C000020B00208203A9DE02F00AF70184600604 -+:1015D0000910480184E00609104803BFDE02F00A42 -+:1015E000F7032B5E02F009B80068DE4F06A99F00E2 -+:1015F000E0023B00208E03BFDE02F009A000E00203 -+:101600003700208D0323DE02F009C00068DE4EF1B2 -+:10161000C9C00187E002107083018460020910488C -+:1016200000B05E870017A1006EE0030029A603D179 -+:10163000DE02F009A700685E4F0629B601BC600310 -+:10164000000AA603295E02F009AC0203DEB300091A -+:10165000AD0191601A84F4270183E002F597AC0292 -+:101660000200BF0009B50203456F0009B00185E023 -+:10167000062B715B02045EB30009B50187E002101E -+:1016800070830183E00209104800025E02F0112716 -+:1016900003BFDE02F009C00205500B0009C0018241 -+:1016A000600609104803BFDE02F009C0028700C3CC -+:1016B0000009BD0068DE4F06A9BD0068D21300090D -+:1016C000BD01BC600300118301BC600300118200F6 -+:1016D00068DE4F0629C000E0024F00209303BFDE02 -+:1016E00002F009C003AB5E02F009C2020441070028 -+:1016F00009C5028341070008AB03BFDE02F009C53C -+:10170000028441070008AB01806006F2979403BF92 -+:10171000DE02F008AB039F5E02F009CA039EDE0200 -+:10172000F00BE902035E53000BE902048143000958 -+:10173000CE010001630017A10102C0270017A2001B -+:1017400038DE86F449C403AB5E02F009D0020052D1 -+:10175000170009C40280522F0009D203335E02F041 -+:101760000BE902181B330009F201BC601F15F0657C -+:1017700001BC60031BB7A400025E02F000E900B0E8 -+:101780005E8F0017A60068DE931BA9EE0207C197C3 -+:101790000009DF01385A070017A1013C5A0700175A -+:1017A000A201BC5A0AF457A2013C5A0B0017A3012C -+:1017B000BC5A0EF477A303BFDE02F009E2013C5AE3 -+:1017C000030017A100B05A070017A200B05A0B007F -+:1017D00017A3006D5E870089E801BC61BF0A17A5E9 -+:1017E0000068DE8AF4A9E801BC60271357A50068E9 -+:1017F000DE8EF4A9E803BFDE02F00A2A00D85E8775 -+:101800000037A100E14196F4306500E1C197003056 -+:101810006501F041970017A200E05E8B0077A200FF -+:101820006D5E8AF4C9D500E840330097A5006E5E6E -+:1018300096004A2A00B01B2F0017A10068DE840A18 -+:101840000BE9023C523F000A03013C523F0017A142 -+:101850000068DE84048A2801BC600316106401BCA1 -+:10186000601F16106500685E870029FF00B05A03EC -+:101870000017A20068DE8AC00A2800E04197003005 -+:101880006500E0419300306400E85E870057A100E6 -+:101890006A5E870029F800685E87000A0401385AEA -+:1018A000030017A1013858030017A20068DE86F470 -+:1018B0004A2803BFDE02F00A040285C107000BE9D3 -+:1018C00001BC601F15F06501BC600305B7A40002F0 -+:1018D0005E02F000E9028000C3000A2801BC601328 -+:1018E00010D7A600E0017F00B7A5006D5E96F4CA90 -+:1018F0000C01BC60130957A500685E940BCA2C004C -+:10190000B0017B00106500B052270017A200B05252 -+:101910002B0017A3006841940BEA170068DE8ED0F5 -+:101920004A1300685E8AD02A2800E0419700B0651B -+:10193000006D4196F4CA1001BC601309506503BFE5 -+:10194000DE02F00A1000E0028B0020A200B0017F4E -+:1019500000106500B0522300168000B05227001618 -+:101960008100B0522B0016820080921B0197A200CA -+:10197000E0015E0DB0640203587F000A2101BC60E3 -+:101980002F0037A103BFDE02F00A2201BC5202F28F -+:10199000F7A101A95E02F436830090446701168422 -+:1019A000020281AB000A260068DE9305AA270184A3 -+:1019B0006006D0968400B05E9700005F020781AB9E -+:1019C000000A2A01806006F2979403AB5E02F006DB -+:1019D000AA03BFDE02F008AB00E0028F0020A303E1 -+:1019E000BFDE02F009C4039EDE02F00BE903AB5E2A -+:1019F00002F00A31020052170009C403335E02F0FC -+:101A00000BE901846006F2979403AB5E02F006AA2C -+:101A100003BFDE02F008AB03835E02F00A38000267 -+:101A20005E02F0117A006D4033038A35006D403359 -+:101A30000389C4032B5E02F00BED03BFDE02F00648 -+:101A4000AA032B5E02F00A3E00E0023300208C0362 -+:101A5000BFDE02F006AC00E0024B0020920103C0A2 -+:101A60002700178101825E0503178100025E02F0E4 -+:101A70000D9A008800230037A200E05E8800F7A2DC -+:101A800000E05E86F451890186E00630118003BFD4 -+:101A9000DE02F009C003A2DE02F0008103A3DE0231 -+:101AA000F00A6400E001FF00207F01BC6003001722 -+:101AB000A303BFDE02F00A66018760040310A001E1 -+:101AC000BC60030051E400B0479300180001BC6003 -+:101AD0000302900401BC620F0011E001BC600F0121 -+:101AE00031E800B047A300180001BC600F0011E806 -+:101AF00001BC60030131EC00B047B300180001BC29 -+:101B000060030011EC018460060910480020601E8B -+:101B1000090A5B00E001FB00207E03BFDE02F00A41 -+:101B20006C01BC60030ED7A1011400630017A20072 -+:101B3000E05E86F4506500E05A0300368002030040 -+:101B4000C7000A6103A95E02F00A660291509F0075 -+:101B50000A650191601A84F42703BFDE02F00A656A -+:101B600000E001FF00207F01BC60030037A30323D6 -+:101B7000DE02F00A6C0183E0020910480184600271 -+:101B8000F597AC01BC600300178E0187E00210706E -+:101B9000830182600209104803D0DE02F00A6D035F -+:101BA000D05E02F00A6E0182E00209104803D5DE21 -+:101BB00002F00A7001BC60030010B401BC600300B5 -+:101BC000F7A1006800A7000A740185421AF437A142 -+:101BD00000025E02F000A200B040670017A501BC41 -+:101BE00063FF1FF7A200025E02F000A800886007F2 -+:101BF0000157A400B85E86F497A100025E02F000CF -+:101C0000A80283C21F000A7B00E044670117A102FB -+:101C1000044523000A80006B4466F42A7D00025EBE -+:101C200002F0116100685E8F0000020020E01E09D2 -+:101C30000A8400B05E9700142E03BFDE02F002CCCF -+:101C400000A8412300F04803BFDE02F00002018338 -+:101C5000600209104801BC6007001042006E40306D -+:101C6000020A8A00E0027700209D00025E02F01264 -+:101C7000A703A35E02F008AB03C6DE02F00A8D01E3 -+:101C800084E00609104803BFDE02F00AF70068206E -+:101C9000E3000A9500E844650717A101BC609F02B4 -+:101CA00017A2006D5E86F44A9501BC6003000838F7 -+:101CB00000025E02F00B160020E10209007C002009 -+:101CC000628A090A9900025E02F0117A03BFDE02FD -+:101CD000F0007C0284452300007C03915E02F0004A -+:101CE0007C0396DE02F0007C03965E02F0007C002E -+:101CF000025E02F00B1601BC600300602000680168 -+:101D000073000AAF00025E02F000D400B044670026 -+:101D1000083800B001730010E401BC600300000645 -+:101D200001BC600300005C01BC600301D78201D2EA -+:101D3000DE087570E000B00EB30010E100B000479F -+:101D400000108600B00ECF00108A01BC600300377F -+:101D50008100025E02F00D8D0190600A09104801B9 -+:101D6000BC610300308003BFDE02F0000201BC60F2 -+:101D7000030030420187E00224712300025E02F07A -+:101D8000109301BC600306778000680DEF000AB66F -+:101D900000B00DEF00178100025E02F00E440397C1 -+:101DA0005E02F00B2703125E02F00AB601BC60036C -+:101DB00000402001BC618300112500B0007B0011B0 -+:101DC0002701BC600702578000025E02F00E3F0050 -+:101DD000B05E07000B3001BC600702778000025E36 -+:101DE00002F00E3F00B05E07000B3101BC6013092A -+:101DF00097A100025E02F000A200B04067000B63F2 -+:101E000001BC601309405E01BC601309405F0180A2 -+:101E1000E006F5D7AE0107C1070017A101805E8675 -+:101E2000F577AB01BC600F0011E801BC620F001137 -+:101E3000E000025E02F00AD801BC61CF0C105C0128 -+:101E4000BC600300105D01BC61CF01F05E01BC60AD -+:101E50003B0AF05F00025E02F0106301BC60030009 -+:101E60000835020300C700000401BC60030006023D -+:101E700001BC600300060701BC600300060C01BC46 -+:101E8000600300061103BFDE02F0000401BC6043E2 -+:101E90000017BB00A04122F770480185E002F5B7AA -+:101EA000AD01BC63FF1FF05401BC63FF1FF055017F -+:101EB000BC63BF1FF05601BC63FF0FF05700025E0A -+:101EC00002F012A70187E00624712301BC60030021 -+:101ED000105401BC600300105501BC600300105693 -+:101EE00001BC600300105701BC600F002017010601 -+:101EF000C1070017A101825E8402E01701074107B4 -+:101F00000017A100B85E870037A10180DE870000BE -+:101F1000160002DE02F000000285C0370000020059 -+:101F2000025E02F0117A00025E02F00F9502864016 -+:101F300037000AEC00E0021B0020860386DE02F078 -+:101F40000A870287C037000A870158600300102AF9 -+:101F500001BC600300900400B040130017A103BF50 -+:101F6000DE02F0000401B8600A04902403AA5E02B5 -+:101F7000F00AFA0158600300102A01BC60030290C5 -+:101F80000400B040130018000183600209104801EA -+:101F9000BC60030051E400B0479300180001BC622C -+:101FA0000F0011E00180600100680300025E02F092 -+:101FB0000F9503855E02F00B0101BC620F0011E07A -+:101FC00001BC600F0131E800B047A300180001BC5C -+:101FD000600F0011E801BC60030157A100E85E87B3 -+:101FE0000037A10068DE87000B0801BC6003029087 -+:101FF0000400B0401300180001BC60030131EC0084 -+:10200000B047B300180001BC60030011EC0324DEEC -+:1020100002F005F801866006F577AB00025E02F07B -+:102020000B160180600610308100B05E870017A19A -+:102030000180600210308103BFDE02F005F801BCB0 -+:10204000610300108000B04203001800006EE0033E -+:10205000002B1903505E02F00B1C00015E02F00021 -+:102060000003BFDE02F002F401846002F597AC00C9 -+:10207000A8412304F048018260020910480206DEEC -+:10208000AF000B2203D5DE02F00B220350DE02F07C -+:102090000B2001BC60030010B40284C783000B2531 -+:1020A00001BC600B0011E0018E6002F577AB00020D -+:1020B000DE02F0000003A2DE02F0007C02BC4287D8 -+:1020C000000B2E01BC60030037A401BC60031FF7A6 -+:1020D000A3011400630017A200886006F457A2034E -+:1020E000BFDE02F00B33008860070117A401BC6358 -+:1020F000FF0017A3011400630017A200E05E8B012C -+:1021000017A200886006F457A201BC601311106585 -+:1021100001BC601B02506401BC60030017A50020D5 -+:10212000C286F48B3D00E0419706D06500E0419304 -+:1021300001F06400E05E970037A500885E930037E9 -+:10214000A400205E92F46B5C03BFDE02F00B36004D -+:1021500068DE92F44B4200680083006B4203A0DE0D -+:1021600002F00B420020C123160B3700025E02F082 -+:102170000B16006DDE93200B58020300C7000B4CBA -+:10218000006DDE97008B4C01BC600300160801BC9B -+:10219000600300160901BC600300160A01BC60035D -+:1021A00000160B01BC600300160C01BC6003001696 -+:1021B0000D01BC600300160E02005AC3000B57024B -+:1021C0003C5A9F000B5700680083006B570385DE65 -+:1021D00002F0007C03855E02F0007C03A2DE02F0C8 -+:1021E000007C03A3DE02F0007C0397DE02F0007C9B -+:1021F00000B041970010600191600A84F42703BF8A -+:10220000DE02F002CC01806002D616B000B05E9310 -+:102210000010A101836002F7F7BF01BC600300302A -+:102220004303BFDE02F00B370068808300607C034D -+:10223000BFDE02F00AB70283C21F00000200B05ED8 -+:10224000870017A103D0DE02F0051001BC60030473 -+:102250001042039EDE02F0000400B05E3F00114514 -+:1022600001BC600300178F00B05E4300178500B00B -+:102270005E0F00179000025E02F00B1603BFDE0235 -+:10228000F00004006D40330589C503AC5E02F00B1D -+:102290006E00685E4F028BC000E002670020990369 -+:1022A000BFDE02F00BC000685E4F028BC000E00290 -+:1022B0005F00209701856002F5B7AD01826002F5ED -+:1022C000D7AE01BC6003000ABD039EDE02F00B82A4 -+:1022D0000321DE02F00B8200E0026F00209B00026F -+:1022E0005E02F00B16018660020910480180600250 -+:1022F0000910480181E00209104801BC6003021086 -+:10230000420280441F000B8100B05E3F0011450176 -+:10231000BC600300178F00B05E4300178500B05EFD -+:102320000F00179003BFDE02F00B8200A044B6F04E -+:102330007145028200C3000BC000B000730017A1FA -+:1023400000E05E86B017A100E15E7AF4379E00E1FE -+:10235000DE7700179D00E1DE7300179C00E0DE6F62 -+:1023600000179B039EDE02F00B91006E5E6E924B97 -+:10237000D6006D5E6E924B91006E5E72922BD6000F -+:102380006D5E72922B91006E5E76920BD6006D5E42 -+:1023900076920B91006DDE7A91EBD6028201AB0052 -+:1023A0000BA200B0446700083400B0446B0008334F -+:1023B00000B0446F00083200B04473000831006878 -+:1023C000A0D2232B9100E920D2F3D79E00E9A0CE22 -+:1023D000F3B79D00E9A0CAF3979C00E8A0C6F37785 -+:1023E0009B00E15E7A91F7A100B05E8700111900B1 -+:1023F000E1DE7692111A00E1DE7292311B00E0DE1E -+:102400006E92511C0068DE86232B9B03BFDE02F018 -+:102410000BC000E9523EF3D7A100E9D242F3B7A2C4 -+:1024200000E9D246F397A300E8D24AF377A40088E4 -+:10243000121B0057A500E0015EF4B06400E95E865F -+:10244000C9A6D200E9DE8AC9C6D300E9DE8EC9E694 -+:10245000D400E8DE92CA06D50080921B0197A50140 -+:10246000BC601B11778000E05E020DB06500885AE9 -+:102470000F00B7A500B05E970217A50125DA0F007F -+:1024800017A600E95E94DA57A500E8DE98DA77A689 -+:10249000017ADE96F4D7A500685E96D06BC000E89E -+:1024A0005E96D077A600B05E9700168300685A1338 -+:1024B000000BBA00E05A16F4D68500685A1B000BD0 -+:1024C000BC00E05A1EF4D68700B05E8700164D00AF -+:1024D000B05E8B00164E00B05E8F00164F00B05EEF -+:1024E00093001650031EDE02F00BD6039F5E02F02F -+:1024F0000BD600685E4F028BD6032C5E02F00BD623 -+:1025000001BC601F16B06501BC600300B7A40002E7 -+:102510005E02F000E90068DE9300ABD60207C197C7 -+:10252000000BCC013C5A07001788013C5A0B0017DE -+:10253000A103BFDE02F00BCE01385A070017880155 -+:10254000385A0B0017A10080921B0197A200E001EE -+:102550005E0DB06400B05E230016280181DE86C3E4 -+:10256000F61F0187DE86249124020680F3000BD635 -+:102570000181E002C3F61F0187E00224912403AB2E -+:102580005E02F006AA03BFDE02F008AB032B5E0278 -+:10259000F009C403BFDE02F006AA03AB5E02F00B33 -+:1025A000DD032C5E02F009C403BFDE02F00BED0078 -+:1025B000B052230011F200B052270011F300B052C4 -+:1025C0002B0011F401BC60030091F500B0005B002A -+:1025D00011F003BFDE02F006AA0138523F0017A136 -+:1025E00002065E53000BE60138524B0017A100684B -+:1025F000DE87008BE903AB5E02F006AA03BFDE02B2 -+:10260000F008AB0068DE4F020BEC020781AB000B59 -+:10261000EC01806006F2979403AB5E02F006AA021A -+:102620000000F3000BF20206DE53000BF201185E0D -+:10263000830017A10068DE8700ABF201BC600B02CB -+:102640005142020052170009C403BFDE02F008AB7A -+:1026500001BC600300118301BC6003001182032CE4 -+:102660005E02F00BF90199E00620110003BFDE02C3 -+:10267000F00BFD0119402F0017A100685E870009CB -+:10268000C00199DE8620110003315E02F009C0000E -+:10269000A05E3B0097A200205E4EF449C00184601A -+:1026A0000209104803BFDE02F009C0032B5E02F0EE -+:1026B00009C00068DE4F042C0600B0523300179F9B -+:1026C00000B0522F0010EB0281522F00069200E062 -+:1026D00002AB0020AA0281522F0009A003295E024A -+:1026E000F00C0C0203DEB3000C0C0191601A84F4B0 -+:1026F000270183E002F597AC0208522F0006AA03D7 -+:10270000BFDE02F008AB01BC600300106701BC60D3 -+:10271000030010460180E0060930490282C11F0013 -+:102720000C1601BC602F1FF06501BC600300168011 -+:1027300000E841970030650069C197000C1301BCA7 -+:10274000600B00179401BC60030017AB01BC600371 -+:102750000017AC01BC60030017AD01BC600300179B -+:10276000AE01BC60030017BF01BC60030020200164 -+:10277000BC60030017A100025E02F000A201384015 -+:1027800067000028011C406700002901BC600300AD -+:10279000504901BC60030017A701BC60030017A8E3 -+:1027A00001BC60030017A901BC60030017AC01BCA9 -+:1027B00060030017AD0182E0060F10780206C1E346 -+:1027C000000C28006880A7000C2B03BFDE02F00C71 -+:1027D0002C006880A7008C2C01BC600B1EA000019F -+:1027E000BC600300200101BC634F01A00201BC6179 -+:1027F000DB06800301BC600300400401BC604309A8 -+:10280000200501BC601F14106101BC601317D0606B -+:1028100001BC600300082900B05E0F00178500A00E -+:1028200044B6F07145028741D7000C3701BC600304 -+:10283000000BF001BC600300107D01BC60030010C0 -+:102840007C01BC606300107B01BC600300107A0156 -+:10285000AC607F00107501BC63470897A10068C198 -+:10286000DAF42C43011A41DF0017A10068DE87016A -+:102870006C4301BC637B15ABF003BFDE02F00A9E24 -+:1028800001885E5CFF87FC01BC601F1F500701BC14 -+:102890006003019008018860060090040386DE0250 -+:1028A000F00A870305DE02F00C480386DE02F00A18 -+:1028B000870385DE02F00C4A00B05E870017A10096 -+:1028C0006EE003002C4E0386DE02F00A87006EC025 -+:1028D000146F2C5101BC60070010420207C0AF000A -+:1028E00007590002DE02F0000003215E02F00C57DF -+:1028F00000E02066F4281900B0206700178B03BFA2 -+:10290000DE02F00C5F028150C7000C5C011C509F7E -+:1029100000178B00E05E2EF4378B019C5E2E84F452 -+:102920002703BFDE02F00C5F011E509F00178B00D3 -+:10293000E05E2EF4378B019E5E2E84F4270002DECB -+:1029400002F000000107402700082800E020A30053 -+:1029500028280002DE02F0000000B044670017A241 -+:10296000017ADE8A2357A10090012F00B7A601BC8F -+:10297000601B11706501BC60030017A201BC601BE5 -+:102980000DD06401BC601B1B906300685A03000CEF -+:10299000A8006B5E86D06C7E00B05A030017A300BF -+:1029A000E05A0EF4D58000E05A0EF4768300E85A1F -+:1029B0002F00368B0069DA2F000C7200E85A0700EE -+:1029C000368B006CDA0EF42C6D01BC60030036000F -+:1029D00001BC600B00104301BC60030026DA00203C -+:1029E0005A0B080C7901BC60030026DB03BFDE0232 -+:1029F000F00C7E00205A0B140C7E01856006F5B7A2 -+:102A0000AD0088009B00D1260090009B0151280159 -+:102A1000BC6303001124006B5E86B00C8600685A0C -+:102A200013000C8301886006D0568200B056030064 -+:102A300017A400E05E92D0968500E05A0EF4D5808F -+:102A400000205A0B080C8601BC60030006DB0068FE -+:102A50005A13000C8E006B5E86D0AC8E0188600A23 -+:102A6000D0568200B056030017A400E05E92D096C4 -+:102A70008501BC600300360101BC600B00104301FE -+:102A8000BC60030026DA00685A1B000CA8006B5ECD -+:102A900086D0ECA802015A0B000C9D00E85A1B00DE -+:102AA000368600B05A270017A300E05A1EF4768736 -+:102AB00001BC601B1C106200E0418AF4506200B04F -+:102AC0005A2B0017A300E05402F475000202D4034D -+:102AD000000C9B00E05A1F003687012054030015AC -+:102AE0000001816002D0568203BFDE02F00CA0001C -+:102AF000B05A230017A300E05A1EF47687018160C4 -+:102B000006D0568200685A1B000CA2006CDA1EF434 -+:102B10002C9002015A0B000CA501BC600300360288 -+:102B200003BFDE02F00CA601BC600300360301BC4B -+:102B3000600B00104301BC60030026DA00E04197FF -+:102B400001906500E05E8B0037A200E041930090A9 -+:102B50006400E0418F003063006D5E8B008C6A0082 -+:102B600002DE02F0000000B05A0300101F00B05A4D -+:102B70000700102000B05A0B0010210180600700F0 -+:102B8000101D02804077000CB20002DE02F000004F -+:102B90000187E002F577AB03915E02F000020020AE -+:102BA000E3FE09000200025E02F00C6301BC601B40 -+:102BB00011706400E041930617A20068D82F000C42 -+:102BC000BC0281D80B00000200E041930190640038 -+:102BD0006D4192F44CBA0287C49300000200689BD6 -+:102BE0006F00000202815E53000CC90283411F0086 -+:102BF0000CC30281DE53000CCF01BC6003001151F5 -+:102C000001BC600300115201BC620300115301BCFE -+:102C1000600300515001896006F2979403BFDE0201 -+:102C2000F000020280C54300000201F0C547001118 -+:102C3000560107C5470017A101F0C54AF4315501F7 -+:102C400089600AF2979401BC60030810470392DE82 -+:102C500002F00D1C01BC601B11706501BC6003001B -+:102C600037A101BC63FF1FF7A201BC60030017A3DB -+:102C700001BC60030017A600685A03000D0B01BCDD -+:102C800060030017A502035A0B000CDE02805A0BEA -+:102C9000000D1C00E944080977BB00E8C40F0017C9 -+:102CA000A4017ADEEEF497A400685A13000CEA033C -+:102CB000BFDE02F00CE70203DA0B000CF200B05AA0 -+:102CC0000F0017A400685A07002CE300685A2F0071 -+:102CD0002CE301BC60030037A500685A13000CE721 -+:102CE000006CDE92D0ACE700B05A170017A401BC0C -+:102CF00060030037A5002019FAF42CEA00685A1B7B -+:102D0000000D0503BFDE02F00CED00885E87009722 -+:102D1000BB002019FAF76D1C02015A0B000D1C00B4 -+:102D20006CDE92D0ED0500B05A1F0017A4002019E8 -+:102D3000FAF42CF101BC60030037A503BFDE02F0FA -+:102D40000D050202DA0B000D0B0204C107000D1C79 -+:102D500000B05A0F0017A400E85A2F0037BB0069D3 -+:102D6000DEEF000CF800E85A070037BB013C016FAA -+:102D70000017800068DE03000CFE0138016F0017A9 -+:102D80008000685E03000D0100E85E030037BB03AE -+:102D9000BFDE02F00D0100E85E030037800080DE38 -+:102DA00002D0378000E05EEE0DB7BB00685EEF003A -+:102DB0000D0500E05E92D017A400E85EEF0037BB7F -+:102DC00003BFDE02F00D0100685E8F000D08006B8E -+:102DD0005E92F44D0903BFDE02F00D0B01BC6003EF -+:102DE0000037A300B05E930017A200B05E970017F3 -+:102DF000A600885E870037A100E04197019065003A -+:102E00006D5E87020CD500685E8F000D1C00B0441B -+:102E1000670017A5017ADE962357A500E85E8AF4BD -+:102E2000B7A400885E9300A6D700905E930166D891 -+:102E300000B0012B0017A300689B63000D17006E04 -+:102E40009B5EF46D1C03A65E02F00D1C00B05E9B41 -+:102E50000006D900E91B5EF4681400E89B630008D3 -+:102E60001503BFDE02F00D1E00681B6700000203A1 -+:102E7000BFDE02F00D6F01BC610300112300692069 -+:102E800057000D220180E006F2979403BFDE02F0A6 -+:102E90000D240180E002F2979403BFDE02F00002ED -+:102EA00000684127000D3002844523000D2500B045 -+:102EB00044670017A100E84466F437A2006D5E8BFA -+:102EC000004D270280C127000D2B0392DE02F00D7A -+:102ED0006F0392DE02F00ACA00025E02F010970051 -+:102EE000025E02F00E4F00025E02F00E4A00025E29 -+:102EF00002F00E5A01BC600F0011E8031EDE02F062 -+:102F00000D3701BC600300105C01BC600300105D64 -+:102F100001BC605304105E01BC600300105F03BF7E -+:102F2000DE02F00D3B01BC600B00105C01BC6003D5 -+:102F300000105D01BC604304105E01BC6003001022 -+:102F40005F01BC6003008020028500BF000D80008F -+:102F5000B0205300115100B02057001152006E20D4 -+:102F6000522A8D430068A057000D4300E0205223F1 -+:102F7000281603BFDE02F00D4500B04467000816B6 -+:102F800001BC600300315001BC60030C90400000A4 -+:102F9000DE02F000000068C103000D4A02804543D4 -+:102FA000000D45006B446502CD4501BC6003001176 -+:102FB0005002844543000D4B00B044670017A10048 -+:102FC000685E86232D4D01BC6003004020018660B1 -+:102FD0000620110000E920522A37A100E8A0562A55 -+:102FE00057A200E14466F4311900E1C46AF4511AB1 -+:102FF00000E1C46F00111B00E0C47300111C00B09D -+:10300000441F001800008844230157A30090442364 -+:1030100000D7A400B0440B0017A100B0440F001764 -+:10302000A200E95E862337A100E8DE8A2357A200CA -+:1030300069DE8B000D6500E1440AF4710200E0C412 -+:103040000EF4910300E02AF7002ABD00E85E230099 -+:1030500037880069DE23000D5900E8002700378813 -+:1030600003BFDE02F00D59018660022011000068E6 -+:10307000C103000D6F00681B67000D6F01BC60434A -+:103080000017A100E04466F4378001BC600300062D -+:10309000DA00025E02F00C63006C4466F00D6F0013 -+:1030A000681B6B000D6B03BFDE02F00CCF0200DE6D -+:1030B00053000D820180E002F2979400025E02F05C -+:1030C0000E4D01BC600300104003BFDE02F00D7521 -+:1030D000020080C3000D7900E044640957A100E8B4 -+:1030E0005E862137A1006CC466F42D7703BFDE0233 -+:1030F000F00D8200E8012A21281401BC60030008B9 -+:103100001500B0205300115101BC600300115201A1 -+:10311000BC600300315002804543000D7E03BFDEDA -+:1031200002F00D4F01BC600300104000B0012B0005 -+:1031300011090068AAE7000D8300B0012F001109F2 -+:1031400001BC61CF0C105C01BC600300105D01BCD0 -+:1031500061CF01F05E01BC603B0AF05F00025E02DD -+:10316000F00E5600025E02F00E5F00025E02F00EEC -+:103170005301BC60030006D903BFDE02F00ACA0196 -+:10318000885E0610D08601025E070017A101825EEC -+:103190008610D08601BC600306778000B00DEF007A -+:1031A00017810288421B000D9400B00DEB001781BF -+:1031B00000685E07000D9600025E02F00E44020BEE -+:1031C000421B000D9803BFDE02F00D99018B20A277 -+:1031D00010D0860002DE02F0000000B05413001789 -+:1031E000A10200DE07000DA100B0418B00106501B7 -+:1031F000BC600301D7A100025E02F011A500E05EF1 -+:103200008400F7A103BFDE02F00DA6020480F300E4 -+:103210000DA602025E07000DA602805E07000DA645 -+:103220000090001B0037A200E85412F457A10002DE -+:10323000DE02F00000020400BF000DAA00025E02E0 -+:10324000F00F4E03BFDE02F00DAB00A044B6F0B1AC -+:10325000450002DE02F00000020000BF000DBC00CD -+:1032600068AC0F000DBC00E05EA30037A8006D5EE7 -+:10327000A005CDBC00B02CB70017A100025E02F083 -+:1032800000A200B040670017A20068DEA3FFEDB9FE -+:1032900000B05E8965D7A2006D00A7008DB8006DF3 -+:1032A000A0A3004DBA03BFDE02F00DB90068A0A3D1 -+:1032B000000DBA00B85E8965D7A200025E02F00078 -+:1032C000A801BC60030017A80002DE02F0000000A5 -+:1032D000D85A030117A201B85A06F457A200B056F3 -+:1032E0000300083C00B0560700083D00B0560B0034 -+:1032F000083E00B0560F00083F00B05613000840CB -+:1033000000E05612F4484100B05A0300083A013870 -+:103310005E8B00083B00B021070017A401BC6003CE -+:103320000017A200B0419300106500B85E92D0175C -+:10333000A400E05E06F4506300F05E930017A30063 -+:10334000F05E930077A400E05E8B0037A200B85EC9 -+:1033500092F477A400E04192F4506500E05602F444 -+:10336000958000B056030017A4006EDE8B00ADCA36 -+:1033700000B85E92C0D7A200D85E8B0037A200E0F2 -+:1033800020F2F4483C00B020F30017A400B85E928D -+:10339000C0F7A200D85E8B0037A200E020F6F44808 -+:1033A0003D00D820F70037A200E020FAF4483E00A4 -+:1033B000D820FB0037A200E020FEF4483F00D820D0 -+:1033C000FF0037A200E02102F4484000D8210300AA -+:1033D00037A200E02106F4484100B021070017A2FF -+:1033E00000B85E8AC017A200905E8B0037A201BCB5 -+:1033F0005E8907683B0002DE02F000000180600683 -+:103400003C91E4018760063CD1E601A860023CD112 -+:10341000E6018B60023CD1E600B05E8F00106300D5 -+:10342000B056030011E700B056070011E700B05690 -+:103430000B0011E700B0560F0011E701A960423CF4 -+:1034400091E401A860023CD1E6018B60063CD1E624 -+:1034500000B05E8B00106301BC60030057A1020442 -+:103460005603000DF801BC60030117A100E0418E76 -+:10347000F4306300B056030011E700B056070011A6 -+:10348000E700B0560B0011E700B05E8B001063013F -+:10349000BC600300B7A10204D603000E0201BC60A9 -+:1034A000030117A102065E53000E0201BC60030176 -+:1034B00097A100E0418EF4306300B056030011E79D -+:1034C00000B056070011E700B0560B0011E701BC31 -+:1034D00060030017A10206DE53000E0D00B05E8BE4 -+:1034E00000106302065E53000E0C00A0563F01F769 -+:1034F000A103BFDE02F00E0D00A0563301F7A100BC -+:10350000B05E870011E701BC60030011E70002DE36 -+:1035100002F0000000685E9B00CE2A01BC6007023A -+:1035200011E30068DE9B004E1D00E847870111E1B2 -+:1035300001BC60030011E201BC60030011E201BCA8 -+:1035400060030011E201BC60030011E201BC6003F2 -+:103550000011E201BC60030011E201BC6003001134 -+:10356000E201BC60030011E200B06142F451E000EE -+:10357000B058030011E200B058070011E200B05843 -+:103580000B0011E200B0580F0011E200B058130018 -+:1035900011E200B058170011E200B0581B0011E210 -+:1035A00000B0581F0011E200B05E9B0017A4006835 -+:1035B000DE9B00AE2801BC60030077A40192DE937D -+:1035C0000217A30002DE02F0000001BC6007001138 -+:1035D000E300B058030011E200B058070011E20008 -+:1035E000B0580B0011E200B0580F0011E200B058C3 -+:1035F000130011E200B058170011E200B0581B0090 -+:1036000011E200B0581F0011E200E00146F0106422 -+:1036100001BC60070031E300B058030011E200B0C4 -+:1036200058070011E200B0580B0011E200B0580F2B -+:103630000011E200B058130011E200B05817001159 -+:10364000E200B0581B0011E200B0581F0011E20167 -+:1036500092E01B0017A30002DE02F0000002874088 -+:10366000C3000E3F01866006F01030028640C300A2 -+:103670000E4100B040C70017810002DE02F00000DA -+:10368000028740C3000E4400B05E0700103101867F -+:10369000E006F010300002DE02F00000006800A733 -+:1036A0000112E303BFDE02F00E5E00025E02F00EC6 -+:1036B0004D00025E02F00E5F0002DE02F00000002C -+:1036C0006800A70112AC0002DE02F0000001816078 -+:1036D00006093049006800A7008E5200025E02F021 -+:1036E0000E6F0002DE02F0000000025E02F00E6FBC -+:1036F000018160020930490002DE02F00000018809 -+:10370000E00E09304900B0412700180000B0002B3E -+:103710000010020002DE02F0000001BC6003001095 -+:10372000020182E0020F107801BC60030010490022 -+:10373000B041270018000002DE02F000000068001F -+:10374000A7010E600280DE53000E6601BC60130705 -+:1037500077A100025E02F000A2019060020337A28E -+:1037600000025E02F000A80002DE02F0000001BCD0 -+:1037700060130797A100025E02F000A20190601E94 -+:103780000337A200025E02F000A801BC60130777B5 -+:10379000A100025E02F000A20190601E0337A200A9 -+:1037A000025E02F000A80002DE02F000000100DE6E -+:1037B000530017A60181DE9A09304900B041270065 -+:1037C00018000002DE02F000000002DE02F000003D -+:1037D00000B044670017A2017D5E8A2357A300B0A2 -+:1037E0001C770017A100B85E84E3D7A2025A5E8B53 -+:1037F000000E7C0180E006F4271E01825E86F297AF -+:103800009400B05E8F00071B02001C7B000EC300FB -+:10381000E85E8CE377A2006D5E88E38EC300E0442F -+:10382000670287210285C523000EC00020E3FE0940 -+:103830000EC001BC60130997A100025E02F000A255 -+:103840000068C067000EC001BC60131617A100021B -+:103850005E02F000A20068C067000EC001BC6013E9 -+:1038600009D7A100025E02F000A20068C067000E46 -+:10387000C001BC63FF1FF7A10068DE862C2EC002CA -+:10388000009C7B000EB40180E000E3C71E01BC6019 -+:10389000230F57A100025E02F000A200B0406700B3 -+:1038A00077A400B05E930017A200025E02F000A8A9 -+:1038B00001BC601B1B57A100025E02F000A2018147 -+:1038C000E0060337A20186E006F457A200025E027A -+:1038D000F000A801BC601714D7A101BC600300B7B9 -+:1038E000A200025E02F000A801BC60171457A101FB -+:1038F000BC60031877A200025E02F000A801BC6061 -+:103900001714B7A101BC600300F7A200025E02F029 -+:1039100000A801BC60171077A101BC600F0417A2BA -+:1039200000025E02F000A801BC60171097A101BC64 -+:1039300060030017A200025E02F000A801BC60173D -+:1039400010B7A101BC600B0017A200025E02F000DC -+:10395000A801BC601710D7A101BC60030017A2002A -+:10396000025E02F000A801BC60171017A101BC6044 -+:103970000B0037A200025E02F000A801BC60230F1A -+:1039800057A100A85E930077A200025E02F000A893 -+:1039900001BC60171017A100025E02F000A2020035 -+:1039A0004067000EB9006CC464E42E8003BFDE02E1 -+:1039B000F00EC001BC60171277A100025E02F00099 -+:1039C000A20068C0671FEEC001806000E3C71E014F -+:1039D000BC600300904301806000E3C71E01826069 -+:1039E00002F297940180E004E3C71E01BC6003006B -+:1039F000071A03BFDE02F00EC30002DE02F0000071 -+:103A00000201C11F000ED602855EAF000EC90185FE -+:103A10006006F577AB00B0446700082500B0446B42 -+:103A200000082600E9446504B7A100E8C46904D78A -+:103A3000A200D05E870077A101E1DE8AF437A20000 -+:103A4000E95E862697A100E8DE8A26B7A200695EB5 -+:103A50008B000ED601BC610300113300E144DAF49F -+:103A6000313600E144DEF4513701856002F577AB71 -+:103A700001BC600301104701BC6003005043000219 -+:103A8000DE02F0000000B0451F00178100B005B74E -+:103A90000017A601BC600704106401BC601311107C -+:103AA0006501BC60030017A10205DEAF000EEF0048 -+:103AB000B0580F00178000685E842C2EF702005E5D -+:103AC0009B000EEF0280DA03000EE50118581F007C -+:103AD000178200E05E0B00378201985E0AC0F6078D -+:103AE00003BFDE02F00EE8011A581F00178200E043 -+:103AF0005E0B003782019A5E0AC0F60701F0DE0312 -+:103B000000378000A05E02C0578000B05E03001640 -+:103B10000300A044B6F0178200B05E0B001605004B -+:103B2000E05E0AC0960603BFDE02F00EF700B05852 -+:103B30001300178200E85E06F057A5006ADE9700C2 -+:103B40000EF500E85816F4B6050069D817000EF512 -+:103B500001BC600300160500B058170017A500E06F -+:103B60005812F4B60600E0419302106400E0419759 -+:103B700006D06500E05E870037A100905E9B0037AD -+:103B8000A60068DE87008EDC01BC600300114701DF -+:103B9000BC600300016D0002DE02F0000001BC60A9 -+:103BA0000300016C01BC600300016D01BC60070AE9 -+:103BB000106401BC60030077A100B0428F00178041 -+:103BC00000A05E0301F78000B05E0300016E01BC3F -+:103BD00063FF1FF7A20068DE03000F0901BC60034A -+:103BE0000017A200886006F43781002005BAF02F84 -+:103BF0000E0068DE8AC0CF0E00E005B300216C0025 -+:103C0000B005B6F0216D00685E03000F1200205E63 -+:103C100006F00F18006EDE8AC0CF1803BFDE02F078 -+:103C20000F13006DDE8AC0CF1800B05E870017A3A7 -+:103C300000B0419300016600B0581B0017A201BC00 -+:103C4000600300016C01BC600300016D00E841935A -+:103C500002106400E85E870037A10069DE87000F6C -+:103C60000900B05E8F0001650002DE02F000000076 -+:103C7000B0059B001064006E581B002F2100E05817 -+:103C80001B00314503BFDE02F00F2200B0581B00BD -+:103C9000114500B0059B00016200B005970001616D -+:103CA00000B0580F00178500B0580700178300B008 -+:103CB000580B0017840118581F00178C011A581F41 -+:103CC00000178D0002DE02F0000000B0059700171B -+:103CD0008000685E002C2F4D01BC600300111201B2 -+:103CE000BC600300111500B0059B00106402004584 -+:103CF00023000F3700B0451F00178100E80592F040 -+:103D00003780006ADE03000F3500B05E0300114506 -+:103D100003BFDE02F00F3801BC600300314503BF72 -+:103D2000DE02F00F3800B0059300114500B00583A6 -+:103D300000016900B0058B00016A00B0058F000129 -+:103D40006B00B0058700016800B005AB001065028C -+:103D5000845A1F000F4100B05E1700168301985E61 -+:103D600032D0F687019A5E36D0F68701846002D0A1 -+:103D7000F68700B0059300016000B0059B0001626A -+:103D800000B0059F00016300B0059700016100B01D -+:103D9000058B00106400B0580F00178500B058075D -+:103DA00000178300B0580B0017840198581EF19734 -+:103DB0008C019A581EF1B78D03BFDE02F00F4D0043 -+:103DC00002DE02F0000000B0058B001064006E41BE -+:103DD000932A0F5B00A044B6F0B7A100B05E870045 -+:103DE000160500E05812F4360600B0581B001145C5 -+:103DF000020000F3000F58006D4193280F58020095 -+:103E0000DEAF000F5801BC600B02514200B05E876C -+:103E100000016F02015EAF000F5B00B05E1700167D -+:103E20000301816002F577AB0002DE02F0000002C0 -+:103E3000014523000F660287C493000F660182606C -+:103E400002F5D7AE02012C43000F6300E02C4B00BB -+:103E50002B1201816001620B1002055EB7000F6634 -+:103E600000E02AF7002ABD01856002F5B7AD000227 -+:103E7000DE02F00000020200BF000F7400025E02CA -+:103E8000F00F960202DEB3000F6C0020428F000C90 -+:103E9000B403BFDE02F00002028881AB000F74029F -+:103EA000845EFF000F6A02845EB3000F6A0282DE46 -+:103EB000FF000F6A02822B4F000F7200682ABB00BE -+:103EC0000F740284DEAF000F6A02835EB7000F6AD0 -+:103ED00000B05E870017A10002DE02F00000018240 -+:103EE000E002F597AC0203DEFF000F7E028445235B -+:103EF000000F7E02012B4F000F7E0180E006F2973B -+:103F00009400025E02F00E6F0180E002F2979400CE -+:103F1000025E02F00E6F0180E002F29794028400CC -+:103F2000C7000E4803BFDE02F00E4A020400C700BD -+:103F30000F880284C56F000F9402844523000F850B -+:103F400002004203000F9400685E4B04AF940068C7 -+:103F50005E4B06AF9400685E4B062F940182E0062C -+:103F6000F597AC02844523000F8B0323DE02F00F8C -+:103F70008C0183E006F597AC0180E006F29794028D -+:103F80008400C7000E4800B02AF70017A2006DDEBB -+:103F900089560E4802872B4F000E4A02005EFF0032 -+:103FA0000E480287AB4F000E4A03BFDE02F00E48F8 -+:103FB0000002DE02F00000020200BF0013000068F1 -+:103FC0002B0B000F9B00E844655857A101BC63F719 -+:103FD0001D17A2006D5E86F44F9B00E84466F44A0C -+:103FE000C2006CC465576F9D00E84467002ABB029D -+:103FF00080456F000FD10203DEB70010580183E047 -+:1040000002F5B7AD0202DEB3000FA3018360062BF9 -+:10401000915C00025E02F00F7602835EBB000FA689 -+:1040200000E845895BF7A1006E5E8555AFBE0204CE -+:10403000DEB7000FBA00E02BB7002AED01BC600329 -+:10404000000AEF00682C67000FAB00E82C67002B1C -+:104050001900B02BB70017A201856002F5B7AD02B9 -+:1040600004DEFF000FB0006D5E895DCFB00184E01B -+:1040700002F7F7BF0206DEFF000FBA00E02BE702EF -+:104080000AF900B04467000B0401182BE70017A1E0 -+:10409000011A2BE70017A2006E5E87000FB8006DB3 -+:1040A000DE895F4FB803BFDE02F00FBA01BC6003C8 -+:1040B000000AF90186E002F7F7BF02025EFF001076 -+:1040C000580068AB0B00105800B02AE7000AC20085 -+:1040D00002DE02F000000182E002F7F7BF02025E9A -+:1040E000FF000FC8020600C7000FC102025EFF00FA -+:1040F0000FC800E845895BF7A1006DDE85614FC6FA -+:1041000000E844656177A1006D5E85618FC800B0ED -+:104110004467000AC20002DE02F000000204DEB7BB -+:10412000000FD000E8446556CABE00682C67000F37 -+:10413000CC00E82C67002B1900E02BBF002AEF0011 -+:10414000B02BC30017A1006D2BBEF42FD001BC60B3 -+:1041500003000AED0002DE02F000000203DEB700F9 -+:104160000FD80282DEB30010580203C57300104A54 -+:1041700000E844655737A1006D5E8556B05801834D -+:104180006006F5D7AE03BFDE02F0105801BC600335 -+:10419000000ADF006D45871F4FDB00B04587000A2E -+:1041A000DF00E044655BF7BB00E85EEE2C2AB90156 -+:1041B000836002F5D7AE0183E006F5B7AD0184E078 -+:1041C00002F5B7AD01826002F7F7BF01846002F526 -+:1041D000B7AD0101456F0017A101875E86F577AB8A -+:1041E00001BC6003000B0D00025E02F0130100E849 -+:1041F00044655737A1006D5E855ECFE6006D5E8534 -+:1042000056AFEA00E02B83002AE000B02AB3001783 -+:10421000B3020680C7000FED02075EAF000FF00289 -+:104220000680C7000FF20184600561AB0D03BFDE9D -+:1042300002F00FF201826006F7F7BF00B02AE70034 -+:104240000AC10200C56F000FF601846006F5B7AD24 -+:10425000020480C3000FF60184E00561AB0D020289 -+:10426000DEBB000FFC0284DEFF000FF90206DEFF5A -+:10427000000FFC00B02BB70017A1006DDE855DCFED -+:10428000FC0182E00561AB0D00E05ECD55B7B301E6 -+:10429000826002F5D7AE00B02C4B0017A100B02A07 -+:1042A000F70017A2006D5E8956100302855EB70005 -+:1042B000100C03BFDE02F01005006D5E8560F00E8D -+:1042C00002812C4300100C00B0440B0017A300B077 -+:1042D000440F0017A200E95E8E2337A300E8DE8AB0 -+:1042E0002357A200695E8B00100E0068DE8B001061 -+:1042F0000E006E5E8EF6700E01826006F5D7AE007F -+:10430000025E02F0114902045EB70010230206802B -+:10431000C700101102075EAF00102300682ADB00FF -+:10432000101C00E8446556D7A201BC60371597A35E -+:10433000006D5E8AF47023006E5E895D90230184B7 -+:10434000E006F5B7AD00685E8B00101C00B05E8B18 -+:10435000000AAE0182E006F5D7AE006E5E896110FC -+:104360001C0182600561AB0D00E844655737A10070 -+:10437000B044670017A300E85E8EF42AB60068AB6D -+:104380001708902200B02BCB0017A200E82ADAF41D -+:104390004AB601846002F7F7BF0282DEB30010580C -+:1043A0000203C57300104A00B02ACB0017A200B068 -+:1043B0002AD30017A300685E8F00102D00682B0B16 -+:1043C00000102D00E844655857A100E05E8EF457B8 -+:1043D000A2006D5E86F4502D0181600561AB0D0277 -+:1043E00081AB4F00103202005EFF00103202044524 -+:1043F0002300103203A0DE02F010320183E00561D9 -+:10440000AB0D0281AC4700104702862C37001058D4 -+:104410000286AC37001058028080BF00105802821C -+:104420005EBB00105802822BF30010470281AC37AC -+:104430000010470280AC3700104702812C37001073 -+:104440004702822C37001047028881AB00104702D8 -+:1044500082AC3700104002842C370010470284AC35 -+:10446000370010470283AC3700104702835EB70065 -+:1044700010460204DEAF0010460281DEBB0010468B -+:104480000184E002F577AB00025E02F0113303BF56 -+:10449000DE02F010580183E0022B915C020701ABB1 -+:1044A00000104A0180E00209D04E00E84465573709 -+:1044B000A1006D5E8555B058028101AB001050021D -+:1044C0000081AB00105202842C370010520280ACE5 -+:1044D00037001052018360022B915C03BFDE02F0B3 -+:1044E0001058018360022B915C00025E02F00F8184 -+:1044F00002835EB70010580184E006F577AB00E058 -+:104500002B47002AD103BFDE02F0111B0002DE029E -+:10451000F000000184E002F5B7AD01836002F5D739 -+:10452000AE0182E002F5D7AE0182E002F7F7BF01EB -+:1045300084E002F7F7BF01BC6003000ADB01BC6046 -+:1045400003000AD001BC6003000AC8018760016053 -+:104550006B030002DE02F00000020200BF001089BF -+:104560000283DEFF0010920183E006F7F7BF01BC73 -+:10457000600302115D00B02AB700115E018560067C -+:104580000B705B018560060BF05F0280456B0010CD -+:104590006D018B60022B915C0188600E2B515A00DB -+:1045A000682ADB00107001846006F7F7BF01BC6069 -+:1045B00003000AB600025E02F0105900E844696088 -+:1045C000D7A1006EDE8700307A00B02BF7000AF822 -+:1045D00001BC6003000AF700682B0B00107A00B0E2 -+:1045E0004467000AC100E84465564AC200B02AD3B5 -+:1045F0000017A100E82B0AF42AC2028080BF001035 -+:10460000800281DEBB0010840200456F0010800232 -+:1046100083C57300108001BC63FF1FF7A10068C54C -+:1046200086F43084018B600E2B915C0183E002F5EF -+:10463000B7AD0184E002F577AB03BFDE02F01126CF -+:10464000018360022B915C00025E02F00F81018306 -+:10465000E006F5B7AD0184E006F577AB03BFDE02F7 -+:10466000F01126018D60020BF05F0188600E2B5166 -+:104670005A028181AB00108E018B60062B915C0386 -+:10468000BFDE02F0108F018B60022B915C0183E092 -+:1046900002F5B7AD0184E002F577AB00025E02F0EF -+:1046A00010590002DE02F0000000B0446B000B065F -+:1046B0000202DEB3001097018360062B915C0002BA -+:1046C0005E02F00F76020200BF00109F0183E0023D -+:1046D000F7F7BF0203C57300109D020080BF0010F2 -+:1046E0009D018B600E2B915C03BFDE02F0109E01DA -+:1046F0008B60022B915C0182E002F597AC0002DE38 -+:1047000002F0000001BC600300701001BC63FF1FD9 -+:10471000F0C501BC63FF1FF0CB00B040470010E5BF -+:1047200000B040470010EB01BC600300901001BCDA -+:1047300063FF1FF0C601BC63FF1FF0CC00B0404711 -+:104740000010E600B040470010EC01BC600300B070 -+:104750001001BC63FF1FF0C701BC63FF1FF0CD0059 -+:10476000B040470010E700B040470010ED01BC60CA -+:104770000300101000B0404300180001BC63FF1F8D -+:10478000F0C800B040470010E801BC6003003010E2 -+:1047900000B0404300180001BC63FF1FF0C900B027 -+:1047A00040470010E901BC600300501000B04043D6 -+:1047B00000180001BC63FF1FF0CA00B040470010A2 -+:1047C000EA0002DE02F0000001BC60030037A20034 -+:1047D00020E3FE0910FA0020E0420D90FA02804228 -+:1047E000030010FA028445230010FA03915E02F0E0 -+:1047F00010FA0068AB6F0010FA0282DEFF0010FAB8 -+:1048000002805EFF00112F020180C7001126028284 -+:10481000DEB30010FA020480C70010E700685E8B68 -+:104820000010D300B02BA30017A1006EAB8AF430A8 -+:10483000D30203C5730010E700682ABB0010D20042 -+:10484000682ADB0010D300E8446556D7A100E82AA7 -+:10485000BAF437A1006ADE8555F0E7006ADE855BB1 -+:1048600050E700682B070010E70203DE530010D664 -+:1048700000B02BA7000AAF03BFDE02F0112601BC77 -+:10488000600302579201BC63FF1FF0C301BC6003C9 -+:104890000910E301865E8A1C70E3018460061C70C7 -+:1048A000E300682B0F0010DD0185E0061C70E301BA -+:1048B000BC600303978200025E02F0110401BC6336 -+:1048C000FF1FF0C400B054130010E400E043915CFB -+:1048D00030E400025E02F010A001BC60030010EEA4 -+:1048E00001BC63FF1FF0CE00E02B0F002AC303BF03 -+:1048F000DE02F010F402835EB70010FA00025E02DE -+:10490000F000D400B05ECF0010E400682ABB0010B5 -+:10491000F100B02AFB0010E40280456F0010F100A6 -+:10492000E8446556D7A100E82ABAF437A100695EC9 -+:10493000870010F100E05E8557D0E401BC60030100 -+:10494000D78200025E02F0110403BFDE02F010F411 -+:1049500000B0004700108600025E02F011980002CD -+:104960005E02F00D8D0190600A0910480184600616 -+:10497000F597AC01BC61330070800002DE02F000EC -+:104980000002805EFF0010FF0281DEBB0010FF020C -+:104990000180C7001126020480C700112601806033 -+:1049A00002F7F7BF0280C28F0011270201DEBB00B1 -+:1049B000112701BC60030017A203BFDE02F010BD87 -+:1049C00001BC63FF1FF0C001BC63FF1FF0C1028583 -+:1049D000DEFF00111400685E4B06310D00B02B574E -+:1049E0000017A1006DAB0EF4311401BC6003013758 -+:1049F0008000B02B5B0017A1006D2B0EF4310F026D -+:104A0000812BF300110F01BC600301778001BC60B2 -+:104A10000300378100025E02F000AF01D2DE0AA07F -+:104A200030E000B0540B0010E103BFDE02F0111AB9 -+:104A30000280ABF300110D01BC600301578001BC83 -+:104A4000600300178100025E02F000AF00B054075F -+:104A50000010E000885E0B0070E10002DE02F00052 -+:104A60000000682B130011260204DEAF001126009F -+:104A7000E844655897A4006E5E9155F12600885E63 -+:104A8000930037A4006D5E9155F12600025E02F09E -+:104A9000115603BFDE02F0113300E844655897A4B5 -+:104AA00000885E930037A400025E02F0115603BF37 -+:104AB000DE02F011330284DEAF00112A0181E00230 -+:104AC000F5D7AE03BFDE02F0113300682B8700116B -+:104AD0002F00E044655C2ADB00682B8B00112E0060 -+:104AE000E044655B4ADB0002DE02F000000180600A -+:104AF00006F7F7BF00682B1300113300E844655830 -+:104B000097A400025E02F0115601846002F597AC92 -+:104B100001BC6003000AC401BC6003000ADB01BCE5 -+:104B20006003000AC30104DEAF0017A101835E86A3 -+:104B3000F5B7AD0284DEAF00113C018060060D9038 -+:104B40006C0002DE02F00000028600C700113E0287 -+:104B5000025EFF00114400B02AAF0017A302040058 -+:104B6000C300114100B02ACF0017A30202DEBB0030 -+:104B7000114300B02AAB0017A300E04466F46ABBFF -+:104B800000B04467000B0B0183E0022B915C02072D -+:104B900001AB0011480180E00209D04E0002DE02A4 -+:104BA000F000000202DEB300114C018360062B917D -+:104BB0005C00025E02F00F760203C5730011510221 -+:104BC00084DEAF0011510281DEBB00115102805E14 -+:104BD000FF00115102035EB7001155018B600E2BCF -+:104BE000915C01836006F5B7AD0184E002F577AB17 -+:104BF00001BC6003000AC30002DE02F0000000688E -+:104C00002B7B00115800B02B7B0017A4006D5E9128 -+:104C100056515A00B02ACB0017A400882B27003722 -+:104C2000A500E82B2AF4AACA00885E930037A400E6 -+:104C3000E02B2AF48ACA00902B2B00AAC900B02BC3 -+:104C400027000AAF0002DE02F000000286410700E2 -+:104C5000116101BC60130917A100025E02F000A2FD -+:104C6000018760060337A200025E02F000A800B0D0 -+:104C70005E870017A100B05E870017A100B05E87B5 -+:104C80000017A101876002F457A200025E02F00043 -+:104C9000A801BC60130957A100025E02F000A20146 -+:104CA0008060060337A200025E02F000A800E00266 -+:104CB000B30020AC01806002F457A200025E02F053 -+:104CC00000A801BC60270857A100025E02F000A204 -+:104CD0000068C06701F17901BC60030017A20002FF -+:104CE0005E02F000A801BC600301F7A200025E02B0 -+:104CF000F000A80002DE02F0000003905E02F01156 -+:104D00008D03875E02F0118D0390DE02F0118D029B -+:104D10000445230011840283C21F00118D0068A086 -+:104D2000B700118100B0446700082D00E844650514 -+:104D3000B7A1006E5E877D118803BFDE02F0118E81 -+:104D40000286C03700118D00E0446700D7A102063B -+:104D5000403700118D006CC466F4318600025E029B -+:104D6000F00B1600025E02F0116101BC6003000846 -+:104D70002D00025E02F00AD803BFDE02F00004013B -+:104D8000BC600300082D0002DE02F0000002804239 -+:104D900003001197028545230011960285DEB700B6 -+:104DA00011940185E006F5B7AD00E0446B002B21BE -+:104DB000006CC46964319700025E02F011610185E4 -+:104DC000E002F5B7AD0002DE02F00000010C814305 -+:104DD0000017A101BC600300508A00685E07001143 -+:104DE0009C00685E8700119C00685E070011A401AA -+:104DF00090422AA1308A00685E070031A4019042E7 -+:104E00002AA0108A0109DE030017A2018F5E8A1111 -+:104E1000508A00685E8B0011A40191E00E11508A47 -+:104E20000002DE02F000000109DE030017A400E02A -+:104E30005A06F497A500905E96F497A50203DE0348 -+:104E40000011AC0282DE030011AC01BC61EF085717 -+:104E5000A60080DE96F4D7A50116DE870017A30012 -+:104E6000885E870077A100E15E8702D7A100E0DEBF -+:104E70008F0017A301BC60030017A2020E5E03009F -+:104E800011B301BC60030037A200905E96F457A5F1 -+:104E90000080DE96F437A100E141B7FFF7A600E1FC -+:104EA000DE8701F7A10080DE96F477A300E1DE86BD -+:104EB0000DB7A100E0DE8F0017A3017A5E86F477BC -+:104EC000A100885E86F457A100B05E870017A20299 -+:104ED00087DE030011C000885E870057A103BFDE94 -+:104EE00002F011CD02875E030011C701BC639B0C69 -+:104EF000D7A50080DE86F4B7A100E141B7FFF7A592 -+:104F000000E0DE870017A100885E870057A103BF7D -+:104F1000DE02F011CD00885E870057A101BC639BC3 -+:104F20000CF7A50080DE86F4B7A101BC6203001770 -+:104F3000A500E141B6F4B7A500E0DE870017A100A7 -+:104F4000E05E8400D7A10002DE02F0000002002033 -+:104F50000F0000040282DE530011D50188600204B4 -+:104F6000902400E020AEF3082B00E820AAF3082AE2 -+:104F700003BFDE02F0096201B8601604902401BC90 -+:104F8000600301D02503055E02F011E70287C037F8 -+:104F9000000A860386DE02F00A8700025E02F00F36 -+:104FA0009500025E02F0117A035CDE02F011D70078 -+:104FB000D8409B0117A100E05E8702379800A85EE9 -+:104FC000630077980102DE530017A10182E002F22C -+:104FD00097940188DE85006803006EA0AAF311E7AC -+:104FE00000E85E6301D02501B8600604902403BF89 -+:104FF000DE02F000020181600500680301B8600A6A -+:1050000004902403BFDE02F0000202285E87001134 -+:10501000FD00B041930017A400E0419300706401CB -+:105020000A5E870017A200E84192F4506301185EFF -+:10503000870017A100E86042F437A200885602F406 -+:1050400036000068418EF491F900E8418F0030632A -+:1050500000E8419300306400685E8B0211F100901B -+:105060005602F457A300B05806F4760103BFDE02DF -+:10507000F011F100684192F491FD00E84193003095 -+:105080006401BC600300160003BFDE02F011F900EA -+:10509000B05E870017A10002DE02F0000001806010 -+:1050A0000286143000B050CB0010650138508300E8 -+:1050B00017A10068DE3B06320500E05A3300368C4B -+:1050C000006EDA32F4200400B05A0B0017A200E0A0 -+:1050D00001F700207D00E001D2F4407401BC63FFC1 -+:1050E0001FF7A300B050CF001064006EDA32F43224 -+:1050F0000C00B05A370017A300B0581300178201F4 -+:10510000BC600300160401BC601B09D7B60102D0C5 -+:10511000C70017A100E04196F4306500E050CB00D5 -+:10512000D06401BC60030017B401BC6003001780A9 -+:1051300001BC6003003781018760040310A0009068 -+:1051400052330097A400E0418701B7B500685ED2F2 -+:10515000F0523300E05EDAF690630020D802F032BD -+:1051600027020250C700122D009056030097A1009D -+:10517000E85E86F497A1019E6002F437A1006DDE1F -+:105180008708122D010A5E870017A201DA6002F477 -+:1051900037A100E05ED6F4506300886006F437A1C2 -+:1051A00000205602F4322D00B05802F0360000E024 -+:1051B0005A2B00368A006ADED2F472290068DED2E9 -+:1051C000F0122E00E05E0300378000685E030032BC -+:1051D0002E0186E0040310A003BFDE02F0122E00B1 -+:1051E0006ADED2F4722900E05ED30037B400D05EEC -+:1051F0000700378102985ED300121800E041930047 -+:10520000306403BFDE02F0121800685E0300000481 -+:1052100003BFDE02F005AB0282D0C700123D00B032 -+:105220002A4F0017A101B82A4AF43684010250130C -+:10523000001685013C50830017A100B050A700174D -+:10524000A4006D5A32F432460182E00686343102FF -+:1052500088502B00124200B05A330017A1019E5E05 -+:105260008684F427018360068634310002DE02F072 -+:10527000000000B050730017A101B8506EF43684DE -+:105280000106D00700168500B050AB0017A400D06F -+:105290006006C0978000E0419700D7B5010A581317 -+:1052A0000017A100E05ED6F437B500B0580F00102B -+:1052B00063011656030017810068D81300125B01C2 -+:1052C0001400630017A10068DE87001251008801F6 -+:1052D0003B01168003BFDE02F012560068DE870035 -+:1052E000725400A0013BE0168003BFDE02F01256AC -+:1052F00000E05E870970620088540301168000E8B0 -+:105300005A0330168001BC600300168101BC6003A3 -+:1053100000168201BC600300168303BFDE02F01298 -+:105320006000E0418EC09063006EC18EC0326000AC -+:10533000E8418EC0306300E858030037A100E04127 -+:105340008EF43063013850A30017A500685813038A -+:10535000F27B0068418EC0527B006DDA0AF4B27BAA -+:10536000011656030017A10068DE86F0327B015853 -+:1053700056030017A100E05E870DD7A200B05ED7EC -+:105380000010620020DE02A0127200E05E86D037BC -+:10539000A300E05E8ED077A3006D5A02F4527B002A -+:1053A0006E5E8EF4927B00E86002F4368300B05E9D -+:1053B0008F00168100A05A0F00768300E05A0B0080 -+:1053C000368200E85A02F4568000D05E030037802F -+:1053D00000E0581300360400E0418F00306302986B -+:1053E000581300127800E05ED70037B5006EC18E0A -+:1053F000C0326100B0580300106303BFDE02F01238 -+:105400006100B058130017A10068DA3700127E005F -+:10541000B05E8700168D006DDE86D1B28000B05E72 -+:105420008700168D0002DE02F0000001BC60030060 -+:1054300017A1018760040310A001BC60030990B5A7 -+:1054400000B0006300F0B401BC60570490B601BC2A -+:1054500060030090B500B0006300B0B400B042D368 -+:105460000018000317DE02F012890397DE02F01223 -+:105470008A00B02A4B00142F018EE00C0310A0000C -+:105480006DDE02D1B29000E85A36F0168D03BFDE11 -+:1054900002F0129201BC600300168C01BC60030094 -+:1054A000168D006E5A3AF0129501BC600300168EFC -+:1054B00003BFDE02F0129600E85A3AF0168E00B0F2 -+:1054C00058070017A100E0580EF01603006ED80E22 -+:1054D000F4329C00E85E86C017A100E8580EF4364E -+:1054E0000300E8580F00360301185E030017A100FF -+:1054F0006DDE030212A400E86042F437A200905A65 -+:105500001AF4368600885A1EF457A200905A1EF4E8 -+:10551000368700B05A1AF4568603BFDE02F012A690 -+:1055200000905A1EF4368601BC6003001687000204 -+:10553000DE02F000000158600300102A01B8600A82 -+:1055400004902401BC60030290040189E0020D90E4 -+:105550006C0002DE02F000000200DE530012D101F6 -+:10556000BC601309B7A100025E02F000A201A560B1 -+:10557000020337A20199E002F457A200025E02F092 -+:1055800000A801BC60130997A100025E02F000A20E -+:1055900001A4607E0337A20199E03EF457A2000205 -+:1055A0005E02F000A801BC601316F7A100025E02C3 -+:1055B000F000A201B460020337A200025E02F00014 -+:1055C000A801BC60131637A100025E02F000A20120 -+:1055D00086E0020337A201856002F457A200025E52 -+:1055E00002F000A801BC60131617A100025E02F0D1 -+:1055F00000A20181E0060337A20185E006F457A26C -+:1056000001836006F457A200025E02F000A801BC0C -+:1056100060131F57A100025E02F000A20181E002A8 -+:105620000337A2028600C70012CB0181E0060337D0 -+:10563000A200025E02F000A801BC60131F37A100A7 -+:10564000025E02F000A20181E0060337A200025EC2 -+:1056500002F000A80002DE02F0000001BC601309A5 -+:1056600097A100025E02F000A201A460020337A22B -+:105670000199E002F457A201886002F457A20002E7 -+:105680005E02F000A801BC60131617A100025E02C2 -+:10569000F000A20181E0020337A20185E002F45785 -+:1056A000A201836002F457A200025E02F000A80289 -+:1056B0000600C70012E201BC60131F37A100025EA2 -+:1056C00002F000A20181E0020337A200025E02F0B4 -+:1056D00000A80002DE02F000000200DE530012D13A -+:1056E00001BC601309B7A100025E02F000A20187AD -+:1056F00060020337A20181E002F457A2018860062C -+:10570000F457A200025E02F000A801BC60130997E2 -+:10571000A100025E02F000A2020400C70012EF0125 -+:1057200088600E0337A203BFDE02F012F10186602B -+:10573000060337A20181E006F457A200025E02F0E0 -+:1057400000A803BFDE02F012C60068DE930012F765 -+:1057500000E05E030057A201095E8B0017A103BFA2 -+:10576000DE02F012FF0068DE930032FB01105E03E0 -+:105770000017A200E05E8B0097A103BFDE02F012CB -+:10578000FF01305E030017A200E05E8B0197A100CD -+:105790006D5E870592FF01BC60030597A10002DEE4 -+:1057A00002F000000200456F00130B02872C0F006F -+:1057B000130B01BC60130217A100025E02F000A2ED -+:1057C0000200C06700130B0287AC0F00130801082A -+:1057D0004067000B030187E005606B0301886006EA -+:1057E0000337A200025E02F000A801876005606B2B -+:1057F000030002DE02F0000000682BEB0013110032 -+:10580000B02C130017A100E05E8560B7A1006BDE2D -+:10581000862333110186E006F7F7BF0002DE02F0AF -+:10582000000000B05E8F00106400B05E870017A318 -+:1058300000B05E8B00106500B05A030017A100682D -+:10584000419300131A00025E02F000A200B040670C -+:1058500000160100E0419300506400B05A070017A1 -+:10586000A200025E02F000A800E04197005065002F -+:10587000E85E8F0037A30068DE8F0013150002DE9C -+:1058800002F0000000B05E8F00106400B05E870080 -+:1058900017A300B05E8B00106500B05A030017809C -+:1058A0000068419300132800025E02F00E3F00B032 -+:1058B0005E0700160100E0419300506400B05A07F3 -+:1058C00000178100025E02F00E4400E04197005094 -+:1058D0006500E85E8F0037A30068DE8F00132300A9 -+:1058E00002DE02F00000020200BF0001880203C5D0 -+:1058F000730001B1000000000000000057860000A6 -+:10590000A5C1E142055AC359DC0175513E5B2349EB -+:105910004728676945005E55F8F5C97D420AB30915 -+:1059200001BD32080100343333363261322D726FDB -+:105930006D6C2F7364696F2D672D706E6F2D706B9A -+:105940007466696C7465722D6B656570616C6976DF -+:10595000652D776170692D776D652D7032702056D9 -+:10596000657273696F6E3A20352E39302E313935B4 -+:105970002E3839204352433A20626431653365350D -+:105980006120446174653A204D6F6E2032303133AE -+:105990002D30342D32322031373A32343A343420FB -+:0559A0004353547D009B -+:00000001FF -diff --git a/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex b/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex -new file mode 100644 -index 0000000..df14f32 ---- /dev/null -+++ b/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex -@@ -0,0 +1,12890 @@ -+:100000000000000019A40000DDA20000DDA2000035 -+:10001000DDA20000DDA20000DDA20000DDA20000E4 -+:10002000DDA20000DDA20000DDA20000DDA20000D4 -+:10003000DDA20000DDA20000DDA20000DDA20000C4 -+:10004000DDA20000DDA20000DDA20000DDA20000B4 -+:10005000DDA20000DDA20000DDA20000DDA20000A4 -+:10006000DDA20000DDA20000DDA20000DDA2000094 -+:10007000DDA20000DDA20000DDA20000DDA2000084 -+:100080000048004719A40000000000000000000024 -+:100090000000000000000000000000000000000060 -+:1000A0000000000000000000000000000000000050 -+:1000B0000000000000000000000000000000000040 -+:1000C0000000000000000000000000000000000030 -+:1000D0000000000000000000000000000000000020 -+:1000E0000000000000000000000000000000000010 -+:1000F0000000000000000000000000000000000000 -+:10010000D11E8000B5228000BD248000491F8000E0 -+:10011000F9218000BDF00000F1208000D120800096 -+:10012000594880006948800015648000E1628000C1 -+:10013000296280003D6580008D628000C56280007C -+:10014000596380005D6580007D6380009D63800051 -+:100150000D668000A961800061618000756080008B -+:1001600095608000DD6380009D65800029668000C9 -+:10017000FD618000B96580001D618000F16580002F -+:100180009D6680006D658000916C8000CD6B800065 -+:10019000316C80008D6B8000556C8000AD6A8000F2 -+:1001A000C16A8000D56A8000496B80001D6A8000AA -+:1001B000FD6A8000AD688000C1698000D168800060 -+:1001C000356B8000B1698000D5A80000D166800041 -+:1001D000E16780008D678000CD6780009D688000AA -+:1001E000ED678000BD678000A1678000ED6680003C -+:1001F00009678000616780004D4880001D488000CD -+:1002000085988000DD96800051948000B19B80002D -+:100210003994800005988000199880002D988000FE -+:10022000C59B8000D19A8000899D8000D193800079 -+:10023000D9918000ED9A8000892800007DF10000AE -+:1002400059290000A5F10000519B80009D29000064 -+:1002500049A9800099988000D529000031A8800024 -+:1002600005A7800021A28000BD938000DD9380005F -+:10027000199E80007D93800045988000E59B80005A -+:100280006DA68000C19C8000C59F8000A19D80005C -+:10029000F598800069F10000DD2A000029AA80009D -+:1002A000B9A9800075AA8000E1A9800039AA800060 -+:1002B0008DAA80005DAA80000DAA8000C5A98000DB -+:1002C0009DA98000A90C8000850D8000C1068000DA -+:1002D00029088000694680004D468000D94480008E -+:1002E0004146800021448000F54380001544800091 -+:1002F000E1438000E1428000854680007544800033 -+:100300002D448000A9428000F9428000CD43800046 -+:10031000B9458000F544800039458000090080001F -+:100320003D00800049018000D10480000D04800060 -+:10033000910380004D038000E503800035038000B9 -+:100340006503800029028000CD02800051028000F8 -+:1003500085028000F5028000950680003906800045 -+:100360008105800005068000FD048000690F800083 -+:100370002516800015168000451380001513800097 -+:100380002513800009138000351380000D1E8000A6 -+:10039000F91D8000291D80001D1C8000391C800073 -+:1003A0003116800059138000F1F801009513800088 -+:1003B000B91C8000F11B8000211E8000751D80008B -+:1003C000E1EA00003D1D80000D1B8000E910800067 -+:1003D000790F8000A9168000311480002D11800053 -+:1003E000A51E8000B11E8000BD1E8000692B80000C -+:1003F000AD28800011298000892B8000FD2B800012 -+:10040000E128800065288000B52C8000912C8000B8 -+:100410001D2B8000752D8000252C80004D30800024 -+:10042000DD2D80005927800031318000D9F2000095 -+:100430008D268000C5268000E5248000FD268000F2 -+:1004400021258000B12A80006525800025288000B4 -+:100450006129800041298000D92980009D298000E0 -+:1004600081298000893080004D2E8000B12B8000D2 -+:10047000312C8000E12C8000613280002D32800020 -+:10048000C93380004D368000693A8000B535800060 -+:10049000F9348000A93480003D3380009D33800012 -+:1004A000013480003536800031388000353A8000D4 -+:1004B000213A8000AD3280000D338000DD328000B3 -+:1004C000953A8000D937800099368000193780002E -+:1004D000593880004938800019398000313D80004A -+:1004E000D53A8000C93C8000E13B8000513D80004E -+:1004F000D93D8000AD3E8000593F80009941800089 -+:1005000041478000CD5B8000895380002D4D8000E5 -+:10051000A94C8000E14D8000E94F8000B14F800080 -+:10052000C94E80008D4E8000F15180005D528000E8 -+:10053000D15180002D52800001528000C94F8000AF -+:10054000594C80006D4C8000455B8000395680001E -+:10055000155A8000C9588000315A800081578000A8 -+:10056000F95980001D568000AD55800091558000DE -+:100570004D5A80002D558000714B800071548000D1 -+:1005800009548000F54D80001D4C8000F94B80001F -+:10059000094C8000114E80001558800061EC00006D -+:1005A0002D508000E5588000555680007D5A80000F -+:1005B000054F8000354E8000D9558000515880008D -+:1005C0009D57800059518000614D8000B1488000E6 -+:1005D0005D5B800081528000494C800049EF000043 -+:1005E000F15B8000E55C8000E15F8000A55E80003B -+:1005F0007D5E80008D5C8000015C8000A15F8000DA -+:10060000895D800005608000395D8000D15E8000DA -+:10061000495E8000ED6C8000656D8000DD6D8000BE -+:100620000D6D8000296D8000896D8000F96C80005F -+:10063000D96C80003D6E8000616F8000756E800017 -+:10064000056E8000A974800055758000D574800007 -+:1006500005748000D17C8000457D8000757C800021 -+:10066000117E8000897E8000E97E8000917D80007F -+:100670003D7E8000517F8000A581800065848000E0 -+:10068000418480008D8380006583800035858000F3 -+:10069000E58480009D848000218580007584800031 -+:1006A000BD8380005D858000BD858000158F800042 -+:1006B000918D8000D58980001986800019AB80005B -+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E -+:1006D000FDB080007DB1800065B080006DAE80000F -+:1006E00085AE8000EDAD800041AF80001DAE800082 -+:1006F00031B180003DB18000B9AE8000F5B180001D -+:1007000079B08000FDAD800009B180008DB080001F -+:1007100049B1800069B180004DAE80003DAE8000DF -+:1007200095AE800029B38000C9AE8000CDAF8000B7 -+:10073000E5AF800025B080008DAF8000B5B28000AD -+:10074000FDB2800019B38000EDB080005DAE800086 -+:100750002DAE800029B28000A9B08000A1B1800038 -+:1007600005B2800039B28000A9AE80007DAF800064 -+:10077000ADB38000A9BD80009DC1800025C7800069 -+:10078000DDC8800065CA8000E1CB8000DDCE80003E -+:1007900019CE800099CE800015CF80000531000071 -+:1007A0000DD88000DDD7800091D78000FD2D00009E -+:1007B000B92E000069D880007DCF800045D9800027 -+:1007C000D12F000099D18000C5EB0000F9E0800036 -+:1007D00071F5800035310000D1DE8000C5F60000E3 -+:1007E00009EA8000A1E480007DF50000E1EC8000D2 -+:1007F00011E3800039EA800039E3800099E380004A -+:1008000029DF80003DF70000D9F50000ADF70000BA -+:100810006DF80000B5F80000BDEB8000B5310000B8 -+:100820003532000051F70000C9F7000005F700005D -+:10083000E1E18000A9E98000B5F6000031F6000092 -+:10084000EDF58000D90081009DF68000C5F780009D -+:1008500085FF800045018100D50281004D038100A4 -+:10086000E50081007DF6800081F78000D5F58000ED -+:1008700051F9800031FB8000F1F68000F9F580002D -+:1008800041FF8000D9F98000DDFC8000A9F78000DD -+:100890002DB6000059FB80008DF78000A5F980007F -+:1008A0008DF9800029F68000A1F880005DF78000B6 -+:1008B00065F6800095FD8000A1B70000F50281007B -+:1008C0002D028100890181000501810091B800009D -+:1008D00099FF800019F7800089F68000C1F680003A -+:1008E00009B7000085F5800005F78000DDF680007F -+:1008F000B1F68000AD6A8100BD6A8100DD2F810004 -+:10090000E1578100F56D8200A98D820009258200E2 -+:10091000196E820001AA81005D608200A537820005 -+:10092000ED69810079598200E55882001D598200E5 -+:10093000FD6D8100493A810041BC8200E95A820084 -+:10094000CD608100D59681001D6181002961810003 -+:1009500089BF81001DAB8100A93282000D330000E8 -+:100960002569810005A6810021AD820029588100FA -+:10097000BD3E8100A540810035958100599B8100D5 -+:100980003D3682001D4582000928810099A0810022 -+:10099000D1288100E93B81008D288100416E8200D1 -+:1009A000859B8100295D81006D398200FD398200BF -+:1009B000253A820095698100C97A810091578100AA -+:1009C0005D57810075308200852F82003557810088 -+:1009D000D12F82002157810049578100F5288100DD -+:1009E00095A8820009EC000089D38100D56B8100B5 -+:1009F0005959810075598100F55A820005AD810071 -+:100A0000F1D2810039378100ED718100C5968100F6 -+:100A10008957820091618200CD618200A9588100CE -+:100A20001D2782004543820001448200156A81002F -+:100A3000614A8100ED4E810071228200055A8100D9 -+:100A40004D8A81007549810071248200B14981007D -+:100A5000B144810075AC8200292B8200595281007B -+:100A6000E12A8200B529820071A7810035A78100A3 -+:100A700001D48100F5BE810055B48100D16A8200A5 -+:100A8000D19C81009D9C8100959B8100B59D81003A -+:100A9000459D8100C59D81006170820009358100FE -+:100AA000A1AB82008DAB820075AB8200F193810017 -+:100AB0009968810015D7810071C182007D2B81006A -+:100AC000E92F81000DB6810025BD82008D4F810088 -+:100AD0000D5081008543820031D78100B1BD820075 -+:100AE00095C182005DB38200DD3400008DD18100AC -+:100AF000A9368100E9BC820029378100E9368100EE -+:100B0000A1D68100A53B81006DAB810041B0810081 -+:100B100045AE8100C9F1000041BD820095BE820052 -+:100B2000CD2E82009D6B8100CD458200453981002C -+:100B3000353B8100BD3A8100F1D58100419F8100A4 -+:100B4000119F810071A48200ADD58100C130810068 -+:100B5000A13982004D618100995B8100A5728100FD -+:100B600089DA810061BF81006157820081218200A2 -+:100B7000A9218200D1AD820009BC8200B5A181000B -+:100B80009DCA8100B92F8200D9BB8200113082003A -+:100B90007DAD8200CDA4810099A48100CDAB8200FF -+:100BA00015AB8200C1AA8200B998810081A581009D -+:100BB000D9D08100A9CF8100E93B8200EDCF81002F -+:100BC00065D1810079D1810051D0810065D081004B -+:100BD000E521820011228200D1350000FD4900008C -+:100BE000FD9C81009145820055AE820041B4810098 -+:100BF00095BD8100F18A8200098B820079D981003C -+:100C00007D618200CDA4820041918100A13F8200DC -+:100C10003594820049948200898982005DC18200F6 -+:100C2000F1C18200D13B8200D5958200E560810050 -+:100C30000920820015F20000BD3B820075A18200F0 -+:100C400025A58200253B8200E93A8200753A8200A0 -+:100C5000F1308200B130820071D781004599820065 -+:100C600091D7810089948200DDC18200A96A820047 -+:100C7000256B8200C944810029458100596B8100A0 -+:100C800059498100EDAA810069618200AD2482008A -+:100C900005368100D535810079D08100A5D081004D -+:100CA000715C8100E1AD8100EDD0810049C9810016 -+:100CB0004DD88100893D82004920820065968200DE -+:100CC000F925820089CF8100856A82001593820010 -+:100CD0002D5D8200E9CA81006D4082006130820092 -+:100CE00015488200313C810061D68100114E81009F -+:100CF0000129810041A1810015A681000999820086 -+:100D0000E5C98100B1D7810035C08200294A810040 -+:100D100041AD8100EDBE82002DBE820005BE820085 -+:100D200079BE820055328100A5958100B1598100BC -+:100D3000E54781009152810015638100956481002F -+:100D40008D668100592C8100392C8100212E810073 -+:100D500065358200D5578200352B8200996082006C -+:100D6000016182001D4082001D2082001DD881008B -+:100D7000A9AC8200F1AB8200F52B820041AE82006B -+:100D8000A9EC0000356A810009AE8200696D82001D -+:100D9000098C8100D58B8100116F810081908100C9 -+:100DA000296C8200DDA18100E92B8100552F820092 -+:100DB000398C8100A55A8200355C820045BB8200D7 -+:100DC00091BE81002D6E8100115C8200258A810018 -+:100DD0004D93810089388200D5378200555A8100B1 -+:100DE000013882008D038100E9208200E13E82000B -+:100DF000914581002D6D81000D58820021478200B0 -+:100E0000FDCE810011CA81005936820051CB81008C -+:100E100025CB8100912E81002D2F8100B93A8200CF -+:100E2000CDE80000DDA9810031D48100D1B382007A -+:100E3000ADA98100D53882008DD88100555E820031 -+:100E4000719A81001541820035DA810019258200EE -+:100E50006926820035358100E93600003D71810048 -+:100E6000012D810009A282000D238200FD71810005 -+:100E7000D960820051728100416182004528810061 -+:100E8000C12382008D6C81006D2382009547810013 -+:100E9000B9D98100B534810075C98100F134810070 -+:100EA0002DBF810059AF8200D93C8100494F81009C -+:100EB000E5AB810009F000007931810005958200E1 -+:100EC0006D638200DD938200A56682000DC88100FB -+:100ED000095E81007D758100156281009159810054 -+:100EE000D575810011498100C1488100B9BF8100D9 -+:100EF000A5458200F5598200F1A9820041A6820031 -+:100F000039588200BD428200BDA782004D22820076 -+:100F100071A78200A5A78200E15C8100ED418200FB -+:100F2000D1A78200D1688100B5CC810015AF8200C5 -+:100F300095418100E1C8810089AA8100E99681007C -+:100F40007D2F8100C548000049428200594482003B -+:100F5000D1E80000313182006149820051F2000085 -+:100F60000DA58100095E8200253E8200CDCD810065 -+:100F700029B382002151810045B18200A91D820060 -+:100F800079BC8200D1568100599D8100999D8100D4 -+:100F9000191C8200513F82001D308100C9BD8100B3 -+:100FA00015388100794A8100DD9B8100199E8100FE -+:100FB00069618100896E8100B5708100D132820043 -+:100FC000F1578100A93382009D5A81003D3582008E -+:100FD00089338200D96E810045708100FD618100F6 -+:100FE000594B81000D9C8100558B8200F18E82004F -+:100FF000E59A8100BD35820049368100291F8200B3 -+:10100000655C82001DEF0000516F8100299B81000B -+:10101000A56D8100B5A28200E1AF8200A9568200D1 -+:10102000894481003D578200E16F8200016F820098 -+:10103000DD728200E53E810095518100FDD4810082 -+:10104000F5BC810081B48100F199810019318100E2 -+:10105000358A8200DDDA8100413D81002D3E81002C -+:10106000E9898200C1D48100FD8D820099B681009A -+:10107000BDA781003D9F82005D0381006D928200CB -+:10108000218B8200599A8100ED278100ED94820026 -+:10109000FD8A81009D8A8100416B8100E16F8100A2 -+:1010A0005D468200A19482009D898200C9928200DF -+:1010B00079998100B1908200219182001D348100D4 -+:1010C00099B28200DD6A82008DC9810059278200B1 -+:1010D000B9EC0000D9908100A56B82006D3C8200C4 -+:1010E000E56D820005C28200C96A8100ED4582007B -+:1010F000816B8100353F8200FD90820071BC8100D0 -+:10110000F16B81003D4E8200514A82003DA2810078 -+:10111000F1E8000079738200B97E8200698882005C -+:10112000695A8200DD2E810015138200117381003F -+:10113000698082009D9181005D8B8100816C8200BD -+:101140008D8F81004D8F810009888100BD6D8200E7 -+:10115000018E81001D5E820091718100C127810096 -+:10116000797582002DBE81002D5B8200E9A5820089 -+:10117000B5728200FD5C0000217D82004D808200FE -+:101180008D7F820001A08100ED7F82002D418100D2 -+:10119000F98481006185820045728200F9548100E2 -+:1011A000692B820069518100C5558100315681004B -+:1011B000A1A6810071508100392A8200615381000B -+:1011C000C5738100F5630000F1978100A99B810040 -+:1011D000FD3B820025A08200DD398100715D810028 -+:1011E000D1EE00004995810009CC810021A3820045 -+:1011F00045AA8100AD818200916782002962820048 -+:101200007D708200E12F8200E903810081DB810093 -+:10121000952482006989820089C38200C5C4820046 -+:10122000F1F20000B1EB820009CB82000DCC82000C -+:1012300059EB820061E9820015F18200E9CD82005C -+:1012400045DF820009F182008DF782008DCA82009D -+:1012500089F38200D5CA8200A1098300C9F7820000 -+:10126000FDEF820099F8820025F9820039FA8200A8 -+:1012700089ED820069810000ADE5820065DA8200B7 -+:101280007DC582002DE6820065EE820031E4820099 -+:10129000E5F182009DC8820055F3820089EF0000CD -+:1012A00061C78200CDE182006DE18200A5E282008B -+:1012B00059DF820029F4820009C7820055EF8200BD -+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D -+:1012D0004DE5820005E08200A5F982000DC582007F -+:1012E00039820000D18400008D85000091E68200E3 -+:1012F000BDCC8200FDE982008DD182002DF18200FB -+:101300002DF7820095FB820069CE8200A1F0820059 -+:10131000D5F08200F5CC820059CB820081D98200C1 -+:1013200045C58200FDCB820025CB8200BDEB82004B -+:101330001DDB820015CD820071860000CDE68200A3 -+:101340004DCF82009DCB8200450C8300E50D8300CC -+:10135000590E8300410E8300010B83004D0A830068 -+:10136000D10D8300310C8300590C8300710A830076 -+:10137000650E8300F10D8300410B8300A11E8300E5 -+:10138000B11E8300012B8300F54E8300112B8300D7 -+:10139000B127830099238300014A8300ED4983002C -+:1013A000FD478300CD4C8300BD4C8300714C83000E -+:1013B000D52783004D25830095258300E14C8300CC -+:1013C000414C8300A1EC000065118300E1448300DF -+:1013D00021288300BD2883007929830065288300A4 -+:1013E000652B830041458300D5298300491D830077 -+:1013F000A12A83005D30830051488300E5488300C3 -+:1014000029488300F5238300114A8300793483003F -+:1014100091188300A5338300ED3483001D118300F0 -+:101420009D4E8300954D8300B51A8300614783006C -+:101430001D4D8300ED1083000D458300C11E830008 -+:1014400001208300E9218300F1258300F91D830039 -+:1014500061EE0000B52B830049108300C10F8300AB -+:1014600021248300A5248300B94A8300B52F83007B -+:10147000C1458300FD1C8300711D8300F5188300A6 -+:1014800059198300F1198300F9E90000492A830002 -+:1014900085890000B957830029578300654F830071 -+:1014A00001608300E559830039518300F54F8300C3 -+:1014B000555483001D5E83002152830065598300CB -+:1014C00079508300714F8300095983003D63830085 -+:1014D000C5578300815C8300B15B8300DD538300CB -+:1014E000115383009D4F830029508300254F8300B3 -+:1014F000D5588300CD62830039608300F95C830096 -+:1015000069F200005D5F83002D548300DD5083008D -+:1015100039578300A555830091638300A16283003E -+:10152000C15D83002D5E8300455F8300A151830070 -+:10153000D58F0000195B83006D5A8300A956830084 -+:10154000A5508300095783000D748300DD63830079 -+:10155000297A830001668300B9B28300D5A783008E -+:101560007D848300819383005DB38300A193830016 -+:10157000E9938300C1E90000BD90000035910000AF -+:10158000717A83005D67830051668300CD708300AC -+:1015900055718300DD7483008DAA830051A88300F8 -+:1015A000A9B183009D918300D18483008992830037 -+:1015B00061848300AD77830081818300158283007D -+:1015C000B1808300E5B583006D7E8300B57983002B -+:1015D00091910000916E8300758F83005587830081 -+:1015E000A1ED00001996830025678300C188830060 -+:1015F000D98F8300F5AC8300E97783009D6D83006C -+:10160000A1A78300FD998300C9A48300619600000F -+:10161000558B8300E58A8300CD6A8300F5868300BD -+:10162000596A8300B9AA83001566830051B283000A -+:101630009DB38300D9B6830059B1830091828300A2 -+:10164000D5B0830081868300C97A83000585830035 -+:10165000797C83008965830055A58300C9AF830029 -+:10166000A1EF00007999830091898300C5B58300BB -+:101670000DB8830099D483002DC083009DC28300E0 -+:10168000ADC38300A1C68300B1C68300C5C2830079 -+:10169000A9D0830055BF8300F9CF830029BF830001 -+:1016A000C5E18300C1C0830095C083004DD883008D -+:1016B0000DD7830015D88300F1D7830079BD83004F -+:1016C000A1E1830035C28300C5E08300DDE0830033 -+:1016D000C5DC830099DA830001DA83004DB883000A -+:1016E00075C0830019C28300F9C983003DD6830009 -+:1016F00015BE8300C9D683005DBA830029D6830056 -+:1017000031B9830035BC83009DD883005DDC830044 -+:1017100029C18300A9C28300E5C0830025DB8300C3 -+:1017200075C283001DD083005DBC830061C6830049 -+:10173000D5C2830005BC830001C98300B5C88300FE -+:10174000EDC8830055D6830015D98300A5D1830049 -+:10175000F1D5830001D9830081B8830089E083003B -+:10176000E1BC8300A5DB8300EDE1830071C1830050 -+:10177000E9B783006DC783008DC183001DC8830056 -+:10178000B5D1830071DC8300E1C18300A9C183006E -+:1017900019DC830039D883004DCB8300A5B78300C3 -+:1017A00069CB83008DC98300C9D48300B59700003D -+:1017B00099D68300E5DC83004DD483001DC38300EC -+:1017C00021DD830045D983007DD383003DD2830092 -+:1017D00041DA8300CDD88300D9BF830095BD830053 -+:1017E000EDBD830051C083002DB8830049BB830049 -+:1017F00031BB8300CDDA8300D5D0830049CA830092 -+:101800009DD5830081BF8300D5CF83003DC9830070 -+:10181000DDD18300B9D7830025C78300BDC3830012 -+:101820005DBE830021E18300F9E0830071B983008C -+:101830008DE1830025D9830049D78300DDDB830058 -+:10184000A9B9830085BA83001DF1000059EB83001C -+:10185000C5E7830041E2830025E283006DF5830044 -+:1018600065EB830085F2830089F78300B1F2830082 -+:10187000A9F58300AD008400E100840019FD830018 -+:1018800035EE8300FDF383003DEC830089FB83008C -+:10189000B9FA830021F98300F1FA8300D9F88300B3 -+:1018A000D9F9830031008400C5FE830049E7830035 -+:1018B000050084004DFF83006DF3830059FE830013 -+:1018C00001FE830025EB83000DEB830031018400D2 -+:1018D00035FD830081EB830059FD830011F88300FF -+:1018E000FDF78300C5ED8300ADED8300A101840009 -+:1018F000E9E78300B1F38300DDF2830025F3830081 -+:10190000F9E68300E5E2830071ED0000A5E98300BC -+:101910008DF5830051EE830079F8830071E2830036 -+:10192000F1E8830045E6830099F783006DEE8300BC -+:1019300041F48300B9EB830075E78300B1E88300CD -+:10194000DDA0000061F1830035F2000089EE830024 -+:10195000E9A10000FDE58300A9FD830085ED0000FD -+:10196000B5FB8300F1F183002D108400E1158400A4 -+:10197000B1198400C5158400D90F8400CD218400DD -+:10198000491E84004D1F8400E1128400ED0884008C -+:10199000F10184002D0F8400ED238400F51E8400E6 -+:1019A000E520840049208400AD128400F11A8400EF -+:1019B000711F8400C9198400AD188400450B840090 -+:1019C000910B84000D2484008D2384000D18840065 -+:1019D000210684008D168400310384006909840087 -+:1019E000FD158400E902840001028400A909840035 -+:1019F0008D148400811E8400E10B8400751C84001A -+:101A0000AD0A840049108400712084000121840003 -+:101A1000850A8400291D840045078400390C840050 -+:101A200029198400551E840089038400E51D840063 -+:101A30002125840049138400291A840055ED0000F3 -+:101A4000ED12840045068400010D84008943840062 -+:101A50006D2A8400014D84001528840069288400C3 -+:101A600021D7000009408400112C8400F92784004C -+:101A7000912D8400794C84008934840019338400CA -+:101A80006D2F8400C92D8400F12E84007D2E8400EA -+:101A900065258400DD348400FD2584001929840037 -+:101AA000B5408400D944840079298400B92B84008E -+:101AB0003D45840095328400B9288400D1388400E3 -+:101AC00031488400A93084006D2C8400994384003F -+:101AD000D13284006D338400FD2F84005D45840085 -+:101AE00011348400B54A840075488400C5488400D8 -+:101AF000B1278400314A8400D949840059328400D6 -+:101B0000014C840039388400314D840055448400F0 -+:101B1000D93D840055438400513C840091398400B0 -+:101B20009536840091378400F5368400E1478400BF -+:101B300015478400CD4C8400F52B84002546840095 -+:101B4000E53A8400C937840049428400292A840088 -+:101B5000A53F840059268400952A8400452B8400E3 -+:101B6000C95D8400A95B8400A15684009556840059 -+:101B700019578400E956840005578400355F8400B6 -+:101B80001D628400B557840065638400ED628400A3 -+:101B900021638400BD628400194E8400B95384001F -+:101BA000B15D8400B5518400D55F8400F95584008F -+:101BB0006560840059538400E5538400E94D840036 -+:101BC000DD518400E15F84008D5384007D5B8400DF -+:101BD000B55B840031568400A5638400CD60840029 -+:101BE00091638400ED5084002D5E840031518400A7 -+:101BF000155C840061548400F55E8400F15D84000E -+:101C0000315A84007152840059588400815C8400E8 -+:101C1000715784002557840071588400AD568400A4 -+:101C2000415984006D4F840029508400E1548400A0 -+:101C3000BD6184006D61840005598400A56684003F -+:101C4000D9678400456684000D658400916784002F -+:101C5000B96384005D67840079678400F966840055 -+:101C60002165840021678400C56684008D66840038 -+:101C70006566840011688400516C8400AD6E840038 -+:101C8000016E8400F97084004D7F84007D6C8400B7 -+:101C90002D748400456A84000D7B840099EC00005B -+:101CA000156E8400457A8400E56C8400456F8400DD -+:101CB000C17C8400297E8400756D8400956B84004E -+:101CC000B56D84007D7D84005D6B8400D56A8400E1 -+:101CD000816A840085748400B1808400857E8400DC -+:101CE000CD7F84004981840069818400ED8984006E -+:101CF0006D8A8400FD8984008D8984009D8984001B -+:101D0000E9858400F982840025858400518A840055 -+:101D100075858400958484008181840071838400AA -+:101D2000C18984005D898400D58984006D8984001F -+:101D30007D8984000D8A840009868400798C840062 -+:101D40007D8A84000D8B8400499484008D928400E8 -+:101D5000E98D84009D8B8400FD8C84007990840043 -+:101D60000D8C8400458C8400E9A68400A5AD840018 -+:101D700029968400C598840015C1840009A98400AF -+:101D800099C2840045B7840031C18400D1B8840071 -+:101D90008D998400B99A840025AC8400D9BF840051 -+:101DA000C9BE8400A196840025B18400519B8400A3 -+:101DB000919884004D9784001D9784007DA684002F -+:101DC000D1B784002DAB84008595840019B08400C0 -+:101DD000F5AD840029A98400C1A98400219F840055 -+:101DE00025A28400B1AE8400C1AF8400D5A38400D5 -+:101DF00075B7840041A28400E1BC84006DA8840012 -+:101E0000BD9D840095B884005D95840075BE8400F6 -+:101E100051B98400A9958400C5C18400599A8400F1 -+:101E2000419684003DB884009DA88400E5A8840004 -+:101E3000A59B8400F5A684003DAF8400159A84001C -+:101E4000F9988400EDA984006DB18400FDF0840050 -+:101E500025DF840025ED8400E5D08400CDF18400E9 -+:101E600009F2840035F2840055F28400CDF284003A -+:101E7000B1D38400F5D384002DD48400C1D4840070 -+:101E8000A5048500F90585006D0585009904850088 -+:101E90008D04850079D4840045E88400B1C58400B0 -+:101EA00095DF840031DF840075E484001DE0840048 -+:101EB000BDC9840005ED8400A500850091FB840068 -+:101EC000F9ED840091EF84009DFB840081EA840099 -+:101ED00079E2840059C6840061EB8400A1EB8400A0 -+:101EE000D1E484009D028500A1F3840015CC840018 -+:101EF0005DFB840081C5840015D5840099D68400DB -+:101F000035E78400B9DF840045F48400B9C7840054 -+:101F100001DF84002D018500E1C7840025D1840004 -+:101F20006DFA8400BDDD84004DF38400E1C98400B6 -+:101F300041E084002DCA84009DD4840005EB840018 -+:101F4000D900850079CB840021FC8400B9E88400A5 -+:101F5000B5D8840031FD8400BDFB84001D048500DC -+:101F60005D048500B9E90000450685005DEC84004C -+:101F700025C384001DF38400D9C684002DEC8400A1 -+:101F8000F1C5840059E9840019C88400B1EF8400C8 -+:101F9000B100850049D3840001C98400E1D28400E6 -+:101FA0008DCB8400DDEB840011F4840009FC8400F7 -+:101FB000D9F3840069C38400A1C884002DEE840095 -+:101FC00071D6840079018500D9EC000025D8840001 -+:101FD000DDF9840009F0840035F7840029F98400D4 -+:101FE000D9FC840015D78400DDD584001DDE840073 -+:101FF000D9F5840019F1840099F1840049F1840035 -+:10200000F1F48400A1F48400F1D084003DCC84007C -+:1020100069D2840089E9840071CD8400C9D3840029 -+:102020008506850089078500E90685004D0785003E -+:102030001107850025078500710685009506850036 -+:10204000BD06850075078500B10785009D078500E1 -+:10205000A9068500D1068500FD06850039078500A3 -+:10206000610785005D0685001509850079098500F1 -+:10207000350A8500BD0985000D0A850019A20000FA -+:10208000E9EC00004D0A8500A909850025098500B5 -+:10209000DD0A85006D0A850081088500C507850079 -+:1020A0000D0B8500590F8500ED118500C9128500C3 -+:1020B00021108500F90D8500D5118500511085008E -+:1020C000AD118500011185006D10850065A401002A -+:1020D000850F850085108500990D850011128500FA -+:1020E0000D22850041178500D917850075208500D0 -+:1020F0007D2C8500352F8500B92285002D25850092 -+:102100009D238500612F8500A5278500C92A8500AC -+:102110006D2985009D22850031228500A52485003A -+:10212000E1238500B12F8500BD2C85005914850061 -+:10213000C9138500A11C8500452C8500A9178500C1 -+:10214000B1208500311A8500FD178500291D850005 -+:1021500021148500AD218500B5308500453185000D -+:1021600035278500D1318500C5148500BD2D85003A -+:102170002D23850059238500891485004D4685004F -+:102180006547850025368500514785003D46850019 -+:102190008D3C8500514A8500994A85007547850028 -+:1021A0001D478500553685005D468500D53B850079 -+:1021B00049498500D53A8500E139850041398500D6 -+:1021C000E53885000937850045358500C93C85001F -+:1021D000754B8500B9458500ED4885002146850091 -+:1021E000213A8500A940850001328500F53285003D -+:1021F000FD378500894E8500DD508500ED50850056 -+:102200005D57850009558500495085005D50850062 -+:10221000D1528500F5528500E54E8500C9558500EF -+:1022200065568500C9508500094F850025A5010028 -+:102230009D5585000D538500A94C8500B957850033 -+:10224000A55785000D518500FD5A8500D5518500A3 -+:10225000A9518500B15285009D53850039558500EF -+:102260009D4E8500C95785006D578500954C8500AA -+:10227000095785008D4F850091A50100FD59850006 -+:10228000014D8500ED598500D9598500194C85000F -+:10229000756C8500816E8500516C8500295C850018 -+:1022A000416E8500795E850059EA0000AD6E8500BB -+:1022B000B56C85006D6585001D5F8500196B850017 -+:1022C0008579850071738500B58E8500E19585005F -+:1022D00001828500519085002D828500D190850076 -+:1022E000FD908500BD9285006D8F8500CD928500A3 -+:1022F00055968500C58E8500857285005D8D8500AB -+:1023000001838500C1918500257085000D918500B0 -+:10231000C17685006971850041718500F97F85006E -+:1023200079708500F19385009D958500F574850091 -+:10233000497485006D788500BD728500ED8A850041 -+:10234000C98C850099918500597D8500BD718500F6 -+:10235000758185000D818500A9798500217785002B -+:102360002193850089928500D194850095968500FA -+:1023700065838500D973850065828500D5A5010038 -+:102380005975850021768500556F85006D9585000E -+:10239000E583850029848500AD8F8500F16E850079 -+:1023A0006D0101004DFB0000F90001007109010001 -+:1023B000C5000100EDFD000069FE0000750401008C -+:1023C0002DFE0000FDFD0000F5FD00002D0F0100B9 -+:1023D000390101000D0A01006DFB000045030100F9 -+:1023E000CD04010095FD0000A9FB0000851201004D -+:1023F000A5FB000085130100B5150100AD0001002B -+:10240000ADFD00001D0101006D0501005D09010029 -+:10241000BD0001009DFB000095FB000031030100A1 -+:1024200001070100F506010029030100250601004E -+:10243000510301005D050100E5FF0000C9FE000039 -+:1024400095180100E9FF0000C9000100D10001005A -+:1024500059030100710D0100C50D010081FF00004D -+:10246000A50001005108010025A3000061A30000A0 -+:102470009DA30000E1A6000025AC0000B9F9010011 -+:102480008DAC000095AC000055AF000045B00000D9 -+:10249000ADB0000005B20000B9B60000F9B8000008 -+:1024A00031B9000055B9000061B90000B1B90000B0 -+:1024B0008DBB0000C9BC0000B932000055330000DC -+:1024C000613400009DE800006537000099E80000D5 -+:1024D000D5510000C16B0000E9750000757E000059 -+:1024E0002DC7000065C800008DD10000C5D50000D3 -+:1024F00009F10000B998000081E800007DE80000C3 -+:102500006DE8000075E800001DD700008DE80000B0 -+:1025100089E8000091E8000095E8000069E8000003 -+:1025200071E8000079E8000085E8000039D7000074 -+:102530003DD7000045D7000049D700004DD7000027 -+:1025400039E7000055E7000075E7000035E70000B7 -+:1025500031E7000071E7000051E700004DE700009F -+:1025600049E7000045E7000041E700003DE70000C3 -+:10257000C5E70000D1E7000001E8000021E8000005 -+:1025800025E8000039E8000035E8000031E80000E7 -+:102590002DE8000029E80000C5E80000BDE80000C3 -+:1025A000B5E80000C9E80000B1E80000A5E80000B7 -+:1025B000B9E80000A1E80000A9E80000C1E80000B7 -+:1025C0003DE8000001000000200000001F000000A6 -+:1025D00050000000020000000100000001000000A7 -+:1025E000010000000000000015A701000A07080014 -+:1025F0002157020051FB800055B900002DB60000A4 -+:1026000000000000D1F980000000000029FB8000DC -+:1026100000000000000000009C1800409600FFFF32 -+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA -+:10263000FFFFAAAA0300409600000000000000006F -+:10264000000000000000000000000000000000008A -+:10265000000000000000000000000000000000007A -+:10266000000000000000000000000000000000006A -+:10267000000000000000000000000000000000005A -+:10268000000000000000000000000000000000004A -+:10269000000000000000000000000000000000003A -+:1026A000000000000000000000000000000000002A -+:1026B000000000000000000000000000000000001A -+:1026C000000000000000000000000000000000000A -+:1026D00000000000000000000000000000000000FA -+:1026E00000000000000000000000000000000000EA -+:1026F00000000000000000000000000000000000DA -+:1027000000000000000000000000000000000000C9 -+:1027100000000000000000000000000000000000B9 -+:1027200000000000000000000000000000000000A9 -+:102730000000000000000000000000000000000099 -+:102740000000000000000000000000000000000089 -+:102750000000000000000000000000000000000079 -+:102760000000000000000000000000000000000069 -+:102770000000000000000000000000000000000059 -+:102780000000000000000000000000000000000049 -+:102790000000000000000000000000000000000039 -+:1027A0000000000000000000000000000000000029 -+:1027B0000000000000000000000000000000000019 -+:1027C00000000000407C704713B500F001D90246BC -+:1027D00008B904460FE000240AE0104601A90022CF -+:1027E000FFF3B6F7019A13782C2B08BF013201349E -+:1027F0001378002BF1D120461CBDC046B0F8423002 -+:1028000070B50446C3B142F2197503E00A2003F023 -+:10281000A3DF0A3D236B1B6913F0704307D0B3F1AC -+:10282000005F04D0B3F1405F01D0092DEED1226BDF -+:10283000136823F01003136070BDC04670B50446E2 -+:10284000D0F8B40030B1037823B1FFF7BBFF0546E1 -+:1028500010B10BE0012509E0D4F8B400012100F02B -+:10286000DDD903E0606A002204F05ADA0121204633 -+:1028700002F0BCDA01460028F4D125B9D4F8B4003E -+:10288000294600F0CBD970BD70B590F87831054677 -+:10289000FF2B1FD0104C406AE36E9847D4F89C3051 -+:1028A000686A984701280BD895F8141241B90B466D -+:1028B00028460A4A03F07CDE012385F8143209E039 -+:1028C000054B686AD3F89C3095F805419847241861 -+:1028D00085F8064170BDC046E0A685003D988000A1 -+:1028E00070B590F818320446012B32D00123002530 -+:1028F00080F8183206E025B1A0682946012204F0CC -+:102900000FDA3546134B606A00219B6B98470646E9 -+:102910000028F0D1D5B1D4F80C323BB11B782BB1E3 -+:10292000A0682946012204F0FBD908E0D4F8F4108D -+:1029300019B1A068012204F0F3D9C4F8F450D4F816 -+:10294000F830AB4202D10023C4F8F830002384F8F9 -+:10295000183270BDE0A6850010B5084671B191F837 -+:102960000832012B0AD091F875313BB14B691A6AD4 -+:10297000034B02EA03030BB10CF000FC10BDC04690 -+:1029800000FC0101D0F8943110B59942044601D9F8 -+:10299000002002E00CF0F2FBE08D10BDD0F88011B9 -+:1029A00010B5044691B10223C068D4F8842108F020 -+:1029B00015DB074B1B684BB9D4F88011D4F8842180 -+:1029C000E06881EA0202023308F008DB10BDC0466D -+:1029D000A8F401002DE9F04190F817320446012BCC -+:1029E00077D00123002780F8173243E0A0683146F2 -+:1029F00000F092DBD4F8F0301B68984205D92846E5 -+:102A00000021324600F01EDB42E02046FFF73CFF8B -+:102A100035690023AB7194F8783131462B7294F804 -+:102A2000063184F80731DBB26B72D4F8FC31606A8E -+:102A30000133C4F8FC316A79274BD20982F00102D4 -+:102A40005B6A9847B0B9D4F8F8106B7900293CD08C -+:102A500013F00F0F39D06A782B7843EA02230F3333 -+:102A60001B091A0A0A6918BF0023937194F8783178 -+:102A700013722AE0D4F8F0301B68012B08D904F156 -+:102A800028052846002100F05FDA06460028ADD16F -+:102A9000002384F81732C4F8F8302FB16269043388 -+:102AA0005364204607F04CDFE28DD4F8C8319A42D7 -+:102AB00003D9206901F0D4DD0BE0D4F8CC319A427F -+:102AC00007D2206901F0BEDD03E00127C4F8F860F9 -+:102AD000D0E7BDE8F081C046E0A685002DE9F041D1 -+:102AE00090F816520023066A044603626DB18D4BBE -+:102AF0001B686BB3D0F88011D0F88421022381EADF -+:102B00000202C06808F06ADA22E090F87931FBB17D -+:102B1000D0F88011E1B1D0F884210223C06881EAA5 -+:102B2000020208F05BDA94F8153284F8795184F8DF -+:102B30007C5123B1204607F06BD984F8155294F8E4 -+:102B40007B312BB1D4F88C0103F0B8DB84F87B51D6 -+:102B500016F0804706D0204607F0AED820460CF08D -+:102B600003FB34E0002E2FDA63695B6813F0040581 -+:102B700018D094F8743133B92046394607F0BEDDD9 -+:102B8000204607F009D9206984F8747101F044DC0B -+:102B9000626920461368022143F00403136006F0C3 -+:102BA00077DE11E0012384F87431206901F044DDFF -+:102BB0002046294607F0A2DD204607F0EDD86269DD -+:102BC000136823F00403136094F874510DB10027C7 -+:102BD000A5E016F0010F07D02046012107F08EDD99 -+:102BE0002046012106F054DE16F0020F09D0012321 -+:102BF00084F87731D4F8FC301BB12046294606F022 -+:102C000047DE16F4807F04D0D4F864310133C4F871 -+:102C1000643116F4007F12D0D4F86831D4F8F4107F -+:102C20000133C4F8683131B1A068012204F078D8CA -+:102C30000023C4F8F4302046002107F05FDD16F0D1 -+:102C4000007F04D0D4F86C310133C4F86C3116F035 -+:102C5000806F04D0D4F870310133C4F87031324839 -+:102C600006EA000018B12046314606F03FDE16F0B5 -+:102C7000040F074623D0D4F8801101B30123626901 -+:102C800084F87931136A526A134013F0F00503D0C7 -+:102C9000204607F055DE12E0D4F884210223E068D4 -+:102CA00081EA020208F09AD994F87B3184F87C51C9 -+:102CB0002BB1D4F88C0103F001DB84F87B51E68D55 -+:102CC0006EB3D4F8A051012D02D0072D0CD023E013 -+:102CD00094F87A211ABBD4F89001D4F8981103F033 -+:102CE00089DA84F87A511AE094F87A3173B1D4F819 -+:102CF00094319E420AD2002104F1280000F05AD9F2 -+:102D000003695B7803F00F03032B08D1012E03D96D -+:102D1000204631460CF046FA2046FFF75BFE384667 -+:102D2000BDE8F081A8F4010000FC01012DE9F041AB -+:102D30000746884616461D4642F2197403E00A20EB -+:102D400003F00ADD0A3C79690B6D002B02DA092CCD -+:102D5000F5D11FE0AB191B0243F00042069BB3F113 -+:102D6000807F04D198F8003043F08073D21842F28B -+:102D700019740A6503E00A2003F0EEDC0A3C7B6963 -+:102D80001B6D002B02DA092CF5D103E0012088F835 -+:102D9000003000E00020BDE8F081C0460022C36B97 -+:102DA0000BB1013BC363531CDAB21030102AF6D1C9 -+:102DB0007047C0462DE9F041066805460F46706829 -+:102DC0004FF4BC7103F084DF08B9044612E000211F -+:102DD0004FF4BC720446FFF333F1D5F8603126603E -+:102DE000C4F8603195F86431C4F8687184F86431CE -+:102DF0006B6863602046BDE8F081C0462DE9F04174 -+:102E00009846036817461B680C6993F895308E8ABC -+:102E10003BB1CB8A13F0800F03D104F11E010120D6 -+:102E200020E00D2E3FDD04F10C014B78227B43EABC -+:102E30000223B3F5C06F01DB002013E0152E32DD55 -+:102E400004F10E051A4829460622FFF379F018B955 -+:102E500004F11401013005E0294606221548FFF36C -+:102E60006FF020E04A780B7842EA0322B2F5014F76 -+:102E700008D104318A1CA3199A4214D84A780B78D5 -+:102E800042EA032240F606039A420CD18A1CC4EBA4 -+:102E90000203C3EB06031C2B00DC04D13A6088F864 -+:102EA0000000002001E04FF0FF30BDE8F081C04697 -+:102EB00014D28500B0A6010003682DE9F74F012A5E -+:102EC00014BF2A25322506460F46586829469146E2 -+:102ED00003F056DF834640B9336801381B68D3F8E6 -+:102EE0008C20136D013313656CE007F10E0A046941 -+:102EF0005146042201A8FFF33FF0019B06F1280888 -+:102F000003F47F421B0643EA02234AF6FE12B2EBA9 -+:102F1000134F0BBF2C4907F108012046204606221B -+:102F2000FFF32AF00622A01D4146FFF325F004F12D -+:102F30000C02B9F1000F0DD02B0A237304F10E001F -+:102F4000557022490622FFF317F008232375062344 -+:102F5000637503E008232373062353706419A4F1F7 -+:102F60001C05394606222846FFF306F0002304F824 -+:102F7000163C023304F8153C4146062205F10800D0 -+:102F8000FEF3FAF707F11801042205F10E00FEF333 -+:102F9000F3F707F10801062205F11200FEF3ECF742 -+:102FA0005146042205F11800FEF3E6F7D6F85C312D -+:102FB00030680133C6F85C315946D6F8682125F0EF -+:102FC000F1D80120BDE8FE8F2C9E850014D285002B -+:102FD0002DE9F74F012B14BF2A25322599460368A6 -+:102FE00006460F465868A91C934603F0C9DE804682 -+:102FF00040B9336801381B68D3F88C20136D013356 -+:10300000136579E0036907F1180A9C1C838A51460D -+:10301000023B83820422046101A8FEF3ADF7019B09 -+:1030200003F47F421B0643EA02234AF6FE12B2EB88 -+:10303000134F0BBF314907F10801204620460622F5 -+:10304000FEF39AF70622A01D5946FEF395F704F108 -+:103050000C02B9F1000F0DD02B0A237304F10E00FE -+:10306000557027490622FEF387F7082323750623A8 -+:10307000637503E008232373062353706419A4F1D6 -+:103080001C05394606222846FEF376F7002304F88D -+:10309000163C023304F8153C5946062205F1080097 -+:1030A000FEF36AF75146042205F10E00FEF364F7C1 -+:1030B00007F10801062205F11200FEF35DF707F1A2 -+:1030C0000E0105F118000422FEF356F7D6F8483138 -+:1030D000D6F868110133C6F84831012386F8643107 -+:1030E0003368986801B189680123424608F058FBAB -+:1030F000002386F864310220BDE8FE8F2C9E8500F7 -+:1031000014D2850010B50368D3F800481B6893F803 -+:10311000AB306BB1FFF742FE08E0A16829B1012096 -+:1031200008F070FA08B1FFF739FE2468002CF4D1DA -+:10313000002010BD7047C046C3682DE9F041064627 -+:103140000D4658683821174603F0C2DD044610B911 -+:103150006FF01A002BE000213822FEF371F70123F3 -+:10316000294623606360A360062204F10C00FEF38D -+:1031700003F76B8E05F10901A3742B7A04F1140097 -+:10318000E3742A7AFEF3F8F66D8D3046A586E7865D -+:103190002146382221230BF003DC00B907E0F36855 -+:1031A00021465868382203F0A3DD4FF0FF30BDE818 -+:1031B000F081C04630B50C4690F8CF1091B09446DF -+:1031C0009E460380194D91B94FF0FF33029303934C -+:1031D000049305930D330094019106910791089192 -+:1031E00009910A950B900C930D910E9115E04FF0FB -+:1031F000FF33029303930493059300F1D0030693E6 -+:103200004BB2002207930C2300940192089209927A -+:103210000A950B900C930D920E927146044A6346E8 -+:10322000C06823F069DE11B030BDC04631F6000041 -+:103230002C9E85001FB5836D0446012B17D1B0F875 -+:10324000583113F0010F12D1C36893F8703273B97B -+:1032500002AA01A903AB0CF071FA029A3AB1204616 -+:103260000199039BFFF7A6FF08B90223A3651FBDC1 -+:1032700010B579B1B0F8583143F00103A0F85831D6 -+:10328000836D022B15D1C3680C21D3F8680151F06E -+:103290008FD90EE0B0F8583113F0010F09D023F0A8 -+:1032A0000103A0F85831836D1BB101238365FFF73B -+:1032B000C1FF002010BDC046642912DC632920DA5A -+:1032C0004A291ED006DC07291EDB082919DD3C2906 -+:1032D00017D019E0502914D016DBA1F15C03032BA1 -+:1032E0000EE0C32905DCC2290BDAA1F1A803022BE9 -+:1032F00006E0B1F5847F04D006DBA1F58973012BCC -+:1033000002D86FF0160000E00020704730B5072AA1 -+:103310001C469DF80C5001DD496809B9036B19681A -+:10332000032906D04B1E012B10D8036B1B68994252 -+:103330000CD12DB190F8293013B96FF00A0007E0D5 -+:103340000CB9204604E00020216001E06FF00C0081 -+:1033500030BDC046C88810F0080018BF6FF01600D6 -+:103360007047C046D1F8D83270B50546188C16465D -+:1033700010BB8B6D40F2371203EA0202002A0CBF29 -+:10338000012411242A6B1368022B07D195F85C36AF -+:103390000133DBB2012B98BF44F02004537D53B1BD -+:1033A000B06B06F13C0122F055DE20B195F94736AD -+:1033B0000BB144F48064204670BDC04691F801C052 -+:1033C00030B5BCF1010F45DDCA788B7843EA0223A2 -+:1033D000012B3FD1ACF10203032B3EDDACF1060320 -+:1033E000012B3ADD0B1D1D1D6A781B79002043EA75 -+:1033F0000222864600E00130ACF10803904203EB64 -+:103400000E0406D0AEF1040EACF104037344042B99 -+:10341000F1DCC0EB0203A4EB830001281DDD05EB0A -+:103420008203DA789B7843EA022E821E002301E0B1 -+:103430000133043A734501D0032AF9DCC3EB0E03D0 -+:10344000A2EB8303012B08DD023B06D0C3EB0C0388 -+:103450004B7002E06FF0160000E0002030BDC04667 -+:103460002F2A30B50446964602D86FF00D0034E09E -+:10347000B0F88031056B0B60B0F88231AA894B60DF -+:10348000EB891B0743EA023302688B601069BEF1C7 -+:103490003B0FC36BCB6093680B61836A4B61C36A5C -+:1034A0008B61B2F87A30CB61D4F884314B62D2F8B8 -+:1034B000B0300B6243688B62836BCB620CD92B8973 -+:1034C00000220B636B89BEF13F0F4B638A6303D904 -+:1034D000036C1046CB6300E0002030BD2DE9F041C5 -+:1034E000064633680F4693F84630154613F0030F2F -+:1034F000C2F3072402F07F00C2F3C01E15D0BEF154 -+:10350000000F12D0032C54D8202807D1B6F8263645 -+:1035100003F44063B3F5406F4BD10CE0072801D9A9 -+:10352000032419E0032C44D015E0244B00F07F0263 -+:103530009B56002B02DA012C3BD80CE0022A05D066 -+:10354000042A03D00B2A01D0162A32D13B68022B61 -+:103550002FD174BB05E024B1D6F860369B78012BDF -+:1035600027D00146BEF1000F05D0022C40F00061CB -+:1035700008BF40F0016141EAC42415F0804F18BF34 -+:1035800044F0804415F4000F18BF44F4000430B137 -+:10359000304621463A68012327F0DCDE48B1C5F306 -+:1035A000405044F0004110B10020B96403E0796458 -+:1035B00001E06FF01C00BDE8F081C046401B8600B2 -+:1035C00010B519B14068302203F092DB10BDC0463F -+:1035D00010B50446D0F860068E46C37A90F80AC04B -+:1035E00093B182894FF6FF739A420DD0837B43B922 -+:1035F0008378012B05D0037B03F0010383F00101E5 -+:1036000000E00021C9B20BE0216B71450ED1837B34 -+:103610002BB98378012B02D091F84C1000E00021E7 -+:103620008C4503D08172206938F03ADE002010BD4D -+:103630004FF0FF33A0F83C3210B5044600F50E7091 -+:10364000063000210C22FEF3FBF423685B6B23B9E8 -+:103650004FF0FF33A4F840320DE04FF00F03A4F811 -+:103660003E324FF0F003A4F840324FF47063A4F8F8 -+:1036700042324FF20003A4F8443210BD70B5044644 -+:10368000D4F8741580680BF0E9DFD4F8F816D0F19F -+:10369000010538BF0025A0680BF0E0DF00B9013557 -+:1036A000A068D4F8FC160BF0D9DF00B90135D4F8C6 -+:1036B000E036A068196A0BF0D1DF00B90135D4F803 -+:1036C000E0260023D360A068D4F83C150BF0C6DFD9 -+:1036D00000B90135A068D4F894170BF0BFDF00B92A -+:1036E0000135284670BDC0462DE9F041069F0646CB -+:1036F0000C46A3F10E0519F0A7DC18B1304621469F -+:103700000FF014DFB5F5106F1DD3D4F8F01040F6AC -+:103710000E1240F6081300290CBF114619466268C4 -+:103720000B4B02EA030303B102398D420BD9A37E8E -+:1037300013F0010F07D121F001026B1E9B18B3FBA0 -+:10374000F2F03A6001E03D600120BDE8F081C04642 -+:103750004000018010B5044625F03CDE204616F0FE -+:1037600055DF10BD2DE9F04F07461069A5B0D1F81F -+:103770001090884601F124011A900792069318913F -+:1037800099F80130D2F87CA199F80020339C42EAE4 -+:103790000323C3F38102022A786808930B9201D0B5 -+:1037A000002302E0089DC5F3C013DBB24146169327 -+:1037B000FFF330F504300A90329888B1037A0B2B6E -+:1037C00008D197F8F0375BB197F8F13743B18379B7 -+:1037D000072B05D832990A9A91F90F30D2180A921C -+:1037E000D7F88831002B1CDA329BD3B11B7A022B1D -+:1037F00017D197F8A034A3B91A9DAB6D13F0080F39 -+:103800000FD132988379292B0BD8032B09D90B2B95 -+:1038100007D82F99012904D10A9A199108320A92DE -+:1038200001E000231993D8F81030B8F81420A3F160 -+:10383000760676329D1FA8F8142000217022C8F861 -+:10384000106030460595FEF3FBF31898036813F4F7 -+:10385000806F01D0828827E00799A64B4A6802EA68 -+:103860000303D3B1089A02F0FC03882B15D199F811 -+:10387000043013F0010F10D1B8F816302F9D03F06B -+:1038800007032E9801EB43016B1E9842B1F8BE204E -+:103890000AD1531CA1F8BE3006E00B99012914D0BF -+:1038A00000224FF0100B04E00B9B012B0DD04FF0CA -+:1038B000000B2E9D05F00F0343EA02139BB289F81B -+:1038C00016301B0A89F8173001E04FF0000B3098D2 -+:1038D000042807D138461A9932460EF091DFADF828 -+:1038E0008C0019E02F992E9D4B1E9D42B7F846255E -+:1038F00002D1531CA7F846352E98309900F00F03DB -+:1039000043EA02135B0147F6E07203EA020201F0A8 -+:1039100007031A43ADF88C20079A92F8DF3023B9D9 -+:10392000089D05F0FC03802B01D14BF0200B724B5E -+:1039300004EA03031BB10020209421941FE00B999B -+:10394000012906D9189A1368002B02DB13F0100026 -+:1039500008D0079C002594F8483003F07F0320939B -+:10396000219349E0396B644B8A6C02EA030343B14B -+:1039700099F8043013F0010F03D0209221920F9098 -+:103980003BE099F8043013F0010009D007980021BA -+:1039900090F848300F9103F07F03209321932CE09F -+:1039A0004A6C554B02EA0303002BE6D120ABD7F853 -+:1039B000600100930DF18F0301930DF18E030293CB -+:1039C0000DF18A03039323AA21AB07994FF072D913 -+:1039D000189A136843F00062189B1A60BDF88A3089 -+:1039E00013F0010F03D0189C42F4005323602E9D66 -+:1039F000D5F1010538BF00250F95D7F86036219A1B -+:103A00009C7A3B6893F8463013F0030100F035814F -+:103A100012F0006F02F07F0104D0072906D9202997 -+:103A200004D02EE0354B5B56002B2ADA12F0804F83 -+:103A300001D1002A25DB22F4401121F4605112F05B -+:103A4000006F21911AD0D7F860068378012B15D921 -+:103A50003B6B93F94D20012A0BD0079D6B6813F047 -+:103A6000804F0BD0B2F1FF3F08D1037B13F0040F5E -+:103A700004D041F4801343F4805301E041EAC423AD -+:103A80002193209911F0006F01F07F0204D0072AE2 -+:103A900006D9202A04D036E0184B9B56002B32DA88 -+:103AA000219B13F0804F01D1002B2CDB21F440121D -+:103AB00022F4605211F0006F209221D0D7F86006F6 -+:103AC0008378012B1CD93B6B93F94D1001290BD046 -+:103AD000079D6B6813F0804F12D0B1F1FF3F0FD1FB -+:103AE000037B13F0040F0BD042F4801343F4805394 -+:103AF00008E0C046400001807F000008401B8600AF -+:103B000042EAC4232093B7F8283603F44063B3F5A0 -+:103B1000406F30D13B6B18690CF070F9219B00F4B9 -+:103B20004070B0F5007F14BF0222032213F0006F33 -+:103B300003F07F0111D0202902D1154605222EE085 -+:103B400097F9CA34B3F1FF3F12D10798436813F4D1 -+:103B5000002F23D01546042221E09C4B5B56002BFE -+:103B6000B4BF97F9C93497F9C834B3F1FF3F15D002 -+:103B700015469AB213E0219B03F07F03202B04BF6C -+:103B80004FF000632193209B03F07F03202B04BFA1 -+:103B90004FF00063209302252A4600E01546219B42 -+:103BA000110223F4E06341EA03032193209B23F4F1 -+:103BB000E06213F0006F14BF41EA020342EA0523FA -+:103BC0002092219A209312F0006F06D097F9DC31F1 -+:103BD000012B02D142F4000304E097F9DC3113B960 -+:103BE00022F400032193209A12F0006F06D097F977 -+:103BF000DC31012B02D142F4000304E097F9DC31FF -+:103C000013B922F4000320930799384612F088D89C -+:103C1000219911F0006202D111920E921DE0D7F8A5 -+:103C2000583693F90530022B02D000220E9207E09D -+:103C3000C1F30223043B012B8CBF002301230E930D -+:103C400011F4000F05D001F07F03072B03D9202BBF -+:103C500001D0119001E004231193209911F000622A -+:103C600001D112921DE011F4000F16D001F07F0374 -+:103C7000072B14D9202B12D00FE0209B22F4E062F6 -+:103C800023F4E06342F4007243F4007302252192AE -+:103C9000209311910E91129103E0129001E00424FF -+:103CA00012940F9888B11A99219BD1F810231A9871 -+:103CB00001EBC201C1F814332F9C0132E3B202F0D0 -+:103CC0003F02C1F81833C0F81023BAF1000F36D004 -+:103CD000FA68DAF80434D2F880410AEBC303C3F877 -+:103CE0000442D2F884013A4AC3F80802B8F8163000 -+:103CF00003F00703D35C022B11D1DAF800100AEBB2 -+:103D0000C102C2F80441C2F80801219B013153608D -+:103D10002F9C01F01F01E3B29360CAF80010DAF89B -+:103D20000424219B0AEBC201C1F808342F98013208 -+:103D3000C3B202F03F02C1F80C34CAF8042421993E -+:103D400011F000642AD011F4000F01F4E06312D0E6 -+:103D50001B0A043B012B1F4801F07F0205D81423E6 -+:103D600002FB0303D3F80C801AE0142302FB0303C5 -+:103D7000D3F8088014E01B0A043B012B154801F01E -+:103D80007F0205D8142302FB0303D3F8048007E065 -+:103D9000142302FB03F353F8008001E001F07F08D5 -+:103DA0000B9A022A00D0BAB9B7F838360A98984266 -+:103DB00004DC189A136813F0806F0DD099F8043062 -+:103DC00083F0010303F0010307E0C046401B8600B7 -+:103DD000C4D285008418860000230D933B6B587D68 -+:103DE00050B1D7F858361B7833B12CB9924A01F04C -+:103DF0007F03D356002B0BDB3B6893F8463013F060 -+:103E0000030F2CD05CB3D7F8583693F9053033B391 -+:103E10002F9A012A13D9D7F858361B780BB11623DD -+:103E200000E03023189C20932193236823F0006343 -+:103E30002360209B43EA0523209321930FE070B178 -+:103E4000D7F858361B7853B14CB97B4A01F07F0341 -+:103E50000E98D35630EA230028BF01200E90219AF5 -+:103E600012F0006F15D102F07F03022B05D0042B56 -+:103E700003D00B2B01D0162B0BD1069939B1022B95 -+:103E800005D097F95C36013B18BF012300E0002301 -+:103E90001193209B13F0006F16D103F07F03022BC8 -+:103EA00005D0042B03D00B2B01D0162B0CD1069C74 -+:103EB00044B1022B06D097F95C36013B18BF0123B1 -+:103EC000129301E0002012900B99079C022904BF75 -+:103ED000079BC3F86021636813F4803F40D097F8D4 -+:103EE000CE31002B3CD097F8D131002B38D0D7F809 -+:103EF000583693F90530032B32D0219B13F0006F15 -+:103F000009D103F07F03022B2AD0042B28D00B2BDE -+:103F100026D0162B24D099F8043013F0010F1FD1AE -+:103F2000089800F0FC03882B1AD1189901240B681B -+:103F30004BF4A04B43F480530B60079B1094D3F8D1 -+:103F4000F0204FF69F73002A0CBF18221E2239F86A -+:103F5000021001EA030343F0200329F8023001E0D4 -+:103F600000201090384621990A9A059B0DF17A0499 -+:103F700019F072DB2346384620990A9A19F06CDB57 -+:103F8000062206F136002146FDF3F6F7209B13F0DA -+:103F9000006F10D103F07F03022B05D0042B03D058 -+:103FA0000B2B01D0162B06D10A99C1F3072386F8F3 -+:103FB0003A1086F83B30189B1A6812F4806F13D0C1 -+:103FC000219B13F0006F0FD0329C14B1237A042B85 -+:103FD0000AD1189842F40063036097F8C3340D992E -+:103FE000002B18BF01210D91219911F0006F0AD10A -+:103FF000114A01F07F03D356002B04DA059A137897 -+:1040000003F00F0301E0059B1B78089C0C93A42C84 -+:1040100014D099F8043013F0010F0FD1109878B92B -+:10402000119A319B38460FF0B9DD89F80200C0F3D0 -+:104030000F2089F803001DE0401B8600109A62B132 -+:10404000119A384640F62A1319F09CD8023080B2F3 -+:1040500089F80200000A89F80300089BA42B09D103 -+:1040600099F8023099F8032043EA022386F83C309D -+:104070001B0A09E099F8043013F0010F01D1109CDC -+:104080002CB1002386F83C3086F83D300BE02099B7 -+:10409000129A319B38460FF081DD86F83C00C0F360 -+:1040A0000F2086F83D001898036813F4007F0DD0A8 -+:1040B00083894BF4005B86F842301B0A86F8433054 -+:1040C000C38986F844301B0A86F845302E9909B911 -+:1040D0004BF0080B09F104021B9299F8043013F01D -+:1040E000010F14D1189B1A6812F4805F0FD197F852 -+:1040F000D03113B112F0400F09D112F4806F04D106 -+:10410000169C14B197F8F8310BB94BF0010B0B98D2 -+:10411000022814D197F8CE318BB1B8F1040F0ED923 -+:10412000A44B30995B5C07EB4303B3F8FE3123B13A -+:10413000189A136813F4806F01D04BF4805B3B6BCB -+:1041400018690BF05BFE199B00F44060B0F5406FFE -+:1041500008BF4BF4807B0BB14BF4004B4FEA1B23A1 -+:1041600086F800B07370329CECB197F8A034D3B9E4 -+:104170001A98836D13F0080F15D1237A0B2B08D1F1 -+:1041800097F8F0377BB197F8F13763B1A379072B34 -+:1041900009D832998A79292A05D80B7B03F00703BD -+:1041A00043EA021A01E04FF0000A189A129C1368C1 -+:1041B000494613F0005F18BF4AF0080A631EDBB2DD -+:1041C000012B98BF4AF4005A301D0222FDF3D4F6A9 -+:1041D0000023B371F37186F82C3086F82D303298B5 -+:1041E000002849D097F8A034002B45D11A998B6D3F -+:1041F00013F0080040D1329B1A7A0B2A0BD197F8A2 -+:10420000F037002B38D097F8F137002B34D0329CA0 -+:10421000A379072B30D832998B79292B2CD8089C7D -+:1042200009F1180104F44073B3F5407F169B08BFF1 -+:1042300009F11E0103B10231022A11D13246329C2A -+:104240002318B3F8BC309375C3F30723D375831CCD -+:1042500002320A2B1846F2D106F12000032209E0AF -+:104260000B2A06F1160002D10231053202E0329B20 -+:1042700093F90E20FDF380F6062206F126001B9925 -+:10428000FDF37AF69DF88C30002286F84C309DF8CC -+:104290008D3086F84E2086F84D3086F84F2086F80F -+:1042A000502086F8512086F8522086F8532086F850 -+:1042B000542086F8552086F8562086F857200D9C05 -+:1042C0000CB10E9203E00E98002800F01D81002230 -+:1042D00021992B46384622F0AFDD209980460022F6 -+:1042E00038462B4622F0A8DD18F00061834609917C -+:1042F00006D1314B08F07F029B56002B2ADA36E0BC -+:1043000018F4000F08F4E06310D01B0A043B012BE3 -+:104310002A4808F07F0204D8142302FB0303DB6859 -+:1043200014E0142302FB03039B680FE01B0A043B09 -+:10433000012B224808F07F0204D8142302FB030358 -+:104340005B6803E0142302FB03F31B58023B18BF16 -+:10435000012302E0931E18BF012343B197F95C3695 -+:10436000012B04D001224AF4804A139201E0002379 -+:1043700013931BF0006F06D10F4B0BF07F029B567F -+:10438000002B31DA3DE01BF4000F0BF4E06317D093 -+:104390001B0A043B012B09480BF07F0204D81423AD -+:1043A00002FB0303DB681BE0142302FB03039B688F -+:1043B00016E0C04698E08500401B86008418860001 -+:1043C0001B0A043B012B9D480BF07F0204D81423E9 -+:1043D00002FB03035B6803E0142302FB03F31B5897 -+:1043E000023B18BF012302E0931E18BF012343B113 -+:1043F00097F95C36012B04D001244AF4004A149446 -+:1044000001E0002514950E983278737820B142EAC5 -+:10441000032343F4006303E042EA032343F006036B -+:1044200033701B0A73700E9A06F158011591002A19 -+:104430000CBF14250E252A461DAC38464146159B57 -+:1044400019F00AD923462A463846594619F004D9A4 -+:104450002146062206F12E00FDF38EF5119C139BDA -+:104460000A9D019400240E9900934246219B0295D7 -+:104470000394384619F010D986F86000C0F30F2075 -+:1044800086F8610014981299209B009001915A4679 -+:104490000E9902950394384619F0FED886F8340038 -+:1044A000C0F30F2086F835000E9A06F162004AB17B -+:1044B0006FF03B0309F10A01062286F85E3086F8A8 -+:1044C0005F4008E06FF04B0386F85E300E9B0C22D5 -+:1044D00086F85F301B99FDF34FF5099C54B9584A93 -+:1044E00008F07F03D356002B04DA159D2B7803F0D8 -+:1044F0000F0301E096F858300C981B0243EA0000C5 -+:1045000006F15E090C901BE00E99062206F1580098 -+:10451000FDF396F50E99102206F15E00FDF390F57D -+:104520000E9906F12E000622FDF38AF50E9986F803 -+:10453000341086F8351089461391149188468B46BD -+:10454000189A136813F4806F0BD0219A12F0006F41 -+:1045500007D0D7F8400107990A9B2AF011DF86F8A7 -+:1045600033004FEA1A2386F802A0F3700C9BB37451 -+:104570000C9C230AF374209B13F0006F02D097F871 -+:10458000C0A40EE003F07F03022B07D0042B05D05C -+:104590000B2B03D0163B18BF012300E000231FFAAA -+:1045A00083FA18F0006F03D097F8C0349D000EE036 -+:1045B00008F07F03022B07D0042B05D00B2B03D070 -+:1045C000163B18BF012300E000239B009DB21BF0A7 -+:1045D000006F03D097F8C0341C010EE00BF07F038E -+:1045E000022B07D0042B05D00B2B03D0163B18BF92 -+:1045F000012300E000231B019CB23B6B18690BF008 -+:10460000FDFB45EA0A032343C0B243EA00233375A6 -+:104610001B0A7375219B13F0006F02D097F8C044FA -+:1046200012E003F07F03022B0CD0042B0AD00B2BDB -+:1046300008D0B3F1160018BF012004E084188600EA -+:10464000401B8600002084B2119D6B1EDBB2012B43 -+:1046500007D83B6844F01004D3F88C2093690133E9 -+:1046600093612199384615F089DA44EA000080B256 -+:104670003072000A7072219938461FF0B3DDB072B3 -+:10468000C0F30F20F072209938461FF0ABDD307375 -+:10469000C0F30F2070730D9808B90E9979B1414697 -+:1046A00038461FF09FDDB073C0F30F20F0735946FA -+:1046B00038461FF097DD3074C0F30F2070742199D5 -+:1046C00011F0006F0CD0119A042A09D10A9A3846C9 -+:1046D00018F00ADE86F83E00C0F30F2086F83F008F -+:1046E000209911F0006F0CD0129B042B09D10A9A6B -+:1046F000384618F0F9DD86F84000C0F30F2086F840 -+:104700004100079C636813F0400F00F0CE80169DB7 -+:10471000002D00F0CA806A4B30981B5C179307EBA2 -+:104720004303B3F8FE31002B00F0BF8018990B68EB -+:1047300013F4806F40F08D802E9A002A40F089801B -+:10474000219C38462146119A0A9B18F01BDD8246AF -+:10475000B9F1000F1AD04146139A38460EF0E0DF47 -+:10476000149A0446594638460EF0DADF99F80320C9 -+:1047700099F8023043EA022303EB040896F8352047 -+:1047800096F8343043EA022318181BE0109B13B14B -+:104790008046484616E02146119A4B4638460FF0AF -+:1047A000FDD9209C129A21460A9B00EB0A08384644 -+:1047B00018F0E8DC21460546129A38464B460FF0C1 -+:1047C000EDD940191FFA88F3B3711B0AF37183B254 -+:1047D00086F82C301B0A86F82D30179C07EB440313 -+:1047E000B3F8FE51CAEB0804A54225D31898036814 -+:1047F00013F0400F02D0309901291DD0384621997D -+:10480000119AC4EB05030EF093DFFF2802D84FF492 -+:10481000807304E0B7F82A36834228BF034699B272 -+:10482000309B07EB4302B2F82C368B4204D0A2F83F -+:104830002C16384626F02AD83B6893F84430002BD3 -+:1048400033D0309C032C30D8D7F8640117994246F6 -+:1048500028E03B6893F844303BB3309D032D24D8C7 -+:10486000B9F1000F0CD0139A384641460EF058DFCC -+:1048700099F8032099F8023043EA02231A180EE04F -+:10488000219C119A21460A9B384618F07BDC119A2C -+:104890000546214638464B460FF080D94219D7F8D5 -+:1048A00064011799079B3DF08DDC1898036843F06D -+:1048B00084030360BDF88C0025B0BDE8F08FC046CE -+:1048C00098E085002DE9F0479946536A064613F4AF -+:1048D000007F884617469DF920A0146902F124053F -+:1048E00015D0E86883B2000C84F8423084F84400A4 -+:1048F0001B0A000A84F8433084F845002378607866 -+:1049000043EA002343F4005323701B0A63703368A7 -+:104910002D6993F8443093B1F36A03EB4803B3F97C -+:104920001C3063B95DB12B69D3F8D43293F89D3054 -+:10493000032B04D9D6F864012B463DF023DDB8F1F2 -+:10494000040F22D194F84D3094F84C2042EA03240D -+:10495000336893F83830D3B1384612F0A3D806EB59 -+:104960008000D0F84C12D1F85835D1F860055A1CA7 -+:10497000C1F85825C369A1F8C8409A4288BFC261EE -+:10498000D1F86025136A013313624FF6FF74B9F151 -+:10499000000F05D0F26A02EB4802938B53449383D5 -+:1049A0004FF6FF739C4204D03069A821224639F0AB -+:1049B00051D93369394603EB8803D8680C4B4A4612 -+:1049C0005B6A9847002810DA0A480AF077FB0A4A1F -+:1049D000136801331360B9F1000F06D0F26A02EBDD -+:1049E0004802938BCAEB03039383BDE8F087C0466C -+:1049F000E0A68500BC568600E4F4010070B50D46C3 -+:104A0000D0F860160446CB7AAB420CD025B10C31FD -+:104A1000B0F8282615F0F6D8D4F860362046DD72B6 -+:104A2000216BFEF7D5FD002070BDC0462DE9F04F8B -+:104A30008FB000230C461D99074604921A9DDDF89D -+:104A40006C800D930C93DDF860B0DDF864903AF063 -+:104A5000D1DC049A824602F00106009638682146AD -+:104A60002A4643461EF030DC0590002840F0438182 -+:104A7000B4F90630002B1CDAA18822895EB11C9B98 -+:104A8000CDF8008003930195CDF80880490038697E -+:104A900001312B4609E01C9BCDF800900393019552 -+:104AA000CDF80880386949005B4638F059D8059040 -+:104AB00021E1B9F1030F0DD904220DA85946FDF3E8 -+:104AC0005BF2B9F1070F05D90CA80BF10401042220 -+:104AD000FDF352F2049A0D99931E202B22D8DFE8A1 -+:104AE00013F02400260028002A002F0032003A008C -+:104AF0003C004E005000570059005B005D005F0015 -+:104B00006100630021006900700078007A008C0069 -+:104B10008E009200940099009B00A0002100AC0040 -+:104B2000A200B4006FF01603E4E0754B09E0744B8B -+:104B300075E0744B05E0002900F3DA80714B06E064 -+:104B4000714B1B687FE00029C0F2D2806E4B196068 -+:104B50006E4B00223BE06E4BF3E721B16D4B1B68BF -+:104B6000002B00F0C5806A4B002219606A4B1A6066 -+:104B70006A4B1A606A4B1A606A4B013A27E0654B30 -+:104B8000DFE7644A1368002B40F3B2801160B2E0A3 -+:104B9000654BD6E7644B42E0644BD2E7634B3EE0A3 -+:104BA0005D4BCEE75C4B3AE0D7F86C32D3F8D832A5 -+:104BB0009B6848E05E4B1A685E4B1B6843EA024301 -+:104BC00041E05B4B0A141A605A4B01F0FF021A6075 -+:104BD00091E0594BB5E7584B1960002900F08B80E4 -+:104BE000564B00211960564B4FF0FF321A60554B5F -+:104BF0001A60554B1960554B11E0554BA1E7002940 -+:104C000076DD534B0BE0534B9BE74B1E092B6FD8C4 -+:104C1000504B04E0504B94E7002969DD4E4B19607E -+:104C200069E04E4B8DE79AF80630002B5CD14C4B77 -+:104C30000A1E18BF01221A705DE09AF80630002B98 -+:104C400052D1474B1B782B6055E038468E2121F01E -+:104C500087DA400080B200F10A03ADF8243000F199 -+:104C60001003ADF8263000F11603ADF8283000F13E -+:104C70001C03ADF82A3000F10C03ADF81C3000F134 -+:104C800012034FF00008ADF81E3000F118031E307B -+:104C9000ADF82030ADF822004646C14609AB39F8E0 -+:104CA0000310384621F05CDA07AB044639F80310EC -+:104CB000384621F055DA24B200B2241A032304FB4B -+:104CC00003F40BAAC4F34714B45464B21F2C01DDDF -+:104CD0001C33B354B3560136042E984409F102092B -+:104CE000DCD1C5F8008006E06FF00602059202E014 -+:104CF0006FF01C03059305980FB0BDE8F08FC04618 -+:104D0000E8F40100D4F40100DCF40100B4F4010083 -+:104D1000BCF4010030ED0100D0F40100CCF401003E -+:104D2000C4F40100B0F4010020ED010034ED0100F5 -+:104D3000ECF80100E8F80100B8F40100E0F401002B -+:104D40001CED010028ED0100C0F40100D8F40100C1 -+:104D500024ED01002CED010018ED0100C8F4010064 -+:104D6000ACF4010037B5036804465B7E002B40F0CD -+:104D7000C480026992F8EA305BB1D36ED3F8202187 -+:104D800040F2044302EA0303B3F5806F40F0B580BC -+:104D900005E0106E06F0DEF8002840F0AE802368D3 -+:104DA00093F8203033B9206904F072FE22680123A1 -+:104DB00082F8203023681B6FFBB9206904F0E6FD00 -+:104DC00010F1090F19D12268136F13F0020114D1E9 -+:104DD00043F0020313670D4604EB8503D3F84C122E -+:104DE00041B18B7933B94B7923B18B7C13B1204618 -+:104DF0003AF046D80135082DEED123681D6F1DB15C -+:104E0000204612F081D876E0012384F8293020462C -+:104E100020F00CDF2368596B39B103234FF4807203 -+:104E2000009320462946134605E0032300932046BD -+:104E30004FF480720B461EF0C7DEA0680AF034DC27 -+:104E4000236801221A7694F89D3173B120460AF046 -+:104E5000E1F9D4F840352046598E23F0E7DD0023F0 -+:104E600084F89D3120461DF0CBD8B4F85C1720465D -+:104E700021F054DE206904F0B3FE236893F82F304C -+:104E80001BB1D4F834072FF045DF236893F8313095 -+:104E90007BB1002504EB8503D3F84C1231B18B793B -+:104EA00023B94B7913B1204635F002DE0135082DC8 -+:104EB000F0D1204615F016DE204615F04FFB0125F7 -+:104EC000D4F8AC114FF47A720123A0680AF07EDBAB -+:104ED000204684F8F15125F0D9DC204614F07ADE22 -+:104EE000204626F035D850B1204626F00FD820466F -+:104EF000294626F015DA002001E06FF008003EBDDB -+:104F0000D0F8403570B55D8E064605F44063B3F5C4 -+:104F1000406F22D1036893F8463013F0030F0BD093 -+:104F200005F47041D0F85C01B1F5805F14BF002139 -+:104F3000012141F0BFD980B92846FEF373F1044640 -+:104F40002846FEF36FF144F430640E288CBF4FF412 -+:104F500080504FF400500443A5B2326B05F4704307 -+:104F60005268B3F5805F14BF00230123934205D03C -+:104F7000D6F85C01012140F0C1DC0546D6F85C01A1 -+:104F8000294641F00BDA80B905F47043B3F5805F30 -+:104F900014BF38233C23F358346BD6F85C013363D9 -+:104FA000012140F0ABDC34630546284670BDC046A5 -+:104FB00070B50025044680F8E85124F0BFDCE36AB0 -+:104FC0002946986A8022FDF33BF0206905F048F8F5 -+:104FD000D4F840012AF0A6DBC4F8885670BDC0465C -+:104FE0002DE9F04390F8A03187B00446002B40F043 -+:104FF000ED8003681B7E002B00F0E880012380F821 -+:10500000A031006904F0BAFD2269074692F8EA303F -+:105010005BB1D36ED3F8202140F2044302EA0303CC -+:10502000B3F5806518BF012503E0106E05F092FF0F -+:105030000546002D6FD1D4F8680104214FF0B8DA8D -+:10504000204621F0ABDD00B90137A94604EB090386 -+:10505000D3F84C62002E59D096F80680B8F1000FB4 -+:1050600054D1304633F072DB73793F18002B4DD0AA -+:10507000236893F83130002B3FD0D6F8CC3013F0B2 -+:10508000010F3AD0204631460AF0D4F823683F1881 -+:1050900093F89530002B39D0D4F86C122046BC31EF -+:1050A00050F07CDB0546002830D02046294621F010 -+:1050B00093DF2B7E13F0020F19D0284602214FF008 -+:1050C000BFDFB17CD4F86C32D1F1010138BF0021CF -+:1050D000082201920291204631460332BC33CDF8BA -+:1050E0000080CDF80C80CDF8108017F017DDD4F8D3 -+:1050F0006C22012382F8F03008E02046314639F076 -+:10510000BFDE3F184FF47A6001F026DB09F1040995 -+:10511000B9F1200F9AD10025D4F8B434EA18136BF2 -+:1051200013B1506A98473F18343540F2AC439D4262 -+:10513000F2D194F8F1314BB1A068D4F8AC110AF077 -+:105140008DDA00B90137002384F8F1312046FEF7EB -+:1051500095FA236800211976236B4FF0FF32C619A8 -+:1051600018690AF023FE204615F092D9D4F8785237 -+:1051700007E00023291D606801220093FDF362F619 -+:105180002D68002DF5D1236893F82F3073B1631982 -+:10519000D3F84C1239B18B792BB10B791BB1204666 -+:1051A0000AF048F836180435202DF0D1D4F87C02E6 -+:1051B00010B109F0E1FA3618206904F091FC0023DF -+:1051C000801984F8293084F8A03100E0002007B06D -+:1051D000BDE8F0832DE9F04F9DB005462798089271 -+:1051E0000793827AC37A0F4642EA0323289A00F192 -+:1051F0000C010C3A08980B9115930C92C27D837D9B -+:105200000DF1600943EA0223C3F3C70ABAF10E0F96 -+:1052100094BF00210121109102794379079942EA54 -+:105220000323099315F01EF9269A11900A321146AC -+:105230000A922846109A50F0BBDA0024804617AE36 -+:1052400028462799289A4B461794189400961CF0E4 -+:10525000E1DE30B928462799289A4B4600961EF081 -+:10526000D9DEB8F1000F06D0D8F8043013F0010FE2 -+:1052700001D00D9427E00C990B983222FDF31EF219 -+:10528000014620B14078023120F0E4DE58B90C9993 -+:105290000B980122FDF312F2014638B14078023139 -+:1052A00020F0D8DE10B101230D9301E000200D9015 -+:1052B000B8F1000F07D00D9929B9D8F8043043F0A0 -+:1052C0000103C8F804300B980C990322FDF3F6F1A2 -+:1052D000044608B14378A3B92B6893F83F3053B123 -+:1052E000B5F82606C3B2534503D0FDF39BF75045EE -+:1052F00001D1012300E0002300225FFA83FB0E921C -+:1053000011E02B6893F83F3043B1B5F82606FDF362 -+:1053100089F7A378834201D1012300E000235FFADB -+:1053200083FBCDF838B0BBF1000F01D15B4602E042 -+:105330003B1E18BF01235FFA83FA2B6893F84630AF -+:1053400013F0030002D11290139024E095F872320A -+:1053500063B9BAF1000F09D0D7F8D432DB8813F063 -+:10536000200003D112901390149018E00B990C9A1E -+:10537000284620F0E1DE0B9913900C9A284620F085 -+:10538000A7DE2B68129093F94C0020B128460B99A8 -+:105390000C9A1DF0CBDB1490BAF1000F69D02B688A -+:1053A00093F8463013F0030F63D0129B002B60D0AC -+:1053B000139800285DD019785A7828460FF0E2DD5E -+:1053C000B5F82696064609F47043B3F5005F0CBFA6 -+:1053D00038233C23EC58D5F85C01616840F08ED945 -+:1053E00010F0080F01D0002104E094F8EC30191EF1 -+:1053F00018BF0121139A137813F0020317BF1298F4 -+:105400001A464378C3F3800209F44063B3F5406F52 -+:1054100018D1B5F82636B34202D100210F912EE003 -+:105420002B6893F82F30002B40F04A843046FDF370 -+:10543000F9F60446B5F82606FDF3F4F6844240F08A -+:105440003F8414E0A9B1A2B106F44063B3F5406F04 -+:105450000FD12B6893F82F3073B93046FDF3E2F685 -+:105460000446B5F82606FDF3DDF6844204D10F9616 -+:1054700005E000220F9202E000230F939A462B6B67 -+:105480005B7D002B3AD0BBF1000F37D095F872321C -+:1054900033B995F87432002B30D0BAF1000F2DD10A -+:1054A00095F849365BB1179B002B08DD189B1B78DC -+:1054B00013F0040F03D0D5F858260423136195F890 -+:1054C000493653B10D9850B9159911F0200F0ED1EE -+:1054D000D5F858260423D36009E00D9A3AB1179BFA -+:1054E000002B08DD189B1B7813F0010F03D0D5F8B3 -+:1054F000582604231362284625F06EDD2B6893F8A6 -+:10550000463013F0030F46D0BBF1000F43D095F89F -+:10551000723233B995F87432002B3CD0BAF1000FD7 -+:1055200039D1B5F8263603F44063B3F5406F14BFA4 -+:1055300000210121129B13B90D9830B916E0129A7F -+:10554000937803F00303032B05D1D5F858260423E1 -+:105550009361129B53B11298837803F00303022BDB -+:1055600004D119B1D5F858260233D362139A7AB10F -+:10557000129B6BB113985A78037813F0020F07D17E -+:1055800012F0040F04D019B1D5F858260423D362C1 -+:10559000284625F0D3DD2B6893F82F30E3B1D5F8FA -+:1055A000FC341B78C3B10E99B1B9284613992FF07A -+:1055B00021D988B128460E992FF01EDA28462FF0FF -+:1055C00011DAB5F8263603F44063B3F5406F03D122 -+:1055D000284601212FF082D9B8F1000F29D0D8F840 -+:1055E000F03033B300230C997C4A0B9800931CF0E5 -+:1055F00089DE41460246284620F0C2D82B6893F83F -+:10560000463013F0030F14D0139A2AB1149B284686 -+:105610000093129B41460AE0D8F8043013F4803F0F -+:1056200007D01398139A00904146284613461DF060 -+:10563000DDDA95F87032002B00F05B830FB93E463F -+:1056400001E0D7F8DC62BAF1000F77D02B6893F84D -+:10565000463013F0030F32D0BB7C43B9B8F1000FD2 -+:1056600008D128460A99109A50F0BCD98046B8F162 -+:10567000000F24D0139971B1149A129B00922846FE -+:105680004146139A1DF0B2DAB7F8343523F02003FF -+:10569000A7F834350DE0BB7C5BB9D8F8043013F4BF -+:1056A000803F06D0139B284641461A4600931DF0C2 -+:1056B0009DDA28460B990C9A434620F087D8089922 -+:1056C00028461EF069D941B238461EF0A7D938469F -+:1056D0001EF0FCD80899284612F0F2D90146384647 -+:1056E00011F054D9BB797BB9D7F8E032D7F8D4227E -+:1056F000188A9B8A5085938573792BB9BB7C1BB123 -+:105700003846012135F046DE0023B371F371BC7CCD -+:10571000A4B996F88530012B10D186F88540D5F8CC -+:10572000400126F00BDF284639460F22234600941D -+:10573000019402940394049417F0F0D9002F5AD0E6 -+:10574000BB79002B57D1BB7C002B54D027992798CD -+:105750008B784A781B0443EA02230A781343CA78F9 -+:10576000043143EA02698B784A781B0443EA022336 -+:1057700002791343CA7843EA0264F26912B9336AC0 -+:1057800013B935E0944204D3944231D1336A994538 -+:105790002ED2DDF898E00023009301930293039347 -+:1057A00004932846394616220EF1100317F0B6D995 -+:1057B00038460899079A279B24F0B0DEBBF1000F0A -+:1057C00016D0FB7963B1BB7C23B107F1BC00FDF3BC -+:1057D000C3F028B907F1BC0104E0C046C3A601002C -+:1057E00007F1D601002228461346009222F038DC49 -+:1057F000C6F82090F461BAF1000F00F01A82BB796C -+:10580000002B40F09181BB7C002B00F08D8116AB0A -+:10581000009327993846289A0DF16F0316F024DA81 -+:10582000BDF85810D7F8E462A7F8201595F8EB41B9 -+:10583000002C65D100284FD03378022B19D138467F -+:105840002146B6F8269009F037FAB5F8303885F8D1 -+:10585000324803B1F38438461EF0B4DED7F8E432A0 -+:10586000A6F826905B8B002B4AD0384611F070D9F1 -+:1058700046E02B685B6B4BB195F8FA3133B1B8F168 -+:10588000000F14D098F8D2300F2B10D0B27822B17C -+:105890002846394622F0E4DF32E04FF0FF33009330 -+:1058A000284607F1BC01134622F0DADB28E095F820 -+:1058B0000D372BB3B3785BB1B8F1000F05D0D8F832 -+:1058C000043023F00063C8F80430384616F0AADA32 -+:1058D000384623F0C7DC13E0337A23B1718911B95C -+:1058E000384623F0EDDCD7F8E4325B8B43B13378F4 -+:1058F000022B05D1336A012B02D138461EF04EDE51 -+:10590000F3781BB13846002123F0CEDB737A3BB924 -+:1059100038460EF095D818B13846012123F0BCDD89 -+:10592000737A5BB1099A3846C2F3C011279B119A6A -+:1059300024F09ADD3846002123F0AEDD2B6B5B7D31 -+:10594000002B41D0159B2846C3F3802124F0AEDC08 -+:10595000189A002A38D0179B002B35DDD5F8581639 -+:1059600091F90130B3F1FF3F09D11378C3F340023D -+:105970000B78934203D0284601211FF0F9DF189BD2 -+:105980001B7813F0040318BF012385F8463695F9F8 -+:105990004636012B03D0D5F858361B690BB10023CE -+:1059A00000E0012385F84236B8F1000F0CD0D8F89A -+:1059B000043023F00402C8F8042095F946361BB9D8 -+:1059C00042F00403C8F804302B6893F8463013F013 -+:1059D000030F35D01298002832D0D5F8582692F906 -+:1059E0000630B3F1FF3F26D1837892F9052003F00A -+:1059F00003039A4204D028460B211A461FF0B8DF51 -+:105A000012998B78C3F38002D5F85836DB7993422C -+:105A100003D028460D211FF0ABDF129A9378C3F311 -+:105A20000012D5F858369B7A934209D028461021A7 -+:105A30001FF09EDF04E0012B0CBF032300235371F2 -+:105A4000D5F85C01B5F8261640F070DA90B1D5F8BB -+:105A50005C01B5F826163FF0A9DE2B6B18690AF039 -+:105A6000CDF9B5F82636834204D1002128460A46EE -+:105A70001EF092DAB8F1000F3FD0D8F8043013F0DE -+:105A8000400F00F029810B9B0C981A93199006E0A7 -+:105A9000284621461AAA19AB1DF060DD40B91A98B4 -+:105AA0001999DD22FCF30AF604460028F0D10CE136 -+:105AB000A11C0E79012E40F00F818A7995F80C32E5 -+:105AC00002F00F0203F00F039A4200F0058105F582 -+:105AD0000074063420461822FCF34EF22B6893F82B -+:105AE00030303BB1D5F83407214600F563701822F9 -+:105AF000FCF342F238463146ECE028460B990C9A0A -+:105B000010F084DB012802D128460EF015D90F9938 -+:105B1000002900F0EE8095F86D35002B40F0E9800B -+:105B2000284617F0D7DFE4E0BB7C002B40F08180F3 -+:105B30000D9A0AB1012102E0159BC3F34011CCB2CA -+:105B4000B8F1000F15D0D8F8043014B143F00403B5 -+:105B500001E023F00403C8F804300C990023664ADE -+:105B60000B9800931CF0CEDB4146024628461FF0FE -+:105B700007DE2B6B5B7D13B3179B002B11DD189B8E -+:105B80001B7813F0040F03D0D5F8582604231361B3 -+:105B9000189B1B7813F0020F03D0D5F85826042366 -+:105BA00053620D9818B9D5F858260423D3611CB94F -+:105BB000D5F858260423D360284625F00DDA2B6843 -+:105BC00093F8463013F0030F00F09380129941B11F -+:105BD0008B7803F00303032B03D1D5F85826013348 -+:105BE0009362139ACAB1139852780378B5F82616BF -+:105BF00043EA022010F0100F03D1D5F858260423F1 -+:105C0000536310F0020F08D101F44063B3F5406F05 -+:105C100003D1D5F8582604231363129929B90D9A94 -+:105C20001AB1D5F8582604235361284625F086DAA0 -+:105C30005FE095F85735002B5BD0BBF1000F58D0D3 -+:105C4000159B13F0020F54D00B980C990022FCF313 -+:105C500035F5034600284CD02846991C5A7839F06F -+:105C600081DB0446002844D0837C002B41D1089975 -+:105C7000079A16F0C7DD00283BD027982899269B65 -+:105C8000D4F8D06203F110020090019128460899DF -+:105C90000123029620F066DB024650BB296BD5F843 -+:105CA0006036503106F138009B784BF067D9289860 -+:105CB00008990090079A2046279B34F047DC18E0AB -+:105CC00000218A460F91FFF7DABB022385F80E32D6 -+:105CD000384601211CF064D800230C990B98064A21 -+:105CE00000931CF00FDB4146024628461FF048DDBA -+:105CF00003E71DB0BDE8F08FC3A601002DE9F04F0A -+:105D0000D2F81080C1B0D8F8D8A2064609910892FE -+:105D1000DAF82C00DAF8301000220793FCF3CEF406 -+:105D200020B1831C109342780B9205E0099A099BDD -+:105D3000093210921B7A0B932CAF0021282238468F -+:105D4000FCF37EF10021282222A8FCF379F1DAF895 -+:105D500030100122DAF82C00FCF3B0F4DAF830103D -+:105D600004463222DAF82C00FCF3A8F405463CB1D4 -+:105D70006278102A04D8381DA11C2C92FCF3FCF088 -+:105D80003DB16A78102A04D823A8A91C2292FCF3FA -+:105D9000F3F0099AD38813F0010F0BD0316B4B7DD0 -+:105DA00043B10A6D2DA854312C92FCF3E5F0002389 -+:105DB000229309E022AB0093099B304603F138029D -+:105DC00041462CAB20F042D8B8F86250DAF82C40AB -+:105DD000B5F5806FDAF8307059D0B5F5006F04D1A1 -+:105DE0000022934611920C9257E020463946FDF36B -+:105DF00071F2119020B143784FF0000B0C930BE03F -+:105E0000204639463022FCF359F4834610B9119AE2 -+:105E10000C9201E043780C93402D09D0802D07D0DF -+:105E2000102D05D0B5F5807F02D0B5F5007F33D1B8 -+:105E3000D8F8582040F2371302EA030363B30C9AF0 -+:105E4000BBF1000F08BF1422402D0C922ED14FF051 -+:105E500000094F4616E0162307FB03F303F5B4735E -+:105E600008EB03040998211D0622FCF369F040B9F0 -+:105E700040AB03EB890204F10A0342F8B83C09F194 -+:105E800001090137D8F8CC329F42E4D310E0002258 -+:105E9000934611920C9200E045B1D8F8582040F298 -+:105EA000371302EA03030BB118230C934FF00009D8 -+:105EB00040F2EE5301933FAB0293079B099A002BEC -+:105EC00014BF20210021304608F1C20300921CF0CB -+:105ED00073DA0D9030B930460D99B8F80C2332F0D2 -+:105EE000FDDD83E23F9A304602F5BC630E330A9231 -+:105EF0004146099A0E93FDF735FA0A9A1070C0F3DD -+:105F00000F2050709AF8223093709AF82330D37093 -+:105F1000131D3F93079B8BB10AF124042046FCF329 -+:105F20001BF510B93F98214602E03F9808F1D601D1 -+:105F30000622FCF321F03F9B06333F933F9A00215A -+:105F40000F921046109B0B9A26F00ED92DAB012113 -+:105F50002C9A3F9026F008D90C9B3F90002B7CD0C8 -+:105F6000BBF1000F11D0B9F1000F03D030465946F4 -+:105F7000FDF724FA3F9C5946204617F0C7DB3F90B7 -+:105F80009BF80130A346637019E0402D09D0802DA5 -+:105F900007D0102D05D0B5F5807F02D0B5F5007F74 -+:105FA0005BD1A649834617F0B1DB099B3F9003F113 -+:105FB0007B02304641460BF1040313F015DA402D05 -+:105FC00009D0802D07D0102D05D0B5F5807F02D0E7 -+:105FD000B5F5007F41D1B9F1000F01D14C4626E063 -+:105FE0009BF801300BF1020202F80390D7184FEA38 -+:105FF00019237B709BF80130002402338BF80130A9 -+:106000003F9B02333F9312AB07EB041053F824106D -+:1060100002301022FBF3B0F79BF80130013410334B -+:106020008BF801303F9B10334C453F93EBD1D6F8B2 -+:106030006C32D3F8D8325B68022B0ED16CB10022DF -+:1060400000920192CDF808B09BF80130304602333F -+:106050000393572113461DF02BDD229A2AB13F9856 -+:10606000322123AB26F080D83F90DAF82C401CE098 -+:106070006278C1F102031B199B18671C83421CD86C -+:10608000119BA34219D02378012B0BD9302B09D0B7 -+:1060900002323F982146FBF36FF73F9B6278023351 -+:1060A0009B183F933B78A21CD41834B1DAF82C101B -+:1060B000DAF830000B189C42DAD3336893F8463094 -+:1060C00013F0030F18D0089A536813F4803F13D0CD -+:1060D000326B0DF1DB041368404621466532022B1A -+:1060E00014BF0023012325F0A1DF3F982D211A22A0 -+:1060F000234626F039D83F9096F8653633B106F539 -+:10610000CC613F98043117F001DB3F90336893F87E -+:10611000463013F0030F1FD0089A536813F4803FE2 -+:106120001AD0326B0DF1DB0113684046022B14BF0D -+:1061300000230123653225F079DF3F990E9B8B42C6 -+:1061400001D2002202E00E9BC1EB030230460DF1AA -+:10615000DB0325F029DE3F9033685B6B4BB3099A74 -+:10616000D38813F0040F24D00DF1F5003449032235 -+:10617000FBF302F702238DF8F83000238DF8F93095 -+:1061800001338DF8FA3096F8FA313BB1099A92F959 -+:106190006A30002B02DA96F80A3700E000238DF807 -+:1061A000FB303F98DD2107220DF1F50325F0DCDF00 -+:1061B0003F90B5F5806F02D0B5F5006F06D1D8F8E5 -+:1061C0002C3543B33F98D8F8281505E00C9B13B342 -+:1061D000119A2AB13F98114617F098DA3F901AE0C9 -+:1061E000402D18D0802D16D0102D14D0B5F5807FFD -+:1061F00011D0B5F5007F0ED03F9C1249204617F014 -+:1062000085DA099B3F9003F16B023046414604F169 -+:10621000080313F0E9D86B1E9BB2012B03D9042DA0 -+:1062200001D0082D10D1099A506E002838D0B2F84C -+:1062300068100C300C39FDF34DF01BE0CCD285001A -+:10624000CBA60100E2D28500402D09D0802D07D0D9 -+:10625000102D05D0B5F5807F02D0B5F5007F1FD198 -+:10626000099B586EE0B1B3F868100C300C3930223D -+:10627000FCF324F2A0B1D6F86C32D3F8D8325B68C4 -+:10628000022B0DD14378102B0AD902330022029041 -+:106290000393304657210123009201921DF008DC40 -+:1062A000D8F8583013F0040F01D004230EE013F097 -+:1062B000020F01D0022309E013F0010F01D00123E6 -+:1062C00004E013F4807318BF4FF48073089A1364CA -+:1062D000336893F8463013F0030F2DD0089A136CEF -+:1062E000013B012B09D8536813F4802F05D01146C8 -+:1062F0003046062224F0D4DC1EE0089A536813F4DA -+:10630000802F19D011463046062224F06DDC30462D -+:1063100016F09ADE012801460ED1D6F8F83742F27F -+:106320000E721B88013B9BB2934202D83046013962 -+:1063300000E0304628F0CADE3F9C0E9BA34201D20B -+:10634000002302E00E9AC4EB020300932023019382 -+:10635000002123464FF0FF32404639F0E5DE0F9B27 -+:1063600000273F90C01A03930490414655223B46B4 -+:10637000304600970197029716F0D0DB0A9A3F9BB0 -+:10638000A2F11805C5EB0304DAF834100D9B9C82CA -+:1063900021B17068DAF8382000F0AADC0A9A706837 -+:1063A000C5EB0203E41A214600F092DCCAF834007F -+:1063B00040B1079BCAF838408AF83C300A99224617 -+:1063C000FBF3DAF5099A3046B2F862300197C3F36D -+:1063D000401300930297089B0D99D6F804281FF0EC -+:1063E000A1DB0D9B002808BF00230D930D9841B041 -+:1063F000BDE8F08F2DE9F04F93B006911969059231 -+:1064000004930A9101F1060A8A799AF80130064646 -+:1064100042EA0323059A0793C0F87828C3F381055D -+:1064200013465B79127942EA0323089303F00303CE -+:10643000022B08D1079C14F4004F04D0D5F10103BE -+:1064400038BF002300E00023DBB204990B930B9AC2 -+:106450008B8AA3F10A0993001DB918339945C0F23C -+:10646000A881079B03F0FC08B8F1A40F05D0B8F190 -+:10647000840F02D0B8F1940F03D1B9F10F0F40F39C -+:1064800098810AF1040409949AF8043013F0010386 -+:106490000C9303D000210F460D9108E03046099976 -+:1064A00038F03CDF021E18BF012207460D9225B1CD -+:1064B00000239B460E930F9310E00AF11004304620 -+:1064C000214638F007DF0E9010B183460F9505E0A6 -+:1064D0003046214638F068DF83460F9096F8C83181 -+:1064E00023B9326892F82C3033B92AE03046059946 -+:1064F000049A00230FF084DCB8F1A40F05D0B8F1A2 -+:10650000840F02D0B8F1940F01D10D9C5CBBB8F19F -+:10651000800F28D0B8F1500F25D0002D40F04883CF -+:106520000D9901BB0998FCF307F2002800F04083A5 -+:10653000BBF1000F17D10AF11000FCF3FDF190B987 -+:1065400036E30C9B7BB90D9C3CB192F8383053B1CB -+:106550004DB9BBF1000F06D12FB9D2F88C20936F43 -+:106560000133936724E396F8C8317BB9BBF1000F80 -+:1065700001D05C4601E0D6F86C4294F8E5302BB1CE -+:1065800030460599049AA3680FF03ADC012D12D128 -+:10659000B8F1C40F0FD0B8F1D40F0CD00AF10A0033 -+:1065A000FCF3DAF1002840F003839AF80A3013F084 -+:1065B000010F40F0FD82049930460B69A1F8149058 -+:1065C00006330B6133685146D3F88C20D36C01330A -+:1065D000D3641FFA89F30093059A11AB11F088DF99 -+:1065E00030B13368D3F88C20D36F0133D367DFE247 -+:1065F000119A12B133689B6A1362012D3DD1049A3E -+:10660000049B1069998A00F11002049C1A61A1F19F -+:106610001003A3820B9B2BB100F11402A1F1140310 -+:106620002261A3820499B8F1A40F8C8A0FD1119929 -+:106630000B699B79002B00F0BB8291F8DF30002BB7 -+:1066400000F0B6823046079A2FF0F2DCB0E23368F1 -+:1066500093F84230002B00F0AB82B8F1840F03D0E6 -+:10666000B8F1940F40F0A482D6F840011199234666 -+:10667000CDF8008028F0D4DE9AE2059B0C9C9A7D30 -+:10668000DB7D42EA0321002C66D19AF816309AF895 -+:10669000172043EA0227119B5BB9C1F3C7023046BA -+:1066A0000AF10A010E2AD4BF002201224FF080D83D -+:1066B0001190079911F4006905D0119B1BB1B3F833 -+:1066C000BC30BB4225D0119B0BB1A3F8BC70119B11 -+:1066D0008BB141E006EBC20303F5F3642046FCF303 -+:1066E0003BF170B90AF10A0021460622FBF328F4B7 -+:1066F000013508B906E01D4696F8E837EAB293423C -+:10670000E8D20024B9F1000F0CD064B1E388BB4299 -+:1067100021D13368D3F88C20D2F8BC310133C2F8D0 -+:10672000BC3145E2BCB996F8E8370AF10A0106EB3C -+:10673000C30202F5F364013386F8E83706222046E7 -+:10674000FBF31AF496F8E8170A23B1FBF3F202FB05 -+:10675000131386F8E837E7800D9A62B10E9B53B1A8 -+:106760009BF806303BB9DBF8E4321B7A1BB1584684 -+:10677000079910F0C9DD049C2069A18A00F1180274 -+:10678000226191460B9AA1F11803A38232B100F164 -+:106790001C02A1F11C032261A3829146049C07996B -+:1067A000089BA78A11F48044C3F3C0150DD0072FAE -+:1067B00006DC3368D3F88C20536E01335366F7E15F -+:1067C000B8F1B00F40F0F48130E0B8F1500F00F0B4 -+:1067D000848013D8B8F1200F00F0B98107D8B8F140 -+:1067E000000F00F0B481B8F1100F49D0E0E1B8F12A -+:1067F000300F45D0B8F1400F57D0D9E1B8F1B00F04 -+:1068000011D007D8B8F1800F7ED0B8F1A00F00F0FA -+:106810003E81CDE1B8F1C00F00F09681B8F1D00F04 -+:1068200000F0B481C4E1052F40F3BC81BBF1000F3F -+:1068300000F0BE819BF806309BB19BF80430002B22 -+:1068400000F0B681059A00970195137CD6F83407BD -+:1068500003F008030293594652464B462CF0A6D942 -+:10686000A6E1D6F8403593F93430002B00F0A08132 -+:10687000584651464A463B46009532F0A9DB97E11F -+:10688000052F40F38F81BBF1000F00F091819BF841 -+:106890000630002B40F08C81119B584600935146E6 -+:1068A0004A463B4632F052D982E1336893F895303C -+:1068B00023B996F87232002B00F07A8107F11803A1 -+:1068C000039330462C210AF10A02234600940194D6 -+:1068D000CDF808A01DF0ECD86AE10B2F40F36281DF -+:1068E000D6F868319B79002B00F062810D9B002B5C -+:1068F00000F05E81304605990A9A5346CDF8009023 -+:10690000019710F063DE53E10B2F40F34B810A9B9C -+:1069100030460E99059ACDF800A0CDF80490029764 -+:10692000FEF758FCD6F868319B7943B1304605999B -+:106930000A9A5346CDF80090019710F047DE96F87A -+:106940007232002B2ED199F80A3013F0010F29D0A2 -+:10695000304649463A4616F05DDF18BB059CA37DDC -+:10696000E27D43EA0223C3F3C7040E2C8CBF00234D -+:10697000012363B109F10C00A7F10C010322FBF321 -+:106980009DF678B143786BB18378A3420AD1336B1B -+:10699000186909F033FAC0B2844203D1D6F868010D -+:1069A0004DF0CEDF0F9909B10D4607E030460AF1F0 -+:1069B000100138F0F9DC0546002844D0AA79002AF5 -+:1069C00041D109F10C00A7F10C01D5F8D842D5F856 -+:1069D000DC82FBF373F6A26882460B2A07D12846B5 -+:1069E00005990A9A4B46009733F0B0DD0CE0336806 -+:1069F00093F8313043B10F2A06D1284605990A9AF7 -+:106A00004B46009734F072D9AB7CE3B198F85A301A -+:106A1000CBB1D6F86801514601224EF039D830B1D9 -+:106A200098F859301BB9013388F859300BE0D6F883 -+:106A30006801514601224EF02BD820B998F8593000 -+:106A40000BB188F859000E9A002A00F0B180DBF8EB -+:106A5000D8329B680C2B40F0AB804B4658460599CA -+:106A60000A9A23F05BDD5846002131F025DF3368B8 -+:106A700093F82F3023B1D6F834072EF04BD997E096 -+:106A8000DBF8E4325846997808F016F990E0012FC7 -+:106A900040F38880BBF1000F00F08A809BF806303D -+:106AA000B9F80050002B2BD13046119920F094DA20 -+:106AB0001198037E13F0020F13D002214EF0C0DABA -+:106AC000119B1B7E13F0080F0BD13046594622460E -+:106AD0000AF10A0300950194CDF80890039707F096 -+:106AE0006FFF0E9B002B63D0DBF8D8329B6813B18D -+:106AF000584631F02BDE5846032134F04BDC57E08A -+:106B000011990B695B4553D1304620F065DA119835 -+:106B1000037E13F0020F13D012214EF091DA3046AB -+:106B2000594622460AF10A0300950194CDF80890CF -+:106B3000039707F045FF304611994EF041DE37E0EC -+:106B400010214EF07DDA33E0012F2BDD30E0032FF2 -+:106B500028DDBBF1000F2BD09BF8043043B39BF82A -+:106B600006302BB30AF110000BF1BC010622FBF337 -+:106B7000E7F1E8B9119BD6F834070193594652461C -+:106B80004B460097029508F06BF911E00A99059CB5 -+:106B900002913046119952464B460097019410F0ED -+:106BA0000DDC05E03368D3F88C20136F01331367D5 -+:106BB00006980499002200F0B3D813B0BDE8F08F16 -+:106BC0002DE9F04F436899B0164689460493918B9E -+:106BD00096F82A30126880460292D9F810A00BB9B4 -+:106BE000059302E096F82220059296F82C00B0B9A1 -+:106BF00011F4006F13D0059A09EB4203B3F8AC20EF -+:106C0000B6F87E309A420AD1D8F80030D3F88C20FA -+:106C1000D2F8BC310133C2F8BC3100F082BC9AF822 -+:106C20000630C1F3802B0BBBDAF8E442237A6BB158 -+:106C300060B9BBF1000F09D199F8D230726A1341E3 -+:106C400013F0010F02D1504610F05EDBD8F800308F -+:106C50005B6B5BB1237E4BB196F82A3033B196F86B -+:106C600028301BB15046002121F094DE338C13F004 -+:106C7000040440F05684B38B03F4804373634BB930 -+:106C8000DAF8582040F2371302EA03032BB39AF8DC -+:106C9000603013B3059BB4630093404604994A46A1 -+:106CA00033464FF035DF08B122460EE0736B23B157 -+:106CB000D9F86C310133C9F86C31D8F8003093F849 -+:106CC0009530002B00F02D840122736B33B1D9F87D -+:106CD00068310133C9F8683100E0002296F82C30A1 -+:106CE0000BB1002708E0059909EB4103B6F87E10C7 -+:106CF000B3F8AC70A3F8AC10D8F8000090F8953059 -+:106D000013B1002A40F00D8496F82C50002D40F06D -+:106D10000081B6F87E20059B12F00F0C4FEA830E1F -+:106D200040F081800EEB0907F96E41B104982A46C4 -+:106D3000FFF3F6F7FD66C7F88C50C7F83051BBF18A -+:106D4000000F00F0E6807369F168FB66D8F8003048 -+:106D50007269DB6903919C681169D368908ACB18CA -+:106D600092681B189B1A09185B1AA34223DA04982D -+:106D7000214600F005D8F866002800F0D283736938 -+:106D8000006919699C689A8AC4EB0104091BA2185E -+:106D9000FBF3F2F07169FA6E08698B68C01A136927 -+:106DA0001B181361938A1B1A93828B8A049893820F -+:106DB0002A46FFF3B5F7D8F80030D8F82828DB6961 -+:106DC00003999B68AA489B1A5B1A063BC7F88C304C -+:106DD00071680822FBF3B4F050B1A648716806222E -+:106DE000FBF3AEF048B97368DB88B3F5407F04D19C -+:106DF000D9F8043043F0080303E0D9F8043023F055 -+:106E00000803C9F804309C4871680822FBF398F025 -+:106E1000D9F8083010B943F0200301E023F0200333 -+:106E2000C9F8083075E00EEB0904E16E11B9D0F82D -+:106E30008C2017E022F00F0227F00F039A4204D1B2 -+:106E400007F00F0301339C4510D02A460498FFF346 -+:106E500067F7D8F80030E566D3F88C20C4F88C507A -+:106E6000C4F83051136E013313665AE3B068D4F896 -+:106E70008C309842E9D8049B09EB0E0200900193F4 -+:106E800040468C3273680CF0ABD8049871692A467E -+:106E9000FFF346F7BBF1000F3BD1E36EC4F88CB0B3 -+:106EA0007361C4F86CB07369C4F830B11A69998A17 -+:106EB00002F118037360A1F11803B36096F829304A -+:106EC0003260F1602BB102F11E037360A1F11E0369 -+:106ED000B36096F82A3043B1736805990233736042 -+:106EE000B36886F82210023BB36032681378527898 -+:106EF00043EA0223B383736B5BB1B16B49B191F980 -+:106F00000E2073689B18736091F90E20B3689B1A6A -+:106F1000B360B36B73B11B7A042B03D14046314687 -+:106F20004FF0A4DEB36B1B7A0B2B03D140463146E6 -+:106F30004FF0B8DFBBF1000F40F04D83D8F80030C0 -+:106F400093F89530002B73D0DAF808309B7913F062 -+:106F5000010F40F005836BE010F4000F00F4E063D4 -+:106F600010D01B0A043B012B444A00F07F0004D8D8 -+:106F7000142300FB0323DA6814E0142300FB03232B -+:106F80009A680FE01B0A043B012B3C4A00F07F008B -+:106F900004D8142300FB03235A6803E0142300FBE6 -+:106FA00003F39A584FF4FA73B2FBF3F007E000F0E2 -+:106FB0007F034FF4FA7203FB02F3B3FBF2F0C0F36A -+:106FC00007238DF825300DF11B05C0F307438DF81D -+:106FD00024008DF826300127030E316805F10F00DB -+:106FE00018228DF827308DF82970FAF3C5F796F836 -+:106FF0002F30DBB19DF82B209DF82A3005F11904C4 -+:1070000043EA022343F400738DF82A3021461B0A19 -+:10701000062205F11F008DF82B30FAF3ADF7D8F8F2 -+:107020006C122046BC310622FAF3A6F7BB4601E0FB -+:107030004FF0000BD8F8003093F8953013B91C4688 -+:107040001A4602E00DF11B042D2273695B6A13F0EE -+:10705000400F15D013F0800F00F063820092D8F833 -+:107060003C0149463246234629F0F2DDB3E2C046F0 -+:10707000401E8600E0A60100481E86008418860097 -+:1070800031680DF15A07043106223846FAF374F7D5 -+:10709000316815AD0A3106222846FAF36DF73168DA -+:1070A0000DF14E04204610310622FAF365F796F8EA -+:1070B00029302BB1316812A818310622FAF35CF797 -+:1070C000B38B13F4807F03F4007305D1002B14BF3E -+:1070D00023462B46776704E074670BB9356701E0F8 -+:1070E00012AB33677468BBF1000F00F003813368A3 -+:1070F000F3662378AA2B23D16378AA2B20D1A37817 -+:10710000032B1DD1E378DBB92379CBB9637943B97C -+:10711000A379E179404641EA03210BF0D5DB50B178 -+:107120000EE0F82B0CD1A379E179404641EA032126 -+:107130000BF0CADB20B1A279E37943EA022500E033 -+:107140003589D8F8003093F89530D3B1DAF8E030CB -+:107150005BB9736BABB9DAF8582040F2371302EA27 -+:10716000030373B19AF860305BB1059A404601920F -+:1071700049465246334600950DF006DA002840F0A5 -+:10718000D081B36B6BB11B7A012B0AD0032B08D0D3 -+:10719000404604994A46334607F05EFC002800F05A -+:1071A000C081736F1B7813F0010F08D0D8F800303E -+:1071B000D3F88C20D2F8D0310133C2F8D031B36B80 -+:1071C00033B11B7A022B03D1404631464FF04EDDDE -+:1071D000726B22B996F82A3023B3144602E0B36BDF -+:1071E00093F90E4096F82A305BB1336802341A786E -+:1071F000597842EA012222F0800292B21A70120AF1 -+:107200005A707368581E03E063421B5C00F8013932 -+:1072100071690A699042F7D28B8A12191B1B0A61A5 -+:107220008B82326096F82F30BBB130684278037899 -+:1072300000F10A0443EA022343F4007303701B0ABB -+:107240004370214606221030FAF396F6D8F86C12F5 -+:107250002046BC310622FAF38FF69AF9103093B12A -+:1072600048F68E039D420ED13168726BDAF80C003D -+:107270001231003A18BF01220AF1180351F092DED0 -+:10728000002840F04E819AF830358BB148F68E03D5 -+:107290009D420DD13168726BDAF814001231003A58 -+:1072A00018BF01224B4606F013F9002840F039813F -+:1072B00071690A698B8A9B18CA68D21A2C2A40F213 -+:1072C000308100238DF829308B8A08692D22181807 -+:1072D0000DF11B01FAF350F6716996F82220CB8A62 -+:1072E00002F0070223F007031A43CA8296F8292006 -+:1072F000009110E1D6F814B02378DBF81070AA2BB7 -+:10730000C7EB040529D16378AA2B26D1A378032BD8 -+:1073100023D1E3780BBB2379FBB9637943B9A37914 -+:10732000E179404641EA03210BF0CEDA50B114E096 -+:10733000F82B12D1A379E179404641EA03210BF001 -+:10734000C3DA50B17269A91F7B18CBF81030938A49 -+:107350005B1A93821369F36628E0DAF8583013F069 -+:10736000200F0FD020469D490822FAF3E9F548B9CD -+:107370007269281D1169938A09181B1A1161938279 -+:10738000F16613E07269A5F10E00938A11691B1A68 -+:10739000938233890918116103F0FF021B0A43EA43 -+:1073A0000223F1660B73C3F30F234B73B36B6BB103 -+:1073B0001B7A012B0AD0032B08D0404604994A4679 -+:1073C000334607F049FB002800F0AB80B36B33B1C4 -+:1073D0001B7A022B03D1404631464FF047DC062290 -+:1073E000716FF06EFAF3C8F5F06E06220630316F59 -+:1073F000FAF3C2F5716996F82220CB8A02F00702EF -+:1074000023F007031A43736FCA821B7813F0010F2E -+:1074100008D0D8F80030D3F88C20D2F8D03101331E -+:10742000C2F8D0319AF8613093B199F8183013F05E -+:10743000100F0DD1F36E1A7B5B7B43EA022348F6F3 -+:107440008E02934204D073695B6A13F0100F68D008 -+:107450009AF86530BBB199F8183013F0100F12D1BB -+:10746000F36E1A7B5B7B43EA022248F6B4039A422E -+:1074700009D0263B9A4206D073695B6A002B02DB77 -+:1074800013F0100F4DD09AF8063023B9DAF8E42241 -+:10749000013382F82A3098F83238013388F83238CC -+:1074A0009AF91030EBB1F16E0B7B4A7B42EA032272 -+:1074B00048F68E039A4214D10B8A03F0FF021B0A8E -+:1074C00043EA0223B2680C3A93422AD8726BDAF884 -+:1074D0000C00003A18BF01220AF1180351F062DDD6 -+:1074E000F8B99AF8303593B1F16E0B7B4A7B42EADA -+:1074F000032248F68E039A4209D1726BDAF814001F -+:10750000003A18BF01224B4605F0E2FF48B9736903 -+:1075100096F82920009340464946736F1FF034D9EE -+:1075200059E0D8F80000436BA3B171692C4ACB8AAB -+:10753000D0F8904003F00703D25C2A4B04989B5C80 -+:1075400004EBC304636EA56E01336366FBF362F65E -+:107550004019A066049871690022FFF3E1F33AE054 -+:10756000D8F8303005991A8940468DF81B20130A47 -+:10757000120E8DF81C308DF81E200023B2698DF894 -+:107580001D30937DD27D43EA0223C3F3C7038DF8F8 -+:107590001F3009EB410393F8AC30D6F8801003F0AC -+:1075A0000F0301338DF828301CF0F6D9029A40B24F -+:1075B000030E8DF82000911FD6F880008DF8213041 -+:1075C0008DF822308DF8233012F04CFF10F0006F50 -+:1075D0007FF4C2ACEBE419B0BDE8F08FF7E38500AF -+:1075E000C4D2850098E085002DE9F04F0024A7B0B3 -+:1075F0008DF832408DF83B408DF838408DF8704062 -+:107600008DF83F409A4609939B8A0546212B0291AB -+:107610001746259412940D940A9224921B9450D9E3 -+:10762000DAF810901046494612F01CFF09F10602E4 -+:1076300003900492527899F8063043EA0223ADF899 -+:107640002C30C3F38103ADF82E30BDF82C30C3F3DA -+:10765000031203F44073B3F5407F14BF00230123EA -+:107660008DF83930BDF82E30ADF83020022B0ABF2E -+:10767000BDF830302346C3F3C0038DF83A303B7970 -+:1076800003F00303022B08D1BDF92C30002B04DAE0 -+:10769000BDF83030C3F3C00300E00023D9B29DF839 -+:1076A00039009DF83A308DF83B1000280CBF22229B -+:1076B000282203B1023201B10432099B9B8A934212 -+:1076C00006D22B68D3F88C20536E01335366A5E3A2 -+:1076D00004990B7903F001038DF83C3020B10023AD -+:1076E0001E468DF8403015E0BDF82C3013F4807F35 -+:1076F00001D0043105E013F4007F01D00A3100E02D -+:107700001031284637F0E6DD031E18BF0123064678 -+:107710008DF840309DF83C303BB90499284604313F -+:1077200037F0FCDD08B1012400E0002495F8C831F1 -+:1077300023B92B6893F82C3033B92FE0284639460B -+:10774000099A00230EF05CDB2B6893F83F300BB9ED -+:107750008DF8403054BBBDF82C3013F4807F05D138 -+:107760009DF83C3013B19DF840303BBB9DF839305B -+:1077700013B19DF83C300BBB2B6893F82C30002BD9 -+:1077800000F04C839DF84030002B00F04783B37924 -+:10779000002B40F043834FF0010B11E09DF83C308B -+:1077A0001BB9002C00F03A8300E03CB19DF8393061 -+:1077B00023B99DF84030002B00F030834FF0000BD0 -+:1077C0002B6893F895304BB346B39DF83C30D6F810 -+:1077D000DC405BB914F0010F00F02083049806F13F -+:1077E000C20104300622FAF3ABF314E0049804302B -+:1077F000FBF3A2F020B114F0080F00F00F830DE0AE -+:1078000014F0040F0AD114F0020F00F00783284689 -+:1078100004990EF061DA002840F00083099A136998 -+:1078200006331361938A063B9382049A02F118038C -+:1078300005939DF8393013B102F11E03059300231F -+:107840008DF83D309DF83A306BB3059B5A781B7824 -+:1078500043EA0221C1F3C0138DF83D307BB126B15C -+:1078600096F81935002B40F0D98295F8CF31002BCE -+:1078700000F0D482099A536A43F040035362844B68 -+:1078800001F007028DF832209A5C824B9B5C0D93CD -+:10789000C1F300138DF83830059B023305939DF832 -+:1078A00032308DF870309DF83D3023B9099A938AB3 -+:1078B000043B938206E002980999FBF323F1838A43 -+:1078C000043B8382099A059C938A12690793A41A40 -+:1078D0001B1B514602980693FBF39CF40499001B72 -+:1078E00008908B7DCA7D43EA0223ADF88E30BBF150 -+:1078F000000F2ED1079B284600933A4625AB10F087 -+:10790000F7DD002840F08A82BDF82C3013F4407F68 -+:107910003BD1BA7DFB7D049942EA0322C2F3C70240 -+:1079200028460A310E2AD4BF002201224EF05AD82E -+:10793000259030B92B68D3F88C20D36E0133D366F1 -+:107940006CE20369D3F8CC30C3F3C0138DF83F3039 -+:107950001BE0BDF82C3013F4407F16D09DF8393071 -+:107960009BB9259B8BB9BA7DFB7D284642EA032251 -+:10797000C2F3C7020A310E2AD4BF002201224EF000 -+:1079800031D82590002800F04982259B1C69D4F845 -+:10799000DC82BBF1000F23D19DF8393003BB9DF889 -+:1079A0003C3023B1BDF82C3013F4807F11D1A37982 -+:1079B000BDF82C201BB112F4807F0AD010E0A37C0C -+:1079C00002F44072002B14BF4FF4007300239A425C -+:1079D00006D02B68D3F88C20936D013393651DE29C -+:1079E00095F82D370AF1240A33B99DF83F1019B9DB -+:1079F000A3790BB10E4608E0284639461BF0CCDFD0 -+:107A0000C0B246B208B18AF80900A379FBB99DF863 -+:107A10003F30E3B9314620461CF000D820461BF029 -+:107A200055DF3946284610F04BD8014620460EF067 -+:107A3000ADDF9DF8403053B1A37C43B1E37933B15E -+:107A400098F805301BB92046012133F0A3DC95F8E6 -+:107A50002D3733B99DF83F301BB9259BD3F8FC3047 -+:107A600073B16EB1259AD2F8F810D2F8F43043F819 -+:107A70002160D2F8F830013303F00703C2F8F83080 -+:107A80009DF8393043B1B4F86200ADF8780040E0B9 -+:107A9000C4D2850098E08500A3792599002B35D0C4 -+:107AA0008A8FADF878204A6812F0400F20D09DF8F8 -+:107AB0003A30EBB1049B9B7D13F00F0F18D191F876 -+:107AC000DF30ABB18B7E13F0010F11D1BDF82C303C -+:107AD00013F4805F0CD012F4003F09D00D9A91F896 -+:107AE000D130134113F0010F02D028462DF0EEDE05 -+:107AF000BDF82C30259913F4805F15BF4B684B6897 -+:107B000043F4003323F400334B6002E0898FADF877 -+:107B1000781095F82D371BB9259BD3F8FC3073B13D -+:107B20006EB1259AD2F8F810D2F8F43043F82160FB -+:107B3000D2F8F830013303F00703C2F8F830259B80 -+:107B4000D3F87C1159B1D1F80836039801EB8302C0 -+:107B5000013303F03F03C2F80C06C1F80836A379DD -+:107B60005BB9A37C4BB19DF83C3033B9BBF1000F3E -+:107B700003D188F806B088F807B09DF83C30FBB117 -+:107B8000A379002B40F04A81A37C4BB1296804986B -+:107B90004E3110300622FAF3D3F1002800F03E8176 -+:107BA00004980430FAF3C8F650B92B6893F83E30C5 -+:107BB00033B9284604990EF08FD8002840F02E8162 -+:107BC000039ACAF814209DF83C308BB999F802202A -+:107BD00099F80130134399F800201A4308D0BB7C70 -+:107BE000FA7CD5F86001039943EA02224BF0DCD914 -+:107BF000DAF8142012F0006F26D012F4000F02F40D -+:107C0000E06310D01B0A043B012B964802F07F0270 -+:107C100004D8142302FB0303DA6817E0142302FBE1 -+:107C200003039A6812E01B0A043B012B8D4802F003 -+:107C30007F0204D8142302FB03035A6806E01423CE -+:107C400002FB03F31A5801E002F07F02864B1A6030 -+:107C500099F90330002B07DA2B68D3F88C20D2F87F -+:107C6000D8320133C2F8D83299F8033003F0300328 -+:107C7000102B07D12B68D3F88C20D2F8E0320133D7 -+:107C8000C2F8E0329DF83C30002B40F09780DAF8E3 -+:107C900014102B6811F0006FD3F88C2026D011F44B -+:107CA000000F01F4E06310D01B0A043B012B6D4868 -+:107CB00001F07F0104D8142301FB0303D96817E006 -+:107CC000142301FB0303996812E01B0A043B012BF8 -+:107CD000644801F07F0104D8142301FB03035968B1 -+:107CE00006E0142301FB03F3195801E001F07F01C2 -+:107CF00016293AD00CD80B2925D004D8022916D041 -+:107D000004291AD05AE00C2923D0122927D055E093 -+:107D100030293CD004D818292DD0242931D04DE069 -+:107D2000602940D06C2944D0482936D046E0D2F8AA -+:107D300070320133C2F8703240E0D2F8743201334D -+:107D4000C2F874323AE0D2F878320133C2F87832AD -+:107D500034E0D2F87C320133C2F87C322EE0D2F823 -+:107D600080320133C2F8803228E0D2F88432013305 -+:107D7000C2F8843222E0D2F888320133C2F8883265 -+:107D80001CE0D2F88C320133C2F88C3216E0D2F803 -+:107D900090320133C2F8903210E0D2F894320133BD -+:107DA000C2F894320AE0D2F898320133C2F898321D -+:107DB00004E0D2F89C320133C2F89C3225994B681A -+:107DC00013F4802F0BD09DF83C3043B9BBF1000F6A -+:107DD00005D1D5F8400104AA00F02EFA03E02846A8 -+:107DE00004AAFEF7EDFE049B1B7C13F0010F05D1E6 -+:107DF000259AD2F858310133C2F85831049B1B7CC4 -+:107E000013F0010F05D0259AD2F85C310133C2F886 -+:107E10005C31259B0398C3F864011FE02868436B1D -+:107E2000BBB19DF83C30A3B90999104ACB8AD0F870 -+:107E3000904003F00703D25C0D4B02989B5C04EB6F -+:107E4000C304636EA56E01336366FBF3E3F140196F -+:107E5000A066029809990022FEF362F727B0BDE8F8 -+:107E6000F08FC04684188600C8F40100C4D2850093 -+:107E700098E085002DE9F341089C05460E4617461B -+:107E80009846009407F0D2FA10F1170F06D1284651 -+:107E900031463A464346009408F0A2DABDE8FC8138 -+:107EA0002DE9F0410368054693F83F30D0F80C8087 -+:107EB00013B1B0F8267602E0FDF722F8074600225B -+:107EC0002869394602F086F85621286935F0A8DB82 -+:107ED000D5F888314000002BC5F8040506DA28697A -+:107EE000B22135F09DDB4000C5F80805A2212869C4 -+:107EF00035F096DB4000C5F8EC07284614F058D85A -+:107F000095F8CD313BB928694C2135F089DBC0F3B8 -+:107F1000C71085F8CD0128461EF0B0DD28463FF099 -+:107F200081DA002605EB8603D3F84C422CB12046BB -+:107F300020F060DF204620F053DD0136082EF1D11D -+:107F40002B6893F83F309BB1002205EB8203D3F8F6 -+:107F50004C0250B1037943B1D0F8D432DB8D1B040D -+:107F6000C8F8883121F07ED902E00132082AECD12C -+:107F7000284639460BF0CCD828467421B5F87A2526 -+:107F800024F028D995F8D13142F21072002B18BF95 -+:107F90004FF4BC622846822124F01CD92B6B95F843 -+:107FA000D111186908F0D4F901221346B5F87817F1 -+:107FB00028460CF085DA0123B5F87A170022284606 -+:107FC0000CF07EDAD5F8400127F0FADB2846FBF703 -+:107FD000C1FB2B685B6B5BB1B8F88836D5F86C02D7 -+:107FE0009BB243F00403A8F88836002119F0D8DECC -+:107FF0002846FBF71DFBD5F8841161B928461EF011 -+:10800000AFD80404C5F88441284602211EF0A8D840 -+:108010002043C5F884012B6893F8A130012B03D1CC -+:10802000D5F8400128F0B8DC284619F0E9DF2846E9 -+:108030000AF0D8DBB5F85C1728461EF06FDD28463D -+:1080400012F026DA424BEA68002185F84410C2F8A3 -+:10805000DC33012385F8A83185F8AA312B6893F821 -+:1080600038303BB14A1901314FF0FF33082982F80B -+:108070009538F7D100244FF44076314628461EF05B -+:108080006FD805EB4401B1F8203213F00F0F06D181 -+:1080900023F00F0300F00F021343A1F82032B1F8D0 -+:1080A000202212F0F00F06D100F0F00322F0F002CF -+:1080B0001343A1F82032B1F8202212F4706F06D1D8 -+:1080C00000F4706322F470621343A1F82032B1F817 -+:1080D00020321A0B06D11B0500F470421B0D1A4307 -+:1080E000A1F8202201340236042CC6D12B68284680 -+:1080F00093F94C100DF098DA2A68137E03B392F8C6 -+:108100002F30EBB1002605EB8603D3F84C426CB15F -+:10811000A3795BB12B6893F838302BB12846D4F89B -+:108120004C15002237F014DE0023E3710136082ECF -+:10813000E9D1002385F87232D5F834072CF0EADD56 -+:10814000D5F8680104214CF033DABDE8F081C0466F -+:108150008096980003681A6819B1012382F8AA3042 -+:1081600001E082F8AA1070472DE9F04717469846BB -+:10817000D2F8F030D278894603EB4203B3F8BE2040 -+:10818000B7F85630B7F85A100133D21A1205120D4B -+:1081900008EB02038B4207DD036842461B68244854 -+:1081A000596806F08BFF40E0C2EB0103C8EB030304 -+:1081B000A7F85A30BB784344BB7033E0F97809F133 -+:1081C0001000FAF3C1F6436AD7F8F01043F4806365 -+:1081D0004362FB78024601EB4301B1F8BE0007F1B0 -+:1081E0004406431CA1F8BE30C0F3C20504050121BA -+:1081F00000F007008140240D1485735D0B43735517 -+:10820000D7F8F010A7F85640D1F82C31FC789D6CC7 -+:10821000D86C084B04F007041B5DA84708F1FF3336 -+:108220001FFA83F8B8F1000FC8D1BDE8F087C04647 -+:10823000E0AB010090E085002DE9FF47138C054677 -+:10824000082B0F46164692F822A0D0F8008001D0E5 -+:10825000404623E04368126851F80390941F09EBED -+:108260008A03D3F8F800E0B9B3691B7903F003037C -+:10827000022B10D112F8033C13F0080F0BD009EBBE -+:108280004A02012382F81831D5F87822D2F8B430A6 -+:108290000133C2F8B430404639463246FEF790FC0E -+:1082A00014E14B6813F4803F16D1B3691B7903F0D6 -+:1082B0000303022B10D112F8033C13F0080F0BD06C -+:1082C00009EB4A02012382F81831D5F87822D2F856 -+:1082D000B4300133C2F8B430B3691B7903F003033F -+:1082E000022B35D1E17811F0080F1DD0D5F8782296 -+:1082F000D2F89C300133C2F89C30D2F8A030013360 -+:1083000011F0800FC2F8A03004D0D2F8AC300133A5 -+:10831000C2F8AC3001F03003102B20D1D2F8B030CD -+:108320000133C2F8B0301AE0A278637813432278A0 -+:108330001A43D5F8782205D1D2F8A0300133C2F81B -+:10834000A0300CE0D2F8A4300133C2F8A43006E02B -+:10835000D5F87822D2F8A8300133C2F8A830B6F8A0 -+:108360007E3013F00F0F40F09C801A09C3889A42A8 -+:1083700024D101230371D3181B051B0D0DF10A0431 -+:10838000C380BD6A07F11A0106222046F9F3F4F50D -+:10839000404639463246FEF713FC404621462A46FF -+:1083A0004DF006DA002800F09180B84240F08E804F -+:1083B00040464946524625F071DF87E0C3EB020391 -+:1083C00002F00F0741781A05120D8A4203D200EB22 -+:1083D00087039B6813B9B2F5006F0DD90022D8F856 -+:1083E00004007169FEF39CF4D5F87822D2F8C0300D -+:1083F0000133C2F8C03069E08A4234D3C1F10103CD -+:10840000D3189BB240464946524625F0DBDE09EBC5 -+:108410008A03D3F8F8404CB1736904EB8702936088 -+:10842000D6F880309364A3780133A3705246404657 -+:10843000494625F033DFD5F87832D3F8C820013229 -+:10844000C3F8C820A378002B40D095F8A333002BA5 -+:108450003CD1013385F8A333D8F80800A96B642216 -+:1084600007F0B4D832E0736900EB87029360D6F866 -+:108470008030936483780133837095F8A33343B9D4 -+:10848000013385F8A333D8F80800A96B642207F0FC -+:108490009DD8D5F87822D2F8BC300133C2F8BC3070 -+:1084A00014E0D8F8040071690022FEF339F4D5F81D -+:1084B00078322846D3F8DC2049460132C3F8DC2064 -+:1084C000012300935246013B26F03CD8BDE8FF87CC -+:1084D0002DE9F0471546937AD27A046843EA022AD6 -+:1084E0002B79074603F007064FF0000929E00B69D6 -+:1084F00060681A785B7842EA0328D7F87822936E8E -+:10850000013393660122FEF30BF4236893F8A12054 -+:10851000012A03D0C8F34123032B08E0204631464B -+:1085200022F062DA09F101031FFA83F9D1450AD07A -+:108530002369022103EB8603D868134B9B6B984792 -+:1085400001460029D3D1236893F8A130012B05D02F -+:108550002046314697F92C2022F046DAAB7913F009 -+:10856000020F0ED0002506E00120FEF3F5F06B1C93 -+:10857000DDB20B2D05D0E368D3F8703113F0010F95 -+:10858000F2D0BDE8F087C046E0A685002DE9F347AC -+:10859000D0F80090044601A9D9F800054CF09ADD06 -+:1085A00000263AE07B6813F4802F36D063684FF0E2 -+:1085B0000008FD58AA46D5F8F8205FFA88FE32B3C5 -+:1085C00091781379002918BF01261BB1002313717C -+:1085D000D3701CE0D9B1D3780133D9B2D1707B68A4 -+:1085E00013F4807F14BF628EA28E6423B2FBF3F279 -+:1085F00091420BD3D4F878224846D2F8C430514681 -+:108600000133C2F8C430724625F0ACDD012608F112 -+:1086100001080435B8F1080FCDD101A84CF062DD96 -+:1086200007460028BED136B9236884F8A36398684A -+:10863000A16B07F013D8BDE8FC87C04610B50368EE -+:1086400004465B7E6BB90749074806F037FD2046B4 -+:10865000FCF7C6FC0548034906F030FD2046FCF750 -+:1086600081FB10BD36AC01001CAC01002AAC01003E -+:108670002DE9F04FD0F800B089B0064607A9DBF825 -+:1086800000054CF027DD00220492E8E0039A5368CD -+:1086900013F4802F00F0E380DBF840315B6852F880 -+:1086A00003800023C146C2460593059ADAF8F830E4 -+:1086B000D7B223B1002388F8193188F8183198F817 -+:1086C0001831A3B198F8193100240133DBB2022B21 -+:1086D00088F8184188F8193109D9262388F81941F2 -+:1086E0003046009349463A46234625F02BDFDAF818 -+:1086F000D840002C00F0A9802378032B00F2A5803D -+:10870000DFE803F092025D7A3046494622460123B3 -+:1087100025F048DF94F8E750DDB1012D11D1E17863 -+:1087200009F11000FAF310F4014650B1DBF8003003 -+:108730002A46D868FEF3F4F2D6F87822D36B0133D8 -+:10874000D363002284F8E7203046214625F06CDE12 -+:108750007BE094F8E830312B08D92723009330468A -+:1087600049463A46012325F0EDDE6EE094F8E63006 -+:1087700023B184F8E65084F8EB5066E0A37823B187 -+:1087800094F8EB30013384F8EB3094F8EB30022BA3 -+:108790005BD1D6F8783230465A6E494601325A6675 -+:1087A000272300933A46012325F0CCDE01233046EF -+:1087B00049463A4623F010DF0123049345E094F83C -+:1087C000E920531C032A84F8E93004D9484621469D -+:1087D00023F0D0DE39E0B27CF37C009296F82E20B4 -+:1087E0003068019203993A4626F0E4D9D6F8782207 -+:1087F000136D0133136528E094F8EA20531C012A15 -+:1088000084F8EA3009D9D6F878223046536E4946C2 -+:10881000013353663A46012303E0304649463A465F -+:10882000002323F0D9DE10E094F8EC20531C3B2AFF -+:1088300084F8EC3009D9304649463A46002325F001 -+:1088400069D910B1042380F8E930059A0AF1040AC5 -+:108850000132082A059208F102087FF426AF07A822 -+:108860004CF040DC039000287FF410AF049B0A4AD0 -+:1088700013B11368013300E0049B074C13602368B5 -+:10888000012B04DD5846FFF7D9FE002323600020AA -+:1088900009B0BDE8F08FC046ECF40100D0F8AC039D -+:1088A0007047C046D0F8C0037047C046C0F8C01338 -+:1088B0007047C046D0F8AC331B68DB6918690A28DA -+:1088C000A8BF0A207047C04610B50446FDF332F633 -+:1088D000B0F5C05F05DD20464CF0F2DB20464CF0E1 -+:1088E000EFDB10BD02292DE9F0410646D0F8AC536C -+:1088F00001D0002401E000F575742B68D3F88C20BA -+:108900005368126C9B1822692361C2EB0302A369AE -+:108910009A4223780ED24BB9E26863699A4205D332 -+:108920000123237063680133636028E0E368013347 -+:10893000E36024E00027E7600BB3012904D1284657 -+:10894000023121F06BDB18E0022916D1A868D6F8B5 -+:10895000D01306F083DED6F8CC3373B12B6893F8CE -+:108960007430012B07D02869012134F0A9DD2A6871 -+:10897000012382F87430C6F8CC7300232370BDE85D -+:10898000F081C0462DE9F04F97B0DDF894B0D0F8F3 -+:10899000AC630023D0F8B0930C46074659463046E6 -+:1089A0000392DDF888A014931393129336F022DD1E -+:1089B0000399054601F001030093484621465246BB -+:1089C000239B1AF081DC1490002840F0FF82219A4A -+:1089D000032A0DD9042213A82099F9F3CDF2219B83 -+:1089E000072B05D9209A12A8111D0422F9F3C4F20D -+:1089F000139C129AB4F1000818BF4FF00108BBF1A4 -+:108A0000000F01D1D5F808B003998B1E472B00F257 -+:108A1000D982DFE813F0F900FE00010104016A00C9 -+:108A20007D008C00D7028E00D7029700D702070185 -+:108A30000A01480058007F0195010D011F014E01F8 -+:108A400054012002D7029900A000AD00B00033010C -+:108A50003601FC00D70236023A02D702D702D7020B -+:108A6000D702D702D702D702D702D702D702D7023E -+:108A7000D702D7026F0281028602E500EF00DA0218 -+:108A80009C02D702D702AC02AF02B802BB02BE0200 -+:108A9000C102C402D702D402C702D702D702D7024A -+:108AA000D7020C021302D9F83430002B00F08A826E -+:108AB0000DAC304607F56371224623F0BDD8504611 -+:108AC00021461022C3E0D9F83430002B00F07A821E -+:108AD00011AC514604222046F9F34EF2304607F518 -+:108AE0006371224623F0C4D81FE0219A0023052A8F -+:108AF0008DF8573040F22781384620990DF1570202 -+:108B000029F0CADF9DF8573014908AF800305CE2F3 -+:108B1000514630464CF042DE0146002800F01E82ED -+:108B200038469AF806202CF0B5D914904DE29B4BAC -+:108B300000E09B4B0093384629465246239B29F080 -+:108B400045DFF2E7974BF5E7D6F83407FFF7AAFEC3 -+:108B5000CAF8000039E2D6F834572846FFF7AAFED3 -+:108B6000844200F3268228462146FFF79FFE2CE22E -+:108B7000D5F850353BE03368DB691F692B79002B52 -+:108B800040F06381BC4200F31482C5F85045139C49 -+:108B9000184619467318D3F84C2222B1937913B1B1 -+:108BA000954218BF013004312029F3D1002800F08C -+:108BB0000C82C4EB070393FBF0F000217318D3F889 -+:108BC0004C224AB193793BB1954205D0D2F8503549 -+:108BD000834288BFC2F8500504312029EED1F4E168 -+:108BE00096F9A838002B01DA002300E00123CAF827 -+:108BF0000030EAE1B8F1000F01D0002301E04FF0AE -+:108C0000FF3386F8A838E0E195F83C30EFE7AB7920 -+:108C1000EDE785F83C80D8E1D6F82837E7E7C6F8D5 -+:108C20002847D2E1D7F8BC33E1E7C7F8BC43CCE131 -+:108C30006A7E049222B105A805F11A01F9F39CF1AC -+:108C4000049B1A1D239B93427DDB504604A9F9F334 -+:108C500093F1BAE1202C02D96FF01103B4E123990A -+:108C6000231D99426FDB2B79002B40F0EE802846C4 -+:108C70000AF10401224635F07FDFA6E195F83A308B -+:108C8000B5E7AB7985F83A8085F83B80002B00F09A -+:108C90009C812B79002B00F098813046294614F0F6 -+:108CA00005D830464FF000614FEAC8621AF082DF03 -+:108CB0008BE199F83830003B18BF012397E799F80A -+:108CC00038301C1E18BF0124444500F07E81304618 -+:108CD00022F0BCD810B96FF0150375E154B13046DD -+:108CE00001F082FA736A23F4C0137362002389F8D7 -+:108CF00038306AE1736A304643F40023736202231A -+:108D000089F83830D6F8AC38013B86F8A938FFF737 -+:108D1000DBFD5AE1219A032A15D9002C05DB3046E8 -+:108D2000214614AA36F0AADA05460DB12B795EE782 -+:108D3000149B13F11E0F40F04881CAF8005044E123 -+:108D4000239B072B02DC6FF00D033DE1032A01D1C9 -+:108D5000002703E0022A14BF00270127002C2DDB87 -+:108D60003046214614AA36F089DA054630BB149BFA -+:108D700013F11E0F22D1129B002B1FDD87F0010380 -+:108D800000932A462B463046139935F011DF0546ED -+:108D900050B96FF01A03149310E0C046991E830077 -+:108DA000A91E8300F92A83003046294636F0EADB03 -+:108DB000149018B13046294636F03EDB129B032B47 -+:108DC00000F00381022B00F00081149A3AB112F1F5 -+:108DD0001E0F40F0FA80002B40F0F780F4E0002BEB -+:108DE0001CDD2B79002B40F0F08033681B6F13F0F3 -+:108DF000030F02D06FF00803E6E0AA7922B13046F3 -+:108E0000294636F0F1D990E66B7E30460092019209 -+:108E1000294605F11A0230F0ABDDD6E06B79002B64 -+:108E200000F0D3803046294636F02AD8CDE015B17F -+:108E300095F96435DBE6CAF800501FE0F5B1002C67 -+:108E40001CDB012C1ADC2B7913B16FF00403BBE09F -+:108E500085F86445B9E099F818307BB199F82F305E -+:108E600063B199F830304BB999F83F3033B9D6F83F -+:108E700068319B7913B9B6F81637B8E66FF001037D -+:108E8000A2E0336893F83030B1E6336893F83030BD -+:108E9000434500F09A80304636F072DC0446B8F163 -+:108EA000000F05D043791BB13046214635F0E8DF8D -+:108EB0002146304688F0010236F06ADC0446149000 -+:108EC000002840F082803368012283F82F20B8F117 -+:108ED000000F03D0D6F8403583F83420336830468D -+:108EE00083F8308012F06CDF86F8DD41304606F002 -+:108EF00015F86AE0BAF80200FAF3AEF1E8B99AF8A8 -+:108F00000400BAF802109AF800209AF80130009094 -+:108F100028462BF011DB08E6D6F83437B3F8A43333 -+:108F200065E624B9D6F83437A3F8A4434DE0D6F863 -+:108F30005C01A1B23DF032DA10B96FF0130343E0E7 -+:108F4000D6F83437BDF84C10A3F8A4133DE0BBF1BC -+:108F5000000F03D09BF80430022B02D06FF01D03EA -+:108F600032E03846DBF8101029F06ADDDDE597F8CD -+:108F7000F0333CE6E3B287F8D53387F8F033384670 -+:108F800029F024DC21E0D7F8E83330E6C7F8E843DD -+:108F90001BE0D7F8EC332AE6C7F8EC4315E097F866 -+:108FA000D43324E6D6F86C32D3F8D432DB8D9C422D -+:108FB00002DD6FF01C0307E0A7F8C84305E0B7F82F -+:108FC000C83314E66FF016031493149817B0BDE875 -+:108FD000F08FC0462DE9F7430F699146D0F830274E -+:108FE0000E46136897F948104FF4887401FB043457 -+:108FF0009369054606EB0308D4F80431013BC4F835 -+:109000000431D369013BD361002386F8DF3096F841 -+:10901000781101222CF006DAB368284623F4F043D5 -+:10902000B3603146032221F03BDED4F8043143BB68 -+:10903000D7F8CC3013F4806F23D1B5F8263603F47B -+:109040007043B3F5805F14BF40234423F9582B6865 -+:1090500093F838301BB128462CF00AD811E081F87B -+:10906000DF30EB6AB3F924305BB195F8763243B95F -+:1090700001214022009385F87612284613461AF003 -+:10908000A3DD002388F8C83088F8CA3088F8CC30CF -+:10909000C8F8D030B9F1000F09D1284631464FF653 -+:1090A000FF7200232CF0B8D80028F6D103E0284640 -+:1090B00031462CF071D8BDE8FE83C0462DE9F0435F -+:1090C0000568064687B028468946174698461DF02B -+:1090D0008DDE10B128461DF081DE284639464CF061 -+:1090E00077DC044698B1B268A86894F8783102B188 -+:1090F000527900923946072207F000D8D5F8440883 -+:1091000094F8781107F0E2D8002384F878310E9BA8 -+:109110002846029300230393049331460B223B46D7 -+:10912000CDF80090CDF8048013F0F8DC07B0BDE86E -+:10913000F083C04670B5114686B0054616464CF021 -+:109140002DDB044608B390F8DF3023B128462146D2 -+:109150000122FFF73FFF20464CF0A6D8E3681BB181 -+:10916000284621463EF08ADE002203230092019326 -+:10917000029203920492284621690532334613F085 -+:10918000CDDC284621464CF01BDB06B070BDC04646 -+:109190002DE9F04F0668D0F8D022D0F8D81297B059 -+:1091A0000746D0F8E8B230460691079220F09AD9E7 -+:1091B000069BB068196806F051DA384602212FF094 -+:1091C0007BDBF7E1D6F8D83603EB82035D686C8E63 -+:1091D00004F47043B3F5805F14BF38233C2356F882 -+:1091E000039004F44063B3F5406F28D1336893F8DB -+:1091F000463013F0030F15D0D6F85C01D9F80410EF -+:109200003CF07CDA10F0080F0CD199F8EC304BB13F -+:10921000D9F80030022B12D1D6F8FC349B7813F029 -+:10922000020F0CD02046F9F3FDF70E2894BF4FF43F -+:1092300000534FF4805340F4306003439CB2D6F89F -+:109240005C0121463DF0AAD8002800F0AE81688E6E -+:10925000F9F3E8F70446688EF9F3E4F744F4306470 -+:109260000E288CBF4FF480504FF400500443A1B23D -+:1092700038462EF0D5DB002800F09781D7F8E83289 -+:10928000002B78D0D3F8DC30002B74D04FF00001E5 -+:10929000A7F85C1095F8AA004FF00C0800FB08B086 -+:1092A000EA8814A982F08002C2F3C0121C30FAF3DB -+:1092B0001FF1BDF850200DF1540AA7F8622095F86F -+:1092C000AA00514600FB08B02030FAF36FF1159B5D -+:1092D00033BB95F8AA1013AC01FB08B1042224316A -+:1092E0002046F8F349F620469A490422F8F328F676 -+:1092F00048B995F8A920A2F10803DBB2022B40F28D -+:1093000054818DF84F2020465146FAF34FF1024622 -+:1093100030B90090CDF8048095F832300293FAE02D -+:10932000159B8D4913F0040F1CBF43F002031593E6 -+:10933000159B304613F0020F1CBF43F00103159339 -+:1093400015AB00930423019301230293BB68002211 -+:10935000039313461AF024D80022072301920093A6 -+:1093600095F8AA3030460293039204923946183297 -+:109370002B4613F0D3DBB5F8623013F0100F0FD08B -+:10938000BA6D40F2371302EA03034BB9734B1A78F4 -+:1093900032B901230092019395F832300293FCE038 -+:1093A0002846F9F3C9F218B100230222009327E0FE -+:1093B0003B6D002B32D0336893F83030002B2DD129 -+:1093C0001C46984609E0796D284641440622F8F388 -+:1093D000B7F508F1060818B10134FB6C9C42F2D3D2 -+:1093E0003B6D012B03D1FB6C9C4206D316E0022B94 -+:1093F00014D1FB6C9C420DD210E000230093032299 -+:10940000019295F832200393029204933046394634 -+:109410001722C7E0002304220093F1E7336893F892 -+:10942000953083B1D6F84C35012B09D1284606F585 -+:10943000AA610622F8F384F5002840F0B68002E025 -+:10944000022B00F0B28095F9344074B9D6F85C0173 -+:10945000698E3CF037DE40B105230094019395F806 -+:109460003230039402930494D0E7B7F862306BB1C2 -+:10947000BA6D40F2371302EA03033BB13046394676 -+:109480002A462EF0EFDC002840F08F80D9F800301B -+:10949000022B0AD199F815203AB9FD33009305F152 -+:1094A000380009A90123019214E0336805F138005E -+:1094B00093F8463009A913F0030317BFD7F8CC304F -+:1094C0001A46C3F3003383F001020192FF23002206 -+:1094D0000093134647F010DE336B09F1500493F804 -+:1094E000EC1039B16B8E03F44063B3F5406F14BFD9 -+:1094F00014212821204647F0A7DDD6F86036002247 -+:1095000009A821469B7847F039DD024630B9009022 -+:109510000923019302920392049277E79DF8382081 -+:1095200096F838379A4240D195F93430C3B96A8EEB -+:10953000304602F47042B2F5805F14BF022201226D -+:1095400005F138012EF032DA024648B90A230090BC -+:10955000DFE7C0460CA7010017738600ACF40100DA -+:10956000336893F8303053B3294630464CF016D95F -+:10957000014620B3037E13F0020F06D0436813F4B4 -+:10958000805202D10D230092C3E7D1F8F030B3B17D -+:1095900000220F230092019302920392049230461C -+:1095A000394617322B4613F0B9DAD6F8DC36013BD0 -+:1095B000C6F8DC36D6F8DC26002A7FF403AED6F8EF -+:1095C000DC46FCB1069B00219977D6F8DC26D6F85C -+:1095D000D836013A03EB8203C6F8DC26069A9C686B -+:1095E0005368012B0AD000910191029103910491DB -+:1095F000304639462022234613F090DA384630F0C0 -+:109600005FDF29E00799FA7991F934304AB1384699 -+:1096100001212246D3F1010338BF00232EF034DEAE -+:1096200009E038460121D3F1010338BF002300923D -+:1096300001922EF063DF97F91030022B03D1F86806 -+:1096400000214FF08FDF96F87532384623F004037F -+:1096500086F875322EF000DF17B0BDE8F08FC046F7 -+:109660002DE9F04F062989B007460D4692469B46E4 -+:109670009DF848900468D0F8D86246D061BBB9F133 -+:10968000000F03D12046394636F090DA94F8723252 -+:10969000002B3AD0D4F8000507A94BF01BDD03E0FE -+:1096A0001B7E13F0020F30D107A84BF01BDD0346E1 -+:1096B0000028F5D151E0236B186906F09FFBD7F81D -+:1096C000D4325B8E834220D020462AF005DFD4F8C6 -+:1096D00034072BF01FDB18E0B368093B012B14D8CB -+:1096E000204611464CF05AD810B10C214BF0A8DCA2 -+:1096F000022D07D0A068316805F0B0DF052D01D03C -+:10970000012D02D14FF0010801E04FF00008139B3A -+:109710000095CDF804B00293336C20460393736C2C -+:1097200039460493B9F1000F0CBF072209225346B2 -+:1097300013F0F4D9B8F1000F13D0052D01D0022D8C -+:1097400007D1B27F337F9A4203D2384630F0B8DE79 -+:1097500007E03846FFF71CFD03E07368032BAAD12E -+:10976000D3E709B0BDE8F08F00487047F0B00100C2 -+:109770000048704710B2010010B5836F40F2EE222E -+:109780001C6A044B94219C4208BF4FF4166234F0CB -+:1097900061DA10BD50200800816F10B50831044611 -+:1097A00032F064DDFFF7E0FF0146204632F03EDD97 -+:1097B00010BDC0462DE9F04104460D469046BDF867 -+:1097C00018E09DF81C701E4633B18368DA6A02EB1C -+:1097D0004102938BFB1893834FF6FF739E4503D092 -+:1097E000A821724634F036DA04EB8503D868084BBA -+:1097F000414632465B6A9847002807DA36B1A368CB -+:10980000DA6A02EB4502938BDB1B9383BDE8F081A0 -+:10981000E0A6850010B507490446406EF9F3D8F07C -+:10982000034620B9606E0449F9F3D2F003461846A6 -+:1098300010BDC04649A801000AAA860070B50D46B1 -+:109840000669144608460A220021F8F3F9F36B88EA -+:109850001C43F36C6C8013F0200F03D02B8843F46F -+:1098600080632B80B16F42F250030A8C9A4206D17A -+:109870004B8C052B03D86B8843F004036B8070BDC1 -+:109880004FEA810210B513188E468168DB6F5218BB -+:109890008367936B0B6390F8EB3063B190F8E8301B -+:1098A0004BB94FF40051006EBEF1000F0CBF0A46D9 -+:1098B000002201F0B7DA10BDB1F1FF3F2DE9F04110 -+:1098C00004460E4605D1836F596A09B90E4600E079 -+:1098D0009E6994F8E9701FB92046394632F0FCD9E8 -+:1098E000206E01F0FFDB80B1002504EB8503D86812 -+:1098F00010B1254B9B6898470135062DF5D1E368DB -+:109900001BB12046002132F033DA94F8E8203AB156 -+:10991000A3680022DA612046032133F069DB30E0DE -+:10992000206E46F0040184F8EA2001F08BDAA06F83 -+:10993000012184F8EA1018B1406A08B106F034F940 -+:10994000204632F0EDDAE26E206ED2F8E0310121ED -+:1099500023F02003C2F8E031FCF31EF3002120467F -+:1099600032F0BAD9204633F035DC2046012133F0FD -+:1099700009D8A2680023D3611FB92046022132F022 -+:10998000ABD9BDE8F081C046E0A6850070B50121E5 -+:10999000044634F0A3D9206E01F0DAFA2046002103 -+:1099A00032F09AD9204633F0F5DD054630B1204635 -+:1099B000002134F093D96FF0080005E020464FF005 -+:1099C000FF31FFF779FF284670BDC04673B50469C3 -+:1099D000054620460E46FFF7DFFEA36F3146586A64 -+:1099E00007F050FC2A68012382F87430204632F0D8 -+:1099F00075DBA36F2046998A33F008DFA36F2046FA -+:109A0000D98A33F0F1DE204694F8861032F0F6D889 -+:109A1000A36F204652219A8B34F01CD9A36F50219A -+:109A2000DA8B204634F016D9204632F079DB204616 -+:109A3000FFF7A2FE032300932046042108220023FF -+:109A400033F0E8DA204631F0A9DE7CBD10B50469B8 -+:109A50004FF440412046002233F0CADAD4F8F830FF -+:109A60001B691BB1204631F099DE02E0204632F03E -+:109A700051DCE26C206E02F00202002A0CBF11469B -+:109A80004FF400710A46002301F07CDA10BDC04695 -+:109A900070B5836804461B6893F82050F5B901211E -+:109AA00034F01CD9206E01F053FA2046294632F0DA -+:109AB00013D9204632F02EDCA068D0F848381B7845 -+:109AC0000BB132F059DAA36F586A06F05FF8A36859 -+:109AD00084F85E501A68012382F8203070BDC046B9 -+:109AE00070B5054690F89000002846D0AB6F002175 -+:109AF00085F89010586A06F05DF8AB681A6992F81C -+:109B0000EA305BB1D36ED3F8202140F2044302EA7D -+:109B10000303B3F5806018BF012002E0106E01F06E -+:109B200019FA68B10024AB6F85F8EB4085F8EA407C -+:109B3000586A214606F038F8A86832F067D91BE069 -+:109B4000286E01F0CFDA044680B1EB6ED3F82031F5 -+:109B500013F0010F02D0284633F0F0DEAB689868AE -+:109B600001F020FF0446284634F0D6D895F8E810D6 -+:109B700011B9284634F0B2D8204670BD70B50546FC -+:109B800090F8900050B3AB681A6992F8EA305BB174 -+:109B9000D36ED3F8202140F2044302EA0303B3F565 -+:109BA000806418BF012403E0106E01F0D3F904466D -+:109BB000AA6814B1002313620CE0906805F08ADDF6 -+:109BC0002846214632F088D895F8E83013B928465F -+:109BD00032F0A0DBAB6F586A06F0B0FC70BDC04637 -+:109BE0000121836F10B580F890100446586A05F083 -+:109BF000E1FF2046022132F06FD8A368986805F093 -+:109C000073DD002010BDC0462DE9F34186680627AC -+:109C100033680DF10204DB6905461B6AD0F86C80DD -+:109C2000C6F8AC3830493A462046F8F3A5F16B6CDB -+:109C30002E48214603FB07003A46F8F39DF1042322 -+:109C4000C6F8AC38013B86F8A938A86821F0FED8E0 -+:109C500008B93C4604E0D6F8AC389B0001339CB20E -+:109C6000D5F8B8700026F05D04F0FF01201880B22E -+:109C7000421E02F0FF0341EA032102F48072C4F3A2 -+:109C800000231A43330243F4004301369BB2062EED -+:109C9000A8F840350446A8F82015A8F82C25A8F8FF -+:109CA0004035E0D1284698217A7833F0D3DFD5F8D3 -+:109CB000B83028469A219A7833F0CCDFD5F8B830FE -+:109CC0002846DC781A789C2142EA042233F0C2DF6D -+:109CD000D5F8B83028465C791A799E2142EA0422E8 -+:109CE00033F0B8DFBDE8FC8113AE010020ED0100C8 -+:109CF0002DE9FF41056907469221284633F090DCA3 -+:109D0000400080B2A7F8420000282FD04FF0000892 -+:109D10000DF101060F213046154A4346F8F3D4F100 -+:109D2000686E3146F8F354F660B13146686EB7F8A4 -+:109D30004240F8F321F604EB480482B2214628465B -+:109D400033F088DF08F10108B8F1770FE0D1686ED1 -+:109D50000849F8F33DF648B1686E0649D5F8F84071 -+:109D6000F8F30AF62081284631F074DFBDE8FF8160 -+:109D7000AEAC8600177C86002DE9F041056986B0FF -+:109D80004FF0FF318A4A80462846EC6E33F030D9D6 -+:109D9000D5F8F8302846196832F00CDBAB6D3BB1D2 -+:109DA0004FF00303A4F8B4364FF0FF03A4F8B8361D -+:109DB000EB6C13F0010F09D02B6D286E13F0800FA0 -+:109DC00001D0032100E0012101F070F94FF0FF31D3 -+:109DD000C4F828112846774A33F00AD9764E03E0B2 -+:109DE0000A20FCF3B9F40A3ED4F8283113F0010F2D -+:109DF00001D1092EF4D14046D4F82831FFF726FED0 -+:109E0000D5F8F4302BB92B6E9A6A40F294539A42EB -+:109E100013D1286E694B826BD318012B07D94AF6F0 -+:109E2000E6039A4203D04AF6E5039A4205D1082395 -+:109E300000212822009301F029D800210A46286E2B -+:109E400001F008D8FFF794FC0146284632F0EED91D -+:109E50002846FFF7D9FE4FF48033009328460623A7 -+:109E600098210DF10E0232F021DDD8F8003093F880 -+:109E70003830D3B1404620F0E9DF012815D1002366 -+:109E80001E461F4605930AE04FF4C023009339464F -+:109E9000284605AA042332F02FDD01362437D8F8EE -+:109EA0000030DB691B6A9E42EED3284680210822DF -+:109EB00033F0D0DE28465C210A2233F0CBDE4FF0AF -+:109EC00080733F4AC4F8003128463E4933F090D8A9 -+:109ED0004FF00043C4F8883103F10243C4F88C31D9 -+:109EE0004FF48043C4F8283103F5404363620121F5 -+:109EF000284633F06BD8286E01F070F883B2A8F8CA -+:109F000018001621A4F8A8362846B5F8442033F0E6 -+:109F1000A1DE2846C021B5F8542033F09BDE284648 -+:109F2000C221B5F8562033F095DE274B2846C4F8F9 -+:109F30006031D4F86031B5F888304421C4F8643118 -+:109F4000224BB5F88C20C4F86031D4F86031B5F8F4 -+:109F50008A30C4F8643133F07DDE28464621B5F8F6 -+:109F60008E2033F077DEB4F888361B051B0DA4F87D -+:109F700088364FF00103A4F89C360023C8F8483017 -+:109F80001C4605EB8403D86810B1114B5B689847F9 -+:109F90000134062CF5D10E4CE868236D9847E36E2A -+:109FA000E86898474046FFF7A3FE06B0BDE8F08199 -+:109FB000040400040204020449420F001D57FFFF7D -+:109FC00000000240000006400600020007000200F8 -+:109FD000E0A685002DE9F04790F8E97004460E46AA -+:109FE0009046856817B9394631F076DEA86805F0E5 -+:109FF00071DB06F47041B1F5805F14BF00210121CF -+:10A0000081462046FFF73CFCA36F3146586A05F0B5 -+:10A01000F1FEA36F586A05F0D3FD2846FFF7ACFEAA -+:10A02000B8F1000F04D0012120460A4633F04ED883 -+:10A0300028463146FFF7CAFCA868494605F05EDBB2 -+:10A04000D4F8D43043F00403C4F8D4300123C4F866 -+:10A05000D0301FB92046022131F03EDEBDE8F08746 -+:10A06000816810B50B680446D3F88C20D2F8B43060 -+:10A070000133C2F8B4300A6992F8EA3063B1D36EA2 -+:10A08000D3F8202140F2044302EA0303B3F5806FC2 -+:10A0900014BF0020012006E0106E00F05BFFD0F13D -+:10A0A000010038BF002020B120464FF0FF31FFF7FC -+:10A0B00003FCA06831F0AADEA0681CF005DD10BD2D -+:10A0C000D0F8EC1010B5044631B100680C22FCF356 -+:10A0D0000FF60023C4F8EC3010BDC046D1F8CC30E8 -+:10A0E00073B543F40053C1F8CC3005460C4635F047 -+:10A0F00049DA0646002873D1B5F8822144F22133AB -+:10A100009A421AD00E3B9A4217D007339A4214D083 -+:10A1100010339A4211D0143B9A420ED007339A4220 -+:10A120000BD010339A4208D025339A4205D0AB6B3E -+:10A130005B7D13B96FF00B0652E02B6B93F8EC309C -+:10A140000BB91E4608E0B5F8263603F44063B3F5B4 -+:10A15000406F14BF142628262B6893F8463013F05E -+:10A16000030305D0D4F8CC30C3F3003383F00103EC -+:10A170000093284633462146022234F095DB0646FA -+:10A1800070BBD5F84C01214645F058D9C4F8F0020F -+:10A1900010B96FF01A0623E0A379D3B194F8F53221 -+:10A1A000312B11D82B681B7E2BB1284694F8F41262 -+:10A1B0000C4A1FF03BD9D5F84C0194F8F41245F045 -+:10A1C00081D8322384F8F43294F8F53284F8F432EA -+:10A1D00006E0D5F84C0104F53D7145F037D8064648 -+:10A1E00030467CBD329E850070B505460026AB1911 -+:10A1F000D3F84C425CB1A3794BB163791BB12846CB -+:10A20000214634F03DDE2846214635F015D9043686 -+:10A21000202EECD170BDC046F0B50E4649691569D7 -+:10A22000908A0A68002A01DA821831D44C6813191E -+:10A2300083422DD8B36801F1080C0CEB040705EB41 -+:10A24000020E6BB9184608E010F80E3010F80C201A -+:10A25000C15D134099421BD10130A042F4DB19E0EB -+:10A26000012B15D12B18C4EB03050DE010F80E30AF -+:10A2700010F80C20C15D1340994203D10130A04277 -+:10A28000F4DB07E00EF1010EAE4501D80020F6E741 -+:10A29000002000E00120337B0BB180F00100F0BD15 -+:10A2A000036870B504465868A36A0D46164623B97C -+:10A2B0009021FCF30DF5A06270B1A06A0123AA8A77 -+:10A2C00003607F3382604660C360296910309A4220 -+:10A2D00028BF1A46F7F350F670BDC046684683693A -+:10A2E000416920300BB5203803695A4651460EB4F7 -+:10A2F0004A46414606B4C36882684168FEB40368B2 -+:10A30000C269EFF303810EB48269EFF3058106B4ED -+:10A31000034801680029FED06846884714B000BD94 -+:10A32000C4A300000A49084202D062B6C9430840EB -+:10A330000849084202D061B6C943084006490840AE -+:10A34000002803D005490A6802430A6070470000EC -+:10A350000000008000000040FFFF000000E100E07E -+:10A360000A49084202D072B6C94308400849084267 -+:10A3700002D071B6C943084006490840002804D0FD -+:10A3800005490A68C04302400A6070470000008027 -+:10A3900000000040FFFF000080E100E00249096882 -+:10A3A0009022885870470000D0A300000249096835 -+:10A3B0009C22885070470000D0A30000DDBAADBBDE -+:10A3C000000000000000000000000000000000008D -+:10A3D000000000000000000000000000000000007D -+:10A3E000024A11681060081C70470000C4A30000F6 -+:10A3F000024A11681060081C70470000C8A30000E2 -+:10A4000003490860034801680029FED08847FEE739 -+:10A41000BCA30000C8A300006348644900220A509E -+:10A420000168634A0A40634F0F403F4232D1002324 -+:10A4300098469A46604A0A401821CA405F494358E4 -+:10A440005F4C1C405F4DAC4204D180465E4D4519C7 -+:10A45000A9460EE05D4DAC420BD182465A4D4519DE -+:10A46000AB460F241D1C2340594C25402D0A2B437D -+:10A470009C460023984501D09A4504D1554BC018FD -+:10A48000013ADCD105E05046004202D0404600428D -+:10A4900029D1FEE7FC2141580A680F2313400F2BF6 -+:10A4A000F1D0012B01D00431F6E708314A4B1340BB -+:10A4B0004A4CA34206D100F0BBF8804600F0C4F835 -+:10A4C0008146E9E7464CA342E6D10B1F1B68454C89 -+:10A4D00023401824E3409C4600F0AAF8824600F08E -+:10A4E000B3F88346D8E74049212242502E4A3F49DB -+:10A4F0008958FF23194219D051683D4B194215D094 -+:10A5000011683C4B1940D36A10E0A3420ED0C046FC -+:10A510000CE039498958194208D0384989581940FE -+:10A520009942FAD12B4B11691942FCD049463F425E -+:10A5300004D19823CB581024E34001E0304BCB5892 -+:10A540001C242340002B01D000F08CF840462D49FC -+:10A55000086048462C49086050462C49086060460F -+:10A560002B4908602B490F602B4D2C490D60043D91 -+:10A57000AD46009DEC431023DD41AC4201D081B0DB -+:10A5800009E0240CA400264D2C606B461B1B254DB6 -+:10A590002B60043B9D4624482449002204C081428C -+:10A5A000FCD810F07BF8FEE700000018140600004D -+:10A5B000F8FF0000000000F00000000FFC0F00009A -+:10A5C000F08F0000A0820000000F0000E08000007B -+:10A5D000007000000010000000FF0F00002A0800BB -+:10A5E000000E0800000000FFE0010000040600006B -+:10A5F00000003800FFFF0000180600000C060000F5 -+:10A6000008040000D0A30000D4A30000D8A30000D9 -+:10A61000DCA30000CCA3000000C00300E8ED0100B3 -+:10A62000F0ED0100ECED0100A8F40100F0F80100EC -+:10A6300008680F2204310240052AF9D1014A10406E -+:10A64000F746000000F0FFFF08680F2204310240C7 -+:10A65000052AF9D180221042F6D0014A1040F7466F -+:10A6600000F0FFFFFEE7000010B57146034804F05C -+:10A6700025FD40F2E370FFF7C3FE10BD8E1F86007C -+:10A6800010B5002128220446F7F3DAF40A4B2360C0 -+:10A690000A4B63600A4BA3600A4BE3600A4B2361D9 -+:10A6A0000A4B63610A4BA3610A4BE3610A4B2362C5 -+:10A6B0000A4B636210BDC04600000000EBEC0100D5 -+:10A6C000ECEC0100A8F40100A8F40100F0F801008E -+:10A6D000F0F80100F59D0200F89D0200BE24030081 -+:10A6E0002DE9F04399B00CA8FFF7CAFF0C9B0D9918 -+:10A6F000DFF8DC91C91A0F9D0E9BD9F80060ED1AA6 -+:10A70000119C109B06F5A0566048E41A76180B9130 -+:10A7100004F0D4FC0B9905F57E73761907333619CE -+:10A7200001F57E729B0A019404F57E740732009352 -+:10A7300007340523A40A920A039355482B46029432 -+:10A74000DFF8848104F0BAFC524BD8F80040196855 -+:10A75000D9F80050C4EB010303F57E7001F57E7259 -+:10A7600007300194039504F57E7405F57E75800A23 -+:10A77000073207340735920A0090A40AAD0A46480A -+:10A780000294049504F09AFC444B45481968D8F8A3 -+:10A790000030C91806F57E7301F57E7207339B0AF7 -+:10A7A0000732920A0093334604F088FC3D4B3E4842 -+:10A7B000196804F083FC3D4B1F683D4B3A689A4290 -+:10A7C00003D03C4804F07AFC24E0179705E0326897 -+:10A7D000374B9A4205D1331D1793179E16AB9E42F5 -+:10A7E000F5D3354BC7EB06001A6817ABC7EB03016F -+:10A7F000C3EB0204C6EB02050092019102910390A3 -+:10A80000049039462D4832460594069407950895DC -+:10A8100004F054FC2A4C2068002834D0C588F8F392 -+:10A820009FF12368013D5C894FF4806104FB05F6CC -+:10A83000443405FB04F406F57E73073393FBF1F310 -+:10A84000009304F57E73073393FBF1F30246029302 -+:10A85000294633461B48019404F030FC1A4B0F4A3A -+:10A860001B681268C6EB03069B181B1B03F57E7161 -+:10A8700006F57E720731890A073200911348314686 -+:10A88000920A04F01BFC19B0BDE8F083E11F8600BA -+:10A89000F01F8600C82600002E208600A426000097 -+:10A8A0007220860090260000AC208600F4F401009F -+:10A8B0004B415453C6208600F8F40100E92086007D -+:10A8C000BC260000662186008826000092218600B2 -+:10A8D000CC2600000D4B10B51A680D4CD2F814169A -+:10A8E000D2F8143699420B4B18BFD2F814162268CE -+:10A8F0001B68C2EB0100984201D2002004E0B0FBCB -+:10A90000F3F003FB0023236010BDC0469C2600002B -+:10A91000E4260000C82500002DE9F04301688FB04F -+:10A92000022907461AD15A4B5A481A680023536124 -+:10A93000046814F4805F11D0574B584A1960C169FC -+:10A94000043B196013680423136024F4805343F418 -+:10A9500000530360524804F0B1FB96E03B680C2BB7 -+:10A9600014D14C4C236813F4005F0FD023F4005330 -+:10A9700043F40063236067604A48F96C04F09EFB6F -+:10A98000236803F40063002BFDD17EE03B68103B9D -+:10A990000F2B02D8FBF31EF577E03E4B4248D969F6 -+:10A9A00004F08CFBBA6C786CBC68FD683968FB6C91 -+:10A9B000009201903A463D480294039504F07EFBD4 -+:10A9C0003B4B7E6C1B68F869D7F828E03C6A7D6ACF -+:10A9D0009B1B39697A694FEA9309BB690090354836 -+:10A9E000CDF80CE00194029504F068FBB86BFC6BA9 -+:10A9F0003D6CF96A3A6B7B6B00902F48019402958D -+:10AA000004F05CFBF06831687268B36800902B4812 -+:10AA100004F054FBF06931697269B3690090284809 -+:10AA200004F04CFB04A8FFF72BFE264804F046FB7D -+:10AA30000024A04625461CE0725912F0010F13D0E5 -+:10AA4000FF2A11D9059B9A4208D91F4B1B0D1B05E4 -+:10AA50009A4209D303F580139A4205D81B48294628 -+:10AA600004F02CFB08F101080435B8F10F0F02D8EF -+:10AA700001344C45E0D1074A40F203301368576077 -+:10AA800043F480631360FFF7BBFC0FB0BDE8F083B5 -+:10AA900070F50100FCF40100241000E0281000E033 -+:10AAA00054AF010058AF010064AF010071AF010065 -+:10AAB000E8ED0100A5AF0100D8AF010007B001002B -+:10AAC00025B00100FC1C86009D66800042B001009C -+:10AAD000F0B51F4E8BB06846FFF7D2FD3578F5B95B -+:10AAE0000698079B1C1A07D029462246F7F3A8F2BE -+:10AAF00006982146FBF394F32146164804F0DEFA4B -+:10AB0000154B1D7001233370144B1968E9B10B7894 -+:10AB1000DBB1134B2A461868F8F386F015E0114FA5 -+:10AB20003D7895B90898099B1C1A07D029462246FA -+:10AB3000F7F386F208982146FBF372F30A482146A0 -+:10AB400004F0BCFA012335703B700BB0F0BDC04679 -+:10AB500038F5010059B001003AF50100BC260000AB -+:10AB600020F5010039F501008BB0010010B5044655 -+:10AB700000F0C0DA0146204600F0FEF810BDC046E5 -+:10AB800070B5044600F0B6DA204600F0F3D9054669 -+:10AB9000204600F073D90022064640F62A012046DE -+:10ABA00000F02CDB0123AB408269134201D0002569 -+:10ABB00000E001352046314600F032DB284670BD0A -+:10ABC00010B5FFF7DDFF10BD2DE9F04107460C463B -+:10ABD00000F090DA384600F051D940F62A0180465C -+:10ABE0000022384600F00ADB83690646456944B115 -+:10ABF0004FF4004043F0004445F00045FFF792FB5E -+:10AC000007E04FF4004023F0004425F00045FFF733 -+:10AC1000A7FBB46138467561414600F001DBBDE831 -+:10AC2000F081C0462DE9F0410E465021804617467E -+:10AC30001D46FCF34DF0044618B300215022F7F3F3 -+:10AC4000FFF140F23C736363A3F55573E363A3F52F -+:10AC5000737323640C23636404230020E56026607F -+:10AC60006760C4F80880A3640749F7F385F6C0B2AB -+:10AC700084F84C000138C0B2012802D9022384F8BC -+:10AC80004C302046BDE8F0813E29860000487047E0 -+:10AC9000A8C201000048704720C301000048704767 -+:10ACA00000A60E00D2F8003670B50546C3F3840442 -+:10ACB000FFF7ECFF03E08378A34204D00C3020B10F -+:10ACC0000388002BF7D1038813B92846FFF7E2FF6A -+:10ACD00003884FF47A7003FB00F070BD0123C2F8C3 -+:10ACE000603610B5D2F86446FFF7D8FF04F0FF04D1 -+:10ACF000B0FBF4F34FF47A7003FB00F010BDC046D4 -+:10AD00002DE9F0411C460646154600F0B7D8002153 -+:10AD10000746304600F084DA0223C0F8583654B1B2 -+:10AD2000D0F85C3605F03F0223F4FC4343EA4223AB -+:10AD3000C0F85C3603E0D0F85C36C3F345253046F6 -+:10AD4000394600F06DDA2846BDE8F08170B504465A -+:10AD50000D4600F093D800210646204600F060DA48 -+:10AD6000294602462046FFF7B9FF314605462046F0 -+:10AD700000F056DA284670BD10B5FFF7E7FF10BDAA -+:10AD800070B504460D4600F079D8002106462046ED -+:10AD900000F046DA294602462046FFF783FF314697 -+:10ADA0000546204600F03CDA284670BD2DE9F0410A -+:10ADB000DFF860800646D8F8004034BB00F05ED86B -+:10ADC00021460746304600F02BDAD0F81456D0F86A -+:10ADD000143604469D4218BFD0F8145642F2107043 -+:10ADE000FBF3BAF4D4F81426D4F8143630469A4259 -+:10ADF00018BFD4F814263946C5EB0203642203FBBE -+:10AE000002F3C8F8003000F00BDA024B1868BDE816 -+:10AE1000F081C04680F501002DE9F04F1746C7F8D4 -+:10AE200020361D46036A85B00C2BCBBFD2F82836DE -+:10AE3000D2F82836C3F3094BC3F3072B01230024B0 -+:10AE4000AB4080468946029403940094FAF346F797 -+:10AE50000646012212FA04F3334207D0009240461C -+:10AE600049463A46FAF33AF726EA000601341F2C1F -+:10AE7000EFD1404603A902AAFAF35AF7039B002533 -+:10AE80006FEA030A2C460123A34006EA0A021A428B -+:10AE900008D0404649463A46E3B2FFF7BDFF854237 -+:10AEA00038BF054601341F2CEDD10BF102004019CB -+:10AEB00005B0BDE8F08FC0462DE9704305468846D1 -+:10AEC000FFF3DCF700218146284600F0A9D90446AB -+:10AED000284600F0ADF8224606464146182328468B -+:10AEE000FFF79AFF0B23023000FB03F0074C4946A3 -+:10AEF0003419B4FBF6F404FB00F4284600F090D9B2 -+:10AF00000A23B4FBF3F4A0B2BDE870833F420F0004 -+:10AF100010B508B1FBF3E0F110BDC04670B5094BA8 -+:10AF200006461D6808E030462C6800F0E3D8294644 -+:10AF30006A68FBF3DDF62546002DF4D1014B1D6058 -+:10AF400070BDC0466C270000002343667047C046B2 -+:10AF50007047C046002070472DE9F04106460D4677 -+:10AF6000144600F08FD8804618B93046012100F011 -+:10AF7000C7D8304614F020FD074610B96FF01D0405 -+:10AF800015E014B96FF0190418E04FF000032B809E -+:10AF9000002404F182013846F6F3CCF6C0B2A0409A -+:10AFA0002B8801341843052C2880F2D10024B8F1F5 -+:10AFB000000F03D13046414600F0A2D82046BDE83C -+:10AFC000F081C04607B54FF0000302A921F8023D09 -+:10AFD0000122FFF7C1FFBDF806000EBD416E2DE94D -+:10AFE000F041044661B1D0F8C83000EB8303D3F8D8 -+:10AFF000D020C36D9A4203D1006E8847064600E018 -+:10B0000000262046616DFFF757FFA56E07465DB12C -+:10B01000D4F8C83004EB8303D3F8D020E36D9A4210 -+:10B0200002D1206E3146A8473846BDE8F081C046BF -+:10B0300010B5044600F05ED801462046FFF7B6FE84 -+:10B0400010BDC04610B5044600F054D80146204655 -+:10B05000FFF796FE10BDC046416E2DE9F041044653 -+:10B0600061B1D0F8C83000EB8303D3F8D020C36DB2 -+:10B070009A4203D1006E8847064600E0002620462B -+:10B08000616DFFF763FEA56E07465DB1D4F8C83069 -+:10B0900004EB8303D3F8D020E36D9A4202D1206EF3 -+:10B0A0003146A8473846BDE8F081C04643692DE9DE -+:10B0B000F743222B06460F4640F3A08000F096D8B7 -+:10B0C000002800F09B80072F00F29880B268B2F54C -+:10B0D000026F01D101220AE040F604039A4201D036 -+:10B0E000002204E0F3680C2B94BF002201225FFAD7 -+:10B0F00082F8B8F1000F0BD130464FF400614246A0 -+:10B10000D6F8C89000F07AD80546002877D006E037 -+:10B11000D6F8843013F5405571D04FF00009032F55 -+:10B1200003D03046012100F0FBD8D5F8303123F0B0 -+:10B130000403C5F8303101239F42C5F8303103D9EB -+:10B14000042F01D0083300E00D23C5F83031D5F8C5 -+:10B150003031012F23F00103C5F8303101D9042F1C -+:10B1600036D1FF2400214FF4E2722346304600948A -+:10B17000FFF38CF62223009300214FF4EE72234656 -+:10B180003046FFF383F62823009300214FF4E67244 -+:10B1900023463046FFF37AF68123009300214FF4D3 -+:10B1A000E87223463046FFF371F601230093002135 -+:10B1B0004FF4A4724FF0FF333046FFF367F630468A -+:10B1C00000214FF4A6724FF6FF730094FFF35EF672 -+:10B1D000D5F8303123F0700343EA0713C5F8303156 -+:10B1E000D5F8303123F00803C5F83031B8F1000F3D -+:10B1F00005D13046494600F013D800E00025284626 -+:10B20000BDE8FE8370B50446FFF3F0F7002839D09F -+:10B21000A268B2F5026F01D101220AE040F60403F0 -+:10B220009A4201D0002204E0E3680C2B94BF002274 -+:10B230000122D5B24DB920464FF400612A46D4F818 -+:10B24000C860FFF3DBF7E8B105E0D4F8843013F50C -+:10B25000405017D00026D0F8303123F00403C0F856 -+:10B26000303143F00103C0F83031C3F30213032B34 -+:10B2700003D02046002100F053D81DB920463146A6 -+:10B28000FFF3CEF770BDC0462DE9774100220121C2 -+:10B2900013460546FAF3D4F50024804621462822B9 -+:10B2A000234628460094FFF3F1F501210646434664 -+:10B2B00028464FF0FF32FAF3C3F5284621462822EC -+:10B2C0004FF0FF330096FFF3E1F5BDE87E81C04605 -+:10B2D000D0F86C32994201D0002004E08B79D3F190 -+:10B2E000010038BF002070472DE9F04100260546D7 -+:10B2F0000446374608E02B68216A986804F0AED906 -+:10B3000000B90136013718346B689F42F3DB3046D1 -+:10B31000BDE8F08103682DE9F0411E680546B76875 -+:10B32000884614463846296904F098D944B13368F0 -+:10B330001B7E2BB1384629694246012304F046D9C9 -+:10B34000BDE8F08170B50546044600260DE0616950 -+:10B3500049B1236A3BB1182006FB00F010302818D1 -+:10B360000122FFF7D7FF013618346B689E42EEDBEF -+:10B37000002070BD2DE9F3411F460368044601918A -+:10B380000092DDF820801E6809B10D2941DD616859 -+:10B390000022FFF7BFFFE1680025656031B1236837 -+:10B3A00022891B685868FBF3A3F4E560009B2BB16E -+:10B3B000B3F5967F02DA6FF01C002CE03046414670 -+:10B3C000FFF786FF28B3019969B123681B685868A5 -+:10B3D000FBF37EF4E06010B96FF01A001BE0394611 -+:10B3E000019AF6F3C9F501A90422C4F8148004F106 -+:10B3F0000800F6F3C1F5201D69460422F6F3BCF5FA -+:10B40000009840B1204661680122FFF783FF0020C9 -+:10B4100001E06FF00100BDE8FC81C0462DE9F04776 -+:10B42000154686B00268DDF84080DDF844A005F0DE -+:10B43000010300930646534610684246DDF84C90DF -+:10B4400017F042DF0746002840F0A180022D54D0BB -+:10B45000032D1FD0012D02D06FF0160797E0414653 -+:10B46000042203A8F6F388F5022208F104010DF185 -+:10B470001600F6F381F556F8100B4946BDF8164054 -+:10B48000039D33F0B7DF214600902A46304608F18D -+:10B4900006032EE00222414605A8F6F36DF50422CC -+:10B4A00008F1040103A8F6F367F502220DF1160076 -+:10B4B00008F10801F6F360F5BDF81430012B02D055 -+:10B4C0006FF0240763E098F80A7073689F425CDAB3 -+:10B4D00049463068BDF81640039D33F08BDF1823D2 -+:10B4E00007FB03F3103300902146F0182A4608F1B9 -+:10B4F0000B03FFF73FFF074649E00E9B1A6873688E -+:10B500009A4242DA002A40DB4FF00103ADF81430D2 -+:10B5100004924FF00B030DF116012A4608F10200C8 -+:10B52000ADF81630F6F328F505A92A464046F6F39D -+:10B5300023F504991824013101FB04612A4608F11E -+:10B540000800F6F319F5012204A908F10A00F6F340 -+:10B5500013F50499042201FB046108F1040014317D -+:10B56000F6F30AF5049B013303FB04F39A5B991984 -+:10B5700002F10B039A4502D26FF00D0707E008F1C4 -+:10B580000B004968F6F3F8F401E06FF00107384664 -+:10B5900006B0BDE8F087C046F7B5016805460E68FD -+:10B5A00096F87032002B2CD0028947693AB93046A0 -+:10B5B00007F1BC01134600921CF052DD21E089899D -+:10B5C00070688918FBF3DCF32A68044618B993689D -+:10B5D0000133936015E09289A38A00699B1A801851 -+:10B5E000A382E9682A892061F6F3C6F404F12402F3 -+:10B5F0005389304643F0400353812146BA681CF01A -+:10B60000D1DDFEBD012801D0002000E08868704730 -+:10B6100010B50C4641B18B6823B9C06F0968F7F7C4 -+:10B62000C9FBA060A06800E0C06F10BD2DE9F0412B -+:10B630008D692B69994202D100273E4604E0CE6A0B -+:10B640000EB9374600E037686B681146D868FBF3DF -+:10B6500085F3AB6804461B6893F895301BB1C38A29 -+:10B6600043F08003C3822846214604F033DB98B9B7 -+:10B670006B6893F8AB308BB128463146FFF7C8FFB3 -+:10B6800060B1214601F084DD022807D16B682146B4 -+:10B69000D8680122FBF344F301200BE02846214641 -+:10B6A00004F07ED8A86821463A461CF07BDD0038BD -+:10B6B00018BF0120BDE8F081536873B5112B064611 -+:10B6C000154608D0122B01D0102B1CD1AB7803F0FB -+:10B6D0000103337517E002AA002342F8043D806895 -+:10B6E00095F82F1033F0CADD044660B1837923B991 -+:10B6F0006988C1F380011EF083DDA3791BB1B068B6 -+:10B70000214600F0CFFF7CBD2DE9F3471F4643687B -+:10B710000646D3F80C9003699246D3F82480B8F11A -+:10B72000000F34D048463C21FBF3D2F200282ED043 -+:10B73000054605F10C0400213C22F6F381F46C600F -+:10B740002F6004F03BD873682061A661CDF800A09B -+:10B750001021114A5B682046F6F3B6F40F4BE56200 -+:10B760001B6840465B682146984700280ADD7871CF -+:10B77000736893F8AB305BB1F06F3946F7F71AFB9B -+:10B78000A86005E0484629463C22FBF3B1F20025BB -+:10B790002846BDE8FC87C04647438600F8260000DF -+:10B7A0002DE9F341044601920E4611B9D0F81080FC -+:10B7B00001E0D1F804800199D8F82450CB8A13F421 -+:10B7C000006201D001271CE02046174603F0DADFB3 -+:10B7D000636893F8AB30A3B120463146FFF718FFFA -+:10B7E00078B1019901F0C6DB042801D0012804D109 -+:10B7F00063680199D8683A4646E0052801D10126D8 -+:10B8000000E00026636893F8953023B11FB9019AD0 -+:10B81000938A2D339382002D32D0DFB9EB6913F078 -+:10B82000010F07D0637D2BB12046019904F0B6D8F3 -+:10B83000024658B176B9636893F8963053B1D4F89C -+:10B840008400019903F050FA024618B9636801991F -+:10B85000D86819E0204601A904F098DAB0B9636805 -+:10B860000199D868FBF3B6F22B690446DB684046C1 -+:10B8700029462246984748B12046FBF3E7F105E008 -+:10B8800063680199D8682A46FBF34AF2BDE8FC8157 -+:10B890004B6A10B591F8432043F480134B62D0F803 -+:10B8A000883002F00702D21892F88030013382F813 -+:10B8B0008030D0F88820012382F88630D0F88810B4 -+:10B8C00091F8812091F87B309A4211D291F8802032 -+:10B8D00091F87A309A420BD291F8822091F87C301C -+:10B8E0009A4205D291F8832091F87D309A4201D393 -+:10B8F00004F0FCDC002010BD1FB5084B024600938D -+:10B90000074B08460193074B0749DB69029312680E -+:10B91000064BF6F301F605B000BDC046E1C30100D9 -+:10B92000A4C30100FCF40100B2C30100D5C30100AF -+:10B9300010B5436804461B7E53B1D0F88000FFF772 -+:10B94000D3FCA068F9F74CFB6268002382F8203032 -+:10B9500010BDC04610B58069FFF7EAFF002010BD9A -+:10B9600070B50446636880681E7E0EB1002515E040 -+:10B97000F9F7F8F9054620B9D4F88000FFF7E2FCA2 -+:10B980000546FFF7A5F86368D3F89C1031B10B7832 -+:10B9900023B1034B32461868F7F346F1284670BDD1 -+:10B9A00020F5010010B58068F9F702FB002010BDFA -+:10B9B00010B50446FFF7F6FFA068FCF771FA10BD5A -+:10B9C00013B54FF0000310F00104ADF8063006D0B7 -+:10B9D000002904DD10F8013B01398DF8073010F023 -+:10B9E000030F05D0012903DD30F8022B023913E0E3 -+:10B9F000002211E00368D218436828BF0132D21830 -+:10BA0000836828BF0132D218C36828BF0132D21818 -+:10BA100028BF01321030103931F00F03EAD113047E -+:10BA20001B0C03EB124203E030F8023C0239D2183F -+:10BA3000034602300129F7DC04BF1B788DF806307D -+:10BA4000BDF80630D3181A04120C02EB134213048B -+:10BA50001B0C03EB124024B1030243EA1023180429 -+:10BA6000000C1CBD10B5FFF7ABFF02E003041B0C7C -+:10BA70009818020CFAD1C04380B210BD2DE9F041F4 -+:10BA8000BDF818500C46294616469846FFF798FF11 -+:10BA90003204120C02EB14422404240C121905F097 -+:10BAA000FF0302EB16421B0202EB082243EA1523B6 -+:10BAB000D218101802E003041B0C9818020CFAD1DB -+:10BAC000C04380B2BDE8F0812DE9F0418D8A164671 -+:10BAD0000D2D1F460C6952DDA38904F10C0003F003 -+:10BAE000FF021B0A43EA0223B3F5C06F0BD2152DE8 -+:10BAF00045DD254804F10E010622F6F321F2002867 -+:10BB00003DD104F11400038803F0FF021B0A43EA4D -+:10BB10000223B3F5014F0AD10430821C63199A4203 -+:10BB20002DD8038803F0FF021B0A43EA0223B3F572 -+:10BB3000006F24D1811CC4EB0103C3EB0504132C5B -+:10BB40001DDD82781309042B19D102F00F039A002E -+:10BB5000132A14D9A24212DC8A78CB7843EA022352 -+:10BB6000A34201DA1C4600E009DC8A79CB7943EA7A -+:10BB700002239804800C10B931603C6001E04FF062 -+:10BB8000FF30BDE8F081C04631C401002DE9F0432B -+:10BB9000436887B013F0020F0546884600F08F8097 -+:10BBA00005AA04ABFFF790FF0028C0F28880059833 -+:10BBB000037803F00F039E003146FFF753FF48B1AF -+:10BBC000B8F8163023F01003A8F816302B6A0133AA -+:10BBD0002B6274E0EB69059F0133EB6197F80990E4 -+:10BBE000B9F1060F24D107F10C01042202A8049C2C -+:10BBF000F6F3C2F1059904221031A41B03A8F6F351 -+:10BC0000BBF1A4B2B8190299039A4B460094FFF70E -+:10BC100035FF48B1B8F8163023F01003A8F81630F5 -+:10BC2000AB6A0133AB624AE06B6A01336B623EE0A0 -+:10BC3000B9F1110F24D107F10C01042203A8049CCF -+:10BC4000F6F39AF1059904221031A41B02A8F6F329 -+:10BC500093F1A4B2B8190399029A4B460094FFF7E6 -+:10BC60000DFF48B1B8F8163023F01003A8F81630CD -+:10BC70002B6B01332B6322E0EB6A0133EB6216E09E -+:10BC8000B9F1010F13D10499B819891B89B2FFF7D3 -+:10BC9000E9FE48B1B8F8163023F01003A8F81630C2 -+:10BCA000AB6B0133AB630AE06B6B01336B63B8F8CA -+:10BCB0001630002043F01003A8F8163001E04FF0D2 -+:10BCC000FF3007B0BDE8F0832DE9F043436887B04B -+:10BCD00013F0010F804600F08780CB8A13F0080F25 -+:10BCE00003D18368013383607EE005AA04ABFFF7CC -+:10BCF000EBFE002878DB059A00271378977203F093 -+:10BD00000F039E00D77231460598FFF7ABFE059BE7 -+:10BD10009872C0F30F20D872D8F80C30059901330F -+:10BD2000C8F80C3091F80990B9F1060F21D18D199E -+:10BD3000049C0C3104222F746F7402A8F6F31CF1DA -+:10BD4000059904221031A41B03A8F6F315F1A4B23F -+:10BD50004B4628460299039A0094FFF78FFE2874F9 -+:10BD6000C0F30F206874D8F810300133C8F81030D1 -+:10BD70003AE0B9F1110F22D18D19049CAF71EF7126 -+:10BD8000059904220C3103A8F6F3F6F00599042274 -+:10BD90001031A41B02A8F6F3EFF0A4B24B462846DC -+:10BDA0000399029A0094FFF769FEA871C0F30F206F -+:10BDB000E871D8F814300133C8F8143014E0B9F140 -+:10BDC000010F11D18C1904992046891BA770E770C7 -+:10BDD00089B2FFF747FEA070C0F30F20E070D8F8DB -+:10BDE00018300133C8F8183007B0BDE8F083C046FA -+:10BDF0002DE9F34114460A9F0268DDF82C8004F017 -+:10BE0000010300930546434610683A4617F05CDA92 -+:10BE1000064618BB052C04D8DFE804F00A06140314 -+:10BE2000030D6FF0160619E0281D3946042213E0B1 -+:10BE30006B683B6012E005F1080000214C22F6F32C -+:10BE4000FFF00BE0B8F14B0F02D86FF00D0605E0E4 -+:10BE5000384605F108014C22F6F38EF03046BDE875 -+:10BE6000FC81C04610B58C6B00200BE00B1893F8DA -+:10BE70003C30064A03F07F03D356002B01DA012041 -+:10BE800003E00130A042F1D1002010BD401B86002C -+:10BE90002DE9F84F022983460E4690469A4614BF74 -+:10BEA0004FF0FF37002714BF002401244FF0000992 -+:10BEB0002EE0022E14BF4FF0FF3300239F4211D01B -+:10BEC000022E08D1B8F1040F07D0B8F1060F04D044 -+:10BED000B8F1080F01D0042200E00022C7EB0403F0 -+:10BEE000934214DD0E2CCCBF4FF480534FF400531B -+:10BEF00044F4306213439DB2DBF85C0129463AF00A -+:10BF00004DDA20B12AF81950274609F10109013408 -+:10BF1000022E0CBF0E2300239C4202DCB9F11F0F3E -+:10BF2000C7D90A9BC3F80090BDE8F88F2DE9F04F00 -+:10BF300088469BB040210027DDF890B09DF8949092 -+:10BF40000646C0F82077C0F81C1740689A46FAF3F6 -+:10BF5000BFF60446C6F8180710B96FF0150473E071 -+:10BF6000D8F800306BB92033C6F82037336B304631 -+:10BF70001A8906F5E463009359462346FFF788FFC4 -+:10BF80001FE0202B6CD8454617E0AC88D6F85C0142 -+:10BF900021463AF003DA002862D01FB12B78E2B2D2 -+:10BFA0009A425DD9D6F82037D6F81827013722F8FB -+:10BFB00013400133C6F820370435D8F800309F42CB -+:10BFC000E3D3D6F82037002B4AD070681021FAF35B -+:10BFD0007FF60746002835D0279B002411AD44602A -+:10BFE000836004732146066080F80DB080F80E90DF -+:10BFF00024222846F6F324F0A24514BF002301238F -+:10C0000001934FF0FF330293039304930593D6F803 -+:10C01000183730460693D6F8203702210793144B81 -+:10C02000144A0A9303230C930123089409940D9452 -+:10C030000E9400950B971AF05FDF044698B9269B83 -+:10C040007B6010E06FF01A04D6F8181759B17068C9 -+:10C05000D6F81C27FAF34CF60023C6F8183702E08E -+:10C060006FF00104F0E720461BB0BDE8F08FC0463A -+:10C07000F9C500002C9E850030B590F8143789B0C2 -+:10C080000446002B3ED0D0F868319D79002D62D156 -+:10C09000036880F814571B7E002B5CD0B0F816376D -+:10C0A000002B58D0036B186903F0A8FEB4F81617DC -+:10C0B000884250D020461CF073DE204603F0AAF8D8 -+:10C0C0002046B4F816171CF0B1DC236893F82F3023 -+:10C0D0006BB1D4F86C322046D3F8D412383117F053 -+:10C0E0005DDB0146C4F8AC06204610F0F5DB2046C7 -+:10C0F0001EF00CDF204629461FF012D9204615F00D -+:10C100007FDF28E003681B7E2BB3D0F868319B7972 -+:10C110000BBBD0F8000507A948F0DCDF03E02B7E5D -+:10C1200013F0020F17D107A848F0DCDF05460028FE -+:10C13000F5D1236B05901B6805A900930323019398 -+:10C1400002900390012220462B46FFF7EFFE10B924 -+:10C15000012384F8143709B030BDC0462DE9F74FEC -+:10C160000192D0F800A090F80D801F460C464FF0C9 -+:10C17000000BE5E0072200212046F5F361F70C9A59 -+:10C18000B8F1020F12F81B00207001D0022308E062 -+:10C19000042F05D0062F03D0082F01D0434600E01E -+:10C1A0000023C3EB0002B8F1020F14BF00230123E8 -+:10C1B0009A4210DBB8F1020F01D0022108E0042FEF -+:10C1C00005D0062F03D0082F01D0414600E0002102 -+:10C1D000C1EB00060FE0B8F1020F14BF00260126E4 -+:10C1E00006E0DAF85C0131463AF096D818B9013623 -+:10C1F00023789E42F5D9B8F1020F207802D00022B0 -+:10C2000002230BE0042F07D0062F00F0A680082F92 -+:10C2100000F0A3804346A1E00E2200231B189342A6 -+:10C220000FDCB8F1020F01D0022108E0042F05D085 -+:10C23000062F03D0082F01D0414600E000210D1841 -+:10C240000FE0B8F1020F0CBF0E25002506E0DAF86A -+:10C250005C0129463AF060D818B9013D23789D4227 -+:10C26000F5D24FF0000963E002EB89039968CB88AF -+:10C27000B1F832E013F020035FFA8EF00DD00EF427 -+:10C280004072B2F5807F02D1821C023806E0B2F51E -+:10C29000007F02D1821E023000E00246B04201D38C -+:10C2A000A84203D9B24241D3AA423FD8B3B1B04267 -+:10C2B00014D3A84212D80EF44073B3F5807F05D191 -+:10C2C0002379FF2B0AD00133237107E0B3F5007FF8 -+:10C2D00004D16379FF2B01D001336371CB8813F054 -+:10C2E000200F0BD0B24209D3AA4207D8824205D010 -+:10C2F000A379FF2B1AD00133A37117E023780E2BFB -+:10C300000FD85046FFF7AEFD28B1E378FF2B0DD0D4 -+:10C310000133E3700AE0A378FF2B07D00133A37049 -+:10C3200004E06378FF2B01D00133637009F1010948 -+:10C33000DAF818251368994596D30BF1010B0734E9 -+:10C340000D9B9B4504DA019A13689B45FFF612AFDB -+:10C35000019BC3F800B0BDE8FE8F00230E225DE70D -+:10C360002DE9F84F5FFA83FC1E4603F44073B3F5E2 -+:10C37000007F14BF4FF000094FF0010905468A46BF -+:10C3800093460CF10200ACF10203B9F1000F02D0A8 -+:10C390008646984601E09E4680460027394629E0B9 -+:10C3A00011F80A40ACF105039C4221DB0CF10503B6 -+:10C3B0009C421DDC0AEB010082783AB9C3782BB9A4 -+:10C3C00003791BB943790BB983798BB1744506D1D5 -+:10C3D000837993B9B9F1000F08D0037907E0444598 -+:10C3E0000BD152B9C37843B9037933B9437923B92F -+:10C3F000013707315F45D3DB1BE0BEF10E0FD4BF21 -+:10C400004FF400534FF480534EF4306213439CB208 -+:10C41000D5F8FC341B7893B12846002128F0ECDADB -+:10C42000284628F0DFDA0AE02846012128F0E4DA7D -+:10C4300004E0D5F8FC341B78002BF5D134462046B7 -+:10C44000BDE8F88F2DE9F04FD0F8008090F80DA0EE -+:10C45000D8F83010DDB00989814614464FF0000B42 -+:10C460005B9300E0042100225B98964608E01EF8EA -+:10C4700004300EF1070E052B01D9934602E001327C -+:10C480008242F4DB082900F2B08001A252F821F0C8 -+:10C49000B5C40000EBC50000BBC40000EBC5000044 -+:10C4A00067C50000EBC50000EBC50000EBC5000050 -+:10C4B00065C400004FF6FF761AE00025AE464FF641 -+:10C4C000FF7612E00EEB0B0292FBF0F300FB13235E -+:10C4D000072203FB02F16218937823B9D378B342A1 -+:10C4E0003CBF655C1E460EF1010E8645EADB15B9C0 -+:10C4F0000025AC4621E00E2D94BF4FF400524FF4BE -+:10C50000805245F4306343EA02006FE00CEB0B020B -+:10C5100092FBF0F300FB1323072203FB02FE04EB64 -+:10C520000E0359789A78DB785218D218B242BCBF01 -+:10C5300014F80E5096B20CF1010C8445E6DB3DB9BF -+:10C540009BFBF0F300FB13B3072203FB02F31D5D1B -+:10C550000E2D94BF4FF400534FF4805345EA03036C -+:10C5600043F4306042E0BAF1020F3ED15AAB00937F -+:10C5700000244046514652464AAB5A94FFF788FC85 -+:10C58000D8F818771FB3D8F8206706B35A9925460C -+:10C5900010E000243AAB37F81520E05A904205D15C -+:10C5A0005CAA02EB410323F8480C01310234402C11 -+:10C5B000F0D10135B542ECDB20230E485B935A9154 -+:10C5C00002F07CFD4AAB00935A9B02AC04E02023AE -+:10C5D0003AAA5B9302AC00920193214648465BAABB -+:10C5E0000223FFF7BBFD02213DE700205DB0BDE85F -+:10C5F000F08FC046B0C40100F0B50546BDB0046878 -+:10C600000E4609B108292DD12023D4F818273B93D1 -+:10C61000236B03AF1B890092D4F82027394601927F -+:10C620003BAAFFF79BFD6B7B022B13D1D4F8FC34A4 -+:10C630001B787BB1D4F83437B3F8A4E30EF440632D -+:10C64000B3F5406F06D1204639463B9A7346FFF753 -+:10C6500087FE05E02846002103AA3B9BFFF7F2FE78 -+:10C66000A4F816076B6813B1A86831469847D4F848 -+:10C670001817D4F81C276068FAF33AF30023C4F8BB -+:10C680001837606829461022FAF332F33DB0F0BD46 -+:10C69000002070470020704700207047012380F879 -+:10C6A0007A3070477FB591F8943006460C4643B314 -+:10C6B000D0F8000503A948F00DDD10E02B7E13F043 -+:10C6C000020F0CD02B69A34209D101230093DB1880 -+:10C6D0000193304621462A46002348F013DE03A882 -+:10C6E00048F000DD05460028E8D13C23C4F88C3032 -+:10C6F000F9F388F70123C4F8900084F8945084F883 -+:10C7000084307FBD036870B545680E4658680C21BB -+:10C71000FAF3DEF2044610B96FF01A0005E00021CA -+:10C720000C22F5F38DF47451002070BD70B50446F1 -+:10C730000E4640684FF48471FAF3CAF208B9054610 -+:10C740000AE000214FF484720546F5F379F4D4F839 -+:10C7500048312C606E60AB60284670BD83682DE95F -+:10C76000F0415D6803684C5907460E4601EB050829 -+:10C7700058684FF48471FAF3ABF2606000282FD050 -+:10C780007359002158684FF48472F5F359F43B68EB -+:10C79000C42158687459FAF39BF2A06000B373592E -+:10C7A00000219868C422F5F34BF473592B499C6817 -+:10C7B0003B683A4623603B689868002302F07CDFC0 -+:10C7C000A06668B1735926499C683B683A469868E8 -+:10C7D000002302F071DFC4F8C00008B100203AE085 -+:10C7E000D8F80030996831B3896E41B13B689868D8 -+:10C7F00002F046DFD8F800309A6800239366D8F834 -+:10C8000000309B68D3F8C01049B13B68986802F0CB -+:10C8100037DFD8F800309A680023C2F8C0303B6890 -+:10C82000D8F8002058689168C422FAF361F2D8F869 -+:10C83000002000239360D8F80030596849B13B6864 -+:10C840004FF484725868FAF353F2D8F800200023AA -+:10C8500053606FF01A00BDE8F081C046A9D6000011 -+:10C86000E1D0000010B5014628B103684FF484728E -+:10C870005868FAF33DF210BDD0F8483170B55D68E4 -+:10C880000646E9420C4640D0495900293DD0496846 -+:10C8900059B14CF0DBDE63594FF48472596870680B -+:10C8A000FAF326F26259002353606359996800290C -+:10C8B0002BD0896E61B1B06802F0D0DE6359B068E8 -+:10C8C0009B68996E02F0DCDE63599A6800239366D8 -+:10C8D00063599B68D3F8C01071B1B06802F0BEDE36 -+:10C8E0006359B0689B68D3F8C01002F0C9DE635981 -+:10C8F0009A680023C2F8C0306359C42299687068EE -+:10C90000FAF3F6F162590023936070BDC16810B567 -+:10C91000044621B10068FFF7AFFF0023E36010BDBC -+:10C9200070B5044600680D46FFF7A6FF2068002199 -+:10C930004318D3F84C3233B15A6922B1D368AB42B1 -+:10C9400001D10023D36004312029F1D164682B196F -+:10C950003BB1295929B140680C22FAF3C9F10023EF -+:10C960002B5170BD70B50568044604F1DE01284600 -+:10C97000102215F0CFDE284604F1EE01102215F04A -+:10C98000C9DE70BD2DE97043A4B004680DF18306C3 -+:10C9900081460DF163050D2230461949F5F3ECF29D -+:10C9A00020462946102215F0B5DE05F110011022AF -+:10C9B000204615F0AFDE3046F5F3D2F3D9F8042067 -+:10C9C0002024C23200920622034601920DF1130880 -+:10C9D00021463246284609F17E05CDF808800394A9 -+:10C9E000FBF3B2F2414622462846F5F3C5F209F1BF -+:10C9F0009E0029462246F5F3BFF224B0BDE87083BD -+:10CA0000C2C4010070B500F17E0405462021204615 -+:10CA1000F7F326F0204605F19E012022F5F390F26F -+:10CA200010B92846FFF79EFF70BDC046F0B58B6D6C -+:10CA3000DFB013F0010F07460C464CD113F0020F84 -+:10CA400005D113F0040F46D04FF0100301E04FF072 -+:10CA5000200359ADA7F87C302049142205AE2846A2 -+:10CA6000F5F38AF204F1C201062207F1BE04304652 -+:10CA7000F5F382F207F17E0120222046F5F37CF2E5 -+:10CA80003846FFF7BFFF214620220DF11A00F5F3CB -+:10CA900073F22846F5F364F345AC26220096019222 -+:10CAA0000294B7F87C200346039220212A4607F11E -+:10CAB000DE00FBF349F22146B7F87C2007F15A006B -+:10CAC000F5F35AF207F1FE0000210822F5F3B8F25F -+:10CAD0003846FFF7E3FD5FB0F0BDC046CFC40100AC -+:10CAE0007FB50292436802AE9B680D4600930068D2 -+:10CAF000B72132460823FBF7BDF9044610B14FF0C9 -+:10CB0000FF3005E0284631460822F5F335F220468D -+:10CB100004B070BD2DE9F04700F1FE088946924649 -+:10CB20001788414690F87B200646FFF7D9FF20B1D1 -+:10CB3000404600210822F5F383F209F171056FF0F8 -+:10CB40002203EB5596F87C30EC1906336370A01C79 -+:10CB500003221349F5F310F20123637196F87A303A -+:10CB6000BC1DA4B203F003032B55281906F15A018A -+:10CB7000B6F87C200230F5F3FFF1B6F87C3009F10D -+:10CB80004F00023341460822E418F5F3F5F1A4B250 -+:10CB9000AAF80040B6F87C000830BDE8F087C0462F -+:10CBA0006EA701002DE9F74F99460368B0F87C4065 -+:10CBB00005468B46586820219046FAF389F00746CF -+:10CBC00008B904467BE02B684FF480715868FAF38B -+:10CBD0007FF08246002862D02B684FF4817158683C -+:10CBE000FAF376F0064600286DD0B8F1010F03D0B5 -+:10CBF000B8F1020F24D064E005F18E01102238460E -+:10CC0000F5F3BAF10BF19C01102207F11000F5F3D6 -+:10CC1000B3F105F15A0122464846F5F3ADF1384625 -+:10CC200020213246FBF396F4504632464FF4807191 -+:10CC3000FBF3C0F4484621463246FBF3BBF42AE03E -+:10CC4000B5F87C300F2B09D805F15A000019C4F152 -+:10CC500010020021F5F3F4F110240EE014F00703A4 -+:10CC60000BD005F15A000019C3F108020021F5F3B9 -+:10CC7000E7F124F0070308339CB210200BF19C016C -+:10CC8000224605F15A03CDF80090F3F359F2C0B9EA -+:10CC900004F108039CB20C9B1C80012414E006469E -+:10CCA00004462B68394658682022FAF321F036B141 -+:10CCB0002B68314658684FF48172FAF319F0204618 -+:10CCC0000AE0002008E004462B68514658684FF4FB -+:10CCD0008072FAF30DF0E4E7BDE8FE8F2DE9F04F26 -+:10CCE0009FB0059202680746884606921E46002BB2 -+:10CCF00000F0E88183685B68F358D3F804909B6880 -+:10CD00000793059B022B37D0042B00F00A81002BE0 -+:10CD100040F0D8811046796806F11A0271334AF062 -+:10CD2000C9DA8246002800F0CD8105694FF4BE4281 -+:10CD300005F112062A8205995F223046F5F380F14B -+:10CD400048F08802130AEB742A75B9F8182009F123 -+:10CD50001C04130A6B75AA7521460698202215F04B -+:10CD6000D9DC214605F11F002022F5F305F1059CD1 -+:10CD70000B23C9F80030A8E1B9F80221B2F5007F11 -+:10CD800002D141F472780AE0802A04D141F49E581D -+:10CD900048F0080803E0042A08BF41F4E4787B68FF -+:10CDA000B9F804A09B6DADF876A013F0020F0CBF8C -+:10CDB00004250225802A30D118F4805F2DD03B8ACB -+:10CDC00013F001041BD13846FFF7CCFD38467968D3 -+:10CDD000FFF72CFE97F87A20B7F87C3000920122FA -+:10CDE0000392019502940698796807F15A024CF073 -+:10CDF000FBDA3B8A87F87B0043F001033B82B7F8FC -+:10CE00007C3010339AB2BDF8763013F0070105D0AC -+:10CE100002F108035B1A9AB200E000220AF17103E2 -+:10CE2000D3180698796806F11A029BB24AF042DAE2 -+:10CE30008246002800F0468105694FF05F0305F146 -+:10CE4000120600215F222B823046F5F3F9F04FEAFB -+:10CE50001823EB7485F81480B9F8182009F11C0127 -+:10CE6000130A6B75AA7505F11F002022F5F384F0F3 -+:10CE7000B9F8042005F17100D9F80810F5F37CF039 -+:10CE8000BDF8763003F0FF021B0A43EA022386F85E -+:10CE90005D30C3F30F2386F85E30B9F80231802B82 -+:10CEA0002ED118F4805F2BD00DF17602384629463A -+:10CEB000FFF730FEBDF8763005F13F0003F0FF02CA -+:10CEC0001B0A43EA022386F85D30C3F30F2386F87A -+:10CED0005E30AB7B022B04D100211022F5F3B0F0C1 -+:10CEE00004E007F18E011022F5F346F0304641468A -+:10CEF00009F19C020023F6F30BF5002800F0E48012 -+:10CF000096F85D3096F85E2042EA03222B8AD2180A -+:10CF100092B202F0FF031B0243EA12232B820C237E -+:10CF200080E090F87A304FF000021B0103F03003EC -+:10CF300041EA0303ADF8762043F460731FFA83F8E7 -+:10CF4000B0F87C30796871339CB218F0020F1CBFC6 -+:10CF500004F108039CB2069806F11A0223464AF02F -+:10CF6000A9D98246002800F0AD8005694FF05F0323 -+:10CF700005F112060021A4F112022B823046F5F3CE -+:10CF80005FF04FEA1823EB7485F81480B7F87C2023 -+:10CF900007F1BE01130A6B75AA7505F11F00202267 -+:10CFA00005F13F0407F18E0BF4F3E6F71022594622 -+:10CFB0002046F4F3E1F7082207F1FE0105F14F00E6 -+:10CFC000F4F3DAF70DF176030093384605F17103B7 -+:10CFD000494608F00302FFF7E5FDAB7B022B05D1C4 -+:10CFE000204600211022F5F32BF004E0204659469C -+:10CFF0001022F4F3C1F7BDF8762002F0FF01130A06 -+:10D0000043EA012386F85D30C3F30F2386F85E30D0 -+:10D010002B8AD21892B202F0FF031B0243EA1223BA -+:10D020002B820F230124C9F800304EE0022301E0D7 -+:10D030006FF001033370701D09F15C010822F4F3F5 -+:10D040009BF78CB10DF12604284608F0030109F185 -+:10D050008C022346F6F31AF5002833D006F14D0072 -+:10D0600021461022F4F388F7B9F80231B3F5007FB6 -+:10D0700005D1DAF8243043F08073CAF82430069AD8 -+:10D08000136893F895305BB1059B0BB1022B07D168 -+:10D09000DAF8243023F4403343F48033CAF82430E0 -+:10D0A0007B6851469A6806981BF07CD8069A079BC5 -+:10D0B0009068D3F8C0104FF47A72002302F086DA39 -+:10D0C000012009E0002007E004460323EB73B9F8D0 -+:10D0D0000231802BAAD0ABE71FB0BDE8F08FC0466D -+:10D0E00070B5C5680446002D4FD083685B68EB5867 -+:10D0F0005968002949D00B8A042B14BF0126022647 -+:10D100000B680C2B1CD00F2B2AD00B2B3DD191F888 -+:10D110000421531C022A81F8043108D9C16821B1C5 -+:10D1200040681A310F224CF035DA20461FE001F139 -+:10D130005C000821F6F394F420463146002221E0F9 -+:10D1400091F80421531C022A81F804310FD801F10F -+:10D150005C000821F6F384F420463146022211E0F7 -+:10D1600091F80421531C022A81F8043102D9FFF7F7 -+:10D17000CDFB0AE001F15C000821F6F371F42046D2 -+:10D18000314604222B46FFF7A9FD70BDF0B50C46D1 -+:10D19000B5B00546002838D0002936D0038A4FF6AE -+:10D1A000FD7103EA010101826388228813F0010FF7 -+:10D1B0001CD0A2F108039BB2382B26D8402A1AD1E2 -+:10D1C00003AF00233846211D00934CF0A5D8064636 -+:10D1D00088B905F11A0007F148012022F4F3CCF6D2 -+:10D1E0002B8A304643F002032B8210E0202A0CD118 -+:10D1F00041F002030382211D228805F11A00F4F395 -+:10D20000BBF6248800202C8301E06FF0010035B0CC -+:10D21000F0BDC04613B58E46144601461A4670B19D -+:10D220006BB183685B68D3580A8B986852B1C38826 -+:10D2300043B91A31734600944CF06ED803E04FF0B6 -+:10D24000FF3000E000201CBD2DE9F04F89B00746FB -+:10D250000C46D0F800900593002B00F032818368D3 -+:10D26000059A5B68D3585D68D3F808A0002D00F0DC -+:10D270002881BAF1000F00F024812B8A042B14BFFF -+:10D28000012302230793B5F80231802B05D0B3F5B3 -+:10D29000007F02D0042B40F0148105F15C031A4694 -+:10D2A00094F81380267D0120069304F117010823CA -+:10D2B000F6F3C8F1069A904200F005812B6846EA21 -+:10D2C00008260C2B5FD00F2B00F0E1800B2B40F0D9 -+:10D2D000FA8006F4DC73B3F5847F40F0F48005F146 -+:10D2E0003C09202204F11F014846F4F345F6059B52 -+:10D2F000796803F11A0B0AF148030093BAF8063073 -+:10D3000005F18C080193CDF80880AB8AC2310393F4 -+:10D31000584605F11C024B46F6F3FAF116F4807FED -+:10D3200008D0204606F003014246F6F351F20028E9 -+:10D3300000F0C98094F8702094F86F3052EA03230B -+:10D3400008D0EA889A4205D104F17100E968F4F343 -+:10D35000F7F528B17868594611224CF01BD9B2E094 -+:10D3600085F804013B68DAF8C010986802F076D9B5 -+:10D3700006980821F6F374F3384607990222059BB4 -+:10D38000FFF7ACFC9FE006F4D873B3F5807F40F064 -+:10D390009A8016F4807F09D0204606F0030105F13B -+:10D3A0008C02F6F315F2002800F08D80002385F83A -+:10D3B00004313B68DAF8C010986802F04FD9059A3A -+:10D3C0002B8B02F11A082A8ACDF804800092484675 -+:10D3D000796805F1AC024CF077D8B5F80241802CA1 -+:10D3E00002D110232B6034E0042C32D10D232B60AA -+:10D3F0003B8A13F0010622D13846FFF7B3FA3846CC -+:10D400007968FFF713FB97F87A20B7F87C30012A88 -+:10D4100014BF0122022287F87A2000922A8A0296FB -+:10D420000192012203924846796807F15A024BF0B3 -+:10D43000DBDF3B8A87F87B0043F001033B820698E1 -+:10D440000821F6F30DF3384607992246059BFFF7AE -+:10D4500045FCB5F80231B3F5007F04D1D9F8440199 -+:10D46000414601F075F9B5F80231802B01D0042B4B -+:10D4700008D17B6848469B68792100934246062381 -+:10D48000FAF7F8FCB5F80231802B1CD115E016F440 -+:10D49000807F07D0204606F0030105F18C02F6F3E9 -+:10D4A00097F180B1002385F804313B68DAF8C010A9 -+:10D4B000986802F0D3D810232B603846FFF726FA7D -+:10D4C00001E0002000E0012009B0BDE8F08FC04677 -+:10D4D00070B50E46054670B1CC7B032C0BD1456967 -+:10D4E000012D08D18C7C022C01D0FE2C03D1FFF73A -+:10D4F000ABFE284600E0002070BDC0462DE9F34792 -+:10D50000DDF82C800646924699460C46002943D009 -+:10D51000B8F1000F40D0836800685B6858F80330AA -+:10D520005D689F6829464CF091D809232B602378C9 -+:10D530003068302B736829460BBFB3F86230B3F8FC -+:10D54000623003F0800303F00403A5F802310A9B64 -+:10D55000224601935346CDF800904CF097D8D8B1AD -+:10D560007369012B01D1FB88B3B1002485F8044114 -+:10D570003368D7F8C010986802F070D8298A0A2357 -+:10D580002B603046042914BF012102212246434664 -+:10D59000FFF7A4FB012000E00020BDE8FC87C046A7 -+:10D5A00007B59E4660B101290AD14161059B11462C -+:10D5B0000093069B72460193049BFFF79FFF00E0D8 -+:10D5C00000200EBD2DE9F04146681546D6F8D4324C -+:10D5D000D0F800805A8EADF5067D02F47042044604 -+:10D5E000B2F5805F14BF00220122404648F0E0D827 -+:10D5F0000746002853D04FF40073859345B1E36884 -+:10D60000002B4CD120463946FFF7A8F8002846D118 -+:10D61000A36820465B68FB589D68FFF7B3F9B6F82E -+:10D620006230BB8703B1E760238A13F0020F09D091 -+:10D6300005F1480004F11A012022F4F39DF44FF0A3 -+:10D640002003EB80EB88202B17D185AB009340465D -+:10D6500050213A6905AB01F0D7FC08AB0093859BDC -+:10D6600020460C3B0193E36801210293D7F8E820A0 -+:10D67000D7F8EC30FFF794FF11E06368B3F862303D -+:10D68000B3F5007F04D1706906F1BC01062203E006 -+:10D690007069727E06F11A013B46FFF7BBFD0DF57E -+:10D6A000067DBDE8F081C0462DE9F047C768054614 -+:10D6B000D0F800907FB383685B68FB589C6854B3D4 -+:10D6C00004F16C0630464FF48071FAF35DF3804646 -+:10D6D000D0B904F1480120223046FAF395F34FF017 -+:10D6E0002003E3806B6807F11A01B3F86230B3F5E9 -+:10D6F000007F04D1D9F8440101F026F80BE0284658 -+:10D700004246FFF75FFF06E00022D9F80800A16E4D -+:10D71000134601F05BDFBDE8F087C0467047C046A6 -+:10D7200010B5C3F8A010082019461C4635F098D84B -+:10D7300084F8A40010BDC04600207047002010608F -+:10D740007047C04600207047002070472DE9F04721 -+:10D75000044688464768002110469146C922F4F3E2 -+:10D760006FF42046414638F019DE78B997F8503703 -+:10D77000002B00F0DB8707F5AA6138460E3138F040 -+:10D7800067D80646002800F0D18700E0266908F433 -+:10D790007043B3F5805F14BF38233C233078FF58C3 -+:10D7A00038F0E8D90446B07837F0ECDD637C5FFAF6 -+:10D7B00088F513F00102064602D097F904E106E06D -+:10D7C00097F90431182BD4BF9646A3F1180E934B4A -+:10D7D0009C4203D158214FF0520C0BE0904B9C42DD -+:10D7E00005D0904B9C4202D04FF07F0C01E04FF0EF -+:10D7F000580C61463B68022B5FD1012D01D80023F4 -+:10D8000003E00A2D8CBF02230123E31893F90620BD -+:10D81000854B9C4203D10B2D10D14C2240E0834B11 -+:10D820009C4203D10E2D3BD1362239E0804B9C42E5 -+:10D8300002D0804B9C4204D10B2D30D00E2D2ED027 -+:10D840002EE07D4B9C4203D10E2D29D12A2227E0C8 -+:10D850007A4B9C4207D1022D01D1582220E00A2D9B -+:10D860001ED154221CE0764B9C4203D10A2D17D1C5 -+:10D87000502215E0734B9C4203D10E2D10D128226B -+:10D880000EE0714B9C4203D10B2D09D13E2207E0E3 -+:10D890006E4B9C4204D10C2D02D1442200E0402268 -+:10D8A000CEEB020323EAE3738B42A8BF0B460022B0 -+:10D8B00002F809300132042AFAD1654B9C4208D0A3 -+:10D8C000644B9C4205D0644B9C4202D0634B9C420B -+:10D8D00007D197F90431182BD4BF4FF0000EA3F1F4 -+:10D8E000180E3A68022A40F00D81012D01D8032359 -+:10D8F00003E00A2D8CBF05230423E31893F90600E7 -+:10D90000494B9C4201D10B2D6CE0554B9C4204D1FC -+:10D91000022D00F00B810A2DD2E0444B9C4201D134 -+:10D920000B2D58E0424B9C4202D0424B9C4201D10D -+:10D930000B2D11E04B4B9C4202D04B4B9C4204D12F -+:10D940000D2D40F004812E2001E1484B9C4206D170 -+:10D950000B2D00F0F1800D2D00F0F080F7E03E4B34 -+:10D960009C4258D0344B9C4204D10B2D40F0EF80A8 -+:10D970003E20ECE0314B9C4219D0314B9C4206D109 -+:10D98000022D00F0E1800A2D00F0DE80DFE0384B50 -+:10D990009C4206D1022D00F0D5800A2D00F0D280E5 -+:10D9A000D5E0344B9C4202D0334B9C4206D1022D31 -+:10D9B00000F0C6800A2D00F0C380C8E02F4B9C42C7 -+:10D9C0000CD1022D00F0BA800A2D00F0B780032D93 -+:10D9D00000F0BC80092D00F0B980B8E0284B9C42D3 -+:10D9E00003D10A2D00F0A480B1E0164B9C4205D172 -+:10D9F000A5F10C03012B40F29D80A8E0214B9C4235 -+:10DA000003D10B2D00F29A80A1E01F4B9C423DD127 -+:10DA10000C2D00F093800D2D43E0C046BC10860015 -+:10DA2000F0108600241186004009860080C50100A0 -+:10DA3000BC0C8600D00C8600700D86007C09860028 -+:10DA400090098600840D86001CC60100B8C701003D -+:10DA5000340D86005C0D860080118600FC0D86006A -+:10DA6000A4C70100E40C86000C0D8600A4CA0100C6 -+:10DA7000CC098600A4098600B8098600F40986004E -+:10DA800018098600980D8600381186008B4B9C4241 -+:10DA900003D1022D52D00A2D29E0894B9C4202D19C -+:10DAA0000B2D49D053E0874B9C4203D10B2D4ED117 -+:10DAB00032204CE0844B9C4204D10B2D3CD00C2DE9 -+:10DAC00034D044E0814B9C4205D10C2D3ED00D2D2D -+:10DAD0003DD13A203BE07E4B9C4204D1A5F10B03A3 -+:10DAE000012B23D933E07B4B9C4202D10B2D21D05B -+:10DAF0002DE0794B9C422AD10C2D25D00D2D26D11D -+:10DB0000442024E0332D01D800200BE03D2D01D826 -+:10DB1000012007E0632D01D8022003E0942D8CBF83 -+:10DB200004200320231893F9060010E04A200EE099 -+:10DB300042200CE03C200AE0382008E0402006E0CB -+:10DB4000502004E0482002E04C2000E04620CEEBCC -+:10DB5000000323EAE3736345B4BF18466046022A14 -+:10DB600004D199F800309842A8BF1846002209EB6A -+:10DB700002030132082A1871F9D1C0B2CC464A46D4 -+:10DB800000210023013182F83430107382F83C30D8 -+:10DB900001320829F5D1337F13F0010202D097F941 -+:10DBA000044106E097F90431182BD4BF1446A3F1C1 -+:10DBB00018043B68022B01D16B1E0FE0332D01D8F6 -+:10DBC00000230BE03D2D01D8012307E0632D01D890 -+:10DBD000022303E0942D8CBF04230323F2569B19E8 -+:10DBE000997B3E4B9E4205D1A5F16403022B01D8DF -+:10DBF0003E2110E03A4B49B29E4203D1642D00F021 -+:10DC00006C850BE0374B9E4205D1A5F16403022BD6 -+:10DC100001D83E2108E0344B9E420ED0334B9E4249 -+:10DC20000BD0334B9E4208D0324B9E4205D0324B34 -+:10DC30009E4202D0314B9E4214D1A5F16803242BA1 -+:10DC400010D82B4B9E421BD02A4B9E4218D02B4BF8 -+:10DC50009E4215D0254B9E4223D0274B9E4220D07A -+:10DC60004A214422264B9E420CD1A5F16803202B69 -+:10DC700003D98C2D00F04E8548E04021442201E07C -+:10DC80004A2142221F4B9E420DD1642D06D0A5F1A0 -+:10DC900068030C2B3AD83C2140226BE0342140220F -+:10DCA00001E044221146184B9E422FD1A5F1640396 -+:10DCB000102B2BD8422152225FE0C0466809860013 -+:10DCC0001CC6010008C6010050C60100B8C701000B -+:10DCD000A8C90100CCC70100E0C70100B508860053 -+:10DCE00030CA0100D2088600DC0586002E058600B9 -+:10DCF0004B0586006805860085058600330686008C -+:10DD0000F90586006D0686008A0686009F4B9E42B6 -+:10DD10001AD1A5F16403082B98BF3021A5F16E0339 -+:10DD200098BF3422162B98BF4621A5F18603022BFB -+:10DD300098BF3E218C2D08BF3622A5F1950308BF60 -+:10DD400048210F2B98BF4422914B9E4212D1A5F13E -+:10DD50006E03162BA5F1860398BF442198BF3A2283 -+:10DD6000022B98BF3E2198BF3A228C2D08BF482134 -+:10DD700008BF3622874B9E4202D0874B9E4204D179 -+:10DD8000A5F18403082B98BF2C22C4EB020323EADD -+:10DD9000E370C4EB010323EAE37E4A4613790021D2 -+:10DDA000137582F8441009F1080301329A42F5D143 -+:10DDB0004B460A460132187783F84CE00133082AB3 -+:10DDC000F8D1764B9E425BD0754B9E4258D0754B36 -+:10DDD0009E4255D0744B9E4252D0744B9E424FD0BF -+:10DDE000734B9E4236D0734B9E4249D0724B9E423B -+:10DDF00046D0724B9E4243D0714B9E4240D0714BF5 -+:10DE00009E423DD0704B9E423AD0704B9E423DD0D8 -+:10DE10006F4B9E4234D06F4B9E4231D06E4B9E4230 -+:10DE20002ED06E4B9E422BD06D4B9E4228D06D4B18 -+:10DE30009E4225D06C4B9E4222D06C4B9E421FD0FE -+:10DE40006B4B9E421CD06B4B9E4219D06A4B9E423C -+:10DE500016D050E0032D02D14FF03C0E0FE02B1FE7 -+:10DE6000042B0AD9092D00F05984A5F10C03012BCC -+:10DE700000F22E842C2000F02CBC4FF0400E4020ED -+:10DE8000524B9E4202D0524B9E4206D1EB1E402086 -+:10DE9000082B94BF86464FF0000E584B9E4221D16E -+:10DEA000A5F124030C2B03D84FF0300E382019E0D5 -+:10DEB000A5F13403082B02D84420864612E0A5F1D0 -+:10DEC0006403022B03D84FF03E0E34200AE0A5F184 -+:10DED0006803202B03D84FF04A0E442002E08C2D1B -+:10DEE00008BF32204B4600220132187583F844E007 -+:10DEF0000133082AF8D14B4600220021013283F871 -+:10DF0000241083F854100133082AF6D14B460A46F0 -+:10DF1000013283F82C0083F85CE00133082AF7D142 -+:10DF20001E4B89F864E09E4206D01D4B9E4220D0D5 -+:10DF30001D4B9E4277D0E5E0012D00F0BE80022D02 -+:10DF400000F0A380032D00F0BD802B1F042B03D80D -+:10DF500038273C223E21B8E0092D03D13027342256 -+:10DF60003621B2E00A2D00F090800B2D00F0A58044 -+:10DF70009FE0012D00F0A180022D00F08B80032D89 -+:10DF80003ED13227362238219FE0C046A2058600C6 -+:10DF9000BF0586002C078600F40486007E0A8600F2 -+:10DFA0009B0A8600B80A8600F20A8600BD0B86002E -+:10DFB000980E860094C5010050C90100EBC5010010 -+:10DFC00069C7010011C80100F4C70100630F860092 -+:10DFD00014108600B50E860064C6010081C60100DB -+:10DFE000F5C6010012C70100B1C50100CEC5010090 -+:10DFF0002FC701004CC70100880C8600DC05860095 -+:10E000002B1F042B5ED9092D04D130273422362151 -+:10E010004A205BE00A2D3DD00B2D4AD10022174645 -+:10E020001146362052E0012D04D100221746114638 -+:10E030002C204BE0022D37D0EB1E052B15D8032DDD -+:10E0400003D128272C222E212CE0042D27D0082DA7 -+:10E0500025D06B1F022B8CBF002734278CBF0022DA -+:10E0600038228CBF00213A211CE0092D04D12A2737 -+:10E070002E223021422029E00A2D15D00B2D18D157 -+:10E080000022174611462A2020E00022174611469A -+:10E0900040201BE00022174611463E2016E03227A2 -+:10E0A00036223821442011E00022174611463C2038 -+:10E0B0000CE000221746114608E0002217461146E0 -+:10E0C000382003E0342738223A214C204B460024E4 -+:10E0D000042C94BF83F84C7083F84C2001341877DB -+:10E0E0000133082CF4D1C7B24B460024032C94BF53 -+:10E0F00083F85C2083F85C10013483F82C700133C2 -+:10E10000082CF3D1A44B9E4206D0A44B9E420DD0C6 -+:10E11000A34B9E4221D062E0032D45D0092D43D070 -+:10E120002B1F042B38D83027342233E0032D03D1A2 -+:10E130004227462248243AE0042D31D06B1F022B9F -+:10E1400003D84C275022522431E0082D28D0092D25 -+:10E1500022D13E274222442429E0032D03D12E2739 -+:10E160003022322423E0042D03D1302732223424FC -+:10E170001DE06B1F022B03D8322736223A2416E00B -+:10E18000082D03D130273422382410E0092D03D183 -+:10E190002E27322236240AE000221746144606E0D3 -+:10E1A00046274A224C2402E028272C222E244B46C4 -+:10E1B0000021042994BF83F84C7083F84C2001316E -+:10E1C00001330829F5D14B460021032994BF83F878 -+:10E1D0005C2083F85C40013101330829F5D1714B93 -+:10E1E0009E422AD1032D0CD02B1F042B03D8382498 -+:10E1F0003E213C2708E0092D03D000210C460F46A4 -+:10E2000002E034243A2138274B460022042A94BFE6 -+:10E2100083F84C4083F84C7001320133082AF5D161 -+:10E220004B460022032A94BF83F85C7083F85C108D -+:10E2300001320133082AF5D136E05B4B9E422CD1E6 -+:10E24000A5F124030C2B03D84FF0340E38201AE02C -+:10E25000A5F134030C2B03D84FF0340E3A2012E012 -+:10E26000A5F16403282B03D84FF0400E3C200AE0B0 -+:10E27000A5F19503102B8CBF4FF0000E4FF0480E08 -+:10E280008CBF002046204B4600220132187583F8CF -+:10E2900044E00133082AF8D10AE0444B9E4269D099 -+:10E2A000434B9E4200F0DF80424B9E4200F0DB80F9 -+:10E2B000414B9E4200F0D780404B9E4200F0D380FD -+:10E2C0003F4B9E4200F0CF803E4B9E4200F0CB8001 -+:10E2D0003D4B9E4200F0C7803C4B9E4200F0C38005 -+:10E2E0003B4B9E4200F0BF803A4B9E4200F0BB8009 -+:10E2F000394B9E4200F0B780384B9E4200F0B3800D -+:10E30000374B9E4200F0AF80364B9E4200F0AB8010 -+:10E31000354B9E4200F0A780344B9E4200F0A38014 -+:10E32000334B9E4200F09F80324B9E4200F09B8018 -+:10E33000314B9E4200F09780304B9E4200F0F281BC -+:10E340002F4B9E4200F08F802E4B9E4200F08E801D -+:10E350002D4B9E4200F087802C4B9E4200F0838024 -+:10E360002B4B9E427FD02B4B9E427CD02A4B9E4211 -+:10E3700072D0B5E0A5F12403082B01D8382069E05C -+:10E38000A5F12E03022B40F29980A5F13403082B4E -+:10E3900044D84FF0400E95E0D50A8600A00B8600C9 -+:10E3A000DA0B86004E0C860011058600F905860002 -+:10E3B000BCC90100D9C901006ACA01002EC8010008 -+:10E3C00033C90100F9C80100D8C601006DC90100B8 -+:10E3D00030C60100DCC801008AC901004DCA010035 -+:10E3E00085C80100F6C9010016C9010061C5010018 -+:10E3F000A2C8010030CA010087CA010086C7010017 -+:10E400009EC60100BBC6010013CA0100BFC80100BF -+:10E410004BC8010068C8010016068600A5F13E033E -+:10E42000022B03D84FF0380E342050E0A5F16403DE -+:10E43000082B02D84FF0380E42E0A5F16E031E2BD8 -+:10E4400003D84FF0400E322041E0A5F19503102B88 -+:10E4500034D9002086463AE0A5F124030C2B36D8A7 -+:10E460004FF0340E2EE09E4B9E4201D1242D5AE1F6 -+:10E470009C4B9E4203D18C2D29D13A2027E09A4B08 -+:10E480009E4204D1642D1FD08C2D1DD01FE0974BD0 -+:10E490009E4203D1A5F19503102B0DE0944B9E42B3 -+:10E4A00015D1A5F124030C2B10D9A5F134030C2BA5 -+:10E4B0000CD9A5F16403282B08D908E04FF0400ED1 -+:10E4C000442004E0382002E0482000E03C204B4695 -+:10E4D00000220132187583F844E00133082AF8D18C -+:10E4E000844B9E420BD0844B9E4208D0834B9E426D -+:10E4F00005D0834B9E4202D0824B9E426DD1A5F146 -+:10E500002403082B0DD87F4B9E4201D13A2006E010 -+:10E510007D4B9E4202D13420024655E03420382201 -+:10E5200052E0A5F12E03022B08D8774B9E4214BF70 -+:10E530004220402014BF3822342245E0A5F13403A4 -+:10E54000082B02D8442046223EE0A5F13E03022BD0 -+:10E5500006D86D4B3A229E4214BF34202C2033E063 -+:10E56000A5F16403082B06D8674B3E209E4214BFDA -+:10E5700044223A2228E0A5F16E031E2B17D8A5F1FC -+:10E580008603022B09D85F4B9E4201D1442005E04F -+:10E590005D4B9E4201D13C2000E048208C2D10D1E3 -+:10E5A000584B9E420FD0584B9E420CD009E0A5F12B -+:10E5B0009503102B8CBF00204A208CBF00224622DE -+:10E5C00002E0442200E03C224B46002101311A7552 -+:10E5D00083F8440001330829F8D14C4B9E4202D005 -+:10E5E0004B4B9E421ED1A5F124030C2B01D83821A0 -+:10E5F0000EE0A5F134030C2B09D9A5F16403282BF7 -+:10E6000005D9A5F19503102B01D9002100E0402187 -+:10E6100008464B4600220132187583F84410013336 -+:10E62000082AF8D14846002202EB090191F83C3053 -+:10E630001BB990F84C3081F83C304AB999F83D301C -+:10E640000BB1013204E090F84C30012289F83D30E2 -+:10E6500001320130072AE7D94A46002192F84430B6 -+:10E660001BB992F84C3082F844300131013208294C -+:10E67000F4D14846002202EB090191F834301BB96D -+:10E6800090F8443081F834304AB999F835300BB1FC -+:10E69000013204E090F84430012289F8353001322B -+:10E6A0000130072AE7D900229CF824301BB99CF8D6 -+:10E6B0001C308CF824309CF854301BB99CF84C303A -+:10E6C0008CF854300132082A0CF1010CECD12DE009 -+:10E6D00040204FF0000EFFF7E0BB3822FFF79BBA57 -+:10E6E000BBC6010013CA01004BC80100DCC8010011 -+:10E6F0004DCA01004B058600680586008505860029 -+:10E7000033068600A2058600BF058600A7068600A0 -+:10E710005006860036221146FFF7F8BA4FF0380E41 -+:10E72000FFF7ADBB642D3FF4CDAED0E6BDE8F0877A -+:10E730007047C04600207047002070470020704797 -+:10E740007047C0467047C0467047C04600207047BB -+:10E750007047C04603680246D3F86C32D3F8E432FF -+:10E76000987818B1938A181E18BF01207047C046C8 -+:10E770007047C0467047C04670B5037D04469BB1E4 -+:10E78000457D8DB9C068A16900F068DF012363751C -+:10E79000E36906460BB1A0689847D6F1010038BF7F -+:10E7A00000206575257500E0002070BD0846002139 -+:10E7B00010B501614181017201730622F3F340F447 -+:10E7C00010BDC04610B50068F6F70AFC10BDC04683 -+:10E7D00090F832007047C04602460868430D5B055A -+:10E7E0006BB922F07F4323F46003520D83422CBFA8 -+:10E7F0004FF40013002352059B1803430B6070472E -+:10E8000070B510600D461C46084619461646FFF7BF -+:10E81000E3FF2368AB4202D233680133336070BD3B -+:10E82000002070477047C0460020704700207047A6 -+:10E830007047C0467047C0467047C04630B505684F -+:10E84000B5B061B10DF107040171C9220021204664 -+:10E85000F3F3F6F32B6B2146186902F0E3FA35B0B7 -+:10E8600030BDC046406B70477047C04600207047BF -+:10E870007047C046002070477047C0460020704770 -+:10E880007047C046002070477047C0467047C0467A -+:10E890007047C0467047C0467047C0467047C04684 -+:10E8A0007047C0467047C0464FF0FF307047C046C3 -+:10E8B0007047C04600207047002070477047C04630 -+:10E8C0007047C0467047C046002070477047C0463A -+:10E8D00010B513F08BDF024640B1416A11F4002FEE -+:10E8E00004D1036813B141F400234362104610BD04 -+:10E8F0002DE9F3411E46036804461B7E0F469046F1 -+:10E90000002B4BD090F87532002B47D10D6828466C -+:10E91000FFF7A8FF016902468B79B3B1837E13F03C -+:10E92000010F12D0D1F8CC3013F4806F0DD1B4F8B0 -+:10E93000263603F47043B3F5805F14BF40234423AD -+:10E94000CB5813B193F8DF3043BB5168002925DB66 -+:10E95000164B01EA03030BB9184602E0EB8A03F0F9 -+:10E96000070011F0400F19D0114B02A91B5C204683 -+:10E9700041F8043D33600CF083D8B0F1FF3F0DD077 -+:10E98000019A3368934209D00A4B32609A5CEB8A51 -+:10E9900002F0070223F007031A43EA8220463946B1 -+:10E9A0004246334616F000DBBDE8FC8140000180A2 -+:10E9B000C4D2850038AB010010B540F0B9D910BD04 -+:10E9C000F0B585B00A9C0D4600940B9C1F4601943F -+:10E9D0000C9C064602940D9C03942AF0BFDDAB7993 -+:10E9E00043B13946304646F0F3DF014610B13046B8 -+:10E9F00046F0E6DE05B0F0BD2DE9F041D0F8B043B9 -+:10EA0000D0F8AC7323F096D894F82F30064603B3B1 -+:10EA100000257B19D3F84C42C4B1A379B3B1237953 -+:10EA2000A3B1A36D13F0020F10D094F884306BB132 -+:10EA3000F7F3E8F5D4F890102AF09EDC30B100230B -+:10EA4000C4F88830C4F88C3084F884300435202D24 -+:10EA5000DFD13046BDE8F0812DE9FF4107461D4674 -+:10EA60009E6B146947F02CDE8046002834D1337A3F -+:10EA7000022B31D1A3797BB3B5F8683063B3A26DB3 -+:10EA800040F2371302EA030333B394F884301BBB1C -+:10EA9000D4F888303A6853B9D2F88C30D3F8E421EE -+:10EAA0000132C3F8E4213C23C4F8883009E0D2F8ED -+:10EAB0008C30D3F8E4210132C3F8E421012384F837 -+:10EAC0009430002394F94820384600930293296F2C -+:10EAD0001133019647F0CCD9404604B0BDE8F0812F -+:10EAE0002DE9F74F80460E4693461F46002B5FD018 -+:10EAF00001295DD14FF4C0730193FCF3FBF24FF495 -+:10EB000040718246F8F3E4F0044610B94FF0FF3547 -+:10EB100055E000214FF44072F3F392F24046314643 -+:10EB2000224601ABF3F322F110F11E0F3AD1019B03 -+:10EB30004FF0FF325D004A2323700B2363701533BF -+:10EB40002371042363716FF02F03A3719233237237 -+:10EB50006FF0560363724FF002096319A270E270FE -+:10EB600084F8079003F8022C03F8012C07F10C033A -+:10EB70009D4202DC6FF00E050DE059463A4604F165 -+:10EB80000A00F3F3F9F195FBF9F3404631462246CA -+:10EB9000F3F342F10546504621464FF44072F8F334 -+:10EBA000A7F00CE0504621464FF44072F8F3A0F075 -+:10EBB000404631465A463B46F2F304F205462846A3 -+:10EBC000BDE8FE8FF0B587B0119C0D4616461F4676 -+:10EBD00024B1A16811B10120FCF714FD10B96FF048 -+:10EBE00016000FE00C9B294600930D9B32460193C3 -+:10EBF0000E9B059402930F9B0393109B04933B463B -+:10EC0000FEF39EF307B0F0BD2DE9F0411F4690F8EA -+:10EC10004038054613F0080F0E461ED0536A02F125 -+:10EC2000240413F0100F18D1002B16DB896811F49F -+:10EC3000807F0CD15FB1E36913F0006007D1C1F3AD -+:10EC4000402223F0004343EAC273E36106E0284612 -+:10EC500031463B461BF0EADA00E00020BDE8F081D7 -+:10EC600070B50546D0F8B40058B103784BB1F3F74E -+:10EC7000A9FD044630B9D5F8B4000121F3F3CEF76D -+:10EC800000E001242846F6F38FF224B9D5F8B40049 -+:10EC90002146F3F3C3F770BD10B5FFF787FD10BD34 -+:10ECA00010B5F9F71FFE10BDB0F8543810B50BB110 -+:10ECB0001BF0F2DB10BDC04610B5044638B1026847 -+:10ECC0002AB121B992F80B370BB182F80B17204605 -+:10ECD0001AF044DA10BDC04610B521B11AB1536E16 -+:10ECE0000BB140F0EBD810BD036A10B50C46002BF9 -+:10ECF0002CD0036809691B68B4F814E093F89530C8 -+:10ED00002BB1E38A13F0800F01D11E2200E00C2208 -+:10ED100002F10B039E4519D38B188A5C591C5B7852 -+:10ED200003EB02239BB2B3F5006F0FD14B784A1C63 -+:10ED30001B09042B0AD1537A012B07D1436A0133F3 -+:10ED40004362C3680133C360002002E0214641F002 -+:10ED5000FFDF10BD036810B51A68536B2BB192F832 -+:10ED6000443013B133F072DA00E0002010BDC04629 -+:10ED700010B50C462FF084DC18B994F8F53284F8FD -+:10ED8000F43210BD70B5012205460C46D1F84C1581 -+:10ED900030F0DEDF284621462FF0AEDB70BDC046E6 -+:10EDA0000C2A70B504460E4615464DD80122AA40DD -+:10EDB00041F2485302EA0303002B45D0D0F8B436A1 -+:10EDC0004BB1D3F8D83233B15B68012B3CD0032B65 -+:10EDD0003AD0022B38D0204618F008D8002833D17A -+:10EDE000D4F868014369012B2ED05EB1B3794BB1E1 -+:10EDF000B36D13F0020F05D0D6F8883013B16FF061 -+:10EE000019002BE0082D01D00C2D02D183790BBB0A -+:10EE10000EE083790BB3D4F82835022B04D094F894 -+:10EE2000F43713F0010F15D0092145F0C1DB14E0D0 -+:10EE3000082D12D1204631460222002327F004DC9F -+:10EE400058B14FF0FF3009E0204631462A462BF0FA -+:10EE5000AFDF03E06FF0180000E0002070BDC04697 -+:10EE60002DE9F043054685B099460E4690460D9C27 -+:10EE70009DF83870F9F712FDD5F8B03393F84630A5 -+:10EE800013F0030F17D0B26D40F2371302EA0303F9 -+:10EE90008BB190F8693713F0010F0CD0636813F44D -+:10EEA000803F08D0236C012B05D100222146134658 -+:10EEB000009213F09BDE0C9B28460093314642469D -+:10EEC0004B460194029724F0DBDB05B0BDE8F083EC -+:10EED0002DE9F04107461CF0D5DA0026BB19D3F81E -+:10EEE0004C42B4B1D4F88C509DB9A3798BB1A36DC9 -+:10EEF00013F0020F0DD094F8843053B1F7F382F37E -+:10EF0000D4F890102AF038DA18B1C4F8885084F890 -+:10EF100084500436202EE1D1BDE8F08170B590F820 -+:10EF2000A131054663B903681B6F4BB1D0F81C488B -+:10EF3000F7F368F3D5F82038E41A2418C5F81C480C -+:10EF4000284616F0B1DE70BD10B588B00A9C00945A -+:10EF50000B9C01940C9C02940D9C03940E9C0494B5 -+:10EF60000F9C0594109C0694119C0794F5F3B8F43B -+:10EF7000044B0421D3F88C300A46044698472046B7 -+:10EF800008B010BDE0A6850070B504460D4620F01F -+:10EF900041DC294606462046F9F7DCF8304670BDCC -+:10EFA0002DE9F0410546D5F8D8320E465B68174684 -+:10EFB000012B0068D5F8DC4202D14FF0000805E0D3 -+:10EFC000042914BF4FF000084FF001080368DB6903 -+:10EFD0001A6D636A934238BF62624EB9D4F89010DA -+:10EFE00031B1406894F89420F7F382F6C4F8906049 -+:10EFF000284631463A4627F0EBDBB8F1000F01D046 -+:10F0000000236362BDE8F0812DE9F04385B00C9FD9 -+:10F0100005469846D7F80090D2F8D4621446009777 -+:10F020000CF0E6DF296891F8463013F0030F3FD06B -+:10F03000D4F8CC2012F4805F3AD196F93430002B0A -+:10F0400036D14B6B002B33D012F0020F30D13B681E -+:10F050000DF109001849032208EB0304F2F38CF7C1 -+:10F0600095F8FA3133B196F96A30002B02DA95F847 -+:10F070000A0700E0002008EB0901A14201D20021AB -+:10F0800000E0091B02238DF80C3000238DF80D30B1 -+:10F0900001338DF80E300DF109038DF80F00009348 -+:10F0A00020460723DD221DF071D83B6809333B6001 -+:10F0B00005B0BDE8F083C04672A701000FB430B5BB -+:10F0C000104BADF5037D9E4501D1002513E002A84C -+:10F0D00087AB053840F20121869A8193F3F3E6F07D -+:10F0E0000024054605E002AB053BE05CF7F328F59C -+:10F0F0000134AC42F7DB28460DF5037DBDE8304016 -+:10F1000004B07047DB62820010B502490248FFF785 -+:10F11000D5FF10BD5FCB01003CCB0100C36970B5CA -+:10F1200013F4006F0E460546016915D00368D3F845 -+:10F130008C20936B5C1C4FF47A739463B4FBF3F2F2 -+:10F1400002FB134323B90748C96B2246FFF7B6FFFA -+:10F15000EB6923F40063EB61284631462EF032DE82 -+:10F1600070BDC046FCAD010010B50446FAF3C6F20E -+:10F17000002384F8173284F8183210BD10B5074CFC -+:10F180002378012B09D0064B1B78012B05D00123D6 -+:10F190002370FBF381F20023237010BDE2F801001D -+:10F1A000E3F8010070B50546F3F7ECFB01280146D2 -+:10F1B00007DD044C012328462370FBF3FBF00023FA -+:10F1C000237070BDE3F801002DE9FF410B9F0D4650 -+:10F1D000B7F862400A9E14F00F0FDDF8308014D0AB -+:10F1E00040F2371406EA04047CB100960197CDF88A -+:10F1F00008800BF0F3DF98F934302BB16B78022BD9 -+:10F2000002D9023B02386B700546284604B0BDE8BF -+:10F21000F081C04610B5064902690B782BB1D2F8CF -+:10F22000D03013B100230B7001E01BF039D810BDB2 -+:10F23000E4F8010010B58B7913B1044B01221A7068 -+:10F240002FF09EDE014B00221A7010BDE4F8010081 -+:10F2500010B5044C24780CB1002001E015F076DBE9 -+:10F2600010BDC046E1F801002DE9F0410546084611 -+:10F2700016461F460C46FFF7F5FA95F84038024649 -+:10F2800013F0080F18D0D0F8F00008B91369986887 -+:10F29000E38A0F4A03F00703D35CC0680D2B01DD3E -+:10F2A0000F2200E05A1C0C2302FB03039B8A032B52 -+:10F2B00002D9084B01221A7032463B4628462146A5 -+:10F2C00026F044DF034B00221A70BDE8F081C046EF -+:10F2D00090E08500E1F8010070B5044C8568A54216 -+:10F2E00001D1002001E0F3F3ADF170BD0800002072 -+:10F2F00070B505460E461CF0CFDF0446C0B131465E -+:10F30000284640F26C521DF0D9D8064620B928464E -+:10F3100021461DF035D80AE0214640F26552F2F34D -+:10F320002BF62846214640F26552F7F3E1F43446C5 -+:10F33000204670BD2DE9F04385B000230C4611999D -+:10F3400017460546DDF83880039330F053D807F0B0 -+:10F350000103009306462146286842460F9B13F09E -+:10F36000B3DF814600285ED10D9B032B04D903A88F -+:10F370000C990422F2F300F6092F06D8DFE807F013 -+:10F38000080D0505141F333A474C6FF0160949E084 -+:10F3900028460AF0D3DC40B229E0284603990AF057 -+:10F3A000F7DC00283CD03DE0B6F95E300BB102201E -+:10F3B0001DE0B6F95C30181E18BF012017E0039B52 -+:10F3C000022B06D14FF00003A6F85C304FF001038A -+:10F3D00006E0003B18BF0123A6F85C304FF00003A5 -+:10F3E000A6F85E301EE0D5F83407F9F75BFAC8F8E6 -+:10F3F000000017E0D5F83407039CF9F75BFA844264 -+:10F400000EDCD5F834070399F9F750FA0AE095F8BD -+:10F41000C334C8F8003005E0039B85F8C33401E02D -+:10F420006FF01C09484605B0BDE8F0832DE9F041B6 -+:10F4300086B00E4698460C9900230546174605935C -+:10F440002FF0D8DF044687B1B8F1030F04D905A81F -+:10F4500039460422F2F390F53FB1B8F1030F04D915 -+:10F4600005A839460422F2F387F51C2E2ED004DCC1 -+:10F47000152E0BD0162E15D005E0D72E56D0D82E2F -+:10F480005FD09F2E28D06FF0160074E0B4F95E3084 -+:10F490000BB1022004E0B4F95C30181E18BF012043 -+:10F4A000386067E0059B022B06D14FF00003A4F8FB -+:10F4B0005C304FF0010306E0003B18BF0123A4F8C5 -+:10F4C0005C304FF00003A4F85E3053E02B6801215C -+:10F4D0001869FBF3EBF64DE0A8F104030622B3FB39 -+:10F4E000F2F33B60D5F80005002304A9059345F02D -+:10F4F000F1DD14E0237E13F0020F10D0059B591CA0 -+:10F500003B688B4202D26FF00D0034E0B81E062239 -+:10F51000059101FB020004F11A01F2F32DF504A894 -+:10F5200045F0E0DD04460028E4D121E02B681B7E95 -+:10F53000DBB1D5F868319879B8B9B5F816373B60C2 -+:10F5400019E02B681B7E83B1D5F868319C7964B9CA -+:10F550002B6B01221B6828460093394623460192F3 -+:10F5600002940394FCF7E2FC05E06FF0010002E076 -+:10F57000059B3B60002006B0BDE8F0812DE9F04717 -+:10F5800004468946FFF358F5F7F33CF094F85431FC -+:10F590008046012B1ED82546002717E06E69B379F7 -+:10F5A000022B11D1B4F86C3013F4807F0CD02046BC -+:10F5B00049464246F3F7C0FD30B90423B37194F8CD -+:10F5C000CD30013B84F8CD3001370435B4F910302B -+:10F5D0009F42E3DBBDE8F08730B54FF0000E0446F4 -+:10F5E00091B08C461546704609E023185A690EF111 -+:10F5F000010ED1794DF80010536B0430D371B4F97A -+:10F6000010309E45F1DB204661462A46FEF308F79E -+:10F610000020014606E063185A695DF801300130A8 -+:10F62000D3710431B4F910309842F4DB11B030BD1D -+:10F630002DE9F0410C2904460D46164690F8537109 -+:10F640000DD100210122FEF3EBF62046002101221C -+:10F65000FEF3A2F6002384F8CE3084F8CD30A36EFA -+:10F660002046B3F1FF3F08BF84F8563129463246A1 -+:10F67000FEF3F6F7B4F86C3003F0C003C02B16D1DC -+:10F68000D4F85C319BB194F85331BB420FD9E36895 -+:10F69000A1689868FFF3E2F7E368A1689868D4F876 -+:10F6A0005C210123FFF392F74FF0FF33A366BDE81F -+:10F6B000F081C046836E10B5B3F1FF3F01D0FEF379 -+:10F6C00003F310BD2DE9F04104460D46866EFFF3AD -+:10F6D00029F4074690B9042204F5AE7005F114012F -+:10F6E000F2F34AF4D4F85C314FF47A7203FB02F37C -+:10F6F000B6F1FF3FC4F85C3108BFA6663846BDE8E6 -+:10F70000F081C0460E2937B505468E4614460BD00B -+:10F710000F2910D1114601A80422F2F32DF4284636 -+:10F720000199F3F7A5FD08E0B0F85831002003F087 -+:10F730000103136001E0FEF34DF73EBD70B51446C2 -+:10F740000546FEF303F723680BB10223AB6570BDDA -+:10F7500070B50D460446FEF361F5014610BBA36D7E -+:10F76000EDB1FBB9D4F854210F4B02EA03037BB18E -+:10F7700094F85431022B04D194F8573113F0010F4F -+:10F7800005E0012B07D194F8573113F0020F02D195 -+:10F790006FF0010300E0002384F8563102E00BB162 -+:10F7A00084F85601084670BDFF0000FF10B50446FE -+:10F7B000FEF3C6F4002384F85731A4F85831C4F896 -+:10F7C0005C3184F8563110BD2DE9F041A2B0882299 -+:10F7D00005460C4690F8558190F8567190F85461A2 -+:10F7E0006846F2F3C9F328462146FEF313F40246B5 -+:10F7F000002836D1009B85F856719E4285F85461E9 -+:10F800002CD01BB995F8573173B112E0022B04D1FB -+:10F8100095F8573113F0010F05E0012B07D195F84A -+:10F82000573113F0020F02D16FF0010314E096B9C3 -+:10F830000DE0012E02D113F0010F05E0022E05D1DB -+:10F8400095F8573113F0020F05D107E036B995F856 -+:10F850005531434502D2002385F85631009B85F887 -+:10F860005431104622B0BDE8F081C0462DE9F04188 -+:10F8700004460E46154690F85671FEF3C7F18646CB -+:10F88000A0B92A4601460DE07318DB88083113F051 -+:10F89000100F06D194F8573143F0010384F8573123 -+:10F8A00002E0083A072AEFD884F856717046BDE89E -+:10F8B000F081C0462DE9F04104460D46164690F809 -+:10F8C0005671FEF33FF1864698B9294632460CE060 -+:10F8D0004B6A13F0100F06D194F8573143F002032E -+:10F8E00084F8573103E0383A3831372AF0D884F8B1 -+:10F8F00056717046BDE8F081012902D14FF6FF70C4 -+:10F9000010E0D0F8BC304FF00002082BD0F8B03037 -+:10F9100008BF41F40071A3F8D813B3F8DA33A0F8A4 -+:10F92000202698B27047C046D0F8B030A3F8D8135C -+:10F93000A3F8DA237047C046D0F8B0300021A3F80E -+:10F94000D8134FF0010230B5B3F8DA434FF0020597 -+:10F95000A3F8D823B3F8DA23A3F8D853B3F8DA33EB -+:10F9600092B29BB2A0F82016C4F3031040EA0470D0 -+:10F9700042EA032240EA023030BDC04670B5054677 -+:10F980000E461446FFF7B8FF314600EA0402284647 -+:10F99000FFF7CAFF70BDC04670B505460E46144657 -+:10F9A000FFF7AAFF40EA04023146284692B2FFF769 -+:10F9B000BBFF70BD2DE9F0411546064688461C4642 -+:10F9C000FFF79AFF2C4020EA0502224330464146C9 -+:10F9D00092B2FFF7A9FFBDE8F081C0462DE9F041E2 -+:10F9E0001C46069B90461980079D0E46FFF784FF34 -+:10F9F000089B28801E802B8804EA080423EA080359 -+:10FA0000099A23431380BDE8F081C046D0F8B03096 -+:10FA10004FF00002A3F8FC13A0F82026B3F8FE0371 -+:10FA200080B27047D0F8B03041EA0242C3F8FC23FC -+:10FA30007047C046D0F8B030A3F8FC13B3F8FE13FB -+:10FA40000A40A3F8FE234FF00003A0F820367047C9 -+:10FA500010B5D0F8B040A4F8FC13B4F8FE339BB254 -+:10FA60001A434FF00003A4F8FE23A0F8203610BD7F -+:10FA700010B5D0F8B0401340A4F8FC13B4F8FE134E -+:10FA800089B221EA02010B43A4F8FE334FF00003D0 -+:10FA9000A0F8203610BDC0462DE9F04106460C46C0 -+:10FAA0002CE0254635F8023B571E990403F44043E9 -+:10FAB000890CB3F5804F11D001DC3BB11CE0B3F5EC -+:10FAC000004F10D0B3F5404F12D015E03046628899 -+:10FAD00035F8023FFFF7CCFF013F0DE0304662886A -+:10FAE000FFF7A0FF08E030466288FFF7A3FF03E0BE -+:10FAF00030466288FFF7ACFFAC1C7A1E002AD0DCCF -+:10FB0000BDE8F0812DE9F0411C46069B9046198026 -+:10FB1000079D0E46FFF77AFF089B28801E802B88E2 -+:10FB200004EA080423EA0803099A23431380BDE882 -+:10FB3000F081C046002380F8E3304FF0FF3241F2FD -+:10FB40000A03C25400F58A500270704710B531B1F3 -+:10FB500040F23B414FF6F872FFF76CFF03E00249B9 -+:10FB60000422FFF799FF10BD32D2010060B1B0F856 -+:10FB7000DE00B0F5006F05D0B0F5406F04D1A0F500 -+:10FB8000386002E0402000E000207047012380F848 -+:10FB9000E130704780F824167047C04690F924067B -+:10FBA0007047C0467047C04610B1C06900B1417788 -+:10FBB0007047C04610B1C06900B101777047C046B8 -+:10FBC00010B590F8E3300446002B45D14FF06401A6 -+:10FBD0004FF44872A0F87428A0F86C18A0F86E18BA -+:10FBE000C0F870381A46A31802324FF06401102A88 -+:10FBF000A3F87618F7D14FF00003A4F82438A4F83E -+:10FC0000AC37A4F8AE374FF00A034FF00A02A4F85D -+:10FC10003038A4F83238636A4FF01401A4F8282869 -+:10FC2000A4F83628A4F82A28A4F83828A4F820280C -+:10FC3000A4F82228A4F89027A4F892274FF05002A5 -+:10FC4000A4F82618A4F89427A4F834180BB1204679 -+:10FC50009847012384F8E33010BDC04610B5FFF784 -+:10FC60006BFE10BD2DE9F84F0C46D1F810A00D68C1 -+:10FC70009B468968E368064643EA812311469AB2A7 -+:10FC8000BDF82880FFF7CEFE0027B9461EE0BAF186 -+:10FC9000200F0BD159F8052030465946120CFFF7BA -+:10FCA000C1FE39F80520304641460AE0BAF1100F8E -+:10FCB00004D135F817203046414602E07A5D3046DF -+:10FCC0004146FFF7AFFE013709F1040963689F421F -+:10FCD000DDD3BDE8F88FC0462DE9F74F0D460193FF -+:10FCE000D1F810B00E68EB688968074643EA8123B3 -+:10FCF00011469AB2BDF83090FFF794FE4FF000081D -+:10FD0000C24626E0BBF1200F0FD149463846FFF727 -+:10FD10007DFE019904464AF806003846FFF776FE54 -+:10FD200044EA00444AF806400FE0BBF1100F06D148 -+:10FD300038464946FFF76AFE26F8180005E03846BF -+:10FD40004946FFF763FE08F8060008F101080AF1CA -+:10FD5000040A6B689845D5D3BDE8FE8F7FB5029342 -+:10FD6000089B03910593099B0192049301A90A9BA7 -+:10FD7000984707B000BDC0467FB50293089B03912A -+:10FD80000593099B0192049301A90A9B984707B028 -+:10FD900000BDC0460B46D0F8F81012B141EA03038B -+:10FDA00001E021EA0303C0F8F830704700B5D0F84D -+:10FDB000F8308E4621B143F01003C0F8F83012E05D -+:10FDC00023F0100312F0010FC0F8F8300BD041F20D -+:10FDD000C413C258C369196A986E814294BF7146B0 -+:10FDE000091AC2F8901000BD00207047A0F8DE107C -+:10FDF0007047C046A0F8DA107047C046B0F8DA0085 -+:10FE00007047C04640F6C313984201D800200BE06B -+:10FE100041F2C843984201D8012005E041F2446311 -+:10FE200098428CBF032002207047C0467047C046EE -+:10FE300000B5002286460748910030F8223073450D -+:10FE400002D10B18588803E001320E2AF3D10020AA -+:10FE500000BDC046C0CB010010B5C8B2FFF7E8FF37 -+:10FE6000FFF7D0FF10BDC04610B541F21823C45CA7 -+:10FE70004FF0000C134B3CF803E0BEF10E0F8CBFAB -+:10FE80004FF480524FF400524EF4306342EA0300C4 -+:10FE90002CB1BEF1940F02D9BEF1A50F0AD90229E7 -+:10FEA00003D1BEF10E0F0BD904E0012902D1BEF13E -+:10FEB0000E0F05D80CF1040CBCF1380FDAD1FF207D -+:10FEC00010BDC046C0CB010010B590F8B232144648 -+:10FED0000B6090F82B3653B190F8F83690F92A263B -+:10FEE00023B1534243F080430B6000E00A6014B139 -+:10FEF00090F8F7362370002010BDC04610B5864636 -+:10FF00001C4641F20B031EF8033002989B000E2999 -+:10FF1000137008D80028ACBF0EEB00030EF10003ED -+:10FF200093F81E3127E07F23237030EA200028BF9A -+:10FF300004200022114BD35A994202D00432382AAD -+:10FF4000F8D1A1F122031E2B04D80EEB000393F885 -+:10FF500083312370A1F16403282B04D80EEB000336 -+:10FF600093F8E8312370A1F19503102B04D80EEB20 -+:10FF7000000393F84D32237010BDC046C0CB010082 -+:10FF80002DE9FF4700250746884691469A46FF26F9 -+:10FF90002C461EE0009341460DF10E020DF10F03B9 -+:10FFA0003846FFF7ABFF41F2D623FA5C9DF80F10FD -+:10FFB00053B2994201DC002302E0C2EB0103DBB241 -+:10FFC0008DF80F30AB4228BF1D46B34238BF1E46E6 -+:10FFD0000134142CE3B2DDD189F800508AF80060B6 -+:10FFE000BDE8FF877047C04690F829067047C046B5 -+:10FFF000B0F8DA3003F47043B3F5805F09D1032A17 -+:020000021000EC -+:1000000018DDA2F16503032B14D9A2F1C9030F2B4C -+:1000100010D9132A0EDCA2F13403642B0AD9A2F101 -+:10002000A9031F2B06D9A2F1D103072B94BF0020EF -+:10003000012000E00020704770B590F8DA500446C7 -+:100040002846FFF7F5FEB4F8DA3003F47043B3F551 -+:10005000005F01D0002004E02B1903F598533F33D3 -+:10006000187940B270BDC04600B54FF0000E00EBED -+:100070000E021EF801300EF1010EBEF1040F82F8DF -+:100080002C36F4D14FF0000E01EB0E0200EB0E0304 -+:1000900012790EF1010EBEF1080F83F83026F3D16C -+:1000A00000BDC04680F8E0107047C046C369996142 -+:1000B0007047C04680F8D5104176704780F8D91057 -+:1000C0007047C0467047C04690F81A067047C04651 -+:1000D00041F21403C35C33B141F20C2380F81A16C9 -+:1000E00080F81B16C154704790F8D83013B1002324 -+:1000F00080F8D83000207047C369012093F8813020 -+:100100000B70704722B10023C0F8D83FA0F8DC3F45 -+:1001100041F21003C15001207047C0460022C1695E -+:1001200010460B1893F982300130D2180828F8D104 -+:1001300092FBF0F040B270477047C0466FF0160077 -+:100140007047C04670B541F20E23C35C04468B4233 -+:100150000D46164603D0D0F8883003B1984741F2D7 -+:100160001023E652023BE55470BDC0460021C3692E -+:10017000CB180131082983F88220F8D10021C36906 -+:100180006FF05B02CB180131082983F88220F6D189 -+:10019000C2690023C2F88C30D36E032B08D1D0F88B -+:1001A000E83F13F0010F03D0136A0833C0F8E03FB3 -+:1001B00000F58A530233002204E0002241F2C21308 -+:1001C000C25470474FF6A47101321980198402336A -+:1001D000102AF7D1F1E7C04649F675334B6000238A -+:1001E0000B60F0B50C469842ACBF01214FF0FF31D7 -+:1001F00003F5340301FB03F103F53403081890FB06 -+:10020000F3F202FB1303581A03D4C31301335B1038 -+:1002100004E04342DB1301335B105B425A2BD4BF33 -+:100220000023012313B1A0F5340014E0002803DB00 -+:10023000C31301335B1004E04342DB1301335B1053 -+:100240005B4213F15A0FACBF002301230BB9012607 -+:1002500003E000F534004FF0FF364FF0000EF44697 -+:100260007546604561682268144F0BDD41FA0EF354 -+:100270009B18236042FA0EF3C3EB01036360EB5952 -+:100280009C440BE041FA0EF3C3EB0203236042FAF5 -+:100290000EF35B186360EB59C3EB0C0C0EF1010E0F -+:1002A0000435BEF1120FDCD1636806FB03F3636013 -+:1002B000236806FB03F32360F0BDC0460CCC0100AD -+:1002C00080EAE071A1EBE0710022D0B251FA00F3B4 -+:1002D0000132002BF9DC70470146002000B586464C -+:1002E0004FF0804343FA0EF31A188A424FEA500047 -+:1002F00002D8891A43EA00000EF1020EBEF1200F67 -+:10030000EED1884238BF013000BDC046C36983F8D2 -+:100310009010C36983F89120C36983F89210C36970 -+:1003200083F893207047C046C36983F892107047E2 -+:1003300041F20633C256013BC0568242B4BF01208F -+:10034000022070470048704754CC010000207047DD -+:100350007047C046084670470020704741F2C813F6 -+:10036000C05803E0C3888B4202D000680028F9D14E -+:100370007047C04610B5B0F8DA10FFF7EFFF10BDB8 -+:10038000C3699B6913F0005F09D0D0F8B0304FF01B -+:100390000302A3F8B4264FF0FF02A3F8B826704773 -+:1003A000D0F8F83013F0060F0CBF00200120704782 -+:1003B0002DE9F0410F46B0F8DA10044615461E4606 -+:1003C000FFF74AFD40B9B4F9FC302B60B4F9FE30B8 -+:1003D0003360B4F900313B60BDE8F081D0F8A8008B -+:1003E0007047C04670B541F2C813C15805460AE0CF -+:1003F0000B6841F2C8142B51EB694FF43D729868B9 -+:10040000F6F376F429590029F2D141F2C81305F523 -+:100410009152E950043BEA504FF6CE70F033E85267 -+:10042000C2F8901070BDC04610B590F8E93094B095 -+:1004300043F0010380F8E93004460021302201A88E -+:10044000F1F3FEF5002110220DA8F1F3F9F50021DA -+:10045000042213A8F1F3F4F511A800210822F1F306 -+:10046000EFF594F8E930002023F0010384F8E93037 -+:1004700014B010BD70B506460D4610461446002156 -+:100480001C22F1F3DDF500200F4BC25A41F2182374 -+:10049000F35C1BB1942A01D9A52A10D9022D02D1EF -+:1004A0000E2A04D90BE0012D09D10E2A07D9D10853 -+:1004B00002F0070301229A40635C13436354043043 -+:1004C0003828E1D170BDC046C0CB010010B50C4644 -+:1004D000002103F01DF82070012010BD10B500218F -+:1004E00003F016F840B210BD41F2C41310B5C45861 -+:1004F000F433C15819B1C369186940F02DD90023EC -+:100500006370A37010BDC04610B59E462BB941F272 -+:10051000F713C35C704613600FE041B1012906D0A8 -+:10052000022904D0032902D06FF01C0005E041F23B -+:10053000F713C154FFF7D8FF002010BD41F2B823D4 -+:10054000C15810B509B9084607E0C369186940F0F9 -+:1005500003D9D0F1010038BF002010BD10B541F221 -+:10056000E423C35C0BB104F08BFD10BD10B503F0A8 -+:10057000ADFB10BDC36970B5DC681B6D054613F09B -+:10058000010F0E4608D02046FAF392F420B1EB6931 -+:100590009B6913F0005F12D1EA69136D13F0010F2C -+:1005A0003BD0536D13F0800F37D1D068FAF31EF6AD -+:1005B000002832D0EB699B6913F0005F2DD0D5F88D -+:1005C000F83013F0020F28D1EEB106F47043B3F502 -+:1005D000005F18D163691149232BB4BF00230C239A -+:1005E000F2B2B8BF0F2120469A400123FAF368F413 -+:1005F00063690B49222B2046D8BF7021CCBF4FF432 -+:100600000072102206E0636904492046222BD8BFFD -+:100610000F2100220123FAF353F470BD00F0555569 -+:10062000000E5555D0F8B030C269D3F82031136DA3 -+:1006300070B513F0010F04460D4608D0D068FAF3E8 -+:1006400037F420B1E3699B6913F0005F11D1E269CF -+:10065000136D13F0010F18D0536D13F0800F14D1E8 -+:10066000D068FAF3C3F580B1E3699B6913F0005FCA -+:100670000BD025B920462946FFF77CFF0AE020462B -+:10068000B4F8DA10FFF776FF00E01DB10449204608 -+:10069000062202E0034920460E22FFF7FDF970BD55 -+:1006A0003AD2010046D2010010B514299E46D0F876 -+:1006B000A82004D015290CD06FF016000CE092F998 -+:1006C0001A3002A941F8043F70460422F1F354F4B1 -+:1006D00001E0039B9376002010BDC04610B590F852 -+:1006E0001A360C462BB10231224601F089FDA3785F -+:1006F000637010BD10B5012103F06AFA10BDC04649 -+:100700002DE9F0418A79CB790D4642EA03216B79D4 -+:100710002A79074642EA0328C3695B690A2B07D98D -+:10072000EB7C1B0213F4807002D10123EB7735E0E0 -+:100730002A7A6B7A384601F0FF0442EA0326FFF773 -+:100740004DFE7F2C1B4AC8BFA4F58074B30AD35654 -+:1007500090F85F00E21818F4006F14BF41F22B33D9 -+:1007600041F22A33FB56D11843B2C918AA7DEB7D5A -+:100770007F2942EA0322C2F3C702C8BFA1F58071F4 -+:100780000E2AD4BF4FF400534FF4805342F430622A -+:10079000384649B243EA0202FFF7DCFD6A79C1B28A -+:1007A0002977384649B2C2F3801201F005FBBDE853 -+:1007B000F081C04614EF010010B590F8E93096467C -+:1007C00053B313F0010F19D0D0F8F0308B420FD192 -+:1007D000C369D3F88C209B1883F882E0C269D2F8F1 -+:1007E0008C30072B01D1002300E00133C2F88C309C -+:1007F00090F8E93023F0010380F8E93090F8E9300F -+:1008000013F0020F08D023F0020380F8E930C36927 -+:10081000724618693FF0B4DF10BDC04690F8E93069 -+:1008200010B5A3B9012902D0022902D003E0C0F813 -+:10083000F02080F8E910C3691B6AC0F8EC3090F82A -+:10084000F53F23B111466FF05E02FFF7B5FF10BD13 -+:1008500037B5044602F016FFE3691A6A01321A62DC -+:1008600094F8E830002B77D041F25233E35A1BB1B1 -+:10087000A4F85E38A4F8603841F25633E35A1BB14D -+:10088000A4F85838A4F8543841F25433E35A1BB151 -+:10089000A4F85238A4F85638E369196A1A6EB1FB05 -+:1008A000F2F302FB131323B92046B4F8DA10FFF772 -+:1008B00061FED4F8F83013F00E0F05D12046012167 -+:1008C00094F8DA20FFF7AAFF94F8E9304BB1E36916 -+:1008D000D4F8EC201B6A9B1A052B02D9002384F85C -+:1008E000E93041F21805615929B1E3691A6A1B6EB2 -+:1008F000521A9A420BD3D4F8F83013F0020F06D1F3 -+:100900002046FFF771FA10B1E3691B6A6351D4F80E -+:10091000F83013F00F0F1FD1D4F88C300BB12046F4 -+:100920009847E36918693FF09FDE68B1E36901A960 -+:1009300018690DF107023FF0A1DE20469DF807106F -+:10094000BDF80420FFF7FEFBD4F8F83013F00F0FCA -+:1009500002D1204603F0BAF900203EBD10B504468E -+:10096000FFF74CFA0221C2B22046FFF757FF10BD35 -+:10097000C36973B5012983F8811004460D46C36924 -+:1009800006D918690122032300930021134605E0CC -+:10099000186900210323009301220B463FF094DEE7 -+:1009A000E269537F002B30D0D4F8B030D3F8203137 -+:1009B00083F0010313F0010602D110693FF0EADE73 -+:1009C000012D0FD90222134620464FF48261FFF712 -+:1009D0004FF820464FF482610122022D14BF0023FC -+:1009E00001230BE020464FF4826102220023FFF72F -+:1009F0003FF820464FF4826101222B46FFF738F87A -+:100A00001EB9E36918693FF0B1DE7CBDC36970B5FA -+:100A100047F67F750446582118692A463FF088DE5C -+:100A2000E3695A2118692A463FF082DEE3697021A2 -+:100A300018692A463FF07CDEE369722118692A466C -+:100A40003FF076DE70BDC046F7B5C2690546537FFC -+:100A5000002B62D090F81A36002B45D0106928215F -+:100A60003F223FF065DEEB692421186910223FF038 -+:100A70005FDEEB6995F829261869262112013FF0FF -+:100A800057DEEB6932211869B5F8FC263FF050DEDD -+:100A90002E460027EB691869204BF95C3FF020DEF9 -+:100AA000EB6996F914250446A11D186992B23FF02E -+:100AB0003FDE96F914250223E96992FBF3F25242D4 -+:100AC000086992B204F10E0101373FF031DE0136C0 -+:100AD000082FDFD1EA6903230093106980220121E6 -+:100AE00013463FF0F1DD18E00146042091F914357A -+:100AF0000822073393FBF2F3DB00013081F8143551 -+:100B000001310C28F2D195F91425EB6907321869E7 -+:100B10004E21C2F3CF023FF00BDEFEBD29D2010011 -+:100B200010B5012102F0B0FC40B210BD10B500219B -+:100B30000446621801317F23652982F89136F8D185 -+:100B40002046FFF7EDFF2046FFF7C8FC10BDC0466A -+:100B50002DE9F04FB0F8DA30A5B003F47041B1F5EB -+:100B6000805F14BF022201220592D0F8A83004460B -+:100B70000693C3695A6C40F239539A4204D05233F7 -+:100B80009A4201D0002304E0B1F5805F14BF002336 -+:100B90000123DBB2002165220DF129000893F1F356 -+:100BA0004FF2B4F8DAA00AF44073B3F5407F02D1F3 -+:100BB0005FFA8AF810E0B3F5007F5FFA8AF104D19A -+:100BC000DD2904D801F1020806E0022902D84FF01D -+:100BD000000801E0A1F1020820460599FFF7A6FFF1 -+:100BE0002046FFF729FA4FF0000BC0B2FF255E4602 -+:100BF00007900395CDF810B070E0204651462A4684 -+:100C0000FFF7F6F9002867D005EB040999F8B262FE -+:100C100024AA571907F8676C94F8AC3043B1059AC9 -+:100C2000204641462B46FFF791FB301807F8670C2A -+:100C300041460DF18E020DF18F0320460095FFF71E -+:100C40005DF999F82C269DF88F309A4234BF1146F1 -+:100C5000194641F2D623E25C53B2994201DC0020EE -+:100C600002E0C2EB0103D8B224AB591911F8673C7A -+:100C7000984234BF02461A4601F8672C94F8E030D7 -+:100C8000642B06D803FB02F3642293FBF2F301F812 -+:100C9000673C11F8673C9DF88E20079E9A4238BF4A -+:100CA0001A462B1993F891368DF88F00934294BF12 -+:100CB000C6EB0306C6EB0206049AF3B25B4588BF97 -+:100CC0002A46049201F8673C039D5B4528BF9B467A -+:100CD000AB4238BF1D460395099E01360996099A15 -+:100CE000142AD5B289D104F5A26000215132F1F362 -+:100CF000A7F1039B049D84F8293684F82A36002343 -+:100D0000184684F818B684F8F83684F8195616E0B0 -+:100D100024AE731813F8672C94F81A36091981F861 -+:100D200075250BB1089B1BB194F818369B1A03E08C -+:100D300094F82936C3EB020381F8103501301428EA -+:100D4000C1B2E5D121460020069D91F91035B5F9D3 -+:100D5000E623D218431CD8B281F8102501310428AB -+:100D6000F2D1E36A0BB12046984725B0BDE8F08F79 -+:100D700070B505460E462C46FFF776F92946002049 -+:100D80003218137D03B91379013081F838360131F7 -+:100D90000828F5D10021721892F8443003B913796C -+:100DA000013184F8483601340829F4D1EB69186917 -+:100DB0003FF0F0DC2846FFF7CBFEEB6918693FF007 -+:100DC000D5DC70BD7F2970B5044601D9052028E027 -+:100DD000002213190132652A83F8B212F9D10023D7 -+:100DE000E26984F8F736137FD3B1D4F8F83013F002 -+:100DF000020F15D1D4F8B030D3F8203183F00103BD -+:100E000013F0010502D110693FF0C4DC2046FFF762 -+:100E10009FFE2DB9E36918693FF0A8DC284600E081 -+:100E2000002070BD70B5054600F52C70042202301C -+:100E30000C46F1F3A1F005F52C70211D08220630B7 -+:100E4000F1F39AF005F52E700822063004F10C013A -+:100E5000F1F392F005F538700822063004F1340100 -+:100E6000F1F38AF005F53A700822063004F13C01EE -+:100E7000F1F382F005F530700822063004F1140118 -+:100E8000F1F37AF005F532700822063004F11C0106 -+:100E9000F1F372F005F534700822063004F12401F4 -+:100EA000F1F36AF005F536700822063004F12C01E2 -+:100EB000F1F362F005F53C700822063004F14401BC -+:100EC000F1F35AF005F53E7004F14C0108220630AA -+:100ED000F1F352F005F540700822063004F1540198 -+:100EE000F1F34AF005F542700630082204F15C0186 -+:100EF000F1F342F094F8643085F81633D5F8B03049 -+:100F0000D3F8203113F0010309D11C462846FFF71E -+:100F10001FFE54B1EB6918693FF028DC05E0EB696E -+:100F2000012418693FF036DCF0E770BD2DE9F0418F -+:100F30000F460546FFF712FA07F47043B3F5805FDA -+:100F4000EB69FAB208BF42F480720446A021186926 -+:100F50003FF0EEDBAE6A14B104F5177201E005F55F -+:100F6000915241F2C413EA5016B128463946B047AF -+:100F70002CB341F2C413EA58537873B1EB6941F2D0 -+:100F8000B824295918693FF0E7DBEB69002218699A -+:100F9000295913463FF05EDB11E041F2F713EB5C99 -+:100FA0006BB1032B0BD0E969D2F890200B6A9B1A26 -+:100FB0008A6E934203D328460221FFF7DBF92846C5 -+:100FC0003946FFF7D7FABDE8F081C046E02910B5F1 -+:100FD0000B46044602DD6FF0120012E043F430636A -+:100FE0000E29D4BF4FF400514FF48051194389B2F8 -+:100FF000FFF79CFF0123204684F8D83008F08CFFCF -+:10100000002010BD70B50C460546FFF76DF844B9D9 -+:10101000284605F0D5FE28464FF4404106F0AAF9CF -+:1010200010E0214628460022FFF7D0FF044648B9C9 -+:10103000284621467022234605F046FB28465E21BD -+:1010400006F0EAFD204670BD2DE9F0410D4604464C -+:10105000FFF74AF845B92046294602F0B1FC2F4671 -+:1010600041F2C423E55213E0204629460122FFF74E -+:10107000ADFF074660B941F2C426A35B23B9204601 -+:101080000A21FEF7C3FCA0532046294602F098FC33 -+:101090003846BDE8F081C04670B50E460546D0F82A -+:1010A000B040FFF721F83EBB41F2C6240A21284692 -+:1010B0002A5BFEF7B7FC284640F24B413246FEF76A -+:1010C000B1FC2846314602F0DBFBEB692E531B6D69 -+:1010D00013F0020F56D041F2C823D5F8B020EB5AD6 -+:1010E0004FF47A70A2F89C3441F2CC23EB5AA2F868 -+:1010F0009E34F5F331F345E0EB691B6D13F0020FFD -+:101100001FD0D5F8B01041F2C822B1F89C344FF48A -+:101110007A709BB2AB50B1F89E3404329BB2AB50A4 -+:10112000B4F89C3423F400731B041B0CA4F89C3407 -+:10113000B4F89E349BB243F40073A4F89E34F5F3E4 -+:101140000BF3314628460122FFF740FF0646C8B997 -+:1011500041F2C6242B5B5BB90A212846FEF756FCF8 -+:1011600040F24B4128534FF6FF722846FEF75AFCD7 -+:101170002846012102F084FB28460A214FF494728C -+:10118000FEF766FC304670BD2DE9F0418AB005AE31 -+:10119000D0F8B07005468846142238493046F0F33E -+:1011A000EBF6142236496846F0F3E6F6EB690021C7 -+:1011B0006C461869142288450CBF234633463FF01D -+:1011C000C1DA4FF00003A7F86835B8F1000F4FF40B -+:1011D0008073A7F8C0370CBF40234123A7F80C3514 -+:1011E00041F60223A7F814354FF00003A7F808359D -+:1011F000A7F80A35A7F84C354FF01403A7F86A355D -+:1012000040F62603A7F868354FF00003A7F800352D -+:101210004FF0D003A7F80235B7F802350CBFFA2516 -+:101220001E25002402E00A20F5F396F2AC420ADA09 -+:10123000B7F80E35013413F0800FF4D103E00A2023 -+:10124000F5F38AF200E0002401340B2C09D0B7F842 -+:101250000E3513F4806FF2D003E00A20F5F37CF230 -+:1012600000E0002401340B2C04D0B7F8903613F4BE -+:10127000807FF2D10AB0BDE8F081C04662D20100A1 -+:10128000F8CB010070B590F8E2200446002A6CD13A -+:10129000012380F8E230D0F8B030A0F8DA10D3F8AB -+:1012A000203141F21003C250D0F8F82012F0020FA2 -+:1012B00006D190F8703E1BB942F02003C0F8F83018 -+:1012C000256A002D51D001212046FEF73FFCB4F8DD -+:1012D000DA30B4F8DE2003F44061914203D0E369D0 -+:1012E00018693FF0D3D9012141F2BD23E1542046D2 -+:1012F000FFF798F92046A847002384F8E1302046FC -+:10130000FFF7A2FBE369204693F88110FFF730FB5B -+:10131000E26992F88030012BB4F8DA300BD103F493 -+:101320007043B3F5005F01D1936F0BE0D36F012BD6 -+:1013300088BF002306E003F47043B3F5005F0CBFE1 -+:10134000136F536FD366E3690022D96E2046FEF710 -+:10135000D9FE002384F8E230E369922118693FF056 -+:10136000C9D941F212234000E05270BDC36910B5E3 -+:1013700018693FF0C9D910BDC36910B518693FF0AD -+:10138000CDD910BDF7B5089F04460D461E463BB1AA -+:10139000032A05D9684619460422F0F3EDF501E069 -+:1013A00000230093A82D009900F0FB8015DC5C2D34 -+:1013B00000F0AE8008DC3C2D00F0A0804A2D00F04B -+:1013C00093801B2D2AD020E05E2D30D0C0F2A88063 -+:1013D0005F2D3DD0872D1BD017E0C32D75D006DCC7 -+:1013E000AA2D49D07BDBC22D00F0DB800DE0D42D8F -+:1013F00000F0AB8003DCD32D00F09B8005E0A5F569 -+:101400009A73033B012B40F2D2806FF01605CFE0B8 -+:101410002046FEF783FE40B23060C8E0E3691D7FDE -+:10142000002D40F0B8802046FEF784FBC0E0012389 -+:101430003B70E3695B7F002B00F0B0802046FFF734 -+:101440009BFF2046BDF80010FEF7E0FA30600FE089 -+:1014500001233B70E3695B7F002B00F09F802046F7 -+:10146000FFF78AFF009A204691B2120CFEF7DAFAD3 -+:101470002046FFF77BFF9AE0E269537F002B00F0E4 -+:101480008D8010693FF086D900252046FFF774FF54 -+:101490003560D4F8BC30082B13D10DF1060220467C -+:1014A0000DF107018DF807508DF8065000F0A8FEE9 -+:1014B0009DF907209DF9063092B29BB243EA0223C0 -+:1014C00033602046FFF752FF60E0E3691B7F002B8B -+:1014D0006AD03388022B64D96FF0010568E0E369B4 -+:1014E0001B7F002B60D05CE0E3691B7F002B52D197 -+:1014F000236B002B5BD02046984718E0E3691B7FE5 -+:10150000002B48D120467268B368FFF7C5FD0EE096 -+:10151000E3691B7F002B3ED12046FFF773FD06E0F9 -+:10152000E3691B7F002B36D12046FFF78DFD054672 -+:101530003EE0E369DA6E3260D4F8E83F13F0010F61 -+:1015400035D042F08003336031E0042902D96FF0D6 -+:101550001C052DE0E269D36E8B4228D0137FD16643 -+:101560002BB310693FF016D9009B23B12046002110 -+:101570000122FEF7C7FDE36901222046D96EFEF77E -+:10158000C1FD002814BF00256FF00205E36918694A -+:101590003FF0ECD80CE06FF0040509E06FF00A05AD -+:1015A00006E06FF00C0503E06FF0030500E0002596 -+:1015B0002846FEBD2DE9F04389B09946109B0026D0 -+:1015C000032B07460C46DDF84480139D079604D98B -+:1015D00007A849460422F0F3CFF4079940F2862386 -+:1015E0000A1E18BF01229C4200F013812CD80C3B2C -+:1015F0009C427CD00FD8532C08D8522C80F04081CC -+:10160000502C00F03D81512C6AD02DE140F26A232C -+:101610009C4250D028E1B4F5207F00F0E48009D846 -+:1016200040F27B239C4200F0A48003339C4200F0F4 -+:10163000D58019E1B4F5217F00F0E48040F28523E4 -+:101640009C4200F0DB800FE140F2D6239C4200F088 -+:10165000178114D8413B9C423ED006D8043B9C42A3 -+:1016600034D002339C4234D0FEE0B4F5277F00F042 -+:10167000D78040F29D239C4200F0D680F4E040F2F7 -+:10168000DD239C4200F0EB8008D8033B9C4200F035 -+:10169000D180B4F5377F00F0D680E5E0B4F53D7F2A -+:1016A00000F0F380C0F0E080A4F53E73063B012B10 -+:1016B00000F2DA80E9E03846FFF75EFE3846414640 -+:1016C000FFF70CF83846FFF751FE50E041F2523375 -+:1016D00004E041F2543301E041F25633F95246E05E -+:1016E0000123009338464346FEF728FDCFE0FA6910 -+:1016F000137F13B96FF00300C9E0D7F8B030D3F807 -+:10170000203183F0010313F0010902D110693FF089 -+:1017100041D83846FEF734FE3846FFF72DFE41F239 -+:10172000D61341F2D910F95C385C0133FA5C01330D -+:1017300017F803E0009041F2DA103D5C01303C5CA8 -+:101740001630385C7346039038460195029404962F -+:10175000FEF76AFEC8F800003846FFF707FEB9F149 -+:10176000000F40F08D80FB6918693EF0FFDF3046C6 -+:101770008DE0C1F3036CBCF1010F00F28380C1F373 -+:10178000015EBEF1010F7DD8C1F38155032D79D0E3 -+:10179000C1F30344012C75D8C1F30722A2F10A0357 -+:1017A000DBB2052B6ED8C8B2012801D9032869D154 -+:1017B0000E2A28BF0E2241F2D613FA540133F854F0 -+:1017C0000133FC54013307F803E00133FD540133C6 -+:1017D00007F803C00A0F1633FA54C8E708A9012313 -+:1017E00041F8043D07E0B7F8DA103846FEF734FB5D -+:1017F00008A941F8040D40462A462DE041F20B03AA -+:10180000F954B4E741F20B03FB5C08A941F8043D2D -+:1018100017E0D7F8F830C3F30013C8F80030A6E794 -+:1018200038464246334602E0384642460123FEF738 -+:101830006BFE9CE70121384601F038FF08A941F80A -+:10184000046D404607E007AC38463146224601F0B9 -+:1018500091FF404621460422F0F38EF387E7384695 -+:10186000324601F087FF82E7019102923846214615 -+:101870004A4643460095FEF717FF10F1170F04D0B4 -+:10188000002004E06FF01C0001E06FF0160009B0CA -+:10189000BDE8F0832DE9F04391460A6801230B73FC -+:1018A00042F008030B60B0F9FA3685B0B3F1FF3FA0 -+:1018B00004BF42F009030B6090F81A3605460C4647 -+:1018C0001BB10B6843F002030B602F4626464FF016 -+:1018D000000897F8B2322846B37749460DF10E0357 -+:1018E0000DF10F02CDF80080FEF708FB9DF80E30D9 -+:1018F00008F1010886F8B03197F87535013786F898 -+:1019000079320136B8F1140FE3D195F81A3633B3B2 -+:10191000EB691B7F1BB32846FFF72EFD95F81836A1 -+:101920002846A37595F81836E37595F81936A37609 -+:1019300095F81936E37600F059FC236810B143F0AE -+:10194000030301E023F003032846236004F10D01A3 -+:1019500004F1150200F054FC2846FFF707FD05B01E -+:10196000BDE8F08310B5054B1B78012B03D1013B7B -+:1019700018461B7001E014F095FA10BD38F501000F -+:1019800010B5054B1B78012B03D1013B18461B708A -+:1019900001E014F0ADFA10BD38F501002DE9F04179 -+:1019A00005460E4617461C46FFF7EAFF30B12346B0 -+:1019B000284631463A4614F0D5FA04462046BDE89A -+:1019C000F081C04610B50023FFF7E8FF10BDC04608 -+:1019D00010B51446FFF7D4FF20B100210A46F0F3FA -+:1019E000B7F60446204610BD10B50022FFF7F0FF01 -+:1019F00010BDC0461FB5079B0C890093089B11467C -+:101A00000193099B224602930A9B03930069069B5C -+:101A10002BF0CCDB04B010BD00B5B0FBF1FE01FB38 -+:101A20001E0001F0010C0CEB51010BE0884228BFB5 -+:101A3000C1EB00034FEA4E0E26BF0CEB43000EF144 -+:101A4000010E4000531EDAB2FF2AEFD1884228BFB0 -+:101A50000EF1010E704600BD00FB01F19202800103 -+:101A600003FB002001F5004101EB4000490090FB21 -+:101A7000F1F07047D0F8A8304FF001025A86704755 -+:101A80002DE9F04798469DF820308A4691469DF80A -+:101A90002470B3B100246FF000462546204651461D -+:101AA0004A464346FFF7D8FFB04204DA6B1CDDB26A -+:101AB000BD421AD006460134802CEFD16FF00040B1 -+:101AC00013E07F244FF0FF361D46204651464A461C -+:101AD0004346FFF7C1FFB04204DD6B1CDDB2BD42DF -+:101AE00003D00646013CF0D22046BDE8F087C04650 -+:101AF00010B5B0F8DA300446DAB203F47043B3F547 -+:101B0000005FD0F8A81003D1531893F8E72486E0BB -+:101B1000702A5ED01CD8382A49D00CD82C2A3DD047 -+:101B200004D8242A34D0282A35D02FE0302A38D0BF -+:101B3000342A39D02AE0642A42D004D83C2A39D049 -+:101B4000402A3AD022E0682A3DD06C2A3ED01DE0DF -+:101B5000882A50D00CD87C2A44D004D8742A3BD090 -+:101B6000782A3CD012E0802A3FD0842A40D00DE071 -+:101B7000992A49D004D88C2A40D0952A41D005E032 -+:101B8000A12A47D0A52A48D09D2A40D0002246E06D -+:101B900091F8F62443E091F8F72440E091F8F82416 -+:101BA0003DE091F8F9243AE091F8FA2437E091F811 -+:101BB000FB2434E091F8FC2431E091F8FD242EE080 -+:101BC00091F8FE242BE091F8FF2428E091F80025FD -+:101BD00025E091F8012522E091F802251FE091F817 -+:101BE00003251CE091F8042519E091F8052516E07D -+:101BF00091F8062513E091F8072510E091F80825E3 -+:101C00000DE091F809250AE091F80A2507E091F81E -+:101C10000B2504E091F80C2501E091F80D25D1F891 -+:101C2000E40494F82A36C01A801840B210BDC046A9 -+:101C30000846704749B24B1C5B104910C3F10803BA -+:101C4000083141EA031188B27047C046B0F8DA3073 -+:101C500003F47043B3F5005FD0F8A82005D192F8E3 -+:101C60003C05FF2801D0C0B200E000207047C0460C -+:101C700070B50546D0F8A840FFF7E8FF10B994F812 -+:101C8000460540B1B5F8DA3003F47043B3F5005FB0 -+:101C900014BF0020012070BD10B50C468EB0D0F8E6 -+:101CA000A8109646002000220DF10603C254013010 -+:101CB0003228F8D1BEF1FF3F91F8E93306D114B1D3 -+:101CC000B1F93EE503E0B1F940E514E09CB1A02B89 -+:101CD00009D000238DF806308DF807308DF80830D4 -+:101CE0008DF8093004E000238DF806308DF80830B7 -+:101CF0008DF80A3033E0A02B17D001238DF81A306D -+:101D00008DF81B306FF0010300228DF81E308DF826 -+:101D10001F3001338DF81C208DF81D208DF82020F8 -+:101D20008DF821308DF8242019E002238DF81A3027 -+:101D30006FF003038DF81E30023300228DF81F3040 -+:101D40008DF820308DF8213006338DF81B208DF86A -+:101D50001C208DF81D208DF824208DF832300EAA1D -+:101D600002EB0E0313F9320C0EB010BD30B5C4698E -+:101D7000D0F8F03F226AD0F8A8509A4202D3C3EBC1 -+:101D8000020101E0DB43991895F8BC2290F8DA30A3 -+:101D90009A4201D0012004E0A36E994234BF002092 -+:101DA000012030BD7047C046D0F8A83093F8060433 -+:101DB000002808BF1020704700B5D0F8A8008E4654 -+:101DC000D0F8D4240EF0FF0343EA0223110EC0F82A -+:101DD000D434D0F8D8347F29C8BFA1F580717344BA -+:101DE0005B1AC0F8D8349B10C0F8DC3400BDC04684 -+:101DF000844610221B4810B5964600244EF3460335 -+:101E00005FFA83FE10EA0C0F4FFA8EF104D088407F -+:101E10000EEB0203DAB203E0C840CEEB0203DAB203 -+:101E20000134042CEAD110EA0C0FD3B201D1013BEA -+:101E3000DAB251B2032301FB03F30329DAB20EDD58 -+:101E4000CB1E2CFA03F00D2801D9D31C06E00A287A -+:101E500001D9931C02E0082801D9531CDAB250B210 -+:101E600010BDC0460000FFFFD0F8A820002382F874 -+:101E7000903382F8913382F8923382F8933382F868 -+:101E8000943370477047C04670B540F22341D0F894 -+:101E9000A8500446FDF7BAFDC0B2A5F864034FF49C -+:101EA000AA612046FDF7B2FD8005800DA5F8680304 -+:101EB00040F234412046FDF7A9FDC0B27F28C8BFDB -+:101EC000A0F58073A5F8660340F23241C8BFA5F8BB -+:101ED00066332046FDF79AFDC0B27F28C4BFA0F547 -+:101EE000807398B285F8BC0370BDC0462DE9F047F9 -+:101EF000884640F2B76104469146FDF787FD40F2FF -+:101F0000B66105462046FDF781FD40F2B561064603 -+:101F10002046FDF77BFD40F2B46107462046FDF701 -+:101F200075FD4FF0000C6246644650FA04F313F05E -+:101F3000010101D0012103E00CF101035FFA83FCF0 -+:101F4000531CDAB2102A12D001340029EDD00EE071 -+:101F5000A2F1100357FA03F313F0010F01D001218E -+:101F600003E00CF101035FFA83FC531CDAB21F2A71 -+:101F700011D80029ECD00EE0A2F1200356FA03F3A9 -+:101F800013F0010F01D0012103E00CF101035FFA0E -+:101F900083FC531CDAB22F2A11D80029ECD00EE0B2 -+:101FA000A2F1300355FA03F313F0010F01D0012120 -+:101FB00003E00CF101035FFA83FC531CDAB23F2A01 -+:101FC00001D80029ECD04FF03F0E00220F2455FA23 -+:101FD00004F313F0010101D0012103E00EF1FF33FE -+:101FE0005FFA83FE531CDAB2102A12D0013C00299A -+:101FF000EDD00EE0C2F11F0356FA03F313F0010F08 -+:1020000001D0012103E00EF1FF335FFA83FE531C80 -+:10201000DAB21F2A11D80029ECD00EE0C2F12F034A -+:1020200057FA03F313F0010F01D0012103E00EF181 -+:10203000FF335FFA83FE531CDAB22F2A11D800292E -+:10204000ECD00EE0C2F13F0350FA03F313F0010F9E -+:1020500001D0012103E00EF1FF335FFA83FE531C30 -+:10206000DAB23F2A01D80029ECD088F800E089F8DC -+:1020700000C0BDE8F087C04670B50D4640F239415A -+:102080000646FDF7C3FCC0F3C210E88040F2B5413C -+:102090003046FDF7BBFC40F2FB4104463046FDF7FD -+:1020A000B5FC04F0FF03C0B2C4F307242B806C809E -+:1020B000A88070BD2DE9F047B0F8DA30074603F488 -+:1020C0007043B3F5805FD0F8A82009D1B2F892052B -+:1020D00003B2B3F1FF3F0CBF4FF4C87080B24CE0C5 -+:1020E000B2F8904523B2B3F1FF3F01D0A0B244E073 -+:1020F00040F2A541FDF78AFC40F2A54181463846F1 -+:10210000FDF784FC40F20D4106463846FDF77EFCA3 -+:1021100040F20D4104463846FDF778FC40F2A241FA -+:1021200005463846FDF772FC40F2A241804638462B -+:10213000FDF76CFCC6F30236012313FA06F6C0F372 -+:102140000220C5F3022513FA05F58340E4B25FFAD5 -+:1021500089F94C44B6B2A419ADB29BB25FFA88F8C3 -+:102160006419434404EB430464005034A4B2B4F54E -+:10217000C86F2CBF20464FF4C860BDE8F087C0464A -+:1021800010B540F2FB41FDF741FCC0F3062010BD45 -+:1021900070B540F2A4410446D0F8A850FDF736FCD3 -+:1021A000C0F38130032814D141F21403E35C83B1FE -+:1021B000204640F27341FDF729FC95F96635C005CC -+:1021C000C00D013303FB00F3022293FBF2F3D8B2FC -+:1021D00001E095F8C10240B270BDC04610B540F2B2 -+:1021E000A441FDF713FC00F4404010BD10B5FFF70B -+:1021F000F5FFB0F5404F14BF0020012010BDC046D0 -+:1022000070B5002313700B7041F21403C35C0446D5 -+:102210000D4616461BB340F2AB41FDF7F7FB10F439 -+:10222000004F03D0204640F2AB410AE0204640F286 -+:102230003C61FDF7EBFB10F4004F07D0204640F265 -+:102240003C61FDF7E3FBC0F3470028702046FFF731 -+:10225000CDFF08B194F810052B781B18337070BDB2 -+:102260002DE9F04140F2FF340E46054690463346D4 -+:10227000224640F24561FDF7FBFB284622464346D5 -+:1022800040F24661FDF7F4FB28462246334640F211 -+:102290004761FDF7EDFB2846224643464FF4C961EE -+:1022A000FDF7E6FB28462246334640F24961FDF73A -+:1022B000DFFB284640F24A6122464346FDF7D8FB41 -+:1022C000BDE8F08170B5002914BF4FF4807300237E -+:1022D00004460D1E18BF01254FF480724FF496611D -+:1022E000FDF7C6FB0122204640F24C412B46FDF78C -+:1022F000BFFB2B0320464FF496614FF4805203F44A -+:102300007043FDF7B5FB6B0320464FF496614FF425 -+:10231000005203F46043FDF7ABFB6B0120229BB23C -+:1023200020464FF49661FDF7A3FB6B0203F47E4356 -+:10233000204640F2AE414FF40072FDF799FBB4F82D -+:10234000DA3003F47043B3F5005F11D1AB022046DD -+:102350004FF496614FF4806203F47C43FDF788FBF1 -+:10236000EB009BB2204640F2E5410822FDF780FBDE -+:1023700070BDC04670B50C02A4B20546234640F2BB -+:10238000FB414FF4FE42FDF773FB284640F2FD414E -+:102390004FF4FE422346FDF76BFB70BD70B500297C -+:1023A00014BF802300230C1E18BF012480224FF489 -+:1023B00096610546FDF75CFBA303A40128464FF494 -+:1023C00096614FF4804203F44043A4B2FDF750FB02 -+:1023D000284640F23B4140222346FDF749FB70BDB1 -+:1023E00070B540F239440D4621460646FDF70EFB16 -+:1023F00040F67F4300EA030343EAC5133046214613 -+:1024000040F6FF729BB2FDF733FB70BD2DE97043C0 -+:102410000C460646FFF7B4FE628823884FF6FF7924 -+:1024200043EA022305464A46304640F2B5419BB294 -+:10243000FDF71EFB2D02A388ADB247F6FF783046AC -+:10244000424645EA030340F2FB41FDF711FB628877 -+:102450002388304643EA022340F2FC414A469BB2BD -+:10246000FDF706FBA3883046424645EA030340F2E7 -+:10247000FD41FDF7FDFA3046E188FFF7B1FF304638 -+:102480000121FFF78BFFBDE87083C04610B50249FC -+:102490000C22FDF701FB10BDCADA01002DE9F0475F -+:1024A0009846BDF82CA0BDF824308946BDF8201010 -+:1024B0000AF00304164603F00F03BDF8282044EA8F -+:1024C000032301F00F0102F0030243EA013343EA60 -+:1024D000821343EA021343EA840340F2B6414FF603 -+:1024E000FF720746BDF83050FDF7C2FA0F2208EA26 -+:1024F0000203384640F2B741FDF7BAFA4FEACA2361 -+:102500009CB22346384640F2B1414FF460522D034D -+:10251000FDF7AEFAADB2062238462049FDF7BCFA07 -+:102520007602384640F2AE414FF470422B46FDF73A -+:102530009FFA384640F2B1414FF4007206F47E43F0 -+:10254000FDF796FAD9F1010338BF0023012238467E -+:1025500040F24D41FDF78CFAB7F8DA3003F47043DE -+:10256000B3F5005F10D1384640F2B1414FF4C0528C -+:102570002346FDF77DFA4FEACA039BB2384640F284 -+:10258000E6411822FDF774FA384640F2AE414FF4A6 -+:1025900070422B46FDF76CFABDE8F0878ED501003E -+:1025A00010B5044686B021B90D490E22FDF774FA24 -+:1025B00014E00C490922FDF76FFA002103220623DB -+:1025C000009302920423039220460A460491019349 -+:1025D000FFF764FF20460121FFF774FE06B010BD2F -+:1025E000D6D40100F2D4010010B5D0F8A830D3F849 -+:1025F000741529B1C3694FF420729868F4F378F325 -+:1026000010BDC0462DE9F041D0F8A8300646D3F8F9 -+:102610007C55D3F8787500240DE0142302FB03F3F6 -+:10262000EA1811695268F06902FB01F28068E95802 -+:10263000D208F4F35DF3E2B20134BA42EDD3BDE85F -+:10264000F081C04670B5D0F8A8500446D5F87C3566 -+:102650006BB10121FFF7D6FFE369D5F87845142265 -+:102660009868D5F87C1504FB02F2F4F341F370BDD1 -+:1026700000F59753196810B5044629B1C36942F6AD -+:1026800008529868F4F334F32046FFF7ADFF204674 -+:10269000FFF7D8FFE369D4F8A81098684FF4B9623F -+:1026A000F4F326F310BDC04610B54FF48052044633 -+:1026B000002340F2C961FDF7DBF9D4F8A820B2F895 -+:1026C000C234EBB192F8E933A02B04D1204640F29A -+:1026D0008961232203E0204640F289613022FDF720 -+:1026E000A1F9D4F8A830B3F8C234022B0ED14FF4BC -+:1026F0008052204640F2C9611346FDF7B9F905E062 -+:10270000204640F289612322FDF78CF904222046FD -+:102710002749FDF7C1F90022204640F27961FDF713 -+:1027200081F9082220462349FDF7B6F9D4F8A830EC -+:102730002046B3F8C2244FF4D961FDF773F906229D -+:1027400020461D49FDF7A8F9D4F8A8304FF480724F -+:10275000B3F8C23420461A41013A4FF4D06192B224 -+:10276000FDF760F9D4F8A8304FF4A072B3F8C23482 -+:1027700020461A41013A92B240F28161FDF752F9C6 -+:10278000D4F8A830B3F8C224012A04D0022A14BF16 -+:102790003422082200E01822204640F27F61FDF733 -+:1027A00041F9204605490E22FDF776F910BDC046D5 -+:1027B00024D80100EEDA01002CD80100FEDA010075 -+:1027C0002DE9F04740F23C4631460446FDF71EF93C -+:1027D00040F23B48824641462046FDF717F94AF051 -+:1027E000010281463146204692B2FDF71BF949F0BD -+:1027F0000102204641464FF6FE7592B2FDF712F9EE -+:10280000204631460AEA0502FDF70CF9204641460A -+:1028100009EA0502FDF706F9204631465246FDF762 -+:1028200001F9204641464A46FDF7FCF8BDE8F0872D -+:10283000802270B513460C4640F2D1610546FDF783 -+:1028400017F90CB1012C05D128464FF4DA610F229B -+:10285000FDF7E8F82846FFF7B3FF70BD2DE9704398 -+:102860000E46B0F8DA10054601F47041B1F5005F8C -+:1028700014BFA521892199469046FDF73DF8B5F88A -+:10288000DA10044601F47041B1F5005F14BFA521D0 -+:1028900089212846FDF730F804F00F04C0F3031037 -+:1028A000241A3470B5F8DA10284601F47041B1F5F5 -+:1028B000005F14BFA6218A21FDF71EF8B5F8DA10D3 -+:1028C000044601F47041B1F5005F14BFA6218A21CE -+:1028D0002846FDF711F804F00F04C0F30310241A82 -+:1028E00088F80040B5F8DA10284601F47041B1F5D7 -+:1028F000005F14BFA7218B21FCF7FEFFB5F8DA10AB -+:10290000044601F47041B1F5005F14BFA7218B218B -+:102910002846FCF7F1FF04F00F04C0F30310241A5B -+:1029200089F80040B5F8DA10284601F47041B1F595 -+:10293000005F14BFA8218C21FCF7DEFFB5F8DA1088 -+:10294000044601F470412846B1F5005F14BFA82188 -+:102950008C21FCF7D1FF04F00F04C0F30310069B99 -+:10296000241A1C70BDE87083B0F8DA1010B501F4B9 -+:1029700070410446B1F5005F14BFA521892188226A -+:10298000FCF7D2FFB4F8DA10204601F47041B1F53B -+:10299000005F14BFA6218A218822FCF7C5FFB4F886 -+:1029A000DA10204601F47041B1F5005F14BFA72191 -+:1029B0008B218822FCF7B8FFB4F8DA10204601F426 -+:1029C0007041B1F5005F14BFA8218C218822FCF76B -+:1029D000ABFF10BD10B5D0F8A830044693F8E9332A -+:1029E000A02B03D110490422FDF756F820460022FF -+:1029F0004FF48E71FCF798FF204618220B49FDF723 -+:102A00004BF841F2DE23E35A2046FF2240F23461C4 -+:102A1000002B08BF0C23FDF72BF8204604490922A0 -+:102A2000FDF73AF810BDC046C0DD0100C8DD010069 -+:102A300026D5010070B504220D4607490646FDF76C -+:102A40002BF80024054B625BE15A30460234FCF758 -+:102A50006BFF302CF6D170BDFAD701005ED40100B7 -+:102A60002DE97043054698461646B0F8DA40FFF760 -+:102A7000E1F804F47044B4F5005F14BFA524892480 -+:102A80000246214628469DF81890FCF74DFF314636 -+:102A90002846FFF7CFF8B5F8DA40024604F4704450 -+:102AA000B4F5005F14BFA6248A2428462146FCF70B -+:102AB0003BFF41462846FFF7BDF8B5F8DA4002462D -+:102AC00004F47044B4F5005F14BFA7248B24284697 -+:102AD0002146FCF729FF49462846FFF7ABF8B5F831 -+:102AE000DA40024604F47044B4F5005F14BFA82431 -+:102AF0008C2428462146FCF717FFBDE87083C046AA -+:102B000070B505460E460024074BA25BE15A2846E5 -+:102B10000234FCF709FF182CF6D128460349224657 -+:102B2000FCF7BAFF70BDC046DCD901008ED80100A9 -+:102B300070B506220E4644490446FCF7ADFF002559 -+:102B4000424B2046E95AFCF7D7FEA8530235182D10 -+:102B5000F6D1072101222046FCF7E6FE1022FF21D4 -+:102B600013462046FCF726FF04221346204640F277 -+:102B70001F11FCF71FFF0C2220463549FCF78CFF84 -+:102B800001223A2113462046FCF714FF04223A2181 -+:102B900013462046FCF70EFF0822134620464FF44A -+:102BA0008D71FCF707FF0822052113462046FCF72C -+:102BB00001FF0122134620464FF48D71FCF7FAFE07 -+:102BC000122220462349FCF767FF20228221134668 -+:102BD0002046FCF7EFFEB4F8DA3003F47043B3F5A7 -+:102BE000005F02D000252E4608E0D4F8A8309A7A7B -+:102BF000D97A42F400721D7B42EA01160122204676 -+:102C000013464FF49B61FCF733FF2046B3004FF4AB -+:102C10009B6140F6FC72FCF72BFF02222046134614 -+:102C20004FF49B61FCF724FF2B0320464FF49B617C -+:102C30004FF4E04203F47043FCF71AFF20460649C4 -+:102C40000622FCF729FF70BDBEDC0100DCD90100C3 -+:102C5000B2DA01003ED6010062D601002DE9F74F3D -+:102C6000D0F8A830814693F80B809C7A1A7E1F7B9F -+:102C70004FEA081844F4007493F817B09E7D44EAB4 -+:102C80000804009293F814A0DD7C44EA07345B7DCD -+:102C900047F2FF38A4B2092223490193FCF7FCFE56 -+:102CA00048464246234640F2DB41FCF7E1FE4846F7 -+:102CB0004246234640F2DC41FCF7DAFE48464246F3 -+:102CC000234640F20A41FCF7D3FE4FEA0A1A019B61 -+:102CD00045F4007545EA0A0545EA0335484642468B -+:102CE000ABB240F20B41FCF7C3FE4FEA0B1B009A5C -+:102CF00046F4007646EA0B0646EA02364846424665 -+:102D0000B3B240F20C41FCF7B3FE202248468221C8 -+:102D10001346FCF74FFE012248467C211346FCF780 -+:102D200049FEBDE8FE8FC046E8D70100012970B515 -+:102D300005460C4616D106222949FCF7ADFE284669 -+:102D40003A2122462346FCF735FE08222846134640 -+:102D50004FF48D71FCF72EFE28467F210022FCF7F0 -+:102D6000E3FD33E079B91F490622FCF795FE2846BA -+:102D70003A2101222346FCF71DFE082228464FF483 -+:102D80008D71134620E0022920D1B0F8DA3003F427 -+:102D90007043B3F5005F02D17D21032201E07D2164 -+:102DA0002246FCF7C1FD284628210F220123FCF70B -+:102DB00001FE8022134628464FF48971FCF7FAFD84 -+:102DC0002846052107220223FCF7F4FD284640F29D -+:102DD00037614FF440420023FCF74AFE70BDC04605 -+:102DE000FAD3010006D401002DE9F047C369D0F8F9 -+:102DF000A8501B6D0C4613F4805F40F2234114BFB2 -+:102E00004FF006094FF00909064695F844A3FCF770 -+:102E1000FDFD40F2344107463046FCF7F7FD204601 -+:102E2000FEF7E6FF95F84433C1B2B5F8642395F890 -+:102E300048030BB9012092E007F0FF07C0EB010344 -+:102E4000C2EB07029B1A5FFA83F84FFA88F4002C52 -+:102E50001DDAF36930461B6D03F48053002B0CBF61 -+:102E60000B21042114BF0322082263429A42A8BF07 -+:102E70001A46B5F8683301FB02324FF4AA6192B2E8 -+:102E8000FCF7D0FD14F1030F06DAFB1C05E0032C60 -+:102E900002DDFB1E9BB200E0BBB2B5F8640319B2C1 -+:102EA00002B2D31C994201DDC31C03E09142ACBFC6 -+:102EB0000B4613469CB2BAF1000F13D023B2BB42AB -+:102EC00010D02346304640F22341FF22FCF7D0FDCC -+:102ED000304624490422FCF7DFFD1420F3F33CF4D0 -+:102EE000002700E00127B5F866434FFA88F220B2C8 -+:102EF000C9EB000352429A42B8BFC9EB040391B236 -+:102F0000B8BF99B20AB200F109039A42C4BF04F1F2 -+:102F1000090399B2B6F8DA3003F47043B3F5005FF1 -+:102F20000CBF95F94B3395F94C335B189BB2BAF152 -+:102F3000000F05D0304640F23441FF22FCF798FDE7 -+:102F4000304640F22341FCF761FD95F8BC33C0B236 -+:102F500085F8BD0385F8BE0385F8BF333846BDE864 -+:102F6000F087C046ACD7010070B5D0F8A850044631 -+:102F7000FF22B5F8663340F23441FCF779FDB5F82D -+:102F800064332046FF2240F22341FCF771FD2046C6 -+:102F9000B5F868234FF4AA61FCF744FD20460449C4 -+:102FA0000422FCF779FD1420F3F3D6F370BDC0467C -+:102FB0004EDD0100082270B5134605465721FCF787 -+:102FC000F9FC56212846FCF797FC00F0F80456213E -+:102FD00022462846FCF7A8FC0120F3F3BDF3562156 -+:102FE00044F003022846FCF79FFC0120F3F3B4F3FE -+:102FF000562144F007022846FCF796FC4FF49670E1 -+:10300000F3F3AAF32846572108220023FCF7D2FC49 -+:1030100070BDC0462DE9F04140F24A463146804637 -+:10302000FCF7F4FC40F04404A4B24FF6BF754046F0 -+:103030003146224604EA0505FCF7F4FC31462A46EF -+:103040004046FCF7EFFC25F004050420F3F384F37D -+:10305000404631462A46FCF7E5FCBDE8F081C04613 -+:103060002DE9F04706460C461546384906221F460C -+:10307000DDF82090BDF82480FCF70EFD304640F2CC -+:1030800082414FF6FF722346FCF7F2FC304640F2D5 -+:103090008141FF222B46FCF7EBFC3FB9304640F262 -+:1030A00081414FF480723B46FCF7E2FC30462849F0 -+:1030B0000322FCF7F1FC0A2308FB03F5002407E0D8 -+:1030C000AC4201DD002439E06420F3F345F3013420 -+:1030D000304640F28141FCF799FC10F4007FEFD1BB -+:1030E00040F283413046FCF791FC40F284410446B3 -+:1030F0003046FCF78BFC40EA0440C9F8000040F27F -+:1031000085413046FCF782FC40F286410446304659 -+:10311000FCF77CFC40EA0440C9F8040040F2874117 -+:103120003046FCF773FC4FF4916104463046FCF7DF -+:103130006DFC40EA0440C9F8080001243046054906 -+:103140000622FCF7A9FC2046BDE8F087ECDB010075 -+:10315000F8DB0100FEDB010070B50546002407E046 -+:103160006420F3F3F9F2013441F289339C4207D031 -+:10317000284640F25141FCF749FC10F4404FEFD192 -+:10318000284640F25141FCF741FC10F4404F14BF77 -+:103190000020012070BDC04610B540F24C414FF6F2 -+:1031A000FC72FCF747FC10BDC36970B504460D46C0 -+:1031B00018698E2116463DF09DDAE36941194900F0 -+:1031C000186932463DF0B4DA70BDC046C36970B5C7 -+:1031D00004460D4618698E213DF08CDAE3694119E9 -+:1031E000490018693DF086DA70BDC0462DE9F0410E -+:1031F0000C46272180461646FFF7E8FF10F0010332 -+:1032000002D101271D4605E04FF6F07500EA0505DD -+:103210004FF6F07728214046FFF7D8FF3840A84204 -+:1032200001D1012009E0013C631C002B02DD1420C8 -+:10323000F3F392F2002CEDDC002006B13460BDE81F -+:10324000F081C0462DE9F0410646D0F8A850FEF7BF -+:10325000C5FFB0F5404F46D1F369E02118693DF054 -+:1032600049DAEC8D8046C4EB000440F2A5413046BB -+:10327000FCF7CCFB0123C0F30227BB40A4B29C4265 -+:1032800031DD95F8C134A5F82E80BB4208D901374D -+:10329000304640F2A5414FF4E0623B02FCF7E8FB08 -+:1032A0003046FEF775FF40B280B22886B6F8DA30B5 -+:1032B0006F8603F47043B3F5005F0CBF85F85404C8 -+:1032C00085F85504D6F8A8202B8E92F966255B0068 -+:1032D000013293FBF2F3304640F2A44140F2FF1278 -+:1032E0009BB2FCF7C5FBBDE8F081C0462DE9F04F6D -+:1032F000044685B00D46D0F8A860FFF7A3FFD4F8C8 -+:10330000B030D3F8203183F0010313F001030393AD -+:1033100003D1E36918693DF03DDA07212046FCF747 -+:10332000EBFAFF2101902046FCF7E6FA40F21F116C -+:1033300002902046FCF7E0FA40F23B4183462046EB -+:10334000FCF764FB40F23C4182462046FCF75EFB02 -+:1033500040F2D74181462046FCF758FB4FF49B6171 -+:1033600080462046FCF752FB0F224649074620467E -+:10337000FCF792FB0122072113462046FCF71AFBBB -+:103380001022FF2113462046FCF714FB04221346AB -+:1033900040F21F112046FCF70DFB0A20F3F3DCF18D -+:1033A000202220464FF49A611346FCF761FB0A2065 -+:1033B000F3F3D2F1012D21D140F276412046FCF702 -+:1033C00025FB40F27741C5052046FCF71FFBC005F1 -+:1033D000C00DED0DFF288ABFA0F5007302469AB21A -+:1033E000FF2D88BFA5F50073A6F86E058CBF98B2B7 -+:1033F0002846C0EB0203A6F86C550AE0204640F2CE -+:103400007541FCF703FBC005C00DFF2803D9A0F5EB -+:1034100000739DB200E00546019B2046DAB2072109 -+:10342000FCF782FA029B2046DAB2FF21FCF77CFA15 -+:10343000204640F21F115FFA8BF2FCF775FA204626 -+:1034400040F23B415246FCF7EDFA204640F23C4147 -+:103450004A46FCF7E7FA204640F2D7414246FCF7DD -+:10346000E1FA20464FF49B613A46FCF7DBFA039BF6 -+:103470001BB9E36918693DF079D928B205B0BDE8F8 -+:10348000F08FC04640D4010070B5D0F8A8300129B3 -+:10349000D3F8DC63D3F8D853D3F8E04304D1013137 -+:1034A000FFF724FF02B20AE040F27541FCF7AEFAE2 -+:1034B000C005C00DFF288CBFA0F500720246631F37 -+:1034C00001209840801905FB1200231F184140B2CB -+:1034D00070BDC04610B50129D0F8A83003D1FFF760 -+:1034E00005FF00B212E0B3F86C25B3F86E35FF2B80 -+:1034F00086BFA3F5007399B21946FF2A86BFA2F5CD -+:1035000000739BB21346C3EB010318B210BDC04653 -+:1035100070B5D0F8A830D3F8D443D3F8D053D3F84B -+:10352000CC63FFF7D7FF621E0123934000B25B1903 -+:1035300006FB1030204140B270BDC0462DE9F0417D -+:10354000B0F8DA20074602F47043B3F5005FD0F814 -+:10355000A85004D1B5F85463B5F8844513E0D3B24C -+:10356000942B03D9B5F88645022308E0632B03D9D1 -+:10357000B5F88845012302E0B5F88A45002305EB3C -+:103580004303B3F85663FF2E1ED001213846FFF7E0 -+:10359000BFFF40B2193804FB00F000B20028CCBFD6 -+:1035A00000F5FA73A0F5FA734FF47A7293FBF2F315 -+:1035B00098B28419A4B2384640F23441FF2223461F -+:1035C000FCF756FAA5F86643BDE8F08170B50546EC -+:1035D000D0F8A8600C4689B340F2DA6142F20802E2 -+:1035E000FCF736FA284640F2A6510522FCF71AFAF3 -+:1035F000284640F2A251C322FCF714FA284640F2B2 -+:10360000A5510722FCF70EFA284640F283514FF4E9 -+:103610004872FCF707FA284640F284510022FCF772 -+:1036200001FA284640F285514FF40072FCF7FAF98E -+:10363000284640F286510022FCF7F4F9284627215B -+:10364000FFF7C4FD1CB140F001039CB203E04FF64C -+:10365000FE7400EA040496F894332846F31893F8AD -+:103660009523052302FB03F22621042A98BF1A465C -+:10367000FFF79AFD04F110022846272192B2FFF7C6 -+:1036800093FD70BD70B5D0F8A850044695F842334C -+:103690005BB10021FFF79AFF204619210022FFF7B6 -+:1036A000A5FD10B9012385F8453370BD70B5D0F87C -+:1036B000A840054694F8423393B990F8E93013F0E6 -+:1036C000010F1CBF23F0010380F8E93090F8E930C6 -+:1036D00013F0020F2DD023F0020380F8E93028E028 -+:1036E00094F847330BB1012303E0D1F1010338BF54 -+:1036F000002384F84733E1B100230126C4F86C337A -+:1037000084F8453384F846632846FFF7BBFF94F8F6 -+:103710004333003B18BF012384F8443313B12846D8 -+:10372000FFF722FC2846FEF79FFB28463146FFF7AD -+:103730004DFF70BD70B5D0F8A83000260C4683F858 -+:10374000466331460546FFF741FF14B12846FFF7AF -+:103750000BFC03222846134640F67A01FCF788F951 -+:10376000284640F2DA6142F208023346FCF780F95B -+:1037700070BDC04670B50546D0F8A84016467AB16F -+:1037800094F8433394F842438C2144EA4304C369D8 -+:10379000146018693CF0AEDF44EA004434600FE086 -+:1037A000CB080DD101F0010384F84233C1F340038B -+:1037B00084F8433394F8423313B90121FFF7BAFF79 -+:1037C00070BDC04610B500210446FFF7B3FF204688 -+:1037D000FEF74AFB10BDC04610B50122044640F674 -+:1037E0000501FCF735F920460722052340F22F4159 -+:1037F000FCF73EF920463021F8234FF4FF62FCF736 -+:1038000037F90623204630210722FCF731F92046FC -+:1038100040F2144141F61062FCF704F9204640F2F0 -+:1038200015414FF4C862FCF7FDF8204640F2DF4135 -+:103830004FF47F424FF47743FCF71AF92046FFF725 -+:10384000E9FB204602492722FCF726F910BDC046B5 -+:1038500024D90100002914BF0223002310B5002A37 -+:1038600018BF43F001030446032240F24D41FCF728 -+:10387000FFF8204640F24C410322FCF7E9F810BD66 -+:1038800010B5044611B91049132219E012220F494C -+:10389000FCF702F9012100222046FFF7DBFF20465A -+:1038A0000B490622FCF7F8F8B4F8DA3003F4704359 -+:1038B000B3F5005F07BF20460649204606491E2291 -+:1038C000FCF7EAF810BDC04638D501005ED501000E -+:1038D00082D50100CADC0100D8D601002DE9F041F3 -+:1038E00004460D46164640F2DA6148F280021F4651 -+:1038F0009DF81880FCF7ACF82046FEF7B9F9B8B18E -+:1039000040F652112046FCF781F8FF22C3B240F680 -+:1039100048112046FCF7ACF840F653112046FCF75E -+:1039200075F840F64911C3B2FF222046FCF7A0F813 -+:10393000D4F8A83093F8463573B140F2EB412046F5 -+:10394000FCF764F8C0F3402340F2EB4120464FF40B -+:1039500080629B02FCF78CF86B1EFF22204640F22F -+:1039600042619BB24FF6FF75FCF782F8AE4201D080 -+:10397000731E9EB220464FF4C8612A463346FCF7B8 -+:1039800077F8204640F241612A463B46FCF770F842 -+:10399000B8F1000F05D0204608490422FCF77CF856 -+:1039A00009E0204640F23F610122FCF73BF8204647 -+:1039B0000121FFF765FFBDE8F081C046A4D70100F3 -+:1039C0002DE9F0410C4640F23B410546FCF71EF85C -+:1039D00040F23C4107462846FCF718F8064674B109 -+:1039E0000E2228460F49FCF757F828460121FFF719 -+:1039F00047FF28460C490722FCF74EF810E02846FE -+:103A00000A490422FCF748F8284640F23B413A466E -+:103A1000FCF708F8284640F23C413246FCF702F831 -+:103A2000BDE8F081C4D7010080D80100B0D5010005 -+:103A30002DE9F04F0546C5B001910092FDF79CFCC1 -+:103A4000EB694FF0805118690A463CF033DE0520DF -+:103A5000F2F382F6002328464FF489614FF4804246 -+:103A6000FCF706F8284640F255414FF4A842FBF710 -+:103A7000D9FF284640F25641FBF7C8FF00F00F007F -+:103A8000052809D14FF4A842284640F25541FBF7DA -+:103A9000C9FF4FF4807207E045F20142284640F228 -+:103AA0005541FBF7BFFFFE22803A521022EAE27234 -+:103AB000102AA8BF10225100002301F18006C2EB9A -+:103AC000060B1F46994698469A464393429340E018 -+:103AD00040F256412846FBF799FF40F25741C0F3A8 -+:103AE0000B142846FBF792FF5E4544EA003021DCC8 -+:103AF000BAF17F0F1EDC8104890CB1F5005FC8BFED -+:103B0000A1F5804101F50063B3F5805F23D802ABD6 -+:103B100023F8191044AB03EB880252F8083C0AF171 -+:103B2000010ACB1842F8083C08EB090383F040096E -+:103B300088F00108C0F3033303F00C0343EA0713D2 -+:103B400016F0010F9FB203D007F0FF03402B02D104 -+:103B5000013E002EBCDCEB69002218694FF0805159 -+:103B60003CF0A8DD2846FDF701FC429B9B114293E7 -+:103B7000439B9B11BAF1800F43931DD0002022E09C -+:103B800041EA801202AB33F9123001315B1B40294C -+:103B900003FB0344F4D1013002280FD1009AA3099A -+:103BA0001460019A1360A3F53A63084A183B9342E4 -+:103BB0008CBF0020012006E00020044642AB53F8F1 -+:103BC00020500021DCE745B0BDE8F08F48F4FF0F3E -+:103BD00070B504460D46FDF7CFFB20226B01204651 -+:103BE0004FF49661FBF744FF0023204640F2B141B9 -+:103BF0004FF40072FBF73CFFB4F8DA3003F4704383 -+:103C0000B3F5005F02D04FF0000E04E0D5F1010ED5 -+:103C100038BF4FF0000E002D0CBF2023002343EAD5 -+:103C20008E13204660224FF48261FBF721FF20466D -+:103C30004FF482618022EB01FBF71AFF2046FDF76B -+:103C400095FB70BD2DE9F047044688461746D0F82D -+:103C5000A890FCF795FB20460121FFF7B9FF00254E -+:103C60002E460CE0012100222046FDF78DFA384651 -+:103C7000F2F372F52046FEF78BFA40B285B2F3B24A -+:103C800001364345EED320460021FFF7A1FF89F816 -+:103C9000C052BDE8F087C04670B505460846FEF73D -+:103CA000A7F8EB69A02144B218693CF023DD9D3CE4 -+:103CB000A4B26FF0610324B29C42B8BF1C46C1B2EB -+:103CC00062B22846FCF778FD70BDC04673B5D0F8E7 -+:103CD000A840064694F84233002B00F0DC8094F8AC -+:103CE0004633002B00F0D780D0F8B030D3F8203125 -+:103CF00013F0010F00F0CF8000230093019394F89C -+:103D00004553002D40F0AA8029462A46FFF76EFA57 -+:103D1000002800F0A380304601A96A46FFF788FE1C -+:103D2000002800F09B80009BC4F86C3394F8463365 -+:103D3000012B40F0938094F891030199AC46AE4674 -+:103D40001FE045B204EB8502D2F87033994201D3EB -+:103D5000002203E0C2F870131946012204EB850328 -+:103D6000D3F870339C440EF101035FFA83FE431CC9 -+:103D7000D8B243B2072BC8BF002012B101910199FC -+:103D800019E094F990334FFA8EF29A42D9DBF5E7B5 -+:103D900043B204EB8303D3F87023C3F87013431CBE -+:103DA000D8B243B2072BC8BF00200EF101038C44E8 -+:103DB0005FFA83FE11464FFA8EF3072BE8DD01917F -+:103DC00094F8902353B2072B05DC002384F8923338 -+:103DD000531C84F8903394F99033082B3ED194F817 -+:103DE0009433E31893F8972393F8995394F8923304 -+:103DF000FC2B02D8013384F8923394F89233934227 -+:103E00002CD194F89133013384F891335BB2072BB2 -+:103E100002DD002384F8913394F890333046023B5E -+:103E200084F890336146FEF7DFFF18B93046FEF79D -+:103E30001BF810E094F89333FC2B02D8013384F87C -+:103E4000933394F89333AB4205D194F8943313B978 -+:103E5000013384F89433002384F8923394F84613A2 -+:103E60000023012984F8453303D13046FFF7AEFB28 -+:103E700003E030461946FFF75DFC3046D4F86C137A -+:103E8000FFF70AFF002384F8473394F89C3313B9F3 -+:103E9000013384F89C337CBD2DE9F04F0746D0F800 -+:103EA000A800E1B00B9041F21403FB5C0C46002B20 -+:103EB00000F09C82FB696A2118693CF01BDC400021 -+:103EC0001FFA80FBBBF1000F00F090823846FEF72E -+:103ED00085F9FB69024610B91869594684E21869E8 -+:103EE00059463CF007DC012800F080820BF1060304 -+:103EF0009BB20C930BF13A039BB20D930BF16E0343 -+:103F00009BB20E930BF1AA039BB20F93002C00F00F -+:103F10005A82384640F2F941FBF778FD10F0080F5D -+:103F200040F064824CAD38ACAB1C0193A31C0393EE -+:103F30003846002340F2764140F2FF120095029489 -+:103F4000FBF7E0FD2B1D0093AB1D0193231D029396 -+:103F5000A31D03933846002340F2774140F2FF123D -+:103F6000FBF7D0FD05F10803009305F10A03019367 -+:103F700004F10803029304F10A030393384640F264 -+:103F8000AA4148F2FF1248F27F03FBF7BBFD05F19F -+:103F90000C03009305F10E03019304F10C031622A8 -+:103FA000029304F10E0303933846134640F23B415B -+:103FB000FBF7A8FD05F11003009305F1120301932F -+:103FC00004F11003029304F11203462203933846CE -+:103FD000002340F23C41FBF795FDB7F8DA3005F1DC -+:103FE000140E03F47043B3F5005F05F11C030A934C -+:103FF00005F11E03099304F11C03089304F11E0349 -+:10400000079305F12003069304F1200305F116023E -+:1040100004F1140104F1160005F1180605F11A085F -+:1040200004F1180904F11A0A05F12205059304F1B7 -+:10403000220437D1019241F22B02134602910390E0 -+:1040400040F24C413846CDF800E0FBF75BFD3846C6 -+:1040500040F24D4144F22B0244F20A030096CDF89F -+:104060000480CDF80890CDF80CA0FBF74BFD089A22 -+:104070000A980999079B02920722009001910393E5 -+:104080003846134640F2F941FBF73CFD0698059986 -+:10409000072200900291384640F2FA4113460195FA -+:1040A000039436E0019241F22B02134602910390F1 -+:1040B00040F24C413846CDF800E0FBF723FD38468E -+:1040C00040F24D4144F22B0244F222030096CDF817 -+:1040D0000480CDF80890CDF80CA0FBF713FD0A9AE8 -+:1040E000099B0898079900920722019302901346B2 -+:1040F0000391384640F2F941FBF704FD069A059B0F -+:104100000092029301950394384640F2FA41072247 -+:10411000002324ACFBF7F6FCA31C019310AB012297 -+:1041200002930DF14203072103933846134600948E -+:10413000FBF754FC231D0093A31D019311AB102228 -+:1041400002930DF14603FF21039338461346FBF714 -+:1041500045FC04F10803009304F10A03019312AB38 -+:10416000042202930DF14A034CAE039338461346E2 -+:1041700040F21F11FBF732FC06F1240338AD009327 -+:1041800006F12603019305F1240340F6440202934D -+:1041900005F1260303933846134640F63811FBF722 -+:1041A000B1FC06F12803009306F12A03019305F1FF -+:1041B0002803029305F12A030393384640F6391188 -+:1041C00040F6440240F60403FBF79CFC04F10C03A8 -+:1041D000009304F10E03019313AB012202930DF13E -+:1041E0004E033A21039338461346FBF7F7FB04F1DD -+:1041F0001003009304F11203019314AB08220293FD -+:104200000DF152030393384613464FF48D71FBF7BB -+:10421000E5FB04F11403009304F11603019315ABBD -+:10422000082202930DF156030521039338461346E5 -+:10423000FBF7D4FB04F11803009304F11A03019374 -+:1042400016AB042202930DF15A033A210393384628 -+:104250001346FBF7C3FB04F11C03009304F11E0398 -+:10426000019317AB012202930DF15E0303933846CD -+:1042700013464FF48D71FBF7B1FB06F12C0300934D -+:1042800006F12E03019305F12C03029305F12E0391 -+:104290000393384640F2D74147F2CB0242F24B0338 -+:1042A000FBF730FC04F12003009318AB20220293AB -+:1042B0000DF16203822122340393384613460194A0 -+:1042C000FBF78CFB0B98037B827AC17A1B0342F4C9 -+:1042D000007242EA011243F0030343EA820306F14B -+:1042E0003002009205F13002323602923235384601 -+:1042F0004FF49B6147F6FF729BB201960395FBF763 -+:1043000001FCDDF83090DDF834800026FB694CAC10 -+:10431000325B186949463CF00BDAFB6938AD725BD9 -+:10432000186941463CF004DAFB69A419186909F1DF -+:10433000020162883CF0FCD9FB69AD1908F1020169 -+:1043400018696A8804363CF0F3D9342E09F104095F -+:1043500008F10408DAD1DDF83890DDF83C80002659 -+:10436000FB6924AC325B186949463CF0E1D9FB6932 -+:1043700010AD725B186941463CF0DAD9FB69A419AB -+:10438000186909F1020162883CF0D2D9FB69AD19C4 -+:1043900008F1020118696A8804363CF0C9D9242E54 -+:1043A00009F1040908F10408DAD1FB690BF10201F3 -+:1043B00018690D223CF0BCD9FB690BF104011869A6 -+:1043C00009223CF0B5D9FB690B991A6A18690B9B55 -+:1043D000C1F83824B3F83C240BF1E6013CF0A8D92D -+:1043E000FB695946186901223CF0A2D961B0BDE8C9 -+:1043F000F08FC0462DE9F04F8DB007460F220E46D4 -+:104400000DF12100B149EDF3B7F5D7F8A8800022EE -+:10441000AF4D14016359B34203D001320E2AF7D1D4 -+:1044200073E3384691210022FBF77EFA38463821A3 -+:104430000722FBF779FA0A2238468821FBF774FA3B -+:10444000D7F8A83093F882251AB138468821FBF7AF -+:104450006BFA64192A213846227AFBF765FA302173 -+:1044600003223846637AFBF7A5FA912103223846E6 -+:10447000A37AFBF79FFAE37A38210F223846FBF73D -+:1044800099FA912100223846FBF74EFA382107228B -+:104490003846FBF749FA237B30210C229B00384633 -+:1044A000FBF788FA5E210F223846637BFBF782FA1E -+:1044B000A37B5E211B01F0223846FBF77BFA6C21BF -+:1044C0003846E27BFBF730FA384638210822FBF702 -+:1044D0002BFA384691210322FBF726FA0CA98B19F7 -+:1044E00013F8102C38465E21FBF71EFA01223846DD -+:1044F0007E21FBF719FA98F8EE231AB138463821D5 -+:10450000FBF712FA0722134638462A21FBF752FA24 -+:1045100038462C210022FBF707FA38462A210C22C4 -+:10452000FBF702FA012238462C21FBF7FDF9D7F8F8 -+:10453000A82092F852352BB338465E2192F85325C5 -+:10454000FBF7F2F9D7F8A830384693F854252A211A -+:10455000FBF7EAF9D7F8A830384693F855252B2110 -+:10456000FBF7E2F9D7F8A830384693F856252C2106 -+:10457000FBF7DAF9D7F8A83038462D2193F85725FC -+:10458000FBF7D2F9B7F8DA3003F47043B3F5805F84 -+:1045900004D13846BF21EE22FBF7C6F902221346AA -+:1045A000384640F21F11FBF705FA0422F7211346A3 -+:1045B0003846FBF7FFF9F121032200233846FBF7C9 -+:1045C000F9F9F221F82290233846FBF7F3F9A223F8 -+:1045D000F321FF223846FBF7EDF9B7F8DA3003F4A0 -+:1045E0007043B3F5005F04D1D7F8A83093F81835BD -+:1045F00006E0B3F5805F06D1D7F8A83093F81935F7 -+:10460000012B00F07982042238469D210023FBF71C -+:10461000D1F90022079244213846FBF76DF940F2A8 -+:104620002B1101903846FBF767F9442102900722CD -+:104630003846FBF7B1F9384640F22B110E22FBF752 -+:10464000ABF9079BD7F8F8AF0BB9554601E04FEA35 -+:104650004A05204B9A4502D84FF0010906E01E4B4F -+:104660009A4594BF4FF002094FF00409B7F8DA30C9 -+:1046700003F47043B3F5005F03D000210591069168 -+:1046800006E06268032302FB03F205926A000692C9 -+:10469000124C102221465046FDF7BEF91022214649 -+:1046A0002846FDF7B9F91022049009FB04F15046A1 -+:1046B000FDF7B2F9B7F8DA30039003F47043B3F5BD -+:1046C000005F0DD04FF0000B10E0C04612D4010087 -+:1046D000A8EF010080BA8C010075190340420F0059 -+:1046E000059802211022FDF797F983464F210222F7 -+:1046F0003846FBF719F9CD4B4FEACA0509FB03F31E -+:10470000B5FBF3F301335B08013B5FFA83F85221F9 -+:10471000072238464FEA9803FBF74CF908F10106E7 -+:104720005321602238464FEA4813FBF743F909FB4F -+:1047300006F3BF4CB5FBF3F5BE4B2C19B4FBF3F4F9 -+:10474000013CE4B2512122463846FBF7EDF8039BC9 -+:1047500010221D0158462946FDF75EF9013406FB7B -+:1047600004F600FB06F000280BDB58462946102211 -+:10477000FDF752F900FB06F0C01301304010441E53 -+:104780000EE0584629461022FDF746F96FEA080365 -+:1047900003FB04F300FB03F0C01301306FEA600475 -+:1047A000C4F3072353210F223846FBF703F95421A2 -+:1047B000E2B23846FBF7B8F806999F4B0A22B1FBE4 -+:1047C000F3F30599384601FB02F2B2FBF3F803FB61 -+:1047D0001822590802F0010401EB04545208B4FBFA -+:1047E000F3F49B0803EB0253B3FBF1F3E418452108 -+:1047F0001F22C8F30713FBF7DDF84FEA0813462121 -+:1048000038464FF4F87203F0F003FBF7D3F8C4F323 -+:10481000074346210F223846FBF7CCF84721C4F363 -+:1048200007223846FBF780F84821E2B23846FBF70A -+:104830007BF8079A41F29416002A08BF4FF4FA5603 -+:10484000A6F5D8760CBF4FF482794FF4E1794FF496 -+:10485000F572033E96FBF2F606FB02F505F52A75A6 -+:104860004FF425636D02B5FBF3F540F27C6405FB64 -+:1048700004F4A4F55834A4F5C064B4FBF2F4640A5B -+:10488000C4F3820242EAC6023846422192B2A4B27E -+:10489000FBF74AF804F0030204F01F0444EA421252 -+:1048A00038464321FBF740F84FEA49244FF4877319 -+:1048B000B4FBF3F404FB05F4604B640A604AB3FBF9 -+:1048C000F4F39A184FF41243B2FBF3F25D4B02F08B -+:1048D0000F02B3FBF4F3A3F54C23A3F500631B0C09 -+:1048E00042EA03123846402192B2FBF71DF84FF01E -+:1048F0002552554BB2FBF4F2B3FBF4F3A2F546326A -+:104900004FF4B841A2F50072A3F56E33B2FBF1F299 -+:10491000A3F50073B3FBF1F302F00F0242EA0312B6 -+:104920003846412192B20BF17444FAF7FDFF04F5C9 -+:1049300090044FF4966394FBF3F4292304FB03F4EF -+:104940004FF45C7308FB03F840F22B5306FB03F6AD -+:1049500006F5E46109FB08F00C311022FDF75CF864 -+:1049600004F5D81400EB640090FBF4F0C0B23C28CE -+:1049700094BF0025012515B14308043B00E0031F47 -+:10498000DCB23C213F2223463846FBF713F8AB014B -+:104990003C2140223846FBF70DF8B7F8DA3004F135 -+:1049A000040603F47043B3F5005F05F1010404D17C -+:1049B000D7F8A83093F8273506E0B3F5805F19D112 -+:1049C000D7F8A83093F82835012B13D1049B40F277 -+:1049D00045105946102203FB00F0FDF71DF804FBBB -+:1049E00006F39E2100FB03F4C02238464023FAF769 -+:1049F000E1FF0BE00499962001FB00F010225946DC -+:104A0000FDF70AF804FB06F300FB03F4B4F5160FF8 -+:104A1000D4BF002501256B1C032203FB02F394FB8A -+:104A2000F3F0B0F5003F11D5002315E0404B4C00EA -+:104A30003F420F0040420F00A08601000000686066 -+:104A40000021F6FF000084A30000302AA0F5C03347 -+:104A5000DB130133C3F347033D213F223846FAF706 -+:104A6000A9FFAB013D2140223846FAF7A3FF284BAE -+:104A70009A4504D9202238465721134603E0384688 -+:104A8000572120220023FAF795FF224B9A4504D99B -+:104A9000102238465721134603E03846572110228A -+:104AA0000023FAF787FF049AB2F5341F05DD384674 -+:104AB0004A210222FAF770FF04E038464A21FD221B -+:104AC000FAF75CFF0C22442113463846FAF772FFCE -+:104AD0000120F1F341F63846FEF76CFA019B3846A7 -+:104AE0004421DAB2FAF720FF029B384640F22B113C -+:104AF000DAB2FAF719FF08E004229D21384613467E -+:104B0000FAF758FF0121079185E50DB0BDE8F08F58 -+:104B100080BA8C01007519032DE9F0478A4BD0F853 -+:104B2000F84F4FF48475B4FBF3F404FB05F41A2337 -+:104B30005721B4FBF3F40646FAF7DEFE172181464F -+:104B40003046FAF7D9FE18213046FAF7D5FE40F282 -+:104B50000511FB2207463046FAF710FF30460421C4 -+:104B60004022FAF719FF30464FF490711022FAF7FD -+:104B700013FF304657210222FAF70EFF304640F26B -+:104B800005110422FAF708FF30464FF483712A22F8 -+:104B9000FAF7CAFEA4B2304640F207116E22FAF7C5 -+:104BA000C3FEE2B230462946FAF7BEFEC4F3042241 -+:104BB000304640F20911FAF7B7FE304640F20511CF -+:104BC000FD22FAF7DBFE30464FF483710122FAF73B -+:104BD000E3FE3220F1F3C0F55C4C03E00A20F1F370 -+:104BE000BBF50A3C30464FF48571FAF785FE10F0AC -+:104BF000010F01D1092CF1D130464FF48571FAF73C -+:104C00007BFE10F0010F08D1FAB230461821FAF7F6 -+:104C1000C3FE4FF00B0847460CE0304640F20F1140 -+:104C2000FAF76AFE00F01F071D2F8CBF4FF00B082C -+:104C300007F1020819213046FAF75EFE4FF483713E -+:104C4000FE2205463046FAF799FE304640F205113D -+:104C5000FB22FAF793FE304640F205110422FAF7E0 -+:104C60009BFE304640F205110222FAF795FE3046CF -+:104C70004FF483710122FAF78FFE3220F1F36CF5C5 -+:104C8000324C03E00A20F1F367F50A3C30464FF45A -+:104C90008571FAF731FE10F0010F01D1092CF1D125 -+:104CA00030464FF48571FAF727FE10F0010F06D158 -+:104CB000EAB230461921FAF737FE092506E03046F8 -+:104CC0004FF48871FAF718FE00F01F053046FE22F7 -+:104CD0004FF483716C01FAF751FE44EA85243046A3 -+:104CE000FB2240F20511FAF749FE2C4330465721CA -+:104CF0005FFA89F2FAF718FE3046224640F6331181 -+:104D0000FAF790FE2246BC02304644EA471440F6C9 -+:104D10003411FAF787FE304645EA040240F63511B1 -+:104D2000FAF780FE304644EA070240F63611FAF7F9 -+:104D300079FE48EA4812D205304640F63711D20DC6 -+:104D4000FAF770FEBDE8F08740420F0089969800A0 -+:104D500070B55B210446FD22FAF710FE20460421BF -+:104D60004022FAF719FE20464FF490711022FAF70C -+:104D700013FE204678218022FAF70EFE204640F2EC -+:104D800029110222FAF708FE204657210122FAF7DC -+:104D900003FE20465B210222FAF7FEFD41F2883035 -+:104DA000F1F3DAF4154D03E00A20F1F3D5F40A3DEE -+:104DB0005C212046FAF7A0FD10F0200F01D1092D4B -+:104DC000F2D15C212046FAF797FD10F0200F03D0B6 -+:104DD00020465C21FAF790FD20465B21FD22FAF780 -+:104DE000CDFD20465721FE22FAF7C8FD204640F2AD -+:104DF0002911FD22FAF7C2FD70BDC04689969800C0 -+:104E000070B504460E4600256E4B2046E95AFAF767 -+:104E100073FDA8530235302DF6D1182220466A4979 -+:104E2000FAF73AFE3A21FB222046FAF7A7FD0122C3 -+:104E300020464FF48D71FAF7AFFD3621012220464E -+:104E4000FAF7AAFD10224FF48D712046FAF7A4FD5F -+:104E50001420F1F381F43A2101222046FAF79CFD57 -+:104E60001420F1F379F4B4F8DA3003F47043B3F5B5 -+:104E7000005F03D120463A21012208E020463A2172 -+:104E800001220023FAF796FD2046CA210422134688 -+:104E9000FAF790FD082220464FF48D71FAF77CFD59 -+:104EA00025210E222046FAF73FFD2521012220462A -+:104EB000FAF772FDB4F8DA3003F47043B3F5805FAB -+:104EC00004D1204628211E22082303E02046282161 -+:104ED0001E220C23FAF76EFD1420F1F33DF4052198 -+:104EE00008222046FAF720FD80224FF489712046DF -+:104EF000FAF752FD1420F1F32FF4FF21102220467F -+:104F0000FAF74AFD442240F21F112046FAF744FD09 -+:104F10001420F1F321F40B2107222046FAF73CFD7F -+:104F2000102240F213112046FAF736FD1420F1F357 -+:104F300013F4072101222046FAF7F6FC1420F1F3BE -+:104F40000BF4022303222046FC21FAF733FDFD2156 -+:104F50002046A622FAF7E8FC442240F21F11204620 -+:104F6000FAF71AFD1420F1F3F7F3FF21102220467F -+:104F7000FAF712FD1420F1F3EFF3B4F8DA3003F48A -+:104F80007043B3F5805F03D110492046082202E048 -+:104F90000F4920460622FAF77FFD20465921CC22F0 -+:104FA000FAF7C2FC20465C212E22FAF7BDFC20460F -+:104FB0007821D722FAF7B8FC204692211522FAF779 -+:104FC000B3FC70BD5ED4010056DD01005ED7010068 -+:104FD00086DD01002DE9F04F04468BB0894609B902 -+:104FE0008B4608E040F2D741FAF710FD01A983464D -+:104FF0002046FDF79DFD202213464FF49A6120467E -+:10500000FAF736FD6420F1F3A7F340F2764120462B -+:10501000FAF7FCFC40F2A64180462046FAF7F6FC7F -+:1050200009A9824608AA204607ABFBF7C1F9099FE8 -+:10503000089E079DB9F1000F09D0204601A9FDF790 -+:105040005FFD204640F2D7415A46FAF7EBFC4FEAA3 -+:10505000C850C00D4FEACA5380F48070DB0D00F5D4 -+:10506000FE70033083F48073C01A801039463246D4 -+:105070002B46FCF7F1FC40000BB0BDE8F08FC046BA -+:10508000F0B5D0F8A85085B095F858340646002BF6 -+:105090007BD00023019302930393FDF779F8C7B205 -+:1050A0000FB17F2F71D101AB02AA304603A9FBF7E4 -+:1050B0007FF940F23E613046FAF7A8FC40F2A64183 -+:1050C000C4053046FAF7A2FCC005C00DE40DFF2868 -+:1050D0008ABFA0F5807300F580729AB2FF2C84BF5E -+:1050E000A4F5807398B2C2F5FE7398BF04F5807082 -+:1050F00003331B18C3F38F00C7B995F85634013337 -+:10510000DBB2042B85F856343FD985F85674029AE1 -+:10511000019B0399FCF7A0FCD5F848244310043BFD -+:105120009342B8BF1346C5F844341AE07F2F2CD100 -+:1051300095F857340133DBB2042B85F8573424D962 -+:10514000002385F85734029A019B0399FCF784FCED -+:10515000D5F84424431004339342A8BF1346C5F83E -+:105160004834D6F8A8109BB2D1F844243046934274 -+:10517000A8BF1346D1F8482440F2A7419342B8BFD4 -+:1051800013469BB2FF22FAF773FC05B0F0BDC04690 -+:105190002DE9F04F474B87B003AC80460D4693E8AE -+:1051A000070084E8070040F245614046D8F8A8B0FF -+:1051B000FAF72CFC40F2466187054046FAF726FCD8 -+:1051C0003D49860506224046FAF766FC00210A465C -+:1051D0004046FDF745F84FF4FA73019340462946DF -+:1051E0002022A3F5FA730094FDF73AFFBF0DB60D28 -+:1051F0008246002849D0049DDDF81490039C09EBF9 -+:105200000503012B02D84FF0000A3EE02046FBF7D1 -+:1052100057F806464846FBF753F8A6F114031AB2AE -+:10522000002A06DB35FA02F13FD0013235FA02F2EC -+:1052300006E0534215FA03F137D0D24315FA02F2D1 -+:1052400033B2C3F11E0314FA03F3C3EB0204A0F15B -+:105250000B031BB2002B0A4602DB35FA03F102E016 -+:105260005B4215FA03F120D003B2C3F11F0309FA20 -+:1052700003F394FBF2F493FBF1F004FB1400FBF74F -+:105280002BF8A7058605BF0DB60D404639463246B8 -+:10529000FCF7E6FF404609490622FAF7FDFB5046B7 -+:1052A000ABF8B872ABF8BA6200E0002007B0BDE816 -+:1052B000F08FC04634D4010074D801007ED90100BB -+:1052C00070B504460D46C9B104221249FAF7E4FB51 -+:1052D000D4F8A83093F8E933A02B05D1204640F646 -+:1052E0004A1140F24F1203E0204640F64A11A7222D -+:1052F000FAF798FB084920460E2201E007490A22E6 -+:10530000FAF7CAFBE369291E18BF012118693BF0AF -+:105310004BDA70BDE0D70100BAD901000EDD010003 -+:1053200070B50C4606222749E4B20546D0F8A860BD -+:10533000FAF7B2FB0C2C01D8002406E005F58A53DD -+:1053400093F900301C1E18BF012496F81A35002B63 -+:1053500031D0284640F64211FAF758FB14B10F2815 -+:105360000BD100E0A8B9D5F8F83013F0060F22D120 -+:1053700096F82C30A3421ED05CB1EB690122D868AC -+:105380009968F0F33BF628460121FFF799FF0123C6 -+:105390000AE0EB690022D8689968F0F32FF62846F6 -+:1053A0000021FFF78DFF002386F82C3028460649A0 -+:1053B0000C22FAF771FB284604490422FAF76CFB29 -+:1053C00070BDC04692DD010046D70100F8DD010046 -+:1053D00070B50D46B0F8DA101646D0F8A840FAF7C6 -+:1053E0003BFD28B994F84C342B7094F84D3401E00F -+:1053F00000232B70337070BD2DE9F0474FF000088B -+:1054000086B0054602ABCDF81080CDF80C80CDF803 -+:10541000088003AA8A4604A9D0F8A890FAF7C8FF22 -+:1054200028460DF117010DF11602FFF7D1FF9DF887 -+:10543000173004990193039A029B01242846009493 -+:10544000FCF71EFB9DF81630074601932846029B89 -+:105450000499039ACDF80080FCF712FB99F8E83321 -+:1054600006460BB39DF81700B5F90221B5F90431D2 -+:10547000B5F9061101902846039202930491009415 -+:10548000FCF7FEFA9DF8163004460193284604996D -+:10549000039A029BCDF80080FCF7F2FAA742B8BF4E -+:1054A00027468642A8BF0646BAF1010F02D0BAF1DC -+:1054B000030F02D17B10C9F84434AAF10203DBB216 -+:1054C000012B02D87310C9F8483406B0BDE8F08744 -+:1054D00007B540F25643009340F255420133FAF7C4 -+:1054E000FBFB0EBD2DE9F04340F2DF4189B0D0F85F -+:1054F000A8400546FAF78AFAC3B27F2BA4F84C30CD -+:10550000C0F30720C4BFA3F58073A4F84C307F28F4 -+:10551000C8BFA0F58073A4F84E0001AFC8BFA4F8BF -+:105520004E301123039320262A330DF118094FF032 -+:105530000208284639460493CDF80490CDF8088037 -+:105540000596FFF7C5FF069B3F2B01D9803B0693CD -+:10555000069B2365079B3F2B01D9803B0793079B45 -+:1055600040F2344163652846FAF750FAC0B27F280A -+:10557000C4BFA0F5807398B284F8580040F224416B -+:105580002846FAF743FAC0F30720A4F85A0040F27D -+:1055900025412846FAF73AFA0D23C0B2A4F85C0078 -+:1055A000039328460F3339460493CDF80490CDF881 -+:1055B00008800596FFF78CFF069B2364079B6364B6 -+:1055C00009B0BDE8F083C0462DE9F041B2F1FF3FDC -+:1055D0008AB0064688461746D0F8A85002D1FCF794 -+:1055E000E3FB47B295F966355FFA88F4013394FB23 -+:1055F000F3F407230393193305930123E4B20293D1 -+:1056000001AD07AB0193304604F5A073294604931E -+:10561000FFF75EFF079BC034C3F307530793304681 -+:1056200006AB294601930494FFF752FF0021079827 -+:105630000DF126020DF12203F2F3BCF60021402009 -+:1056400008AB09AAF2F3B6F6BDF92230BDF9201075 -+:105650008B4209DABDF92400C91AF2F35DF7BDF8EF -+:105660002240ADF8240009E0BDF92600C1EB03019A -+:10567000F2F352F7BDF82040ADF82600BDF9260040 -+:10568000BDF92410F2F352F723B2032B80B201DDEF -+:10569000231F01E0C4F104039AB212B208FA02F126 -+:1056A00003B2052003FB0010911E01238B40013A39 -+:1056B000C018104107FB00F0C0F3CF000AB0BDE8EE -+:1056C000F081C04670B5182386B0D0F8A840039387 -+:1056D00000238022049340F276662033054605932A -+:1056E000314613460292FAF7C3F904F19C032846A7 -+:1056F00001A90193FFF7ECFE40F271612846FAF729 -+:1057000085F940F27361A4F89C022846FAF77EF905 -+:1057100040F27461A4F89E022846FAF777F940F245 -+:105720007561A4F8A2022846FAF770F940F279618F -+:10573000A4F8A0022846FAF769F93146A4F8A402B1 -+:105740002846FAF763F940F2DA61A4F8A60228467F -+:10575000FAF75CF940F22551A4F8A8022846FAF7B6 -+:1057600055F994F86735A4F8AA0284F8AC324FF4DE -+:105770008F612846FAF74AF94FF49A61A4F8AE020D -+:105780002846FAF743F940F22451A4F8B00228461B -+:10579000FAF73CF9B4F86835C0F3C030A4F8B43275 -+:1057A00094F80734A4F8B20284F8B63294F80834B6 -+:1057B00084F8B73206B070BD7FB500230293103372 -+:1057C00004930DF1160300930123019369465433AA -+:1057D0000393FFF77DFEBDF8160007B000BDC0467D -+:1057E0002DE9F84FD0F8A860074696F846355BB922 -+:1057F000FFF7E2FF40F3072340B21FFA80F81FFAD9 -+:1058000083F9C346CA4607E0B6F84AA5B6F84C8500 -+:10581000B6F84E95B6F850B5B7F8DA30384603F416 -+:105820007043B3F5005F0CBFB6F86660B6F8686009 -+:105830004FF0FF320121FCF72FFA36B20121324638 -+:1058400084B23846FCF728FA0021241A4FF0FF32C0 -+:105850003846FCF721FA0121324685B23846FCF77A -+:105860001BFAA4B2C4EB0A06B6B2C4EB08042D1AA4 -+:10587000FF2238463346A4B240F65211FAF7F8F840 -+:105880003846FF22234640F65311FAF7F1F838461E -+:10589000FF22334640F65611FAF7EAF8ADB2384621 -+:1058A000FF22234640F65711FAF7E2F8C5EB090349 -+:1058B0003846FF2240F648119BB2C5EB0B05FAF7BC -+:1058C000D7F8384640F64911FF22ABB2FAF7D0F8C4 -+:1058D000BDE8F88F2DE9F04F93B00DF126080C4686 -+:1058E000D0F8A8503B49064693464046222201AFD5 -+:1058F000ECF342F3384638492222ECF33DF3BCB1D5 -+:105900000022304640F60F11FAF78CF895F8E9338B -+:10591000324AA02B324B14BF0524032414BF104677 -+:10592000184614BF4FF0100A4FF0110AB94616E09E -+:10593000012230464FF41161FAF774F895F8E93313 -+:10594000284AA02B284B14BF0E240A2414BF10464B -+:10595000184614BF4FF0100A4FF0110AC14600223A -+:10596000114604E00B5A013224319B4506D0A24275 -+:105970001FFA82F8F6D14FF6FF7416E00FFA88F29C -+:10598000242302FB03070024254607E035F809100D -+:10599000304637F81420FAF745F8023501340AF199 -+:1059A00001039C42F2D11FFA88F43046FCF74EF90D -+:1059B00010B13046FFF714FF3046FCF767FD20B208 -+:1059C000B0F1FF3F0CBF4FF0FF30002013B0BDE837 -+:1059D000F08FC046BED8010004D5010088F0010058 -+:1059E0003AEF0100A4F201003CF101002DE9F0437F -+:1059F0008BB006460F4691460DF106001D49222246 -+:105A0000ECF3BAF2D6F8A83093F8E933A02B14BF20 -+:105A10004FF010084FF0110817B93D463C4619E009 -+:105A200000252C4609E00DF10603E15A3046F9F74E -+:105A3000EDFF013524F8090002344545F3D10BE0B0 -+:105A40000DF10603E15A34F809203046F9F7EAFF70 -+:105A5000013502344545F3D13046FCF7F7F810B173 -+:105A60003046FFF7BDFE17B93046FCF70FFD0BB00F -+:105A7000BDE8F0839EDD010030B587B005AB009333 -+:105A8000022301930023029350330C46039369468B -+:105A9000102315460493FFF71BFDBDF81430238037 -+:105AA000BDF816302B8007B030BDC0467FB50DF174 -+:105AB0001603009301230193013B02935733039391 -+:105AC000694610230493FFF703FDBDF81600000A92 -+:105AD00007B000BD07B540F25643009340F255426F -+:105AE0000133FAF7BFF80EBDF0B5B0F8DA30D0F8F0 -+:105AF000A85003F47043B3F5005F0CBF95F8403332 -+:105B000095F8413387B085F8423395F8423306461D -+:105B100085F84333B0F8DA3003F47043B3F5005F2F -+:105B200014D195F8492353B2002B02DD85F84823A0 -+:105B300009E0C3691B6D13F4805F01D0342300E0DA -+:105B4000302385F8483395F85C3313E095F84A2301 -+:105B500053B2002B02DD85F8482309E0C3691B6DB1 -+:105B600013F0805F01D0342300E0302385F8483300 -+:105B700095F85D335BB2002B4CDD0322022BA8BFEE -+:105B8000022303FB02F340F2DF413046DFB2F9F7B4 -+:105B90003DFFC1B27F29C0F30720C4BFA1F58073C8 -+:105BA00099B203B27F2BC8BFA0F580737AB2C8BF89 -+:105BB00098B292B2C2EB0003C2EB0102DBB202F078 -+:105BC000FF0242EA0322304640F2DF41F9F72AFFA2 -+:105BD0000DF116030093022301930F3302930F2359 -+:105BE00003933046082369460493FFF771FC9DF840 -+:105BF0001630FAB29B1A8DF816309DF817303046E1 -+:105C00009B1A69468DF81730FFF764FF30466C46E3 -+:105C1000FDF700FA4FF0FF3385F89A3395F84D33CE -+:105C2000002285F8472385F89C23BBB185F84223E1 -+:105C300085F84323304640F22341FF32B5F8503314 -+:105C4000F9F716FF30464FF4AA61B5F86023F9F76B -+:105C5000E9FE304604490422F9F71EFF3046FCF7FE -+:105C600013F907B0F0BDC0462ADB01002DE9F04F63 -+:105C7000C3690C464FF08051BBB00546D0F8A87000 -+:105C8000164618690A463AF015DD0520F0F364F56A -+:105C900028464FF489614FF480420023F9F7E8FE6B -+:105CA0000122284640F20A511346F9F7E1FE0DF1B0 -+:105CB000E703349301233593103336930F2337933F -+:105CC0002846082334A93893FFF702FC0CB131466B -+:105CD00012E0B5F8DA3003F47043B3F5005F40F03A -+:105CE0003E81EB6997F8BF641B6D13F4805F0CBFB6 -+:105CF00008210621FF2E00D10E469DF8E720032340 -+:105D000006FB13238DF8E6300DF1E60334932846A5 -+:105D1000102334A93793FFF7DDFE7300FE229BB2F8 -+:105D2000284640F20A51F9F7A3FE97F8C044FF2C29 -+:105D300000F0EA80002C00F0C980102C28BF10244D -+:105D4000C4F12403D9B272B24BB29A4201DDCEB291 -+:105D500002E0002E08BF012670B2A042019002DCD2 -+:105D60005FFA86F902E0631C5FFA83F904F1010B24 -+:105D7000C9EB0B035FFA83F80D2336931333389383 -+:105D80004FFA89F35B004FFA88F2049309AB03EBF7 -+:105D9000C203570003937B1CDBB2079363000133FC -+:105DA00005934FEA4B03029206934FF0000A0198C5 -+:105DB000049AA042CABF73B2CDF8DCB03793379BC8 -+:105DC00034A953445B003793039B284635923493A0 -+:105DD000FFF77EFB07990AE03AA800EB810353F82E -+:105DE000C42C42F0800243F8C42C8B1CD9B2059A13 -+:105DF0009142F1DD002111E03AAB03EB810203EBAC -+:105E0000870353F8C43C3AA842F8C43C00EB87032C -+:105E100053F8C03C42F8C03C8B1CD9B2B942EBDB12 -+:105E2000069A09AB349328464FEA4A0334A90AF18B -+:105E3000250A35923793FFF74DFEBAF14A0FB6D1D6 -+:105E4000019B4FFA88F2A342C4BF73B237934FFA53 -+:105E500089F335930DF1AE0303EB4203D8BFCDF8C0 -+:105E6000DCB034931023389328460E2334A936939C -+:105E7000FFF72EFB0CE03AAE06EB480333F83A2C62 -+:105E800042F4006223F83A2C08F101035FFA83F828 -+:105E9000A045F0D9002109E0029E3AA800EB430298 -+:105EA00000EB460333F83A3C22F83A3C0298CBB276 -+:105EB00001318342F0DB0DF1AE0334932846002319 -+:105EC00034A9CDF8D4B03793FFF704FE012213466E -+:105ED000284640F20E51F9F7CBFD4FF47E426302A3 -+:105EE0001340284640F20E51F9F7C2FD284640F211 -+:105EF0000F517F222346F9F7BBFD284640F20F5190 -+:105F00004FF47E52E3011BE0284640F20E5101227D -+:105F10000023F9F7ADFD284640F20E514FF47E42C2 -+:105F20000023F9F7A5FD284640F20F517F220023F8 -+:105F3000F9F79EFD284640F20F514FF47E520023A0 -+:105F4000F9F796FDEB694FF08051186900223AF09D -+:105F5000B1DB2846FDF75EF83BB0BDE8F08F214687 -+:105F6000CAE6C0462DE9F041D0F8A8600746D6F849 -+:105F70007C45002505E021463846FFF7ABFD01359D -+:105F80001434D6F878359D42F5D3BDE8F081C0468B -+:105F9000F0B5C369D0F8A85087B00746802198684B -+:105FA000F0F396F6044600286DD0B5F81C340026B0 -+:105FB00003F4807C03F4007E30464FF0000316F0BB -+:105FC000100206F00101035316D0BEF1000F03D0FA -+:105FD000D5F81C34C3F3802116F0080F02D095F8D1 -+:105FE0001A3408E0D5F8183416F0200F14BFC3F3A4 -+:105FF000072303F0FF030353BCF1000F00D062BB83 -+:1060000016F0040F09D016F0020F025B02D0D5F88B -+:106010000C340EE0D5F80C3418E016F0200F06F022 -+:1060200002030CD0025B13B1D5F8103401E0D5F8AF -+:10603000143409B11B0E0EE0C3F307430BE0025BFF -+:1060400013B1D5F8103401E0D5F8143411B1C3F30D -+:10605000072300E0DBB21343035301360230402E26 -+:10606000ABD10F230393002304933846103301A9C7 -+:10607000059302960194FFF72DFDFB692146986870 -+:106080008022F0F335F607B0F0BDC0462DE9F041AF -+:10609000002486B00594D0F8A8800646FBF784FE5D -+:1060A00007230293193304930746012325460193DE -+:1060B00016E00BB90C4603E011F0010F0FD14C08AC -+:1060C00030467AB2FFF780FA06AB43F8040D00932E -+:1060D000304604F5107369460393FFF7FBFC013566 -+:1060E000802DE9B298F96635E3D17BB101230193A4 -+:1060F000402405AB0093304604F5107369460393C2 -+:10610000FFF7E8FC631CDCB2802CF2D106B0BDE8DE -+:10611000F081C0462DE9F04FB0F8DA3089B003F4D1 -+:106120007043B3F5005F07468B46D0F8A85002D104 -+:10613000B5F8C42304E0B3F5805F08D1B5F8C623F1 -+:1061400013B2B3F1FF3F02D01FFA82FA01E04FF021 -+:10615000700A072304931933069301234FF00009B3 -+:10616000039307AB0293C846CDF80490019B18F047 -+:10617000010F0BEB0306F378009303D095F9663516 -+:10618000002B59D1B7F8DA3003F47043B3F5005F50 -+:1061900003D0019B13F80B9012E0B5F8402413B222 -+:1061A000B3F1FF3F18BF1FFA82F9B5F83E2408BFCC -+:1061B0004FF00F0913B2B3F1FF3F1CBF92B2009230 -+:1061C000B37872781B0443EA022343EA0A6343EA82 -+:1061D0000903079395F9663502AC0133B8FBF3F375 -+:1061E000C033384621460593FFF774FC07AB029392 -+:1061F00095F9663538460133B8FBF3F303F5A07320 -+:1062000021460593FFF764F93279009B120542EAB3 -+:106210000372079B384623F07F4323F470031A432D -+:10622000079295F9663521460133B8FBF3F303F580 -+:10623000A0730593FFF74EFC019B08F1010805339D -+:10624000B8F1800F019391D195F96635002B36D0C6 -+:106250005E4608F1800896F8423196F841211B0409 -+:1062600043EA022302AC43EA0A6343EA09033846DD -+:10627000214608F180050793CDF81480FFF72AFC2A -+:1062800007AB3846214602930595FFF721F996F8AA -+:106290004421009B120542EA0372079B384623F013 -+:1062A0007F4323F470031A43214608F10108079243 -+:1062B00005950536FFF70EFCB8F5A07FCBD109B0E8 -+:1062C000BDE8F08F10B5B0F8DA30D0F8A82003F4AC -+:1062D0007043B3F5005F03D1D2F87415FFF71AFFCE -+:1062E00010BDC0462DE9F043054687B0D0F8A89010 -+:1062F000002940D0072399F8C272029319330493FE -+:10630000012301934FF0000805AB00932AE007F149 -+:10631000C003284669460393FFF7DAF806F1C00385 -+:10632000284669460393FFF7D5FB07F5A073284677 -+:1063300069460393FFF7CCF806F5A0732846694633 -+:106340000393FFF7C7FB07F51073284669460393CD -+:10635000FFF7BEF806F51073284669466C460393AE -+:10636000FFF7B8FB99F8C2325FFA88F6B34208F13A -+:106370000108CCD20CE0B0F8DA3003F47043B3F586 -+:10638000005F02D10449FFF7C5FE2846FFF77EFEF5 -+:1063900007B0BDE8F083C046589502002DE9F041F2 -+:1063A000D0F8A84086B094F907144FF0FF3289B2B4 -+:1063B0000646FFF709F994F967350546022B01D027 -+:1063C000002007E094F90814304689B24FF0FF32FC -+:1063D000FFF7FAF807230293193304930123C0EB64 -+:1063E00005070193304605ABB4F868154FF0FF324E -+:1063F0000093FFF7E9F84FF000084FF00003C019D1 -+:10640000A4F86A3548BFA4F86A0521E094F8662527 -+:1064100012B111F0010F19D1B4F86835B4F96A5509 -+:106420008B4253B238BFED1B013391FBF3F3DBB268 -+:1064300003F5107330464FF0FF320393FFF7C4F8B3 -+:10644000401B059069463046FFF744FB08F1010800 -+:10645000B8F1800F5FFA88F1D8D194F966357BB135 -+:106460000123019305AB0093402404F510733046DB -+:1064700069460393FFF72EFB631CDCB2802CF4D13A -+:1064800006B0BDE8F081C04630B5182387B0D0F81B -+:10649000A840039308330593603302930023054615 -+:1064A000049301A904F19C030193FFF713FB284611 -+:1064B000B4F89C2240F27161F9F7B4FA2846B4F8B6 -+:1064C0009E2240F27361F9F7ADFA2846B4F8A22291 -+:1064D00040F27461F9F7A6FA2846B4F8A02240F217 -+:1064E0007561F9F79FFA2846B4F8A42240F2796161 -+:1064F000F9F798FA2846B4F8A62240F27661F9F73F -+:1065000091FA2846B4F8A82240F2DA61F9F78AFA3B -+:106510002846B4F8AA2240F22551F9F783FA284612 -+:10652000B4F8AE224FF48F61F9F77CFA2846B4F83C -+:10653000B0224FF49A61F9F775FAB4F8B2324FF419 -+:106540000042DB032846134040F22451F9F790FA49 -+:1065500094F8AC32284684F86735B4F8B432A4F81D -+:10656000683594F8B63284F8073494F8B73284F872 -+:106570000834FFF713FF07B030BDC0462DE9F04FD8 -+:106580008DB0039202930BAB0646D0F8A8708B46F1 -+:1065900000930DF12F010DF12D030DF12E02FCF7EB -+:1065A0005DF930460DF12A010AAAFFF765FA304677 -+:1065B000FFF702F9072306931933089309AB0493F5 -+:1065C0004FF000080123059381464FF450735D4658 -+:1065D000C246079338E097F8662522B10AEB0B0311 -+:1065E00013F0010F2DD153B2013304ACB5FBF3F31B -+:1065F00003F5A073304621460793FEF769FF099B18 -+:10660000BDF828201B0D92051B05920D1A43BDF8FD -+:106610002A3030469B059B0D42EA83282146CDF85F -+:106620002480FFF757FACDF8249097F96635304665 -+:106630000133B5FBF3F303F5E07321460793FFF74E -+:1066400049FA01350AF1010A039A9542C3D997F92B -+:106650006635C3B17F2A16D14FF4C07504AC3046FD -+:1066600021460795CDF82480FFF734FA05F1800321 -+:10667000304621460135CDF824900793FFF72AFADA -+:10668000B5F5E07FEAD1029A07EB4203BDF82A2074 -+:10669000A3F86C20BDF82820A3F87890A3F8722006 -+:1066A0009DF82F3087F87E309DF82E3087F87F30A8 -+:1066B0009DF82D3087F880309DF82C3087F8813098 -+:1066C0000DB0BDE8F08FC0462DE9F04F8DB00393BB -+:1066D000C369D0F8A86005460C4698684FF48061FD -+:1066E0009346F0F3F5F20746002800F08A80C5F8DB -+:1066F000EC4F28460121FDF76BFA96F82C3043B198 -+:10670000284641490622F9F7C7F928460021FEF735 -+:10671000D7FDA4B101203D4984EAE472A2EBE47202 -+:1067200000FB01F1B1FBF2F39EB202FB06F2431C47 -+:106730008A4298B2EFD1B6F5807F01D95AE002269D -+:10674000242304FB03F349F6404293FBF2F30024B5 -+:106750001B04642293FBF2FAA146A0462EE04846B1 -+:106760000AA9F9F739FD0B9B03FB0BF3002B04DBA4 -+:10677000DB130133C3F3490206E05B42DB13013351 -+:106780005B105B429A05920D0A9B03FB0BF3002BF7 -+:1067900004DBDB130133C3F3490306E05B42DB1385 -+:1067A00001335B105B429B059B0D43EA822347F854 -+:1067B0002830631CD1449CB208F10108B442CED108 -+:1067C000062228461249F9F767F915230793002492 -+:1067D0000B33284605A90993059706960894FFF7F9 -+:1067E00079F9039B2846009331464FF6FF72234602 -+:1067F000FDF774F8EB69394698684FF48062F0F35E -+:1068000077F20DB0BDE8F08FE2DA0100005A6202C3 -+:1068100000DE010030B587B005AB00930123019382 -+:10682000173302930833002204934FF400230546E4 -+:1068300003920593144628466946FFF74BF9039BDC -+:1068400001330393631CDCB2802CF4D107B030BD5C -+:10685000F0B5D0F8A83087B093F89A250746002AFB -+:106860002DD1324B324D1E68144605E0294638467C -+:10687000FFF730F901341435B442F7D12D4A002422 -+:106880005368384601931023029308230493136836 -+:10689000694600930394FFF71DF9FB691B6B082BF6 -+:1068A0000DD1254A38465368694601931223029355 -+:1068B0000E330493136803940093FFF70BF910232E -+:1068C00004930DF1160300934FF07203082601257F -+:1068D000ADF81630384600236946039302960195B9 -+:1068E000FFF7F8F84FF0820338466946ADF81630E6 -+:1068F0000395FFF7EFF84FF0060369463846ADF809 -+:1069000016300396FFF7E6F83846FFF7DBFC38460B -+:10691000FFF728FB3846FFF73BFB3846FFF7B6FB8F -+:1069200038466C46FFF776FF07B0F0BD1CE001006B -+:10693000F8E401003CEC010018EC010070B5B0F87F -+:10694000DA30054603F47043B3F5005FD0F8A820B1 -+:106950000CD192F9F133B3F1FF3F37D1B2F9F833EB -+:10696000B3F1FF3F32D1B2F92C352CE0B3F5805FA3 -+:1069700035D192F95B35B3F1FF3F27D192F9F3336B -+:10698000B3F1FF3F22D192F95C35B3F1FF3F1DD146 -+:10699000B2F90034B3F1FF3F18D1B2F93035B3F199 -+:1069A000FF3F13D1B2F90234B3F1FF3F0ED1B2F978 -+:1069B0003435B3F1FF3F09D1B2F90434B3F1FF3FED -+:1069C00004D1B2F93835B3F1FF3F08D0012482F881 -+:1069D0006645102228464FF49A61134607E00024CA -+:1069E00082F8664528464FF49A6110222346F9F74B -+:1069F0003FF84FF48F61032223462846F9F738F811 -+:106A00002846FFF725FF2846FBF7E4FF2846FCF75A -+:106A1000E3FE2846FFF768F870BDC04610B50023B6 -+:106A200088B00593103307930DF1060303930123F8 -+:106A30000446ADF80610049303A954330693FFF7F8 -+:106A400049F82046FBF702F910B12046FEF7C8FED0 -+:106A500008B010BD2DE9F041D0F8A870064600241A -+:106A600019E0B6F8DA3003F47043B3F5805F07D16C -+:106A7000A218137923B1890492783046890C07E073 -+:106A80006B4BE21853792BB18904D2783046890CCC -+:106A9000F8F74AFF0634664A4FF6FF73A15A994247 -+:106AA000DFD1304673210022F8F73EFF3046322115 -+:106AB0006A22F8F739FF192230463321F8F734FFFC -+:106AC00097F8EC231AB130463321F8F72DFFC22195 -+:106AD0006F223046F8F728FF902110223046F8F751 -+:106AE00023FF102100223046F8F71EFF9B210722CA -+:106AF0003046F8F719FF1D2102223046F8F714FF3F -+:106B00001E2106223046F8F70FFF304640F2EA41D8 -+:106B100044F28862F8F786FFB6F8DA3003F470437F -+:106B2000B3F5005F0DD197F8E933B6F8CE1FA02B6F -+:106B300014BF022204220BB2B3F1FF3F0DD0CAB240 -+:106B40000BE0B3F5805F07D1B6F8D02F13B2B3F1E5 -+:106B5000FF3F01D0D2B200E0022253B21FFA83F805 -+:106B600007224346304640F2EB41F8F781FFB6F882 -+:106B7000DA3003F47043B3F5005F05D0B3F5805FFE -+:106B800004D197F83B350BB9002400E001242346DB -+:106B9000254624010F22A4B2304640F2F241F8F714 -+:106BA00067FFF0222346304640F2F241F8F760FFDB -+:106BB0000F22304640F2F1412B46F8F759FFF02200 -+:106BC0002346304640F2F141F8F752FF4FEA0823DE -+:106BD000304640F2F2414FF4E06203F47F43F8F7AD -+:106BE00047FFB6F8DA30304603F47043B3F5805F00 -+:106BF0000CBF03F5377341F2DA23F45A40F2EB414C -+:106C0000630203F47E434FF40072F8F731FFB6F8E5 -+:106C1000DA3003F47043B3F5805F0BD041F22433D4 -+:106C2000F25A13B2B3F1FF3F04D0930203E0C0461F -+:106C30009CF40100A3024FF4806203F47C433046CD -+:106C400040F2EB41F8F714FF40F2EB413046D6F842 -+:106C5000A840F8F7DBFEC0F3802084F8470540F237 -+:106C6000EB413046D6F8A840F8F7D0FEC0F34020FC -+:106C700084F84805D6F8A820304692F8481592F8CE -+:106C800047355B1A18BF012382F84635FAF7F0FF43 -+:106C9000830203F47C43304640F646114FF4806291 -+:106CA000F8F7E6FE304643490622F8F7F5FE41F2D2 -+:106CB0000D23F35C2BB10F22304677211346F8F7F2 -+:106CC00079FE30460021FFF7A9FE97F89A352BB9D7 -+:106CD0003046FEF73DF83046FDF71EFFF3697A2196 -+:106CE000186939F007DD97F8EC23400084B22AB127 -+:106CF00024B1F369A11C186939F01ADD97F8ED2366 -+:106D00002AB124B1F3692146186939F011DD97F8E9 -+:106D1000BB34DBB104221346304640F21D11F8F7B4 -+:106D200049FE30469F213F2297F8BC34F8F742FED7 -+:106D300030469E213F2297F8BD34F8F73BFE30469F -+:106D400077210F2297F8BE34F8F734FEB6F8DA3020 -+:106D500003F47043B3F5805F29D197F9583533B305 -+:106D6000B42124223046F8F7DFFDB7212422304633 -+:106D7000F8F7DAFD0322B8213046F8F7D5FD97F988 -+:106D80005825022A07D13046B821F8F7CDFD304604 -+:106D9000B521012209E0032A09D13046B821013A80 -+:106DA000F8F7C2FD3046B5210022F8F7BDFDBDE879 -+:106DB000F081C04644D8010010B5FFF74BFE10BD6E -+:106DC00070B50026D0F8A850C0F8EC6F95F82C30BC -+:106DD00004463BB12A490622F8F75EFE204601210F -+:106DE000FEF76EFA204640F24461F8F70FFE10F00D -+:106DF000010309D020463146FCF742FD022220461D -+:106E000040F23F61134607E010F0020F06D0204623 -+:106E100040F253414FF40042F8F72AFE2046194948 -+:106E20000922F8F739FE20460021FCF7D1FE204662 -+:106E3000FAF71EFF30B12046FEF7BEFC01462046A1 -+:106E4000FFF7ECFD95F8473520469B0203F47C43A1 -+:106E500040F2EB414FF48062F8F70AFEB5F84E3588 -+:106E60006BB1204640F64811FF22F8F701FE20469C -+:106E700040F64911FF22B5F85035F8F7F9FD70BD1D -+:106E800002D801008AD9010070B50C4688B00546C9 -+:106E9000F9F72AF944B92846FFF792FF2846214618 -+:106EA000FCF796FE204622E0284621460122FAF70A -+:106EB0008DF8064608B1012019E028460121FCF7AB -+:106EC00087FE0C4B4024039315230593284610237B -+:106ED00003A9079304940696FEF7FCFD2846214675 -+:106EE0004FF6FF7233460096FCF7F8FC304608B0C8 -+:106EF00070BDC04694EE010070B5002386B00293C9 -+:106F00001033049305AB009302230446ADF814102C -+:106F100001930D464E3369461646ADF8162003938D -+:106F2000FEF7D8FD2046FAF7A3FE78B3204640F6D8 -+:106F3000461140F2FF322B46F8F79AFD204640F604 -+:106F4000471140F2FF323346F8F792FD20464FF4E6 -+:106F5000156140F2FF322B46F8F78AFD204640F6D5 -+:106F6000511140F2FF323346F8F782FD204640F6D9 -+:106F7000541140F2FF322B46F8F77AFD204640F6D6 -+:106F8000551140F2FF323346F8F772FD06B070BD7E -+:106F90002DE9F04F8DB004910392D0F8A860074618 -+:106FA00006EB4303B3F872B0B3F86C10B3F8789003 -+:106FB0005A460591FFF7A0FF38464946FFF72EFDD8 -+:106FC0000723089319330A934FF000080123049D07 -+:106FD0000793C2460BAB069337E096F866252AB1B5 -+:106FE00004990AEB010313F0010F2BD153B20133C3 -+:106FF00006ACB5FBF3F303F5A073384621460993BD -+:10700000FEF766FA0B9B05994FEA8B521B0D1B0589 -+:10701000920D1A438B059B0D42EA83283846214680 -+:10702000CDF82C80FEF756FD96F9663538460133CB -+:10703000B5FBF3F303F5E07321460993CDF82C90EB -+:10704000FEF748FD01350AF1010A039A9542C4D9B9 -+:1070500096F96635C3B17F2A16D14FF4C07506ACD8 -+:10706000384621460995CDF82C80FEF733FD05F111 -+:107070008003384621460135CDF82C900993FEF760 -+:1070800029FDB5F5E07FEAD196F8810096F87E10EB -+:1070900096F87F2096F8803000903846FBF7E0FCA9 -+:1070A0000DB0BDE8F08FC04670B500210446D0F8A1 -+:1070B000A8500B467F22FFF76BFF2046FFF7E4F94D -+:1070C0002046B5F8B812B5F8BA22FBF7C9F8204641 -+:1070D00040F2D16104220023F8F7CAFC70BDC0461B -+:1070E00070B50446D0F8A8300D4699B193F8BC327B -+:1070F00033B3FFF7D9FF20460422002340F2D161C9 -+:10710000F8F7B6FC8022204640F276611346F8F785 -+:10711000AFFC15E00422134640F2D161F8F7A8FC59 -+:107120008022204640F276612B46F8F7A1FC2046EB -+:107130002946FFF773FC204629462A46FFF7DCFE66 -+:1071400070BDC04630B500238BB0089307930693FB -+:107150000733054603930A4609B9049102E04FF448 -+:10716000307304932023059309AB01930123029309 -+:107170003AB9284608A907AA06ABF9F719F9002475 -+:1071800009E0B5F902310793B5F904310693B5F971 -+:1071900006310893F3E70899069B2046079AFAF709 -+:1071A0005BFC01A909902846FEF794FC049B01347E -+:1071B0000133802C0493EED10BB030BDF0B5284BD9 -+:1071C0008BB005AC05460F460FCB84E80F0041F2AB -+:1071D0001403EB5CD5F8A8601BB196F8E034002BE3 -+:1071E0003BD028461F490822F8F756FC0723029394 -+:1071F0001933049304230193009403F54F7301247E -+:107200000393284686F86A406946FEF763FC00232C -+:10721000099309AB019400934FF4517428466946D1 -+:107220000394FEF757FC013440F25E339C42F5D1E3 -+:1072300028460D491222F8F72FFC7B009BB2284606 -+:1072400040F2A94140F2FF12F8F712FC284640F242 -+:10725000A36110220023F8F70BFC0BB0F0BDC04671 -+:1072600080DB0100B8D50100C8D5010030B5D0F8E9 -+:10727000A8509BB004460022A31893F9103501A929 -+:107280005B4241F822300132142AF5D195F86A3078 -+:1072900063B90733179319331993159103F548739D -+:1072A000204615A916921893FEF714FCD4F8A810DE -+:1072B00094F82936D1F8442420469342A8BF1346B7 -+:1072C000D1F8482440F2A7419342B8BF13469BB27D -+:1072D000FF22F8F7CDFB95F8E833F3B1B5F8E623D4 -+:1072E00094F8293620469B1A1B024FF47F42134024 -+:1072F00040F2D141F8F7BCFB94F8292695F82535E2 -+:107300002046C3EB420395F8E62340F2D1419B1A95 -+:107310005BB2FF229BB2F8F7ABFB2046FAF7AAFB61 -+:107320001BB030BD70B5C6B001ACD0F8A850064651 -+:10733000002120464FF48072EAF382F6072343933C -+:1073400019334593419495F86A3043B91E334293FB -+:1073500030464FF4507341A94493FEF7BBFB4023E2 -+:1073600042933046DB1841A94493FEF7B3FB46B085 -+:1073700070BDC0462DE9F04106460C46FAF72EFFD7 -+:10738000214605463046FAF753FC29460446304666 -+:10739000FAF74EFC4022B4F5404F0CBF13460023D1 -+:1073A000054640F2DA613046D6F8A870F8F760FB7F -+:1073B0001022B4F5404F14BF13460023304640F26C -+:1073C000A361F8F755FB0122B4F5404F14BF002329 -+:1073D0000123304640F26E41F8F74AFBA54200F027 -+:1073E0009580B5F5404F02D13046FFF79BFFB4F5CD -+:1073F000404F3CD13046FFF739FFD6F8A8203B8EEE -+:1074000092F966255B00013293FBF2F3304640F2BD -+:10741000A44140F2FF129BB2F8F72AFB7B8E304664 -+:107420001B0240F2A5414FF4E06203F47F43F8F7FA -+:107430001FFB04223046002340F21F11F8F7BAFA6E -+:10744000F369E021186939F055D90021F8853046F3 -+:10745000FAF7A4FF4FF0FF3387F83430304640F29C -+:10746000A9414FF400420133F8F702FB03E0304634 -+:107470000121FAF793FF304640F2A4414FF46042F5 -+:107480002346F8F7F5FAB4F5404F0FD13046FAF736 -+:10749000EFFB40F2A44100280CBF4FF4005300233F -+:1074A0004FF400523046F8F7E3FA15E04EF20103CC -+:1074B0009C4211D13046FAF71BFB01463046FFF7DC -+:1074C0007DFE304640F2A941F8F7A0FA0223C0B28F -+:1074D00090FBF3F087F8C10297F96735012B0DDDBA -+:1074E00040F2A4413046F8F791FAC0F3803340F2FD -+:1074F000255130464FF40042DB0305E0304640F2B0 -+:1075000025514FF400420023F8F7B2FABDE8F081AC -+:1075100070B50023D0F8A82080F82B3692F8E0341C -+:1075200005468BB190F92A16D2F84834994203DB0C -+:10753000D2F81035994207DA4EF20101FFF71AFF2F -+:10754000012385F82B3612E041F21403EB5C73B192 -+:107550002846FAF743FE002104462846FFF70AFFB3 -+:107560002846FFF783FE28462146FFF703FF70BD3C -+:1075700030B5072389B0D0F8A84003931933059399 -+:1075800006AB0193012302930546013B049308E0F7 -+:10759000284601A9FEF79EFA049B01330493069B3B -+:1075A00001330693069B7F2BF2D94FF4307304937B -+:1075B000A3F5307308E0284601A9FEF78BFA049B77 -+:1075C00001330493069B01330693069B7F2BF2D96C -+:1075D000092228465B49F8F75FFA01212846FBF7A4 -+:1075E000A5FB242228465849F8F756FA2846FAF708 -+:1075F00061FDC0F34F00E62801DDFF2305E02846CA -+:10760000FAF758FD4008193083B2FF2240F2A54135 -+:107610002846F8F72DFA2846FFF784FEB4F8E6234B -+:10762000B4F8E433284603EB42039B019BB24FF4CA -+:107630009A6147F6C072F8F71BFA092228464349B7 -+:10764000F8F72AFAB5F8DA30282103F470431E223D -+:10765000B3F5005F14BF18231C232846F8F7AAF9D6 -+:1076600001223A2113462846F8F7A4F908221346C6 -+:1076700028464FF48D71F8F79DF925210C222846F4 -+:10768000F8F752F9B5F8DA3003F47043B3F5005F58 -+:1076900004D1022228463A21134603E028463A2123 -+:1076A00002220023F8F786F908221346284605210E -+:1076B000F8F780F9284606222549F8F7EDF947F250 -+:1076C0000802284640F2D7414FF40053F8F7D0F9AA -+:1076D0002846FAF7EFFC102305930DF11E030193E2 -+:1076E00001230824ADF81E0002932846053301A9A2 -+:1076F00004930394FEF7EEF928460F221549F8F794 -+:10770000CBF928463521FF220023F8F753F9284604 -+:10771000362103220023F8F74DF928462246234656 -+:107720004FF48D71F8F746F94FF48062284640F225 -+:10773000A4411346F8F79CF92846FBF78FFA09B0E5 -+:1077400030BDC04618DA01002ADA0100ECD501008C -+:1077500032DB01003EDB01007FB5090206AB23F8F6 -+:10776000021D009301230193013B029357330393BE -+:10777000694610230493FEF7ADF907B000BDC0467B -+:107780002DE9F041D0F8A8308AB083F8341083F89E -+:10779000C11293F9663506460F466BB111F001032D -+:1077A00004D04FF48F610C22082302E04FF48F6164 -+:1077B0000C22F8F75DF97F080723039301AC07F566 -+:1077C000A07320254FF001080493304609AB2146F1 -+:1077D00001930595CDF80880FDF77AFE07F1C00307 -+:1077E000049330460DEB0503214601930595FDF703 -+:1077F0006FFE089B304603F0FF02ADF81820C3F37C -+:107800000722C3F30743ADF81C30099B06A9C3F355 -+:107810000273ADF81A20ADF81E30FAF7F7FD09999A -+:107820003046C1F30751FFF797FF30464146FAF75C -+:10783000B5FD0AB0BDE8F0812DE9F04F91B0BDF87B -+:10784000783002AC0193BDF87C3007460093534B6F -+:107850009DF880601D460FCD0FC495E80F009DF880 -+:10786000748084E80F0038464D490422BDF87090BA -+:10787000BDF884A0BDF888B0F8F70EF9384640F29C -+:10788000A36102227300F8F7F3F8B8F1000F18D0E3 -+:1078900010AB4FF4002243F8042D0A9301230B93FD -+:1078A00017330C9308330E9300230D931C46384670 -+:1078B0000AA9FEF70FF90D9B01340133402C0D93FB -+:1078C000F5D1032409FB04F43846FAF7EDFE013440 -+:1078D000384640F2A1615246F8F7A4F8A4B23846FF -+:1078E00040F2A2615A46F8F79DF82246384640F227 -+:1078F0007E61F8F797F838462A490422F8F7CCF861 -+:107900000134142304FB03F4013CA2B238464FF4C3 -+:10791000C861F8F787F80022384640F27761F8F737 -+:1079200081F808230B930D330C930B3300240E9333 -+:10793000384602AB0AA90A930D94FEF7CBF83846F5 -+:1079400040F27B61019AF8F76DF8384640F27C61AD -+:10795000009AF8F767F82246384640F27D61F8F75A -+:1079600061F821463846FFF7F7FE38460E490422F3 -+:10797000F8F792F80D4C03E00A20EEF3EDF60A3C1E -+:10798000384640F27661F8F741F810F0010F01D067 -+:10799000092CF1D111B0BDE8F08FC04694D601009A -+:1079A000B4D701006ED601006CD8010049420F0027 -+:1079B0002DE9F043D0F8A8908BB0064688460525FF -+:1079C00003270F2DA8BF0F250024ABB2019330462B -+:1079D0000121224623460094029403940494FAF76A -+:1079E0005DFDDB2302934FF4AF6304934FF48243B6 -+:1079F0000593A3F581430122079330462146234690 -+:107A000000940194039206940894FFF715FFB8F1CF -+:107A1000000F1DD140F2BA613046F7F7F7FF40F290 -+:107A2000BB6104B23046F7F7F1FFA401A4B244F3FE -+:107A3000891404FB04F440F3090000FB0043B3F590 -+:107A4000005F01DAED1B03E0B3F5804F04DBED19B5 -+:107A500017B17B1EDFB2B4E7092D01DD092501E076 -+:107A600025EAE5752846C9F838500BB0BDE8F08323 -+:107A70002DE9F043D0F8A8608DB096F96635074639 -+:107A80008846CCB2D3B1634B01EA0303002B05DA7D -+:107A9000013B6FEAC3736FEAD3730133012B04D147 -+:107AA0004FF48F610C22073303E04FF48F610C22F7 -+:107AB0000023F7F7DDFF022398FBF3F8072386F88E -+:107AC000344086F8C14201AD039308F5A073202429 -+:107AD0004FF00109049338460BAB294601930594F6 -+:107AE000CDF80890FDF7F4FC08F1C0030493384684 -+:107AF0000AAB294601930594FDF7EAFC0A9B384638 -+:107B000003F0FF02ADF81820C3F30722C3F30743C5 -+:107B1000ADF81C300B9B06A9C3F30273ADF81E3001 -+:107B2000ADF81A20FAF772FC9DF82B10384601F0D8 -+:107B30007F01FAF71FFC0B993846C1F30751FFF795 -+:107B40000BFE38464946FAF729FC0B9A3846C2F331 -+:107B500089219205920DFFF7CFF908F5E0730493A0 -+:107B6000384609AB29460193FDF7B2FC3846BDF80B -+:107B70002410FEF753FF08F51073049338460DEBFD -+:107B8000040329460193FDF7A3FC089B3846DB005C -+:107B90009BB240F2A66141F6FF72F7F769FF96F9D2 -+:107BA00067354B4532DD40F225513846F7F72EFF59 -+:107BB0004FF48072C3B29845D4BF002401243846E4 -+:107BC0009845CCBF1346002340F22551F7F750FFEC -+:107BD0006302384640F225514FF4007203F47E43AD -+:107BE000F7F746FFA302384640F225514FF4806272 -+:107BF00003F47C43E402F7F73BFF384640F225519B -+:107C00004FF4006204F47843F7F732FF0DB0BDE89B -+:107C1000F083C0460100008070B504460D46002187 -+:107C2000FFF7A8FB20462946FFF722FF70BDC0469C -+:107C30002DE9F04F89B0054600920191FAF7CEFA8E -+:107C400040F23B4103902846F7F7E0FE04A902907A -+:107C50002846FAF711FA00244FF47A700134EEF353 -+:107C60007BF5022CF8D105F597531A6892F820306D -+:107C70001F1E18BF012792F821300BB17B1C9FB249 -+:107C800092F822300BB17B1C9FB292F823300BB1DB -+:107C90007B1C9FB24FF00009C8464FF0140ABCE0AD -+:107CA000D5F8B030D3F8203183F0010313F001048C -+:107CB00003D1EB69186938F06DDD2846F8F760FBF1 -+:107CC00005F597531B68284603EB4803998CFFF78B -+:107CD000A3FF28465146FFF73FFD1CB9EB69186921 -+:107CE00038F044DD4FF40042284640F2A4411346E8 -+:107CF000F7F7BEFE002441F288300134EEF32CF594 -+:107D0000032CF8D1284640F2A641F7F77FFEC005C4 -+:107D1000C00DFF2886BFA0F580731FFA83FB00F516 -+:107D2000807B00263446284640F23E61F7F76EFE1F -+:107D3000631CC005C00D9CB23618102CF3D1C6F3DD -+:107D40000F13FF2B8CBFA3F5807303F58073504690 -+:107D500000210DF11E029EB20DF11A03F0F32AF379 -+:107D600005F597531B680021434493F8200007AAA8 -+:107D700006ABF0F31FF3BDF91A30BDF918108B42B2 -+:107D800009DABDF91C00C91AF0F3C6F3BDF81A40B0 -+:107D9000ADF81C0009E0BDF91E00C1EB0301F0F3D2 -+:107DA000BBF3BDF81840ADF81E00BDF91C10BDF9BD -+:107DB0001E00F0F3BBF323B2032B81B201DD231FBE -+:107DC00001E0C4F1040398B200B2431E01229A40BC -+:107DD00009B2052301FB032353FA00F000F10C0361 -+:107DE000182B16D805F597531B68019A03EB8803E7 -+:107DF0001B69C31802F809304FEA9B03C3F17F03E4 -+:107E0000009A03EB960302F8093009F101031FFA07 -+:107E100083F908F101031FFA83F8B845FFF440AF76 -+:107E20000AF101035FFA83FABAF1640F02D84FF046 -+:107E30000008F2E7029B2846C3F38011FAF7AEFA76 -+:107E4000284604A9FAF7E2FA28460399FFF792FABE -+:107E5000484609B0BDE8F08F2DE9F04F1E46C369D2 -+:107E6000A9B0D0F8A88004460F4698684FF48371F3 -+:107E70001546EEF32DF70790002800F0EF81022E53 -+:107E80000FD016E00E4694F8DA3011F80629013DBD -+:107E90009A420BD17188B2882046FAF7E1F901269F -+:107EA000CCE1062305FB03F3063BF918002DE9D1CD -+:107EB000C3E1012E40F0C1812046FAF78FF900217D -+:107EC00008902046FFF756FA0025934B2046E95AC2 -+:107ED000F7F712FD1AABE8520235182DF5D140F232 -+:107EE00031612046F7F792FD15220B9040F2316187 -+:107EF0002046F7F7ADFD40F24C412046F7F786FDEE -+:107F000040F24D410C902046F7F780FD4FF496610A -+:107F10000D902046F7F77AFD40F2B1410E902046D1 -+:107F2000F7F774FD40F2F9410F902046F7F76EFD28 -+:107F300040F2FA4110902046F7F768FD40F63811FC -+:107F400011902046F7F762FD40F639111290204655 -+:107F5000F7F75CFD40F23B4114902046F7F756FDE1 -+:107F600040F23C4115902046F7F750FD40F2DA61AF -+:107F700016902046F7F74AFD40F2DB611890204644 -+:107F8000F7F744FD40F2B74119902046F7F73EFD60 -+:107F900040F23B4113902046F7F738FDC0F38010C4 -+:107FA0000A9008B9099007E0204626A9FAF764F874 -+:107FB00098F8C182CDF8248020463299FFF72CFE34 -+:107FC000062220465549F7F767FDB4F8DA3003F486 -+:107FD0007043B3F5005F04D1204698210322F7F7E0 -+:107FE000A3FC20464E491922F7F756FD20464D497D -+:107FF0001822F7F751FDB4F8DA304FF0030B03F411 -+:108000007043B3F5005F14BF04230023179322E1EC -+:108010001FFA88F300931FFA89F3002601931FFAD1 -+:108020008BF3324602932046179B31460396049603 -+:10803000FAF734FA20460121FAF744F9334620468C -+:1080400039493C22FEF740FB20464FF48971324605 -+:10805000F7F76AFC20AB00934FF4FA7A20464FF40E -+:10806000806120223346CDF804A0FAF7F9FF0546D7 -+:1080700020B92E48F7F722F82F4636E0334620463F -+:1080800029497822FEF720FB20464FF489713246B9 -+:10809000F7F74AFC23AB009320464FF4806120227F -+:1080A0003346CDF804A0FAF7DBFF18B92048F7F7FC -+:1080B00005F81AE0219A24982299B0EB420F0ED9C4 -+:1080C00093009B1898420AD2259AB2EB410F06D929 -+:1080D0008B005B189A422CBF0027012700E0002785 -+:1080E000B8F1010801D3002F92D0B9F1010902D3F0 -+:1080F000002F00F0AC80BBF1010B02D3002F00F089 -+:10810000AA80204640F2D16104220023F7F7B0FC98 -+:1081100087B93E4614E0C0468ED4010072D90100F2 -+:1081200014D7010090DB010080841E0008D60100F6 -+:1081300022D6010020464FF48061FDF729F806465B -+:108140002046FEF73DFE204640F231610B9AF7F7DC -+:1081500069FC204640F24C410C9AF7F763FC20463C -+:1081600040F24D410D9AF7F75DFC20464FF49661C1 -+:108170000E9AF7F757FC204640F2B1410F9AF7F7F5 -+:1081800051FC204640F2F941109AF7F74BFC20468B -+:1081900040F2FA41119AF7F745FC204640F63811B3 -+:1081A000129AF7F73FFC204640F63911149AF7F778 -+:1081B00039FC204640F23B41159AF7F733FC204644 -+:1081C00040F23C41169AF7F72DFC204640F2DA6166 -+:1081D000189AF7F727FC204640F2DB61199AF7F767 -+:1081E00021FC204640F2B741139AF7F71BFC2046CA -+:1081F00040F24C4104220023F7F73AFC0025194BCA -+:108200002046E95A1AABEA5A0235F7F78DFB182DCA -+:10821000F5D10A9B23B120460999FFF7FDFC03E045 -+:1082200020460A99FAF7BAF820460899FFF7A2F80B -+:1082300020460021FAF746F800E00026E369079996 -+:1082400098684FF48372EEF353F5304606E000274A -+:108250004FF00608DCE64FF00409F8E729B0BDE866 -+:10826000F08FC0468ED401002DE9F04FB3B00F93CC -+:108270009DF8F8409DF8F4300D940E939DF8004160 -+:108280009DF8FC300B940C93012405461646D0F85B -+:10829000A89088469DF8F0B0BDF804718DF8C740ED -+:1082A0008DF8C640FDF702FC40F2D74112902846F7 -+:1082B000F7F7ACFB40F2D74110902846F7F7A6FB42 -+:1082C0003449119006222846F7F7E6FB2846324942 -+:1082D0000F22F7F7E1FB284621461AAAFDF786FB95 -+:1082E000284621460022FDF7F5FABBF1000F02D027 -+:1082F0000023199318E028462146FBF769FCD5F8BE -+:10830000B030D3F8203183F0010313F00103199347 -+:108310000AD1EB69B821186942F2107238F008DA14 -+:10832000EB69186938F036DA28460121F9F7CAFFF7 -+:1083300028460121FBF7A4FA28460121FAF730F973 -+:1083400040F2EA412846F7F761FB40F2EB41179013 -+:108350002846F7F75BFB40F2EB4118902846F7F709 -+:1083600055FB00F0070340F2EB4128463822DB00C2 -+:10837000F7F77EFB28462DA999F8C1A2F9F77CFEF4 -+:1083800086B1337A53B12846717AFFF745FC96F8E7 -+:1083900009A007E038D801006ED701002846314611 -+:1083A000FAF734F840F29C412846F7F72FFB40F2E9 -+:1083B000316113902846F7F729FB40F2D6611590FA -+:1083C0002846F7F723FB40F2DA6114902846F7F7C6 -+:1083D0001DFB002116902846FAF72AFA28468849FC -+:1083E0000722F7F759FB2FAB23930123249306337E -+:1083F000259376B199F96625737A013293FBF2F3EE -+:1084000003F5107326932846202323A92793FDF70D -+:108410005FF82F9A2846D2002F9240F2716192B2F3 -+:10842000F7F700FB284677490C22F7F735FB0024C5 -+:10843000754B284633F81410F7F75EFA0DF1A203D6 -+:10844000E0540134122CF3D1072228464FF48B71EB -+:10845000F7F76AFAB5F8DA3003F47043B3F5005F62 -+:1084600005D1284640F22D110122F7F75DFA0722C7 -+:1084700028464FF49671F7F757FAB5F8DA3003F457 -+:108480007043B3F5005F14D128466A21C222F7F782 -+:108490004BFA284698210C22F7F746FA284640F274 -+:1084A0002F110322F7F740FA28469721F922F7F710 -+:1084B0003BFA0B2107222846F7F736FA1022284606 -+:1084C00040F21311F7F730FA1D2101222846F7F781 -+:1084D0002BFA012228464FF48A71F7F725FAB5F8EE -+:1084E000DA3003F47043B3F5005F04D128462E213F -+:1084F0001022F7F719FA082228464FF49571F7F77A -+:1085000013FA092102222846F7F70EFA042213462D -+:10851000284640F21F11F7F74DFAFF2110220023E1 -+:108520002846F7F747FA0721012200232846F7F7E4 -+:1085300041FA0521082200232846F7F73BFA4FF4B9 -+:1085400000421346284640F2DA61F7F791FA4146B5 -+:108550000F9A53462846FFF72BFA002480B20121D8 -+:1085600001902246284623460094029403940494E2 -+:10857000F9F794FF0E9BA74208BF4FF48247009380 -+:108580000D9B284601930C9B414602930B9B224670 -+:1085900003934FF4AF630493A3F59F6307935B4684 -+:1085A000059706940894FFF747F90DF1C60228468F -+:1085B0000DF1C701F9F79AFC9DF8C6203F2A53D860 -+:1085C0009DF9C730A3424FDB3F2B4DDC52B29A429C -+:1085D0004ADCB8F1000F27D123AC1823214625939C -+:1085E000284630AB26922393FCF772FF9DF9C730E3 -+:1085F00021462846309E2693FCF76AFF44460EE04B -+:108600007ED601008CD701005CDB010030AB284630 -+:1086100023A9269430962393FDF75CFA01349DF943 -+:10862000C62063B29A42F1DC182323AC259326338B -+:108630002693284630AB21462393FCF749FF3F237E -+:10864000284621462693FDF745FA01232846214670 -+:108650002693FCF73DFF0023284621462693FDF78D -+:1086600039FA2846FDF72EF8284640F2EA41179AD3 -+:10867000F7F7D8F9284640F2EB41189AF7F7D2F904 -+:108680002846D72102220023F7F794F9082213463F -+:108690002846D721F7F78EF9002328464FF4947126 -+:1086A0000822F7F787F928464FF48B710022F7F775 -+:1086B0003BF9284640F29C41139AF7F7B3F9284654 -+:1086C00040F23161159AF7F7ADF9284640F2D661CC -+:1086D000149AF7F7A7F9169C284644F0010292B2C3 -+:1086E00040F2DA61F7F79EF928460121FAF7A0F87F -+:1086F000109C082204EA0203284640F2D741F7F70B -+:10870000B7F9119C4FF4E04204EA0203284640F214 -+:10871000D741F7F7ADF92846FAF73EFD0024234B81 -+:10872000284633F814100DF1A203E25C0134F7F788 -+:10873000FBF8122CF3D14FF400620023284640F2DC -+:108740004C41F7F795F928460021FBF799F82846A0 -+:108750000021F9F7B7FD284640F23B4101220023F2 -+:10876000F7F786F900234FF40062284640F63811E7 -+:10877000F7F77EF928460021FBF72AFA2846002160 -+:108780001AAAFDF733F9284609490F22F7F784F9A9 -+:10879000199B1BB9EB69186937F0E8DF2846129975 -+:1087A000FEF7DAFF33B0BDE8F08FC0465CDB0100B6 -+:1087B000A0DC01002DE9F04FD0F8A83091B093F87B -+:1087C000F49318230C930FAB0A9320230E930123E9 -+:1087D00017460B9301FB01FB3E3305210022804627 -+:1087E000B9F1FF0F08BF4FF001090D9307910992EE -+:1087F00006230024039347F6FF733A4601250593A9 -+:108800004046234621460094019402940495FFF7C4 -+:108810002BFD40460AA9FCF75BFE0F9A42F30B338F -+:1088200003FB03F342F30B0202FB02327B7A5A454D -+:10883000069303D307990894CEB206E0B9F1000F6E -+:108840004DD1079908954B42DEB273B206999DB29D -+:108850006B189CB24FF0000A06990AEB01030899C5 -+:108860009BB221B15A4506D99B1B7B722DE0089B18 -+:108870000BB95A4529D322B27F2A26DC0AEB05031D -+:10888000002A1FFA83FA20DB06237C72039301235C -+:108890000021049347F6FF733A46059340460B4682 -+:1088A000009101910291FFF7DFFC40460AA9FCF715 -+:1088B0000FFE0F9A42F30B3303FB03F342F30B0259 -+:1088C00002FB023263199CB2C6E70799099A41F389 -+:1088D00046030132DBB2032A0793099288D111B013 -+:1088E000BDE8F08F2DE9F04F8DB0DDF858A01F46A0 -+:1088F0000123834616468AF808304FF000094FF0EE -+:10890000640808EB09030021C3F34F05DB238AF851 -+:10891000095001245246039358460B460091019199 -+:10892000029105910494FFF79FFC182308932733C5 -+:1089300009930BAB06935846202306A90A93079484 -+:10894000FCF7C6FD0B9B43F30B3202FB02F243F331 -+:108950000B0303FB03231A464FEAE273BB4202D820 -+:1089600003D1B24201D9A94600E0A8460B484FF016 -+:10897000FF31801941EB07018B4202D806D18242B8 -+:1089800004D99F4206D801D1964203D8C9EB080307 -+:10899000012BB6DC28460DB0BDE8F08F30F8FFFFA4 -+:1089A000F7B50546D0F8A87090F8DA000E46F7F74C -+:1089B0003FFA40F6B41398420446B5F8DA2001D1E4 -+:1089C0001E480AE0D3B2012B02D14FF4523004E02A -+:1089D0000302A3F5C420A0F5806000224FF47A7151 -+:1089E000F9F71AF8A0FB002328460096FFF77AFF54 -+:1089F000A0F128039BB21D2B1BD9272802D84FF4C6 -+:108A000034300BE040F6B4139C4202D14FF4703086 -+:108A100004E02302A3F5BE20A0F5007000224FF46D -+:108A20007A71F8F7F9FFA0FB002328460096FFF7BC -+:108A300059FF031F87F8C232FEBDC046008E0300F7 -+:108A40002DE9F04390F8DA30D0F8A8608BB086F8C2 -+:108A5000BC32D0F8B0300546D3F8203183F00103A2 -+:108A600013F001090AD1C369B821186942F21072E2 -+:108A700037F05EDEEB69186937F08CDE40F2A54115 -+:108A80002846F6F7C3FF04462846F9F7A7FB00215E -+:108A900080462846FEF76EFC4FF440412846FEF71C -+:108AA00069FC2846FEF73EFCD5F8A8202846D2F8F7 -+:108AB0004434D2F84824402BA8BF40239342B8BF87 -+:108AC000134640F2A741FF229BB2F6F7D1FF0023E5 -+:108AD000284640F2A5414FF4E062F6F7C9FF4FF493 -+:108AE0007A7232212846FBF7ADF80121284696F824 -+:108AF000C072FBF76DF82846F7F742FC4FF4E062CE -+:108B000004EA0203284640F2A541F6F7B1FF00212E -+:108B10002846FEF72FFC96F8C4420DF11E0E012CDC -+:108B200035D171462846FFF73BFF28462146FDF721 -+:108B3000D9FBD5F8A8202846D2F84434D2F84824E6 -+:108B40003E2BA8BF3E239342B8BF134640F2A74135 -+:108B5000FF229BB2F6F78CFF0023284640F2A54186 -+:108B60004FF4E062F6F784FF284632214FF47A7220 -+:108B7000FBF768F896F8C032DBB996F8C23228469F -+:108B8000043386F8C2322146FDF7ACFB11E0002128 -+:108B90000122DB238DF82620039304922846724697 -+:108BA0000B468DF827700091019102910591FFF716 -+:108BB0005BFB28464146FEF7DDFB284608490422B8 -+:108BC000F6F76AFFB9F1000F03D1EB69186937F0C6 -+:108BD000CDDD28460021FAF7FBFF0BB0BDE8F0839E -+:108BE00076D601002DE9F04F044695B0D0F8A86084 -+:108BF00040F2E7300F46EDF3AFF507212046F6F7D8 -+:108C00007BFEC0B20390FF212046F6F775FEC0B28E -+:108C1000049040F21F112046F6F76EFEC0B2059098 -+:108C200005212046F6F768FE25215FFA80FB2046E5 -+:108C3000F6F762FE4FF489715FFA80FA2046F6F784 -+:108C40005BFE00250190864B2046E95AF6F7DEFED2 -+:108C500007ABE85202351C2DF5D1D4F8B030D3F86B -+:108C6000203183F0010313F00103029303D1E36980 -+:108C7000186937F08FDD40F2A4412046F6F73CFE3C -+:108C8000002181462046FEF775FB7F21204696F89D -+:108C9000C182FEF7C1FF0122072113462046F6F7E5 -+:108CA00089FE1022FF2113462046F6F783FE042298 -+:108CB0001346204640F21F11F6F77CFE362220466E -+:108CC0006849F6F7E9FE2046F9F7F4F9C0F34F00DA -+:108CD000E62801DDFF2305E02046F9F7EBF940081F -+:108CE000193083B2FF22204640F2A541F6F7C0FEBC -+:108CF00025210C222046F6F717FE082213460521EF -+:108D00002046F6F757FE092257492046F6F7C4FEDB -+:108D10002046F9F7CFF9102312930123ADF84E0046 -+:108D200008260F9306250DF14E0320460EA9109636 -+:108D30000E931195FCF7CEFE012F0CD12A4620464A -+:108D40004A49F6F7A9FE2022204682211346F6F76B -+:108D500031FE042506E02A4620464549F6F79CFEEA -+:108D600007260A250122134620464FF49B61F6F799 -+:108D70007FFE45F4007343EA06139B0020464FF440 -+:108D80009B6140F6FC72F6F773FE02221346204602 -+:108D90004FF49B61F6F76CFE20464FF49B614FF455 -+:108DA000E0424FF40053F6F763FE202213462046BC -+:108DB0004FF49A61F6F75CFE012100222046F8F795 -+:108DC000E3F9204640F27641F6F720FE10F4004F1A -+:108DD00002D10A20EDF3C0F420460721039AF6F7EA -+:108DE000A3FD2046FF21049AF6F79EFD204640F29F -+:108DF0001F11059AF6F798FD204605215A46F6F709 -+:108E000093FD204625215246F6F78EFD019B204614 -+:108E10004FF48971DAB2F6F787FD0025104B204632 -+:108E2000E95A07ABEA5A0235F6F7FCFD1C2DF5D1DD -+:108E300020464FFA88F1FEF7EFFE204640F2A441AB -+:108E40004A46F6F771FD029B1BB9E369186937F0D2 -+:108E50008DDC40F2E730EDF37FF415B0BDE8F08F24 -+:108E600050D801000ADC010076DC010088DC01003A -+:108E700094DC01002DE9F04FBDB007460C46914649 -+:108E8000002116220DF15E000493E9F3D9F0A84900 -+:108E90000E220DF19E00E9F36FF0A6490E2224A8E0 -+:108EA000E9F36AF048F2670148F24522ADF8EA10AA -+:108EB000ADF8E820A04908220DF1C600E9F35CF006 -+:108EC0009E490E220DF18200E9F356F09C490822DA -+:108ED0000DF1BE00E9F350F09A490E221DA8E9F306 -+:108EE0004BF047F69733002108220DF1B600ADF89C -+:108EF000E630ADF8E430E9F3A3F0FB69302198687F -+:108F0000D7F8A880EDF3E4F60590002800F0AB82D6 -+:108F100040F2DB613846F6F779FD40F2DA610B90FA -+:108F20003846F6F773FD88490A9004223846F6F76A -+:108F3000B3FDB9F1070F0BD8DFE809F011040A0AF5 -+:108F40000A22352D1DAA069224AB0DF15E0214E013 -+:108F50000DF18202002306921A46079319E00021C0 -+:108F60000A460B4638460091F9F77AFD0DF1820169 -+:108F700006910DF15E020DF19E03072107933EE07D -+:108F80000DF1E6030DF1EA01069308F18202079163 -+:108F900001230E9334E039A906913AAB08F182021D -+:108FA000012107932BE03BAB00930DF1EF010DF195 -+:108FB000EE020DF1ED033846F9F750FC9DF8EF2075 -+:108FC0009DF8EE300DF1BE0143EA02234FF000029E -+:108FD000ADF86C30ADF86E209DF8EC309DF8ED20CA -+:108FE000069143EA0223ADF870304FF00003ADF86C -+:108FF00072300DF1C6030DF15E02079304210E914C -+:109000001023009330330193504B002102933846D4 -+:109010000B23F6F7B1FE05224D493846F6F73CFD25 -+:109020003846F9F7DBF84FF480521346089040F2C7 -+:10903000A4413846F6F71CFD00213846FEF79AF9A0 -+:1090400040F2DB413846F6F7E1FC4249062209903E -+:109050003846F6F721FDB7F8DA3003F47043B3F57C -+:10906000005F07BF38463C4938463C491222F6F7B4 -+:1090700013FD40F2D7413846F6F7C8FC0599119028 -+:109080003846FBF7BDFE384640F23B41F6F7BEFCE2 -+:10909000C0F380100C9020B138460DF1B601F8F7FE -+:1090A000EBFF64B90C9A22B93846B8F83010FEF7D5 -+:1090B000B3FD0DF1CE0438462146F8F7DDFF638895 -+:1090C00022881B0143EA0223A288214613439EB251 -+:1090D000B7F8DA30082203F470430DF1D600B3F587 -+:1090E000805F14BF00250125E8F346F70A222BA86C -+:1090F0000021E8F3A5F71A4B002233F8154010467B -+:1091000033E0184B53F82530C1180B881230B342A6 -+:109110002AD14B882BA8ADF8D6308A88ADF8D82054 -+:1091200031F8063F0A22ADF8DA30E8F325F71EE001 -+:1091300030DD01000ED801001CD801001ADB01004F -+:10914000D8DB010022DD0100BCD70100D55A0100A7 -+:109150009AD50100A4D50100B4D60100F4D90100CC -+:1091600028DB0100D8D901000132A242C9D138461A -+:109170000DF1D601F9F74AF900240422384637499F -+:10918000374DF6F789FC10260A2338462146354A22 -+:10919000009601940295F6F7EFFD202301933846DF -+:1091A0000A2321462F4A00960295F6F7E5FD40F284 -+:1091B0005341384640F2A472F6F734FCB8F8C813AD -+:1091C00040F6A663A14208BF1946B9F1050F01D1C7 -+:1091D0004B4299B2D7F8EC3F0CB22BB13846FDF7B1 -+:1091E000EFFD0520EDF3B8F24FF47A710123582218 -+:1091F000384604FB01F1FDF767FA40F2DA614FF6F9 -+:10920000FF723846F6F70EFCB7F8DA30384603F44A -+:109210007043B3F5005F0CBF98F8959598F8969554 -+:10922000F8F7B6FF0021C0B2FF228B4610900D91D7 -+:109230000F929AE04FF000030799ADF8E0303BF849 -+:109240000130C3F30324B9F1000F1AD0042C0BD062 -+:109250000F9A042A13D110990EE0C04606DD0100D2 -+:10926000D55A010010D90100109901EB0903D9B2B8 -+:1092700011F0800F18BF7F213846FEF781FAE2B265 -+:109280000F92069B3CA93BF8032001EB440333F803 -+:10929000441C21B102F0FF0343EA01239AB238468D -+:1092A00040F25241F6F7BEFBE31E1FFA83FABAF111 -+:1092B000010F16D86D4B1025452402933846002126 -+:1092C0000DF1E202012300950194F6F747FD684B8A -+:1092D00038460293002138AA012300950194F6F73D -+:1092E0004BFD079B384640F251413BF80320F6F70F -+:1092F00099FB3846F9F730FF00287CD05B4A6021A3 -+:1093000012AC10250B23019102920021384622460F -+:109310000095574EF6F722FD4023019300210B23C1 -+:109320003846224600950296F6F726FDBAF1010F5F -+:109330000AD845230193384600210DF1E2020123AA -+:1093400000950296F6F718FD4849602301930291B3 -+:1093500008F18202384600210B230095F6F7FEFC47 -+:109360000D9A0BF1020B01320D920D9B0E998B425F -+:109370007FF460AF602301933C4B08F18206102418 -+:1093800002933846002132460B23394D0094F6F7FC -+:10939000E5FC4FF001025023A8F8982038460193CD -+:1093A00000213246042300940295F6F7E5FC55238C -+:1093B00001933846002108F18C02022300940295A3 -+:1093C000F6F7DAFC3846F8F753FCA0B138A90DF1EE -+:1093D000DE023846FCF750FB3846FCF7EDF9BDF8E5 -+:1093E000E0100446BDF8DE203846FDF785FD38461E -+:1093F0002146FDF713FB049B13B93846FDF7E0FC4B -+:1094000038460599F9F716FB384640F2D741119ACC -+:10941000F6F708FBFB69059998683022EDF368F4CC -+:10942000384640F2DB41099AF6F7FCFA40F2534124 -+:1094300038460022F6F7F6FA0C9921B138460DF1BC -+:10944000B601F8F7E3FF38460899FDF793FF384671 -+:1094500040F2DA610A9AF6F7E5FA384640F2DB6143 -+:109460000B9AF6F7DFFA3DB0BDE8F08FD15401005A -+:10947000D55A01002DE9F0470546D0F8A8404FEA3B -+:109480000118F8F785FE40F2D74147B22846F6F7B3 -+:10949000BDFA94F925258146B2F1FF3F11D004238E -+:1094A00092FBF3F3984505DA284640F2D741402273 -+:1094B000002304E04022284640F2D7411346F6F745 -+:1094C000D7FAD5F8EC3F53B12846FDF779FC0520D3 -+:1094D000EDF342F11C4928467022002302E01A49AC -+:1094E00028467022FDF7F0F828463946FEF794FB2F -+:1094F000002601212846FBF76DFD0423C8EB00047C -+:109500007A1E94FBF3F3D2187F2AA8BF7F2222EAA7 -+:10951000E277284639460434FEF77EFB082C03D94F -+:109520000A2E01D00136E4E72846FDF749FC28461B -+:1095300040F2D7414A46F6F775FA2846F8F728FE72 -+:1095400040B2BDE8F087C04600093D002DE9F04378 -+:1095500091B08046D0F8A860F8F71AFE1C23B8F83E -+:10956000DA208DF83B3001238DF83A3002F4704355 -+:10957000B3F5805F5FFA80F907D1D3B2402B01D8F1 -+:109580001B2300E02D238DF83B30B8F8DA2002F4DD -+:109590007043B3F5005F33D1B6F82A2513B2B3F1A7 -+:1095A000FF3F04D04FF6FF73002A08BF1A46B6F8F3 -+:1095B000F6130BB2B3F1FF3F02D14FF4917104E007 -+:1095C0004FF6FF73002908BF1946B6F82C5596F8D8 -+:1095D000F0032BB2B3F1FF3F04D04FF6FF73002D21 -+:1095E00008BF1D46B6F8F84323B2B3F1FF3F04D0DD -+:1095F0004FF6FF73002C08BF1C4696F8F1739FE0EE -+:10960000D3B2402B33D8B6F82E2513B2B3F1FF3FB7 -+:1096100004D04FF6FF73002A08BF1A46B6F8FA13B3 -+:109620000BB2B3F1FF3F02D14FF4917104E04FF65A -+:10963000FF73002908BF1946B6F8305596F859054A -+:109640002BB2B3F1FF3F04D04FF6FF73002D08BFDC -+:109650001D46B6F8004423B2B3F1FF3F04D04FF6E5 -+:10966000FF73002C08BF1C4696F85B7568E08C2BD6 -+:1096700033D8B6F8322513B2B3F1FF3F04D04FF61A -+:10968000FF73002A08BF1A46B6F8FC130BB2B3F1F9 -+:10969000FF3F02D14FF4917104E04FF6FF730029B0 -+:1096A00008BF1946B6F8345596F8F2032BB2B3F159 -+:1096B000FF3F04D04FF6FF73002D08BF1D46B6F8DC -+:1096C000024423B2B3F1FF3F04D04FF6FF73002CE6 -+:1096D00008BF1C4696F8F37332E0B6F8362513B28D -+:1096E000B3F1FF3F04D04FF6FF73002A08BF1A46BC -+:1096F000B6F8FE130BB2B3F1FF3F02D14FF49171F4 -+:1097000004E04FF6FF73002908BF1946B6F8385534 -+:1097100096F85A052BB2B3F1FF3F04D04FF6FF7312 -+:10972000002D08BF1D46B6F8044423B2B3F1FF3F35 -+:1097300004D04FF6FF73002C08BF1C4696F85C75EA -+:1097400013B2B3F1FF3F04D040461946FFF792FE33 -+:109750000DE009B2B1F1FF3F07D040460DF13202F2 -+:10976000FFF728F89DF83B3007E0FF2802D086F885 -+:10977000070404E09DF83B300BB186F8073429B2AA -+:10978000B1F1FF3F05D04046FFF774FE86F80804AC -+:1097900011E021B2B1F1FF3F09D040460DF1320294 -+:1097A000FFF708F89DF83B3086F8083403E0FF2FF8 -+:1097B00018BF86F8087496F9EF33B3F1FF3F1CBF6A -+:1097C0004FF0FF3386F8083496F8080441B2B1F13F -+:1097D000FF3F76D096F8072453B29942D8BF86F857 -+:1097E000082496F80834D8BF86F8070400248DF8BA -+:1097F0003B30DB23012503934046234621460DF1F0 -+:10980000320204950094019402940594FEF72CFD15 -+:1098100018230993083308950B93254607AC0FAB23 -+:109820004046214607930A95FBF752FE05F1400397 -+:109830004046214601350A93FCF74CF9402DEDD105 -+:1098400096F9072496F908349B18022293FBF2F349 -+:10985000A6F86835B8F8DA2002F47043B3F5005F73 -+:1098600002D1B6F85E3583B9D3B2402B05D8B6F82D -+:10987000602512B1A6F8682509E08C2B02D8B6F84D -+:10988000623513B9B6F864350BB1A6F868354046B1 -+:1098900040F224514FF400420023F6F7E9F896F91C -+:1098A0006625B6F86835013293FBF2F39BB2404669 -+:1098B00040F22551FF22F6F7DBF8022386F86735E0 -+:1098C00029E0012386F86735404640F22551FF2202 -+:1098D0007E33F6F7CDF8404640F225514FF48072C2 -+:1098E0000023F6F7C5F8404640F225514FF40072C8 -+:1098F0000023F6F7BDF8404640F225514FF4806250 -+:109900000023F6F7B5F8404640F225514FF40062C7 -+:109910000023F6F7ADF84FF00003A6F86A3540468D -+:1099200040F2255196F96645F6F770F80134C0B259 -+:1099300004FB00F496F96635A6F8684513B1404675 -+:10994000FCF72CFD96F8EF330DF13202FF2B08BF28 -+:1099500096F8073400218DF83B30DB230393012375 -+:10996000049340460B460091019102910591FEF748 -+:109970007BFC40464946FEF74FF9404640F2716194 -+:10998000F6F744F8B6F96A3540F27161A0EBC3020C -+:1099900092B24046F6F746F84046FBF793FE11B008 -+:1099A000BDE8F08370B58E46BEF1FF3F0546144614 -+:1099B00019469DF9106002D006EB0E010DE022B9A8 -+:1099C00090F82916FFF756FD02E0B2F1FF3F04D0F0 -+:1099D00021462846FFF74EFD81192846FEF71CF95F -+:1099E00070BDC0462DE9F04F87B00446F8F7F6FB8E -+:1099F00004A981462046D4F8A850F8F73DFB20463C -+:109A0000F8F7BEFB40F2D74183462046F5F7FEFF4C -+:109A100003902046FCF74AF88246B9F1000F02D0C5 -+:109A2000FF23029304E02046F8F7B2FB40B2029015 -+:109A3000B4F8DA304FF02A0803F47043B3F5005F4E -+:109A40000CBF95F81E1595F81F1520464FB23946E4 -+:109A50000F223C23CDF80080FFF7A4FF95F8466560 -+:109A6000002E00F09080204640F2EB41F5F7CEFF4B -+:109A70001221C0F3402301222046F5F79BFF6A78AC -+:109A80000021521A18BF01220B462046FFF7F2F9B7 -+:109A90002046FBF791FE40F3072340B2A5F84A3574 -+:109AA000A5F84C0540F2EB412046F5F7AFFFC0F3B7 -+:109AB00080235B02204640F2EB414FF40072F5F741 -+:109AC000D7FF002107220B462046FFF7D3F9204697 -+:109AD000FBF772FE40F3072340B2A5F84E35A5F818 -+:109AE0005005FF222046B5F84A3540F65211F5F7E9 -+:109AF000BFFF2046FF22B5F84C3540F65311F5F76D -+:109B0000B7FF2046FF22B5F84A3540F65611F5F763 -+:109B1000AFFF2046FF22B5F84C3540F65711F5F758 -+:109B2000A7FF2046FF22B5F84E3540F64811F5F75D -+:109B30009FFFFF222046B5F8503540F64911F5F752 -+:109B400097FF95F84A3595F84C15204641EA0321D0 -+:109B5000FCF764FF95F8473520469B0240F2EB4145 -+:109B60004FF4806203F47C43F5F782FF95F84835A3 -+:109B700020465B0240F2EB414FF4007203F47E4357 -+:109B8000F5F776FF10E0204639460F223C23CDF84A -+:109B90000080FFF707FF6A7820463146003A18BF79 -+:109BA00001223346FFF766F92046F8F74FF810B167 -+:109BB0002046FBF715FE00217F220B462046FCF7CE -+:109BC000DDFC20465146FDF7C7FD20465946F8F713 -+:109BD000D1FB204604A9F8F719FC204640F2D741F2 -+:109BE000039AF5F71FFFB9F1000F04D0204649464C -+:109BF000FDF7C0FB03E020460299FEF70DF807B021 -+:109C0000BDE8F08F2DE9F04F89B00446D0F8A87078 -+:109C1000F8F7E4FA04902046F8F7BAFA4FF489719D -+:109C20005FFA80FA2046F5F767FE07210590204687 -+:109C3000F5F762FEFF2101902046F5F75DFE40F248 -+:109C40001F1102902046F5F757FE40F2AB410390FA -+:109C50002046F5F7DBFED4F8B030D3F8203183F09E -+:109C6000010313F0010B03D1E369186936F092DDAB -+:109C700000212046FDF77EFB2046F6F781FB40F2EF -+:109C80003B412046F5F7C2FE0DF1180949468046D2 -+:109C90002046F8F7F1F920460121F8F77FFB20462E -+:109CA0007F21FDF7B9FF0122134620460721F5F772 -+:109CB00081FE102213462046FF21F5F77BFE042289 -+:109CC000134640F21F112046F5F774FE2046FDF7BB -+:109CD0004FFC06224B492046F5F7DEFE2046FBF7F7 -+:109CE000E5FE002106462046FDF736FD002220460F -+:109CF0000121F7F749FA40F2AB412046F5F786FE1D -+:109D000040F23E612046F5F781FEC505ED0D2B467C -+:109D1000204640F2A64140F2FF12F5F7A9FE97F85F -+:109D2000E8330BB3204638490922F5F7B5FE002287 -+:109D300020460121F7F728FA40F2AB412046F5F71B -+:109D400065FE40F23E612046F5F760FEC30540F235 -+:109D50009A41204640F2FF12DB0DF5F789FE2046BE -+:109D60002A490922F5F798FE2B46204640F2A641E3 -+:109D700040F2FF12F5F77CFE00234FF4805220469C -+:109D800040F24C41F5F774FE20463146FDF7E4FC05 -+:109D90002046C8F38011F8F701FB20464946F8F742 -+:109DA00035FB20465146FDF737FF20460499FDF765 -+:109DB000E1FA20464FF48971059AF5F7B5FD019D4A -+:109DC000012205EA020320460721F5F7F3FD029D73 -+:109DD000102205EA02032046FF21F5F7EBFD039D63 -+:109DE0000422204640F21F1105EA0203F5F7E2FDC6 -+:109DF000BBF1000F03D1E369186936F0B7DC09B095 -+:109E0000BDE8F08FE0D80100ECD80100FED80100D9 -+:109E10002DE9F3410446F8F7E1F9E369D4F8A850D5 -+:109E20001B6A0026C4F8F03F94F8DA30804685F8C3 -+:109E3000BC32D4F8B03084F8F46FD3F8203183F01A -+:109E4000010313F001070AD1E369B821186942F24E -+:109E5000107236F06DDCE369186936F09BDC204641 -+:109E60000121F9F7B5FE0F2223492046F5F714FE2C -+:109E70002046F8F779FD20463146FCF7CFFD204615 -+:109E800031463246FDF738F82046F6F779FA41F2C6 -+:109E90001403E35C6BB12046FFF7B4FE2046314665 -+:109EA000FDF750F995F8E8331BB120460121FDF785 -+:109EB00049F92046FFF796FD00217F230A460093CB -+:109EC00020460123FDF7C8FF4FF0FF3385F8073424 -+:109ED00085F808342046FFF739FB20464146FDF758 -+:109EE00049FA20460021F9F773FE1FB9E3691869A2 -+:109EF00036F03CDCBDE8FC819CD90100082910B596 -+:109F000003D00A2904D0022904D1FFF781FF01E020 -+:109F1000FEF796FD10BDC04610B50446F6F730FAC0 -+:109F200020460021FDF726FA20460821FFF7E6FF2C -+:109F300010BDC04670B590F8F43F0446D0F8A85064 -+:109F400013B9F7F713FFE8B1D4F8F83013F0070F9F -+:109F500006D194F8F5301BB920460921FFF7CEFF52 -+:109F6000D4F8F82012F00F0F0CD194F9FC3F4BB944 -+:109F700012F0800F06D194F8F5301BB9204602216B -+:109F8000FFF7BCFFD4F8F83013F00E0F02D12046D3 -+:109F9000F9F758F9D4F8F83013F0060F3ED1D5F898 -+:109FA000340448B3E169D5F838240B6A9B1A83421C -+:109FB00034D308696A2136F09DDB400081B2B1B12B -+:109FC000E369186936F096DB88B940F2764120469D -+:109FD000F5F71CFDC005C00DA5F86C0540F27741F2 -+:109FE0002046F5F713FDC005C00DA5F86E05204607 -+:109FF0000021F9F751FF11E040F276412046F5F7D4 -+:10A0000005FDC005C00DA5F86C0540F2774120465E -+:10A01000F5F7FCFCC005C00DA5F86E052046F8F765 -+:10A02000DDF8B0F5404F0CD02046F8F7B1F8C0B2DB -+:10A0300020B100237F2885F8563402D0002385F80C -+:10A04000573470BD2DE9F047CCB20746D0F8A86070 -+:10A0500020468946F5F7ECFE494680463846F5F736 -+:10A06000C9FE3846B7F8DA10FBF75AF90422384629 -+:10A070005B49F5F711FD21463846FAF7BBF90A208E -+:10A08000ECF36AF34FF4004213464FF4896138460B -+:10A09000F5F7EEFC3846F8F793FB052100224FEA6E -+:10A0A0004800F7F7B9FC0022054641464FF420105E -+:10A0B000F7F7B2FC40F257610446AAB23846F5F70A -+:10A0C000B1FC38464FF4CB61A2B2F5F7ABFC4FF4CC -+:10A0D000007338464FF489614FF44072F5F7C8FCBD -+:10A0E00097F8DA300E2B01D11E2206E0B6F8622076 -+:10A0F00013B2B3F1FF3F08BF1522A6F8402538463A -+:10A10000002112B2FBF7E6FB20B1384600211422F1 -+:10A11000FBF7E0FB97F8DA3038220E2B0CBF182340 -+:10A120000023384640F2EB41F5F7A2FCB7F8DA30ED -+:10A13000384603F47043B3F5005F0CBFB6F86620F1 -+:10A14000B6F86820012113B2B3F1FF3F08BF022225 -+:10A15000A6F83E2512B2FBF7BDFB1822384621496E -+:10A16000F5F79AFC3846F6F71BF996F8BC2298B139 -+:10A170000E2AB7F8DA3003D9DBB20E2B03D805E08C -+:10A18000DBB20E2B02D83846012101E0384600210F -+:10A190004A46FCF7A5FF21E097F8DA309A4201D150 -+:10A1A000012A04D138460821FFF7A8FE02E038460C -+:10A1B000FCF77AFF00210A463846FBF757FD384680 -+:10A1C000F9F7BCF938460121F9F770FA41F21403A6 -+:10A1D000FB5C1BB138460321FBF70EF9BDE8F087A5 -+:10A1E0008CD60100A6D40100D0F8B03073B5D3F8F6 -+:10A1F0002031044683F0010313F00106D0F8A85083 -+:10A2000003D1C369186936F0C5DA41F21403E25C80 -+:10A2100042BBB4F8DA3003F47043B3F5005F08D101 -+:10A220004FF00403ADF800304FF00C03ADF80230EE -+:10A2300007E04FF0FF03ADF80030ADF802304FF00B -+:10A24000F00320466946ADF80430ADF80620F8F773 -+:10A25000DDF820469621FDF77FFA20460121FEF722 -+:10A26000C1FC56E02046FFF7CDFC2046FDF75AF82A -+:10A2700020460021FCF766FF204635490F22F5F7FE -+:10A280000BFC95F8E833DBB120460121FCF75AFFBF -+:10A2900095F92435204640F2D141FF229BB2F5F7D3 -+:10A2A000E7FB95F82535204640F2D1414FF47F4237 -+:10A2B0001B02F5F7DDFB204626490C22F5F7ECFBE7 -+:10A2C000052220462449F5F7E7FBD4F8A8202046CC -+:10A2D000D2F84434D2F848243C2BA8BF3C23934204 -+:10A2E000B8BF134640F2A741FF229BB2F5F7C0FB6F -+:10A2F000B4F8DA30204603F47043B3F5005F0CBFC6 -+:10A3000095F8543495F855344FF440412B86FDF7B9 -+:10A3100031F840F276412046F5F778FBC005C00DD4 -+:10A32000A5F86C0540F277412046F5F76FFBD5F8AC -+:10A330003434C005C00DA5F86E051BB120460121BF -+:10A34000F9F7AAFD1EB9E369186936F00FDA7CBD8A -+:10A3500072DA010090DA0100A8DA01002DE9F0417B -+:10A36000D0F8A860012386F86130013B86F8C0333D -+:10A37000B0F8DA30074603F47043B3F5005F02D15A -+:10A3800096F8C13304E0B3F5805F06D196F8C23386 -+:10A39000022B02D1012386F8C033B7F8DA303846F1 -+:10A3A00003F47043B3F5805F0CBF96F8EB3396F877 -+:10A3B000EA33002486F8E933738B0125A6F8BE3210 -+:10A3C00004222349347086F8C24286F8C34286F8D4 -+:10A3D000C44286F86755F5F75FFB38462946F8F71B -+:10A3E00027FA04221B493846F5F756FB3846FCF796 -+:10A3F000A5FA3846FCF7E0FC3846FFF7F5FE86F88C -+:10A400002C40B7F8DA103846F6F790FD3846FBF7DF -+:10A4100069F84FF4804213464FF489613846F5F7E6 -+:10A4200027FB6420ECF398F1234638464FF489610A -+:10A430004FF48042F5F71CFB38464FF44041FCF7DF -+:10A4400099FF41F28833F38686F89A55BDE8F0818A -+:10A450003EDD010046DD010010B58068F5F310F126 -+:10A4600010BDC04610B5437902790C4642EA032E6E -+:10A470000EF00303012B0AD0022B0ED013B14FF4C0 -+:10A4800000702EE00A780523B2FBF3F029E00B7888 -+:10A49000144A03F00703D05C23E00978E3782279BB -+:10A4A00011F0800F43EA022201F07F0343F00060C5 -+:10A4B00002D040F4806006E01EF0200F1CBF20F4A4 -+:10A4C000E06343F4407012F0800F18BF40F40000C6 -+:10A4D00012F0400F18BF40F48000C2F3011340EAAD -+:10A4E000035010BD54CC010070B585680446D4F803 -+:10A4F000F811A868F5F3B2F04FF0FF3384F8E231B9 -+:10A50000A361236800229A712B6B06460221186909 -+:10A51000F5F740FC204639F0B5DBD6F1010038BF35 -+:10A52000002070BD70B50D460968044671B1D1F8C0 -+:10A530007C1129B1036840F20C72D868ECF3D8F3AF -+:10A5400023682968D8686269ECF3D2F32368294646 -+:10A55000D8681022ECF3CCF370BDC04637B5054681 -+:10A5600001A9D0F800053AF0B5DD09E028462146FA -+:10A570003BF010D8636C1BB9284621463BF020D92C -+:10A5800001A83AF0AFDD04460028EFD13EBDC04639 -+:10A59000036870B510210546D868ECF399F308B943 -+:10A5A000064615E02B6806466969D868ECF390F317 -+:10A5B0000446306028B931462846FFF7B3FF2646E7 -+:10A5C00006E00023C0F87C31314628463AF062DCD0 -+:10A5D000304670BD2DE9F3470D469246002853D012 -+:10A5E000002951D00B88D0F80490D0F89843D0F8C7 -+:10A5F0009463002B4BD00027E780A7804B880A8804 -+:10A6000013F0010824D0402A14D1043120463B46DF -+:10A6100000973EF081DEB8423BDBB6F8023113F022 -+:10A62000400F34D0BAF1000F31D0D9F80C003DF012 -+:10A6300015DE0BE0A2F108039BB2372B29D804F1F9 -+:10A6400008000431E7F398F42D88A580384622E00D -+:10A65000202A19D8043104F14800E7F38DF4A4F856 -+:10A6600004802D880123E580C6F8CC30B6F802318D -+:10A6700013F0400F0BD0BAF1000F08D0D9F80C003E -+:10A680003DF0ECDD404606E06FF0010003E0002005 -+:10A6900001E04FF0FF30BDE8FC87C04610B50DF07B -+:10A6A0002DFA0446F0F714FA2046EBF363F610BDDA -+:10A6B000AAAA03001958000040960000904C000020 -+:10A6C00014720000101800000FAC000050F20000DF -+:10A6D00050F201000050F20200000050F2020100AE -+:10A6E000AAAA0300195800000000000050F204005C -+:10A6F00000147200000FAC000050F20000101800AF -+:10A700000050F200000FAC00004096000000000076 -+:10A710000000101800696C306D6163616464723D03 -+:10A7200030303A31313A32323A33333A34343A35DE -+:10A730003500626F617264747970653D3078666669 -+:10A74000666600626F6172647265763D30783130A2 -+:10A7500000626F617264666C6167733D38006161AD -+:10A76000303D330073726F6D7265763D3200000FBD -+:10A77000AC000050F2000000594D80009557800059 -+:10A7800049588000315680000D5A8000C158800021 -+:10A79000295A8000455A8000795780004D56800024 -+:10A7A000755A800025558000F15980000D588000B1 -+:10A7B00069548000C14E8000E951800055528000EC -+:10A7C000C9518000DD58800051518000D155800072 -+:10A7D000A555800015568000E14F80008955800006 -+:10A7E000FD4E80002550800061EC0000ED4D8000A2 -+:10A7F000854E8000A94F8000D94D8000094E800011 -+:10A80000514C8000654C80000000000000000000FA -+:10A8100000000000C14F800025528000F9518000E7 -+:10A82000FD2700002800000073645F6C6576656C8E -+:10A830005F74726967676572007370695F70755FD6 -+:10A84000656E6162006172705F6D61636164647204 -+:10A85000006172705F72656D6F74656970000000F1 -+:10A86000F83B86000000000007000000FF3B860068 -+:10A8700001000000070000000B3C86000200000001 -+:10A88000000000001B3C86000300000007000000E1 -+:10A89000263C86000400000000000000373C8600D3 -+:10A8A0000500000008003000413C86000600000062 -+:10A8B0000000000045A8010008000000060000009C -+:10A8C00051A801000900000007000000000000007E -+:10A8D00000000000000000000200000000005C78A2 -+:10A8E0002530325800253034780A00747863686166 -+:10A8F000696E007278636861696E0025733A206240 -+:10A900007373636667206973206E756C6C210A002F -+:10A91000776C635F696F766172733200727373690B -+:10A920005F6F66667365740064796E74785F7164D6 -+:10A93000626D5F6F766572726964650064796E74CA -+:10A94000785F726174655F616C6C00505A443A20A4 -+:10A9500025643E2564206F722025643E25642061B5 -+:10A960003D25640A006F747077006164640064655B -+:10A970006C006C6F775F727373695F74726967677D -+:10A980006572006C6F775F727373695F6475726173 -+:10A9900074696F6E0074635F656E61626C650074EC -+:10A9A000635F706572696F640074635F68695F7785 -+:10A9B0006D0074635F6C6F5F776D0074635F7374B9 -+:10A9C00061747573006173736F635F737461746531 -+:10A9D0000064796E74780074785F737461745F6377 -+:10A9E000686B0074785F737461745F63686B5F7029 -+:10A9F00072640074785F737461745F63686B5F7214 -+:10AA00006174696F0074785F737461745F63686BFD -+:10AA10005F6E756D0072785F726174650069735F57 -+:10AA20005750535F656E726F6C6C65650069735F3C -+:10AA30007770735F656E726F6C6C656500676574C7 -+:10AA4000736E72001CA901000100000006000000E6 -+:10AA500072A90100020000000600000083A90100A5 -+:10AA6000030000000600000095A90100040000009A -+:10AA7000060000009FA9010005000000060000007C -+:10AA8000A9A901000600000006000000B2A901000B -+:10AA90000700000006000000BBA90100080000003C -+:10AAA00006000000C5A90100090000000600000022 -+:10AAB000D1A901000A00000006000000D7A901008A -+:10AAC0000B00000006000000E3A901000C000000DC -+:10AAD00006000000F3A901000D00000006000000C0 -+:10AAE00005AA01000E0000000600000015AA0100E2 -+:10AAF0000F000000060000001DAA01001000000069 -+:10AB0000010000002DAA010010000000010000005B -+:10AB10003DAA010011000000060000000000000036 -+:10AB2000000000000000000005A58100FDA58100D7 -+:10AB30000000000000000000010005060000000009 -+:10AB40000DCD820089E68200F5CB8200EDCC82003B -+:10AB5000678986000000800001000000458B8600A8 -+:10AB600001000000080002004F8B86001D0000005D -+:10AB7000080002005C8B86000F000000030000004C -+:10AB80006A8B860010008000070000007A8B860028 -+:10AB900002000000080007008B8B86000300000005 -+:10ABA000080007009C8B8600040080000100000064 -+:10ABB000AE8B86000600000002000000B98B860004 -+:10ABC0000C00000002000000C88B860021008000FD -+:10ABD0000300000000000000000000000000000072 -+:10ABE000776C25643A20776C635F616D7064755F84 -+:10ABF00072656C656173653A2063616E6E6F742077 -+:10AC000072656C6561736520256420286F757420FA -+:10AC10006F662077696E646F77290A0025733A2082 -+:10AC2000776C20646F776E210A0025733A20776C69 -+:10AC3000207570210A00776C635F616D7064755FC9 -+:10AC40007265737461727400D6AD0100100000006B -+:10AC500006000000529B8600010000000100000079 -+:10AC60005D9B860002002000070000006F9B8600AD -+:10AC700003004000080007007C9B860004004000A1 -+:10AC8000080004008B9B86000500400008000400BB -+:10AC90009A9B86000600000008000400D9AD010060 -+:10ACA0000D00100007000000A79B86000E0020008A -+:10ACB00007000000B49B860007001000070000009A -+:10ACC000BF9B86000800000008001000E2AD0100F4 -+:10ACD0000900000006000000C99B86002400000057 -+:10ACE00006000000E6AD01000A00000006000000BA -+:10ACF000AB7286000F00000001000000D59B8600AB -+:10AD00000B00800001000000DA9B86000C000000B0 -+:10AD100005000000E59B86001D0000000300000008 -+:10AD2000FA9B86001E00000007000000139C8600AE -+:10AD30001F00000007000000259C86002100000085 -+:10AD4000050000003B9C860020000000030000007E -+:10AD5000499C860011008000010000004F9C860085 -+:10AD60001800400008000600539C860019000000EF -+:10AD700005000000619C86001A0000000100000030 -+:10AD80006C9C86001B0040000100000000000000D9 -+:10AD900000000000000000000050F202010100006D -+:10ADA0000364000027A4000041435E0061322F00CD -+:10ADB00073656E74206F7574205052554E45204552 -+:10ADC00056454E5420657863656564206D617861F1 -+:10ADD00073736F630A006170006D61786173736FE4 -+:10ADE000630062737300737369640000D55083005D -+:10ADF000215783000000000000000000776C2564EC -+:10AE00003A205048595458206572726F7228256450 -+:10AE1000290A00092F160E0E0500000091BA8600BF -+:10AE2000000080000100000030BB8600020000002E -+:10AE3000080044003ABB86000300000008004400FC -+:10AE400044BB860004000000080000004FBB8600E1 -+:10AE5000050000000800440059BB86000600000001 -+:10AE60000800000067BB86000700000008004C00D7 -+:10AE700074BB86000800000008004C0081BB8600FF -+:10AE80000900800002000000000000000000000037 -+:10AE900000000000C8E686000000000008000C006A -+:10AEA000D7E686000100000007000400E9E68600FE -+:10AEB0000200000008000800FBE686000300000016 -+:10AEC000070004000BE786000400000008001C00D7 -+:10AED0001BE786000500000008000C002CE7860038 -+:10AEE000060000000700040043E78600070000009A -+:10AEF0000700040024AF0100080000000700040060 -+:10AF000034AF0100090000000700040048AF010051 -+:10AF10000A0000000800900000000000000000008F -+:10AF200000000000706B745F66696C7465725F6925 -+:10AF3000636D7000706B745F66696C7465725F69D5 -+:10AF4000636D705F636E740077616B655F706163E2 -+:10AF50006B65740053657420425250542061742014 -+:10AF600025780A000A465749442030312D25780AB1 -+:10AF7000000A54524150202578282578293A20701B -+:10AF8000632025782C206C722025782C207370206B -+:10AF900025782C207073722025782C20787073729D -+:10AFA0002025780A00202072302025782C2072314C -+:10AFB0002025782C2072322025782C2072332025F1 -+:10AFC000782C2072342025782C2072352025782C7E -+:10AFD0002072362025780A00202072372025782C10 -+:10AFE0002072382025782C2072392025782C207268 -+:10AFF00031302025782C207231312025782C207298 -+:10B0000031322025780A000A20202073702B30204E -+:10B01000253038782025303878202530387820259C -+:10B020003038780A00202073702B313020253038DA -+:10B030007820253038782025303878202530387829 -+:10B040000A0073702B257820253038780A00646553 -+:10B0500061646D616E5F746F007265636C61696DD0 -+:10B060002073656374696F6E20313A205265747580 -+:10B07000726E656420256420627974657320746F34 -+:10B080002074686520686561700A007265636C6190 -+:10B09000696D2073656374696F6E20303A20526564 -+:10B0A0007475726E656420256420627974657320FE -+:10B0B000746F2074686520686561700A0072616D44 -+:10B0C0007374627964697300706125643D3078251A -+:10B0D000257800706425643D3078252578006E76EB -+:10B0E00072616D5F6F766572726964650000000061 -+:10B0F00086060200D0090000800602003E3E0000E5 -+:10B10000820602003E020000000702003C00000030 -+:10B110008406020012020000600104000300010026 -+:10B1200064010200C000000060010400030001008F -+:10B13000660102000A000000600104000400010032 -+:10B140006401020014000000600104000700010017 -+:10B150006401020083010000600104002500010079 -+:10B1600064010200F4010000600104009605010082 -+:10B17000660102002B040000600104009705010035 -+:10B18000640102000001000060010400D701010019 -+:10B19000640102003C00000060010400DC010100C9 -+:10B1A000660102003400000060010400E2010100B9 -+:10B1B000640102003000000060010400E7010100AA -+:10B1C000660102002C00000060010400ED01010096 -+:10B1D000640102002C00000060010400F201010083 -+:10B1E000660102002800000060010400F80101006F -+:10B1F000640102002800000060010400FD0101005C -+:10B200006601020028000000FFFF000000000000AF -+:10B21000600104000500010364010400000019003E -+:10B2200024010400040000002801040000000000C4 -+:10B230002C010400000000003001040000000000A8 -+:10B24000340104000A04700034010400EFBED4008D -+:10B2500034010400050000FF3401040001FF02FF77 -+:10B260003001040018000000340104000A04E0006A -+:10B2700034010400EFBE480034010400050000FF63 -+:10B280003401040001FF02FF340104000010180122 -+:10B2900034010400020300103401040018F1F2F339 -+:10B2A00034010400BBCC000030010400680600003B -+:10B2B000340104001404700034010400EFBE58018E -+:10B2C00034010400000000FF3401040001FF02FF0C -+:10B2D00034010400001018013401040002030309C2 -+:10B2E00034010400BF00001034010400000000001D -+:10B2F00030010400380000003401040000000000A8 -+:10B3000030010400880600003401040014048000A9 -+:10B3100034010400EFBE18023401040000000309E8 -+:10B3200034010400BF0000033401040000010203E3 -+:10B330003401040004050001340104000203040583 -+:10B340003401040000000000300104005800000037 -+:10B350003401040000000000300104003800000047 -+:10B36000340104000F2000073401040000009400A1 -+:10B3700034010400000000903401040074757677F5 -+:10B380003401040000000000340104000000050046 -+:10B3900034010400FFFFFFFF3001040068020000D9 -+:10B3A000340104006E84330034010400DCBA500020 -+:10B3B00034010400D40000AB34010400BADABADA74 -+:10B3C00034010400001018F134010400F2F30010FD -+:10B3D0003401040018F1F2F33401040010000000FD -+:10B3E00034010400000000003401040000000A00E1 -+:10B3F000340104000100000E340104004252434DA8 -+:10B40000340104005F54455334010400545F535326 -+:10B4100034010400494401043401040082848B9601 -+:10B42000340104000301010634010400020000009D -+:10B430003001040068000000340104000A042802FE -+:10B4400034010400DCBA8000340104000000FFFF76 -+:10B4500034010400FFFFFFFF34010400001018F165 -+:10B4600034010400F2F300103401040018F1F2F387 -+:10B4700034010400D0AF00003401040000000000DB -+:10B480003401040000000001340104000200000E39 -+:10B49000340104004252434D340104005F544553CB -+:10B4A00034010400545F535334010400494401043F -+:10B4B0003401040082848B963401040003010106E8 -+:10B4C000340104000201000030010400680400009F -+:10B4D000340104000A04280234010400DCBA8000AC -+:10B4E000340104000000FFFF34010400FFFFFFFFF0 -+:10B4F00034010400001018F134010400F2F30010CC -+:10B500003401040018F1F2F334010400D0AF00005C -+:10B5100034010400000000003401040000000001B8 -+:10B52000340104000200000E340104004252434D75 -+:10B53000340104005F54455334010400545F5353F5 -+:10B5400034010400494401043401040082848B96D0 -+:10B55000340104000301010634010400020100006B -+:10B56000000104000000000190040200000000003F -+:10B57000A0040200F1F30000B0040200EFFD00009F -+:10B58000A8040200FFFF0000A80402000000000061 -+:10B59000AA04020000000000A4040200CF1A000068 -+:10B5A000AC04020000000000BC0402000000000027 -+:10B5B000A6040200D7020000B6040200FFFD00004E -+:10B5C000AE040200FFFF00000604020001000000BC -+:10B5D00006040200000000000C0402001800000035 -+:10B5E000060402000000000048040200000C0000F5 -+:10B5F00002040200A0070000020502000000000093 -+:10B6000000050200004000000205020004000000E6 -+:10B6100000050200004000000205020008000000D2 -+:10B620000005020000400000020502000C000000BE -+:10B63000000502000040000002050200C0000000FA -+:10B6400080050200FFFF000082050200FFFF0000EE -+:10B6500084050200FFFF000086050200FFFF0000D6 -+:10B6600088050200FFFF00009C050200F0FF0000BB -+:10B67000400502000080000020050200060F0000C7 -+:10B68000400502000080000040050200008100002B -+:10B6900020050200101D000040050200008100008E -+:10B6A0004005020000820000200502001E28000064 -+:10B6B00040050200008200004005020000830000F7 -+:10B6C000200502002931000040050200008300002F -+:10B6D000400502000084000020050200323F000007 -+:10B6E00040050200008400004005020000850000C3 -+:10B6F00020050200404100004005020000850000D6 -+:10B7000012060200010000002E060200CDCC00004F -+:10B71000300602000C000000000602000480000059 -+:10B7200096060200080000009A060200E4000000ED -+:10B7300088060200000000009C06020002000000D3 -+:10B7400088060200001000009C06020002000000B3 -+:10B7500088060200002000009C0602000200000093 -+:10B7600088060200003000009C0602000200000073 -+:10B77000880602000B0F00009E0602000700000072 -+:10B78000100502000B00000050040200014E0000F2 -+:10B79000520402005B010000E4040200900000007B -+:10B7A00004040200B400000054050200FF3F000042 -+:10B7B00060010400040001036401040000000000B3 -+:10B7C00064010400B4000000640104004700470065 -+:10B7D00064010400000064006401040030094000BA -+:10B7E000600104000D000103640104000200020076 -+:10B7F00064010400010080006401040005000000F1 -+:10B80000640104000000800064010400640064001E -+:10B81000640104000E0047006401040000050000FC -+:10B8200060010400150001036401040000004208E7 -+:10B8300064010400E00B0700640104000A0000003A -+:10B84000600104001A0001036401040000C0660BDB -+:10B85000600104001D0001036401040010270000C2 -+:10B860006401040000007A03600104002000010369 -+:10B870006401040006001027600104002300010396 -+:10B88000640104000000F606640104000000AA0A36 -+:10B890006401040000003200640104000A0E0B0978 -+:10B8A000640104000E020000640104000000520A5A -+:10B8B0006401040000003F0164010400FFFF000C6C -+:10B8C0006401040032046E06640104000200F209FF -+:10B8D000600104002E0001036401040000000080E8 -+:10B8E0006001040032000103640104000000320B17 -+:10B8F0006001040034000103640104000000CC0571 -+:10B900006001040058000103640104004252434DE9 -+:10B91000640104005F54455364010400545F5353B1 -+:10B920006401040049440000600104006000010358 -+:10B9300064010400390000006401040050000000AC -+:10B9400064010400C00000006001040070000103F5 -+:10B9500064010400AA03AA0364010400AA03AA0361 -+:10B9600064010400AA03AA0364010400AA03AA0351 -+:10B9700064010400EC03D60364010400C003AA03BD -+:10B9800064010400F703E10364010400CB03B50381 -+:10B9900064010400AA03AA0364010400AA03AA0321 -+:10B9A00064010400AA03AA0364010400AA03AA0311 -+:10B9B00064010400EC03D60364010400C003AA037D -+:10B9C00064010400F703E10364010400CB03B50341 -+:10B9D000640104000204020464010400020402047D -+:10B9E000640104000E0402046401040002041A0449 -+:10B9F000640104000204020464010400020402045D -+:10BA00006401040002040204640104002604020428 -+:10BA1000640104000204020464010400020402043C -+:10BA2000640104000E0402046401040002041A0408 -+:10BA3000640104000204020464010400020402041C -+:10BA400064010400020402046401040026040204E8 -+:10BA50006401040000001F0064010400FF031F00D4 -+:10BA60006401040002000000640104000200000000 -+:10BA700060010400980001036401040000001F003D -+:10BA800064010400FF031F006401040001000000C2 -+:10BA9000640104000100000060010400A000010333 -+:10BAA0006401040000001F0064010400FF031F0084 -+:10BAB00064010400010000006401040001000000B2 -+:10BAC00060010400A80001036401040000001F00DD -+:10BAD00064010400FF031F00640104000100000072 -+:10BAE000640104000100000060010400B8000103CB -+:10BAF00064010400E700EC006401040000007B0026 -+:10BB0000640104007E0000006401040000000000E5 -+:10BB10006401040000004F51640104003F00000074 -+:10BB2000640104000000001060010400C000010373 -+:10BB300064010400372437246401040037243724C7 -+:10BB40006001040093010103640104000F00400040 -+:10BB500064010400E606000060010400970101038F -+:10BB6000640104001A08000060010400A001010340 -+:10BB700064010400FFFFFFFF64010400FFFFFFFFFB -+:10BB800064010400FFFFFFFF64010400FFFFFFFFEB -+:10BB900064010400FFFFFFFF64010400FFFFFFFFDB -+:10BBA00064010400FFFFFFFF64010400FFFFFFFFCB -+:10BBB00060010400BC0101036401040000000500F1 -+:10BBC00060010400C50101036401040000001003CA -+:10BBD00064010400E000FFFF640104000309BF00EA -+:10BBE000640104000000030964010400BF000010A8 -+:10BBF000640104000309BF006401040000030000A5 -+:10BC000060010400CD01010364010400FFFFFFFF98 -+:10BC100064010400FFFFFFFF64010400FFFFFFFF5A -+:10BC200064010400FFFFFFFF64010400FFFFFFFF4A -+:10BC300064010400FFFFFFFF64010400FFFFFFFF3A -+:10BC400064010400FFFFFFFF640104002000CB013A -+:10BC50006401040000005400640104000000AB080B -+:10BC60006401040000001004640104008400020068 -+:10BC7000640104000000140064010400CF0102000C -+:10BC8000640104004400000064010400AF080200E5 -+:10BC90006401040010046400640104000202000056 -+:10BCA000640104001000CA016401040002003C00A9 -+:10BCB000640104000000AA086401040002001004EA -+:10BCC000640104005400020864010400000008003C -+:10BCD00064010400CE01000064010400340000008F -+:10BCE00064010400AE080000640104001004440074 -+:10BCF00064010400020A0000640104000800C90194 -+:10BD00006401040002003000640104000000A9087E -+:10BD10006401040002001004640104003C000210ED -+:10BD2000640104000000040064010400CD0100006F -+:10BD3000640104002C00000064010400AD08000050 -+:10BD400064010400100434006401040002120000C5 -+:10BD5000640104000400C8016401040000002C0018 -+:10BD6000640104000000A80864010400000010043D -+:10BD700064010400300002196401040000000000A6 -+:10BD800064010400CC010200640104002C000000E6 -+:10BD900064010400AC0802006401040010043000D7 -+:10BDA00064010400021A000064010400C0000A04D7 -+:10BDB0006401040070000000640104003A010A04F8 -+:10BDC0006401040028022CC064010400F2020A0489 -+:10BDD0006401040000000001640104006000140418 -+:10BDE000640104003800000064010400020114042E -+:10BDF0006401040014012CC064010400DE01140479 -+:10BE00006401040000008000640104002200370483 -+:10BE1000640104001500000064010400DF00370421 -+:10BE20006401040065002CC0640104002E01370485 -+:10BE30006401040000002F006401040011006E84FE -+:10BE4000640104000B00000064010400D4006E844F -+:10BE50006401040033002CC064010400FC006E8403 -+:10BE600064010400000018006401040002008A9DBF -+:10BE700064010400FB00020864010400C54EFA00DE -+:10BE800064010400020A833464010400FE0002100D -+:10BE9000640104006227F900640104000212421ADE -+:10BEA00064010400FD00021964010400B113F800EC -+:10BEB00064010400021A811164010400FC00021CE8 -+:10BEC00064010400C10FFC00600104007B03010356 -+:10BED0006401040007001400640104001E00000057 -+:10BEE000600104008303010364010400000000F00A -+:10BEF00064010400C33010926401040050318022B8 -+:10BF000064010400C33000006001040088030103E1 -+:10BF10006401040000001004600104008C030103AC -+:10BF20006401040080000000600104008E0301032E -+:10BF30006401040005000000600104000B0401031B -+:10BF400064010400000007026001040014040103FE -+:10BF500064010400010000006001040016040103F4 -+:10BF6000640104000C00000060010400530501039B -+:10BF7000640104000000180060010400550501037D -+:10BF800064010400983A983A64010400A60E640023 -+:10BF9000640104000000F4016401040005000000D5 -+:10BFA00064010400A861A8616401040030751E00EA -+:10BFB000600104005D0501036401040050C300003A -+:10BFC000600104005F050103640104000000140522 -+:10BFD0006401040050C30000600104006305010314 -+:10BFE00064010400204E00006401040000000F0002 -+:10BFF00064010400F4010400600104006905010308 -+:10C00000640104000000310064010400000003002A -+:10C01000640104000100070064010400C8AF0000CF -+:10C020006401040088130000640104002C17FF0061 -+:10C0300060010400700501036401040000002C018C -+:10C04000640104000000A00F6001040073050103F7 -+:10C0500064010400000003006401040000002C01DE -+:10C0600064010400C00000006401040088130000A3 -+:10C07000640104006400000064010400DC05401F4A -+:10C08000600104007A05010364010400010001005D -+:10C090006401040002000000600104007D0501034A -+:10C0A0006401040002000000640104000000409CE0 -+:10C0B00064010400204E000064010400B80B00007D -+:10C0C0006001040082050103640104000000204EA9 -+:10C0D000640104000000050064010400DC053F0069 -+:10C0E0006401040071020000640104003075000066 -+:10C0F000600104008A05010364010400C409A00F63 -+:10C10000600104008D050103640104000A00D007EA -+:10C11000600104008F05010364010400204E204EDD -+:10C12000600104009505010364010400BE000000E5 -+:10C1300060010400B105010364010400E80300008C -+:10C1400060010400ED05010364010400000000002B -+:10C1500060010400F6050103640104008813000077 -+:10C160006001040003000200640104001F000000DD -+:10C17000600104000400020064010400FF030000E9 -+:10C180006001040005000200640104001F000000BB -+:10C1900060010400060002006401040007000000C2 -+:10C1A00060010400070002006401040004000000B4 -+:10C1B000600104000800020064010400FFFF0000A9 -+:10C1C0006001040009000200640104000000000096 -+:10C1D000600104000A000200640104000000000085 -+:10C1E000600104000B000200640104000000000074 -+:10C1F000600104000C000200640104000000000063 -+:10C20000600104000D000200640104000000000051 -+:10C21000600104000E000200640104000000000040 -+:10C22000600104000F00020064010400000000002F -+:10C230006001040010000200640104001F000000FF -+:10C24000600104001100020064010400000000000D -+:10C2500060010400120002006401040000000000FC -+:10C2600060010400130002006401040000000000EB -+:10C2700060010400150002006401040000000000D9 -+:10C2800060010400160002006401040000000000C8 -+:10C29000FFFF000000000000636275636B5F73774F -+:10C2A0006672657100000000E02E0101015000007F -+:10C2B00000000000C832020101490000899DD80039 -+:10C2C0004038030101420000AAAAAA00003C040170 -+:10C2D000013E000000008000483F050101390000D8 -+:10C2E000D05E4200A04106010139000049922400BD -+:10C2F000004B07010132000000000000584D08010A -+:10C3000001300000071F7C00204E090101300000B1 -+:10C3100000000000A8610A010126000066666600B0 -+:10C3200090650B0101240000C44EEC0030750C0137 -+:10C33000012000000000000018920D0201330000EF -+:10C34000F93E560000960E02013200000000000087 -+:10C35000409C0F02013000000000000080BB100272 -+:10C3600001280000000000000000000000000000A4 -+:10C370000000000099C30100000000000800080050 -+:10C3800098C301000100000008000B00000000003D -+:10C3900000000000000000006D6B6565705F616C5F -+:10C3A00069766500352E39302E3139352E32362EEC -+:10C3B0003300776C25643A20257320257320766539 -+:10C3C0007273696F6E2025732046574944203031BF -+:10C3D0002D25780A00417567203133203230313203 -+:10C3E0000031393A31303A3436000000DA43860001 -+:10C3F0000000000008000000E34386000100000088 -+:10C40000010000000000000000000000000000002B -+:10C41000746F655F6F6C00746F655F7374617473C4 -+:10C4200000746F655F73746174735F636C656172D0 -+:10C4300000AAAA030000000010C4010000000000D0 -+:10C440000700000017C401000100000008004C00B4 -+:10C4500021C40100020000000000000000000000F4 -+:10C460000000000000000000D58D86000C00800058 -+:10C4700001000000A98E86000B00000001000000F2 -+:10C48000B58E86000300000005000000C18E860006 -+:10C490000400000007000000D08E86000500800028 -+:10C4A000010000000000000000000000000000008B -+:10C4B0005B574C414E5D636F756E74203D20256463 -+:10C4C0000A00496E697420436F756E746572004787 -+:10C4D000726F7570206B657920657870616E736915 -+:10C4E0006F6E0061757468000000000000000000BD -+:10C4F00000000000627461006274616D700062741B -+:10C50000616D705F666C616773006274616D705F0E -+:10C510006368616E006274616D705F31316E5F736C -+:10C520007570706F7274006274616D705F66620026 -+:10C530006274616D705F73746174656C6F670041E4 -+:10C540004D502D253032782D253032782D25303242 -+:10C55000782D253032782D253032782D25303278DF -+:10C5600000545454545400000000000000000050D7 -+:10C570005050505000000000000000000023000058 -+:10C580000300000000084C4C4C4C4C4C141414009C -+:10C5900000010000646464646464646464646464EA -+:10C5A0006400000000000000000000000000000027 -+:10C5B000013C4242424242424242423C00000000B0 -+:10C5C0000000000000000000000000000000344AED -+:10C5D0004E4E4E4E4E4E4E4A3800000000000000B7 -+:10C5E00000000000000000000000004C4C4C4C4CCF -+:10C5F0004C4C4C4C4C4C4C4C00000040404040409B -+:10C600004040000000000001030000000001424221 -+:10C6100042324242141414000000000003000000E3 -+:10C6200000013E3E42343E4214141400000000005B -+:10C6300054545400540000000000000000000000AA -+:10C6400000000000000000000000000023000000C7 -+:10C650000300000000014444443844401414140012 -+:10C6600000000000484A4A4A4A4A4A4A4A4A4A4A54 -+:10C67000480000003434343434343434340000009E -+:10C68000004E4E4E4E4E4E4E4E4E4E4E4E4E0000B4 -+:10C6900000000000000000000000000000085454EA -+:10C6A00054005400000000000000000050505000F2 -+:10C6B00050000000000000000000233A3E38004215 -+:10C6C000000000000000000000000000000000006A -+:10C6D000000000000000000A0000000064000000EC -+:10C6E00000000000000000000000580000000000F2 -+:10C6F0000000000001364444444444444444443669 -+:10C700004A4000000000000000000000000000009F -+:10C7100000082E4444444444444444442E463A00D1 -+:10C720000000000000000000000000000000083CC5 -+:10C730003E3E3E3E3E3E3E3E3E3C3E3E0000000013 -+:10C7400000000000000000000000000834444444E1 -+:10C750004444444444443844400000000000000085 -+:10C760000000000000000000085C5C5C5C5C5C5C3D -+:10C770005C5C5C5C5C5C0000505050505050505011 -+:10C78000500000000001383E383E4200000000002A -+:10C790000000000000000000000000000000000099 -+:10C7A00000000A000100000000014E4E4E344C38DB -+:10C7B0001E1E1E0000000000030000000001424495 -+:10C7C0004230443014141400000000000300000044 -+:10C7D00000013E3E3E3C3E3E1414140000000000AA -+:10C7E000030000000001444444364C381414140083 -+:10C7F0000000000042424242424242424242424221 -+:10C80000420000002E343434343434343400000018 -+:10C81000004A4A4A4A4A4A4A4A4A4A4A4A4A000056 -+:10C82000002E343434343434343400000000545492 -+:10C830005400540000000000000000004848480078 -+:10C8400048000000000000000000233E3E3E4A0079 -+:10C850000000000000000000002828284000000020 -+:10C8600000000000000000004644444A00000000B0 -+:10C8700000000000000000000000000000000000B8 -+:10C88000000000000A54545400540000000000004E -+:10C890000000004848480048000000000000000078 -+:10C8A0000023545454540000000000000000000015 -+:10C8B00050505050000000000000000000002338DD -+:10C8C00044444A4A0000000000000000000000004C -+:10C8D00000000000000000000000000A000000004E -+:10C8E00034000000000000000000000000003400E0 -+:10C8F0000000000000000000005454545454000094 -+:10C9000000000000000000484848484800000000BF -+:10C910000000000000235454545454000000000050 -+:10C920000000000050505050500000000000000077 -+:10C930000000235C5C5C0050000000000000000070 -+:10C940000050485000440000000000000000002398 -+:10C950004C4C4C4C4C4C4C4C4C4C4C4C4C000000FB -+:10C9600000000000000000000000000009545454C2 -+:10C9700054540000000000000000004848484848A7 -+:10C980000000000000000000002300000000640020 -+:10C99000000000000000000000000000580000003F -+:10C9A00000000000000001000300000000004646F7 -+:10C9B00046484A4817171700000000003A3A3A3A2A -+:10C9C0004600000000000000000000000000000021 -+:10C9D000000000000000000008384444444A000001 -+:10C9E0000000000000000000000000000000000047 -+:10C9F00000000000002A00000000540000000000B9 -+:10CA000000000000000000004400000000000000E2 -+:10CA10000000013E484842460000000000000000BF -+:10CA20000000000000000000000000000000000AFC -+:10CA30000038383E42000000000000000000000006 -+:10CA40000000000000000000000000000A32323246 -+:10CA500038000000000000000000003838383800BE -+:10CA6000000000000000000000004C0000004C002E -+:10CA70000000000000000000500000005000000016 -+:10CA800000000000000001545454000000000000A9 -+:10CA900000000000005050500000000000000000A6 -+:10CAA00000000023030000000001444444344444D7 -+:10CAB00014141400000000007DC586000000000072 -+:10CAC0000800240084C58600010000000800000062 -+:10CAD00093C586000200000008000C00A4C5860073 -+:10CAE000030000000800E402AFC586000400000057 -+:10CAF00007000000C0C586000500000008002400F3 -+:10CB0000C9C586000600000001000000D1C58600EE -+:10CB10000700000007000000DBC5860008000000D9 -+:10CB20000100000049C58600090000000100000066 -+:10CB300000000000000000000000000025733A2003 -+:10CB400063616C6C65640A0070617463685F696F2F -+:10CB50007661727300616D7064755F7274730077D3 -+:10CB60006C635F61757468656E74696361746F721C -+:10CB70005F646F776E00000020798600000000403F -+:10CB8000030000003D7D86000100088008000000D1 -+:10CB9000E3C401000200004006000000D9AD01001E -+:10CBA000030010000700000055CB01000400000046 -+:10CBB0000100000000000000000000000000000074 -+:10CBC00001006C09020071090300760904007B0969 -+:10CBD000050080090600850907008A0908008F09F9 -+:10CBE000090094090A0099090B009E090C00A30989 -+:10CBF0000D00A8090E00B4096E840B000000D400DB -+:10CC000000000000000000010000000000002D00F6 -+:10CC1000A7901A0047090E00012007008B9303001C -+:10CC200038CA01002AE50000977200004C39000064 -+:10CC3000A61C0000530E0000290700009503000009 -+:10CC4000CA010000E5000000730000003900000088 -+:10CC50001D0000006030180C6C482412776C2564AD -+:10CC60003A205363616E20696E2070726F6772653F -+:10CC700073732C20736B697070696E6720747870A1 -+:10CC80006F77657220636F6E74726F6C0A00706FDD -+:10CC90007765722061646A210A002E6661622E0047 -+:10CCA00025732E6661622E25640063636B627732A2 -+:10CCB000303267706F0063636B62773230756C324D -+:10CCC00067706F006C65676F66646D6277323032D3 -+:10CCD00067706F006C65676F66646D627732307580 -+:10CCE0006C3267706F006D637362773230326770D9 -+:10CCF0006F006D637362773230756C3267706F00EE -+:10CD00006D6373627734303267706F006C65676F84 -+:10CD100066646D6277323035676C706F006C656782 -+:10CD20006F66646D62773230756C35676C706F005A -+:10CD30006C65676F66646D6277323035676D706FF2 -+:10CD4000006C65676F66646D62773230756C35674D -+:10CD50006D706F006C65676F66646D627732303539 -+:10CD60006768706F006C65676F66646D62773230FC -+:10CD7000756C356768706F006D637362773230353C -+:10CD8000676C706F006D637362773230756C3567F6 -+:10CD90006C706F006D63736277343035676C706FE1 -+:10CDA000006D63736277323035676D706F006D634D -+:10CDB0007362773230756C35676D706F006D6373B9 -+:10CDC0006277343035676D706F006D6373627732F0 -+:10CDD00030356768706F006D637362773230756CE1 -+:10CDE000356768706F006D637362773430356768DC -+:10CDF000706F006D63733332706F006C65676F66C0 -+:10CE0000646D3430647570706F00616E747377692F -+:10CE100074636800616135670074737369706F7360 -+:10CE200032670065787470616761696E326700709F -+:10CE300064657472616E6765326700747269736FDE -+:10CE4000326700616E74737763746C326700747359 -+:10CE50007369706F733567006578747061676169B5 -+:10CE60006E3567007064657472616E676535670062 -+:10CE7000747269736F356700616E74737763746C75 -+:10CE800035670070613267773061330070613267F7 -+:10CE900077316133006D61787032676130006D61A8 -+:10CEA00078703267613100706132677730613000CD -+:10CEB000706132677730613100706132677731615C -+:10CEC00030007061326777316131007061326777AD -+:10CED000326130007061326777326131006D6178A4 -+:10CEE0007035676C6130006D61787035676C6131E9 -+:10CEF00000706135676C7730613000706135676C48 -+:10CF00007730613100706135676C77316130007066 -+:10CF10006135676C7731613100706135676C7732EC -+:10CF2000613000706135676C77326131006D617816 -+:10CF30007035676130006D61787035676131007000 -+:10CF40006135677730613000706135677730613106 -+:10CF50000070613567773161300070613567773116 -+:10CF6000613100706135677732613000706135671B -+:10CF700077326131006D6178703567686130006DBE -+:10CF80006178703567686131007061356768773046 -+:10CF900061300070613567687730613100706135EC -+:10CFA000676877316130007061356768773161316A -+:10CFB000007061356768773261300070613567688D -+:10CFC00077326131006D61787035676133006D6172 -+:10CFD000787035676C613300706135677730613325 -+:10CFE00000706135676C7730613300706135677749 -+:10CFF00031613300706135676C7731613300706186 -+:10D0000035677732613300706135676C7732613331 -+:10D010000062773430706F00636464706F00737403 -+:10D020006263706F006277647570706F00747870FF -+:10D0300069643267613000747870696432676131A5 -+:10D0400000697474326761300069747432676131E9 -+:10D050000063636B3267706F006F66646D32677078 -+:10D060006F006D63733267706F30006D637332678A -+:10D07000706F31006D63733267706F32006D637370 -+:10D080003267706F33006D63733267706F34006D99 -+:10D0900063733267706F35006D63733267706F361C -+:10D0A000006D63733267706F370074787069643530 -+:10D0B000676C613000747870696435676C61310049 -+:10D0C0006F66646D35676C706F006D637335676C88 -+:10D0D000706F30006D637335676C706F31006D6316 -+:10D0E0007335676C706F32006D637335676C706F8A -+:10D0F00033006D637335676C706F34006D63733527 -+:10D10000676C706F35006D637335676C706F3600D8 -+:10D110006D637335676C706F370074787069643550 -+:10D1200067613000747870696435676131006974D3 -+:10D1300074356761300069747435676131006F66FA -+:10D14000646D3567706F006D63733567706F3000A5 -+:10D150006D63733567706F31006D63733567706F22 -+:10D1600032006D63733567706F33006D63733567BD -+:10D17000706F34006D63733567706F35006D637366 -+:10D180003567706F36006D63733567706F37007485 -+:10D1900078706964356768613000747870696435E7 -+:10D1A00067686131006F66646D356768706F006D28 -+:10D1B0006373356768706F30006D637335676870CF -+:10D1C0006F31006D6373356768706F32006D637324 -+:10D1D000356768706F33006D6373356768706F34DF -+:10D1E000006D6373356768706F35006D6373356705 -+:10D1F00068706F36006D6373356768706F370065F0 -+:10D200006C6E61326700656C6E6135670074656DC8 -+:10D21000706F66667365740070687963616C5F74C3 -+:10D22000656D7064656C7461000C12182430486080 -+:10D230006C003CC407003BC407004C84FFE0B08492 -+:10D24000F7F7F984F7FF4D84FF834CC4001FB784C0 -+:10D25000FF80B184FFDFB0C40808FA84F7FFF9C487 -+:10D260000800CC0102000000D40000000000000013 -+:10D2700000010000000000003CD30100350108302F -+:10D280000800030046D30100430100000100000034 -+:10D2900050D30100480108000300000060D30100E2 -+:10D2A00049010800030000006DD301004A01080095 -+:10D2B000030000007BD301004E01080003000000C2 -+:10D2C00086D301003D0140000700070092D3010012 -+:10D2D0007A01000407000000A0D301003F01000014 -+:10D2E00006000000ABD30100400100000200000076 -+:10D2F000B6D301007C01000002000000C3D301008E -+:10D300004201000007000000CFD301002800080000 -+:10D3100003000000E0D3010029000000010000002C -+:10D32000EDD301007F0100000200000000000000BA -+:10D330000000000000000000706879007478696ED9 -+:10D340007374707772007068795F6D7574656400CE -+:10D350007068795F676C6974636874687273680079 -+:10D360007068795F6E6F6973655F7570007068795A -+:10D370005F6E6F6973655F64776E007068795F7068 -+:10D38000657263616C007068795F7278697165734A -+:10D3900074007068796E6F6973655F73726F6D008A -+:10D3A0006E756D5F73747265616D0062616E645F4E -+:10D3B00072616E67650073756262616E643567766F -+:10D3C0006572006D696E5F7478706F77657200705A -+:10D3D00068795F6F636C736364656E61626C65002E -+:10D3E0007068795F7278616E7473656C00706879CB -+:10D3F0005F6372735F7761720000D90404000000FC -+:10D40000D90408000800D90404000400D904080065 -+:10D410000000FFEEDDCCBB998877665544332211BE -+:10D4200000000000000000000000000000000000FC -+:10D4300000000000000000000000000000000000EC -+:10D44000D70408000000D80401000000D80402003E -+:10D4500000003B04040004003C040400000036000B -+:10D460001A013A002500280005001201FF001F01E3 -+:10D470000B0013010700FC00FD00FF00C000CA0004 -+:10D48000C5001200570059005C0078009200980017 -+:10D4900016012C016A000B001B0013011D00140172 -+:10D4A0002E002A0112013B04010001003C0401008E -+:10D4B00001003C04010000003B04010000003B04AB -+:10D4C000020002003C04020002003C0402000000D2 -+:10D4D0003B04020000004C04000800084D0400203A -+:10D4E0000000B00400010001B644FFFFB7040F00C4 -+:10D4F0000F004C04000800084D0400200020B00478 -+:10D50000000100010F0900090109060907090809BE -+:10D510000209030909090A090B09040905090C098B -+:10D520000D090E0911094804000300010806FF0057 -+:10D5300017000406FF07EA033B84EDFF3C040200EA -+:10D5400002004C84D0EF4D84D7BF4D04040004008A -+:10D550004D0403000100F984F8FFFA84F8FF3B044E -+:10D56000020002003C04020000003B041000100016 -+:10D570003C04400000004C04001000104D0400402A -+:10D5800000404D04040000004C0404000400B104F9 -+:10D5900000040000B10400800000DA46FFFF03052C -+:10D5A00008000800DB04FF03A602DB040070002073 -+:10D5B0000A80D7FDDA867FFFA40400400040A4045F -+:10D5C00000400000DAC64000A40400800080A404EB -+:10D5D00000400040A40400200020B00480000000AF -+:10D5E0003B0440000000A90400800080A6040080E5 -+:10D5F0000080A604FF01FF009A04FF01FF002564DC -+:10D600002009202564200A004572726F7220676528 -+:10D610007474696E67206C6F77206971206573740C -+:10D620000A004572726F722067657474696E6720B4 -+:10D6300068696768206971206573740A0000D704FF -+:10D6400002000200D70480000000D704010001009E -+:10D65000D70440004000D70408000800D704007039 -+:10D660000020DA0640004000A404002000008746A5 -+:10D670006000424607004AC444004A44800031C664 -+:10D680001500D60603000000DAC68F004AC4440025 -+:10D690004A44800000FC070069A50500FF01000066 -+:10D6A000695D0A0000040800975E0A00010200009C -+:10D6B00097A605009A05FF0326009B05FF03890036 -+:10D6C0009C05FF038A009C0500FC00209D05003C92 -+:10D6D000002C9D05FF038C004C04080008004D043D -+:10D6E000080000004C04200020004D042000200011 -+:10D6F000F90402000200FA0402000000F904040028 -+:10D700000400FA0404000000F90401000100FA0416 -+:10D71000010000004C04001800184D040060006077 -+:10D720003809FF01FF013909FF019E003B04030096 -+:10D7300003003C0403000000DA46FFFFDBC60300E1 -+:10D74000D106040004003B04010001003C04010078 -+:10D7500001003C04010000003B0401000000D7442C -+:10D760000000D70401000100D70440000000760645 -+:10D7700080000000DA06010000006C0804000000D0 -+:10D780006C08400000006C08000400003B0401002D -+:10D7900001003C04010000003809000800083909B4 -+:10D7A000000800085384FF7F53C400804AC444002B -+:10D7B0004A448000A3C60100A386FEFFDAC64000EB -+:10D7C000DBC603003B04020002003C040200000030 -+:10D7D0003B04100010003C04400000004B44FFFFDD -+:10D7E0003B4917203C49C527D80401000000D80454 -+:10D7F00002000000D704080000004C84FFE73B84CF -+:10D800000C00424907003B4917203C49C5272184A9 -+:10D810002384348384806782568034828480678244 -+:10D82000568034827A46030073467017C946000654 -+:10D830008046FF0081463F01D70408000800D70456 -+:10D8400000700020EB04C00100006A04FFFF190013 -+:10D850000305A404D004D904DA04A604380939095C -+:10D86000D804D004D704A5040D04A2048B460000FC -+:10D870007646A1B8D106040000004B0640004000E7 -+:10D88000340600FF0000DAC680000AC028023B040C -+:10D8900004000000380940000000380904000000BE -+:10D8A000D70402000000D70401000000D7040800DC -+:10D8B0000000D80401000000D80402000000100994 -+:10D8C0001E091F09240925092609200921092709FC -+:10D8D00028092909220923093009310932091209C5 -+:10D8E000D70401000100D70440004000D704010024 -+:10D8F0000100D70440000000370600C00080D704B4 -+:10D9000001000000D90401000100D9040200000058 -+:10D9100000400140024003400440054006400740EB -+:10D92000075B07803A09800080002304FF0049005C -+:10D930003404FF00FCFF1604FF00A4FF160400FFE0 -+:10D94000009F240400FF002A230400FF002D25046B -+:10D95000FF000F000005FF000F00000500FF000F93 -+:10D960002004FF000A00340400070001FF0400FC4B -+:10D970000018F90401000100FA04010000004B0640 -+:10D98000010001004B0608000800D6060300010054 -+:10D99000DA0608000000DA06800000007606800043 -+:10D9A0000000DA06010000006C08040000006C08AA -+:10D9B000400000006C080004000042490F0042498A -+:10D9C000000042490F004A4484004A448000D34684 -+:10D9D0002222D3462022000022D401000700FF00AB -+:10D9E0001F013A001A010500820086002E01130172 -+:10D9F0007D0028009A05FF0326009B05FF03A50074 -+:10DA00009C05FF03A6009C0500FC00289D05003C2A -+:10DA1000001C9D05FF03A80003050100000003058D -+:10DA200004000000030510001000A40400400000E2 -+:10DA3000A40400800080D00420000000A404FF01A2 -+:10DA40000000A504FF00FF00A50400700050A5041D -+:10DA5000000700000D04FF0040000D040007000453 -+:10DA6000A204FF004000A20400070004A804FF0075 -+:10DA70000100D00401000000D304FF000000D30423 -+:10DA800000FF0000D00410000000D00404000000DB -+:10DA9000D00402000000D204FF000000D20400FF06 -+:10DAA0000000D00408000000100480000000A8441A -+:10DAB0000A00380940004000380904000400390910 -+:10DAC00040000000390904000400DA0600800080EC -+:10DAD000D30600800080D30600800000DA060080B4 -+:10DAE0000000424902003B4900003C4900007446E6 -+:10DAF000440475463F00704681068C464900CE4678 -+:10DB00000000CB460000CC460000CD4600009D46FC -+:10DB1000FF07A4460000A5460000977A977A977AF7 -+:10DB2000977A877A877A977B01004AC444004A44EF -+:10DB30008000D70408000000D704007000203809D6 -+:10DB400004000400390904000400A40400100010BB -+:10DB5000D70404000400D704000F000016012D01B3 -+:10DB60002C016A00980097002F010B0013011D0083 -+:10DB700014012E002A0109001F010700FF00050003 -+:10DB8000060000000600000006000000060000007D -+:10DB9000B704007F006CB1040020000039090002C6 -+:10DBA0000000380900020002B00408000800B004B8 -+:10DBB00000080008390900080000380900080008BA -+:10DBC0001004020000001004010000001004020014 -+:10DBD0000000100401000100977A877A877A977B0A -+:10DBE000100402000200100401000000DA06200008 -+:10DBF000200010040800000081040002000210044C -+:10DC000008000800DA0620000000030501000000FB -+:10DC1000030504000000A40400400000A4040080E8 -+:10DC20000000D00420000000A504FF00FF00A504B0 -+:10DC300000700050A504000700000D04FF00400024 -+:10DC40000D0400070006A204FF004000A204000724 -+:10DC50000006D90470002000D90400070003D9048D -+:10DC600000700010DA0400100000DA040020002028 -+:10DC7000A60400800080380904000400390904006B -+:10DC80000400A40400100010D70408000800D70402 -+:10DC900000700010D70408000800D704007000309E -+:10DCA000760680008000DA06010001006C0804009E -+:10DCB00004006C08400040006C08000400043B04B1 -+:10DCC000040004003C04040000004C0408000800A8 -+:10DCD0004D04080008004C04200020004D042000E2 -+:10DCE0000000F90402000200FA0402000200F90434 -+:10DCF00004000400FA0404000400F9040100010017 -+:10DD0000FA04010001005344A90A3D49C0004249F8 -+:10DD1000000042490F00424900003B4917003C49BE -+:10DD2000C507977A977A977A977A877A877A977BCF -+:10DD300021842384348384806782568034824AC459 -+:10DD400080004A847F000A46A0006A4419004AC441 -+:10DD500044004A4480004C04001000104D04004070 -+:10DD600000404C04000800084D04002000003B0463 -+:10DD7000020002003C04020000003B04010001001C -+:10DD80003C0401000000D70401000100D70440005A -+:10DD900040008007000400048007000200020F0911 -+:10DDA0000009010906090709080902090309090907 -+:10DDB0000A090B09040905090C090D090E091109C5 -+:10DDC000D7C6010031C600183B4400003C440000A7 -+:10DDD0004C440000E6440000F9440000B044000058 -+:10DDE00038490000B04400004E44000067C50300FD -+:10DDF0004AC444004A4480004AC444004A44800063 -+:10DE0000D60603000000DA06080008005F36291F66 -+:10DE10005F36291F5F36291F5F36291F000000006B -+:10DE200000000000000000000000000000000000F2 -+:10DE300000000000000000000000000004000000DE -+:10DE400000000000040000000800000001000000C5 -+:10DE500005000000090000000D0000004D0000005A -+:10DE60008D0000000D0000004D0000008D0000003E -+:10DE7000CD0000005200000092000000D20000001F -+:10DE8000D60000001601000016050000160900006B -+:10DE900056090000560D00005611000096110000B2 -+:10DEA000965100009691000096D100009611010055 -+:10DEB0000000000000000000000000000000000062 -+:10DEC000000000000000000004000000000000004E -+:10DED0000400000008000000010000000500000030 -+:10DEE000090000000D0000004D0000008D00000042 -+:10DEF0000D0000004D0000008D000000CD0000006E -+:10DF00005200000092000000D2000000D600000085 -+:10DF10001601000016050000160900005609000051 -+:10DF2000560D000056110000565100005691000099 -+:10DF300056D10000561101005651010056910100C2 -+:10DF400056D10100000000000000000000000000A9 -+:10DF500000000000000000000000000000000000C1 -+:10DF600000000000000000000000000000000000B1 -+:10DF700000000000000000000000000000000000A1 -+:10DF80000000000000000000000000000000000091 -+:10DF90000000000000000000000000000A0009006E -+:10DFA000060005000A000900060005000A00090035 -+:10DFB000060005000A000900060005000A00090025 -+:10DFC000060005000A000900060005000A00090015 -+:10DFD000060005000A000900060005000A00090005 -+:10DFE000060005000A000900060005000A000900F5 -+:10DFF000060005000A000900060005000A000900E5 -+:10E00000060005000A000900060005000A000900D4 -+:10E01000060005000A000900060005000E000000C9 -+:10E0200000020003000400060008000B00100110AD -+:10E030000210031004100510061007100717072020 -+:10E04000072D074000000000000000000000000055 -+:10E0500000000000000000000000000000000000C0 -+:10E0600000020003000400060008000B001001106D -+:10E0700002100310041005100610071007170720E0 -+:10E08000072D074000000000000000000000000015 -+:10E090000000000000000000000000000000000080 -+:10E0A0000000000000000000000000000000000070 -+:10E0B0000000000000000000000000000000000060 -+:10E0C0000000000000000000000000000000004010 -+:10E0D0000000000000000000000000000000000040 -+:10E0E0000000000000000000000000000000000030 -+:10E0F0000000000000000000000000000000000020 -+:10E10000000000000000000000000000000000000F -+:10E1100000000000000000000000000000000000FF -+:10E1200000000000000000000000000000000000EF -+:10E1300000000000000000000000000000000000DF -+:10E1400000000000000000000000000000000000CF -+:10E1500000000000000000000000000000000000BF -+:10E1600000000000000000000000000000000000AF -+:10E170000000000000000000F8410100F82100004C -+:10E18000FB210000FB410000DBFE01007B210000C1 -+:10E1900033210000EB400000A3FE01004B02000011 -+:10E1A0004D014D014D014D014D014D014D014D01FF -+:10E1B0004D014D014D014D014D014D014D014D01EF -+:10E1C0004D014D014D014D014D014D014D014D01DF -+:10E1D0004D014D014D014D014D014D014D014D01CF -+:10E1E0004D014D014D014D014D014D014D014D01BF -+:10E1F0004D014D014D014D014D014D014D014D01AF -+:10E200004D014D014D014D014D014D014D014D019E -+:10E210004D014D014D014D014D014D014D014D018E -+:10E22000090F1418FE070B0FFBFE0105080B0E115A -+:10E230001417000000000000000306090C0F120074 -+:10E240000000000000000000000306090C0F12157A -+:10E25000181B00000000000003EB0000010010008C -+:10E26000100020000100300010004000220050008B -+:10E27000220160002202700022038000220490002C -+:10E280002205A0002206B0002207C0002208D0000C -+:10E290002209F000220A1000220B2000220C30007C -+:10E2A000220D4000220E5000220F600000000000EE -+:10E2B000000000000000000000000000000000005E -+:10E2C000000000000000000000000000040000004A -+:10E2D0000000000004000000080000000100000031 -+:10E2E00005000000090000000D0000004D000000C6 -+:10E2F0008D0000000D0000004D0000008D000000AA -+:10E30000CD0000004F0000008F000000CF00000093 -+:10E31000D3000000130100001305000013090000E2 -+:10E3200053090000530D0000531100009311000029 -+:10E33000935100009391000093D1000093110100CC -+:10E3400000000000000000000000000000000000CD -+:10E3500000000000000000000400000000000000B9 -+:10E36000040000000800000001000000050000009B -+:10E37000090000000D0000004D0000008D000000AD -+:10E380000D0000004D0000008D000000CD000000D9 -+:10E390004F0000008F000000CF000000D3000000FD -+:10E3A00013010000130500001309000053090000C9 -+:10E3B000530D000053110000535100005391000011 -+:10E3C00053D100005311010053510100539101003A -+:10E3D00053D1010000000000000000000000000018 -+:10E3E000000000000000000000000000000000002D -+:10E3F000000000000000000000000000000000001D -+:10E40000000000000000000000000000000000000C -+:10E4100000000000000000000000000000000000FC -+:10E4200000000000000000000000000001040204E1 -+:10E4300003040404050406040704080409040A0488 -+:10E440008B058C058D058E058F059000910092003F -+:10E4500093019401950196019701980199019A0100 -+:10E460009B019C019D019E019F01A001A101A201B0 -+:10E47000A301A401A50100000101010101010101A5 -+:10E48000010101010101010101010101010101017C -+:10E490000101010101010203010302010101010166 -+:10E4A000010101010101010101010101010101015C -+:10E4B000010101010101010101010101010101014C -+:10E4C000010101010101010101010101010101013C -+:10E4D0000101010101010203010302010101010126 -+:10E4E000010101010101010101010101010101011C -+:10E4F0000101010101010101A0E101004000000052 -+:10E50000020000000000000010000000F8E0010020 -+:10E5100040000000010000000000000010000000AA -+:10E5200078E101000A0000000B000000000000007C -+:10E53000200000005CE20100140000000C0000005C -+:10E540000000000020000000C8E901009400000065 -+:10E550000D00000000000000200000002CE401007D -+:10E56000260000000E000000000000001000000067 -+:10E570009CDF0100400000000F00000000000000D0 -+:10E58000100000002CEC0100100000001000000042 -+:10E59000000000000800000020E201003C00000034 -+:10E5A000110000000000000008000000ACE20100C3 -+:10E5B00060000000120000000000000020000000C9 -+:10E5C00078E401008000000014000000000000005A -+:10E5D0000800000010E601009A000000170000008B -+:10E5E000000000001000000020E001006C000000AE -+:10E5F00000000000000000001000000044E70100DF -+:10E60000A000000018000000000000002000000032 -+:10E610001A0034004E0068009C00D000EA0004019B -+:10E62000340068009C00D0003801A001D401080229 -+:10E630004E009C00EA003801D4017002BE020C03B7 -+:10E640006800D0003801A00170024003A803100444 -+:10E6500018009C00D0000401EA0038018601D000B7 -+:10E660000401040138016C016C01A001380186012C -+:10E670008601D401220222027002040138016C01D9 -+:10E6800038016C01A001D401A001D40108020802E4 -+:10E690003C028601D4012202D40122027002BE0291 -+:10E6A0007002BE020C030C035A0336006C00A20079 -+:10E6B000D8004401B001E6011C026C00D8004401FE -+:10E6C000B00188026003CC033804A2004401E601D3 -+:10E6D0008802CC031005B2055406D800B0018802A8 -+:10E6E00060031005C0069807700818004401B001C7 -+:10E6F0001C02E60188022A03B0011C021C028802E7 -+:10E70000F402F402600388022A032A03CC036E0495 -+:10E710006E0410051C028802F4028802F4026003F1 -+:10E72000CC036003CC0338043804A4042A03CC03CC -+:10E730006E04CC036E041005B2051005B205540634 -+:10E740005406F6060000080000000800000008005B -+:10E750000000080000000800000008000000080099 -+:10E760000000080000000800000008000000080089 -+:10E770000000080000000800000008000000080079 -+:10E780000000080000000800000008000000080069 -+:10E790000000080000000800000008000000080059 -+:10E7A0000000080000000800000008000000080049 -+:10E7B0000000080000000800000008000000080039 -+:10E7C0000000080000000800000008000000080029 -+:10E7D0000000080000000800000008000000080019 -+:10E7E0000000080000000800000008000000080009 -+:10E7F00000000800000008000000080000000800F9 -+:10E8000000000800000008000000080000000800E8 -+:10E8100000000800000008000000080000000800D8 -+:10E8200000000800000008000000080000000800C8 -+:10E8300000000800000008000000080000000800B8 -+:10E8400000000800000008000000080000000800A8 -+:10E850000000080000000800000008000000080098 -+:10E860000000080000000800000008000000080088 -+:10E870000000080000000800000008000000080078 -+:10E880000000080000000800000008000000080068 -+:10E890000000080000000800000008000000080058 -+:10E8A0000000080000000800000008000000080048 -+:10E8B0000000080000000800000008000000080038 -+:10E8C0000000080000000800000008000000080028 -+:10E8D0000000080000000800000008000000080018 -+:10E8E0000000080000000800000008000000080008 -+:10E8F00000000800000008000000080000000800F8 -+:10E9000000000800000008000000080000000800E7 -+:10E9100000000800000008000000080000000800D7 -+:10E9200000000800000008000000080000000800C7 -+:10E9300000000800000008000000080000000800B7 -+:10E9400000000800000008000000080000000800A7 -+:10E950000000080000000800000008000000080097 -+:10E960000000080000000800000008000000080087 -+:10E970000000080000000800000008000000080077 -+:10E980000000080000000800000008000000080067 -+:10E990000000080000000800000008000000080057 -+:10E9A0000000080000000800000008000000080047 -+:10E9B0000000080000000800000008000000080037 -+:10E9C000000008000500000000000000000000003A -+:10E9D0000000001000000000000000200000000007 -+:10E9E00000000030000000000000004000000000B7 -+:10E9F0000000005000000000000000600000000067 -+:10EA00000000007000000000000000800000000016 -+:10EA10000000009008000000000000A008000000B6 -+:10EA2000000000B008000000000000C00800000066 -+:10EA3000000000D008000000000000E00800000016 -+:10EA4000000000F0080000000000000009000000C5 -+:10EA50000000001009000000000000201900000064 -+:10EA60000000003019000000000000401900000004 -+:10EA700000000050190000000000006019000000B4 -+:10EA80000000007019000000000000801900000064 -+:10EA90000000009019000000000000A01900000014 -+:10EAA000000000B019000000000000C019000000C4 -+:10EAB000000000D019000000000000E01900000074 -+:10EAC000000000F019000000000000001A00000023 -+:10EAD000000000101A000000000000201A000000D2 -+:10EAE000000000301A000000000000401A00000082 -+:10EAF0000000005002000000000000600200000062 -+:10EB00000000007002000000000000800200000011 -+:10EB10000000009002000000000000A002000000C1 -+:10EB2000000000B002000000000000C00A00000069 -+:10EB3000000000D00A000000000000E00A00000011 -+:10EB4000000000F00A000000000000000B000000C0 -+:10EB5000000000100B000000000000200B0000006F -+:10EB6000000000300B000000000000400B0000001F -+:10EB7000000000501B000000000000601B000000AF -+:10EB8000000000701B000000000000801B0000005F -+:10EB9000000000901B000000000000A01B0000000F -+:10EBA000000000B01B000000000000C01B000000BF -+:10EBB000000000D01B000000000000E01B0000006F -+:10EBC000000000F01B000000000000001C0000001E -+:10EBD000000000101C000000000000201C000000CD -+:10EBE000000000301C000000000000401C0000007D -+:10EBF000000000501C000000000000601C0000002D -+:10EC0000000000701C000000000000801C000000DC -+:10EC1000000000901C0000001CDE010060000000ED -+:10EC20001200000000000000200000005F36291FD5 -+:10EC30005F36291F5F36291F5F36291F0CDE010052 -+:10EC4000100000001000000000000000080000009C -+:10EC500090E8860000008000010000000000000035 -+:10EC600000000000000000007363616E00000000FF -+:10EC700044EB86000100204005000000A2A58600AC -+:10EC8000020020400500000090A5860003002040FF -+:10EC9000050000007EA5860004002040050000005D -+:10ECA000759986000500104005000000EBE886001D -+:10ECB00006002040020000004CEB86000C00000023 -+:10ECC000010000005EEB8600070020000800000045 -+:10ECD0000000000000000000000000006E6F637282 -+:10ECE00063005344494F0043444300000D16800025 -+:10ECF0008D13800025118000291480001D138000D1 -+:10ED0000A1168000E1EA0000011380002D138000AD -+:10ED1000000000001D16800005000000FFFFFFFF3F -+:10ED20001400000005000000FFFFFFFF05000000C9 -+:10ED300005000000050000000E0E0E0E0E02090D6B -+:10ED40000A080D01090D0A080D01090D0A080D0137 -+:10ED5000090D0A080D01090E0A090E060A0E0B0913 -+:10ED60000E02093A160E0E05093A160E0E050A0E87 -+:10ED70000B090E050A0E0B090E020A0E0B090E02F4 -+:10ED800014C0C015110514C0C015110514C0C0155C -+:10ED9000110514C0C015110514C0C0151105093A9C -+:10EDA000160E0E0514C0C015110514C0C0151105AE -+:10EDB000093A160E0E05093A160E0E05093A160EF8 -+:10EDC0000E0514C0C0151105093A160E0E05093AB4 -+:10EDD000160E0E05093A160E0E0509B21C0E0E058A -+:10EDE00012B119111108000000000000000000001D -+:10EDF0000000000019300200F52F0200E12F020090 -+:10EE000055AA80000000000021AA800085AA800089 -+:10EE100031AA80006DAA8000C993800095A9800066 -+:10EE2000BDA98000D5938000B593800075938000C4 -+:10EE3000D191800000000000B1A98000736470636C -+:10EE40006D6465760000000000000000F4ED010034 -+:10EE500000000000000000000000000000000000B2 -+:10EE60000000000000000000776C000000000000BF -+:10EE70000000000000000000F0250000000000007D -+:10EE80000000000000000000000000000000000082 -+:10EE900000000000F918010DE400F4DEF106FC0F9B -+:10EEA00027FAFF1DF01018090AF210E017140411D8 -+:10EEB00014F1FAF2DBF7FCE2FBE1EE130DFF1CE9C3 -+:10EEC0001A17180300DAE803E617E4E9F3FF121350 -+:10EED00005E104E225F706F2ECF1FC11E914F0E09B -+:10EEE000F6F2E8091010011DD9FA040F0F060CDE26 -+:10EEF0001C00FF0D07181AF60EE4160FF905EC18A2 -+:10EF00001B0A1EFF0026E2FFE50A14180705EA0F98 -+:10EF1000F2E4E6F608080808080808090A080807DD -+:10EF200007010202020202020202020202020202BD -+:10EF30000202020201010000000000000000C50101 -+:10EF40001DFFE0FFC0FFE0FF0000000000FF000029 -+:10EF500000006B0382FEE7FFCCFFE7FF0800020022 -+:10EF60000000D7010BFFEEFFDCFFEEFFA7033CFE26 -+:10EF7000ECFF1700ECFF720385FEAEFEF801AEFE5B -+:10EF8000070004000000980160FFCBFF96FFCBFF55 -+:10EF90009C0345FE2500C1FF2500B10316FEE4FEDB -+:10EFA000A501E4FE07000000010000006C0900005C -+:10EFB0000B0A00070A88888002000000710900001F -+:10EFC0000B0A00070A888880030000007609000009 -+:10EFD0000B0A00070A888880040000007B090000F3 -+:10EFE0000B0A00070A8888800500000080090000DD -+:10EFF0000B0A00070A8888800600000085090000C7 -+:10F000000B0A00070A888880070000008A090000B0 -+:10F010000B0A00070A888880080000008F0900009A -+:10F020000B0A00070A888880090000009409000084 -+:10F030000B0A00070A8888800A000000990900006E -+:10F040000B0A00070A8888800B0000009E09000058 -+:10F050000B0A00070A8888800C000000A309000042 -+:10F060000B0A00070A8888800D000000A80900002C -+:10F070000B0A00070A8888800E000000B40900000F -+:10F080000B0A00070A88888000000000A200000028 -+:10F0900000FF00FF00000000000000FF0000000073 -+:10F0A0007802A0FE80FF00FF80FF08000100000042 -+:10F0B000760179FFF0FFE0FFF0FF1F0374FECEFF43 -+:10F0C000E0FFCEFFEE022BFE2CFF32002CFF0800EB -+:10F0D00002000000770116FFDBFFB4FFDBFF1F0318 -+:10F0E00074FEE0FFECFFE0FFEC02F2FE80FF1E008A -+:10F0F00080FF080003000000770116FFDBFFB4FF6C -+:10F10000DBFF1F0374FEE0FFECFFE0FFEC02F2FE0A -+:10F110006CFF23006CFF0800040000003301AEFF09 -+:10F12000CBFF96FFCBFF0B0385FECBFF0A00CBFF87 -+:10F13000FD022BFE2CFFCA002CFF0800140001006A -+:10F14000BF0131FFF20049FEF200870361FE33FF89 -+:10F15000620133FF800378FEDAFEE900DAFE080080 -+:10F1600015000100BF0131FF18010EFE18018703D1 -+:10F1700061FE16FF7C0116FF800378FE8FFF93006F -+:10F180008FFF090016000100BF0131FF620055FF2B -+:10F190006200870361FE1FFF6B011FFF79037EFE84 -+:10F1A000F4FE5D00F4FE080017000100BC0131FF11 -+:10F1B000740042FF7400870361FE52FF020152FF98 -+:10F1C000800378FE7FFFF1FF7FFF08001800010039 -+:10F1D000B40131FFDFFF1D00DFFF880361FE87FF01 -+:10F1E00090FF87FF7F0378FECDFEF401CDFE08007F -+:10F1F00019000100AD0131FFB8FF3E00B8FF8203E6 -+:10F2000061FEAAFFB1FFAAFF7F0378FEC7FEFE01E1 -+:10F21000C7FE08001A000100930154FFD9FF0C003B -+:10F22000D9FF1B03C7FE4CFF38004CFF3303B8FE69 -+:10F2300080FF280080FF08001B000100890154FFA7 -+:10F24000CFFF1300CFFF1703C7FE00FF500000FFE2 -+:10F250002E03BDFE8BFF25008BFF08001E00010062 -+:10F26000BB0119FFC3FF1D00C3FF6B0361FE66FFF7 -+:10F27000480066FF7C0378FE56FF4F0056FF0800EB -+:10F280002C000100BF0131FFE00071FEE0008703A8 -+:10F2900061FE8BFFC4008BFF800378FEB2FEC000CE -+:10F2A000B2FE0800000001009F01520740008000EC -+:10F2B0004000180378064000800040000A032E0634 -+:10F2C0004000800040000800010001009201370763 -+:10F2D00003013B0003019F02020744003600440083 -+:10F2E000600247075D00A7005D0008000200010002 -+:10F2F0009F01520740008000400018037806C000BC -+:10F300008001C0000A032E06400080004000080073 -+:10F31000030001002E0131078100020181009202E9 -+:10F32000B806CD009A01CD00F202E006AA00540111 -+:10F33000AA0008001400010068015CFFF200C6FE8C -+:10F34000F200F002B8FE33FFCB0033FFFF02E0FE15 -+:10F3500003FF49FF03FF08001500010068015CFF7F -+:10F36000950052FF9500F002B8FE33FFA40033FF72 -+:10F37000FF02E0FE00FFEFFE00FF080016000100A4 -+:10F3800068015CFF62009CFF6200F002B8FE33FF80 -+:10F390007C0033FFFF02E0FE00FFA0FE00FF08003C -+:10F3A000170001005E015CFF8CFF52008CFFF00231 -+:10F3B000B8FE33FF280033FFFF02E0FE7FFF15FF9A -+:10F3C0007FFF08001800010045015CFFE0FFD8FF47 -+:10F3D000E0FFF402B8FE00FF29FE00FFFE02E0FE9F -+:10F3E000FAFEAA00FAFE0800190001002B015CFFDA -+:10F3F000CDFFC0FFCDFFE002B8FE00FF29FE00FFF9 -+:10F40000FD02E0FEFAFEAA00FAFE08001A00010062 -+:10F41000150197FFD9FF8BFFA8FF7D022EFFC0FFCC -+:10F4200040FF70FF660248FF80FF80FEE0FE08009C -+:10F430001B000100F50097FFCFFF6DFF92FF7202E6 -+:10F440002EFF5EFF1BFE95FE650248FFC2FF46FFD2 -+:10F4500075FF08001E0001002E0131FFC3FF86FF6B -+:10F46000C3FF9202B8FE33FF66FE33FFF202E0FEF6 -+:10F4700056FFACFE56FF08002800010068015CFF43 -+:10F48000F200C6FEF200F002B8FECD0035FFCD005E -+:10F49000FF02E0FEFF017201FF0108000501000804 -+:10F4A0000001FFFF0000000000000000000000005D -+:10F4B000000000000000000000000000000000004C -+:10F4C000000000000000000000000000000000003C -+:10F4D000000000000000000000000000000000002C -+:10F4E000000000000000000000000000000000001C -+:10F4F000000000000000000000000000000000000C -+:10F5000000000000000000000000000000000000FB -+:10F5100000000000000000000000000000000000EB -+:10F5200000000000000000000000000000000000DB -+:10F5300000000000000000000000000000000000CB -+:10F5400000000000000000000000000000000000BB -+:10F5500000000000000000000000000000000000AB -+:10F56000000000000000000000000000000000009B -+:10F57000000000000000000000000000000000008B -+:10F58000000000000000000000000000000000007B -+:10F59000000000000000000000000000000000006B -+:10F5A000000000000000000000000000000000005B -+:10F5B000000000000000000000000000000000004B -+:10F5C000000000000000000000000000000000003B -+:10F5D000000000000000000000000000000000002B -+:10F5E000000000000000000000000000000000001B -+:10F5F000000000000000000000000000000000000B -+:10F6000000000000000000000000000000000000FA -+:10F6100000000000000000000000000000000000EA -+:10F6200000000000000000000000000000000000DA -+:10F6300000000000000000000000000000000000CA -+:10F6400000000000000000000000000000000000BA -+:10F6500000000000000000000000000000000000AA -+:10F66000000000000000000000000000000000009A -+:10F67000000000000000000000000000000000008A -+:10F68000000000000000000000000000000000007A -+:10F69000000000000000000000000000000000006A -+:10F6A000000000000000000000000000000000005A -+:10F6B000000000000000000000000000000000004A -+:10F6C000000000000000000000000000000000003A -+:10F6D000000000000000000000000000000000002A -+:10F6E000000000000000000000000000000000001A -+:10F6F000000000000000000000000000000000000A -+:10F7000000000000000000000000000000000000F9 -+:10F7100000000000000000000000000000000000E9 -+:10F7200000000000000000000000000000000000D9 -+:10F7300000000000000000000000000000000000C9 -+:10F7400000000000000000000000000000000000B9 -+:10F7500000000000000000000000000000000000A9 -+:10F760000000000000000000000000000000000099 -+:10F770000000000000000000000000000000000089 -+:10F780000000000000000000000000000000000079 -+:10F790000000000000000000000000000000000069 -+:10F7A0000000000000000000000000000000000059 -+:10F7B0000000000000000000000000000000000049 -+:10F7C0000000000000000000000000000000000039 -+:10F7D0000000000000000000000000000000000029 -+:10F7E0000000000000000000000000000000000019 -+:10F7F0000000000000000000000000000000000009 -+:10F8000000000000000000000000000000000000F8 -+:10F8100000000000000000000000000000000000E8 -+:10F8200000000000000000000000000000000000D8 -+:10F8300000000000000000000000000000000000C8 -+:10F8400000000000000000000000000000000000B8 -+:10F8500000000000000000000000000000000000A8 -+:10F860000000000000000000000000000000000098 -+:10F870000000000000000000000000000000000088 -+:10F880000000000000000000000000000000000078 -+:10F890000000000000000000000000000000000068 -+:10F8A0000000000000000000000000000000000058 -+:10F8B0000000000000000000000000000000000048 -+:10F8C0000000000000000000000000000000000038 -+:10F8D0000000000000000000000000000000000028 -+:10F8E0000000000000000000000000000000000018 -+:10F8F00083682DE9F0415B690546152B0F460AD058 -+:10F90000182B08D01B2B06D0242B01D0272B04D179 -+:10F910002B8A7F2B05D80C2304E0172B01D0182B42 -+:10F9200001DD1423AB624FF004430022BB6100E011 -+:10F930000132BB69002B03DA1D4B9A42F8D134E047 -+:10F940001C4B9A4231D8AE6A3C69331DAB83AC6123 -+:10F95000A868298AE1F3DAF4022390FBF3F014F4A7 -+:10F96000807F68840AD0284639463246E1F3E6F4BF -+:10F97000C0F30F1083B2E8832B8403E0AB8B2B849E -+:10F980006B8CEB83AB6913F4007F0AD0AA6A28461C -+:10F9900039460132E1F3D2F4C0F30F1083B2688428 -+:10F9A00000E02B8CAB842B8AEB84BDE8F081C04651 -+:10F9B000809698007F96980070B50446E1F3D0F2E7 -+:10F9C000002144220546E2F33BF36369152B2B60CB -+:10F9D00001D0162B01D9104B6B60686808B9054639 -+:10F9E00017E0AC602046EBF385F3E8602046EBF3CC -+:10F9F00049F3064618B920460121EBF381F36B6801 -+:10FA000020469B68984705461EB920463146EBF3D1 -+:10FA100077F3284670BDC046ECEC01000523C0F822 -+:10FA200094310223C0F898311E33C0F89C31234B27 -+:10FA30004FF010021B68002B0CBF07230023C0F8F7 -+:10FA4000A0314FF00103C0F8AC3103F16303C0F8FB -+:10FA5000B0314FF00603C0F8C03140F23C73C0F83B -+:10FA6000C4314FF00803C0F8C83103F10D03C0F8EA -+:10FA7000A421C0F8B821C0F8BC21C0F8CC31C0F82E -+:10FA8000D02101D1032302E00D4B1B68013BC0F8DC -+:10FA9000D4311C230422C0F8DC310C23C0F8E0313F -+:10FAA0009B18C0F8E4310623C0F8EC310023C0F8FD -+:10FAB000D821C0F8E821C0F8F0317047EC260000EA -+:10FAC000D4250000D0F8101270B5044609B90D46CF -+:10FAD0000CE08068E3F368F0D4F810120546E822E1 -+:10FAE000A068E7F305F10023C4F81032284670BD82 -+:10FAF00070B50024054680F87541006903F0F0FAFE -+:10FB00002846EAF3D9F0E8682146EBF393F1D5F8FB -+:10FB1000900128B1E6F3D2F3D5F89001E6F318F49A -+:10FB2000D5F88C0128B1E6F3C9F3D5F88C01E6F3DA -+:10FB30000FF4E86805F070FBD5F8103223B11B789C -+:10FB400013B12846FFF7BEFFA86829464FF4077295 -+:10FB5000E7F3CEF070BDC0461FB5044606238068AB -+:10FB6000E8210393E7F3B4F0C4F8100210B94FF0A2 -+:10FB7000FF300CE00021E822E2F362F20023009360 -+:10FB8000A068D4F8101203AA1C33E3F3A5F004B064 -+:10FB900010BDC0462DE9F0478AB01F46129D9C4B10 -+:10FBA00008461D6011469046EAF308F0002800F070 -+:10FBB0002A8138464FF40771E7F38AF0044600289B -+:10FBC00000F0218100214FF407720646E2F338F27B -+:10FBD000A76065612046FFF721FF8E4B1B68C4F8C4 -+:10FBE0000C320BB99A4605E01B78B3F1000A18BF36 -+:10FBF0004FF0010A884B04F128001A680121002AFD -+:10FC000014BF31221122E3F339F100230093019351 -+:10FC10000293404639462A46139B05F03BFCE060C0 -+:10FC2000002800F0EA80EBF31DF12060E068EBF3C0 -+:10FC300037F1656960606B68784A83F00103784941 -+:10FC400003F00103002B0CBF88469046226884F81D -+:10FC5000763140F629039A42D4F80890D4F80CC0C3 -+:10FC60000AD120B905F5007E05F5047508E005F513 -+:10FC7000007E05F5087503E005F5007E05F50475C1 -+:10FC8000D4F8B831D4F8BC21D4F8C411D4F8C001E8 -+:10FC900001934FF0FF33049309330693002302923C -+:10FCA0000391059007934846414662467346009586 -+:10FCB000EFF74AF96062002800F09F80D4F80C1238 -+:10FCC000C1B10B78B3B1E4F393F756492246D4F8A7 -+:10FCD0000C02E2F355F7D4F80C0253492246E2F342 -+:10FCE00089F7BAF1000F05D02046FFF735FF00284D -+:10FCF00040F0838001210A46606AE4F381F72046E0 -+:10FD00000021E2683B4603F0F7F92061002874D037 -+:10FD100000210B462046454AE6F33CF30023C4F895 -+:10FD2000900184F879314248E7F3A0F718B3E2F381 -+:10FD3000CFF3012383403F48C4F88031E7F396F7BF -+:10FD400010B1E2F3C5F308B1D4F88001C4F884011E -+:10FD500039490020E2F310F6030CA4F888319BB275 -+:10FD6000A4F88A013BB100212046344A0B46E6F351 -+:10FD700011F3C4F88C0100203149E2F3FDF50128AC -+:10FD800009D184F816022F490138E2F3F5F501286C -+:10FD900004BF2D4B18602046E9F370F520B3002511 -+:10FDA000C4F8A05128462949E2F3E6F528B1012319 -+:10FDB00084F8F9312648EFF781F928462549E2F31E -+:10FDC000DBF588B123492846E2F3D6F54FF080737E -+:10FDD00000F00F000AA901F8010D4FF440720093E2 -+:10FDE00020460F23E2F7A2FF1B481C492246E6F3F8 -+:10FDF00081F61B48EAF7FCFA06E0A06821464FF4BA -+:10FE00000772E6F375F7002630460AB0BDE8F087C2 -+:10FE1000F4260000BC260000EC260000AE27860079 -+:10FE2000B6278600DD9B80005929000065A680006A -+:10FE3000052886000E28860017288600499B80002A -+:10FE40001F28860028A80100A8F401002A2886009F -+:10FE50003428860039A801004D288600E59A8000E4 -+:10FE6000D596800010B5044660B10368064918684D -+:10FE7000224604F069D82368214658684FF4BC72C2 -+:10FE8000E6F336F710BDC046853B86007FB50546D4 -+:10FE90004FF4BC714068E6F31BF708B9064619E059 -+:10FEA00000214FF4BC720646E2F3CAF00B4B3560FA -+:10FEB00000930B4B002401932868334609490A4AF2 -+:10FEC0000294039404F008D84FF49663C6F86031A6 -+:10FED00086F86441304604B070BDC046C5EB0000F2 -+:10FEE0000531000060A80100853B860041F2E44333 -+:10FEF000984201D00020AFE044F22033994200F054 -+:10FF0000AA800533994200F0A680223B994200F076 -+:10FF1000A2801E33994200F09E800333994200F084 -+:10FF20009A800C3B994200F096800133994200F090 -+:10FF300092800133994200F08E80093B994200F093 -+:10FF40008A800233994200F08680013B994200F09A -+:10FF50008280023399427ED0013399427BD00133B3 -+:10FF6000994278D00533994275D00133994272D0C5 -+:10FF7000013399426FD001F53C43D8339BB2022B39 -+:10FF800069D94BF6D543CB189BB2022B63D944F207 -+:10FF9000413399425FD0013B99425CD001F53C432B -+:10FFA000B0339BB2022B56D944F25333994252D00C -+:10FFB000043399424FD04AF69D1399424BD044F2F4 -+:10FFC0005433994247D0253B994244D0013B994252 -+:10FFD00041D0063399423ED0013399423BD00133A0 -+:10FFE000994238D04BF6C943CB189BB2022B32D979 -+:10FFF00044F2167399422ED0113399422BD0A3F5B7 -+:020000022000DC -+:100000007973994227D001F53C43A0339BB2012B71 -+:1000100021D901F53C43BA339BB2022B1BD94BF6D5 -+:10002000CF43CB189BB2012B15D94BF6AB43CB1862 -+:100030009BB2012B0FD901F53C43A8339BB2012B96 -+:1000400009D944F26333994205D00D33994214BF64 -+:100050000020012000E001207047C0462DE9F84F44 -+:1000600000264FF0010842F601334FF0FF344FF005 -+:10007000640B0746A0F8283680F8474680F8C44449 -+:100080000221224680F8288080F868B780F842660E -+:1000900080F84C8680F8436680F8498680F846668A -+:1000A00005F066DC38464146324605F061DC0C213D -+:1000B0002246384605F05CDC0B213846324605F016 -+:1000C00057DC0E212246384605F052DC0D21384619 -+:1000D000324605F04DDC0F212246384605F048DC5B -+:1000E00004210222384605F043DCD7F860364FF091 -+:1000F000030987F8488683F80690D7F860364FF0F2 -+:10010000020A83F8079040F62A13A7F82A36A7F8C0 -+:100110002C369BB2A7F82E3640F62A13A7F83036B5 -+:10012000A7F83236A7F83436A7F8363640F62B1340 -+:10013000A7F838363B68A7F87A6583F895604FF0E2 -+:100140000703A7F83A364FF00403A7F83C360F230D -+:1001500087F80C37D7F89034A7F83E96C7F8803266 -+:10016000A7F840A6A7F87C68A7F87EB887F8EA61E8 -+:1001700087F8EB6187F81E6287F8EE6187F8EC611B -+:1001800087F8FA8187F80B6787F8A0649E71D7F823 -+:1001900094340B22C7F8843283F80680D7F8983459 -+:1001A0003146C7F8883283F806A0D7F89C34354624 -+:1001B000C7F88C3283F806903B6887F8506783F85D -+:1001C0004D805C633B6807F5CC6483F842803B68F4 -+:1001D000043483F843603B6887F8CF6183F8396063 -+:1001E0003B68204683F8AA803B6887F8DF6187F880 -+:1001F000E081C7F8E46187F8E161DE66E1F320F7AA -+:100200006FF0220387F864362C3387F865364A4648 -+:1002100004EB0A001A49E1F3AFF63B6887F869A6D8 -+:1002200087F8568587F8578583F84C603A6887F8D1 -+:100230009267A7F89067A7F88CB892F8463013F049 -+:10024000030F0CD092F94C304BB1D7F8FC0424309A -+:10025000F4F3FEF7D7F8FC043230F4F3F9F74FF477 -+:100260004873A7F85C373B68012287F8252883F894 -+:10027000A2203A684FF0FF3382F8B530BDE8F88F1E -+:10028000C3A60100836B70B5002483F84C40C36B98 -+:10029000012583F84C500646816BE3F799F9F16B21 -+:1002A0003046E3F795F921463046F9F351F5B36B43 -+:1002B000304683F84D40F36B294683F84D40D6F81D -+:1002C00060364FF0FF34DD72D6F860369C81F9F36A -+:1002D0003FF5D6F860369B78AB4214D9B36B83F800 -+:1002E0004D40F26B4FF0FF3382F84D3096F8CB342F -+:1002F00096F8CC2443EA022343F0800386F8CB34FB -+:100300001B0A86F8CC3470BDD0F8AC1110B5044689 -+:1003100029B18068EFF3B4F10023C4F8AC31D4F80C -+:10032000C41129B1A068EFF3ABF10023C4F8C431C4 -+:10033000D4F8741529B1A068EFF3A2F10023C4F832 -+:100340007435D4F8F81629B1A068EFF399F10023B9 -+:10035000C4F8F836D4F8FC1629B1A068EFF390F190 -+:100360000023C4F8FC36D4F8E036196A31B1A0682D -+:10037000EFF386F1D4F8E02600231362D4F83C159D -+:1003800029B1A068EFF37CF10023C4F83C35D4F820 -+:10039000941729B1A068EFF373F10023C4F89437E0 -+:1003A000D4F8B01829B1A068EFF36AF10023C4F8BB -+:1003B000B03810BD70B505462D4980682A46002327 -+:1003C000EFF37AF1C5F8AC0100284ED0A8682949AE -+:1003D0002A460023EFF370F1C5F8C401002844D089 -+:1003E000A86825492A460023EFF366F1C5F874058D -+:1003F00000283AD0A86821492A460023EFF35CF18F -+:10040000C5F8F806002830D0A8681D492A46002300 -+:10041000EFF352F1C5F8FC0638B3A86819492A462B -+:100420000023D5F8E046EFF347F12062E8B1A86871 -+:1004300015492A460023EFF33FF1C5F83C05A0B16A -+:10044000A86812492A460023EFF336F1C5F894074D -+:1004500058B1A8680E492A460023EFF32DF1C5F8DC -+:10046000B008003818BF012000E0002070BDC04671 -+:100470003DAA81003D708100253E8100959181005B -+:10048000858F8100256E810089598100396B81003B -+:10049000496F810010B50446006805F0A7FFD4F845 -+:1004A000480120B105F078FA0023C4F84831D4F8A7 -+:1004B000583113B10023C4F85831D4F83C0120B1AD -+:1004C00005F008FA0023C4F83C31D4F8400120B10B -+:1004D00001F078F80023C4F84031D4F84C0120B181 -+:1004E00002F0EEF80023C4F84C31D4F8540120B1E6 -+:1004F00005F0A6FA0023C4F85431D4F8600120B105 -+:1005000007F0EAF80023C4F86031D4F8383113B1A9 -+:100510000023C4F83831D4F8640120B102F008F89F -+:100520000023C4F86431D4F8000520B107F010FAB4 -+:100530000023C4F80035204605F0BEFB10BDC046C0 -+:100540002DE9F041054608B9074695E001F068FC41 -+:100550000746284605F06ADB00B90137D5F8F016E2 -+:1005600049B16868D5F8F426E6F3C2F30023C5F86C -+:10057000F436C5F8F0362846D5F81815FCF38AF29B -+:100580002846D5F8D816FCF385F2D5F8201528466C -+:10059000FCF380F2D5F82C1521B168684FF496620F -+:1005A000E6F3A6F3D5F87C0220B105F03DFB00236D -+:1005B000C5F87C3200242B19D3F84C1211B128460F -+:1005C0001EF03ADF0434202CF5D10121284635F005 -+:1005D000C9D8284601F082FF2E6BB16911B12846B7 -+:1005E00034F054DB0024B461D5F85C0105F066FA00 -+:1005F0002846FFF789FE2846FFF74CFF2846D5F826 -+:100600002C18E2F7DDFFC5F82C48D5F8B84404E013 -+:1006100068681022E468E6F36BF32146002CF7D1FA -+:10062000C5F8B844286816492A4603F08DDCD5F889 -+:10063000340718B101F008F9C5F83447D5F8680156 -+:1006400018B107F0AFF8C5F86841D5F8181759B1D7 -+:100650006868D5F81C27E6F34BF3C5F8184703E0A4 -+:10066000284669680AF0B0DBD5F87822002AF7D16D -+:100670002846696800F02CFD3846BDE8F081C04688 -+:10068000BB5C8600036870B55E6905461449304658 -+:10069000E2F372F1C0B218B930461249E2F36CF1DC -+:1006A00040B2431E0E2B0ED8012803D1D5F8603678 -+:1006B000002204E0022806D1D5F8603601229A71A2 -+:1006C000D5F86036DA71084930462C6BE2F354F104 -+:1006D00084F804012846F2F3EFF4012070BDC0460F -+:1006E000C65C8600CB5C86000E5D8600036870B534 -+:1006F0001B490546D0F860465869E2F33DF1207089 -+:100700002B6818495869D5F86046E2F335F1E07076 -+:10071000D5F8602613780BB10F2B01D1012313708C -+:10072000D5F8603601211A785A70D5F8604620460F -+:10073000E1F3DEF6A070D5F86026D3780BB10F2B6D -+:1007400001D10123D370D5F860360121DA781A710E -+:10075000D5F86046E01CE1F3CBF6607170BDC04691 -+:10076000EBA80100F3A8010070B50446214600681B -+:1007700007F0FCF8C4F8000508B9293061E02068EA -+:1007800005F03CFE2068214601F082F8C4F83407E9 -+:1007900008B92A3055E02B4B2046C4F8583105F0F3 -+:1007A000B3F8C4F83C0108B931304AE0204600F003 -+:1007B00043FFC4F8400108B9323042E0204606F059 -+:1007C0009DFFC4F8600108B935303AE02068214641 -+:1007D000A2681D4B05F044FAC4F87C0208B9393010 -+:1007E0002FE0204601F0F4FEC4F8640108B93C3063 -+:1007F00027E0164B0125C4F838310023A4F830381F -+:1008000084F8883884F88A3884F88958204605F0B6 -+:10081000D5F8C4F8480108B9433012E023682146EE -+:1008200083F8A350236883F8A950236883F8A8505D -+:10083000206805F04BFA08B1452002E0236883F8F0 -+:10084000A05070BDEFBEADDE9D6D8100EFBEAD0D61 -+:10085000F0B5D0F840750021AC2287B00646384686 -+:10086000E1F3EEF34FF06403FB85032387F8603078 -+:1008700000220123D6F85C014FF42C5125F0D2DA86 -+:10088000FF2804D1336B18691968EFF7EDFA316866 -+:100890007886A6F8260691F84640336B00F440654A -+:1008A000FF201A8900211B68B5F5406F14BF14257D -+:1008B0002825019004F00304D6F860060091029404 -+:1008C00003958078049007F1380030F0D7DB336867 -+:1008D00093F8463013F0030F03D0FB8843F0200356 -+:1008E000FB8007B0F0BDC0462DE9F04F8DB01A9FD8 -+:1008F0009A46002307910B93064693461046179994 -+:10090000189A199B9DF85890009709F075FA0446BB -+:1009100010B11E230B9375E304F082FE1798514625 -+:100920000BAA00F003FD0546002800F06B83179A20 -+:100930004FF0FF334260D0F86026D0F8008082F894 -+:100940001C31836B86600363436BC8F804A0C362E9 -+:10095000179BC0F87871C8F80C30B44B88F8219018 -+:10096000C8F8B030032380F8693780F89D415146BC -+:10097000FFF774FB2846FBF323F2284605F0C0F985 -+:100980000446002840F0478328463146179A5346CC -+:1009900006F028FFC5F8680108B91F23CAE2A44B76 -+:1009A0000194009302940394A249A34A2B46286819 -+:1009B00003F092DAA14B0194009302940394A049AE -+:1009C000A04A2B46286803F087DA189A199B179ECD -+:1009D00002920393284607995A465346CDF8009051 -+:1009E0000196049701F06CFB04460B90002840F040 -+:1009F00012832B69186EEAF7E5FAA5F8BE082846B7 -+:100A0000F9F38EF008B9142394E2264631460AAA77 -+:100A10002846FAF311F531462846BDF8282001365C -+:100A2000FAF314F5062EF1D1012488F89A4005F561 -+:100A3000BE72286908F114011BF054DF8249D8F80E -+:100A40001400E1F399F781498146D8F81400E1F3E5 -+:100A500093F77F49A5F86208D8F81400E1F38CF702 -+:100A6000B5F86228A5F86408A5F87827A5F87A07EC -+:100A70007849D8F81400E1F37FF77749A5F85408CE -+:100A8000D8F81400E1F378F785F856087349D8F8D8 -+:100A90001400E1F371F785F858087149D8F814008B -+:100AA000E1F36AF785F85A086E49D8F81400E1F3C3 -+:100AB00063F785F857086C49D8F81400E1F35CF740 -+:100AC00085F859086949D8F81400E1F355F785F815 -+:100AD0005B086749D8F81400E1F34EF785F85C0825 -+:100AE0006449D8F81400E1F347F785F85E086249D5 -+:100AF000D8F81400E1F340F785F860085F49D8F8AA -+:100B00001400E1F339F785F85D085D49D8F8140061 -+:100B1000E1F332F785F85F085A49D8F81400E1F399 -+:100B20002BF785F861082846FFF7E0FDD5F8602629 -+:100B30002B6B85F8F04785F8F14718691178D27862 -+:100B4000EFF7E4FB2869EA6AD0F8A03005F5CB742A -+:100B50005360D0F8A43021469360D0F8A830D36019 -+:100B6000D0F8AC301361D0F8B0305361D0F8B43065 -+:100B700093611BF0E7DF08F14E0021463246E1F3B6 -+:100B8000FBF1B5F8822144F221339A4217D00E3B93 -+:100B90009A4214D007339A4211D010339A420ED0A1 -+:100BA000143B9A420BD007339A4208D010339A4232 -+:100BB00005D025339A4214BF0024012400E001240B -+:100BC00005EB84039B6B28462B63FFF75BFD08B99D -+:100BD0001823AFE1296B4FF00F0340F2FF36A1F865 -+:100BE000063101F1FC0201F58073A1F80861284685 -+:100BF00000F0C4FF2A6BD2F8FC30C2F8F830C2F81B -+:100C0000F030D2F80031C2F8F4301368022B07D16B -+:100C1000013B53752B6B284603215A7D04F0A8DE57 -+:100C200019F0010F30D000222FE0C0461AC35A0538 -+:100C300079DB810078D48500BB5C86002D4A0000FA -+:100C400044AA010010A90100D6688600E268860067 -+:100C5000F5688600076986001C6986002B69860096 -+:100C60003A698600496986005A6986006B69860080 -+:100C70007C6986008A69860098698600A669860074 -+:100C8000B6698600C6698600012288F846200A21D6 -+:100C9000284604F06DDE296B28461C31FCF3C6F6AD -+:100CA0007F23296B00932B68002293F8463001F1D3 -+:100CB0001C0003F0030301935031134630F01CDA9B -+:100CC000B4F1FF3F3FF45DAF2846F8F383F74FF4EC -+:100CD000D163C5F874382846FFF746FD04460B90EB -+:100CE000002840F0988128465146FFF763FB08B979 -+:100CF00020231FE1284604F0EBFEC5F85C0108B98B -+:100D0000212317E12846FFF7A3FD2146AD4AAE4B4C -+:100D100028460094019506F0FBFDAC4B6E461A1D6B -+:100D200007CA1B6886E80700072128462A4609F0FB -+:100D30009DDF04212846A64AA64B0094019506F0A3 -+:100D4000E7FD0028C5F88C0701DA2223F2E02846E7 -+:100D500017990AF00FD808B96423EBE0C5F8040826 -+:100D60004FF0FF3728469C499C4A9D4B009702F064 -+:100D70004BD9C5F82C08002800F04D81284601F019 -+:100D8000B7FB044608B12323D4E02B684FF00602DA -+:100D900093F8A130A8F86420012B04BF4023A8F8E1 -+:100DA0006430D8F88C304FF006064FF439721E804C -+:100DB0005A80D8F890304FF0C4024FF0010605F584 -+:100DC000007128461E805A8006310AF0A7DFD5F848 -+:100DD0003C0110F031D808B185F8CF61022385F8C5 -+:100DE000C0341C3385F8CB3410222B6B85F8CC240F -+:100DF0005B89022B02D81C2385F8CB342846214678 -+:100E000085F8CA7485F8C97485F8C874F9F344F490 -+:100E10002B68284683F8B4402146C5F8D471F4F312 -+:100E200053F485F8DC412846FFF72CFA19F0080F37 -+:100E300018BF85F8DC4119F0100F03D02846214671 -+:100E4000F4F342F419F0020F13D0AB6B83F84D406A -+:100E5000EB6B83F84D4095F8CB3495F8CC2443EAFE -+:100E6000022323F080039BB285F8CB341B0A85F85C -+:100E7000CC3419F0040F03D028462146F8F388F744 -+:100E800019F0800F0DD095F8CB3495F8CC2443EAB7 -+:100E9000022323F010039BB285F8CB341B0A85F89C -+:100EA000CC342B6893F842308BB119F0600F0ED020 -+:100EB00019F0200F0CBFFF21002119F0400F284628 -+:100EC00049B214BF00226FF0000200F069FB062255 -+:100ED0000DF122004349E1F34FF0B5F8822144F2CD -+:100EE00021339A4217D00E3B9A4214D007339A42CC -+:100EF00011D010339A420ED0143B9A420BD00733D4 -+:100F00009A4208D010339A4205D025339A4214BF32 -+:100F10000027012700E0012705EB8706B46B0DF1E0 -+:100F200022012846224633F073DEB16BA061886946 -+:100F300010B937230B936EE0443050312822E1F38F -+:100F40001BF0B36BB7F1FF3F9B699F62BFD0D8F82E -+:100F50005C30179E43F00403C8F85C30224BF56008 -+:100F6000B3602846EDF7DAFF1B9A0AB1002313603D -+:100F70002B681E495869E1F32BF530B100210A4670 -+:100F8000E1F3E6F31A4BC0B218602B6819495869AF -+:100F9000E1F31EF530B100210A46E1F3D9F3164B17 -+:100FA000C0B218602B6815495869E1F311F530B1EA -+:100FB00000210A46E1F3CCF3114BC0B21860284679 -+:100FC0002DE0C04639AE820001AE820028AB0100A0 -+:100FD000D5A18100ADA181002D578100415781002D -+:100FE00019578100D8A80100B54282001CA9010050 -+:100FF000E8F4010028A90100E8F801003CA901007B -+:10100000ECF801001B9B0BB9184608E00B9B1B9EDC -+:101010000020336003E02846FFF792FAF2E70DB0B4 -+:10102000BDE8F08F20230360436040F23C7383608F -+:10103000092330B503618361073303623033836270 -+:101040000F230822036340F29E330424012500216C -+:1010500042618263C3640322A3F56773C460C56100 -+:101060004462C46244630164456402654166436549 -+:101070008465C265036630BD70B505460C4631B364 -+:10108000496D11B1C022E5F333F6D4F88C1039B1B3 -+:1010900028464FF43972E5F32BF60023C4F88C3060 -+:1010A000D4F8901031B12846C422E5F321F600238C -+:1010B000C4F89030E16929B128466822E5F318F6B2 -+:1010C0000023E36128462146B822E5F311F670BDFE -+:1010D00070B50D460446002800F0E580D0F81815DC -+:1010E00039B128464FF48472E5F302F60023C4F8C0 -+:1010F0001835D4F8201539B128464FF48472E5F339 -+:10110000F7F50023C4F82035D4F8B41439B12846D3 -+:1011100040F2AC42E5F3ECF50023C4F8B434D4F863 -+:10112000401531B12846AC22E5F3E2F50023C4F8BE -+:101130004035D4F86C1229B128460BF021D9002390 -+:10114000C4F86C32D4F8FC1431B128464022E5F3DF -+:10115000CFF50023C4F8FC34D4F8841671B12368A9 -+:1011600063B1DB6953B19B690C22013303FB02F2CB -+:101170002846E5F3BDF50023C4F88436D4F8BC1442 -+:1011800019B12846B422E5F3B3F5D4F8901421B18F -+:1011900028464FF4AE62E5F3ABF5D4F8581631B1FA -+:1011A00028463822E5F3A4F50023C4F85836D4F8CD -+:1011B000601639B128464FF49072E5F399F5002393 -+:1011C000C4F86036D4F8F81731B128460622E5F3A2 -+:1011D0008FF50023C4F8F837D4F8D81639B128466B -+:1011E0004FF48472E5F384F50023C4F8D836D4F8BC -+:1011F000E01631B128462422E5F37AF50023C4F83D -+:10120000E036D4F8EC1631B128466822E5F370F5E3 -+:101210000023C4F8EC36D4F8441731B12846EC2248 -+:10122000E5F366F50023C4F84437A16B21B12846E5 -+:101230004FF40672E5F35CF5616B79B1896A31B1FF -+:1012400080222846E5F354F5626B0023936228461A -+:10125000616B2C22E5F34CF500236363216821B117 -+:101260002846FFF709FF002323602369ABB1D3F8B9 -+:10127000F81028461822E5F33BF523690026D96FBC -+:10128000C3F8F86019B128465822E5F331F528462D -+:101290002169FC22E5F32CF526612846214640F61B -+:1012A000CC02E5F325F570BD2DE9F0411646B822D4 -+:1012B00007460D460BF002D9044610B940F2E93357 -+:1012C0002BE03846294668220BF0F8D8E06110B9C7 -+:1012D00040F2044321E0FFF7A5FE38462946C0222C -+:1012E0000BF0ECD8606510B940F2EB3315E03846EE -+:1012F00029464FF439720BF0E1D8C4F88C0010B9CC -+:101300004FF47B7309E038462946C4220BF0D6D847 -+:10131000C4F8900038B940F2ED33214633603846C6 -+:10132000FFF7AAFE00242046BDE8F0812DE9F04138 -+:10133000174640F6CC0280460E460BF0BFD8054655 -+:1013400000283BD02623C0F82838314640463A468C -+:10135000FFF7AAFF2860002800F018818F4B056076 -+:101360001B683146C0F89C30FC2240460BF0A6D8E2 -+:101370000446286110B940F2ED3306E1856031463C -+:10138000404618220BF09AD8C4F8F800B0B1404695 -+:10139000314658222C690BF091D8E06770B12B6967 -+:1013A0004046DA6F31462C32C3F880204FF4847205 -+:1013B0000BF084D8C5F8180518B105E040F2EE33FB -+:1013C000E3E040F2EF33E0E0404631464FF4847210 -+:1013D0000BF074D8C5F8200510B94FF47C73D4E035 -+:1013E0004046314640F2AC420BF068D8C5F8B40430 -+:1013F00010B940F2F133C8E040463146AC220BF060 -+:101400005DD8C5F8400510B940F2F233BDE0314671 -+:101410004046EDF76DFF0146C5F86C0210B940F289 -+:10142000F333B2E028461DF099DB404631464022B6 -+:101430000BF044D8C5F8FC0410B94FF47D73A4E058 -+:101440002B680C22DB6940469B693146013303FB64 -+:1014500002F20BF033D8C5F8840610B940F2F53328 -+:1014600093E040463146B4220BF028D8C5F8BC04BE -+:1014700010B940F2F63388E0404631464FF4AE6290 -+:101480000BF01CD8C5F8900410B940F2F7337CE09B -+:101490002A464FF4AE71D5F89034CB1801F5AE71F1 -+:1014A000C2F894340432B1F5AE6FF4D140463146FF -+:1014B00038220BF003D8C5F8580610B94FF47E73E4 -+:1014C00063E0404631464FF490720AF0F7DFC5F80A -+:1014D000600638B14046314606220AF0EFDFC5F813 -+:1014E000F80710B940F2F9334FE0404631464FF467 -+:1014F00084720AF0E3DFC5F8D80610B940F2FA3377 -+:1015000043E04046314624220AF0D8DFC5F8E00621 -+:1015100010B940F2FD3338E04046314668220AF007 -+:10152000CDDFC5F8EC0610B940F2FE332DE04046A1 -+:101530003146EC220AF0C2DFC5F8440710B940F288 -+:10154000FF3322E0404631464FF406720AF0B6DF20 -+:10155000A86358B100F58673EB63404631462C22F0 -+:101560000AF0ACDF0446686318B105E040F20143BD -+:101570000BE040F2024308E04046314680220AF088 -+:101580009DDFA06238B940F203433B6028464146E4 -+:10159000FFF79EFD00252846BDE8F081BC2600002F -+:1015A000D0F84031B1F1FF3F18BF83F89C13B2F17E -+:1015B000FF3F83F89E1383F89F2318BF83F89D2372 -+:1015C0007047C04670B50446002831D00025631925 -+:1015D000D3F8501221B12368F4225868E5F388F358 -+:1015E0000435282DF3D1A16B69B194F8A3331BB155 -+:1015F00023689868EEF332F02368A16B9868EEF3E5 -+:101600003FF00023A363D4F8781221B12368E822C5 -+:101610005868E5F36DF3236806491868224602F01E -+:1016200093DC2368214658684FF46972E5F360F350 -+:1016300070BDC046678986002DE9F0434FF469719B -+:1016400085B006464068E5F343F3054608B9814690 -+:10165000CFE000214FF469728146E0F3F1F42E608F -+:101660007068E821E5F334F3C9F87802002800F047 -+:10167000B1800021E822E0F3E3F4002101236A189D -+:10168000C91808299372F9D1013B2B746B742B7321 -+:10169000EB721A460121AB185218082A83F89413EA -+:1016A000F8D14023EB74062385F827304FF0FF3341 -+:1016B00085F82830213385F8A233052385F82930B1 -+:1016C0004FF47A736B864FF0C803AB86002385F81E -+:1016D0002A30023385F82B302B682A75A9741B68D1 -+:1016E0002A4693F8A1308B4218BF032385F82C308B -+:1016F0004FF0FF3385F89E3385F89F334FF4006336 -+:10170000EB63012385F82D3004336B750223AB7531 -+:101710006B7DD375AB7DD377013205F108039A4217 -+:10172000F6D100244FF0010895F82910284685F8D5 -+:101730002E4085F82F800BF0A5D9284686F8C38463 -+:101740000CF0C0DF042130462C4A2D4B009401954B -+:1017500006F0DEF8A04268603CDB2A4B306800935C -+:10176000294B2A4901932A4B2A4A03932B46029478 -+:1017700002F0B2DB074668BBB06827492A463B4601 -+:10178000EDF39AF7A86328B3244C85F87C82231DD7 -+:1017900093E807006B4683E807002A462368304633 -+:1017A000062109F063DA4FF0FF3385F8A13333687F -+:1017B000284693F842100DF0E5DFC823C5F8E03263 -+:1017C00028460DF0C5D928464146EDF7DDFB85F8E2 -+:1017D000A3730EE0D5F8781219B17068E822E5F32A -+:1017E00087F2706829464FF46972E5F381F24FF091 -+:1017F0000009484605B0BDE8F083C04695CB82009D -+:101800001DCB820045CF82007186000050AB0100E5 -+:1018100079D98200678986008D85000040AB010080 -+:1018200070B5182686B00C46324668460549E0F386 -+:10183000A3F32046694632466D46E0F39DF306B0B9 -+:1018400070BDC04698AD010070B5D0F8AC530446E9 -+:10185000D0F8B063284600F079F8D4F8D013A8681F -+:10186000EDF3FCF6A868D4F8D013EDF309F70023E4 -+:101870002246C4F8D0333046044902F065DBF068F4 -+:1018800021464FF47E72E5F333F270BDAB998600CA -+:101890002DE9FF413C23C1F824370523C1F828373F -+:1018A00007460D46C0684FF47E71E5F311F2044619 -+:1018B00000283DD000214FF47E724FF00008E0F385 -+:1018C000BFF3C4F8AC53C4F8B07384F80180204669 -+:1018D000E6F7F0FFC4F8C003284600F04DF80646CE -+:1018E00038B1F86821464FF47E72E5F301F24046C4 -+:1018F0001FE0204604F56371FFF792FFA8680E49C8 -+:1019000022463346EDF3D8F6C4F8D00380B1204622 -+:1019100010F05CDF094B38460093094B09490193ED -+:10192000094A23460296039602F0D6DA204600E0E2 -+:10193000002004B0BDE8F0818D258300858900007A -+:10194000F9E9000048AC0100AB99860070B5D0F809 -+:10195000305704466DB107492246006802F0F4DAB8 -+:10196000606829464FF40A62E5F3C2F10023C4F827 -+:10197000303770BD529E86002DE9FF4106464FF478 -+:101980000A614068E5F3A4F1074618B9C6F83007C4 -+:101990000138E1E000214FF40A62E0F351F307F16E -+:1019A00020033B603368082200247A613C61DC211B -+:1019B0001A6630466A4A6B4B0094019605F0A8FF00 -+:1019C000A042B86105DA3046FFF7C0FF6FF00100B2 -+:1019D000C2E0A6462546644B00221EF0010FEA50E5 -+:1019E0001FD0624B19780D2902DD4FF4004C03E043 -+:1019F0004A1C012303FA02FC5C4BD8780D2802DD57 -+:101A00004FF4004403E0421C012313FA02F40123C3 -+:101A100013FA00F28B401A4342EA0C02524B224363 -+:101A2000EA501EF0020F24D04F4B55F803804F4B65 -+:101A300058780D2802DD4FF4004C03E0421C0123CE -+:101A400003FA02FC494B99780D2902DD4FF400445A -+:101A500003E04A1C012313FA02F4012313FA01F2F2 -+:101A600083401A4342EA0C0222433F4B42EA0802F7 -+:101A7000EA501EF0040F24D03B4B55F803803B4B3B -+:101A800018790D2802DD4FF4004C03E0421C0123BD -+:101A900003FA02FC354B59790D2902DD4FF400445D -+:101AA00003E04A1C012313FA02F4012313FA01F2A2 -+:101AB00083401A4342EA0C0222432B4B42EA0802BB -+:101AC000EA501EF0080F24D0274B55F80380274B0F -+:101AD00098790D2802DD4FF4004C03E0421C0123ED -+:101AE00003FA02FC214BD9790D2902DD4FF40044A1 -+:101AF00003E04A1C012313FA02F4012313FA01F252 -+:101B000083401A4342EA0C022243174B42EA08027E -+:101B1000EA500EF1010E0435BEF1100F7FF45BAFF9 -+:101B2000134B0025134C03932946134A3346306860 -+:101B300000950195029502F0CFD9231D93E8070087 -+:101B40006B4683E80700304623680321324609F0DC -+:101B50008DD8C6F83077284604B0BDE8F081C0467D -+:101B600001578300A15683008427000090E0850080 -+:101B70009D508300ECAD0100529E860010B50446D6 -+:101B80000846B0F80CE0194642F256039E4506D8C6 -+:101B9000013B9E452ED2053B9E4509D02AE042F2EC -+:101BA00060039E451BD04EF2F5439E451CD021E0BC -+:101BB000C389012B04D16FF03B0313604B3303E067 -+:101BC0006FF0450313605A330B602368D3F88030FD -+:101BD00013F4805F13D01368023B13600FE06FF0C3 -+:101BE0004A0313605A3309E06FF09503136003F55D -+:101BF000967303E06FF04A0313605F330B6010BD10 -+:101C000070B504460025E06820B1054B1B68984775 -+:101C10000023E36001350434062DF4D170BDC046C5 -+:101C2000E0A685000D4B82685362002380F8863061 -+:101C30004FF00303A0F88C304FF00203A0F88E3071 -+:101C40004FF00703A0F888304FF00403A0F88A3063 -+:101C500042F60133A0F89C307047C04664A8E7BE46 -+:101C6000426C1F2A01D9002004E04FF00073134199 -+:101C700003F001007047C046026EB0F84A1010B57C -+:101C8000946AB9B1FF2901D8012014E00B0B013B84 -+:101C9000012B0FD8C1F30323092B0BD853B1C1F388 -+:101CA0000313092B06D801F00F03092B8CBF00206A -+:101CB000012000E00020D26A41F2E4439A4210D1B0 -+:101CC000A4F58263073B012B01D83F2907E040F2CE -+:101CD0000C439C4204D015339C4202D1502900D8B9 -+:101CE000002010BD00B58E46C16E4FF04073944683 -+:101CF0007046C1F8603115E00379C2781B0443EAED -+:101D0000026382791343427943EA0223C1F86431C2 -+:101D1000437802781B0243EA024382780730134378 -+:101D2000C1F86431CEEB00036345E5D300BDC04686 -+:101D300010B590F85E3004463BB9044B04491A686C -+:101D4000FFF7D0FF012384F85E3010BD789E0200BB -+:101D50007C9E0200C16E4FF48030C1F860011D4AC4 -+:101D6000D1F8603110B5D1F86441C1F86001D1F803 -+:101D70006031C1F86421C1F86001D1F86031D1F857 -+:101D80006431934224D1144AC1F86001D1F8603122 -+:101D9000C1F86421C1F86001D1F86031D1F8643133 -+:101DA000934215D1C1F86001D1F860310023C1F828 -+:101DB0006441C1F88C31D1F82001084B984201D11F -+:101DC000012006E0064B984214BF0020012000E0ED -+:101DD000002010BDAA5555AA55AAAA550004000412 -+:101DE00000040084D0F8501810B5044641B1D0F872 -+:101DF0004C2840689200E4F37BF70023C4F8503885 -+:101E0000D4F8481859B16068E0F3CEF66068D4F8A9 -+:101E10004818E822E4F36CF70023C4F8483810BDF2 -+:101E200070B504690646206E08B1E9F78DF82046C2 -+:101E3000FFF7E6FEA56F686A18B103F0FFFF002305 -+:101E40006B62606F03F08CFF206F05F023FC616E06 -+:101E500029B12068A26EE4F34BF700236366206E7D -+:101E600018B103F0D9F9002323662046E8F728F9D2 -+:101E70003046FFF7B7FF002070BDC0462DE9F04F98 -+:101E8000036807698FB00890DE691446FB6B0CA8E5 -+:101E90000821704AE0F318F1FB68002B40F0CE8077 -+:101EA000F96E386E01F50071D7F800B0E2F3FCF47A -+:101EB000BB6801469868EDF395F3002800F0C680F2 -+:101EC000D7F860E00CB9A44602E0FB6E03F5007C95 -+:101ED000FB6E03F5087504B13468B168BB687268BD -+:101EE000F068D3F8283803915B490DF130094FF0C1 -+:101EF000FF38029205907246069307916346494661 -+:101F0000584600950194CDF81080EDF71DF8316822 -+:101F1000F8603A6EFB6E01914F4900240546079127 -+:101F200003F5107349465846009402940394CDF883 -+:101F3000108005940694EDF707F8316838613A6E21 -+:101F4000FB6E019144490990079103F520734946BE -+:101F50005846009402940394CDF81080059406949A -+:101F6000ECF7F2FF316878613A6EFB6E01913A4905 -+:101F70000A90079103F5307349465846009402943D -+:101F80000394CDF8108005940694ECF7DDFF3168DA -+:101F9000B8613A6EFB6E01912F490B90079103F5E2 -+:101FA000407349465846009402940394CDF810803B -+:101FB00005940694ECF7C8FF3168F8613A6EFB6E41 -+:101FC000019125498246079103F5507349465846C9 -+:101FD000009402940394CDF8108005940694ECF7D5 -+:101FE000B3FF099AA54214BF002501250A9BA2420E -+:101FF00008BF45F001050B99A34208BF45F0010554 -+:10200000A14208BF45F00105A24508BF45F0010502 -+:102010003862A04214BF284645F00100B0B90F4B0A -+:102020003C46D3F884600546E06818B10C49B047D7 -+:10203000C4F8A00001350434062DF5D1B96F089815 -+:1020400008310022E7F7FAFB012000E000200FB082 -+:10205000BDE8F08FFB41860014260000E0A6850055 -+:10206000C32686001FB5022303930D330446C0F830 -+:102070004C383C214068E4F32BF6C4F85008D0B14A -+:10208000D4F84C2800219200DFF3DAF76068E821E9 -+:10209000E4F31EF6C4F8480868B10021E822DFF333 -+:1020A000CFF7012300936068D4F8481803AAB3332C -+:1020B000E0F312F601E04FF0FF3004B010BDC0466F -+:1020C0002DE9F04F056997B0DDF884A014469B46D2 -+:1020D0009DF88020EB63EB6FA860AB672A71074621 -+:1020E000C5F800A028460E46FFF79CFD249B05F18D -+:1020F000640205F168010093019202912046514665 -+:10210000229A239B03F0C6F92866002800F0D581A7 -+:10211000D5F8648095494046E0F35AF420B1002197 -+:102120000A46E0F315F386B240469149E0F350F4D5 -+:1021300048B100210A46E0F30BF34FF6FF7380B27B -+:10214000984218BF044630462146FDF7CFFE08B935 -+:102150000C30B7E140F612010022A5F84060A5F866 -+:102160004240286EE9F34AF0E866286EE8F398F6F4 -+:10217000D5F86C906864C7F80C902846FFF770FD9E -+:1021800008B90D309EE1286EE8F7E2FE28460021EE -+:1021900019F0A2DD28464FF0FF31E7F78DFB284606 -+:1021A000FFF7D8FD08B90E308CE140467149E0F3E5 -+:1021B000E3F3FF2808BF0120A5F84A002846FFF7EF -+:1021C0005BFD08B90F307DE16B494046E0F3D4F385 -+:1021D0006A4985F848004046E0F3CEF36849E86470 -+:1021E0004046E0F3C9F3296E2865CA6A41F26B03E1 -+:1021F0009A420AD18B6A4E2B07D1B5F84A30402B50 -+:1022000003D9EB6C43F00203EB64EB6C13F0200F8B -+:1022100004D0012128460A461BF014D9B5F8402005 -+:102220000123A7F88021C5F89830B5F842303A6804 -+:10223000A7F882312B6E284613616B6C936095F87A -+:10224000483082F87C303A68B5F84A30B968A2F86C -+:102250007A30EB6CC2F880302B6DC2F88430D5F840 -+:10226000983053623A4605F01FFA286708B91930CA -+:1022700028E12B6ECDF810A005932B6FCDF81CB084 -+:10228000B5F8402006936B6CADF8302008932A6EA9 -+:10229000B5F84230CDF82C80ADF83230936B04A8FD -+:1022A0000D93D36B0E93136C0F9395F848301093E6 -+:1022B000936A1193B5F84A301293D36A1393EB6C77 -+:1022C00014932B6D159353680993D3680A9303F005 -+:1022D0004FFD686708B91030F4E0B5F8421044F2D9 -+:1022E0002133994217D00E3B994214D007339942BB -+:1022F00011D0103399420ED0143B99420BD00733C2 -+:10230000994208D01033994205D02533994214BF21 -+:102310000026012600E0012631462846E7F7B0FAFC -+:10232000AA6F002E0CBF02230123136056603A6B84 -+:10233000286E13605660FC6AE8F3A0F52060D9F8B7 -+:102340005C31696C0F4A6B65AB65062301FB0323A7 -+:10235000AC6FC5F8B830686F49462268434603F051 -+:102360009FFE606280B91130ACE0C046D1AD8600FE -+:102370004837860084AE8600E5AE86008637860044 -+:102380009E79860020ED0100AB6F696D586AEDF70C -+:102390008DFEAB6F03F1220203F11C01586A00921B -+:1023A00003F11E02203303F0C3FCAC6F606A03F03C -+:1023B000CFFC84F82800AB6F3C6B586A03F0C8FC74 -+:1023C0002075AC6F606A03F0C7FCA96FA061CB8B6E -+:1023D000032B01D0122075E03B6B4A6A38461A6124 -+:1023E0008A8B1A81CA8B5A810A8C9A814A8CDA812B -+:1023F00040F2FF324FF00F03CA828B820122314636 -+:10240000FFF73CFD08B913305CE0B6F1FF3F3FF445 -+:1024100064AFAB6F3A68586A92F89910EDF74AFECC -+:10242000002128461AF040D90821284619F0C2DFB9 -+:1024300028461BF071DC286E2449254A00230097AA -+:10244000E8F398F6284600211BF048DC2846E7F719 -+:10245000E1F908B9153035E005F1DC042146E0F377 -+:10246000ABF02046E0F368F248BB2046E0F374F29C -+:10247000044620BB284619F077DAAB681B68D3F80E -+:102480009C00F0B10378E3B112492A46E0F378F3F7 -+:10249000AB6811491B682A46D3F89C00E0F3AAF305 -+:1024A000A868FFF7DFFDE86858B1AB681B68D3F890 -+:1024B0009C10E2F39DF3204604E00B2002E016207E -+:1024C00000E0002017B0BDE8F08FC04669C183006E -+:1024D00085C1830025C0830049C0830010B5044630 -+:1024E0001DF04ED90122014620461DF0C1D910BD74 -+:1024F00037B505461DF044D90023C5F84C0280F8D5 -+:1025000048302A68044692F82F10284600914E322F -+:1025100021461BF0E3DE30B1284621461CF08CDF5B -+:102520004FF0FF3003E0284621461DF02BD83EBD7A -+:1025300037B50446002847D0D0F8201131B10368E0 -+:102540009868EDF39DF00023C4F8203122681368E9 -+:1025500093F82F303BB3D2F8000501A932F0BADD71 -+:1025600013E0536813F0400F0FD0D4F82C31D51876 -+:1025700007E00B684822C5F8103123685868E4F377 -+:10258000B7F3D5F810110029F3D101A832F0AADD74 -+:1025900002460028E5D106E00B684068C4F84031E7 -+:1025A0004822E4F3A5F3D4F8401120680029F3D1C0 -+:1025B00006492246006801F0C7DC236821465868B6 -+:1025C0004FF4A472E4F394F33EBDC04691BA860082 -+:1025D000F0B54FF4A47185B005464068E4F378F394 -+:1025E000064608B9074655E000214FF4A472074695 -+:1025F000DFF326F5294B35600093294B29490193D8 -+:10260000294B002403932868284A3346029401F09A -+:1026100063DC31462A6B1368022B03D1537D0BB95F -+:10262000163300E0302301340B744431042CF1D113 -+:10263000A8681F492A460023EDF33EF00446C6F879 -+:10264000200130B9686831464FF4A472E4F350F3C6 -+:102650001FE04FF49673C6F81C3145F27353A6F889 -+:1026600038314FF04603A6F83A31124B0024C6F831 -+:102670004041284600934FF48A710F4A0F4B019551 -+:1026800005F046F9A042C6F82C0103DA3046FFF700 -+:102690004FFF2746384605B0F0BDC046F90C840010 -+:1026A00055ED00001CAE01007D0A840091BA860041 -+:1026B0003D068400D9128400E5128400A51284002E -+:1026C00070B50568044622462868044901F03CDCE0 -+:1026D000686821465022E4F30BF370BD3CE48600A9 -+:1026E00070B50546002826D00368134918682A46A5 -+:1026F00001F02ADC6B6905E01C68596828462EF059 -+:102700000DD92346002BF7D12B6905E01C685968C9 -+:1027100028462EF003D92346002BF7D1A96A21B110 -+:102720002B6890225868E4F3E3F22B682946586836 -+:102730002C22E4F3DDF270BD91E6860030B52C2149 -+:10274000044685B04068E4F3C3F208B9054618E0D2 -+:1027500000212C220546DFF373F40823AB610A4BFA -+:102760002C6000930023019302930393074A2B46A6 -+:102770002068074901F0B0DB2268012382F8963017 -+:102780002B71284605B030BD050B850091E686000B -+:1027900094AE01002DE9F047154680460F461E46CF -+:1027A000E8F36CF3002181464046E8F339F5002256 -+:1027B000044611460F480B185B6873B90C3302FBD3 -+:1027C00003F31D501A18636A576096600A4A45EA77 -+:1027D000030313606362012404E001320C31052A13 -+:1027E000E8D1002440464946E8F31AF52046BDE802 -+:1027F000F087C0463C260000782600002DE9F0470F -+:1028000005468846E8F376F400212846E8F308F503 -+:10281000064628466C69AF69E8F7D2F90A2C81466A -+:1028200016D90F2C19D02846E8F70CFC142C0546B5 -+:1028300003D9B36823F00803B360B36843F001031E -+:10284000B36003D9B36843F00803B360012211E019 -+:10285000022C02D8174D30220CE02846E8F7FCFB8A -+:10286000D6F8A430054623F0FF0343F00203C6F870 -+:10287000A4300222B36813F0010F07D107F0180348 -+:10288000082B14BF4FF4E115B5FBF2F507F0030771 -+:1028900000240BE006F54073B8F1000F05D003EB00 -+:1028A000042049462A460023C0470134BC42F1DBDC -+:1028B000BDE8F08700C63E0537B5134B15461360DB -+:1028C00001E0114B13600432ADF17C039A42F8D35E -+:1028D000033020F003000D4BC0EB01041C600C4BD7 -+:1028E000002119600B4B05F5A05219600A4B083CFA -+:1028F00019600A4B41601D60094B1A60094B196051 -+:10290000094B046058603EBD4B415453C82600003B -+:1029100088260000A4260000CC260000F4F4010064 -+:10292000F8F4010090260000C0260000436910B5AD -+:10293000142B01DD02F09CFB10BDC0461FB5E82042 -+:102940000021E3F363F50C4C2060A0B10021E822E4 -+:10295000DFF376F304AA012342F8043D013B009320 -+:10296000064B2168186840F23C73E0F3B5F120682B -+:102970000F21E0F3FBF11FBDBC26000020F5010094 -+:10298000B1F5E06F73B505460C46164606D10369EE -+:102990000091002101911C680A460CE00D4B0022B9 -+:1029A0001868E8F32BF4014680B12B6900220094EB -+:1029B00001921C6828463346A04738B1064AA861F0 -+:1029C000136800202B626E61156001E04FF0FF304C -+:1029D0007CBDC0468C2600001CF501002DE9F047A7 -+:1029E00010200E46002117469946E3F30FF50446E2 -+:1029F00010B96FF01A001EE0104D2868E8F33EF29F -+:102A0000099B804623B9286831463A46E8F3F6F335 -+:102A10002868E8F3AFF201238340094AE360089B8A -+:102A2000C4F80490A36013682868236041461460CA -+:102A3000E8F3F6F30020BDE8F087C0468C260000DE -+:102A40009826000007B50021E8F3EAF3074B4FF49E -+:102A500000611860064B00F57060186000200246A7 -+:102A6000044B00900190FFF7B9FF0EBD9C260000BB -+:102A7000F0F401006D60800037B5234B234C02ADAC -+:102A800000211C2245F8043D2046DFF3D9F2012342 -+:102A900023601F4BA5F5A0551B6843F8044C00F0BC -+:102AA0000DF929462A461B48FFF706FFE3F36AF6AD -+:102AB00000F042F8002002F01FFA174B174C186084 -+:102AC00002F0BCFC2060FFF7BDFF206800F01EF99B -+:102AD000E7F700FF206800F0A5F800221048114930 -+:102AE000E4F308F0002210481049E4F303F0104921 -+:102AF00000221048E3F3FEF72068FFF717FFFFF707 -+:102B00001DFF20683EBDC046ADDEADDEFCF4010019 -+:102B1000E8ED0100BE24030020F501008C26000032 -+:102B2000D81F8600E1A60000DB1F860065658000D7 -+:102B30008D608000DE1F860070B5A4200021E3F3C5 -+:102B400065F4124D286080B10021A422DFF378F2F1 -+:102B50004FF4806000212C68E3F358F4A0602868EB -+:102B600084682CB9E3F3B8F32C604FF0FF300CE02D -+:102B70004FF48062C2608460446100212046DFF32C -+:102B80005FF22A68024B00201A6070BD34F5010024 -+:102B9000D426000070B51C4D06462B6833B91B4C7B -+:102BA00023680BB9FFF7C8FF23682B60164C184B3E -+:102BB0002068586130B3002505604560336CC0F86B -+:102BC0009C500E3B012B03D930461249FFF716FEED -+:102BD000114A936813B12368C3F89C20246807E066 -+:102BE000D4F89C0018B1A368595DE3F36FF7013581 -+:102BF00023699D42F4D3094809492246E3F37AF751 -+:102C0000014B186870BDC046D426000034F50100A1 -+:102C1000FCF40100492C020024F50100BD218600CE -+:102C2000A568800010B54022002305490446FFF73F -+:102C3000B1FD044B00229A602046FFF7ABFF10BDA8 -+:102C4000A969800024F5010070B51B4DAE68002E07 -+:102C500031D114092C60AB8104F561444FF4E133A8 -+:102C600094FBF3F4A8606960284603218022E3F313 -+:102C700023F728463146E2B2E3F31EF72846012146 -+:102C80002212E3F319F703210A462846E3F314F767 -+:102C900001210A462846E3F30FF7284604210822BB -+:102CA000E3F30AF7284602210122E3F305F74FF484 -+:102CB0007A70E3F351F570BD24F50100104A072145 -+:102CC000136843F010031360136843F008031360A4 -+:102CD000136823F400731360E832136843F08073C1 -+:102CE00043F480331360074B00221960043B1A60E1 -+:102CF00008331A681960044B20221A607047C046D6 -+:102D000014ED00E0241000E000E400E02DE9F041C3 -+:102D1000054600F0ADF82A48E7F762FB2846E7F7DA -+:102D200025FF284B284AC318B3FBF2F3274A28464D -+:102D30001360E8F77DF900F5787007304FF47A7387 -+:102D4000B0FBF3F0224B234A18602B6A2249002B78 -+:102D5000CCBF6FF07F4340F2FF3313601D4A1F4F1B -+:102D60001368B3FBF0F31360284620220023FFF71B -+:102D700011FD00201A49DFF3FFF504463860E8B181 -+:102D80002846E7F7F3FEB4FBF0F0861E002E15DDB3 -+:102D9000144C002134222046DFF352F1124B4FF441 -+:102DA0007A71A3606560204606FB01F10122E3F31E -+:102DB00021F218B128463968E1F32CF5BDE8F0811D -+:102DC00019A900003F420F0040420F00D02500002B -+:102DD000C8250000CC25000001678000E82600001F -+:102DE0004EB001003CF50100E56680002DE9F0479A -+:102DF00007461E4615460C46E8F37CF13846E8F3D4 -+:102E00003DF02946324681463846E8F3F7F1384628 -+:102E1000E8F3B0F040F62A01064600223846E8F30F -+:102E2000EDF105468CB1012414FA06F3826932EA09 -+:102E3000030802D12046E7F793FA701C14FA00F059 -+:102E4000E7F770FAC5F818800CE00124701C14FA3A -+:102E500000F0E7F785FA2046B440E7F763FAAB697C -+:102E60001C43AC6138464946E8F3DAF1BDE8F08727 -+:102E70002DE9F0470746E8F33DF1384640F60E01EC -+:102E80000022E8F3BBF10446002831D0D0F80080DE -+:102E900005683846E8F304F00428064604D827D12C -+:102EA000C5F30243032B23D100204849DFF364F527 -+:102EB000F0B94749C8F3031212E0013A072E226124 -+:102EC0000AD90C2E08D0236C13F4806F02D013F4AF -+:102ED000006F01D108B903E0012041F004516161A4 -+:102EE000002AEAD1D4F8E83123F01003C4F8E8311D -+:102EF000002240F62A013846E8F380F1354C206084 -+:102F00003846E7F3CDF7344B22681860136843F670 -+:102F1000A12443F080731360136843F0020313602D -+:102F20000023C2F8E03103E00A20E3F315F40A3C81 -+:102F3000DFF8A090D9F80030D3F8E03113F4003F67 -+:102F400001D1092CF0D100210B4638464FF4006224 -+:102F5000FFF74CFF00210B46384640F61202FFF700 -+:102F600045FF00210B46384640F62902FFF73EFF99 -+:102F700038460121E7F728FE00201849DFF3FCF46A -+:102F8000E0B13846E7F37AF740F62A01804600229E -+:102F90003846E8F333F146690446D0F8985038468D -+:102FA000E7F36CF70123834045F001053343636188 -+:102FB0003846C4F898504146E8F332F1D9F8002079 -+:102FC000136A43F003031362BDE8F087BDB001004C -+:102FD000FF7F010070F5010074F501004EB00100A3 -+:102FE00010B58469A068FCF783FDE068E7F790FFFF -+:102FF000002010BD10B584690021342204F11C00AA -+:10300000DFF31EF0034BA06863622462ECF7ACF8B8 -+:10301000002010BD05AA80002DE9F347DFF8AC8041 -+:103020009946D8F800300546072B0F46924643DCF8 -+:1030300001F062FF50210646E3F34AF604460028F9 -+:103040003AD000215022DEF3FBF7D8F8003065605B -+:103050002360A4F814902761E660204641F2E44121 -+:103060004A4633460097CDF804A0FCF793FDA060D4 -+:1030700010B300200A990B9A114B0095CDF804A0CB -+:10308000FFF7ACFC18B1A068FCF732FD14E0A068B3 -+:10309000E6F3DAF10B49A061D8F800202846DFF307 -+:1030A00023F009482946ECF709F8D8F80030204603 -+:1030B0000133C8F8003000E00020BDE8FC87C046BE -+:1030C00031AA8000FC7C0200DC7C020078F5010063 -+:1030D000014610B550228068E3F30AF610BDC046E1 -+:1030E000C36B10B51BB100225A62836B5A62C06871 -+:1030F000FFF7EEFF10BDC0462DE9F041184E1C460B -+:1031000033780746072B904626D820464C21E3F318 -+:10311000DFF5054600B300214C22DEF391F76C6029 -+:103120002F60C5F808803378204685F84430013395 -+:1031300033700223AB640821E3F3CAF50446286424 -+:1031400020B100210822DEF37BF706E029464C225D -+:10315000E3F3CEF5254600E000252846BDE8F081E2 -+:103160007CF501002DE9F04FD1F8FC3091B00F93C0 -+:10317000054603F56063079335E10FAF0E22002388 -+:1031800028463946DDF3A0F10F28044600F03681C9 -+:103190000022284639461346DDF396F110F00E065C -+:1031A00040F0268140F23B43B3EB145FC4F30B21A4 -+:1031B000C0F3041804D140F6FF73994200F0138164 -+:1031C000C0F344220992002A00F00D81C0F3C443E9 -+:1031D000C0F3843B13EB0B02089319D140F2673321 -+:1031E000994240F000810EAB01930DAB02930CAB02 -+:1031F00003930BAB04932846394613460092DDF344 -+:1032000001F1002800F0EF800E9BC5F85433EAE08E -+:10321000D5F8CCA005EB8A03C3F8D4423446C3F8F2 -+:103220001403C3F8D0100BE00122284631461346A0 -+:10323000DDF34AF100F00E00022840F0D98001349D -+:1032400044450FAEF0D1002213460DF138090DF1BF -+:1032500034080CAF0BAC284631460092CDF80490F0 -+:10326000CDF8088003970494DDF3CCF00246E8B96A -+:1032700040230093284631461346CDF80490CDF8FC -+:10328000088003970494DDF3BDF010B14FF00108FE -+:103290000EE00D9B002B40F0AB800B9B002B40F011 -+:1032A000A7800C9BB3F5805F40F0A2804FF0000830 -+:1032B0000E9A05EB8A03C3F810210C9A0124C3F877 -+:1032C000D0210EAB01930DAB02930CAB03930BAB70 -+:1032D0000022049328460FA923460092DDF392F0C2 -+:1032E00008B9012727E0012C40F086800C99B1F540 -+:1032F000805F40F081800E9B05EB8A02C2F890311E -+:10330000C2F8101278E00024002300930EAB019362 -+:103310000DAB02930CAB03930BAB049328460FA9A0 -+:103320003A462346661CDDF36DF008B13446EBE700 -+:10333000002E5DD00137099A9742E4D100241FE0A6 -+:10334000C02300930EAB01930DAB02930CAB039320 -+:103350000BAB049328460FA922460023DDF352F05D -+:10336000002845D00B9B002B42D10C9BB3F5805F0E -+:103370003ED124B90E9B05EB8A02C2F89432013487 -+:103380005C45DDD1002423E0802300930EAB019344 -+:103390000DAB02930CAB03930BAB049328460FA920 -+:1033A000012F0CBF2246621C0023DDF32BF0F8B185 -+:1033B0000B9BEBB90C9BB3F5805F19D1BBF1000FF0 -+:1033C00005D124B90E9B05EB8A02C2F89432013470 -+:1033D000089B9C42D8D1B8F1000F04D1D5F8CC306D -+:1033E0000133C5F8CC300F9B079A9342FFF4C5AE6A -+:1033F0000023C5F8CC3001E0013462E711B0BDE82C -+:10340000F08FC04682604160016070470EB4F3B532 -+:1034100081680646012901D8002044E008AB4068D5 -+:10342000079A0193DEF342F7B0F1FF3F074603D05E -+:10343000B368023B984203DD00231846B36032E0D4 -+:1034400070683D21DEF360F630B373683568C3EB16 -+:1034500000041EE028462246DEF372F5A8B92B5D73 -+:103460003D2B12D12846DEF37BF67268441CBA1855 -+:10347000291901322846521ADEF3B4F573681B1B72 -+:103480007360B3681B19B36006E015F8013B002BAD -+:10349000FBD171688D42DDD3B368781C1B1AB36011 -+:1034A00073681B187360BDE8FC4003B07047C046EA -+:1034B0002DE9F041C1EB0204012C0E461F46DDF858 -+:1034C000188010DD2146E3F303F4054610B96FF0D0 -+:1034D0001A000DE031462246DEF34EF500203D6035 -+:1034E000C8F8004004E000233B60C8F800301846EC -+:1034F000BDE8F0812DE9F04FA5B008914FF480515F -+:10350000099007920693E3F3E3F30A9018B96FF07A -+:10351000010401F029B921A80A994FF48052FFF75C -+:1035200071FF4FF480520A980021DEF389F50023E1 -+:103530004FF0FF328DF844300B930D930E9201F053 -+:10354000DEB80D9B089A002152F8239001230C91BC -+:103550000F930F9B19F8012073B1531EDBB2FD2BA3 -+:1035600001F1010898BF19F808B016468CBF4FF05A -+:10357000000B08F101080CE002F1FF33DBB2FE2B77 -+:1035800093462CBF1646802628BF4FF0000B01F152 -+:1035900001080BEB0803B3F5607F81F2AD80202EAC -+:1035A0002AD005D8152E0AD01B2E6DD001F078B880 -+:1035B000222E3AD036D3802E72D001F071B808EBAB -+:1035C00009035A7819F8083003EB0223072B13DD9F -+:1035D00009F10204444421AD874922462846FFF7F9 -+:1035E00015FF2046DEF3BCF509F1030200EB0803EA -+:1035F00082492846D2184FE008EB0904637819F88D -+:10360000082021AD02EB032228467D49FFF7FEFE8C -+:10361000E378A27828467B4902EB0322FFF7F6FE07 -+:1036200001F03EB819F8082003E00C9B0C2B03D1E5 -+:1036300000220C9201F036B89DF84430002B41F086 -+:10364000318019F80830042B41F02C8009F1020474 -+:1036500004EB08052846DFF37FF1002841F02280C3 -+:1036600014F8083013F0010F41F01C80284611A90E -+:10367000DEF3BAF70E9BB3F1FF3F41F0138008EB86 -+:1036800009039A79DB790DE108EB0903DC799A7972 -+:103690005D4921A842EA0422FFF7B8FE01F002B812 -+:1036A00019F80830822B00F2FD87DFE813F0920052 -+:1036B000B30038013B02D4021102CB01DA01470109 -+:1036C000EA02FB0210031703FB077F020302FB075A -+:1036D0003603570397007A037F0390039503F7009F -+:1036E000E903FB07770107047F01FB07FB07FB07E3 -+:1036F00010042204270472045305FB07FB0721066C -+:103700008D0088008300AE06D306DA06E106FB07CB -+:1037100026037101FB07FB070001F007E806FB0722 -+:10372000FB07FB07FB07FB07FB07FB07FB07870103 -+:1037300013072807490764077F079907B307CD07D1 -+:10374000D407FB078E01FB07FB07FB07FB07FB0703 -+:10375000FB07FB07FB07FB07FB07FB07FB07FB0759 -+:10376000FB07FB07FB07FB07FB07FB07FB07FB0749 -+:10377000FB07FB07FB07FB07FB07FB07FB07FB0739 -+:10378000FB07FB07FB07FB07FB07FB07FB07FB0729 -+:10379000FB07FB07FB07FB07FB07FB07FB07FB0719 -+:1037A000FB07FB07FB07FB07FB07FB07FB07FB0709 -+:1037B000FB07DE0709EB0804002500F00BBE09EB50 -+:1037C0000804002500F0F4BD09EB0804002500F012 -+:1037D000DEBD0E4908EB090321A8DDE008EB090175 -+:1037E000CA780B79120442EA03624B7821A81A4383 -+:1037F0008B7807497EE2C046E07D02003C800200F3 -+:103800009E7D02003381020002840200797F020063 -+:10381000157D020008EB0904A378627821AE02EB63 -+:103820000322AE493046FFF7F1FD2379E2783046B6 -+:10383000AB4902EB0322FFF7E9FDBBF1060F40F2B3 -+:103840003187A37962793046A64902EB0322FFF75C -+:10385000DDFDBBF1080F40F22587237AE27930467F -+:10386000A14902EB0322FFF7D1FDBBF10A0F40F2A1 -+:10387000198709F10A0409F1090514F8083015F847 -+:1038800008209A4902EB03223046FFF7BFFD14F8E7 -+:10389000083015F80820964930464CE008EB09033B -+:1038A0009A785B7803EB02220E9200F0FBBE0623AF -+:1038B000904ABBFBF3F309EB08074FF0000A1370C3 -+:1038C00027E019AD534610218B4A1DAE2846DEF382 -+:1038D000FBF353461021894A3046DEF3F5F3BB78FB -+:1038E0007A7821AC42EA032229462046FFF78EFD72 -+:1038F0007A79BB79120442EA0362FB7820461A43C4 -+:103900003B79314642EA0322FFF780FD0AF1010AC2 -+:103910000637784B1B789A45D3DB00F0C3BEBBF16A -+:10392000020F21A808EB090202D175495278B3E6CB -+:1039300093787349527802EB0322ADE608EB090451 -+:10394000A2786378BBF1040F03EB022505D9237934 -+:10395000E2781B0603EB02431D4321AE3046694962 -+:103960002A46FFF753FDBBF1060F40F29B86A27972 -+:103970006379BBF1080F03EB022505D9237AE279BD -+:103980001B0603EB02431D435F4930462A4683E68C -+:103990005E4908EB090321A85A787DE608EB090384 -+:1039A0009C785A78524921A800F05BBE0BF10103C4 -+:1039B0005FFA83FB00230F9300F074BE08EB09034A -+:1039C0009C785A78524921A864E64A4B4FEADB02B8 -+:1039D00009EB08074FF0000A1A702DE01DAD5346A1 -+:1039E0001021454A19AE2846DEF36EF353461021E6 -+:1039F000424A3046DEF368F3FA783B79120442EA31 -+:103A000003627B7821AC1A43BB78294642EA032241 -+:103A10002046FFF7FBFCFA793B7A120442EA036284 -+:103A20007B7920461A43BB79314642EA0322FFF7ED -+:103A3000EDFC0AF1010A08372E4B1B789A45CDDBC5 -+:103A400000F030BE21AD08EB090428463149627808 -+:103A5000FFF7DCFCBBF1020F40F224862E4928461A -+:103A600059E121AD08EB0904002228462B4963786F -+:103A7000FFF7CCFCBBF1020F40F20F860122284673 -+:103A80002649A378FFF7C2FCBBF1030F00F00586BF -+:103A9000022228462149E378FFF7B8FCBBF1040F66 -+:103AA00000F0FB8528461D4903222379FFF7AEFC71 -+:103AB00000F0F3BD21AC08EB090517496A782046F0 -+:103AC000FFF7A4FC1549AB782046012200F0DCBDCD -+:103AD000134908EB090321A85EE7C046548202009F -+:103AE000158302005E810200AA7D0200C17E0200F1 -+:103AF000C17D02007DF50100C8B00100D3B0010016 -+:103B0000F67E0200D7820200227E0200F47F0200CD -+:103B10006A830200217D02004C83020021800200A2 -+:103B2000E5830200ABF10203082B00F2BB85DFE85E -+:103B300013F00900B905B905B905B9052B001C003A -+:103B400015000E00A74908EB090321A824E708EB9C -+:103B5000090321A8A4495A7AFFF758FC08EB090386 -+:103B600021A8A0491A7AFFF751FC09F1070521ACF9 -+:103B70009E4915F808202046FFF748FC20469C493E -+:103B800015F80820FFF742FC9A4D09EB0804A378CA -+:103B90006278294602EB032221A8FFF737FC964BF7 -+:103BA000093502349D42F2D100F07CBDBBF1140F07 -+:103BB00019D0BBF1170F04D0BBF1130F1AD000F0CE -+:103BC00071BD21AC08EB09058C49AA7D2046FFF7A1 -+:103BD0001DFC8B496A7D2046FFF718FC2046894969 -+:103BE0002A7DFFF713FC08EB090321A88649DA7C3C -+:103BF000FFF70CFC854D09EB0804A3786278294691 -+:103C000002EB032221A8FFF701FC814B09350234A6 -+:103C10009D42F2D109EB08057E4E2C46237AE279CB -+:103C2000314602EB032221A8FFF7F0FB7A4B0B365B -+:103C300002349E42F2D1794CAB7B6A7B214602EB87 -+:103C4000032221A8FFF7E2FB754B0B3402359C429F -+:103C5000F2D100F027BD08EB0901C8784A788B78CB -+:103C60000090087901904879029088790390C8798A -+:103C70000490097A21A805916A49FFF7C7FB00F073 -+:103C800011BD09EB080400256378FF2B04D021A89F -+:103C900065492A46FFF7BAFB01350134042DF3D1FB -+:103CA00000F000BD08EB09035A780AB19B7823B9EC -+:103CB00021A85E49FFF7AAFB03E021A85C49FFF7B2 -+:103CC000A5FB08EB09035B49DA7821A8E4E408EBDB -+:103CD00009039C785A78584921A8DBE408EB0901CC -+:103CE000CA780B79120442EA03624B7821A81A437E -+:103CF0008B78524942EA0322CEE421AD08EB090455 -+:103D000028464F496278FFF781FBBBF1020F40F272 -+:103D1000C9844C492846A278BEE409F1010515F88A -+:103D2000082021AC484902F00F022046FFF76EFB45 -+:103D300015F808204549120909F102052046FFF748 -+:103D400065FB15F80820424902F007022046FFF7FC -+:103D50005DFB15F808203F4920461FE009F10105E9 -+:103D600015F8082021AC3C4902F00F022046FFF76D -+:103D70004DFB15F808203949120909F102052046C2 -+:103D8000FFF744FB15F80820354902F007022046EA -+:103D9000FFF73CFB15F8082032492046C2F3C10268 -+:103DA0007AE4314908EB090321A8F5E521AC08EBD9 -+:103DB00009052E496A782046FFF728FB2C49AA7886 -+:103DC0002046FFF723FB2B49EA78204664E42A4982 -+:103DD00008EB090321A8DFE5284908EB090321A81E -+:103DE000DAE5C0468C8202004D8202003F8102006B -+:103DF000837D0200C27F0200DD7F0200747D02002D -+:103E00008D7E0200E97E0200917D0200A281020007 -+:103E1000BD8102008E7F0200AF7F02009982020006 -+:103E2000BA820200F0820200377D0200C5830200E0 -+:103E3000DA830200F8830200FD7F0200A4830200FF -+:103E400056830200847F0200087D0200DD7F0200AD -+:103E5000537D0200E782020031830200157E0200DA -+:103E60009783020061830200B08302000880020091 -+:103E700044820200EA7F0200E6800200AA7E02007D -+:103E800009F1010404EB08052846DEF365F5002876 -+:103E900040F0088414F8083013F0010F40F0028459 -+:103EA000284611A9DEF3A0F30E9BB3F1FF3F40F0CB -+:103EB000F98308EB09035A799B79F3E408EB0903CA -+:103EC0009A785C788C49120621A8FFF7E3BB08EBCF -+:103ED000090421AD894962782846FFF797FA884995 -+:103EE000A2782846FFF792FA2379E2788549284696 -+:103EF00021E5854908EB090321A84DE508EB0906F2 -+:103F0000B378747821AD04EB0324A4B2E20A7F49AC -+:103F10002846FFF77BFA7E49C4F302222846FFF7C2 -+:103F200075FA7C49C4F3C4022846FFF76FFA7A4950 -+:103F3000C4F341022846FFF769FA2846774904F09E -+:103F40000102FFF763FABBF1040F40F2AB83337950 -+:103F5000F478734904EB0324A4B2E20A2846FFF77D -+:103F600055FA7049C4F302222846FFF74FFA6E490A -+:103F7000C4F3C4022846FFF749FA6C49C4F341026E -+:103F80002846FFF743FA6A49284604F00102FFF782 -+:103F900083BB08EB090621AF664972783846FFF704 -+:103FA00035FA4FF0000A6449B2783846FFF72EFA26 -+:103FB000CDF800A03279F378604903EB0223019336 -+:103FC000022253463846FFF721FACDF800A0B27915 -+:103FD00073795A4903EB02230193022201233846E5 -+:103FE000FFF714FACDF800A0327AF379384603EBE4 -+:103FF00002230222019351491346FFF707FABBF14E -+:104000001E0F40F24F834E49727A3846FFF7FEF991 -+:104010004C49B27A3846FFF7F9F94B49F27A3846FB -+:10402000FFF7F4F94949327B3846FFF7EFF9CDF84D -+:1040300000A0B27B737B414903EB0223019305226D -+:1040400053463846FFF7E2F9CDF800A0327CF37B07 -+:104050003A4903EB02230193052201233846FFF777 -+:10406000D5F9CDF800A0B27C737C344903EB022370 -+:104070000193052202233846FFF7C8F9CDF800A0C6 -+:10408000CDF804A0327DF37C314903EB0223029387 -+:1040900005226C2301253846FFF7B8F90095CDF8C5 -+:1040A00004A0B27D737D2A4903EB0223029305220B -+:1040B0006C2338460224FFF7A9F90094CDF804A038 -+:1040C000327EF37D224903EB0223029305226C2307 -+:1040D0003846FFF79BF9CDF800A0CDF804A0B27EDA -+:1040E000737E384603EB02230293194905226823A5 -+:1040F000FFF78CF90095DFE077810200268102004E -+:10410000F080020017810200CB8202008783020048 -+:10411000337E0200407E020011840200447D0200D2 -+:10412000E68102002E840200618402002B800200DE -+:1041300078830200837D0200FD800200208302005C -+:10414000CA810200CF7E020084810200E87D020065 -+:10415000AF7F020008EB090621AFAF4972783846FD -+:10416000FFF754F94FF0010AAC49B2783846FFF72F -+:104170004DF9CDF800A03279F378A94903EB022379 -+:104180000193022200233846FFF740F9CDF800A042 -+:10419000B2797379A24903EB0223019302225346B9 -+:1041A0003846FFF733F9CDF800A0327AF379384674 -+:1041B00003EB02230222019399491346FFF726F9E4 -+:1041C000BBF11E0F40F26E829649727A3846FFF7B5 -+:1041D0001DF99549B27A3846FFF718F99349F27AF2 -+:1041E0003846FFF713F99249327B3846FFF70EF94C -+:1041F000CDF800A0B27B737B894903EB02230193C6 -+:10420000052200233846FFF701F9CDF800A0327CE3 -+:10421000F37B834903EB022301930522534638467F -+:10422000FFF7F4F8CDF800A0B27C737C7C4903EB77 -+:10423000022301930522022300253846FFF7E6F802 -+:104240000095CDF804A0327DF37C7A4903EB02237C -+:10425000029305226C233846FFF7D8F8CDF800A06A -+:10426000CDF804A0B27D737D724903EB0223029363 -+:1042700005226C2338460224FFF7C8F80094CDF8D5 -+:1042800004A0327EF37D6B4903EB022302930522E7 -+:104290006C233846FFF7BAF80095CDF804A0B27E3B -+:1042A000737E384603EB022302936249052268239A -+:1042B000FFF7ACF8CDF800A0CDF804A0327FF37E74 -+:1042C000384603EB02230293052268235949FFF77E -+:1042D0009DF80094CDF804A0B27F737F384603EBBD -+:1042E00002230293534905226823FFF78FF8D9E18F -+:1042F00008EB0904A378627821AD02EB03224E4952 -+:104300002846FFF783F86279A379120402EB03626F -+:10431000E3782846D2182379484902EB0322FFF7B5 -+:1043200075F8BBF1120F40F2BD81627AA37A1204D4 -+:1043300002EB0362E3794249D218237A284602EB62 -+:104340000322FFF763F8627BA37B120402EB036294 -+:10435000E37A2846D218237B3A4902EB0322FFF77F -+:1043600055F8627CA37C120402EB0362E37BD21853 -+:10437000237CABE0A278637821A803EB02230093AF -+:1043800031492B460222FFF741F801350234B5EBE3 -+:104390005B0FEFDD86E1A278637821A803EB0223AF -+:1043A000009329492B460522FFF730F801350234E6 -+:1043B000B5EB5B0FEFDD75E10095A278637821A87E -+:1043C00003EB02230193214905226C23FFF71EF81A -+:1043D000013502344FEA9B06B542EDDD002411E0C1 -+:1043E00008EB5B034B44009403EB44039A785B783F -+:1043F00021A803EB02230193144905226823FFF748 -+:1044000005F80134B442EBDD4CE108EB09039C787C -+:104410005A780F4921A824E19C7E02000A810200FB -+:1044200020830200D8810200DC7E0200938102001A -+:10443000F77D0200AF7F0200EB8302003E830200A3 -+:1044400069810200067E0200D07D0200F681020032 -+:104450004B80020008EB09039C785A78934921A805 -+:10446000FFE008EB09039C785A78914921A8F8E00D -+:1044700008EB09039C785A788E4921A8F1E008EBF3 -+:104480000904E2782379120402EB0362637821AD18 -+:10449000D218A378884902EB03222846FEF7B6FF1C -+:1044A000E279237A120402EB036263792846D21878 -+:1044B000A379824902EB0322FEF7A8FFE27A237B6D -+:1044C000120402EB0362637AD218A37A7C4928466D -+:1044D000FFF731BA08EB0904A378627821AD2846CA -+:1044E000784902EB0322FEF791FFBBF1040F40F283 -+:1044F000D9802379E27874492846FFF71CBA08EB83 -+:104500000904E2782379120402EB0362637821AD97 -+:10451000D218A37828466D4902EB0322FEF776FFF6 -+:10452000BBF1060F40F2BE80E279237A120402EB5F -+:10453000036263796649D218A3792846FFF7FBB96D -+:10454000644E09EB08040225AB45C0F2AB80E2786B -+:104550002379120402EB036263783146D218A37800 -+:1045600021A802EB03220435FEF750FF043418366D -+:104570001A2DE9D196E0584E09EB08040225AB4507 -+:10458000C0F29080E2782379120402EB0362637830 -+:104590003146D218A37821A802EB03220435FEF796 -+:1045A00035FF043413360E2DE9D17BE04B4E09EB79 -+:1045B00008040225AB4575DBE2782379120402EB8F -+:1045C000036263783146D218A37821A802EB032254 -+:1045D0000435FEF71BFF043414360E2DEAD161E0DA -+:1045E0003F4E09EB08040225AB455BDBE2782379FB -+:1045F000120402EB036263783146D218A37821A833 -+:1046000002EB03220435FEF701FF043414360E2DAD -+:10461000EAD147E0334E09EB08040225AB4541DB04 -+:10462000E2782379120402EB036263783146D218F0 -+:10463000A37821A802EB03220435FEF7E7FE043439 -+:1046400014360E2DEAD12DE008EB09039C785A7838 -+:10465000254921A805E008EB09039C785A782349ED -+:1046600021A802EB0422FFF717B808EB0901CB7869 -+:104670000A791B0403EB02634A788C789B181C4967 -+:1046800021A8012203EB0423FEF7C0FE0AE019492A -+:1046900008EB090321A8FFF77FB901220B9201E083 -+:1046A000FF2E29D00BEB0801FEF753BFB9830200A0 -+:1046B0002B7D0200BD81020069810200067E02009E -+:1046C000128002003B8402004E84020060820200DD -+:1046D0007682020056800200047F0200517E0200B2 -+:1046E0003D7F020008820200B47E0200607D02006D -+:1046F000BA8202004C8102000D9B01330D930D9A8A -+:10470000079B9A427EF41DAF0E9AB2F1FF3F03D091 -+:1047100021A81749FEF77AFE9DF8443023B121A85D -+:10472000144911AAFEF772FE00201349DEF350F17E -+:1047300038B90B9B2BB91A4621A81049FF33FEF755 -+:1047400065FE229A002302F8013B2E9B0A990093F2 -+:104750000998069B2292FEF7ABFE0A9904464FF495 -+:1047600080520998E2F3C4F2204625B0BDE8F08FEC -+:1047700022840200CF8302000E5D860021800200A9 -+:104780002DE9F04F9A468FB000230D936D4B0646EE -+:104790001C7889460592002C40F0C180142208A89C -+:1047A0002146DDF34DF47369232B05DC01224FF024 -+:1047B000040B0694079214E01C222346304621463F -+:1047C0000094E6F363F30028ACBF03230123ACBFDE -+:1047D0000022012207930692ACBF4FF00C0B4FF062 -+:1047E000020B3046E6F306F30128054602D0022804 -+:1047F00006D013E030464946DDF356F340000CE0A6 -+:104800003046FBF7D9F8044640B1DDF3FBF210F473 -+:10481000807F03D02046DDF3EBF20D900D99002947 -+:1048200000F084804846E2F353F2044610B96FF07A -+:104830001A0083E0012D0746DDF8348003D0022DF5 -+:104840000ED000251CE0002102900091CDF80480DC -+:1048500003913046059A4B46DDF320F305460DE003 -+:104860000EAB4FEA580243F8042D30460121224690 -+:10487000DDF37CF20D9B05465B000D93002D45D1C9 -+:1048800023884FF6FD72013B9BB2934205D94846FF -+:1048900021464246E2F32CF24AE0069B1BB104EBB0 -+:1048A0004B03089315E0638804EB0B01227901EBBD -+:1048B000132303EB0223A3F580530993E3880891A4 -+:1048C000CB18A3F580530A932389C918A1F5805109 -+:1048D0000B91DDB9189A4846009208A9079A5346E9 -+:1048E000FEF708FE90B91849DEF346F038B1189B80 -+:1048F0003046DAF800101A6800F024FB06E0189B36 -+:104900003046DAF800101A6800F004FB27B1484678 -+:1049100039464246E2F3ECF10A4B01221A700023B9 -+:10492000189A1846CAF80030136007E00D4688460A -+:10493000064B0027089301230793CAE70FB0BDE891 -+:10494000F08FC04640270000DEB00100B97D0200B4 -+:1049500013B5049C9E4605994CB141B100232360D8 -+:104960000B60009123467146FFF70AFF00E000202C -+:104970001CBDC046094A13888B4201D1002206E0C3 -+:1049800093888B4202D04FF0FF3005E00122034BA9 -+:1049900003EB820393F902007047C046BC84020017 -+:1049A00070B50446E6F36AF2002105462046E6F3B8 -+:1049B00037F4236A012B04D1D0F8003623F40073B6 -+:1049C00004E005DDD0F8003643F40073C0F800368B -+:1049D00020462946E6F324F470BDC046036A70B54C -+:1049E000092B054601DC00242CE0E6F347F2002108 -+:1049F00006462846E6F314F4D0F80836044613F4C5 -+:104A0000807001D1044619E04FF00043C4F86C36C1 -+:104A10004FF47A70E1F3A0F6D4F86C360022DB0490 -+:104A2000DB0C5B03C4F86C2603F54243064A03F52E -+:104A3000A873B3FBF2F3642203FB02F42846314669 -+:104A4000E6F3EEF3204670BDA08601002DE9F041AB -+:104A5000074614461E46002B7ED0E6F717F905469A -+:104A600002E0B34205D00C35002D75D02B88002B09 -+:104A7000F7D12B88002B6FD0D4F80036AA78C3F377 -+:104A80008403934268D0D4F81836642023F0C073AE -+:104A9000C4F81836D4F81C3643F6A12623F0C073A8 -+:104AA000C4F81C36E1F358F603E00A20E1F354F6AB -+:104AB0000A3ED4F8E03113F4003F01D0092EF4D1BE -+:104AC0000023C4F86036EA782B79D4F864161B0604 -+:104AD000120502F4700203F07063134321F07F614A -+:104AE0000B43C4F864360223C4F86036D4F8643645 -+:104AF0006A7923F0FE5323F4781343EA025343F414 -+:104B00008023C4F864360323C4F86036D4F86426DE -+:104B1000AB6802F07F4223F07F431343C4F864364E -+:104B20003B6A012B05DDD4F8003643F48063C4F8FA -+:104B30000036AA782988D4F8000692004FF68373CD -+:104B40007F3102F07C0200EA0303C9111A430139E4 -+:104B500042EA0142C4F80026BDE8F0812DE9F041A7 -+:104B6000044616460D46E6F389F1002180462046AC -+:104B7000E6F356F32946024633462046FFF766FF22 -+:104B800020464146E6F34CF3BDE8F0812DE9F043C1 -+:104B9000002485B0074603940294E6F36FF12146A2 -+:104BA00081463846E6F33CF37B6A4E4A0546C3F33A -+:104BB000042605E0137AC5F82036D368C5F82836F0 -+:104BC000494B083A9A42F5D14FF0000820E00821FD -+:104BD0006846464A4346DDF377F200206946DDF336 -+:104BE000F7F698B100210A46DDF3B2F53B6A0C2BCB -+:104BF00008DDB0F5803F05D200F0FF02C0F30723C7 -+:104C000042EA0340C5F82086C5F8280608F10108E5 -+:104C1000B045DCD1364C28E0E36A13B138469847FA -+:104C200010B300211EE001238B40226A134218D0EA -+:104C3000C5F8201694F924302BB1012B05D0B3F11F -+:104C4000FF3F07D00DE0A36A09E0D5F82436A26A39 -+:104C5000134304E0D5F82436A26A23EA0203C5F818 -+:104C600024360131B142DED1103C224B9C42D3D1DB -+:104C7000002614E0082168461F4A3346DDF324F27B -+:104C8000002069466C46DDF3A3F638B10021C5F873 -+:104C900020660A46DDF35CF5C5F824060136464574 -+:104CA000E8D103A902AA3846E1F342F0029B039936 -+:104CB00041EA0302D5F81C3642EA0303C5F81C3664 -+:104CC0000AB1C5F81C2609B1C5F818164FF4FA60E8 -+:104CD0000292E1F341F538464946E6F3A1F205B008 -+:104CE000BDE8F083B484020094840200513686004B -+:104CF0007484020044840200563686002DE9F04395 -+:104D000085B00546E6F3BAF0002181462846E6F371 -+:104D100087F22B6A8046042B6B6A01DDDF0E01E00F -+:104D2000C3F34367002614E0102168460D4A33465A -+:104D3000DDF3CAF1002069466C46DDF349F638B16F -+:104D400000210A46DDF304F5C8F85066C8F8540699 -+:104D50000136BE42E8D128464946E6F361F205B085 -+:104D6000BDE8F0835B3686002DE9F043036A85B029 -+:104D7000042B436A0546CCBFC3F38458C3F343589E -+:104D8000E6F37CF0002181462846E6F349F200264E -+:104D9000074615E0102168460E4A3346DDF394F1CC -+:104DA000002069466C46DDF313F638B100210A464F -+:104DB000DDF3CEF4C7F85866C7F85C06731CDEB2A4 -+:104DC0004645E7D128464946E6F32AF205B0BDE854 -+:104DD000F083C04663368600F7B5053A06461F469F -+:104DE000062A2BD8DFE802F00A0C12040E2A06006D -+:104DF00005250CE01125032402230AE0012502E029 -+:104E0000052500E011250F24042302E000251F24BE -+:104E10000323009300214FF4CB624FF0FF33304661 -+:104E2000E6F334F004EA0703AB4030460093002178 -+:104E300040F25C6214FA05F3E6F328F0FEBDC046CA -+:104E40002DE9F04105460E4600201749DDF394F5A3 -+:104E5000164984B20020DDF38FF540F2DC51002CBE -+:104E600018BF2146C7B22846FFF784FDC0B210F034 -+:104E7000800F0CD1C4B23146284607222346FFF7E3 -+:104E8000ABFF2846314608222346FFF7A5FF2FB186 -+:104E9000284631463A460123E5F732FF2846314697 -+:104EA000FFF762FFBDE8F0816F36860098C201000F -+:104EB00070B505460C46FFF721FF00222146284623 -+:104EC000E1F38AF02846E5F3D9F70A4904460020C1 -+:104ED000DDF352F54FF4002210F001034FF0000112 -+:104EE000284618BF1346E0F3ABF728462146E6F301 -+:104EF00097F170BD7836860070B500210546102008 -+:104F0000E1F384F2002110220446DDF399F02046FB -+:104F1000656070BD70B50C461546E6F3EBF01021E8 -+:104F2000E1F3D6F610B96FF01A0008E0044A102336 -+:104F300043601368C460036085601060002070BD2A -+:104F40006C27000070B515460C46E6F3D3F010212F -+:104F5000E1F3BEF6024610B96FF01A0010E010231C -+:104F600043600849002303600B68C46085601BB977 -+:104F70000860184604E0034618680028FBD11A6050 -+:104F800070BDC0466C27000070B50C461546E6F3B0 -+:104F9000B1F01021E1F39CF610B96FF01A0008E0AF -+:104FA000044A102343601368C46003608560106086 -+:104FB000002070BD6C270000064B10B51B683BB984 -+:104FC000054B196821B1054B1A680AB1FFF7DCFFE0 -+:104FD000002010BD6C270000ECED0100F0ED010099 -+:104FE000012070470020704710B50020DDF3C4F4A5 -+:104FF00010BDC04610B50B490446FFF7F5FF80B25F -+:1050000078B9E06F0749DDF3B7F480B248B9E06FD3 -+:105010000549DDF3B1F44FF6FF7380B2002808BFF5 -+:10502000184610BD483786004E37860041F2E443EB -+:1050300070B5C36204460D4629B108460949DDF33F -+:105040009BF4A06240B900200749DDF395F4A0620B -+:1050500010B94FF6FF73A36228460449DDF38CF4C0 -+:10506000206370BD543786005B3786008637860024 -+:10507000836973B513F0005F04466FD08268B2F5A0 -+:10508000026F01D101220AE040F604039A4201D0E6 -+:10509000002204E0C3680C2B94BF002201224FF0D1 -+:1050A0000003D5B2ADF8063055B920464FF4006183 -+:1050B0002A46D4F8C860E6F3A1F000284ED005E0F7 -+:1050C000D4F8843013F5405048D000266369222B71 -+:1050D00003DC0023C0F8683100E00023C0F864312D -+:1050E000C0F860316369222B03DC1F4BC0F84431E8 -+:1050F00005E00123C0F84831FE33C0F84C31636944 -+:10510000222B07DC0023C0F88031C0F87C31C0F8C6 -+:10511000783104E00023C0F87431C0F870311DB953 -+:1051200020463146E6F37CF020460DF10601FFF7FC -+:1051300059FF0546A8B9BDF8063093B163690B491C -+:10514000222B2046D8BF4FF48021CCBF40224FF401 -+:1051500080222B46E5F3B4F6284603E04FF0FF30FB -+:1051600000E000207CBDC0460000FBBF400055555C -+:105170002DE9F047002104461F46DDF82080DDF8C8 -+:105180002490E6F34DF005462046E5F389F660618C -+:105190000A28C4BFEB6A63646B68A3616369222B4E -+:1051A000C4BFD5F8AC30E361A36913F0805F05D0CC -+:1051B000D5F80436636203F0FF0323624FF4E06323 -+:1051C000A3604FF0FF33E3602546123300262361CE -+:1051D00016E031462046E6F323F02046E5F342F69A -+:1051E0002046E5F35DF61FB1D5F810319F4203D09C -+:1051F000D5F88830994501D1C8F8006001360435EA -+:10520000D4F8CC309E42E4D32046D8F80010E6F320 -+:1052100007F00120BDE8F08730B585B0019000258A -+:1052200004A840F8045D01A90422DCF3A5F6019C62 -+:10523000D4B122462946D2F8883013B10023C2F8EF -+:105240008830013104321029F5D10398DCF332F6AD -+:105250000398E5F763FE054B9C4205D0606D21463F -+:105260004FF45672E1F344F505B030BD88F5010006 -+:105270002DE9FF470C9E1446DDF834808A464FF432 -+:105280005672002105461F46DDF83890012E08BFF2 -+:105290000026DCF3D5F611232B61C5F88470C5F820 -+:1052A00058806C656E60002E40F0B980284631460B -+:1052B00052464346FFF794FE002800F0B0804FF0BE -+:1052C000C05422682846130F2B6013041B0CAB63D9 -+:1052D000C2F30343C2F303522A640E3A012A8CBF7D -+:1052E00000220122EB6385F8482021465246FDF753 -+:1052F00039FFD5F8CC30002B00F0918004AB43F897 -+:10530000046D009328462146324633460197FFF745 -+:105310002FFF002800F083802846FFF74DFE0F9AEC -+:105320006B6D2846019231463A46CDF80090FFF762 -+:105330000FFB002873D1B9F1000F01D14E4601E0F7 -+:10534000D9F8006028463146FFF770FE364B1C78CE -+:10535000002C30D16B69132B0BDD4FF40061284614 -+:105360002246E5F34BF78465C46503992846E5F3C7 -+:1053700057F72846696DFFF713FB2846696DFFF75D -+:1053800097FD30462949DDF3F7F2024620B9284659 -+:10539000696DFFF723FB02462846696DFFF7DEFBC8 -+:1053A0002846696DFFF7F2FB2846696DFFF748FD57 -+:1053B0001D4B01221A706B690F2B0FDD1C49304603 -+:1053C000DDF3DAF21B4B0021002808BF18460090DD -+:1053D000882228464FF0FF33E5F358F5304616494A -+:1053E000DDF3F6F238B114493046DDF3C5F201467B -+:1053F0002846E5F749FF6B69142B11DD002421468F -+:105400000822234628460094E5F340F5214640F063 -+:105410000403082228460093E5F338F500E0002550 -+:10542000284604B0BDE8F087E0F80100E2388600C5 -+:10543000EB3886005A000A00F13886001FB5104C80 -+:1054400086462178C9B90F4A0F4B002808BF02468B -+:1054500008BF034600910191029303920B4844F266 -+:10546000107172464FF0C053FFF702FF00B905E01C -+:10547000074A2023136001232370044804B010BDA1 -+:1054800084F5010008F6010004F6010088F501002A -+:10549000742700002DE9FF4781460D4608464FF46A -+:1054A000567192461E460D9FDDF83880E1F310F4E8 -+:1054B000044610B30C9B494601932A465346009676 -+:1054C0000297CDF80C80FFF7D3FE064638B9284680 -+:1054D00021464FF45672E1F30BF430460EE00FB95B -+:1054E0003B4600E03B68E367B8F1000F01D143465B -+:1054F00001E0D8F80030C4F88030204604B0BDE8A0 -+:10550000F087C04670B5044628B30368124918688E -+:105510002246FEF319F52546002610E0296A29B136 -+:1055200023689868EAF3ACF000232B62E96921B1A3 -+:1055300023682A8B5868E1F3DBF30136183561687C -+:105540008E42EBDB182201FB02F2236821465868E9 -+:105550001032E1F3CDF370BD98C301002DE9F043A3 -+:10556000036885B081467021D868E1F3B1F3044641 -+:1055700008B9064648E0002170220646DCF360F5D3 -+:105580000423636027464FF0B40325464FF000081C -+:10559000C4F80090A38112E0182208FB02F2103236 -+:1055A0002C61D9F808001A49A2180023EAF384F004 -+:1055B0002862183508B905461CE008F1010863683F -+:1055C0009845E9DB134BD9F80000009300230193C1 -+:1055D000029303931049114A2346FEF37DF413E02E -+:1055E000396A29B123689868EAF34AF000233B62DC -+:1055F0000135183763689D42F2DB236821465868FD -+:105600007022E1F375F30026304605B0BDE8F08363 -+:1056100099B500001DB4000074C3010099C30100D6 -+:10562000034B012210B51A70E5F752FA10BDC046BF -+:1056300038F5010070B50446D0F884000D4608B175 -+:10564000FDF74EF8D4F8800008B1FFF75BFFE06F7C -+:1056500008B1FAF707FCA06F08B100F001F9A068E3 -+:1056600008B1FAF76DFF284621468C22E1F340F39A -+:1056700070BDC0460B682DE9F041DC694368054602 -+:105680000E46D868A021E1F323F3C5F8880000286E -+:105690003ED00021A022DCF3D3F4D5F88820A36DFE -+:1056A000082182F87B30D5F88820636D82F87A3043 -+:1056B000D5F88820E36D82F87C30236ED5F88820F9 -+:1056C00082F87D306B68D868E1F302F3C6F84408CD -+:1056D000F0B1002108220127DCF3B2F486F841780A -+:1056E000D5F888402846C4F89C500B4922460B4BFD -+:1056F000E9F3E2F7C4F8980050B1D6F87C024A21E9 -+:105700003A4621F041D80023184686F8403801E097 -+:105710004FF0FF30BDE8F08191FF80008A418600A4 -+:105720002DE9F04F064689B00D4600208C219146A8 -+:105730009846139FE1F3CCF20446002874D0002170 -+:105740008C22DCF37DF427603046FFF7D5FB07ABF6 -+:105750000190059383464FF0000A204641F2E44150 -+:1057600042463B460295CDF800A0CDF80C9004943B -+:10577000FBF7BAF80546002858D0A06000F0B0D971 -+:105780002B696060E3602D4B1021A3642C4A3B46DB -+:10579000266164643046DCF397F42B6939461B6E4E -+:1057A00028489A6B284BE9F789FC504612993A46EB -+:1057B000264B0096CDF80490FDF710F9002835D15E -+:1057C00020462946FFF756FF064600282ED163687B -+:1057D000012283F878203621D5F87C0220F0D4DF2E -+:1057E0001B4B2846E36300F04DF8A067F0B1284654 -+:1057F000FAF74CFBE067C8B12846FFF7AFFEC4F8E4 -+:10580000800098B12846FCF799FFC4F8840068B17D -+:10581000104B019600930296039628680E490F4A92 -+:105820002346FEF359F308B9204604E020465946C2 -+:10583000FFF700FF002009B0BDE8F08F55F78000AA -+:10584000FB418600C4840200A4C3010029FB800040 -+:10585000EFBEAD0D99F88000ECC30100C542860093 -+:1058600010B5044658B10368054918682246FEF38E -+:105870006BF32368214658685422E1F339F210BDD6 -+:105880002B7A860030B55421044685B04068E1F398 -+:105890001FF208B9054611E0002154220546DCF349 -+:1058A000CFF3084B2C6000930023019302930393E2 -+:1058B00020680549054A2B46FEF30EF3284605B03D -+:1058C00030BDC046F1BD000038C401002B7A86000F -+:1058D0000020704710B5044698B10BF0B3D80949C1 -+:1058E00060682246FEF330F3E16E21B163683C222A -+:1058F000D868E1F3FDF163682146D8687022E1F3CE -+:10590000F7F110BDD58D86007FB505467021406842 -+:10591000E1F3DEF1064608B9044631E000217022C9 -+:105920000446DCF38DF32B683560736068683C21B6 -+:10593000E1F3CEF1E066F8B100213C22DCF380F324 -+:10594000114B12490093002301930293104B114A0B -+:10595000039370683346FEF3BFF268B94FF001035A -+:105960007382B38230462946FFF7B2FF002803DB7B -+:1059700030460BF063D903E03046FFF7ABFF00245D -+:10598000204604B070BDC046390B830068C40100D6 -+:10599000290C8300D58D860010B5044658B10368E4 -+:1059A000054918682246FEF3CFF22368214658685D -+:1059B0000822E1F39DF110BDE3C40100F0B5082118 -+:1059C00085B005464068E1F383F1064608B9044610 -+:1059D00024E00021082200270446DCF331F30421EF -+:1059E0002846104A104B0097019601F091FFB842EB -+:1059F00070600FDB0D4B286800930D4B0D49019330 -+:105A00000D4B0E4A039333460297FEF365F208B935 -+:105A1000356003E03046FFF7BFFF0024204605B0A5 -+:105A2000F0BDC04605C7000021C9000099C60000AE -+:105A300095C60000E8C4010091C60000E3C401005F -+:105A40002DE9F041066805461B4930682A46FEF3F9 -+:105A50007BF22C460027D4F8081121B17068B4F805 -+:105A60001021E1F345F1D4F80C1121B17068B4F8BC -+:105A70001221E1F33DF101374034042FEBD1D5F889 -+:105A80000C1221B17068B5F81022E1F331F1D5F8AC -+:105A90001C1211B1B068E9F3F3F5D5F8201219B171 -+:105AA00070683A46E1F324F1706829464FF4237296 -+:105AB000E1F31EF1BDE8F081F4C4010010B5014628 -+:105AC00020B10368B022D868E1F312F110BDC046DE -+:105AD0002DE9F34107680546B021F868E1F3F8F0D5 -+:105AE000064608B980468BE00021B02201AC804612 -+:105AF000DCF3A6F20422002137607560C5F85C6112 -+:105B00002046DCF39DF22A6892F87C30012B07D9FD -+:105B10003D495069DCF35CF7014690B120460AE04C -+:105B200050693A49DCF328F70928034609D838496F -+:105B3000204601EB83010322DCF33AF300238DF8C6 -+:105B4000073001AC0322214606F10800DCF330F3F4 -+:105B50000023F3722B682F495869DCF30DF739697C -+:105B6000F060CA6A41F26B039A420CD18B6A8B2BAC -+:105B700009D1022807D1204627490422DCF3F8F294 -+:105B800008B90323F360396941F26B03CA6A9A4288 -+:105B90000DD18B6A932B0AD101A820490422DCF392 -+:105BA000E7F220B9F368042B01D10233F36001AFAF -+:105BB000284639461FF04CDE044650B9184938468D -+:105BC0000322DCF3F5F2284639468DF807401FF032 -+:105BD0003FDE05F5AA60394603220A30DCF3E8F21D -+:105BE000002405F5AA600F4985F85D450E300322B3 -+:105BF000DCF3DEF285F861453046394620F0B2DA52 -+:105C00004046BDE8FC81C046B3C48600B9C48600E6 -+:105C1000CE028600BCC48600C3C4860071C2860062 -+:105C2000C6C48600CAC4860010B50446E8F7A4FDC1 -+:105C3000A16961B1237D23B1E068E9F30FF5002389 -+:105C40002375E068A169E9F31BF50023A3612369CB -+:105C50002146D8682C22E1F34BF0002010BDC0464D -+:105C60002DE9F04107468846C0682C2114461E469F -+:105C7000E1F32EF008B9054619E0054600212C2273 -+:105C8000DCF3DEF1EC602046EE61C5F808802F61A0 -+:105C900008492A460023E9F30FF50446A86130B904 -+:105CA0002B692946D8682C22E1F322F025462846A4 -+:105CB000BDE8F0813D66840010B50349002200680C -+:105CC000FEF342F1002010BD49C586001FB5094A08 -+:105CD0000B46009200220192029203920649074A63 -+:105CE000FEF3FAF0002814BF4FF0FF30002005B09B -+:105CF00000BDC04609688400B8CA010049C58600D5 -+:105D00001FB5084A034600920022019202920392B4 -+:105D10000549064A0068FEF3DFF0003818BF01208D -+:105D200005B000BD35F3000078CB010048CB010081 -+:105D300010B5B0F8BC400C80B0F8C0101180B0F8BD -+:105D4000C6201A8090F8C820029B01201A8010BD3E -+:105D500090F8D4007047C046D0F8CC007047C046D9 -+:105D600010B5014618B180689822E0F3C1F710BD64 -+:105D700070B5982104460068E0F3AAF708B9054613 -+:105D800033E0002198220546DCF35AF12368AB602A -+:105D90006368EB60A3682B61E3686B6023696B61E8 -+:105DA000238CAB84638CEB84636AAB62A36AEB6283 -+:105DB000E36A2B63236B6B63636B6B64A36BAB64F2 -+:105DC000E36BEB64236C2B65636C6B656369AB659C -+:105DD000A369EB650F232B662D336B663C33AB66F3 -+:105DE0000323EB66002385F89430284670BDC04637 -+:105DF00070B501210446E9F7A9FE2046E9F72EFF18 -+:105E0000C0F30F33A4F8C630B4F8C620030F84F8EB -+:105E1000C83042F2640300F00F009A4284F8C900CF -+:105E200005D002339A4202D04FF0FF3500E0002542 -+:105E300020460021EAF7F6FB284670BD70B50446FF -+:105E400000282DD0D0F8E4305D1EC0F8E4503DBBF2 -+:105E500041F2B826815921B1C3691869F4F7FCFAF7 -+:105E6000A55141F2CD13E5542046EAF7BBFAE169AA -+:105E70000A68A24203D1D4F8B4300B6005E0D2F82E -+:105E8000B430A34208BFC2F8B450E36E0BB1204651 -+:105E90009847E3692146986841F25832E0F328F7C1 -+:105EA00070BDC04670B5D0F8B8400E46E9B108469E -+:105EB000DCF356F10546C0B10FE0204631462A46D4 -+:105EC000DCF33EF028B9635D3D2B02D1631C581909 -+:105ED0000CE014F8013B002BFBD114B12378002B0C -+:105EE000EBD13046E1F3C2F600E0002070BDC046C1 -+:105EF0002DE9F34141F22835435B064688462BB332 -+:105F00000846DCF32DF104461448DCF329F124188B -+:105F10001034F369A7B298683946E0F3D9F604461D -+:105F200008B9054617E0735B0D4A009339464346AE -+:105F3000DCF3CAF021463046EBF714FDF369054661 -+:105F4000214698683A46E0F3D3F625B930464146F3 -+:105F5000EBF708FD05462846BDE8FC819ACC010018 -+:105F6000A0CC01002DE9F04F41F2283B85B003930E -+:105F700030F80B30064689469246D0F8B880002BA0 -+:105F800038D00846DCF3ECF004462448DCF3E8F0B3 -+:105F90002418F3691034A7B298683946E0F398F6EC -+:105FA000054608B9044634E036F80B30394600930C -+:105FB0001B4A4B46DCF388F030462946EBF7E0FC01 -+:105FC000834668B140462946DCF7FEFB40B15045A8 -+:105FD00006DD404629465246DCF3DCF4044600E088 -+:105FE000039CF369294698683A46E0F381F6BBF1D1 -+:105FF000000F0ED140464946DCF7E6FB40B1504564 -+:1060000006DD404649465246DCF3C4F4044600E04F -+:10601000039C204605B0BDE8F08FC0469ACC010035 -+:10602000A0CC010070B590F8C43001229A401A4902 -+:10603000013A0446D5B2EBF7D7FC41F20202C0B2F6 -+:10604000A0540138C0B2FD2801D97323A354A25C27 -+:1060500041F20303E25420461049EBF7C5FC41F23C -+:106060000402C0B2A05408B10F2801D10523A354E3 -+:1060700041F20203E25C0233E35CD21A41F205030F -+:10608000E25400220133E2540233E25445EA05129D -+:10609000013BE25470BDC046178502002285020014 -+:1060A0002DE9F84F88460021846807469246C0686B -+:1060B0000A469B46E4F3CEF610F0080F814615D051 -+:1060C0003E689EB13046514600F084FA002800F048 -+:1060D0007481F369D6F8CC1018692AF0E1DAD6F8A1 -+:1060E000E43030460133C6F8E4306DE1204641F239 -+:1060F0005831E0F3EDF50546002800F05C81002101 -+:1061000041F258320646DBF39BF7012105F5915227 -+:1061100041F2C41385F8E110EA50FA6CA3F5AC73B0 -+:10612000013B9A42C5F8B080EF6105D17B6C932B9F -+:1061300002D1A5F8221603E04FF01802A5F8222696 -+:106140006423002185F8E03041F208230422E95459 -+:106150000133EA540133E9540133BAF1020FC5F8AF -+:10616000B8B0EA5406D119F0010F1CBF4FF4005328 -+:10617000C5F8CC30EB69D5F8CC1018692AF090DA64 -+:10618000D5F8B030B3F8E0339CB2EB69D868E4F7E7 -+:1061900019FF41F22833E852C4F30323C5F8BC3099 -+:1061A00004F00F03C5F8C030EB699A6A874BD31827 -+:1061B000012B06D94AF6E6039A4202D0043B9A42E2 -+:1061C00007D1EB69DB6A023B012B02D80923C5F832 -+:1061D000C030D5F8BC30092B07D10423C5F8BC303A -+:1061E000D5F8C0301033C5F8C030012385F8C4306D -+:1061F000230BC5F8D030D5F8BC30022B0CD9042BBA -+:106200000AD0052B08D0062B06D0082B04D00A2B69 -+:1062100002D0072B40F0D1803C23C5F8E43F002397 -+:10622000C5F8E83F4FF40063A5F8DE3042F60132CE -+:1062300041F62433BAF1020F08BF1346A5F8DA304D -+:1062400095F8DA30284685F800376149EBF798FB76 -+:1062500090B15F492846EC69EBF7C6FB5C492067C3 -+:106260002846EC69EBF7C0FBEA69BAF1020F6067F8 -+:106270000CBF136F536FD3660A2241F2D613EA5450 -+:1062800003210133E9540123002485F8E83041F269 -+:10629000F013EC54A3F5F273013A013BEA54EB69B5 -+:1062A00085F8E94585F8EE4585F8F34585F8F84524 -+:1062B00085F8FD45284683F89310FFF7B3FE41F2B9 -+:1062C0000903EC544FF6CE7241F2B423EA5285F83A -+:1062D000F440621901347F23652C82F82C3682F851 -+:1062E000913682F8B232F4D14FF0FF33A5F8FA3686 -+:1062F000002385F8AC302846514601F037F90028D4 -+:106300005BD02846E9F716FC2846FFF771FD0446E6 -+:10631000002852D12F4906222846EBF759FB41F2BB -+:10632000D623E8542C4901222846EBF751FB41F2D1 -+:10633000E423E854294922462846EBF749FB41F279 -+:106340002A33E854264928460722EBF741FB41F25D -+:106350002B33E854224628462249EBF733FB6319D6 -+:1063600003F5985301342833182C1871F2D1002406 -+:10637000224628461C49EBF725FB6319013403F537 -+:106380009A530E2C1871F3D1D5F8E430EA69013331 -+:10639000C5F8E4301368D068C5F8B4303D60FEF746 -+:1063A00067FE05F1B803C5F8B830284605F1BC0111 -+:1063B0001C22DBF3E1F5284606E0B868314641F2DD -+:1063C0005832E0F395F40020BDE8F88F1D57FFFF29 -+:1063D00054850200F8840200488502000A85020004 -+:1063E00033850200418502000385020010B5024991 -+:1063F0000268FDF3A9F510BD38D301001FB5094BA4 -+:10640000094900930023019302930393074A036809 -+:10641000FDF362F5002814BF4FF0FF30002005B0F7 -+:1064200000BDC046F519010078D2010038D3010043 -+:106430002DE9F041002580460F4616462C4607E020 -+:1064400004EB0800E1190522DBF396F5013505346C -+:10645000B542F5D1BDE8F081022970B505460C467C -+:106460000AD0032911D0012916D106220B49E9F7D8 -+:1064700013FBEA69002305E006220949E9F70CFB52 -+:10648000EA69012382F8813006E006490622E9F72D -+:1064900003FBEB6983F8814070BDC046C0DB01009F -+:1064A000CCDB0100E0DB010070B5D0F8A840002390 -+:1064B00094F8C113C4F874350F4A104B022914BF65 -+:1064C00015461D46C3694FF420719868E0F300F447 -+:1064D000C4F8740578B180222946FFF7A9FF94F823 -+:1064E0003A35022B06D1D4F874050549A03015229F -+:1064F000FFF79EFF012070BD589502007C900200BE -+:106500001C9802002DE9F047D0F8A8308146D3F856 -+:106510007C55D3F878A54FF0000817E0142403FB4E -+:1065200004F42B191A695B682F5903FB02F3DE0888 -+:10653000D9F81C3031469868E0F3CAF308F1010835 -+:10654000285140B139463246DBF316F55FFA88F33D -+:106550005345E3D30120BDE8F087C0462DE9F04163 -+:10656000194BD0F8A8501A68C369002614210746B1 -+:10657000C5F87C65C5F87825986802FB01F1E0F361 -+:10658000A7F30446C5F87C05E0B1B0460FE0FB690F -+:1065900006EB04001B6D08F1010813F4805F14BFC3 -+:1065A0000A490B4914227118DBF3E6F41436D5F8C6 -+:1065B00078359845EBD338460121FFF7A3FF003823 -+:1065C00018BF0120BDE8F081C4E90100988E0200E7 -+:1065D000589D02002DE9F041884686B07A4905466B -+:1065E000D0F8A860EBF700FA784930722846EBF74C -+:1065F000FBF9774970722846EBF7F6F97549A5F86B -+:10660000FC002846EBF7F0F97349A5F8FE00284690 -+:10661000EBF7EAF97149A5F800012846EBF7B0F964 -+:1066200038B128466D49EBF7DFF910B1012386F840 -+:10663000E83396F8E8330BB368492846EBF7D4F90A -+:106640006749A5F802012846EBF7CEF96549A5F898 -+:1066500004012846EBF7C8F96349A5F80601284666 -+:10666000EBF7C2F9614986F824052846EBF7BCF937 -+:10667000002241F20B0386F82505EA545C492846BE -+:10668000EBF7B2F95B49C6F8340414222846EBF75D -+:106690009FF95949A6F83C045A222846EBF798F985 -+:1066A000564986F8540408222846EBF791F95449D4 -+:1066B00086F84C0403222846EBF78AF9514986F8FC -+:1066C0004D0408222846EBF783F94F4986F84E041B -+:1066D00003222846EBF77CF94C4986F84F04082240 -+:1066E0002846EBF775F94A4986F8500403222846F4 -+:1066F000EBF76EF9474986F8510408222846EBF774 -+:1067000067F9032286F8520443492846EBF760F9FB -+:10671000424986F853042846EBF766F9404986F863 -+:10672000580402222846EBF753F93E4986F8C10483 -+:106730002846EBF725F928B128463A49EBF754F9F2 -+:10674000F07400E0F07428463749EBF719F928B1E6 -+:1067500028463549EBF748F9307501E008233375D1 -+:1067600028463249EBF70CF928B128462F49EBF7B8 -+:106770003BF9707501E00223737528462C49EBF74D -+:10678000FFF828B128462A49EBF72EF9B07501E049 -+:106790000423B37528462749EBF7F2F828B12846B9 -+:1067A0002449EBF721F9F07501E00823F375284639 -+:1067B0002149EBF7E5F8002840D028461E49EBF7C1 -+:1067C00013F930763CE0C046FA8C0200988C020047 -+:1067D000DF890200E5890200EB890200BF8A02001E -+:1067E0009289020092880200858602009A86020041 -+:1067F0006E8E0200388902006C8D0200E38D02006B -+:10680000338E0200B18D020073850200C28D02003A -+:1068100084850200A08D0200878E02006688020037 -+:10682000B8860200E7870200D4870200EF870200E3 -+:10683000DB8D0200D38D0200F28C0200022333763E -+:10684000B6492846EBF7D0F8B549B0722846EBF7C1 -+:10685000CBF8B449F0722846EBF7C6F8B17AF27A71 -+:10686000C3B230737173B273F37331747274B374EF -+:10687000AD492846EBF7B8F8B5F8FC2041F20A33E9 -+:10688000EA520633EA52B5F8FE20043BEA520633D8 -+:10689000EA52B5F80021043BC7B2EA52063385F844 -+:1068A0001A71EA522846A149EBF79EF8002480B2FB -+:1068B0002A1900F00F030134A7EB43030009042C4D -+:1068C00082F81E31F4D128469949EBF78DF82A1940 -+:1068D00000F00F030134A7EB430300090C2C82F8EE -+:1068E0001E31F4D193492846EBF77EF892490446CD -+:1068F0002846EBF779F880B240EA04417160142031 -+:106900002A1801F00F030130A7EB430309091C28E3 -+:1069100082F81631F4D189492846EBF765F88849A1 -+:1069200070832846EBF760F8864930772846EBF706 -+:106930005BF8854970772846EBF756F88349B077BE -+:106940002846EBF751F88249F0772846EBF74CF8E8 -+:10695000804986F822002846EBF746F87E4986F8FB -+:1069600021002846EBF740F87C4986F8E0042846E9 -+:10697000EBF73AF80127C6F8E40401AC7849204661 -+:106980003A46DBF3B1F3D5F8B8002146DCF320F04A -+:1069900030B100210A46DBF3DBF6F31983F8E70494 -+:1069A00001370F2FE9D16F492846EBF71DF86E49E3 -+:1069B00086F8F6042846EBF717F86C4986F8F704D2 -+:1069C0002846EBF711F86A4986F8F8042846EBF7F1 -+:1069D0000BF8684986F8F9042846EBF705F866498C -+:1069E00086F8FA042846EAF7FFFF644986F8FB04B4 -+:1069F0002846EAF7F9FF624986F8FC042846EAF7D8 -+:106A0000F3FF604986F8FD042846EAF7EDFF5E498A -+:106A100086F8FE042846EAF7E7FF5C4986F8FF049B -+:106A20002846EAF7E1FF5A4986F800052846EAF7C2 -+:106A3000DBFF584986F801052846EAF7D5FF564995 -+:106A400086F802052846EAF7CFFF544986F8030581 -+:106A50002846EAF7C9FF524986F804052846EAF7AE -+:106A6000C3FF504986F805052846EAF7BDFF4E49A1 -+:106A700086F806052846EAF7B7FF4C4986F8070569 -+:106A80002846EAF7B1FF4A4986F808052846EAF79A -+:106A9000ABFF484986F809052846EAF7A5FF4649AD -+:106AA00086F80A052846EAF79FFF444986F80B0551 -+:106AB0002846EAF799FF424986F80C052846EAF786 -+:106AC00093FF404986F80D052846EAF78DFF3E49B9 -+:106AD000A6F814052846EAF787FF4FF00042A6F80B -+:106AE00016053A492846EAF773FF3949C6F81005F2 -+:106AF0002846EAF779FF374986F824002846EAF75E -+:106B000073FF354986F823002846EAF76DFF3349BD -+:106B100086F820002846EAF767FF61E0AF850200AB -+:106B2000B58A020088890200A78902004489020010 -+:106B3000F98B02006A85020061850200368A020034 -+:106B4000A5850200978B0200A28B020095850200AA -+:106B50007E880200A8880200628A0200A88A0200D9 -+:106B600008880200F1890200298B02003A8B02009A -+:106B70005B8D0200B38C0200C48C0200F18D020018 -+:106B8000128E0200248A0200438A0200708A0200E8 -+:106B9000D58C0200AD8B02000B8D02001D8D020012 -+:106BA0002F8D0200418E0200538E0200F9850200F3 -+:106BB00023860200218702004087020054880200D9 -+:106BC00063870200A986020001890200068702008D -+:106BD000778D0200838D0200238E0200DA8B020083 -+:106BE000B94985F826062846EAF7FEFEB74986F831 -+:106BF000C1032846EAF7F8FEB54986F8C2032846DD -+:106C0000EAF7F2FE86F8C30395F8261611B1284676 -+:106C1000FFF722FC4FF0FF32AE492846EAF7D8FED4 -+:106C200080B210F4004F18BF4FF0FF324FF0FF3327 -+:106C3000A6F86200A6F8663018BFA6F86220A6F88B -+:106C400068302846A449EAF79BFE58B12846A24975 -+:106C5000EAF7CAFE80B210F4004F04BFA6F866003F -+:106C6000A6F8680028469D49EAF78AFE48B12846FA -+:106C70009A49EAF7B9FE80B210F4004F08BFA6F8AF -+:106C8000660028469649EAF77BFE48B128469449B3 -+:106C9000EAF7AAFE80B210F4004F08BFA6F8680019 -+:106CA00090494FF0FF322846EAF792FE4FF0FF324C -+:106CB000A6F8C4038C492846EAF78AFE8B49A6F851 -+:106CC000C6032846EAF790FE8949A6F8C8034FF4A0 -+:106CD000CF722846EAF77CFE8649C6F8CC0347F611 -+:106CE0009A622846EAF774FE8349C6F8D0030A225E -+:106CF0002846EAF76DFE8149C6F8D40308222846E3 -+:106D0000EAF766FE7E49C6F8D80341F26E022846CD -+:106D1000EAF75EFE0A22C6F8DC037A492846EAF75B -+:106D200057FE7949C6F8E0032846EAF75DFE774941 -+:106D3000A6F8E4032846EAF757FE96F8E83380B24F -+:106D4000A6F8E6032BB103B2002BC4BF0022A6F8BD -+:106D5000E62350226E492846EAF73AFE6D4986F846 -+:106D6000EA032846EAF740FE6B4986F8EC0328461A -+:106D7000EAF73AFE694986F8ED032846EAF734FE59 -+:106D8000674986F8EE034FF0FF322846EAF720FE07 -+:106D9000644986F8F0034FF0FF322846EAF718FE00 -+:106DA0004FF0FF3486F8F1035F49224686F8EF433F -+:106DB0002846EAF70DFE5D4986F8F203224628468A -+:106DC000EAF706FE5A4986F8590522462846EAF7A8 -+:106DD000FFFD584986F85A0522462846EAF7F8FD8D -+:106DE000554986F8F30322462846EAF7F1FD534950 -+:106DF00086F85B0522462846EAF7EAFD504986F800 -+:106E00005C0522462846EAF7E3FD4E4986F8F4037E -+:106E100022462846EAF7DCFD4B4985F8DA0522468A -+:106E20002846EAF7D5FD4949A6F8F6032246284642 -+:106E3000EAF7CEFD4649A6F8F80322462846EAF7C7 -+:106E4000C7FD4449A6F8FA0322462846EAF7C0FDE2 -+:106E50004149A6F8FC0322462846EAF7B9FD3F4916 -+:106E6000A6F8FE0322462846EAF7B2FD3C49A6F8FA -+:106E7000000422462846EAF7ABFD3A49A6F8020488 -+:106E800022462846EAF7A4FD0022A6F80404364963 -+:106E90002846EAF79DFD0022A6F85E0533492846FC -+:106EA000EAF796FD0022A6F8600531492846EAF780 -+:106EB0008FFD0022A6F862052E492846EAF788FDD4 -+:106EC0002D49A6F8640559E0178602000B860200DA -+:106ED000588C02005A890200DF8B0200498D0200A3 -+:106EE0007587020087870200E88A0200E2860200B6 -+:106EF000EF8B020068860200818902008E87020003 -+:106F0000028D0200178C02004B8C02004C8902009B -+:106F1000888802004B8B0200D88502006F8B02002C -+:106F20005D860200C7880200E78C0200748C0200B4 -+:106F30003387020072880200EB860200898B020010 -+:106F4000A5870200948A0200D4890200718602009B -+:106F50001E8C020076890200F9860200B9880200C0 -+:106F60009B890200288802002B8C0200EF8A020015 -+:106F7000DA8A0200888C0200548B02002846EAF765 -+:106F800033FDB8F1020F86F8060414D12846A4494F -+:106F9000EAF7F6FC002800F0A382344600273A46C0 -+:106FA00028469F49EAF70EFD0137C4F80C04043463 -+:106FB000052FF4D116E0B8F1010F13D128469949F5 -+:106FC000EAF7DEFC002800F08B82344600273A46C0 -+:106FD00028469449EAF7F6FC0137C4F82004043443 -+:106FE000052FF4D190494FF0FF322846EAF7F0FC24 -+:106FF0008E49A6F83E044FF0FF322846EAF7E8FC37 -+:107000008B49A6F840044FF0FF322846EAF7E0FC2F -+:107010008849A5F8CE0F2846EAF7B2FC30B12846D9 -+:107020008449EAF7E1FC41F2DA23E8528249284632 -+:107030004FF0FF32EAF7CCFC41F22433E8527F49AB -+:107040002846EAF79DFC30B128467C49EAF7CCFC9B -+:1070500041F2DE23E852284679490022EAF7B8FCDB -+:10706000C0B286F84D0358B176492846EAF7BCFC11 -+:107070007549C6F850032846EAF7B6FCC6F860031F -+:1070800028467249EAF77CFC28B3D5F8B8006F4966 -+:10709000DBF79AFB06281ED1344600273A466B4997 -+:1070A000D5F8B800DBF376F484F895037A1C6749C9 -+:1070B000D5F8B800DBF36EF484F89703BA1CD5F862 -+:1070C000B8006249DBF366F4033784F899030134AE -+:1070D000062FE3D111E0012386F89533313386F88A -+:1070E00096330E3386F8973386F89833042386F860 -+:1070F00099334FF0FF3386F89A3355492846FF22DB -+:10710000EAF766FC4FF0FF03A6F85403A6F85633DF -+:10711000A6F85833A6F85A3328464E49EAF730FC09 -+:1071200028B3D5F8B8004B49DBF74EFB34460328AB -+:10713000B4BF80464FF00308002707E03A462846D0 -+:107140004449EAF73FFC0137A4F8540302344745A9 -+:10715000F4DB06EB470303F55473063304E0B6F89B -+:107160005623013723F8022C0233022FF7DD0122C8 -+:1071700039492846EAF72CFC384986F84003284666 -+:10718000EAF732FC012286F84B0335492846EAF734 -+:107190001FFC344986F841032846EAF725FC3249AA -+:1071A00086F84C034FF0FF322846EAF711FC2F49CE -+:1071B00086F849034FF0FF322846EAF709FC2C49CC -+:1071C00086F84A034FF0FF322846EAF701FC2949C6 -+:1071D00086F85C034FF0FF322846EAF7F9FB2649B0 -+:1071E00086F85D032846EAF7CBFB002846D0012449 -+:1071F0002149002286F8BB442846EAF7E3FB1E49F2 -+:1072000086F8BC0422462846EAF7DCFB1A4986F8D1 -+:10721000BD0402222846EAF7D5FB86F8BE042FE01B -+:1072200098870200FF8A02007D860200818C02009E -+:10723000C1890200D3880200028E0200BF8B0200C7 -+:10724000138702005B8B02001D8902005287020037 -+:10725000DF880200778E02009F8C020036880200D1 -+:10726000C3860200028C020041860200B08902003F -+:10727000788B0200028A0200658E020086F8BB0449 -+:10728000FF2299492846EAF7A3FBFF2286F8BF04AC -+:1072900096492846EAF79CFB954986F8C00428469B -+:1072A000EAF7A2FB0022A6F8C20492492846EAF7B0 -+:1072B0008FFB002286F818058F492846EAF788FBDD -+:1072C000C0B286F81A05EB69DB685B6C03F0070354 -+:1072D000052B03D910B1002386F81A3587490022FF -+:1072E0002846EAF775FB864986F81C0500222846E1 -+:1072F000EAF76EFB834986F81D054FF0FF322846FA -+:10730000EAF766FB804986F81E0500222846EAF760 -+:107310005FFB7E4986F895054FF0FF322846EAF775 -+:1073200057FB7B49A6F8200501222846EAF750FBC7 -+:10733000784986F827054FF0FF322846EAF748FBE0 -+:107340007549A6F82A054FF0FF322846EAF740FBB8 -+:107350007249A6F82C0500222846EAF739FB704945 -+:1073600086F83A0500222846EAF732FB6D4986F88E -+:107370003B054FF0FF322846EAF72AFB6A4986F8B8 -+:107380003C052846EAF7FCFA30B128466649EAF798 -+:107390002BFB86F8420503E04FF0FF3386F84235B9 -+:1073A00028466249EAF7ECFA30B128465F49EAF725 -+:1073B0001BFBA6F8440503E04FF0FF33A6F8443565 -+:1073C0005B4928464FF0FF32EAF702FB5949A6F81D -+:1073D00090052846EAF7D4FA30B301245549002233 -+:1073E00086F852452846EAF7EDFA524986F85305E1 -+:1073F00022462846EAF7E6FA4E4986F85405022264 -+:107400002846EAF7DFFA4B4986F855050322284655 -+:10741000EAF7D8FA474986F8560504222846EAF7DB -+:10742000D1FA86F8570501E086F8520542494FF037 -+:10743000FF322846EAF7CCFA404986F858054FF063 -+:10744000FF322846EAF7C4FA3D4986F859054FF05D -+:10745000FF322846EAF7BCFA3A4986F85A05002274 -+:107460002846EAF7B5FA384986F87005002228461A -+:10747000EAF7AEFA032286F8800534492846EAF78F -+:10748000A7FA334986F881052846EAF7ADFA31496B -+:1074900086F882052846EAF7A7FA2F49A6F8840558 -+:1074A0002846EAF7A1FA2D49A6F886052846EAF704 -+:1074B0009BFA2B49A6F888052846EAF795FA294948 -+:1074C000A6F88A052846EAF78FFA2749C6F88C05F8 -+:1074D00000222846EAF77CFA86F89405012000E0AD -+:1074E000002006B0BDE8F081FA8C0200418D020058 -+:1074F0008A860200E58502000C8B0200138A0200D6 -+:10750000638C0200558A0200CB850200AF8702001F -+:10751000B9850200D7860200BC8702009F86020060 -+:10752000C88702001F8B02009B880200358602007C -+:10753000DC8702005286020069890200748C020016 -+:10754000338702001089020019880200F7870200C1 -+:107550004B880200C98B0200398C0200828A02002B -+:10756000C88A0200EF880200918D0200C36970B5DD -+:1075700004460E4698684FF4B961DFF3A9F3C4F8E6 -+:10758000A80000285BD000214FF4B962DAF358F567 -+:10759000E369D4F8A8501B6D13F4803F05D1012294 -+:1075A00041F2140384F81A26E254E369D868E3F739 -+:1075B00049FD0023C4F8F80FEB63224B20462362F9 -+:1075C000214B31466362214BA362214BE362214B85 -+:1075D000A367214BE367214BC4F89030204BC4F8DC -+:1075E0008430204B2363204B6363204BE363204BA9 -+:1075F0006364204B6365204BA365204BC4F88C303B -+:107600001F4BC4F888301F4BE3661F4BC4F89C30F7 -+:107610001E4BC4F8A0301E4BC4F8A430FEF7DAFFAE -+:1076200068B12046ECF7CEF82046FEF73DFF30B1BA -+:107630002046FEF793FF003818BF012000E000202D -+:1076400070BDC0465DA30100A51D010045A001005D -+:107650001175010075730100DD210100317C01000D -+:10766000197C0100896E0100795A0100F96E010050 -+:10767000B95701005D280100612A0100359F010012 -+:10768000851E010071260100D55A0100D154010068 -+:10769000FD9E010010B5014620B103680C22186858 -+:1076A000DFF326F310BDC0462DE9F04105460F4635 -+:1076B00000680C211646DFF30BF308B9044607E017 -+:1076C000044600210C22DAF3BBF425606660A76053 -+:1076D0002046BDE8F081C04610B5044650B10649C9 -+:1076E00022464068FCF330F463682146D86888225B -+:1076F000DFF3FEF210BDC04603E88600F0B5882136 -+:1077000085B005464068DFF3E3F2074608B9044652 -+:107710003BE0002188220446DAF392F42B683D60B6 -+:107720007B60002604212846194A1A4B00960197CF -+:1077300000F0EEF8B042B86021DB174B01960093E1 -+:107740000296039678681549154A3B46FCF3C4F344 -+:10775000A8B91E237B610423FB7302233B74083307 -+:1077600001227B744FF6AF7384F82000FA773A73E6 -+:10777000BA61A0746073A073BB83BA7705E06868D0 -+:1077800039468822DFF3B4F20024204605B0F0BD6C -+:1077900051238500252385008114850050EC0100CC -+:1077A00003E8860070B50468CCB1D4F8F811A56878 -+:1077B00029B1A868E7F364F70023C4F8F831084951 -+:1077C00028682246FCF3C0F3216819B168681C22BE -+:1077D000DFF38EF2686821466269DFF389F270BDDB -+:1077E00068EC01002DE9FF4740F2C45681468A4605 -+:1077F0001046314617469846DFF36AF204460028E1 -+:1078000079D000213246DAF31BF438461C21DFF32D -+:107810005FF20546206030B9384621463246DFF334 -+:1078200067F2284667E000211C22DAF309F4226897 -+:107830004FF0FF33A36100254FF014036661C4F8D5 -+:107840000890E760C4F804809571A4F808324FF0FE -+:107850002803A4F806324FF02D03A4F804324FF0A9 -+:10786000FA03A4F80A320223146084F80C324FF0B1 -+:107870006403A4F83E3284F80D5250461F49224654 -+:107880002B46E7F319F7C4F8F80108B30523C4F849 -+:107890001C323733C4F8283204F51072184BC4F880 -+:1078A0001822C4F8142204F53D72C4F82422C4F846 -+:1078B00020220093134BD9F8000003931249134A76 -+:1078C000234601950295FCF307F308B9206812E0FE -+:1078D000D4F8F81111B15046E7F3D2F6216819B186 -+:1078E00038461C22DFF304F23846214640F2C452E7 -+:1078F000DFF3FEF1002004B0BDE8F087C13C850055 -+:10790000F5378500E9A4010070EC010068EC010086 -+:1079100070B5D0F800451E46A3698E460F2B15465C -+:1079200002D94FF0FF3011E01801E1690133A36182 -+:10793000049B42189360059B5660D3606269455072 -+:10794000D31C734423F003036361104670BDC0462B -+:1079500010B5014640B190F820200368D200D868E5 -+:1079600002F59272DFF3C4F110BDC046C36908226C -+:107970001B692DE9F041073393FBF2F3DFB2FB0003 -+:1079800003F5927605463146C068DFF3A1F108B9E8 -+:10799000044614E0044632460021DAF351F304F1C0 -+:1079A0002403E361FAB204F59273E36003EB82030C -+:1079B00023614FF40373256084F8207063612046CF -+:1079C000BDE8F0817047C0462DE9F04F3B4F89B0CC -+:1079D00038683B49DAF3D0F70128DFF81881DFF87F -+:1079E000189157D0DFF800C1364EDCF800100022A5 -+:1079F0000091354913680968344D354C029131685E -+:107A00003448019304912B6821680393069103681D -+:107A1000314905930B68DFF8D4E007932A4B0260E5 -+:107A20002E481A600A602E4B08F10401D7F800A016 -+:107A3000DEF800B03A60CEF80020CCF800203260CA -+:107A40002260091A013A2B60DAF3EAF7254B9842D3 -+:107A5000FCD11A4B0099C3F800A0234B1960234BAB -+:107A60000021C3F800B00A68214B1A60019A164B36 -+:107A70000A600299039A1960144B04991A60114B19 -+:107A8000059A1960134B06991A60114B079A1960F1 -+:107A9000114B1A6098F81B3089F8003098F81C30A8 -+:107AA00089F8013098F81D3089F8023098F81E30B6 -+:107AB00089F8033009B0BDE8F08FC046ECED010055 -+:107AC000DCEC0100CCA30000D0A30000BCA30000AC -+:107AD000D8A30000D4A30000DCA300000000000035 -+:107AE000DDBAADBBE320BBDEF0ED0100E8ED010047 -+:107AF000C0A30000BE24030018F501002DE9F04FDB -+:107B000091B0FFF761FF684B1B68043B012B03D862 -+:107B1000664B1868FFF756FFFAF7AEFF00210746DD -+:107B2000E3F3C4F338460021E3F37AF328B1036AA0 -+:107B3000002BBCBF4FF0004303620EA90822B86BB4 -+:107B4000DAF30CF5FA6B0B9038460C92E3F77AFAFD -+:107B5000574E00F5424000F5A870B0FBF6F00D90CE -+:107B60003846E3F76FFA04463846E3F76BFA00F558 -+:107B700042483846E3F770FA00F5424A3846E3F7E0 -+:107B80006BFA04F5424408F5A87804F5A874B8FB2C -+:107B9000F6F808FB164804463846E3F75DFA00F5A8 -+:107BA00042453846E2F7E2FF00F542493846E2F73F -+:107BB000DDFF04F5424405F5A87504F5A874B5FB8E -+:107BC000F6F505FB164504463846E2F7CFFF394A7D -+:107BD00000F54240019204F542440B9A00F5A8706A -+:107BE000B0FBF6F00AF5A87A09F5A87904F5A874AF -+:107BF000BAFBF6FAB9FBF6F9029200FB16460C9AAC -+:107C0000DFF8D4B003920D9A2B4B04922B492C4AE7 -+:107C1000B8FBFBF8B5FBFBF5B6FBFBF62948009378 -+:107C2000CDF81480CDF818A00795CDF820900996CE -+:107C3000E7F744FA244840F60D0144F2F432FAF72B -+:107C40009FFE48B1204840F6290144F2F432FAF789 -+:107C500097FE08B1002403E01C4A1D4B1A4C1A6021 -+:107C60003846FDF7C7F944F218334FF6FF729042D9 -+:107C700014BF02461A4640F612011648FAF780FE73 -+:107C8000144B00280CBF194600214CB141B1104BD8 -+:107C900020461B685B689847236920465B689847C5 -+:107CA000384611B0BDE8F08FDCA30000D8A3000077 -+:107CB00040420F00A4C30100ABFF8600E2EC0100CC -+:107CC000E7EC0100BC9D02003CEE010018EE010053 -+:107CD000F826000068EE0100A086010025733A2016 -+:107CE00042726F6164636F6D20534450434D442072 -+:107CF000434443206472697665720A00736470635A -+:107D00006D6463646325640072737369736D6632B6 -+:107D1000673D2564007874616C667265713D256409 -+:107D200000616132673D30782578006277343070C9 -+:107D30006F3D30782578006C6564626825643D305D -+:107D40007825780074737369706F7332673D30788B -+:107D50002578007273736973617632673D2564001C -+:107D60006C65676F66646D3430647570706F3D303C -+:107D70007825780070613168696D61787077723D3F -+:107D80002564006D617870326761303D3078257808 -+:107D9000007061316974737369743D2564006D61AD -+:107DA0006E6669643D307825780073756276656E1D -+:107DB0006469643D30782578002004D0023643FFA2 -+:107DC000FF626F617264747970653D307825780068 -+:107DD0006D6373256467706F25643D307825780086 -+:107DE0006D616E663D2573006D61787035676C61FD -+:107DF000303D30782578006D61787035676C613181 -+:107E00003D30782578006F66646D35676C706F3D26 -+:107E1000307825780072737369736D6335673D251B -+:107E20006400626F617264666C616773323D3078C2 -+:107E3000257800747269736F32673D307825780059 -+:107E40007064657472616E676532673D307825785D -+:107E5000006D63736277323035676C706F3D3078D8 -+:107E600025780000006D637362773230756C35677A -+:107E70006C706F3D30782578006D637362773430B5 -+:107E800035676C706F3D3078257800000070613187 -+:107E90006C6F6D61787077723D2564006D617870EC -+:107EA000326761313D30782578007278706F3567C0 -+:107EB0003D2564006D63733332706F3D30782578F3 -+:107EC0000073756264657669643D30782578006971 -+:107ED0007474356761303D30782578006974743585 -+:107EE0006761313D30782578007061316D6178705F -+:107EF00077723D256400626F6172647265763D3011 -+:107F0000782578006D6373627732303267706F3D29 -+:107F1000307825780000006D637362773230756CBD -+:107F20003267706F3D30782578006D637362773407 -+:107F3000303267706F3D307825780000006D6373D4 -+:107F40006277323035676D706F3D3078257800008C -+:107F5000006D637362773230756C35676D706F3D9D -+:107F600030782578006D63736277343035676D70D3 -+:107F70006F3D3078257800000073726F6D72657602 -+:107F80003D2564007770736C65643D256400706105 -+:107F9000316C6F62303D2564007061316C6F62310D -+:107FA0003D2564007061316C6F62323D2564007064 -+:107FB0006125646725637725646125643D307825F4 -+:107FC000780070613062303D25640070613062314C -+:107FD0003D25640070613062323D25640072737328 -+:107FE00069736D6332673D25640074726935676833 -+:107FF0003D25640075736266733D25640063636BA1 -+:10800000706F3D307825780074726935676C3D2556 -+:1080100064006F66646D356768706F3D30782578F1 -+:1080200000616725643D307825780065787470615B -+:108030006761696E35673D307825780070726F64CE -+:108040007563746E616D653D257300636464706F64 -+:108050003D30782578006C65676F66646D627732B5 -+:108060003035676C706F3D307825780000006C65A6 -+:10807000676F66646D62773230756C35676C706FF0 -+:108080003D30782578006C65676F66646D62773285 -+:108090003035676D706F3D307825780000006C6575 -+:1080A000676F66646D62773230756C35676D706FBF -+:1080B0003D30782578006C65676F66646D62773255 -+:1080C00030356768706F3D307825780000006C654A -+:1080D000676F66646D62773230756C356768706F94 -+:1080E0003D30782578007278706F32673D256400E6 -+:1080F0007278636861696E3D3078257800697474C0 -+:10810000326761303D307825780069747432676178 -+:10811000313D3078257800616E74737769746368D7 -+:108120003D30782578007478636861696E3D3078F9 -+:1081300025780070726F6469643D3078257800702E -+:1081400061306974737369743D25640063636B64A3 -+:10815000696766696C74747970653D25640063684D -+:1081600069707265763D2564006F66646D35677071 -+:108170006F3D30782578006C656464633D30782508 -+:10818000303478006D61787035676861303D3078E3 -+:108190002578006D61787035676861313D307825EC -+:1081A000780070613162303D256400706131623168 -+:1081B0003D25640070613162323D25640062776460 -+:1081C0007570706F3D30782578006D617870356717 -+:1081D00061303D30782578006D61787035676131A8 -+:1081E0003D3078257800616E74737763746C356701 -+:1081F0003D30782578006D63732564672563706F63 -+:1082000025643D30782578006D63736277323035B0 -+:108210006768706F3D307825780000006D63736289 -+:10822000773230756C356768706F3D30782578002F -+:108230006D637362773430356768706F3D307825D1 -+:108240007800000074726935673D2564006F706FB7 -+:108250003D25640076656E6469643D30782578005C -+:108260006C65676F66646D627732303267706F3D40 -+:108270003078257800006C65676F66646D627732D0 -+:1082800030756C3267706F3D307825787061306D75 -+:1082900061787077723D2564007061316869623081 -+:1082A0003D256400706131686962313D256400706C -+:1082B0006131686962323D256400637573746F6D66 -+:1082C00076617225643D3078257800726567726545 -+:1082D000763D3078257800626F617264666C616704 -+:1082E000733D307825780062786132673D256400FF -+:1082F0006F656D3D25303278253032782530327803 -+:108300002530327825303278253032782530327871 -+:10831000253032780064657669643D3078257800D0 -+:1083200070612564677725646125643D3078257820 -+:108330000072737369736D6635673D2564006F66FF -+:10834000646D3267706F3D30782578006161356704 -+:108350003D30782578007770736770696F3D2564CC -+:108360000062786135673D25640075736265706EE3 -+:10837000756D3D307825780074737369706F73354F -+:10838000673D3078257800616E74737763746C3262 -+:10839000673D30782578007273736973617635674D -+:1083A0003D2564006F66646D706F3D307825780000 -+:1083B00074726932673D25640073746263706F3D47 -+:1083C000307825780063636F64653D307830006DE8 -+:1083D0006163616464723D25730063636F64653D2E -+:1083E000256325630063633D25640063636B326727 -+:1083F000706F3D30782578006363746C3D3078256C -+:10840000780072656777696E646F77737A3D25646B -+:108410000065787470616761696E32673D307825F8 -+:108420007800626F6172646E756D3D2564007472D0 -+:1084300069736F35673D307825780063636B6277C9 -+:1084400032303267706F3D3078257800000063630A -+:108450006B62773230756C3267706F3D307825789B -+:10846000007064657472616E676535673D307825AC -+:108470007800000080000000FF0000000C000000F9 -+:108480000000000000040000FF0000000C000000DD -+:108490000000000000000800FF0000000E000000C7 -+:1084A00000000000020000000100040003000000C2 -+:1084B000010002000A00000002006000DC0500006C -+:1084C00008071700776C25643A2042726F61646375 -+:1084D0006F6D2042434D2564203830322E313120DB -+:1084E000576972656C65737320436F6E74726F6C3D -+:1084F0006C65722025730A00747870777262636B02 -+:108500006F660032675F6367610072737369636FE0 -+:1085100072726E6F726D0074656D707468726573DF -+:10852000680074656D70735F6879737465726573E4 -+:1085300069730072737369636F7272617474656ECC -+:108540000035675F63676100747373696C696D758B -+:10855000636F6400696E746572666572656E6365EB -+:10856000006D63733267706F30006D6373326770D4 -+:108570006F3100747373696F66667365746D696ECD -+:1085800035676C00747373696F66667365746D69C3 -+:108590006E35676D0074656D7073656E73655F73BE -+:1085A0006C6F7065006D656173706F7765720072D6 -+:1085B000737369736D66326700706C6C646F75629B -+:1085C0006C65725F6D6F646532670069716C6F73A3 -+:1085D00074316F6666326700726672656730333376 -+:1085E0005F63636B00706C6C646F75626C65725F67 -+:1085F000656E61626C653267006F70656E6C706786 -+:1086000061696E69647861313430006578747061D5 -+:108610006761696E35670065787470616761696E5E -+:108620003267006F70656E6C706761696E6964783F -+:108630006131343900747869716C6F7061673267C9 -+:10864000006E6F6973655F63616C5F7265665F3250 -+:1086500067006C6F67656E5F6D6F64650070616366 -+:10866000616C69647832670074656D705F61646421 -+:1086700000706163616C61746832673100646163CA -+:108680006763326700706D696E00706163616C7062 -+:10869000756C7365776964746800706D61780074D7 -+:1086A000786761696E74626C006F70656E6C70746F -+:1086B000656D70636F727200747373696D61786E4B -+:1086C0007074006E6F6973655F63616C5F656E6186 -+:1086D000626C655F356700706163616C70777232E0 -+:1086E0006700747869716C6F746600706163616CA7 -+:1086F00069647835676C6F3100706163616C6174B7 -+:108700006835676869006F70656E6C707077726C41 -+:10871000696D006E6F6973655F63616C5F6462674A -+:10872000006F70656E6C706761696E696478613145 -+:10873000353300706163616C69647835676869001E -+:108740006F70656E6C706761696E696478613135F0 -+:1087500037006E6F6973655F63616C5F757064612C -+:108760007465006F70656E6C706761696E696478BE -+:1087700061313635006F66646D64696766696C7473 -+:10878000747970653567007061676332670076627F -+:1087900061745F6D756C740073776374726C6D6176 -+:1087A000705F326700706163616C616C696D006954 -+:1087B000716C6F63616C70777232670070616361B6 -+:1087C0006C7077723267310074786761696E7462B9 -+:1087D0006C35670076626174736D63006164637207 -+:1087E0006673657132670076626174736D660076D8 -+:1087F0006261747361760072786761696E62616349 -+:108800006B6F666676616C006F70656E6C70676129 -+:10881000696E6964786225640072786761696E7454 -+:10882000626C776C62676100706163616C6174682F -+:108830003567686931006E6F6973655F63616C5F8E -+:10884000706F5F626961735F32670072667265673D -+:10885000303838006F70656E6C706761696E69647E -+:1088600078613136310064796E7077726C696D654C -+:108870006E00706163616C6964783567310074659E -+:108880006D70636F727278006461637261746532D7 -+:10889000670070613062325F6C6F00747869716C70 -+:1088A0006F7061707532670074656D7073656E739B -+:1088B000655F6F7074696F6E00706163616C617485 -+:1088C0006835676C6F3100706163616C6964783220 -+:1088D0006731007478616C70666279703267006E1F -+:1088E0006F6973655F63616C5F706F5F326700759E -+:1088F0006E6D6F645F727373695F6F6666736574C4 -+:10890000006F70656E6C70766F6C74636F7272005E -+:1089100072786761696E74626C313030006E6F69B5 -+:1089200073655F63616C5F6E665F737562737472AB -+:108930006163745F76616C007473736974786465E5 -+:108940006C61790063636B3267706F0063636B50B7 -+:108950007772496478436F72720063636B6469670E -+:1089600066696C7474797065006C6F696461636DBD -+:108970006F6465356700706163616C617468356749 -+:108980000074656D705F7100727373697361763224 -+:10899000670070613062315F6C6F00706163616CA1 -+:1089A000617468356731006D6178703267613000DD -+:1089B0006E6F6973655F63616C5F7265665F356773 -+:1089C000006F66646D616E616C6F6766696C74627E -+:1089D00077326700706163616C6174683267007040 -+:1089E000613062300070613062310070613062323B -+:1089F000006F70656E6C706761696E696478613371 -+:108A000036006E6F6973655F63616C5F61646A5F96 -+:108A100035670069716C6F63616C69647832676F88 -+:108A2000666673006F70656E6C706761696E69640D -+:108A300078613130300072617774656D7073656E86 -+:108A40007365006F70656E6C706761696E696478DC -+:108A5000613130340069716C6F63616C69647832C4 -+:108A600067006F70656E6C707077726374726C0003 -+:108A70006F70656E6C706761696E696478613130C2 -+:108A8000380072786761696E74656D70636F7272B9 -+:108A900035676D0074785F746F6E655F706F7765B2 -+:108AA000725F696E646578006F70656E6C70726578 -+:108AB000667077720072737369736D6332670070EA -+:108AC000613062305F6C6F0072786761696E7465E7 -+:108AD0006D70636F727235676C00706163616C6991 -+:108AE000647835673174680070616763356700705A -+:108AF0006163616C69647835676C6F3174680073A9 -+:108B0000776374726C6D61705F3567007370757236 -+:108B100061766F69645F656E61626C653267006C77 -+:108B20006F63636D6F646531006F70656E6C706745 -+:108B300061696E696478613430006F70656E6C7065 -+:108B40006761696E69647861343400726672656762 -+:108B500030333300706172667073006E6F697365D5 -+:108B60005F63616C5F686967685F6761696E007207 -+:108B700066726567303338006E6F6973655F636175 -+:108B80006C5F61646A5F326700706163616C696425 -+:108B9000783567686931006D656173706F776572EC -+:108BA00031006D656173706F77657232006F70654B -+:108BB0006E6C706761696E6964786131313600622C -+:108BC0007068797363616C650072786761696E744F -+:108BD000656D70636F727232670061613267006F3A -+:108BE00066646D64696766696C7474797065007435 -+:108BF000656D705F6D756C74006F66646D32677063 -+:108C00006F006E6F6973655F63616C5F706F5F6249 -+:108C10006961735F356700766261745F71007061CE -+:108C200063616C61746835676C6F00706163616C5F -+:108C300069647832673174680072786761696E744C -+:108C4000656D70636F72723567680063636B507730 -+:108C5000724F6666736574007478707772696E64BB -+:108C600065780069716C6F63616C69647835676FF2 -+:108C700066667300706163616C69647835676C6FF8 -+:108C800000676D6763326700706163616C69647867 -+:108C900035676869317468007278706F3267006E8A -+:108CA0006F6973655F63616C5F656E61626C655F60 -+:108CB0003267006F70656E6C706761696E696478A9 -+:108CC000613532006F70656E6C706761696E6964E2 -+:108CD00078613536006F70656E6C706761696E69BA -+:108CE00064786131313200706163616C6964783538 -+:108CF000670074656D7073617600747269736F32AA -+:108D00006700766261745F616464006F70656E6CA9 -+:108D1000706761696E69647861313230006F7065C7 -+:108D20006E6C706761696E69647861313234006FAE -+:108D300070656E6C706761696E6964786131323834 -+:108D40000074726964783267006F66646D64696785 -+:108D500066696C74747970653267006F70656E6CEB -+:108D6000706761696E69647861343800696E69742E -+:108D70007869647832670068775F697163616C5FF6 -+:108D8000656E00697163616C5F7377705F646973AE -+:108D9000006D75785F6761696E5F7461626C650014 -+:108DA000747373696F66667365746D61783567682F -+:108DB00000747373696F66667365746D6178356787 -+:108DC0006C00747373696F66667365746D61783572 -+:108DD000676D0074656D70736D630074656D70739D -+:108DE0006D6600747373696F66667365746D617820 -+:108DF000006F70656E6C706761696E69647861366A -+:108E000030007478616C706662797032675F63639A -+:108E10006B006F70656E6C706761696E6964786114 -+:108E2000363400667265716F66667365745F636F72 -+:108E3000727200747373696F66667365746D696EC0 -+:108E4000006F70656E6C706761696E69647861311E -+:108E50003332006F70656E6C706761696E6964783B -+:108E600061313336007874616C6D6F6465007473C2 -+:108E7000736974696D65006E6F6973655F63616CBA -+:108E80005F706F5F356700747373696F66667365D3 -+:108E9000746D696E356768008C9302006000000095 -+:108EA000120000000000000020000000FC92020000 -+:108EB000260000000E00000000000000100000006E -+:108EC00088980200980000000D00000000000000DB -+:108ED0002000000048930200440000001100000040 -+:108EE0000000000008000000489D02001000000083 -+:108EF000100000000000000008000000000000005A -+:108F00004000000080000000C000000001000000E0 -+:108F10000500000002000000060000000A0000003A -+:108F20004A0000008A000000CA0000000A01000098 -+:108F30004A0100008A0100008A0500008A09000039 -+:108F40008A0D00008A1100008A5100008A910000F9 -+:108F50008AD100008A1101008A5101008A91010022 -+:108F6000890000008AD101008A110200000000007F -+:108F700000000000000000000000000000000000F1 -+:108F800000000000000000000000000000000000E1 -+:108F900000000000000000000000000000000000D1 -+:108FA00000000000000000000000000000000000C1 -+:108FB00000000000000000000000000000000000B1 -+:108FC00000000000000000000000000000000000A1 -+:108FD0000000000000000000000000000000000091 -+:108FE0000000000000000000000000000000000081 -+:108FF0000000000000000000000000000000000071 -+:109000000000000000000000000000000000000060 -+:109010000000000000000000000000000000000050 -+:109020000000000000000000000000000000000040 -+:109030000000000000000000000000000000000030 -+:109040000000000000000000000000000000000020 -+:109050000000000000000000000000000000000010 -+:109060000000000000000000000000000000000000 -+:1090700000000000000000000000000003001300DA -+:10908000410300130040030012004103001200409E -+:1090900003001100410300110040030010004103D0 -+:1090A00000100040030010003E030010003C0300CD -+:1090B00010003A03000F003D03000F003B03000EB9 -+:1090C000003D03000E003C03000E003A03000D00BB -+:1090D0003C03000D003B03000C003E03000C003C71 -+:1090E00003000C003A03000B003E03000B003C039E -+:1090F000000B003B03000B003903000A003D030096 -+:109100000A003B03000A0039030009003E0300097E -+:10911000003C030009003A0300090039030008007D -+:109120003E030008003C030008003A030008003931 -+:109130000300080037030007003D030007003C035D -+:109140000007003A03000700380300070037030058 -+:1091500006003E030006003C030006003A0300063A -+:10916000003903000600370300060036030006003E -+:1091700034030005003D030005003B0300050039F2 -+:109180000300050038030005003603000500350321 -+:1091900000050033030004003E030004003C03000C -+:1091A00004003A03000400390300040037030004FC -+:1091B00000360300040034030004003303000400FD -+:1091C000310300040030030004002E030003003CC0 -+:1091D000030003003A0300030039030003003703D0 -+:1091E00000030036030003003403000300330300D0 -+:1091F0000300310300030030030003002E030003CB -+:10920000002D030003002C030003002B03000300C8 -+:1092100029030002003D030002003B030002003965 -+:109220000300020038030002003603000200350389 -+:10923000000200330300020032030002003003008A -+:1092400002002F030002002E030002002C03000284 -+:10925000002B030002002A03000200290300020081 -+:109260002703000200260300020025030002002459 -+:109270000300020023030002002203000200210376 -+:1092800000020020030001003F030001003D030035 -+:1092900001003B0300010039030001003803000115 -+:1092A0000036030001003503000100330300010014 -+:1092B000320300010030030001002F030001002EE3 -+:1092C000030001002C030001002B030001002A030E -+:1092D000000100290300010027030001002603000C -+:1092E0000100250300010024030001002303000105 -+:1092F00000220300010021030001002000040004FB -+:10930000000400040004000400040004000400043D -+:109310000004010480048204830484040004000423 -+:10932000000400040004000400040004000401041C -+:1093300080048204830484048504860405050605EC -+:109340000705080509050A05090C12181818090C63 -+:109350001218181800000C076F7A060C0F7B7E019C -+:1093600005080B0E110000000000000000000306BD -+:10937000090C0F12000000000000000000000306AE -+:10938000090C0000000000000000000000000000C8 -+:10939000040000004000000080000000C000000049 -+:1093A00001000000050000004500000085000000ED -+:1093B000C500000005010000450100008501000016 -+:1093C0008505000085090000850D00008909000061 -+:1093D000890D000089110000895100008991000069 -+:1093E00089D1000089110100854D0000858D0000A4 -+:1093F00085CD000089510100899101000000000025 -+:10940000000000000000000000000000000000005C -+:10941000000000000000000000000000000000004C -+:10942000000000000000000000000000000000003C -+:10943000000000000000000000000000000000002C -+:10944000000000000000000000000000000000001C -+:10945000000000000000000000000000000000000C -+:1094600000000000000000000000000000000000FC -+:1094700000000000000000000000000000000000EC -+:1094800000000000000000000000000000000000DC -+:1094900000000000000000000000000000000000CC -+:1094A00000000000000000000000000000000000BC -+:1094B00000000000000000000000000000000000AC -+:1094C000000000000000000000000000000000009C -+:1094D000000000000000000000000000000000008C -+:1094E000000000000000000000000000000000007C -+:1094F000000000000000000000000000000000006C -+:10950000000000000000000000000000800080005B -+:10951000800080008000800080008000800081004A -+:109520008200830084008500040105018000800022 -+:109530008000800080008000800081008200830025 -+:109540008400850004010501060107011901870156 -+:10955000880189018A018B0107001F004807001F4D -+:10956000004607001F004407001E004307001D00BF -+:109570004407001C004407001B004507001A004672 -+:1095800007001900460700180047070017004807A2 -+:10959000001700460700160047070015004807009F -+:1095A0001500460700150044070015004207001586 -+:1095B0000040070015003F0700140040070013009B -+:1095C000410700130040070012004107001200404D -+:1095D000070011004107001100400700100041077B -+:1095E00000100040070010003E070010003C07007C -+:1095F00010003A07000F003D07000F003B07000E68 -+:10960000003D07000E003C07000E003A07000D0069 -+:109610003C07000D003B07000C003E07000C003C1F -+:1096200007000C003A07000B003E07000B003C0748 -+:10963000000B003B07000B003907000A003D070044 -+:109640000A003B07000A0039070009003E0700092D -+:10965000003C070009003A0700090039070008002C -+:109660003E070008003C070008003A0700080039E0 -+:109670000700080037070007003D070007003C0708 -+:109680000007003A07000700380700070037070007 -+:1096900006003E070006003C070006003A070006E9 -+:1096A00000390700060037070006003607000600ED -+:1096B00034070005003D070005003B0700050039A1 -+:1096C00007000500380700050036070005003507CC -+:1096D00000050033070004003E070004003C0700BB -+:1096E00004003A07000400390700040037070004AB -+:1096F00000360700040034070004003307000400AC -+:10970000310700040030070004002E070003003C6E -+:10971000070003003A07000300390700030037077A -+:10972000000300360700030034070003003307007E -+:109730000300310700030030070003002E07000379 -+:10974000002D070003002C070003002B0700030077 -+:1097500029070002003D070002003B070002003914 -+:109760000700020038070002003607000200350734 -+:109770000002003307000200320700020030070039 -+:1097800002002F070002002E070002002C07000233 -+:10979000002B070002002A07000200290700020030 -+:1097A0002707000200260700020025070002002408 -+:1097B0000700020023070002002207000200210721 -+:1097C00000020020070001003F070001003D0700E4 -+:1097D00001003B0700010039090C12181818090C88 -+:1097E0001218181800000C076F7A060C0F7B7E0108 -+:1097F00005080B0E11000000000000000000030629 -+:10980000090C0F1200000000000000000000030619 -+:10981000090C00000000000000000000070010001C -+:109820003907001000380700100036070010003418 -+:109830000700100033070010003107001000300748 -+:109840000010002F070010002D070010002C07004B -+:1098500010002B070010002A070010002807001036 -+:109860000027070010002607001000250700100041 -+:109870002407001000230700100022070010002119 -+:109880000700100020000000000000004000000061 -+:109890000000000040000000000000004000000048 -+:1098A0000000000040000000000000004000000038 -+:1098B0000000000040000000000000004000000028 -+:1098C0000000000040000000000000004000000018 -+:1098D0000000000040000000000000004000000008 -+:1098E00000000010400000000000000048000000E0 -+:1098F0000000002048000000000000304800000088 -+:109900000000004048000000000000504800000037 -+:1099100000000060480000000000005050000000FF -+:1099200000000060500000000000007050000000C7 -+:109930000000008050000000000000905000000077 -+:10994000000000A050000000000000B05000000027 -+:10995000000000C050000000000000D050000000D7 -+:10996000000000E050000000000000F05000000087 -+:10997000000000E058000000000000005900000056 -+:1099800000000010590000000000002059000000F5 -+:1099900000000030590000000000004059000000A5 -+:1099A0000000005059000000000000605900000055 -+:1099B0000000000040000000000000004000000027 -+:1099C0000000000040000000000000004000000017 -+:1099D0000000000040000000000000004000000007 -+:1099E00000000000400000000000000040000000F7 -+:1099F00000000000400000000000001040000000D7 -+:109A000000000000480000000000002048000000A6 -+:109A10000000003048000000000000404800000046 -+:109A200000000050480000000000006048000000F6 -+:109A300000000050500000000000006050000000D6 -+:109A40000000007050000000000000805000000086 -+:109A50000000009050000000000000A05000000036 -+:109A6000000000B050000000000000C050000000E6 -+:109A7000000000D050000000000000E05000000096 -+:109A8000000000F0500000000000007051000000D5 -+:109A90000000008051000000000000905100000014 -+:109AA00000000020590000000000003059000000B4 -+:109AB0000000004059000000000000505900000064 -+:109AC0000000006059000000000000A059000000E4 -+:109AD000000000B05900000000000000000000007D -+:109AE000000000000000000000000000080000006E -+:109AF0000000000008000000000000000800000056 -+:109B00000000000008000000000000000800000045 -+:109B10000000000008000000000000000800000035 -+:109B20000000000008000000000000000800000025 -+:109B300000000010080000000000002008000000E5 -+:109B40000000003008000000000000400800000095 -+:109B5000000000500800000000000040100000005D -+:109B60000000005010000000000000601000000025 -+:109B700000000070100000000000008010000000D5 -+:109B800000000070180000000000008018000000B5 -+:109B90000000009018000000000000A01800000065 -+:109BA000000000B018000000000000C01800000015 -+:109BB000000000D018000000000000E018000000C5 -+:109BC000000000F018000000000000001900000074 -+:109BD0000000001019000000000000201900000023 -+:109BE00000000030190000000000004019000000D3 -+:109BF0000000005019000000000000601900000083 -+:109C00000000007019000000000000801900000032 -+:109C10000000000008000000000000000800000034 -+:109C20000000000008000000000000000800000024 -+:109C30000000000008000000000000000800000014 -+:109C400000000000080000000000001008000000F4 -+:109C500000000020080000000000003008000000A4 -+:109C60000000004008000000000000500800000054 -+:109C70000000004010000000000000501000000034 -+:109C800000000060100000000000007010000000E4 -+:109C9000000000901100000000000070180000009B -+:109CA0000000008018000000000000901800000074 -+:109CB000000000A018000000000000B01800000024 -+:109CC000000000C018000000000000D018000000D4 -+:109CD000000000E018000000000000F01800000084 -+:109CE0000000000019000000000000101900000032 -+:109CF00000000020190000000000003019000000E2 -+:109D00000000004019000000000000501900000091 -+:109D10000000006019000000000000701900000041 -+:109D20000000008019000000000000A019000000E1 -+:109D3000000000B01900000000000000000000005A -+:109D400000000000000000005F36291F5F36291F59 -+:109D50005F36291F5F36291FFC8E0200600000005D -+:109D60001200000000000000200000000C9502001E -+:109D7000260000000E00000000000000100000009F -+:109D8000E89A0200980000000D00000000000000AA -+:109D900020000000D89702004400000011000000DD -+:109DA0000000000008000000489D020010000000B4 -+:109DB0001000000000000000080000000A52544596 -+:109DC000202825732D2573257325732920257320BD -+:109DD0006F6E2042434D257320722564204020255C -+:109DE000642E25642F25642E25642F25642E25647A -+:109DF0004D487A0A000000002DE9FF4106460D4655 -+:109E00000846FC2117469846DCF362F7044608B979 -+:109E10001E302DE00021FC22D8F312F10A9B04F140 -+:109E2000640204F1680100930192029130462946D0 -+:109E30003A464346FBF72EFB206608B90B2017E095 -+:109E400040F612010022E1F3D9F100210A46E06652 -+:109E50002560206EE0F3F6F72046F7F769FF206EE5 -+:109E6000FBF7DAF928462146FC22DCF341F7002013 -+:109E700004B0BDE8F081C0464286000001BC60032A -+:109E800000104E03BFDE02F00BF1035B5E02F00038 -+:109E90000401BC601300104300015E02F0000000EA -+:109EA000025E02F0117700025E02F0118C020200E5 -+:109EB000BF00008302045EFF00000C006B44655786 -+:109EC000800C01846002F7F7BF01BC6003000AAE9A -+:109ED00000025E02F00F000202DEFF000011006BC4 -+:109EE00044655620110182E002F7F7BF03BFDE028E -+:109EF000F005C100682B6F0000160280DEFF000035 -+:109F000083006B44655B60830184E006F577AB00FA -+:109F1000025E02F01126020480C700001802818050 -+:109F2000C700001A01806002F7F7BF01BC600300A0 -+:109F30000AE200902C0300D7A200E02BFEF457A306 -+:109F4000006D446AF4601E00B02BF7000AF8018728 -+:109F50006002F7F7BF00682BDF00002500E94465C9 -+:109F60005EF7A300E8C4695F77A20068DE8B00009B -+:109F700025006DDE8D5F002501876006F7F7BF02C3 -+:109F800007DEFF00002A00E844655B37A2006D5E33 -+:109F9000895B002A0187E002F7F7BF01BC6003007C -+:109FA0000AD900682B0700003500E844655837A13E -+:109FB000006DDE8557403100682B4300003500E816 -+:109FC00044655A17A1006DDE8557403303BFDE029A -+:109FD000F0003501BC6003000AC201BC6003000A46 -+:109FE000C101BC6003000AD001BC6003000AC802C2 -+:109FF00002DEB30000380200420300003800025EB7 -+:10A0000002F00B1902845EB30000830068AB0F00FE -+:10A0100000830283DEB700003C020180C7000056C7 -+:10A0200000B02ACB0017A202802BF300004300B03F -+:10A030002B230017A1006DDE855CE07700685E874A -+:10A0400000004300682C0700004300B02C070017F5 -+:10A05000A200682B0B00004800E844655857A10097 -+:10A060006DDE86F4407700E05E8555F7A1006DDE79 -+:10A0700086F440770202DEBB00005600682ABB006F -+:10A08000005600E8446556D7A100E02ABB0157A25C -+:10A09000006EDE86F440500182E002F5D7AE01BCCE -+:10A0A0006003000AAE03BFDE02F0005600E82ABAE1 -+:10A0B000F437A100902ABB0037A2006E2ABEF440FC -+:10A0C0005400B02ABF0017A20069DE86F440560390 -+:10A0D000BFDE02F000770283DEB700006F028881E6 -+:10A0E000AB00006D02035EB7000083020480C7006E -+:10A0F000005B02005EFF00006D028080BF00006D0B -+:10A1000000682B4300006102802BF300006100B067 -+:10A110002B4B0017BB006E2B22F7608303BFDE02C0 -+:10A12000F0006D0204DEB700006400682B170860C1 -+:10A130008303BFDE02F0006D028400C700006602E8 -+:10A140008600C700006800682B0B00006D02812CA0 -+:10A150004700006D00E844655737A1006DDE855863 -+:10A16000006D006CC46557608300B04467000ABB93 -+:10A1700002845EB700008300025E02F0114303BF59 -+:10A18000DE02F0008301BC63FF1FF7A10068458673 -+:10A19000F4206D0203C57300007702845EB70000EF -+:10A1A00077020100C7000083006B4465578083007D -+:10A1B00020E3FE1460830282DEBB000083028881FC -+:10A1C000AB0000830282DEB3000083028080BF0008 -+:10A1D00000830284DEAF00008302825EBB00008346 -+:10A1E00003A0DE02F0007F0200420300007F0002B5 -+:10A1F0005E02F00B1901836002F5B7AD0184E00641 -+:10A20000F577AB01BC6003000AC300B04467000AE5 -+:10A21000C4018060020D906C03595E02F00085035A -+:10A22000D85E02F0008603D8DE02F0008701BC6130 -+:10A230008300112900B0007B00112B01BC630300D7 -+:10A24000112303125E02F00A9303975E02F00B2AB9 -+:10A25000020181B300009A0285C52300009A02879B -+:10A2600081B300009303A3DE02F0009A03A0DE0294 -+:10A27000F0009A00025E02F00B190187E0040D80E5 -+:10A280006C00E044640DB7BD006B4466F7A0940118 -+:10A29000BC600301978001BC600300378101BC6092 -+:10A2A0006B00508A01BC600306379203BFDE02F0E8 -+:10A2B00002D503D05E02F0030F03D0DE02F0051ECC -+:10A2C00003D5DE02F00A4D03915E02F00595039678 -+:10A2D000DE02F00A480288C1730000BB03C45E02BC -+:10A2E000F0070803C75E02F0073703DCDE02F01157 -+:10A2F000CC03AA5E02F0077A0386DE02F00A8B0224 -+:10A3000087C037000A8B03835E02F008BC0391DE2E -+:10A3100002F0061703C2DE02F00AEF00025E02F04E -+:10A320000EFF00025E02F0117703D4DE02F006A1F8 -+:10A3300003A3DE02F0000200025E02F00E2E03A272 -+:10A340005E02F000B803565E02F000B501866006BA -+:10A35000091048031F5E02F000B5006A5E2300008A -+:10A36000B400B0002700178800E85E230037880398 -+:10A37000A65E02F0012200025E02F00EC700286015 -+:10A380000E08E14303C4DE02F00B610020C20300AB -+:10A39000215403BFDE02F001A003815E02F000BD84 -+:10A3A0000300DE02F000A00188E0020B905C03BF16 -+:10A3B000DE02F0030C028740630000BF0282C10787 -+:10A3C0000000C001866006F4301802864063000079 -+:10A3D000C200B05E870017A10002DE02F00000029A -+:10A3E0008740630000C500B05E8B0010190186E055 -+:10A3F00006F430180281DEAF0000CA0286C0630096 -+:10A4000000C900B05E870017A10002DE02F0000064 -+:10A4100001BC60030280060280DE070000D601DA7C -+:10A420006002F0178002085E070000E601BC6003CE -+:10A430001E17A100E05E02F4306501BC60031C172A -+:10A44000A100E05E02F4306401BC60030028180340 -+:10A45000BFDE02F000EC01105E030017A100885E71 -+:10A46000870037A200E05E86F457A100E0015AF4AD -+:10A470003063028600C30000DF00B0560B0010629C -+:10A4800000B0540300106201BC600300281803BF31 -+:10A49000DE02F000EE00B0418F0010620109DE0321 -+:10A4A0000017A100885E870057A100E05E85059730 -+:10A4B000A100E05E8703C00601BC600300481803EA -+:10A4C000BFDE02F000EE01BC60070217A100E05EF3 -+:10A4D00002F4306501BC60070017A100E05E02F4E1 -+:10A4E000306401BC600318000601BC60030008185A -+:10A4F00000B05A0300106200B05803001063010559 -+:10A5000001430017A10088001AF420060002DE02B1 -+:10A51000F0000001BC600306379201BC63FF1FF02E -+:10A52000C301BC60031890E301BC63FF1FF0C501C9 -+:10A53000BC63FF1FF0C601BC63FF1FF0C700B02C57 -+:10A540005B0010E500B02C5F0010E600B02C63004B -+:10A5500010E70280AC4700010401BC60030010104A -+:10A5600000B0404300180000B040470010E501BCB7 -+:10A57000600300301000B0404300180000B04047B6 -+:10A580000010E601BC600300501000B0404300180A -+:10A590000000B040470010E701BC63FF1FF0C4009B -+:10A5A00002DE02F0000000E840330097A100B04056 -+:10A5B0000B0017A3006D5E86F4610B00905E8F00A8 -+:10A5C00037A303BFDE02F0010C00905E870037A3C3 -+:10A5D00001BC601F1417A100E05E8EF437A301F0E8 -+:10A5E00041970017A1006DDE86F461200287C197B4 -+:10A5F00000011401385A030017A1013C5A03001747 -+:10A60000A203BFDE02F00116013C5A030017A101AC -+:10A61000385A070017A200685E86F4811B00D85ED6 -+:10A620008B0037A200E14196F4506500E1C197002C -+:10A63000306503BFDE02F0010E00D85E8B0037A24A -+:10A6400000E14196F457A100E1DE870037A101F057 -+:10A650005E870017A1006EDE86F4612101BC63FFF6 -+:10A660001FF7A40002DE02F000000020E38E0900C4 -+:10A6700002031EDE02F00127039F5E02F0012700A5 -+:10A68000025E02F0014A03BFDE02F000020208414E -+:10A690001F00012501816005620B1000025E02F0BF -+:10A6A0000B1900B000AB00108600B0016300108AE7 -+:10A6B00000025E02F00D0001BC600304179200B0BE -+:10A6C000003B00111D0190600609104803A1DE0245 -+:10A6D000F0013D0181E00609104801BC60030090D3 -+:10A6E0004201BC600300112D039EDE02F001400117 -+:10A6F000846002F2979400B0451700178F00B05E97 -+:10A70000170017900200441F00013B0185600209F9 -+:10A7100010480181600700104701F0DE0F0037A1EB -+:10A7200000A044B6F43145039EDE02F0014001BCB6 -+:10A73000613712B08003BFDE02F0000200A044B413 -+:10A740002A314501BC612712708003BFDE02F00090 -+:10A75000020020E082090002010CDE530017A10173 -+:10A76000885E8700104701BC600300504201084129 -+:10A770001F0017A1018CDE86F2979403BFDE02F062 -+:10A78000000201BC600300904200E85E23003788AD -+:10A790000069DE2300014E00E800270037880186AB -+:10A7A000600209104801856006F5B7AD0088009B7E -+:10A7B00000D1260090009B01512801BC63030011C9 -+:10A7C000240002DE02F000000020E07E090002000A -+:10A7D000025E02F00ED10283C21F0000020202805C -+:10A7E000F300015E00B044670017A1017C5E862380 -+:10A7F00057A302835EFF00015D00E000FAF46830B9 -+:10A8000001836006F7F7BF006BDE8D06016202066A -+:10A81000D00300016600E950862337A100E8D08A02 -+:10A820002357A20069DE8B00016600025E02F00B76 -+:10A83000190191601684F42700E020C300883003DA -+:10A84000BFDE02F002F2020400BF00016D03945E5D -+:10A8500002F000020020C28F02000200A0428F011D -+:10A86000F78000685E002DC00200025E02F00B1946 -+:10A8700003BFDE02F000020201C28F0000020114D9 -+:10A8800000630017A100685E8700600200025E029C -+:10A89000F00B190194600F00001800025E02F00135 -+:10A8A0007403BFDE02F00002011400630017A10070 -+:10A8B000B05E870010A501BC601311106000685ED7 -+:10A8C0008700017B00E0418306D06000E85E8700DE -+:10A8D00037A103BFDE02F00177028050C30001857B -+:10A8E000018760040310A000B000630010B400B042 -+:10A8F00042D3001800008841830030B601BC6003D9 -+:10A900000B10B500B0006300B0B40317DE02F00115 -+:10A91000820397DE02F00183018060068614300016 -+:10A9200002DE02F000000020E01280419F018760FB -+:10A93000040310A000B000630010B401BC60030E5B -+:10A9400010B500B0006300F0B401BC60570490B6CD -+:10A9500000B000630010B401BC600302D0B5020770 -+:10A96000500B00019C01BC600303D0B5018E600256 -+:10A97000F297940204500B0001950204D00B0001E1 -+:10A980009501866006F2979400E042D700D0B500AA -+:10A99000A0500B1117A10068DE8711019B0186E012 -+:10A9A00006F2979400E042D70050B50207D00B00A2 -+:10A9B000019B00E042D70090B500B042D70011E102 -+:10A9C00000B0006300B0B40317DE02F0019D0397EE -+:10A9D000DE02F0019E0002DE02F00000006820DFCF -+:10A9E0000001A3006CC46506E00201BC600300081E -+:10A9F00037006820D70001A6006CC46506C00201BC -+:10AA0000BC60030008350020E0BE09000203905E30 -+:10AA100002F0000203A25E02F001E1020200BF00A8 -+:10AA200001AB0203C5730001D400682F6B0001AFB6 -+:10AA300000E844657B57A1006D5E857B21D401BC95 -+:10AA40006003000BDA00682D9B0001D40282C1076D -+:10AA50000001D4028042030001D40285C523000115 -+:10AA6000D4028640370001D40181E006F577AB00BF -+:10AA7000B02D9F0017A101BC602F1077A201BC6010 -+:10AA8000030017A300025E02F0130F00B02DA30015 -+:10AA900017A101BC602F1777A201BC60030017A3A8 -+:10AAA00000025E02F0131D01BC60131A17A1000220 -+:10AAB0005E02F000BF00B040670417A200025E0211 -+:10AAC000F000C500E0446700D7A1006CC466F42123 -+:10AAD000C201BC60130ED7A100025E02F000BF00ED -+:10AAE000A040673FF7A201BC601314D7A101BC626C -+:10AAF000030017A300B05E8AF477A200025E02F0A2 -+:10AB000000C500B02D9F0017A101BC602F0D37A21A -+:10AB100001BC60030017A300025E02F0130F00B037 -+:10AB20002DA30017A101BC602F13B7A201BC6003C5 -+:10AB30000017A300025E02F0131D0181E002F57709 -+:10AB4000AB01BC6003000B6600025E02F00DDE028A -+:10AB50000200BF0001E00284DEAF0001DB02035E01 -+:10AB6000B70001E000025E02F010F202035EB700DF -+:10AB700001E003BFDE02F0000202035EB70001DE67 -+:10AB8000020480C70001E002805EFF0001E00002D5 -+:10AB90005E02F010B303BFDE02F0000200025E02AC -+:10ABA000F00ED10200421F0001F9006842F30001DB -+:10ABB000E4006D42F30041F9011400630017A100A5 -+:10ABC000B05E870017A203A25E02F001ED0183E0F0 -+:10ABD000020D906C03145E02F001FB006EC45680FF -+:10ABE00061FB028145230001FB006E5E870061F975 -+:10ABF00001BC60030077A200886006F457A30088B8 -+:10AC00005E8B01001800E85E8B0037A20020C28E28 -+:10AC1000F461F3006ADE86F441ED03BFDE02F00169 -+:10AC2000F9020400BF0002250090006301016500E5 -+:10AC30008085970217A100E064820DA16600025E84 -+:10AC400002F00E8703BFDE02F002250182600209D6 -+:10AC5000104803BFDE02F0000201BC6003001115C2 -+:10AC600000B0017F0017A6031F5E02F0020A020374 -+:10AC700000C30002000020C28F02020403255E020E -+:10AC8000F0020A0020C28F02020400688153FFE034 -+:10AC90000203BFDE02F002060194601300001803F5 -+:10ACA000BFDE02F00225039EDE02F002090068DE2C -+:10ACB000980BC2090201411F000C4C01856002097A -+:10ACC000104800685E980BC20E00695E9F00622A01 -+:10ACD0000298428F00020E03BFDE02F0022A020138 -+:10ACE000411F000C4C020400BF0002150218428FE5 -+:10ACF000000C4C00025E02F00E6900025E02F00ED3 -+:10AD0000870194058700001803BFDE02F0022502C8 -+:10AD10000013BB00021E0200156B00022100B013DD -+:10AD2000470017A10068DE84A7A21E00B0134B00E5 -+:10AD300017A10068DE84A7C21E00B0134F0017A140 -+:10AD40000068DE84A7E21E029E1397000221020122 -+:10AD5000C28F0002230194600F00001803BFDE02BF -+:10AD6000F002250201C28F000223018060060D90CF -+:10AD70006C0200C28F000C4C0194600700001800A8 -+:10AD8000025E02F00174020400BF00025A02850054 -+:10AD90006300025A0183E0060D906C03BFDE02F0EF -+:10ADA000025A01BC60031810600129500B00179271 -+:10ADB00000B0017B001065006800EB0002330088E2 -+:10ADC0005A130117A100E84466F437A1006EDE842F -+:10ADD00007423300E0029B0020A603BFDE02F0061C -+:10ADE0009A019060120910480194601F0000180138 -+:10ADF000085A0F00178101885E0681540A01345AEF -+:10AE00000F00178000025E02F000CC00B0017B0052 -+:10AE1000106500B056230017A100E05E86A097A140 -+:10AE200000E85E8400F40300E85E8400F41600B0DD -+:10AE30005A0300141300B05A0700141400B05A0B40 -+:10AE40000014150068DE0700424B00E80097005729 -+:10AE5000A101BC5E86F0141B017C5E8700F41C001F -+:10AE6000B0206300178100025E02F00D0400B00103 -+:10AE70007B00106501085A0F00178100B05E870043 -+:10AE8000141E03BFDE02F0024E00B0561700141B62 -+:10AE900000B0561B00141C00B0541300141E00B068 -+:10AEA0005013001086006D00A700825401900163CA -+:10AEB00000108A00B0418F00106200025E02F011A3 -+:10AEC0009900B0422B00140601BC60031817A100C2 -+:10AED0006DC18C20025701BC60030297A100E05EA7 -+:10AEE000840377A100E05E86B0111D03BFDE02F08F -+:10AEF00002CF020300C700026A020CD00300026AFC -+:10AF0000011400630017A10285006300026A00803B -+:10AF1000DE8701F7A201BC601B0257A200E05E8A37 -+:10AF20000DB06500B041970014320080DE8700B795 -+:10AF3000A201BC60171FD7A200E05E8A0DB06400BA -+:10AF4000B041930014330068D81300027402005A11 -+:10AF50001B00026C0180600684F42703BFDE02F050 -+:10AF600005C10201D00300026C00B0509B00142FF9 -+:10AF70000281D0C70002EF010BD0030017A1013CF2 -+:10AF8000502B0017A2018C5E86F457A101480143A3 -+:10AF90000017A200685E86F442740191601284F486 -+:10AFA0002703BFDE02F002F200025E02F00186001B -+:10AFB000B0501300108600B0501700108A00682FA0 -+:10AFC000C300027F0291D01700027D0291D01B00C6 -+:10AFD000027D0291D01F00027D0291D02300027DEC -+:10AFE00003BFDE02F0027F0191600284F42703BFF9 -+:10AFF000DE02F002F203A25E02F002AE020CD00307 -+:10B0000000029B020300C700029A00B050CB001060 -+:10B010006500025E02F01232020350C7000288018E -+:10B02000BC60230097A100A85002F4340003BFDEE7 -+:10B0300002F0029F020481AB00028A006D4246C00A -+:10B04000800200B05A1300178000025E02F000D6A2 -+:10B0500000B0540F00141E00B05A070017A100B032 -+:10B060005A1300178001875A16F0178000B0418FDD -+:10B0700000106500025E02F011A200E05E86A0747E -+:10B080000302875E030002990109DE030017A30093 -+:10B09000E05E8B0077A200E05E8AF477A200885E13 -+:10B0A0008B0037A100E05E86F4508903BFDE02F01A -+:10B0B000029F006D424A848002010650070017A1DA -+:10B0C000028CD00300029E00685E8700029F01820E -+:10B0D000DE86863431018260028634310020D0035E -+:10B0E0000402A500B0504F0011F200B050530011FF -+:10B0F000F300B050570011F401BC60030091F0025E -+:10B100000101B30002A70187E006F577AB03945E67 -+:10B1100002F002AE020650030002AA0287DEAF0070 -+:10B1200002AE028150030004FF0202D0C70002AD4C -+:10B130000208502B0002AE0285D0030005160190D4 -+:10B14000601286343103A25E02F002BB00B0500FE1 -+:10B150000011160202D0C70002B300B0505B00110C -+:10B16000160282D0030002BB028147C30002B40270 -+:10B1700080504F0002B9002047C73F82BB0020C764 -+:10B18000DB00C2F103BFDE02F002BB03A55E02F0EA -+:10B1900002BB0280C7DF0002F1028850C70002D55F -+:10B1A0000129500B001792020300C70002C8020CCD -+:10B1B000D0030002C8028350C70002C800B050CBC1 -+:10B1C00000106501385A1300178001825A17005782 -+:10B1D00081010E5A130017A1018E5E86F03781029D -+:10B1E00002D0C70002D500B0501B00108A03BFDE9A -+:10B1F00002F002D50282D0C70002CF0138502700EA -+:10B20000178001085013001781010250130017A185 -+:10B2100001825E86F0378100B0507F00108903BF45 -+:10B22000DE02F002D50138506F0017800108502B64 -+:10B230000017810106D0070017A101825E86F03752 -+:10B240008100B0501B00108A00B0508300108900AC -+:10B25000025E02F000CC00025E02F00CF701024236 -+:10B260001B00178101825E0503178100025E02F058 -+:10B270000D0400E05E840117A101D9DE8700108370 -+:10B28000020001B30002DE01E001B700108301BC3F -+:10B29000613703B79100685E4B0282F5020400BF7C -+:10B2A0000002E3028750030002E303945E02F0020F -+:10B2B000E403225E02F002E601BC61030030800379 -+:10B2C000BFDE02F0000201BC613303B791032BDE45 -+:10B2D00002F002EC009000630097A100E06482F4A9 -+:10B2E0003065006E5A130022EC0188E006F23791B7 -+:10B2F0000068DE4B0482EE01BC61BB03B79103BF63 -+:10B30000DE02F002F50191600E84F42703BFDE0235 -+:10B31000F002F20191600684F42701BC6003001082 -+:10B32000B40181E00686343103BFDE02F005C103BB -+:10B33000C4DE02F00B61020650030002FD0207DECC -+:10B34000AF0002FD01BC610300379102075003000A -+:10B3500002FB01BC620300F79100E0010B002042F8 -+:10B3600003BFDE02F002FE01BC600300204200B019 -+:10B370005E47001080020001B300030401826006F2 -+:10B38000103081020181B300030401BC600305B7E2 -+:10B390009303BFDE02F006CC020400BF00030B00E3 -+:10B3A000B0058B001064006E45170000020068DED7 -+:10B3B0004B02830A00A044B42A314503BFDE02F0E9 -+:10B3C000000200025E02F00D110068C517000002C5 -+:10B3D00003D05E02F0030F00025E02F00D1103BF06 -+:10B3E000DE02F0000201836002F7F7BF01BC6003D8 -+:10B3F00000900400A8412330104801BC620F0011E6 -+:10B40000E001816002F5D7AE020200BF0003230015 -+:10B4100068DE4B02031700025E02F013090068DECB -+:10B420004B06232302045EB30003230200456F0092 -+:10B43000032300E844655737A100E82AB6F437A192 -+:10B4400000695E870823230183E0022B915C0207D9 -+:10B4500001AB0003200180E00209D04E01BC600373 -+:10B4600018517800B045E3001800018060022F31C8 -+:10B47000790187E002F577AB0068810B0023260095 -+:10B48000B044670000430182E00609104801816072 -+:10B49000020D906C018260062891440188E0020B45 -+:10B4A000905C00025E02F00EFF0185E002F7F7BF3C -+:10B4B0000288421B00032E0185E006F7F7BF035BFD -+:10B4C0005E02F0033001BC601300104301BC600356 -+:10B4D00000108501BC60030010B800885077009010 -+:10B4E000B90208502B000337013850730017A1012F -+:10B4F0007C506EF437A100885E870090B902004747 -+:10B50000A300033B01BC60030011EA009042E70086 -+:10B5100091EB00B047A300D1E8020047B300033D20 -+:10B5200001B0E08E3D91EC01D2E00210908403A9BD -+:10B530005E02F0042901BC600300108400E001C336 -+:10B54000002070028181B30003730320DE02F00348 -+:10B550008F01816006F5B7AD0068DE4B04A356028B -+:10B5600003DEBB00034800E02C9300106503BFDE40 -+:10B5700002F0034901BC602301D06500A05E7FFE9C -+:10B5800010EC00B05A030010ED00B05A070010EEA6 -+:10B5900000B05A0B0010EF00B05A0F0010F001BCC1 -+:10B5A00063FF1EF08401BC600300308501BC6003B2 -+:10B5B0000010B401BC600301D0A601BC60030450BC -+:10B5C000B501BC602304D0B400E002AF0020AB039F -+:10B5D000BFDE02F003D70068DE4B05235C01BC60D0 -+:10B5E000030010B401BC60071350A601BC60030245 -+:10B5F000D0B501BC602304D0B403BFDE02F0036603 -+:10B600000068DE4B0243730285C38F00035F00E0D6 -+:10B610005E2700378901DA5E270010EE01BC63FF68 -+:10B620001FF0CE01BC60030010B401BC600300D069 -+:10B63000A601BC600303D0B501BC602304D0B400F4 -+:10B64000E001D300207401BC61FF1FF08401BC60E5 -+:10B6500003001085018460070011E00282DEB30060 -+:10B6600004E602045EB30004E60183E00609104824 -+:10B6700000B0412300180001BC600306B78E0181B1 -+:10B68000E006F5D7AE00B054130017A100E05E84C9 -+:10B690000117A100885E8700708303BFDE02F004FB -+:10B6A000E601BC60031FF0840103DE530017A20211 -+:10B6B000005EFF00037701BC60030037A200682B27 -+:10B6C0006F00037901BC60030037A201865E8A1C0B -+:10B6D00070E3006AC39300038300E8439000D0E462 -+:10B6E0000202421B0003810090001B0037A10020D2 -+:10B6F000421B00438000B020B30017A100E043923A -+:10B70000F430E40069C39300038301BC60030010BC -+:10B71000E400682B6F00038500E043915C30E40196 -+:10B72000BC60030010B401BC60030010A601BC6043 -+:10B73000030210B501BC602304D0B400685E4B0660 -+:10B74000A38D00E001CB00207201BC60030008382B -+:10B7500003BFDE02F003D700E001CF00207303BF78 -+:10B76000DE02F003D703205E02F003DE0181E00277 -+:10B7700009104800E001D7002075031EDE02F00327 -+:10B78000BE01BC60030017A2006A5E23000397019C -+:10B7900002428F0017A201855E8A0910480180E0ED -+:10B7A000061030810284DE5300039E00B000770053 -+:10B7B00017A100E05E840437A100885E870057A1CE -+:10B7C00000E05E870D57A103BFDE02F0039F01BCBE -+:10B7D00060030D57A1006800270003BE00E05E84EF -+:10B7E00001F7A101BC60230150650088419700303A -+:10B7F000B601BC60030010B400905E870050A60143 -+:10B80000BC60030110B501BC602300B0B40317DEB7 -+:10B8100002F003A70397DE02F003A80020DE8700F2 -+:10B8200043B10020DE870023AE01B85E22D016802F -+:10B8300001805E8AD0368103BFDE02F003B701BC0F -+:10B840005E22D0168001845E8AD0368103BFDE027C -+:10B85000F003B70020DE870023B501B85E22D036A2 -+:10B860008101805E8AD0568203BFDE02F003B701F9 -+:10B87000BC5E22D0368101845E8AD0568201886007 -+:10B8800002F430A800B05A030010B000B05A07000C -+:10B8900010B1028042A30003BA00E042A30090A8C6 -+:10B8A00000B05A0B0010B000B05A0F0010B1018761 -+:10B8B000600610908400E05E2700378901DA5E2779 -+:10B8C0000010EE01BC60030010B401BC6003035023 -+:10B8D000A600B000330010B50284DE530003C80098 -+:10B8E000E0606803B0A600E042980430A600B00013 -+:10B8F000370010B501BC602304D0B401846006F2A7 -+:10B90000979401866002091048039EDE02F003D27C -+:10B910000280441F0003D500B05E3F00114501BC0A -+:10B92000600300178F00B05E4300178500B05E0F04 -+:10B9300000179003BFDE02F003D500B05E0F0017C2 -+:10B94000850280441F0003D500A044B6F0B1450134 -+:10B95000BC600301104201836006F2979401846089 -+:10B96000070011E003A05E02F004E402065EAF00EF -+:10B9700004E60186E006F577AB01BC6003001080A9 -+:10B9800000025E02F00B1F03BFDE02F0061703A1E8 -+:10B990005E02F00450011400630017A10068DE8706 -+:10B9A00000E3E30181600609104803BFDE02F004F2 -+:10B9B0005001816006F5D7AE0020600E8624080194 -+:10B9C0008760040310A000B000630010B401BC60E5 -+:10B9D000030B10B500B0006300F0B4020300C70011 -+:10B9E00003F6020CD0030003F6028050C70003EEFA -+:10B9F00000B054130017A100E05E8680741A00B0F6 -+:10BA0000506B0010E400B042130210840209502B66 -+:10BA10000003F600B0421300308401D2E03AA030B7 -+:10BA2000E0028050C70003FC01D2E052A030E003E6 -+:10BA3000BFDE02F003FC0202D0C70003FC00B050DE -+:10BA40005F0010E000B050630010E100B0506700EC -+:10BA500010E200B0506B0010E400B0421302F0841A -+:10BA6000020050C700040300B000630010B401BC22 -+:10BA700060030210B500B0006304D0B40184600715 -+:10BA80000011E001BC600300178E03BFDE02F0046A -+:10BA9000E800E001C700207100B000630010B401AD -+:10BAA000BC600302D0B500B0006304D0B403BFDEB5 -+:10BAB00002F0048001856006F7F7BF010350030020 -+:10BAC00017A100B85E870037A101875E861010803D -+:10BAD000020CD00300044F020300C700041F00B093 -+:10BAE00050CB00106501BC600300168500E05A339E -+:10BAF00000368C020350C700041400E05A270036B9 -+:10BB00008903BFDE02F0045001BC60030017B200DD -+:10BB1000B05A0B000B2501385A130017A101BC5A6B -+:10BB200006F430E0013C5A130017A1017C5A06F4D8 -+:10BB300030E10181E0061090840185E0070010E308 -+:10BB40000185E0070010C30282D0C700042403BFB0 -+:10BB5000DE02F004270202D0C700042900B02A4BFD -+:10BB60000017A101B8506EF430E000B05073001718 -+:10BB7000A101B82A4EF430E10282421300042700EA -+:10BB8000B0507B0010E400B042130210840185E045 -+:10BB9000061C30E100B0421300708401876004038A -+:10BBA00010A0020300C700043E00B050CB00106597 -+:10BBB000006D5ECAD1C42F0185E0021870C300E099 -+:10BBC0005ECB00368E01BC601B09D06500E041965B -+:10BBD000F6506500B050970016800068DECB000478 -+:10BBE0003601BC60230150B800682C9700243C0348 -+:10BBF000BFDE02F0044800B05ECB0010B500B0001C -+:10BC0000630870B4028342D300043801BC600301AE -+:10BC100070B80068AC9700244801BC60030170B89C -+:10BC200002BC506700044703BFDE02F00446010C6B -+:10BC3000D0030017A103A95E02F0044301BC6023F6 -+:10BC40000150B800685E8700644603BFDE02F0045E -+:10BC50004801BC60030170B800685E870044480179 -+:10BC6000BC60030170B80181E0021710B801BC602C -+:10BC70000300F0A501BC60030E10B500B000630026 -+:10BC800010B400B0006300F0B400B042D30018005C -+:10BC9000018860080310B4018160060D906C03BF39 -+:10BCA000DE02F004800202D0C700045600B0506FDC -+:10BCB0000010E000B050730010E100B050770010A9 -+:10BCC000E20282421300045500B0507B0010E400F1 -+:10BCD000B0421302F08400E05E9F0037A703A15E2C -+:10BCE00002F0045F01BC60030017A7018760040332 -+:10BCF00010A000B000630010B401BC60030E10B5CA -+:10BD000000B0006300F0B4018860080310B403BF02 -+:10BD1000DE02F0047500B0017B00106500B05A032C -+:10BD20000010E501BC63FF1FF0C500B05A0700100A -+:10BD3000E601BC63FF1FF0C600B05A0B0010E7011C -+:10BD4000BC63FF1FF0C70068A06700046800E05EE6 -+:10BD5000270037890068206700046C0185E0070030 -+:10BD600010E30185E0070010C300B0421301108406 -+:10BD700001DA5E270010EE0187600610908400B0A3 -+:10BD800042131C108401BC60030010B400E0606822 -+:10BD900003B0A600B000970010B501BC602304D02A -+:10BDA000B4018460070011E003BFDE02F004D40197 -+:10BDB000085E4B0017A100685E87002480020250D5 -+:10BDC0000300047F029E509F00047C0201D0030008 -+:10BDD000047C00E05E2700378901585E2700142D9F -+:10BDE00001DA50B70010EE0187600610908403BF9F -+:10BDF000DE02F0048001BC600300142D0104C107C1 -+:10BE00000017A103225E02F004830103DE53001732 -+:10BE1000A100B05E870017A202005EFF0004860149 -+:10BE2000BC60030037A200682B6F00048801BC606F -+:10BE3000030037A202885E4B00048B00685E4B064D -+:10BE4000848B01BC60030017A20183DE86F2979405 -+:10BE50000183DE8684F4270281C2130004920186E6 -+:10BE60005E8B0010E3018660070010C30181E006CD -+:10BE700010908403BFDE02F0049401865E8A1C7079 -+:10BE8000E3018660061870C302B847A70004D00219 -+:10BE9000A047B70004D203A95E02F0049C01085E2B -+:10BEA0004B0017A100685E870024D1021E509F003E -+:10BEB000049C0185E0061C70E30185E0061870C350 -+:10BEC000011400630017A10068DE870084A500B09C -+:10BED00001530017A20068DE8BFFE4A1006842470F -+:10BEE0000024A20068DE8A84C4A5018560020910CE -+:10BEF000480186E0021C70E30186E0061870C30169 -+:10BF00001050070017A600685E9B0004D101BC60BA -+:10BF1000030011E4013A500700178000885E030017 -+:10BF2000778000E000AEF010640068DE9B0044B64D -+:10BF30000207D0030004B001BC602B12B7A200E0DE -+:10BF40005E000B37A300025E02F00D5201BC6023BD -+:10BF500007978100E0418301706300E0418F00B0EA -+:10BF60006500025E02F00D2701BC602307506401EA -+:10BF7000BC60470017A200025E02F00D7A00685E06 -+:10BF80009B0044D201A46046F471E00068DE9B008F -+:10BF9000C4C401BC611300B7A1020600F30004BDD4 -+:10BFA00001BC601300B7A10192C21AF437A20329A1 -+:10BFB0005E02F004C201BC60030011EE009042E793 -+:10BFC0000091EF0192E00EF437A200B05E8B0011F9 -+:10BFD000EC03BFDE02F004D200685E9B0064C9007F -+:10BFE000685E9B00A4C900B0502F0011E200B05061 -+:10BFF000330011E203BFDE02F004D2018760023D8C -+:10C0000011E80068DE9B00A4CC018760063D11E8C2 -+:10C0100001BC60030011EA009042E70091EB01923D -+:10C02000C21B00B7A201B85E8A3D11E803BFDE0261 -+:10C03000F004D2018460070011E001BC600300112C -+:10C040002D00B0448300142C03A3DE02F004E701AA -+:10C05000BC600300178E00685E4B05A4D802005038 -+:10C06000030004E10183E00609104800B041230009 -+:10C07000180001BC600304B78E03A95E02F004E659 -+:10C0800000685E4B0424E601BC600306378E00683E -+:10C090005E4B05A4E601BC600306B78E03BFDE025B -+:10C0A000F004E601816006F577AB00B05E0F001783 -+:10C0B0008500025E02F00D1101BC600300178C01C7 -+:10C0C000BC600300178D0323DE02F004E80187E063 -+:10C0D000061070830185E002F5B7AD03295E02F01A -+:10C0E00004FC020300C70004F700B050CB00106549 -+:10C0F0000282D0C70004EF00E05A2300368803BF55 -+:10C10000DE02F004F000E05A2700368900682C9720 -+:10C110000024F700E05ECB0037B2010A5ECB0017C7 -+:10C12000A100E050CAF4306500D06006F657A200C6 -+:10C13000205A1AF444F703BFDE02F004F100025E55 -+:10C1400002F00EFF03D5DE02F00A4D03D6DE02F048 -+:10C150000A650350DE02F004F703BFDE02F0051E9D -+:10C1600002055EAF0004FE0187E00626713303BFBF -+:10C17000DE02F000020190600A8634310282D0C7EC -+:10C18000000508013C50270017800109502B0017BB -+:10C1900081010750070017A101825E86F0378100F8 -+:10C1A000B0501F00108A00B0500F00111603BFDE00 -+:10C1B00002F0050E0138505F001780010A502B0075 -+:10C1C00017810107D0070017A101825E86F0378131 -+:10C1D00000B0502300108A00B0505B00111602031B -+:10C1E00000C7000513020CD00300051302085E0708 -+:10C1F000000513013854070017800190422AA1302E -+:10C200008A028050C700051C01BC600305B7920379 -+:10C21000BFDE02F002B301906006863431020300F3 -+:10C22000C7000500020CD00300050000B0001F008D -+:10C2300017A100E05E8680741A03BFDE02F00500DD -+:10C2400001BC600306379203BFDE02F002B30205B1 -+:10C250005EFF00052D01856002F7F7BF032BDE02AC -+:10C26000F0052D020000F300052400E80023005132 -+:10C270004201BC600A28514203945E02F005290085 -+:10C28000B0058B0010640068580300052900B04415 -+:10C290006700111200B058030011150068451F0017 -+:10C2A000052D03A25E02F0052D0185E006F577ABB2 -+:10C2B00000025E02F00E410201C2E30005570203D4 -+:10C2C00000C700053200682C97002542006E4246E8 -+:10C2D000F6454203BFDE02F00534006E42470025FA -+:10C2E00042020300C700053F0355DE02F00534019A -+:10C2F000806002861430013850830017A100B050CE -+:10C30000CB001065006DDA32F42A4D00A8412314E9 -+:10C3100010480114006300106500E041970ED065DD -+:10C3200000E05A0300368001BC621F0011E003BF29 -+:10C33000DE02F000020181E0068634310191600ED8 -+:10C3400084F42703BFDE02F00557013C5067001755 -+:10C35000A101AC5E861750BA01BC60030190B8021F -+:10C360000300C70005510068AC9700254C0181E02F -+:10C37000021710B803D5DE02F00A4D03D6DE02F034 -+:10C380000A650350DE02F0054803BFDE02F00557E0 -+:10C3900000E82C97002B2500B05ECB0010B500B054 -+:10C3A00000630870B4028342D300054F03BFDE026E -+:10C3B000F005520186E0040310A000025E02F001C5 -+:10C3C0007D03D5DE02F00A4D03D6DE02F00A6503D6 -+:10C3D00050DE02F0055303BFDE02F0032E01BC6005 -+:10C3E0000300F0A50182E00209104801BC621F00B1 -+:10C3F00011E001BC60030011EC01BC600F0011E80A -+:10C400000285500B00055E0182600209104802811E -+:10C4100081B300056503A0DE02F0056303D5DE02EB -+:10C42000F00A4D03D6DE02F00A6503205E02F00535 -+:10C43000650188600209104803BFDE02F0000201B6 -+:10C44000BC60030037A1020001B3000573020401C0 -+:10C45000B300057200E901BB00206E00E881BF0057 -+:10C46000006F006881BB000572006881BF00057223 -+:10C47000028181B300056F01BC600300006C03BF43 -+:10C48000DE02F005C101BC600300006C00025E0228 -+:10C49000F00ADC03BFDE02F0000201BC60030017FB -+:10C4A000A100025E02F00C36020101B30005760322 -+:10C4B000BFDE02F0000203A3DE02F0000202005021 -+:10C4C000C700057F01BC600300108001826006097F -+:10C4D0001048018060028634310104C1070017A1B1 -+:10C4E0000183DE86F2979400E001CB00207203BF47 -+:10C4F000DE02F001A0020101B30005810187E00620 -+:10C50000F577AB00B0010B0017A1006DDE840805C4 -+:10C51000C100E844640877A1006E5E840825C1016B -+:10C5200087E006F577AB020200BF00059402888120 -+:10C53000AB000594028400C70005940129500B004C -+:10C5400017A10068DE870205940282DEBB00059415 -+:10C550000203C5730005930283DEB30005930282D4 -+:10C56000DEBB00059000682B07000594006DDE2FF0 -+:10C5700001E5940182E006F7F7BF00E04465564A02 -+:10C58000B103BFDE02F0000203BFDE02F005C1020C -+:10C59000825EAF0005A401826006F577AB00B0446F -+:10C5A0006700082300B0014B0017A20208421B00DD -+:10C5B000059B00B0016B0017A200685E8B0005A10F -+:10C5C0000090452B0097A10080DE86F457A1006EF5 -+:10C5D00020D60DA5A100B041B700083500E020D657 -+:10C5E0002328360185E002F5B7AD02055EAF0005F0 -+:10C5F000A401BC610300113300E844650477A50081 -+:10C60000B04467000BDA006D5E9701009E020200E5 -+:10C61000BF0005B30068DE4B06A5AA0184E002F75F -+:10C62000F7BF0068DE4B0405AD0282DEB30005AD46 -+:10C6300001BC6003000B1202045EB30005B0006889 -+:10C64000DE4B0625B000025E02F0111A00025E0207 -+:10C65000F00F0003A3DE02F005B30183E002F597BB -+:10C66000AC01BC60131497A100025E02F000BF0190 -+:10C67000BC63830017A100A04066F437A20068DE07 -+:10C680008AF425BF01BC60130E77A100025E02F0A0 -+:10C6900000BF00A040673FF7A200985E8B0037A262 -+:10C6A00000685E8B0005BE0068DE8B0FE5BF01BC35 -+:10C6B000602300104301826002F577AB03D15E0274 -+:10C6C000F00002020050C30006100325DE02F00550 -+:10C6D000C50183600684F42703BFDE02F005F7027C -+:10C6E0000CD0030005F5020300C70005E4011400A7 -+:10C6F000630017A1006DDE870085F501BC600300B3 -+:10C70000178000B050CB00106500B050CF0010640F -+:10C71000018160060D906C0182600686343100B0A4 -+:10C720005A230017A101BC600300168801BC5A2AD5 -+:10C73000F437A101BC600300168A00B05E870014C4 -+:10C740008F00B05A270017A101BC600300168901B1 -+:10C75000BC5A2EF437A101BC600300168B00B05EFA -+:10C760008700149000B05A1B00148D00B05A1F00AF -+:10C77000148E01BC60030016040068DE030005E1AE -+:10C78000020350C70005E00100509F0017800180A0 -+:10C790005E0291B48D01BC5E0292149001BC6003F4 -+:10C7A00000378000025E02F0127E00B05E030014CB -+:10C7B0008C03BFDE02F005F00068C2470005E90106 -+:10C7C00081E0068634310191600E84F42701BC605B -+:10C7D0000300143003BFDE02F0000200B0509F00DF -+:10C7E00017A100025E02F0017C00B05E87001427F2 -+:10C7F0000186E0040310A000B04283001800010C81 -+:10C80000D0030017A10068DE870065E4010250C76D -+:10C810000017A101805E8684F427018AE00E84F46B -+:10C820002700B050BF00142603BFDE02F005F70159 -+:10C8300086E0040310A00200509F0005F70286C1A5 -+:10C840000700060B03295E02F005FC00B05233001E -+:10C85000142D00B052370017A1019E5E8684F42784 -+:10C8600000B0509F0017A10180DE86F437A100B010 -+:10C8700050BB00108F00B050B700108E00B0509B1E -+:10C8800000108D01806006F4308C020250C7000653 -+:10C890000A00B0524300108F00B0523F00108E00CB -+:10C8A000B0523B00108D011A52370017A10198DEDB -+:10C8B000870437A101B85E8691B08C018260028640 -+:10C8C0003431018160020D906C0325DE02F0060E0A -+:10C8D000019C600284F42703BFDE02F00612028589 -+:10C8E000500B00061000A850C70D143101BC6003A6 -+:10C8F00000143001816002F5D7AE0183600284F438 -+:10C90000270185E00209104801BC600300142E03D2 -+:10C91000A25E02F001A003BFDE02F000020323DEEC -+:10C9200002F0067B03A35E02F0067B03A2DE02F0A8 -+:10C93000067B01816006F577AB03AA5E02F0067BF9 -+:10C940000183E0020910480351DE02F0063A0204B6 -+:10C950005EB300062701846002F597AC0183E00214 -+:10C9600009104800B02B5F0017A1006D2B0EF420BA -+:10C970000200E0027B00209E01BC6003000AC300AD -+:10C98000025E02F0111D03BFDE02F000020203DEB0 -+:10C99000B30006370183E002F597AC00E02A9B0064 -+:10C9A0002AA602015EBB00063700B02A9F0017A12D -+:10C9B000006D2A9AF4263201BC6003000AA600E04A -+:10C9C000027F00209F03A95E02F006350191601AE4 -+:10C9D00084F42703BFDE02F002F201BC63FF1FF7FD -+:10C9E000A100025E02F00C3603295E02F006370158 -+:10C9F00091601A84F42703BFDE02F0063700E002DC -+:10CA00006B00209A0180E006F577AB03BFDE02F0F1 -+:10CA1000063F0301DE02F0063D00685E4F06263D3C -+:10CA200001BC60030017A803A45E02F0063F03C127 -+:10CA3000DE02F0067E01846002091048020400BF95 -+:10CA400000064401BC6003001115011400630017C7 -+:10CA5000A100E06602F4306500025E02F00D1601EE -+:10CA600082600209104803A95E02F0065F00685E5A -+:10CA70003B04A64F01F0DE1700378500A05E16F0DC -+:10CA8000978500685E3B06264F0201500300064E64 -+:10CA9000028780BF00064E0185E00609104802802B -+:10CAA000D00300065F00B05E1B0017A300B0008B30 -+:10CAB0000017A4020400BF000655006E41973066BF -+:10CAC0005501185A030017A3011A5A030017A400AE -+:10CAD00068C18318065800E002930020A403BFDE5B -+:10CAE00002F0065A006D5E2EF4865A0182E0068638 -+:10CAF000343100E05E3300378C0068DE32F4665D6E -+:10CB000000B05E0F001785006DDE2EF4666B03BF6C -+:10CB1000DE02F0067600B05E1F0017A300B0008FA3 -+:10CB20000017A4020400BF000665006E419730663E -+:10CB300065011C5A030017A3011E5A030017A40025 -+:10CB40006D5E2EF486670182E00686343100E05E79 -+:10CB50003700378D0068DE36F4666A00B05E0F007D -+:10CB60001785006D5E2EF466760185E00209104897 -+:10CB700003D1DE02F0066D00025E02F00D110068C6 -+:10CB8000418318069A020300C7000674020CD00302 -+:10CB9000000674028350C70006740068DE4B05A6C9 -+:10CBA0007403BFDE02F011FC0181E006863431031C -+:10CBB000BFDE02F005C100025E02F00D11018160CE -+:10CBC0000209104803295E02F0067B028300C700B9 -+:10CBD00011FC03BFDE02F005C103D1DE02F0067CCA -+:10CBE00003A5DE02F005C103BFDE02F000020280F1 -+:10CBF00001B30000020206500300068500B00103E5 -+:10CC00000017A1006D810AF4268500E844640877C6 -+:10CC1000A1006E5E840826850187E006F577AB01EA -+:10CC2000085E4B0017A100685E8700268800B05E92 -+:10CC30000F00178500025E02F00D1100685E3B06D2 -+:10CC4000268E01BC600300178C0200D003000693FF -+:10CC500001BC600300178D03BFDE02F0069301BC28 -+:10CC6000600300178C020300C70001A0020CD00370 -+:10CC70000001A0019C600284F42703BFDE02F001E2 -+:10CC8000A0006841831806990180600684F4270398 -+:10CC9000295E02F005C101826006863431028300FC -+:10CCA000C70011FC03BFDE02F005C100E0029700DF -+:10CCB00020A50181600209104801BC600300081929 -+:10CCC00000E0017B00A05E01BC601310D7A1006DE5 -+:10CCD000017AF4200201BC601309405E03BFDE024A -+:10CCE000F0000200025E02F00B190338DE02F000D1 -+:10CCF00002039EDE02F0000200E8444C00F7A100AF -+:10CD0000E85E840117A1006ADE840106AA00E85EDD -+:10CD10008401118701BC600300118801A5E0223065 -+:10CD2000118001BC600300111301BC6003001114E9 -+:10CD300000B044670017A100B0446B0017A200B018 -+:10CD40005E8700110400B05E8B00110503B8DE029F -+:10CD5000F006AC03BFDE02F0000201BC600304B7C2 -+:10CD60009201BC60030417A101BC63FF1FF0CB015B -+:10CD7000BC63FF1FF0CC01BC63FF1FF0CD01BC639F -+:10CD8000FF1FF0CE01BC63FF1FF0CF01BC63FF1F8C -+:10CD9000F0D000B052170010E801BC63FF1FF0C8CC -+:10CDA00000B0521B0010E901BC63FF1FF0C900B0C6 -+:10CDB000521F0010EA01BC63FF1FF0CA01BC6003F0 -+:10CDC0000010E4028600C30006CD00B0540F001727 -+:10CDD000A20069DE8A9086C500E85212F450E40091 -+:10CDE00068A0630006CD01BC60030010E400B054ED -+:10CDF000270010E000B0542F0010E103BFDE02F066 -+:10CE000006D603A4DE02F008BC03A9DE02F008BCCB -+:10CE100001BC600301D7A1020600C30006CF028057 -+:10CE2000DE5F0006D400B054070010E00068206305 -+:10CE30000006D201D2DE86A030E000B0540B001014 -+:10CE4000E103BFDE02F006D601BC5E869010E00171 -+:10CE5000BC601F0010E101BC60030010E200B05292 -+:10CE6000230010E501BC63FF1FF0C500B05227008E -+:10CE700010E601BC63FF1FF0C600B0522B0010E7A4 -+:10CE800001BC63FF1FF0C700B00047001086010817 -+:10CE90002063001781013852030017800102C02768 -+:10CEA0000017A600025E02F011950068206300469C -+:10CEB000E400B05407001780028181B30006E60049 -+:10CEC000025E02F00CF7006820630026EE0068A006 -+:10CED000630006E9021A54070006EE006800A70185 -+:10CEE00006EC0103C0270017A103BFDE02F006ED28 -+:10CEF0000106C03B0017A101825E8610D08603A9FF -+:10CF0000DE02F0091700685E4F04270001BC63FFD2 -+:10CF10001FF0C300685E4F05A6F601BC60031A90BF -+:10CF2000E301BC600306B79200685E4F052700036B -+:10CF3000BFDE02F006FA01BC600306379202984495 -+:10CF4000070009E6028046070009E601BC600318F5 -+:10CF500090E300B0206300178100025E02F00D0430 -+:10CF600000E85E8400D7A1006A5E8690870000E832 -+:10CF70005212F430E403BFDE02F0070301BC600389 -+:10CF80000010E40338DE02F007030187E0061C907E -+:10CF9000E40190600A09104801BC61030437910064 -+:10CFA000685E4F05A9E603835E02F008BC03BFDE9E -+:10CFB00002F0000201866002F7F7BF0182E002F58D -+:10CFC000B7AD0185E002F5B7AD0204416300071378 -+:10CFD000018460020B105802055EAF00070F018745 -+:10CFE000E006267133020400BF0007120185E0024B -+:10CFF000F577AB00025E02F00E4103BFDE02F000E7 -+:10D00000020283C03700071B006CC4656C271C013B -+:10D01000BC601B1A77A100025E02F000BF0180E035 -+:10D02000060337A200025E02F000C50180E002F4B0 -+:10D0300057A200025E02F000C500E044656C4B613F -+:10D040000285C52300072B018460060B10580200DF -+:10D05000DEFF0007220180E002F7F7BF00682B6FB8 -+:10D0600000072200E044655B4ADB0207AC0F0007C3 -+:10D070002B0280456F00072B01BC63FF1FF7A10047 -+:10D0800068DE862C272B01BC60130217A100025E0C -+:10D0900002F000BF01882C0E0337A200025E02F0EE -+:10D0A00000C501BC6003000B0302055EAF00072D45 -+:10D0B00001BC6103001133020580BF00073301BCCE -+:10D0C00060131157A100025E02F000BF0196600ECE -+:10D0D00003301900B040670017A200025E02F000A2 -+:10D0E000C50283C03700000200E0021F0020870154 -+:10D0F00082600628914403BFDE02F00002028140F4 -+:10D10000130000020200420300073A01846002F5A6 -+:10D1100097AC01BC600300108003A3DE02F0073D62 -+:10D120000190600209104800B0446700179E00B0EB -+:10D13000446B00179D00B0446F00179C00B044730F -+:10D1400000179B0068DE7A23273D00E002230020C1 -+:10D15000880115403B00179700B001430017A1015B -+:10D16000C9DE8405280501BC60031077950191E0B4 -+:10D17000020D906C0286403700074B00E002BB00B6 -+:10D1800020AE03BFDE02F00A8E01BC6003001480F3 -+:10D1900001BC600300148101B8600A04902401BC42 -+:10D1A000600304082B01BC600300482A01BC600333 -+:10D1B00000D02A01B3600700100401BC600300081E -+:10D1C0000E01BC600300080F01BC600300081001E1 -+:10D1D000BC60030008110183E002F5D7AE0287C0EE -+:10D1E00037000A8A00025E02F0117700025E02F048 -+:10D1F0000EFF03435E02F00757006D403300CAFA8A -+:10D2000000685E5F00476F00685E5F00276C006823 -+:10D2100000A700C761006800A7010761006880A738 -+:10D2200000A76200E0446690283701BC62C3001783 -+:10D23000A102805203000765019652030017A10066 -+:10D2400080DE8690379A0203520300076A00E05E90 -+:10D250006A90379A0207D20300076A00E85E6B0003 -+:10D26000379A029E5E6B000AFA03BFDE02F0077473 -+:10D270000152D2030017A10185D206F4379A03BFE9 -+:10D28000DE02F00774013C52030017A101BC5206F4 -+:10D29000F4379A006E5E680BAAFA00682FC3000785 -+:10D2A00074028E5207000AFA0204C03B00077E0196 -+:10D2B00081E0060D906C02874037000A8E00025E06 -+:10D2C00002F0117700025E02F00EFF0287C0AF008D -+:10D2D00007760287C0AF000A8A015840AF00179A4C -+:10D2E00001BC603F1E17A1006DDE6AF42A8A035B51 -+:10D2F0005E02F0078001BC601300104300B04123C0 -+:10D3000028104801806002F297940184E00209101D -+:10D3100048015840AF00102A006840AB002A8A013B -+:10D32000BB5E5600900402035E5700078F02004761 -+:10D33000A300078C01BC621E3C11E001BC6003002D -+:10D3400011EA00B05E6B0011EB0198601E3D11E820 -+:10D35000020047B300078F00B05E6B0011EF01B011 -+:10D36000E0CE3D91EC03835E02F0079300025E0283 -+:10D37000F0117700025E02F00EFF006D403304C72B -+:10D380008F03AADE02F0079C018360020D906C02FD -+:10D390000200F300079A0280521700079C00E04148 -+:10D3A0008700B06500025E02F00C460280C0770084 -+:10D3B000079B03305E02F0079C018360060D906CB2 -+:10D3C00001BC60030008020188E00F000803006D43 -+:10D3D00040330208B60129520F0017930109520F7A -+:10D3E0000017AA01966002F2979400E0418701F0CD -+:10D3F0006501BC600F0017A10028DE869067A801B8 -+:10D40000866006F2979400E0419700706500E02086 -+:10D41000AF00C82B01065E530017A200A05E4F04A8 -+:10D4200077A10068DE870447B60186E006F297948C -+:10D4300000B85E8B0037A200B05A030017A0020AA2 -+:10D44000DA030007B001876006F297940284C03BBC -+:10D450000007B60203DA030007B603AB5E02F0076B -+:10D46000B4020441070007B60180600500680301AB -+:10D47000065E530017A20182DE8A00900403AADE32 -+:10D4800002F007E703AB5E02F007D10287D2130078 -+:10D4900007E700B0521300118601A5E00A301180A1 -+:10D4A000018460020D906C01BC63FF1FF79900E0DE -+:10D4B00041870170650068DEAB0027C300A05E4FA6 -+:10D4C000FF77A10068DE870727CF03BFDE02F007E2 -+:10D4D000C50284520F0007CF0204D20F0007C80311 -+:10D4E000B15E02F007CE00E0418701106503BFDEA8 -+:10D4F00002F007C903B35E02F007CE020080F3001A -+:10D5000007CF020052170007CF00025E02F00C4660 -+:10D510000200C0770007CF012940770017990184E6 -+:10D5200060060D906C020052170007E703315E029F -+:10D53000F007E7018660023011800180E001620B94 -+:10D5400010020052170007D50202AB4F0007E2009D -+:10D5500068DE5F0007E200B02BB70017A100682A61 -+:10D56000BB0007E200B02BB30017A2006DAABAF40B -+:10D5700047E20068DEAB0047DE006D2BBAF427DD22 -+:10D5800000B02C6B000B190184E006F7F7BF0068B0 -+:10D59000DE4F0287E200025E02F013090206DEFFA0 -+:10D5A0000007E200E02BE7002AF90068DE5F0007D1 -+:10D5B000E50068DEAB0047E50180E005620B100086 -+:10D5C000682B6F0007E70180E006F7F7BF020752FC -+:10D5D0000F000867028047A3000864028047B30079 -+:10D5E000086400E020AF00882B00E820AB00882A08 -+:10D5F00001BC60030011E401BC63FF1FF7A501BC7F -+:10D60000600303D1E102065E530007F101BC600331 -+:10D610000491E10206DE530007F500E04787005160 -+:10D62000E10207D20F0007F500E047870091E10013 -+:10D630006D403302C8B600685E4F0587F80068DEAB -+:10D64000AB00486703AB5E02F007FB020052170015 -+:10D650000867020580F300080600E04187011065B5 -+:10D66000020200F30007FF0204D20F0007FF00E0F0 -+:10D67000418700B06500025E02F00C460200C077F0 -+:10D68000000803012940770017A500E05E97009786 -+:10D69000A50068DE97FFE8060280521700086702BF -+:10D6A0000700BF00086701BC601F1417A200904765 -+:10D6B0008700306500E04196F4506500E04787013F -+:10D6C000082103835E02F0080E00025E02F011776B -+:10D6D00000025E02F00EFF006D403104280A006D6A -+:10D6E00040310428B601BC600B1D57A10068DE97CD -+:10D6F000FFE81E010F5A070017A5031EDE02F008FF -+:10D700001E0200521700081E032C5E02F00867007C -+:10D71000685E67FFE81E00E05E6700979900E05EC4 -+:10D7200066F43064012A58030017990100DE97005F -+:10D7300017A500E05E66F4B79900E05E67003799D0 -+:10D74000011558030017A603BFDE02F0082E00E003 -+:10D750005E96F43064012A5803001799020580F39D -+:10D7600000082D0182E002F33799020052170008E9 -+:10D770002D0116D8030017A6010F5A070017A401A0 -+:10D780000CD8030017A10068DE92F4282900E05E9F -+:10D790006702179903BFDE02F00832010DD80300BB -+:10D7A00017A10068DE92F4286700E05E670417990D -+:10D7B00003BFDE02F00832011058030017A600680C -+:10D7C000DE9B00C8320181DA030017A100B85E8633 -+:10D7D000C017A10281DE8700086700885E670077B6 -+:10D7E0008000E000AEF0106401AADE65004802008F -+:10D7F00068DE9B00484C0207818700083F006DDE11 -+:10D80000030C083F0285520F00083F0298523B006C -+:10D81000083F0181E00500680300E05E000B37A3CC -+:10D8200000E05E8F0097A300E041870077A200022E -+:10D830005E02F00D5200E820AB01082A01BC602313 -+:10D8400007978100885E970077A100E85E86F4B0B4 -+:10D850006301BC60070E17A100E0418EF430630045 -+:10D86000B056170017A100B0561B0017A20068DEC3 -+:10D8700086D048670068DE8AD0686700025E02F0E2 -+:10D880000D2701BC602307506401BC624F0017A242 -+:10D8900000025E02F00D7A00685E9B00486401BCE5 -+:10D8A000621EF471E00068DE9B00C85701BC611382 -+:10D8B00000B7A1020600F300085301BC601300B7D3 -+:10D8C000A101BC60030011EE00B05E6B0011EF011E -+:10D8D00092E00EF431EC03BFDE02F0086400685EF3 -+:10D8E0009B0068590068DE9B00A864019860063DB3 -+:10D8F00011E800E020AF00882B00E820AB00882A68 -+:10D9000001BC60030011EA0068DE5F00485F00B000 -+:10D910005E6B0011EB0192DE5E3D11E80187600253 -+:10D920003D11E80068DE9B00A863018760063D1199 -+:10D93000E8019860163D11E80181E0050048020108 -+:10D94000AADE6500480203BFDE02F0086C01BC627B -+:10D950000F0011E001BC60030011E40181E001004F -+:10D96000680301BC600F0011E801BC60030011EC0A -+:10D970000200200F00087300E020AAF3482A00B03C -+:10D9800020AF00102500E820AA04A82A006AA0AB56 -+:10D9900001C87301B860060490240182E006F29782 -+:10D9A000940188600A00900401BC60031877950315 -+:10D9B000A0DE02F0088000685E4F06A8850138529C -+:10D9C0000300178000B05E5F0017810203DEB7001E -+:10D9D000087F00685E0700087E01BC600301778055 -+:10D9E00001BC600300378103BFDE02F0087F01BC89 -+:10D9F000600301578000025E02F000CC0068DEABDD -+:10DA000000488500A05E4F0477A100685E87004A49 -+:10DA10003600685E87044A3603BFDE02F00BCC0393 -+:10DA200086DE02F00A8B0287C037000A8A00025E97 -+:10DA300002F0117700025E02F00EFF03035E02F0B7 -+:10DA4000088503A9DE02F0089100025E02F011775A -+:10DA500000025E02F00EFF0207403700088B0386CB -+:10DA6000DE02F00A8B0287C037000A8A00025E02DB -+:10DA7000F00C43006E40300208BC0301DE02F008E7 -+:10DA8000BC0068DEAB0008A3032B5E02F008970021 -+:10DA9000E0022B00208A03BFDE02F0089B028052C6 -+:10DAA0001700089A00E0024300209003BFDE02F056 -+:10DAB000089B00E0025700209500685E4F040B6C45 -+:10DAC00000685E4F028B6C00685E4F0209ED0068D3 -+:10DAD0005E4F048A2F00685E4F050BBD00685E4FE5 -+:10DAE000060BBD00685E4F068BC603BFDE02F00B5F -+:10DAF000CC0068DEAB0028B4032B5E02F008A70060 -+:10DB0000E0022F00208B03BFDE02F008AB02805240 -+:10DB1000170008AA00E0024700209103BFDE02F0D0 -+:10DB200008AB00E0025B00209600685E4F06A9C1CA -+:10DB300000685E4F042BE400685E4F04ABE40068AD -+:10DB40005E4F05AA3C00685E4F0629C100685E4F23 -+:10DB5000052BBB00A05E4FFF77A100685E87072BF7 -+:10DB6000D703BFDE02F009E600E0021300208403C1 -+:10DB7000BFDE02F009EA00E0020F00208301BC6072 -+:10DB8000030011EC01BC600F0011E80284C03B00EF -+:10DB900008670184E00609104803BFDE02F0086749 -+:10DBA0000200C09300000203A35E02F008C003C39A -+:10DBB0005E02F008BF03BFDE02F00AF600025E025A -+:10DBC000F0117700025E02F00EFF0207C0AF0008FE -+:10DBD000C4020740370008C00107C0AF0017A1000A -+:10DBE000B85E870037A101825E860D906C00B0445C -+:10DBF0007F000804018360020910480287C03700D3 -+:10DC00000A8A0386DE02F00A8B00025E02F01177B8 -+:10DC100000025E02F00EFF03435E02F008C90287B5 -+:10DC2000C037000A8A020081B30008E7018060065D -+:10DC3000F297940301DE02F008E70138520300175F -+:10DC40008000B05E5F0017A400025E02F012F001D7 -+:10DC5000BC602F0657A400E05E86F4906500E05A91 -+:10DC60000300368003B05E02F008DB00E00207002C -+:10DC7000208103BFDE02F008DC00E0020300208008 -+:10DC8000028481B30008E10184E0040D806C01BCD2 -+:10DC9000600300006E01BC600300006F03BFDE0282 -+:10DCA000F008E600E8523AF7B7A100E85E870217ED -+:10DCB000A100905E870097A100E101BAF4206E00F8 -+:10DCC000E081BF00006F00B0523B0017BD0301DED2 -+:10DCD00002F008FD028081B30008EA03305E02F022 -+:10DCE00008FD01BC601B1F506500E04194DF3065FA -+:10DCF000012D406B0017A200885E8B0137A201380E -+:10DD0000402B001680028840270008F1018460063D -+:10DD1000D0168000B05A02F456800205C0270008D1 -+:10DD2000F40187E006D0168001BC601B0DD7A1006E -+:10DD3000025E02F000BF00B0406700168101BC60C7 -+:10DD40001B0DF7A100025E02F000BF00B0406700AB -+:10DD5000168200E01BE70066F900691BE70188FDF9 -+:10DD600001BC60030006F9020081B30008FF020550 -+:10DD700001B3000AFA0280200F000901006E403052 -+:10DD80000209BC0381DE02F0090B00E0021700204B -+:10DD90008503A9DE02F009070184E00609104801A5 -+:10DDA00080E0020910480184E002F7F7BF0386DE35 -+:10DDB00002F00A8B0180600500480201806006F2D3 -+:10DDC000979403BFDE02F0098A01836002F7F7BF70 -+:10DDD0000386DE02F00A8B032B5E02F0093103A9F1 -+:10DDE000DE02F009140068DEAB00493100B0523B9E -+:10DDF00000179F00B0523B0017BE01BC6003002813 -+:10DE00000E03BFDE02F0093102875E5300093E03B4 -+:10DE1000A0DE02F0092003BFDE02F006B20182E0BC -+:10DE2000060D906C0190600A09104800B0523B004A -+:10DE3000179F00B0523B0017BE019E5E8300B0EBFF -+:10DE40000106520F0017A100B85E870037A10182BA -+:10DE5000DE86F577AB01BC610300308000E8523A02 -+:10DE6000F3F7A2006BD23AF3E92300E85E7E91D784 -+:10DE7000A200905E8B0097A101BC602301D06400DA -+:10DE80006B523AF3E92E01185E870017A2010A5E71 -+:10DE9000870017A300886006F457A200E04192F4BF -+:10DEA000706400B05802F45600006BDEFA91C9317C -+:10DEB00000B0523B0017BE03BFDE02F00931000282 -+:10DEC0005E02F011E700B0203B00280E00B0523B8C -+:10DED00000179F0320DE02F0093E02075E5300098F -+:10DEE000350180E00209104803BFDE02F0093E0060 -+:10DEF00068DE5F00093B021A54070009390103C0BC -+:10DF0000270017A101825E8610D0860102C027007B -+:10DF100017A100E0422AF4308A0180E0050048029F -+:10DF200003A9DE02F0093E00B05E47001080010840 -+:10DF30005E4F0017A100685E8700295E03AB5E029A -+:10DF4000F009620200521700094F0068DEAB004979 -+:10DF50004400E0025300209402865E5300098A02C6 -+:10DF600084520F000AFA0284D20F00094903AC5E02 -+:10DF700002F0094D03BFDE02F00956032C5E02F0E9 -+:10DF8000095600685E4F04094D0106D20F0017A123 -+:10DF900001845E86F2979400685E4F02098A03BF8F -+:10DFA000DE02F0097A031EDE02F0095303315E023D -+:10DFB000F009530068DEAB00495301846002F29718 -+:10DFC000940068DEAB00495800E0023F00208F0358 -+:10DFD000BFDE02F0095B00685EAB00495B02805265 -+:10DFE0002F00098A0202410700095B00685E4F04A6 -+:10DFF000098A00685E4F02898A0284410700098A03 -+:10E0000001806006F2979403BFDE02F0098A032BB9 -+:10E010005E02F0098A00685E4F05A97A00685E4FCB -+:10E0200005297A03BFDE02F0098A0068DEAB0049E9 -+:10E030006A01BC6003000ABD01826002F5D7AE022E -+:10E04000805EFF00096800682B6F00096A00E044E9 -+:10E05000655B4ADB00682B8BFFC96A00E02B8B00F5 -+:10E060002AE202065E5300096D00E0026300209878 -+:10E0700003BFDE02F0098A0323DE02F009750129DD -+:10E08000500B0017A30068DE8F0529750187E00299 -+:10E090001070830184600209104800B05E87001789 -+:10E0A000A1006EE00300297403D1DE02F0097500BF -+:10E0B00068DEAB00497700E0022700208900685E37 -+:10E0C0004F00098A00685E4F01098A00685E4F05AB -+:10E0D000898A028047C70009BA0329DE02F0098055 -+:10E0E0000102DEAF0017A10106520F0017A200388F -+:10E0F0005E86F4498A0182DE8AF577AB00B052234E -+:10E100000011F200B052270011F300B0522B0011A1 -+:10E11000F40106520F0017A100E05E870031F50000 -+:10E12000B0005B0011F000B047C30018000134C715 -+:10E13000C70017A1006EDE8402A98A01BC60030833 -+:10E1400010420283C10700098C02805E53000AFA64 -+:10E1500000B040330017A10108A00F0017A200680B -+:10E160005E8B00699400E840310577A10281200FA1 -+:10E1700000099400B020AF0017A10280A00F000991 -+:10E180009400B05E630017A1006E5E840209BC00BB -+:10E19000B05E870007FA018160010048020202C0F8 -+:10E1A0001300099A00E05E840347FA0181600500CC -+:10E1B00048020201200F0009B501035E530017A1B8 -+:10E1C0000187DE850048020386DE02F00A8B00022A -+:10E1D0005E02F0117700025E02F00EFF03855E0220 -+:10E1E000F0099D018E60023D11E80107C783001709 -+:10E1F000A101825E850048020201A00F0009A7016B -+:10E2000003C7970017A101825E8500680300B02054 -+:10E210004B0017A1018E5E850068030207C0AF00A6 -+:10E220000C2701BC60030011EC01BC600F0011E879 -+:10E230000184600500680300B040270007FC00B0BF -+:10E24000402B0007FD00B0406B0007FE00B0406FA0 -+:10E250000007FF0184600500680300025E02F00C05 -+:10E260004301BC63FF1FD7A800025E02F00D160039 -+:10E27000025E02F00C2701A8600A0090040201204F -+:10E280000F0011D200A8401300500403BFDE02F0BB -+:10E29000061700E002870020A103BFDE02F009BDDF -+:10E2A00000E0020B00208203A9DE02F00AFA0184DA -+:10E2B00060060910480184E00609104803BFDE0229 -+:10E2C000F00AFA032B5E02F009DE0068DE4F06A9B1 -+:10E2D000C500E0023B00208E03BFDE02F009C6004D -+:10E2E000E0023700208D0323DE02F009E60068DE3D -+:10E2F0004EF1C9E60187E0021070830184600209D3 -+:10E30000104800B05E870017A1006EE0030029CC22 -+:10E3100003D1DE02F009CD00685E4F0629DC01BCA6 -+:10E320006003000AA603295E02F009D20203DEB3ED -+:10E330000009D30191601A84F4270183E002F59764 -+:10E34000AC020200BF0009DB0203456F0009D601E1 -+:10E3500085E0062B715B02045EB30009DB0187E0F8 -+:10E36000021070830183E00209104800025E02F08F -+:10E37000111E03BFDE02F009E60205500B0009E69C -+:10E380000182600609104803BFDE02F009E6028739 -+:10E3900000C30009E30068DE4F06A9E30068D2135A -+:10E3A0000009E301BC600300118301BC600300119C -+:10E3B000820068DE4F0629E600E0024F002093034A -+:10E3C000BFDE02F009E603AB5E02F009E802044199 -+:10E3D000070009EB028341070008BC03BFDE02F01F -+:10E3E00009EB028441070008BC01806006F29794A3 -+:10E3F00003BFDE02F008BC039F5E02F009F0039E3B -+:10E40000DE02F00BCC02035E53000BCC020481430E -+:10E410000009F4010001630017A10102C0270017E1 -+:10E42000A20038DE86F449EA03AB5E02F009F60288 -+:10E430000052170009EA0280522F0009F803335EE8 -+:10E4400002F00BCC023C523F000A09013C523F0053 -+:10E4500017A10068DE84048A2901BC6003161064D9 -+:10E4600001BC601F16106500685E87002A0500B0B9 -+:10E470005A030017A20068DE8AC00A2900E041970B -+:10E4800000306500E0419300306400E85E8700578B -+:10E49000A1006A5E870029FE00685E87000A0A0103 -+:10E4A000385A030017A1013858030017A20068DE8C -+:10E4B00086F44A2903BFDE02F00A0A0285C107007A -+:10E4C0000BCC01BC601F15F06501BC600305B7A44F -+:10E4D00000025E02F00106028000C3000A2901BCAE -+:10E4E000601310D7A600E0017F00B7A5006D5E960F -+:10E4F000F4CA1201BC60130957A500685E940BCAE8 -+:10E500002D00B0017B00106500B052270017A2005B -+:10E51000B0522B0017A3006841940BEA1D0068DE7F -+:10E520008ED04A1900685E8AD02A2900E0419700FF -+:10E53000B065006D4196F4CA1601BC6013095065C0 -+:10E5400003BFDE02F00A1600E0028B0020A200B03A -+:10E55000017F00106500B0522300168000B05227E2 -+:10E5600000168100B0522B00168201BC5202F2F755 -+:10E57000A101A95E02F4368300904467011684026B -+:10E580000281AB000A270068DE9305AA2801846097 -+:10E5900006D0968400B05E9700005F020781AB0052 -+:10E5A0000A2B01806006F2979403AB5E02F006CA64 -+:10E5B00003BFDE02F008BC00E0028F0020A303BF0F -+:10E5C000DE02F009EA039EDE02F00BCC03AB5E0232 -+:10E5D000F00A32020052170009EA03335E02F00B20 -+:10E5E000CC01846006F2979403AB5E02F006CA0386 -+:10E5F000BFDE02F008BC03835E02F00A3900025E4F -+:10E6000002F01177006D4033038A36006D4033030A -+:10E6100089EA032B5E02F00BD003BFDE02F006CACC -+:10E62000032B5E02F00A3F00E0023300208C03BFA0 -+:10E63000DE02F006CC00E0024B0020920103C0276E -+:10E6400000178101825E0503178100025E02F00D52 -+:10E6500004008800230037A200E05E8800F7A200D3 -+:10E66000E05E86F451890186E00630118003BFDE4A -+:10E6700002F009E603A2DE02F0009F03A3DE02F02F -+:10E680000A6500E001FF00207F01BC60030017A3C2 -+:10E6900003BFDE02F00A67018760040310A001BC1B -+:10E6A00060030051E400B0479300180001BC600310 -+:10E6B00002900401BC620F0011E001BC600F013147 -+:10E6C000E800B047A300180001BC600F0011E8018A -+:10E6D000BC60030131EC00B047B300180001BC601E -+:10E6E000030011EC018460060910480020601E0937 -+:10E6F0000A5C00E001FB00207E03BFDE02F00A6D31 -+:10E7000001BC60030ED7A1011400630017A200E052 -+:10E710005E86F4506500E05A03003680020300C7AD -+:10E72000000A6203A95E02F00A670291509F000A84 -+:10E73000660191601A84F42703BFDE02F00A6600C6 -+:10E74000E001FF00207F01BC60030037A30323DE4C -+:10E7500002F00A6D0183E00209104801846002F5AD -+:10E7600097AC01BC600300178E0187E00210708334 -+:10E770000182600209104803D0DE02F00A6E03D065 -+:10E780005E02F00A6F0182E00209104803D5DE0242 -+:10E79000F00A7101BC60030010B401BC600300F713 -+:10E7A000A1006800A7000A750185421AF437A1008C -+:10E7B000025E02F000BF00B040670017A501BC6315 -+:10E7C000FF1FF7A200025E02F000C500886007018B -+:10E7D00057A400B85E86F497A100025E02F000C55F -+:10E7E0000283C21F000A7C00E044670117A10204F3 -+:10E7F0004523000A81006B4466F42A7E00025E0213 -+:10E80000F0115E00685E8F000002006801B3000A2C -+:10E810008501BC60030004EE03BFDE02F00A88003D -+:10E8200020E01E090A8800B05E9700142E03BFDEA8 -+:10E8300002F002F200A8412300F04803BFDE02F01C -+:10E8400000020183600209104801BC600700104209 -+:10E85000006E4030020A8E00E0027700209D000228 -+:10E860005E02F012A403A35E02F008BC03C6DE023F -+:10E87000F00A910184E00609104803BFDE02F00AA5 -+:10E88000FA006820E3000A9900E844650717A1012F -+:10E89000BC609F0217A2006D5E86F44A9901BC60BD -+:10E8A0000300083800025E02F00B190020E10209A3 -+:10E8B000008C0020628A090A9D00025E02F0117736 -+:10E8C00003BFDE02F0008C0284452300008C03911C -+:10E8D0005E02F0008C0396DE02F0008C03965E026E -+:10E8E000F0008C00025E02F00B1901BC60030060B6 -+:10E8F0002000680173000AB300025E02F000F1001C -+:10E90000B0446700083800B001730010E401BC6037 -+:10E910000300000601BC600300005C01BC60030151 -+:10E92000D78201D2DE087570E000B00EB30010E1AE -+:10E9300000B0004700108600B00ECF00108A01BC66 -+:10E94000600300378100025E02F00CF70190600A5C -+:10E9500009104801BC610300308003BFDE02F000F3 -+:10E960000201BC60030030420187E00224712300F1 -+:10E97000025E02F0108401BC600306778000680D1F -+:10E98000EF000ABA00B00DEF00178100025E02F03E -+:10E990000DAE03975E02F00B2A03125E02F00ABA74 -+:10E9A00001BC600300402001BC618300112500B060 -+:10E9B000007B00112701BC600702578000025E0245 -+:10E9C000F00DA900B05E07000B3001BC60070277B4 -+:10E9D0008000025E02F00DA900B05E07000B31015D -+:10E9E000BC60130997A100025E02F000BF00B040B6 -+:10E9F00067000B6301BC601309405E01BC60130932 -+:10EA0000405F0180E006F5D7AE0107C1070017A1FE -+:10EA100001805E86F577AB01BC600F0011E801BC98 -+:10EA2000620F0011E000025E02F00ADC01BC61CF5F -+:10EA30000C105C01BC600300105D01BC61CF01F0F3 -+:10EA40005E01BC603B0AF05F00025E02F01048010C -+:10EA5000BC6003000835020300C700000201BC606F -+:10EA60000300060201BC600300060701BC6003004E -+:10EA7000060C01BC600300061103BFDE02F00002B9 -+:10EA800001BC60030010480185E002F5B7AD01BC90 -+:10EA900063FF1FF05401BC63FF1FF05501BC63BF4F -+:10EAA0001FF05601BC63FF0FF05700025E02F01228 -+:10EAB000A40187E00624712301BC60030010540107 -+:10EAC000BC600300105501BC600300105601BC601F -+:10EAD0000300105701BC600F0020170106C107009A -+:10EAE00017A101825E8402E017010741070017A108 -+:10EAF00000B85E870037A10180DE870000160002A3 -+:10EB0000DE02F000000285C03700000200025E0253 -+:10EB1000F0117700025E02F00EFF02864037000A15 -+:10EB2000EF00E0021B0020860386DE02F00A8B0263 -+:10EB300087C037000A8B0158600300102A01BC60AF -+:10EB40000300900400B040130017A103BFDE02F0E1 -+:10EB5000000201B8600A04902403AA5E02F00AFDD4 -+:10EB60000158600300102A01BC600302900400B049 -+:10EB700040130018000183600209104801BC6003C3 -+:10EB80000051E400B0479300180001BC620F00116F -+:10EB9000E00180600100680300025E02F00EFF03E6 -+:10EBA000855E02F00B0401BC620F0011E001BC6045 -+:10EBB0000F0131E800B047A300180001BC600F004E -+:10EBC00011E801BC60030157A100E85E870037A18E -+:10EBD0000068DE87000B0B01BC600302900400B0EC -+:10EBE000401300180001BC60030131EC00B047B3D2 -+:10EBF00000180001BC60030011EC0324DE02F006E3 -+:10EC00001701866006F577AB00025E02F00B190172 -+:10EC100080600610308100B05E870017A10180601F -+:10EC20000210308103BFDE02F0061701BC61030051 -+:10EC3000108000B04203001800006EE003002B1C9F -+:10EC400003505E02F00B1F00015E02F0000003BFE4 -+:10EC5000DE02F0030F01846002F597AC00A84123A7 -+:10EC600004F048018260020910480206DEAF000B82 -+:10EC70002503D5DE02F00B250350DE02F00B230145 -+:10EC8000BC60030010B40284C783000B2801BC6081 -+:10EC90000B0011E0018E6002F577AB0002DE02F09E -+:10ECA000000003A2DE02F0008C02BC4287000B31A0 -+:10ECB00001BC60030037A401BC60031FF7A301146B -+:10ECC00000630017A200886006F457A203BFDE02AB -+:10ECD000F00B36008860070117A401BC63FF001722 -+:10ECE000A3011400630017A200E05E8B0117A200CD -+:10ECF000886006F457A201BC601311106501BC6066 -+:10ED00001B02506401BC60030017A50020C286F4FA -+:10ED10008B4000E0419706D06500E0419301F0642C -+:10ED200000E05E970037A500885E930037A40020BE -+:10ED30005E92F46B5F03BFDE02F00B390068DE9277 -+:10ED4000F44B4500680083006B4503A0DE02F00B26 -+:10ED5000450020C123160B3A00025E02F00B190099 -+:10ED60006DDE93200B5B020300C7000B4F006DDECE -+:10ED700097008B4F01BC600300160801BC600300C4 -+:10ED8000160901BC600300160A01BC600300160BE3 -+:10ED900001BC600300160C01BC600300160D01BC31 -+:10EDA000600300160E02005AC3000B5A023C5A9F21 -+:10EDB000000B5A00680083006B5A0385DE02F000E6 -+:10EDC0008C03855E02F0008C03A2DE02F0008C034F -+:10EDD000A3DE02F0008C0397DE02F0008C00B0414D -+:10EDE000970010600191600A84F42703BFDE02F0EF -+:10EDF00002F201806002D616B000B05E930010A14E -+:10EE000001836002F7F7BF01BC600300304303BF1A -+:10EE1000DE02F00B3A0068808300608C03BFDE02E4 -+:10EE2000F00ABB0283C21F00000200B05E87001719 -+:10EE3000A103D0DE02F0051E01BC600304104203F2 -+:10EE40009EDE02F0000200B05E3F00114501BC6092 -+:10EE50000300178F00B05E4300178500B05E0F00FF -+:10EE6000179000025E02F00B1903BFDE02F00002F1 -+:10EE7000006D40330589EB03AC5E02F00B71006856 -+:10EE80005E4F028BA600E0026700209903BFDE02FE -+:10EE9000F00BA600685E4F028BA600E0025F002028 -+:10EEA0009701856002F5B7AD01826002F5D7AE012A -+:10EEB000BC6003000ABD039F5E02F00BB9039EDE37 -+:10EEC00002F00B860321DE02F00B8600E0026F00E9 -+:10EED000209B00025E02F00B1901866002091048B7 -+:10EEE000018060020910480181E00209104801BC5C -+:10EEF00060030210420280441F000B8500B05E3F99 -+:10EF000000114501BC600300178F00B05E4300177D -+:10EF10008500B05E0F00179003BFDE02F00B860085 -+:10EF2000A044B6F07145039F5E02F00BB902820067 -+:10EF3000C3000BA603335E02F00BA600B000730003 -+:10EF400017A100E05E86B017A100E15E7AF4379E5B -+:10EF500000E1DE7700179D00E1DE7300179C00E002 -+:10EF6000DE6F00179B039EDE02F00B97006E5E6E55 -+:10EF7000924BB9006D5E6E924B97006E5E72922B53 -+:10EF8000B9006D5E72922B97006E5E76920BB9009F -+:10EF90006D5E76920B97006DDE7A91EBB900B0440E -+:10EFA0006700083400B0446B00083300B0446F00C1 -+:10EFB000083200B044730008310068A0D2232B97B8 -+:10EFC00000E920D2F3D79E00E9A0CEF3B79D00E977 -+:10EFD000A0CAF3979C00E8A0C6F3779B00E15E7A95 -+:10EFE00091F7A100B05E8700111900E1DE76921161 -+:10EFF0001A00E1DE7292311B00E0DE6E92511C00BD -+:10F0000068DE86232BA0031EDE02F00BB9039F5E91 -+:10F0100002F00BB900685E4F028BB903335E02F059 -+:10F020000BB901BC601F16B06501BC600300B7A43A -+:10F0300000025E02F001060068DE9300ABB9020731 -+:10F04000C197000BB2013C5A07001788013C5A0BCC -+:10F050000017A103BFDE02F00BB401385A070017F6 -+:10F060008801385A0B0017A101845E86F29794013B -+:10F0700087DE86249124020680F3000BB9018460A8 -+:10F0800002F297940187E00224912403AB5E02F020 -+:10F0900006CA03BFDE02F008BC032B5E02F009EAD9 -+:10F0A00003BFDE02F006CA03AB5E02F00BC0032C06 -+:10F0B0005E02F009EA03BFDE02F00BD000B052237B -+:10F0C0000011F200B052270011F300B0522B0011D2 -+:10F0D000F401BC60030091F500B0005B0011F00387 -+:10F0E000BFDE02F006CA0138523F0017A102065ED9 -+:10F0F00053000BC90138524B0017A10068DE87008E -+:10F100008BCC03AB5E02F006CA03BFDE02F008BC84 -+:10F110000068DE4F020BCF020781AB000BCF0180EE -+:10F120006006F2979403AB5E02F006CA020000F399 -+:10F13000000BD50206DE53000BD501185E830017C5 -+:10F14000A10068DE8700ABD501BC600B0251420212 -+:10F150000052170009EA03BFDE02F008BC01BC60E0 -+:10F160000300118301BC6003001182032C5E02F0D6 -+:10F170000BDC0199E00620110003BFDE02F00BE07A -+:10F180000119402F0017A100685E870009E6019968 -+:10F19000DE8620110003315E02F009E600A05E3B2E -+:10F1A0000097A200205E4EF449E601846002091037 -+:10F1B0004803BFDE02F009E6032B5E02F009E60019 -+:10F1C00068DE4F042BE900B0523300179F00B052A5 -+:10F1D0002F0010EB0281522F0006B200E002AB00BC -+:10F1E00020AA0281522F0009C603295E02F00BEF0C -+:10F1F0000203DEB3000BEF0191601A84F427018350 -+:10F20000E002F597AC0208522F0006CA03BFDE02E7 -+:10F21000F008BC01BC600300106701BC6003001073 -+:10F22000460180E0060930490282C11F000BF90146 -+:10F23000BC602F1FF06501BC600300168000E84130 -+:10F24000970030650069C197000BF601BC600B00A8 -+:10F25000179401BC60030017AB01BC60030017AC3E -+:10F2600001BC60030017AD01BC60030017AE01BC18 -+:10F2700060030017BF01BC600300202001BC6003D5 -+:10F280000017A100025E02F000BF013840670000D5 -+:10F2900028011C406700002901BC6003005049019F -+:10F2A000BC60030017A701BC60030017A801BC6085 -+:10F2B000030017A901BC60030017AC01BC60030088 -+:10F2C00017AD0182E0060F10780206C1E3000C0BB7 -+:10F2D000006880A7000C0E03BFDE02F00C0F006870 -+:10F2E00080A7008C0F01BC600B1EA00001BC600356 -+:10F2F00000200101BC631301200201BC62330AC07B -+:10F300000301BC600300000401BC60530D800501D3 -+:10F31000BC601F14106101BC601317D06001BC6099 -+:10F320000300082900B05E0F00178500A044B6F066 -+:10F330007145028741D7000C1A01BC6003000BF035 -+:10F3400001BC600300107D01BC600300107C01BCA7 -+:10F35000606300107B01BC600300107A01AC607F29 -+:10F3600000107501BC63470897A10068C1DAF42C4E -+:10F3700026011A41DF0017A10068DE87016C260113 -+:10F38000BC637B15ABF003BFDE02F00AA201885E0E -+:10F390005CFF87FC01BC601F1F500701BC600301BC -+:10F3A0009008018860060090040386DE02F00A8B54 -+:10F3B0000305DE02F00C2B0386DE02F00A8B0385C8 -+:10F3C000DE02F00C2D00B05E870017A1006EE00396 -+:10F3D000002C310386DE02F00A8B006EC0146F2C05 -+:10F3E0003401BC60070010420207C0AF00077A007A -+:10F3F00002DE02F0000003215E02F00C3A00E02081 -+:10F4000066F4281900B0206700178B03BFDE02F0F6 -+:10F410000C42028150C7000C3F011C509F00178B0B -+:10F4200000E05E2EF4378B019C5E2E84F42703BF30 -+:10F43000DE02F00C42011E509F00178B00E05E2E92 -+:10F44000F4378B019E5E2E84F4270002DE02F0006A -+:10F45000000107402700082800E020A3002828001A -+:10F4600002DE02F0000000B05A0300101F00B05A84 -+:10F470000700102000B05A0B001021018060070027 -+:10F48000101D02804077000C4A0002DE02F00000EE -+:10F490000187E002F577AB03915E02F000020020E5 -+:10F4A000E3FE09000202815E53000C580283411FF3 -+:10F4B000000C520281DE53000C5E01BC600300119F -+:10F4C0005101BC600300115201BC620300115301E1 -+:10F4D000BC600300515001896006F2979403BFDEBF -+:10F4E00002F000020280C54300000201F0C547009F -+:10F4F00011560107C5470017A101F0C54AF431555F -+:10F500000189600AF2979401BC60030810470392D6 -+:10F51000DE02F000020204C107000002039EDE02C8 -+:10F52000F00C6503B8DE02F0000200B0017F0017A6 -+:10F53000A10068DE840BC00203BFDE02F00C67028C -+:10F5400003DE530000020068DE23000C6802845EC4 -+:10F55000530000020287C4930000020282DEBB0057 -+:10F560000C6B00682B07000C6E00682B8FFFE0020D -+:10F5700000B02AF70017A1006DDE8556000200B02A -+:10F58000012B0017A30282DEBB000C7100682B0761 -+:10F59000000C7200E05E8D5C77A300B0440B001796 -+:10F5A000A100B0440F0017A200E95E862337A10036 -+:10F5B000E8DE8A2357A200E95E86F4681400E8DEDC -+:10F5C0008B00081500B0441F001800008844230178 -+:10F5D00057A30090442300D7A4006E5E8AF48ACE1D -+:10F5E0000068816F000C7F00685E23002C9100682A -+:10F5F0000027002C9100E85E230037A10069DE8718 -+:10F60000000C8200E05E840137A1013C016F00170D -+:10F61000A50068DE97000C890138016F0017A5006E -+:10F62000685E97000C8D00E85E970037A100685E69 -+:10F6300087000C9103BFDE02F00C8D00E85E97009E -+:10F6400037A50080DE940137A500E05E860DB7A1E6 -+:10F6500000685E87000C9100E12052F4681400E01D -+:10F66000A056F4881500E85E870037A1006A5E871F -+:10F67000000C8D01BC610300112300692057000CB0 -+:10F68000950180E006F2979403BFDE02F00C97012B -+:10F6900080E002F2979403BFDE02F00002006841AE -+:10F6A00027000CA102844523000C9800B044670099 -+:10F6B00017A100E84466F437A2006D5E8B004C9AF7 -+:10F6C0000392DE02F00ACE00025E02F01088000211 -+:10F6D0005E02F00DB900025E02F00DB400025E029F -+:10F6E000F00DC401BC600F0011E8031EDE02F00C37 -+:10F6F000A801BC600300105C01BC600300105D0148 -+:10F70000BC605304105E01BC600300105F03BFDEE9 -+:10F7100002F00CAC01BC600B00105C01BC6003008B -+:10F72000105D01BC604304105E01BC600300105F0B -+:10F7300001BC6003008020028500BF000CE800B01F -+:10F74000205300115100B02057001152006E20527A -+:10F750002A8CB40068A057000CB400E02052232883 -+:10F760001603BFDE02F00CB600B0446700081601B5 -+:10F77000BC600300315001BC60030C90400000DE0F -+:10F7800002F000000068C103000CBB02804543008A -+:10F790000CB6006B446502CCB601BC60030011508E -+:10F7A00002844543000CBC00B044670017A1006808 -+:10F7B0005E86232CBE01BC600300402001866006EB -+:10F7C00020110000E920522A37A100E8A0562A574C -+:10F7D000A200E14466F4311900E1C46AF4511A0050 -+:10F7E000E1C46F00111B00E0C47300111C00B044A1 -+:10F7F0001F001800008844230157A30090442300F1 -+:10F80000D7A400B0440B0017A100B0440F0017A20A -+:10F8100000E95E862337A100E8DE8A2357A200694B -+:10F82000DE8B000CD600E1440AF4710200E0C40E45 -+:10F83000F4910300E02AF7002ABD00E85E230037B8 -+:10F84000880069DE23000CCA00E80027003788031F -+:10F85000BFDE02F00CCA018660022011000200DE49 -+:10F8600053000CEA0180E002F2979400025E02F07D -+:10F870000DB701BC600300104003BFDE02F00CDDD9 -+:10F88000020080C3000CE100E044640957A100E8D5 -+:10F890005E862137A1006CC466F42CDF03BFDE0254 -+:10F8A000F00CEA00E8012A21281401BC60030008DA -+:10F8B0001500B0205300115101BC6003001152012A -+:10F8C000BC600300315002804543000CE603BFDEFC -+:10F8D00002F00CC001BC600300104000B0012B001E -+:10F8E00011090068AAE7000CEC0000DE02F000003D -+:10F8F00003565E02F00CEE00025E02F0014A00B018 -+:10F90000012F00110901BC61CF0C105C01BC600328 -+:10F9100000105D01BC61CF01F05E01BC603B0AF0EC -+:10F920005F00025E02F00DC000025E02F00DC90031 -+:10F93000025E02F00DBD03BFDE02F00ACE01885E5A -+:10F940000610D08601025E070017A101825E8610B4 -+:10F95000D08601BC600306778000B00DEF001781F0 -+:10F960000288421B000CFE00B00DEB0017810068FE -+:10F970005E07000D0000025E02F00DAE020B421B9E -+:10F98000000D0203BFDE02F00D03018B20A210D098 -+:10F99000860002DE02F0000000B054130017A1023E -+:10F9A00000DE07000D0B00B0418B00106501BC604C -+:10F9B0000301D7A100025E02F011A200E05E840004 -+:10F9C000F7A103BFDE02F00D10020480F3000D105A -+:10F9D00002025E07000D1002805E07000D1000900D -+:10F9E000001B0037A200E85412F457A10002DE0207 -+:10F9F000F00000020400BF000D1400025E02F00ED1 -+:10FA0000B803BFDE02F00D1500A044B6F0B145000A -+:10FA100002DE02F00000020000BF000D260068AC0C -+:10FA20000F000D2600E05EA30037A8006D5EA00564 -+:10FA3000CD2600B02CB70017A100025E02F000BF77 -+:10FA400000B040670017A20068DEA3FFED2300B0FE -+:10FA50005E8965D7A2006D00A7008D22006DA0A36E -+:10FA6000004D2403BFDE02F00D230068A0A3000DAB -+:10FA70002400B85E8965D7A200025E02F000C501CD -+:10FA8000BC60030017A80002DE02F0000000D85A94 -+:10FA9000030117A201B85A06F457A200B05603009A -+:10FAA000083C00B0560700083D00B0560B00083E69 -+:10FAB00000B0560F00083F00B0561300084000E0A9 -+:10FAC0005612F4484100B05A0300083A01385E8BE0 -+:10FAD00000083B00B021070017A401BC6003001719 -+:10FAE000A200B0419300106500B85E92D017A40048 -+:10FAF000E05E06F4506300F05E930017A300F05E32 -+:10FB0000930077A400E05E8B0037A200B85E92F409 -+:10FB100077A400E04192F4506500E05602F495802D -+:10FB200000B056030017A4006EDE8B00AD3400B8A1 -+:10FB30005E92C0D7A200D85E8B0037A200E020F210 -+:10FB4000F4483C00B020F30017A400B85E92C0F760 -+:10FB5000A200D85E8B0037A200E020F6F4483D00FA -+:10FB6000D820F70037A200E020FAF4483E00D82061 -+:10FB7000FB0037A200E020FEF4483F00D820FF0041 -+:10FB800037A200E02102F4484000D821030037A248 -+:10FB900000E02106F4484100B021070017A200B898 -+:10FBA0005E8AC017A200905E8B0037A201BC5E89FE -+:10FBB00007683B0002DE02F00000018060063C9115 -+:10FBC000E4018760063CD1E601A860023CD1E60171 -+:10FBD0008B60023CD1E600B05E8F00106300B0562F -+:10FBE000030011E700B056070011E700B0560B0004 -+:10FBF00011E700B0560F0011E701A960423C91E403 -+:10FC000001A860023CD1E6018B60063CD1E600B061 -+:10FC10005E8B00106301BC60030057A10204560311 -+:10FC2000000D6201BC60030117A100E0418EF430B9 -+:10FC30006300B056030011E700B056070011E7005B -+:10FC4000B0560B0011E700B05E8B00106301BC6082 -+:10FC50000300B7A10204D603000D6C01BC600301D0 -+:10FC600017A102065E53000D6C01BC60030197A151 -+:10FC700000E0418EF4306300B056030011E700B09D -+:10FC800056070011E700B0560B0011E701BC6003F6 -+:10FC90000017A10206DE53000D7700B05E8B001046 -+:10FCA0006302065E53000D7600A0563F01F7A103E4 -+:10FCB000BFDE02F00D7700A0563301F7A100B05E61 -+:10FCC000870011E701BC60030011E70002DE02F0CB -+:10FCD000000000685E9B00CD9401BC60070211E348 -+:10FCE0000068DE9B004D8700E847870111E101BCF9 -+:10FCF00060030011E201BC60030011E201BC60037B -+:10FD00000011E201BC60030011E201BC60030011BC -+:10FD1000E201BC60030011E201BC60030011E201DA -+:10FD2000BC60030011E200B06142F451E000B05841 -+:10FD3000030011E200B058070011E200B0580B00B8 -+:10FD400011E200B0580F0011E200B058130011E2A8 -+:10FD500000B058170011E200B0581B0011E200B0CB -+:10FD6000581F0011E200B05E9B0017A40068DE9BE4 -+:10FD700000AD9201BC60030077A40192DE930217EC -+:10FD8000A30002DE02F0000001BC60070011E300E6 -+:10FD9000B058030011E200B058070011E200B0585B -+:10FDA0000B0011E200B0580F0011E200B058130030 -+:10FDB00011E200B058170011E200B0581B0011E228 -+:10FDC00000B0581F0011E200E00146F0106401BCD1 -+:10FDD00060070031E300B058030011E200B058079B -+:10FDE0000011E200B0580B0011E200B0580F0011F2 -+:10FDF000E200B058130011E200B058170011E20001 -+:10FE0000B0581B0011E200B0581F0011E20192E04F -+:10FE10001B0017A30002DE02F00000028740C300AF -+:10FE20000DA901866006F01030028640C3000DABBC -+:10FE300000B040C70017810002DE02F00000028718 -+:10FE400040C3000DAE00B05E070010310186E00631 -+:10FE5000F010300002DE02F00000006800A701127E -+:10FE6000E003BFDE02F00DC800025E02F00DB70035 -+:10FE7000025E02F00DC90002DE02F0000000680020 -+:10FE8000A70112A90002DE02F0000001816006094C -+:10FE90003049006800A7008DBC00025E02F00DD959 -+:10FEA0000002DE02F0000000025E02F00DD90181C6 -+:10FEB00060020930490002DE02F000000188E00E15 -+:10FEC00009304900B0412700180000B0002B001095 -+:10FED000020002DE02F0000001BC6003001002011B -+:10FEE00082E0020F107801BC600300104900B041AD -+:10FEF000270018000002DE02F00000006800A701E1 -+:10FF00000DCA0280DE53000DD001BC60130777A13B -+:10FF100000025E02F000BF019060020337A20002FF -+:10FF20005E02F000C50002DE02F0000001BC6013BA -+:10FF30000797A100025E02F000BF0190601E033728 -+:10FF4000A200025E02F000C501BC60130777A100A9 -+:10FF5000025E02F000BF0190601E0337A200025E45 -+:10FF600002F000C50002DE02F000000100DE5300D6 -+:10FF700017A60181DE9A09304900B0412700180018 -+:10FF80000002DE02F000000002DE02F0000000B01D -+:10FF900044670017A2017D5E8A2357A300B01C7737 -+:10FFA0000017A100B85E84E3D7A2025A5E8B000D51 -+:10FFB000E60180E006F4271E01825E86F297940037 -+:10FFC000B05E8F00071B02001C7B000E2D00E85E58 -+:10FFD0008CE377A2006D5E88E38E2D00E04467021B -+:10FFE00087210285C523000E2A0020E3FE090E2A80 -+:10FFF00001BC60130997A100025E02F000BF006817 -+:020000023000CC -+:10000000C067000E2A01BC60131617A100025E0231 -+:10001000F000BF0068C067000E2A01BC601309D75A -+:10002000A100025E02F000BF0068C067000E2A0156 -+:10003000BC63FF1FF7A10068DE862C2E2A02009CFD -+:100040007B000E1E0180E000E3C71E01BC60230F91 -+:1000500057A100025E02F000BF00B040670077A425 -+:1000600000B05E930017A200025E02F000C501BC62 -+:10007000601B1B57A100025E02F000BF0181E00679 -+:100080000337A20186E006F457A200025E02F000E8 -+:10009000C501BC601714D7A101BC600300B7A20062 -+:1000A000025E02F000C501BC60171457A101BC60DC -+:1000B000031877A200025E02F000C501BC601714AD -+:1000C000B7A101BC600300F7A200025E02F000C508 -+:1000D00001BC60171077A101BC600F0417A20002D9 -+:1000E0005E02F000C501BC60171097A101BC60035F -+:1000F0000017A200025E02F000C501BC601710B735 -+:10010000A101BC600B0017A200025E02F000C50155 -+:10011000BC601710D7A101BC60030017A200025EEB -+:1001200002F000C501BC60171017A101BC600B00F4 -+:1001300037A200025E02F000C501BC60230F57A188 -+:1001400000A85E930077A200025E02F000C501BC29 -+:1001500060171017A100025E02F000BF02004067A6 -+:10016000000E23006CC464E42DEA03BFDE02F00E2F -+:100170002A01BC60171277A100025E02F000BF00E6 -+:1001800068C0671FEE2A01806000E3C71E01BC60E3 -+:100190000300904301806000E3C71E01826002F209 -+:1001A00097940180E004E3C71E01BC600300071AB6 -+:1001B00003BFDE02F00E2D0002DE02F0000002019D -+:1001C000C11F000E4002855EAF000E330185600640 -+:1001D000F577AB00B0446700082500B0446B000819 -+:1001E0002600E9446504B7A100E8C46904D7A20069 -+:1001F000D05E870077A101E1DE8AF437A200E95ED4 -+:10020000862697A100E8DE8A26B7A200695E8B00E9 -+:100210000E4001BC610300113300E144DAF43136D1 -+:1002200000E144DEF4513701856002F577AB01BC93 -+:10023000600301104701BC60030050430002DE026E -+:10024000F0000000B0451F00178100B005B700178F -+:10025000A601BC600704106401BC601311106501A5 -+:10026000BC60030017A10205DEAF000E5900B058B4 -+:100270000F00178000685E842C2E6102005E9B00D8 -+:100280000E590280DA03000E4F0118581F00178222 -+:1002900000E05E0B00378201985E0AC0F60703BFDC -+:1002A000DE02F00E52011A581F00178200E05E0BAA -+:1002B000003782019A5E0AC0F60701F0DE030037BC -+:1002C0008000A05E02C0578000B05E0300160300ED -+:1002D000A044B6F0178200B05E0B00160500E05E89 -+:1002E0000AC0960603BFDE02F00E6100B05813008C -+:1002F000178200E85E06F057A5006ADE97000E5FE1 -+:1003000000E85816F4B6050069D817000E5F01BC66 -+:10031000600300160500B058170017A500E058123A -+:10032000F4B60600E0419302106400E0419706D065 -+:100330006500E05E870037A100905E9B0037A60055 -+:1003400068DE87008E4601BC600300114701BC6077 -+:100350000300016D0002DE02F0000001BC6003003A -+:10036000016C01BC600300016D01BC60070A1064F0 -+:1003700001BC60030077A100B0428F00178000A08D -+:100380005E0301F78000B05E0300016E01BC63FFF5 -+:100390001FF7A20068DE03000E7301BC60030017A4 -+:1003A000A200886006F43781002005BAF02E78009C -+:1003B00068DE8AC0CE7800E005B300216C00B0058D -+:1003C000B6F0216D00685E03000E7C00205E06F032 -+:1003D0000E82006EDE8AC0CE8203BFDE02F00E7D8A -+:1003E000006DDE8AC0CE8200B05E870017A300B029 -+:1003F000419300016600B0581B0017A201BC6003C6 -+:1004000000016C01BC600300016D00E84193021023 -+:100410006400E85E870037A10069DE87000E730084 -+:10042000B05E8F0001650002DE02F0000000B00542 -+:100430009B001064006E581B002E8B00E0581B00C0 -+:10044000314503BFDE02F00E8C00B0581B00114591 -+:1004500000B0059B00016200B0059700016100B08B -+:10046000580F00178500B0580700178300B0580BCD -+:100470000017840118581F00178C011A581F001705 -+:100480008D0002DE02F0000000B00597001780002A -+:10049000685E002C2EB701BC600300111201BC6025 -+:1004A0000300111500B0059B0010640200452300F5 -+:1004B0000EA100B0451F00178100E80592F03780BB -+:1004C000006ADE03000E9F00B05E0300114503BF0B -+:1004D000DE02F00EA201BC600300314503BFDE0264 -+:1004E000F00EA200B0059300114500B00583000195 -+:1004F0006900B0058B00016A00B0058F00016B0038 -+:10050000B0058700016800B005AB00106502845A91 -+:100510001F000EAB00B05E1700168301985E32D04C -+:10052000F687019A5E36D0F68701846002D0F6879E -+:1005300000B0059300016000B0059B00016200B0AF -+:10054000059F00016300B0059700016100B0058BB5 -+:1005500000106400B0580F00178500B0580700174E -+:100560008300B0580B0017840198581EF1978C0136 -+:100570009A581EF1B78D03BFDE02F00EB70002DEFF -+:1005800002F0000000B0058B001064006E41932A59 -+:100590000EC500A044B6F0B7A100B05E87001605F6 -+:1005A00000E05812F4360600B0581B001145020056 -+:1005B00000F3000EC2006D4193280EC20200DEAFB0 -+:1005C000000EC201BC600B02514200B05E87000108 -+:1005D0006F02015EAF000EC500B05E17001603018A -+:1005E000816002F577AB0002DE02F00000020145F7 -+:1005F00023000ED00287C493000ED001826002F562 -+:10060000D7AE02012C43000ECD00E02C4B002B1284 -+:1006100001816001620B1002055EB7000ED000E0A0 -+:100620002AF7002ABD01856002F5B7AD0002DE029F -+:10063000F00000020200BF000EDE00025E02F00FBA -+:10064000000202DEB3000ED60020428F000C4C03E5 -+:10065000BFDE02F00002028881AB000EDE02845E83 -+:10066000FF000ED402845EB3000ED40282DEFF00CF -+:100670000ED402822B4F000EDC00682ABB000EDE77 -+:100680000284DEAF000ED402835EB7000ED400B049 -+:100690005E870017A10002DE02F000000182E00286 -+:1006A000F597AC0203DEFF000EE802844523000E3E -+:1006B000E802012B4F000EE80180E006F29794005B -+:1006C000025E02F00DD90180E002F2979400025E12 -+:1006D00002F00DD90180E002F29794028400C70075 -+:1006E0000DB203BFDE02F00DB4020400C7000EF22B -+:1006F0000284C56F000EFE02844523000EEF020047 -+:100700004203000EFE00685E4B04AEFE00685E4BC6 -+:1007100006AEFE00685E4B062EFE0182E006F597EF -+:10072000AC02844523000EF50323DE02F00EF60131 -+:1007300083E006F597AC0180E006F297940284000E -+:10074000C7000DB200B02AF70017A2006DDE89566F -+:100750000DB202872B4F000DB402005EFF000DB2F8 -+:100760000287AB4F000DB403BFDE02F00DB20002F2 -+:10077000DE02F00000020200BF0012FD00682B0B39 -+:10078000000F0500E844655857A101BC63F71D1729 -+:10079000A2006D5E86F44F0500E84466F44AC2008C -+:1007A0006CC465576F0700E84467002ABB028045A8 -+:1007B0006F000F430203DEB700103D0183E002F536 -+:1007C000B7AD0202DEB3000F0D018360062B915C12 -+:1007D00000025E02F00EE002835EBB000F1000E834 -+:1007E00045895BF7A1006E5E8555AF280204DEB730 -+:1007F000000F2400E02BB7002AED01BC6003000AC3 -+:10080000EF00682C67000F1500E82C67002B19001B -+:10081000B02BB70017A201856002F5B7AD0204DE68 -+:10082000FF000F1A006D5E895DCF1A0184E002F7A8 -+:10083000F7BF0206DEFF000F2400E02BE7020AF9F3 -+:1008400000B04467000B0401182BE70017A1011A40 -+:100850002BE70017A2006E5E87000F22006DDE8975 -+:100860005F4F2203BFDE02F00F2401BC6003000AC9 -+:10087000F90186E002F7F7BF02025EFF00103D00BB -+:1008800068AB0B00103D00B02AE7000AC20002DE90 -+:1008900002F000000182E002F7F7BF02025EFF00F3 -+:1008A0000F35020600C7000F2E02802BF3000F2E1B -+:1008B00000B02B4B0017BB006E2B22F7703D0202DD -+:1008C0005EFF000F3500E845895BF7A1006DDE850E -+:1008D000614F3300E844656177A1006D5E85618FEB -+:1008E0003500B04467000AC20002DE02F0000002D8 -+:1008F00004DEB7000F3D00E8446556CABE00682C10 -+:1009000067000F3900E82C67002B1900E02BBF00AF -+:100910002AEF00B02BC30017A1006D2BBEF42F3DB2 -+:1009200001BC6003000AED0068AB1700AF4000B0E7 -+:100930004467000AF700B0446B000AFB0068AB177D -+:10094000012F4200B04467000B130002DE02F000EA -+:10095000000203DEB7000F4A0282DEB300103D0240 -+:1009600003C57300102F00E844655737A1006D5E82 -+:100970008556B03D01836006F5D7AE03BFDE02F0B9 -+:10098000103D01BC6003000ADF006D45871F4F4D1D -+:1009900000B04587000ADF00E044655BF7BB00E874 -+:1009A0005EEE2C2AB901836002F5D7AE0183E00622 -+:1009B000F5B7AD0184E002F5B7AD01826002F7F74B -+:1009C000BF01846002F5B7AD0101456F0017A101B9 -+:1009D000875E86F577AB01BC6003000B0D00025EFD -+:1009E00002F012FE00E844655737A1006D5E855E97 -+:1009F000CF58006D5E8556AF5C00E02B83002AE087 -+:100A000000B02AB30017B3028600C7000F690206C0 -+:100A100080C7000F6002075EAF000F63020680C749 -+:100A2000000F650184600561AB0D03BFDE02F00FAE -+:100A30006501826006F7F7BF00B02AE7000AC1022D -+:100A400000C56F000F6901846006F5B7AD02048030 -+:100A5000C3000F690184E00561AB0D01BC600300B8 -+:100A6000117800B045E300180000B045E7000ACC5B -+:100A700001BC600300317800B045E300180000B00D -+:100A800045E7000ACD01BC600300517800B045E3A2 -+:100A900000180000B045E7000ACE0184600006009F -+:100AA000300207AB3B000F75018460040600300084 -+:100AB000B02B330017BB012A5EEF000AC501BC60F2 -+:100AC000131C57BB021E2B33000F7C011E2B33005F -+:100AD00017A60080DE9AF777BB00B041B70017B3C6 -+:100AE000006E2B1701EF800088600558B7BB00200F -+:100AF000DEED5D4F8303BFDE02F00F8600E82B17AB -+:100B00000217BB00886006F777BB00205EED5D6FC3 -+:100B10008601846006F5B7AD020480C3000F86012C -+:100B200084E00561AB0D006E2B1701EF8D006D2B7E -+:100B300017004F8A006E2B17006F8A0068AC6700A1 -+:100B40000F910088600558B7BB0020DEED5B8F90E9 -+:100B500003BFDE02F00F9100E82B170217BB0088DD -+:100B60006006F777BB00205EED5BAF910184600506 -+:100B700061AB0D0068AB1702EF97010DAB370017A3 -+:100B8000A1010EAB370017A200685E87000F970027 -+:100B9000E05E86F457A100E05E87080AC50068ABF6 -+:100BA0001700AFA102075EFF000FA1012C2B3B0035 -+:100BB00017A3006DDE8D612FA100685E8F000FA16D -+:100BC0000280AB37000F9F0183600561AB0D03BF4F -+:100BD000DE02F00FA100B02BFB000AF800B0446B5E -+:100BE000000AFF0068AB17012FAE0281ABF3000FC4 -+:100BF000AE01BC6003000AE200682C4F000FAE009B -+:100C0000E844656277A1006D5E85628FAB00B02C11 -+:100C1000530017A200E05E8962B7A2006DDE86F481 -+:100C20004FAD0200AC43000FAE0185600561AB0D16 -+:100C300003BFDE02F00FAE0180E001620B1000681E -+:100C4000AB17010FB100B02AE7000AD90187E0060F -+:100C5000F7F7BF0207DEFF000FB30181E00561ABCC -+:100C60000D00682B17002FB700682B1701EFB70096 -+:100C7000682B17030FB70068AB17008FC0018260A5 -+:100C800006F7F7BF00B02AE7000AC10068AB1703F8 -+:100C90000FBD00B00013000AC500B02B9F000AC8AA -+:100CA00003BFDE02F00FBF0068AB17008FC0011A50 -+:100CB0002B37000AC800B02AE7000AD00202DEBBC8 -+:100CC000000FC60284DEFF000FC30206DEFF000F26 -+:100CD000C600B02BB70017A1006DDE855DCFC60141 -+:100CE00082E00561AB0D00E05ECD55B7B3018260D7 -+:100CF00002F5D7AE00B02C4B0017A100B02AF700C8 -+:100D000017A2006D5E89560FCD02855EB7000FD623 -+:100D100003BFDE02F00FCF006D5E8560EFD8028169 -+:100D20002C43000FD600B0440B0017A300B0440FB3 -+:100D30000017A200E95E8E2337A300E8DE8A23575E -+:100D4000A200695E8B000FD80068DE8B000FD80010 -+:100D50006E5E8EF66FD801826006F5D7AE00025E39 -+:100D600002F01143020600C7000FE601BC60131C2D -+:100D700057BB012C2B3B0017A20080DE8AF777BB04 -+:100D800000B041B70017A200682B17004FEE0068B3 -+:100D90002B17024FEE00682B17026FEE00682B171F -+:100DA000006FEE00682B17084FEE00682B17086FD6 -+:100DB000EE00682B17088FEE03BFDE02F00FFB0377 -+:100DC000BFDE02F00FEE02045EB7000FFB020680EA -+:100DD000C7000FE902075EAF000FFB00682ADB00C7 -+:100DE0000FF400E8446556D7A201BC60371597A3FD -+:100DF000006D5E8AF46FFB006E5E895D8FFB01847F -+:100E0000E006F5B7AD00685E8B000FF400B05E8BB6 -+:100E1000000AAE0182E006F5D7AE006E5E89610F72 -+:100E2000F40182600561AB0D00E844655737A1000D -+:100E3000B044670017A300E85E8EF42AB60068ABE2 -+:100E400017088FFA00B02BCB0017A200E82ADAF4BB -+:100E50004AB601846002F7F7BF0282DEB300103D9C -+:100E60000203C57300102F00B02ACB0017A200B0F8 -+:100E70002AD30017A3020600C70010090068AB17A9 -+:100E800000900902802BF300100900B02B230017FB -+:100E9000A1006D5E855970050180E00561AB0D0014 -+:100EA000685E8700100900682C0700100900B02C4C -+:100EB000070017A200B02C0B0017A300685E8F007C -+:100EC000100F00682B0B00100F00E844655857A165 -+:100ED00000E05E8EF457A2006D5E86F4500F018133 -+:100EE000600561AB0D0281AB4F00101402005EFF84 -+:100EF0000010140204452300101403A0DE02F010B9 -+:100F0000140183E00561AB0D028080BF00103D023B -+:100F1000825EBB00103D02822BF30010290281ACDF -+:100F2000370010290280AC3700102902812C3700CD -+:100F3000102902822C37001029028881AB00102969 -+:100F40000282AC3700102202802B37001029028366 -+:100F50002C3700102202852C3700102202842C37F7 -+:100F60000010290284AC370010290283AC3700102E -+:100F70002902835EB70010280204DEAF00102802A9 -+:100F800081DEBB0010280184E002F577AB00025E31 -+:100F900002F0112A03BFDE02F0103D0183E0022BB4 -+:100FA000915C020701AB00102C0180E00209D04ED9 -+:100FB00001BC600318517800B045E30018000180BF -+:100FC00060022F317900E844655737A1006D5E85D6 -+:100FD00055B03D028101AB001035020081AB00101D -+:100FE0003702842C370010370280AC3700103701ED -+:100FF0008360022B915C03BFDE02F0103D01836031 -+:10100000022B915C00025E02F00EEB02835EB700E1 -+:10101000103D0184E006F577AB00E02B47002AD1B4 -+:1010200003BFDE02F011120002DE02F000000184B4 -+:10103000E002F5B7AD01836002F5D7AE0182E002B0 -+:10104000F5D7AE0182E002F7F7BF0184E002F7F7BF -+:10105000BF01BC6003000ADB01BC6003000AD001D1 -+:10106000BC6003000AC801876001606B030002DEF8 -+:1010700002F00000020200BF0010740283DEFF00D5 -+:1010800010830183E006F7F7BF01BC600302115D26 -+:1010900000B02AB700115E018560060B705B018508 -+:1010A00060060BF05F0280456B001055018B6002FB -+:1010B0002B915C01BC600318517800B045E3001827 -+:1010C00000018060022F31790188600E2B515A0097 -+:1010D000682ADB00105801846006F7F7BF01BC6086 -+:1010E00003000AB600025E02F0103E00E8446960A8 -+:1010F000D7A1006EDE8700306200B02BF7000AF83F -+:1011000001BC6003000AF700682B0B00106200B0FE -+:101110004467000AC100E84465564AC200B02AD3B9 -+:101120000017A100E82B0AF42AC2028080BF001039 -+:10113000680281DEBB00106F0200456F001068027C -+:1011400083C57300106801BC63FF1FF7A10068C569 -+:1011500086F4306F018B600E2B915C01BC6003182C -+:10116000517800B045E3001800018B2B4E2F3179E8 -+:101170000183E002F5B7AD0184E002F577AB03BF70 -+:10118000DE02F0111D018360022B915C00025E0201 -+:10119000F00EEB0183E006F5B7AD0184E006F577CC -+:1011A000AB03BFDE02F0111D018D60020BF05F0189 -+:1011B00088600E2B515A028181AB00107C018B603C -+:1011C000062B915C01BC600318517800B045E30028 -+:1011D0001800018060022F317903BFDE02F0108019 -+:1011E000018B60022B915C01BC600318517800B048 -+:1011F00045E3001800018060022F31790183E0028D -+:10120000F5B7AD0184E002F577AB00025E02F010A5 -+:101210003E0002DE02F0000000B0446B000B06024C -+:1012200002DEB3001088018360062B915C00025E31 -+:1012300002F00EE0020200BF0010960183E002F708 -+:10124000F7BF0203C573001091020080BF00109128 -+:10125000018B600E2B915C01BC600318517800B0CB -+:1012600045E3001800018B2B4E2F317903BFDE02BE -+:10127000F01095018B60022B915C01BC600318514A -+:101280007800B045E3001800018060022F31790139 -+:1012900082E002F597AC0002DE02F0000001BC60C3 -+:1012A0000300701001BC63FF1FF0C501BC63FF1F8A -+:1012B000F0CB00B040470010E500B040470010EB15 -+:1012C00001BC600300901001BC63FF1FF0C601BCAD -+:1012D00063FF1FF0CC00B040470010E600B040476D -+:1012E0000010EC01BC600300B01001BC63FF1FF0F4 -+:1012F000C701BC63FF1FF0CD00B040470010E700FE -+:10130000B040470010ED01BC600300101000B04079 -+:101310004300180001BC63FF1FF0C800B040470045 -+:1013200010E801BC600300301000B040430018001A -+:1013300001BC63FF1FF0C900B040470010E901BCC9 -+:10134000600300501000B0404300180001BC63FF70 -+:101350001FF0CA00B040470010EA0002DE02F000B1 -+:101360000001BC60030037A20020E3FE0910F10079 -+:1013700020E0420D90F1028042030010F10284450A -+:10138000230010F103915E02F010F10068AB6F00D2 -+:1013900010F10282DEFF0010F102805EFF001126D4 -+:1013A000020180C700111D0282DEB30010F10204A9 -+:1013B00080C70010DE00685E8B0010CA00B02BA34F -+:1013C0000017A1006EAB8AF430CA0203C573001087 -+:1013D000DE00682ABB0010C900682ADB0010CA00C2 -+:1013E000E8446556D7A100E82ABAF437A1006ADEBE -+:1013F0008555F0DE006ADE855B50DE00682B070055 -+:1014000010DE0203DE530010CD00B02BA7000AAFA0 -+:1014100003BFDE02F0111D01BC600302579201BC44 -+:1014200063FF1FF0C301BC60030910E301865E8AFD -+:101430001C70E3018460061C70E300682B0F001031 -+:10144000D40185E0061C70E301BC600303978200B1 -+:10145000025E02F010FB01BC63FF1FF0C400B05439 -+:10146000130010E400E043915C30E400025E02F0FF -+:10147000109701BC60030010EE01BC63FF1FF0CEAB -+:1014800000E02B0F002AC303BFDE02F010EB028343 -+:101490005EB70010F100025E02F000F100B05ECF16 -+:1014A0000010E400682ABB0010E800B02AFB00101E -+:1014B000E40280456F0010E800E8446556D7A100BB -+:1014C000E82ABAF437A100695E870010E800E05E00 -+:1014D0008557D0E401BC600301D78200025E02F0B0 -+:1014E00010FB03BFDE02F010EB00B00047001086D7 -+:1014F00000025E02F0119500025E02F00CF701900E -+:10150000600A09104801846006F597AC01BC61339C -+:101510000070800002DE02F0000002805EFF00101A -+:10152000F60281DEBB0010F6020180C700111D0229 -+:101530000480C700111D01806002F7F7BF0280C25E -+:101540008F00111E0201DEBB00111E01BC600300F2 -+:1015500017A203BFDE02F010B401BC63FF1FF0C08E -+:1015600001BC63FF1FF0C10285DEFF00110B0068A4 -+:101570005E4B06310400B02B570017A1006DAB0E77 -+:10158000F4310B01BC600301378000B02B5B001706 -+:10159000A1006D2B0EF4310602812BF30011060120 -+:1015A000BC600301778001BC600300378100025EEC -+:1015B00002F000CC01D2DE0AA030E000B0540B00F3 -+:1015C00010E103BFDE02F011110280ABF300110441 -+:1015D00001BC600301578001BC6003001781000259 -+:1015E0005E02F000CC00B054070010E000885E0BF3 -+:1015F0000070E10002DE02F0000000682B13001111 -+:101600001D0204DEAF00111D00E844655897A400D8 -+:101610006E5E9155F11D00885E930037A4006D5EEB -+:101620009155F11D00025E02F0115303BFDE02F07E -+:10163000112A00E844655897A400885E930037A4F7 -+:1016400000025E02F0115303BFDE02F0112A028491 -+:10165000DEAF0011210181E002F5D7AE03BFDE024B -+:10166000F0112A00682B8700112600E044655C2AEF -+:10167000DB00682B8B00112500E044655B4ADB0032 -+:1016800002DE02F0000001806006F7F7BF00682B61 -+:101690001300112A00E844655897A400025E02F086 -+:1016A000115301846002F597AC01BC6003000AC4C9 -+:1016B00001BC6003000ADB01BC6003000AC3010433 -+:1016C000DEAF0017A101835E86F5B7AD0284DEAF01 -+:1016D000001133018060060D906C0002DE02F00004 -+:1016E00000028600C700113502025EFF00113B00B8 -+:1016F000B02AAF0017A3020400C300113800B02ABB -+:10170000CF0017A30202DEBB00113A00B02AAB00E3 -+:1017100017A300E04466F46ABB00B04467000B0BFB -+:101720000183E0022B915C020701AB00113F0180B5 -+:10173000E00209D04E01BC600318517800B045E3C7 -+:10174000001800018060022F31790002DE02F000F3 -+:10175000000202DEB3001146018360062B915C009B -+:10176000025E02F00EE00203C57300114B0284DE3C -+:10177000AF00114B0281DEBB00114B02805EFF0007 -+:10178000114B02035EB7001152018B600E2B915C6E -+:1017900001BC600318517800B045E3001800018BCC -+:1017A0002B4E2F317901836006F5B7AD0184E0023D -+:1017B000F577AB01BC6003000AC30002DE02F00053 -+:1017C0000000682B7B00115500B02B7B0017A40094 -+:1017D0006D5E9156515700B02ACB0017A400882B9C -+:1017E000270037A500E82B2AF4AACA00885E9300D8 -+:1017F00037A400E02B2AF48ACA00902B2B00AAC938 -+:1018000000B02B27000AAF0002DE02F000000286C3 -+:10181000410700115E01BC60130917A100025E02BE -+:10182000F000BF018760060337A200025E02F000ED -+:10183000C500B05E870017A100B05E870017A10049 -+:10184000B05E870017A101876002F457A200025E14 -+:1018500002F000C501BC60130957A100025E02F04E -+:1018600000BF018060060337A200025E02F000C5DF -+:1018700000E002B30020AC01806002F457A2000235 -+:101880005E02F000C501BC60270857A100025E029D -+:10189000F000BF0068C06701F17601BC600300176B -+:1018A000A200025E02F000C501BC600301F7A200C5 -+:1018B000025E02F000C50002DE02F0000003905E4E -+:1018C00002F0118A03875E02F0118A0390DE02F0B3 -+:1018D000118A020445230011810283C21F00118A6C -+:1018E0000068A0B700117E00B0446700082D00E832 -+:1018F000446505B7A1006E5E877D118503BFDE02DA -+:10190000F0118B0286C03700118A00E0446700D7CF -+:10191000A10206403700118A006CC466F4318300CE -+:10192000025E02F00B1900025E02F0115E01BC6063 -+:101930000300082D00025E02F00ADC03BFDE02F0A5 -+:10194000000201BC600300082D0002DE02F000006E -+:101950000280420300119402854523001193028501 -+:10196000DEB70011910185E006F5B7AD00E0446BEC -+:10197000002B21006CC46964319400025E02F011F6 -+:101980005E0185E002F5B7AD0002DE02F000000165 -+:101990000C81430017A101BC600300508A00685EFF -+:1019A0000700119900685E8700119900685E0700C2 -+:1019B00011A10190422AA1308A00685E070031A17E -+:1019C0000190422AA0108A0109DE030017A2018FAC -+:1019D0005E8A11508A00685E8B0011A10191E00EB1 -+:1019E00011508A0002DE02F000000109DE03001738 -+:1019F000A400E05A06F497A500905E96F497A5021D -+:101A000003DE030011A90282DE030011A901BC61FB -+:101A1000EF0857A60080DE96F4D7A50116DE8700F2 -+:101A200017A300885E870077A100E15E8702D7A137 -+:101A300000E0DE8F0017A301BC60030017A2020EB6 -+:101A40005E030011B001BC60030037A200905E96F7 -+:101A5000F457A50080DE96F437A100E141B7FFF707 -+:101A6000A600E1DE8701F7A10080DE96F477A300EF -+:101A7000E1DE860DB7A100E0DE8F0017A3017A5EDC -+:101A800086F477A100885E86F457A100B05E8700D7 -+:101A900017A20287DE030011BD00885E870057A1F0 -+:101AA00003BFDE02F011CA02875E030011C401BC4D -+:101AB000639B0CD7A50080DE86F4B7A100E141B797 -+:101AC000FFF7A500E0DE870017A100885E870057BA -+:101AD000A103BFDE02F011CA00885E870057A10192 -+:101AE000BC639B0CF7A50080DE86F4B7A101BC6245 -+:101AF000030017A500E141B6F4B7A500E0DE8700BA -+:101B000017A100E05E8400D7A10002DE02F0000011 -+:101B10000200200F0000020282DE530011D2018871 -+:101B2000600204902400E020AEF3082B00E820AA15 -+:101B3000F3082A03BFDE02F0098A01B86016049098 -+:101B40002401BC600301D02503055E02F011E4020C -+:101B500087C037000A8A0386DE02F00A8B00025E25 -+:101B600002F00EFF00025E02F01177035CDE02F06D -+:101B700011D400D8409B0117A100E05E870237987E -+:101B800000A85E630077980102DE530017A101826E -+:101B9000E002F297940188DE85006803006EA0AA37 -+:101BA000F311E400E85E6301D02501B860060490FB -+:101BB0002403BFDE02F0000201816005006803011A -+:101BC000B8600A04902403BFDE02F0000202285E1F -+:101BD000870011FA00B041930017A400E041930080 -+:101BE0007064010A5E870017A200E84192F4506316 -+:101BF00001185E870017A100E86042F437A2008850 -+:101C00005602F436000068418EF491F600E8418FE8 -+:101C100000306300E8419300306400685E8B02117D -+:101C2000EE00905602F457A300B05806F476010374 -+:101C3000BFDE02F011EE00684192F491FA00E84133 -+:101C40009300306401BC600300160003BFDE02F0A5 -+:101C500011F600B05E870017A10002DE02F000005E -+:101C60000180600286143000B050CB00106501384E -+:101C700050830017A10068DE3B06320200E05A33B1 -+:101C800000368C006EDA32F4200200B05A0B0017D6 -+:101C9000A200E001F700207D00E001D2F4407401D1 -+:101CA000BC63FF1FF7A300B050CF001064006EDAD2 -+:101CB00032F4320900B05A370017A300B0581300AD -+:101CC000178201BC600300160401BC601B09D7B673 -+:101CD0000102D0C70017A100E04196F4306500E092 -+:101CE00050CB00D06401BC60030017B401BC60039A -+:101CF00000178001BC600300378101876004031076 -+:101D0000A0009052330097A400E0418701B7B500CE -+:101D1000685ED2F0523000E05EDAF690630020D8C0 -+:101D200002F03224020250C700122A00905603002B -+:101D300097A100E85E86F497A1019E6002F437A1A6 -+:101D4000006DDE8708122A010A5E870017A201DAF9 -+:101D50006002F437A100E05ED6F4506300886006AC -+:101D6000F437A100205602F4322A00B05802F036AF -+:101D70000000E05A2B00368A006ADED2F472260098 -+:101D800068DED2F0122B00E05E0300378000685E50 -+:101D90000300322B0186E0040310A003BFDE02F033 -+:101DA000122B006ADED2F4722600E05ED30037B454 -+:101DB00000D05E0700378102985ED300121500E064 -+:101DC000419300306403BFDE02F0121500685E0329 -+:101DD00000000203BFDE02F005CA0282D0C7001273 -+:101DE0003A00B02A4F0017A101B82A4AF4368401FC -+:101DF000025013001685013C50830017A100B0501B -+:101E0000A70017A4006D5A32F432430182E006861F -+:101E100034310288502B00123F00B05A330017A112 -+:101E2000019E5E8684F427018360068634310002B9 -+:101E3000DE02F0000000B050730017A101B8506E30 -+:101E4000F436840106D00700168500B050AB0017A9 -+:101E5000A400D06006C0978000E0419700D7B5018C -+:101E60000A58130017A100E05ED6F437B500B05849 -+:101E70000F001063011656030017810068D8130085 -+:101E80001258011400630017A10068DE8700124E8B -+:101E90000088013B01168003BFDE02F01253006888 -+:101EA000DE8700725100A0013BE0168003BFDE0216 -+:101EB000F0125300E05E8709706200885403011637 -+:101EC0008000E85A0330168001BC600300168101CF -+:101ED000BC600300168201BC600300168303BFDEF2 -+:101EE00002F0125D00E0418EC09063006EC18EC0B2 -+:101EF000325D00E8418EC0306300E858030037A12E -+:101F000000E0418EF43063013850A30017A500684B -+:101F1000581303F2780068418EC05278006DDA0AD7 -+:101F2000F4B278011656030017A10068DE86F0327D -+:101F300078015856030017A100E05E870DD7A20074 -+:101F4000B05ED70010620020DE02A0126F00E05EDB -+:101F500086D037A300E05E8ED077A3006D5A02F4DE -+:101F60005278006E5E8EF4927800E86002F4368358 -+:101F700000B05E8F00168100A05A0F00768300E04B -+:101F80005A0B00368200E85A02F4568000D05E03F5 -+:101F900000378000E0581300360400E0418F003025 -+:101FA000630298581300127500E05ED70037B50041 -+:101FB0006EC18EC0325E00B0580300106303BFDEF6 -+:101FC00002F0125E00B058130017A10068DA370063 -+:101FD000127B00B05E8700168D006DDE86D1B27D6B -+:101FE00000B05E8700168D0002DE02F0000001BC2A -+:101FF00060030017A1018760040310A001BC600307 -+:102000000990B500B0006300F0B401BC60570490C3 -+:10201000B601BC60030090B500B0006300B0B4002E -+:10202000B042D30018000317DE02F012860397DED9 -+:1020300002F0128700B02A4B00142F018EE00C032F -+:1020400010A0006DDE02D1B28D00E85A36F0168D78 -+:1020500003BFDE02F0128F01BC600300168C01BCCE -+:10206000600300168D006E5A3AF0129201BC6003B4 -+:1020700000168E03BFDE02F0129300E85A3AF01603 -+:102080008E00B058070017A100E0580EF0160300AC -+:102090006ED80EF4329900E85E86C017A100E858A9 -+:1020A0000EF4360300E8580F00360301185E0300F3 -+:1020B00017A1006DDE030212A100E86042F437A20E -+:1020C00000905A1AF4368600885A1EF457A20090DF -+:1020D0005A1EF4368700B05A1AF4568603BFDE0241 -+:1020E000F012A300905A1EF4368601BC600300165D -+:1020F000870002DE02F000000158600300102A0190 -+:10210000B8600A04902401BC60030290040189E0D5 -+:10211000020D906C0002DE02F000000200DE5300AF -+:1021200012CE01BC601309B7A100025E02F000BF2D -+:1021300001A560020337A20199E002F457A2000250 -+:102140005E02F000C501BC60130997A100025E02A7 -+:10215000F000BF01A4607E0337A20199E03EF4576E -+:10216000A200025E02F000C501BC601316F7A100D8 -+:10217000025E02F000BF01B460020337A200025EFB -+:1021800002F000C501BC60131637A100025E02F028 -+:1021900000BF0186E0020337A201856002F457A266 -+:1021A00000025E02F000C501BC60131617A1000218 -+:1021B0005E02F000BF0181E0060337A20185E00660 -+:1021C000F457A201836006F457A200025E02F000F9 -+:1021D000C501BC60131F57A100025E02F000BF01E1 -+:1021E00081E0020337A2028600C70012C80181E025 -+:1021F000060337A200025E02F000C501BC60131F97 -+:1022000037A100025E02F000BF0181E0060337A2A1 -+:1022100000025E02F000C50002DE02F0000001BC18 -+:1022200060130997A100025E02F000BF01A46002E2 -+:102230000337A20199E002F457A201886002F45723 -+:10224000A200025E02F000C501BC60131617A100D7 -+:10225000025E02F000BF0181E0020337A20185E0C7 -+:1022600002F457A201836002F457A200025E02F05A -+:1022700000C5020600C70012DF01BC60131F37A1B2 -+:1022800000025E02F000BF0181E0020337A20002FB -+:102290005E02F000C50002DE02F000000200DE5324 -+:1022A0000012CE01BC601309B7A100025E02F0006B -+:1022B000BF018760020337A20181E002F457A20147 -+:1022C000886006F457A200025E02F000C501BC60FF -+:1022D000130997A100025E02F000BF020400C700CC -+:1022E00012EC0188600E0337A203BFDE02F012EE8B -+:1022F000018660060337A20181E006F457A20002BE -+:102300005E02F000C503BFDE02F012C30068DE9378 -+:102310000012F400E05E030057A201095E8B001773 -+:10232000A103BFDE02F012FC0068DE930032F80168 -+:10233000105E030017A200E05E8B0097A103BFDED2 -+:1023400002F012FC01305E030017A200E05E8B0178 -+:1023500097A1006D5E870592FC01BC60030597A103 -+:102360000002DE02F000000200456F001308028741 -+:102370002C0F00130801BC60130217A100025E02BB -+:10238000F000BF0200C0670013080287AC0F001303 -+:102390000501084067000B030187E005606B03013E -+:1023A0008860060337A200025E02F000C501876064 -+:1023B00005606B030002DE02F0000000682BEB00FA -+:1023C000130E00B02C130017A100E05E8560B7A1CA -+:1023D000006BDE8623330E0186E006F7F7BF0002AE -+:1023E000DE02F0000000B05E8F00106400B05E8777 -+:1023F0000017A300B05E8B00106500B05A030017F1 -+:10240000A10068419300131700025E02F000BF00B4 -+:10241000B0406700160100E0419300506400B05ADC -+:10242000070017A200025E02F000C500E04197001D -+:10243000506500E85E8F0037A30068DE8F0013123E -+:102440000002DE02F0000000B05E8F00106400B0F9 -+:102450005E870017A300B05E8B00106500B05A03C2 -+:102460000017800068419300132500025E02F00D02 -+:10247000A900B05E0700160100E04193005064001F -+:10248000B05A0700178100025E02F00DAE00E04175 -+:102490009700506500E85E8F0037A30068DE8F006C -+:1024A00013200002DE02F00000020200BF0001ABB8 -+:1024B0000203C5730001D400000000000000676241 -+:1024C0004B17055AC31A14E12850005B234B2524EF -+:1024D0000A00B55A5C55D8F4A179397DBF0701BD12 -+:1024E000320801002A756E6B6E6F776E2A2F736447 -+:1024F000696F2D672D706F6F6C2D69647375702D0A -+:102500006964617574682D617073746120566572B9 -+:1025100073696F6E3A20352E39302E3139352E32AF -+:1025200036204352433A20653862343964393820C2 -+:10253000446174653A204D6F6E20323031322D3057 -+:10254000382D31332031393A31323A323020435349 -+:03255000546D00C7 -+:00000001FF -diff --git a/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex b/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex -new file mode 100644 -index 0000000..a8e3092 ---- /dev/null -+++ b/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex -@@ -0,0 +1,13727 @@ -+:100000000000000091EC000055EB000055EB0000F3 -+:1000100055EB000055EB000055EB000055EB0000E0 -+:1000200055EB000055EB000055EB000055EB0000D0 -+:1000300055EB000055EB000055EB000055EB0000C0 -+:1000400055EB000055EB000055EB000055EB0000B0 -+:1000500055EB000055EB000055EB000055EB0000A0 -+:1000600055EB000055EB000055EB000055EB000090 -+:1000700055EB000055EB000055EB000055EB000080 -+:100080000048004791EC0000000000000000000064 -+:100090000000000000000000000000000000000060 -+:1000A0000000000000000000000000000000000050 -+:1000B0000000000000000000000000000000000040 -+:1000C0000000000000000000000000000000000030 -+:1000D0000000000000000000000000000000000020 -+:1000E0000000000000000000000000000000000010 -+:1000F0000000000000000000000000000000000000 -+:10010000D11E8000B5228000BD248000491F8000E0 -+:10011000F9218000A9160100F1208000D120800083 -+:10012000594880006948800015648000E1628000C1 -+:10013000296280003D6580008D628000C56280007C -+:10014000596380005D6580007D6380009D63800051 -+:100150000D668000A961800061618000756080008B -+:1001600095608000DD6380009D65800029668000C9 -+:10017000FD618000B96580001D618000F16580002F -+:100180009D6680006D658000916C8000CD6B800065 -+:10019000316C80008D6B8000556C8000AD6A8000F2 -+:1001A000C16A8000D56A8000496B80001D6A8000AA -+:1001B000FD6A8000AD688000C1698000D168800060 -+:1001C000356B8000B16980004DF10000D166800080 -+:1001D000E16780008D678000CD6780009D688000AA -+:1001E000ED678000BD678000A1678000ED6680003C -+:1001F00009678000616780004D4880001D488000CD -+:1002000085988000DD96800051948000B19B80002D -+:100210003994800005988000199880002D988000FE -+:10022000C59B8000D19A8000899D8000D193800079 -+:10023000D9918000ED9A80002129000099170100D2 -+:1002400079290000C1170100519B8000BD290000E1 -+:1002500049A9800099988000F529000031A8800004 -+:1002600005A7800021A28000BD938000DD9380005F -+:10027000199E80007D93800045988000E59B80005A -+:100280006DA68000C19C8000C59F8000A19D80005C -+:10029000F5988000851701005517010029AA8000F4 -+:1002A000B9A9800075AA8000E1A9800039AA800060 -+:1002B0008DAA80005DAA80000DAA8000C5A98000DB -+:1002C0009DA98000A90C8000850D8000C1068000DA -+:1002D00029088000694680004D468000D94480008E -+:1002E0004146800021448000F54380001544800091 -+:1002F000E1438000E1428000854680007544800033 -+:100300002D448000A9428000F9428000CD43800046 -+:10031000B9458000F544800039458000090080001F -+:100320003D00800049018000D10480000D04800060 -+:10033000910380004D038000E503800035038000B9 -+:100340006503800029028000CD02800051028000F8 -+:1003500085028000F5028000950680003906800045 -+:100360008105800005068000FD048000690F800083 -+:100370002516800015168000451380001513800097 -+:100380002513800009138000351380000D1E8000A6 -+:10039000F91D8000291D80001D1C8000391C800073 -+:1003A0003116800059138000192C0200951380002B -+:1003B000B91C8000C5270000452D0200751D800076 -+:1003C000A90F01003D1D80000D1B8000E910800079 -+:1003D000790F8000A9168000311480002D11800053 -+:1003E000A51E8000B11E8000BD1E8000692B80000C -+:1003F000AD28800011298000892B8000FD2B800012 -+:10040000E128800065288000B52C8000912C8000B8 -+:100410001D2B8000752D8000252C80004D30800024 -+:10042000DD2D800059278000313180002118010026 -+:100430008D268000C5268000E5248000FD268000F2 -+:1004400021258000B12A80006525800025288000B4 -+:100450006129800041298000D92980009D298000E0 -+:1004600081298000893080004D2E8000B12B8000D2 -+:10047000312C8000E12C8000613280002D32800020 -+:10048000C93380004D368000693A8000B535800060 -+:10049000F9348000A93480003D3380009D33800012 -+:1004A000013480003536800031388000353A8000D4 -+:1004B000213A8000AD3280000D338000DD328000B3 -+:1004C000953A8000D937800099368000193780002E -+:1004D000593880004938800019398000313D80004A -+:1004E000D53A8000C93C8000E13B8000513D80004E -+:1004F000D93D8000AD3E8000593F80009941800089 -+:1005000041478000CD5B8000895380002D4D8000E5 -+:10051000A94C8000E14D8000E94F8000B14F800080 -+:10052000C94E80008D4E8000F15180005D528000E8 -+:10053000D15180002D52800001528000C94F8000AF -+:10054000594C80006D4C8000455B8000395680001E -+:10055000155A8000C9588000315A800081578000A8 -+:10056000F95980001D568000AD55800091558000DE -+:100570004D5A80002D558000714B800071548000D1 -+:1005800009548000F54D80001D4C8000F94B80001F -+:10059000094C8000114E800015588000C9110100DF -+:1005A0002D508000E5588000555680007D5A80000F -+:1005B000054F8000354E8000D9558000515880008D -+:1005C0009D57800059518000614D8000B1488000E6 -+:1005D0005D5B800081528000494C80003515010030 -+:1005E000F15B8000E55C8000E15F8000A55E80003B -+:1005F0007D5E80008D5C8000015C8000A15F8000DA -+:10060000895D800005608000395D8000D15E8000DA -+:10061000495E8000ED6C8000656D8000DD6D8000BE -+:100620000D6D8000296D8000896D8000F96C80005F -+:10063000D96C80003D6E8000616F8000756E800017 -+:10064000056E8000A974800055758000D574800007 -+:1006500005748000D17C8000457D8000757C800021 -+:10066000117E8000897E8000E97E8000917D80007F -+:100670003D7E8000517F8000A581800065848000E0 -+:10068000418480008D8380006583800035858000F3 -+:10069000E58480009D848000218580007584800031 -+:1006A000BD8380005D858000BD858000158F800042 -+:1006B000918D8000D58980001986800019AB80005B -+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E -+:1006D000FDB080007DB1800065B080006DAE80000F -+:1006E00085AE8000EDAD800041AF80001DAE800082 -+:1006F00031B180003DB18000B9AE8000F5B180001D -+:1007000079B08000FDAD800009B180008DB080001F -+:1007100049B1800069B180004DAE80003DAE8000DF -+:1007200095AE800029B38000C9AE8000CDAF8000B7 -+:10073000E5AF800025B080008DAF8000B5B28000AD -+:10074000FDB2800019B38000EDB080005DAE800086 -+:100750002DAE800029B28000A9B08000A1B1800038 -+:1007600005B2800039B28000A9AE80007DAF800064 -+:10077000ADB38000A9BD80009DC1800025C7800069 -+:10078000DDC8800065CA8000E1CB8000DDCE80003E -+:1007900019CE800099CE800015CF8000E52C000096 -+:1007A0000DD88000DDD7800091D78000B110010006 -+:1007B000CD2B000069D880007DCF800045D9800016 -+:1007C000FD10010099D1800025110100F9E08000A1 -+:1007D00071F58000152D0000D1DE80008D21010013 -+:1007E00009EA8000A1E4800045200100E1EC8000DE -+:1007F00011E3800039EA800039E3800099E380004A -+:1008000029DF800005220100A120010075220100DE -+:10081000352301007D230100BDEB8000952D0000F4 -+:10082000152E00001922010091220100CD210100A6 -+:10083000E1E18000A9E980007D210100F9200100AB -+:10084000EDF58000D90081009DF68000C5F780009D -+:1008500085FF800045018100D50281004D038100A4 -+:10086000E50081007DF6800081F78000D5F58000ED -+:1008700051F9800031FB8000F1F68000F9F580002D -+:1008800041FF8000D9F98000DDFC8000A9F78000DD -+:10089000C12E000059FB80008DF78000A5F9800073 -+:1008A0008DF9800029F68000A1F880005DF78000B6 -+:1008B00065F6800095FD8000912F0000F502810013 -+:1008C0002D0281008901810005018100A93000000D -+:1008D00099FF800019F7800089F68000C1F680003A -+:1008E0008D10010085F5800005F78000DDF68000A1 -+:1008F000B1F68000AD6A8100BD6A8100DD2F810004 -+:10090000E1578100F56D8200A98D820009258200E2 -+:10091000196E820001AA81005D608200A537820005 -+:10092000ED69810079598200E55882001D598200E5 -+:10093000FD6D8100493A810041BC8200E95A820084 -+:10094000CD608100D59681001D6181002961810003 -+:1009500089BF81001DAB810069320000893200002F -+:10096000D132000005A6810021AD82002958810006 -+:10097000BD3E8100A540810035958100599B8100D5 -+:100980003D3682001D4582000928810099A0810022 -+:10099000D1288100E93B81008D288100416E8200D1 -+:1009A000859B8100295D81006D398200FD398200BF -+:1009B000253A820095698100C97A810091578100AA -+:1009C0005D57810075308200852F82003557810088 -+:1009D000D12F82002157810049578100F5288100DD -+:1009E00095A882002DA2820089D38100D56B810059 -+:1009F0005959810075598100F55A820005AD810071 -+:100A0000F1D2810039378100ED718100C5968100F6 -+:100A10008957820091618200CD618200A9588100CE -+:100A20001D2782004543820001448200156A81002F -+:100A3000614A8100ED4E810071228200055A8100D9 -+:100A40004D8A81007549810071248200B14981007D -+:100A5000B144810075AC8200292B8200595281007B -+:100A6000E12A8200B529820071A7810035A78100A3 -+:100A700001D48100F5BE810055B48100D16A8200A5 -+:100A8000D19C81009D9C8100959B8100B59D81003A -+:100A9000459D8100C59D81006170820009358100FE -+:100AA000A1AB82008DAB820075AB8200F193810017 -+:100AB0009968810015D7810071C182007D2B81006A -+:100AC000E92F81000DB6810025BD82008D4F810088 -+:100AD0000D5081008543820031D78100B1BD820075 -+:100AE00095C182005DB38200B90D01008DD18100F6 -+:100AF000A9368100E9BC820029378100E9368100EE -+:100B0000A1D68100A53B81006DAB810041B0810081 -+:100B100045AE8100DDB1810041BD820095BE8200FD -+:100B2000CD2E82009D6B8100CD458200453981002C -+:100B3000353B8100BD3A8100F1D58100419F8100A4 -+:100B4000119F810071A48200ADD58100C130810068 -+:100B5000A13982004D618100995B8100A5728100FD -+:100B600089DA810061BF81006157820081218200A2 -+:100B7000A9218200D1AD820009BC8200B5A181000B -+:100B80009DCA8100B92F8200D9BB8200113082003A -+:100B90007DAD8200CDA4810099A48100CDAB8200FF -+:100BA00015AB8200C1AA8200B998810081A581009D -+:100BB000D9D08100A9CF8100E93B8200EDCF81002F -+:100BC00065D1810079D1810051D0810065D081004B -+:100BD000E521820011228200D1340000B9480000D2 -+:100BE000FD9C81009145820055AE820041B4810098 -+:100BF00095BD8100F18A8200098B820079D981003C -+:100C00007D618200CDA4820041918100A13F8200DC -+:100C10003594820049948200898982005DC18200F6 -+:100C2000F1C18200D13B8200D5958200E560810050 -+:100C300009208200E5170100BD3B820075A18200FA -+:100C400025A58200253B8200E93A8200753A8200A0 -+:100C5000F1308200B130820071D781004599820065 -+:100C600091D7810089948200DDC18200A96A820047 -+:100C7000256B8200C944810029458100596B8100A0 -+:100C800059498100EDAA810069618200AD2482008A -+:100C900005368100D535810079D08100A5D081004D -+:100CA000715C8100E1AD8100EDD0810049C9810016 -+:100CB0004DD88100893D82004920820065968200DE -+:100CC000F925820089CF8100856A82001593820010 -+:100CD0002D5D8200E9CA81006D4082006130820092 -+:100CE00015488200313C810061D68100114E81009F -+:100CF0000129810041A1810015A681000999820086 -+:100D0000E5C98100B1D7810035C08200294A810040 -+:100D100041AD8100EDBE82002DBE820005BE820085 -+:100D200079BE820055328100A5958100B1598100BC -+:100D3000E54781009152810015638100956481002F -+:100D40008D668100592C8100392C8100212E810073 -+:100D500065358200D5578200352B8200996082006C -+:100D6000016182001D4082001D2082001DD881008B -+:100D7000A9AC8200F1AB8200F52B820041AE82006B -+:100D800011120100356A810009AE8200696D82008E -+:100D9000098C8100D58B8100116F810081908100C9 -+:100DA000296C8200DDA18100E92B8100552F820092 -+:100DB000398C8100A55A8200355C820045BB8200D7 -+:100DC00091BE81002D6E8100115C8200258A810018 -+:100DD0004D93810089388200D5378200555A8100B1 -+:100DE000013882008D038100E9208200E13E82000B -+:100DF000914581002D6D81000D58820021478200B0 -+:100E0000FDCE810011CA81005936820051CB81008C -+:100E100025CB8100912E81002D2F8100B93A8200CF -+:100E2000A10D0100DDA9810031D48100D1B3820080 -+:100E3000ADA98100D53882008DD88100555E820031 -+:100E4000719A81001541820035DA810019258200EE -+:100E50006926820035358100D90D01003D71810080 -+:100E6000012D810009A282000D238200FD71810005 -+:100E7000D960820051728100416182004528810061 -+:100E8000C12382008D6C81006D2382009547810013 -+:100E9000B9D98100B534810075C98100F134810070 -+:100EA0002DBF810059AF8200D93C8100494F81009C -+:100EB000E5AB8100F51501007931810005958200CF -+:100EC0006D638200DD938200A56682000DC88100FB -+:100ED000095E81007D758100156281009159810054 -+:100EE000D575810011498100C1488100B9BF8100D9 -+:100EF000A5458200F5598200F1A9820041A6820031 -+:100F000039588200BD428200BDA782004D22820076 -+:100F100071A78200A5A78200E15C8100ED418200FB -+:100F2000D1A78200D1688100B5CC810015AF8200C5 -+:100F300095418100E1C8810089AA8100E99681007C -+:100F40007D2F810081470000494282005944820080 -+:100F5000F90D010031318200614982004D49820062 -+:100F60000DA58100095E8200253E8200CDCD810065 -+:100F700029B382002151810045B18200A91D820060 -+:100F800079BC8200D1568100599D8100999D8100D4 -+:100F9000191C8200513F82001D308100C9BD8100B3 -+:100FA00015388100794A8100DD9B8100199E8100FE -+:100FB00069618100896E8100B5708100D132820043 -+:100FC000F1578100A93382009D5A81003D3582008E -+:100FD00089338200D96E810045708100FD618100F6 -+:100FE000594B81000D9C8100558B8200F18E82004F -+:100FF000E59A8100BD35820049368100291F8200B3 -+:10100000655C820009150100516F8100299B8100F8 -+:10101000A56D8100B5A28200E1AF8200A9568200D1 -+:10102000894481003D578200E16F8200016F820098 -+:10103000DD728200E53E810095518100FDD4810082 -+:10104000F5BC810081B48100F199810019318100E2 -+:10105000358A8200DDDA8100413D81002D3E81002C -+:10106000E9898200C1D48100FD8D820099B681009A -+:10107000BDA781003D9F82005D0381006D928200CB -+:10108000218B8200599A8100ED278100ED94820026 -+:10109000FD8A81009D8A8100416B8100E16F8100A2 -+:1010A0005D468200A19482009D898200C9928200DF -+:1010B00079998100B1908200219182001D348100D4 -+:1010C00099B28200DD6A82008DC9810059278200B1 -+:1010D00021120100D9908100A56B82006D3C820035 -+:1010E000E56D820005C28200C96A8100ED4582007B -+:1010F000816B8100353F8200FD90820071BC8100D0 -+:10110000F16B81003D4E8200514A82003DA2810078 -+:10111000190E010079738200B97E8200698882000D -+:10112000695A8200DD2E810015138200117381003F -+:10113000698082009D9181005D8B8100816C8200BD -+:101140008D8F81004D8F810009888100BD6D8200E7 -+:10115000018E81001D5E820091718100C127810096 -+:10116000797582002DBE81002D5B8200E9A5820089 -+:10117000B5728200255B0000217D82004D808200D7 -+:101180008D7F820001A08100ED7F82002D418100D2 -+:10119000F98481006185820045728200F9548100E2 -+:1011A000692B820069518100C5558100315681004B -+:1011B000A1A6810071508100392A8200615381000B -+:1011C000C573810035620000F1978100A99B810001 -+:1011D000FD3B820025A08200DD398100715D810028 -+:1011E000BD1401004995810009CC810021A3820032 -+:1011F00045AA8100AD818200916782002962820048 -+:101200007D708200E12F8200E97D000081DB81009A -+:10121000952482006989820089C38200C5C4820046 -+:1012200039180100B1EB820009CB82000DCC82009D -+:1012300059EB820061E9820015F18200E9CD82005C -+:1012400045DF820009F182008DF782008DCA82009D -+:1012500089F38200D5CA8200A1098300C9F7820000 -+:10126000FDEF820099F8820025F9820039FA8200A8 -+:1012700089ED8200ADE08200ADE5820065DA820092 -+:101280007DC582002DE6820065EE820031E4820099 -+:10129000E5F182009DC8820055F3820075150100BA -+:1012A00061C78200CDE182006DE18200A5E282008B -+:1012B00059DF820029F4820009C7820055EF8200BD -+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D -+:1012D0004DE5820005E08200A5F982000DC582007F -+:1012E00089F48200ADA1000085A2000091E6820091 -+:1012F000BDCC8200FDE982008DD182002DF18200FB -+:101300002DF7820095FB820069CE8200A1F0820059 -+:10131000D5F08200F5CC820035A3000081D982008F -+:1013200045C58200FDCB820025CB8200BDEB82004B -+:101330001DDB820015CD820019E78200CDE6820018 -+:101340004DCF82009DCB8200450C8300E50D8300CC -+:10135000590E8300410E8300010B83004D0A830068 -+:10136000D10D8300310C8300590C8300710A830076 -+:10137000650E8300F10D8300410B8300A11E8300E5 -+:10138000B11E8300012B8300F54E8300112B8300D7 -+:10139000B127830099238300014A8300ED4983002C -+:1013A000FD478300CD4C8300BD4C8300714C83000E -+:1013B000D52783004D25830095258300E14C8300CC -+:1013C000414C83000912010065118300E144830050 -+:1013D00021288300BD2883007929830065288300A4 -+:1013E000652B830041458300D5298300491D830077 -+:1013F000A12A83005D30830051488300E5488300C3 -+:1014000029488300F5238300114A8300793483003F -+:1014100091188300A5338300ED3483001D118300F0 -+:101420009D4E8300954D8300B51A8300614783006C -+:101430001D4D8300ED1083000D458300C11E830008 -+:1014400001208300E9218300F1258300F91D830039 -+:10145000F513010059B3000049108300C10F830048 -+:1014600021248300A5248300B94A8300B52F83007B -+:10147000C1458300FD1C8300711D8300F5188300A6 -+:1014800059198300F1198300190F0100492A8300BB -+:1014900011B40000B957830029578300654F8300BA -+:1014A00001608300E559830039518300F54F8300C3 -+:1014B000555483001D5E83002152830065598300CB -+:1014C00079508300714F8300095983003D63830085 -+:1014D000C5578300815C8300B15B8300DD538300CB -+:1014E000115383009D4F830029508300254F8300B3 -+:1014F000D5588300CD62830039608300F95C830096 -+:101500004D6183005D5F83002D548300DD508300B7 -+:1015100039578300A555830091638300A16283003E -+:10152000C15D83002D5E8300455F8300A151830070 -+:101530004D5E8300195B83006D5A8300A9568300BA -+:10154000A5508300095783000D748300DD63830079 -+:10155000297A830001668300B9B28300D5A783008E -+:101560007D848300819383005DB38300A193830016 -+:10157000E9938300E10E010071BA0000B1BA0000E6 -+:10158000717A83005D67830051668300CD708300AC -+:1015900055718300DD7483008DAA830051A88300F8 -+:1015A000A9B183009D918300D184830039BB0000E1 -+:1015B00061848300AD77830081818300158283007D -+:1015C000B1808300E5B583006D7E8300B57983002B -+:1015D0002DBC0000916E8300758F830055878300BA -+:1015E0002913010015C1000025678300C18883000D -+:1015F000D98F8300F5AC8300E97783009D6D83006C -+:10160000A1A78300FD998300C9A4830051C40000F1 -+:10161000558B8300E58A8300CD6A8300F5868300BD -+:10162000596A8300B9AA83001566830051B283000A -+:101630009DB38300D9B6830059B1830091828300A2 -+:10164000D5B0830081868300C97A83000585830035 -+:10165000797C83008965830055A58300C9AF830029 -+:101660008D1501007999830091898300C5B58300A8 -+:101670000DB8830099D483002DC083009DC28300E0 -+:10168000ADC38300A1C68300B1C68300C5C2830079 -+:10169000A9D0830055BF8300F9CF830029BF830001 -+:1016A000C5E18300C1C0830095C083004DD883008D -+:1016B0000DD7830015D88300F1D7830079BD83004F -+:1016C000A1E1830035C28300C5E08300DDE0830033 -+:1016D000C5DC830099DA830001DA83004DB883000A -+:1016E00075C0830019C28300F9C983003DD6830009 -+:1016F00015BE8300C9D683005DBA830029D6830056 -+:1017000031B9830035BC83009DD883005DDC830044 -+:1017100029C18300A9C28300E5C0830025DB8300C3 -+:1017200075C283001DD083005DBC830061C6830049 -+:10173000D5C2830005BC830001C98300B5C88300FE -+:10174000EDC8830055D6830015D98300A5D1830049 -+:10175000F1D5830001D9830081B8830089E083003B -+:10176000E1BC8300A5DB8300EDE1830071C1830050 -+:10177000E9B783006DC783008DC183001DC8830056 -+:10178000B5D1830071DC8300E1C18300A9C183006E -+:1017900019DC830039D883004DCB8300A5B78300C3 -+:1017A00069CB83008DC98300C9D48300A5C500001F -+:1017B00099D68300E5DC83004DD483001DC38300EC -+:1017C00021DD830045D983007DD383003DD2830092 -+:1017D00041DA8300CDD88300D9BF830095BD830053 -+:1017E000EDBD830051C083002DB8830049BB830049 -+:1017F00031BB8300CDDA8300D5D0830049CA830092 -+:101800009DD5830081BF8300D5CF83003DC9830070 -+:10181000DDD18300B9D7830025C78300D1C800007C -+:101820005DBE830021E18300F9E0830071B983008C -+:101830008DE1830025D9830049D78300DDDB830058 -+:10184000A9B9830085BA83000917010059EB830009 -+:10185000C5E7830041E2830025E283006DF5830044 -+:1018600065EB830085F2830089F78300B1F2830082 -+:10187000A9F58300AD008400E100840019FD830018 -+:1018800035EE8300FDF38300D1D1000089FB830096 -+:10189000B9FA830021F98300F1FA8300D9F88300B3 -+:1018A000D9F9830031008400C5FE830049E7830035 -+:1018B000050084004DFF83006DF3830059FE830013 -+:1018C00001FE830025EB83000DEB830031018400D2 -+:1018D00035FD830081EB830059FD830011F88300FF -+:1018E000FDF78300C5ED8300ADED8300A101840009 -+:1018F000E9E78300B1F38300DDF2830025F3830081 -+:10190000F9E68300E5E28300F9120100A5E983000E -+:101910008DF5830051EE830079F8830071E2830036 -+:10192000F1E8830045E6830099F783006DEE8300BC -+:1019300041F48300B9EB830075E78300B1E88300CD -+:10194000BDD3000061F183000518010089EE83001A -+:10195000F5D40000FDE58300A9FD83000D1301000F -+:10196000B5FB8300F1F183002D108400E1158400A4 -+:10197000B1198400C5158400D90F8400CD218400DD -+:10198000491E84004D1F8400E1128400ED0884008C -+:10199000F10184002D0F8400ED238400F51E8400E6 -+:1019A000E520840049208400AD128400F11A8400EF -+:1019B000711F8400C9198400AD188400450B840090 -+:1019C000910B84000D2484008D2384000D18840065 -+:1019D000210684008D168400310384006909840087 -+:1019E000FD158400E902840001028400A909840035 -+:1019F0008D148400811E8400E10B8400751C84001A -+:101A0000AD0A840049108400712084000121840003 -+:101A1000850A8400291D840045078400390C840050 -+:101A200029198400551E840089038400E51D840063 -+:101A30002125840049138400291A8400DD12010045 -+:101A4000ED12840045068400010D84008943840062 -+:101A50006D2A8400014D84001528840069288400C3 -+:101A6000DD0B010009408400112C8400F92784005B -+:101A7000912D8400794C84008934840019338400CA -+:101A80006D2F8400C92D8400F12E84007D2E8400EA -+:101A900065258400DD348400FD2584001929840037 -+:101AA000B5408400D944840079298400B92B84008E -+:101AB0003D45840095328400B9288400D1388400E3 -+:101AC00031488400A93084006D2C8400994384003F -+:101AD000D13284006D338400FD2F84005D45840085 -+:101AE00011348400B54A840075488400C5488400D8 -+:101AF000B1278400314A8400D949840059328400D6 -+:101B0000014C840039388400314D840055448400F0 -+:101B1000D93D840055438400513C840091398400B0 -+:101B20009536840091378400F5368400E1478400BF -+:101B300015478400CD4C8400F52B84002546840095 -+:101B4000E53A8400C937840049428400292A840088 -+:101B5000A53F840059268400952A8400452B8400E3 -+:101B6000C95D8400C1230100A156840095568400FC -+:101B700019578400E956840005578400355F8400B6 -+:101B80001D628400B557840065638400ED628400A3 -+:101B900021638400BD628400194E8400B95384001F -+:101BA000B15D8400B5518400D55F8400F95584008F -+:101BB0006560840059538400E5538400E94D840036 -+:101BC00049240100E15F8400212501005125010025 -+:101BD000B55B840031568400A5638400CD60840029 -+:101BE00091638400ED5084002D5E840031518400A7 -+:101BF000155C840061548400F55E8400F15D84000E -+:101C0000352401007152840059588400815C84009D -+:101C1000715784002557840071588400AD568400A4 -+:101C2000415984006D4F840029508400E1548400A0 -+:101C3000BD6184006D61840005598400A56684003F -+:101C4000D9678400456684000D658400916784002F -+:101C5000B96384005D67840079678400F966840055 -+:101C60002165840021678400C56684008D66840038 -+:101C70006566840011688400516C8400AD6E840038 -+:101C8000016E8400F97084004D7F84007D6C8400B7 -+:101C90002D748400456A84000D7B840001120100CC -+:101CA000156E8400457A8400E56C8400456F8400DD -+:101CB000C17C8400297E8400756D8400956B84004E -+:101CC000B56D84007D7D84005D6B8400D56A8400E1 -+:101CD000816A840085748400B1808400857E8400DC -+:101CE000CD7F84004981840069818400ED8984006E -+:101CF0006D8A8400FD8984008D8984009D8984001B -+:101D0000E9858400F982840025858400518A840055 -+:101D100075858400958484008181840071838400AA -+:101D2000C18984005D898400D58984006D8984001F -+:101D30007D8984000D8A840009868400798C840062 -+:101D40007D8A84000D8B8400499484008D928400E8 -+:101D5000E98D84009D8B8400FD8C84007990840043 -+:101D60000D8C8400458C8400E9A68400A5AD840018 -+:101D700029968400C598840015C1840009A98400AF -+:101D800099C2840045B7840031C18400D1B8840071 -+:101D90008D998400B99A840025AC8400D9BF840051 -+:101DA000C9BE8400A196840025B18400519B8400A3 -+:101DB000919884004D9784001D9784007DA684002F -+:101DC000D1B784002DAB84008595840019B08400C0 -+:101DD000F5AD840029A98400C1A98400219F840055 -+:101DE00025A28400B1AE8400C1AF8400D5A38400D5 -+:101DF00075B7840041A28400E1BC84006DA8840012 -+:101E0000BD9D840095B884005D95840075BE8400F6 -+:101E100051B98400A9958400C5C18400599A8400F1 -+:101E2000419684003DB884009DA88400E5A8840004 -+:101E3000A59B8400F5A684003DAF8400159A84001C -+:101E4000F9988400EDA984006DB18400FDF0840050 -+:101E500025DF840025ED8400E5D08400CDF18400E9 -+:101E600009F2840035F2840055F28400CDF284003A -+:101E7000B1D38400F5D384002DD48400C1D4840070 -+:101E8000A5048500F90585006D0585009904850088 -+:101E90008D04850079D4840045E88400B1C58400B0 -+:101EA00095DF840031DF840075E484001DE0840048 -+:101EB000BDC9840005ED8400A500850091FB840068 -+:101EC000F9ED840091EF84009DFB840081EA840099 -+:101ED00079E28400E1E500006DE60000A1EB8400FA -+:101EE000D1E484009D028500F1E7000015CC840058 -+:101EF0005DFB840081C5840015D5840099D68400DB -+:101F000035E78400B9DF840045F48400B9C7840054 -+:101F100001DF84002D018500E1C7840025D1840004 -+:101F2000B5E60000BDDD84004DF38400E1C9840006 -+:101F300041E084002DCA84009DD4840091E7000014 -+:101F4000D900850079CB840021FC8400B9E88400A5 -+:101F5000B5D8840031FD8400BDFB84001D048500DC -+:101F60005D04850031ED8400450685005DEC84004C -+:101F700025C384001DF38400D9C684002DEC8400A1 -+:101F8000F1C5840059E9840019C884005112010088 -+:101F9000B100850049D3840001C98400E1D28400E6 -+:101FA0008DCB8400DDEB840011F4840009FC8400F7 -+:101FB000D9F3840069C38400A1C884002DEE840095 -+:101FC00071D68400790185004112010025D8840072 -+:101FD000DDF9840009F0840035F784008DE8000005 -+:101FE000D9FC840015D78400DDD584001DDE840073 -+:101FF00001E9000019F1840099F1840049F184009D -+:10200000BDE90000A1F48400F1D084003DCC84003F -+:1020100069D2840089E98400F51D0100C9D38400D8 -+:102020008506850089078500E90685004D0785003E -+:102030001107850025078500710685009506850036 -+:10204000BD06850075078500B10785009D078500E1 -+:10205000A9068500D1068500FD06850039078500A3 -+:10206000610785005D0685001509850079098500F1 -+:10207000350A8500BD0985000D0A850091EA00003A -+:10208000711201004D0A8500A90985002509850006 -+:10209000DD0A85006D0A850081088500C507850079 -+:1020A0000D0B8500590F8500ED118500C9128500C3 -+:1020B00021108500F90D8500D5118500511085008E -+:1020C000AD118500011185006D108500B1D10100B1 -+:1020D000850F850085108500990D850011128500FA -+:1020E0000D22850041178500D917850075208500D0 -+:1020F0007D2C8500352F8500B92285002D25850092 -+:102100009D238500612F8500A5278500C92A8500AC -+:102110006D2985009D22850031228500A52485003A -+:10212000E1238500B12F8500BD2C85005914850061 -+:10213000C9138500A11C8500452C8500A9178500C1 -+:10214000B1208500311A8500FD178500291D850005 -+:1021500021148500AD218500B5308500453185000D -+:1021600035278500D1318500C5148500BD2D85003A -+:102170002D23850059238500891485004D4685004F -+:102180006547850025368500514785003D46850019 -+:102190008D3C8500514A8500994A85007547850028 -+:1021A0001D478500553685005D468500D53B850079 -+:1021B00049498500D53A8500E139850041398500D6 -+:1021C000E53885000937850045358500C93C85001F -+:1021D000754B8500B9458500ED4885002146850091 -+:1021E000213A8500A940850001328500F53285003D -+:1021F000FD378500894E8500DD508500ED50850056 -+:102200005D57850009558500495085005D50850062 -+:10221000D1528500F5528500E54E8500C9558500EF -+:1022200065568500C9508500094F850071D20100AF -+:102230009D5585000D538500A94C8500B957850033 -+:10224000A55785000D518500FD5A8500D5518500A3 -+:10225000A9518500B15285009D53850039558500EF -+:102260009D4E8500C95785006D578500954C8500AA -+:10227000095785008D4F8500DDD20100FD5985008D -+:10228000014D8500ED598500D9598500194C85000F -+:10229000756C8500816E8500516C8500295C850018 -+:1022A000416E8500795E8500210F0100AD6E8500CD -+:1022B000B56C85006D6585001D5F8500196B850017 -+:1022C0008579850071738500B58E8500E19585005F -+:1022D00001828500519085002D828500D190850076 -+:1022E000FD908500BD9285006D8F8500CD928500A3 -+:1022F00055968500C58E8500857285005D8D8500AB -+:1023000001838500C1918500257085000D918500B0 -+:10231000C17685006971850041718500F97F85006E -+:1023200079708500F19385009D958500F574850091 -+:10233000497485006D788500BD728500ED8A850041 -+:10234000C98C850099918500597D8500BD718500F6 -+:10235000758185000D818500A9798500217785002B -+:102360002193850089928500D194850095968500FA -+:1023700065838500D97385006582850021D30100BE -+:102380005975850021768500556F85006D9585000E -+:10239000E583850029848500AD8F8500F16E850079 -+:1023A0009D2E010075280100292E0100A53601008F -+:1023B000F52D01001D2B0100992B0100A531010015 -+:1023C0005D2B01002D2B0100252B0100613C01003C -+:1023D000692E010041370100952801007530010088 -+:1023E000FD310100C52A0100D1280100C13F0100D3 -+:1023F000CD280100C1400100F1420100DD2D0100A6 -+:10240000DD2A01004D2E01009D32010091360100B0 -+:10241000ED2D0100C5280100BD280100613001003B -+:1024200031340100253401005930010055330100D9 -+:10243000813001008D320100152D0100F92B0100C2 -+:10244000D1450100192D0100F92D0100012E0100D7 -+:1024500089300100A53A0100F93A0100B12C0100D0 -+:10246000D52D0100853501009DEB0000D9EB000062 -+:1024700015EC000059EF00009DF40000E12C020073 -+:1024800005F500000DF5000049F8000049F90000CD -+:10249000B1F9000009FB0000452F000011310000D8 -+:1024A000493100006D31000079310000C931000070 -+:1024B000D500010011020100D931000039330000BC -+:1024C00045340000710D0100F93500006D0D01006B -+:1024D000E54F00006D6B00005D750000B19E0000CF -+:1024E0005D0D0100610D0100690D0100650D010028 -+:1024F000F5160100A9C60000450D0100410D0100BF -+:10250000310D0100390D0100D90B0100510D010001 -+:102510004D0D0100550D0100590D01002D0D01005B -+:10252000350D01003D0D0100490D01004DD50000A4 -+:1025300031D5000039D5000041D5000059D5000043 -+:10254000FD0B0100190C0100390C0100F90B010011 -+:10255000F50B0100350C0100150C0100110C0100F8 -+:102560000D0C0100090C0100050C0100010C01001B -+:10257000890C0100950C0100C50C0100E50C01005F -+:10258000E90C0100FD0C0100F90C0100F50C010043 -+:10259000F10C0100ED0C0100990D0100910D0100FD -+:1025A000890D01009D0D0100850D0100790D0100CF -+:1025B0008D0D0100750D01007D0D0100950D0100CF -+:1025C000010D010001000000200000001F000000BC -+:1025D00050000000020000000100000001000000A7 -+:1025E000010000000000000061D401000A0708009B -+:1025F000B533020051FB80006D310000C12E000098 -+:1026000000000000D1F980000000000029FB8000DC -+:1026100000000000000000009C1800409600FFFF32 -+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA -+:10263000FFFFAAAA0300409600000000000000006F -+:10264000000000000000000000000000000000008A -+:10265000000000000000000000000000000000007A -+:10266000000000000000000000000000000000006A -+:10267000000000000000000000000000000000005A -+:10268000000000000000000000000000000000004A -+:10269000000000000000000000000000000000003A -+:1026A000000000000000000000000000000000002A -+:1026B000000000000000000000000000000000001A -+:1026C000000000000000000000000000000000000A -+:1026D00000000000000000000000000000000000FA -+:1026E00000000000000000000000000000000000EA -+:1026F00000000000000000000000000000000000DA -+:1027000000000000000000000000000000000000C9 -+:1027100000000000000000000000000000000000B9 -+:1027200000000000000000000000000000000000A9 -+:102730000000000000000000000000000000000099 -+:102740000000000000000000000000000000000089 -+:102750000000000000000000000000000000000079 -+:102760000000000000000000000000000000000069 -+:102770000000000000000000000000000000000059 -+:102780000000000000000000000000000000000049 -+:102790000000000000000000000000000000000039 -+:1027A0000000000000000000000000000000000029 -+:1027B0000000000000000000000000000000000019 -+:1027C000000000002DE97043994605460E469046EC -+:1027D00020F086FA436831469C69284642464B46BB -+:1027E000A047BDE87083C0462DE9F74F0029054694 -+:1027F00092469B46009153DB438A828A514403FBF5 -+:1028000002F399424CDA806808F038DB002101902D -+:10281000A86808F005DD4369044643F000434FF023 -+:102820000008436124E000989BF8007008EB000664 -+:102830004FF0000903E00136D04517D07F0817F0AC -+:10284000010F0CD0284621463246FEF3EDF630B19A -+:1028500063694FF0FF3023F00043636122E009F128 -+:102860000109B9F1080F08F10108E4D10BF1010BDE -+:10287000D045D8DB6369A86823F000436361002179 -+:1028800008F03EDCA868012108F03ADC2846214621 -+:1028900020F0C2F9A868019908F0C2DC002001E02C -+:1028A0006FF01C00BDE8FE8F407C704713B500F050 -+:1028B0008FD8024608B904460FE000240AE010460B -+:1028C00001A90022FFF344F7019A13782C2B08BFCB -+:1028D000013201341378002BF1D120461CBDC046D3 -+:1028E000B0F8423070B50446C3B142F2197503E046 -+:1028F0000A2003F031DF0A3D236B1B6913F070439C -+:1029000007D0B3F1005F04D0B3F1405F01D0092DCF -+:10291000EED1226B136823F01003136070BDC04624 -+:1029200070B590F878310546FF2B1FD0104C406AE7 -+:10293000E36E9847D4F89C30686A984701280BD812 -+:1029400095F8141241B90B4628460A4A03F030DEC6 -+:10295000012385F8143209E0054B686AD3F89C30EE -+:1029600095F805419847241885F8064170BDC04682 -+:10297000E0A685003D98800010B5084671B191F839 -+:102980000832012B0AD091F875313BB14B691A6AB4 -+:10299000034B02EA03030BB10EF0FEFE10BDC0466E -+:1029A00000FC0101D0F8943110B59942044601D9D8 -+:1029B000002002E00EF0F0FEE08D10BDD0F8801196 -+:1029C00010B5044691B10223C068D4F8842108F000 -+:1029D00005DB074B1B684BB9D4F88011D4F8842170 -+:1029E000E06881EA0202023308F0F8DA10BDC0465E -+:1029F000AC2702002DE9F04190F817320446012B74 -+:102A000077D00123002780F8173243E0A0683146D1 -+:102A100000F082DBD4F8F0301B68984205D92846D4 -+:102A20000021324600F00EDB42E02046FFF778FF3F -+:102A300035690023AB7194F8783131462B7294F8E4 -+:102A4000063184F80731DBB26B72D4F8FC31606A6E -+:102A50000133C4F8FC316A79274BD20982F00102B4 -+:102A60005B6A9847B0B9D4F8F8106B7900293CD06C -+:102A700013F00F0F39D06A782B7843EA02230F3313 -+:102A80001B091A0A0A6918BF0023937194F8783158 -+:102A900013722AE0D4F8F0301B68012B08D904F136 -+:102AA00028052846002100F04FDA06460028ADD15F -+:102AB000002384F81732C4F8F8302FB16269043368 -+:102AC0005364204607F03CDFE28DD4F8C8319A42C7 -+:102AD00003D9206901F0C4DD0BE0D4F8CC319A426F -+:102AE00007D2206901F0AEDD03E00127C4F8F860E9 -+:102AF000D0E7BDE8F081C046E0A685002DE9F041B1 -+:102B00000746884616461D4642F2197403E00A201D -+:102B100003F022DE0A3C79690B6D002B02DA092CE6 -+:102B2000F5D11FE0AB191B0243F00042069BB3F145 -+:102B3000807F04D198F8003043F08073D21842F2BD -+:102B400019740A6503E00A2003F006DE0A3C7B697B -+:102B50001B6D002B02DA092CF5D103E0012088F867 -+:102B6000003000E00020BDE8F081C0460022C36BC9 -+:102B70000BB1013BC363531CDAB21030102AF6D1FB -+:102B80007047C0462DE9F041066805460F4670685B -+:102B90004FF4BC7104F09CD808B9044612E000213F -+:102BA0004FF4BC720446FFF34BF2D5F86031266057 -+:102BB000C4F8603195F86431C4F8687184F8643100 -+:102BC0006B6863602046BDE8F081C04603682DE96C -+:102BD000F74F012A14BF2A25322506460F465868AA -+:102BE0002946914604F0CCD8834640B93368013871 -+:102BF0001B68D3F88C20136D013313656CE007F16B -+:102C00000E0A04695146042201A8FFF3B5F1019BA5 -+:102C100006F1280803F47F421B0643EA02234AF622 -+:102C2000FE12B2EB134F0BBF2C4907F108012046EF -+:102C300020460622FFF3A0F10622A01D4146FFF325 -+:102C40009BF104F10C02B9F1000F0DD02B0A237394 -+:102C500004F10E00557022490622FFF38DF108237E -+:102C600023750623637503E008232373062353703B -+:102C70006419A4F11C05394606222846FFF37CF1AD -+:102C8000002304F8163C023304F8153C41460622A2 -+:102C900005F10800FFF370F107F11801042205F1B6 -+:102CA0000E00FFF369F107F10801062205F1120099 -+:102CB000FFF362F15146042205F11800FFF35CF1C5 -+:102CC000D6F85C3130680133C6F85C315946D6F825 -+:102CD000682125F067DA0120BDE8FE8F2C9E850073 -+:102CE00014D2850010B50368D3F800481B6893F828 -+:102CF000AB306BB1FFF73AFF08E0A16829B10120C2 -+:102D000000F0CAF808B1FFF731FF2468002CF4D1B5 -+:102D1000002010BD7047C046C3682DE9F04106464B -+:102D20000D4658683821174603F0D2DF044610B923 -+:102D30006FF01A002BE000213822FFF381F101230C -+:102D4000294623606360A360062204F10C00FFF3B0 -+:102D500013F16B8E05F10901A3742B7A04F11400B1 -+:102D6000E3742A7AFFF308F16D8D3046A586E78675 -+:102D70002146382221230BF013DE00B907E0F36867 -+:102D800021465868382203F0B3DF4FF0FF30BDE82A -+:102D9000F081C04630B50C4690F8CF1091B0944603 -+:102DA0009E460380194D91B94FF0FF330293039370 -+:102DB000049305930D3300940191069107910891B6 -+:102DC00009910A950B900C930D910E9115E04FF01F -+:102DD000FF33029303930493059300F1D00306930A -+:102DE0004BB2002207930C2300940192089209929F -+:102DF0000A950B900C930D920E927146044A63460D -+:102E0000C06824F079D811B030BDC046F920010067 -+:102E10002C9E85001FB5836D0446012B17D1B0F899 -+:102E2000583113F0010F12D1C36893F8703273B99F -+:102E300002AA01A903AB0FF0E5F9029A3AB12046C4 -+:102E40000199039BFFF7A6FF08B90223A3651FBDE5 -+:102E500010B579B1B0F8583143F00103A0F85831FA -+:102E6000836D022B15D1C3680C21D3F8680151F092 -+:102E70009FDB0EE0B0F8583113F0010F09D023F0BA -+:102E80000103A0F85831836D1BB101238365FFF75F -+:102E9000C1FF002010BDC046012801D0002000E085 -+:102EA0008868704710B50C4641B18B6823B9C06F74 -+:102EB0000968FFF767FEA060A06800E0C06F10BD62 -+:102EC0002DE9F0418C692369994202D100273E46E1 -+:102ED00004E0CE6A0EB9374600E0376863681146F1 -+:102EE000D86803F03BDFA36805461B6893F895306C -+:102EF0001BB1C38A43F08003C382636893F8AB308D -+:102F00008BB120463146FFF7CDFF60B129460AF06C -+:102F10003FD9022807D163682946D868012203F007 -+:102F2000FFDE01200BE0204629460CF039DCA068CA -+:102F300029463A4625F036D9003818BF0120BDE8A9 -+:102F4000F081C04637B5144605461146406FFFF77D -+:102F5000E1FE6368112B08D0122B01D0102B15D184 -+:102F6000A37803F001032B7510E002AA002342F8B6 -+:102F7000043DA86894F82F103CF080D930B18379D3 -+:102F800023B96188C1F3800127F03AD93EBDC0461C -+:102F90002DE9F0470446084615460DF003FF80462C -+:102FA00010B9D4F8109001E0D0F80490A368D9F8D3 -+:102FB00024701B682A6993F895303BB1EB8A13F4AF -+:102FC000006301D001262AE01E460AE0537B127BF3 -+:102FD00043EA022348F66C02934214BF00260126FE -+:102FE000EEB9204629460CF0CDDB636893F8AB3090 -+:102FF000ABB120464146FFF755FF80B1294609F0A5 -+:10300000B9DF042801D0012804D163682946D868B3 -+:10301000002244E0052802D14FF0010801E04FF002 -+:103020000008636893F895301BB116B9AB8A2D334D -+:10303000AB82002F2FD0EEB9FB6913F0010F07D040 -+:10304000637D2BB1204629460CF0A8DC024668B10E -+:10305000B8F1000F0ED1636893F8963053B1D4F8ED -+:10306000840029460EF004F9024618B9636829461F -+:10307000D86814E063682946D86803F0ABDE3B6982 -+:103080000446DB68484639462246984748B1204600 -+:1030900003F0DCDD05E063682946D8683A4603F0B2 -+:1030A0003FDEBDE8F087C0464B6A10B591F843207B -+:1030B00043F480134B62D0F8883002F00702D21834 -+:1030C00092F88030013382F88030D0F888200123D4 -+:1030D00082F88630D0F8881091F8812091F87B3002 -+:1030E0009A4211D291F8802091F87A309A420BD20C -+:1030F00091F8822091F87C309A4205D291F8832091 -+:1031000091F87D309A4201D30DF0F0D8002010BD27 -+:103110001FB5084B02460093074B08460193074B27 -+:103120000749DB6902931268064BFFF3F5F105B01E -+:1031300000BDC046DDD60100A0D601000028020077 -+:10314000AED60100D1D6010010B5436804461B7EFF -+:1031500053B1D0F880000CF049FDA06801F048FEA2 -+:103160006268002382F8203010BDC04610B5806927 -+:10317000FFF7EAFF002010BD70B504466368806861 -+:103180001E7E0EB1002515E001F0F4FC054620B9C5 -+:10319000D4F880000CF058FD05460CF0D5F86368B3 -+:1031A000D3F89C1031B10B7823B1034B3246186829 -+:1031B000FFF33AF5284670BD2428020010B5806858 -+:1031C00001F0FEFD002010BD10B50446FFF7F6FF2C -+:1031D000A06806F083FE10BD61290DDC602940DA8D -+:1031E00054293ED003DC2F293BD0442912E0A1F121 -+:1031F0005C03012B0FD834E0AC2932D005DC7C29EC -+:103200002FD0A1292DD06A2904E0DE2929D0F42964 -+:1032100027D0CD2925D0642911DC632921DA4A2958 -+:103220001FD006DC07291ADB08291ADD3C2918D033 -+:1032300015E0502915D012DBA1F15C030DE0C32984 -+:1032400005DCC2290DDAA1F1A803022B06E0B1F5D5 -+:10325000847F06D003DBA1F58973012B01D90020FF -+:1032600001E06FF01600704731B1036B1B689942A3 -+:1032700002D06FF00C0006E090F82930002B14BF4C -+:1032800000206FF00A00704730B5072A1C469DF8F1 -+:103290000C5001DD496809B9036B1968032906D090 -+:1032A0004B1E012B10D8036B1B6899420CD12DB11A -+:1032B00090F8293013B96FF00A0007E00CB92046E6 -+:1032C00004E00020216001E06FF00C0030BDC0463A -+:1032D0001FB59646BEF1070F1A4601DC002300E039 -+:1032E0005B685F2903930ADC5E2914DA4A2916D049 -+:1032F00002DC3C2913D00CE05C290ADB0FE0AA2990 -+:103300000DD002DCA82904DB0DE0C22907D0C329B7 -+:1033100009D000200EE01946FFF7A6FF0AE00021C1 -+:10332000FFF7A2FF06E000230093114603AB7246AD -+:10333000FFF7AAFF05B000BDC88810F0080018BF4D -+:103340006FF016007047C046D1F8D83270B5054608 -+:10335000188C164610BB8B6D40F2371203EA02023E -+:10336000002A0CBF012411242A6B1368022B07D1F9 -+:1033700095F85C360133DBB2012B98BF44F0200492 -+:10338000537D53B1B06B06F13C0122F063DE20B1F6 -+:1033900095F947360BB144F48064204670BDC046B1 -+:1033A00091F801C030B5BCF1010F45DDCA788B78CA -+:1033B00043EA0223012B3FD1ACF10203032B3EDD94 -+:1033C000ACF10603012B3ADD0B1D1D1D6A781B793C -+:1033D000002043EA0222864600E00130ACF10803F7 -+:1033E000904203EB0E0406D0AEF1040EACF10403E0 -+:1033F0007344042BF1DCC0EB0203A4EB830001282F -+:103400001DDD05EB8203DA789B7843EA022E821EEB -+:10341000002301E00133043A734501D0032AF9DCAB -+:10342000C3EB0E03A2EB8303012B08DD023B06D0A6 -+:10343000C3EB0C034B7002E06FF0160000E00020BD -+:1034400030BDC0462F2A30B50446964602D86FF0EC -+:103450000D0034E0B0F88031056B0B60B0F88231BC -+:10346000AA894B60EB891B0743EA023302688B6031 -+:103470001069BEF13B0FC36BCB6093680B61836A2D -+:103480004B61C36A8B61B2F87A30CB61D4F8843176 -+:103490004B62D2F8B0300B6243688B62836BCB62B5 -+:1034A0000CD92B8900220B636B89BEF13F0F4B6354 -+:1034B0008A6303D9036C1046CB6300E0002030BD63 -+:1034C00010B519B14068302203F012DC10BDC046BF -+:1034D00010B50446D0F860068E46C37A90F80AC04C -+:1034E00093B182894FF6FF739A420DD0837B43B923 -+:1034F0008378012B05D0037B03F0010383F00101E6 -+:1035000000E00021C9B20BE0216B71450ED1837B35 -+:103510002BB98378012B02D091F84C1000E00021E8 -+:103520008C4503D08172206938F0BADE002010BDCE -+:103530004FF0FF33A0F83C3210B5044600F50E7092 -+:10354000063000210C22FEF37BF523685B6B23B968 -+:103550004FF0FF33A4F840320DE04FF00F03A4F812 -+:103560003E324FF0F003A4F840324FF47063A4F8F9 -+:1035700042324FF20003A4F8443210BD70B5044645 -+:10358000D4F8741580680CF069D8D4F8F816D0F126 -+:10359000010538BF0025A0680CF060D800B90135DE -+:1035A000A068D4F8FC160CF059D800B90135D4F84D -+:1035B000E036A068196A0CF051D800B90135D4F88A -+:1035C000E0260023D360A068D4F83C150CF046D860 -+:1035D00000B90135A068D4F894170CF03FD800B9B1 -+:1035E0000135284670BDC04610B5044625F0F2DE10 -+:1035F000204617F00BD810BD2DE9F04F0746106993 -+:10360000A5B0D1F81090884601F124011A900792D4 -+:103610000693189199F80130D2F87CA199F800200E -+:10362000339C42EA0323C3F38102022A7868089399 -+:103630000B9201D0002302E0089DC5F3C013DBB25A -+:1036400041461693FFF3E6F504300A90329888B1AC -+:10365000037A0B2B08D197F8F0375BB197F8F13765 -+:1036600043B18379072B05D832990A9A91F90F3023 -+:10367000D2180A92D7F88831002B1CDA329BD3B1CA -+:103680001B7A022B17D197F8A034A3B91A9DAB6D02 -+:1036900013F0080F0FD132988379292B0BD8032B05 -+:1036A00009D90B2B07D82F99012904D10A9A19910E -+:1036B00008320A9201E000231993D8F81030B8F8C4 -+:1036C0001420A3F1760676329D1FA8F8142000215D -+:1036D0007022C8F8106030460595FEF3B1F41898D2 -+:1036E000036813F4806F01D0828827E00799A64B06 -+:1036F0004A6802EA0303D3B1089A02F0FC03882B5C -+:1037000015D199F8043013F0010F10D1B8F8163024 -+:103710002F9D03F007032E9801EB43016B1E984287 -+:10372000B1F8BE200AD1531CA1F8BE3006E00B99B7 -+:10373000012914D000224FF0100B04E00B9B012B49 -+:103740000DD04FF0000B2E9D05F00F0343EA02133E -+:103750009BB289F816301B0A89F8173001E04FF048 -+:10376000000B3098042807D138461A9932460FF0DA -+:1037700047D8ADF88C0019E02F992E9D4B1E9D4225 -+:10378000B7F8462502D1531CA7F846352E98309934 -+:1037900000F00F0343EA02135B0147F6E07203EA0D -+:1037A000020201F007031A43ADF88C20079A92F841 -+:1037B000DF3023B9089D05F0FC03802B01D14BF0CD -+:1037C000200B724B04EA03031BB1002020942194C8 -+:1037D0001FE00B99012906D9189A1368002B02DB08 -+:1037E00013F0100008D0079C002594F8483003F02F -+:1037F0007F032093219349E0396B644B8A6C02EA82 -+:10380000030343B199F8043013F0010F03D0209261 -+:1038100021920F903BE099F8043013F0010009D099 -+:103820000798002190F848300F9103F07F03209310 -+:1038300021932CE04A6C554B02EA0303002BE6D19E -+:1038400020ABD7F8600100930DF18F0301930DF1C8 -+:103850008E0302930DF18A03039323AA21AB0799E8 -+:103860004FF028DA189A136843F00062189B1A6028 -+:10387000BDF88A3013F0010F03D0189C42F40053B6 -+:1038800023602E9DD5F1010538BF00250F95D7F88F -+:103890006036219A9C7A3B6893F8463013F0030116 -+:1038A00000F0358112F0006F02F07F0104D007298B -+:1038B00006D9202904D02EE0354B5B56002B2ADA9E -+:1038C00012F0804F01D1002A25DB22F4401121F4AF -+:1038D000605112F0006F21911AD0D7F860068378FA -+:1038E000012B15D93B6B93F94D20012A0BD0079D75 -+:1038F0006B6813F0804F0BD0B2F1FF3F08D1037B10 -+:1039000013F0040F04D041F4801343F4805301E01A -+:1039100041EAC4232193209911F0006F01F07F0246 -+:1039200004D0072A06D9202A04D036E0184B9B562B -+:10393000002B32DA219B13F0804F01D1002B2CDBBE -+:1039400021F4401222F4605211F0006F209221D035 -+:10395000D7F860068378012B1CD93B6B93F94D1087 -+:1039600001290BD0079D6B6813F0804F12D0B1F185 -+:10397000FF3F0FD1037B13F0040F0BD042F48013F1 -+:1039800043F4805308E0C046400001807F000008F7 -+:10399000401B860042EAC4232093B7F8283603F47C -+:1039A0004063B3F5406F30D13B6B18690FF0BEF840 -+:1039B000219B00F44070B0F5007F14BF0222032267 -+:1039C00013F0006F03F07F0111D0202902D11546BA -+:1039D00005222EE097F9CA34B3F1FF3F12D10798C0 -+:1039E000436813F4002F23D01546042221E09C4B9A -+:1039F0005B56002BB4BF97F9C93497F9C834B3F1BB -+:103A0000FF3F15D015469AB213E0219B03F07F03C8 -+:103A1000202B04BF4FF000632193209B03F07F0312 -+:103A2000202B04BF4FF00063209302252A4600E0BC -+:103A30001546219B110223F4E06341EA030321931D -+:103A4000209B23F4E06213F0006F14BF41EA0203ED -+:103A500042EA05232092219A209312F0006F06D0AB -+:103A600097F9DC31012B02D142F4000304E097F90D -+:103A7000DC3113B922F400032193209A12F0006F75 -+:103A800006D097F9DC31012B02D142F4000304E0A7 -+:103A900097F9DC3113B922F40003209307993846D3 -+:103AA00012F03ED9219911F0006202D111920E92CA -+:103AB0001DE0D7F8583693F90530022B02D00022CA -+:103AC0000E9207E0C1F30223043B012B8CBF0023BD -+:103AD00001230E9311F4000F05D001F07F03072B93 -+:103AE00003D9202B01D0119001E0042311932099D8 -+:103AF00011F0006201D112921DE011F4000F16D0F6 -+:103B000001F07F03072B14D9202B12D00FE0209B4C -+:103B100022F4E06223F4E06342F4007243F40073A1 -+:103B200002252192209311910E91129103E012909F -+:103B300001E0042412940F9888B11A99219BD1F8BE -+:103B400010231A9801EBC201C1F814332F9C0132E3 -+:103B5000E3B202F03F02C1F81833C0F81023BAF103 -+:103B6000000F36D0FA68DAF80434D2F880410AEB54 -+:103B7000C303C3F80442D2F884013A4AC3F80802E6 -+:103B8000B8F8163003F00703D35C022B11D1DAF832 -+:103B900000100AEBC102C2F80441C2F80801219BDF -+:103BA000013153602F9C01F01F01E3B29360CAF80A -+:103BB0000010DAF80424219B0AEBC201C1F8083492 -+:103BC0002F980132C3B202F03F02C1F80C34CAF898 -+:103BD0000424219911F000642AD011F4000F01F49B -+:103BE000E06312D01B0A043B012B1F4801F07F0247 -+:103BF00005D8142302FB0303D3F80C801AE0142326 -+:103C000002FB0303D3F8088014E01B0A043B012BDA -+:103C1000154801F07F0205D8142302FB0303D3F8F3 -+:103C2000048007E0142302FB03F353F8008001E053 -+:103C300001F07F080B9A022A00D0BAB9B7F83836DB -+:103C40000A98984204DC189A136813F0806F0DD01C -+:103C500099F8043083F0010303F0010307E0C04644 -+:103C6000401B8600C4D285008418860000230D9373 -+:103C70003B6B587D50B1D7F858361B7833B12CB90F -+:103C8000924A01F07F03D356002B0BDB3B6893F87D -+:103C9000463013F0030F2CD05CB3D7F8583693F9A5 -+:103CA000053033B32F9A012A13D9D7F858361B7829 -+:103CB0000BB1162300E03023189C20932193236836 -+:103CC00023F000632360209B43EA05232093219384 -+:103CD0000FE070B1D7F858361B7853B14CB97B4A16 -+:103CE00001F07F030E98D35630EA230028BF01204D -+:103CF0000E90219A12F0006F15D102F07F03022B73 -+:103D000005D0042B03D00B2B01D0162B0BD1069919 -+:103D100039B1022B05D097F95C36013B18BF01235E -+:103D200000E000231193209B13F0006F16D103F0E5 -+:103D30007F03022B05D0042B03D00B2B01D0162BB5 -+:103D40000CD1069C44B1022B06D097F95C36013B9E -+:103D500018BF0123129301E0002012900B99079CD9 -+:103D6000022904BF079BC3F86021636813F4803FF6 -+:103D700040D097F8CE31002B3CD097F8D131002BB2 -+:103D800038D0D7F8583693F90530032B32D0219B21 -+:103D900013F0006F09D103F07F03022B2AD0042B0C -+:103DA00028D00B2B26D0162B24D099F8043013F0F2 -+:103DB000010F1FD1089800F0FC03882B1AD1189925 -+:103DC00001240B684BF4A04B43F480530B60079B1A -+:103DD0001094D3F8F0204FF69F73002A0CBF1822DE -+:103DE0001E2239F8021001EA030343F0200329F8E8 -+:103DF000023001E000201090384621990A9A059B74 -+:103E00000DF17A0419F028DC2346384620990A9AE5 -+:103E100019F022DC062206F136002146FEF3ACF052 -+:103E2000209B13F0006F10D103F07F03022B05D00D -+:103E3000042B03D00B2B01D0162B06D10A99C1F30A -+:103E4000072386F83A1086F83B30189B1A6812F45C -+:103E5000806F13D0219B13F0006F0FD0329C14B1F0 -+:103E6000237A042B0AD1189842F40063036097F870 -+:103E7000C3340D99002B18BF01210D91219911F028 -+:103E8000006F0AD1114A01F07F03D356002B04DAE8 -+:103E9000059A137803F00F0301E0059B1B78089C3B -+:103EA0000C93A42C14D099F8043013F0010F0FD107 -+:103EB000109878B9119A319B38460FF06FDE89F867 -+:103EC0000200C0F30F2089F803001DE0401B8600AC -+:103ED000109A62B1119A384640F62A1319F052D955 -+:103EE000023080B289F80200000A89F80300089BBA -+:103EF000A42B09D199F8023099F8032043EA022350 -+:103F000086F83C301B0A09E099F8043013F0010FE1 -+:103F100001D1109C2CB1002386F83C3086F83D304E -+:103F20000BE02099129A319B38460FF037DE86F865 -+:103F30003C00C0F30F2086F83D001898036813F486 -+:103F4000007F0DD083894BF4005B86F842301B0A5A -+:103F500086F84330C38986F844301B0A86F845301A -+:103F60002E9909B94BF0080B09F104021B9299F83C -+:103F7000043013F0010F14D1189B1A6812F4805FFB -+:103F80000FD197F8D03113B112F0400F09D112F4CC -+:103F9000806F04D1169C14B197F8F8310BB94BF02F -+:103FA000010B0B98022814D197F8CE318BB1B8F1E0 -+:103FB000040F0ED9AB4B30995B5C07EB4303B3F8AE -+:103FC000FE3123B1189A136813F4806F01D04BF4BB -+:103FD000805B3B6B18690EF0A9FD199B00F44060F3 -+:103FE000B0F5406F08BF4BF4807B0BB14BF4004B36 -+:103FF0004FEA1B2386F800B07370329CECB197F83F -+:10400000A034D3B91A98836D13F0080F15D1237A11 -+:104010000B2B08D197F8F0377BB197F8F13763B1E4 -+:10402000A379072B09D832998A79292A05D80B7BDD -+:1040300003F0070343EA021A01E04FF0000A189A5E -+:10404000129C1368494613F0005F18BF4AF0080A33 -+:10405000631EDBB2012B98BF4AF4005A301D0222C6 -+:10406000FDF38AF70023B371F37186F82C3086F8DC -+:104070002D303298002849D097F8A034002B45D134 -+:104080001A998B6D13F0080040D1329B1A7A0B2AD3 -+:104090000BD197F8F037002B38D097F8F137002B79 -+:1040A00034D0329CA379072B30D832998B79292BC5 -+:1040B0002CD8089C09F1180104F44073B3F5407F33 -+:1040C000169B08BF09F11E0103B10231022A11D16A -+:1040D0003246329C2318B3F8BC309375C3F30723E0 -+:1040E000D375831C02320A2B1846F2D106F1200048 -+:1040F000032209E00B2A06F1160002D10231053233 -+:1041000002E0329B93F90E20FDF336F706221B994D -+:1041100006F12600FDF330F79DF88C30002486F878 -+:104120004C309DF88D3086F84D30D7F84C011A99F7 -+:104130004AF0EEDF96F8463096F8472080B243EA20 -+:10414000022343EA00239BB286F846301B0A86F816 -+:10415000473086F84E4086F84F4086F8504086F843 -+:10416000514086F8524086F8534086F8544086F80D -+:10417000554086F8564086F857400D9808B10E9481 -+:1041800003E00E99002900F01D81002221992B46A1 -+:10419000384622F051DE00228046209938462B46D0 -+:1041A00022F04ADE18F000628346099206D12E4BB7 -+:1041B00008F07F029B56002B2ADA36E018F4000F35 -+:1041C00008F4E06310D01B0A043B012B274808F0D9 -+:1041D0007F0204D8142302FB0303DB6814E01423DA -+:1041E00002FB03039B680FE01B0A043B012B1F48E3 -+:1041F00008F07F0204D8142302FB03035B6803E08A -+:10420000142302FB03F31B58023B18BF012302E0F7 -+:10421000931E18BF012343B197F95C36012B04D0DC -+:1042200001234AF4804A139301E0002413941BF005 -+:10423000006F06D10C4B0BF07F029B56002B30DA3F -+:104240003CE01BF4000F0BF4E06316D01B0A043BA8 -+:10425000012B06480BF07F020AD8142302FB03034C -+:10426000DB681AE098E08500401B86008418860011 -+:10427000142302FB03039B680FE01B0A043B012B82 -+:104280009D480BF07F0204D8142302FB03035B68F4 -+:1042900003E0142302FB03F31B58023B18BF012366 -+:1042A00002E0931E18BF012343B197F95C36012B3E -+:1042B00004D001254AF4004A149501E0002014902E -+:1042C0000E993278737821B142EA032343F40063F4 -+:1042D00003E042EA032343F0060333701B0A7370C2 -+:1042E0000E9B06F15802002B0CBF14250E251592CB -+:1042F0001DAC2A4638464146159B19F0ADD92346D8 -+:104300002A463846594619F0A7D92146062206F111 -+:104310002E00FDF331F6139C119D0A9800940024A1 -+:104320000E99219B0195029042460394384619F05C -+:10433000B3D986F86000C0F30F2086F861001499A5 -+:10434000129A0A9B009101920E9902930394209B6A -+:1043500038465A4619F0A0D986F83400C0F30F2029 -+:1043600086F835000E9D06F162004DB16FF03B03FB -+:1043700009F10A01062286F85E3086F85F4008E0FF -+:104380006FF04B0386F85E300E990C2286F85F10B2 -+:104390001B99FDF3F1F5099A52B9584A08F07F03C9 -+:1043A000D356002B04DA159C237803F00F0301E0A9 -+:1043B00096F858300C9D1B0243EA050506F15E098C -+:1043C0000C951BE00E99062206F15800FDF338F615 -+:1043D0000E99102206F15E00FDF332F606F12E0072 -+:1043E0000E990622FDF32CF60E9886F8340086F816 -+:1043F00035008146139014908046834618990B68C7 -+:1044000013F4806F0BD0219A12F0006F07D0D7F809 -+:10441000400107990A9B2AF0B3DF86F833004FEA80 -+:104420001A23F37086F802A00C9A130AB274F3747C -+:10443000209B13F0006F02D097F8C0A40EE003F0A9 -+:104440007F03022B07D0042B05D00B2B03D0163B88 -+:1044500018BF012300E000231FFA83FA18F0006F51 -+:1044600003D097F8C0349D000EE008F07F03022BC4 -+:1044700007D0042B05D00B2B03D0163B18BF01230C -+:1044800000E000239B009DB21BF0006F03D097F863 -+:10449000C0341C010EE00BF07F03022B07D0042B6D -+:1044A00005D00B2B03D0163B18BF012300E00023DF -+:1044B0001B019CB23B6B18690EF038FB45EA0A03FE -+:1044C0002343C0B243EA002333751B0A7375219B53 -+:1044D00013F0006F02D097F8C04413E003F07F039D -+:1044E000022B0DD0042B0BD00B2B09D0B3F11600EF -+:1044F00018BF012005E0C04684188600401B8600D6 -+:10450000002084B2119D6B1EDBB2012B07D83B68E3 -+:1045100044F01004D3F88C209369013393612199FE -+:10452000384615F02BDB44EA000080B23072000AF6 -+:104530007072219938461FF055DEB072C0F30F201B -+:10454000F072209938461FF04DDE3073C0F30F2013 -+:1045500070730D9808B90E9979B1414638461FF02D -+:1045600041DEB073C0F30F20F073594638461FF098 -+:1045700039DE3074C0F30F207074219911F0006F90 -+:104580000CD0119A042A09D10A9A384618F0ACDEE8 -+:1045900086F83E00C0F30F2086F83F00209911F006 -+:1045A000006F0CD0129B042B09D10A9A384618F0E0 -+:1045B0009BDE86F84000C0F30F2086F84100079C80 -+:1045C000636813F0400F00F0CE80169D002D00F0C0 -+:1045D000CA806A4B30981B5C179307EB4303B3F810 -+:1045E000FE31002B00F0BF8018990B6813F4806F28 -+:1045F00040F08D802E9A002A40F08980219C384618 -+:104600002146119A0A9B18F0BDDD8246B9F1000FD0 -+:104610001AD04146139A38460FF082D8149A0446AD -+:10462000594638460FF07CD899F8032099F80230A3 -+:1046300043EA022303EB040896F8352096F8343059 -+:1046400043EA022318181BE0109B13B1804648462A -+:1046500016E02146119A4B4638460FF09FDA209C0F -+:10466000129A21460A9B00EB0A08384618F08ADDA8 -+:1046700021460546129A38464B460FF08FDA40190C -+:104680001FFA88F3B3711B0AF37183B286F82C30DA -+:104690001B0A86F82D30179C07EB4403B3F8FE5134 -+:1046A000CAEB0804A54225D31898036813F0400FFD -+:1046B00002D0309901291DD038462199119AC4EBB6 -+:1046C00005030FF035D8FF2802D84FF4807304E0BB -+:1046D000B7F82A36834228BF034699B2309B07EBCE -+:1046E0004302B2F82C368B4204D0A2F82C1638467E -+:1046F00026F0CCD83B6893F84430002B33D0309C64 -+:10470000032C30D8D7F864011799424628E03B685B -+:1047100093F844303BB3309D032D24D8B9F1000FFA -+:104720000CD0139A384641460EF0FADF99F8032070 -+:1047300099F8023043EA02231A180EE0219C119ADC -+:1047400021460A9B384618F01DDD119A0546214680 -+:1047500038464B460FF022DA4219D7F86401179910 -+:10476000079B3DF02FDD1898036843F08403036036 -+:10477000BDF88C0025B0BDE8F08FC04698E08500FC -+:104780002DE9F0479946536A064613F4007F8846A0 -+:1047900017469DF920A0146902F1240515D0E86898 -+:1047A00083B2000C84F8423084F844001B0A000AEB -+:1047B00084F8433084F845002378607843EA002386 -+:1047C00043F4005323701B0A637033682D6993F818 -+:1047D000443093B1F36A03EB4803B3F91C3063B977 -+:1047E0005DB12B69D3F8D43293F89D30032B04D9F3 -+:1047F000D6F864012B463DF0C5DDB8F1040F22D197 -+:1048000094F84D3094F84C2042EA0324336893F82E -+:104810003830D3B1384612F045D906EB8000D0F8D5 -+:104820004C12D1F85835D1F860055A1CC1F85825FA -+:10483000C369A1F8C8409A4288BFC261D1F8602517 -+:10484000136A013313624FF6FF74B9F1000F05D0FC -+:10485000F26A02EB4802938B534493834FF6FF7343 -+:104860009C4204D03069A821224639F0F3D933693B -+:10487000394603EB8803D8680C4B4A465B6A984775 -+:10488000002810DA0A480CF00FFF0A4A13680133B7 -+:104890001360B9F1000F06D0F26A02EB4802938B65 -+:1048A000CAEB03039383BDE8F087C046E0A685000A -+:1048B000BC568600E827020070B50D46D0F8601699 -+:1048C0000446CB7AAB420CD025B10C31B0F8282687 -+:1048D00015F098D9D4F860362046DD72216BFEF7CA -+:1048E000F7FD002070BDC0462DE9F04F89B00023D0 -+:1048F0000D46179907460492149CDDF854800793DF -+:104900000693DDF848B0DDF84C903AF073DD049A78 -+:10491000824602F001060096386829462246434640 -+:104920001EF0D2DC0590002840F0ED80B5F906308D -+:10493000002B1CDAA9882A895EB1169BCDF800806D -+:1049400003930194CDF8088049003869013123466A -+:1049500009E0169BCDF8009003930194CDF80880F0 -+:10496000386949005B4638F0FBD80590CBE0B9F1D7 -+:10497000030F0DD9042207A85946FDF3FDF2B9F142 -+:10498000070F05D906A80BF104010422FDF3F4F288 -+:10499000049A0799931E1F2B21D8DFE813F02300F8 -+:1049A0002500270029002E00310038003A004B0076 -+:1049B0004D0053005500570059005B005D005F003B -+:1049C000200065006C0074007600870089008D006F -+:1049D0008F00940096009B002000A6009D006FF0C1 -+:1049E00016038FE04A4B09E0494B71E0494B05E063 -+:1049F000002900F38580474B05E0474B1B6879E0B1 -+:104A000000297DDB444B1960444B002239E0444BC4 -+:104A1000F4E719B1434B1B68002B71D0404B0022C7 -+:104A20001960414B1A60414B1A60414B1A60414B6F -+:104A3000013A26E03B4BE1E73A4A1368002B5FDD81 -+:104A4000116060E03C4BD9E73B4B41E03B4BD5E785 -+:104A50003A4B3DE0344BD1E7334B39E0D7F86C3279 -+:104A6000D3F8D8329B6845E0354B1A68354B1B6844 -+:104A700043EA02433EE0324B0A141A60314B01F024 -+:104A8000FF021A603FE0304BB8E72F4B1960002956 -+:104A900039D02E4B002119602D4B4FF0FF321A6098 -+:104AA0002C4B1A602C4B19602C4B11E02C4BA5E7BA -+:104AB000002925DD2A4B0BE02A4B9FE74B1E092BD3 -+:104AC0001ED8284B04E0284B98E7002918DD264B18 -+:104AD000196018E0254B91E79AF8063063B9244B2A -+:104AE0000A1E18BF01221A700DE09AF806301BB991 -+:104AF0001F4B1B78236006E06FF00602059202E070 -+:104B00006FF01C030593059809B0BDE8F08FC0460F -+:104B1000EC270200D8270200E0270200B827020095 -+:104B2000C0270200401E0200D4270200D027020046 -+:104B3000C8270200B42702002C1E0200441E0200F7 -+:104B4000142C0200102C0200BC270200E4270200F3 -+:104B5000281E0200381E0200C4270200DC270200C3 -+:104B6000341E02003C1E0200241E0200CC2702005C -+:104B7000B027020037B5036804465B7E002B40F087 -+:104B8000C480026992F8EA305BB1D36ED3F8202179 -+:104B900040F2044302EA0303B3F5806F40F0B580AE -+:104BA00005E0106E0AF050FE002840F0AE80236849 -+:104BB00093F8203033B9206907F062FE22680123A0 -+:104BC00082F8203023681B6FFBB9206907F0D6FDFF -+:104BD00010F1090F19D12268136F13F0020114D1DB -+:104BE00043F0020313670D4604EB8503D3F84C1220 -+:104BF00041B18B7933B94B7923B18B7C13B120460A -+:104C00003AF03ED90135082DEED123681D6F1DB154 -+:104C1000204612F079D976E0012384F82930204625 -+:104C200021F004D82368596B39B103234FF4807203 -+:104C3000009320462946134605E0032300932046AF -+:104C40004FF480720B461EF0BFDFA0680AF02CDD27 -+:104C5000236801221A7694F89D3173B120460CF036 -+:104C6000C1FDD4F840352046598E23F0DFDE002305 -+:104C700084F89D3120461DF0C3D9B4F85C17204656 -+:104C800021F04CDF206907F0DFFF236893F82F3015 -+:104C90001BB1D4F8340730F03DD8236893F8313095 -+:104CA0007BB1002504EB8503D3F84C1231B18B792D -+:104CB00023B94B7913B1204635F0FADE0135082DC2 -+:104CC000F0D1204615F00EDF204618F0EDFA012550 -+:104CD000D4F8AC114FF448720123A0680AF076DCD6 -+:104CE000204684F8F15125F0D1DD204614F072DF22 -+:104CF000204626F02DD950B1204626F007D920466F -+:104D0000294626F00DDB002001E06FF008003EBDD3 -+:104D1000D0F8403570B55D8E064605F44063B3F5B6 -+:104D2000406F22D1036893F8463013F0030F0BD085 -+:104D300005F47041D0F85C01B1F5805F14BF00212B -+:104D4000012141F0B7DA80B92846FEF36BF2044640 -+:104D50002846FEF367F244F430640E288CBF4FF40B -+:104D600080504FF400500443A5B2326B05F47043F9 -+:104D70005268B3F5805F14BF00230123934205D02E -+:104D8000D6F85C01012140F0B9DD0546D6F85C019A -+:104D9000294641F003DB80B905F47043B3F5805F29 -+:104DA00014BF38233C23F358346BD6F85C013363CB -+:104DB000012140F0A3DD34630546284670BDC0469E -+:104DC00070B50025044680F8E85124F0B7DDE36AA9 -+:104DD0002946986A8022FDF333F1206908F0BAF978 -+:104DE000D4F840012AF09EDCC4F8885670BDC04655 -+:104DF0002DE9F04390F8A03187B00446002B40F035 -+:104E0000ED8003681B7E002B00F0E880012380F812 -+:104E1000A031006907F0E6FE2269074692F8EA3001 -+:104E20005BB1D36ED3F8202140F2044302EA0303BE -+:104E3000B3F5806518BF012503E0106E0AF004FD8C -+:104E40000546002D6FD1D4F8680104214FF0B0DB86 -+:104E5000204621F0A3DE00B90137A94604EB09037F -+:104E6000D3F84C62002E59D096F80680B8F1000FA6 -+:104E700054D1304633F06ADC73793F18002B4DD0A3 -+:104E8000236893F83130002B3FD0D6F8CC3013F0A4 -+:104E9000010F3AD0204631460CF0B4FC23683F188D -+:104EA00093F89530002B39D0D4F86C122046BC31E1 -+:104EB00050F074DC0546002830D02046294622F008 -+:104EC0008BD82B7E13F0020F19D02846022150F008 -+:104ED000B7D8B17CD4F86C32D1F1010138BF0021D0 -+:104EE000082201920291204631460332BC33CDF8AC -+:104EF0000080CDF80C80CDF8108017F00FDED4F8CC -+:104F00006C22012382F8F03008E02046314639F067 -+:104F1000B7DF3F184FF47A6001F01EDC09F1040995 -+:104F2000B9F1200F9AD10025D4F8B434EA18136BE4 -+:104F300013B1506A98473F18343540F2AC439D4254 -+:104F4000F2D194F8F1314BB1A068D4F8AC110AF069 -+:104F500085DB00B90137002384F8F1312046FEF7E4 -+:104F60000DFB236800211976236B4FF0FF32C61921 -+:104F700018690DF0B3FD204615F08ADAD4F878529E -+:104F800007E00023291D606801220093FDF35AF712 -+:104F90002D68002DF5D1236893F82F3073B1631974 -+:104FA000D3F84C1239B18B792BB10B791BB1204658 -+:104FB0000CF028FC36180435202DF0D1D4F87C02F2 -+:104FC00010B10BF03BFE3618206907F0BDFD002341 -+:104FD000801984F8293084F8A03100E0002007B05F -+:104FE000BDE8F0832DE9F04F9BB005462598089267 -+:104FF0000793827AC37A0F4642EA0323269A00F186 -+:105000000C010C3A08980A9113930B92C27D837D90 -+:105010000DF1580943EA0223C3F3C70ABAF10E0F90 -+:1050200094BF002101210F91079918F0C1F8249A2B -+:1050300028460A32114609920F9A50F0B9DB002433 -+:10504000804615AE28462599269A4B461594169407 -+:1050500000961CF0DFDF30B928462599269A4B468A -+:1050600000961EF0D7DFB8F1000F06D0D8F8043054 -+:1050700013F0010F01D00C9427E00B990A9832220B -+:10508000FDF31CF3014620B14078023120F0E2DF4D -+:1050900058B90B990A980122FDF310F3014638B173 -+:1050A0004078023120F0D6DF10B101230C9301E0EB -+:1050B00000200C90B8F1000F07D00C9929B9D8F84E -+:1050C000043043F00103C8F804300A980B99032216 -+:1050D000FDF3F4F2044608B14378A3B92B6893F8C2 -+:1050E0003F3053B1B5F82606C3B2534503D0FEF3A3 -+:1050F00099F0504501D1012300E0002300225FFA1E -+:1051000083FB0D9211E02B6893F83F3043B1B5F863 -+:105110002606FEF387F0A378834201D1012300E045 -+:1051200000235FFA83FBCDF834B0BBF1000F01D14F -+:105130005B4602E03B1E18BF01235FFA83FA2B682F -+:1051400093F8463013F0030002D11090119024E040 -+:1051500095F8723263B9BAF1000F09D0D7F8D4329A -+:10516000DB8813F0200003D110901190129018E00A -+:105170000A990B9A284620F0DFDF0A9911900B9AC2 -+:10518000284620F0A5DF2B68109093F94C0020B141 -+:1051900028460A990B9A1DF0C9DC1290BAF1000F4B -+:1051A00069D02B6893F8463013F0030F63D0109B3F -+:1051B000002B60D0119800285DD019785A782846C5 -+:1051C0000FF0E0DEB5F82696064609F47043B3F515 -+:1051D000005F0CBF38233C23EC58D5F85C016168B4 -+:1051E00040F08CDA10F0080F01D0002104E094F8B0 -+:1051F000EC30191E18BF0121119A137813F0020325 -+:1052000017BF10981A464378C3F3800209F440632D -+:10521000B3F5406F18D1B5F82636B34202D100215C -+:105220000E912EE02B6893F82F30002B40F05B841A -+:105230003046FDF3F7F70446B5F82606FDF3F2F71E -+:10524000844240F0508414E0A9B1A2B106F4406356 -+:10525000B3F5406F0FD12B6893F82F3073B93046F8 -+:10526000FDF3E0F70446B5F82606FDF3DBF78442CC -+:1052700004D10E9605E000220E9202E000230E9368 -+:105280009A462B6B5B7D002B3AD0BBF1000F37D0D9 -+:1052900095F8723233B995F87432002B30D0BAF1E8 -+:1052A000000F2DD195F849365BB1159B002B08DD19 -+:1052B000169B1B7813F0040F03D0D5F8582604234F -+:1052C000136195F8493653B10C9850B9139911F000 -+:1052D000200F0ED1D5F858260423D36009E00C9A8C -+:1052E0003AB1159B002B08DD169B1B7813F0010FBC -+:1052F00003D0D5F8582604231362284625F06CDE27 -+:105300002B6893F8463013F0030F46D0BBF1000F23 -+:1053100043D095F8723233B995F87432002B3CD0F3 -+:10532000BAF1000F39D1B5F8263603F44063B3F56E -+:10533000406F14BF00210121109B13B90C9830B9A4 -+:1053400016E0109A937803F00303032B05D1D5F8E8 -+:10535000582604239361109B53B11098837803F06F -+:105360000303022B04D119B1D5F858260233D362B6 -+:10537000119A7AB1109B6BB111985A78037813F097 -+:10538000020F07D112F0040F04D019B1D5F8582636 -+:105390000423D362284625F0D1DE2B6893F82F3002 -+:1053A000E3B1D5F8FC341B78C3B10D99B1B92846E7 -+:1053B00011992FF01FDA88B128460D992FF01CDBC8 -+:1053C00028462FF00FDBB5F8263603F44063B3F51B -+:1053D000406F03D1284601212FF080DAB8F1000F89 -+:1053E00029D0D8F8F03033B300230B99824A0A98B9 -+:1053F00000931CF087DF41460246284620F0C0D9C2 -+:105400002B6893F8463013F0030F14D0119A2AB189 -+:10541000129B28460093109B41460AE0D8F80430BE -+:1054200013F4803F07D01198119A00904146284606 -+:1054300013461DF0DBDB95F87032002B00F06C8317 -+:105440000FB93E4601E0D7F8DC62BAF1000F00F078 -+:1054500083802B6893F8463013F0030F3DD0BB7C5C -+:1054600043B9B8F1000F08D1284609990F9A50F0B6 -+:10547000B9DA8046B8F1000F2FD01199C9B1D7F829 -+:10548000CC3013F4005F05D0B7F8343543F0200377 -+:10549000A7F83435129A109B009228464146119A7B -+:1054A0001DF0A4DBB7F8343523F02003A7F834351A -+:1054B0000DE0BB7C5BB9D8F8043013F4803F06D014 -+:1054C000119B284641461A4600931DF08FDB284663 -+:1054D0000A990B9A434620F079D9089928461EF07C -+:1054E0005BDA41B238461EF099DA38461EF0EED942 -+:1054F0000899284612F0E4DA0146384611F046DAF7 -+:10550000BB797BB9D7F8E032D7F8D422188A9B8AC6 -+:105510005085938573792BB9BB7C1BB1384601212B -+:1055200035F038DF0023B371F371BC7CA4B996F871 -+:105530008530012B10D186F88540D5F8400126F042 -+:10554000FDDF284639460F22234600940194029439 -+:105550000394049417F0E2DA002F5AD0BB79002BA1 -+:1055600057D1BB7C002B54D0259925988B784A784D -+:105570001B0443EA02230A781343CA78043143EA3E -+:1055800002698B784A781B0443EA022302791343A9 -+:10559000CA7843EA0264F26912B9336A13B935E092 -+:1055A000944204D3944231D1336A99452ED2DDF826 -+:1055B00090E0002300930193029303930493284601 -+:1055C000394616220EF1100317F0A8DA384608996A -+:1055D000079A259B24F0A2DFBBF1000F16D0FB79C0 -+:1055E00063B1BB7C23B107F1BC00FDF3B5F128B971 -+:1055F00007F1BC0104E0C0460FD4010007F1D60159 -+:10560000002228461346009222F02ADDC6F8209098 -+:10561000F461BAF1000F00F01F82BB79002B40F05B -+:105620009681BB7C002B00F0928114AB00932599EE -+:105630003846269A0DF1670316F016DBBDF85010B8 -+:10564000D7F8E462A7F8201595F8EB41002C65D156 -+:1056500000284FD03378022B19D138462146B6F8AE -+:1056600026900BF0DDFDB5F8303885F8324803B1EF -+:10567000F38438461EF0A6DFD7F8E432A6F8269069 -+:105680005B8B002B4AD0384611F062DA46E02B687B -+:105690005B6B4BB195F8FA3133B1B8F1000F14D010 -+:1056A00098F8D2300F2B10D0B27822B12846394664 -+:1056B00023F0D6D832E04FF0FF330093284607F1AD -+:1056C000BC01134622F0CCDC28E095F80D372BB353 -+:1056D000B3785BB1B8F1000F05D0D8F8043023F0EF -+:1056E0000063C8F80430384616F09CDB384623F0D7 -+:1056F000B9DD13E0337A23B1718911B9384623F04B -+:10570000DFDDD7F8E4325B8B43B13378022B05D170 -+:10571000336A012B02D138461EF040DFF3781BB10B -+:105720003846002123F0C0DC737A1BB138460021D3 -+:1057300023F0B2DE2B6B5B7D002B41D0139A284601 -+:10574000C2F3802124F0B2DD169A002A38D0159BCE -+:10575000002B35DDD5F8581691F90130B3F1FF3F34 -+:1057600009D11378C3F340020B78934203D0284643 -+:10577000012120F0FDD8169B1B7813F0040318BFFD -+:10578000012385F8463695F94636012B03D0D5F826 -+:1057900058361B690BB1002300E0012385F842361F -+:1057A000B8F1000F0CD0D8F8043023F00402C8F888 -+:1057B000042095F946361BB942F00403C8F80430BA -+:1057C0002B6893F8463013F0030F36D0109B002B54 -+:1057D00033D0D5F8582692F90630B3F1FF3F27D1E0 -+:1057E000109892F90520837803F003039A4204D0BD -+:1057F00028460B211A4620F0BBD810998B78C3F3AA -+:105800008002D5F85836DB79934203D028460D2123 -+:1058100020F0AED8109A9378C3F30012D5F858361A -+:105820009B7A934209D02846102120F0A1D804E0A9 -+:10583000012B0CBF032300235371D5F85C01B5F88D -+:10584000261640F073DB90B1D5F85C01B5F826164A -+:105850003FF0ACDF2B6B18690DF068F9B5F8263610 -+:10586000834204D1002128460A461EF095DBB8F198 -+:10587000000F3FD0D8F8043013F0400F00F03F8104 -+:105880000A9B0B981893179006E02846214618AA01 -+:1058900017AB1DF063DE40B918981799DD22FCF3B1 -+:1058A0000DF704460028F0D122E1A11C0E79012E4B -+:1058B00040F025818A7995F80C3202F00F0203F04E -+:1058C0000F039A4200F01B8105F500740634204650 -+:1058D0001822FCF351F32B6893F830303BB1D5F824 -+:1058E0003407214600F563701822FCF345F338466F -+:1058F000314602E128460A990B9A10F087DC01280C -+:1059000002D128460EF018DA0E9929B195F86D35B6 -+:1059100013B9284618F0DED8259A079B0092D5F8CF -+:105920004C013946089A49F07DDAD7F8CC3013F4A7 -+:10593000005F00F0F180259B269800930190394686 -+:10594000D5F84C01089A079B4AF0C2D9E4E0BB7C29 -+:10595000002B40F081800C9909B1012102E0139ADB -+:10596000C2F34011CCB2B8F1000F15D0D8F8043012 -+:1059700014B143F0040301E023F00403C8F8043039 -+:105980000B990023664A0A9800931CF0BBDC414641 -+:10599000024628461FF0F4DE2B6B5B7D13B3159B8C -+:1059A000002B11DD169B1B7813F0040F03D0D5F8E4 -+:1059B000582604231361169B1B7813F0020F03D0A3 -+:1059C000D5F85826042353620C9B1BB9D5F85826EA -+:1059D0000433D3611CB9D5F858260423D360284674 -+:1059E00025F0FADA2B6893F8463013F0030F00F035 -+:1059F0009380109840B1837803F00303032B03D105 -+:105A0000D5F85826013393621199C9B1119BB5F8A5 -+:105A100026165A781B7843EA022010F0100F03D1A3 -+:105A2000D5F858260423536310F0020F08D101F46F -+:105A30004063B3F5406F03D1D5F8582604231363B0 -+:105A4000109828B90C9919B1D5F858260423536138 -+:105A5000284625F073DB5FE095F85735002B5BD0C7 -+:105A6000BBF1000F58D0139A12F0020F54D00A98CD -+:105A70000B990022FCF322F6034600284CD028465E -+:105A8000991C5A7839F06EDC0446002844D0837C97 -+:105A9000002B41D10899079A16F0B4DE00283BD0BC -+:105AA000259BD4F8D06226980093249B019003F1A3 -+:105AB0001002284608990123029620F053DC024682 -+:105AC00050BB296BD5F86036503106F138009B7811 -+:105AD0004BF054DA269808990090079A2046259BA7 -+:105AE00034F034DD18E000218A460E91FFF7C9BB7F -+:105AF000022385F80E32384601211CF051D90023CB -+:105B00000B990A98064A00931CF0FCDB41460246BA -+:105B100028461FF035DEEDE61BB0BDE8F08FC0462D -+:105B20000FD401002DE9F04FD2F81080C1B0D8F8A1 -+:105B3000D8A2064609910892DAF82C00DAF830105B -+:105B400000220793FCF3BAF520B1831C109342782E -+:105B50000B9205E0099A099B093210921B7A0B936C -+:105B60002CAF002128223846FCF36AF200212822BB -+:105B700022A8FCF365F2DAF830100122DAF82C00E2 -+:105B8000FCF39CF5DAF8301004463222DAF82C00E7 -+:105B9000FCF394F505463CB16278102A04D8381D10 -+:105BA000A11C2C92FCF3E8F13DB16A78102A04D8CC -+:105BB00023A8A91C2292FCF3DFF1099AD38813F0E1 -+:105BC000010F17D0316B4B7DA3B10A6D2CAC201D9A -+:105BD00054312C92FCF3D0F1D8F8CC3013F4005FA0 -+:105BE00005D0D6F84C014146224649F0E3DF0023B8 -+:105BF000229309E022AB0093099B304603F138025F -+:105C000041462CAB20F022D9B8F86250DAF82C408B -+:105C1000B5F5806FDAF8307059D0B5F5006F04D162 -+:105C20000022934611920C9257E020463946FDF32C -+:105C300051F3119020B143784FF0000B0C930BE01F -+:105C4000204639463022FCF339F5834610B9119AC3 -+:105C50000C9201E043780C93402D09D0802D07D0A1 -+:105C6000102D05D0B5F5807F02D0B5F5007F33D17A -+:105C7000D8F8582040F2371302EA030363B30C9AB2 -+:105C8000BBF1000F08BF1422402D0C922ED14FF013 -+:105C900000094F4616E0162307FB03F303F5B47320 -+:105CA00008EB03040998211D0622FCF349F140B9D1 -+:105CB00040AB03EB890204F10A0342F8B83C09F156 -+:105CC00001090137D8F8CC329F42E4D310E000221A -+:105CD000934611920C9200E045B1D8F8582040F25A -+:105CE000371302EA03030BB118230C934FF000099A -+:105CF00040F2EE5301933FAB0293079B099A002BAE -+:105D000014BF20210021304608F1C20300921CF08C -+:105D100053DB0D9030B930460D99B8F80C2332F0B2 -+:105D2000DDDE83E23F9A304602F5BC630E330A9211 -+:105D30004146099A0E93FDF707FB0A9A1070C0F3CB -+:105D40000F2050709AF8223093709AF82330D37055 -+:105D5000131D3F93079B8BB10AF124042046FCF3EB -+:105D6000FBF510B93F98214602E03F9808F1D601B3 -+:105D70000622FCF301F13F9B06333F933F9A00213B -+:105D80000F921046109B0B9A26F0EED92DAB0121F5 -+:105D90002C9A3F9026F0E8D90C9B3F90002B7CD0AA -+:105DA000BBF1000F11D0B9F1000F03D030465946B6 -+:105DB000FDF7F6FA3F9C5946204617F0A7DC3F90C6 -+:105DC0009BF80130A346637019E0402D09D0802D67 -+:105DD00007D0102D05D0B5F5807F02D0B5F5007F36 -+:105DE0005BD1A649834617F091DC099B3F9003F1F4 -+:105DF0007B02304641460BF1040313F0F5DA402DE7 -+:105E000009D0802D07D0102D05D0B5F5807F02D0A8 -+:105E1000B5F5007F41D1B9F1000F01D14C4626E024 -+:105E20009BF801300BF1020202F80390D7184FEAF9 -+:105E300019237B709BF80130002402338BF801306A -+:105E40003F9B02333F9312AB07EB041053F824102F -+:105E500002301022FCF390F09BF801300134103333 -+:105E60008BF801303F9B10334C453F93EBD1D6F874 -+:105E70006C32D3F8D8325B68022B0ED16CB10022A1 -+:105E800000920192CDF808B09BF801303046023301 -+:105E90000393572113461DF00BDE229A2AB13F9837 -+:105EA000322123AB26F060D93F90DAF82C401CE079 -+:105EB0006278C1F102031B199B18671C83421CD82E -+:105EC000119BA34219D02378012B0BD9302B09D079 -+:105ED00002323F982146FCF34FF03F9B6278023339 -+:105EE0009B183F933B78A21CD41834B1DAF82C10DD -+:105EF000DAF830000B189C42DAD3336893F8463056 -+:105F000013F0030F18D0089A536813F4803F13D08E -+:105F1000326B0DF1DB041368404621466532022BDB -+:105F200014BF0023012326F081D83F982D211A2287 -+:105F3000234626F019D93F9096F8653633B106F519 -+:105F4000CC613F98043117F0E1DB3F90336893F860 -+:105F5000463013F0030F1FD0089A536813F4803FA4 -+:105F60001AD0326B0DF1DB0113684046022B14BFCF -+:105F700000230123653226F059D83F990E9B8B42AE -+:105F800001D2002202E00E9BC1EB030230460DF16C -+:105F9000DB0325F009DF3F9033685B6B4BB3099A55 -+:105FA000D38813F0040F24D00DF1F50034490322F7 -+:105FB000FBF3E2F702238DF8F83000238DF8F93077 -+:105FC00001338DF8FA3096F8FA313BB1099A92F91B -+:105FD0006A30002B02DA96F80A3700E000238DF8C9 -+:105FE000FB303F98DD2107220DF1F50326F0BCD8E8 -+:105FF0003F90B5F5806F02D0B5F5006F06D1D8F8A7 -+:106000002C3543B33F98D8F8281505E00C9B13B303 -+:10601000119A2AB13F98114617F078DB3F901AE0A9 -+:10602000402D18D0802D16D0102D14D0B5F5807FBE -+:1060300011D0B5F5007F0ED03F9C1249204617F0D5 -+:1060400065DB099B3F9003F16B023046414604F14A -+:10605000080313F0C9D96B1E9BB2012B03D9042D81 -+:1060600001D0082D10D1099A506E002838D0B2F80E -+:1060700068100C300C39FDF32DF11BE0CCD28500FB -+:1060800017D40100E2D28500402D09D0802D07D021 -+:10609000102D05D0B5F5807F02D0B5F5007F1FD15A -+:1060A000099B586EE0B1B3F868100C300C393022FF -+:1060B000FCF304F3A0B1D6F86C32D3F8D8325B68A5 -+:1060C000022B0DD14378102B0AD902330022029003 -+:1060D0000393304657210123009201921DF0E8DC22 -+:1060E000D8F8583013F0040F01D004230EE013F059 -+:1060F000020F01D0022309E013F0010F01D00123A8 -+:1061000004E013F4807318BF4FF48073089A13648B -+:10611000336893F8463013F0030F2DD0089A136CB0 -+:10612000013B012B09D8536813F4802F05D0114689 -+:106130003046062224F0B4DD1EE0089A536813F4BA -+:10614000802F19D011463046062224F04DDD30460E -+:1061500016F07ADF012801460ED1D6F8F83742F260 -+:106160000E721B88013B9BB2934202D83046013924 -+:1061700000E0304628F0AADF3F9C0E9BA34201D2EC -+:10618000002302E00E9AC4EB020300932023019344 -+:10619000002123464FF0FF32404639F0C5DF0F9B08 -+:1061A00000273F90C01A03930490414655223B4676 -+:1061B000304600970197029716F0B0DC0A9A3F9B91 -+:1061C000A2F11805C5EB0304DAF834100D9B9C828C -+:1061D00021B17068DAF8382000F08ADD0A9A706818 -+:1061E000C5EB0203E41A214600F072DDCAF8340060 -+:1061F00040B1079BCAF838408AF83C300A992246D9 -+:10620000FBF3BAF6099A3046B2F862300197C3F34D -+:10621000401300930297089B0D99D6F804281FF0AD -+:1062200081DC0D9B002808BF00230D930D9841B021 -+:10623000BDE8F08F2DE9F04F95B0079119690692EE -+:1062400005930A9101F106098A7999F80130064609 -+:1062500042EA0323069A0893C0F87828C3F381051D -+:1062600013465B79127942EA0323099303F003038F -+:10627000022B08D1089C14F4004F04D0D5F101037F -+:1062800038BF002300E00023DBB205990B930B9A83 -+:106290008B8AA3F10A0893001DB918339845C0F200 -+:1062A000A081089B03F0FC07A42F03D0842F01D00A -+:1062B000942F03D1B8F10F0F40F3938199F8043074 -+:1062C00009F1040A13F001030C9303D00024109485 -+:1062D0000D9408E05146304639F020D8011E18BF11 -+:1062E000012110900D9125B1002293460E920F923C -+:1062F00010E009F110043046214638F0EBDF0E9033 -+:1063000010B183460F9505E03046214639F04CD850 -+:1063100083460F9096F8C83123B9326892F82C3032 -+:1063200033B925E030460699059A00230FF068DD61 -+:10633000A42F03D0842F01D0942F01D10D9B53BBE8 -+:10634000802F28D0502F26D0002D40F006840D9CA1 -+:106350000CBB5046FCF3F0F2002800F0FE83BBF1CA -+:10636000000F18D109F11000FCF3E6F298B9F4E33C -+:106370000C9981B90D9B43B192F838305BB155B996 -+:10638000BBF1000F07D1109C2CB9D2F88C20936F71 -+:1063900001339367E1E396F8C8317BB9BBF1000F95 -+:1063A00001D05C4601E0D6F86C4294F8E5302BB1A0 -+:1063B00030460699059AA3680FF022DD012D10D111 -+:1063C000C42F0ED0D42F0CD009F10A00FCF3C4F274 -+:1063D000002840F0C28399F80A3013F0010F40F012 -+:1063E000BC83059930460B69A1F8148006330B6114 -+:1063F00033684946D3F88C20D36C0133D3641FFA39 -+:1064000088F30093069A13AB12F072D830B1336858 -+:10641000D3F88C20D36F0133D3679EE3139A12B164 -+:1064200033689B6A1362012D39D1059A059B106967 -+:10643000998A00F11002059C1A61A1F11003A38250 -+:106440000B9B2BB100F11402A1F114032261A38272 -+:106450000599A42F8C8A0FD113990B699B79002B76 -+:1064600000F07B8391F8DF30002B00F0768330461C -+:10647000089A2FF0DDDD70E3336893F84230002B8B -+:1064800000F06B83842F02D0942F40F06683D6F8FF -+:10649000400113992346009728F0C2DF5DE3069A76 -+:1064A000937DD27D43EA0223C3F3C7030E2BD4BFEF -+:1064B0000023012311930C9B002B62D199F8163015 -+:1064C00099F8172043EA0228139B33B9304609F1A3 -+:1064D0000A01119A4FF06CD91390089C14F4006AC9 -+:1064E00005D0139B1BB1B3F8BC30434525D0139B9B -+:1064F0000BB1A3F8BC80139B8BB142E006EBC20347 -+:1065000003F5F3642046FCF327F270B909F10A00A1 -+:1065100021460622FBF314F5013508B906E01D46B5 -+:1065200096F8E837EAB29342E8D20024BAF1000FB5 -+:106530000CD064B1E388434521D13368D3F88C2073 -+:10654000D2F8BC310133C2F8BC3106E3BCB996F8CD -+:10655000E83709F10A0106EBC30202F5F3640133DF -+:1065600086F8E83706222046FBF306F596F8E8178A -+:106570000A23B1FBF3F202FB131386F8E837A4F801 -+:1065800006800D9961B10E9A52B19BF806303BB965 -+:10659000DBF8E4321B7A1BB15846089910F0B4DEE0 -+:1065A000059B059C1869998A00F118021A619246A8 -+:1065B0000B9AA1F11803A38232B100F11C02A1F1E0 -+:1065C0001C032261A3829246059C0899099BB4F89A -+:1065D000148011F48044C3F3C0150DD0B8F1070F37 -+:1065E00006DC3368D3F88C20536E01335366B4E273 -+:1065F000B02F40F0B28227E0502F00F087800ED8F5 -+:10660000202F00F0768205D8002F00F07282102F24 -+:1066100045D0A2E2302F42D0402F56D09DE2B02F7D -+:106620000ED006D8802F00F09080A02F00F055816A -+:1066300093E2C02F00F0AC81D02F00F07B828CE27F -+:10664000B8F1050F40F38382BBF1000F00F08582A3 -+:106650009BF80630A3B19BF80430002B00F07D823C -+:10666000069ACDF800800195137CD6F8340703F024 -+:106670000803029359464A46534604F06DFE6CE205 -+:10668000D6F8403593F93430002B00F06682584636 -+:10669000494652464346009532F09ADC5DE2B8F135 -+:1066A000050F40F35482BBF1000F00F056829BF8B7 -+:1066B0000630002B40F05182139B58460093494608 -+:1066C0005246434632F042DA47E2336893F8953057 -+:1066D00013B996F872326BB108F118030393304680 -+:1066E0002C2109F10A02234600940194CDF8089068 -+:1066F0001DF0DED9069B0A9C0093D6F84C01494652 -+:1067000052464346019449F00FDB26E2B8F10B0FE5 -+:1067100040F31D82D6F84C015146424649F0BEDC9A -+:10672000D6F868319B79002B00F017820D9900296B -+:1067300000F01382304606990A9A4B46CDF800A025 -+:10674000CDF8048010F042DF07E2B8F10B0F40F300 -+:10675000FE810A9B30460E99069ACDF80090CDF83E -+:1067600004A0CDF80880FEF73DFCD6F868319B798F -+:106770004BB1304606990A9A4B46CDF800A0CDF8A9 -+:10678000048010F023DF96F87232002B2ED19AF895 -+:106790000A3013F0010F29D030465146424617F017 -+:1067A00039D818BB069A937DD27D43EA0223C3F3FE -+:1067B000C7040E2C8CBF0023012363B10AF10C0027 -+:1067C000A8F10C010322FBF379F778B143786BB1A0 -+:1067D0008378A3420AD1336B18690CF0A7F9C0B2D1 -+:1067E000844203D1D6F868014EF0AAD80F9B0BB1B2 -+:1067F0001D4607E0304609F1100138F0D5DD0546A9 -+:10680000002846D0AA79002A43D10AF10C00A8F149 -+:106810000C01D5F8D842D5F8DC72FBF34FF7A2682B -+:1068200081460B2A08D1284606990A9A5346CDF884 -+:10683000008033F08BDE0DE0336893F831304BB1DC -+:106840000F2A07D1284606990A9A5346CDF80080A8 -+:1068500034F04CDAAB7CE3B197F85A30CBB1D6F8D0 -+:106860006801494601224EF013D930B197F85930EA -+:106870001BB9013387F859300BE0D6F86801494657 -+:1068800001224EF005D920B997F859300BB187F89D -+:1068900059000E9C002C00F06081DBF8D8329B6818 -+:1068A0000C2B40F05A815346584606990A9A23F019 -+:1068B00035DE5846002131F0FFDF336893F82F3082 -+:1068C00023B1D6F834072EF025DA46E1DBF8E432BE -+:1068D000584699780AF0A4FC3FE1B8F1010F40F363 -+:1068E0003681BBF1000F00F038819BF80630BAF812 -+:1068F00000505BBB3046139920F06EDB1398037E8B -+:1069000013F0020F14D002214EF09ADB139B1B7E72 -+:1069100013F0080F0CD130465946224609F10A03FC -+:1069200000950194CDF808A0CDF80C800AF0D8FAB3 -+:106930000E99002900F01181DBF8D8329B6813B161 -+:10694000584631F003DF58460321ADE013990B6937 -+:106950005B4540F00281304620F03EDB1398037E19 -+:1069600013F0020F10D012214EF06ADB3046594668 -+:10697000224609F10A0300950194CDF808A0CDF84C -+:106980000C800AF0ADFAAFE010214EF059DBE4E0E4 -+:10699000B8F1010F40F3DB80BBF1000F01D05F467F -+:1069A00004E0109A002A00F0D880174600252C46F3 -+:1069B0003319D3F84C1241B109F11000BC31062251 -+:1069C000FBF3BEF2002808BF01250434202CEFD1D0 -+:1069D000002D00F0C280139BBAF8004033B9304656 -+:1069E00009F10A01119A4EF0E3DE1390139911B1E7 -+:1069F000304620F0F1DABB791398002B57D10028EC -+:106A00003CD012214EF01CDB1398037E13F0010FD3 -+:106A100003D1436813F0005F30D001214EF010DB4A -+:106A2000A4F10D039BB2092B07D83368D3F88C204F -+:106A3000D2F8F8310133C2F8F83197F91030022B4F -+:106A400003D1F8680E2152F08DDD13990B7E13F0FF -+:106A500004020ED100944B683046C3F34073019397 -+:106A6000394609F10A03CDF808A0CDF80C8032F0C0 -+:106A7000B7DC139A536823F0005353600E9B002B2E -+:106A80006BD09BF81230002B67D0DBF8D82253680C -+:106A9000022B02D19368082B5FD8936813B1584634 -+:106AA00031F054DE5846022134F074DC55E0002801 -+:106AB00053D00169B94250D1D0F8F0301BB14368CE -+:106AC00023F400734360139B1B7E13F0010F44D02B -+:106AD0000022304609F10A0300940192CDF808A083 -+:106AE000CDF80C8032F07CDC304613994EF068DE35 -+:106AF00033E0B8F1030F2ADDBBF1000F2DD09BF876 -+:106B0000043053B39BF806303BB309F110000BF18E -+:106B1000BC010622FBF314F2F8B9139BD6F8340734 -+:106B2000019359464A465346CDF8008002950AF033 -+:106B300061FC12E00A99069C0291304613994A467C -+:106B40005346CDF80080019410F038DC05E033683E -+:106B5000D3F88C20136F013313670798059900222F -+:106B600000F0DED815B0BDE8F08FC0462DE9F04F3B -+:106B7000436899B0164689460493918B96F82A305B -+:106B8000126880460292D9F810A00BB9059302E072 -+:106B900096F82220059296F82C00B0B911F4006FF7 -+:106BA00013D0059A09EB4203B3F8AC20B6F87E3057 -+:106BB0009A420AD1D8F80030D3F88C20D2F8BC31F0 -+:106BC0000133C2F8BC3100F065BC9AF80630C1F35D -+:106BD000802B7BBBDAF8E442237A6BB160B9BBF15E -+:106BE000000F09D199F8D230726A134113F0010FE6 -+:106BF00002D1504610F088DBD8F800305B6BCBB187 -+:106C0000237EBBB196F82A30A3B196F828308BB119 -+:106C10000021504621F0BEDEDAF8CC3013F4005FDC -+:106C200008D0B38B13F4005204D1D8F84C0151466C -+:106C300048F0AAD9338C13F0040440F02B84B38BB2 -+:106C400003F4804373634BB9DAF8582040F23713EA -+:106C500002EA03032BB39AF8603013B3059BB463C5 -+:106C60000093404604994A4633464FF051DF08B13D -+:106C700022460EE0736B23B1D9F86C310133C9F8A9 -+:106C80006C31D8F8003093F89530002B00F0028476 -+:106C90000122736B33B1D9F868310133C9F8683117 -+:106CA00000E0002296F82C300BB1002708E005998F -+:106CB00009EB4103B6F87E10B3F8AC70A3F8AC1042 -+:106CC000D8F8000090F8953013B1002A40F0E28324 -+:106CD00096F82C50002D40F00081B6F87E20059BE0 -+:106CE00012F00F0C4FEA830E40F081800EEB090783 -+:106CF000F96E41B104982A4600F012D8FD66C7F833 -+:106D00008C50C7F83051BBF1000F00F0E68073697A -+:106D1000F168FB66D8F800307269DB6903919C6802 -+:106D20001169D368908ACB1892681B189B1A0918AE -+:106D30005B1AA34223DA0498214600F021D8F866B2 -+:106D4000002800F0A7837369006919699C689A8A12 -+:106D5000C4EB0104091BA218FBF30EF17169FA6E72 -+:106D600008698B68C01A13691B181361938A1B1A70 -+:106D700093828B8A049893822A46FFF3D1F7D8F83E -+:106D80000030D8F82828DB6903999B68AA489B1A29 -+:106D90005B1A063BC7F88C3071680822FBF3D0F011 -+:106DA00050B1A64871680622FBF3CAF048B973686F -+:106DB000DB88B3F5407F04D1D9F8043043F00803F1 -+:106DC00003E0D9F8043023F00803C9F804309C48E4 -+:106DD00071680822FBF3B4F0D9F8083010B943F019 -+:106DE000200301E023F02003C9F8083075E00EEB22 -+:106DF0000904E16E11B9D0F88C2017E022F00F02DF -+:106E000027F00F039A4204D107F00F0301339C458A -+:106E100010D02A460498FFF383F7D8F80030E566CF -+:106E2000D3F88C20C4F88C50C4F83051136E013361 -+:106E300013662FE3B068D4F88C309842E9D8049BED -+:106E400009EB0E020090019340468C3273680CF0FF -+:106E5000C7D8049871692A46FFF362F7BBF1000FA7 -+:106E60003BD1E36EC4F88CB07361C4F86CB0736945 -+:106E7000C4F830B11A69998A02F118037360A1F15C -+:106E80001803B36096F829303260F1602BB102F13B -+:106E90001E037360A1F11E03B36096F82A3043B15C -+:106EA0007368059902337360B36886F82210023B59 -+:106EB000B36032681378527843EA0223B383736B6A -+:106EC0005BB1B16B49B191F90E2073689B18736087 -+:106ED00091F90E20B3689B1AB360B36B73B11B7A40 -+:106EE000042B03D1404631464FF0C0DEB36B1B7A12 -+:106EF0000B2B03D1404631464FF0D4DFBBF1000FDE -+:106F000040F02283D8F8003093F89530002B73D0EE -+:106F1000DAF808309B7913F0010F40F0DA826BE069 -+:106F200010F4000F00F4E06310D01B0A043B012BA7 -+:106F3000444A00F07F0004D8142300FB0323DA68DE -+:106F400014E0142300FB03239A680FE01B0A043BA0 -+:106F5000012B3C4A00F07F0004D8142300FB0323DC -+:106F60005A6803E0142300FB03F39A584FF4FA73B2 -+:106F7000B2FBF3F007E000F07F034FF4FA7203FB7B -+:106F800002F3B3FBF2F0C0F307238DF825300DF1C7 -+:106F90001B05C0F307438DF824008DF82630012728 -+:106FA000030E316805F10F0018228DF827308DF897 -+:106FB0002970FAF3E1F796F82F30DBB19DF82B201A -+:106FC0009DF82A3005F1190443EA022343F40073C3 -+:106FD0008DF82A3021461B0A062205F11F008DF884 -+:106FE0002B30FAF3C9F7D8F86C122046BC310622D0 -+:106FF000FAF3C2F7BB4601E04FF0000BD8F80030BF -+:1070000093F8953013B91C461A4602E00DF11B04A3 -+:107010002D2273695B6A13F0400F15D013F0800FB7 -+:1070200000F038820092D8F83C01494632462346A7 -+:1070300029F00EDE88E2C046401E86002CD40100F6 -+:10704000481E86008418860031680DF15A07043105 -+:1070500006223846FAF390F7316815AD0A31062258 -+:107060002846FAF389F731680DF14E0420461031B5 -+:107070000622FAF381F796F829302BB1316812A86D -+:1070800018310622FAF378F7B38B13F4807F03F4F8 -+:10709000007305D1002B14BF23462B46776704E00D -+:1070A00074670BB9356701E012AB33677468BBF1E5 -+:1070B000000F00F0EE803368F3662378AA2B23D10B -+:1070C0006378AA2B20D1A378032B1DD1E378DBB9F9 -+:1070D0002379CBB9637943B9A379E179404641EA91 -+:1070E00003210BF0F1DB50B10EE0F82B0CD1A379AA -+:1070F000E179404641EA03210BF0E6DB20B1A279B9 -+:10710000E37943EA022500E03589D8F8003093F8A6 -+:107110009530D3B1DAF8E0305BB9736BABB9DAF81C -+:10712000582040F2371302EA030373B19AF8603033 -+:107130005BB1059A40460192494652463346009556 -+:107140000DF022DA002840F0A581B36B6BB11B7AF9 -+:10715000012B0AD0032B08D0404604994A463346F7 -+:1071600009F0DEFE002800F09581736F1B7813F0A4 -+:10717000010F08D0D8F80030D3F88C20D2F8D031E5 -+:107180000133C2F8D031B36B33B11B7A022B03D178 -+:10719000404631464FF06ADD726B22B996F82A30CC -+:1071A00023B3144602E0B36B93F90E4096F82A30ED -+:1071B0005BB1336802341A78597842EA012222F02E -+:1071C000800292B21A70120A5A707368581E03E055 -+:1071D00063421B5C00F8013971690A699042F7D279 -+:1071E0008B8A12191B1B0A618B82326096F82F3032 -+:1071F000BBB130684278037800F10A0443EA022305 -+:1072000043F4007303701B0A4370214606221030BA -+:10721000FAF3B2F6D8F86C122046BC310622FAF323 -+:10722000ABF69AF9103093B148F68E039D420ED119 -+:107230003168726BDAF80C001231003A18BF012283 -+:107240000AF1180351F0AEDE002840F02381716985 -+:107250000A698B8A9B18CA68D21A2C2A40F21A81B2 -+:1072600000238DF829308B8A08692D2218180DF11A -+:107270001B01FAF381F6716996F82220CB8A02F09D -+:10728000070223F007031A43CA8296F829200091C7 -+:10729000FAE0D6F814B02378DBF81070AA2BC7EB0D -+:1072A000040529D16378AA2B26D1A378032B23D1F7 -+:1072B000E3780BBB2379FBB9637943B9A379E1790F -+:1072C000404641EA03210BF0FFDA50B114E0F82BFD -+:1072D00012D1A379E179404641EA03210BF0F4DAB7 -+:1072E00050B17269A91F7B18CBF81030938A5B1AD2 -+:1072F00093821369F36628E0DAF8583013F0200F10 -+:107300000FD0204692490822FAF31AF648B972695A -+:10731000281D1169938A09181B1A11619382F1665D -+:1073200013E07269A5F10E00938A11691B1A93820A -+:1073300033890918116103F0FF021B0A43EA022393 -+:10734000F1660B73C3F30F234B73B36B6BB11B7AF3 -+:10735000012B0AD0032B08D0404604994A463346F5 -+:1073600009F0DEFD002800F09580B36B33B11B7A85 -+:10737000022B03D1404631464FF078DC0622716F74 -+:10738000F06EFAF3F9F5F06E06220630316FFAF37B -+:10739000F3F5716996F82220CB8A02F0070223F0F8 -+:1073A00007031A43736FCA821B7813F0010F08D0CA -+:1073B000D8F80030D3F88C20D2F8D0310133C2F89D -+:1073C000D0319AF8613093B199F8183013F0100F5A -+:1073D0000DD1F36E1A7B5B7B43EA022348F68E02E3 -+:1073E000934204D073695B6A13F0100F52D09AF87D -+:1073F0006530BBB199F8183013F0100F12D1F36E4D -+:107400001A7B5B7B43EA022248F6B4039A4209D016 -+:10741000263B9A4206D073695B6A002B02DB13F0AD -+:10742000100F37D09AF8063023B9DAF8E422013386 -+:1074300082F82A3098F83238013388F832389AF9CD -+:107440001030EBB1F16E0B7B4A7B42EA032248F627 -+:107450008E039A4214D10B8A03F0FF021B0A43EAFF -+:107460000223B2680C3A934214D8726BDAF80C001B -+:10747000003A18BF01220AF1180351F093DD48B910 -+:10748000736996F82920009340464946736F1FF0B0 -+:107490007BD959E0D8F80000436BA3B171692D4A3C -+:1074A000CB8AD0F8904003F00703D25C2A4B0498B3 -+:1074B0009B5C04EBC304636EA56E01336366FBF350 -+:1074C000A9F64019A066049871690022FFF328F418 -+:1074D0003AE0D8F8303005991A8940468DF81B20DB -+:1074E000130A120E8DF81C308DF81E200023B2698D -+:1074F0008DF81D30937DD27D43EA0223C3F3C70389 -+:107500008DF81F3009EB410393F8AC30D6F88010AA -+:1075100003F00F0301338DF828301CF03DDA029A96 -+:1075200040B2030E8DF82000911FD6F880008DF830 -+:1075300021308DF822308DF8233015F039FE10F00F -+:10754000006F7FF4EDAC16E519B0BDE8F08FC046D2 -+:10755000F7E38500C4D2850098E085002DE9F04F5F -+:107560000024A7B08DF832408DF83B408DF83840AC -+:107570008DF870408DF83F409A4609939B8A0546E6 -+:10758000212B02911746259412940D940A9224926D -+:107590001B9450D9DAF810901046494615F008FEB1 -+:1075A00009F1060203900492527899F8063043EAF2 -+:1075B0000223ADF82C30C3F38103ADF82E30BDF8B3 -+:1075C0002C30C3F3031203F44073B3F5407F14BFB0 -+:1075D000002301238DF83930BDF82E30ADF830206E -+:1075E000022B0ABFBDF830302346C3F3C0038DF829 -+:1075F0003A303B7903F00303022B08D1BDF92C305C -+:10760000002B04DABDF83030C3F3C00300E00023E0 -+:10761000D9B29DF839009DF83A308DF83B1000281A -+:107620000CBF2222282203B1023201B10432099B8D -+:107630009B8A934206D22B68D3F88C20536E013379 -+:107640005366A5E304990B7903F001038DF83C30F0 -+:1076500020B100231E468DF8403015E0BDF82C30D7 -+:1076600013F4807F01D0043105E013F4007F01D0D2 -+:107670000A3100E01031284637F02CDE031E18BF17 -+:10768000012306468DF840309DF83C303BB9049903 -+:107690002846043137F042DE08B1012400E000241E -+:1076A00095F8C83123B92B6893F82C3033B92FE003 -+:1076B00028463946099A00230EF0A2DB2B6893F87E -+:1076C0003F300BB98DF8403054BBBDF82C3013F46B -+:1076D000807F05D19DF83C3013B19DF840303BBB15 -+:1076E0009DF8393013B19DF83C300BBB2B6893F8F3 -+:1076F0002C30002B00F04C839DF84030002B00F024 -+:107700004783B379002B40F043834FF0010B11E026 -+:107710009DF83C301BB9002C00F03A8300E03CB1EE -+:107720009DF8393023B99DF84030002B00F03083AC -+:107730004FF0000B2B6893F895304BB346B39DF890 -+:107740003C30D6F8DC405BB914F0010F00F0208328 -+:10775000049806F1C20104300622FAF3F1F314E0B2 -+:1077600004980430FBF3E8F020B114F0080F00F0A7 -+:107770000F830DE014F0040F0AD114F0020F00F093 -+:107780000783284604990EF0A7DA002840F000830A -+:10779000099A136906331361938A063B9382049A0C -+:1077A00002F1180305939DF8393013B102F11E035D -+:1077B000059300238DF83D309DF83A306BB3059B5F -+:1077C0005A781B7843EA0221C1F3C0138DF83D308B -+:1077D0007BB126B196F81935002B40F0D98295F887 -+:1077E000CF31002B00F0D482099A536A43F0400352 -+:1077F0005362844B01F007028DF832209A5C824B71 -+:107800009B5C0D93C1F300138DF83830059B023358 -+:1078100005939DF832308DF870309DF83D3023B9D6 -+:10782000099A938A043B938206E002980999FBF334 -+:1078300069F1838A043B8382099A059C938A1269C1 -+:107840000793A41A1B1B514602980693FBF3E2F41C -+:107850000499001B08908B7DCA7D43EA0223ADF892 -+:107860008E30BBF1000F2ED1079B284600933A467D -+:1078700025AB10F03DDE002840F08A82BDF82C30A8 -+:1078800013F4407F3BD1BA7DFB7D049942EA032289 -+:10789000C2F3C70228460A310E2AD4BF00220122B1 -+:1078A0004EF0A0D8259030B92B68D3F88C20D36E39 -+:1078B0000133D3666CE20369D3F8CC30C3F3C01351 -+:1078C0008DF83F301BE0BDF82C3013F4407F16D00C -+:1078D0009DF839309BB9259B8BB9BA7DFB7D284635 -+:1078E00042EA0322C2F3C7020A310E2AD4BF0022A1 -+:1078F00001224EF077D82590002800F04982259B80 -+:107900001C69D4F8DC82BBF1000F23D19DF839301B -+:1079100003BB9DF83C3023B1BDF82C3013F4807FBD -+:1079200011D1A379BDF82C201BB112F4807F0AD0AD -+:1079300010E0A37C02F44072002B14BF4FF40073DC -+:1079400000239A4206D02B68D3F88C20936D013324 -+:1079500093651DE295F82D370AF1240A33B99DF895 -+:107960003F1019B9A3790BB10E4608E028463946F5 -+:107970001CF012D8C0B246B208B18AF80900A37947 -+:10798000FBB99DF83F30E3B9314620461CF046D89C -+:1079900020461BF09BDF3946284610F091D801465F -+:1079A00020460EF0F3DF9DF8403053B1A37C43B185 -+:1079B000E37933B198F805301BB92046012133F043 -+:1079C000E9DC95F82D3733B99DF83F301BB9259B7D -+:1079D000D3F8FC3073B16EB1259AD2F8F810D2F812 -+:1079E000F43043F82160D2F8F830013303F0070394 -+:1079F000C2F8F8309DF8393043B1B4F86200ADF800 -+:107A0000780040E0C4D2850098E08500A3792599EC -+:107A1000002B35D08A8FADF878204A6812F0400FDD -+:107A200020D09DF83A30EBB1049B9B7D13F00F0FF3 -+:107A300018D191F8DF30ABB18B7E13F0010F11D16B -+:107A4000BDF82C3013F4805F0CD012F4003F09D045 -+:107A50000D9A91F8D130134113F0010F02D028464E -+:107A60002DF034DFBDF82C30259913F4805F15BF5D -+:107A70004B684B6843F4003323F400334B6002E05F -+:107A8000898FADF8781095F82D371BB9259BD3F861 -+:107A9000FC3073B16EB1259AD2F8F810D2F8F430F8 -+:107AA00043F82160D2F8F830013303F00703C2F83D -+:107AB000F830259BD3F87C1159B1D1F808360398DA -+:107AC00001EB8302013303F03F03C2F80C06C1F857 -+:107AD0000836A3795BB9A37C4BB19DF83C3033B930 -+:107AE000BBF1000F03D188F806B088F807B09DF805 -+:107AF0003C30FBB1A379002B40F04A81A37C4BB111 -+:107B0000296804984E3110300622FAF319F2002841 -+:107B100000F03E8104980430FAF30EF750B92B6858 -+:107B200093F83E3033B9284604990EF0D5D8002892 -+:107B300040F02E81039ACAF814209DF83C308BB98E -+:107B400099F8022099F80130134399F800201A435C -+:107B500008D0BB7CFA7CD5F86001039943EA022285 -+:107B60004BF022DADAF8142012F0006F26D012F46B -+:107B7000000F02F4E06310D01B0A043B012B96486F -+:107B800002F07F0204D8142302FB0303DA6817E033 -+:107B9000142302FB03039A6812E01B0A043B012B27 -+:107BA0008D4802F07F0204D8142302FB03035A68B5 -+:107BB00006E0142302FB03F31A5801E002F07F02EF -+:107BC000864B1A6099F90330002B07DA2B68D3F83B -+:107BD0008C20D2F8D8320133C2F8D83299F8033069 -+:107BE00003F03003102B07D12B68D3F88C20D2F888 -+:107BF000E0320133C2F8E0329DF83C30002B40F017 -+:107C00009780DAF814102B6811F0006FD3F88C20ED -+:107C100026D011F4000F01F4E06310D01B0A043BDE -+:107C2000012B6D4801F07F0104D8142301FB0303ED -+:107C3000D96817E0142301FB0303996812E01B0ABB -+:107C4000043B012B644801F07F0104D8142301FB9D -+:107C50000303596806E0142301FB03F3195801E0FC -+:107C600001F07F0116293AD00CD80B2925D004D871 -+:107C7000022916D004291AD05AE00C2923D012293F -+:107C800027D055E030293CD004D818292DD02429FC -+:107C900031D04DE0602940D06C2944D0482936D0FD -+:107CA00046E0D2F870320133C2F8703240E0D2F8C8 -+:107CB00074320133C2F874323AE0D2F878320133C8 -+:107CC000C2F8783234E0D2F87C320133C2F87C3228 -+:107CD0002EE0D2F880320133C2F8803228E0D2F8A8 -+:107CE00084320133C2F8843222E0D2F88832013380 -+:107CF000C2F888321CE0D2F88C320133C2F88C32E0 -+:107D000016E0D2F890320133C2F8903210E0D2F887 -+:107D100094320133C2F894320AE0D2F89832013337 -+:107D2000C2F8983204E0D2F89C320133C2F89C3297 -+:107D300025994B6813F4802F0BD09DF83C3043B944 -+:107D4000BBF1000F05D1D5F8400104AA27F098DB5C -+:107D500003E0284604AAFEF709FF049B1B7C13F0EE -+:107D6000010F05D1259AD2F858310133C2F85831A4 -+:107D7000049B1B7C13F0010F05D0259AD2F85C31CF -+:107D80000133C2F85C31259B0398C3F864011FE0FE -+:107D90002868436BBBB19DF83C30A3B90999104AE0 -+:107DA000CB8AD0F8904003F00703D25C0D4B0298C9 -+:107DB0009B5C04EBC304636EA56E01336366FBF347 -+:107DC00029F24019A066029809990022FEF3A8F74B -+:107DD00027B0BDE8F08FC04684188600CC2702008B -+:107DE000C4D2850098E085002DE9F04FADF50F7DF8 -+:107DF000DDF860B28A46594617469946064637F07E -+:107E0000F9DAD0F8D412D0F8D822D0F8DC32D0F891 -+:107E1000E4428046089109920A930B94BBF1000F4B -+:107E200001D1D0F808B000238DF837328B9330465B -+:107E300051463A464B46FBF7CFF9041EC2F2338057 -+:107E400033685B7EEBB9326992F8EA305BB1D36E8E -+:107E5000D3F8202140F2044302EA0303B3F5806023 -+:107E600018BF012005E0106E07F0EEFC003818BFC7 -+:107E7000012030B1B068FBF767F94FF0FF3402F032 -+:107E800012B847B1B9F1030F05D98CA839460422BD -+:107E9000FAF372F001E000238C93BAF1A30F8C9DEA -+:107EA000F168706827D00DDCBAF11C0F07DCBAF15D -+:107EB0001B0F20DAAAF10203012B15D81BE0BAF13F -+:107EC000340F10E040F20B139A4514D005DCBAF1E0 -+:107ED000D60F10D0BAF1FB0F05E0BAF58B7F0AD0B0 -+:107EE00040F21B139A4506D0002F01F09587B9F197 -+:107EF000000F41F3918740F23B132A1E18BF012265 -+:107F00009A4501F2618701A454F82AF0098400001F -+:107F1000138400001D8400008F840000C99D0000B0 -+:107F2000C99D0000C99D0000C99D0000C99D0000B9 -+:107F3000E7840000F5840000C99D0000558500001D -+:107F4000C99D0000CF850000C99D0000C99D0000AB -+:107F5000C99D0000C99D0000DB850000E785000089 -+:107F60000786000023860000558600007986000001 -+:107F7000AB86000019870000979C0000899C0000D8 -+:107F8000D987000019880000D7890000E389000024 -+:107F9000438A00004F8A0000F38A0000FF8A000035 -+:107FA000158B0000218B0000638B0000C99D000031 -+:107FB000C99D0000C99D0000C99D0000858B00007F -+:107FC000418C0000478D0000FB8C0000C99D000023 -+:107FD000C99D0000538D0000958D0000C78D0000E5 -+:107FE000F38D00008F8E0000DD8E00002D8F0000CD -+:107FF000758F0000B38F0000BF8F0000979C0000BA -+:10800000F188000001890000418900007B8900009F -+:10801000C99D0000C99D0000C98F0000D58F0000D8 -+:10802000EB8F000019900000C7900000F79000004F -+:10803000C99D0000979C0000199200004592000025 -+:108040005D9200008D920000A3920000C99D000087 -+:108050006F8B00007B8B0000CD9900000384000033 -+:10806000E7920000F3920000C99D0000C99D000046 -+:10807000C99D0000C99D0000C99D0000979C00009B -+:10808000979C0000979C0000979C0000C99D0000F1 -+:10809000C99D000049930000C99D0000C99D0000D2 -+:1080A000C99D0000C99D0000C99D0000C99D000038 -+:1080B0007D90000089900000118500001D85000062 -+:1080C000BD970000CF9700007D97000087970000C4 -+:1080D000A789000093900000C99D0000C99D000081 -+:1080E000D793000057930000E5930000F993000038 -+:1080F0008794000087940000C99D0000C99D00007E -+:10810000239500004395000059950000C99D00008B -+:10811000C99D0000C99D0000C99D0000C99D0000C7 -+:10812000FD95000011960000979C00004596000008 -+:10813000C5950000C99D0000C99D0000B1960000D2 -+:10814000BF960000D39600000D9400001D9700001C -+:108150002797000031970000C99D0000C99D0000CD -+:10816000E79700001598000023980000C99D0000C3 -+:10817000C99D0000C99D0000C99D0000C99D000067 -+:10818000C99D0000C99D0000C99D0000B584000084 -+:10819000C1840000A98400006984000025960000C5 -+:1081A00031960000C99D0000C99D0000979C000009 -+:1081B000979C0000979C0000039900003D980000E8 -+:1081C000C99D0000C99D0000C99D0000C99D000017 -+:1081D000C99D0000F397000001980000DD960000A3 -+:1081E000C99D0000C99D0000578C0000C99D00007A -+:1081F000C99D0000C99D0000C99D0000C99D0000E7 -+:10820000C99D0000C99D0000C99D00005399000050 -+:108210005D990000979C0000979C0000C99D00009C -+:10822000C99D0000C99D0000C99D0000C99D0000B6 -+:1082300013940000C99D0000C99D0000C99D000065 -+:108240002799000045990000C99D0000C99D0000C4 -+:10825000C99D0000C99D0000979C0000979C0000EC -+:10826000EB990000F5990000C99D0000C99D000030 -+:10827000019A00007D9A0000879A0000978800000C -+:10828000A3880000979A0000AB9A0000199E000096 -+:10829000199E0000938A0000A18A0000C18A000094 -+:1082A000CF8A0000C99D0000C99D0000BD9A000052 -+:1082B000C99D0000C99D0000C59A0000ED9A00000C -+:1082C000C99D0000C99D0000C99D0000C99D000016 -+:1082D000C99D0000C99D0000C99D0000C99D000006 -+:1082E000C99D0000C99D0000C99D0000C99D0000F6 -+:1082F000C99D0000339B0000C99D0000C99D00007E -+:10830000C99D0000C99D0000C99D0000739C00002C -+:10831000C99D0000C99D0000C99D0000699A000028 -+:10832000739A0000FD830000FD830000C99D0000DA -+:10833000C99D0000C99D0000C99D00008D9B0000E3 -+:10834000C99D0000C99D0000C99D0000C99D000095 -+:10835000C99D0000B19B0000B19B0000C99D0000B9 -+:10836000C99D000065910000D1910000DD910000E1 -+:10837000E7910000F99100000B920000C99D0000F8 -+:10838000DB9B0000EB9B0000F99B0000C99D0000F7 -+:10839000C99D0000C99D0000C99D0000C99D000045 -+:1083A000C99D0000C99D0000C99D0000C99D000035 -+:1083B000C99D0000C99D0000C99D0000C99D000025 -+:1083C0004F9C0000619C0000279C0000C99D00009C -+:1083D000C99D0000C99D0000C99D0000C99D000005 -+:1083E000C99D0000C99D0000979C0000979C00005B -+:1083F0008D9D0000A19D0000B59D0000002101F0B1 -+:108400009EBB002401F0B9BAC14B00243B6001F0CF -+:108410004ABD012300243B6001F045BD33685B7E0B -+:10842000002B41F0F38486F89F3186F8A231304664 -+:1084300009F06AF830460EF04BDD30460EF036DEBD -+:108440003268137E002B41F0DF84136F13F0030FAB -+:1084500041F01D8513F0040F41F0D68413F0080F8E -+:1084600001F0DD8401F0D0BC33685D7E002D41F069 -+:10847000CD84012486F8A241304609F045F886F8FB -+:108480009F41304608F072FC2C4601F00CBD0123E0 -+:1084900086F89F3133685C7E002C41F0B584B0686B -+:1084A000FAF752FE01F0FFBC336800241B7E3B60EC -+:1084B00001F0F9BC96F8293000243B6001F0F3BCD0 -+:1084C00031680B7E002B41F0CB844C7E002C41F0B8 -+:1084D000DE8411463069079235F06AD9079A86F82A -+:1084E000292001F0E0BC3368002493F82C303B6075 -+:1084F00001F0D9BC336883F82C2096F82930002B82 -+:1085000001F0828430461BF0EBDA002401F0CBBC92 -+:1085100096F8C83100243B6001F0C5BC86F8C8213C -+:1085200086F8CB21304608F0EFFF96F82930002B73 -+:1085300001F06A8430461BF099DA30461BF0D0DA3D -+:10854000B0688C9907F0C4DD304620F0CBDF002402 -+:1085500001F0A9BC40461AF083D810F0006F2AD071 -+:1085600010F4000F00F4E06310D01B0A043B012B51 -+:10857000684900F07F0004D8142300FB0313DA6875 -+:1085800014E0142300FB03139A680FE01B0A043B5A -+:10859000012B604900F07F0004D8142300FB031373 -+:1085A0005A6803E0142300FB03F35A584FF4FA739C -+:1085B000B2FBF3F007E000F07F034FF4FA7203FB25 -+:1085C00002F3B3FBF2F00024386001F06CBC3368B6 -+:1085D00000245B683B6001F066BC98F81230002410 -+:1085E0003B6001F060BC98F8063013B1002D01F03B -+:1085F0002284D6F840252B1E18BF0123002482F8C0 -+:10860000343001F050BCB8F95E300BB1022004E008 -+:10861000B8F95C30181E18BF01200024386001F042 -+:1086200042BC022D0AD14FF000014FF0010200249C -+:10863000A8F85C10A8F85E2001F035BC2B1E18BF0E -+:108640000123A8F85C3000244FF00003A8F85E3046 -+:1086500001F029BCB8F80630002B01F0E983B9F12C -+:10866000050F41F3F483384608F1BC010622F9F303 -+:1086700083F4002401F017BC98F80440002C41F06A -+:10868000EF83B9F1050F41F3E28308F1BC003946ED -+:108690000622F9F371F496F82930002B01F0B48327 -+:1086A000404620F09DD901F0FEBBB9F1230F41F304 -+:1086B000CE83384600212422F9F3C2F498F80650FC -+:1086C0005DB198F8192008F11A0147F8042B3846D3 -+:1086D000F9F352F4002401F0E6BB98F80740381D86 -+:1086E00054B1089C237A04F109013B60227AF9F322 -+:1086F00043F42C4601F0D7BBD6F84025137A02F19B -+:1087000009013B60127AF9F337F401F0CCBBC046A3 -+:10871000776CE41484188600B9F1030F41F3978352 -+:108720003A68131D9945C1F29283202A03D96FF04C -+:10873000110401F062BB07F1040A3046514636F0DD -+:1087400011DE10B1404541F06A8398F806309BB1C4 -+:10875000404651463A6836F00FDA3046414636F028 -+:108760008FDB98F819303BB13046414636F03CDD9E -+:108770000446002841F0418398F80630002B41F070 -+:108780004383B9F1310F02D819461A4619E07A8DA0 -+:1087900022B1FB6A13B90125FA6200E000253046D8 -+:1087A00007F12C01A9F12C020AF034DC04460DB1CA -+:1087B0000023FB62002C41F0208307F12402A9F181 -+:1087C00024013B683046009201915246414631F007 -+:1087D000CFD8002401F067BB336B18690AF0A6F903 -+:1087E000C0B2386098F807301BB1089991F8323060 -+:1087F00003E0D6F8403593F832300024D6F868010B -+:108800007B60BC608379002B01F0FE824BF09CDF23 -+:10881000C0B2B86001F047BB0E2DCCBF4FF4805200 -+:108820004FF40052E02D03D96FF0120401F0E5BAC5 -+:1088300045F4306342EA03039DB2D6F85C01294651 -+:108840003DF0ACDD18B96FF0130401F0D6BAD6F8DC -+:10885000403532685D86137E002B01F0D58292F898 -+:108860003F40002C41F0D082336B18690AF05EF96A -+:10887000A84201F0C9822946304620F091DA3046FC -+:1088800008F0B0FF3046294620F0D0D8304619F025 -+:10889000B7DB01F008BB96F8683700243B6001F0B5 -+:1088A00002BB642D01F2BE8286F8685730699DF8DC -+:1088B000301235F021D833681B7E002B01F0A482E2 -+:1088C000D6F868319D79002D41F09E82304608F03F -+:1088D00089FF3046D6F85C410DF066D80146204647 -+:1088E0003CF042DF304619F08BDB2C4601F0DBBA5E -+:1088F000D6F86036002493F907303B6001F0D3BA14 -+:10890000304669B211F024D9041EC1F276828C9BE4 -+:10891000D6F86026D37133681B7E002B01F06B8282 -+:10892000304608F05FFF304611F054D93046D6F893 -+:10893000AC1614F005D8304619F062DB01F05BBAD2 -+:108940003368187E30B9D6F8603604469B793B60B0 -+:1089500001F0A9BA336B89A918690AF065FA0446CF -+:1089600028B19DF8243200243B6001F09CBAD6F86F -+:1089700060369B793B6001F096BA6B1C042B01F2C8 -+:108980005182B5F1FF3F01D103238C93D6F86036B5 -+:108990008C9A00249A71336B9DF8301218690AF092 -+:1089A00081FE01F080BA33681B7E002B01F0498202 -+:1089B000B1F8E8339AB24DF6AD639A4201F02F82D6 -+:1089C0004FF6FF739A4201F02A82C2F3401300244B -+:1089D0003B6001F068BAB6F83A3600243B6001F01B -+:1089E00062BA6B1EFE2B01F21D82A9B2A6F83A16DE -+:1089F0003069B6F83C2634F029DEB6F82032B6F8F5 -+:108A00003A2623F00F031343A6F82032B6F8223299 -+:108A1000304623F00F031343A6F82232B6F824326F -+:108A2000002423F00F031343A6F82432B6F82632AD -+:108A300023F00F031343A6F8263212F053D801F0A7 -+:108A400032BAB6F83C3600243B6001F02CBA6B1EFB -+:108A5000FE2B01F2E781AAB2B6F83A16A6F83C2638 -+:108A6000306934F0F3DD3146B1F82022B6F83C36F7 -+:108A700022F4706242EA0322A1F8202206F10803E0 -+:108A800002319942F0D1304612F02CD8002401F086 -+:108A90000ABA336B0024B3F806313B6001F003BA25 -+:108AA00096F82930002B01F0C9816B1EFE2B01F2D4 -+:108AB000B9813046A9B220F023D8002401F0F3B9DF -+:108AC000336B0024B3F808313B6001F0ECB996F841 -+:108AD0002930002B01F0B281A5F1FF03B3F5E06F5F -+:108AE00001F2A0813046A9B21FF0FEDF002401F0A0 -+:108AF000DAB996F95C3600243B6001F0D4B96B1CFE -+:108B0000012B02D9012D41F08D81002486F85C569D -+:108B100001F0C9B9336800241B6F3B6001F0C3B991 -+:108B20002A0C01F07F8122F00303002B41F07A81AF -+:108B3000A9B221F00303002B41F07481D04310EA65 -+:108B4000010441F06F813268136F00EA03030B43A5 -+:108B5000304613670EF0BCD930460EF0A7DA01F0AC -+:108B6000A2B9336B00241B893B6001F09CB998F8D3 -+:108B7000603000243B6001F096B9002488F8602042 -+:108B800001F091B9832D01F2508106EB8503B9F113 -+:108B9000A30FD3F8804241F35A8145AD2846002106 -+:108BA000A422F9F34DF2002C42D0E37947A82B60C0 -+:108BB000226904F114016A60F9F3DEF1237A61930A -+:108BC00096F8A0349BB9D8F8583013F0080F0ED19E -+:108BD000237A0B2B08D196F8F03743B196F8F1378A -+:108BE0002BB1A379072B02D8A379292B03D9629B38 -+:108BF00043F001036293638913F0020F03D0629B79 -+:108C000043F002036293638913F0200F03D0629B49 -+:108C100043F010036293638913F0100F03D0629B3B -+:108C200043F0200362936CA821460622F9F3A4F1D5 -+:108C3000384645A9A422F9F39FF1002401F033B985 -+:108C4000A549012330460097CDF804900293CDF852 -+:108C50000CB000F096BFB9F1070F41F3F880304631 -+:108C600036F08EDD80450BD08C9B032B01F2DD802E -+:108C700008EB83035B6F002B01F0D7809B798C930B -+:108C80008C9B832B01F2D18006EB8303D3F88042C7 -+:108C9000002C01F0CA802369002B01F0C680B8F8CF -+:108CA000623013F0010F08D02046F9F355F620B1D9 -+:108CB000B8F86C30D8F8680003E0B4F8B830D4F8ED -+:108CC000B4008DF818321B0A8DF81932030A8DF89A -+:108CD0001B32030C00248DF81A028DF81C3286A971 -+:108CE000030E082238468DF81D328DF81E428DF88D -+:108CF0001F42F9F341F101F0D6B8336893F83F30E1 -+:108D0000002B41F0B380D6F86801837923B10421A8 -+:108D100007924BF04DDC079A96F8723286F850278E -+:108D200086F85925002B41F06F80D6F85C011AB106 -+:108D300006F5AA610E3102E006F5AA610A313DF09E -+:108D400011DA01F057B896F8503700243B6001F073 -+:108D5000AAB80325304639464A4600230095CDF887 -+:108D600004800BF0BBD8044638B110F1190F01F0A4 -+:108D70004480C6F8245501F040B80223C6F82435D3 -+:108D800096F8F437C6F8285523F0010386F8F4372F -+:108D900001F089B8B9F10B0F41F23E803B680B2B13 -+:108DA000899341F239804B45C8BFCDF82492899B05 -+:108DB00030460C3B8993394689AAD6F8243510F001 -+:108DC000EDDB01F017B896F829303BB933681B6F1B -+:108DD00013F0040F01F0328001F016B898F8064045 -+:108DE000002C41F028803046414636F049D801F049 -+:108DF0005AB833681B7E002B01F02380B9F1050FB0 -+:108E000041F22580B9F10D0F0CD9304607F1080168 -+:108E1000A9F108020AF0FED83D460446002840F0B9 -+:108E2000EC870AE082AC204639460622F9F3A4F02A -+:108E3000002384934FF00E09254698F80640CCB9DC -+:108E40000A9AD2F8901039B1706892F89420FDF324 -+:108E50004FF70A9BC3F890400A9C494684F89490C7 -+:108E60007068FDF335F7C4F8900018B129464A46FA -+:108E7000F9F382F02946404632F028D90A9904468F -+:108E8000D1F89030002B40F0BF8700F0B4BF002332 -+:108E90000093304639464A468BABFAF7F5F904465B -+:108EA000002840F0AA878B99032900F0ED87326BE8 -+:108EB0001368994204D1D2F8F0303B6000F0F3BF60 -+:108EC0005368002B14BF38233C23F358D3F8F030F9 -+:108ED0003B6000F0E8BFC0467B7286000023009331 -+:108EE000304639464A468BABFAF7CEF9044600289D -+:108EF00040F083878C9A02F16403672B00F292871B -+:108F00008B99032904D0336B1B68994240F0CB87BF -+:108F1000002A04DB3046316B32F01CDA0246336B38 -+:108F2000C3F8FC20C3F8F02000F0BDBF002300937D -+:108F3000304639464A468BABFAF7A6F90446002874 -+:108F400040F05B878B99032900F09E87326B136892 -+:108F5000994204D1D2F8F4303B6000F0A4BF5368CA -+:108F6000002B14BF38233C23F358D3F8F4303B6074 -+:108F700000F099BF00230093304639464A468BAB38 -+:108F8000FAF782F90446002840F037878C9A642A61 -+:108F900000F27A878B99032904D0336B1B689942BE -+:108FA00040F08187336BC3F80021C3F8F42000F050 -+:108FB0007ABF0A9A0024D36A3B6000F074BF0A9B10 -+:108FC0000024DD6200F06FBF98F83A3000243B6067 -+:108FD00000F069BFBB49012330460097CDF80490EB -+:108FE0000293CDF80CB000F0CCBDD8F84C2006248C -+:108FF000531C03FB04F39945C0F2298747F8042B5F -+:10900000D8F84C20384602FB04F2D8F85410F8F394 -+:10901000B3F7002400F047BF3B68402B00F2028703 -+:10902000062403FB04F304339945C0F21087D8F8F3 -+:10903000541049B1D8F84C2002FB04F20432FDF37D -+:1090400057F60023C8F84C303968706801FB04F10A -+:109050000431FDF33DF6C8F8540018B96FF01A0456 -+:1090600000F0CBBE57F8042BC8F84C20394602FB61 -+:1090700004F2F8F381F7002400F015BFD8F850305F -+:1090800000243B6000F00FBF0024C8F8505000F0EF -+:109090000ABF98F807301BB1089C04F1380203E0BE -+:1090A000D6F8403503F1380211680B1D9945C0F21E -+:1090B000CE8647F8041B3846111D1268F8F35CF79A -+:1090C000002400F0F0BE78AC282200212046F8F3FE -+:1090D000B7F73046214614F0A9DC789A131D99455C -+:1090E000C0F2B58647F8042B211D3846F8F344F743 -+:1090F000002400F0D8BE3A68131D9945C0F2A78637 -+:10910000102A00F2AA8678AC002128222046F8F323 -+:1091100097F757F8042B201D39467892F8F32CF76F -+:10912000336893F8463013F0030F0ED098F80730E9 -+:1091300004F115001BB1089A02F14D0102E0D6F8C6 -+:1091400040154D311022F8F317F7304678A910F08A -+:109150008BDC0446002840F0508630460DF04AD89B -+:1091600000F0A1BE6DB100243046414623222346C3 -+:109170000094019402940394049413F0CFDC00F063 -+:1091800092BE98F806303BB9D6F8680104214BF03E -+:109190000FDA40462FF0DADAD6F878122B467068EC -+:1091A000043101220095F9F34DF698F8063043B9E1 -+:1091B000404601212A462B4602F0ACFF2C4600F027 -+:1091C00072BE3046414635F05BDE2C4600F06BBE89 -+:1091D000D6F84C3500243B6000F065BE0024C6F88C -+:1091E0004C5500F060BE384606F5AA610622F8F339 -+:1091F000C3F6002400F057BE06F5AA6039460622E1 -+:10920000F8F3BAF6002400F04EBE304641460AF0AC -+:1092100089DF002400F047BE98F8060058B998F896 -+:10922000123043B198F807302BB1089CE38D044607 -+:109230003B6000F038BED6F840350024DB8D3B6043 -+:1092400000F031BE6A1E4FF6FE739A4200F2EA85C4 -+:10925000D6F840350024DD8500F025BE98F80600DC -+:1092600060B998F812304BB198F8073033B10899CB -+:10927000044691F860303B6000F015BED6F84035EA -+:10928000002493F860303B6000F00DBE6B1EFE2B97 -+:1092900000F2C885D6F84035002483F8605000F00D -+:1092A00002BE3A6845F2AB539A420FD106490023F9 -+:1092B00030463B600097CDF804900293CDF80CB097 -+:1092C0000DE0C046AB728600DD7286000023A04927 -+:1092D0000097CDF804900293CDF80CB030463A4692 -+:1092E0004B4600F050BC0B9A002413783B6000F012 -+:1092F000DABD022D00F293850B9B1D7033681B7E37 -+:109300004BB140460DF062DCD8F8E4325B8B13B110 -+:1093100040461BF043D90B9C637E0BB18C9B33B949 -+:109320008C994046003918BF012107F079FF40466B -+:109330001CF05CDB0146404622F000DC404631F088 -+:10934000B7DF002400F0AFBD304639464A46FAF791 -+:1093500079F800F04FBD316891F830300F7E1BB1C5 -+:1093600015B96FF0190400E0002491F8953013B19D -+:10937000002D40F08F85002C40F03F8591F82F3074 -+:10938000934200F0908527B1B0680792F9F7DCFEB0 -+:10939000079A3368304683F82F20414636F0F8D9D3 -+:1093A000326892F8443023B192F82F300BB182F832 -+:1093B0004440304612F004DD002386F8DD3186F8A3 -+:1093C000DE311FB1B068F9F7D7FE0446304608F029 -+:1093D0009BF800F010BD3368002493F82F303B60F9 -+:1093E00000F061BD5B49002230460097CDF8049043 -+:1093F0000292CDF80CB0C5E35649012330460097E0 -+:10940000CDF804900293CDF80CB0BAE304238C930A -+:1094100004E0B9F10B0F40F31A85043798F80630D1 -+:10942000002B30D13B78304613F0010F39463D46D2 -+:1094300018BF08F1BC054CF0B1D9044628B1436807 -+:1094400013F4805F01D04BF02FDF98F81230002B1F -+:1094500000F0DA84002140460A460B4602F05AFE2C -+:1094600054B1BDF830323046019329462A4608F1FE -+:10947000C20300941EF086DD3046414635F000DD23 -+:10948000002400F010BDAAF179033846DDF83092CF -+:10949000012B8CBF01251025F9F34EF2BAF1790F9B -+:1094A00014BF4FF0000B4FF0010B044638B3D6F851 -+:1094B00000058AA94BF00EDE19E0D2F8F030B3B9FE -+:1094C0001369434513D1102D03D1137E13F0020FFE -+:1094D00004E0012D03D1137E13F0010F07D03046B5 -+:1094E00041465B460095CDF804904BF00BDF8AA80F -+:1094F0004BF0F8DD02460028DFD100F085BC304695 -+:1095000039464CF04BD90246002800F07D843046A5 -+:1095100041465B460095CDF804904BF0F3DE00F039 -+:10952000C2BC98F8070028B1089900240B8E3B6054 -+:1095300000F0B9BCD6F8403504461B8E3B6000F005 -+:10954000B2BCD6F8403500241D8600F0ACBCC04645 -+:10955000E3728600E8728600002F00F05D84B9F1A6 -+:109560000C0F1FD13B79391D13F0010440F05484D6 -+:1095700030464CF013D938B1012386F82D374BF023 -+:10958000A3DE386000F08FBC98F8060018B16FF0C9 -+:109590001D0400F032BCD8F8E03204461B693B6081 -+:1095A00000F081BCB9F1040F40F0368498F8060051 -+:1095B000002840F03184D8F8E03204461B693B6053 -+:1095C00000F071BC304620F0B9D93368D3F88C0074 -+:1095D000036C3B60836C7B60D0F8D831BB60D0F803 -+:1095E000B03102699B18B9F1130FFB6040F30C8492 -+:1095F000D0F83C3100243B6100F055BC9D4900226D -+:1096000030460097CDF804900292CDF80CB0B9E244 -+:109610009849012330460097CDF804900293CDF885 -+:109620000CB0AEE2B8F8623000243B6000F03BBC06 -+:109630009149012330460097CDF804900293CDF86C -+:109640000CB09EE2832D40F30284336B3D1D1869FC -+:1096500009F0FCFB089A4FF0000982F861008C9B2E -+:109660003046043B08992A46CDF8009009F0EEDD1B -+:10967000AB6F84333B6098F80630002B00F0C48356 -+:1096800007F11704204649462022F8F3D9F498F848 -+:1096900019202046AA7408F11A01F8F36DF407F1B5 -+:1096A0000C0008F1BC010622F8F366F44C46FAE31C -+:1096B00001233B60336B00241B687B60F3E396F867 -+:1096C0009C310BB9184601E0336B186800243860F0 -+:1096D000E9E33046294612F053DC8BE3B9F1020F7F -+:1096E00040F3B583336B188968B1022801D1653026 -+:1096F0000FE0052801D167300BE0042801D16A3062 -+:1097000007E0072801D1613003E0082814BF3F209B -+:10971000632000231C4638707B70C4E396F8433600 -+:1097200000243B60BFE396F9473600243B60BAE370 -+:109730006B1C012B02D9012D40F07483EAB2316811 -+:1097400086F84726087E48B191F83F40002C40F04B -+:109750005B833046214620F0A9DDA4E351B2B1F18C -+:10976000FF3F03D1044686F843069CE3012914BF5A -+:1097700000230123044686F8433694E396F84836DE -+:1097800000243B608FE396F84836934200F03C8318 -+:10979000336886F8482693F82F30002B00F0348386 -+:1097A00096F82930002B00F02F83304621F0AEDBF5 -+:1097B0003046012121F0B4DD002474E3306B0368EE -+:1097C000022B40F02183437D00243B606BE3336830 -+:1097D00093F83F30002B40F049833046E9B2012234 -+:1097E0001FF0B4D906E3D6F8583600241B783B6046 -+:1097F00059E3D6F85836002493F903303B6052E31E -+:10980000022D00F20F83304604216AB21CF0B0D85A -+:10981000002448E3D6F85836002493F901303B6021 -+:1098200041E36B1C012B02D9012D40F0FB82304635 -+:1098300002216AB21CF09CD8002434E3B9F1270F4E -+:1098400040F30583282278A83946F8F395F3789CED -+:10985000102C00F20883336B5B7D002B00F0FA8242 -+:1098600064B906F5AE600C3021462822F8F3E8F31F -+:1098700019E3C046177386001C73860033686EAC0C -+:1098800093F84630214613F0030317BFD8F8CC30C5 -+:109890001846C3F3003383F0010000227F230093B6 -+:1098A0000190134678A847F027DCD6F860360022EE -+:1098B0009B782046AC4947F061DB789A6E9B9A42D0 -+:1098C00040F0D18206F5AE6028220C302146F8F334 -+:1098D00053F33268137E002B00F0968292F82F30FB -+:1098E000002B00F0918292F83F30002B00F08C8228 -+:1098F000304621F00BDB3046012121F011DD002440 -+:10990000D1E2336B5B7D002B00F0A482B9F1270F0D -+:1099100040F39D8206F5AE6138460C312822F8F3FB -+:109920002BF30024BFE225B1022D02D0012D40F01F -+:109930009182D8F8E832404683F8E05030F046DFB4 -+:109940000024B0E2D8F8E832002493F8E0303B601D -+:10995000A9E2B6F87A3500243B60A4E23368187EA9 -+:10996000002840F07D824FF6FE739D4200F25A823D -+:109970000446A6F87A5596E201344C4502DAE35DD6 -+:10998000002BF9D1032C00F3688288AD002104225A -+:109990002846F8F355F3224639462846F8F308F4EA -+:1099A000D6F85C0129463CF0DDDB0446002840F097 -+:1099B000248230460DF07ADB06F5AA600A3029468B -+:1099C0000322F8F3F5F386F859456CE2B9F1030F79 -+:1099D00040F33D82D6F85C013BF05EDE0422014696 -+:1099E0003846F8F3C9F200245DE2D6F80C350024BD -+:1099F0003B6058E233681B7E002B00F0228229E294 -+:109A0000B9F1030F40F32382A9F1040399083B68DD -+:109A10008B4288BF396000252C460E2C8CBF4FF43A -+:109A200080514FF4005144F430631943D6F85C017F -+:109A300089B23CF0B3DC10B10DAB5C55013501349B -+:109A4000E02CEAD13B68AB4201D3002107E03D6046 -+:109A5000FDE10DAA8A5C07EB81035A600131A9423E -+:109A6000F7D100243D601EE2304639463BF064DF0A -+:109A7000C0E13046394608F0DDFCBBE196F8CE3156 -+:109A800000243B600FE286F8CE21304600210AF028 -+:109A90005FDF002407E23368114683F84120336B0F -+:109AA0000024186909F0A6F9FDE13368002493F851 -+:109AB0004130003B18BF01233B60F4E133680024D0 -+:109AC0003B60F0E1D8F87030B3F1FF3F00F0AD81BA -+:109AD00008EB8303586F002800F0A781C3790024A6 -+:109AE000AB4214BF002301233B60DCE140466FF032 -+:109AF00007040025416FB9B1CA798C9B9A4213D1F2 -+:109B0000D8F87030B3F1FF3F07D008EB83035A6FEA -+:109B10001AB1538923F0020353814B89C8F870505E -+:109B200043F002034B81002401350430042DE1D1C0 -+:109B300061E1B9F1090F40F38A8185E101314945BD -+:109B400000F08581CB5D002BF8D1A6E100230293C4 -+:109B5000304639463A19C4EB09030097CDF8049012 -+:109B6000CDF80CB00FE0C0460C1886003B19C4EBD2 -+:109B700009020093012301920293CDF80CB0304604 -+:109B800039460022134619F00BDC33E198F8063011 -+:109B9000002B40F0598198F81130002B00F05481CF -+:109BA000D8F80C00394698F8072013F0B9FB21E1EA -+:109BB00019F0010440F0308101230293AD49AE4B0E -+:109BC00040F21312924518BF1946304622460097BC -+:109BD000CDF80490CDF80CB0D4E73846B16B4FF413 -+:109BE0008672F8F3C9F100245DE138460899AC2289 -+:109BF000F8F3C2F1002456E1099C099AA36B516B5A -+:109C000047F8043B926B3846F8F3B6F1099B099C80 -+:109C10009A6B5B6CB818BB50216C626C0430F8F323 -+:109C2000ABF100243FE1336893F83F30002B00F0A4 -+:109C3000FF800899002900F0FB80496E002900F0A0 -+:109C4000F78038460822F8F397F100242BE1089AB0 -+:109C5000384602F16B011022F8F38EF1002422E164 -+:109C6000089B384603F17B011022F8F385F10024AC -+:109C700019E133681B7E002B00F0E3803046394643 -+:109C80004A460AF065DFB5E033680121186901F042 -+:109C90000DDB002407E1304651464A463B46F9F7C2 -+:109CA00017FB0446002840F0A880BAF13C0F49D1C8 -+:109CB0003D1D00F0AE807B6813F0006F40F0A9807E -+:109CC00003F07F03022B06D0042B04D00B2B02D011 -+:109CD000162B40F09E806EAC3046214613F0A6DE77 -+:109CE000304621461CF01ED8286810F0006F26D0A0 -+:109CF00010F4000F00F4E06310D01B0A043B012BAA -+:109D00005E4900F07F0204D8142302FB0313D868D5 -+:109D100017E0142302FB0313986812E01B0A043BAC -+:109D2000012B564900F07F0204D8142302FB0313D1 -+:109D3000586806E0142302FB03F3585801E000F0D2 -+:109D40007F002860336B514618698CAB0733009352 -+:109D50004A463B460AF0B4F9BAF13C0F044608D033 -+:109D6000BAF15C0F05D0BAF14A0F02D0BAF15D0F1B -+:109D700041D1002C41D1002F00F095803B68326822 -+:109D8000003B18BF012382F840308CE03C490022A0 -+:109D900030460097CDF804900292CDF80CB0F1E671 -+:109DA0003749012330460097CDF804900293CDF84F -+:109DB0000CB0E6E63349012330460097CDF8049015 -+:109DC0000293CDF80CB0DCE6D6F8680151463A466D -+:109DD0004B46CDF800B04AF0C9DC10F1170F04462D -+:109DE00009D1D6F8340751463A464B46CDF800B073 -+:109DF00029F030D90446002C55D004F12A032A2B2F -+:109E000002D83368DC664EE000244CE06FF00804B2 -+:109E100049E06FF0010446E06FF00104EDE74FF018 -+:109E2000FF34EAE76FF01C04E7E76FF00704E4E7AC -+:109E30006FF01004E1E76FF00604DEE76FF00A044C -+:109E4000DBE76FF00304D8E76FF01604D5E76FF097 -+:109E50000D04D2E76FF00C04CFE76FF00E04CCE7EF -+:109E60006FF00404C9E76FF00B04C6E76FF01B0442 -+:109E7000C3E7C0467ED701002F7386008418860092 -+:109E8000507386005D7386006FF00204B5E76FF0D3 -+:109E90000804B2E76FF01904AFE74C1CBAF5837FF2 -+:109EA0003FF454AE62E620460DF50F7DBDE8F08F1D -+:109EB0002DE9F341089C05460E4617469846009446 -+:109EC00007F0A6FD10F1170F06D1284631463A4695 -+:109ED00043460094FDF788FFBDE8FC812DE9F04181 -+:109EE0000368054693F83F30D0F80C8013B1B0F802 -+:109EF000267602E0FAF70CFF074600222869394669 -+:109F000003F0E2F85621286933F08ADBD5F888316E -+:109F10004000002BC5F8040506DA2869B22133F0A9 -+:109F20007FDB4000C5F80805A221286933F078DB03 -+:109F30004000C5F8EC07284612F03AD895F8CD3124 -+:109F40003BB928694C2133F06BDBC0F3C71085F8AF -+:109F5000CD0128461CF092DDD5F84C0104F02EFD11 -+:109F600028463DF05FDA002605EB8603D3F84C4225 -+:109F70002CB120461EF03EDF20461EF031DD0136BA -+:109F8000082EF1D12B6893F83F309BB1002205EBEE -+:109F90008203D3F84C0250B1037943B1D0F8D432E4 -+:109FA000DB8D1B04C8F888311FF05CD902E0013258 -+:109FB000082AECD12846394609F0AAD82846742147 -+:109FC000B5F87A2522F006D995F8D13142F210720F -+:109FD000002B18BF4FF4BC622846822122F0FAD829 -+:109FE0002B6B95F8D111186909F04AF80122134634 -+:109FF000B5F8781728460AF063DA0123B5F87A171E -+:10A00000002228460AF05CDAD5F8400125F0D8DBBA -+:10A010002846F9F7E9FA2B685B6B5BB1B8F888362C -+:10A02000D5F86C029BB243F00403A8F888360021EF -+:10A0300017F0B6DE2846F9F77BFAD5F8841161B936 -+:10A0400028461CF08DD80404C5F884412846022116 -+:10A050001CF086D82043C5F884012B6893F8A13002 -+:10A06000012B03D1D5F8400126F096DC284617F0E5 -+:10A07000C7DF284608F0B6DBB5F85C1728461CF0A9 -+:10A080004DDD284610F004DA424BEA68002185F8DD -+:10A090004410C2F8DC33012385F8A83185F8AA31D1 -+:10A0A0002B6893F838303BB14A1901314FF0FF3338 -+:10A0B000082982F89538F7D100244FF440763146CC -+:10A0C00028461CF04DD805EB4401B1F8203213F0BE -+:10A0D0000F0F06D123F00F0300F00F021343A1F876 -+:10A0E0002032B1F8202212F0F00F06D100F0F00378 -+:10A0F00022F0F0021343A1F82032B1F8202212F42A -+:10A10000706F06D100F4706322F470621343A1F8FB -+:10A110002032B1F820321A0B06D11B0500F4704230 -+:10A120001B0D1A43A1F8202201340236042CC6D19B -+:10A130002B68284693F94C100BF076DA2A68137EC8 -+:10A1400003B392F82F30EBB1002605EB8603D3F86A -+:10A150004C426CB1A3795BB12B6893F838302BB1CA -+:10A160002846D4F84C15002235F0F2DD0023E371C7 -+:10A170000136082EE9D1002385F87232D5F834076C -+:10A180002AF0C8DDD5F8680104214AF011DABDE8EB -+:10A19000F081C0468096980003681A6819B10123BF -+:10A1A00082F8AA3001E082F8AA1070472DE9F04742 -+:10A1B0001746937AD27A056843EA022A3B79064623 -+:10A1C00003F007044FF0000938E00B6968681A785B -+:10A1D0005B7842EA0328D6F87822936E01339366BF -+:10A1E0000122FCF39DF52B6893F8A130012B03D0DD -+:10A1F000C8F34123032B17E0182304FB0362B2F8D2 -+:10A200008232B2F88612284699420CBFB2F88032E8 -+:10A210004B1CA2F886322146012220F0E5DB09F131 -+:10A2200001031FFA83F9D1450AD02B69022103EB00 -+:10A230008403D868124B9B6B984701460029C4D110 -+:10A240002B6893F8A130012B05D02846214696F9BA -+:10A250002C2020F0C9DBBB7913F0020F0ED00024B4 -+:10A2600006E00120FCF378F2631CDCB20B2C05D075 -+:10A27000EB68D3F8703113F0010FF2D0BDE8F0872E -+:10A28000E0A685002DE9F347D0F80090044601A927 -+:10A29000D9F800054AF01EDF00263AE07B6813F487 -+:10A2A000802F36D063684FF00008FD58AA46D5F8D5 -+:10A2B000F8205FFA88FE32B391781379002918BF2D -+:10A2C00001261BB100231371D3701CE0D9B1D378E0 -+:10A2D0000133D9B2D1707B6813F4807F14BF628ED2 -+:10A2E000A28E6423B2FBF3F291420BD3D4F878220E -+:10A2F0004846D2F8C43051460133C2F8C4307246E1 -+:10A3000023F030DF012608F101080435B8F1080F09 -+:10A31000CDD101A84AF0E6DE07460028BED136B905 -+:10A32000236884F8A3639868A16B05F097D9BDE80A -+:10A33000FC87C0464368F7B5CE5805460027FCB2F7 -+:10A3400028463146224622F0DBD901370123284630 -+:10A350003146224622F040D9082FF0D12A68002346 -+:10A360000093506806F110010122F8F36BF5FEBD71 -+:10A37000D0F8AC037047C046D0F8C0037047C04661 -+:10A38000C0F8C0137047C046D0F8AC331B68DB6917 -+:10A3900018690528A8BF05207047C0462DE9F04F71 -+:10A3A000F3B00890894608999DF8F8010792D1F812 -+:10A3B000B0231C46D9F8D4320690D1F8AC730C9275 -+:10A3C000002148A828226F9115937C9DDDF8F48127 -+:10A3D000F7F336F607980C99037803F0FC03202B6B -+:10A3E00014BF002301230D9391F82F3033B1D7F818 -+:10A3F0006801837913B104214AF0DAD80D9A0AB1C1 -+:10A40000092D00E0032D40F2E58522786378211DB7 -+:10A4100042EA032AA278E37842EA03230E930D9BD3 -+:10A4200023B9043D8B4613950F9304E00A3D04F1D4 -+:10A430000A0B13950F911398012840F2CB859BF8D6 -+:10A44000013002339842C0F2C58548AB00933846CC -+:10A450005946139A002319F059DE002840F045832D -+:10A4600097F838279DF834319A4240F03E8399F8A6 -+:10A4700019309BF801209A4240F03E8309F11A00FE -+:10A480000BF10201F7F35CF5002840F0358398F8F2 -+:10A49000183013F0020F0BD098F8DF3023B1384694 -+:10A4A000414601222BF0CEDC4046FE214AF0C8DDB9 -+:10A4B00099F94820002AC0F21F8398F8183013F049 -+:10A4C000010F00F01983082392FBF3F34344197D35 -+:10A4D000A44B02EA0303002B05DA013B6FEA437346 -+:10A4E0006FEA5373013351FA03F313F0010F00F0D5 -+:10A4F000038319A80021C8F81090A8F800A101381A -+:10A500006D22F7F39DF50024214613E072AA53183B -+:10A5100013F8A43C03F07F026C2A0AD89248835CAB -+:10A520003BB119AB013B9A54835634EA230428BF4C -+:10A5300001240131489B9942E8D3D8F8043023F034 -+:10A5400007023B6BC8F804205B7D23B11CB942F0C5 -+:10A550000103C8F804303B6B5B7D43B11AF4806F94 -+:10A5600005D1D8F8043043F00203C8F804301AF0DB -+:10A57000200405D0D8F8043043F00403C8F80430B0 -+:10A58000159B0021986B0FE0159A531893F83C2007 -+:10A5900012F0800F07D019AB013B02F07F029B5CE9 -+:10A5A000002B00F0A28201318142EDD10C9890F88D -+:10A5B000463013F0030F45D05946139A38461BF026 -+:10A5C0009BDD00260546414638462A46334600961E -+:10A5D00018F00CDBB5B14DA8E91C01301022F7F3DF -+:10A5E000CBF431467B1872A893F8EB24431813F888 -+:10A5F000933C02EA0303934240F077820131102931 -+:10A60000F0D105E00C9991F84730002B40F06D82B5 -+:10A6100038465946139A43461BF0D8D83B22584631 -+:10A620001399F8F34BF0024660B141784B1EDBB250 -+:10A630001E2B07D888F80B1108F58670911C5278EC -+:10A64000F7F39AF4B9F862200023A8F83C20C8F880 -+:10A650004030B9F8623033B1D9F8582040F237139E -+:10A6600002EA030343B9D9F8583013F0400003D18C -+:10A670000646119016905EE0139B58461946CDF899 -+:10A68000C0B16E9326F02EDD119038B14378042BC3 -+:10A6900040F239820020064616904CE070986E9980 -+:10A6A000F8F318F6119050B108F1400300930898A0 -+:10A6B0004946119A08F13C0327F092DD10E0584614 -+:10A6C00013993022F7F3FAF770B1119008F14003B3 -+:10A6D000009308984946119A08F13C0327F08CDC56 -+:10A6E000002840F0108223E0584613994422F7F3E3 -+:10A6F000E5F7119080B108F14003009308984946AE -+:10A70000119A08F13C0327F0D7DB002840F0FB81C9 -+:10A7100001210E4616910EE0D9F8583013F0410F82 -+:10A7200000F0F181119A1646A8F83C20169202E03A -+:10A73000002301261693D8F8043023F4001323F0E5 -+:10A740004003C8F804303B685B6B002B3AD0D9F863 -+:10A75000CC3013F0020F35D11398CDF8C0B16E9004 -+:10A760000BE0C04607000080401B860038462946A3 -+:10A7700070AA6EAB18F0F2DE38B970986E99DD22CF -+:10A78000F7F39CF705460028F0D1404600211BF066 -+:10A79000ADD9BDB1D8F8043043F04003C8F8043057 -+:10A7A00097F8FA3173B14046297A1BF09FD998F88F -+:10A7B000D13013F00F0F05D0D8F8043043F4001354 -+:10A7C000C8F8043000231399304A5846009317F014 -+:10A7D00099DD4146024638461AF0D2DF1AF01005DC -+:10A7E0000DD0D9F8582040F2371302EA030333B9E9 -+:10A7F00012F0400F00F08D81002E40F08A810C99FC -+:10A8000091F8303053B93B6B1B68022B06D197F996 -+:10A810005C361BB914B94FF0130A24E03B6B1B687C -+:10A82000022B08D1089A53782BB11AF4806402D114 -+:10A830004FF0190A17E0384611F074DB0899D1F887 -+:10A84000C033984211D303230093079B002403F1E4 -+:10A850000A0238461721012301940294039419F047 -+:10A8600027D94FF0110A10945AE10C9890F838301B -+:10A8700073B13846494612F079D8D9F85035984224 -+:10A8800006D300214FF0110A109149E148D401008C -+:10A890000C9A92F8463013F0030F27D0D9F85820BD -+:10A8A00040F2371302EA030303B397F8692712F063 -+:10A8B000020F08D0D8F8043013F4803F03D0D8F842 -+:10A8C0004030022B0BD012F0010F0FD0D8F804301B -+:10A8D00013F4803F0AD0D8F84030012B06D1002273 -+:10A8E000384641461346009218F080D9D9F8CC304A -+:10A8F00013F4005F09D0D7F84C0141465A46139B28 -+:10A9000003F0D8FE002840F00481D8F8043013F09A -+:10A91000010F02D0012387F84D36D8F8043013F028 -+:10A92000011F02D1012387F84E36D8F8043013F402 -+:10A93000801F02D0012387F85136D8F8043013F471 -+:10A94000002F09D11598438E03F44063B3F5406F8F -+:10A9500002D1012387F85236D8F8043013F0020FE1 -+:10A9600002D0012387F84F36D8F8043013F0040FD3 -+:10A9700002D1012387F85036D8F8043013F4001FB1 -+:10A9800002D0012387F8FB31D7F8344720462AF05C -+:10A9900091D930B120462AF095D910B120462AF03D -+:10A9A00063D9D8F8043013F0007F1DD0012487F854 -+:10A9B00054460C9991F8463013F0030F14D091F9D6 -+:10A9C0004C308BB10221384618F0CAD8159A538EF4 -+:10A9D00003F44063B3F5406F06D138462AF002D83D -+:10A9E0003846214629F07ADFD8F8043003F40413FE -+:10A9F000B3F5001F02D1012387F853363B6B5B7D13 -+:10AA000013B1384620F0E8DA0C9890F8463013F08D -+:10AA1000030F02D0384620F091DBD8F8403043B91C -+:10AA20003DB1D9F8583013F0010F02D00123C8F816 -+:10AA300040300C99D9F8582091F838301BB9D7F824 -+:10AA40006C32994524D0B9F8620008BB12F0010FAE -+:10AA50001ED0D9F87030B3F1FF3F19D009EB830352 -+:10AA60005C6FACB1217A012901D0032910D1628930 -+:10AA7000E379009204F11402029208F11A020191A2 -+:10AA80000490059003923846494622693CF0F6DC72 -+:10AA9000B8F8D4302BB9D8F8100034F081DDA8F81C -+:10AAA000D400B8F8D4200C98109290F8463013F0E7 -+:10AAB000030F33D0D8F84030013B012B0AD8D8F827 -+:10AAC000043013F4802F05D038464146062220F08A -+:10AAD000E7D823E0D8F8043013F4802F1ED038468E -+:10AAE0004146062220F080D818E000214FF0120ADB -+:10AAF00011911091169113E000224FF00C0A11925F -+:10AB0000109216920CE000234FF00C0A169310934B -+:10AB100006E000204FF00C0A109001E04FF0000A10 -+:10AB20003EAC00212822204634ADF7F389F22846B6 -+:10AB300000212822F7F384F2D7F87C3533B107F5EA -+:10AB4000AE6120460C312822F7F316F21599234600 -+:10AB50003831099138464946099A00951BF076D953 -+:10AB60003E9B03F10804349B0BB10233E418D8F880 -+:10AB700004304846002BB8BF14340421002235F0BD -+:10AB800091DA97F8653604190BB10233E418D8F856 -+:10AB900004300DF5A57013F0400F18BF1A340021D2 -+:10ABA0002022F7F34DF2D8F8043013F4803F05D09B -+:10ABB000D7F8FC3434341B7803B11334D8F8083098 -+:10ABC00013F0400F06D0D7F84C014146524645F0ED -+:10ABD00041DC2418079A09F1C2030A3217920D9A30 -+:10ABE0000A9309F1BC006FAB0B9000900293002A0E -+:10ABF0000CBF102130213846179A0A9B019417F098 -+:10AC0000DBDB1490002800F0E5816F980123041924 -+:10AC100012940370013B43703B6B1B68022B05D100 -+:10AC200097F95C2612B91F3303704270D9F8582087 -+:10AC300040F2371302EA03035BB199F8603043B185 -+:10AC40000378427843EA022343F0100303701B0A9F -+:10AC5000437097F843365BB13B6B5B7D43B1037840 -+:10AC6000427843EA022343F4806303701B0A437073 -+:10AC7000002380F802A0C370109B037110990B0A87 -+:10AC80004371012106303FAB3E9A21F06DDAD8F8CE -+:10AC900004300646002B06DA0C21122207F5037356 -+:10ACA00021F062DA0646349A2AB13046322135ABB9 -+:10ACB00021F05ADA0646D7F8603648AC00229B7875 -+:10ACC0002046099946F05AD9D8F8043013F4803F49 -+:10ACD0003FD03B6B0DF5B5751B6804F11502022BD7 -+:10ACE00014BF002301234846294661AC21F09ED9B8 -+:10ACF0004846214621F0F6D830462D211A222B460F -+:10AD000021F032DA23463D21162221F02DDAD7F840 -+:10AD1000FC3406461B78E3B172AB012203F8012D27 -+:10AD20007F2121F021DAD7F8FC140DF5D574054602 -+:10AD300024310E222046F7F31FF138462146002227 -+:10AD400017F0EEDE28464A210E22234621F00CDAC7 -+:10AD50000646129AB24201D2002002E0129BC6EBD4 -+:10AD600003000423009001934846334600214FF02E -+:10AD7000FF3235F0D9D997F8653604462BB107F57F -+:10AD8000CC61043112F0C2DC0446D8F8043013F070 -+:10AD9000400F08D007F500732046DD211822063346 -+:10ADA00021F0E2D90446D8F8083013F0400F06D05D -+:10ADB000D7F84C0141465246234645F02BDB069816 -+:10ADC0000023D9F808200090019302933846149983 -+:10ADD000D26843461AF0A6DEBAF1000F40F0FA80BE -+:10ADE0001099159AA8F8D41092F860300E989BB27A -+:10ADF000834238BF0346A8F80231022140464AF098 -+:10AE00007FDB404649464AF0C5DAD9F8CC3013F426 -+:10AE1000801F09D03846494611F0A8DD012803D12A -+:10AE20003846494634F002D80C990D9A8B6AC8F816 -+:10AE300024305AB10B980F990622F7F381F028B10C -+:10AE400008981799D9F8082027F0CEDBD9F8082000 -+:10AE50000898179926F0CCDFD9F8CC2012F40053CB -+:10AE60000CBF1C4602243B6893F8463013F0030FD6 -+:10AE700007D012F4805F04D1B8F8063003F0010265 -+:10AE800000E000227F2300930192234648A808F1A6 -+:10AE90004401002246F030D9384641464AF032D9C2 -+:10AEA0000C9890F82F3063B1D8F8E81049B1C06819 -+:10AEB000D8F8EC20FBF31CF70023C8F8EC30C8F8F6 -+:10AEC000E830B9F86230002B33D0D9F8582040F27E -+:10AED000371302EA030363B312F0010F01D1119992 -+:10AEE00039B398F8DE300BB1119AB2B90C9890F8DA -+:10AEF0002F30F3B11199E1B14978C0680231FBF309 -+:10AF0000E7F6C8F8E800A0B1119B5A78194602325A -+:10AF1000C8F8EC20F7F330F00BE00224384608F1D3 -+:10AF20001A010B9A0A9BCDF8008001941DF02AD8D3 -+:10AF3000A246D9F8CC3013F4005F04D0D7F84C0106 -+:10AF4000494644F0FFD938464946012216F0E8DF69 -+:10AF500000231398009302930D9B0490002B0CBFC9 -+:10AF600008220A2238464946179BCDF804A0CDF89E -+:10AF70000CB011F0D3DD169860B3D9F87030B3F18E -+:10AF8000FF3F03D009EB83035B6F13B90DF5CD725F -+:10AF900002E003F5997312E0362313700DF5CD71BD -+:10AFA00026335370023201F110039A42F4D10C9A05 -+:10AFB00092F82F3013B137238DF89A310B46009356 -+:10AFC000F12301933846494608F11A02D8F8E830CF -+:10AFD00020F0FAD973B0BDE8F08FC0462DE9F04FEC -+:10AFE000D0F8ACA3D1B0D0F8B00389469DF86C116D -+:10AFF0000890DAF86801079206911E4683799DF859 -+:10B00000704113B1042149F0D3DA99F8063023B125 -+:10B0100099F80430002B00F09B813278737842EA73 -+:10B020000328B278F37842EA0323079A0993537806 -+:10B030001B0213F4804040F07D81099B012B00F03E -+:10B04000828083460E2545E1DBF8D830002B00F0E6 -+:10B050007F81F3789F0914B30AEB8703D3F88052FA -+:10B06000EDB12B69DBB12B7ACBB14CAC314603226D -+:10B070002046F6F381F705F114012A69E01CF6F386 -+:10B080007BF729690DF12E05204603312A46FDF391 -+:10B0900061F25A9A301D111F2A46FDF38BF2032FDD -+:10B0A00040D809EB87035B6F002B3BD01A695A9895 -+:10B0B0003146143301F02ADF002833D0321D3179B4 -+:10B0C000537841EA03289178D378B8F1010F41EA27 -+:10B0D000032309931FD1032B1DD1B37A06F10A0272 -+:10B0E000102B18D1DBF8D80006F10C010230527891 -+:10B0F000F6F326F7044670B95846414699F94820B8 -+:10B100004AF016DA8BF8DE805846414622464AF06D -+:10B110000FDA25460BE05846012199F9482049F0FD -+:10B1200099DF03E003234FF0010809930F25DBF8B3 -+:10B13000D810089E4A78F0680232FBF3D9F5002354 -+:10B14000CBF8D830C6E0D9F85050D9F84C60D9F8CF -+:10B150005410ADB10C46074609E00799062201F1EB -+:10B160000A002146F6F3ECF6063410B10137B74277 -+:10B17000F3DB012D02D1B74206DB01E0022D01D045 -+:10B18000002512E0B742FBDB03230093079B00245A -+:10B1900003F10A02504617212346019402940394B6 -+:10B1A00018F086DC0125A346AFE0BAF8822144F20C -+:10B1B00021339A4214D00E3B9A4211D007339A425F -+:10B1C0000ED010339A420BD0143B9A4208D007336A -+:10B1D0009A4205D010339A4202D025339A4200D1C8 -+:10B1E0000125079E504606F10A0421462A464AF0E8 -+:10B1F000DFDA014610B150464AF0E2DA0135002D9F -+:10B20000D3DD504621464AF0E3DB8346002800F0B8 -+:10B210009C8049464AF0BED8DBF8042012F4805FD7 -+:10B2200009D0089991F83030002B40F08E8022F43C -+:10B230008053CBF80430504659461BF0CDDEB8F1B0 -+:10B24000000F03D0B8F1010F16D041E0B9F95C301E -+:10B2500099F9482023B9584601214AF069D903E0F9 -+:10B260005846012149F0F6DE9BF8183013F0010F23 -+:10B2700069D000252C4632E0DBF8D81041B1089B9C -+:10B280004A78D8680232FBF333F50023CBF8D83084 -+:10B29000B9F86250002D56D1089E8221F068FBF368 -+:10B2A00017F5044608B945462FE0102303706FF0E8 -+:10B2B0007F0343702946DAF80C30B3F85A26631836 -+:10B2C000013180299A70F6D10025CBF8D84006E0EC -+:10B2D0000D2502E0099903293AD80024ADB9BBF144 -+:10B2E000000F12D09BF8183013F0010F0DD0079EFD -+:10B2F00050464946042206F10A0300950195CDF80F -+:10B3000008800395049511F009DC0999069A4B1CF5 -+:10B31000019300230393079B059203F10A0148461A -+:10B3200009F1BC025B46CDF80080029504941CF044 -+:10B33000F3DC0DE0079A504602F10A014AF02EDADA -+:10B34000834628B180E60D2500E001250024DCE7D6 -+:10B3500051B0BDE8F08FC0467FB5089D9DF82440F0 -+:10B360009DF82860009501940296FFF737FE7FBD97 -+:10B3700002292DE9F0410646D0F8AC5301D0002453 -+:10B3800001E000F575742B68D3F88C205368126CBB -+:10B390009B1822692361C2EB0302A3699A422378B6 -+:10B3A0000ED24BB9E26863699A4205D30123237038 -+:10B3B00063680133636028E0E3680133E36024E0FD -+:10B3C0000027E7600BB3012904D1284602311EF0A3 -+:10B3D00025DE18E0022916D1A868D6F8D01304F0AB -+:10B3E0003DD9D6F8CC3373B12B6893F87430012B68 -+:10B3F00007D02869012132F063D82A68012382F836 -+:10B400007430C6F8CC7300232370BDE8F081C046C9 -+:10B410002DE9F04F97B0DDF894B0D0F8AC6300237D -+:10B42000D0F8B0930C460746594630460392DDF8F3 -+:10B4300088A014931393129333F0DCDF039905462D -+:10B4400001F001030093484621465246239B17F022 -+:10B450003BDF1490002840F00783219A032A0DD97E -+:10B46000042213A82099F6F387F5219B072B05D911 -+:10B47000209A12A8111D0422F6F37EF5139C129A4D -+:10B48000B4F1000818BF4FF00108BBF1000F01D163 -+:10B49000D5F808B003998B1E472B00F2E182DFE854 -+:10B4A00013F0F900FE00010104016A007D008C0028 -+:10B4B000DF028E00DF029700DF0207010A01480069 -+:10B4C00058007F0195010D011F014E015401280212 -+:10B4D000DF029900A000AD00B00033013601FC008E -+:10B4E000DF023E024202DF02DF02DF02DF02DF0292 -+:10B4F000DF02DF02DF02DF02DF02DF02DF02DF0244 -+:10B50000770289028E02E500EF00E202A402DF0268 -+:10B51000DF02B402B702C002C302C602C902CC02F3 -+:10B52000DF02DC02CF02DF02DF02DF02DF021402F1 -+:10B530001B02D9F83430002B00F092820DAC30465B -+:10B5400007F56371224620F077DB50462146102232 -+:10B55000C3E0D9F83430002B00F0828211AC5146A0 -+:10B5600004222046F6F308F5304607F563712246BB -+:10B5700020F07EDB1FE0219A0023052A8DF857304A -+:10B5800040F22781384620990DF1570227F084DADE -+:10B590009DF8573014908AF8003064E251463046E6 -+:10B5A0004AF0FCD80146002800F0268238469AF876 -+:10B5B000062029F06FDC149055E29B4B00E09B4B7A -+:10B5C0000093384629465246239B27F0FFD9F2E7DD -+:10B5D000974BF5E7D6F83407FEF7CEFECAF8000021 -+:10B5E00041E2D6F834572846FEF7CEFE844200F3F7 -+:10B5F0002E8228462146FEF7C3FE34E2D5F85035A8 -+:10B600003BE03368DB691F692B79002B40F06B81CD -+:10B61000BC4200F31C82C5F85045139C18461946DD -+:10B620007318D3F84C2222B1937913B1954218BF05 -+:10B63000013004312029F3D1002800F01482C4EB3A -+:10B64000070393FBF0F000217318D3F84C224AB1A2 -+:10B6500093793BB1954205D0D2F85035834288BFEB -+:10B66000C2F8500504312029EED1FCE196F9A83842 -+:10B67000002B01DA002300E00123CAF80030F2E1D8 -+:10B68000B8F1000F01D0002301E04FF0FF3386F83E -+:10B69000A838E8E195F83C30EFE7AB79EDE785F8BD -+:10B6A0003C80E0E1D6F82837E7E7C6F82847DAE13A -+:10B6B000D7F8BC33E1E7C7F8BC43D4E16A7E049213 -+:10B6C00022B105A805F11A01F6F356F4049B1A1DE0 -+:10B6D000239B93427DDB504604A9F6F34DF4C2E16F -+:10B6E000202C02D96FF01103BCE12399231D99424C -+:10B6F0006FDB2B79002B40F0F68028460AF104011D -+:10B70000224633F039DAAEE195F83A30B5E7AB7955 -+:10B7100085F83A8085F83B80002B00F0A4812B79D6 -+:10B72000002B00F0A0813046294611F0BFDA3046E8 -+:10B730004FF000614FEAC86218F03CDA93E199F8E3 -+:10B740003830003B18BF012397E799F838301C1EAA -+:10B7500018BF0124444500F0868130461FF076DB97 -+:10B7600010B96FF015037DE154B1304601F0C2FE0F -+:10B77000736A23F4C0137362002389F8383072E1CE -+:10B78000736A304643F400237362022389F8383029 -+:10B79000D6F8AC38013B86F8A93805F081FE62E1A5 -+:10B7A000219A032A15D9002C05DB3046214614AA1C -+:10B7B00033F064DD05460DB12B795EE7149B13F180 -+:10B7C0001E0F40F05081CAF800504CE1239B072B1C -+:10B7D00002DC6FF00D0345E1032A01D1002703E0ED -+:10B7E000022A14BF00270127002C2DDB30462146FA -+:10B7F00014AA33F043DD054630BB149B13F11E0F32 -+:10B8000022D1129B002B1FDD87F0010300932A46F3 -+:10B810002B463046139933F0CBD9054650B96FF01B -+:10B820001A03149310E0C046991E8300A91E8300DA -+:10B83000F92A83003046294633F0A4DE149018B16B -+:10B840003046294633F0F8DD129B032B00F00B81C4 -+:10B85000022B00F00881149A3AB112F11E0F40F049 -+:10B860000281002B40F0FF80FCE0002B24DD2B79CF -+:10B87000002B40F0F88033681B6F13F0030F02D0E9 -+:10B880006FF00803EEE0AB7923B13046294633F080 -+:10B89000ABDC90E6D5F8CC3013F4005202D04FF078 -+:10B8A000FF33DFE06B7E304600920192294605F1BE -+:10B8B0001A022EF05DD8D6E06B79002B00F0D38011 -+:10B8C0003046294633F0DCDACDE015B195F9643520 -+:10B8D000D3E6CAF800501FE0F5B1002C1CDB012CA8 -+:10B8E0001ADC2B7913B16FF00403BBE085F86445D3 -+:10B8F000B9E099F818307BB199F82F3063B199F815 -+:10B9000030304BB999F83F3033B9D6F868319B796C -+:10B9100013B9B6F81637B0E66FF00103A2E033684A -+:10B9200093F83030A9E6336893F83030434500F09F -+:10B930009A80304633F024DF0446B8F1000F05D07A -+:10B9400043791BB13046214633F09ADA214630461E -+:10B9500088F0010233F01CDF04461490002840F008 -+:10B9600082803368012283F82F20B8F1000F03D0C2 -+:10B97000D6F8403583F834203368304683F8308079 -+:10B9800010F01EDA86F8DD41304605F0BDFD6AE0B4 -+:10B99000BAF80200F7F360F4E8B99AF80400BAF8CC -+:10B9A00002109AF800209AF801300090284628F0FA -+:10B9B000C3DD00E6D6F83437B3F8A4335DE624B926 -+:10B9C000D6F83437A3F8A4434DE0D6F85C01A1B211 -+:10B9D0003AF0E4DC10B96FF0130343E0D6F83437E3 -+:10B9E000BDF84C10A3F8A4133DE0BBF1000F03D049 -+:10B9F0009BF80430022B02D06FF01D0332E0384672 -+:10BA0000DBF8101027F01CD8D5E597F8F03334E6B2 -+:10BA1000E3B287F8D53387F8F033384626F0D6DE20 -+:10BA200021E0D7F8E83328E6C7F8E8431BE0D7F869 -+:10BA3000EC3322E6C7F8EC4315E097F8D4331CE664 -+:10BA4000D6F86C32D3F8D432DB8D9C4202DD6FF035 -+:10BA50001C0307E0A7F8C84305E0B7F8C8330CE6B5 -+:10BA60006FF016031493149817B0BDE8F08FC0461A -+:10BA70002DE9F0410468074686B020460E46904600 -+:10BA80001D461BF0B3D910B120461BF0A7D90C9B63 -+:10BA90002046029300230393049339460B22434626 -+:10BAA0000096019511F03AD806B0BDE8F081C04685 -+:10BAB00070B5114686B00546164649F06FDE04465D -+:10BAC00008B390F8DF3023B12846214601222AF03E -+:10BAD000B9D9204649F0E8DBE3681BB12846214686 -+:10BAE0003CF0CCD9002203230092019302920392EE -+:10BAF0000492284621690532334611F00FD82846B2 -+:10BB0000214649F05DDE06B070BDC04670B5036BDE -+:10BB1000002680F8D068D0F85C410546186907F027 -+:10BB200005F8014620463AF001DA20B12846012105 -+:10BB3000324618F031DA70BDF0B505688BB00646B4 -+:10BB40000021EF681DF0D6DA304610F01BDFD5F883 -+:10BB5000E4366BB1A868D5F8741503F07FDD0023D7 -+:10BB6000C5F8E43695F8583503F0FD0385F85835E7 -+:10BB7000D5F85C013AF0BAD92A6992F8EA3063B193 -+:10BB8000D36ED3F8202140F2044302EA0303B3F555 -+:10BB9000806F14BF0020012006E0106E03F054FEF9 -+:10BBA000D0F1010038BF002000283CD0284605F025 -+:10BBB00019FE2B6BD5F85C41186906F0B7FF0146FA -+:10BBC00020463AF0B3D930B195F8D0281AB92846B2 -+:10BBD000012118F0E1D9304611F06EDC4FF000433E -+:10BBE000C7F888310F21286931F010DE286940F24A -+:10BBF000FF3131F0F9DD2B6B1B68022B04D1286972 -+:10BC000095F8431631F05EDE284616F02DDC284606 -+:10BC100016F0F6D900232846694600931AF082D818 -+:10BC200028461DF0D7DB0BB0F0BDC0462DE9F04F24 -+:10BC30000668D0F8D022D0F8D81297B00746D0F8CE -+:10BC4000E8B23046069107921DF04CDC069BB068C6 -+:10BC5000196803F003DD384602212CF02DDEF7E1F0 -+:10BC6000D6F8D83603EB82035D686C8E04F470431B -+:10BC7000B3F5805F14BF38233C2356F8039004F4D7 -+:10BC80004063B3F5406F28D1336893F8463013F022 -+:10BC9000030F15D0D6F85C01D9F8041039F02EDD69 -+:10BCA00010F0080F0CD199F8EC304BB1D9F80030F6 -+:10BCB000022B12D1D6F8FC349B7813F0020F0CD073 -+:10BCC0002046F7F3AFF20E2894BF4FF400534FF421 -+:10BCD000805340F4306003439CB2D6F85C012146A7 -+:10BCE0003AF05CDB002800F0AE81688EF7F39AF240 -+:10BCF0000446688EF7F396F244F430640E288CBF45 -+:10BD00004FF480504FF400500443A1B238462BF05A -+:10BD100087DE002800F09781D7F8E832002B78D032 -+:10BD2000D3F8DC30002B74D04FF00001A7F85C1082 -+:10BD300095F8AA004FF00C0800FB08B0EA8814A997 -+:10BD400082F08002C2F3C0121C30F7F3D1F3BDF8C9 -+:10BD500050200DF1540AA7F8622095F8AA00514628 -+:10BD600000FB08B02030F7F321F4159B33BB95F8A6 -+:10BD7000AA1013AC01FB08B1042224312046F6F3CB -+:10BD8000FBF020469A490422F6F3DAF048B995F818 -+:10BD9000A920A2F10803DBB2022B40F254818DF8F6 -+:10BDA0004F2020465146F7F301F4024630B9009087 -+:10BDB000CDF8048095F832300293FAE0159B8D4956 -+:10BDC00013F0040F1CBF43F002031593159B30467C -+:10BDD00013F0020F1CBF43F00103159315AB009342 -+:10BDE0000423019301230293BB68002203931346AB -+:10BDF00017F0D6DA002207230192009395F8AA30B3 -+:10BE00003046029303920492394618322B4610F0C2 -+:10BE100085DEB5F8623013F0100F0FD0BA6D40F226 -+:10BE2000371302EA03034BB9734B1A7832B9012373 -+:10BE30000092019395F832300293FCE02846F6F325 -+:10BE40007BF518B100230222009327E03B6D002B05 -+:10BE500032D0336893F83030002B2DD11C469846F1 -+:10BE600009E0796D284641440622F6F369F008F1AD -+:10BE7000060818B10134FB6C9C42F2D33B6D012BD8 -+:10BE800003D1FB6C9C4206D316E0022B14D1FB6C51 -+:10BE90009C420DD210E0002300930322019295F8FA -+:10BEA0003220039302920493304639461722C7E0AA -+:10BEB000002304220093F1E7336893F8953083B1AF -+:10BEC000D6F84C35012B09D1284606F5AA61062281 -+:10BED000F6F336F0002840F0B68002E0022B00F0C6 -+:10BEE000B28095F9344074B9D6F85C01698E3AF0A5 -+:10BEF000E9D840B105230094019395F832300394BA -+:10BF000002930494D0E7B7F862306BB1BA6D40F297 -+:10BF1000371302EA03033BB1304639462A462BF079 -+:10BF2000A1DF002840F08F80D9F80030022B0AD121 -+:10BF300099F815203AB9FD33009305F1380009A9A5 -+:10BF40000123019214E0336805F1380093F846307C -+:10BF500009A913F0030317BFD7F8CC301A46C3F36F -+:10BF6000003383F001020192FF2300220093134665 -+:10BF700045F0C2D8336B09F1500493F8EC1039B195 -+:10BF80006B8E03F44063B3F5406F14BF1421282176 -+:10BF9000204645F059D8D6F86036002209A8214637 -+:10BFA0009B7844F0EBDF024630B9009009230193FF -+:10BFB00002920392049277E79DF8382096F838377A -+:10BFC0009A4240D195F93430C3B96A8E304602F4B2 -+:10BFD0007042B2F5805F14BF0222012205F13801E0 -+:10BFE0002BF0E4DC024648B90A230090DFE7C046A4 -+:10BFF00058D4010017738600B0270200336893F805 -+:10C00000303053B32946304649F0C8DB014620B3EF -+:10C01000037E13F0020F06D0436813F4805202D15E -+:10C020000D230092C3E7D1F8F030B3B100220F2303 -+:10C0300000920193029203920492304639461732DD -+:10C040002B4610F06BDDD6F8DC36013BC6F8DC364B -+:10C05000D6F8DC26002A7FF403AED6F8DC36FBB136 -+:10C06000069B00219977D6F8DC26D6F8D836013A17 -+:10C0700003EB8203C6F8DC26069A9C685368012B02 -+:10C080000AD0009101910291039104913046394602 -+:10C090002022234610F042DD38462EF011DA35E03A -+:10C0A000D7F8CC3013F4005F06D0FB7923B9D6F86B -+:10C0B0004C01394643F0F8DF0799FA7991F93430A9 -+:10C0C0004AB1002238460121934214BF00230123C4 -+:10C0D0002CF0DAD809E038460121D3F1010338BF4A -+:10C0E0000023009201922CF009DA97F91030022B0C -+:10C0F00003D1F86800214DF035DA96F875323846EC -+:10C1000023F0040386F875322CF0A6D917B0BDE8E9 -+:10C11000F08FC0462DE9F04F9B460568D0F8D0322D -+:10C1200089B003932B68064693F83F308A469046C1 -+:10C13000D0F8D872D0F8D492002B00F08281C37965 -+:10C14000002B00F07E81837C0DF1160013B106F107 -+:10C15000D60100E049460622F5F30EF700242B68CD -+:10C1600085F84A4593F844301BB1D5F8640135F0A1 -+:10C1700067DFB37C2BB1D5F84C013146224605F080 -+:10C1800067F82A6992F8EA305BB1D36ED3F82021C0 -+:10C1900040F2044302EA0303B3F5806418BF0124AC -+:10C1A00005E0106E03F050FB041E18BF0124CCB153 -+:10C1B000002130462FF012DA3046FFF7BDFCB37C89 -+:10C1C0003046D3F1010338BF0023009300210DF165 -+:10C1D00016020823FFF74CFC002130460A4632F0D5 -+:10C1E000CBDC1AE1B37C002B00F08F80D6F8DC3278 -+:10C1F000D3F8901041B193F894206868FAF378F579 -+:10C20000D6F8DC32C3F89040BB6823B10D2B02D0C6 -+:10C2100030462CF09BDAD5F86801042148F0C8D9E3 -+:10C220000DF11601284649F0B9DA002421460746E7 -+:10C2300086F8944030461CF06FDC2146304619F0F9 -+:10C240002DDC304621460FF01FDEBAF1000F45D03D -+:10C2500006F1BC00F6F380F300283FD12B6BB9F850 -+:10C260003240186906F062FC844237D1D5F85C018F -+:10C27000B9F8321039F0AADE30B9D5F85C01B9F856 -+:10C28000321039F01FDF80B1B8F1000F0DD1D5F8B1 -+:10C290005C01B9F8321039F049DE30B9DFF8ACA1F1 -+:10C2A0000123C34685F8D03800E0C24608230DF1CB -+:10C2B00016010193284606F1C2030A4600971BF0B7 -+:10C2C00091DE034658B1BAF1000F08D02846514616 -+:10C2D0005A4618F053D810B9824600E0C2460FB94A -+:10C2E0003C462FE038460E2148F0AADE2B6893F832 -+:10C2F000443023B1D5F86401394635F0B5DE28461F -+:10C3000039461AF069DE00241CE02B6893F895305A -+:10C3100093B1D5F8000507A948F0DCDE06E05368C4 -+:10C3200013F0005F1CBF23F00053536007A848F0D0 -+:10C33000D9DE02460028F2D10124B474304616F04A -+:10C34000B3DEC246304600212FF048D905F5007112 -+:10C35000284606311FF0E2DC2B6893F83F20A2B993 -+:10C3600095F9473685F84226B3F1FF3F08BF85F8B7 -+:10C370004326284619F0B2DA2B6893F8463013F0BA -+:10C38000030F02D0284619F0C5DA06F1BC00F6F317 -+:10C39000E3F2014630B930460DF11602082300944D -+:10C3A000FFF766FB95F872323BB9D5F86C329E42C6 -+:10C3B00003D13046FFF7C0FB05E0304611F07CD8D2 -+:10C3C000304610F0DFDAD9F8641049B16868B9F87E -+:10C3D0006820FAF38DF40023C9F86430A9F86830B6 -+:10C3E00002230DF11602009328463346002117F070 -+:10C3F0002FD93046002117F0FDDA304617F066DA03 -+:10C40000284605F081F8BAF1000F03D02846002134 -+:10C410005A46D047B8F1000F01D0002013E0304653 -+:10C420004146424632F0A8DB414606220398F5F326 -+:10C4300007F606F1BC0041460622F5F301F6404638 -+:10C4400001E04FF0FF3009B0BDE8F08F0DBB0000F8 -+:10C450002DE9F04F062989B007460D4692469B46C6 -+:10C460009DF848900468D0F8D86246D061BBB9F115 -+:10C47000000F03D12046394633F098DB94F872322E -+:10C48000002B3AD0D4F8000507A948F023DE03E0DA -+:10C490001B7E13F0020F30D107A848F023DE0346BD -+:10C4A0000028F5D151E0236B186906F03FFBD7F85F -+:10C4B000D4325B8E834220D0204628F00DD8D4F8A9 -+:10C4C000340728F027DC18E0B368093B012B14D8A7 -+:10C4D0002046114649F062D910B10C2148F0B0DD78 -+:10C4E000022D07D0A068316803F0B8D8052D01D01F -+:10C4F000012D02D14FF0010801E04FF00008139B1D -+:10C500000095CDF804B00293336C20460393736C0E -+:10C5100039460493B9F1000F0CBF07220922534694 -+:10C5200010F0FCDAB8F1000F13D0052D01D0022D68 -+:10C5300007D1B27F337F9A4203D238462DF0C0DF55 -+:10C5400007E03846FFF772FB03E07368032BAAD1BC -+:10C55000D3E709B0BDE8F08F0048704760E70100FD -+:10C560000048704780E8010010B5836F40F2EE226A -+:10C570001C6A044B94219C4208BF4FF4166231F0B0 -+:10C5800069DB10BD50200800816F10B508310446EA -+:10C590002FF06CDEFFF7E0FF014620462FF046DE6D -+:10C5A00010BDC0462DE9F04104460D469046BDF849 -+:10C5B00018E09DF81C701E4633B18368DA6A02EBFE -+:10C5C0004102938BFB1893834FF6FF739E4503D074 -+:10C5D000A821724631F03EDB04EB8503D868084B96 -+:10C5E000414632465B6A9847002807DA36B1A368AD -+:10C5F000DA6A02EB4502938BDB1B9383BDE8F08183 -+:10C60000E0A6850010B507490446406EF6F3E0F158 -+:10C61000034620B9606E0449F6F3DAF10346184682 -+:10C6200010BDC04699D501000AAA860070B50D4616 -+:10C630000669144608460A220021F5F301F56B88C5 -+:10C640001C43F36C6C8013F0200F03D02B8843F451 -+:10C6500080632B80B16F42F250030A8C9A4206D15C -+:10C660004B8C052B03D86B8843F004036B8070BDA3 -+:10C670004FEA810210B513188E468168DB6F52189D -+:10C680008367936B0B6390F8EB3063B190F8E830FD -+:10C690004BB94FF40051006EBEF1000F0CBF0A46BB -+:10C6A0000022FEF3BFF310BDB1F1FF3F2DE9F041D1 -+:10C6B00004460E4605D1836F596A09B90E4600E05B -+:10C6C0009E6994F8E9701FB9204639462FF004DBC3 -+:10C6D000206EFEF307F580B1002504EB8503D868D2 -+:10C6E00010B1254B9B6898470135062DF5D1E368BD -+:10C6F0001BB1204600212FF03BDB94F8E8203AB133 -+:10C70000A3680022DA612046032130F071DC30E0BA -+:10C71000206E46F0040184F8EA20FEF393F3A06F44 -+:10C72000012184F8EA1018B1406A08B106F0D0F887 -+:10C7300020462FF0F5DBE26E206ED2F8E0310121C9 -+:10C7400023F02003C2F8E031F9F326F4002120465B -+:10C750002FF0C2DA204630F03DDD2046012130F0D6 -+:10C7600011D9A2680023D3611FB9204602212FF0FE -+:10C77000B3DABDE8F081C046E0A6850070B50121BE -+:10C78000044631F0ABDA206E03F05CF8204600215D -+:10C790002FF0A2DA204630F0FDDE054630B120460B -+:10C7A000002131F09BDA6FF0080005E020464FF0E1 -+:10C7B000FF31FFF779FF284670BDC04673B50469A5 -+:10C7C000054620460E46FFF7DFFEA36F3146586A46 -+:10C7D00007F0F6FB2A68012382F8743020462FF018 -+:10C7E0007DDCA36F2046998A31F010D8A36F2046D4 -+:10C7F000D98A30F0F9DF204694F886102FF0FED960 -+:10C80000A36F204652219A8B31F024DAA36F502176 -+:10C81000DA8B204631F01EDA20462FF081DC2046EC -+:10C82000FFF7A2FE032300932046042108220023E1 -+:10C8300030F0F0DB20462EF0B1DF7CBD10B504698E -+:10C840004FF440412046002230F0D2DBD4F8F830DB -+:10C850001B691BB120462EF0A1DF02E020462FF01D -+:10C8600059DDE26C206E02F00202002A0CBF114674 -+:10C870004FF400710A460023FEF384F310BDC04656 -+:10C8800070B5836804461B6893F82050F5B9012100 -+:10C8900031F024DA206E02F0D5FF204629462FF031 -+:10C8A0001BDA20462FF036DDA068D0F848381B7818 -+:10C8B0000BB12FF061DBA36F586A05F0FBFFA36893 -+:10C8C00084F85E501A68012382F8203070BDC0469B -+:10C8D00070B5082986B005460C4602DD6FF00100F0 -+:10C8E0002DE1836897491B685869F6F345F0082CD9 -+:10C8F00024D12A6E936913F0005F03D0D36913F03B -+:10C90000010F0BD0EB6C13F0010F0BD02B6D13F05C -+:10C91000800F07D1D36913F0010F03D06B6D13F0B3 -+:10C92000005F05D12B6D13F0800101D10C4612E0A0 -+:10C9300043B2022B40F30181052400E05CB1D5F83D -+:10C94000F8305B68022B06DDAB6D13F0005F02D19F -+:10C950006FF00200F3E00A220DF10E000021F5F362 -+:10C960006FF3D5F8F8304FF000021A8195F8903047 -+:10C970000BB91E4604E0EB6ED3F8203103F001063C -+:10C9800095F8903053B164B9D5F8F8301B68002B96 -+:10C9900000F0888028462FF0BDDC83E0002C00F0FA -+:10C9A0008180BDF80E30D5F8F82043F01003ADF8C3 -+:10C9B0000E305368022B6B6D03D123F000536B656F -+:10C9C00039E043F0005314F0040F6B6503D1138971 -+:10C9D00043F0140313812A6E936913F0005F03D0B0 -+:10C9E000D36913F0010F0BD0EB6C13F0010F12D0D1 -+:10C9F0002B6D13F0800F0ED1D36913F0010F0AD005 -+:10CA00006B6D13F0005F06D0D5F8F820138943F062 -+:10CA1000400313810FE0D5F8F8305B68042B05D193 -+:10CA2000BDF8123043F40053ADF81230D5F8F820B9 -+:10CA300000231361D360D5F8F8205368022B12D17C -+:10CA4000EB6C13F4804FBDF8103008D043F48073C2 -+:10CA5000ADF810303023D3602023136103E023F4BA -+:10CA60008073ADF8103014F0020FD5F8F81003D031 -+:10CA70000B8943F0010304E00A894FF6FE7302EAD2 -+:10CA8000030314F0040F0B81D5F8F81003D00B89C1 -+:10CA900043F0080304E00A894FF6F77302EA030340 -+:10CAA0000B8109E0BDF80E3023F01003ADF80E3015 -+:10CAB0006B6D23F000536B65D5F8F8301C60AB6FDD -+:10CAC000696D586A06F08AF995F890301BB116B175 -+:10CAD000284630F033DF0224BDF80E30284600210E -+:10CAE0001022009430F096DABDF81030284601216B -+:10CAF0004FF48072009430F08DDABDF81230284681 -+:10CB000021464FF40052009430F084DA28462FF08A -+:10CB1000A1D895F8903073B1AB6F1B68A34206D1D2 -+:10CB2000D5F8F8301B6813B128462EF037DE16B161 -+:10CB300028462FF05DDF002001E00124FFE606B06B -+:10CB400070BDC046C65C860070B5054690F8900082 -+:10CB5000002846D0AB6F002185F89010586A05F088 -+:10CB6000BDFEAB681A6992F8EA305BB1D36ED3F8B8 -+:10CB7000202140F2044302EA0303B3F5806018BFAA -+:10CB8000012002E0106E02F05FFE68B10024AB6F7E -+:10CB900085F8EB4085F8EA40586A214605F098FE92 -+:10CBA000A8682FF033D91BE0286EFEF39BF20446F1 -+:10CBB00080B1EB6ED3F8203113F0010F02D028467C -+:10CBC00030F0BCDEAB689868F6F7F8FA0446284601 -+:10CBD00031F0A2D895F8E81011B9284631F07ED886 -+:10CBE000204670BD70B5054690F8900050B3AB6814 -+:10CBF0001A6992F8EA305BB1D36ED3F8202140F283 -+:10CC0000044302EA0303B3F5806418BF012403E080 -+:10CC1000106E02F019FE0446AA6814B100231362D4 -+:10CC20000CE0906802F056DD284621462FF054D8DB -+:10CC300095F8E83013B928462FF06CDBAB6F586AD3 -+:10CC400006F014FB70BDC0460121836F10B580F85B -+:10CC500090100446586A05F041FE204602212FF04C -+:10CC60003BD8A368986802F03FDD002010BDC046A5 -+:10CC70002DE9F3418668062733680DF10204DB696C -+:10CC800005461B6AD0F86C80C6F8AC3830493A4685 -+:10CC90002046F5F371F16B6C2E48214603FB07002B -+:10CCA0003A46F5F369F10423C6F8AC38013B86F83F -+:10CCB000A938A8681EF0CAD808B93C4604E0D6F8DE -+:10CCC000AC389B0001339CB2D5F8B8700026F05DFB -+:10CCD00004F0FF01201880B2421E02F0FF0341EA77 -+:10CCE000032102F48072C4F300231A43330243F495 -+:10CCF000004301369BB2062EA8F840350446A8F83A -+:10CD00002015A8F82C25A8F84035E0D12846982110 -+:10CD10007A7830F09FDFD5F8B83028469A219A7893 -+:10CD200030F098DFD5F8B8302846DC781A789C21A6 -+:10CD300042EA042230F08EDFD5F8B83028465C791C -+:10CD40001A799E2142EA042230F084DFBDE8FC819A -+:10CD500061DB0100301E02002DE9FF410569074635 -+:10CD60009221284630F05CDC400080B2A7F84200F7 -+:10CD700000282FD04FF000080DF101060F2130469A -+:10CD8000154A4346F5F3A0F1686E3146F5F320F6F7 -+:10CD900060B13146686EB7F84240F5F3EDF504EB4B -+:10CDA000480482B22146284630F054DF08F10108D9 -+:10CDB000B8F1770FE0D1686E0849F5F309F648B18C -+:10CDC000686E0649D5F8F840F5F3D6F52081284677 -+:10CDD0002EF040DFBDE8FF81AEAC8600177C8600F8 -+:10CDE0002DE9F041056986B04FF0FF31AC4A80462D -+:10CDF0002846EE6E30F0FCD8D5F8F8302846196891 -+:10CE0000FFF766FDAB6D3BB14FF00303A6F8B436F8 -+:10CE10004FF0FF03A6F8B836EB6C13F0010F27D0E4 -+:10CE2000A04A136823BB012111602B6D286E13F0FB -+:10CE3000800F03D0023102F0BBFD19E002F0B8FD13 -+:10CE40002B6D13F0005F13D12846922130F0E8DB00 -+:10CE5000400080B260B100F1CE042146284630F097 -+:10CE6000DFDB40F040022146284692B230F0F2DE8D -+:10CE70004FF0FF31C6F8281128468B4A30F0B8D859 -+:10CE80008A4C03E00A20F9F367F40A3CD6F828310B -+:10CE900013F0010F01D1092CF4D14046D6F8283106 -+:10CEA000FFF7CCFCD5F8F4302BB92B6E9A6A40F220 -+:10CEB00094539A4213D1286E7D4B826BD318012B69 -+:10CEC00007D94AF6E6039A4203D04AF6E5039A42A6 -+:10CED00005D10823002128220093FDF3D7F7002174 -+:10CEE0000A46286EFDF3B6F7FFF73AFB01462846DF -+:10CEF0002FF09CD92846FFF7BBFE4FF480330093F8 -+:10CF00002846062398210DF10E022FF0CFDCD8F829 -+:10CF1000003093F83830D3B140461DF097DF012838 -+:10CF200015D100231C461F4605930AE04FF4C02389 -+:10CF300000933946284605AA04232FF0DDDC01348E -+:10CF40002437D8F80030DB691B6A9C42EED32846B0 -+:10CF50008021082230F07EDE28465C210A2230F053 -+:10CF600079DE4FF08073534AC6F8003128465249A3 -+:10CF700030F03ED84FF00043C6F8883103F1024349 -+:10CF8000C6F88C314FF48043C6F8283103F540438E -+:10CF900073620121284630F019D8286E02F0A0FCF7 -+:10CFA00083B2A8F818001621A6F8A8362846B5F8C6 -+:10CFB000442030F04FDE2846C021B5F8542030F030 -+:10CFC00049DE2846C221B5F8562030F043DE3B4BFF -+:10CFD0002846C6F86031D6F86031B5F8883044216B -+:10CFE000C6F86431364BB5F88C20C6F86031D6F8F7 -+:10CFF0006031B5F88A30C6F8643130F02BDE28464F -+:10D000004621B5F88E2030F025DEB6F888361B05AF -+:10D010001B0DA6F888364FF00103A6F89C360023B6 -+:10D02000C8F848301C4605EB8403D86810B1254B7E -+:10D030005B6898470134062CF5D1224CE868236DD3 -+:10D040009847E36EE86898474046FFF785FE2B6EE9 -+:10D050009A6B4AF662139A421ED1EB6C13F0010FE1 -+:10D060001AD02B6D13F0800F16D113F0005F13D17F -+:10D070002846922130F0D4DA400080B260B100F14D -+:10D08000CE042146284630F0CBDA40F0400221465B -+:10D09000284692B230F0DEDD06B0BDE8F081C04631 -+:10D0A00004040004F02702000204020449420F00B5 -+:10D0B0001D57FFFF0000024000000640060002006E -+:10D0C00007000200E0A685002DE9F04790F8E9701E -+:10D0D00004460E469046856817B939462EF0FCDDA9 -+:10D0E000A86802F0F7DA06F47041B1F5805F14BF6A -+:10D0F0000021012181462046FFF7BAFAA36F31468D -+:10D10000586A05F00FFDA36F586A05F0EDFB28463D -+:10D11000FFF766FEB8F1000F04D0012120460A4651 -+:10D120002FF0D4DF28463146FFF748FBA868494670 -+:10D1300002F0E4DAD4F8D43043F00403C4F8D43075 -+:10D140000123C4F8D0301FB9204602212EF0C4DDDF -+:10D15000BDE8F087816810B50B680446D3F88C20D1 -+:10D16000D2F8B4300133C2F8B4300A6992F8EA3028 -+:10D1700063B1D36ED3F8202140F2044302EA0303E3 -+:10D18000B3F5806F14BF0020012006E0106E02F09E -+:10D190005BFBD0F1010038BF002020B120464FF0EA -+:10D1A000FF31FFF781FAA0682EF030DEA06819F099 -+:10D1B0008BDC10BDD0F8EC1010B5044631B100681E -+:10D1C0000C22F9F395F50023C4F8EC3010BDC046ED -+:10D1D0002DE9F04FD1F8D43289B0B3F832A0D0F8AD -+:10D1E0004C31804603938B798946D0F80CB0002BE4 -+:10D1F00000F0B58000273E4608EB8603D3F84C527A -+:10D200008DB1AB797BB9EB796BB1D5F8D432588E4F -+:10D21000F6F308F004465046F6F304F0844201D0D9 -+:10D220002F4606E02F460136082EE5D1002F00F0EC -+:10D230009680D7F8D432588EF5F3F4F7044650466A -+:10D24000F5F3F0F7844205D0D7F8D432D9F8D422D8 -+:10D25000DB8DD385404605A904AA18F08BDF39463B -+:10D26000D8F84C0141F0E2DF182300FB03F4D8F8B2 -+:10D270004C0104F13A0142F0C3DC38B9049A059B31 -+:10D28000039839460092019301F0DCFA04F1400161 -+:10D29000D8F84C0142F0B4DCD7F8D4320599DB8DD4 -+:10D2A00040019E02CE42079001D3B04209D321F043 -+:10D2B0007F4323F460038219984201D21046F6E7B7 -+:10D2C000079006AC07AD22462B46049803F0FAFC03 -+:10D2D000384618F0E5D929460346002220461DF0BD -+:10D2E000EDDDD9F8D4327608DB8D29469F02204641 -+:10D2F000334600221DF0FCDD3B46012101E049469A -+:10D300001346DA19B34201F10109F8D306A807A9B7 -+:10D31000002204AC05AD1DF0EBDD20462946069A3F -+:10D32000079B1DF0E5DD059B2046CBF88031049B73 -+:10D330002946CBF88431002304930593069A079B72 -+:10D340001DF0D6DDD8F84C010499059A42F010DFA3 -+:10D35000BB01CBF8883107FB09F3CBF88C3109B05E -+:10D36000BDE8F08F2DE9F34100EB8101D1F84C428B -+:10D37000064690461D469DF8207014B94FF0FF33C5 -+:10D3800019E004F11A0000212022F4F359F60023D9 -+:10D39000637615B9336803F14E054346304621469E -+:10D3A0002A46009730F09ADF034620B930462146DE -+:10D3B00032F0E8D803461846BDE8FC81D1F8CC30FD -+:10D3C00073B543F40053C1F8CC3005460C4632F037 -+:10D3D000D9D80646002840F08880B5F8822144F26A -+:10D3E00021339A421AD00E3B9A4217D007339A4201 -+:10D3F00014D010339A4211D0143B9A420ED0073306 -+:10D400009A420BD010339A4208D025339A4205D065 -+:10D41000AB6B5B7D13B96FF00B0666E02B6B93F87B -+:10D42000EC300BB91E4608E0B5F8263603F440632D -+:10D43000B3F5406F14BF142628262B6893F84630A6 -+:10D4400013F0030305D0D4F8CC30C3F3003383F0DA -+:10D4500001030093284633462146022231F024DAA4 -+:10D460000646002841D1D4F8CC3013F4803F0AD1CD -+:10D47000D5F84C01214641F0E1DFC4F8F00280B953 -+:10D480006FF01A0631E0062204F1BC0004F1C2017B -+:10D49000F4F372F5D4F8D432B5F8262683F8346064 -+:10D4A0005A86A379D3B194F8F532312B11D82B6871 -+:10D4B0001B7E2BB1284694F8F4120D4A1BF0B6DF00 -+:10D4C000D5F84C0194F8F41241F0FCDE322384F8D4 -+:10D4D000F43294F8F53284F8F43206E0D5F84C01D1 -+:10D4E00004F53D7141F0B2DE064630467CBDC046D3 -+:10D4F000329E85002DE9F041054632F041D90026E3 -+:10D500000746AB19D3F84C426CB1A3795BB1BC426E -+:10D5100009D063791BB12846214631F0B1DC284699 -+:10D52000214631F089DF0436202EEAD1BDE8F081B2 -+:10D53000002010607047C04610B505F021F810BDFE -+:10D5400010B504F05DFFC0B210BDC04610B508466E -+:10D55000114604F037FF10BD2DE9F0470446884618 -+:10D560004768002110469146C922F4F369F5204628 -+:10D57000414638F013DF78B997F85037002B00F0A8 -+:10D58000D08707F5AA6138460E3138F061D90646D2 -+:10D59000002800F0C68700E0266908F47043B3F560 -+:10D5A000805F14BF38233C233078FF5804F0D0FF4D -+:10D5B0000446B07804F0B4FF637C5FFA88F513F09A -+:10D5C0000102064602D097F904E106E097F904311A -+:10D5D000182BD4BF9646A3F1180E934B9C4203D14F -+:10D5E00058214FF0520C0BE0904B9C4205D0904BD1 -+:10D5F0009C4202D04FF07F0C01E04FF0580C614686 -+:10D600003B68022B5FD1012D01D8002303E00A2DD6 -+:10D610008CBF02230123E31893F90620854B9C421B -+:10D6200003D10B2D10D14C2240E0834B9C4203D1FF -+:10D630000E2D3BD1362239E0804B9C4202D0804BEC -+:10D640009C4204D10B2D30D00E2D2ED02EE07D4BE0 -+:10D650009C4203D10E2D29D12A2227E07A4B9C42ED -+:10D6600007D1022D01D1582220E00A2D1ED15422CB -+:10D670001CE0764B9C4203D10A2D17D1502215E0B5 -+:10D68000734B9C4203D10E2D10D128220EE0714B1A -+:10D690009C4203D10B2D09D13E2207E06E4B9C42E8 -+:10D6A00004D10C2D02D1442200E04022CEEB020333 -+:10D6B00023EAE3738B42A8BF0B46002202F809302D -+:10D6C0000132042AFAD1654B9C4208D0644B9C423B -+:10D6D00005D0644B9C4202D0634B9C4207D197F922 -+:10D6E0000431182BD4BF4FF0000EA3F1180E3A6886 -+:10D6F000022A40F01081012D01D8032303E00A2DF6 -+:10D700008CBF05230423E31893F90600494B9C4280 -+:10D7100001D10B2D6CE0554B9C4204D1022D00F041 -+:10D720000E810A2DCFE0444B9C4201D10B2D58E0D5 -+:10D73000424B9C4202D0424B9C4201D10B2D11E046 -+:10D740004B4B9C4202D04B4B9C4204D10D2D40F0E0 -+:10D7500007812E2004E1484B9C4206D10B2D00F09E -+:10D76000F2800D2D00F0F380FAE03E4B9C4258D041 -+:10D77000344B9C4204D10B2D40F0F2803E20EFE070 -+:10D78000314B9C4219D0314B9C4206D1022D00F006 -+:10D79000E4800A2D00F0E180E2E0384B9C4206D1A3 -+:10D7A000022D00F0D8800A2D00F0D580D8E0344B4F -+:10D7B0009C4202D0334B9C4206D1022D00F0C9801E -+:10D7C0000A2D00F0C680CBE02F4B9C420CD1022DDD -+:10D7D00000F0BD800A2D00F0BA80032D00F0BF805C -+:10D7E000092D00F0BC80BBE0284B9C4203D10A2DE0 -+:10D7F00000F0A780B4E0164B9C4205D1A5F10C03C4 -+:10D80000012B40F2A280ABE0214B9C4203D10B2DB7 -+:10D8100000F29D80A4E01F4B9C423DD10C2D00F0F6 -+:10D8200096800D2D75E0C046BC108600F010860075 -+:10D8300024118600400986002CDC0100BC0C860007 -+:10D84000D00C8600700D86007C0986009009860049 -+:10D85000840D8600DCDC010094DE0100340D8600BE -+:10D860005C0D860080118600FC0D860080DE0100C4 -+:10D87000E40C86000C0D8600FCE30100CC09860058 -+:10D88000A4098600B8098600F409860018098600F4 -+:10D89000980D8600381186008C4B9C4203D1022DD6 -+:10D8A00055D00A2D26E08A4B9C4231D0894B9C42B0 -+:10D8B00003D10B2D54D1322052E0874B9C4204D12E -+:10D8C0000B2D40D00C2D3AD04AE0844B9C4205D120 -+:10D8D0000C2D44D00D2D43D13A2041E0804B9C4289 -+:10D8E00004D1A5F10B03012B29D939E07D4B9C42D2 -+:10D8F00002D10B2D29D033E07B4B9C4205D10C2D5E -+:10D900002BD00D2D2CD144202AE0784B9C4227D1DE -+:10D910000B2D18D024E0332D01D800200BE03D2D35 -+:10D9200001D8012007E0632D01D8022003E0942DE7 -+:10D930008CBF04200320231893F9060010E04A202E -+:10D940000EE042200CE038200AE03C2008E04020B5 -+:10D9500006E0502004E0482002E04C2000E0462091 -+:10D96000CEEB000323EAE3736345B4BF1846604679 -+:10D97000022A04D199F800309842A8BF1846002224 -+:10D9800009EB02030132082A1871F9D1C0B2CC4662 -+:10D990004A4600210023013182F83430107382F8A6 -+:10D9A0003C3001320829F5D1337F13F0010202D057 -+:10D9B00097F9040106E097F90431182BD4BF1046FB -+:10D9C000A3F118003B68022B01D16B1E0FE0332D31 -+:10D9D00001D800230BE03D2D01D8012307E0632D82 -+:10D9E00001D8022303E0942D8CBF04230323F256B5 -+:10D9F0009B19997B3E4B9E4205D1A5F16403022BF6 -+:10DA000001D83E2110E03B4B49B29E4203D1642D28 -+:10DA100000F05C850BE0384B9E4205D1A5F1640314 -+:10DA2000022B01D83E2108E0344B9E420ED0344BED -+:10DA30009E420BD0334B9E4208D0334B9E4205D0C2 -+:10DA4000324B9E4202D0324B9E4214D1A5F1680364 -+:10DA5000242B10D82B4B9E421BD02B4B9E4218D010 -+:10DA60002B4B9E4215D0264B9E4223D0274B9E42E5 -+:10DA700020D044224A21274B9E420CD1A5F16803B5 -+:10DA8000202B03D98C2D00F03F8549E04422402112 -+:10DA900001E042224A21204B9E420DD1642D06D046 -+:10DAA000A5F168030C2B3BD840223C216CE04022BE -+:10DAB000342101E044210A46184B9E4230D1A5F1A1 -+:10DAC0006403102B2CD85222422160E068098600A2 -+:10DAD000DCDC0100B4DC010010DD010094DE01009B -+:10DAE00014E10100A8DE0100BCDE0100C8DC010079 -+:10DAF000B50886005BE30100D2088600DC058600DD -+:10DB00002E0586004B058600680586008505860083 -+:10DB100033068600F90586006D0686008A068600B3 -+:10DB20009C4B9E421AD1A5F16403082B98BF30216B -+:10DB3000A5F16E0398BF3422162B98BF4621A5F19C -+:10DB40008603022B98BF3E218C2D08BF3622A5F1FB -+:10DB5000950308BF48210F2B98BF44228E4B9E424D -+:10DB600012D1A5F16E03162BA5F1860398BF3A22B8 -+:10DB700098BF4421022B98BF3A2298BF3E218C2D9A -+:10DB800008BF362208BF4821844B9E4202D0844BF6 -+:10DB90009E4204D1A5F18403082B98BF2C22814B0F -+:10DBA0009E4202D1262D08BF2C21C0EB020323EA9E -+:10DBB000E377C0EB010323EAE37E4A4613790021B1 -+:10DBC000137582F8441009F1080301329A42F5D125 -+:10DBD0004B460A4601321F7783F84CE00133082A8E -+:10DBE000F8D1714B9E425BD0704B9E4258D0704B27 -+:10DBF0009E4255D06F4B9E4252D06F4B9E424FD0AB -+:10DC00006E4B9E4236D06E4B9E4249D06D4B9E422B -+:10DC100046D06D4B9E4243D06C4B9E4240D06C4BE5 -+:10DC20009E423DD06B4B9E423AD06B4B9E423DD0C4 -+:10DC30006A4B9E4234D06A4B9E4231D0694B9E4221 -+:10DC40002ED0694B9E422BD0684B9E4228D0684B09 -+:10DC50009E4225D0674B9E4222D0674B9E421FD0EA -+:10DC6000664B9E421CD0664B9E4219D0654B9E422D -+:10DC700016D052E0032D02D14FF03C0E0FE02B1FC7 -+:10DC8000042B0AD9092D00F04384A5F10C03012BC4 -+:10DC900000F217842C2700F015BC4FF0400E4027EF -+:10DCA0004D4B9E4202D04D4B9E4207D1EB1E082B9E -+:10DCB00094BF4FF0400E4FF0000E4027524B9E4253 -+:10DCC00022D1A5F124030C2B03D838274FF0300EB6 -+:10DCD0001AE0A5F13403082B03D84FF0440E774621 -+:10DCE00012E0A5F16403022B03D834274FF03E0E57 -+:10DCF0000AE0A5F16803202B03D844274FF04A0E11 -+:10DD000002E08C2D08BF32274B46002201321F75DE -+:10DD100083F844E00133082AF8D14B460022002161 -+:10DD2000013283F8241083F854100133082AF6D105 -+:10DD30004B460A46013283F82C7083F85CE00133CD -+:10DD4000082AF7D1184B89F864E09E4206D0174B99 -+:10DD50009E425BD0174B9E4270D0CEE0012D00F06A -+:10DD6000A780022D00F09980032D00F0A6802B1FC4 -+:10DD7000042B04D84C273C2338243E21A1E0092D54 -+:10DD800001D14C2750E00A2D00F087800B2D00F0C8 -+:10DD90008F808EE0A2058600BF0586002C078600D6 -+:10DDA000F40486002CE201007E0A86009B0A8600AD -+:10DDB000B80A8600F20A8600BD0B8600980E86001F -+:10DDC00040DC01006AE0010097DC010046DE010052 -+:10DDD00001DF0100E4DE0100630F860014108600FD -+:10DDE000B50E860024DD010041DD0100D2DD010019 -+:10DDF000EFDD01005DDC01007ADC01000CDE0100DA -+:10DE000029DE0100880C8600DC058600012D4FD03C -+:10DE1000022D44D0032D01D14C2743E02B1F042BAE -+:10DE20004BD9092D04D14A2734233024362148E028 -+:10DE30000A2D34D00B2D3CD136273AE0012D01D1EB -+:10DE40002C2736E0022D31D0EB1E052B18D8032DE0 -+:10DE500004D144272C2328242E2132E0042D20D065 -+:10DE6000082D1ED06B1F022B4FF044078CBF0023E0 -+:10DE700038238CBF002434248CBF00213A2120E0B9 -+:10DE8000092D04D142272E232A24302119E00A2DFE -+:10DE90000CD00B2D0DD12A270BE0402709E03E279F -+:10DEA00007E044273623322438210AE03C2700E0EB -+:10DEB000382700231C46194603E04C273823342416 -+:10DEC0003A214A460020042894BF82F84C4082F848 -+:10DED0004C300130177701320828F4D1FCB24A46A1 -+:10DEE0000020032894BF82F85C3082F85C10013077 -+:10DEF00082F82C4001320828F3D1A74B9E4206D06D -+:10DF0000A64B9E420DD0A64B9E4221D062E0032D2F -+:10DF100045D0092D43D02B1F042B38D83024342270 -+:10DF200033E0032D03D14224462248203AE0042D59 -+:10DF300031D06B1F022B03D84C245022522031E0E9 -+:10DF4000082D28D0092D22D13E244222442029E048 -+:10DF5000032D03D12E243022322023E0042D03D1BF -+:10DF60003024322234201DE06B1F022B03D83224D0 -+:10DF700036223A2016E0082D03D1302434223820EE -+:10DF800010E0092D03D12E24322236200AE000228F -+:10DF90001446104606E046244A224C2002E028247B -+:10DFA0002C222E204B460021042994BF83F84C409C -+:10DFB00083F84C20013101330829F5D14B4600216B -+:10DFC000032994BF83F85C2083F85C00013101339E -+:10DFD0000829F5D1734B9E422AD1032D0CD02B1F5B -+:10DFE000042B03D838203C213E2408E0092D03D01F -+:10DFF000002108460C4602E0342038213A244B46E2 -+:10E000000022042A94BF83F84C0083F84C1001329C -+:10E010000133082AF5D14B460022032A94BF83F826 -+:10E020005C1083F85C4001320133082AF5D134E0FA -+:10E030005D4B9E422AD1A5F124030C2B01D8382731 -+:10E0400004E0A5F134030C2B03D83A274FF0340E2B -+:10E0500012E0A5F16403282B03D83C274FF0400EB3 -+:10E060000AE0A5F19503102B8CBF002746278CBF33 -+:10E070004FF0000E4FF0480E4B46002201321F7544 -+:10E0800083F844E00133082AF8D10AE0474B9E4266 -+:10E0900069D0474B9E4200F0DF80464B9E4200F025 -+:10E0A000DB80454B9E4200F0D780444B9E4200F0FF -+:10E0B000D380434B9E4200F0CF80424B9E4200F003 -+:10E0C000CB80414B9E4200F0C780404B9E4200F007 -+:10E0D000C3803F4B9E4200F0BF803E4B9E4200F00B -+:10E0E000BB803D4B9E4200F0B7803C4B9E4200F00F -+:10E0F000B3803B4B9E4200F0AF803A4B9E4200F013 -+:10E10000AB80394B9E4200F0A780384B9E4200F016 -+:10E11000A380374B9E4200F09F80364B9E4200F01A -+:10E120009B80354B9E4200F09780344B9E4200F01E -+:10E13000F481334B9E4200F08F80324B9E4200F0C0 -+:10E140008E80314B9E4200F08780304B9E4200F023 -+:10E1500083802F4B9E427FD02E4B9E427CD02E4BF5 -+:10E160009E4271D0B5E0A5F12403082B02D84FF0F0 -+:10E17000380E67E0A5F12E03022B40F29880A5F13E -+:10E180003403082B01D8382792E0A5F13E03022B77 -+:10E1900044D8342747E0C046D50A8600A00B860045 -+:10E1A000DA0B86004E0C860011058600F905860004 -+:10E1B00049E2010066E20100A9E301001EDF01005F -+:10E1C0004DE0010013E0010098DD0100D8E00100FE -+:10E1D000F0DC0100F6DF0100F5E001008CE3010056 -+:10E1E00075DF010083E2010030E001000CDC01007A -+:10E1F000BCDF01005BE30100DCE3010063DE010042 -+:10E200005EDD01007BDD01003EE30100D9DF01009E -+:10E210003BDF010058DF010016068600A5F164030C -+:10E22000082B03D844274FF0380E49E0A5F16E03C0 -+:10E230001E2B01D832273BE0A5F19503102B36D9D0 -+:10E240004FF0000E77463BE0A5F124030C2B37D8A6 -+:10E2500038274FF0340E33E09E4B9E4201D1242DDF -+:10E260005CE19D4B9E4203D18C2D29D13A2727E0BA -+:10E270009A4B9E4204D1642D1FD08C2D1DD01FE0DF -+:10E28000974B9E4203D1A5F19503102B0DE0954BC2 -+:10E290009E4215D1A5F124030C2B10D9A5F134030E -+:10E2A0000C2B0CD9A5F16403282B08D908E04427CE -+:10E2B0004FF0400E04E0382702E0482700E03C27FA -+:10E2C0004B46002201321F7583F844E00133082ACF -+:10E2D000F8D1854B9E420BD0844B9E4208D0844B94 -+:10E2E0009E4205D0834B9E4202D0834B9E426DD10D -+:10E2F000A5F12403082B0DD87F4B9E4201D13A2073 -+:10E3000006E07E4B9E4202D13420014655E0342087 -+:10E31000382152E0A5F12E03022B08D8774B9E42FC -+:10E3200014BF3821342114BF4220402045E0A5F11C -+:10E330003403082B02D8462144203EE0A5F13E03D9 -+:10E34000022B06D86D4B3A219E4214BF34202C205C -+:10E3500033E0A5F16403082B06D8684B3E209E42AB -+:10E3600014BF44213A2128E0A5F16E031E2B17D8D3 -+:10E37000A5F18603022B09D85F4B9E4201D14420B0 -+:10E3800005E05E4B9E4201D13C2000E048208C2DF0 -+:10E3900010D1594B9E420FD0584B9E420CD009E0F1 -+:10E3A000A5F19503102B8CBF002146218CBF0020C6 -+:10E3B0004A2002E0442100E03C214B460022013289 -+:10E3C000197583F844000133082AF8D14C4B9E425A -+:10E3D00002D04C4B9E421ED1A5F124030C2B01D838 -+:10E3E00038210EE0A5F134030C2B09D9A5F1640303 -+:10E3F000282B05D9A5F19503102B01D9002100E0A8 -+:10E40000402108464B4600220132187583F844101B -+:10E410000133082AF8D14846002202EB090191F89D -+:10E420003C301BB990F84C3081F83C304AB999F82F -+:10E430003D300BB1013204E090F84C30012289F8F4 -+:10E440003D3001320130072AE7D94A46002192F8CF -+:10E4500044301BB992F84C3082F84430013101321B -+:10E460000829F4D14846002202EB090191F8343022 -+:10E470001BB990F8443081F834304AB999F83530F6 -+:10E480000BB1013204E090F84430012289F83530B4 -+:10E4900001320130072AE7D900229CF824301BB949 -+:10E4A0009CF81C308CF824309CF854301BB99CF834 -+:10E4B0004C308CF854300132082A0CF1010CECD1AC -+:10E4C0002FE040274FF0000EFFF7F8BB3822FFF790 -+:10E4D000ABBAC0467BDD01003EE301003BDF01003B -+:10E4E000F6DF01008CE301004B058600680586001D -+:10E4F0008505860033068600A2058600BF058600D6 -+:10E50000A70686005006860036210A46FFF708BB9C -+:10E5100040274FF0380EFFF7C3BB642D3FF4CBAE5E -+:10E52000CEE6BDE8F087C0462DE9F041069D0746DE -+:10E530000E4610461946002A4ED0002B4CD0002D16 -+:10E540004AD0B30A012B3FD914790EF031FEE40909 -+:10E5500001460023384622460FF046D895F8651547 -+:10E56000012911D195F86725531C0F2A85F86735C5 -+:10E5700032D90023C5F86865064685F8653585F803 -+:10E58000661585F8673527E095F8662532B90123C9 -+:10E59000114685F86635C5F8686513E0D5F8683525 -+:10E5A000F11A09D48B12012B06D995F86725531C53 -+:10E5B0000F2A85F8673505D9002385F86735C5F832 -+:10E5C000686519460E1807E0012385F86535013B9B -+:10E5D00085F8673585F866353046BDE8F081C04678 -+:10E5E0002DE9F3410A9D0B9E9846002304463360B3 -+:10E5F00017462B600846D9B18B784A781B0443EA4A -+:10E6000002230A781343CA78043143EA0263336071 -+:10E610008B784A781B0443EA022302791343CA78B1 -+:10E6200043EA02632B60427A037A53EA022001D163 -+:10E630004FF48060296832680EF0A2DE0C9B014620 -+:10E6400000933A4643462046FFF76EFF04463146A4 -+:10E650002846002223461CF04BDC0898099900222A -+:10E6600023461CF045DCBDE8FC81C046F0B50768D8 -+:10E670001C460E4687B019463846154617F07ADD17 -+:10E680002268D6F8A0309A4202D22B68013B2B6058 -+:10E69000D6F8A030002223600C9B384602930D9BD5 -+:10E6A000716E03931346009501940492FFF798FF4F -+:10E6B00007B0F0BD2DE9F04F8A460668002189B009 -+:10E6C000834690461F4689460D460791069105915F -+:10E6D000029103912BE063789D1C029B43B907AB29 -+:10E6E0000093304621462A4602233EF017DD029071 -+:10E6F000B9F1000F08D106AB0093304621462A46F7 -+:10E700000D233EF00BDD8146039B43B905AB00931F -+:10E71000304621462A4610233EF000DD0390C5EB2B -+:10E7200007031B1B03EB080704EB05080125404604 -+:10E730003946F4F3B7F504460028CCD1304607A992 -+:10E740003EF036D8304606A93EF032D8CDB1DAF8E0 -+:10E75000083043F04003CAF80830029B9BB1B9F17E -+:10E76000000F01D1039B73B1DBF810305AF803306E -+:10E770003BB9584651463DF0FFDE10B16FF01A002C -+:10E7800003E0002001E04FF0FF3009B0BDE8F08F5A -+:10E790002DE9704F066886B08B46104619469046A4 -+:10E7A0009A460F9C109D0EF003FD014630460EF078 -+:10E7B000F9DE41468146224630462B4617F002DDFF -+:10E7C0002046294600224B461CF078DB119B304640 -+:10E7D0000293129B0E99039342465346009401956F -+:10E7E000CDF810B0FFF7FCFE06B0BDE8708FC04654 -+:10E7F00043682DE9F04106460C4617460568F3B11B -+:10E8000099421CD12B681B7E73B1284691F8F412F3 -+:10E8100004F1C2021AF00ADE7368212293F8F4129E -+:10E82000284613461AF00CDEF37B022B07D13B6817 -+:10E830002BB9384606F114012422F3F39DF3BDE809 -+:10E84000F081C0462DE9F7430A9C0B9D0F46814697 -+:10E85000164698460094019540F00ED94346484626 -+:10E86000394632460094019540F0F4D901224846D9 -+:10E87000394640F0D7D9B7F8343513F0100F03D02C -+:10E88000484639463EF008D8BDE8FE8370B58B791E -+:10E8900006461546002B2DD0D1F8CC3013F4005F7E -+:10E8A00028D0107828B15378092B02D86FF00100D6 -+:10E8B00024E0D1F8F042237F834204D1E8B1627FA3 -+:10E8C0006B789A4219D020776B786377638843F02E -+:10E8D000020313F0080F63800FD0304621463EF04C -+:10E8E00063DD304621463EF043D9304621463EF0B6 -+:10E8F000BBDE02E04FF0FF3000E0002070BDC046FC -+:10E900002DE9F743D0F8009004460027E31993F867 -+:10E910003B80B8F1FF0F4CD0FD0000262046294671 -+:10E9200041F06ED9002840D020462946002241F00F -+:10E9300085DE4846414601AA30F0A0DC002834D0EC -+:10E94000D0F8F01221B9002E2FD10EF059D92CE0B9 -+:10E95000837933B1D0F8CC3013F4005F01D0037960 -+:10E960001BB34B8813F0080F1FD0032E1DD8DFE810 -+:10E9700006F002060F1620463EF0C8DE15E013F042 -+:10E98000020F12D00B7F83B120463EF0FBD80CE083 -+:10E9900013F0010F09D020463DF0AEDF05E013F083 -+:10E9A000010F02D020463FF035DA01360235042E41 -+:10E9B000B4D10137042FA9D1BDE8FE832DE9F3417D -+:10E9C000D0F8008007463EF021D9AE21404617F02E -+:10E9D000C7DB4000B8641421404617F0C1DB262491 -+:10E9E000A7F84C0021464046284A1AF01FDD214670 -+:10E9F000002340464FF6FF7201341AF021DD322C1D -+:10EA0000F0D126E0294600223846013441F016DED6 -+:10EA100002350C2CF6D118369A2E1BD11DE0294652 -+:10EA200000223846013441F009DE0235042CF6D1CB -+:10EA30000836202E12D114E029460022384601342F -+:10EA400041F0FCDD0235042CF6D10836BA2E09D18E -+:10EA50000BE03A2635460024D4E70026354600244C -+:10EA6000DDE79A2635460024E6E7384620210022D5 -+:10EA700041F0E4DD032310220093404604211346B5 -+:10EA800015F0A2D80020BDE8FC81C046329E85006A -+:10EA9000F0B50E4649691569908A0A68002A01DABC -+:10EAA000821831D44C68131983422DD8B36801F110 -+:10EAB000080C0CEB040705EB020E6BB9184608E0D6 -+:10EAC00010F80E3010F80C20C15D134099421BD194 -+:10EAD0000130A042F4DB19E0012B15D12B18C4EB57 -+:10EAE00003050DE010F80E3010F80C20C15D134046 -+:10EAF000994203D10130A042F4DB07E00EF1010E90 -+:10EB0000AE4501D80020F6E7002000E00120337B6D -+:10EB10000BB180F00100F0BD036870B50446586881 -+:10EB2000A36A0D46164623B99021F8F3D1F0A062EE -+:10EB300070B1A06A0123AA8A03607F3382604660B5 -+:10EB4000C360296910309A4228BF1A46F3F314F2C1 -+:10EB500070BDC04668468369416920300BB52038D6 -+:10EB600003695A4651460EB44A46414606B4C36844 -+:10EB700082684168FEB40368C269EFF303810EB492 -+:10EB80008269EFF3058106B4034801680029FED0CD -+:10EB90006846884714B000BD3CEC00000A490842B2 -+:10EBA00002D062B6C94308400849084202D061B6A3 -+:10EBB000C943084006490840002803D005490A68AF -+:10EBC00002430A607047000000000080000000401F -+:10EBD000FFFF000000E100E00A49084202D072B6DF -+:10EBE000C94308400849084202D071B6C9430840E9 -+:10EBF00006490840002804D005490A68C04302407D -+:10EC00000A6070470000008000000040FFFF000025 -+:10EC100080E100E0024909689022885870470000AE -+:10EC200048EC0000024909689C22885070470000A7 -+:10EC300048EC0000DDBAADBB0000000000000000A1 -+:10EC400000000000000000000000000000000000C4 -+:10EC50000000000000000000024A11681060081C5B -+:10EC6000704700003CEC0000024A11681060081C6C -+:10EC70007047000040EC0000034908600348016849 -+:10EC80000029FED08847FEE734EC000040EC00008D -+:10EC90006348644900220A500168634A0A40634F8E -+:10ECA0000F403F4232D1002398469A46604A0A40BC -+:10ECB0001821CA405F4943585F4C1C405F4DAC422D -+:10ECC00004D180465E4D4519A9460EE05D4DAC422B -+:10ECD0000BD182465A4D4519AB460F241D1C2340CB -+:10ECE000594C25402D0A2B439C460023984501D0C2 -+:10ECF0009A4504D1554BC018013ADCD105E0504685 -+:10ED0000004202D04046004229D1FEE7FC21415892 -+:10ED10000A680F2313400F2BF1D0012B01D00431CF -+:10ED2000F6E708314A4B13404A4CA34206D100F0A3 -+:10ED3000BBF8804600F0C4F88146E9E7464CA342A0 -+:10ED4000E6D10B1F1B68454C23401824E3409C462A -+:10ED500000F0AAF8824600F0B3F88346D8E74049AD -+:10ED6000212242502E4A3F498958FF23194219D087 -+:10ED700051683D4B194215D011683C4B1940D36A7C -+:10ED800010E0A3420ED0C0460CE039498958194220 -+:10ED900008D03849895819409942FAD12B4B11694A -+:10EDA0001942FCD049463F4204D19823CB58102445 -+:10EDB000E34001E0304BCB581C242340002B01D012 -+:10EDC00000F08CF840462D49086048462C49086000 -+:10EDD00050462C49086060462B4908602B490F605B -+:10EDE0002B4D2C490D60043DAD46009DEC43102396 -+:10EDF000DD41AC4201D081B009E0240CA400264DD5 -+:10EE00002C606B461B1B254D2B60043B9D46244804 -+:10EE10002449002204C08142FCD80EF0E5FAFEE746 -+:10EE20000000001814060000F8FF0000000000F0C9 -+:10EE30000000000FFC0F0000F08F0000A082000017 -+:10EE4000000F0000E08000000070000000100000D3 -+:10EE500000FF0F00002A0800000E0800000000FF5D -+:10EE6000E00100000406000000003800FFFF000081 -+:10EE7000180600000C0600000804000048EC000022 -+:10EE80004CEC000050EC000054EC000044EC00009E -+:10EE900000C00300F81E0200001F0200FC1E02005A -+:10EEA000AC270200182C020008680F22043102402F -+:10EEB000052AF9D1014A1040F746000000F0FFFF93 -+:10EEC00008680F2204310240052AF9D1802210423D -+:10EED000F6D0014A1040F74600F0FFFFFEE70000C1 -+:10EEE00010B57146034802F0DFFB40F61100FFF752 -+:10EEF000C3FE10BD8E1F860010B5002128220446D7 -+:10EF0000F3F39EF00A4B23600A4B63600A4BA36045 -+:10EF10000A4BE3600A4B23610A4B63610A4BA3610E -+:10EF20000A4BE3610A4B23620A4B636210BDC04681 -+:10EF300000000000C71D0200C81D0200AC2702002F -+:10EF4000AC270200182C0200182C020021D202006B -+:10EF500024D20200005903002DE9F04399B00CA817 -+:10EF6000FFF7CAFF0C9B0D99DFF8DC91C91A0F9DC2 -+:10EF70000E9BD9F80060ED1A119C109B06F5A05667 -+:10EF80006048E41A76180B9102F08EFB0B9905F598 -+:10EF90007E7376190733361901F57E729B0A019448 -+:10EFA00004F57E740732009307340523A40A920AFD -+:10EFB000039355482B460294DFF8848102F074FBDA -+:10EFC000524BD8F800401968D9F80050C4EB01033F -+:10EFD00003F57E7001F57E7207300194039504F508 -+:10EFE0007E7405F57E75800A073207340735920A6C -+:10EFF0000090A40AAD0A46480294049502F054FB1E -+:10F00000444B45481968D8F80030C91806F57E7396 -+:10F0100001F57E7207339B0A0732920A009333464A -+:10F0200002F042FB3D4B3E48196802F03DFB3D4B70 -+:10F030001F683D4B3A689A4203D03C4802F034FBCB -+:10F0400024E0179705E03268374B9A4205D1331D0B -+:10F050001793179E16AB9E42F5D3354BC7EB0600B0 -+:10F060001A6817ABC7EB0301C3EB0204C6EB02053A -+:10F070000092019102910390049039462D48324646 -+:10F08000059406940795089502F00EFB2A4C20681B -+:10F09000002834D0C588F3F363F52368013D5C890B -+:10F0A0004FF4806104FB05F6443405FB04F406F5D7 -+:10F0B0007E73073393FBF1F3009304F57E730733FC -+:10F0C00093FBF1F302460293294633461B48019411 -+:10F0D00002F0EAFA1A4B0F4A1B681268C6EB0306E5 -+:10F0E0009B181B1B03F57E7106F57E720731890A9A -+:10F0F0000732009113483146920A02F0D5FA19B04E -+:10F10000BDE8F083E11F8600F01F8600C8260000DE -+:10F110002E208600A4260000722086009026000083 -+:10F12000AC208600F82702004B415453C6208600CD -+:10F13000FC270200E9208600BC260000662186002C -+:10F140008826000092218600CC2600000D4B10B5C9 -+:10F150001A680D4CD2F81416D2F8143699420B4B9B -+:10F1600018BFD2F8141622681B68C2EB010098423F -+:10F1700001D2002004E0B0FBF3F003FB0023236086 -+:10F1800010BDC0469C260000E4260000C8250000F3 -+:10F190002DE9F04301688FB0022907461AD15A4B76 -+:10F1A0005A481A6800235361046814F4805F11D030 -+:10F1B000574B584A1960C169043B1960136804230E -+:10F1C000136024F4805343F400530360524802F068 -+:10F1D0006BFA96E03B680C2B14D14C4C236813F46B -+:10F1E000005F0FD023F4005343F400632360676093 -+:10F1F0004A48F96C02F058FA236803F40063002BC4 -+:10F20000FDD17EE03B68103B0F2B02D8F7F3E2F014 -+:10F2100077E03E4B4248D96902F046FABA6C786C06 -+:10F22000BC68FD683968FB6C009201903A463D4825 -+:10F230000294039502F038FA3B4B7E6C1B68F86928 -+:10F24000D7F828E03C6A7D6A9B1B39697A694FEAE6 -+:10F250009309BB6900903548CDF80CE00194029504 -+:10F2600002F022FAB86BFC6B3D6CF96A3A6B7B6B6F -+:10F2700000902F480194029502F016FAF068316868 -+:10F280007268B36800902B4802F00EFAF069316999 -+:10F290007269B3690090284802F006FA04A8FFF7E3 -+:10F2A0002BFE264802F000FA0024A04625461CE06A -+:10F2B000725912F0010F13D0FF2A11D9059B9A42FF -+:10F2C00008D91F4B1B0D1B059A4209D303F5801368 -+:10F2D0009A4205D81B48294602F0E6F908F10108D0 -+:10F2E0000435B8F10F0F02D801344C45E0D1074A7C -+:10F2F00040F203301368576043F480631360FFF7F4 -+:10F30000BBFC0FB0BDE8F0837428020000280200A7 -+:10F31000241000E0281000E0C4E50100C8E5010069 -+:10F32000D4E50100E1E50100F81E020015E6010048 -+:10F3300048E6010077E6010095E60100FC1C860026 -+:10F340009D668000B2E60100F0B51F4E8BB06846A6 -+:10F35000FFF7D2FD3578F5B90698079B1C1A07D040 -+:10F3600029462246F2F36CF606982146F6F358F742 -+:10F370002146164802F098F9154B1D700123337091 -+:10F38000144B1968E9B10B78DBB1134B2A461868A6 -+:10F39000F3F34AF415E0114F3D7895B90898099BAD -+:10F3A0001C1A07D029462246F2F34AF6089821464D -+:10F3B000F6F336F70A48214602F076F90123357054 -+:10F3C0003B700BB0F0BDC0463C280200C9E601000E -+:10F3D0003E280200BC260000242802003D2802002E -+:10F3E000FBE6010010B50446FBF384F60146204617 -+:10F3F00000F034F910BDC04670B50446FBF37AF650 -+:10F400002046FBF3B7F505462046FBF337F500220F -+:10F41000064640F62A012046FBF3F0F60123AB40F6 -+:10F420008269134201D0002500E0013520463146B3 -+:10F43000FBF3F6F6284670BD10B5FFF7DDFF10BDF3 -+:10F440002DE9F04107460C46FBF354F63846FBF332 -+:10F4500015F540F62A01804600223846FBF3CEF629 -+:10F4600083690646456944B14FF4004043F00044C7 -+:10F4700045F00045FFF792FB07E04FF4004023F012 -+:10F48000004425F00045FFF7A7FBB46138467561DD -+:10F490004146FBF3C5F6BDE8F081C0462DE9F041D9 -+:10F4A0000E465021804617461D46F7F311F40446D8 -+:10F4B00018B300215022F2F3C3F540F23C736363AA -+:10F4C000A3F55573E363A3F5737323640C2363649B -+:10F4D00004230020E56026606760C4F80880A36408 -+:10F4E0000749F3F349F2C0B284F84C000138C0B2C6 -+:10F4F000012802D9022384F84C302046BDE8F0816F -+:10F500003E2986000048704718F9010000487047FE -+:10F5100090F901000048704700A60E00D2F80036AE -+:10F5200070B50546C3F38404FFF7ECFF03E083786E -+:10F53000A34204D00C3020B10388002BF7D10388FC -+:10F5400013B92846FFF7E2FF03884FF47A7003FBF4 -+:10F5500000F070BD0123C2F8603610B5D2F86446E1 -+:10F56000FFF7D8FF04F0FF04B0FBF4F34FF47A7018 -+:10F5700003FB00F010BDC0462DE9F0411C460646D5 -+:10F580001546FBF37BF4002107463046FBF348F6B3 -+:10F590000223C0F8583654B1D0F85C3605F03F026B -+:10F5A00023F4FC4343EA4223C0F85C3603E0D0F87E -+:10F5B0005C36C3F3452530463946FBF331F6284621 -+:10F5C000BDE8F0812DE9F041DFF860800646D8F80B -+:10F5D000004034BBFBF352F4214607463046FBF3B0 -+:10F5E0001FF6D0F81456D0F8143604469D4218BFC2 -+:10F5F000D0F8145642F21070F7F3AEF0D4F8142697 -+:10F60000D4F8143630469A4218BFD4F81426394636 -+:10F61000C5EB0203642203FB02F3C8F80030FBF3DE -+:10F62000FFF5024B1868BDE8F081C046842802004F -+:10F6300070B504460D46FBF321F400210646204632 -+:10F64000FBF3EEF5294602462046FFF783FF3146DD -+:10F6500005462046FBF3E4F5284670BD10B5FFF7DC -+:10F66000E7FF10BD70B504460D46FBF307F400211B -+:10F6700006462046FBF3D4F5294602462046FFF70E -+:10F680004DFF314605462046FBF3CAF5284670BDBE -+:10F690002DE9F04F1746C7F820361D46036A85B09E -+:10F6A0000C2BCBBFD2F82836D2F82836C3F3094B3F -+:10F6B000C3F3072B01230024AB4080468946029404 -+:10F6C00003940094F6F30AF30646012212FA04F3B7 -+:10F6D000334207D00092404649463A46F6F3FEF2DE -+:10F6E00026EA000601341F2CEFD1404603A902AAE6 -+:10F6F000F6F31EF3039B00256FEA030A2C46012351 -+:10F70000A34006EA0A021A4208D0404649463A4651 -+:10F71000E3B2FFF7BDFF854238BF054601341F2C19 -+:10F72000EDD10BF10200401905B0BDE8F08FC046E5 -+:10F730002DE9704305468846FBF3A0F3002181467E -+:10F740002846FBF36DF50446284600F0F3F8224600 -+:10F750000646414618232846FFF79AFF0B2302303E -+:10F7600000FB03F0074C49463419B4FBF6F404FBE4 -+:10F7700000F42846FBF354F50A23B4FBF3F4A0B2DB -+:10F78000BDE870833F420F0073B5044616461D4620 -+:10F7900000914FF4CB6200214FF0FF33FBF376F37F -+:10F7A0002046002140F25C6233460095FBF36EF385 -+:10F7B0007CBDC046002270B513460C4604210546A8 -+:10F7C000FFF7E2FF012C20F0F07308BF43F0F07365 -+:10F7D000284604214FF0FF32FFF7D6FF012C03D15A -+:10F7E00049F64040F6F3B8F770BDC04610B50021A9 -+:10F7F000FFF7E0FF10BDC04610B50121FFF7DAFFAB -+:10F8000010BDC04610B508B1F6F366F510BDC04690 -+:10F8100070B5094B06461D6808E030462C68FBF3BE -+:10F8200069F429466A68F7F363F22546002DF4D19E -+:10F83000014B1D6070BDC0466C270000002343666D -+:10F840007047C0467047C0460020704710B5FFF7AC -+:10F85000D3FF10BD10B5FFF7C9FF10BD2DE9F04172 -+:10F8600006460D461446FBF30DF4804618B93046A3 -+:10F870000121FBF345F4304613F032FA074610B984 -+:10F880006FF01D0415E014B96FF0190418E04FF083 -+:10F8900000032B80002404F182013846F2F34AF27F -+:10F8A000C0B2A0402B8801341843052C2880F2D127 -+:10F8B0000024B8F1000F03D130464146FBF320F499 -+:10F8C0002046BDE8F081C04607B54FF0000302A90D -+:10F8D00021F8023D0122FFF7C1FFBDF806000EBD71 -+:10F8E000416E2DE9F041044661B1D0F8C83000EB1B -+:10F8F0008303D3F8D020C36D9A4203D1006E8847AA -+:10F90000064600E000262046616DFFF711FFA56E58 -+:10F9100007465DB1D4F8C83004EB8303D3F8D02098 -+:10F92000E36D9A4202D1206E3146A8473846BDE8C1 -+:10F93000F081C04610B50446FBF3DCF301462046D7 -+:10F94000FFF740FE10BDC04610B50446FBF3D2F3EE -+:10F9500001462046FFF786FE10BDC046416E2DE9E8 -+:10F96000F041044661B1D0F8C83000EB8303D3F80E -+:10F97000D020C36D9A4203D1006E8847064600E04E -+:10F9800000262046616DFFF753FEA56E07465DB168 -+:10F99000D4F8C83004EB8303D3F8D020E36D9A4247 -+:10F9A00002D1206E3146A8473846BDE8F081C046F6 -+:10F9B00043692DE9F743222B06460F4640F3A0800A -+:10F9C000FBF314F4002800F09B80072F00F29880CE -+:10F9D000B268B2F5026F01D101220AE040F60403D9 -+:10F9E0009A4201D0002204E0F3680C2B94BF00225D -+:10F9F00001225FFA82F8B8F1000F0BD130464FF4C4 -+:10FA000000614246D6F8C890FBF3F8F3054600289B -+:10FA100077D006E0D6F8843013F5405571D04FF01A -+:10FA20000009032F03D030460121FBF379F4D5F808 -+:10FA3000303123F00403C5F8303101239F42C5F86B -+:10FA4000303103D9042F01D0083300E00D23C5F86D -+:10FA50003031D5F83031012F23F00103C5F83031B2 -+:10FA600001D9042F36D1FF2400214FF4E27223463E -+:10FA700030460094FBF30AF22223009300214FF456 -+:10FA8000EE7223463046FBF301F228230093002157 -+:10FA90004FF4E67223463046FBF3F8F181230093DE -+:10FAA00000214FF4E87223463046FBF3EFF10123C7 -+:10FAB000009300214FF4A4724FF0FF333046FBF364 -+:10FAC000E5F1304600214FF4A6724FF6FF73009423 -+:10FAD000FBF3DCF1D5F8303123F0700343EA071370 -+:10FAE000C5F83031D5F8303123F00803C5F830318E -+:10FAF000B8F1000F05D130464946FBF391F300E021 -+:10FB000000252846BDE8FE8370B50446FBF36EF37E -+:10FB1000002839D0A268B2F5026F01D101220AE0B3 -+:10FB200040F604039A4201D0002204E0E3680C2B63 -+:10FB300094BF00220122D5B24DB920464FF4006196 -+:10FB40002A46D4F8C860FBF359F3E8B105E0D4F8CD -+:10FB5000843013F5405017D00026D0F8303123F010 -+:10FB60000403C0F8303143F00103C0F83031C3F36F -+:10FB70000213032B03D020460021FBF3D1F31DB960 -+:10FB800020463146FBF34CF370BDC0462DE977416A -+:10FB90000022012113460546F6F352F10024804667 -+:10FBA00021462822234628460094FBF36FF10121C9 -+:10FBB0000646434628464FF0FF32F6F341F1284609 -+:10FBC000214628224FF0FF330096FBF35FF1BDE89A -+:10FBD0007E81C046D0F86C32994201D0002004E00A -+:10FBE0008B79D3F1010038BF002070472DE9F04137 -+:10FBF000002605460446374608E02B68216A9868C7 -+:10FC0000FFF32CF500B90136013718346B689F42B9 -+:10FC1000F3DB3046BDE8F08103682DE9F0411E6852 -+:10FC20000546B7688846144638462969FFF316F535 -+:10FC300044B133681B7E2BB1384629694246012303 -+:10FC4000FFF3C4F4BDE8F08170B505460446002614 -+:10FC50000DE0616949B1236A3BB1182006FB00F051 -+:10FC6000103028180122FFF7D7FF013618346B68CF -+:10FC70009E42EEDB002070BD2DE9F3411F46036874 -+:10FC8000044601910092DDF820801E6809B10D291B -+:10FC900041DD61680022FFF7BFFFE1680025656074 -+:10FCA00031B1236822891B685868F7F321F0E560B9 -+:10FCB000009B2BB1B3F5967F02DA6FF01C002CE0AD -+:10FCC00030464146FFF786FF28B3019969B12368A2 -+:10FCD0001B685868F6F3FCF7E06010B96FF01A0083 -+:10FCE0001BE03946019AF2F347F101A90422C4F856 -+:10FCF000148004F10800F2F33FF1201D694604224C -+:10FD0000F2F33AF1009840B1204661680122FFF712 -+:10FD100083FF002001E06FF00100BDE8FC81C046D8 -+:10FD20002DE9F047154686B00268DDF84080DDF821 -+:10FD300044A005F00103009306465346106842466E -+:10FD4000DDF84C9013F0C0DA0746002840F0A1809F -+:10FD5000022D54D0032D1FD0012D02D06FF01607B5 -+:10FD600097E04146042203A8F2F306F1022208F1CB -+:10FD700004010DF11600F2F3FFF056F8100B49469E -+:10FD8000BDF81640039D2FF035DB214600902A4632 -+:10FD9000304608F106032EE00222414605A8F2F3A0 -+:10FDA000EBF0042208F1040103A8F2F3E5F00222CB -+:10FDB0000DF1160008F10801F2F3DEF0BDF8143081 -+:10FDC000012B02D06FF0240763E098F80A70736883 -+:10FDD0009F425CDA49463068BDF81640039D2FF01B -+:10FDE00009DB182307FB03F3103300902146F018BA -+:10FDF0002A4608F10B03FFF73FFF074649E00E9B39 -+:10FE00001A6873689A4242DA002A40DB4FF0010315 -+:10FE1000ADF8143004924FF00B030DF116012A4691 -+:10FE200008F10200ADF81630F2F3A6F005A92A4653 -+:10FE30004046F2F3A1F004991824013101FB04615A -+:10FE40002A4608F10800F2F397F0012204A908F10C -+:10FE50000A00F2F391F00499042201FB046108F115 -+:10FE600004001431F2F388F0049B013303FB04F324 -+:10FE70009A5B991902F10B039A4502D26FF00D07B4 -+:10FE800007E008F10B004968F2F376F001E06FF04B -+:10FE90000107384606B0BDE8F087C046F7B50168EF -+:10FEA00005460E6896F87032002B2CD002894769FF -+:10FEB0003AB9304607F1BC011346009218F0D0D889 -+:10FEC00021E0898970688918F6F35AF72A68044690 -+:10FED00018B993680133936015E09289A38A006989 -+:10FEE0009B1A8018A382E9682A892061F2F344F002 -+:10FEF00004F124025389304643F0400353812146E4 -+:10FF0000BA6818F04FD9FEBD13B54FF0000310F0DA -+:10FF10000104ADF8063006D0002904DD10F8013BDD -+:10FF200001398DF8073010F0030F05D0012903DDEA -+:10FF300030F8022B023913E0002211E00368D218D6 -+:10FF4000436828BF0132D218836828BF0132D21813 -+:10FF5000C36828BF0132D21828BF013210301039CF -+:10FF600031F00F03EAD113041B0C03EB124203E040 -+:10FF700030F8023C0239D218034602300129F7DC7E -+:10FF800004BF1B788DF80630BDF80630D3181A046C -+:10FF9000120C02EB134213041B0C03EB124024B1AE -+:10FFA000030243EA10231804000C1CBD10B5FFF730 -+:10FFB000ABFF02E003041B0C9818020CFAD1C043FB -+:10FFC00080B210BD2DE9F041BDF818500C4629460D -+:10FFD00016469846FFF798FF3204120C02EB1442C3 -+:10FFE0002404240C121905F0FF0302EB16421B0235 -+:10FFF00002EB082243EA1523D218101802E003048A -+:020000021000EC -+:100000001B0C9818020CFAD1C04380B2BDE8F081F5 -+:100010002DE9F0418D8A16460D2D1F460C6952DDE3 -+:10002000A38904F10C0003F0FF021B0A43EA022338 -+:10003000B3F5C06F0BD2152D45DD254804F10E0137 -+:100040000622F1F37DF700283DD104F11400038866 -+:1000500003F0FF021B0A43EA0223B3F5014F0AD162 -+:100060000430821C63199A422DD8038803F0FF02E2 -+:100070001B0A43EA0223B3F5006F24D1811CC4EBB1 -+:100080000103C3EB0504132C1DDD82781309042B37 -+:1000900019D102F00F039A00132A14D9A24212DCDC -+:1000A0008A78CB7843EA0223A34201DA1C4600E0B7 -+:1000B00009DC8A79CB7943EA02239804800C10B9D1 -+:1000C00031603C6001E04FF0FF30BDE8F081C04698 -+:1000D00035FA01002DE9F043436887B013F0020FB1 -+:1000E0000546884600F08F8005AA04ABFFF790FF15 -+:1000F0000028C0F288800598037803F00F039E0063 -+:100100003146FFF753FF48B1B8F8163023F010031B -+:10011000A8F816302B6A01332B6274E0EB69059F57 -+:100120000133EB6197F80990B9F1060F24D107F17B -+:100130000C01042202A8049CF1F31EF70599042285 -+:100140001031A41B03A8F1F317F7A4B2B819029950 -+:10015000039A4B460094FFF735FF48B1B8F81630C4 -+:1001600023F01003A8F81630AB6A0133AB624AE003 -+:100170006B6A01336B623EE0B9F1110F24D107F1D4 -+:100180000C01042203A8049CF1F3F6F6059904225D -+:100190001031A41B02A8F1F3EFF6A4B2B819039929 -+:1001A000029A4B460094FFF70DFF48B1B8F816309D -+:1001B00023F01003A8F816302B6B01332B6322E0D9 -+:1001C000EB6A0133EB6216E0B9F1010F13D1049928 -+:1001D000B819891B89B2FFF7E9FE48B1B8F81630A3 -+:1001E00023F01003A8F81630AB6B0133AB630AE0C1 -+:1001F0006B6B01336B63B8F81630002043F01003CB -+:10020000A8F8163001E04FF0FF3007B0BDE8F083EA -+:100210002DE9F043436887B013F0010F804600F0EA -+:100220008780CB8A13F0080F03D183680133836082 -+:100230007EE005AA04ABFFF7EBFE002878DB059A09 -+:1002400000271378977203F00F039E00D772314690 -+:100250000598FFF7ABFE059B9872C0F30F20D8728C -+:10026000D8F80C3005990133C8F80C3091F8099092 -+:10027000B9F1060F21D18D19049C0C3104222F7481 -+:100280006F7402A8F1F378F6059904221031A41BCB -+:1002900003A8F1F371F6A4B24B4628460299039ADB -+:1002A0000094FFF78FFE2874C0F30F206874D8F80D -+:1002B00010300133C8F810303AE0B9F1110F22D1F3 -+:1002C0008D19049CAF71EF71059904220C3103A8BC -+:1002D000F1F352F6059904221031A41B02A8F1F3A0 -+:1002E0004BF6A4B24B4628460399029A0094FFF7B6 -+:1002F00069FEA871C0F30F20E871D8F814300133FB -+:10030000C8F8143014E0B9F1010F11D18C19049917 -+:100310002046891BA770E77089B2FFF747FEA070DF -+:10032000C0F30F20E070D8F818300133C8F8183047 -+:1003300007B0BDE8F083C0462DE9F34114460A9F9B -+:100340000268DDF82C8004F0010300930546434663 -+:1003500010683A4612F0B8DF064618BB052C04D8E0 -+:10036000DFE804F00A061403030D6FF0160619E027 -+:10037000281D3946042213E06B683B6012E005F14A -+:10038000080000214C22F1F35BF60BE0B8F14B0FB3 -+:1003900002D86FF00D0605E0384605F108014C2241 -+:1003A000F1F3EAF53046BDE8FC81C04610B58C6B30 -+:1003B00000200BE00B1893F83C30064A03F07F0353 -+:1003C000D356002B01DA012003E00130A042F1D125 -+:1003D000002010BD401B86002DE9F84F02298346FE -+:1003E0000E4690469A4614BF4FF0FF37002714BFC1 -+:1003F000002401244FF000092EE0022E14BF4FF01C -+:10040000FF3300239F4211D0022E08D1B8F1040F10 -+:1004100007D0B8F1060F04D0B8F1080F01D00422BC -+:1004200000E00022C7EB0403934214DD0E2CCCBF86 -+:100430004FF480534FF4005344F4306213439DB2A1 -+:10044000DBF85C01294635F0A9DF20B12AF8195004 -+:10045000274609F101090134022E0CBF0E230023A7 -+:100460009C4202DCB9F11F0FC7D90A9BC3F8009068 -+:10047000BDE8F88F2DE9F04F88469BB0402100275A -+:10048000DDF890B09DF894900646C0F82077C0F84B -+:100490001C1740689A46F6F31BF40446C6F8180782 -+:1004A00010B96FF0150473E0D8F800306BB9203341 -+:1004B000C6F82037336B30461A8906F5E46300939B -+:1004C00059462346FFF788FF1FE0202B6CD845468E -+:1004D00017E0AC88D6F85C01214635F05FDF0028D4 -+:1004E00062D01FB12B78E2B29A425DD9D6F820379C -+:1004F000D6F81827013722F813400133C6F8203701 -+:100500000435D8F800309F42E3D3D6F82037002BCB -+:100510004AD070681021F6F3DBF30746002835D087 -+:10052000279B002411AD446083600473214606605C -+:1005300080F80DB080F80E9024222846F1F380F563 -+:10054000A24514BF0023012301934FF0FF33029310 -+:10055000039304930593D6F8183730460693D6F8DC -+:10056000203702210793144B144A0A9303230C9358 -+:100570000123089409940D940E9400950B9716F09E -+:10058000BBDC044698B9269B7B6010E06FF01A0430 -+:10059000D6F8181759B17068D6F81C27F6F3A8F3E7 -+:1005A0000023C6F8183702E06FF00104F0E7204698 -+:1005B0001BB0BDE8F08FC046410B01002C9E8500AA -+:1005C00030B590F8143789B00446002B3ED0D0F8EF -+:1005D00068319D79002D62D1036880F814571B7E25 -+:1005E000002B5CD0B0F81637002B58D0036B18697D -+:1005F00002F09CFAB4F81617884250D0204618F042 -+:10060000CFDB204601F0EEF82046B4F8161718F0BC -+:100610000DDA236893F82F306BB1D4F86C32204692 -+:10062000D3F8D412383113F0B9D80146C4F8AC0667 -+:1006300020460CF051D920461AF068DC20462946A5 -+:100640001AF06EDE204611F0DBDC28E003681B7E2A -+:100650002BB3D0F868319B790BBBD0F8000507A904 -+:1006600044F038DD03E02B7E13F0020F17D107A80A -+:1006700044F038DD05460028F5D1236B05901B6852 -+:1006800005A90093032301930290039001222046C1 -+:100690002B46FFF7EFFE10B9012384F8143709B099 -+:1006A00030BDC0462DE9F74F0192D0F800A090F878 -+:1006B0000D801F460C464FF0000BE5E0072200219D -+:1006C0002046F1F3BDF40C9AB8F1020F12F81B00AA -+:1006D000207001D0022308E0042F05D0062F03D09C -+:1006E000082F01D0434600E00023C3EB0002B8F11D -+:1006F000020F14BF002301239A4210DBB8F1020F4E -+:1007000001D0022108E0042F05D0062F03D0082FC6 -+:1007100001D0414600E00021C1EB00060FE0B8F136 -+:10072000020F14BF0026012606E0DAF85C0131460C -+:1007300035F0F2DD18B9013623789E42F5D9B8F1CB -+:10074000020F207802D0002202230BE0042F07D0F2 -+:10075000062F00F0A680082F00F0A3804346A1E0FA -+:100760000E2200231B1893420FDCB8F1020F01D0B8 -+:10077000022108E0042F05D0062F03D0082F01D056 -+:10078000414600E000210D180FE0B8F1020F0CBF48 -+:100790000E25002506E0DAF85C01294635F0BCDDBF -+:1007A00018B9013D23789D42F5D24FF0000963E06E -+:1007B00002EB89039968CB88B1F832E013F020038B -+:1007C0005FFA8EF00DD00EF44072B2F5807F02D148 -+:1007D000821C023806E0B2F5007F02D1821E023090 -+:1007E00000E00246B04201D3A84203D9B24241D34D -+:1007F000AA423FD8B3B1B04214D3A84212D80EF4E3 -+:100800004073B3F5807F05D12379FF2B0AD00133E4 -+:10081000237107E0B3F5007F04D16379FF2B01D08A -+:1008200001336371CB8813F0200F0BD0B24209D390 -+:10083000AA4207D8824205D0A379FF2B1AD00133F0 -+:10084000A37117E023780E2B0FD85046FFF7AEFDAB -+:1008500028B1E378FF2B0DD00133E3700AE0A378D1 -+:10086000FF2B07D00133A37004E06378FF2B01D086 -+:100870000133637009F10109DAF818251368994505 -+:1008800096D30BF1010B07340D9B9B4504DA019ABB -+:1008900013689B45FFF612AF019BC3F800B0BDE89B -+:1008A000FE8F00230E225DE72DE9F84F5FFA83FCEF -+:1008B0001E4603F44073B3F5007F14BF4FF00009E8 -+:1008C0004FF0010905468A4693460CF10200ACF14F -+:1008D0000203B9F1000F02D08646984601E09E4619 -+:1008E00080460027394629E011F80A40ACF105039B -+:1008F0009C4221DB0CF105039C421DDC0AEB01004C -+:1009000082783AB9C3782BB903791BB943790BB90B -+:1009100083798BB1744506D1837993B9B9F1000F0E -+:1009200008D0037907E044450BD152B9C37843B9E5 -+:10093000037933B9437923B9013707315F45D3DBF5 -+:100940001BE0BEF10E0FD4BF4FF400534FF48053A1 -+:100950004EF4306213439CB2D5F8FC341B7893B14B -+:100960002846002124F048D8284624F03BD80AE045 -+:100970002846012124F040D804E0D5F8FC341B7847 -+:10098000002BF5D134462046BDE8F88F2DE9F04F15 -+:10099000D0F8008090F80DA0D8F83010DDB00989AB -+:1009A000814614464FF0000B5B9300E004210022C7 -+:1009B0005B98964608E01EF804300EF1070E052BF2 -+:1009C00001D9934602E001328242F4DB082900F2A9 -+:1009D000B08001A252F821F0FD090100330B0100A3 -+:1009E000030A0100330B0100AF0A0100330B0100C1 -+:1009F000330B0100330B0100AD0901004FF6FF7608 -+:100A00001AE00025AE464FF6FF7612E00EEB0B0221 -+:100A100092FBF0F300FB1323072203FB02F16218A1 -+:100A2000937823B9D378B3423CBF655C1E460EF180 -+:100A3000010E8645EADB15B90025AC4621E00E2DF6 -+:100A400094BF4FF400524FF4805245F4306343EAB0 -+:100A500002006FE00CEB0B0292FBF0F300FB1323A0 -+:100A6000072203FB02FE04EB0E0359789A78DB7829 -+:100A70005218D218B242BCBF14F80E5096B20CF104 -+:100A8000010C8445E6DB3DB99BFBF0F300FB13B39F -+:100A9000072203FB02F31D5D0E2D94BF4FF400539C -+:100AA0004FF4805345EA030343F4306042E0BAF167 -+:100AB000020F3ED15AAB00930024404651465246A5 -+:100AC0004AAB5A94FFF788FCD8F818771FB3D8F8C8 -+:100AD000206706B35A99254610E000243AAB37F850 -+:100AE0001520E05A904205D15CAA02EB410323F89D -+:100AF000480C01310234402CF0D10135B542ECDB19 -+:100B000020230E485B935A9100F0CEFD4AAB009330 -+:100B10005A9B02AC04E020233AAA5B9302AC0092F9 -+:100B20000193214648465BAA0223FFF7BBFD022141 -+:100B30003DE700205DB0BDE8F08FC046B4FA01008B -+:100B4000F0B50546BDB004680E4609B108292DD19F -+:100B50002023D4F818273B93236B03AF1B89009203 -+:100B6000D4F82027394601923BAAFFF79BFD6B7B07 -+:100B7000022B13D1D4F8FC341B787BB1D4F8343772 -+:100B8000B3F8A4E30EF44063B3F5406F06D12046FA -+:100B900039463B9A7346FFF787FE05E02846002159 -+:100BA00003AA3B9BFFF7F2FEA4F816076B6813B18C -+:100BB000A86831469847D4F81817D4F81C276068FD -+:100BC000F6F396F00023C4F818376068294610221F -+:100BD000F6F38EF03DB0F0BD7047C04610B5C3F8D7 -+:100BE000A010082019461C4631F03ADE84F8A40013 -+:100BF00010BDC0467047C0460020704700207047B7 -+:100C0000002070477047C0467047C0467047C046D6 -+:100C1000002070477047C04603680246D3F86C3224 -+:100C2000D3F8E432987818B1938A181E18BF0120BF -+:100C30007047C0467047C0467047C04670B5037DD8 -+:100C400004469BB1457D8DB9C068A169FEF306F5E8 -+:100C500001236375E36906460BB1A0689847D6F196 -+:100C6000010038BF00206575257500E0002070BDCB -+:100C70000846002110B5016141810172017306220D -+:100C8000F1F3DEF110BDC04610B50068F4F7B0F81E -+:100C900010BDC04690F832007047C0460246086852 -+:100CA000430D5B056BB922F07F4323F46003520DC3 -+:100CB00083422CBF4FF40013002352059B180343BB -+:100CC0000B60704770B510600D461C46084619460B -+:100CD0001646FFF7E3FF2368AB4202D233680133C5 -+:100CE000336070BD002070477047C04600207047D9 -+:100CF000002070477047C0467047C0467047C046E6 -+:100D000030B50568B5B061B10DF107040171C922B4 -+:100D100000212046F1F394F12B6B2146186902F073 -+:100D20001BFF35B030BDC046406B70477047C046B2 -+:100D3000002070477047C046002070477047C0468B -+:100D4000002070477047C046002070477047C0467B -+:100D50007047C0467047C0467047C0460020704785 -+:100D60007047C0467047C046002070477047C04675 -+:100D70007047C0467047C0467047C0464FF0FF30CE -+:100D80007047C0467047C04600207047002070473B -+:100D90007047C0467047C0467047C0460020704745 -+:100DA0007047C04603490A6812B100230B60104621 -+:100DB0007047C046E82B020070B515460C464E6CD5 -+:100DC00018F00CD9024628B915F4001F02D0636C44 -+:100DD0006664A364104670BD73B500EB420440F630 -+:100DE0002A15B4F82C66A4F82C56069D009503F03D -+:100DF0008FDCA4F82C667CBD10B511F0F7DC024640 -+:100E000040B1416A11F4002F04D1036813B141F4D9 -+:100E100000234362104610BD2DE9F3411E460368CE -+:100E200004461B7E0F469046002B4BD090F875323F -+:100E3000002B47D10D682846FFF776FF016902466F -+:100E40008B79B3B1837E13F0010F12D0D1F8CC307F -+:100E500013F4806F0DD1B4F8263603F47043B3F564 -+:100E6000805F14BF40234423CB5813B193F8DF3085 -+:100E700043BB5168002925DB164B01EA03030BB97C -+:100E8000184602E0EB8A03F0070011F0400F19D07A -+:100E9000114B02A91B5C204641F8043D336009F068 -+:100EA000EFDDB0F1FF3F0DD0019A3368934209D0D6 -+:100EB0000A4B32609A5CEB8A02F0070223F00703C8 -+:100EC0001A43EA82204639464246334614F06CD82B -+:100ED000BDE8FC8140000180C4D28500301E0200C4 -+:100EE000F0B585B00A9C0D4600940B9C1F460194FA -+:100EF0000C9C064602940D9C039428F02FDBAB79E2 -+:100F000043B13946304644F063DD014610B1304606 -+:100F100044F056DC05B0F0BD10B520F00BDE10BD7E -+:100F20002DE9FF4107461D469E6B146945F0C8DB5D -+:100F30008046002834D1337A022B31D1A3797BB398 -+:100F4000B5F8683063B3A26D40F2371302EA0303C9 -+:100F500033B394F884301BBBD4F888303A6853B963 -+:100F6000D2F88C30D3F8E4210132C3F8E4213C23D9 -+:100F7000C4F8883009E0D2F88C30D3F8E42101328B -+:100F8000C3F8E421012384F89430002394F9482025 -+:100F9000384600930293296F1133019644F068DFBD -+:100FA000404604B0BDE8F0812DE9F74F80460E467B -+:100FB00093461F46002B5FD001295DD14FF4C073CB -+:100FC0000193FAF397F04FF440718246F5F380F6FF -+:100FD000044610B94FF0FF3555E000214FF4407240 -+:100FE000F1F32EF040463146224601ABF0F3BEF657 -+:100FF00010F11E0F3AD1019B4FF0FF325D004A23E2 -+:1010000023700B23637015332371042363716FF016 -+:101010002F03A371923323726FF0560363724FF064 -+:1010200002096319A270E27084F8079003F8022C99 -+:1010300003F8012C07F10C039D4202DC6FF00E0552 -+:101040000DE059463A4604F10A00F0F395F795FB96 -+:10105000F9F340463146224611F074FE05465046EB -+:1010600021464FF44072F5F343F60CE0504621461A -+:101070004FF44072F5F33CF6404631465A463B4643 -+:10108000EFF3A0F705462846BDE8FE8F70B504468D -+:101090001E46FEF39FF3054640B1636893F8AB30FC -+:1010A00023B1E06F3146F1F76DFDA860284670BDB1 -+:1010B0002DE9F0411F4603680C461B68164693F85D -+:1010C000953005460969A28A1BB1E38A13F0800FA7 -+:1010D00009D0152A07DD08480E310622F0F330F753 -+:1010E00008B9013805E02846214632463B46FCF364 -+:1010F000A5F4BDE8F081C046BAD4010010B59E4603 -+:10110000D0F8683103B19B68054C23607346FCF34B -+:10111000F3F1B0F1FF3F01D10023236010BDC046C1 -+:10112000E82B02002DE9F04F87B0DDF854808946A6 -+:1011300015469A46129FDDF84CB00446B8F1000FF0 -+:1011400006D0D8F8081019B10120F1F7A5FE044621 -+:1011500014B96FF0160632E0226805F0010300931F -+:10116000106849463A465B4612F0AED8064630BB98 -+:10117000112D02D0132D09D00FE03846F1F3ECF316 -+:10118000E8B904F5B8703946062203E004F5B670F4 -+:1011900039460422F0F3F0F611E0109B204600934C -+:1011A000119B49460193149B2A4604935346029788 -+:1011B000CDF80CB0CDF81480FCF3C2F006463046F2 -+:1011C00007B0BDE8F08FC04670B50546D0F8B40052 -+:1011D00058B103784BB1F1F767FB044630B9D5F845 -+:1011E000B4000121F1F31AF500E001242846F3F3DD -+:1011F000DBF724B9D5F8B4002146F1F30FF570BD43 -+:1012000010B5FFF735FD10BD10B5FAF7B1F810BDF8 -+:10121000B0F8543810B50BB119F03ED910BDC04626 -+:1012200010B5044638B102682AB121B992F80B37DB -+:101230000BB182F80B17204617F090DF10BDC046A7 -+:1012400010B521B11AB1536E0BB13DF037DE10BDB0 -+:1012500010B50C4651B1002381F8653581F866352B -+:1012600081F86735C1F868353DF0A2DE10BDC04693 -+:10127000036A10B50C46002B2CD0036809691B6863 -+:10128000B4F814E093F895302BB1E38A13F0800F93 -+:1012900001D11E2200E00C2202F10B039E4519D35E -+:1012A0008B188A5C591C5B7803EB02239BB2B3F565 -+:1012B000006F0FD14B784A1C1B09042B0AD1537ABB -+:1012C000012B07D1436A01334362C3680133C36012 -+:1012D000002002E021463FF03BDD10BD036810B561 -+:1012E0001A68536B2BB192F8443013B130F0AEDF73 -+:1012F00000E0002010BDC04610B50C462DF0C0D94E -+:1013000018B994F8F53284F8F43210BD70B50122A2 -+:1013100005460C46D1F84C152EF01ADD284621461C -+:101320002DF0EAD870BDC0460C2A2DE9F0410446E4 -+:101330000F46154651D80122AA4041F2485302EA0D -+:101340000303002B49D0D0F8B4364BB1D3F8D832D0 -+:1013500033B15B68012B40D0032B3ED0022B3CD035 -+:10136000204615F043DD002837D1D4F868315B6999 -+:10137000012B32D0D4F81808FEF3F6F0064628B157 -+:10138000D4F86801092143F013D91AE0082D01D0DF -+:101390000C2D04D1D4F868319B7923BB11E0D4F82B -+:1013A0006801837913B3D4F82835022B04D094F85C -+:1013B000F43713F0010F16D0092143F0F9D8304665 -+:1013C00015E0082D12D1204639460222002325F0CF -+:1013D0003BD958B14FF0FF3009E0204639462A4644 -+:1013E00029F0E6DC03E06FF0180000E00020BDE823 -+:1013F000F081C0462DE9F04F85B005469B468846F2 -+:1014000091460F9F9DF840A0F8F7B2FFD5F8B06362 -+:1014100004460AF087DDD5F8C03398420CD3032385 -+:10142000009300230193029303932046172109F1AF -+:101430000A02013312F03CDB96F8463013F0030F3A -+:1014400019D0D8F8582040F2371302EA030393B1B9 -+:1014500094F8693713F0010F0DD07B6813F4803FC7 -+:1014600009D03B6C012B06D1002220463946134699 -+:10147000009211F0BBDB094C7F2323600E9B2846B2 -+:10148000009341465B464A460197CDF808A0F8F71D -+:1014900085FF0023236005B0BDE8F08F0C2C02000F -+:1014A00010B50446F5F346F0B0F5C05F05DD204603 -+:1014B00043F006DE204643F003DE10BD2DE9F04187 -+:1014C000074619F0DFDF0026BB19D3F84C42B4B150 -+:1014D000D4F88C509DB9A3798BB1A36D13F0020F92 -+:1014E0000DD094F8843053B1F5F38CF0D4F890100B -+:1014F00027F042DF18B1C4F8885084F884500436CD -+:10150000202EE1D1BDE8F08170B590F8A1310546FB -+:1015100063B903681B6F4BB1D0F81C48F5F372F048 -+:10152000D5F82038E41A2418C5F81C48284614F0C9 -+:10153000BBDB70BD10B588B00A9C00940B9C019475 -+:101540000C9C02940D9C03940E9C04940F9C059497 -+:10155000109C0694119C0794F3F3C2F1044B0421F0 -+:10156000D3F88C300A4604469847204608B010BD90 -+:10157000E0A6850070B504460D461EF04BD92946FD -+:1015800006462046F8F708FE304670BD2DE9F041CA -+:101590000546D5F8D8320E465B681746012B006821 -+:1015A000D5F8DC4202D14FF0000805E0042914BF51 -+:1015B0004FF000084FF001080368DB691A6D636A99 -+:1015C000934238BF62624EB9D4F8901031B140688E -+:1015D00094F89420F5F38CF3C4F8906028463146D3 -+:1015E0003A4625F0F5D8B8F1000F01D00023636228 -+:1015F000BDE8F0812DE9F04385B00C9F0546984683 -+:10160000D7F80090D2F8D462144600970AF0F0DCC4 -+:10161000296891F8463013F0030F3FD0D4F8CC205E -+:1016200012F4805F3AD196F93430002B36D14B6BEF -+:10163000002B33D012F0020F30D13B680DF10900BE -+:101640001849032208EB0304F0F396F495F8FA31F5 -+:1016500033B196F96A30002B02DA95F80A0700E0F8 -+:10166000002008EB0901A14201D2002100E0091B82 -+:1016700002238DF80C3000238DF80D3001338DF8E6 -+:101680000E300DF109038DF80F000093204607235B -+:10169000DD221AF07BDD3B6809333B6005B0BDE815 -+:1016A000F083C046C1D401000FB430B5104BADF586 -+:1016B000037D9E4501D1002513E002A887AB0538C4 -+:1016C00040F20121869A8193F0F3F0F5002405465B -+:1016D00005E002AB053BE05CF5F332F20134AC42CD -+:1016E000F7DB28460DF5037DBDE8304004B07047B8 -+:1016F000DB62820010B502490248FFF7D5FF10BD3A -+:10170000CCFB0100E3FB0100C36970B513F4006F6B -+:101710000E460546016915D00368D3F88C20936BFB -+:101720005C1C4FF47A739463B4FBF3F202FB134333 -+:1017300023B90748C96B2246FFF7B6FFEB6923F4CC -+:101740000063EB61284631462CF03CDB70BDC0469F -+:101750007CDB010010B590F81632044663B1084BEB -+:101760001B684BB1D0F88011D0F884210223C068E7 -+:1017700081EA0202F9F332F42046F7F36FF610BD66 -+:10178000AC27020010B50446F7F3B8F7002384F83D -+:10179000173284F8183210BD10B5074C2378012B8E -+:1017A00009D0064B1B78012B05D001232370F8F3D9 -+:1017B00073F70023237010BD002C0200EC2B0200F5 -+:1017C00070B50546F1F7EEF80128014607DD044C37 -+:1017D000012328462370F8F3EDF50023237070BD34 -+:1017E000EC2B020010B5064902690B782BB1D2F838 -+:1017F000D03013B100230B7001E018F051DD10BDA3 -+:10180000F42B020010B58B7913B1044B01221A702E -+:101810002DF0B6DB014B00221A7010BDF42B020034 -+:1018200070B5044C8568A54201D1002001E0F0F3B9 -+:1018300009F770BD0800002070B505460E461AF085 -+:101840002BDD0446C0B13146284640F26C521AF0F6 -+:1018500035DE064620B9284621461AF091DD0AE019 -+:10186000214640F26552F0F387F32846214640F2C4 -+:101870006552F5F33DF23446204670BD2DE9F04146 -+:101880008AB088460023159917460546129C09938D -+:101890002DF0B0DD07F001030093414606462246D5 -+:1018A0002868139B11F010DD8046002840F0AA80C4 -+:1018B000119B032B04D909A810990422F0F35CF3BF -+:1018C0000D2F08D8DFE807F00A0F07071722363C6C -+:1018D0004B07074E93976FF0160892E0284608F0E2 -+:1018E0002DDA40B22AE02846099908F051DA00289A -+:1018F00000F0858085E0B6F95E300BB102201DE076 -+:10190000B6F95C30181E18BF012017E0099B022BA6 -+:1019100006D14FF00003A6F85C304FF0010306E05B -+:10192000003B18BF0123A6F85C304FF00003A6F877 -+:101930005E3066E0D5F83407F8F71EFD206060E001 -+:10194000099BD5F834070393F8F71EFD039B8342E8 -+:1019500055DCD5F834070999F8F712FD51E0B5F8D0 -+:10196000BE3846E02B6893F8A030002B3FD00DF135 -+:101970001608264906224046F0F3FEF221460422CC -+:1019800008A8F0F3F9F2211D042207A8F0F3F4F2FD -+:10199000404604F108010622F0F3EEF2079F57B922 -+:1019A000D5F86821937993B95369012B0FD02B682F -+:1019B00093F83F305BB904F1100301932846314698 -+:1019C000089A3B46CDF8008015F084DC0DE02B68CA -+:1019D0001B7E13B96FF0030813E0284631460DF162 -+:1019E000160204F1100315F061DC804609E095F859 -+:1019F000C334236005E0099B85F8C33401E06FF030 -+:101A00001C0840460AB0BDE8F081C0462C9E850007 -+:101A10002DE9F04790B0DDF860A00C461E46514617 -+:101A20000023054617460F932DF0E4DC8046D0F8DE -+:101A3000DC9277B1032E04D90FA839460422F0F3C3 -+:101A40009BF237B1032E04D90FA839460422F0F3D4 -+:101A500093F2352C6BD010DC162C00F07C8105DC69 -+:101A60000B2C21D0152C00F065811AE01C2C00F005 -+:101A700086812F2C00F0288113E0382C00F0E580BF -+:101A800006DC362C00F09880372C00F0B58008E09A -+:101A90009F2C00F07A81A52C00F03F81392C00F0BA -+:101AA000F5806FF01604A1E12B6893F8A030002BAD -+:101AB0003DD00DF12606A24906223046F0F35CF235 -+:101AC000394604220DA8F0F357F2391D04220CA860 -+:101AD000F0F352F2304607F108010622F0F34CF21F -+:101AE0000C9C54B9D5F8682193798BB95369012BB3 -+:101AF0000ED02B6893F83F3053B907F110030193D0 -+:101B0000284641460D9A2346009615F0E3DB0CE08B -+:101B10002B681B7E002B00F05D81284641460DF1AD -+:101B2000260207F1100315F0C1DB04465EE12B68C5 -+:101B30001B7E002B00F04E81052E40F24E810D2EB3 -+:101B40000BD9284607F10801A6F1080201F062DA74 -+:101B50000446002840F04A8109E005AC3946204699 -+:101B60000622F0F309F2002307930E26274698F881 -+:101B70000640B4B9D9F8901031B1686899F894204A -+:101B8000F5F3B6F0C9F8904089F89460686831467A -+:101B9000F5F39EF0C9F8900018B139463246F0F3DB -+:101BA000EBF14046394629F091DAD9F890300446F5 -+:101BB000002B40F01A8119E1002300932846394692 -+:101BC00032460EABF1F760FB0446002840F00E8170 -+:101BD0000E99032900F004812A6B1368994202D1FF -+:101BE000D2F8F03050E05368002B14BF38233C2368 -+:101BF000EB58D3F8F03047E00023009328463946ED -+:101C000032460EABF1F740FB0446002840F0EE8070 -+:101C10000F9A02F16403672B02D96FF01C04E5E010 -+:101C20000E99032904D02B6B1B68994240F0DE808B -+:101C3000002A04DB2846296B29F08CDB02462B6B3B -+:101C4000C3F8FC20C3F8F020D0E00023009328461E -+:101C5000394632460EABF1F717FB0446002840F038 -+:101C6000C5800E99032900F0BB802A6B1368994246 -+:101C700002D1D2F8F43007E05368002B14BF3823A8 -+:101C80003C23EB58D3F8F4303B60AFE000230093E3 -+:101C90002846394632460EABF1F7F6FA04460028DC -+:101CA00040F0A4800F9A642A00F29A800E990329CA -+:101CB00004D02B6B1B68994240F098802B6BC3F8C3 -+:101CC0000021C3F8F42091E02B680F9C93F83F307B -+:101CD00013B16FF01B0489E0D5F86801837913B163 -+:101CE000042142F065DC95F87232221E18BF0122F1 -+:101CF00085F8502785F85925002B76D12AB105F5AE -+:101D0000AA61D5F85C010E3104E005F5AA61D5F8A9 -+:101D10005C010A3134F026DA07E70123002202933E -+:101D200028460849134600970196CDF80CA011F0FB -+:101D300037DBFAE6B8F95E3033B1022009E0C0467D -+:101D40002C9E85001C738600B8F95C30181E18BFE5 -+:101D50000120386049E00F9B022B06D14FF00003B1 -+:101D6000A8F85C304FF0010306E0003B18BF0123E8 -+:101D7000A8F85C304FF00003A8F85E3035E02B681F -+:101D800001211869F9F392F22FE0331F0622B3FB09 -+:101D9000F2F33B60D5F8000500230BA90F9343F045 -+:101DA00099D910E00B7E13F0020F0CD00F9B5C1C36 -+:101DB0000F943B68A34210D3B81E062204FB020016 -+:101DC0001A31F0F3D9F00BA843F08CD90146002862 -+:101DD000E8D108E06FF0030408E06FF00D0405E0BF -+:101DE0006FF0020402E00F9B3B600024204610B01D -+:101DF000BDE8F0872DE9F04F056889B082460C46B2 -+:101E00001E4628460023179907939346DDF848801D -+:101E10002DF0F0DA139B032B04D907A841460422C6 -+:101E2000F0F3AAF0BBF10D0F56D12846414698F8C1 -+:101E3000066098F8087098F809402DF06FDA10B134 -+:101E40006FF00107F1E098F80630003E18BF012658 -+:101E5000022B14BF4FF400594FF4811947EA0427AD -+:101E60006EB13846F1F3F8F1002840F0E080D5F883 -+:101E70005C01394634F092DA002800F0D880284618 -+:101E80002DF070DBB0F1FF3F014600F0D280284614 -+:101E90004A46434600962CF08BDE0446002800F0AC -+:101EA000C88028462146FBF789FA20B128462146FA -+:101EB0002DF0C2DABDE0002E00F0B9803946284688 -+:101EC000A2683BF0CDD90746002800F0AE80284636 -+:101ED00021462DF0B1DA12E0139B50460193149B7A -+:101EE00021460293159B5A460393169BCDF800801A -+:101EF0000493179B059333463AF03ADF074617F1F0 -+:101F0000170F40F09280DAF80060002330461799EE -+:101F100006932DF06FDA139B0446032B04D906A811 -+:101F200041460422F0F328F0BBF11B0F7DD130466F -+:101F3000414698F8065098F8089098F809702DF0E6 -+:101F4000EDD9034620B1A04202D06FF0010373E047 -+:101F5000B5F1000A18BF4FF0010ABAF1000F0BD01B -+:101F6000032D0BD09A68304649EA07213BF078D917 -+:101F70000346002860D111E0032D0FD130462146E1 -+:101F80002CF070DF012394F94810304600934FF491 -+:101F90008802013BFBF7E6F903464DE0D4F8CC306C -+:101FA000304643F40003C4F8CC3021462CF05ADF0D -+:101FB000A37913B1322384F8F43294F8F41231295E -+:101FC0000FD833681B7E1BB130461D4A17F02EDA3E -+:101FD000D6F84C0194F8F4123DF074D9322384F809 -+:101FE000F4324146062204F1C200EFF3C5F784F84B -+:101FF00006A030462146FBF7E1F9054640B1D4F88A -+:10200000CC3023F40003C4F8CC304FF0FF3313E09E -+:1020100030460321A26811F087D8D4F8CC3023F4DD -+:102020000003C4F8CC302B4606E03B4604E0002712 -+:10203000FBE74FF0FF37F8E7184609B0BDE8F08F2F -+:10204000329E85002DE9F04704468946FCF3F4F7FB -+:10205000F4F3D8F294F854318046012B1ED825466B -+:10206000002717E06E69B379022B11D1B4F86C30F8 -+:1020700013F4807F0CD0204649464246F0F74CFED0 -+:1020800030B90423B37194F8CD30013B84F8CD30DE -+:1020900001370435B4F910309F42E3DBBDE8F08727 -+:1020A00030B54FF0000E044691B08C461546704690 -+:1020B00009E023185A690EF1010ED1794DF800108C -+:1020C000536B0430D371B4F910309E45F1DB2046D8 -+:1020D00061462A46FCF3A4F10020014606E063189D -+:1020E0005A695DF801300130D3710431B4F9103010 -+:1020F0009842F4DB11B030BD2DE9F0410C290446C3 -+:102100000D46164690F853710DD100210122FCF3C3 -+:1021100087F1204600210122FCF33EF1002384F8E0 -+:10212000CE3084F8CD30A36E2046B3F1FF3F08BF18 -+:1021300084F8563129463246FCF392F2B4F86C30FA -+:1021400003F0C003C02B16D1D4F85C319BB194F8D6 -+:102150005331BB420FD9E368A1689868FDF37EF262 -+:10216000E368A1689868D4F85C210123FDF32EF29E -+:102170004FF0FF33A366BDE8F081C046836E10B513 -+:10218000B3F1FF3F01D0FBF39FF510BD2DE9F04106 -+:1021900004460D46866EFCF3C5F6074690B9042248 -+:1021A00004F5AE7005F11401EFF3E6F6D4F85C31F6 -+:1021B0004FF47A7203FB02F3B6F1FF3FC4F85C31CF -+:1021C00008BFA6663846BDE8F081C0460E2937B57F -+:1021D00005468E4614460BD00F2910D1114601A892 -+:1021E0000422EFF3C9F628460199F0F731FE08E022 -+:1021F000B0F85831002003F00103136001E0FCF354 -+:10220000E9F13EBD70B514460546FCF39FF1236825 -+:102210000BB10223AB6570BD70B50D460446FBF3F0 -+:10222000FDF7014610BBA36DEDB1FBB9D4F8542105 -+:102230000F4B02EA03037BB194F85431022B04D113 -+:1022400094F8573113F0010F05E0012B07D194F8F2 -+:10225000573113F0020F02D16FF0010300E00023A9 -+:1022600084F8563102E00BB184F85601084670BD7F -+:10227000FF0000FF10B50446FBF362F7002384F86B -+:102280005731A4F85831C4F85C3184F8563110BD88 -+:102290002DE9F041A2B0882205460C4690F8558100 -+:1022A00090F8567190F854616846EFF365F6284649 -+:1022B0002146FBF3AFF60246002836D1009B85F895 -+:1022C00056719E4285F854612CD01BB995F8573150 -+:1022D00073B112E0022B04D195F8573113F0010FBE -+:1022E00005E0012B07D195F8573113F0020F02D109 -+:1022F0006FF0010314E096B90DE0012E02D113F046 -+:10230000010F05E0022E05D195F8573113F0020FA9 -+:1023100005D107E036B995F85531434502D200237F -+:1023200085F85631009B85F85431104622B0BDE83F -+:10233000F081C0462DE9F04104460E46154690F85E -+:102340005671FBF363F48646A0B92A4601460DE0B8 -+:102350007318DB88083113F0100F06D194F8573149 -+:1023600043F0010384F8573102E0083A072AEFD816 -+:1023700084F856717046BDE8F081C0462DE9F04101 -+:1023800004460D46164690F85671FBF3DBF386467D -+:1023900098B9294632460CE04B6A13F0100F06D16B -+:1023A00094F8573143F0020384F8573103E0383A88 -+:1023B0003831372AF0D884F856717046BDE8F0817C -+:1023C000002070472DE9F0410B4C07460E460025D2 -+:1023D0000BE038462146EFF3A1F620B923799E425F -+:1023E00001D1A06806E001350C34044B1B689D4206 -+:1023F000EFD30020BDE8F08120FC0100F02B0200AB -+:1024000070B50D4600240AE00849284601EBC401D6 -+:102410000422EFF395F508B9013005E00134044BCF -+:102420001B689C42F0D3002070BDC04620FC010018 -+:10243000F82B020010B5034C216033F0F9DA0023C9 -+:10244000236010BD082C02002DE9F0412A4B0646FE -+:10245000D3F800800F4600250BE0284B304603EBF5 -+:10246000C5042146EFF35AF610B9E3789F4241D0F4 -+:1024700001354545F1D1224B0025D3F800800FE00E -+:10248000204B304603EBC5042146EFF347F630B945 -+:10249000E3789F4203D11C4B01221A7010E00135F2 -+:1024A0004545EDD117BB194B3D46D3F800800AE0F6 -+:1024B000174B304603EBC5042146EFF32FF608B95E -+:1024C000201D17E001354545F2D1124B124DD3F8CE -+:1024D0000080002408E029463046EFF31FF604355B -+:1024E00008B90E4806E001344445F4D13046394677 -+:1024F00032F074DEBDE8F081042C0200E3FB010041 -+:102500009421020018FC010098210200F82B02001F -+:1025100020FC0100FC2B020018FC0100CA0286000E -+:1025200010B5084B02461B783BB1074B1B6898421D -+:1025300003D2064B53F8200010B9104632F026DFC4 -+:1025400010BDC046982102007C200200781F0200C6 -+:1025500010B5084B02461B783BB1074B1B689842ED -+:1025600003D2064B53F8200010B9104633F006DBB7 -+:1025700010BDC04698210200802002008420020085 -+:102580002DE9F04F234B8FB01C68234B82468946C0 -+:10259000D3F800B00CB9204638E0036BA168186985 -+:1025A00007AA00F0FFFD00261C4DB0462BE0A368F3 -+:1025B0006F1F012B03D12878FFF702FF03E015F806 -+:1025C000010CFFF7C5FF694633F00EDC002107ABB5 -+:1025D0001DF80120CB5C1A420FD05046394632F02C -+:1025E000E5DD40B1B9F1000F05D009EB86003946B1 -+:1025F0000422EFF3DDF5013602E001311C29E6D1BA -+:1026000008F101080835D845D1D130460FB0BDE8F2 -+:10261000F08FC046082C0200F82B020025FC0100B8 -+:10262000012902D14FF6FF7010E0D0F8BC304FF016 -+:102630000002082BD0F8B03008BF41F40071A3F8B5 -+:10264000D813B3F8DA33A0F8202698B27047C04602 -+:10265000D0F8B030A3F8D813A3F8DA237047C046F7 -+:10266000D0F8B0300021A3F8D8134FF0010230B5F4 -+:10267000B3F8DA434FF00205A3F8D823B3F8DA230E -+:10268000A3F8D853B3F8DA3392B29BB2A0F820166D -+:10269000C4F3031040EA047042EA032240EA023025 -+:1026A00030BDC04670B505460E461446FFF7B8FF6C -+:1026B000314600EA04022846FFF7CAFF70BDC04653 -+:1026C00070B505460E461446FFF7AAFF40EA04021D -+:1026D0003146284692B2FFF7BBFF70BD2DE9F041AD -+:1026E0001546064688461C46FFF79AFF2C4020EA0E -+:1026F000050222433046414692B2FFF7A9FFBDE8EA -+:10270000F081C0462DE9F0411C46069B9046198099 -+:10271000079D0E46FFF784FF089B28801E802B88AC -+:1027200004EA080423EA0803099A23431380BDE856 -+:10273000F081C046D0F8B0304FF00002A3F8FC138F -+:10274000A0F82026B3F8FE0380B27047D0F8B0306E -+:1027500041EA0242C3F8FC237047C046D0F8B030CB -+:10276000A3F8FC13B3F8FE130A40A3F8FE234FF0BE -+:102770000003A0F82036704710B5D0F8B040A4F898 -+:10278000FC13B4F8FE339BB21A434FF00003A4F8D5 -+:10279000FE23A0F8203610BD10B5D0F8B04013408D -+:1027A000A4F8FC13B4F8FE1389B221EA02010B432A -+:1027B000A4F8FE334FF00003A0F8203610BDC04649 -+:1027C0002DE9F04106460C462CE0254635F8023B43 -+:1027D000571E990403F44043890CB3F5804F11D080 -+:1027E00001DC3BB11CE0B3F5004F10D0B3F5404F16 -+:1027F00012D015E03046628835F8023FFFF7CCFF73 -+:10280000013F0DE030466288FFF7A0FF08E0304648 -+:102810006288FFF7A3FF03E030466288FFF7ACFF52 -+:10282000AC1C7A1E002AD0DCBDE8F0812DE9F04115 -+:102830001C46069B90461980079D0E46FFF77AFFBF -+:10284000089B28801E802B8804EA080423EA0803DA -+:10285000099A23431380BDE8F081C04600234FF05E -+:10286000FF3280F8E33041F21A03C25403F59B7340 -+:10287000C254704710B531B140F23B414FF6F87287 -+:10288000FFF76CFF03E002490422FFF799FF10BD38 -+:102890002E03020060B1B0F8DE00B0F5006F05D085 -+:1028A000B0F5406F04D1A0F5386002E0402000E0B0 -+:1028B00000207047012380F8E130704780F824162B -+:1028C0007047C04690F924067047C0467047C0461E -+:1028D00010B1C06900B141777047C04610B1C069FE -+:1028E00000B101777047C04610B590F8E330044658 -+:1028F000002B49D14FF064014FF44872A0F88428AE -+:10290000A0F87C18A0F87E18C0F880381A46A318E2 -+:1029100002324FF06401102AA3F88618F7D14FF065 -+:102920000003A4F82E38A4F8AC37A4F8AE374FF063 -+:102930000A034FF00A02A4F83E38A4F83C38A4F881 -+:102940004038636A4FF01401A4F83228A4F84428F0 -+:10295000A4F83428A4F84628A4F82A28A4F828289B -+:10296000A4F82C28A4F89027A4F892274FF050023E -+:10297000A4F83018A4F89427A4F842180BB1204604 -+:102980009847012384F8E33010BDC04610B5FFF727 -+:1029900067FE10BD2DE9F84F0C46D1F810A00D6868 -+:1029A0009B468968E368064643EA812311469AB24A -+:1029B000BDF82880FFF7CAFE0027B9461EE0BAF12D -+:1029C000200F0BD159F8052030465946120CFFF75D -+:1029D000BDFE39F80520304641460AE0BAF1100F35 -+:1029E00004D135F817203046414602E07A5D304682 -+:1029F0004146FFF7ABFE013709F1040963689F42C6 -+:102A0000DDD3BDE8F88FC0462DE9F74F0D460193A1 -+:102A1000D1F810B00E68EB688968074643EA812355 -+:102A200011469AB2BDF83090FFF790FE4FF00008C3 -+:102A3000C24626E0BBF1200F0FD149463846FFF7CA -+:102A400079FE019904464AF806003846FFF772FEFF -+:102A500044EA00444AF806400FE0BBF1100F06D1EB -+:102A600038464946FFF766FE26F8180005E0384666 -+:102A70004946FFF75FFE08F8060008F101080AF171 -+:102A8000040A6B689845D5D3BDE8FE8F7FB50293E5 -+:102A9000089B03910593099B0192049301A90A9B4A -+:102AA000984707B000BDC0467FB50293089B0391CD -+:102AB0000593099B0192049301A90A9B984707B0CB -+:102AC00000BDC0460B46D0F8F81012B141EA03032E -+:102AD00001E021EA0303C0F8F830704700B5D0F8F0 -+:102AE000F8308E4621B143F01003C0F8F83012E000 -+:102AF00023F0100312F0010FC0F8F8300BD041F2B0 -+:102B0000D413C258C369196A986E814294BF714642 -+:102B1000091AC2F8901000BD00207047A0F8DE101E -+:102B20007047C046A0F8DA107047C046B0F8DA0027 -+:102B30007047C04640F6C313984201D800200BE00E -+:102B400041F2C843984201D8012005E041F24463B4 -+:102B500098428CBF032002207047C0467047C04691 -+:102B600000B5002286460748910030F822307345B0 -+:102B700002D10B18588803E001320E2AF3D100204D -+:102B800000BDC046A8FC010010B5C8B2FFF7E8FFC1 -+:102B9000FFF7D0FF10BDC04610B541F22823C45C3A -+:102BA0004FF0000C134B3CF803E0BEF10E0F8CBF4E -+:102BB0004FF480524FF400524EF4306342EA030067 -+:102BC0002CB1BEF1940F02D9BEF1A50F0AD902298A -+:102BD00003D1BEF10E0F0BD904E0012902D1BEF1E1 -+:102BE0000E0F05D80CF1040CBCF1380FDAD1FF2020 -+:102BF00010BDC046A8FC010010B590F8B2321446D2 -+:102C00000B6090F82B3653B190F8F83690F92A26DD -+:102C100023B1534243F080430B6000E00A6014B1DB -+:102C200090F8F7362370002010BDC04610B58646D8 -+:102C30001C4641F21B031EF8033002989B000E292C -+:102C4000137008D80028ACBF0EEB00030EF1000390 -+:102C500093F81E3127E07F23237030EA200028BF3D -+:102C600004200022114BD35A994202D00432382A50 -+:102C7000F8D1A1F122031E2B04D80EEB000393F828 -+:102C800083312370A1F16403282B04D80EEB0003D9 -+:102C900093F8E8312370A1F19503102B04D80EEBC3 -+:102CA000000393F84D32237010BDC046A8FC01000C -+:102CB0002DE9FF4700250746884691469A46FF269C -+:102CC0002C461EE0009341460DF10E020DF10F035C -+:102CD0003846FFF7ABFF41F2E623FA5C9DF80F1090 -+:102CE00053B2994201DC002302E0C2EB0103DBB2E4 -+:102CF0008DF80F30AB4228BF1D46B34238BF1E4689 -+:102D00000134142CE3B2DDD189F800508AF8006058 -+:102D1000BDE8FF877047C04690F829067047C04657 -+:102D2000B0F8DA3003F47043B3F5805F09D1032AB9 -+:102D300018DDA2F16503032B14D9A2F1C9030F2BEF -+:102D400010D9132A0EDCA2F13403642B0AD9A2F1A4 -+:102D5000A9031F2B06D9A2F1D103072B94BF002092 -+:102D6000012000E00020704770B590F8DA5004466A -+:102D70002846FFF7F5FEB4F8DA3003F47043B3F5F4 -+:102D8000005F01D0002004E02B1903F59A530F33A4 -+:102D9000187940B270BDC04600B54FF0000E00EB90 -+:102DA0000E021EF801300EF1010EBEF1040F82F882 -+:102DB0002C36F4D14FF0000E01EB0E0200EB0E03A7 -+:102DC00012790EF1010EBEF1080F83F83026F3D10F -+:102DD00000BDC04680F8E0107047C046C3699961E5 -+:102DE0007047C04680F8D5104176704780F8D910FA -+:102DF0007047C0467047C04690F81A067047C046F4 -+:102E000041F22403C35C33B141F21C2380F81A164B -+:102E100080F81B16C154704790F8D83013B10023C6 -+:102E200080F8D83000207047C369012093F88130C2 -+:102E30000B70704722B10023C0F8E83FA0F8EC3FC8 -+:102E400000F58153012019607047C0460022C16916 -+:102E500010460B1893F982300130D2180828F8D1A7 -+:102E600092FBF0F040B270477047C0466FF016001A -+:102E70007047C04670B541F21E23C35C04468B42C6 -+:102E80000D46164603D0D0F8883003B1984704F5B4 -+:102E900091531E8041F21E23E55470BD0021C36989 -+:102EA000CB180131082983F88220F8D10021C369A9 -+:102EB0006FF05B02CB180131082983F88220F6D12C -+:102EC000C2690023C2F88C30D36E032B08D1D0F82E -+:102ED000F83F13F0010F03D0136A0833C0F8F03F36 -+:102EE00000F58A531233002204E0002241F2D2138B -+:102EF000C25470474FF6A47101321980198402330D -+:102F0000102AF7D1F1E7C04649F675334B6000232C -+:102F10000B60F0B50C469842ACBF01214FF0FF3179 -+:102F200003F5340301FB03F103F53403081890FBA8 -+:102F3000F3F202FB1303581A03D4C31301335B10DB -+:102F400004E04342DB1301335B105B425A2BD4BFD6 -+:102F50000023012313B1A0F5340014E0002803DBA3 -+:102F6000C31301335B1004E04342DB1301335B10F6 -+:102F70005B4213F15A0FACBF002301230BB90126AA -+:102F800003E000F534004FF0FF364FF0000EF4463A -+:102F90007546604561682268144F0BDD41FA0EF3F7 -+:102FA0009B18236042FA0EF3C3EB01036360EB59F5 -+:102FB0009C440BE041FA0EF3C3EB0203236042FA98 -+:102FC0000EF35B186360EB59C3EB0C0C0EF1010EB2 -+:102FD0000435BEF1120FDCD1636806FB03F36360B6 -+:102FE000236806FB03F32360F0BDC046F4FC010038 -+:102FF00080EAE071A1EBE0710022D0B251FA00F357 -+:103000000132002BF9DC70470146002000B58646EE -+:103010004FF0804343FA0EF31A188A424FEA5000E9 -+:1030200002D8891A43EA00000EF1020EBEF1200F09 -+:10303000EED1884238BF013000BDC046C36983F875 -+:103040009010C36983F89120C36983F89210C36913 -+:1030500083F893207047C046C36983F89210704785 -+:1030600041F21633C256013BC0568242B4BF012022 -+:10307000022070470048704750FD01000020704753 -+:103080007047C046084670470020704741F2D81389 -+:10309000C05803E0C3888B4202D000680028F9D1F1 -+:1030A0007047C04610B5B0F8DA10FFF7EFFF10BD5B -+:1030B000C3699B6913F0005F09D0D0F8B0304FF0BE -+:1030C0000302A3F8B4264FF0FF02A3F8B826704716 -+:1030D000D0F8F83013F0060F0CBF00200120704725 -+:1030E0002DE9F0410F46B0F8DA10044615461E46A9 -+:1030F000FFF74AFD40B9B4F9FC302B60B4F9FE305B -+:103100003360B4F900313B60BDE8F081D0F8A8002D -+:103110007047C04670B541F2D813C15805460AE061 -+:103120000B6841F2D8142B51EB694FF43D7298684B -+:10313000F3F3DEF529590029F2D141F2D81305F550 -+:1031400090523032E950043BEA504FF6CE70F033E3 -+:10315000E852C2F8901070BD10B590F8E93094B004 -+:1031600043F0010380F8E93004460021302201A831 -+:10317000EEF366F7002110220DA8EEF361F70021AF -+:10318000042213A8EEF35CF711A800210822EEF345 -+:1031900057F794F8E930002023F0010384F8E93070 -+:1031A00014B010BD70B506460D46104614460021F9 -+:1031B0001C22EEF345F700200F4BC25A41F22823A0 -+:1031C000F35C1BB1942A01D9A52A10D9022D02D192 -+:1031D0000E2A04D90BE0012D09D10E2A07D9D108F6 -+:1031E00002F0070301229A40635C134363540430E6 -+:1031F0003828E1D170BDC046A8FC010010B50C46CE -+:10320000002103F025F82070012010BD10B5002129 -+:1032100003F01EF840B210BD41F2D41310B5C458EB -+:10322000F433C15819B1C36918693DF095DA002328 -+:103230006370A37010BDC04610B59E462BB941F215 -+:103240000723C35C704613600FE041B1012906D02B -+:10325000022904D0032902D06FF01C0005E041F2DE -+:103260000723C154FFF7D8FF002010BD41F2C82347 -+:10327000C15810B509B9084607E0C36918693DF09F -+:103280006BDAD0F1010038BF002010BD10B541F25B -+:10329000F423C35C0BB104F097FD10BD10B503F02F -+:1032A000B5FB10BDC36970B5DC681B6D054613F036 -+:1032B000010F0E4608D02046F7F3FAF520B1EB696E -+:1032C0009B6913F0005F12D1EA69136D13F0010FCF -+:1032D0003BD0536D13F0800F37D1D068F7F386F7EA -+:1032E000002832D0EB699B6913F0005F2DD0D5F830 -+:1032F000F83013F0020F28D1EEB106F47043B3F5A5 -+:10330000005F18D163691149232BB4BF00230C233C -+:10331000F2B2B8BF0F2120469A400123F7F3D0F54F -+:1033200063690B49222B2046D8BF7021CCBF4FF4D4 -+:103330000072102206E0636904492046222BD8BFA0 -+:103340000F2100220123F7F3BBF570BD00F05555A6 -+:10335000000E5555D0F8B030C269D3F82031136D46 -+:1033600070B513F0010F04460D4608D0D068F7F38E -+:103370009FF520B1E3699B6913F0005F11D1E26909 -+:10338000136D13F0010F18D0536D13F0800F14D18B -+:10339000D068F7F32BF780B1E3699B6913F0005F06 -+:1033A0000BD025B920462946FFF77CFF0AE02046CE -+:1033B000B4F8DA10FFF776FF00E01DB104492046AB -+:1033C000062202E0034920460E22FFF7F9F970BDFC -+:1033D000360302008CFC010010B514299E46D0F87B -+:1033E000A82004D015290CD06FF016000CE092F93B -+:1033F0001A3002A941F8043F70460422EEF3BCF5EE -+:1034000001E0039B9376002010BDC04610B590F8F4 -+:103410001A360C462BB10231224601F091FDA378F9 -+:10342000637010BD10B5012103F072FA10BDC046E3 -+:103430002DE9F0418A79CB790D4642EA03216B7977 -+:103440002A79074642EA0328C3695B690A2B07D930 -+:10345000EB7C1B0213F4807002D10123EB7735E083 -+:103460002A7A6B7A384601F0FF0442EA0326FFF716 -+:103470004DFE7F2C1B4AC8BFA4F58074B30AD356F7 -+:1034800090F85F00E21818F4006F14BF41F23B336C -+:1034900041F23A33FB56D11843B2C918AA7DEB7DED -+:1034A0007F2942EA0322C2F3C702C8BFA1F5807197 -+:1034B0000E2AD4BF4FF400534FF4805342F43062CD -+:1034C000384649B243EA0202FFF7DCFD6A79C1B22D -+:1034D0002977384649B2C2F3801201F00DFBBDE8EE -+:1034E000F081C0461A22020010B590F8E9309646E5 -+:1034F00053B313F0010F19D0D0F8F0308B420FD135 -+:10350000C369D3F88C209B1883F882E0C269D2F893 -+:103510008C30072B01D1002300E00133C2F88C303E -+:1035200090F8E93023F0010380F8E93090F8E930B1 -+:1035300013F0020F08D023F0020380F8E930C369CA -+:10354000724618693DF01CD910BDC04690F8E930AC -+:1035500010B5ABB9012902D0022902D003E0C0F8AE -+:10356000F02080F8E910C3691B6AC0F8EC3041F222 -+:103570000503C35C23B111466FF05E02FFF7B4FF91 -+:1035800010BDC04637B5044602F01CFFE3691A6A55 -+:1035900001321A6294F8E830002B77D041F262339E -+:1035A000E35A1BB1A4F86E38A4F8703841F26633C0 -+:1035B000E35A1BB1A4F86838A4F8643841F26433C4 -+:1035C000E35A1BB1A4F86238A4F86638E369196AB3 -+:1035D0001A6EB1FBF2F302FB131323B92046B4F8C1 -+:1035E000DA10FFF75FFED4F8F83013F00E0F05D1B4 -+:1035F0002046012194F8DA20FFF7A8FF94F8E9307B -+:103600004BB1E369D4F8EC201B6A9B1A052B02D955 -+:10361000002384F8E93041F22805615929B1E369B2 -+:103620001A6A1B6E521A9A420BD3D4F8F83013F070 -+:10363000020F06D12046FFF76FFA10B1E3691B6A4B -+:103640006351D4F8F83013F00F0F1FD1D4F88C3039 -+:103650000BB120469847E36918693DF005D868B179 -+:10366000E36901A918690DF107023DF007D820466A -+:103670009DF80710BDF80420FFF7FCFBD4F8F830E4 -+:1036800013F00F0F02D1204603F0C0F900203EBD19 -+:1036900010B50446FFF74AFA0221C2B22046FFF7EE -+:1036A00055FF10BDC36973B5012983F88110044625 -+:1036B0000D46C36906D9186901220323009300212E -+:1036C000134605E0186900210323009301220B46ED -+:1036D0003CF0FADFE269537F002B30D0D4F8B030F1 -+:1036E000D3F8203183F0010313F0010602D11069F1 -+:1036F0003DF050D8012D0FD90222134620464FF439 -+:103700008261FFF749F820464FF482610122022DC1 -+:1037100014BF002301230BE020464FF482610222F4 -+:103720000023FFF739F820464FF4826101222B462F -+:10373000FFF732F81EB9E36918693DF017D87CBD70 -+:10374000C36970B547F67F750446582118692A4643 -+:103750003CF0EEDFE3695A2118692A463CF0E8DFC5 -+:10376000E369702118692A463CF0E2DFE3697221BF -+:1037700018692A463CF0DCDF70BDC046F7B5C26967 -+:103780000546537F002B62D090F81A36002B45D0A7 -+:10379000106928213F223CF0CBDFEB692421186916 -+:1037A00010223CF0C5DFEB6995F82926186926211F -+:1037B00012013CF0BDDFEB6932211869B5F8FC2637 -+:1037C0003CF0B6DF2E460027EB691869204BF95C08 -+:1037D0003CF086DFEB6996F914250446A11D1869B3 -+:1037E00092B23CF0A5DF96F914250223E96992FB19 -+:1037F000F3F25242086992B204F10E0101373CF033 -+:1038000097DF0136082FDFD1EA690323009310699F -+:103810008022012113463CF057DF18E001460420C6 -+:1038200091F914350822073393FBF2F3DB000130E2 -+:1038300081F8143501310C28F2D195F91425EB6982 -+:10384000073218694E21C2F3CF023CF071DFFEBD92 -+:103850002503020010B5012102F0B6FC40B210BDF4 -+:1038600010B500210446621801317F23652982F8D2 -+:103870009136F8D12046FFF7EDFF2046FFF7C6FC52 -+:1038800010BDC0462DE9F04FB0F8DA30A5B003F412 -+:103890007041B1F5805F14BF022201220592D0F879 -+:1038A000A83004460693C3695A6C40F239539A42D1 -+:1038B00004D052339A4201D0002304E0B1F5805F76 -+:1038C00014BF00230123DBB2002165220DF1290082 -+:1038D0000893EEF3B5F3B4F8DAA00AF44073B3F545 -+:1038E000407F02D15FFA8AF810E0B3F5007F5FFAFB -+:1038F0008AF104D1DD2904D801F1020806E0022989 -+:1039000002D84FF0000801E0A1F102082046059915 -+:10391000FFF7A6FF2046FFF727FA4FF0000BC0B2D3 -+:10392000FF255E4607900395CDF810B070E0204665 -+:1039300051462A46FFF7F4F9002867D005EB040941 -+:1039400099F8B26224AA571907F8676C94F8AC305A -+:1039500043B1059A204641462B46FFF78FFB3018AE -+:1039600007F8670C41460DF18E020DF18F032046DA -+:103970000095FFF75BF999F82C269DF88F309A4255 -+:1039800034BF1146194641F2E623E25C53B2994234 -+:1039900001DC002002E0C2EB0103D8B224AB5919CC -+:1039A00011F8673C984234BF02461A4601F8672C6A -+:1039B00094F8E030642B06D803FB02F3642293FBF7 -+:1039C000F2F301F8673C11F8673C9DF88E20079EE2 -+:1039D0009A4238BF1A462B1993F891368DF88F000A -+:1039E000934294BFC6EB0306C6EB0206049AF3B2F9 -+:1039F0005B4588BF2A46049201F8673C039D5B45FE -+:103A000028BF9B46AB4238BF1D460395099E013631 -+:103A10000996099A142AD5B289D104F5A260002129 -+:103A20005132EEF30DF3039B049D84F8293684F89C -+:103A30002A360023184684F818B684F8F83684F835 -+:103A4000195616E024AE731813F8672C94F81A363A -+:103A5000091981F875250BB1089B1BB194F818362C -+:103A60009B1A03E094F82936C3EB020381F8103562 -+:103A700001301428C1B2E5D121460020069D91F9FC -+:103A80001035B5F9E623D218431CD8B281F81025B9 -+:103A900001310428F2D1E36A0BB12046984725B0E2 -+:103AA000BDE8F08F70B505460E462C46FFF774F959 -+:103AB000294600203218137D03B91379013081F8AB -+:103AC000383601310828F5D10021721892F84430B7 -+:103AD00003B91379013184F8483601340829F4D147 -+:103AE000EB6918693CF056DE2846FFF7CBFEEB6920 -+:103AF00018693CF03BDE70BD7F2970B5044601D9E2 -+:103B0000052028E0002213190132652A83F8B21239 -+:103B1000F9D10023E26984F8F736137FD3B1D4F8E2 -+:103B2000F83013F0020F15D1D4F8B030D3F82031AB -+:103B300083F0010313F0010502D110693CF02ADE85 -+:103B40002046FFF79FFE2DB9E36918693CF00EDEB1 -+:103B5000284600E0002070BD70B5054600F52C70C9 -+:103B6000042202300C46EEF307F205F52C70211DFD -+:103B700008220630EEF300F205F52E70082206301A -+:103B800004F10C01EEF3F8F105F538700822063067 -+:103B900004F13401EEF3F0F105F53A700822063035 -+:103BA00004F13C01EEF3E8F105F53070082206302F -+:103BB00004F11401EEF3E0F105F53270082206304D -+:103BC00004F11C01EEF3D8F105F53470082206303B -+:103BD00004F12401EEF3D0F105F536700822063029 -+:103BE00004F12C01EEF3C8F105F53C700822063013 -+:103BF00004F14401EEF3C0F105F53E7004F14C010F -+:103C000008220630EEF3B8F105F5407008220630C0 -+:103C100004F15401EEF3B0F105F5427006300822CC -+:103C200004F15C01EEF3A8F194F8643085F81633E2 -+:103C3000D5F8B030D3F8203113F0010309D11C4678 -+:103C40002846FFF71FFE54B1EB6918693CF08EDD82 -+:103C500005E0EB69012418693CF09CDDF0E770BDDC -+:103C60002DE9F0410F460546FFF710FA07F47043BF -+:103C7000B3F5805FEB69FAB208BF42F48072044684 -+:103C8000A02118693CF054DDAE6A2CB104F517721E -+:103C900041F2D413EA5005E005F59053303341F278 -+:103CA000D412AB5016B128463946B0472CB341F276 -+:103CB000D413EA58537873B1EB6941F2C8242959F7 -+:103CC00018693CF049DDEB6900221869295913464F -+:103CD0003CF0C0DC11E041F20723EB5C6BB1032B3D -+:103CE0000BD0E969D2F890200B6A9B1A8A6E934236 -+:103CF00003D328460221FFF7D5F928463946FFF7B6 -+:103D0000D1FABDE8F081C046E02910B50B46044663 -+:103D100002DD6FF0120012E043F430630E29D4BFCD -+:103D20004FF400514FF48051194389B2FFF798FFC7 -+:103D30000123204684F8D83008F092FF002010BDFF -+:103D400070B50C460546FFF767F844B9284605F0FC -+:103D5000D9FE28464FF4404106F0AEF910E0214666 -+:103D600028460022FFF7D0FF044648B928462146DE -+:103D70007022234605F04AFB28465E2106F0EEFD40 -+:103D8000204670BD2DE9F0410D460446FFF744F88A -+:103D900045B92046294602F0B3FC2F4641F2D42310 -+:103DA000E55213E0204629460122FFF7ADFF074602 -+:103DB00060B941F2D426A35B23B920460A21FEF75D -+:103DC000B9FCA0532046294602F09AFC3846BDE8CB -+:103DD000F081C04670B50E460546D0F8B040FFF7FA -+:103DE0001BF83EBB41F2D6240A2128462A5BFEF787 -+:103DF000ADFC284640F24B413246FEF7A7FC284670 -+:103E0000314602F0DDFBEB692E531B6D13F0020F00 -+:103E100056D041F2D823D5F8B020EB5A4FF47A703F -+:103E2000A2F89C3441F2DC23EB5AA2F89E34F2F360 -+:103E300093F445E0EB691B6D13F0020F1FD0D5F82A -+:103E4000B01041F2D822B1F89C344FF47A709BB292 -+:103E5000AB50B1F89E3404329BB2AB50B4F89C34F2 -+:103E600023F400731B041B0CA4F89C34B4F89E3498 -+:103E70009BB243F40073A4F89E34F2F36DF4314620 -+:103E800028460122FFF740FF0646C8B941F2D62472 -+:103E90002B5B5BB90A212846FEF74CFC40F24B41F4 -+:103EA00028534FF6FF722846FEF750FC28460121A2 -+:103EB00002F086FB28460A214FF49472FEF75CFC60 -+:103EC000304670BD2DE9F0418AB005AED0F8B07033 -+:103ED00005468846142238493046EEF34DF0142248 -+:103EE00036496846EEF348F0EB6900216C461869E4 -+:103EF000142288450CBF234633463CF023DC4FF0A8 -+:103F00000003A7F86835B8F1000F4FF48073A7F8E5 -+:103F1000C0370CBF40234123A7F80C3541F60223DC -+:103F2000A7F814354FF00003A7F80835A7F80A35AD -+:103F3000A7F84C354FF01403A7F86A3540F626036E -+:103F4000A7F868354FF00003A7F800354FF0D0030D -+:103F5000A7F80235B7F802350CBFFA251E25002454 -+:103F600002E00A20F2F3F8F3AC420ADAB7F80E35B1 -+:103F7000013413F0800FF4D103E00A20F2F3ECF3E4 -+:103F800000E0002401340B2C09D0B7F80E3513F4EF -+:103F9000806FF2D003E00A20F2F3DEF300E00024A9 -+:103FA00001340B2C04D0B7F8903613F4807FF2D193 -+:103FB0000AB0BDE8F081C046E0FC01003CFD010014 -+:103FC00070B590F8E2200446002A6CD1012380F8F5 -+:103FD000E230D0F8B030A0F8DA10D3F8203100F594 -+:103FE00081531A60D0F8F82012F0020F06D190F831 -+:103FF000803E1BB942F02003C0F8F830256A002D3E -+:1040000051D001212046FEF735FCB4F8DA30B4F87F -+:10401000DE2003F44061914203D0E36918693CF06B -+:1040200035DB012141F2CD23E1542046FFF792F91F -+:104030002046A847002384F8E1302046FFF79EFB86 -+:10404000E369204693F88110FFF72CFBE26992F8B0 -+:104050008030012BB4F8DA300BD103F47043B3F5A0 -+:10406000005F01D1936F0BE0D36F012B88BF00235A -+:1040700006E003F47043B3F5005F0CBF136F536F9A -+:10408000D366E3690022D96E2046FEF7D3FE0023F3 -+:1040900084F8E230E369922118693CF02BDB41F2AD -+:1040A00022234000E05270BDC36910B518693CF08E -+:1040B0002BDB10BDC36910B518693CF02FDB10BDB8 -+:1040C000F7B5089F04460D461E463BB1032A05D9A5 -+:1040D000684619460422EDF34FF701E000230093F0 -+:1040E000A82D009900F0FB8015DC5C2D00F0AE805F -+:1040F00008DC3C2D00F0A0804A2D00F093801B2DA1 -+:104100002AD020E05E2D30D0C0F2A8805F2D3DD0B7 -+:10411000872D1BD017E0C32D75D006DCAA2D49D002 -+:104120007BDBC22D00F0DB800DE0D42D00F0AB80F6 -+:1041300003DCD32D00F09B8005E0A5F59A73033BCB -+:10414000012B40F2D2806FF01605CFE02046FEF73B -+:104150007DFE40B23060C8E0E3691D7F002D40F075 -+:10416000B8802046FEF77AFBC0E001233B70E3698C -+:104170005B7F002B00F0B0802046FFF79BFF2046BE -+:10418000BDF80010FEF7D6FA30600FE001233B7057 -+:10419000E3695B7F002B00F09F802046FFF78AFFDA -+:1041A000009A204691B2120CFEF7D0FA2046FFF793 -+:1041B0007BFF9AE0E269537F002B00F08D8010694D -+:1041C0003CF0E8DA00252046FFF774FF3560D4F8AC -+:1041D000BC30082B13D10DF1060220460DF107016A -+:1041E0008DF807508DF8065000F0AAFE9DF90720C3 -+:1041F0009DF9063092B29BB243EA02233360204617 -+:10420000FFF752FF60E0E3691B7F002B6AD0338821 -+:10421000022B64D96FF0010568E0E3691B7F002B76 -+:1042200060D05CE0E3691B7F002B52D1236B002B35 -+:104230005BD02046984718E0E3691B7F002B48D1EC -+:1042400020467268B368FFF7C5FD0EE0E3691B7F87 -+:10425000002B3ED12046FFF773FD06E0E3691B7F8C -+:10426000002B36D12046FFF78DFD05463EE0E36981 -+:10427000DA6E3260D4F8F83F13F0010F35D042F017 -+:104280008003336031E0042902D96FF01C052DE072 -+:10429000E269D36E8B4228D0137FD1662BB31069AD -+:1042A0003CF078DA009B23B1204600210122FEF782 -+:1042B000C1FDE36901222046D96EFEF7BBFD00284F -+:1042C00014BF00256FF00205E36918693CF04EDA6F -+:1042D0000CE06FF0040509E06FF00A0506E06FF0EE -+:1042E0000C0503E06FF0030500E000252846FEBD45 -+:1042F0002DE9F04389B09946109B0026032B074611 -+:104300000C46DDF84480139D079604D907A849465A -+:104310000422EDF331F6079940F286230A1E18BFF6 -+:1043200001229C4200F013812CD80C3B9C427CD093 -+:104330000FD8532C08D8522C80F04081502C00F01C -+:104340003D81512C6AD02DE140F26A239C4250D02D -+:1043500028E1B4F5207F00F0E48009D840F27B2307 -+:104360009C4200F0A48003339C4200F0D58019E108 -+:10437000B4F5217F00F0E48040F285239C4200F0F8 -+:10438000DB800FE140F2D6239C4200F0178114D865 -+:10439000413B9C423ED006D8043B9C4234D0023381 -+:1043A0009C4234D0FEE0B4F5277F00F0D78040F285 -+:1043B0009D239C4200F0D680F4E040F2DD239C4235 -+:1043C00000F0EB8008D8033B9C4200F0D180B4F5AC -+:1043D000377F00F0D680E5E0B4F53D7F00F0F38054 -+:1043E000C0F0E080A4F53E73063B012B00F2DA80BA -+:1043F000E9E03846FFF75EFE38464146FFF706F82B -+:104400003846FFF751FE50E041F2623304E041F2DA -+:10441000643301E041F26633F95246E00123009330 -+:1044200038464346FEF722FDCFE0FA69137F13B901 -+:104430006FF00300C9E0D7F8B030D3F8203183F033 -+:10444000010313F0010902D110693CF0A3D93846E9 -+:10445000FEF72EFE3846FFF72DFE41F2E61341F23D -+:10446000E910F95C385C0133FA5C013317F803E0BA -+:10447000009041F2EA103D5C01303C5C1630385C43 -+:10448000734603903846019502940496FEF764FE45 -+:10449000C8F800003846FFF707FEB9F1000F40F0FA -+:1044A0008D80FB6918693CF061D930468DE0C1F31D -+:1044B000036CBCF1010F00F28380C1F3015EBEF119 -+:1044C000010F7DD8C1F38155032D79D0C1F3034489 -+:1044D000012C75D8C1F30722A2F10A03DBB2052B28 -+:1044E0006ED8C8B2012801D9032869D10E2A28BF85 -+:1044F0000E2241F2E613FA540133F8540133FC540E -+:10450000013307F803E00133FD54013307F803C01A -+:104510000A0F1633FA54C8E708A9012341F8043DED -+:1045200007E0B7F8DA103846FEF72EFB08A941F885 -+:10453000040D40462A462DE041F21B03F954B4E72E -+:1045400041F21B03FB5C08A941F8043D17E0D7F8D2 -+:10455000F830C3F30013C8F80030A6E738464246E7 -+:10456000334602E0384642460123FEF765FE9CE7EB -+:104570000121384601F03AFF08A941F8046D404690 -+:1045800007E007AC38463146224601F093FF40462B -+:1045900021460422EDF3F0F487E73846324601F075 -+:1045A00089FF82E701910292384621464A464346F6 -+:1045B0000095FEF711FF10F1170F04D0002004E062 -+:1045C0006FF01C0001E06FF0160009B0BDE8F08349 -+:1045D0002DE9F04391460A6801230B7342F008036A -+:1045E0000B60B0F9FA3685B0B3F1FF3F04BF42F07B -+:1045F00009030B6090F81A3605460C461BB10B6890 -+:1046000043F002030B602F4626464FF0000897F850 -+:10461000B2322846B37749460DF10E030DF10F0271 -+:10462000CDF80080FEF702FB9DF80E3008F101087E -+:1046300086F8B03197F87535013786F8793201364A -+:10464000B8F1140FE3D195F81A3633B3EB691B7F39 -+:104650001BB32846FFF72EFD95F818362846A3759C -+:1046600095F81836E37595F81936A37695F8193646 -+:10467000E37600F05BFC236810B143F0030301E034 -+:1046800023F003032846236004F10D0104F1150211 -+:1046900000F056FC2846FFF707FD05B0BDE8F083A3 -+:1046A00010B5054B1B78012B03D1013B18461B703D -+:1046B00001E014F00BFE10BD3C28020010B5054BC4 -+:1046C0001B78012B03D1013B18461B7001E014F04D -+:1046D00023FE10BD3C2802002DE9F04105460E46A0 -+:1046E00017461C46FFF7EAFF30B1234628463146FD -+:1046F0003A4614F04BFE04462046BDE8F081C04621 -+:1047000010B50023FFF7E8FF10BDC04610B51446F2 -+:10471000FFF7D4FF20B100210A46EEF319F004465A -+:10472000204610BD10B50022FFF7F0FF10BDC046B7 -+:104730001FB5079B0C890093089B11460193099BA9 -+:10474000224602930A9B03930069069B28F02EDD04 -+:1047500004B010BD00B5B0FBF1FE01FB1E0001F07E -+:10476000010C0CEB51010BE0884228BFC1EB0003A8 -+:104770004FEA4E0E26BF0CEB43000EF1010E400037 -+:10478000531EDAB2FF2AEFD1884228BF0EF1010E84 -+:10479000704600BD00FB01F19202800103FB002086 -+:1047A00001F5004101EB4000490090FBF1F070473A -+:1047B000D0F8A8304FF001025A8670472DE9F04733 -+:1047C00098469DF820308A4691469DF82470B3B1F2 -+:1047D00000246FF000462546204651464A4643468F -+:1047E000FFF7D8FFB04204DA6B1CDDB2BD421AD02D -+:1047F00006460134802CEFD16FF0004013E07F2497 -+:104800004FF0FF361D46204651464A464346FFF7C5 -+:10481000C1FFB04204DD6B1CDDB2BD4203D00646D1 -+:10482000013CF0D22046BDE8F087C04610B5B0F894 -+:10483000DA300446DAB203F47043B3F5005FD0F81F -+:10484000A81003D1531893F8E72486E0702A5ED0AD -+:104850001CD8382A49D00CD82C2A3DD004D8242A78 -+:1048600034D0282A35D02FE0302A38D0342A39D015 -+:104870002AE0642A42D004D83C2A39D0402A3AD0CF -+:1048800022E0682A3DD06C2A3ED01DE0882A50D014 -+:104890000CD87C2A44D004D8742A3BD0782A3CD047 -+:1048A00012E0802A3FD0842A40D00DE0992A49D0D6 -+:1048B00004D88C2A40D0952A41D005E0A12A47D0BF -+:1048C000A52A48D09D2A40D0002246E091F8F6243F -+:1048D00043E091F8F72440E091F8F8243DE091F8A6 -+:1048E000F9243AE091F8FA2437E091F8FB2434E017 -+:1048F00091F8FC2431E091F8FD242EE091F8FE249B -+:104900002BE091F8FF2428E091F8002525E091F8AC -+:10491000012522E091F802251FE091F803251CE013 -+:1049200091F8042519E091F8052516E091F806257F -+:1049300013E091F8072510E091F808250DE091F8B3 -+:1049400009250AE091F80A2507E091F80B2504E013 -+:1049500091F80C2501E091F80D25D1F8E40494F8C4 -+:104960002A36C01A801840B210BDC04608467047AB -+:1049700049B24B1C5B104910C3F10803083141EAEE -+:10498000031188B27047C046B0F8DA3003F47043C0 -+:10499000B3F5005FD0F8A82005D192F83C05FF28B8 -+:1049A00001D0C0B200E000207047C04670B5054697 -+:1049B000D0F8A840FFF7E8FF10B994F8460540B1D9 -+:1049C000B5F8DA3003F47043B3F5005F14BF00208C -+:1049D000012070BD10B50C468EB0D0F8A8109646D8 -+:1049E000002000220DF10603C25401303228F8D114 -+:1049F000BEF1FF3F91F8E93306D114B1B1F93EE5BC -+:104A000003E0B1F940E514E09CB1A02B09D00023EC -+:104A10008DF806308DF807308DF808308DF80930A4 -+:104A200004E000238DF806308DF808308DF80A3048 -+:104A300033E0A02B17D001238DF81A308DF81B30EE -+:104A40006FF0010300228DF81E308DF81F30013306 -+:104A50008DF81C208DF81D208DF820208DF8213038 -+:104A60008DF8242019E002238DF81A306FF003032B -+:104A70008DF81E30023300228DF81F308DF8203063 -+:104A80008DF8213006338DF81B208DF81C208DF811 -+:104A90001D208DF824208DF832300EAA02EB0E0373 -+:104AA00013F9320C0EB010BD30B5C46900F5805357 -+:104AB000226A1B68D0F8A8509A4202D3C3EB0201C5 -+:104AC00001E0DB43991895F8BC2290F8DA309A425D -+:104AD00001D0012004E0A36E994234BF00200120E0 -+:104AE00030BDC0467047C046D0F8A83093F80604E1 -+:104AF000002808BF1020704700B5D0F8A8008E46E7 -+:104B0000D0F8D4240EF0FF0343EA0223110EC0F8BC -+:104B1000D434D0F8D8347F29C8BFA1F5807173444C -+:104B20005B1AC0F8D8349B10C0F8DC3400BDC04616 -+:104B3000844610221B4810B5964600244EF34603C7 -+:104B40005FFA83FE10EA0C0F4FFA8EF104D0884012 -+:104B50000EEB0203DAB203E0C840CEEB0203DAB296 -+:104B60000134042CEAD110EA0C0FD3B201D1013B7D -+:104B7000DAB251B2032301FB03F30329DAB20EDDEB -+:104B8000CB1E2CFA03F00D2801D9D31C06E00A280D -+:104B900001D9931C02E0082801D9531CDAB250B2A3 -+:104BA00010BDC0460000FFFFD0F8A820002382F807 -+:104BB000903382F8913382F8923382F8933382F8FB -+:104BC000943370477047C04670B540F22341D0F827 -+:104BD000A8500446FDF7AEFDC0B2A5F864034FF43B -+:104BE000AA612046FDF7A6FD8005800DA5F86803A3 -+:104BF00040F234412046FDF79DFDC0B27F28C8BF7A -+:104C0000A0F58073A5F8660340F23241C8BFA5F84D -+:104C100066332046FDF78EFDC0B27F28C4BFA0F5E5 -+:104C2000807398B285F8BC0370BDC0462DE9F0478B -+:104C3000884640F2B76104469146FDF77BFD40F29D -+:104C4000B66105462046FDF775FD40F2B5610646A2 -+:104C50002046FDF76FFD40F2B46107462046FDF7A0 -+:104C600069FD4FF0000C6246644650FA04F313F0FD -+:104C7000010101D0012103E00CF101035FFA83FC83 -+:104C8000531CDAB2102A12D001340029EDD00EE004 -+:104C9000A2F1100357FA03F313F0010F01D0012121 -+:104CA00003E00CF101035FFA83FC531CDAB21F2A04 -+:104CB00011D80029ECD00EE0A2F1200356FA03F33C -+:104CC00013F0010F01D0012103E00CF101035FFAA1 -+:104CD00083FC531CDAB22F2A11D80029ECD00EE045 -+:104CE000A2F1300355FA03F313F0010F01D00121B3 -+:104CF00003E00CF101035FFA83FC531CDAB23F2A94 -+:104D000001D80029ECD04FF03F0E00220F2455FAB5 -+:104D100004F313F0010101D0012103E00EF1FF3390 -+:104D20005FFA83FE531CDAB2102A12D0013C00292C -+:104D3000EDD00EE0C2F11F0356FA03F313F0010F9A -+:104D400001D0012103E00EF1FF335FFA83FE531C13 -+:104D5000DAB21F2A11D80029ECD00EE0C2F12F03DD -+:104D600057FA03F313F0010F01D0012103E00EF114 -+:104D7000FF335FFA83FE531CDAB22F2A11D80029C1 -+:104D8000ECD00EE0C2F13F0350FA03F313F0010F31 -+:104D900001D0012103E00EF1FF335FFA83FE531CC3 -+:104DA000DAB23F2A01D80029ECD088F800E089F86F -+:104DB00000C0BDE8F087C04670B50D4640F23941ED -+:104DC0000646FDF7B7FCC0F3C210E88040F2B541DB -+:104DD0003046FDF7AFFC40F2FB4104463046FDF79C -+:104DE000A9FC04F0FF03C0B2C4F307242B806C803D -+:104DF000A88070BD2DE9F047B0F8DA30074603F41B -+:104E00007043B3F5805FD0F8A82009D1B2F89205BD -+:104E100003B2B3F1FF3F0CBF4FF4C87080B24CE057 -+:104E2000B2F8904523B2B3F1FF3F01D0A0B244E005 -+:104E300040F2A541FDF77EFC40F2A541814638468F -+:104E4000FDF778FC40F20D4106463846FDF772FC4E -+:104E500040F20D4104463846FDF76CFC40F2A24199 -+:104E600005463846FDF766FC40F2A24180463846CA -+:104E7000FDF760FCC6F30236012313FA06F6C0F311 -+:104E80000220C5F3022513FA05F58340E4B25FFA68 -+:104E900089F94C44B6B2A419ADB29BB25FFA88F856 -+:104EA0006419434404EB430464005034A4B2B4F5E1 -+:104EB000C86F2CBF20464FF4C860BDE8F087C046DD -+:104EC00010B540F2FB41FDF735FCC0F3062010BDE4 -+:104ED00070B540F2A4410446D0F8A850FDF72AFC72 -+:104EE000C0F38130032814D141F22403E35C83B181 -+:104EF000204640F27341FDF71DFC95F96635C0056B -+:104F0000C00D013303FB00F3022293FBF2F3D8B28E -+:104F100001E095F8C10240B270BDC04610B540F244 -+:104F2000A441FDF707FC00F4404010BD10B5FFF7A9 -+:104F3000F5FFB0F5404F14BF0020012010BDC04662 -+:104F400070B5002313700B7041F22403C35C044658 -+:104F50000D4616461BB340F2AB41FDF7EBFB10F4D8 -+:104F6000004F03D0204640F2AB410AE0204640F219 -+:104F70003C61FDF7DFFB10F4004F07D0204640F204 -+:104F80003C61FDF7D7FBC0F3470028702046FFF7D0 -+:104F9000CDFF08B194F810052B781B18337070BD45 -+:104FA0002DE9F04140F2FF340E4605469046334667 -+:104FB000224640F24561FDF7EFFB28462246434674 -+:104FC00040F24661FDF7E8FB28462246334640F2B0 -+:104FD0004761FDF7E1FB2846224643464FF4C9618D -+:104FE000FDF7DAFB28462246334640F24961FDF7D9 -+:104FF000D3FB284640F24A6122464346FDF7CCFBEC -+:10500000BDE8F08170B5002914BF4FF48073002310 -+:1050100004460D1E18BF01254FF480724FF49661AF -+:10502000FDF7BAFB0122204640F24C412B46FDF72A -+:10503000B3FB2B0320464FF496614FF4805203F4E8 -+:105040007043FDF7A9FB6B0320464FF496614FF4C4 -+:10505000005203F46043FDF79FFB6B0120229BB2DB -+:1050600020464FF49661FDF797FB6B0203F47E43F5 -+:10507000204640F2AE414FF40072FDF78DFBB4F8CC -+:10508000DA3003F47043B3F5005F11D1AB02204670 -+:105090004FF496614FF4806203F47C43FDF77CFB90 -+:1050A000EB009BB2204640F2E5410822FDF774FB7D -+:1050B00070BDC04670B50C02A4B20546234640F24E -+:1050C000FB414FF4FE42FDF767FB284640F2FD41ED -+:1050D0004FF4FE422346FDF75FFB70BD70B500291B -+:1050E00014BF802300230C1E18BF012480224FF41C -+:1050F00096610546FDF750FBA303A40128464FF433 -+:1051000096614FF4804203F44043A4B2FDF744FBA0 -+:10511000284640F23B4140222346FDF73DFB70BD4F -+:1051200070B540F239440D4621460646FDF702FBB4 -+:1051300040F67F4300EA030343EAC51330462146A5 -+:1051400040F6FF729BB2FDF727FB70BD2DE970435F -+:105150000C460646FFF7B4FE628823884FF6FF79B7 -+:1051600043EA022305464A46304640F2B5419BB227 -+:10517000FDF712FB2D02A388ADB247F6FF7830464B -+:10518000424645EA030340F2FB41FDF705FB628816 -+:105190002388304643EA022340F2FC414A469BB250 -+:1051A000FDF7FAFAA3883046424645EA030340F287 -+:1051B000FD41FDF7F1FA3046E188FFF7B1FF3046D7 -+:1051C0000121FFF78BFFBDE87083C04610B502498F -+:1051D0000C22FDF7F5FA10BD380D02002DE9F0475D -+:1051E0009846BDF82CA0BDF824308946BDF82010A3 -+:1051F0000AF00304164603F00F03BDF8282044EA22 -+:10520000032301F00F0102F0030243EA013343EAF2 -+:10521000821343EA021343EA840340F2B6414FF695 -+:10522000FF720746BDF83050FDF7B6FA0F2208EAC4 -+:105230000203384640F2B741FDF7AEFA4FEACA23FF -+:105240009CB22346384640F2B1414FF460522D03E0 -+:10525000FDF7A2FAADB2062238462049FDF7B0FAB2 -+:105260007602384640F2AE414FF470422B46FDF7CD -+:1052700093FA384640F2B1414FF4007206F47E438F -+:10528000FDF78AFAD9F1010338BF0023012238461D -+:1052900040F24D41FDF780FAB7F8DA3003F470437D -+:1052A000B3F5005F10D1384640F2B1414FF4C0521F -+:1052B0002346FDF771FA4FEACA039BB2384640F223 -+:1052C000E6411822FDF768FA384640F2AE414FF445 -+:1052D00070422B46FDF760FABDE8F087A209020094 -+:1052E00010B5044686B021B90D490E22FDF768FAC3 -+:1052F00014E00C490922FDF763FA0021032206237A -+:10530000009302920423039220460A4604910193DB -+:10531000FFF764FF20460121FFF774FE06B010BDC1 -+:10532000420702005E07020010B5D0F8A830D3F89B -+:10533000741529B1C3694FF420729868F1F3D8F459 -+:1053400010BDC0462DE9F041D0F8A8300646D3F88C -+:105350007C55D3F8787500240DE0142302FB03F389 -+:10536000EA1811695268F06902FB01F28068E95895 -+:10537000D208F1F3BDF4E2B20134BA42EDD3BDE894 -+:10538000F081C04670B5D0F8A8500446D5F87C35F9 -+:105390006BB10121FFF7D6FFE369D5F878451422F8 -+:1053A0009868D5F87C1504FB02F2F1F3A1F470BD06 -+:1053B00041F2F023C15810B5044629B1C36942F641 -+:1053C00008529868F1F394F42046FFF7ADFF2046A9 -+:1053D000FFF7D8FFE369D4F8A81098684FF4B962D2 -+:1053E000F1F386F410BDC04610B54FF48052044668 -+:1053F000002340F2C961FDF7CFF9D4F8A820B2F834 -+:10540000C234EBB192F8E933A02B04D1204640F22C -+:105410008961232203E0204640F289613022FDF7B2 -+:1054200095F9D4F8A830B3F8C234022B0ED14FF45A -+:105430008052204640F2C9611346FDF7ADF905E000 -+:10544000204640F289612322FDF780F9042220469C -+:105450002749FDF7B5F90022204640F27961FDF7B2 -+:1054600075F9082220462349FDF7AAF9D4F8A83097 -+:105470002046B3F8C2244FF4D961FDF767F906223C -+:1054800020461D49FDF79CF9D4F8A8304FF48072EE -+:10549000B3F8C23420461A41013A4FF4D06192B2B7 -+:1054A000FDF754F9D4F8A8304FF4A072B3F8C23421 -+:1054B00020461A41013A92B240F28161FDF746F965 -+:1054C000D4F8A830B3F8C224012A04D0022A14BFA9 -+:1054D0003422082200E01822204640F27F61FDF7C6 -+:1054E00035F9204605490E22FDF76AF910BDC04680 -+:1054F000440B02004C0B02002E0C02003A0C02007E -+:105500002DE9F04740F23C4631460446FDF712F9DA -+:1055100040F23B48824641462046FDF70BF94AF0EF -+:10552000010281463146204692B2FDF70FF949F05B -+:105530000102204641464FF6FE7592B2FDF706F98C -+:10554000204631460AEA0502FDF700F920464146A9 -+:1055500009EA0502FDF7FAF8204631465246FDF702 -+:10556000F5F8204641464A46FDF7F0F8BDE8F087D9 -+:10557000802270B513460C4640F2D1610546FDF716 -+:105580000BF90CB1012C05D128464FF4DA610F223A -+:10559000FDF7DCF82846FFF7B3FF70BD2DE9704337 -+:1055A0000E46B0F8DA10054601F47041B1F5005F1F -+:1055B00014BFA521892199469046FDF731F8B5F829 -+:1055C000DA10044601F47041B1F5005F14BFA52163 -+:1055D00089212846FDF724F804F00F04C0F30310D6 -+:1055E000241A3470B5F8DA10284601F47041B1F588 -+:1055F000005F14BFA6218A21FDF712F8B5F8DA1072 -+:10560000044601F47041B1F5005F14BFA6218A2160 -+:105610002846FDF705F804F00F04C0F30310241A20 -+:1056200088F80040B5F8DA10284601F47041B1F569 -+:10563000005F14BFA7218B21FCF7F2FFB5F8DA1049 -+:10564000044601F47041B1F5005F14BFA7218B211E -+:105650002846FCF7E5FF04F00F04C0F30310241AFA -+:1056600089F80040B5F8DA10284601F47041B1F528 -+:10567000005F14BFA8218C21FCF7D2FFB5F8DA1027 -+:10568000044601F470412846B1F5005F14BFA8211B -+:105690008C21FCF7C5FF04F00F04C0F30310069B38 -+:1056A000241A1C70BDE87083B0F8DA1010B501F44C -+:1056B00070410446B1F5005F14BFA52189218822FD -+:1056C000FCF7C6FFB4F8DA10204601F47041B1F5DA -+:1056D000005F14BFA6218A218822FCF7B9FFB4F825 -+:1056E000DA10204601F47041B1F5005F14BFA72124 -+:1056F0008B218822FCF7ACFFB4F8DA10204601F4C5 -+:105700007041B1F5005F14BFA8218C218822FCF7FD -+:105710009FFF10BD10B5D0F8A830044693F8E933C8 -+:10572000A02B03D110490422FDF74AF8204600229D -+:105730004FF48E71FCF78CFF204618220B49FDF7C1 -+:105740003FF841F2EE23E35A2046FF2240F2346153 -+:10575000002B08BF0C23FDF71FF82046044909223F -+:10576000FDF72EF810BDC046580D0200600D020076 -+:10577000900D020070B504220D4607490646FDF75C -+:105780001FF80024054B625BE15A30460234FCF7F7 -+:105790005FFF302CF6D170BDD60B0200D2040200A0 -+:1057A0002DE97043054698461646B0F8DA40FFF7F3 -+:1057B000DFF804F47044B4F5005F14BFA524892415 -+:1057C0000246214628469DF81890FCF741FF3146D5 -+:1057D0002846FFF7CDF8B5F8DA40024604F47044E5 -+:1057E000B4F5005F14BFA6248A2428462146FCF79E -+:1057F0002FFF41462846FFF7BBF8B5F8DA400246CE -+:1058000004F47044B4F5005F14BFA7248B24284629 -+:105810002146FCF71DFF49462846FFF7A9F8B5F8D1 -+:10582000DA40024604F47044B4F5005F14BFA824C3 -+:105830008C2428462146FCF70BFFBDE87083C04648 -+:1058400070B505460E460024074BA25BE15A284678 -+:105850000234FCF7FDFE182CF6D1284603492246F7 -+:10586000FCF7AEFF70BDC046800B0200880C020042 -+:1058700070B506220E4644490446FCF7A1FF0025F8 -+:10588000424B2046E95AFCF7CBFEA8530235182DAF -+:10589000F6D1072101222046FCF7DAFE1022FF2173 -+:1058A00013462046FCF71AFF04221346204640F216 -+:1058B0001F11FCF713FF0C2220463549FCF780FF2F -+:1058C00001223A2113462046FCF708FF04223A2120 -+:1058D00013462046FCF702FF0822134620464FF4E9 -+:1058E0008D71FCF7FBFE0822052113462046FCF7CC -+:1058F000F5FE0122134620464FF48D71FCF7EEFEB3 -+:10590000122220462349FCF75BFF20228221134606 -+:105910002046FCF7E3FEB4F8DA3003F47043B3F545 -+:10592000005F02D000252E4608E0D4F8A8309A7A0D -+:10593000D97A42F400721D7B42EA01160122204608 -+:1059400013464FF49B61FCF727FF2046B3004FF44A -+:105950009B6140F6FC72FCF71FFF022220461346B3 -+:105960004FF49B61FCF718FF2B0320464FF49B611B -+:105970004FF4E04203F47043FCF70EFF2046064963 -+:105980000622FCF71DFF70BD16080200800B020006 -+:10599000AE090200C6090200EA0902002DE9F74F2C -+:1059A000D0F8A830814693F80B809C7A1A7E1F7B32 -+:1059B0004FEA081844F4007493F817B09E7D44EA47 -+:1059C0000804009293F814A0DD7C44EA07345B7D60 -+:1059D00047F2FF38A4B2092223490193FCF7F0FEF5 -+:1059E00048464246234640F2DB41FCF7D5FE484696 -+:1059F0004246234640F2DC41FCF7CEFE4846424692 -+:105A0000234640F20A41FCF7C7FE4FEA0A1A019BFF -+:105A100045F4007545EA0A0545EA0335484642461D -+:105A2000ABB240F20B41FCF7B7FE4FEA0B1B009AFA -+:105A300046F4007646EA0B0646EA023648464246F7 -+:105A4000B3B240F20C41FCF7A7FE20224846822167 -+:105A50001346FCF743FE012248467C211346FCF71F -+:105A60003DFEBDE8FE8FC046C40B0200012970B5A3 -+:105A700005460C4616D106222949FCF7A1FE284608 -+:105A80003A2122462346FCF729FE082228461346DF -+:105A90004FF48D71FCF722FE28467F210022FCF78F -+:105AA000D7FD33E079B91F490622FCF789FE284665 -+:105AB0003A2101222346FCF711FE082228464FF422 -+:105AC0008D71134620E0022920D1B0F8DA3003F4BA -+:105AD0007043B3F5005F02D17D21032201E07D21F7 -+:105AE0002246FCF7B5FD284628210F220123FCF7AA -+:105AF000F5FD8022134628464FF48971FCF7EEFD30 -+:105B00002846052107220223FCF7E8FD284640F23B -+:105B100037614FF440420023FCF73EFE70BDC046A3 -+:105B2000AE060200560C02002DE9F047C369D0F81A -+:105B3000A8501B6D0C4613F4805F40F2234114BF44 -+:105B40004FF006094FF00909064695F844A3FCF703 -+:105B5000F1FD40F2344107463046FCF7EBFD2046AC -+:105B6000FEF7E6FF95F84433C1B2B5F8642395F823 -+:105B700048030BB9012092E007F0FF07C0EB0103D7 -+:105B8000C2EB07029B1A5FFA83F84FFA88F4002CE5 -+:105B90001DDAF36930461B6D03F48053002B0CBFF4 -+:105BA0000B21042114BF0322082263429A42A8BF9A -+:105BB0001A46B5F8683301FB02324FF4AA6192B27B -+:105BC000FCF7C4FD14F1030F06DAFB1C05E0032CFF -+:105BD00002DDFB1E9BB200E0BBB2B5F8640319B254 -+:105BE00002B2D31C994201DDC31C03E09142ACBF59 -+:105BF0000B4613469CB2BAF1000F13D023B2BB423E -+:105C000010D02346304640F22341FF22FCF7C4FD6A -+:105C1000304624490422FCF7D3FD1420F0F39CF510 -+:105C2000002700E00127B5F866434FFA88F220B25A -+:105C3000C9EB000352429A42B8BFC9EB040391B2C8 -+:105C4000B8BF99B20AB200F109039A42C4BF04F185 -+:105C5000090399B2B6F8DA3003F47043B3F5005F84 -+:105C60000CBF95F94B3395F94C335B189BB2BAF1E5 -+:105C7000000F05D0304640F23441FF22FCF78CFD86 -+:105C8000304640F22341FCF755FD95F8BC33C0B2D5 -+:105C900085F8BD0385F8BE0385F8BF333846BDE8F7 -+:105CA000F087C0465C0B020070B5D0F8A8500446DF -+:105CB000FF22B5F8663340F23441FCF76DFDB5F8CC -+:105CC00064332046FF2240F22341FCF765FD204665 -+:105CD000B5F868234FF4AA61FCF738FD2046044963 -+:105CE0000422FCF76DFD1420F0F336F570BDC046BC -+:105CF0008A050200082270B5134605465721FCF7B5 -+:105D0000EDFC56212846FCF78BFC00F0F8045621E8 -+:105D100022462846FCF79CFC0120F0F31DF5562195 -+:105D200044F003022846FCF793FC0120F0F314F53D -+:105D3000562144F007022846FCF78AFC4FF496707F -+:105D4000F0F30AF52846572108220023FCF7C6FC89 -+:105D500070BDC0462DE9F04140F24A4631468046CA -+:105D6000FCF7E8FC40F04404A4B24FF6BF7540468F -+:105D70003146224604EA0505FCF7E8FC31462A468E -+:105D80004046FCF7E3FC25F004050420F0F3E4F4BE -+:105D9000404631462A46FCF7D9FCBDE8F081C046B2 -+:105DA0002DE9F04706460C461546384906221F469F -+:105DB000DDF82090BDF82480FCF702FD304640F26B -+:105DC00082414FF6FF722346FCF7E6FC304640F274 -+:105DD0008141FF222B46FCF7DFFC3FB9304640F201 -+:105DE00081414FF480723B46FCF7D6FC304628498F -+:105DF0000322FCF7E5FC0A2308FB03F5002407E077 -+:105E0000AC4201DD002439E06420F0F3A5F4013454 -+:105E1000304640F28141FCF78DFC10F4007FEFD159 -+:105E200040F283413046FCF785FC40F28441044651 -+:105E30003046FCF77FFC40EA0440C9F8000040F21D -+:105E400085413046FCF776FC40F2864104463046F8 -+:105E5000FCF770FC40EA0440C9F8040040F28741B6 -+:105E60003046FCF767FC4FF4916104463046FCF77E -+:105E700061FC40EA0440C9F80800012430460549A5 -+:105E80000622FCF79DFC2046BDE8F087980702003B -+:105E9000F40502002A06020070B50546002407E05A -+:105EA0006420F0F359F4013441F289339C4207D065 -+:105EB000284640F25141FCF73DFC10F4404FEFD131 -+:105EC000284640F25141FCF735FC10F4404F14BF16 -+:105ED0000020012070BDC04610B540F24C414FF685 -+:105EE000FC72FCF73BFC10BDC36970B504460D465F -+:105EF00018698E2116463AF0FDDBE3694119490025 -+:105F0000186932463AF014DC70BDC046C36970B5FA -+:105F100004460D4618698E213AF0ECDBE36941191D -+:105F2000490018693AF0E6DB70BDC0462DE9F04142 -+:105F30000C46272180461646FFF7E8FF10F00103C4 -+:105F400002D101271D4605E04FF6F07500EA050570 -+:105F50004FF6F07728214046FFF7D8FF3840A84297 -+:105F600001D1012009E0013C631C002B02DD14205B -+:105F7000F0F3F2F3002CEDDC002006B13460BDE854 -+:105F8000F081C0462DE9F0410646D0F8A850FEF752 -+:105F9000C5FFB0F5404F46D1F369E02118693AF0EA -+:105FA000A9DBEC8D8046C4EB000440F2A5413046ED -+:105FB000FCF7C0FB0123C0F30227BB40A4B29C4204 -+:105FC00031DD95F8C134A5F82E80BB4208D90137E0 -+:105FD000304640F2A5414FF4E0623B02FCF7DCFBA7 -+:105FE0003046FEF775FF40B280B22886B6F8DA3048 -+:105FF0006F8603F47043B3F5005F0CBF85F854045B -+:1060000085F85504D6F8A8202B8E92F966255B00FA -+:10601000013293FBF2F3304640F2A44140F2FF120A -+:106020009BB2FCF7B9FBBDE8F081C0462DE9F04F0B -+:10603000044685B00D46D0F8A860FFF7A3FFD4F85A -+:10604000B030D3F8203183F0010313F00103039340 -+:1060500003D1E36918693AF09DDB07212046FCF77C -+:10606000DFFAFF2101902046FCF7DAFA40F21F1117 -+:1060700002902046FCF7D4FA40F23B41834620468A -+:10608000FCF758FB40F23C4182462046FCF752FBAD -+:1060900040F2D74181462046FCF74CFB4FF49B6110 -+:1060A00080462046FCF746FB0F224649074620461D -+:1060B000FCF786FB0122072113462046FCF70EFB66 -+:1060C0001022FF2113462046FCF708FB042213464A -+:1060D00040F21F112046FCF701FB0A20F0F33CF3CD -+:1060E000202220464FF49A611346FCF755FB0A2004 -+:1060F000F0F332F3012D21D140F276412046FCF736 -+:1061000019FB40F27741C5052046FCF713FBC0059B -+:10611000C00DED0DFF288ABFA0F5007302469AB2AC -+:10612000FF2D88BFA5F50073A6F86E058CBF98B249 -+:106130002846C0EB0203A6F86C550AE0204640F260 -+:106140007541FCF7F7FAC005C00DFF2803D9A0F58B -+:1061500000739DB200E00546019B2046DAB207219C -+:10616000FCF776FA029B2046DAB2FF21FCF770FAC0 -+:10617000204640F21F115FFA8BF2FCF769FA2046C5 -+:1061800040F23B415246FCF7E1FA204640F23C41E6 -+:106190004A46FCF7DBFA204640F2D7414246FCF77C -+:1061A000D5FA20464FF49B613A46FCF7CFFA039BA1 -+:1061B0001BB9E36918693AF0D9DA28B205B0BDE82D -+:1061C000F08FC046F807020070B5D0F8A83001295A -+:1061D000D3F8DC63D3F8D853D3F8E04304D10131CA -+:1061E000FFF724FF02B20AE040F27541FCF7A2FA81 -+:1061F000C005C00DFF288CBFA0F500720246631FCA -+:1062000001209840801905FB1200231F184140B25D -+:1062100070BDC04610B50129D0F8A83003D1FFF7F2 -+:1062200005FF00B212E0B3F86C25B3F86E35FF2B12 -+:1062300086BFA3F5007399B21946FF2A86BFA2F55F -+:1062400000739BB21346C3EB010318B210BDC046E6 -+:1062500070B5D0F8A830D3F8D443D3F8D053D3F8DE -+:10626000CC63FFF7D7FF621E0123934000B25B1996 -+:1062700006FB1030204140B270BDC0462DE9F04110 -+:10628000B0F8DA20074602F47043B3F5005FD0F8A7 -+:10629000A85004D1B5F85463B5F8844513E0D3B2DF -+:1062A000942B03D9B5F88645022308E0632B03D964 -+:1062B000B5F88845012302E0B5F88A45002305EBCF -+:1062C0004303B3F85663FF2E1ED001213846FFF773 -+:1062D000BFFF40B2193804FB00F000B20028CCBF69 -+:1062E00000F5FA73A0F5FA734FF47A7293FBF2F3A8 -+:1062F00098B28419A4B2384640F23441FF222346B2 -+:10630000FCF74AFAA5F86643BDE8F08170B505468A -+:10631000D0F8A8600C4689B340F2DA6142F2080274 -+:10632000FCF72AFA284640F2A6510522FCF70EFA9D -+:10633000284640F2A251C322FCF708FA284640F250 -+:10634000A5510722FCF702FA284640F283514FF488 -+:106350004872FCF7FBF9284640F284510022FCF712 -+:10636000F5F9284640F285514FF40072FCF7EEF93A -+:10637000284640F286510022FCF7E8F928462721FA -+:10638000FFF7C4FD1CB140F001039CB203E04FF6DF -+:10639000FE7400EA040496F894332846F31893F840 -+:1063A0009523052302FB03F22621042A98BF1A46EF -+:1063B000FFF79AFD04F110022846272192B2FFF759 -+:1063C00093FD70BD70B5D0F8A850044695F84233DF -+:1063D0005BB10021FFF79AFF204619210022FFF749 -+:1063E000A5FD10B9012385F8453370BD70B5D0F80F -+:1063F000A840054694F8423393B990F8E93013F079 -+:10640000010F1CBF23F0010380F8E93090F8E93058 -+:1064100013F0020F2DD023F0020380F8E93028E0BA -+:1064200094F847330BB1012303E0D1F1010338BFE6 -+:10643000002384F84733E1B100230126C4F86C330C -+:1064400084F8453384F846632846FFF7BBFF94F889 -+:106450004333003B18BF012384F8443313B128466B -+:10646000FFF722FC2846FEF79FFB28463146FFF740 -+:106470004DFF70BD70B5D0F8A83000260C4683F8EB -+:10648000466331460546FFF741FF14B12846FFF742 -+:106490000BFC03222846134640F67A01FCF77CF9F0 -+:1064A000284640F2DA6142F208023346FCF774F9FA -+:1064B00070BDC04670B50546D0F8A84016467AB102 -+:1064C00094F8433394F842438C2144EA4304C3696B -+:1064D000146018693AF00ED944EA004434600FE0C1 -+:1064E000CB080DD101F0010384F84233C1F340031E -+:1064F00084F8433394F8423313B90121FFF7BAFF0C -+:1065000070BDC04610B500210446FFF7B3FF20461A -+:10651000FEF74AFB10BDC04610B50122044640F606 -+:106520000501FCF729F920460722052340F22F41F7 -+:10653000FCF732F920463021F8234FF4FF62FCF7D4 -+:106540002BF90623204630210722FCF725F92046A7 -+:1065500040F2144141F61062FCF7F8F8204640F290 -+:1065600015414FF4C862FCF7F1F8204640F2DF41D4 -+:106570004FF47F424FF47743FCF70EF92046FFF7C4 -+:10658000E9FB204602492D22FCF71AF910BDC0464E -+:10659000680E0200002914BF0223002310B5002A50 -+:1065A00018BF43F001030446032240F24D41FCF7BB -+:1065B000F3F8204640F24C410322FCF7DDF810BD11 -+:1065C00010B5044611B91049132219E012220F49DF -+:1065D000FCF7F6F8012100222046FFF7DBFF2046FA -+:1065E0000B490622FCF7ECF8B4F8DA3003F47043F8 -+:1065F000B3F5005F07BF20460649204606491E2224 -+:10660000FCF7DEF810BDC04692080200B808020090 -+:10661000DC080200660A0200E80802002DE9F041E9 -+:1066200004460D46164640F2DA6148F280021F46E3 -+:106630009DF81880FCF7A0F82046FEF7B7F9B8B12E -+:1066400040F652112046FCF775F8FF22C3B240F61F -+:1066500048112046FCF7A0F840F653112046FCF7FD -+:1066600069F840F64911C3B2FF222046FCF794F8BE -+:10667000D4F8A83093F8463573B140F2EB41204688 -+:10668000FCF758F8C0F3402340F2EB4120464FF4AA -+:1066900080629B02FCF780F86B1EFF22204640F2CE -+:1066A00042619BB24FF6FF75FCF776F8AE4201D01F -+:1066B000731E9EB220464FF4C8612A463346FCF74B -+:1066C0006BF8204640F241612A463B46FCF764F8ED -+:1066D000B8F1000F05D0204608490422FCF770F8F5 -+:1066E00009E0204640F23F610122FCF72FF82046E6 -+:1066F0000121FFF765FFBDE8F081C046DE0B020017 -+:106700002DE9F0410C4640F23B410546FCF712F8FA -+:1067100040F23C4107462846FCF70CF8064674B1A7 -+:106720000E2228460F49FCF74BF828460121FFF7B7 -+:1067300047FF28460C490722FCF742F810E028469C -+:106740000A490422FCF73CF8284640F23B413A460D -+:10675000FBF7FCFF284640F23C413246FBF7F6FFD0 -+:10676000BDE8F08186090200980B0200500D02007E -+:106770002DE9F04F0546C5B001910092FDF79AFC56 -+:10678000EB694FF0805118690A4639F093DF052014 -+:10679000EFF3E2F7002328464FF489614FF480427B -+:1067A000FBF7FAFF284640F255414FF4A842FBF7A9 -+:1067B000CDFF284640F25641FBF7BCFF00F00F002A -+:1067C000052809D14FF4A842284640F25541FBF76D -+:1067D000BDFF4FF4807207E045F20142284640F2C7 -+:1067E0005541FBF7B3FFFE22803A521022EAE272D3 -+:1067F000102AA8BF10225100002301F18006C2EB2D -+:10680000060B1F46994698469A464393429340E0AA -+:1068100040F256412846FBF78DFF40F25741C0F346 -+:106820000B142846FBF786FF5E4544EA003021DC66 -+:10683000BAF17F0F1EDC8104890CB1F5005FC8BF7F -+:10684000A1F5804101F50063B3F5805F23D802AB69 -+:1068500023F8191044AB03EB880252F8083C0AF104 -+:10686000010ACB1842F8083C08EB090383F0400901 -+:1068700088F00108C0F3033303F00C0343EA071365 -+:1068800016F0010F9FB203D007F0FF03402B02D197 -+:10689000013E002EBCDCEB69002218694FF08051EC -+:1068A00039F008DF2846FDF7FFFB429B9B1142931E -+:1068B000439B9B11BAF1800F43931DD0002022E02F -+:1068C00041EA801202AB33F9123001315B1B4029DF -+:1068D00003FB0344F4D1013002280FD1009AA3092D -+:1068E0001460019A1360A3F53A63084A183B934277 -+:1068F0008CBF0020012006E00020044642AB53F884 -+:1069000020500021DCE745B0BDE8F08F48F4FF0FD0 -+:1069100070B504460D46FDF7CDFB20226B012046E5 -+:106920004FF49661FBF738FF0023204640F2B14157 -+:106930004FF40072FBF730FFB4F8DA3003F4704321 -+:10694000B3F5005F02D04FF0000E04E0D5F1010E68 -+:1069500038BF4FF0000E002D0CBF2023002343EA68 -+:106960008E13204660224FF48261FBF715FF20460C -+:106970004FF482618022EB01FBF70EFF2046FDF70A -+:1069800093FB70BD2DE9F047044688461746D0F8C2 -+:10699000A890FCF78DFB20460121FFF7B9FF0025E9 -+:1069A0002E460CE0012100222046FDF78BFA3846E6 -+:1069B000EFF3D2F62046FEF78BFA40B285B2F3B27F -+:1069C00001364345EED320460021FFF7A1FF89F8A9 -+:1069D000C052BDE8F087C04670B505460846FEF7D0 -+:1069E000A7F8EB69A02144B2186939F083DE9D3C19 -+:1069F000A4B26FF0610324B29C42B8BF1C46C1B27E -+:106A000062B22846FCF770FD70BDC04673B5D0F881 -+:106A1000A840064694F84233002B00F0DC8094F83E -+:106A20004633002B00F0D780D0F8B030D3F82031B7 -+:106A300013F0010F00F0CF8000230093019394F82E -+:106A40004553002D40F0AA8029462A46FFF76EFAEA -+:106A5000002800F0A380304601A96A46FFF788FEAF -+:106A6000002800F09B80009BC4F86C3394F84633F8 -+:106A7000012B40F0938094F891030199AC46AE4607 -+:106A80001FE045B204EB8502D2F87033994201D37E -+:106A9000002203E0C2F870131946012204EB8503BB -+:106AA000D3F870339C440EF101035FFA83FE431C5C -+:106AB000D8B243B2072BC8BF002012B1019101998F -+:106AC00019E094F990334FFA8EF29A42D9DBF5E748 -+:106AD00043B204EB8303D3F87023C3F87013431C51 -+:106AE000D8B243B2072BC8BF00200EF101038C447B -+:106AF0005FFA83FE11464FFA8EF3072BE8DD019112 -+:106B000094F8902353B2072B05DC002384F89233CA -+:106B1000531C84F8903394F99033082B3ED194F8A9 -+:106B20009433E31893F8972393F8995394F8923396 -+:106B3000FC2B02D8013384F8923394F892339342B9 -+:106B40002CD194F89133013384F891335BB2072B45 -+:106B500002DD002384F8913394F890333046023BF1 -+:106B600084F890336146FEF7DFFF18B93046FEF730 -+:106B70001BF810E094F89333FC2B02D8013384F80F -+:106B8000933394F89333AB4205D194F8943313B90B -+:106B9000013384F89433002384F8923394F8461335 -+:106BA0000023012984F8453303D13046FFF7AEFBBB -+:106BB00003E030461946FFF75DFC3046D4F86C130D -+:106BC000FFF70AFF002384F8473394F89C3313B986 -+:106BD000013384F89C337CBD2DE9F04F0746D0F893 -+:106BE000A800E1B00B9041F22403FB5C0C46002BA3 -+:106BF00000F09C82FB696A21186939F07BDD400056 -+:106C00001FFA80FBBBF1000F00F090823846FEF7C0 -+:106C100085F9FB69024610B91869594684E218697A -+:106C2000594639F067DD012800F080820BF1060338 -+:106C30009BB20C930BF13A039BB20D930BF16E03D5 -+:106C40009BB20E930BF1AA039BB20F93002C00F0A2 -+:106C50005A82384640F2F941FBF76CFD10F0080FFC -+:106C600040F064824CAD38ACAB1C0193A31C039381 -+:106C70003846002340F2764140F2FF12009502941C -+:106C8000FBF7D4FD2B1D0093AB1D0193231D029335 -+:106C9000A31D03933846002340F2774140F2FF12D0 -+:106CA000FBF7C4FD05F10803009305F10A03019306 -+:106CB00004F10803029304F10A030393384640F2F7 -+:106CC000AA4148F2FF1248F27F03FBF7AFFD05F13E -+:106CD0000C03009305F10E03019304F10C0316223B -+:106CE000029304F10E0303933846134640F23B41EE -+:106CF000FBF79CFD05F11003009305F112030193CE -+:106D000004F11003029304F1120346220393384660 -+:106D1000002340F23C41FBF789FDB7F8DA3005F17A -+:106D2000140E03F47043B3F5005F05F11C030A93DE -+:106D300005F11E03099304F11C03089304F11E03DB -+:106D4000079305F12003069304F1200305F11602D1 -+:106D500004F1140104F1160005F1180605F11A08F2 -+:106D600004F1180904F11A0A05F12205059304F14A -+:106D7000220437D1019241F22B0213460291039073 -+:106D800040F24C413846CDF800E0FBF74FFD384665 -+:106D900040F24D4144F22B0244F20A030096CDF832 -+:106DA0000480CDF80890CDF80CA0FBF73FFD089AC1 -+:106DB0000A980999079B0292072200900191039378 -+:106DC0003846134640F2F941FBF730FD0698059925 -+:106DD000072200900291384640F2FA41134601958D -+:106DE000039436E0019241F22B0213460291039084 -+:106DF00040F24C413846CDF800E0FBF717FD38462D -+:106E000040F24D4144F22B0244F222030096CDF8A9 -+:106E10000480CDF80890CDF80CA0FBF707FD0A9A86 -+:106E2000099B089807990092072201930290134644 -+:106E30000391384640F2F941FBF7F8FC069A059BAE -+:106E40000092029301950394384640F2FA410722DA -+:106E5000002324ACFBF7EAFCA31C019310AB012236 -+:106E600002930DF142030721039338461346009421 -+:106E7000FBF748FC231D0093A31D019311AB1022C7 -+:106E800002930DF14603FF21039338461346FBF7A7 -+:106E900039FC04F10803009304F10A03019312ABD7 -+:106EA000042202930DF14A034CAE03933846134675 -+:106EB00040F21F11FBF726FC06F1240338AD0093C6 -+:106EC00006F12603019305F1240340F644020293E0 -+:106ED00005F1260303933846134640F63811FBF7B5 -+:106EE000A5FC06F12803009306F12A03019305F19E -+:106EF0002803029305F12A030393384640F639111B -+:106F000040F6440240F60403FBF790FC04F10C0346 -+:106F1000009304F10E03019313AB012202930DF1D0 -+:106F20004E033A21039338461346FBF7EBFB04F17B -+:106F30001003009304F11203019314AB082202938F -+:106F40000DF152030393384613464FF48D71FBF74E -+:106F5000D9FB04F11403009304F11603019315AB5C -+:106F6000082202930DF15603052103933846134678 -+:106F7000FBF7C8FB04F11803009304F11A03019313 -+:106F800016AB042202930DF15A033A2103933846BB -+:106F90001346FBF7B7FB04F11C03009304F11E0337 -+:106FA000019317AB012202930DF15E030393384660 -+:106FB00013464FF48D71FBF7A5FB06F12C030093EC -+:106FC00006F12E03019305F12C03029305F12E0324 -+:106FD0000393384640F2D74147F2CB0242F24B03CB -+:106FE000FBF724FC04F12003009318AB202202934A -+:106FF0000DF1620382212234039338461346019433 -+:10700000FBF780FB0B98037B827AC17A1B0342F467 -+:10701000007242EA011243F0030343EA820306F1DD -+:107020003002009205F13002323602923235384693 -+:107030004FF49B6147F6FF729BB201960395FBF7F5 -+:10704000F5FBDDF83090DDF834800026FB694CACB0 -+:10705000325B1869494639F06BDBFB6938AD725B0E -+:107060001869414639F064DBFB69A419186909F114 -+:107070000201628839F05CDBFB69AD1908F102019D -+:1070800018696A88043639F053DB342E09F1040993 -+:1070900008F10408DAD1DDF83890DDF83C800026EC -+:1070A000FB6924AC325B1869494639F041DBFB6966 -+:1070B00010AD725B1869414639F03ADBFB69A419DF -+:1070C000186909F10201628839F032DBFB69AD19F8 -+:1070D00008F1020118696A88043639F029DB242E88 -+:1070E00009F1040908F10408DAD1FB690BF1020186 -+:1070F00018690D2239F01CDBFB690BF104011869DA -+:10710000092239F015DBFB690B991A6A18690B9B88 -+:10711000C1F83824B3F83C240BF1E60139F008DB60 -+:10712000FB6959461869012239F002DB61B0BDE8FC -+:10713000F08FC0462DE9F04F8DB007460F220E4666 -+:107140000DF12100B249EAF317F7D7F8A880002221 -+:10715000B04D14016359B34203D001320E2AF7D166 -+:1071600075E3384691210022FBF772FA3846382140 -+:107170000722FBF76DFA0A2238468821FBF768FAE6 -+:10718000D7F8A83093F882251AB138468821FBF742 -+:107190005FFA64192A213846227AFBF759FA30211E -+:1071A00003223846637AFBF799FA91210322384685 -+:1071B000A37AFBF793FAE37A38210F223846FBF7DC -+:1071C0008DFA912100223846FBF742FA3821072236 -+:1071D0003846FBF73DFA237B30210C229B003846D2 -+:1071E000FBF77CFA5E210F223846637BFBF776FAC9 -+:1071F000A37B5E211B01F0223846FBF76FFA6C215E -+:107200003846E27BFBF724FA384638210822FBF7A0 -+:107210001FFA384691210322FBF71AFA0CA98B19A1 -+:1072200013F8102C38465E21FBF712FA012238467B -+:107230007E21FBF70DFA98F8EE231AB13846382173 -+:10724000FBF706FA0722134638462A21FBF746FACF -+:1072500038462C210022FBF7FBF938462A210C2264 -+:10726000FBF7F6F9012238462C21FBF7F1F9D7F8A4 -+:10727000A82092F852352BB338465E2192F8532558 -+:10728000FBF7E6F9D7F8A830384693F854252A21B9 -+:10729000FBF7DEF9D7F8A830384693F855252B21AF -+:1072A000FBF7D6F9D7F8A830384693F856252C21A5 -+:1072B000FBF7CEF9D7F8A83038462D2193F857259B -+:1072C000FBF7C6F9B7F8DA3003F47043B3F5805F23 -+:1072D00004D13846BF21EE22FBF7BAF90222134649 -+:1072E000384640F21F11FBF7F9F90422F721134643 -+:1072F0003846FBF7F3F9F121032200233846FBF768 -+:10730000EDF9F221F82290233846FBF7E7F9A223A2 -+:10731000F321FF223846FBF7E1F9B7F8DA3003F43E -+:107320007043B3F5005F04D1D7F8A83093F818354F -+:1073300006E0B3F5805F06D1D7F8A83093F8193589 -+:10734000012B00F07B82042238469D210023FBF7AD -+:10735000C5F90022079244213846FBF761F940F253 -+:107360002B1101903846FBF75BF94421029007226C -+:107370003846FBF7A5F9384640F22B110E22FBF7F1 -+:107380009FF941F2080357F803A0079B0BB9554634 -+:1073900001E04FEA4A05204B9A4502D84FF0010917 -+:1073A00006E01E4B9A4594BF4FF002094FF00409C6 -+:1073B000B7F8DA3003F47043B3F5005F03D000216F -+:1073C0000591069106E06268032302FB03F2059231 -+:1073D0006A000692124C102221465046FDF7BAF977 -+:1073E000102221462846FDF7B5F91022049009FB2A -+:1073F00004F15046FDF7AEF9B7F8DA30039003F424 -+:107400007043B3F5005F0DD04FF0000B10E0C046A5 -+:10741000C80602001424020080BA8C01007519030A -+:1074200040420F00059802211022FDF793F9834690 -+:107430004F2102223846FBF70BF9CD4B4FEACA0524 -+:1074400009FB03F3B5FBF3F301335B08013B5FFA80 -+:1074500083F85221072238464FEA9803FBF73EF99A -+:1074600008F101065321602238464FEA4813FBF722 -+:1074700035F909FB06F3BF4CB5FBF3F5BE4B2C19F0 -+:10748000B4FBF3F4013CE4B2512122463846FBF749 -+:10749000DFF8039B10221D0158462946FDF75AF9D3 -+:1074A000013406FB04F600FB06F000280BDB58460F -+:1074B00029461022FDF74EF900FB06F0C0130130FB -+:1074C0004010441E0EE0584629461022FDF742F9AE -+:1074D0006FEA080303FB04F300FB03F0C013013061 -+:1074E0006FEA6004C4F3072353210F223846FBF7E9 -+:1074F000F5F85421E2B23846FBF7AAF806999F4BFB -+:107500000A22B1FBF3F30599384601FB02F2B2FB04 -+:10751000F3F803FB1822590802F0010401EB0454AC -+:107520005208B4FBF3F49B0803EB0253B3FBF1F3F3 -+:10753000E41845211F22C8F30713FBF7CFF84FEAE1 -+:107540000813462138464FF4F87203F0F003FBF7B6 -+:10755000C5F8C4F3074346210F223846FBF7BEF8AF -+:107560004721C4F307223846FBF772F84821E2B2FC -+:107570003846FBF76DF8079A41F29416002A08BFC7 -+:107580004FF4FA56A6F5D8760CBF4FF482794FF433 -+:10759000E1794FF4F572033E96FBF2F606FB02F535 -+:1075A00005F52A754FF425636D02B5FBF3F540F23E -+:1075B0007C6405FB04F4A4F55834A4F5C064B4FB62 -+:1075C000F2F4640AC4F3820242EAC6023846422157 -+:1075D00092B2A4B2FBF73CF804F0030204F01F04DB -+:1075E00044EA421238464321FBF732F84FEA492475 -+:1075F0004FF48773B4FBF3F404FB05F4604B640AA7 -+:10760000604AB3FBF4F39A184FF41243B2FBF3F25F -+:107610005D4B02F00F02B3FBF4F3A3F54C23A3F58B -+:1076200000631B0C42EA03123846402192B2FBF77A -+:107630000FF84FF02552554BB2FBF4F2B3FBF4F3C5 -+:10764000A2F546324FF4B841A2F50072A3F56E33AD -+:10765000B2FBF1F2A3F50073B3FBF1F302F00F02FA -+:1076600042EA03123846412192B20BF17444FAF710 -+:10767000EFFF04F590044FF4966394FBF3F4292391 -+:1076800004FB03F44FF45C7308FB03F840F22B5344 -+:1076900006FB03F606F5E46109FB08F00C31102245 -+:1076A000FDF758F804F5D81400EB640090FBF4F0F3 -+:1076B000C0B23C2894BF0025012515B14308043B06 -+:1076C00000E0031FDCB23C213F2223463846FBF793 -+:1076D00005F8AB013C2140223846FAF7FFFFB7F826 -+:1076E000DA3004F1040603F47043B3F5005F05F1EA -+:1076F000010404D1D7F8A83093F8273506E0B3F594 -+:10770000805F19D1D7F8A83093F82835012B13D111 -+:10771000049B40F245105946102203FB00F0FDF790 -+:1077200019F804FB06F39E2100FB03F4C02238463F -+:107730004023FAF7D3FF0BE00499962001FB00F0F9 -+:1077400010225946FDF706F804FB06F300FB03F48C -+:10775000B4F5160FD4BF002501256B1C032203FBD3 -+:1077600002F394FBF3F0B0F5003F11D5002315E0D0 -+:10777000404B4C003F420F0040420F00A0860100EA -+:10778000000068600021F6FF000084A30000302A9A -+:10779000A0F5C033DB130133C3F347033D213F2280 -+:1077A0003846FAF79BFFAB013D2140223846FAF7F5 -+:1077B00095FF284B9A4504D9202238465721134675 -+:1077C00003E03846572120220023FAF787FF224B97 -+:1077D0009A4504D9102238465721134603E038460B -+:1077E000572110220023FAF779FF049AB2F5341FCB -+:1077F00005DD38464A210222FAF762FF04E03846E6 -+:107800004A21FD22FAF74EFF0C2244211346384646 -+:10781000FAF764FF0120EEF39FF73846FEF76AFAA5 -+:10782000019B38464421DAB2FAF712FF029B384630 -+:1078300040F22B11DAB2FAF70BFF08E004229D2187 -+:1078400038461346FAF74AFF0121079183E50DB048 -+:10785000BDE8F08F80BA8C010075190341F208036E -+:107860002DE9F047C4588A4B4FF48475B4FBF3F408 -+:1078700004FB05F41A235721B4FBF3F40646FAF788 -+:10788000CFFE172181463046FAF7CAFE182130464E -+:10789000FAF7C6FE40F20511FB2207463046FAF71A -+:1078A00001FF304604214022FAF70AFF30464FF428 -+:1078B00090711022FAF704FF304657210222FAF79E -+:1078C000FFFE304640F205110422FAF7F9FE304679 -+:1078D0004FF483712A22FAF7BBFEA4B2304640F27D -+:1078E00007116E22FAF7B4FEE2B230462946FAF7E3 -+:1078F000AFFEC4F30422304640F20911FAF7A8FEA5 -+:10790000304640F20511FD22FAF7CCFE30464FF426 -+:1079100083710122FAF7D4FE3220EEF31DF75D4C9D -+:1079200003E00A20EEF318F70A3C30464FF4857165 -+:10793000FAF776FE10F0010F01D1092CF1D1304693 -+:107940004FF48571FAF76CFE10F0010F08D1FAB20E -+:1079500030461821FAF7B4FE4FF00B0847460CE00A -+:10796000304640F20F11FAF75BFE00F01F071D2FA3 -+:107970008CBF4FF00B0807F1020819213046FAF7C7 -+:107980004FFE4FF48371FE2205463046FAF78AFE19 -+:10799000304640F20511FB22FAF784FE304640F2F1 -+:1079A00005110422FAF78CFE304640F2051102223E -+:1079B000FAF786FE30464FF483710122FAF780FE13 -+:1079C0003220EEF3C9F6334C03E00A20EEF3C4F69E -+:1079D0000A3C30464FF48571FAF722FE10F0010F91 -+:1079E00001D1092CF1D130464FF48571FAF718FE18 -+:1079F00010F0010F06D1EAB230461921FAF728FE3D -+:107A0000092506E030464FF48871FAF709FE00F0C8 -+:107A10001F053046FE224FF483716C01FAF742FED7 -+:107A200044EA85243046FB2240F20511FAF73AFE7B -+:107A30002C43304657215FFA89F2FAF709FE3046A7 -+:107A4000224640F63311FAF781FE2246BC02304648 -+:107A500044EA471440F63411FAF778FE304645EA16 -+:107A6000040240F63511FAF771FE304644EA070287 -+:107A700040F63611FAF76AFE48EA4812D205304657 -+:107A800040F63711D20DFAF761FEBDE8F087C04627 -+:107A900040420F008996980070B55B210446FD2294 -+:107AA000FAF700FE204604214022FAF709FE20469C -+:107AB0004FF490711022FAF703FE204678218022BD -+:107AC000FAF7FEFD204640F229110222FAF7F8FDEE -+:107AD000204657210122FAF7F3FD20465B210222BE -+:107AE000FAF7EEFD41F28830EEF336F6154D03E07D -+:107AF0000A20EEF331F60A3D5C212046FAF790FDAC -+:107B000010F0200F01D1092DF2D15C212046FAF7A7 -+:107B100087FD10F0200F03D020465C21FAF780FD8E -+:107B200020465B21FD22FAF7BDFD20465721FE22AB -+:107B3000FAF7B8FD204640F22911FD22FAF7B2FD0E -+:107B400070BDC0468996980070B504460E46002563 -+:107B50006E4B2046E95AFAF763FDA8530235302DE3 -+:107B6000F6D1182220466A49FAF72AFE3A21FB226A -+:107B70002046FAF797FD012220464FF48D71FAF75F -+:107B80009FFD362101222046FAF79AFD10224FF47C -+:107B90008D712046FAF794FD1420EEF3DDF53A21BD -+:107BA00001222046FAF78CFD1420EEF3D5F5B4F847 -+:107BB000DA3003F47043B3F5005F03D120463A2175 -+:107BC000012208E020463A2101220023FAF786FD2F -+:107BD0002046CA2104221346FAF780FD08222046D7 -+:107BE0004FF48D71FAF76CFD25210E222046FAF72D -+:107BF0002FFD252101222046FAF762FDB4F8DA3084 -+:107C000003F47043B3F5805F04D1204628211E227F -+:107C1000082303E0204628211E220C23FAF75EFDEC -+:107C20001420EEF399F5052108222046FAF710FDFD -+:107C300080224FF489712046FAF742FD1420EEF3BA -+:107C40008BF5FF2110222046FAF73AFD442240F23C -+:107C50001F112046FAF734FD1420EEF37DF50B21B9 -+:107C600007222046FAF72CFD102240F2131120467D -+:107C7000FAF726FD1420EEF36FF5072101222046C6 -+:107C8000FAF7E6FC1420EEF367F502230322204600 -+:107C9000FC21FAF723FDFD212046A622FAF7D8FCA5 -+:107CA000442240F21F112046FAF70AFD1420EEF399 -+:107CB00053F5FF2110222046FAF702FD1420EEF3BF -+:107CC0004BF5B4F8DA3003F47043B3F5805F03D1B9 -+:107CD00010492046082202E00F4920460622FAF702 -+:107CE0006FFD20465921CC22FAF7B2FC20465C21D8 -+:107CF0002E22FAF7ADFC20467821D722FAF7A8FC0D -+:107D0000204692211522FAF7A3FC70BDD20402008E -+:107D1000360A0200040B0200140B02002DE9F04F9A -+:107D200004468BB0894609B98B4608E040F2D7413A -+:107D3000FAF700FD01A983462046FDF799FD2022B0 -+:107D400013464FF49A612046FAF726FD6420EEF3BD -+:107D500003F540F276412046FAF7ECFC40F2A641EA -+:107D600080462046FAF7E6FC09A9824608AA204682 -+:107D700007ABFBF7B5F9099F089E079DB9F1000F06 -+:107D800009D0204601A9FDF75BFD204640F2D7410E -+:107D90005A46FAF7DBFC4FEAC850C00D4FEACA5307 -+:107DA00080F48070DB0D00F5FE70033083F4807387 -+:107DB000C01A8010394632462B46FCF7EBFC4000D7 -+:107DC0000BB0BDE8F08FC046F0B5D0F8A85085B034 -+:107DD00095F858340646002B7BD00023019302937C -+:107DE0000393FDF775F8C7B20FB17F2F71D101ABC7 -+:107DF00002AA304603A9FBF773F940F23E61304610 -+:107E0000FAF798FC40F2A641C4053046FAF792FC16 -+:107E1000C005C00DE40DFF288ABFA0F5807300F5F2 -+:107E200080729AB2FF2C84BFA4F5807398B2C2F519 -+:107E3000FE7398BF04F5807003331B18C3F38F00E3 -+:107E4000C7B995F856340133DBB2042B85F85634A4 -+:107E50003FD985F85674029A019B0399FCF79AFC66 -+:107E6000D5F848244310043B9342B8BF1346C5F8E5 -+:107E700044341AE07F2F2CD195F857340133DBB20C -+:107E8000042B85F8573424D9002385F85734029AF7 -+:107E9000019B0399FCF77EFCD5F84424431004337E -+:107EA0009342A8BF1346C5F84834D6F8A8109BB231 -+:107EB000D1F8442430469342A8BF1346D1F8482451 -+:107EC00040F2A7419342B8BF13469BB2FF22FAF794 -+:107ED00063FC05B0F0BDC0462DE9F04F474B87B0BD -+:107EE00003AC80460D4693E8070084E8070040F2A3 -+:107EF00045614046D8F8A8B0FAF71CFC40F246614C -+:107F000087054046FAF716FC3D498605062240469D -+:107F1000FAF756FC00210A464046FDF741F84FF4B7 -+:107F2000FA730193404629462022A3F5FA73009480 -+:107F3000FDF736FFBF0DB60D8246002849D0049DDF -+:107F4000DDF81490039C09EB0503012B02D84FF0D8 -+:107F5000000A3EE02046FBF74BF806464846FBF792 -+:107F600047F8A6F114031AB2002A06DB35FA02F12B -+:107F70003FD0013235FA02F206E0534215FA03F11E -+:107F800037D0D24315FA02F233B2C3F11E0314FA0A -+:107F900003F3C3EB0204A0F10B031BB2002B0A4650 -+:107FA00002DB35FA03F102E05B4215FA03F120D05F -+:107FB00003B2C3F11F0309FA03F394FBF2F493FB3A -+:107FC000F1F004FB1400FBF71FF8A7058605BF0DB1 -+:107FD000B60D404639463246FCF7E2FF40460949B5 -+:107FE0000622FAF7EDFB5046ABF8B872ABF8BA626E -+:107FF00000E0002007B0BDE8F08FC046BC060200DC -+:10800000C20E0200DC0E020070B504460D46C9B176 -+:1080100004221249FAF7D4FBD4F8A83093F8E933D4 -+:10802000A02B05D1204640F64A1140F24F1203E042 -+:10803000204640F64A11A722FAF788FB0849204655 -+:108040000E2201E007490A22FAF7BAFBE369291E6A -+:1080500018BF0121186938F0A7DB70BDBE0D020002 -+:10806000A20D0200D80D020070B50C46062226496A -+:10807000E4B20546D0F8A860FAF7A2FB0C2C01D8B0 -+:10808000002405E041F25013EB561C1E18BF0124DA -+:1080900096F81A35002B31D0284640F64211FAF7EF -+:1080A00049FB14B10F280BD100E0A8B9D5F8F8307E -+:1080B00013F0060F22D196F82C30A3421ED05CB1EB -+:1080C000EB690122D8689968EDF398F728460121F9 -+:1080D000FFF79AFF01230AE0EB690022D86899684C -+:1080E000EDF38CF728460021FFF78EFF002386F87A -+:1080F0002C30284605490C22FAF762FB2846044931 -+:108100000422FAF75DFB70BDB6070200700702009B -+:108110008807020070B50D46B0F8DA101646D0F8A0 -+:10812000A840FAF731FD28B994F84C342B7094F834 -+:108130004D3401E000232B70337070BD2DE9F04702 -+:108140004FF0000886B0054602ABCDF81080CDF8A0 -+:108150000C80CDF8088003AA8A4604A9D0F8A8901C -+:10816000FAF7BEFF28460DF117010DF11602FFF7D1 -+:10817000D1FF9DF8173004990193039A029B0124C3 -+:1081800028460094FCF71AFB9DF816300746019329 -+:108190002846029B0499039ACDF80080FCF70EFB59 -+:1081A00099F8E83306460BB39DF81700B5F902219C -+:1081B000B5F90431B5F906110190284603920293EE -+:1081C00004910094FCF7FAFA9DF8163004460193E6 -+:1081D00028460499039A029BCDF80080FCF7EEFA3A -+:1081E000A742B8BF27468642A8BF0646BAF1010F8C -+:1081F00002D0BAF1030F02D17B10C9F84434AAF1BE -+:108200000203DBB2012B02D87310C9F8483406B060 -+:10821000BDE8F08707B540F25643009340F255425F -+:108220000133FAF7F1FB0EBD2DE9F04340F2DF41D7 -+:1082300089B0D0F8A8400546FAF77CFAC3B27F2B84 -+:10824000A4F84C30C0F30720C4BFA3F58073A4F892 -+:108250004C307F28C8BFA0F58073A4F84E0001AF52 -+:10826000C8BFA4F84E301123039320262A330DF102 -+:1082700018094FF00208284639460493CDF80490B7 -+:10828000CDF808800596FFF7C5FF069B3F2B01D967 -+:10829000803B0693069B2365079B3F2B01D9803BC0 -+:1082A0000793079B40F2344163652846FAF742FA88 -+:1082B000C0B27F28C4BFA0F5807398B284F858007C -+:1082C00040F224412846FAF735FAC0F30720A4F813 -+:1082D0005A0040F225412846FAF72CFA0D23C0B285 -+:1082E000A4F85C00039328460F3339460493CDF875 -+:1082F0000490CDF808800596FFF78CFF069B236459 -+:10830000079B636409B0BDE8F083C0462DE9F041E6 -+:10831000B2F1FF3F8AB0064688461746D0F8A8500B -+:1083200002D1FCF7E1FB47B295F966355FFA88F4B4 -+:10833000013394FBF3F407230393193305930123CB -+:10834000E4B2029301AD07AB0193304604F5A0738C -+:1083500029460493FFF75EFF079BC034C3F307531E -+:108360000793304606AB294601930494FFF752FF6A -+:10837000002107980DF126020DF12203F0F31AF007 -+:108380000021402008AB09AAF0F314F0BDF9223017 -+:10839000BDF920108B4209DABDF92400C91AF0F3A7 -+:1083A000BBF0BDF82240ADF8240009E0BDF926007D -+:1083B000C1EB0301F0F3B0F0BDF82040ADF82600AA -+:1083C000BDF92600BDF92410F0F3B0F023B2032B61 -+:1083D00080B201DD231F01E0C4F104039AB212B29E -+:1083E00008FA02F103B2052003FB0010911E0123DD -+:1083F0008B40013AC018104107FB00F0C0F3CF00DA -+:108400000AB0BDE8F081C04670B5182386B0D0F838 -+:10841000A840039300238022049340F27666203321 -+:1084200005460593314613460292FAF7B5F904F171 -+:108430009C03284601A90193FFF7ECFE40F271610D -+:108440002846FAF777F940F27361A4F89C022846AF -+:10845000FAF770F940F27461A4F89E022846FAF720 -+:1084600069F940F27561A4F8A2022846FAF762F9A8 -+:1084700040F27961A4F8A0022846FAF75BF9314688 -+:10848000A4F8A4022846FAF755F940F2DA61A4F8F4 -+:10849000A6022846FAF74EF940F22551A4F8A802A0 -+:1084A0002846FAF747F994F86735A4F8AA0284F841 -+:1084B000AC324FF48F612846FAF73CF94FF49A61D9 -+:1084C000A4F8AE022846FAF735F940F22451A4F890 -+:1084D000B0022846FAF72EF9B4F86835C0F3C03078 -+:1084E000A4F8B43294F80734A4F8B20284F8B6328F -+:1084F00094F8083484F8B73206B070BD7FB5002315 -+:108500000293103304930DF116030093012301939A -+:10851000694654330393FFF77DFEBDF8160007B09C -+:1085200000BDC0462DE9F84FD0F8A860074696F880 -+:1085300046355BB9FFF7E2FF40F3072340B21FFA6D -+:1085400083F81FFA80F9C246CB4607E0B6F84A85A1 -+:10855000B6F84C95B6F84EA5B6F850B5B7F8DA307F -+:10856000384603F47043B3F5005F0CBFB6F866609D -+:10857000B6F868604FF0FF320121FCF72BFA36B2F3 -+:108580000121324684B23846FCF724FA0021241A2D -+:108590004FF0FF323846FCF71DFA0121324685B212 -+:1085A0003846FCF717FAA4B2C4EB0806B6B2C4EB1F -+:1085B00009042D1AFF2238463346A4B240F6521160 -+:1085C000FAF7EAF83846FF22234640F65311FAF745 -+:1085D000E3F83846FF22334640F65611FAF7DCF846 -+:1085E000ADB23846FF22234640F65711FAF7D4F8C9 -+:1085F000C5EB0A033846FF2240F648119BB2C5EB93 -+:108600000B05FAF7C9F8384640F64911FF22ABB21C -+:10861000FAF7C2F8BDE8F88F2DE9F04F93B00DF1ED -+:1086200026080C46D0F8A8503B49064693464046DB -+:10863000222201AFE9F3A0F4384638492222E9F3B7 -+:108640009BF4BCB10022304640F60F11FAF77EF8D9 -+:1086500095F8E933324AA02B324B14BF052403248A -+:1086600014BF1046184614BF4FF0100A4FF0110AFD -+:10867000B94616E0012230464FF41161FAF766F868 -+:1086800095F8E933284AA02B284B14BF0E240A245E -+:1086900014BF1046184614BF4FF0100A4FF0110ACD -+:1086A000C1460022114604E00B5A013224319B4599 -+:1086B00006D0A2421FFA82F8F6D14FF6FF7416E0F8 -+:1086C0000FFA88F2242302FB03070024254607E063 -+:1086D00035F80910304637F81420FAF737F8023524 -+:1086E00001340AF101039C42F2D11FFA88F43046AA -+:1086F000FCF74AF910B13046FFF714FF3046FCF79B -+:1087000065FD20B2B0F1FF3F0CBF4FF0FF300020FD -+:1087100013B0BDE8F08FC046E20A0200680802000C -+:10872000F826020040220200F4240200AC220200DB -+:108730002DE9F0438BB006460F4691460DF1060039 -+:108740001D492222E9F318F4D6F8A83093F8E9334A -+:10875000A02B14BF4FF010084FF0110817B93D4679 -+:108760003C4619E000252C4609E00DF10603E15ACC -+:108770003046F9F7DFFF013524F80900023445459A -+:10878000F3D10BE00DF10603E15A34F8092030462D -+:10879000F9F7DCFF013502344545F3D13046FCF7EB -+:1087A000F3F810B13046FFF7BDFE17B93046FCF7BD -+:1087B0000DFD0BB0BDE8F0830C0C020030B587B0A6 -+:1087C00005AB0093022301930023029350330C4620 -+:1087D00003936946102315460493FFF71BFDBDF86C -+:1087E00014302380BDF816302B8007B030BDC04652 -+:1087F0007FB50DF11603009301230193013B029312 -+:1088000057330393694610230493FFF703FDBDF824 -+:108810001600000A07B000BD07B540F256430093AA -+:1088200040F255420133FAF7B5F80EBDF0B5B0F895 -+:10883000DA30D0F8A85003F47043B3F5005F0CBFF2 -+:1088400095F8403395F8413387B085F8423395F871 -+:108850004233064685F84333B0F8DA3003F4704308 -+:10886000B3F5005F14D195F8492353B2002B02DD14 -+:1088700085F8482309E0C3691B6D13F4805F01D0BC -+:10888000342300E0302385F8483395F85C3313E057 -+:1088900095F84A2353B2002B02DD85F8482309E0FE -+:1088A000C3691B6D13F0805F01D0342300E03023D7 -+:1088B00085F8483395F85D335BB2002B4CDD03221D -+:1088C000022BA8BF022303FB02F340F2DF41304634 -+:1088D000DFB2F9F72FFFC1B27F29C0F30720C4BF71 -+:1088E000A1F5807399B203B27F2BC8BFA0F5807346 -+:1088F0007AB2C8BF98B292B2C2EB0003C2EB0102D7 -+:10890000DBB202F0FF0242EA0322304640F2DF41CE -+:10891000F9F71CFF0DF116030093022301930F33A7 -+:1089200002930F2303933046082369460493FFF70D -+:1089300071FC9DF81630FAB29B1A8DF816309DF82E -+:10894000173030469B1A69468DF81730FFF764FFE1 -+:1089500030466C46FDF7FEF94FF0FF3385F89A3349 -+:1089600095F84D33002285F8472385F89C23BBB149 -+:1089700085F8422385F84323304640F22341FF32F5 -+:10898000B5F85033F9F708FF30464FF4AA61B5F84F -+:108990006023F9F7DBFE304604490422F9F710FFA3 -+:1089A0003046FCF711F907B0F0BDC046EC0D0200EF -+:1089B0002DE9F04FC3690C464FF08051BBB005461E -+:1089C000D0F8A870164618690A4637F073DE0520FD -+:1089D000EDF3C2F628464FF489614FF4804200233C -+:1089E000F9F7DAFE0122284640F20A511346F9F758 -+:1089F000D3FE0DF1E70334930123359310333693FF -+:108A00000F2337932846082334A93893FFF702FC35 -+:108A10000CB1314612E0B5F8DA3003F47043B3F527 -+:108A2000005F40F03E81EB6997F8BF641B6D13F463 -+:108A3000805F0CBF08210621FF2E00D10E469DF855 -+:108A4000E720032306FB13238DF8E6300DF1E60340 -+:108A500034932846102334A93793FFF7DDFE7300C3 -+:108A6000FE229BB2284640F20A51F9F795FE97F88C -+:108A7000C044FF2C00F0EA80002C00F0C980102CCC -+:108A800028BF1024C4F12403D9B272B24BB29A4267 -+:108A900001DDCEB202E0002E08BF012670B2A04276 -+:108AA000019002DC5FFA86F902E0631C5FFA83F949 -+:108AB00004F1010BC9EB0B035FFA83F80D23369326 -+:108AC000133338934FFA89F35B004FFA88F204931B -+:108AD00009AB03EBC203570003937B1CDBB2079384 -+:108AE0006300013305934FEA4B03029206934FF064 -+:108AF000000A0198049AA042CABF73B2CDF8DCB054 -+:108B00003793379B34A953445B003793039B284624 -+:108B100035923493FFF77EFB07990AE03AA800EB01 -+:108B2000810353F8C42C42F0800243F8C42C8B1C00 -+:108B3000D9B2059A9142F1DD002111E03AAB03EB85 -+:108B4000810203EB870353F8C43C3AA842F8C43CC3 -+:108B500000EB870353F8C03C42F8C03C8B1CD9B2F1 -+:108B6000B942EBDB069A09AB349328464FEA4A0335 -+:108B700034A90AF1250A35923793FFF74DFEBAF171 -+:108B80004A0FB6D1019B4FFA88F2A342C4BF73B219 -+:108B900037934FFA89F335930DF1AE0303EB42039C -+:108BA000D8BFCDF8DCB034931023389328460E2379 -+:108BB00034A93693FFF72EFB0CE03AAE06EB4803E0 -+:108BC00033F83A2C42F4006223F83A2C08F10103FE -+:108BD0005FFA83F8A045F0D9002109E0029E3AA887 -+:108BE00000EB430200EB460333F83A3C22F83A3CF0 -+:108BF0000298CBB201318342F0DB0DF1AE03349326 -+:108C00002846002334A9CDF8D4B03793FFF704FEEB -+:108C100001221346284640F20E51F9F7BDFD4FF4EC -+:108C20007E4263021340284640F20E51F9F7B4FD2C -+:108C3000284640F20F517F222346F9F7ADFD284622 -+:108C400040F20F514FF47E52E3011BE0284640F200 -+:108C50000E5101220023F9F79FFD284640F20E51E4 -+:108C60004FF47E420023F9F797FD284640F20F515A -+:108C70007F220023F9F790FD284640F20F514FF470 -+:108C80007E520023F9F788FDEB694FF08051186997 -+:108C9000002237F00FDD2846FDF75CF83BB0BDE859 -+:108CA000F08F2146CAE6C0462DE9F041D0F8A86011 -+:108CB0000746D6F87C45002505E021463846FFF7F3 -+:108CC000ABFD01351434D6F878359D42F5D3BDE8B7 -+:108CD000F081C046F0B5C369D0F8A85087B0074608 -+:108CE00080219868EDF3F4F7044600286DD0B5F8BC -+:108CF0001C34002603F4807C03F4007E30464FF0E1 -+:108D0000000316F0100206F00101035316D0BEF165 -+:108D1000000F03D0D5F81C34C3F3802116F0080FE0 -+:108D200002D095F81A3408E0D5F8183416F0200F60 -+:108D300014BFC3F3072303F0FF030353BCF1000F79 -+:108D400000D062BB16F0040F09D016F0020F025BD0 -+:108D500002D0D5F80C340EE0D5F80C3418E016F03B -+:108D6000200F06F002030CD0025B13B1D5F81034CB -+:108D700001E0D5F8143409B11B0E0EE0C3F307432C -+:108D80000BE0025B13B1D5F8103401E0D5F81434D0 -+:108D900011B1C3F3072300E0DBB2134303530136E1 -+:108DA0000230402EABD10F230393002304933846A7 -+:108DB000103301A9059302960194FFF72DFDFB697D -+:108DC000214698688022EDF393F707B0F0BDC046C6 -+:108DD0002DE9F041002486B00594D0F8A88006461D -+:108DE000FBF782FE072302931933049307460123FE -+:108DF0002546019316E00BB90C4603E011F0010F74 -+:108E00000FD14C0830467AB2FFF780FA06AB43F830 -+:108E1000040D0093304604F5107369460393FFF781 -+:108E2000FBFC0135802DE9B298F96635E3D17BB1C1 -+:108E300001230193402405AB0093304604F51073E1 -+:108E400069460393FFF7E8FC631CDCB2802CF2D187 -+:108E500006B0BDE8F081C0462DE9F04FB0F8DA3039 -+:108E600089B003F47043B3F5005F07468B46D0F832 -+:108E7000A85002D1B5F8C42304E0B3F5805F08D14F -+:108E8000B5F8C62313B2B3F1FF3F02D01FFA82FA3E -+:108E900001E04FF0700A072304931933069301236E -+:108EA0004FF00009039307AB0293C846CDF8049036 -+:108EB000019B18F0010F0BEB0306F378009303D02E -+:108EC00095F96635002B59D1B7F8DA3003F47043C1 -+:108ED000B3F5005F03D0019B13F80B9012E0B5F8D7 -+:108EE000402413B2B3F1FF3F18BF1FFA82F9B5F85F -+:108EF0003E2408BF4FF00F0913B2B3F1FF3F1CBF70 -+:108F000092B20092B37872781B0443EA022343EAD8 -+:108F10000A6343EA0903079395F9663502AC013306 -+:108F2000B8FBF3F3C033384621460593FFF774FCD2 -+:108F300007AB029395F9663538460133B8FBF3F376 -+:108F400003F5A07321460593FFF764F93279009B7E -+:108F5000120542EA0372079B384623F07F4323F44D -+:108F600070031A43079295F9663521460133B8FB21 -+:108F7000F3F303F5A0730593FFF74EFC019B08F193 -+:108F800001080533B8F1800F019391D195F9663549 -+:108F9000002B36D05E4608F1800896F8423196F8EC -+:108FA00041211B0443EA022302AC43EA0A6343EA79 -+:108FB00009033846214608F180050793CDF814804F -+:108FC000FFF72AFC07AB3846214602930595FFF7C9 -+:108FD00021F996F84421009B120542EA0372079B8F -+:108FE000384623F07F4323F470031A43214608F1E7 -+:108FF0000108079205950536FFF70EFCB8F5A07F2E -+:10900000CBD109B0BDE8F08F10B5B0F8DA30D0F8A8 -+:10901000A82003F47043B3F5005F03D1D2F87415B0 -+:10902000FFF71AFF10BDC0462DE9F043054687B093 -+:10903000D0F8A890002940D0072399F8C272029373 -+:1090400019330493012301934FF0000805AB0093FB -+:109050002AE007F1C003284669460393FFF7DAF8D0 -+:1090600006F1C003284669460393FFF7D5FB07F5D1 -+:10907000A073284669460393FFF7CCF806F5A07362 -+:10908000284669460393FFF7C7FB07F51073284688 -+:1090900069460393FFF7BEF806F510732846694644 -+:1090A0006C460393FFF7B8FB99F8C2325FFA88F673 -+:1090B000B34208F10108CCD20CE0B0F8DA3003F486 -+:1090C0007043B3F5005F02D10449FFF7C5FE28469F -+:1090D000FFF77EFE07B0BDE8F083C04684C90200FA -+:1090E0002DE9F041D0F8A84086B094F907144FF06C -+:1090F000FF3289B20646FFF709F994F9673505464C -+:10910000022B01D0002007E094F90814304689B200 -+:109110004FF0FF32FFF7FAF8072302931933049355 -+:109120000123C0EB05070193304605ABB4F8681581 -+:109130004FF0FF320093FFF7E9F84FF000084FF0CF -+:109140000003C019A4F86A3548BFA4F86A0521E0F5 -+:1091500094F8662512B111F0010F19D1B4F86835F1 -+:10916000B4F96A558B4253B238BFED1B013391FB02 -+:10917000F3F3DBB203F5107330464FF0FF32039385 -+:10918000FFF7C4F8401B059069463046FFF744FBE3 -+:1091900008F10108B8F1800F5FFA88F1D8D194F98D -+:1091A00066357BB10123019305AB0093402404F5A0 -+:1091B0001073304669460393FFF72EFB631CDCB245 -+:1091C000802CF4D106B0BDE8F081C04630B518233C -+:1091D00087B0D0F8A8400393083305936033029317 -+:1091E00000230546049301A904F19C030193FFF7B2 -+:1091F00013FB2846B4F89C2240F27161F9F7A6FAF5 -+:109200002846B4F89E2240F27361F9F79FFA284687 -+:10921000B4F8A22240F27461F9F798FA2846B4F83B -+:10922000A02240F27561F9F791FA2846B4F8A42219 -+:1092300040F27961F9F78AFA2846B4F8A62240F29A -+:109240007661F9F783FA2846B4F8A82240F2DA6189 -+:10925000F9F77CFA2846B4F8AA2240F22551F9F72A -+:1092600075FA2846B4F8AE224FF48F61F9F76EFA1A -+:109270002846B4F8B0224FF49A61F9F767FAB4F8C7 -+:10928000B2324FF40042DB032846134040F224512F -+:10929000F9F782FA94F8AC32284684F86735B4F8C6 -+:1092A000B432A4F8683594F8B63284F8073494F8E8 -+:1092B000B73284F80834FFF713FF07B030BDC0465B -+:1092C0002DE9F04F8DB0039202930BAB0646D0F818 -+:1092D000A8708B4600930DF12F010DF12D030DF1B8 -+:1092E0002E02FCF75BF930460DF12A010AAAFFF7BE -+:1092F00065FA3046FFF702F90723069319330893FE -+:1093000009AB04934FF000080123059381464FF405 -+:1093100050735D46C246079338E097F8662522B140 -+:109320000AEB0B0313F0010F2DD153B2013304AC40 -+:10933000B5FBF3F303F5A073304621460793FEF720 -+:1093400069FF099BBDF828201B0D92051B05920D96 -+:109350001A43BDF82A3030469B059B0D42EA83280C -+:109360002146CDF82480FFF757FACDF8249097F9DD -+:10937000663530460133B5FBF3F303F5E073214660 -+:109380000793FFF749FA01350AF1010A039A95425A -+:10939000C3D997F96635C3B17F2A16D14FF4C0758A -+:1093A00004AC304621460795CDF82480FFF734FA07 -+:1093B00005F18003304621460135CDF8249007930E -+:1093C000FFF72AFAB5F5E07FEAD1029A07EB4203EC -+:1093D000BDF82A20A3F86C20BDF82820A3F87890C7 -+:1093E000A3F872209DF82F3087F87E309DF82E303C -+:1093F00087F87F309DF82D3087F880309DF82C302D -+:1094000087F881300DB0BDE8F08FC0462DE9F04FF0 -+:109410008DB00393C369D0F8A86005460C469868E0 -+:109420004FF480619346EDF353F40746002800F0B3 -+:109430008A80C5F8FC4F28460121FDF769FA96F8A5 -+:109440002C3043B1284641490622F9F7B9F928469C -+:109450000021FEF7D9FDA4B101203D4984EAE47260 -+:10946000A2EBE47200FB01F1B1FBF2F39EB202FB4E -+:1094700006F2431C8A4298B2EFD1B6F5807F01D93B -+:109480005AE00226242304FB03F349F6404293FBEF -+:10949000F2F300241B04642293FBF2FAA146A046D7 -+:1094A0002EE048460AA9F9F72FFD0B9B03FB0BF3AF -+:1094B000002B04DBDB130133C3F3490206E05B42FC -+:1094C000DB1301335B105B429A05920D0A9B03FB91 -+:1094D0000BF3002B04DBDB130133C3F3490306E07A -+:1094E0005B42DB1301335B105B429B059B0D43EA40 -+:1094F000822347F82830631CD1449CB208F101084C -+:10950000B442CED1062228461249F9F759F915235B -+:10951000079300240B33284605A90993059706965F -+:109520000894FFF779F9039B2846009331464FF6DC -+:10953000FF722346FDF772F8EB69394698684FF4DD -+:109540008062EDF3D5F30DB0BDE8F08FCE070200D9 -+:10955000005A6202C207020030B587B005AB009323 -+:1095600001230193173302930833002204934FF42D -+:109570000023054603920593144628466946FFF7E3 -+:109580004BF9039B01330393631CDCB2802CF4D1B1 -+:1095900007B030BDF0B5D0F8A83087B093F89A2561 -+:1095A0000746002A2DD1324B324D1E68144605E085 -+:1095B00029463846FFF730F901341435B442F7D163 -+:1095C0002D4A002453683846019310230293082340 -+:1095D00004931368694600930394FFF71DF9FB6930 -+:1095E0001B6B082B0DD1254A3846536869460193F9 -+:1095F000122302930E330493136803940093FFF72E -+:109600000BF9102304930DF1160300934FF072032E -+:1096100008260125ADF81630384600236946039325 -+:1096200002960195FFF7F8F84FF082033846694635 -+:10963000ADF816300395FFF7EFF84FF006036946D3 -+:109640003846ADF816300396FFF7E6F83846FFF7D0 -+:10965000DBFC3846FFF728FB3846FFF73BFB384674 -+:10966000FFF7B6FB38466C46FFF776FF07B0F0BD54 -+:10967000F8100200D4150200181D0200F41C0200AC -+:1096800070B5B0F8DA30054603F47043B3F5005F07 -+:10969000D0F8A8200CD192F9F133B3F1FF3F37D1C4 -+:1096A000B2F9F833B3F1FF3F32D1B2F92C352CE0E7 -+:1096B000B3F5805F35D192F95B35B3F1FF3F27D128 -+:1096C00092F9F333B3F1FF3F22D192F95C35B3F154 -+:1096D000FF3F1DD1B2F90034B3F1FF3F18D1B2F909 -+:1096E0003035B3F1FF3F13D1B2F90234B3F1FF3F8C -+:1096F0000ED1B2F93435B3F1FF3F09D1B2F90434D8 -+:10970000B3F1FF3F04D1B2F93835B3F1FF3F08D0D0 -+:10971000012482F86645102228464FF49A611346C8 -+:1097200007E0002482F8664528464FF49A6110222B -+:109730002346F9F731F84FF48F6103222346284678 -+:10974000F9F72AF82846FFF725FF2846FBF7E2FF3E -+:109750002846FCF7E1FE2846FFF768F870BDC046D2 -+:1097600010B5002388B00593103307930DF106035D -+:10977000039301230446ADF80610049303A9543360 -+:109780000693FFF749F82046FBF7FEF810B1204694 -+:10979000FEF7C8FE08B010BD2DE9F041D0F8A87062 -+:1097A0000646002419E0B6F8DA3003F47043B3F546 -+:1097B000805F07D1A218137923B1890492783046CB -+:1097C000890C07E06B4BE21853792BB18904D278EE -+:1097D0003046890CF8F73CFF0634664A4FF6FF73B3 -+:1097E000A15A9942DFD1304673210022F8F730FFA9 -+:1097F000304632216A22F8F72BFF192230463321F6 -+:10980000F8F726FF97F8EC231AB130463321F8F722 -+:109810001FFFC2216F223046F8F71AFF9021102255 -+:109820003046F8F715FF102100223046F8F710FFF8 -+:109830009B2107223046F8F70BFF1D2102223046FC -+:10984000F8F706FF1E2106223046F8F701FF3046E2 -+:1098500040F2EA4144F28862F8F778FFB6F8DA306D -+:1098600003F47043B3F5005F0DD197F8E933B6F810 -+:10987000DE1FA02B14BF022204220BB2B3F1FF3F64 -+:109880000DD0CAB20BE0B3F5805F07D1B6F8E02F78 -+:1098900013B2B3F1FF3F01D0D2B200E0022253B2C3 -+:1098A0001FFA83F807224346304640F2EB41F8F7AF -+:1098B00073FFB6F8DA3003F47043B3F5005F05D0F8 -+:1098C000B3F5805F04D197F83B350BB9002400E075 -+:1098D00001242346254624010F22A4B2304640F23B -+:1098E000F241F8F759FFF0222346304640F2F241A8 -+:1098F000F8F752FF0F22304640F2F1412B46F8F7BD -+:109900004BFFF0222346304640F2F141F8F744FF86 -+:109910004FEA0823304640F2F2414FF4E06203F48C -+:109920007F43F8F739FFB6F8DA30304603F4704376 -+:10993000B3F5805F0CBF03F53B7341F2EA23F45AA1 -+:1099400040F2EB41630203F47E434FF40072F8F7F8 -+:1099500023FFB6F8DA3003F47043B3F5805F0BD021 -+:1099600041F23433F25A13B2B3F1FF3F04D0930201 -+:1099700003E0C046EC260200A3024FF4806203F429 -+:109980007C43304640F2EB41F8F706FF40F2EB41F2 -+:109990003046D6F8A840F8F7CDFEC0F3802084F812 -+:1099A000470540F2EB413046D6F8A840F8F7C2FE32 -+:1099B000C0F3402084F84805D6F8A820304692F835 -+:1099C000481592F847355B1A18BF012382F84635CF -+:1099D000FAF7ECFF830203F47C43304640F646116D -+:1099E0004FF48062F8F7D8FE304643490622F8F774 -+:1099F000E7FE41F21D23F35C2BB10F2230467721A5 -+:109A00001346F8F76BFE30460021FFF7A9FE97F8E2 -+:109A10009A352BB93046FEF73FF83046FDF71EFF6A -+:109A2000F3697A21186936F065DE97F8EC23400077 -+:109A300084B22AB124B1F369A11C186936F078DE2A -+:109A400097F8ED232AB124B1F3692146186936F05D -+:109A50006FDE97F8BB34DBB104221346304640F288 -+:109A60001D11F8F73BFE30469F213F2297F8BC348A -+:109A7000F8F734FE30469E213F2297F8BD34F8F7C0 -+:109A80002DFE304677210F2297F8BE34F8F726FED8 -+:109A9000B6F8DA3003F47043B3F5805F29D197F953 -+:109AA000583533B3B42124223046F8F7D1FDB7211D -+:109AB00024223046F8F7CCFD0322B8213046F8F7CF -+:109AC000C7FD97F95825022A07D13046B821F8F783 -+:109AD000BFFD3046B521012209E0032A09D13046F5 -+:109AE000B821013AF8F7B4FD3046B5210022F8F765 -+:109AF000AFFDBDE8F081C046C604020010B5FFF717 -+:109B00004BFE10BD70B50026D0F8A850C0F8FC6F11 -+:109B100095F82C3004463BB12A490622F8F750FE4E -+:109B200020460121FEF770FA204640F24461F8F722 -+:109B300001FE10F0010309D020463146FCF740FD3C -+:109B40000222204640F23F61134607E010F0020F68 -+:109B500006D0204640F253414FF40042F8F71CFE75 -+:109B6000204619490922F8F72BFE20460021FCF770 -+:109B7000CFFE2046FAF71AFF30B12046FEF7BEFCB2 -+:109B800001462046FFF7ECFD95F8473520469B023D -+:109B900003F47C4340F2EB414FF48062F8F7FCFDA4 -+:109BA000B5F84E356BB1204640F64811FF22F8F764 -+:109BB000F3FD204640F64911FF22B5F85035F8F77D -+:109BC000EBFD70BDE60B0200F20B020070B50C4617 -+:109BD00088B00546F9F720F944B92846FFF792FF07 -+:109BE00028462146FCF794FE204622E028462146DE -+:109BF0000122FAF789F8064608B1012019E0284643 -+:109C00000121FCF785FE0C4B40240393152305939B -+:109C10002846102303A9079304940696FEF7FCFD3B -+:109C2000284621464FF6FF7233460096FCF7F6FCB5 -+:109C3000304608B070BDC0469A21020070B50023BE -+:109C400086B002931033049305AB009302230446BD -+:109C5000ADF8141001930D464E3369461646ADF823 -+:109C600016200393FEF7D8FD2046FAF79FFE78B33F -+:109C7000204640F6461140F2FF322B46F8F78CFDA5 -+:109C8000204640F6471140F2FF323346F8F784FD94 -+:109C900020464FF4156140F2FF322B46F8F77CFD69 -+:109CA000204640F6511140F2FF323346F8F774FD7A -+:109CB000204640F6541140F2FF322B46F8F76CFD77 -+:109CC000204640F6551140F2FF323346F8F764FD66 -+:109CD00006B070BD2DE9F04F8DB004910392D0F81D -+:109CE000A860074606EB4303B3F872B0B3F86C10F4 -+:109CF000B3F878905A460591FFF7A0FF38464946D9 -+:109D0000FFF72EFD0723089319330A934FF000083D -+:109D10000123049D0793C2460BAB069337E096F8E8 -+:109D200066252AB104990AEB010313F0010F2BD128 -+:109D300053B2013306ACB5FBF3F303F5A073384619 -+:109D400021460993FEF766FA0B9B05994FEA8B5261 -+:109D50001B0D1B05920D1A438B059B0D42EA8328B0 -+:109D600038462146CDF82C80FEF756FD96F966352B -+:109D700038460133B5FBF3F303F5E073214609934D -+:109D8000CDF82C90FEF748FD01350AF1010A039A3F -+:109D90009542C4D996F96635C3B17F2A16D14FF4DE -+:109DA000C07506AC384621460995CDF82C80FEF7E3 -+:109DB00033FD05F18003384621460135CDF82C905E -+:109DC0000993FEF729FDB5F5E07FEAD196F8810009 -+:109DD00096F87E1096F87F2096F8803000903846EE -+:109DE000FBF7DEFC0DB0BDE8F08FC04670B500217A -+:109DF0000446D0F8A8500B467F22FFF76BFF2046A1 -+:109E0000FFF7E4F92046B5F8B812B5F8BA22FBF727 -+:109E1000C7F8204640F2D16104220023F8F7BCFCC9 -+:109E200070BDC04670B50446D0F8A8300D4699B153 -+:109E300093F8BC3233B3FFF7D9FF20460422002346 -+:109E400040F2D161F8F7A8FC8022204640F276610A -+:109E50001346F8F7A1FC15E00422134640F2D16145 -+:109E6000F8F79AFC8022204640F276612B46F8F7FC -+:109E700093FC20462946FFF773FC204629462A46D4 -+:109E8000FFF7DCFE70BDC04630B500238BB00893F1 -+:109E9000079306930733054603930A4609B90491CD -+:109EA00002E04FF4307304932023059309AB019330 -+:109EB000012302933AB9284608A907AA06ABF9F785 -+:109EC0000FF9002409E0B5F902310793B5F904311F -+:109ED0000693B5F906310893F3E70899069B2046E7 -+:109EE000079AFAF757FC01A909902846FEF794FC57 -+:109EF000049B01340133802C0493EED10BB030BDB0 -+:109F0000F0B5284B8BB005AC05460F460FCB84E867 -+:109F10000F0041F22403EB5CD5F8A8601BB196F862 -+:109F2000E034002B3BD028461F490822F8F748FCB4 -+:109F3000072302931933049304230193009403F538 -+:109F40004F7301240393284686F86A406946FEF75A -+:109F500063FC0023099309AB019400934FF45174FF -+:109F6000284669460394FEF757FC013440F25E33FD -+:109F70009C42F5D128460D491222F8F721FC7B00BE -+:109F80009BB2284640F2A94140F2FF12F8F704FCC8 -+:109F9000284640F2A36110220023F8F7FDFB0BB026 -+:109FA000F0BDC04668050200620C020054090200C0 -+:109FB00030B5D0F8A8509BB004460022A31893F9FE -+:109FC000103501A95B4241F822300132142AF5D143 -+:109FD00095F86A3063B907331793193319931591BC -+:109FE00003F54873204615A916921893FEF714FC42 -+:109FF000D4F8A81094F82936D1F844242046934286 -+:10A00000A8BF1346D1F8482440F2A7419342B8BFF5 -+:10A0100013469BB2FF22F8F7BFFB95F8E833F3B184 -+:10A02000B5F8E62394F8293620469B1A1B024FF414 -+:10A030007F42134040F2D141F8F7AEFB94F8292655 -+:10A0400095F825352046C3EB420395F8E62340F208 -+:10A05000D1419B1A5BB2FF229BB2F8F79DFB2046D1 -+:10A06000FAF7A6FB1BB030BD70B5C6B001ACD0F896 -+:10A07000A8500646002120464FF48072E7F3E0F72F -+:10A080000723439319334593419495F86A3043B9B4 -+:10A090001E33429330464FF4507341A94493FEF768 -+:10A0A000BBFB402342933046DB1841A94493FEF7A3 -+:10A0B000B3FB46B070BDC0462DE9F04106460C46E4 -+:10A0C000FAF72CFF214605463046FAF74FFC2946A1 -+:10A0D00004463046FAF74AFC4022B4F5404F0CBF24 -+:10A0E00013460023054640F2DA613046D6F8A870E0 -+:10A0F000F8F752FB1022B4F5404F14BF134600236B -+:10A10000304640F2A361F8F747FB0122B4F5404F17 -+:10A1100014BF00230123304640F26E41F8F73CFBA8 -+:10A12000A54200F09580B5F5404F02D13046FFF7CB -+:10A130009BFFB4F5404F3CD13046FFF739FFD6F8CE -+:10A14000A8203B8E92F966255B00013293FBF2F367 -+:10A15000304640F2A44140F2FF129BB2F8F71CFBDC -+:10A160007B8E30461B0240F2A5414FF4E06203F4BF -+:10A170007F43F8F711FB04223046002340F21F1101 -+:10A18000F8F7ACFAF369E021186936F0B3DA002188 -+:10A19000F8853046FAF7A2FF4FF0FF3387F83430E6 -+:10A1A000304640F2A9414FF400420133F8F7F4FA87 -+:10A1B00003E030460121FAF791FF304640F2A44116 -+:10A1C0004FF460422346F8F7E7FAB4F5404F0FD159 -+:10A1D0003046FAF7EBFB40F2A44100280CBF4FF4E5 -+:10A1E000005300234FF400523046F8F7D5FA15E03B -+:10A1F0004EF201039C4211D13046FAF717FB01469B -+:10A200003046FFF77DFE304640F2A941F8F792FA5A -+:10A210000223C0B290FBF3F087F8C10297F96735CB -+:10A22000012B0DDD40F2A4413046F8F783FAC0F36C -+:10A23000803340F2255130464FF40042DB0305E005 -+:10A24000304640F225514FF400420023F8F7A4FABB -+:10A25000BDE8F08170B50023D0F8A82080F82B3637 -+:10A2600092F8E03405468BB190F92A16D2F84834BA -+:10A27000994203DBD2F81035994207DA4EF2010118 -+:10A28000FFF71AFF012385F82B3612E041F2240371 -+:10A29000EB5C73B12846FAF741FE002104462846DC -+:10A2A000FFF70AFF2846FFF783FE28462146FFF7FF -+:10A2B00003FF70BD30B5072389B0D0F8A8400393E1 -+:10A2C0001933059306AB0193012302930546013B25 -+:10A2D000049308E0284601A9FEF79EFA049B013387 -+:10A2E0000493069B01330693069B7F2BF2D94FF410 -+:10A2F00030730493A3F5307308E0284601A9FEF7F4 -+:10A300008BFA049B01330493069B01330693069B4F -+:10A310007F2BF2D9092228465B49F8F751FA01212F -+:10A320002846FBF7A3FB242228465849F8F748FAA9 -+:10A330002846FAF75FFDC0F34F00E62801DDFF2352 -+:10A3400005E02846FAF756FD4008193083B2FF228F -+:10A3500040F2A5412846F8F71FFA2846FFF784FE89 -+:10A36000B4F8E623B4F8E433284603EB42039B0138 -+:10A370009BB24FF49A6147F6C072F8F70DFA0922C2 -+:10A3800028464349F8F71CFAB5F8DA30282103F4D7 -+:10A3900070431E22B3F5005F14BF18231C23284608 -+:10A3A000F8F79CF901223A2113462846F8F796F966 -+:10A3B0000822134628464FF48D71F8F78FF92521AE -+:10A3C0000C222846F8F744F9B5F8DA3003F4704364 -+:10A3D000B3F5005F04D1022228463A21134603E078 -+:10A3E00028463A2102220023F8F778F9082213467A -+:10A3F00028460521F8F772F9284606222549F8F77C -+:10A40000DFF947F20802284640F2D7414FF40053E3 -+:10A41000F8F7C2F92846FAF7EDFC102305930DF181 -+:10A420001E03019301230824ADF81E000293284661 -+:10A43000053301A904930394FEF7EEF928460F2291 -+:10A440001549F8F7BDF928463521FF220023F8F712 -+:10A4500045F92846362103220023F8F73FF928461C -+:10A46000224623464FF48D71F8F738F94FF4806295 -+:10A47000284640F2A4411346F8F78EF92846FBF728 -+:10A480008DFA09B030BDC046C60D02009A05020023 -+:10A49000A4070200F40D0200000E02007FB50902BD -+:10A4A00006AB23F8021D009301230193013B0293A5 -+:10A4B00057330393694610230493FEF7ADF907B0B1 -+:10A4C00000BDC0462DE9F041D0F8A8308AB083F82D -+:10A4D000341083F8C11293F9663506460F466BB106 -+:10A4E00011F0010304D04FF48F610C22082302E025 -+:10A4F0004FF48F610C22F8F74FF97F08072303937D -+:10A5000001AC07F5A07320254FF0010804933046F5 -+:10A5100009AB214601930595CDF80880FDF77AFE39 -+:10A5200007F1C003049330460DEB05032146019368 -+:10A530000595FDF76FFE089B304603F0FF02ADF86E -+:10A540001820C3F30722C3F30743ADF81C30099B5F -+:10A5500006A9C3F30273ADF81A20ADF81E30FAF75E -+:10A56000F5FD09993046C1F30751FFF797FF3046D3 -+:10A570004146FAF7B3FD0AB0BDE8F0812DE9F04F8E -+:10A5800091B0BDF8783002AC0193BDF87C3007463D -+:10A590000093534B9DF880601D460FCD0FC495E886 -+:10A5A0000F009DF8748084E80F0038464D4904225E -+:10A5B000BDF87090BDF884A0BDF888B0F8F700F938 -+:10A5C000384640F2A36102227300F8F7E5F8B8F1CB -+:10A5D000000F18D010AB4FF4002243F8042D0A935B -+:10A5E00001230B9317330C9308330E9300230D9321 -+:10A5F0001C4638460AA9FEF70FF90D9B01340133BA -+:10A60000402C0D93F5D1032409FB04F43846FAF7E6 -+:10A61000EBFE0134384640F2A1615246F8F796F855 -+:10A62000A4B2384640F2A2615A46F8F78FF82246A3 -+:10A63000384640F27E61F8F789F838462A49042204 -+:10A64000F8F7BEF80134142304FB03F4013CA2B272 -+:10A6500038464FF4C861F8F779F80022384640F2DE -+:10A660007761F8F773F808230B930D330C930B33D2 -+:10A6700000240E93384602AB0AA90A930D94FEF704 -+:10A68000CBF8384640F27B61019AF8F75FF838461C -+:10A6900040F27C61009AF8F759F82246384640F2B9 -+:10A6A0007D61F8F753F821463846FFF7F7FE384644 -+:10A6B0000E490422F8F784F80D4C03E00A20ECF36D -+:10A6C0004BF00A3C384640F27661F8F733F810F068 -+:10A6D000010F01D0092CF1D111B0BDE8F08FC046B7 -+:10A6E000B80C0200780B02008A0802001E0E02005D -+:10A6F00049420F002DE9F043D0F8A8908BB00646F0 -+:10A700008846052503270F2DA8BF0F250024ABB2CF -+:10A71000019330460121224623460094029403947B -+:10A720000494FAF75BFDDB2302934FF4AF630493C9 -+:10A730004FF482430593A3F58143012207933046EA -+:10A740002146234600940194039206940894FFF74F -+:10A7500015FFB8F1000F1DD140F2BA613046F7F78E -+:10A76000E9FF40F2BB6104B23046F7F7E3FFA40112 -+:10A77000A4B244F3891404FB04F440F3090000FB81 -+:10A780000043B3F5005F01DAED1B03E0B3F5804F42 -+:10A7900004DBED1917B17B1EDFB2B4E7092D01DD33 -+:10A7A000092501E025EAE5752846C9F838500BB0BF -+:10A7B000BDE8F0832DE9F043D0F8A8608DB096F99C -+:10A7C000663507468846CCB2D3B1634B01EA030332 -+:10A7D000002B05DA013B6FEAC3736FEAD3730133D1 -+:10A7E000012B04D14FF48F610C22073303E04FF4A7 -+:10A7F0008F610C220023F7F7CFFF022398FBF3F8B9 -+:10A80000072386F8344086F8C14201AD039308F56A -+:10A81000A07320244FF00109049338460BAB29465E -+:10A8200001930594CDF80890FDF7F4FC08F1C003FE -+:10A83000049338460AAB294601930594FDF7EAFCD8 -+:10A840000A9B384603F0FF02ADF81820C3F3072235 -+:10A85000C3F30743ADF81C300B9B06A9C3F3027387 -+:10A86000ADF81E30ADF81A20FAF770FC9DF82B10E9 -+:10A87000384601F07F01FAF71DFC0B993846C1F309 -+:10A880000751FFF70BFE38464946FAF727FC0B9AAB -+:10A890003846C2F389219205920DFFF7CFF908F5EA -+:10A8A000E0730493384609AB29460193FDF7B2FCE7 -+:10A8B0003846BDF82410FEF753FF08F510730493D3 -+:10A8C00038460DEB040329460193FDF7A3FC089BD2 -+:10A8D0003846DB009BB240F2A66141F6FF72F7F703 -+:10A8E0005BFF96F967354B4532DD40F2255138461E -+:10A8F000F7F720FF4FF48072C3B29845D4BF00240D -+:10A90000012438469845CCBF1346002340F2255118 -+:10A91000F7F742FF6302384640F225514FF40072C8 -+:10A9200003F47E43F7F738FFA302384640F225517F -+:10A930004FF4806203F47C43E402F7F72DFF3846BE -+:10A9400040F225514FF4006204F47843F7F724FFF6 -+:10A950000DB0BDE8F083C0460100008070B504462C -+:10A960000D460021FFF7A8FB20462946FFF722FFEE -+:10A9700070BDC0462DE9F04F89B0054600920191A7 -+:10A98000FAF7CCFA40F23B4103902846F7F7D2FEA3 -+:10A9900004A902902846FAF70FFA00244FF47A70BF -+:10A9A0000134EBF3D9F6022CF8D141F2F023EA5846 -+:10A9B00092F820301F1E18BF012792F821300BB1EA -+:10A9C0007B1C9FB292F822300BB17B1C9FB292F895 -+:10A9D00023300BB17B1C9FB24FF00009C8464FF0EB -+:10A9E000140ABCE0D5F8B030D3F8203183F001036D -+:10A9F00013F0010403D1EB69186935F0CBDE28466A -+:10AA0000F8F756FB41F2F023EB58284603EB4803D6 -+:10AA1000998CFFF7A3FF28465146FFF73FFD1CB96D -+:10AA2000EB69186935F0A2DE4FF40042284640F287 -+:10AA3000A4411346F7F7B0FE002441F288300134F8 -+:10AA4000EBF38AF6032CF8D1284640F2A641F7F73B -+:10AA500071FEC005C00DFF2886BFA0F580731FFAE8 -+:10AA600083FB00F5807B00263446284640F23E6199 -+:10AA7000F7F760FE631CC005C00D9CB23618102CA1 -+:10AA8000F3D1C6F30F13FF2B8CBFA3F5807303F52F -+:10AA90008073504600210DF11E029EB20DF11A0383 -+:10AAA000EDF388F441F2F023EB580021434493F88E -+:10AAB000200007AA06ABEDF37DF4BDF91A30BDF90D -+:10AAC00018108B4209DABDF91C00C91AEDF324F500 -+:10AAD000BDF81A40ADF81C0009E0BDF91E00C1EB3D -+:10AAE0000301EDF319F5BDF81840ADF81E00BDF9EE -+:10AAF0001C10BDF91E00EDF319F523B2032B81B232 -+:10AB000001DD231F01E0C4F1040398B200B2431E2B -+:10AB100001229A4009B2052301FB032353FA00F0F6 -+:10AB200000F10C03182B16D841F2F023EB58019AD0 -+:10AB300003EB88031B69C31802F809304FEA9B0333 -+:10AB4000C3F17F03009A03EB960302F8093009F181 -+:10AB500001031FFA83F908F101031FFA83F8B845CE -+:10AB6000FFF440AF0AF101035FFA83FABAF1640F10 -+:10AB700002D84FF00008F2E7029B2846C3F3801189 -+:10AB8000FAF7ACFA284604A9FAF7E0FA284603993E -+:10AB9000FFF792FA484609B0BDE8F08F2DE9F04F73 -+:10ABA0001E46C369A9B0D0F8A88004460F4698682D -+:10ABB0004FF483711546ECF38BF00790002800F0FA -+:10ABC000EF81022E0FD016E00E4694F8DA3011F81D -+:10ABD0000629013D9A420BD17188B2882046FAF7C6 -+:10ABE000DFF90126CCE1062305FB03F3063BF91848 -+:10ABF000002DE9D1C3E1012E40F0C1812046FAF7D2 -+:10AC00008DF9002108902046FFF756FA0025934B56 -+:10AC10002046E95AF7F704FD1AABE8520235182D21 -+:10AC2000F5D140F231612046F7F784FD15220B90F3 -+:10AC300040F231612046F7F79FFD40F24C4120463B -+:10AC4000F7F778FD40F24D410C902046F7F772FD82 -+:10AC50004FF496610D902046F7F76CFD40F2B1413C -+:10AC60000E902046F7F766FD40F2F9410F9020461E -+:10AC7000F7F760FD40F2FA4110902046F7F75AFDD1 -+:10AC800040F6381111902046F7F754FD40F639117F -+:10AC900012902046F7F74EFD40F23B4114902046BB -+:10ACA000F7F748FD40F23C4115902046F7F742FD8A -+:10ACB00040F2DA6116902046F7F73CFD40F2DB6186 -+:10ACC00018902046F7F736FD40F2B741199020461C -+:10ACD000F7F730FD40F23B4113902046F7F72AFD8D -+:10ACE000C0F380100A9008B9099007E0204626A911 -+:10ACF000FAF762F898F8C182CDF82480204632999C -+:10AD0000FFF72CFE062220465549F7F759FDB4F807 -+:10AD1000DA3003F47043B3F5005F04D12046982184 -+:10AD20000322F7F795FC20464E491922F7F748FD14 -+:10AD300020464D491822F7F743FDB4F8DA304FF0BA -+:10AD4000030B03F47043B3F5005F14BF0423002327 -+:10AD5000179322E11FFA88F300931FFA89F3002664 -+:10AD600001931FFA8BF3324602932046179B31461C -+:10AD700003960496FAF732FA20460121FAF742F9CF -+:10AD80003346204639493C22FEF740FB20464FF42B -+:10AD900089713246F7F75CFC20AB00934FF4FA7AE6 -+:10ADA00020464FF4806120223346CDF804A0FAF704 -+:10ADB000F7FF054620B92E48F6F776FC2F4636E019 -+:10ADC0003346204629497822FEF720FB20464FF4DF -+:10ADD00089713246F7F73CFC23AB009320464FF4D1 -+:10ADE000806120223346CDF804A0FAF7D9FF18B9C4 -+:10ADF0002048F6F759FC1AE0219A24982299B0EBE2 -+:10AE0000420F0ED993009B1898420AD2259AB2EBB2 -+:10AE1000410F06D98B005B189A422CBF00270127EF -+:10AE200000E00027B8F1010801D3002F92D0B9F15A -+:10AE3000010902D3002F00F0AC80BBF1010B02D35B -+:10AE4000002F00F0AA80204640F2D16104220023A6 -+:10AE5000F7F7A2FC87B93E4614E0C046020502009F -+:10AE60001A05020026050200FA05020080841E0071 -+:10AE7000EC0602000607020020464FF48061FDF751 -+:10AE80002BF806462046FEF73DFE204640F2316193 -+:10AE90000B9AF7F75BFC204640F24C410C9AF7F70F -+:10AEA00055FC204640F24D410D9AF7F74FFC2046E5 -+:10AEB0004FF496610E9AF7F749FC204640F2B141F3 -+:10AEC0000F9AF7F743FC204640F2F941109AF7F742 -+:10AED0003DFC204640F2FA41119AF7F737FC204634 -+:10AEE00040F63811129AF7F731FC204640F6391136 -+:10AEF000149AF7F72BFC204640F23B41159AF7F7DE -+:10AF000025FC204640F23C41169AF7F71FFC2046EC -+:10AF100040F2DA61189AF7F719FC204640F2DB613B -+:10AF2000199AF7F713FC204640F2B741139AF7F746 -+:10AF30000DFC204640F24C4104220023F7F72CFC84 -+:10AF40000025194B2046E95A1AABEA5A0235F7F7A1 -+:10AF50007FFB182DF5D10A9B23B120460999FFF7F5 -+:10AF6000FDFC03E020460A99FAF7B8F82046089954 -+:10AF7000FFF7A2F820460021FAF744F800E0002687 -+:10AF8000E369079998684FF48372EBF3B1F63046A2 -+:10AF900006E000274FF00608DCE64FF00409F8E76A -+:10AFA00029B0BDE8F08FC046020502002DE9F04F40 -+:10AFB000B3B00F939DF8F8409DF8F4300D940E93C4 -+:10AFC0009DF800419DF8FC300B940C93012405463C -+:10AFD0001646D0F8A89088469DF8F0B0BDF80471E8 -+:10AFE0008DF8C7408DF8C640FDF702FC40F2D7410E -+:10AFF00012902846F7F79EFB40F2D7411090284662 -+:10B00000F7F798FB3449119006222846F7F7D8FB4A -+:10B01000284632490F22F7F7D3FB284621461AAAC1 -+:10B02000FDF786FB284621460022FDF7F5FABBF125 -+:10B03000000F02D00023199318E028462146FBF7A1 -+:10B0400067FCD5F8B030D3F8203183F0010313F05A -+:10B05000010319930AD1EB69B821186942F2107201 -+:10B0600035F066DBEB69186935F094DB2846012181 -+:10B07000F9F7C8FF28460121FBF7A2FA284601216B -+:10B08000FAF72EF940F2EA412846F7F753FB40F26F -+:10B09000EB4117902846F7F74DFB40F2EB41189033 -+:10B0A0002846F7F747FB00F0070340F2EB4128463C -+:10B0B0003822DB00F7F770FB28462DA999F8C1A2CA -+:10B0C000F9F77AFE86B1337A53B12846717AFFF7E1 -+:10B0D00045FC96F809A007E0F6090200A60B02005D -+:10B0E00028463146FAF732F840F29C412846F7F7F5 -+:10B0F00021FB40F2316113902846F7F71BFB40F229 -+:10B10000D66115902846F7F715FB40F2DA611490E6 -+:10B110002846F7F70FFB002116902846FAF728FA81 -+:10B12000284688490722F7F74BFB2FAB23930123CF -+:10B1300024930633259376B199F96625737A013203 -+:10B1400093FBF2F303F5107326932846202323A9DB -+:10B150002793FDF75FF82F9A2846D2002F9240F2EE -+:10B16000716192B2F7F7F2FA284677490C22F7F7A5 -+:10B1700027FB0024754B284633F81410F7F750FAD4 -+:10B180000DF1A203E0540134122CF3D1072228461A -+:10B190004FF48B71F7F75CFAB5F8DA3003F47043CB -+:10B1A000B3F5005F05D1284640F22D110122F7F7D3 -+:10B1B0004FFA072228464FF49671F7F749FAB5F887 -+:10B1C000DA3003F47043B3F5005F14D128466A21E6 -+:10B1D000C222F7F73DFA284698210C22F7F738FAF1 -+:10B1E000284640F22F110322F7F732FA284697211A -+:10B1F000F922F7F72DFA0B2107222846F7F728FA4C -+:10B200001022284640F21311F7F722FA1D210122DD -+:10B210002846F7F71DFA012228464FF48A71F7F7FE -+:10B2200017FAB5F8DA3003F47043B3F5005F04D1D0 -+:10B2300028462E211022F7F70BFA082228464FF451 -+:10B240009571F7F705FA092102222846F7F700FA67 -+:10B2500004221346284640F21F11F7F73FFAFF2158 -+:10B26000102200232846F7F739FA0721012200238C -+:10B270002846F7F733FA0521082200232846F7F776 -+:10B280002DFA4FF400421346284640F2DA61F7F7F0 -+:10B2900083FA41460F9A53462846FFF72BFA0024BB -+:10B2A00080B2012101902246284623460094029450 -+:10B2B00003940494F9F792FF0E9BA74208BF4FF442 -+:10B2C000824700930D9B284601930C9B41460293B5 -+:10B2D0000B9B224603934FF4AF630493A3F59F6344 -+:10B2E00007935B46059706940894FFF747F90DF11D -+:10B2F000C60228460DF1C701F9F798FC9DF8C62053 -+:10B300003F2A53D89DF9C730A3424FDB3F2B4DDC7A -+:10B3100052B29A424ADCB8F1000F27D123AC18236D -+:10B3200021462593284630AB26922393FCF772FFE3 -+:10B330009DF9C73021462846309E2693FCF76AFFC8 -+:10B3400044460EE0020A0200200D0200260E020012 -+:10B3500030AB284623A9269430962393FDF75CFA58 -+:10B3600001349DF9C62063B29A42F1DC182323AC64 -+:10B37000259326332693284630AB21462393FCF7AA -+:10B3800049FF3F23284621462693FDF745FA01232E -+:10B39000284621462693FCF73DFF002328462146F8 -+:10B3A0002693FDF739FA2846FDF72EF8284640F295 -+:10B3B000EA41179AF7F7CAF9284640F2EB41189A82 -+:10B3C000F7F7C4F92846D72102220023F7F786F9B8 -+:10B3D000082213462846D721F7F780F9002328468C -+:10B3E0004FF494710822F7F779F928464FF48B71DE -+:10B3F0000022F7F72DF9284640F29C41139AF7F7FF -+:10B40000A5F9284640F23161159AF7F79FF92846C9 -+:10B4100040F2D661149AF7F799F9169C284644F041 -+:10B42000010292B240F2DA61F7F790F92846012161 -+:10B43000FAF79EF8109C082204EA0203284640F21C -+:10B44000D741F7F7A9F9119C4FF4E04204EA02034F -+:10B45000284640F2D741F7F79FF92846FAF73CFD16 -+:10B460000024234B284633F814100DF1A203E25CAC -+:10B470000134F7F7EDF8122CF3D14FF400620023FA -+:10B48000284640F24C41F7F787F928460021FBF7A0 -+:10B4900097F828460021F9F7B5FD284640F23B41D0 -+:10B4A00001220023F7F778F900234FF400622846C1 -+:10B4B00040F63811F7F770F928460021FBF728FA13 -+:10B4C000284600211AAAFDF733F9284609490F2218 -+:10B4D000F7F776F9199B1BB9EB69186935F046D96E -+:10B4E00028461299FEF7DAFF33B0BDE8F08FC04668 -+:10B4F000260E0200C40A02002DE9F04FD0F8A83051 -+:10B5000091B093F8F49318230C930FAB0A93202374 -+:10B510000E93012317460B9301FB01FB3E330521DC -+:10B5200000228046B9F1FF0F08BF4FF001090D93CB -+:10B530000791099206230024039347F6FF733A46C6 -+:10B540000125059340462346214600940194029428 -+:10B550000495FFF72BFD40460AA9FCF75BFE0F9A06 -+:10B5600042F30B3303FB03F342F30B0202FB023201 -+:10B570007B7A5A45069303D307990894CEB206E026 -+:10B58000B9F1000F4DD1079908954B42DEB273B265 -+:10B5900006999DB26B189CB24FF0000A06990AEB0F -+:10B5A000010308999BB221B15A4506D99B1B7B72B6 -+:10B5B0002DE0089B0BB95A4529D322B27F2A26DCFD -+:10B5C0000AEB0503002A1FFA83FA20DB06237C72AC -+:10B5D000039301230021049347F6FF733A46059332 -+:10B5E00040460B46009101910291FFF7DFFC404677 -+:10B5F0000AA9FCF70FFE0F9A42F30B3303FB03F388 -+:10B6000042F30B0202FB023263199CB2C6E70799B0 -+:10B61000099A41F346030132DBB2032A07930992E8 -+:10B6200088D111B0BDE8F08F2DE9F04F8DB0DDF875 -+:10B6300058A01F460123834616468AF808304FF06B -+:10B6400000094FF0640808EB09030021C3F34F051C -+:10B65000DB238AF8095001245246039358460B46CF -+:10B6600000910191029105910494FFF79FFC18232A -+:10B670000893273309930BAB06935846202306A95A -+:10B680000A930794FCF7C6FD0B9B43F30B3202FBB6 -+:10B6900002F243F30B0303FB03231A464FEAE27360 -+:10B6A000BB4202D803D1B24201D9A94600E0A84664 -+:10B6B0000B484FF0FF31801941EB07018B4202D854 -+:10B6C00006D1824204D99F4206D801D1964203D8BE -+:10B6D000C9EB0803012BB6DC28460DB0BDE8F08F9E -+:10B6E00030F8FFFFF7B50546D0F8A87090F8DA00FB -+:10B6F0000E46F7F735FA40F6B41398420446B5F80B -+:10B70000DA2001D11E480AE0D3B2012B02D14FF456 -+:10B71000523004E00302A3F5C420A0F580600022AB -+:10B720004FF47A71F9F716F8A0FB0023284600962B -+:10B73000FFF77AFFA0F128039BB21D2B1BD9272806 -+:10B7400002D84FF434300BE040F6B4139C4202D1DF -+:10B750004FF4703004E02302A3F5BE20A0F5007082 -+:10B7600000224FF47A71F8F7F5FFA0FB002328467A -+:10B770000096FFF759FF031F87F8C232FEBDC0468F -+:10B78000008E03002DE9F04390F8DA30D0F8A8607D -+:10B790008BB086F8BC32D0F8B0300546D3F82031F3 -+:10B7A00083F0010313F001090AD1C369B8211869B4 -+:10B7B00042F2107234F0BCDFEB69186934F0EADF52 -+:10B7C00040F2A5412846F6F7B5FF04462846F9F7AA -+:10B7D000A5FB002180462846FEF76EFC4FF4404151 -+:10B7E0002846FEF769FC2846FEF73EFCD5F8A8205F -+:10B7F0002846D2F84434D2F84824402BA8BF40232E -+:10B800009342B8BF134640F2A741FF229BB2F6F71E -+:10B81000C3FF0023284640F2A5414FF4E062F6F74B -+:10B82000BBFF4FF47A7232212846FBF7ABF80121B7 -+:10B83000284696F8C072FBF76BF82846F7F738FCF5 -+:10B840004FF4E06204EA0203284640F2A541F6F70D -+:10B85000A3FF00212846FEF72FFC96F8C4420DF105 -+:10B860001E0E012C35D171462846FFF73BFF2846B6 -+:10B870002146FDF7D9FBD5F8A8202846D2F8443454 -+:10B88000D2F848243E2BA8BF3E239342B8BF1346AC -+:10B8900040F2A741FF229BB2F6F77EFF0023284625 -+:10B8A00040F2A5414FF4E062F6F776FF28463221D8 -+:10B8B0004FF47A72FBF766F896F8C032DBB996F867 -+:10B8C000C2322846043386F8C2322146FDF7ACFB6B -+:10B8D00011E000210122DB238DF82620039304923E -+:10B8E000284672460B468DF827700091019102910F -+:10B8F0000591FFF75BFB28464146FEF7DDFB284636 -+:10B9000008490422F6F75CFFB9F1000F03D1EB6997 -+:10B91000186934F02BDF28460021FAF7F9FF0BB045 -+:10B92000BDE8F083800C02002DE9F04F044695B08D -+:10B93000D0F8A86040F2E7300F46EAF30DF7072190 -+:10B940002046F6F76DFEC0B20390FF212046F6F7C1 -+:10B9500067FEC0B2049040F21F112046F6F760FE69 -+:10B96000C0B2059005212046F6F75AFE25215FFA60 -+:10B9700080FB2046F6F754FE4FF489715FFA80FA97 -+:10B980002046F6F74DFE00250190864B2046E95AE9 -+:10B99000F6F7D0FE07ABE85202351C2DF5D1D4F8EE -+:10B9A000B030D3F8203183F0010313F00103029388 -+:10B9B00003D1E369186934F0EDDE40F2A44120467A -+:10B9C000F6F72EFE002181462046FEF775FB7F210B -+:10B9D000204696F8C182FEF7C1FF012207211346D7 -+:10B9E0002046F6F77BFE1022FF2113462046F6F78D -+:10B9F00075FE04221346204640F21F11F6F76EFE34 -+:10BA0000362220466849F6F7DBFE2046F9F7F2F9C0 -+:10BA1000C0F34F00E62801DDFF2305E02046F9F7DB -+:10BA2000E9F94008193083B2FF22204640F2A541CF -+:10BA3000F6F7B2FE25210C222046F6F709FE082271 -+:10BA4000134605212046F6F749FE092257492046AC -+:10BA5000F6F7B6FE2046F9F7CDF91023129301232D -+:10BA6000ADF84E0008260F9306250DF14E03204633 -+:10BA70000EA910960E931195FCF7CEFE012F0CD156 -+:10BA80002A4620464A49F6F79BFE2022204682217C -+:10BA90001346F6F723FE042506E02A4620464549CC -+:10BAA000F6F78EFE07260A250122134620464FF49C -+:10BAB0009B61F6F771FE45F4007343EA06139B00A1 -+:10BAC00020464FF49B6140F6FC72F6F765FE0222B9 -+:10BAD000134620464FF49B61F6F75EFE20464FF476 -+:10BAE0009B614FF4E0424FF40053F6F755FE2022DD -+:10BAF000134620464FF49A61F6F74EFE01210022CC -+:10BB00002046F8F7DFF9204640F27641F6F712FEBC -+:10BB100010F4004F02D10A20EAF31EF62046072156 -+:10BB2000039AF6F795FD2046FF21049AF6F790FD5B -+:10BB3000204640F21F11059AF6F78AFD204605219E -+:10BB40005A46F6F785FD204625215246F6F780FD38 -+:10BB5000019B20464FF48971DAB2F6F779FD002592 -+:10BB6000104B2046E95A07ABEA5A0235F6F7EEFDCC -+:10BB70001C2DF5D120464FFA88F1FEF7EFFE204646 -+:10BB800040F2A4414A46F6F763FD029B1BB9E36904 -+:10BB9000186934F0EBDD40F2E730EAF3DDF515B07B -+:10BBA000BDE8F08F1A0A020036060200780502008E -+:10BBB000A2060200740C02002DE9F04FBDB007464A -+:10BBC0000C469146002116220DF15E000493E6F327 -+:10BBD00037F2A8490E220DF19E00E6F3CDF1A649F9 -+:10BBE0000E2224A8E6F3C8F148F2670148F2452284 -+:10BBF000ADF8EA10ADF8E820A04908220DF1C60022 -+:10BC0000E6F3BAF19E490E220DF18200E6F3B4F19B -+:10BC10009C4908220DF1BE00E6F3AEF19A490E22CE -+:10BC20001DA8E6F3A9F147F69733002108220DF18C -+:10BC3000B600ADF8E630ADF8E430E6F301F2FB69AA -+:10BC400030219868D7F8A880EBF342F005900028DF -+:10BC500000F0AB8240F2DB613846F6F76BFD40F254 -+:10BC6000DA610B903846F6F765FD88490A900422A0 -+:10BC70003846F6F7A5FDB9F1070F0BD8DFE809F054 -+:10BC800011040A0A0A22352D1DAA069224AB0DF1D1 -+:10BC90005E0214E00DF18202002306921A46079319 -+:10BCA00019E000210A460B4638460091F9F778FD65 -+:10BCB0000DF1820106910DF15E020DF19E03072147 -+:10BCC00007933EE00DF1E6030DF1EA01069308F15A -+:10BCD0008202079101230E9334E039A906913AAB11 -+:10BCE00008F18202012107932BE03BAB00930DF199 -+:10BCF000EF010DF1EE020DF1ED033846F9F74EFCC0 -+:10BD00009DF8EF209DF8EE300DF1BE0143EA0223CD -+:10BD10004FF00002ADF86C30ADF86E209DF8EC30BD -+:10BD20009DF8ED20069143EA0223ADF870304FF004 -+:10BD30000003ADF872300DF1C6030DF15E020793FA -+:10BD400004210E911023009330330193504B0021B6 -+:10BD5000029338460B23F6F7A7FE05224D493846D5 -+:10BD6000F6F72EFD3846F9F7D9F84FF4805213460E -+:10BD7000089040F2A4413846F6F70EFD00213846FF -+:10BD8000FEF79AF940F2DB413846F6F7D3FC424918 -+:10BD9000062209903846F6F713FDB7F8DA3003F4B7 -+:10BDA0007043B3F5005F07BF38463C4938463C490D -+:10BDB0001222F6F705FD40F2D7413846F6F7BAFCF5 -+:10BDC000059911903846FBF7BFFE384640F23B41DB -+:10BDD000F6F7B0FCC0F380100C9020B138460DF19E -+:10BDE000B601F8F7E9FF64B90C9A22B93846B8F8F9 -+:10BDF0003010FEF7B3FD0DF1CE0438462146F8F7BA -+:10BE0000DBFF638822881B0143EA0223A2882146C4 -+:10BE100013439EB2B7F8DA30082203F470430DF1F1 -+:10BE2000D600B3F5805F14BF00250125E6F3A4F02A -+:10BE30000A222BA80021E6F303F11A4B002233F863 -+:10BE40001540104633E0184B53F82530C1180B88C5 -+:10BE50001230B3422AD14B882BA8ADF8D6308A884D -+:10BE6000ADF8D82031F8063F0A22ADF8DA30E6F313 -+:10BE700083F01EE078090200CE0E020022080200C4 -+:10BE800058050200BC0A02005A080200900702008E -+:10BE900019880100D806020024090200FC0C0200E7 -+:10BEA00030090200720C0200F80C02000132A242BA -+:10BEB000C9D138460DF1D601F9F748F9002404221A -+:10BEC00038463749374DF6F77BFC10260A233846AB -+:10BED0002146354A009601940295F6F7E5FD2023A8 -+:10BEE000019338460A2321462F4A00960295F6F719 -+:10BEF000DBFD40F25341384640F2A472F6F726FCCF -+:10BF0000B8F8C81340F6A663A14208BF1946B9F1B4 -+:10BF1000050F01D14B4299B2D7F8FC3F0CB22BB1BF -+:10BF20003846FDF7EFFD0520EAF316F44FF47A7179 -+:10BF300001235822384604FB01F1FDF767FA40F26D -+:10BF4000DA614FF6FF723846F6F700FCB7F8DA30E0 -+:10BF5000384603F47043B3F5005F0CBF98F895952D -+:10BF600098F89695F8F7B4FF0021C0B2FF228B46EF -+:10BF700010900D910F929AE04FF000030799ADF8E1 -+:10BF8000E0303BF80130C3F30324B9F1000F1AD0BD -+:10BF9000042C0BD00F9A042A13D110990EE0C0463E -+:10BFA000A20A020019880100640B0200109901EB3B -+:10BFB0000903D9B211F0800F18BF7F213846FEF770 -+:10BFC00081FAE2B20F92069B3CA93BF8032001EBF9 -+:10BFD000440333F8441C21B102F0FF0343EA012378 -+:10BFE0009AB2384640F25241F6F7B0FBE31E1FFA10 -+:10BFF00083FABAF1010F16D86D4B10254524029330 -+:10C00000384600210DF1E202012300950194F6F774 -+:10C010003DFD684B38460293002138AA0123009564 -+:10C020000194F6F741FD079B384640F251413BF839 -+:10C030000320F6F78BFB3846F9F72EFF00287CD05B -+:10C040005B4A602112AC10250B2301910292002162 -+:10C05000384622460095574EF6F718FD40230193C7 -+:10C0600000210B233846224600950296F6F71CFD68 -+:10C07000BAF1010F0AD845230193384600210DF18A -+:10C08000E202012300950296F6F70EFD484960236F -+:10C090000193029108F18202384600210B2300959A -+:10C0A000F6F7F4FC0D9A0BF1020B01320D920D9B89 -+:10C0B0000E998B427FF460AF602301933C4B08F1F3 -+:10C0C0008206102402933846002132460B23394D54 -+:10C0D0000094F6F7DBFC4FF001025023A8F89820FB -+:10C0E0003846019300213246042300940295F6F766 -+:10C0F000DBFC552301933846002108F18C02022312 -+:10C1000000940295F6F7D0FC3846F8F74FFCA0B142 -+:10C1100038A90DF1DE023846FCF750FB3846FCF733 -+:10C12000EDF9BDF8E0100446BDF8DE203846FDF715 -+:10C1300085FD38462146FDF713FB049B13B93846AD -+:10C14000FDF7E0FC38460599F9F714FB384640F254 -+:10C15000D741119AF6F7FAFAFB69059998683022E7 -+:10C16000EAF3C6F5384640F2DB41099AF6F7EEFAF3 -+:10C1700040F2534138460022F6F7E8FA0C9921B113 -+:10C1800038460DF1B601F8F7E1FF38460899FDF79A -+:10C1900093FF384640F2DA610A9AF6F7D7FA384642 -+:10C1A00040F2DB610B9AF6F7D1FA3DB0BDE8F08FB3 -+:10C1B00015820100198801002DE9F0470546D0F8E5 -+:10C1C000A8404FEA0118F8F783FE40F2D74147B282 -+:10C1D0002846F6F7AFFA94F925258146B2F1FF3FDC -+:10C1E00011D0042392FBF3F3984505DA284640F278 -+:10C1F000D7414022002304E04022284640F2D741A4 -+:10C200001346F6F7C9FAD5F8FC3F53B12846FDF7B7 -+:10C2100079FC0520EAF3A0F21C492846702200238D -+:10C2200002E01A4928467022FDF7F0F82846394600 -+:10C23000FEF794FB002601212846FBF76FFD04233F -+:10C24000C8EB00047A1E94FBF3F3D2187F2AA8BF30 -+:10C250007F2222EAE277284639460434FEF77EFB45 -+:10C26000082C03D90A2E01D00136E4E72846FDF751 -+:10C2700049FC284640F2D7414A46F6F767FA284675 -+:10C28000F8F726FE40B2BDE8F087C04600093D0041 -+:10C290002DE9F04391B08046D0F8A860F8F718FE79 -+:10C2A0001C23B8F8DA208DF83B3001238DF83A30A2 -+:10C2B00002F47043B3F5805F5FFA80F907D1D3B21F -+:10C2C000402B01D81B2300E02D238DF83B30B8F81C -+:10C2D000DA2002F47043B3F5005F33D1B6F82A25B3 -+:10C2E00013B2B3F1FF3F04D04FF6FF73002A08BF2B -+:10C2F0001A46B6F8F6130BB2B3F1FF3F02D14FF472 -+:10C30000917104E04FF6FF73002908BF1946B6F893 -+:10C310002C5596F8F0032BB2B3F1FF3F04D04FF643 -+:10C32000FF73002D08BF1D46B6F8F84323B2B3F1E2 -+:10C33000FF3F04D04FF6FF73002C08BF1C4696F851 -+:10C34000F1739FE0D3B2402B33D8B6F82E2513B249 -+:10C35000B3F1FF3F04D04FF6FF73002A08BF1A461F -+:10C36000B6F8FA130BB2B3F1FF3F02D14FF491715B -+:10C3700004E04FF6FF73002908BF1946B6F83055A0 -+:10C3800096F859052BB2B3F1FF3F04D04FF6FF7377 -+:10C39000002D08BF1D46B6F8004423B2B3F1FF3F9D -+:10C3A00004D04FF6FF73002C08BF1C4696F85B754F -+:10C3B00068E08C2B33D8B6F8322513B2B3F1FF3FC7 -+:10C3C00004D04FF6FF73002A08BF1A46B6F8FC13D4 -+:10C3D0000BB2B3F1FF3F02D14FF4917104E04FF67D -+:10C3E000FF73002908BF1946B6F8345596F8F203D2 -+:10C3F0002BB2B3F1FF3F04D04FF6FF73002D08BFFF -+:10C400001D46B6F8024423B2B3F1FF3F04D04FF605 -+:10C41000FF73002C08BF1C4696F8F37332E0B6F8A1 -+:10C42000362513B2B3F1FF3F04D04FF6FF73002A55 -+:10C4300008BF1A46B6F8FE130BB2B3F1FF3F02D1A4 -+:10C440004FF4917104E04FF6FF73002908BF1946BD -+:10C45000B6F8385596F85A052BB2B3F1FF3F04D021 -+:10C460004FF6FF73002D08BF1D46B6F8044423B2F3 -+:10C47000B3F1FF3F04D04FF6FF73002C08BF1C46FA -+:10C4800096F85C7513B2B3F1FF3F04D040461946ED -+:10C49000FFF792FE0DE009B2B1F1FF3F07D0404631 -+:10C4A0000DF13202FFF728F89DF83B3007E0FF2836 -+:10C4B00002D086F8070404E09DF83B300BB186F803 -+:10C4C000073429B2B1F1FF3F05D04046FFF774FEB3 -+:10C4D00086F8080411E021B2B1F1FF3F09D04046CF -+:10C4E0000DF13202FFF708F89DF83B3086F808346A -+:10C4F00003E0FF2F18BF86F8087496F9EF33B3F105 -+:10C50000FF3F1CBF4FF0FF3386F8083496F808044D -+:10C5100041B2B1F1FF3F76D096F8072453B2994269 -+:10C52000D8BF86F8082496F80834D8BF86F80704E0 -+:10C5300000248DF83B30DB2301250393404623463E -+:10C5400021460DF132020495009401940294059461 -+:10C55000FEF72CFD18230993083308950B93254605 -+:10C5600007AC0FAB4046214607930A95FBF752FEF6 -+:10C5700005F140034046214601350A93FCF74CF98A -+:10C58000402DEDD196F9072496F908349B18022224 -+:10C5900093FBF2F3A6F86835B8F8DA2002F470439A -+:10C5A000B3F5005F02D1B6F85E3583B9D3B2402B44 -+:10C5B00005D8B6F8602512B1A6F8682509E08C2BDD -+:10C5C00002D8B6F8623513B9B6F864350BB1A6F8DF -+:10C5D0006835404640F224514FF400420023F6F7FC -+:10C5E000DBF896F96625B6F86835013293FBF2F36D -+:10C5F0009BB2404640F22551FF22F6F7CDF80223C8 -+:10C6000086F8673529E0012386F86735404640F211 -+:10C610002551FF227E33F6F7BFF8404640F2255100 -+:10C620004FF480720023F6F7B7F8404640F22551E8 -+:10C630004FF400720023F6F7AFF8404640F2255160 -+:10C640004FF480620023F6F7A7F8404640F22551E8 -+:10C650004FF400620023F6F79FF84FF00003A6F8AE -+:10C660006A35404640F2255196F96645F6F762F87C -+:10C670000134C0B204FB00F496F96635A6F86845AB -+:10C6800013B14046FCF72CFD96F8EF330DF1320262 -+:10C69000FF2B08BF96F8073400218DF83B30DB23D1 -+:10C6A00003930123049340460B46009101910291AC -+:10C6B0000591FEF77BFC40464946FEF74FF94046A0 -+:10C6C00040F27161F6F736F8B6F96A3540F27161F9 -+:10C6D000A0EBC30292B24046F6F738F84046FBF7AB -+:10C6E00093FE11B0BDE8F08370B58E46BEF1FF3FFA -+:10C6F0000546144619469DF9106002D006EB0E015E -+:10C700000DE022B990F82916FFF756FD02E0B2F1CC -+:10C71000FF3F04D021462846FFF74EFD81192846E9 -+:10C72000FEF71CF970BDC0462DE9F04F87B00446F6 -+:10C73000F8F7F4FB04A981462046D4F8A850F8F78E -+:10C740003BFB2046F8F7BCFB40F2D741834620462E -+:10C75000F5F7F0FF03902046FCF74AF88246B9F15E -+:10C76000000F02D0FF23029304E02046F8F7B0FB4D -+:10C7700040B20290B4F8DA304FF02A0803F4704364 -+:10C78000B3F5005F0CBF95F81E1595F81F152046F0 -+:10C790004FB239460F223C23CDF80080FFF7A4FFAB -+:10C7A00095F84665002E00F09080204640F2EB415F -+:10C7B000F5F7C0FF1221C0F3402301222046F5F710 -+:10C7C0008DFF6A780021521A18BF01220B462046BD -+:10C7D000FFF7F2F92046FBF791FE40F3072340B242 -+:10C7E000A5F84A35A5F84C0540F2EB412046F5F78F -+:10C7F000A1FFC0F380235B02204640F2EB414FF4DF -+:10C800000072F5F7C9FF002107220B462046FFF70B -+:10C81000D3F92046FBF772FE40F3072340B2A5F898 -+:10C820004E35A5F85005FF222046B5F84A3540F6AA -+:10C830005211F5F7B1FF2046FF22B5F84C3540F60E -+:10C840005311F5F7A9FF2046FF22B5F84A3540F607 -+:10C850005611F5F7A1FF2046FF22B5F84C3540F6FA -+:10C860005711F5F799FF2046FF22B5F84E3540F6EF -+:10C870004811F5F791FFFF222046B5F8503540F6F4 -+:10C880004911F5F789FF95F84A3595F84C1520467A -+:10C8900041EA0321FCF764FF95F8473520469B02E7 -+:10C8A00040F2EB414FF4806203F47C43F5F774FFF0 -+:10C8B00095F8483520465B0240F2EB414FF4007298 -+:10C8C00003F47E43F5F768FF10E0204639460F2257 -+:10C8D0003C23CDF80080FFF707FF6A7820463146F9 -+:10C8E000003A18BF01223346FFF766F92046F8F7F1 -+:10C8F0004BF810B12046FBF715FE00217F220B46B6 -+:10C900002046FCF7DDFC20465146FDF7C7FD2046DA -+:10C910005946F8F7CFFB204604A9F8F717FC204644 -+:10C9200040F2D741039AF5F711FFB9F1000F04D097 -+:10C9300020464946FDF7C0FB03E020460299FEF77A -+:10C940000DF807B0BDE8F08F2DE9F04F89B004462F -+:10C95000D0F8A870F8F7E2FA04902046F8F7B8FA91 -+:10C960004FF489715FFA80FA2046F5F759FE0721E6 -+:10C9700005902046F5F754FEFF2101902046F5F77B -+:10C980004FFE40F21F1102902046F5F749FE40F29B -+:10C99000AB4103902046F5F7CDFED4F8B030D3F884 -+:10C9A000203183F0010313F0010B03D1E36918690F -+:10C9B00033F0F0DE00212046FDF77EFB2046F6F73F -+:10C9C00077FB40F23B412046F5F7B4FE0DF1180924 -+:10C9D000494680462046F8F7EFF920460121F8F74E -+:10C9E0007DFB20467F21FDF7B9FF0122134620463B -+:10C9F0000721F5F773FE102213462046FF21F5F7B5 -+:10CA00006DFE0422134640F21F112046F5F766FE24 -+:10CA10002046FDF74FFC06224B492046F5F7D0FE95 -+:10CA20002046FBF7E5FE002106462046FDF736FDD1 -+:10CA3000002220460121F7F745FA40F2AB4120469B -+:10CA4000F5F778FE40F23E612046F5F773FEC50526 -+:10CA5000ED0D2B46204640F2A64140F2FF12F5F7BD -+:10CA60009BFE97F8E8330BB3204638490922F5F7C7 -+:10CA7000A7FE002220460121F7F724FA40F2AB413D -+:10CA80002046F5F757FE40F23E612046F5F752FE8C -+:10CA9000C30540F29A41204640F2FF12DB0DF5F744 -+:10CAA0007BFE20462A490922F5F78AFE2B462046BE -+:10CAB00040F2A64140F2FF12F5F76EFE00234FF45C -+:10CAC0008052204640F24C41F5F766FE2046314642 -+:10CAD000FDF7E4FC2046C8F38011F8F7FFFA204682 -+:10CAE0004946F8F733FB20465146FDF737FF20460D -+:10CAF0000499FDF7E1FA20464FF48971059AF5F79C -+:10CB0000A7FD019D012205EA020320460721F5F752 -+:10CB1000E5FD029D102205EA02032046FF21F5F7FC -+:10CB2000DDFD039D0422204640F21F1105EA0203A9 -+:10CB3000F5F7D4FDBBF1000F03D1E369186933F0B9 -+:10CB400015DE09B0BDE8F08FD80C0200E205020046 -+:10CB5000E40C02002DE9F3410446F8F7DFF9E3693C -+:10CB6000D4F8A8501A6A04F580531A6094F8DA30A1 -+:10CB7000002685F8BC3241F20403E654D4F8B03004 -+:10CB80008046D3F8203183F0010313F001070AD166 -+:10CB9000E369B821186942F2107233F0C9DDE36924 -+:10CBA000186933F0F7DD20460121F9F7B1FE0F22B5 -+:10CBB00023492046F5F704FE2046F8F775FD204688 -+:10CBC0003146FCF7CDFD204631463246FDF736F8BA -+:10CBD0002046F6F76DFA41F22403E35C6BB1204680 -+:10CBE000FFF7B2FE20463146FDF74EF995F8E833DF -+:10CBF0001BB120460121FDF747F92046FFF794FDC0 -+:10CC000000217F230A46009320460123FDF7C6FF3B -+:10CC10004FF0FF3385F8073485F808342046FFF7D6 -+:10CC200037FB20464146FDF747FA20460021F9F739 -+:10CC30006FFE1FB9E369186933F098DDBDE8FC8128 -+:10CC4000DA070200082910B503D00A2904D0022906 -+:10CC500004D1FFF77FFF01E0FEF794FD10BDC04651 -+:10CC600010B50446F6F724FA20460021FDF724FA11 -+:10CC700020460821FFF7E6FF10BDC04670B541F21F -+:10CC80000403C35C0446D0F8A85013B9F7F70CFFAF -+:10CC9000F0B1D4F8F83013F0070F06D194F8F5305E -+:10CCA0001BB920460921FFF7CDFFD4F8F82012F078 -+:10CCB0000F0F0DD141F20C03E3564BB912F0800F68 -+:10CCC00006D194F8F5301BB920460221FFF7BAFFD0 -+:10CCD000D4F8F83013F00E0F02D12046F9F752F9CC -+:10CCE000D4F8F83013F0060F3ED1D5F8340448B329 -+:10CCF000E169D5F838240B6A9B1A834234D308695A -+:10CD00006A2133F0F7DC400081B2B1B1E369186900 -+:10CD100033F0F0DC88B940F276412046F5F70AFDA1 -+:10CD2000C005C00DA5F86C0540F277412046F5F727 -+:10CD300001FDC005C00DA5F86E0520460021F9F7DC -+:10CD40004BFF11E040F276412046F5F7F3FCC005B9 -+:10CD5000C00DA5F86C0540F277412046F5F7EAFCD6 -+:10CD6000C005C00DA5F86E052046F8F7D7F8B0F558 -+:10CD7000404F0CD02046F8F7ABF8C0B220B10023EA -+:10CD80007F2885F8563402D0002385F8573470BDCB -+:10CD90002DE9F047CCB20746D0F8A8602046894676 -+:10CDA000F5F7DEFE494680463846F5F7BBFE3846C5 -+:10CDB000B7F8DA10FBF758F9042238465B49F5F763 -+:10CDC000FFFC21463846FAF7B5F90A20E9F3C4F426 -+:10CDD0004FF4004213464FF489613846F5F7DCFC06 -+:10CDE0003846F8F78DFB052100224FEA4800F7F797 -+:10CDF000B1FC0022054641464FF42010F7F7AAFC8B -+:10CE000040F257610446AAB23846F5F79FFC38460F -+:10CE10004FF4CB61A2B2F5F799FC4FF4007338469A -+:10CE20004FF489614FF44072F5F7B6FC97F8DA30A9 -+:10CE30000E2B01D11E2206E0B6F8622013B2B3F128 -+:10CE4000FF3F08BF1522A6F840253846002112B240 -+:10CE5000FBF7E2FB20B1384600211422FBF7DCFB94 -+:10CE600097F8DA3038220E2B0CBF182300233846EF -+:10CE700040F2EB41F5F790FCB7F8DA30384603F4AE -+:10CE80007043B3F5005F0CBFB6F86620B6F86820B3 -+:10CE9000012113B2B3F1FF3F08BF0222A6F83E25DD -+:10CEA00012B2FBF7B9FB182238462149F5F788FC86 -+:10CEB0003846F6F70DF996F8BC2298B10E2AB7F865 -+:10CEC000DA3003D9DBB20E2B03D805E0DBB20E2B30 -+:10CED00002D83846012101E0384600214A46FCF7D5 -+:10CEE000A1FF21E097F8DA309A4201D1012A04D15A -+:10CEF00038460821FFF7A6FE02E03846FCF776FF29 -+:10CF000000210A463846FBF753FD3846F9F7B6F9D3 -+:10CF100038460121F9F76AFA41F22403FB5C1BB1A0 -+:10CF200038460321FBF70AF9BDE8F08792050200B5 -+:10CF30002A080200D0F8B03073B5D3F82031044687 -+:10CF400083F0010313F00106D0F8A85003D1C369A0 -+:10CF5000186933F01FDC41F22403E25C42BBB4F8F1 -+:10CF6000DA3003F47043B3F5005F08D14FF00403E7 -+:10CF7000ADF800304FF00C03ADF8023007E04FF091 -+:10CF8000FF03ADF80030ADF802304FF0F00320465B -+:10CF90006946ADF80430ADF80620F8F7D7F820461A -+:10CFA0009621FDF77BFA20460121FEF7BDFC56E0F5 -+:10CFB0002046FFF7C9FC2046FDF756F82046002121 -+:10CFC000FCF762FF204635490F22F5F7F9FB95F88B -+:10CFD000E833DBB120460121FCF756FF95F92435F3 -+:10CFE000204640F2D141FF229BB2F5F7D5FB95F8E0 -+:10CFF0002535204640F2D1414FF47F421B02F5F720 -+:10D00000CBFB204626490C22F5F7DAFB0522204609 -+:10D010002449F5F7D5FBD4F8A8202046D2F84434AB -+:10D02000D2F848243C2BA8BF3C239342B8BF1346F8 -+:10D0300040F2A741FF229BB2F5F7AEFBB4F8DA301D -+:10D04000204603F47043B3F5005F0CBF95F85434E9 -+:10D0500095F855344FF440412B86FDF72DF840F2FA -+:10D0600076412046F5F766FBC005C00DA5F86C05B6 -+:10D0700040F277412046F5F75DFBD5F83434C00522 -+:10D08000C00DA5F86E051BB120460121F9F7A4FDDE -+:10D090001EB9E369186933F069DB7CBD4A0E0200F2 -+:10D0A0002A070200100A02002DE9F041D0F8A8601A -+:10D0B000012386F86130013B86F8C033B0F8DA30DE -+:10D0C000074603F47043B3F5005F02D196F8C1330D -+:10D0D00004E0B3F5805F06D196F8C233022B02D18B -+:10D0E000012386F8C033B7F8DA30384603F47043CA -+:10D0F000B3F5805F0CBF96F8EB3396F8EA33002463 -+:10D1000086F8E933738B0125A6F8BE320422234941 -+:10D11000347086F8C24286F8C34286F8C44286F864 -+:10D120006755F5F74DFB38462946F8F721FA0422F2 -+:10D130001B493846F5F744FB3846FCF7A1FA384658 -+:10D14000FCF7DCFC3846FFF7F5FE86F82C40B7F814 -+:10D15000DA103846F6F784FD3846FBF765F84FF4E9 -+:10D16000804213464FF489613846F5F715FB642079 -+:10D17000E9F3F2F2234638464FF489614FF48042D6 -+:10D18000F5F70AFB38464FF44041FCF795FF41F2B2 -+:10D190008833F38686F89A55BDE8F08122070200AD -+:10D1A000040C020010B58068F2F36AF210BDC046AC -+:10D1B00010B5437902790C4642EA032E0EF00303C0 -+:10D1C000012B0AD0022B0ED013B14FF400702EE0C9 -+:10D1D0000A780523B2FBF3F029E00B78144A03F038 -+:10D1E0000703D05C23E00978E378227911F0800FFF -+:10D1F00043EA022201F07F0343F0006002D040F4D2 -+:10D20000806006E01EF0200F1CBF20F4E06343F4B2 -+:10D21000407012F0800F18BF40F4000012F0400F71 -+:10D2200018BF40F48000C2F3011340EA035010BD60 -+:10D2300050FD010070B585680446D4F8F811A8685F -+:10D24000F2F30CF24FF0FF3384F8E231A36123686C -+:10D2500000229A712B6B064602211869F5F732FC01 -+:10D26000204636F00FDDD6F1010038BF002070BD3A -+:10D2700070B50D460968044671B1D1F87C1129B129 -+:10D28000036840F20C72D868E9F332F52368296824 -+:10D29000D8686269E9F32CF523682946D86810221A -+:10D2A000E9F326F570BDC04637B5054601A9D0F8AB -+:10D2B000000537F00FDF09E02846214638F06AD92B -+:10D2C000636C1BB92846214638F07ADA01A837F09A -+:10D2D00009DF04460028EFD13EBDC046036870B5A3 -+:10D2E00010210546D868E9F3F3F408B9064615E0BD -+:10D2F0002B6806466969D868E9F3EAF404463060A9 -+:10D3000028B931462846FFF7B3FF264606E000233A -+:10D31000C0F87C313146284637F0BCDD304670BD60 -+:10D320002DE9F3470D469246002853D0002951D0ED -+:10D330000B88D0F80490D0F89843D0F89463002B71 -+:10D340004BD00027E780A7804B880A8813F001089C -+:10D3500024D0402A14D1043120463B4600973BF0AC -+:10D36000DBDFB8423BDBB6F8023113F0400F34D0BC -+:10D37000BAF1000F31D0D9F80C003AF06FDF0BE0B2 -+:10D38000A2F108039BB2372B29D804F1080004311D -+:10D39000E4F3F2F52D88A580384622E0202A19D83A -+:10D3A000043104F14800E4F3E7F5A4F804802D8883 -+:10D3B0000123E580C6F8CC30B6F8023113F0400FF7 -+:10D3C0000BD0BAF1000F08D0D9F80C003AF046DFC4 -+:10D3D000404606E06FF0010003E0002001E04FF05E -+:10D3E000FF30BDE8FC87C04610B50DF09DFD04463A -+:10D3F000F1F7AAFF2046E8F3BDF710BDAAAA030083 -+:10D400001958000040960000904C00001472000073 -+:10D41000101800000FAC000050F2000050F20100A4 -+:10D420000050F20200000050F2020100AAAA03001C -+:10D43000195800000000000050F2040000147200AF -+:10D44000000FAC000050F200001018000050F20075 -+:10D45000000FAC0000409600000000000000101813 -+:10D4600000696C306D6163616464723D30303A31E3 -+:10D47000313A32323A33333A34343A353500626F26 -+:10D48000617264747970653D3078666666660062C4 -+:10D490006F6172647265763D3078313000626F6121 -+:10D4A0007264666C6167733D38006161303D3300C2 -+:10D4B00073726F6D7265763D3200AAAA0300195827 -+:10D4C000000050F200000000594D80009557800088 -+:10D4D00049588000315680000D5A8000C1588000A4 -+:10D4E000295A8000455A8000795780004D568000A7 -+:10D4F000755A800025558000F15980000D58800034 -+:10D5000069548000C14E8000E9518000555280006E -+:10D51000C9518000DD58800051518000D1558000F4 -+:10D52000A555800015568000E14F80008955800088 -+:10D53000FD4E800025508000C9110100ED4D800096 -+:10D54000854E8000A94F8000D94D8000094E800093 -+:10D55000514C8000654C800000000000000000007D -+:10D5600000000000C14F800025528000F95180006A -+:10D57000E12800002800000073645F6C6576656C2C -+:10D580005F74726967676572007370695F70755F59 -+:10D59000656E6162006172705F6D61636164647287 -+:10D5A000006172705F72656D6F7465697000000074 -+:10D5B000F83B86000000000007000000FF3B8600EB -+:10D5C00001000000070000000B3C86000200000084 -+:10D5D000000000001B3C8600030000000700000064 -+:10D5E000263C86000400000000000000373C860056 -+:10D5F0000500000008003000413C860006000000E5 -+:10D600000000000095D501000800000006000000A1 -+:10D61000A1D5010009000000070000000000000083 -+:10D62000000000000000000070666E5F737573708C -+:10D63000656E640058408600000000000800140079 -+:10D6400060408600010000000800880068408600F5 -+:10D65000020000000800380070408600030000004F -+:10D66000080008007E408600040000000100000061 -+:10D670008240860005000000000000008B4086000C -+:10D68000060000000800380028D60100070000004E -+:10D690000100000000000000000000000000000089 -+:10D6A000352E39302E3139352E38392E3600776CFB -+:10D6B00025643A2025732025732076657273696F7F -+:10D6C0006E20257320465749442030312D25780A95 -+:10D6D0000041707220323220323031330031343A1E -+:10D6E00035303A3030000000DA4386000000000098 -+:10D6F00008000000E3438600010000000100000074 -+:10D700000000000000000000000000005C782530F0 -+:10D71000325800253034780A007478636861696E85 -+:10D72000007278636861696E00776C635F696F7619 -+:10D730006172733200727373695F6F6666736574CA -+:10D740000064796E74785F7164626D5F6F76657284 -+:10D75000726964650064796E74785F726174655F84 -+:10D76000616C6C00505A443A2025643E2564206F59 -+:10D77000722025643E256420613D25640A006F7493 -+:10D780007077006164640064656C006C6F775F7231 -+:10D790007373695F74726967676572006C6F775F36 -+:10D7A000727373695F6475726174696F6E0074631C -+:10D7B0005F656E61626C650074635F706572696F4E -+:10D7C000640074635F68695F776D0074635F6C6F9A -+:10D7D0005F776D0074635F73746174757300617358 -+:10D7E000736F635F73746174650064796E7478003D -+:10D7F00074785F737461745F63686B0074785F73CF -+:10D800007461745F63686B5F7072640074785F73D7 -+:10D810007461745F63686B5F726174696F007478C0 -+:10D820005F737461745F63686B5F6E756D007278AF -+:10D830005F726174650069735F5750535F656E7204 -+:10D840006F6C6C65650069735F7770735F656E728E -+:10D850006F6C6C65650002000000000035D70100A8 -+:10D8600001000000060000008BD70100020000004C -+:10D87000060000009CD70100030000000600000025 -+:10D88000AED701000400000006000000B8D7010078 -+:10D890000500000006000000C2D7010006000000DD -+:10D8A00006000000CBD701000700000006000000C2 -+:10D8B000D4D701000800000006000000DED70100F8 -+:10D8C0000900000006000000EAD701000A0000007D -+:10D8D00006000000F0D701000B0000000600000069 -+:10D8E000FCD701000C000000060000000CD801006D -+:10D8F0000D000000060000001ED801000E00000010 -+:10D90000060000002ED801000F00000006000000F5 -+:10D9100036D80100100000000100000046D80100C8 -+:10D9200010000000010000000000000000000000E6 -+:10D930000000000005A58100FDA581000000000099 -+:10D94000000000000DCD820089E68200F5CB820048 -+:10D95000EDCC820067898600000080000100000095 -+:10D96000458B860001000000080002004F8B8600F6 -+:10D970001D000000080002005C8B86000F00000004 -+:10D98000030000006A8B8600100080000700000082 -+:10D990007A8B860002000000080007008B8B86004F -+:10D9A00003000000080007009C8B86000400800034 -+:10D9B00001000000AE8B860006000000020000009F -+:10D9C000B98B86000C00000002000000C88B8600A6 -+:10D9D00021008000030000000000000000000000A3 -+:10D9E000000000004CDB01001000000006000000F9 -+:10D9F000529B860001000000010000005D9B860034 -+:10DA000002002000070000006F9B8600030040001A -+:10DA1000080007007C9B860004004000080004000A -+:10DA20008B9B860005004000080004009A9B86003E -+:10DA300006000000080004004FDB01000D0010008C -+:10DA400007000000A79B86000E00200007000000D2 -+:10DA5000B49B86000700100007000000BF9B8600F3 -+:10DA6000080000000800100058DB01000900000059 -+:10DA700006000000C99B860024000000060000008C -+:10DA80005CDB01000A00000006000000AB728600AB -+:10DA90000F00000001000000D59B86000B008000F5 -+:10DAA00001000000DA9B86000C0000000500000069 -+:10DAB000E59B86001D00000003000000FA9B860025 -+:10DAC0001E00000007000000139C86001F000000DD -+:10DAD00007000000259C86002100000005000000D2 -+:10DAE0003B9C86002000000003000000499C86004B -+:10DAF00011008000010000004F9C860018004000CB -+:10DB000008000600539C8600190000000500000074 -+:10DB1000619C86001A000000010000006C9C8600D9 -+:10DB20001B00400001000000000000000000000099 -+:10DB3000000000000050F20201010000013200006C -+:10DB400027A4000041325E0061212F006170006D4A -+:10DB500061786173736F63006273730073736964D8 -+:10DB600000092F160E0E057573696E6720703270EE -+:10DB7000206D6963726F636F64650A00776C25645A -+:10DB80003A205048595458206572726F72282564A3 -+:10DB9000290A000091BA8600000080000100000000 -+:10DBA00030BB860002000000080044003ABB86003B -+:10DBB000030000000800440044BB8600040000008D -+:10DBC000080000004FBB860005000000080044006C -+:10DBD00059BB8600060000000800000067BB8600F5 -+:10DBE0000700000008004C0074BB8600080000001D -+:10DBF00008004C0081BB8600090080000200000084 -+:10DC000000000000000000000000000054545454C4 -+:10DC10005400000000000000000050505050500020 -+:10DC200000000000000000002300000003000000CE -+:10DC300000084C4C4C4C4C4C1414140000010000D7 -+:10DC400064646464646464646464646464000000C0 -+:10DC5000000000000000000000000000013C424203 -+:10DC6000424242424242423C0000000000000000AA -+:10DC700000000000000000000000344A4E4E4E4EEE -+:10DC80004E4E4E4A38000000000000000000000028 -+:10DC9000000000000000004C4C4C4C4C4C4C4C4CD8 -+:10DCA0004C4C4C4C00000040404040404040000084 -+:10DCB00000000001030000000001424242324242E3 -+:10DCC0001414140000000000030000000008444485 -+:10DCD0004438444414141400000000000300000001 -+:10DCE00000013E3E42343E42141414000000000085 -+:10DCF00054545400540000000000000000000000D4 -+:10DD000000000000000000000000000023000000F0 -+:10DD1000030000000001444444384440141414003B -+:10DD200000000000484A4A4A4A4A4A4A4A4A4A4A7D -+:10DD300048000000343434343434343434000000C7 -+:10DD4000004E4E4E4E4E4E4E4E4E4E4E4E4E0000DD -+:10DD50000000000000000000000000000008545413 -+:10DD6000540054000000000000000000505050001B -+:10DD700050000000000000000000233A3E3800423E -+:10DD80000000000000000000000000000000000093 -+:10DD9000000000000000000A000000006400000015 -+:10DDA000000000000000000000005800000000001B -+:10DDB00000000000013242424242424242424232AC -+:10DDC00042420000000000000000000000000000CF -+:10DDD000000836444444444444444444364A4000E1 -+:10DDE0000000000000000000000000000000082EFD -+:10DDF0004444444444444444442E463A0000000011 -+:10DE00000000000000000000000000083C3E3E3E14 -+:10DE10003E3E3E3E3E3E3C3E3E00000000000000D6 -+:10DE2000000000000000000008344444444444441E -+:10DE3000444444384440000000000000000000005A -+:10DE40000000000000085C5C5C5C5C5C5C5C5C5C32 -+:10DE50005C5C5C00005050505050505050500000DE -+:10DE6000000001383E383E42000000000000000083 -+:10DE70000000000000000000000000000000000A98 -+:10DE80000100000000014E4E4E344C381E1E1E0094 -+:10DE90000000000003000000000142444230443012 -+:10DEA00014141400000000000300000000013E3EB6 -+:10DEB0003E3C3E3E1414140000000000030000002D -+:10DEC0000001444444364C3814141400000000008F -+:10DED0000300000000013E3E30363A2C14141400BA -+:10DEE000000000004242424242424242424242421A -+:10DEF000420000002E343434343434343400000012 -+:10DF0000004A4A4A4A4A4A4A4A4A4A4A4A4A00004F -+:10DF1000002E34343434343434340000000054548B -+:10DF20005400540000000000000000004848480071 -+:10DF300048000000000000000000233E3E3E4A0072 -+:10DF40000000000000000000002828284000000019 -+:10DF500000000000000000004644444A00000000A9 -+:10DF600000000000000000000000000000000000B1 -+:10DF7000000000000A545454005400000000000047 -+:10DF80000000004848480048000000000000000071 -+:10DF900000230000030000000000424242424242CF -+:10DFA00014141400000000000300000000003E3EB6 -+:10DFB0003E3E3E3E141414000000000054545454DD -+:10DFC0000000000000000000000050505050000011 -+:10DFD0000000000000000000233844444A4A0000CA -+:10DFE0000000000000000000000000000000000031 -+:10DFF00000000000000A00000000340000000000E3 -+:10E0000000000000000000003400000000000000DC -+:10E01000000000545454545400000000000000005C -+:10E020000048484848480000000000000000002365 -+:10E03000545454545400000000000000000050509C -+:10E04000505050000000000000000000235C5C5CA9 -+:10E050000050000000000000000000504850004444 -+:10E06000000000000000000000234C4C4C4C4C4CC5 -+:10E070004C4C4C4C4C4C4C0000000000000000008C -+:10E0800000000000000009000100000000013E3E09 -+:10E090003E323E361414140000000000010000005F -+:10E0A00000013E3E3E343E381414140000000000CF -+:10E0B0000100000000014242423C423C1E1E1E0084 -+:10E0C000000000000100000000014E4E4E364C38AA -+:10E0D0001E1E1E0000000000545454545400000042 -+:10E0E00000000000000048484848480000000000C8 -+:10E0F0000000000023000000006400000000000099 -+:10E1000000000000000000580000000000000000B7 -+:10E1100000010000030000000000464646484A484F -+:10E120001717170000000000610A86007E0A8600AB -+:10E130009B0A86000F0B8600490B8600660B860043 -+:10E14000630F8600240E8600410E860014108600A0 -+:10E150006B108600311086009C108600D01086005F -+:10E160000411860060118600B1118600830B8600C1 -+:10E17000A00B86000C0F8600F70B8600CE118600E0 -+:10E18000310C86006B0C860094118600DA0B860039 -+:10E190005E0E86004E0C8600290F8600B80A8600A7 -+:10E1A000D50A8600F20A86007B0E86004E10860095 -+:10E1B000BD0B8600980E86009D0F8600B50E86006A -+:10E1C000880C8600D20E8600140C8600290F86006B -+:10E1D000BA0F86002C0B8600440A8600800F86004A -+:10E1E000460F8600EF0E8600B5DD0100D2DD01008E -+:10E1F000EFDD01005DDC010024DD01000CDE01002B -+:10E2000001DF010046DE010097DC01006AE0010049 -+:10E2100040DC01007ADC010041DD010029DE010063 -+:10E22000E4DE010021E3010004E30100383838385E -+:10E2300038000000000000000000343434343400A2 -+:10E240000000000000000000003A3A3A3A460000A0 -+:10E2500000000000000000000000000000000000BE -+:10E26000000000000008384444444A000000000058 -+:10E27000000000000000000000000000000000009E -+:10E2800000002A0000000054000000000000000010 -+:10E290000000000000440000000000000000000139 -+:10E2A00018098600C00D8600E80D8600200D860046 -+:10E2B000AC0D8600DCDC01009CE00100C8E301003D -+:10E2C000A8DF010088E0010094DF0100B4DC010058 -+:10E2D00010DD010094DE0100B0E0010014E1010056 -+:10E2E000A8DE0100FCE3010080DE010078E301000C -+:10E2F00010E40100C4E00100BCDE0100D0DE01003A -+:10E30000C8DC010038444444444444444444384450 -+:10E31000440000002C3838383838303434000000DD -+:10E3200000343A3A3A3A3A3A3A3A3A3A2C2C00001D -+:10E3300000323C3C3C3C3C000000000000003E48F9 -+:10E3400048424600000000000000000000000000FD -+:10E35000000000000000000000000A0038383E42C3 -+:10E3600000000000000000000000000000000000AD -+:10E37000000000000000000A030000000000444408 -+:10E38000444C4C4C17171700000000003232323852 -+:10E39000000000000000000000003838383800009D -+:10E3A0000000000000000000004C0000004C0000D5 -+:10E3B00000000000000000500000005000000000BD -+:10E3C00000000000000100000300000000004242C5 -+:10E3D00042424242171717000000000054545400F4 -+:10E3E000000000000000000000005050500000003D -+:10E3F00000000000000000002300000003000000F7 -+:10E400000001444444344444141414000000000047 -+:10E410000300000000006464646464642424240035 -+:10E42000000100003CE486000000800001000000C4 -+:10E4300084E5860001000000080024008DE58600C8 -+:10E44000020000000100000096E5860003000000C5 -+:10E45000030000009EE586000400000008000000A4 -+:10E46000A7E586000500000008000200B1E586006F -+:10E470000600000008000800BBE586000700000059 -+:10E4800008000600C5E58600080000000800060038 -+:10E49000CCE586000900000008000200D4E58600F3 -+:10E4A0000A00000008000300DCE586000B00000005 -+:10E4B00007000000E9E586000C00000008000600E7 -+:10E4C000EDE401000D00000008000700F7E4010082 -+:10E4D0000E0000000100000000000000000000002D -+:10E4E000000000006368616E7370656300703270D5 -+:10E4F0005F6966757064007032705F646566696537 -+:10E5000000000000C8E686000000000008000C00C3 -+:10E51000D7E686000100000007000400E9E6860057 -+:10E520000200000008000800FBE68600030000006F -+:10E53000070004000BE786000400000008001C0030 -+:10E540001BE786000500000008000C002CE7860091 -+:10E55000060000000700040043E7860007000000F3 -+:10E560000700040094E50100080000000700040013 -+:10E57000A4E501000900000007000400B8E501005F -+:10E580000A000000080090000000000000000000E9 -+:10E5900000000000706B745F66696C7465725F697F -+:10E5A000636D7000706B745F66696C7465725F692F -+:10E5B000636D705F636E740077616B655F7061633C -+:10E5C0006B6574005365742042525054206174206E -+:10E5D00025780A000A465749442030312D25780A0B -+:10E5E000000A54524150202578282578293A207075 -+:10E5F000632025782C206C722025782C20737020C5 -+:10E6000025782C207073722025782C2078707372F6 -+:10E610002025780A00202072302025782C207231A5 -+:10E620002025782C2072322025782C20723320254A -+:10E63000782C2072342025782C2072352025782CD7 -+:10E640002072362025780A00202072372025782C69 -+:10E650002072382025782C2072392025782C2072C1 -+:10E6600031302025782C207231312025782C2072F1 -+:10E6700031322025780A000A20202073702B3020A8 -+:10E6800025303878202530387820253038782025F6 -+:10E690003038780A00202073702B31302025303834 -+:10E6A0007820253038782025303878202530387883 -+:10E6B0000A0073702B257820253038780A006465AD -+:10E6C00061646D616E5F746F007265636C61696D2A -+:10E6D0002073656374696F6E20313A2052657475DA -+:10E6E000726E656420256420627974657320746F8E -+:10E6F0002074686520686561700A007265636C61EA -+:10E70000696D2073656374696F6E20303A205265BD -+:10E710007475726E65642025642062797465732057 -+:10E72000746F2074686520686561700A0072616D9D -+:10E730007374627964697300706125643D30782573 -+:10E74000257800706425643D3078252578006E7644 -+:10E7500072616D5F6F7665727269646500000000BA -+:10E7600086060200D0090000800602003E3E00003E -+:10E77000820602003E020000000702003C0000008A -+:10E780008406020012020000600104000300010080 -+:10E7900064010200C00000006001040003000100E9 -+:10E7A000660102000A00000060010400040001008C -+:10E7B0006401020014000000600104000700010071 -+:10E7C00064010200830100006001040025000100D3 -+:10E7D00064010200F40100006001040096050100DC -+:10E7E000660102002B04000060010400970501008F -+:10E7F000640102000001000060010400D701010073 -+:10E80000640102003C00000060010400DC01010022 -+:10E81000660102003400000060010400E201010012 -+:10E82000640102003000000060010400E701010003 -+:10E83000660102002C00000060010400ED010100EF -+:10E84000640102002C00000060010400F2010100DC -+:10E85000660102002800000060010400F8010100C8 -+:10E86000640102002800000060010400FD010100B5 -+:10E870006601020028000000FFFF00000000000009 -+:10E880006001040005000103640104000000190098 -+:10E89000240104000400000028010400000000001E -+:10E8A0002C01040000000000300104000000000002 -+:10E8B000340104000A04700034010400EFBED400E7 -+:10E8C00034010400050000FF3401040001FF02FFD1 -+:10E8D0003001040018000000340104000A04E000C4 -+:10E8E00034010400EFBE480034010400050000FFBD -+:10E8F0003401040001FF02FF34010400001018017C -+:10E9000034010400020300103401040018F1F2F392 -+:10E9100034010400BBCC0000300104006806000094 -+:10E92000340104001404700034010400EFBE5801E7 -+:10E9300034010400000000FF3401040001FF02FF65 -+:10E94000340104000010180134010400020303091B -+:10E9500034010400BF000010340104000000000076 -+:10E960003001040038000000340104000000000001 -+:10E970003001040088060000340104001404800003 -+:10E9800034010400EFBE1802340104000000030942 -+:10E9900034010400BF00000334010400000102033D -+:10E9A00034010400040500013401040002030405DD -+:10E9B0003401040000000000300104005800000091 -+:10E9C00034010400000000003001040038000000A1 -+:10E9D000340104000F2000073401040000009400FB -+:10E9E000340104000000009034010400747576774F -+:10E9F00034010400000000003401040000000500A0 -+:10EA000034010400FFFFFFFF300104006802000032 -+:10EA1000340104006E84330034010400DCBA500079 -+:10EA200034010400D40000AB34010400BADABADACD -+:10EA300034010400001018F134010400F2F3001056 -+:10EA40003401040018F1F2F3340104001000000056 -+:10EA500034010400000000003401040000000A003A -+:10EA6000340104000100000E340104004252434D01 -+:10EA7000340104005F54455334010400545F535380 -+:10EA800034010400494401043401040082848B965B -+:10EA900034010400030101063401040002000000F7 -+:10EAA0003001040068000000340104000A04280258 -+:10EAB00034010400DCBA8000340104000000FFFFD0 -+:10EAC00034010400FFFFFFFF34010400001018F1BF -+:10EAD00034010400F2F300103401040018F1F2F3E1 -+:10EAE00034010400D0AF0000340104000000000035 -+:10EAF0003401040000000001340104000200000E93 -+:10EB0000340104004252434D340104005F54455324 -+:10EB100034010400545F5353340104004944010498 -+:10EB20003401040082848B96340104000301010641 -+:10EB300034010400020100003001040068040000F8 -+:10EB4000340104000A04280234010400DCBA800005 -+:10EB5000340104000000FFFF34010400FFFFFFFF49 -+:10EB600034010400001018F134010400F2F3001025 -+:10EB70003401040018F1F2F334010400D0AF0000B6 -+:10EB80003401040000000000340104000000000112 -+:10EB9000340104000200000E340104004252434DCF -+:10EBA000340104005F54455334010400545F53534F -+:10EBB00034010400494401043401040082848B962A -+:10EBC00034010400030101063401040002010000C5 -+:10EBD0000001040000000001900402000000000099 -+:10EBE000A0040200F1F30000B0040200EFFD0000F9 -+:10EBF000A8040200FFFF0000A804020000000000BB -+:10EC0000AA04020000000000A4040200CF1A0000C1 -+:10EC1000AC04020000000000BC0402000000000080 -+:10EC2000A6040200D7020000B6040200FFFD0000A7 -+:10EC3000AE040200FFFF0000060402000100000015 -+:10EC400006040200000000000C040200180000008E -+:10EC5000060402000000000048040200000C00004E -+:10EC600002040200A00700000205020000000000EC -+:10EC70000005020000400000020502000400000040 -+:10EC8000000502000040000002050200080000002C -+:10EC90000005020000400000020502000C00000018 -+:10ECA000000502000040000002050200C000000054 -+:10ECB00080050200FFFF000082050200FFFF000048 -+:10ECC00084050200FFFF000086050200FFFF000030 -+:10ECD00088050200FFFF00009C050200F0FF000015 -+:10ECE000400502000080000020050200060F000021 -+:10ECF0004005020000800000400502000081000085 -+:10ED000020050200101D00004005020000810000E7 -+:10ED10004005020000820000200502001E280000BD -+:10ED20004005020000820000400502000083000050 -+:10ED30002005020029310000400502000083000088 -+:10ED4000400502000084000020050200323F000060 -+:10ED5000400502000084000040050200008500001C -+:10ED6000200502004041000040050200008500002F -+:10ED700012060200010000002E060200CDCC0000A9 -+:10ED8000300602000C0000000006020004800000B3 -+:10ED900096060200080000009A060200E400000047 -+:10EDA00088060200000000009C060200020000002D -+:10EDB00088060200001000009C060200020000000D -+:10EDC00088060200002000009C06020002000000ED -+:10EDD00088060200003000009C06020002000000CD -+:10EDE000880602000B0F00009E06020007000000CC -+:10EDF000100502000B00000050040200014E00004C -+:10EE0000520402005B010000E404020090000000D4 -+:10EE100004040200B400000054050200FF3F00009B -+:10EE2000600104000400010364010400000000000C -+:10EE300064010400B40000006401040047004700BE -+:10EE40006401040000006400640104003009400013 -+:10EE5000600104000D0001036401040002000200CF -+:10EE6000640104000100800064010400050000004A -+:10EE70006401040000008000640104006400640078 -+:10EE8000640104000E004700640104000005000056 -+:10EE90006001040015000103640104000000420841 -+:10EEA00064010400E00B0700640104000A00000094 -+:10EEB000600104001A0001036401040000C0660B35 -+:10EEC000600104001D00010364010400102700001C -+:10EED0006401040000007A036001040020000103C3 -+:10EEE00064010400060010276001040023000103F0 -+:10EEF000640104000000F606640104000000AA0A90 -+:10EF00006401040000003200640104000A0E0B09D1 -+:10EF1000640104000E020000640104000000520AB3 -+:10EF20006401040000003F0164010400FFFF000CC5 -+:10EF30006401040032046E06640104000200F20958 -+:10EF4000600104002E000103640104000000008041 -+:10EF50006001040032000103640104000000320B70 -+:10EF60006001040034000103640104000000CC05CA -+:10EF70006001040058000103640104004252434D43 -+:10EF8000640104005F54455364010400545F53530B -+:10EF900064010400494400006001040060000103B2 -+:10EFA0006401040039000000640104005000000006 -+:10EFB00064010400C000000060010400700001034F -+:10EFC00064010400AA03AA0364010400AA03AA03BB -+:10EFD00064010400AA03AA0364010400AA03AA03AB -+:10EFE00064010400EC03D60364010400C003AA0317 -+:10EFF00064010400F703E10364010400CB03B503DB -+:10F0000064010400AA03AA0364010400AA03AA037A -+:10F0100064010400AA03AA0364010400AA03AA036A -+:10F0200064010400EC03D60364010400C003AA03D6 -+:10F0300064010400F703E10364010400CB03B5039A -+:10F0400064010400020402046401040002040204D6 -+:10F05000640104000E0402046401040002041A04A2 -+:10F0600064010400020402046401040002040204B6 -+:10F070006401040002040204640104002604020482 -+:10F080006401040002040204640104000204020496 -+:10F09000640104000E0402046401040002041A0462 -+:10F0A0006401040002040204640104000204020476 -+:10F0B0006401040002040204640104002604020442 -+:10F0C0006401040000001F0064010400FF031F002E -+:10F0D000640104000200000064010400020000005A -+:10F0E00060010400980001036401040000001F0097 -+:10F0F00064010400FF031F0064010400010000001C -+:10F10000640104000100000060010400A00001038C -+:10F110006401040000001F0064010400FF031F00DD -+:10F12000640104000100000064010400010000000B -+:10F1300060010400A80001036401040000001F0036 -+:10F1400064010400FF031F006401040001000000CB -+:10F15000640104000100000060010400B800010324 -+:10F1600064010400E700EC006401040000007B007F -+:10F17000640104007E00000064010400000000003F -+:10F180006401040000004F51640104003F000000CE -+:10F19000640104000000001060010400C0000103CD -+:10F1A0006401040037243724640104003724372421 -+:10F1B0006001040093010103640104000F0040009A -+:10F1C00064010400E60600006001040097010103E9 -+:10F1D000640104001A08000060010400A00101039A -+:10F1E00064010400FFFFFFFF64010400FFFFFFFF55 -+:10F1F00064010400FFFFFFFF64010400FFFFFFFF45 -+:10F2000064010400FFFFFFFF64010400FFFFFFFF34 -+:10F2100064010400FFFFFFFF64010400FFFFFFFF24 -+:10F2200060010400BC01010364010400000005004A -+:10F2300060010400C5010103640104000000100323 -+:10F2400064010400E000FFFF640104000309BF0043 -+:10F25000640104000000030964010400BF00001001 -+:10F26000640104000309BF006401040000030000FE -+:10F2700060010400CD01010364010400FFFFFFFFF2 -+:10F2800064010400FFFFFFFF64010400FFFFFFFFB4 -+:10F2900064010400FFFFFFFF64010400FFFFFFFFA4 -+:10F2A00064010400FFFFFFFF64010400FFFFFFFF94 -+:10F2B00064010400FFFFFFFF640104002000CB0194 -+:10F2C0006401040000005400640104000000AB0865 -+:10F2D00064010400000010046401040084000200C2 -+:10F2E000640104000000140064010400CF01020066 -+:10F2F000640104004400000064010400AF0802003F -+:10F3000064010400100464006401040002020000AF -+:10F31000640104001000CA016401040002003C0002 -+:10F32000640104000000AA08640104000200100443 -+:10F330006401040054000208640104000000080095 -+:10F3400064010400CE0100006401040034000000E8 -+:10F3500064010400AE0800006401040010044400CD -+:10F3600064010400020A0000640104000800C901ED -+:10F370006401040002003000640104000000A908D8 -+:10F380006401040002001004640104003C00021047 -+:10F39000640104000000040064010400CD010000C9 -+:10F3A000640104002C00000064010400AD080000AA -+:10F3B000640104001004340064010400021200001F -+:10F3C000640104000400C8016401040000002C0072 -+:10F3D000640104000000A808640104000000100497 -+:10F3E0006401040030000219640104000000000000 -+:10F3F00064010400CC010200640104002C00000040 -+:10F4000064010400AC080200640104001004300030 -+:10F4100064010400021A000064010400C0000A0430 -+:10F420006401040070000000640104003A010A0451 -+:10F430006401040028022CC064010400F2020A04E2 -+:10F440006401040000000001640104006000140471 -+:10F450006401040038000000640104000201140487 -+:10F460006401040014012CC064010400DE011404D2 -+:10F4700064010400000080006401040022003704DD -+:10F48000640104001500000064010400DF0037047B -+:10F490006401040065002CC0640104002E013704DF -+:10F4A0006401040000002F006401040011006E8458 -+:10F4B000640104000B00000064010400D4006E84A9 -+:10F4C0006401040033002CC064010400FC006E845D -+:10F4D00064010400000018006401040002008A9D19 -+:10F4E00064010400FB00020864010400C54EFA0038 -+:10F4F00064010400020A833464010400FE00021067 -+:10F50000640104006227F900640104000212421A37 -+:10F5100064010400FD00021964010400B113F80045 -+:10F5200064010400021A811164010400FC00021C41 -+:10F5300064010400C10FFC00600104007B030103AF -+:10F540006401040007001400640104001E000000B0 -+:10F55000600104008303010364010400000000F063 -+:10F5600064010400C3301092640104005031802211 -+:10F5700064010400C330000060010400880301033B -+:10F580006401040000001004600104008C03010306 -+:10F590006401040080000000600104008E03010388 -+:10F5A0006401040005000000600104000B04010375 -+:10F5B0006401040000000702600104001404010358 -+:10F5C000640104000100000060010400160401034E -+:10F5D000640104000C0000006001040053050103F5 -+:10F5E00064010400000018006001040055050103D7 -+:10F5F00064010400983A983A64010400A60E64007D -+:10F60000640104000000F40164010400050000002E -+:10F6100064010400A861A8616401040030751E0043 -+:10F62000600104005D0501036401040050C3000093 -+:10F63000600104005F05010364010400000014057B -+:10F640006401040050C3000060010400630501036D -+:10F6500064010400204E00006401040000000F005B -+:10F6600064010400F4010400600104006905010361 -+:10F670006401040000003100640104000000030084 -+:10F68000640104000100070064010400C8AF000029 -+:10F690006401040088130000640104002C17FF00BB -+:10F6A00060010400700501036401040000002C01E6 -+:10F6B000640104000000A00F600104007305010351 -+:10F6C00064010400000003006401040000002C0138 -+:10F6D00064010400C00000006401040088130000FD -+:10F6E000640104006400000064010400DC05401FA4 -+:10F6F000600104007A0501036401040001000100B7 -+:10F700006401040002000000600104007D050103A3 -+:10F710006401040002000000640104000000409C39 -+:10F7200064010400204E000064010400B80B0000D6 -+:10F730006001040082050103640104000000204E02 -+:10F74000640104000000050064010400DC053F00C2 -+:10F7500064010400710200006401040030750000BF -+:10F76000600104008A05010364010400C409A00FBC -+:10F77000600104008D050103640104000A00D00744 -+:10F78000600104008F05010364010400204E204E37 -+:10F79000600104009505010364010400BE0000003F -+:10F7A00060010400B105010364010400E8030000E6 -+:10F7B00060010400ED050103640104000000000085 -+:10F7C00060010400F60501036401040088130000D1 -+:10F7D0006001040003000200640104001F00000037 -+:10F7E000600104000400020064010400FF03000043 -+:10F7F0006001040005000200640104001F00000015 -+:10F80000600104000600020064010400070000001B -+:10F81000600104000700020064010400040000000D -+:10F82000600104000800020064010400FFFF000002 -+:10F8300060010400090002006401040000000000EF -+:10F84000600104000A0002006401040000000000DE -+:10F85000600104000B0002006401040000000000CD -+:10F86000600104000C0002006401040000000000BC -+:10F87000600104000D0002006401040000000000AB -+:10F88000600104000E00020064010400000000009A -+:10F89000600104000F000200640104000000000089 -+:10F8A0006001040010000200640104001F00000059 -+:10F8B0006001040011000200640104000000000067 -+:10F8C0006001040012000200640104000000000056 -+:10F8D0006001040013000200640104000000000045 -+:10F8E0006001040015000200640104000000000033 -+:10F8F0006001040016000200640104000000000022 -+:10F90000FFFF000000000000636275636B5F7377A8 -+:10F910006672657100000000E02E010101500000D8 -+:10F9200000000000C832020101490000899DD80092 -+:10F930004038030101420000AAAAAA00003C0401C9 -+:10F94000013E000000008000483F05010139000031 -+:10F95000D05E4200A0410601013900004992240016 -+:10F96000004B07010132000000000000584D080163 -+:10F9700001300000071F7C00204E0901013000000B -+:10F9800000000000A8610A0101260000666666000A -+:10F9900090650B0101240000C44EEC0030750C0191 -+:10F9A000012000000000000018920D020133000049 -+:10F9B000F93E560000960E020132000000000000E1 -+:10F9C000409C0F02013000000000000080BB1002CC -+:10F9D00001280000000000000000000000000000FE -+:10F9E0000000000009FA0100000000000800080003 -+:10F9F00008FA01000100000008000B0000000000F0 -+:10FA000000000000000000006D6B6565705F616CB8 -+:10FA100069766500746F655F6F6C00746F655F7306 -+:10FA20007461747300746F655F73746174735F6382 -+:10FA30006C65617200AAAA030000000014FA0100BC -+:10FA400000000000070000001BFA01000100000098 -+:10FA500008004C0025FA0100020000000000000030 -+:10FA6000000000000000000000000000D58D8600AE -+:10FA70000C00800001000000A98E86000B00000031 -+:10FA800001000000B58E86000300000005000000A4 -+:10FA9000C18E86000400000007000000D08E8600A2 -+:10FAA00005008000010000000000000000000000D0 -+:10FAB000000000005B574C414E5D636F756E742013 -+:10FAC0003D2025640A000000D550830021578300A3 -+:10FAD0000000000000000000627461006274616D4B -+:10FAE00070006274616D705F666C61677300627450 -+:10FAF000616D705F6368616E006274616D705F312B -+:10FB0000316E5F737570706F7274006274616D70C6 -+:10FB10005F6662006274616D705F73746174656CBE -+:10FB20006F6700414D502D253032782D25303278C9 -+:10FB30002D253032782D253032782D253032782D14 -+:10FB400025303278000000007DC5860000000000EE -+:10FB50000800240084C586000100000008000000A1 -+:10FB600093C586000200000008000C00A4C58600B2 -+:10FB7000030000000800E402AFC586000400000096 -+:10FB800007000000C0C58600050000000800240032 -+:10FB9000C9C586000600000001000000D1C586002E -+:10FBA0000700000007000000DBC586000800000019 -+:10FBB0000100000049C586000900000001000000A6 -+:10FBC000000000000000000000000000776C635F90 -+:10FBD00061757468656E74696361746F725F646F78 -+:10FBE000776E0025733A2063616C6C65640A00705F -+:10FBF000617463685F696F76617273006F747072AD -+:10FC00006177006175746800666162696400616DA6 -+:10FC10007064755F727473005856000243004000B0 -+:10FC2000207986000000004003000000FCFB01007A -+:10FC300007000800080000003D7D860001000880E4 -+:10FC40000800000003FC0100020000400600000064 -+:10FC50004FDB0100030010000700000008FC01005A -+:10FC60000400000005000000647D8600050000001F -+:10FC700008001C000EFC010006000000010000004E -+:10FC80000000000000000000000000004D84FF8321 -+:10FC90004CC4001FB784FF80B184FFDFB0C40808E4 -+:10FCA000FA84F7FFF9C4080001006C090200710929 -+:10FCB0000300760904007B09050080090600850918 -+:10FCC00007008A0908008F09090094090A009909A8 -+:10FCD0000B009E090C00A3090D00A8090E00B40931 -+:10FCE000CC0102000000D400000000000000000170 -+:10FCF0000000000000002D00A7901A0047090E0028 -+:10FD0000012007008B93030038CA01002AE5000098 -+:10FD1000977200004C390000A61C0000530E000032 -+:10FD20002907000095030000CA010000E50000005B -+:10FD300073000000390000001D0000006E840B00FD -+:10FD40000000D400000000000000000100000000DE -+:10FD50006030180C6C482412776C25643A20536389 -+:10FD6000616E20696E2070726F67726573732C20EC -+:10FD7000736B697070696E67207478706F776572E5 -+:10FD800020636F6E74726F6C0A00706F77657220FB -+:10FD900061646A210A002E6661622E0025732E6658 -+:10FDA00061622E25640063636B6277323032677064 -+:10FDB0006F0063636B62773230756C3267706F000F -+:10FDC0006C65676F66646D627732303267706F00A2 -+:10FDD0006C65676F66646D62773230756C32677020 -+:10FDE0006F006D6373627732303267706F006D63DE -+:10FDF0007362773230756C3267706F006D63736257 -+:10FE00007734303267706F006C65676F66646D625F -+:10FE100077323035676C706F006C65676F66646D44 -+:10FE200062773230756C35676C706F006C65676F28 -+:10FE300066646D6277323035676D706F006C656730 -+:10FE40006F66646D62773230756C35676D706F0008 -+:10FE50006C65676F66646D62773230356768706FA6 -+:10FE6000006C65676F66646D62773230756C3567FC -+:10FE700068706F006D63736277323035676C706FD6 -+:10FE8000006D637362773230756C35676C706F002C -+:10FE90006D63736277343035676C706F006D6373B8 -+:10FEA0006277323035676D706F006D6373627732E1 -+:10FEB00030756C35676D706F006D637362773430C9 -+:10FEC00035676D706F006D637362773230356768C8 -+:10FED000706F006D637362773230756C3567687070 -+:10FEE0006F006D637362773430356768706F006DD3 -+:10FEF00063733332706F006C65676F66646D3430A6 -+:10FF0000647570706F00616E7473776974636800F4 -+:10FF1000616135670074737369706F733267006570 -+:10FF2000787470616761696E3267007064657472BD -+:10FF3000616E6765326700747269736F3267006162 -+:10FF40006E74737763746C32670074737369706F67 -+:10FF50007335670065787470616761696E35670035 -+:10FF60007064657472616E67653567007472697379 -+:10FF70006F356700616E74737763746C35670070FA -+:10FF80006132677730613300706132677731613396 -+:10FF9000006D61787032676130006D617870326732 -+:10FFA00061310070613267773061300070613267B3 -+:10FFB0007730613100706132677731613000706194 -+:10FFC00032677731613100706132677732613000BA -+:10FFD0007061326777326131006D61787035676CBE -+:10FFE0006130006D61787035676C6131007061352A -+:10FFF000676C7730613000706135676C77306131E4 -+:020000022000DC -+:1000000000706135676C7731613000706135676C05 -+:100010007731613100706135676C77326130007023 -+:100020006135676C77326131006D61787035676179 -+:1000300030006D61787035676131007061356777C8 -+:100040003061300070613567773061310070613543 -+:1000500067773161300070613567773161310070E9 -+:1000600061356777326130007061356777326131B1 -+:10007000006D6178703567686130006D617870354A -+:100080006768613100706135676877306130007092 -+:100090006135676877306131007061356768773145 -+:1000A00061300070613567687731613100706135AA -+:1000B0006768773261300070613567687732613127 -+:1000C000006D61787035676133006D6178703567F8 -+:1000D0006C61330070613567773061330070613572 -+:1000E000676C773061330070613567773161330059 -+:1000F000706135676C7731613300706135677732D5 -+:10010000613300706135676C773261330062773438 -+:1001100030706F00636464706F0073746263706F3B -+:10012000006277647570706F00747870696432670C -+:100130006130007478706964326761310069747489 -+:100140003267613000697474326761310063636BD8 -+:100150003267706F006F66646D3267706F006D6339 -+:10016000733267706F30006D63733267706F310088 -+:100170006D63733267706F32006D63733267706FD7 -+:1001800033006D63733267706F34006D6373326771 -+:10019000706F35006D63733267706F36006D637317 -+:1001A0003267706F3700747870696435676C6130DE -+:1001B00000747870696435676C6131006F66646DD6 -+:1001C00035676C706F006D637335676C706F3000EE -+:1001D0006D637335676C706F31006D637335676C79 -+:1001E000706F32006D637335676C706F33006D63D1 -+:1001F0007335676C706F34006D637335676C706F47 -+:1002000035006D637335676C706F36006D637335E1 -+:10021000676C706F3700747870696435676130009F -+:100220007478706964356761310069747435676129 -+:10023000300069747435676131006F66646D3567CD -+:10024000706F006D63733567706F30006D63733569 -+:1002500067706F31006D63733567706F32006D6367 -+:10026000733567706F33006D63733567706F34007B -+:100270006D63733567706F35006D63733567706FCD -+:1002800036006D63733567706F370074787069641A -+:10029000356768613000747870696435676861310A -+:1002A000006F66646D356768706F006D63733567E6 -+:1002B00068706F30006D6373356768706F31006D03 -+:1002C0006373356768706F32006D6373356768708C -+:1002D0006F33006D6373356768706F34006D6373DF -+:1002E000356768706F35006D6373356768706F369A -+:1002F000006D6373356768706F3700656C6E6132CF -+:100300006700656C6E6135670074656D706F666659 -+:100310007365740070687963616C5F74656D706497 -+:10032000656C7461000C1218243048606C003CC489 -+:1003300007003BC407004C84FFE0B084F7F7F98462 -+:10034000F7FF000008040200350108300800030030 -+:100350001204020043010000010000001C0402001E -+:1003600048010800030000002C04020049010800B5 -+:1003700003000000390402004A01080003000000E5 -+:10038000470402004E01080003000000520402006E -+:100390003D014000070007005E0402007A010004EE -+:1003A000070000006C0402003F010000060000008E -+:1003B00077040200400100000200000082040200F5 -+:1003C0007C010000020000008F04020042010000D6 -+:1003D000070000009B040200280008000300000042 -+:1003E000AC0402002900000001000000B904020072 -+:1003F0007F0100000200000000000000000000007B -+:1004000000000000706879007478696E737470770A -+:1004100072007068795F6D75746564007068795FEB -+:10042000676C697463687468727368007068795F78 -+:100430006E6F6973655F7570007068795F6E6F6964 -+:1004400073655F64776E007068795F706572636171 -+:100450006C007068795F7278697165737400706898 -+:10046000796E6F6973655F73726F6D006E756D5F26 -+:1004700073747265616D0062616E645F72616E6754 -+:10048000650073756262616E643567766572006DD2 -+:10049000696E5F7478706F776572007068795F6FEE -+:1004A000636C736364656E61626C65007068795F2C -+:1004B0007278616E7473656C007068795F637273D3 -+:1004C0005F7761720000EB04C00100006A04FFFF67 -+:1004D000190036001A013A00250028000500120113 -+:1004E000FF001F010B0013010700FC00FD00FF00CF -+:1004F000C000CA00C5001200570059005C00780017 -+:100500009200980016012C016A000B001B001301D9 -+:100510001D0014012E002A011201F904010001003E -+:10052000FA04010000004C04001800184D0400609B -+:1005300000603809FF01FF013909FF019E003B04FB -+:10054000030003003C0403000000DA46FFFFDBC6A3 -+:100550000300D10604000400977A977A977A977A75 -+:10056000877A877A977B000006000000060000006B -+:1005700006000000060000003809040004003909E4 -+:1005800004000400A404001000104AC444004A44BB -+:1005900080004AC444004A448000A4040040000093 -+:1005A000A40400800080D00420000000A404FF0107 -+:1005B0000000A504FF00FF00A50400700050A50482 -+:1005C000000700000D04FF0040000D0400070004B8 -+:1005D000A204FF004000A20400070004A804FF00DA -+:1005E0000100D70401000100D704400000003706D5 -+:1005F00000C00080810400020002B704007F006C8C -+:10060000B10400200000390900020000380900028E -+:100610000002B00408000800B0040008000839090E -+:10062000000800003809000800081004080008004D -+:10063000DA062000000003050100000003050400A5 -+:100640000000A40400400000A40400800000D004C6 -+:1006500020000000A504FF00FF00A504007000506A -+:10066000A504000700000D04FF0040000D04000772 -+:100670000006A204FF004000A20400070006D904FF -+:1006800070002000D90400070003D9040070001096 -+:10069000DA0400100000DA0400200020A604008024 -+:1006A0000080D70408000800D70400700010D904A7 -+:1006B00004000000D9040800080000000000000049 -+:1006C0000000000000000000FFEEDDCCBB99887741 -+:1006D0006655443322110000DA46FFFF0305080087 -+:1006E000080025642009202564200A004572726FE5 -+:1006F000722067657474696E67206C6F772069710A -+:10070000206573740A004572726F72206765747495 -+:10071000696E672068696768206971206573740A6B -+:1007200000004AC480004A847F00D0040200000018 -+:10073000D204FF000000D20400FF0000D004080033 -+:1007400000004C04000800084D0400200000B00424 -+:1007500000010001B644FFFFB7040F000F004C0476 -+:10076000000800084D0400200020B0040001000132 -+:100770003B04010001003C04010001003C040100B5 -+:1007800000003B04010000004AC444004A448000C9 -+:10079000DAC64000DBC60300DA06200020001004A1 -+:1007A00008000000A60400800080A604FF01FF00EE -+:1007B0009A04FF01FF008007000400048007000284 -+:1007C0000002D60603000000DA06080008004249CD -+:1007D00002003B4900003C49000076068000000012 -+:1007E000DA06010000006C08040000006C084000FC -+:1007F00000006C0800040000D70408000000D804C2 -+:1008000001000000D804020000003B0404000400C2 -+:100810003C04040000003B04040004003C04040009 -+:10082000000084806782568034823B04010001000E -+:100830003C04010001003C04010000003B040100F5 -+:1008400000003B04020002003C04020002003C04E1 -+:10085000020000003B0402000000977A977A977A22 -+:10086000977A877A877A977B0F0900090109060929 -+:10087000070908090209030909090A090B090409FA -+:1008800005090C090D090E09110987466000424649 -+:1008900007003B84EDFF3C04020002004C84D0EFD3 -+:1008A0004D84D7BF4D04040004004D040300010033 -+:1008B000F984F8FFFA84F8FF3B04020002003C04CC -+:1008C000020000003B04100010003C044000000047 -+:1008D0004C04001000104D04004000404D04040082 -+:1008E00000004C04040004004C04080008004D04FF -+:1008F000080000004C04200020004D0420002000CF -+:10090000F90402000200FA0402000000F9040400E5 -+:100910000400FA0404000000F90401000100FA04D4 -+:1009200001000000DB04FF03A602DB0400700020CE -+:100930009A05FF0326009B05FF03A5009C05FF0306 -+:10094000A6009C0500FC00289D05003C001C9D05A0 -+:10095000FF03A800A40400800080A404004000401D -+:10096000A40400200020B004800000003B044000EC -+:100970000000A904008000802184238434838480C3 -+:100980006782568034823B04020002003C0402006D -+:1009900000003B04100010003C04400000004B44E9 -+:1009A000FFFFB10400040000B1040080000038091A -+:1009B00040004000380904000400390940000000EC -+:1009C000390904000400D70402000200D7048000A3 -+:1009D0000000D70401000100D70440004000D70404 -+:1009E00008000800D70400700020DA06400040002C -+:1009F000A40400200000D70408000800D7040070F9 -+:100A0000002031C61500D60603000000DAC68F00AC -+:100A1000100480000000A8440A000305A404D004C8 -+:100A2000D904DA04A60438093909D804D004D70453 -+:100A3000A5040D04A2044C04001000104D04004055 -+:100A400000404C04000800084D04002000003B0456 -+:100A5000020002003C04020000003B04010001000F -+:100A60003C04010000004C04080008004D0408008C -+:100A700008004C04200020004D0420000000F90470 -+:100A800002000200FA0402000200F904040004005B -+:100A9000FA0404000400F90401000100FA04010052 -+:100AA00001005344A90A3D49C000000000000000B5 -+:100AB000000000000000000000000000977A877A24 -+:100AC000877A977B760680008000DA0601000100B5 -+:100AD0006C08040004006C08400040006C0800042E -+:100AE000000410091E091F092409250926092009E7 -+:100AF000210927092809290922092309300931096F -+:100B000032091209D7440000D70401000100D704BC -+:100B100040000000D70401000100D704400040005D -+:100B20001004020000001004010000001004020084 -+:100B30000000100401000100100402000200100473 -+:100B4000010000007A46030073467017744644049F -+:100B500075463F00704681068C4649004AC44400F1 -+:100B60004A448000004001400240034004400540E8 -+:100B700006400740075B0780A3C60100A386FEFF6F -+:100B80000700FF001F013A001A01050082008600DD -+:100B90002E0113017D002800340600FF0000DAC694 -+:100BA00080000AC02802760680000000DA060100F4 -+:100BB00000006C08040000006C08400000006C0895 -+:100BC00000040000D80401000000D8040200000066 -+:100BD000D704080000004C84FFE73B840C005384DA -+:100BE000FF7F53C40080424907003B4917203C491E -+:100BF000C527D60603000100DA0608000000DA0661 -+:100C0000800000000A46A0006A4419000F0900098C -+:100C100001090609070908090209030909090A095E -+:100C20000B09040905090C090D090E091109C9462A -+:100C300000068046FF0081463F01CE460000CB46BD -+:100C40000000CC460000CD4600009D46FF07A446AC -+:100C50000000A5460000D90404000400D9040800DF -+:100C60000000A40400400040A40400400000DAC6D4 -+:100C700040000100D70408000800D70400700030CD -+:100C80004AC444004A4480003B0404000000380980 -+:100C900040000000380904000000D70402000000F2 -+:100CA000D70401000000D70408000000D8040100A8 -+:100CB0000000D8040200000000FC070069A5050040 -+:100CC000FF010000695D0A0000040800975E0A0049 -+:100CD0000102000097A60500D70401000100D70417 -+:100CE00040004000D70401000000D90401000100C9 -+:100CF000D904020000000000AA0A02009A05FF03BE -+:100D000026009B05FF0389009C05FF038A009C05C4 -+:100D100000FC00209D05003C002C9D05FF038C007D -+:100D20003B04010001003C040100000038090008F8 -+:100D30000008390900080008DA0600800080D306A0 -+:100D400000800080D30600800000DA0600800000EA -+:100D50000A80D7FDDA867FFFD7C6010031C60018AA -+:100D60003B4400003C4400004C440000E6440000CA -+:100D7000F9440000B044000038490000B0440000CD -+:100D80004E44000067C503004AC444004A44800042 -+:100D90004804000300010806FF0017000406FF07CF -+:100DA000EA0342490F004249000042490F004A4409 -+:100DB00084004A448000D3462222D34620223B4965 -+:100DC00017203C49C5270305010000000305040066 -+:100DD00000000305100010004249000042490F00C6 -+:100DE000424900003B4917003C49C5074AC444003A -+:100DF0004A448000D70408000000D7040070002097 -+:100E0000380904000400390904000400A404001097 -+:100E10000010D70404000400D704000F00008B4624 -+:100E200000007646A1B816012D012C016A00980039 -+:100E300097002F010B0013011D0014012E002A0141 -+:100E400009001F010700FF000500D0040100000099 -+:100E5000D304FF000000D30400FF0000D004100002 -+:100E60000000D004040000003A0980008000230440 -+:100E7000FF0049003404FF00FCFF1604FF00A4FF3C -+:100E8000160400FF009F240400FF002A230400FF33 -+:100E9000002D2504FF000F000005FF000F000005D6 -+:100EA00000FF000F2004FF000A00340400070001C7 -+:100EB0003204FF00BF00320400FF00B8FF0400FC52 -+:100EC0000018D106040000004B06400040002184B9 -+:100ED0002384348384806782568034824B060100E9 -+:100EE00001004B06080008005F36291F5F36291FE6 -+:100EF0005F36291F5F36291F000000000000000038 -+:100F000000000000000000000000000000000000E1 -+:100F100000000000000000000400000000000000CD -+:100F200004000000080000000100000005000000AF -+:100F3000090000000D0000004D0000008D000000C1 -+:100F40000D0000004D0000008D000000CD000000ED -+:100F50005200000092000000D2000000D600000005 -+:100F600016010000160500001609000056090000D1 -+:100F7000560D000056110000961100009651000019 -+:100F80009691000096D1000096110100000000002B -+:100F90000000000000000000000000000000000051 -+:100FA0000000000004000000000000000400000039 -+:100FB000080000000100000005000000090000001A -+:100FC0000D0000004D0000008D0000000D0000002D -+:100FD0004D0000008D000000CD0000005200000018 -+:100FE00092000000D2000000D600000016010000B0 -+:100FF000160500001609000056090000560D0000F5 -+:1010000056110000565100005691000056D10000C4 -+:1010100056110100565101005691010056D10100B0 -+:1010200000000000000000000000000000000000C0 -+:1010300000000000000000000000000000000000B0 -+:1010400000000000000000000000000000000000A0 -+:101050000000000000000000000000000000000090 -+:101060000000000000000000000000000000000080 -+:1010700000000000000000000A0009000600050052 -+:101080000A000900060005000A0009000600050024 -+:101090000A000900060005000A0009000600050014 -+:1010A0000A000900060005000A0009000600050004 -+:1010B0000A000900060005000A00090006000500F4 -+:1010C0000A000900060005000A00090006000500E4 -+:1010D0000A000900060005000A00090006000500D4 -+:1010E0000A000900060005000A00090006000500C4 -+:1010F0000A000900060005000E00000000020003BF -+:10110000000400060008000B00100110021003107C -+:10111000041005100610071007170720072D0740B9 -+:1011200000000000000000000000000000000000BF -+:1011300000000000000000000000000000020003AA -+:10114000000400060008000B00100110021003103C -+:10115000041005100610071007170720072D074079 -+:10116000000000000000000000000000000000007F -+:10117000000000000000000000000000000000006F -+:10118000000000000000000000000000000000005F -+:10119000000000000000000000000000000000004F -+:1011A00000000000000000000000004000000000FF -+:1011B000000000000000000000000000000000002F -+:1011C000000000000000000000000000000000001F -+:1011D000000000000000000000000000000000000F -+:1011E00000000000000000000000000000000000FF -+:1011F00000000000000000000000000000000000EF -+:1012000000000000000000000000000000000000DE -+:1012100000000000000000000000000000000000CE -+:1012200000000000000000000000000000000000BE -+:1012300000000000000000000000000000000000AE -+:10124000000000000000000000000000000000009E -+:1012500000000000F8410100F8210000FB2100001F -+:10126000FB410000DBFE01007B2100003321000078 -+:10127000EB400000A3FE01004B0200004D014D01B8 -+:101280004D014D014D014D014D014D014D014D01EE -+:101290004D014D014D014D014D014D014D014D01DE -+:1012A0004D014D014D014D014D014D014D014D01CE -+:1012B0004D014D014D014D014D014D014D014D01BE -+:1012C0004D014D014D014D014D014D014D014D01AE -+:1012D0004D014D014D014D014D014D014D014D019E -+:1012E0004D014D014D014D014D014D014D014D018E -+:1012F0004D014D014D014D014D014D01090F1418D6 -+:10130000FE070B0FFBFE0105080B0E111417000062 -+:1013100000000000000306090C0F1200000000008E -+:1013200000000000000306090C0F1215181B000036 -+:101330000000000003EB000001001000100020007E -+:101340000100300010004000220050002201600027 -+:101350002202700022038000220490002205A000D7 -+:101360002206B0002207C0002208D0002209F000A7 -+:10137000220A1000220B2000220C3000220D400017 -+:10138000220E5000220F600000000000000000004C -+:10139000000000000000000000000000000000004D -+:1013A0000000000000000000040000000000000039 -+:1013B000040000000800000001000000050000001B -+:1013C000090000000D0000004D0000008D0000002D -+:1013D0000D0000004D0000008D000000CD00000059 -+:1013E0004F0000008F000000CF000000D30000007D -+:1013F0001301000013050000130900005309000049 -+:10140000530D000053110000931100009351000090 -+:101410009391000093D1000093110100000000009F -+:1014200000000000000000000000000000000000BC -+:1014300000000000040000000000000004000000A4 -+:101440000800000001000000050000000900000085 -+:101450000D0000004D0000008D0000000D00000098 -+:101460004D0000008D000000CD0000004F00000086 -+:101470008F000000CF000000D30000001301000027 -+:10148000130500001309000053090000530D00006C -+:1014900053110000535100005391000053D100003C -+:1014A00053110100535101005391010053D1010028 -+:1014B000000000000000000000000000000000002C -+:1014C000000000000000000000000000000000001C -+:1014D000000000000000000000000000000000000C -+:1014E00000000000000000000000000000000000FC -+:1014F00000000000000000000000000000000000EC -+:1015000000000000000000000104020403040404C1 -+:10151000050406040704080409040A048B058C0565 -+:101520008D058E058F059000910092009301940126 -+:10153000950196019701980199019A019B019C01DF -+:101540009D019E019F01A001A101A201A301A4018F -+:10155000A5010000010101010101010101010101D9 -+:10156000010101010101010101010101010101016B -+:101570000101020301030201010101010101010155 -+:10158000010101010101010101010101010101014B -+:10159000010101010101010101010101010101013B -+:1015A000010101010101010101010101010101012B -+:1015B0000101020301030201010101010101010115 -+:1015C000010101010101010101010101010101010B -+:1015D000010101017C120200400000000200000035 -+:1015E0000000000010000000D411020040000000C4 -+:1015F0000100000000000000100000005412020072 -+:101600000A0000000B0000000000000020000000A5 -+:1016100038130200140000000C000000000000005D -+:1016200020000000A41A0200940000000D00000039 -+:101630000000000020000000081502002600000045 -+:101640000E000000000000001000000078100200F2 -+:10165000400000000F00000000000000100000002B -+:10166000081D020010000000100000000000000033 -+:1016700008000000FC1202003C0000001100000005 -+:101680000000000008000000881302006000000055 -+:1016900012000000000000002000000054150200AD -+:1016A000800000001400000000000000080000009E -+:1016B000EC1602009A000000170000000000000075 -+:1016C00010000000FC1002006C0000000000000090 -+:1016D000000000001000000020180200A000000020 -+:1016E0001800000000000000200000001A00340074 -+:1016F0004E0068009C00D000EA000401340068003D -+:101700009C00D0003801A001D40108024E009C00CA -+:10171000EA003801D4017002BE020C036800D00058 -+:101720003801A00170024003A803100418009C00B7 -+:10173000D0000401EA0038018601D0000401040150 -+:1017400038016C016C01A001380186018601D401C9 -+:10175000220222027002040138016C0138016C017E -+:10176000A001D401A001D401080208023C028601B4 -+:10177000D4012202D40122027002BE027002BE0213 -+:101780000C030C035A0336006C00A200D80044017D -+:10179000B001E6011C026C00D8004401B0018802CF -+:1017A0006003CC033804A2004401E6018802CC03A4 -+:1017B0001005B2055406D800B00188026003100578 -+:1017C000C0069807700818004401B0011C02E60129 -+:1017D00088022A03B0011C021C028802F402F402EF -+:1017E000600388022A032A03CC036E046E041005EA -+:1017F0001C028802F4028802F4026003CC03600336 -+:10180000CC0338043804A4042A03CC036E04CC03AC -+:101810006E041005B2051005B20554065406F6060E -+:101820000000080000000800000008000000080098 -+:101830000000080000000800000008000000080088 -+:101840000000080000000800000008000000080078 -+:101850000000080000000800000008000000080068 -+:101860000000080000000800000008000000080058 -+:101870000000080000000800000008000000080048 -+:101880000000080000000800000008000000080038 -+:101890000000080000000800000008000000080028 -+:1018A0000000080000000800000008000000080018 -+:1018B0000000080000000800000008000000080008 -+:1018C00000000800000008000000080000000800F8 -+:1018D00000000800000008000000080000000800E8 -+:1018E00000000800000008000000080000000800D8 -+:1018F00000000800000008000000080000000800C8 -+:1019000000000800000008000000080000000800B7 -+:1019100000000800000008000000080000000800A7 -+:101920000000080000000800000008000000080097 -+:101930000000080000000800000008000000080087 -+:101940000000080000000800000008000000080077 -+:101950000000080000000800000008000000080067 -+:101960000000080000000800000008000000080057 -+:101970000000080000000800000008000000080047 -+:101980000000080000000800000008000000080037 -+:101990000000080000000800000008000000080027 -+:1019A0000000080000000800000008000000080017 -+:1019B0000000080000000800000008000000080007 -+:1019C00000000800000008000000080000000800F7 -+:1019D00000000800000008000000080000000800E7 -+:1019E00000000800000008000000080000000800D7 -+:1019F00000000800000008000000080000000800C7 -+:101A000000000800000008000000080000000800B6 -+:101A100000000800000008000000080000000800A6 -+:101A20000000080000000800000008000000080096 -+:101A30000000080000000800000008000000080086 -+:101A40000000080000000800000008000000080076 -+:101A50000000080000000800000008000000080066 -+:101A60000000080000000800000008000000080056 -+:101A70000000080000000800000008000000080046 -+:101A80000000080000000800000008000000080036 -+:101A90000000080000000800000008000000080026 -+:101AA0000500000000000000000000000000001021 -+:101AB00000000000000000200000000000000030D6 -+:101AC0000000000000000040000000000000005086 -+:101AD0000000000000000060000000000000007036 -+:101AE00000000000000000800000000000000090E6 -+:101AF00008000000000000A008000000000000B086 -+:101B000008000000000000C008000000000000D035 -+:101B100008000000000000E008000000000000F0E5 -+:101B20000800000000000000090000000000001094 -+:101B30000900000000000020190000000000003033 -+:101B400019000000000000401900000000000050D3 -+:101B50001900000000000060190000000000007083 -+:101B60001900000000000080190000000000009033 -+:101B700019000000000000A019000000000000B0E3 -+:101B800019000000000000C019000000000000D093 -+:101B900019000000000000E019000000000000F043 -+:101BA00019000000000000001A00000000000010F2 -+:101BB0001A000000000000201A00000000000030A1 -+:101BC0001A000000000000401A0000000000005051 -+:101BD0000200000000000060020000000000007031 -+:101BE00002000000000000800200000000000090E1 -+:101BF00002000000000000A002000000000000B091 -+:101C000002000000000000C00A000000000000D038 -+:101C10000A000000000000E00A000000000000F0E0 -+:101C20000A000000000000000B000000000000108F -+:101C30000B000000000000200B000000000000303E -+:101C40000B000000000000400B00000000000050EE -+:101C50001B000000000000601B000000000000707E -+:101C60001B000000000000801B000000000000902E -+:101C70001B000000000000A01B000000000000B0DE -+:101C80001B000000000000C01B000000000000D08E -+:101C90001B000000000000E01B000000000000F03E -+:101CA0001B000000000000001C00000000000010ED -+:101CB0001C000000000000201C000000000000309C -+:101CC0001C000000000000401C000000000000504C -+:101CD0001C000000000000601C00000000000070FC -+:101CE0001C000000000000801C00000000000090AC -+:101CF0001C000000F80E020060000000120000004E -+:101D000000000000200000005F36291F5F36291FF9 -+:101D10005F36291F5F36291FE80E02001000000001 -+:101D200010000000000000000800000090E886009D -+:101D30000000800001000000000000000000000022 -+:101D4000000000007363616E0000000044EB860039 -+:101D50000100204005000000A2A5860002002040EE -+:101D60000500000090A5860003002040050000004B -+:101D70007EA58600040020400500000075998600BD -+:101D80000500104005000000EBE88600060020403A -+:101D9000020000004CEB86000C0000000100000077 -+:101DA0005EEB860007002000080000000000000035 -+:101DB00000000000000000006E6F63726300534477 -+:101DC000494F0043444300000D1680008D138000EE -+:101DD00025118000291480001D138000A1168000A9 -+:101DE000A90F0100011380002D13800000000000E6 -+:101DF0001D168000E9270000776C0000000000003D -+:101E00000000000000000000F025000000000000BD -+:101E100000000000000000000000000000000000C2 -+:101E20000000000005000000FFFFFFFF140000009D -+:101E30000100050605000000FFFFFFFF0500000090 -+:101E400005000000050000000E0E0E0E0E02090D2A -+:101E50000A080D01090D0A080D01090D0A080D01F6 -+:101E6000090D0A080D01090E0A090E060A0E0B09D2 -+:101E70000E02093A160E0E05093A160E0E050A0E46 -+:101E80000B090E050A0E0B090E020A0E0B090E02B3 -+:101E900014C0C015110514C0C015110514C0C0151B -+:101EA000110514C0C015110514C0C0151105093A5B -+:101EB000160E0E0514C0C015110514C0C01511056D -+:101EC000093A160E0E05093A160E0E05093A160EB7 -+:101ED0000E0514C0C0151105093A160E0E05093A73 -+:101EE000160E0E05093A160E0E0509B21C0E0E0549 -+:101EF00012B11911110800000000000000000000DC -+:101F00000000000065660200416602002D660200C6 -+:101F100055AA80000000000021AA800085AA800048 -+:101F200031AA80006DAA8000C993800095A9800025 -+:101F3000BDA98000D5938000B59380007593800083 -+:101F4000D191800000000000B1A98000736470632B -+:101F50006D6465760000000000000000041F0200B0 -+:101F60000000000000000000000000000000000071 -+:101F70000000000000000000000000000000000061 -+:101F80000000000000000000000000000000000051 -+:101F90000000000000000000000000000000000041 -+:101FA0000000000000000000000000000000000031 -+:101FB0000000000000000000000000000000000021 -+:101FC0000000000000000000000000000000000011 -+:101FD0000000000000000000000000000000000001 -+:101FE00000000000000000000000000000000000F1 -+:101FF00000000000000000000000000000000000E1 -+:1020000000000000000000000000000000000000D0 -+:1020100000000000000000000000000000000000C0 -+:1020200000000000000000000000000000000000B0 -+:1020300000000000000000000000000000000000A0 -+:102040000000000000000000000000000000000090 -+:102050000000000000000000000000000000000080 -+:102060000000000000000000000000000000000070 -+:10207000000000000000000004E301004100000037 -+:10208000440000000000000000000000000000000C -+:102090000000000000000000000000000000000040 -+:1020A0000000000000000000000000000000000030 -+:1020B0000000000000000000000000000000000020 -+:1020C0000000000000000000000000000000000010 -+:1020D0000000000000000000000000000000000000 -+:1020E00000000000000000000000000000000000F0 -+:1020F00000000000000000000000000000000000E0 -+:1021000000000000000000000000000000000000CF -+:1021100000000000000000000000000000000000BF -+:1021200000000000000000000000000000000000AF -+:10213000000000000000000000000000000000009F -+:10214000000000000000000000000000000000008F -+:10215000000000000000000000000000000000007F -+:10216000000000000000000000000000000000006F -+:10217000000000000000000000000000000000005F -+:10218000000000000000000000000000000000004F -+:10219000C8DC0100010000000100F918010DE40095 -+:1021A000F4DEF106FC0F27FAFF1DF01018090AF201 -+:1021B00010E01714041114F1FAF2DBF7FCE2FBE172 -+:1021C000EE130DFF1CE91A17180300DAE803E617EF -+:1021D000E4E9F3FF121305E104E225F706F2ECF15E -+:1021E000FC11E914F0E0F6F2E8091010011DD9FA2B -+:1021F000040F0F060CDE1C00FF0D07181AF60EE484 -+:10220000160FF905EC181B0A1EFF0026E2FFE50A6F -+:1022100014180705EA0FF2E4E6F6080808080808AB -+:1022200008090A0808070701020202020202020264 -+:102230000202020202020202020201010000000088 -+:1022400000000000C5011DFFE0FFC0FFE0FF00002F -+:10225000000000FF000000006B0382FEE7FFCCFFE0 -+:10226000E7FF080002000000D7010BFFEEFFDCFFD4 -+:10227000EEFFA7033CFEECFF1700ECFF720385FEA8 -+:10228000AEFEF801AEFE070004000000980160FFFA -+:10229000CBFF96FFCBFF9C0345FE2500C1FF250029 -+:1022A000B10316FEE4FEA501E4FE070014000100E0 -+:1022B000BF0131FFF20049FEF200870361FE33FFE8 -+:1022C000620133FF800378FEDAFEE900DAFE0800DF -+:1022D00015000100BF0131FF18010EFE1801870330 -+:1022E00061FE16FF7C0116FF800378FE8FFF9300CE -+:1022F0008FFF090016000100BF0131FF620055FF8A -+:102300006200870361FE1FFF6B011FFF79037EFEE2 -+:10231000F4FE5D00F4FE080017000100BC0131FF6F -+:10232000740042FF7400870361FE52FF020152FFF6 -+:10233000800378FE7FFFF1FF7FFF08001800010097 -+:10234000B40131FFDFFF1D00DFFF880361FE87FF5F -+:1023500090FF87FF7F0378FECDFEF401CDFE0800DD -+:1023600019000100AD0131FFB8FF3E00B8FF820344 -+:1023700061FEAAFFB1FFAAFF7F0378FEC7FEFE0140 -+:10238000C7FE08001A000100930154FFD9FF0C009A -+:10239000D9FF1B03C7FE4CFF38004CFF3303B8FEC8 -+:1023A00080FF280080FF08001B000100890154FF06 -+:1023B000CFFF1300CFFF1703C7FE00FF500000FF41 -+:1023C0002E03BDFE8BFF25008BFF08001E000100C1 -+:1023D000BB0119FFC3FF1D00C3FF6B0361FE66FF56 -+:1023E000480066FF7C0378FE56FF4F0056FF08004A -+:1023F0002C000100BF0131FFE00071FEE000870307 -+:1024000061FE8BFFC4008BFF800378FEB2FEC0002C -+:10241000B2FE0800010000006C0900000B0A000772 -+:102420000A88888002000000710900000B0A00077A -+:102430000A88888003000000760900000B0A000764 -+:102440000A888880040000007B0900000B0A00074E -+:102450000A88888005000000800900000B0A000738 -+:102460000A88888006000000850900000B0A000722 -+:102470000A888880070000008A0900000B0A00070C -+:102480000A888880080000008F0900000B0A0007F6 -+:102490000A88888009000000940900000B0A0007E0 -+:1024A0000A8888800A000000990900000B0A0007CA -+:1024B0000A8888800B0000009E0900000B0A0007B4 -+:1024C0000A8888800C000000A30900000B0A00079E -+:1024D0000A8888800D000000A80900000B0A000788 -+:1024E0000A8888800E000000B40900000B0A00076B -+:1024F0000A888880000001009F0152074000800088 -+:102500004000180378064000800040000A032E06B1 -+:1025100040008000400008000100010092013707E0 -+:1025200003013B0003019F02020744003600440000 -+:10253000600247075D00A7005D000800020001007F -+:102540009F01520740008000400018037806C00039 -+:102550008001C0000A032E064000800040000800F1 -+:10256000030001002E013107810002018100920267 -+:10257000B806CD009A01CD00F202E006AA0054018F -+:10258000AA0008001400010068015CFFF200C6FE0A -+:10259000F200F002B8FE33FFCB0033FFFF02E0FE93 -+:1025A00003FF49FF03FF08001500010068015CFFFD -+:1025B000950052FF9500F002B8FE33FFA40033FFF0 -+:1025C000FF02E0FE00FFEFFE00FF08001600010022 -+:1025D00068015CFF62009CFF6200F002B8FE33FFFE -+:1025E0007C0033FFFF02E0FE00FFA0FE00FF0800BA -+:1025F000170001005E015CFF8CFF52008CFFF002AF -+:10260000B8FE33FF280033FFFF02E0FE7FFF15FF17 -+:102610007FFF08001800010045015CFFE0FFD8FFC4 -+:10262000E0FFF402B8FE00FF29FE00FFFE02E0FE1C -+:10263000FAFEAA00FAFE0800190001002B015CFF57 -+:10264000CDFFC0FFCDFFE002B8FE00FF29FE00FF76 -+:10265000FD02E0FEFAFEAA00FAFE08001A000100E0 -+:10266000150197FFD9FF8BFFA8FF7D022EFFC0FF4A -+:1026700040FF70FF660248FF80FF80FEE0FE08001A -+:102680001B000100F50097FFCFFF6DFF92FF720264 -+:102690002EFF5EFF1BFE95FE650248FFC2FF46FF50 -+:1026A00075FF08001E0001002E0131FFC3FF86FFE9 -+:1026B000C3FF9202B8FE33FF66FE33FFF202E0FE74 -+:1026C00056FFACFE56FF08002800010068015CFFC1 -+:1026D000F200C6FEF200F002B8FECD0035FFCD00DC -+:1026E000FF02E0FEFF017201FF0108000501000882 -+:1026F0000001FFFF0000000000000000A200000039 -+:1027000000FF00FF00000000000000FF00000000CC -+:102710007802A0FE80FF00FF80FF0800010000009B -+:10272000760179FFF0FFE0FFF0FF1F0374FECEFF9C -+:10273000E0FFCEFFEE022BFE2CFF32002CFF080044 -+:1027400002000000770116FFDBFFB4FFDBFF1F0371 -+:1027500074FEE0FFECFFE0FFEC02F2FE80FF1E00E3 -+:1027600080FF080003000000770116FFDBFFB4FFC5 -+:10277000DBFF1F0374FEE0FFECFFE0FFEC02F2FE64 -+:102780006CFF23006CFF0800040000003301AEFF63 -+:10279000CBFF96FFCBFF0B0385FECBFF0A00CBFFE1 -+:1027A000FD022BFE2CFFCA002CFF080000000000D9 -+:1027B0000000000000000000000000000000000019 -+:1027C0000000000000000000000000000000000009 -+:1027D00000000000000000000000000000000000F9 -+:1027E00000000000000000000000000000000000E9 -+:1027F00000000000000000000000000000000000D9 -+:1028000000000000000000000000000000000000C8 -+:1028100000000000000000000000000000000000B8 -+:1028200000000000000000000000000000000000A8 -+:102830000000000000000000000000000000000098 -+:102840000000000000000000000000000000000088 -+:102850000000000000000000000000000000000078 -+:102860000000000000000000000000000000000068 -+:102870000000000000000000000000000000000058 -+:102880000000000000000000000000000000000048 -+:102890000000000000000000000000000000000038 -+:1028A0000000000000000000000000000000000028 -+:1028B0000000000000000000000000000000000018 -+:1028C0000000000000000000000000000000000008 -+:1028D00000000000000000000000000000000000F8 -+:1028E00000000000000000000000000000000000E8 -+:1028F00000000000000000000000000000000000D8 -+:1029000000000000000000000000000000000000C7 -+:1029100000000000000000000000000000000000B7 -+:1029200000000000000000000000000000000000A7 -+:102930000000000000000000000000000000000097 -+:102940000000000000000000000000000000000087 -+:102950000000000000000000000000000000000077 -+:102960000000000000000000000000000000000067 -+:102970000000000000000000000000000000000057 -+:102980000000000000000000000000000000000047 -+:102990000000000000000000000000000000000037 -+:1029A0000000000000000000000000000000000027 -+:1029B0000000000000000000000000000000000017 -+:1029C0000000000000000000000000000000000007 -+:1029D00000000000000000000000000000000000F7 -+:1029E00000000000000000000000000000000000E7 -+:1029F00000000000000000000000000000000000D7 -+:102A000000000000000000000000000000000000C6 -+:102A100000000000000000000000000000000000B6 -+:102A200000000000000000000000000000000000A6 -+:102A30000000000000000000000000000000000096 -+:102A40000000000000000000000000000000000086 -+:102A50000000000000000000000000000000000076 -+:102A60000000000000000000000000000000000066 -+:102A70000000000000000000000000000000000056 -+:102A80000000000000000000000000000000000046 -+:102A90000000000000000000000000000000000036 -+:102AA0000000000000000000000000000000000026 -+:102AB0000000000000000000000000000000000016 -+:102AC0000000000000000000000000000000000006 -+:102AD00000000000000000000000000000000000F6 -+:102AE00000000000000000000000000000000000E6 -+:102AF00000000000000000000000000000000000D6 -+:102B000000000000000000000000000000000000C5 -+:102B100000000000000000000000000000000000B5 -+:102B200000000000000000000000000000000000A5 -+:102B30000000000000000000000000000000000095 -+:102B40000000000000000000000000000000000085 -+:102B50000000000000000000000000000000000075 -+:102B60000000000000000000000000000000000065 -+:102B70000000000000000000000000000000000055 -+:102B80000000000000000000000000000000000045 -+:102B90000000000000000000000000000000000035 -+:102BA0000000000000000000000000000000000025 -+:102BB0000000000000000000000000000000000015 -+:102BC0000000000000000000000000000000000005 -+:102BD00000000000000000000000000000000000F5 -+:102BE00000000000000000000000000000000000E5 -+:102BF00000000000000000000000000000000000D5 -+:102C000000000000000000000000000000000000C4 -+:102C1000000000000000000083682DE9F0415B69BE -+:102C20000546152B0F460AD0182B08D01B2B06D0B3 -+:102C3000242B01D0272B04D12B8A7F2B05D80C23E2 -+:102C400004E0172B01D0182B01DD1423AB624FF0E9 -+:102C500004430022BB6100E00132BB69002B03DAB0 -+:102C60001D4B9A42F8D134E01C4B9A4231D8AE6ADF -+:102C70003C69331DAB83AC61A868298ADEF346F357 -+:102C8000022390FBF3F014F4807F68840AD0284676 -+:102C900039463246DEF352F3C0F30F1083B2E883B5 -+:102CA0002B8403E0AB8B2B846B8CEB83AB6913F42D -+:102CB000007F0AD0AA6A284639460132DEF33EF385 -+:102CC000C0F30F1083B2688400E02B8CAB842B8A96 -+:102CD000EB84BDE8F081C046809698007F9698000E -+:102CE00070B50446DEF33CF1002144220546DFF3D3 -+:102CF000A7F16369152B2B6001D0162B01D9104B5E -+:102D00006B60686808B9054617E0AC602046E8F3D8 -+:102D1000F1F1E8602046E8F3B5F1064618B920461F -+:102D20000121E8F3EDF16B6820469B689847054662 -+:102D30001EB920463146E8F3E3F1284670BDC0468F -+:102D4000C81D02002DE9F0470546884691469A467F -+:102D5000E8F398F1074618B928460121E8F3D0F1C5 -+:102D60002846E8F38FF1D0B12846E8F381F1B0B9F5 -+:102D70002846FFF7B5FF064610B94FF0FF3410E0C4 -+:102D80002846ECF763FD736830465C6941464A4665 -+:102D90005346A04704462846ECF75CFD01E06FF07F -+:102DA00018041FB928463946E8F3AAF12046BDE8C1 -+:102DB000F087C0460523C0F894310223C0F898314B -+:102DC0001E33C0F89C31234B4FF010021B68002BC0 -+:102DD0000CBF07230023C0F8A0314FF00103C0F857 -+:102DE000AC3103F16303C0F8B0314FF00603C0F813 -+:102DF000C03140F23C73C0F8C4314FF00803C0F852 -+:102E0000C83103F10D03C0F8A421C0F8B821C0F8FF -+:102E1000BC21C0F8CC31C0F8D02101D1032302E09D -+:102E20000D4B1B68013BC0F8D4311C230422C0F8B1 -+:102E3000DC310C23C0F8E0319B18C0F8E4310623E4 -+:102E4000C0F8EC310023C0F8D821C0F8E821C0F860 -+:102E5000F0317047EC260000D4250000D0F81012A5 -+:102E600070B5044609B90D460CE08068DFF39CF6A6 -+:102E7000D4F810120546E822A068E3F339F70023DE -+:102E8000C4F81032284670BD70B50024054680F89D -+:102E90007541006903F04AFC2846E6F30DF7E8683F -+:102EA0002146E7F3C7F7D5F8900128B1E3F306F21E -+:102EB000D5F89001E3F34CF2D5F88C0128B1E3F397 -+:102EC000FDF1D5F88C01E3F343F2E86805F0CAFCA4 -+:102ED000D5F8103223B11B7813B12846FFF7BEFF97 -+:102EE000A86829464FF40772E3F302F770BDC046A5 -+:102EF0001FB5044606238068E8210393E3F3E8F650 -+:102F0000C4F8100210B94FF0FF300CE00021E822A5 -+:102F1000DFF396F000230093A068D4F8101203AA00 -+:102F20001C33DFF3D9F604B010BDC0462DE9F047DD -+:102F30008AB01F46129D9C4B08461D601146904664 -+:102F4000E6F33CF6002800F02A8138464FF407717A -+:102F5000E3F3BEF60446002800F0218100214FF47F -+:102F600007720646DFF36CF0A76065612046FFF745 -+:102F700021FF8E4B1B68C4F80C320BB99A4605E052 -+:102F80001B78B3F1000A18BF4FF0010A884B04F117 -+:102F900028001A680121002A14BF31221122DFF310 -+:102FA0006DF70023009301930293404639462A4669 -+:102FB000139B05F095FDE060002800F0EA80E7F340 -+:102FC00051F72060E068E7F36BF7656960606B6854 -+:102FD000784A83F00103784903F00103002B0CBF0A -+:102FE00088469046226884F8763140F629039A4252 -+:102FF000D4F80890D4F80CC00AD120B905F5007EA9 -+:1030000005F5047508E005F5007E05F5087503E093 -+:1030100005F5007E05F50475D4F8B831D4F8BC2167 -+:10302000D4F8C411D4F8C00101934FF0FF330493D6 -+:1030300009330693002302920391059007934846B3 -+:103040004146624673460095EEF774FA60620028C6 -+:1030500000F09F80D4F80C12C1B10B78B3B1E1F34A -+:10306000C7F556492246D4F80C02DFF389F5D4F8A7 -+:103070000C0253492246DFF3BDF5BAF1000F05D02B -+:103080002046FFF735FF002840F0838001210A46E3 -+:10309000606AE1F3B5F520460021E2683B4603F0A3 -+:1030A00051FB2061002874D000210B462046454A80 -+:1030B000E3F370F10023C4F8900184F879314248B9 -+:1030C000E4F3D4F518B3DFF303F2012383403F4860 -+:1030D000C4F88031E4F3CAF510B1DFF3F9F108B1B7 -+:1030E000D4F88001C4F8840139490020DFF344F4A6 -+:1030F000030CA4F888319BB2A4F88A013BB10021EB -+:103100002046344A0B46E3F345F1C4F88C01002015 -+:103110003149DFF331F4012809D184F816022F492F -+:103120000138DFF329F4012804BF2D4B1860204635 -+:10313000E6F3A4F320B30025C4F8A051284629499A -+:10314000DFF31AF428B1012384F8F9312648EEF7A9 -+:10315000ABFA28462549DFF30FF488B12349284606 -+:10316000DFF30AF44FF0807300F00F000AA901F8B2 -+:10317000010D4FF44072009320460F23DFF7BEFC91 -+:103180001B481C492246E3F3B5F41B48EBF76CFDE2 -+:1031900006E0A06821464FF40772E3F3A9F5002684 -+:1031A00030460AB0BDE8F087F4260000BC260000D7 -+:1031B000EC260000AE278600B6278600DD9B800047 -+:1031C0007929000065A68000052886000E28860063 -+:1031D00017288600499B80001F28860078D50100AB -+:1031E000AC2702002A2886003428860089D50100F1 -+:1031F0004D288600E59A8000D596800010B50446DB -+:1032000060B1036806491868224600F09DDE236815 -+:10321000214658684FF4BC72E3F36AF510BDC0460E -+:10322000853B86007FB505464FF4BC714068E3F3EB -+:103230004FF508B9064619E000214FF4BC72064666 -+:10324000DEF3FEF60B4B356000930B4B002401932D -+:103250002868334609490A4A0294039400F03CDE88 -+:103260004FF49663C6F8603186F86441304604B086 -+:1032700070BDC04625110100E52C0000B0D501004D -+:10328000853B860070B5044608B906462AE0816889 -+:1032900009B90E460CE0C3689868ECF3DFF1E36807 -+:1032A000D0F1010638BF0026A1689868ECF3E8F178 -+:1032B000616F0025A56529B1E368A26F5868E3F343 -+:1032C00017F565672046EEF7D5FFE36806491868ED -+:1032D000224600F039DEE368214658684FF4B072A8 -+:1032E000E3F306F5304670BDEB3D860030B54FF494 -+:1032F000B07185B005464068E3F3EAF40446E0B1F6 -+:1033000000214FF4B072DEF39BF6E560C5F8184873 -+:10331000A8680D4922460023ECF3CEF1A06060B10D -+:103320000A4B2868009300230193029303930849F2 -+:10333000084A234600F0D0DD18B12046FFF7A2FF6F -+:103340000024204605B030BD152E0000D9E18000D4 -+:1033500034D60100EB3D8600034B012210B51A70F4 -+:10336000EBF7F2FF10BDC0463C28020070B50446E2 -+:10337000D0F884000D4608B102F0D8FCD4F88000E3 -+:1033800008B105F0E5FBE06F08B1FFF737FFA06F6C -+:1033900008B105F06BFC606F08B1FFF773FFA06820 -+:1033A00008B100F0CDFB284621468C22E3F3A0F4BF -+:1033B00070BDC0462DE9F04F064689B00D4600208D -+:1033C0008C2191469846139FE3F382F4044600282B -+:1033D00077D000218C22DEF333F62760304605F0EB -+:1033E000B1F807AB0190059383464FF0000A2046E1 -+:1033F00041F2E44142463B460295CDF800A0CDF8AB -+:103400000C90049400F06EFD054600285BD0A0608F -+:1034100002F066DB2B696060E3602F4B1021A36430 -+:103420002E4A3B46266164643046DEF34DF62B6936 -+:1034300039461B6E2A489A6B2A4BEEF735F93A4605 -+:1034400050461299284B0096CDF8049002F0ECFDFE -+:103450000746002837D16368012683F87860362153 -+:103460003246D5F87C0223F08FD9204B2846E363FF -+:10347000FFF73CFF606730B36368284683F8A460B9 -+:1034800005F006FCA067F0B12846FFF7CBFEE06729 -+:10349000C8B1284605F088FBC4F8800098B12846DA -+:1034A00002F072FCC4F8840068B1114B01970093DC -+:1034B0000297039728680F490F4A234600F00CDD56 -+:1034C00008B9204604E020465946FFF74FFF002088 -+:1034D00009B0BDE8F08FC04655F78000FB4186007B -+:1034E00008B10200A0D6010029FB8000EFBEAD0D9F -+:1034F00099F88000E8D60100C542860041F2E44315 -+:10350000984201D00020AFE044F22033994200F00D -+:10351000AA800533994200F0A680223B994200F030 -+:10352000A2801E33994200F09E800333994200F03E -+:103530009A800C3B994200F096800133994200F04A -+:1035400092800133994200F08E80093B994200F04D -+:103550008A800233994200F08680013B994200F054 -+:103560008280023399427ED0013399427BD001336D -+:10357000994278D00533994275D00133994272D07F -+:10358000013399426FD001F53C43D8339BB2022BF3 -+:1035900069D94BF6D543CB189BB2022B63D944F2C1 -+:1035A000413399425FD0013B99425CD001F53C43E5 -+:1035B000B0339BB2022B56D944F25333994252D0C6 -+:1035C000043399424FD04AF69D1399424BD044F2AE -+:1035D0005433994247D0253B994244D0013B99420C -+:1035E00041D0063399423ED0013399423BD001335A -+:1035F000994238D04BF6C943CB189BB2022B32D933 -+:1036000044F2167399422ED0113399422BD0A3F570 -+:103610007973994227D001F53C43A0339BB2012B2B -+:1036200021D901F53C43BA339BB2022B1BD94BF68F -+:10363000CF43CB189BB2012B15D94BF6AB43CB181C -+:103640009BB2012B0FD901F53C43A8339BB2012B50 -+:1036500009D944F26333994205D00D33994214BF1E -+:103660000020012000E001207047C0462DE9F84FFE -+:1036700000264FF0010842F601334FF0FF344FF0BF -+:10368000640B0746A0F8283680F8474680F8C44403 -+:103690000221224680F8288080F868B780F84266C8 -+:1036A00080F84C8680F8436680F8498680F8466644 -+:1036B00002F05ED938464146324602F059D90C2113 -+:1036C0002246384602F054D90B213846324602F0E1 -+:1036D0004FD90E212246384602F04AD90D213846EC -+:1036E000324602F045D90F212246384602F040D931 -+:1036F00004210222384602F03BD9D7F860364FF059 -+:10370000030987F8488683F80690D7F860364FF0AB -+:10371000020A83F8079040F62A13A7F82A36A7F87A -+:103720002C369BB2A7F82E3640F62A13A7F830366F -+:10373000A7F83236A7F83436A7F8363640F62B13FA -+:10374000A7F838363B68A7F87A6583F895604FF09C -+:103750000703A7F83A364FF00403A7F83C360F23C7 -+:1037600087F80C37D7F89034A7F83E96C7F8803220 -+:10377000A7F840A6A7F87C68A7F87EB887F8EA61A2 -+:1037800087F8EB6187F81E6287F8EE6187F8EC61D5 -+:1037900087F8FA8187F80B6787F8A0649E71D7F8DD -+:1037A00094340B22C7F8843283F80680D7F8983413 -+:1037B0003146C7F8883283F806A0D7F89C343546DE -+:1037C000C7F88C3283F806903B6887F8506783F817 -+:1037D0004D805C633B6807F5CC6483F842803B68AE -+:1037E000043483F843603B6887F8CF6183F839601D -+:1037F0003B68204683F8AA803B6887F8DF6187F83A -+:10380000E081C7F8E46187F8E161DE66DEF318F471 -+:103810006FF0220387F864362C3387F865364A4602 -+:1038200004EB0A001A49DEF3A7F33B6887F869A6A0 -+:1038300087F8568587F8578583F84C603A6887F88B -+:103840009267A7F89067A7F88CB892F8463013F003 -+:10385000030F0CD092F94C304BB1D7F8FC04243054 -+:10386000F1F3F6F4D7F8FC043230F1F3F1F44FF44D -+:103870004873A7F85C373B68012287F8252883F84E -+:10388000A2203A684FF0FF3382F8B530BDE8F88FD8 -+:103890000FD40100836B70B5002483F84C40C36BD8 -+:1038A000012583F84C500646816BDFF711FEF16B62 -+:1038B0003046DFF70DFE21463046F6F349F2B36B92 -+:1038C000304683F84D40F36B294683F84D40D6F8D7 -+:1038D00060364FF0FF34DD72D6F860369C81F6F327 -+:1038E00037F2D6F860369B78AB4214D9B36B83F8C5 -+:1038F0004D40F26B4FF0FF3382F84D3096F8CB34E9 -+:1039000096F8CC2443EA022343F0800386F8CB34B4 -+:103910001B0A86F8CC3470BDD0F8AC1110B5044643 -+:1039200029B18068EBF3ACF60023C4F8AC31D4F8CD -+:10393000C41129B1A068EBF3A3F60023C4F8C43185 -+:10394000D4F8741529B1A068EBF39AF60023C4F8F3 -+:103950007435D4F8F81629B1A068EBF391F600237A -+:10396000C4F8F836D4F8FC1629B1A068EBF388F651 -+:103970000023C4F8FC36D4F8E036196A31B1A068E7 -+:10398000EBF37EF6D4F8E02600231362D4F83C155E -+:1039900029B1A068EBF374F60023C4F83C35D4F8E1 -+:1039A000941729B1A068EBF36BF60023C4F89437A1 -+:1039B000D4F8B01829B1A068EBF362F60023C4F87C -+:1039C000B03810BD70B505462D4980682A460023E1 -+:1039D000EBF372F6C5F8AC0100284ED0A86829496F -+:1039E0002A460023EBF368F6C5F8C401002844D04A -+:1039F000A86825492A460023EBF35EF6C5F874054E -+:103A000000283AD0A86821492A460023EBF354F64F -+:103A1000C5F8F806002830D0A8681D492A460023BA -+:103A2000EBF34AF6C5F8FC0638B3A86819492A46EC -+:103A30000023D5F8E046EBF33FF62062E8B1A86832 -+:103A400015492A460023EBF337F6C5F83C05A0B12B -+:103A5000A86812492A460023EBF32EF6C5F894070E -+:103A600058B1A8680E492A460023EBF325F6C5F89D -+:103A7000B008003818BF012000E0002070BDC0462B -+:103A80003DAA81003D708100253E81009591810015 -+:103A9000858F8100256E810089598100396B8100F5 -+:103AA000496F810010B50446006805F0B3FED4F8F4 -+:103AB000583113B10023C4F85831D4F83C0120B177 -+:103AC00005F00EF90023C4F83C31D4F8400120B1D0 -+:103AD00001F080F80023C4F84031D4F84C0120B143 -+:103AE00002F09AF80023C4F84C31D4F8540120B104 -+:103AF00005F070FA0023C4F85431D4F8600120B105 -+:103B000007F000F80023C4F86031D4F8383113B15D -+:103B10000023C4F83831D4F8640120B101F0FEFE6E -+:103B20000023C4F86431D4F8000520B107F026F969 -+:103B30000023C4F80035204605F0D2FA10BDC04677 -+:103B40002DE9F041054608B9074695E001F046FB2E -+:103B50000746284602F06AD800B90137D5F8F016B2 -+:103B600049B16868D5F8F426E3F3C2F00023C5F83C -+:103B7000F436C5F8F0362846D5F81815F8F38AF764 -+:103B80002846D5F8D816F8F385F7D5F82015284635 -+:103B9000F8F380F7D5F82C1521B168684FF49662D8 -+:103BA000E3F3A6F0D5F87C0220B105F051FA00232A -+:103BB000C5F87C3200242B19D3F84C1211B12846D9 -+:103BC0001BF03ADC0434202CF5D10121284631F0D9 -+:103BD000C9DD284601F078FE2E6BB16911B1284687 -+:103BE00031F054D80024B461D5F85C0101F05EFFD7 -+:103BF0002846FFF791FE2846FFF754FF2846D5F8E0 -+:103C00002C18DFF75DFCC5F82C48D5F8B84404E063 -+:103C100068681022E468E3F36BF02146002CF7D1CA -+:103C2000C5F8B844286816492A4600F08DD9D5F859 -+:103C3000340718B101F010F9C5F83447D5F8680118 -+:103C400018B106F0C5FFC5F86841D5F8181759B185 -+:103C50006868D5F81C27E3F34BF0C5F8184703E074 -+:103C60002846696807F0B0D8D5F87822002AF7D13D -+:103C70002846696800F034FD3846BDE8F081C0464A -+:103C8000BB5C8600036870B55E6905461449304622 -+:103C9000DEF372F6C0B218B930461249DEF36CF6A4 -+:103CA00040B2431E0E2B0ED8012803D1D5F8603642 -+:103CB000002204E0022806D1D5F8603601229A716C -+:103CC000D5F86036DA71084930462C6BDEF354F6CD -+:103CD00084F804012846EFF3EFF1012070BDC046DF -+:103CE000C65C8600CB5C86000E5D8600036870B5FE -+:103CF0001B490546D0F860465869DEF33DF6207052 -+:103D00002B6818495869D5F86046DEF335F6E0703F -+:103D1000D5F8602613780BB10F2B01D10123137056 -+:103D2000D5F8603601211A785A70D5F860462046D9 -+:103D3000DEF3DEF3A070D5F86026D3780BB10F2B3D -+:103D400001D10123D370D5F860360121DA781A71D8 -+:103D5000D5F86046E01CDEF3CBF3607170BDC04661 -+:103D600019D7010021D7010070B50446214600682B -+:103D700007F012F8C4F8000508B929305EE02068A1 -+:103D800005F050FD2068214601F08AF8C4F8340798 -+:103D900008B92A3052E02A4B2046C4F8583104F0C2 -+:103DA000B9FFC4F83C0108B9313047E0204600F0C3 -+:103DB0004BFFC4F8400108B932303FE0204606F01E -+:103DC000B3FEC4F8600108B9353037E020682146F9 -+:103DD000A2681C4B05F058F9C4F87C0208B93930C8 -+:103DE0002CE0204601F0EAFDC4F8640108B93C303B -+:103DF00024E0154B0125C4F838310023A4F83038ED -+:103E000084F8883884F88A3884F88958204601F084 -+:103E100013FFC4F84C0108B93F300FE02368214676 -+:103E200083F83A50236883F8A950206805F062F9B6 -+:103E300008B1452002E0236883F8A05070BDC04659 -+:103E4000EFBEADDE9D6D8100EFBEAD0DF0B5D0F8DB -+:103E500040750021AC2287B006463846DEF3F0F00C -+:103E60004FF06403FB85032387F8603000220123B1 -+:103E7000D6F85C014FF42C5121F0D4DFFF2804D197 -+:103E8000336B18691968EEF787FE31687886A6F8F3 -+:103E9000260691F84640336B00F44065FF201A89EE -+:103EA00000211B68B5F5406F14BF1425282501902B -+:103EB00004F00304D6F8600600910294039580781C -+:103EC000049007F138002DF0D9D8336893F84630C4 -+:103ED00013F0030F03D0FB8843F02003FB8007B0EF -+:103EE000F0BDC0462DE9F04F8DB01A9F9A460023D1 -+:103EF00007910B930646934610461799189A199BFB -+:103F00009DF85890009709F08DF9044610B11E23D2 -+:103F10000B937FE3FFF720FA179851460BAA00F0A6 -+:103F20000DFD0546002800F07583179AD0F860361D -+:103F300042604FF0FF32D0F8008083F81C21836B81 -+:103F4000C8F804A00363436B8660C362179BC0F884 -+:103F50007871C8F80C30B54B88F82190C8F8B030AB -+:103F6000032380F86937C0F8CC2880F89D4151467A -+:103F7000FFF77CFB2846F7F323F7284605F0D4F833 -+:103F80000446002840F04F8328463146179A53468E -+:103F900006F03EFEC5F8680108B91F23D3E2A44B22 -+:103FA0000194009302940394A249A34A2B462868E3 -+:103FB000FFF392F7A14B0194009302940394A0495C -+:103FC000A04A2B462868FFF387F7189A199B179E7B -+:103FD00002920393284607995A465346CDF800901B -+:103FE0000196049701F04AFA04460B90002840F02D -+:103FF0001A832B69186EEBF767FCA5F8BE082846F4 -+:10400000F5F38EF508B914239DE2264631460AAA37 -+:104010002846F7F311F231462846BDF8282001362C -+:10402000F7F314F2062EF1D1012488F89A4005F531 -+:10403000BE72286908F1140118F054DC8249D8F8DE -+:104040001400DEF399F481498146D8F81400DEF3B8 -+:1040500093F47F49A5F86208D8F81400DEF38CF4D5 -+:10406000B5F86228A5F86408A5F87827A5F87A07B6 -+:104070007849D8F81400DEF37FF47749A5F854089E -+:10408000D8F81400DEF378F485F856087349D8F8A8 -+:104090001400DEF371F485F858087149D8F814005B -+:1040A000DEF36AF485F85A086E49D8F81400DEF396 -+:1040B00063F485F857086C49D8F81400DEF35CF413 -+:1040C00085F859086949D8F81400DEF355F485F8E5 -+:1040D0005B086749D8F81400DEF34EF485F85C08F5 -+:1040E0006449D8F81400DEF347F485F85E086249A5 -+:1040F000D8F81400DEF340F485F860085F49D8F87A -+:104100001400DEF339F485F85D085D49D8F8140031 -+:10411000DEF332F485F85F085A49D8F81400DEF36C -+:104120002BF485F861082846FFF7E0FDD5F86026F6 -+:104130002B6B85F8F04785F8F14718691178D2782C -+:10414000EEF77CFF2869EA6AD0F8A03005F5CB7459 -+:104150005360D0F8A43021469360D0F8A830D360E3 -+:10416000D0F8AC301361D0F8B0305361D0F8B4302F -+:10417000936118F0E7DC08F14E0021463246DDF38A -+:10418000FBF6B5F8822144F221339A4217D00E3B58 -+:104190009A4214D007339A4211D010339A420ED06B -+:1041A000143B9A420BD007339A4208D010339A42FC -+:1041B00005D025339A4214BF0024012400E00124D5 -+:1041C00005EB84039B6B28462B63FFF75BFD08B967 -+:1041D0001823B8E1296B4FF00F0340F2FF36A1F826 -+:1041E000063101F1FC0201F58073A1F8086128464F -+:1041F00000F0B4FE2A6BD2F8FC30C2F8F830C2F8F6 -+:10420000F030D2F80031C2F8F4301368022B07D135 -+:10421000013B53752B6B284603215A7D01F0A8DB27 -+:1042200019F0010F30D000222FE0C0465F7D5A0503 -+:1042300079DB810078D48500BB5C8600E94800000A -+:104240005CD8010029D70100D6688600E2688600A4 -+:10425000F5688600076986001C6986002B69860060 -+:104260003A698600496986005A6986006B6986004A -+:104270007C6986008A69860098698600A66986003E -+:10428000B6698600C6698600012288F846200A21A0 -+:10429000284601F06DDB296B28461C31F9F3C6F383 -+:1042A0007F23296B00932B68002293F8463001F19D -+:1042B0001C0003F003030193503113462CF01CDF64 -+:1042C000B4F1FF3F3FF45DAF2846F5F383F44FF4BC -+:1042D000D163C5F874382846FFF746FD04460B90B5 -+:1042E000002840F0A0812869214619F00FDB2869D9 -+:1042F00098F83A1018F052DF28465146FFF762FB53 -+:1043000008B920231FE1284601F0DAFBC5F85C015B -+:1043100008B9212317E12846FFF798FD2146AD4A49 -+:10432000AD4B28460094019506F008FDAB4B6E4658 -+:104330001A1D07CA1B6886E80700072128462A4677 -+:1043400006F094DC04212846A54AA64B009401956A -+:1043500006F0F4FC0028C5F88C0701DA2223F2E00D -+:104360002846179906F006DD08B96423EBE0C5F886 -+:1043700004084FF0FF3728469B499C4A9C4B009706 -+:10438000FEF342F6C5F82C08002800F04C812846C0 -+:1043900001F0A4FA044608B12323D4E02B684FF0BF -+:1043A000060293F8A130A8F86420012B04BF402333 -+:1043B000A8F86430D8F88C304FF006064FF4397204 -+:1043C0001E805A80D8F890304FF0C4024FF001069A -+:1043D00005F5007128461E805A80063107F09EDCE4 -+:1043E000D5F83C010CF028DD08B185F8CF61022337 -+:1043F00085F8C0341C3385F8CB3410222B6B85F83C -+:10440000CC245B89022B02D81C2385F8CB342846A8 -+:10441000214685F8CA7485F8C97485F8C874F6F31E -+:104420003BF12B68284683F8B4402146C5F8D47187 -+:10443000F1F34AF185F8DC412846FFF72BFA19F031 -+:10444000080F18BF85F8DC4119F0100F03D028467B -+:104450002146F1F339F119F0020F13D0AB6B83F859 -+:104460004D40EB6B83F84D4095F8CB3495F8CC2458 -+:1044700043EA022323F080039BB285F8CB341B0A66 -+:1044800085F8CC3419F0040F03D028462146F5F303 -+:104490007FF419F0800F0DD095F8CB3495F8CC242B -+:1044A00043EA022323F010039BB285F8CB341B0AA6 -+:1044B00085F8CC342B6893F842308BB119F0600F3B -+:1044C0000ED019F0200F0CBFFF21002119F0400F72 -+:1044D000284649B214BF00226FF0000200F068FBCA -+:1044E00006220DF122004349DDF346F5B5F882219D -+:1044F00044F221339A4217D00E3B9A4214D007332C -+:104500009A4211D010339A420ED0143B9A420BD0EB -+:1045100007339A4208D010339A4205D025339A4285 -+:1045200014BF0027012700E0012705EB8706B46BC5 -+:104530000DF122012846224630F06ADBB16BA06102 -+:10454000886910B937230B936DE04430503128222D -+:10455000DDF312F5B36BB7F1FF3F9B699F62BFD0EC -+:10456000D8F85C30179E43F00403C8F85C30224B47 -+:10457000F560B3602846ECF7C7FF1B9A0AB1002329 -+:1045800013602B681D495869DEF322F230B1002117 -+:104590000A46DEF3DDF01A4BC0B218602B681949E9 -+:1045A0005869DEF315F230B100210A46DEF3D0F08F -+:1045B000154BC0B218602B6814495869DEF308F235 -+:1045C00030B100210A46DEF3C3F0114BC0B21860CF -+:1045D00028462CE039AE820001AE820034D90100B9 -+:1045E000D5A18100ADA181002D57810041578100E7 -+:1045F0001957810056D80100B542820035D7010015 -+:10460000EC27020041D70100102C020055D7010011 -+:10461000142C02001B9B0BB9184608E00B9B1B9E39 -+:104620000020336003E02846FFF78AFAF2E70DB076 -+:10463000BDE8F08F20230360436040F23C73836049 -+:10464000092330B50361836107330362303383622A -+:104650000F230822036340F29E3304240125002126 -+:1046600042618263C3640322A3F56773C460C561BA -+:104670004462C46244630164456402654166436503 -+:104680008465C265036630BD70B505460C4631B31E -+:10469000496D11B1C022E2F32BF3D4F88C1039B17B -+:1046A00028464FF43972E2F323F30023C4F88C3028 -+:1046B000D4F8901031B12846C422E2F319F3002354 -+:1046C000C4F89030E16929B128466822E2F310F37A -+:1046D0000023E36128462146B822E2F309F370BDC6 -+:1046E00070B50D460446002800F0E580D0F8181596 -+:1046F00039B128464FF48472E2F3FAF20023C4F889 -+:104700001835D4F8201539B128464FF48472E2F3F5 -+:10471000EFF20023C4F82035D4F8B41439B1284698 -+:1047200040F2AC42E2F3E4F20023C4F8B434D4F82B -+:10473000401531B12846AC22E2F3DAF20023C4F886 -+:104740004035D4F86C1229B1284607F019DE002351 -+:10475000C4F86C32D4F8FC1431B128464022E2F39C -+:10476000C7F20023C4F8FC34D4F8841671B123686E -+:1047700063B1DB6953B19B690C22013303FB02F285 -+:104780002846E2F3B5F20023C4F88436D4F8BC140A -+:1047900019B12846B422E2F3ABF2D4F8901421B157 -+:1047A00028464FF4AE62E2F3A3F2D4F8581631B1C2 -+:1047B00028463822E2F39CF20023C4F85836D4F895 -+:1047C000601639B128464FF49072E2F391F200235B -+:1047D000C4F86036D4F8F81731B128460622E2F35F -+:1047E00087F20023C4F8F837D4F8D81639B1284630 -+:1047F0004FF48472E2F37CF20023C4F8D836D4F884 -+:10480000E01631B128462422E2F372F20023C4F804 -+:10481000E036D4F8EC1631B128466822E2F368F2AB -+:104820000023C4F8EC36D4F8441731B12846EC2202 -+:10483000E2F35EF20023C4F84437A16B21B12846AD -+:104840004FF40672E2F354F2616B79B1896A31B1C7 -+:1048500080222846E2F34CF2626B002393622846E2 -+:10486000616B2C22E2F344F200236363216821B1DF -+:104870002846FFF709FF002323602369ABB1D3F873 -+:10488000F81028461822E2F333F223690026D96F84 -+:10489000C3F8F86019B128465822E2F329F22846F5 -+:1048A0002169FC22E2F324F226612846214640F6E3 -+:1048B000D402E2F31DF270BD2DE9F0411646B82294 -+:1048C00007460D4607F0FADD044610B940F2E93319 -+:1048D0002BE038462946682207F0F0DDE06110B988 -+:1048E00040F2044321E0FFF7A5FE38462946C022E6 -+:1048F00007F0E4DD606510B940F2EB3315E03846AF -+:1049000029464FF4397207F0D9DDC4F88C0010B98C -+:104910004FF47B7309E038462946C42207F0CEDD08 -+:10492000C4F8900038B940F2ED3321463360384680 -+:10493000FFF7AAFE00242046BDE8F0812DE9F041F2 -+:10494000174640F6D40280460E4607F0B7DD05460E -+:1049500000283BD02623C0F82838314640463A4646 -+:10496000FFF7AAFF2860002800F018818F4B056030 -+:104970001B683146C0F89C30FC22404607F09EDDA3 -+:104980000446286110B940F2ED3306E185603146F6 -+:104990004046182207F092DDC4F8F800B0B1404656 -+:1049A000314658222C6907F089DDE06770B12B6928 -+:1049B0004046DA6F31462C32C3F880204FF48472BF -+:1049C00007F07CDDC5F8180518B105E040F2EE33BC -+:1049D000E3E040F2EF33E0E0404631464FF48472CA -+:1049E00007F06CDDC5F8200510B94FF47C73D4E0F6 -+:1049F0004046314640F2AC4207F060DDC5F8B404F1 -+:104A000010B940F2F133C8E040463146AC2207F01D -+:104A100055DDC5F8400510B940F2F233BDE031462E -+:104A20004046ECF709FF0146C5F86C0210B940F2A8 -+:104A3000F333B2E028461AF091D84046314640227E -+:104A400007F03CDDC5F8FC0410B94FF47D73A4E019 -+:104A50002B680C22DB6940469B693146013303FB1E -+:104A600002F207F02BDDC5F8840610B940F2F533E9 -+:104A700093E040463146B42207F020DDC5F8BC047F -+:104A800010B940F2F63388E0404631464FF4AE624A -+:104A900007F014DDC5F8900410B940F2F7337CE05C -+:104AA0002A464FF4AE71D5F89034CB1801F5AE71AB -+:104AB000C2F894340432B1F5AE6FF4D140463146B9 -+:104AC000382207F0FBDCC5F8580610B94FF47E73A6 -+:104AD00063E0404631464FF4907207F0EFDCC5F8D2 -+:104AE000600638B140463146062207F0E7DCC5F8DB -+:104AF000F80710B940F2F9334FE0404631464FF421 -+:104B0000847207F0DBDCC5F8D80610B940F2FA333E -+:104B100043E040463146242207F0D0DCC5F8E006E9 -+:104B200010B940F2FD3338E040463146682207F0C4 -+:104B3000C5DCC5F8EC0610B940F2FE332DE0404666 -+:104B40003146EC2207F0BADCC5F8440710B940F250 -+:104B5000FF3322E0404631464FF4067207F0AEDCE8 -+:104B6000A86358B100F58673EB63404631462C22AA -+:104B700007F0A4DC0446686318B105E040F2014385 -+:104B80000BE040F2024308E040463146802207F045 -+:104B900095DCA06238B940F203433B6028464146A9 -+:104BA000FFF79EFD00252846BDE8F081BC260000E9 -+:104BB000D0F84031B1F1FF3F18BF83F89C13B2F138 -+:104BC000FF3F83F89E1383F89F2318BF83F89D232C -+:104BD0007047C04670B50446002831D000256319DF -+:104BE000D3F8501221B12368F4225868E2F380F020 -+:104BF0000435282DF3D1A16B69B194F8A3331BB10F -+:104C000023689868EAF32AF52368A16B9868EAF3A9 -+:104C100037F50023A363D4F8781221B12368E82282 -+:104C20005868E2F365F02368064918682246FFF3E6 -+:104C30008BF12368214658684FF46A72E2F358F00A -+:104C400070BDC046678986002DE9F0434FF46A7154 -+:104C500085B006464068E2F33BF0054608B9814658 -+:104C6000CFE000214FF46A728146DDF3E9F12E6056 -+:104C70007068E821E2F32CF0C9F87802002800F00F -+:104C8000B1800021E822DDF3DBF1002101236A1865 -+:104C9000C91808299372F9D1013B2B746B742B73DB -+:104CA000EB721A460121AB185218082A83F89413A4 -+:104CB000F8D11023EB74062385F827304FF0FF332B -+:104CC00085F82830213385F8A233052385F829306B -+:104CD0004FF47A736B864FF0C803AB86002385F8D8 -+:104CE0002A30023385F82B302B682A75A9741B688B -+:104CF0002A4693F8A1308B4218BF032385F82C3045 -+:104D00004FF0FF3385F89E3385F89F334FF40063EF -+:104D1000EB63012385F82D3004336B750223AB75EB -+:104D20006B7DD375AB7DD377013205F108039A42D1 -+:104D3000F6D100244FF0010895F82910284685F88F -+:104D40002E4085F82F8007F09DDE284686F8C38424 -+:104D500009F0B8DC042130462C4A2D4B0094019513 -+:104D600005F0ECFFA04268603CDB2A4B3068009302 -+:104D7000294B2A4901932A4B2A4A03932B46029432 -+:104D8000FFF3AAF0074668BBB06827492A463B46AE -+:104D9000EAF392F4A86328B3244C85F87C82231D9F -+:104DA00093E807006B4683E807002A4623683046ED -+:104DB000062105F05BDF4FF0FF3385F8A133336840 -+:104DC000284693F842100AF0DDDCC823C5F8E0322B -+:104DD000284609F0BDDE28464146ECF7CBFB85F8B6 -+:104DE000A3730EE0D5F8781219B17068E822E1F3E8 -+:104DF0007FF7706829464FF46A72E1F379F74FF054 -+:104E00000009484605B0BDE8F083C04695CB820056 -+:104E10001DCB820045CF820011E7820054D90100EA -+:104E200079D982006789860085A2000044D90100F3 -+:104E300070B5182686B00C46324668460549DDF343 -+:104E40009BF02046694632466D46DDF395F006B08C -+:104E500070BDC04634DB010070B5D0F8AC530446D9 -+:104E6000D0F8B063284603F09DFFD4F8D013A868AB -+:104E7000EAF3F4F3A868D4F8D013EAF301F40023BA -+:104E80002246C4F8D03330460449FFF35DF0F068A1 -+:104E900021464FF47E72E1F32BF770BDAB9986008B -+:104EA0002DE9FF413C23C1F824370523C1F82837F9 -+:104EB00007460D46C0684FF47E71E1F309F70446DA -+:104EC00000283DD000214FF47E724FF00008DDF342 -+:104ED000B7F0C4F8AC53C4F8B07384F8018020462E -+:104EE000E5F752FAC4F8C003284603F071FF0646FE -+:104EF00038B1F86821464FF47E72E1F3F9F6404686 -+:104F00001FE0204604F56371FFF792FFA8680E4981 -+:104F100022463346EAF3D0F3C4F8D00380B12046EA -+:104F20000DF054DC094B38460093094B09490193B5 -+:104F3000094A234602960396FEF3CEF7204600E088 -+:104F4000002004B0BDE8F0818D25830011B400007D -+:104F5000190F0100E4D90100AB99860010B5044691 -+:104F60000846B0F80CE0194642F256039E4506D8B2 -+:104F7000013B9E452ED2053B9E4509D02AE042F2D8 -+:104F800060039E451BD04EF2F5439E451CD021E0A8 -+:104F9000C389012B04D16FF03B0313604B3303E053 -+:104FA0006FF0450313605A330B602368D3F88030E9 -+:104FB00013F4805F13D01368023B13600FE06FF0AF -+:104FC0004A0313605A3309E06FF09503136003F549 -+:104FD000967303E06FF04A0313605F330B6010BDFC -+:104FE00070B504460025E06820B1054B1B68984762 -+:104FF0000023E36001350434062DF4D170BDC046B2 -+:10500000E0A685000D4B82685362002380F886304D -+:105010004FF00303A0F88C304FF00203A0F88E305D -+:105020004FF00703A0F888304FF00403A0F88A304F -+:1050300042F60133A0F89C307047C04664A8E7BE32 -+:10504000426C1F2A01D9002004E04FF00073134185 -+:1050500003F001007047C046026EB0F84A1010B568 -+:10506000946AB9B1FF2901D8012014E00B0B013B70 -+:10507000012B0FD8C1F30323092B0BD853B1C1F374 -+:105080000313092B06D801F00F03092B8CBF002056 -+:10509000012000E00020D26A41F2E4439A4210D19C -+:1050A000A4F58263073B012B01D83F2907E040F2BA -+:1050B0000C439C4204D015339C4202D1502900D8A5 -+:1050C000002010BD00B58E46C16E4FF0407394466F -+:1050D0007046C1F8603115E00379C2781B0443EAD9 -+:1050E000026382791343427943EA0223C1F86431AF -+:1050F000437802781B0243EA024382780730134365 -+:10510000C1F86431CEEB00036345E5D300BDC04672 -+:10511000C16E4FF48030C1F860011D4AD1F8603192 -+:1051200010B5D1F86441C1F86001D1F86031C1F81F -+:105130006421C1F86001D1F86031D1F86431934243 -+:1051400024D1144AC1F86001D1F86031C1F864215A -+:10515000C1F86001D1F86031D1F86431934215D1C2 -+:10516000C1F86001D1F860310023C1F86441C1F891 -+:105170008C31D1F82001084B984201D1012006E082 -+:10518000064B984214BF0020012000E0002010BD13 -+:10519000AA5555AA55AAAA55000400040004008483 -+:1051A000D0F8501810B5044641B1D0F84C284068EA -+:1051B0009200E1F39DF50023C4F85038D4F8481864 -+:1051C00059B16068DDF3F0F46068D4F84818E8225B -+:1051D000E1F38EF50023C4F8483810BD70B50469BA -+:1051E0000646206E08B1EAF729FB2046FFF7F8FED5 -+:1051F000A56F686A18B104F035F800236B62606F20 -+:1052000003F0C2FF206F05F05BFC616E29B12068DE -+:10521000A26EE1F36DF500236366206E18B103F012 -+:1052200021FB002323662046E7F7C4FF3046FFF743 -+:10523000B7FF002070BDC0462DE9F04F0368076935 -+:105240008FB00890DE691446FB6B0CA80821704AE9 -+:10525000DCF33AF7FB68002B40F0CE80F96E386E35 -+:1052600001F50071D7F800B0DFF31EF3BB6801460B -+:105270009868EAF3B7F1002800F0C680D7F860E03C -+:105280000CB9A44602E0FB6E03F5007CFB6E03F54F -+:10529000087504B13468B168BB687268F068D3F807 -+:1052A000283803915B490DF130094FF0FF38029225 -+:1052B0000590724606930791634649465846009505 -+:1052C0000194CDF81080ECF735F93168F8603A6E4A -+:1052D000FB6E01914F4900240546079103F51073B9 -+:1052E00049465846009402940394CDF810800594E2 -+:1052F0000694ECF71FF9316838613A6EFB6E019144 -+:1053000044490990079103F5207349465846009493 -+:1053100002940394CDF8108005940694ECF70AF9F2 -+:10532000316878613A6EFB6E01913A490A900791B3 -+:1053300003F5307349465846009402940394CDF81F -+:10534000108005940694ECF7F5F83168B8613A6E70 -+:10535000FB6E01912F490B90079103F5407349466D -+:105360005846009402940394CDF810800594069456 -+:10537000ECF7E0F83168F8613A6EFB6E019125496F -+:105380008246079103F550734946584600940294AB -+:105390000394CDF8108005940694ECF7CBF8099AA5 -+:1053A000A54214BF002501250A9BA24208BF45F073 -+:1053B00001050B99A34208BF45F00105A14208BFB2 -+:1053C00045F00105A24508BF45F001053862A0423D -+:1053D00014BF284645F00100B0B90F4B3C46D3F846 -+:1053E00084600546E06818B10C49B047C4F8A000D5 -+:1053F00001350434062DF5D1B96F08980831002223 -+:10540000E7F714F9012000E000200FB0BDE8F08FAD -+:10541000FB41860014260000E0A68500C326860016 -+:105420001FB5022303930C330446C0F84C383821CF -+:105430004068E1F34DF4C4F85008D0B1D4F84C28DA -+:1054400000219200DCF3FCF56068E821E1F340F410 -+:10545000C4F8480868B10021E822DCF3F1F5012323 -+:1054600000936068D4F8481803AAB333DDF334F42A -+:1054700001E04FF0FF3004B010BDC0462DE9F04F01 -+:10548000056997B0DDF884A014469B469DF88020FE -+:10549000EB63EB6FA860AB672A710746C5F800A005 -+:1054A00028460E46FFF7AEFD249B05F1640205F188 -+:1054B000680100930192029120465146229A239B53 -+:1054C00003F00EFB2866002800F0D581D5F8648033 -+:1054D00095494046DDF37CF220B100210A46DDF318 -+:1054E00037F186B240469149DDF372F248B10021AE -+:1054F0000A46DDF32DF14FF6FF7380B2984218BFD4 -+:10550000044630462146FDF7F9FF08B90C30B7E1F3 -+:1055100040F612010022A5F84060A5F84240286E2E -+:10552000E5F36CF6E866286EE5F3BAF4D5F86C900E -+:105530006864C7F80C902846FFF782FD08B90D3063 -+:105540009EE1286EEAF77EF92846002116F0C4DBBA -+:1055500028464FF0FF31E7F7A7F82846FFF7D8FDB8 -+:1055600008B90E308CE140467149DDF305F2FF28A1 -+:1055700008BF0120A5F84A002846FFF76DFD08B9CD -+:105580000F307DE16B494046DDF3F6F16A4985F85D -+:1055900048004046DDF3F0F16849E8644046DDF339 -+:1055A000EBF1296E2865CA6A41F26B039A420AD16F -+:1055B0008B6A4E2B07D1B5F84A30402B03D9EB6CE0 -+:1055C00043F00203EB64EB6C13F0200F04D00121D5 -+:1055D00028460A4617F036DFB5F840200123A7F821 -+:1055E0008021C5F89830B5F842303A68A7F8823182 -+:1055F0002B6E284613616B6C936095F8483082F8E7 -+:105600007C303A68B5F84A30B968A2F87A30EB6C69 -+:10561000C2F880302B6DC2F88430D5F898305362D0 -+:105620003A4605F057FA286708B9193028E12B6E79 -+:10563000CDF810A005932B6FCDF81CB0B5F8402025 -+:1056400006936B6CADF8302008932A6EB5F84230A3 -+:10565000CDF82C80ADF83230936B04A80D93D36B4A -+:105660000E93136C0F9395F848301093936A11932F -+:10567000B5F84A301293D36A1393EB6C14932B6DE5 -+:10568000159353680993D3680A9303F085FD6867FF -+:1056900008B91030F4E0B5F8421044F221339942D1 -+:1056A00017D00E3B994214D00733994211D01033D2 -+:1056B00099420ED0143B99420BD00733994208D03F -+:1056C0001033994205D02533994214BF0026012694 -+:1056D00000E0012631462846E6F7CAFFAA6F002EF1 -+:1056E0000CBF02230123136056603A6B286E1360CF -+:1056F0005660FC6AE5F3C2F32060D9F85C31696C4E -+:105700000F4A6B65AB65062301FB0323AC6FC5F83D -+:10571000B830686F49462268434603F0D5FE6062A0 -+:1057200080B91130ACE0C046D1AD86004837860064 -+:1057300084AE8600E5AE8600863786009E798600B8 -+:10574000301E0200AB6F696D586AEDF747FBAB6F17 -+:1057500003F1220203F11C01586A009203F11E02B8 -+:10576000203303F0F9FCAC6F606A03F005FD84F8A8 -+:105770002800AB6F3C6B586A03F0FEFC2075AC6FE1 -+:10578000606A03F0FDFCA96FA061CB8B032B01D0F5 -+:10579000122075E03B6B4A6A38461A618A8B1A817F -+:1057A000CA8B5A810A8C9A814A8CDA8140F2FF3284 -+:1057B0004FF00F03CA828B8201223146FFF73CFD76 -+:1057C00008B913305CE0B6F1FF3F3FF464AFAB6F54 -+:1057D0003A68586A92F89910EDF704FB00212846C0 -+:1057E00016F062DF08212846E7F772F8284618F01D -+:1057F00093DA286E2449254A00230097E5F3BAF48A -+:105800002846002118F06ADA2846E6F7FBFE08B9B8 -+:10581000153035E005F1DC042146DCF3CDF62046F9 -+:10582000DDF38AF048BB2046DDF396F0044620BB4A -+:10583000284616F099D8AB681B68D3F89C00F0B1E5 -+:105840000378E3B112492A46DDF39AF1AB681149B6 -+:105850001B682A46D3F89C00DDF3CCF1A868FFF75B -+:10586000DFFDE86858B1AB681B68D3F89C10DFF324 -+:10587000BFF1204604E00B2002E0162000E00020EB -+:1058800017B0BDE8F08FC04669C1830085C18300B1 -+:1058900025C0830049C0830010B590F85E300446EF -+:1058A0005BB90648EBF700FF054B20461A6805492F -+:1058B000FFF708FC012384F85E3010BD67DB0100B0 -+:1058C000FC580300A4D2020010B5044619F058DFBA -+:1058D00001220146204619F0CBDF10BD37B5054641 -+:1058E00019F04EDF0023C5F84C0280F848302A68D2 -+:1058F000044692F82F10284600914E32214618F0A7 -+:10590000EDDC30B12846214619F096DD4FF0FF302E -+:1059100003E02846214619F035DE3EBD37B5044682 -+:10592000002847D0D0F8201131B103689868E9F316 -+:10593000A7F60023C4F820312268136893F82F30AB -+:105940003BB3D2F8000501A92FF0C4DB13E0536884 -+:1059500013F0400F0FD0D4F82C31D51807E00B68A6 -+:105960004822C5F8103123685868E1F3C1F1D5F831 -+:1059700010110029F3D101A82FF0B4DB0246002852 -+:10598000E5D106E00B684068C4F840314822E1F3F5 -+:10599000AFF1D4F8401120680029F3D1064922461E -+:1059A0000068FEF3D1F22368214658684FF4A472D0 -+:1059B000E1F39EF13EBDC04691BA8600F0B54FF4CA -+:1059C000A47185B005464068E1F382F1064608B946 -+:1059D000074655E000214FF4A4720746DCF330F38C -+:1059E000294B35600093294B29490193294B002409 -+:1059F00003932868284A33460294FEF36DF2314639 -+:105A00002A6B1368022B03D1537D0BB9163300E0C8 -+:105A1000302301340B744431042CF1D1A8681F49A0 -+:105A20002A460023E9F348F60446C6F8200130B9B7 -+:105A3000686831464FF4A472E1F35AF11FE04FF465 -+:105A40009673C6F81C3145F27353A6F838314FF0FF -+:105A50004603A6F83A31124B0024C6F840412846C6 -+:105A600000934FF48A710F4A0F4B019505F066F9C8 -+:105A7000A042C6F82C0103DA3046FFF74FFF274655 -+:105A8000384605B0F0BDC046F90C8400DD120100B7 -+:105A900094DB01007D0A840091BA86003D068400F3 -+:105AA000D9128400E5128400A512840010B50146C5 -+:105AB00020B10368B022D868E1F31AF110BDC046E6 -+:105AC0002DE9F34107680546B021F868E1F300F1DC -+:105AD000064608B980468BE00021B02201AC804622 -+:105AE000DCF3AEF20422002137607560C5F85C611A -+:105AF0002046DCF3A5F22A6892F87C30012B07D906 -+:105B00003D495069DCF364F7014690B120460AE054 -+:105B100050693A49DCF330F70928034609D8384977 -+:105B2000204601EB83010322DCF342F300238DF8CE -+:105B3000073001AC0322214606F10800DCF338F3FC -+:105B40000023F3722B682F495869DCF315F7396984 -+:105B5000F060CA6A41F26B039A420CD18B6A8B2BBC -+:105B600009D1022807D1204627490422DCF300F39B -+:105B700008B90323F360396941F26B03CA6A9A4298 -+:105B80000DD18B6A932B0AD101A820490422DCF3A2 -+:105B9000EFF220B9F368042B01D10233F36001AFB7 -+:105BA000284639461FF054DE044650B91849384695 -+:105BB0000322DCF3FDF2284639468DF807401FF03A -+:105BC00047DE05F5AA60394603220A30DCF3F0F21D -+:105BD000002405F5AA600F4985F85D450E300322C3 -+:105BE000DCF3E6F285F861453046394620F0BADA52 -+:105BF0004046BDE8FC81C046B3C48600B9C48600F7 -+:105C0000CE028600BCC48600C3C4860071C2860072 -+:105C1000C6C48600CAC4860070B50568044622461C -+:105C200028680449FEF390F1686821465022E1F3A8 -+:105C30005FF070BD3CE486002DE9FF410546502130 -+:105C40004068E1F345F0064608B904465AE00021F1 -+:105C500050220446DCF3F4F1FF210422356006F102 -+:105C60003B00DCF3EDF1284619F08ADD002790F8BF -+:105C7000483080F8387586F83B3096F840304FF061 -+:105C8000FF3843F00803202186F840301F4AC6F849 -+:105C9000488006F11800DCF317F27061304626F0F8 -+:105CA000B5DF042128461A4A1A4B0097019605F0E1 -+:105CB00045F8B84230611FDB174B02970093174B32 -+:105CC00017490193174B184A039328683346FEF38C -+:105CD00003F188B9012586F83A50304629F00ADAEE -+:105CE00018B13046294627F0FFD9A37BA4F84C8091 -+:105CF00043F00203A37305E0686831465022E0F3E5 -+:105D0000F7F70024204604B0BDE8F08140E48600A7 -+:105D10001DDF8400F9DE8400F51D01001DED840007 -+:105D200024E40100DDD084003CE4860070B5054623 -+:105D3000002826D00368134918682A46FEF304F1A8 -+:105D40006B6905E01C68596828462AF0E7DD2346A0 -+:105D5000002BF7D12B6905E01C68596828462AF00A -+:105D6000DDDD2346002BF7D1A96A21B12B689022F3 -+:105D70005868E0F3BDF72B68294658682C22E0F3F9 -+:105D8000B7F770BD91E6860030B52C21044685B08A -+:105D90004068E0F39DF708B9054618E000212C2281 -+:105DA0000546DCF34DF10823AB610A4B2C600093F0 -+:105DB0000023019302930393074A2B462068074967 -+:105DC000FEF38AF02268012382F896302B71284670 -+:105DD00005B030BD050B850091E6860004E50100A5 -+:105DE0002DE9F047154680460F461E46E5F346F07E -+:105DF000002181464046E5F313F200220446114695 -+:105E00000F480B185B6873B90C3302FB03F31D508A -+:105E10001A18636A576096600A4A45EA03031360DA -+:105E20006362012404E001320C31052AE8D1002428 -+:105E300040464946E5F3F4F12046BDE8F087C04608 -+:105E40003C260000782600002DE9F04705468846EC -+:105E5000E5F350F100212846E5F3E2F10646284635 -+:105E60006C69AF69E9F7E8FA0A2C814616D90F2C5C -+:105E700019D02846E9F768FD142C054603D9B36804 -+:105E800023F00803B360B36843F00103B36003D9A0 -+:105E9000B36843F00803B360012211E0022C02D87A -+:105EA000174D30220CE02846E9F758FDD6F8A4300B -+:105EB000054623F0FF0343F00203C6F8A430022294 -+:105EC000B36813F0010F07D107F01803082B14BFB4 -+:105ED0004FF4E115B5FBF2F507F0030700240BE0E2 -+:105EE00006F54073B8F1000F05D003EB04204946D6 -+:105EF0002A460023C0470134BC42F1DBBDE8F087ED -+:105F000000C63E0537B5134B1546136001E0114B33 -+:105F100013600432ADF17C039A42F8D3033020F0D1 -+:105F200003000D4BC0EB01041C600C4B00211960F9 -+:105F30000B4B05F5A05219600A4B083C19600A4B3F -+:105F400041601D60094B1A60094B1960094B0460E0 -+:105F500058603EBD4B415453C826000088260000BF -+:105F6000A4260000CC260000F8270200FC2702002F -+:105F700090260000C0260000436910B5142B01DDF7 -+:105F800002F09CFB10BDC0461FB5E8200021E0F3E5 -+:105F90003DF20C4C2060A0B10021E822DCF350F06F -+:105FA00004AA012342F8043D013B0093064B2168FB -+:105FB000186840F23C73DCF38FF620680E21DCF3A6 -+:105FC000D5F61FBDBC26000024280200B1F5E06F05 -+:105FD00073B505460C46164606D1036900910021AB -+:105FE00001911C680A460CE00D4B00221868E5F38D -+:105FF00005F1014680B12B690022009401921C68D2 -+:1060000028463346A04738B1064AA86113680020E5 -+:106010002B626E61156001E04FF0FF307CBDC04621 -+:106020008C260000202802002DE9F04710200E46A3 -+:10603000002117469946E0F3E9F1044610B96FF0E4 -+:106040001A001EE0104D2868E4F318F7099B8046FB -+:1060500023B9286831463A46E5F3D0F02868E4F3DE -+:1060600089F701238340094AE360089BC4F8049040 -+:10607000A36013682868236041461460E5F3D0F0FC -+:106080000020BDE8F087C0468C260000982600005E -+:1060900007B50021E5F3C4F0074B4FF40061186029 -+:1060A000064B00F57060186000200246044B00901B -+:1060B0000190FFF7B9FF0EBD9C260000F4270200F7 -+:1060C0006D60800037B5234B234C02AD00211C22AC -+:1060D00045F8043D2046DBF3B3F7012323601F4B53 -+:1060E000A5F5A0551B6843F8044C00F00DF92946AE -+:1060F0002A461B48FFF706FFE0F344F300F042F89E -+:10610000002002F01FFA174B174C186002F0BCFC7D -+:106110002060FFF7BDFF206800F01EF9E9F716F8D0 -+:10612000206800F0A5F8002210481149E0F3E2F4DD -+:10613000002210481049E0F3DDF410490022104815 -+:10614000E0F3D8F42068FFF717FFFFF71DFF206882 -+:106150003EBDC046ADDEADDE00280200F81E0200E6 -+:1061600000590300242802008C260000D81F860056 -+:1061700059EF0000DB1F8600656580008D608000A0 -+:10618000DE1F860070B5A4200021E0F33FF1124D20 -+:10619000286080B10021A422DBF352F74FF4806025 -+:1061A00000212C68E0F332F1A060286884682CB9E3 -+:1061B000E0F392F02C604FF0FF300CE04FF480627F -+:1061C000C2608460446100212046DBF339F72A680D -+:1061D000024B00201A6070BD38280200D42600004F -+:1061E00070B51C4D06462B6833B91B4C23680BB9A0 -+:1061F000FFF7C8FF23682B60164C184B20685861C6 -+:1062000030B3002505604560336CC0F89C500E3BF0 -+:10621000012B03D930461249FFF716FE114A936845 -+:1062200013B12368C3F89C20246807E0D4F89C00CD -+:1062300018B1A368595DE0F349F4013523699D4223 -+:10624000F4D3094809492246E0F354F4014B186895 -+:1062500070BDC046D4260000382802000028020085 -+:106260009562020028280200BD218600A5688000F2 -+:1062700010B54022002305490446FFF7B1FD044B49 -+:1062800000229A602046FFF7ABFF10BDA96980008D -+:106290002828020070B51B4DAE68002E31D11409BC -+:1062A0002C60AB8104F561444FF4E13394FBF3F4CB -+:1062B000A8606960284603218022E0F3FDF32846A8 -+:1062C0003146E2B2E0F3F8F3284601212212E0F36E -+:1062D000F3F303210A462846E0F3EEF301210A46D0 -+:1062E0002846E0F3E9F3284604210822E0F3E4F32A -+:1062F000284602210122E0F3DFF34FF47A70E0F345 -+:106300002BF270BD28280200104A0721136843F0C1 -+:1063100010031360136843F008031360136823F439 -+:1063200000731360E832136843F0807343F48033E2 -+:106330001360074B00221960043B1A6008331A6887 -+:106340001960044B20221A607047C04614ED00E02B -+:10635000241000E000E400E02DE9F041054600F0E3 -+:10636000ADF82A48E8F778FC2846E9F73BF8284BCF -+:10637000284AC318B3FBF2F3274A28461360E9F70B -+:10638000D9FA00F5787007304FF47A73B0FBF3F068 -+:10639000224B234A18602B6A2249002BCCBF6FF096 -+:1063A0007F4340F2FF3313601D4A1F4F1368B3FB56 -+:1063B000F0F31360284620220023FFF711FD002090 -+:1063C0001A49DCF3D9F204463860E8B12846E9F707 -+:1063D00009F8B4FBF0F0861E002E15DD144C0021E8 -+:1063E00034222046DBF32CF6124B4FF47A71A36073 -+:1063F0006560204606FB01F10122DFF3FBF618B1D0 -+:1064000028463968DEF306F2BDE8F08191F100001C -+:106410003F420F0040420F00D0250000C825000079 -+:10642000CC25000001678000E8260000BEE60100E0 -+:1064300040280200E56680002DE9F04707461E4629 -+:1064400015460C46E4F356F63846E4F317F52946AC -+:10645000324681463846E4F3D1F63846E4F38AF50D -+:1064600040F62A01064600223846E4F3C7F6054600 -+:106470008CB1012414FA06F3826932EA030802D1CE -+:106480002046E8F7A9FB701C14FA00F0E8F786FB39 -+:10649000C5F818800CE00124701C14FA00F0E8F72D -+:1064A0009BFB2046B440E8F779FBAB691C43AC6129 -+:1064B00038464946E4F3B4F6BDE8F0872DE9F047E5 -+:1064C0000746E4F317F6384640F60E010022E4F3DF -+:1064D00095F60446002831D0D0F80080056838468B -+:1064E000E4F3DEF40428064604D827D1C5F30243BA -+:1064F000032B23D100204849DCF33EF2F0B9474991 -+:10650000C8F3031212E0013A072E22610AD90C2EB9 -+:1065100008D0236C13F4806F02D013F4006F01D104 -+:1065200008B903E0012041F004516161002AEAD179 -+:10653000D4F8E83123F01003C4F8E831002240F623 -+:106540002A013846E4F35AF6354C20603846E4F325 -+:10655000A7F4344B22681860136843F6A12443F073 -+:1065600080731360136843F0020313600023C2F8C2 -+:10657000E03103E00A20E0F3EFF00A3CDFF8A090FE -+:10658000D9F80030D3F8E03113F4003F01D1092CE1 -+:10659000F0D100210B4638464FF40062FFF74CFF64 -+:1065A00000210B46384640F61202FFF745FF002156 -+:1065B0000B46384640F62902FFF73EFF38460121D8 -+:1065C000E8F73EFF00201849DCF3D6F1E0B1384689 -+:1065D000E4F354F440F62A01804600223846E4F3FE -+:1065E0000DF646690446D0F898503846E4F346F470 -+:1065F0000123834045F00105334363613846C4F805 -+:1066000098504146E4F30CF6D9F80020136A43F0A1 -+:1066100003031362BDE8F0872DE70100FF7F01004F -+:106620007428020078280200BEE6010010B58469D3 -+:10663000A068FCF729FCE068E9F7E4F8002010BD49 -+:1066400010B584690021342204F11C00DBF3F8F456 -+:10665000034BA06863622462EBF794F8002010BD3E -+:1066600005AA80002DE9F347DFF8AC809946D8F8F9 -+:1066700000300546072B0F46924643DC01F062FFCF -+:1066800050210646E0F324F3044600283AD00021C6 -+:106690005022DBF3D5F4D8F8003065602360A4F80D -+:1066A00014902761E660204641F2E4414A463346B1 -+:1066B0000097CDF804A0FCF739FCA06010B30020CF -+:1066C0000A990B9A114B0095CDF804A0FFF7ACFC8A -+:1066D00018B1A068FCF7D8FB14E0A068E2F3B4F6A8 -+:1066E0000B49A061D8F800202846DBF3FDF40948E7 -+:1066F0002946EAF7D9FFD8F8003020460133C8F818 -+:10670000003000E00020BDE8FC87C04631AA8000D0 -+:106710005CB102003CB102007C280200014610B5C9 -+:1067200050228068E0F3E4F210BDC046C36B10B5A0 -+:106730001BB100225A62836B5A62C068FFF7EEFFFA -+:1067400010BDC0462DE9F041184E1C46337807466F -+:10675000072B904626D820464C21E0F3B9F2054697 -+:1067600000B300214C22DBF36BF46C602F60C5F8A2 -+:1067700008803378204685F8443001333370022393 -+:10678000AB640821E0F3A4F20446286420B10021A0 -+:106790000822DBF355F406E029464C22E0F3A8F288 -+:1067A000254600E000252846BDE8F081802802004B -+:1067B0002DE9F04FD1F8FC3091B00F93054603F569 -+:1067C0006063079335E10FAF0E2200232846394658 -+:1067D000D9F37AF60F28044600F0368100222846C5 -+:1067E00039461346D9F370F610F00E0640F02681B4 -+:1067F00040F23B43B3EB145FC4F30B21C0F3041826 -+:1068000004D140F6FF73994200F01381C0F3442293 -+:106810000992002A00F00D81C0F3C443C0F3843B09 -+:1068200013EB0B02089319D140F26733994240F001 -+:1068300000810EAB01930DAB02930CAB03930BAB3A -+:1068400004932846394613460092D9F3DBF5002815 -+:1068500000F0EF800E9BC5F85433EAE0D5F8CCA0E9 -+:1068600005EB8A03C3F8D4423446C3F81403C3F8D3 -+:10687000D0100BE00122284631461346D9F324F606 -+:1068800000F00E00022840F0D980013444450FAEDC -+:10689000F0D1002213460DF138090DF134080CAF88 -+:1068A0000BAC284631460092CDF80490CDF8088014 -+:1068B00003970494D9F3A6F50246E8B94023009360 -+:1068C000284631461346CDF80490CDF8088003974A -+:1068D0000494D9F397F510B14FF001080EE00D9B29 -+:1068E000002B40F0AB800B9B002B40F0A7800C9B53 -+:1068F000B3F5805F40F0A2804FF000080E9A05EBE0 -+:106900008A03C3F810210C9A0124C3F8D0210EABDE -+:1069100001930DAB02930CAB03930BAB00220493DA -+:1069200028460FA923460092D9F36CF508B9012730 -+:1069300027E0012C40F086800C99B1F5805F40F093 -+:1069400081800E9B05EB8A02C2F89031C2F81012CA -+:1069500078E00024002300930EAB01930DAB02936B -+:106960000CAB03930BAB049328460FA93A4623467E -+:10697000661CD9F347F508B13446EBE7002E5DD02D -+:106980000137099A9742E4D100241FE0C023009305 -+:106990000EAB01930DAB02930CAB03930BAB0493C3 -+:1069A00028460FA922460023D9F32CF5002845D00C -+:1069B0000B9B002B42D10C9BB3F5805F3ED124B9D9 -+:1069C0000E9B05EB8A02C2F8943201345C45DDD19E -+:1069D000002423E0802300930EAB01930DAB0293C0 -+:1069E0000CAB03930BAB049328460FA9012F0CBFEC -+:1069F0002246621C0023D9F305F5F8B10B9BEBB9D5 -+:106A00000C9BB3F5805F19D1BBF1000F05D124B900 -+:106A10000E9B05EB8A02C2F894320134089B9C421B -+:106A2000D8D1B8F1000F04D1D5F8CC300133C5F876 -+:106A3000CC300F9B079A9342FFF4C5AE0023C5F8F4 -+:106A4000CC3001E0013462E711B0BDE8F08FC04600 -+:106A500082604160016070470EB4F3B581680646FC -+:106A6000012901D8002044E008AB4068079A01934F -+:106A7000DBF31CF4B0F1FF3F074603D0B368023BE1 -+:106A8000984203DD00231846B36032E070683D2170 -+:106A9000DBF33AF330B373683568C3EB00041EE0F0 -+:106AA00028462246DBF34CF2A8B92B5D3D2B12D1D0 -+:106AB0002846DBF355F37268441CBA1829190132D1 -+:106AC0002846521ADBF38EF273681B1B7360B3689F -+:106AD0001B19B36006E015F8013B002BFBD1716870 -+:106AE0008D42DDD3B368781C1B1AB36073681B1822 -+:106AF0007360BDE8FC4003B07047C0462DE9F0412B -+:106B0000C1EB0204012C0E461F46DDF8188010DD93 -+:106B10002146E0F3DDF0054610B96FF01A000DE0F4 -+:106B200031462246DBF328F200203D60C8F80040E1 -+:106B300004E000233B60C8F800301846BDE8F0814F -+:106B40002DE9F04FA5B008914FF4805109900792BC -+:106B50000693E0F3BDF00A9018B96FF0010401F05C -+:106B600029B921A80A994FF48052FFF771FF4FF419 -+:106B700080520A980021DBF363F200234FF0FF32CA -+:106B80008DF844300B930D930E9201F0DEB80D9BFF -+:106B9000089A002152F8239001230C910F930F9B28 -+:106BA00019F8012073B1531EDBB2FD2B01F101086E -+:106BB00098BF19F808B016468CBF4FF0000B08F1CB -+:106BC00001080CE002F1FF33DBB2FE2B93462CBF31 -+:106BD0001646802628BF4FF0000B01F101080BEB91 -+:106BE0000803B3F5607F81F2AD80202E2AD005D84E -+:106BF000152E0AD01B2E6DD001F078B8222E3AD077 -+:106C000036D3802E72D001F071B808EB09035A78A0 -+:106C100019F8083003EB0223072B13DD09F10204F6 -+:106C2000444421AD874922462846FFF715FF2046F8 -+:106C3000DBF396F209F1030200EB080382492846D0 -+:106C4000D2184FE008EB0904637819F8082021AD49 -+:106C500002EB032228467D49FFF7FEFEE378A27887 -+:106C600028467B4902EB0322FFF7F6FE01F03EB80F -+:106C700019F8082003E00C9B0C2B03D100220C9286 -+:106C800001F036B89DF84430002B41F0318019F8FE -+:106C90000830042B41F02C8009F1020404EB0805B4 -+:106CA0002846DBF359F6002841F0228014F808301A -+:106CB00013F0010F41F01C80284611A9DBF394F476 -+:106CC0000E9BB3F1FF3F41F0138008EB09039A7963 -+:106CD000DB790DE108EB0903DC799A795D4921A89C -+:106CE00042EA0422FFF7B8FE01F002B819F80830B2 -+:106CF000822B00F2FD87DFE813F09200B300380129 -+:106D00003B02D4021102CB01DA014701EA02FB0285 -+:106D100010031703FB077F020302FB073603570329 -+:106D200097007A037F0390039503F700E903FB07BD -+:106D3000770107047F01FB07FB07FB071004220410 -+:106D4000270472045305FB07FB0721068D0088000A -+:106D50008300AE06D306DA06E106FB0726037101BF -+:106D6000FB07FB070001F007E806FB07FB07FB0733 -+:106D7000FB07FB07FB07FB07FB0787011307280738 -+:106D8000490764077F079907B307CD07D407FB07B7 -+:106D90008E01FB07FB07FB07FB07FB07FB07FB0756 -+:106DA000FB07FB07FB07FB07FB07FB07FB07FB07D3 -+:106DB000FB07FB07FB07FB07FB07FB07FB07FB07C3 -+:106DC000FB07FB07FB07FB07FB07FB07FB07FB07B3 -+:106DD000FB07FB07FB07FB07FB07FB07FB07FB07A3 -+:106DE000FB07FB07FB07FB07FB07FB07FB07FB0793 -+:106DF000FB07FB07FB07FB07FB07FB07FB07DE07A0 -+:106E000009EB0804002500F00BBE09EB080400257F -+:106E100000F0F4BD09EB0804002500F0DEBD0E49CA -+:106E200008EB090321A8DDE008EB0901CA780B791A -+:106E3000120442EA03624B7821A81A438B7807496F -+:106E40007EE2C04640B202009CB40200FEB10200E5 -+:106E500093B5020062B80200D9B3020075B1020016 -+:106E600008EB0904A378627821AE02EB0322AE4955 -+:106E70003046FFF7F1FD2379E2783046AB4902EB6B -+:106E80000322FFF7E9FDBBF1060F40F23187A3793A -+:106E900062793046A64902EB0322FFF7DDFDBBF124 -+:106EA000080F40F22587237AE2793046A14902EBA8 -+:106EB0000322FFF7D1FDBBF10A0F40F2198709F158 -+:106EC0000A0409F1090514F8083015F808209A4950 -+:106ED00002EB03223046FFF7BFFD14F8083015F827 -+:106EE0000820964930464CE008EB09039A785B7815 -+:106EF00003EB02220E9200F0FBBE0623904ABBFB7E -+:106F0000F3F309EB08074FF0000A137027E019ADFF -+:106F1000534610218B4A1DAE2846DBF3D5F053466D -+:106F20001021894A3046DBF3CFF0BB787A7821AC68 -+:106F300042EA032229462046FFF78EFD7A79BB7983 -+:106F4000120442EA0362FB7820461A433B79314639 -+:106F500042EA0322FFF780FD0AF1010A0637784B67 -+:106F60001B789A45D3DB00F0C3BEBBF1020F21A80A -+:106F700008EB090202D175495278B3E69378734958 -+:106F8000527802EB0322ADE608EB0904A27863789D -+:106F9000BBF1040F03EB022505D92379E2781B0628 -+:106FA00003EB02431D4321AE304669492A46FFF7F1 -+:106FB00053FDBBF1060F40F29B86A2796379BBF1CA -+:106FC000080F03EB022505D9237AE2791B0603EBB0 -+:106FD00002431D435F4930462A4683E65E4908EB7B -+:106FE000090321A85A787DE608EB09039C785A78B2 -+:106FF000524921A800F05BBE0BF101035FFA83FB4D -+:1070000000230F9300F074BE08EB09039C785A78B4 -+:10701000524921A864E64A4B4FEADB0209EB080714 -+:107020004FF0000A1A702DE01DAD53461021454A5D -+:1070300019AE2846DBF348F053461021424A304649 -+:10704000DBF342F0FA783B79120442EA03627B7880 -+:1070500021AC1A43BB78294642EA03222046FFF7B7 -+:10706000FBFCFA793B7A120442EA03627B79204600 -+:107070001A43BB79314642EA0322FFF7EDFC0AF1DD -+:10708000010A08372E4B1B789A45CDDB00F030BE45 -+:1070900021AD08EB0904284631496278FFF7DCFC92 -+:1070A000BBF1020F40F224862E49284659E121AD5A -+:1070B00008EB0904002228462B496378FFF7CCFC33 -+:1070C000BBF1020F40F20F86012228462649A37821 -+:1070D000FFF7C2FCBBF1030F00F005860222284631 -+:1070E0002149E378FFF7B8FCBBF1040F00F0FB8502 -+:1070F00028461D4903222379FFF7AEFC00F0F3BDBB -+:1071000021AC08EB090517496A782046FFF7A4FC73 -+:107110001549AB782046012200F0DCBD134908EB8D -+:10712000090321A85EE7C046B4B6020075B70200A5 -+:10713000BEB502000AB2020021B3020021B2020071 -+:107140008128020038E7010043E7010056B302003E -+:1071500037B7020082B2020054B40200CAB702007C -+:1071600081B10200ACB7020081B4020045B8020050 -+:10717000ABF10203082B00F2BB85DFE813F0090036 -+:10718000B905B905B905B9052B001C0015000E009D -+:10719000A74908EB090321A824E708EB090321A864 -+:1071A000A4495A7AFFF758FC08EB090321A8A04923 -+:1071B0001A7AFFF751FC09F1070521AC9E4915F831 -+:1071C00008202046FFF748FC20469C4915F8082077 -+:1071D000FFF742FC9A4D09EB0804A3786278294630 -+:1071E00002EB032221A8FFF737FC964B0935023446 -+:1071F0009D42F2D100F07CBDBBF1140F19D0BBF160 -+:10720000170F04D0BBF1130F1AD000F071BD21ACE1 -+:1072100008EB09058C49AA7D2046FFF71DFC8B4928 -+:107220006A7D2046FFF718FC204689492A7DFFF732 -+:1072300013FC08EB090321A88649DA7CFFF70CFC54 -+:10724000854D09EB0804A3786278294602EB0322F6 -+:1072500021A8FFF701FC814B093502349D42F2D190 -+:1072600009EB08057E4E2C46237AE279314602EB83 -+:10727000032221A8FFF7F0FB7A4B0B3602349E4223 -+:10728000F2D1794CAB7B6A7B214602EB032221A829 -+:10729000FFF7E2FB754B0B3402359C42F2D100F054 -+:1072A00027BD08EB0901C8784A788B7800900879E7 -+:1072B00001904879029088790390C8790490097AFE -+:1072C00021A805916A49FFF7C7FB00F011BD09EB42 -+:1072D000080400256378FF2B04D021A865492A46BD -+:1072E000FFF7BAFB01350134042DF3D100F000BDE6 -+:1072F00008EB09035A780AB19B7823B921A85E49A3 -+:10730000FFF7AAFB03E021A85C49FFF7A5FB08EB08 -+:1073100009035B49DA7821A8E4E408EB09039C78C7 -+:107320005A78584921A8DBE408EB0901CA780B799F -+:10733000120442EA03624B7821A81A438B7852491F -+:1073400042EA0322CEE421AD08EB090428464F4966 -+:107350006278FFF781FBBBF1020F40F2C9844C4910 -+:107360002846A278BEE409F1010515F8082021ACF1 -+:10737000484902F00F022046FFF76EFB15F808207F -+:107380004549120909F102052046FFF765FB15F88A -+:107390000820424902F007022046FFF75DFB15F87E -+:1073A00008203F4920461FE009F1010515F8082093 -+:1073B00021AC3C4902F00F022046FFF74DFB15F8C7 -+:1073C00008203949120909F102052046FFF744FB5C -+:1073D00015F80820354902F007022046FFF73CFB6C -+:1073E00015F8082032492046C2F3C1027AE4314937 -+:1073F00008EB090321A8F5E521AC08EB09052E49A6 -+:107400006A782046FFF728FB2C49AA782046FFF728 -+:1074100023FB2B49EA78204664E42A4908EB090358 -+:1074200021A8DFE5284908EB090321A8DAE5C046D1 -+:10743000ECB60200ADB602009FB50200E3B1020057 -+:1074400022B402003DB40200D4B10200EDB2020049 -+:1074500049B30200F1B1020002B602001DB60200FB -+:10746000EEB302000FB40200F9B602001AB7020030 -+:1074700050B7020097B1020025B802003AB80200E6 -+:1074800058B802005DB4020004B80200B6B70200AA -+:10749000E4B3020068B102003DB40200B3B10200DF -+:1074A00047B7020091B7020075B20200F7B70200B9 -+:1074B000C1B7020010B8020068B40200A4B602000E -+:1074C0004AB4020046B502000AB3020009F1010401 -+:1074D00004EB08052846DBF33FF2002840F008845F -+:1074E00014F8083013F0010F40F00284284611A967 -+:1074F000DBF37AF00E9BB3F1FF3F40F0F98308EB2A -+:1075000009035A799B79F3E408EB09039A785C78CC -+:107510008C49120621A8FFF7E3BB08EB090421AD53 -+:10752000894962782846FFF797FA8849A278284661 -+:10753000FFF792FA2379E2788549284621E58549C3 -+:1075400008EB090321A84DE508EB0906B378747828 -+:1075500021AD04EB0324A4B2E20A7F492846FFF7D9 -+:107560007BFA7E49C4F302222846FFF775FA7C496C -+:10757000C4F3C4022846FFF76FFA7A49C4F3410204 -+:107580002846FFF769FA2846774904F00102FFF719 -+:1075900063FABBF1040F40F2AB833379F47873499B -+:1075A00004EB0324A4B2E20A2846FFF755FA704917 -+:1075B000C4F302222846FFF74FFA6E49C4F3C4020F -+:1075C0002846FFF749FA6C49C4F341022846FFF701 -+:1075D00043FA6A49284604F00102FFF783BB08EB2F -+:1075E000090621AF664972783846FFF735FA4FF041 -+:1075F000000A6449B2783846FFF72EFACDF800A0A9 -+:107600003279F378604903EB022301930222534657 -+:107610003846FFF721FACDF800A0B27973795A49BC -+:1076200003EB02230193022201233846FFF714FAE9 -+:10763000CDF800A0327AF379384603EB0223022218 -+:10764000019351491346FFF707FABBF11E0F40F2B1 -+:107650004F834E49727A3846FFF7FEF94C49B27AA9 -+:107660003846FFF7F9F94B49F27A3846FFF7F4F953 -+:107670004949327B3846FFF7EFF9CDF800A0B27BDD -+:10768000737B414903EB022301930522534638469D -+:10769000FFF7E2F9CDF800A0327CF37B3A4903EB27 -+:1076A00002230193052201233846FFF7D5F9CDF8CF -+:1076B00000A0B27C737C344903EB022301930522C2 -+:1076C00002233846FFF7C8F9CDF800A0CDF804A092 -+:1076D000327DF37C314903EB0223029305226C23B4 -+:1076E00001253846FFF7B8F90095CDF804A0B27D22 -+:1076F000737D2A4903EB0223029305226C2338464B -+:107700000224FFF7A9F90094CDF804A0327EF37D9E -+:10771000224903EB0223029305226C233846FFF72C -+:107720009BF9CDF800A0CDF804A0B27E737E384658 -+:1077300003EB02230293194905226823FFF78CF912 -+:107740000095DFE0D7B5020086B5020050B5020013 -+:1077500077B502002BB70200E7B7020093B2020030 -+:10776000A0B2020071B80200A4B1020046B6020045 -+:107770008EB80200C1B802008BB40200D8B7020074 -+:10778000E3B102005DB5020080B702002AB6020034 -+:107790002FB30200E4B5020048B202000FB40200A9 -+:1077A00008EB090621AFAF4972783846FFF754F964 -+:1077B0004FF0010AAC49B2783846FFF74DF9CDF8E1 -+:1077C00000A03279F378A94903EB02230193022246 -+:1077D00000233846FFF740F9CDF800A0B27973795D -+:1077E000A24903EB02230193022253463846FFF7D6 -+:1077F00033F9CDF800A0327AF379384603EB02234F -+:107800000222019399491346FFF726F9BBF11E0F97 -+:1078100040F26E829649727A3846FFF71DF9954913 -+:10782000B27A3846FFF718F99349F27A3846FFF7EB -+:1078300013F99249327B3846FFF70EF9CDF800A0D4 -+:10784000B27B737B894903EB02230193052200235A -+:107850003846FFF701F9CDF800A0327CF37B83496D -+:1078600003EB02230193052253463846FFF7F4F851 -+:10787000CDF800A0B27C737C7C4903EB022301931A -+:107880000522022300253846FFF7E6F80095CDF8DB -+:1078900004A0327DF37C7A4903EB02230293052294 -+:1078A0006C233846FFF7D8F8CDF800A0CDF804A037 -+:1078B000B27D737D724903EB0223029305226C2390 -+:1078C00038460224FFF7C8F80094CDF804A0327EB1 -+:1078D000F37D6B4903EB0223029305226C233846A8 -+:1078E000FFF7BAF80095CDF804A0B27E737E384653 -+:1078F00003EB02230293624905226823FFF7ACF8E9 -+:10790000CDF800A0CDF804A0327FF37E384603EB1B -+:1079100002230293052268235949FFF79DF800943A -+:10792000CDF804A0B27F737F384603EB02230293A5 -+:10793000534905226823FFF78FF8D9E108EB0904C2 -+:10794000A378627821AD02EB03224E492846FFF767 -+:1079500083F86279A379120402EB0362E378284684 -+:10796000D2182379484902EB0322FFF775F8BBF1DF -+:10797000120F40F2BD81627AA37A120402EB036215 -+:10798000E3794249D218237A284602EB0322FFF713 -+:1079900063F8627BA37B120402EB0362E37A28465E -+:1079A000D218237B3A4902EB0322FFF755F8627C99 -+:1079B000A37C120402EB0362E37BD218237CABE0CE -+:1079C000A278637821A803EB0223009331492B4668 -+:1079D0000222FFF741F801350234B5EB5B0FEFDD12 -+:1079E00086E1A278637821A803EB0223009329495A -+:1079F0002B460522FFF730F801350234B5EB5B0F5B -+:107A0000EFDD75E10095A278637821A803EB0223EE -+:107A10000193214905226C23FFF71EF8013502343A -+:107A20004FEA9B06B542EDDD002411E008EB5B0355 -+:107A30004B44009403EB44039A785B7821A803EB52 -+:107A400002230193144905226823FFF705F8013446 -+:107A5000B442EBDD4CE108EB09039C785A780F49FE -+:107A600021A824E1FCB202006AB5020080B702003E -+:107A700038B602003CB30200F3B5020057B2020070 -+:107A80000FB402004BB802009EB70200C9B5020055 -+:107A900066B2020030B2020056B60200ABB4020079 -+:107AA00008EB09039C785A78934921A8FFE008EB7A -+:107AB00009039C785A78914921A8F8E008EB09035A -+:107AC0009C785A788E4921A8F1E008EB0904E27805 -+:107AD0002379120402EB0362637821ADD218A378F4 -+:107AE000884902EB03222846FEF7B6FFE279237AA3 -+:107AF000120402EB036263792846D218A379824903 -+:107B000002EB0322FEF7A8FFE27A237B120402EBCA -+:107B10000362637AD218A37A7C492846FFF731BA08 -+:107B200008EB0904A378627821AD2846784902EB76 -+:107B30000322FEF791FFBBF1040F40F2D9802379B5 -+:107B4000E27874492846FFF71CBA08EB0904E2788A -+:107B50002379120402EB0362637821ADD218A37873 -+:107B600028466D4902EB0322FEF776FFBBF1060FB4 -+:107B700040F2BE80E279237A120402EB0362637959 -+:107B80006649D218A3792846FFF7FBB9644E09EB82 -+:107B900008040225AB45C0F2AB80E27823791204D9 -+:107BA00002EB036263783146D218A37821A802EB76 -+:107BB00003220435FEF750FF043418361A2DE9D19C -+:107BC00096E0584E09EB08040225AB45C0F29080C0 -+:107BD000E2782379120402EB036263783146D2180B -+:107BE000A37821A802EB03220435FEF735FF043405 -+:107BF00013360E2DE9D17BE04B4E09EB080402252C -+:107C0000AB4575DBE2782379120402EB03626378FB -+:107C10003146D218A37821A802EB03220435FEF7DF -+:107C20001BFF043414360E2DEAD161E03F4E09EB00 -+:107C300008040225AB455BDBE2782379120402EBF2 -+:107C4000036263783146D218A37821A802EB03229D -+:107C50000435FEF701FF043414360E2DEAD147E057 -+:107C6000334E09EB08040225AB4541DBE27823796A -+:107C7000120402EB036263783146D218A37821A87C -+:107C800002EB03220435FEF7E7FE043414360E2D12 -+:107C9000EAD12DE008EB09039C785A78254921A800 -+:107CA00005E008EB09039C785A78234921A802EBE8 -+:107CB0000422FFF717B808EB0901CB780A791B04F7 -+:107CC00003EB02634A788C789B181C4921A8012297 -+:107CD00003EB0423FEF7C0FE0AE0194908EB090391 -+:107CE00021A8FFF77FB901220B9201E0FF2E29D0D6 -+:107CF0000BEB0801FEF753BF19B802008BB102006D -+:107D00001DB60200C9B5020066B2020072B40200DC -+:107D10009BB80200AEB80200C0B60200D6B60200A0 -+:107D2000B6B4020064B30200B1B202009DB3020017 -+:107D300068B6020014B30200C0B102001AB7020014 -+:107D4000ACB502000D9B01330D930D9A079B9A422F -+:107D50007EF41DAF0E9AB2F1FF3F03D021A8174960 -+:107D6000FEF77AFE9DF8443023B121A8144911AAE8 -+:107D7000FEF772FE00201349DAF32AF638B90B9B9E -+:107D80002BB91A4621A81049FF33FEF765FE229A47 -+:107D9000002302F8013B2E9B0A9900930998069B49 -+:107DA0002292FEF7ABFE0A9904464FF480520998DE -+:107DB000DEF39EF7204625B0BDE8F08F82B80200C2 -+:107DC0002FB802000E5D860081B402002DE9F04F4D -+:107DD0009A468FB000230D936D4B06461C7889465A -+:107DE0000592002C40F0C180142208A82146DAF345 -+:107DF00027F17369232B05DC01224FF0040B069455 -+:107E0000079214E01C222346304621460094E3F3F7 -+:107E10003DF00028ACBF03230123ACBF00220122A8 -+:107E200007930692ACBF4FF00C0B4FF0020B30469D -+:107E3000E2F3E0F70128054602D0022806D013E05D -+:107E400030464946DAF330F040000CE03046FAF7AD -+:107E500047FF044640B1D9F3D5F710F4807F03D033 -+:107E60002046D9F3C5F70D900D99002900F08480C4 -+:107E70004846DEF32DF7044610B96FF01A0083E090 -+:107E8000012D0746DDF8348003D0022D0ED00025E9 -+:107E90001CE0002102900091CDF80480039130464F -+:107EA000059A4B46D9F3FAF705460DE00EAB4FEABB -+:107EB000580243F8042D304601212246D9F356F7E3 -+:107EC0000D9B05465B000D93002D45D123884FF691 -+:107ED000FD72013B9BB2934205D94846214642467A -+:107EE000DEF306F74AE0069B1BB104EB4B03089355 -+:107EF00015E0638804EB0B01227901EB132303EBFC -+:107F00000223A3F580530993E3880891CB18A3F5C6 -+:107F100080530A932389C918A1F580510B91DDB9CB -+:107F2000189A4846009208A9079A5346FEF708FE99 -+:107F300090B91849DAF320F538B1189B3046DAF8D1 -+:107F400000101A6800F024FB06E0189B3046DAF8AF -+:107F500000101A6800F004FB27B148463946424633 -+:107F6000DEF3C6F60A4B01221A700023189A18464F -+:107F7000CAF80030136007E00D468846064B00271C -+:107F8000089301230793CAE70FB0BDE8F08FC046FE -+:107F9000402700004EE7010019B2020013B5049C0F -+:107FA0009E4605994CB141B1002323600B600091BE -+:107FB00023467146FFF70AFF00E000201CBDC046C3 -+:107FC000094A13888B4201D1002206E093888B4234 -+:107FD00002D04FF0FF3005E00122034B03EB820398 -+:107FE00093F902007047C0461CB902002DE9F04128 -+:107FF000074614461E46002B7ED0E7F783FA054657 -+:1080000002E0B34205D00C35002D75D02B88002B33 -+:10801000F7D12B88002B6FD0D4F80036AA78C3F3A1 -+:108020008403934268D0D4F81836642023F0C073D8 -+:10803000C4F81836D4F81C3643F6A12623F0C073D2 -+:10804000C4F81C36DEF388F303E00A20DEF384F381 -+:108050000A3ED4F8E03113F4003F01D0092EF4D1E8 -+:108060000023C4F86036EA782B79D4F864161B062E -+:10807000120502F4700203F07063134321F07F6174 -+:108080000B43C4F864360223C4F86036D4F864366F -+:108090006A7923F0FE5323F4781343EA025343F43E -+:1080A0008023C4F864360323C4F86036D4F8642609 -+:1080B000AB6802F07F4223F07F431343C4F8643679 -+:1080C0003B6A012B05DDD4F8003643F48063C4F825 -+:1080D0000036AA782988D4F8000692004FF68373F8 -+:1080E0007F3102F07C0200EA0303C9111A4301390F -+:1080F00042EA0142C4F80026BDE8F081036A70B587 -+:10810000092B054601DC00242CE0E2F3B7F6002140 -+:1081100006462846E3F384F0D0F80836044613F404 -+:10812000807001D1044619E04FF00043C4F86C366A -+:108130004FF47A70DEF310F3D4F86C360022DB04CF -+:10814000DB0C5B03C4F86C2603F54243064A03F5D7 -+:10815000A873B3FBF2F3642203FB02F42846314612 -+:10816000E3F35EF0204670BDA086010070B50446C2 -+:10817000E2F384F6002105462046E3F351F0236A3A -+:10818000012B04D1D0F8003623F4007304E005DDA0 -+:10819000D0F8003643F40073C0F800362046294674 -+:1081A000E3F33EF070BDC0462DE9F04104461646AB -+:1081B0000D46E2F363F6002180462046E3F330F0FB -+:1081C0002946024633462046FFF710FF2046414627 -+:1081D000E3F326F0BDE8F0812DE9F043002485B0FB -+:1081E000074603940294E2F349F621468146384655 -+:1081F000E3F316F07B6A4E4A0546C3F3042605E016 -+:10820000137AC5F82036D368C5F82836494B083AA2 -+:108210009A42F5D14FF0000820E008216846464A0E -+:108220004346D9F351F700206946DAF3D1F398B108 -+:1082300000210A46DAF38CF23B6A0C2B08DDB0F51C -+:10824000803F05D200F0FF02C0F3072342EA03405B -+:10825000C5F82086C5F8280608F10108B045DCD12C -+:10826000364C28E0E36A13B13846984710B3002132 -+:108270001EE001238B40226A134218D0C5F8201655 -+:1082800094F924302BB1012B05D0B3F1FF3F07D077 -+:108290000DE0A36A09E0D5F82436A26A134304E08E -+:1082A000D5F82436A26A23EA0203C5F82436013140 -+:1082B000B142DED1103C224B9C42D3D1002614E0C7 -+:1082C000082168461F4A3346D9F3FEF60020694666 -+:1082D0006C46DAF37DF338B10021C5F820660A4612 -+:1082E000DAF336F2C5F8240601364645E8D103A98B -+:1082F00002AA3846DDF31CF5029B039941EA03020A -+:10830000D5F81C3642EA0303C5F81C360AB1C5F895 -+:108310001C2609B1C5F818164FF4FA600292DEF374 -+:108320001BF238464946E2F37BF705B0BDE8F0831F -+:1083300014B90200F4B8020051368600D4B8020025 -+:10834000A4B80200563686002DE9F04385B00546F4 -+:10835000E2F394F5002181462846E2F361F72B6AA7 -+:108360008046042B6B6A01DDDF0E01E0C3F3436737 -+:10837000002614E0102168460D4A3346D9F3A4F6CE -+:10838000002069466C46DAF323F338B100210A462F -+:10839000DAF3DEF1C8F85066C8F854060136BE427A -+:1083A000E8D128464946E2F33BF705B0BDE8F08343 -+:1083B0005B3686002DE9F043036A85B0042B436ADF -+:1083C0000546CCBFC3F38458C3F34358E2F356F5D4 -+:1083D000002181462846E2F323F70026074615E0F0 -+:1083E000102168460E4A3346D9F36EF600206946DE -+:1083F0006C46DAF3EDF238B100210A46DAF3A8F15F -+:10840000C7F85866C7F85C06731CDEB24645E7D16C -+:1084100028464946E2F304F705B0BDE8F083C046BC -+:1084200063368600F7B5053A06461F46062A2BD85E -+:10843000DFE802F00A0C12040E2A060005250CE003 -+:108440001125032402230AE0012502E0052500E0AE -+:1084500011250F24042302E000251F240323009389 -+:1084600000214FF4CB624FF0FF333046E2F30EF5BC -+:1084700004EA0703AB4030460093002140F25C62FF -+:1084800014FA05F3E2F302F5FEBDC0462DE9F04112 -+:1084900005460E4600201749DAF36EF2164984B2FB -+:1084A0000020DAF369F240F2DC51002C18BF2146BB -+:1084B000C7B22846FFF784FDC0B210F0800F0CD180 -+:1084C000C4B23146284607222346FFF7ABFF2846B1 -+:1084D000314608222346FFF7A5FF2FB12846314633 -+:1084E0003A460123E7F748F828463146FFF762FF8E -+:1084F000BDE8F0816F36860008F9010070B50546C9 -+:108500000C46FFF721FF002221462846DDF364F5E3 -+:108510002846E2F3B3F40A4904460020DAF32CF2C9 -+:108520004FF4002210F001034FF00001284618BF5D -+:108530001346DDF385F428462146E2F371F670BD5B -+:108540007836860070B5002105461020DDF35EF711 -+:10855000002110220446D9F373F52046656070BDF2 -+:1085600070B50C461546E2F3C5F51021DEF3B0F305 -+:1085700010B96FF01A0008E0044A10234360136832 -+:10858000C460036085601060002070BD6C2700002F -+:1085900070B515460C46E2F3ADF51021DEF398F305 -+:1085A000024610B96FF01A0010E01023436008492A -+:1085B000002303600B68C46085601BB9086018461F -+:1085C00004E0034618680028FBD11A6070BDC0465D -+:1085D0006C27000070B50C461546E2F38BF51021B0 -+:1085E000DEF376F310B96FF01A0008E0044A1023A6 -+:1085F00043601368C460036085601060002070BD34 -+:108600006C270000064B10B51B683BB9054B196879 -+:1086100021B1054B1A680AB1FFF7DCFF002010BD3D -+:108620006C270000FC1E0200001F020001207047A2 -+:108630000020704710B50020DAF39EF110BDC0464F -+:1086400010B50B490446FFF7F5FF80B278B9E06F2B -+:108650000749DAF391F180B248B9E06F0549DAF3DE -+:108660008BF14FF6FF7380B2002808BF184610BD8B -+:10867000483786004E37860041F2E44370B5C36246 -+:1086800004460D4629B108460949DAF375F1A0629E -+:1086900040B900200749DAF36FF1A06210B94FF634 -+:1086A000FF73A36228460449DAF366F1206370BDC4 -+:1086B000543786005B37860086378600836973B53A -+:1086C00013F0005F04466FD08268B2F5026F01D1EB -+:1086D00001220AE040F604039A4201D0002204E09D -+:1086E000C3680C2B94BF002201224FF00003D5B2C7 -+:1086F000ADF8063055B920464FF400612A46D4F84B -+:10870000C860E2F37BF500284ED005E0D4F8843051 -+:1087100013F5405048D000266369222B03DC002368 -+:10872000C0F8683100E00023C0F86431C0F860315F -+:108730006369222B03DC1F4BC0F8443105E00123A1 -+:10874000C0F84831FE33C0F84C316369222B07DC96 -+:108750000023C0F88031C0F87C31C0F8783104E0E3 -+:108760000023C0F87431C0F870311DB9204631467D -+:10877000E2F356F520460DF10601FFF759FF0546D5 -+:10878000A8B9BDF8063093B163690B49222B204686 -+:10879000D8BF4FF48021CCBF40224FF480222B461B -+:1087A000E2F38EF3284603E04FF0FF3000E00020B4 -+:1087B0007CBDC0460000FBBF400055552DE9F04789 -+:1087C000002104461F46DDF82080DDF82490E2F306 -+:1087D00027F505462046E2F363F360610A28C4BF2B -+:1087E000EB6A63646B68A3616369222BC4BFD5F82D -+:1087F000AC30E361A36913F0805F05D0D5F804368F -+:10880000636203F0FF0323624FF4E063A3604FF061 -+:10881000FF33E360254612330026236116E031461C -+:108820002046E2F3FDF42046E2F31CF32046E2F397 -+:1088300037F31FB1D5F810319F4203D0D5F88830F7 -+:10884000994501D1C8F8006001360435D4F8CC3020 -+:108850009E42E4D32046D8F80010E2F3E1F4012070 -+:10886000BDE8F08730B585B00190002504A840F838 -+:10887000045D01A90422D9F37FF3019CD4B12246FF -+:108880002946D2F8883013B10023C2F8883001316C -+:1088900004321029F5D10398D9F30CF30398E6F7C5 -+:1088A000B7FF054B9C4205D0606D21464FF45672D0 -+:1088B000DEF31EF205B030BD8C2802002DE9FF4723 -+:1088C0000C9E1446DDF834808A464FF4567200211F -+:1088D00005461F46DDF83890012E08BF0026D9F363 -+:1088E000AFF311232B61C5F88470C5F858806C650F -+:1088F0006E60002E40F0B98028463146524643460D -+:10890000FFF794FE002800F0B0804FF0C0542268BA -+:108910002846130F2B6013041B0CAB63C2F30343F5 -+:10892000C2F303522A640E3A012A8CBF00220122AC -+:10893000EB6385F8482021465246FDF739FFD5F80C -+:10894000CC30002B00F0918004AB43F8046D009311 -+:1089500028462146324633460197FFF72FFF00286D -+:1089600000F083802846FFF74DFE0F9A6B6D284676 -+:10897000019231463A46CDF80090FFF70FFB0028F0 -+:1089800073D1B9F1000F01D14E4601E0D9F8006072 -+:1089900028463146FFF770FE364B1C78002C30D14C -+:1089A0006B69132B0BDD4FF4006128462246E2F37E -+:1089B00025F48465C46503992846E2F331F428461A -+:1089C000696DFFF7D3FB2846696DFFF797FD3046C9 -+:1089D0002949D9F3D1F7024620B92846696DFFF736 -+:1089E0008DFB02462846696DFFF7DEFB2846696D60 -+:1089F000FFF7F2FB2846696DFFF748FD1D4B01228A -+:108A00001A706B690F2B0FDD1C493046D9F3B4F790 -+:108A10001B4B0021002808BF1846009088222846DA -+:108A20004FF0FF33E2F332F230461649D9F3D0F774 -+:108A300038B114493046D9F39FF701462846E7F785 -+:108A4000A5F86B69142B11DD00242146082223466A -+:108A500028460094E2F31AF2214640F0040308226B -+:108A600028460093E2F312F200E00025284604B005 -+:108A7000BDE8F087E42B0200E2388600EB38860080 -+:108A80005A000A00F13886001FB5104C864621783E -+:108A9000C9B90F4A0F4B002808BF024608BF03465A -+:108AA00000910191029303920B4844F210717246B7 -+:108AB0004FF0C053FFF702FF00B905E0074A20233B -+:108AC000136001232370044804B010BD88280200FD -+:108AD0000C290200082902008C28020074270000DB -+:108AE0002DE9FF4781460D4608464FF456719246E0 -+:108AF0001E460D9FDDF83880DEF3EAF0044610B321 -+:108B00000C9B494601932A46534600960297CDF89E -+:108B10000C80FFF7D3FE064638B9284621464FF4AD -+:108B20005672DEF3E5F030460EE00FB93B4600E04A -+:108B30003B68E367B8F1000F01D1434601E0D8F884 -+:108B40000030C4F88030204604B0BDE8F087C0464D -+:108B500070B5044628B30368124918682246FBF32F -+:108B6000F3F12546002610E0296A29B123689868A8 -+:108B7000E6F386F500232B62E96921B123682A8B8D -+:108B80005868DEF3B5F00136183561688E42EBDBCC -+:108B9000182201FB02F22368214658681032DEF3E6 -+:108BA000A7F070BD08FA01002DE9F043036885B015 -+:108BB00081467021D868DEF38BF0044608B906467A -+:108BC00048E0002170220646D9F33AF2042363609C -+:108BD00027464FF0B40325464FF00008C4F8009034 -+:108BE000A38112E0182208FB02F210322C61D9F89E -+:108BF00008001A49A2180023E6F35EF5286218352A -+:108C000008B905461CE008F1010863689845E9DBEE -+:108C1000134BD9F8000000930023019302930393B0 -+:108C20001049114A2346FBF357F113E0396A29B181 -+:108C300023689868E6F324F500233B620135183772 -+:108C400063689D42F2DB2368214658687022DEF398 -+:108C50004FF00026304605B0BDE8F0839DFE0000D1 -+:108C600021FD0000E4F9010009FA010010B50446F5 -+:108C700058B10368054918682246FBF365F123687B -+:108C8000214658685422DEF333F010BD2B7A86005B -+:108C900030B55421044685B04068DEF319F008B9B8 -+:108CA000054611E0002154220546D9F3C9F1084BCD -+:108CB0002C600093002301930293039320680549DD -+:108CC000054A2B46FBF308F1284605B030BDC046E7 -+:108CD000390301003CFA01002B7A8600002070471E -+:108CE00010B5044698B107F0ADDE09496068224628 -+:108CF000FBF32AF1E16E21B163683C22D868DDF311 -+:108D0000F7F763682146D8687022DDF3F1F710BDEC -+:108D1000D58D86007FB5054670214068DDF3D8F714 -+:108D2000064608B9044631E0002170220446D9F312 -+:108D300087F12B683560736068683C21DDF3C8F704 -+:108D4000E066F8B100213C22D9F37AF1114B1249C7 -+:108D50000093002301930293104B114A0393706810 -+:108D60003346FBF3B9F068B94FF001037382B38265 -+:108D700030462946FFF7B2FF002803DB304607F0F4 -+:108D80005DDF03E03046FFF7ABFF0024204604B070 -+:108D900070BDC046390B83006CFA0100290C8300BA -+:108DA000D58D860070B5D0F8305704466DB10749AF -+:108DB00022460068FBF3C8F0606829464FF40A6257 -+:108DC000DDF396F70023C4F8303770BD529E86005D -+:108DD0002DE9FF4106464FF40A614068DDF378F75C -+:108DE000074618B9C6F830070138E1E000214FF412 -+:108DF0000A62D9F325F107F120033B6033680822AA -+:108E000000247A613C61DC211A6630466A4A6B4B69 -+:108E10000094019601F092FFA042B86105DA304655 -+:108E2000FFF7C0FF6FF00100C2E0A6462546644B85 -+:108E300000221EF0010FEA501FD0624B19780D2955 -+:108E400002DD4FF4004C03E04A1C012303FA02FC4C -+:108E50005C4BD8780D2802DD4FF4004403E0421C3F -+:108E6000012313FA02F4012313FA00F28B401A4390 -+:108E700042EA0C02524B2243EA501EF0020F24D069 -+:108E80004F4B55F803804F4B58780D2802DD4FF4B7 -+:108E9000004C03E0421C012303FA02FC494B997881 -+:108EA0000D2902DD4FF4004403E04A1C012313FAAC -+:108EB00002F4012313FA01F283401A4342EA0C023E -+:108EC00022433F4B42EA0802EA501EF0040F24D02E -+:108ED0003B4B55F803803B4B18790D2802DD4FF4CE -+:108EE000004C03E0421C012303FA02FC354B597984 -+:108EF0000D2902DD4FF4004403E04A1C012313FA5C -+:108F000002F4012313FA01F283401A4342EA0C02ED -+:108F100022432B4B42EA0802EA501EF0080F24D0ED -+:108F2000274B55F80380274B98790D2802DD4FF425 -+:108F3000004C03E0421C012303FA02FC214BD979C7 -+:108F40000D2902DD4FF4004403E04A1C012313FA0B -+:108F500002F4012313FA01F283401A4342EA0C029D -+:108F60002243174B42EA0802EA500EF1010E043583 -+:108F7000BEF1100F7FF45BAF134B0025134C03932E -+:108F80002946134A33463068009501950295FAF355 -+:108F9000A3F7231D93E807006B4683E807003046DC -+:108FA00023680321324601F061DEC6F83077284697 -+:108FB00004B0BDE8F081C04601578300A15683008C -+:108FC0008427000090E085009D508300C8FA0100CE -+:108FD000529E86002DE9F041066805461B4930681F -+:108FE0002A46FAF3B1F72C460027D4F8081121B12C -+:108FF0007068B4F81021DDF37BF6D4F80C1121B1C0 -+:109000007068B4F81221DDF373F601374034042F91 -+:10901000EBD1D5F80C1221B17068B5F81022DDF350 -+:1090200067F6D5F81C1211B1B068E6F329F3D5F84C -+:10903000201219B170683A46DDF35AF67068294675 -+:109040004FF42372DDF354F6BDE8F081D8FA010045 -+:1090500010B50446E7F7F2FDA16961B1237D23B1A4 -+:10906000E068E6F3FBF200232375E068A169E6F30C -+:1090700007F30023A36123692146D8682C22DDF37E -+:1090800037F6002010BDC0462DE9F041074688465E -+:10909000C0682C2114461E46DDF31AF608B90546B1 -+:1090A00019E0054600212C22D8F3CAF7EC602046CF -+:1090B000EE61C5F808802F6108492A460023E6F3CF -+:1090C000FBF20446A86130B92B692946D8682C22E6 -+:1090D000DDF30EF625462846BDE8F0813D668400A6 -+:1090E00010B5034900220068FAF32EF7002010BDE6 -+:1090F00049C586001FB5094A0B460092002201921D -+:10910000029203920649074AFAF3E6F6002814BFD2 -+:109110004FF0FF30002005B000BDC0460968840054 -+:1091200048FB010049C586001FB5084A0346009266 -+:1091300000220192029203920549064A0068FAF35E -+:10914000CBF6003818BF012005B000BD7D18010026 -+:1091500020FC0100EFFB010010B5B0F8BC400C8012 -+:10916000B0F8C0101180B0F8C6201A8090F8C8205E -+:10917000029B01201A8010BD90F8D4007047C046B1 -+:10918000D0F8CC007047C04610B5014618B18068D1 -+:109190009822DDF3ADF510BD70B598210446006846 -+:1091A000DDF396F508B9054633E00021982205461F -+:1091B000D8F346F72368AB606368EB60A3682B6164 -+:1091C000E3686B6023696B61238CAB84638CEB84F5 -+:1091D000636AAB62A36AEB62E36A2B63236B6B6324 -+:1091E000636B6B64A36BAB64E36BEB64236C2B6509 -+:1091F000636C6B656369AB65A369EB650F232B66D5 -+:109200002D336B663C33AB660323EB66002385F896 -+:109210009430284670BDC04670B501210446E9F778 -+:1092200029FB2046E9F7B2FBC0F30F33A4F8C630A0 -+:10923000B4F8C620030F84F8C83042F2640300F08B -+:109240000F009A4284F8C90005D002339A4202D036 -+:109250004FF0FF3500E0002520460021EAF77AF8BC -+:10926000284670BD70B5044600282DD0D0F8E430F3 -+:109270005D1EC0F8E4503DBB41F2C826815921B1C2 -+:10928000C3691869F3F78EFFA55141F2DD13E55468 -+:109290002046E9F73FFFE1690A68A24203D1D4F80A -+:1092A000B4300B6005E0D2F8B430A34208BFC2F876 -+:1092B000B450E36E0BB120469847E36921469868A5 -+:1092C00041F26832DDF314F570BDC04670B5D0F8D8 -+:1092D000B8400E46E9B10846D8F342F70546C0B19A -+:1092E0000FE0204631462A46D8F32AF628B9635DB6 -+:1092F0003D2B02D1631C58190CE014F8013B002BE4 -+:10930000FBD114B12378002BEBD13046DEF3AEF461 -+:1093100000E0002070BDC0462DE9F34141F2383530 -+:10932000435B064688462BB30846D8F319F7044634 -+:109330001448D8F315F724181034F369A7B29868C5 -+:109340003946DDF3C5F4044608B9054617E0735BFA -+:109350000D4A009339464346D8F3B6F621463046C7 -+:10936000EBF79EF9F3690546214698683A46DDF326 -+:10937000BFF425B930464146EBF792F90546284639 -+:10938000BDE8FC8196FD01009CFD01002DE9F04F38 -+:1093900041F2383B85B0039330F80B3006468946DE -+:1093A0009246D0F8B880002B38D00846D8F3D8F6CB -+:1093B00004462448D8F3D4F62418F3691034A7B22D -+:1093C00098683946DDF384F4054608B9044634E06C -+:1093D00036F80B30394600931B4A4B46D8F374F6E7 -+:1093E00030462946EBF76AF9834668B1404629467C -+:1093F000D9F75CFA40B1504506DD40462946524651 -+:10940000D9F3C8F2044600E0039CF3692946986842 -+:109410003A46DDF36DF4BBF1000F0ED140464946EC -+:10942000D9F744FA40B1504506DD40464946524618 -+:10943000D9F3B0F2044600E0039C204605B0BDE835 -+:10944000F08FC04696FD01009CFD010070B590F8BC -+:10945000C43001229A401A49013A0446D5B2EBF7CA -+:1094600061F941F21202C0B2A0540138C0B2FD2825 -+:1094700001D97323A354A25C41F21303E2542046A2 -+:109480001049EBF74FF941F21402C0B2A05408B1F1 -+:109490000F2801D10523A35441F21203E25C0233E9 -+:1094A000E35CD21A41F21503E25400220133E25484 -+:1094B0000233E25445EA0512013BE25470BDC04656 -+:1094C00075B902004FB902002DE9F84F8846002116 -+:1094D000846807469246C0680A469B46E1F3BAF4A0 -+:1094E00010F0080F814615D03E689EB130465146B7 -+:1094F00000F084FA002800F07481F369D6F8CC10EB -+:10950000186927F0CDD8D6F8E43030460133C6F8D4 -+:10951000E4306DE1204641F26831DDF3D9F30546D0 -+:10952000002800F05C81002141F268320646D8F341 -+:1095300087F5012105F59053303341F2D41285F8B7 -+:10954000E110AB50FA6C41F26B039A42C5F8B0805F -+:10955000EF6105D17B6C932B02D1A5F8221603E0B5 -+:109560004FF01802A5F822266423002185F8E03088 -+:1095700041F218230422E9540133EA540133E95437 -+:109580000133BAF1020FC5F8B8B0EA5406D119F0A8 -+:10959000010F1CBF4FF40053C5F8CC30EB69D5F870 -+:1095A000CC10186927F07CD8D5F8B030B3F8E03388 -+:1095B0009CB2EB69D868E6F787F941F23833E85294 -+:1095C000C4F30323C5F8BC3004F00F03C5F8C03062 -+:1095D000EB699A6A874BD318012B06D94AF6E60342 -+:1095E0009A4202D0043B9A4207D1EB69DB6A023B04 -+:1095F000012B02D80923C5F8C030D5F8BC30092B9F -+:1096000007D10423C5F8BC30D5F8C0301033C5F8F5 -+:10961000C030012385F8C430230BC5F8D030D5F80D -+:10962000BC30022B0CD9042B0AD0052B08D0062BFA -+:1096300006D0082B04D00A2B02D0072B40F0D18093 -+:109640003C23C5F8F43F0023C5F8F83F4FF400630E -+:10965000A5F8DE3042F6013241F62433BAF1020FAA -+:1096600008BF1346A5F8DA3095F8DA30284685F8B1 -+:1096700000376149EBF722F890B15F492846EC6961 -+:10968000EBF750F85C4920672846EC69EBF74AF89D -+:10969000EA69BAF1020F60670CBF136F536FD366AC -+:1096A0000A2241F2E613EA5403210133E95401236B -+:1096B000002485F8E83005F59053013A1C7041F21A -+:1096C0001B03EA54EB6985F8E94585F8EE4585F812 -+:1096D000F34585F8F84585F8FD45284683F893104D -+:1096E000FFF7B4FE41F21903EC544FF6CE7241F28B -+:1096F000C423EA5285F8F440621901347F23652CB3 -+:1097000082F82C3682F8913682F8B232F4D14FF0DA -+:10971000FF33A5F8FA36002385F8AC3028465146C9 -+:1097200001F03AF900285CD02846E9F797F8284676 -+:10973000FFF772FD0446002853D13049062228461F -+:10974000EAF7E4FF41F2E623E8542D4901222846D6 -+:10975000EAF7DCFF41F2F423E8542A49224628467E -+:10976000EAF7D4FF41F23A33E85427492846072262 -+:10977000EAF7CCFF41F23B33E8542246284623491E -+:10978000EAF7BEFF631903F5985301343833182CF8 -+:109790001871F2D10024224628461D49EAF7B0FF8D -+:1097A000631903F59A53013410330E2C1871F2D15A -+:1097B000D5F8E430EA690133C5F8E4301368D068BD -+:1097C000C5F8B4303D60FEF779FF05F1B803C5F880 -+:1097D000B830284605F1BC011C22D8F3CDF3284649 -+:1097E00006E0B868314641F26832DDF381F20020CC -+:1097F000BDE8F88F1D57FFFF80B9020024B90200B1 -+:1098000043B9020036B9020060B902006EB9020025 -+:109810002FB9020010B502490268FAF395F310BDA2 -+:10982000040402001FB5094B09490093002301936A -+:1098300002930393074A0368FAF34EF3002814BF18 -+:109840004FF0FF30002005B000BDC0463147010099 -+:1098500044030200040402002DE9F0410025804683 -+:109860000F4616462C4607E004EB0800E1190522D6 -+:10987000D8F382F301350534B542F5D1BDE8F08166 -+:10988000022970B505460C460AD0032911D00129DA -+:1098900016D106220B49E8F793FFEA69002305E099 -+:1098A00006220949E8F78CFFEA69012382F8813032 -+:1098B00006E006490622E8F783FFEB6983F881405A -+:1098C00070BDC046200B02002C0B0200380B0200BA -+:1098D00070B5D0F8A840002394F8C113C4F87435CB -+:1098E0000F4A104B022914BF15461D46C3694FF499 -+:1098F00020719868DDF3ECF1C4F8740578B180222A -+:109900002946FFF7A9FF94F83A35022B06D1D4F87F -+:1099100074050549A0301522FFF79EFF012070BD98 -+:1099200084C90200A8C4020048CC02002DE9F04717 -+:10993000D0F8A8308146D3F87C55D3F878A54FF0FD -+:10994000000817E0142403FB04F42B191A695B6860 -+:109950002F5903FB02F3DE08D9F81C303146986812 -+:10996000DDF3B6F108F10108285140B1394632461D -+:10997000D8F302F35FFA88F35345E3D30120BDE83F -+:10998000F087C0462DE9F041194BD0F8A8501A686D -+:10999000C369002614210746C5F87C65C5F87825FB -+:1099A000986802FB01F1DDF393F10446C5F87C05EC -+:1099B000E0B1B0460FE0FB6906EB04001B6D08F157 -+:1099C000010813F4805F14BF0A490B49142271186F -+:1099D000D8F3D2F21436D5F878359845EBD338461B -+:1099E0000121FFF7A3FF003818BF0120BDE8F08177 -+:1099F000A01A0200C4C2020084D102002DE9F04185 -+:109A0000884686B07A490546D0F8A860EAF78AFE0B -+:109A1000784930722846EAF785FE77497072284601 -+:109A2000EAF780FE7549A5F8FC002846EAF77AFEB9 -+:109A30007349A5F8FE002846EAF774FE7149A5F8B7 -+:109A400000012846EAF73AFE38B128466D49EAF7A0 -+:109A500069FE10B1012386F8E83396F8E8330BB3BA -+:109A600068492846EAF75EFE6749A5F802012846DC -+:109A7000EAF758FE6549A5F804012846EAF752FEC0 -+:109A80006349A5F806012846EAF74CFE614986F8C5 -+:109A900024052846EAF746FE002241F21B0386F819 -+:109AA0002505EA545C492846EAF73CFE5B49C6F8BE -+:109AB000340414222846EAF729FE5949A6F83C0442 -+:109AC0005A222846EAF722FE564986F8540408220C -+:109AD0002846EAF71BFE544986F84C040322284620 -+:109AE000EAF714FE514986F84D0408222846EAF7A1 -+:109AF0000DFE4F4986F84E0403222846EAF706FE7B -+:109B00004C4986F84F0408222846EAF7FFFD4A49E7 -+:109B100086F8500403222846EAF7F8FD474986F8FC -+:109B2000510408222846EAF7F1FD032286F8520480 -+:109B300043492846EAF7EAFD424986F85304284695 -+:109B4000EAF7F0FD404986F8580402222846EAF771 -+:109B5000DDFD3E4986F8C1042846EAF7AFFD28B18D -+:109B600028463A49EAF7DEFDF07400E0F074284632 -+:109B70003749EAF7A3FD28B128463549EAF7D2FD6F -+:109B8000307501E00823337528463249EAF796FD1F -+:109B900028B128462F49EAF7C5FD707501E0022378 -+:109BA000737528462C49EAF789FD28B128462A49C9 -+:109BB000EAF7B8FDB07501E00423B37528462749DC -+:109BC000EAF77CFD28B128462449EAF7ABFDF07599 -+:109BD00001E00823F37528462149EAF76FFD0028C4 -+:109BE00040D028461E49EAF79DFD30763CE0C0464D -+:109BF00045C10200E3C002002ABE020030BE0200DE -+:109C000036BE0200C3C00200E2BD0200CDBC0200AD -+:109C1000D5BA0200EABA02009AC202006BBD020085 -+:109C2000A6C102001DC202007EBF0200EBC10200FD -+:109C3000ABB90200FCC10200BCB90200DAC10200EB -+:109C4000B3C202009ABC02000BBB02001ABC0200A5 -+:109C500007BC020065C0020015C202000DC202006E -+:109C60003DC1020002233376B7492846EAF75AFD80 -+:109C7000B649B0722846EAF755FDB549F072284654 -+:109C8000EAF750FDB17AF27AC3B230737173B273EE -+:109C9000F37331747274B374AE492846EAF742FD27 -+:109CA000B5F8FC2041F21A33EA5205F599531A80AF -+:109CB000B5F8FE2041F21C33EA520633EA52B5F8F9 -+:109CC0000021043BC7B2EA52063385F81A71EA5202 -+:109CD0002846A149EAF726FD002480B22A1900F09F -+:109CE0000F030134A7EB43030009042C82F81E3153 -+:109CF000F4D128469949EAF715FD2A1900F00F0317 -+:109D00000134A7EB430300090C2C82F81E31F4D177 -+:109D100093492846EAF706FD924904462846EAF7A1 -+:109D200001FD80B240EA0441716014202A1801F05C -+:109D30000F030130A7EB430309091C2882F81631F1 -+:109D4000F4D189492846EAF7EDFC88497083284612 -+:109D5000EAF7E8FC864930772846EAF7E3FC8549CC -+:109D600070772846EAF7DEFC8349B0772846EAF7A1 -+:109D7000D9FC8249F0772846EAF7D4FC804986F876 -+:109D800022002846EAF7CEFC7E4986F821002846C4 -+:109D9000EAF7C8FC7C4986F8E0042846EAF7C2FCEA -+:109DA0000127C6F8E40401AC784920463A46D8F3C6 -+:109DB0009BF1D5F8B8002146D8F30AF630B100215E -+:109DC0000A46D8F3C5F4F31983F8E70401370F2FD7 -+:109DD000E9D16F492846EAF7A5FC6E4986F8F604F2 -+:109DE0002846EAF79FFC6C4986F8F7042846EAF70C -+:109DF00099FC6A4986F8F8042846EAF793FC684912 -+:109E000086F8F9042846EAF78DFC664986F8FA04D4 -+:109E10002846EAF787FC644986F8FB042846EAF7F7 -+:109E200081FC624986F8FC042846EAF77BFC60491D -+:109E300086F8FD042846EAF775FC5E4986F8FE04BC -+:109E40002846EAF76FFC5C4986F8FF042846EAF7E3 -+:109E500069FC5A4986F800052846EAF763FC584928 -+:109E600086F801052846EAF75DFC564986F80205A2 -+:109E70002846EAF757FC544986F803052846EAF7CE -+:109E800051FC524986F804052846EAF74BFC504934 -+:109E900086F805052846EAF745FC4E4986F806058A -+:109EA0002846EAF73FFC4C4986F807052846EAF7BA -+:109EB00039FC4A4986F808052846EAF733FC484940 -+:109EC00086F809052846EAF72DFC464986F80A0572 -+:109ED0002846EAF727FC444986F80B052846EAF7A6 -+:109EE00021FC424986F80C052846EAF71BFC40494C -+:109EF00086F80D052846EAF715FC3E49A6F8140534 -+:109F00002846EAF70FFC4FF00042A6F816053A493A -+:109F10002846EAF7FBFB3949C6F810052846EAF758 -+:109F200001FC374986F824002846EAF7FBFB35494F -+:109F300086F823002846EAF7F5FB334986F8200027 -+:109F40002846EAF7EFFB61E0E7B902000CBF020028 -+:109F5000C5BD0200F2BD020077BD020044BC020094 -+:109F600096B902008DB902008DBE0200DDB9020073 -+:109F7000F6BF020001C00200CDB90200B2BC02006F -+:109F8000E3BC0200B9BE0200FFBE020033BC020007 -+:109F90003CBE02008CBF02009DBF0200B7BF0200A2 -+:109FA000FEC002000FC102002BC202004CC2020020 -+:109FB0006FBE02009ABE0200C7BE020020C10200AE -+:109FC0000CC0020056C1020068C102007AC1020042 -+:109FD0006DC202007FC2020031BA02005BBA020009 -+:109FE00074BB02009DBB020088BC0200A9BA02003B -+:109FF000FCBA020034BD020059BB0200B1C102002C -+:10A00000BDC102005DC2020046C00200B94985F828 -+:10A0100026062846EAF786FBB74986F8C103284694 -+:10A02000EAF780FBB54986F8C2032846EAF77AFBCF -+:10A0300086F8C30395F8261611B12846FFF720FCD1 -+:10A040004FF0FF32AE492846EAF760FB80B210F4C9 -+:10A05000004F18BF4FF0FF324FF0FF33A6F86200F9 -+:10A06000A6F8663018BFA6F86220A6F86830284621 -+:10A07000A449EAF723FB58B12846A249EAF752FB64 -+:10A0800080B210F4004F04BFA6F86600A6F868007E -+:10A0900028469D49EAF712FB48B128469A49EAF753 -+:10A0A00041FB80B210F4004F08BFA6F866002846B6 -+:10A0B0009649EAF703FB48B128469449EAF732FB90 -+:10A0C00080B210F4004F08BFA6F8680090494FF026 -+:10A0D000FF322846EAF71AFB4FF0FF32A6F8C40316 -+:10A0E0008C492846EAF712FB8B49A6F8C603284696 -+:10A0F000EAF718FB8949A6F8C8034FF4CF7228463F -+:10A10000EAF704FB8649C6F8CC0347F69A6228466C -+:10A11000EAF7FCFA8349C6F8D0030A222846EAF790 -+:10A12000F5FA8149C6F8D40308222846EAF7EEFA80 -+:10A130007E49C6F8D80341F26E022846EAF7E6FAED -+:10A140000A22C6F8DC037A492846EAF7DFFA794999 -+:10A15000C6F8E0032846EAF7E5FA7749A6F8E403EB -+:10A160002846EAF7DFFA96F8E83380B2A6F8E60365 -+:10A170002BB103B2002BC4BF0022A6F8E623502265 -+:10A180006E492846EAF7C2FA6D4986F8EA0328467E -+:10A19000EAF7C8FA6B4986F8EC032846EAF7C2FAF0 -+:10A1A000694986F8ED032846EAF7BCFA674986F85C -+:10A1B000EE034FF0FF322846EAF7A8FA644986F822 -+:10A1C000F0034FF0FF322846EAF7A0FA4FF0FF34D1 -+:10A1D00086F8F1035F49224686F8EF432846EAF7FE -+:10A1E00095FA5D4986F8F20322462846EAF78EFA88 -+:10A1F0005A4986F8590522462846EAF787FA584907 -+:10A2000086F85A0522462846EAF780FA554986F824 -+:10A21000F30322462846EAF779FA534986F85B05A4 -+:10A2200022462846EAF772FA504986F85C0522462B -+:10A230002846EAF76BFA4E4986F8F4032246284688 -+:10A24000EAF764FA4B4985F8DA0522462846EAF728 -+:10A250005DFA4949A6F8F60322462846EAF756FA77 -+:10A260004649A6F8F80322462846EAF74FFA444939 -+:10A27000A6F8FA0322462846EAF748FA4149A6F822 -+:10A28000FC0322462846EAF741FA3F49A6F8FE03B6 -+:10A2900022462846EAF73AFA3C49A6F80004224644 -+:10A2A0002846EAF733FA3A49A6F802042246284635 -+:10A2B000EAF72CFA0022A6F8040436492846EAF701 -+:10A2C00025FA0022A6F85E0533492846EAF71EFA69 -+:10A2D0000022A6F8600531492846EAF717FA00225D -+:10A2E000A6F862052E492846EAF710FA2D49A6F885 -+:10A2F000640559E04FBA020043BA0200A7C0020049 -+:10A300008DBD02004BC0020094C10200C0BB020020 -+:10A31000D2BB020067BF020035BB02005BC0020077 -+:10A32000A0BA0200BEBD0200D9BB02004DC10200AE -+:10A33000EBBD02009AC002007FBD0200BCBC02005F -+:10A34000AEBF020010BA0200DCBF020095BA0200E4 -+:10A3500002BD020032C1020039C0020090BB0200FF -+:10A36000A6BC02003EBB0200BBBA0200F0BB02006A -+:10A37000EBBE02001FBE0200C9BA02006DC002009F -+:10A38000B3BD02004CBB0200F4BC020016BF0200C9 -+:10A390005CBC02007AC002006EBF020059BF02001E -+:10A3A000D3C00200C6BC02002846EAF7BBF9B8F1E8 -+:10A3B000020F86F8060414D12846A449EAF77EF96C -+:10A3C000002800F0A382344600273A4628469F49D9 -+:10A3D000EAF796F90137C4F80C040434052FF4D1D8 -+:10A3E00016E0B8F1010F13D128469949EAF766F94A -+:10A3F000002800F08B82344600273A4628469449CC -+:10A40000EAF77EF90137C4F820040434052FF4D1AB -+:10A4100090494FF0FF322846EAF778F98E49A6F8BE -+:10A420003E044FF0FF322846EAF770F98B49A6F850 -+:10A4300040044FF0FF322846EAF768F98849A5F84A -+:10A44000DE0F2846EAF73AF930B128468449EAF7A0 -+:10A4500069F941F2EA23E852824928464FF0FF3277 -+:10A46000EAF754F941F23433E8527F492846EAF7D3 -+:10A4700025F930B128467C49EAF754F941F2EE2338 -+:10A48000E852284679490022EAF740F9C0B286F836 -+:10A490004D0358B176492846EAF744F97549C6F89C -+:10A4A00050032846EAF73EF9C6F860032846724989 -+:10A4B000EAF704F928B3D5F8B8006F49D8F7F6F9E8 -+:10A4C00006281ED1344600273A466B49D5F8B80015 -+:10A4D000D8F360F284F895037A1C6749D5F8B80080 -+:10A4E000D8F358F284F89703BA1CD5F8B80062493B -+:10A4F000D8F350F2033784F899030134062FE3D1DF -+:10A5000011E0012386F89533313386F896330E3304 -+:10A5100086F8973386F89833042386F899334FF0FA -+:10A52000FF3386F89A3355492846FF22EAF7EEF8BA -+:10A530004FF0FF03A6F85403A6F85633A6F8583395 -+:10A54000A6F85A3328464E49EAF7B8F828B3D5F8A2 -+:10A55000B8004B49D8F7AAF934460328B4BF80465F -+:10A560004FF00308002707E03A4628464449EAF737 -+:10A57000C7F80137A4F8540302344745F4DB06EB6F -+:10A58000470303F55473063304E0B6F85623013746 -+:10A5900023F8022C0233022FF7DD01223949284625 -+:10A5A000EAF7B4F8384986F840032846EAF7BAF8DB -+:10A5B000012286F84B0335492846EAF7A7F83449C3 -+:10A5C00086F841032846EAF7ADF8324986F84C038D -+:10A5D0004FF0FF322846EAF799F82F4986F84903E9 -+:10A5E0004FF0FF322846EAF791F82C4986F84A03E3 -+:10A5F0004FF0FF322846EAF789F8294986F85C03CC -+:10A600004FF0FF322846EAF781F8264986F85D03C5 -+:10A610002846EAF753F8002846D0012421490022B1 -+:10A6200086F8BB442846EAF76BF81E4986F8BC0456 -+:10A6300022462846EAF764F81A4986F8BD04022241 -+:10A640002846EAF75DF886F8BE042FE0E3BB020077 -+:10A65000EFBA02001ABD0200CCC002000CBE02001C -+:10A660000EBD02003CC202001EC0020066BB02001A -+:10A67000C8BF020050BD0200AFBB020037BF0200DE -+:10A68000A3C20200EAC002006ABC020016BB0200BC -+:10A6900022BF020079BA0200FBBD0200E5BF020042 -+:10A6A0004DBE020091C2020086F8BB04FF22994908 -+:10A6B0002846EAF72BF8FF2286F8BF049649284679 -+:10A6C000EAF724F8954986F8C0042846EAF72AF8FC -+:10A6D0000022A6F8C20492492846EAF717F8002299 -+:10A6E00086F818058F492846EAF710F8C0B286F8B0 -+:10A6F0001A05EB69DB685B6C03F00703052B03D9D4 -+:10A7000010B1002386F81A35874900222846E9F758 -+:10A71000FDFF864986F81C0500222846E9F7F6FF6A -+:10A72000834986F81D054FF0FF322846E9F7EEFF12 -+:10A73000804986F81E0500222846E9F7E7FF7E4992 -+:10A7400086F895054FF0FF322846E9F7DFFF7B4991 -+:10A75000A6F8200501222846E9F7D8FF784986F8AF -+:10A7600027054FF0FF322846E9F7D0FF7549A6F8D4 -+:10A770002A054FF0FF322846E9F7C8FF7249A6F8CC -+:10A780002C0500222846E9F7C1FF704986F83A05F2 -+:10A7900000222846E9F7BAFF6D4986F83B054FF0DD -+:10A7A000FF322846E9F7B2FF6A4986F83C05284699 -+:10A7B000E9F784FF30B128466649E9F7B3FF86F828 -+:10A7C000420503E04FF0FF3386F8423528466249E0 -+:10A7D000E9F774FF30B128465F49E9F7A3FFA6F80F -+:10A7E000440503E04FF0FF33A6F844355B492846A3 -+:10A7F0004FF0FF32E9F78AFF5949A6F8900528463D -+:10A80000E9F75CFF30B301245549002286F8524530 -+:10A810002846E9F775FF524986F85305224628462F -+:10A82000E9F76EFF4E4986F8540502222846E9F7FB -+:10A8300067FF4B4986F8550503222846E9F760FF74 -+:10A84000474986F8560504222846E9F759FF86F855 -+:10A85000570501E086F8520542494FF0FF3228467D -+:10A86000E9F754FF404986F858054FF0FF32284673 -+:10A87000E9F74CFF3D4986F859054FF0FF3228466D -+:10A88000E9F744FF3A4986F85A0500222846E9F7D5 -+:10A890003DFF384986F8700500222846E9F736FF63 -+:10A8A000032286F8800534492846E9F72FFF33490B -+:10A8B00086F881052846E9F735FF314986F8820593 -+:10A8C0002846E9F72FFF2F49A6F884052846E9F71F -+:10A8D00029FF2D49A6F886052846E9F723FF2B49CD -+:10A8E000A6F888052846E9F71DFF2949A6F88A0534 -+:10A8F0002846E9F717FF2749C6F88C0500222846A5 -+:10A90000E9F704FF86F89405012000E0002006B076 -+:10A91000BDE8F08145C102008CC10200DABA020034 -+:10A920001DBA0200CFBD02005EBE0200B2C002002E -+:10A93000ACBE020003BA0200FABB0200F1B9020089 -+:10A940002ABB020081BE020086BB02009FB9020042 -+:10A950009CBD0200D6BC02006DBA02000FBC020012 -+:10A960008ABA0200A6BD020039C0020090BB0200F4 -+:10A9700043BD02004DBC020022BC02007FBC0200AD -+:10A9800028C0020088C00200D9BE020047BF0200F2 -+:10A9900022BD0200CBC10200C36970B504460E4659 -+:10A9A00098684FF4B961DCF393F1C4F8A80000286B -+:10A9B0005CD000214FF4B962D7F342F3E369D4F8D5 -+:10A9C000A8501B6D13F4803F05D1012241F22403EE -+:10A9D00084F81A26E254E369D868E4F7B5FF41F237 -+:10A9E0000803E0500023EB63214B20462362214BF8 -+:10A9F00031466362204BA362204BE362204BA36786 -+:10AA0000204BE367204BC4F89030204BC4F88430CF -+:10AA10001F4B23631F4B63631F4BE3631F4B636435 -+:10AA20001F4B63651F4BA3651F4BC4F88C301F4B36 -+:10AA3000C4F888301E4BE3661E4BC4F89C301E4B96 -+:10AA4000C4F8A0301D4BC4F8A430FEF7D7FF68B19E -+:10AA50002046EBF757FD2046FEF73AFF30B120467F -+:10AA6000FEF790FF003818BF012000E0002070BD05 -+:10AA7000A9D00100E54A010091CD010055A20100D5 -+:10AA8000B9A001001D4F010075A901005DA90100D9 -+:10AA9000CD9B0100BD8701003D9C0100FD840100AC -+:10AAA0009D550100A15701007DCC0100C54B01005F -+:10AAB000B1530100198801001582010045CC010045 -+:10AAC00010B5014620B103680C221868DCF310F1C0 -+:10AAD00010BDC0462DE9F04105460F4600680C2127 -+:10AAE0001646DCF3F5F008B9044607E004460021F9 -+:10AAF0000C22D7F3A5F225606660A7602046BDE86A -+:10AB0000F081C04610B5044650B10649224640685F -+:10AB1000F9F31AF263682146D8688822DCF3E8F07A -+:10AB200010BDC04603E88600F0B5882185B0054613 -+:10AB30004068DCF3CDF0074608B904463BE000214D -+:10AB400088220446D7F37CF22B683D607B600026A8 -+:10AB500004212846194A1A4B0096019700F0EEF896 -+:10AB6000B042B86021DB174B019600930296039622 -+:10AB700078681549154A3B46F9F3AEF1A8B91E238A -+:10AB80007B610423FB7302233B74083301227B7433 -+:10AB90004FF6AF7384F82000FA773A73BA61A07465 -+:10ABA0006073A073BB83BA7705E068683946882272 -+:10ABB000DCF39EF00024204605B0F0BD5123850053 -+:10ABC00025238500811485002C1D020003E88600E2 -+:10ABD00070B50468CCB1D4F8F811A56829B1A8689B -+:10ABE000E4F34EF50023C4F8F831084928682246FA -+:10ABF000F9F3AAF1216819B168681C22DCF378F036 -+:10AC0000686821466269DCF373F070BD441D020080 -+:10AC10002DE9FF4740F2C45681468A461046314628 -+:10AC200017469846DCF354F00446002879D00021FA -+:10AC30003246D7F305F238461C21DCF349F00546CD -+:10AC4000206030B9384621463246DCF351F02846C0 -+:10AC500067E000211C22D7F3F3F122684FF0FF33A5 -+:10AC6000A36100254FF014036661C4F80890E76003 -+:10AC7000C4F804809571A4F808324FF02803A4F8B2 -+:10AC800006324FF02D03A4F804324FF0FA03A4F873 -+:10AC90000A320223146084F80C324FF06403A4F8E3 -+:10ACA0003E3284F80D5250461F4922462B46E4F3AB -+:10ACB00003F5C4F8F80108B30523C4F81C32373390 -+:10ACC000C4F8283204F51072184BC4F81822C4F8DE -+:10ACD000142204F53D72C4F82422C4F82022009303 -+:10ACE000134BD9F8000003931249134A23460195E8 -+:10ACF0000295F9F3F1F008B9206812E0D4F8F811E0 -+:10AD000011B15046E4F3BCF4216819B138461C2255 -+:10AD1000DBF3EEF73846214640F2C452DBF3E8F7A6 -+:10AD2000002004B0BDE8F087C13C8500F537850000 -+:10AD300035D201004C1D0200441D020070B5D0F850 -+:10AD400000451E46A3698E460F2B154602D94FF0CB -+:10AD5000FF3011E01801E1690133A361049B42183F -+:10AD60009360059B5660D36062694550D31C734461 -+:10AD700023F003036361104670BDC04610B5014661 -+:10AD800040B190F820200368D200D86802F5927292 -+:10AD9000DBF3AEF710BDC046C36908221B692DE97D -+:10ADA000F041073393FBF2F3DFB2FB0003F5927639 -+:10ADB00005463146C068DBF38BF708B9044614E05A -+:10ADC000044632460021D7F33BF104F12403E3614A -+:10ADD000FAB204F59273E36003EB820323614FF44C -+:10ADE0000373256084F8207063612046BDE8F0811C -+:10ADF0007047C0462DE9F04F3B4F89B038683B495A -+:10AE0000D7F3BAF50128DFF81881DFF8189157D089 -+:10AE1000DFF800C1364EDCF8001000220091354901 -+:10AE200013680968344D354C0291316834480193F8 -+:10AE300004912B68216803930691036831490593B7 -+:10AE40000B68DFF8D4E007932A4B02602E481A60A3 -+:10AE50000A602E4B08F10401D7F800A0DEF800B01C -+:10AE60003A60CEF80020CCF8002032602260091A47 -+:10AE7000013A2B60D7F3D4F5254B9842FCD11A4BFD -+:10AE80000099C3F800A0234B1960234B0021C3F89D -+:10AE900000B00A68214B1A60019A164B0A600299A9 -+:10AEA000039A1960144B04991A60114B059A1960A2 -+:10AEB000134B06991A60114B079A1960114B1A60CF -+:10AEC00098F81B3089F8003098F81C3089F8013068 -+:10AED00098F81D3089F8023098F81E3089F8033050 -+:10AEE00009B0BDE8F08FC046FC1E0200B81D02008C -+:10AEF00044EC000048EC000034EC000050EC000092 -+:10AF00004CEC000054EC000000000000DDBAADBBCA -+:10AF1000E320BBDE001F0200F81E020038EC000038 -+:10AF2000005903001C2802002DE9F04F91B0FFF7F3 -+:10AF300061FF684B1B68043B012B03D8664B186804 -+:10AF4000FFF756FFFBF7BEF800210746E0F3AEF12E -+:10AF500038460021E0F364F128B1036A002BBCBF3E -+:10AF60004FF0004303620EA90822B86BD7F3F6F244 -+:10AF7000FA6B0B9038460C92E4F7E6FC574E00F55E -+:10AF8000424000F5A870B0FBF6F00D903846E4F7AB -+:10AF9000DBFC04463846E4F7D7FC00F54248384667 -+:10AFA000E4F7DCFC00F5424A3846E4F7D7FC04F548 -+:10AFB000424408F5A87804F5A874B8FBF6F808FB35 -+:10AFC000164804463846E4F7C9FC00F542453846C1 -+:10AFD000E4F708FA00F542493846E4F703FA04F5C5 -+:10AFE000424405F5A87504F5A874B5FBF6F505FB14 -+:10AFF000164504463846E4F7F5F9394A00F542406B -+:10B00000019204F542440B9A00F5A870B0FBF6F0EB -+:10B010000AF5A87A09F5A87904F5A874BAFBF6FA36 -+:10B02000B9FBF6F9029200FB16460C9ADFF8D4B091 -+:10B0300003920D9A2B4B04922B492C4AB8FBFBF838 -+:10B04000B5FBFBF5B6FBFBF629480093CDF8148061 -+:10B05000CDF818A00795CDF820900996E6F724FBC7 -+:10B06000244840F60D0144F2F432FAF7AFFF48B13C -+:10B07000204840F6290144F2F432FAF7A7FF08B15C -+:10B08000002403E01C4A1D4B1A4C1A603846FDF799 -+:10B09000D7FA44F218334FF6FF72904214BF0246BB -+:10B0A0001A4640F612011648FAF790FF144B002892 -+:10B0B0000CBF194600214CB141B1104B20461B6812 -+:10B0C0005B689847236920465B689847384611B00B -+:10B0D000BDE8F08F54EC000050EC000040420F003F -+:10B0E000A0D60100ABFF8600BE1D0200C31D0200FA -+:10B0F000E8D102004C1F0200281F0200F8260000C1 -+:10B10000F81D0200A0860100776C25643A20427287 -+:10B110006F6164636F6D2042434D25642038303287 -+:10B120002E313120576972656C65737320436F6EE1 -+:10B1300074726F6C6C65722025730A0025733A2057 -+:10B1400042726F6164636F6D20534450434D4420DD -+:10B15000434443206472697665720A0073647063C5 -+:10B160006D6463646325640072737369736D663222 -+:10B17000673D2564007874616C667265713D256475 -+:10B1800000616132673D3078257800627734307035 -+:10B190006F3D30782578006C6564626825643D30C9 -+:10B1A0007825780074737369706F7332673D3078F7 -+:10B1B0002578007273736973617632673D25640088 -+:10B1C0006C65676F66646D3430647570706F3D30A8 -+:10B1D0007825780070613168696D61787077723DAB -+:10B1E0002564006D617870326761303D3078257874 -+:10B1F000007061316974737369743D2564006D6119 -+:10B200006E6669643D307825780073756276656E88 -+:10B210006469643D30782578002004D0023643FF0D -+:10B22000FF626F617264747970653D3078257800D3 -+:10B230006D6373256467706F25643D3078257800F1 -+:10B240006D616E663D2573006D61787035676C6168 -+:10B25000303D30782578006D61787035676C6131EC -+:10B260003D30782578006F66646D35676C706F3D92 -+:10B27000307825780072737369736D6335673D2587 -+:10B280006400626F617264666C616773323D30782E -+:10B29000257800747269736F32673D3078257800C5 -+:10B2A0007064657472616E676532673D30782578C9 -+:10B2B000006D63736277323035676C706F3D307844 -+:10B2C00025780000006D637362773230756C3567E6 -+:10B2D0006C706F3D30782578006D63736277343021 -+:10B2E00035676C706F3D30782578000000706131F3 -+:10B2F0006C6F6D61787077723D2564006D61787058 -+:10B30000326761313D30782578007278706F35672B -+:10B310003D2564006D63733332706F3D307825785E -+:10B320000073756264657669643D307825780069DC -+:10B330007474356761303D307825780069747435F0 -+:10B340006761313D30782578007061316D617870CA -+:10B3500077723D256400626F6172647265763D307C -+:10B36000782578006D6373627732303267706F3D95 -+:10B37000307825780000006D637362773230756C29 -+:10B380003267706F3D30782578006D637362773473 -+:10B39000303267706F3D307825780000006D637340 -+:10B3A0006277323035676D706F3D307825780000F8 -+:10B3B000006D637362773230756C35676D706F3D09 -+:10B3C00030782578006D63736277343035676D703F -+:10B3D0006F3D3078257800000073726F6D7265766E -+:10B3E0003D2564007770736C65643D256400706171 -+:10B3F000316C6F62303D2564007061316C6F623179 -+:10B400003D2564007061316C6F62323D25640070CF -+:10B410006125646725637725646125643D3078255F -+:10B42000780070613062303D2564007061306231B7 -+:10B430003D25640070613062323D25640072737393 -+:10B4400069736D6332673D2564007472693567689E -+:10B450003D25640075736266733D25640063636B0C -+:10B46000706F3D307825780074726935676C3D25C2 -+:10B4700064006F66646D356768706F3D307825785D -+:10B4800000616725643D30782578006578747061C7 -+:10B490006761696E35673D307825780070726F643A -+:10B4A0007563746E616D653D257300636464706FD0 -+:10B4B0003D30782578006C65676F66646D62773221 -+:10B4C0003035676C706F3D307825780000006C6512 -+:10B4D000676F66646D62773230756C35676C706F5C -+:10B4E0003D30782578006C65676F66646D627732F1 -+:10B4F0003035676D706F3D307825780000006C65E1 -+:10B50000676F66646D62773230756C35676D706F2A -+:10B510003D30782578006C65676F66646D627732C0 -+:10B5200030356768706F3D307825780000006C65B5 -+:10B53000676F66646D62773230756C356768706FFF -+:10B540003D30782578007278706F32673D25640051 -+:10B550007278636861696E3D30782578006974742B -+:10B56000326761303D3078257800697474326761E4 -+:10B57000313D3078257800616E7473776974636843 -+:10B580003D30782578007478636861696E3D307865 -+:10B5900025780070726F6469643D3078257800709A -+:10B5A00061306974737369743D25640063636B640F -+:10B5B000696766696C74747970653D2564006368B9 -+:10B5C00069707265763D2564006F66646D356770DD -+:10B5D0006F3D30782578006C656464633D30782574 -+:10B5E000303478006D61787035676861303D30784F -+:10B5F0002578006D61787035676861313D30782558 -+:10B60000780070613162303D2564007061316231D3 -+:10B610003D25640070613162323D256400627764CB -+:10B620007570706F3D30782578006D617870356782 -+:10B6300061303D30782578006D6178703567613113 -+:10B640003D3078257800616E74737763746C35676C -+:10B650003D30782578006D63732564672563706FCE -+:10B6600025643D30782578006D637362773230351C -+:10B670006768706F3D307825780000006D637362F5 -+:10B68000773230756C356768706F3D30782578009B -+:10B690006D637362773430356768706F3D3078253D -+:10B6A0007800000074726935673D2564006F706F23 -+:10B6B0003D25640076656E6469643D3078257800C8 -+:10B6C0006C65676F66646D627732303267706F3DAC -+:10B6D0003078257800006C65676F66646D6277323C -+:10B6E00030756C3267706F3D307825787061306DE1 -+:10B6F00061787077723D25640070613168696230ED -+:10B700003D256400706131686962313D25640070D7 -+:10B710006131686962323D256400637573746F6DD1 -+:10B7200076617225643D30782578007265677265B0 -+:10B73000763D3078257800626F617264666C61676F -+:10B74000733D307825780062786132673D2564006A -+:10B750006F656D3D2530327825303278253032786E -+:10B7600025303278253032782530327825303278DD -+:10B77000253032780064657669643D30782578003C -+:10B7800070612564677725646125643D307825788C -+:10B790000072737369736D6635673D2564006F666B -+:10B7A000646D3267706F3D30782578006161356770 -+:10B7B0003D30782578007770736770696F3D256438 -+:10B7C0000062786135673D25640075736265706E4F -+:10B7D000756D3D307825780074737369706F7335BB -+:10B7E000673D3078257800616E74737763746C32CE -+:10B7F000673D3078257800727373697361763567B9 -+:10B800003D2564006F66646D706F3D30782578006B -+:10B8100074726932673D25640073746263706F3DB2 -+:10B82000307825780063636F64653D307830006D53 -+:10B830006163616464723D25730063636F64653D99 -+:10B84000256325630063633D25640063636B326792 -+:10B85000706F3D30782578006363746C3D307825D7 -+:10B86000780072656777696E646F77737A3D2564D7 -+:10B870000065787470616761696E32673D30782564 -+:10B880007800626F6172646E756D3D25640074723C -+:10B8900069736F35673D307825780063636B627735 -+:10B8A00032303267706F3D30782578000000636376 -+:10B8B0006B62773230756C3267706F3D3078257807 -+:10B8C000007064657472616E676535673D30782518 -+:10B8D0007800000080000000FF0000000C00000065 -+:10B8E0000000000000040000FF0000000C00000049 -+:10B8F0000000000000000800FF0000000E00000033 -+:10B90000000000000200000001000400030000002D -+:10B91000010002000A00000002006000DC050000D7 -+:10B9200008071700747870777262636B6F66003275 -+:10B93000675F6367610072737369636F72726E6FC2 -+:10B94000726D00747373696C696D75636F640074F4 -+:10B95000656D70735F687973746572657369730080 -+:10B9600072737369636F7272617474656E003567A8 -+:10B970005F6367610074656D7074687265736800F9 -+:10B98000696E746572666572656E6365006D63737A -+:10B990003267706F30006D63733267706F3100749F -+:10B9A000786761696E74626C356700747373696F70 -+:10B9B00066667365746D696E35676C007473736960 -+:10B9C0006F66667365746D696E35676D0074656D5D -+:10B9D0007073656E73655F736C6F7065006D656124 -+:10B9E00073706F7765720072737369736D66326717 -+:10B9F00000706C6C646F75626C65725F6D6F64650E -+:10BA000032670069716C6F7374316F6666326700FC -+:10BA100072667265673033335F63636B00706C6CA2 -+:10BA2000646F75626C65725F656E61626C653267CA -+:10BA3000006F70656E6C706761696E696478613102 -+:10BA400034300065787470616761696E35670065D0 -+:10BA5000787470616761696E3267006F70656E6CD3 -+:10BA6000706761696E69647861313439007478692E -+:10BA7000716C6F7061673267006E6F6973655F63C9 -+:10BA8000616C5F7265665F3267006C6F67656E5FE1 -+:10BA90006D6F646500706163616C69647832670022 -+:10BAA00074656D705F616464006F70656E6C706763 -+:10BAB00061696E6964786131363500706163616C0B -+:10BAC000696478356768693100706163616C6174BD -+:10BAD0006832673100706D696E00706163616C700F -+:10BAE000756C7365776964746800706D6178007354 -+:10BAF000776374726C6D61705F3567006F70656E2F -+:10BB00006C7074656D70636F727200747373696DBD -+:10BB100061786E7074006E6F6973655F63616C5FEE -+:10BB2000656E61626C655F356700706163616C7042 -+:10BB30007772326700747869716C6F746600706137 -+:10BB400063616C69647835676C6F31007061636143 -+:10BB50006C61746835676869006F70656E6C7070D1 -+:10BB600077726C696D006E6F6973655F63616C5F9E -+:10BB7000646267006F70656E6C706761696E69649E -+:10BB800078613135330074786761696E74626C0076 -+:10BB9000706163616C69647835676869006F7065AE -+:10BBA0006E6C706761696E69647861313537006EFB -+:10BBB0006F6973655F63616C5F7570646174650064 -+:10BBC0006F66646D64696766696C747479706535F5 -+:10BBD000670070616763326700766261745F6D75DC -+:10BBE0006C740073776374726C6D61705F326700A0 -+:10BBF000706163616C616C696D0069716C6F636128 -+:10BC00006C70777232670076626174736D63006185 -+:10BC10006463726673657132670076626174736D16 -+:10BC2000660072786761696E6261636B6F666676E3 -+:10BC3000616C006F70656E6C706761696E696478C5 -+:10BC4000622564006F66646D3267706F007278679A -+:10BC500061696E74626C776C6267610070616361C8 -+:10BC60006C6174683567686931006E6F6973655F10 -+:10BC700063616C5F706F5F626961735F32670072EE -+:10BC800066726567303838006F70656E6C7067611A -+:10BC9000696E696478613136310064796E707772EB -+:10BCA0006C696D656E00706163616C69647835679D -+:10BCB000310074656D70636F7272780064616372D5 -+:10BCC0006174653267007061726670730070613014 -+:10BCD00062325F6C6F00747869716C6F706170753F -+:10BCE00032670074656D7073656E73655F6F707435 -+:10BCF000696F6E00706163616C61746835676C6F49 -+:10BD00003100706163616C69647832673100747806 -+:10BD1000616C706662797032670064616367633278 -+:10BD20006700756E6D6F645F727373695F6F6666CF -+:10BD3000736574006F70656E6C70766F6C74636F92 -+:10BD400072720072786761696E74626C31303000B3 -+:10BD50006E6F6973655F63616C5F6E665F7375625A -+:10BD60007374726163745F76616C00747373697469 -+:10BD70007864656C61790063636B3267706F006330 -+:10BD8000636B507772496478436F72720063636BC0 -+:10BD900064696766696C7474797065006C6F63635D -+:10BDA0006D6F646531006C6F696461636D6F6465AC -+:10BDB000356700706163616C617468356700746534 -+:10BDC0006D705F71007273736973617632670073AF -+:10BDD00070757261766F69645F656E61626C653201 -+:10BDE000670070613062315F6C6F00766261745F12 -+:10BDF00071006D61787032676130006E6F697365D4 -+:10BE00005F63616C5F7265665F3567006F66646D66 -+:10BE1000616E616C6F6766696C746277326700701F -+:10BE20006163616C61746832670070613062300018 -+:10BE30007061306231007061306232006F70656E27 -+:10BE40006C706761696E696478613336006E6F6922 -+:10BE500073655F63616C5F61646A5F356700697118 -+:10BE60006C6F63616C69647832676F666673006FCC -+:10BE700070656E6C706761696E69647861313030CD -+:10BE800000706163616C7077723267310072617744 -+:10BE900074656D7073656E7365006F70656E6C7040 -+:10BEA0006761696E696478613130340069716C6F03 -+:10BEB00063616C6964783267006F70656E6C707076 -+:10BEC00077726374726C006F70656E6C7067616915 -+:10BED0006E696478613130380072786761696E74B8 -+:10BEE000656D70636F727235676D0074785F746F23 -+:10BEF0006E655F706F7765725F696E646578006FFD -+:10BF000070656E6C707265667077720072737369BB -+:10BF1000736D63326700706163616C61746835676B -+:10BF200031006E6F6973655F63616C5F706F5F6234 -+:10BF30006961735F3567006E6F6973655F63616C1C -+:10BF40005F706F5F32670072786761696E74656DEC -+:10BF500070636F727235676C00706163616C6964E5 -+:10BF600078356731746800706167633567007061A8 -+:10BF700063616C69647835676C6F317468007473E1 -+:10BF800073696F66667365746D696E006F70656E58 -+:10BF90006C706761696E696478613430006F7065D8 -+:10BFA0006E6C706761696E696478613434007266C2 -+:10BFB000726567303333006F70656E6C70676169EE -+:10BFC0006E696478613438006E6F6973655F6361B0 -+:10BFD0006C5F686967685F6761696E007266726549 -+:10BFE00067303338006E6F6973655F63616C5F61E2 -+:10BFF000646A5F3267006D656173706F7765723177 -+:10C00000006D656173706F77657232006F70656E79 -+:10C010006C706761696E6964786131313600627095 -+:10C0200068797363616C650072786761696E7465C5 -+:10C030006D70636F7272326700706163616C696406 -+:10C040007835676C6F0061613267006F66646D649C -+:10C05000696766696C74747970650074656D705F8A -+:10C060006D756C74007662617473617600706163E3 -+:10C07000616C61746835676C6F00706163616C69D5 -+:10C08000647832673174680072786761696E7465CC -+:10C090006D70636F72723567680063636B5077729F -+:10C0A0004F6666736574007478707772696E646544 -+:10C0B000780069716C6F63616C69647835676F666D -+:10C0C00066730070613062305F6C6F00676D67632C -+:10C0D000326700706163616C6964783567686931E3 -+:10C0E0007468007278706F3267006E6F6973655F95 -+:10C0F00063616C5F656E61626C655F3267006F7073 -+:10C10000656E6C706761696E696478613532006F65 -+:10C1100070656E6C706761696E6964786135360050 -+:10C120006F70656E6C706761696E696478613131DA -+:10C130003200706163616C69647835670074656DA5 -+:10C140007073617600747269736F32670076626132 -+:10C15000745F616464006F70656E6C706761696EB6 -+:10C1600069647861313230006F70656E6C70676140 -+:10C17000696E69647861313234006F70656E6C701D -+:10C180006761696E6964786131323800747269641C -+:10C19000783267006F66646D64696766696C747491 -+:10C1A000797065326700696E69747869647832679E -+:10C1B0000068775F697163616C5F656E00697163C8 -+:10C1C000616C5F7377705F646973006D75785F672A -+:10C1D00061696E5F7461626C6500747373696F6628 -+:10C1E000667365746D617835676800747373696F21 -+:10C1F00066667365746D617835676C007473736916 -+:10C200006F66667365746D617835676D0074656D12 -+:10C2100070736D630074656D70736D660074737315 -+:10C22000696F66667365746D6178006F70656E6CBA -+:10C23000706761696E696478613630007478616C2A -+:10C24000706662797032675F63636B006F70656EF2 -+:10C250006C706761696E6964786136340066726516 -+:10C26000716F66667365745F636F7272006F70657D -+:10C270006E6C706761696E69647861313332006F2A -+:10C2800070656E6C706761696E69647861313336B0 -+:10C29000007874616C6D6F646500747373697469A0 -+:10C2A0006D65006E6F6973655F63616C5F706F5F72 -+:10C2B000356700747373696F66667365746D696E54 -+:10C2C00035676800B8C70200600000001200000077 -+:10C2D000000000002000000028C702002600000027 -+:10C2E0000E0000000000000010000000B4CC0200AE -+:10C2F000980000000D000000000000002000000079 -+:10C3000074C702004400000011000000000000009B -+:10C310000800000074D102001000000010000000AE -+:10C3200000000000080000000000000040000000C5 -+:10C3300080000000C00000000100000005000000B7 -+:10C3400002000000060000000A0000004A00000091 -+:10C350008A000000CA0000000A0100004A01000033 -+:10C360008A0100008A0500008A0900008A0D000089 -+:10C370008A1100008A5100008A9100008AD10000D1 -+:10C380008A1101008A5101008A9101008900000090 -+:10C390008AD101008A1102000000000000000000A4 -+:10C3A000000000000000000000000000000000008D -+:10C3B000000000000000000000000000000000007D -+:10C3C000000000000000000000000000000000006D -+:10C3D000000000000000000000000000000000005D -+:10C3E000000000000000000000000000000000004D -+:10C3F000000000000000000000000000000000003D -+:10C40000000000000000000000000000000000002C -+:10C41000000000000000000000000000000000001C -+:10C42000000000000000000000000000000000000C -+:10C4300000000000000000000000000000000000FC -+:10C4400000000000000000000000000000000000EC -+:10C4500000000000000000000000000000000000DC -+:10C4600000000000000000000000000000000000CC -+:10C4700000000000000000000000000000000000BC -+:10C4800000000000000000000000000000000000AC -+:10C49000000000000000000000000000000000009C -+:10C4A000000000000000000003001300410300131F -+:10C4B000004003001200410300120040030011007D -+:10C4C0004103001100400300100041030010004030 -+:10C4D000030010003E030010003C030010003A036C -+:10C4E000000F003D03000F003B03000E003D030062 -+:10C4F0000E003C03000E003A03000D003C03000D4B -+:10C50000003B03000C003E03000C003C03000C0049 -+:10C510003A03000B003E03000B003C03000B003B02 -+:10C5200003000B003903000A003D03000A003B032F -+:10C53000000A0039030009003E030009003C030023 -+:10C5400009003A0300090039030008003E0300080F -+:10C55000003C030008003A0300080039030008000B -+:10C5600037030007003D030007003C030007003AC3 -+:10C5700003000700380300070037030006003E03EE -+:10C580000006003C030006003A03000600390300E1 -+:10C5900006003703000600360300060034030005DA -+:10C5A000003D030005003B030005003903000500C2 -+:10C5B000380300050036030005003503000500338D -+:10C5C000030004003E030004003C030004003A039F -+:10C5D00000040039030004003703000400360300A0 -+:10C5E000040034030004003303000400310300049A -+:10C5F0000030030004002E030003003C030003008E -+:10C600003A03000300390300030037030003003638 -+:10C61000030003003403000300330300030031036D -+:10C6200000030030030003002E030003002D03006D -+:10C6300003002C030003002B030003002903000266 -+:10C64000003D030002003B0300020039030002002A -+:10C6500038030002003603000200350300020033F5 -+:10C6600003000200320300020030030002002F0327 -+:10C670000002002E030002002C030002002B030026 -+:10C6800002002A030002002903000200270300021F -+:10C69000002603000200250300020024030002001C -+:10C6A00023030002002203000200210300020020F5 -+:10C6B000030001003F030001003D030001003B03B4 -+:10C6C00000010039030001003803000100360300B7 -+:10C6D00001003503000100330300010032030001B3 -+:10C6E0000030030001002F030001002E03000100B1 -+:10C6F0002C030001002B030001002A030001002984 -+:10C7000003000100270300010026030001002503A8 -+:10C7100000010024030001002303000100220300A4 -+:10C7200001002103000100200004000400040004B3 -+:10C7300000040004000400040004000400040104D8 -+:10C7400080048204830484040004000400040004C0 -+:10C7500000040004000400040004010480048204B6 -+:10C760008304840485048604050506050705080579 -+:10C7700009050A05090C12181818090C12181818BE -+:10C7800000000C076F7A060C0F7B7E0105080B0E6C -+:10C79000110000000000000000000306090C0F1249 -+:10C7A000000000000000000000000306090C00006B -+:10C7B0000000000000000000000000000400000075 -+:10C7C0004000000080000000C000000001000000E8 -+:10C7D000050000004500000085000000C5000000C5 -+:10C7E00005010000450100008501000085050000ED -+:10C7F00085090000850D000089090000890D0000F1 -+:10C8000089110000895100008991000089D1000040 -+:10C8100089110100854D0000858D000085CD000047 -+:10C820008951010089910100000000000000000012 -+:10C8300000000000000000000000000000000000F8 -+:10C8400000000000000000000000000000000000E8 -+:10C8500000000000000000000000000000000000D8 -+:10C8600000000000000000000000000000000000C8 -+:10C8700000000000000000000000000000000000B8 -+:10C8800000000000000000000000000000000000A8 -+:10C890000000000000000000000000000000000098 -+:10C8A0000000000000000000000000000000000088 -+:10C8B0000000000000000000000000000000000078 -+:10C8C0000000000000000000000000000000000068 -+:10C8D0000000000000000000000000000000000058 -+:10C8E0000000000000000000000000000000000048 -+:10C8F0000000000000000000000000000000000038 -+:10C900000000000000000000000000000000000027 -+:10C910000000000000000000000000000000000017 -+:10C920000000000000000000000000000000000007 -+:10C9300000000000000000008000800080008000F7 -+:10C9400080008000800080008000810082008300E1 -+:10C9500084008500040105018000800080008000C3 -+:10C9600080008000800081008200830084008500B8 -+:10C9700004010501060107011901870188018901E8 -+:10C980008A018B0107001F004807001F00460700AF -+:10C990001F004407001E004307001D004407001C41 -+:10C9A000004407001B004507001A00460700190055 -+:10C9B0004607001800470700170048070017004601 -+:10C9C0000700160047070015004807001500460736 -+:10C9D000001500440700150042070015004007003D -+:10C9E00015003F0700140040070013004107001323 -+:10C9F000004007001200410700120040070011002C -+:10CA000041070011004007001000410700100040DE -+:10CA1000070010003E070010003C070010003A0716 -+:10CA2000000F003D07000F003B07000E003D070010 -+:10CA30000E003C07000E003A07000D003C07000DF9 -+:10CA4000003B07000C003E07000C003C07000C00F8 -+:10CA50003A07000B003E07000B003C07000B003BB1 -+:10CA600007000B003907000A003D07000A003B07DA -+:10CA7000000A0039070009003E070009003C0700D2 -+:10CA800009003A0700090039070008003E070008BE -+:10CA9000003C070008003A070008003907000800BA -+:10CAA00037070007003D070007003C070007003A72 -+:10CAB00007000700380700070037070006003E0799 -+:10CAC0000006003C070006003A0700060039070090 -+:10CAD0000600370700060036070006003407000589 -+:10CAE000003D070005003B07000500390700050071 -+:10CAF000380700050036070005003507000500333C -+:10CB0000070004003E070004003C070004003A0749 -+:10CB1000000400390700040037070004003607004E -+:10CB20000400340700040033070004003107000448 -+:10CB30000030070004002E070003003C070003003C -+:10CB40003A070003003907000300370700030036E7 -+:10CB50000700030034070003003307000300310718 -+:10CB600000030030070003002E070003002D07001C -+:10CB700003002C070003002B070003002907000215 -+:10CB8000003D070002003B070002003907000200D9 -+:10CB900038070002003607000200350700020033A4 -+:10CBA00007000200320700020030070002002F07D2 -+:10CBB0000002002E070002002C070002002B0700D5 -+:10CBC00002002A07000200290700020027070002CE -+:10CBD00000260700020025070002002407000200CB -+:10CBE00023070002002207000200210700020020A4 -+:10CBF000070001003F070001003D070001003B075F -+:10CC000000010039090C12181818090C121818180C -+:10CC100000000C076F7A060C0F7B7E0105080B0ED7 -+:10CC2000110000000000000000000306090C0F12B4 -+:10CC3000000000000000000000000306090C0000D6 -+:10CC4000000000000000000007001000390700107D -+:10CC500000380700100036070010003407001000ED -+:10CC60003307001000310700100030070010002FBC -+:10CC7000070010002D070010002C070010002B07E4 -+:10CC80000010002A070010002807001000270700E6 -+:10CC900010002607001000250700100024070010D0 -+:10CCA00000230700100022070010002107001000D9 -+:10CCB0002000000000000000400000000000000014 -+:10CCC00040000000000000004000000000000000E4 -+:10CCD00040000000000000004000000000000000D4 -+:10CCE00040000000000000004000000000000000C4 -+:10CCF00040000000000000004000000000000000B4 -+:10CD00004000000000000000400000000000001093 -+:10CD1000400000000000000048000000000000206B -+:10CD20004800000000000030480000000000004003 -+:10CD300048000000000000504800000000000060B3 -+:10CD4000480000000000005050000000000000609B -+:10CD50005000000000000070500000000000008043 -+:10CD6000500000000000009050000000000000A0F3 -+:10CD700050000000000000B050000000000000C0A3 -+:10CD800050000000000000D050000000000000E053 -+:10CD900050000000000000F050000000000000E023 -+:10CDA00058000000000000005900000000000010C2 -+:10CDB0005900000000000020590000000000003071 -+:10CDC0005900000000000040590000000000005021 -+:10CDD0005900000000000060590000000000000041 -+:10CDE00040000000000000004000000000000000C3 -+:10CDF00040000000000000004000000000000000B3 -+:10CE000040000000000000004000000000000000A2 -+:10CE10004000000000000000400000000000000092 -+:10CE20004000000000000010400000000000000072 -+:10CE30004800000000000020480000000000003012 -+:10CE400048000000000000404800000000000050C2 -+:10CE50004800000000000060480000000000005092 -+:10CE60005000000000000060500000000000007052 -+:10CE70005000000000000080500000000000009002 -+:10CE800050000000000000A050000000000000B0B2 -+:10CE900050000000000000C050000000000000D062 -+:10CEA00050000000000000E050000000000000F012 -+:10CEB00050000000000000705100000000000080E1 -+:10CEC0005100000000000090510000000000002010 -+:10CED0005900000000000030590000000000004030 -+:10CEE00059000000000000505900000000000060E0 -+:10CEF00059000000000000A059000000000000B030 -+:10CF000059000000000000000000000000000000C8 -+:10CF10000000000000000000080000000000000009 -+:10CF200008000000000000000800000000000000F1 -+:10CF300008000000000000000800000000000000E1 -+:10CF400008000000000000000800000000000000D1 -+:10CF500008000000000000000800000000000010B1 -+:10CF60000800000000000020080000000000003061 -+:10CF70000800000000000040080000000000005011 -+:10CF800008000000000000401000000000000050F9 -+:10CF900010000000000000601000000000000070A1 -+:10CFA0001000000000000080100000000000007071 -+:10CFB0001800000000000080180000000000009031 -+:10CFC00018000000000000A018000000000000B0E1 -+:10CFD00018000000000000C018000000000000D091 -+:10CFE00018000000000000E018000000000000F041 -+:10CFF00018000000000000001900000000000010F0 -+:10D00000190000000000002019000000000000309E -+:10D01000190000000000004019000000000000504E -+:10D0200019000000000000601900000000000070FE -+:10D03000190000000000008019000000000000003E -+:10D0400008000000000000000800000000000000D0 -+:10D0500008000000000000000800000000000000C0 -+:10D0600008000000000000000800000000000000B0 -+:10D070000800000000000010080000000000002070 -+:10D080000800000000000030080000000000004020 -+:10D0900008000000000000500800000000000040F0 -+:10D0A00010000000000000501000000000000060B0 -+:10D0B0001000000000000070100000000000009050 -+:10D0C0001100000000000070180000000000008047 -+:10D0D000180000000000009018000000000000A0F0 -+:10D0E00018000000000000B018000000000000C0A0 -+:10D0F00018000000000000D018000000000000E050 -+:10D1000018000000000000F01800000000000000FF -+:10D1100019000000000000101900000000000020AD -+:10D12000190000000000003019000000000000405D -+:10D13000190000000000005019000000000000600D -+:10D1400019000000000000701900000000000080BD -+:10D1500019000000000000A019000000000000B04D -+:10D1600019000000000000000000000000000000A6 -+:10D17000000000005F36291F5F36291F5F36291F18 -+:10D180005F36291F28C30200600000001200000063 -+:10D19000000000002000000038C902002600000046 -+:10D1A0000E000000000000001000000014CF02007C -+:10D1B000980000000D0000000000000020000000AA -+:10D1C00004CC020044000000110000000000000038 -+:10D1D0000800000074D102001000000010000000E0 -+:10D1E00000000000080000000A5254452028257362 -+:10D1F0002D25732573257329202573206F6E2042FA -+:10D20000434D25732072256420402025642E25641B -+:10D210002F25642E25642F25642E25644D487A0A17 -+:10D22000000000002DE9FF4106460D460846FC219E -+:10D2300017469846D9F34CF5044608B91E302DE040 -+:10D240000021FC22D4F3FCF60A9B04F1640204F1F1 -+:10D250006801009301920291304629463A464346BE -+:10D26000FBF73EFC206608B90B2017E040F61201E0 -+:10D270000022DDF3C3F700210A46E0662560206E38 -+:10D28000DDF3E0F52046F8F707FB206EFBF7EAFA3E -+:10D2900028462146FC22D9F32BF5002004B0BDE836 -+:10D2A000F081C04601BC600300104E03BFDE02F0F7 -+:10D2B0000C0E0280C12700000403BFDE02F00D6FD8 -+:10D2C000035B5E02F0000601BC6013001043000126 -+:10D2D0005E02F0000000025E02F0117A00025E02BF -+:10D2E000F0118F020200BF00007302045EFF000015 -+:10D2F0000E006B446557800E01846002F7F7BF0192 -+:10D30000BC6003000AAE00025E02F00F960202DE6D -+:10D31000FF000013006B44655620130182E002F702 -+:10D32000F7BF03BFDE02F005A200682B6F000018F4 -+:10D330000280DEFF000073006B44655B6073018454 -+:10D34000E006F577AB00025E02F0112F020480C701 -+:10D3500000001A028180C700001C01806002F7F7FC -+:10D36000BF01BC6003000AE200682B070000270031 -+:10D37000E844655837A1006DDE8557402300682BCF -+:10D380004300002700E844655A17A1006DDE855769 -+:10D39000402503BFDE02F0002701BC6003000AC283 -+:10D3A00001BC6003000AC101BC6003000AD001BCDB -+:10D3B0006003000AC80202DEB300002A0200420332 -+:10D3C00000002A00025E02F00B1602845EB3000029 -+:10D3D000730068AB0F0000730283DEB700002E02FB -+:10D3E0000180C700004800B02ACB0017A202802BA2 -+:10D3F000F300003500B02B230017A1006DDE855C23 -+:10D40000E06400685E8700003500682C0700003586 -+:10D4100000B02C070017A200682B0B00003A00E8B0 -+:10D4200044655857A1006DDE86F4406400E05E85D7 -+:10D4300055F7A1006DDE86F440640202DEBB0000F9 -+:10D440004800682ABB00004800E8446556D7A100A0 -+:10D45000E02ABB0157A2006EDE86F440420182E062 -+:10D4600002F5D7AE01BC6003000AAE03BFDE02F0D6 -+:10D47000004800E82ABAF437A100902ABB0037A27E -+:10D48000006E2ABEF4404600B02ABF0017A2006911 -+:10D49000DE86F4404803BFDE02F000640283DEB79C -+:10D4A00000005C028881AB00005A02035EB70000F6 -+:10D4B00073020480C700004D02005EFF00005A02A4 -+:10D4C0008080BF00005A0204DEB700005100682BC4 -+:10D4D0001708607303BFDE02F0005A028400C70021 -+:10D4E0000053028600C700005500682B0B00005A4D -+:10D4F00002812C4700005A00E844655737A1006DAF -+:10D50000DE8558005A006CC46557607300B04467EC -+:10D51000000ABB02845EB700007300025E02F011D5 -+:10D520004903BFDE02F0007301BC63FF1FF7A100D7 -+:10D53000684586F4205A0203C57300006402845EC5 -+:10D54000B7000064020100C7000073006B44655718 -+:10D5500080730020E3FE1460730282DEBB00007360 -+:10D5600002022C470000670282DEBB00006703BF97 -+:10D57000DE02F0005A028881AB0000730282DEB343 -+:10D58000000073028080BF0000730284DEAF0000E1 -+:10D590007302825EBB00007303A0DE02F0006F0224 -+:10D5A00000420300006F00025E02F00B1601836070 -+:10D5B00002F5B7AD0184E006F577AB01BC6003006E -+:10D5C0000AC300B04467000AC4018060020D906C79 -+:10D5D00003595E02F0007503D85E02F0007603D8AE -+:10D5E000DE02F0007701BC618300112900B0007BEE -+:10D5F00000112B01BC630300112303125E02F00A29 -+:10D600008F03975E02F00B2703D05E02F002F40353 -+:10D61000D0DE02F0051003D5DE02F00A4C03915E65 -+:10D6200002F005760396DE02F00A470288C1730015 -+:10D63000009E03C45E02F006E703C75E02F0071611 -+:10D6400003DCDE02F011CF03AA5E02F00759038665 -+:10D65000DE02F00A870287C037000A8703835E0272 -+:10D66000F008AB0391DE02F005F803C2DE02F00A17 -+:10D67000EC00025E02F00F9500025E02F0117A03E8 -+:10D68000D4DE02F0068103A3DE02F0000200025E97 -+:10D6900002F00C6300025E02F00EC403A25E02F010 -+:10D6A000009B03565E02F000980186600609104850 -+:10D6B000031F5E02F00098006A5E2300009700B02E -+:10D6C000002700178800E85E2300378803A65E0263 -+:10D6D000F0010500025E02F00F5D0028600E08E117 -+:10D6E0002803C4DE02F00B5E0020C20300213003D9 -+:10D6F000BFDE02F0017D03815E02F000A00300DEC8 -+:10D7000002F000820188E0020B905C03BFDE02F0B1 -+:10D7100002F1028740630000A20282C1070000A359 -+:10D7200001866006F43018028640630000A500B050 -+:10D730005E870017A10002DE02F00000028740634E -+:10D740000000A800B05E8B0010190186E006F430DE -+:10D75000180281DEAF0000AD0286C0630000AC009D -+:10D76000B05E870017A10002DE02F0000001BC607D -+:10D77000030280060280DE070000B901DA6002F0D1 -+:10D78000178002085E070000C901BC60031E17A1D4 -+:10D7900000E05E02F4306501BC60031C17A100E0EC -+:10D7A0005E02F4306401BC600300281803BFDE028F -+:10D7B000F000CF01105E030017A100885E870037DC -+:10D7C000A200E05E86F457A100E0015AF430630243 -+:10D7D0008600C30000C200B0560B00106200B054B7 -+:10D7E0000300106201BC600300281803BFDE02F0D2 -+:10D7F00000D100B0418F0010620109DE030017A1C3 -+:10D8000000885E870057A100E05E850597A100E0D3 -+:10D810005E8703C00601BC600300481803BFDE0238 -+:10D82000F000D101BC60070217A100E05E02F430F5 -+:10D830006501BC60070017A100E05E02F4306401DE -+:10D84000BC600318000601BC600300081800B05A51 -+:10D850000300106200B0580300106301050143008B -+:10D8600017A10088001AF420060002DE02F0000072 -+:10D8700001BC600306379201BC63FF1FF0C301BC0B -+:10D8800060031890E301BC63FF1FF0C501BC63FF98 -+:10D890001FF0C601BC63FF1FF0C700B02C5B001077 -+:10D8A000E500B02C5F0010E600B02C630010E7022A -+:10D8B00080AC470000E701BC600300101000B040DE -+:10D8C0004300180000B040470010E501BC600300B1 -+:10D8D000301000B0404300180000B040470010E690 -+:10D8E00001BC600300501000B0404300180000B0BD -+:10D8F00040470010E701BC63FF1FF0C40002DE02D6 -+:10D90000F0000000E840330097A100B0400B001782 -+:10D91000A3006D5E86F460EE00905E8F0037A30377 -+:10D92000BFDE02F000EF00905E870037A301BC600D -+:10D930001F1417A100E05E8EF437A301F041970099 -+:10D9400017A1006DDE86F461030287C1970000F71E -+:10D9500001385A030017A1013C5A030017A203BF64 -+:10D96000DE02F000F9013C5A030017A101385A0702 -+:10D970000017A200685E86F480FE00D85E8B003738 -+:10D98000A200E14196F4506500E1C19700306503C3 -+:10D99000BFDE02F000F100D85E8B0037A200E1414B -+:10D9A00096F457A100E1DE870037A101F05E870001 -+:10D9B00017A1006EDE86F4610401BC63FF1FF7A4AB -+:10D9C0000002DE02F000000020E38E090002031EC8 -+:10D9D000DE02F0010B039F5E02F0010B01BC60430D -+:10D9E0000117A100A84122F4304803BFDE02F00075 -+:10D9F0000200689B6F0000990208411F00010801A6 -+:10DA0000816005620B1000025E02F00B1600B00090 -+:10DA1000AB00108600B0016300108A00025E02F0C5 -+:10DA20000D9601BC600304179200B0003B00111D6D -+:10DA30000190600609104803A1DE02F00122018175 -+:10DA4000E00609104801BC600300904201BC60037D -+:10DA500000112D039EDE02F0012501846002F29781 -+:10DA60009400B0451700178F00B05E1700179002A2 -+:10DA700000441F00012001856002091048018160F7 -+:10DA80000700104701F0DE0F0037A100A044B6F4F4 -+:10DA90003145039EDE02F0012501BC613712B080E2 -+:10DAA00003BFDE02F0000200A044B42A314501BCED -+:10DAB000612712708003BFDE02F000020020E082C6 -+:10DAC000090002010CDE530017A101885E870010D7 -+:10DAD0004701BC60030050420108411F0017A1012B -+:10DAE0008CDE86F2979403BFDE02F000020002DEB5 -+:10DAF00002F000000020E07E09000200025E02F059 -+:10DB00000F670283C21F000002020280F300013A85 -+:10DB100000B044670017A1017C5E862357A30283EF -+:10DB20005EFF00013900E000FAF46830018360060E -+:10DB3000F7F7BF006BDE8D06013E0206D003000141 -+:10DB40004200E950862337A100E8D08A2357A2007B -+:10DB500069DE8B00014200025E02F00B160191604B -+:10DB60001684F42700E020C300883003BFDE02F0F3 -+:10DB700002CC00025E02F002CF020400BF00014AA4 -+:10DB800003945E02F000020020C28F02000200A097 -+:10DB9000428F01F78000685E002DC00200025E0225 -+:10DBA000F00B1603BFDE02F000040201C28F00007A -+:10DBB00002011400630017A100685E870060020084 -+:10DBC000025E02F00B160194600F00001800025E66 -+:10DBD00002F0015103BFDE02F000040114006300F3 -+:10DBE00017A100B05E870010A501BC601311106082 -+:10DBF00000685E8700015800E0418306D06000E8BD -+:10DC00005E870037A103BFDE02F00154028050C3DB -+:10DC1000000162018760040310A000B000630010DF -+:10DC2000B400B042D3001800008841830030B60130 -+:10DC3000BC60030B10B500B0006300B0B40317DE86 -+:10DC400002F0015F0397DE02F0016001806006864A -+:10DC500014300002DE02F000000020E01280417C5F -+:10DC6000018760040310A000B000630010B401BC81 -+:10DC700060030E10B500B0006300F0B401BC605743 -+:10DC80000490B600B000630010B401BC600302D081 -+:10DC9000B50207500B00017901BC600303D0B50148 -+:10DCA0008E6002F297940204500B0001720204D0BD -+:10DCB0000B00017201866006F2979400E042D700E3 -+:10DCC000D0B500A0500B1117A10068DE87110178B4 -+:10DCD0000186E006F2979400E042D70050B50207B3 -+:10DCE000D00B00017800E042D70090B500B042D7D9 -+:10DCF0000011E100B0006300B0B40317DE02F001D0 -+:10DD00007A0397DE02F0017B0002DE02F0000000E1 -+:10DD10006820DF000180006CC46506E00401BC607F -+:10DD200003000837006820D7000183006CC4650633 -+:10DD3000C00401BC60030008350020E0BE090002F9 -+:10DD400003905E02F0000403A25E02F001BE020234 -+:10DD500000BF0001880203C5730001B100682F6B8A -+:10DD600000018C00E844657B57A1006D5E857B2136 -+:10DD7000B101BC6003000BDA00682D9B0001B10209 -+:10DD800082C1070001B1028042030001B10285C5D2 -+:10DD9000230001B1028640370001B10181E006F5A0 -+:10DDA00077AB00B02D9F0017A101BC602F1077A2A8 -+:10DDB00001BC60030017A300025E02F0131200B062 -+:10DDC0002DA30017A101BC602F1777A201BC60032F -+:10DDD0000017A300025E02F0132001BC60131A17A3 -+:10DDE000A100025E02F000A200B040670417A2008A -+:10DDF000025E02F000A800E0446700D7A1006CC4F6 -+:10DE000066F4219F01BC60130ED7A100025E02F0F0 -+:10DE100000A200A040673FF7A201BC601314D7A185 -+:10DE200001BC62030017A300B05E8AF477A200026F -+:10DE30005E02F000A800B02D9F0017A101BC602F6A -+:10DE40000D37A201BC60030017A300025E02F013AD -+:10DE50001200B02DA30017A101BC602F13B7A201BF -+:10DE6000BC60030017A300025E02F013200181E0F2 -+:10DE700002F577AB01BC6003000B6600025E02F0A6 -+:10DE80000E74020200BF0001BD0284DEAF0001B8C3 -+:10DE900002035EB70001BD00025E02F010FB020348 -+:10DEA0005EB70001BD03BFDE02F0000202035EB7F1 -+:10DEB0000001BB020480C70001BD02805EFF0001BB -+:10DEC000BD00025E02F010BC03BFDE02F0000200E3 -+:10DED000025E02F00F670200421F0001D600684296 -+:10DEE000F30001C1006D42F30041D601140063004C -+:10DEF00017A100B05E870017A203A25E02F001CA5C -+:10DF00000183E0020D906C03145E02F001D8006EF4 -+:10DF1000C4568061D8028145230001D8006E5E8717 -+:10DF20000061D601BC60030077A200886006F45748 -+:10DF3000A300885E8B01001800E85E8B0037A2000A -+:10DF400020C28EF461D0006ADE86F441CA03BFDECF -+:10DF500002F001D6020400BF00020200900063013B -+:10DF60000165008085970217A100E064820DA1661B -+:10DF700000025E02F00F1D03BFDE02F0020201820A -+:10DF8000600209104803BFDE02F0000201BC60031A -+:10DF900000111500B0017F0017A6031F5E02F001FB -+:10DFA000E7020300C30001DD0020C28F0201E1038C -+:10DFB000255E02F001E70020C28F0201E1006881C6 -+:10DFC00053FFE00403BFDE02F001E301946013009D -+:10DFD000001803BFDE02F00202039EDE02F001E63B -+:10DFE0000068DE980BC1E60201411F000CB40185F8 -+:10DFF000600209104800685E980BC1EB00695E9FE3 -+:10E000000062070298428F0001EB03BFDE02F002BC -+:10E01000070201411F000CB4020400BF0001F2021C -+:10E0200018428F000CB400025E02F00EFF00025E88 -+:10E0300002F00F1D0194058700001803BFDE02F0F7 -+:10E040000202020013BB0001FB0200156B0001FE7F -+:10E0500000B013470017A10068DE84A7A1FB00B041 -+:10E06000134B0017A10068DE84A7C1FB00B0134F5B -+:10E070000017A10068DE84A7E1FB029E1397000150 -+:10E08000FE0201C28F0002000194600F000018031D -+:10E09000BFDE02F002020201C28F000200018060B6 -+:10E0A000060D906C0200C28F000CB4019460070052 -+:10E0B000001800025E02F00151020400BF000237A6 -+:10E0C000028500630002370183E0060D906C03BFF8 -+:10E0D000DE02F0023701BC60031810600129500B0A -+:10E0E00000179200B0017B001065006800EB000291 -+:10E0F0001000885A130117A100E84466F437A10004 -+:10E100006EDE8407421000E0029B0020A603BFDE03 -+:10E1100002F0067A019060120910480194601F0015 -+:10E12000001801085A0F00178101885E0681540A01 -+:10E1300001345A0F00178000025E02F000AF00B0F9 -+:10E14000017B00106500B056230017A100E05E8639 -+:10E15000A097A100E85E8400F40300E85E8400F468 -+:10E160001600B05A0300141300B05A07001414002C -+:10E17000B05A0B0014150068DE0700422800E800C2 -+:10E18000970057A101BC5E86F0141B017C5E8700DE -+:10E19000F41C00B0206300178100025E02F00D9AAB -+:10E1A00000B0017B00106501085A0F00178100B014 -+:10E1B0005E8700141E03BFDE02F0022B00B056176C -+:10E1C00000141B00B0561B00141C00B054130014A4 -+:10E1D0001E00B05013001086006D00A700823101B0 -+:10E1E00090016300108A00B0418F00106200025E4F -+:10E1F00002F0119C00B0422B00140601BC60031811 -+:10E2000017A1006DC18C20023401BC60030297A1EC -+:10E2100000E05E840377A100E05E86B0111D03BFBD -+:10E22000DE02F002AB020300C7000247020CD0037B -+:10E23000000247011400630017A102850063000279 -+:10E24000470080DE8701F7A201BC601B0257A200D5 -+:10E25000E05E8A0DB06500B041970014320080DEA8 -+:10E260008700B7A201BC60171FD7A200E05E8A0D2D -+:10E27000B06400B041930014330068D81300025218 -+:10E2800002005A1B0002490180600684F42703BF84 -+:10E29000DE02F005A20201D00300024900B0509B4B -+:10E2A00000142F0281D0C70002C900025E02F002F2 -+:10E2B000CF010BD0030017A1013C502B0017A20186 -+:10E2C0008C5E86F457A1014801430017A200685EE6 -+:10E2D00086F442520191601284F42703BFDE02F0FB -+:10E2E00002CC00025E02F0016300B0501300108601 -+:10E2F00000B0501700108A00682FC300025D029121 -+:10E30000D01700025B0291D01B00025B0291D01F6C -+:10E3100000025B0291D02300025B03BFDE02F00229 -+:10E320005D0191600284F42703BFDE02F002CC039A -+:10E33000A25E02F0028A020CD003000279020300FE -+:10E34000C700027800B050CB00106500025E02F0FA -+:10E350001235020350C700026601BC60230097A17A -+:10E3600000A85002F4340003BFDE02F0027D020474 -+:10E3700081AB000268006D4246C0800400B05A13B1 -+:10E3800000178000025E02F000B900B0540F0014C4 -+:10E390001E00B05A070017A100B05A1300178001E1 -+:10E3A000875A16F0178000B0418F00106500025E9A -+:10E3B00002F011A500E05E86A0740302875E0300F0 -+:10E3C00002770109DE030017A300E05E8B0077A24D -+:10E3D00000E05E8AF477A200885E8B0037A100E03F -+:10E3E0005E86F4508903BFDE02F0027D006D424A72 -+:10E3F000848004010650070017A1028CD00300029C -+:10E400007C00685E8700027D0182DE8686343101F1 -+:10E410008260028634310020D00304028300B050B1 -+:10E420004F0011F200B050530011F300B0505700EC -+:10E4300011F401BC60030091F003945E02F0028AC3 -+:10E44000020650030002860287DEAF00028A0281C4 -+:10E4500050030004F10202D0C70002890208502BC9 -+:10E4600000028A0285D003000508019060128634FC -+:10E470003103A25E02F0029700B0500F00111602A5 -+:10E4800002D0C700028F00B0505B0011160282D08C -+:10E4900003000297028147C30002900280504F00A0 -+:10E4A0000295002047C73F82970020C7DB00C2CB00 -+:10E4B00003BFDE02F0029703A55E02F0029702801E -+:10E4C000C7DF0002CB028850C70002B10129500B00 -+:10E4D000001792020300C70002A4020CD00300023E -+:10E4E000A4028350C70002A400B050CB0010650105 -+:10E4F000385A1300178001825A17005781010E5AAB -+:10E50000130017A1018E5E86F037810202D0C7008A -+:10E5100002B100B0501B00108A03BFDE02F002B14E -+:10E520000282D0C70002AB013850270017800108D3 -+:10E530005013001781010250130017A101825E865B -+:10E54000F0378100B0507F00108903BFDE02F00277 -+:10E55000B10138506F0017800108502B001781015E -+:10E5600006D0070017A101825E86F0378100B05007 -+:10E570001B00108A00B0508300108900025E02F078 -+:10E5800000AF00025E02F00D8D0102421B001781F8 -+:10E5900001825E0503178100025E02F00D9A00E021 -+:10E5A0005E840117A101D9DE8700108301BC6137A9 -+:10E5B00003B79100685E4B0282DF020400BF0002D5 -+:10E5C000BD028750030002BD03945E02F002BE0349 -+:10E5D000225E02F002C001BC610300308003BFDE96 -+:10E5E00002F0000201BC613303B791032BDE02F09D -+:10E5F00002C6009000630097A100E06482F43065D9 -+:10E60000006E5A130022C60188E006F237910068B6 -+:10E61000DE4B0482C801BC61BB03B79103BFDE02BD -+:10E62000F002DF0191600E84F42703BFDE02F002E6 -+:10E63000CC0191600684F42701BC60030010B40192 -+:10E6400081E00686343103BFDE02F005A2011C50D2 -+:10E650008F0017A100E0015EF43065010C5A4700FD -+:10E6600017A10080DE870197A200E0015E0DB06572 -+:10E6700002805A7F0002DE02815A7F0002DA020322 -+:10E68000DA7F0002DE00685A870002DE008860063A -+:10E69000F437A1002019FAF422DE00025E02F00B2A -+:10E6A000160191601E84F42700015E02F000000351 -+:10E6B000BFDE02F002CC0002DE02F0000003C4DE86 -+:10E6C00002F00B5E020650030002E70207DEAF0015 -+:10E6D00002E701BC6103003791020750030002E525 -+:10E6E00001BC620300F79100E0010B00204203BF70 -+:10E6F000DE02F002E801BC600300204200B05E4789 -+:10E70000001080020400BF0002F000B0058B001072 -+:10E7100064006E45170000020068DE4B0282EF00C5 -+:10E72000A044B42A314503BFDE02F0000200025EBD -+:10E7300002F00DA70068C51700000203D05E02F0CA -+:10E7400002F400025E02F00DA703BFDE02F0000239 -+:10E7500001836002F7F7BF01BC600300900400A8CA -+:10E76000412330104801BC620F0011E001816002BA -+:10E77000F5D7AE020200BF0003050068DE4B0202BF -+:10E78000FC00025E02F0130C0068DE4B062305025B -+:10E79000045EB30003050200456F00030500E84472 -+:10E7A000655737A100E82AB6F437A100695E8708EB -+:10E7B00023050183E0022B915C020701AB000305F6 -+:10E7C0000180E00209D04E0187E002F577AB0068D6 -+:10E7D000810B00230800B044670000430182E0067B -+:10E7E000091048018160020D906C01826006289139 -+:10E7F000440188E0020B905C00025E02F00F95017C -+:10E8000085E002F7F7BF0288421B0003100185E094 -+:10E8100006F7F7BF035B5E02F0031201BC60130052 -+:10E82000104301BC600300108501BC60030010B8F8 -+:10E83000008850770090B90208502B000319013866 -+:10E8400050730017A1017C506EF437A100885E87D9 -+:10E850000090B9020047A300031D01BC6003001132 -+:10E86000EA009042E70091EB00B047A300D1E80234 -+:10E870000047B300031F01B0E08E3D91EC01D2E0F0 -+:10E880000210908403A95E02F0041601BC6003002C -+:10E89000108400E001C30020700320DE02F0037347 -+:10E8A00001816006F5B7AD0068DE4B04A3370203B3 -+:10E8B000DEBB00032900E02C9300106503BFDE02DD -+:10E8C000F0032A01BC602301D06500A05E7FFE102A -+:10E8D000EC00B05A030010ED00B05A070010EE0033 -+:10E8E000B05A0B0010EF00B05A0F0010F001BC63DB -+:10E8F000FF1EF08401BC600300308501BC60030092 -+:10E9000010B401BC600301D0A601BC60030450B583 -+:10E9100001BC602304D0B400E002AF0020AB03BF11 -+:10E92000DE02F003BB0068DE4B05233D01BC600343 -+:10E930000010B401BC60071350A601BC600302D0F4 -+:10E94000B501BC602304D0B403BFDE02F00347006E -+:10E9500068DE4B0243540285C38F00034000E05E33 -+:10E960002700378901DA5E270010EE01BC63FF1F24 -+:10E97000F0CE01BC60030010B401BC600300D0A65F -+:10E9800001BC600303D0B501BC602304D0B400E037 -+:10E9900001D300207401BC61FF1FF08401BC60033F -+:10E9A000001085018460070011E00282DEB30004DC -+:10E9B000D802045EB30004D80183E00609104800C1 -+:10E9C000B0412300180001BC600306B78E0181E04E -+:10E9D00006F5D7AE00B054130017A100E05E840125 -+:10E9E00017A100885E8700708303BFDE02F004D8A1 -+:10E9F00001BC60031FF0840103DE530017A200680E -+:10EA0000121B00035900B0121B0017A2009019FA44 -+:10EA1000F457A202005EFF00035B01BC60030037F5 -+:10EA2000A200682B6F00035D01BC60030037A201E8 -+:10EA3000865E8A1C70E3006AC39300036700E843A4 -+:10EA40009000D0E40202421B0003650090001B000E -+:10EA500037A10020421B00436400B020B30017A17F -+:10EA600000E04392F430E40069C39300036701BC03 -+:10EA700060030010E400682B6F00036900E043911D -+:10EA80005C30E401BC60030010B401BC6003001002 -+:10EA9000A601BC60030210B501BC602304D0B40021 -+:10EAA000685E4B06A37100E001CB00207201BC60E0 -+:10EAB0000300083803BFDE02F003BB00E001CF0013 -+:10EAC000207303BFDE02F003BB03205E02F003C22B -+:10EAD0000181E00209104800E001D7002075031E03 -+:10EAE000DE02F003A201BC60030017A2006A5E23ED -+:10EAF00000037B0102428F0017A201855E8A091084 -+:10EB0000480180E0061030810284DE530003820059 -+:10EB1000B000770017A100E05E840437A100885E92 -+:10EB2000870057A100E05E870D57A103BFDE02F00A -+:10EB3000038301BC60030D57A1006800270003A2F6 -+:10EB400000E05E8401F7A101BC60230150650088EC -+:10EB500041970030B601BC60030010B400905E879E -+:10EB60000050A601BC60030110B501BC602300B0D9 -+:10EB7000B40317DE02F0038B0397DE02F0038C0070 -+:10EB800020DE870043950020DE8700239201B85ED7 -+:10EB900022D0168001805E8AD0368103BFDE02F06B -+:10EBA000039B01BC5E22D0168001845E8AD0368130 -+:10EBB00003BFDE02F0039B0020DE8700239901B82B -+:10EBC0005E22D0368101805E8AD0568203BFDE028B -+:10EBD000F0039B01BC5E22D0368101845E8AD05650 -+:10EBE0008201886002F430A800B05A030010B0001F -+:10EBF000B05A070010B1028042A300039E00E04219 -+:10EC0000A30090A800B05A0B0010B000B05A0F003B -+:10EC100010B10187600610908400E05E27003789FC -+:10EC200001DA5E270010EE01BC60030010B401BCE5 -+:10EC300060030350A600B000330010B50284DE5319 -+:10EC40000003AC00E0606803B0A600E04298043026 -+:10EC5000A600B000370010B501BC602304D0B40199 -+:10EC6000846006F2979401866002091048039EDED4 -+:10EC700002F003B60280441F0003B900B05E3F00FB -+:10EC8000114501BC600300178F00B05E430017857B -+:10EC900000B05E0F00179003BFDE02F003B900B0B2 -+:10ECA0005E0F0017850280441F0003B900A044B620 -+:10ECB000F0B14501BC600301104201836006F29788 -+:10ECC00094018460070011E003A05E02F004D60204 -+:10ECD000065EAF0004D80186E006F577AB01BC60A4 -+:10ECE0000300108000025E02F00B1C03BFDE02F086 -+:10ECF00005F803A15E02F0043D011400630017A1B2 -+:10ED00000068DE8700E3C70181600609104803BF81 -+:10ED1000DE02F0043D01816006F5D7AE011C508F84 -+:10ED20000017A100E0015EF43064010C58470004B4 -+:10ED3000870206508F0003D100B044670010F30033 -+:10ED4000B0446B0010F401BC63FF1FF0D301BC633F -+:10ED5000FF1FF0D400B042170310850020600E861C -+:10ED600023F5018760040310A000B000630010B415 -+:10ED700001BC60030B10B500B0006300F0B40203E7 -+:10ED800000C70003E3020CD0030003E3028050C776 -+:10ED90000003DB00B054130017A100E05E8680740E -+:10EDA0001A00B0506B0010E400B04213021084024D -+:10EDB00009502B0003E300B0421300308401D2E07D -+:10EDC0003AA030E0028050C70003E901D2E052A02F -+:10EDD00030E003BFDE02F003E90202D0C70003E91E -+:10EDE00000B0505F0010E000B050630010E100B0D0 -+:10EDF00050670010E200B0506B0010E400B0421306 -+:10EE000002F084020050C70003F000B0006300105D -+:10EE1000B401BC60030210B500B0006304D0B401BB -+:10EE20008460070011E001BC600300178E03BFDEA1 -+:10EE300002F004DA00E001C700207100B0006300B6 -+:10EE400010B401BC600302D0B500B0006304D0B4BC -+:10EE500003BFDE02F0046D01856006F7F7BF010312 -+:10EE600050030017A100B85E870037A101875E86B6 -+:10EE7000101080020CD00300043C020300C7000401 -+:10EE80000C00B050CB00106501BC6003001685007B -+:10EE9000E05A3300368C020350C700040100E05AE8 -+:10EEA0002700368903BFDE02F0043D01BC60030089 -+:10EEB00017B200B05A0B000B2501385A130017A1E6 -+:10EEC00001BC5A06F430E0013C5A130017A1017C42 -+:10EED0005A06F430E10181E0061090840185E007D4 -+:10EEE0000010E30185E0070010C30282D0C70004D0 -+:10EEF0001103BFDE02F004140202D0C700041600A2 -+:10EF0000B02A4B0017A101B8506EF430E000B050A9 -+:10EF1000730017A101B82A4EF430E10282421300B7 -+:10EF2000041400B0507B0010E400B04213021084BF -+:10EF30000185E0061C30E100B042130070840187B7 -+:10EF400060040310A0020300C700042B00B050CBE4 -+:10EF5000001065006D5ECAD1C41C0185E002187006 -+:10EF6000C300E05ECB00368E01BC601B09D065009B -+:10EF7000E04196F6506500B050970016800068DEBC -+:10EF8000CB00042301BC60230150B800682C97001B -+:10EF9000242903BFDE02F0043500B05ECB0010B5BB -+:10EFA00000B000630870B4028342D300042501BCA2 -+:10EFB00060030170B80068AC9700243501BC6003A1 -+:10EFC0000170B802BC506700043403BFDE02F004D5 -+:10EFD00033010CD0030017A103A95E02F004300135 -+:10EFE000BC60230150B800685E8700643303BFDE55 -+:10EFF00002F0043501BC60030170B800685E870050 -+:10F00000443501BC60030170B80181E0021710B8FB -+:10F0100001BC600300F0A501BC60030E10B500B098 -+:10F0200000630010B400B0006300F0B400B042D33D -+:10F03000001800018860080310B4018160060D907B -+:10F040006C03BFDE02F0046D0202D0C7000443006F -+:10F05000B0506F0010E000B050730010E100B050ED -+:10F06000770010E20282421300044200B0507B009D -+:10F0700010E400B0421302F08400E05E9F0037A766 -+:10F0800003A15E02F0044C01BC60030017A70187D6 -+:10F0900060040310A000B000630010B401BC600362 -+:10F0A0000E10B500B0006300F0B4018860080310D2 -+:10F0B000B403BFDE02F0046200B0017B0010650003 -+:10F0C000B05A030010E501BC63FF1FF0C500B05A41 -+:10F0D000070010E601BC63FF1FF0C600B05A0B002A -+:10F0E00010E701BC63FF1FF0C70068A0670004556C -+:10F0F00000E05E2700378900682067000459018519 -+:10F10000E0070010E30185E0070010C300B04213E0 -+:10F1100001108401DA5E270010EE0187600610906E -+:10F120008400B042131C108401BC60030010B400C2 -+:10F13000E0606803B0A600B000970010B501BC60A5 -+:10F140002304D0B4018460070011E003BFDE02F0A5 -+:10F1500004C601085E4B0017A100685E8700246D9D -+:10F160000202500300046C029E509F0004690201D9 -+:10F17000D00300046900E05E2700378901585E274C -+:10F1800000142D01DA50B70010EE018760061090D0 -+:10F190008403BFDE02F0046D01BC600300142D0186 -+:10F1A00004C1070017A10068121F00047200B0120A -+:10F1B0001F0017A1009019FAF437A103BFDE02F077 -+:10F1C000047403225E02F004740103DE530017A1ED -+:10F1D00000B05E870017A202005EFF00047701BC4A -+:10F1E00060030037A200682B6F00047901BC600344 -+:10F1F0000037A202885E4B00047C00685E4B0684E8 -+:10F200007C01BC60030017A20068921F00047E010D -+:10F2100083DE86F297940183DE8684F4270281C21E -+:10F220001300048401865E8B0010E30186600700F2 -+:10F2300010C30181E00610908403BFDE02F0048653 -+:10F2400001865E8A1C70E3018660061870C302B8EE -+:10F2500047A70004C202A047B70004C403A95E0286 -+:10F26000F0048E01085E4B0017A100685E87002441 -+:10F27000C3021E509F00048E0185E0061C70E3014E -+:10F2800085E0061870C3011400630017A10068DE52 -+:10F290008700849700B001530017A20068DE8BFF3F -+:10F2A000E493006842470024940068DE8A84C4978F -+:10F2B000018560020910480186E0021C70E30186A6 -+:10F2C000E0061870C3011050070017A600685E9B87 -+:10F2D0000004C301BC60030011E4013A50070017A9 -+:10F2E0008000885E0300778000E000AEF0106400CC -+:10F2F00068DE9B0044A80207D0030004A201BC60A2 -+:10F300002B12B7A200E05E000B37A300025E02F0F2 -+:10F310000DE801BC602307978100E0418301706321 -+:10F3200000E0418F00B06500025E02F00DBD01BC3F -+:10F33000602307506401BC60470017A200025E0210 -+:10F34000F00E1000685E9B0044C401A46046F47196 -+:10F35000E00068DE9B00C4B601BC611300B7A102E7 -+:10F360000600F30004AF01BC601300B7A10192C214 -+:10F370001AF437A203295E02F004B401BC60030052 -+:10F3800011EE009042E70091EF0192E00EF437A2F7 -+:10F3900000B05E8B0011EC03BFDE02F004C4006815 -+:10F3A0005E9B0064BB00685E9B00A4BB00B0502F56 -+:10F3B0000011E200B050330011E203BFDE02F0049E -+:10F3C000C4018760023D11E80068DE9B00A4BE0115 -+:10F3D0008760063D11E801BC60030011EA0090421D -+:10F3E000E70091EB0192C21B00B7A201B85E8A3D13 -+:10F3F00011E803BFDE02F004C4018460070011E0DD -+:10F4000001BC600300112D00B0448300142C03A341 -+:10F41000DE02F004D901BC600300178E00685E4B69 -+:10F4200005A4CA020050030004D30183E0060910BA -+:10F430004800B0412300180001BC600304B78E03EC -+:10F44000A95E02F004D800685E4B0424D801BC60B9 -+:10F450000306378E00685E4B05A4D801BC60030626 -+:10F46000B78E03BFDE02F004D801816006F577ABEA -+:10F4700000B05E0F00178500025E02F00DA701BC10 -+:10F48000600300178C01BC600300178D0323DE02AC -+:10F49000F004DA0187E0061070830185E002F5B719 -+:10F4A000AD03295E02F004EE020300C70004E90088 -+:10F4B000B050CB0010650282D0C70004E100E05AD2 -+:10F4C0002300368803BFDE02F004E200E05A270082 -+:10F4D000368900682C970024E900E05ECB0037B243 -+:10F4E000010A5ECB0017A100E050CAF4306500D0DD -+:10F4F0006006F657A200205A1AF444E903BFDE0260 -+:10F50000F004E300025E02F00F9503D5DE02F00A7C -+:10F510004C03D6DE02F00A640350DE02F004E90375 -+:10F52000BFDE02F0051002055EAF0004F00187E0C7 -+:10F530000626713303BFDE02F000020190600A86E6 -+:10F5400034310282D0C70004FA013C5027001780F2 -+:10F550000109502B001781010750070017A10182F4 -+:10F560005E86F0378100B0501F00108A00B0500F47 -+:10F5700000111603BFDE02F005000138505F0017CE -+:10F5800080010A502B0017810107D0070017A10145 -+:10F59000825E86F0378100B0502300108A00B050A0 -+:10F5A0005B001116020300C7000505020CD0030022 -+:10F5B000050502085E07000505013854070017809D -+:10F5C0000190422AA1308A028050C700050E01BC7A -+:10F5D000600305B79203BFDE02F0028F0190600660 -+:10F5E000863431020300C70004F2020CD003000489 -+:10F5F000F200B0001F0017A100E05E8680741A03BD -+:10F60000BFDE02F004F201BC600306379203BFDEE6 -+:10F6100002F0028F02055EFF00051F01856002F700 -+:10F62000F7BF032BDE02F0051F020000F3000516F2 -+:10F6300000E8002300514201BC600A2851420394B3 -+:10F640005E02F0051B00B0058B00106400685803D3 -+:10F6500000051B00B0446700111200B058030011F0 -+:10F66000150068451F00051F03A25E02F0051F017B -+:10F6700085E006F577AB00025E02F00ED70201C20C -+:10F68000E3000549020300C700052400682C970029 -+:10F690002534006E4246F6453403BFDE02F00526EF -+:10F6A000006E4247002534020300C70005310355B0 -+:10F6B000DE02F00526018060028614300138508396 -+:10F6C0000017A100B050CB001065006DDA32F42AAB -+:10F6D0004C00A84123141048011400630010650079 -+:10F6E000E041970ED06500E05A0300368001BC620D -+:10F6F0001F0011E003BFDE02F000040181E0068676 -+:10F7000034310191600E84F42703BFDE02F0054915 -+:10F71000013C50670017A101AC5E861750BA01BCCE -+:10F7200060030190B8020300C70005430068AC976E -+:10F7300000253E0181E0021710B803D5DE02F00A71 -+:10F740004C03D6DE02F00A640350DE02F0053A03F1 -+:10F75000BFDE02F0054900E82C97002B2500B05EC3 -+:10F76000CB0010B500B000630870B4028342D30030 -+:10F77000054103BFDE02F005440186E0040310A04A -+:10F7800000025E02F0015A03D5DE02F00A4C03D6F5 -+:10F79000DE02F00A640350DE02F0054503BFDE021C -+:10F7A000F0031001BC600300F0A50182E002091023 -+:10F7B0004801BC621F0011E001BC60030011EC01B4 -+:10F7C000BC600F0011E80285500B000550018260FB -+:10F7D0000209104803A0DE02F0055403D5DE02F052 -+:10F7E0000A4C03D6DE02F00A6403205E02F00556DE -+:10F7F0000188600209104803BFDE02F0000401BC6A -+:10F8000060030037A100025E02F00C5303A3DE0286 -+:10F81000F00004020050C700056201BC6003001044 -+:10F820008001826006091048018060028634310040 -+:10F8300068921F0005600104C1070017A10183DE63 -+:10F8400086F2979400E001CB00207203BFDE02F045 -+:10F85000017D00B0010B0017A1006DDE840805A238 -+:10F8600000E844640877A1006E5E840825A2018741 -+:10F87000E006F577AB020200BF000575028881AB98 -+:10F88000000575028400C70005750129500B00179B -+:10F89000A10068DE870205750282DEBB00057502E5 -+:10F8A00003C5730005740283DEB30005740282DEB3 -+:10F8B000BB00057100682B07000575006DDE2F0188 -+:10F8C000E5750182E006F7F7BF00E04465564AB1EE -+:10F8D00003BFDE02F0000403BFDE02F005A20282D5 -+:10F8E0005EAF00058501826006F577AB00B0446726 -+:10F8F00000082300B0014B0017A20208421B0005BC -+:10F900007C00B0016B0017A200685E8B00058200CE -+:10F9100090452B0097A10080DE86F457A1006E2051 -+:10F92000D60DA58200B041B700083500E020D623EF -+:10F9300028360185E002F5B7AD02055EAF0005850A -+:10F9400001BC610300113300E844650477A500B0F1 -+:10F950004467000BDA006D5E97010080020200BF71 -+:10F960000005940068DE4B06A58B0184E002F7F7E2 -+:10F97000BF0068DE4B04058E0282DEB300058E01F7 -+:10F98000BC6003000B1202045EB30005910068DE48 -+:10F990004B06259100025E02F0112300025E02F088 -+:10F9A0000F9603A3DE02F005940183E002F597AC05 -+:10F9B00001BC60131497A100025E02F000A201BC1A -+:10F9C00063830017A100A04066F437A20068DE8AB6 -+:10F9D000F425A001BC60130E77A100025E02F000C6 -+:10F9E000A200A040673FF7A200985E8B0037A200FC -+:10F9F000685E8B00059F0068DE8B0FE5A001BC6090 -+:10FA00002300104301826002F577AB03D15E02F060 -+:10FA10000002020050C30005F10325DE02F005A636 -+:10FA20000183600684F42703BFDE02F005D8020CD0 -+:10FA3000D0030005D6020300C70005C5011400630A -+:10FA40000017A1006DDE870085D601BC600300179A -+:10FA50008000B050CB00106500B050CF00106401A2 -+:10FA60008160060D906C0182600686343100B05AC8 -+:10FA7000230017A101BC600300168801BC5A2AF4B8 -+:10FA800037A101BC600300168A00B05E8700148FA6 -+:10FA900000B05A270017A101BC600300168901BC01 -+:10FAA0005A2EF437A101BC600300168B00B05E87AC -+:10FAB00000149000B05A1B00148D00B05A1F00149F -+:10FAC0008E01BC60030016040068DE030005C2025C -+:10FAD0000350C70005C10100509F00178001805EE0 -+:10FAE0000291B48D01BC5E0292149001BC600300CF -+:10FAF000378000025E02F0128100B05E0300148CB9 -+:10FB000003BFDE02F005D10068C2470005CA0181CB -+:10FB1000E0068634310191600E84F42701BC600355 -+:10FB200000143003BFDE02F0000200B0509F001747 -+:10FB3000A100025E02F0015900B05E8700142701A7 -+:10FB400086E0040310A000B04283001800010CD02E -+:10FB5000030017A10068DE870065C5010250C700D9 -+:10FB600017A101805E8684F427018AE00E84F427C1 -+:10FB700000B050BF00142603BFDE02F005D8018696 -+:10FB8000E0040310A00200509F0005D80286C107C0 -+:10FB90000005EC03295E02F005DD00B052330014CD -+:10FBA0002D00B052370017A1019E5E8684F4270015 -+:10FBB000B0509F0017A10180DE86F437A100B0503D -+:10FBC000BB00108F00B050B700108E00B0509B00EB -+:10FBD000108D01806006F4308C020250C70005EBE6 -+:10FBE00000B0524300108F00B0523F00108E00B0A2 -+:10FBF000523B00108D011A52370017A10198DE8781 -+:10FC00000437A101B85E8691B08C0182600286340F -+:10FC100031018160020D906C0325DE02F005EF01D9 -+:10FC20009C600284F42703BFDE02F005F3028550D6 -+:10FC30000B0005F100A850C70D143101BC60030092 -+:10FC4000143001816002F5D7AE0183600284F4278D -+:10FC50000185E00209104801BC600300142E03A2D4 -+:10FC60005E02F0017D03BFDE02F000040323DE022A -+:10FC7000F0065C03A35E02F0065C03A2DE02F0065F -+:10FC80005C01816006F577AB03AA5E02F0065C01B9 -+:10FC900083E0020910480351DE02F0061B02045EF5 -+:10FCA000B300060801846002F597AC0183E0020905 -+:10FCB000104800B02B5F0017A1006D2B0EF420023E -+:10FCC00000E0027B00209E01BC6003000AC300022A -+:10FCD0005E02F0112603BFDE02F000020203DEB373 -+:10FCE0000006180183E002F597AC00E02A9B002A89 -+:10FCF000A602015EBB00061800B02A9F0017A100F3 -+:10FD00006D2A9AF4261301BC6003000AA600E002E3 -+:10FD10007F00209F03A95E02F006160191601A84FD -+:10FD2000F42703BFDE02F002CC01BC63FF1FF7A182 -+:10FD300000025E02F00C5303295E02F006180191E6 -+:10FD4000601A84F42703BFDE02F0061800E0026B9D -+:10FD500000209A0180E006F577AB03BFDE02F006D3 -+:10FD6000200301DE02F0061E00685E4F06261E011B -+:10FD7000BC60030017A803A45E02F0062003C1DEE6 -+:10FD800002F0065F01846002091048020400BF000F -+:10FD9000062501BC6003001115011400630017A1C2 -+:10FDA00000E06602F4306500025E02F00DAC0182F4 -+:10FDB000600209104803A95E02F0064000685E3B3D -+:10FDC00004A63001F0DE1700378500A05E16F0971C -+:10FDD0008500685E3B0626300201500300062F02B4 -+:10FDE0008780BF00062F0185E0060910480280D0F9 -+:10FDF0000300064000B05E1B0017A300B0008B009C -+:10FE000017A4020400BF000636006E419730663624 -+:10FE100001185A030017A3011A5A030017A4006817 -+:10FE2000C18318063900E002930020A403BFDE025C -+:10FE3000F0063B006D5E2EF4863B0182E0068634C0 -+:10FE40003100E05E3300378C0068DE32F4663E003D -+:10FE5000B05E0F001785006DDE2EF4664C03BFDE2A -+:10FE600002F0065700B05E1F0017A300B0008F001D -+:10FE700017A4020400BF000646006E419730664694 -+:10FE8000011C5A030017A3011E5A030017A4006D9A -+:10FE90005E2EF486480182E00686343100E05E374B -+:10FEA00000378D0068DE36F4664B00B05E0F001739 -+:10FEB00085006D5E2EF466570185E0020910480347 -+:10FEC000D1DE02F0064E00025E02F00DA70068418E -+:10FED0008318067A020300C7000655020CD00300FF -+:10FEE0000655028350C70006550068DE4B05A6552F -+:10FEF00003BFDE02F011FF0181E00686343103BF4B -+:10FF0000DE02F005A200025E02F00DA70181600290 -+:10FF100009104803295E02F0065C028300C7001145 -+:10FF2000FF03BFDE02F005A203D1DE02F0065D038F -+:10FF3000A5DE02F005A203BFDE02F00004020650B7 -+:10FF40000300066500B001030017A1006D810AF4EB -+:10FF5000266500E844640877A1006E5E8408266583 -+:10FF60000187E006F577AB01085E4B0017A100683A -+:10FF70005E8700266800B05E0F00178500025E02F3 -+:10FF8000F00DA700685E3B06266E01BC60030017FB -+:10FF90008C0200D00300067301BC600300178D03C0 -+:10FFA000BFDE02F0067301BC600300178C02030081 -+:10FFB000C700017D020CD00300017D019C6002841A -+:10FFC000F42703BFDE02F0017D0068418318067943 -+:10FFD0000180600684F42703295E02F005A20182F5 -+:10FFE0006006863431028300C70011FF03BFDE02C2 -+:10FFF000F005A200E002970020A50181600209102F -+:020000023000CC -+:100000004801BC600300081900E0017B00A05E010C -+:10001000BC601310D7A1006D017AF4200401BC600C -+:100020001309405E03BFDE02F0000400025E02F02E -+:100030000B160338DE02F00004039EDE02F000041B -+:1000400000E8444C00F7A100E85E840117A1006AB3 -+:10005000DE8401068A00E85E8401118701BC60032A -+:1000600000118801A5E02230118001BC600300115D -+:100070001301BC600300111400B044670017A10015 -+:10008000B0446B0017A200B05E8700110400B05EA0 -+:100090008B00110503B8DE02F0068C03BFDE02F010 -+:1000A000000401BC600304B79201BC60030417A103 -+:1000B00001BC63FF1FF0CB01BC63FF1FF0CC01BC90 -+:1000C00063FF1FF0CD01BC63FF1FF0CE01BC63FFD7 -+:1000D0001FF0CF01BC63FF1FF0D000B0521700101B -+:1000E000E801BC63FF1FF0C800B0521B0010E9011B -+:1000F000BC63FF1FF0C900B0521F0010EA01BC63CF -+:10010000FF1FF0CA01BC60030010E4028600C300B8 -+:1001100006AD00B0540F0017A20069DE8A9086A5D4 -+:1001200000E85212F450E40068A0630006AD01BC80 -+:1001300060030010E400B054270010E000B0542F1A -+:100140000010E103BFDE02F006B603A4DE02F008F1 -+:10015000AB03A9DE02F008AB01BC600301D7A1022A -+:100160000600C30006AF0280DE5F0006B400B05494 -+:10017000070010E0006820630006B201D2DE86A00E -+:1001800030E000B0540B0010E103BFDE02F006B611 -+:1001900001BC5E869010E001BC601F0010E101BC54 -+:1001A00060030010E200B052230010E501BC63FFC1 -+:1001B0001FF0C500B052270010E601BC63FF1FF01E -+:1001C000C600B0522B0010E701BC63FF1FF0C70050 -+:1001D000B0004700108601082063001781013852E3 -+:1001E000030017800102C0270017A600025E02F07C -+:1001F0001198006820630046C400B05407001780BF -+:1002000000025E02F00D8D006820630026CD0068BC -+:10021000A0630006C8021A54070006CD006800A7B4 -+:100220000106CB0103C0270017A103BFDE02F006C1 -+:10023000CC0106C03B0017A101825E8610D0860368 -+:10024000A9DE02F008EB00685E4F0426DF01BC6304 -+:10025000FF1FF0C300685E4F05A6D501BC60031AFE -+:1002600090E301BC600306B79200685E4F0526DF8D -+:1002700003BFDE02F006D901BC6003063792029884 -+:1002800044070009C0028046070009C001BC6003A2 -+:100290001890E300B0206300178100025E02F00DA9 -+:1002A0009A00E85E8400D7A1006A5E869086DF002F -+:1002B000E85212F430E403BFDE02F006E201BC6053 -+:1002C000030010E40338DE02F006E20187E0061CBA -+:1002D00090E40190600A09104801BC610304379161 -+:1002E00000685E4F05A9C003835E02F008AB03BF40 -+:1002F000DE02F0000201866002F7F7BF0182E00231 -+:10030000F5B7AD0185E002F5B7AD02044163000623 -+:10031000F2018460020B105802055EAF0006EE0188 -+:1003200087E006267133020400BF0006F10185E074 -+:1003300002F577AB00025E02F00ED703BFDE02F0DB -+:1003400000020283C0370006FA006CC4656C26FB0D -+:1003500001BC601B1A77A100025E02F000A20180BE -+:10036000E0060337A200025E02F000A80180E0026E -+:10037000F457A200025E02F000A800E044656C4B56 -+:10038000610285C52300070A018460060B1058022C -+:1003900000DEFF0007010180E002F7F7BF00682BD5 -+:1003A0006F00070100E044655B4ADB0207AC0F0009 -+:1003B000070A0280456F00070A01BC63FF1FF7A10F -+:1003C0000068DE862C270A01BC60130217A1000218 -+:1003D0005E02F000A201882C0E0337A200025E022A -+:1003E000F000A801BC6003000B0302055EAF00072C -+:1003F0000C01BC6103001133020580BF000712012C -+:10040000BC60131157A100025E02F000A2019660C9 -+:100410000E03301900B040670017A200025E02F020 -+:1004200000A80283C03700000400E0021F002087FC -+:100430000182600628914403BFDE02F000040281BD -+:100440004013000002020042030007190184600209 -+:10045000F597AC01BC600300108003A3DE02F00737 -+:100460001C0190600209104800B0446700179E000C -+:10047000B0446B00179D00B0446F00179C00B0445F -+:100480007300179B0068DE7A23271C00E00223001C -+:1004900020880115403B00179700B001430017A1C9 -+:1004A00001C9DE8405280501BC6003107795019120 -+:1004B000E0020D906C0286403700072A00E002BB84 -+:1004C0000020AE03BFDE02F00A8A01BC6003001404 -+:1004D0008001BC600300148101B8600A049024010B -+:1004E000BC600304082B01BC600300482A01BC6007 -+:1004F0000300D02A01B3600700100401BC600300B0 -+:10050000080E01BC600300080F01BC600300081066 -+:1005100001BC60030008110183E002F5D7AE028739 -+:10052000C037000A8600025E02F0117A00025E0205 -+:10053000F00F9503435E02F00736006D403300CAAA -+:10054000F700685E5F00474E00685E5F00274B0063 -+:100550006800A700C740006800A701074000688046 -+:10056000A700A74100E0446690283701BC62C300A1 -+:1005700017A102805203000744019652030017A1FD -+:100580000080DE8690379A0203520300074900E09C -+:100590005E6A90379A0207D20300074900E85E6B53 -+:1005A00000379A029E5E6B000AF703BFDE02F00777 -+:1005B000530152D2030017A10185D206F4379A03E2 -+:1005C000BFDE02F00753013C52030017A101BC52E9 -+:1005D00006F4379A006E5E680BAAF700682FC30016 -+:1005E0000753028E5207000AF70204C03B00075D62 -+:1005F0000181E0060D906C02874037000A8A0002F4 -+:100600005E02F0117A00025E02F00F950287C0AF21 -+:100610000007550287C0AF000A86015840AF001797 -+:100620009A01BC603F1E17A1006DDE6AF42A8603A2 -+:100630005B5E02F0075F01BC601300104300B04135 -+:100640002328104801806002F297940184E0020997 -+:100650001048015840AF00102A006840AB002A86BD -+:1006600001BB5E5600900402035E5700076E020055 -+:1006700047A300076B01BC621E3C11E001BC600394 -+:100680000011EA00B05E6B0011EB0198601E3D1195 -+:10069000E8020047B300076E00B05E6B0011EF0187 -+:1006A000B0E0CE3D91EC03835E02F0077200025E83 -+:1006B00002F0117A00025E02F00F95006D403304E3 -+:1006C000C76E03AADE02F0078E01BC63FF1FE4863B -+:1006D00001BC601B19D06401BC600300B7A101BC60 -+:1006E00063FF1FE66D00E04186F4306501BC63FFE7 -+:1006F0001FF60000E05E870077A100025E02F00CAA -+:10070000AE0200C077000784012940770017A200DD -+:100710006D5E8B04C78200E85E8B04D60001BC606E -+:100720001B0FF06300E0418EC01063010C56030004 -+:1007300004860068DE8701678400B05E8B00066D6A -+:10074000006DDE8701C78700E0419300306403BF7E -+:10075000DE02F0077703B05E02F0078D01836002CE -+:100760000D906C00681B3BFFE78E01BC601B0FF017 -+:100770006500E04194D9D06502005A0300078E015C -+:100780008360060D906C0020402F08A79001BC608C -+:100790000300048601BC60030008020188E00F002A -+:1007A0000803006D40330208A50129520F0017937A -+:1007B0000109520F0017AA01966002F2979400E017 -+:1007C000418701F06501BC600F0017A10028DE869B -+:1007D00090679C01866006F2979400E04197007054 -+:1007E0006500E020AF00C82B01065E530017A20091 -+:1007F000A05E4F0477A10068DE870447AA0186E067 -+:1008000006F2979400B85E8B0037A200B05A03003E -+:1008100017A0020ADA030007A401876006F2979482 -+:100820000284C03B0007AA0203DA030007AA03AB55 -+:100830005E02F007A8020441070007AA01806005D4 -+:1008400000680301065E530017A20182DE8A009051 -+:100850000403AADE02F007DB03AB5E02F007C50269 -+:1008600087D2130007DB00B0521300118601A5E008 -+:100870000A301180018460020D906C01BC63FF1F7F -+:10088000F79900B01B430017A20068DEAB0027B742 -+:1008900000A05E4FFF77A10068DE870727C303BF74 -+:1008A000DE02F007B90284520F0007C30204D20F20 -+:1008B0000007BC03B15E02F007C200B01B3F001787 -+:1008C000A203BFDE02F007BD03B35E02F007C2025F -+:1008D0000052170007C300685E8BFFE7C300E0010A -+:1008E0005EF4506502015A470007C300B019B70013 -+:1008F0001799018460060D906C020052170007DB07 -+:1009000003315E02F007DB01866002301180018056 -+:10091000E001620B10020052170007C90202AB4F40 -+:100920000007D60068DE5F0007D600B02BB70017BF -+:10093000A100682ABB0007D600B02BB30017A200A5 -+:100940006DAABAF447D60068DEAB0047D2006D2B23 -+:10095000BAF427D100B02C6B000B190184E006F724 -+:10096000F7BF0068DE4F0287D600025E02F0130C6C -+:100970000206DEFF0007D600E02BE7002AF9006838 -+:10098000DE5F0007D90068DEAB0047D90180E005D3 -+:10099000620B1000682B6F0007DB0180E006F7F7A1 -+:1009A000BF0207520F000856028047A300085302F7 -+:1009B0008047B300085300E020AF00882B00E820F8 -+:1009C000AB00882A01BC60030011E401BC63FF1F77 -+:1009D000F7A501BC600303D1E102065E530007E501 -+:1009E00001BC60030491E10206DE530007E900E068 -+:1009F00047870051E10207D20F0007E900E047876F -+:100A00000091E1006D403302C8A500685E4F058784 -+:100A1000EC0068DEAB00485603AB5E02F007EF0265 -+:100A2000005217000856020580F30007F500681908 -+:100A3000B7FFE7F200B019B70017A500E05E970016 -+:100A400097A50068DE97FFE7F50280521700085669 -+:100A5000020700BF00085601BC601F1417A20090D7 -+:100A6000478700306500E04196F4506500E0478715 -+:100A700001082103835E02F007FD00025E02F0110F -+:100A80007A00025E02F00F95006D40310427F900F4 -+:100A90006D40310428A501BC600B1D57A10068DE24 -+:100AA00097FFE80D010F5A070017A5031EDE02F09D -+:100AB000080D0200521700080D032C5E02F00856C4 -+:100AC00000685E67FFE80D00E05E6700979900E050 -+:100AD0005E66F43064012A58030017990100DE971E -+:100AE0000017A500E05E66F4B79900E05E67003786 -+:100AF00099011558030017A603BFDE02F0081D0078 -+:100B0000E05E96F43064012A5803001799020580CC -+:100B1000F300081C0182E002F3379902005217002B -+:100B2000081C0116D8030017A6010F5A070017A4C6 -+:100B3000010CD8030017A10068DE92F4281800E029 -+:100B40005E6702179903BFDE02F00821010DD8038A -+:100B50000017A10068DE92F4285600E05E670417D3 -+:100B60009903BFDE02F00821011058030017A60008 -+:100B700068DE9B00C8210181DA030017A100B85E7E -+:100B800086C017A10281DE8700085600885E6700D4 -+:100B9000778000E000AEF0106401AADE6500480234 -+:100BA0000068DE9B00483B0207818700082E006D2D -+:100BB000DE030C082E0285520F00082E0298523BCD -+:100BC00000082E0181E00500680300E05E000B379D -+:100BD000A300E05E8F0097A300E041870077A200AA -+:100BE000025E02F00DE800E820AB01082A01BC60BB -+:100BF0002307978100885E970077A100E85E86F45E -+:100C0000B06301BC60070E17A100E0418EF43063B1 -+:100C100000B056170017A100B0561B0017A20068BD -+:100C2000DE86D048560068DE8AD0685600025E0232 -+:100C3000F00DBD01BC602307506401BC624F00177A -+:100C4000A200025E02F00E1000685E9B0048530195 -+:100C5000BC621EF471E00068DE9B00C84601BC6106 -+:100C60001300B7A1020600F300084201BC601300A4 -+:100C7000B7A101BC60030011EE00B05E6B0011EF84 -+:100C80000192E00EF431EC03BFDE02F0085300687D -+:100C90005E9B0068480068DE9B00A85301986006D0 -+:100CA0003D11E800E020AF00882B00E820AB008871 -+:100CB0002A01BC60030011EA0068DE5F00484E00B4 -+:100CC000B05E6B0011EB0192DE5E3D11E8018760C2 -+:100CD000023D11E80068DE9B00A852018760063DD6 -+:100CE00011E8019860163D11E80181E00500480215 -+:100CF00001AADE6500480203BFDE02F0085B01BC0A -+:100D0000620F0011E001BC60030011E40181E00109 -+:100D100000680301BC600F0011E801BC6003001112 -+:100D2000EC0200200F00086200E020AAF3482A002D -+:100D3000B020AF00102500E820AA04A82A006AA06D -+:100D4000AB01C86201B860060490240182E006F29B -+:100D500097940188600A00900401BC60031877959D -+:100D600003A0DE02F0086F00685E4F06A874013829 -+:100D7000520300178000B05E5F0017810203DEB7E8 -+:100D800000086E00685E0700086D01BC6003017713 -+:100D90008001BC600300378103BFDE02F0086E01F2 -+:100DA000BC600301578000025E02F000AF0068DE05 -+:100DB000AB00487400A05E4F0477A100685E870016 -+:100DC0004A3500685E87044A3503BFDE02F00BE94E -+:100DD0000386DE02F00A870287C037000A86000217 -+:100DE0005E02F0117A00025E02F00F9503035E02CC -+:100DF000F0087403A9DE02F0088000025E02F01120 -+:100E00007A00025E02F00F950207403700087A036D -+:100E100086DE02F00A870287C037000A8600025E7B -+:100E200002F00C60006E40300208AB0301DE02F0FD -+:100E300008AB0068DEAB000892032B5E02F0088668 -+:100E400000E0022B00208A03BFDE02F0088A028045 -+:100E5000521700088900E0024300209003BFDE0221 -+:100E6000F0088A00E0025700209500685E4F040BEE -+:100E70006900685E4F028B6900685E4F0209C70017 -+:100E8000685E4F048A2E00685E4F050BDA00685ECC -+:100E90004F060BDA00685E4F068BE303BFDE02F0FD -+:100EA0000BE90068DEAB0028A3032B5E02F0089676 -+:100EB00000E0022F00208B03BFDE02F0089A0280C0 -+:100EC000521700089900E0024700209103BFDE029C -+:100ED000F0089A00E0025B00209600685E4F06A9C9 -+:100EE0009B00685E4F042C0100685E4F04AC01005B -+:100EF000685E4F05AA3B00685E4F06299B00685E4E -+:100F00004F052BD800A05E4FFF77A100685E8707D2 -+:100F10002BF403BFDE02F009C000E00213002084BE -+:100F200003BFDE02F009C400E0020F00208301BC11 -+:100F300060030011EC01BC600F0011E80284C03BAB -+:100F40000008560184E00609104803BFDE02F008DD -+:100F5000560200C09300000203A35E02F008AF0334 -+:100F6000C35E02F008AE03BFDE02F00AF300025EC9 -+:100F700002F0117A00025E02F00F950207C0AF0086 -+:100F800008B3020740370008AF0107C0AF0017A140 -+:100F900000B85E870037A101825E860D906C00B0BC -+:100FA000447F000804018360020910480287C037AB -+:100FB000000A860386DE02F00A8700025E02F01154 -+:100FC0007A00025E02F00F9503435E02F008B80259 -+:100FD00087C037000A860301DE02F008D303305EC3 -+:100FE00002F008D301BC601B1F506500E04194DF94 -+:100FF0003065012D406B0017A200885E8B0137A27F -+:101000000138402B001680028840270008C7018461 -+:101010006006D0168000B05A02F456800205C02740 -+:101020000008CA0187E006D0168001BC601B0DD7FE -+:10103000A100025E02F000A200B04067001681012C -+:10104000BC601B0DF7A100025E02F000A200B040E0 -+:101050006700168200E01BE70066F900691BE701E4 -+:1010600088D301BC60030006F90280200F0008D578 -+:10107000006E40300209960381DE02F008DF00E0D6 -+:10108000021700208503A9DE02F008DB0184E006D8 -+:101090000910480180E0020910480184E002F7F7D6 -+:1010A000BF0386DE02F00A87018060050048020166 -+:1010B000806006F2979403BFDE02F009620183604C -+:1010C00002F7F7BF0386DE02F00A87032B5E02F009 -+:1010D000090503A9DE02F008E80068DEAB00490557 -+:1010E00000B0523B00179F00B0523B0017BE01BC3E -+:1010F000600300280E03BFDE02F0090502875E537D -+:1011000000091203A0DE02F008F403BFDE02F006BD -+:10111000920182E0060D906C0190600A091048006F -+:10112000B0523B00179F00B0523B0017BE019E5EBD -+:101130008300B0EB0106520F0017A100B85E8700D4 -+:1011400037A10182DE86F577AB01BC6103003080F8 -+:1011500000E8523AF3F7A2006BD23AF3E8F700E85E -+:101160005E7E91D7A200905E8B0097A101BC6023A8 -+:1011700001D064006B523AF3E90201185E87001750 -+:10118000A2010A5E870017A300886006F457A20038 -+:10119000E04192F4706400B05802F45600006BDE37 -+:1011A000FA91C90500B0523B0017BE03BFDE02F042 -+:1011B000090500025E02F011EA00B0203B00280E93 -+:1011C00000B0523B00179F0320DE02F00912020715 -+:1011D0005E530009090180E00209104803BFDE02E6 -+:1011E000F009120068DE5F00090F021A54070009B7 -+:1011F0000D0103C0270017A101825E8610D0860171 -+:1012000002C0270017A100E0422AF4308A0180E0E2 -+:101210000500480203A9DE02F0091200B05E470093 -+:10122000108001085E4F0017A100685E8700293614 -+:1012300003AB5E02F0093A0200521700092500686C -+:10124000DEAB00491800E0025300209402865E5392 -+:101250000009620284520F000AF70284D20F0009CB -+:101260001D03AC5E02F0092303BFDE02F0092E036A -+:101270002C5E02F0092E00685E4F0409230106D29D -+:101280000F0017A10080921B0197A200E0015E0DE4 -+:10129000B0640181DE86C3F61F00685E4F020962FA -+:1012A00003BFDE02F00952031EDE02F0092B0331F8 -+:1012B0005E02F0092B0068DEAB00492B0080921B18 -+:1012C0000197A200E0015E0DB0640181E002C3F667 -+:1012D0001F0068DEAB00493000E0023F00208F03B2 -+:1012E000BFDE02F0093300685EAB00493302805272 -+:1012F0002F0009620202410700093300685E4F04B3 -+:10130000096200685E4F0289620284410700096237 -+:1013100001806006F2979403BFDE02F00962032B9E -+:101320005E02F0096200685E4F05A95200685E4FD8 -+:1013300005295203BFDE02F009620068DEAB0049F6 -+:101340004201BC6003000ABD01826002F5D7AE0213 -+:10135000805EFF00094000682B6F00094200E044F6 -+:10136000655B4ADB00682B8BFFC94200E02B8B00DA -+:101370002AE202065E5300094500E002630020985D -+:1013800003BFDE02F009620323DE02F0094D0129EA -+:10139000500B0017A30068DE8F05294D0187E0027E -+:1013A0001070830184600209104800B05E87001746 -+:1013B000A1006EE00300294C03D1DE02F0094D00CC -+:1013C00068DEAB00494F00E0022700208900685E1C -+:1013D0004F00096200685E4F01096200685E4F05B8 -+:1013E0008962028047C70009940329DE02F0095888 -+:1013F0000102DEAF0017A10106520F0017A200384C -+:101400005E86F449620182DE8AF577AB00B0522332 -+:101410000011F200B052270011F300B0522B00115E -+:10142000F40106520F0017A100E05E870031F500BD -+:10143000B0005B0011F000B047C30018000134C7D2 -+:10144000C70017A1006EDE8402A96201BC60030818 -+:1014500010420283C1070009660301DE02F009653C -+:1014600003B55E02F0096602805E53000AF700B021 -+:1014700040330017A10108A00F0017A200685E8B7F -+:1014800000696E00E840310577A10281200F000954 -+:101490006E00B020AF0017A10280A00F00096E00FF -+:1014A000B05E630017A1006E5E8402099600B05E14 -+:1014B000870007FA018160010048020202C01300A0 -+:1014C000097400E05E840347FA0181600500480268 -+:1014D0000201200F00098F01035E530017A101874D -+:1014E000DE850048020386DE02F00A8700025E0203 -+:1014F000F0117A00025E02F00F9503855E02F0099A -+:1015000077018E60023D11E80107C7830017A10132 -+:10151000825E850048020201A00F0009810103C715 -+:10152000970017A101825E8500680300B0204B0080 -+:1015300017A1018E5E850068030207C0AF000C444E -+:1015400001BC60030011EC01BC600F0011E80184D4 -+:10155000600500680300B040270007FC00B0402B86 -+:101560000007FD00B0406B0007FE00B0406F0007B1 -+:10157000FF0184600500680300025E02F00C600158 -+:10158000BC63FF1FD7A800025E02F00DAC00025E34 -+:1015900002F00C4401A8600A0090040201200F0030 -+:1015A00011D500A8401300500403BFDE02F005F877 -+:1015B00000E002870020A103BFDE02F0099700E0EF -+:1015C000020B00208203A9DE02F00AF70184600604 -+:1015D0000910480184E00609104803BFDE02F00A42 -+:1015E000F7032B5E02F009B80068DE4F06A99F00E2 -+:1015F000E0023B00208E03BFDE02F009A000E00203 -+:101600003700208D0323DE02F009C00068DE4EF1B2 -+:10161000C9C00187E002107083018460020910488C -+:1016200000B05E870017A1006EE0030029A603D179 -+:10163000DE02F009A700685E4F0629B601BC600310 -+:10164000000AA603295E02F009AC0203DEB300091A -+:10165000AD0191601A84F4270183E002F597AC0292 -+:101660000200BF0009B50203456F0009B00185E023 -+:10167000062B715B02045EB30009B50187E002101E -+:1016800070830183E00209104800025E02F0112716 -+:1016900003BFDE02F009C00205500B0009C0018241 -+:1016A000600609104803BFDE02F009C0028700C3CC -+:1016B0000009BD0068DE4F06A9BD0068D21300090D -+:1016C000BD01BC600300118301BC600300118200F6 -+:1016D00068DE4F0629C000E0024F00209303BFDE02 -+:1016E00002F009C003AB5E02F009C2020441070028 -+:1016F00009C5028341070008AB03BFDE02F009C53C -+:10170000028441070008AB01806006F2979403BF92 -+:10171000DE02F008AB039F5E02F009CA039EDE0200 -+:10172000F00BE902035E53000BE902048143000958 -+:10173000CE010001630017A10102C0270017A2001B -+:1017400038DE86F449C403AB5E02F009D0020052D1 -+:10175000170009C40280522F0009D203335E02F041 -+:101760000BE902181B330009F201BC601F15F0657C -+:1017700001BC60031BB7A400025E02F000E900B0E8 -+:101780005E8F0017A60068DE931BA9EE0207C197C3 -+:101790000009DF01385A070017A1013C5A0700175A -+:1017A000A201BC5A0AF457A2013C5A0B0017A3012C -+:1017B000BC5A0EF477A303BFDE02F009E2013C5AE3 -+:1017C000030017A100B05A070017A200B05A0B007F -+:1017D00017A3006D5E870089E801BC61BF0A17A5E9 -+:1017E0000068DE8AF4A9E801BC60271357A50068E9 -+:1017F000DE8EF4A9E803BFDE02F00A2A00D85E8775 -+:101800000037A100E14196F4306500E1C197003056 -+:101810006501F041970017A200E05E8B0077A200FF -+:101820006D5E8AF4C9D500E840330097A5006E5E6E -+:1018300096004A2A00B01B2F0017A10068DE840A18 -+:101840000BE9023C523F000A03013C523F0017A142 -+:101850000068DE84048A2801BC600316106401BCA1 -+:10186000601F16106500685E870029FF00B05A03EC -+:101870000017A20068DE8AC00A2800E04197003005 -+:101880006500E0419300306400E85E870057A100E6 -+:101890006A5E870029F800685E87000A0401385AEA -+:1018A000030017A1013858030017A20068DE86F470 -+:1018B0004A2803BFDE02F00A040285C107000BE9D3 -+:1018C00001BC601F15F06501BC600305B7A40002F0 -+:1018D0005E02F000E9028000C3000A2801BC601328 -+:1018E00010D7A600E0017F00B7A5006D5E96F4CA90 -+:1018F0000C01BC60130957A500685E940BCA2C004C -+:10190000B0017B00106500B052270017A200B05252 -+:101910002B0017A3006841940BEA170068DE8ED0F5 -+:101920004A1300685E8AD02A2800E0419700B0651B -+:10193000006D4196F4CA1001BC601309506503BFE5 -+:10194000DE02F00A1000E0028B0020A200B0017F4E -+:1019500000106500B0522300168000B05227001618 -+:101960008100B0522B0016820080921B0197A200CA -+:10197000E0015E0DB0640203587F000A2101BC60E3 -+:101980002F0037A103BFDE02F00A2201BC5202F28F -+:10199000F7A101A95E02F436830090446701168422 -+:1019A000020281AB000A260068DE9305AA270184A3 -+:1019B0006006D0968400B05E9700005F020781AB9E -+:1019C000000A2A01806006F2979403AB5E02F006DB -+:1019D000AA03BFDE02F008AB00E0028F0020A303E1 -+:1019E000BFDE02F009C4039EDE02F00BE903AB5E2A -+:1019F00002F00A31020052170009C403335E02F0FC -+:101A00000BE901846006F2979403AB5E02F006AA2C -+:101A100003BFDE02F008AB03835E02F00A38000267 -+:101A20005E02F0117A006D4033038A35006D403359 -+:101A30000389C4032B5E02F00BED03BFDE02F00648 -+:101A4000AA032B5E02F00A3E00E0023300208C0362 -+:101A5000BFDE02F006AC00E0024B0020920103C0A2 -+:101A60002700178101825E0503178100025E02F0E4 -+:101A70000D9A008800230037A200E05E8800F7A2DC -+:101A800000E05E86F451890186E00630118003BFD4 -+:101A9000DE02F009C003A2DE02F0008103A3DE0231 -+:101AA000F00A6400E001FF00207F01BC6003001722 -+:101AB000A303BFDE02F00A66018760040310A001E1 -+:101AC000BC60030051E400B0479300180001BC6003 -+:101AD0000302900401BC620F0011E001BC600F0121 -+:101AE00031E800B047A300180001BC600F0011E806 -+:101AF00001BC60030131EC00B047B300180001BC29 -+:101B000060030011EC018460060910480020601E8B -+:101B1000090A5B00E001FB00207E03BFDE02F00A41 -+:101B20006C01BC60030ED7A1011400630017A20072 -+:101B3000E05E86F4506500E05A0300368002030040 -+:101B4000C7000A6103A95E02F00A660291509F0075 -+:101B50000A650191601A84F42703BFDE02F00A656A -+:101B600000E001FF00207F01BC60030037A30323D6 -+:101B7000DE02F00A6C0183E0020910480184600271 -+:101B8000F597AC01BC600300178E0187E00210706E -+:101B9000830182600209104803D0DE02F00A6D035F -+:101BA000D05E02F00A6E0182E00209104803D5DE21 -+:101BB00002F00A7001BC60030010B401BC600300B5 -+:101BC000F7A1006800A7000A740185421AF437A142 -+:101BD00000025E02F000A200B040670017A501BC41 -+:101BE00063FF1FF7A200025E02F000A800886007F2 -+:101BF0000157A400B85E86F497A100025E02F000CF -+:101C0000A80283C21F000A7B00E044670117A102FB -+:101C1000044523000A80006B4466F42A7D00025EBE -+:101C200002F0116100685E8F0000020020E01E09D2 -+:101C30000A8400B05E9700142E03BFDE02F002CCCF -+:101C400000A8412300F04803BFDE02F00002018338 -+:101C5000600209104801BC6007001042006E40306D -+:101C6000020A8A00E0027700209D00025E02F01264 -+:101C7000A703A35E02F008AB03C6DE02F00A8D01E3 -+:101C800084E00609104803BFDE02F00AF70068206E -+:101C9000E3000A9500E844650717A101BC609F02B4 -+:101CA00017A2006D5E86F44A9501BC6003000838F7 -+:101CB00000025E02F00B160020E10209007C002009 -+:101CC000628A090A9900025E02F0117A03BFDE02FD -+:101CD000F0007C0284452300007C03915E02F0004A -+:101CE0007C0396DE02F0007C03965E02F0007C002E -+:101CF000025E02F00B1601BC600300602000680168 -+:101D000073000AAF00025E02F000D400B044670026 -+:101D1000083800B001730010E401BC600300000645 -+:101D200001BC600300005C01BC600301D78201D2EA -+:101D3000DE087570E000B00EB30010E100B000479F -+:101D400000108600B00ECF00108A01BC600300377F -+:101D50008100025E02F00D8D0190600A09104801B9 -+:101D6000BC610300308003BFDE02F0000201BC60F2 -+:101D7000030030420187E00224712300025E02F07A -+:101D8000109301BC600306778000680DEF000AB66F -+:101D900000B00DEF00178100025E02F00E440397C1 -+:101DA0005E02F00B2703125E02F00AB601BC60036C -+:101DB00000402001BC618300112500B0007B0011B0 -+:101DC0002701BC600702578000025E02F00E3F0050 -+:101DD000B05E07000B3001BC600702778000025E36 -+:101DE00002F00E3F00B05E07000B3101BC6013092A -+:101DF00097A100025E02F000A200B04067000B63F2 -+:101E000001BC601309405E01BC601309405F0180A2 -+:101E1000E006F5D7AE0107C1070017A101805E8675 -+:101E2000F577AB01BC600F0011E801BC620F001137 -+:101E3000E000025E02F00AD801BC61CF0C105C0128 -+:101E4000BC600300105D01BC61CF01F05E01BC60AD -+:101E50003B0AF05F00025E02F0106301BC60030009 -+:101E60000835020300C700000401BC60030006023D -+:101E700001BC600300060701BC600300060C01BC46 -+:101E8000600300061103BFDE02F0000401BC6043E2 -+:101E90000017BB00A04122F770480185E002F5B7AA -+:101EA000AD01BC63FF1FF05401BC63FF1FF055017F -+:101EB000BC63BF1FF05601BC63FF0FF05700025E0A -+:101EC00002F012A70187E00624712301BC60030021 -+:101ED000105401BC600300105501BC600300105693 -+:101EE00001BC600300105701BC600F002017010601 -+:101EF000C1070017A101825E8402E01701074107B4 -+:101F00000017A100B85E870037A10180DE870000BE -+:101F1000160002DE02F000000285C0370000020059 -+:101F2000025E02F0117A00025E02F00F9502864016 -+:101F300037000AEC00E0021B0020860386DE02F078 -+:101F40000A870287C037000A870158600300102AF9 -+:101F500001BC600300900400B040130017A103BF50 -+:101F6000DE02F0000401B8600A04902403AA5E02B5 -+:101F7000F00AFA0158600300102A01BC60030290C5 -+:101F80000400B040130018000183600209104801EA -+:101F9000BC60030051E400B0479300180001BC622C -+:101FA0000F0011E00180600100680300025E02F092 -+:101FB0000F9503855E02F00B0101BC620F0011E07A -+:101FC00001BC600F0131E800B047A300180001BC5C -+:101FD000600F0011E801BC60030157A100E85E87B3 -+:101FE0000037A10068DE87000B0801BC6003029087 -+:101FF0000400B0401300180001BC60030131EC0084 -+:10200000B047B300180001BC60030011EC0324DEEC -+:1020100002F005F801866006F577AB00025E02F07B -+:102020000B160180600610308100B05E870017A19A -+:102030000180600210308103BFDE02F005F801BCB0 -+:10204000610300108000B04203001800006EE0033E -+:10205000002B1903505E02F00B1C00015E02F00021 -+:102060000003BFDE02F002F401846002F597AC00C9 -+:10207000A8412304F048018260020910480206DEEC -+:10208000AF000B2203D5DE02F00B220350DE02F07C -+:102090000B2001BC60030010B40284C783000B2531 -+:1020A00001BC600B0011E0018E6002F577AB00020D -+:1020B000DE02F0000003A2DE02F0007C02BC4287D8 -+:1020C000000B2E01BC60030037A401BC60031FF7A6 -+:1020D000A3011400630017A200886006F457A2034E -+:1020E000BFDE02F00B33008860070117A401BC6358 -+:1020F000FF0017A3011400630017A200E05E8B012C -+:1021000017A200886006F457A201BC601311106585 -+:1021100001BC601B02506401BC60030017A50020D5 -+:10212000C286F48B3D00E0419706D06500E0419304 -+:1021300001F06400E05E970037A500885E930037E9 -+:10214000A400205E92F46B5C03BFDE02F00B36004D -+:1021500068DE92F44B4200680083006B4203A0DE0D -+:1021600002F00B420020C123160B3700025E02F082 -+:102170000B16006DDE93200B58020300C7000B4CBA -+:10218000006DDE97008B4C01BC600300160801BC9B -+:10219000600300160901BC600300160A01BC60035D -+:1021A00000160B01BC600300160C01BC6003001696 -+:1021B0000D01BC600300160E02005AC3000B57024B -+:1021C0003C5A9F000B5700680083006B570385DE65 -+:1021D00002F0007C03855E02F0007C03A2DE02F0C8 -+:1021E000007C03A3DE02F0007C0397DE02F0007C9B -+:1021F00000B041970010600191600A84F42703BF8A -+:10220000DE02F002CC01806002D616B000B05E9310 -+:102210000010A101836002F7F7BF01BC600300302A -+:102220004303BFDE02F00B370068808300607C034D -+:10223000BFDE02F00AB70283C21F00000200B05ED8 -+:10224000870017A103D0DE02F0051001BC60030473 -+:102250001042039EDE02F0000400B05E3F00114514 -+:1022600001BC600300178F00B05E4300178500B00B -+:102270005E0F00179000025E02F00B1603BFDE0235 -+:10228000F00004006D40330589C503AC5E02F00B1D -+:102290006E00685E4F028BC000E002670020990369 -+:1022A000BFDE02F00BC000685E4F028BC000E00290 -+:1022B0005F00209701856002F5B7AD01826002F5ED -+:1022C000D7AE01BC6003000ABD039EDE02F00B82A4 -+:1022D0000321DE02F00B8200E0026F00209B00026F -+:1022E0005E02F00B16018660020910480180600250 -+:1022F0000910480181E00209104801BC6003021086 -+:10230000420280441F000B8100B05E3F0011450176 -+:10231000BC600300178F00B05E4300178500B05EFD -+:102320000F00179003BFDE02F00B8200A044B6F04E -+:102330007145028200C3000BC000B000730017A1FA -+:1023400000E05E86B017A100E15E7AF4379E00E1FE -+:10235000DE7700179D00E1DE7300179C00E0DE6F62 -+:1023600000179B039EDE02F00B91006E5E6E924B97 -+:10237000D6006D5E6E924B91006E5E72922BD6000F -+:102380006D5E72922B91006E5E76920BD6006D5E42 -+:1023900076920B91006DDE7A91EBD6028201AB0052 -+:1023A0000BA200B0446700083400B0446B0008334F -+:1023B00000B0446F00083200B04473000831006878 -+:1023C000A0D2232B9100E920D2F3D79E00E9A0CE22 -+:1023D000F3B79D00E9A0CAF3979C00E8A0C6F37785 -+:1023E0009B00E15E7A91F7A100B05E8700111900B1 -+:1023F000E1DE7692111A00E1DE7292311B00E0DE1E -+:102400006E92511C0068DE86232B9B03BFDE02F018 -+:102410000BC000E9523EF3D7A100E9D242F3B7A2C4 -+:1024200000E9D246F397A300E8D24AF377A40088E4 -+:10243000121B0057A500E0015EF4B06400E95E865F -+:10244000C9A6D200E9DE8AC9C6D300E9DE8EC9E694 -+:10245000D400E8DE92CA06D50080921B0197A50140 -+:10246000BC601B11778000E05E020DB06500885AE9 -+:102470000F00B7A500B05E970217A50125DA0F007F -+:1024800017A600E95E94DA57A500E8DE98DA77A689 -+:10249000017ADE96F4D7A500685E96D06BC000E89E -+:1024A0005E96D077A600B05E9700168300685A1338 -+:1024B000000BBA00E05A16F4D68500685A1B000BD0 -+:1024C000BC00E05A1EF4D68700B05E8700164D00AF -+:1024D000B05E8B00164E00B05E8F00164F00B05EEF -+:1024E00093001650031EDE02F00BD6039F5E02F02F -+:1024F0000BD600685E4F028BD6032C5E02F00BD623 -+:1025000001BC601F16B06501BC600300B7A40002E7 -+:102510005E02F000E90068DE9300ABD60207C197C7 -+:10252000000BCC013C5A07001788013C5A0B0017DE -+:10253000A103BFDE02F00BCE01385A070017880155 -+:10254000385A0B0017A10080921B0197A200E001EE -+:102550005E0DB06400B05E230016280181DE86C3E4 -+:10256000F61F0187DE86249124020680F3000BD635 -+:102570000181E002C3F61F0187E00224912403AB2E -+:102580005E02F006AA03BFDE02F008AB032B5E0278 -+:10259000F009C403BFDE02F006AA03AB5E02F00B33 -+:1025A000DD032C5E02F009C403BFDE02F00BED0078 -+:1025B000B052230011F200B052270011F300B052C4 -+:1025C0002B0011F401BC60030091F500B0005B002A -+:1025D00011F003BFDE02F006AA0138523F0017A136 -+:1025E00002065E53000BE60138524B0017A100684B -+:1025F000DE87008BE903AB5E02F006AA03BFDE02B2 -+:10260000F008AB0068DE4F020BEC020781AB000B59 -+:10261000EC01806006F2979403AB5E02F006AA021A -+:102620000000F3000BF20206DE53000BF201185E0D -+:10263000830017A10068DE8700ABF201BC600B02CB -+:102640005142020052170009C403BFDE02F008AB7A -+:1026500001BC600300118301BC6003001182032CE4 -+:102660005E02F00BF90199E00620110003BFDE02C3 -+:10267000F00BFD0119402F0017A100685E870009CB -+:10268000C00199DE8620110003315E02F009C0000E -+:10269000A05E3B0097A200205E4EF449C00184601A -+:1026A0000209104803BFDE02F009C0032B5E02F0EE -+:1026B00009C00068DE4F042C0600B0523300179F9B -+:1026C00000B0522F0010EB0281522F00069200E062 -+:1026D00002AB0020AA0281522F0009A003295E024A -+:1026E000F00C0C0203DEB3000C0C0191601A84F4B0 -+:1026F000270183E002F597AC0208522F0006AA03D7 -+:10270000BFDE02F008AB01BC600300106701BC60D3 -+:10271000030010460180E0060930490282C11F0013 -+:102720000C1601BC602F1FF06501BC600300168011 -+:1027300000E841970030650069C197000C1301BCA7 -+:10274000600B00179401BC60030017AB01BC600371 -+:102750000017AC01BC60030017AD01BC600300179B -+:10276000AE01BC60030017BF01BC60030020200164 -+:10277000BC60030017A100025E02F000A201384015 -+:1027800067000028011C406700002901BC600300AD -+:10279000504901BC60030017A701BC60030017A8E3 -+:1027A00001BC60030017A901BC60030017AC01BCA9 -+:1027B00060030017AD0182E0060F10780206C1E346 -+:1027C000000C28006880A7000C2B03BFDE02F00C71 -+:1027D0002C006880A7008C2C01BC600B1EA000019F -+:1027E000BC600300200101BC634F01A00201BC6179 -+:1027F000DB06800301BC600300400401BC604309A8 -+:10280000200501BC601F14106101BC601317D0606B -+:1028100001BC600300082900B05E0F00178500A00E -+:1028200044B6F07145028741D7000C3701BC600304 -+:10283000000BF001BC600300107D01BC60030010C0 -+:102840007C01BC606300107B01BC600300107A0156 -+:10285000AC607F00107501BC63470897A10068C198 -+:10286000DAF42C43011A41DF0017A10068DE87016A -+:102870006C4301BC637B15ABF003BFDE02F00A9E24 -+:1028800001885E5CFF87FC01BC601F1F500701BC14 -+:102890006003019008018860060090040386DE0250 -+:1028A000F00A870305DE02F00C480386DE02F00A18 -+:1028B000870385DE02F00C4A00B05E870017A10096 -+:1028C0006EE003002C4E0386DE02F00A87006EC025 -+:1028D000146F2C5101BC60070010420207C0AF000A -+:1028E00007590002DE02F0000003215E02F00C57DF -+:1028F00000E02066F4281900B0206700178B03BFA2 -+:10290000DE02F00C5F028150C7000C5C011C509F7E -+:1029100000178B00E05E2EF4378B019C5E2E84F452 -+:102920002703BFDE02F00C5F011E509F00178B00D3 -+:10293000E05E2EF4378B019E5E2E84F4270002DECB -+:1029400002F000000107402700082800E020A30053 -+:1029500028280002DE02F0000000B044670017A241 -+:10296000017ADE8A2357A10090012F00B7A601BC8F -+:10297000601B11706501BC60030017A201BC601BE5 -+:102980000DD06401BC601B1B906300685A03000CEF -+:10299000A8006B5E86D06C7E00B05A030017A300BF -+:1029A000E05A0EF4D58000E05A0EF4768300E85A1F -+:1029B0002F00368B0069DA2F000C7200E85A0700EE -+:1029C000368B006CDA0EF42C6D01BC60030036000F -+:1029D00001BC600B00104301BC60030026DA00203C -+:1029E0005A0B080C7901BC60030026DB03BFDE0232 -+:1029F000F00C7E00205A0B140C7E01856006F5B7A2 -+:102A0000AD0088009B00D1260090009B0151280159 -+:102A1000BC6303001124006B5E86B00C8600685A0C -+:102A200013000C8301886006D0568200B056030064 -+:102A300017A400E05E92D0968500E05A0EF4D5808F -+:102A400000205A0B080C8601BC60030006DB0068FE -+:102A50005A13000C8E006B5E86D0AC8E0188600A23 -+:102A6000D0568200B056030017A400E05E92D096C4 -+:102A70008501BC600300360101BC600B00104301FE -+:102A8000BC60030026DA00685A1B000CA8006B5ECD -+:102A900086D0ECA802015A0B000C9D00E85A1B00DE -+:102AA000368600B05A270017A300E05A1EF4768736 -+:102AB00001BC601B1C106200E0418AF4506200B04F -+:102AC0005A2B0017A300E05402F475000202D4034D -+:102AD000000C9B00E05A1F003687012054030015AC -+:102AE0000001816002D0568203BFDE02F00CA0001C -+:102AF000B05A230017A300E05A1EF47687018160C4 -+:102B000006D0568200685A1B000CA2006CDA1EF434 -+:102B10002C9002015A0B000CA501BC600300360288 -+:102B200003BFDE02F00CA601BC600300360301BC4B -+:102B3000600B00104301BC60030026DA00E04197FF -+:102B400001906500E05E8B0037A200E041930090A9 -+:102B50006400E0418F003063006D5E8B008C6A0082 -+:102B600002DE02F0000000B05A0300101F00B05A4D -+:102B70000700102000B05A0B0010210180600700F0 -+:102B8000101D02804077000CB20002DE02F000004F -+:102B90000187E002F577AB03915E02F000020020AE -+:102BA000E3FE09000200025E02F00C6301BC601B40 -+:102BB00011706400E041930617A20068D82F000C42 -+:102BC000BC0281D80B00000200E041930190640038 -+:102BD0006D4192F44CBA0287C49300000200689BD6 -+:102BE0006F00000202815E53000CC90283411F0086 -+:102BF0000CC30281DE53000CCF01BC6003001151F5 -+:102C000001BC600300115201BC620300115301BCFE -+:102C1000600300515001896006F2979403BFDE0201 -+:102C2000F000020280C54300000201F0C547001118 -+:102C3000560107C5470017A101F0C54AF4315501F7 -+:102C400089600AF2979401BC60030810470392DE82 -+:102C500002F00D1C01BC601B11706501BC6003001B -+:102C600037A101BC63FF1FF7A201BC60030017A3DB -+:102C700001BC60030017A600685A03000D0B01BCDD -+:102C800060030017A502035A0B000CDE02805A0BEA -+:102C9000000D1C00E944080977BB00E8C40F0017C9 -+:102CA000A4017ADEEEF497A400685A13000CEA033C -+:102CB000BFDE02F00CE70203DA0B000CF200B05AA0 -+:102CC0000F0017A400685A07002CE300685A2F0071 -+:102CD0002CE301BC60030037A500685A13000CE721 -+:102CE000006CDE92D0ACE700B05A170017A401BC0C -+:102CF00060030037A5002019FAF42CEA00685A1B7B -+:102D0000000D0503BFDE02F00CED00885E87009722 -+:102D1000BB002019FAF76D1C02015A0B000D1C00B4 -+:102D20006CDE92D0ED0500B05A1F0017A4002019E8 -+:102D3000FAF42CF101BC60030037A503BFDE02F0FA -+:102D40000D050202DA0B000D0B0204C107000D1C79 -+:102D500000B05A0F0017A400E85A2F0037BB0069D3 -+:102D6000DEEF000CF800E85A070037BB013C016FAA -+:102D70000017800068DE03000CFE0138016F0017A9 -+:102D80008000685E03000D0100E85E030037BB03AE -+:102D9000BFDE02F00D0100E85E030037800080DE38 -+:102DA00002D0378000E05EEE0DB7BB00685EEF003A -+:102DB0000D0500E05E92D017A400E85EEF0037BB7F -+:102DC00003BFDE02F00D0100685E8F000D08006B8E -+:102DD0005E92F44D0903BFDE02F00D0B01BC6003EF -+:102DE0000037A300B05E930017A200B05E970017F3 -+:102DF000A600885E870037A100E04197019065003A -+:102E00006D5E87020CD500685E8F000D1C00B0441B -+:102E1000670017A5017ADE962357A500E85E8AF4BD -+:102E2000B7A400885E9300A6D700905E930166D891 -+:102E300000B0012B0017A300689B63000D17006E04 -+:102E40009B5EF46D1C03A65E02F00D1C00B05E9B41 -+:102E50000006D900E91B5EF4681400E89B630008D3 -+:102E60001503BFDE02F00D1E00681B6700000203A1 -+:102E7000BFDE02F00D6F01BC610300112300692069 -+:102E800057000D220180E006F2979403BFDE02F0A6 -+:102E90000D240180E002F2979403BFDE02F00002ED -+:102EA00000684127000D3002844523000D2500B045 -+:102EB00044670017A100E84466F437A2006D5E8BFA -+:102EC000004D270280C127000D2B0392DE02F00D7A -+:102ED0006F0392DE02F00ACA00025E02F010970051 -+:102EE000025E02F00E4F00025E02F00E4A00025E29 -+:102EF00002F00E5A01BC600F0011E8031EDE02F062 -+:102F00000D3701BC600300105C01BC600300105D64 -+:102F100001BC605304105E01BC600300105F03BF7E -+:102F2000DE02F00D3B01BC600B00105C01BC6003D5 -+:102F300000105D01BC604304105E01BC6003001022 -+:102F40005F01BC6003008020028500BF000D80008F -+:102F5000B0205300115100B02057001152006E20D4 -+:102F6000522A8D430068A057000D4300E0205223F1 -+:102F7000281603BFDE02F00D4500B04467000816B6 -+:102F800001BC600300315001BC60030C90400000A4 -+:102F9000DE02F000000068C103000D4A02804543D4 -+:102FA000000D45006B446502CD4501BC6003001176 -+:102FB0005002844543000D4B00B044670017A10048 -+:102FC000685E86232D4D01BC6003004020018660B1 -+:102FD0000620110000E920522A37A100E8A0562A55 -+:102FE00057A200E14466F4311900E1C46AF4511AB1 -+:102FF00000E1C46F00111B00E0C47300111C00B09D -+:10300000441F001800008844230157A30090442364 -+:1030100000D7A400B0440B0017A100B0440F001764 -+:10302000A200E95E862337A100E8DE8A2357A200CA -+:1030300069DE8B000D6500E1440AF4710200E0C412 -+:103040000EF4910300E02AF7002ABD00E85E230099 -+:1030500037880069DE23000D5900E8002700378813 -+:1030600003BFDE02F00D59018660022011000068E6 -+:10307000C103000D6F00681B67000D6F01BC60434A -+:103080000017A100E04466F4378001BC600300062D -+:10309000DA00025E02F00C63006C4466F00D6F0013 -+:1030A000681B6B000D6B03BFDE02F00CCF0200DE6D -+:1030B00053000D820180E002F2979400025E02F05C -+:1030C0000E4D01BC600300104003BFDE02F00D7521 -+:1030D000020080C3000D7900E044640957A100E8B4 -+:1030E0005E862137A1006CC466F42D7703BFDE0233 -+:1030F000F00D8200E8012A21281401BC60030008B9 -+:103100001500B0205300115101BC600300115201A1 -+:10311000BC600300315002804543000D7E03BFDEDA -+:1031200002F00D4F01BC600300104000B0012B0005 -+:1031300011090068AAE7000D8300B0012F001109F2 -+:1031400001BC61CF0C105C01BC600300105D01BCD0 -+:1031500061CF01F05E01BC603B0AF05F00025E02DD -+:10316000F00E5600025E02F00E5F00025E02F00EEC -+:103170005301BC60030006D903BFDE02F00ACA0196 -+:10318000885E0610D08601025E070017A101825EEC -+:103190008610D08601BC600306778000B00DEF007A -+:1031A00017810288421B000D9400B00DEB001781BF -+:1031B00000685E07000D9600025E02F00E44020BEE -+:1031C000421B000D9803BFDE02F00D99018B20A277 -+:1031D00010D0860002DE02F0000000B05413001789 -+:1031E000A10200DE07000DA100B0418B00106501B7 -+:1031F000BC600301D7A100025E02F011A500E05EF1 -+:103200008400F7A103BFDE02F00DA6020480F300E4 -+:103210000DA602025E07000DA602805E07000DA645 -+:103220000090001B0037A200E85412F457A10002DE -+:10323000DE02F00000020400BF000DAA00025E02E0 -+:10324000F00F4E03BFDE02F00DAB00A044B6F0B1AC -+:10325000450002DE02F00000020000BF000DBC00CD -+:1032600068AC0F000DBC00E05EA30037A8006D5EE7 -+:10327000A005CDBC00B02CB70017A100025E02F083 -+:1032800000A200B040670017A20068DEA3FFEDB9FE -+:1032900000B05E8965D7A2006D00A7008DB8006DF3 -+:1032A000A0A3004DBA03BFDE02F00DB90068A0A3D1 -+:1032B000000DBA00B85E8965D7A200025E02F00078 -+:1032C000A801BC60030017A80002DE02F0000000A5 -+:1032D000D85A030117A201B85A06F457A200B056F3 -+:1032E0000300083C00B0560700083D00B0560B0034 -+:1032F000083E00B0560F00083F00B05613000840CB -+:1033000000E05612F4484100B05A0300083A013870 -+:103310005E8B00083B00B021070017A401BC6003CE -+:103320000017A200B0419300106500B85E92D0175C -+:10333000A400E05E06F4506300F05E930017A30063 -+:10334000F05E930077A400E05E8B0037A200B85EC9 -+:1033500092F477A400E04192F4506500E05602F444 -+:10336000958000B056030017A4006EDE8B00ADCA36 -+:1033700000B85E92C0D7A200D85E8B0037A200E0F2 -+:1033800020F2F4483C00B020F30017A400B85E928D -+:10339000C0F7A200D85E8B0037A200E020F6F44808 -+:1033A0003D00D820F70037A200E020FAF4483E00A4 -+:1033B000D820FB0037A200E020FEF4483F00D820D0 -+:1033C000FF0037A200E02102F4484000D8210300AA -+:1033D00037A200E02106F4484100B021070017A2FF -+:1033E00000B85E8AC017A200905E8B0037A201BCB5 -+:1033F0005E8907683B0002DE02F000000180600683 -+:103400003C91E4018760063CD1E601A860023CD112 -+:10341000E6018B60023CD1E600B05E8F00106300D5 -+:10342000B056030011E700B056070011E700B05690 -+:103430000B0011E700B0560F0011E701A960423CF4 -+:1034400091E401A860023CD1E6018B60063CD1E624 -+:1034500000B05E8B00106301BC60030057A1020442 -+:103460005603000DF801BC60030117A100E0418E76 -+:10347000F4306300B056030011E700B056070011A6 -+:10348000E700B0560B0011E700B05E8B001063013F -+:10349000BC600300B7A10204D603000E0201BC60A9 -+:1034A000030117A102065E53000E0201BC60030176 -+:1034B00097A100E0418EF4306300B056030011E79D -+:1034C00000B056070011E700B0560B0011E701BC31 -+:1034D00060030017A10206DE53000E0D00B05E8BE4 -+:1034E00000106302065E53000E0C00A0563F01F769 -+:1034F000A103BFDE02F00E0D00A0563301F7A100BC -+:10350000B05E870011E701BC60030011E70002DE36 -+:1035100002F0000000685E9B00CE2A01BC6007023A -+:1035200011E30068DE9B004E1D00E847870111E1B2 -+:1035300001BC60030011E201BC60030011E201BCA8 -+:1035400060030011E201BC60030011E201BC6003F2 -+:103550000011E201BC60030011E201BC6003001134 -+:10356000E201BC60030011E200B06142F451E000EE -+:10357000B058030011E200B058070011E200B05843 -+:103580000B0011E200B0580F0011E200B058130018 -+:1035900011E200B058170011E200B0581B0011E210 -+:1035A00000B0581F0011E200B05E9B0017A4006835 -+:1035B000DE9B00AE2801BC60030077A40192DE937D -+:1035C0000217A30002DE02F0000001BC6007001138 -+:1035D000E300B058030011E200B058070011E20008 -+:1035E000B0580B0011E200B0580F0011E200B058C3 -+:1035F000130011E200B058170011E200B0581B0090 -+:1036000011E200B0581F0011E200E00146F0106422 -+:1036100001BC60070031E300B058030011E200B0C4 -+:1036200058070011E200B0580B0011E200B0580F2B -+:103630000011E200B058130011E200B05817001159 -+:10364000E200B0581B0011E200B0581F0011E20167 -+:1036500092E01B0017A30002DE02F0000002874088 -+:10366000C3000E3F01866006F01030028640C300A2 -+:103670000E4100B040C70017810002DE02F00000DA -+:10368000028740C3000E4400B05E0700103101867F -+:10369000E006F010300002DE02F00000006800A733 -+:1036A0000112E303BFDE02F00E5E00025E02F00EC6 -+:1036B0004D00025E02F00E5F0002DE02F00000002C -+:1036C0006800A70112AC0002DE02F0000001816078 -+:1036D00006093049006800A7008E5200025E02F021 -+:1036E0000E6F0002DE02F0000000025E02F00E6FBC -+:1036F000018160020930490002DE02F00000018809 -+:10370000E00E09304900B0412700180000B0002B3E -+:103710000010020002DE02F0000001BC6003001095 -+:10372000020182E0020F107801BC60030010490022 -+:10373000B041270018000002DE02F000000068001F -+:10374000A7010E600280DE53000E6601BC60130705 -+:1037500077A100025E02F000A2019060020337A28E -+:1037600000025E02F000A80002DE02F0000001BCD0 -+:1037700060130797A100025E02F000A20190601E94 -+:103780000337A200025E02F000A801BC60130777B5 -+:10379000A100025E02F000A20190601E0337A200A9 -+:1037A000025E02F000A80002DE02F000000100DE6E -+:1037B000530017A60181DE9A09304900B041270065 -+:1037C00018000002DE02F000000002DE02F000003D -+:1037D00000B044670017A2017D5E8A2357A300B0A2 -+:1037E0001C770017A100B85E84E3D7A2025A5E8B53 -+:1037F000000E7C0180E006F4271E01825E86F297AF -+:103800009400B05E8F00071B02001C7B000EC300FB -+:10381000E85E8CE377A2006D5E88E38EC300E0442F -+:10382000670287210285C523000EC00020E3FE0940 -+:103830000EC001BC60130997A100025E02F000A255 -+:103840000068C067000EC001BC60131617A100021B -+:103850005E02F000A20068C067000EC001BC6013E9 -+:1038600009D7A100025E02F000A20068C067000E46 -+:10387000C001BC63FF1FF7A10068DE862C2EC002CA -+:10388000009C7B000EB40180E000E3C71E01BC6019 -+:10389000230F57A100025E02F000A200B0406700B3 -+:1038A00077A400B05E930017A200025E02F000A8A9 -+:1038B00001BC601B1B57A100025E02F000A2018147 -+:1038C000E0060337A20186E006F457A200025E027A -+:1038D000F000A801BC601714D7A101BC600300B7B9 -+:1038E000A200025E02F000A801BC60171457A101FB -+:1038F000BC60031877A200025E02F000A801BC6061 -+:103900001714B7A101BC600300F7A200025E02F029 -+:1039100000A801BC60171077A101BC600F0417A2BA -+:1039200000025E02F000A801BC60171097A101BC64 -+:1039300060030017A200025E02F000A801BC60173D -+:1039400010B7A101BC600B0017A200025E02F000DC -+:10395000A801BC601710D7A101BC60030017A2002A -+:10396000025E02F000A801BC60171017A101BC6044 -+:103970000B0037A200025E02F000A801BC60230F1A -+:1039800057A100A85E930077A200025E02F000A893 -+:1039900001BC60171017A100025E02F000A2020035 -+:1039A0004067000EB9006CC464E42E8003BFDE02E1 -+:1039B000F00EC001BC60171277A100025E02F00099 -+:1039C000A20068C0671FEEC001806000E3C71E014F -+:1039D000BC600300904301806000E3C71E01826069 -+:1039E00002F297940180E004E3C71E01BC6003006B -+:1039F000071A03BFDE02F00EC30002DE02F0000071 -+:103A00000201C11F000ED602855EAF000EC90185FE -+:103A10006006F577AB00B0446700082500B0446B42 -+:103A200000082600E9446504B7A100E8C46904D78A -+:103A3000A200D05E870077A101E1DE8AF437A20000 -+:103A4000E95E862697A100E8DE8A26B7A200695EB5 -+:103A50008B000ED601BC610300113300E144DAF49F -+:103A6000313600E144DEF4513701856002F577AB71 -+:103A700001BC600301104701BC6003005043000219 -+:103A8000DE02F0000000B0451F00178100B005B74E -+:103A90000017A601BC600704106401BC601311107C -+:103AA0006501BC60030017A10205DEAF000EEF0048 -+:103AB000B0580F00178000685E842C2EF702005E5D -+:103AC0009B000EEF0280DA03000EE50118581F007C -+:103AD000178200E05E0B00378201985E0AC0F6078D -+:103AE00003BFDE02F00EE8011A581F00178200E043 -+:103AF0005E0B003782019A5E0AC0F60701F0DE0312 -+:103B000000378000A05E02C0578000B05E03001640 -+:103B10000300A044B6F0178200B05E0B001605004B -+:103B2000E05E0AC0960603BFDE02F00EF700B05852 -+:103B30001300178200E85E06F057A5006ADE9700C2 -+:103B40000EF500E85816F4B6050069D817000EF512 -+:103B500001BC600300160500B058170017A500E06F -+:103B60005812F4B60600E0419302106400E0419759 -+:103B700006D06500E05E870037A100905E9B0037AD -+:103B8000A60068DE87008EDC01BC600300114701DF -+:103B9000BC600300016D0002DE02F0000001BC60A9 -+:103BA0000300016C01BC600300016D01BC60070AE9 -+:103BB000106401BC60030077A100B0428F00178041 -+:103BC00000A05E0301F78000B05E0300016E01BC3F -+:103BD00063FF1FF7A20068DE03000F0901BC60034A -+:103BE0000017A200886006F43781002005BAF02F84 -+:103BF0000E0068DE8AC0CF0E00E005B300216C0025 -+:103C0000B005B6F0216D00685E03000F1200205E63 -+:103C100006F00F18006EDE8AC0CF1803BFDE02F078 -+:103C20000F13006DDE8AC0CF1800B05E870017A3A7 -+:103C300000B0419300016600B0581B0017A201BC00 -+:103C4000600300016C01BC600300016D00E841935A -+:103C500002106400E85E870037A10069DE87000F6C -+:103C60000900B05E8F0001650002DE02F000000076 -+:103C7000B0059B001064006E581B002F2100E05817 -+:103C80001B00314503BFDE02F00F2200B0581B00BD -+:103C9000114500B0059B00016200B005970001616D -+:103CA00000B0580F00178500B0580700178300B008 -+:103CB000580B0017840118581F00178C011A581F41 -+:103CC00000178D0002DE02F0000000B0059700171B -+:103CD0008000685E002C2F4D01BC600300111201B2 -+:103CE000BC600300111500B0059B00106402004584 -+:103CF00023000F3700B0451F00178100E80592F040 -+:103D00003780006ADE03000F3500B05E0300114506 -+:103D100003BFDE02F00F3801BC600300314503BF72 -+:103D2000DE02F00F3800B0059300114500B00583A6 -+:103D300000016900B0058B00016A00B0058F000129 -+:103D40006B00B0058700016800B005AB001065028C -+:103D5000845A1F000F4100B05E1700168301985E61 -+:103D600032D0F687019A5E36D0F68701846002D0A1 -+:103D7000F68700B0059300016000B0059B0001626A -+:103D800000B0059F00016300B0059700016100B01D -+:103D9000058B00106400B0580F00178500B058075D -+:103DA00000178300B0580B0017840198581EF19734 -+:103DB0008C019A581EF1B78D03BFDE02F00F4D0043 -+:103DC00002DE02F0000000B0058B001064006E41BE -+:103DD000932A0F5B00A044B6F0B7A100B05E870045 -+:103DE000160500E05812F4360600B0581B001145C5 -+:103DF000020000F3000F58006D4193280F58020095 -+:103E0000DEAF000F5801BC600B02514200B05E876C -+:103E100000016F02015EAF000F5B00B05E1700167D -+:103E20000301816002F577AB0002DE02F0000002C0 -+:103E3000014523000F660287C493000F660182606C -+:103E400002F5D7AE02012C43000F6300E02C4B00BB -+:103E50002B1201816001620B1002055EB7000F6634 -+:103E600000E02AF7002ABD01856002F5B7AD000227 -+:103E7000DE02F00000020200BF000F7400025E02CA -+:103E8000F00F960202DEB3000F6C0020428F000C90 -+:103E9000B403BFDE02F00002028881AB000F74029F -+:103EA000845EFF000F6A02845EB3000F6A0282DE46 -+:103EB000FF000F6A02822B4F000F7200682ABB00BE -+:103EC0000F740284DEAF000F6A02835EB7000F6AD0 -+:103ED00000B05E870017A10002DE02F00000018240 -+:103EE000E002F597AC0203DEFF000F7E028445235B -+:103EF000000F7E02012B4F000F7E0180E006F2973B -+:103F00009400025E02F00E6F0180E002F2979400CE -+:103F1000025E02F00E6F0180E002F29794028400CC -+:103F2000C7000E4803BFDE02F00E4A020400C700BD -+:103F30000F880284C56F000F9402844523000F850B -+:103F400002004203000F9400685E4B04AF940068C7 -+:103F50005E4B06AF9400685E4B062F940182E0062C -+:103F6000F597AC02844523000F8B0323DE02F00F8C -+:103F70008C0183E006F597AC0180E006F29794028D -+:103F80008400C7000E4800B02AF70017A2006DDEBB -+:103F900089560E4802872B4F000E4A02005EFF0032 -+:103FA0000E480287AB4F000E4A03BFDE02F00E48F8 -+:103FB0000002DE02F00000020200BF0013000068F1 -+:103FC0002B0B000F9B00E844655857A101BC63F719 -+:103FD0001D17A2006D5E86F44F9B00E84466F44A0C -+:103FE000C2006CC465576F9D00E84467002ABB029D -+:103FF00080456F000FD10203DEB70010580183E047 -+:1040000002F5B7AD0202DEB3000FA3018360062BF9 -+:10401000915C00025E02F00F7602835EBB000FA689 -+:1040200000E845895BF7A1006E5E8555AFBE0204CE -+:10403000DEB7000FBA00E02BB7002AED01BC600329 -+:10404000000AEF00682C67000FAB00E82C67002B1C -+:104050001900B02BB70017A201856002F5B7AD02B9 -+:1040600004DEFF000FB0006D5E895DCFB00184E01B -+:1040700002F7F7BF0206DEFF000FBA00E02BE702EF -+:104080000AF900B04467000B0401182BE70017A1E0 -+:10409000011A2BE70017A2006E5E87000FB8006DB3 -+:1040A000DE895F4FB803BFDE02F00FBA01BC6003C8 -+:1040B000000AF90186E002F7F7BF02025EFF001076 -+:1040C000580068AB0B00105800B02AE7000AC20085 -+:1040D00002DE02F000000182E002F7F7BF02025E9A -+:1040E000FF000FC8020600C7000FC102025EFF00FA -+:1040F0000FC800E845895BF7A1006DDE85614FC6FA -+:1041000000E844656177A1006D5E85618FC800B0ED -+:104110004467000AC20002DE02F000000204DEB7BB -+:10412000000FD000E8446556CABE00682C67000F37 -+:10413000CC00E82C67002B1900E02BBF002AEF0011 -+:10414000B02BC30017A1006D2BBEF42FD001BC60B3 -+:1041500003000AED0002DE02F000000203DEB700F9 -+:104160000FD80282DEB30010580203C57300104A54 -+:1041700000E844655737A1006D5E8556B05801834D -+:104180006006F5D7AE03BFDE02F0105801BC600335 -+:10419000000ADF006D45871F4FDB00B04587000A2E -+:1041A000DF00E044655BF7BB00E85EEE2C2AB90156 -+:1041B000836002F5D7AE0183E006F5B7AD0184E078 -+:1041C00002F5B7AD01826002F7F7BF01846002F526 -+:1041D000B7AD0101456F0017A101875E86F577AB8A -+:1041E00001BC6003000B0D00025E02F0130100E849 -+:1041F00044655737A1006D5E855ECFE6006D5E8534 -+:1042000056AFEA00E02B83002AE000B02AB3001783 -+:10421000B3020680C7000FED02075EAF000FF00289 -+:104220000680C7000FF20184600561AB0D03BFDE9D -+:1042300002F00FF201826006F7F7BF00B02AE70034 -+:104240000AC10200C56F000FF601846006F5B7AD24 -+:10425000020480C3000FF60184E00561AB0D020289 -+:10426000DEBB000FFC0284DEFF000FF90206DEFF5A -+:10427000000FFC00B02BB70017A1006DDE855DCFED -+:10428000FC0182E00561AB0D00E05ECD55B7B301E6 -+:10429000826002F5D7AE00B02C4B0017A100B02A07 -+:1042A000F70017A2006D5E8956100302855EB70005 -+:1042B000100C03BFDE02F01005006D5E8560F00E8D -+:1042C00002812C4300100C00B0440B0017A300B077 -+:1042D000440F0017A200E95E8E2337A300E8DE8AB0 -+:1042E0002357A200695E8B00100E0068DE8B001061 -+:1042F0000E006E5E8EF6700E01826006F5D7AE007F -+:10430000025E02F0114902045EB70010230206802B -+:10431000C700101102075EAF00102300682ADB00FF -+:10432000101C00E8446556D7A201BC60371597A35E -+:10433000006D5E8AF47023006E5E895D90230184B7 -+:10434000E006F5B7AD00685E8B00101C00B05E8B18 -+:10435000000AAE0182E006F5D7AE006E5E896110FC -+:104360001C0182600561AB0D00E844655737A10070 -+:10437000B044670017A300E85E8EF42AB60068AB6D -+:104380001708902200B02BCB0017A200E82ADAF41D -+:104390004AB601846002F7F7BF0282DEB30010580C -+:1043A0000203C57300104A00B02ACB0017A200B068 -+:1043B0002AD30017A300685E8F00102D00682B0B16 -+:1043C00000102D00E844655857A100E05E8EF457B8 -+:1043D000A2006D5E86F4502D0181600561AB0D0277 -+:1043E00081AB4F00103202005EFF00103202044524 -+:1043F0002300103203A0DE02F010320183E00561D9 -+:10440000AB0D0281AC4700104702862C37001058D4 -+:104410000286AC37001058028080BF00105802821C -+:104420005EBB00105802822BF30010470281AC37AC -+:104430000010470280AC3700104702812C37001073 -+:104440004702822C37001047028881AB00104702D8 -+:1044500082AC3700104002842C370010470284AC35 -+:10446000370010470283AC3700104702835EB70065 -+:1044700010460204DEAF0010460281DEBB0010468B -+:104480000184E002F577AB00025E02F0113303BF56 -+:10449000DE02F010580183E0022B915C020701ABB1 -+:1044A00000104A0180E00209D04E00E84465573709 -+:1044B000A1006D5E8555B058028101AB001050021D -+:1044C0000081AB00105202842C370010520280ACE5 -+:1044D00037001052018360022B915C03BFDE02F0B3 -+:1044E0001058018360022B915C00025E02F00F8184 -+:1044F00002835EB70010580184E006F577AB00E058 -+:104500002B47002AD103BFDE02F0111B0002DE029E -+:10451000F000000184E002F5B7AD01836002F5D739 -+:10452000AE0182E002F5D7AE0182E002F7F7BF01EB -+:1045300084E002F7F7BF01BC6003000ADB01BC6046 -+:1045400003000AD001BC6003000AC8018760016053 -+:104550006B030002DE02F00000020200BF001089BF -+:104560000283DEFF0010920183E006F7F7BF01BC73 -+:10457000600302115D00B02AB700115E018560067C -+:104580000B705B018560060BF05F0280456B0010CD -+:104590006D018B60022B915C0188600E2B515A00DB -+:1045A000682ADB00107001846006F7F7BF01BC6069 -+:1045B00003000AB600025E02F0105900E844696088 -+:1045C000D7A1006EDE8700307A00B02BF7000AF822 -+:1045D00001BC6003000AF700682B0B00107A00B0E2 -+:1045E0004467000AC100E84465564AC200B02AD3B5 -+:1045F0000017A100E82B0AF42AC2028080BF001035 -+:10460000800281DEBB0010840200456F0010800232 -+:1046100083C57300108001BC63FF1FF7A10068C54C -+:1046200086F43084018B600E2B915C0183E002F5EF -+:10463000B7AD0184E002F577AB03BFDE02F01126CF -+:10464000018360022B915C00025E02F00F81018306 -+:10465000E006F5B7AD0184E006F577AB03BFDE02F7 -+:10466000F01126018D60020BF05F0188600E2B5166 -+:104670005A028181AB00108E018B60062B915C0386 -+:10468000BFDE02F0108F018B60022B915C0183E092 -+:1046900002F5B7AD0184E002F577AB00025E02F0EF -+:1046A00010590002DE02F0000000B0446B000B065F -+:1046B0000202DEB3001097018360062B915C0002BA -+:1046C0005E02F00F76020200BF00109F0183E0023D -+:1046D000F7F7BF0203C57300109D020080BF0010F2 -+:1046E0009D018B600E2B915C03BFDE02F0109E01DA -+:1046F0008B60022B915C0182E002F597AC0002DE38 -+:1047000002F0000001BC600300701001BC63FF1FD9 -+:10471000F0C501BC63FF1FF0CB00B040470010E5BF -+:1047200000B040470010EB01BC600300901001BCDA -+:1047300063FF1FF0C601BC63FF1FF0CC00B0404711 -+:104740000010E600B040470010EC01BC600300B070 -+:104750001001BC63FF1FF0C701BC63FF1FF0CD0059 -+:10476000B040470010E700B040470010ED01BC60CA -+:104770000300101000B0404300180001BC63FF1F8D -+:10478000F0C800B040470010E801BC6003003010E2 -+:1047900000B0404300180001BC63FF1FF0C900B027 -+:1047A00040470010E901BC600300501000B04043D6 -+:1047B00000180001BC63FF1FF0CA00B040470010A2 -+:1047C000EA0002DE02F0000001BC60030037A20034 -+:1047D00020E3FE0910FA0020E0420D90FA02804228 -+:1047E000030010FA028445230010FA03915E02F0E0 -+:1047F00010FA0068AB6F0010FA0282DEFF0010FAB8 -+:1048000002805EFF00112F020180C7001126028284 -+:10481000DEB30010FA020480C70010E700685E8B68 -+:104820000010D300B02BA30017A1006EAB8AF430A8 -+:10483000D30203C5730010E700682ABB0010D20042 -+:10484000682ADB0010D300E8446556D7A100E82AA7 -+:10485000BAF437A1006ADE8555F0E7006ADE855BB1 -+:1048600050E700682B070010E70203DE530010D664 -+:1048700000B02BA7000AAF03BFDE02F0112601BC77 -+:10488000600302579201BC63FF1FF0C301BC6003C9 -+:104890000910E301865E8A1C70E3018460061C70C7 -+:1048A000E300682B0F0010DD0185E0061C70E301BA -+:1048B000BC600303978200025E02F0110401BC6336 -+:1048C000FF1FF0C400B054130010E400E043915CFB -+:1048D00030E400025E02F010A001BC60030010EEA4 -+:1048E00001BC63FF1FF0CE00E02B0F002AC303BF03 -+:1048F000DE02F010F402835EB70010FA00025E02DE -+:10490000F000D400B05ECF0010E400682ABB0010B5 -+:10491000F100B02AFB0010E40280456F0010F100A6 -+:10492000E8446556D7A100E82ABAF437A100695EC9 -+:10493000870010F100E05E8557D0E401BC60030100 -+:10494000D78200025E02F0110403BFDE02F010F411 -+:1049500000B0004700108600025E02F011980002CD -+:104960005E02F00D8D0190600A0910480184600616 -+:10497000F597AC01BC61330070800002DE02F000EC -+:104980000002805EFF0010FF0281DEBB0010FF020C -+:104990000180C7001126020480C700112601806033 -+:1049A00002F7F7BF0280C28F0011270201DEBB00B1 -+:1049B000112701BC60030017A203BFDE02F010BD87 -+:1049C00001BC63FF1FF0C001BC63FF1FF0C1028583 -+:1049D000DEFF00111400685E4B06310D00B02B574E -+:1049E0000017A1006DAB0EF4311401BC6003013758 -+:1049F0008000B02B5B0017A1006D2B0EF4310F026D -+:104A0000812BF300110F01BC600301778001BC60B2 -+:104A10000300378100025E02F000AF01D2DE0AA07F -+:104A200030E000B0540B0010E103BFDE02F0111AB9 -+:104A30000280ABF300110D01BC600301578001BC83 -+:104A4000600300178100025E02F000AF00B054075F -+:104A50000010E000885E0B0070E10002DE02F00052 -+:104A60000000682B130011260204DEAF001126009F -+:104A7000E844655897A4006E5E9155F12600885E63 -+:104A8000930037A4006D5E9155F12600025E02F09E -+:104A9000115603BFDE02F0113300E844655897A4B5 -+:104AA00000885E930037A400025E02F0115603BF37 -+:104AB000DE02F011330284DEAF00112A0181E00230 -+:104AC000F5D7AE03BFDE02F0113300682B8700116B -+:104AD0002F00E044655C2ADB00682B8B00112E0060 -+:104AE000E044655B4ADB0002DE02F000000180600A -+:104AF00006F7F7BF00682B1300113300E844655830 -+:104B000097A400025E02F0115601846002F597AC92 -+:104B100001BC6003000AC401BC6003000ADB01BCE5 -+:104B20006003000AC30104DEAF0017A101835E86A3 -+:104B3000F5B7AD0284DEAF00113C018060060D9038 -+:104B40006C0002DE02F00000028600C700113E0287 -+:104B5000025EFF00114400B02AAF0017A302040058 -+:104B6000C300114100B02ACF0017A30202DEBB0030 -+:104B7000114300B02AAB0017A300E04466F46ABBFF -+:104B800000B04467000B0B0183E0022B915C02072D -+:104B900001AB0011480180E00209D04E0002DE02A4 -+:104BA000F000000202DEB300114C018360062B917D -+:104BB0005C00025E02F00F760203C5730011510221 -+:104BC00084DEAF0011510281DEBB00115102805E14 -+:104BD000FF00115102035EB7001155018B600E2BCF -+:104BE000915C01836006F5B7AD0184E002F577AB17 -+:104BF00001BC6003000AC30002DE02F0000000688E -+:104C00002B7B00115800B02B7B0017A4006D5E9128 -+:104C100056515A00B02ACB0017A400882B27003722 -+:104C2000A500E82B2AF4AACA00885E930037A400E6 -+:104C3000E02B2AF48ACA00902B2B00AAC900B02BC3 -+:104C400027000AAF0002DE02F000000286410700E2 -+:104C5000116101BC60130917A100025E02F000A2FD -+:104C6000018760060337A200025E02F000A800B0D0 -+:104C70005E870017A100B05E870017A100B05E87B5 -+:104C80000017A101876002F457A200025E02F00043 -+:104C9000A801BC60130957A100025E02F000A20146 -+:104CA0008060060337A200025E02F000A800E00266 -+:104CB000B30020AC01806002F457A200025E02F053 -+:104CC00000A801BC60270857A100025E02F000A204 -+:104CD0000068C06701F17901BC60030017A20002FF -+:104CE0005E02F000A801BC600301F7A200025E02B0 -+:104CF000F000A80002DE02F0000003905E02F01156 -+:104D00008D03875E02F0118D0390DE02F0118D029B -+:104D10000445230011840283C21F00118D0068A086 -+:104D2000B700118100B0446700082D00E844650514 -+:104D3000B7A1006E5E877D118803BFDE02F0118E81 -+:104D40000286C03700118D00E0446700D7A102063B -+:104D5000403700118D006CC466F4318600025E029B -+:104D6000F00B1600025E02F0116101BC6003000846 -+:104D70002D00025E02F00AD803BFDE02F00004013B -+:104D8000BC600300082D0002DE02F0000002804239 -+:104D900003001197028545230011960285DEB700B6 -+:104DA00011940185E006F5B7AD00E0446B002B21BE -+:104DB000006CC46964319700025E02F011610185E4 -+:104DC000E002F5B7AD0002DE02F00000010C814305 -+:104DD0000017A101BC600300508A00685E07001143 -+:104DE0009C00685E8700119C00685E070011A401AA -+:104DF00090422AA1308A00685E070031A4019042E7 -+:104E00002AA0108A0109DE030017A2018F5E8A1111 -+:104E1000508A00685E8B0011A40191E00E11508A47 -+:104E20000002DE02F000000109DE030017A400E02A -+:104E30005A06F497A500905E96F497A50203DE0348 -+:104E40000011AC0282DE030011AC01BC61EF085717 -+:104E5000A60080DE96F4D7A50116DE870017A30012 -+:104E6000885E870077A100E15E8702D7A100E0DEBF -+:104E70008F0017A301BC60030017A2020E5E03009F -+:104E800011B301BC60030037A200905E96F457A5F1 -+:104E90000080DE96F437A100E141B7FFF7A600E1FC -+:104EA000DE8701F7A10080DE96F477A300E1DE86BD -+:104EB0000DB7A100E0DE8F0017A3017A5E86F477BC -+:104EC000A100885E86F457A100B05E870017A20299 -+:104ED00087DE030011C000885E870057A103BFDE94 -+:104EE00002F011CD02875E030011C701BC639B0C69 -+:104EF000D7A50080DE86F4B7A100E141B7FFF7A592 -+:104F000000E0DE870017A100885E870057A103BF7D -+:104F1000DE02F011CD00885E870057A101BC639BC3 -+:104F20000CF7A50080DE86F4B7A101BC6203001770 -+:104F3000A500E141B6F4B7A500E0DE870017A100A7 -+:104F4000E05E8400D7A10002DE02F0000002002033 -+:104F50000F0000040282DE530011D50188600204B4 -+:104F6000902400E020AEF3082B00E820AAF3082AE2 -+:104F700003BFDE02F0096201B8601604902401BC90 -+:104F8000600301D02503055E02F011E70287C037F8 -+:104F9000000A860386DE02F00A8700025E02F00F36 -+:104FA0009500025E02F0117A035CDE02F011D70078 -+:104FB000D8409B0117A100E05E8702379800A85EE9 -+:104FC000630077980102DE530017A10182E002F22C -+:104FD00097940188DE85006803006EA0AAF311E7AC -+:104FE00000E85E6301D02501B8600604902403BF89 -+:104FF000DE02F000020181600500680301B8600A6A -+:1050000004902403BFDE02F0000202285E87001134 -+:10501000FD00B041930017A400E0419300706401CB -+:105020000A5E870017A200E84192F4506301185EFF -+:10503000870017A100E86042F437A200885602F406 -+:1050400036000068418EF491F900E8418F0030632A -+:1050500000E8419300306400685E8B0211F100901B -+:105060005602F457A300B05806F4760103BFDE02DF -+:10507000F011F100684192F491FD00E84193003095 -+:105080006401BC600300160003BFDE02F011F900EA -+:10509000B05E870017A10002DE02F0000001806010 -+:1050A0000286143000B050CB0010650138508300E8 -+:1050B00017A10068DE3B06320500E05A3300368C4B -+:1050C000006EDA32F4200400B05A0B0017A200E0A0 -+:1050D00001F700207D00E001D2F4407401BC63FFC1 -+:1050E0001FF7A300B050CF001064006EDA32F43224 -+:1050F0000C00B05A370017A300B0581300178201F4 -+:10510000BC600300160401BC601B09D7B60102D0C5 -+:10511000C70017A100E04196F4306500E050CB00D5 -+:10512000D06401BC60030017B401BC6003001780A9 -+:1051300001BC6003003781018760040310A0009068 -+:1051400052330097A400E0418701B7B500685ED2F2 -+:10515000F0523300E05EDAF690630020D802F032BD -+:1051600027020250C700122D009056030097A1009D -+:10517000E85E86F497A1019E6002F437A1006DDE1F -+:105180008708122D010A5E870017A201DA6002F477 -+:1051900037A100E05ED6F4506300886006F437A1C2 -+:1051A00000205602F4322D00B05802F0360000E024 -+:1051B0005A2B00368A006ADED2F472290068DED2E9 -+:1051C000F0122E00E05E0300378000685E030032BC -+:1051D0002E0186E0040310A003BFDE02F0122E00B1 -+:1051E0006ADED2F4722900E05ED30037B400D05EEC -+:1051F0000700378102985ED300121800E041930047 -+:10520000306403BFDE02F0121800685E0300000481 -+:1052100003BFDE02F005AB0282D0C700123D00B032 -+:105220002A4F0017A101B82A4AF43684010250130C -+:10523000001685013C50830017A100B050A700174D -+:10524000A4006D5A32F432460182E00686343102FF -+:1052500088502B00124200B05A330017A1019E5E05 -+:105260008684F427018360068634310002DE02F072 -+:10527000000000B050730017A101B8506EF43684DE -+:105280000106D00700168500B050AB0017A400D06F -+:105290006006C0978000E0419700D7B5010A581317 -+:1052A0000017A100E05ED6F437B500B0580F00102B -+:1052B00063011656030017810068D81300125B01C2 -+:1052C0001400630017A10068DE87001251008801F6 -+:1052D0003B01168003BFDE02F012560068DE870035 -+:1052E000725400A0013BE0168003BFDE02F01256AC -+:1052F00000E05E870970620088540301168000E8B0 -+:105300005A0330168001BC600300168101BC6003A3 -+:1053100000168201BC600300168303BFDE02F01298 -+:105320006000E0418EC09063006EC18EC0326000AC -+:10533000E8418EC0306300E858030037A100E04127 -+:105340008EF43063013850A30017A500685813038A -+:10535000F27B0068418EC0527B006DDA0AF4B27BAA -+:10536000011656030017A10068DE86F0327B015853 -+:1053700056030017A100E05E870DD7A200B05ED7EC -+:105380000010620020DE02A0127200E05E86D037BC -+:10539000A300E05E8ED077A3006D5A02F4527B002A -+:1053A0006E5E8EF4927B00E86002F4368300B05E9D -+:1053B0008F00168100A05A0F00768300E05A0B0080 -+:1053C000368200E85A02F4568000D05E030037802F -+:1053D00000E0581300360400E0418F00306302986B -+:1053E000581300127800E05ED70037B5006EC18E0A -+:1053F000C0326100B0580300106303BFDE02F01238 -+:105400006100B058130017A10068DA3700127E005F -+:10541000B05E8700168D006DDE86D1B28000B05E72 -+:105420008700168D0002DE02F0000001BC60030060 -+:1054300017A1018760040310A001BC60030990B5A7 -+:1054400000B0006300F0B401BC60570490B601BC2A -+:1054500060030090B500B0006300B0B400B042D368 -+:105460000018000317DE02F012890397DE02F01223 -+:105470008A00B02A4B00142F018EE00C0310A0000C -+:105480006DDE02D1B29000E85A36F0168D03BFDE11 -+:1054900002F0129201BC600300168C01BC60030094 -+:1054A000168D006E5A3AF0129501BC600300168EFC -+:1054B00003BFDE02F0129600E85A3AF0168E00B0F2 -+:1054C00058070017A100E0580EF01603006ED80E22 -+:1054D000F4329C00E85E86C017A100E8580EF4364E -+:1054E0000300E8580F00360301185E030017A100FF -+:1054F0006DDE030212A400E86042F437A200905A65 -+:105500001AF4368600885A1EF457A200905A1EF4E8 -+:10551000368700B05A1AF4568603BFDE02F012A690 -+:1055200000905A1EF4368601BC6003001687000204 -+:10553000DE02F000000158600300102A01B8600A82 -+:1055400004902401BC60030290040189E0020D90E4 -+:105550006C0002DE02F000000200DE530012D101F6 -+:10556000BC601309B7A100025E02F000A201A560B1 -+:10557000020337A20199E002F457A200025E02F092 -+:1055800000A801BC60130997A100025E02F000A20E -+:1055900001A4607E0337A20199E03EF457A2000205 -+:1055A0005E02F000A801BC601316F7A100025E02C3 -+:1055B000F000A201B460020337A200025E02F00014 -+:1055C000A801BC60131637A100025E02F000A20120 -+:1055D00086E0020337A201856002F457A200025E52 -+:1055E00002F000A801BC60131617A100025E02F0D1 -+:1055F00000A20181E0060337A20185E006F457A26C -+:1056000001836006F457A200025E02F000A801BC0C -+:1056100060131F57A100025E02F000A20181E002A8 -+:105620000337A2028600C70012CB0181E0060337D0 -+:10563000A200025E02F000A801BC60131F37A100A7 -+:10564000025E02F000A20181E0060337A200025EC2 -+:1056500002F000A80002DE02F0000001BC601309A5 -+:1056600097A100025E02F000A201A460020337A22B -+:105670000199E002F457A201886002F457A20002E7 -+:105680005E02F000A801BC60131617A100025E02C2 -+:10569000F000A20181E0020337A20185E002F45785 -+:1056A000A201836002F457A200025E02F000A80289 -+:1056B0000600C70012E201BC60131F37A100025EA2 -+:1056C00002F000A20181E0020337A200025E02F0B4 -+:1056D00000A80002DE02F000000200DE530012D13A -+:1056E00001BC601309B7A100025E02F000A20187AD -+:1056F00060020337A20181E002F457A2018860062C -+:10570000F457A200025E02F000A801BC60130997E2 -+:10571000A100025E02F000A2020400C70012EF0125 -+:1057200088600E0337A203BFDE02F012F10186602B -+:10573000060337A20181E006F457A200025E02F0E0 -+:1057400000A803BFDE02F012C60068DE930012F765 -+:1057500000E05E030057A201095E8B0017A103BFA2 -+:10576000DE02F012FF0068DE930032FB01105E03E0 -+:105770000017A200E05E8B0097A103BFDE02F012CB -+:10578000FF01305E030017A200E05E8B0197A100CD -+:105790006D5E870592FF01BC60030597A10002DEE4 -+:1057A00002F000000200456F00130B02872C0F006F -+:1057B000130B01BC60130217A100025E02F000A2ED -+:1057C0000200C06700130B0287AC0F00130801082A -+:1057D0004067000B030187E005606B0301886006EA -+:1057E0000337A200025E02F000A801876005606B2B -+:1057F000030002DE02F0000000682BEB0013110032 -+:10580000B02C130017A100E05E8560B7A1006BDE2D -+:10581000862333110186E006F7F7BF0002DE02F0AF -+:10582000000000B05E8F00106400B05E870017A318 -+:1058300000B05E8B00106500B05A030017A100682D -+:10584000419300131A00025E02F000A200B040670C -+:1058500000160100E0419300506400B05A070017A1 -+:10586000A200025E02F000A800E04197005065002F -+:10587000E85E8F0037A30068DE8F0013150002DE9C -+:1058800002F0000000B05E8F00106400B05E870080 -+:1058900017A300B05E8B00106500B05A030017809C -+:1058A0000068419300132800025E02F00E3F00B032 -+:1058B0005E0700160100E0419300506400B05A07F3 -+:1058C00000178100025E02F00E4400E04197005094 -+:1058D0006500E85E8F0037A30068DE8F00132300A9 -+:1058E00002DE02F00000020200BF0001880203C5D0 -+:1058F000730001B1000000000000000057860000A6 -+:10590000A5C1E142055AC359DC0175513E5B2349EB -+:105910004728676945005E55F8F5C97D420AB30915 -+:1059200001BD32080100343333363261322D726FDB -+:105930006D6C2F7364696F2D672D706E6F2D706B9A -+:105940007466696C7465722D6B656570616C6976DF -+:10595000652D776170692D776D652D7032702056D9 -+:10596000657273696F6E3A20352E39302E313935B4 -+:105970002E3839204352433A20626431653365350D -+:105980006120446174653A204D6F6E2032303133AE -+:105990002D30342D32322031373A32343A343420FB -+:0559A0004353547D009B -+:00000001FF -diff --git a/firmware/ap6210/nvram_ap6210.txt.ihex b/firmware/ap6210/nvram_ap6210.txt.ihex -new file mode 100644 -index 0000000..250c1e9 ---- /dev/null -+++ b/firmware/ap6210/nvram_ap6210.txt.ihex -@@ -0,0 +1,75 @@ -+:10000000234150363231305F4E5652414D5F5631AA -+:100010002E325F30333139323031330D0A6D616E3B -+:100020006669643D30783264300D0A70726F6469BD -+:10003000643D30783439320D0A76656E6469643D0A -+:100040003078313465340D0A64657669643D307802 -+:10005000343334330D0A626F617264747970653DB4 -+:100060003078303539380D0A0D0A2320426F61721D -+:1000700064205265766973696F6E2069732050330E -+:1000800030372C2073616D65206E7672616D20664D -+:10009000696C652063616E206265207573656420FC -+:1000A000666F7220503330342C20503330352C2082 -+:1000B0005033303620616E64205033303720617306 -+:1000C0002074686520747373692070612070617298 -+:1000D000616D732075736564206172652073616D55 -+:1000E000650D0A23506C6561736520666F726365E8 -+:1000F00020746865206175746F6D61746963205246 -+:100100005820504552206461746120746F207468D7 -+:1001100065207265737065637469766520626F61CE -+:100120007264206469726563746F727920696620F5 -+:100130006E6F74207573696E67205033303720629C -+:100140006F6172642C20666F7220652E672E2066A8 -+:100150006F72205033303520626F61726473206695 -+:100160006F72636520746865206461746120696ED4 -+:10017000746F2074686520666F6C6C6F77696E674A -+:10018000206469726563746F7279202F70726F6A70 -+:10019000656374732F42434D34333336322F6131EC -+:1001A0005F6C6162646174612F626F617264746517 -+:1001B0007374732F726573756C74732F7364675FD8 -+:1001C000726576303330350D0A626F617264726524 -+:1001D000763D3078313330370D0A626F6172646E6C -+:1001E000756D3D3737370D0A7874616C66726571CD -+:1001F0003D32363030300D0A626F617264666C6178 -+:1002000067733D307838303230310D0A626F617279 -+:1002100064666C616773323D307838300D0A7372F2 -+:100220006F6D7265763D330D0A776C3069643D30D1 -+:1002300078343331620D0A6D6163616464723D30FC -+:10024000303A39303A34633A30373A37313A31322A -+:100250000D0A616132673D310D0A6167303D320D33 -+:100260000A6D617870326761303D37340D0A63631F -+:100270006B3267706F3D3078323232320D0A6F6602 -+:10028000646D3267706F3D307834343434343434D4 -+:10029000340D0A6D63733267706F303D30783636D7 -+:1002A00036360D0A6D63733267706F313D307836C4 -+:1002B0003636360D0A7061306D61787077723D3573 -+:1002C000360D0A0D0A23503230372050412070611C -+:1002D00072616D730D0A2370613062303D353434C4 -+:1002E000370D0A2370613062313D2D3635380D0AE5 -+:1002F0002370613062323D2D3137353C6469763E82 -+:100300003C2F6469763E0D0A0D0A2353616D65200A -+:10031000504120706172616D7320666F722050339E -+:1003200030342C503330352C20503330362C205084 -+:100330003330370D0A0D0A70613062303D35343488 -+:10034000370D0A70613062313D2D3630370D0A703D -+:10035000613062323D2D3136300D0A706130697482 -+:10036000737369743D36320D0A7061316974737349 -+:1003700069743D36320D0A0D0A0D0A63636B5077BE -+:10038000724F66667365743D350D0A63636F64650D -+:100390003D300D0A72737369736D6632673D307854 -+:1003A000610D0A72737369736D6332673D30783320 -+:1003B0000D0A7273736973617632673D3078370D59 -+:1003C0000A747269736F32673D300D0A6E6F69731C -+:1003D000655F63616C5F656E61626C655F32673D2E -+:1003E000300D0A6E6F6973655F63616C5F706F5F7C -+:1003F00032673D300D0A73776374726C6D61705FA4 -+:1004000032673D307830343034303430342C30780A -+:1004100030323032303230322C307830323032308C -+:100420003230322C30783031303130312C3078313C -+:1004300066660D0A74656D705F6164643D323937BC -+:1004400036370D0A74656D705F6D756C743D3432AE -+:10045000350D0A0D0A6274635F666C6167733D3027 -+:1004600078360D0A6274635F706172616D73303D3E -+:10047000353030300D0A6274635F706172616D7384 -+:10048000313D313030300D0A6274635F70617261EA -+:0A0490006D73363D36330D0A0D0A78 -+:00000001FF diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index 8a48129b..b7f3737c 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -692,7 +692,6 @@ CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y -CONFIG_NETLABEL=y # CONFIG_ANDROID_PARANOID_NETWORK is not set CONFIG_NET_ACTIVITY_STATS=y CONFIG_NETWORK_SECMARK=y @@ -833,6 +832,40 @@ CONFIG_IP_VS_IPV6=y # CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 +# +# IPVS transport protocol load balancing support +# +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +# CONFIG_IP_VS_PROTO_AH_ESP is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_AH is not set +# CONFIG_IP_VS_PROTO_SCTP is not set + +# +# IPVS scheduler +# +# CONFIG_IP_VS_RR is not set +# CONFIG_IP_VS_WRR is not set +# CONFIG_IP_VS_LC is not set +# CONFIG_IP_VS_WLC is not set +# CONFIG_IP_VS_LBLC is not set +# CONFIG_IP_VS_LBLCR is not set +# CONFIG_IP_VS_DH is not set +# CONFIG_IP_VS_SH is not set +# CONFIG_IP_VS_SED is not set +# CONFIG_IP_VS_NQ is not set + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +# CONFIG_IP_VS_NFCT is not set + # # IP: Netfilter Configuration # @@ -871,7 +904,6 @@ CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m @@ -898,7 +930,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_REJECT_SKERR=y CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1312,7 +1343,8 @@ CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=y CONFIG_PPP_MULTILINK=y CONFIG_PPPOE=y -CONFIG_PPPOL2TP=y +# CONFIG_PPTP is not set +CONFIG_PPPOL2TP=m CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_PPP_ASYNC=y @@ -1953,7 +1985,7 @@ CONFIG_WATCHDOG=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_SUNXI_WDT=m +CONFIG_SUNXI_WDT=y # # USB-based Watchdog Cards @@ -2697,7 +2729,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_DEV_UIE_EMUL=y # CONFIG_RTC_DRV_TEST is not set # @@ -2955,6 +2987,7 @@ CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_V4_1 is not set +# CONFIG_ROOT_NFS is not set # CONFIG_NFS_FSCACHE is not set # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y @@ -3238,7 +3271,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -CONFIG_CRYPTO_SHA1=yCONFIG_DW_DMAC +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3320,9 +3353,9 @@ CONFIG_XZ_DEC_BCJ=y CONFIG_DECOMPRESS_GZIP=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=y -CONFIG_TEXTSEARCH_BM=y -CONFIG_TEXTSEARCH_FSM=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/linux-3.4/arch/arm/mach-sunxi/Makefile b/linux-3.4/arch/arm/mach-sunxi/Makefile index 43bd7a6a..7a50c26b 100755 --- a/linux-3.4/arch/arm/mach-sunxi/Makefile +++ b/linux-3.4/arch/arm/mach-sunxi/Makefile @@ -49,7 +49,7 @@ obj-y += sunxi-headsmp.o sunxi-platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += sunxi-hotplug.o endif -obj-y += sys_config.o sunxi_dump_reg.o sunxi-chip.o sunxi_sram.o sunxi-debug.o +obj-y += sys_config.o sunxi_dump_reg.o sunxi-chip.o sunxi_sram.o obj-$(CONFIG_SUNXI_TRUSTZONE) += firmware.o obj-$(CONFIG_SUNXI_TRUSTZONE) += sunxi-smc.o diff --git a/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c b/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c index 74f3ac57..9bd04cd0 100755 --- a/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c +++ b/linux-3.4/drivers/cpufreq/sunxi-cpufreq.c @@ -609,6 +609,11 @@ static int sunxi_cpufreq_resume(struct cpufreq_policy *policy) #endif /* #ifdef CONFIG_PM */ +static struct freq_attr *sunxi_cpufreq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + static struct cpufreq_driver sunxi_cpufreq_driver = { .name = "cpufreq-sunxi", @@ -620,6 +625,7 @@ static struct cpufreq_driver sunxi_cpufreq_driver = { .getavg = sunxi_cpufreq_getavg, .suspend = sunxi_cpufreq_suspend, .resume = sunxi_cpufreq_resume, + .attr = sunxi_cpufreq_attr, }; diff --git a/linux-3.4/drivers/devfreq/dramfreq/sunxi-ddrfreq.c b/linux-3.4/drivers/devfreq/dramfreq/sunxi-ddrfreq.c index f0d04a1c..528b8120 100755 --- a/linux-3.4/drivers/devfreq/dramfreq/sunxi-ddrfreq.c +++ b/linux-3.4/drivers/devfreq/dramfreq/sunxi-ddrfreq.c @@ -43,7 +43,8 @@ enum { DEBUG_FREQ = 1U << 0, DEBUG_SUSPEND = 1U << 1, }; -static int debug_mask = DEBUG_FREQ | DEBUG_SUSPEND; +// static int debug_mask = DEBUG_FREQ | DEBUG_SUSPEND; +static int debug_mask = 0; module_param(debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); #define DDRFREQ_DBG(mask,format,args...) \ do { if (mask & debug_mask) printk("[ddrfreq] "format,##args); } while (0) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index b1c2b1f3..49308167 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -4628,7 +4628,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) { case CSI_SUBDEV_STBY_ON: vfe_dev_dbg("CSI_SUBDEV_STBY_ON\n"); - vfe_dev_print("disalbe oe!\n"); + vfe_dev_dbg("disalbe oe!\n"); ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); if(ret < 0) vfe_dev_err("disalbe oe falied!\n"); @@ -4651,7 +4651,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) vfe_set_mclk_freq(sd, (MCLK*1000*1000)); vfe_set_mclk(sd,ON); usleep_range(10000,12000); - vfe_dev_print("enable oe!\n"); + vfe_dev_dbg("enable oe!\n"); ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); if(ret < 0) vfe_dev_err("enable oe falied!\n"); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h index d5580bde..86a7ece7 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h @@ -31,7 +31,7 @@ #endif #ifdef ISP_DGB_FL -#define FUNCTION_LOG do { printk("%s, line: %d\n", __FUNCTION__, __LINE__); } while(0) +#define FUNCTION_LOG do { pr_debug("%s, line: %d\n", __FUNCTION__, __LINE__); } while(0) #else #define FUNCTION_LOG #endif diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 b/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 old mode 100755 new mode 100644 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 b/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 old mode 100755 new mode 100644 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp b/linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp old mode 100755 new mode 100644 index 1e816099475efaca9700062c4cb4113cf0bafa09..ae490c144d7765dda879b3550931bb95f6122d87 GIT binary patch literal 607408 zcmeFa4SXEMl`q=!p%2T0J+_q_hj_ynltdxQGBOTv5^osWG8kgQ_#;3Pzi39%$QF^M zL6X7ba+i_hFKmm9CD{hsikpw@W3$<0Y)F>PBfH}dh%tT%EM%8UxOZ!M=oK;S#Fjb?VgV@xrC)fzC}|Xt*lo{I7NK z)vecD^Vw?_Es4eA1|$ z3H>|!tNDjFmG}SN*TMTX@V*WFd$57pPpHcKfA8zye+nD;#_LM$`+x82;C&l--v<7z zY~a)prS|>5_jT~T4ZLpy{~y~x-G}c{-v4`F2k+a!`!?`zZUcj_DRuAvy|07+8EoK3 zjY^&P_mk(9I{N#EbN^<4^?Hl)|EIqhb8^bRtG|W6S7wNRpShsSkpHDK?Y%vHnMFfA zn=?wsmY&|O_M!eQotxV4%Jgj9G^8vW7)al}Zp&t6MStI&%Bpl6op`%$Ne?L3XNJB+5^w77%G_$ozHv*} z#?10`=QmaxRgnmYGpi>#tNI6ezS-Y5lrXvExk%-e_wacMqaWnvvsH)a{C9j3}jr`rmg`$s8XW6eSKzdXjx``N3XIh)83ID z%(VCSwGX8`dNWFT%TT{90cu-)3z$~)XYV!&TsP3a`G&q8kk(}^5$IM=Uk~)39!PIi zhDh{ErKhhev(?ZiD!H|%@22$NHx#scAhUVP=Jq?$>B<9GmCh{#0~oCKBw2&iF8;m! zn)s$~QbQ|*PrC>JZ|UjE^qU1&q_aa%jQNlp$lTeJxyy~TWx7$w2I+a_)+`y;mO-sw(DcRrCH#Dep(?fgb z&{k#Hb?e&Ou3OJP+uJfjFb^14x^Jkby}P%k^Bb9g_H^$?CEY#9X92X<*JVtUc37Jt zJPyK6hx%cnCfZkd6nG4xA%VVSsYUH+npac>wf(M+>oAv$S&+;O3}!Ix?&_eCr+Hyh zk^}vnnZZF96?~+%8~VEYso0AC0jSkr?CINRO21)ndAbWWuo~4H)o}t9Sex10ez7jd6t{(mj34w{&-N(O8KFhXz0-fa-^oTMaI| zb?d&-(`N`H5*1wRpul!+?SNvtGZ>ams~*g%A?2KUSG-kYY%z*OlcJ*>hglS+7Z?7lz%CpwzH za_bQ6(Wrw27++Rw8MxDs?J^ICZS)zIg@MM3zMP7hU$3{nuBERS69dJk0pWA4vN@f_ z9NgHR?&=ya9(w!JUF}_1a%|FI`p%3jAf0!cJ&NazQf9)%^{3I8ag4AD71vp zOz*neAZ_%Lwq(1~P^P(7@?!m4hO%3R+6S{4WLFTe(_DfuD*ai5&@*s{*b;gaTSHTl zDiaz@kHkg;i-p9H+B@JTQKJn-7;53|G4;PFY zHe|a7qp014{-N&nF8gs2Od-?P--F!^z5<52BC8{PHx}8An7{4)-Q8$?1-X06ol-hx z7_l3CG%}`!MJnk4&z-$J=7`gC@1WTlyF_Pqx_vXMg(fO>%4l6Z1MNebT-6aHIXOd_ ztu7>un$vgM6%TGo57ewe+85DS$TUFPj=dLEiVR_if%B4ajvcoCj)5Mu zbRaWmwwAgL>Rr^w%tm)J{eaHCfp%l0D)ptiq2nxewap?)6l>Ikeq#&tGyvqTp6+gu zZjS*e%T>q;x{Fq7!b}`+HVLBKZ8BztNF3;gy};_>)edHQjqVsE(p29@xLhyrFh;4HF1k?yTsN?7Xr*(6UNyn}K4Q zVKE|-VdG{AW8@u6fI$(K3DY>>(^jhBi(=0=?Foxr)sjj>7nla0rLGe zVxhzW;>5cK?i48988Q#-#)fM}<+<4QEIFb5)+$c@HkIEhsF^ty{#guw^c;-w#t?u)^AG?shcYjL>&;-+XkX~+h9v@%QYpq zsb0-c%bc1anNG^kMi;@D@;HtO`ZV`P*uFqBY|T6L2HD#~(=t7SF9;EPBM9-3y}dNJ z(J4{SoF*2h&A{1rzIB-UrqDSK(4Ml`hkmsWeUT4cY@R6J*+g=Y2COaFSRQEaaB3bD zXE*qk=pxgW<6^{~i~Uw;Ann575!--$-c=0yf>RC%q#3bC7D*J;Z94PV%0*S#R8dhj zRTOGdMY*))p*(bDC6<*R3mh7ICi} zuZ)hquI_fMad!!AHE09a|2;(KaG9>8YYa_y(?!J2-rA1MsIxb{Iol4&bOteZDF*^~ z%NH8(g)34VlOZh{9Y z?X8t(YsacQi*?!j@d_^1CG7tOZtvTse0mn;)3Yew<~QZr{Pwfh7i(9q)W!Q{?&JoU z@8R|XnS}8qY`JFhgw0kUhz%5qm@N{D2n4Z>1_v4@NW_!LZ0*BFYxqWJ&QJ%**n2&c zt38xO9*S8h7j3Mz1`lneGyy9QTqov^YLLaf)F4>9s0o_;XXSgPOV*xg0Osz*zZz@5 z_+aY5-r39!+0SNo>}Rtx_Oqo!YY#Le^WCrVfEBFry)y8`#ZMu8M>B=Pv% zvEmm4odV64C=z9*O&Zp6ai1~T$afgy!P;Al?_jR<+_|4{*xX|(Pp&;gpgVRCPB-=q z{$QJcu~!&mYnR~Pd1LIQ-ZTxzB3~g{n}=x+4wedu3#^39DyzOxXp9#o zr$Y?lcsXnn@?z%j8pi1aE0%A>>!p}n6XrPc*s-&qF(g*h$ca!dgb1AkgeJ^bof9*o zUQ)H2kbf(M$evTCGsfq{#Au%rq0Uv}e!dVQfL@GtE6EtxF;P1@>n!XJ6*|#MRMAOx z1v;G|^}-Q9^}@6#^XRG^9jt_Dow(g0k|73ptMLhuVkaB5wYnhAQC&oLweHwaaA)O0 zU+kE=lf|h0T|gmt?=9>M`FnBKO@Ws|bSJHiUSfXSeUw1vHHK5L&~uC;U3&Q8;&q9W zhg4(Tuy_ISI>w3GRr~XhXu9@smLw|0zP(iR!MHMVB6dx{$!C<8^g+0D>aTO}1(>sb zYOnYD%*$ilxOoBVX3h(U*LYskD8}ysy)d1$EBA+9*uHS|V#cascve0b)_;kT-42zv zuyC>J1nn)J&QDH^^vk^iI#Ib$<8sC6L6N`1?=+aga>E(u7qnEt!fg z`Fs+3$wr{aX?TuV<+d0H=vJjU*<6)KoR-Q2bFn%?M9xNW$O;xYL09z03;G@6XZPC(3l30Y$)ZY7_y#Bd5sYcXSnbUfBT@E`zET z11}=o6{`^;BkD$Pukcuf2>M5YL@sGSNo0^kq(t1Aj_T|-bxTN0b%KIU+z~T}e0Mm` z1v=xB4iKvLgaO?Q-jF2c5ZYHwkdw_{oS_R6NxJ-A4!mw7pCRf6HIr2G!jPQ zt8)-c2hI`P;KfWxzMe`0%9Vns%X0oGht^r4EYi*kdL!)|G3E!)uyqO)ph~1&EanQn zaL5%Y=VW^{-2r&cArHWF)ZYK?02IflrGiuJQjFV`=B0RyNjgRxl#dcsC<{Pw(S89a zj@tn!qR0YJoRgGgZ2GQFkzHCRC12b+FZtrusmT|&PNKfJbsqJ_t#gzw4o6#x*=I`U zL7(e{@M?V{yjtIE`OYYTSH3@9t#5Qjt2Q=-S8G4v)!J{%m$%QB?~hk&Kk3JBY)G~r zW-OysK|8a~xzv~*q@CC1L}_P-*iTE1#R3;s19|$XRP3T^CFKTa)hX95X|J;6NM#d; zuw41-lXP8O5^=m2NzTk?ry967W96<$7aQRX8@Zyn5W2&WYg^=yt6b!e>s{oKE1ze0 zN%c;kuZ@X0)lLQ3zM$_&aZl2h!I_Hfluw?qos{jxVES@(P(grlO*pf-ol?#DB-Ifh z8bf)77AUWfA5-K-IqF~5v_JpSCN3}U-(*7MWvbOzt*%N+n^b?Elx(Nw4cKpqv{T@u zqRkVizlk}L+{hiK)NN<=&NRA8YIRj6x&Psm^ z72MfGX784?Gu`P{9_Px?%h`hz*s#s33tJQ?a z+eV1IZMHOb3v6jJMBX;)saKmM$xG!Vh`*EIRGj5Vx_B)w(cLlbJi55~iwrKwm25A* z1eh+Qt1x#S^HWy+zh7y`vwp^}UX2k(?$+cZS8Q>j! z+ud{V+m4x@`JaSqTuHB86KRfptCuX2UxV&!-B#+x2a9dXE|!IqJU*#RyNhk3d%b9njN4=&J|9pC~b*#QDa zWoq;6052w2B=y*Ifz9jyp;M-a%?@z!NV5Z6JltEd93V*(EU(Ok*!OXAoW_ToJo*JFZ?~-M z09RYA>;Qpk*Fyd#|E(yAysD_39pEck$PSS5(CNp@4iIqaWFZgUo2PZ3J-1OPibKmy7~i7NDD2MDF5*#QD>Wd~Rk zPj-O7>BtTc=wy1H8)z49h1~4Wrwg|NZ@#z{%=E>rkftwgh2ng1oMEJx9hMYg#X{Q& zuhuuhtM$#6F9e#U^8N8@eWS2gwXq?*TKfsF)_z;QynVKOf4o}zNk4vLL$duaV;QXq zIdPT4SHAirU00Vx z9PdSvCp$n;1NUakBf7M~oW%&qzAJ}Z+oBA)%0&*j-bD_%Y4d=sw2@ZW)(`WuT-z7) z9VzZf`Z9R31B3yvg1XXX@ffZY^dtZXLg85X^#_m^wf=bNzvb2~h%KUCTl93|` zu86a*6j$8YkI$6=;OvPr0YJcTYV_Nv0aYvJXZDWpvwZb%u*j#g8K;)^l|oE@fI9&| z=&9gEyABP6SU#ErvAi=0V)@Jx#PXIUh~%-(qxFdZPZh*Hc66~%KcbZCk(Q6MI&gc;=8)o zxz{Qu8#mj66z-|YxfjXFZWG{ssf(NXUhyL(n9GB7agdJuN)uMSw2%NG^p-nv<|gc_ zkb{P|Sp_o^03<@GoLga{Ot;oV%xzHIpL8|D@+7@fuQ55jM^_2aZ*)OI0)Ws*%U5*q zaxc+E7H;}Q5#~+5KrwwqS7GiY%E@j$ao^9aTTYkpTi%(g0>KY-A%+Jip}A$t7xNjGR#EF{s?f$TFqwWh!P{Gxb)GVN~ znnk#}Y&Yui&0HGcUYUz5-1G}wG(9mFtIG%TLnU;V-zDYn-1Iw}Q@QDPlKD-)KsEg< zR~?pT<)wO!&EYD!XPg6cPYu(9a@8TZo~v93x>)&jKELS~I>jOBl3xAtQM~CFB+}H8 z-1G|^-kW|G=y#P$-kp8ZFBGbBdF#CC7s@zp`ki!s)9<2I(mI#Oe+Ph*y*K^%*B&@1 zx#_o1=S{yr6oT0Tm4exhn|>GOyv!Fs3hDcT?wfw0oEWa>H~j)^NBS$j13-PIUO8|2 zg)#)ld*{9B7m862oHzXf=)LI|KapqTR(=P74@(8&ONk(pFvm^53xoINxaoJn#{MbX^t)ikO}`7nZoqH) zU5M+Z--Vi6Hm!Uvz`p5s0n(d(7mxI&-^IhdCE-%p#bJ46uEyDSYjT{%fSf$*rr#yg zy6JaOt($%q6{f*|c8(9eT{*d-LIQxRXm!+101%2fMGFZ4QXV?}*gp@zn@4@GBmfBI zh|b+_mpY9i^s2e|^8lhe@x3njEH89NxH) z03dY407;WP0YJdaGqZiU?1ALVtTzEbEQq?S^S1r-0KA)?1OTC+D*-@23}bixJOCFc zK$V{d5HVV=cmjYRQA_|3$o6PD5aNdka?+HQgU^8jLNggAtIK8pzeqD1Q-Fq4iE z&km4}5~;?M03e8#CIASy{qq3S1y2Hi!0AW;5a?ujo=avIZiU?Jz^Dti0&l*!70mR- zt&pZKZiV7}aU5-=m>rfBV#Pw+39r^S!mIVomM;XFrSkppYJH=yShcYsyjuGSuhxEB zzPx?5e1E)J`$<23V?(n2Fk>053Oeo;1dUgMs8V~d;+oE%2jFwx0)+$sL9PV~SJGZ^ zQMEed255eW2UZN*5A$1c93gA@>fvCKPiHf>Ev=ivQhtCtJ3#2E;9|Q@6ogm~ zoCL94Hwj`n)DpyUr6q{vs7Vm$(?zu%TjN?l=nEn8784?Gu`SKGN03UBA@UZJt719D zu2vHwZyO=yIB01S@0^DhJaZ}$bPNoENxtA^u(ve?j!m5`RvI7L2aWBu@gk2SK&~QboVEpF+ zxC+H`ZiR`MTWccbHYo0Fx|(6RnO>^bn4GSqtAyxOx*#DtKv10JNV<3}FVWpG?mW7< zDZ(qUdLfrUtg!N{0bI?dXX%p3eM&jmtyS(Rx*N>tGJeaKb5$UCjV{FS7bP^eY`I*^ zJ9L$=_=PfhC6_?Z9`^-Z{I(b90&M@!1vtGr{_Z{>5+_=Dci#s#?(Bs|I!jAX!7-E6 zETFQQMYy_bH|p}_TpHm%oQo{v5(r&1{Wce?%VYCHC3HzHfwMBVf991@$t7?VwEyiL zK6<7%=8|CfVP2|t0dhE2?iuF*-BZK#w_J5dE&wYRjxJW7Fu-#OgsyT(x&c(b-V}2Q z1c@|tB)J3vhc}nN1^Qjqk}qiI5(tH=Tn{^Q34}6^TmmPZ=MuQ66(8_3@>~K=mgW+0 zP@YRbs3(_z6PsDUc z?hwiFUfas~JlDybjoMmW5a*~a!tp}8YuLzRcie>Y%7wnTZ_+u7QTw}qo@;!uuq+Kg z#HD!zB7=BDai$}PT>La)ZNnlY=0|Y4&~uEUomb(-=^)|E&EPzw8b@M>2v9L+wg^Y< zs{MILw4I{DOA^&iXA!CBgOL8h5xXYfbS97}#~q)YqnIaxD~GS#jT*FFKz|fd~qB{q?jFebVh@D+X=7MH^Qs+&6e*BC41%jPEsaMmywYTdyv1a0)|7Vjg%Ek$2$8qVmga7O zElq~V+eSV0YLg^+sl;2ESgxKB=9*G24wC6tny~7nB~#HQpHD(BnZHIOIPQ*F<+d0H z=vJjU*<6)KoR-S**u~1@Q$pyfVp{|0&Fuqs$z4KejER>d(C-jWGu9Df;)SY&4LmU> zUdA0`66ivVNu(miL~$Um^WvcP^z{rGeB@Pk4fNcZ8E_Ws+%jNN;FfL4wp-fWbeF+p zJyq&3q_wx-FqmDJ8EWgs4E6MF98^r6b^X2Rfu3)gIol>_ z`K=b#mg!D!=^a{elOZ9U&Gz2y6oJE0ch5#7g!lFjv~Nx$A9kz2YLG2zyZIu@U_WJ# zql{t_=#bVkIKZDW;sZ_)0@N)$4EEvFX=B~#K|~i^wBGdKCV}V9o~}$kLJ;YWo?hNt zvk9B~>0h&J@5&5iI?aI~$)qw0tZhbI&Ke)9vz2E{^~UoG(g5^E#d^@m^uR#+ZsUnm z-j(TAXdo8dFxbDoqgTOL3}pt|hdO!Vk-0^sw<7uV% z)L~SYZMR%*{>Ytd{!H`0#X=-E8~4#&teos-H&yC9NAMcm7{Z7g>e-y$h#%rjXYr;0 zHfYMo@Wq5;G&_VyCznP?6$zOFhZ3?7yyOCi?QyES4|jk6jwHzUZHeo?xyy@&*BCo|%8BE2I$m@%VxBDHICT3EZ?h!B1iA^M45d%<@jl0sG(+;x{> z9E>Zfv3Tej#0eO)n^%(Ailu-**g+66+#*MLoX3muFo_qT;2p(}eZQ2)SSd#fL?NC1p#y8An~3>qPA z`bU{<9d#QUEcQT;GP#l^g*Fam`Uc@DaHA09RZ6*3Y12Cf`!R>b>THY#9Y)$e&@&_s zjoJ9Lx1mua@g=mkG9W7gr33nZ)OJi z%@SQ*&_4djW8xm%(lIoU?yNj-hKJmf?d|C_U1;U1t78AR{#&#tZtPl;nW8B58*oj;k|h$AY6ib0Df{20BTO$h1Qh;XKxtO&Cq;RAPmrLR#RfyOa*5KQyuC25cNNw0g_}S1tA+pNCN2E@P1g9H5K~Lh)Rg|^=yq-Us9GAnLoL;WRydXQK ze>2O<+j}!C5gXIO$ua$br<>W5=$O7VF{bB~y=+IPTAHzMFZHnN5&ik8&;fF+Hx1>5Cyh9G%jSglfyNhT;Z>}1Wr8`QlllHb8X+3hS&^xQCO0sRZ#zfoK9ZPbz2&K46rHO#2K zkh+`I=RuEdXNlyPHfzmx7Rukp6y>WWMO7bCl-o*5PJJk#e6<`<)yEa(YbB*X^skhZ zJbm6;QnK`UOG!!5=lT-#kIywFC8|DD&+gZf7k=^90@N8$zE%zt)W-wLSIU9B`gpxM z0@|(RK$d8?mFrd1gE|7rE#*LpKG&B63Hn@94n)<*YcBbExn`_SQwk$`IFGW>Uj#C0 z;-f5@9nl+8Bl`Trh`t~?qQ_z*+VP7QFI|GZ*AJ_u2y{g@5k@dKSZ zomwb1IbElyrP?^`Hma8ElNf6j)dMHCvHIw+cJH~p+S|~k>F4_SCbg4YXpRDwqY zyitNj1$@2)Zxrwa5`4aZQy&8@-_Up;-^N^65Z|T8V8cIz-h!m#tXi(i?KX9_cb681 z4)THy3>lV=W@6suQU1T7?558K%Aq*)t*k4bzj@o-Ku(UhHJp=Ql5c_HA?a;17c}4khSx4Inxu2H) zkBb-22M9-BgNbb#@nGF37qX`VZ(qFFKy9hL6mtr7&>X5q`6rbZN(bu#Scj5j1+<)^ zmV%(?Lkgp|Wn&lrDG<4>T!@`6O{1Q+_)$HYozla}QC-Q7>TS=DX~AEPX&1irlh>(l z&B{@o%DsrTj0R1cA{poK{C0X$|LvMdJ&HB=O*|W04E{&^$|bMfq(!i=1QV#gMJ+GE znp_td)1pyYpK}_`SCUJgflsRCUCNk7&vP%qx&YeItFShJk7zScj%0}Cmc*v?+ZK-N z!KKT!dt%rpux^B)(kqw2Q%ZRcaYnHvv1*5}ke59HEpBRU0 zW5XE7HRWsL80#q3Q>^PKcWl|!YH1=AVyi|6SsM`cEsIN0=={UZVJrc*fhy9X11IaIA?KNp+Gqtf!M(x8|4x8yX zPUXp-1KCk61o>EZ&yxOLxJ-er4(Q{dAOl`n2tAP8WL7P2#XkFyc&A2v4#mI0A{ZZ< zm!zkedtpzRqxz|9Pn9B1?8jQVORGz&rFj^md2#iTPOQ^d^R-6kE?OMZBN!X(hvj?1 z%B3_PYT|0(60|cKpVGe{!~O!D2GN%Q?KK$p?O~PrZIuOK$r1P zAJtouV|p|Gwq4%Ef(u7k9BpleZa$)1r`0mGbT9V4dzt!3adr{<{Cep&Mfq`U_DfnI zn$ueH@MHdROsm5lA5nK}P0-nl)S>A=QIzjC7f{DCwG>A?!tq^fF&ooo#!_rvak&;b zfjxKOFjKG(h1Fe*d>EPwBy;tJSKeB!9x?Vc_ynbBb}sh734P_4u^wQbBbiau6DzLP z4rM;Z!oZ`D^Cev^HL4T(4f|o2g$ey&-ygHa)Leb#7PT}#IamMU59xDEzY%g4sB`t0 zig}CAL%;e2n~!ogqWl7U(tda2cOV0Jg!p31wL^zL!J_ET;e(%G5w!Kd{*STw$tgXS zpVIgDeT+T0@nh^cjLl*;r8leaZ(<284*uZ6U92IVVl=Ly);%n&9EYFt^-{QawI0A4 zny67rM^YbSSo^-)QiLx5c}$DIPl}}OpKeyBbn@2%(95^6_JzUUtiTV9j_C(5hBOc7 z{?V8=qXlJv)x+LGu=AzrK7H;@V_G7&Pmf@YZOdX`-nWgdO6|jXG0Ija_v!WcOeXf} zb@*J*_UX0wysZd2>LMR%E7gb3XmUiKg-=C=pOqWY)eHamt$O%Z5zr#35&hm|N^4BO z$3p${8T_rH>2Hz0P*YM%H++3etB384&fczJ?Jm#gg+CoF==E6lgT);zj5g20ykm3V zQ$Z%|`_dPu!sSy}siltmvhst2r(h#$`LgZsC9-O%ZuOW}Q-B?yUq>FPEx$3mvb-YG z!Ibzxeda>=;j0H@_p{~;&%f1t;qTshFm#fgy4GAv$p2V=btkJy zj{{vq;<5^A|aT~k;4@#Ew6 zpf%Q1_e`8o9*CYY>OO_>Wr3aguV`+47V{2vNA(4J;k$ko>l)VQCGZ8_#-@xtM*024 zix+84S8C_!yHaB{bKqkIP#>+efmoaNG}?1Arj|~})zT&RjNuH?Sgt4EXUdG~9^pKKc>g*gVVh)E06K3ZR1 zg0-g}vK2)wzp-#-c~=o<)6-Kr`NO$9*7F?xPLJtZ!T-kJVlT$p87YkEpa0UZ)`<1- z{0}f^Qxkgd$PLGij&M-Y%;w@od8P zRlrCWidD}u;AsYZHR!7?xp6#?_dLg%^B7-zfA%Q$P~g3J#2-K-Sy|$_{W(?-InO-Y z!^Sr~%Yu7%YxUqs5)Wu$lquw%D~)e_jwv|X1@GCdtp`@GVn0T?Fnr^)BR%XkJdf{x znl%DDo_(ei#CfA0{LgjV&LWVpf$#@^%7VQ+v?%eUp2Hb>R8K+1(`#>MR7VUv!42Cr z>ibUzx>+IlY$*!=dwl(A7QAPtwkk=opDm65Z)aE|>g@vGrtFk{dU=M8fA<--AP@bL zjMdw;Gb7(%u>{(Sc0ALu5%QlcHG_BjyU!VIXae8y)U%~H$}B)T#_xKX%}0Az=ct{} zutMT&sW&mDXHh1epU|H>zKOK}dwMPWo2T|@&n(}_mcot}!*0p;sm|ktv!xc)N%P=% z;!G*H`g&~=V@bA4{c0+V>SPmzcB3Dg*!Z^7te`$udiq|Br;2t%=MnUw4gDeAl3o|1Kc|=Xu&38< z#N60s)V&n#T7o(g@F5Dxv!&zcUjx>GA=GhM2J1j^N}uzoF>M?AOzYrQ^p$*rJz2H% zk+1L7-bk-3E75VRFWXrVGS1J=!CzZf3NBct?W+&41N+Xg6PKx_b8`^`!C5{W9eJ$~ zEs~FX>8==LVSU*ZHDVhj1wO(qbxaGTarTE_vEjnszZIc)NlJYvl2VTal?^4F+fHDw zf1wU>pxUDPP+d_yRtrC_KDAE|#70lnf+wP=57jE_u?Tn~kQq#ko`j4SB1*D^vJXXK zbY9p{iUJD(GwMJYlr!pR1U+ofo&57buaWRC0KFD;n&<91>Xgxw@P{C84B;&XsgUS#Vv9N;jY(+lDqLp%9tg%w= ztf$=kN;xmKz`|%gkUpqCR5!0PRw?VPv&q7us#x}HrEGJhtXXg1dz&DTw}(a28;D}SYjbK4DjqS(s$Z{gexTY3<-L}S_jU&pkWGbM^$ z(z?+GoBZk*_G+L12>fN7L*JOaSEKV^urRFU(B|{sLOeT){VIxhKx!1R?NKe5fZTje z!?{5F+V}TrQ3bw0g3gSHRcB#e`7xdBY`#kSBlbnq^R+LGU_4(g{qwye8rlE9^y685 zwe;)u5p5~TfAEqKZT3wg+HZb7q74`BW3|4Kl zi_Vr`efZbYg@@0u3y3ik9)6YuzL(Y(qfUzV7SvysTEG)WTMGGKmPi)KF!of)Fv~v2 zTF|~G@KO0@;zc<+=ZR&S@@BofOcZ4nSY?{5GUOkKWvHE;pT?Ga1=<^_o&{DJ+FQjk z^T8*UBVO85j;k-0$TsIwIo=n<`GtzEn4`k=4xU)ee$CyReq zqIh>9`g|#JvX|lPZN%o+%tbxeH=m52H1^IF|A>9kiaQ!HpO_kmATE6cBfALzi{HOGZcp~Bk=a_f;~aqf3Tr#=r)ZBk|ASF&0c>Iy&hAaXAHyfj={LSLs>Q$;Mg24nE+9VE0(=$b zV|{Yc@X6zNj-NPE<%)`WUyUoxu2QT8{NjcQBtn7bH{0(`N+kq(XK2l-{R zu9N*2)H9{yg)@lJU@qinP63DAQe3$OG>RcLgI*{+0~>qB@RE{fM1?tvvb8#j_t#{$qLSor~Yy_YUE=mA?a= z&a*~*1LxR76KC0t^E%ksM>^O$7|-$6PId})J_`O$j0et{uUz(l`tr%yYUzzRE6Ws{ z+;{RMqqyX9oL9F(hkp-Vq6gq(Y|WW5%NIbSnDyX4-lVAs_+5w*N5G4*HTHfww|)pV zmrRantFo|{hqtq}{fHR_!{z$u2lUxW!i;6-uqS~QwrKUa8Y89{R%$T5+p%XH)G6*r z@r)?eg7Nx#Hi7*{$?ed?$_^vWL+9yL3vr%~wrK;X<13#Dl!s63V1LzmQ+a7@On>oH z;WCX&M{HU7p5g*MS{E!Y#TY3m#99v?)hF)S&K4A5Uq!^j{@0`W_^zGo=__l>anJ^S zKBj%=7R0`yt zeoigFy5lHpI#F(eeNv2RKIo%AyQKUVpS-#J;Ztp8ij6Lb!8SpEqV}lX7@N}T*5s#y z==XOOcn$tUO?GBdHjg};va>} z9nodwy_e(r|Bmm)W#xSz&aq$=@dRpr2(bdh6pj>gjK1^xllf?W80`$f_x>DY1#nId zDC*Twe9l&irxJ_Q6H5Zh*@&`R?+7RjG1NPbF+TF#FkAQ`^Zq2Z2=YF9RHvAG4dNHI z@sVlrITk}UWR!)H4kip8M5ExhbP$28dS#cs^o~)T z?$L5smx7U7%dz-UpSu7G$j?2+0! z^BCf*7$dALzoIePHSeh2bm5n8kv%ozvmWiORUVoS$A*nHs6KX|ZrE)U;}}hpDgGR4 z9cHz$ebbY{BPjdgThuOU)84tJ9Zx_nWXo>*B^#tV=No-WmTr%zqw|%-DCyX3!x7~^ zy#@WEd4s*U)CZoWXj>EdAAt?sj%S*`eBRI;CVk98nTRr_FTog0p3LiekLUG$^F|rB zwR()-z6Ci(cKXOaA>MVhT6*ykv|m|P4$+(ljj}618xMupx2>}kwYMJi24N3(O4>^E zZAhW{woAvN(GWvB52LRWOP%wr>Euy;=fa(a&CtB7jqjZfF5JtSaE>IskWJCtqk6)q zCk{EZUSKb4#TmUsbCI18<{j*g=3N?np2QmRmAXKg`uSIZn~ZgZ`m&eS8Eb8!HD%vi ztMAvK@51^L{b|q`uOrlMK2E5guQP2v{a$YLd$)cg^&2{(ejhnG!Y&uqnb)w_wxMsd zzWy1$56s3L?6ISI@ba8tqdC|p*=B9*FQ&;h>(Nir2kn7jWe;Me&_C>O1Ny06Q(uPN zlmqcZ8McExayQm_$i`TS>l<`ddIoiQ`EhUW!~Z)!ezg5CQ|#*xTHLJd0zkU)otay z!94V(yfSfelr5VJn++)J3QOPhxu3jFbdeUr9zygBvp@AKvX52E^E&N2N}iQhV~!*t zcm1Ng{!$iW65Ga}FJMiK?`2nfYDBx@Pe!!{>~FY-()I<V%)Up|C_Aolz!Vfxc-ajVG4Oo|yz)nW7_IirH|4APAi{H`b!Di}} zE|yQlSYRghu$k&9#IRmjk9+{~x5>YzTqN3i$iJrVP|1}v|7p*qyQj+(wTv8s^Fi1T zau&|h87qL?sB4j@^a}6`vw!mXM=oAfBDFq=3xVHbLx-I5g}|qNh4uW!Cg`yq&-5KJ ztQT$G9yQ*F8kB+P#n2AShs6ZO-d38CQy&V0 zrX+gV>6=d@S7UwYCd}Vjb(Iz)$M8n>Hif z#VB4zdqSvnFI$q0>U3sP5St|#fx`H7g!0dDf4Ahqy0@;!UG9Ou`Zx<@N2V92qIwuQ zxh|uY_TTw27D$au$CD^um}lG-AI^M~1(GAvErqBa$<8zGe-D1`lPpjenQlfsQRq~Z z*93WuE_pG?n~$<9ac6wclD7bSG2ACC06hj>QT+#RG3)vnbWOQ^GxA-G_UiDm9GkIk zl!cYa*CNnaIQgO1CR(?stFu3fv8kOvCoR8-@<(j<*rz$v=qX)j84J)CV5I zxXynb`?qC#Gah9atBX2O;awbUo@1v;1@jK3Z+Dm(6FC$98C% z;zG6YJ{H9HAo50xvmE+c%lep^hju&ruk3dymtq@G=epM4P19ZTEZC^K-biRWaw~Ao zguT$&BMe{X5@kdA3$U-i%=O6c+pe|YJL#eke2FW@b&7?C*+D&g;nn|Mui`U?H6*^x zxI26WeVtXhpM}-KMxX1!t0;Izo4<;-Aa}>`H+a9PzsP^Vx#r-n!t5~gW5l%=&cc2> zOHo@5-vsq?{z$;m5!wS@+^<7N>VrDQ7wgucX_DveqfrNRTOWTAYX$TgpO~&yI+&t# zO7-z$tXYxxex3TSU@fC@2`uf@NLP{gcFdRU8hEfQspTfJDfom~8%v3K$PtLErL6L) zUtQ=RTUk?nZSJ_9TRX1bvm7}|GlzpUk>R<4=Z3L1!1s)f{>nI4oT7ULv>UpObRlnW z{iq&oL*C$NRII{uR{;#DX$=bJxYnuI$XeA|2hq86#E_8(gpfNFvzZrk7$&y z6GB{lIeZCPXCJ_)UhzSleCE1~cayb@?53~6gYx2*+;Gda#V0vb3 z9OIfS8~HoX6Yh9_O#Z{n1bkm*0vPTuP;Xs)55v9!U-1EhR%f*3zUi9SIOhJo>AE8P zT$BkZyJ632348Td>0A&-4g%E`f-V~I9Dtr^O{KE}wVBqCU^+J)Y#pA)etu~bv|_wa zD&l)gSQFmHnxG`tP#pM0+#SDg73#0YoiTq7V=uY_v>An!My$B5@LYKV?L|~S><)No zL($xiZp+WpXF{LrRdYWIM6nL!=IKXPH?h@N^HyQqoPn5E8=I#$;4@L2r$2bZCnyHS z>hMQ<(xF3FA`U&wX5sIF$C`~8*}{nk#PT4Sj&XQ;w%_I6m?iKcH^Z8)iM$Ca*aehz(Fy@9pa;Ns4B<)p3Zk3rgmfDVcE>lKl zg6ECxV2{K}j+Hl-SdYDC2m3S7;A1q@BoTLvqAt>1GIN~Dlgt2O-yz6{KXI09>}|}O zrN}vtx8@NK>SUC&g)u)%`C#+0$HCTLtikh=746qBI=U7bmbU z+wfAjKyGY=w}qqk*0B-VkN~-;Ov=zAHZuIWbM;l@!((?BfgabMz$_*1XlWlIGzY#JuO|2i7+so{e_p=3uWz zd@s37i$#}d!NlnF;ym_m+#fP!|Lc_7b@+xRM)Wx7^nA#AZc(E;t*;2 zKc?KcSW|h0^vTl!{SElSuOfGp_7uu*HEaTU ziadHqZ^8Ic-<~UA9u%-%#%Nuon9$l%3v&4$y9>Vjw>nrbjk!_m&?t{Sq;{}5-^M!% zC|jG{$!b%0R{(v%`v7GnyC3WA0ewcyS~H{jk*~N0Hl=)*`iZ>;IsS;NqmQBJp=rwV zqcu~3J`rb~j>N{~f^I->kx%I^v;+=l*tr8GGd z)F1s}P&e|`qf`2cXrWXe9n;T3*OQAIvA*K0SG%tKRm5^apH@r%WxzMdXYz;(2s`RHt}y5beB}=X_r&*X3_G3BA48km^An zZYe9N?&ATRNj754>D`18e7_BC*d5=^CYplf8!o@0Jc@hb@j>LJ;od$JA7Lv382{Mq zYzF+Mhp!r8k6b&-PR6i~#MM#*>YGtiA8IJ7xKm$?J-FjI`Qb{u^Z5TL_QFqJTW*M{ zk2ipZoL~6p8*qNCv_drW<#9rSki@qY_?d(mw72k`w|Q9S{fFVeb5zEUIF9>co# zS&U;WHKlJwZt3!?c4&cK*mLwa`4sd{!_|Q(e8%V_hzqSVV(06BcoexCh%;s38^j)X zt*&toYeU&EdmQ`lF|0Ew=mojoO6oY3QLtCiojc8?aI79SdTaRto|CZG+YrlM4clFh zu_xPwpYsUD{BimoWO$#0smCb)5_a`C#SRtZwFdBB2jQWZ`jBz1#P?a)FM~1lR3wgj z{DnJ_`#V=pL_0N_V@foAoX%FkxcU&?11_C&SdT9}jJer?ePC_*HH`nst4?AcSX)lS z)E8&M))r8E;&|@@c1wH20_Z0Jy(Xa7^>dJ?d0H*43g8^RUM*2vx)C-@_o|HycNKFE z=&J(IhGyMm(5$j7DL{W9AsmT&X1xUQRFNs z=qKubqKvURHO!P~k4E>E6jN7 zwAH*rj-sw+v|&bm56+3y*GtWQLNAnC9oqNcbQs@B7Y~LT*kSa`=;t`@GYaT`LxYj$ zb$G@MBk$}=w5b98{KO>oN$`?>ccZ^_ht`bmO>Ov2?Sf9Qb{hL6*GU9=Rlq}cWG#@SxCTY$7@$uLTCHjv0DI>N- zzU{>#-7%WyHafG_r}DVB&Fhh5UT-SqaW{x{TWa6BoCn0xrHm|23vkNjeCGZUTJ)pO#dHuG0USE|%+_I3@dy8lX z%BFyCi{)1iM+lwnbVIX^Lj3d^7)*8o0>yzXHH+ALtWXN-Ua?m z@tod^GTCBI&n0vE11S4IET=yOnQAt#e-CoDflmePQD9GkzDv#PlX=`T zETr~f_+9>S72{q;mn|7|g+zZuQx7h?G1@haFt0%g?# z^bdJt3vH08qFfGivIUlh4P?>R9Bd+iF^VCU6{qnsb$2?IH`;O<@*gciAE;v+WRNW| zHK)gN=wmjgCkn8OB-)fPZJ`bPT~QiGv=1_0kLUDVkh=+WMIf^!2|GyO8T2-SWnzry*4s~T=i{K|) zBU{*8G;RBNlzl!1eL-ep7B&Vsaqu;Qwiwt;peI#~a~}4VgIz*C*~0uH<^gzK0`DYv z$QC9O(0_u)33eFAe2Jng+EGwVTlg*7upazm3qvu?8SrNdC{r|T;YrBYs=_w&n3Gx4 z7B&>~`csg3PYm)4;NOsd4HhxKQ0_=f zum!{^Rw5^1$r|i6ST90ZtSbq%q~zcir|?s3^IVjp3L17)0b&Nr7P;d5>%U5z`^-~SWNxrO}n3^qA^I5?AiI}%|E;)jRv*>duJ z+=K4aXA~!=kIbCOW*3nsg1nDNK|S`xhj+8cDdf&$ABYqubi}+5iETzWT{WQP&+ zG35v0uk6>Uj&Vc&9?0LW&nQscz_2IGE{@RM!LdLjSzbP}i#4NfO7Q^v73|YE2P(0{ z)9_W;w@<&G0(r&{U_$t(%+j0NV{G+4ryYi4bi?tn_)DO>^$&Sp7FvEW=9MoG* zQr$cCwiA>3ky*3QH=N&b-i*M1rha`1{o{QjxeD8_2g#?P_!XUV(Y_#gR^(3AT82eKcZKeGQ=f;L~3+@AGe}W&z z_otgNp7fp^-=7xp{mFP=&fcG>PE+o|_at}edzQP?lpEbI$i@5F)L!Io8|_7WnzuJb za$~Pg%raSdb@L|Zm3E)1ntI>QH zl-qh6bPbj|9x=` zzRZ;VszSP^F@)|RYYEDdZEOWU+2>O5Z2%A1#*vt$lC8I(9N7ZpQ?80(KBE3!;A9t@AnP$;d%^oy(YB8_QRYqXp9AkX zlp*^+Q^4FonHKQTeC`FlmoUiq0?rG#w?iC5Em1B7_uGFcd_RNlx$%Iq6=#avL_o<+ z28{b|x@QQGpWlVJchcOuLpfU0ac7iO%e71`rJut2VV_c_^){@2`!zae;Lc3whQ?QkQ(vH)_=uiZIEg%v5Sxv>c*M&n-g9gPa(V*z?Ft1sR&)n&5&IGLxASi! zr$R~K{nVMr$4Y?*x>2m(VW`79?kF2TOtDUh(cZSUjI;8kq@U)%q_A)J?{jZh`g!+# z&fGuWt6T&p-}C-?@!HwtmyPz~44C^#J++_4_TBdAC*N}&X4_w$Bg*yPOI4Elp7zom zI@tbjF{$5e_!hU8@f!mT=?M1dD0~a}FNR&x891`0{4J`Zc%jr1 zyw$YJ;`7FLvdf8Jh_xXHtCH`9`~_w4ggy}nvHZLoiw(jCvd;17w)~mz;?7s}XT-TM zWa*218T;M;q%jxj@VgQUa;$^OiN>=>_eR=+X7#D0I7+Q5Ea`eWV(_Nwun`u)yq)u{6im(4D>Ar^G; zvYX3+XeZkTeb76tO5=pXm*ckh&b8|3gu8yhrxSI6Tm)-9@an**ANf#qABHY4p90az z=|8|WFJ60dITTMbnzNxhs2!${c{6lCWAy-j_k-u{g<5mQSRD-2v3(y${0Cz-0lvD= zn=(U?$@38R1p{mY?(qT(N0@?pvwRRaZ85~Kpx-4ZLu+XlePUf)ZGE;{pC6)6*wr9? zVy(CzpYy}B$|2;MeP8&F-wrsh;J+-bBUn2ok&{I^T9ltf=cD@6etqxU{W{fKd%0S= zVg|+*?Vxol65Fp|_G#obFTi`itt-oI(QVjUw;>-6?MrRbC+1prikEk=1m3I8VlGe) zSTpjXwgunrWoASIUXOccCwxq-rtc{8CJt#*ppEIrd z^f+<`=sw{SSkqpH%$E_93dPjY)O?py0nKD#!re-7W#mP3(ZCu_xdWn1y+FDRF4>&fshMq6=@j#y$SF~UMgeRWYzZ;KDZ*BeG#%^WDB4X`oX0Z?5H zq>Gr)?&oQ2K#K@8K1PNfRzVke#M{vSaN<)~)7O<_X#W$%qxut6j{1Kxqz^qC!1<5* zw}E15mu8V4_c?s8MgNvA!-{>3K6cgHH^o{x@ z&}4lx=2-%^oJf>6UQ=7{zUI1e0Q>gP$wuSddU~Ip<{?HI_fCoO#DY`o+|Sk0iW9wT zeCbJc?pn39{PIq=2=is)WG6cS|05JtOYzq2#@aWus1f})e?NkJoFU8wnyYhWsb!jf zOQ5?8n1i9>zUda+>%;Fb<~jKeOQZM>8=>5YEhistXHQRdap z+rM{pAD(&qX9vDh&It9-&;fkojUTIpA3CLXf9$$4?U5m@C8Ke*bTMl9ceExQTd^29 zK^U*`d5HC6j887?WG$_D2MRi;I{zc&#^IkV1&#KaFMh4&9-~QX7w>&?lUBDcp{aCcUyGTbxwbYBXj_iQ)yy$nI zE(&>PG}g3T8uL+{F>?5AzBh44#qDm}!uuJG_C5~qVdwM9TmhQP+p(r=C)$Qx+`p9kSDC9hFG+^ANVf|N5 z@|_jrDZqZBSbNDv8c*XlN#OHF+7N%mda^GPVD$;CckoRc!9(jVM4S)D zjv4kw`#}u)9KpF0{{5x(u*2u0BU%!H(q#j5s`MQBem0MT;5%6)iRiBtR;U6oN%duLDFxB{d2vD#+AoYb~v* zk6znqjn=BQc(u2-wXLm_jHjsewzk*)%k7K*cbz#Kj;Ci{$t1kyd_F(c+0V5fYpuQZ zK6^r#u>8G)O`PAh@tt_%@Zr|)T~~_ShUayyX}>wP0o=&9=bQLmeFMMey}tT}*ca9H zv0qEOg8U7z(en2oZhOneJ-LlOA9t14cCEJCJ(zTvr!v~FYNMTUPawd2Nu1oXl(kFF zDPJFZo4LI%!ktvn#^P}%kKXI$yg?AV`i@ZLDyp~nBn6kDF75!&#E_qhE^6&e+ki9d06jH@4ifAv#u&p#s?e}5RdSSxM5 zG+s&nM$^Bxqw!&>&$54f>#+L8{?pmN7svR`=brJK9X`MLif86oXCa*!rvMP$_*lZJ7>M}dosDFggv`^7B*A#Ovjf{2Y24y4ZGsy&Nt)wZj~Lc z=UQRIWX?4ezdweNl4m@N+bU27U;)qzaVa?BToI6zo~_QJ_pa)zftN9=t`J=0Nph;akjSM zaK3f2FP46{9gdITN7v^j#$ixMb#1?IlZ<=3WMaZ64Ev+cgl9y5;;W84E8~AWeX#Z{ z%)8hOIWJJ5b=KM)fRa8$`-?u+6dz9h=??#r-?j`XXC9hnv`}Vd{8G|6$74*mAIH0t zZQ~p!O5Zl%FGxGD7~Rr!?S;q-@>#-nApgW@{D=u}B4=yflHd3K4Ly`O*mb>i4?o_F zuI)aV^OR7_&JWz+>5e!Y2$ox2uvk;U{HEpOrg- ziNE9e>S}z*ZzTS{YYA<7b<9T!eX(g>uMYdjkpsJKh&9a^h+N&E>Yp9RdBF|Al4Uo< zR?R3VTs78zq%XwZgdV#tRyucGY{QJ=#GZD}TC-)xT64~vb>!65;->pux|&I$eWyRYk3pd(=z8%yLSt$vRVE^ zHEJ%(BDAlcr7#>*pp?+Qd^l6I?8h+1G{(Dx`{H4JQ=b640QaaYDq)H5&4+F()?C0^2d;}MxE0jw>m3H%BKi4-bfiI;TAm&-@$WACR}lN5Iu6ldq^dGL-+ zB`oohF8OlFU&fNNB{dYB4OW52zz&;ASmGsJ^5tsmr4J%UtiRT{eiC{uxF3AmrV^HT z8F$Gi`Fq-TDUS+UeK`tx5~v33U)7!9%Qls;#7ny5lfFy2?(&y%GIp3Q#r*|qJjX+4 zfMwuj!2a8!5|(&LmvNW;QclWe%U|;qxsg5`4u%810jQZ^F<1@O+f>35FX@s`@=G}> zpDlmkEn_Ba$K6mL0mp;Wf%I=7SPA~arV^HTNtb+*U&=}OY{uT*=OE=j3Pu6`cCxw{ z%mbp+D{LxZiI;TAC;6pZHhmYq&OWpJsUrY>t0hNgLN5ZJ28}?*TBw92UeZP0jsa3m z$~*fmb$dOUugs6klh`Pc8Ijvz;A9|mUjVKE(%1Pmm9WH1y5y7mQclWCJpUUDaV1;SVCg0xj+ zMaE6$PHe^)AoF=15V^V>e9ER0mUu~*e3DXUk(PCdv5_|R12SIh zG1SMv2|((c2+jdAx3hrsSEz&~UeYC>I02$wEApI38VTqS?$tU@xoRpV(q&}%v_uV=6(jI|~jT1UvXgM%kkT_jV(n3J& zi$LBDpzD)&i4WV5cLQXTo~-_K?bH3xyfoGEG{YL7o1u$kU`P-uVHr1hJchoiI;qDgUfjT7I+Ux9-$JJcuCiN z5K6KIXPh%$(#wJ2g2YLh->cg^kZnhV*Ca2z9%f>w~rsD%hE?_=OAf| z-A;Mm6PAhC$IpS*P8mjdnm`O(OvHBZXAq(@jo@DJ3iuZog)Gbjp9lAW=fS(6jIlon zTnH9}o59z>^Pmg-3mlE%90x7{3qS;H2JPTQ@Fw_wU;qYw1UMC31nR*x;EUis@NMuC z_$~M|D8wk2gA>6Spc>2t&0rna488`w2X=tpfIonLfk7zdu^SICU70N1>6h1 z37!Hwz^?&+SU~Lp#VklifeJ7dOad2yE5TLZ8n6y*0{4N3!BgNR@H#NTpTTZW#=?Fy zI3A1xXMyS9a?k*lf&TzEfjhyM!NcHt;03^c#G&2<{J~ZASK!C+4g^EMabOIX2&RFV zpay&ftN;;kGq@An2fhKG06zdPgV#YE`~mC&1vml&K{*%!P689a+28_j8K?t`z||lE zZUURYz2HIc2zU}a4_*bo0{oy^{Q>L(z5%Qq;7D)`s03rd>0m0j5X=U3;407zz5s3j zZQw3&AJ`5a2j2%TfLFmUK^OQv_yGJ96yabD0_9*B7zM_GiC_x209*=czyi<&t^upT zP2e_g5BM_J4juzffgghZ0zU`81v|kX!7d=is{{nW(O?)D3C4g^!6a}#m;tT;bHQi8 zGH@+e18xGhfxE$d;34oW@E!0B_!0OC_$7#ex54{h7uYRf^f!Qh4g+U_E5R4QR`7ig z0|n@1B@o?R4(CajQoMIIFvsI3vuZC;ovN-c@fw)>UZ_%-zGo5;qa>yI_X%S3ZLLp8&3AABl+WwzYhCU=XpML z!c3oPpW{}q@TuZo@;~$a z&SxFe5AyrfnxJ2O`dGhuU^KsSKhv+SyU?$WuJNl;O@8&CtNrSkjed2(SNy8xJAU=I z9ey>u)34t63+ep})ZxPl)SaIwP)}c2pjzh_sG{o%RA_U78uUnkdTu;_`8W#l1r+3+asAazE&bI}6y$4FWojAX${O7~euH}cT7k3@5W}qOC4H&FSP>`!okiWfjr26j#N2$Rm z$Zx;-5p^*Na!bk4>bp-Kt^VJNA!;ECG7bfaJTp{Xje?wEE66*Bp^igAI{z|EO-DiQ zFh{6A?W|C@{OLILfd2%w5CsXMAV04krT+K!6V?5%RH+kCkSDJ^S>5+YNF9TMtUy8j zhtu>|7M`LOpddaJy&PMrd??84lde{O z*_2R_``1R)CZk2Q{Ne@`LP0J^L7v;TQB6caHkEEsUs@bhlTeV$P>>y$eN)|f=A&xs zv?tUbu6|0bf9Y9u4GQv8^JVqu!#`CMQILC{c~kjOkoL9jso#%GD9CvzNF@qVf`Zhd zAdgfX>sx=;3BGGkkV+KfY!qZo>^$E$j-Tn<{O}y#2o&UW6y%Nnxz=|W3i9XmZN9Jk z_#WSU6yzEde&fKWtdR1t`eN-@mZn&l~0!T!n&^q9D%>e5By( zUri`T1qyO+U|7IFLDrmiW#ENJRt1hlLEakk{lK?VR z5+sK` zAjhB}Lr{>PeP-;DE&un@ktd-b-#nti#qaa^gF#e;nQILyJ zkU=QOCANYbgM$3IBB3CIP>|D6kX`TZtT0fJzuxaZ;S3aHJPPvA&+11Nqac@~AfG}( zZus7nCm(}?Oh7?iX})IM%kTYu{6|rcZ_R)I6Zf)$9E*ZHbZtUGCZZtbdBL-HKlA&^ z$Dklrqac6keC52eP>?^IS9syID98d7WF`uN6;%Py53p=n=S&q)Ie!U*i$OgQt!M)* z2iDz`PN?j|hJh)d5n!&>cfecVFhAwNXTkm8mmr8aJrA^iXMiv^AjM!`JqC>Be5pT> zaiHma`WSG-%}}@{3YW$@OOSRjTz&EwaFH`MIm?hXuu@oOj4~&>9lbdw27KhKLB;?# z%sOY3HsI=|JnthpCyzlb!XG!!l6_o4s|}(HG9S32)|}wdTH_&ND|6GEV?y;GdW4r3 zbSAGfXZ!Ybx^8E0QgF&6`4yS5EChbp_N5^aG?w5}5DK)5I zU)ukkwm)A!KLYs?=>7;86y2BpSNB_7;8 z6y2BS58ZEhzGQv`@*~jG5iqD=U!MQX7{@(rG*H1LRJS z+{cl7TH*_EecbvjpxX}UyE%C~zyRf+{0QvlBVf=zr~b=5Jn;c!ACSxjIDG-x6Ug1X zRCXY53mBmMlOKWoa0Cq6r1f9#0mKK;`v5r$aQgvrCLlJz=?moT00WYL@*{A7jetRW zMgO%8kUfC-0D2!Fze{l20J)nlHbCzOA!OyAT~gLpQO(O#RljzfmFUgCUzii3mDA&lOKV7FaicVo%%0(0H+V2_W^Pi;Isk! zNeAoqs$v72`vIpf;NBC+?-|7xNahdZ?Er(5fAS;Hha+IXE1mw!S)l9#(%Asn59qT& zy&n)8kck~|?+x;{fPu?D`4Q;l5iqD<>%UOF{=0nurwx$vK)n|bKS1sXXg@&P0681< z@&%mV3cUOQFFTO81q^2X$&WxUjDSI%ZvEFbK%WE39>Bd1@Uj8Ub3uJ3plyKD9}pXm z%nmsB241#+qWLF30{Ich(FhpSlT80p`2hNxfZGqy=YsnCfZGnpy&?CWK%Wsh{eg6L zAnz08NC5KH9MU6T(ECjEU*8FE?gP4O1Dw8q^K78Ib|7yH4rvk2cfJQBU{Kbn|MD*W zzjF`Z+y{vMch?4Z`2yM>aPA2*u>)RvgS;JJa`I1p1hNf-Hm}pY@O(0fU}rqW?}GK;H{;eiKZ$7tnUV`F+6o zjlgS9khcSetXSqd-bW)~z$cmh>peg+AHZuLkjxM8Iu~^A2b{h@w*G+otT5T$Anz0O zkx=E?955qb&{DVlOW1h^p!Hw-0PcN&(+?2+_p$+UN5E|Zy6X!h+ZSYG2lBRn3CTZ) z{0JC~Kq~!Dc8Fxi2twm08Sskxesuj z2d44^oHoE~KcLSA+~gS#;T24%eTU*hx`fO`+%_5rfB0s1!s z`aD3}fOPu-Z3Db~0k3Zb;tTZDAIRGQ1~LB}v?E~9v+n4>wgIC1TL1MvAQL~pX#=z! z5dHVE0eU~+_62%k2fWS-)9nrNwtxxBKL^za81yC^{nvW{t^e+QfVKg04&Xcs(BA}{ zdx3N|K<@|ixq#?@DjSf=p1|!7nVnK+Xd6d4RS7Ugv_D*Z{BZ1kOD{uIxbGCt%X@&jCFG2CeU@ z{%7g~=(B+C*nnjF0ev=@>RiCNC+LYCNOo43sU67g4-RNmIVc;SPXAM#0eJZU$-W2Z zeLya4KyUa0nd}SlcHp2?g+sDa+3J6?JwPfSzQTZZpgZy45Htef~@%`KLWiz0tOsX zo&V`H=RJT-^xw+|NVgBj#0I#(4WzOGUT1?|_Xkt?0`6}Gnfe2%&Iq#E8{~b0URQxb znn5n~-+2z`bq?U=1Ef0-Otlxt#0I3=4>)ar(-+9wfkRpq4$01USO2s10laL0>;W`V z-4Al^1(MwnaQXrI&Y+hKaGni1?SSaMhI2oV>U*J=FW_~bQ120v?F+K?2l76_A*rgp z(rJTQwU3{Qy8VB*{wMPRvfT%`?*@4J0o}C$>GlJ;^aZ+W2lBR{SHwJDX_65zh)<>W z&NR0T5S@2Ie18qmdktCpHRKGyc@E&U59p~4aQXt`189i;J8eKRUm$M>7^wVnNQ{6% zFP%D`>fNpXZXZDFzNT9Loj!oqKETTc$XTF<_yF1Z0qJaj(+=qGgwFjyDjVS56J&Bm z*q8o5et&?#i)2MKj38py!HgS_6PcE zZ;-bIJ=4j)EWN+!e<~kff3yLq_5^oIUtx(9Ik0B#!~>%J3C{qN3M zKzD3Frssm$><2Qj0bYB8Y|aMy(hlUpC&=4^ePavuXZ?5k0IBu?z3B&}vH{ub2YS;N zNcOFur*VXMwxD~4V1L&CY<&RtSwOCAfZG?)`v6Uo z?FHO^KzD3FPke!7-wRXu173e~z!@js12Tc=b~X_G%@wFB|717<2Kkb$>zT%Tt^3Y6 zz2>`VcYJ_!`vA8MaNZAg?*p>&1G2FJ?sGx69dMop=y&ItK(2j(L)8xCeS-8xV1L*D zT>Aj~iw($?FR(B71eyH4K>G^W_yRg_uKa<#9Y}5ma-sj?Cpg!8_q%)D*I}>qKa+ES zY<&RtKHxyI0sDh5knU{YK(YgQTkv69&=>kI_CV{rn|j%ROuhx|Pd1<@-v+$=0NE3y z+Yfl13uNO9bZ1X+u-SpUEl_HI)PFA@Ad`JSx_bfX`~bNVI1m%2)geF^o0%B*SI23Hb{-FQ4_5pgj57-wr z!2OM|yEY)3bAep%2{Q2qdi$(U_6MT3xdv4pl#fBLGX2hD zKqhB_?t200&I05K(6)y>Fx)0=S;9W-v=`}6Y#PDUf&6m*??^K1gX9k=Iub@+#&gDyZ@!^Px{|i zK0tTQ0&;O4kSiO|ll?$4JK+5L0?v2QcQ1&pr-JzYso?xgQL=Y^cQ_NO?*(*+=K8Eq z*T)d-_m4pf)1B*OlkRoq=Z@27eqJ=2bHGe}fL!eZx?=;nb4MVPb3rc~&|AJhcfJ$k z$`{DydqGe31--d9*q`?Yxz_(o&Hz&F0dnC3cWdpMH1-iQ@*jM|4{dsS&FMWc2rT@9y10>V`T<5zh z0?ED=9*TCLxAz8pf7XAo2f4BV^8L>Z z(RVM%HvlKxXMtY(0I>s3-PiBAvH@P_g1zAjh`xJ4e19*uj($&IS5&bgx>BEs~25*ANe0+(5zk>5I!ka-CsKi;j3Ty}OfC?^r&H)?23*c|yL=65FU_E#Y zyb1d8!DuYF97Mna;3e<}5aeKaESL$J!6xu1_zCzUD8nJG1XDmQ_&m5BJPdvWy1?JT z5iDFMg0sQppb4x4TfigW1@Ig2Cs2g*I|PgdlfWflA^1FK1yS$_cn;$_&KNiv< z;6!jbm=5NEMPL=U8QcRN0^b2If?og=d;t77=s|ESr~;>fY2Xqt4>W-ea5%cm& z0c-?!fo$ zJ`PR;VQ>!kB)Aw{3g&=1umCIq%fRQr7r+{D184=efjhxga3A<8_y%|c{3m!4JOiEw zJHSuC&%v)j44B|u@JH|g_&@M3P+;&q6$}7}fuq1jfdP&Kqrhk|4om=NfJxvS@JVnH zm<28eSAw}<0k{e@fo5Rn?_f757{(ld{vZejgK{tw7@z`Ff+`RKcKY$v}cz|M13I>A1 zz>%OFd=wlDhJ)k4NKgerU>rCFoCeMSVK5n-3(f}@fQ!K_a2dD)d>Yh&dawXo1(tx% zf@bhJ@OkhbU^Qp~H-MW!E4USG0(XMD!B!9jUj|1$<5C^{l?|}EfAHko%2jH*ZZ{VLmjbIEx5$FfXz(8;q7z{oF zhJcR&0}KbpflA=@_=t4FPn@8@0qw8IS%W~nR|<-O_@n~)CW0%mXD@{-VeP?iAr!8I z1>6ROtDtZV6s~}EkA!92`VAUOv2`}h(x_O@6w8ivCk8WYo!c2uTa08FR0TK=oB%4p zNH7YV2&%wna54yiF<>kh4?Ye~0iOU9z-i!gFcF*q&ID(HN#JZS8B76F!8zbuFb$j! zJ_)9S3&4foB2W!31~b4+FbiA)E(Mo?+2C?;1^5)0W8+Hbr$G&<1$8#&Lg#^c&|qUe zbb*b9&_)}dfnH@}5mc}kECF7Rd+sHy=iey<+04I|fimjSdvGlSUh|LJXZ_yrD5z5g zob%6emsAFhC#|P4a4L0p$v~KRk%MG1a2{!HIY=b~>EuAmfLjhk26`$7RN?u!Wgy%6 zFQ!(l|GjAglF5MBfMhao5^0&*0g(Z*1#UYKCQfAFY#?&rwgX-=&|O=g?SYm9Z3}AQ zTL-iZIPHPh0&Ne(7HE4Qw!mo*2zox5%zptTy=;KYy`Fz91ET+e{ve$V$aWoY%D`~y z9|0;rG8w2MEtw3ABh9@QXc-V&;9LvBgq<=lg|L=`X}ot=22!mFA_HzY5E*dFK|NtX z14t(aWbu4@GXF)?=$?P44UqZQGN9K0@ddorfg_1`uK`CBr+tBs@$Q`eVT9Akfc6Et zD+6K+&IIBQgux_mHV`}Dl!0>z_e2ideu2|BaLRzT2U-T^!dKe@ryMLGULdwW&# zch?SNvPZa_`n_zyr-^skf=uLqBA$s2u=a|e8A}wia(&&0;e6wl?#=YrX;1IN+M?yd!5 z2lW0>&Ixm22hO9O^T8*J>p`mXV=r6a_79V-3Avd6Y<+-aYrp^+qvzj!9+2!z z$ayxL$vQ9`9wR^n$dw&%%D`#Vn@SF{m4Q^YU>3XtmjI^>q_YLiHG!g@kC*;SoanuV z)_<@0mvunwe|OdZEd$B?fWg%3WdnM$4s>T<;9LuGEd%M+gJkE=I~4G`O};k5>68z6J9=ij*(%*GGs&N^Vgx4SYR z^Pg)OIGZ{rgLE>GY=7Y88)j+?V4L*m?fLgw1Dt2V+1dcFb>O4)F5NnitsT(w-%~q~ z=~+>#_25GKcM)*QfP0_l_6xKvNILl>ba(!<^#QW60q!%Q!L-wD1Cp%+>Gp&b)RoE~ zs3QF&;9LiKA_HeqS2`I;wH_opEAa9SlkE{`LeeLf^Y7jV=rtghHo)x*Ci4Zv4@l<= z98aEX_5|7b1DT!~r}7EB)`M(qLDI=5!E62{PS$-5=N>@bMfaWhFMdEOA3)E)wgF=Q z^%{`O4@hSNvRMZV_zeTYf!8|FTQZQz8Np=QGzECcK(hUT*LvXg4V|`t>XSa1%)iKi zQwH?>J7pl7`PY7+mI3hr1cN}(hMs@DAJA(+ChI^lUm%qXRKiy<5{v>Tf-2x%3&aLw zY6mhoCpw$@lF5LVPcWVQ7XYUWr1J~Np7hD}{HI$3x@!a6`@u}tfn<9^FFT;;KUXqv zDx;oC2EwFI0$wt34)I=l#7x!$w=JNmq))EqKif4x+W@iudJV|L2538==RebRAek>v z0srH`@xZ+fHCIhk#2)er#OrUHs8A!D^@bU?|vmS^Xqzq~tTAeZy6ZGhN+y#{1r1Je0|?sFk8Utl;qM*#Oa;9d)~4M=7O#!`pC>#X<_ z#3!=@$z1;c>T2Dt5j>7WBp%kf{xD`huy}fg!ZhxejFF3wX(Z%zsa1;1ufcS_{0+iM;j(?)5;{ zf=t!}vZZ`-Isaa3Kr!6K{tLwZ3*;O?p9S>i-MJ2=vjK;bU(bK0>wr@R#1C-$0&Y8S z9C-w8e{f&QfO|a9CuUc*cOo%7$_H6WD@NVXqz+5qP| zAo}mL0qJ}J=USlW-z@{9s8gVQLcI=Tx)ylZ0k3l+uf2g=2By*urwn+l2V_b4?2GwN zW&>pI-Sh9Y7s$j0Xn)Wx1F{CV*8zh#rwtfE*trhu3mNd*8%&~IP8pa&*eL^E>j7C( zKFQ`^;zj43(7LZ_IvXIiUn83}z%2vLy+F1$!08L7S_cf;>XZSQf2RzbKv+--^g57B zJ8&xXy6u2l2EydYMh0X(NcS8F^RI1y$bp`JFB{OEbs(KDkWL0<9q7(l@Nvqy*8;Z; zWU@DyOg&S8wgb-fU|-LF5$$s8f2Mw5wl*M{FPP~%;64`^PTQU9fc6Kp4RG3lzLWv? z-oUvYhzw{sIG6WnAl;LV{>xgRZNJcf3x$LQGVdCC{)NiicX$3%*#NyC5dBYP1Cp%+ zseFN+%7B~=2vVI7xb1+~S)tnwq>=%rEf5*Vp|MdCqp*#FY-{}fXulQUh|*r8X$JS%Ld5YyXQaK z{a{agf#L8U0rdPI$Gi3goOZx11L6yG*B@|yGe{)^UVb60(>^_!f02c3=HF`#$kq=` zCIhk$(0c(d8=(C`*$ZT{A4s+iB$EO02enVwS2B=lZ!n4WWb*XZ{EICR-FNE0bN;j0 z3u-?g6C0pqz_}kx=L;rV2QrZXu>sl+>}wft?+yBT{>2vbWDUsF56s2}c=>|4S_kx6 zkV*#J=R?l5K+Xn|oezvB&3QiHTnkd26*^^Lf1H1(4G`O}A#>l;`Pb(Gscb;Hbs&>- z0jDpJOa|m!Kp<;DZ_7ZkGXhwreNx$fNfV#X4W|#-6CWVe8j#Enlsf{MtOMc$Xg@&P zfZkjOlKF%CLI(8ykReF>^yd6KeE_E)AoH%_*8g1F04)PD_j>-d4M?{RIQN8^_yXC= zfSeKPbHZG#1x`C4GLY$$N(S7zFX2@BpNS8U=^D^iHo$8?kZv6q#yAWIvL6uWbs!TN zkaGd&*+8~3a0=y<`2$WFAX`SyzMOxrHK4a_fL;eg|5Mojul+!>ZvzPv<|C50K3oAZvllz1RH9nUL%Q^cQMX`=6Lh|PB*K-dYf z`x@f=J0bp`hI=32wFYG42L`Fz{arw>0eb$mAE0f3_60=$-8MkWfUE&}9nf~bAWop? zKT{cy`R@xEfK5hEF6O^GK7ex{knI}KT|Xe13}m_vXc>?-K(7M^?`|28H9)Tend}MV zj7aYZ^ci7K_66b-X8QET{EIEn`Y$w{{yXPCS2iG-9T5FbW&^Y@AU=Th1GEj${-ARm z&@v$NpGpRtdx8_ltJeW-2W0+pEdx}U(bJvzm-WDD|K0kZYW_tQwEcJ50GW3Uy$|r( z3+R17u5Car)&VU8Bj}63X$PD#AoHK844h0}L8fO!`h0*Q89jY5|JmArRP&#SAE^C+ zWHvyr1L6a?{QzwP+`fS5zqSE-9q{r6yktPu06|~M0PHe)_Q(0pbPeb&8=z$%)jFVM zAe}Fu?Layiko|xl*;np zm!5yU4u~A+`4@k{X$M9U7C7xdIvE&4e!*B9Rl`4^gO z{+%+AZVgCwE+ljBo`1Iu$YdQbs7KHLzK{XfXZ+-9{>2|~uK)5bdavQM|C!8xx-~%L zps#E|G8qs*Q2T;{k~ zE^nUt*%gZ#udQotT)M=VH-CZDH;hb6RxFkZ<~A-^pvy0Bytbjrm`jycRT+{lTs~Bv zasG<>1r2A{&AV!P9TnZ^~R#T z6-zs768)Pr)$U%?vWBZ08$Ks(Yg}@5-J-^NsWs6jciyWT>l>CDAI|Dk=fCBvGU}R| z7F}a3Zd_8cpssO=QQt7XZpETz1BNRaEQZfXt+Xbf%8=gKL3=XK zojmz8qjKJ|rOTH$FI~FmqzlhA7Bw!ZTekG1F{8(f8$ITvv7s?zM~B8*G&FYXSmPvP zx|PA8s9~p$G{%oUW%M{J7$VN7Wa5@JENZA*-Y`;4lGUrOp>A%Y@{QuP@DnFZQbnc3 zlS+L3{H1}z1A~1>`aV)n?mOBy#Q)KPWBkK?RX#O(`8A7?acJ|h1YM}#sCjgA!^&ng zy1uTtPK}JxuX9?2K^m=5jDH-R+C zCw_)JE7$wgti9Q+_DTA=K&aF!&yJh?*8fSG2qn@ay&4GB&zPGXl@Y1aYI&y*P0oBD z*8!-`CucpnuaZ2U`t}rZPPx5{-}N=EbEMZBs@_Epc0LenISc&Sy#E7fkNi!N2c zw8KtcN%%b$!fM7^@?TGQBEnp6=f4daB`oqN>GwikCtPWle~_>&lFfGbQG(5MVj)!W zKM#F_aCK=S{4>H;r|zx)cZAyrm)ZRPN_flZd&5Q4``{V07w1*#JCg9ishkmnQDVO89-ka|r*#?r#Bf_T|_WyS{;h z-yqykKNPZZxenIr%~sB zp0MEv|D5oHv# z^44Ekw@jVe(0rlPc)`;8hRYIlf7ti3s-U_Ad#PvI(q)a;E?v@Gx9EaK@ypbu4a=Gv z=j{m!PYTpsy})8?2N&WZI>QYsn;PaNV#rMCn&k~kmM>jagYSqVv1CQvB8&C>MRm&; zinr0YG|`)74K)o{*UVe7c*P<$Z|RcxjSFqIv1w8W^_emy&7n(xz*y0_QASy7;^$jYQ3C zu&bb3jY}FC|2iBdg(uKFX{u^mQs1yrh6n#uUDmkdg1Y5bDcZfPVeyK^HMoU)17ub6 zRxDe_WYtuQG}!IZ?=`1{7G5h2-4pR~R|JWditCyvIJvH=nSn_JsuS+7J7r44dozqwl#p^&AA_=3%o0l57TNTTWB7K!9LAtk z&6~GSa!pVv*8&xO?RNZQ zcKj|o{=wmi^!IEU9FYh|ZTgl?jfzD49Gh;i>612n&!*+aF+bSqp*A&aS|OBqn+28j zEVOCU@rn3mp+4ls4mYvUmV9s9bm6E(c#}~O73>+Sfm za}xE0g))w9=Ot+Q`3d?QRNA%64$s23k^a_0rGMi4oESikp;gd@(-ZNFY}#bgW}8mA zAdx=JrqgX&ZBygIM0$lyD{We3)A3N@HvuaAW=pt`{z(|R0V?x!zt9u#>n?(#8{>r{ z`%{Dt1J!^{+xm;41{lyVAROU9uZYRREc`Z?PU&k@Qzth|JLW$+V<>`k~VQT~J3 z30ih}f>zix43&DO2&Mcqq0Gy4J6vtkSvHM8KSp~t+4Mo1K55eqsMPnIQ0jZpraSET zSMBg?LgDke9exig{riVar(Z$13O+*N_kmF4EAXiVT_u$G4R*N0rf=Et|FG#`_OX(0 zC{*|vLTO)xP})~%hpX)LkWI(i=@abmM4^-m+woIuI?Ya>ZigF}H`R=*tErnmdg;jq z&zSM!#+-7>si%yczF4--G}3;2e8t-vVr~s9p>VuK zD%o51Q=xI&%=gbd=^a%a?fl$tFX-|$MLSDgy`ZZkytYe4HkyIjjiz5s>*DMqRuqhO z{%iN{-}?x!{?h80QVXoO(k~_ASC3g8E3xAW>Y|;cO)W9WzxuG%v7)w3J4@B3okg`R zG2fVIXRzr`a{%=PYws`%BAa#=7%j12_%>7WuMf6%^;3yD4?Cu{tHgeve{5@4vHd=r z_#*rLA>sq}yVN;ubZgfDJN$=}Te}o-^9QwdN!^E?K{y=klrqYQ#)l6~#2;}|B43HI zW=~z~Rcn{jCFP~8u1lA3*QI$}VwcfvIt(6O^*rQilk`d2r0coTuE*J?BL=i~T`6M{ zTy5nYcczR_#Om98-Y>E1koL-0NSk$i?)K__c=nw+kg__DyR5GB-}(xFDVOWMEpha% zB(&D*Z~Zx2&GXc(csLyW0jl*O=r##F2{&YU=2pGsTV=rSNbO~`XZUM$i(j>n5 zBU?@WmzuZ=#R@R9rA@_K&FG*=tizTc6^h1{y51}x{M$EMyL`WH?Rx))r`{G7DpR+< z<2UBT+Wh|5?gAA*`{Qe4KRD|Lol4E@B>%TK5%|(EyHD;c37_;%DS4He7xM+@#Z+N} z_wI2j-Z7|yyw#HbOC^z~-kv~S4ykBQI8Hx0%SLWAOD;zbgBwjBvRO8AE&7-!?;CUb zPI$yiLM`S5U6wMT&^A-bNf{~2|G*RX8Bw3lI6Gx|=~M7jfBgN6PI{-nXxl0LiHcWY z53pSEl3=Up9~$XW9V)(N#G07uppA@=f7t3+MX1$Ob8jem&OCNt=NtYCT`-d zo;RqcmOj;n zomq9vI&(a66NsBgo-pxKh@VFM^iQud+sABTZf3>{{?X6nYJ0n^gSNZoX8YJp=I#-R`6;R0N}sAb8TT&@ zR;}iUvC+;z@D9@l-x4GG({iKrXF~yOe>Kb>?eqmFcllJfE8P;tcAQU@PJCvQiS3OKK5?5_$h?L+H<@MdJE3EGmv89VT?5sePUh|>^Uhk=)2`rgImor&)m?pOQA=>wzqu7j4rhrIr}W~*16FvduF2YPt>Cf6%SC4GLWC9+stD6ExI@~wAEaFYqYc6APpJwMQ*fY ztn5cyOkXtGd3!J_2yv4ZgBN_v%G!1SwdLqRqC>M z8M0dzTyMU@9Qo9_w0*0U7Cm*FDeIGO%-UFq=$N{+^LgxmukcgxpOUv+Z8VF5b+P`c z)>_Nzk)MsK0C`_;wNYe4^q{ou##p~wH^fR9quFEbF#mP(pm=%hUFK^SZ!s%FH;PVl zUVU;je(8~aeBtWgZjN&!$bkT!7ya*iGPA@lERTi#`0X9_}_cIvrMZP9Uqu^|-_-@a*Q zV%}6-=0@7#8xx87?Rl#ViA|ds_qE;VxAM^!@jaw3GOq<=uqouN#DDRr*>M$#9??&I zs#CQ`f8cA6{?sZ%Kdidxhi}Y=n9o?xx{#0ysbBQdABp;sSK1FnZEI zG!Oe<7i%j}mTpz3_2x+O_|eyuED@U%cJ97=|;f(ko>|B8n{noSgdR~rh$`}VkKjGtNY(z(WP0>z& zb+oex8zSRd)^CGZc{F1>Y@ONP>hBft6KP+7IlAwxHL)LrqMZc>Hk5fhSE+|&JrI4> z@?C^Ji>}e$$HgZ2s;56vcKI6123T`QJA}8`BHx&eJ6{{Nfw^19dW>$cc5N*3$CC9y zx6zW7P@??>w7-(Mmv)z*x&>Ld!~D&^cE4-M6f$Ya0sSs%Y_n{k$dsjr$dt&Iw8=N- zj-6sxEM3Nym19qKP=~|~Mdu}6?13?|%`8CXM1}){w>@59tZ6q!u72DXJh$uC5hG&O zdd^xd_OP6F{CiRdyx(9SBV%1YdW$LRl%I8T1h#YNXylJ~gLlJz=V+?5!hRpZd*zuM zk^ecJAK_iMvFc3PLEPcQX}e?Ttbq=C*cvT|(iW#((ehZ2JkG^OmHMT9(%(wj92(tb zmeJSK;WOTDldK67?DvoJKGA;X8)s?Qem|M_DfTGY=z89APJZC{hM zUHX=)?FFHRSSf8k0{IkODn*yrM*m9sX~{WbE^|_eT!@b)eVgUqX8O>LB4bgkk~u0H zxjL~9Gj<}wWg~AhEgy!lFlI1sG8RX-F;5rAucpm`;O+QCx0^v3C+!PUwxkieLU~_k z1N+qLyToRdv1aX&FWRKnW3g2tr{hFEYAszcMOO@TLwwZ|^v*dpo5$?+17yw$jD}b} zI_{^h1;%{qog;*o3ajVweo1`8?%lsC2uVEaP%!#~^@PQ~jQU5yw#Zy#J(Y0@RHIW((fI8J$#qt2Lt&`aT66T6 z2+u(9Hq)@jM{I!}%Zj7dnw8hAwS1HEQ#YFL{u8_GXwR>A?=F@6*f!d;!Tc3tW$6Wc zq)pZwp4!IVq75Ex)?918G8gVOMCQSo5BP}9n4q> z2Cf4&;4E+~*i9SW1oEAH8@LYCfV04{U^h*86R;mp+rV|82AlQW#kM)H4Hv&3fvo3e0nvGx`#)0lI*?zl8H5Au8Em(gX;e(2UE5JXJk8{60kIv`*Ex|y8dr5n8C3s3u@;l{!_Hb++kRyj!;XOCNLwnxF?78wS zH@+7yt^ZJ1$t@#(4aZIEnmW1OZAEa)xw)}v5!b8bhjmue@)dKNm(|VN6RxYTZ`>P@ zl2QdVsjKHL<{G$M9k1cXc8jdAyhsG`au0ky*Of2i{_$k)f9o*Uf9F}@N!)opXX!j{ z{z}`HEnTsszUH&z_5JngrCeiQuI5XInt9DD6S_APVHO<|T5Hobp^WPmn?7h$nFERM zu;~t)z9E$RUGLd6fY8f5GWp$v#LMqDgif%j_!W{~YloX`8nNkSJAJzyeo-jS#Orpv z{N6$869tue1`8!zVbh6r{B%1!$ENao1If?No2>lz3#HyC?D)5YA}s%~=}_ctC<;FT z>IWH7ygG%|gfs`Li8EIdwO`B13NnZt(bn6~A?UH-g5+AkW+wJgUb~px=_W#4C zRmF*VCqkv%6sXj9za8Fgho7*+PugL*FCzIx(X94CB|Ov)%e@i_Pq4$&?eHu+ycsI( z*kZ@uZ^w7o@z2@uJM8!m?D$=Fyy&*@HK0;Y1yuOSIwkSb?f7atezqOI(vDwc$G6z= z58CnD?fA#+`1kDa`*yetUczrMu=)!Xe&g-%L_545D)V)}P|yw}{}WKj|C}9PK^}>( zgi8E0=un*VYCFExj(^Y&Z@0rw*x?R4{3=xVl%cayz8os`8c?Y>Y=`B(y~W24SKHxw zsFYu1$2ZyW5j(uz4!7Ik$L#QP5=JI>NEjMKHzh3h_9a{em3l)GPdg?^JaoDpUv0Yq)Qf`$UZn48rJAA(#e$WoL+u`S+!heSy|C$~DmK}c24hOI~lCKsj{1!rm-zGb} z#SV8sW!|2%<9FEcZ%MrL-;RIZj<3XaNqto|4MC;e@iwi7O1ar~daWJ5QsU|V{ZK!) z??Iv1ukCiYT`0EUF`MqWU%NbU!8ZN<+K9a<^G@74(UF%;KA&vu-!Tl%LYxYEC4tl$X3xpW1%6sjlFA-1qOHEw}MK z_g328W{z)aHHWNf={jb5OV>2YOs9M`o(jg*TbC z9j#`4ZL7JE@{1y^W>Z-1+3{09+Pl7ky9vP?yH*>#xA48#AMIRyF*ti}?Ahz0oi}de zPR=vY&ML}$^$XF?9S=u4JD!eq_Pcd`?1xLazx$17=hvT#cDA&&nqOJWUE}bESdcay z8xC|8N7lpw;m^d5jg)i+zQnz*$bwkOts8gxJ2u23(YvjCV;ku24){c9>)>dD#{|Zr zgmxB3HpBvxHtv-2B~1%rcYSwcY$Ex~XiM?xwXx#QQdju;SUJ3lxYshcZL4`~bzzr$ zA2;ahgj(up+G^g_zclvTwgiu_ZH;!``IS+zq10cvdgIO(?o{*(x5T8qg%_`l1=<>E zTdTPtN_^egSS9(&=>JQ%P@Zq$5ytkxR_tki~ z$sdlyO6b#uj%eq~NUIr%AZr(I+_?(AKdOm#-gDE)SWxnRYi;a-E2Evy(Z-@W>TJKq zEGJKCbtGn}M4JNS8`|D#hT$W3LfgK6Vr(#R4-TMT#4E-iC~aUI0+HI-jzRQm(%M*I z^;NMc#1}Fa!aIUIMWqbmV8BB$ms6@K*HP9Lq~0>_)>PDPH7mlcW@UJ*dB^P|WB%G3 zVx>(tFs|flD(-rowo7|A(S}0qBuT#&Z5Rxn66RzY<%*lGij|XJ#$V61jMX&qM4DR7 z<|ghJl2#R=KOI}mJ2#Dt6@?pOFH(1aF&DXMZfiA#kBp&|^&2+@Z&|_wVXo-4HX#ziG?J zSPOCYY#$YyO}OxxjXTu`ul=P$@*|@nhnwyh8I$qd^z~7(Ipi5E@5DvyxLV>$?6@*J zuAaDZ-tQ#e!lp#oCgSe6b7XAuS4YJbMX*1cN5*b@a8&Ge@@%2*@f~t!;_|p^YkWkh zE8;5pnMZ=$50QJS>b?zch16Dad51vsvy#4tnZsxuR zn>l1Uch0NVn#DgRT)WmR`cwqlverCmQKYLZveqp8e5C8}4Uw*6%1D3WHnW_v3R|V_ zz0H(1E9A(stzu)D2eGe~&1KGqk~i4C)-CDglm;y-)Mt>@E$+BKr`v}-Tm1T2Y1LNR6jwV-C5`s!eu!PzGcLjC5Bif{)*7jz3;CM>nx<~ z0Opf9dP(k46&M?01G#Gy=g#?T%7nu$UB2i|=*Jatk%7MuuZ+YU-DiF3y93)}@c|vN zc$tdD`v+t3(&|`TmAAel_tzC^a-UjcM4?Ch$WubzV)7K##^Qxdv3MX7ix)(ZqhKuV zYm3DPw@bNbT-NA7yWG2<*=g{Oi}=t0MSUH6`Sh!$OtAGG#aXC}0YA!=P*-v7hj~hQ&9jKS zh2#y8uYi31Ch|t$6&0RQ#xlXPfHFhdTG4w!VmzyO7k;G*ULAXR6-ga>JgZwxDO<)^ zswR99@&?FT06%{%`N)e&goiGDDej8P5uvU)biiM+V@hWx&Z#%4&Jx>l*yvMZE=0@QT1I3a?-^Ufc%1>IA=j z?eMEk@T;`>O|kh|G9bLF=~pfF(Z2#^>pNwn>|TEGqRs;N1)AUmzasb*2cz+lHu!ZU z_?5Q9uOq>)%H}uC=2sxR7^4r#fF4iyNmO;1{y_O@|+6vJXj{EIEL$mIJY6QbzizXs4fg#8)mLuka33C+aP%g$MbHn&2CO zZxp`4XuPxye$-z^n#|#Nn`gCyrzHy(Pxw=h@Ra<*Q-0%Apb|U-9nrYh(!%Nl&m!^) z&*CQdMc@~OUy$-`37!K;6P^=np0jvAntqBLh&=entLI2~N`Bd=1Qa~TBQ`vs=w~(d zyD7oDs5-&BxRx;a`JF?&Gz!lk`PveE2NExQC)#}H@c!CAcR!@6X)opW$UFIK>7(Qq zpSUa{c8z-5@T)uM7x_!b->(TC5qL!55sbzMv?bc0Leco3c6f#o^C@?7iTm>R;q^W4 ztcrdOqMrj9+X0~%{fNc;*V6Cym^HTY`y;Wr<&+n@EBzFkD`TwfePJXP4@AiyjA2(} ziS;lPi=WQ@SbZpY8v92C1UGk!nw=fjWKuJdy*d2?8Nk8u2cX>+K}{9xJb=5F%7 zIA-;cPx8CA-J!|&*)!v(_|;9SR>hmQ({-#y5ogNp z9M;4JMg06mZC>m};>y?Xdm)K$UmqJJdz1Egv775}irxGuzd_is&FmMt8GnDUiG5># zbz_%$|FyqFqK#bz{DvpQ@89J9v7{-*ZwJYz!vVsTj&KR#3P-q%u;B;?2@iFI2NN!L zgv$vJCT!qG36GWd!$YNx+I3y8;bX7rzs+1(dvllkHd=+F@ni12p{uAa!ZG+=JEeV6 zhBoaCP`*^n>a70!HuJCY+o;I;t{{GJ`I;NdsQBt~|2>E-hr;oqs%U)8g=@QR9JH1_ zgc4iJ??A%w@|zR)sRJS8hPun}`~Bptn7z(iJ8)fBNp*|)gL~Im?G%2J=gY)P9;+RU zBl^-=G<`}}XwEvb4gD#h?k#Pt<_*`~(ABS&y)AXqj!r-NgMH}ayUDu&`Hd)gqaNY6 zUhGimKjV zZ#+tjwGRZ0wU0|#*?0Ji8!5wYwyg5!S?^Z)4!it1yZrO(9xrp0m$K!w!Drk|nK_;B z`h@={t#_+@n_YgrU4HYr$NM?TOIg{Q==Q&6mG@}>O?LV3ez^ToHsomk_pS0C?cZRR z-|^x0OWCla{SPK<{}=7@_kOtjQdagXy8YaP+cW;(!LKjrklzvC6!VQ*!=94g{V`9B zJ?DX2&1nw4*E;xq&r$C1st=cwGUFZm>K*(ZaFi=N@x$e0A2;2>??MN^haKgPa`BTg z6CC{bF1M$DcR9)xx%f?hU$ukZa0kCHJIW1l@sl!gPNT=O%)yVpfwpHni#5Lv#*_WF zg5N|3zyHTR%-849y)G{9kXKt^T6*Y(I1%yIYS8W+a@_fkTZ(__N0v8 z`IfPFzmYv!#R=QYsuwuhXn$mLI7y;jW; zCvx78-xD9cWlfj(<+AToZFkY{d(3I%5t$HwPvlvbFT7`O`LJF7D9VeU?JPf?@-oL# zugIk?U*sr1%`QKL^5Qo;%U4r=BI#1E$eAu*Y?nWVIhH<5Cy$(SOFx8PnO)CBgFYIh z(HA)%?AN{~R!!JXzFAOT8?tPNrHqWJ{Jyk|IwtbopYy(1y!U%#u62&u@3y(I*=>xq z#PL3dcR4ebch+dmdJ^yTyj$Z+{6gMCcKjmVt??qhiFeU&DJyegjRWrn?=t2RU&*`l zP2N}XE`5{t2=CSQ`+D9*t|fjG?=oKU9_8KFzI~_fyBoR!?XBkFTQ+nRes6;{?-hiP zB3wjR&Nx>Q9zwX7u$;qhAT07co4V$-Gk&*Sk33#)))JO8Ky?SaHdQBcef(*hDEI-z+fM1&SFaWdvwbb}y*X&x#X42S5|J1_U7|98ztV4XwfU_M&lOZIh;vDd1epD%o5=YKJfFMNdb zUgm3Gx0ckX`>zRbT4|{W3I% z4wJOnHf1!vJIRl6pHcSN_73(K3Gd?%U*r&vLH`yugZQA$Nxg^75n``#gLq`$w=&^- zuj_0}czcJBmy{&i9OT~U`;)Sz-8xTu`-z(x--7lQz zmyv&7dzB3~vV}cL>jmWMt@yCNi+?+?&p0)KZ-YHb?K4VtH&TB#?MoidjrDJzu|oRk z0`}YIVdL#sJ$cknzc8n z{UYs6nmtJEQEELg`$MJdNoqe(^|dECwaMFy)ZV0g%i5EauSD-JA?gJ_T$uN?L%rk*FNM#aIvWan+CjUFS49*4rV{np}iXLF1^5^zx~;d zoI#!5_9JIBvY$4{{Yb63RlG<0k&_y{y}xSuoV_0@eKvbP(&-r7ex&vlM0cVu?MG@K zaVYj9XVZ@6Gq@iq-S|}6kCa{2*M4L}NB;fDd!`~!`q+PIqlb&q7~%OA;=7oh6OtvdHA(pq!hf;8 zlkYGj5BzK_VMbE>N$2BxDQj?czZ||b#f3@MG`0Hx?LI)e4`kx^K9ISY`|croLGsC~ z;Z^y;>;-!c@O^?W;P0Dw0sU&gH)`P};^+}s~iNx0>wKrPs_75JQzw*0;I<|IM4!Cl7KjliT zn^Ki8ZA?Zv?*i_V|4Tj^{9RUj;hqq7n$2@qYj(rh{V~4Fw2%C=`7T*h-%LT5&fC%P zMCRal&fE|W#hu8(@taCG=2W5b_~=T)r0r;Y;vDiu9UQ;5Q=>%<~bJPJDrU!sUn_twjWuSL;^7Ou{sR z&a96maHPxn-<0bj;0rr)fB+tjaF_qcZo(6O(6iE%r!p$5I;yKS)Rx**+j@uIrFZJx z`c)Bh%xk`Z8f5L1pF>zC?g_ttkXPb?W}TbdYE<)+2n=>d4Ose^2;6;jak0 z2s;Vt<97&uLwKI>6T*KZyhotAb=uwgI0k=Y;(X8~nt?9e-$edDSnEdsQU5XfzQ>|V zC`U!jlj^G+$7HPw{CEVY-|uM)Ug-Xr_NeZbH{~j+IQ1;G<1#lk5Gh2ouvA&LLv- zZoOS}ki5^7Fj)2CAHMH#bT2-9pQO|@d1kklDm;~L&_@?668=4fwzpeNtua4q> zOFT-xS3hd)SGx*~!uHZ!#!eeE0QYO%G%W6nRnzwh&U=MV`jfu`0o9`es%63}YSw;DglM|iw^rMnz>E6iVxA^8`3Ni3P z#{_&c3G^;}6g4q@Yw+e2sC+?te{t%RaTe_Z^u|!)`c9pRLv&Vznx^w?r8gutB=6_! zs@`ATl1P>=NT37n$kfCi!KX=x?Z`yfcPr<;U#DJ)voJZVZDBHG-I3%RLF#ctv4yVg z?)#~Z^4> zmv&;b6Z6}#v)ZZh+o|%~sp+MiYRXj8mikkj)sDtggPvbSeYfxE@)5p|wap(>dE6V5 zO?{+y(xz;TvXS^5-DPV1zSR1Csm#%rI_j(aI?6<8Q++XbDW^}uU%k$2vTsmtc{q-? zN5T1R-MG^}0(;fTO6te0weLjO3y$%u?Ek`Wn^n|MXb1BY@BI!k+<;E-t!Ee ze|I(CXC(bbp1<)~@41oZWp}aHewA#lTi_GtKv~>*{nCe=0~MQ{*BkBYJHyS+&pFR} zK;QOd!Ds&+ULU`u%RHAS)+Ehyc=r~*Yd$N5&Ql@VcsRUP0nbGnAML7uHlo&!F3Vb+ zd_@vIHs=M94~@vG z-;po74EdFAM3y+s;0asq7o=hHr5)1RNDGtpkD5Qy4wIH3EkfEs(juglYeF^9-#MH!E(N~%MtR#conz0(7jHYG!flKdU;Hq>rQ5>1Yp-k;$bL7e`?*Npib@?y?sQ(dJC zM2Gse=Cz#{UdH?IV?|<4C_?+{Lu=gY!<>KWX`lS@p;+q}WZih=;^@$5_=0m`ZeKWG zq3>Wv>;-OrDKlFAm~&~WD?)pwzjG${w5M@}E!w0VYrNmzeC=G4)y`D|Z0Dk^b|ww5 zolj-8b7eo;(U>j94vxfMb1v}OGCVeCBJ-ThXOs(rqXe?i<3n&QKD1lLFn6QpL_}Yj zk3_P?FEeL>+UY5$`3sMy{`~vBGRVjX>tVQw{xr3Wd5?WfOFx9$2XZR7zeZQ@m(HQ{ zrgM;zS}DL61%#zlpX-8}tG6ZQQ<(o0F#+N(OsSKg$C9~>h8-4A$= z-VtfytRZuubp~_&t+yL?Wn>4HE?Ao!ZEZi~u3P?`mHX?H&Agd)u9jzwqZIx6e=-jB zDbn;PGR|wSZIJD$|E9eU5LA;rjYBSZ%b5ke9~!~^VRWO((0Sch-OHVsw$YDQ zf{WK)!k$F;dUf=!%&SufyV0F0IJ1Ku7P_jXvwrWEOz6C|os}J5Nm|xdkbhrEhV8F# zw)iW_+79kZ!Z-CX&KuF*MC$0y*Uhw>pe^*F^u1fq1;Kqy2m7B*PO3SyD^rWz5{)lS zR>&U2Hj$lMVY4<&CE&P?BFWOl-S$4 z%H!8`Uj30->5DCEqs~Q@#2@P_Z@ZSXKTTgiTKzWG``Fry#eLzJ4W!K@+pP33+43>Y zjzYIJO=};v2_=^GxXZ(&OIInUj^d(=lKA6Y;zxZ)T<7eDb2m(PqI7>I#(PEk+6yX) zJ?5TADzVrnXD_HcKBcoH@mQDo7>cbuB>ra);c>NRHNi84azZ5`MyMjtpA7wR`JX+9 zcZJ6Ucdu;PmtLcDs=B+tdEXZ%8=YU1e>FjV(|H7xJ$;l;G_d7gKi}!{8ai=^GrSFa zciI~#`aQaG34bF@Eg$0~Zx1E&kh>Ir6sPEq0 zB=3!3=*y&UYT=B-6^W#s;GCXhdP3)kH)m|{JUO-*y5!#SpHepdK+<^(`{Z)uZ*0e* z25*b2sXNHt?lXDQPzzzbdNU6N>D*Nb+0=7gpUYhS zzQ-5%TTj8d+AqylSNFP%zTVKbxib=aOu8v+neIKdx;l@A&fXy1q{DG_{HkWX?~B+L z$=7j(y@g95T?XDwJKT9lS&Y5p3ECU+SeMq$NVC_Tu>sI^Qrb(@9(>u~ZU(pDs`-Y_ zn#2vAwLF)#qYHmybLZLC^M@+$TAvK>+}x?V4x4EEZ0ngrF`kW0YSSNg|1!Ql8RL0I zIk>f{GiFUPaykAY_)h*IwWaeQs^4(Za-blH$tupz1tuDD3M0UrHZwoUt#W|Hm{R&`*^5qMyq6hNSL5+xDaUJ%R_4 z>hIH!?#k4a@^@rn>yvfF!{}t9LD66JmH5a;J&;rz;nC}X+$T8v^WO^Z;n5qC+Gn+5 z&hA*u*_(id6EWw>$i$7w4=x?)&Wmdo@lE%wp>R^ZylckjZ_I4Yz*@`|z98lW?n+~g zrpvLRHpG~(?~ejU;A=u6DS24?fc}nv?3!EBN7|jSXNRn-bbiv*)BO$I-H;p}X0HL) z&^zC`57$1Jbo)$S>)MDT>qJMQpZ`sJHTJ{Y)79N%*XQ?)=Dm#inzso0lxcq$^2x;u z?dmQ_{LizGgO2RIwtGpU-_ zN&M}Nx;Fl9P8Pdvaoob)7MoHX{5-~AFcOvQJgBk%^TRD`$}Q`v?e2mQ95F%JX(<<$8| zyLZ>C#CFnA@-ODxMTK-}>BaE{_GoOM;g&O+?+sj_ziU(0hTTFw?WQ;rJ7)CvoK#D~ z8I6C_j*RDAKQ_$<y?k@$SO1shFetTohu#?kSid$rR-ev?hw=sMn4 zPW~F?m);k$6VN7Qu!Yng(nr@}qpM7U_eA(x7(MSvjHx@Dw)Gy~C;C*myzio{`!2Vg z1U5VCi`yT)i~i7#+B0pay_|hM4(({n-nfKk{?4JsQK-EIeNs3Se(rGbbJ5kT-{iNn3qP&U#e>iVW!k~Nwa|XB z-5ISi54t#3ev6;~;Fv|wO$d1rjUhi0oY{m1q_2me0gLjHHYbG)eK*3he6^uACp|gt z(MXthoM-OTrbJ7`p#i?d1N})iluo!%>u17woim32{Pq8H1Yf6@e*P8Z>5j{s)UU=* zOK*!ENFEr&-2&>~r8|-6qVB;Cf3rPgH?Ssnz8vYORs%j#Y?V->lUjkD>MX)0v8HgB z1)Bsr?>j%^>?eF1V;sBxo;{RN>`^qgrRo4|?aP)GTnAuhX-b4L}gw(eq|>50tRYt|)8W9YT58(crXo-M~g&-8HV#+&($ zQDb%H<%VkR5_*4s?qIAMTV#=Y-mb#FJ^7u>T9ViX?%#k~!yb^%s_nPgPiR<&y|%WK zKjfQ^G&tYi8V;iyd@&t~ukV~X1sZ5}zJL8)i;|Ci>Ql*Z1-dBvn<4f&Ykhk{_!@?7 zBfYB>T>~G(Gu)p}Rnq^K1rH=k7j8(t+WgUs+Wb54D|`#@!a3)(T>ASJP_|LIgFVOE z{evS%o_V!pSEdymE^;~b?NQX9nf^P@ugQjxFXUisROaRQsEoe7RBfY6bZCE3{aw%6 z(n8wi%=c(l=X!^+5Bd~s-lI0d>yj3@eATL^&BpY%)h6$C+w33>9KB3lb%Hh>bYI%5 z#HUl8*qqr$d%8oSdmWYZ^Fi9Ib=yRT479mUZBnkgO>EZgHrtMF^XnQr?a3yTy>=IE zzP4spX6=|w$*|hA)z6vfJF?mgt4;FUe$r+*(9b4~oBo$G?mwlygxcG`E?KGeG)8ou zS+sYst=jFQ?p~?Cm1>jxD&lIlMrpJ=%pd=C8o&DLwtZ{rvl_qKHfP5JZS%MO`rY;= z1`mGQV`%$e0vgJ~Lrp*MFhY1>44VH6+Pg>XZC#ffMqgz&y_yg%_%;mBVcM16?ao=- z#~8bZ6Yc_27FrNa$bXqSDlc74dDWy#mmLP4euJzOT_1$rMdvRALrqSa1DNk3)vPy> zZHq42l}VsmN|y2Wrjnr~@~we=eq>tYa?X}oUq)s)2cCttWmBN{zw{__A&wop8#x|o z;vOIAq2?)_^_M@K`Ri{wslVEVoSXG-#vo6&$nd?i(f;vFg>y%eZy}`09mb>k;_Y|P)-7qyCG63e z^kMDaLeKE}B3bfK=l$JnoRy}H!~$>sFp%V{gQoVs6j>sBV8$T-OOvy$I(`@l&} zwewb4l5e)r2h~+S-1^S)WJS`u3z6MUlyAP{*FcH5GRxC5z zYGMqmiB=P1X!OR=@kHjSvyqn_Z7vS@8=Y?bwfmV1`lbF?9sma&HJP*6pYrw(mr?&# zx4vxOGS)ZYueq_^U4gDeG zUpHq2L`(a9TKX!qBw7F66{4p{QqX69T53C*mWJh_rKp44cOJ>20mcCSG=4(^!*kI< z6EyH^?wB`y+pTZ#U)BWvd4K6bAOGxm4r{s%9Lz~uO}BxAIUfGpcOP9hbiC${zLz$& zrC5X9x#N8BTWd9U%xP#W^Jb64W?w*`z4P+lID2OLI_~%q-i=_li_hJ;IA3$IrT4jD zoI$>>$TJtiVq1=$hmr82KM#hMhUcIqmlx^BSxK*c_dMj{qa5>S-fQZW#ytMfJ6#@z zhI78R1ODN?l^x!DyLlko!$0D|XW_rIa`2zt%R1)bf3om@4dbsX9LL&H8G|RT?qv=}(jVqqbKv4JF(Ol%XAY!eIJ+J@nx2IZ&0zo^xp=yg zxq9mFzm?){s5_=IcTBt+Jee`cuNkDNJ7)>A!Q|(S3L4 zvVgun#hCwvyDFN)|MmxeE*OvL_wcNKuchBD^jkin@7^aKcr<_iTZ~NXS=;jRK=Y$V z^MKYP`q7sxk}Q@iDr?S?C(Yj6m96q=x%u2o1$XN_-|p?mqA#Yk77j}uU9ZqJMBj_d zxrRuVB)xtc-aRV^?`j?R26)%`D;Jkn@5qnGPTFi!oBW;iG<=o#WTrQ{?tJg@qv*I$ z+3JqzXFF5enRV&mX3>KgkI$QDWzmBLJ?N~X=II7>F6mqPy~>^Ho;@y|W0{%O9?`E@ zr|b86_gyW%nPWLl+D5mM?pN#UDz8(f?Me2lIB!!EXWWhWHyOVT&b6o2x^5#j7T=Yf zwlVpiFJnLA?v0$AWZ&U?*r}AMMcWlo5t!UTgZXEUNJGN)S z*0xl&mwul1Fr;J29{MihD&1^MJX9shZ#V_K(l)MtN&ub^!w=X5Nu{Umx1?U&PjJ$IqP=m6D9vzI3SV@pr_ zI&)M(J6fmzk};NG-^q?WOYM+W<+j6j6=`QUysP$fw@~)@vgD%~>2CkATkU!JTLn62 z$V&V|_c$w@ZK`*k#z(!kOuedPRUh>jhu*;nFy0eZe@4-c-p_I9XX5_*OOhLtukGH2 zF1RtdjPqP|N%Z)n^u4dReJUqjNBr5tzx-`EFuRYEx$2|Fs`>ZkWR^Qt)90#qbw=Y; zyBhOZ@r6nJjri;r?$H@OjnzGS8TW8sLz}W=EBU^ni+j$A_E}%$JG?R0*wm*l^8cOf z;~X9QnR?pQ`;$q&E6Ul?k~sHeNsEkqi2YRQj$WTcJ31ToEPG$-n}z;obU*m|0J`K` z!=a0b+Q(!MLHn2TyUR9ezz-keT@%?0S9{Px=<}>KtcB^{AU{I*60I0#kR5Cl?D2U$ zX(^@MLR|fyXk%XqG7j;Ra3Y>^eVX#&vyWK|pJ*Rb-|MqG_$CCt{-gFW;qOP#qYszi z7eZ&f1UsqSVJ~16_rJAo*66&>9iX@B4-m%=+kyR8+UTUd{U@TuThsSnv7v*$9sq}L z#n}H7?yB1KH;%Vu8jvBD^+2+PO*b1qXvwA6Y4$ao1%cPt|1J3l`g`NLU+CP}uNl8^ zQ-35TxGeCESjHo} zK;xOrSl-VX%XxvZyzP(Wp&5a(!2i(cTQT~N55yY_X9+bH?x80W+~FKO!b#nPzbq;r zA>(MoCh*2FGsU^j?s5FPKMpg72zy2m&eU~}gYz6E(9lR|LAZt{-kKUmPIfryh6efM z@FlV*Bb#H>1#3H?j{{N4NH*75E#%KiHPA<$H`N@M;rrlj;Cb2jn9TWi_ghu*hVe=j)Emig6P)6(Gy>~U~bqkhh|j5(Vb`s0R9J^yIlk5c92 zE#mvAiyECL7d0;Ke3*H8bnK7adHL~zg|2@sG`xXxHrq38B_+ww9rt(2zZRk1qgVVS z`J;IrpXj{fPi8LWOg8*+%eqdT5m6cO&~@O~J@@GI)HLGmxko>)bB}7XuXB$&O8||e z53m2hp$_n>^~;<^svGOAVHP~}Dbd72;_Xg)Cue6DKBhYabJASfcuQ+b7iUu+ym@^R zoTVRZp`Xw%>)Zj>i`T=fKRUP40FNUxD<*PwCu(m(=oD84Z=@qhjT zcfzc+&bZW5ZW!|i-9KIekE_1MuD1R=`4&7KYL_4SmK66vd(IoP7R$eTx{aqj{`1sf z&J!VHQhThQr_d2xdwM?SDV~fo|0S(1Z9NzN=agu7pY_jfelTw$-_@wC52eG6k90*l z@CE%vYiBLIYy0OC%D^|advZ%Cl#JS(OBkth3D3Ic60n)l$p5$AhfdZtuS@>EV{>QO z%GPAT^#f-UBB3X`!pH{v0q$91bc~c`JG&d0dwAMCOQ82z9ZAlSS#O!M2%#A|gRs3z z{@_T*(Pt1OCv*45LHwb(f3I>f^i4 zNmz+kU3^ywXP5b7ORcfW39VL5>9%ufhixl)Cv<;izV>!?o~abNx=6(3o!`^hu6w{m zo%jM?xDQ{3&Q8@|OT5wX&Y;7CqFwpD*Ilu`gE1bE{xPw`lbs>fhuV&9CDJV9}?2zrXVm-%`hS zt^LNWQ#j*-KWK*)5wCCij;*~wY=qc?WN1Wda(hQ8gHH4KcKqLSrj?}ItWlYpr%g+5 zqQ2EZxeok?$j|~Bw48?YhQ@O;D;tjd+p3Nu|E9f_^Aja}?+?h_Z@6h= za$ohd)Sl_nQtgBv{$yH;JJgTsdsUJ%@?}TifoPMHvfXc!%}nY06YMQ+iCWHCR^iq7%h!{GjD=XSW@9_Et9HuOB`)y()g>-@<>4?mhgA z>Gt@KQhJWCcH69pWqw(ek**pZJ}12={)$`XGH6Y{!4iHP3iE*dB6M4o6hTFfHY1M6y(Jwb& zXZxJJJ@1&6-a~u)2rB25nS~AH>|I4a-1&qi)Rt&MdyCK6KjQrrnO~yE+3;3rV2rPj zCLU}|gscyyUHb0}KA-5Ee`lf-o=fTbkhSPYYwJSkeTg?xdz^<;i+Fyn`Hj>O&XGPB z`!A`pS>yLv|0T7@emJ$IER<~HgUnki!qD|i$UbMc?l^>j@<)csU47z}P!xZPc#v^x zj;vBA^#N^#&RgTINqgdNq(YVGYL(93&!Jm=?ri5t^`Whzg7(XkI-~lzr<_z+mn#-x))1{wwU{XRcYB zlrHL?H|$_Nc4Zjf^N4TGyiIzz6uK$Bc^mrT#&GFu>;Y?|E7z@?M!|cC_StFKJi0$N zeq3wki^#Evwe?WMYCVJ;K~8w*YS1Y=6Uf5^^Ea>nSw`K`&)MeNgB_q*$&)nTRo>1uGsc^~Ogd#z3EZ+dwldu?Yk{G&5y z-yuzRrmh+bj;XUJz9ywQKfBD`!)C5FxqPa!pVgfl%I>w+q;z*lddDOfQ*)?$K$?>< z^JBr^4a|Y&%-jRo!#ds08eQo9AB*ulNBM!={keAt?*6!IZqw0gZmzpORR!MtIb6K^ zQ@s1bnkU_2R`Kpn@$QfGa(p0jPS?9X7xvuySye!H(eV$;iTub z;p0H>*)Z*a4)hvV*JJI(j=ni1KN)+!*wNcvzZp7rTKDaxSC+v~fA$;M$X+>}Czr3f zf-^Jk@+>=Fx|7za4_Kq5Gi^Xmz;BX%C)AcfH|sv%`z78{6Whui2%W=h)Sdoknkd`K z-G|78mSp{H+cJyj<2C4f3qHTDbL}Kg&sx-UTjyT%F5P3&y`>k>!=#s$t;V10_fa}j zXmUfRbn{2>kEq{|js22kaN@zB=@0r zNmrSE;Ngt)thNX?$vZ2KTShn%ZZ!Tq=%mkqo3^sDKLkp%P;zaRRUlaekUfkv)F&vfTDu`cx- zbq=rj!6A(?gw3IGQYWQxU>CkSh4U>_zUk~ei}y!plf2!(m3_v0e~V4@JDz`sAM=-# z{T==L9eq`r@=4$8*MD*fcE*&eodbM#?A(>eSw{WI-qT+r4l^0labIPQF3 zcjxb+-Fs+vKXsnr`57MvDifiM{KMa%ZO+KO`v>y>K-oX|efR@?2vyEahc@9`md!KS zIk1;<4VSlNbf+$cU&O}8bZ-Z8rNKQ5?%s{FIl~d-yKdVeXC=ejv1_vV7Wn0xGIfM_ zdXsmr4_eh-J42@pl+k<}8aCV-LBjma?*!@J3~<;(6u*JCYeD?vtMKbEy^N|wbR zO3GH$cjDEj!`3kFtZ}Z^`qn!tr!@I_VrO%Afi_~+)^{{MlP9~=eJAfKWB>aQJ}%*} z96yx&>oIt*{Oa}CyZAwxw`czPuJ)A1!#5z#)A&Q5cGCKr38nEC_xs$X@l9QN{wee< zJZrB=dtln<(78#SJ=QtU1Z#uvu6t<-^0a5Cv!IjwJl$Q?nbEoq`l|gT$~qIu(~%qjKa$tN;Pcz=){|H!AuOMN;#AK6$AeYoYRD;iaO)#WVa zyDgQQI$w>kKXS2?eu}&9!sBF(gLpgXTPs^TyVL2L(jC&jLp_uJUuZ`(2+xY{GthlX z`_|BYrhz^|{`!qcOQ-p)I#AV^W*7 z%D)dDUP1V#XJ6|sX|3hm3$zT3@pl(c&~zA<32 zPscgAc|Xj*mrG35SzgT3$--XP^6}F$<6l z_`f;l6GFC%cWN!@8s51#{*WvG7&UyQxcoruuQLCdQ=9SDjnaKu{gK#k=Zt%yU1-ki#7&TSPzcK|H~)}?V88@RA+C%xth zzL_vm{#0~X{K#K}XT-nWUhB-%SmF~Kw`IZ!?!mNfO3EKK@i%Y&mc6Jj-?OQhgg;Dr z2=iDG0xksCYDarc_0+p>lZ7Ad=G52GWpqYaGOav8AN^;YkCpzNV&AIL@qBLbv1yN^ ziu&q@?iZJHmbZj&iwGa;yNe_AQ28IN80ULQmt2XVf9jmH{60DtEuWt5(3Cf}q66cb zXY9IbWD?N#M(D}%JMDHqXTA%zMW2C>#NnOA=%9<0&?{Qw~wd40g2k0+50!Fegoniril(j4hL^$yBvZn$InFlk%)TeuIi*Yfx`H-_9f z1?H)*|it9|UQ%zEFK8xanCnwDRVd3k1H1GI)eRkmO~ z&-hkTi@-%(>6BHu?Um7FE%zzLnXtYP$F==x!Ez zko8tAw8A%*yY6G0*kcD8G*66mBD|yi)sN@9|KxoR9Mtk1JY(lYtZn$L*B&ad3;CVde{Zd-v&=;MushMy}@U zSqRz+w_{@_Sf}BQ+eL5Ky1(ZfTiHq{H3c~++uB_#7~6!;^6e@7+J8d&UTZ^2_Q{_3 zhSWdc+ZHrs^{pxH>$zog-$3(zfI9-b`}G%ihXpPc&<{fc+e$cl(wa5@_zO@q(=Sn8 z^d#TA!Pnl{j#QYr*=z4$ub`E6ly}8RX{@2fd}8z3XP}ze(oL zO>dm`U^RCdf=-$38~NyeN1yb|xxNwf&=Sr^$u|;hcp|f(v3?KRhdUi_ ziEnksRlJK{l8Onp#3hULHzk!eT>T_ItdTNpy34^`wFb_&0rhuDSf^cIi}nPV1LnqJ z+aPzqzhkjC+#R5gK7YB|s-jk|bhY1Co7wf$7T*uE1cU9WEz_Rb%okKQ7}Q3MpB8M- zyw|jw58Bkt7tDK1UsX=;QZQ+PoF(cGHqZSDroDWS=DL3xlghCd=gx=Ttv=cWrB@UX zDAN5?duofd!0msqJ&nnUr+G2onz_QmF~y3%A_j^WI0G?YGv;#$_ioYTTPH_y_^q(_Qt_>hRK(-9f zK81XP(gkD_ln|s31m!?c7J!iAuZV$D5Cb-S7XKR^K>McJd)1zR^Z>p?;Op`2=JS7+t{F1le*x`v#H$ML7TxioYTT zPI3&`^e@Q&<{XynfP69_s0+v@kZ+(jIZ%`ZAgK5&V&EjifK8ta{~H@XI)JeQbcQlp z50FnlG9ai66y*R2DgKHWIK?nv(_itwkpZ#+qyrc`K)!%%8DP#Y8+$;00r>}mHbGDy zFuuZ|ZBWz+Kv?lt#J~y0fX(~!@xOEcV+TkE=!~H82}%YSpFnTAKp}FVC<{Pl@mIva z3BZ8OJA?c$8z86y7&}0|fS?S}Jt`vug7!dA7s$2=%)VhheV`}@Kx*+<#K3XHfX%!5 z;(zG?vIF{(0kQ{-Z_wBSk^zOtfo$8LC<{Pb@mIvaF~)#R`-cAo&HA6M0|aG&{DH<6 zkRG5j0*Ut*tD6=|3(HFKcH-YY&#&A z3<&xKjZeVHfS^7g8IVs71Z{&{vVf|^Ul9XE3=9zlY}(1k|Gnt|W=|kn4+#1Mdea4h zHi7XG2K9lyvu^n(bBMbB6a*o?do{txN^=3G#4Pp~grz{r81 zPawEQkjo|*3Vom`2hLd1E)Ki^4A_*($N$C#$fpD3vIFwz0lEBwL3<#m3-nhX$o3WH zvki)}pa6m>7CECZU^Cim{#QKc12Ft=bbxF-AgBk3|8vOzoe{{E0Rz;dB!$o3EB+AA1JIZ%`ZryMC4J3Igk*wo3z|4K7HfNUEeTLFj6cB0fWGVjBLi~j0=f1IqzepIA1KNJkXZbkwivJ(*+BT;$N=%a;eTTX6ru+N zWq^?b;{RMSz}N%Xy1-!MKrUZlU$#L}7BE4@-)V&bo6+=#|BVe`_&?hYFfu@XfS@nH z>XjE3@F4V$kqpnasZ?je`hQPY(`!P|L3v+^2q?L|3(KGhzv0H zfcQUK1{9(T45b_>>I6(e@psx{z-DCm_+RO{d;o>&0R5E#!Tmua1Nv(Z^koxd`v?ow z2MUn`Mf>2iWs}o(U^XKg4FBiT0gN4BWPtVq%$`7Rwm@$(V6eJC&_`I51E(!X7YEi4 z4A_({l>dV^z(93?Y#E^Mi7Ln!VEh3_2ITS!79s<3?GprTf}xTFMV)|2EB;Pt4A}I3 zu>4=B4q$u%1Casw>;dB&?9DF_v2gSKha==iJnX*#U!<0YP0rI)Dk{|DX)WrwbJ20EjC7 z&IklX>H&SpfS?>O`-DMzpf?$i zZ4(sYBRrn^K+!&cV2ZzjFkn-vH=YmX^~L{%*Z@KP59$HN50GnLu(y4IT(*F@HxQHo zxqJda888rCV5sFlUwZ}vu?>o{pddClV+$Qi{+Axmmkux(84&afYEK}zFVL3^=#OtO zTNmhSpJ1^1Kv52yvFv!<2X6Dm;2Pi8^Rd(cf_6ZmdO)EvAgBu%e?U+M91mTfzxxG+ z$bq6xaNJquw0hyO=Kucc06`gG_5^eJ1B3p6Trwc23yAkkkR4!xkptp=6J!UNkk2oW ztq=6JUzkf5IGN-?(LP|p&)}cU*!x=ZgZYK5|GoJE^7#V$vICB_3>d5~kZltb;u|Q+ zfisx#PLiPy1^;L717!36V03_>9WYoK&>x>bq4q$3b%Flq1B2N!kX&n6e0&?1LO)?`*Q{Hd%j@S{NA8=dZ2--#ouX$ z0h{pz?fXKWbFKgV<^Mwb0QvYoXa}4OG9X(Q$d&`y{=q_h1Nr;|z1anY>H~wZ4T^ff z=_3S=CI9#32RNQGps#a6h3WwV^$QfD3-s3}D9VA;hYwHGNCv|H`FsF_)dBiz2lQ7D z=&uYIh&|AkE^xZafuc@uqBwYP?>*N1KNuY#xFC{zXvbblaQ7dX~7!Kow%in8Fu%YtLU|ApEB**ZYB z4A8nC3_<=Mh%aCuGN4euV1Mj^LS#TLo1j0wf#WF$hC(MO%7POk3r=SK&(;BYvjdK$ z9?+W%=#M>cEOmi=dj*4)1O4$46y?B);o-r&buj$j+c|)t(gCt%KyNz0=_&*IqYIo) za-gUa42H7{t9z>Pf3^G`Jh5=f!@vt^yU-Dwg>w14IVF>;CSl;L!}cGWkF&5 z+}~2ioBwn90sHa;Wa|J!B?I)`kYJE6&;;>)FvtclL3|$!vH?sG-v@*EJ{V*J1cUfK z7<5)BJ81n62KfPUh3x&p-gJSY8~};MpJjuCTzh+krsdlMH0k2^>>z&64%vGF*}lNO zWI%8~AlnY;O%Dk2fABj(+4}0Cu5S(m)3hH@NDy!LCy0NCD$rE% zS0Dy#%H>O@5=|!UmM^==>XY#0w+QS45cnGR5rnx zCkgl z^Y>LQ+wY$%p6&lL@mw}Qp*lbzzQF8r0e$%bj)x2wh)-ZJ_Q3Jd1x{x|1W zINow#puWOmB?nGro#1%$|4{h>bLjv>We465!GY`#7UC1gB?EHp6Xufv{j~{t z+b=B20nhJ{f3-dNa!w}xKVCY(Kzsp1;SU%p888@oAfFrveqSK?EPl@w#Ou8U>HfWi z;GLp;&*toKA<&!)7zi9{U!iFa6rA)wn;!P%*XvJyE}vg^n(_JNg8lIW7ODdbl^rk; z88DDD0)_YmbIE{Xr3(yXpJ1qTf&T0l48|@vmbSskY#$6Y{}xw!w+i2~HIM52X!| zkN=0#4k%<#ppbomfy#iP_6ZEd9zkz1pf6pZCwWffzV$yJ{}0vVI7 zNcYbbwC3jvxy}ulwBF7R72+E>mU2L{Vj%n z{y!de!093b^4S9e(FF!$6BOk@;dTXVJfNRVt^V+If6C_K^;~H|e$VwhR5BoY{WtMK zbbwsv0!|k_V5sbYf%*rBVz1z2*9W8@CzJon?QRAh3pYzmkIj(2J?J8Y=c~Kpn-9l(8zNWA>l*CZGvd*O+v2v zB%cw#cNqLKMk*WkO#D5=`2U50PbX;KL9~7*{hAp6|75@|gewU;$0?a{rtrk480aC! z`z^ws5-uSK2lCOL3AFHg#`({L-Gn;{*AQw6(#@sMYF#*;X+gZdpYUzM*9bES6A9As z3=YH(qJ`5D4=*vUcEY2CKPTKmm_iUAe4L;)Qfq_kj?)nbf6KUb6CNUH{+kFl5UwCx zK#;Ahb;01k@Wbgs3p*LxHo`i>YQlWNjfBaBdV)=mUqH5Y5C^9VEqs%4Z6JJuu!7J; zkbXFYFoAF(K{lGsJ;=ro4zxA|Wx}aU3$2XhKN0RGe1-63!cBy034cV892iZI9jSG( zHyoUbc#zD~*q0M-BS`*f{-+VHB3wog4ajyEA81XGT^XbU$ppg>ry36KqVHPwmk{O? z<`TX@(D?tDARf4gAR3U5QG9SVK{mAX1H%j1I5<`Cu#_>}PFO&=m2flR^8}4wGElmJ z+`z{~1AZFa76F2vZ3fzt+KVgijG{f^-7I2a*Nyk>sL- zAU~YUw4iZ|=QZ}(1kwHt1j#>*UpA3sfOudmL2^JeAU=?8bgJV(#-9rZClf!2-ftvm-akjUj&LpEvjnYw;(v`_GEg#L3_)_x z(12uNj37RcJj}*{!Gq+1g2rwFk0<=6aZBE5-bMG4ds7IXA$*z;9Dg10u>|peL4c;H-~wH6pz7~})3i~YgDiJ*mR=%Ydd z!HnI^y=Z>|LF=FRU-Pf=k0EIMh6fA{7+EM9FtR{6kdBy-4#MPV+`&NfxcwSAX$(P z2NCil3v$T=BOAyb@}I`6pgA{V7u}2RCHFM<;{A&VxyB!q0m1QS(}4IOC<}7Q#1nx7 zjX5}O(Y(eUocrwYOa9vg&A-NPWPsLzAP*Qhki8xRX~4(>jok!82l;4$qC@u6T$_+R zb~E>e_b;TZ^q=0wpNj^9vM?7P3nfqe2XC=>I^1L0txcrar&^loV0j9qKKnS1g6SVF$> zOApfg8yOJf0Yd}9^{_WtAX+dqa4d14@tPoBSI8cFaPCF>8o%`4?D-Fl->d`T0ntEk z{KJV?5Q5_m@_~^B#{&mu%x2vA#%|``@P5AW%NEf5Yy8LE|-J z7OyK9n%BIWx!3s3+}k{B{L+85{u}<+{AZ6p9}i^HKyW?i4-N(^6M|#bxbux&d>BeI8kQ2T|&Z{!K7*AA}lXU%`ww2sQ3p zW6z#@v-b6O{JGYFAPp4C2Sb4aGj20x1B3H!gAX(ITytOO`17p;ebGQ~d@xuXnDGYZ z+t9nlop0>9=02bNm;B2o1A{!!9~ubC!@=Od%ySS1$DKXz!8JdZ?3ezRz5eAJf3_}^ zYy3tI^oIr{6T&${h_vi*%MG&{?P)V-{+T`hYYXNrT(NA$%6Y37-`Tu)<-BDpzGkmj z`Qh{>OK)FdFJ8IQuD4a>Gxi0G>TNesj}l_nUwiFUcHP32D^{&qy<)|(OK-g1Ubb}k z{FN&%9Y1dT<>SU*Iw3xO!npVZ7se+{m|$OO&u|OaRJHxwi|mQxt{iu{8;z4@*EO$P zymIlf#q(D!zQ~#~kr&NhJb%GbDSgwBmrhdvfM zFZ}VyC&Obx^&xBAsz1MT_520E)hj)?#5~dRxYdjAS#6D5G=KGcYutiWtE_P=S9lQ* zs@C{%6RmLzSKN8$;^h=wzGC&_ao68?^QEg+&tG_lHEznx&ySnGdiBbs3+`UMcop3$ z^d~yg+-R-SPoq0@ll$oYCmPpJG$;9JersdQGzp>|)mJ&ujMj6-MGN}X%(Scq6CrNe zyM$+zH(9sdj2`ExruQ@D!)&8c#rP?rkrH38LKiLr(Aa>;-;Kn z@J&_2!d3&wkgQf4!b^;xxd^s5`y*lNvOt1qk79X$k?yy8MIuMFsP>~-C8F+p_cU1I z+T1YjYf&!Kreaq}b?ad$I&QX<_{ z>!n59U5;SBD6Hof0c!!$cJcV-o@_TBqy^zQ$V-ZUo$vufe-A?#33k3oyqU#h2~hFf zz&DAP`}u!IJc+<9XHu2_W8#NsXb192@i&Q^pW6Q=Apx_!#zZUs*Tfrb&ImK%ivJ(t zFJEL?Z!_15e}wlqmr|Z|#cPN+kAp`1_m2Z6E`x6T_|?F*@t*Rth|eD16Th8!Elkwr zm;V}Y-{qFI$!~u>@dkv1h@xy-ki-^BG)v})Q^CuBs zGR?9M`uLhb-28;^S;XTvFh)p4{aH->9f$<B< zpQ^;8)-K|c0{PDncMW^el>c{%Gk+po#eb~0gfA~p{0+tR^Yhb+?@~g@&HuIH%%_M| z<^PxB;uk+2;yvzRIzL{iIQTXB=PE9u_4ChH{Jx&}rxah&6Sv0Am~!K_)4wn?-u-lW z_tW_9C)Osv+=T9@Pj^3E(fxF#HE*7~c+Ok8Xz5q2=9NpAufC%@?QS>m&c%1GTD+RX zDPLP~-O^>tX0YzBZd|-li6mXWcy(4vqxODl9yYDdmZ$iW;HKfxOD!qqtfWnwNis-qXl{WAZ5x|Z=bq! zm5+?>>}!|IUw->yztH@p%dffnw%bh8*REKOwm{KG80?nB4a*zODQw2dH%}zcUntV zHP54$iz#D0 zd$@{B2kpX)8A#8NXuu>MHHvBXtX{l)k^2rc;67Y?_sXxjZD-NSQG|kiMR^Ef*4=kr z)AM+J&*MxzGBs{4(9Hs(>ombSH6y+C;1YyLGx2)hJ3z$``|&vPqGklL*N0k96qh^| z?C_!Pi7Kx3L$J<=l4FWD`*6Dt_nCC~ILtb%&8=&Fa^Cg7ovS58oF=#!e=v{nBF~uSdF|E9_oDf8c^eWLr~>?__hy|K77ZAEEX<)V?L}E#DOpgsQI4^ z)ciLp&ba0(4s24K@hwpt7^M%2mje}d{P@#;{0+sa_om{&cNAxC-%}jez#J=oDp2|N z`0;!FctUZ?tyLWOrl0?|pT8QMs=xOF)!#|zN*YI_51WC)$7&zm9&_YLy-FKjq%F8$Xcyt;mv1(YVSoKR-d21<5}Q)O%u6Jb2iLmDhOr zF(2AM@m;MT^j8lQ|4kAkJ{c(aHP?r$eR!|nxsbei{`8Xr#d;bcMHGZ!d4-YOVD{`hc_f!9%vd1&_G1|M$s;j=z`-iHT)mtbqX zCdeA_2C$y^n}Won*L&?%`*5NUCj*7A2B0ekr&De`eC@+FAJ*RB^|Q{0^*)>olw6uB zSdDuBIocbBtpF4~*8poi27mhLwSM|UrQ_^-L(sOY=Vt(!-&cK@^x-=|m;ZojZ_|xl zd^=F_cl`JvKmI$mERJqrHHDket;3e2{f}aBKjX>VJ$%o}P5x8-R;|n}ADzZNO!~?Z9T>4&Z9wPT)O22Y4^=DPRKlG;l5O zS>Og>J8%|0H-OIqLoX&eUjt70`$Xp( zz-xeS0{{T1>_1{l75GW=n}B~# zd=c>Lz$L)H04@WbPkuA-8^l)w{}b>Y;C;Y*fno5Q0Ingv7T5yZ0Bi+r0*Xw6J&Zp}LQ@UUQwOvZgN|%yi1^FI4-$Ws z`12un5-#(L~E2~Z_8Nmt(j1~HEqRPGG>i&^Wx-@f4<$(Wx-=^ zo^?~Ygrgqu_%7;s`LWu6=*|z3Pq`7XV1C`tyYsbD){+;p8q-mGTS+v&?Ht};!h6n% z##9&p#JDvkji+Rn z{Zbj@D9Ij2xnI|^TT9*n)UV5^CPX|8 ze42Qa@mMj&5*)@(sMQVC;eI8T^*wh+8SZg z2C}4v_=qvI!LzOBS`QDkdcKf0NUzg#oi~T|dcOF-y6JH}*B?z2?H#Y78#kn%cl)ot zdVShMdQCND>Bo!Y?Nd2-EMER|f&6yzpYP6R-l+3}o6o%QypM6b7^A*B4)W>a4~dVc zBcEr3OVgKwz4YbP9DV5^P5tru_lo;Y^{1x#E%*6l-v2`P`^nGo&i8wH=Lgi^*InPk z_j7LlkH)3&xOU98%!Ub~g{_&JV!!HYk99Eat(lp1zv|j!>v>ydrv0m~eR`(dS(AR% z^<2CoWpJQ2eowl}85%cv?dpU0WW1L@!smfK>dS@R9IKxr>W{{&>TFk^EY^VXe|Oga zL*G%qtytZEI|?tV)17B~b7uOXyd8df!L-%;w`J}bxh-=qIIuc)W)dpXkpLH4GSL_i zJe1o&jXVDTbyda_-E*%tE7g|{kJrRwq1b^;*gkMnnOGlX3=P?%X)8dlL3*wwuQz(G zBfp29J$m=(+2emAaq`<=GW6)>?;&pJaUx^bH^T6PM~}}DA5jOr z253__nPle2{?Ui>7Io*n^r5`z0U9#$v3ssMJef5e8gp^v%bpPFHJ|)fmuDoqW|04E zhvV{9sAEQFP0Zsh$uXt7X+DoN^1e#si|BTD%t?)~y>Z1zbK^P2X5N3(N7KBs!=;az zx}pGTkL`|_`Jlc8_+d; zI&2&BW9Grfp|8uR?PVt4?%{XoGSZ!w_-(gk>CU0J)%lv0>{=6VO@^$QX)Dy4Y_@*= zZ)b6Zh(2E|Tfnp%8~t+kd&88aeNKh>gm$h)$gRd%~yc1Kp(oqpNxQP!nl)`n1ZxobaPQ#B>Mg#7P}bJA^}LjQ^- zGP99&mc1r3*N2OcN!>Wpx?*{23p)?#7wNY}xj%SqQ(yUNry>2NS}SeR%VYGB^qc*( zDz_t6+N4k8{VI$5U%&43Kk>`6MRrvB>z8@u*;+U%ea#r}opZC&|H4micGDZvc;(NV z3*J1N{dIJ)aOX<<*Z(Fu(t3fcIhQe?6S7-~d-NjS)ZE*FdLe71TRvp(AEol)KzY3? z(V=nAN;g~h=NsBGvm1A2tfq(Y>HlMw)wIsD0hj#0?(k99_HDwZIQ6Wp?mWc&H7bfeI?}aqS~Kta^RE6MB^yOAS@JyW zk5RJG*x}&|dvFjVeMydb8taGJ7j1ycpsy%*`}@0b?6#kyp4zu;D;*ae?S`}+bJDR! zCmrr^()EmCBzlk4uq_k5VJ)yV(=Z-GFhrW+Yd;yL7G;cX>r;Gm`YYb>V zZ`H#29OGKFbk+O?%NFy(p0vfw{iHw|JAbCk;??t3+`YQ_?$z^FE&cjpuMBAmm#^%8 zUb%uYx6R|2{^EJdIe_Q3O&K?V!+~z1-`<@o7Trxp7B8Q-YW`OjFS5<=Gq!!fJ$8jn zG3&-J%$_&v=ElY^%$z-M_VgQO&AaaA8?T*x!xwJ6>Vj3=8{jopd6xxF@w)=LHQ-$l zIPv!d-e(`%{E(sU@8kT>_Hy@c$qk%QDe=y+Yfo3@$_W<{6vy}J{_0RvmMOvinf5Lq z9&GP<_OmoxyBdv5@r*Hzd5KYf;spi!QV zjK!IahY=u*Zlqm+faOPE0Rm)@u?P`^P1kfwHC;m+Mt~}j<%dGwYfg=55{adxd@BO*=d!FZe?{l84L*=hO_q<;1_j#Z1_ndp~ zx#!+{l5@@{6p?%sx68iEgyU+RvErE8PCl)y7h+1h@==`puQ1zTo-yKduY`|c^l!jy zNdGi({-YRuM)*gy(^o3r6~~g9$|uCFCdHjz;R@!+Cn{0tF@=f`=PKU!MB0ya6f9Fq z_D1VGO8iqB`|`$aE)@QWbs^ysjvF{;Yxfaco*cg#dwFgj!DEtR+xUdA$K>`ET#@W6 zsOI-IRDBt-yHD-DhQ~Os;?+Z{AMFe9pUW5)t6%Cf%s;IQXIWD6y^TYQUj|R}J@D({ zy;MV&Q~puxLC3l#C*U6QzXRJwwbWk}{|i{HX>2jxhaH2}U*!J?mY@DA<^Lso9PT#% zL)cbMD;)ppaF^p`tqvT@zlsYv=C~c6cJbc_FTl-K{;jaq$Oj&V55b}SJKzh>|4z7x zW)1cEWw_n(BHZKnqwuif&%iq!GpH!+cKpxqe#eiab02}*t-eo!FTkPwo(1>u14(HA z9(WdRvv}25dS#(){Nup;Jt8Yf9)|i0C!t?uY@nc;e3YRG6T}UTj3t~u*Lr* zTzXvfcnk0v#~*@w;j+aahDYIP<1fNz;VI(_@E8vex<=+es!J&QL4o|@0`YyopaA?mD!AId~%m3%_;FalfRPFsm_yF8({;$Iq z;c)y0-c2n$4}@#o@#_8@vQ}7{5pHaFg-x!QrFxz28`V z?X&qCSl{Q2{{il!&!v9eCp-&#VJ<82mlvJ{_c(rzo|TSoh1WaY1nZs(`QHq8I{sO> z!}0szHI9EDZg>1iSnq~V-a~NN@jt<>jvvR3)8hCkaI@p@gG-KYgPR=R1vfhWQMkeJ zyJ4EKQlDRkFBYr(VfcdMPr~ONe*r${`2U5^I=-A|?HR|d@JYuv!zUcS96s)NBYe#9 zB&@wqq5XaqKH~TT@L|Wl4j-L39n~;rMOvxZ`)hV~&3n9(DZt@QC9-hld>>hld<%pT?l$25#&D$JfC9jyvE! z$K7zR<9@iu@f~otW4*iAJKhC%IsRq1)A1tQ;rJ8q8pnSHw>v%$w>f?s@8+`O8{k&Q zJ#dTTAA*}5zZot$*1nS_$G-(PIz9w9IR0z6;P|WXMczfBe}4nM;JAgc!g9Q8ncGu-3#w?{BC%!;}5`l9RDu7;P{W>dB>lEcRT(f zJm>gp@T}u+!ZVH^$4hgU<0rz?j-LrnIer1W)A6g|Nyi)D3CG*uamR0i#~i;C9(DZl z@QCC0!^4h$8y<4}5qQw?U%&&7zXm9!U?sEJJ zxYO|u!5xmr;Wdum4!1j=gWDYc8eDd~1h+c=1l;2I({Qun<8aCGSK%hd{{%NWzMQdb zgX1gVg5&GpizJ2q{B-z&<7dO?9p3_zsz#8j@>+?(Stm8#^#_>UTmt*a}n|AzFc*=3Hnfu@I6W~e5 zH^38)p97COz6Bn0{7QJ#@g4Ap<8gS{@h*7C@d7;P_&4DJ$A19#J3a{aIX(jSI{s_8 z$MIL-ZpYt%*E{}hem3iJ{3N*3@fx_p@w4DHj&Fh69S^{5j_-oYj^7HmI^G4hI9`CM zV&(e(E?jc_3AoAeQMl3ZgK&f6zk~Hrntnd2?8w)?{#%m&s=N8C-_{kjZcI1yY#bTc zp1|0)jUyXI*yFvSl9c>9-lgf6_%=15uVLmO{BECL>$AChu=nVmO8dQpM(|xIz==@(gvYEX**<+k_zXdD49L|TQ=>erdOsmD(7b@ zzP38(C^;^^Nt~`s+QL3njRJ2P+mc@KCTNCwsKfnqH@ew z+Q=4Us77;#Q{ecPP3Tii<~$oY^2U3r2i`HdaeI|EZMz#K2GkqES#tDsx)!k(*mx)1 z;qHko8}1z2vgt=EStjnV>9@=U-H1@a_AS(O`{o^KZFSnDzDeh}`L295>p7T-+mKwT z%JDYdNgIzd{Z^fdBgq$=9EtPZ@y4w+6(D(J%bj=n^y)QGW92eso%yVlBXK7p3+Agt zQTaM0H-b;p)FOAvhE1azc5EI?&M-+*OWl2!Jw|BXP3TnIy?Lw>q{G^iCEN&Gw`|{z zK$&|?aFsI8IAub2W6Q|q4e2w?CA{&TO7p6pSDp{rCy82D+CLI0lw|8<(#L}|O44;U z`T5ssimOgKMXRaT(AUDV@!vG@s=}(z)Q#J#U3uFb)ki{TKv$oT$&7&)Iv#G zrBQag@$RlIZ(2LPc7qN)KDKe<&TZSbs!@3A*>j{eHJfW>`#ptf%AK3lchDf&zI|hQ zUBbaOAnJC{mTmTkSI0=N%-ZxBQ|T^mOs-cx_07@Lw1kdm3Hj8tgnTMj(Bmg~ zFL@q}Z`+Yi(ozJMmh`~dMoyAz&oJ$;H5cC%;?KqvQj=VJmPs@x<@;Jl^V#*L$ew$6 zucR+kcXGj@7fxrL^qcFXud9>ptLMwlR#D@p?e@M-?j^lgvMof-|~DIb;X#mRd#*OU~+>KWG{VL;_e4{5%5rKQ~_ADO25*nC^%8>+UP+A{9Ad*sdy zJmcQv>YAi&XK+xHn7v%-I5T$*)3InSk=Op(4ZNZ@jcwdIzJZdpUMPJvW;~3=>bkbq zb>%!Ab&upc`6GE({qnqr(@C3?QT62J5m&o=a3w!3RnKKqNttJ#S|f8ekYHo`{H^Ld zm3C8_n(m&BV_P_O?&eOt9reAIEmK^s3vbRd2&kO9bSdX zLPGb-O{?Qxwl2X}&}B($=(4y3U&kbZin$V@G}zw5N!`MWFug-FNqS0l)}-8Ald`TR zB|T^;I(gbAF?yBi2CM*gQurPk(Z5R*pS?ws?|NH?A7;awGjZ5EGx?srox<1T+3z83 zgX)_tJ)tV6r&HzhWU6d!Xz#$JZ08g;W_sWG=R9Gn*-e_szfzqPgn=L7%%BjD4 zM%9+JH&_yH@2=!~<*ikvLIl>G`NlUPY}uM+#^ z#`aAvty-c_jO9+#c$WM3Oj5`2hDpHQEy;I+D`%d4p9FXMj;T=Y9pch6Z;z0kyf*?= zyFl`;NRsU>5x$4YR3G(e*T_8ND@pe9Nc%%3q>>a0to-_=^3+cbxkJAP-TtNx$x__p zM{i4T4+8Ghn&0>7w{ex<1E`aXZN7U4BhRf{H&)a2`+?+@o=wXB-jO>>zs2MrNrenI zr@u0THcf0#fA^v9$!?y=@%_s>lGDO!m1uxuPByImRRc*#l6N_uP7cd)_O(pl(E(; zisy~BUQxVcd>)(B!_rxHnjB{at8}dyQT&{xYki{lfU(vmig#jFKTQaT8?j=oaY+2e z%f<(dwLUS4$0}ay6UFVuTAwH$GS>P;@r1F~CyHl{wLVe2&sggd#mmN8pD5OX^uf;z?tzM-=Zd)_O#-=57_Q^@vG+toQ;}*IDZjm99Tr zrgY5}D*cezMka#9y=M2DEiY!IT3<~Q6pDAH^KwPnjBZsZUZ2k66`!2W z?-kq9dB5UQ()qyRQ`33E;?vUk!(uySE8jEH`Nks9DZVkCpDf;#&RZ6rna*bxJJNa1 z;yUWDxSP{?(c-f?5Ak!;dDJ30l$viXqAxit%jD;X?6cD6ei41iF)^D%$7OFx=YNYY zO6P@(FH7f(i#@cj{4Y-Dmx~;9m-q+M`RL-y>4#$4dQSF+bY5HY%?o1g?LD&GlY3=L z={$OozP>2tUfD0pJ+UN9z5}xK^<`NE`wz-;?GDLu4Gzn)Z{&z9ld4B$*#~hn-~nuD9%3o;R{xTzA=*a@}QLlCH}sc5~gu zFGNm$EwYU6^KhDtYoGmG2|4n4c+JK`^aDPZQ$0RTv+;8F8nU;(0gbvwH0qkh(fLB7 zuC;&a!E!g+Udv9evEkk`jZ^oYY8pqgaTv|Uel#1|Z`itgFIqNeHkQ%Zy1Z74PTFJL zv#AbV|6-~^Hh`4|*&tRreM4AjkPTy{K{kSw2AOmjr9n1^l?K^3RvKgzSZR<=Vx>X0 z6Dtj}DXcWerm@l>lP;q)$Y!w89Gk^TQ)~|VGuYkOpT*8&AB*N%(CHhX4JK)WowUIe zZE)RnQxCrRnW=8$eZ;>D-M&5KX`e;AZvpMTDYW~>(e4{&|7AaWGrQ3wTSj}VgeF-T z9lSzTgY2AXS?Zia+ZBox8Lib?(x7)VZI>>fA42 zb?z6jI`;y4eLD9Btj@g=t8;I{>fB4%mCpT%ocoV*?#;x7b8q4MzFGAA7SQsWLdS0$ zeYW9yPc8SO&(@7T+cNrWCG^?K^pBiIq57NlqvrSJvaloBuPuF<{GQr^(}W8C|G)It z65R)@Yr41k|8l)Fu2rebUT&_XKlem8t&T6zPAg>N(M~&+*IsM4YaP>StNK3nKsa{L zB@6quODpJ-CHtt=*Vt>mewkylFTJ^+^XQ*BmFSWUvR|6--35Hz>`6yopm`Zh5j2mI zJ?V$g65)GKQt$eE&ntVWo$kdf?UL``LHA|X^Kp$Z=nIO6B{%|rno*{QzXANXYnCm~u;r0%U^t$10{!uV9?6X58M8d&F3&`rJkq~V-4-m5bpFC| z_SVUhXpN9(+Vbpjd1i8X)Sir}t9n#UH{>X>^>jmi_sOY-2bn86Age8{B`LF-{`;ou z!4OiPO8jqGIz!$}`fr$S$Yd`4eHOnvq<7!=rBdm=r+$faMzzv(_=?V@aq1&ymO~7F z`QBrB&*aj7*3z{Gnop%}|I^YnmiFmyvviG-efm9?KAuZ|nrWuY<9ZF{5TUCO0D z&C-vCbSv{okuuMR7%TI8EwA>n`FdVu>Doi*(;sK)+Pmk|A8Y9&x%A5{UB9FB@o%&C zT*#&W!;{kfelVB*cb0x8m;M$jr>P-Z{zDeuo=d;q(tC30zhdblx%4}&{OMf!yDWZB zE`5{5FXz(VVe!Xv>GxRrg*Li*WG0&7T$Ympn%pC& zPvv>H&7R%bkF0dN=fAAS&4N-M{rrcwK)T%UW?QycS=DLF5JP%yr75+_=F@V>%o^5+ zUvr;fiEAu>vNWi&S~gpL{k66$#kmE$b?W0+?bfYRb**spyxkJxdj7B~xyJ9#tGdiN zR#)eZ)-$uFI@>0?HrbWfwf@`!?wWe43_q72mcYmA5@zpXzI2Uw_V}(1=pkB>UeE8> zvS(vdKU@ADt-ErDCG`1vRgdqZYRhMRLA-1fq4H&_K3W~1h5dP7^>{>R`aXBQmN)U_ z^U4=i3aoSuYBwv?o=@#ohuRq19Z_=*s)uc)i2D4-i`Y3NdBgsV$oXppRAtjg#9!Se zQd{TbIh0I!*YUBCAy%jSRCg@K?TCq{0zM ztwi`X|Gn@L=5oR(9d_3Kz3`*VOH4i{og35GL~)J$vuTw=It*v7h_c4gpOum#LwQeu z7)Mqn)Dy zwd6C*yq^8so3P4LIZX2;wj)Vp?uxk0_FYCX`p2|QVlm0*+H`&-V8u5=3g@6lU-D5L zQ+1V(%F>5wSI$-ZYT_pJ#XccUHk_+m7nnEe_|Avd|7xe(6v)Eb3zXtDvd(8ha>^WHHto&cZ zmbu_9#ws`H(a3)_$CX}9DF4~;Alz;7x52xe|A*oIj;G-xa47$MuzvOp{70~E%257a z!>x{`x7FoX+7$zEvmL(+*58l~{QdAw7ykx$x8t9I_rvX$UwUN}+WLay9=OEwCzQ7VZg>19T^q+g4-dlO{5}k8-BZYa6rOYZb$FkPe*)L;i1Tax zhW=J?$p0c(FO$GSaEs%eurz0a|L5Rd$4l_AV`=kEI#x%Sb^JZ>UdQX;Wyk&SF~{5B zbB=!oZe%@GsLyY}TE7+ePv9=c55WD7FQc!FIxfRg@R;?V_3&A^&-it47i%|qjkhZv z9yXRf(+S7F33u}@5B2#ZJP30NN&oyR96q`~E~9VgBfs>%u7dS_&iF=H&tAGY{>uxu zsxLW~{!+8!pN310e-qa4ibMWS!dkx(_^Ytj%Xln(L$^`zKONRHIq=Ki3y!6ibl&k# z!si_SI(*jgpTTDwe+fS6__3V)3CB-|k2`)De9Z9{_^9KbgpWA>Rrs*ukHTelehegJND{0+Fp z@imNbn;qW_b4r!|@JhJJ@m+AE13fP0nd>WS!}f@v1^c z)vE>SwgEev7`AC=Q}r8)s#Zs>&q;J-o%;1mU1vtgBb!eL4Exp-O^>X5lUMi1x}45O zts{PRIqi>ZHl2Y}0m(WyW%WR^&g9oRQZrZi+NV_~HEAK|I3EKSTnm$|O-|m@~*atJla0res6ZmJjE20xY$eAK_#{Z2_^Fg4(Fc zJVCAN+b~T~d(is7{jWB9{TQ{nW(XqXGCxq88fFKwp6Zbver_O}Q^(KG4Ae&aJI@Q$ z9>69AY8`$?pw^q252$r#rUPo-|K{0%+9LCl0ksisDj@5uzUj5iHS5z=3WEe~e9d_` zNh?Pi-LmOHkS6-t3C{Yj$CV}}Y87eX>NVL4Rds4KL7dg8$wt;{)71KH-?!~ful3tD z=(>K}gI?Ef`?%}+ZO?RFKNlqGtL{k;JNUD8ukKN=?_cTMs^y2B{q@SP?_cTMs(aq! z^^z1UWtXz^JE~TXU zA{5zcPMnvcsBt>giL5WPLpXlDG9mFMC!}7hYQ{C%n3bV@)axD)xu>2y*8L(LyKy3( zAW4xu|7vL+kvw*rL_D=mHWx2XyvFjxYg{cYU$1IuF;Be4>Tc=z=j$dsBo-UxR9CF;Bd1I-lCsR7tg|imlvOkyg&#Qn?6~SueMIE9Z{fin;Q`O<0?p?DEfc zyv$vdzbYALzA4k2Eq9Q}!iLHXmJ7}7@6T2$xNN6?)|uP7U+b**6Ta>-{vKNG<;?s+ zv}}1!0wC%@44@`Gkp-wttq25Y->ZJVrG2pay`gx-c#_`(i>I*iYu-~li4|+!Q#@yU z7OVZW`g<3$Wvu*d{8PNRyYph?si5svw zj^;DPWn;}}iq{)!4o*C1tocmwn6c(F#Z$(b&lJxaAH%BN$1VM&rOz-IrgY6;Dt->D z`kb-!cIK+&pErBlY%6m}O5bJnyxAV+PL!_sMwK@p%drNrDtAa09>rd}E}eJOzUXnq zQTBxVu>Qt|=18Sipg7G(DsIO7bCxb01MTnD{G|MQ%)ih4i{{sSrThoXf6)Ag%&+-N z`H!0axcN_*|D^fPn*Y4{FPQ(L`J0%lQT%|C4Z5%X()RQ_@EPnv(H`KQdk%lxzEmwtoF-);T{^Y1nPKJzb{ zf64sI=09luL*_qX{$u7pZvGSIKV$xL=09)#3+C4!UsL-vV%0uPSk+JSu{ysN^Ow!v zW`51j%CB`J%HL)F_2$=nt^B>_?>GN|`89tl|ET%Lu)2Pe=GT0#{L|*2!K!|<=GXkL z{PX7DWB$G7*L<)12h6{WRr!a_f5iO9%zpx_@=u!ojQP)*|AP51nqLzDDnHTJz?NX; zZ^o+qG+!)#8LRebH~$**YyMdNF7tPrzsLNVPnN&m{DbBnGXJpoN6kNOe(8MZ_><v zA^EYx@{go*MHL;1JJb25x;hf*4`@D1`U7QICiB{4Uz^U06<8~;!iCd|+_!a4VUlAZA(R-k%La`?u4-{{q-r^UTj>OB-`N)cn zM0YxWDV>Q4#i55VDT^+}PFZv)rex8jn3jEx=}7dMjs%O{W|hu*wmDgJ4tC2nr}Mi1 zW*rF@a2-^6OadN~y;L0ubR$kE9^HtOvgLFhU%C-z#SE6t$)bmGUiSKQoj^rLqK!nx zP165JbR^KT&^iR^N@#t8^gpz2L3$Hf&rp0J_krwFx!$r*<9f>ur}Op2ja+YWC)Zo{ z2Cld4Gq~Qebb>C~8@b-HH*vjXpJ_T0=!Nu(*K)mOU(WTGeJTA__LcNk*_UwLWxKfU zvd=XgiT}ZM7k8i|(Rp*a7}x%PI30;~>u!GTx+M1DbtL-G@!)egr^%I(MxDR@1b!4je#ljB*xK`7@m5tjGjVU_tb-HN>dNEvzNSUaq7YK<*5fd z_`d3jd(SjYp(}xoK=UxV66grDcHeudyo{~{Is$7J;QHrb`U#-9l}myr7^J!D~*X6tTZNOv18adtTZNeV<)il*h%aHb|-cZRvHs~vC^2> zhn2>}B6bG5A1jTCCF~sb0CqQa89R?Xh+V)Q#!5fp2zD>_D0UzAax^H8U~fa0;VAai z*kjn+vB$Ajq2q7@`~9%=AYOx&9>i<0XR%Mfe-8Tt@OkX(uotjblYSBVdRTf8KZKPY z#2r}aL2SZG58``>lODuoSb7h4Vx{$P7q%69H@1wuKz-Y=7qRWwRp?c$!M+fG2lhqS zPV6n%F6?T`U5|Y++>Lz+wg-D1>Al!D!+lt3h4f?JiXFfv8X?$3BLtghgkTem5Nx6m zf=x6+u!%+pHqi*dCK@4F>16E0z5_djO*BHViAD%E(FnmN8X?$3BLtghgkTem5Ug}E z&Xj0t`fc}Ys%hdiLx%ggzQhHcj6HnsoTaZXpbIjEF332#Aj9Z_^wVd$=`YLll@k4= zOdo*{!iV6)@ZOwmM$ioLef}WjtIr?8s?Q(Bs?Q(6s?Q(As?Q(8s?Q(Cs?VRms?VRq zs?VRns?VRrs?VRps?VRts?T4*s?T4hrBw_4zVZeZCE=KHrN~pYOw}&-Y{1*9Wlb>w{SJ@gc1G_%K#|d<3gLK8jTzAH%AT zk7L!xC$Q?{lUVifomlnpDXjYVG**3l7gl|I2CF_ki&Y<=!>W((#;T9cW7WqOu+R(<>sR(kR(<>^R(<>! zR(gR(<>=R(<>oR(<>|R(<>&R(eR(<>;R(-tiyJ;V9z^acoV%5i+ zufQ`2b8dBXZw3qaR?xjk^hXMppnF5RG<4s{9_;Riv=>}j z9)<3AF@8f!r~B=x)=n>b%lST0_r>!A0y| zxPkf>O4POV@zc^hX@py^{L|!nlfE}oN776B{)A5@-<$Ql)Yl*pf)2Y%}HNAT+Q zswRM*KcOy%R;bJ2NL`jmQ+?9<{dsas)u*-PuafTvIsPA3j*p+?=gS7d}Y(eNX*-a?U!3)i-`2 z`R>acRDBEYKGom&rPG!4?_5aAJ4rpt`p)^3S}2F>d8Sf_KRaD&Ps^_4qYfu4{`6XV z-;fFFzb?mzwb-ebw}E9JVr+4v;Nb@ze4Pnz(pbf1*)SMQVbK1%PC^ge6Gf1uKjQ~w_& z{W$fv;9vY`=;x{bgK%q0dY`qf<@l?!_t}Tw{C%c=QYJR-W1pz>2Y;PDZMxK98`LeX7{KxLz;L# zsZQ@h>tl5}y-!P|CEU)v?C#s-UbExh_JoHx<}!J?&u)6?^s4gmslF2ZS^kduPTl*w zg$F*sKeRs{ytiZFfrgH$B>ncTFP{!+jY-X8tW6%8L-N5y{)b?rMdR=P!gnNtMq9xiq{|P+#4%;TY>{j*-4kvd2jK zdw2dA)=w*a#>N22`7NN0zrd&nWE)rAGwTt+4u2BuW5bHGX>K@C*)EvwCl6K|!sN?CK z*ixAN(wdJhJn-bT3lFrtQ1|QVt*PBx8#bnr2LVJXGlBX9v?w+P8KtdB#bPZc*PYUC+Hz_eai< z{$+kU{t(lF*GS*5A$i7shOtBO!R_U*{jD?xll#B?(W^D~SXF*IoIWdq7FF5hTUEF+ ziCb#9@}(MIciC? zrDc{)ZQQ=?#^B zlTQzSGhnlQmr;!VF$JAiO!E14;`~Q3`Y_d7pgQ9T@SozCwyu0a99vBlSNVK_xUmXV zkEM8;q4F8Hmbv6B({%t%r0P6M{8QWc@_IO-*Of`MPdIMin0@3LEmtJR4sBN`Tv1?b z;Xb}bs$aGiml5wjmlYT}xX)$Dm98dS##u7Oo_y56(zIadK+@RfX(TaA8VVyER_hDJ zZ-DzbOsmDe13Tt;9^M7_n12a-7}hx{|7WomVci1auVb63CfzgP@8Xn3;ZVNj+o$1f z^S=~6=={U*3CC}NFT$bxpNE_2=z;gcYv54+r{P}5=im{?S90D{F8@vNZpW{H7vV0e z-za>>`F{#lX9~yrHMrIB$Kftm{Z8%i1$e#l|1&)3{7>Lo3^{%lJnVP?9)a7fym44- z4JV9$3NA3MAKH5_JOGE|e-s{s!}a?scphH1{NI3wcqq*nUr$D@=?dldz*u)0k{}q>`S>WE>#JOGFO`n&KneAxV-hqcxy)c2p^F*uZe4SjnYE?fNb z;8}Ru__c6zsZf|QehWMYhw`MsvIvLx{ctA_w^06PVg0S7!2bxZhv{<3`CUif?{WT@ zz`by2uRGx>c*Np$Z=H1f0mbt?>^A>0ybBKXI}Y!0{(n?{$B(BXZI7?kuLEv}L;tuH zo`*yETj1l4?}b~rcw=__Ux9Zy{zLdYto1j^^8{`~2Q0M5S-2f0B=LVYeSbY1&VLOY zJ~VUTX5Ab3!|`4PpMd-Dsr;?5{T?3_f}1Q}_g?tu z_)jpFUz#lKu)fb3cf(rKt@5OCpnFp~Oo1oiX2-kXlH(<~$?-9`(eVYi!EuWQ9F9BT zi#&tE@wCqLg5wET?~35p`cY|a1>O(q-4XaGe8%y4_@ra4^E~0W6F%;E06yk;0zT?^ z4nE>|KYZA+)>CR66zZdA(SFB|<=L?4_^I$d$35^~#~a~2j(-eZaQsW~yyGQ!x8u*k zbB@0bOP4FuubF4hvg7se0mnZCFFAe(ti1st|NG$?$De?AIX(?fJAN$Bswv0MfOk5+ z6`pjw4W4j31CKl23y(SeI6Uh3Z{ZQgkKv{mcKl>`$ngu{vg@Bi@SyX*86I%_9=PAJ zo~?b3KMD6b{xaO-xRGaLx8tY6>m9!Y?s9x5-04`)+78FR2(NMcA-LV~U&3vU&%tHK zkJGc*@fx_r@hjkF$3G009RCd5We&kL;rd)e8KS#!{;6U z46HF#i2opb*72v{GmgIkpLBc$5AqX^Z-9?G*5B(p=6D=F>UcMN#PRRJhaG))!|@RH;I1@CwK5qQz@ zXW)H~zXI=d+`vG4kK^x!7aVuO^Nw$YcRT(Oc+T-p!LyEk9iDOgr|>Svr{HPF4g7v& z%JGxoosM4!PdeTJPdL5@9(Ozgk2!uHJnHz5;StB5gNGge6FlVjd)X^6=y)AG;J6p= zcl>&|&+!hp*YPg6$MLVi-Hty7uXp@8xXbaE;ZDce!_eXQT6m4)=fUlc2jMoy+u*X} z`(Q3n<^KCExW)0G!_AH#f=iCS0XI3mx}5&(*g%?ozIZ0A?}1+o>l3(eQ{M|;c}wrB zUfsdBTay3QR?@<@Vf{KeqO2B@qsnT*8CO;dzo5=Yi-g3iq)14WhDlyo&HHM^(}Gjt zHg%m5Wwnsci>5ebwcy@VtE?7WHOgw<5kI@AvRcTdGpJEk3(lyrT5#$dBDrS5Thfl?6tq@k!{3m(c@b- zZD0~ASE*`@l;f&@R>U9L>x}vIoHUttB_eYhC$?-0x&+=?U--;N<^I@8_SDoOF#)zr z0g=DFX??beaYa;2}6eD>ebB4PKJmT zWhX;Wbr?{UT?;t1spKrXEzcd@fYfS5;EV%3Fo9 zt9nZH{VSbYwfuP9tL4}CuXJuwCR*v*$iLFHk$B|3^xuU`8U`>d6mohvzSUdg#`C1<>YS%u=QtJbS%Rz=HJL{7OX z8mG2ixgWv;-KJvwz!<_M!U>INbi0SV! z<@f>389!k7877`JcDim(e_Kc+Zm~@ z;I7vZ(jPPHUbXbc)4FbkuxmH)qwl7%ja$bzXsmqC=8@c}AsfS==DUQT`1m7RQr(!2 zOQ?~Hsb3=>bSX!R$Iv|KrQLAnmdVW{(bK<&pyZcZv9=kNv(8IQZC__ZgUf#PQ2*)V zVj@>gUR_|*46XZ&OXE5&C9YO}Gz_p*NZkkJ=DH1lR{2WV>NQSAIx&9#XF}q)bE>fz zy`uW%R6WNVlb_(CUJa465}cuZ2lE(&W5fAN|OVz+4 zUSoOUHI^q{<7#R78dpn;dEzzJP$gbBdE#}GCtkN|Y55vdON)8pb<_FOwx&v|O$~$G zT+=7XJQ-rik)KqmuhK~msh(3*?ZxmO065npb2nTt>x)ypm4 z%DHV=nkzGm^3o@D9cMBWUBQ=ct5B%&Yta59%_1Ib7#N6w#E7(C{pZP=Jgt^G}LI)u!Hg~4MyIp2I?NSLo#NRP$ape=U* z<**@J&XWubBWd}vx^Tv+s-7A-!_c9hqFGD(H%bjx=tmTqzn3hYWsK`~w4$W$_qyx7|dTuxt zjmQkdY9o>%SZ#9bg^>)qa-lZhs!gpu&CCcYf5&B<`CB6$SmllpneVI2FXlpnLUppI zC^tp1edE>*+uvjtIG=BV$(bD!TQ=?Re}g*=n)Elt-Jj+T$+~sMHs8I2A7Zy|-586A zYGQ}%a@L!h)c`J|i5)VnFdJN>i5>EoqoRrJ(w!!@PmO9~Yu$*nm$kk`n#0aoJe=NyOd8yRa%p`$Cj14Ql1n+H`RvRy=4tY^;4C^6xR$J`nK;R`H3p zFE-Kk#cCf&;>XILXy0P@8Efse{L-wIU;9ABO<1w^fr!@_YafVMnzHh1ABb4mv1085 z5ic5RABgy{@fy}T>%6t!L+R3(RX*+a5Dyt^zlV6nSo=N1(w0@c_IHRUjJ3Z*tiP)+ zzxH>CTd-p7?@0W{T7xWJGS>bKaX(h^S~D!(Wvu-f;DnJ5&GhxyHP~+KwVTp4M-{E!&FQ+OB6X(O63th> z7Nq$~c%j&qu8S%@C0#F7d}_LmN?NY%^7G#sS^n#gy)j*`mo}&IB%sB+%Nlm={hrM?+%KepRP+Q{*QFMnlySxl>VG_eOvKG>AJV#3uy`d3~6{*Cm{HzO}lYK_I{;$ZjUl2E? z>j#VU`MqNL@IG1k&Y~=RbiZsVUAL%w2gLM|W!a&0{i8II4~e-}hh=HxBeJ%>vdFr{ zV`A2a9+z#U|H-mG@1!j2;Lgah-t4SwIb8=@d{VkTw0M2GZnUD=`*ea>XDV%7tv@Zk zK3$hu{GoKcsu`&&Qwvse11-ww@Q>6c2g zSNf&W?3GrpG<&6ED$QQ$m`bx(I;PU>m5!-2d!=J4&0gu4O0!owrUi6YrDNKFm5ym6 zRyw9lSm~ISuyR;+YP%UJ1{wqd1X+K!cu=^CtbOgpgBG3~@k$5fiV z(lK3+eF?T3D;?7wtaMC!vC=W^!%D}rA1fWx0jzXP2eHyI9l}b-bQmig(-Ew6Oh>WO zF&)E7$8;Pk9n%S{bWA6)@4)WF{seXkD;?8mtaMCwVWnd_gOyhAELJ+Eb6Dw^?#5n< zR_{DRqOMY4sk&PGS#XcVZ7?r?5w`)7Ya}Y4sk%&R~yYrPX@^ zJBK}q-HknioyVTVE@01L_h8RsrPX@@tG<2_yNE5I{kk99fL+2iVh>=Ou*=vI_8_(y zdl=h-l~!*n_9(WDl~!*LR$9HiSZVe4Vb#a`vFhUkSoQHitory6R(*UJt3E!0RUaS4 zs*jIh)yK!N>f;kw_3=rp`uI+)`uG%9eS8|LKE4a9K0bq0AD_jlkI!M%$9H4Z$LF!? z;|o~z@jY1e@x55}@qJkJ@kOlq_N}geh{lZeh8~Rei*AhegvyN zeiW-dehjNVejKYlegdmLeiExbeg>;Peio}feh#ZXejcknegUgKei5raF3n!`acTCd zk4v*xeO#Kom!j1xOqVQl6Yhf7!`*PpqguU>YV}H26)mSy(AO(}@^sKxV(^^!n(O$=s}>TCyB7HiRSmn4 z{-05+H=I+@nVr26J-(dQVeokk-h?9#$pa)Bm!5neCsh`2M?T0T<9uyBy6d zX~WG|`V_i`6-}?(q@lQ4I(QX-I~s@K`e@i|eR4thms8Er)gMDYIMG$C_Q6NBg5Q4X zQLW%-@_b64VLfOC_kLTnf^(Y3{|2q#ftXe>&+3Zi?<3R$4%)+dX8GsVS$8kh==WOt zom(l!Y5bmlgc`pM(ygnb@hkn`l{9{(0lbpNuQY&H()g7Ia9raz)v|6u^RBA#n_kyc z6Y6OEUU(RdUughes>W}D>-F!Y@mpRU*Z6Hy zpD5MW`0b$oW$RmC)K|~Epz+&PbBy{Lzw7hIxI~TL8IDm;<9EjNWb0}C;$KnY zchJg?Y5Wdcg2wM)C_kd{J79JDRyBS@+4VGj!?}6C#x@)`eO5f_V0LWdG=4+bF^%6) z@0B!uL;je?Z^(Zs8o!~O(h3^CmGg8lL3g)uuFj`nTukG)axACOo7ecQ9LvSj9LxE1 zENQd;duaSlm^N;r^^3;uPSeKCYy1vbT%z?$+=#{HHGXF;F46iWZnwqdHGbzUF46iW zZjZ&~HGW4eF46iWZrtMX8oyH(muUSGx69&U8ow7~ z?p2>p`3OBv*)wkZXabjZomOI`!v3bWMxP(k`a=%HfHT`HVZi4yJ@M*9wnyO=| zMdh=Txy)glET2g7E3T1$HWga9%p&(v)|d`ppHSXYU|-&G<}?p+BdR>*4dpSlos=8O zYi15tnu6gI%2T~{7^XIpkK%^yyNu%Gzr}0^R-XytHm6^c{}rQueP)wH{`)*}{-YRu zm~vKq#}nW`#WCGp`Gh#8uq$mM=XcYfW0k1%m_o(tc@#d=%t;?%p1X+z{nL4r_@}mW z%}^NNgq~U^(LUk0fn)Z+vc~UO8c72%H*U(XFQ%#9Pu?}3lPedd?OZ<+NbJ;u`b)!+LL=P!-l zDaX?Iorgnv9)yp=;rdDA_pFPT#&09*SVDQy_-%um?RdAqT`<{_^W6kXC$r618o$Gi zrSYpZUZKBA<99!N*y5$}JHI+r-5R`K9sO z2annDrSZGuSQ@`=tZ&kKo#c4}53n9798Vg*T6;#8#4nBCF*uxmOyhSC{%|~L{FYeP z6#B0;euv;*D^D7~d*ESXY5X?OIRh`lBXFqC33wE4viJh`R`_t4FG=IqYx?Tm^_squ zu-Ek64L5O*>iE*^T7tc%?=jeG`d)wwE?yeH7kTD{{GIRx#{=+r#}n{5$8)gW6(RqA z_>AMD@JYw#;S-LVX{h6lJK2~GhK8njo*Ea zrSZGhu{3`7IF`omf@5j?&O4UI?{3G^_?>esjo(?v()e9=EREj-j`i$Xax9JC{f?#a zJL6ayzq=eu<9FJzG=8TXOXGK^V`=thh+~Qaozs-(sf=iBXg_|6|0d92sb8v&>55on= zUxY96Yz_CzWjw1dIF?@fdB?ZH8Z(9XH^65dzXv|!SQ@`49sdPWyfEE4>-Ppcg>RHr^6aUhV$)%7aiXP?{ho_ z?{)ku@E*rY@PgyNgy$Wfg?Br?f_K%NW3A7gb^JVd#&JKq%kdAx(~hU%DaXG8?{vHb zPdfffc*5~nc--+7yc@?Hm*G*z&x1!C59nR$_-=T}@h*7K@vp!Gj`zdej_-%pJAM%E za{SM5r{mSUn>!r0!)qMB0B(2u8o15zR=DhV8t!+z0QWim7~Jdl3viF)0&AvQ9X|nX zaV(ABX2-9BOOAg8ZgTt+aHHc7zzvT77%n*ef8dKGh5mgOzTkKjKYyQhERElDj-Lyk zb^I#$jN{GlNyj_k6OP{nA9uV5KIZrj;G>R@z(*XPh7UXbCVa^8)%;%IpyRdhvg234 z2OMvJmmKea_dEVcc+v5D;eC#OAKvTu2)xJfX?Vf02HNwEzX#s!_&M;L?2j^7E7IQ{@U?D!M# zkmJ+vpyO}A1CE>7OVIE5>2ROp7r?!a2jCvZZ-BcU{|vm|@dw~8#~*?_9sdQ~;rL7N z8pl`g3&3{AZE&08?}N*ZUk`H$D)--8;1q$%xn0%d|rVsX!tt!rksYab7eJrbB_4g)oS>ee;gdNHy>~Sz4F5dP(Yrs97W@f_mK8maVbEGaA0G@FXWqoz?J- z1mr|_U4*OON(E)Z>K9k3k=O8bhYS9AW67I5z~XK_u2IKu8osXN#Hp4H8oth#iq}M6 zxT!1tJgwF6^<{D_6TUGGU+1jR@O8eNhOhJJ^u2~}+?8th=6rfCMczbS!`J1gUQH>_ z-o0(hjzsm?Mby{ubwSl(fNA(TpU%bU0_A)4CW$JWfQ8EyWO}2QDmdd8O9!mc@O4E$ z0u5i6%QSo~rAEWoMXDt$Vsb8B{n8|{>iSI>tFGVVvFiHM@||Q_?)WA=RyV&1X4Um` zp`yO3c$iakbH}bqh}HM6bZ*u1xMax!%dx+I-Pqp>RB`M-kN~+QDb}1(puD6Bh%{& z)u_MD;}usTZ5A!loblETKc>X5PVm;xYf5R+11q;_rbYert1M6am@6G`rDIi8+M+e7 zYPHpO*K7N#Zd){ORlP0h&S|(^LW~#1b-g27&|UE%MmDH!jFV^MM}{Cjn?0C|sb3=> zbSX!R$K*8MqBRQ2Z&7EBOs_kYR0S@Y4Od*IH=8}gMA}IuZ#CoeaIBRmq6N#h)ITkofJKs>wwUpkE@@bL3@u-RZbdbnZt9 zd7Q9pE{~1QB6)1g9P!v_IpVRgSj59)B$ukOgN-dCo_LLwCtl-fX^C>5J4<=uHLjMH z&!f>uyl(Qu>n2aUZq?Fa$BEaiT3SAjYF*o!imy!#FrLg+(MFQBskNOcJ9^CJ@Z-ju%gOY*hO@C^E;fu3 zbIDGR*B6ogfQBvGn9mF~l6TSGhW_%f(kmbU8ivHG)tn!`3Chc$O=PkXN_1TJR#VStgx5dYewf93jicS2+$Bni3Lw@P?%CEg2NxZT4 zeu$@ywf953$5?wm#K(-a_d|TnSbIOjO<0w$y&vLsW387KcN=T3hj_$Tdp*QK&sTdr z#0Si;y&mFetjgEk4)Gpi?d=dBGS=P>aW7W!+S`%%jkUK!e8yONGsII^#cOYdc*$6M zGsLY}`S)XWowO%I=?5&m#JX9f_nSRrwvoj`O7AtR^{?VG>q?V&)^Eyc&xFbw!s**ud&SOlO<%DuUF-L#zHhoFwsuWq`8=xci}vR#@>8?Z!$AwFfIL)LyK#Q2VgbLhZ-C z1v`M17V02YTBt)Uft42OBvx9eJF(J2ox(~B zbs8%z)LmFUTBy6R(n6ibN(*%XdntOqdx#5qzkB)qt?K>my9B-8 zLzF+tH8_l&%!#2&>;@Anv1dcVi9yRav)GuV?@>HVI;O7Hh9b~pAMb{=~kE4|+f zSn2&<#O}ow(1}&wZ@^0Lw-GD7-zMx5wuC)^ZN^IPw*@P`-&X8lY#A%P-!`oDe%rCq z`|ZO@@3$W-z25<>`urePeSHY4K0b_9A0NT0kB?&2$H%bhQ@_#{?+d?!|Y zdj?sid7#!hE*Rwj#VE&fmI(riB%sz zgH<0ti&Y;#hgBaxk5wPPfK?yAh*ck#zOVYY^nKOGrSGdgE`4A1aq0J}k4wAvQuKaX zh?Cy$?T_Oc^L_C?`U85uOX&R`cmsU^z2Aekq4SHrZwLCmomZmsi@xuAxEt<)d*Sl` zWqQAZXlXT|`PSG`dQkdfjUD$szOm!umz7H5x1TD(CAe%{hRblbaW~uzPZiSmDR}ng zKYdKlN9>HH;u4sBmmj~UR%kf=~HsIxXoiXXONqe`^ z@)pW(f1sjuTI2gz+*f$_skaph4|+YvCY8rOhWjUK(xssnInI9<{a@c66}{dYK3lnF z@`r!_-Sl}w+jJCe{F3@*d0^pzg=P9n_x!0+_s35+6c!#>T|{fQ@vl$w6U?d5epj_0 zN!qWY@R2j2j7Rl%AJyNj^ac7-ANsrf-xmGd`z!adp0A7FqW*5k7qoU)n||B}Deu0g zem*(Ie!j21@e7&b>Ao3?>Gpo-LZX#^hUaft-_g7+wNOs!?WYp`UD8YCKRaEDX!@S1 zyj#%j3|iRsei*i6g=ba|@1pXd#RnR?Z#;Fra_`b6-7}{yD<3{pEFC`8#k+`m_bT3* zdM{m7?7H`|_qKofYTkSBy;qgOeXJLt9VgLdrM%Me$4}R21UvoTi;qzMR~o+c^naz_ zyORE|^m|v*|82p)lKyWi{i^=;U57;LHMxe5>i>SL`oGfT zO*EA2=>HbDUTI&U4|3nET0U~BwVA%ncj?_qOFFBki)J&vMtn+NwcPh$YfGx_+{m&1 zz4U+ESI6~#*XVpo_4R*iwR!97|JG>pmQy|IQfcHiL0g8uJtC_keAJM?eV z{|#k(ecxi?)ydy5Xy-W`&dvL!Q;e!hbKZzwya{~PMPlKyYVAJhL0`7cHPHay}jF-%I~@r|IS<`nl-lPMdCS zUjKK*;u1Yx;>Ij4um8K-;u3vd;ub6}um8Kp;`YiCx6k78`oH5Am*^A|H)(Ns{oh>{ zHzP~jti{Fjf6EV}|GVh)fA{PAe=_~wfpD)~qW-V+f@Au>gO5=ES9-yroV-47c&7R1 z<)!HV^1Q2g&Z>LYlyB$kb$sLHf9#u+O@9w*BzxL;F!4wj76=>Hy~ zEa@$UPblvxB>3`%zCYE;Q+fQJFVXu@dC%mZtkU%9L@%d3036C=3OcFBItB4j+;H+O z{ZDbK#w}($(&WM%ahvVCjAHbUsqDmJlFvU8=Re_;qy%=y&21~bq`0LnKc*I!x zzf*81Us_!AaJTti3TsVQ@DIZm983RKe``IIFa6&&j`zb_(-rbd|5t0e0-u9-I+p&g z)^vsPr2o6F;lN&k00ylnB( z|DE6=GGlzbGIH~T@_S%ua`u^D`oGI?C{Oyo4XoV?=P&(Vtq}_>{onO)XwQSN{+4^- zzlQa<+(Y|*6F%tt*Iv%rIyjW~Y`BHBT+LRW*TMQ*?_^8b`z^5k=6k;}zu_uO!EMIB z3GabJ|NV3LD16xb=U}Y~3&&ecUq1kc^4G#zBUZNf+u#%MwDH~WNQq+_-v^(BLwUai zBg|BZzaO54L-}W6{Vn*w-_5-+1Jfmw^LrLN=lrjScf+AQe-u6fk68RK!JVur3;c(Q zhr7-HIrtbH>i75XdFTIb4&2G}G{oNkPr#vmFNG)J&|gO2vo3xLUcDt{W@3HKV$D;^#;{sXv;&KdY~@H8Ci^N;W@xXI$L=H3b)9sfpS`B(EsdjYKP zbH=ZQ%iM!1PkLS3VCnS-{#n@T1^+he^@2YId%fVV!A&mz!$Z-fsx{$+U1@gKmmj*r7Lj=ur#a$MH4%JGZfDaRx5PRH+nCmnwP zo^brf@VMi@g2x>HD?IA>I&O*)$IpX@9lr){bNzP*Jmmbd@Sx*;@POk#h5H@r+1uxM z70_*(d+;}^mw9B+V+JN^mynB(7uk2*dKA8~vJKJ551-Yth5KM_9Y z_<8WMsb1~dmKyucfqmrf9D-b8-KUs zyWu&<(*K=xEdAdZ$I}1Z>*q_d5P2+~fEOyo-|chU3AZ_ZIb3#p7u@RjUbw~ad*NosABIbgKL%<-q-QO93}M;u>{-tMsDr@=#xUj`349)<@T-vjqM zeka`L_{z#WcX0k3g93b#9c2i)fPm*KMG zKZdzvmHY2F+~W8G-0XODnfu@I8o0^vi{VDcuZJ5P?|}7D+NJ3S+pnAR`oS)_RzKJ| zQ-Rrxez5xmc2y(KB|2?9mnv<%jDB#=mz4;1P6-9pb>{VhT|Te=7xaUjds9w7*txR$ z!8u3#>}vIcT{fLTRzKJ|YxRSjQ|FN1Wtwx_?o_WIoQufpYt8x6%NtZ1bIz=OaLyUo zrRyRpdxC?0aIG)ikUHZ;JA-ZM+E48ARa{{Ya?Y3056=0JZOG^c=iJH0d#4|qb7%B} zb3V3_2mRojC#N5r^QL?KBd1u^56IdgyqWZzPm>{#@q-t{!Cg+f=Tvf3%?$`B^ zI)v#5=gKtw;9RQd2j^1h8u^P~J-GBMoUCvz>&o7$tgy?LE!xQnM`I+(VzR={uXC@+ z3g^;;Zbz;;lPr>`-8ivj+uaeTml~;mt!ib3bBC{y70&t563EI5*ZQ3lu5(t~Eh{VR zLUfLjKdH(J*E-{cCpl^AtgLW8Hvu^vU>D))w^Bjbu=>SSYUE{w-Qj}2{`n-&wYXbP zah`ZiR@jxCIMtFtR@nJcv7P99ICaGzv$e9qzD$l~LOmuc?3^{S!p@hI6?Psqj+YgV zyHZ)M#FF^_PF8`d7=3 z*RNWBeg8`J*ZJ4GHY&TGFUYY)FKQ5FtMAO}6}r9_1lpomgG}2>PA7C*TkN`(aykjb z+MMy$RqIt`*rH`C!ac<5wx`;9<&qR}DJ9j&3cHgDL!DF)C|cnVk_f#$Y(%`ZeHrm4 z_Yv`S_Yv{N4>EAkN}3p4Jzu?UofU?Q<_^Qmx|gy>R@hwtlZuNM%z&GE#hW9j$whP4 zXb!t0G9;^avbYlYwrH8=j5mGw(I#Hk;H{t6)Zn5AR&LXUi~8$VS)TYYS32HG$EqmN zMQak%9Cj_Axa+ljRhuqabXB1)>dtD(IfY+$_-u?<_^lu0)O+g&)s1lybaiXwV(Qn( z2VKh1;xRd0yJ$NGb-SpuMswITNvd=g&6d-5a!`Y+?0=CI3V%6QRw;j7o}GeUUrr$;6vemkd%dC_C*cUJWrdCg&WI&O%a`#D1% z8^A?8Hgt=4Y(O3Hq@^V)fVmpjKrNDo_ROVfU||E#h$miS<%!q0T3Wtd^2BRgEiIo% zLzQ^l+-hwlx)Bn;HhWxdsly+gNgti*#2u3~6)WVK5s{ zPIPo@3t1PBPV^>gqhse@8D!>4QoH1am$?YFQN7&qt(@Cw4!eqmQC|8I&K)o~lcDGe zzI~BU%u(WU^7<@8)nv~)^?`s&@z|94=Qsmr#b8z&IXdXSQ{ngPb>@` zbJ6OMno@BfjNz0cV zFV{wgx%`!JVJy9(Q0&?&j0JP?)lp#1Q62x~9NAG_q7&>6ll9*9Fz!SNxNh!<*A2`f zMLTco$lkqj*?DhnB$sQEFow$|JB4C*is`s57n&Qf)$>NuBMQaYgK6pFJE6@}t# za_l`)Q7CqyHV(_xEgga75;Fs<{2iBZ=5LL3yp=01GCNqAjm(7x8RC(R6C3NeqA!4z z=RUncv1<|CIuV6p7g4KFoO9Nj$<6dEl zLZWAi6>BYuSbJI$eN(Jhds@UpSh4oBB=N>au+l9pu-;u(dsyUe#43KLrB7M*tBno)yI}m|uHV z#7oA~A5PAP_2^1(#Ht+aRS~xuYp;s9%UF9;#Dm5QSe2taCQ9FD>Dpr=E@M@$_LPVx zjkTvle85{mK=8G9}1Ygosblxud`Y?;MQN}n>Ty%y3Jp213Acouu@ zNV;C>|FHKq@KKd#-tavi`7lNqAgqz5dcder0Vj}Rw5WpwjcuwCP_e~kLJ~;YK*l5} zc4-~RBt(sNfPiSR94zaPr)9U{V_nu#JABx(KJ+OqbeDD6^_&?FLF?{Pm-?_gJm&rX z&$&->G8riQzRy0t_j%tl!*HGdeO>q0b$_1weBc-utaHcHY@mf9I{T&g6L?fL`dY(mKQE{jzno&s%1l`J+AEIQb~MUeepFvx8pL zflb8IQIAN`=C+ceO>84YUEWTLI@L#ty1JV*V4Z!W|GmVhGYQfstuvHfl;t5}l-*%c zl+6)RoZ&o1inEc&NpS}C1Zff411Zh`o+QOtyVImN)Ali`Vx1-RPO#3HvK-IR9p!j| z^cMVwGWXt!@+bW|%Ad5xI`itSw$8$OAF&*pEPWp!S&W!XM4SK zQ2unEYn=u5&a=)4dmpvV4tpQ7&J=qex6T@S=UZoxy-!$Ylf7R<`P2U$D1XwstTVyh zsVINqFQWWOzl8E9eb71s?X5uh6Mq%=cuPymO|!xBztXa4rPHV1IejWzOM^k@|I??J z!EJhZIS4-Cyys?D-S6=rAo=m&#NiM^nWB8~8MHHeHE$)u&eNGJ%kG{Ui! zTQm%tlhv>(8iGC11nkWQU~5*1CO!U+)49yT=rD?v z4&zMLkUh9FqpYxLmopTHeOfh|tcJ~8+UJ}HO8cDiL1~|J0VwTrhCykcvmTW8IU7M~ zpR*a1_BkVssnEf^Fv5loR)i2{BAUGJx@hv*+hL~^a<&cHt#~ep!v?1c8=O(t z;EccqXBaj(t2>NP2sStqu)!JVFsc;TcoopisFAv1o^9P6>yx%gK~3AFpr&n7P}4Rk zsA-!N)U-_sYT70RHEolEnzl(nP1~fPrfpK#m^E#af||BTK~3AFpr&n7&`ah0dgT4v z$a?|g?7SD^d3zjoNmbY-jlwQz1a?WouuEDEyQHBG<4^*2X#=oHtDt_Q+1sVPG}?Sh zw;#m%X!4}(v*9)=9x?5124PEwb}mhuQN@2VXg`RyWni;nG;LZ8@=Kg{JJH_3qumVH z52bz1L0f44V2AJe3Ht|ap-I~pX8T}zOgoxY>6z>Om<3#c>8tRc8P7LbCO*bl>M)aR`#!6GvVMXwv5^1 zAzs_Ir3l51840ARdK3DtU-paY9>XuA1B=~RpuvUyZ>aOC0m~6zEiqm%E`~5{Eu!|&9IlJx&N7z-)Oss zCVv<}+?(Of_>rF9F)z8%pPo+GGBRziO23?w<1-l7I_b`PWls0!r91D>Io&&?JLkeq z_ist}NSgcWGB3Sp?n|Zo?lkvTrTnop_peL&vuW-dq&)A@I@9x@ln=U?(%fH=@+Z>Vza`zzrMW*T<1NCV zh&RF%-nPb@w(HF??x^8ayvbJOUrz~+p%};G%D!tb2N>s3RsmacCe9Pk-;7p*wypW2 z=^@*ZXXSju}H@}>si2g`Tk%i%|eHAb~Pre3Bkyh_O1Htd*ghE*mu8}l$v;=E{d z;=lIi!}ciWJRU{W$4>bGbMUA+$FtMxhkO;}?QrNmY<`eoPUN&zXV3S%Hx22+oF8QH z$2^Y+U*_5Q{*XER;kNMXG1=+Q(& zV&vqf-BB8mPKMz;^9Gh3ze5Mm_R!6(k$j#;7=HW9mSOtj)v=6e zr%(GzT6(&M;&)1oECb$zOZUrod2cS0J2GS5v`gm=#RmzVG00G!HYeRLiP zJZ!CJN>lotaV8nZh1-nz&U6XLj^A;z%sOYt#b)z!x1!v*92HR~>=q^`B4t*yPKrFrs050G2i z+A_IxO6jyIrIV)yOQ%i=PBm$8>eQ*qWTna!P~cUO+*_2gDbuG+Ghq;JN=c-(p|zp8 zp|-8z7BRC7Ijn7{UDzZ%*dGvCcTAosvh#9g=6bI1=K06?3q0dI*Z2xO*Luc#Kj*v7 zJJEwR|0!+HE`gFj+gmN#Xg?w3DeVo*VN8@y=8pc9g>7wsEf%mSeU?rs6I1G1mMm%b zPq#f10`DH!HZuL%;b9HH4A&0tW9%2ncR|yy9Ue=D(O9o9*z1AZ0&5O6Om2ph!?ua} zsl@)0eD5_e!(%vKmNaO(V(taG2Kh`v8UC=1V^R?FlV$CL*l>_n4;SPiVlycB1si}e zEPk*(HmEyd(-saNKns9;vN69*Dr&j^mRpupQ_4I8(^{XFGVr!&B))c+QW{tRX`#zF{?s{`1Uw zNr?sc(MDfLK6B5G7~74e4I=IV68|YE-@%I{j)TS>_)XyLz!j3eAM^|`^GyFAfGWsV zp~MWg9GLZs{A&>J3}8F_>A>@WLz4dp@J0v!8^F6AI0k$K*baXSFyDP`{0=Z9v%~)f z;35Y;4_xlRvq7It`#0B-}f!&?G;+JRRCm!O(7%lO^^?sedIfLU$W zm#{qk9+-bun|&DZ{{ZHB7CU{{A}{ub?MeaWITu@BcL4M6ZQGc-q#Z~bw*k`*q>a}A z?{?rFz=s|9?}1MO7b7mFM?e?380KvM6M->24&qtBXgRV6Pt^hvgz%{@D^hb7jp8+m$;8%b{z;^zA0$lIl(;hI-`PlwH z0q%9k{|U-+kApu6_=p4F2YlLr7XWi`vBO&dTD`H3UDKEv#dWe zfcbaQt0ev^u!4c2QsP$11BWI4F7P1-{&V0GjOBLxzXT2eBgtm{{AXbM!}j4rUEqg& z+9(|d%;#Q-X~UF#FRD5CS>h|KI}W@AxWIv50uDIvp96EP*!KTRV4l;k@jnAQZIE4o zy1-^+^KSvZ04Ezi2z<_gn}E+c@bkcD9QeNgf9$}21AN+nKLkGMz*ivingibge8Pbr z1U~M-O~A(-_<7(X4*X}phaGqyu;R#H3b@#TuSD6GIPhd(%uNUL|0wVwM|j@`KIp)& z0Vf>zE#SQl{P)0n9GGX}c02Gjs7rkgOnb`P9rz*OZ4S)3xYdDI0jmzY33!tOzXiO} zfsX*QuG!`L5pdjr1?p~(1CIypcHlDLm;*lq9ChGE;1v$M3V68#Zvt+2;J1Jy4txZ- z*?~U-ZggOOV7Lu4+Bgk6_~pP09QYyN`3_tUJkNonz|{`?25^-FzXM$9z#4Fc1M}Qg z$bqi~p5ef^1D88+6>ymYHvtD7_&dOp9C!_Ii39%^;9>_p2&_1;4qW8Gp8*#-@OaE| z3mkYFFtRjQA07hEci_dqxeojsu-}2#1M@?-%dlZKrE2Cwvnn5+Gu82;p23o`gGBa2+v;8qb`y!LWnwib6 z8)?nVW{t3B=452fT}EqWwm0Trgf%mpnbDe=&14=joJe=F^LR#5!(fli8d{i4x6ETp zT+%X+Ei|}?FnkF$Z3|&IlbIQ|e=w5m+&;+6{ZHFG$Q<3pcOjUYw4H+tK@4phWMmFE z$z>~dsEiz20vY@d?H6QZj<6?YhtH({2R92wMv!TzV5HRGKEX)V|AuXXk&#|}^?yj| z7nh;phHT|I)ye&Vk+Ipk1H(B(G1)r+!}*Nm;+*uIfsuay7w-#1V(a) z?FWox58DnH$^L)58!$4+^v!^g5{|8a;mo0te#kPJvp(39gr;vbq}PkO;g-p4U$*hF zjKhx2y!gO#sZELhm}N3MK|_|w=#t4YnJvkIR$k~IW?aF^m)H6)%9oe>FUq&VA8znr zWcU~7OXCR_4IekMGxB)x{Ze@&|5AA)|5AAy3O{q&hr+)&|5AD5hSa6fPyVISKeVAW z+#ZLm`=RhNr*A0yi}Np)e&+vTWy7#9#-qPMa|9PHSw}OyXh@9Z(jigeazf%w;tbQ3d zvf*Ul$nGEm#|q89qwGw9tY#Vf44GrF<%gQ3eHGft$(&;P$(-V$(9+XIPUaL3g_iDz z)lD|(w7ig$Ic?-*PTNpunc~TuwxQ6{{V>%dwMqGru9O{YSZO&SFRe+XNifWd`6lnu zzB4q%wD9dlIMUg1`QEM+!&+5(jTy#FSD4k<(jv)luwn4sIZZUf<#{_%Hfz}Bd7GK> zmb;Uge#?E3mwwCLW?W)TVZ<$W+fVu}cZa*2iIG_jkE&$a}l>5--O( zFmV)=eC~S^F9#*&z9(_7#2<48$+|MLdB<6l5@eGN%2S>a>V(w=Ww@b|ZOyX{dRf)Gs ztbsD!C#Czx(!CdZVP<|n>3NB1E1sz|p=dQ#G2>><%TF6jkHCt>e|?%Z!= zc-*VuJ?9W8!>u3%=HGz){8Ve-k@uZ>zn=G&7myDeCIxPka@>!kT)X72knT}XFDe7~ zC&}-T{9ei5DEXTtf2-tgm;64-=l&)A@0I+6l7C3@4@>?r$v+|an&h99{IimO4zvjQ z^JDLZ>EnJU!w-Nme}$mTf05*K|C9U@$q!0?ndEanl>Ct7S4w`B&r1F|$>&vE>Ms|R`pXAp{pbOFs8=$#0f?+HYX|%O#)tyX40tzen=plF$8K^0!L%MJe=PZDB>$Y`^KcUNM>`x$Klitp z{{X1jz9qj%^10tleu?ATw^9b_BS;=AC2hyLlf$dWfr$9@2-c{X6ehkRIYM zTl;-p0Eh_hY-@keTVc%yytB}5>3*LzFYrES?MKp{L^It((ryGIX(xu=iRGlzrQHbF zABYmeE>7&+uE$wNj#L)RxQs{0QX+YYGfIWylV(jnj zCLJT~MZn))VjL_>klOYlunBmG80X;*la816BB0!3#IOr-ob+?jUIgqzXv8>>c9K-F z_VK+Fq`im**1kXOFPtTRVw$~(VmM;nE)O`2{mq6Fnl_gk#<4BnaOH;8XSd6V9Z z@+J*i`}N*hls9o1%A537lsD;Z(q05AK{@eclsD-VlsD<^C~wkfC~wkIlsD;@P~M~u zpu9;RLVF;+ALUM3j&dix6Xi~N56Yc1NP7`w)2!3D*8hLhUc{YKgO=nUw-?cac7;zC zvWZWL$QKy=?fdz-)9n?i&byES+*K1HRrljg&BjgdTaDk> z9-LeKq|($DQ3jV5o9dOjac+46Mra|x9^@!ZOPku2*>mPhP#$Vg+8b-zmFni&_C+nN zOOyvIEO~}Uk>Oz~b<0{?l}4DrRhG82o8eIW|L}9sBhEzsZ$1mnzQX?aq4$ zL{^-Hl((9{#pHWg2#%O`nR;bD0`l1z-u5hhxx>iIrt&QRABH!{H;M`>E*RF{B|0C zKMkJ;-i{xJ4m18Mq~e(K(X2K0X_cTrCsi}pNnz2Wsja=Cb+{`#C}Hk;e^V~5Op`a| zMtZb%fyyt%zq9F?(o6ASw(pPer~eWE_JYXB^f9~KU#xF!dOAIy>`tK|eE3dIUGZJK z7_cB@D?KEuZDT#nOn{0@jC zrj49=xFs;ql$+x??z4tMDN#*3Exkqo?(p(XEM*y<=N8Q(7h=%mPPRf}%6Yd&2a?v{-&rz4r^A z)Gw}%CjBCs^i}uv(@qT2HN*BR9!=#3d&dQW9b@x@v2pZEWjWI~=PKC1f`9ts{pn2U z>MQmP>S?El>$r!V+!DNq zNTc7ds?U9r>FhO_hKR#|68xQFgG`sC$_9P8L#6~eYbp$34V8!GH}}RNU3o>kKi}auA3U#E-yd+ejmz&$1`uA<5uUSr#^u8<8Tc$8 z+W)c3CtZfRr%do7GF9V{F4Wt3?}9>R2XyEUtW53*tksKw_bO}kOkqFzdDf4WNd>a> z*X;LaLP2wG}`I&%Ji*p$ZtxE zFV_*@4Ag&nj?OUR_%U7Rit-*oJ--V&Vjfj9j9!`M-f>acKJ0n2-M*sLn~jJcwg7_b zjUt(bMnC4*z|94{h61;U7&yf+yBVfnnAIta%6Si57fX6>Q&ZG2=kjQW2GR;0#f%<@ zEb340>PyJlZ8qe{TRr**=C4quX`>@N^d;mPuOx-UZz~u<;ewLljU;a_2ylkoc}Vz^WvQaG-w*7^f%uvH~sb4o1Wdw%YB(64@izWgzaS)T;f znPcE5$~xT>ifZ0aObcLr0&;~h!;|_fxK5vezRKY9F_8}zHIjWa8)`HkIonQJJR2Qp8zyC;;mku7M~^QWifYX?P#z5gMO z!B6hsll87+L&bgo4LP2pj^|-7b{K#LKmT8i;Q#QoowPge|I078V@cPn680NA-`R@I z6*sG9*wrF^Jtu%Q`XDDT(m&-`FR_GchG(xy%!dHiR_%`+-i>f@t`CI@@jk~!4R`vr z!^4v8uyr5qZ#nC~9UjxoXoC3hL%9a)(fpr0{;(u(QqvLtU1hze*>I4DErDU{Ih4Dc z^_=@4hh_G`598#A)Y;sk=!6o;D3UpNCkU^wrcP|#0g4dT^10`4f9&vVoQaNHkI5R$ zmjVx7AjUQH$r9rM6#S@1@>!1a@S7wtmb^vOfw9$Mu9w*Ii-0x!Lio}D)1V3xTP*SO zpj>;ekobF`Tyrzm1R($Czz2aNlD`+U3<|UPzXFZ`S4;i}pb20*{0qP*9r#*=l?%O@ zYYzyY`vf8266yaw;6`A-#9Z%h1}>7g3Ah{B4u2)^cHp4o$AM2cEi-8jkdF>Q_j5J zu(ScTPq-#0Ww6S~$M)9RwsxmG54Srp|3Zlq%gYu{C+lj+Fc)4~CH>a2E{3(m+7ONG34;PfP~8kkPjd3&>18LWiEOHVqEC_U*u zSb7p?2;P|pDK%Ke5)Wx$D43}TYFH}GD?h_rh6-JJ!=)srz+eeWcIHBqOlJ*|PAv;9 zZQ8JXQBA!p=3yb?@9j9FZC~s}cA-fhyu{^XI|@-sq!*%j?W?xEsb#5H(y*j1@~r6{ zH)WPZYUI(##%D}7i3XR(&DDLDtYcZ6;|R~Ap^Gukp%qJ9A~E|N@)t-Plek;rK8bfr zZ0>ub&n(6`Kz}8mJl|F+G54*BdnD#~M0`l%!xGa*3H{FiCBI!_^V}jZZH|zCNb*lh z%=3$s&qu#SegKrXLgGq^dnAra+$S;5EmEH647uhW2Q9*2yjRjA(mfYr7Tsy1lX4Z3 zHcM)sBit+TNlEk3MN^*kPDuIphDc+QZkLocGU$FmQu};i6~-32w@bQ7(u0zIEGhq< z5anh_%D)pt%)bjndRWq8^!>yaNTGX9WQlV@i@pdwf>MtKpwtWg2`_X6@4|~o2geXE z(pW%>^B3kk1Zhx+asHx&6vF0w43lF1hBFUaXEel|xH0L-SCRsIAa$rED2Mkq;CVx}`U9?c zW{sY$`HHNy*?5*mn^}N8oj`5!_%A%En!97k3*lb9FxZidDpBpz>ZAIF$WeWRS7=$) zU0P0cr?w{RMs4;yRo`13)6a&E>Yu1b^>dIpA3m!0dauwvOB~hDc#i6?d2_WK^#v^- zzih6@#9xBF@R;^#{HVU>gRe!ecXQ$qZAJ7ZquN%*(KRdOo`X{G~;AeN_fSw(G zK@;IF&Ch(Uy;&;`y>2KB=dGJG`n|ti)t`y(Ikg9}`H61LA9>w)T7CPJ5HDzNhY#p$ zZoE-jQ#Hxd&zi_YZEy7fz3QN<-&d^a?<5ZBeG?Aola9QUJoDY3o@P04jW;aU$ypZr z##m+XJ*)xExYL{BUXZ!Rfb}U4)|JL$EhvJuw%}OolPT-DHl*(xwQq}0s5=T0tCIPm zTK^KtJ4>uW`OnqSHsAAw;a5>pi3y#?qzS$7Gbc44^&%f@`2$$%^@&i*lRr0A7G6JY z;QB>LpG?pE(#^&O=#*||s0n3Z(g*wTt;)cuw&1|2*1*7qw!lDF&E0D1 z-x9rg&E#0}?J@gxFV^k$g1&>_@oPM(O(I{L1YPV%#Pm-BztPtSk2aw|)!!byUq9=> zdx1Z7;CFz}IdC7sJMX|dfiF1lZs5-x_$}Zw6MmzwMOUEsReg{5fL;*pG|KRUE>9OE z?lbjir^-t{A3>d+fjw-9?FFQ8xO zd52TSZ(@zF1G>)^kLW)b71?|`$a&)G4qsf|QhJY? zdLDKD&B@W^u3%h${>!k}k2W2|{$svCJ3?6;E4TKa{=WAw`va)&#gNGjzGS3Owq4-m zSHEuT!un_o&sj*vF6>(hz;mB`+1A1@B5XiuUolKn?3D*%@ECruhE3q+th)tPu=3}Q+MPi zUN<%(e1_>$Hd%25NnbJ;hac%;JXsfw=YTeQ?ERW2uu7XXty%LUJWsF#aV;2(3w3J; z!($#*#uZ>(>t$T)`wL`T1z{_$?8HKCO}`}U~EQrQW0%eQ}}?#dC5=_?Wgr(mD^*SXNmu0RjkT1V20 zHhdCw&L4Q)xc)D5Q-#Xw#_x6@ey06%Gn0V``bDH=AiOH+kG^gURCgqwyS^vsnW3h- z!mG8;>eX6qv8sE~{y&NQLI2+VztKL4eyZ>PG17bR1JfP)N%rRCXb=A28(Mt%&Dy|s zMQUL4YNY$|lrR2#@`{MMs<|GAcx$y}uUxtdi;U$`sjtL{vC{`7%l z7j!gmeRs06x<^|r^WcxXWPB1rK3d;xf`?W81G-~k&ilKYt z|e@j0fX%LZpu0hqd_x*XBj4xfIU|{>H>3aU+)K z(N2tx8@od%^bXYf-u<~L-?UX)3}a_cbRGUK7xpY?sd_w&=V-LwpID{&Lu>oR=uICs zwIz%I_GA_uh#DK=FFY%1cmmzpH*QE6?{s@o1>l+eP(a<4ACC4vmq4=7FAW6LA2dP+ ze^16(5n5+N5l1YHy&dE$U(C_-6?I2<^*Uo-0zCA6QAPa$&pYf1MfJL`sHxqNsE$3C z|Oyk#A!KQVO^HO_dfzms(m{gc`MVK2P^eVpCD zVf-FfcBg0T$(8XeUv%v?Rd;(*-@bZ&>f0}?yL>1IUsT=l;#~sc*L=MZW1cU_edzi6 zxA3gri+&By-@$X;otFDbJflsf>YF^N9HFMNL+CRS7}wC2^HH~Ypm*w+{c+E{)ta_% zvk|LUt-bkVXVSN2Q$PD^vyVm{_n}_1tl#`fEXjU2JMaxHh`K1C%OLdN3vcSjUebHD zu&d8KnqA6z^uN8j2Yud}9FO+MxF7Z7Zvbe!lrFRFW}_bcf%OOJsGRnStUs%b0$G2e zBC4%|e6*}bTUFeny?J*>^3BPsk{;~&ajwIDpZz-9QLgg35lr-$V}&36Q7-s}JFt(2 zeC9^Kp|M}eL3>s^^Cy^}vjtq3-Tz(p!zbALFVwqU!7ix8d(O;PvIBK5uyso_9L0-J*!#w$qqCWC%?$MNYMpqL1f#b>Ri~L+Ck1|OA z_#?=F9>V2W3!ZT>=aCPa=czwpd<#5Q{!SxLOkXi{%JU}NKdjvz8-sL@`DcW~`Y2fM z;ip)sbuPdm}9KUvhR{;07;8qB{2e=6MZOQ=e{N8?j_mB4L zZ@su*-}BA=`rBW_{PQP>6LRlB<^b}~IsF-)8A92N!q`_gDVF3}mX}d?1A&g@&R|l1 z3hCqg`8?#IyClo}`_L<1_h5f;@`p$7_CtqjjD^9Oskn%r&aIA{e?u%k95>EC97~?B z=}d0&`?d3eFP7{*>U>&JrBsOp~ND5Nn9^8?NStM+4VkGW8OXq7Q*D)z}S z55jn0h`@gI`}@%^tTF;(74j?pCLzMeK^QrXFb?DILD^v(z`Q;eVW6IT#I|s5_T&%Q zKilshjB}_@j$g7*#(vIVpN!Y$!9E##T!VcwWz0VLTC+XszOb5NKeq~cIaY$U8|m%m z-=1P0%(m~_vbNuYzLx!LF8Wt2M~p{bZnn2YF#1ee*_-M~mY(^H%oFt95U%BWd@|Y*+JTAEM*ggS7es?0fDv z=Xyur=7n4LSWoKT@%$#v?7g!jYK{+P+9UCP#%=d~{{$K4w;p-7^-Z1g?`gh?_FMN7 z{#K{5#wd<dEHVYqw!8t3%!h$pq)o2B{G zjr~{jZR|%r^_~)i6=y$LhNV}>O#1Ut7NuLz7c+k5z-7QZ_rdp5u5s)N#C7VU z2Iu1Ly-iDT?PG7?2l~#y5q&4#&v)ZTx3@rdBL3aV5xn0mOzuY7-jdH|I_2{oxW6r* z-^TM^`Mej;@5twO@Z2}S3WsX|JR``z$5!)8oH4}sS_s{b61z{265CIsf5)%qwEZ{O za{XA#qwH63-WC1!rDQp7Wxt4e1G$<%k0xusjd1{D7|;41echib$JiDWnDh5xTteOR zgfRC({aP5GnJPm$1yD|f7!%O8KJudc+tKg%L7yNE9?;9DbsC=VW64-Z)iKtAH5 zUM^%f&S5-#EsAHf@jOrdyc9Yu{4Ke8smdGHX9bj1zRDXqvpz<>x97!hH~6=W;BK6P zdm+{&*vGWdKWHatu7dFjW0psG4`Z2{S}|t5ksrXg1uB9)csF|i;|Sgb1FwVs3uDV@ z-cx$PIC~A-=DYm?xNn)D>eYq7;@$pSgXv*h7#maV zQ#+0FX-MCsRjI1Li{Nz{KSdh1PhcA7q|kREjdN1pVH%OHd^7w*#)^qtmw6X|D^kVy z&$M4wklI{5M?{4#N zc?bFK9$eo~J)z(B9V&e>%ZD`J9Xxg5-UGize|i9J2IoXf|G^1NJJKZe+=Dpw$~!7j0>3a` zMtE81_c>o=+RXkuh`BFhe1Z4+Sq7%=6@-5?#u4~qc`$5&va;ScG5-*#JE#XD&||!T zH2Z?T=w})jzX-xl5bp`%g%6pw0Q6wi7o7FVMV(=NX+=5)^MkxhV%CCK0T>sKZV z;3nYr{HUlo_Op&K4MFf(HyJK@MQ|%XI=JRi2A)?r)GrVp{hz;{{MXI(O{TR-vDP-% zVw|G>UKJ}f`rR^C)nCP2jBTL^;l6PLuxBOS-GkORX9FLZ^$I#-eWR`pn)Pm#>4)v*_fm#q{KaH& zA@C#TJY)Vhp?maKgL92iy#EE`*Kl19b@~A7cNgXjXMCHDRRLA+h;-onW2Lrobf>oZ zsZPy1A*%UGqgnvx1)s$_cObgX*oJZH*%hmkxuKPqSA#|uVtkvQTE%eGV|sRYp>{_6 z9p^rX_Z!*<%+pw>IA(BdcbDiid7nV`6Ub2}o^8qOzXR!Y$ee}D*)*AhX)>Qe=F>Ep zpQp*3gUq=!nL}wZ=OJ@GP3FBcnG2A)kS23DP3AMme3mBj-_m5xY&oW%@eI%Vku;f4 zAoEF@%x}_U&O+vFn#{2@nNMdzKc-CmU|IaFDHAixqUI}j55yS9G1D3khsI6L`3^P- zv|Fr6hSe?EVReVKPVktH?Vn!(ON~byh z`$RdW+s|hm&!0M;&pDpYJDx8%oGqj)W8Il2-OkinX<=OnNw-g=8|%g->2_ASu`U!! zH`W8@gJr)f)Tu|=C*f0#-#OlsK|jH|;EAaEe7w_BmUW`$ml(G&r^*hm@3-evLOh0Y z?>UWi{_zXACS;GH7&|$ZO!;@dJD^{l!L_?i;~eIUbk9Mb@ICN2=CPluzr~X}i?g_l zJ6Ibx)NLu~O~UI+cDS_D$ZlJ$m0({; zU`$-VGsl?ou>EACzg~sD|19$SoAU#|J3bZnK5Ew+zX8^sV+mLv==-BHD2ECEh`ot= zoCoJzGlcg^=te2qfN>8u9b99~!+Q<)46rTxT7+w#;Qb}!mQTR^ z)Puj@UD|7e16bc0-HY))im?e}GxkUJ-MjDCD@OMkWu-XPjkOf6d;A&pA6V|ovA6Yp z>2HlO!2|v8m%eK(M;Kh|T@Kk}6M1(kV0k#(cD->2Zt5ag;cCq3qk8OQg>j1yyGoSW%hrA|XwSqz_P%MEm9UHBa5 zLP#(8A@KZgJ15;3pPk+r%K9v!bY?Nl#ZpInzu#TTdF9;H9MsQ>8+wf@yvGKV{i#s! zK&on5%xE<0Y;S+X4b1yo)X`pqqx!bq5X-_nH(%wnSXQx=A>V_(PW4)ALhVy~P5mnv zsI2$-UUUAKBj%3vB0lDUx@4Lvu;%FfhnJFPQ2$StLl=Q~e$IOR}_Y9uTmSm1MJB&Dy4-rONLY|H- zjG1%Ma?xr01Yt7W^Fa%OakI>*>mpg-Vd^1|dbscEm&|uqK4&RI_`Z8yN{R^9fdU=L z`M9&^k?R|KpQ65d(Qm|(LDcyfXb&C1E^R&Duf0mG*>CK>eLwn}IjQwnr*EDRGd7{0 z=`j0}RaRf3u`f9&`;vp`OWrZxJ%{M`&Axl2pGDq$fw9RuSf^0;szCX-%0r->*Pp)^^VBg><7LdHXQ2EyUmr_` zQ0FS}8}mP`H6ia8t$Z{?cU;rO{j!ZLJEp%G^(`<1WsG{|5h1fYxPAed!d&cwmz1qD z+a_?XQx9xo_V{}U{SDi14$62hp6xcpws1Ss35q^{JmYhQfiRD6haSsA)>>}ij8Ul& z@-lGm!>J0;aw-F^96+fQ0IVaDY6imZ?I+Pjz#&I_4-MR1nGT(oiC1>PlMkhvf0qn11C0MbynTbAw9NW(Go)2u&jc+LWS3N(TGbHvkWBrr~x z=?BJ`lEVJPYYOv*dR0IgvHG$?JQq3oveQVb)t@ak`?KwcFGpFa9Wlq|xv86xUmw!+ z&3mz5kWlqak+Ft1)RXLujy3MV`pU*?(&psW_*laa{&sb&krVCK;*iS%-3GombMy~t z-&iA0ecn7rqo7aEs(wMcxeaSUp-!!M)@t;hE46;CdEc|NE1CPq2J~6gNm07N@Xy>} zHP`6HRm)6#Z9-Nax_B7_CSofQY`LB4*&wdVZcn}AUtK~7A z=sh_p&H=lx%SqYc`4skrv3{%@VeF4#PW4;d`|U_^Zbf(|)b zqhq+k$bIBFI>IgF{4w_5a#EZ>dctZ7b3CI0XRvUuxjz^08u{T^e-wNX)=~)DAg23n zbFLb~zGSSQ`Sl{49E^b+9}({98JK@!9*2Bk9*S@|N1ccHgh*ig6rCSZ_g4C1{XVHP z>MM%Au)K`#vUBve(a+3?tT962HAY2rjj?G=+{lrA+jjJQKe{U~wJ|$a`{7+*;=Epu z=i(g9m=5g+K~-0>=jy8?YU!I{wNykp4L{=Md}xNJ*E}y49NlZ&j4{#7N3a!l;nitq zZ#wgccK_a_YrU!H)j287eQ|2DAM>yz`4dssST58z-*qtmP2B`aJ+hwrP*+$_sdLs{ z)+aB@z#r&1d zEpt*?Oasz{dHA?caQ!&wV>I+II$v}adSu#|E~bz3(Qql=RZu>DZL*P%_nZ0&E0J%s zC9Kb~-#dN_&g9~!+zQ)hpxYh4ZRlrs=7#Nn=W>|$`K2on4(4`fm(2*f4);90!C6VZ z520@Cs7KiKLCo7A$M>(sK^dG|Nt0=W%!08`J{4zgf)A%AL>Kc{y>vP9WH`j5B5OodMrKs1@?SIANuN$igQmQwNv>! ztuOdnJrC^;YJVXQ^~}$)BB1Jx*;d)?R36tU(>xkud~l)0`_5j(!F?VN;#uSKY3r`^ zX|u3*x>Gr=e`wANRQ-qlo%7WVM$~+d=t6sVeNgv-`!^dw=wSxJ6lkC8+200hHH@>+ z!`#$*v;)p3n@hVepAva2Gy11a!kkZ`Y*;T3FWWrsUX(+xg#yIZ&ewNa$mH9Rp-WyhH%L8i-kqbRRhtV+`jOD>q zS>%V1ACs@HMY`suR-n#gsb5O2@p&}tS9m6jR!1|9%s1DD*>`QjJ0#8-{2cY?s0Zhu zc8V^&a$1+c@EBGkh`12eOX%aWQO>JS&RICSbr^Z~U=65bLYL8t`8DUiZ$aiH*C}v@ zQ#02qHuQ(UuYfG_r%_K_H=?e#Y3q#biFHOF{BDY34;g2>w&E<;ZWZUZ;;?^$Ga~c! zE@S?_E~63t7a*LFQ(Z>&BV9&#OP5iRadg|hAv|sbVyyVFvohU9JPrX#v#73fxxP9@rk)9FZ4vcWy!RmeHsyS?AUME z{)#alZ$=q=6RcAm$@YmTZZwO`^|w##f(&$rdQ*-42&Th& zx3lUc)^gsbF3Q0>K6wOoxprJLxhuIVu|Yqc<4N87 zIgUv#^T-bHP$cgKcl}k-z}+wifK`dy&BdrqQ+I&_h&ivB0Q%KYyP<_IsZXV zignJefBw)0xqke8OyO}h6zi)P0Ob0yRo9+?t{Kkv|83xR+%rpTPN2VdB6S7k6rR9? zV?4_9V|r0u?28*#bm1N3k<{V^U4wn}#?J=c!(Q_EI=nw|j?A-NeRvmT8vg=iYNzo$ z!pHeo*oM$jX5B}<=eSxS>wg$L*5w4&lC6Fb;h@i{9E<)Mx~Q18An&JMZG9M;wu^$GL~HyzdYPCu&mX*k2jGg&BmlPZ!1hwxs+u@ks*Y?twU zr1$q|*SS)+v;HvfyVv1X!SX`8t-Qg~zo)!oFx^ujYoE=lWt5GQhVR{four!**G;aew4qnmdsIeWgyYcJ8Z!hIaxJMf`62w^7EkK<1 z8I*45)7H^jsP8X0Fy1}JbIpirL3KFuRE#+R<`sGv??#+&kA;q{@<)9{xLnU>d*qrB z`(|_AkNGy+E9caIi}~cna;z`mw*ZTz%kfL#cM`wCyKpZHjr$*1pU;5_l(JTjCtJQFJD|8*!c$XZGsx-c?+THU#}B2fK_( z{w|}W0ON_mwR*hkBi%e#_2yNvB=1gaOnA`$b|m*|I4i5H*ZJI+IHIcpd;Mm*>%zkgbhVf#ck)|1~p-P{%f zpL?~|c+T~LiRdE)=F(hCTka7rRA6n>H;r`!YtGPr0`IRZX9dr`!1{i!k8+IT`e-@I z`26i^DlsOOwftXlQisN1p8@ZMTmx;uT{hlb3ZYJL?p*=ec#AjXP4xEHgC0a331170 z`Y~{Wz`Q~o%XiqT@xI9NpND-GwwYeE`;B-f*@Ry&e%?f^KMpsqzFY6ZtUt4_*@F7j16lS{-^X(={BxcNyA^rsJh&Sr*Qc(%8t+-? zi_jMw*fSyaF8ZwZ#=z~HnA3Yvcj0Dm?!tFxwl}OJzCTLoz&L|7Q@l@Z%Gzwql413r zZLyt!H#XX^*_em-Xj~l~&-JsJXvcopX7528FO<)UzYDK8b5magzaHh;n#(hEI4jP6 zQ|r|inPn_-qF4V0aj+M4zgK?tD*bGL+C@HU$)z3q(vyuG1?m`^HVVv z@0HhLO%Qkn%9k`fPEQf~c!Yy=>7xrjz&V^)Kl}RbLdzf1I)ilu?tjJf`Ff2zuN!5i ztrF>C+@65Y*r$;9tmI8{@G_;tgK*8Xpr5hx&osX;!})g^&dIu=IP7r#g)(EYhJm;b zlAnM+;n!EN4|`wx%sz~=PTd}apN)_m)Ia3Y+Fs*CmPoBY8;`DH{eME=gZ9ycI*vN3F9v;M^D1rIz1DO9o67{GjBCP6bvOHQ2bjCDfjcL%t993V5b85Dmz#5-7Z+@z1Va!nG#Eg5R>J7!{ z*DyZZI)JtAZ5`@LPgGsU{UYkVx&vivzK2`;lytM#<*oM?Ywz~_)#}kNKdBy_(5xQC zxy<)@w*c5&_kdf9Wd)hk2dF!*;?D27T%R^@_4DX+p1}M$njE+e{ZCxoF$!Zcbwb@f zxIxutO;>fS`+pQM-_xx%g|g}LOi>VZ?1?qfRdQJVEj z)~z4@e&BaaaASQ^(UzlLgo`@4iS1g%`rlBvSC92cxNSr~#kJMf5N1@aKQSH4iegEv z#FOfS9LENZW!`BW=6J-oo`5{hw(yzqEs#IqkmvlvwO1JwjVNiZ=G! zHJ=T<|1!ejT$lR-c)<`M6kHL0*8P)5lIFS>&gkLDMcyXtgI$IBRpCyw{jiF20ke{u zFh}$ES?i0UkL!zC3TsDLS9sA{qYuAm&VA^{^zvP3cWun5495(0{yOMJ#TtCfIEZo0 zhv#hZs6G$8D!9#uTn_Y~1>Gv>8w!NA7BwG~ZuWk(z?ng=6Pe{;ra?9DM*39i{^PTo zUQC|D-M|j5L%UXdH6?K0P2jHE6+->>)u~n5b!b=P@eWsrvFnOzbxk7t{Mu_H>bl8z zmzyTt6V=bJ&0g~S+Np5A8SYimJ^RV$*IohlFT;HT+#Bq0;O=XFer-M6v8MCdcc80l zP!D|zo?kl(^52F#_FG;XbrtF?@`gS@_m0M%2-+<7NxY+9?#Fnm;~f8Z59T}@kZ#PY z^M_JlRTzRB})KhyC^TAY2rJjbBm%n{39^x>QU%9HnBsq@NNFB*3Favb6L9K1GV z`1nPxxKfOQ^`HWAjks2PPJCWmFD8f^M6tLD_8)E$x54_uWHALcs7l3DSV%7uUl7y9 z9k2m$C+wqt5w^1K#`hlBwhxJ!_}(XGi3)sYi~I3?0N+aSAiiJ1_sgOR->=~N5WWxN zTaE7{_|Cz1uKArO=7~q~ea!qmE*^*VBz~X3_p9djYl7be_&#ZVzb^Q#F~4D9eQO23 z3(aqxu)g(z-v;?zB&_dZVSO86m4e?U`Td5lzTXtqw^`WVCBphH752A9*x!h-zfTGK z+bZmDo3Ov_V(7a}*x#pN!OZ?XBZj`q#nAUz;rxCJHt6l|p9<%91^xoT(D&QI`TdS? zexDP=zfm##yHX7Qt`ft)9b))5Cepv1BK_MX(!Z-k`nMbQKhnR?i;>?K#K`Z9V&u06 zc0@*gUlN(VFN;jy?~2S{-1o}(T_ZAo*NTgM*NKaLdtue>V&C=RV&4s7_!r{|N;fp@ zf2&*YfH;5YorN#m;s3{&disBhKA4vDkL^}}Z93=DIC^Qe%XKy2YQWWis{vO7t_EBU zxEgRZ;A+6tfU5yl1Fi;K4Y(R`HQ;K%)qtx3R|BpFTn)Gya5dm+z}0}O0apXA23!re z8gMn>YQWWis{vO7t_EBUxEgRZ;A+6tfU5yl1Fi;K4Y(R`HQ;K%)qtx3R|BpFTn)Gy za5dm+z}0}O0apXA23!re8gMn>YQWWis{vO7t_EBUxEgRZ;A+6tfU5yl1Fi;K4Y(R` zHQ;K%)qtx3R|BpFTn)Gya5dm+z}0}O0apXA23!re8gMn>YQWWis{vO7t_EBUxEgRZ z;A+6tfU5yl1Fi;K4Y(R`HQ;K%)qtx3R|BpFTn)Gya5dm+z}0}O0apXA23!re8gMn> zYQWWis{vO7t_EBUxEgRZ;A+6tfU5yl1Fi;K4Y(R`HQ;K%)qtx3R|BpFTn)Gya5dm+ zz}0}O0apXA23!re8gMn>YQWWis{vO7t_EBUxEgRZ;A+6tfU5yl1Fi=CZ)jkY*CWIz zuj#WVPY8cNi0-jM)L$zEu{z3neyp~6S;K=%+Z$RV_t&y@T9WpQgmEj%jijkQaavf!Q5r{oDoc*DY~ zshEA=qYpeeb9PN*eQQl?!&7D`d1gG4r?f6!sMNRCDRu3w%}RaC(uN5Nlj4-AeP*H3 z)?VA%Zl_WDrF+BD`eETMinPf{hKJGA7E$V2mM&^qtTeQ?wzMjXT5FdyDD6#4nwBnR zxV4LFo~Bw%-;4|3gH^K{*knn=q~1T{4jdAg~-p``{1T-emy z^sU#cuYU&%>8|vDJNjzXG+o45Asjy5?9t}&|o7$hP zi8Qo+t?5Z-L8kM@`bj7lWPox~FU)IgGcvlg-i$ttH<+iUCAEtiYMxqF+l-)Xt(oyD z4D9~dGv_@zXZGBhss|sMJ#!9%V{KrF8DuIRoIA@Q0fjy=Yt~&#NnLA8TU&ceOY`K1 z9#EQ_me#hmOfH>LI&Dhng1yj@JGuWhdtQx>+hi7Blu7O*INl};%W zQ|ellEJ3k|DN9@08>T$)(4&)42kO2lrp%o4l_|CD?X67F!@CWL^0u7v z--U>EkCY3-iQ!v4j1ZJ78WI~!U%8Z(Tt*mKzOZ=ar1RAUEg<*p?%8BwOshAjBCY zJ|FJXHS-a`k7eNuZ>z^6erzijJUcu*Ui9NjlkyDUGCNH7gUA4i06^ogt?mWl0J zWjXsqP8y#zVCdsRuEq^PGoKUF@GWUL2z&@*Oc63X2B{4JpM-*DfD%6jYJaG=hz&rA zUr58-)9`y~xIYd15U+y5jl-Ss{Rwa%@Fa<^2R;E@BJu6O{xL%Af$AuKKd}8_dY%B@ z`zJz_N&XVxGvkG52aoa{!1ZX10Z`&z&~`KkmIUz|!1jmX?MlP@((rG9m&1RxjPHXq z{-@@s!;6sWK+Yt}b-<-yers0><@Rl_E7r^Zkp+7VZ zhWC>+{(nuwzXjfgPODJHe=?2#ufU0$th&PRdHfL+s6 z-}JPIv^Fhm|E5^du%s^XELab=MdmiNS2QhtptfnL;OuHqQ*(38;)bO)n31((uGS_N z!j+uG4ed2;wNE$H*I*)8Q~Puz0|$)73@Njp`ldyTYT6qy$7{?WQMahJ2D8H&%uq9M zYa42wA+up|24>yT)|#a)O>GUr%Fx`F=Gs;{H+R9 z^1H05xxS{oWm#Qg%`**6iyPa8HIuEWYiVw2tyxlwsm5}LZ_`=2T2s%awiXC;_6r?T zceRV!KwCvErj<2|nw#pr+0a^pIpbjIEHjJ8E-Mo)X{on;H<+GfD%u*Bwjmh}%P}=x z*4iM<5`%g$8)_FUq)1a;P4luPn5flY2G}qalkNsP3(_;+4+aCMUDn>>Kn*o@n0rgX zx=9rltSkm)*PANj&W-Fk5_Gs=kVDoyUvhUS|3rZ&#c1ygRmtsv>h zfhmu+vn*1B0$c|5G(I!JuQjzdMI*I%F{)`=+SG1BS;i)2Gvh;zDZ}D)AnIR6Fz8w0 zNONubqLx+}D%v`dlUDvqG3OpC@>#6cXdn!eRkyaawf0#Pu_LH&SR~jzOntDeg=$BA z!wYFm`$Fgdtcp3aYGzhFP&50XnfF!A7Be5eZy3CP7@F-wB8Yyj2$QP4=)Xy;&<~Tc zU-#mfeIN05Or37S^KMY~e|v~A-AWL1+LdR?6+^ZNooP9!7t^m9qzEe{X$2|#YyxGt z=kWXdRp@WwhyLpEOn&v%porhkxfR?dkwUhS6mkhrhJTP0@@FtO6ybM{l#^ZjiZIXd zlVUv}Kw2O~0VyVV$3YqXaqzf=a6(c|(vy;2fS)4Ff2ywmMf~lOZj^Mdq?)9D3`CSG zk+e$Eh@`!e?veC_q!+MW!F&Y}7iqDi<&suO8kV$O(r!sNN!lmrK}nBGdK#4a`j`~@ z@?#EHgkK}(UM!zxQs^ThG3Ruj$IICT(4reqA3hHXTzH+8z6w&5(QeXW)E`pJV@{AN zCXy`(q8A1VAFCdDN6Bq_>!Is8x$n@BOg*#pY-?IlI}6QoG@ zL5a%|cF}F9zohuBAcg;Jq>~^A`g!20iNKRFXCj>AuSbRBPiqDM2dJ-Nw-Sc3tbgW z!~8|k0_ce0FNaQ8Z&yefl{6-4x1>Fi#wFbZ%5+p<4#@Z#L5s=}4l%-uN*a^2Thbm$ zIl4_Ekl=QTu%q!D%47#8m6qF^?GatGn-AIc3%*T&E(ug^*v+&(B0ZObq|$NFft~j)?0?5nn{&UWxaBn(dPmdPqomP|`z^UH~n+ z7yZaRptF!(Qp8bDT7mvm(kSU{v@=kSGuuHq&P3q1=<{e-r0_40X8O+srM~49VM@#G ziuoxmn^rn~`km9KmMcnWFzEb$`t&lml};^(BR=80=Vn*k@A0581+=^~Sn z1=ZtIBCf)q=Lz~!5i$8gpQzT6tQUNF)v5cjyb_*z>^w@a zgV?Zqlwb!=S^FeY60D(EPb4VQ4%$549Y|OL+!F!*v5GUF8Y*Ek zOasxB%P3TOk|+(WvN2t0rmVtA-`#O5T4rjbQCiNJHTwJB?E@Z<0Hvgv%*4|-v$y;0 ze*5jW-~N63zHiSiA5PijSR$(?LIEdkWXW$=Cpf}tBCa`^RV}HkG6@^TF2^7}W4w6r z!_%KEhZ2#h@IVtkeS;2n5e}F3s#s#LiW_@XQ);h@Cil9u4P(d|hwi26>31UV{OgAC zvEZ+Lz9KaKdV2bav&;VO{0q-U$*v0jaadl zFp+c1{?C-%Jx|$3p%YHkWVhI`DvOPhE6>G=pd5pFiQ+LvbqSlKS>(iR%NeeCzd5x*=_eftePrBr_u9KFZCyl=3 zmTSI8dh0yttgzS3@1@U|U-)jBhqlLC^E~Mu?fKG$cH2C8C9VBBX^HEkbzCQ{^Ezp% zdC~&$nhXo`q#JXjcS@g2(&v)NszG0^(HK{eyYkMsrW0VUizf1_lYUr_U!!?7zTv~? zz$^cE zAKfo&x~qu`#Di7gN6HTP=n2hcXhwa!OPwB&JZZZsW7kaQm5gO~{OfuNo&NyNW?!9N z_m!R0Wls_(d|t2o7RtX&d#?QaA@xVhKho|p4t}3-P=|j{<|V?iPS}J)I=(m?UwxXe zZ5rnxAI=LtoV&rfQR8g# z;rxjYXAL;_$=a>UrcX8o%xp#K{O9EH+Uqs)csOi(XK+$J9FePs)8xZh=EK?R!=Z1? z(D^NJXzQ}H$+v|+-M+3|bi3z>*RrTu8b|u!ztHj0AD$pAbR>R{4ohFk`|!W6!xH~E zVUOl^9WQh;goTcTcMz7gfc8vVWQmhGVMxabp77!E{S6(KGQOt6!qWg@uRL!p_s^3u z_eo#c>CIV$BgkY>!!oa$#$(l~`)c!K^z0WahRuG*+Es~Xc2(NayJ$P3v6X$0!CsYZ z|1D?kW?w?tLf2cbB`k69QXbZ{+su50F^24(R-gGl(?51`kbS!`t`7S65&jdzO?Yvo zaTSF}$r~}rpRlXx(u7*>&Vh^z%E@b7Nn1m|H;e}vzeZy_<3#wp2R=h-yWGb7x(42c znbW3k&sL^Co2x9QKQ3l(Ieq)f)#=Z^QeAAmTxFkFgVESyIMm#@@hAnElokhppoNc}|)^)fJxeJUQOo>9B} zv+3y{8<|wal<~3f%T?y#w}SY*HoY$VNq-4`oqnR_#cTCDZCXa(qdwuKhm`coC~b6B z^C$D@NL?FAT*22y!|8D~y=8Z0ae8-Uddq9o#p&0oGG3)juPnE{Dc|2mr0t}=y*|=Z z+NXYj^5gI{XtKV-$5=zinP_NmZtJwmzr2(FWQ<8F96vod*8#t_dij`_=&YWT#Dl85c`UES67d%sz$Qs7|scu+T;Z2Z-%k9YLxnqMVJc% zrG96;{Z{9H%UqV(Q)x85T>dMNgmtNxMA$ zz#-MbSZ#Ll6*IA`5_LvZ8{shW48v2CG0GU)Rf#1==_|V`!c!a^Zyd!EMR%M?IVNo; zW9D}mGtK6>y0SP>ZE?nVSCjal6DK|3{JA@}Tb#UF1pQ_subLwAeln`055|#ya~%Az z*C&OCadqD~?|HuXz~r|p$y1E!G_tivDh-yFtHoSfwaZU_7kL)GS&33ckas1+_)S-? z(eNW$uI%HC^sxpb?Sz`PXt}O}xAn(Z3(E`Q>z%?iJO`C+;MsJ+}4&D;$5uPR_uWS5t-vep2jM-kF@FV8QQMR+{awEPYuV1 z-p5=wr02RJ>X&s|WUl*HFJ5d-)cV38bA#I#K1W}mA0$GDR45U20=&1vM>$5FTS|E) zdyaqV?Jx6zzx@UFx4*!1wZGT)lJ0N+=&iHu|2w+rkf2WpZU=BD?HZ+TtW4$ASn4+Ci;VfF z?pW%i=o10fmhL$5&}<^l@!%n~){(u^m)O^g^A2f6dY~bDpj6z7$Q~#Sy@;80`V5JG zxf)B4E7=R}eEEO}$)OdW1xyf=0r7@S^ zgQN++E$K0rU*T2w6yCnGbg6UH%&Cd^t4>z>{V!BIO;A=OWT>!lPF<<*cO5q<=`?kaw<(HGyomI0Kmp zXsma3rYGoM>z#wQ-|ie(Mw>e$YJWi5dxZ8LQ9t~DC~xiGqr8X7BV%DDj`v{WD6ane z(a?QsuCvJ%*GcQTPMVyh&3E1zohL0CFCaVVTVrbFJUE@;1m?n7dPq&l`B$2~(5l*A z&PWQaQTCd9F9saKCHDErQPp7NE(Qa3wTb;(cVeP;7L?h~x&4re;R42&s}1z8XktI% z)zw9WV>-;|iAHyA=RHsMAz`D)evmm+^J{mbhh09+{K)pGiAy?JODoD z{f$BDEawn3v-`w-XM!>Ynlzv8cwk@L?t?|Htv=X)&Qim7-!;nKnWV%?9vN5uIB7%T z%Huv-?p#KElyT$7m3HvXa^lFezHc7YH0J7?lh;W*ex0-v*GW5howU+*(oS6`?eulh zj`-62ZNq({~ty-{}-htYEM}E617l= z#f!5E5}i!GMY`Wl1uu&Gh=!$q$dmNZ5?K0=JRipiz8~*|B9_e%P2)$S> z=>B?moj^jHvq$$?30^^m#S=V9zfb!@SDy3W_11#!ui%JFY2S_H=Po8*|06i^q;b?C zBVl<2kF(jC$HU{Cb*8S8_&9honSeb!@x8hV-qeQ;SNBxvECWR95yweec(NmC#BVc< zX-^oy9z98$@3~etzg`#LM-U?Kt$Xk1Nbp(3d{4-2@!1H`#h3nboC=G0MVI&%{Ifpz zW5AbyO`VQvff1t^4_*b_4(#Rc1Mc#{7I2Rbe*!q~ga1A7VITYk@F^esKY%X)d-NkB zSj1xD3BO_!VEW)Yfs?=ZHaW2fhUC@p}w7N~iSTvy$HjzXP1~ z!C~aO)(3wSc&87(4|v=M_W-;4e7bxK_>3?8Ah785wd(YL2kbr4KBYSN2f%_W(V`oF zfq?0Qr+_8ROP|qTPk3rI>$KLar-$;5nlGEHzKuq(XcYH+eWoB3cwHsny6BDl+vbYi zyzQ}iK}b}6&7>@e7u9X_tUWOb(K({A8*nWE>cl3T34zVq2R3iqzHWU_&#b2OqnpL@ zvz`?lTh9$j@tJy5H?AI0O5F75Y$FIvJEPBCvva6v(tEYpiYmX$Bl|$qr%_zqvcBIC zGXrX#=$1I zF2PkR_p02x69sh-n6(7CzRiZDiZKEfo^#|yyZt)0B6Hi9h)VqRtw;o8`;JHFH#2#k zh9q8H-KJ;UJzSITOg(C<_*&DxrpbSm+P&z~i=2A4ZGOCWo6);dTNU`b3EkE;U#8z1 zn|5re>D{l}xMSNk=3ds9AnpY2+^^wb4UcH}h=z}9__T)4X!xRrFKJlT87W`(;O+RW8WvrCfmdj_OT%dm_h@)f z!{Vf5{)m7g+Q-1x{#qt%lPYw(&(L_OSMk zX#c48C$)cE`zN%2Qv0&sko>2#e_H!zv_Ht6McOrwFMJH+3t#KTw8jfqYNyE(= zZpZ)7N0FQOt>{kc_#}H8p|?W&UD{u%{ce1z=Nf#eXGX(f%OLQGh6@@#qT!<&KBeK) z8Wvjzp?5*UV)Gzy6kq6dutyU6x=!)oD~T`ZEASKnQ-1h6golY51Uq#U?`N9oO&)4WHHUn;I6I2%$Hn;mi1<6MjW}^o~EdtaF*^ zd)`Z@xMSI;6E*br)+t`OfPRD8S%>Sj@&3BdIJZpB5m%Qx?=0MO?ndjTcp~?K&O5D} zM9=q4U)q~>X~rG1`HUsjO{Onj%$F7;E%47~X`b}aJPA#7ac9bla=s(HNW7HaqH$X^ z9MkEscrD%Z(K5ja`)Eo2Q=}WFT|K$fa_OGZbk6(oohL3@m#^eYFOi<~r3d&vif&%$ z+%hX7Wpv&qJg=&T(0?<~tuvQdd?(LVJ8!d;q`Ti!9%doM=gHGS%~yDioJvZWGBEY)#`rD!X3LvmHx30>>j_xre( z4Q05pGv=Y+3=j46yP&@k`YGslYx*L$R*~ECtIKK9ZQDe-9CS zKM9Vw`hHa3&(8YV|13P9V=+^g*3Sg0ay}VK6yD}sop1H4`Ceqa)x`G{IisWd^Y z$w;GHo_dON{HIh5y8zMC2pX%{M)<>qNlp5%Cf{6{;Dd=P-6&R z=!Nl-Rb!VYE6%~K&o+>je_P}dN#x(|Oul$gzFP(iyX=Jx@cdyfj~Ca5fPMF~tj3I) z(_OJgH8+V(Y3+8KrPQZ}=ib4?d$TG!%KiGdG3%*Jc75f7Ic4w zyriS2>iU8&PZtwTZ!PHl3XZrg?Yoiu{1JHmM{wj>gQE@^7vM+m-p_e#1-w2l6TU}J ze6}|;PdmcOP=K6Uirl0gi1eEC*a;9e_+;qO19jf#+Vj<`bA_a4zDMp(@joG>w$bq7 z<~o1%D0=5vTm#~sZFw-?&5ceSC+B%=jf`#|ENv*l_3$?n9>IwW1b+~J!Uq=!AN9e9 z2%p4x`TvaYIh@o)^8XP3JdSOq3;!+tyEqSjAr+8&Nj&@y6K=wJ=?TK(JbvycoWz-$ zUN7M^j%~F||6dXwzGb1-Pvbm#-zR(yC;d$L{Sn~=9mGoy%U&4Qs?+7J zk{(}rC*c7f{1D;158g&t&P+XePZB!e@Nxa(;T=2a6J!oR@p`nIfbbyBD^JeSEu2UH zzY#9@;3>kk4-SxV(g!aAE&&fxmXvP-FULur6ZlTT-Xmq)UkA?|By3-|VVhhsv89*0 zue?)-?Q(s@z&5Tn@I`IsoNk+YVBm}F+tKTT=D2fVmgLNZ53^A&{#B_?Wor&Ib;E9_1D_VcpN@_P+JoGWAvN+qRYC zsr3(U^bvC}*Vr_Be#9B0Tvsut%rhqD|R+Al^`mG<>x^4TqW%DK6 z;Y)CfakmTZ#Uop|P-9kZwF@S=Z^2(DH-{(WIWj%0@6_;)eSGw0a@C1)Hh#nQtsLX| zibsP7}`H0q-Uw>`RS^{^k(U~6ilhiq`ZqBQ#wPEvme>Zg#w@`YooLyek z@;*-Z0MC6IU*EF+QBDK5aSNU=t#%sD8S?CPe*RRhqY$xehSRHSCl^)tQtCUQd&h{} zkl`=O<+fHy3gjfe{$RJ(xjYOG=5>?FN#50&{YU1yPinEsU(l(XDO@Rd^M*AjjTEs$tjDn&qFgmnN`m7IduZsPV`njwXw0vIGxCQJtIwCU5lSoGQiPuaH$2_Q9K-RTrPlse+YNmxgj`Jd;&Z zJ96q^I;-C8MGrHTRhJ*gDLa`}SMJHF!=UbP}Df>;z zK1bQ-Dchm!3zU7TP*kVwqB>(0)ul=F)!^Y`oOsGIA4kWNvRXIg)EUZZdoZWYQdaxD zIrS!GB`E70Wpz;2dCKS{?}-9--urXvq>cUa?^7QOJL}y!p}7)vufqNIrVNSt5UD!)MX>9 zx)ngn zTY|$As^`K4I<2G1#C{`^u**H*uS|`qf$)S%cTcEH(}ap;M%CI==x=7Q<4^8a?bfJD z;5u*(7B(8-$1>Q~r1z`1O?VPK2fL8MUd|Wxs+N-2h#2oAsdp=~P8ApvlZ*-YT8kW7 zGK`H9;}bm7*{d2dy-usWS9MWtD|DJ2#+8lT3FR-cH#>_;eU1g(LVT+YJ@6J~zUs7- zchDA{=Py@{%)`gJ$=d>6Eq_rha=z*`fxn#i1h|cMuhU7o#H}IDa>j^z#986y8C5Cb zMQ>a3<)PaTP6zp#NMB1h?xt;a`Xmf)r%Q8_lOa8=iCjX2AJ+br5K^MuoBNuHYR zkVSd|x`EOr$HMn`Gr<>I8N>eSu}1q_j^QwmK~L63xTPLv1b;2Kk<=5;0P%r% zzawp2hzqS+{+9S&WukA5O^w4B5N8GH;|A?v%<|C%eh0MrNHYqXokASFZA03)#%CvK zfn<-r@d z@bOTUa*lcRm9`c6bdaar#T|C#v>Z5E8gW)g9CTv93k!Q_rx7Qb8gd3DKD`NgwKkP8 zV}X+=zK{OyweO08^uHX&2Rk z$tRt0XiEQVCr`BWRfqO*`cguxHWtpTqo1w2$9eq+AH%J5x=1rKj2rSM$Sd`0OEES| zqe|ML!5(r7X_=3uej|>^zY`p>e>BpYj*VE9OTA5SJee&@jX3?_gp)(im-t%U7Z#p$ zqSh0R;19oYNG&RS(}`HaPKVT;y0ycH*iYICE@4}hByTG;WSj@AJry&Rt26^g?Y>Ggyfr+Ay$Wd!z)dEy zc`D~5Q_^R4S0brR&|(}uLmae&yGER~CbnYf-A+R(=fu*`CceSMZb@h*a!x~Lw|F*E2h|OemSY+(xcDY~htQ#~ z$CEx}&>o^U9Zvii`qIy-m@}#bHy)R^tkIP+XK5dB^O(k;)M#VlHy7LIkl@gn!d zJXrn#=e*4+=3eSzW@__ti21^#9%kk~Y#`_#Ru|!#d?OkAMr3qTOR0F%Ve-nlo}7fI zNxr9Gk8nf6E<4yMn#j7f#2NzKfSIc_WHwZysSTADlX@&;eIZ|P7xH~_~ zpOw*Ec<#LG%1CT(PcqLkuTyr|I9Y20;Ck9kq>Egojip_rZB6ine$yQI&0ag0)QNWZ zPsmdCsy%7;i?oAjN&EvKV+QPK&ub37xw%zsmMrn%)Xvut^fOb2y zWUfd;%V5tCPO!IPFClx|c!vGSBzs3~gJuW;`}CD@U7f``Z7ZZ^lTQ65ua=BRS8{xF2ToCPhP!yfx9kF=&Ut~<46gU^bzih&Hg8N{e#h!<_HJ_p#hiJ1M zv|lf6rD&H|^J)cox}K+9u(@Br_nK5kUd1*XQW4(Sp2Uv&fknG3cYS!b+h3x5b9xXw zL-(mf_x^}{cWiFmuf#4+?2JO5O)q^g5#FuB;GTSpHGuC<9X$tJ{Fc@O*W#z`az}WN zih@6)@jJ(B_~u;r1->PL9|M1_#$SH8hTl3DzKyLJ_;K*tHGVQ*!*81l-?Ga|@SDKD zlBw~(B77ji5Nm9o1Am3^USK>kA4D0;k%axsf|UJ?*j9(q_A`9@`aRy(zZ*0jD9au% zNI1?Mz|egmNFKf|J{K|V=Rzs_InyxyFcxR-<*t|zc$E1NB z-j{E2tY7wbL*U8%G7=AN8N9Nrml8*NzC!xzLX-HHz!7?7X_v0B+-0z_1b@|)t@Ken zw@^lzI+XuH+uVr#imZiauuELo%03%=ysp-^G#2hKZeQ{E+JTXpZ}ixFf*arJ}ePE{(Lwl>9FXgWKJ7mB-v=)?p?^=xLY(9m zJo(P`5e?Hn-AC?V^=L?h7ry5EAb6I?gby!4Sm=u{&lT``YeDx{(!_m6`)(vZ>ucv( z9_Zo-@C6*aWxNEzDF>zYqt@(itJq90p)w8_Xyweea(9WmiDzkT1!## zU4`RH<2-}?BEG=)O zlty8COApGd8hIoCMk3|3Ab1mB^tf8_MeplP;#%meSG1oXEbtobchg`3i$0+EV#^@D zqx}qZ4${yA+TW@DLG6b{9}xTw?e}PZT>GcA|E~7WAv2-p;I~l534|-~N$r=!r*YkT zrPmMit=loMxu2UX-|Nix&N~v^WGT;k>zj4JFV9tHzL(i^23aSa@yWZqxS8tbQp zK9;8SKiO}~`9+&Mh)rWO$i-Hbf2=r>EcItb_G*h_e=KO~qzc z)>rd@kI(&@&)u3&_Fv`);d51uPu>f|3ESmU?y>Ri5D3s_(q6$N@`bjvSvZ6JueD$6 zKgqo&tEq?cfm^9V1NWpvGxjqL8T&Z{+f6y2xQX@s;nx;a!`yEZu9YM0Sl#s6z16Vw zyq4+rR0A@L#>HlT*x{}(XJW}|=jC7GedWgWPGHwACx%`Auz9x=MRy6^zlz8-n2>t2 zzg#x{w#bn?aF&EK?2WO_7yDw5H*AF8S)4E`$sqSZ37%oST+<=5t5X5qixTMZp+gm6 z4-}(a18MFWqs|M~?{Weq>TG?FHsRgqu@UFs^4pv}CFG&=gxP=nuj%R6<*rXO5s<~k zAZZb~Pc&lE2i$!{K}`i}x_hES6<|ylTBg#LB3Bs)Zof`A-*xZ&Nen$7lKmayf;t9d zY`|NiD@&8M)-s&vc*!~SInhnCDt9g0=!9;}IlJO393#295{~~H1#h>|H{81qwJsj@ zmnFrniVUKL=+R|_-kk!=n00we6Azz3%e`-m@ijYULm3&<<0@R(r=DK0z&!_X&yI{W zZ+t{(yEf9be(}q|Hy96qeZaKK|K(@XKNdW99AT^O z^%b!rcV$4`4Us_-8BES00}B~Y|8Qo!P6l6jL)y$p46BXQy@9$foU~uM!LVQY6~=`Z*Dp0n_D-qQ7)ZxA7U+&1Ff69FXcHqBa-_MyVeR-I9R&4KO4&LXJ)3}xs z_l&r5;yu~C$(>K!IauVZ=iuYCt&BHWC!(fZK1Cn!>MMPLdkxv4-4a^H*|#b3VogG}q67L<+9Pgqjt{LEdE_n#gZm^5)XC4 zZ@R?nF$EnwgL!Y>_onmgx4%ZZ_ju)c@Lc}2??ImQYS`E6M@Ft9GuL~PzuY+3BDRs> ztbQAND8mLGz?b);kK&8IoTs1mtH1?dc|Vc#`|ytghaoI*H?Y`Lg`pvE5AaC_cuJ?s ze@3C=r|7O~p;UAJ}if%5yEi}-1_z+*-t;83*Gx5dVOZ*G)D*pckkbM0Z delta 68092 zcmeFa4}4t3b?85L_pY>(7yH_lu`mK(*#ZQJu<{=e#K0OvaEOzv|A0;6g!LbSX$=T) z64H>|l_goiNX}Z4y$;Ce8pw-Fc&Yp+m{60f|1@!on?m9BIextM?q1)>IJ9wEx1kA* z-uK+SYa3o)l9%Ss`+a_07|)&mGiS~@bLPyM(a@t8o%+GKnMqb-Q`0pwny!kQCjaw0 z`(M+X8NcSLCOIZ2>Ac<{CCGx_;>BB-*p4OqJHalKEhw#0p|agXZRhbTfc`n{$&IF&-wq)`TwO5 zaNknl-=VX9mzDn-bwmHZ!_ocfx~<$4WB-;%R_ zTNV9=^;o~Pk^E*Iuzq`>{Ea$b{g&qOH)@==e@pZK#df8i?bargF3xWH70&uq8Gf_$ z$VyxNTF&})Gyab9S-(~6xh`FD6S8&li_uam9)jcaduxe@FA5Ffk@0H2*vDqyxt3J2z-j?Kp_b=-^HTmMv z6qE0z%kEiq&+5Etl`#k<1i>N6X! zz9u_#e)**fzoq0Cnc;i&>Ks+6qKPZsRB=1MB$V-9yFz!DnX}#AT-q_icAf*6d~a@z zGllPrrksW2`n+F^jQr@2X4!6aJmH2_GOzb-|NHS)H2u=?u(I>wpZw?*Z-#PqzUGw= z7gWN|Ye_pFZn5*_N}ZUK+u~Iarz(4nk0QR3_-L-j`w6v1DU(QT@nUAXQy%Yd_L+8m zf85UN%FdUiyPamz4yNsV#2{>UI+FL0P5I0k%lTf0$kZyQD%In~QY#z-zjCOJ@D}go zAv&RMcmHl=G;l6 zH-qXaoct1lyyc2FR~WW?xHaR2{>QzHw1u9UA1=JIHRDCz>M0EDFLQ5GU4^b$E1kCK zE1eD3PIbmzcT?e<_)UeFT96ML_V$=zZ&mR&M^p1$&9Has##7#CH9!9^BO{YOv!t`2 za<&_B7;yrK#celi_Bb(ZP2ZOeUt&EYFq@=bRqpDEjzU;vhjpWvOPTnL90>>L+K*<&wJYSPvBbrvFNJ3sPg${kGyl@9xGAyP9e)7~c)KH7f?aI;40XvZo^Xdcdy5xsAM~QD2fe=A zTAki!JDl^s-cv|#UFZD8Wf6Dlxpw}M%MxzP?(wRO9`F1MdkSh?t8>u;J6~<~SY8d0 z%C_AqV~f|2?D6c|qpp@rxCY;s+^)F;n&y1%;~#ZR!u8}$jMLpQM#7EqtqkQx%`Nx| zw{qTw;gGs5f4@?XSH-t@)x`HjB2JX=ugr&aUDV-xg+?VVM%p9saZH_YTYjlObqifV z$nn?ref{_(Yq?U_$}B~hK^@#=b|$IJCQqq5+z*h=xFqC;)E&~+Iw2NaZSgvP0i5H- zZ^$_xi+A~`BykaDRpL|-S3~<_RL))9D1Aug!$Wp!h`O4Fws@md(#oqLyH**SnPMs& z>he^)$FFRZRH7HDvd0X$QPt&1M-+p6;H=I_{^imkv)G}Kbja*1c8EBsSK?GDj`GqW z2nrOn)U{1SNYCg!9my6u67M|S5ou65BBK%v(+Njar#EYBo2S|93TYTrDE2YejIZ@f zMqLM5nUt?fcNOX&#K(Z>y?it+$9+7N70*&Ft{;q?ak{feAcx-sJ|GiJLg+xT6RaB2d&!&v+^gryOD^Nf^rVj2BIS>hOl>(;GZxX1q<|GAAb3sy+s< z=vULjSUo=S?s3BL z-r*#5Rx!6_&Y1h0(av%wmRsiht@HEYC4Ec(>3k~|>R`!X23Y$HC`E^2&S9NSF~Dg22@vw};b^>12G#fDQ|B(GlZTl4SbU== zos!9m)pmH=tmTE+lnyTz@9?Cf3&7_0lnV7hpZ&6pg`NFbZCT5=d+_+wE z&ir1lx$hJIeEx-p_w~Yj?EJwgy=YWJk&e<#P=HCkR;@d2_zsqmmP9 zXrn)xfp1A;ObL*Y&Pu0Z=`QDJc1wkJrKKxo2~+o-nvJr!rbppoO2xt%&)<|JX(Q3=XyRzJv z>{e6{goTii+3b~r5@mEsWXLd$j#7*Amu_Sq^uanuB>;SU^RY0E{gaRHA9F`;SXT%$ zuFAN*^`;531{aq}WfmEc0yZP@b+iEtYm@r{I_g8Hk;) zAImqppDLEo@4q9EW*~I5-WuEQ9r7bOy&=9wZWzP5IWLdo8a>IRM?R^H&1PIrcS4W za1N`UN}iQMX8*9r`ZCIJka_deE~mat=B(5E?=)fu`F=qsM{fA2yD&ZI{p`=!9>teA zk0aRn4UOGAEX&;K5mJAzl!N-EoHAvQA9W>vIKK2^$8Yd-p-%558fubtieHQDkpbnB z?5kDUcx_?UtI{r+mN44ACe`kRrr7xzsdle#+5+~DbnE0~Z4F593<+sL=g9E3vb{GO{rUc5Hr&1&>_8%SvC zkj74j3E!&4?VWA4ZBD!~?S*QY*f>a&7#NNjeQyrzOM6r3PgAZHKGf>XNVIzPl(aX? zZ1r^9Gt<&#ULxM=MYGyOt)`A9&9jH%qqT zkeN)ze`gY^4FnVx^M=}fZvzx0s5N51Y~d4vJ~z#fT}qFKX>%oV9_uNS2s%CY(4aRW zdE@recb{A4zFna)x$|8X@137I_X7w&^W72Cep==Ft>I8@C#2cw9Mk%}^mTn+`ifpJ zWG;6$6pHwN)3jyI{wt^AZggU7rC?w?MFo(Qj?>7gOEvj^F$AgapS(Z6@5+7o8))DL z8dx*c&RZpqBv}upE?ABh))$*njl&-B*>l zpStP;ZmxWsr;Y7&(id#-Ce|!1TyC@$`u6U3_D;6*H%(jWD5K2@!!>2P`e@A89Rq_YGHa~Tl>(8ok^cQ>kp7x$M@Ibg5@Gx@h{ex>*q>&vyFiF!kC%?BR7unZh#7iX-ib~meqYbSCl8Kgp zwFAB?q!-!w#HMfZ%1xF{6$P|?V7QH3fSS)3@-~DtN3<6vjkUIPI-=%#1iIJNb}tiB zep;HebdVM`L>+7A-`P-9=<1MFUfE~~XrPP)ArpHCWRjx6tw{N!J}#q}YBzRV^iicQ zE6t@KBH>97H?q%WZYBI7!cpTM=h41v?nezmEK<5@<=;QKX9! zDx>ur{{->n@uCbUX*y{VzleCjV4Qf$5`8|;%N92b$O>#Pi-^~}brwd&9d-_71y zt$o0H;p!?cLN4KB!YW?4TKBi|W9hC48;@L~xp4%Bkje~)wS*%}X%{QR$=O%D8BS$} zMG8FiAWT#wz`M)6Mp#(c`)xN`EvraoSg+UM1{t^k-w?Cxlw?A8U0v=CT~dCT_gs0o zw{2p%2in3UlOnZLmc75d@XVA!Hn51Fzz;@uVs-XaQ(JD$2o+VUh*<8))|ZaA)4%Fz zaG{jcd%L^pQ{^6e+@t*yHJ9x+ifTAf4#beQRp9%5nD53e3477+hCRJJ?5T-iZy3^) zE_nE#yso`)7_McW-G%x6*`2l8T~;>$SlEhG6)z5E+w?B)dKztMV$f7Bdy%j-CO#eT zeLpWM*zsN7zB{|d#ll^l-eQk6rlOZi+2gCILqzC$#u_s>LW=YAz+~OFshhoJ*LC`v z_%hm>MyX8lY3R#YlB`gLk&(-~R1vbJ_$YOV?6&$n@v*qo;r)PwRFF`bili_^MlB#@YN915l)}p| z0P9gHn@mOh>9V#zjUsSW9Z{+s?z0D9e&U%(D?|9Q^^#4s$iA`c(y0iK*Mry1R1-}U zw+S)Cq`6W)lejC1t2rx9ntYC?R^p@^Y5Ztdsm=IuDkE6Fa9qZd z11+KW#pC)dPjUPpfiZDaNX!@J2Rm8Q?-|!3=p;M#m9PW#ROQ2G2~~tA31LcEO|`f) z3Deezhe72~ynXl`fn&0L_!T<3&EzovQMwPA4>_)7Z5r=H(WJ zBNY#>b#hmSCPcvsE&aj5(4x^^blF-bY@!{xdbIb}{7!Edan7Pj@3|FM$GmO0=mIwT zxT@(z9iW_jNKdyJ3IEVQMtY2ml8ivMoO13l#Bc@Vi;=7Z+$C}QFyPkI$cQ+Sl%CyC z9U7lCDjR}v`fmM301DLt)C4q%9@vIQ?>BFACEwz6jVx+yZ1F|Yer>T>ZzmaJE7)mrYdY? zPxfg>Hhny#?;biBdgamcK5?zN;I7r?vIpg)_P)CwddR%ayl6#jrOHMYgeRY~df6&D z)b%4Pvmag%p18YdL3mpzX^fQe-P%i8di^6HDh z*&nFvw_ga?mPsJJG5fx7#gwwme~u)eWuLu0JSCiYNoD`)_V7iKe}0KxXKNRQ$7f@U z!bX^IcJd+;F8dby(d+|1jZBR^lT#|5ePB^|YT4`iQTT+i-=A5L%wE5~yliY~nrL6a zS=8#RwmAHGOJGs@8GL}xr+*Tjh06gn^z3RJQ2XHNRK>{)+yVCnL=j~UC4D*JV-<7* zU&5>Kt6*Di2kD<997DL1xh36FYx!s)qNy06kh9e`!cw_Z@HGAlgp)843GW~rWx7uV z>HF~CAv`B&;B~^yu*#J|`rqR}N4Qk~zY#u0xLCiXsnHZXMZ_yXfy)RV7^l=TLHK6E zE61M+FCiR**&C5!hwdd@!>+*yI{10Q4d*kPLHSO?&k?4GKY$*>Il^(EI*u!?$|m9@ zc-gP)Kzd8!DJPH>zfOGc zWNr{%5%{y1jLXT}jNgEN62Ar%)XSut1=08)06g&1;*+622pX(a0O(GeRc_cSDiV;M;+}YE&^i z5cmfJe-(Ky0QcL0mO!#U@Sh3%ckrcNMW>`49p93VG#^r6kN8xw3NT(k=6CQV9Eae< zpM@_|kPx48tAqGg#HYL?@eD{P_Hw{~9KQj77X&KtF9iOcz|W0i<0J`->9zPv0zVb_ zD+2$Wz!$QVe0tzV1AjGs4Qi~6_|>d^;zQ*LR9!U?=VsyrhYpC(Kw_lH0F3jPfBC4A z2r8}?pAq)s%ZRp#Z<3DcLkd0;_;FZ*jBp0NjBufZL9E3R#_z(H25s@_zyL-OJ`%$@ z#9tNo?N;!S6CZFN#+Qz~68Nu+Plt{K;Wxw=+z8^21^)5Ce=A6@rcs%~hQLn*{=&dt zj4$n2OXPzFQh~oBNLU$!SBX!9EkU>)Um%eQ{KMkc6*t2&fGE%se?WXX@LUjnLHvuD z0(`0Op!gv*RUHl@UMWVX*8~4Z5dVgm{p4NY>USGOMXs6Nc$Jy0JrcRZk{kIzFJ%I;f3s?^OMudZdIS1!6G)IRK>x63zMysauYD*QMag%{Fn3F4cEmCb3D zTAbGg?AM^sqfxa`js>ZtJT6fESI9AbhI|=&r!>U(YhuVCIwZdi!ldo5NRM}PD5$bt z4)v&@x~0S4k655R_&uhm_Y^m&hBXxG4 zw+m=(F4vsdoVZjnWf2A=5IZ^MrQ??Dlc7Mdym=9$suM3{{1Wo{hSewDV4a z%>-O0R3__lgZJa$(O$MZr;OT(lEDzDQgeWJWV1 zVOB1uk*y|VyRIB_jQ_^zqI9$@wcI&o(eUexQX)zf`3b~-KN$TF_;s@n(9L&Q z*eV6F;)FS}92Pw@aYxsfYn-M;pEtjDH^-UtAvbk&hU#ON!-iXNo(x3EcVZTK29k2l zx+HJGT3=j^wSv7*bSF#lN6fy++h*Sc$s975Iu`m1NKHs@`x{i2rUPlnFp|UKg|pJ; zoFF7Tf$#yok5P_>4~cs4i1LrSeSX1|Za=Qt7)bG$qdnK|B+QK$cuV%~9+rl&K|A^! zDuC()WQckIgT)is*gfIJmM8}sU_%C~DkFiGXZ#k0H+4GN8J5j4%(_C z@wJwxp(l!^uqnWN#7J-P64N&Oh5w0(sLpNia*YFwd4c<5!eVRHHG8wyZ1$q!O2AV1Wu&9EVQ|?#pgp()EBgOunnAFQOK^ ze*?72;&Tehe5epMpK?OPh2q#D#Mdw*3tW0VsVawgQrMge7#M+?KOS6M7o&n25{|TN z_TETr#$cn14&Lpo!0%8Uj-I+36PPaFJmf8W73e?W5Me59?`Oq0B)Xn>I=wHRwqJ`; z*DKeduP_I^Q|WH-X}&v##xz1I8>PyO;`osLoWDQ|Wy%dIQN(I&e&@Z=IPi2K)lm#B+u?^PI8Dt)oFvhtJj*>VOvms z$h5bLnn*?gq3qlpQqM|f2IdZWbK;x4*BPapmwc0gkei#J!Xr7zjXZC_+QiEEI!zs| zNed(v=dab&vmx?58+h*N55!;<+pML?O$LdVRto>USw z);KgMJnlt-&XM>470a=gbQJ621m?@he(xQl-#Z>}_o~49*_t}>)`w8RVgoE>e1v!* z?Kkj+q+=kj@PttyuaK?KKe%RjIz8KU{vdR{3A#r82~vew6AkO3vr0@lb`^>;WTLk@<|XaK%Et!1w9i~HXQVT+wD6WL?@dl<=Du8FJl%etSk98f zZVx5Z2^s0zVCftFXy@mb!aM{-Z^M`*O;5w^s2C-`r#E(ctVe#Cn#30G)U|`~RT!1A z%n=(TWh~uMhW}OSunflynJa+k{JbWNo;A6|=tGujcZ9188-*|r9U)P^Rq8+>+&K2j}S)p zzzw#$v!yHl0`Zm}9~c(oV&CJBRydlNl+LJRM40r5>5R%1EkZ~ zd+mFCsxuY+qsfVK9qwg7-G2>hUR+M6=8JWTkBC{8G1K1S!ASfCTX;!Trq5e>-XH?o zSv?RV(VJ%PsgDPiwk0-kQ0m?~_RR#9n3mAo&2$Nv-a;redW~0q} zI|WPT`v4AuJx`Y7g|$9sbX!m%OZPhlI`XubM=W+X2{bIgA*@j7 zI>zCh4F?nC@Cy|*4P2eDF(b|rtuO)Fn`4}*)f{-epTD% zJtA8av5YhnjKb(C2;-?^b^9FlRB%C8Rz4=J@(A9ffG9^DMogI!WWPbs<3DzqUCMMGWl|{@h=U9@_LtSE?{-V!NAd@g;B83If zs%TKytRUI(#9D7gKp|3@a5Uk3Wo*tKNp*X1D5wdSz_sJLas9X#a5-EZt^s!tH^b~k z_~`b!a2ecYi+|F%fmAp2+zmZ&F3IFzskx7Dl3o-H)1oW>w z)V6x55^qVid1dBGN2OPS2MhDZ(rkfH^1O>n3FaS9ba}5*NSPaa2}d&@M2h9Cow-+# z-Sx81C7(#j@0Uf3Zz0thbF(MQ>@gD#C3Zk({@%4KSe$w8aB*83I^6mkqmE|4(?d>Ip= z#FsCH?^v(L85NZYHs4D^8FTZ!0IY%+4IHZ%NoccoiZx)4(Is=vDz-dyEDiz!>WJ9} zn-vulkfE+4kf-dCW%1F4s?x&H#ENP8j(3=*=GldbQv99H+}}cAAd9cK&k^~)d92W@D3990`4&1dvGWUVkoS)Nf#eEhCRWc4D#oZLHXeykcQ~4-1q)Q>LOOj*bD6Jr=jRB-3e{yr0ep zxJqk)2plpUB@XxvI`v+1{GY)zDJne!`YvB}xedg8gMmpW4$x`%j4SviD`MDK>C{*( zzsC$oK=vo2B!&ZNMdtIk+3gWVBy15dhx-H-Q3zlD1WGvUq zASm0+hNKF7IG(_#{ITQ!c=blUT?U~*N^_HE$xJ( zuN^$;GT@N-8T@|y&G-XpxFzlx+(F{l`Fe->-h->b`2(YkckzRua|oiA-$Uu0^z4)L zOhzF*`}@qf;Dpe2>Yd`qg@&VCgAtXMPey=Hn9m6XqL>kKNy@bSEkM{!_C^bBER>MCfqabl8+xnI^K3nw+hx)4*hKx)7 zND@$fDo$?vqrxV9aq%Ed(v0jqaqavFrw+mArT%A-Lvp^il%)H$X7`TO$7d69O|OtJ z%oS6J2Nq%qQTLrt!|tKagx}D7tAp9n8NV_7QuU=GrH)D`&A`dGIKN7KBm3dFHnBpA zN|cek_m>7G^EHzBSJhoge^=kKOFxV0fdKKGQu~r#eP*~9mGVm;{M2WB>y-v`>8e!(vZ(`+*F$%$%C3K`{EMO2 zCl<|EW=y4f8poVPGnS}yugo`Ni9|UcG_tKXmQD3PW7!SgET4D{>f+PCxpl>{amJ_U zq2E)PFtIJ6PQ~)?|Ej2IPWIJ*iA;?w;q$I+>&*~v?57bUwD-d7g+Gm49Nv3j(ds4i zFBfL-BjTKaT3|*c9KWcF?AD(~&X4SwqSU8-OPNjU%P-76xxU=U{$gguxa{JaDlW`^ zeSP^ftUk{CWSTiuJpGffta$B!y&hjoFdFcmBP_mzrRPTozk~Wk!nY7E{iOUyaAFZd z7Az{*?%>DHgc}qBhyT-wlnm-l-kIPThdb|CanEN?2R<#KzS;|Gt+O7NXnF9S`&R$) zFMVSocyeO->W8I~88}hlw*-DV@TG$ipTG}+L0#aR_%m=dU`w<3q_>B`bxBCmPw{j3 zlAtr0;)^{*h)NQH-yHaJ0{hx&nkN_?iKY82{D z`A}exRJ4TImWm7vnWRHi;?w(T@uhP?*c6|}>jJ-CeDXI0J~jH~DB}A*tD&BI9%{LB z`qDd>e(It3-G8NNnvE4R-t~Y+WcpRp;=x(5*j(^CeO4S(75)v_D2Fo#Gnj*OP<1dR zc7FFba+ORsS*(Y+n?LmEu~9aX+?O6LRG4cV#ab%2rbW76*TOlmiDMrePH=(fuQ-}8 zHV=my))b!mOTH`FNvJlbJlgwT{v@4X1MhUS@WkGcfNW=Onv)J$|0Y zVWq1QD|U!po6YnNxq}u-v^xfuKC$$4MkUq^hxR;H(Bl;zXHJu9=rkMk{A+wiJ2^rG#1BCuLjM&bAJE<&1cRZM(JiH8UuOGWa=BzDa%Ckt*k-Z?*TzmNt~L z_Zk+0GLI;50mfmU!q(A{BX(aYTN$qPFEZrAWDFU_LI(Lc#zptB#0{GX0eA6+23rlj z+eGjN9V*WuodF&~7?F{{jQo$ zXOM@hr?knFBPXPTvQ3o^mSI->=$Q2dEp6x5e0@FhT~u2G2VQt!?p4B#rq?kTv_klG zUF*I5|FFKGJL?N&9K__?MyCsM!&-XDqU)j?K@m@(7CZm+=+=T%B573_NYA8UGvONC zywoALc=sBwb4*7eN|~}Hw-)p?>d7Hq53wP$wCzSAS;4Eb5g8qce-(XT*&qioByKK% zxjBvqYt|Ra&Gp0OX6vvN(8euu!bbOL3XoeEVih4HUrgb&d6V44as^LdBPUdj(*dSX z8(N3mdpD5i@UTIu^s&9BwIK8_O8@foqvh1a-Q8ZxQ-xknOLZ5t+}uJL`V9~aBZW`q z_1wm9Xb$!sxs6}ZoOQcL=emcq^t!K7@l$%P;~UXj$5*5=5O0!>;I4D8H56Oq3RF1S z^hp$LVL=D^ctB$U8pH`eW5S=4U!|0PjIUBwg3Aj$2~y2X-TF;lLv)i@_DCCG-NbI7 zkNYbeq(ZBhSLY*uEyg|8G8C$UJfX+BK(tn8|D9Y7yYptKWU)Ir*Hz%zpRI>Ox8OJrlOX1Ka8P~U3>Lj5KXc1N&;q?H|8~L zZ1k=8L)@Cu#G6r1P%$QEtLB#YQVpn zBFfuynHD(@vyzg)IhM=|LJKE%3tUXRSe^XCnMtyz*(FEQgqiE`uEy>N>tChhhn^#7 zbHn7BK-&0SjcX&MPf+YGRgTd!0F_H{N21%i0;&=E*PtTG@rCfkkt4*bY~#N~*!F}g zqMN=Mjz+|UF%aO)Z-x!+y6o5+D<)>=@EyL6_X&K{vbdeW^1%H8O)H z4;C$*otYIg&hZC83nEU9%3kwg_`2*zu0os}La?(~$^GAP{uN2=f*>rONMe`aByBOn zm2^~(r+!cSe(AC!^%rq!~Ch0HmDN_Qr`{4r;Mpld$8&KJSKMx!+F@Mi`7Blu#n+Kw+KtB3K$8nK3Nu{x~77pucr_+nw22;%1y z<1N(^B&-e+9w{cM?jXKDh~FHsDgYq~Zydr#44T>-8kPZfGOt1Rr-NWH-DV zo>*m2w31rCeEELoXY?)YOTn|nFjw6p<1Np!p0VWcH9#3ujRJbWz)SLdS5q?&X= z0fUGsLR)4y&T=DTsweI9TsV>oNmsuQ#vH`A5;vc41L@K1(!=5LmQ*9R@#VT2paewz zb6`hb!5Xe1X}cS5y2zoL<0=4G6fw$FfYCtp9K_WTmhMK-@`^wz&HLt>L0w({=en$4 zS()^;R2g^jjwJrimHo=PJwu{iZ0)<7SWdEVDSonT9MN z&rKQho|}*B1*0q53k^s#+O=y6dX80a66<{89!K7#(YT=*GUa`mdz=}G9$qrwIyq~9 zg8G_83PPmoq2APvK`#{&=wfYPnY>mNPdN*TtU%(8% z;cDZ?g7x#!^W0mIcq_E;5>MjCao$@v6fkz}ef z?OuJlJz^5qfDd!7j4AY>R3Z(ippq)ljS^Q+9icN7A8#NWG5dz=D9`?&AW!L(qd!f8 zsFyPh)eJ0V$~k!EiQ$Oq9X5!NH-#c;!glX)wfVuq&qpKCMB0z<7#Vq7DpM&i9~Z?{ z<7#jwt{&Hblg3`gMss$i4gEq2H_H9 z0Mqf^R2t6M`Gz=FV3|h?@dQ&K<^_W zf6KjRL3X(2jUVYLU@9D3f4$sx>v`%f3V5ValYr@UKC2-BS zIk>qvDd(_JslSZ(2na94$;Il$_)BnD2IcFF9xuiB3f#(-yj{17j~3i&TqwD5_yBXG zbKn-?nF}+8za1*}|(KsSVz!^h&4B+2C!)ZaCC(w^Nb& zloQQu@UrFQPT0B6X<#lZbE}+9YcF=5{NnqZfmIETa@vRMogOwC>#>f-uyRz=m6!iS zPcTIWLI>8YC!J12d4#Iti#-Lg8Z)R@I#p%St3BhmpP2(xHXTWB@S+YRXaA97rZ#ww zS62F+7@fS!?_7vZZNiAMf{v6rwec$#IZxh4hn7f(I)_z`jV7HD$yuze#cr}F&O7dy zkmCx(q|>3XPY$#Fo+oBS+huKL8_v^4^Ih3o_?ixM0<7pqWdx;yGK!FF(WPAOOgTB2 z@%IC%GmV7C%6(Y!rOxD&`iuJpG%0Dv62s%8rOE|7A)W*f;egHK-k?)^OO)I>Lt!xIT>_pcaDSQ z!8H@HhqAi87kP`wzI3ASdiH!EjHCQ*b*VA2b67LI%_*bNaN~L>sgL#QQAErj{%i7h z(pe2{xcFknzUEx7ZF<^KvH@Z9Avh2QG37ZpIed|_GB8oaG+9{h$&OaAHwit9hHE|s z>;CCI1!My$XW3YZcsCIL2sG|LpouA&bhLp5N^}6yNZ(r*JF**|n`^~>QVezMd^c|# z$U`u#bhK+K)*uX0%5{Dpq@?axURtj95HiB$c6nLKS_qY$+8Xy@}LTrZIAiG7kP&Ifm*)hOW$fv>NipeU zU~2C#GQpyv#o>Gj8syfqSbq5L6tk|}&E8*>8+vWKBMVN5ca*erb3xfqz!1;t#rrI; ztOZ3;uDu{yP~r8WFbYwjP=c70$-Bc*_3^wZMixmZqPEr93e=*4$%!6sO(M*0UgAk#FP1w;W`Q@=n_D4sX65|;4LjR(JA@v{=M3Pp!QupR zi%Yx2300JVfclLc{*8hRQ>d&|@v#dr71a}M&dJYJdB^Xl@|V)L&a2|g`%`GC?{c2H za*eOANvkfW)#!BgGx|uf)!An*cZ5}k<4jQs29>n8_l82m-A>%v!p-y88Nhx&u=Flx z)5RA%p~~CAiK50;bc>cey{swQ{rOq6?64{b9cx=#9nEBm(U^9$T%u6<6jOx=bfr7Pt3a#=IXOkCx;XL0TACx)1_lq@j@N_4JIGE6B9oX32G% zL$Q3fvl*;??xV%M%=%;NoY79F^VGNdF*iah%05WuP@ZX(1xasV3YeOzp$on8p+9ye zfAO)x4|ggz%$&-za;jy^M&`Fywe)QCkr_>=oR^+f(&8dXFzhmLLT$J&QhgXR( z#5(5E|4PZH!Hbd*5_dY}-R7gs>?d{5LQsObExAkPKjtijN(ty9CpD)#iux$2gw1Ce z6~HbI(HVa;BOTo|hFx+w?10$-4-d%;ajHc)?;;nL@ETgUqr9u>cYGi{=#?ey{F5Jo z&#@;dYoznW`NAK%azZsVCgjO#rg(HfeNN%EV68zr+#|2{muOr#c?d;IUiQ!MP; zpOv8qi=HcFlVc4}fMA9QsKU*XF0x<1<=S%*@=295Fy<8|)`Tw%4TXb0|FRE2-8boE z`I%!G8ImX+#Osf2V>$#o zKGB~volJ$nPRW0N>X1Pv5m>hxJpJ@#O>?A!A_K_fokY+?bdAmp|L_v87Y(61eOm54`q0@Uu0}`vux3%oIPlnHn-H71-G)zNiHtU=W z*IiH#XBJ64l-x9|=RRB*_4&3!9c`OtpVyGB{YiK#f3FKTUfxqU20S7Uta0i90a|I~ zXBGz}&;cIO)G>PAu(uX}%`vgOmMf7;Aq0+deEn;5U7s>HPUN6>?pDxJ5(%|-VENUISvCXNk8;6Ev zyeD>S5uRMu;vLf)OdA{*&CK8gT%)IfzXp*!3k*@L-o18h)}H_1^Bl%yEI z2JjZa0Z@%RA{dvF$>6ddyz_0e5PE`e64T)pAOjUgd@5e}uC*3UaI_hS$wbR}PCVBa zfv!Ty?ACt_Pt^V)`^|q0PqqZ_Lxy3byAt1B1(_V7mO<_pH( z06Mi6dS|ae%ae3BpA%-7cHdJbM@c5PVYt_!jcs%K|5Ec{YLE9{G2XlV=7^g)XS{dY z%{RN<7i6dXQ}_c`%MGET_o^d|@7z^Oq!u@%h}*yw2iX67HmftsstcQZw2e z&G|?{(Rr=$QRk{FZsa@R?i!k(A7hLz?8wZ|w{GRwgY#Gs08%siysQ4}t%Y6YU*~oE z*1~9R)3F%0IRnctcAf~E&X?Qjo!*Boaq{Rl1vz9X5MSB!R-F~5!{uj(8H6kcl0P)+ zV{Yhc#j9W@r_82p@B9-R=w&c&9mS=#$L#$>_V-wi)gjYDUt*^1oe!tUU`vKYZs_y& z{vGK<#SHLHv&G)|S?(6dUBVFC)X*q<|E`vOL3+|PmA$h?jr=ewPy#wJ)>t1pyo>z2 z`fk4Kx{A|p#D+%Ab3?2ce&evH?A(72SBOb(Xw-an$T*M}M(uY54Z;rdP+lqvjauM_ z-cO_EcY{V3xMtkm`B0oj85IQQN*Q$6u4X=3cs_n8-*tuZ?FmhY!Zhuj51J!C++iM& zh5Urf{n^w0zNZ5bMpo@RKAbL`yDBY6laI0THn4Ecy;yU1rC-nQus7x#F3$e!pTnOC z&AmAL;J<`#1)t;{*CdyEd%T%+-p3PR9&7|c3GisB5A6iv57Q{O){wSDHbp~dxc$X^O=WU8rI%W%t9L!5DLuT0D50sT-_zufdu8&b>!X47~fkkV5nNl;`3oXF& zDZ+|8iu4_g`|=`B?7|n!Dv`kR+J2E=PY45&lN^8Nma+3Y;;-g~Ze^|07;?U%t!Eo9MGe$)y5q9MV$$dG+7?xXt8~^irB= zcV&*kLth>)N6IfBvR@_3Yn<91oy!6>D&OOrW7_$1a&qVM^y*_3A}Zx%$XO=Kk5*iM zz=$%|S0Q z^9g@9A8uUZ)ITVTz#_LiZrR$UEY;PD8`o!z)I>Qh(^8EVFC2_s(nVoj8H6QWl%mlR zbSNWvL&41!6E!;^)_c3{+>WH4=oB2;=M83J*EuY<)W19B2H$R#S!*MK*zD~%NP62Y^tkg*{Jw(`=$rl}V@+wM5md**ZJ`XH2s zh4Am-NxL0(e|~7}Yx!?wUd!)jeJ%go_s;c%0FCASyfUaEtyMVMJ!{o&j#9~?Q%o)Y;+GRn&iBVvP)v9}A- z%&unMTkP#0+-&D>IcU?7{d8o1e#c&%-JUm=w|fE&UW|2l^8JK}BC>Y-WC=88K$0>T zU9mt|eAGZXol`j+DZRPJRob78nGNe$z$&kp@n_DArpdS<3ER za7gOVY}Q;r|HsTb=;3NZw~~kJ)3QqRjk?_FtGvvqNk8G$WFALVOruG8bfb7k5`t#i z;%l68bEP9%_zL_my%z=^Wh*JWDN&q7W~1@f_^SgnB7f?H*O&ai=i+lqGy>9aB-x3d za7RH6kwyzEjHI1^;e%lhUD70JxVi=VZ3_F+9!gHpWw0N0u)m+w5J2OT0(QQS&kQpq z^Yb4A?4l|NaRPMH3@8T3^*=D^^`rL^=o)lRPwntTaUK^40UdeA^Iw_&NyqOByI9@0 zSA5-eD_??S=w)iG&?`$;ZQ2<%)aqo`jpH!1)z>{jQf^rWvw5IUguv~2{|~PupJ3$0 z(fh_V>aH`R=Ze0b>>So1;Uuz}Y?>6yoRx%zMWI;)7q4(2EQ${E70IA%cSfMII%0F3 zHqF(F3~wkicboh*dVzZpkjRntvoG217w)s&Bx$^1abhx~76@%qT(1QhG6jO@U$_uc z6cAkg*o1klX88fZa``h4Qs8G}ZYp$6hZ+FuflFEWxS65ko>;sxU{;F#^GHWBJ$SES9v|Z24nr($q z%y6ic*G3yTjzy}2SjX>3y*?Jpm`QW5%092@S4}!Hm6xif@DdWfUZ+$#@E1 zoi~@8;XBhE`R7vy@+WzJMB32gMtJsfA${12@&`Y}$Ob*a_!{^>`_Zsz*yFVZJFH!9 zk5}wPbzIbJ6NsFUfk_!*M6+N*IUe?q^3Omm)Zq@`H=!d9$HT&VT$XrV2^0f6a1!I3 znjEJ`@t#OL*As!lEa-TF8z-WH2;2k`aNvi7r4MHz@|4E%tlF z>GX!i5K4SRD@!w7wvb@AQ%8IonW82JmP0s`BPCd`nf-~bk3WZVIBz2&hoFg(9UIZ7 zULo((if*q=wef^Szn2!~Omgh3tfKQTQ{BU6c47opx_n7phl;*3)bKrO`;g+{_JJpq8uJ(Y_aQ+wzu>nFInc0c( zi4@+_?|t=wp}h1GW%48;TJ0JbsN9|}i?89BQ~d5>`F@${7GjdSLPA)=%S7QPC&$8# z(_p6nNr)v)nw-hW9hMnEnw-;xm=SqNJ%ffq@P1an31nsrsGAw5v%EjRw0o;)@NC>+ z%k1M08(|+!_-7L4Y=SOyN@lLdyHjwIiX>jBTH+=B4&qS?yES}Eyu>XG;-qmuKFIqK z80ZQAeDvl(@TK5fklQ~mr=YNwQYAC^ZoWFZq)0 z=P}7+lIOZ{Fy{r(w3=jOGsTrVD+# z<+gb7A*K%e)cJEYB0`GoWmyJ6+2k;2o`%)~qH4j)fO4`N$)YW5V>HdVtL%2*T}Nv^ zjpYHmUc?2L69Ok9(iZXxc3G7&|FTmNCR$70W_B(j%b-IIaY$G>CoSQ{?mzM^SG!rI z(Y-Hn#cX;Od97~6j%rb!?bSM8XUnQl+%a(O?yIiojbx0FiF5PEtC2yaQQ0as_pB$>+l>h?Pa zCL=J>Xowru`x}>{Na4W?fvhUx!wfnTPa*@!Vv5E~i`lPP%=@cI*sqF;P2O!sY&^Xw zBA(68yW{-y6uhalZAgO$X+f%LreJ}~rnT}5V-~q0$(6UPb^c+BLb6+wf0=MuD((E) znA_dGGT02lmks?_&`2z4yO#&^y@fe!gDTFRH`w*N=1m)Vtk6dunJ(@WZq(9Uy}UEB z5ozu5FRjC-i1;dW@73uo9ZYX8>1(Rc!B?kyIxq-5tDIFV_=R7i;A#pQHZl&FT}h`a zlRzrqeriYzLqG28XP1a*nZV-guyXsBYOZvsq#Qn%kvFll=#A|~M7L(3J(H0K7%p03 zWYuSz4G<7S68Uo$-!UYw>wtosnMq#Bw;`fAwPWpkB2d~Q6ul_geVzR)NX*|LWNL)w z!IdK2kM*Jn1ZSoRm15<`pfpR6saMw>K_(duwqicw#kly`R|QgW6w(Az?Vq;7M<~{v z{g}lbdU!ShRe)HAA%EKO-AtzjtQXQQ!yFbfwFwQ4#iI+v$I1j^W$`(IUhDWB*L4@f zvN){Tj=#4O;oBu^5|KRx4+H`m%Fm2^h-rzE=EqlPnGKa%x&)O!B~7zIG?0xw4}XV{ z4Yf=oBILy!gO)9`?EGx>-es(p3QYDnAlNMA_kwmX-yEd9*mw{UJm{~f-y;4(Dv|tm zoYPql?8h9sFf{f^en;(*{PT@R{Cu*AwVUmZPp)vwH8-~VP!?HPIA>q`ekXQ|+3Eck zGX5Ed7%S13X+wBV0TMz2}3GwG-JCGw~RR1r^?U3(diS}=f>;R6-q1qXJogg zLld+1SUsA3#?W8Lc7HZpon1XvZ(`YBda*V!n|U~_XAcrFR%&2*Q!IJKUv}&`{qq$j z0oe#w6{{LbhoaeCTr*8?mF6+QSc*GD9V+APxCG}nui{orpkiDGa=a7`&jH+087zps z71zwx;Z0ly&Du2_SslY|z#ut+^!pRsGm{yZN&U496xWUrJR9Lx)v>_rts~+h43aM< z!zD`n0QXG2QV*c0NnD0)FpTaP?wc%nnJX~Zdmjy6sZ=eLp&FIS;|@$y>Q9mFGc%O> z92|AURqX1orhF4wuAv>o_VeCP{j&fXY(c*sGw>TIuO+f4`XZNowfPn;sd`>;{c}eLrd-6(M-#zzEjpwTcRdy3TUCs2;XZGZDJ+>*K>(4joZ zzm&TBvEd%;FO9h`U z<=%brtEEpV7~gF^rynlm`m<8f?vp#ueC{rNW>4@U*D7dSV)4$?R_bg>bWY_BzO>(t(iuH*gNjzC2{|J}Fm0okV_}-%_mBN<` zCmZlH zzEt=VoY+xy;Y+$szBz#N^&tNQeE-&M5T1%3XPMj<kArz%DkhlJMcP!jBM^_q`7X>D`0}py@7r>CnLcs_bk4qpYsH|IAlr5+e*GNW>@u zL`*g6@S#SV*0G{ZE3Hu@qT+T`RBUODE!(9nIun?XRH1K>z>`|6qvhT5c4-@s3frZ2 z__EZsm9DmByL9)N8J;F0yKhvsrM_(Q{{GM0gpuvOAJO4F=YF1h?)SatoC|DVy6rXo zTfui|`ZahCT$;XFgZ~nI7r6A7J%jp#I3$>tM=3lBE_2*FfXX05z=O=w!v?Pd-^Bnk zn&HLZt<2j|g_^&q2F3p<_~@TF`bltU#WJf}DFs-BL-TZ=6)*`r4BpgG(!`ek za_}U$6kUX`0bj#>-$cC%|0eh@=J-(#ZUaBUS)CfabcS96*SdpF2Oh9~4t^Z}wCZ00 z4&xxoMgy>wvUG1U;6(^p!{Cy3+y#LOKLV};dz}UfKN~;&DU5Kb33*G$gwMmVBIt=_ zD--!&F8m52ppWZ0Tq6foGot}+5KbM9;%&koIE^n9e*0-WDg1`h_}Ie%@v*O2V_#Q| zeO+xOM&BBkbvoqiG5=YoBh49eoI9p(@2T6LJ@vzPk80z43i#G_e|6tSA6RzVvU`_( z>~jx3V$gXHe_`1j4?N7PAbPCe3lA(a?(@HBT!}J&fpNU!;m<9&cj?26Z(Mrs`cF^2 zef^=Sjn&t6bS(W+`)51aKL5yl>rYIbIgSYW#tOjFhnIb6eQm6#qNMBp!Z%{)`BL-Y zhM(nYAF!V8vem%-2F9p9X;w9<8iB1qgfK*dud z7VIm*l(oe;I0l|Du$sE^^NSi-YoLbddX~y*1A7g8!$2Om^8D98jKXa)aI1ksKtFjL z7Yxv_hP@BEm4PP>JY`@b-A6Y1lLija{4e2q7^tolV}l?LH2}q-HsQE06b@Ws{FfU4 zgThJsknj{A+VCiW2v7;k6^?t0aNvBPC~gyk3+)CjG;lYtp3Omo;a5-^dzXYE4A=y0 zG4AsXTw>q~U`i2o@SzNL36jBX1GUAG`#eG1m(WgBcPk9sWT3V_3Rf#gxH5Ih4%`A_Zir4 z;C`S8a15+vyjQq71M6$4e>udA!)Bl&Y!yzz1IGP*CLt*G4h9{?+YP*gc8~)$0rwmH zpurc>0Og+q%73wNs${8f;PR9SkTC%c0X>Qh95&EmQz-W|Pzm+`mEcK(Yv2~%0uRNn*# zfXX-_NVs_h@0ULWw9(Gw-tIx_e=#5R)U)^01@)#EEY$rRpt|2lgP$^Za%#z6&pF8d z5KsvpmOK63kvnij44kf+0X6|&1$qQb1IB4Pf+;?Z@F9vE1CI()q9H*_a@@EN8+gLF zpA@94^-V7&yv4v>K);U+49pq0-@ti(&GG2Ni2~$_g4eT{= zlYu)7%o%tHcnM>Nrszu;GmZd}(y<&t@ambR^kN3K%vAp;gLycJ<*h)mG;yvU zcLDWmN=}f5v|kW*9t5g4yb4t7KP-1zz9UEjJSs?Gh6HIR$AJnz3{-flF@*>9Row_A z;V4k8zYgei6N9%Hy!Qho|9+tSw;Fth!H)v#FJ&aW7)YCFG_cvg7N7{w(TfOZPF+$; zumz|D-w=++VdH*8?%XPtbRJO9y(j+264O9n_m)N@6ORf9^g0GZxdpgLU0Fh(>;i{m{1*M zp$gOO*}3p1eV?#9bK&y<&*Z`}-wgXDuv#Ql{MH68@K2{&WB+R|JQWjFXYUE~sG&V; zPq?A7MiM94eEUB8FZP5lBayXxNMw%vy*=TJNb6UnpzjIHu`k#gzH;2h&Q2Gu;UHMV zX6M-V?G4X-U`5-rZU@gfSV-B|n=F_3u^SA&l;<5{xJlYkae6$l0ja8?E5jP)nW;S0 zh~T0QrFET(pfPeT8Fx)txaRbaA`jVb?+qt>b9T<&7ye&?2nBoxwtdpR;wRx4_MMA= zim%VNkbcx?9qX|X7+l=n!9@jZ3?;JCRyl@gaaUJ3j89ysXY-;dV%!)qxLL~#ONU#Bj+fW8lwrz zj81u?(r%K4ZY$;>y0Y4?IS7MS@4V_@c$?oJtMX1NeAV{Ze;>Xmq-9x~>{ZP0wb=K_ zW%F5dw320uWKTt;lCj?V+iZVV-j&s0rGts%e;IZyilM~%}!>__$_nk2&UomU;+_|3l zjGCo8VcYx7XW0MqpTg&+UgV*Iul9b`>Ao~wcp=`K|LRTL2P2#i`)-k`=E;Q(fL-bf-;6|+4R zg1~@1c=d-P#bWdI=M~RF?0=)L!dYkeob@jsa9(~So8R*q@3lW_fAdKA;=rz1e*3i} z;d9250TGH7gjZtr@R9H&-=lWLZ^M@?z^@z4l{ccw1QiqAHDc#SLI}!;dtxtcICr13 zuG;5pV(MSN=YX?^+w`3BO73%RsJRXmgq6MVr!AR_fzH$o4*gWk5XFp^9c zy3iC@okY3};ZWUohLN{?r{mxA-|+v`c_;n*{NC>yLc?L_W8eC;vu^oC&d9Uf5PC;3 zAeo1bY--ybfBF5vs%$ru-eoAgtN7UWQ4xSrIOSz10=HYo^I@nKp_1Scp%O?Ep(;_Z zmu7RxN4#rfi5R6GS>ws|jToX+pF-OjF(qUd3LY!7dUVoRnrh~W9k~~I~Tj>N7PYqhNo8FwYD(9|V?JGuO$gA#4yU|y|#m4K?t}pt8 zGkZqPl?;FnMXg%=M!8BRv>|2i3{+U@GSnIKmGjMp9OB zD*}9Hv%VOxUiTCLw7yCE5oct0&@j*u8~L3ywgzGcv<`Vf>j}SPxU1WX42le6?L~h} zR{>qKDe@ag9$<*UjW9A1(9aN4rFZTFmP{*Vizja=Jw_djX7lrrsZ=IfSBSVqN|#~L zB_W7AxAshg=!r`B&L*uTv&Ek?wnd|>3ftp_{G(_v=$U${GZD6+0wP#(jKPw>TZ_ZK zOW$NGQ)MB9^LpyiV9_(h!pdr;)%)gsvFi|wLGCiy>%KR&v+!Q3yYSxlp28-d&w1~W z)dj0SQWG zfU06X`AtcD_Fl&i#{%)iPH&(j{bwamH?q*VVCjezBvx=GZlb_=j7iiQg7uQe#A;7! zQ0msTR%u$;jfe*d&6Aq1^409Vw>LEZY(!#{eUruF$Hp<5eJ=ZgMmN@<&js7IBY3qS zf0L0c)@x(Zko3p0#l?5}is2jr!wxbK5E3B16s1=&3V)6N*5uYWX=E%{?LdQCiW*<* z%Q$N`XPk5}8j~{LD5DrM^RgrNjeICpk{sC)|7PAwF~n}6q3vL- z_X5Pf?ghwL-Gf?9%Nk-9{{e?pcP^XH#O=Y685W`=2+BmUu!HFig|P`E;m94A#LoeQeVyobE^vf9k-I@D^^QMeoI+XSXs%^7A?J#tsS>wKKIBc^l~ zkG|6HMj4)lru4fT{2}MnPxrfrzSHma`Gd|IU+#Ag|FGZP=}>>Fq3h!|!*H-2_Ls zm8qpNn%y>YaW+F_T^uU?aTi# zu`jAH^zlN3VA!viTp5PkVB;FODxMo?JGr1T`L=^k>{{#$EU+aP_hUj8Op^ zJnfC~jDZwkY|Lh*3ey?5WOJkgneOdL^jO>Iu8E}M%PlJCmB;PL>+?TAIvKODg>7w_ z{Px5@P)n7> z7#eSF9g@+lfMr)53r{?I!6&eXK--mZo|yf|H^b-IiDO~C^O?=xLFbZE?}BH#3g@io zD%8pt!vO8xTI-&b%ocrgC{GJAjVvx5unzVz^c>?!hT`1}qCsFnFupHu&FOM|$pwWB zOw^9jn!~%RR&72I%St1oil~f@n%$uBei5S9HdP5UbQcbVgT5 zI(nl@^|-tK*h>7nTy~+y>auzT>8|1}iVs`_?81uZx~W}-N-`Vy6Uy_n_qqyS(HH-T zJ8$9!w{<#k;s*w!>29~e*ZpR6Mhfca!7VGhTv3X3&thxzNmrRj2&{)^S{^frYS5iS zZD9aY$i%WFr*})SIY!k&n8GweklzsV z4Z?LA;tv{vRmk!%Daq8KTg`GPTXT@_au$C7|HQ&9EDUzP`90!FBtr~A<-9se|BK4+l}gF@q@YkHWD*1M0c=q?<>q|qUIg+)&}k+Yew(LIaz z=c}UFS)(y(cKA6aaCTT-c`fqlXz0>oTaftKlZ9$g<#pTLLor79@z&qaZ8!0Ia%i;m z?|;}TipT(yZbdS??a6C2w=Kw5*!R92J}>n%3jOGcbYabRtm2_GtCer+9iwhfAI9QO z6a4~4ZAMqmw2DkHL2KTZ&E^+9#5ohg7z1iP26M(+yN5y@OpnRF!SU9&JyN8=7qGgA zIFy-^yo&XJrdgQiHM==|Dc9Gc)%NMB?eM)Elo3fH-jBi1jeKuR^7=9QbrlnCbOM;t zRi+!Q3g*1O3~RL){Y=2`qq2@6oJ9)9Z9{Cm&c zn(svc_QbZ-tqitbb+os#@0;#?gpI`uu{Efxt&*vWq85o2FgSu90*lEh{{XiZv3Who zDW0bh6vJW;%-u77&vOji+iG)+y@b6HY2J{f@7wb26e4JSzF3i5`MfWgeL)>_>$E4_ zrfFy`O8K4uRn_sQ-H~c$01G)(_9gM;)00M~K3G7t#FVzuS&V+w0yGI(NFcF`0g@zI z9JT9QO%fmIWB$&fW%gGOJ67+*SWRB*eyNuw_M;s2!HsC|TGvy+?pW)-lVu|5c);-| zmpG}&fP~o>JC(g%o<48@f#wCze5`QsW|VQW*XRGx(Vy=PhniJWJuHwQ+hW`LVpLn`rjo#V|yG*`z`|OXn%I_y@BrLXuCoaefG1AFIuMgyV#^ zRG#~S?^Gl|B6jB)$@Mf<5jMU40|KeO{Z-jw(r}@-BJBL+^QAgpi9c;R|2IHiat$^2YWo8x!sk8Q%6p6&w(R>aaw2BH z?ubc%8e^WMyDX~jTZ)^fbxmrV&^0N9+h%CCEaaQ-pXn^(0QE4h*2r0FoM5SqD9`!jtj&aFcw%EqXZD5aV zdEJ)3MDE(~5{9Frs&+Pwar9$bc$(NhA>%BXK%8jW+c;?Hyyx0IzgRe-&z(C93yAFV z)Cj*#^{VT()AC=Q^-FhReBa>9vks)N&rDaK!L$>2({%bjeK!$hzQHW&{CJl;0eg@W zF38Sk$?0|UwtRy3kPbq`6izVI4fTFrTTEd$uvE zt$GHph_ObG#`YEy@qI-s=!0k6rDn8KyI>7ZI@!R|8JSQtzAC_g7it{!Kc4_T28kY2 z$&^vcZ0|{;VvKF^(3SRszYkw<=emD6Z71Y7yA~NJZ-rxl7=~B9gnDU!yn!0yrKss? zH%KAWKpA$cCL1n^5RSa7bnX+ufAj2&+hYIr_u;8Cclk2zuW2Jul4{|m!c*&2vW(;+ zDZ+R4MfUVRgs1;S7RHW7XOD8Mx`xW54c5X3?Ny@D&f?NQ#!b+Mt7}-`a^z48Pc+C& z>irbtw{Sb6Jcd;ilgA0ZPtLTT{zG_XYSVogj}>#RE?FV->=`Wp*2dXe(;EHoz23CO zSrkc|{@K{)6RrBzCT$e|`>AVXP9X2&kf7b_^1^I+w2N&_Hh&xaAq%@VN3+GO*I&_w zWNkrb-I!m;IgZy^9d*|I-c`=kbN0LAt(Uw-@@e=@@HInTg~m`5g$Wv6bakUbUyg`> zmQ~k0t5m<2P>?LGT*__1YkW1d;K^#ib4)>-qp2?JdaN57XLSv!vbNBxU&m7;(h~i{ zpDrRii@b?!eiK_@UmK<}=dSl!rS6AxSfd%N7Vb#N?T$;+g=US-(V7BlQ5L?p6kCCq zCn&Z6wHtkpqu=1fwA=Y1_An8uc^#Kg)wGf*zj}r`mCXOaQmL9@n@)qstY54Y>ziph zb=TOB|1o^dg=5XzwC>}k^jZ44x=xrX?6ZIR$M95t<5l*tKZY+zRg?F~wKo@|z#xrR z*+yK@bU-OO)48a>{n84MP4n+$Uq2&)pD1o~N*RM4zYa_wITgH@*6@oS&1?^`uA zR4t;JvurQk%=aey?Nh9`s?Np`Q=G{cmkDeqIDlBU1zW5@81DH6la3=!5JTw18z@%ISm0;;P!Q!GWjY5k#nJ@*MgG zchjh(pqrr17*nNm^mK##=$3VY9i^^c&v%SWHO~6+8@R8}U9Tgo=tG_|Y7g}pj&(Y_ znP$X;E2&oslK0)cx)9-cX^R&wf_r#<*SC=cK#J4cc*fDm5Bfij#cxJUr=u0^JXE`f zuPYtmsqqZ3`SvnRGF&Ayl-Mi5Z(@W~V@rIV+fhorY+|3Q?(`g7)qr2YOyxa+G3$OO zz?quD9=d`;u#bKrVPy#P(Lx0j%0m+>T&U|ctx_A$9D}=Bw#G{AK6#UG4_w;q>vGSr z|MpaP>bY7qXG|0}W>Z!$qdiZHOWPa%BRn;wkU99(M%rzbaHkQ-%H=;b@AUc<~|NE`C~)oOmG20t+Q=(>9e3A~jW~E({m_ z9lci#dU}#f52b*aK^<7CNEZTi(#9I0?&WE}^d{OESv_Jf(@XUv+(RdGZ zXgayWdkaC~PFxW#YMpUvQn)x8KH#-N>P4eUEW=FxOK!GT6`9e!@T$AfytEjTzZjvB z#tUcv>`&pz7oQ^OKu2aU!kn+Ew}NPUz2Lv_j=f%CQhZio}Dj3~`> zwQIXI|3i9dbH_TjC0TJ;RRO(|4aZ^-bVyYObMZs7@DXS3pFr)@0qI~e<3Ccf8NQg{T z7%j?L;u}INa(&;5XMNRHSHuTjy_Q6rU+INot!H&4=c9{gT}v;0I>!t4Y89m7-9c0^ z>{*<((9w?_jv)>7XMV5ZrWT>4sgCM=W#83iN-Ot|vyx+&WmI9~Y%CeE=EOJ&&m_M* z>lf~8SSpx0=VhAh9&Z>6(+RV;hd~&Ji3tYV;@HpT*|xhJbyX{p&94jioKRw3;kgM}-?RzY2`Z^&WgMl^ zaiwn`zt`zcuX8E7=Y?4JFQTO73Zv7u4HicY(XWARtyYe^PRQbjEIaL0(~7eYPt@RyqXI1(*(kbouows!XSz+pQtbh>@!AUffjr zw725yc3V@FQhP(O{i%J^osK9hg%epC4c&&lA!l&F%|L}w*r)b!ZOPtLU96XI$FHU> za6vyLNSjCycHXRRx4galSKq0vus=e=iunB0?!s=_d*4qK=n;a>v8QRJWDM=xvy?1!oZ8N+Ld$g9P0%Q1 zlT>yTnc6*z+6whFkb(xRhp$s?Uxu5shJ!@Du zmzFwpW&OIEGp{rIG;UMon{l9$?~^x#ix+Oo4-HJVh%#4 zEcj42W4zaz^MTyhWkbQcYhW7N-p27zf_nxBxd*GQpu2_bZP({_BsS%BudprgwfuI+ z+%q_zD{OcE^F2dq^rE2;YWg|j(C9=1nnVMd^aw2{yywOplpy1UPC z7NubMVfyMf@Kou?|6$~xpT&te~i6c4Ec#e z2YkidiFAG*t+zU!9*n-sX$5ex@MwB4oy!(;2t(}WcaYx~NvDZ4&Tr(OLr6Jb@_Uf6 zxcCO&l9<@aZ-+gtIx-{G7S9G=-NU~0weiImaeV}f&q{|xQwDqhzxoMjw}&Xb{MPX6 zQ@BP>6!`Avm*GIh0ghTnZG)o{ty1HDkuHC08P1Y_3a{=QlVQBO?@6Z$jg0wLBAZXL z1l2OEhE`vyMrKhG_Kut=hc^V`kuAiq=k zvA#Qc%?5Yp`I&-K#mbCNO%Ps8SVtVvmjleE#Vxc>8re(XY~#( zW?9?N&_lbTHum?pO~D?wv9`x;=O{|U`A;Bt^OOy4(}TX^mWwyI17x=2*ar8}=*aJO zy|TgG`kf7~Ol#(kRsLfK>>I~LE=fI~c8+_^Gn0QM%PrqHZ0dcFiyLjUv3KhGo05&w zyST<&@Yzg3mmpYuDTJMDe!u2a7`lnVCoiagVo_CR+qCI{#CyV_np@3Wq$=3pf-hqFVD zi|Sg&7kk*x>LjF#O0lBr+(qz4eJ#kz#(VTLopvnau(M}kCe%AoC#-B&sWe(;&DL{# zHNJReGSg&Wk(S!HBXe+HfQ5UQRz9JJxp|E$G}kwn@%ib*+Bn@(Tzx)=$uw)N+3Pv5 zTSV7f#ao8QU|whKlxgHN*fo5$Wb3EpZS7$2FMTFAkWTK2c7_jdN? zX5GPIh`!s3&)~k^hb<4Y;XQX;=|qIp)!2!MPCq8%zRri;b$Wd16y*J*r@STIT3Wq&0EE=kt$x;RhY{DZu24BYOcx89-t@|61}SMg4373OkFi*@LXShw(vNX9j(56D;;BN7mqq=j9~UHwnw|% z7(JtjUn4*DlBoo$-q+{O8W%2(RNq|m)f1NR%es&dv8tWw0LC-PbU>|N)4-pBbI3c_kyIaH%hufSXMql}-UhiSogjCdLO5Hp&$dde|iJN8)qu z<|QUhE+QRWc_~aFm@8ITId7ctI8~O0?x5qDXSq=%l1eaE`rzq|bR4LanHrTw%F%|U zI%lr?%}L%})v{qR9Z+jnorbAT#7Qqfr)%LS+tk`5@1h!-!F}|H>Bw8P5oWGN%%Hbc z%na@zfT|%zW_Mr8BuIx*#t0l1^!--Z_l~mf2Z=u#=IpX>j*!OUPAU85u6WG-;QTUV znC-crxq!n)?07lF9{)Ck6*4Ye$J+pFiKyXd`@fI8wc@Eh_ejX%%DvBRU8$~mXFhF* zY9e!{pomyp9|$-Dy%{7;FmuY)sjnkjeEetjtu>LmuD%jU+ZWpU^6L33FJwMfI2fAI zaGRx>sq?gD@{Jl1ZdKB^7cb;{k?qz*Zo6^l-i&+vmW+FCIy+;S0}Dpvi$^f%wPjVd z)0fV!*RijttXl=Iy&X>JazJjwA00g~v>&gHOqsrr!@-;GDea1Wj=_;BN-6~-eRFmp0l(E$*kTS<_THQ>v|!Cj4I#m+#fv#i zuOp1OAR%8Zm{l{;IV(%YfNd+iWrN%lMrQk>DGodiezXSG=+Li|6*Q}*TRNE!+w=3< zI^8yYdPS%mHys^GyjhJn7Rz$~w#r-C%aEo9vvy3#%TI~Rt=1|XrpOH2=bJcWCG9|( z<`Z36c>QvO*daD0bFrwibHKTjO0Fpzq1SP$FA;xrW{UM$+eGQ>MA5h%gZdp{cj( zL_L&gpgMS!Z%o*D3LBj|&GZ}-j1n@tmz{dY>cSD~agOm1$scylhR~bjpIlkEHAM*t zGrv3xT)2raiwSe-21c)YW)hlC!dekaqB z$!NpIY<5+B@|mv3vf1_6`P#6tH@p4=pIiA9MyopEQm5|gYe}bptMa`!QzdXnCKm?#MDOrK3-T4=Fk#_=^^!Y@6ly46oiunBlSCkBx9N%ks`Wz(#CKX3fj$8P+{nx7lGb(nV6tUd$ zY?%04cGzEgJu)-25XXr9KNbXL1d=Zr(1vENxs22sB~`hI;0Y_WPriCQ{l&3@{n(!vr*>x{o2sPLZv&VQUrSNyp+$T~~|KmPXu ze1?z4GW^SY%Yp&_d;UH4GyfQwbvBkP?(g`LRWduV^Pm1PvdLd@?_Vx^u9 z3+NBiaHvT6pAf`dT4kPl1jx5z;88)+lwk+YB7~Hd{4l+m$n`L?R&YWoF)7c+gwtN7 z+bqrTxFFYDM}UggL1um`eVKvF4P?3Exwq3vq@Ju^BSIR0(mw7NOp!>&WY$AwD#1yh z5*{K`QF>eueAwV8fai0(oq?G88Qi}^jMSR5f@J!tAepwD18jhEf)}FJCK#hz2u`E> z0GWZHj3X>L)CtanLP47Hd_fXeB-ltv1!4VhK{BeQsYz?N5hwzi1gVO+AcW5~xM!B& z5-v8tmCs2*;$xlwjqoOh0y_TrI2;5@q52I$4h4=F{3y`lh#(mpH*g_rRRJQfQ?OBx z3|0V@URF5pRpWou_%C5#ky3t7eTt7+G$uI^a5qpH|^;B0h$#9fE!D>d@em|}8j4sq7g*my z#)7kH-GW3|PWw>!9znQr$l%$FO72^Ls{5^i6l6fq4@V3x<$k$KmmW@~tbx*pC8c_? zZkK_(4a^ycL37Xlpn)fVYK#N4A8{afDGs05)vR!f4D9eA^*^AG zYhfMm`~=-XI0-DL)Jh;H2!2$M42KO~OFIxg7pM|83sSNc0}}?$GjIj4{=@Wp!H>{p z1RsEvL;AR$5zD~HT=02xC!j_^E?vD5aI@Ucx2#_3Q3-4oB>q;QSbpCZIzILA7dkve z{1|^{DC38&zEZ02(+-C&O7+wA`3sREe~p%2EstHJUL0h#X1?<}0aT{SKoVg3R{Vc9-=tsE zjlYVhg6Z^F#L86X6Mj=tMwx3W5po(IMPLUdlJU_!#c$=Z`R5X>w4*ECXl^B z_k~!kJ3g_$7)h*jD>&H^kx+PXkZY~#_*1S7+(vUxvGjk+T^9(TLX~#<;xWgvNXMu; zc-%y3As_QtSz;gO3{OarOXmy7b$S_knPJ>k1O*_-X9$Wwln9l^i%aRmJxcta3L*c| zLIfy4Ew~Dyv{Iv`_$3J_LuIT3K9y7%mpIW`5GO={I3WU*xj6C@v6!t~#9CR9q5mMI zpAhXGVsqp6)l73XMVp*@zGH-Co<)I(bFJw8PIX(-AzJoeRQuY)=?uRM}^J@?aC{-yAF z=XwnlQHIcU8QMgtXZYe&xBaiAj4Ay0ds*_r-U4E69NQ)edY)btz%%5YtiZ=;ew%57 z1N?ULJIGIZ^$x$|{GJzzJ)Im46iwqgTSl_)I^Nyz@NhIUe z{6c!RI$8g{&$>ORL5R3O%wP0H`N4My;&M_o0U|l#%?9*~B3+_H+egbr{2=KqCw`Fl zcI2HE#GxLGKCNXHpoYU^MrmF%_dk zL0x>M+X1T%wLM#Uk(am{i?q4(I8U*;(nuXsqH1Tm@X$TFzO`jkaW%f^m{AcF`TKk; zyxg~%@cRBAe6!Q{cqvIzgt)wKiF1d|x3ohR8diufr5XRz-6dX%k6vm13trY5UXCUp zq8P)Bpruu`5{aUZlK|Dra+8T=Up*YT>1;Wr$DGy;M{2I-J@x`*F%CcN&Nj8F;x@ut z-HCc*G|}YNgxjW3H~Y84k@F@gMU`5LtEHeEXW3`J9XYSEftqZ^d#OF^?Z^yJ4$We# zoL2juw<8zbqlmHI%xQ9z2MJX|OOHvcoVK_1!ZKmxeCo=hbWwdOpL?yyb^X&)kL_Rp{d6TO6GXIQJ<Q_`l z_Oy2+lcDMAcNr>{QeUn1o$p4zeZ$Gy&}!@GEO=r#157J122xIoEN-lH%|#j;i@XE8R2=m?tCxv|IvFcEZo-$2v8IGePI0kbD)w3cbXUep5v6S! zhNvZm?vvAbSQR(R`i6V1$3PPB7`UOVv6bA~EX3r?GE(CxZ)FYY1}Me_;Da9dV%2(E zaV@h+Ae+rMaC6cMwM(=11;39>pWVQy;Wa)Yp#bWP-rhGD20q6POI@tbJ$0=Qvj}}| zv!6%rBA2KB9HV+mj8dZ;V-#f+ePWcJktp>9-G;rNS*5ab&SlD_voY~Vb*-@ec_f8_?)>Ou@m?=vGWofnZe~83W$x@v+l-D`MtFS0e zc~N@*?{%&=qINJ^43V!YSMj)0_xwhSps=l!A{C?vou&x?FLf>jIlbtnGy2a_J&PF7 zb(k3;okvVMr7rz`R+PH*>9(^pyTKj#-V>J<#-lwu^1WAz1v*yZWI9PyW~` zSn8KiR;a!9kNy~$oYK5%wPo|!>q>8!s=sMa($pooSg%jnB$0Eu!`S6aiMpiG#58h2 zXCV>m3yr4_^Y&XP6zz0IF4$9?7t7$br`Q@>UEn45&>G@P5>!>#!o`5%FNtpqEskwW zg%-zGhcp;1iLDO#;B0oRLon0El@C(L!oFM6o_iT8o^rBcb0)NP1PeG;rlZ9bD zXH8;UWE85Vbvit1GpHBg^qOlVI?;?eB}-Y%4tnFgsOPc&Cu~uos2fl5<2D35hFo)G z@`uF9T2m&Et8A#6%5WdWZz#jHDjQvQFr$q`YOYf>1yhCemId`VM}O@rcO#6#2BR5w zEUf*PBax}J^7Zc4QjKgIF*UMdtVVW?eeL$XHcYE5t+)4&c^veya6uQv~fTGdI3wk~y<~d(v1M)prD<0r1k9{Y-Y)r8E1=EW73y*;dz@m-H(s&;&Vhwzi<+?B>G2fcW~zJ?zZg6R9y9(Q0y<^*E#MXt z=V_-KM5U+Ku!B;Z-{ zK2a8a4*s<;VKlt16TH)C(h&i7fzKcF=lJ_k9F~kZ_&m$rnKJxY{Ig~F-+}K2A0^-y z;77{vA@Eb+90z$B$~2nJl}GUjaBmT~?5I!FYbMk9SRS??uc*8rwMAPgN+U||!F^X1 zM{y>hN5I>uFIBPp*Mg7!MfvChU&c}1XvzOOcrSPk0u=s7;B6eVjQaCjpS83M|5rcf z6+LAR5eV5_hEE62mEj)(KLXxB=E~q+a6ZQHFM~ILA2j~m;K#uS4BiL6spd36+XI}E z?J9H75&auw_%U!DPLGx#2q&uPF{AiQ@WwLyqu}$(@WtTCGCU2wq73g3;m}`eUl6Ih z?1C6nf^y>!w2tzjOh)lxy4Bx>&)vByQu*(}1&8s`!JMvyE`dbZqH6-m2DR|52H$V+ zg9blp@F9ciYDwY6_oje7?!JoYDcugqE$O*IuEEm=-(>Kt!FL-xXYj)YKVtBc20vwR z4O2?L9w?gU8oarLbAV(V+D(9^2JbL@F7fnOdffim)^+FJn>A!(opSzHNM zQZuMN`k(>~7`Vg0!}LYnUJMBm?v#PL%+%@jJkE0E-!6#1XXhHIdmH&Tb9EyBRzchs z8Msss|3&oOlrm28;fLDAg5XOGj-hMMy~DU?falL-JQr-BJsS4}eN^%08Q5yzd;{Bo zD)~a7O5S1cWfK?>hkVuLR+ zc-r8Z>x{!D)9+*&>NDZLD%jyZsFTIlnCZs2! z6jWo)Nl%ix*VZz>t!MZhF7rE#U#u+Nkutv{`1w9~I?cW^zrG3S$&(OF8p|-kvPH!7 zO|bv1w(=Z%)5J>5$3a<)RInd77Esh}A|)-GJxO08Z6b`^ca-I@12@D5-xsgH%)cN1 zM47)t6FHs>3?N;sw8;BXD7u9cD+V)+ti%v2hL9pGa=iffv8_eDAsvdw)06CEO=Zm2 zV|Uh6)|`9dy0m)|+2m6b(yoPw4ykbTqTw6J%QcNLCjb(qLw(_ETR~YXVh6ibbrwuM)A}$V^L5Qc-$= zP*ancz^G+v+%gqlMN7OKt*t)$m$j9bU$CW&bz4Z98;~*9qCh--QswlNH1Oa^F$0XU zL}fH(0A=xv@U_o#FL6%XTVv8&W5~=IJZJFz2H$V+g9blna1~2tnHW>5Zo4*Jh{ZbX zeUmD$zED;Yv?pkw9_eZfj_6xn7!C+W&^#=H+U;rQR8IDvyxqR$oXRWxC$6wRe@^9W z;Lg83r*g?zXPE7rGxy55JmBg^8dHqH{Eb~7on=L=VeO>Z5dHLDKHfIaY496NsgqKy-~$9eav{X9Ne? z%*LR9(X>t%gDg|HHBGYvYs>2`=AUAdVAyaudPQlsEUmZLK)RskO#Mkr#B^L=u+rQ= z44}O%)A^c9b_AUXA2wL&;q!>{_>K;7O+v`#s_0YW&u^4h4?y zN4Pg)@yaK1PRvJnY;<|zWUz3;Ap+?A!we_vO(dq?WbJ>}6XOoVA950uG8TJCrU;7j z;6@m3=&4#g+^r#Z<>p=1`rJs#tw&^V?=W8H;F{Jw%D)>seTI{F~%cl01@ zxc5Hl2Z))M28db|>nQ{}dz^S2x7bSRbd{rrSm!DXrL0`H%JIc{otUuUIDWWSlZoCA z54GJ}@Fmc4qS}1Vr5!y28s;J`+_4G~4ouC&ce|H!{GJb5+g-h0Zdvy`!RT6g8CN4# za{C5$LfQbXz)k=wU%jMqn(v49 z-w-k-IX^FC^cikn7UW-psj&_o*-j%^mZM1^lpjN^F4iF?%`b>qVxk!TJbQ7OKUG;8 z!5fGZkw~}Nu;Qtl>DEFcaT|!ICfr2$y1mc3i2=j`2e2unw_2U}%0dGPtcb4Rxp&%X zY)t`Gp}d}Pme#vJ_K*{g>fvGV^r}K6w*;an7PdxZ_;mpmZA7e|jE<8|IE}vro>j-{ zc0_EbEeW%+`ld>P;n6HDV%_y?oJJzfB|xNejnl+;b+p@a(;L&0T(ll7x$Eue2$==r z+daw1p!LI2rP$wXsyuh%SPhiKCSjR9&{SEQ^7N!s6{<%nR7pqyFlg;ARR{Q)^%=!q zm9hdYQ^oU`NqE(N^v{IXYtRaB#V9kCh_d_?@smnS@rd&2T5RYzU5k2LSv99xj1jSc zZ`Go@Qh6;lP$8qW*px2SVhiEbza?5ak2n^0n$5&Z;1=Y9D$>ElYI-FXsHv51?Z8TR z^m)-mK~A(n45&aU+|W1kbMJfBtz-0RH|Acr^{PSaW=cz;*9|RNUGSZS2?J+bVcb!= z$y=ZFE)lHU*UZql$s00RHS=;vCfg7LR) zZpPis?O>SE=kvJTKCY{9-347<7{rAOU(@xGAt*j?Lx@Yps=5Zx0$n~3zt0JbUOyyg zazSjH5O%3<8yUOjE-QtvCwwYE{k<=ON=$?Z5n4J+5t`fky$oUv{qBDX-^Lh@Jbg9c zt4;WpzEb#xKNr3?n{Od}l<-H=2wox9p?t=-54=p$ZnTwAONdn0P2>S=>g=TTRtKw2?#6;qA%8!MMBK6n{32$jC#@xbxE3iLt{r511$9=X-MKn2)ju4u zzxKD`bL?HK15y8pi2a+nl`}&pB9`@l-FXA=9JGCe6Sq6HjwngICa$QA2Eff@eR$mI z*~AZJ*}fgJfBTWj8KDlcSWpV?Tu~Xfo2OKcvoE`{a<<)bePy(b{n^-`4qndVw}lF8 zWh$s{N@>Q2A@dK`3_FONou5L{@W X?Aj}V6T;!x0Di)E7`RK2E%pBf?8ro~ diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c index 1afc9ed9..d9867d0b 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/vfe.c @@ -1404,17 +1404,17 @@ static irqreturn_t vfe_isr(int irq, void *priv) bsp_csi_int_disable(dev->vip_sel, dev->cur_ch,CSI_INT_FRAME_DONE); if (dev->first_flag == 0) { dev->first_flag++; - vfe_print("capture video mode!\n"); + vfe_dbg(0, "capture video mode!\n"); goto set_isp_stat_addr; } if (dev->first_flag == 1) { dev->first_flag++; - vfe_print("capture video first frame done!\n"); + vfe_dbg(0, "capture video first frame done!\n"); } //video buffer handle: if ((&dma_q->active) == dma_q->active.next->next->next) { - vfe_warn("Only two buffer left for csi\n"); + vfe_dbg(0, "Only two buffer left for csi\n"); dev->first_flag=0; goto unlock; } @@ -1422,13 +1422,13 @@ static irqreturn_t vfe_isr(int irq, void *priv) /* Nobody is waiting on this buffer*/ if (!waitqueue_active(&buf->vb.done)) { - vfe_warn(" Nobody is waiting on this video buffer,buf = 0x%p\n",buf); + vfe_dbg(0, " Nobody is waiting on this video buffer,buf = 0x%p\n",buf); } list_del(&buf->vb.queue); do_gettimeofday(&buf->vb.ts); buf->vb.field_count++; - vfe_dbg(2,"video buffer frame interval = %ld\n",buf->vb.ts.tv_sec*1000000+buf->vb.ts.tv_usec - (dev->sec*1000000+dev->usec)); + vfe_dbg(0,"video buffer frame interval = %ld\n",buf->vb.ts.tv_sec*1000000+buf->vb.ts.tv_usec - (dev->sec*1000000+dev->usec)); dev->sec = buf->vb.ts.tv_sec; dev->usec = buf->vb.ts.tv_usec; dev->ms += jiffies_to_msecs(jiffies - dev->jiffies); @@ -1572,7 +1572,7 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned } } - vfe_print("%s, buffer count=%d, size=%d\n", __func__,*count, *size); + vfe_dbg(0, "%s, buffer count=%d, size=%d\n", __func__,*count, *size); return 0; } @@ -2459,7 +2459,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) { int ret = 0; struct vfe_dev *dev = video_drvdata(file); - vfe_dbg(2,"vidioc dqbuf\n"); + vfe_dbg(0,"vidioc dqbuf\n"); ret = videobuf_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK); //if (dev->isp_3a_result_pt != NULL && dev->is_bayer_raw) //{ @@ -2588,7 +2588,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) mutex_lock(&dev->stream_lock); vfe_dbg(0,"video stream off\n"); if (!vfe_is_generating(dev)) { - vfe_err("stream has been already off\n"); + vfe_dbg(0, "stream has been already off\n"); ret = 0; goto streamoff_unlock; } @@ -2725,12 +2725,12 @@ static int internal_s_input(struct vfe_dev *dev, unsigned int i) if(get_sensor_info(dev->ccm_cfg[i]->ccm, &sensor_info) == 0) { os_clk_set_rate(dev->clock.vfe_core_clk, sensor_info.core_clk_for_sensor); - vfe_print("Set vfe core clk = %d, after Set vfe core clk = %ld \n",sensor_info.core_clk_for_sensor, clk_get_rate(dev->clock.vfe_core_clk)); + vfe_dbg(0, "Set vfe core clk = %d, after Set vfe core clk = %ld \n",sensor_info.core_clk_for_sensor, clk_get_rate(dev->clock.vfe_core_clk)); } else { os_clk_set_rate(dev->clock.vfe_core_clk, VFE_CORE_CLK_RATE); - vfe_warn("Not find this sensor info, Set vfe core clk = %d, after Set vfe core clk = %ld \n",VFE_CORE_CLK_RATE, clk_get_rate(dev->clock.vfe_core_clk)); + vfe_dbg(0, "Not find this sensor info, Set vfe core clk = %d, after Set vfe core clk = %ld \n",VFE_CORE_CLK_RATE, clk_get_rate(dev->clock.vfe_core_clk)); } //alternate isp setting @@ -3885,14 +3885,14 @@ static unsigned int vfe_poll(struct file *file, struct poll_table_struct *wait) void vfe_clk_open(struct vfe_dev *dev) { //hardware - vfe_print("..........................vfe clk open!.......................\n"); + vfe_dbg(0, "..........................vfe clk open!.......................\n"); vfe_dphy_clk_set(dev,DPHY_CLK); vfe_clk_enable(dev); vfe_reset_disable(dev); } void vfe_clk_close(struct vfe_dev *dev) { - vfe_print("..........................vfe clk close!.......................\n"); + vfe_dbg(0, "..........................vfe clk close!.......................\n"); vfe_clk_disable(dev); if(vfe_opened_num < 2) { @@ -3905,7 +3905,7 @@ static int vfe_open(struct file *file) struct vfe_dev *dev = video_drvdata(file); int ret;//,input_num; - vfe_print("vfe_open\n"); + vfe_dbg(0, "vfe_open\n"); if (vfe_is_opened(dev)) { vfe_err("device open busy\n"); ret = -EBUSY; @@ -3940,11 +3940,11 @@ static int vfe_open(struct file *file) open_end: if (ret != 0){ //up(&dev->standby_seq_sema); - vfe_print("vfe_open busy\n"); + vfe_dbg(0, "vfe_open busy\n"); } else { - vfe_print("vfe_open ok\n"); + vfe_dbg(0, "vfe_open ok\n"); vfe_opened_num ++; if (dev->input == -1) { @@ -3967,7 +3967,7 @@ static int vfe_close(struct file *file) struct vfe_dev *dev = video_drvdata(file); int ret; - vfe_print("vfe_close\n"); + vfe_dbg(0, "vfe_close\n"); //device vfe_stop_generating(dev); if(dev->vfe_s_input_flag == 1) @@ -4024,7 +4024,7 @@ static int vfe_close(struct file *file) vfe_stop_opened(dev); dev->ctrl_para.prev_exp_line = 0; dev->ctrl_para.prev_ana_gain = 1; - vfe_print("vfe_close end\n"); + vfe_dbg(0, "vfe_close end\n"); up(&dev->standby_seq_sema); return 0; } diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/vfe_subdev.c b/linux-3.4/drivers/media/video/sunxi-vfe/vfe_subdev.c index d42de66e..be8fe6c7 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/vfe_subdev.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/vfe_subdev.c @@ -91,7 +91,7 @@ int vfe_set_mclk(struct v4l2_subdev *sd, enum on_off on_off) struct vfe_dev *dev=(struct vfe_dev *)dev_get_drvdata(sd->v4l2_dev->dev); switch(on_off) { case ON: - vfe_print("mclk on\n"); + vfe_dbg(0,"mclk on\n"); os_gpio_set(&dev->gpio->mclk, 1); //set mclk PIN to MCLKt. usleep_range(10000,12000); if(dev->clock.vfe_master_clk) { @@ -105,7 +105,7 @@ int vfe_set_mclk(struct v4l2_subdev *sd, enum on_off on_off) } break; case OFF: - vfe_print("mclk off\n"); + vfe_dbg(0,"mclk off\n"); if(dev->clock.vfe_master_clk) { os_clk_disable_unprepare(dev->clock.vfe_master_clk); } else { diff --git a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c index 893be78f..d09d6766 100644 --- a/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c +++ b/linux-3.4/drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c @@ -1473,7 +1473,7 @@ u8 rtw_check_invalid_mac_address(u8 *mac_addr, u8 check_local_bit) goto func_exit; } } - + func_exit: return res; } diff --git a/linux-3.4/drivers/thermal/sunxi-cpu-budget-cooling.c b/linux-3.4/drivers/thermal/sunxi-cpu-budget-cooling.c index 5bfaec3c..71ebc41e 100755 --- a/linux-3.4/drivers/thermal/sunxi-cpu-budget-cooling.c +++ b/linux-3.4/drivers/thermal/sunxi-cpu-budget-cooling.c @@ -72,25 +72,6 @@ static struct cpu_budget_table m_default_budgets_table[]= #ifdef CONFIG_ARCH_SUN8IW7 static struct cpu_budget_table m_default_budgets_table[]= { -/* - {1,1536000,4,1536000,4}, - {1,1104000,4,1104000,4}, - {1,1008000,4,1008000,4}, - {1,816000,4,816000,4}, - {1,1536000,4,1536000,3}, - {1,1104000,4,1104000,3}, - {1,1008000,4,1008000,3}, - {1,816000,4,816000,3}, - {1,1536000,4,1536000,2}, - {1,1104000,4,1104000,2}, - {1,1008000,4,1008000,2}, - {1,816000,4,816000,2}, - {1,1536000,4,1536000,1}, - {1,1104000,4,1104000,1}, - {1,1008000,4,1008000,1}, - {1,816000,4,816000,1}, -*/ - {1,1536000 ,4,INVALID_FREQ,0}, {1,1200000 ,4,INVALID_FREQ,0}, {1,1008000 ,4,INVALID_FREQ,0}, {1,1008000 ,2,INVALID_FREQ,0}, diff --git a/linux-3.4/drivers/watchdog/sunxi_wdt.c b/linux-3.4/drivers/watchdog/sunxi_wdt.c index 8320991b..88efaa1a 100755 --- a/linux-3.4/drivers/watchdog/sunxi_wdt.c +++ b/linux-3.4/drivers/watchdog/sunxi_wdt.c @@ -58,8 +58,8 @@ #define WDT_FUNC TO_WHOLE_SYSTEM #endif /* CONFIG_ARCH_SUN9I */ -#define MAX_TIMEOUT 15 /* max 15 seconds */ -#define WATCHDOG_NOWAYOUT 1 +#define MAX_TIMEOUT 16 /* max 16 seconds */ +#define WATCHDOG_NOWAYOUT 0 static struct platform_device *platform_device; static bool is_active, expect_release; From 24947d8ac543c92a93f1b911d23b7f16a3ca0bb4 Mon Sep 17 00:00:00 2001 From: lhelontra Date: Wed, 9 Aug 2017 23:55:27 -0300 Subject: [PATCH 22/26] update kernel config & vfe driver --- build/sun8iw7p1smp_lobo_defconfig | 72 +- build/sun8iw7p1smp_lobo_defconfig.old | 72 +- linux-3.4/.config.bak | 74 +- .../arm/configs/sun8iw7p1smp_lobo_defconfig | 72 +- .../drivers/media/video/sunxi-vfe/Kconfig | 29 +- .../drivers/media/video/sunxi-vfe/Makefile | 10 +- .../media/video/sunxi-vfe/actuator/Makefile | 4 + .../video/sunxi-vfe/actuator/ad5820_act.c | 12 +- .../video/sunxi-vfe/actuator/dw9714_act.c | 14 +- .../drivers/media/video/sunxi-vfe/config.c | 169 +- .../drivers/media/video/sunxi-vfe/config.h | 3 +- .../media/video/sunxi-vfe/csi_cci/Makefile | 2 +- .../media/video/sunxi-vfe/csi_cci/bsp_cci.c | 80 +- .../media/video/sunxi-vfe/csi_cci/bsp_cci.h | 2 +- .../video/sunxi-vfe/csi_cci/cci_helper.c | 76 + .../video/sunxi-vfe/csi_cci/cci_helper.h | 4 +- .../sunxi-vfe/csi_cci/cci_platform_drv.c | 14 +- .../media/video/sunxi-vfe/device/Makefile | 17 +- .../media/video/sunxi-vfe/device/ar0330.c | 493 +- .../video/sunxi-vfe/device/ar0330_mipi.c | 213 +- .../media/video/sunxi-vfe/device/camera.h | 1 - .../media/video/sunxi-vfe/device/camera_cfg.h | 5 + .../video/sunxi-vfe/device/gc1004_mipi.c | 1239 +++ .../media/video/sunxi-vfe/device/gc2035.c | 4 +- .../media/video/sunxi-vfe/device/gc2235.c | 0 .../media/video/sunxi-vfe/device/gc2355.c | 1146 +++ .../media/video/sunxi-vfe/device/h22_mipi.c | 1032 +++ .../media/video/sunxi-vfe/device/hm5065.c | 45 +- .../video/sunxi-vfe/device/ov2710_mipi.c | 2 + .../media/video/sunxi-vfe/device/ov4689.c | 253 +- .../video/sunxi-vfe/device/ov4689_60fps.c | 212 +- .../media/video/sunxi-vfe/device/ov4689_sdv.c | 1923 +++++ .../media/video/sunxi-vfe/device/ov5647.c | 194 +- .../video/sunxi-vfe/device/ov8858_4lane.c | 4 + .../media/video/sunxi-vfe/device/s5k3h7.c | 181 +- .../media/video/sunxi-vfe/device/s5k4ec.c | 10 +- .../video/sunxi-vfe/device/s5k4ec_mipi.c | 7414 +++++++++-------- .../isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg.h | 844 ++ .../SENSOR_H/ar0330_mipi_isp_cfg_ST6123.h | 846 ++ .../SENSOR_H/ar0330_mipi_isp_cfg_V3S_JV372T.h | 846 ++ .../isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg.h | 845 ++ .../SENSOR_H/gc1004_mipi_isp_cfg_HK8214C.h | 847 ++ .../isp_cfg/SENSOR_H/h22_mipi_isp_cfg.h | 845 ++ .../SENSOR_H/h22_mipi_isp_cfg_HK8214C.h | 847 ++ .../isp_cfg/SENSOR_H/ov2710_mipi_isp_cfg.h | 832 ++ .../isp_cfg/SENSOR_H/ov4689_isp_cfg.h | 845 ++ .../SENSOR_H/ov4689_sdv_isp_cfg_HK8189.h | 847 ++ .../media/video/sunxi-vfe/isp_cfg/isp_cfg.c | 53 + .../media/video/sunxi-vfe/isp_cfg/isp_cfg.h | 39 + .../media/video/sunxi-vfe/lib/bsp_isp_algo.h | 84 +- .../video/sunxi-vfe/lib/isp_module_cfg.h | 3 +- .../media/video/sunxi-vfe/lib/lib_mipicsi2_v1 | Bin .../media/video/sunxi-vfe/lib/lib_mipicsi2_v2 | Bin .../drivers/media/video/sunxi-vfe/lib/libisp | Bin .../sunxi-vfe/platform/sun8iw8p1_vfe_cfg.h | 10 +- .../media/video/sunxi-vfe/test/Makefile | 4 +- .../media/video/sunxi-vfe/test/app_basic.c | 1479 +--- .../media/video/sunxi-vfe/utility/cfg_op.c | 195 +- .../media/video/sunxi-vfe/utility/cfg_op.h | 16 +- linux-3.4/drivers/media/video/sunxi-vfe/vfe.c | 391 +- 60 files changed, 19843 insertions(+), 5972 deletions(-) create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/device/gc1004_mipi.c mode change 100644 => 100755 linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/device/gc2355.c create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/device/h22_mipi.c create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_sdv.c create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_ST6123.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_V3S_JV372T.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg_HK8214C.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg_HK8214C.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov2710_mipi_isp_cfg.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_isp_cfg.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_sdv_isp_cfg_HK8189.h create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.c create mode 100755 linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.h mode change 100644 => 100755 linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 mode change 100644 => 100755 linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 mode change 100644 => 100755 linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp diff --git a/build/sun8iw7p1smp_lobo_defconfig b/build/sun8iw7p1smp_lobo_defconfig index b7f3737c..87b6bf30 100644 --- a/build/sun8iw7p1smp_lobo_defconfig +++ b/build/sun8iw7p1smp_lobo_defconfig @@ -110,7 +110,7 @@ CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 loglevel=1 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -1056,56 +1056,62 @@ CONFIG_BPF_JIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y +CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y +CONFIG_BT_HIDP=m # # Bluetooth device drivers # CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m # CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m +CONFIG_BT_LPM=m CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEVELOPER_WARNINGS=y # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_CFG80211_ALLOW_RECONNECT=y CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y # CONFIG_MAC80211_RC_PID is not set @@ -1113,16 +1119,22 @@ CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 -# CONFIG_RFKILL is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set # CONFIG_NFC is not set # diff --git a/build/sun8iw7p1smp_lobo_defconfig.old b/build/sun8iw7p1smp_lobo_defconfig.old index b7f3737c..87b6bf30 100644 --- a/build/sun8iw7p1smp_lobo_defconfig.old +++ b/build/sun8iw7p1smp_lobo_defconfig.old @@ -110,7 +110,7 @@ CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 loglevel=1 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -1056,56 +1056,62 @@ CONFIG_BPF_JIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y +CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y +CONFIG_BT_HIDP=m # # Bluetooth device drivers # CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m # CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m +CONFIG_BT_LPM=m CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEVELOPER_WARNINGS=y # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_CFG80211_ALLOW_RECONNECT=y CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y # CONFIG_MAC80211_RC_PID is not set @@ -1113,16 +1119,22 @@ CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 -# CONFIG_RFKILL is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set # CONFIG_NFC is not set # diff --git a/linux-3.4/.config.bak b/linux-3.4/.config.bak index f973480b..87b6bf30 100644 --- a/linux-3.4/.config.bak +++ b/linux-3.4/.config.bak @@ -110,7 +110,7 @@ CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 loglevel=1 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -1056,56 +1056,62 @@ CONFIG_BPF_JIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y +CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y +CONFIG_BT_HIDP=m # # Bluetooth device drivers # CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m # CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m +CONFIG_BT_LPM=m CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEVELOPER_WARNINGS=y # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_CFG80211_ALLOW_RECONNECT=y CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y # CONFIG_MAC80211_RC_PID is not set @@ -1113,16 +1119,22 @@ CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 -# CONFIG_RFKILL is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set # CONFIG_NFC is not set # @@ -2729,7 +2741,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_DEV_UIE_EMUL=y # CONFIG_RTC_DRV_TEST is not set # diff --git a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig index b7f3737c..87b6bf30 100644 --- a/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig +++ b/linux-3.4/arch/arm/configs/sun8iw7p1smp_lobo_defconfig @@ -110,7 +110,7 @@ CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y -# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_MM_OWNER=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y @@ -495,7 +495,7 @@ CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y # CONFIG_USE_OF is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_CMDLINE="rootwait ro consoleblank=0 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" +CONFIG_CMDLINE="rootwait ro consoleblank=0 loglevel=1 enforcing=0 elevator=deadline console=tty1 fsck.mode=auto fsck.repair=yes init=/init ipv6.disable=1 kernel.nohalt kernel.panic=5" # CONFIG_CMDLINE_FROM_BOOTLOADER is not set # CONFIG_CMDLINE_EXTEND is not set CONFIG_CMDLINE_FORCE=y @@ -1056,56 +1056,62 @@ CONFIG_BPF_JIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -CONFIG_BT=y -CONFIG_BT_RFCOMM=y +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y +CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y +CONFIG_BT_HIDP=m # # Bluetooth device drivers # CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTSDIO is not set -CONFIG_BT_HCIUART=y -# CONFIG_BT_HCIUART_H4 is not set -# CONFIG_BT_HCIUART_BCSP is not set -# CONFIG_BT_HCIUART_ATH3K is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_RTKH5=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m # CONFIG_BT_HCIVHCI is not set -CONFIG_BCM_BT_LPM=m +CONFIG_BT_LPM=m CONFIG_RTL_BT_LPM=m -# CONFIG_BT_MRVL is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_AF_RXRPC is not set +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEVELOPER_WARNINGS=y # CONFIG_CFG80211_REG_DEBUG is not set CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set # CONFIG_CFG80211_INTERNAL_REGDB is not set CONFIG_CFG80211_WEXT=y -# CONFIG_WIRELESS_EXT_SYSFS is not set -# CONFIG_LIB80211 is not set -# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_CFG80211_ALLOW_RECONNECT=y CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y # CONFIG_MAC80211_RC_PID is not set @@ -1113,16 +1119,22 @@ CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 -# CONFIG_RFKILL is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set -# CONFIG_CEPH_LIB is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set # CONFIG_NFC is not set # diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/Kconfig b/linux-3.4/drivers/media/video/sunxi-vfe/Kconfig index 446c7109..c4cc4861 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/Kconfig +++ b/linux-3.4/drivers/media/video/sunxi-vfe/Kconfig @@ -3,4 +3,31 @@ config CSI_VFE tristate "v4l2 driver for SUNXI" default m select VIDEOBUF_DMA_CONTIG - \ No newline at end of file + +if ARCH_SUN8IW8 + +menu "Sensor CSI" +config OV2710_MIPI + tristate "ov2710_mipi" + default n +config OV4689 + tristate "ov4689" + default n +config OV4689_60FPS + tristate "ov4689 60fps" + default n +config AR0330_MIPI + tristate "ar0330 mipi" + default n +config OV4689_SDV + tristate "ov4689 sdv" + default n +config GC1004_MIPI + tristate "gc1004_mipi" + default n +config H22_MIPI + tristate "h22_mipi" + default n +endmenu + +endif diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/Makefile b/linux-3.4/drivers/media/video/sunxi-vfe/Makefile index 9765dc14..6a4bdea8 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/Makefile +++ b/linux-3.4/drivers/media/video/sunxi-vfe/Makefile @@ -1,7 +1,14 @@ +EXTRA_LDFLAGS += --strip-debug obj-$(CONFIG_CSI_VFE) += vfe_os.o obj-$(CONFIG_CSI_VFE) += vfe_subdev.o obj-$(CONFIG_CSI_VFE) += device/ + +ifneq ($(strip $(CONFIG_ARCH_SUN8IW8)),) + +else obj-$(CONFIG_CSI_VFE) += actuator/ +endif + obj-$(CONFIG_CSI_VFE) += csi_cci/ #obj-$(CONFIG_CSI_VFE) += flash_light/ #obj-$(CONFIG_CSI_VFE) += camera_detector/ @@ -12,10 +19,11 @@ vfe_v4l2-y += csi/bsp_csi.o vfe_v4l2-y += bsp_common.o vfe_v4l2-y += config.o vfe_v4l2-y += utility/sensor_info.o +vfe_v4l2-y += isp_cfg/isp_cfg.o vfe_v4l2-y += utility/cfg_op.o vfe_v4l2-y += vfe.o vfe_v4l2-y += lib/libisp - +EXTRA_LDFLAGS += --strip-debug ifneq ($(strip $(CONFIG_ARCH_SUN9I)),) vfe_v4l2-y += lib/lib_mipicsi2_v2 else ifneq ($(strip $(CONFIG_ARCH_SUN8IW6)),) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/Makefile b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/Makefile index 9a36d9a5..1e201e15 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/Makefile +++ b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/Makefile @@ -1,4 +1,8 @@ +ifneq ($(strip $(CONFIG_ARCH_SUN8IW8)),) + +else obj-$(CONFIG_CSI_VFE) += actuator.o obj-m += ad5820_act.o obj-m += dw9714_act.o obj-m += ov8825_act.o +endif diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/ad5820_act.c b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/ad5820_act.c index 939a31bb..fa260d62 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/ad5820_act.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/ad5820_act.c @@ -38,13 +38,15 @@ static int subdev_i2c_write(struct actuator_ctrl_t *act_ctrl, unsigned short halfword, void* pt) { int ret=0; - unsigned char waddr,bdata; - waddr = (unsigned char)(halfword>>8); - bdata = (unsigned char)(0xff&halfword); - ret = cci_write_a8_d8(&act_ctrl->sdev,waddr,bdata); +// unsigned char waddr,bdata; +// waddr = (unsigned char)(halfword>>8); +// bdata = (unsigned char)(0xff&halfword); +// ret = cci_write_a8_d8(&act_ctrl->sdev,waddr,bdata); + ret = cci_write_a0_d16(&act_ctrl->sdev,halfword); if(ret < 0) act_dev_err("subdev_i2c_write write 0x%x err!\n ",halfword); - act_dev_dbg("set client->addr = [0x%x][0x%x, 0x%x]\n", halfword, waddr, bdata); +// act_dev_dbg("set client->addr = [0x%x][0x%x, 0x%x]\n", halfword, waddr, bdata); + act_dev_dbg("set value = [0x%x]\n", halfword); return ret; } diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/dw9714_act.c b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/dw9714_act.c index 80449af4..f28db564 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/actuator/dw9714_act.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/actuator/dw9714_act.c @@ -38,13 +38,17 @@ static int subdev_i2c_write(struct actuator_ctrl_t *act_ctrl, unsigned short halfword, void* pt) { int ret=0; - unsigned char waddr,bdata; - waddr = (unsigned char)(halfword>>8); - bdata = (unsigned char)(0xff&halfword); - ret = cci_write_a8_d8(&act_ctrl->sdev,waddr,bdata); +// int i; +// unsigned short value; +// unsigned char waddr,bdata; +// waddr = (unsigned char)(halfword>>8); +// bdata = (unsigned char)(0xff&halfword); +// ret = cci_write_a8_d8(&act_ctrl->sdev,waddr,bdata); + ret = cci_write_a0_d16(&act_ctrl->sdev,halfword); if(ret < 0) act_dev_err("subdev_i2c_write write 0x%x err!\n ",halfword); - act_dev_dbg("set client->addr = [0x%x][0x%x, 0x%x]\n", halfword, waddr, bdata); +// act_dev_dbg("set client->addr = [0x%x][0x%x, 0x%x]\n", halfword, waddr, bdata); + act_dev_dbg("set value = [0x%x]\n", halfword); return ret; } diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/config.c b/linux-3.4/drivers/media/video/sunxi-vfe/config.c index 6279859f..fb79ef39 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/config.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/config.c @@ -15,8 +15,8 @@ */ #include "config.h" -#include "utility/cfg_op.h" #include "platform_cfg.h" +#include "isp_cfg/isp_cfg.h" #define SIZE_OF_LSC_TBL_MOD0 7*768*2 #define SIZE_OF_LSC_TBL_MOD1 8*768*2 #define SIZE_OF_HDR_TBL 4*256*2 @@ -188,8 +188,8 @@ int fetch_sensor_list(struct sensor_config_init *sensor_cfg_ini , char *main, st { if(SensorCommon->set_param) { - SensorCommon->set_param(sensor_cfg_ini, (void *)&subkey.value->val, SensorCommon->len); - vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %d\n",main, SensorCommon->sub,subkey.value->val); + SensorCommon->set_param(sensor_cfg_ini, (void *)&subkey.value.val, SensorCommon->len); + vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %d\n",main, SensorCommon->sub,subkey.value.val); } } } @@ -203,12 +203,12 @@ int fetch_sensor_list(struct sensor_config_init *sensor_cfg_ini , char *main, st { if(SensorCommon->set_param) { - if(!strcmp(subkey.value->str, "\"\"")) + if(!strcmp(subkey.value.str, "\"\"")) { - strcpy(subkey.value->str,""); + strcpy(subkey.value.str,""); } - SensorCommon->set_param(sensor_cfg_ini, (void *)subkey.value->str, SensorCommon->len); - vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %s\n",main, SensorCommon->sub,subkey.value->str); + SensorCommon->set_param(sensor_cfg_ini, (void *)subkey.value.str, SensorCommon->len); + vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %s\n",main, SensorCommon->sub,subkey.value.str); } } } @@ -242,8 +242,8 @@ int fetch_sensor_list(struct sensor_config_init *sensor_cfg_ini , char *main, st { if(SensorDetect->set_param) { - SensorDetect->set_param(sensor_cfg_ini, (void *)&subkey.value->val, j); - vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %d\n",main, sub_name,subkey.value->val); + SensorDetect->set_param(sensor_cfg_ini, (void *)&subkey.value.val, j); + vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %d\n",main, sub_name,subkey.value.val); } } } @@ -257,12 +257,12 @@ int fetch_sensor_list(struct sensor_config_init *sensor_cfg_ini , char *main, st { if(SensorDetect->set_param) { - if(!strcmp(subkey.value->str, "\"\"")) + if(!strcmp(subkey.value.str, "\"\"")) { - strcpy(subkey.value->str,""); + strcpy(subkey.value.str,""); } - SensorDetect->set_param(sensor_cfg_ini, (void *)subkey.value->str, j); - vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %s\n",main, sub_name,subkey.value->str); + SensorDetect->set_param(sensor_cfg_ini, (void *)subkey.value.str, j); + vfe_dbg(0,"fetch sensor cfg ini: %s->%s = %s\n",main, sub_name,subkey.value.str); } } } @@ -431,7 +431,11 @@ int fetch_config(struct vfe_dev *dev) if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { vfe_dbg(0,"fetch vip_dev%d_stby_mode from sys_config failed\n", i); } else { +#ifdef CONFIG_ARCH_SUN8IW8P1 + dev->ccm_cfg[i]->power.stby_mode = POWER_OFF; +#else dev->ccm_cfg[i]->power.stby_mode = val.val; +#endif } /* fetch flip issue */ @@ -827,8 +831,7 @@ struct isp_init_config isp_init_def_cfg = { .define_ae_table = 0, .ae_max_lv = 1800, .fno = 280, - .ae_lum_low_th = 125, - .ae_lum_high_th = 135, + .ae_hist_mod_en = 0, .ae_window_overexp_weigth = 16, .ae_hist_overexp_weight = 32, .ae_video_speed = 4, @@ -844,22 +847,20 @@ struct isp_init_config isp_init_def_cfg = { /*isp awb param */ .awb_interval = 4, + .awb_speed = 8, //.awb_mode_select = 1, .awb_color_temper_low = 2500, .awb_color_temper_high = 7500, .awb_skin_color_num = 0, - //.r_gain_2900k = 385, - //.b_gain_2900k = 140, - //.awb_coeff = {31,135}, - //.awb_tolerance = 10, - /*isp af param */ .vcm_min_code = 0, .vcm_max_code = 650, - //.color_matrix_inv = - //{ - // .matrix = {{256,0,0},{0,256,0},{0,0,256}}, - // .offset = {0, 0, 0}, - //}, + .af_interval_time = 100, + .af_speed_ind = 4, //0~5 + .af_auto_fine_en = 1, + .af_single_fine_en = 0, + .af_fine_step = 24, + .af_move_cnt = 4, + .af_still_cnt = 1, }, .isp_tunning_settings = { @@ -909,6 +910,8 @@ struct isp_init_config isp_init_def_cfg = { }, }; + + void set_isp_test_mode(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_test_settings.isp_test_mode = *(int *)value; } void set_isp_test_exptime(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_test_settings.isp_test_exptime = *(int *)value;} void set_exp_line_start(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_test_settings.exp_line_start = *(int *)value; } @@ -957,8 +960,7 @@ void set_ae_table_video_length(struct isp_init_config *isp_ini_cfg, void *value, void set_ae_max_lv(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_max_lv = *(int *)value; } void set_fno(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.fno = *(int *)value; } -void set_ae_lum_low_th(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_lum_low_th = *(int *)value; } -void set_ae_lum_high_th(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_lum_high_th = *(int *)value; } +void set_ae_hist_mod_en(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_hist_mod_en = *(int *)value; } void set_ae_window_overexp_weigth(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_window_overexp_weigth = *(int *)value; } void set_ae_hist_overexp_weight(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_hist_overexp_weight = *(int *)value; } void set_ae_video_speed(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.ae_video_speed = *(int *)value; } @@ -974,6 +976,8 @@ void set_adaptive_frame_rate(struct isp_init_config *isp_ini_cfg, void *value, i void set_force_frame_rate(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.force_frame_rate = *(int *)value; } void set_awb_interval(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.awb_interval = *(int *)value; } +void set_awb_speed(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.awb_speed = *(int *)value; } + //void set_awb_mode_select(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.awb_mode_select = *(int *)value; } //void set_awb_tolerance(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.awb_tolerance = *(int *)value; } @@ -983,6 +987,18 @@ void set_awb_color_temper_high(struct isp_init_config *isp_ini_cfg, void *value, //void set_b_gain_2900k(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.b_gain_2900k = *(int *)value; } void set_vcm_min_code(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.vcm_min_code = *(int *)value; } void set_vcm_max_code(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.vcm_max_code = *(int *)value; } +void set_af_interval_time(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_interval_time = *(int *)value; } + +void set_af_speed_ind(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_speed_ind = *(int *)value; } +void set_af_auto_fine_en(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_auto_fine_en = *(int *)value; } +void set_af_single_fine_en(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_single_fine_en = *(int *)value; } +void set_af_fine_step(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_fine_step = *(int *)value; } + + +void set_af_move_cnt(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_move_cnt = *(int *)value; } +void set_af_still_cnt(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_3a_settings.af_still_cnt = *(int *)value; } + + void set_flash_gain(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_tunning_settings.flash_gain = *(int *)value; } void set_flash_delay_frame(struct isp_init_config *isp_ini_cfg, void *value, int len) { isp_ini_cfg->isp_tunning_settings.flash_delay_frame = *(int *)value; } @@ -1041,7 +1057,7 @@ void set_awb_skin_color_info(struct isp_init_config *isp_ini_cfg, void *value, i } } -void set_awb_perset_gain(struct isp_init_config *isp_ini_cfg, void *value, int len) +void set_awb_preset_gain(struct isp_init_config *isp_ini_cfg, void *value, int len) { int i,*tmp; tmp = (int *)value; @@ -1335,8 +1351,7 @@ static struct IspParamAttribute Isp3aParam[] = { "isp_ae_cfg", "ae_table_video_", 28 , set_ae_table_video ,}, { "isp_ae_cfg", "ae_win_weight_", 64 , set_ae_win_weight ,}, - { "isp_ae_cfg", "ae_lum_low_th", 1 , set_ae_lum_low_th ,}, - { "isp_ae_cfg", "ae_lum_high_th", 1 , set_ae_lum_high_th ,}, + { "isp_ae_cfg", "ae_hist_mod_en", 1 , set_ae_hist_mod_en ,}, { "isp_ae_cfg", "ae_window_overexp_weigth", 1 , set_ae_window_overexp_weigth ,}, { "isp_ae_cfg", "ae_hist_overexp_weight", 1 , set_ae_hist_overexp_weight ,}, { "isp_ae_cfg", "ae_video_speed", 1 , set_ae_video_speed ,}, @@ -1353,18 +1368,11 @@ static struct IspParamAttribute Isp3aParam[] = { "isp_ae_cfg", "force_frame_rate", 1 , set_force_frame_rate ,}, { "isp_awb_cfg", "awb_interval", 1 , set_awb_interval ,}, + { "isp_awb_cfg", "awb_speed", 1 , set_awb_speed ,}, - //{ "isp_awb_cfg", "awb_mode_select", 1 , set_awb_mode_select ,}, - //{ "isp_awb_cfg", "awb_tolerance", 1 , set_awb_tolerance ,}, - //{ "isp_awb_cfg", "awb_light_param_", 21 , set_awb_light_param ,}, - //{ "isp_awb_cfg", "awb_coeff_", 30 , set_awb_coeff ,}, - - //{ "isp_awb_cfg", "matrix_inv_", 12 , set_color_matrix_inv ,}, { "isp_awb_cfg", "awb_color_temper_low", 1 , set_awb_color_temper_low ,}, { "isp_awb_cfg", "awb_color_temper_high", 1 , set_awb_color_temper_high ,}, -// { "isp_awb_cfg", "r_gain_2900k", 1 , set_r_gain_2900k ,}, -// { "isp_awb_cfg", "b_gain_2900k", 1 , set_b_gain_2900k ,}, { "isp_awb_cfg", "awb_light_num", 1 , set_awb_light_num ,}, { "isp_awb_cfg", "awb_ext_light_num", 1 , set_awb_ext_light_num ,}, @@ -1372,19 +1380,29 @@ static struct IspParamAttribute Isp3aParam[] = { "isp_awb_cfg", "awb_light_info_", 100 , set_awb_light_info ,}, { "isp_awb_cfg", "awb_ext_light_info_", 60 , set_awb_ext_light_info ,}, { "isp_awb_cfg", "awb_skin_color_info_", 40 , set_awb_skin_color_info ,}, - { "isp_awb_cfg", "awb_perset_gain_", 22 , set_awb_perset_gain ,}, + { "isp_awb_cfg", "awb_perset_gain_", 22 , set_awb_preset_gain ,}, { "isp_af_cfg", "vcm_min_code", 1 , set_vcm_min_code ,}, { "isp_af_cfg", "vcm_max_code", 1 , set_vcm_max_code ,}, + { "isp_af_cfg", "af_interval_time", 1 , set_af_interval_time ,}, + + { "isp_af_cfg", "af_speed_ind", 1 , set_af_speed_ind ,}, + { "isp_af_cfg", "af_auto_fine_en", 1 , set_af_auto_fine_en ,}, + { "isp_af_cfg", "af_single_fine_en", 1 , set_af_single_fine_en ,}, + { "isp_af_cfg", "af_fine_step", 1 , set_af_fine_step ,}, + + + { "isp_af_cfg", "af_move_cnt", 1 , set_af_move_cnt ,}, + { "isp_af_cfg", "af_still_cnt", 1 , set_af_still_cnt ,}, }; static struct IspParamAttribute IspIsoParam[] = { - { "isp_iso_100_cfg" , "iso_param_", 41, set_isp_iso_100_cfg ,}, - { "isp_iso_200_cfg" , "iso_param_", 41, set_isp_iso_200_cfg ,}, - { "isp_iso_400_cfg" , "iso_param_", 41, set_isp_iso_400_cfg ,}, - { "isp_iso_800_cfg" , "iso_param_", 41 , set_isp_iso_800_cfg ,}, - { "isp_iso_1600_cfg" , "iso_param_", 41 , set_isp_iso_1600_cfg,}, - { "isp_iso_3200_cfg" , "iso_param_", 41 , set_isp_iso_3200_cfg,}, + { "isp_iso_100_cfg" , "iso_param_", 48, set_isp_iso_100_cfg ,}, + { "isp_iso_200_cfg" , "iso_param_", 48, set_isp_iso_200_cfg ,}, + { "isp_iso_400_cfg" , "iso_param_", 48, set_isp_iso_400_cfg ,}, + { "isp_iso_800_cfg" , "iso_param_", 48, set_isp_iso_800_cfg ,}, + { "isp_iso_1600_cfg" , "iso_param_", 48, set_isp_iso_1600_cfg,}, + { "isp_iso_3200_cfg" , "iso_param_", 48, set_isp_iso_3200_cfg,}, }; static struct IspParamAttribute IspTuningParam[] = { @@ -1452,8 +1470,8 @@ int fetch_isp_cfg(struct isp_init_config *isp_ini_cfg, struct cfg_section *cfg_s { if(param->set_param) { - param->set_param(isp_ini_cfg, (void *)&subkey.value->val, param->len); - vfe_dbg(0,"fetch_isp_cfg_single: %s->%s = %d\n",param->main, param->sub,subkey.value->val); + param->set_param(isp_ini_cfg, (void *)&subkey.value.val, param->len); + vfe_dbg(0,"fetch_isp_cfg_single: %s->%s = %d\n",param->main, param->sub,subkey.value.val); } } } @@ -1472,19 +1490,21 @@ int fetch_isp_cfg(struct isp_init_config *isp_ini_cfg, struct cfg_section *cfg_s param->len = 10 * isp_ini_cfg->isp_3a_settings.awb_skin_color_num; } - array_value = (int*)kzalloc(param->len*sizeof(int),GFP_KERNEL); + array_value = (int*)vmalloc(param->len*sizeof(int)); + memset(array_value, 0, param->len*sizeof(int)); for(j = 0;jlen;j++) { sprintf(sub_name, "%s%d",param->sub, j); if (CFG_ITEM_VALUE_TYPE_INT != cfg_get_one_subkey(cfg_section,param->main,sub_name,&subkey)) { - vfe_warn("fetch %s from %s failed, set %s = 0!\n",sub_name,param->main, sub_name); + if(strcmp(param->sub, "iso_param_")) + vfe_warn("fetch %s from %s failed, set %s = 0!\n",sub_name,param->main, sub_name); array_value[j] = 0; } else { - array_value[j] = subkey.value->val; - vfe_dbg(0,"fetch_isp_cfg_array: %s->%s = %d\n",param->main, sub_name, subkey.value->val); + array_value[j] = subkey.value.val; + vfe_dbg(0,"fetch_isp_cfg_array: %s->%s = %d\n",param->main, sub_name, subkey.value.val); } } if(param->set_param) @@ -1493,7 +1513,7 @@ int fetch_isp_cfg(struct isp_init_config *isp_ini_cfg, struct cfg_section *cfg_s } if(array_value) - kfree(array_value); + vfree(array_value); } } vfe_dbg(0,"fetch isp_cfg done!\n"); @@ -1580,23 +1600,60 @@ int fetch_isp_tbl(struct isp_init_config *isp_ini_cfg, char* tbl_patch) return ret; } -int read_ini_info(struct vfe_dev *dev,int isp_id) +int match_isp_cfg(struct vfe_dev *dev,int isp_id) +{ + int ret; + struct isp_cfg_item isp_cfg_tmp; + struct isp_init_config *isp_ini_cfg = &dev->isp_gen_set[isp_id].isp_ini_cfg; + ret = get_isp_cfg(dev->ccm_cfg[isp_id]->isp_cfg_name,&isp_cfg_tmp); + if(ret < 0) + { + return -1; + } + isp_ini_cfg->isp_3a_settings = *isp_cfg_tmp.isp_cfg->isp_3a_settings; + isp_ini_cfg->isp_test_settings = *isp_cfg_tmp.isp_cfg->isp_test_settings; + isp_ini_cfg->isp_tunning_settings = *isp_cfg_tmp.isp_cfg->isp_tunning_settings; + isp_ini_cfg->isp_iso_settings = *isp_cfg_tmp.isp_cfg->isp_iso_settings; + memcpy(isp_ini_cfg->isp_tunning_settings.gamma_tbl, isp_ini_cfg->isp_tunning_settings.gamma_tbl_ini, ISP_GAMMA_MEM_SIZE); + memcpy(isp_ini_cfg->isp_tunning_settings.gamma_tbl_post, isp_ini_cfg->isp_tunning_settings.gamma_tbl_ini, ISP_GAMMA_MEM_SIZE); + return 0; +} +int read_ini_info(struct vfe_dev *dev,int isp_id, char *main_path) { int i, ret = 0; char isp_cfg_path[128],isp_tbl_path[128],file_name_path[128]; struct cfg_section *cfg_section; + struct file* fp; - vfe_print("read ini start\n"); if(dev->ccm_cfg[isp_id] != NULL && strcmp(dev->ccm_cfg[isp_id]->isp_cfg_name, "") != 0) { - sprintf(isp_cfg_path, "/system/etc/hawkview/%s/", dev->ccm_cfg[isp_id]->isp_cfg_name); - sprintf(isp_tbl_path, "/system/etc/hawkview/%s/bin/", dev->ccm_cfg[isp_id]->isp_cfg_name); + sprintf(isp_cfg_path, "%s%s/",main_path, dev->ccm_cfg[isp_id]->isp_cfg_name); + sprintf(isp_tbl_path, "%s%s/bin/", main_path, dev->ccm_cfg[isp_id]->isp_cfg_name); + + //sprintf(isp_cfg_path, "/system/etc/hawkview/%s/", dev->ccm_cfg[isp_id]->isp_cfg_name); + //sprintf(isp_tbl_path, "/system/etc/hawkview/%s/bin/", dev->ccm_cfg[isp_id]->isp_cfg_name); + //sprintf(isp_cfg_path, "/mnt/extsd/hawkview/%s/", dev->ccm_cfg[isp_id]->isp_cfg_name); + //sprintf(isp_tbl_path, "/mnt/extsd/hawkview/%s/bin/", dev->ccm_cfg[isp_id]->isp_cfg_name); } else { sprintf(isp_cfg_path, "/system/etc/hawkview/camera.ini"); sprintf(isp_tbl_path, "/system/etc/hawkview/bin/"); } + + + sprintf(file_name_path,"%s%s",isp_cfg_path,FileAttr[0].file_name); + fp = filp_open(isp_cfg_path,O_RDONLY,0); + if(IS_ERR(fp)) { + vfe_print("Check open %s failed!\nMatch isp cfg start!\n", file_name_path); + if(match_isp_cfg(dev,isp_id) == 0) + { + vfe_print("Match isp cfg ok\n"); + goto read_ini_info_end; + } + } + vfe_print("read ini start\n"); + dev->isp_gen_set[isp_id].isp_ini_cfg = isp_init_def_cfg; for(i=0; i< ARRAY_SIZE(FileAttr); i++) { diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/config.h b/linux-3.4/drivers/media/video/sunxi-vfe/config.h index 67179642..b8f3db4f 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/config.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/config.h @@ -9,8 +9,9 @@ #define __CONFIG__H__ #include "vfe.h" +#include "utility/cfg_op.h" int fetch_config(struct vfe_dev *dev); -int read_ini_info(struct vfe_dev *dev,int isp_id); +int read_ini_info(struct vfe_dev *dev,int isp_id, char *main_path); #endif //__CONFIG__H__ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/Makefile b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/Makefile index 1b8199be..e6e19568 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/Makefile +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_CSI_VFE) += cci.o - +EXTRA_LDFLAGS += --strip-debug cci-objs := csi_cci_reg.o bsp_cci.o cci_helper.o cci_platform_drv.o diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.c b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.c index cf3b6ea0..c6aa44dd 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.c @@ -19,12 +19,22 @@ #include "../platform_cfg.h" #include #include +#include +#include #define MAX_CCI_DEVICE 2 wait_queue_head_t wait[MAX_CCI_DEVICE]; static int status_err_flag[MAX_CCI_DEVICE] = {0}; +struct mutex cci_mutex[MAX_CCI_DEVICE]; +struct semaphore cci_sema[MAX_CCI_DEVICE]; +int cci_cnt_done = 0; +int cci_cnt_irq = 0; int bsp_csi_cci_set_base_addr(unsigned int sel, unsigned int addr) { + cci_cnt_done = 0; + cci_cnt_irq = 0; init_waitqueue_head(&wait[sel]); + mutex_init(&cci_mutex[sel]); + sema_init(&cci_sema[sel],1); return csi_cci_set_base_addr(sel, addr); } @@ -72,7 +82,7 @@ void bsp_csi_cci_init(unsigned int sel) csi_cci_reset(sel); csi_cci_enable(sel); - cci_cal_div(400*1000, div_coef); + cci_cal_div(300*1000, div_coef); csi_cci_set_clk_div(sel, div_coef); csi_cci_set_pkt_interval(sel, 16); csi_cci_set_ack_timeout(sel, 16); @@ -153,8 +163,16 @@ void bsp_cci_tx_data_rb(unsigned int sel, struct cci_msg *msg) } csi_cci_fifo_pt_reset(sel); } -int bsp_cci_tx_start_wait_done(unsigned int sel, struct cci_msg *msg) +static void bsp_cci_error_process(unsigned int sel) +{ + cci_int_clear_status(sel, CCI_INT_ERROR); + bsp_cci_bus_error_process(sel); + bsp_csi_cci_exit(sel); + bsp_csi_cci_init_helper(sel); +} +static int bsp_cci_tx_start_wait_done_unlocked(unsigned int sel, struct cci_msg *msg) { +#ifdef CCI_IRQ int ret = 0; unsigned long timeout = 0; bsp_cci_tx_start(sel, msg); @@ -164,20 +182,66 @@ int bsp_cci_tx_start_wait_done(unsigned int sel, struct cci_msg *msg) #else timeout = wait_event_timeout(wait[sel], csi_cci_get_trans_done(sel) == 0, HZ); //cci_print_info(sel); - //printk("timeout = %ld \n",timeout); if (timeout == 0) { - printk("[VFE CCI_%d ERR] timeout error at addr_8bit = %x, wr_flag = %d\n", sel, msg->bus_fmt.saddr_7bit<<1,msg->bus_fmt.wr_flag); + printk("[VFE CCI_%d ERR] timeout error at addr_8bit = %x, wr_flag = %d, val = %x\n", sel,msg->bus_fmt.saddr_7bit<<1,msg->bus_fmt.wr_flag, *(int *)msg->pkt_buf); + cci_cnt_done--; ret = -1; } #endif + //printk("cci_cnt_done = %d, cci_cnt_irq = %d\n",cci_cnt_done, cci_cnt_irq); if(1 == status_err_flag[sel]) { + printk("[VFE CCI_%d ERR] Status error at addr_8bit = %x, wr_flag = %d, val = %x\n", sel, msg->bus_fmt.saddr_7bit<<1,msg->bus_fmt.wr_flag, *(int *)msg->pkt_buf); + ret = -1; + } + if(msg->bus_fmt.wr_flag == 1) + bsp_cci_tx_data_rb(sel, msg); + return ret; +#else + struct cci_int_status status; + int ret = 0; + bsp_cci_tx_start(sel, msg); + usleep_range(100,120); + while(1) + { + if(csi_cci_get_trans_done(sel) == 0) + { + break; + } + else + { + usleep_range(80,100); + } + }; + cci_int_get_status(sel, &status); + if(status.error) { + cci_int_clear_status(sel, CCI_INT_ERROR); printk("[VFE CCI_%d ERR] Status error at addr_8bit = %x, wr_flag = %d\n", sel, msg->bus_fmt.saddr_7bit<<1,msg->bus_fmt.wr_flag); + bsp_cci_bus_error_process(sel); + bsp_csi_cci_exit(sel); + bsp_csi_cci_init_helper(sel); ret = -1; } + if(status.complete) + cci_int_clear_status(sel, CCI_INT_FINISH); if(msg->bus_fmt.wr_flag == 1) bsp_cci_tx_data_rb(sel, msg); return ret; +#endif +} + +int bsp_cci_tx_start_wait_done(unsigned int sel, struct cci_msg *msg) +{ + int ret = -1; + mutex_lock(&cci_mutex[sel]); + if(down_trylock(&cci_sema[sel])){ + printk("down_trylock fail!!!!!!!!!!!!!\n"); + return -1; + } + ret = bsp_cci_tx_start_wait_done_unlocked(sel,msg); + up(&cci_sema[sel]); + mutex_unlock(&cci_mutex[sel]); + return ret; } void bsp_cci_int_enable(unsigned int sel, enum cci_int_sel interrupt) @@ -209,14 +273,10 @@ int bsp_cci_irq_process(unsigned int sel) { struct cci_int_status status; unsigned int ret = 0; - + cci_cnt_irq++; cci_int_get_status(sel, &status); if(status.error) { - cci_int_clear_status(sel, CCI_INT_ERROR); - //cci_print_info(sel); - bsp_cci_bus_error_process(sel); - bsp_csi_cci_exit(sel); - bsp_csi_cci_init_helper(sel); + bsp_cci_error_process(sel); status_err_flag[sel] = 1; ret = -1; } diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.h b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.h index 08468c0d..b8c22640 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/bsp_cci.h @@ -8,7 +8,7 @@ #define __BSP_CCI__H__ #include "csi_cci_reg.h" - +#define CCI_IRQ struct cci_tx_mode { struct cci_tx_buf tx_buf_mode; diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.c b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.c index 42732022..afda6c5b 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.c @@ -688,6 +688,74 @@ int cci_write_a16_d16(struct v4l2_subdev *sd, unsigned short addr, EXPORT_SYMBOL_GPL(cci_write_a16_d16); +int cci_read_a0_d16(struct v4l2_subdev *sd, unsigned short *value) +{ +#ifdef USE_SPECIFIC_CCI + struct cci_driver *cci_drv; + cci_drv = v4l2_get_subdevdata(sd); + return cci_rd_0_16(cci_drv->cci_id, value, cci_drv->cci_saddr); +#else + + struct i2c_msg msg; + unsigned char data[2]; + int ret; + struct i2c_client *client = v4l2_get_subdevdata(sd); + + data[0] = 0xee; + data[1] = 0xee; + + msg.addr = client->addr; + msg.flags = 1; + msg.len = 2; + msg.buf = &data[0]; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret >= 0) { + *value = data[0]*256 + data[1]; + ret = 0; + } else { + cci_err("%s error! slave = 0x%x, value = 0x%4x\n ",__func__, client->addr, *value); + } + return ret; +#endif +} + +EXPORT_SYMBOL_GPL(cci_read_a0_d16); + +int cci_write_a0_d16(struct v4l2_subdev *sd, unsigned short value) +{ +#ifdef USE_SPECIFIC_CCI + struct cci_driver *cci_drv; + cci_drv = v4l2_get_subdevdata(sd); + return cci_wr_0_16(cci_drv->cci_id, value, cci_drv->cci_saddr); +#else + + struct i2c_msg msg; + unsigned char data[2]; + int ret; + struct i2c_client *client = v4l2_get_subdevdata(sd); + + data[0] = (value&0xff00)>>8; + data[1] = (value&0x00ff); + + msg.addr = client->addr; + msg.flags = 0; + msg.len = 2; + msg.buf = data; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret >= 0) { + ret = 0; + } else { + cci_err("%s error! slave = 0x%x, value = 0x%4x\n ",__func__, client->addr,value); + } + return ret; +#endif +} + +EXPORT_SYMBOL_GPL(cci_write_a0_d16); + + int cci_write_a16_d8_continuous_helper(struct v4l2_subdev *sd, unsigned short addr, unsigned char *vals , uint size) { #ifdef USE_SPECIFIC_CCI @@ -747,6 +815,10 @@ int cci_write(struct v4l2_subdev *sd, unsigned short addr, unsigned short value, { return cci_write_a16_d16(sd, addr, value); } + else if (0 == addr_width && 16 == data_width) + { + return cci_write_a0_d16(sd, value); + } else { cci_err("%s error! addr_width = %d , data_width = %d!\n ",__func__, addr_width, data_width); @@ -773,6 +845,10 @@ int cci_read(struct v4l2_subdev *sd, unsigned short addr, unsigned short *value, { return cci_read_a16_d16(sd, addr, value); } + else if (0 == addr_width && 16 == data_width) + { + return cci_read_a0_d16(sd, value); + } else { cci_err("%s error! addr_width = %d , data_width = %d!\n ",__func__, addr_width, data_width); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.h b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.h index 07c174a5..fff5643a 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_helper.h @@ -37,7 +37,7 @@ struct cci_driver int data_width; int read_flag; short read_value; - + struct mutex cci_mutex; //int (*probe)(struct i2c_client *, const struct i2c_device_id *); //int (*remove)(struct i2c_client *); struct list_head cci_list; @@ -81,6 +81,8 @@ extern int cci_read_a16_d8(struct v4l2_subdev *sd, unsigned short addr,unsigned extern int cci_write_a16_d8(struct v4l2_subdev *sd, unsigned short addr,unsigned char value); extern int cci_read_a16_d16(struct v4l2_subdev *sd, unsigned short addr,unsigned short *value); extern int cci_write_a16_d16(struct v4l2_subdev *sd, unsigned short addr,unsigned short value); +extern int cci_read_a0_d16(struct v4l2_subdev *sd, unsigned short *value); +extern int cci_write_a0_d16(struct v4l2_subdev *sd, unsigned short value); extern int cci_write_a16_d8_continuous_helper(struct v4l2_subdev *sd, unsigned short addr, unsigned char *vals , uint size); extern int cci_read(struct v4l2_subdev *sd, unsigned short addr, unsigned short *value, int addr_width, int data_width); extern int cci_write(struct v4l2_subdev *sd, unsigned short addr, unsigned short value, int addr_width, int data_width); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_platform_drv.c b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_platform_drv.c index de58b281..9fc1a4dd 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_platform_drv.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/csi_cci/cci_platform_drv.c @@ -31,7 +31,7 @@ static void cci_release(struct device *dev) vfe_print("cci_device_release\n"); }; - +#ifdef CCI_IRQ static irqreturn_t cci_irq_handler(int this_irq, void * dev) { unsigned long flags = 0; @@ -41,6 +41,7 @@ static irqreturn_t cci_irq_handler(int this_irq, void * dev) spin_unlock_irqrestore(&cci->slock, flags); return IRQ_HANDLED; } +#endif static int __devinit cci_probe(struct platform_device *pdev) { @@ -80,12 +81,13 @@ static int __devinit cci_probe(struct platform_device *pdev) ret = -EIO; goto eremap; } - +#ifdef CCI_IRQ ret = request_irq(irq, cci_irq_handler, IRQF_DISABLED, CCI_MODULE_NAME, cci); if (ret) { vfe_err("[cci_%d] requeset irq failed!\n", cci->cci_sel); goto ereqirq; } +#endif #if defined (CONFIG_ARCH_SUN9IW1P1) ret = bsp_csi_cci_set_base_addr(cci->cci_sel, (unsigned int)cci->base); if(ret < 0) @@ -101,13 +103,13 @@ static int __devinit cci_probe(struct platform_device *pdev) #endif platform_set_drvdata(pdev, cci); vfe_print("cci probe end cci_sel = %d!\n",pdata->cci_sel); - return 0; - ehwinit: +#ifdef CCI_IRQ free_irq(irq, cci); + ereqirq: +#endif -ereqirq: iounmap(cci->base); eremap: @@ -124,7 +126,9 @@ static int __devexit cci_remove(struct platform_device *pdev) struct cci_dev *cci = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); +#ifdef CCI_IRQ free_irq(cci->irq, cci); +#endif if(cci->base) iounmap(cci->base); kfree(cci); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/Makefile b/linux-3.4/drivers/media/video/sunxi-vfe/device/Makefile index cea59f83..3799fb1d 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/Makefile +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/Makefile @@ -1,3 +1,15 @@ +EXTRA_LDFLAGS += --strip-debug +ifneq ($(strip $(CONFIG_ARCH_SUN8IW8)),) + +obj-$(CONFIG_OV2710_MIPI) += ov2710_mipi.o +obj-$(CONFIG_OV4689) += ov4689.o +obj-$(CONFIG_OV4689_60FPS) += ov4689_60fps.o +obj-$(CONFIG_AR0330_MIPI) += ar0330_mipi.o +obj-$(CONFIG_OV4689_SDV) += ov4689_sdv.o +obj-$(CONFIG_GC1004_MIPI) += gc1004_mipi.o +obj-$(CONFIG_H22_MIPI) += h22_mipi.o + +else obj-m += ov5640.o obj-m += ov2640.o obj-m += ov7736.o @@ -40,4 +52,7 @@ obj-m += imx214.o obj-m += ov8858_4lane.o obj-m += sp5409.o obj-m += s5k5e2yx.o -obj-m += ov2710_mipi.o \ No newline at end of file +obj-m += ov2710_mipi.o + +endif + diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330.c index 789d00d3..2182daac 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330.c @@ -1008,138 +1008,147 @@ static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) { - struct sensor_info *info = to_state(sd); - unsigned short tmp_gain = 0; - //gain_val = gain_val >> 4; - if (gain_val < 16) - gain_val = 16; - //if(info->gain == gain_val) - - if (16<= gain_val*100 && gain_val*100 < (103*16) ) - sensor_write(sd,0x3060,0x0000); - else if ((103*16) <= gain_val*100 && gain_val*100 < (107*16)) - sensor_write(sd,0x3060,0x0001); - else if ((107*16) <= gain_val*100 && gain_val*100 < (110*16)) - sensor_write(sd,0x3060,0x0002); - else if ((110*16) <= gain_val*100 && gain_val*100 < (114*16)) - sensor_write(sd,0x3060,0x0003); - else if ((114*16) <= gain_val*100 && gain_val*100 < (119*16)) - sensor_write(sd,0x3060,0x0004); - else if ((119*16) <= gain_val*100 && gain_val*100 < (123*16)) - sensor_write(sd,0x3060,0x0005); - else if ((123*16) <= gain_val*100 && gain_val*100 < (128*16)) - sensor_write(sd,0x3060,0x0006); - else if ((128*16) <= gain_val*100 && gain_val*100 < (133*16)) - sensor_write(sd,0x3060,0x0007); - else if ((133*16) <= gain_val*100 && gain_val*100 < (139*16)) - sensor_write(sd,0x3060,0x0008); - else if ((139*16) <= gain_val*100 && gain_val*100 < (145*16)) - sensor_write(sd,0x3060,0x0009); - else if ((145*16) <= gain_val*100 && gain_val*100 < (152*16)) - sensor_write(sd,0x3060,0x000a); - else if ((152*16) <= gain_val*100 && gain_val*100 < (160*16)) - sensor_write(sd,0x3060,0x000b); - else if ((160*16) <= gain_val*100 && gain_val*100 < (168*16)) - sensor_write(sd,0x3060,0x000c); - else if ((168*16) <= gain_val*100 && gain_val*100 < (178*16)) - sensor_write(sd,0x3060,0x000d); - else if ((178*16) <= gain_val*100 && gain_val*100 < (188*16)) - sensor_write(sd,0x3060,0x000e); - else if ((188*16) <= gain_val*100 && gain_val*100 < (200*16)) - sensor_write(sd,0x3060,0x000f); - else if (200*16 <= gain_val*100 && gain_val*100 < (213*16)) - sensor_write(sd,0x3060,0x0010); - else if ((213*16) <= gain_val*100 && gain_val*100 < (229*16)) - sensor_write(sd,0x3060,0x0012); - else if ((229*16) <= gain_val*100 && gain_val*100 < (246*16)) - sensor_write(sd,0x3060,0x0014); - else if ((246*16) <= gain_val*100 && gain_val*100 < (267*16)) - sensor_write(sd,0x3060,0x0016); - else if ((267*16) <= gain_val*100 && gain_val*100 < (291*16)) - sensor_write(sd,0x3060,0x0018); - else if ((291*16) <= gain_val*100 && gain_val*100 < (320*16)) - sensor_write(sd,0x3060,0x001a); - /* - else if ((320*16) <= gain_val*100 && gain_val*100 < (356*16)) - sensor_write(sd,0x3060,0x001c); - else if ((356*16) <= gain_val*100 && gain_val*100 < (400*16)) - sensor_write(sd,0x3060,0x001e); - else if ((400*16) <= gain_val*100 && gain_val*100 < (457*16)) - sensor_write(sd,0x3060,0x0020); - else if ((457*16) <= gain_val*100 && gain_val*100 < (533*16)) - sensor_write(sd,0x3060,0x0024); - else if ((533*16) <= gain_val*100 && gain_val*100 < (640*16)) - sensor_write(sd,0x3060,0x0028); - else if ((640*16) <= gain_val*100 && gain_val*100 < (800*16)) - sensor_write(sd,0x3060,0x002c); - else if ((800*16) >= gain_val*100 ) - sensor_write(sd,0x3060,0x0030); - if((1*16 <= gain_val) && (gain_val< 2*16)) - sensor_write(sd,0x305e,0x0085); - else if ((2*16 <= gain_val) && (gain_val < 4*16)) - sensor_write(sd,0x305e,0x0088); - else if ((4*16 <= gain_val)&&(gain_val < 8*16)) - sensor_write(sd,0x305e,0x0092); - else if (8*16 <= gain_val) - sensor_write(sd,0x305e,0x00a0); - */ - else if ((320*16) <= gain_val*100 && gain_val*100 < (800*16)) - { - tmp_gain = (2449700 + gain_val*564520 - gain_val*gain_val*1646)/1000000; - sensor_write(sd,0x3060,tmp_gain); - } - else if ((800*16) <= gain_val*100 ) - sensor_write(sd,0x3060,0x0030); - - //Digit Gain - if((1*16 <= gain_val) && (gain_val<= 8*16)) - sensor_write(sd,0x305e, 128); - else if ((8*16 < gain_val) && (gain_val <= 10*16)) - sensor_write(sd,0x305e, gain_val); - - sensor_read(sd,0x3060,&tmp_gain); - - // sensor_write(sd,0x3060,0x0030); - //printk("sensor_set_gain = %d,readout gain =0x%x\n", gain_val,tmp_gain); - info->gain = gain_val; - return 0; + struct sensor_info *info = to_state(sd); + unsigned short dig_gain = 0x80; // 1 times digital gain + + if (gain_val < 16) + gain_val = 16; + + if (16<= gain_val*100 && gain_val*100 < (103*16) ) + sensor_write(sd,0x3060,0x0000); + else if ((103*16) <= gain_val*100 && gain_val*100 < (107*16)) + sensor_write(sd,0x3060,0x0001); + else if ((107*16) <= gain_val*100 && gain_val*100 < (110*16)) + sensor_write(sd,0x3060,0x0002); + else if ((110*16) <= gain_val*100 && gain_val*100 < (114*16)) + sensor_write(sd,0x3060,0x0003); + else if ((114*16) <= gain_val*100 && gain_val*100 < (119*16)) + sensor_write(sd,0x3060,0x0004); + else if ((119*16) <= gain_val*100 && gain_val*100 < (123*16)) + sensor_write(sd,0x3060,0x0005); + else if ((123*16) <= gain_val*100 && gain_val*100 < (128*16)) + sensor_write(sd,0x3060,0x0006); + else if ((128*16) <= gain_val*100 && gain_val*100 < (133*16)) + sensor_write(sd,0x3060,0x0007); + else if ((133*16) <= gain_val*100 && gain_val*100 < (139*16)) + sensor_write(sd,0x3060,0x0008); + else if ((139*16) <= gain_val*100 && gain_val*100 < (145*16)) + sensor_write(sd,0x3060,0x0009); + else if ((145*16) <= gain_val*100 && gain_val*100 < (152*16)) + sensor_write(sd,0x3060,0x000a); + else if ((152*16) <= gain_val*100 && gain_val*100 < (160*16)) + sensor_write(sd,0x3060,0x000b); + else if ((160*16) <= gain_val*100 && gain_val*100 < (168*16)) + sensor_write(sd,0x3060,0x000c); + else if ((168*16) <= gain_val*100 && gain_val*100 < (178*16)) + sensor_write(sd,0x3060,0x000d); + else if ((178*16) <= gain_val*100 && gain_val*100 < (188*16)) + sensor_write(sd,0x3060,0x000e); + else if ((188*16) <= gain_val*100 && gain_val*100 < (200*16)) + sensor_write(sd,0x3060,0x000f); + else if ((200*16) <= gain_val*100 && gain_val*100 < (213*16)) + { + sensor_write(sd,0x3060,0x0010); + dig_gain = gain_val*12800/(200*16); + } + else if ((213*16) <= gain_val*100 && gain_val*100 < (229*16)) + { + sensor_write(sd,0x3060,0x0012); + dig_gain = gain_val*12800/(213*16); + } + else if ((229*16) <= gain_val*100 && gain_val*100 < (246*16)) + { + sensor_write(sd,0x3060,0x0014); + dig_gain = gain_val*12800/(229*16); + } + else if ((246*16) <= gain_val*100 && gain_val*100 < (267*16)) + { + sensor_write(sd,0x3060,0x0016); + dig_gain = gain_val*12800/(246*16); + } + else if ((267*16) <= gain_val*100 && gain_val*100 < (291*16)) + { + sensor_write(sd,0x3060,0x0018); + dig_gain = gain_val*12800/(267*16); + } + else if ((291*16) <= gain_val*100 && gain_val*100 < (320*16)) + { + sensor_write(sd,0x3060,0x001a); + dig_gain = gain_val*12800/(291*16); + } + else if ((320*16) <= gain_val*100 && gain_val*100 < (356*16)) + { + sensor_write(sd,0x3060,0x001c); + dig_gain = gain_val*12800/(320*16); + } + else if ((356*16) <= gain_val*100 && gain_val*100 < (400*16)) + { + sensor_write(sd,0x3060,0x001e); + dig_gain = gain_val*12800/(356*16); + } + else if ((400*16) <= gain_val*100 && gain_val*100 < (457*16)) + { + sensor_write(sd,0x3060,0x0020); + dig_gain = gain_val*12800/(400*16); + } + else if ((457*16) <= gain_val*100 && gain_val*100 < (533*16)) + { + sensor_write(sd,0x3060,0x0024); + dig_gain = gain_val*12800/(457*16); + } + else if ((533*16) <= gain_val*100 && gain_val*100 < (640*16)) + { + sensor_write(sd,0x3060,0x0028); + dig_gain = gain_val*12800/(533*16); + } + else if ((640*16) <= gain_val*100 && gain_val*100 < (800*16)) + { + sensor_write(sd,0x3060,0x002c); + dig_gain = gain_val*12800/(640*16); + } + else if ((800*16) <= gain_val*100 ) + { + sensor_write(sd,0x3060,0x0030); + dig_gain = gain_val*12800/(800*16); + } + + sensor_write(sd, 0x305e, dig_gain); + + //sensor_read(sd,0x3060,&tmp_gain); + //printk("sensor_set_gain = %d,readout gain =0x%x\n", gain_val,tmp_gain); + info->gain = gain_val; + return 0; } static int ar0330_sensor_vts; - static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) { - int exp_val, gain_val,shutter,frame_length; -// unsigned char explow=0,expmid=0,exphigh=0,vts_diff_low,vts_diff_high; -// unsigned char gainlow=0,gainhigh=0; - struct sensor_info *info = to_state(sd); - - exp_val = exp_gain->exp_val; - gain_val = exp_gain->gain_val; - - //if((info->exp == exp_val)&&(info->gain == gain_val)) - // return 0; - if(gain_val<1*16) - gain_val=16; - if(gain_val>64*16-1) - gain_val=64*16-1; - if(exp_val>0xfffff) - exp_val=0xfffff; - - shutter = exp_val/16; - if(shutter > ar0330_sensor_vts- 4) - frame_length = shutter + 4; - else - frame_length = ar0330_sensor_vts; - - printk("norm exp_val = %d,gain_val = %d\n",exp_val,gain_val); - - sensor_write(sd, 0x300A,frame_length);//coarse integration time - sensor_s_exp(sd,exp_val); - sensor_s_gain(sd,gain_val); - info->exp = exp_val; - info->gain = gain_val; - return 0; + int exp_val, gain_val,shutter,frame_length; + // unsigned char explow=0,expmid=0,exphigh=0,vts_diff_low,vts_diff_high; + // unsigned char gainlow=0,gainhigh=0; + struct sensor_info *info = to_state(sd); + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + if(gain_val<1*16) + gain_val=16; + if(gain_val>64*16-1) + gain_val=64*16-1; + if(exp_val>0xfffff) + exp_val=0xfffff; + + shutter = exp_val/16; + if(shutter > ar0330_sensor_vts - 4) + frame_length = shutter + 4; + else + frame_length = ar0330_sensor_vts; + +// printk("norm exp_val = %d,gain_val = %d\n",exp_val,gain_val); + sensor_write(sd, 0x300A,frame_length);//coarse integration time + sensor_s_exp(sd,exp_val); + sensor_s_gain(sd,gain_val); + info->exp = exp_val; + info->gain = gain_val; + return 0; } static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) { @@ -1176,138 +1185,104 @@ static int sensor_set_pll_enable(struct v4l2_subdev *sd, int on_off) static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - ret = 0; - switch(on) - { - case CSI_SUBDEV_STBY_ON: - vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); - //software standby on - ret = sensor_s_sw_stby(sd, CSI_STBY_ON); - if(ret < 0) - vfe_dev_err("soft stby falied!\n"); - usleep_range(1000,1200); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //standby on io - // vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - - vfe_set_mclk(sd,OFF); - // printk("ar0330 standby on!!"); - - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - - case CSI_SUBDEV_STBY_OFF: - vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - printk("ar0330 standby off!!"); - usleep_range(1000,1200); - //standby off io - // vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - // usleep_range(100000,120000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //software standby - ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); - if(ret < 0) - vfe_dev_err("soft stby off falied!\n"); - usleep_range(1000,1200); - // vfe_dev_print("enable oe!\n"); - // ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); - // if(ret < 0) - // vfe_dev_err("enable oe falied!\n"); - break; - - case CSI_SUBDEV_PWR_ON: - vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //power on reset - // vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - //vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //usleep_range(10000,12000); - //power supply - //vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - // vfe_set_pmu_channel(sd,PLLVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - // vfe_set_pmu_channel(sd,AFVDD,ON); - // vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - // vfe_gpio_write(sd,RESET,CSI_RST_OFF); - //usleep_range(100000,120000); - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(2000,2200); - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(6000,7000); - - //active mclk before power on - -/* - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - mdelay(10); - //reset after power on - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - mdelay(30); - */ - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - - - case CSI_SUBDEV_PWR_OFF: - vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - // vfe_gpio_write(sd,RESET,CSI_RST_ON); - // vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - - - //inactive mclk before power off - - - - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - //vfe_set_pmu_channel(sd,AFVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_mclk(sd,OFF); - - - //set the io to hi-z - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - default: - return -EINVAL; - } + int ret; + ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + //software standby on + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + //power on reset + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,POWER_EN,1);//set the gpio to output + + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_LOW); + usleep_range(1000,1200); + //power supply + vfe_set_pmu_channel(sd,AVDD,ON); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_HIGH); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(1000,1200); + vfe_set_pmu_channel(sd,IOVDD,ON); + //active mclk before power on + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + + usleep_range(7000,8000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + //reset on io + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + usleep_range(20000,22000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + printk("soft stby off..................................!"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + //inactive mclk before power off + vfe_set_mclk(sd,OFF); + //power supply off + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_LOW); + vfe_set_pmu_channel(sd,AVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + //set the io to hi-z + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + vfe_gpio_set_status(sd,POWER_EN,0);//set the gpio to input + cci_unlock(sd); + break; + default: + return -EINVAL; + } return 0; } diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330_mipi.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330_mipi.c index 6e76c0c8..52d689ef 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330_mipi.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ar0330_mipi.c @@ -171,9 +171,9 @@ static struct regval_list sensor_default_regs[] = {0x3042,0x0000}, //EXTRA_DELAY = 0 {0x30BA,0x002C}, //DIGITAL_CTRL = 44 {0x3070,0x0000}, -#if 0 +#if 1 {0x30FE, 0x0080}, // RESERVED_MFR_30FE - {0x31E0, 0x0000}, // RESERVED_MFR_31E0 dpc enable reg 0x0003 + {0x31E0, 0x0703}, // RESERVED_MFR_31E0 dpc enable reg 0x0003 {0x3ECE, 0x08FF}, // RESERVED_MFR_3ECE {0x3ED0, 0xE4F6}, // RESERVED_MFR_3ED0 {0x3ED2, 0x0146}, // RESERVED_MFR_3ED2 @@ -469,7 +469,7 @@ static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp else frame_length = ar0330_sensor_vts; - printk("norm exp_val = %d,gain_val = %d\n",exp_val,gain_val); +// printk("norm exp_val = %d,gain_val = %d\n",exp_val,gain_val); // sensor_write(sd, 0x300A,frame_length);//coarse integration time sensor_s_exp(sd,exp_val); sensor_s_gain(sd,gain_val); @@ -497,124 +497,97 @@ static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - ret = 0; - switch(on) - { - case CSI_SUBDEV_STBY_ON: - vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); - //software standby on - ret = sensor_s_sw_stby(sd, CSI_STBY_ON); - if(ret < 0) - vfe_dev_err("soft stby falied!\n"); - usleep_range(1000,1200); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //standby on io - // vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - vfe_set_mclk(sd,OFF); - // printk("ar0330_mipi standby on!!"); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - case CSI_SUBDEV_STBY_OFF: - vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - printk("ar0330 standby off!!"); - usleep_range(1000,1200); - //standby off io - // vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - // usleep_range(100000,120000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //software standby - ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); - if(ret < 0) - vfe_dev_err("soft stby off falied!\n"); - usleep_range(1000,1200); - // vfe_dev_print("enable oe!\n"); - // ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); - // if(ret < 0) - // vfe_dev_err("enable oe falied!\n"); - break; - case CSI_SUBDEV_PWR_ON: - vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //power on reset - // vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - //vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //usleep_range(10000,12000); - //power supply - //vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - // vfe_set_pmu_channel(sd,PLLVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - // vfe_set_pmu_channel(sd,AFVDD,ON); - // vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - // vfe_gpio_write(sd,RESET,CSI_RST_OFF); - //usleep_range(100000,120000); - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(2000,2200); - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(6000,7000); - //active mclk before power on - /* - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - mdelay(10); - //reset after power on - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - mdelay(30); - */ - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - case CSI_SUBDEV_PWR_OFF: - vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - // vfe_gpio_write(sd,RESET,CSI_RST_ON); - // vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //inactive mclk before power off - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - //vfe_set_pmu_channel(sd,AFVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_mclk(sd,OFF); - //set the io to hi-z - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - default: - return -EINVAL; - } + int ret; + ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + //software standby on + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + //power on reset +// vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,POWER_EN,1);//set the gpio to output + + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); +// vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_LOW); + usleep_range(1000,1200); + //power supply + vfe_set_pmu_channel(sd,AVDD,ON); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_HIGH); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(1000,1200); + vfe_set_pmu_channel(sd,IOVDD,ON); + //active mclk before power on + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + +// usleep_range(7000,8000); +// vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); +// usleep_range(10000,12000); + //reset on io + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + usleep_range(20000,22000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); +// vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output +// vfe_gpio_set_status(sd,RESET,1);//set the gpio to output +// vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); +// vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + //power supply off + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + vfe_gpio_write(sd,POWER_EN,CSI_GPIO_LOW); + vfe_set_pmu_channel(sd,AVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + //inactive mclk before power off + vfe_set_mclk(sd,OFF); + //set the io to hi-z +// vfe_gpio_set_status(sd,RESET,0);//set the gpio to input +// vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input +// vfe_gpio_set_status(sd,POWER_EN,0);//set the gpio to input + cci_unlock(sd); + usleep_range(50000,52000); + break; + default: + return -EINVAL; + } - return 0; + return 0; } static int sensor_reset(struct v4l2_subdev *sd, u32 val) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h index a066c990..0a7d7c6d 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera.h @@ -85,7 +85,6 @@ struct sensor_info { struct v4l2_fract tpf; struct sensor_win_size *current_wins; struct flash_dev_info *fl_dev_info; - u8 clkrc; /* Clock divider value */ }; #endif //__CAMERA__H__ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera_cfg.h index 71b1fa6a..7963aa1e 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/camera_cfg.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/camera_cfg.h @@ -11,12 +11,17 @@ typedef enum tag_CAMERA_IO_CMD { SET_FLASH_CTRL, ISP_SET_EXP_GAIN, GET_SENSOR_EXIF, + ISP_SET_WIN_OFF, }__camera_cmd_t; struct sensor_exp_gain { int exp_val; int gain_val; }; +struct sensor_win_off { + int hor_off; + int ver_off; +}; struct sensor_exif_attribute { __u32 exposure_time_num; diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc1004_mipi.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc1004_mipi.c new file mode 100755 index 00000000..e7a29699 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc1004_mipi.c @@ -0,0 +1,1239 @@ +/* + * A V4L2 driver for gc1004_mipi Raw cameras. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "camera.h" + + +MODULE_AUTHOR("lwj"); +MODULE_DESCRIPTION("A low-level driver for gc1004_mipi Raw sensors"); +MODULE_LICENSE("GPL"); + +//for internel driver debug +#define DEV_DBG_EN 0 +#if(DEV_DBG_EN == 1) +#define vfe_dev_dbg(x,arg...) printk("[gc1004_mipi Raw]"x,##arg) +#else +#define vfe_dev_dbg(x,arg...) +#endif +#define vfe_dev_err(x,arg...) printk("[gc1004_mipi Raw]"x,##arg) +#define vfe_dev_print(x,arg...) printk("[gc1004_mipi Raw]"x,##arg) + +#define LOG_ERR_RET(x) { \ + int ret; \ + ret = x; \ + if(ret < 0) {\ + vfe_dev_err("error at %s\n",__func__); \ + return ret; \ + } \ + } + +//define module timing +#define MCLK (24*1000*1000) +#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_LOW +#define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH +#define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING +#define V4L2_IDENT_SENSOR 0x1004 + + +//define the voltage level of control signal +#define CSI_STBY_ON 1 +#define CSI_STBY_OFF 0 +#define CSI_RST_ON 0 +#define CSI_RST_OFF 1 +#define CSI_PWR_ON 1 +#define CSI_PWR_OFF 0 +#define CSI_AF_PWR_ON 1 +#define CSI_AF_PWR_OFF 0 +#define regval_list reg_list_a8_d8 +#define REG_DLY 0xff + +//define the registers +#define EXP_HIGH 0xff +#define EXP_MID 0x03 +#define EXP_LOW 0x04 +#define GAIN_HIGH 0xff +#define GAIN_LOW 0x24 +//#define FRACTION_EXP +#define ID_REG_HIGH 0xf0 +#define ID_REG_LOW 0xf1 +#define ID_VAL_HIGH ((V4L2_IDENT_SENSOR) >> 8) +#define ID_VAL_LOW ((V4L2_IDENT_SENSOR) & 0xff) + +#define ANALOG_GAIN_1 64 // 1.00x +#define ANALOG_GAIN_2 90 // 1.4x +#define ANALOG_GAIN_3 118 // 1.8x +#define ANALOG_GAIN_4 163 // 2.56x +#define ANALOG_GAIN_5 218 // 3.40x +#define ANALOG_GAIN_6 304 // 4.7x +#define ANALOG_GAIN_7 438 // 6.84x +#define ANALOG_GAIN_8 602 // 9.4x +#define ANALOG_GAIN_9 851 // 13.2x + +/* + *Our nominal (default) frame rate. + */ + +#define SENSOR_FRAME_RATE 30 + + +/* + * The gc1004_mipi i2c address + */ +#define I2C_ADDR 0x78 +#define SENSOR_NAME "gc1004_mipi" + +//static struct delayed_work sensor_s_ae_ratio_work; +static struct v4l2_subdev *glb_sd; + +/* + * Information we maintain about a known sensor. + */ +struct sensor_format_struct; /* coming later */ + +struct cfg_array { /* coming later */ + struct regval_list * regs; + int size; +}; + +static inline struct sensor_info *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sensor_info, sd); +} + + +/* + * The default register settings + * + */ + +static struct regval_list sensor_default_regs[] = +{ +#if 1 + {0xfe, 0x80}, + {0xfe, 0x80}, + {0xfe, 0x80}, + {0xf2, 0x00}, //sync_pad_io_ebi + {0xf6, 0x00}, //up down + {0xfc, 0xc6}, + {0xf7, 0x33}, //pll enable + {0xf8, 0x08}, //Pll mode 2 + {0xf9, 0x2e}, //[0] pll enable + {0xfa, 0x00}, //div + {0xfe, 0x00}, + {0x03, 0x02}, + {0x04, 0xee}, + {0x05, 0x01}, + {0x06, 0xae}, + {0x07, 0x00}, + {0x08, 0x50}, + {0x0d, 0x02}, //height + {0x0e, 0xe8}, + {0x0f, 0x05}, //widths + {0x10, 0x10}, + {0x11, 0x00}, + {0x12, 0x18},//sh_delay + {0x17, 0x14}, //01//14//[0]mirror [1]flip + {0x18, 0x02}, //sdark off + {0x19, 0x06}, + {0x1a, 0x01}, + {0x1b, 0x4f}, + {0x1c, 0x21}, + {0x1d, 0xe0},//f0 + {0x1e, 0x7c}, //fe The dark stripes + {0x1f, 0x08}, //08//comv_r + {0x20, 0xa9}, + {0x21, 0x0f}, //2f//20//rsg + {0x22, 0xb0}, + {0x23, 0x32}, //38 + {0x24, 0x2f}, //PAD drive + {0x2a, 0x00}, + {0x2c, 0xc0}, + {0x2d, 0x0f}, + {0x2e, 0xf0}, + {0x2f, 0x1f}, //exp not work + {0x25, 0xc0}, + {0x36, 0x0b}, + {0x37, 0x13}, + {0x38, 0x1b}, + {0xfe, 0x00}, + {0x8a, 0x00}, + {0x8c, 0x07}, + {0x8e, 0x02}, //luma value not normal + {0x90, 0x01}, + {0x94, 0x02}, + {0x95, 0x02}, + {0x96, 0xd0}, + {0x97, 0x05}, + {0x98, 0x00}, + {0xfe, 0x00}, + {0x18, 0x02}, + {0x1a, 0x01}, + {0x40, 0x23}, + {0x5e, 0x00}, + {0x66, 0x20}, + {0xfe, 0x02}, + {0x49, 0x23}, + {0xa4, 0x00}, + {0xfe, 0x00}, + {0xb0, 0x50}, + {0xb3, 0x40}, + {0xb4, 0x40}, + {0xb5, 0x40}, + {0xfe, 0x00}, + {0xfe, 0x03}, + {0x01, 0x07}, + {0x02, 0x33}, + {0x03, 0x13}, + {0x04, 0x02}, + {0x05, 0x00}, + {0x06, 0xa4}, + {0x10, 0x91}, + {0x11, 0x2b}, + {0x12, 0x40}, + {0x13, 0x06}, + {0x21, 0x03}, + {0x15, 0x02}, + {0x22, 0x03}, + {0x23, 0x04}, + {0x24, 0x10}, + {0x29, 0x03}, + {0xfe, 0x00}, + +#else // 1 lane + +/////////////////////////////////////////// +//////////// SYS ////////////////////// +/////////////////////////////////////////// +{0xfe, 0x80}, +{0xfe, 0x80}, +{0xfe, 0x80}, +{0xf2, 0x00}, //sync_pad_io_ebi +{0xf6, 0x00}, //up down +{0xfc, 0xc6}, +{0xf7, 0x19}, //pll enable +{0xf8, 0x03}, //Pll mode 2 +{0xf9, 0x2e}, //[0] pll enable +{0xfa, 0x00}, //div +{0xfe, 0x00}, + +/////////////////////////////////////////// +////// ANALOG & CISCTL //////////////// +/////////////////////////////////////////// +{0x03, 0x03}, +{0x04, 0x00}, +{0x05, 0x01}, +{0x06, 0x77}, +{0x07, 0x00}, +{0x08, 0x1e}, +{0x0d, 0x02}, //height +{0x0e, 0xe8}, +{0x0f, 0x05}, //widths +{0x10, 0x10}, +{0x11, 0x00}, +{0x12, 0x18}, //sh_delay//write big can weaken dark current not work +{0x17, 0x14}, //01//14//[0]mirror [1]flip +{0x18, 0x0a}, //sdark off +{0x19, 0x06}, +{0x1a, 0x09}, +{0x1b, 0x4f}, +{0x1c, 0x41}, +{0x1d, 0xe0},//f0 +{0x1e, 0x7c}, //fe The dark stripes +{0x1f, 0x08}, //08//comv_r +{0x20, 0xa9}, //A vertical bar on the right +{0x21, 0x2f}, //2f//20//rsg +{0x22, 0xb0}, +{0x23, 0x32}, //38 +{0x24, 0x2f}, //PAD drive +{0x2a, 0x00}, +{0x2c, 0xb0}, +{0x2d, 0x0f}, +{0x2e, 0xf0}, +{0x2f, 0x1f}, //exp not work +{0x25, 0xc0}, +{0x36, 0x0b}, +{0x37, 0x13}, +{0x38, 0x1b}, + +/////////////////////////////////////////// +//////////// ISP ////////////////////// +/////////////////////////////////////////// + + +{0xfe, 0x00}, +{0x8a, 0x00}, +{0x8c, 0x07}, +{0x8e, 0x02}, //luma value not normal +{0x90, 0x01}, +{0x94, 0x02}, +{0x95, 0x02}, +{0x96, 0xd0}, +{0x97, 0x05}, +{0x98, 0x00}, + + + +/////////////////////////////////////////// +//////////// BLK ///////////////////// +/////////////////////////////////////////// +{0xfe, 0x00}, +{0x18, 0x02}, +{0x1a, 0x01}, +{0x40, 0x23}, +{0x5e, 0x00}, +{0x66, 0x20}, + + +/////////////////////////////////////////// +//////////// Dark SUN ///////////////////// +/////////////////////////////////////////// + +{0xfe, 0x02}, +{0x49, 0x23}, +{0xa4, 0x00}, +{0xfe, 0x00}, + +/////////////////////////////////////////// +//////////// Gain ///////////////////// +/////////////////////////////////////////// + +{0xb0, 0x50}, +{0xb3, 0x40}, +{0xb4, 0x40}, +{0xb5, 0x40}, +{0xfe, 0x00}, + +/////////////////////////////////////////// +//////////// MIPI ///////////////////// +/////////////////////////////////////////// +{0xfe, 0x03}, +{0x01, 0x03}, +{0x02, 0x11}, +{0x03, 0x13}, +{0x04, 0x01}, +{0x05, 0x00}, +{0x06, 0xa4}, +{0x10, 0x90}, +{0x11, 0x2b}, +{0x12, 0x40}, +{0x13, 0x06}, +{0x15, 0x02}, + +{0xfe, 0x00}, + +#endif + +}; + + +/* + * Here we'll try to encapsulate the changes for just the output + * video format. + * + */ + +static struct regval_list sensor_fmt_raw[] = { + //{REG_TERM,VAL_TERM}, +}; + +/* + * Low-level register I/O. + * + */ +static int sensor_read(struct v4l2_subdev *sd, unsigned char reg, + unsigned char *value) //!!!!be careful of the para type!!! +{ + int ret=0; + int cnt=0; + + ret = cci_read_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_read_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor read retry=%d\n",cnt); + + return ret; +} + +static int sensor_write(struct v4l2_subdev *sd, unsigned char reg, + unsigned char value) +{ + int ret=0; + int cnt=0; + + ret = cci_write_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_write_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor write retry=%d\n",cnt); + + return ret; +} + +/* + * Write a list of register settings; + */ +static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size) +{ + int i=0; + + if(!regs) + return -EINVAL; + + while(iaddr == REG_DLY) { + msleep(regs->data); + } + else { + LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data)) + } + i++; + regs++; + } + return 0; +} + +/* + * Code for dealing with controls. + * fill with different sensor module + * different sensor module has different settings here + * if not support the follow function ,retrun -EINVAL + */ +static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->exp; + vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); + return 0; +} + +static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) +{ + unsigned char explow,expmid,exphigh; + struct sensor_info *info = to_state(sd); + + if(exp_val>0xfffff) + exp_val=0xfffff; + + sensor_write(sd, 0xfe, 0x00); + + #ifdef FRACTION_EXP + exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); + expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); + explow = (unsigned char) ( (0x0000ff&exp_val) ); + sensor_write(sd, EXP_HIGH, exphigh); + #else + exphigh = 0; + expmid = (unsigned char) ( (0x0ff000&exp_val)>>12); + explow = (unsigned char) ( (0x000ff0&exp_val)>>4); + #endif + + sensor_write(sd, EXP_MID, expmid); + sensor_write(sd, EXP_LOW, explow); + + //printk("gc1004_mipi sensor_set_exp = %d, Done!\n", exp_val); + + info->exp = exp_val; + return 0; +} + +static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->gain; + vfe_dev_dbg("sensor_get_gain = %d\n", info->gain); + return 0; +} + +static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) +{ + unsigned char tmp; + struct sensor_info *info = to_state(sd); + // printk("gc2235 sensor gain value is %d\n",gain_val); + gain_val = gain_val * 6; + + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0xb1, 0x01); + sensor_write(sd, 0xb2, 0x00); + + if(gain_val < 0x40) + gain_val = 0x40; + + else if((ANALOG_GAIN_1<= gain_val)&&(gain_val < ANALOG_GAIN_2)) + { + //analog gain + sensor_write(sd, 0xb6, 0x00);// + tmp = gain_val; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 1x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_2<= gain_val)&&(gain_val < ANALOG_GAIN_3)) + { + //analog gain + sensor_write(sd, 0xb6, 0x01);// + tmp = 64*gain_val/ANALOG_GAIN_2; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 1.4x , GC1004_mipi add pregain = %d\n",tmp); + } + + else if((ANALOG_GAIN_3<= gain_val)&&(gain_val < ANALOG_GAIN_4)) + { + //analog gain + sensor_write(sd, 0xb6, 0x02);// + tmp = 64*gain_val/ANALOG_GAIN_3; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 1.8x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_4<= gain_val)&&(gain_val < ANALOG_GAIN_5)) + { + //analog gain + sensor_write(sd, 0xb6, 0x03);// + tmp = 64*gain_val/ANALOG_GAIN_4; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 2.56x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_5<= gain_val)&&(gain_val < ANALOG_GAIN_6)) + { + //analog gain + sensor_write(sd, 0xb6, 0x04);// + tmp = 64*gain_val/ANALOG_GAIN_5; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 3.4x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_6<= gain_val)&&(gain_val < ANALOG_GAIN_7)) + { + //analog gain + sensor_write(sd, 0xb6, 0x05);// + tmp = 64*gain_val/ANALOG_GAIN_6; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 4.7x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_7<= gain_val)&&(gain_val < ANALOG_GAIN_8)) + { + //analog gain + sensor_write(sd, 0xb6, 0x06);// + tmp = 64*gain_val/ANALOG_GAIN_7; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 6.84x , GC1004_mipi add pregain = %d\n",tmp); + } + else if((ANALOG_GAIN_8<= gain_val)&&(gain_val < ANALOG_GAIN_9)) + { + //analog gain + sensor_write(sd, 0xb6, 0x07);// + tmp = 64*gain_val/ANALOG_GAIN_8; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 9.4x , GC1004_mipi add pregain = %d\n",tmp); + } + else if(ANALOG_GAIN_9<= gain_val) + { + //analog gain + sensor_write(sd, 0xb6, 0x08);// + tmp = 64*gain_val/ANALOG_GAIN_9; + sensor_write(sd, 0xb1, tmp>>6); + sensor_write(sd, 0xb2, (tmp<<2)&0xfc); + //printk("GC1004_mipi analogic gain 13.2x , GC1004_mipi add pregain = %d\n",tmp); + } + + //printk("gc1004 sensor read out gain is %d\n",gain); + info->gain = gain_val; + + return 0; +} + +static int gc1004_sensor_vts; +static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) +{ + int exp_val, gain_val; + struct sensor_info *info = to_state(sd); + + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + //printk("gc1004 sensor read out exp & gain is %d\t%d\n",exp_val, gain_val); + + if(gain_val<1*16) + gain_val=16; + if(gain_val>64*16-1) + gain_val=64*16-1; + + if(exp_val>0xfffff) + exp_val=0xfffff; + + sensor_s_exp(sd,exp_val); + sensor_s_gain(sd,gain_val); + + sensor_write(sd, 0x08, 0x36); //fix 30fps + + info->exp = exp_val; + info->gain = gain_val; + return 0; +} + + +/* +static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) +{ + int ret; + unsigned char rdval; + + ret=sensor_read(sd, 0x0100, &rdval); + if(ret!=0) + return ret; + + if(on_off==CSI_STBY_ON)//sw stby on + { + ret=sensor_write(sd, 0x0100, rdval&0xfe); + } + else//sw stby off + { + ret=sensor_write(sd, 0x0100, rdval|0x01); + } + return ret; +} +*/ + +/* + * Stuff that knows about the sensor. + */ + +static int sensor_power(struct v4l2_subdev *sd, int on) +{ + int ret; + + //insure that clk_disable() and clk_enable() are called in pair + //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF + ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + //disable io oe + // vfe_dev_print("disalbe oe!\n"); + //ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); + // if(ret < 0) + // vfe_dev_err("disalbe oe falied!\n"); + //software standby on + //ret = sensor_s_sw_stby(sd, CSI_STBY_ON); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); +// //reset on io +// vfe_gpio_write(sd,RESET,CSI_RST_ON); +// usleep_range(10000,12000); + //standby on io + vfe_gpio_write(sd,PWDN,CSI_STBY_ON); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + //inactive mclk after stadby in +// vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //active mclk before stadby out + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + //standby off io + vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); + + usleep_range(10000,12000); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + //software standby + // ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); + // if(ret < 0) + // vfe_dev_err("soft stby off falied!\n"); + usleep_range(10000,12000); + // vfe_dev_print("enable oe!\n"); + // ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); + // if(ret < 0) + // vfe_dev_err("enable oe falied!\n"); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //power on reset + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + //power down io + vfe_gpio_write(sd,PWDN,CSI_STBY_ON); + //reset on io + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(1000,1200); + + //power supply + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,IOVDD,ON); + vfe_set_pmu_channel(sd,AVDD,ON); + //active mclk before power on + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + //vfe_set_pmu_channel(sd,AFVDD,ON); + //standby off io + vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); + usleep_range(10000,12000); + //reset after power on + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(30000,31000); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //inactive mclk before power off + vfe_set_mclk(sd,OFF); + //power supply off + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + //vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,AVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + //standby and reset io + usleep_range(10000,12000); + vfe_gpio_write(sd,POWER_EN,CSI_STBY_OFF); + vfe_gpio_write(sd,RESET,CSI_RST_ON); + //set the io to hi-z + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sensor_reset(struct v4l2_subdev *sd, u32 val) +{ + switch(val) + { + case 0: + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(10000,12000); + break; + case 1: + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(10000,12000); + break; + default: + return -EINVAL; + } + return 0; +} + +static int sensor_detect(struct v4l2_subdev *sd) +{ + unsigned char rdval; + + LOG_ERR_RET(sensor_read(sd, ID_REG_HIGH, &rdval)) + printk("gc1004_mipi ID_VAL_HIGH = %2x, Done! 20150316a \n", rdval); + if(rdval != ID_VAL_HIGH) + return -ENODEV; + + + LOG_ERR_RET(sensor_read(sd, ID_REG_LOW, &rdval)) + // printk("gc1004_mipi ID_VAL_LOW = %2x, Done!\n", rdval); + if(rdval != ID_VAL_LOW) + return -ENODEV; + + + return 0; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + int ret; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_init\n"); + + /*Make sure it is a target sensor*/ + ret = sensor_detect(sd); + if (ret) { + vfe_dev_err("chip found is not an target chip.\n"); + return ret; + } + vfe_get_standby_mode(sd,&info->stby_mode); + + if((info->stby_mode == HW_STBY || info->stby_mode == SW_STBY) \ + && info->init_first_flag == 0) { + vfe_dev_print("stby_mode and init_first_flag = 0\n"); + return 0; + } + + info->focus_status = 0; + info->low_speed = 0; + info->width = HD720_WIDTH; + info->height = HD720_HEIGHT; + info->hflip = 0; + info->vflip = 0; + info->gain = 0; + + info->tpf.numerator = 1; + info->tpf.denominator = 30; /* 30fps */ + + ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); + if(ret < 0) { + vfe_dev_err("write sensor_default_regs error\n"); + return ret; + } + if(info->stby_mode == 0) + info->init_first_flag = 0; + info->preview_first_flag = 1; + return 0; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + int ret=0; + struct sensor_info *info = to_state(sd); + switch(cmd) { + case GET_CURRENT_WIN_CFG: + if(info->current_wins != NULL) + { + memcpy( arg, + info->current_wins, + sizeof(struct sensor_win_size) ); + ret=0; + } + else + { + vfe_dev_err("empty wins!\n"); + ret=-1; + } + break; + case SET_FPS: + ret=0; + break; + case ISP_SET_EXP_GAIN: + ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); + break; + default: + return -EINVAL; + } + return ret; +} + + +/* + * Store information about the video data format. + */ +static struct sensor_format_struct { + __u8 *desc; + //__u32 pixelformat; + enum v4l2_mbus_pixelcode mbus_code; + struct regval_list *regs; + int regs_size; + int bpp; /* Bytes per pixel */ +}sensor_formats[] = { + { + .desc = "Raw RGB Bayer", + .mbus_code = V4L2_MBUS_FMT_SRGGB10_10X1, + .regs = sensor_fmt_raw, + .regs_size = ARRAY_SIZE(sensor_fmt_raw), + .bpp = 1 + }, +}; +#define N_FMTS ARRAY_SIZE(sensor_formats) + +/* + * Then there is the issue of window sizes. Try to capture the info here. + */ +static struct sensor_win_size sensor_win_sizes[] = { + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 0, + .voffset = 0, + .hts = 982, + .vts = 814, + .pclk = 24*1000*1000, + .mipi_bps = 222*1000*1000,//216 + .fps_fixed = 1, + .bin_factor = 1, + .intg_min = 1<<4, + .intg_max = 814<<4,// + .gain_min = 1<<4, + .gain_max = 16<<4, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + +}; + +#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) + +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= N_FMTS) + return -EINVAL; + + *code = sensor_formats[index].mbus_code; + return 0; +} + +static int sensor_enum_size(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + if(fsize->index > N_WIN_SIZES-1) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = sensor_win_sizes[fsize->index].width; + fsize->discrete.height = sensor_win_sizes[fsize->index].height; + + return 0; +} + +static int sensor_try_fmt_internal(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt, + struct sensor_format_struct **ret_fmt, + struct sensor_win_size **ret_wsize) +{ + int index; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + for (index = 0; index < N_FMTS; index++) + if (sensor_formats[index].mbus_code == fmt->code) + break; + + if (index >= N_FMTS) + return -EINVAL; + + if (ret_fmt != NULL) + *ret_fmt = sensor_formats + index; + + /* + * Fields: the sensor devices claim to be progressive. + */ + + fmt->field = V4L2_FIELD_NONE; + + /* + * Round requested image size down to the nearest + * we support, but not below the smallest. + */ + for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; + wsize++) + if (fmt->width >= wsize->width && fmt->height >= wsize->height) + break; + + if (wsize >= sensor_win_sizes + N_WIN_SIZES) + wsize--; /* Take the smallest one */ + if (ret_wsize != NULL) + *ret_wsize = wsize; + /* + * Note the size we'll actually handle. + */ + fmt->width = wsize->width; + fmt->height = wsize->height; + info->current_wins = wsize; + //pix->bytesperline = pix->width*sensor_formats[index].bpp; + //pix->sizeimage = pix->height*pix->bytesperline; + + return 0; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + return sensor_try_fmt_internal(sd, fmt, NULL, NULL); +} + +static int sensor_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + cfg->type = V4L2_MBUS_CSI2; + cfg->flags = 0|V4L2_MBUS_CSI2_2_LANE|V4L2_MBUS_CSI2_CHANNEL_0; + + return 0; +} + + +/* + * Set a format. + */ +static int sensor_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + int ret; + struct sensor_format_struct *sensor_fmt; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_s_fmt\n"); + // sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); + ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); + if (ret) + return ret; + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } + else if(info->capture_mode == V4L2_MODE_IMAGE) + { + //image + } + LOG_ERR_RET(sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size)) + ret = 0; + if (wsize->regs) + LOG_ERR_RET(sensor_write_array(sd, wsize->regs, wsize->regs_size)) + if (wsize->set_size) + LOG_ERR_RET(wsize->set_size(sd)) + + info->fmt = sensor_fmt; + info->width = wsize->width; + info->height = wsize->height; + gc1004_sensor_vts = wsize->vts; + // show_regs_array(sd,sensor_1080p_regs); + + vfe_dev_print("s_fmt set width = %d, height = %d\n",wsize->width,wsize->height); + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } else { + //capture image + } + //sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); + return 0; +} + +/* + * Implement G/S_PARM. There is a "high quality" mode we could try + * to do someday; for now, we just do the frame rate tweak. + */ +static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + struct sensor_info *info = to_state(sd); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->capturemode = info->capture_mode; + + return 0; +} + +static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + //struct v4l2_fract *tpf = &cp->timeperframe; + struct sensor_info *info = to_state(sd); + //unsigned char div; + + vfe_dev_dbg("sensor_s_parm\n"); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (info->tpf.numerator == 0) + return -EINVAL; + + info->capture_mode = cp->capturemode; + + return 0; +} + + +static int sensor_queryctrl(struct v4l2_subdev *sd, + struct v4l2_queryctrl *qc) +{ + /* Fill in min, max, step and default value for these controls. */ + /* see include/linux/videodev2.h for details */ + + switch (qc->id) { + case V4L2_CID_GAIN: + return v4l2_ctrl_query_fill(qc, 1*16, 32*16, 1, 16); + case V4L2_CID_EXPOSURE: + return v4l2_ctrl_query_fill(qc, 0, 65535*16, 1, 0); + } + return -EINVAL; +} + +static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_g_gain(sd, &ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_g_exp(sd, &ctrl->value); + } + return -EINVAL; +} + +static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc; + int ret; + + qc.id = ctrl->id; + ret = sensor_queryctrl(sd, &qc); + if (ret < 0) { + return ret; + } + + if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) { + return -ERANGE; + } + + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_s_gain(sd, ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_s_exp(sd, ctrl->value); + } + return -EINVAL; +} + + +static int sensor_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SENSOR, 0); +} + + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops sensor_core_ops = { + .g_chip_ident = sensor_g_chip_ident, + .g_ctrl = sensor_g_ctrl, + .s_ctrl = sensor_s_ctrl, + .queryctrl = sensor_queryctrl, + .reset = sensor_reset, + .init = sensor_init, + .s_power = sensor_power, + .ioctl = sensor_ioctl, +}; + +static const struct v4l2_subdev_video_ops sensor_video_ops = { + .enum_mbus_fmt = sensor_enum_fmt, + .enum_framesizes = sensor_enum_size, + .try_mbus_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .s_parm = sensor_s_parm, + .g_parm = sensor_g_parm, + .g_mbus_config = sensor_g_mbus_config, +}; + +static const struct v4l2_subdev_ops sensor_ops = { + .core = &sensor_core_ops, + .video = &sensor_video_ops, +}; + +/* ----------------------------------------------------------------------- */ +static struct cci_driver cci_drv = { + .name = SENSOR_NAME, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct sensor_info *info; + + info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + sd = &info->sd; + glb_sd = sd; + cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); + + info->fmt = &sensor_formats[0]; + info->af_first_flag = 1; + info->init_first_flag = 1; + + return 0; +} + + +static int sensor_remove(struct i2c_client *client) +{ + struct v4l2_subdev * sd; + + sd = cci_dev_remove_helper(client, &cci_drv); + kfree(to_state(sd)); + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + { SENSOR_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + + +static struct i2c_driver sensor_driver = { + .driver = { + .owner = THIS_MODULE, + .name = SENSOR_NAME, + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; +static __init int init_sensor(void) +{ + return cci_dev_init_helper(&sensor_driver); +} + +static __exit void exit_sensor(void) +{ + cci_dev_exit_helper(&sensor_driver); +} + +module_init(init_sensor); +module_exit(exit_sensor); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c index 49308167..b1c2b1f3 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2035.c @@ -4628,7 +4628,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) { case CSI_SUBDEV_STBY_ON: vfe_dev_dbg("CSI_SUBDEV_STBY_ON\n"); - vfe_dev_dbg("disalbe oe!\n"); + vfe_dev_print("disalbe oe!\n"); ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); if(ret < 0) vfe_dev_err("disalbe oe falied!\n"); @@ -4651,7 +4651,7 @@ static int sensor_power(struct v4l2_subdev *sd, int on) vfe_set_mclk_freq(sd, (MCLK*1000*1000)); vfe_set_mclk(sd,ON); usleep_range(10000,12000); - vfe_dev_dbg("enable oe!\n"); + vfe_dev_print("enable oe!\n"); ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); if(ret < 0) vfe_dev_err("enable oe falied!\n"); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2235.c old mode 100644 new mode 100755 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2355.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2355.c new file mode 100755 index 00000000..d6c09c27 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/gc2355.c @@ -0,0 +1,1146 @@ +/* + * A V4L2 driver for GC2355 cameras. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "camera.h" + + +MODULE_AUTHOR("lwj"); +MODULE_DESCRIPTION("A low-level driver for GC2355 sensors"); +MODULE_LICENSE("GPL"); + +//for internel driver debug +#define DEV_DBG_EN 0 +#if(DEV_DBG_EN == 1) +#define vfe_dev_dbg(x,arg...) printk("[GC2355]"x,##arg) +#else +#define vfe_dev_dbg(x,arg...) +#endif +#define vfe_dev_err(x,arg...) printk("[GC2355]"x,##arg) +#define vfe_dev_print(x,arg...) printk("[GC2355]"x,##arg) + +#define LOG_ERR_RET(x) { \ + int ret; \ + ret = x; \ + if(ret < 0) {\ + vfe_dev_err("error at %s\n",__func__); \ + return ret; \ + } \ + } + +//define module timing +#define MCLK (24*1000*1000) +#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_LOW +#define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH +#define CLK_POL V4L2_MBUS_PCLK_SAMPLE_FALLING + +#define V4L2_IDENT_SENSOR 0x2355 + +//define the voltage level of control signal +#define CSI_STBY_ON 1 +#define CSI_STBY_OFF 0 +#define CSI_RST_ON 0 +#define CSI_RST_OFF 1 +#define CSI_PWR_ON 1 +#define CSI_PWR_OFF 0 +#define CSI_AF_PWR_ON 1 +#define CSI_AF_PWR_OFF 0 +#define regval_list reg_list_a8_d8 +#define REG_DLY 0xff + +//define the registers +#define EXP_HIGH 0xff +#define EXP_MID 0x03 +#define EXP_LOW 0x04 +#define GAIN_HIGH 0xff +#define GAIN_LOW 0x24 +//#define FRACTION_EXP +#define ID_REG_HIGH 0xf0 +#define ID_REG_LOW 0xf1 +#define ID_VAL_HIGH ((V4L2_IDENT_SENSOR) >> 8) +#define ID_VAL_LOW ((V4L2_IDENT_SENSOR) & 0xff) + +#define ANALOG_GAIN_1 64 // 1.00x +#define ANALOG_GAIN_2 88 // 1.375x +#define ANALOG_GAIN_3 122 // 1.90x +#define ANALOG_GAIN_4 168 // 2.625x +#define ANALOG_GAIN_5 239 // 3.738x +#define ANALOG_GAIN_6 330 // 5.163x +#define ANALOG_GAIN_7 470 // 7.350x + + +/* + * Our nominal (default) frame rate. + */ +#define SENSOR_FRAME_RATE 30 + +/* + * The gc2355 sits on i2c with ID 0x6c + */ +#define I2C_ADDR 0x78 +#define SENSOR_NAME "gc2355" + +//static struct delayed_work sensor_s_ae_ratio_work; +static struct v4l2_subdev *glb_sd; + +/* + * Information we maintain about a known sensor. + */ +struct sensor_format_struct; /* coming later */ + +struct cfg_array { /* coming later */ + struct regval_list * regs; + int size; +}; + +static inline struct sensor_info *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sensor_info, sd); +} + + +/* + * The default register settings + * + */ + +static struct regval_list sensor_default_regs[] = +{} /* GC2355_Init_Settings */ +; + +//for capture +static struct regval_list sensor_uxga_regs[] = +{ + ///////////////////////////////////////////////////// + ////////////////////// SYS ////////////////////// + ///////////////////////////////////////////////////// + {0xfe,0x80}, + {0xfe,0x80}, + {0xfe,0x80}, + {0xf2,0x00}, + {0xf6,0x00}, + {0xf7,0x19}, + {0xf8,0x06}, + {0xf9,0x4e}, + {0xfa,0x00}, + {0xfc,0x06}, + {0xfe,0x00}, + + ///////////////////////////////////////////////////// + ////////////////// ANALOG & CISCTL /////////////// + ///////////////////////////////////////////////////// + {0x03,0x01}, + {0x04,0xd0}, + {0x05,0x03}, + {0x06,0x4c}, + + {0x07,0x00}, + {0x08,0x12}, + + {0x0a,0x00}, + {0x0c,0x04}, + {0x0d,0x04}, + {0x0e,0xc0}, + {0x0f,0x06}, + {0x10,0x50}, + {0x17,0x14}, // mirror + {0x19,0x0b}, + {0x1b,0x48}, + {0x1c,0x12}, + {0x1d,0x10}, + {0x1e,0xbc}, + {0x1f,0xc9}, + {0x20,0x71}, + {0x21,0x20}, + {0x22,0xa0}, + {0x23,0x51}, + {0x24,0x1b}, + {0x27,0x20}, + {0x28,0x00}, + {0x2b,0x80},// 0x81 20140926 + {0x2c,0x38}, + {0x2e,0x16}, + {0x2f,0x14}, + {0x30,0x00}, + {0x31,0x01}, + {0x32,0x02}, + {0x33,0x03}, + {0x34,0x07}, + {0x35,0x0b}, + {0x36,0x0f}, + + ///////////////////////////////////////////////////// + ////////////////////// ISP ///////////////////// + ///////////////////////////////////////////////////// + {0x8c,0x02}, + + ///////////////////////////////////////////////////// + ////////////////////// gain ///////////////////// + ///////////////////////////////////////////////////// + {0xb0,0x50}, + {0xb1,0x01}, + {0xb2,0x00}, + {0xb3,0x40}, + {0xb4,0x40}, + {0xb5,0x40}, + {0xb6,0x00}, + + ///////////////////////////////////////////////////// + /////////////////////// crop ////////////////////// + ///////////////////////////////////////////////////// + {0x92,0x01}, + {0x94,0x05}, + {0x95,0x04}, + {0x96,0xb0}, + {0x97,0x06}, + {0x98,0x40}, + + ///////////////////////////////////////////////////// + /////////////////////// BLK ////////////////////// + ///////////////////////////////////////////////////// + {0x18,0x02}, + {0x1a,0x01}, + {0x40,0x42}, + {0x41,0x00}, + {0x44,0x00}, + {0x45,0x00}, + {0x46,0x00}, + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x00}, + {0x4a,0x00}, + {0x4b,0x00}, + {0x4e,0x3c}, + {0x4f,0x00}, + {0x5e,0x00}, + {0x66,0x20}, + {0x6a,0x02}, + {0x6b,0x02}, + {0x6c,0x02}, + {0x6d,0x02}, + {0x6e,0x02}, + {0x6f,0x02}, + {0x70,0x02}, + {0x71,0x02}, + + ///////////////////////////////////////////////////// + //////////////////// dark sun ///////////////////// + ///////////////////////////////////////////////////// + {0x87,0x03}, + {0xe0,0xe7}, + {0xe3,0xc0}, + + ///////////////////////////////////////////////////// + ////////////////////// DVP /////////////////////// + ///////////////////////////////////////////////////// + {0xfe,0x03}, + {0x01,0x00}, + {0x02,0x00}, + {0x03,0x00}, + {0x06,0x20}, + {0x10,0x00}, + {0x15,0x00}, + {0x40,0x09}, + {0x41,0x00}, + {0x42,0x40}, + {0x43,0x00}, + {0xfe,0x00}, + {0xf2,0x0f}, +}; + + +/* + * Here we'll try to encapsulate the changes for just the output + * video format. + * + + */ + +static struct regval_list sensor_fmt_raw[] = { + +}; + +/* + * Low-level register I/O. + * + */ + + +/* + * On most platforms, we'd rather do straight i2c I/O. + */ +static int sensor_read(struct v4l2_subdev *sd, unsigned char reg, + unsigned char *value) //!!!!be careful of the para type!!! +{ + int ret=0; + int cnt=0; + + ret = cci_read_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_read_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor read retry=%d\n",cnt); + + return ret; +} + +static int sensor_write(struct v4l2_subdev *sd, unsigned char reg, + unsigned char value) +{ + int ret=0; + int cnt=0; + + ret = cci_write_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_write_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor write retry=%d\n",cnt); + + return ret; +} + +/* + * Write a list of register settings; + */ +static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size) +{ + int i=0; + + if(!regs) + return -EINVAL; + + while(iaddr == REG_DLY) { + msleep(regs->data); + } + else { + LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data)) + } + i++; + regs++; + } + return 0; +} + +static int reg_val_show(struct v4l2_subdev *sd,unsigned short reg) +{ + unsigned char tmp; + sensor_read(sd,reg,&tmp); + printk("0x%x value is 0x%x\n",reg,tmp); + return 0; +} + +/* + * Code for dealing with controls. + * fill with different sensor module + * different sensor module has different settings here + * if not support the follow function ,retrun -EINVAL + */ + +/* *********************************************begin of ******************************************** */ +/* +static int sensor_g_hflip(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->hflip; + return 0; +} + +static int sensor_s_hflip(struct v4l2_subdev *sd, int value) +{ + + return 0; +} + +static int sensor_g_vflip(struct v4l2_subdev *sd, __s32 *value) +{ + + return 0; +} + +static int sensor_s_vflip(struct v4l2_subdev *sd, int value) +{ + + + return 0; +}*/ +//static struct regval_list sensor_oe_disable_regs[] = { +//// {0x3002,0x00}, +// //{REG_TERM,VAL_TERM}, +//}; + +/* stuff about exposure when capturing image */ + + + +static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->exp; + vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); + return 0; +} + +static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) +{ + unsigned char explow,expmid,exphigh; + struct sensor_info *info = to_state(sd); + // vfe_dev_dbg("sensor_set_exposure = %d\n", exp_val>>4); + if(exp_val>0xfffff) + exp_val=0xfffff; + + //if(info->exp == exp_val && exp_val <= (2001)*6) + // return 0; + + sensor_write(sd, 0xfe, 0x00); + + #ifdef FRACTION_EXP + exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); + expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); + explow = (unsigned char) ( (0x0000ff&exp_val) ); + sensor_write(sd, EXP_HIGH, exphigh); + #else + exphigh = 0; + expmid = (unsigned char) ( (0x0ff000&exp_val)>>12); + explow = (unsigned char) ( (0x000ff0&exp_val)>>4); + #endif + + sensor_write(sd, EXP_MID, expmid); + sensor_write(sd, EXP_LOW, explow); + //sensor_write(sd, 0x01, 0x01); + //printk("gc2355 sensor_set_exp = %d, Done!\n", exp_val); + + info->exp = exp_val; + return 0; +} + +static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->gain; + vfe_dev_dbg("sensor_get_gain = %d\n", info->gain); + return 0; +} + +static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) +{ + unsigned char temp; + int gain_set; + struct sensor_info *info = to_state(sd); + //printk("gc2235 sensor gain value is %d\n",gain_val); + //gain_val = gain_val * 6; + + sensor_write(sd, 0xfe, 0x00); + sensor_write(sd, 0xb1, 0x01); + sensor_write(sd, 0xb2, 0x00); + + gain_set = gain_val * 4; + + if(gain_set < 0x40) + gain_set = 0x40; + if((ANALOG_GAIN_1<= gain_set)&&(gain_set < ANALOG_GAIN_2)) + { + //analog gain + sensor_write(sd,0xb6, 0x00);// + temp = gain_set; + sensor_write(sd,0xb1, temp>>6); + sensor_write(sd,0xb2, (temp<<2)&0xfc); +// printk("GC2355 analogic gain 1x , add pregain = %d\n",temp); + + } + else if((ANALOG_GAIN_2<= gain_set)&&(gain_set < ANALOG_GAIN_3)) + { + //analog gain + sensor_write(sd,0xb6, 0x01);// + temp = 64*gain_set/ANALOG_GAIN_2; + sensor_write(sd,0xb1, temp>>6); + sensor_write(sd,0xb2, (temp<<2)&0xfc); +// printk("GC2355 analogic gain 1.375x , add pregain = %d\n",temp); + } + + else if((ANALOG_GAIN_3<= gain_set)&&(gain_set < ANALOG_GAIN_4)) + { + //analog gain + sensor_write(sd,0xb6, 0x02);// + temp = 64*gain_set/ANALOG_GAIN_3; + sensor_write(sd,0xb1, temp>>6); + sensor_write(sd,0xb2, (temp<<2)&0xfc); +// printk("GC2355 analogic gain 1.90x , add pregain = %d\n",temp); + } + + else if(ANALOG_GAIN_4<= gain_set) + { + //analog gain + sensor_write(sd,0xb6, 0x03);// + temp = 64*gain_set/ANALOG_GAIN_4; + sensor_write(sd,0xb1, temp>>6); + sensor_write(sd,0xb2, (temp<<2)&0xfc); +// printk("GC2355 analogic gain 2.625x , add pregain = %d\n",temp); + } + + //printk("gc2235 sensor read out gain is %d\n",gain); + info->gain = gain_val; + + return 0; +} + +static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) +{ + int exp_val, gain_val; + struct sensor_info *info = to_state(sd); + + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + //printk("gc2355 sensor read out exp & gain is %d\t%d\n",exp_val, gain_val); + + if(gain_val<1*16) + gain_val=16; + if(gain_val>64*16-1) + gain_val=64*16-1; + + if(exp_val>0xfffff) + exp_val=0xfffff; + + sensor_s_exp(sd,exp_val); + sensor_s_gain(sd,gain_val); + + info->exp = exp_val; + info->gain = gain_val; + return 0; +} + + +/* +static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) +{ + int ret; + unsigned char rdval; + + ret=sensor_read(sd, 0x0100, &rdval); + if(ret!=0) + return ret; + + if(on_off==CSI_STBY_ON)//sw stby on + { + ret=sensor_write(sd, 0x0100, rdval&0xfe); + } + else//sw stby off + { + ret=sensor_write(sd, 0x0100, rdval|0x01); + } + return ret; +} +*/ + +/* + * Stuff that knows about the sensor. + */ + +static int sensor_power(struct v4l2_subdev *sd, int on) +{ + cci_lock(sd); + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON\n"); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(5000,12000); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF\n"); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(5000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(5000,12000); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON\n"); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,IOVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,DVDD,ON); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,AVDD,ON); + usleep_range(10000,12000); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + usleep_range(10000,12000); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF\n"); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + vfe_set_pmu_channel(sd,AVDD,OFF); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,DVDD,OFF); + usleep_range(5000,12000); + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + usleep_range(10000,12000); + vfe_set_mclk(sd,OFF); + usleep_range(5000,12000); + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + break; + default: + return -EINVAL; + } + cci_unlock(sd); + return 0; +} + +static int sensor_reset(struct v4l2_subdev *sd, u32 val) +{ + switch(val) + { + case 0: + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(10000,12000); + break; + case 1: + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(10000,12000); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sensor_detect(struct v4l2_subdev *sd) +{ + unsigned char rdval; + + reg_val_show(sd, 0xf0); + reg_val_show(sd, 0xf1); + + LOG_ERR_RET(sensor_read(sd, ID_REG_HIGH, &rdval)) + if(rdval != ID_VAL_HIGH) + return -ENODEV; + +// printk("gc2355 ID_VAL_HIGH = %2x, Done!\n", rdval); + + LOG_ERR_RET(sensor_read(sd, ID_REG_LOW, &rdval)) + if(rdval != ID_VAL_LOW) + return -ENODEV; + +// printk("gc2355 ID_VAL_LOW = %2x, Done!\n", rdval); + + return 0; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + int ret; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_init\n"); + + /*Make sure it is a target sensor*/ + ret = sensor_detect(sd); + if (ret) { + vfe_dev_err("chip found is not an target chip.\n"); + return ret; + } + + vfe_get_standby_mode(sd,&info->stby_mode); + + if((info->stby_mode == HW_STBY || info->stby_mode == SW_STBY) \ + && info->init_first_flag == 0) { + vfe_dev_print("stby_mode and init_first_flag = 0\n"); + return 0; + } + + info->focus_status = 0; + info->low_speed = 0; + info->width = UXGA_WIDTH; + info->height = UXGA_HEIGHT; + info->hflip = 0; + info->vflip = 0; + info->gain = 0; + + info->tpf.numerator = 1; + info->tpf.denominator = 30; /* 30fps */ + + ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); + if(ret < 0) { + vfe_dev_err("write sensor_default_regs error\n"); + return ret; + } + + if(info->stby_mode == 0) + info->init_first_flag = 0; + + info->preview_first_flag = 1; + + return 0; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + int ret=0; + struct sensor_info *info = to_state(sd); +// vfe_dev_dbg("[]cmd=%d\n",cmd); +// vfe_dev_dbg("[]arg=%0x\n",arg); + switch(cmd) { + case GET_CURRENT_WIN_CFG: + if(info->current_wins != NULL) + { + memcpy( arg, + info->current_wins, + sizeof(struct sensor_win_size) ); + ret=0; + } + else + { + vfe_dev_err("empty wins!\n"); + ret=-1; + } + break; + case SET_FPS: + ret=0; +// if((unsigned int *)arg==1) +// ret=sensor_write(sd, 0x3036, 0x78); +// else +// ret=sensor_write(sd, 0x3036, 0x32); + break; + case ISP_SET_EXP_GAIN: + sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); + break; + default: + return -EINVAL; + } + return ret; +} + + +/* + * Store information about the video data format. + */ +static struct sensor_format_struct { + __u8 *desc; + //__u32 pixelformat; + enum v4l2_mbus_pixelcode mbus_code; + struct regval_list *regs; + int regs_size; + int bpp; /* Bytes per pixel */ +}sensor_formats[] = { + { + .desc = "Raw RGB Bayer", + .mbus_code = V4L2_MBUS_FMT_SBGGR10_1X10, + .regs = sensor_fmt_raw, + .regs_size = ARRAY_SIZE(sensor_fmt_raw), + .bpp = 1 + }, +}; +#define N_FMTS ARRAY_SIZE(sensor_formats) + + + +/* + * Then there is the issue of window sizes. Try to capture the info here. + */ + + +static struct sensor_win_size sensor_win_sizes[] = { + /* UXGA */ + { + .width = UXGA_WIDTH, + .height = UXGA_HEIGHT, + .hoffset = 0, + .voffset = 0, + .hts = 1680, + .vts = 1250,//1073, + .pclk = 42*1000*1000, + .fps_fixed = 1, + .bin_factor = 1, + .intg_min = 1<<4, + .intg_max = 1250<<4, + .gain_min = 1<<4, + .gain_max = (10<<4), + .regs = sensor_uxga_regs, + .regs_size = ARRAY_SIZE(sensor_uxga_regs), + .set_size = NULL, + } +}; + +#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) + +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= N_FMTS) + return -EINVAL; + + *code = sensor_formats[index].mbus_code; + return 0; +} + +static int sensor_enum_size(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + if(fsize->index > N_WIN_SIZES-1) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = sensor_win_sizes[fsize->index].width; + fsize->discrete.height = sensor_win_sizes[fsize->index].height; + + return 0; +} + + +static int sensor_try_fmt_internal(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt, + struct sensor_format_struct **ret_fmt, + struct sensor_win_size **ret_wsize) +{ + int index; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + for (index = 0; index < N_FMTS; index++) + if (sensor_formats[index].mbus_code == fmt->code) + break; + + if (index >= N_FMTS) + return -EINVAL; + + if (ret_fmt != NULL) + *ret_fmt = sensor_formats + index; + + /* + * Fields: the sensor devices claim to be progressive. + */ + + fmt->field = V4L2_FIELD_NONE; + + /* + * Round requested image size down to the nearest + * we support, but not below the smallest. + */ + for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; + wsize++) + if (fmt->width >= wsize->width && fmt->height >= wsize->height) + break; + + if (wsize >= sensor_win_sizes + N_WIN_SIZES) + wsize--; /* Take the smallest one */ + if (ret_wsize != NULL) + *ret_wsize = wsize; + /* + * Note the size we'll actually handle. + */ + fmt->width = wsize->width; + fmt->height = wsize->height; + info->current_wins = wsize; + //pix->bytesperline = pix->width*sensor_formats[index].bpp; + //pix->sizeimage = pix->height*pix->bytesperline; + + return 0; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + return sensor_try_fmt_internal(sd, fmt, NULL, NULL); +} + +static int sensor_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + cfg->type = V4L2_MBUS_PARALLEL; + cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL ; + + return 0; +} + + +/* + * Set a format. + */ +static int sensor_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + int ret; + struct sensor_format_struct *sensor_fmt; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_s_fmt\n"); + + ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); + if (ret) + return ret; + + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } + else if(info->capture_mode == V4L2_MODE_IMAGE) + { + //image + + } + + sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size); + + ret = 0; + if (wsize->regs) + LOG_ERR_RET(sensor_write_array(sd, wsize->regs, wsize->regs_size)) + + if (wsize->set_size) + LOG_ERR_RET(wsize->set_size(sd)) + + info->fmt = sensor_fmt; + info->width = wsize->width; + info->height = wsize->height; + + vfe_dev_print("s_fmt set width = %d, height = %d\n",wsize->width,wsize->height); + + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + + } else { + //capture image + + } + + return 0; +} + +/* + * Implement G/S_PARM. There is a "high quality" mode we could try + * to do someday; for now, we just do the frame rate tweak. + */ +static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + struct sensor_info *info = to_state(sd); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->capturemode = info->capture_mode; + + return 0; +} + +static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + //struct v4l2_fract *tpf = &cp->timeperframe; + struct sensor_info *info = to_state(sd); + //unsigned char div; + + vfe_dev_dbg("sensor_s_parm\n"); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (info->tpf.numerator == 0) + return -EINVAL; + + info->capture_mode = cp->capturemode; + + return 0; +} + + +static int sensor_queryctrl(struct v4l2_subdev *sd, + struct v4l2_queryctrl *qc) +{ + /* Fill in min, max, step and default value for these controls. */ + /* see include/linux/videodev2.h for details */ + + switch (qc->id) { + case V4L2_CID_GAIN: + return v4l2_ctrl_query_fill(qc, 1*16, 32*16, 1, 16); + case V4L2_CID_EXPOSURE: + return v4l2_ctrl_query_fill(qc, 0, 65535*16, 1, 0); + } + return -EINVAL; +} + +static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_g_gain(sd, &ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_g_exp(sd, &ctrl->value); + } + return -EINVAL; +} + +static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc; + int ret; + + qc.id = ctrl->id; + ret = sensor_queryctrl(sd, &qc); + if (ret < 0) { + return ret; + } + + if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) { + return -ERANGE; + } + + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_s_gain(sd, ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_s_exp(sd, ctrl->value); + } + return -EINVAL; +} + + +static int sensor_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SENSOR, 0); +} + + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops sensor_core_ops = { + .g_chip_ident = sensor_g_chip_ident, + .g_ctrl = sensor_g_ctrl, + .s_ctrl = sensor_s_ctrl, + .queryctrl = sensor_queryctrl, + .reset = sensor_reset, + .init = sensor_init, + .s_power = sensor_power, + .ioctl = sensor_ioctl, +}; + +static const struct v4l2_subdev_video_ops sensor_video_ops = { + .enum_mbus_fmt = sensor_enum_fmt, + .enum_framesizes = sensor_enum_size, + .try_mbus_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .s_parm = sensor_s_parm, + .g_parm = sensor_g_parm, + .g_mbus_config = sensor_g_mbus_config, +}; + +static const struct v4l2_subdev_ops sensor_ops = { + .core = &sensor_core_ops, + .video = &sensor_video_ops, +}; + +/* ----------------------------------------------------------------------- */ +static struct cci_driver cci_drv = { + .name = SENSOR_NAME, + .addr_width = CCI_BITS_8, + .data_width = CCI_BITS_8, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct sensor_info *info; +// int ret; + + info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + sd = &info->sd; + glb_sd = sd; + cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); + + info->fmt = &sensor_formats[0]; + info->af_first_flag = 1; + info->init_first_flag = 1; + + return 0; +} + + +static int sensor_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd; + sd = cci_dev_remove_helper(client, &cci_drv); + kfree(to_state(sd)); + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + { SENSOR_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + + +static struct i2c_driver sensor_driver = { + .driver = { + .owner = THIS_MODULE, + .name = SENSOR_NAME, + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; +static __init int init_sensor(void) +{ + return cci_dev_init_helper(&sensor_driver); +} + +static __exit void exit_sensor(void) +{ + cci_dev_exit_helper(&sensor_driver); +} + +module_init(init_sensor); +module_exit(exit_sensor); + diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/h22_mipi.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/h22_mipi.c new file mode 100755 index 00000000..38c8d5b2 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/h22_mipi.c @@ -0,0 +1,1032 @@ +/* + * A V4L2 driver for h22_mipi Raw cameras. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "camera.h" + + +MODULE_AUTHOR("lwj"); +MODULE_DESCRIPTION("A low-level driver for h22_mipi Raw sensors"); +MODULE_LICENSE("GPL"); + +//for internel driver debug +#define DEV_DBG_EN 1 +#if(DEV_DBG_EN == 1) +#define vfe_dev_dbg(x,arg...) printk("[h22_mipi Raw]"x,##arg) +#else +#define vfe_dev_dbg(x,arg...) +#endif +#define vfe_dev_err(x,arg...) printk("[h22_mipi Raw]"x,##arg) +#define vfe_dev_print(x,arg...) printk("[h22_mipi Raw]"x,##arg) + +#define LOG_ERR_RET(x) { \ + int ret; \ + ret = x; \ + if(ret < 0) {\ + vfe_dev_err("error at %s\n",__func__); \ + return ret; \ + } \ + } + +//define module timing +#define MCLK (24*1000*1000) +#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_LOW +#define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH +#define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING +#define V4L2_IDENT_SENSOR 0xa022 + + +//define the voltage level of control signal +#define CSI_STBY_ON 1 +#define CSI_STBY_OFF 0 +#define CSI_RST_ON 0 +#define CSI_RST_OFF 1 +#define CSI_PWR_ON 1 +#define CSI_PWR_OFF 0 +#define CSI_AF_PWR_ON 1 +#define CSI_AF_PWR_OFF 0 +#define regval_list reg_list_a8_d8 +#define REG_DLY 0xff + +//define the registers +#define EXP_HIGH 0xff +#define EXP_MID 0x02 +#define EXP_LOW 0x01 +#define GAIN_HIGH 0xff +#define GAIN_LOW 0x00 +//#define FRACTION_EXP +#define ID_REG_HIGH 0x0a +#define ID_REG_LOW 0x0b +#define ID_VAL_HIGH ((V4L2_IDENT_SENSOR) >> 8) +#define ID_VAL_LOW ((V4L2_IDENT_SENSOR) & 0xff) + +//#define GROUP_WRITE + +/* + *Our nominal (default) frame rate. + */ + +#define SENSOR_FRAME_RATE 30 + + +/* + * The h22_mipi i2c address + */ +#define I2C_ADDR 0x60 +#define SENSOR_NAME "h22_mipi" + +//static struct delayed_work sensor_s_ae_ratio_work; +static struct v4l2_subdev *glb_sd; + +/* + * Information we maintain about a known sensor. + */ +struct sensor_format_struct; /* coming later */ + +struct cfg_array { /* coming later */ + struct regval_list * regs; + int size; +}; + +static inline struct sensor_info *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sensor_info, sd); +} + + +/* + * The default register settings + * + */ + +static struct regval_list sensor_default_regs[] = +{ + {0x12, 0x40}, + {0x1F, 0x00}, + {0x0E, 0x1D}, + {0x0F, 0x09}, + {0x10, 0x20}, + {0x11, 0x80}, + {0x20, 0xDC}, + {0x21, 0x05}, + {0x22, 0x56}, + {0x23, 0x03}, + {0x24, 0x00}, + {0x25, 0xD0}, + {0x26, 0x25}, + {0x27, 0xBB}, + {0x28, 0x0D}, + {0x29, 0x00}, + {0x2A, 0xAC}, + {0x2B, 0x10}, + {0x2C, 0x01}, + {0x2D, 0x0A}, + {0x2E, 0xC2}, + {0x2F, 0x20}, + {0x31, 0x08}, + {0x33, 0x14}, + {0x1D, 0x00}, + {0x1E, 0x00}, + {0x6C, 0x10}, + {0x73, 0x33}, + {0x70, 0x69}, + {0x76, 0x40}, + {0x77, 0x06}, + {0x67, 0x30}, + {0x6D, 0x09}, + {0x13, 0xC7}, + {0x14, 0x80}, + {0x16, 0xC0}, + {0x17, 0x40}, + {0x18, 0x00}, + {0x19, 0x01}, + {0x37, 0x35}, + {0x38, 0x98}, + {0x4a, 0x03}, + {0x49, 0x10}, + {0x69, 0x32}, + {0x0D, 0x58}, + {0x12, 0x00}, + +}; + + +/* + * Here we'll try to encapsulate the changes for just the output + * video format. + * + */ + +static struct regval_list sensor_fmt_raw[] = { + //{REG_TERM,VAL_TERM}, +}; + +/* + * Low-level register I/O. + * + */ +static int sensor_read(struct v4l2_subdev *sd, unsigned char reg, + unsigned char *value) //!!!!be careful of the para type!!! +{ + int ret=0; + int cnt=0; + + ret = cci_read_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_read_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor read retry=%d\n",cnt); + + return ret; +} + +static int sensor_write(struct v4l2_subdev *sd, unsigned char reg, + unsigned char value) +{ + int ret=0; + int cnt=0; + + ret = cci_write_a8_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_write_a8_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor write retry=%d\n",cnt); + + return ret; +} + +/* + * Write a list of register settings; + */ +static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size) +{ + int i=0; + + if(!regs) + return -EINVAL; + + while(iaddr == REG_DLY) { + msleep(regs->data); + } + else { + LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data)) + } + i++; + regs++; + } + return 0; +} + +/* + * Code for dealing with controls. + * fill with different sensor module + * different sensor module has different settings here + * if not support the follow function ,retrun -EINVAL + */ +static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->exp; + vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); + return 0; +} + +static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) +{ + unsigned char explow,expmid,exphigh; + struct sensor_info *info = to_state(sd); + + if(exp_val>0xfffff) + exp_val=0xfffff; + + #ifdef FRACTION_EXP + exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); + expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); + explow = (unsigned char) ( (0x0000ff&exp_val) ); + sensor_write(sd, EXP_HIGH, exphigh); + #else + exphigh = 0; + expmid = (unsigned char) ( (0x0ff000&exp_val)>>12); + explow = (unsigned char) ( (0x000ff0&exp_val)>>4); + #endif + +#ifdef GROUP_WRITE + sensor_write(sd, 0xc0, EXP_MID); + sensor_write(sd, 0xc1, expmid); + sensor_write(sd, 0xc2, EXP_LOW); + sensor_write(sd, 0xc3, explow); +#else + sensor_write(sd, EXP_MID, expmid); + sensor_write(sd, EXP_LOW, explow); +#endif + +// printk("h22_mipi sensor_set_exp = 0x%x 0x%x, Done!\n", expmid, explow); + + info->exp = exp_val; + return 0; +} + +static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->gain; + vfe_dev_dbg("sensor_get_gain = %d\n", info->gain); + return 0; +} + +static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) +{ + struct sensor_info *info = to_state(sd); + unsigned char gainlow=0; + unsigned char gainhigh=0; + unsigned char gainlow_l4b=0; + unsigned int tmp_gain_val=0; + + tmp_gain_val=gain_val; + + //determine ?gain_val>31 + if(tmp_gain_val>31) + { + gainlow |= 0x10; + tmp_gain_val = tmp_gain_val>>1; + } + //determine ?gain_val>2*31 + if(tmp_gain_val>31) + { + gainlow |= 0x20; + tmp_gain_val = tmp_gain_val>>1; + } + //determine ?gain_val>4*31 + if(tmp_gain_val>31) + { + gainlow |= 0x40; + tmp_gain_val = tmp_gain_val>>1; + } + //determine ?gain_val>8*31 + if(tmp_gain_val>31) + { + gainlow |= 0x80; + tmp_gain_val = tmp_gain_val>>1; + } + //determine ?gain_val>16*31 + if(tmp_gain_val>31) + { + gainhigh = 0x01; + tmp_gain_val = tmp_gain_val>>1; + } + + if(tmp_gain_val>=16) + gainlow_l4b=((tmp_gain_val-16)&0x0f); + + gainlow = gainlow | gainlow_l4b; + +#ifdef GROUP_WRITE + sensor_write(sd, 0xc4, 0x00); + sensor_write(sd, 0xc5, gainlow); +#else + sensor_write(sd, GAIN_LOW, gainlow); +#endif + + info->gain = gain_val; + + return 0; +} + + +static int h22_sensor_vts; +static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) +{ + int exp_val, gain_val; + struct sensor_info *info = to_state(sd); + unsigned char rdval; + + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + +// printk("h22 sensor exp & gain is %d\t%d\n", exp_val, gain_val); + + if(gain_val<1*16) + gain_val=16; + if(gain_val>64*16-1) + gain_val=64*16-1; + + if(exp_val>0xfffff) + exp_val=0xfffff; + + LOG_ERR_RET(sensor_read(sd, 0x12, &rdval)) + rdval &= 0xF7; + sensor_write(sd, 0x12, rdval); + + sensor_s_exp(sd,exp_val); + sensor_s_gain(sd,gain_val); + + LOG_ERR_RET(sensor_read(sd, 0x12, &rdval)) + rdval |= 0x08; + sensor_write(sd, 0x12, rdval); + + info->exp = exp_val; + info->gain = gain_val; + return 0; +} + + +/* +static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) +{ + int ret; + unsigned char rdval; + + ret=sensor_read(sd, 0x0100, &rdval); + if(ret!=0) + return ret; + + if(on_off==CSI_STBY_ON)//sw stby on + { + ret=sensor_write(sd, 0x0100, rdval&0xfe); + } + else//sw stby off + { + ret=sensor_write(sd, 0x0100, rdval|0x01); + } + return ret; +} +*/ + +/* + * Stuff that knows about the sensor. + */ + +static int sensor_power(struct v4l2_subdev *sd, int on) +{ + int ret; + + //insure that clk_disable() and clk_enable() are called in pair + //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF + ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + //disable io oe + // vfe_dev_print("disalbe oe!\n"); + //ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); + // if(ret < 0) + // vfe_dev_err("disalbe oe falied!\n"); + //software standby on + //ret = sensor_s_sw_stby(sd, CSI_STBY_ON); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); +// //reset on io +// vfe_gpio_write(sd,RESET,CSI_RST_ON); +// usleep_range(10000,12000); + //standby on io + vfe_gpio_write(sd,PWDN,CSI_STBY_ON); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + //inactive mclk after stadby in +// vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //active mclk before stadby out + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + //standby off io + vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); + + usleep_range(10000,12000); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + //software standby + // ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); + // if(ret < 0) + // vfe_dev_err("soft stby off falied!\n"); + usleep_range(10000,12000); + // vfe_dev_print("enable oe!\n"); + // ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); + // if(ret < 0) + // vfe_dev_err("enable oe falied!\n"); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //power on reset + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + //power down io + vfe_gpio_write(sd,PWDN,CSI_STBY_ON); + //reset on io + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(1000,1200); + + //power supply + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,IOVDD,ON); + vfe_set_pmu_channel(sd,AVDD,ON); + //active mclk before power on + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + //vfe_set_pmu_channel(sd,AFVDD,ON); + //standby off io + vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); + usleep_range(10000,12000); + //reset after power on + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(30000,31000); + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + //make sure that no device can access i2c bus during sensor initial or power down + //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter + cci_lock(sd); + //inactive mclk before power off + vfe_set_mclk(sd,OFF); + //power supply off + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + //vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,AVDD,OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + //standby and reset io + usleep_range(10000,12000); + vfe_gpio_write(sd,POWER_EN,CSI_STBY_OFF); + vfe_gpio_write(sd,RESET,CSI_RST_ON); + //set the io to hi-z + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + //remember to unlock i2c adapter, so the device can access the i2c bus again + cci_unlock(sd); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sensor_reset(struct v4l2_subdev *sd, u32 val) +{ + switch(val) + { + case 0: + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(10000,12000); + break; + case 1: + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(10000,12000); + break; + default: + return -EINVAL; + } + return 0; +} + +static int sensor_detect(struct v4l2_subdev *sd) +{ + unsigned char rdval; + + LOG_ERR_RET(sensor_read(sd, ID_REG_HIGH, &rdval)) + vfe_dev_dbg("h22_mipi ID_VAL_HIGH = %2x, Done!\n", rdval); + if(rdval != ID_VAL_HIGH) + return -ENODEV; + + + LOG_ERR_RET(sensor_read(sd, ID_REG_LOW, &rdval)) + vfe_dev_dbg("h22_mipi ID_VAL_LOW = %2x, Done!\n", rdval); + if(rdval != ID_VAL_LOW) + return -ENODEV; + + return 0; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + int ret; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_init\n"); + + /*Make sure it is a target sensor*/ + ret = sensor_detect(sd); + if (ret) { + vfe_dev_err("chip found is not an target chip.\n"); + return ret; + } + vfe_get_standby_mode(sd,&info->stby_mode); + + if((info->stby_mode == HW_STBY || info->stby_mode == SW_STBY) \ + && info->init_first_flag == 0) { + vfe_dev_print("stby_mode and init_first_flag = 0\n"); + return 0; + } + + info->focus_status = 0; + info->low_speed = 0; + info->width = HD720_WIDTH; + info->height = HD720_HEIGHT; + info->hflip = 0; + info->vflip = 0; + info->gain = 0; + + info->tpf.numerator = 1; + info->tpf.denominator = 30; /* 30fps */ + + ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); + if(ret < 0) { + vfe_dev_err("write sensor_default_regs error\n"); + return ret; + } + if(info->stby_mode == 0) + info->init_first_flag = 0; + info->preview_first_flag = 1; + return 0; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + int ret=0; + struct sensor_info *info = to_state(sd); + switch(cmd) { + case GET_CURRENT_WIN_CFG: + if(info->current_wins != NULL) + { + memcpy( arg, + info->current_wins, + sizeof(struct sensor_win_size) ); + ret=0; + } + else + { + vfe_dev_err("empty wins!\n"); + ret=-1; + } + break; + case SET_FPS: + ret=0; + break; + case ISP_SET_EXP_GAIN: + ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); + break; + default: + return -EINVAL; + } + return ret; +} + + +/* + * Store information about the video data format. + */ +static struct sensor_format_struct { + __u8 *desc; + //__u32 pixelformat; + enum v4l2_mbus_pixelcode mbus_code; + struct regval_list *regs; + int regs_size; + int bpp; /* Bytes per pixel */ +}sensor_formats[] = { + { + .desc = "Raw RGB Bayer", + .mbus_code = V4L2_MBUS_FMT_SBGGR10_10X1, + .regs = sensor_fmt_raw, + .regs_size = ARRAY_SIZE(sensor_fmt_raw), + .bpp = 1 + }, +}; +#define N_FMTS ARRAY_SIZE(sensor_formats) + +/* + * Then there is the issue of window sizes. Try to capture the info here. + */ +static struct sensor_win_size sensor_win_sizes[] = { + /* qsxga: 2304*1296 */ + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 0, + .voffset = 0, + .hts = 1500, + .vts = 854, + .pclk = 38400000, + .mipi_bps = 384*1000*1000, + .fps_fixed = 1, + .bin_factor = 1, + .intg_min = 1<<4, + .intg_max = (854-4)<<4,// + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .regs = sensor_default_regs, + .regs_size = ARRAY_SIZE(sensor_default_regs), + .set_size = NULL, + }, + +}; + +#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) + +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= N_FMTS) + return -EINVAL; + + *code = sensor_formats[index].mbus_code; + return 0; +} + +static int sensor_enum_size(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + if(fsize->index > N_WIN_SIZES-1) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = sensor_win_sizes[fsize->index].width; + fsize->discrete.height = sensor_win_sizes[fsize->index].height; + + return 0; +} + +static int sensor_try_fmt_internal(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt, + struct sensor_format_struct **ret_fmt, + struct sensor_win_size **ret_wsize) +{ + int index; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + for (index = 0; index < N_FMTS; index++) + if (sensor_formats[index].mbus_code == fmt->code) + break; + + if (index >= N_FMTS) + return -EINVAL; + + if (ret_fmt != NULL) + *ret_fmt = sensor_formats + index; + + /* + * Fields: the sensor devices claim to be progressive. + */ + + fmt->field = V4L2_FIELD_NONE; + + /* + * Round requested image size down to the nearest + * we support, but not below the smallest. + */ + for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; + wsize++) + if (fmt->width >= wsize->width && fmt->height >= wsize->height) + break; + + if (wsize >= sensor_win_sizes + N_WIN_SIZES) + wsize--; /* Take the smallest one */ + if (ret_wsize != NULL) + *ret_wsize = wsize; + /* + * Note the size we'll actually handle. + */ + fmt->width = wsize->width; + fmt->height = wsize->height; + info->current_wins = wsize; + //pix->bytesperline = pix->width*sensor_formats[index].bpp; + //pix->sizeimage = pix->height*pix->bytesperline; + + return 0; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + return sensor_try_fmt_internal(sd, fmt, NULL, NULL); +} + +static int sensor_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + cfg->type = V4L2_MBUS_CSI2; + cfg->flags = 0|V4L2_MBUS_CSI2_1_LANE|V4L2_MBUS_CSI2_CHANNEL_0; + + return 0; +} + + +/* + * Set a format. + */ +static int sensor_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + int ret; + struct sensor_format_struct *sensor_fmt; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_s_fmt\n"); + // sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); + ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); + if (ret) + return ret; + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } + else if(info->capture_mode == V4L2_MODE_IMAGE) + { + //image + } + LOG_ERR_RET(sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size)) + ret = 0; + if (wsize->regs) + LOG_ERR_RET(sensor_write_array(sd, wsize->regs, wsize->regs_size)) + if (wsize->set_size) + LOG_ERR_RET(wsize->set_size(sd)) + + info->fmt = sensor_fmt; + info->width = wsize->width; + info->height = wsize->height; + h22_sensor_vts = wsize->vts; + // show_regs_array(sd,sensor_1080p_regs); + + vfe_dev_print("s_fmt set width = %d, height = %d\n",wsize->width,wsize->height); + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } else { + //capture image + } + //sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); + return 0; +} + +/* + * Implement G/S_PARM. There is a "high quality" mode we could try + * to do someday; for now, we just do the frame rate tweak. + */ +static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + struct sensor_info *info = to_state(sd); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->capturemode = info->capture_mode; + + return 0; +} + +static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + //struct v4l2_fract *tpf = &cp->timeperframe; + struct sensor_info *info = to_state(sd); + //unsigned char div; + + vfe_dev_dbg("sensor_s_parm\n"); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (info->tpf.numerator == 0) + return -EINVAL; + + info->capture_mode = cp->capturemode; + + return 0; +} + + +static int sensor_queryctrl(struct v4l2_subdev *sd, + struct v4l2_queryctrl *qc) +{ + /* Fill in min, max, step and default value for these controls. */ + /* see include/linux/videodev2.h for details */ + + switch (qc->id) { + case V4L2_CID_GAIN: + return v4l2_ctrl_query_fill(qc, 1*16, 32*16, 1, 16); + case V4L2_CID_EXPOSURE: + return v4l2_ctrl_query_fill(qc, 0, 65535*16, 1, 0); + } + return -EINVAL; +} + +static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_g_gain(sd, &ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_g_exp(sd, &ctrl->value); + } + return -EINVAL; +} + +static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc; + int ret; + + qc.id = ctrl->id; + ret = sensor_queryctrl(sd, &qc); + if (ret < 0) { + return ret; + } + + if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) { + return -ERANGE; + } + + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_s_gain(sd, ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_s_exp(sd, ctrl->value); + } + return -EINVAL; +} + + +static int sensor_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SENSOR, 0); +} + + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops sensor_core_ops = { + .g_chip_ident = sensor_g_chip_ident, + .g_ctrl = sensor_g_ctrl, + .s_ctrl = sensor_s_ctrl, + .queryctrl = sensor_queryctrl, + .reset = sensor_reset, + .init = sensor_init, + .s_power = sensor_power, + .ioctl = sensor_ioctl, +}; + +static const struct v4l2_subdev_video_ops sensor_video_ops = { + .enum_mbus_fmt = sensor_enum_fmt, + .enum_framesizes = sensor_enum_size, + .try_mbus_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .s_parm = sensor_s_parm, + .g_parm = sensor_g_parm, + .g_mbus_config = sensor_g_mbus_config, +}; + +static const struct v4l2_subdev_ops sensor_ops = { + .core = &sensor_core_ops, + .video = &sensor_video_ops, +}; + +/* ----------------------------------------------------------------------- */ +static struct cci_driver cci_drv = { + .name = SENSOR_NAME, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct sensor_info *info; + + info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + sd = &info->sd; + glb_sd = sd; + cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); + + info->fmt = &sensor_formats[0]; + info->af_first_flag = 1; + info->init_first_flag = 1; + + return 0; +} + + +static int sensor_remove(struct i2c_client *client) +{ + struct v4l2_subdev * sd; + + sd = cci_dev_remove_helper(client, &cci_drv); + kfree(to_state(sd)); + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + { SENSOR_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + + +static struct i2c_driver sensor_driver = { + .driver = { + .owner = THIS_MODULE, + .name = SENSOR_NAME, + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; +static __init int init_sensor(void) +{ + return cci_dev_init_helper(&sensor_driver); +} + +static __exit void exit_sensor(void) +{ + cci_dev_exit_helper(&sensor_driver); +} + +module_init(init_sensor); +module_exit(exit_sensor); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/hm5065.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/hm5065.c index 2d62c370..2940c3a4 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/hm5065.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/hm5065.c @@ -50,8 +50,8 @@ MODULE_LICENSE("GPL"); #define V4L2_IDENT_SENSOR 0x039E //define the voltage level of control signal -#define CSI_STBY_ON 1 -#define CSI_STBY_OFF 0 +#define CSI_STBY_ON 0 +#define CSI_STBY_OFF 1 #define CSI_RST_ON 0 #define CSI_RST_OFF 1 #define CSI_PWR_ON 1 @@ -3021,7 +3021,7 @@ static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, while(iaddr == REG_DLY) { - mdelay(regs->data); + msleep(regs->data); } else { //printk("write 0x%x=0x%x\n", regs->addr, regs->data); @@ -3104,7 +3104,7 @@ static int sensor_download_af_fw(struct v4l2_subdev *sd) } //download af fw - ret =sensor_write_continuous(sd, 0x8000, sensor_af_fw_regs, ARRAY_SIZE(sensor_af_fw_regs)); + ret =cci_write_a16_d8_continuous_helper(sd, 0x8000, sensor_af_fw_regs, ARRAY_SIZE(sensor_af_fw_regs)); if(ret < 0) { vfe_dev_err("download af fw error\n"); return ret; @@ -3173,7 +3173,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) return V4L2_AUTO_FOCUS_STATUS_REACHED; } - return V4L2_AUTO_FOCUS_STATUS_FAILED; + return V4L2_AUTO_FOCUS_STATUS_BUSY; } static int sensor_g_contin_af(struct v4l2_subdev *sd) @@ -3190,12 +3190,12 @@ static int sensor_g_contin_af(struct v4l2_subdev *sd) sensor_read(sd, 0x07AE, &rdval); if(rdval==0) { -// vfe_dev_print("Contin AF focus fail, 0x3028 = 0x%x\n",rdval); - return V4L2_AUTO_FOCUS_STATUS_FAILED; + vfe_dev_print("Contin AF focus fail, 0x3028 = 0x%x\n",rdval); + return V4L2_AUTO_FOCUS_STATUS_BUSY; } else { -// vfe_dev_dbg("Contin AF focus ok, 0x3028 = 0x%x\n",rdval); + vfe_dev_dbg("Contin AF focus ok, 0x3028 = 0x%x\n",rdval); return V4L2_AUTO_FOCUS_STATUS_REACHED; } @@ -3206,10 +3206,10 @@ static int sensor_g_af_status(struct v4l2_subdev *sd) int ret=0; struct sensor_info *info = to_state(sd); - if(info->auto_focus==1) + //if(info->auto_focus==1) ret = sensor_g_contin_af(sd); - else - ret = sensor_g_single_af(sd); + //else + // ret = sensor_g_single_af(sd); return ret; } @@ -3309,13 +3309,14 @@ static int sensor_s_release_af(struct v4l2_subdev *sd) return 0; } -static int sensor_s_af_zone(struct v4l2_subdev *sd, unsigned int xc, unsigned int yc) +static int sensor_s_af_zone(struct v4l2_subdev *sd, + struct v4l2_win_coordinate * win_c) { struct sensor_info *info = to_state(sd); - int ret; + int ret,xc,yc; vfe_dev_print("sensor_s_af_zone\n"); - vfe_dev_dbg("af zone input xc=%d,yc=%d\n",xc,yc); + //sensor_s_single_af(sd); return 0;//gong if(info->width == 0 || info->height == 0) { vfe_dev_err("current width or height is zero!\n"); @@ -4129,8 +4130,8 @@ static int sensor_power(struct v4l2_subdev *sd, int on) //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling cci_unlock cci_lock(sd); //power on reset - // vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - // vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output //power down io vfe_gpio_write(sd,PWDN,CSI_STBY_ON); //reset on io @@ -4174,8 +4175,8 @@ static int sensor_power(struct v4l2_subdev *sd, int on) vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); vfe_gpio_write(sd,RESET,CSI_RST_ON); //set the io to hi-z - // vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - // vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input //remember to unlock i2c adapter, so the device can access the i2c bus again cci_unlock(sd); break; @@ -5015,15 +5016,15 @@ static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUTO_FOCUS_RELEASE: return sensor_s_release_af(sd); case V4L2_CID_AUTO_FOCUS_START: - return sensor_s_single_af(sd); + return sensor_s_continueous_af(sd); case V4L2_CID_AUTO_FOCUS_STOP: return sensor_s_pause_af(sd); case V4L2_CID_AUTO_FOCUS_STATUS: case V4L2_CID_FOCUS_AUTO: return sensor_s_continueous_af(sd); - // case V4L2_CID_AUTO_FOCUS_WIN_NUM: - // vfe_dev_dbg("s_ctrl win value=%d\n",ctrl->value); - // pix = (struct v4l2_pix_size*)ctrl->user_pt; + case V4L2_CID_AUTO_FOCUS_WIN_NUM: + vfe_dev_dbg("s_ctrl win value=%d\n",ctrl->value); + return sensor_s_af_zone(sd, (struct v4l2_win_coordinate *)(ctrl->user_pt)); // return sensor_s_af_zone(sd,pix->width,pix->height); case V4L2_CID_AUTO_EXPOSURE_WIN_NUM: return 0; diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov2710_mipi.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov2710_mipi.c index 4f839efe..87c8cc29 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov2710_mipi.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov2710_mipi.c @@ -1046,6 +1046,8 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, info->fmt = sensor_fmt; info->width = wsize->width; info->height = wsize->height; + info->exp = 0; + info->gain = 0; ov2710_sensor_vts = wsize->vts; vfe_dev_print("s_fmt set width = %d, height = %d\n",wsize->width,wsize->height); diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689.c index c3fabb08..7bc6ec04 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689.c @@ -105,7 +105,7 @@ static inline struct sensor_info *to_state(struct v4l2_subdev *sd) static struct regval_list sensor_default_regs[] = { {0x0103, 0x01},// ; software reset - //{REG_DLY,0x05}, + {REG_DLY,0x05}, {0x3638, 0x00},// ; ADC & analog {0x0300, 0x00},// ; PLL1 prediv {0x0302, 0x1c},// ; PLL1 divm @@ -521,6 +521,40 @@ static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); return 0; } +static int sensor_s_win_off(struct v4l2_subdev *sd, struct sensor_win_off *win_off) +{ + int reg_h_off, reg_v_off, hor_total, ver_total,h_star=0,h_end=0,v_star=0,v_end=0; + int hor_off_total, ver_off_total; + unsigned char val1=0, val2 = 0; + struct sensor_info *info = to_state(sd); + + sensor_read(sd, 0x3800, &val1); + sensor_read(sd, 0x3801, &val2); + h_star = ((val1&0x1f)<<8)+val2; + sensor_read(sd, 0x3804, &val1); + sensor_read(sd, 0x3805, &val2); + h_end = ((val1&0x1f)<<8)+val2; + + sensor_read(sd, 0x3802, &val1); + sensor_read(sd, 0x3803, &val2); + v_star = ((val1&0x1f)<<8)+val2; + sensor_read(sd, 0x3806, &val1); + sensor_read(sd, 0x3807, &val2); + v_end = ((val1&0x1f)<<8)+val2; + hor_total = h_end - h_star; + ver_total = v_end - v_star; + + hor_off_total = hor_total - info->width; + ver_off_total = ver_total - info->height; + reg_h_off = CLIP(hor_off_total/2 + win_off->hor_off*hor_off_total/200, 0, 1000); + reg_v_off = CLIP(ver_off_total/2 + win_off->ver_off*ver_off_total/200, 0, 1000); + //printk("hor_off_total = %d, %d, reg_h_off = %d, %d\n",hor_off_total, ver_off_total,reg_h_off , reg_v_off); + sensor_write(sd, 0x3810, (reg_h_off>>8)&0x1f); + sensor_write(sd, 0x3811, reg_h_off&0xfe); + sensor_write(sd, 0x3812, (reg_v_off>>8)&0x1f); + sensor_write(sd, 0x3813, reg_v_off&0xfe); + return 0; +} int ov4689_sensor_vts ; static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) { @@ -743,121 +777,85 @@ static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - ret = 0; - switch(on) - { - case CSI_SUBDEV_STBY_ON: - vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); -// //disable io oe -// vfe_dev_print("disalbe oe!\n"); -// ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); -// if(ret < 0) -// vfe_dev_err("disalbe oe falied!\n"); - //software standby on - ret = sensor_s_sw_stby(sd, CSI_STBY_ON); - if(ret < 0) - vfe_dev_err("soft stby falied!\n"); - usleep_range(10000,12000); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //standby on io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //inactive mclk after stadby in - vfe_set_mclk(sd,OFF); - break; - case CSI_SUBDEV_STBY_OFF: - vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); -// //software standby -// ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); -// if(ret < 0) -// vfe_dev_err("soft stby off falied!\n"); -// mdelay(10); -// vfe_dev_print("enable oe!\n"); -// ret = sensor_write_array(sd, sensor_oe_enable_regs); -// if(ret < 0) -// vfe_dev_err("enable oe falied!\n"); - break; - case CSI_SUBDEV_PWR_ON: - vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //power on reset - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - //power down io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(1000,1200); - //active mclk before power on - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //power supply - vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,AFVDD,ON); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //reset after power on - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(30000,31000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - case CSI_SUBDEV_PWR_OFF: - vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //inactive mclk before power off - vfe_set_mclk(sd,OFF); - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - vfe_set_pmu_channel(sd,AFVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - //standby and reset io - usleep_range(10000,12000); - vfe_gpio_write(sd,POWER_EN,CSI_STBY_OFF); - vfe_gpio_write(sd,RESET,CSI_RST_ON); - //set the io to hi-z - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - default: - return -EINVAL; - } + int ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,POWER_EN,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_set_pmu_channel(sd,IOVDD,ON); + usleep_range(10000,12000); + + vfe_set_pmu_channel(sd,AVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); + vfe_set_mclk(sd,OFF); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,AVDD,OFF); + + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,IOVDD,OFF); + usleep_range(10000,12000); + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + vfe_gpio_set_status(sd,POWER_EN,0);//set the gpio to input + cci_unlock(sd); + break; + default: + return -EINVAL; + } - return 0; + return 0; } static int sensor_reset(struct v4l2_subdev *sd, u32 val) @@ -972,6 +970,9 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case ISP_SET_EXP_GAIN: ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); break; + case ISP_SET_WIN_OFF: + ret = sensor_s_win_off(sd, (struct sensor_win_off *)arg); + break; default: return -EINVAL; } @@ -1028,7 +1029,27 @@ static struct sensor_win_size sensor_win_sizes[] = { .regs_size = ARRAY_SIZE(sensor_quxga_regs), .set_size = NULL, }, - /* 2688*1520 */ + /* 2048*1520 for 4:3 capture */ + { + .width = 2048, + .height = 1520, + .hoffset = 320, + .voffset = 0, + .hts = 2576, + .vts = 1554,//2480, + .pclk = 120*1000*1000, + .mipi_bps = 720*1000*1000, + .fps_fixed = 2, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (1554-4)<<4, + .gain_min = 1<<4, + .gain_max = (12<<4)-1, + .regs = sensor_quxga_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_regs), + .set_size = NULL, + }, + /* 2304*1296 */ { .width = 2304,//QUXGA_WIDTH,//3280, .height = 1296,//QUXGA_HEIGHT,//2464, diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_60fps.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_60fps.c index 93503cc8..75a8033b 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_60fps.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_60fps.c @@ -763,121 +763,85 @@ static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - ret = 0; - switch(on) - { - case CSI_SUBDEV_STBY_ON: - vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); -// //disable io oe -// vfe_dev_print("disalbe oe!\n"); -// ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); -// if(ret < 0) -// vfe_dev_err("disalbe oe falied!\n"); - //software standby on - ret = sensor_s_sw_stby(sd, CSI_STBY_ON); - if(ret < 0) - vfe_dev_err("soft stby falied!\n"); - usleep_range(10000,12000); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //standby on io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //inactive mclk after stadby in - vfe_set_mclk(sd,OFF); - break; - case CSI_SUBDEV_STBY_OFF: - vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); -// //software standby -// ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); -// if(ret < 0) -// vfe_dev_err("soft stby off falied!\n"); -// mdelay(10); -// vfe_dev_print("enable oe!\n"); -// ret = sensor_write_array(sd, sensor_oe_enable_regs); -// if(ret < 0) -// vfe_dev_err("enable oe falied!\n"); - break; - case CSI_SUBDEV_PWR_ON: - vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //power on reset - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - //power down io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(1000,1200); - //active mclk before power on - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //power supply - vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,AFVDD,ON); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //reset after power on - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(30000,31000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - case CSI_SUBDEV_PWR_OFF: - vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //inactive mclk before power off - vfe_set_mclk(sd,OFF); - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - vfe_set_pmu_channel(sd,AFVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - //standby and reset io - usleep_range(10000,12000); - vfe_gpio_write(sd,POWER_EN,CSI_STBY_OFF); - vfe_gpio_write(sd,RESET,CSI_RST_ON); - //set the io to hi-z - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - default: - return -EINVAL; - } + int ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,POWER_EN,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_set_pmu_channel(sd,IOVDD,ON); + usleep_range(10000,12000); + + vfe_set_pmu_channel(sd,AVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); + vfe_set_mclk(sd,OFF); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,AVDD,OFF); + + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,IOVDD,OFF); + usleep_range(10000,12000); + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + vfe_gpio_set_status(sd,POWER_EN,0);//set the gpio to input + cci_unlock(sd); + break; + default: + return -EINVAL; + } - return 0; + return 0; } static int sensor_reset(struct v4l2_subdev *sd, u32 val) @@ -1047,6 +1011,26 @@ static struct sensor_win_size sensor_win_sizes[] = { .regs = sensor_quxga_25fps_regs, .regs_size = ARRAY_SIZE(sensor_quxga_25fps_regs), .set_size = NULL, + }, + /* 2048*1520 for 4:3 capture */ + { + .width = 2048, + .height = 1520, + .hoffset = 320, + .voffset = 0, + .hts = 1288, + .vts = 3727, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 2, + .bin_factor = 1, + .intg_min = 16, + .intg_max =(3727-4)<<4, + .gain_min = 1<<4, + .gain_max = (12<<4)-1, + .regs = sensor_quxga_25fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_25fps_regs), + .set_size = NULL, }, { .width = 2560, diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_sdv.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_sdv.c new file mode 100755 index 00000000..64f95674 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov4689_sdv.c @@ -0,0 +1,1923 @@ +/* + * A V4L2 driver for ov4689 cameras. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "camera.h" + + +MODULE_AUTHOR("Chomoly"); +MODULE_DESCRIPTION("A low-level driver for ov4689 sensors"); +MODULE_LICENSE("GPL"); + +//for internel driver debug +#define DEV_DBG_EN 0 +#if(DEV_DBG_EN == 1) +#define vfe_dev_dbg(x,arg...) printk("[ov4689_sdv]"x,##arg) +#else +#define vfe_dev_dbg(x,arg...) +#endif +#define vfe_dev_err(x,arg...) printk("[ov4689_sdv]"x,##arg) +#define vfe_dev_print(x,arg...) printk("[ov4689_sdv]"x,##arg) + +#define LOG_ERR_RET(x) { \ + int ret; \ + ret = x; \ + if(ret < 0) {\ + vfe_dev_err("error at %s\n",__func__); \ + return ret; \ + } \ + } + +//define module timing +#define MCLK (24*1000*1000) +#define VREF_POL V4L2_MBUS_VSYNC_ACTIVE_HIGH +#define HREF_POL V4L2_MBUS_HSYNC_ACTIVE_HIGH +#define CLK_POL V4L2_MBUS_PCLK_SAMPLE_RISING +#define V4L2_IDENT_SENSOR 0x4689 + +//#define QSXGA_12FPS + +//define the voltage level of control signal +#define CSI_STBY_ON 0 +#define CSI_STBY_OFF 1 +#define CSI_RST_ON 0 +#define CSI_RST_OFF 1 +#define CSI_PWR_ON 1 +#define CSI_PWR_OFF 0 +#define CSI_AF_PWR_ON 1 +#define CSI_AF_PWR_OFF 0 +#define regval_list reg_list_a16_d8 + + +#define REG_TERM 0xfffe +#define VAL_TERM 0xfe +#define REG_DLY 0xffff + +#define DGAIN_R (0x0888) +#define DGAIN_G (0x0400) +#define DGAIN_B (0x063d) + +/* + * Our nominal (default) frame rate. + */ + +#define SENSOR_FRAME_RATE 30 + + +/* + * The ov4689 sits on i2c with ID 0x42 + */ +#define I2C_ADDR 0x42 +#define SENSOR_NAME "ov4689_sdv" +//static struct delayed_work sensor_s_ae_ratio_work; +static struct v4l2_subdev *glb_sd; + +/* + * Information we maintain about a known sensor. + */ +struct sensor_format_struct; /* coming later */ + +struct cfg_array { /* coming later */ + struct regval_list * regs; + int size; +}; + +static inline struct sensor_info *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct sensor_info, sd); +} + + +/* + * The default register settings + * + */ + + +static struct regval_list sensor_default_regs[] = { + {0x0103, 0x01},// ; software reset + {REG_DLY,0x05}, + {0x3638, 0x00},// ; ADC & analog + {0x0300, 0x00},// ; PLL1 prediv + {0x0302, 0x1c},// ; PLL1 divm + {0x0304, 0x03},// ; PLL1 div mipi + {0x030b, 0x00},// ; PLL2 pre div + {0x030d, 0x1e},// ; PLL2 multiplier + {0x030e, 0x04},// ; PLL2 divs + {0x030f, 0x01},// ; PLL2 divsp + {0x0312, 0x01},// ; PLL2 divdac + {0x031e, 0x00},// ; Debug mode + {REG_DLY,0x15}, + {0x3000, 0x20},// ; FSIN output + {0x3002, 0x00},// ; Vsync input, HREF input, FREX input, GPIO0 input + {0x3018, 0x72},// ; MIPI 4 lane, Reset MIPI PHY when sleep + {0x3020, 0x93},// ; Clock switch to PLL clock, Debug mode + {0x3021, 0x03},// ; Sleep latch, software standby at line blank + {0x3022, 0x01},// ; LVDS disable, Enable power down MIPI when sleep + {0x3031, 0x0a},// ; MIPI 10-bit mode + {0x303f, 0x0c}, + {0x3305, 0xf1},// ; ASRAM + {0x3307, 0x04},// ; ASRAM + {0x3309, 0x29},// ; ASRAM + {0x3500, 0x00},// ; Long exposure HH + {0x3501, 0x60},// ; Long exposure H + {0x3502, 0x00},// ; Long exposure L + {0x3503, 0x04},// ; Gain delay 1 frame, use sensor gain, exposure delay 1 frame + {0x3504, 0x00},// ; debug mode + {0x3505, 0x00},// ; debug mode + {0x3506, 0x00},// ; debug mode + {0x3507, 0x00},// ; Long gain HH + {0x3508, 0x00},// ; Long gain H + {0x3509, 0x80},// ; Long gain L + {0x350a, 0x00},// ; Middle exposure HH + {0x350b, 0x00},// ; Middle exposure H + {0x350c, 0x00},// ; Middle exposure L + {0x350d, 0x00},// ; Middle gain HH + {0x350e, 0x00},// ; Middle gain H + {0x350f, 0x80},// ; Middle gain L + {0x3510, 0x00},// ; Short exposure HH + {0x3511, 0x00},// ; Short exposure H + {0x3512, 0x00},// ; Short exposure L + {0x3513, 0x00},// ; Short gain HH + {0x3514, 0x00},// ; Short gain H + {0x3515, 0x80},// ; Short gain L + {0x3516, 0x00},// ; 4th exposure HH + {0x3517, 0x00},// ; 4th exposure H + {0x3518, 0x00},// ; 4th exposure L + {0x3519, 0x00},// ; 4th gain HH + {0x351a, 0x00},// ; 4th gain H + {0x351b, 0x80},// ; 4th gian L + {0x351c, 0x00},// ; 5th exposure HH + {0x351d, 0x00},// ; 5th exposure H + {0x351e, 0x00},// ; 5th exposure L + {0x351f, 0x00},// ; 5th gain HH + {0x3520, 0x00},// ; 5th gain H + {0x3521, 0x80},// ; 5th gain L + {0x3522, 0x08},// ; Middle digital fraction gain H + {0x3524, 0x08},// ; Short digital fraction gain H + {0x3526, 0x08},// ; 4th digital fraction gain H + {0x3528, 0x08},// ; 5th digital framction gain H + {0x352a, 0x08},// ; Long digital fraction gain H + {0x3602, 0x00},// ; ADC & analog + {0x3604, 0x02},// ; + {0x3605, 0x00},// ; + {0x3606, 0x00},// ; + {0x3607, 0x00},// ; + {0x3609, 0x12},// ; + {0x360a, 0x40},// ; + {0x360c, 0x08},// ; + {0x360f, 0xe5},// ; + {0x3608, 0x8f},// ; + {0x3611, 0x00},// ; + {0x3613, 0xf7},// ; + {0x3616, 0x58},// ; + {0x3619, 0x99},// ; + {0x361b, 0x60},// ; + {0x361c, 0x7a},// ; + {0x361e, 0x79},// ; + {0x361f, 0x02},// ; + {0x3632, 0x00},// ; + {0x3633, 0x10},// ; + {0x3634, 0x10},// ; + {0x3635, 0x10},// ; + {0x3636, 0x15},// ; + {0x3646, 0x86},// ; + {0x364a, 0x0b},// ; ADC & analog + {0x3700, 0x17},// ; Sensor control + {0x3701, 0x22},// ; + {0x3703, 0x10},// ; + {0x370a, 0x37},// ; + {0x3705, 0x00},// ; + {0x3706, 0x63},// ; + {0x3709, 0x3c},// ; + {0x370b, 0x01},// ; + {0x370c, 0x30},// ; + {0x3710, 0x24},// ; + {0x3711, 0x0c},// ; + {0x3716, 0x00},// ; + {0x3720, 0x28},// ; + {0x3729, 0x7b},// ; + {0x372a, 0x84},// ; + {0x372b, 0xbd},// ; + {0x372c, 0xbc},// ; + {0x372e, 0x52},// ; + {0x373c, 0x0e},// ; + {0x373e, 0x33},// ; + {0x3743, 0x10},// ; + {0x3744, 0x88},// ; + {0x3745, 0xc0 },// important!!! + {0x374a, 0x43},// ; + {0x374c, 0x00},// ; + {0x374e, 0x23},// ; + {0x3751, 0x7b},// ; + {0x3752, 0x84},// ; + {0x3753, 0xbd},// ; + {0x3754, 0xbc},// ; + {0x3756, 0x52},// ; + {0x375c, 0x00},// ; + {0x3760, 0x00},// ; + {0x3761, 0x00},// ; + {0x3762, 0x00},// ; + {0x3763, 0x00},// ; + {0x3764, 0x00},// ; + {0x3767, 0x04},// ; + {0x3768, 0x04},// ; + {0x3769, 0x08},// ; + {0x376a, 0x08},// ; + {0x376b, 0x20},// ; + {0x376c, 0x00},// ; + {0x376d, 0x00},// ; + {0x376e, 0x00},// ; + {0x3773, 0x00},// ; + {0x3774, 0x51},// ; + {0x3776, 0xbd},// ; + {0x3777, 0xbd},// ; + {0x3781, 0x18},// ; + {0x3783, 0x25},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3802, 0x00},// ; V crop start H + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x97},// ; H crop end L + {0x3806, 0x05},// ; V crop end H + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x0a},// ; H output size H + {0x3809, 0x80},// ; H output size L + {0x380a, 0x05},// ; V output size H + {0x380b, 0xf0},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x08},// ; HTS L + {0x380e, 0x06},// ; VTS H + {0x380f, 0x12},// ; VTS L + {0x3810, 0x00},// ; H win off H + {0x3811, 0x08},// ; H win off L + {0x3812, 0x00},// ; V win off H + {0x3813, 0x04},// ; V win off L + {0x3814, 0x01},// ; H inc odd + {0x3815, 0x01},// ; H inc even + {0x3819, 0x01},// ; Vsync end L + {0x3820, 0x00},// ; flip off, bin off + {0x3821, 0x06},// ; mirror on, bin off + {0x3829, 0x00},// ; HDR lite off + {0x382a, 0x01},// ; vertical subsample odd increase number + {0x382b, 0x01},// ; vertical subsample even increase number + {0x382d, 0x7f},// ; black column end address + {0x3830, 0x04},// ; blc use num/2 + {0x3836, 0x01},// ; r zline use num/2 + {0x3837, 0x00},// + {0x3841, 0x02},// ; r_rcnt_fix on + {0x3846, 0x08},// ; fcnt_trig_rst_en on + {0x3847, 0x07},// ; debug mode + {0x3d85, 0x36},// ; OTP bist enable, OTP BIST compare with zero, OTP power up load data on, OTP power up load setting on, OTP write register load setting off + {0x3d8c, 0x71},// ; OTP start address H + {0x3d8d, 0xcb},// ; OTP start address L + {0x3f0a, 0x00},// ; PSRAM + {0x4000, 0x71},// ; out of range trig off, format chg on, gain chg on, exp chg on, manual trig off, no freeze, always trig off, debug mode + {0x4001, 0x40},// ; debug mode + {0x4002, 0x04},// ; debug mode + {0x4003, 0x14},// ; black line number + {0x400e, 0x00},// ; offset for BLC bypass + {0x4011, 0x00},// ; offset man same off, offset man off, black line output off, + {0x401a, 0x00},// ; debug mode + {0x401b, 0x00},// ; debug mode + {0x401c, 0x00},// ; debug mode + {0x401d, 0x00},// ; debug mode + {0x401f, 0x00},// ; debug mode + {0x4020, 0x00},// ; Anchor left start H + {0x4021, 0x10},// ; Anchor left start L + {0x4022, 0x07},// ; Anchor left end H + {0x4023, 0xcf},// ; Anchor left end L + {0x4024, 0x09},// ; Anchor right start H + {0x4025, 0x60},// ; Andhor right start L + {0x4026, 0x09},// ; Anchor right end H + {0x4027, 0x6f},// ; Anchor right end L + {0x4028, 0x00},// ; top Zline start + {0x4029, 0x02},// ; top Zline number + {0x402a, 0x06},// ; top blk line start + {0x402b, 0x04},// ; to blk line number + {0x402c, 0x02},// ; bot Zline start + {0x402d, 0x02},// ; bot Zline number + {0x402e, 0x0e},// ; bot blk line start + {0x402f, 0x04},// ; bot blk line number + {0x4302, 0xff},// ; clipping max H + {0x4303, 0xff},// ; clipping max L + {0x4304, 0x00},// ; clipping min H + {0x4305, 0x00},// ; clipping min L + {0x4306, 0x00},// ; vfifo pix swap off, dpcm off, vfifo first line is blue line + {0x4308, 0x02},// ; debug mode, embeded off + {0x4500, 0x6c},// ; ADC sync control + {0x4501, 0xc4},// ; + {0x4502, 0x40},// ; + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x04},// ; V fifo read start + {0x4800, 0x04},// ; MIPI always high speed off, Clock lane gate off, line short packet off, + {0x4813, 0x08},// ; Select HDR VC + {0x481f, 0x40},// ; MIPI clock prepare min + {0x4829, 0x78},// ; MIPI HS exit min + {0x4837, 0x18},// ; MIPI global timing + {0x4b00, 0x2a},// + {0x4b0d, 0x00},// + {0x4d00, 0x04},// ; tpm slope H + {0x4d01, 0x42},// ; tpm slope L + {0x4d02, 0xd1},// ; tpm offset HH + {0x4d03, 0x93},// ; tpm offset H + {0x4d04, 0xf5},// ; tpm offset M + {0x4d05, 0xc1},// ; tpm offset L + {0x5000, 0xf3},// ; digital gain on, bin on, OTP on, WB gain on, average on, ISP on + {0x5001, 0x11},// ; ISP EOF select, ISP SOF off, BLC on + {0x5004, 0x00},// ; debug mode + {0x500a, 0x00},// ; debug mode + {0x500b, 0x00},// ; debug mode + {0x5032, 0x00},// ; debug mode + {0x5040, 0x00},// ; test mode off + {0x5050, 0x0c},// ; debug mode + {0x5500, 0x00},// ; OTP DPC start H + {0x5501, 0x10},// ; OTP DPC start L + {0x5502, 0x01},// ; OTP DPC end H + {0x5503, 0x0f},// ; OTP DPC end L + {0x8000, 0x00},// ; test mode + {0x8001, 0x00},// ; + {0x8002, 0x00},// ; + {0x8003, 0x00},// ; + {0x8004, 0x00},// ; + {0x8005, 0x00},// ; + {0x8006, 0x00},// ; + {0x8007, 0x00},// ; + {0x8008, 0x00},// ; test mode + {0x3638, 0x00},// ; ADC & analog + {0x3105, 0x31},// ; SCCB control, debug mode + {0x301a, 0xf9},// ; enable emb clock, enable strobe clock, enable timing control clock, mipi-phy manual reset, reset timing control block + {0x3508, 0x07},// ; Long gain H + {0x484b, 0x05},// ; line start after fifo_st, sclock start after SOF, frame start after SOF + {0x4805, 0x03},// ; MIPI control + {0x3601, 0x01},// ; ADC & analog + {0x0100, 0x01},// ; wake up from sleep + {REG_DLY,0x02},//{0x; de, 0xay},// 2ms here + {0x3105, 0x11},// ; SCCB control, debug mode + {0x301a, 0xf1},// ; disable mipi-phy reset + {0x4805, 0x00},// ; MIPI control + {0x301a, 0xf0},// ; enable emb clock, enable strobe clock, enable timing control clock, + {0x3208, 0x00},// ; group hold start, group bank 0 + {0x302a, 0x00},// ; delay? + {0x302a, 0x00},// ; + {0x302a, 0x00},// ; + {0x302a, 0x00},// ; + {0x302a, 0x00},// ; + {0x3601, 0x00},// ; ADC & analog + {0x3638, 0x00},// ; ADC & analog + {0x3208, 0x10},// ; group hold end, group select 0 + {0x3208, 0xa0},// ; group delay launch, group select 0 + + //MWB gain + {0x500c,DGAIN_R>>8}, + {0x500d,DGAIN_R&0xff}, + {0x500e,DGAIN_G>>8}, + {0x500f,DGAIN_G&0xff}, + {0x5010,DGAIN_B>>8}, + {0x5011,DGAIN_B&0xff}, + + {0x0100, 0x01 },//; wake up from sleep +}; + +//for capture +static struct regval_list sensor_quxga_15fps_regs[] = { + // Full Resolution 2688x1520 15fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + {0x030d, 0x1e},// ; PLL2 multiplier + {REG_DLY,0x20}, + {0x3501, 0x60},// ; long exposure H + {0x3632, 0x00},// ; ADC & Analog + {0x376b, 0x20},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x97},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x0a},// ; H output size H + {0x3809, 0x80},// ; H output size L + {0x380a, 0x05},// ; V output size H + {0x380b, 0xf0},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x08},// ; HTS L + {0x380e, 0x18},// ; VTS H 25fps:0x0e + {0x380f, 0x44},// ; VTS L 25fps:0x8f + {0x3811, 0x08},// ; H win off L + {0x3813, 0x04},// ; V win off L + {0x3814, 0x01},// ; H inc odd + {0x3820, 0x06},// ; flip off, bin off + {0x3821, 0x00},// ; mirror on, bin off + {0x382a, 0x01},// ; vertical subsample odd increase number + {0x3830, 0x04},// ; blc use num/2 + {0x3836, 0x01},// ; r zline use num/2 + {0x4001, 0x40},// ; debug mode + {0x4022, 0x07},// ; Anchor left end H + {0x4023, 0xcf},// ; Anchor left end L + {0x4024, 0x09},// ; Anchor right start H + {0x4025, 0x60},// ; Andhor right start L + {0x4026, 0x09},// ; Anchor right end H + {0x4027, 0x6f},// ; Anchor right end L + {0x4502, 0x40},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x04},// ; V fifo read start + {0x0100, 0x01},// wake up +}; + +static struct regval_list sensor_quxga_30fps_regs[] = { + // Full Resolution 2688x1520 30fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x1e},// ; PLL2 multiplier + {REG_DLY,0x20}, + + {0x3501, 0x60},// ; long exposure H + {0x3632, 0x00},// ; ADC & Analog + {0x376b, 0x20},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x97},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x0a},// ; H output size H + {0x3809, 0x80},// ; H output size L + {0x380a, 0x05},// ; V output size H + {0x380b, 0xf0},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x08},// ; HTS L + {0x380e, 0x0c},// ; VTS H + {0x380f, 0x24},// ; VTS L + {0x3811, 0x08},// ; H win off L + {0x3813, 0x04},// ; V win off L + {0x3814, 0x01},// ; H inc odd + {0x3820, 0x06},// ; flip off, bin off + {0x3821, 0x00},// ; mirror on, bin off + {0x382a, 0x01},// ; vertical subsample odd increase number + {0x3830, 0x04},// ; blc use num/2 + {0x3836, 0x01},// ; r zline use num/2 + {0x4001, 0x40},// ; debug mode + {0x4022, 0x07},// ; Anchor left end H + {0x4023, 0xcf},// ; Anchor left end L + {0x4024, 0x09},// ; Anchor right start H + {0x4025, 0x60},// ; Andhor right start L + {0x4026, 0x09},// ; Anchor right end H + {0x4027, 0x6f},// ; Anchor right end L + {0x4502, 0x40},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x04},// ; V fifo read start + {0x0100, 0x01}, // wake up + +}; + +static struct regval_list sensor_quxga_60fps_regs[] = { + // Full Resolution 2688x1520 60fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x1e},// ; PLL2 multiplier + {REG_DLY,0x20}, + + {0x3501, 0x60},// ; long exposure H + {0x3632, 0x00},// ; ADC & Analog + {0x376b, 0x20},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x97},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x0a},// ; H output size H + {0x3809, 0x80},// ; H output size L + {0x380a, 0x05},// ; V output size H + {0x380b, 0xf0},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x08},// ; HTS L + {0x380e, 0x06},// ; VTS H + {0x380f, 0x12},// ; VTS L + {0x3811, 0x08},// ; H win off L + {0x3813, 0x04},// ; V win off L + {0x3814, 0x01},// ; H inc odd + {0x3820, 0x06},// ; flip off, bin off + {0x3821, 0x00},// ; mirror on, bin off + {0x382a, 0x01},// ; vertical subsample odd increase number + {0x3830, 0x04},// ; blc use num/2 + {0x3836, 0x01},// ; r zline use num/2 + {0x4001, 0x40},// ; debug mode + {0x4022, 0x07},// ; Anchor left end H + {0x4023, 0xcf},// ; Anchor left end L + {0x4024, 0x09},// ; Anchor right start H + {0x4025, 0x60},// ; Andhor right start L + {0x4026, 0x09},// ; Anchor right end H + {0x4027, 0x6f},// ; Anchor right end L + {0x4502, 0x40},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x04},// ; V fifo read start + {0x0100, 0x01}, // wake up + +}; + +static struct regval_list sensor_720p_120fps_regs[] = { + // EIS 720p 1344x760 120fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x21},// ; PLL2 multiplier 0x1e:for 110fps, 0x21 for 120fps + {REG_DLY,0x20}, + {0x3501, 0x31},// ; long exposure H + {0x3632, 0x05},// ; ADC & Analog + {0x376b, 0x40},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x9f},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x05},// ; H output size H + {0x3809, 0x40},// ; H output size L + {0x380a, 0x02},// ; V output size H + {0x380b, 0xf8},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x58},// ; HTS L + {0x380e, 0x03},// ; VTS H + {0x380f, 0x20},// ; VTS L + {0x3811, 0x08},// ; H win off L + {0x3813, 0x02},// ; V win off L + {0x3814, 0x03},// ; H inc odd + {0x3820, 0x16},// ; flip off, bin on + {0x3821, 0x01},// ; mirror on, bin on + {0x382a, 0x03},// ; vertical subsample odd increase number + {0x3830, 0x08},// ; blc use num/2 + {0x3836, 0x02},// ; r zline use num/2 + {0x4001, 0x50},// ; debug mode + {0x4022, 0x03},// ; Anchor left end H + {0x4023, 0xe7},// ; Anchor left end L + {0x4024, 0x05},// ; Anchor right start H + {0x4025, 0x14},// ; Andhor right start L + {0x4026, 0x05},// ; Anchor right end H + {0x4027, 0x23},// ; Anchor right end L + {0x4502, 0x44},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x28},// ; V fifo read start + {0x0100, 0x01}, // wake up + +}; + +static struct regval_list sensor_720p_60fps_regs[] = { + // EIS 720p 1344x760 60fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x16},// ; PLL2 multiplier 0x1e:for 110fps, 0x21 for 120fps + {REG_DLY,0x20}, + {0x3501, 0x31},// ; long exposure H + {0x3632, 0x05},// ; ADC & Analog + {0x376b, 0x40},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x9f},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x05},// ; H output size H + {0x3809, 0x40},// ; H output size L + {0x380a, 0x02},// ; V output size H + {0x380b, 0xf8},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x58},// ; HTS L + {0x380e, 0x04},// ; VTS H + {0x380f, 0x30},// ; VTS L + {0x3811, 0x08},// ; H win off L + {0x3813, 0x02},// ; V win off L + {0x3814, 0x03},// ; H inc odd + {0x3820, 0x16},// ; flip off, bin on + {0x3821, 0x01},// ; mirror on, bin on + {0x382a, 0x03},// ; vertical subsample odd increase number + {0x3830, 0x08},// ; blc use num/2 + {0x3836, 0x02},// ; r zline use num/2 + {0x4001, 0x50},// ; debug mode + {0x4022, 0x03},// ; Anchor left end H + {0x4023, 0xe7},// ; Anchor left end L + {0x4024, 0x05},// ; Anchor right start H + {0x4025, 0x14},// ; Andhor right start L + {0x4026, 0x05},// ; Anchor right end H + {0x4027, 0x23},// ; Anchor right end L + {0x4502, 0x44},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x28},// ; V fifo read start + {0x0100, 0x01}, // wake up + +}; + +static struct regval_list sensor_720p_30fps_regs[] = { + // EIS 720p 1344x760 30fps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x16},// ; PLL2 multiplier 0x1e:for 110fps, 0x21 for 120fps + {REG_DLY,0x20}, + {0x3501, 0x31},// ; long exposure H + {0x3632, 0x05},// ; ADC & Analog + {0x376b, 0x40},// ; Sensor control + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x08},// ; H crop start L + {0x3803, 0x04},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x9f},// ; H crop end L + {0x3807, 0xfb},// ; V crop end L + {0x3808, 0x05},// ; H output size H + {0x3809, 0x40},// ; H output size L + {0x380a, 0x02},// ; V output size H + {0x380b, 0xf8},// ; V output size L + {0x380c, 0x05},// ; HTS H + {0x380d, 0x58},// ; HTS L + {0x380e, 0x08},// ; VTS H + {0x380f, 0x60},// ; VTS L + {0x3811, 0x08},// ; H win off L + {0x3813, 0x02},// ; V win off L + {0x3814, 0x03},// ; H inc odd + {0x3820, 0x16},// ; flip off, bin on + {0x3821, 0x01},// ; mirror on, bin on + {0x382a, 0x03},// ; vertical subsample odd increase number + {0x3830, 0x08},// ; blc use num/2 + {0x3836, 0x02},// ; r zline use num/2 + {0x4001, 0x50},// ; debug mode + {0x4022, 0x03},// ; Anchor left end H + {0x4023, 0xe7},// ; Anchor left end L + {0x4024, 0x05},// ; Anchor right start H + {0x4025, 0x14},// ; Andhor right start L + {0x4026, 0x05},// ; Anchor right end H + {0x4027, 0x23},// ; Anchor right end L + {0x4502, 0x44},// ; ADC sync control + {0x4503, 0x02},// ; ADC sync control + {0x4601, 0x28},// ; V fifo read start + {0x0100, 0x01}, // wake up + +}; + +static struct regval_list sensor_380p_330fps_regs[] = { + // 672x380_4x_Bin_330fps_300Mbps + {0x0100, 0x00}, // sleep + {REG_DLY,0x20}, + + {0x030d, 0x16},//6},//e},// ; PLL2 multiplier 0x16:for 240fps, 0x1e for 330fps + {REG_DLY,0x20}, + {0x3501, 0x18},// ; long exposure H + {0x3632, 0x06},// ; ADC & Analog + {0x376b, 0x40},// ; Sensor control + + {0x3800, 0x00},// ; H crop start H + {0x3801, 0x00},// ; H crop start L + {0x3803, 0x00},// ; V crop start L + {0x3804, 0x0a},// ; H crop end H + {0x3805, 0x9f},// ; H crop end L + {0x3807, 0xff},// ; V crop end L + + {0x3808, 0x02},// ; H output size H + {0x3809, 0xa0},// ; H output size L + {0x380a, 0x01},// ; V output size H + {0x380b, 0x7c},// ; V output size L + + {0x380c, 0x03},// ; HTS H + {0x380d, 0x5c},// ; HTS L + {0x380e, 0x01},// ; VTS H + {0x380f, 0xa5},// ; VTS L + {0x3811, 0x04},// ; H win off L + {0x3813, 0x02},// ; V win off L + {0x3814, 0x07},// ; H inc odd + {0x3820, 0x16},// ; flip off, bin on + {0x3821, 0x09},// ; mirror on, bin on + {0x382a, 0x07},// ; vertical subsample odd increase number + {0x3830, 0x08},// ; blc use num/2 + {0x3836, 0x02},// ; r zline use num/2 + {0x4001, 0x60},// ; debug mode + {0x4022, 0x01},// ; Anchor left end H + {0x4023, 0x2b},// ; Anchor left end L + {0x4024, 0x02},// ; Anchor right start H + {0x4025, 0x58},// ; Andhor right start L + {0x4026, 0x02},// ; Anchor right end H + {0x4027, 0x67},// ; Anchor right end L + {0x4502, 0x48},// ; ADC sync control + {0x4503, 0x00},// ; ADC sync control + {0x4601, 0x29},// ; V fifo read start + {0x0100, 0x01}, // wake up +}; + +/* + * Here we'll try to encapsulate the changes for just the output + * video format. + * + */ + +static struct regval_list sensor_fmt_raw[] = { + +}; + +/* + * Low-level register I/O. + * + */ + + +/* + * On most platforms, we'd rather do straight i2c I/O. + */ +static int sensor_read(struct v4l2_subdev *sd, unsigned short reg, + unsigned char *value) //!!!!be careful of the para type!!! +{ + int ret=0; + int cnt=0; + + ret = cci_read_a16_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_read_a16_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor read retry=%d\n",cnt); + + return ret; +} + +static int sensor_write(struct v4l2_subdev *sd, unsigned short reg, + unsigned char value) +{ + int ret=0; + int cnt=0; + + ret = cci_write_a16_d8(sd,reg,value); + while(ret!=0&&cnt<2) + { + ret = cci_write_a16_d8(sd,reg,value); + cnt++; + } + if(cnt>0) + vfe_dev_dbg("sensor write retry=%d\n",cnt); + + return ret; +} + +/* + * Write a list of register settings; + */ +static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size) +{ + int i=0; + + if(!regs) + return 0; + + while(iaddr == REG_DLY) { + msleep(regs->data); + } + else { + LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data)) + } + i++; + regs++; + } + return 0; +} + +static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->exp; + vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); + return 0; +} + +int ov4689_sensor_vts ; +static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) +{ + int exp_val, gain_val, frame_length, shutter; + long gainr=0, gaing=0, gainb=0, gain_digi=0; + unsigned char explow=0,expmid=0,exphigh=0; + unsigned char gainlow=0,gainhigh=0; + struct sensor_info *info = to_state(sd); + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + + if(exp_val>0xfffff) + exp_val=0xfffff; + + gain_digi = gain_val; + gain_val *=8; + + if (gain_val<2*16*8) + { + gainhigh=0; + gainlow = (gain_val & 0x7ff); + } + else if (2*16*8<=gain_val && gain_val <4*16*8) + { + gainhigh = 1; + gainlow = (gain_val & 0x7ff)/2-8; + } + else if (4*16*8<= gain_val && gain_val <8*16*8) + { + gainhigh = 3; + gainlow = (gain_val & 0x7ff)/4-12; + + } + else if (8*16*8<= gain_val && gain_val <16*16*8) + { + gainhigh = 7; + gainlow= (gain_val & 0x7ff)/8-8; + } + else + { + gainhigh = 7; + gainlow = 0xff; + } + + if (gain_val < 16*16*8) + { + gainr = DGAIN_R; + gaing = DGAIN_G; + gainb = DGAIN_B; + } + else + { + gainr = (gain_digi*DGAIN_R)>>8; + gaing = (gain_digi*DGAIN_G)>>8; + gainb = (gain_digi*DGAIN_B)>>8; + } + + exp_val >>=4; + + exphigh = (unsigned char) ( (0xffff&exp_val)>>12); + expmid = (unsigned char) ( (0xfff&exp_val)>>4); + explow = (unsigned char) ( (0xf&exp_val)<<4 ); + + shutter = exp_val; + if(shutter > ov4689_sensor_vts - 4) + frame_length = shutter + 4; + else + frame_length = ov4689_sensor_vts; + + vfe_dev_dbg("exp_val = %d,gain_val = %d\n",exp_val,gain_val); + + sensor_write(sd, 0x380f, (frame_length & 0xff)); + sensor_write(sd, 0x380e, (frame_length >> 8)); + + sensor_write(sd, 0x3509, gainlow); + sensor_write(sd, 0x3508, gainhigh); + + sensor_write(sd, 0x3502, explow); + sensor_write(sd, 0x3501, expmid); + sensor_write(sd, 0x3500, exphigh); + + sensor_write(sd, 0x500c, gainr>>8); + sensor_write(sd, 0x500d, gainr&0xff); + sensor_write(sd, 0x500e, gaing>>8); + sensor_write(sd, 0x500f, gaing&0xff); + sensor_write(sd, 0x5010, gainb>>8); + sensor_write(sd, 0x5011, gainb&0xff); + + vfe_dev_dbg("gain_digi = %ld,gainr = %ld,gaing = %ld,gainb = %ld, frame_length = %d\n", gain_digi, gainr, gaing, gainb, frame_length); + + info->exp = exp_val; + info->gain = gain_digi; + return 0; +} + +static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) +{ + unsigned char explow,expmid,exphigh,tmp1,tmp2,tmp3; + unsigned int tmp; + struct sensor_info *info = to_state(sd); + if(exp_val>0xfffff) + exp_val=0xfffff; + + exp_val >>=4; + exphigh = (unsigned char) ( (0xffff&exp_val)>>12); + expmid = (unsigned char) ( (0xfff&exp_val)>>4); + explow = (unsigned char) ( (0x0f&exp_val)<<4 ); + + sensor_write(sd, 0x3208,0x00); + + sensor_write(sd, 0x3502, /*0x00);//*/explow); + sensor_write(sd, 0x3501, /*0xa0);//*/expmid); + sensor_write(sd, 0x3500, /*0x01);//*/exphigh); + + sensor_write(sd, 0x3208,0x10); + sensor_write(sd, 0x3208,0xe0); + + sensor_read(sd,0x3502,&tmp1); + sensor_read(sd,0x3501,&tmp2); + sensor_read(sd,0x3500,&tmp3); + tmp = (tmp1>>4)+(tmp2<<4)+(tmp3<<12); + +// printk("ov4689 sensor_set_exp = %d, Done!\n", tmp); + + info->exp = exp_val; + return 0; +} + +static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) +{ + struct sensor_info *info = to_state(sd); + + *value = info->gain; + vfe_dev_dbg("sensor_get_gain = %d\n", info->gain); + return 0; +} + +static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) +{ + struct sensor_info *info = to_state(sd); + long gainr=0, gaing=0, gainb=0, gain_digi=0; + unsigned char gainlow=0; + unsigned char gainhigh=0; + + gain_digi = gain_val; + gain_val *=8; + + if (gain_val<2*16*8) + { + gainhigh=0; + gainlow = (gain_val & 0x7ff); + } + else if (2*16*8<=gain_val && gain_val <4*16*8) + { + gainhigh = 1; + gainlow = (gain_val & 0x7ff)/2-8; + } + else if (4*16*8<= gain_val && gain_val <8*16*8) + { + gainhigh = 3; + gainlow = (gain_val & 0x7ff)/4-12; + + } + else if (8*16*8<= gain_val && gain_val <16*16*8) + { + gainhigh = 7; + gainlow= (gain_val & 0x7ff)/8-8; + } + else + { + gainhigh = 7; + gainlow = 0xff; + } + + if (gain_val < 16*16*8) + { + gainr = DGAIN_R; + gaing = DGAIN_G; + gainb = DGAIN_B; + } + else + { + gainr = (gain_digi*DGAIN_R)>>8; + gaing = (gain_digi*DGAIN_G)>>8; + gainb = (gain_digi*DGAIN_B)>>8; + } + + sensor_write(sd, 0x3208,0x11); + sensor_write(sd, 0x3509, gainlow); + sensor_write(sd, 0x3508, gainhigh); + + sensor_write(sd, 0x3208,0x11); + sensor_write(sd, 0x3208,0xe1); + + sensor_write(sd, 0x500c, gainr>>8); + sensor_write(sd, 0x500d, gainr&0xff); + sensor_write(sd, 0x500e, gaing>>8); + sensor_write(sd, 0x500f, gaing&0xff); + sensor_write(sd, 0x5010, gainb>>8); + sensor_write(sd, 0x5011, gainb&0xff); + + info->gain = gain_digi; + return 0; +} + + +static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) +{ + int ret; + unsigned char rdval; + + ret=sensor_read(sd, 0x0100, &rdval); + if(ret!=0) + return ret; + + if(on_off==CSI_STBY_ON)//sw stby on + { + ret=sensor_write(sd, 0x0100, rdval&0xfe); + } + else//sw stby off + { + ret=sensor_write(sd, 0x0100, rdval|0x01); + } + return ret; +} + +/* + * Stuff that knows about the sensor. + */ + +static int sensor_power(struct v4l2_subdev *sd, int on) +{ + int ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_set_status(sd,POWER_EN,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_set_pmu_channel(sd,IOVDD,ON); + usleep_range(10000,12000); + + vfe_set_pmu_channel(sd,AVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(5000,6000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); + vfe_set_mclk(sd,OFF); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_pmu_channel(sd,DVDD,OFF); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,AVDD,OFF); + + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,IOVDD,OFF); + usleep_range(10000,12000); + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + vfe_gpio_set_status(sd,POWER_EN,0);//set the gpio to input + cci_unlock(sd); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sensor_reset(struct v4l2_subdev *sd, u32 val) +{ + switch(val) + { + case 0: + vfe_gpio_write(sd,RESET,CSI_RST_OFF); + usleep_range(10000,12000); + break; + case 1: + vfe_gpio_write(sd,RESET,CSI_RST_ON); + usleep_range(10000,12000); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sensor_detect(struct v4l2_subdev *sd) +{ + unsigned char rdval; + + LOG_ERR_RET(sensor_read(sd, 0x300a, &rdval)) + if(rdval != 0x46) + return -ENODEV; + + LOG_ERR_RET(sensor_read(sd, 0x300b, &rdval)) + if(rdval != 0x88) + return -ENODEV; + + return 0; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + int ret; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_init\n"); + + /*Make sure it is a target sensor*/ + ret = sensor_detect(sd); + if (ret) { + vfe_dev_err("chip found is not an target chip.\n"); + return ret; + } + + vfe_get_standby_mode(sd,&info->stby_mode); + + if((info->stby_mode == HW_STBY || info->stby_mode == SW_STBY) \ + && info->init_first_flag == 0) { + vfe_dev_print("stby_mode and init_first_flag = 0\n"); + return 0; + } + + info->focus_status = 0; + info->low_speed = 0; + info->width = 2688; + info->height = 1520; + info->hflip = 0; + info->vflip = 0; + info->gain = 0; + + info->tpf.numerator = 1; + info->tpf.denominator = 30; /* 30fps */ + + ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); + if(ret < 0) { + vfe_dev_err("write sensor_default_regs error\n"); + return ret; + } + + if(info->stby_mode == 0) + info->init_first_flag = 0; + + info->preview_first_flag = 1; + + return 0; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + int ret=0; + struct sensor_info *info = to_state(sd); +// vfe_dev_dbg("[]cmd=%d\n",cmd); +// vfe_dev_dbg("[]arg=%0x\n",arg); + switch(cmd) { + case GET_CURRENT_WIN_CFG: + if(info->current_wins != NULL) + { + memcpy( arg, + info->current_wins, + sizeof(struct sensor_win_size) ); + ret=0; + } + else + { + vfe_dev_err("empty wins!\n"); + ret=-1; + } + break; + case SET_FPS: + ret=0; +// if((unsigned int *)arg==1) +// ret=sensor_write(sd, 0x3036, 0x78); +// else +// ret=sensor_write(sd, 0x3036, 0x32); + break; + case ISP_SET_EXP_GAIN: + ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); + break; + default: + return -EINVAL; + } + return ret; +} + + +/* + * Store information about the video data format. + */ +static struct sensor_format_struct { + __u8 *desc; + //__u32 pixelformat; + enum v4l2_mbus_pixelcode mbus_code; + struct regval_list *regs; + int regs_size; + int bpp; /* Bytes per pixel */ +}sensor_formats[] = { + { + .desc = "Raw RGB Bayer", + .mbus_code = V4L2_MBUS_FMT_SBGGR10_10X1,//V4L2_MBUS_FMT_SGRBG10_10X1, + .regs = sensor_fmt_raw, + .regs_size = ARRAY_SIZE(sensor_fmt_raw), + .bpp = 1 + }, +}; +#define N_FMTS ARRAY_SIZE(sensor_formats) + + + +/* + * Then there is the issue of window sizes. Try to capture the info here. + */ + + +static struct sensor_win_size sensor_win_sizes[] = { + /* 2688*1520 */ + { + .width = 2688, + .height = 1520, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 6212, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 15, + .bin_factor = 1, + .intg_min = 16, + .intg_max =(6212-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .regs = sensor_quxga_15fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_15fps_regs), + .set_size = NULL, + }, + + /* 2048*1520 for 4:3 capture */ + { + .width = 2048, + .height = 1520, + .hoffset = 320, + .voffset = 0, + .hts = 1288, + .vts = 3108, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (3108-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .regs = sensor_quxga_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_30fps_regs), + .set_size = NULL, + }, + + { + .width = 2560, + .height = 1440, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 3108, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (3108-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .width_input = 2688, + .height_input = 1520, + .regs = sensor_quxga_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_30fps_regs), + .set_size = NULL, + }, + +///////////////////////////1080P////////////////////////////// + { + .width = 1920, + .height = 1088, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 3108, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (3108-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .width_input = 2688, + .height_input = 1520, + .regs = sensor_quxga_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_30fps_regs), + .set_size = NULL, + + }, + { + .width = HD1080_WIDTH, + .height = HD1080_HEIGHT, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 3108, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (3108-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .width_input = 2688, + .height_input = 1520, + .regs = sensor_quxga_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_30fps_regs), + .set_size = NULL, + + }, + + { + .width = 1920, + .height = 1088, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 1554, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 60, + .bin_factor = 1, + .intg_min = 16, + .intg_max =(1554-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .width_input = 2688, + .height_input = 1520, + .regs = sensor_quxga_60fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_60fps_regs), + .set_size = NULL, + }, + + { + .width = HD1080_WIDTH, + .height = HD1080_HEIGHT, + .hoffset = 0, + .voffset = 0, + .hts = 1288, + .vts = 1554, + .pclk = 120*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 60, + .bin_factor = 1, + .intg_min = 16, + .intg_max =(1554-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .width_input = 2688, + .height_input = 1520, + .regs = sensor_quxga_60fps_regs, + .regs_size = ARRAY_SIZE(sensor_quxga_60fps_regs), + .set_size = NULL, + }, +///////////////////////////720P////////////////////////////// + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 32,//(1344-1280)/2, + .voffset = 20,//(760-720)/2, + .hts = 1368, + .vts = 2144, + .pclk = 88*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (2144-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .regs = sensor_720p_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_30fps_regs), + .set_size = NULL, + }, + + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 32,//(1344-1280)/2, + .voffset = 20,//(760-720)/2, + .hts = 1368, + .vts = 1072, + .pclk = 88*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 60, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (1072-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .regs = sensor_720p_60fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_60fps_regs), + .set_size = NULL, + }, + + { + .width = HD720_WIDTH, + .height = HD720_HEIGHT, + .hoffset = 32,//(1344-1280)/2, + .voffset = 20,//(760-720)/2, + .hts = 1368, + .vts = 800, + .pclk = 132*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 120, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (800-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .regs = sensor_720p_120fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_120fps_regs), + .set_size = NULL, + }, + +///////////////////////////WVGA////////////////////////////// + { + .width = 848, + .height = 480, + .hoffset = 0, + .voffset = 0, + .hts = 1368, + .vts = 2144, + .pclk = 88*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 30, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (2144-4)<<4, + .gain_min = 1<<4, + .gain_max = (16<<4)-1, + .width_input = 1344, + .height_input = 760, + .regs = sensor_720p_30fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_30fps_regs), + .set_size = NULL, + }, + + { + .width = 848, + .height = 480, + .hoffset = 0, + .voffset = 0, + .hts = 1368, + .vts = 1072, + .pclk = 88*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 60, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (1072-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .width_input = 1344, + .height_input = 760, + .regs = sensor_720p_60fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_60fps_regs), + .set_size = NULL, + }, + + { + .width = 848, + .height = 480, + .hoffset = 0, + .voffset = 0, + .hts = 1368, + .vts = 800, + .pclk = 132*1000*1000, + .mipi_bps = 672*1000*1000, + .fps_fixed = 120, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (800-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .width_input = 1344, + .height_input = 760, + .regs = sensor_720p_120fps_regs, + .regs_size = ARRAY_SIZE(sensor_720p_120fps_regs), + .set_size = NULL, + }, + + { + .width = 672, + .height = 380, + .hoffset = 0, + .voffset = 0, + .hts = 860, + .vts = 421, + .pclk = 88*1000*1000, + .mipi_bps = 300*1000*1000, + .fps_fixed = 240, + .bin_factor = 1, + .intg_min = 16, + .intg_max = (421-4)<<4, + .gain_min = 1<<4, + .gain_max = (30<<4)-1, + .regs = sensor_380p_330fps_regs, + .regs_size = ARRAY_SIZE(sensor_380p_330fps_regs), + .set_size = NULL, + }, +}; + +#define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) + +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= N_FMTS) + return -EINVAL; + + *code = sensor_formats[index].mbus_code; + return 0; +} + +static int sensor_enum_size(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + if(fsize->index > N_WIN_SIZES-1) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = sensor_win_sizes[fsize->index].width; + fsize->discrete.height = sensor_win_sizes[fsize->index].height; + + return 0; +} + + +static int sensor_try_fmt_internal(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt, + struct sensor_format_struct **ret_fmt, + struct sensor_win_size **ret_wsize) +{ + int index; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + for (index = 0; index < N_FMTS; index++) + if (sensor_formats[index].mbus_code == fmt->code) + break; + + if (index >= N_FMTS) + return -EINVAL; + + if (ret_fmt != NULL) + *ret_fmt = sensor_formats + index; + + /* + * Fields: the sensor devices claim to be progressive. + */ + + fmt->field = V4L2_FIELD_NONE; + + /* + * Round requested image size down to the nearest + * we support, but not below the smallest. + */ + for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; + wsize++) + if (fmt->width >= wsize->width && fmt->height >= wsize->height && info->tpf.denominator == wsize->fps_fixed) + break; + + if (wsize >= sensor_win_sizes + N_WIN_SIZES) + wsize--; /* Take the smallest one */ + if (ret_wsize != NULL) + *ret_wsize = wsize; + + info->current_wins = wsize; + + /* + * Note the size we'll actually handle. + */ + fmt->width = wsize->width; + fmt->height = wsize->height; + //pix->bytesperline = pix->width*sensor_formats[index].bpp; + //pix->sizeimage = pix->height*pix->bytesperline; + + return 0; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + return sensor_try_fmt_internal(sd, fmt, NULL, NULL); +} + +static int sensor_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + cfg->type = V4L2_MBUS_CSI2; + cfg->flags = 0|V4L2_MBUS_CSI2_4_LANE|V4L2_MBUS_CSI2_CHANNEL_0; + + return 0; +} + + +/* + * Set a format. + */ +static int sensor_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt) +{ + int ret; + + struct sensor_format_struct *sensor_fmt; + struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); + + vfe_dev_dbg("sensor_s_fmt\n"); + + //sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); + + ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize); + if (ret) + return ret; + + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + } + else if(info->capture_mode == V4L2_MODE_IMAGE) + { + //image + + } + + sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size); + + ret = 0; + if (wsize->regs) + LOG_ERR_RET(sensor_write_array(sd, wsize->regs, wsize->regs_size)) + + if (wsize->set_size) + LOG_ERR_RET(wsize->set_size(sd)) + + info->fmt = sensor_fmt; + info->width = wsize->width; + info->height = wsize->height; + ov4689_sensor_vts = wsize->vts; + + vfe_dev_print("s_fmt = %x, width = %d, height = %d\n",sensor_fmt->mbus_code,wsize->width,wsize->height); + + if(info->capture_mode == V4L2_MODE_VIDEO) + { + //video + + } else { + //capture image + + } + //usleep_range(300000,350000); + //sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); + vfe_dev_print("s_fmt end\n"); + return 0; +} + +/* + * Implement G/S_PARM. There is a "high quality" mode we could try + * to do someday; for now, we just do the frame rate tweak. + */ +static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + struct sensor_info *info = to_state(sd); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->capturemode = info->capture_mode; + cp->timeperframe = info->tpf; + return 0; +} + +static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct v4l2_captureparm *cp = &parms->parm.capture; + //struct v4l2_fract *tpf = &cp->timeperframe; + struct sensor_info *info = to_state(sd); + //unsigned char div; + + vfe_dev_dbg("sensor_s_parm\n"); + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + +// cp->timeperframe.denominator = 60; +// cp->timeperframe.numerator = 1; + + info->tpf = cp->timeperframe; + vfe_dev_dbg("ov4689_s_parm fps = %d\n", info->tpf.denominator); + + if (info->tpf.numerator == 0) + return -EINVAL; + + info->capture_mode = cp->capturemode; + + return 0; +} + + +static int sensor_queryctrl(struct v4l2_subdev *sd, + struct v4l2_queryctrl *qc) +{ + /* Fill in min, max, step and default value for these controls. */ + /* see include/linux/videodev2.h for details */ + + switch (qc->id) { + case V4L2_CID_GAIN: + return v4l2_ctrl_query_fill(qc, 1*16, 128*16-1, 1, 16); + case V4L2_CID_EXPOSURE: + return v4l2_ctrl_query_fill(qc, 0, 65536*16, 1, 0); + } + return -EINVAL; +} + +static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_g_gain(sd, &ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_g_exp(sd, &ctrl->value); + } + return -EINVAL; +} + +static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc; + int ret; + + qc.id = ctrl->id; + ret = sensor_queryctrl(sd, &qc); + if (ret < 0) { + return ret; + } + + if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) { + return -ERANGE; + } + + switch (ctrl->id) { + case V4L2_CID_GAIN: + return sensor_s_gain(sd, ctrl->value); + case V4L2_CID_EXPOSURE: + return sensor_s_exp(sd, ctrl->value); + } + return -EINVAL; +} + + +static int sensor_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SENSOR, 0); +} + + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops sensor_core_ops = { + .g_chip_ident = sensor_g_chip_ident, + .g_ctrl = sensor_g_ctrl, + .s_ctrl = sensor_s_ctrl, + .queryctrl = sensor_queryctrl, + .reset = sensor_reset, + .init = sensor_init, + .s_power = sensor_power, + .ioctl = sensor_ioctl, +}; + +static const struct v4l2_subdev_video_ops sensor_video_ops = { + .enum_mbus_fmt = sensor_enum_fmt, + .enum_framesizes = sensor_enum_size, + .try_mbus_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .s_parm = sensor_s_parm, + .g_parm = sensor_g_parm, + .g_mbus_config = sensor_g_mbus_config, +}; + +static const struct v4l2_subdev_ops sensor_ops = { + .core = &sensor_core_ops, + .video = &sensor_video_ops, +}; + +/* ----------------------------------------------------------------------- */ +static struct cci_driver cci_drv = { + .name = SENSOR_NAME, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct sensor_info *info; +// int ret; + + info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); + if (info == NULL) + return -ENOMEM; + sd = &info->sd; + glb_sd = sd; + cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); + + info->fmt = &sensor_formats[0]; + info->af_first_flag = 1; + info->init_first_flag = 1; + + return 0; +} + + +static int sensor_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd; + sd = cci_dev_remove_helper(client, &cci_drv); + kfree(to_state(sd)); + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + { SENSOR_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + + +static struct i2c_driver sensor_driver = { + .driver = { + .owner = THIS_MODULE, + .name = SENSOR_NAME, + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; +static __init int init_sensor(void) +{ + return cci_dev_init_helper(&sensor_driver); +} + +static __exit void exit_sensor(void) +{ + cci_dev_exit_helper(&sensor_driver); +} + +module_init(init_sensor); +module_exit(exit_sensor); + diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov5647.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov5647.c index a3fb4acf..0e6702fe 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov5647.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov5647.c @@ -790,127 +790,83 @@ static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) static int sensor_power(struct v4l2_subdev *sd, int on) { - int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - ret = 0; - switch(on) - { - case CSI_SUBDEV_STBY_ON: - vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); - //disable io oe - vfe_dev_print("disalbe oe!\n"); - ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); - if(ret < 0) - vfe_dev_err("disalbe oe falied!\n"); - //software standby on - ret = sensor_s_sw_stby(sd, CSI_STBY_ON); - if(ret < 0) - vfe_dev_err("soft stby falied!\n"); - usleep_range(10000,12000); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - -// //reset on io -// vfe_gpio_write(sd,RESET,CSI_RST_ON); -// usleep_range(10000,12000); - //standby on io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //inactive mclk after stadby in - vfe_set_mclk(sd,OFF); - break; - case CSI_SUBDEV_STBY_OFF: - vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //active mclk before stadby out - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - //software standby - ret = sensor_s_sw_stby(sd, CSI_STBY_OFF); - if(ret < 0) - vfe_dev_err("soft stby off falied!\n"); - usleep_range(10000,12000); - vfe_dev_print("enable oe!\n"); - ret = sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); - if(ret < 0) - vfe_dev_err("enable oe falied!\n"); - break; - case CSI_SUBDEV_PWR_ON: - vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - - //power on reset - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - //power down io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(1000,1200); - //active mclk before power on - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - usleep_range(10000,12000); - //power supply - vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,AFVDD,ON); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(10000,12000); - //reset after power on - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(30000,31000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - case CSI_SUBDEV_PWR_OFF: - vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //inactive mclk before power off - vfe_set_mclk(sd,OFF); - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - vfe_set_pmu_channel(sd,AFVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - //standby and reset io - usleep_range(10000,12000); - vfe_gpio_write(sd,POWER_EN,CSI_STBY_OFF); - vfe_gpio_write(sd,RESET,CSI_RST_ON); - //set the io to hi-z - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); - break; - default: - return -EINVAL; - } + int ret = 0; + switch(on) + { + case CSI_SUBDEV_STBY_ON: + vfe_dev_dbg("CSI_SUBDEV_STBY_ON!\n"); + ret = sensor_s_sw_stby(sd, CSI_GPIO_HIGH); + if(ret < 0) + vfe_dev_err("soft stby falied!\n"); + usleep_range(10000,12000); + cci_lock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + cci_unlock(sd); + vfe_set_mclk(sd,OFF); + break; + case CSI_SUBDEV_STBY_OFF: + vfe_dev_dbg("CSI_SUBDEV_STBY_OFF!\n"); + cci_lock(sd); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + ret = sensor_s_sw_stby(sd, CSI_GPIO_LOW); + if(ret < 0) + vfe_dev_err("soft stby off falied!\n"); + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_ON: + vfe_dev_dbg("CSI_SUBDEV_PWR_ON!\n"); + cci_lock(sd); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,IOVDD,ON); + usleep_range(5000,6000); + + vfe_set_pmu_channel(sd,AVDD,ON); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + usleep_range(10000,12000); + + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + + cci_unlock(sd); + break; + case CSI_SUBDEV_PWR_OFF: + vfe_dev_dbg("CSI_SUBDEV_PWR_OFF!\n"); + cci_lock(sd); + + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,DVDD,OFF); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,AVDD,OFF); + usleep_range(5000,6000); + vfe_set_pmu_channel(sd,IOVDD,OFF); + vfe_set_pmu_channel(sd,AFVDD,OFF); + vfe_set_mclk(sd,OFF); + usleep_range(10000,12000); + vfe_gpio_set_status(sd,RESET,0);//set the gpio to input + vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input + cci_unlock(sd); + break; + default: + return -EINVAL; + } - return 0; + return 0; } - static int sensor_reset(struct v4l2_subdev *sd, u32 val) { switch(val) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov8858_4lane.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov8858_4lane.c index 30ce9a7b..e113a1c1 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/ov8858_4lane.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/ov8858_4lane.c @@ -106,6 +106,7 @@ static inline struct sensor_info *to_state(struct v4l2_subdev *sd) static struct regval_list sensor_default_regs[] = { //4lane initial {0x0103, 0x01},// ; software reset + {REG_DLY,0x10}, //must delay {0x0100, 0x00},// ; software standby {0x0100, 0x00},// ; {0x0100, 0x00},// ; @@ -416,6 +417,7 @@ static struct regval_list sensor_default_regs[] = { static struct regval_list sensor_quxga_regs[] = { //@@3264_2448_4lane_30fps_720Mbps/lane {0x0100, 0x00},// + {REG_DLY,0x05}, //must delay {0x030f, 0x04},// ; pll2_divsp {0x3501, 0x9a},// ; exposure M {0x3502, 0x20},// ; exposure L @@ -518,6 +520,7 @@ static struct regval_list sensor_quxga_regs[] = { static struct regval_list sensor_6M_regs[] = { //@@3264_1836_4Lane_30fps_720Mbps/lane {0x0100, 0x00},// + {REG_DLY,0x05}, //must delay {0x030f, 0x04},// ; pll2_divsp {0x3501, 0x74},// ; exposure M {0x3502, 0x80},// ; exposure L @@ -618,6 +621,7 @@ static struct regval_list sensor_6M_regs[] = { static struct regval_list sensor_uxga_regs[] = { //@@1632_1224_4Lane_30fps_720Mbps/lane {0x0100, 0x00},// + {REG_DLY,0x05}, //must delay {0x030f, 0x09},// ; pll2_divsp {0x3501, 0x4d},// ; exposure M {0x3502, 0x40},// ; exposure L diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k3h7.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k3h7.c index ac859590..ec9ff570 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k3h7.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k3h7.c @@ -1574,7 +1574,8 @@ static struct regval_list sensor_default_regs[] = { //for capture static struct regval_list sensor_quxga_regs[] = { //quxga {8, 0x0100,0x00}, //stream off -{8, 0x0104,0x01}, //group on +#if 1 +//{8, 0x0104,0x01}, //group on //==================================================================== // |-->dbr_clk_div================>charge_pump_clk // 6~54 3~6 0.5~1G| |-->gray_div====>adc_clk @@ -1584,17 +1585,17 @@ static struct regval_list sensor_quxga_regs[] = { //quxga //==================================================================== // set PLL {16, 0x0304,0x0006}, //pre_pll_clk_div -{16, 0x0306,0x008a}, //pll_multiplier 15/20/30fps-0x8a/0xb8/0x +{16, 0x0306,0x008c}, //pll_multiplier 15/20/30fps-0x8a/0xb8/0x {16, 0x0302,0x0001}, //vt_sys_clk_div -{16, 0x0300,0x0004}, //vt_pix_clk_div +{16, 0x0300,0x0002}, //vt_pix_clk_div {16, 0x030C,0x0006}, //2nd_pre_pll_clk_div -{16, 0x030E,0x00b0}, //2nd_pll_multiplier +{16, 0x030E,0x00a5}, //2nd_pll_multiplier {16, 0x030A,0x0001}, //op_sys_clk_div {16, 0x0308,0x0008}, //op_pix_clk_div //set output size -{16, 0x0342,0x0E80}, // frame_timing_line_length_pck -{16, 0x0340,0x09ae}, // frame_timing_frame_length_lines +{16, 0x0342,0x0E68}, // frame_timing_line_length_pck +{16, 0x0340,0x0bdc},//9e2}, // frame_timing_frame_length_lines {16, 0x0344,0x0004}, //x_addr_start {16, 0x0346,0x0004}, //y_addr_start {16, 0x0348,0x0CC3}, //x_addr_end @@ -1628,8 +1629,19 @@ static struct regval_list sensor_quxga_regs[] = { //quxga // Set gain {16, 0x0204,0x0020}, // X1 //================================= -{8, 0x0104,0x00}, //group off +//{8, 0x0104,0x00}, //group off {16, 0xffff,10}, // delay +#endif +#if 0 +{8, 0x0114,0x03}, // 4Lane +{16, 0x030E,0x00a5}, //2nd_pll_multiplier +{16, 0x0342,0x0E68}, // frame_timing_line_length_pck +{16, 0x0340,0x09e2}, // frame_timing_frame_length_lines +{16, 0x0200,0x0618}, // fine_integration_time +{16, 0x0202,0x09c9}, // coarse_integration_time +{16, 0x0204,0x0020}, // X1 +#endif + {8, 0x0100,0x01}, //stream on }; @@ -1816,7 +1828,7 @@ static int sensor_write(struct v4l2_subdev *sd, unsigned short reg, return ret; } static int print_reg(struct v4l2_subdev *sd, unsigned short addr) -{return 0; +{ int ret=0; unsigned char tmp=0xff; sensor_read_byte(sd, addr, &tmp); @@ -1957,55 +1969,6 @@ static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) vfe_dev_dbg("sensor_get_exposure = %d\n", info->exp); return 0; } - -static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) -{//return -1; - int exp_val, gain_val,frame_length,shutter; - unsigned char explow=0,expmid=0,exphigh=0; - unsigned char gainlow=0,gainhigh=0; - struct sensor_info *info = to_state(sd); - - exp_val = exp_gain->exp_val; - gain_val = exp_gain->gain_val; - - if(exp_val>0xfffff) - exp_val=0xfffff; - - gainlow=(unsigned char)((gain_val<<3)&0xff); - gainhigh=(unsigned char)((gain_val>>5)); - - exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); - expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); - explow = (unsigned char) ( (0x0000ff&exp_val) ); - shutter = exp_val/16; - if(shutter > s5k3h7_sensor_vts- 4) - frame_length = shutter + 4; - else - frame_length = s5k3h7_sensor_vts; - - sensor_write(sd, 0x3208, 0x00);//enter group write - - sensor_write(sd, 0x3503, 0x03); - - sensor_write(sd, 0x380f, (frame_length & 0xff)); - sensor_write(sd, 0x380e, (frame_length >> 8)); - - sensor_write(sd, 0x3509, gainlow); - sensor_write(sd, 0x3508, gainhigh); - - sensor_write(sd, 0x3502, explow); - sensor_write(sd, 0x3501, expmid); - sensor_write(sd, 0x3500, exphigh); - sensor_write(sd, 0x3208, 0x10);//end group write - sensor_write(sd, 0x3208, 0xa0);//init group write - - printk("exp_val = %d,gain_val = %d 0x%x 0x%x\t%d\n",exp_val,gain_val,gainhigh,gainlow, frame_length); - - info->exp = exp_val; - info->gain = gain_val; - return 0; -} - static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) { unsigned int exp_coarse; @@ -2061,6 +2024,56 @@ static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val) return 0; } + +static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) +{//return -1; + int exp_val, gain_val,shutter,frame_length; + //return -EINVAL; + + unsigned char explow,exphigh; + unsigned char gainlow=0; + unsigned char gainhigh=0; + struct sensor_info *info = to_state(sd); + exp_val = exp_gain->exp_val; + gain_val = exp_gain->gain_val; + + +//sensor_s_gain(sd, gain_val); +//sensor_s_exp(sd, exp_val); +#if 1 + shutter = exp_val>>4; + + if(shutter > s5k3h7_sensor_vts-4) + frame_length = shutter+4; + else + frame_length = s5k3h7_sensor_vts; + +// print_reg(sd,0x0341); +// print_reg(sd,0x0340); +// sensor_write(sd, 0x0341,( (frame_length) & 0xff)); +// sensor_write(sd, 0x0340,((frame_length) >> 8)); +// vfe_dev_dbg("frame_length = %d,%d,%d\n",frame_length,shutter,s5k3h7_sensor_vts); + sensor_write(sd,0x0104,0x01); + sensor_write(sd, 0x0340, frame_length); + sensor_s_gain(sd, gain_val); + sensor_s_exp(sd, exp_val); + sensor_write(sd,0x0104,0x00); + + printk("s5k3h7 sensor_set_gain = %d, %d Done!\n", gain_val,exp_val); + +// sensor_write(sd,0x0104,0x01); +// sensor_write(sd, 0x0341,0xae); +// sensor_write(sd, 0x0340,0x09); +// sensor_write(sd,0x0104,0x00); + + + //vfe_dev_dbg("s5k5e2 sensor_set_gain = %d, Done!\n", gain_val); +#endif + info->gain = gain_val; + info->exp = exp_val; + return 0; +} + static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) { int ret; @@ -2360,16 +2373,16 @@ static struct sensor_win_size sensor_win_sizes[] = { .height = QUXGA_HEIGHT, .hoffset = 0, .voffset = 0, - .hts = 3712,//must over x, limited by sensor - .vts = 2478, - .pclk = 184*1000*1000, - .mipi_bps = 400*1000*1000, + .hts = 3688,//must over x, limited by sensor + .vts = 3036,//2530, + .pclk = 280*1000*1000, + .mipi_bps = 660*1000*1000, .fps_fixed = 1, .bin_factor = 1, .intg_min = 1<<4, - .intg_max = 2484<<4, + .intg_max = 3036<<4, .gain_min = 1<<4, - .gain_max = 16<<4, + .gain_max = 8<<4, .regs = sensor_quxga_regs, .regs_size = ARRAY_SIZE(sensor_quxga_regs), .set_size = NULL, @@ -2397,45 +2410,7 @@ static struct sensor_win_size sensor_win_sizes[] = { .regs_size = ARRAY_SIZE(sensor_1080p_regs),//sensor_1080p_regs .set_size = NULL, }, - /* UXGA */ -// { -// .width = UXGA_WIDTH, -// .height = UXGA_HEIGHT, -// .hoffset = 0, -// .voffset = 0, -// .hts = 2800,//limited by sensor -// .vts = 1000, -// .pclk = 84*1000*1000, -// .fps_fixed = 1, -// .bin_factor = 1, -// .intg_min = , -// .intg_max = , -// .gain_min = , -// .gain_max = , -// .regs = sensor_uxga_regs, -// .regs_size = ARRAY_SIZE(sensor_uxga_regs), -// .set_size = NULL, -// }, - /* 720p */ - { - .width = HD720_WIDTH, - .height = HD720_HEIGHT, - .hoffset = 0, - .voffset = 0, - .hts = 2800,// - .vts = 1000, - .pclk = 84*1000*1000, - .mipi_bps = 200*1000*1000, - .fps_fixed = 1, - .bin_factor = 1, - .intg_min = 3<<4, - .intg_max = (1000-8)<<4, - .gain_min = 1<<4, - .gain_max = 16<<4, - .regs = sensor_720p_regs,// - .regs_size = ARRAY_SIZE(sensor_720p_regs),// - .set_size = NULL, - }, + }; #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) @@ -2588,7 +2563,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, sensor_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); - if(1) + if(0) { unsigned int i=0; for(i=0;i<0x40;i+=2) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec.c index 5abfe6cf..541a1648 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec.c @@ -5400,7 +5400,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) if (ret < 0) { vfe_dev_err("sensor_g_single_af read error !\n"); - ret = -EAGAIN; + ret = V4L2_AUTO_FOCUS_STATUS_FAILED; goto af_out; } @@ -5408,7 +5408,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) vfe_dev_dbg("Single AF 1st is busy,value = 0x%4x\n",rdval); msleep(50); coarse_af_pd = 0; - return EBUSY; + return V4L2_AUTO_FOCUS_STATUS_BUSY; } else if (rdval == 0x0002) { //focus ok coarse_af_pd = 1; @@ -5417,7 +5417,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) vfe_dev_print("Single AF 1st is failed,value = 0x%4x\n",rdval); info->focus_status = 0; //idle coarse_af_pd = 2; - ret = EFAULT; + ret = V4L2_AUTO_FOCUS_STATUS_FAILED; goto af_out; } } @@ -5440,7 +5440,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) if((rdval&0xff00)!=0x0000) { vfe_dev_dbg("Single AF 2nd is busy,value = 0x%4x\n",rdval); - return EBUSY; + return V4L2_AUTO_FOCUS_STATUS_BUSY; } vfe_dev_print("Single AF 2nd is complete,value = 0x%4x\n",rdval); @@ -5452,7 +5452,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) //ae lock off sensor_ae_awb_lockoff(sd); - return ret; + return V4L2_AUTO_FOCUS_STATUS_REACHED; } static int sensor_g_contin_af(struct v4l2_subdev *sd) diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec_mipi.c b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec_mipi.c index 3b179897..c56e8dcb 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec_mipi.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/device/s5k4ec_mipi.c @@ -68,6 +68,31 @@ MODULE_LICENSE("GPL"); #define AF_WIN_NEW_COORD +#define QSXGA_WIDTH_S5K 2560 +#define QSXGA_HEIGHT_S5K 1920 +#define QXGA_WIDTH_S5K 2048 +#define QXGA_HEIGHT_S5K 1536 +#define HD1080_WIDTH_S5K 1920 +#define HD1080_HEIGHT_S5K 1080 +#define UXGA_WIDTH_S5K 1600 +#define UXGA_HEIGHT_S5K 1200 +#define SXGA_WIDTH_S5K 1280 +#define SXGA_HEIGHT_S5K 960 +#define HD720_WIDTH_S5K 1280 +#define HD720_HEIGHT_S5K 720 +#define XGA_WIDTH_S5K 1024 +#define XGA_HEIGHT_S5K 768 +#define SVGA_WIDTH_S5K 800 +#define SVGA_HEIGHT_S5K 600 +#define VGA_WIDTH_S5K 640 +#define VGA_HEIGHT_S5K 480 +#define QVGA_WIDTH_S5K 320 +#define QVGA_HEIGHT_S5K 240 +#define CIF_WIDTH_S5K 352 +#define CIF_HEIGHT_S5K 288 +#define QCIF_WIDTH_S5K 176 +#define QCIF_HEIGHT_S5K 144 + unsigned int coarse_af_pd=0; /* @@ -82,6 +107,11 @@ unsigned int coarse_af_pd=0; #define SENSOR_NAME "s5k4ec_mipi" /* Registers */ +/* +if s5k4ec_firsttime ==0 ,sensor will init sensor_default_regs; +otherwise it just standy off. +*/ +//static unsigned int s5k4ec_firsttime =0; //potter add static int sensor_s_band_filter(struct v4l2_subdev *sd, enum v4l2_power_line_frequency value); @@ -109,1620 +139,1650 @@ static inline struct sensor_info *to_state(struct v4l2_subdev *sd) */ static struct regval_list sensor_default_regs[] = { -//================================================================================== -// 00.History -//================================================================================== -//2010 : EVT1.1 -//20110429 : LSI CSE Standard -//20110728 : Sequence Changed -//20110728 : ESD Check Register Address Changed -//20110829 : TnP Changed by S.Y.Lee -//20120104 : init Parm Update sequence changed -//20120201 : Flash�� �ֺ��� Green Noise ���� setting -//20120228 : Add Brightness Block -//================================================================================== - -//================================================================================== -// 01.Start Setting -//================================================================================== {0xFCFC, 0xD000}, -{0x0010, 0x0001}, -{0x1030, 0x0000}, -{0x0014, 0x0001}, - -//p10 //Delay 10ms +{0x0010, 0x0001}, //S/W Reset +{0x1030, 0x0000}, //contint_host_int +{0x0014, 0x0001}, //sw_load_complete - Release CORE (Arm) from reset state //================================================================================== //02.ETC Setting //================================================================================== +{0x002A,0x1082}, +{0x0F12,0x0000}, // cregs_d0_d4_cd10 //D4[9:8], D3[7:6], D2[5:4], D1[3:2], D0[1:0] +{0x0F12,0x0000}, // cregs_d5_d9_cd10 //D9[9:8], D8[7:6], D7[5:4], D6[3:2], D5[1:0] +{0x002A,0x1088}, +{0x0F12,0x0000}, // cregs_clks_output_cd10 //SDA[11:10], SCL[9:8], PCLK[7:6], VSYNC[3:2], HSYNC[1:0] -{0x002A, 0x1082}, -{0x0F12, 0x0000}, //cregs_d0_d4_cd10 //D4[9:8], D3[7:6], D2[5:4], D1[3:2], D0[1:0] -{0x0F12, 0x0000}, //cregs_d5_d9_cd10 //D9[9:8], D8[7:6], D7[5:4], D6[3:2], D5[1:0] -{0x002A, 0x1088}, -{0x0F12, 0x0000}, //cregs_clks_output_cd10 //SDA[11:10], SCL[9:8], PCLK[7:6], VSYNC[3:2], HSYNC[1:0] //================================================================================== // 03.Analog Setting & ASP Control //================================================================================== - //This register is for FACTORY ONLY. //If you change it without prior notification //YOU are RESPONSIBLE for the FAILURE that will happen in the future - {0x0028, 0xD000}, -{0x002A, 0x007A}, -{0x0f12, 0x0000}, -{0x002A, 0xE406}, //[7]f_ladlc_en [6:5]f max [4]fadlc_en [3:2]L max [1]ladlc_en [0]adlc_ch_sel -{0x0F12, 0x0092}, -{0x002A, 0xE410}, -{0x0F12, 0x3804}, //[15:8]fadlc_filter_co_b [7:0]fadlc_filter_co_a -{0x002A, 0xE41A}, -{0x0F12, 0x0010}, -{0x002A, 0xE420}, -{0x0F12, 0x0003}, //adlc_fadlc_filter_refresh -{0x0F12, 0x0060}, //adlc_filter_level_diff_threshold -{0x002A, 0xE42E}, -{0x0F12, 0x0004}, //dithered l-ADLC(4bit) -{0x002A, 0xF400}, -{0x0F12, 0x5A3C}, //[15:8]stx_width [7:0]dstx_width -{0x0F12, 0x0023}, //[14]binning_test [13]gain_mode [11:12]row_id [10]cfpn_test [9]pd_pix [8]teg_en [7]adc_res [6]smp_en [5]ldb_en [4]ld_en [3]clp_en [2]srx_en [1]dshut_en [0]dcds_en -{0x0F12, 0x8080}, //CDS option -{0x0F12, 0x03AF}, //[11:6]rst_mx [5:0]sig_mx -{0x0F12, 0x000A}, //Avg mode -{0x0F12, 0xAA54}, //x1~x1.49:No MS x1.5~x3.99:MS2 x4~x16:MS4 -{0x0F12, 0x0040}, //RMP option [6]1: RES gain -{0x0F12, 0x464E}, //[14]msoff_en [13:8]off_rst [7:0]adc_sat -{0x0F12, 0x0240}, //bist_sig_width_e -{0x0F12, 0x0240}, //bist_sig_width_o -{0x0F12, 0x0040}, //[9]dbs_bist_en [8:0]bist_rst_width -{0x0F12, 0x1000}, //[15]aac_en [14]GCLK_DIV2_EN [13:10]dl_cont [9:8]dbs_mode [7:0]dbs_option -{0x0F12, 0x55cc}, //bias [15:12]pix [11:8]pix_bst [7:4]comp2 [3:0]comp1 -{0x0F12, 0xD000}, //[15:8]clp_lvl [7:0]ref_option [5]pix_bst_en -{0x0F12, 0x0010}, //[7:0]monit -{0x0F12, 0x0202}, //[15:8]dbr_tune_tgsl [7:0]dbr_tune_pix -{0x0F12, 0x0401}, //[15:8]dbr_tune_ntg [7:0]dbr_tune_rg -{0x0F12, 0x0022}, //[15:8]reg_option [7:4]rosc_tune_ncp [3:0]rosc_tune_cp -{0x0F12, 0x0088}, //PD [8]inrush_ctrl [7]fblv [6]reg_ntg [5]reg_tgsl [4]reg_rg [3]reg_pix [2]ncp_rosc [1]cp_rosc [0]cp -{0x0F12, 0x009F}, //[9]capa_ctrl_en [8:7]fb_lv [6:5]dbr_clk_sel [4:0]cp_capa -{0x0F12, 0x0000}, //[15:0]blst_en_cintr -{0x0F12, 0x1800}, //[11]blst_en [10]rfpn_test [9]sl_off [8]tx_off [7:0]rdv_option -{0x0F12, 0x0088}, //[15:0]pmg_reg_tune -{0x0F12, 0x0000}, //[15:1]analog_dummy [0]pd_reg_test -{0x0F12, 0x2428}, //[13:11]srx_gap1 [10:8]srx_gap0 [7:0]stx_gap -{0x0F12, 0x0000}, //[0]atx_option -{0x0F12, 0x03EE}, //aig_avg_half -{0x0F12, 0x0000}, //[0]hvs_test_reg -{0x0F12, 0x0000}, //[0]dbus_bist_auto -{0x0F12, 0x0000}, //[7:0]dbr_option -{0x002A, 0xF552}, -{0x0F12, 0x0708}, //[7:0]lat_st [15:8]lat_width -{0x0F12, 0x080C}, //[7:0]hold_st [15:8]hold_width - -//For subsampling Size - -{0x0028, 0x7000}, -{0x002A, 0x18BC}, -{0x0F12, 0x0004}, -{0x0F12, 0x05B6}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0001}, -{0x0F12, 0x05BA}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0007}, -{0x0F12, 0x05BA}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F4}, -{0x0F12, 0x024E}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F4}, -{0x0F12, 0x05B6}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F4}, -{0x0F12, 0x05BA}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F4}, -{0x0F12, 0x024F}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0075}, -{0x0F12, 0x00CF}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0075}, -{0x0F12, 0x00D6}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0004}, -{0x0F12, 0x01F4}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x00F0}, -{0x0F12, 0x01F4}, -{0x0F12, 0x029E}, -{0x0F12, 0x05B2}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F8}, -{0x0F12, 0x0228}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0208}, -{0x0F12, 0x0238}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0218}, -{0x0F12, 0x0238}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0001}, -{0x0F12, 0x0009}, -{0x0F12, 0x00DE}, -{0x0F12, 0x05C0}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x00DF}, -{0x0F12, 0x00E4}, -{0x0F12, 0x01F8}, -{0x0F12, 0x01FD}, -{0x0F12, 0x05B6}, -{0x0F12, 0x05BB}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x01F8}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0077}, -{0x0F12, 0x007E}, -{0x0F12, 0x024F}, -{0x0F12, 0x025E}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, - - // For Capture - -{0x0F12, 0x0004}, -{0x0F12, 0x09D1}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0001}, -{0x0F12, 0x09D5}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0008}, -{0x0F12, 0x09D5}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AA}, -{0x0F12, 0x0326}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AA}, -{0x0F12, 0x09D1}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AA}, -{0x0F12, 0x09D5}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AA}, -{0x0F12, 0x0327}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0008}, -{0x0F12, 0x0084}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0008}, -{0x0F12, 0x008D}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0008}, -{0x0F12, 0x02AA}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x00AA}, -{0x0F12, 0x02AA}, -{0x0F12, 0x03AD}, -{0x0F12, 0x09CD}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AE}, -{0x0F12, 0x02DE}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02BE}, -{0x0F12, 0x02EE}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02CE}, -{0x0F12, 0x02EE}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0001}, -{0x0F12, 0x0009}, -{0x0F12, 0x0095}, -{0x0F12, 0x09DB}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0096}, -{0x0F12, 0x009B}, -{0x0F12, 0x02AE}, -{0x0F12, 0x02B3}, -{0x0F12, 0x09D1}, -{0x0F12, 0x09D6}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x02AE}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0009}, -{0x0F12, 0x0010}, -{0x0F12, 0x0327}, -{0x0F12, 0x0336}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x0F12, 0x0000}, -{0x002A, 0x1AF8}, -{0x0F12, 0x5A3C}, //senHal_TuneStr_AngTuneData1_2_D000F400 register at subsampling -{0x002A, 0x1896}, -{0x0F12, 0x0002}, //senHal_SamplingType 0002 03EE: PLA setting -{0x0F12, 0x0000}, //senHal_SamplingMode 0 : 2 PLA / 1 : 4PLA -{0x0F12, 0x0003}, -{0x002A, 0x189E}, -{0x0F12, 0x0FB0}, -{0x002A, 0x18AC}, -{0x0F12, 0x0060}, -{0x0F12, 0x0060}, -{0x0F12, 0x05C0}, -{0x0F12, 0x05C0}, -{0x002A, 0x1AEA}, -{0x0F12, 0x8080}, -{0x0F12, 0x0080}, -{0x002A, 0x1AE0}, -{0x0F12, 0x0000}, -{0x002A, 0x1A72}, -{0x0F12, 0x0000}, -{0x002A, 0x18A2}, -{0x0F12, 0x0004}, -{0x002A, 0x1A6A}, -{0x0F12, 0x009A}, -{0x002A, 0x385E}, -{0x0F12, 0x024C}, -{0x002A, 0x0EE6}, -{0x0F12, 0x0000}, -{0x002A, 0x1B2A}, -{0x0F12, 0x0300}, -{0x0F12, 0x00D6}, -{0x0F12, 0x008D}, -{0x0F12, 0x00CF}, -{0x0F12, 0x0084}, - -//================================================================================== - - +{0x002A,0x007A}, +{0x0F12,0x0000}, +{0x002A,0xE406}, +{0x0F12,0x0092}, +{0x002A,0xE410}, +{0x0F12,0x3804}, // [15:8]fadlc_filter_co_b, [7:0]fadlc_filter_co_a +{0x002A,0xE41A}, +{0x0F12,0x0010}, +{0x002A,0xE420}, +{0x0F12,0x0003}, // adlc_fadlc_filter_refresh +{0x0F12,0x0060}, // adlc_filter_level_diff_threshold +{0x002A,0xE42E}, +{0x0F12,0x0004}, // dithered l-ADLC(4bit) +{0x002A,0xF400}, +{0x0F12,0x5A3C}, // [15:8]stx_width, [7:0]dstx_width +{0x0F12,0x0023}, // [14]binning_test [13]gain_mode [11:12]row_id [10]cfpn_test [9]pd_pix [8]teg_en, [7]adc_res, [6]smp_en, [5]ldb_en, [4]ld_en, [3]clp_en [2]srx_en, [1]dshut_en, [0]dcds_en +{0x0F12,0x8080}, // CDS option +{0x0F12,0x03AF}, // [11:6]rst_mx, [5:0]sig_mx +{0x0F12,0x000A}, // Avg mode +{0x0F12,0xAA54}, // x1~x1.49:No MS, x1.5~x3.99:MS2, x4~x16:MS4 +{0x0F12,0x0040}, // RMP option [6]1: RES gain +{0x0F12,0x464E}, // [14]msoff_en, [13:8]off_rst, [7:0]adc_sat +{0x0F12,0x0240}, // bist_sig_width_e +{0x0F12,0x0240}, // bist_sig_width_o +{0x0F12,0x0040}, // [9]dbs_bist_en, [8:0]bist_rst_width +{0x0F12,0x1000}, // [15]aac_en, [14]GCLK_DIV2_EN, [13:10]dl_cont [9:8]dbs_mode, [7:0]dbs_option +{0x0F12,0x55FF}, // bias [15:12]pix, [11:8]pix_bst [7:4]comp2, [3:0]comp1 +{0x0F12,0xD000}, // [15:8]clp_lvl, [7:0]ref_option, [5]pix_bst_en +{0x0F12,0x0010}, // [7:0]monit +{0x0F12,0x0202}, // [15:8]dbr_tune_tgsl, [7:0]dbr_tune_pix +{0x0F12,0x0401}, // [15:8]dbr_tune_ntg, [7:0]dbr_tune_rg +{0x0F12,0x0022}, // [15:8]reg_option, [7:4]rosc_tune_ncp, [3:0]rosc_tune_cp +{0x0F12,0x0088}, // PD [8]inrush_ctrl, [7]fblv, [6]reg_ntg, [5]reg_tgsl, [4]reg_rg, [3]reg_pix, [2]ncp_rosc, [1]cp_rosc, [0]cp +{0x0F12,0x009F}, // [9]capa_ctrl_en, [8:7]fb_lv, [6:5]dbr_clk_sel, [4:0]cp_capa +{0x0F12,0x0000}, // [15:0]blst_en_cintr +{0x0F12,0x1800}, // [11]blst_en, [10]rfpn_test, [9]sl_off, [8]tx_off, [7:0]rdv_option +{0x0F12,0x0088}, // [15:0]pmg_reg_tune +{0x0F12,0x0000}, // [15:1]analog_dummy, [0]pd_reg_test +{0x0F12,0x2428}, // [13:11]srx_gap1, [10:8]srx_gap0, [7:0]stx_gap +{0x0F12,0x0000}, // [0]atx_option +{0x0F12,0x03EE}, // aig_avg_half +{0x0F12,0x0000}, // [0]hvs_test_reg +{0x0F12,0x0000}, // [0]dbus_bist_auto +{0x0F12,0x0000}, // [7:0]dbr_option +{0x002A,0xF552}, +{0x0F12,0x0708}, // [7:0]lat_st, [15:8]lat_width +{0x0F12,0x080C}, // [7:0]hold_st, [15:8]hold_width //================================================================================= -// 05.Trap and Patch +// 04.Trap and Patch //================================================================================= // Start of Patch data -{0x0028, 0x7000}, -{0x002A, 0x3AF8}, -{0x0F12, 0xB570}, // 70003AF8 -{0x0F12, 0x4B39}, // 70003AFA -{0x0F12, 0x4939}, // 70003AFC -{0x0F12, 0x483A}, // 70003AFE -{0x0F12, 0x2200}, // 70003B00 -{0x0F12, 0xC008}, // 70003B02 -{0x0F12, 0x6001}, // 70003B04 -{0x0F12, 0x4939}, // 70003B06 -{0x0F12, 0x4839}, // 70003B08 -{0x0F12, 0x2401}, // 70003B0A -{0x0F12, 0xF000}, // 70003B0C -{0x0F12, 0xFBEC}, // 70003B0E -{0x0F12, 0x4938}, // 70003B10 -{0x0F12, 0x4839}, // 70003B12 -{0x0F12, 0x2502}, // 70003B14 -{0x0F12, 0x0022}, // 70003B16 -{0x0F12, 0xF000}, // 70003B18 -{0x0F12, 0xFBE6}, // 70003B1A -{0x0F12, 0x4837}, // 70003B1C -{0x0F12, 0x0261}, // 70003B1E -{0x0F12, 0x8001}, // 70003B20 -{0x0F12, 0x2100}, // 70003B22 -{0x0F12, 0x8041}, // 70003B24 -{0x0F12, 0x4936}, // 70003B26 -{0x0F12, 0x4836}, // 70003B28 -{0x0F12, 0x6041}, // 70003B2A -{0x0F12, 0x4936}, // 70003B2C -{0x0F12, 0x4837}, // 70003B2E -{0x0F12, 0x2403}, // 70003B30 -{0x0F12, 0x002A}, // 70003B32 -{0x0F12, 0xF000}, // 70003B34 -{0x0F12, 0xFBD8}, // 70003B36 -{0x0F12, 0x4832}, // 70003B38 -{0x0F12, 0x4935}, // 70003B3A -{0x0F12, 0x30C0}, // 70003B3C -{0x0F12, 0x63C1}, // 70003B3E -{0x0F12, 0x4930}, // 70003B40 -{0x0F12, 0x4834}, // 70003B42 -{0x0F12, 0x3980}, // 70003B44 -{0x0F12, 0x6408}, // 70003B46 -{0x0F12, 0x4833}, // 70003B48 -{0x0F12, 0x4934}, // 70003B4A -{0x0F12, 0x6388}, // 70003B4C -{0x0F12, 0x4934}, // 70003B4E -{0x0F12, 0x4834}, // 70003B50 -{0x0F12, 0x0022}, // 70003B52 -{0x0F12, 0x2504}, // 70003B54 -{0x0F12, 0xF000}, // 70003B56 -{0x0F12, 0xFBC7}, // 70003B58 -{0x0F12, 0x4933}, // 70003B5A -{0x0F12, 0x4833}, // 70003B5C -{0x0F12, 0x2405}, // 70003B5E -{0x0F12, 0x002A}, // 70003B60 -{0x0F12, 0xF000}, // 70003B62 -{0x0F12, 0xF881}, // 70003B64 -{0x0F12, 0x491F}, // 70003B66 -{0x0F12, 0x4830}, // 70003B68 -{0x0F12, 0x0022}, // 70003B6A -{0x0F12, 0x2506}, // 70003B6C -{0x0F12, 0x39B6}, // 70003B6E -{0x0F12, 0x1D80}, // 70003B70 -{0x0F12, 0xF000}, // 70003B72 -{0x0F12, 0xF879}, // 70003B74 -{0x0F12, 0x482D}, // 70003B76 -{0x0F12, 0x492D}, // 70003B78 -{0x0F12, 0x2407}, // 70003B7A -{0x0F12, 0x002A}, // 70003B7C -{0x0F12, 0x300C}, // 70003B7E -{0x0F12, 0xF000}, // 70003B80 -{0x0F12, 0xF872}, // 70003B82 -{0x0F12, 0x4829}, // 70003B84 -{0x0F12, 0x492B}, // 70003B86 -{0x0F12, 0x0022}, // 70003B88 -{0x0F12, 0x2508}, // 70003B8A -{0x0F12, 0x3010}, // 70003B8C -{0x0F12, 0xF000}, // 70003B8E -{0x0F12, 0xF86B}, // 70003B90 -{0x0F12, 0x4929}, // 70003B92 -{0x0F12, 0x4829}, // 70003B94 -{0x0F12, 0x2409}, // 70003B96 -{0x0F12, 0x002A}, // 70003B98 -{0x0F12, 0xF000}, // 70003B9A -{0x0F12, 0xFBA5}, // 70003B9C -{0x0F12, 0x4928}, // 70003B9E -{0x0F12, 0x4828}, // 70003BA0 -{0x0F12, 0x0022}, // 70003BA2 -{0x0F12, 0x250A}, // 70003BA4 -{0x0F12, 0xF000}, // 70003BA6 -{0x0F12, 0xFB9F}, // 70003BA8 -{0x0F12, 0x4927}, // 70003BAA -{0x0F12, 0x4827}, // 70003BAC -{0x0F12, 0x240B}, // 70003BAE -{0x0F12, 0x002A}, // 70003BB0 -{0x0F12, 0xF000}, // 70003BB2 -{0x0F12, 0xFB99}, // 70003BB4 -{0x0F12, 0x4926}, // 70003BB6 -{0x0F12, 0x4826}, // 70003BB8 -{0x0F12, 0x0022}, // 70003BBA -{0x0F12, 0x250C}, // 70003BBC -{0x0F12, 0xF000}, // 70003BBE -{0x0F12, 0xFB93}, // 70003BC0 -{0x0F12, 0x4925}, // 70003BC2 -{0x0F12, 0x4825}, // 70003BC4 -{0x0F12, 0x240D}, // 70003BC6 -{0x0F12, 0x002A}, // 70003BC8 -{0x0F12, 0xF000}, // 70003BCA -{0x0F12, 0xFB8D}, // 70003BCC -{0x0F12, 0x4924}, // 70003BCE -{0x0F12, 0x4824}, // 70003BD0 -{0x0F12, 0x0022}, // 70003BD2 -{0x0F12, 0xF000}, // 70003BD4 -{0x0F12, 0xFB88}, // 70003BD6 -{0x0F12, 0xBC70}, // 70003BD8 -{0x0F12, 0xBC08}, // 70003BDA -{0x0F12, 0x4718}, // 70003BDC -{0x0F12, 0x0000}, // 70003BDE -{0x0F12, 0x017B}, // 70003BE0 -{0x0F12, 0x4EC2}, // 70003BE2 -{0x0F12, 0x037F}, // 70003BE4 -{0x0F12, 0x0000}, // 70003BE6 -{0x0F12, 0x1F90}, // 70003BE8 -{0x0F12, 0x7000}, // 70003BEA -{0x0F12, 0x3C81}, // 70003BEC -{0x0F12, 0x7000}, // 70003BEE -{0x0F12, 0xE38B}, // 70003BF0 -{0x0F12, 0x0000}, // 70003BF2 -{0x0F12, 0x3CB9}, // 70003BF4 -{0x0F12, 0x7000}, // 70003BF6 -{0x0F12, 0xC3B1}, // 70003BF8 -{0x0F12, 0x0000}, // 70003BFA -{0x0F12, 0x4780}, // 70003BFC -{0x0F12, 0x7000}, // 70003BFE -{0x0F12, 0x3D17}, // 70003C00 -{0x0F12, 0x7000}, // 70003C02 -{0x0F12, 0x0080}, // 70003C04 -{0x0F12, 0x7000}, // 70003C06 -{0x0F12, 0x3D53}, // 70003C08 -{0x0F12, 0x7000}, // 70003C0A -{0x0F12, 0xB49D}, // 70003C0C -{0x0F12, 0x0000}, // 70003C0E -{0x0F12, 0x3DFF}, // 70003C10 -{0x0F12, 0x7000}, // 70003C12 -{0x0F12, 0x3DB3}, // 70003C14 -{0x0F12, 0x7000}, // 70003C16 -{0x0F12, 0xFFFF}, // 70003C18 -{0x0F12, 0x00FF}, // 70003C1A -{0x0F12, 0x17E0}, // 70003C1C -{0x0F12, 0x7000}, // 70003C1E -{0x0F12, 0x3F7B}, // 70003C20 -{0x0F12, 0x7000}, // 70003C22 -{0x0F12, 0x053D}, // 70003C24 -{0x0F12, 0x0000}, // 70003C26 -{0x0F12, 0x0000}, // 70003C28 -{0x0F12, 0x0A89}, // 70003C2A -{0x0F12, 0x6CD2}, // 70003C2C -{0x0F12, 0x0000}, // 70003C2E -{0x0F12, 0x0000}, // 70003C30 -{0x0F12, 0x0A9A}, // 70003C32 -{0x0F12, 0x0000}, // 70003C34 -{0x0F12, 0x02D2}, // 70003C36 -{0x0F12, 0x3FC9}, // 70003C38 -{0x0F12, 0x7000}, // 70003C3A -{0x0F12, 0x9E65}, // 70003C3C -{0x0F12, 0x0000}, // 70003C3E -{0x0F12, 0x403D}, // 70003C40 -{0x0F12, 0x7000}, // 70003C42 -{0x0F12, 0x7C49}, // 70003C44 -{0x0F12, 0x0000}, // 70003C46 -{0x0F12, 0x40B1}, // 70003C48 -{0x0F12, 0x7000}, // 70003C4A -{0x0F12, 0x7C63}, // 70003C4C -{0x0F12, 0x0000}, // 70003C4E -{0x0F12, 0x40CD}, // 70003C50 -{0x0F12, 0x7000}, // 70003C52 -{0x0F12, 0x8F01}, // 70003C54 -{0x0F12, 0x0000}, // 70003C56 -{0x0F12, 0x416F}, // 70003C58 -{0x0F12, 0x7000}, // 70003C5A -{0x0F12, 0x7F3F}, // 70003C5C -{0x0F12, 0x0000}, // 70003C5E -{0x0F12, 0x41FD}, // 70003C60 -{0x0F12, 0x7000}, // 70003C62 -{0x0F12, 0x98C5}, // 70003C64 -{0x0F12, 0x0000}, // 70003C66 -{0x0F12, 0xB570}, // 70003C68 -{0x0F12, 0x000C}, // 70003C6A -{0x0F12, 0x0015}, // 70003C6C -{0x0F12, 0x0029}, // 70003C6E -{0x0F12, 0xF000}, // 70003C70 -{0x0F12, 0xFB42}, // 70003C72 -{0x0F12, 0x49F8}, // 70003C74 -{0x0F12, 0x00A8}, // 70003C76 -{0x0F12, 0x500C}, // 70003C78 -{0x0F12, 0xBC70}, // 70003C7A -{0x0F12, 0xBC08}, // 70003C7C -{0x0F12, 0x4718}, // 70003C7E -{0x0F12, 0x6808}, // 70003C80 -{0x0F12, 0x0400}, // 70003C82 -{0x0F12, 0x0C00}, // 70003C84 -{0x0F12, 0x6849}, // 70003C86 -{0x0F12, 0x0409}, // 70003C88 -{0x0F12, 0x0C09}, // 70003C8A -{0x0F12, 0x4AF3}, // 70003C8C -{0x0F12, 0x8992}, // 70003C8E -{0x0F12, 0x2A00}, // 70003C90 -{0x0F12, 0xD00D}, // 70003C92 -{0x0F12, 0x2300}, // 70003C94 -{0x0F12, 0x1A89}, // 70003C96 -{0x0F12, 0xD400}, // 70003C98 -{0x0F12, 0x000B}, // 70003C9A -{0x0F12, 0x0419}, // 70003C9C -{0x0F12, 0x0C09}, // 70003C9E -{0x0F12, 0x23FF}, // 70003CA0 -{0x0F12, 0x33C1}, // 70003CA2 -{0x0F12, 0x1810}, // 70003CA4 -{0x0F12, 0x4298}, // 70003CA6 -{0x0F12, 0xD800}, // 70003CA8 -{0x0F12, 0x0003}, // 70003CAA -{0x0F12, 0x0418}, // 70003CAC -{0x0F12, 0x0C00}, // 70003CAE -{0x0F12, 0x4AEB}, // 70003CB0 -{0x0F12, 0x8150}, // 70003CB2 -{0x0F12, 0x8191}, // 70003CB4 -{0x0F12, 0x4770}, // 70003CB6 -{0x0F12, 0xB5F3}, // 70003CB8 -{0x0F12, 0x0004}, // 70003CBA -{0x0F12, 0xB081}, // 70003CBC -{0x0F12, 0x9802}, // 70003CBE -{0x0F12, 0x6800}, // 70003CC0 -{0x0F12, 0x0600}, // 70003CC2 -{0x0F12, 0x0E00}, // 70003CC4 -{0x0F12, 0x2201}, // 70003CC6 -{0x0F12, 0x0015}, // 70003CC8 -{0x0F12, 0x0021}, // 70003CCA -{0x0F12, 0x3910}, // 70003CCC -{0x0F12, 0x408A}, // 70003CCE -{0x0F12, 0x40A5}, // 70003CD0 -{0x0F12, 0x4FE4}, // 70003CD2 -{0x0F12, 0x0016}, // 70003CD4 -{0x0F12, 0x2C10}, // 70003CD6 -{0x0F12, 0xDA03}, // 70003CD8 -{0x0F12, 0x8839}, // 70003CDA -{0x0F12, 0x43A9}, // 70003CDC -{0x0F12, 0x8039}, // 70003CDE -{0x0F12, 0xE002}, // 70003CE0 -{0x0F12, 0x8879}, // 70003CE2 -{0x0F12, 0x43B1}, // 70003CE4 -{0x0F12, 0x8079}, // 70003CE6 -{0x0F12, 0xF000}, // 70003CE8 -{0x0F12, 0xFB0E}, // 70003CEA -{0x0F12, 0x2C10}, // 70003CEC -{0x0F12, 0xDA03}, // 70003CEE -{0x0F12, 0x8839}, // 70003CF0 -{0x0F12, 0x4329}, // 70003CF2 -{0x0F12, 0x8039}, // 70003CF4 -{0x0F12, 0xE002}, // 70003CF6 -{0x0F12, 0x8879}, // 70003CF8 -{0x0F12, 0x4331}, // 70003CFA -{0x0F12, 0x8079}, // 70003CFC -{0x0F12, 0x49DA}, // 70003CFE -{0x0F12, 0x8809}, // 70003D00 -{0x0F12, 0x2900}, // 70003D02 -{0x0F12, 0xD102}, // 70003D04 -{0x0F12, 0xF000}, // 70003D06 -{0x0F12, 0xFB07}, // 70003D08 -{0x0F12, 0x2000}, // 70003D0A -{0x0F12, 0x9902}, // 70003D0C -{0x0F12, 0x6008}, // 70003D0E -{0x0F12, 0xBCFE}, // 70003D10 -{0x0F12, 0xBC08}, // 70003D12 -{0x0F12, 0x4718}, // 70003D14 -{0x0F12, 0xB538}, // 70003D16 -{0x0F12, 0x9C04}, // 70003D18 -{0x0F12, 0x0015}, // 70003D1A -{0x0F12, 0x002A}, // 70003D1C -{0x0F12, 0x9400}, // 70003D1E -{0x0F12, 0xF000}, // 70003D20 -{0x0F12, 0xFB02}, // 70003D22 -{0x0F12, 0x4AD1}, // 70003D24 -{0x0F12, 0x8811}, // 70003D26 -{0x0F12, 0x2900}, // 70003D28 -{0x0F12, 0xD00F}, // 70003D2A -{0x0F12, 0x8820}, // 70003D2C -{0x0F12, 0x4281}, // 70003D2E -{0x0F12, 0xD20C}, // 70003D30 -{0x0F12, 0x8861}, // 70003D32 -{0x0F12, 0x8853}, // 70003D34 -{0x0F12, 0x4299}, // 70003D36 -{0x0F12, 0xD200}, // 70003D38 -{0x0F12, 0x1E40}, // 70003D3A -{0x0F12, 0x0400}, // 70003D3C -{0x0F12, 0x0C00}, // 70003D3E -{0x0F12, 0x8020}, // 70003D40 -{0x0F12, 0x8851}, // 70003D42 -{0x0F12, 0x8061}, // 70003D44 -{0x0F12, 0x4368}, // 70003D46 -{0x0F12, 0x1840}, // 70003D48 -{0x0F12, 0x6060}, // 70003D4A -{0x0F12, 0xBC38}, // 70003D4C -{0x0F12, 0xBC08}, // 70003D4E -{0x0F12, 0x4718}, // 70003D50 -{0x0F12, 0xB5F8}, // 70003D52 -{0x0F12, 0x0004}, // 70003D54 -{0x0F12, 0x6808}, // 70003D56 -{0x0F12, 0x0400}, // 70003D58 -{0x0F12, 0x0C00}, // 70003D5A -{0x0F12, 0x2201}, // 70003D5C -{0x0F12, 0x0015}, // 70003D5E -{0x0F12, 0x0021}, // 70003D60 -{0x0F12, 0x3910}, // 70003D62 -{0x0F12, 0x408A}, // 70003D64 -{0x0F12, 0x40A5}, // 70003D66 -{0x0F12, 0x4FBE}, // 70003D68 -{0x0F12, 0x0016}, // 70003D6A -{0x0F12, 0x2C10}, // 70003D6C -{0x0F12, 0xDA03}, // 70003D6E -{0x0F12, 0x8839}, // 70003D70 -{0x0F12, 0x43A9}, // 70003D72 -{0x0F12, 0x8039}, // 70003D74 -{0x0F12, 0xE002}, // 70003D76 -{0x0F12, 0x8879}, // 70003D78 -{0x0F12, 0x43B1}, // 70003D7A -{0x0F12, 0x8079}, // 70003D7C -{0x0F12, 0xF000}, // 70003D7E -{0x0F12, 0xFADB}, // 70003D80 -{0x0F12, 0x2C10}, // 70003D82 -{0x0F12, 0xDA03}, // 70003D84 -{0x0F12, 0x8838}, // 70003D86 -{0x0F12, 0x4328}, // 70003D88 -{0x0F12, 0x8038}, // 70003D8A -{0x0F12, 0xE002}, // 70003D8C -{0x0F12, 0x8878}, // 70003D8E -{0x0F12, 0x4330}, // 70003D90 -{0x0F12, 0x8078}, // 70003D92 -{0x0F12, 0x48B6}, // 70003D94 -{0x0F12, 0x8800}, // 70003D96 -{0x0F12, 0x0400}, // 70003D98 -{0x0F12, 0xD507}, // 70003D9A -{0x0F12, 0x4BB5}, // 70003D9C -{0x0F12, 0x7819}, // 70003D9E -{0x0F12, 0x4AB5}, // 70003DA0 -{0x0F12, 0x7810}, // 70003DA2 -{0x0F12, 0x7018}, // 70003DA4 -{0x0F12, 0x7011}, // 70003DA6 -{0x0F12, 0x49B4}, // 70003DA8 -{0x0F12, 0x8188}, // 70003DAA -{0x0F12, 0xBCF8}, // 70003DAC -{0x0F12, 0xBC08}, // 70003DAE -{0x0F12, 0x4718}, // 70003DB0 -{0x0F12, 0xB538}, // 70003DB2 -{0x0F12, 0x48B2}, // 70003DB4 -{0x0F12, 0x4669}, // 70003DB6 -{0x0F12, 0xF000}, // 70003DB8 -{0x0F12, 0xFAC6}, // 70003DBA -{0x0F12, 0x48B1}, // 70003DBC -{0x0F12, 0x49B0}, // 70003DBE -{0x0F12, 0x69C2}, // 70003DC0 -{0x0F12, 0x2400}, // 70003DC2 -{0x0F12, 0x31A8}, // 70003DC4 -{0x0F12, 0x2A00}, // 70003DC6 -{0x0F12, 0xD008}, // 70003DC8 -{0x0F12, 0x61C4}, // 70003DCA -{0x0F12, 0x684A}, // 70003DCC -{0x0F12, 0x6242}, // 70003DCE -{0x0F12, 0x6282}, // 70003DD0 -{0x0F12, 0x466B}, // 70003DD2 -{0x0F12, 0x881A}, // 70003DD4 -{0x0F12, 0x6302}, // 70003DD6 -{0x0F12, 0x885A}, // 70003DD8 -{0x0F12, 0x6342}, // 70003DDA -{0x0F12, 0x6A02}, // 70003DDC -{0x0F12, 0x2A00}, // 70003DDE -{0x0F12, 0xD00A}, // 70003DE0 -{0x0F12, 0x6204}, // 70003DE2 -{0x0F12, 0x6849}, // 70003DE4 -{0x0F12, 0x6281}, // 70003DE6 -{0x0F12, 0x466B}, // 70003DE8 -{0x0F12, 0x8819}, // 70003DEA -{0x0F12, 0x6301}, // 70003DEC -{0x0F12, 0x8859}, // 70003DEE -{0x0F12, 0x6341}, // 70003DF0 -{0x0F12, 0x49A5}, // 70003DF2 -{0x0F12, 0x88C9}, // 70003DF4 -{0x0F12, 0x63C1}, // 70003DF6 -{0x0F12, 0xF000}, // 70003DF8 -{0x0F12, 0xFAAE}, // 70003DFA -{0x0F12, 0xE7A6}, // 70003DFC -{0x0F12, 0xB5F0}, // 70003DFE -{0x0F12, 0xB08B}, // 70003E00 -{0x0F12, 0x20FF}, // 70003E02 -{0x0F12, 0x1C40}, // 70003E04 -{0x0F12, 0x49A1}, // 70003E06 -{0x0F12, 0x89CC}, // 70003E08 -{0x0F12, 0x4E9E}, // 70003E0A -{0x0F12, 0x6AB1}, // 70003E0C -{0x0F12, 0x4284}, // 70003E0E -{0x0F12, 0xD101}, // 70003E10 -{0x0F12, 0x489F}, // 70003E12 -{0x0F12, 0x6081}, // 70003E14 -{0x0F12, 0x6A70}, // 70003E16 -{0x0F12, 0x0200}, // 70003E18 -{0x0F12, 0xF000}, // 70003E1A -{0x0F12, 0xFAA5}, // 70003E1C -{0x0F12, 0x0400}, // 70003E1E -{0x0F12, 0x0C00}, // 70003E20 -{0x0F12, 0x4A96}, // 70003E22 -{0x0F12, 0x8A11}, // 70003E24 -{0x0F12, 0x9109}, // 70003E26 -{0x0F12, 0x2101}, // 70003E28 -{0x0F12, 0x0349}, // 70003E2A -{0x0F12, 0x4288}, // 70003E2C -{0x0F12, 0xD200}, // 70003E2E -{0x0F12, 0x0001}, // 70003E30 -{0x0F12, 0x4A92}, // 70003E32 -{0x0F12, 0x8211}, // 70003E34 -{0x0F12, 0x4D97}, // 70003E36 -{0x0F12, 0x8829}, // 70003E38 -{0x0F12, 0x9108}, // 70003E3A -{0x0F12, 0x4A8B}, // 70003E3C -{0x0F12, 0x2303}, // 70003E3E -{0x0F12, 0x3222}, // 70003E40 -{0x0F12, 0x1F91}, // 70003E42 -{0x0F12, 0xF000}, // 70003E44 -{0x0F12, 0xFA96}, // 70003E46 -{0x0F12, 0x8028}, // 70003E48 -{0x0F12, 0x488E}, // 70003E4A -{0x0F12, 0x4987}, // 70003E4C -{0x0F12, 0x6BC2}, // 70003E4E -{0x0F12, 0x6AC0}, // 70003E50 -{0x0F12, 0x4282}, // 70003E52 -{0x0F12, 0xD201}, // 70003E54 -{0x0F12, 0x8CC8}, // 70003E56 -{0x0F12, 0x8028}, // 70003E58 -{0x0F12, 0x88E8}, // 70003E5A -{0x0F12, 0x9007}, // 70003E5C -{0x0F12, 0x2240}, // 70003E5E -{0x0F12, 0x4310}, // 70003E60 -{0x0F12, 0x80E8}, // 70003E62 -{0x0F12, 0x2000}, // 70003E64 -{0x0F12, 0x0041}, // 70003E66 -{0x0F12, 0x194B}, // 70003E68 -{0x0F12, 0x001E}, // 70003E6A -{0x0F12, 0x3680}, // 70003E6C -{0x0F12, 0x8BB2}, // 70003E6E -{0x0F12, 0xAF04}, // 70003E70 -{0x0F12, 0x527A}, // 70003E72 -{0x0F12, 0x4A7D}, // 70003E74 -{0x0F12, 0x188A}, // 70003E76 -{0x0F12, 0x8897}, // 70003E78 -{0x0F12, 0x83B7}, // 70003E7A -{0x0F12, 0x33A0}, // 70003E7C -{0x0F12, 0x891F}, // 70003E7E -{0x0F12, 0xAE01}, // 70003E80 -{0x0F12, 0x5277}, // 70003E82 -{0x0F12, 0x8A11}, // 70003E84 -{0x0F12, 0x8119}, // 70003E86 -{0x0F12, 0x1C40}, // 70003E88 -{0x0F12, 0x0400}, // 70003E8A -{0x0F12, 0x0C00}, // 70003E8C -{0x0F12, 0x2806}, // 70003E8E -{0x0F12, 0xD3E9}, // 70003E90 -{0x0F12, 0xF000}, // 70003E92 -{0x0F12, 0xFA77}, // 70003E94 -{0x0F12, 0xF000}, // 70003E96 -{0x0F12, 0xFA7D}, // 70003E98 -{0x0F12, 0x4F79}, // 70003E9A -{0x0F12, 0x37A8}, // 70003E9C -{0x0F12, 0x2800}, // 70003E9E -{0x0F12, 0xD10A}, // 70003EA0 -{0x0F12, 0x1FE0}, // 70003EA2 -{0x0F12, 0x38FD}, // 70003EA4 -{0x0F12, 0xD001}, // 70003EA6 -{0x0F12, 0x1CC0}, // 70003EA8 -{0x0F12, 0xD105}, // 70003EAA -{0x0F12, 0x4874}, // 70003EAC -{0x0F12, 0x8829}, // 70003EAE -{0x0F12, 0x3818}, // 70003EB0 -{0x0F12, 0x6840}, // 70003EB2 -{0x0F12, 0x4348}, // 70003EB4 -{0x0F12, 0x6078}, // 70003EB6 -{0x0F12, 0x4972}, // 70003EB8 -{0x0F12, 0x6878}, // 70003EBA -{0x0F12, 0x6B89}, // 70003EBC -{0x0F12, 0x4288}, // 70003EBE -{0x0F12, 0xD300}, // 70003EC0 -{0x0F12, 0x0008}, // 70003EC2 -{0x0F12, 0x6078}, // 70003EC4 -{0x0F12, 0x2000}, // 70003EC6 -{0x0F12, 0x0041}, // 70003EC8 -{0x0F12, 0xAA04}, // 70003ECA -{0x0F12, 0x5A53}, // 70003ECC -{0x0F12, 0x194A}, // 70003ECE -{0x0F12, 0x269C}, // 70003ED0 -{0x0F12, 0x52B3}, // 70003ED2 -{0x0F12, 0xAB01}, // 70003ED4 -{0x0F12, 0x5A59}, // 70003ED6 -{0x0F12, 0x32A0}, // 70003ED8 -{0x0F12, 0x8111}, // 70003EDA -{0x0F12, 0x1C40}, // 70003EDC -{0x0F12, 0x0400}, // 70003EDE -{0x0F12, 0x0C00}, // 70003EE0 -{0x0F12, 0x2806}, // 70003EE2 -{0x0F12, 0xD3F0}, // 70003EE4 -{0x0F12, 0x4965}, // 70003EE6 -{0x0F12, 0x9809}, // 70003EE8 -{0x0F12, 0x8208}, // 70003EEA -{0x0F12, 0x9808}, // 70003EEC -{0x0F12, 0x8028}, // 70003EEE -{0x0F12, 0x9807}, // 70003EF0 -{0x0F12, 0x80E8}, // 70003EF2 -{0x0F12, 0x1FE0}, // 70003EF4 -{0x0F12, 0x38FD}, // 70003EF6 -{0x0F12, 0xD13B}, // 70003EF8 -{0x0F12, 0x4D64}, // 70003EFA -{0x0F12, 0x89E8}, // 70003EFC -{0x0F12, 0x1FC1}, // 70003EFE -{0x0F12, 0x39FF}, // 70003F00 -{0x0F12, 0xD136}, // 70003F02 -{0x0F12, 0x4C5F}, // 70003F04 -{0x0F12, 0x8AE0}, // 70003F06 -{0x0F12, 0xF000}, // 70003F08 -{0x0F12, 0xFA4C}, // 70003F0A -{0x0F12, 0x0006}, // 70003F0C -{0x0F12, 0x8B20}, // 70003F0E -{0x0F12, 0xF000}, // 70003F10 -{0x0F12, 0xFA50}, // 70003F12 -{0x0F12, 0x9000}, // 70003F14 -{0x0F12, 0x6AA1}, // 70003F16 -{0x0F12, 0x6878}, // 70003F18 -{0x0F12, 0x1809}, // 70003F1A -{0x0F12, 0x0200}, // 70003F1C -{0x0F12, 0xF000}, // 70003F1E -{0x0F12, 0xFA23}, // 70003F20 -{0x0F12, 0x0400}, // 70003F22 -{0x0F12, 0x0C00}, // 70003F24 -{0x0F12, 0x0022}, // 70003F26 -{0x0F12, 0x3246}, // 70003F28 -{0x0F12, 0x0011}, // 70003F2A -{0x0F12, 0x310A}, // 70003F2C -{0x0F12, 0x2305}, // 70003F2E -{0x0F12, 0xF000}, // 70003F30 -{0x0F12, 0xFA20}, // 70003F32 -{0x0F12, 0x66E8}, // 70003F34 -{0x0F12, 0x6B23}, // 70003F36 -{0x0F12, 0x0002}, // 70003F38 -{0x0F12, 0x0031}, // 70003F3A -{0x0F12, 0x0018}, // 70003F3C -{0x0F12, 0xF000}, // 70003F3E -{0x0F12, 0xFA41}, // 70003F40 -{0x0F12, 0x466B}, // 70003F42 -{0x0F12, 0x8518}, // 70003F44 -{0x0F12, 0x6EEA}, // 70003F46 -{0x0F12, 0x6B60}, // 70003F48 -{0x0F12, 0x9900}, // 70003F4A -{0x0F12, 0xF000}, // 70003F4C -{0x0F12, 0xFA3A}, // 70003F4E -{0x0F12, 0x466B}, // 70003F50 -{0x0F12, 0x8558}, // 70003F52 -{0x0F12, 0x0029}, // 70003F54 -{0x0F12, 0x980A}, // 70003F56 -{0x0F12, 0x3170}, // 70003F58 -{0x0F12, 0xF000}, // 70003F5A -{0x0F12, 0xFA3B}, // 70003F5C -{0x0F12, 0x0028}, // 70003F5E -{0x0F12, 0x3060}, // 70003F60 -{0x0F12, 0x8A02}, // 70003F62 -{0x0F12, 0x4946}, // 70003F64 -{0x0F12, 0x3128}, // 70003F66 -{0x0F12, 0x808A}, // 70003F68 -{0x0F12, 0x8A42}, // 70003F6A -{0x0F12, 0x80CA}, // 70003F6C -{0x0F12, 0x8A80}, // 70003F6E -{0x0F12, 0x8108}, // 70003F70 -{0x0F12, 0xB00B}, // 70003F72 -{0x0F12, 0xBCF0}, // 70003F74 -{0x0F12, 0xBC08}, // 70003F76 -{0x0F12, 0x4718}, // 70003F78 -{0x0F12, 0xB570}, // 70003F7A -{0x0F12, 0x2400}, // 70003F7C -{0x0F12, 0x4D46}, // 70003F7E -{0x0F12, 0x4846}, // 70003F80 -{0x0F12, 0x8881}, // 70003F82 -{0x0F12, 0x4846}, // 70003F84 -{0x0F12, 0x8041}, // 70003F86 -{0x0F12, 0x2101}, // 70003F88 -{0x0F12, 0x8001}, // 70003F8A -{0x0F12, 0xF000}, // 70003F8C -{0x0F12, 0xFA2A}, // 70003F8E -{0x0F12, 0x4842}, // 70003F90 -{0x0F12, 0x3820}, // 70003F92 -{0x0F12, 0x8BC0}, // 70003F94 -{0x0F12, 0xF000}, // 70003F96 -{0x0F12, 0xFA2D}, // 70003F98 -{0x0F12, 0x4B42}, // 70003F9A -{0x0F12, 0x220D}, // 70003F9C -{0x0F12, 0x0712}, // 70003F9E -{0x0F12, 0x18A8}, // 70003FA0 -{0x0F12, 0x8806}, // 70003FA2 -{0x0F12, 0x00E1}, // 70003FA4 -{0x0F12, 0x18C9}, // 70003FA6 -{0x0F12, 0x81CE}, // 70003FA8 -{0x0F12, 0x8846}, // 70003FAA -{0x0F12, 0x818E}, // 70003FAC -{0x0F12, 0x8886}, // 70003FAE -{0x0F12, 0x824E}, // 70003FB0 -{0x0F12, 0x88C0}, // 70003FB2 -{0x0F12, 0x8208}, // 70003FB4 -{0x0F12, 0x3508}, // 70003FB6 -{0x0F12, 0x042D}, // 70003FB8 -{0x0F12, 0x0C2D}, // 70003FBA -{0x0F12, 0x1C64}, // 70003FBC -{0x0F12, 0x0424}, // 70003FBE -{0x0F12, 0x0C24}, // 70003FC0 -{0x0F12, 0x2C07}, // 70003FC2 -{0x0F12, 0xD3EC}, // 70003FC4 -{0x0F12, 0xE658}, // 70003FC6 -{0x0F12, 0xB510}, // 70003FC8 -{0x0F12, 0x4834}, // 70003FCA -{0x0F12, 0x4C34}, // 70003FCC -{0x0F12, 0x88C0}, // 70003FCE -{0x0F12, 0x8060}, // 70003FD0 -{0x0F12, 0x2001}, // 70003FD2 -{0x0F12, 0x8020}, // 70003FD4 -{0x0F12, 0x4831}, // 70003FD6 -{0x0F12, 0x3820}, // 70003FD8 -{0x0F12, 0x8BC0}, // 70003FDA -{0x0F12, 0xF000}, // 70003FDC -{0x0F12, 0xFA0A}, // 70003FDE -{0x0F12, 0x88E0}, // 70003FE0 -{0x0F12, 0x4A31}, // 70003FE2 -{0x0F12, 0x2800}, // 70003FE4 -{0x0F12, 0xD003}, // 70003FE6 -{0x0F12, 0x4930}, // 70003FE8 -{0x0F12, 0x8849}, // 70003FEA -{0x0F12, 0x2900}, // 70003FEC -{0x0F12, 0xD009}, // 70003FEE -{0x0F12, 0x2001}, // 70003FF0 -{0x0F12, 0x03C0}, // 70003FF2 -{0x0F12, 0x8050}, // 70003FF4 -{0x0F12, 0x80D0}, // 70003FF6 -{0x0F12, 0x2000}, // 70003FF8 -{0x0F12, 0x8090}, // 70003FFA -{0x0F12, 0x8110}, // 70003FFC -{0x0F12, 0xBC10}, // 70003FFE -{0x0F12, 0xBC08}, // 70004000 -{0x0F12, 0x4718}, // 70004002 -{0x0F12, 0x8050}, // 70004004 -{0x0F12, 0x8920}, // 70004006 -{0x0F12, 0x80D0}, // 70004008 -{0x0F12, 0x8960}, // 7000400A -{0x0F12, 0x0400}, // 7000400C -{0x0F12, 0x1400}, // 7000400E -{0x0F12, 0x8090}, // 70004010 -{0x0F12, 0x89A1}, // 70004012 -{0x0F12, 0x0409}, // 70004014 -{0x0F12, 0x1409}, // 70004016 -{0x0F12, 0x8111}, // 70004018 -{0x0F12, 0x89E3}, // 7000401A -{0x0F12, 0x8A24}, // 7000401C -{0x0F12, 0x2B00}, // 7000401E -{0x0F12, 0xD104}, // 70004020 -{0x0F12, 0x17C3}, // 70004022 -{0x0F12, 0x0F5B}, // 70004024 -{0x0F12, 0x1818}, // 70004026 -{0x0F12, 0x10C0}, // 70004028 -{0x0F12, 0x8090}, // 7000402A -{0x0F12, 0x2C00}, // 7000402C -{0x0F12, 0xD1E6}, // 7000402E -{0x0F12, 0x17C8}, // 70004030 -{0x0F12, 0x0F40}, // 70004032 -{0x0F12, 0x1840}, // 70004034 -{0x0F12, 0x10C0}, // 70004036 -{0x0F12, 0x8110}, // 70004038 -{0x0F12, 0xE7E0}, // 7000403A -{0x0F12, 0xB510}, // 7000403C -{0x0F12, 0x000C}, // 7000403E -{0x0F12, 0x4919}, // 70004040 -{0x0F12, 0x2204}, // 70004042 -{0x0F12, 0x6820}, // 70004044 -{0x0F12, 0x5E8A}, // 70004046 -{0x0F12, 0x0140}, // 70004048 -{0x0F12, 0x1A80}, // 7000404A -{0x0F12, 0x0280}, // 7000404C -{0x0F12, 0x8849}, // 7000404E -{0x0F12, 0xF000}, // 70004050 -{0x0F12, 0xF9D8}, // 70004052 -{0x0F12, 0x6020}, // 70004054 -{0x0F12, 0xE7D2}, // 70004056 -{0x0F12, 0x38D4}, // 70004058 -{0x0F12, 0x7000}, // 7000405A -{0x0F12, 0x17D0}, // 7000405C -{0x0F12, 0x7000}, // 7000405E -{0x0F12, 0x5000}, // 70004060 -{0x0F12, 0xD000}, // 70004062 -{0x0F12, 0x1100}, // 70004064 -{0x0F12, 0xD000}, // 70004066 -{0x0F12, 0x171A}, // 70004068 -{0x0F12, 0x7000}, // 7000406A -{0x0F12, 0x4780}, // 7000406C -{0x0F12, 0x7000}, // 7000406E -{0x0F12, 0x2FCA}, // 70004070 -{0x0F12, 0x7000}, // 70004072 -{0x0F12, 0x2FC5}, // 70004074 -{0x0F12, 0x7000}, // 70004076 -{0x0F12, 0x2FC6}, // 70004078 -{0x0F12, 0x7000}, // 7000407A -{0x0F12, 0x2ED8}, // 7000407C -{0x0F12, 0x7000}, // 7000407E -{0x0F12, 0x2BD0}, // 70004080 -{0x0F12, 0x7000}, // 70004082 -{0x0F12, 0x17E0}, // 70004084 -{0x0F12, 0x7000}, // 70004086 -{0x0F12, 0x2DE8}, // 70004088 -{0x0F12, 0x7000}, // 7000408A -{0x0F12, 0x37E0}, // 7000408C -{0x0F12, 0x7000}, // 7000408E -{0x0F12, 0x210C}, // 70004090 -{0x0F12, 0x7000}, // 70004092 -{0x0F12, 0x1484}, // 70004094 -{0x0F12, 0x7000}, // 70004096 -{0x0F12, 0xA006}, // 70004098 -{0x0F12, 0x0000}, // 7000409A -{0x0F12, 0x0724}, // 7000409C -{0x0F12, 0x7000}, // 7000409E -{0x0F12, 0xA000}, // 700040A0 -{0x0F12, 0xD000}, // 700040A2 -{0x0F12, 0x2270}, // 700040A4 -{0x0F12, 0x7000}, // 700040A6 -{0x0F12, 0x2558}, // 700040A8 -{0x0F12, 0x7000}, // 700040AA -{0x0F12, 0x146C}, // 700040AC -{0x0F12, 0x7000}, // 700040AE -{0x0F12, 0xB510}, // 700040B0 -{0x0F12, 0x000C}, // 700040B2 -{0x0F12, 0x4983}, // 700040B4 -{0x0F12, 0x2208}, // 700040B6 -{0x0F12, 0x6820}, // 700040B8 -{0x0F12, 0x5E8A}, // 700040BA -{0x0F12, 0x0140}, // 700040BC -{0x0F12, 0x1A80}, // 700040BE -{0x0F12, 0x0280}, // 700040C0 -{0x0F12, 0x88C9}, // 700040C2 -{0x0F12, 0xF000}, // 700040C4 -{0x0F12, 0xF99E}, // 700040C6 -{0x0F12, 0x6020}, // 700040C8 -{0x0F12, 0xE798}, // 700040CA -{0x0F12, 0xB5FE}, // 700040CC -{0x0F12, 0x000C}, // 700040CE -{0x0F12, 0x6825}, // 700040D0 -{0x0F12, 0x6866}, // 700040D2 -{0x0F12, 0x68A0}, // 700040D4 -{0x0F12, 0x9001}, // 700040D6 -{0x0F12, 0x68E7}, // 700040D8 -{0x0F12, 0x1BA8}, // 700040DA -{0x0F12, 0x42B5}, // 700040DC -{0x0F12, 0xDA00}, // 700040DE -{0x0F12, 0x1B70}, // 700040E0 -{0x0F12, 0x9000}, // 700040E2 -{0x0F12, 0x4977}, // 700040E4 -{0x0F12, 0x4878}, // 700040E6 -{0x0F12, 0x884A}, // 700040E8 -{0x0F12, 0x8843}, // 700040EA -{0x0F12, 0x435A}, // 700040EC -{0x0F12, 0x2304}, // 700040EE -{0x0F12, 0x5ECB}, // 700040F0 -{0x0F12, 0x0A92}, // 700040F2 -{0x0F12, 0x18D2}, // 700040F4 -{0x0F12, 0x02D2}, // 700040F6 -{0x0F12, 0x0C12}, // 700040F8 -{0x0F12, 0x88CB}, // 700040FA -{0x0F12, 0x8880}, // 700040FC -{0x0F12, 0x4343}, // 700040FE -{0x0F12, 0x0A98}, // 70004100 -{0x0F12, 0x2308}, // 70004102 -{0x0F12, 0x5ECB}, // 70004104 -{0x0F12, 0x18C0}, // 70004106 -{0x0F12, 0x02C0}, // 70004108 -{0x0F12, 0x0C00}, // 7000410A -{0x0F12, 0x0411}, // 7000410C -{0x0F12, 0x0400}, // 7000410E -{0x0F12, 0x1409}, // 70004110 -{0x0F12, 0x1400}, // 70004112 -{0x0F12, 0x1A08}, // 70004114 -{0x0F12, 0x496C}, // 70004116 -{0x0F12, 0x39E0}, // 70004118 -{0x0F12, 0x6148}, // 7000411A -{0x0F12, 0x9801}, // 7000411C -{0x0F12, 0x3040}, // 7000411E -{0x0F12, 0x7880}, // 70004120 -{0x0F12, 0x2800}, // 70004122 -{0x0F12, 0xD103}, // 70004124 -{0x0F12, 0x9801}, // 70004126 -{0x0F12, 0x0029}, // 70004128 -{0x0F12, 0xF000}, // 7000412A -{0x0F12, 0xF971}, // 7000412C -{0x0F12, 0x8839}, // 7000412E -{0x0F12, 0x9800}, // 70004130 -{0x0F12, 0x4281}, // 70004132 -{0x0F12, 0xD814}, // 70004134 -{0x0F12, 0x8879}, // 70004136 -{0x0F12, 0x9800}, // 70004138 -{0x0F12, 0x4281}, // 7000413A -{0x0F12, 0xD20C}, // 7000413C -{0x0F12, 0x9801}, // 7000413E -{0x0F12, 0x0029}, // 70004140 -{0x0F12, 0xF000}, // 70004142 -{0x0F12, 0xF96D}, // 70004144 -{0x0F12, 0x9801}, // 70004146 -{0x0F12, 0x0029}, // 70004148 -{0x0F12, 0xF000}, // 7000414A -{0x0F12, 0xF969}, // 7000414C -{0x0F12, 0x9801}, // 7000414E -{0x0F12, 0x0029}, // 70004150 -{0x0F12, 0xF000}, // 70004152 -{0x0F12, 0xF965}, // 70004154 -{0x0F12, 0xE003}, // 70004156 -{0x0F12, 0x9801}, // 70004158 -{0x0F12, 0x0029}, // 7000415A -{0x0F12, 0xF000}, // 7000415C -{0x0F12, 0xF960}, // 7000415E -{0x0F12, 0x9801}, // 70004160 -{0x0F12, 0x0032}, // 70004162 -{0x0F12, 0x0039}, // 70004164 -{0x0F12, 0xF000}, // 70004166 -{0x0F12, 0xF963}, // 70004168 -{0x0F12, 0x6020}, // 7000416A -{0x0F12, 0xE5D0}, // 7000416C -{0x0F12, 0xB57C}, // 7000416E -{0x0F12, 0x4856}, // 70004170 -{0x0F12, 0xA901}, // 70004172 -{0x0F12, 0x0004}, // 70004174 -{0x0F12, 0xF000}, // 70004176 -{0x0F12, 0xF8E7}, // 70004178 -{0x0F12, 0x466B}, // 7000417A -{0x0F12, 0x88D9}, // 7000417C -{0x0F12, 0x8898}, // 7000417E -{0x0F12, 0x4B51}, // 70004180 -{0x0F12, 0x3346}, // 70004182 -{0x0F12, 0x1E9A}, // 70004184 -{0x0F12, 0xF000}, // 70004186 -{0x0F12, 0xF95B}, // 70004188 -{0x0F12, 0x4850}, // 7000418A -{0x0F12, 0x494E}, // 7000418C -{0x0F12, 0x3812}, // 7000418E -{0x0F12, 0x3140}, // 70004190 -{0x0F12, 0x8A42}, // 70004192 -{0x0F12, 0x888B}, // 70004194 -{0x0F12, 0x18D2}, // 70004196 -{0x0F12, 0x8242}, // 70004198 -{0x0F12, 0x8AC2}, // 7000419A -{0x0F12, 0x88C9}, // 7000419C -{0x0F12, 0x1851}, // 7000419E -{0x0F12, 0x82C1}, // 700041A0 -{0x0F12, 0x0020}, // 700041A2 -{0x0F12, 0x4669}, // 700041A4 -{0x0F12, 0xF000}, // 700041A6 -{0x0F12, 0xF8CF}, // 700041A8 -{0x0F12, 0x4849}, // 700041AA -{0x0F12, 0x214D}, // 700041AC -{0x0F12, 0x8301}, // 700041AE -{0x0F12, 0x2196}, // 700041B0 -{0x0F12, 0x8381}, // 700041B2 -{0x0F12, 0x211D}, // 700041B4 -{0x0F12, 0x3020}, // 700041B6 -{0x0F12, 0x8001}, // 700041B8 -{0x0F12, 0xF000}, // 700041BA -{0x0F12, 0xF949}, // 700041BC -{0x0F12, 0xF000}, // 700041BE -{0x0F12, 0xF94F}, // 700041C0 -{0x0F12, 0x4844}, // 700041C2 -{0x0F12, 0x4C44}, // 700041C4 -{0x0F12, 0x6E00}, // 700041C6 -{0x0F12, 0x60E0}, // 700041C8 -{0x0F12, 0x466B}, // 700041CA -{0x0F12, 0x8818}, // 700041CC -{0x0F12, 0x8859}, // 700041CE -{0x0F12, 0x0025}, // 700041D0 -{0x0F12, 0x1A40}, // 700041D2 -{0x0F12, 0x3540}, // 700041D4 -{0x0F12, 0x61A8}, // 700041D6 -{0x0F12, 0x483B}, // 700041D8 -{0x0F12, 0x9900}, // 700041DA -{0x0F12, 0x3060}, // 700041DC -{0x0F12, 0xF000}, // 700041DE -{0x0F12, 0xF947}, // 700041E0 -{0x0F12, 0x466B}, // 700041E2 -{0x0F12, 0x8819}, // 700041E4 -{0x0F12, 0x1DE0}, // 700041E6 -{0x0F12, 0x30F9}, // 700041E8 -{0x0F12, 0x8741}, // 700041EA -{0x0F12, 0x8859}, // 700041EC -{0x0F12, 0x8781}, // 700041EE -{0x0F12, 0x2000}, // 700041F0 -{0x0F12, 0x71A0}, // 700041F2 -{0x0F12, 0x74A8}, // 700041F4 -{0x0F12, 0xBC7C}, // 700041F6 -{0x0F12, 0xBC08}, // 700041F8 -{0x0F12, 0x4718}, // 700041FA -{0x0F12, 0xB5F8}, // 700041FC -{0x0F12, 0x0005}, // 700041FE -{0x0F12, 0x6808}, // 70004200 -{0x0F12, 0x0400}, // 70004202 -{0x0F12, 0x0C00}, // 70004204 -{0x0F12, 0x684A}, // 70004206 -{0x0F12, 0x0412}, // 70004208 -{0x0F12, 0x0C12}, // 7000420A -{0x0F12, 0x688E}, // 7000420C -{0x0F12, 0x68CC}, // 7000420E -{0x0F12, 0x492C}, // 70004210 -{0x0F12, 0x884B}, // 70004212 -{0x0F12, 0x4343}, // 70004214 -{0x0F12, 0x0A98}, // 70004216 -{0x0F12, 0x2304}, // 70004218 -{0x0F12, 0x5ECB}, // 7000421A -{0x0F12, 0x18C0}, // 7000421C -{0x0F12, 0x02C0}, // 7000421E -{0x0F12, 0x0C00}, // 70004220 -{0x0F12, 0x88CB}, // 70004222 -{0x0F12, 0x4353}, // 70004224 -{0x0F12, 0x0A9A}, // 70004226 -{0x0F12, 0x2308}, // 70004228 -{0x0F12, 0x5ECB}, // 7000422A -{0x0F12, 0x18D1}, // 7000422C -{0x0F12, 0x02C9}, // 7000422E -{0x0F12, 0x0C09}, // 70004230 -{0x0F12, 0x2701}, // 70004232 -{0x0F12, 0x003A}, // 70004234 -{0x0F12, 0x40AA}, // 70004236 -{0x0F12, 0x9200}, // 70004238 -{0x0F12, 0x002A}, // 7000423A -{0x0F12, 0x3A10}, // 7000423C -{0x0F12, 0x4097}, // 7000423E -{0x0F12, 0x2D10}, // 70004240 -{0x0F12, 0xDA06}, // 70004242 -{0x0F12, 0x4A25}, // 70004244 -{0x0F12, 0x9B00}, // 70004246 -{0x0F12, 0x8812}, // 70004248 -{0x0F12, 0x439A}, // 7000424A -{0x0F12, 0x4B23}, // 7000424C -{0x0F12, 0x801A}, // 7000424E -{0x0F12, 0xE003}, // 70004250 -{0x0F12, 0x4B22}, // 70004252 -{0x0F12, 0x885A}, // 70004254 -{0x0F12, 0x43BA}, // 70004256 -{0x0F12, 0x805A}, // 70004258 -{0x0F12, 0x0023}, // 7000425A -{0x0F12, 0x0032}, // 7000425C -{0x0F12, 0xF000}, // 7000425E -{0x0F12, 0xF8EF}, // 70004260 -{0x0F12, 0x2D10}, // 70004262 -{0x0F12, 0xDA05}, // 70004264 -{0x0F12, 0x491D}, // 70004266 -{0x0F12, 0x9A00}, // 70004268 -{0x0F12, 0x8808}, // 7000426A -{0x0F12, 0x4310}, // 7000426C -{0x0F12, 0x8008}, // 7000426E -{0x0F12, 0xE003}, // 70004270 -{0x0F12, 0x481A}, // 70004272 -{0x0F12, 0x8841}, // 70004274 -{0x0F12, 0x4339}, // 70004276 -{0x0F12, 0x8041}, // 70004278 -{0x0F12, 0x4D17}, // 7000427A -{0x0F12, 0x2000}, // 7000427C -{0x0F12, 0x3580}, // 7000427E -{0x0F12, 0x88AA}, // 70004280 -{0x0F12, 0x5E30}, // 70004282 -{0x0F12, 0x2100}, // 70004284 -{0x0F12, 0xF000}, // 70004286 -{0x0F12, 0xF8FB}, // 70004288 -{0x0F12, 0x8030}, // 7000428A -{0x0F12, 0x2000}, // 7000428C -{0x0F12, 0x88AA}, // 7000428E -{0x0F12, 0x5E20}, // 70004290 -{0x0F12, 0x2100}, // 70004292 -{0x0F12, 0xF000}, // 70004294 -{0x0F12, 0xF8F4}, // 70004296 -{0x0F12, 0x8020}, // 70004298 -{0x0F12, 0xE587}, // 7000429A -{0x0F12, 0xB510}, // 7000429C -{0x0F12, 0xF000}, // 7000429E -{0x0F12, 0xF8F7}, // 700042A0 -{0x0F12, 0x4A0F}, // 700042A2 -{0x0F12, 0x8D50}, // 700042A4 -{0x0F12, 0x2800}, // 700042A6 -{0x0F12, 0xD007}, // 700042A8 -{0x0F12, 0x490A}, // 700042AA -{0x0F12, 0x31C0}, // 700042AC -{0x0F12, 0x684B}, // 700042AE -{0x0F12, 0x490C}, // 700042B0 -{0x0F12, 0x4283}, // 700042B2 -{0x0F12, 0xD202}, // 700042B4 -{0x0F12, 0x8D90}, // 700042B6 -{0x0F12, 0x81C8}, // 700042B8 -{0x0F12, 0xE6A0}, // 700042BA -{0x0F12, 0x8DD0}, // 700042BC -{0x0F12, 0x81C8}, // 700042BE -{0x0F12, 0xE69D}, // 700042C0 -{0x0F12, 0x0000}, // 700042C2 -{0x0F12, 0x2558}, // 700042C4 -{0x0F12, 0x7000}, // 700042C6 -{0x0F12, 0x2AB8}, // 700042C8 -{0x0F12, 0x7000}, // 700042CA -{0x0F12, 0x145E}, // 700042CC -{0x0F12, 0x7000}, // 700042CE -{0x0F12, 0x2698}, // 700042D0 -{0x0F12, 0x7000}, // 700042D2 -{0x0F12, 0x2BB8}, // 700042D4 -{0x0F12, 0x7000}, // 700042D6 -{0x0F12, 0x2998}, // 700042D8 -{0x0F12, 0x7000}, // 700042DA -{0x0F12, 0x1100}, // 700042DC -{0x0F12, 0xD000}, // 700042DE -{0x0F12, 0x4780}, // 700042E0 -{0x0F12, 0x7000}, // 700042E2 -{0x0F12, 0xE200}, // 700042E4 -{0x0F12, 0xD000}, // 700042E6 -{0x0F12, 0x4778}, // 700042E8 -{0x0F12, 0x46C0}, // 700042EA -{0x0F12, 0xC000}, // 700042EC -{0x0F12, 0xE59F}, // 700042EE -{0x0F12, 0xFF1C}, // 700042F0 -{0x0F12, 0xE12F}, // 700042F2 -{0x0F12, 0x1789}, // 700042F4 -{0x0F12, 0x0001}, // 700042F6 -{0x0F12, 0x4778}, // 700042F8 -{0x0F12, 0x46C0}, // 700042FA -{0x0F12, 0xC000}, // 700042FC -{0x0F12, 0xE59F}, // 700042FE -{0x0F12, 0xFF1C}, // 70004300 -{0x0F12, 0xE12F}, // 70004302 -{0x0F12, 0x16F1}, // 70004304 -{0x0F12, 0x0001}, // 70004306 -{0x0F12, 0x4778}, // 70004308 -{0x0F12, 0x46C0}, // 7000430A -{0x0F12, 0xC000}, // 7000430C -{0x0F12, 0xE59F}, // 7000430E -{0x0F12, 0xFF1C}, // 70004310 -{0x0F12, 0xE12F}, // 70004312 -{0x0F12, 0xC3B1}, // 70004314 -{0x0F12, 0x0000}, // 70004316 -{0x0F12, 0x4778}, // 70004318 -{0x0F12, 0x46C0}, // 7000431A -{0x0F12, 0xC000}, // 7000431C -{0x0F12, 0xE59F}, // 7000431E -{0x0F12, 0xFF1C}, // 70004320 -{0x0F12, 0xE12F}, // 70004322 -{0x0F12, 0xC36D}, // 70004324 -{0x0F12, 0x0000}, // 70004326 -{0x0F12, 0x4778}, // 70004328 -{0x0F12, 0x46C0}, // 7000432A -{0x0F12, 0xC000}, // 7000432C -{0x0F12, 0xE59F}, // 7000432E -{0x0F12, 0xFF1C}, // 70004330 -{0x0F12, 0xE12F}, // 70004332 -{0x0F12, 0xF6D7}, // 70004334 -{0x0F12, 0x0000}, // 70004336 -{0x0F12, 0x4778}, // 70004338 -{0x0F12, 0x46C0}, // 7000433A -{0x0F12, 0xC000}, // 7000433C -{0x0F12, 0xE59F}, // 7000433E -{0x0F12, 0xFF1C}, // 70004340 -{0x0F12, 0xE12F}, // 70004342 -{0x0F12, 0xB49D}, // 70004344 -{0x0F12, 0x0000}, // 70004346 -{0x0F12, 0x4778}, // 70004348 -{0x0F12, 0x46C0}, // 7000434A -{0x0F12, 0xC000}, // 7000434C -{0x0F12, 0xE59F}, // 7000434E -{0x0F12, 0xFF1C}, // 70004350 -{0x0F12, 0xE12F}, // 70004352 -{0x0F12, 0x7EDF}, // 70004354 -{0x0F12, 0x0000}, // 70004356 -{0x0F12, 0x4778}, // 70004358 -{0x0F12, 0x46C0}, // 7000435A -{0x0F12, 0xC000}, // 7000435C -{0x0F12, 0xE59F}, // 7000435E -{0x0F12, 0xFF1C}, // 70004360 -{0x0F12, 0xE12F}, // 70004362 -{0x0F12, 0x448D}, // 70004364 -{0x0F12, 0x0000}, // 70004366 -{0x0F12, 0x4778}, // 70004368 -{0x0F12, 0x46C0}, // 7000436A -{0x0F12, 0xF004}, // 7000436C -{0x0F12, 0xE51F}, // 7000436E -{0x0F12, 0x29EC}, // 70004370 -{0x0F12, 0x0001}, // 70004372 -{0x0F12, 0x4778}, // 70004374 -{0x0F12, 0x46C0}, // 70004376 -{0x0F12, 0xC000}, // 70004378 -{0x0F12, 0xE59F}, // 7000437A -{0x0F12, 0xFF1C}, // 7000437C -{0x0F12, 0xE12F}, // 7000437E -{0x0F12, 0x2EF1}, // 70004380 -{0x0F12, 0x0000}, // 70004382 -{0x0F12, 0x4778}, // 70004384 -{0x0F12, 0x46C0}, // 70004386 -{0x0F12, 0xC000}, // 70004388 -{0x0F12, 0xE59F}, // 7000438A -{0x0F12, 0xFF1C}, // 7000438C -{0x0F12, 0xE12F}, // 7000438E -{0x0F12, 0xEE03}, // 70004390 -{0x0F12, 0x0000}, // 70004392 -{0x0F12, 0x4778}, // 70004394 -{0x0F12, 0x46C0}, // 70004396 -{0x0F12, 0xC000}, // 70004398 -{0x0F12, 0xE59F}, // 7000439A -{0x0F12, 0xFF1C}, // 7000439C -{0x0F12, 0xE12F}, // 7000439E -{0x0F12, 0xA58B}, // 700043A0 -{0x0F12, 0x0000}, // 700043A2 -{0x0F12, 0x4778}, // 700043A4 -{0x0F12, 0x46C0}, // 700043A6 -{0x0F12, 0xC000}, // 700043A8 -{0x0F12, 0xE59F}, // 700043AA -{0x0F12, 0xFF1C}, // 700043AC -{0x0F12, 0xE12F}, // 700043AE -{0x0F12, 0x7C49}, // 700043B0 -{0x0F12, 0x0000}, // 700043B2 -{0x0F12, 0x4778}, // 700043B4 -{0x0F12, 0x46C0}, // 700043B6 -{0x0F12, 0xC000}, // 700043B8 -{0x0F12, 0xE59F}, // 700043BA -{0x0F12, 0xFF1C}, // 700043BC -{0x0F12, 0xE12F}, // 700043BE -{0x0F12, 0x7C63}, // 700043C0 -{0x0F12, 0x0000}, // 700043C2 -{0x0F12, 0x4778}, // 700043C4 -{0x0F12, 0x46C0}, // 700043C6 -{0x0F12, 0xC000}, // 700043C8 -{0x0F12, 0xE59F}, // 700043CA -{0x0F12, 0xFF1C}, // 700043CC -{0x0F12, 0xE12F}, // 700043CE -{0x0F12, 0x2DB7}, // 700043D0 -{0x0F12, 0x0000}, // 700043D2 -{0x0F12, 0x4778}, // 700043D4 -{0x0F12, 0x46C0}, // 700043D6 -{0x0F12, 0xC000}, // 700043D8 -{0x0F12, 0xE59F}, // 700043DA -{0x0F12, 0xFF1C}, // 700043DC -{0x0F12, 0xE12F}, // 700043DE -{0x0F12, 0xEB3D}, // 700043E0 -{0x0F12, 0x0000}, // 700043E2 -{0x0F12, 0x4778}, // 700043E4 -{0x0F12, 0x46C0}, // 700043E6 -{0x0F12, 0xC000}, // 700043E8 -{0x0F12, 0xE59F}, // 700043EA -{0x0F12, 0xFF1C}, // 700043EC -{0x0F12, 0xE12F}, // 700043EE -{0x0F12, 0xF061}, // 700043F0 -{0x0F12, 0x0000}, // 700043F2 -{0x0F12, 0x4778}, // 700043F4 -{0x0F12, 0x46C0}, // 700043F6 -{0x0F12, 0xC000}, // 700043F8 -{0x0F12, 0xE59F}, // 700043FA -{0x0F12, 0xFF1C}, // 700043FC -{0x0F12, 0xE12F}, // 700043FE -{0x0F12, 0xF0EF}, // 70004400 -{0x0F12, 0x0000}, // 70004402 -{0x0F12, 0x4778}, // 70004404 -{0x0F12, 0x46C0}, // 70004406 -{0x0F12, 0xF004}, // 70004408 -{0x0F12, 0xE51F}, // 7000440A -{0x0F12, 0x2824}, // 7000440C -{0x0F12, 0x0001}, // 7000440E -{0x0F12, 0x4778}, // 70004410 -{0x0F12, 0x46C0}, // 70004412 -{0x0F12, 0xC000}, // 70004414 -{0x0F12, 0xE59F}, // 70004416 -{0x0F12, 0xFF1C}, // 70004418 -{0x0F12, 0xE12F}, // 7000441A -{0x0F12, 0x8EDD}, // 7000441C -{0x0F12, 0x0000}, // 7000441E -{0x0F12, 0x4778}, // 70004420 -{0x0F12, 0x46C0}, // 70004422 -{0x0F12, 0xC000}, // 70004424 -{0x0F12, 0xE59F}, // 70004426 -{0x0F12, 0xFF1C}, // 70004428 -{0x0F12, 0xE12F}, // 7000442A -{0x0F12, 0x8DCB}, // 7000442C -{0x0F12, 0x0000}, // 7000442E -{0x0F12, 0x4778}, // 70004430 -{0x0F12, 0x46C0}, // 70004432 -{0x0F12, 0xC000}, // 70004434 -{0x0F12, 0xE59F}, // 70004436 -{0x0F12, 0xFF1C}, // 70004438 -{0x0F12, 0xE12F}, // 7000443A -{0x0F12, 0x8E17}, // 7000443C -{0x0F12, 0x0000}, // 7000443E -{0x0F12, 0x4778}, // 70004440 -{0x0F12, 0x46C0}, // 70004442 -{0x0F12, 0xC000}, // 70004444 -{0x0F12, 0xE59F}, // 70004446 -{0x0F12, 0xFF1C}, // 70004448 -{0x0F12, 0xE12F}, // 7000444A -{0x0F12, 0x98C5}, // 7000444C -{0x0F12, 0x0000}, // 7000444E -{0x0F12, 0x4778}, // 70004450 -{0x0F12, 0x46C0}, // 70004452 -{0x0F12, 0xC000}, // 70004454 -{0x0F12, 0xE59F}, // 70004456 -{0x0F12, 0xFF1C}, // 70004458 -{0x0F12, 0xE12F}, // 7000445A -{0x0F12, 0x7C7D}, // 7000445C -{0x0F12, 0x0000}, // 7000445E -{0x0F12, 0x4778}, // 70004460 -{0x0F12, 0x46C0}, // 70004462 -{0x0F12, 0xC000}, // 70004464 -{0x0F12, 0xE59F}, // 70004466 -{0x0F12, 0xFF1C}, // 70004468 -{0x0F12, 0xE12F}, // 7000446A -{0x0F12, 0x7E31}, // 7000446C -{0x0F12, 0x0000}, // 7000446E -{0x0F12, 0x4778}, // 70004470 -{0x0F12, 0x46C0}, // 70004472 -{0x0F12, 0xC000}, // 70004474 -{0x0F12, 0xE59F}, // 70004476 -{0x0F12, 0xFF1C}, // 70004478 -{0x0F12, 0xE12F}, // 7000447A -{0x0F12, 0x7EAB}, // 7000447C -{0x0F12, 0x0000}, // 7000447E -{0x0F12, 0x4778}, // 70004480 -{0x0F12, 0x46C0}, // 70004482 -{0x0F12, 0xC000}, // 70004484 -{0x0F12, 0xE59F}, // 70004486 -{0x0F12, 0xFF1C}, // 70004488 -{0x0F12, 0xE12F}, // 7000448A -{0x0F12, 0x7501}, // 7000448C -{0x0F12, 0x0000}, // 7000448E -{0x0F12, 0x4778}, // 70004490 -{0x0F12, 0x46C0}, // 70004492 -{0x0F12, 0xC000}, // 70004494 -{0x0F12, 0xE59F}, // 70004496 -{0x0F12, 0xFF1C}, // 70004498 -{0x0F12, 0xE12F}, // 7000449A -{0x0F12, 0xF63F}, // 7000449C -{0x0F12, 0x0000}, // 7000449E - -// End of Patch Data(Last : 7000449Eh) -// Total Size 2472 (09A8) -// Addr : 3AF8 Size : 2470(9A6h) - -//TNP_USER_MBCV_CONTROL -//TNP_4EC_MBR_TUNE -//TNP_4EC_FORBIDDEN_TUNE -//TNP_AF_FINESEARCH_DRIVEBACK -//TNP_FLASH_ALG -//TNP_GAS_ALPHA_OTP -//TNP_AWB_MODUL_COMP -//TNP_AWB_INIT_QUEUE -//TNP_AWB_GRID_LOWBR -//TNP_AWB_GRID_MODULECOMP - -{0x0028, 0xD000}, -{0x002A, 0x1000}, -{0x0F12, 0x0001}, + +{0x0028,0x7000}, +{0x002A,0x3AF8}, +{0x0F12,0xB5F8}, // 70003AF8 +{0x0F12,0x4B4D}, // 70003AFA +{0x0F12,0x494D}, // 70003AFC +{0x0F12,0x484E}, // 70003AFE +{0x0F12,0x2200}, // 70003B00 +{0x0F12,0xC008}, // 70003B02 +{0x0F12,0x6001}, // 70003B04 +{0x0F12,0x494D}, // 70003B06 +{0x0F12,0x484D}, // 70003B08 +{0x0F12,0x2401}, // 70003B0A +{0x0F12,0xF000}, // 70003B0C +{0x0F12,0xFCDE}, // 70003B0E +{0x0F12,0x494C}, // 70003B10 +{0x0F12,0x484D}, // 70003B12 +{0x0F12,0x2702}, // 70003B14 +{0x0F12,0x0022}, // 70003B16 +{0x0F12,0xF000}, // 70003B18 +{0x0F12,0xFCD8}, // 70003B1A +{0x0F12,0x0260}, // 70003B1C +{0x0F12,0x4C4B}, // 70003B1E +{0x0F12,0x8020}, // 70003B20 +{0x0F12,0x2000}, // 70003B22 +{0x0F12,0x8060}, // 70003B24 +{0x0F12,0x484A}, // 70003B26 +{0x0F12,0x4E4A}, // 70003B28 +{0x0F12,0x6070}, // 70003B2A +{0x0F12,0x494A}, // 70003B2C +{0x0F12,0x484B}, // 70003B2E +{0x0F12,0x003A}, // 70003B30 +{0x0F12,0x2503}, // 70003B32 +{0x0F12,0xF000}, // 70003B34 +{0x0F12,0xFCCA}, // 70003B36 +{0x0F12,0x4949}, // 70003B38 +{0x0F12,0x1DF0}, // 70003B3A +{0x0F12,0x30F9}, // 70003B3C +{0x0F12,0x6001}, // 70003B3E +{0x0F12,0x4948}, // 70003B40 +{0x0F12,0x3840}, // 70003B42 +{0x0F12,0x63C1}, // 70003B44 +{0x0F12,0x4848}, // 70003B46 +{0x0F12,0x0037}, // 70003B48 +{0x0F12,0x3F80}, // 70003B4A +{0x0F12,0x6438}, // 70003B4C +{0x0F12,0x4847}, // 70003B4E +{0x0F12,0x4947}, // 70003B50 +{0x0F12,0x6388}, // 70003B52 +{0x0F12,0x002A}, // 70003B54 +{0x0F12,0x4947}, // 70003B56 +{0x0F12,0x4847}, // 70003B58 +{0x0F12,0x2504}, // 70003B5A +{0x0F12,0xF000}, // 70003B5C +{0x0F12,0xFCB6}, // 70003B5E +{0x0F12,0x002A}, // 70003B60 +{0x0F12,0x4946}, // 70003B62 +{0x0F12,0x4846}, // 70003B64 +{0x0F12,0x2505}, // 70003B66 +{0x0F12,0xF000}, // 70003B68 +{0x0F12,0xF8C2}, // 70003B6A +{0x0F12,0x4844}, // 70003B6C +{0x0F12,0x002A}, // 70003B6E +{0x0F12,0x4944}, // 70003B70 +{0x0F12,0x2506}, // 70003B72 +{0x0F12,0x1D80}, // 70003B74 +{0x0F12,0xF000}, // 70003B76 +{0x0F12,0xF8BB}, // 70003B78 +{0x0F12,0x4841}, // 70003B7A +{0x0F12,0x002A}, // 70003B7C +{0x0F12,0x4942}, // 70003B7E +{0x0F12,0x2507}, // 70003B80 +{0x0F12,0x300C}, // 70003B82 +{0x0F12,0xF000}, // 70003B84 +{0x0F12,0xF8B4}, // 70003B86 +{0x0F12,0x483D}, // 70003B88 +{0x0F12,0x002A}, // 70003B8A +{0x0F12,0x493F}, // 70003B8C +{0x0F12,0x2508}, // 70003B8E +{0x0F12,0x3010}, // 70003B90 +{0x0F12,0xF000}, // 70003B92 +{0x0F12,0xF8AD}, // 70003B94 +{0x0F12,0x002A}, // 70003B96 +{0x0F12,0x493D}, // 70003B98 +{0x0F12,0x483E}, // 70003B9A +{0x0F12,0x2509}, // 70003B9C +{0x0F12,0xF000}, // 70003B9E +{0x0F12,0xFC95}, // 70003BA0 +{0x0F12,0x002A}, // 70003BA2 +{0x0F12,0x493C}, // 70003BA4 +{0x0F12,0x483D}, // 70003BA6 +{0x0F12,0x250A}, // 70003BA8 +{0x0F12,0xF000}, // 70003BAA +{0x0F12,0xFC8F}, // 70003BAC +{0x0F12,0x002A}, // 70003BAE +{0x0F12,0x493B}, // 70003BB0 +{0x0F12,0x483C}, // 70003BB2 +{0x0F12,0x250B}, // 70003BB4 +{0x0F12,0xF000}, // 70003BB6 +{0x0F12,0xFC89}, // 70003BB8 +{0x0F12,0x002A}, // 70003BBA +{0x0F12,0x493A}, // 70003BBC +{0x0F12,0x483B}, // 70003BBE +{0x0F12,0x250C}, // 70003BC0 +{0x0F12,0xF000}, // 70003BC2 +{0x0F12,0xFC83}, // 70003BC4 +{0x0F12,0x002A}, // 70003BC6 +{0x0F12,0x4939}, // 70003BC8 +{0x0F12,0x483A}, // 70003BCA +{0x0F12,0x250D}, // 70003BCC +{0x0F12,0xF000}, // 70003BCE +{0x0F12,0xFC7D}, // 70003BD0 +{0x0F12,0x002A}, // 70003BD2 +{0x0F12,0x4938}, // 70003BD4 +{0x0F12,0x4839}, // 70003BD6 +{0x0F12,0x250E}, // 70003BD8 +{0x0F12,0xF000}, // 70003BDA +{0x0F12,0xFC77}, // 70003BDC +{0x0F12,0x002A}, // 70003BDE +{0x0F12,0x4937}, // 70003BE0 +{0x0F12,0x4838}, // 70003BE2 +{0x0F12,0x250F}, // 70003BE4 +{0x0F12,0xF000}, // 70003BE6 +{0x0F12,0xFC71}, // 70003BE8 +{0x0F12,0x002A}, // 70003BEA +{0x0F12,0x4936}, // 70003BEC +{0x0F12,0x4837}, // 70003BEE +{0x0F12,0x2510}, // 70003BF0 +{0x0F12,0xF000}, // 70003BF2 +{0x0F12,0xFC6B}, // 70003BF4 +{0x0F12,0x002A}, // 70003BF6 +{0x0F12,0x4935}, // 70003BF8 +{0x0F12,0x4836}, // 70003BFA +{0x0F12,0x2511}, // 70003BFC +{0x0F12,0xF000}, // 70003BFE +{0x0F12,0xFC65}, // 70003C00 +{0x0F12,0x4835}, // 70003C02 +{0x0F12,0x61B0}, // 70003C04 +{0x0F12,0x2000}, // 70003C06 +{0x0F12,0x8620}, // 70003C08 +{0x0F12,0x20FF}, // 70003C0A +{0x0F12,0x1C40}, // 70003C0C +{0x0F12,0x8660}, // 70003C0E +{0x0F12,0x4832}, // 70003C10 +{0x0F12,0x64F8}, // 70003C12 +{0x0F12,0x4932}, // 70003C14 +{0x0F12,0x4833}, // 70003C16 +{0x0F12,0x2412}, // 70003C18 +{0x0F12,0x002A}, // 70003C1A +{0x0F12,0xF000}, // 70003C1C +{0x0F12,0xFC56}, // 70003C1E +{0x0F12,0x4931}, // 70003C20 +{0x0F12,0x4832}, // 70003C22 +{0x0F12,0x0022}, // 70003C24 +{0x0F12,0xF000}, // 70003C26 +{0x0F12,0xFC51}, // 70003C28 +{0x0F12,0xBCF8}, // 70003C2A +{0x0F12,0xBC08}, // 70003C2C +{0x0F12,0x4718}, // 70003C2E +{0x0F12,0x0184}, // 70003C30 +{0x0F12,0x4EC2}, // 70003C32 +{0x0F12,0x77FF}, // 70003C34 +{0x0F12,0x0000}, // 70003C36 +{0x0F12,0x1F90}, // 70003C38 +{0x0F12,0x7000}, // 70003C3A +{0x0F12,0x3D09}, // 70003C3C +{0x0F12,0x7000}, // 70003C3E +{0x0F12,0xE38B}, // 70003C40 +{0x0F12,0x0000}, // 70003C42 +{0x0F12,0x3D41}, // 70003C44 +{0x0F12,0x7000}, // 70003C46 +{0x0F12,0xC3B1}, // 70003C48 +{0x0F12,0x0000}, // 70003C4A +{0x0F12,0x4780}, // 70003C4C +{0x0F12,0x7000}, // 70003C4E +{0x0F12,0x3D9F}, // 70003C50 +{0x0F12,0x7000}, // 70003C52 +{0x0F12,0x0080}, // 70003C54 +{0x0F12,0x7000}, // 70003C56 +{0x0F12,0x3DDB}, // 70003C58 +{0x0F12,0x7000},// 70003C5A +{0x0F12,0xB49D}, // 70003C5C +{0x0F12,0x0000}, // 70003C5E +{0x0F12,0x4003}, // 70003C60 +{0x0F12,0x7000}, // 70003C62 +{0x0F12,0x3E87}, // 70003C64 +{0x0F12,0x7000}, // 70003C66 +{0x0F12,0x3E3B}, // 70003C68 +{0x0F12,0x7000}, // 70003C6A +{0x0F12,0xFFFF}, // 70003C6C +{0x0F12,0x00FF}, // 70003C6E +{0x0F12,0x17E0}, // 70003C70 +{0x0F12,0x7000}, // 70003C72 +{0x0F12,0x4021}, // 70003C74 +{0x0F12,0x7000}, // 70003C76 +{0x0F12,0x053D}, // 70003C78 +{0x0F12,0x0000}, // 70003C7A +{0x0F12,0x0000}, // 70003C7C +{0x0F12,0x0A89}, // 70003C7E +{0x0F12,0x6CD2}, // 70003C80 +{0x0F12,0x0000}, // 70003C82 +{0x0F12,0x02C9}, // 70003C84 +{0x0F12,0x0000}, // 70003C86 +{0x0F12,0x0000}, // 70003C88 +{0x0F12,0x0A9A}, // 70003C8A +{0x0F12,0x0000}, // 70003C8C +{0x0F12,0x02D2}, // 70003C8E +{0x0F12,0x406F}, // 70003C90 +{0x0F12,0x7000}, // 70003C92 +{0x0F12,0x9E65}, // 70003C94 +{0x0F12,0x0000}, // 70003C96 +{0x0F12,0x4141}, // 70003C98 +{0x0F12,0x7000}, // 70003C9A +{0x0F12,0x7C49}, // 70003C9C +{0x0F12,0x0000}, // 70003C9E +{0x0F12,0x415D}, // 70003CA0 +{0x0F12,0x7000}, // 70003CA2 +{0x0F12,0x7C63}, // 70003CA4 +{0x0F12,0x0000}, // 70003CA6 +{0x0F12,0x4179}, // 70003CA8 +{0x0F12,0x7000}, // 70003CAA +{0x0F12,0x8F01}, // 70003CAC +{0x0F12,0x0000}, // 70003CAE +{0x0F12,0x421B}, // 70003CB0 +{0x0F12,0x7000}, // 70003CB2 +{0x0F12,0x7F3F}, // 70003CB4 +{0x0F12,0x0000}, // 70003CB6 +{0x0F12,0x42A9}, // 70003CB8 +{0x0F12,0x7000}, // 70003CBA +{0x0F12,0x98C5}, // 70003CBC +{0x0F12,0x0000}, // 70003CBE +{0x0F12,0x4349}, // 70003CC0 +{0x0F12,0x7000}, // 70003CC2 +{0x0F12,0xCE75}, // 70003CC4 +{0x0F12,0x0000}, // 70003CC6 +{0x0F12,0x4447}, // 70003CC8 +{0x0F12,0x7000}, // 70003CCA +{0x0F12,0x6099}, // 70003CCC +{0x0F12,0x0000}, // 70003CCE +{0x0F12,0x4445}, // 70003CD0 +{0x0F12,0x7000}, // 70003CD2 +{0x0F12,0xF87F}, // 70003CD4 +{0x0F12,0x0000}, // 70003CD6 +{0x0F12,0x443D}, // 70003CD8 +{0x0F12,0x7000}, // 70003CDA +{0x0F12,0x4397}, // 70003CDC +{0x0F12,0x7000}, // 70003CDE +{0x0F12,0x43ED}, // 70003CE0 +{0x0F12,0x7000}, // 70003CE2 +{0x0F12,0xA70B}, // 70003CE4 +{0x0F12,0x0000}, // 70003CE6 +{0x0F12,0x440F}, // 70003CE8 +{0x0F12,0x7000}, // 70003CEA +{0x0F12,0x400D}, // 70003CEC +{0x0F12,0x0000}, // 70003CEE +{0x0F12,0xB570}, // 70003CF0 +{0x0F12,0x000C}, // 70003CF2 +{0x0F12,0x0015}, // 70003CF4 +{0x0F12,0x0029}, // 70003CF6 +{0x0F12,0xF000}, // 70003CF8 +{0x0F12,0xFBF0}, // 70003CFA +{0x0F12,0x49F9}, // 70003CFC +{0x0F12,0x00A8}, // 70003CFE +{0x0F12,0x500C}, // 70003D00 +{0x0F12,0xBC70}, // 70003D02 +{0x0F12,0xBC08}, // 70003D04 +{0x0F12,0x4718}, // 70003D06 +{0x0F12,0x6808}, // 70003D08 +{0x0F12,0x0400}, // 70003D0A +{0x0F12,0x0C00}, // 70003D0C +{0x0F12,0x6849}, // 70003D0E +{0x0F12,0x0409}, // 70003D10 +{0x0F12,0x0C09}, // 70003D12 +{0x0F12,0x4AF4}, // 70003D14 +{0x0F12,0x8992}, // 70003D16 +{0x0F12,0x2A00}, // 70003D18 +{0x0F12,0xD00D}, // 70003D1A +{0x0F12,0x2300}, // 70003D1C +{0x0F12,0x1A89}, // 70003D1E +{0x0F12,0xD400}, // 70003D20 +{0x0F12,0x000B}, // 70003D22 +{0x0F12,0x0419}, // 70003D24 +{0x0F12,0x0C09}, // 70003D26 +{0x0F12,0x23FF}, // 70003D28 +{0x0F12,0x33C1}, // 70003D2A +{0x0F12,0x1810}, // 70003D2C +{0x0F12,0x4298}, // 70003D2E +{0x0F12,0xD800}, // 70003D30 +{0x0F12,0x0003}, // 70003D32 +{0x0F12,0x0418}, // 70003D34 +{0x0F12,0x0C00}, // 70003D36 +{0x0F12,0x4AEC}, // 70003D38 +{0x0F12,0x8150}, // 70003D3A +{0x0F12,0x8191}, // 70003D3C +{0x0F12,0x4770}, // 70003D3E +{0x0F12,0xB5F3}, // 70003D40 +{0x0F12,0x0004}, // 70003D42 +{0x0F12,0xB081}, // 70003D44 +{0x0F12,0x9802}, // 70003D46 +{0x0F12,0x6800}, // 70003D48 +{0x0F12,0x0600}, // 70003D4A +{0x0F12,0x0E00}, // 70003D4C +{0x0F12,0x2201}, // 70003D4E +{0x0F12,0x0015}, // 70003D50 +{0x0F12,0x0021}, // 70003D52 +{0x0F12,0x3910}, // 70003D54 +{0x0F12,0x408A}, // 70003D56 +{0x0F12,0x40A5}, // 70003D58 +{0x0F12,0x4FE5}, // 70003D5A +{0x0F12,0x0016}, // 70003D5C +{0x0F12,0x2C10}, // 70003D5E +{0x0F12,0xDA03}, // 70003D60 +{0x0F12,0x8839}, // 70003D62 +{0x0F12,0x43A9}, // 70003D64 +{0x0F12,0x8039}, // 70003D66 +{0x0F12,0xE002}, // 70003D68 +{0x0F12,0x8879}, // 70003D6A +{0x0F12,0x43B1}, // 70003D6C +{0x0F12,0x8079}, // 70003D6E +{0x0F12,0xF000}, // 70003D70 +{0x0F12,0xFBBC}, // 70003D72 +{0x0F12,0x2C10}, // 70003D74 +{0x0F12,0xDA03}, // 70003D76 +{0x0F12,0x8839}, // 70003D78 +{0x0F12,0x4329}, // 70003D7A +{0x0F12,0x8039}, // 70003D7C +{0x0F12,0xE002}, // 70003D7E +{0x0F12,0x8879}, // 70003D80 +{0x0F12,0x4331}, // 70003D82 +{0x0F12,0x8079}, // 70003D84 +{0x0F12,0x49DB}, // 70003D86 +{0x0F12,0x8809}, // 70003D88 +{0x0F12,0x2900}, // 70003D8A +{0x0F12,0xD102}, // 70003D8C +{0x0F12,0xF000}, // 70003D8E +{0x0F12,0xFBB5}, // 70003D90 +{0x0F12,0x2000}, // 70003D92 +{0x0F12,0x9902}, // 70003D94 +{0x0F12,0x6008}, // 70003D96 +{0x0F12,0xBCFE}, // 70003D98 +{0x0F12,0xBC08}, // 70003D9A +{0x0F12,0x4718}, // 70003D9C +{0x0F12,0xB538}, // 70003D9E +{0x0F12,0x9C04}, // 70003DA0 +{0x0F12,0x0015}, // 70003DA2 +{0x0F12,0x002A}, // 70003DA4 +{0x0F12,0x9400}, // 70003DA6 +{0x0F12,0xF000}, // 70003DA8 +{0x0F12,0xFBB0}, // 70003DAA +{0x0F12,0x4AD2}, // 70003DAC +{0x0F12,0x8811}, // 70003DAE +{0x0F12,0x2900}, // 70003DB0 +{0x0F12,0xD00F}, // 70003DB2 +{0x0F12,0x8820}, // 70003DB4 +{0x0F12,0x4281}, // 70003DB6 +{0x0F12,0xD20C}, // 70003DB8 +{0x0F12,0x8861}, // 70003DBA +{0x0F12,0x8853}, // 70003DBC +{0x0F12,0x4299}, // 70003DBE +{0x0F12,0xD200}, // 70003DC0 +{0x0F12,0x1E40}, // 70003DC2 +{0x0F12,0x0400}, // 70003DC4 +{0x0F12,0x0C00}, // 70003DC6 +{0x0F12,0x8020}, // 70003DC8 +{0x0F12,0x8851}, // 70003DCA +{0x0F12,0x8061}, // 70003DCC +{0x0F12,0x4368}, // 70003DCE +{0x0F12,0x1840}, // 70003DD0 +{0x0F12,0x6060}, // 70003DD2 +{0x0F12,0xBC38}, // 70003DD4 +{0x0F12,0xBC08}, // 70003DD6 +{0x0F12,0x4718}, // 70003DD8 +{0x0F12,0xB5F8}, // 70003DDA +{0x0F12,0x0004}, // 70003DDC +{0x0F12,0x6808}, // 70003DDE +{0x0F12,0x0400}, // 70003DE0 +{0x0F12,0x0C00}, // 70003DE2 +{0x0F12,0x2201}, // 70003DE4 +{0x0F12,0x0015}, // 70003DE6 +{0x0F12,0x0021}, // 70003DE8 +{0x0F12,0x3910}, // 70003DEA +{0x0F12,0x408A}, // 70003DEC +{0x0F12,0x40A5}, // 70003DEE +{0x0F12,0x4FBF}, // 70003DF0 +{0x0F12,0x0016}, // 70003DF2 +{0x0F12,0x2C10}, // 70003DF4 +{0x0F12,0xDA03}, // 70003DF6 +{0x0F12,0x8839}, // 70003DF8 +{0x0F12,0x43A9}, // 70003DFA +{0x0F12,0x8039}, // 70003DFC +{0x0F12,0xE002}, // 70003DFE +{0x0F12,0x8879}, // 70003E00 +{0x0F12,0x43B1}, // 70003E02 +{0x0F12,0x8079}, // 70003E04 +{0x0F12,0xF000}, // 70003E06 +{0x0F12,0xFB89}, // 70003E08 +{0x0F12,0x2C10}, // 70003E0A +{0x0F12,0xDA03}, // 70003E0C +{0x0F12,0x8838}, // 70003E0E +{0x0F12,0x4328}, // 70003E10 +{0x0F12,0x8038}, // 70003E12 +{0x0F12,0xE002}, // 70003E14 +{0x0F12,0x8878}, // 70003E16 +{0x0F12,0x4330}, // 70003E18 +{0x0F12,0x8078}, // 70003E1A +{0x0F12,0x48B7}, // 70003E1C +{0x0F12,0x8800}, // 70003E1E +{0x0F12,0x0400}, // 70003E20 +{0x0F12,0xD507}, // 70003E22 +{0x0F12,0x4BB6}, // 70003E24 +{0x0F12,0x7819}, // 70003E26 +{0x0F12,0x4AB6}, // 70003E28 +{0x0F12,0x7810}, // 70003E2A +{0x0F12,0x7018}, // 70003E2C +{0x0F12,0x7011}, // 70003E2E +{0x0F12,0x49B5}, // 70003E30 +{0x0F12,0x8188}, // 70003E32 +{0x0F12,0xBCF8}, // 70003E34 +{0x0F12,0xBC08}, // 70003E36 +{0x0F12,0x4718}, // 70003E38 +{0x0F12,0xB538}, // 70003E3A +{0x0F12,0x48B3}, // 70003E3C +{0x0F12,0x4669}, // 70003E3E +{0x0F12,0xF000}, // 70003E40 +{0x0F12,0xFB74}, // 70003E42 +{0x0F12,0x48B2}, // 70003E44 +{0x0F12,0x49B1}, // 70003E46 +{0x0F12,0x69C2}, // 70003E48 +{0x0F12,0x2400}, // 70003E4A +{0x0F12,0x31A8}, // 70003E4C +{0x0F12,0x2A00}, // 70003E4E +{0x0F12,0xD008}, // 70003E50 +{0x0F12,0x61C4}, // 70003E52 +{0x0F12,0x684A}, // 70003E54 +{0x0F12,0x6242}, // 70003E56 +{0x0F12,0x6282}, // 70003E58 +{0x0F12,0x466B}, // 70003E5A +{0x0F12,0x881A}, // 70003E5C +{0x0F12,0x6302}, // 70003E5E +{0x0F12,0x885A}, // 70003E60 +{0x0F12,0x6342}, // 70003E62 +{0x0F12,0x6A02}, // 70003E64 +{0x0F12,0x2A00}, // 70003E66 +{0x0F12,0xD00A}, // 70003E68 +{0x0F12,0x6204}, // 70003E6A +{0x0F12,0x6849}, // 70003E6C +{0x0F12,0x6281}, // 70003E6E +{0x0F12,0x466B}, // 70003E70 +{0x0F12,0x8819}, // 70003E72 +{0x0F12,0x6301}, // 70003E74 +{0x0F12,0x8859}, // 70003E76 +{0x0F12,0x6341}, // 70003E78 +{0x0F12,0x49A6}, // 70003E7A +{0x0F12,0x88C9}, // 70003E7C +{0x0F12,0x63C1}, // 70003E7E +{0x0F12,0xF000}, // 70003E80 +{0x0F12,0xFB5C}, // 70003E82 +{0x0F12,0xE7A6}, // 70003E84 +{0x0F12,0xB5F0}, // 70003E86 +{0x0F12,0xB08B}, // 70003E88 +{0x0F12,0x20FF}, // 70003E8A +{0x0F12,0x1C40}, // 70003E8C +{0x0F12,0x49A2}, // 70003E8E +{0x0F12,0x89CC}, // 70003E90 +{0x0F12,0x4E9F}, // 70003E92 +{0x0F12,0x6AB1}, // 70003E94 +{0x0F12,0x4284}, // 70003E96 +{0x0F12,0xD101}, // 70003E98 +{0x0F12,0x48A0}, // 70003E9A +{0x0F12,0x6081}, // 70003E9C +{0x0F12,0x6A70}, // 70003E9E +{0x0F12,0x0200}, // 70003EA0 +{0x0F12,0xF000}, // 70003EA2 +{0x0F12,0xFB53}, // 70003EA4 +{0x0F12,0x0400}, // 70003EA6 +{0x0F12,0x0C00}, // 70003EA8 +{0x0F12,0x4A97}, // 70003EAA +{0x0F12,0x8A11}, // 70003EAC +{0x0F12,0x9109}, // 70003EAE +{0x0F12,0x2101}, // 70003EB0 +{0x0F12,0x0349}, // 70003EB2 +{0x0F12,0x4288}, // 70003EB4 +{0x0F12,0xD200}, // 70003EB6 +{0x0F12,0x0001}, // 70003EB8 +{0x0F12,0x4A93}, // 70003EBA +{0x0F12,0x8211}, // 70003EBC +{0x0F12,0x4D98}, // 70003EBE +{0x0F12,0x8829}, // 70003EC0 +{0x0F12,0x9108}, // 70003EC2 +{0x0F12,0x4A8C}, // 70003EC4 +{0x0F12,0x2303}, // 70003EC6 +{0x0F12,0x3222}, // 70003EC8 +{0x0F12,0x1F91}, // 70003ECA +{0x0F12,0xF000}, // 70003ECC +{0x0F12,0xFB44}, // 70003ECE +{0x0F12,0x8028}, // 70003ED0 +{0x0F12,0x488F}, // 70003ED2 +{0x0F12,0x4988}, // 70003ED4 +{0x0F12,0x6BC2}, // 70003ED6 +{0x0F12,0x6AC0}, // 70003ED8 +{0x0F12,0x4282}, // 70003EDA +{0x0F12,0xD201}, // 70003EDC +{0x0F12,0x8CC8}, // 70003EDE +{0x0F12,0x8028}, // 70003EE0 +{0x0F12,0x88E8}, // 70003EE2 +{0x0F12,0x9007}, // 70003EE4 +{0x0F12,0x2240}, // 70003EE6 +{0x0F12,0x4310}, // 70003EE8 +{0x0F12,0x80E8}, // 70003EEA +{0x0F12,0x2000}, // 70003EEC +{0x0F12,0x0041}, // 70003EEE +{0x0F12,0x194B}, // 70003EF0 +{0x0F12,0x001E}, // 70003EF2 +{0x0F12,0x3680}, // 70003EF4 +{0x0F12,0x8BB2}, // 70003EF6 +{0x0F12,0xAF04}, // 70003EF8 +{0x0F12,0x527A}, // 70003EFA +{0x0F12,0x4A7E}, // 70003EFC +{0x0F12,0x188A}, // 70003EFE +{0x0F12,0x8897}, // 70003F00 +{0x0F12,0x83B7}, // 70003F02 +{0x0F12,0x33A0}, // 70003F04 +{0x0F12,0x891F}, // 70003F06 +{0x0F12,0xAE01}, // 70003F08 +{0x0F12,0x5277}, // 70003F0A +{0x0F12,0x8A11}, // 70003F0C +{0x0F12,0x8119}, // 70003F0E +{0x0F12,0x1C40}, // 70003F10 +{0x0F12,0x0400}, // 70003F12 +{0x0F12,0x0C00}, // 70003F14 +{0x0F12,0x2806}, // 70003F16 +{0x0F12,0xD3E9}, // 70003F18 +{0x0F12,0xF000}, // 70003F1A +{0x0F12,0xFB25}, // 70003F1C +{0x0F12,0xF000}, // 70003F1E +{0x0F12,0xFB2B}, // 70003F20 +{0x0F12,0x4F7A}, // 70003F22 +{0x0F12,0x37A8}, // 70003F24 +{0x0F12,0x2800}, // 70003F26 +{0x0F12,0xD10A}, // 70003F28 +{0x0F12,0x1FE0}, // 70003F2A +{0x0F12,0x38FD}, // 70003F2C +{0x0F12,0xD001}, // 70003F2E +{0x0F12,0x1CC0}, // 70003F30 +{0x0F12,0xD105}, // 70003F32 +{0x0F12,0x4875}, // 70003F34 +{0x0F12,0x8829}, // 70003F36 +{0x0F12,0x3818}, // 70003F38 +{0x0F12,0x6840}, // 70003F3A +{0x0F12,0x4348}, // 70003F3C +{0x0F12,0x6078}, // 70003F3E +{0x0F12,0x4973}, // 70003F40 +{0x0F12,0x6878}, // 70003F42 +{0x0F12,0x6B89}, // 70003F44 +{0x0F12,0x4288}, // 70003F46 +{0x0F12,0xD300}, // 70003F48 +{0x0F12,0x0008}, // 70003F4A +{0x0F12,0x6078}, // 70003F4C +{0x0F12,0x2000}, // 70003F4E +{0x0F12,0x0041}, // 70003F50 +{0x0F12,0xAA04}, // 70003F52 +{0x0F12,0x5A53}, // 70003F54 +{0x0F12,0x194A}, // 70003F56 +{0x0F12,0x269C}, // 70003F58 +{0x0F12,0x52B3}, // 70003F5A +{0x0F12,0xAB01}, // 70003F5C +{0x0F12,0x5A59}, // 70003F5E +{0x0F12,0x32A0}, // 70003F60 +{0x0F12,0x8111}, // 70003F62 +{0x0F12,0x1C40}, // 70003F64 +{0x0F12,0x0400}, // 70003F66 +{0x0F12,0x0C00}, // 70003F68 +{0x0F12,0x2806}, // 70003F6A +{0x0F12,0xD3F0}, // 70003F6C +{0x0F12,0x4966}, // 70003F6E +{0x0F12,0x9809}, // 70003F70 +{0x0F12,0x8208}, // 70003F72 +{0x0F12,0x9808}, // 70003F74 +{0x0F12,0x8028}, // 70003F76 +{0x0F12,0x9807}, // 70003F78 +{0x0F12,0x80E8}, // 70003F7A +{0x0F12,0x1FE0}, // 70003F7C +{0x0F12,0x38FD}, // 70003F7E +{0x0F12,0xD13B}, // 70003F80 +{0x0F12,0x4D65}, // 70003F82 +{0x0F12,0x89E8}, // 70003F84 +{0x0F12,0x1FC1}, // 70003F86 +{0x0F12,0x39FF}, // 70003F88 +{0x0F12,0xD136}, // 70003F8A +{0x0F12,0x4C60}, // 70003F8C +{0x0F12,0x8AE0}, // 70003F8E +{0x0F12,0xF000}, // 70003F90 +{0x0F12,0xFAFA}, // 70003F92 +{0x0F12,0x0006}, // 70003F94 +{0x0F12,0x8B20}, // 70003F96 +{0x0F12,0xF000}, // 70003F98 +{0x0F12,0xFAFE}, // 70003F9A +{0x0F12,0x9000}, // 70003F9C +{0x0F12,0x6AA1}, // 70003F9E +{0x0F12,0x6878}, // 70003FA0 +{0x0F12,0x1809}, // 70003FA2 +{0x0F12,0x0200}, // 70003FA4 +{0x0F12,0xF000}, // 70003FA6 +{0x0F12,0xFAD1}, // 70003FA8 +{0x0F12,0x0400}, // 70003FAA +{0x0F12,0x0C00}, // 70003FAC +{0x0F12,0x0022}, // 70003FAE +{0x0F12,0x3246}, // 70003FB0 +{0x0F12,0x0011}, // 70003FB2 +{0x0F12,0x310A}, // 70003FB4 +{0x0F12,0x2305}, // 70003FB6 +{0x0F12,0xF000}, // 70003FB8 +{0x0F12,0xFACE}, // 70003FBA +{0x0F12,0x66E8}, // 70003FBC +{0x0F12,0x6B23}, // 70003FBE +{0x0F12,0x0002}, // 70003FC0 +{0x0F12,0x0031}, // 70003FC2 +{0x0F12,0x0018}, // 70003FC4 +{0x0F12,0xF000}, // 70003FC6 +{0x0F12,0xFAEF}, // 70003FC8 +{0x0F12,0x466B}, // 70003FCA +{0x0F12,0x8518}, // 70003FCC +{0x0F12,0x6EEA}, // 70003FCE +{0x0F12,0x6B60}, // 70003FD0 +{0x0F12,0x9900}, // 70003FD2 +{0x0F12,0xF000}, // 70003FD4 +{0x0F12,0xFAE8}, // 70003FD6 +{0x0F12,0x466B}, // 70003FD8 +{0x0F12,0x8558}, // 70003FDA +{0x0F12,0x0029}, // 70003FDC +{0x0F12,0x980A}, // 70003FDE +{0x0F12,0x3170}, // 70003FE0 +{0x0F12,0xF000}, // 70003FE2 +{0x0F12,0xFAE9}, // 70003FE4 +{0x0F12,0x0028}, // 70003FE6 +{0x0F12,0x3060}, // 70003FE8 +{0x0F12,0x8A02}, // 70003FEA +{0x0F12,0x4947}, // 70003FEC +{0x0F12,0x3128}, // 70003FEE +{0x0F12,0x808A}, // 70003FF0 +{0x0F12,0x8A42}, // 70003FF2 +{0x0F12,0x80CA}, // 70003FF4 +{0x0F12,0x8A80}, // 70003FF6 +{0x0F12,0x8108}, // 70003FF8 +{0x0F12,0xB00B}, // 70003FFA +{0x0F12,0xBCF0}, // 70003FFC +{0x0F12,0xBC08}, // 70003FFE +{0x0F12,0x4718}, // 70004000 +{0x0F12,0x4845}, // 70004002 +{0x0F12,0x3060}, // 70004004 +{0x0F12,0x8881}, // 70004006 +{0x0F12,0x2900}, // 70004008 +{0x0F12,0xD007}, // 7000400A +{0x0F12,0x2100}, // 7000400C +{0x0F12,0x8081}, // 7000400E +{0x0F12,0x4944}, // 70004010 +{0x0F12,0x20FF}, // 70004012 +{0x0F12,0x1C40}, // 70004014 +{0x0F12,0x8048}, // 70004016 +{0x0F12,0x2001}, // 70004018 +{0x0F12,0x4770}, // 7000401A +{0x0F12,0x2000}, // 7000401C +{0x0F12,0x4770}, // 7000401E +{0x0F12,0xB570}, // 70004020 +{0x0F12,0x2400}, // 70004022 +{0x0F12,0x4D40}, // 70004024 +{0x0F12,0x4841}, // 70004026 +{0x0F12,0x8881}, // 70004028 +{0x0F12,0x4841}, // 7000402A +{0x0F12,0x8041}, // 7000402C +{0x0F12,0x2101}, // 7000402E +{0x0F12,0x8001}, // 70004030 +{0x0F12,0xF000}, // 70004032 +{0x0F12,0xFAC9}, // 70004034 +{0x0F12,0x483D}, // 70004036 +{0x0F12,0x3820}, // 70004038 +{0x0F12,0x8BC0}, // 7000403A +{0x0F12,0xF000}, // 7000403C +{0x0F12,0xFACC}, // 7000403E +{0x0F12,0x4B3C}, // 70004040 +{0x0F12,0x220D}, // 70004042 +{0x0F12,0x0712}, // 70004044 +{0x0F12,0x18A8}, // 70004046 +{0x0F12,0x8806}, // 70004048 +{0x0F12,0x00E1}, // 7000404A +{0x0F12,0x18C9}, // 7000404C +{0x0F12,0x81CE}, // 7000404E +{0x0F12,0x8846}, // 70004050 +{0x0F12,0x818E}, // 70004052 +{0x0F12,0x8886}, // 70004054 +{0x0F12,0x824E}, // 70004056 +{0x0F12,0x88C0}, // 70004058 +{0x0F12,0x8208}, // 7000405A +{0x0F12,0x3508}, // 7000405C +{0x0F12,0x042D}, // 7000405E +{0x0F12,0x0C2D}, // 70004060 +{0x0F12,0x1C64}, // 70004062 +{0x0F12,0x0424}, // 70004064 +{0x0F12,0x0C24}, // 70004066 +{0x0F12,0x2C07}, // 70004068 +{0x0F12,0xD3EC}, // 7000406A +{0x0F12,0xE649}, // 7000406C +{0x0F12,0xB510}, // 7000406E +{0x0F12,0x482E}, // 70004070 +{0x0F12,0x4C2F}, // 70004072 +{0x0F12,0x88C0}, // 70004074 +{0x0F12,0x8060}, // 70004076 +{0x0F12,0x2001}, // 70004078 +{0x0F12,0x8020}, // 7000407A +{0x0F12,0x482B}, // 7000407C +{0x0F12,0x3820}, // 7000407E +{0x0F12,0x8BC0}, // 70004080 +{0x0F12,0xF000}, // 70004082 +{0x0F12,0xFAA9}, // 70004084 +{0x0F12,0x88E0}, // 70004086 +{0x0F12,0x4A2B}, // 70004088 +{0x0F12,0x2800}, // 7000408A +{0x0F12,0xD003}, // 7000408C +{0x0F12,0x492B}, // 7000408E +{0x0F12,0x8849}, // 70004090 +{0x0F12,0x2900}, // 70004092 +{0x0F12,0xD009}, // 70004094 +{0x0F12,0x2001}, // 70004096 +{0x0F12,0x03C0}, // 70004098 +{0x0F12,0x8050}, // 7000409A +{0x0F12,0x80D0}, // 7000409C +{0x0F12,0x2000}, // 7000409E +{0x0F12,0x8090}, // 700040A0 +{0x0F12,0x8110}, // 700040A2 +{0x0F12,0xBC10}, // 700040A4 +{0x0F12,0xBC08}, // 700040A6 +{0x0F12,0x4718},// 700040A8 +{0x0F12,0x8050}, // 700040AA +{0x0F12,0x8920}, // 700040AC +{0x0F12,0x80D0}, // 700040AE +{0x0F12,0x8960}, // 700040B0 +{0x0F12,0x0400}, // 700040B2 +{0x0F12,0x1400}, // 700040B4 +{0x0F12,0x8090}, // 700040B6 +{0x0F12,0x89A1}, // 700040B8 +{0x0F12,0x0409}, // 700040BA +{0x0F12,0x1409}, // 700040BC +{0x0F12,0x8111}, // 700040BE +{0x0F12,0x89E3}, // 700040C0 +{0x0F12,0x8A24}, // 700040C2 +{0x0F12,0x2B00}, // 700040C4 +{0x0F12,0xD104}, // 700040C6 +{0x0F12,0x17C3}, // 700040C8 +{0x0F12,0x0F5B}, // 700040CA +{0x0F12,0x1818}, // 700040CC +{0x0F12,0x10C0}, // 700040CE +{0x0F12,0x8090}, // 700040D0 +{0x0F12,0x2C00}, // 700040D2 +{0x0F12,0xD1E6}, // 700040D4 +{0x0F12,0x17C8}, // 700040D6 +{0x0F12,0x0F40}, // 700040D8 +{0x0F12,0x1840}, // 700040DA +{0x0F12,0x10C0}, // 700040DC +{0x0F12,0x8110}, // 700040DE +{0x0F12,0xE7E0}, // 700040E0 +{0x0F12,0x0000}, // 700040E2 +{0x0F12,0x38D4}, // 700040E4 +{0x0F12,0x7000}, // 700040E6 +{0x0F12,0x17D0}, // 700040E8 +{0x0F12,0x7000}, // 700040EA +{0x0F12,0x5000}, // 700040EC +{0x0F12,0xD000}, // 700040EE +{0x0F12,0x1100}, // 700040F0 +{0x0F12,0xD000}, // 700040F2 +{0x0F12,0x171A}, // 700040F4 +{0x0F12,0x7000}, // 700040F6 +{0x0F12,0x4780}, // 700040F8 +{0x0F12,0x7000}, // 700040FA +{0x0F12,0x2FCA}, // 700040FC +{0x0F12,0x7000}, // 700040FE +{0x0F12,0x2FC5}, // 70004100 +{0x0F12,0x7000}, // 70004102 +{0x0F12,0x2FC6}, // 70004104 +{0x0F12,0x7000}, // 70004106 +{0x0F12,0x2ED8}, // 70004108 +{0x0F12,0x7000}, // 7000410A +{0x0F12,0x2BD0}, // 7000410C +{0x0F12,0x7000}, // 7000410E +{0x0F12,0x17E0}, // 70004110 +{0x0F12,0x7000}, // 70004112 +{0x0F12,0x2DE8}, // 70004114 +{0x0F12,0x7000}, // 70004116 +{0x0F12,0x37E0}, // 70004118 +{0x0F12,0x7000}, // 7000411A +{0x0F12,0x210C}, // 7000411C +{0x0F12,0x7000}, // 7000411E +{0x0F12,0x1484}, // 70004120 +{0x0F12,0x7000}, // 70004122 +{0x0F12,0xC100}, // 70004124 +{0x0F12,0xD000}, // 70004126 +{0x0F12,0xA006}, // 70004128 +{0x0F12,0x0000}, // 7000412A +{0x0F12,0x0724}, // 7000412C +{0x0F12,0x7000}, // 7000412E +{0x0F12,0xA000}, // 70004130 +{0x0F12,0xD000}, // 70004132 +{0x0F12,0x2270}, // 70004134 +{0x0F12,0x7000}, // 70004136 +{0x0F12,0x2558}, // 70004138 +{0x0F12,0x7000}, // 7000413A +{0x0F12,0x146C}, // 7000413C +{0x0F12,0x7000}, // 7000413E +{0x0F12,0xB510}, // 70004140 +{0x0F12,0x000C}, // 70004142 +{0x0F12,0x49D4}, // 70004144 +{0x0F12,0x2204}, // 70004146 +{0x0F12,0x6820}, // 70004148 +{0x0F12,0x5E8A}, // 7000414A +{0x0F12,0x0140}, // 7000414C +{0x0F12,0x1A80}, // 7000414E +{0x0F12,0x0280}, // 70004150 +{0x0F12,0x8849}, // 70004152 +{0x0F12,0xF000}, // 70004154 +{0x0F12,0xFA48}, // 70004156 +{0x0F12,0x6020}, // 70004158 +{0x0F12,0xE7A3}, // 7000415A +{0x0F12,0xB510}, // 7000415C +{0x0F12,0x000C}, // 7000415E +{0x0F12,0x49CD}, // 70004160 +{0x0F12,0x2208}, // 70004162 +{0x0F12,0x6820}, // 70004164 +{0x0F12,0x5E8A}, // 70004166 +{0x0F12,0x0140}, // 70004168 +{0x0F12,0x1A80}, // 7000416A +{0x0F12,0x0280}, // 7000416C +{0x0F12,0x88C9}, // 7000416E +{0x0F12,0xF000}, // 70004170 +{0x0F12,0xFA3A}, // 70004172 +{0x0F12,0x6020}, // 70004174 +{0x0F12,0xE795}, // 70004176 +{0x0F12,0xB5FE}, // 70004178 +{0x0F12,0x000C}, // 7000417A +{0x0F12,0x6825}, // 7000417C +{0x0F12,0x6866}, // 7000417E +{0x0F12,0x68A0}, // 70004180 +{0x0F12,0x9001}, // 70004182 +{0x0F12,0x68E7}, // 70004184 +{0x0F12,0x1BA8}, // 70004186 +{0x0F12,0x42B5}, // 70004188 +{0x0F12,0xDA00}, // 7000418A +{0x0F12,0x1B70}, // 7000418C +{0x0F12,0x9000}, // 7000418E +{0x0F12,0x49C1}, // 70004190 +{0x0F12,0x48C2}, // 70004192 +{0x0F12,0x884A}, // 70004194 +{0x0F12,0x8843}, // 70004196 +{0x0F12,0x435A}, // 70004198 +{0x0F12,0x2304}, // 7000419A +{0x0F12,0x5ECB}, // 7000419C +{0x0F12,0x0A92}, // 7000419E +{0x0F12,0x18D2}, // 700041A0 +{0x0F12,0x02D2}, // 700041A2 +{0x0F12,0x0C12}, // 700041A4 +{0x0F12,0x88CB}, // 700041A6 +{0x0F12,0x8880}, // 700041A8 +{0x0F12,0x4343}, // 700041AA +{0x0F12,0x0A98}, // 700041AC +{0x0F12,0x2308}, // 700041AE +{0x0F12,0x5ECB}, // 700041B0 +{0x0F12,0x18C0}, // 700041B2 +{0x0F12,0x02C0}, // 700041B4 +{0x0F12,0x0C00}, // 700041B6 +{0x0F12,0x0411}, // 700041B8 +{0x0F12,0x0400}, // 700041BA +{0x0F12,0x1409}, // 700041BC +{0x0F12,0x1400}, // 700041BE +{0x0F12,0x1A08}, // 700041C0 +{0x0F12,0x49B6}, // 700041C2 +{0x0F12,0x39E0}, // 700041C4 +{0x0F12,0x6148}, // 700041C6 +{0x0F12,0x9801}, // 700041C8 +{0x0F12,0x3040}, // 700041CA +{0x0F12,0x7880}, // 700041CC +{0x0F12,0x2800}, // 700041CE +{0x0F12,0xD103}, // 700041D0 +{0x0F12,0x9801}, // 700041D2 +{0x0F12,0x0029}, // 700041D4 +{0x0F12,0xF000}, // 700041D6 +{0x0F12,0xFA0D}, // 700041D8 +{0x0F12,0x8839}, // 700041DA +{0x0F12,0x9800}, // 700041DC +{0x0F12,0x4281}, // 700041DE +{0x0F12,0xD814}, // 700041E0 +{0x0F12,0x8879}, // 700041E2 +{0x0F12,0x9800}, // 700041E4 +{0x0F12,0x4281}, // 700041E6 +{0x0F12,0xD20C}, // 700041E8 +{0x0F12,0x9801}, // 700041EA +{0x0F12,0x0029}, // 700041EC +{0x0F12,0xF000}, // 700041EE +{0x0F12,0xFA09}, // 700041F0 +{0x0F12,0x9801}, // 700041F2 +{0x0F12,0x0029}, // 700041F4 +{0x0F12,0xF000}, // 700041F6 +{0x0F12,0xFA05}, // 700041F8 +{0x0F12,0x9801}, // 700041FA +{0x0F12,0x0029}, // 700041FC +{0x0F12,0xF000}, // 700041FE +{0x0F12,0xFA01}, // 70004200 +{0x0F12,0xE003}, // 70004202 +{0x0F12,0x9801}, // 70004204 +{0x0F12,0x0029}, // 70004206 +{0x0F12,0xF000}, // 70004208 +{0x0F12,0xF9FC}, // 7000420A +{0x0F12,0x9801}, // 7000420C +{0x0F12,0x0032}, // 7000420E +{0x0F12,0x0039}, // 70004210 +{0x0F12,0xF000}, // 70004212 +{0x0F12,0xF9FF}, // 70004214 +{0x0F12,0x6020}, // 70004216 +{0x0F12,0xE5BE}, // 70004218 +{0x0F12,0xB57C}, // 7000421A +{0x0F12,0x48A0}, // 7000421C +{0x0F12,0xA901}, // 7000421E +{0x0F12,0x0004}, // 70004220 +{0x0F12,0xF000}, // 70004222 +{0x0F12,0xF983}, // 70004224 +{0x0F12,0x466B}, // 70004226 +{0x0F12,0x88D9}, // 70004228 +{0x0F12,0x8898}, // 7000422A +{0x0F12,0x4B9B}, // 7000422C +{0x0F12,0x3346}, // 7000422E +{0x0F12,0x1E9A}, // 70004230 +{0x0F12,0xF000}, // 70004232 +{0x0F12,0xF9F7}, // 70004234 +{0x0F12,0x489A}, // 70004236 +{0x0F12,0x4998}, // 70004238 +{0x0F12,0x3812}, // 7000423A +{0x0F12,0x3140}, // 7000423C +{0x0F12,0x8A42}, // 7000423E +{0x0F12,0x888B}, // 70004240 +{0x0F12,0x18D2}, // 70004242 +{0x0F12,0x8242}, // 70004244 +{0x0F12,0x8AC2}, // 70004246 +{0x0F12,0x88C9}, // 70004248 +{0x0F12,0x1851}, // 7000424A +{0x0F12,0x82C1}, // 7000424C +{0x0F12,0x0020}, // 7000424E +{0x0F12,0x4669}, // 70004250 +{0x0F12,0xF000}, // 70004252 +{0x0F12,0xF96B}, // 70004254 +{0x0F12,0x4893}, // 70004256 +{0x0F12,0x214D}, // 70004258 +{0x0F12,0x8301}, // 7000425A +{0x0F12,0x2196}, // 7000425C +{0x0F12,0x8381}, // 7000425E +{0x0F12,0x211D}, // 70004260 +{0x0F12,0x3020}, // 70004262 +{0x0F12,0x8001}, // 70004264 +{0x0F12,0xF000}, // 70004266 +{0x0F12,0xF9E5}, // 70004268 +{0x0F12,0xF000}, // 7000426A +{0x0F12,0xF9EB}, // 7000426C +{0x0F12,0x488E}, // 7000426E +{0x0F12,0x4C8E}, // 70004270 +{0x0F12,0x6E00}, // 70004272 +{0x0F12,0x60E0}, // 70004274 +{0x0F12,0x466B}, // 70004276 +{0x0F12,0x8818}, // 70004278 +{0x0F12,0x8859}, // 7000427A +{0x0F12,0x0025}, // 7000427C +{0x0F12,0x1A40}, // 7000427E +{0x0F12,0x3540}, // 70004280 +{0x0F12,0x61A8}, // 70004282 +{0x0F12,0x4885}, // 70004284 +{0x0F12,0x9900}, // 70004286 +{0x0F12,0x3060}, // 70004288 +{0x0F12,0xF000}, // 7000428A +{0x0F12,0xF9E3}, // 7000428C +{0x0F12,0x466B}, // 7000428E +{0x0F12,0x8819}, // 70004290 +{0x0F12,0x1DE0}, // 70004292 +{0x0F12,0x30F9}, // 70004294 +{0x0F12,0x8741}, // 70004296 +{0x0F12,0x8859}, // 70004298 +{0x0F12,0x8781}, // 7000429A +{0x0F12,0x2000}, // 7000429C +{0x0F12,0x71A0}, // 7000429E +{0x0F12,0x74A8}, // 700042A0 +{0x0F12,0xBC7C}, // 700042A2 +{0x0F12,0xBC08}, // 700042A4 +{0x0F12,0x4718}, // 700042A6 +{0x0F12,0xB5F8}, // 700042A8 +{0x0F12,0x0005}, // 700042AA +{0x0F12,0x6808}, // 700042AC +{0x0F12,0x0400}, // 700042AE +{0x0F12,0x0C00}, // 700042B0 +{0x0F12,0x684A}, // 700042B2 +{0x0F12,0x0412}, // 700042B4 +{0x0F12,0x0C12}, // 700042B6 +{0x0F12,0x688E}, // 700042B8 +{0x0F12,0x68CC}, // 700042BA +{0x0F12,0x4976}, // 700042BC +{0x0F12,0x884B}, // 700042BE +{0x0F12,0x4343}, // 700042C0 +{0x0F12,0x0A98}, // 700042C2 +{0x0F12,0x2304}, // 700042C4 +{0x0F12,0x5ECB}, // 700042C6 +{0x0F12,0x18C0}, // 700042C8 +{0x0F12,0x02C0}, // 700042CA +{0x0F12,0x0C00}, // 700042CC +{0x0F12,0x88CB}, // 700042CE +{0x0F12,0x4353}, // 700042D0 +{0x0F12,0x0A9A}, // 700042D2 +{0x0F12,0x2308}, // 700042D4 +{0x0F12,0x5ECB}, // 700042D6 +{0x0F12,0x18D1}, // 700042D8 +{0x0F12,0x02C9}, // 700042DA +{0x0F12,0x0C09}, // 700042DC +{0x0F12,0x2701}, // 700042DE +{0x0F12,0x003A}, // 700042E0 +{0x0F12,0x40AA}, // 700042E2 +{0x0F12,0x9200}, // 700042E4 +{0x0F12,0x002A}, // 700042E6 +{0x0F12,0x3A10}, // 700042E8 +{0x0F12,0x4097}, // 700042EA +{0x0F12,0x2D10}, // 700042EC +{0x0F12,0xDA06}, // 700042EE +{0x0F12,0x4A6F}, // 700042F0 +{0x0F12,0x9B00}, // 700042F2 +{0x0F12,0x8812}, // 700042F4 +{0x0F12,0x439A}, // 700042F6 +{0x0F12,0x4B6D}, // 700042F8 +{0x0F12,0x801A}, // 700042FA +{0x0F12,0xE003}, // 700042FC +{0x0F12,0x4B6C}, // 700042FE +{0x0F12,0x885A}, // 70004300 +{0x0F12,0x43BA}, // 70004302 +{0x0F12,0x805A}, // 70004304 +{0x0F12,0x0023}, // 70004306 +{0x0F12,0x0032}, // 70004308 +{0x0F12,0xF000}, // 7000430A +{0x0F12,0xF98B}, // 7000430C +{0x0F12,0x2D10}, // 7000430E +{0x0F12,0xDA05}, // 70004310 +{0x0F12,0x4967}, // 70004312 +{0x0F12,0x9A00}, // 70004314 +{0x0F12,0x8808}, // 70004316 +{0x0F12,0x4310}, // 70004318 +{0x0F12,0x8008}, // 7000431A +{0x0F12,0xE003}, // 7000431C +{0x0F12,0x4864}, // 7000431E +{0x0F12,0x8841}, // 70004320 +{0x0F12,0x4339}, // 70004322 +{0x0F12,0x8041}, // 70004324 +{0x0F12,0x4D61}, // 70004326 +{0x0F12,0x2000}, // 70004328 +{0x0F12,0x3580}, // 7000432A +{0x0F12,0x88AA}, // 7000432C +{0x0F12,0x5E30}, // 7000432E +{0x0F12,0x2100}, // 70004330 +{0x0F12,0xF000}, // 70004332 +{0x0F12,0xF997}, // 70004334 +{0x0F12,0x8030}, // 70004336 +{0x0F12,0x2000}, // 70004338 +{0x0F12,0x88AA}, // 7000433A +{0x0F12,0x5E20}, // 7000433C +{0x0F12,0x2100}, // 7000433E +{0x0F12,0xF000}, // 70004340 +{0x0F12,0xF990}, // 70004342 +{0x0F12,0x8020}, // 70004344 +{0x0F12,0xE575}, // 70004346 +{0x0F12,0xB508}, // 70004348 +{0x0F12,0x6808}, // 7000434A +{0x0F12,0x4959}, // 7000434C +{0x0F12,0x8088}, // 7000434E +{0x0F12,0x0600}, // 70004350 +{0x0F12,0x0D80}, // 70004352 +{0x0F12,0x8288}, // 70004354 +{0x0F12,0x2103}, // 70004356 +{0x0F12,0x466B}, // 70004358 +{0x0F12,0x7019}, // 7000435A +{0x0F12,0x0A01}, // 7000435C +{0x0F12,0x7059}, // 7000435E +{0x0F12,0x7098}, // 70004360 +{0x0F12,0x2103}, // 70004362 +{0x0F12,0x4668}, // 70004364 +{0x0F12,0xF000}, // 70004366 +{0x0F12,0xF985}, // 70004368 +{0x0F12,0xB001}, // 7000436A +{0x0F12,0xBC08}, // 7000436C +{0x0F12,0x4718}, // 7000436E +{0x0F12,0xB510}, // 70004370 +{0x0F12,0xF000}, // 70004372 +{0x0F12,0xF987}, // 70004374 +{0x0F12,0x4A50}, // 70004376 +{0x0F12,0x8D50}, // 70004378 +{0x0F12,0x2800}, // 7000437A +{0x0F12,0xD007}, // 7000437C +{0x0F12,0x494A}, // 7000437E +{0x0F12,0x31C0}, // 70004380 +{0x0F12,0x684B}, // 70004382 +{0x0F12,0x494D}, // 70004384 +{0x0F12,0x4283}, // 70004386 +{0x0F12,0xD202}, // 70004388 +{0x0F12,0x8D90}, // 7000438A +{0x0F12,0x81C8}, // 7000438C +{0x0F12,0xE689}, // 7000438E +{0x0F12,0x8DD0}, // 70004390 +{0x0F12,0x81C8}, // 70004392 +{0x0F12,0xE686}, // 70004394 +{0x0F12,0xB5F8}, // 70004396 +{0x0F12,0xF000}, // 70004398 +{0x0F12,0xF97C}, // 7000439A +{0x0F12,0x4D46}, // 7000439C +{0x0F12,0x8E28}, // 7000439E +{0x0F12,0x2800}, // 700043A0 +{0x0F12,0xD01F}, // 700043A2 +{0x0F12,0x4E46}, // 700043A4 +{0x0F12,0x4840}, // 700043A6 +{0x0F12,0x68B4}, // 700043A8 +{0x0F12,0x6800}, // 700043AA +{0x0F12,0x4284}, // 700043AC +{0x0F12,0xD903}, // 700043AE +{0x0F12,0x1A21}, // 700043B0 +{0x0F12,0x0849}, // 700043B2 +{0x0F12,0x1847}, // 700043B4 +{0x0F12,0xE006}, // 700043B6 +{0x0F12,0x4284}, // 700043B8 +{0x0F12,0xD203}, // 700043BA +{0x0F12,0x1B01}, // 700043BC +{0x0F12,0x0849}, // 700043BE +{0x0F12,0x1A47}, // 700043C0 +{0x0F12,0xE000}, // 700043C2 +{0x0F12,0x0027}, // 700043C4 +{0x0F12,0x0020}, // 700043C6 +{0x0F12,0x4937}, // 700043C8 +{0x0F12,0x3120}, // 700043CA +{0x0F12,0x7A0C}, // 700043CC +{0x0F12,0x2C00}, // 700043CE +{0x0F12,0xD004}, // 700043D0 +{0x0F12,0x0200}, // 700043D2 +{0x0F12,0x0039}, // 700043D4 +{0x0F12,0xF000}, // 700043D6 +{0x0F12,0xF8B9}, // 700043D8 +{0x0F12,0x8668}, // 700043DA +{0x0F12,0x2C00}, // 700043DC +{0x0F12,0xD000}, // 700043DE +{0x0F12,0x60B7}, // 700043E0 +{0x0F12,0xE527}, // 700043E2 +{0x0F12,0x20FF}, // 700043E4 +{0x0F12,0x1C40}, // 700043E6 +{0x0F12,0x8668}, // 700043E8 +{0x0F12,0xE523}, // 700043EA +{0x0F12,0xB510}, // 700043EC +{0x0F12,0x000C}, // 700043EE +{0x0F12,0x6820}, // 700043F0 +{0x0F12,0x0400}, // 700043F2 +{0x0F12,0x0C00}, // 700043F4 +{0x0F12,0x4930}, // 700043F6 +{0x0F12,0x8E0A}, // 700043F8 +{0x0F12,0x2A00}, // 700043FA +{0x0F12,0xD003}, // 700043FC +{0x0F12,0x8E49}, // 700043FE +{0x0F12,0x0200}, // 70004400 +{0x0F12,0xF000}, // 70004402 +{0x0F12,0xF8A3}, // 70004404 +{0x0F12,0x6020}, // 70004406 +{0x0F12,0x0400}, // 70004408 +{0x0F12,0x0C00}, // 7000440A +{0x0F12,0xE64A}, // 7000440C +{0x0F12,0xB570}, // 7000440E +{0x0F12,0x680C}, // 70004410 +{0x0F12,0x4D2C}, // 70004412 +{0x0F12,0x0020}, // 70004414 +{0x0F12,0x6F29}, // 70004416 +{0x0F12,0xF000}, // 70004418 +{0x0F12,0xF944}, // 7000441A +{0x0F12,0x6F69}, // 7000441C +{0x0F12,0x1D20}, // 7000441E +{0x0F12,0xF000}, // 70004420 +{0x0F12,0xF940}, // 70004422 +{0x0F12,0x4824}, // 70004424 +{0x0F12,0x8E00}, // 70004426 +{0x0F12,0x2800}, // 70004428 +{0x0F12,0xD006}, // 7000442A +{0x0F12,0x491E}, // 7000442C +{0x0F12,0x2214}, // 7000442E +{0x0F12,0x3168}, // 70004430 +{0x0F12,0x0008}, // 70004432 +{0x0F12,0x383C}, // 70004434 +{0x0F12,0xF000}, // 70004436 +{0x0F12,0xF93D}, // 70004438 +{0x0F12,0xE462}, // 7000443A +{0x0F12,0x4821}, // 7000443C +{0x0F12,0x6FC1}, // 7000443E +{0x0F12,0x2001}, // 70004440 +{0x0F12,0x4708}, // 70004442 +{0x0F12,0x4770}, // 70004444 +{0x0F12,0xB5F8}, // 70004446 +{0x0F12,0x0004}, // 70004448 +{0x0F12,0x481E}, // 7000444A +{0x0F12,0x6FC1}, // 7000444C +{0x0F12,0x2000}, // 7000444E +{0x0F12,0xF000}, // 70004450 +{0x0F12,0xF928}, // 70004452 +{0x0F12,0x491C}, // 70004454 +{0x0F12,0x20FF}, // 70004456 +{0x0F12,0x1C40}, // 70004458 +{0x0F12,0x8048}, // 7000445A +{0x0F12,0x2101}, // 7000445C +{0x0F12,0x000D}, // 7000445E +{0x0F12,0x0020}, // 70004460 +{0x0F12,0x3810}, // 70004462 +{0x0F12,0x4081}, // 70004464 +{0x0F12,0x40A5}, // 70004466 +{0x0F12,0x4F11}, // 70004468 +{0x0F12,0x000E}, // 7000446A +{0x0F12,0x2C10}, // 7000446C +{0x0F12,0xDA03}, // 7000446E +{0x0F12,0x8838}, // 70004470 +{0x0F12,0x43A8}, // 70004472 +{0x0F12,0x8038}, // 70004474 +{0x0F12,0xE002}, // 70004476 +{0x0F12,0x8878}, // 70004478 +{0x0F12,0x43B0}, // 7000447A +{0x0F12,0x8078}, // 7000447C +{0x0F12,0xF000}, // 7000447E +{0x0F12,0xF91F}, // 70004480 +{0x0F12,0x2C10}, // 70004482 +{0x0F12,0xDA03}, // 70004484 +{0x0F12,0x8838}, // 70004486 +{0x0F12,0x4328}, // 70004488 +{0x0F12,0x8038}, // 7000448A +{0x0F12,0xE4D2}, // 7000448C +{0x0F12,0x8878}, // 7000448E +{0x0F12,0x4330}, // 70004490 +{0x0F12,0x8078}, // 70004492 +{0x0F12,0xE4CE}, // 70004494 +{0x0F12,0x0000}, // 70004496 +{0x0F12,0x2558}, // 70004498 +{0x0F12,0x7000}, // 7000449A +{0x0F12,0x2AB8}, // 7000449C +{0x0F12,0x7000}, // 7000449E +{0x0F12,0x145E}, // 700044A0 +{0x0F12,0x7000}, // 700044A2 +{0x0F12,0x2698}, // 700044A4 +{0x0F12,0x7000}, // 700044A6 +{0x0F12,0x2BB8}, // 700044A8 +{0x0F12,0x7000}, // 700044AA +{0x0F12,0x2998}, // 700044AC +{0x0F12,0x7000}, // 700044AE +{0x0F12,0x1100}, // 700044B0 +{0x0F12,0xD000}, // 700044B2 +{0x0F12,0x3044}, // 700044B4 +{0x0F12,0x7000}, // 700044B6 +{0x0F12,0x4780}, // 700044B8 +{0x0F12,0x7000}, // 700044BA +{0x0F12,0xE200}, // 700044BC +{0x0F12,0xD000}, // 700044BE +{0x0F12,0x210C}, // 700044C0 +{0x0F12,0x7000}, // 700044C2 +{0x0F12,0x0000}, // 700044C4 +{0x0F12,0x7000}, // 700044C6 +{0x0F12,0xC100}, // 700044C8 +{0x0F12,0xD000}, // 700044CA +{0x0F12,0x4778}, // 700044CC +{0x0F12,0x46C0}, // 700044CE +{0x0F12,0xC000}, // 700044D0 +{0x0F12,0xE59F}, // 700044D2 +{0x0F12,0xFF1C}, // 700044D4 +{0x0F12,0xE12F}, // 700044D6 +{0x0F12,0x1789}, // 700044D8 +{0x0F12,0x0001}, // 700044DA +{0x0F12,0x4778}, // 700044DC +{0x0F12,0x46C0}, // 700044DE +{0x0F12,0xC000}, // 700044E0 +{0x0F12,0xE59F}, // 700044E2 +{0x0F12,0xFF1C}, // 700044E4 +{0x0F12,0xE12F}, // 700044E6 +{0x0F12,0x16F1}, // 700044E8 +{0x0F12,0x0001}, // 700044EA +{0x0F12,0x4778}, // 700044EC +{0x0F12,0x46C0}, // 700044EE +{0x0F12,0xC000}, // 700044F0 +{0x0F12,0xE59F}, // 700044F2 +{0x0F12,0xFF1C}, // 700044F4 +{0x0F12,0xE12F}, // 700044F6 +{0x0F12,0xC3B1}, // 700044F8 +{0x0F12,0x0000}, // 700044FA +{0x0F12,0x4778}, // 700044FC +{0x0F12,0x46C0}, // 700044FE +{0x0F12,0xC000}, // 70004500 +{0x0F12,0xE59F}, // 70004502 +{0x0F12,0xFF1C}, // 70004504 +{0x0F12,0xE12F}, // 70004506 +{0x0F12,0xC36D}, // 70004508 +{0x0F12,0x0000}, // 7000450A +{0x0F12,0x4778}, // 7000450C +{0x0F12,0x46C0}, // 7000450E +{0x0F12,0xC000}, // 70004510 +{0x0F12,0xE59F}, // 70004512 +{0x0F12,0xFF1C}, // 70004514 +{0x0F12,0xE12F}, // 70004516 +{0x0F12,0xF6D7}, // 70004518 +{0x0F12,0x0000}, // 7000451A +{0x0F12,0x4778}, // 7000451C +{0x0F12,0x46C0}, // 7000451E +{0x0F12,0xC000}, // 70004520 +{0x0F12,0xE59F}, // 70004522 +{0x0F12,0xFF1C}, // 70004524 +{0x0F12,0xE12F}, // 70004526 +{0x0F12,0xB49D}, // 70004528 +{0x0F12,0x0000}, // 7000452A +{0x0F12,0x4778}, // 7000452C +{0x0F12,0x46C0}, // 7000452E +{0x0F12,0xC000}, // 70004530 +{0x0F12,0xE59F}, // 70004532 +{0x0F12,0xFF1C}, // 70004534 +{0x0F12,0xE12F}, // 70004536 +{0x0F12,0x7EDF}, // 70004538 +{0x0F12,0x0000}, // 7000453A +{0x0F12,0x4778}, // 7000453C +{0x0F12,0x46C0}, // 7000453E +{0x0F12,0xC000}, // 70004540 +{0x0F12,0xE59F}, // 70004542 +{0x0F12,0xFF1C}, // 70004544 +{0x0F12,0xE12F}, // 70004546 +{0x0F12,0x448D}, // 70004548 +{0x0F12,0x0000}, // 7000454A +{0x0F12,0x4778}, // 7000454C +{0x0F12,0x46C0}, // 7000454E +{0x0F12,0xF004}, // 70004550 +{0x0F12,0xE51F}, // 70004552 +{0x0F12,0x29EC}, // 70004554 +{0x0F12,0x0001}, // 70004556 +{0x0F12,0x4778}, // 70004558 +{0x0F12,0x46C0}, // 7000455A +{0x0F12,0xC000}, // 7000455C +{0x0F12,0xE59F}, // 7000455E +{0x0F12,0xFF1C}, // 70004560 +{0x0F12,0xE12F}, // 70004562 +{0x0F12,0x2EF1}, // 70004564 +{0x0F12,0x0000}, // 70004566 +{0x0F12,0x4778}, // 70004568 +{0x0F12,0x46C0}, // 7000456A +{0x0F12,0xC000}, // 7000456C +{0x0F12,0xE59F}, // 7000456E +{0x0F12,0xFF1C}, // 70004570 +{0x0F12,0xE12F}, // 70004572 +{0x0F12,0xEE03}, // 70004574 +{0x0F12,0x0000}, // 70004576 +{0x0F12,0x4778}, // 70004578 +{0x0F12,0x46C0}, // 7000457A +{0x0F12,0xC000}, // 7000457C +{0x0F12,0xE59F}, // 7000457E +{0x0F12,0xFF1C}, // 70004580 +{0x0F12,0xE12F}, // 70004582 +{0x0F12,0xA58B}, // 70004584 +{0x0F12,0x0000}, // 70004586 +{0x0F12,0x4778}, // 70004588 +{0x0F12,0x46C0}, // 7000458A +{0x0F12,0xC000}, // 7000458C +{0x0F12,0xE59F}, // 7000458E +{0x0F12,0xFF1C}, // 70004590 +{0x0F12,0xE12F}, // 70004592 +{0x0F12,0x7C49}, // 70004594 +{0x0F12,0x0000}, // 70004596 +{0x0F12,0x4778}, // 70004598 +{0x0F12,0x46C0}, // 7000459A +{0x0F12,0xC000}, // 7000459C +{0x0F12,0xE59F}, // 7000459E +{0x0F12,0xFF1C}, // 700045A0 +{0x0F12,0xE12F}, // 700045A2 +{0x0F12,0x7C63}, // 700045A4 +{0x0F12,0x0000}, // 700045A6 +{0x0F12,0x4778}, // 700045A8 +{0x0F12,0x46C0}, // 700045AA +{0x0F12,0xC000}, // 700045AC +{0x0F12,0xE59F}, // 700045AE +{0x0F12,0xFF1C}, // 700045B0 +{0x0F12,0xE12F}, // 700045B2 +{0x0F12,0x2DB7}, // 700045B4 +{0x0F12,0x0000}, // 700045B6 +{0x0F12,0x4778}, // 700045B8 +{0x0F12,0x46C0}, // 700045BA +{0x0F12,0xC000}, // 700045BC +{0x0F12,0xE59F}, // 700045BE +{0x0F12,0xFF1C}, // 700045C0 +{0x0F12,0xE12F}, // 700045C2 +{0x0F12,0xEB3D}, // 700045C4 +{0x0F12,0x0000}, // 700045C6 +{0x0F12,0x4778}, // 700045C8 +{0x0F12,0x46C0}, // 700045CA +{0x0F12,0xC000}, // 700045CC +{0x0F12,0xE59F}, // 700045CE +{0x0F12,0xFF1C}, // 700045D0 +{0x0F12,0xE12F}, // 700045D2 +{0x0F12,0xF061}, // 700045D4 +{0x0F12,0x0000},// 700045D6 +{0x0F12,0x4778}, // 700045D8 +{0x0F12,0x46C0}, // 700045DA +{0x0F12,0xC000}, // 700045DC +{0x0F12,0xE59F}, // 700045DE +{0x0F12,0xFF1C}, // 700045E0 +{0x0F12,0xE12F}, // 700045E2 +{0x0F12,0xF0EF}, // 700045E4 +{0x0F12,0x0000}, // 700045E6 +{0x0F12,0x4778}, // 700045E8 +{0x0F12,0x46C0}, // 700045EA +{0x0F12,0xF004}, // 700045EC +{0x0F12,0xE51F}, // 700045EE +{0x0F12,0x2824}, // 700045F0 +{0x0F12,0x0001}, // 700045F2 +{0x0F12,0x4778}, // 700045F4 +{0x0F12,0x46C0}, // 700045F6 +{0x0F12,0xC000}, // 700045F8 +{0x0F12,0xE59F}, // 700045FA +{0x0F12,0xFF1C}, // 700045FC +{0x0F12,0xE12F}, // 700045FE +{0x0F12,0x8EDD}, // 70004600 +{0x0F12,0x0000},// 70004602 +{0x0F12,0x4778}, // 70004604 +{0x0F12,0x46C0}, // 70004606 +{0x0F12,0xC000}, // 70004608 +{0x0F12,0xE59F}, // 7000460A +{0x0F12,0xFF1C}, // 7000460C +{0x0F12,0xE12F}, // 7000460E +{0x0F12,0x8DCB}, // 70004610 +{0x0F12,0x0000},// 70004612 +{0x0F12,0x4778}, // 70004614 +{0x0F12,0x46C0}, // 70004616 +{0x0F12,0xC000}, // 70004618 +{0x0F12,0xE59F}, // 7000461A +{0x0F12,0xFF1C}, // 7000461C +{0x0F12,0xE12F}, // 7000461E +{0x0F12,0x8E17}, // 70004620 +{0x0F12,0x0000}, // 70004622 +{0x0F12,0x4778}, // 70004624 +{0x0F12,0x46C0}, // 70004626 +{0x0F12,0xC000}, // 70004628 +{0x0F12,0xE59F}, // 7000462A +{0x0F12,0xFF1C}, // 7000462C +{0x0F12,0xE12F}, // 7000462E +{0x0F12,0x98C5}, // 70004630 +{0x0F12,0x0000}, // 70004632 +{0x0F12,0x4778}, // 70004634 +{0x0F12,0x46C0}, // 70004636 +{0x0F12,0xC000}, // 70004638 +{0x0F12,0xE59F}, // 7000463A +{0x0F12,0xFF1C}, // 7000463C +{0x0F12,0xE12F}, // 7000463E +{0x0F12,0x7C7D}, // 70004640 +{0x0F12,0x0000}, // 70004642 +{0x0F12,0x4778}, // 70004644 +{0x0F12,0x46C0}, // 70004646 +{0x0F12,0xC000}, // 70004648 +{0x0F12,0xE59F}, // 7000464A +{0x0F12,0xFF1C}, // 7000464C +{0x0F12,0xE12F}, // 7000464E +{0x0F12,0x7E31}, // 70004650 +{0x0F12,0x0000}, // 70004652 +{0x0F12,0x4778}, // 70004654 +{0x0F12,0x46C0}, // 70004656 +{0x0F12,0xC000}, // 70004658 +{0x0F12,0xE59F}, // 7000465A +{0x0F12,0xFF1C}, // 7000465C +{0x0F12,0xE12F}, // 7000465E +{0x0F12,0x7EAB}, // 70004660 +{0x0F12,0x0000}, // 70004662 +{0x0F12,0x4778}, // 70004664 +{0x0F12,0x46C0}, // 70004666 +{0x0F12,0xC000}, // 70004668 +{0x0F12,0xE59F}, // 7000466A +{0x0F12,0xFF1C}, // 7000466C +{0x0F12,0xE12F}, // 7000466E +{0x0F12,0x7501}, // 70004670 +{0x0F12,0x0000}, // 70004672 +{0x0F12,0x4778}, // 70004674 +{0x0F12,0x46C0}, // 70004676 +{0x0F12,0xC000}, // 70004678 +{0x0F12,0xE59F}, // 7000467A +{0x0F12,0xFF1C}, // 7000467C +{0x0F12,0xE12F}, // 7000467E +{0x0F12,0xD19D}, // 70004680 +{0x0F12,0x0000}, // 70004682 +{0x0F12,0x4778}, // 70004684 +{0x0F12,0x46C0}, // 70004686 +{0x0F12,0xC000}, // 70004688 +{0x0F12,0xE59F}, // 7000468A +{0x0F12,0xFF1C}, // 7000468C +{0x0F12,0xE12F}, // 7000468E +{0x0F12,0xF63F}, // 70004690 +{0x0F12,0x0000}, // 70004692 +{0x0F12,0x4778}, // 70004694 +{0x0F12,0x46C0}, // 70004696 +{0x0F12,0xC000}, // 70004698 +{0x0F12,0xE59F}, // 7000469A +{0x0F12,0xFF1C}, // 7000469C +{0x0F12,0xE12F}, // 7000469E +{0x0F12,0x3D0B}, // 700046A0 +{0x0F12,0x0000}, // 700046A2 +{0x0F12,0x4778}, // 700046A4 +{0x0F12,0x46C0}, // 700046A6 +{0x0F12,0xC000}, // 700046A8 +{0x0F12,0xE59F}, // 700046AA +{0x0F12,0xFF1C}, // 700046AC +{0x0F12,0xE12F}, // 700046AE +{0x0F12,0x29BF}, // 700046B0 +{0x0F12,0x0001}, // 700046B2 +{0x0F12,0x4778}, // 700046B4 +{0x0F12,0x46C0}, // 700046B6 +{0x0F12,0xF004}, // 700046B8 +{0x0F12,0xE51F}, // 700046BA +{0x0F12,0x26D8}, // 700046BC +{0x0F12,0x0001}, // 700046BE +{0x0F12,0x4778}, // 700046C0 +{0x0F12,0x46C0}, // 700046C2 +{0x0F12,0xC000}, // 700046C4 +{0x0F12,0xE59F}, // 700046C6 +{0x0F12,0xFF1C}, // 700046C8 +{0x0F12,0xE12F}, // 700046CA +{0x0F12,0x6099}, // 700046CC +{0x0F12,0x0000}, // 700046CE +// End of Patch Data(Last : 700046CEh) +// Total Size 3032 (0x0BD8) +// Addr : 3AF8 , Size : 3030(BD6h) + +// TNP_USER_MBCV_CONTROL +// TNP_4EC_MBR_TUNE +// TNP_4EC_FORBIDDEN_TUNE +// TNP_AF_FINESEARCH_DRIVEBACK +// TNP_FLASH_ALG +// TNP_GAS_ALPHA_OTP +// TNP_AWB_MODUL_COMP +// TNP_AWB_INIT_QUEUE +// TNP_AWB_GRID_LOWBR +// TNP_AWB_GRID_MODULECOMP +// TNP_AFD_MOTO +// TNP_ADLC_TUNE +// TNP_1FRAME_AE +// TNP_TG_OFF_CFG_CHG_IN_SPOOF_MODE //================================================================================== -// 13.Flash Setting +// 05.OTP Control //================================================================================== +{0x002A,0x0722}, +{0x0F12,0x0100},///skl_OTP_usWaitTime This register should be positioned in fornt of D0001000 +{0x002A,0x0726}, +{0x0F12,0x0000},//skl_bUseOTPfunc This is OTP on/off function +{0x002A,0x08D6}, +{0x0F12,0x0000},//ash_bUseOTPData +{0x002A,0x146E}, +{0x0F12,0x0000} ,//awbb_otp_disable +{0x002A,0x08DC}, +{0x0F12,0x0000},//ash_bUseGasAlphaOTP + +//OTP on +//{0x002A,0x 0722 +//{0x0F12,0x 0100 ///skl_OTP_usWaitTime This register should be positioned in fornt of D0001000 +//{0x002A,0x 0726 +//{0x0F12,0x 0001 //skl_bUseOTPfunc This is OTP on/off function +//{0x002A,0x 08D6 +//{0x0F12,0x 0001 //ash_bUseOTPData +//{0x002A,0x 146E +//{0x0F12,0x 0000 //awbb_otp_disable +//{0x002A,0x 08DC +//{0x0F12,0x 0000 //ash_bUseGasAlphaOTP + +{0x0028,0xD000}, +{0x002A,0x1000}, +{0x0F12,0x0001}, //================================================================================== @@ -1834,1377 +1894,2122 @@ static struct regval_list sensor_default_regs[] = { {0x002A, 0x028C}, {0x0F12, 0x0003}, //REG_TC_AF_AfCmd + //================================================================================== -//04.Gas_Anti Shading_Otp +// 06.Gas_Anti Shading //================================================================================== -{0x002A, 0x08B4}, -{0x0F12, 0x0001}, //wbt_bUseOutdoorASH // Refer Mon_AWB_RotGain -{0x002A, 0x08BC}, -{0x0F12, 0x00C0}, //TVAR_ash_AwbAshCord_0_ 2300K -{0x0F12, 0x00DF}, //TVAR_ash_AwbAshCord_1_ 2750K -{0x0F12, 0x0100}, //TVAR_ash_AwbAshCord_2_ 3300K -{0x0F12, 0x0125}, //TVAR_ash_AwbAshCord_3_ 4150K -{0x0F12, 0x015F}, //TVAR_ash_AwbAshCord_4_ 5250K -{0x0F12, 0x017C}, //TVAR_ash_AwbAshCord_5_ 6400K -{0x0F12, 0x0194}, //TVAR_ash_AwbAshCord_6_ 7500K - -// GAS Alpha Table -{0x002A, 0x08F6}, -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_0__0_ R // 2300K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_0__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_0__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_0__3_ B -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_1__0_ R // 2750K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_1__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_1__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_1__3_ B -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_2__0_ R // 3300K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_2__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_2__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_2__3_ B -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_3__0_ R // 4150K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_3__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_3__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_3__3_ B -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_4__0_ R // 5250K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_4__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_4__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_4__3_ B -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_5__0_ R // 6400K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_5__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_5__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_5__3_ B -{0x0F12, 0x4500}, //TVAR_ash_GASAlpha_6__0_ R // 7500K -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_6__1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_6__2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASAlpha_6__3_ B - -// Outdoor GAS Alpha -{0x0F12, 0x4800}, //TVAR_ash_GASOutdoorAlpha_0_ R -{0x0F12, 0x4200}, //TVAR_ash_GASOutdoorAlpha_1_ GR -{0x0F12, 0x4000}, //TVAR_ash_GASOutdoorAlpha_2_ GB -{0x0F12, 0x4000}, //TVAR_ash_GASOutdoorAlpha_3_ B - -{0x002A, 0x08F4}, -{0x0F12, 0x0001}, //ash_bUseGasAlpha +{0x0028,0x7000}, +{0x002A,0x08B4}, +{0x0F12,0x0001}, // wbt_bUseOutdoorASH +{0x002A,0x08BC}, +{0x0F12,0x00C0}, // TVAR_ash_AwbAshCord_0_ 2300K +{0x0F12,0x00DF}, // TVAR_ash_AwbAshCord_1_ 2750K +{0x0F12,0x0100}, // TVAR_ash_AwbAshCord_2_ 3300K +{0x0F12,0x0125}, // TVAR_ash_AwbAshCord_3_ 4150K +{0x0F12,0x015F}, // TVAR_ash_AwbAshCord_4_ 5250K +{0x0F12,0x017C}, // TVAR_ash_AwbAshCord_5_ 6400K +{0x0F12,0x0194}, // TVAR_ash_AwbAshCord_6_ 7500K +{0x002A,0x08F6}, +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_0__0_ R} // 2300K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_0__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_0__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_0__3_ B +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_1__0_ R} // 2750K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_1__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_1__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_1__3_ B +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_2__0_ R} // 3300K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_2__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_2__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_2__3_ B +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_3__0_ R} // 4150K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_3__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_3__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_3__3_ B +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_4__0_ R} // 5250K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_4__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_4__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_4__3_ B +{0x0F12,0x4300}, // TVAR_ash_GASAlpha_5__0_ R} // 6400K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_5__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_5__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_5__3_ B +{0x0F12,0x4300}, // TVAR_ash_GASAlpha_6__0_ R} // 7500K +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_6__1_ GR +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_6__2_ GB +{0x0F12,0x4000}, // TVAR_ash_GASAlpha_6__3_ B +//Outdoor GAS Alpha +{0x0F12,0x4500}, +{0x0F12,0x4000}, +{0x0F12,0x4000}, +{0x0F12,0x4000}, +{0x002A,0x08F4}, +{0x0F12,0x0001}, // ash_bUseGasAlpha +// GAS High table If OTP is used, GAS Setting Should be deleted.} // +//BENI 1.1 module 101018// +{0x002A,0x0D26}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x000F}, +{0x0F12,0x000F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x000F}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x000F}, +{0x0F12,0x000F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F0F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F00}, +{0x0F12,0x0000}, +{0x0F12,0x0F00}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +{0x0F12,0x000F}, +{0x0F12,0x000F}, +{0x0F12,0x0000}, +{0x0F12,0x000F}, +{0x0F12,0x0F0F}, +// TVAR_ash_pGAS_low +{0x002A,0x0DB6}, +{0x0F12,0x88A2}, +{0x0F12,0xEF5B}, +{0x0F12,0xF576}, +{0x0F12,0x2242}, +{0x0F12,0xEC90}, +{0x0F12,0xFCB2}, +{0x0F12,0xD726}, +{0x0F12,0xF77C}, +{0x0F12,0x1CCB}, +{0x0F12,0xDB4D}, +{0x0F12,0x0948}, +{0x0F12,0x13C2}, +{0x0F12,0x0A14}, +{0x0F12,0x017A}, +{0x0F12,0xE9B4}, +{0x0F12,0x190D}, +{0x0F12,0x16E5}, +{0x0F12,0xCAB2}, +{0x0F12,0x18CD}, +{0x0F12,0x0A84}, +{0x0F12,0x097E}, +{0x0F12,0xF076}, +{0x0F12,0xE849}, +{0x0F12,0x2CFC}, +{0x0F12,0xE460}, +{0x0F12,0xEE89}, +{0x0F12,0x0693}, +{0x0F12,0x06B4}, +{0x0F12,0xF16E}, +{0x0F12,0x12B6}, +{0x0F12,0x0F99}, +{0x0F12,0x0F3B}, +{0x0F12,0xE728}, +{0x0F12,0x19BB}, +{0x0F12,0x058E}, +{0x0F12,0xDA99}, +{0x0F12,0x952B}, +{0x0F12,0xE6F0}, +{0x0F12,0x0163}, +{0x0F12,0x1376}, +{0x0F12,0xFC0E}, +{0x0F12,0xF3A2}, +{0x0F12,0xCE5D}, +{0x0F12,0xFA86}, +{0x0F12,0x11D3}, +{0x0F12,0xEB02}, +{0x0F12,0xFE43}, +{0x0F12,0x17ED}, +{0x0F12,0x1320}, +{0x0F12,0x0156}, +{0x0F12,0xF4FF}, +{0x0F12,0x0ACA}, +{0x0F12,0x162B}, +{0x0F12,0xD2D8}, +{0x0F12,0x0F4F}, +{0x0F12,0x0178}, +{0x0F12,0x0AD1}, +{0x0F12,0xEDE5}, +{0x0F12,0xFBA5}, +{0x0F12,0x1A69}, +{0x0F12,0xF30F}, +{0x0F12,0xFC58}, +{0x0F12,0xF92D}, +{0x0F12,0x131C}, +{0x0F12,0xE607}, +{0x0F12,0x1564}, +{0x0F12,0x02A8}, +{0x0F12,0x08B5}, +{0x0F12,0xF04C}, +{0x0F12,0x15D0}, +{0x0F12,0xFAD0}, +{0x0F12,0xEB70}, +{0x0F12,0x8564}, +{0x0F12,0xE967}, +{0x0F12,0xFFFF}, +{0x0F12,0x16A8}, +{0x0F12,0xEFD6}, +{0x0F12,0x01AF}, +{0x0F12,0xD7AD}, +{0x0F12,0x01A2}, +{0x0F12,0x0A4E}, +{0x0F12,0xF1CE}, +{0x0F12,0xFA95}, +{0x0F12,0x143F}, +{0x0F12,0x1046}, +{0x0F12,0xF6A1}, +{0x0F12,0xF7BB}, +{0x0F12,0x0E8D}, +{0x0F12,0x11A3}, +{0x0F12,0xDB43}, +{0x0F12,0x1459}, +{0x0F12,0x0FFA}, +{0x0F12,0x0731}, +{0x0F12,0xEC67}, +{0x0F12,0xF7CA}, +{0x0F12,0x1682}, +{0x0F12,0xDF77}, +{0x0F12,0xEEA5}, +{0x0F12,0xFF71}, +{0x0F12,0x08FF}, +{0x0F12,0xF8FA}, +{0x0F12,0x138E}, +{0x0F12,0x16FE}, +{0x0F12,0x0BA0}, +{0x0F12,0xF297}, +{0x0F12,0x1717}, +{0x0F12,0xF5BB}, +{0x0F12,0xE6B7}, +{0x0F12,0x87A3}, +{0x0F12,0xECB4}, +{0x0F12,0xF8A1}, +{0x0F12,0x1D23}, +{0x0F12,0xF35F}, +{0x0F12,0xF7C7}, +{0x0F12,0xD9ED}, +{0x0F12,0xF792}, +{0x0F12,0x1E98}, +{0x0F12,0xD734}, +{0x0F12,0x0BA1}, +{0x0F12,0x14E3}, +{0x0F12,0x0BB9}, +{0x0F12,0x0279}, +{0x0F12,0xDEC5}, +{0x0F12,0x2EDC}, +{0x0F12,0x010A}, +{0x0F12,0xD36F}, +{0x0F12,0x1A6A}, +{0x0F12,0x03F6}, +{0x0F12,0x1AE5}, +{0x0F12,0xD3FB}, +{0x0F12,0xFFFA}, +{0x0F12,0x26A0}, +{0x0F12,0xDF98}, +{0x0F12,0xF8DC}, +{0x0F12,0xF675}, +{0x0F12,0x168E}, +{0x0F12,0xEFC9}, +{0x0F12,0x0A42}, +{0x0F12,0x11D3}, +{0x0F12,0x08BE}, +{0x0F12,0xEF30}, +{0x0F12,0x1785}, +{0x0F12,0xFBF7}, +{0x0F12,0xE573}, //================================================================================== -// 09.Auto Flicker Detection +// 07. Analog Setting 2 //================================================================================== - -{0x002A, 0x0F30}, -{0x0F12, 0x0001}, //AFC_D_ConvAccelerPower - -// Auto Flicker (60Mhz start) -{0x002A, 0x0F2A}, -{0x0F12, 0x0000}, //AFC_Default BIT[0] 1:60Hz 0:50Hz -{0x002A, 0x04E6}, -{0x0F12, 0x077F}, //REG_TC_DBG 7F: 60Hz 5F:50Hz - +//This register is for FACTORY ONLY. +//If you change it without prior notification +//YOU are RESPONSIBLE for the FAILURE that will happen in the future +//For subsampling Size +{0x002A,0x18BC}, +{0x0F12,0x0004}, +{0x0F12,0x05B6}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0001}, +{0x0F12,0x05BA}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0007}, +{0x0F12,0x05BA}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F4}, +{0x0F12,0x024E}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F4}, +{0x0F12,0x05B6}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F4}, +{0x0F12,0x05BA}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F4}, +{0x0F12,0x024F}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0075}, +{0x0F12,0x00CF}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0075}, +{0x0F12,0x00D6}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0004}, +{0x0F12,0x01F4}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x00F0}, +{0x0F12,0x01F4}, +{0x0F12,0x029E}, +{0x0F12,0x05B2}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F8}, +{0x0F12,0x0228}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0208}, +{0x0F12,0x0238}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0218}, +{0x0F12,0x0238}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0001}, +{0x0F12,0x0009}, +{0x0F12,0x00DE}, +{0x0F12,0x05C0}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x00DF}, +{0x0F12,0x00E4}, +{0x0F12,0x01F8}, +{0x0F12,0x01FD}, +{0x0F12,0x05B6}, +{0x0F12,0x05BB}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x01F8}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0077}, +{0x0F12,0x007E}, +{0x0F12,0x024F}, +{0x0F12,0x025E}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +// For Capture +{0x0F12,0x0004}, +{0x0F12,0x09D1}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0001}, +{0x0F12,0x09D5}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0008}, +{0x0F12,0x09D5}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AA}, +{0x0F12,0x0326}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AA}, +{0x0F12,0x09D1}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AA}, +{0x0F12,0x09D5}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AA}, +{0x0F12,0x0327}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0008}, +{0x0F12,0x0084}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0008}, +{0x0F12,0x008D}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0008}, +{0x0F12,0x02AA}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x00AA}, +{0x0F12,0x02AA}, +{0x0F12,0x03AD}, +{0x0F12,0x09CD}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AE}, +{0x0F12,0x02DE}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02BE}, +{0x0F12,0x02EE}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02CE}, +{0x0F12,0x02EE}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0001}, +{0x0F12,0x0009}, +{0x0F12,0x0095}, +{0x0F12,0x09DB}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0096}, +{0x0F12,0x009B}, +{0x0F12,0x02AE}, +{0x0F12,0x02B3}, +{0x0F12,0x09D1}, +{0x0F12,0x09D6}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x02AE}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0009}, +{0x0F12,0x0010}, +{0x0F12,0x0327}, +{0x0F12,0x0336}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x002A,0x1AF8}, +{0x0F12,0x5A3C}, // senHal_TuneStr_AngTuneData1_2_D000F400 register at subsampling +{0x002A,0x1896}, +{0x0F12,0x0002}, // senHal_SamplingType 0002 03EE: PLA setting +{0x0F12,0x0000}, // senHal_SamplingMode 0 : 2 PLA / 1 : 4PLA +{0x0F12,0x0001}, // senHal_PLAOption [0] VPLA enable [1] HPLA enable +{0x002A,0x1B00}, +{0x0F12,0xF428}, +{0x0F12,0xFFFF}, +{0x0F12,0x0000}, +{0x002A,0x189E}, +{0x0F12,0x0FB0}, // senHal_ExpMinPixels +{0x002A,0x18AC}, +{0x0F12,0x0060}, // senHal_uAddColsBin +{0x0F12,0x0060}, // senHal_uAddColsNoBin +{0x0F12,0x07DC}, // senHal_uMinColsBin +{0x0F12,0x05C0}, // senHal_uMinColsNoBin +{0x002A,0x1AEA}, +{0x0F12,0x8080}, // senHal_SubF404Tune +{0x0F12,0x0080}, // senHal_FullF404Tune +{0x002A,0x1AE0}, +{0x0F12,0x0000}, // senHal_bSenAAC +{0x002A,0x1A72}, +{0x0F12,0x0000}, // senHal_bSRX SRX off +{0x002A,0x18A2}, +{0x0F12,0x0004}, // senHal_NExpLinesCheckFine extend Forbidden area line +{0x002A,0x1A6A}, +{0x0F12,0x009A}, // senHal_usForbiddenRightOfs extend right Forbidden area line +{0x002A,0x385E}, +{0x0F12,0x024C}, // Mon_Sen_uExpPixelsOfs +{0x002A,0x0EE6}, +{0x0F12,0x0000}, // setot_bUseDigitalHbin +{0x002A,0x1B2A}, +{0x0F12,0x0300}, // 70001B2A //senHal_TuneStr2_usAngTuneGainTh +{0x0F12,0x00D6}, // 70001B2C //senHal_TuneStr2_AngTuneF4CA_0_ +{0x0F12,0x008D}, // 70001B2E //senHal_TuneStr2_AngTuneF4CA_1_ +{0x0F12,0x00CF}, // 70001B30 //senHal_TuneStr2_AngTuneF4C2_0_ +{0x0F12,0x0084}, // 70001B32 //senHal_TuneStr2_AngTuneF4C2_1_ //================================================================================== -// 10.AE Setting +// 08.AF Setting //================================================================================== -//AE Target -{0x002A, 0x1484}, -{0x0F12, 0x003C}, //TVAR_ae_BrAve +//AF interface setting +{0x002A,0x01FC}, +{0x0F12,0x0001}, // REG_TC_IPRM_LedGpio, for Flash control +//s002A1720 +//s0F120100 // afd_usFlags, Low voltage AF enable +{0x0F12,0x0003}, // REG_TC_IPRM_CM_Init_AfModeType, VCM IIC +{0x0F12,0x0000}, // REG_TC_IPRM_CM_Init_PwmConfig1 +{0x002A,0x0204}, +{0x0F12,0x0061}, // REG_TC_IPRM_CM_Init_GpioConfig1, AF Enable GPIO 6 +{0x002A,0x020C}, +{0x0F12,0x2F0C}, // REG_TC_IPRM_CM_Init_Mi2cBit +{0x0F12,0x0190}, // REG_TC_IPRM_CM_Init_Mi2cRateKhz, IIC Speed + + +//AF Window Settings +{0x002A,0x0294}, +{0x0F12,0x0100}, // REG_TC_AF_FstWinStartX +{0x0F12,0x00E3}, // REG_TC_AF_FstWinStartY +{0x0F12,0x0200}, // REG_TC_AF_FstWinSizeX +{0x0F12,0x0238}, // REG_TC_AF_FstWinSizeY +{0x0F12,0x018C}, // REG_TC_AF_ScndWinStartX +{0x0F12,0x0166}, // REG_TC_AF_ScndWinStartY +{0x0F12,0x00E6}, // REG_TC_AF_ScndWinSizeX +{0x0F12,0x0132}, // REG_TC_AF_ScndWinSizeY +{0x0F12,0x0001}, // REG_TC_AF_WinSizesUpdated + + +//2nd search setting +{0x002A,0x070E}, +{0x0F12,0x00C0}, // skl_af_StatOvlpExpFactor +{0x002A,0x071E}, +{0x0F12,0x0000}, // skl_af_bAfStatOff +{0x002A,0x163C}, +{0x0F12,0x0000}, // af_search_usAeStable +{0x002A,0x1648}, +{0x0F12,0x9002}, // af_search_usSingleAfFlags +{0x002A,0x1652}, +{0x0F12,0x0002}, // af_search_usFinePeakCount +{0x0F12,0x0000}, // af_search_usFineMaxScale +{0x002A,0x15E0}, +{0x0F12,0x0403}, // af_pos_usFineStepNumSize +{0x002A,0x1656}, +{0x0F12,0x0000}, // af_search_usCapturePolicy + + +//Peak Threshold +{0x002A,0x164C}, +{0x0F12,0x0003}, // af_search_usMinPeakSamples +{0x002A,0x163E}, +{0x0F12,0x00C0}, // af_search_usPeakThr +{0x0F12,0x0080}, // af_search_usPeakThrLow +{0x002A,0x47A8}, +{0x0F12,0x0080}, // TNP, Macro Threshold register + + +//Home Pos +{0x002A,0x15D4}, +{0x0F12,0x0000}, // af_pos_usHomePos +{0x0F12,0xD000}, // af_pos_usLowConfPos + + +//AF statistics +{0x002A,0x169A}, +{0x0F12,0xFF95}, // af_search_usConfCheckOrder_1_ +{0x002A,0x166A}, +{0x0F12,0x0280}, // af_search_usConfThr_4_ +{0x002A,0x1676}, +{0x0F12,0x03A0}, // af_search_usConfThr_10_ +{0x0F12,0x0320}, // af_search_usConfThr_11_ +{0x002A,0x16BC}, +{0x0F12,0x0030}, // af_stat_usMinStatVal +{0x002A,0x16E0}, +{0x0F12,0x0060}, // af_scene_usSceneLowNormBrThr +{0x002A,0x16D4}, +{0x0F12,0x0010}, // af_stat_usBpfThresh + + +//AF Lens Position Table Settings +{0x002A,0x15E8}, +{0x0F12,0x0010}, // af_pos_usTableLastInd +{0x0F12,0x0018}, // af_pos_usTable +{0x0F12,0x0020}, // af_pos_usTable +{0x0F12,0x0028}, // af_pos_usTable +{0x0F12,0x0030}, // af_pos_usTable +{0x0F12,0x0038}, // af_pos_usTable +{0x0F12,0x0040}, // af_pos_usTable +{0x0F12,0x0048}, // af_pos_usTable +{0x0F12,0x0050}, // af_pos_usTable +{0x0F12,0x0058}, // af_pos_usTable +{0x0F12,0x0060}, // af_pos_usTable +{0x0F12,0x0068}, // af_pos_usTable +{0x0F12,0x0070}, // af_pos_usTable +{0x0F12,0x0080}, // af_pos_usTable +{0x0F12,0x0090}, // af_pos_usTable +{0x0F12,0x00A0}, // af_pos_usTable +{0x0F12,0x00B0}, // af_pos_usTable +{0x0F12,0x00C0}, // af_pos_usTable + +//VCM AF driver with PWM/I2C +{0x002A,0x1722}, +{0x0F12,0x8000}, // afd_usParam[0] I2C power down command +{0x0F12,0x0006}, // afd_usParam[1] Position Right Shift +{0x0F12,0x3FF0}, // afd_usParam[2] I2C Data Mask +{0x0F12,0x03E8}, // afd_usParam[3] PWM Period +{0x0F12,0x0000}, // afd_usParam[4] PWM Divider +{0x0F12,0x0020}, // afd_usParam[5] SlowMotion Delay 4. reduce lens collision noise. +{0x0F12,0x0010}, // afd_usParam[6] SlowMotion Threshold +{0x0F12,0x0008}, // afd_usParam[7] Signal Shaping +{0x0F12,0x0040}, // afd_usParam[8] Signal Shaping level +{0x0F12,0x0080}, // afd_usParam[9] Signal Shaping level +{0x0F12,0x00C0}, // afd_usParam[10] Signal Shaping level +{0x0F12,0x00E0}, // afd_usParam[11] Signal Shaping level +{0x002A,0x028C}, +{0x0F12,0x0003}, // REG_TC_AF_AfCmd -//ae_StatMode bit[3] BLC has to be bypassed to prevent AE weight change especially backlight scene -{0x002A, 0x148A}, -{0x0F12, 0x000F}, //ae_StatMode - -{0x002A, 0x0588}, -{0x0F12, 0x0000}, //lt_uInitPostToleranceCnt - -//AE_state -{0x002A, 0x0544}, -{0x0F12, 0x0111}, //lt_uLimitHigh -{0x0F12, 0x00EF}, //lt_uLimitLow - -//AE Concept -{0x002A, 0x0608}, -{0x0F12, 0x0001}, //lt_ExpGain_uSubsamplingmode -{0x0F12, 0x0001}, //lt_ExpGain_uNonSubsampling -{0x0F12, 0x0800}, //lt_ExpGain_ExpCurveGainMaxStr -{0x0F12, 0x0100}, //lt_ExpGain_ExpCurveGainMaxStr_0__uMaxDigGain - -//Exposure -{0x002A, 0x0610}, //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpIn_0 -{0x0F12, 0x0001}, -{0x0F12, 0x0000}, -{0x0F12, 0x0A3C}, -{0x0F12, 0x0000}, -{0x0F12, 0x0D04}, -{0x0F12, 0x0000}, -{0x0F12, 0x4008}, -{0x0F12, 0x0000}, -{0x0F12, 0x7000}, -{0x0F12, 0x0000}, -{0x0F12, 0x9C00}, -{0x0F12, 0x0000}, -{0x0F12, 0xAD00}, -{0x0F12, 0x0001}, -{0x0F12, 0xF1D4}, -{0x0F12, 0x0002}, -{0x0F12, 0xDC00}, -{0x0F12, 0x0005}, -{0x0F12, 0xDC00}, -{0x0F12, 0x0005}, - -{0x002A, 0x0638}, //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ -{0x0F12, 0x0001}, -{0x0F12, 0x0000}, -{0x0F12, 0x0A3C}, -{0x0F12, 0x0000}, -{0x0F12, 0x0D05}, -{0x0F12, 0x0000}, -{0x0F12, 0x3408}, -{0x0F12, 0x0000}, -{0x0F12, 0x3408}, -{0x0F12, 0x0000}, -{0x0F12, 0x6810}, -{0x0F12, 0x0000}, -{0x0F12, 0x8214}, -{0x0F12, 0x0000}, -{0x0F12, 0xC350}, -{0x0F12, 0x0000}, -{0x0F12, 0xC350}, -{0x0F12, 0x0000}, -{0x0F12, 0xC350}, -{0x0F12, 0x0000}, - -//Gain -{0x002A, 0x05A2}, -{0x0F12, 0x1000}, //lt_uMaxTotGain - -// Lei Control -{0x002A, 0x06B8}, -{0x0F12, 0x452C}, -{0x0F12, 0x0005}, //lt_uMaxLei //================================================================================== -// 11.AE Weight (Normal) +// 09.AWB-BASIC setting //================================================================================== -{0x002A, 0x1492}, -{0x0F12, 0x0100}, //ae_WeightTbl_16_0_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_1_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_2_ -{0x0F12, 0x0001}, //ae_WeightTbl_16_3_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_4_ -{0x0F12, 0x0201}, //ae_WeightTbl_16_5_ -{0x0F12, 0x0102}, //ae_WeightTbl_16_6_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_7_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_8_ -{0x0F12, 0x0202}, //ae_WeightTbl_16_9_ -{0x0F12, 0x0202}, //ae_WeightTbl_16_10_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_11_ -{0x0F12, 0x0201}, //ae_WeightTbl_16_12_ -{0x0F12, 0x0302}, //ae_WeightTbl_16_13_ -{0x0F12, 0x0203}, //ae_WeightTbl_16_14_ -{0x0F12, 0x0102}, //ae_WeightTbl_16_15_ -{0x0F12, 0x0201}, //ae_WeightTbl_16_16_ -{0x0F12, 0x0302}, //ae_WeightTbl_16_17_ -{0x0F12, 0x0203}, //ae_WeightTbl_16_18_ -{0x0F12, 0x0102}, //ae_WeightTbl_16_19_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_20_ -{0x0F12, 0x0202}, //ae_WeightTbl_16_21_ -{0x0F12, 0x0202}, //ae_WeightTbl_16_22_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_23_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_24_ -{0x0F12, 0x0201}, //ae_WeightTbl_16_25_ -{0x0F12, 0x0102}, //ae_WeightTbl_16_26_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_27_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_28_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_29_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_30_ -{0x0F12, 0x0101}, //ae_WeightTbl_16_31_ - //================================================================================== -// 14.AWB-BASIC setting +// 09.AWB-BASIC setting //================================================================================== -// AWB init Start point -{0x002A, 0x145E}, -{0x0F12, 0x0580}, //awbb_GainsInit_0_ -{0x0F12, 0x0428}, //awbb_GainsInit_1_ -{0x0F12, 0x0780}, //awbb_GainsInit_2_ - -// AWB Convergence Speed -{0x002A, 0x1464}, -{0x0F12, 0x0008}, //awbb_WpFilterMinThr -{0x0F12, 0x0190}, //awbb_WpFilterMaxThr -{0x0F12, 0x00A0}, //awbb_WpFilterCoef -{0x0F12, 0x0004}, //awbb_WpFilterSize -{0x0F12, 0x0002}, //awbb_GridEnable - -{0x002A, 0x144E}, -{0x0F12, 0x0000}, //awbb_RGainOff -{0x0F12, 0x0000}, //awbb_BGainOff -{0x0F12, 0x0000}, //awbb_GGainOff -{0x0f12, 0x00C2}, //awbb_Alpha_Comp_Mode -{0x0F12, 0x0002}, //awbb_Rpl_InvalidOutDoor -{0x0F12, 0x0001}, //awbb_UseGrThrCorr -{0x0F12, 0x0074}, //awbb_Use_Filters -{0x0F12, 0x0001}, //awbb_CorrectMinNumPatches +// AWB Init +{0x002A,0x145E}, +{0x0F12,0x0523}, //awbb_GainsInit_0_ +{0x0F12,0x0400}, //awbb_GainsInit_1_ +{0x0F12,0x07D0}, //awbb_GainsInit_2_ // White Locus -{0x002A, 0x11F0}, -{0x0F12, 0x012C}, //awbb_IntcR -{0x0F12, 0x0121}, //awbb_IntcB -{0x0F12, 0x02DF}, //awbb_GLocusR -{0x0F12, 0x0314}, //awbb_GLocusB - -{0x002A, 0x120E}, -{0x0F12, 0x0000}, //awbb_MovingScale10 -{0x0F12, 0x05FD}, //awbb_GamutWidthThr1 -{0x0F12, 0x036B}, //awbb_GamutHeightThr1 -{0x0F12, 0x0020}, //awbb_GamutWidthThr2 -{0x0F12, 0x001A}, //awbb_GamutHeightThr2 - -{0x002A, 0x1278}, -{0x0F12, 0xFEF7}, //awbb_SCDetectionMap_SEC_StartR_B -{0x0F12, 0x0021}, //awbb_SCDetectionMap_SEC_StepR_B -{0x0F12, 0x07D0}, //awbb_SCDetectionMap_SEC_SunnyNB -{0x0F12, 0x07D0}, //awbb_SCDetectionMap_SEC_StepNB -{0x0F12, 0x01C8}, //awbb_SCDetectionMap_SEC_LowTempR_B -{0x0F12, 0x0096}, //awbb_SCDetectionMap_SEC_SunnyNBZone -{0x0F12, 0x0004}, //awbb_SCDetectionMap_SEC_LowTempR_BZone - -{0x002A, 0x1224}, -{0x0F12, 0x0032}, //awbb_LowBr -{0x0F12, 0x001E}, //awbb_LowBr_NBzone -{0x0F12, 0x00E2}, //awbb_YThreshHigh -{0x0F12, 0x0010}, //awbb_YThreshLow_Norm -{0x0F12, 0x0002}, //awbb_YThreshLow_Low -{0x002A, 0x2BA4}, -{0x0F12, 0x0002}, //Mon_AWB_ByPassMode - -{0x002A, 0x11FC}, -{0x0F12, 0x000C}, //awbb_MinNumOfFinalPatches - -{0x002A, 0x1208}, -{0x0F12, 0x0020}, //awbb_MinNumOfChromaclassifpatches - -// Indoor Zone -{0x002A, 0x101C}, -{0x0F12, 0x0360}, //awbb_IndoorGrZones_m_BGrid_0__m_left -{0x0F12, 0x036C}, //awbb_IndoorGrZones_m_BGrid_0__m_right -{0x0F12, 0x0320}, //awbb_IndoorGrZones_m_BGrid_1__m_left -{0x0F12, 0x038A}, //awbb_IndoorGrZones_m_BGrid_1__m_right -{0x0F12, 0x02E8}, //awbb_IndoorGrZones_m_BGrid_2__m_left -{0x0F12, 0x0380}, //awbb_IndoorGrZones_m_BGrid_2__m_right -{0x0F12, 0x02BE}, //awbb_IndoorGrZones_m_BGrid_3__m_left -{0x0F12, 0x035A}, //awbb_IndoorGrZones_m_BGrid_3__m_right -{0x0F12, 0x0298}, //awbb_IndoorGrZones_m_BGrid_4__m_left -{0x0F12, 0x0334}, //awbb_IndoorGrZones_m_BGrid_4__m_right -{0x0F12, 0x0272}, //awbb_IndoorGrZones_m_BGrid_5__m_left -{0x0F12, 0x030E}, //awbb_IndoorGrZones_m_BGrid_5__m_right -{0x0F12, 0x024C}, //awbb_IndoorGrZones_m_BGrid_6__m_left -{0x0F12, 0x02EA}, //awbb_IndoorGrZones_m_BGrid_6__m_right -{0x0F12, 0x0230}, //awbb_IndoorGrZones_m_BGrid_7__m_left -{0x0F12, 0x02CC}, //awbb_IndoorGrZones_m_BGrid_7__m_right -{0x0F12, 0x0214}, //awbb_IndoorGrZones_m_BGrid_8__m_left -{0x0F12, 0x02B0}, //awbb_IndoorGrZones_m_BGrid_8__m_right -{0x0F12, 0x01F8}, //awbb_IndoorGrZones_m_BGrid_9__m_left -{0x0F12, 0x0294}, //awbb_IndoorGrZones_m_BGrid_9__m_right -{0x0F12, 0x01DC}, //awbb_IndoorGrZones_m_BGrid_10__m_left -{0x0F12, 0x0278}, //awbb_IndoorGrZones_m_BGrid_10__m_right -{0x0F12, 0x01C0}, //awbb_IndoorGrZones_m_BGrid_11__m_left -{0x0F12, 0x0264}, //awbb_IndoorGrZones_m_BGrid_11__m_right -{0x0F12, 0x01AA}, //awbb_IndoorGrZones_m_BGrid_12__m_left -{0x0F12, 0x0250}, //awbb_IndoorGrZones_m_BGrid_12__m_right -{0x0F12, 0x0196}, //awbb_IndoorGrZones_m_BGrid_13__m_left -{0x0F12, 0x023C}, //awbb_IndoorGrZones_m_BGrid_13__m_right -{0x0F12, 0x0180}, //awbb_IndoorGrZones_m_BGrid_14__m_left -{0x0F12, 0x0228}, //awbb_IndoorGrZones_m_BGrid_14__m_right -{0x0F12, 0x016C}, //awbb_IndoorGrZones_m_BGrid_15__m_left -{0x0F12, 0x0214}, //awbb_IndoorGrZones_m_BGrid_15__m_right -{0x0F12, 0x0168}, //awbb_IndoorGrZones_m_BGrid_16__m_left -{0x0F12, 0x0200}, //awbb_IndoorGrZones_m_BGrid_16__m_right -{0x0F12, 0x0172}, //awbb_IndoorGrZones_m_BGrid_17__m_left -{0x0F12, 0x01EC}, //awbb_IndoorGrZones_m_BGrid_17__m_right -{0x0F12, 0x019A}, //awbb_IndoorGrZones_m_BGrid_18__m_left -{0x0F12, 0x01D8}, //awbb_IndoorGrZones_m_BGrid_18__m_right -{0x0F12, 0x0000}, //awbb_IndoorGrZones_m_BGrid_19__m_left -{0x0F12, 0x0000}, //awbb_IndoorGrZones_m_BGrid_19__m_right - -{0x0F12, 0x0005}, //awbb_IndoorGrZones_m_GridStep -{0x002A, 0x1070}, -{0x0F12, 0x0013}, //awbb_IndoorGrZones_ZInfo_m_GridSz -{0x002A, 0x1074}, -{0x0F12, 0x00EC}, //awbb_IndoorGrZones_m_Boffs +{0x002A,0x11F0}, +{0x0F12,0x0125}, //#awbb_IntcR +{0x0F12,0x0130}, //#awbb_IntcB + +// IndoorZone +{0x002A,0x101C}, +{0x0F12,0x03A0}, //#awbb_IndoorGrZones_m_BGrid_0__m_left +{0x0F12,0x03B6}, //#awbb_IndoorGrZones_m_BGrid_0__m_right +{0x0F12,0x02DC}, //#awbb_IndoorGrZones_m_BGrid_1__m_left +{0x0F12,0x037C}, //#awbb_IndoorGrZones_m_BGrid_1__m_right +{0x0F12,0x02A8}, //#awbb_IndoorGrZones_m_BGrid_2__m_left +{0x0F12,0x034C}, //#awbb_IndoorGrZones_m_BGrid_2__m_right +{0x0F12,0x0286}, //#awbb_IndoorGrZones_m_BGrid_3__m_left +{0x0F12,0x031E}, //#awbb_IndoorGrZones_m_BGrid_3__m_right +{0x0F12,0x0266}, //#awbb_IndoorGrZones_m_BGrid_4__m_left +{0x0F12,0x02FA}, //#awbb_IndoorGrZones_m_BGrid_4__m_right +{0x0F12,0x0246}, //#awbb_IndoorGrZones_m_BGrid_5__m_left +{0x0F12,0x02DA}, //#awbb_IndoorGrZones_m_BGrid_5__m_right +{0x0F12,0x0230}, //#awbb_IndoorGrZones_m_BGrid_6__m_left +{0x0F12,0x02B8}, //#awbb_IndoorGrZones_m_BGrid_6__m_right +{0x0F12,0x021A}, //#awbb_IndoorGrZones_m_BGrid_7__m_left +{0x0F12,0x0298}, //#awbb_IndoorGrZones_m_BGrid_7__m_right +{0x0F12,0x0200}, //#awbb_IndoorGrZones_m_BGrid_8__m_left +{0x0F12,0x0284}, //#awbb_IndoorGrZones_m_BGrid_8__m_right +{0x0F12,0x01F0}, //#awbb_IndoorGrZones_m_BGrid_9__m_left +{0x0F12,0x0278}, //#awbb_IndoorGrZones_m_BGrid_9__m_right +{0x0F12,0x01E0}, //#awbb_IndoorGrZones_m_BGrid_10__m_left +{0x0F12,0x026C}, //#awbb_IndoorGrZones_m_BGrid_10__m_right +{0x0F12,0x01D0}, //#awbb_IndoorGrZones_m_BGrid_11__m_left +{0x0F12,0x025E}, //#awbb_IndoorGrZones_m_BGrid_11__m_right +{0x0F12,0x01C4}, //#awbb_IndoorGrZones_m_BGrid_12__m_left +{0x0F12,0x0252}, //#awbb_IndoorGrZones_m_BGrid_12__m_right +{0x0F12,0x01B6}, //#awbb_IndoorGrZones_m_BGrid_13__m_left +{0x0F12,0x0244}, //#awbb_IndoorGrZones_m_BGrid_13__m_right +{0x0F12,0x01D2}, //#awbb_IndoorGrZones_m_BGrid_14__m_left +{0x0F12,0x0216}, //#awbb_IndoorGrZones_m_BGrid_14__m_right +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_15__m_left +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_15__m_right +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_16__m_left +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_16__m_right +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_17__m_left +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_17__m_right +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_18__m_left +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_18__m_right +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_19__m_left +{0x0F12,0x0000}, //#awbb_IndoorGrZones_m_BGrid_19__m_right + +{0x0F12,0x0005}, //#awbb_IndoorGrZones_m_GridStep +{0x002A,0x1070}, +{0x0F12,0x000F}, //#awbb_IndoorGrZones_ZInfo_m_GridSz +{0x002A,0x1074}, +{0x0F12,0x013C}, //#awbb_IndoorGrZones_m_Boffs // Outdoor Zone -{0x002A, 0x1078}, -{0x0F12, 0x0232}, //awbb_OutdoorGrZones_m_BGrid_0__m_left -{0x0F12, 0x025A}, //awbb_OutdoorGrZones_m_BGrid_0__m_right -{0x0F12, 0x021E}, //awbb_OutdoorGrZones_m_BGrid_1__m_left -{0x0F12, 0x0274}, //awbb_OutdoorGrZones_m_BGrid_1__m_right -{0x0F12, 0x020E}, //awbb_OutdoorGrZones_m_BGrid_2__m_left -{0x0F12, 0x028E}, //awbb_OutdoorGrZones_m_BGrid_2__m_right -{0x0F12, 0x0200}, //awbb_OutdoorGrZones_m_BGrid_3__m_left -{0x0F12, 0x0290}, //awbb_OutdoorGrZones_m_BGrid_3__m_right -{0x0F12, 0x01F4}, //awbb_OutdoorGrZones_m_BGrid_4__m_left -{0x0F12, 0x0286}, //awbb_OutdoorGrZones_m_BGrid_4__m_right -{0x0F12, 0x01E8}, //awbb_OutdoorGrZones_m_BGrid_5__m_left -{0x0F12, 0x027E}, //awbb_OutdoorGrZones_m_BGrid_5__m_right -{0x0F12, 0x01DE}, //awbb_OutdoorGrZones_m_BGrid_6__m_left -{0x0F12, 0x0274}, //awbb_OutdoorGrZones_m_BGrid_6__m_right -{0x0F12, 0x01D2}, //awbb_OutdoorGrZones_m_BGrid_7__m_left -{0x0F12, 0x0268}, //awbb_OutdoorGrZones_m_BGrid_7__m_right -{0x0F12, 0x01D0}, //awbb_OutdoorGrZones_m_BGrid_8__m_left -{0x0F12, 0x025E}, //awbb_OutdoorGrZones_m_BGrid_8__m_right -{0x0F12, 0x01D6}, //awbb_OutdoorGrZones_m_BGrid_9__m_left -{0x0F12, 0x0252}, //awbb_OutdoorGrZones_m_BGrid_9__m_right -{0x0F12, 0x01E2}, //awbb_OutdoorGrZones_m_BGrid_10__m_left -{0x0F12, 0x0248}, //awbb_OutdoorGrZones_m_BGrid_10__m_right -{0x0F12, 0x01F4}, //awbb_OutdoorGrZones_m_BGrid_11__m_left -{0x0F12, 0x021A}, //awbb_OutdoorGrZones_m_BGrid_11__m_right - -{0x0F12, 0x0004}, //awbb_OutdoorGrZones_m_GridStep -{0x002A, 0x10AC}, -{0x0F12, 0x000C}, //awbb_OutdoorGrZones_ZInfo_m_GridSz -{0x002A, 0x10B0}, -{0x0F12, 0x01DA}, //awbb_OutdoorGrZones_m_Boffs - -// Low Brightness Zone -{0x002A, 0x10B4}, -{0x0F12, 0x0348}, //awbb_LowBrGrZones_m_BGrid_0__m_left -{0x0F12, 0x03B6}, //awbb_LowBrGrZones_m_BGrid_0__m_right -{0x0F12, 0x02B8}, //awbb_LowBrGrZones_m_BGrid_1__m_left -{0x0F12, 0x03B6}, //awbb_LowBrGrZones_m_BGrid_1__m_right -{0x0F12, 0x0258}, //awbb_LowBrGrZones_m_BGrid_2__m_left -{0x0F12, 0x038E}, //awbb_LowBrGrZones_m_BGrid_2__m_right -{0x0F12, 0x0212}, //awbb_LowBrGrZones_m_BGrid_3__m_left -{0x0F12, 0x0348}, //awbb_LowBrGrZones_m_BGrid_3__m_right -{0x0F12, 0x01CC}, //awbb_LowBrGrZones_m_BGrid_4__m_left -{0x0F12, 0x030C}, //awbb_LowBrGrZones_m_BGrid_4__m_right -{0x0F12, 0x01A2}, //awbb_LowBrGrZones_m_BGrid_5__m_left -{0x0F12, 0x02D2}, //awbb_LowBrGrZones_m_BGrid_5__m_right -{0x0F12, 0x0170}, //awbb_LowBrGrZones_m_BGrid_6__m_left -{0x0F12, 0x02A6}, //awbb_LowBrGrZones_m_BGrid_6__m_right -{0x0F12, 0x014C}, //awbb_LowBrGrZones_m_BGrid_7__m_left -{0x0F12, 0x0280}, //awbb_LowBrGrZones_m_BGrid_7__m_right -{0x0F12, 0x0128}, //awbb_LowBrGrZones_m_BGrid_8__m_left -{0x0F12, 0x025C}, //awbb_LowBrGrZones_m_BGrid_8__m_right -{0x0F12, 0x0146}, //awbb_LowBrGrZones_m_BGrid_9__m_left -{0x0F12, 0x0236}, //awbb_LowBrGrZones_m_BGrid_9__m_right -{0x0F12, 0x0164}, //awbb_LowBrGrZones_m_BGrid_10__m_left -{0x0F12, 0x0212}, //awbb_LowBrGrZones_m_BGrid_10__m_right -{0x0F12, 0x0000}, //awbb_LowBrGrZones_m_BGrid_11__m_left -{0x0F12, 0x0000}, //awbb_LowBrGrZones_m_BGrid_11__m_right - -{0x0F12, 0x0006}, //awbb_LowBrGrZones_m_GridStep -{0x002A, 0x10E8}, -{0x0F12, 0x000B}, //awbb_LowBrGrZones_ZInfo_m_GridSz -{0x002A, 0x10EC}, -{0x0F12, 0x00D2}, //awbb_LowBrGrZones_m_Boffs - -// Low Temp. Zone -{0x002A, 0x10F0}, -{0x0F12, 0x039A}, -{0x0F12, 0x0000}, //awbb_CrclLowT_R_c -{0x0F12, 0x00FE}, -{0x0F12, 0x0000}, //awbb_CrclLowT_B_c -{0x0F12, 0x2284}, -{0x0F12, 0x0000}, //awbb_CrclLowT_Rad_c - -//AWB - GridCorrection -{0x002A, 0x1434}, -{0x0F12, 0x02C1}, //awbb_GridConst_1_0_ -{0x0F12, 0x033A}, //awbb_GridConst_1_1_ -{0x0F12, 0x038A}, //awbb_GridConst_1_2_ -{0x0F12, 0x101A}, //awbb_GridConst_2_0_ -{0x0F12, 0x1075}, //awbb_GridConst_2_1_ -{0x0F12, 0x113D}, //awbb_GridConst_2_2_ -{0x0F12, 0x113F}, //awbb_GridConst_2_3_ -{0x0F12, 0x11AF}, //awbb_GridConst_2_4_ -{0x0F12, 0x11F0}, //awbb_GridConst_2_5_ -{0x0F12, 0x00B2}, //awbb_GridCoeff_R_1 -{0x0F12, 0x00B8}, //awbb_GridCoeff_B_1 -{0x0F12, 0x00CA}, //awbb_GridCoeff_R_2 -{0x0F12, 0x009D}, //awbb_GridCoeff_B_2 +{0x002A,0x1078}, +{0x0F12,0x0264}, //#awbb_OutdoorGrZones_m_BGrid_0__m_left +{0x0F12,0x0278}, //#awbb_OutdoorGrZones_m_BGrid_0__m_right +{0x0F12,0x0242}, //#awbb_OutdoorGrZones_m_BGrid_1__m_left +{0x0F12,0x028E}, //#awbb_OutdoorGrZones_m_BGrid_1__m_right +{0x0F12,0x022A}, //#awbb_OutdoorGrZones_m_BGrid_2__m_left +{0x0F12,0x0290}, //#awbb_OutdoorGrZones_m_BGrid_2__m_right +{0x0F12,0x021E}, //#awbb_OutdoorGrZones_m_BGrid_3__m_left +{0x0F12,0x0290}, //#awbb_OutdoorGrZones_m_BGrid_3__m_right +{0x0F12,0x0214}, //#awbb_OutdoorGrZones_m_BGrid_4__m_left +{0x0F12,0x0290}, //#awbb_OutdoorGrZones_m_BGrid_4__m_right +{0x0F12,0x0206}, //#awbb_OutdoorGrZones_m_BGrid_5__m_left +{0x0F12,0x028E}, //#awbb_OutdoorGrZones_m_BGrid_5__m_right +{0x0F12,0x01FA}, //#awbb_OutdoorGrZones_m_BGrid_6__m_left +{0x0F12,0x0286}, //#awbb_OutdoorGrZones_m_BGrid_6__m_right +{0x0F12,0x01F4}, //#awbb_OutdoorGrZones_m_BGrid_7__m_left +{0x0F12,0x0280}, //#awbb_OutdoorGrZones_m_BGrid_7__m_right +{0x0F12,0x01F2}, //#awbb_OutdoorGrZones_m_BGrid_8__m_left +{0x0F12,0x0278}, //#awbb_OutdoorGrZones_m_BGrid_8__m_right +{0x0F12,0x01F0}, //#awbb_OutdoorGrZones_m_BGrid_9__m_left +{0x0F12,0x026E}, //#awbb_OutdoorGrZones_m_BGrid_9__m_right +{0x0F12,0x01F0}, //#awbb_OutdoorGrZones_m_BGrid_10__m_left +{0x0F12,0x0262}, //#awbb_OutdoorGrZones_m_BGrid_10__m_right +{0x0F12,0x01F0}, //#awbb_OutdoorGrZones_m_BGrid_11__m_left +{0x0F12,0x0218}, //#awbb_OutdoorGrZones_m_BGrid_11__m_right + +{0x0F12,0x0004}, //#awbb_OutdoorGrZones_m_GridStep +{0x002A,0x10AC}, +{0x0F12,0x000C}, //#awbb_OutdoorGrZones_ZInfo_m_GridSz +{0x002A,0x10B0}, +{0x0F12,0x020C}, //#awbb_OutdoorGrZones_m_Boffs + +// LowBR Zone +{0x002A,0x10B4}, +{0x0F12,0x0350}, //#awbb_LowBrGrZones +{0x0F12,0x0422}, //#awbb_LowBrGrZones_m_BGrid_0__m_right +{0x0F12,0x02C4}, //#awbb_LowBrGrZones_m_BGrid_1__m_left +{0x0F12,0x0452}, //#awbb_LowBrGrZones_m_BGrid_1__m_right +{0x0F12,0x0278}, //#awbb_LowBrGrZones_m_BGrid_2__m_left +{0x0F12,0x041C}, //#awbb_LowBrGrZones_m_BGrid_2__m_right +{0x0F12,0x0230}, //#awbb_LowBrGrZones_m_BGrid_3__m_left +{0x0F12,0x03EE}, //#awbb_LowBrGrZones_m_BGrid_3__m_right +{0x0F12,0x01F0}, //#awbb_LowBrGrZones_m_BGrid_4__m_left +{0x0F12,0x0392}, //#awbb_LowBrGrZones_m_BGrid_4__m_right +{0x0F12,0x01C0}, //#awbb_LowBrGrZones_m_BGrid_5__m_left +{0x0F12,0x0340}, //#awbb_LowBrGrZones_m_BGrid_5__m_right +{0x0F12,0x0194}, //#awbb_LowBrGrZones_m_BGrid_6__m_left +{0x0F12,0x0302}, //#awbb_LowBrGrZones_m_BGrid_6__m_right +{0x0F12,0x016E}, //#awbb_LowBrGrZones_m_BGrid_7__m_left +{0x0F12,0x02C2}, //#awbb_LowBrGrZones_m_BGrid_7__m_right +{0x0F12,0x0148}, //#awbb_LowBrGrZones_m_BGrid_8__m_left +{0x0F12,0x0286}, //#awbb_LowBrGrZones_m_BGrid_8__m_right +{0x0F12,0x018A}, //#awbb_LowBrGrZones_m_BGrid_9__m_left +{0x0F12,0x0242}, //#awbb_LowBrGrZones_m_BGrid_9__m_right +{0x0F12,0x0000}, //#awbb_LowBrGrZones_m_BGrid_10__m_left +{0x0F12,0x0000}, //#awbb_LowBrGrZones_m_BGrid_10__m_right +{0x0F12,0x0000}, //#awbb_LowBrGrZones_m_BGrid_11__m_left +{0x0F12,0x0000}, //#awbb_LowBrGrZones_m_BGrid_11__m_right + +{0x0F12,0x0006}, //#awbb_LowBrGrZones_m_GridStep +{0x002A,0x10E8}, +{0x0F12,0x000A}, //#awbb_LowBrGrZones_ZInfo_m_GridSz +{0x002A,0x10EC}, +{0x0F12,0x0106}, //#awbb_LowBrGrZones_m_Boffs + +// LowTemp Zone +{0x002A,0x10F0}, +{0x0F12,0x0380}, +{0x0F12,0x0000}, //#awbb_CrclLowT_R_c +{0x0F12,0x0168}, +{0x0F12,0x0000}, //#awbb_CrclLowT_B_c +{0x0F12,0x2D90}, +{0x0F12,0x0000}, //#awbb_CrclLowT_Rad_c + +// AWB Convergence Speed +{0x002A,0x1464}, +{0x0F12,0x0008}, //#awbb_WpFilterMinThr +{0x0F12,0x0190}, //#awbb_WpFilterMaxThr +{0x0F12,0x00FF}, //#awbb_WpFilterCoef + +{0x002A,0x1228}, +{0x0F12,0x00C0}, //#awbb_YThreshHigh +{0x002A,0x122C}, +{0x0F12,0x0010}, //#awbb_YThreshLow_Low +{0x002A,0x122A}, +{0x0F12,0x0010}, //#awbb_YThreshLow_Norm + +{0x002A,0x120A}, +{0x0F12,0x05D5}, //#awbb_MvEq_RBthresh +{0x002A,0x120E}, +{0x0F12,0x0000}, //#awbb_MovingScale10 + +{0x0F12,0x0771}, //#awbb_GamutWidthThr1 +{0x0F12,0x03A4}, //#awbb_GamutHeightThr1 +{0x0F12,0x0036}, //#awbb_GamutWidthThr2 +{0x0F12,0x002A}, //#awbb_GamutHeightThr2 + +{0x002A,0x1278}, +{0x0F12,0xFEF7}, //#awbb_SCDetectionMap_SEC_StartR_B +{0x0F12,0x0021}, //#awbb_SCDetectionMap_SEC_StepR_B +{0x0F12,0x0BB8}, //#awbb_SCDetectionMap_SEC_SunnyNB +{0x0F12,0x0BB8}, //#awbb_SCDetectionMap_SEC_StepNB +{0x0F12,0x018F}, //#awbb_SCDetectionMap_SEC_LowTempR_B +{0x0F12,0x0096}, //#awbb_SCDetectionMap_SEC_SunnyNBZone +{0x0F12,0x000E}, //#awbb_SCDetectionMap_SEC_LowTempR_BZone +{0x002A,0x1224}, +{0x0F12,0x0032}, //#awbb_LowBr +{0x0F12,0x001E}, //#awbb_LowBr_NBzone +{0x002A,0x2BA4}, +{0x0F12,0x0006}, //#Mon_AWB_ByPassMode + +{0x002A,0x146C}, +{0x0F12,0x0002}, //#awbb_GridEnable + +// Grid +{0x002A,0x1434}, +{0x0F12,0x0300}, //#awbb_GridConst_1 +{0x0F12,0x036E}, //#awbb_GridConst_1_1_ +{0x0F12,0x03C2}, //#awbb_GridConst_1_2_ +{0x0F12,0x1015}, //#awbb_GridConst_2 +{0x0F12,0x106C}, //#awbb_GridConst_2_1_ +{0x0F12,0x10CA}, //#awbb_GridConst_2_2_ +{0x0F12,0x1142}, //#awbb_GridConst_2_3_ +{0x0F12,0x11BB}, //#awbb_GridConst_2_4_ +{0x0F12,0x123B}, //#awbb_GridConst_2_5_ +{0x0F12,0x00AB}, //#awbb_GridCoeff_R_1 +{0x0F12,0x00BF}, //#awbb_GridCoeff_B_1 +{0x0F12,0x00D2}, //#awbb_GridCoeff_R_2 +{0x0F12,0x0093}, //#awbb_GridCoeff_B_2 // Indoor Grid Offset -{0x002A, 0x13A4}, -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_0__0_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_0__1_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_0__2_ -{0x0F12, 0xFFA0}, //awbb_GridCorr_R_0__3_ -{0x0F12, 0xFFEE}, //awbb_GridCorr_R_0__4_ -{0x0F12, 0x0096}, //awbb_GridCorr_R_0__5_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_1__0_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_1__1_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_1__2_ -{0x0F12, 0xFFA0}, //awbb_GridCorr_R_1__3_ -{0x0F12, 0xFFEE}, //awbb_GridCorr_R_1__4_ -{0x0F12, 0x0096}, //awbb_GridCorr_R_1__5_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_2__0_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_2__1_ -{0x0F12, 0xFFE0}, //awbb_GridCorr_R_2__2_ -{0x0F12, 0xFFA0}, //awbb_GridCorr_R_2__3_ -{0x0F12, 0xFFEE}, //awbb_GridCorr_R_2__4_ -{0x0F12, 0x0096}, //awbb_GridCorr_R_2__5_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_0__0_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_0__1_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_0__2_ -{0x0F12, 0xFF38}, //awbb_GridCorr_B_0__3_ -{0x0F12, 0xFEF2}, //awbb_GridCorr_B_0__4_ -{0x0F12, 0xFE5C}, //awbb_GridCorr_B_0__5_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_1__0_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_1__1_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_1__2_ -{0x0F12, 0xFF38}, //awbb_GridCorr_B_1__3_ -{0x0F12, 0xFEF2}, //awbb_GridCorr_B_1__4_ -{0x0F12, 0xFE5C}, //awbb_GridCorr_B_1__5_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_2__0_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_2__1_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_B_2__2_ -{0x0F12, 0xFF38}, //awbb_GridCorr_B_2__3_ -{0x0F12, 0xFEF2}, //awbb_GridCorr_B_2__4_ -{0x0F12, 0xFE5C}, //awbb_GridCorr_B_2__5_ +{0x002A,0x13A4}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, +{0x0F12,0x0000}, // Outdoor Grid Offset -{0x0F12, 0xFFC0}, //awbb_GridCorr_R_Out_0__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_0__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_0__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_0__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_0__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_0__5_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_R_Out_1__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_1__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_1__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_1__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_1__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_1__5_ -{0x0F12, 0xFFC0}, //awbb_GridCorr_R_Out_2__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_2__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_2__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_R_Out_2__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_2__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_R_Out_2__5_ -{0x0F12, 0x0010}, //awbb_GridCorr_B_Out_0__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_0__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_0__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_0__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_0__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_0__5_ -{0x0F12, 0x0010}, //awbb_GridCorr_B_Out_1__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_1__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_1__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_1__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_1__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_1__5_ -{0x0F12, 0x0010}, //awbb_GridCorr_B_Out_2__0_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_2__1_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_2__2_ -{0x0F12, 0xFFD0}, //awbb_GridCorr_B_Out_2__3_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_2__4_ -{0x0F12, 0x0000}, //awbb_GridCorr_B_Out_2__5_ +{0x0F12,0xFFEA}, +{0x0F12,0xFFEA}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFEA}, +{0x0F12,0xFFEA}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFEA}, +{0x0F12,0xFFEA}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0xFFC8}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0xFDA0}, +{0x0F12,0xFCF0}, +{0x0F12,0xFCD0}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0xFDA0}, +{0x0F12,0xFCF0}, +{0x0F12,0xFCD0}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0x0014}, +{0x0F12,0xFDA0}, +{0x0F12,0xFCF0}, +{0x0F12,0xFCD0}, + +{0x002A,0x1208}, +{0x0F12,0x0020}, //#awbb_MinNumOfChromaClassifyPatches + +{0x002A,0x144E}, +{0x0F12,0x0000}, //#awbb_RGainOff +{0x0F12,0x0000}, //#awbb_BGainOff +{0x0F12,0x0000}, //#awbb_GGainOff +//================================================================================== +// 10.Clock Setting +//================================================================================== +//Input Clock (Mclk) +{0x002A,0x01F8}, +{0x0F12,0x5DC0},//REG_TC_IPRM_InClockLSBs MCLK: 24Mhz +{0x002A,0x0212}, +{0x0F12,0x0000}, //REG_TC_IPRM_UseNPviClocks +{0x0F12,0x0003},//REG_TC_IPRM_UseNMipiClocks 0x0002 +{0x0F12,0x0002}, //REG_TC_IPRM_NumberOfMipiLanes +{0x002A,0x021A}, +{0x0F12,0x3A98}, //3A98} //REG_TC_IPRM_OpClk4KHz_0 SCLK: 60Mhz +{0x0F12,0x277D}, //REG_TC_IPRM_MinOutRate4KHz_0 PCLK Min : 81Mhz +{0x0F12,0x279D}, //REG_TC_IPRM_MaxOutRate4KHz_0 PCLK Max : 81Mhz +{0x0F12,0x4F1A}, //REG_TC_IPRM_OpClk4KHz_1 SCLK : 81Mhz +{0x0F12,0x277D}, //REG_TC_IPRM_MinOutRate4KHz_1 PCLK Min : 81Mhz +{0x0F12,0x279D}, //REG_TC_IPRM_MaxOutRate4KHz_1 PCLK Max : 81Mhz +{0x0F12,0x4F1A}, +{0x0F12,0x5988}, +{0x0F12,0x59D8}, +//================================================================================== +// 11.Auto Flicker Detection +//================================================================================== + +{0x002A,0x0F30}, +{0x0F12,0x0001}, // AFC_D_ConvAccelerPower +// Auto Flicker (60Mhz start) +{0x002A,0x0F2A}, +{0x0F12,0x0000},//AFC_Default60Hz 0001:60Hz 0000h:50Hz +{0x002A,0x04E6}, +{0x0F12,0x077F}, //REG_TC_DBG //================================================================================== -// 15.CCM Setting +// 12.AE Setting //================================================================================== -{0x002A, 0x08A6}, -{0x0F12, 0x0050}, //SARR_AwbCcmCord_0_ -{0x0F12, 0x00F0}, //SARR_AwbCcmCord_1_ -{0x0F12, 0x0110}, //SARR_AwbCcmCord_2_ -{0x0F12, 0x0120}, //SARR_AwbCcmCord_3_ -{0x0F12, 0x0130}, //SARR_AwbCcmCord_4_ -{0x0F12, 0x0162}, //SARR_AwbCcmCord_5_ - -{0x0F12, 0x0001}, //wbt_bUseOutdoorCCM - -{0x002A, 0x0898}, -{0x0F12, 0x4800}, //TVAR_wbt_pBaseCcms -{0x0F12, 0x7000}, -{0x002A, 0x08A0}, -{0x0F12, 0x48D8}, //TVAR_wbt_pOutdoorCcm -{0x0F12, 0x7000}, - -{0x002A, 0x4800}, -{0x0F12, 0x0119}, //TVAR_wbt_pBaseCcms[0] // Horizon -{0x0F12, 0xFFA9}, //TVAR_wbt_pBaseCcms[1] -{0x0F12, 0xFF9D}, //TVAR_wbt_pBaseCcms[2] -{0x0F12, 0xFF30}, //TVAR_wbt_pBaseCcms[3] -{0x0F12, 0x0130}, //TVAR_wbt_pBaseCcms[4] -{0x0F12, 0xFF8E}, //TVAR_wbt_pBaseCcms[5] -{0x0F12, 0xFFF8}, //TVAR_wbt_pBaseCcms[6] -{0x0F12, 0xFFAC}, //TVAR_wbt_pBaseCcms[7] -{0x0F12, 0x0137}, //TVAR_wbt_pBaseCcms[8] -{0x0F12, 0x0087}, //TVAR_wbt_pBaseCcms[9] -{0x0F12, 0x00D0}, //TVAR_wbt_pBaseCcms[10] -{0x0F12, 0xFEE3}, //TVAR_wbt_pBaseCcms[11] -{0x0F12, 0x0162}, //TVAR_wbt_pBaseCcms[12] -{0x0F12, 0xFF77}, //TVAR_wbt_pBaseCcms[13] -{0x0F12, 0x00E8}, //TVAR_wbt_pBaseCcms[14] -{0x0F12, 0xFF40}, //TVAR_wbt_pBaseCcms[15] -{0x0F12, 0x0114}, //TVAR_wbt_pBaseCcms[16] -{0x0F12, 0x00F4}, //TVAR_wbt_pBaseCcms[17] - -{0x0F12, 0x0119}, //TVAR_wbt_pBaseCcms[18] // IncandA -{0x0F12, 0xFFA9}, //TVAR_wbt_pBaseCcms[19] -{0x0F12, 0xFF9D}, //TVAR_wbt_pBaseCcms[20] -{0x0F12, 0xFF30}, //TVAR_wbt_pBaseCcms[21] -{0x0F12, 0x0130}, //TVAR_wbt_pBaseCcms[22] -{0x0F12, 0xFF8E}, //TVAR_wbt_pBaseCcms[23] -{0x0F12, 0xFFF8}, //TVAR_wbt_pBaseCcms[24] -{0x0F12, 0xFFAC}, //TVAR_wbt_pBaseCcms[25] -{0x0F12, 0x0137}, //TVAR_wbt_pBaseCcms[26] -{0x0F12, 0x0087}, //TVAR_wbt_pBaseCcms[27] -{0x0F12, 0x00D0}, //TVAR_wbt_pBaseCcms[28] -{0x0F12, 0xFEE3}, //TVAR_wbt_pBaseCcms[29] -{0x0F12, 0x0162}, //TVAR_wbt_pBaseCcms[30] -{0x0F12, 0xFF77}, //TVAR_wbt_pBaseCcms[31] -{0x0F12, 0x00E8}, //TVAR_wbt_pBaseCcms[32] -{0x0F12, 0xFF40}, //TVAR_wbt_pBaseCcms[33] -{0x0F12, 0x0114}, //TVAR_wbt_pBaseCcms[34] -{0x0F12, 0x00F4}, //TVAR_wbt_pBaseCcms[35] - -{0x0F12, 0x0204}, //TVAR_wbt_pBaseCcms[36] // WW -{0x0F12, 0xFFB2}, //TVAR_wbt_pBaseCcms[37] -{0x0F12, 0xFFF5}, //TVAR_wbt_pBaseCcms[38] -{0x0F12, 0xFEE7}, //TVAR_wbt_pBaseCcms[39] -{0x0F12, 0x0161}, //TVAR_wbt_pBaseCcms[40] -{0x0F12, 0xFF10}, //TVAR_wbt_pBaseCcms[41] -{0x0F12, 0xFFDD}, //TVAR_wbt_pBaseCcms[42] -{0x0F12, 0xFFE6}, //TVAR_wbt_pBaseCcms[43] -{0x0F12, 0x01B2}, //TVAR_wbt_pBaseCcms[44] -{0x0F12, 0x00F2}, //TVAR_wbt_pBaseCcms[45] -{0x0F12, 0x00CA}, //TVAR_wbt_pBaseCcms[46] -{0x0F12, 0xFF48}, //TVAR_wbt_pBaseCcms[47] -{0x0F12, 0x0151}, //TVAR_wbt_pBaseCcms[48] -{0x0F12, 0xFF50}, //TVAR_wbt_pBaseCcms[49] -{0x0F12, 0x0147}, //TVAR_wbt_pBaseCcms[50] -{0x0F12, 0xFF75}, //TVAR_wbt_pBaseCcms[51] -{0x0F12, 0x01BA}, //TVAR_wbt_pBaseCcms[52] -{0x0F12, 0x018C}, //TVAR_wbt_pBaseCcms[53] - -{0x0F12, 0x0204}, //TVAR_wbt_pBaseCcms[54] // CW -{0x0F12, 0xFFB2}, //TVAR_wbt_pBaseCcms[55] -{0x0F12, 0xFFF5}, //TVAR_wbt_pBaseCcms[56] -{0x0F12, 0xFEF1}, //TVAR_wbt_pBaseCcms[57] -{0x0F12, 0x014E}, //TVAR_wbt_pBaseCcms[58] -{0x0F12, 0xFF18}, //TVAR_wbt_pBaseCcms[59] -{0x0F12, 0xFFE6}, //TVAR_wbt_pBaseCcms[60] -{0x0F12, 0xFFDD}, //TVAR_wbt_pBaseCcms[61] -{0x0F12, 0x01B2}, //TVAR_wbt_pBaseCcms[62] -{0x0F12, 0x00F2}, //TVAR_wbt_pBaseCcms[63] -{0x0F12, 0x00CA}, //TVAR_wbt_pBaseCcms[64] -{0x0F12, 0xFF48}, //TVAR_wbt_pBaseCcms[65] -{0x0F12, 0x0151}, //TVAR_wbt_pBaseCcms[66] -{0x0F12, 0xFF50}, //TVAR_wbt_pBaseCcms[67] -{0x0F12, 0x0147}, //TVAR_wbt_pBaseCcms[68] -{0x0F12, 0xFF75}, //TVAR_wbt_pBaseCcms[69] -{0x0F12, 0x0187}, //TVAR_wbt_pBaseCcms[70] -{0x0F12, 0x01BF}, //TVAR_wbt_pBaseCcms[71] - -{0x0F12, 0x0204}, //TVAR_wbt_pBaseCcms[72] // D50 -{0x0F12, 0xFFB2}, //TVAR_wbt_pBaseCcms[73] -{0x0F12, 0xFFF5}, //TVAR_wbt_pBaseCcms[74] -{0x0F12, 0xFEF1}, //TVAR_wbt_pBaseCcms[75] -{0x0F12, 0x014E}, //TVAR_wbt_pBaseCcms[76] -{0x0F12, 0xFF18}, //TVAR_wbt_pBaseCcms[77] -{0x0F12, 0xFFE6}, //TVAR_wbt_pBaseCcms[78] -{0x0F12, 0xFFDD}, //TVAR_wbt_pBaseCcms[79] -{0x0F12, 0x01B2}, //TVAR_wbt_pBaseCcms[80] -{0x0F12, 0x00F2}, //TVAR_wbt_pBaseCcms[81] -{0x0F12, 0x00CA}, //TVAR_wbt_pBaseCcms[82] -{0x0F12, 0xFF48}, //TVAR_wbt_pBaseCcms[83] -{0x0F12, 0x0151}, //TVAR_wbt_pBaseCcms[84] -{0x0F12, 0xFF50}, //TVAR_wbt_pBaseCcms[85] -{0x0F12, 0x0147}, //TVAR_wbt_pBaseCcms[86] -{0x0F12, 0xFF75}, //TVAR_wbt_pBaseCcms[87] -{0x0F12, 0x0187}, //TVAR_wbt_pBaseCcms[88] -{0x0F12, 0x01BF}, //TVAR_wbt_pBaseCcms[89] - -{0x0F12, 0x0204}, //TVAR_wbt_pBaseCcms[90] // D65 -{0x0F12, 0xFFB2}, //TVAR_wbt_pBaseCcms[91] -{0x0F12, 0xFFF5}, //TVAR_wbt_pBaseCcms[92] -{0x0F12, 0xFEF1}, //TVAR_wbt_pBaseCcms[93] -{0x0F12, 0x014E}, //TVAR_wbt_pBaseCcms[94] -{0x0F12, 0xFF18}, //TVAR_wbt_pBaseCcms[95] -{0x0F12, 0xFFE6}, //TVAR_wbt_pBaseCcms[96] -{0x0F12, 0xFFDD}, //TVAR_wbt_pBaseCcms[97] -{0x0F12, 0x01B2}, //TVAR_wbt_pBaseCcms[98] -{0x0F12, 0x00F2}, //TVAR_wbt_pBaseCcms[99] -{0x0F12, 0x00CA}, //TVAR_wbt_pBaseCcms[100] -{0x0F12, 0xFF48}, //TVAR_wbt_pBaseCcms[101] -{0x0F12, 0x0151}, //TVAR_wbt_pBaseCcms[102] -{0x0F12, 0xFF50}, //TVAR_wbt_pBaseCcms[103] -{0x0F12, 0x0147}, //TVAR_wbt_pBaseCcms[104] -{0x0F12, 0xFF75}, //TVAR_wbt_pBaseCcms[105] -{0x0F12, 0x0187}, //TVAR_wbt_pBaseCcms[106] -{0x0F12, 0x01BF}, //TVAR_wbt_pBaseCcms[107] - -{0x0F12, 0x01E5}, //TVAR_wbt_pOutdoorCcm[0] -{0x0F12, 0xFFA4}, //TVAR_wbt_pOutdoorCcm[1] -{0x0F12, 0xFFDC}, //TVAR_wbt_pOutdoorCcm[2] -{0x0F12, 0xFE87}, //TVAR_wbt_pOutdoorCcm[3] -{0x0F12, 0x013C}, //TVAR_wbt_pOutdoorCcm[4] -{0x0F12, 0xFF2A}, //TVAR_wbt_pOutdoorCcm[5] -{0x0F12, 0xFFD2}, //TVAR_wbt_pOutdoorCcm[6] -{0x0F12, 0xFFDF}, //TVAR_wbt_pOutdoorCcm[7] -{0x0F12, 0x0236}, //TVAR_wbt_pOutdoorCcm[8] -{0x0F12, 0x00EC}, //TVAR_wbt_pOutdoorCcm[9] -{0x0F12, 0x00F8}, //TVAR_wbt_pOutdoorCcm[10] -{0x0F12, 0xFF34}, //TVAR_wbt_pOutdoorCcm[11] -{0x0F12, 0x01CE}, //TVAR_wbt_pOutdoorCcm[12] -{0x0F12, 0xFF83}, //TVAR_wbt_pOutdoorCcm[13] -{0x0F12, 0x0195}, //TVAR_wbt_pOutdoorCcm[14] -{0x0F12, 0xFEF3}, //TVAR_wbt_pOutdoorCcm[15] -{0x0F12, 0x0126}, //TVAR_wbt_pOutdoorCcm[16] -{0x0F12, 0x0162}, //TVAR_wbt_pOutdoorCcm[17] +//AE Target +{0x002A,0x1484}, +{0x0F12,0x003C}, // TVAR_ae_BrAve +//ae_StatMode bit[3] BLC has to be bypassed to prevent AE weight change especially backlight scene +{0x002A,0x148A}, +{0x0F12,0x000F}, //ae_StatMode +{0x002A,0x058C}, +{0x0F12,0x3520}, +{0x0F12,0x0000}, //lt_uMaxExp1 +{0x0F12,0xD4C0}, +{0x0F12,0x0001}, //lt_uMaxExp2 +{0x0F12,0x3520}, +{0x0F12,0x0000}, //lt_uCapMaxExp1 +{0x0F12,0xD4C0}, +{0x0F12,0x0001},//lt_uCapMaxExp2 +{0x002A,0x059C}, +{0x0F12,0x0470},//lt_uMaxAnGain1 +{0x0F12,0x0C00}, //lt_uMaxAnGain2 +{0x0F12,0x0100}, //lt_uMaxDigGain +{0x0F12,0x1000}, //lt_uMaxTotGain +{0x002A,0x0544}, +{0x0F12,0x0111}, //lt_uLimitHigh +{0x0F12,0x00EF}, //lt_uLimitLow +{0x002A,0x0608}, +{0x0F12,0x0001}, //lt_ExpGain_uSubsamplingmode +{0x0F12,0x0001}, //lt_ExpGain_uNonSubsampling +{0x0F12,0x0800}, //lt_ExpGain_ExpCurveGainMaxStr +{0x0F12,0x0100}, //0100} //lt_ExpGain_ExpCurveGainMaxStr_0__uMaxDigGain +{0x0F12,0x0001}, //0001 +{0x0F12,0x0000}, //0000} //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpIn_0_ +{0x0F12,0x0A3C}, //0A3C +{0x0F12,0x0000}, //0000 +{0x0F12,0x0D05}, //0D05 +{0x0F12,0x0000}, //0000 +{0x0F12,0x4008}, //4008 +{0x0F12,0x0000}, //0000 +{0x0F12,0x7000}, //7400} //?? //700Lux +{0x0F12,0x0000}, //0000 +{0x0F12,0x9C00}, //C000} //?? //9C00->9F->A5 //400Lux +{0x0F12,0x0000}, //0000 +{0x0F12,0xAD00}, //AD00 +{0x0F12,0x0001}, //0001 +{0x0F12,0xF1D4}, //F1D4 +{0x0F12,0x0002}, //0002 +{0x0F12,0xDC00}, //DC00 +{0x0F12,0x0005}, //0005 +{0x0F12,0xDC00}, //DC00 +{0x0F12,0x0005}, //0005 } // +{0x002A,0x0638}, //0638 +{0x0F12,0x0001}, //0001 +{0x0F12,0x0000}, //0000} //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ +{0x0F12,0x0A3C}, //0A3C +{0x0F12,0x0000}, //0000 +{0x0F12,0x0D05}, //0D05 +{0x0F12,0x0000}, //0000 +{0x0F12,0x3408}, //3408 +{0x0F12,0x0000}, //0000 +{0x0F12,0x3408}, //3408 +{0x0F12,0x0000}, //0000 +{0x0F12,0x6810}, //6810 +{0x0F12,0x0000}, //0000 +{0x0F12,0x8214}, //8214 +{0x0F12,0x0000}, //0000 +{0x0F12,0xC350}, //C350 +{0x0F12,0x0000}, //0000 +{0x0F12,0xD4C0}, //C350 +{0x0F12,0x0001}, //0000 +{0x0F12,0xD4C0}, //C350 +{0x0F12,0x0001}, //0000 +{0x002A,0x0660}, +{0x0F12,0x0650}, //lt_ExpGain_ExpCurveGainMaxStr_1_ +{0x0F12,0x0100}, //lt_ExpGain_ExpCurveGainMaxStr_1__uMaxDigGain +{0x002A,0x06B8}, +{0x0F12,0x452C}, +{0x0F12,0x000A}, //0005} //lt_uMaxLei +{0x002A,0x05D0}, +{0x0F12,0x0000}, //lt_mbr_Peak_behind //================================================================================== -// 16.GAMMA +// 13.AE Weight (Normal) //================================================================================== +{0x002A,0x1492}, +{0x0F12,0x0100}, // ae_WeightTbl_16[0] +{0x0F12,0x0101}, // ae_WeightTbl_16[1] +{0x0F12,0x0101}, // ae_WeightTbl_16[2] +{0x0F12,0x0001}, // ae_WeightTbl_16[3] +{0x0F12,0x0101}, // ae_WeightTbl_16[4] +{0x0F12,0x0201}, // ae_WeightTbl_16[5] +{0x0F12,0x0102}, // ae_WeightTbl_16[6] +{0x0F12,0x0101}, // ae_WeightTbl_16[7] +{0x0F12,0x0101}, // ae_WeightTbl_16[8] +{0x0F12,0x0202}, // ae_WeightTbl_16[9] +{0x0F12,0x0202}, // ae_WeightTbl_16[10] +{0x0F12,0x0101}, // ae_WeightTbl_16[11] +{0x0F12,0x0201}, // ae_WeightTbl_16[12] +{0x0F12,0x0302}, // ae_WeightTbl_16[13] +{0x0F12,0x0203}, // ae_WeightTbl_16[14] +{0x0F12,0x0102}, // ae_WeightTbl_16[15] +{0x0F12,0x0201}, // ae_WeightTbl_16[16] +{0x0F12,0x0302}, // ae_WeightTbl_16[17] +{0x0F12,0x0203}, // ae_WeightTbl_16[18] +{0x0F12,0x0102}, // ae_WeightTbl_16[19] +{0x0F12,0x0201}, // ae_WeightTbl_16[20] +{0x0F12,0x0202}, // ae_WeightTbl_16[21] +{0x0F12,0x0202}, // ae_WeightTbl_16[22] +{0x0F12,0x0102}, // ae_WeightTbl_16[23] +{0x0F12,0x0101}, // ae_WeightTbl_16[24] +{0x0F12,0x0202}, // ae_WeightTbl_16[25] +{0x0F12,0x0202}, // ae_WeightTbl_16[26] +{0x0F12,0x0101}, // ae_WeightTbl_16[27] +{0x0F12,0x0101}, // ae_WeightTbl_16[28] +{0x0F12,0x0101}, // ae_WeightTbl_16[29] +{0x0F12,0x0101}, // ae_WeightTbl_16[30] +{0x0F12,0x0101}, // ae_WeightTbl_16[31] -// Indoor Gamma -{0x002A, 0x0734}, -{0x0F12, 0x0001}, //SARR_usGammaLutRGBIndoor_0__0_ -{0x0F12, 0x0003}, //SARR_usGammaLutRGBIndoor_0__1_ -{0x0F12, 0x000F}, //SARR_usGammaLutRGBIndoor_0__2_ -{0x0F12, 0x002B}, //SARR_usGammaLutRGBIndoor_0__3_ -{0x0F12, 0x0069}, //SARR_usGammaLutRGBIndoor_0__4_ -{0x0F12, 0x00D9}, //SARR_usGammaLutRGBIndoor_0__5_ -{0x0F12, 0x0138}, //SARR_usGammaLutRGBIndoor_0__6_ -{0x0F12, 0x0163}, //SARR_usGammaLutRGBIndoor_0__7_ -{0x0F12, 0x0189}, //SARR_usGammaLutRGBIndoor_0__8_ -{0x0F12, 0x01C6}, //SARR_usGammaLutRGBIndoor_0__9_ -{0x0F12, 0x01F8}, //SARR_usGammaLutRGBIndoor_0__10_ -{0x0F12, 0x0222}, //SARR_usGammaLutRGBIndoor_0__11_ -{0x0F12, 0x0249}, //SARR_usGammaLutRGBIndoor_0__12_ -{0x0F12, 0x028D}, //SARR_usGammaLutRGBIndoor_0__13_ -{0x0F12, 0x02C9}, //SARR_usGammaLutRGBIndoor_0__14_ -{0x0F12, 0x0327}, //SARR_usGammaLutRGBIndoor_0__15_ -{0x0F12, 0x0371}, //SARR_usGammaLutRGBIndoor_0__16_ -{0x0F12, 0x03AC}, //SARR_usGammaLutRGBIndoor_0__17_ -{0x0F12, 0x03DD}, //SARR_usGammaLutRGBIndoor_0__18_ -{0x0F12, 0x03FF}, //SARR_usGammaLutRGBIndoor_0__19_ -{0x0F12, 0x0001}, //SARR_usGammaLutRGBIndoor_1__0_ -{0x0F12, 0x0003}, //SARR_usGammaLutRGBIndoor_1__1_ -{0x0F12, 0x000F}, //SARR_usGammaLutRGBIndoor_1__2_ -{0x0F12, 0x002B}, //SARR_usGammaLutRGBIndoor_1__3_ -{0x0F12, 0x0069}, //SARR_usGammaLutRGBIndoor_1__4_ -{0x0F12, 0x00D9}, //SARR_usGammaLutRGBIndoor_1__5_ -{0x0F12, 0x0138}, //SARR_usGammaLutRGBIndoor_1__6_ -{0x0F12, 0x0163}, //SARR_usGammaLutRGBIndoor_1__7_ -{0x0F12, 0x0189}, //SARR_usGammaLutRGBIndoor_1__8_ -{0x0F12, 0x01C6}, //SARR_usGammaLutRGBIndoor_1__9_ -{0x0F12, 0x01F8}, //SARR_usGammaLutRGBIndoor_1__10_ -{0x0F12, 0x0222}, //SARR_usGammaLutRGBIndoor_1__11_ -{0x0F12, 0x0249}, //SARR_usGammaLutRGBIndoor_1__12_ -{0x0F12, 0x028D}, //SARR_usGammaLutRGBIndoor_1__13_ -{0x0F12, 0x02C9}, //SARR_usGammaLutRGBIndoor_1__14_ -{0x0F12, 0x0327}, //SARR_usGammaLutRGBIndoor_1__15_ -{0x0F12, 0x0371}, //SARR_usGammaLutRGBIndoor_1__16_ -{0x0F12, 0x03AC}, //SARR_usGammaLutRGBIndoor_1__17_ -{0x0F12, 0x03DD}, //SARR_usGammaLutRGBIndoor_1__18_ -{0x0F12, 0x03FF}, //SARR_usGammaLutRGBIndoor_1__19_ -{0x0F12, 0x0001}, //SARR_usGammaLutRGBIndoor_2__0_ -{0x0F12, 0x0003}, //SARR_usGammaLutRGBIndoor_2__1_ -{0x0F12, 0x000F}, //SARR_usGammaLutRGBIndoor_2__2_ -{0x0F12, 0x002B}, //SARR_usGammaLutRGBIndoor_2__3_ -{0x0F12, 0x0069}, //SARR_usGammaLutRGBIndoor_2__4_ -{0x0F12, 0x00D9}, //SARR_usGammaLutRGBIndoor_2__5_ -{0x0F12, 0x0138}, //SARR_usGammaLutRGBIndoor_2__6_ -{0x0F12, 0x0163}, //SARR_usGammaLutRGBIndoor_2__7_ -{0x0F12, 0x0189}, //SARR_usGammaLutRGBIndoor_2__8_ -{0x0F12, 0x01C6}, //SARR_usGammaLutRGBIndoor_2__9_ -{0x0F12, 0x01F8}, //SARR_usGammaLutRGBIndoor_2__10_ -{0x0F12, 0x0222}, //SARR_usGammaLutRGBIndoor_2__11_ -{0x0F12, 0x0249}, //SARR_usGammaLutRGBIndoor_2__12_ -{0x0F12, 0x028D}, //SARR_usGammaLutRGBIndoor_2__13_ -{0x0F12, 0x02C9}, //SARR_usGammaLutRGBIndoor_2__14_ -{0x0F12, 0x0327}, //SARR_usGammaLutRGBIndoor_2__15_ -{0x0F12, 0x0371}, //SARR_usGammaLutRGBIndoor_2__16_ -{0x0F12, 0x03AC}, //SARR_usGammaLutRGBIndoor_2__17_ -{0x0F12, 0x03DD}, //SARR_usGammaLutRGBIndoor_2__18_ -{0x0F12, 0x03FF}, //SARR_usGammaLutRGBIndoor_2__19_ - -// Outdoor Gamma -{0x0F12, 0x0001}, //SARR_usGammaLutRGBOutdoor_0__0_ -{0x0F12, 0x000B}, //SARR_usGammaLutRGBOutdoor_0__1_ -{0x0F12, 0x0019}, //SARR_usGammaLutRGBOutdoor_0__2_ -{0x0F12, 0x0036}, //SARR_usGammaLutRGBOutdoor_0__3_ -{0x0F12, 0x006F}, //SARR_usGammaLutRGBOutdoor_0__4_ -{0x0F12, 0x00D8}, //SARR_usGammaLutRGBOutdoor_0__5_ -{0x0F12, 0x0135}, //SARR_usGammaLutRGBOutdoor_0__6_ -{0x0F12, 0x015F}, //SARR_usGammaLutRGBOutdoor_0__7_ -{0x0F12, 0x0185}, //SARR_usGammaLutRGBOutdoor_0__8_ -{0x0F12, 0x01C1}, //SARR_usGammaLutRGBOutdoor_0__9_ -{0x0F12, 0x01F3}, //SARR_usGammaLutRGBOutdoor_0__10_ -{0x0F12, 0x0220}, //SARR_usGammaLutRGBOutdoor_0__11_ -{0x0F12, 0x024A}, //SARR_usGammaLutRGBOutdoor_0__12_ -{0x0F12, 0x0291}, //SARR_usGammaLutRGBOutdoor_0__13_ -{0x0F12, 0x02D0}, //SARR_usGammaLutRGBOutdoor_0__14_ -{0x0F12, 0x032A}, //SARR_usGammaLutRGBOutdoor_0__15_ -{0x0F12, 0x036A}, //SARR_usGammaLutRGBOutdoor_0__16_ -{0x0F12, 0x039F}, //SARR_usGammaLutRGBOutdoor_0__17_ -{0x0F12, 0x03CC}, //SARR_usGammaLutRGBOutdoor_0__18_ -{0x0F12, 0x03F9}, //SARR_usGammaLutRGBOutdoor_0__19_ -{0x0F12, 0x0001}, //SARR_usGammaLutRGBOutdoor_1__0_ -{0x0F12, 0x000B}, //SARR_usGammaLutRGBOutdoor_1__1_ -{0x0F12, 0x0019}, //SARR_usGammaLutRGBOutdoor_1__2_ -{0x0F12, 0x0036}, //SARR_usGammaLutRGBOutdoor_1__3_ -{0x0F12, 0x006F}, //SARR_usGammaLutRGBOutdoor_1__4_ -{0x0F12, 0x00D8}, //SARR_usGammaLutRGBOutdoor_1__5_ -{0x0F12, 0x0135}, //SARR_usGammaLutRGBOutdoor_1__6_ -{0x0F12, 0x015F}, //SARR_usGammaLutRGBOutdoor_1__7_ -{0x0F12, 0x0185}, //SARR_usGammaLutRGBOutdoor_1__8_ -{0x0F12, 0x01C1}, //SARR_usGammaLutRGBOutdoor_1__9_ -{0x0F12, 0x01F3}, //SARR_usGammaLutRGBOutdoor_1__10_ -{0x0F12, 0x0220}, //SARR_usGammaLutRGBOutdoor_1__11_ -{0x0F12, 0x024A}, //SARR_usGammaLutRGBOutdoor_1__12_ -{0x0F12, 0x0291}, //SARR_usGammaLutRGBOutdoor_1__13_ -{0x0F12, 0x02D0}, //SARR_usGammaLutRGBOutdoor_1__14_ -{0x0F12, 0x032A}, //SARR_usGammaLutRGBOutdoor_1__15_ -{0x0F12, 0x036A}, //SARR_usGammaLutRGBOutdoor_1__16_ -{0x0F12, 0x039F}, //SARR_usGammaLutRGBOutdoor_1__17_ -{0x0F12, 0x03CC}, //SARR_usGammaLutRGBOutdoor_1__18_ -{0x0F12, 0x03F9}, //SARR_usGammaLutRGBOutdoor_1__19_ -{0x0F12, 0x0001}, //SARR_usGammaLutRGBOutdoor_2__0_ -{0x0F12, 0x000B}, //SARR_usGammaLutRGBOutdoor_2__1_ -{0x0F12, 0x0019}, //SARR_usGammaLutRGBOutdoor_2__2_ -{0x0F12, 0x0036}, //SARR_usGammaLutRGBOutdoor_2__3_ -{0x0F12, 0x006F}, //SARR_usGammaLutRGBOutdoor_2__4_ -{0x0F12, 0x00D8}, //SARR_usGammaLutRGBOutdoor_2__5_ -{0x0F12, 0x0135}, //SARR_usGammaLutRGBOutdoor_2__6_ -{0x0F12, 0x015F}, //SARR_usGammaLutRGBOutdoor_2__7_ -{0x0F12, 0x0185}, //SARR_usGammaLutRGBOutdoor_2__8_ -{0x0F12, 0x01C1}, //SARR_usGammaLutRGBOutdoor_2__9_ -{0x0F12, 0x01F3}, //SARR_usGammaLutRGBOutdoor_2__10_ -{0x0F12, 0x0220}, //SARR_usGammaLutRGBOutdoor_2__11_ -{0x0F12, 0x024A}, //SARR_usGammaLutRGBOutdoor_2__12_ -{0x0F12, 0x0291}, //SARR_usGammaLutRGBOutdoor_2__13_ -{0x0F12, 0x02D0}, //SARR_usGammaLutRGBOutdoor_2__14_ -{0x0F12, 0x032A}, //SARR_usGammaLutRGBOutdoor_2__15_ -{0x0F12, 0x036A}, //SARR_usGammaLutRGBOutdoor_2__16_ -{0x0F12, 0x039F}, //SARR_usGammaLutRGBOutdoor_2__17_ -{0x0F12, 0x03CC}, //SARR_usGammaLutRGBOutdoor_2__18_ -{0x0F12, 0x03F9}, //SARR_usGammaLutRGBOutdoor_2__19_ //================================================================================== -// 17.AFIT +// 14.Flash Setting //================================================================================== -{0x002A, 0x0944}, -{0x0F12, 0x0050}, //afit_uNoiseIndInDoor -{0x0F12, 0x00B0}, //afit_uNoiseIndInDoor -{0x0F12, 0x0196}, //afit_uNoiseIndInDoor -{0x0F12, 0x0245}, //afit_uNoiseIndInDoor -{0x0F12, 0x0300}, //afit_uNoiseIndInDoor - -{0x002A, 0x0938}, -{0x0F12, 0x0000}, // on/off AFIT by NB option -{0x0F12, 0x0014}, //SARR_uNormBrInDoor -{0x0F12, 0x00D2}, //SARR_uNormBrInDoor -{0x0F12, 0x0384}, //SARR_uNormBrInDoor -{0x0F12, 0x07D0}, //SARR_uNormBrInDoor -{0x0F12, 0x1388}, //SARR_uNormBrInDoor - -{0x002A, 0x0976}, -{0x0F12, 0x0070}, //afit_usGamutTh -{0x0F12, 0x0005}, //afit_usNeargrayOffset -{0x0F12, 0x0000}, //afit_bUseSenBpr -{0x0F12, 0x01CC}, //afit_usBprThr_0_ -{0x0F12, 0x01CC}, //afit_usBprThr_1_ -{0x0F12, 0x01CC}, //afit_usBprThr_2_ -{0x0F12, 0x01CC}, //afit_usBprThr_3_ -{0x0F12, 0x01CC}, //afit_usBprThr_4_ -{0x0F12, 0x0180}, //afit_NIContrastAFITValue -{0x0F12, 0x0196}, //afit_NIContrastTh - -{0x002A, 0x098C}, -{0x0F12, 0x0000}, //7000098C //_BRIGHTNESS AFIT 0 -{0x0F12, 0x0000}, //7000098E //_CONTRAST -{0x0F12, 0x0000}, //70000990 //_SATURATION -{0x0F12, 0x0000}, //70000992 //_SHARP_BLUR -{0x0F12, 0x0000}, //70000994 //_GLAMOUR -{0x0F12, 0x00C0}, //70000996 //_bnr_edge_high -{0x0F12, 0x0064}, //70000998 //_postdmsc_iLowBright -{0x0F12, 0x0384}, //7000099A //_postdmsc_iHighBright -{0x0F12, 0x005F}, //7000099C //_postdmsc_iLowSat -{0x0F12, 0x01F4}, //7000099E //_postdmsc_iHighSat -{0x0F12, 0x0070}, //700009A0 //_postdmsc_iTune -{0x0F12, 0x0040}, //700009A2 //_yuvemix_mNegRanges_0 -{0x0F12, 0x00A0}, //700009A4 //_yuvemix_mNegRanges_1 -{0x0F12, 0x0100}, //700009A6 //_yuvemix_mNegRanges_2 -{0x0F12, 0x0010}, //700009A8 //_yuvemix_mPosRanges_0 -{0x0F12, 0x0040}, //700009AA //_yuvemix_mPosRanges_1 -{0x0F12, 0x00A0}, //700009AC //_yuvemix_mPosRanges_2 -{0x0F12, 0x1430}, //700009AE //_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh -{0x0F12, 0x0201}, //700009B0 //_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh -{0x0F12, 0x0204}, //700009B2 //_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh -{0x0F12, 0x3604}, //700009B4 //_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low -{0x0F12, 0x032A}, //700009B6 //_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low -{0x0F12, 0x0403}, //700009B8 //_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin -{0x0F12, 0x1B06}, //700009BA //_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow -{0x0F12, 0x6015}, //700009BC //_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH -{0x0F12, 0x00C0}, //700009BE //_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune -{0x0F12, 0x6080}, //700009C0 //_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh -{0x0F12, 0x4080}, //700009C2 //_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh -{0x0F12, 0x0640}, //700009C4 //_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed -{0x0F12, 0x0306}, //700009C6 //_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh -{0x0F12, 0x2003}, //700009C8 //_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH -{0x0F12, 0xFF01}, //700009CA //_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit -{0x0F12, 0x0000}, //700009CC //_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 -{0x0F12, 0x0400}, //700009CE //_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower -{0x0F12, 0x365A}, //700009D0 //_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow -{0x0F12, 0x102A}, //700009D2 //_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow -{0x0F12, 0x000B}, //700009D4 //_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow -{0x0F12, 0x0600}, //700009D6 //_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower -{0x0F12, 0x5A0F}, //700009D8 //_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit -{0x0F12, 0x0505}, //700009DA //_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope -{0x0F12, 0x1802}, //700009DC //_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR -{0x0F12, 0x0000}, //700009DE //_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres -{0x0F12, 0x2006}, //700009E0 //_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR -{0x0F12, 0x3028}, //700009E2 //_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen -{0x0F12, 0x0418}, //700009E4 //_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh -{0x0F12, 0x0101}, //700009E6 //_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative -{0x0F12, 0x0800}, //700009E8 //_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle -{0x0F12, 0x1804}, //700009EA //_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh -{0x0F12, 0x4008}, //700009EC //_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh -{0x0F12, 0x0540}, //700009EE //_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange -{0x0F12, 0x8006}, //700009F0 //_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad -{0x0F12, 0x0020}, //700009F2 //_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal -{0x0F12, 0x0000}, //700009F4 //_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh -{0x0F12, 0x2000}, //700009F6 //_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat -{0x0F12, 0x0000}, //700009F8 //_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit -{0x0F12, 0x1E10}, //700009FA //_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff -{0x0F12, 0x000B}, //700009FC //_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 -{0x0F12, 0x0607}, //700009FE //_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 -{0x0F12, 0x0005}, //70000A00 //_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 -{0x0F12, 0x0607}, //70000A02 //_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 -{0x0F12, 0x0705}, //70000A04 //_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY -{0x0F12, 0x0206}, //70000A06 //_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm -{0x0F12, 0x0304}, //70000A08 //_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm -{0x0F12, 0x0309}, //70000A0A //_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift -{0x0F12, 0x0305}, //70000A0C //_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y -{0x0F12, 0x2006}, //70000A0E //_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y -{0x0F12, 0x1320}, //70000A10 //_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV -{0x0F12, 0x1014}, //70000A12 //_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y -{0x0F12, 0x1010}, //70000A14 //_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV -{0x0F12, 0x0C10}, //70000A16 //_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL -{0x0F12, 0x1A0C}, //70000A18 //_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL -{0x0F12, 0x4A18}, //70000A1A //_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower -{0x0F12, 0x0080}, //70000A1C //_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce -{0x0F12, 0x0350}, //70000A1E //_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset -{0x0F12, 0x0180}, //70000A20 //_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H -{0x0F12, 0x0A0A}, //70000A22 //_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C -{0x0F12, 0x0101}, //70000A24 //_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C -{0x0F12, 0x2A36}, //70000A26 //_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh -{0x0F12, 0x6024}, //70000A28 //_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower -{0x0F12, 0x2A36}, //70000A2A //_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise -{0x0F12, 0xFFFF}, //70000A2C //_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp -{0x0F12, 0x0808}, //70000A2E //_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope -{0x0F12, 0x0A01}, //70000A30 //_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin -{0x0F12, 0x010A}, //70000A32 //_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin -{0x0F12, 0x2701}, //70000A34 //_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin -{0x0F12, 0x241E}, //70000A36 //_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin -{0x0F12, 0x2E60}, //70000A38 //_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin -{0x0F12, 0xFF22}, //70000A3A //_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin -{0x0F12, 0x40FF}, //70000A3C //_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin -{0x0F12, 0x0009}, //70000A3E //_ee_iReduceEdgeSlope_Bin [7:0] -{0x0F12, 0x0001}, //70000A40 //_bnr_nClustLevel_C [0] -{0x0F12, 0x0000}, //70000A42 //_BRIGHTNESS AFIT 1 -{0x0F12, 0x0000}, //70000A44 //_CONTRAST -{0x0F12, 0x0000}, //70000A46 //_SATURATION -{0x0F12, 0x0000}, //70000A48 //_SHARP_BLUR -{0x0F12, 0x0000}, //70000A4A //_GLAMOUR -{0x0F12, 0x00C0}, //70000A4C //_bnr_edge_high -{0x0F12, 0x0064}, //70000A4E //_postdmsc_iLowBright -{0x0F12, 0x0384}, //70000A50 //_postdmsc_iHighBright -{0x0F12, 0x0051}, //70000A52 //_postdmsc_iLowSat -{0x0F12, 0x01F4}, //70000A54 //_postdmsc_iHighSat -{0x0F12, 0x0070}, //70000A56 //_postdmsc_iTune -{0x0F12, 0x0040}, //70000A58 //_yuvemix_mNegRanges_0 -{0x0F12, 0x00A0}, //70000A5A //_yuvemix_mNegRanges_1 -{0x0F12, 0x0100}, //70000A5C //_yuvemix_mNegRanges_2 -{0x0F12, 0x0010}, //70000A5E //_yuvemix_mPosRanges_0 -{0x0F12, 0x0060}, //70000A60 //_yuvemix_mPosRanges_1 -{0x0F12, 0x0100}, //70000A62 //_yuvemix_mPosRanges_2 -{0x0F12, 0x1430}, //70000A64 //_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh -{0x0F12, 0x0201}, //70000A66 //_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh -{0x0F12, 0x0204}, //70000A68 //_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh -{0x0F12, 0x2404}, //70000A6A //_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low -{0x0F12, 0x031B}, //70000A6C //_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low -{0x0F12, 0x0103}, //70000A6E //_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin -{0x0F12, 0x1205}, //70000A70 //_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow -{0x0F12, 0x400D}, //70000A72 //_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH -{0x0F12, 0x0080}, //70000A74 //_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune -{0x0F12, 0x1980}, //70000A76 //_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh -{0x0F12, 0x272E}, //70000A78 //_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh -{0x0F12, 0x0629}, //70000A7A //_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed -{0x0F12, 0x0306}, //70000A7C //_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh -{0x0F12, 0x2003}, //70000A7E //_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH -{0x0F12, 0xFF01}, //70000A80 //_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit -{0x0F12, 0x0404}, //70000A82 //_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 -{0x0F12, 0x0300}, //70000A84 //_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower -{0x0F12, 0x245A}, //70000A86 //_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow -{0x0F12, 0x1018}, //70000A88 //_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow -{0x0F12, 0x000B}, //70000A8A //_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow -{0x0F12, 0x0B00}, //70000A8C //_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower -{0x0F12, 0x5A0F}, //70000A8E //_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit -{0x0F12, 0x0505}, //70000A90 //_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope -{0x0F12, 0x1802}, //70000A92 //_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR -{0x0F12, 0x0000}, //70000A94 //_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres -{0x0F12, 0x2006}, //70000A96 //_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR -{0x0F12, 0x3828}, //70000A98 //_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen -{0x0F12, 0x0425}, //70000A9A //_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh -{0x0F12, 0x0101}, //70000A9C //_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative -{0x0F12, 0x0800}, //70000A9E //_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle -{0x0F12, 0x1004}, //70000AA0 //_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh -{0x0F12, 0x4008}, //70000AA2 //_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh -{0x0F12, 0x0540}, //70000AA4 //_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange -{0x0F12, 0x8006}, //70000AA6 //_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad -{0x0F12, 0x0020}, //70000AA8 //_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal -{0x0F12, 0x0000}, //70000AAA //_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh -{0x0F12, 0x2000}, //70000AAC //_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat -{0x0F12, 0x0000}, //70000AAE //_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit -{0x0F12, 0x1E10}, //70000AB0 //_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff -{0x0F12, 0x000B}, //70000AB2 //_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 -{0x0F12, 0x0607}, //70000AB4 //_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 -{0x0F12, 0x0005}, //70000AB6 //_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 -{0x0F12, 0x0607}, //70000AB8 //_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 -{0x0F12, 0x0405}, //70000ABA //_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY -{0x0F12, 0x0205}, //70000ABC //_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm -{0x0F12, 0x0304}, //70000ABE //_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm -{0x0F12, 0x0409}, //70000AC0 //_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift -{0x0F12, 0x0306}, //70000AC2 //_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y -{0x0F12, 0x0407}, //70000AC4 //_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y -{0x0F12, 0x2204}, //70000AC6 //_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV -{0x0F12, 0x021C}, //70000AC8 //_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y -{0x0F12, 0x1102}, //70000ACA //_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV -{0x0F12, 0x0611}, //70000ACC //_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL -{0x0F12, 0x1A02}, //70000ACE //_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL -{0x0F12, 0x8018}, //70000AD0 //_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower -{0x0F12, 0x0080}, //70000AD2 //_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce -{0x0F12, 0x0374}, //70000AD4 //_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset // -{0x0F12, 0x0180}, //70000AD6 //_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H -{0x0F12, 0x0A0A}, //70000AD8 //_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C -{0x0F12, 0x0101}, //70000ADA //_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C -{0x0F12, 0x141D}, //70000ADC //_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh -{0x0F12, 0x6024}, //70000ADE //_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower -{0x0F12, 0x1217}, //70000AE0 //_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise -{0x0F12, 0xFFFF}, //70000AE2 //_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp -{0x0F12, 0x0808}, //70000AE4 //_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope -{0x0F12, 0x0A01}, //70000AE6 //_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin -{0x0F12, 0x010A}, //70000AE8 //_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin -{0x0F12, 0x0001}, //70000AEA //_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin -{0x0F12, 0x2400}, //70000AEC //_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin -{0x0F12, 0x1660}, //70000AEE //_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin -{0x0F12, 0xFF10}, //70000AF0 //_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin -{0x0F12, 0x40FF}, //70000AF2 //_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin -{0x0F12, 0x0009}, //70000AF4 //_ee_iReduceEdgeSlope_Bin [7:0] -{0x0F12, 0x0001}, //70000AF6 //_bnr_nClustLevel_C [0] -{0x0F12, 0x0000}, //70000AF8 //_BRIGHTNESS AFIT 2 -{0x0F12, 0x0000}, //70000AFA //_CONTRAST -{0x0F12, 0x0000}, //70000AFC //_SATURATION -{0x0F12, 0x0000}, //70000AFE //_SHARP_BLUR -{0x0F12, 0x0000}, //70000B00 //_GLAMOUR -{0x0F12, 0x00C0}, //70000B02 //_bnr_edge_high -{0x0F12, 0x0064}, //70000B04 //_postdmsc_iLowBright -{0x0F12, 0x0384}, //70000B06 //_postdmsc_iHighBright -{0x0F12, 0x0043}, //70000B08 //_postdmsc_iLowSat -{0x0F12, 0x01F4}, //70000B0A //_postdmsc_iHighSat -{0x0F12, 0x0070}, //70000B0C //_postdmsc_iTune -{0x0F12, 0x0040}, //70000B0E //_yuvemix_mNegRanges_0 -{0x0F12, 0x00A0}, //70000B10 //_yuvemix_mNegRanges_1 -{0x0F12, 0x0100}, //70000B12 //_yuvemix_mNegRanges_2 -{0x0F12, 0x0010}, //70000B14 //_yuvemix_mPosRanges_0 -{0x0F12, 0x0060}, //70000B16 //_yuvemix_mPosRanges_1 -{0x0F12, 0x0100}, //70000B18 //_yuvemix_mPosRanges_2 -{0x0F12, 0x1430}, //70000B1A //_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh -{0x0F12, 0x0201}, //70000B1C //_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh -{0x0F12, 0x0204}, //70000B1E //_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh -{0x0F12, 0x1B04}, //70000B20 //_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low -{0x0F12, 0x0312}, //70000B22 //_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low -{0x0F12, 0x0003}, //70000B24 //_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin -{0x0F12, 0x0C03}, //70000B26 //_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow -{0x0F12, 0x2806}, //70000B28 //_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH -{0x0F12, 0x0060}, //70000B2A //_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune -{0x0F12, 0x1580}, //70000B2C //_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh -{0x0F12, 0x2020}, //70000B2E //_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh -{0x0F12, 0x0620}, //70000B30 //_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed -{0x0F12, 0x0306}, //70000B32 //_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh -{0x0F12, 0x2003}, //70000B34 //_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH -{0x0F12, 0xFF01}, //70000B36 //_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit -{0x0F12, 0x0404}, //70000B38 //_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 -{0x0F12, 0x0300}, //70000B3A //_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower -{0x0F12, 0x145A}, //70000B3C //_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow -{0x0F12, 0x1010}, //70000B3E //_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow -{0x0F12, 0x000B}, //70000B40 //_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow -{0x0F12, 0x0E00}, //70000B42 //_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower -{0x0F12, 0x5A0F}, //70000B44 //_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit -{0x0F12, 0x0504}, //70000B46 //_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope -{0x0F12, 0x1802}, //70000B48 //_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR -{0x0F12, 0x0000}, //70000B4A //_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres -{0x0F12, 0x2006}, //70000B4C //_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR -{0x0F12, 0x3828}, //70000B4E //_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen -{0x0F12, 0x0428}, //70000B50 //_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh -{0x0F12, 0x0101}, //70000B52 //_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative -{0x0F12, 0x8000}, //70000B54 //_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle -{0x0F12, 0x0A04}, //70000B56 //_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh -{0x0F12, 0x4008}, //70000B58 //_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh -{0x0F12, 0x0540}, //70000B5A //_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange -{0x0F12, 0x8006}, //70000B5C //_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad -{0x0F12, 0x0020}, //70000B5E //_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal -{0x0F12, 0x0000}, //70000B60 //_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh -{0x0F12, 0x2000}, //70000B62 //_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat -{0x0F12, 0x0000}, //70000B64 //_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit -{0x0F12, 0x1E10}, //70000B66 //_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff -{0x0F12, 0x000B}, //70000B68 //_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 -{0x0F12, 0x0607}, //70000B6A //_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 -{0x0F12, 0x0005}, //70000B6C //_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 -{0x0F12, 0x0607}, //70000B6E //_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 -{0x0F12, 0x0405}, //70000B70 //_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY -{0x0F12, 0x0207}, //70000B72 //_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm -{0x0F12, 0x0304}, //70000B74 //_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm -{0x0F12, 0x0409}, //70000B76 //_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift -{0x0F12, 0x0306}, //70000B78 //_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y -{0x0F12, 0x0407}, //70000B7A //_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y -{0x0F12, 0x2404}, //70000B7C //_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV -{0x0F12, 0x0221}, //70000B7E //_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y -{0x0F12, 0x1202}, //70000B80 //_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV -{0x0F12, 0x0613}, //70000B82 //_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL -{0x0F12, 0x1A02}, //70000B84 //_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL -{0x0F12, 0x8018}, //70000B86 //_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower -{0x0F12, 0x0080}, //70000B88 //_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce -{0x0F12, 0x0080}, //70000B8A //_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset // -{0x0F12, 0x0180}, //70000B8C //_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H -{0x0F12, 0x0A0A}, //70000B8E //_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C -{0x0F12, 0x0101}, //70000B90 //_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C -{0x0F12, 0x121B}, //70000B92 //_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh -{0x0F12, 0x6024}, //70000B94 //_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower -{0x0F12, 0x0C0C}, //70000B96 //_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise -{0x0F12, 0xFFFF}, //70000B98 //_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp -{0x0F12, 0x0808}, //70000B9A //_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope -{0x0F12, 0x0A01}, //70000B9C //_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin -{0x0F12, 0x010A}, //70000B9E //_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin -{0x0F12, 0x0001}, //70000BA0 //_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin -{0x0F12, 0x2400}, //70000BA2 //_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin -{0x0F12, 0x0460}, //70000BA4 //_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin -{0x0F12, 0xFF04}, //70000BA6 //_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin -{0x0F12, 0x40FF}, //70000BA8 //_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin -{0x0F12, 0x0009}, //70000BAA //_ee_iReduceEdgeSlope_Bin [7:0] -{0x0F12, 0x0001}, //70000BAC //_bnr_nClustLevel_C [0] -{0x0F12, 0x0000}, //70000BAE //_BRIGHTNESS AFIT 3 -{0x0F12, 0x0000}, //70000BB0 //_CONTRAST -{0x0F12, 0x0000}, //70000BB2 //_SATURATION -{0x0F12, 0x0000}, //70000BB4 //_SHARP_BLUR -{0x0F12, 0x0000}, //70000BB6 //_GLAMOUR -{0x0F12, 0x00C0}, //70000BB8 //_bnr_edge_high -{0x0F12, 0x0064}, //70000BBA //_postdmsc_iLowBright -{0x0F12, 0x0384}, //70000BBC //_postdmsc_iHighBright -{0x0F12, 0x0032}, //70000BBE //_postdmsc_iLowSat -{0x0F12, 0x01F4}, //70000BC0 //_postdmsc_iHighSat -{0x0F12, 0x0070}, //70000BC2 //_postdmsc_iTune -{0x0F12, 0x0040}, //70000BC4 //_yuvemix_mNegRanges_0 -{0x0F12, 0x00A0}, //70000BC6 //_yuvemix_mNegRanges_1 -{0x0F12, 0x0100}, //70000BC8 //_yuvemix_mNegRanges_2 -{0x0F12, 0x0010}, //70000BCA //_yuvemix_mPosRanges_0 -{0x0F12, 0x0060}, //70000BCC //_yuvemix_mPosRanges_1 -{0x0F12, 0x0100}, //70000BCE //_yuvemix_mPosRanges_2 -{0x0F12, 0x1430}, //70000BD0 //_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh -{0x0F12, 0x0201}, //70000BD2 //_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh -{0x0F12, 0x0204}, //70000BD4 //_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh -{0x0F12, 0x1504}, //70000BD6 //_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low -{0x0F12, 0x030F}, //70000BD8 //_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low -{0x0F12, 0x0003}, //70000BDA //_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin -{0x0F12, 0x0902}, //70000BDC //_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow -{0x0F12, 0x2004}, //70000BDE //_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH -{0x0F12, 0x0050}, //70000BE0 //_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune -{0x0F12, 0x1140}, //70000BE2 //_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh -{0x0F12, 0x201C}, //70000BE4 //_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh -{0x0F12, 0x0620}, //70000BE6 //_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed -{0x0F12, 0x0306}, //70000BE8 //_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh -{0x0F12, 0x2003}, //70000BEA //_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH -{0x0F12, 0xFF01}, //70000BEC //_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit -{0x0F12, 0x0404}, //70000BEE //_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 -{0x0F12, 0x0300}, //70000BF0 //_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower -{0x0F12, 0x145A}, //70000BF2 //_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow -{0x0F12, 0x1010}, //70000BF4 //_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow -{0x0F12, 0x000B}, //70000BF6 //_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow -{0x0F12, 0x1000}, //70000BF8 //_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower -{0x0F12, 0x5A0F}, //70000BFA //_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit -{0x0F12, 0x0503}, //70000BFC //_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope -{0x0F12, 0x1802}, //70000BFE //_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR -{0x0F12, 0x0000}, //70000C00 //_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres -{0x0F12, 0x2006}, //70000C02 //_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR -{0x0F12, 0x3C28}, //70000C04 //_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen -{0x0F12, 0x042C}, //70000C06 //_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh -{0x0F12, 0x0101}, //70000C08 //_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative -{0x0F12, 0xFF00}, //70000C0A //_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle -{0x0F12, 0x0904}, //70000C0C //_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh -{0x0F12, 0x4008}, //70000C0E //_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh -{0x0F12, 0x0540}, //70000C10 //_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange -{0x0F12, 0x8006}, //70000C12 //_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad -{0x0F12, 0x0020}, //70000C14 //_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal -{0x0F12, 0x0000}, //70000C16 //_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh -{0x0F12, 0x2000}, //70000C18 //_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat -{0x0F12, 0x0000}, //70000C1A //_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit -{0x0F12, 0x1E10}, //70000C1C //_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff -{0x0F12, 0x000B}, //70000C1E //_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 -{0x0F12, 0x0607}, //70000C20 //_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 -{0x0F12, 0x0005}, //70000C22 //_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 -{0x0F12, 0x0607}, //70000C24 //_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 -{0x0F12, 0x0405}, //70000C26 //_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY -{0x0F12, 0x0206}, //70000C28 //_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm -{0x0F12, 0x0304}, //70000C2A //_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm -{0x0F12, 0x0409}, //70000C2C //_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift -{0x0F12, 0x0305}, //70000C2E //_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y -{0x0F12, 0x0406}, //70000C30 //_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y -{0x0F12, 0x2804}, //70000C32 //_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV -{0x0F12, 0x0228}, //70000C34 //_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y -{0x0F12, 0x1402}, //70000C36 //_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV -{0x0F12, 0x0618}, //70000C38 //_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL -{0x0F12, 0x1A02}, //70000C3A //_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL -{0x0F12, 0x8018}, //70000C3C //_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower -{0x0F12, 0x0080}, //70000C3E //_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce -{0x0F12, 0x0080}, //70000C40 //_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset // -{0x0F12, 0x0180}, //70000C42 //_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H -{0x0F12, 0x0A0A}, //70000C44 //_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C -{0x0F12, 0x0101}, //70000C46 //_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C -{0x0F12, 0x0F15}, //70000C48 //_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh -{0x0F12, 0x6024}, //70000C4A //_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower -{0x0F12, 0x0A0A}, //70000C4C //_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise -{0x0F12, 0xFFFF}, //70000C4E //_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp -{0x0F12, 0x0808}, //70000C50 //_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope -{0x0F12, 0x0A01}, //70000C52 //_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin -{0x0F12, 0x010A}, //70000C54 //_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin -{0x0F12, 0x0001}, //70000C56 //_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin -{0x0F12, 0x2400}, //70000C58 //_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin -{0x0F12, 0x0260}, //70000C5A //_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin -{0x0F12, 0xFF02}, //70000C5C //_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin -{0x0F12, 0x40FF}, //70000C5E //_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin -{0x0F12, 0x0009}, //70000C60 //_ee_iReduceEdgeSlope_Bin [7:0] -{0x0F12, 0x0001}, //70000C62 //_bnr_nClustLevel_C [0] -{0x0F12, 0x0000}, //70000C64 //_BRIGHTNESS AFIT 4 -{0x0F12, 0x0000}, //70000C66 //_CONTRAST -{0x0F12, 0x0000}, //70000C68 //_SATURATION -{0x0F12, 0x0000}, //70000C6A //_SHARP_BLUR -{0x0F12, 0x0000}, //70000C6C //_GLAMOUR -{0x0F12, 0x00C0}, //70000C6E //_bnr_edge_high -{0x0F12, 0x0064}, //70000C70 //_postdmsc_iLowBright -{0x0F12, 0x0384}, //70000C72 //_postdmsc_iHighBright -{0x0F12, 0x0032}, //70000C74 //_postdmsc_iLowSat -{0x0F12, 0x01F4}, //70000C76 //_postdmsc_iHighSat -{0x0F12, 0x0070}, //70000C78 //_postdmsc_iTune -{0x0F12, 0x0040}, //70000C7A //_yuvemix_mNegRanges_0 -{0x0F12, 0x00A0}, //70000C7C //_yuvemix_mNegRanges_1 -{0x0F12, 0x0100}, //70000C7E //_yuvemix_mNegRanges_2 -{0x0F12, 0x0010}, //70000C80 //_yuvemix_mPosRanges_0 -{0x0F12, 0x0060}, //70000C82 //_yuvemix_mPosRanges_1 -{0x0F12, 0x0100}, //70000C84 //_yuvemix_mPosRanges_2 -{0x0F12, 0x1430}, //70000C86 //_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh -{0x0F12, 0x0201}, //70000C88 //_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh -{0x0F12, 0x0204}, //70000C8A //_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh -{0x0F12, 0x0F04}, //70000C8C //_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low -{0x0F12, 0x030C}, //70000C8E //_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low -{0x0F12, 0x0003}, //70000C90 //_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin -{0x0F12, 0x0602}, //70000C92 //_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow -{0x0F12, 0x1803}, //70000C94 //_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH -{0x0F12, 0x0040}, //70000C96 //_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune -{0x0F12, 0x0E20}, //70000C98 //_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh -{0x0F12, 0x2018}, //70000C9A //_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh -{0x0F12, 0x0620}, //70000C9C //_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed -{0x0F12, 0x0306}, //70000C9E //_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh -{0x0F12, 0x2003}, //70000CA0 //_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH -{0x0F12, 0xFF01}, //70000CA2 //_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit -{0x0F12, 0x0404}, //70000CA4 //_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 -{0x0F12, 0x0200}, //70000CA6 //_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower -{0x0F12, 0x145A}, //70000CA8 //_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow -{0x0F12, 0x1010}, //70000CAA //_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow -{0x0F12, 0x000B}, //70000CAC //_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow -{0x0F12, 0x1200}, //70000CAE //_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower -{0x0F12, 0x5A0F}, //70000CB0 //_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit -{0x0F12, 0x0502}, //70000CB2 //_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope -{0x0F12, 0x1802}, //70000CB4 //_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR -{0x0F12, 0x0000}, //70000CB6 //_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres -{0x0F12, 0x2006}, //70000CB8 //_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR -{0x0F12, 0x4028}, //70000CBA //_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen -{0x0F12, 0x0430}, //70000CBC //_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh -{0x0F12, 0x0101}, //70000CBE //_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative -{0x0F12, 0xFF00}, //70000CC0 //_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle -{0x0F12, 0x0804}, //70000CC2 //_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh -{0x0F12, 0x4008}, //70000CC4 //_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh -{0x0F12, 0x0540}, //70000CC6 //_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange -{0x0F12, 0x8006}, //70000CC8 //_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad -{0x0F12, 0x0020}, //70000CCA //_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal -{0x0F12, 0x0000}, //70000CCC //_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh -{0x0F12, 0x2000}, //70000CCE //_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat -{0x0F12, 0x0000}, //70000CD0 //_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit -{0x0F12, 0x1E10}, //70000CD2 //_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff -{0x0F12, 0x000B}, //70000CD4 //_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 -{0x0F12, 0x0607}, //70000CD6 //_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 -{0x0F12, 0x0005}, //70000CD8 //_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 -{0x0F12, 0x0607}, //70000CDA //_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 -{0x0F12, 0x0405}, //70000CDC //_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY -{0x0F12, 0x0205}, //70000CDE //_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm -{0x0F12, 0x0304}, //70000CE0 //_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm -{0x0F12, 0x0409}, //70000CE2 //_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift -{0x0F12, 0x0306}, //70000CE4 //_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y -{0x0F12, 0x0407}, //70000CE6 //_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y -{0x0F12, 0x2C04}, //70000CE8 //_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV -{0x0F12, 0x022C}, //70000CEA //_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y -{0x0F12, 0x1402}, //70000CEC //_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV -{0x0F12, 0x0618}, //70000CEE //_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL -{0x0F12, 0x1A02}, //70000CF0 //_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL -{0x0F12, 0x8018}, //70000CF2 //_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower -{0x0F12, 0x0080}, //70000CF4 //_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce -{0x0F12, 0x0080}, //70000CF6 //_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset // -{0x0F12, 0x0180}, //70000CF8 //_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H -{0x0F12, 0x0A0A}, //70000CFA //_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C -{0x0F12, 0x0101}, //70000CFC //_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C -{0x0F12, 0x0C0F}, //70000CFE //_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh -{0x0F12, 0x6024}, //70000D00 //_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower -{0x0F12, 0x0808}, //70000D02 //_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise -{0x0F12, 0xFFFF}, //70000D04 //_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp -{0x0F12, 0x0808}, //70000D06 //_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope -{0x0F12, 0x0A01}, //70000D08 //_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin -{0x0F12, 0x010A}, //70000D0A //_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin -{0x0F12, 0x0001}, //70000D0C //_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin -{0x0F12, 0x2400}, //70000D0E //_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin -{0x0F12, 0x0060}, //70000D10 //_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin -{0x0F12, 0xFF00}, //70000D12 //_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin -{0x0F12, 0x40FF}, //70000D14 //_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin -{0x0F12, 0x0009}, //70000D16 //_ee_iReduceEdgeSlope_Bin [7:0] -{0x0F12, 0x0001}, //70000D18 //_bnr_nClustLevel_C [0] bWideWide[1] - -{0x0F12, 0x23CE}, //70000D1A //[0]CAFITB_bnr_bypass -{0x0F12, 0xFDC8}, //70000D1C //[0]CAFITB_bnr_bSlopenessTune -{0x0F12, 0x112E}, //70000D1E //[0]CAFITB_ee_bReduceNegMedSh -{0x0F12, 0x93A5}, //70000D20 //[0]CAFITB_dmsc_bDoDesat -{0x0F12, 0xFE67}, //70000D22 //[0]CAFITB_postdmsc_bSat -{0x0F12, 0x0000}, //70000D24 //[0]CAFITB_yuviirnr_bWideY + +{0x002A,0x0484}, +{0x0F12,0x0002}, // capture flash on +{0x002A,0x183A}, +{0x0F12,0x0001}, // one frame AE +{0x002A,0x17F6}, +{0x0F12,0x023C}, // AWB R point +{0x0F12,0x0248}, // AWB B point +{0x002A,0x1840}, +{0x0F12,0x0001}, // Fls AE tune start +{0x0F12,0x0100}, // fls_afl_FlsAFIn Rin +{0x0F12,0x0120}, +{0x0F12,0x0180}, +{0x0F12,0x0200}, +{0x0F12,0x0400}, +{0x0F12,0x0800}, +{0x0F12,0x0A00}, +{0x0F12,0x1000}, +{0x0F12,0x0100}, // fls_afl_FlsAFOut Rout +{0x0F12,0x00A0}, +{0x0F12,0x0090}, +{0x0F12,0x0080}, +{0x0F12,0x0070}, +{0x0F12,0x0045}, +{0x0F12,0x0030}, +{0x0F12,0x0010}, +{0x002A,0x1884}, +{0x0F12,0x0100}, // fls_afl_FlsNBOut flash NB default +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x002A,0x1826}, +{0x0F12,0x0100}, // fls_afl_FlashWP_Weight flash NB default +{0x0F12,0x00C0}, +{0x0F12,0x0080}, +{0x0F12,0x000A}, +{0x0F12,0x0000}, +{0x0F12,0x0030}, // fls_afl_FlashWP_Weight flash NB default +{0x0F12,0x0040}, +{0x0F12,0x0048}, +{0x0F12,0x0050}, +{0x0F12,0x0060}, +{0x002A,0x4784}, +{0x0F12,0x00A0}, // TNP_Regs_FlsWeightRIn weight tune start in +{0x0F12,0x00C0}, +{0x0F12,0x00D0}, +{0x0F12,0x0100}, +{0x0F12,0x0200}, +{0x0F12,0x0300}, +{0x0F12,0x0088}, // TNP_Regs_FlsWeightROut weight tune start out +{0x0F12,0x00B0}, +{0x0F12,0x00C0}, +{0x0F12,0x0100}, +{0x0F12,0x0200}, +{0x0F12,0x0300}, +{0x0F12,0x0120}, // Fls BRIn +{0x0F12,0x0150}, +{0x0F12,0x0200}, +{0x0F12,0x003C}, // Fls BROut +{0x0F12,0x003B}, +{0x0F12,0x0026}, // brightness + //================================================================================== -// 06.Clock Setting +// 15.CCM Setting //================================================================================== -//Input Clock (Mclk) -{0x002A, 0x01F8}, -{0x0F12, 0x5DC0}, //REG_TC_IPRM_InClockLSBs -{0x002A, 0x0212}, -{0x0F12, 0x0000}, //REG_TC_IPRM_UseNPviClocks -{0x0F12, 0x0002}, //REG_TC_IPRM_UseNMipiClocks -{0x0F12, 0x0002}, //REG_TC_IPRM_NumberOfMipiLanes - -//System Clock & Output clock (Pclk) - -{0x002A, 0x021A}, -{0x0F12, 0x3A98}, //REG_TC_IPRM_OpClk4KHz_0 -{0x0F12, 0x278D}, //4F1A //REG_TC_IPRM_MinOutRate4KHz_0 -{0x0F12, 0x278D}, //4F1A //REG_TC_IPRM_MaxOutRate4KHz_0 + +{0x002A,0x08A6}, +{0x0F12,0x00C0}, // SARR_AwbCcmCord[0] +{0x0F12,0x0100}, // SARR_AwbCcmCord[1] +{0x0F12,0x0125}, // SARR_AwbCcmCord[2] +{0x0F12,0x015F}, // SARR_AwbCcmCord[3] +{0x0F12,0x017C}, // SARR_AwbCcmCord[4] +{0x0F12,0x0194}, // SARR_AwbCcmCord[5] +{0x002A,0x0898}, +{0x0F12,0x4800}, // TVAR_wbt_pBaseCcms +{0x0F12,0x7000}, +{0x002A,0x08A0}, +{0x0F12,0x48D8}, // TVAR_wbt_pOutdoorCcm +{0x0F12,0x7000}, +//Horizon +{0x002A,0x4800}, +{0x0F12,0x01EF}, // TVAR_wbt_pBaseCcms[18] +{0x0F12,0xFFCC}, // TVAR_wbt_pBaseCcms[19] +{0x0F12,0xFFE2}, // TVAR_wbt_pBaseCcms[20] +{0x0F12,0xFECE}, // TVAR_wbt_pBaseCcms[21] +{0x0F12,0x0253}, // TVAR_wbt_pBaseCcms[22] +{0x0F12,0xFF05}, // TVAR_wbt_pBaseCcms[23] +{0x0F12,0x0007}, // TVAR_wbt_pBaseCcms[24] +{0x0F12,0xFFB9}, // TVAR_wbt_pBaseCcms[25] +{0x0F12,0x0204}, // TVAR_wbt_pBaseCcms[26] +{0x0F12,0x00F7}, // TVAR_wbt_pBaseCcms[27] +{0x0F12,0x00D3}, // TVAR_wbt_pBaseCcms[28] +{0x0F12,0xFE86}, // TVAR_wbt_pBaseCcms[29] +{0x0F12,0x01E8}, // TVAR_wbt_pBaseCcms[30] +{0x0F12,0xFFB6}, // TVAR_wbt_pBaseCcms[31] +{0x0F12,0x0176}, // TVAR_wbt_pBaseCcms[32] +{0x0F12,0xFE6B}, // TVAR_wbt_pBaseCcms[33] +{0x0F12,0x0219}, // TVAR_wbt_pBaseCcms[34] +{0x0F12,0x013C}, // TVAR_wbt_pBaseCcms[35] + +// INCA A +{0x0F12,0x01EF}, // TVAR_wbt_pBaseCcms[18] +{0x0F12,0xFFCC}, // TVAR_wbt_pBaseCcms[19] +{0x0F12,0xFFE2}, // TVAR_wbt_pBaseCcms[20] +{0x0F12,0xFECE}, // TVAR_wbt_pBaseCcms[21] +{0x0F12,0x0253}, // TVAR_wbt_pBaseCcms[22] +{0x0F12,0xFF05}, // TVAR_wbt_pBaseCcms[23] +{0x0F12,0x0007}, // TVAR_wbt_pBaseCcms[24] +{0x0F12,0xFFB9}, // TVAR_wbt_pBaseCcms[25] +{0x0F12,0x0204}, // TVAR_wbt_pBaseCcms[26] +{0x0F12,0x00F7}, // TVAR_wbt_pBaseCcms[27] +{0x0F12,0x00D3}, // TVAR_wbt_pBaseCcms[28] +{0x0F12,0xFE86}, // TVAR_wbt_pBaseCcms[29] +{0x0F12,0x01E8}, // TVAR_wbt_pBaseCcms[30] +{0x0F12,0xFFB6}, // TVAR_wbt_pBaseCcms[31] +{0x0F12,0x0176}, // TVAR_wbt_pBaseCcms[32] +{0x0F12,0xFE6B}, // TVAR_wbt_pBaseCcms[33] +{0x0F12,0x0219}, // TVAR_wbt_pBaseCcms[34] +{0x0F12,0x013C}, // TVAR_wbt_pBaseCcms[35 + +//Warm White +{0x0F12,0x01EF}, // TVAR_wbt_pBaseCcms[18] +{0x0F12,0xFFCC}, // TVAR_wbt_pBaseCcms[19] +{0x0F12,0xFFE2}, // TVAR_wbt_pBaseCcms[20] +{0x0F12,0xFECE}, // TVAR_wbt_pBaseCcms[21] +{0x0F12,0x0253}, // TVAR_wbt_pBaseCcms[22] +{0x0F12,0xFF05}, // TVAR_wbt_pBaseCcms[23] +{0x0F12,0x0007}, // TVAR_wbt_pBaseCcms[24] +{0x0F12,0xFFB9}, // TVAR_wbt_pBaseCcms[25] +{0x0F12,0x0204}, // TVAR_wbt_pBaseCcms[26] +{0x0F12,0x00F7}, // TVAR_wbt_pBaseCcms[27] +{0x0F12,0x00D3}, // TVAR_wbt_pBaseCcms[28] +{0x0F12,0xFE86}, // TVAR_wbt_pBaseCcms[29] +{0x0F12,0x01E8}, // TVAR_wbt_pBaseCcms[30] +{0x0F12,0xFFB6}, // TVAR_wbt_pBaseCcms[31] +{0x0F12,0x0176}, // TVAR_wbt_pBaseCcms[32] +{0x0F12,0xFE6B}, // TVAR_wbt_pBaseCcms[33] +{0x0F12,0x0219}, // TVAR_wbt_pBaseCcms[34] +{0x0F12,0x013C}, // TVAR_wbt_pBaseCcms[35 + +//Cool White +{0x0F12,0x01CA}, //TVAR_wbt_pBaseCcms[54] +{0x0F12,0xFFDA}, //TVAR_wbt_pBaseCcms[55] +{0x0F12,0xFFFA}, //TVAR_wbt_pBaseCcms[56] +{0x0F12,0xFF27}, //TVAR_wbt_pBaseCcms[57] +{0x0F12,0x01AC}, //TVAR_wbt_pBaseCcms[58] +{0x0F12,0xFF4D}, //TVAR_wbt_pBaseCcms[59] +{0x0F12,0x002D}, //TVAR_wbt_pBaseCcms[60] +{0x0F12,0xFFF6}, //TVAR_wbt_pBaseCcms[61] +{0x0F12,0x01A5}, //TVAR_wbt_pBaseCcms[62] +{0x0F12,0x00BF}, //TVAR_wbt_pBaseCcms[63] +{0x0F12,0x009B}, //TVAR_wbt_pBaseCcms[64] +{0x0F12,0xFEFA}, //TVAR_wbt_pBaseCcms[65] +{0x0F12,0x01EF}, //TVAR_wbt_pBaseCcms[66] +{0x0F12,0xFF98}, //TVAR_wbt_pBaseCcms[67] +{0x0F12,0x0180}, //TVAR_wbt_pBaseCcms[68] +{0x0F12,0xFF20}, //TVAR_wbt_pBaseCcms[69] +{0x0F12,0x019F}, //TVAR_wbt_pBaseCcms[70] +{0x0F12,0x010C}, //TVAR_wbt_pBaseCcms[71] + +//D50 +{0x0F12,0x01CA}, //TVAR_wbt_pBaseCcms[54] +{0x0F12,0xFFDA}, //TVAR_wbt_pBaseCcms[55] +{0x0F12,0xFFFA}, //TVAR_wbt_pBaseCcms[56] +{0x0F12,0xFF27}, //TVAR_wbt_pBaseCcms[57] +{0x0F12,0x01AC}, //TVAR_wbt_pBaseCcms[58] +{0x0F12,0xFF4D}, //TVAR_wbt_pBaseCcms[59] +{0x0F12,0x002D}, //TVAR_wbt_pBaseCcms[60] +{0x0F12,0xFFF6}, //TVAR_wbt_pBaseCcms[61] +{0x0F12,0x01A5}, //TVAR_wbt_pBaseCcms[62] +{0x0F12,0x00BF}, //TVAR_wbt_pBaseCcms[63] +{0x0F12,0x009B}, //TVAR_wbt_pBaseCcms[64] +{0x0F12,0xFEFA}, //TVAR_wbt_pBaseCcms[65] +{0x0F12,0x01EF}, //TVAR_wbt_pBaseCcms[66] +{0x0F12,0xFF98}, //TVAR_wbt_pBaseCcms[67] +{0x0F12,0x0180}, //TVAR_wbt_pBaseCcms[68] +{0x0F12,0xFF20}, //TVAR_wbt_pBaseCcms[69] +{0x0F12,0x019F}, //TVAR_wbt_pBaseCcms[70] +{0x0F12,0x010C}, //TVAR_wbt_pBaseCcms[71] + +//D65 +{0x0F12,0x0204}, // TVAR_wbt_pBaseCcms[90] +{0x0F12,0xFFB2}, // TVAR_wbt_pBaseCcms[91] +{0x0F12,0xFFF5}, // TVAR_wbt_pBaseCcms[92] +{0x0F12,0xFEF1}, // TVAR_wbt_pBaseCcms[93] +{0x0F12,0x014E}, // TVAR_wbt_pBaseCcms[94] +{0x0F12,0xFF18}, // TVAR_wbt_pBaseCcms[95] +{0x0F12,0xFFE6}, // TVAR_wbt_pBaseCcms[96] +{0x0F12,0xFFDD}, // TVAR_wbt_pBaseCcms[97] +{0x0F12,0x01B2}, // TVAR_wbt_pBaseCcms[98] +{0x0F12,0x00F2}, // TVAR_wbt_pBaseCcms[99] +{0x0F12,0x00CA}, // TVAR_wbt_pBaseCcms[100] +{0x0F12,0xFF48}, // TVAR_wbt_pBaseCcms[101] +{0x0F12,0x0151}, // TVAR_wbt_pBaseCcms[102] +{0x0F12,0xFF50}, // TVAR_wbt_pBaseCcms[103] +{0x0F12,0x0147}, // TVAR_wbt_pBaseCcms[104] +{0x0F12,0xFF75}, // TVAR_wbt_pBaseCcms[105] +{0x0F12,0x0187}, // TVAR_wbt_pBaseCcms[106] +{0x0F12,0x01BF}, // TVAR_wbt_pBaseCcms[107] + +//Outdoor +{0x0F12,0x01E5}, // TVAR_wbt_pOutdoorCcm[0] +{0x0F12,0xFFA4}, // TVAR_wbt_pOutdoorCcm[1] +{0x0F12,0xFFDC}, // TVAR_wbt_pOutdoorCcm[2] +{0x0F12,0xFE90}, // TVAR_wbt_pOutdoorCcm[3] +{0x0F12,0x013F}, // TVAR_wbt_pOutdoorCcm[4] +{0x0F12,0xFF1B}, // TVAR_wbt_pOutdoorCcm[5] +{0x0F12,0xFFD2}, // TVAR_wbt_pOutdoorCcm[6] +{0x0F12,0xFFDF}, // TVAR_wbt_pOutdoorCcm[7] +{0x0F12,0x0236}, // TVAR_wbt_pOutdoorCcm[8] +{0x0F12,0x00EC}, // TVAR_wbt_pOutdoorCcm[9] +{0x0F12,0x00F8}, // TVAR_wbt_pOutdoorCcm[10] +{0x0F12,0xFF34}, // TVAR_wbt_pOutdoorCcm[11] +{0x0F12,0x01CE}, // TVAR_wbt_pOutdoorCcm[12] +{0x0F12,0xFF83}, // TVAR_wbt_pOutdoorCcm[13] +{0x0F12,0x0195}, // TVAR_wbt_pOutdoorCcm[14] +{0x0F12,0xFEF3}, // TVAR_wbt_pOutdoorCcm[15] +{0x0F12,0x0126}, // TVAR_wbt_pOutdoorCcm[16] +{0x0F12,0x0162}, // TVAR_wbt_pOutdoorCcm[17] + -{0x0F12, 0x4F1A}, //REG_TC_IPRM_OpClk4KHz_11 -{0x0F12, 0x278D}, //4F1A //REG_TC_IPRM_MinOutRate4KHz_1 -{0x0F12, 0x278D}, //4F1A //REG_TC_IPRM_MaxOutRate4KHz_1 -{0x002A, 0x022C}, -{0x0F12, 0x0001}, //REG_TC_IPRM_InitParamsUpdated +//================================================================================== +// 16.GAMMA +//================================================================================== +{0x002A,0x0734}, +{0x0F12,0x0000}, // saRR_usDualGammaLutRGBIndoor[0][0] +{0x0F12,0x0004}, // saRR_usDualGammaLutRGBIndoor[0][1] +{0x0F12,0x000B}, // saRR_usDualGammaLutRGBIndoor[0][2] +{0x0F12,0x001B}, // saRR_usDualGammaLutRGBIndoor[0][3] +{0x0F12,0x0046}, // saRR_usDualGammaLutRGBIndoor[0][4] +{0x0F12,0x00AE}, // saRR_usDualGammaLutRGBIndoor[0][5] +{0x0F12,0x011E}, // saRR_usDualGammaLutRGBIndoor[0][6] +{0x0F12,0x0154}, // saRR_usDualGammaLutRGBIndoor[0][7] +{0x0F12,0x0184}, // saRR_usDualGammaLutRGBIndoor[0][8] +{0x0F12,0x01C6}, // saRR_usDualGammaLutRGBIndoor[0][9] +{0x0F12,0x01F8}, // saRR_usDualGammaLutRGBIndoor[0][10] +{0x0F12,0x0222}, // saRR_usDualGammaLutRGBIndoor[0][11] +{0x0F12,0x0247}, // saRR_usDualGammaLutRGBIndoor[0][12] +{0x0F12,0x0282}, // saRR_usDualGammaLutRGBIndoor[0][13] +{0x0F12,0x02B5}, // saRR_usDualGammaLutRGBIndoor[0][14] +{0x0F12,0x030F}, // saRR_usDualGammaLutRGBIndoor[0][15] +{0x0F12,0x035F}, // saRR_usDualGammaLutRGBIndoor[0][16] +{0x0F12,0x03A2}, // saRR_usDualGammaLutRGBIndoor[0][17] +{0x0F12,0x03D8}, // saRR_usDualGammaLutRGBIndoor[0][18] +{0x0F12,0x03FF}, // saRR_usDualGammaLutRGBIndoor[0][19] +{0x0F12,0x0000}, // saRR_usDualGammaLutRGBIndoor[0][0] +{0x0F12,0x0004}, // saRR_usDualGammaLutRGBIndoor[0][1] +{0x0F12,0x000B}, // saRR_usDualGammaLutRGBIndoor[0][2] +{0x0F12,0x001B}, // saRR_usDualGammaLutRGBIndoor[0][3] +{0x0F12,0x0046}, // saRR_usDualGammaLutRGBIndoor[0][4] +{0x0F12,0x00AE}, // saRR_usDualGammaLutRGBIndoor[0][5] +{0x0F12,0x011E}, // saRR_usDualGammaLutRGBIndoor[0][6] +{0x0F12,0x0154}, // saRR_usDualGammaLutRGBIndoor[0][7] +{0x0F12,0x0184}, // saRR_usDualGammaLutRGBIndoor[0][8] +{0x0F12,0x01C6}, // saRR_usDualGammaLutRGBIndoor[0][9] +{0x0F12,0x01F8}, // saRR_usDualGammaLutRGBIndoor[0][10] +{0x0F12,0x0222}, // saRR_usDualGammaLutRGBIndoor[0][11] +{0x0F12,0x0247}, // saRR_usDualGammaLutRGBIndoor[0][12] +{0x0F12,0x0282}, // saRR_usDualGammaLutRGBIndoor[0][13] +{0x0F12,0x02B5}, // saRR_usDualGammaLutRGBIndoor[0][14] +{0x0F12,0x030F}, // saRR_usDualGammaLutRGBIndoor[0][15] +{0x0F12,0x035F}, // saRR_usDualGammaLutRGBIndoor[0][16] +{0x0F12,0x03A2}, // saRR_usDualGammaLutRGBIndoor[0][17] +{0x0F12,0x03D8}, // saRR_usDualGammaLutRGBIndoor[0][18] +{0x0F12,0x03FF}, // saRR_usDualGammaLutRGBIndoor[0][19] +{0x0F12,0x0000}, // saRR_usDualGammaLutRGBIndoor[0][0] +{0x0F12,0x0004}, // saRR_usDualGammaLutRGBIndoor[0][1] +{0x0F12,0x000B}, // saRR_usDualGammaLutRGBIndoor[0][2] +{0x0F12,0x001B}, // saRR_usDualGammaLutRGBIndoor[0][3] +{0x0F12,0x0046}, // saRR_usDualGammaLutRGBIndoor[0][4] +{0x0F12,0x00AE}, // saRR_usDualGammaLutRGBIndoor[0][5] +{0x0F12,0x011E}, // saRR_usDualGammaLutRGBIndoor[0][6] +{0x0F12,0x0154}, // saRR_usDualGammaLutRGBIndoor[0][7] +{0x0F12,0x0184}, // saRR_usDualGammaLutRGBIndoor[0][8] +{0x0F12,0x01C6}, // saRR_usDualGammaLutRGBIndoor[0][9] +{0x0F12,0x01F8}, // saRR_usDualGammaLutRGBIndoor[0][10] +{0x0F12,0x0222}, // saRR_usDualGammaLutRGBIndoor[0][11] +{0x0F12,0x0247}, // saRR_usDualGammaLutRGBIndoor[0][12] +{0x0F12,0x0282}, // saRR_usDualGammaLutRGBIndoor[0][13] +{0x0F12,0x02B5}, // saRR_usDualGammaLutRGBIndoor[0][14] +{0x0F12,0x030F}, // saRR_usDualGammaLutRGBIndoor[0][15] +{0x0F12,0x035F}, // saRR_usDualGammaLutRGBIndoor[0][16] +{0x0F12,0x03A2}, // saRR_usDualGammaLutRGBIndoor[0][17] +{0x0F12,0x03D8}, // saRR_usDualGammaLutRGBIndoor[0][18] +{0x0F12,0x03FF}, // saRR_usDualGammaLutRGBIndoor[0][19] +{0x0F12,0x0000}, // saRR_usDualGammaLutRGBIndoor[0][0] +{0x0F12,0x0004}, // saRR_usDualGammaLutRGBIndoor[0][1] +{0x0F12,0x000B}, // saRR_usDualGammaLutRGBIndoor[0][2] +{0x0F12,0x001B}, // saRR_usDualGammaLutRGBIndoor[0][3] +{0x0F12,0x0046}, // saRR_usDualGammaLutRGBIndoor[0][4] +{0x0F12,0x00AE}, // saRR_usDualGammaLutRGBIndoor[0][5] +{0x0F12,0x011E}, // saRR_usDualGammaLutRGBIndoor[0][6] +{0x0F12,0x0154}, // saRR_usDualGammaLutRGBIndoor[0][7] +{0x0F12,0x0184}, // saRR_usDualGammaLutRGBIndoor[0][8] +{0x0F12,0x01C6}, // saRR_usDualGammaLutRGBIndoor[0][9] +{0x0F12,0x01F8}, // saRR_usDualGammaLutRGBIndoor[0][10] +{0x0F12,0x0222}, // saRR_usDualGammaLutRGBIndoor[0][11] +{0x0F12,0x0247}, // saRR_usDualGammaLutRGBIndoor[0][12] +{0x0F12,0x0282}, // saRR_usDualGammaLutRGBIndoor[0][13] +{0x0F12,0x02B5}, // saRR_usDualGammaLutRGBIndoor[0][14] +{0x0F12,0x030F}, // saRR_usDualGammaLutRGBIndoor[0][15] +{0x0F12,0x035F}, // saRR_usDualGammaLutRGBIndoor[0][16] +{0x0F12,0x03A2}, // saRR_usDualGammaLutRGBIndoor[0][17] +{0x0F12,0x03D8}, // saRR_usDualGammaLutRGBIndoor[0][18] +{0x0F12,0x03FF}, // saRR_usDualGammaLutRGBIndoor[0][19] +{0x0F12,0x0000}, // saRR_usDualGammaLutRGBIndoor[0][0] +{0x0F12,0x0004}, // saRR_usDualGammaLutRGBIndoor[0][1] +{0x0F12,0x000B}, // saRR_usDualGammaLutRGBIndoor[0][2] +{0x0F12,0x001B}, // saRR_usDualGammaLutRGBIndoor[0][3] +{0x0F12,0x0046}, // saRR_usDualGammaLutRGBIndoor[0][4] +{0x0F12,0x00AE}, // saRR_usDualGammaLutRGBIndoor[0][5] +{0x0F12,0x011E}, // saRR_usDualGammaLutRGBIndoor[0][6] +{0x0F12,0x0154}, // saRR_usDualGammaLutRGBIndoor[0][7] +{0x0F12,0x0184}, // saRR_usDualGammaLutRGBIndoor[0][8] +{0x0F12,0x01C6}, // saRR_usDualGammaLutRGBIndoor[0][9] +{0x0F12,0x01F8}, // saRR_usDualGammaLutRGBIndoor[0][10] +{0x0F12,0x0222}, // saRR_usDualGammaLutRGBIndoor[0][11] +{0x0F12,0x0247}, // saRR_usDualGammaLutRGBIndoor[0][12] +{0x0F12,0x0282}, // saRR_usDualGammaLutRGBIndoor[0][13] +{0x0F12,0x02B5}, // saRR_usDualGammaLutRGBIndoor[0][14] +{0x0F12,0x030F}, // saRR_usDualGammaLutRGBIndoor[0][15] +{0x0F12,0x035F}, // saRR_usDualGammaLutRGBIndoor[0][16] +{0x0F12,0x03A2}, // saRR_usDualGammaLutRGBIndoor[0][17] +{0x0F12,0x03D8}, // saRR_usDualGammaLutRGBIndoor[0][18] +{0x0F12,0x03FF}, // saRR_usDualGammaLutRGBIndoor[0][19] //================================================================================== -// 08.Preview & Capture Configration Setting +// 17.AFIT //================================================================================== -//Preview config[0] 64480 7.5~15fps -{0x002A, 0x02A6}, -{0x0F12, 0x0280}, //REG_0TC_PCFG_usWidth -{0x0F12, 0x01E0}, //REG_0TC_PCFG_usHeight -{0x0F12, 0x0005}, //REG_0TC_PCFG_Format -{0x0F12, 0x278D}, //4F1A //REG_0TC_PCFG_usMaxOut4KHzRate -{0x0F12, 0x278D}, //4F1A //REG_0TC_PCFG_usMinOut4KHzRate -{0x0F12, 0x0100}, //REG_0TC_PCFG_OutClkPerPix88 -{0x0F12, 0x0300}, //REG_0TC_PCFG_uBpp88 -{0x0F12, 0x0002}, //REG_0TC_PCFG_PVIMask -{0x0F12, 0x0000}, //REG_0TC_PCFG_OIFMask -{0x0F12, 0x01E0}, //REG_0TC_PCFG_usJpegPacketSize -{0x0F12, 0x0000}, //REG_0TC_PCFG_usJpegTotalPackets -{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd -{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType -{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType -{0x0F12, 0x03E8}, //029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x014A}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 -{0x002A, 0x02D0}, -{0x0F12, 0x0002}, //REG_0TC_PCFG_uPrevMirror -{0x0F12, 0x0002}, //REG_0TC_PCFG_uCaptureMirror - -//Capture Config[0] 2561920 7.5~15fps -{0x002A, 0x0396}, -{0x0F12, 0x0001}, //REG_0TC_CCFG_uCaptureMode -{0x0F12, 0x0A00}, //REG_0TC_CCFG_usWidth -{0x0F12, 0x0780}, //REG_0TC_CCFG_usHeight -{0x0F12, 0x0005}, //REG_0TC_CCFG_Format -{0x0F12, 0x278D}, //4F1A //REG_0TC_CCFG_usMaxOut4KHzRate -{0x0F12, 0x278D}, //4F1A //REG_0TC_CCFG_usMinOut4KHzRate -{0x0F12, 0x0100}, //REG_0TC_CCFG_OutClkPerPix88 -{0x0F12, 0x0300}, //REG_0TC_CCFG_uBpp88 -{0x0F12, 0x0002}, //REG_0TC_CCFG_PVIMask -{0x0F12, 0x0070}, //REG_0TC_CCFG_OIFMask -{0x0F12, 0x0810}, //REG_0TC_CCFG_usJpegPacketSize -{0x0F12, 0x0900}, //REG_0TC_CCFG_usJpegTotalPackets -{0x0F12, 0x0001}, //REG_0TC_CCFG_uClockInd -{0x0F12, 0x0000}, //REG_0TC_CCFG_usFrTimeType -{0x0F12, 0x0002}, //REG_0TC_CCFG_FrRateQualityType -{0x0F12, 0x07d0}, //REG_0TC_CCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x07d0}, //REG_0TC_CCFG_usMinFrTimeMsecMult10 +{0x002A,0x0944}, +{0x0F12,0x0050}, // afit_uNoiseIndInDoor +{0x0F12,0x00B0}, // afit_uNoiseIndInDoor +{0x0F12,0x0196}, // afit_uNoiseIndInDoor +{0x0F12,0x0245}, // afit_uNoiseIndInDoor +{0x0F12,0x0300}, // afit_uNoiseIndInDoor +{0x002A,0x0938}, +{0x0F12,0x0000}, // on/off AFIT by NB option +{0x0F12,0x0014}, // SARR_uNormBrInDoor +{0x0F12,0x00D2}, // SARR_uNormBrInDoor +{0x0F12,0x0384}, // SARR_uNormBrInDoor +{0x0F12,0x07D0}, // SARR_uNormBrInDoor +{0x0F12,0x1388}, // SARR_uNormBrInDoor +{0x002A,0x0976}, +{0x0F12,0x0070}, // afit_usGamutTh +{0x0F12,0x0005}, // afit_usNeargrayOffset +{0x0F12,0x0000}, // afit_bUseSenBpr +{0x0F12,0x01CC}, // afit_usBprThr_0_ +{0x0F12,0x01CC}, // afit_usBprThr_1_ +{0x0F12,0x01CC}, // afit_usBprThr_2_ +{0x0F12,0x01CC}, // afit_usBprThr_3_ +{0x0F12,0x01CC}, // afit_usBprThr_4_ +{0x0F12,0x0180}, // afit_NIContrastAFITValue +{0x0F12,0x0196}, // afit_NIContrastTh +{0x002A,0x098C}, +{0x0F12,0x0000}, // 7000098C//AFIT16_BRIGHTNESS +{0x0F12,0xFFE0}, // 7000098E//AFIT16_CONTRAST +{0x0F12,0x0000}, // 70000990//AFIT16_SATURATION +{0x0F12,0xFFC6}, // 70000992//AFIT16_SHARP_BLUR +{0x0F12,0x0000}, // 70000994//AFIT16_GLAMOUR +{0x0F12,0x00C0}, // 70000996//AFIT16_bnr_edge_high +{0x0F12,0x0064}, // 70000998//AFIT16_postdmsc_iLowBright +{0x0F12,0x0384}, // 7000099A//AFIT16_postdmsc_iHighBright +{0x0F12,0x005F}, // 7000099C//AFIT16_postdmsc_iLowSat +{0x0F12,0x01F4}, // 7000099E//AFIT16_postdmsc_iHighSat +{0x0F12,0x0070}, // 700009A0//AFIT16_postdmsc_iTune +{0x0F12,0x0040}, // 700009A2//AFIT16_yuvemix_mNegRanges_0 +{0x0F12,0x00A0}, // 700009A4//AFIT16_yuvemix_mNegRanges_1 +{0x0F12,0x0100}, // 700009A6//AFIT16_yuvemix_mNegRanges_2 +{0x0F12,0x0010}, // 700009A8//AFIT16_yuvemix_mPosRanges_0 +{0x0F12,0x0040}, // 700009AA//AFIT16_yuvemix_mPosRanges_1 +{0x0F12,0x00A0}, // 700009AC//AFIT16_yuvemix_mPosRanges_2 +{0x0F12,0x1430}, // 700009AE//AFIT8_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh +{0x0F12,0x0201}, // 700009B0//AFIT8_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh +{0x0F12,0x0204}, // 700009B2//AFIT8_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh +{0x0F12,0x3604}, // 700009B4//AFIT8_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low +{0x0F12,0x032A}, // 700009B6//AFIT8_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low +{0x0F12,0x0403}, // 700009B8//AFIT8_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin +{0x0F12,0x1B06}, // 700009BA//AFIT8_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow +{0x0F12,0x6015}, // 700009BC//AFIT8_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH +{0x0F12,0x00C0}, // 700009BE//AFIT8_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune +{0x0F12,0x6080}, // 700009C0//AFIT8_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh +{0x0F12,0x4080}, // 700009C2//AFIT8_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh +{0x0F12,0x0640}, // 700009C4//AFIT8_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed +{0x0F12,0x0306}, // 700009C6//AFIT8_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh +{0x0F12,0x2003}, // 700009C8//AFIT8_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH +{0x0F12,0xFF01}, // 700009CA//AFIT8_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit +{0x0F12,0x0000}, // 700009CC//AFIT8_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 +{0x0F12,0x0400}, // 700009CE//AFIT8_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower +{0x0F12,0x365A}, // 700009D0//AFIT8_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow +{0x0F12,0x102A}, // 700009D2//AFIT8_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow +{0x0F12,0x000B}, // 700009D4//AFIT8_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow +{0x0F12,0x0600}, // 700009D6//AFIT8_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower +{0x0F12,0x5A0F}, // 700009D8//AFIT8_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit +{0x0F12,0x0505}, // 700009DA//AFIT8_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope +{0x0F12,0x1802}, // 700009DC//AFIT8_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR +{0x0F12,0x0000}, // 700009DE//AFIT8_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres +{0x0F12,0x2006}, // 700009E0//AFIT8_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR +{0x0F12,0x3028}, // 700009E2//AFIT8_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen +{0x0F12,0x0418}, // 700009E4//AFIT8_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh +{0x0F12,0x0101}, // 700009E6//AFIT8_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative +{0x0F12,0x0800}, // 700009E8//AFIT8_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle +{0x0F12,0x1804}, // 700009EA//AFIT8_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh +{0x0F12,0x4008}, // 700009EC//AFIT8_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh +{0x0F12,0x0540}, // 700009EE//AFIT8_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange +{0x0F12,0x8006}, // 700009F0//AFIT8_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad +{0x0F12,0x0020}, // 700009F2//AFIT8_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal +{0x0F12,0x0000}, // 700009F4//AFIT8_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh +{0x0F12,0x1800}, // 700009F6//AFIT8_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat +{0x0F12,0x0000}, // 700009F8//AFIT8_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit +{0x0F12,0x1E10}, // 700009FA//AFIT8_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff +{0x0F12,0x000B}, // 700009FC//AFIT8_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 +{0x0F12,0x0607}, // 700009FE//AFIT8_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 +{0x0F12,0x0005}, // 70000A00//AFIT8_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 +{0x0F12,0x0607}, // 70000A02//AFIT8_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 +{0x0F12,0x0405}, // 70000A04//AFIT8_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY +{0x0F12,0x0205}, // 70000A06//AFIT8_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm +{0x0F12,0x0304}, // 70000A08//AFIT8_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm +{0x0F12,0x0409}, // 70000A0A//AFIT8_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift +{0x0F12,0x0306}, // 70000A0C//AFIT8_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y +{0x0F12,0x0407}, // 70000A0E//AFIT8_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y +{0x0F12,0x1C04}, // 70000A10//AFIT8_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV +{0x0F12,0x0214}, // 70000A12//AFIT8_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y +{0x0F12,0x1002}, // 70000A14//AFIT8_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV +{0x0F12,0x0610}, // 70000A16//AFIT8_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL +{0x0F12,0x1A02}, // 70000A18//AFIT8_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL +{0x0F12,0x4A18}, // 70000A1A//AFIT8_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower +{0x0F12,0x0080}, // 70000A1C//AFIT8_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce +{0x0F12,0x0348}, // 70000A1E//AFIT8_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset +{0x0F12,0x0180}, // 70000A20//AFIT8_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H +{0x0F12,0x0A0A}, // 70000A22//AFIT8_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C +{0x0F12,0x0101}, // 70000A24//AFIT8_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C +{0x0F12,0x2A78}, // 70000A26//AFIT8_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh +{0x0F12,0x6024}, // 70000A28//AFIT8_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower +{0x0F12,0x2A74}, // 70000A2A//AFIT8_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise +{0x0F12,0xFFFF}, // 70000A2C//AFIT8_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp +{0x0F12,0x0808}, // 70000A2E//AFIT8_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope +{0x0F12,0x0A01}, // 70000A30//AFIT8_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin +{0x0F12,0x010A}, // 70000A32//AFIT8_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin +{0x0F12,0x3601}, // 70000A34//AFIT8_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin +{0x0F12,0x242A}, // 70000A36//AFIT8_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin +{0x0F12,0x3660}, // 70000A38//AFIT8_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin +{0x0F12,0xFF2A}, // 70000A3A//AFIT8_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin +{0x0F12,0x08FF}, // 70000A3C//AFIT8_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin +{0x0F12,0x0008}, // 70000A3E//AFIT8_ee_iReduceEdgeSlope_Bin [7:0] +{0x0F12,0x0001}, // 70000A40//AFITB_bnr_nClustLevel_C [0] +{0x0F12,0x0000}, // 70000A42//AFIT16_BRIGHTNESS +{0x0F12,0x000C}, // 70000A44//AFIT16_CONTRAST +{0x0F12,0x0010}, // 70000A46//AFIT16_SATURATION +{0x0F12,0x0000}, // 70000A48//AFIT16_SHARP_BLUR +{0x0F12,0x0000}, // 70000A4A//AFIT16_GLAMOUR +{0x0F12,0x00C0}, // 70000A4C//AFIT16_bnr_edge_high +{0x0F12,0x0064}, // 70000A4E//AFIT16_postdmsc_iLowBright +{0x0F12,0x0384}, // 70000A50//AFIT16_postdmsc_iHighBright +{0x0F12,0x0051}, // 70000A52//AFIT16_postdmsc_iLowSat +{0x0F12,0x01F4}, // 70000A54//AFIT16_postdmsc_iHighSat +{0x0F12,0x0070}, // 70000A56//AFIT16_postdmsc_iTune +{0x0F12,0x0040}, // 70000A58//AFIT16_yuvemix_mNegRanges_0 +{0x0F12,0x00A0}, // 70000A5A//AFIT16_yuvemix_mNegRanges_1 +{0x0F12,0x0100}, // 70000A5C//AFIT16_yuvemix_mNegRanges_2 +{0x0F12,0x0010}, // 70000A5E//AFIT16_yuvemix_mPosRanges_0 +{0x0F12,0x0060}, // 70000A60//AFIT16_yuvemix_mPosRanges_1 +{0x0F12,0x0100}, // 70000A62//AFIT16_yuvemix_mPosRanges_2 +{0x0F12,0x1430}, // 70000A64//AFIT8_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh +{0x0F12,0x0201}, // 70000A66//AFIT8_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh +{0x0F12,0x0204}, // 70000A68//AFIT8_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh +{0x0F12,0x2404}, // 70000A6A//AFIT8_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low +{0x0F12,0x031B}, // 70000A6C//AFIT8_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low +{0x0F12,0x0103}, // 70000A6E//AFIT8_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin +{0x0F12,0x1205}, // 70000A70//AFIT8_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow +{0x0F12,0x400D}, // 70000A72//AFIT8_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH +{0x0F12,0x0080}, // 70000A74//AFIT8_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune +{0x0F12,0x2080}, // 70000A76//AFIT8_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh +{0x0F12,0x3040}, // 70000A78//AFIT8_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh +{0x0F12,0x0630}, // 70000A7A//AFIT8_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed +{0x0F12,0x0306}, // 70000A7C//AFIT8_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh +{0x0F12,0x2003}, // 70000A7E//AFIT8_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH +{0x0F12,0xFF01}, // 70000A80//AFIT8_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit +{0x0F12,0x0404}, // 70000A82//AFIT8_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 +{0x0F12,0x0300}, // 70000A84//AFIT8_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower +{0x0F12,0x245A}, // 70000A86//AFIT8_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow +{0x0F12,0x1018}, // 70000A88//AFIT8_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow +{0x0F12,0x000B}, // 70000A8A//AFIT8_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow +{0x0F12,0x0B00}, // 70000A8C//AFIT8_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower +{0x0F12,0x5A0F}, // 70000A8E//AFIT8_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit +{0x0F12,0x0505}, // 70000A90//AFIT8_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope +{0x0F12,0x1802}, // 70000A92//AFIT8_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR +{0x0F12,0x0000}, // 70000A94//AFIT8_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres +{0x0F12,0x2006}, // 70000A96//AFIT8_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR +{0x0F12,0x3428}, // 70000A98//AFIT8_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen +{0x0F12,0x041C}, // 70000A9A//AFIT8_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh +{0x0F12,0x0101}, // 70000A9C//AFIT8_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative +{0x0F12,0x0800}, // 70000A9E//AFIT8_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle +{0x0F12,0x1004}, // 70000AA0//AFIT8_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh +{0x0F12,0x4008}, // 70000AA2//AFIT8_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh +{0x0F12,0x0540}, // 70000AA4//AFIT8_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange +{0x0F12,0x8006}, // 70000AA6//AFIT8_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad +{0x0F12,0x0020}, // 70000AA8//AFIT8_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal +{0x0F12,0x0000}, // 70000AAA//AFIT8_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh +{0x0F12,0x1800}, // 70000AAC//AFIT8_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat +{0x0F12,0x0000}, // 70000AAE//AFIT8_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit +{0x0F12,0x1E10}, // 70000AB0//AFIT8_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff +{0x0F12,0x000B}, // 70000AB2//AFIT8_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 +{0x0F12,0x0607}, // 70000AB4//AFIT8_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 +{0x0F12,0x0005}, // 70000AB6//AFIT8_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 +{0x0F12,0x0607}, // 70000AB8//AFIT8_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 +{0x0F12,0x0405}, // 70000ABA//AFIT8_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY +{0x0F12,0x0205}, // 70000ABC//AFIT8_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm +{0x0F12,0x0304}, // 70000ABE//AFIT8_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm +{0x0F12,0x0409}, // 70000AC0//AFIT8_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift +{0x0F12,0x0306}, // 70000AC2//AFIT8_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y +{0x0F12,0x0407}, // 70000AC4//AFIT8_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y +{0x0F12,0x1F04}, // 70000AC6//AFIT8_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV +{0x0F12,0x0218}, // 70000AC8//AFIT8_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y +{0x0F12,0x1102}, // 70000ACA//AFIT8_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV +{0x0F12,0x0611}, // 70000ACC//AFIT8_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL +{0x0F12,0x1A02}, // 70000ACE//AFIT8_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL +{0x0F12,0x8018}, // 70000AD0//AFIT8_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower +{0x0F12,0x0080}, // 70000AD2//AFIT8_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce +{0x0F12,0x0380}, // 70000AD4//AFIT8_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset +{0x0F12,0x0180}, // 70000AD6//AFIT8_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H +{0x0F12,0x0A0A}, // 70000AD8//AFIT8_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C +{0x0F12,0x0101}, // 70000ADA//AFIT8_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C +{0x0F12,0x1B51}, // 70000ADC//AFIT8_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh +{0x0F12,0x6024}, // 70000ADE//AFIT8_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower +{0x0F12,0x1D5F}, // 70000AE0//AFIT8_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise +{0x0F12,0xFFFF}, // 70000AE2//AFIT8_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp +{0x0F12,0x0808}, // 70000AE4//AFIT8_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope +{0x0F12,0x0A01}, // 70000AE6//AFIT8_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin +{0x0F12,0x010A}, // 70000AE8//AFIT8_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin +{0x0F12,0x2401}, // 70000AEA//AFIT8_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin +{0x0F12,0x241B}, // 70000AEC//AFIT8_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin +{0x0F12,0x1E60}, // 70000AEE//AFIT8_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin +{0x0F12,0xFF18}, // 70000AF0//AFIT8_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin +{0x0F12,0x08FF}, // 70000AF2//AFIT8_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin +{0x0F12,0x0008}, // 70000AF4//AFIT8_ee_iReduceEdgeSlope_Bin [7:0] +{0x0F12,0x0001}, // 70000AF6//AFITB_bnr_nClustLevel_C [0] +{0x0F12,0x0000}, // 70000AF8//AFIT16_BRIGHTNESS +{0x0F12,0x0018}, // 70000AFA//AFIT16_CONTRAST +{0x0F12,0x0010}, // 70000AFC//AFIT16_SATURATION +{0x0F12,0x0000}, // 70000AFE//AFIT16_SHARP_BLUR +{0x0F12,0x0000}, // 70000B00//AFIT16_GLAMOUR +{0x0F12,0x00C0}, // 70000B02//AFIT16_bnr_edge_high +{0x0F12,0x0064}, // 70000B04//AFIT16_postdmsc_iLowBright +{0x0F12,0x0384}, // 70000B06//AFIT16_postdmsc_iHighBright +{0x0F12,0x0043}, // 70000B08//AFIT16_postdmsc_iLowSat +{0x0F12,0x01F4}, // 70000B0A//AFIT16_postdmsc_iHighSat +{0x0F12,0x0070}, // 70000B0C//AFIT16_postdmsc_iTune +{0x0F12,0x0040}, // 70000B0E//AFIT16_yuvemix_mNegRanges_0 +{0x0F12,0x00A0}, // 70000B10//AFIT16_yuvemix_mNegRanges_1 +{0x0F12,0x0100}, // 70000B12//AFIT16_yuvemix_mNegRanges_2 +{0x0F12,0x0010}, // 70000B14//AFIT16_yuvemix_mPosRanges_0 +{0x0F12,0x0060}, // 70000B16//AFIT16_yuvemix_mPosRanges_1 +{0x0F12,0x0100}, // 70000B18//AFIT16_yuvemix_mPosRanges_2 +{0x0F12,0x1430}, // 70000B1A//AFIT8_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh +{0x0F12,0x0201}, // 70000B1C//AFIT8_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh +{0x0F12,0x0204}, // 70000B1E//AFIT8_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh +{0x0F12,0x1B04}, // 70000B20//AFIT8_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low +{0x0F12,0x0312}, // 70000B22//AFIT8_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low +{0x0F12,0x0003}, // 70000B24//AFIT8_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin +{0x0F12,0x0C03}, // 70000B26//AFIT8_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow +{0x0F12,0x2806}, // 70000B28//AFIT8_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH +{0x0F12,0x0060}, // 70000B2A//AFIT8_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune +{0x0F12,0x1580}, // 70000B2C//AFIT8_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh +{0x0F12,0x2020}, // 70000B2E//AFIT8_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh +{0x0F12,0x0620}, // 70000B30//AFIT8_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed +{0x0F12,0x0306}, // 70000B32//AFIT8_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh +{0x0F12,0x2003}, // 70000B34//AFIT8_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH +{0x0F12,0xFF01}, // 70000B36//AFIT8_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit +{0x0F12,0x0404}, // 70000B38//AFIT8_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 +{0x0F12,0x0300}, // 70000B3A//AFIT8_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower +{0x0F12,0x145A}, // 70000B3C//AFIT8_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow +{0x0F12,0x1010}, // 70000B3E//AFIT8_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow +{0x0F12,0x000B}, // 70000B40//AFIT8_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow +{0x0F12,0x0E00}, // 70000B42//AFIT8_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower +{0x0F12,0x5A0F}, // 70000B44//AFIT8_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit +{0x0F12,0x0504}, // 70000B46//AFIT8_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope +{0x0F12,0x1802}, // 70000B48//AFIT8_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR +{0x0F12,0x0000}, // 70000B4A//AFIT8_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres +{0x0F12,0x2006}, // 70000B4C//AFIT8_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR +{0x0F12,0x3828}, // 70000B4E//AFIT8_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen +{0x0F12,0x0428}, // 70000B50//AFIT8_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh +{0x0F12,0x0101}, // 70000B52//AFIT8_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative +{0x0F12,0x8000}, // 70000B54//AFIT8_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle +{0x0F12,0x0A04}, // 70000B56//AFIT8_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh +{0x0F12,0x4008}, // 70000B58//AFIT8_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh +{0x0F12,0x0540}, // 70000B5A//AFIT8_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange +{0x0F12,0x8006}, // 70000B5C//AFIT8_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad +{0x0F12,0x0020}, // 70000B5E//AFIT8_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal +{0x0F12,0x0000}, // 70000B60//AFIT8_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh +{0x0F12,0x1800}, // 70000B62//AFIT8_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat +{0x0F12,0x0000}, // 70000B64//AFIT8_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit +{0x0F12,0x1E10}, // 70000B66//AFIT8_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff +{0x0F12,0x000B}, // 70000B68//AFIT8_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 +{0x0F12,0x0607}, // 70000B6A//AFIT8_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 +{0x0F12,0x0005}, // 70000B6C//AFIT8_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 +{0x0F12,0x0607}, // 70000B6E//AFIT8_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 +{0x0F12,0x0405}, // 70000B70//AFIT8_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY +{0x0F12,0x0207}, // 70000B72//AFIT8_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm +{0x0F12,0x0304}, // 70000B74//AFIT8_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm +{0x0F12,0x0409}, // 70000B76//AFIT8_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift +{0x0F12,0x0306}, // 70000B78//AFIT8_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y +{0x0F12,0x0407}, // 70000B7A//AFIT8_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y +{0x0F12,0x2404}, // 70000B7C//AFIT8_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV +{0x0F12,0x0221}, // 70000B7E//AFIT8_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y +{0x0F12,0x1202}, // 70000B80//AFIT8_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV +{0x0F12,0x0613}, // 70000B82//AFIT8_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL +{0x0F12,0x1A02}, // 70000B84//AFIT8_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL +{0x0F12,0x8018}, // 70000B86//AFIT8_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower +{0x0F12,0x0080}, // 70000B88//AFIT8_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce +{0x0F12,0x0080}, // 70000B8A//AFIT8_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset +{0x0F12,0x0180}, // 70000B8C//AFIT8_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H +{0x0F12,0x0A0A}, // 70000B8E//AFIT8_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C +{0x0F12,0x0101}, // 70000B90//AFIT8_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C +{0x0F12,0x142E}, // 70000B92//AFIT8_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh +{0x0F12,0x6024}, // 70000B94//AFIT8_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower +{0x0F12,0x0C4A}, // 70000B96//AFIT8_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise +{0x0F12,0xFFFF}, // 70000B98//AFIT8_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp +{0x0F12,0x0808}, // 70000B9A//AFIT8_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope +{0x0F12,0x0A01}, // 70000B9C//AFIT8_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin +{0x0F12,0x010A}, // 70000B9E//AFIT8_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin +{0x0F12,0x1B01}, // 70000BA0//AFIT8_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin +{0x0F12,0x2412}, // 70000BA2//AFIT8_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin +{0x0F12,0x0C60}, // 70000BA4//AFIT8_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin +{0x0F12,0xFF0C}, // 70000BA6//AFIT8_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin +{0x0F12,0x08FF}, // 70000BA8//AFIT8_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin +{0x0F12,0x0008}, // 70000BAA//AFIT8_ee_iReduceEdgeSlope_Bin [7:0] +{0x0F12,0x0001}, // 70000BAC//AFITB_bnr_nClustLevel_C [0] +{0x0F12,0x0000}, // 70000BAE//AFIT16_BRIGHTNESS +{0x0F12,0x0018}, // 70000BB0//AFIT16_CONTRAST +{0x0F12,0x0010}, // 70000BB2//AFIT16_SATURATION +{0x0F12,0x0000}, // 70000BB4//AFIT16_SHARP_BLUR +{0x0F12,0x0000}, // 70000BB6//AFIT16_GLAMOUR +{0x0F12,0x00C0}, // 70000BB8//AFIT16_bnr_edge_high +{0x0F12,0x0064}, // 70000BBA//AFIT16_postdmsc_iLowBright +{0x0F12,0x0384}, // 70000BBC//AFIT16_postdmsc_iHighBright +{0x0F12,0x0032}, // 70000BBE//AFIT16_postdmsc_iLowSat +{0x0F12,0x01F4}, // 70000BC0//AFIT16_postdmsc_iHighSat +{0x0F12,0x0070}, // 70000BC2//AFIT16_postdmsc_iTune +{0x0F12,0x0040}, // 70000BC4//AFIT16_yuvemix_mNegRanges_0 +{0x0F12,0x00A0}, // 70000BC6//AFIT16_yuvemix_mNegRanges_1 +{0x0F12,0x0100}, // 70000BC8//AFIT16_yuvemix_mNegRanges_2 +{0x0F12,0x0010}, // 70000BCA//AFIT16_yuvemix_mPosRanges_0 +{0x0F12,0x0060}, // 70000BCC//AFIT16_yuvemix_mPosRanges_1 +{0x0F12,0x0100}, // 70000BCE//AFIT16_yuvemix_mPosRanges_2 +{0x0F12,0x1430}, // 70000BD0//AFIT8_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh +{0x0F12,0x0201}, // 70000BD2//AFIT8_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh +{0x0F12,0x0204}, // 70000BD4//AFIT8_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh +{0x0F12,0x1504}, // 70000BD6//AFIT8_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low +{0x0F12,0x030F}, // 70000BD8//AFIT8_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low +{0x0F12,0x0003}, // 70000BDA//AFIT8_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin +{0x0F12,0x0902}, // 70000BDC//AFIT8_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow +{0x0F12,0x2004}, // 70000BDE//AFIT8_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH +{0x0F12,0x0050}, // 70000BE0//AFIT8_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune +{0x0F12,0x1140}, // 70000BE2//AFIT8_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh +{0x0F12,0x201C}, // 70000BE4//AFIT8_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh +{0x0F12,0x0620}, // 70000BE6//AFIT8_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed +{0x0F12,0x0306}, // 70000BE8//AFIT8_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh +{0x0F12,0x2003}, // 70000BEA//AFIT8_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH +{0x0F12,0xFF01}, // 70000BEC//AFIT8_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit +{0x0F12,0x0404}, // 70000BEE//AFIT8_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 +{0x0F12,0x0300}, // 70000BF0//AFIT8_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower +{0x0F12,0x145A}, // 70000BF2//AFIT8_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow +{0x0F12,0x1010}, // 70000BF4//AFIT8_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow +{0x0F12,0x000B}, // 70000BF6//AFIT8_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow +{0x0F12,0x1000}, // 70000BF8//AFIT8_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower +{0x0F12,0x5A0F}, // 70000BFA//AFIT8_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit +{0x0F12,0x0503}, // 70000BFC//AFIT8_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope +{0x0F12,0x1802}, // 70000BFE//AFIT8_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR +{0x0F12,0x0000}, // 70000C00//AFIT8_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres +{0x0F12,0x2006}, // 70000C02//AFIT8_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR +{0x0F12,0x3C28}, // 70000C04//AFIT8_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen +{0x0F12,0x042C}, // 70000C06//AFIT8_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh +{0x0F12,0x0101}, // 70000C08//AFIT8_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative +{0x0F12,0xFF00}, // 70000C0A//AFIT8_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle +{0x0F12,0x0904}, // 70000C0C//AFIT8_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh +{0x0F12,0x4008}, // 70000C0E//AFIT8_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh +{0x0F12,0x0540}, // 70000C10//AFIT8_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange +{0x0F12,0x8006}, // 70000C12//AFIT8_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad +{0x0F12,0x0020}, // 70000C14//AFIT8_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal +{0x0F12,0x0000}, // 70000C16//AFIT8_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh +{0x0F12,0x1800}, // 70000C18//AFIT8_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat +{0x0F12,0x0000}, // 70000C1A//AFIT8_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit +{0x0F12,0x1E10}, // 70000C1C//AFIT8_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff +{0x0F12,0x000B}, // 70000C1E//AFIT8_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 +{0x0F12,0x0607}, // 70000C20//AFIT8_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 +{0x0F12,0x0005}, // 70000C22//AFIT8_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 +{0x0F12,0x0607}, // 70000C24//AFIT8_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 +{0x0F12,0x0405}, // 70000C26//AFIT8_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY +{0x0F12,0x0206}, // 70000C28//AFIT8_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm +{0x0F12,0x0304}, // 70000C2A//AFIT8_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm +{0x0F12,0x0409}, // 70000C2C//AFIT8_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift +{0x0F12,0x0305}, // 70000C2E//AFIT8_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y +{0x0F12,0x0406}, // 70000C30//AFIT8_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y +{0x0F12,0x2804}, // 70000C32//AFIT8_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV +{0x0F12,0x0228}, // 70000C34//AFIT8_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y +{0x0F12,0x1402}, // 70000C36//AFIT8_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV +{0x0F12,0x0618}, // 70000C38//AFIT8_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL +{0x0F12,0x1A02}, // 70000C3A//AFIT8_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL +{0x0F12,0x8018}, // 70000C3C//AFIT8_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower +{0x0F12,0x0080}, // 70000C3E//AFIT8_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce +{0x0F12,0x0080}, // 70000C40//AFIT8_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset +{0x0F12,0x0180}, // 70000C42//AFIT8_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H +{0x0F12,0x0A0A}, // 70000C44//AFIT8_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C +{0x0F12,0x0101}, // 70000C46//AFIT8_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C +{0x0F12,0x1129}, // 70000C48//AFIT8_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh +{0x0F12,0x6024}, // 70000C4A//AFIT8_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower +{0x0F12,0x0A2E}, // 70000C4C//AFIT8_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise +{0x0F12,0xFFFF}, // 70000C4E//AFIT8_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp +{0x0F12,0x0808}, // 70000C50//AFIT8_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope +{0x0F12,0x0A01}, // 70000C52//AFIT8_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin +{0x0F12,0x010A}, // 70000C54//AFIT8_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin +{0x0F12,0x1501}, // 70000C56//AFIT8_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin +{0x0F12,0x240F}, // 70000C58//AFIT8_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin +{0x0F12,0x0A60}, // 70000C5A//AFIT8_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin +{0x0F12,0xFF0A}, // 70000C5C//AFIT8_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin +{0x0F12,0x08FF}, // 70000C5E//AFIT8_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin +{0x0F12,0x0008}, // 70000C60//AFIT8_ee_iReduceEdgeSlope_Bin [7:0] +{0x0F12,0x0001}, // 70000C62//AFITB_bnr_nClustLevel_C [0] +{0x0F12,0x0000}, // 70000C64//AFIT16_BRIGHTNESS +{0x0F12,0x0018}, // 70000C66//AFIT16_CONTRAST +{0x0F12,0x0010}, // 70000C68//AFIT16_SATURATION +{0x0F12,0x0000}, // 70000C6A//AFIT16_SHARP_BLUR +{0x0F12,0x0000}, // 70000C6C//AFIT16_GLAMOUR +{0x0F12,0x00C0}, // 70000C6E//AFIT16_bnr_edge_high +{0x0F12,0x0064}, // 70000C70//AFIT16_postdmsc_iLowBright +{0x0F12,0x0384}, // 70000C72//AFIT16_postdmsc_iHighBright +{0x0F12,0x0032}, // 70000C74//AFIT16_postdmsc_iLowSat +{0x0F12,0x01F4}, // 70000C76//AFIT16_postdmsc_iHighSat +{0x0F12,0x0070}, // 70000C78//AFIT16_postdmsc_iTune +{0x0F12,0x0040}, // 70000C7A//AFIT16_yuvemix_mNegRanges_0 +{0x0F12,0x00A0}, // 70000C7C//AFIT16_yuvemix_mNegRanges_1 +{0x0F12,0x0100}, // 70000C7E//AFIT16_yuvemix_mNegRanges_2 +{0x0F12,0x0010}, // 70000C80//AFIT16_yuvemix_mPosRanges_0 +{0x0F12,0x0060}, // 70000C82//AFIT16_yuvemix_mPosRanges_1 +{0x0F12,0x0100}, // 70000C84//AFIT16_yuvemix_mPosRanges_2 +{0x0F12,0x1430}, // 70000C86//AFIT8_bnr_edge_low [7:0] AFIT8_bnr_repl_thresh +{0x0F12,0x0201}, // 70000C88//AFIT8_bnr_repl_force [7:0] AFIT8_bnr_iHotThreshHigh +{0x0F12,0x0204}, // 70000C8A//AFIT8_bnr_iHotThreshLow [7:0] AFIT8_bnr_iColdThreshHigh +{0x0F12,0x0F04}, // 70000C8C//AFIT8_bnr_iColdThreshLow [7:0] AFIT8_bnr_DispTH_Low +{0x0F12,0x030C}, // 70000C8E//AFIT8_bnr_DispTH_High [7:0] AFIT8_bnr_DISP_Limit_Low +{0x0F12,0x0003}, // 70000C90//AFIT8_bnr_DISP_Limit_High [7:0] AFIT8_bnr_iDistSigmaMin +{0x0F12,0x0602}, // 70000C92//AFIT8_bnr_iDistSigmaMax [7:0] AFIT8_bnr_iDiffSigmaLow +{0x0F12,0x1803}, // 70000C94//AFIT8_bnr_iDiffSigmaHigh [7:0] AFIT8_bnr_iNormalizedSTD_TH +{0x0F12,0x0040}, // 70000C96//AFIT8_bnr_iNormalizedSTD_Limit [7:0] AFIT8_bnr_iDirNRTune +{0x0F12,0x0E20}, // 70000C98//AFIT8_bnr_iDirMinThres [7:0] AFIT8_bnr_iDirFltDiffThresHigh +{0x0F12,0x2018}, // 70000C9A//AFIT8_bnr_iDirFltDiffThresLow [7:0] AFIT8_bnr_iDirSmoothPowerHigh +{0x0F12,0x0620}, // 70000C9C//AFIT8_bnr_iDirSmoothPowerLow [7:0] AFIT8_bnr_iLowMaxSlopeAllowed +{0x0F12,0x0306}, // 70000C9E//AFIT8_bnr_iHighMaxSlopeAllowed [7:0] AFIT8_bnr_iLowSlopeThresh +{0x0F12,0x2003}, // 70000CA0//AFIT8_bnr_iHighSlopeThresh [7:0] AFIT8_bnr_iSlopenessTH +{0x0F12,0xFF01}, // 70000CA2//AFIT8_bnr_iSlopeBlurStrength [7:0] AFIT8_bnr_iSlopenessLimit +{0x0F12,0x0404}, // 70000CA4//AFIT8_bnr_AddNoisePower1 [7:0] AFIT8_bnr_AddNoisePower2 +{0x0F12,0x0200}, // 70000CA6//AFIT8_bnr_iRadialTune [7:0] AFIT8_bnr_iRadialPower +{0x0F12,0x145A}, // 70000CA8//AFIT8_bnr_iRadialLimit [7:0] AFIT8_ee_iFSMagThLow +{0x0F12,0x1010}, // 70000CAA//AFIT8_ee_iFSMagThHigh [7:0] AFIT8_ee_iFSVarThLow +{0x0F12,0x000B}, // 70000CAC//AFIT8_ee_iFSVarThHigh [7:0] AFIT8_ee_iFSThLow +{0x0F12,0x1200}, // 70000CAE//AFIT8_ee_iFSThHigh [7:0] AFIT8_ee_iFSmagPower +{0x0F12,0x5A0F}, // 70000CB0//AFIT8_ee_iFSVarCountTh [7:0] AFIT8_ee_iRadialLimit +{0x0F12,0x0502}, // 70000CB2//AFIT8_ee_iRadialPower [7:0] AFIT8_ee_iSmoothEdgeSlope +{0x0F12,0x1802}, // 70000CB4//AFIT8_ee_iROADThres [7:0] AFIT8_ee_iROADMaxNR +{0x0F12,0x0000}, // 70000CB6//AFIT8_ee_iROADSubMaxNR [7:0] AFIT8_ee_iROADSubThres +{0x0F12,0x2006}, // 70000CB8//AFIT8_ee_iROADNeiThres [7:0] AFIT8_ee_iROADNeiMaxNR +{0x0F12,0x4028}, // 70000CBA//AFIT8_ee_iSmoothEdgeThres [7:0] AFIT8_ee_iMSharpen +{0x0F12,0x0430}, // 70000CBC//AFIT8_ee_iWSharpen [7:0] AFIT8_ee_iMShThresh +{0x0F12,0x0101}, // 70000CBE//AFIT8_ee_iWShThresh [7:0] AFIT8_ee_iReduceNegative +{0x0F12,0xFF00}, // 70000CC0//AFIT8_ee_iEmbossCentAdd [7:0] AFIT8_ee_iShDespeckle +{0x0F12,0x0804}, // 70000CC2//AFIT8_ee_iReduceEdgeThresh [7:0] AFIT8_dmsc_iEnhThresh +{0x0F12,0x4008}, // 70000CC4//AFIT8_dmsc_iDesatThresh [7:0] AFIT8_dmsc_iDemBlurHigh +{0x0F12,0x0540}, // 70000CC6//AFIT8_dmsc_iDemBlurLow [7:0] AFIT8_dmsc_iDemBlurRange +{0x0F12,0x8006}, // 70000CC8//AFIT8_dmsc_iDecisionThresh [7:0] AFIT8_dmsc_iCentGrad +{0x0F12,0x0020}, // 70000CCA//AFIT8_dmsc_iMonochrom [7:0] AFIT8_dmsc_iGBDenoiseVal +{0x0F12,0x0000}, // 70000CCC//AFIT8_dmsc_iGRDenoiseVal [7:0] AFIT8_dmsc_iEdgeDesatThrHigh +{0x0F12,0x1800}, // 70000CCE//AFIT8_dmsc_iEdgeDesatThrLow [7:0] AFIT8_dmsc_iEdgeDesat +{0x0F12,0x0000}, // 70000CD0//AFIT8_dmsc_iNearGrayDesat [7:0] AFIT8_dmsc_iEdgeDesatLimit +{0x0F12,0x1E10}, // 70000CD2//AFIT8_postdmsc_iBCoeff [7:0] AFIT8_postdmsc_iGCoeff +{0x0F12,0x000B}, // 70000CD4//AFIT8_postdmsc_iWideMult [7:0] AFIT8_yuvemix_mNegSlopes_0 +{0x0F12,0x0607}, // 70000CD6//AFIT8_yuvemix_mNegSlopes_1 [7:0] AFIT8_yuvemix_mNegSlopes_2 +{0x0F12,0x0005}, // 70000CD8//AFIT8_yuvemix_mNegSlopes_3 [7:0] AFIT8_yuvemix_mPosSlopes_0 +{0x0F12,0x0607}, // 70000CDA//AFIT8_yuvemix_mPosSlopes_1 [7:0] AFIT8_yuvemix_mPosSlopes_2 +{0x0F12,0x0405}, // 70000CDC//AFIT8_yuvemix_mPosSlopes_3 [7:0] AFIT8_yuviirnr_iXSupportY +{0x0F12,0x0205}, // 70000CDE//AFIT8_yuviirnr_iXSupportUV [7:0] AFIT8_yuviirnr_iLowYNorm +{0x0F12,0x0304}, // 70000CE0//AFIT8_yuviirnr_iHighYNorm [7:0] AFIT8_yuviirnr_iLowUVNorm +{0x0F12,0x0409}, // 70000CE2//AFIT8_yuviirnr_iHighUVNorm [7:0] AFIT8_yuviirnr_iYNormShift +{0x0F12,0x0306}, // 70000CE4//AFIT8_yuviirnr_iUVNormShift [7:0] AFIT8_yuviirnr_iVertLength_Y +{0x0F12,0x0407}, // 70000CE6//AFIT8_yuviirnr_iVertLength_UV [7:0] AFIT8_yuviirnr_iDiffThreshL_Y +{0x0F12,0x2C04}, // 70000CE8//AFIT8_yuviirnr_iDiffThreshH_Y [7:0] AFIT8_yuviirnr_iDiffThreshL_UV +{0x0F12,0x022C}, // 70000CEA//AFIT8_yuviirnr_iDiffThreshH_UV [7:0] AFIT8_yuviirnr_iMaxThreshL_Y +{0x0F12,0x1402}, // 70000CEC//AFIT8_yuviirnr_iMaxThreshH_Y [7:0] AFIT8_yuviirnr_iMaxThreshL_UV +{0x0F12,0x0618}, // 70000CEE//AFIT8_yuviirnr_iMaxThreshH_UV [7:0] AFIT8_yuviirnr_iYNRStrengthL +{0x0F12,0x1A02}, // 70000CF0//AFIT8_yuviirnr_iYNRStrengthH [7:0] AFIT8_yuviirnr_iUVNRStrengthL +{0x0F12,0x8018}, // 70000CF2//AFIT8_yuviirnr_iUVNRStrengthH [7:0] AFIT8_byr_gras_iShadingPower +{0x0F12,0x0080}, // 70000CF4//AFIT8_RGBGamma2_iLinearity [7:0] AFIT8_RGBGamma2_iDarkReduce +{0x0F12,0x0080}, // 70000CF6//AFIT8_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset +{0x0F12,0x0180}, // 70000CF8//AFIT8_RGB2YUV_iRGBGain [7:0] AFIT8_bnr_nClustLevel_H +{0x0F12,0x0A0A}, // 70000CFA//AFIT8_bnr_iClustMulT_H [7:0] AFIT8_bnr_iClustMulT_C +{0x0F12,0x0101}, // 70000CFC//AFIT8_bnr_iClustThresh_H [7:0] AFIT8_bnr_iClustThresh_C +{0x0F12,0x0C22}, // 70000CFE//AFIT8_bnr_iDenThreshLow [7:0] AFIT8_bnr_iDenThreshHigh +{0x0F12,0x6024}, // 70000D00//AFIT8_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower +{0x0F12,0x0808}, // 70000D02//AFIT8_ee_iLowShDenoise [7:0] AFIT8_ee_iHighShDenoise +{0x0F12,0xFFFF}, // 70000D04//AFIT8_ee_iLowSharpClamp [7:0] AFIT8_ee_iHighSharpClamp +{0x0F12,0x0808}, // 70000D06//AFIT8_ee_iReduceEdgeMinMult [7:0] AFIT8_ee_iReduceEdgeSlope +{0x0F12,0x0A01}, // 70000D08//AFIT8_bnr_nClustLevel_H_Bin [7:0] AFIT8_bnr_iClustMulT_H_Bin +{0x0F12,0x010A}, // 70000D0A//AFIT8_bnr_iClustMulT_C_Bin [7:0] AFIT8_bnr_iClustThresh_H_Bin +{0x0F12,0x0F01}, // 70000D0C//AFIT8_bnr_iClustThresh_C_Bin [7:0] AFIT8_bnr_iDenThreshLow_Bin +{0x0F12,0x240C}, // 70000D0E//AFIT8_bnr_iDenThreshHigh_Bin [7:0] AFIT8_ee_iLowSharpPower_Bin +{0x0F12,0x0860}, // 70000D10//AFIT8_ee_iHighSharpPower_Bin [7:0] AFIT8_ee_iLowShDenoise_Bin +{0x0F12,0xFF08}, // 70000D12//AFIT8_ee_iHighShDenoise_Bin [7:0] AFIT8_ee_iLowSharpClamp_Bin +{0x0F12,0x08FF}, // 70000D14//AFIT8_ee_iHighSharpClamp_Bin [7:0] AFIT8_ee_iReduceEdgeMinMult_Bin +{0x0F12,0x0008}, // 70000D16//AFIT8_ee_iReduceEdgeSlope_Bin [7:0] +{0x0F12,0x0001}, //70000D18 AFITB_bnr_nClustLevel_C [0] bWideWide[1] +{0x0F12,0x23CE}, // 70000D19//ConstAfitBaseVals +{0x0F12,0xFDC8}, // 70000D1A//ConstAfitBaseVals +{0x0F12,0x112E}, // 70000D1B//ConstAfitBaseVals +{0x0F12,0x93A5}, // 70000D1C//ConstAfitBaseVals +{0x0F12,0xFE67}, // 70000D1D//ConstAfitBaseVals +{0x0F12,0x0000}, // 70000D1E//ConstAfitBaseVals +//================================================================================== +// 19.Input Size Setting +//================================================================================== +//Input Size +{0x002A,0x0250}, +{0x0F12,0x0A00}, // REG_TC_GP_PrevReqInputWidth +{0x0F12,0x0780}, // REG_TC_GP_PrevReqInputHeight +{0x0F12,0x0010}, // REG_TC_GP_PrevInputWidthOfs +{0x0F12,0x000C}, // REG_TC_GP_PrevInputHeightOfs +{0x0F12,0x0A00}, // REG_TC_GP_CapReqInputWidth +{0x0F12,0x0780}, // REG_TC_GP_CapReqInputHeight +{0x0F12,0x0010}, // REG_TC_GP_CapInputWidthOfs +{0x0F12,0x000C}, // REG_TC_GP_CapInputHeightOfs +{0x002A,0x0494}, +{0x0F12,0x0A00}, // REG_TC_PZOOM_ZoomInputWidth +{0x0F12,0x0780}, // REG_TC_PZOOM_ZoomInputHeight +{0x0F12,0x0000}, // REG_TC_PZOOM_ZoomInputWidthOfs +{0x0F12,0x0000}, // REG_TC_PZOOM_ZoomInputHeightOfs +{0x0F12,0x0A00}, // REG_TC_CZOOM_ZoomInputWidth +{0x0F12,0x0780}, // REG_TC_CZOOM_ZoomInputHeight +{0x0F12,0x0000}, // REG_TC_CZOOM_ZoomInputWidthOfs +{0x0F12,0x0000}, // REG_TC_CZOOM_ZoomInputHeightOfs +{0x002A,0x0262}, +{0x0F12,0x0001}, // REG_TC_GP_bUseReqInputInPre +{0x0F12,0x0001}, // REG_TC_GP_bUseReqInputInCap //================================================================================== -// 19.Select Cofigration Display +// 20.Preview & Capture Configration Setting +//================================================================================== +//Preview config[0] 640x480 +//Normal mode(VGA preview ) +{0x002A,0x02A6}, +{0x0F12,0x0280},//REG_0TC_PCFG_usWidth +{0x0F12,0x01E0}, //REG_0TC_PCFG_usHeight +{0x0F12,0x0005}, //REG_0TC_PCFG_Format 5 YUV 7 Raw 9 JPG +{0x0F12,0x279D}, //REG_0TC_PCFG_usMaxOut4KHzRate +{0x0F12,0x277D}, //REG_0TC_PCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_0TC_PCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_0TC_PCFG_uBpp88 +{0x0F12,0x0012}, //REG_0TC_PCFG_PVIMask +{0x0F12,0x0000}, //REG_0TC_PCFG_OIFMask +{0x0F12,0x01E0}, //REG_0TC_PCFG_usJpegPacketSize +{0x0F12,0x0000}, //REG_0TC_PCFG_usJpegTotalPackets +{0x0F12,0x0000}, //REG_0TC_PCFG_uClockInd +{0x0F12,0x0000}, //REG_0TC_PCFG_usFrTimeType +{0x0F12,0x0001}, //REG_0TC_PCFG_FrRateQualityType +{0x0F12,0x03E8}, //REG_0TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x014A}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 +{0x002A,0x02D0}, +{0x0F12,0x0000}, //REG_0TC_PCFG_uPrevMirror +{0x0F12,0x0000}, //REG_0TC_PCFG_uCaptureMirror +{0x0F12,0x0000}, //REG_0TC_PCFG_uRotation + + + //Preview config[1] 1280x720 +//Normal mode(SXGA preview ) +{0x002A,0x02D6}, +{0x0F12,0x0500},//REG_1TC_PCFG_usWidth +{0x0F12,0x02D0}, //REG_1TC_PCFG_usHeight +{0x0F12,0x0005}, //REG_1TC_PCFG_Format 5 YUV 7 Raw 9 JPG +{0x0F12,0x279D}, //REG_1TC_PCFG_usMaxOut4KHzRate +{0x0F12,0x277D}, //REG_1TC_PCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_1TC_PCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_1TC_PCFG_uBpp88 +{0x0F12,0x0012}, //REG_1TC_PCFG_PVIMask +{0x0F12,0x0000}, //REG_1TC_PCFG_OIFMask +{0x0F12,0x01E0}, //REG_1TC_PCFG_usJpegPacketSize +{0x0F12,0x0000}, //REG_1TC_PCFG_usJpegTotalPackets +{0x0F12,0x0000}, //REG_1TC_PCFG_uClockInd +{0x0F12,0x0000}, //REG_1TC_PCFG_usFrTimeType +{0x0F12,0x0001}, //REG_1TC_PCFG_FrRateQualityType +{0x0F12,0x0535}, //REG_1TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x014d}, //REG_1TC_PCFG_usMinFrTimeMsecMult10 +{0x002A,0x0300}, +{0x0F12,0x0000}, //REG_1TC_PCFG_uPrevMirror +{0x0F12,0x0000}, //REG_1TC_PCFG_uCaptureMirror +{0x0F12,0x0000},//REG_1TC_PCFG_uRotation + + + + +//Preview config[2] 1280x860 +//Normal mode(SXGA preview ) +{0x002A,0x0306}, +{0x0F12,0x0800},//0500 //REG_2TC_PCFG_usWidth +{0x0F12,0x0600},//03C0 //REG_2TC_PCFG_usHeight +{0x0F12,0x0005}, //REG_2TC_PCFG_Format 5 YUV 7 Raw 9 JPG +{0x0F12,0x279D}, //REG_2TC_PCFG_usMaxOut4KHzRate +{0x0F12,0x277D}, //REG_2TC_PCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_2TC_PCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_2TC_PCFG_uBpp88 +{0x0F12,0x0012}, //REG_2TC_PCFG_PVIMask +{0x0F12,0x0000}, //REG_2TC_PCFG_OIFMask +{0x0F12,0x01E0}, //REG_2TC_PCFG_usJpegPacketSize +{0x0F12,0x0000}, //REG_2TC_PCFG_usJpegTotalPackets +{0x0F12,0x0000}, //REG_2TC_PCFG_uClockInd +{0x0F12,0x0000}, //REG_2TC_PCFG_usFrTimeType +{0x0F12,0x0002}, //REG_2TC_PCFG_FrRateQualityType +{0x0F12,0x07d0}, //REG_2TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x0000}, //REG_2TC_PCFG_usMinFrTimeMsecMult10 +{0x002A,0x0330}, +{0x0F12,0x0000}, //REG_2TC_PCFG_uPrevMirror +{0x0F12,0x0000}, //REG_2TC_PCFG_uCaptureMirror +{0x0F12,0x0000}, //REG_2TC_PCFG_uRotation + +//Preview config[3] 2560x1920 +//Normal mode(5M preview ) +{0x002A,0x0336}, +{0x0F12,0x0A00}, //REG_3TC_PCFG_usWidth +{0x0F12,0x0780}, //REG_3TC_PCFG_usHeight +{0x0F12,0x0005}, //REG_3TC_PCFG_Format 5 YUV 7 Raw 9 JPG +{0x0F12,0x279D}, //REG_3TC_PCFG_usMaxOut4KHzRate +{0x0F12,0x277D}, //REG_3TC_PCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_3TC_PCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_3TC_PCFG_uBpp88 +{0x0F12,0x0012}, //REG_3TC_PCFG_PVIMask +{0x0F12,0x0000}, //REG_3TC_PCFG_OIFMask +{0x0F12,0x01E0}, //REG_3TC_PCFG_usJpegPacketSize +{0x0F12,0x0000}, //REG_3TC_PCFG_usJpegTotalPackets +{0x0F12,0x0000}, //REG_3TC_PCFG_uClockInd +{0x0F12,0x0000}, //REG_3TC_PCFG_usFrTimeType +{0x0F12,0x0002}, //REG_3TC_PCFG_FrRateQualityType +{0x0F12,0x07D0}, //REG_3TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x07D0}, //REG_3TC_PCFG_usMinFrTimeMsecMult10 +{0x002A,0x0360}, +{0x0F12,0x0000}, //REG_3TC_PCFG_uPrevMirror +{0x0F12,0x0000}, //REG_3TC_PCFG_uCaptureMirror +{0x0F12,0x0000}, //REG_3TC_PCFG_uRotation + + + +{0x002A,0x0396}, +{0x0F12,0x0001}, //REG_0TC_CCFG_uCaptureMode +{0x0F12,0x0A00}, //REG_0TC_CCFG_usWidth +{0x0F12,0x0780}, //REG_0TC_CCFG_usHeight +{0x0F12,0x0005}, //REG_0TC_CCFG_Format +{0x0F12,0x279D}, //REG_0TC_CCFG_usMaxOut4KHzRate +{0x0F12,0x277D}, //REG_0TC_CCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_0TC_CCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_0TC_CCFG_uBpp88 +{0x0F12,0x0012}, //REG_0TC_CCFG_PVIMask +{0x0F12,0x0070}, //REG_0TC_CCFG_OIFMask +{0x0F12,0x0810}, //REG_0TC_CCFG_usJpegPacketSize +{0x0F12,0x0900}, //REG_0TC_CCFG_usJpegTotalPackets +{0x0F12,0x0001}, //REG_0TC_CCFG_uClockInd +{0x0F12,0x0000}, //REG_0TC_CCFG_usFrTimeType +{0x0F12,0x0002}, //REG_0TC_CCFG_FrRateQualityType +{0x0F12,0x0535}, //REG_0TC_CCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x029A}, //REG_0TC_CCFG_usMinFrTimeMsecMult10 + + +{0x002A,0x1CC2}, //DRx_uDRxWeight for AutoCont function +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x0F12,0x0100}, +{0x002A,0x022C}, +{0x0F12,0x0001}, //REG_TC_IPRM_InitParamsUpdated + +//================================================================================== +// 21.Select Cofigration Display //================================================================================== //PREVIEW -{0x0028, 0x7000},//many insert -{0x002A, 0x0266}, -{0x0F12, 0x0000}, //REG_TC_GP_ActivePrevConfig -{0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange -{0x002A, 0x024E}, -{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync -{0x002A, 0x0268}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged -{0x002A, 0x0270}, -{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged -{0x002A, 0x023E}, -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +{0x0028,0x7000},//many insert +{0x002A,0x0266}, +{0x0F12,0x0000}, // REG_TC_GP_ActivePrevConfig +{0x002A,0x026A}, +{0x0F12,0x0001}, // REG_TC_GP_PrevOpenAfterChange +{0x002A,0x0268}, +{0x0F12,0x0001}, // REG_TC_GP_PrevConfigChanged +{0x002A,0x026E}, +{0x0F12,0x0000}, // REG_TC_GP_ActiveCapConfig +{0x002A,0x026A}, +{0x0F12,0x0001}, // REG_TC_GP_CapOpenAfterChange +{0x002A,0x0270}, +{0x0F12,0x0001}, // REG_TC_GP_CapConfigChanged +{0x002A,0x024E}, +{0x0F12,0x0001}, // REG_TC_GP_NewConfigSync +{0x002A,0x023E}, +{0x0F12,0x0001}, // REG_TC_GP_EnablePreview +{0x0F12,0x0001}, // REG_TC_GP_EnablePreviewChanged //=================================================================================== // 22. ESD Check //=================================================================================== -{0x002A, 0x01A8}, -{0x0F12, 0xAAAA}, +{0x002A,0x01A8}, +{0x0F12,0xAAAA}, //=================================================================================== // 23. Brightness min/Max //=================================================================================== -{0x0028, 0x147C}, -{0x002A, 0x01AA}, -{0x0F12, 0x0180}, //bp_uMaxBrightnessFactor -{0x0028, 0x1482}, -{0x002A, 0x01AC}, -{0x0F12, 0x0180}, //bp_uMinBrightnessFactor +{0x0028,0x147C}, +{0x002A,0x01AA}, +{0x0F12,0x0180}, // bp_uMaxBrightnessFactor +{0x0028,0x1482}, +{0x002A,0x01AC}, +{0x0F12,0x0180}, // bp_uMinBrightnessFactor -//=================================================================================== -// 24.ISSUE -//=================================================================================== -//20110728 : Sequence Changed by image dev.(by J.M.Ahn) -//20110728 : ESD Check Register Address Change -//20110829 : TnP Changed by S.Y.Lee -//20120104 : init Parm Update sequence changed(by J.M.Ahn) -//20120201 : Flash�� �ֺ��� Green Noise ���� setting (by J.M.Ahn) -//20120228 : Add Brightness Block -//20120717 : Lowtemp bypass ��Ŵ }; //////////////////////////////////////////////////////////////// // Automatically written by Setfile Rule Check function. @@ -3212,451 +4017,230 @@ static struct regval_list sensor_default_regs[] = { //WRITE #REG_TC_GP_InvokeReadOTPData 0001 //////////////////////////////////////////////////////////////// -#if 0 -//for capture -static struct regval_list sensor_qsxga_regs[] = { //qsxga: 2560*1920 5fps -/* capture setting */ - -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0x002A, 0x0396}, -{0x0F12, 0x0001}, //REG_0TC_CCFG_uCaptureMode -{0x0F12, 0x0A00}, //REG_0TC_CCFG_usWidth -{0x0F12, 0x0780}, //REG_0TC_CCFG_usHeight -{0x002A, 0x03AE}, -{0x0F12, 0x0000}, //REG_0TC_CCFG_uClockInd -{0x002A, 0x03B4}, -{0x0F12, 0x07D0}, //REG_0TC_CCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x07D0}, //REG_0TC_CCFG_usMinFrTimeMsecMult10 - -//================================================================================== -// 21.Select Cofigration Display -//================================================================================== -//CAPTURE -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, -{0x002A, 0x026E}, -{0x0F12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x0F12, 0x0001}, // / -{0x002A, 0x0242}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCapture -{0x002A, 0x024E}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_NewConfigSync -{0x002A, 0x0244}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCaptureChanged - -{0xffff, 0x00c8}, //delay 200ms -}; - - -#else //for capture static struct regval_list sensor_qsxga_regs[] = { //qsxga: 2560*1920 7fps -/* capture setting */ - -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0x002A, 0x0396}, -{0x0F12, 0x0001}, //REG_0TC_CCFG_uCaptureMode -{0x0F12, 0x0A00}, //REG_0TC_CCFG_usWidth -{0x0F12, 0x0780}, //REG_0TC_CCFG_usHeight -{0x002A, 0x03AE}, -{0x0F12, 0x0000}, //REG_0TC_CCFG_uClockInd -{0x002A, 0x03B4}, -{0x0F12, 0x0535}, //REG_0TC_CCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x0535}, //REG_0TC_CCFG_usMinFrTimeMsecMult10 - -//================================================================================== -// 21.Select Cofigration Display -//================================================================================== -//CAPTURE -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, -{0x002A, 0x026E}, -{0x0F12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x0F12, 0x0001}, // / -{0x002A, 0x0242}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCapture -{0x002A, 0x024E}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_NewConfigSync -{0x002A, 0x0244}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCaptureChanged - -{0xffff, 0x00c8}, //delay 200ms -}; -#endif - -static struct regval_list sensor_qxga_regs[] = { //qxga: 2048*1536 -/* capture setting */ - -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0x002A, 0x0396}, -{0x0F12, 0x0001}, //REG_0TC_CCFG_uCaptureMode -{0x0F12, 0x0800}, //REG_0TC_CCFG_usWidth -{0x0F12, 0x0600}, //REG_0TC_CCFG_usHeight -{0x002A, 0x03AE}, -{0x0F12, 0x0000}, //REG_0TC_CCFG_uClockInd -{0x002A, 0x03B4}, -{0x0F12, 0x0535}, //REG_0TC_CCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x0535}, //REG_0TC_CCFG_usMinFrTimeMsecMult10 - -//================================================================================== -// 21.Select Cofigration Display -//================================================================================== -//CAPTURE -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, -{0x002A, 0x026E}, -{0x0F12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x0F12, 0x0001}, // / -{0x002A, 0x0242}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCapture -{0x002A, 0x024E}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_NewConfigSync -{0x002A, 0x0244}, // -{0x0F12, 0x0001}, // /#REG_TC_GP_EnableCaptureChanged - -{0xffff, 0x00c8}, //delay 200ms -}; - - -//for video -static struct regval_list sensor_1080p_regs[] = { //1080: 1920*1080 -/* preview setting */ - -{0x002A, 0x18AC}, -{0x0F12, 0x0060}, //senHal_uAddColsBin -{0x0F12, 0x0060}, //senHal_uAddColsNoBin -{0x0F12, 0x05C0}, //senHal_uMinColsBin -{0x0F12, 0x0A96}, //05C0 //senHal_uMinColsNoBin - -//================================================================================== -// 19.Input Size Setting -//================================================================================== -//Input Size -{0x002A, 0x0250}, -{0x0F12, 0x0780}, //REG_TC_GP_PrevReqInputWidth -{0x0F12, 0x0438}, //REG_TC_GP_PrevReqInputHeight -{0x0F12, 0x014E}, //REG_TC_GP_PrevInputWidthOfs -{0x0F12, 0x01B0}, //REG_TC_GP_PrevInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_GP_CapReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_CapReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_CapInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_CapInputHeightOfs - -{0x002A, 0x0494}, -{0x0F12, 0x0780}, //REG_TC_PZOOM_ZoomInputWidth -{0x0F12, 0x0438}, //REG_TC_PZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_CZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_CZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputHeightOfs - -{0x002A, 0x0262}, -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInPre -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInCap +//Preview config[0] 64480 7.5~15fps +{0x002A, 0x0336}, +{0x0F12, 0x0A00}, //REG_0TC_PCFG_usWidth +{0x0F12, 0x0780}, //REG_0TC_PCFG_usHeight +{0x0F12, 0x0005}, //REG_0TC_PCFG_Format +{0x0F12, 0x279D}, //4F1A //REG_0TC_PCFG_usMaxOut4KHzRate +{0x0F12, 0x277D}, //4F1A //REG_0TC_PCFG_usMinOut4KHzRate +{0x0F12, 0x0100}, //REG_0TC_PCFG_OutClkPerPix88 +{0x0F12, 0x0300}, //REG_0TC_PCFG_uBpp88 +{0x0F12, 0x0012}, //REG_0TC_PCFG_PVIMask +{0x0F12, 0x0000}, //REG_0TC_PCFG_OIFMask +{0x0F12, 0x01E0}, //REG_0TC_PCFG_usJpegPacketSize +{0x0F12, 0x0000}, //REG_0TC_PCFG_usJpegTotalPackets +{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd +{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType +{0x0F12, 0x0002}, //REG_0TC_PCFG_FrRateQualityType +{0x0F12, 0x07D0}, //029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12, 0x07D0}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, -{0x002A, 0x02A6}, -{0x0F12, 0x0780}, //280 REG_0TC_PCFG_usWidth -{0x0F12, 0x0438}, //1E0 REG_0TC_PCFG_usHeight -{0x002A, 0x02BC}, -{0x0F12, 0x0001}, //REG_0TC_PCFG_uClockInd -{0x0F12, 0x0001}, //REG_0TC_PCFG_usFrTimeType -{0x0F12, 0x0000}, //REG_0TC_PCFG_FrRateQualityType -{0x0F12, 0x029A}, //REG_0TC_PCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x029A}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 - -{0x002A, 0x022C}, -{0x0F12, 0x0001}, //REG_TC_IPRM_InitParamsUpdated //================================================================================== -// 21.Select Cofigration Display +// 19.Select Cofigration Display //================================================================================== //PREVIEW -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, + +{0x0028, 0x7000},//many insert {0x002A, 0x0266}, -{0x0f12, 0x0000}, //REG_TC_GP_ActivePrevConfig +{0x0F12, 0x0003}, //REG_TC_GP_ActivePrevConfig {0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange +{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange {0x002A, 0x0268}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged -{0x002A, 0x026E}, -{0x0f12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_CapOpenAfterChange -{0x002A, 0x0270}, -{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged - +{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync {0x002A, 0x024E}, -{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync +{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged {0x002A, 0x023E}, -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged - +{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview +//============================================= -{0xffff, 0x00c8}, //delay 200ms +{0xffff, 0x00c8}, //delay 200ms*/ }; -static struct regval_list sensor_720p_regs[] = { //1280*720 -/* preview setting */ -{0x002A, 0x18AC}, -{0x0F12, 0x0060}, //senHal_uAddColsBin -{0x0F12, 0x0060}, //senHal_uAddColsNoBin -{0x0F12, 0x05C0}, //senHal_uMinColsBin -{0x0F12, 0x0A96}, //05C0 //senHal_uMinColsNoBin +static struct regval_list sensor_qxga_regs[] = { //qxga: 2048*1536 + +//Preview config[0] 64480 7.5~15fps +{0x002A, 0x0306}, +{0x0F12, 0x0800}, //REG_0TC_PCFG_usWidth +{0x0F12, 0x0600}, //REG_0TC_PCFG_usHeight +{0x0F12, 0x0005}, //REG_0TC_PCFG_Format +{0x0F12, 0x279D}, //4F1A //REG_0TC_PCFG_usMaxOut4KHzRate +{0x0F12, 0x277D}, //4F1A //REG_0TC_PCFG_usMinOut4KHzRate +{0x0F12, 0x0100}, //REG_0TC_PCFG_OutClkPerPix88 +{0x0F12, 0x0300}, //REG_0TC_PCFG_uBpp88 +{0x0F12, 0x0012}, //REG_0TC_PCFG_PVIMask +{0x0F12, 0x0000}, //REG_0TC_PCFG_OIFMask +{0x0F12, 0x01E0}, //REG_0TC_PCFG_usJpegPacketSize +{0x0F12, 0x0000}, //REG_0TC_PCFG_usJpegTotalPackets +{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd +{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType +{0x0F12, 0x0002}, //REG_0TC_PCFG_FrRateQualityType +{0x0F12, 0x07D0}, //029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12, 0x0000}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 -//================================================================================== -// 19.Input Size Setting -//================================================================================== -//Input Size -{0x002A, 0x0250}, -{0x0F12, 0x0A00}, //REG_TC_GP_PrevReqInputWidth -{0x0F12, 0x05A0}, //REG_TC_GP_PrevReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_PrevInputWidthOfs -{0x0F12, 0x00FC}, //REG_TC_GP_PrevInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_GP_CapReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_CapReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_CapInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_CapInputHeightOfs - -{0x002A, 0x0494}, -{0x0F12, 0x0A00}, //REG_TC_PZOOM_ZoomInputWidth -{0x0F12, 0x05A0}, //REG_TC_PZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_CZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_CZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputHeightOfs - -{0x002A, 0x0262}, -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInPre -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInCap -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, -{0x002A, 0x02A6}, -{0x0F12, 0x0500}, //280 REG_0TC_PCFG_usWidth -{0x0F12, 0x02D0}, //1E0 REG_0TC_PCFG_usHeight -{0x002A, 0x02BC}, -{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd -{0x0F12, 0x0001}, //REG_0TC_PCFG_usFrTimeType -{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType -{0x0F12, 0x014D}, //REG_0TC_PCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x014D}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 - -{0x002A, 0x022C}, -{0x0F12, 0x0001}, //REG_TC_IPRM_InitParamsUpdated //================================================================================== -// 21.Select Cofigration Display +// 19.Select Cofigration Display //================================================================================== //PREVIEW -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, + +{0x0028, 0x7000},//many insert {0x002A, 0x0266}, -{0x0f12, 0x0000}, //REG_TC_GP_ActivePrevConfig +{0x0F12, 0x0002}, //REG_TC_GP_ActivePrevConfig {0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange +{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange {0x002A, 0x0268}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged -{0x002A, 0x026E}, -{0x0f12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_CapOpenAfterChange -{0x002A, 0x0270}, -{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged - +{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged {0x002A, 0x024E}, -{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync +{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync {0x002A, 0x023E}, -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +//============================================= -{0xffff, 0x00c8}, //delay 200ms +{0xffff, 0x00c8}, //delay 200ms*/ }; -static struct regval_list sensor_vga_regs[] = { //VGA: 640*480 -#if 0 //vga 7.5~30fps -/* preview setting */ -{0x002A, 0x18AC}, -{0x0F12, 0x0060}, //senHal_uAddColsBin -{0x0F12, 0x0060}, //senHal_uAddColsNoBin -{0x0F12, 0x05C0}, //senHal_uMinColsBin -{0x0F12, 0x05C0}, //senHal_uMinColsNoBin +//for video +static struct regval_list sensor_1080p_regs[] = { //1080: 1920*1080 +//Preview config[0] 64480 7.5~15fps +{0x0028,0x7000}, +{0x002A,0x0306}, +{0x0F12,0x0780}, //REG_2TC_PCFG_usWidth +{0x0F12,0x0438}, //REG_2TC_PCFG_usHeight +{0x0F12,0x0005}, //REG_2TC_PCFG_Format 5 YUV 7 Raw 9 JPG +{0x0F12,0x59D8}, //REG_2TC_PCFG_usMaxOut4KHzRate +{0x0F12,0x5988}, //REG_2TC_PCFG_usMinOut4KHzRate +{0x0F12,0x0100}, //REG_2TC_PCFG_OutClkPerPix88 +{0x0F12,0x0300}, //REG_2TC_PCFG_uBpp88 +{0x0F12,0x0012}, //REG_2TC_PCFG_PVIMask +{0x0F12,0x0000}, //REG_2TC_PCFG_OIFMask +{0x0F12,0x01E0}, //REG_2TC_PCFG_usJpegPacketSize +{0x0F12,0x0000}, //REG_2TC_PCFG_usJpegTotalPackets +{0x0F12,0x0002}, //REG_2TC_PCFG_uClockInd +{0x0F12,0x0000}, //REG_2TC_PCFG_usFrTimeType +{0x0F12,0x0002}, //REG_2TC_PCFG_FrRateQualityType +{0x0F12,0x02ca}, //REG_2TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12,0x0000}, //REG_2TC_PCFG_usMinFrTimeMsecMult10 -//================================================================================== -// 19.Input Size Setting -//================================================================================== -//Input Size -{0x002A, 0x0250}, -{0x0F12, 0x0A00}, //REG_TC_GP_PrevReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_PrevReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_PrevInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_PrevInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_GP_CapReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_CapReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_CapInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_CapInputHeightOfs - -{0x002A, 0x0494}, -{0x0F12, 0x0A00}, //REG_TC_PZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_PZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_CZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_CZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputHeightOfs - -{0x002A, 0x0262}, -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInPre -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInCap + +{0x002A,0x0266}, +{0x0F12,0x0002}, //REG_TC_GP_ActivePrevConfig +{0x002A,0x026A}, +{0x0F12,0x0001}, //REG_TC_GP_PrevOpenAfterChange +{0x002A,0x0268}, +{0x0F12,0x0001}, //REG_TC_GP_PrevConfigChanged +{0x002A,0x026E}, +{0x0F12,0x0000}, //REG_TC_GP_ActiveCapConfig +{0x002A,0x026A}, +{0x0F12,0x0001}, //REG_TC_GP_CapOpenAfterChange +{0x002A,0x0270}, +{0x0F12,0x0001}, //REG_TC_GP_CapConfigChanged +{0x002A,0x024E}, +{0x0F12,0x0001}, //REG_TC_GP_NewConfigSync +{0x002A,0x023E}, +{0x0F12,0x0001}, //REG_TC_GP_EnablePreview +{0x0F12,0x0001}, //REG_TC_GP_EnablePreviewChanged + +//============================================= + +{0xffff, 0x00c8}, //delay 200ms*/ -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0xFCFC, 0xD000}, + +}; + +static struct regval_list sensor_720p_regs[] = { //1280*720 + +//Preview config[0] 64480 7.5~15fps {0x0028, 0x7000}, -{0x002A, 0x02A6}, -{0x0F12, 0x0280}, //REG_0TC_PCFG_usWidth -{0x0F12, 0x01E0}, //REG_0TC_PCFG_usHeight -{0x002A, 0x02BC}, -{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd -{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType -{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType -{0x0F12, 0x0535}, //REG_0TC_PCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x014D}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 - -{0x002A, 0x022C}, -{0x0F12, 0x0001}, //REG_TC_IPRM_InitParamsUpdated +{0x002A, 0x02D6}, +{0x0F12, 0x0500}, //REG_0TC_PCFG_usWidth +{0x0F12, 0x02D0}, //REG_0TC_PCFG_usHeight +{0x0F12, 0x0005}, //REG_0TC_PCFG_Format +{0x0F12, 0x279D}, //4F1A //REG_0TC_PCFG_usMaxOut4KHzRate +{0x0F12, 0x277D}, //4F1A //REG_0TC_PCFG_usMinOut4KHzRate +{0x0F12, 0x0100}, //REG_0TC_PCFG_OutClkPerPix88 +{0x0F12, 0x0300}, //REG_0TC_PCFG_uBpp88 +{0x0F12, 0x0012}, //REG_0TC_PCFG_PVIMask +{0x0F12, 0x0000}, //REG_0TC_PCFG_OIFMask +{0x0F12, 0x01E0}, //REG_0TC_PCFG_usJpegPacketSize +{0x0F12, 0x0000}, //REG_0TC_PCFG_usJpegTotalPackets +{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd +{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType +{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType +{0x0F12, 0x0190}, //029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12, 0x014D}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 //================================================================================== -// 21.Select Cofigration Display +// 19.Select Cofigration Display //================================================================================== //PREVIEW -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, + +{0x0028, 0x7000},//many insert {0x002A, 0x0266}, -{0x0f12, 0x0000}, //REG_TC_GP_ActivePrevConfig +{0x0F12, 0x0001}, //REG_TC_GP_ActivePrevConfig {0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange +{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange {0x002A, 0x0268}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged -{0x002A, 0x026E}, -{0x0f12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_CapOpenAfterChange -{0x002A, 0x0270}, -{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged - +{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged {0x002A, 0x024E}, -{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync +{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync {0x002A, 0x023E}, -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +//============================================= -{0xffff, 0x00c8}, //delay 200ms -#else //vga fix 30fps -/* preview setting */ +{0xffff, 0x00c8}, //delay 200ms*/ -{0x002A, 0x18AC}, -{0x0F12, 0x0060}, //senHal_uAddColsBin -{0x0F12, 0x0060}, //senHal_uAddColsNoBin -{0x0F12, 0x05C0}, //senHal_uMinColsBin -{0x0F12, 0x05C0}, //05C0 //senHal_uMinColsNoBin +}; -//================================================================================== -// 19.Input Size Setting -//================================================================================== -//Input Size -{0x002A, 0x0250}, -{0x0F12, 0x0A00}, //REG_TC_GP_PrevReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_PrevReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_PrevInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_PrevInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_GP_CapReqInputWidth -{0x0F12, 0x0780}, //REG_TC_GP_CapReqInputHeight -{0x0F12, 0x0010}, //REG_TC_GP_CapInputWidthOfs -{0x0F12, 0x000C}, //REG_TC_GP_CapInputHeightOfs - -{0x002A, 0x0494}, -{0x0F12, 0x0A00}, //REG_TC_PZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_PZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_PZOOM_ZoomInputHeightOfs -{0x0F12, 0x0A00}, //REG_TC_CZOOM_ZoomInputWidth -{0x0F12, 0x0780}, //REG_TC_CZOOM_ZoomInputHeight -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputWidthOfs -{0x0F12, 0x0000}, //REG_TC_CZOOM_ZoomInputHeightOfs - -{0x002A, 0x0262}, -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInPre -{0x0F12, 0x0001}, //REG_TC_GP_bUseReqInputInCap +static struct regval_list sensor_vga_regs[] = { //VGA: 640*480 -//================================================================================== -// 20.Preview & Capture Configration Setting -//================================================================================== -{0xFCFC, 0xD000}, -{0x0028, 0x7000}, {0x002A, 0x02A6}, -{0x0F12, 0x0280}, //280 REG_0TC_PCFG_usWidth -{0x0F12, 0x01E0}, //1E0 REG_0TC_PCFG_usHeight -{0x002A, 0x02BC}, -{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd -{0x0F12, 0x0002}, //REG_0TC_PCFG_usFrTimeType -{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType -{0x0F12, 0x014D}, //REG_0TC_PCFG_usMaxFrTimeMsecMult10 -{0x0F12, 0x0000}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 +{0x0F12, 0x0280}, //REG_0TC_PCFG_usWidth +{0x0F12, 0x01E0}, //REG_0TC_PCFG_usHeight +{0x0F12, 0x0005}, //REG_0TC_PCFG_Format +{0x0F12, 0x279D}, //4F1A //REG_0TC_PCFG_usMaxOut4KHzRate +{0x0F12, 0x277D}, //4F1A //REG_0TC_PCFG_usMinOut4KHzRate +{0x0F12, 0x0100}, //REG_0TC_PCFG_OutClkPerPix88 +{0x0F12, 0x0300}, //REG_0TC_PCFG_uBpp88 +{0x0F12, 0x0012}, //REG_0TC_PCFG_PVIMask +{0x0F12, 0x0000}, //REG_0TC_PCFG_OIFMask +{0x0F12, 0x01E0}, //REG_0TC_PCFG_usJpegPacketSize +{0x0F12, 0x0000}, //REG_0TC_PCFG_usJpegTotalPackets +{0x0F12, 0x0000}, //REG_0TC_PCFG_uClockInd +{0x0F12, 0x0000}, //REG_0TC_PCFG_usFrTimeType +{0x0F12, 0x0001}, //REG_0TC_PCFG_FrRateQualityType +{0x0F12, 0x01A0}, //029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 +{0x0F12, 0x014A}, //REG_0TC_PCFG_usMinFrTimeMsecMult10 + //================================================================================== -// 21.Select Cofigration Display +// 19.Select Cofigration Display //================================================================================== //PREVIEW -{0x0028, 0x7000}, + +{0x0028, 0x7000},//many insert {0x002A, 0x0266}, -{0x0f12, 0x0000}, //REG_TC_GP_ActivePrevConfig +{0x0F12, 0x0000}, //REG_TC_GP_ActivePrevConfig {0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange +{0x0F12, 0x0001}, //REG_TC_GP_PrevOpenAfterChange {0x002A, 0x0268}, -{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged -{0x002A, 0x026E}, -{0x0f12, 0x0000}, //REG_TC_GP_ActiveCapConfig -{0x002A, 0x026A}, -{0x0F12, 0x0001}, //REG_TC_GP_CapOpenAfterChange -{0x002A, 0x0270}, -{0x0F12, 0x0001}, //REG_TC_GP_CapConfigChanged - +{0x0F12, 0x0001}, //REG_TC_GP_PrevConfigChanged {0x002A, 0x024E}, -{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync +{0x0F12, 0x0001}, //REG_TC_GP_NewConfigSync {0x002A, 0x023E}, -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview -{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreview +{0x0F12, 0x0001}, //REG_TC_GP_EnablePreviewChanged -//{0xffff, 0x00,150}, -#endif -//{0xFCFC, 0xD000}, -//{0x0028, 0x7000}, -//{0x002A, 0x0236}, -//{0x0F12, 0x0040}, //Control value }; #if 0 @@ -4101,13 +4685,13 @@ static struct regval_list sensor_brightness_neg1_regs[] = { static struct regval_list sensor_brightness_zero_regs[] = { {0x0028, 0x7000}, {0x002A, 0x1484}, -{0x0F12, 0x003C}, +{0x0F12, 0x0040}, }; static struct regval_list sensor_brightness_pos1_regs[] = { {0x0028, 0x7000}, {0x002A, 0x1484}, -{0x0F12, 0x0047}, +{0x0F12, 0x004A}, }; static struct regval_list sensor_brightness_pos2_regs[] = { @@ -4366,63 +4950,63 @@ static struct regval_list sensor_ev_neg4_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0080}, //Control value +{0x0F12, 0x0040}, //Control value 0080 }; static struct regval_list sensor_ev_neg3_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x00A0}, //Control value +{0x0F12, 0x0070}, //Control value 00A0 }; static struct regval_list sensor_ev_neg2_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x00C0}, //Control value +{0x0F12, 0x00A0}, //Control value 00C0 }; static struct regval_list sensor_ev_neg1_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x00E0}, //Control value +{0x0F12, 0x00D0}, //Control value 00E0 }; static struct regval_list sensor_ev_zero_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0100}, //Control value +{0x0F12, 0x0100}, //Control value 0100 }; static struct regval_list sensor_ev_pos1_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0120}, //Control value +{0x0F12, 0x0130}, //Control value 0120 }; static struct regval_list sensor_ev_pos2_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0140}, //Control value +{0x0F12, 0x0160}, //Control value 0140 }; static struct regval_list sensor_ev_pos3_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0160}, //Control value +{0x0F12, 0x0190}, //Control value 0160 }; static struct regval_list sensor_ev_pos4_regs[] = { {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x023A}, -{0x0F12, 0x0180}, //Control value +{0x0F12, 0x01C0}, //Control value 0180 }; static struct cfg_array sensor_ev[] = { @@ -4471,16 +5055,13 @@ static struct cfg_array sensor_ev[] = { * */ static struct regval_list sensor_fmt_mipi_yuv422[] = { - - +//uyvy {0xFCFC, 0xD000}, {0x0028, 0x7000}, {0x002A, 0x02B4}, -{0x0F12, 0x0040}, //REG_0TC_PCFG_PVIMask [5:4] YUYV 00 / UYVY 01 / YVYU 10 / VYUV 11 +{0x0F12, 0x0050}, //REG_0TC_PCFG_PVIMask [5:4] YUYV 00 / UYVY 01 / YVYU 10 / VYUV 11 {0x002A, 0x03A6}, -{0x0F12, 0x0040}, //REG_0TC_CCFG_PVIMask [5:4] YUYV 00 / UYVY 01 / YVYU 10 / VYUV 11 - - +{0x0F12, 0x0050}, //REG_0TC_CCFG_PVIMask [5:4] YUYV 00 / UYVY 01 / YVYU 10 / VYUV 11 @@ -4830,18 +5411,17 @@ static int sensor_s_vflip(struct v4l2_subdev *sd, int value) switch (value) { case 0: - pre_val &= 0xf5; - cap_val &= 0xf5; + pre_val = 0x0; + cap_val = 0x0; break; case 1: - pre_val |= 0x0A; - cap_val |= 0x0A; + pre_val = 0x01; + cap_val = 0x01; break; default: return -EINVAL; } - - sensor_write(sd, 0x0f12, pre_val); + sensor_write(sd, 0x0f12, pre_val); sensor_write(sd, 0x0f12, cap_val); ret = sensor_write_array(sd, regs, ARRAY_SIZE(regs)); @@ -5007,7 +5587,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) if (ret < 0) { vfe_dev_err("sensor_g_single_af read error !\n"); - ret = -EAGAIN; + ret = V4L2_AUTO_FOCUS_STATUS_FAILED; goto af_out; } @@ -5015,7 +5595,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) vfe_dev_dbg("Single AF 1st is busy,value = 0x%4x\n",rdval); msleep(50); coarse_af_pd = 0; - return EBUSY; + return V4L2_AUTO_FOCUS_STATUS_BUSY; } else if (rdval == 0x0002) { //focus ok coarse_af_pd = 1; @@ -5024,7 +5604,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) vfe_dev_print("Single AF 1st is failed,value = 0x%4x\n",rdval); info->focus_status = 0; //idle coarse_af_pd = 2; - ret = EFAULT; + ret = V4L2_AUTO_FOCUS_STATUS_FAILED; goto af_out; } } @@ -5047,7 +5627,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) if((rdval&0xff00)!=0x0000) { vfe_dev_dbg("Single AF 2nd is busy,value = 0x%4x\n",rdval); - return EBUSY; + return V4L2_AUTO_FOCUS_STATUS_BUSY; } vfe_dev_print("Single AF 2nd is complete,value = 0x%4x\n",rdval); @@ -5059,7 +5639,7 @@ static int sensor_g_single_af(struct v4l2_subdev *sd) //ae lock off sensor_ae_awb_lockoff(sd); - return ret; + return V4L2_AUTO_FOCUS_STATUS_REACHED; } static int sensor_g_contin_af(struct v4l2_subdev *sd) @@ -5225,7 +5805,7 @@ static int sensor_s_af_zone(struct v4l2_subdev *sd, xc=(x1+x2)/2; yc=(y1+y2)/2; #endif - vfe_dev_dbg("af zone input xc=%d,yc=%d\n",xc,yc); + vfe_dev_dbg("af zone input xc=%d,yc=%d,x1=%d,y1=%d,x2=%d,y2=%d\n",xc,yc,x1,y1,x2,y2); //first window @@ -5619,120 +6199,65 @@ static int sensor_s_flash_mode(struct v4l2_subdev *sd, static int sensor_power(struct v4l2_subdev *sd, int on) { - //int ret; - - //insure that clk_disable() and clk_enable() are called in pair - //when calling CSI_SUBDEV_STBY_ON/OFF and CSI_SUBDEV_PWR_ON/OFF - switch(on) + cci_lock(sd); + switch(on) { case CSI_SUBDEV_STBY_ON: vfe_dev_dbg("CSI_SUBDEV_STBY_ON\n"); -// //software standby -// ret = sensor_write_array(sd, sensor_sw_stby_on_regs, ARRAY_SIZE(sensor_sw_stby_on_regs)); -// if(ret < 0) -// vfe_dev_err("soft stby falied!\n"); -// usleep_range(10000,12000); -// //disable io oe -// vfe_dev_print("disalbe oe!\n"); -// ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs)); -// if(ret < 0) -// vfe_dev_err("disalbe oe falied!\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - usleep_range(1000,1200); - //standby on io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - usleep_range(1000,1200); - //inactive mclk after stadby in - vfe_set_mclk(sd,OFF); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(5000,12000); + vfe_set_mclk(sd,OFF); break; case CSI_SUBDEV_STBY_OFF: vfe_dev_dbg("CSI_SUBDEV_STBY_OFF\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //active mclk before stadby out vfe_set_mclk_freq(sd,MCLK); vfe_set_mclk(sd,ON); - usleep_range(1000,1200); - //standby off io - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); - usleep_range(1000,1200); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_OFF); - usleep_range(1000,1200); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); -// //software standby -// ret = sensor_write_array(sd, sensor_sw_stby_off_regs, ARRAY_SIZE(sensor_sw_stby_off_regs)); -// if(ret < 0) -// vfe_dev_err("soft stby off falied!\n"); -// usleep_range(10000,12000); + usleep_range(5000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(5000,12000); break; case CSI_SUBDEV_PWR_ON: vfe_dev_dbg("CSI_SUBDEV_PWR_ON\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //power on reset - vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output - vfe_gpio_set_status(sd,RESET,1);//set the gpio to output - //power down io - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //reset on io - vfe_gpio_write(sd,RESET,CSI_RST_ON); - //power supply - vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); - vfe_set_pmu_channel(sd,IOVDD,ON); - vfe_set_pmu_channel(sd,AVDD,ON); - vfe_set_pmu_channel(sd,DVDD,ON); - vfe_set_pmu_channel(sd,AFVDD,ON); + vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output + vfe_gpio_set_status(sd,RESET,1);//set the gpio to output + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); usleep_range(10000,12000); - //active mclk power on reset - vfe_set_mclk_freq(sd,MCLK); - vfe_set_mclk(sd,ON); - //power on reset - vfe_gpio_write(sd,PWDN,CSI_STBY_OFF); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON); + vfe_set_pmu_channel(sd,IOVDD,ON); + vfe_set_pmu_channel(sd,AFVDD,ON); + vfe_set_pmu_channel(sd,DVDD,ON); + vfe_set_pmu_channel(sd,AVDD,ON); usleep_range(10000,12000); - vfe_gpio_write(sd,RESET,CSI_RST_OFF); + vfe_set_mclk_freq(sd,MCLK); + vfe_set_mclk(sd,ON); + usleep_range(10000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH); + usleep_range(10000,12000); + vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH); usleep_range(10000,12000); - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); break; case CSI_SUBDEV_PWR_OFF: vfe_dev_dbg("CSI_SUBDEV_PWR_OFF\n"); - //make sure that no device can access i2c bus during sensor initial or power down - //when using i2c_lock_adpater function, the following codes must not access i2c bus before calling i2c_unlock_adapter - cci_lock(sd); - //reset on - vfe_gpio_write(sd,RESET,CSI_RST_ON); - udelay(100); - //inactive mclk before power off - vfe_set_mclk(sd,OFF); - udelay(10); - //standy on - vfe_gpio_write(sd,PWDN,CSI_STBY_ON); - //power supply off - vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); - vfe_set_pmu_channel(sd,IOVDD,OFF); - vfe_set_pmu_channel(sd,AVDD,OFF); - vfe_set_pmu_channel(sd,DVDD,OFF); - vfe_set_pmu_channel(sd,AFVDD,OFF); - //set the io to hi-z - vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input - vfe_gpio_set_status(sd,RESET,0);//set the gpio to input - //remember to unlock i2c adapter, so the device can access the i2c bus again - cci_unlock(sd); + vfe_gpio_write(sd,RESET,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_set_mclk(sd,OFF); + usleep_range(5000,12000); + vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW); + usleep_range(10000,12000); + vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF); + vfe_set_pmu_channel(sd,IOVDD,OFF); + vfe_set_pmu_channel(sd,AFVDD,OFF); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,AVDD,OFF); + usleep_range(10000,12000); + vfe_set_pmu_channel(sd,DVDD,OFF); + usleep_range(5000,12000); break; default: return -EINVAL; } - + cci_unlock(sd); return 0; } @@ -5823,12 +6348,21 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) info->width = 0; info->height = 0; - ret = sensor_write_array(sd, sensor_default_regs , ARRAY_SIZE(sensor_default_regs)); - if(ret < 0) { - vfe_dev_err("write sensor_default_regs error\n"); - return ret; - } - + //if(s5k4ec_firsttime==0) + //{ + vfe_dev_dbg("sensor_init sensor_write_array START\n"); + ret = sensor_write_array(sd, sensor_default_regs , ARRAY_SIZE(sensor_default_regs)); + if(ret < 0) { + vfe_dev_err("write sensor_default_regs error\n"); + return ret; + } + // s5k4ec_firsttime=1; + vfe_dev_dbg("sensor_init sensor_write_array OK\n"); + //} + //else + //{ + // vfe_dev_dbg("no need to init sensor_write_array\r\n"); + //} sensor_s_band_filter(sd, V4L2_CID_POWER_LINE_FREQUENCY_50HZ); if(info->stby_mode == 0) @@ -5840,8 +6374,29 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - int ret=0; - return ret; + int ret=0; + struct sensor_info *info = to_state(sd); +// vfe_dev_dbg("[]cmd=%d\n",cmd); +// vfe_dev_dbg("[]arg=%0x\n",arg); + switch(cmd) { + case GET_CURRENT_WIN_CFG: + if(info->current_wins != NULL) + { + memcpy( arg, + info->current_wins, + sizeof(struct sensor_win_size) ); + ret=0; + } + else + { + vfe_dev_err("empty wins!\n"); + ret=-1; + } + break; + default: + return -EINVAL; + } + return ret; } @@ -5913,30 +6468,33 @@ static struct sensor_format_struct { static struct sensor_win_size sensor_win_sizes[] = { /* qsxga: 2592*1936 */ { - .width = QSXGA_WIDTH, - .height = QSXGA_HEIGHT, + .width = QSXGA_WIDTH_S5K, + .height = QSXGA_HEIGHT_S5K, .regs = sensor_qsxga_regs, .hoffset = 0, .voffset = 0, + .mipi_bps = 200*1000*1000, .regs_size = ARRAY_SIZE(sensor_qsxga_regs), .set_size = NULL, }, /* qxga: 2048*1536 */ { - .width = QXGA_WIDTH, - .height = QXGA_HEIGHT, + .width = QXGA_WIDTH_S5K, + .height = QXGA_HEIGHT_S5K, .hoffset = 0, .voffset = 0, + .mipi_bps = 200*1000*1000, .regs = sensor_qxga_regs, .regs_size = ARRAY_SIZE(sensor_qxga_regs), .set_size = NULL, }, /* 1080P */ { - .width = HD1080_WIDTH, - .height = HD1080_HEIGHT, + .width = HD1080_WIDTH_S5K, + .height = HD1080_HEIGHT_S5K, .hoffset = 0, .voffset = 0, + .mipi_bps = 200*1000*1000, .regs = sensor_1080p_regs, .regs_size = ARRAY_SIZE(sensor_1080p_regs), .set_size = NULL, @@ -5944,20 +6502,22 @@ static struct sensor_win_size sensor_win_sizes[] = { /* 720p */ { - .width = HD720_WIDTH, - .height = HD720_HEIGHT, + .width = HD720_WIDTH_S5K, + .height = HD720_HEIGHT_S5K, .hoffset = 0, .voffset = 0, + .mipi_bps = 200*1000*1000, .regs = sensor_720p_regs, .regs_size = ARRAY_SIZE(sensor_720p_regs), .set_size = NULL, }, /* VGA */ { - .width = VGA_WIDTH, - .height = VGA_HEIGHT, + .width = VGA_WIDTH_S5K, + .height = VGA_HEIGHT_S5K, .hoffset = 0, .voffset = 0, + .mipi_bps = 200*1000*1000, .regs = sensor_vga_regs, .regs_size = ARRAY_SIZE(sensor_vga_regs), .set_size = NULL, @@ -6000,6 +6560,7 @@ static int sensor_try_fmt_internal(struct v4l2_subdev *sd, { int index; struct sensor_win_size *wsize; + struct sensor_info *info = to_state(sd); for (index = 0; index < N_FMTS; index++) if (sensor_formats[index].mbus_code == fmt->code) @@ -6037,6 +6598,8 @@ static int sensor_try_fmt_internal(struct v4l2_subdev *sd, fmt->height = wsize->height; fmt->reserved[0] = wsize->hoffset; fmt->reserved[1] = wsize->voffset; + info->current_wins = wsize; + vfe_dev_dbg("sensor_try_fmt_internal wsize->width = %d,wsize->height = %d,wsize->hoffset = %d,wsize->voffset = %d\n",wsize->width,wsize->height,wsize->hoffset,wsize->voffset); //pix->bytesperline = pix->width*sensor_formats[index].bpp; //pix->sizeimage = pix->height*pix->bytesperline; @@ -6052,10 +6615,9 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, static int sensor_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { - cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL ; - - return 0; + cfg->type = V4L2_MBUS_CSI2; + cfg->flags = 0|V4L2_MBUS_CSI2_2_LANE|V4L2_MBUS_CSI2_CHANNEL_0; + return 0; } /* diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg.h new file mode 100755 index 00000000..79a45c00 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg.h @@ -0,0 +1,844 @@ +/* +****************************************************************************************** +* +* ar0330_mipi_isp_cfg.h +* +* Hawkview ISP - ar0330_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/03/17 Automatic generation. +* +****************************************************************************************** +*/ + +#ifndef _AR0330_MIPI_ISP_CFG_H_V100_ +#define _AR0330_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param ar0330_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 1000, + .exp_line_end = 56000, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 3, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 32, + .isp_exp_line = 10000, + .isp_color_temp = 6000, + .ae_forced = 0, + .lum_forced = 0, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 0, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ar0330_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1600, + .fno = 20, + .ae_table_preview_length = 6, + .ae_table_preview = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 7500, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 6, + .ae_table_capture = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 7500, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 7500, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 8, + .ae_capture_speed = 8, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .ae_hist_mod_en = 0, + .awb_interval = 2, + .awb_speed = 16, + .awb_color_temper_low = 1900, + .awb_color_temper_high = 7500, + .awb_light_num = 9, + .awb_light_info = { + 563, 256, 110, 256, 256, 256, 75, 1900, 64, 40, + 537, 256, 120, 256, 256, 256, 75, 2000, 64, 40, + 513, 256, 131, 256, 256, 256, 75, 2100, 64, 42, + 488, 256, 142, 400, 256, 175, 75, 2500, 64, 45, + 462, 256, 150, 320, 256, 220, 75, 2800, 72, 55, + 365, 256, 192, 290, 256, 240, 60, 4000, 96, 55, + 318, 256, 231, 256, 256, 256, 60, 5000, 100, 55, + 303, 256, 292, 256, 256, 256, 65, 6500, 128, 55, + 281, 256, 326, 240, 256, 300, 55, 7500, 96, 30, + }, + .awb_ext_light_num = 5, + .awb_ext_light_info = { + 273, 256, 248, 256, 256, 256, 30, 6000, 128, 100, + 280, 256, 221, 256, 256, 256, 30, 5500, 128, 100, + 296, 256, 199, 256, 256, 256, 30, 4100, 128, 100, + 347, 256, 288, 256, 256, 256, 30, 6300, 128, 100, + 268, 256, 284, 256, 256, 256, 30, 6600, 128, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 405, 256, 263, 256, 256, 256, 35, 3500, 128, 100, + 431, 256, 247, 256, 256, 256, 35, 3300, 16, 100, + 384, 256, 272, 256, 256, 256, 35, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 151, 405, 210, 340, 210, 340, + 145, 480, 265, 256, 256, 256, 285, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param ar0330_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 0, 32, 1024, }, { 0, 255, 5, }, { 1, 6, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 15, -5, }, 50, { 32, 24, 2, 18, }, 6, 124, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 0, 32, 896, }, { 0, 255, 5, }, { 1, 6, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 10, -5, }, 50, { 32, 24, 4, 20, }, 10, 124, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 1, 32, 768, }, { 0, 255, 5, }, { 2, 8, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 10, -5, }, 36, { 32, 20, 6, 32, }, 14, 114, 4, + { 2, 12, 2, 200, }, { 3, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 3, 32, 512, }, { 0, 255, 5, }, { 3, 12, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 0, 5, }, 10, { 32, 18, 12, 32, }, 40, 85, 8, + { 2, 12, 2, 200, }, { 6, 0, }, { 40, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 4, 32, 450, }, { 0, 255, 5, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 0, 10, }, -8, { 32, 18, 16, 32, }, 30, 42, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 4, 32, 400, }, { 0, 255, 5, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 0, 10, }, -12, { 32, 18, 16, 32, }, 32, 15, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 108, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param ar0330_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 12, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 106, + .ver_visual_angle = 55, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 398, 256, 256, 419, -249, -160, -160, -262, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 319, 0, -63, }, { -88, 344, 0, }, { -51, -177, 484, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 391, -91, -44, }, { -63, 319, 0, }, { 0, -113, 369, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 389, -94, -39, }, { -54, 326, -16, }, { 0, -82, 338, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 2612, 12340, 12600, 12588, 12848, 2615, 12340, 12343, 12588, 13104, 2608, 12340, + 14645, 12588, 13104, 2611, 12340, 14388, 12588, 13104, 2613, 12340, 14131, 12588, 13104, 2616, 12340, 14130, + 12588, 13360, 2609, 12340, 13873, 12588, 13360, 2612, 12340, 13872, 12588, 13360, 2614, 14643, 13881, 12588, + 13360, 2617, 14643, 13624, 12588, 13616, 2610, 14643, 13623, 12588, 13616, 2612, 14643, 13622, 12588, 13616, + 2615, 14643, 13621, 12588, 13872, 2608, 14643, 13620, 12588, 13872, 2610, 14643, 13875, 12588, 13872, 2613, + 14643, 13874, 12588, 13872, 2616, 14643, 13873, 12588, 14128, 2608, 14643, 14128, 12588, 14128, 2611, 14387, + 14393, 12588, 14128, 2613, 14387, 14392, 12588, 14128, 2616, 14387, 14647, 12588, 14384, 2609, 14387, 12343, + 12588, 14384, 2611, 14387, 12598, 12588, 14384, 2614, 14387, 12853, 12588, 14384, 2616, 14387, 13108, 12588, + 14640, 2609, 14387, 13363, 12588, 14640, 2611, 14387, 13618, 12588, 14640, 2614, 14387, 13873, 12588, 14640, + 2616, 14387, 14384, 12588, 12337, 2609, 14131, 14649, 12588, 12337, 2611, 14131, 12601, 12588, 12337, 2614, + 14131, 12856, 12588, 12337, 2616, 14131, 13367, 12588, 12593, 2609, 14131, 13622, 12588, 12593, 2611, 14131, + 14133, 12588, 12593, 2614, 14131, 14644, 12588, 12593, 2616, 14131, 12596, 12588, 12849, 2608, 14131, 13107, + 12588, 12849, 2611, 14131, 13618, 12588, 12849, 2613, 14131, 14129, 12588, 12849, 2616, 14131, 14640, 12588, + 13105, 2608, 14131, 12592, 12588, 13105, 2611, 13875, 13113, 12588, 13105, 2613, 13875, 13880, 12588, 13105, + 2615, 13875, 14391, 12588, 13361, 2608, 13875, 12343, 12588, 13361, 2610, 13875, 13110, 12588, 13361, 2612, + 13875, 13621, 12588, 13361, 2615, 13875, 14388, 12588, 13361, 2617, 13875, 12340, 12588, 13617, 2610, 13875, + 13107, 12588, 13617, 2612, 13875, 13874, 12588, 13617, 2614, 13875, 14641, 12588, 13617, 2616, 13875, 12593, + 12588, 13873, 2609, 13875, 13360, 12588, 13873, 2611, 13619, 14137, 12588, 13873, 2613, 13619, 12345, 12588, + 13873, 2616, 13619, 13112, 12588, 14129, 2608, 13619, 13879, 12588, 14129, 2610, 13619, 14646, 12588, 14129, + 2612, 13619, 12854, 12588, 14129, 2615, 13619, 13877, 12588, 14129, 2617, 13619, 14644, 12588, 14385, 2609, + 13619, 12852, 12588, 14385, 2611, 13619, 13619, 12588, 14385, 2614, 13619, 14642, 12588, 14385, 2616, 13619, + 12850, 12588, 14641, 2608, 13619, 13873, 12588, 14641, 2610, 13619, 14640, 12588, 14641, 2613, 13619, 13104, + 12588, 14641, 2615, 13363, 13881, 12588, 14641, 2617, 13363, 12345, 12588, 12338, 2609, 13363, 13368, 12588, + 12338, 2611, 13363, 14135, 12588, 12338, 2614, 13363, 12599, 12588, 12338, 2616, 13363, 13622, 12588, 12594, + 2608, 13363, 14645, 12588, 12594, 2610, 13363, 13109, 12588, 12594, 2612, 13363, 13876, 12588, 12594, 2614, + 13363, 12340, 12588, 12594, 2616, 13363, 13363, 12588, 12850, 2609, 13363, 14386, 12588, 12850, 2611, 13363, + 12850, 12588, 12850, 2613, 13363, 14129, 12588, 12850, 2615, 13363, 12593, 12588, 12850, 2617, 13363, 13616, + 12588, 13106, 2609, 13107, 14649, 12588, 13106, 2611, 13107, 13113, 12588, 13106, 2613, 13107, 14136, 12588, + 13106, 2616, 13107, 12856, 12588, 13106, 2617, 13107, 13879, 12588, 13362, 2610, 13107, 12343, 12588, 13362, + 2612, 13107, 13622, 12588, 13362, 2614, 13107, 14645, 12588, 13362, 2616, 13107, 13365, 12588, 13618, 2608, + 13107, 14388, 12588, 13618, 2610, 13107, 13108, 12588, 13618, 2612, 13107, 14131, 12588, 13618, 2614, 13107, + 12851, 12588, 13618, 2616, 13107, 13874, 12588, 13874, 2608, 13107, 12594, 12588, 13874, 2610, 13107, 13873, + 12588, 13874, 2612, 13107, 12337, 12588, 13874, 2614, 13107, 13616, 12588, 13874, 2616, 13107, 12336, 12588, + 14130, 2608, 12851, 13625, 12588, 14130, 2610, 12851, 14648, 12588, 14130, 2612, 12851, 13368, 12588, 14130, + 2614, 12851, 14647, 12588, 14130, 2616, 12851, 13367, 12588, 14386, 2608, 12851, 14646, 12588, 14386, 2610, + 12851, 13366, 12588, 14386, 2612, 12851, 14645, 12588, 14386, 2614, 12851, 13365, 12588, 14386, 2616, 12851, + 14644, 12588, 14642, 2608, 12851, 13364, 12588, 14642, 2610, 12851, 14643, 12588, 14642, 2612, 12851, 13363, + 12588, 14642, 2614, 12851, 14642, 12588, 14642, 2616, 12851, 13362, 12588, 12339, 2608, 12851, 12338, 12588, + 12339, 2610, 12851, 13617, 12588, 12339, 2612, 12851, 12337, 12588, 12339, 2614, 12851, 13616, 12588, 12339, + 2616, 12851, 12592, 12588, 12339, 2617, 12595, 13881, 12588, 12595, 2610, 12595, 12601, 12588, 12595, 2612, + 12595, 14136, 12588, 12595, 2613, 12595, 12856, 12588, 12595, 2615, 12595, 14135, 12588, 12595, 2617, 12595, + 13111, 12588, 12851, 2609, 12595, 14390, 12588, 12851, 2611, 12595, 13366, 12588, 12851, 2613, 12595, 14645, + 12588, 12851, 2615, 12595, 13621, 12588, 12851, 2617, 12595, 12341, 12588, 13107, 2609, 12595, 13876, 12588, + 13107, 2610, 12595, 12596, 12588, 13107, 2613, 12595, 14131, 12588, 13107, 2614, 12595, 13107, 12588, 13107, + 2616, 12595, 14386, 12588, 13363, 2608, 12595, 13362, 12588, 13363, 2610, 12595, 14641, 12588, 13363, 2612, + 12595, 13617, 12588, 13363, 2614, 12595, 12593, 12588, 13363, 2615, 12595, 14128, 12588, 13363, 2617, 12595, + 12848, 12588, 13619, 2609, 12339, 14393, 12588, 13619, 2611, 12339, 13369, 12588, 13619, 2613, 12339, 12345, + 12588, 13619, 2615, 12339, 13880, 12588, 13619, 2616, 12339, 12600, 12588, 13875, 2609, 12339, 14135, 12588, + }, + .disc_tbl = { + 4095, 4081, 4070, 4059, 4048, 4037, 4027, 4016, 4006, 3996, 3985, 3975, 3965, 3955, 3945, 3936, + 3926, 3916, 3907, 3898, 3888, 3879, 3870, 3861, 3852, 3843, 3834, 3825, 3816, 3808, 3799, 3791, + 3782, 3774, 3765, 3757, 3749, 3741, 3733, 3725, 3717, 3709, 3701, 3693, 3686, 3678, 3670, 3663, + 3655, 3648, 3640, 3633, 3626, 3619, 3611, 3604, 3597, 3590, 3583, 3576, 3569, 3562, 3556, 3549, + 3542, 3535, 3529, 3522, 3516, 3509, 3503, 3496, 3490, 3484, 3477, 3471, 3465, 3459, 3453, 3446, + 3440, 3434, 3428, 3422, 3417, 3411, 3405, 3399, 3393, 3387, 3382, 3376, 3370, 3365, 3359, 3354, + 3348, 3343, 3337, 3332, 3326, 3321, 3316, 3310, 3305, 3300, 3295, 3289, 3284, 3279, 3274, 3269, + 3264, 3259, 3254, 3249, 3244, 3239, 3234, 3229, 3224, 3220, 3215, 3210, 3205, 3201, 3196, 3191, + 3187, 3182, 3177, 3173, 3168, 3164, 3159, 3155, 3150, 3146, 3141, 3137, 3133, 3128, 3124, 3119, + 3115, 3111, 3107, 3102, 3098, 3094, 3090, 3086, 3081, 3077, 3073, 3069, 3065, 3061, 3057, 3053, + 3049, 3045, 3041, 3037, 3033, 3029, 3025, 3021, 3018, 3014, 3010, 3006, 3002, 2999, 2995, 2991, + 2987, 2984, 2980, 2976, 2973, 2969, 2965, 2962, 2958, 2954, 2951, 2947, 2944, 2940, 2937, 2933, + 2930, 2926, 2923, 2919, 2916, 2912, 2909, 2906, 2902, 2899, 2896, 2892, 2889, 2886, 2882, 2879, + 2876, 2872, 2869, 2866, 2863, 2860, 2859, 2858, 2857, 2856, 2855, 2854, 2853, 2852, 2851, 2850, + 2849, 2848, 2847, 2846, 2845, 2844, 2843, 2842, 2841, 2840, 2839, 2838, 2837, 2836, 2835, 2834, + 2833, 2832, 2831, 2830, 2829, 2828, 2827, 2826, 2825, 2824, 2823, 2822, 2821, 2820, 2819, 2818, + 1024, 1027, 1030, 1033, 1035, 1038, 1041, 1044, 1046, 1049, 1052, 1054, 1057, 1060, 1062, 1065, + 1068, 1070, 1073, 1075, 1078, 1081, 1083, 1086, 1088, 1091, 1093, 1096, 1098, 1101, 1103, 1106, + 1108, 1111, 1113, 1116, 1118, 1120, 1123, 1125, 1128, 1130, 1133, 1135, 1137, 1140, 1142, 1144, + 1147, 1149, 1152, 1154, 1156, 1158, 1161, 1163, 1165, 1168, 1170, 1172, 1174, 1177, 1179, 1181, + 1183, 1186, 1188, 1190, 1192, 1195, 1197, 1199, 1201, 1203, 1206, 1208, 1210, 1212, 1214, 1216, + 1218, 1221, 1223, 1225, 1227, 1229, 1231, 1233, 1235, 1238, 1239, 1242, 1244, 1246, 1248, 1250, + 1252, 1254, 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294, 1296, 1298, 1300, 1302, 1304, 1306, 1308, 1309, 1312, 1314, + 1315, 1317, 1319, 1321, 1323, 1325, 1327, 1329, 1331, 1332, 1335, 1336, 1338, 1340, 1342, 1344, + 1346, 1347, 1349, 1351, 1353, 1355, 1357, 1358, 1361, 1362, 1364, 1366, 1368, 1369, 1371, 1373, + 1375, 1377, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + }, +}; +struct isp_cfg_pt ar0330_mipi_isp_cfg = +{ + .isp_test_settings = &ar0330_mipi_isp_test_settings, + .isp_3a_settings = &ar0330_mipi_isp_3a_settings, + .isp_tunning_settings = &ar0330_mipi_isp_tuning_settings, + .isp_iso_settings = &ar0330_mipi_isp_iso_settings, +}; +#endif /* end of _AR0330_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_ST6123.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_ST6123.h new file mode 100755 index 00000000..357b0d77 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_ST6123.h @@ -0,0 +1,846 @@ +/* +****************************************************************************************** +* +* ar0330_mipi_isp_cfg.h +* +* Hawkview ISP - ar0330_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/30 Automatic generation. +* +****************************************************************************************** +*/ + +//F2.2 ST_6123_A1 + +#ifndef _AR0330_MIPI_ISP_CFG_H_V100_ +#define _AR0330_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param ar0330_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 1000, + .exp_line_end = 56000, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 3, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 32, + .isp_exp_line = 10000, + .isp_color_temp = 6000, + .ae_forced = 0, + .lum_forced = 0, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 0, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ar0330_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1900, + .fno = 20, + .ae_table_preview_length = 6, + .ae_table_preview = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 6, + .ae_table_capture = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 8, + .ae_capture_speed = 8, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .ae_hist_mod_en = 0, + .awb_interval = 2, + .awb_speed = 32, + .awb_color_temper_low = 1900, + .awb_color_temper_high = 7500, + .awb_light_num = 9, + .awb_light_info = { + 563, 256, 110, 256, 256, 256, 75, 1900, 64, 40, + 537, 256, 120, 256, 256, 256, 75, 2000, 64, 40, + 513, 256, 131, 256, 256, 256, 75, 2100, 64, 42, + 488, 256, 142, 400, 256, 175, 75, 2500, 64, 45, + 462, 256, 150, 320, 256, 220, 75, 2800, 72, 55, + 365, 256, 192, 290, 256, 240, 60, 4000, 96, 55, + 318, 256, 231, 256, 256, 256, 60, 5000, 100, 55, + 303, 256, 292, 256, 256, 256, 60, 6500, 128, 55, + 281, 256, 326, 240, 256, 300, 30, 7500, 96, 25, + }, + .awb_ext_light_num = 5, + .awb_ext_light_info = { + 273, 256, 248, 256, 256, 256, 16, 6000, 128, 100, + 280, 256, 221, 256, 256, 256, 16, 5500, 128, 100, + 296, 256, 199, 256, 256, 256, 16, 4100, 128, 100, + 347, 256, 288, 256, 256, 256, 16, 6300, 128, 100, + 268, 256, 284, 256, 256, 256, 16, 6600, 128, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 405, 256, 263, 256, 256, 256, 20, 3500, 128, 100, + 431, 256, 247, 256, 256, 256, 20, 3300, 16, 100, + 384, 256, 272, 256, 256, 256, 20, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 151, 405, 210, 340, 210, 340, + 145, 480, 265, 256, 256, 256, 285, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param ar0330_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 1, 28, 1000, }, { 2, 255, 5, }, { 1, 6, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 1, -1, }, 50, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 800, }, { 2, 255, 5, }, { 1, 6, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 2, -2, }, 50, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 3, 24, 600, }, { 2, 255, 5, }, { 2, 8, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 3, -3, }, 36, { 32, 20, 6, 32, }, 14, 110, 4, + { 2, 12, 2, 200, }, { 3, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 4, 24, 512, }, { 5, 255, 5, }, { 3, 12, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 0, 3, }, 10, { 32, 18, 12, 32, }, 40, 60, 8, + { 2, 12, 2, 200, }, { 6, 0, }, { 40, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 5, 24,400,}, { 6, 255, 6, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -3, 8, }, -10, { 32, 18, 16, 32, }, 30, 30, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 6, 24, 300, }, { 6, 255, 7, }, { 5, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -5, 10, }, -20, { 32, 18, 16, 32, }, 32, 6, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 108, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param ar0330_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 12, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 82, + .ver_visual_angle = 45, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 398, 256, 256, 419, -249, -160, -160, -262, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 319, 0, -63, }, { -88, 344, 0, }, { -51, -177, 484, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 391, -91, -44, }, { -63, 319, 0, }, { 0, -113, 369, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 389, -94, -39, }, { -54, 326, -16, }, { 0, -82, 338, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 2612, 12340, 12600, 12588, 12848, 2615, 12340, 12343, 12588, 13104, 2608, 12340, + 14645, 12588, 13104, 2611, 12340, 14388, 12588, 13104, 2613, 12340, 14131, 12588, 13104, 2616, 12340, 14130, + 12588, 13360, 2609, 12340, 13873, 12588, 13360, 2612, 12340, 13872, 12588, 13360, 2614, 14643, 13881, 12588, + 13360, 2617, 14643, 13624, 12588, 13616, 2610, 14643, 13623, 12588, 13616, 2612, 14643, 13622, 12588, 13616, + 2615, 14643, 13621, 12588, 13872, 2608, 14643, 13620, 12588, 13872, 2610, 14643, 13875, 12588, 13872, 2613, + 14643, 13874, 12588, 13872, 2616, 14643, 13873, 12588, 14128, 2608, 14643, 14128, 12588, 14128, 2611, 14387, + 14393, 12588, 14128, 2613, 14387, 14392, 12588, 14128, 2616, 14387, 14647, 12588, 14384, 2609, 14387, 12343, + 12588, 14384, 2611, 14387, 12598, 12588, 14384, 2614, 14387, 12853, 12588, 14384, 2616, 14387, 13108, 12588, + 14640, 2609, 14387, 13363, 12588, 14640, 2611, 14387, 13618, 12588, 14640, 2614, 14387, 13873, 12588, 14640, + 2616, 14387, 14384, 12588, 12337, 2609, 14131, 14649, 12588, 12337, 2611, 14131, 12601, 12588, 12337, 2614, + 14131, 12856, 12588, 12337, 2616, 14131, 13367, 12588, 12593, 2609, 14131, 13622, 12588, 12593, 2611, 14131, + 14133, 12588, 12593, 2614, 14131, 14644, 12588, 12593, 2616, 14131, 12596, 12588, 12849, 2608, 14131, 13107, + 12588, 12849, 2611, 14131, 13618, 12588, 12849, 2613, 14131, 14129, 12588, 12849, 2616, 14131, 14640, 12588, + 13105, 2608, 14131, 12592, 12588, 13105, 2611, 13875, 13113, 12588, 13105, 2613, 13875, 13880, 12588, 13105, + 2615, 13875, 14391, 12588, 13361, 2608, 13875, 12343, 12588, 13361, 2610, 13875, 13110, 12588, 13361, 2612, + 13875, 13621, 12588, 13361, 2615, 13875, 14388, 12588, 13361, 2617, 13875, 12340, 12588, 13617, 2610, 13875, + 13107, 12588, 13617, 2612, 13875, 13874, 12588, 13617, 2614, 13875, 14641, 12588, 13617, 2616, 13875, 12593, + 12588, 13873, 2609, 13875, 13360, 12588, 13873, 2611, 13619, 14137, 12588, 13873, 2613, 13619, 12345, 12588, + 13873, 2616, 13619, 13112, 12588, 14129, 2608, 13619, 13879, 12588, 14129, 2610, 13619, 14646, 12588, 14129, + 2612, 13619, 12854, 12588, 14129, 2615, 13619, 13877, 12588, 14129, 2617, 13619, 14644, 12588, 14385, 2609, + 13619, 12852, 12588, 14385, 2611, 13619, 13619, 12588, 14385, 2614, 13619, 14642, 12588, 14385, 2616, 13619, + 12850, 12588, 14641, 2608, 13619, 13873, 12588, 14641, 2610, 13619, 14640, 12588, 14641, 2613, 13619, 13104, + 12588, 14641, 2615, 13363, 13881, 12588, 14641, 2617, 13363, 12345, 12588, 12338, 2609, 13363, 13368, 12588, + 12338, 2611, 13363, 14135, 12588, 12338, 2614, 13363, 12599, 12588, 12338, 2616, 13363, 13622, 12588, 12594, + 2608, 13363, 14645, 12588, 12594, 2610, 13363, 13109, 12588, 12594, 2612, 13363, 13876, 12588, 12594, 2614, + 13363, 12340, 12588, 12594, 2616, 13363, 13363, 12588, 12850, 2609, 13363, 14386, 12588, 12850, 2611, 13363, + 12850, 12588, 12850, 2613, 13363, 14129, 12588, 12850, 2615, 13363, 12593, 12588, 12850, 2617, 13363, 13616, + 12588, 13106, 2609, 13107, 14649, 12588, 13106, 2611, 13107, 13113, 12588, 13106, 2613, 13107, 14136, 12588, + 13106, 2616, 13107, 12856, 12588, 13106, 2617, 13107, 13879, 12588, 13362, 2610, 13107, 12343, 12588, 13362, + 2612, 13107, 13622, 12588, 13362, 2614, 13107, 14645, 12588, 13362, 2616, 13107, 13365, 12588, 13618, 2608, + 13107, 14388, 12588, 13618, 2610, 13107, 13108, 12588, 13618, 2612, 13107, 14131, 12588, 13618, 2614, 13107, + 12851, 12588, 13618, 2616, 13107, 13874, 12588, 13874, 2608, 13107, 12594, 12588, 13874, 2610, 13107, 13873, + 12588, 13874, 2612, 13107, 12337, 12588, 13874, 2614, 13107, 13616, 12588, 13874, 2616, 13107, 12336, 12588, + 14130, 2608, 12851, 13625, 12588, 14130, 2610, 12851, 14648, 12588, 14130, 2612, 12851, 13368, 12588, 14130, + 2614, 12851, 14647, 12588, 14130, 2616, 12851, 13367, 12588, 14386, 2608, 12851, 14646, 12588, 14386, 2610, + 12851, 13366, 12588, 14386, 2612, 12851, 14645, 12588, 14386, 2614, 12851, 13365, 12588, 14386, 2616, 12851, + 14644, 12588, 14642, 2608, 12851, 13364, 12588, 14642, 2610, 12851, 14643, 12588, 14642, 2612, 12851, 13363, + 12588, 14642, 2614, 12851, 14642, 12588, 14642, 2616, 12851, 13362, 12588, 12339, 2608, 12851, 12338, 12588, + 12339, 2610, 12851, 13617, 12588, 12339, 2612, 12851, 12337, 12588, 12339, 2614, 12851, 13616, 12588, 12339, + 2616, 12851, 12592, 12588, 12339, 2617, 12595, 13881, 12588, 12595, 2610, 12595, 12601, 12588, 12595, 2612, + 12595, 14136, 12588, 12595, 2613, 12595, 12856, 12588, 12595, 2615, 12595, 14135, 12588, 12595, 2617, 12595, + 13111, 12588, 12851, 2609, 12595, 14390, 12588, 12851, 2611, 12595, 13366, 12588, 12851, 2613, 12595, 14645, + 12588, 12851, 2615, 12595, 13621, 12588, 12851, 2617, 12595, 12341, 12588, 13107, 2609, 12595, 13876, 12588, + 13107, 2610, 12595, 12596, 12588, 13107, 2613, 12595, 14131, 12588, 13107, 2614, 12595, 13107, 12588, 13107, + 2616, 12595, 14386, 12588, 13363, 2608, 12595, 13362, 12588, 13363, 2610, 12595, 14641, 12588, 13363, 2612, + 12595, 13617, 12588, 13363, 2614, 12595, 12593, 12588, 13363, 2615, 12595, 14128, 12588, 13363, 2617, 12595, + 12848, 12588, 13619, 2609, 12339, 14393, 12588, 13619, 2611, 12339, 13369, 12588, 13619, 2613, 12339, 12345, + 12588, 13619, 2615, 12339, 13880, 12588, 13619, 2616, 12339, 12600, 12588, 13875, 2609, 12339, 14135, 12588, + }, + .disc_tbl = { + 4095, 4087, 4081, 4076, 4070, 4064, 4059, 4053, 4048, 4042, 4036, 4031, 4026, 4020, 4015, 4009, + 4004, 3999, 3993, 3988, 3983, 3978, 3973, 3967, 3962, 3957, 3952, 3947, 3942, 3937, 3932, 3927, + 3922, 3917, 3912, 3908, 3903, 3898, 3893, 3888, 3884, 3879, 3874, 3870, 3865, 3860, 3856, 3851, + 3846, 3842, 3837, 3833, 3828, 3824, 3820, 3815, 3811, 3806, 3802, 3798, 3793, 3789, 3785, 3780, + 3776, 3772, 3768, 3764, 3759, 3755, 3751, 3747, 3743, 3739, 3735, 3731, 3727, 3723, 3719, 3715, + 3711, 3707, 3703, 3699, 3695, 3691, 3687, 3683, 3679, 3676, 3672, 3668, 3664, 3660, 3657, 3653, + 3649, 3646, 3642, 3638, 3634, 3631, 3627, 3624, 3620, 3616, 3613, 3609, 3606, 3602, 3599, 3595, + 3592, 3588, 3585, 3581, 3578, 3574, 3571, 3567, 3564, 3561, 3557, 3554, 3550, 3547, 3544, 3540, + 3537, 3534, 3531, 3527, 3524, 3521, 3517, 3514, 3511, 3508, 3505, 3501, 3498, 3495, 3492, 3489, + 3486, 3483, 3479, 3476, 3473, 3470, 3467, 3464, 3461, 3458, 3455, 3452, 3449, 3446, 3443, 3440, + 3437, 3434, 3431, 3428, 3425, 3422, 3419, 3416, 3413, 3411, 3408, 3405, 3402, 3399, 3396, 3393, + 3391, 3388, 3385, 3382, 3379, 3377, 3374, 3371, 3368, 3366, 3363, 3360, 3357, 3355, 3352, 3349, + 3347, 3344, 3341, 3338, 3336, 3333, 3331, 3328, 3325, 3323, 3320, 3317, 3315, 3312, 3310, 3307, + 3305, 3302, 3299, 3297, 3294, 3292, 3291, 3290, 3289, 3288, 3287, 3286, 3285, 3284, 3283, 3282, + 3281, 3280, 3279, 3278, 3277, 3276, 3275, 3274, 3273, 3272, 3271, 3270, 3269, 3268, 3267, 3266, + 3265, 3264, 3263, 3262, 3261, 3260, 3259, 3258, 3257, 3256, 3255, 3254, 3253, 3252, 3251, 3250, + 1024, 1026, 1027, 1028, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1040, 1041, 1043, 1044, 1045, + 1047, 1048, 1050, 1051, 1052, 1054, 1055, 1057, 1058, 1059, 1061, 1062, 1063, 1065, 1066, 1067, + 1069, 1070, 1071, 1072, 1074, 1075, 1077, 1078, 1079, 1081, 1082, 1083, 1084, 1086, 1087, 1088, + 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1102, 1104, 1105, 1106, 1107, 1109, + 1110, 1111, 1112, 1114, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1125, 1126, 1127, 1128, + 1129, 1131, 1132, 1133, 1134, 1136, 1137, 1138, 1139, 1140, 1141, 1143, 1144, 1145, 1146, 1147, + 1149, 1150, 1151, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1164, 1165, 1166, + 1167, 1168, 1169, 1170, 1171, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1181, 1182, 1183, 1184, + 1185, 1186, 1187, 1188, 1189, 1190, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, + 1202, 1203, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, + 1220, 1221, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + }, +}; +struct isp_cfg_pt ar0330_mipi_isp_cfg = +{ + .isp_test_settings = &ar0330_mipi_isp_test_settings, + .isp_3a_settings = &ar0330_mipi_isp_3a_settings, + .isp_tunning_settings = &ar0330_mipi_isp_tuning_settings, + .isp_iso_settings = &ar0330_mipi_isp_iso_settings, +}; +#endif /* end of _AR0330_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_V3S_JV372T.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_V3S_JV372T.h new file mode 100755 index 00000000..54c108bb --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ar0330_mipi_isp_cfg_V3S_JV372T.h @@ -0,0 +1,846 @@ +/* +****************************************************************************************** +* +* ar0330_mipi_isp_cfg.h +* +* Hawkview ISP - ar0330_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/03/17 Automatic generation. +* +****************************************************************************************** +*/ + +//for V3S_JV372T + +#ifndef _AR0330_MIPI_ISP_CFG_H_V100_ +#define _AR0330_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param ar0330_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 1000, + .exp_line_end = 56000, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 3, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 32, + .isp_exp_line = 10000, + .isp_color_temp = 6000, + .ae_forced = 0, + .lum_forced = 0, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 0, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ar0330_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1900, + .fno = 20, + .ae_table_preview_length = 6, + .ae_table_preview = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 6, + .ae_table_capture = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 8, + .ae_capture_speed = 8, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .ae_hist_mod_en = 0, + .awb_interval = 2, + .awb_speed = 32, + .awb_color_temper_low = 1900, + .awb_color_temper_high = 7500, + .awb_light_num = 9, + .awb_light_info = { + 563, 256, 110, 256, 256, 256, 75, 1900, 64, 40, + 537, 256, 120, 256, 256, 256, 75, 2000, 64, 40, + 513, 256, 131, 256, 256, 256, 75, 2100, 64, 42, + 488, 256, 142, 400, 256, 175, 75, 2500, 64, 45, + 462, 256, 150, 320, 256, 220, 75, 2800, 72, 55, + 365, 256, 192, 290, 256, 240, 60, 4000, 96, 55, + 318, 256, 231, 256, 256, 256, 60, 5000, 100, 55, + 303, 256, 292, 256, 256, 256, 60, 6500, 128, 55, + 281, 256, 326, 240, 256, 300, 30, 7500, 96, 25, + }, + .awb_ext_light_num = 5, + .awb_ext_light_info = { + 273, 256, 248, 256, 256, 256, 16, 6000, 128, 100, + 280, 256, 221, 256, 256, 256, 16, 5500, 128, 100, + 296, 256, 199, 256, 256, 256, 16, 4100, 128, 100, + 347, 256, 288, 256, 256, 256, 16, 6300, 128, 100, + 268, 256, 284, 256, 256, 256, 16, 6600, 128, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 405, 256, 263, 256, 256, 256, 20, 3500, 128, 100, + 431, 256, 247, 256, 256, 256, 20, 3300, 16, 100, + 384, 256, 272, 256, 256, 256, 20, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 151, 405, 210, 340, 210, 340, + 145, 480, 265, 256, 256, 256, 285, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param ar0330_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 2, 28, 1000, }, { 2, 255, 5, }, { 1, 6, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 1, -1, }, 50, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 800, }, { 2, 255, 5, }, { 1, 6, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 2, -2, }, 50, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 1, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 4, 24, 600, }, { 2, 255, 5, }, { 2, 8, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 3, -3, }, 36, { 32, 20, 6, 32, }, 14, 110, 4, + { 2, 12, 2, 200, }, { 3, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 5, 24, 512, }, { 5, 255, 5, }, { 3, 12, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 0, 3, }, 10, { 32, 18, 12, 32, }, 40, 60, 8, + { 2, 12, 2, 200, }, { 6, 0, }, { 40, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 6, 24,400,}, { 6, 255, 6, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -3, 8, }, -2, { 32, 18, 16, 32, }, 30, 30, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 6, 24, 300, }, { 6, 255, 7, }, { 5, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -5, 10, }, -10, { 32, 18, 16, 32, }, 32, 6, 35, + { 2, 12, 2, 200, }, { 10, 0, }, { 108, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param ar0330_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 12, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 106, + .ver_visual_angle = 55, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 398, 256, 256, 419, -249, -160, -160, -262, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 319, 0, -63, }, { -88, 344, 0, }, { -51, -177, 484, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 391, -91, -44, }, { -63, 319, 0, }, { 0, -113, 369, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 389, -94, -39, }, { -54, 326, -16, }, { 0, -82, 338, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 2612, 12340, 12600, 12588, 12848, 2615, 12340, 12343, 12588, 13104, 2608, 12340, + 14645, 12588, 13104, 2611, 12340, 14388, 12588, 13104, 2613, 12340, 14131, 12588, 13104, 2616, 12340, 14130, + 12588, 13360, 2609, 12340, 13873, 12588, 13360, 2612, 12340, 13872, 12588, 13360, 2614, 14643, 13881, 12588, + 13360, 2617, 14643, 13624, 12588, 13616, 2610, 14643, 13623, 12588, 13616, 2612, 14643, 13622, 12588, 13616, + 2615, 14643, 13621, 12588, 13872, 2608, 14643, 13620, 12588, 13872, 2610, 14643, 13875, 12588, 13872, 2613, + 14643, 13874, 12588, 13872, 2616, 14643, 13873, 12588, 14128, 2608, 14643, 14128, 12588, 14128, 2611, 14387, + 14393, 12588, 14128, 2613, 14387, 14392, 12588, 14128, 2616, 14387, 14647, 12588, 14384, 2609, 14387, 12343, + 12588, 14384, 2611, 14387, 12598, 12588, 14384, 2614, 14387, 12853, 12588, 14384, 2616, 14387, 13108, 12588, + 14640, 2609, 14387, 13363, 12588, 14640, 2611, 14387, 13618, 12588, 14640, 2614, 14387, 13873, 12588, 14640, + 2616, 14387, 14384, 12588, 12337, 2609, 14131, 14649, 12588, 12337, 2611, 14131, 12601, 12588, 12337, 2614, + 14131, 12856, 12588, 12337, 2616, 14131, 13367, 12588, 12593, 2609, 14131, 13622, 12588, 12593, 2611, 14131, + 14133, 12588, 12593, 2614, 14131, 14644, 12588, 12593, 2616, 14131, 12596, 12588, 12849, 2608, 14131, 13107, + 12588, 12849, 2611, 14131, 13618, 12588, 12849, 2613, 14131, 14129, 12588, 12849, 2616, 14131, 14640, 12588, + 13105, 2608, 14131, 12592, 12588, 13105, 2611, 13875, 13113, 12588, 13105, 2613, 13875, 13880, 12588, 13105, + 2615, 13875, 14391, 12588, 13361, 2608, 13875, 12343, 12588, 13361, 2610, 13875, 13110, 12588, 13361, 2612, + 13875, 13621, 12588, 13361, 2615, 13875, 14388, 12588, 13361, 2617, 13875, 12340, 12588, 13617, 2610, 13875, + 13107, 12588, 13617, 2612, 13875, 13874, 12588, 13617, 2614, 13875, 14641, 12588, 13617, 2616, 13875, 12593, + 12588, 13873, 2609, 13875, 13360, 12588, 13873, 2611, 13619, 14137, 12588, 13873, 2613, 13619, 12345, 12588, + 13873, 2616, 13619, 13112, 12588, 14129, 2608, 13619, 13879, 12588, 14129, 2610, 13619, 14646, 12588, 14129, + 2612, 13619, 12854, 12588, 14129, 2615, 13619, 13877, 12588, 14129, 2617, 13619, 14644, 12588, 14385, 2609, + 13619, 12852, 12588, 14385, 2611, 13619, 13619, 12588, 14385, 2614, 13619, 14642, 12588, 14385, 2616, 13619, + 12850, 12588, 14641, 2608, 13619, 13873, 12588, 14641, 2610, 13619, 14640, 12588, 14641, 2613, 13619, 13104, + 12588, 14641, 2615, 13363, 13881, 12588, 14641, 2617, 13363, 12345, 12588, 12338, 2609, 13363, 13368, 12588, + 12338, 2611, 13363, 14135, 12588, 12338, 2614, 13363, 12599, 12588, 12338, 2616, 13363, 13622, 12588, 12594, + 2608, 13363, 14645, 12588, 12594, 2610, 13363, 13109, 12588, 12594, 2612, 13363, 13876, 12588, 12594, 2614, + 13363, 12340, 12588, 12594, 2616, 13363, 13363, 12588, 12850, 2609, 13363, 14386, 12588, 12850, 2611, 13363, + 12850, 12588, 12850, 2613, 13363, 14129, 12588, 12850, 2615, 13363, 12593, 12588, 12850, 2617, 13363, 13616, + 12588, 13106, 2609, 13107, 14649, 12588, 13106, 2611, 13107, 13113, 12588, 13106, 2613, 13107, 14136, 12588, + 13106, 2616, 13107, 12856, 12588, 13106, 2617, 13107, 13879, 12588, 13362, 2610, 13107, 12343, 12588, 13362, + 2612, 13107, 13622, 12588, 13362, 2614, 13107, 14645, 12588, 13362, 2616, 13107, 13365, 12588, 13618, 2608, + 13107, 14388, 12588, 13618, 2610, 13107, 13108, 12588, 13618, 2612, 13107, 14131, 12588, 13618, 2614, 13107, + 12851, 12588, 13618, 2616, 13107, 13874, 12588, 13874, 2608, 13107, 12594, 12588, 13874, 2610, 13107, 13873, + 12588, 13874, 2612, 13107, 12337, 12588, 13874, 2614, 13107, 13616, 12588, 13874, 2616, 13107, 12336, 12588, + 14130, 2608, 12851, 13625, 12588, 14130, 2610, 12851, 14648, 12588, 14130, 2612, 12851, 13368, 12588, 14130, + 2614, 12851, 14647, 12588, 14130, 2616, 12851, 13367, 12588, 14386, 2608, 12851, 14646, 12588, 14386, 2610, + 12851, 13366, 12588, 14386, 2612, 12851, 14645, 12588, 14386, 2614, 12851, 13365, 12588, 14386, 2616, 12851, + 14644, 12588, 14642, 2608, 12851, 13364, 12588, 14642, 2610, 12851, 14643, 12588, 14642, 2612, 12851, 13363, + 12588, 14642, 2614, 12851, 14642, 12588, 14642, 2616, 12851, 13362, 12588, 12339, 2608, 12851, 12338, 12588, + 12339, 2610, 12851, 13617, 12588, 12339, 2612, 12851, 12337, 12588, 12339, 2614, 12851, 13616, 12588, 12339, + 2616, 12851, 12592, 12588, 12339, 2617, 12595, 13881, 12588, 12595, 2610, 12595, 12601, 12588, 12595, 2612, + 12595, 14136, 12588, 12595, 2613, 12595, 12856, 12588, 12595, 2615, 12595, 14135, 12588, 12595, 2617, 12595, + 13111, 12588, 12851, 2609, 12595, 14390, 12588, 12851, 2611, 12595, 13366, 12588, 12851, 2613, 12595, 14645, + 12588, 12851, 2615, 12595, 13621, 12588, 12851, 2617, 12595, 12341, 12588, 13107, 2609, 12595, 13876, 12588, + 13107, 2610, 12595, 12596, 12588, 13107, 2613, 12595, 14131, 12588, 13107, 2614, 12595, 13107, 12588, 13107, + 2616, 12595, 14386, 12588, 13363, 2608, 12595, 13362, 12588, 13363, 2610, 12595, 14641, 12588, 13363, 2612, + 12595, 13617, 12588, 13363, 2614, 12595, 12593, 12588, 13363, 2615, 12595, 14128, 12588, 13363, 2617, 12595, + 12848, 12588, 13619, 2609, 12339, 14393, 12588, 13619, 2611, 12339, 13369, 12588, 13619, 2613, 12339, 12345, + 12588, 13619, 2615, 12339, 13880, 12588, 13619, 2616, 12339, 12600, 12588, 13875, 2609, 12339, 14135, 12588, + }, + .disc_tbl = { + 4095, 4081, 4070, 4059, 4048, 4037, 4027, 4016, 4006, 3996, 3985, 3975, 3965, 3955, 3945, 3936, + 3926, 3916, 3907, 3898, 3888, 3879, 3870, 3861, 3852, 3843, 3834, 3825, 3816, 3808, 3799, 3791, + 3782, 3774, 3765, 3757, 3749, 3741, 3733, 3725, 3717, 3709, 3701, 3693, 3686, 3678, 3670, 3663, + 3655, 3648, 3640, 3633, 3626, 3619, 3611, 3604, 3597, 3590, 3583, 3576, 3569, 3562, 3556, 3549, + 3542, 3535, 3529, 3522, 3516, 3509, 3503, 3496, 3490, 3484, 3477, 3471, 3465, 3459, 3453, 3446, + 3440, 3434, 3428, 3422, 3417, 3411, 3405, 3399, 3393, 3387, 3382, 3376, 3370, 3365, 3359, 3354, + 3348, 3343, 3337, 3332, 3326, 3321, 3316, 3310, 3305, 3300, 3295, 3289, 3284, 3279, 3274, 3269, + 3264, 3259, 3254, 3249, 3244, 3239, 3234, 3229, 3224, 3220, 3215, 3210, 3205, 3201, 3196, 3191, + 3187, 3182, 3177, 3173, 3168, 3164, 3159, 3155, 3150, 3146, 3141, 3137, 3133, 3128, 3124, 3119, + 3115, 3111, 3107, 3102, 3098, 3094, 3090, 3086, 3081, 3077, 3073, 3069, 3065, 3061, 3057, 3053, + 3049, 3045, 3041, 3037, 3033, 3029, 3025, 3021, 3018, 3014, 3010, 3006, 3002, 2999, 2995, 2991, + 2987, 2984, 2980, 2976, 2973, 2969, 2965, 2962, 2958, 2954, 2951, 2947, 2944, 2940, 2937, 2933, + 2930, 2926, 2923, 2919, 2916, 2912, 2909, 2906, 2902, 2899, 2896, 2892, 2889, 2886, 2882, 2879, + 2876, 2872, 2869, 2866, 2863, 2860, 2859, 2858, 2857, 2856, 2855, 2854, 2853, 2852, 2851, 2850, + 2849, 2848, 2847, 2846, 2845, 2844, 2843, 2842, 2841, 2840, 2839, 2838, 2837, 2836, 2835, 2834, + 2833, 2832, 2831, 2830, 2829, 2828, 2827, 2826, 2825, 2824, 2823, 2822, 2821, 2820, 2819, 2818, + 1024, 1027, 1030, 1033, 1035, 1038, 1041, 1044, 1046, 1049, 1052, 1054, 1057, 1060, 1062, 1065, + 1068, 1070, 1073, 1075, 1078, 1081, 1083, 1086, 1088, 1091, 1093, 1096, 1098, 1101, 1103, 1106, + 1108, 1111, 1113, 1116, 1118, 1120, 1123, 1125, 1128, 1130, 1133, 1135, 1137, 1140, 1142, 1144, + 1147, 1149, 1152, 1154, 1156, 1158, 1161, 1163, 1165, 1168, 1170, 1172, 1174, 1177, 1179, 1181, + 1183, 1186, 1188, 1190, 1192, 1195, 1197, 1199, 1201, 1203, 1206, 1208, 1210, 1212, 1214, 1216, + 1218, 1221, 1223, 1225, 1227, 1229, 1231, 1233, 1235, 1238, 1239, 1242, 1244, 1246, 1248, 1250, + 1252, 1254, 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294, 1296, 1298, 1300, 1302, 1304, 1306, 1308, 1309, 1312, 1314, + 1315, 1317, 1319, 1321, 1323, 1325, 1327, 1329, 1331, 1332, 1335, 1336, 1338, 1340, 1342, 1344, + 1346, 1347, 1349, 1351, 1353, 1355, 1357, 1358, 1361, 1362, 1364, 1366, 1368, 1369, 1371, 1373, + 1375, 1377, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + }, +}; +struct isp_cfg_pt ar0330_mipi_isp_cfg = +{ + .isp_test_settings = &ar0330_mipi_isp_test_settings, + .isp_3a_settings = &ar0330_mipi_isp_3a_settings, + .isp_tunning_settings = &ar0330_mipi_isp_tuning_settings, + .isp_iso_settings = &ar0330_mipi_isp_iso_settings, +}; +#endif /* end of _AR0330_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg.h new file mode 100755 index 00000000..a8416c60 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg.h @@ -0,0 +1,845 @@ +/* +****************************************************************************************** +* +* gc1004_mipi_isp_cfg.h +* +* Hawkview ISP - gc1004_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/24 Automatic generation. +* +****************************************************************************************** +*/ + +#ifndef _GC1004_MIPI_ISP_CFG_H_V100_ +#define _GC1004_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param gc1004_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 39520, + .exp_line_step = 16, + .exp_line_end = 39840, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 2, + .gain_end = 256, + .gain_change_interval = 4, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 237, + .isp_exp_line = 13000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 44, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param gc1004_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1488, + .fno = 20, + .ae_table_preview_length = 4, + .ae_table_preview = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 4, + .ae_table_capture = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 4, + .ae_table_video = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 6, + .ae_capture_speed = 6, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 4, + .awb_speed = 8, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 14, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 20, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 20, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 20, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 20, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 20, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 20, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 20, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 20, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 20, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 20, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 20, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 20, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 20, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 20, 8000, 128, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param gc1004_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 2, 28, 768, }, { 0, 255, 5, }, { 2, 9, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 30, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 768, }, { 1, 255, 5, }, { 2, 9, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 26, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 4, 24, 512, }, { 2, 255, 5, }, { 4, 16, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 16, { 32, 20, 6, 32, }, 14, 110, 5, + { 2, 12, 2, 200, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 8, 16, 400, }, { 3, 255, 5, }, { 5, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, -2, { 32, 18, 12, 32, }, 40, 60, 20, + { 2, 12, 2, 200, }, { 10, 0, }, { 64, 24, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 20, 12, 350, }, { 4, 255, 6, }, { 7, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 5, -5, }, -20, { 32, 18, 16, 32, }, 30, 22, 40, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 20, 8, 300, }, { 5, 255, 7, }, { 8, 28, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 5, -5, }, -32, { 32, 18, 16, 32, }, 32, 4, 40, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param gc1004_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 2, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 106, + .ver_visual_angle = 55, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 345, 256, 256, 285, 0, 0, 0, 0, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 306, -21, -29, }, { -161, 451, -34, }, { -155, -279, 690, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 366, -110, 0, }, { -80, 336, 0, }, { -39, -202, 497, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 385, -129, 0, }, { -104, 439, -79, }, { -42, -166, 464, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1023, 1028, 1039, 1047, 1056, 1064, 1077, 1088, 1103, 1116, 1131, 1145, 1162, 1178, 1195, 1208, + 1223, 1237, 1254, 1269, 1286, 1299, 1313, 1326, 1340, 1354, 1366, 1381, 1397, 1409, 1421, 1434, + 1444, 1451, 1458, 1468, 1477, 1486, 1493, 1501, 1509, 1517, 1524, 1533, 1543, 1551, 1556, 1562, + 1570, 1582, 1588, 1592, 1599, 1608, 1616, 1620, 1625, 1631, 1638, 1644, 1651, 1657, 1663, 1668, + 1676, 1681, 1686, 1692, 1698, 1704, 1709, 1716, 1721, 1726, 1731, 1736, 1741, 1747, 1754, 1759, + 1763, 1767, 1772, 1778, 1783, 1789, 1794, 1800, 1805, 1811, 1817, 1822, 1826, 1832, 1841, 1848, + 1854, 1860, 1863, 1868, 1875, 1884, 1888, 1897, 1905, 1911, 1915, 1923, 1930, 1936, 1947, 1958, + 1966, 1974, 1986, 1995, 1999, 2007, 2019, 2031, 2041, 2048, 2057, 2070, 2070, 2069, 2068, 2067, + 2066, 2065, 2064, 2063, 2063, 2062, 2061, 2060, 2059, 2058, 2057, 2056, 2055, 2055, 2054, 2053, + 2052, 2051, 2050, 2049, 2048, 2048, 2047, 2046, 2045, 2044, 2043, 2042, 2041, 2041, 2040, 2039, + 2038, 2037, 2036, 2035, 2034, 2034, 2033, 2032, 2031, 2030, 2029, 2028, 2027, 2026, 2026, 2025, + 2024, 2023, 2022, 2021, 2020, 2019, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2012, 2011, + 2010, 2009, 2008, 2007, 2006, 2005, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1998, 1997, + 1996, 1995, 1994, 1993, 1992, 1991, 1990, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983, 1983, + 1982, 1981, 1980, 1979, 1978, 1977, 1976, 1976, 1975, 1974, 1973, 1972, 1971, 1970, 1969, 1969, + 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1961, 1960, 1959, 1958, 1957, 1956, 1955, 1954, + 1021, 1030, 1039, 1048, 1057, 1064, 1078, 1091, 1107, 1123, 1146, 1159, 1166, 1174, 1191, 1217, + 1235, 1244, 1244, 1256, 1264, 1285, 1302, 1318, 1330, 1349, 1359, 1365, 1378, 1389, 1408, 1423, + 1431, 1434, 1446, 1459, 1465, 1466, 1467, 1476, 1494, 1503, 1509, 1515, 1519, 1524, 1534, 1540, + 1545, 1551, 1552, 1554, 1567, 1581, 1587, 1589, 1594, 1600, 1604, 1613, 1623, 1631, 1634, 1641, + 1642, 1647, 1651, 1658, 1661, 1663, 1663, 1666, 1674, 1684, 1690, 1697, 1698, 1700, 1697, 1703, + 1714, 1722, 1721, 1724, 1734, 1741, 1743, 1747, 1755, 1757, 1760, 1769, 1776, 1778, 1784, 1789, + 1793, 1797, 1801, 1806, 1813, 1820, 1822, 1828, 1835, 1840, 1849, 1854, 1858, 1863, 1868, 1874, + 1881, 1890, 1896, 1904, 1912, 1919, 1924, 1930, 1943, 1959, 1971, 1965, 1964, 1963, 1962, 1962, + 1961, 1960, 1959, 1958, 1957, 1957, 1956, 1955, 1954, 1953, 1952, 1952, 1951, 1950, 1949, 1948, + 1947, 1947, 1946, 1945, 1944, 1943, 1942, 1942, 1941, 1940, 1939, 1938, 1937, 1937, 1936, 1935, + 1934, 1933, 1932, 1932, 1931, 1930, 1929, 1928, 1927, 1927, 1926, 1925, 1924, 1923, 1922, 1922, + 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, 1912, 1912, 1911, 1910, 1909, 1908, + 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, 1899, 1898, 1897, 1897, 1896, 1895, + 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, 1886, 1885, 1884, 1883, 1882, 1882, + 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, + 1867, 1867, 1866, 1865, 1864, 1863, 1862, 1862, 1861, 1860, 1859, 1858, 1857, 1857, 1856, 1855, + 1023, 1026, 1034, 1041, 1049, 1056, 1066, 1076, 1087, 1098, 1109, 1122, 1135, 1149, 1163, 1173, + 1185, 1195, 1206, 1218, 1232, 1246, 1255, 1268, 1278, 1291, 1302, 1312, 1323, 1335, 1346, 1358, + 1370, 1375, 1381, 1391, 1400, 1408, 1417, 1426, 1433, 1441, 1451, 1456, 1462, 1469, 1478, 1485, + 1490, 1494, 1501, 1510, 1516, 1521, 1527, 1535, 1542, 1545, 1548, 1557, 1564, 1570, 1574, 1580, + 1585, 1591, 1594, 1599, 1605, 1611, 1615, 1620, 1628, 1635, 1641, 1647, 1653, 1657, 1662, 1665, + 1671, 1676, 1680, 1684, 1689, 1692, 1698, 1706, 1715, 1719, 1725, 1733, 1738, 1742, 1748, 1755, + 1759, 1761, 1765, 1772, 1778, 1782, 1782, 1786, 1793, 1800, 1807, 1816, 1822, 1828, 1833, 1838, + 1842, 1849, 1854, 1865, 1873, 1878, 1887, 1905, 1921, 1934, 1945, 1956, 1956, 1955, 1954, 1953, + 1952, 1951, 1951, 1950, 1949, 1948, 1947, 1946, 1946, 1945, 1944, 1943, 1942, 1941, 1941, 1940, + 1939, 1938, 1937, 1936, 1936, 1935, 1934, 1933, 1932, 1931, 1931, 1930, 1929, 1928, 1927, 1926, + 1926, 1925, 1924, 1923, 1922, 1922, 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, + 1912, 1912, 1911, 1910, 1909, 1908, 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, + 1899, 1898, 1897, 1897, 1896, 1895, 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, + 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1878, 1877, 1876, 1875, 1874, 1873, + 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1863, 1863, 1862, 1861, 1860, + 1859, 1858, 1858, 1857, 1856, 1855, 1854, 1853, 1853, 1852, 1851, 1850, 1849, 1848, 1848, 1847, + }, + { + /*1*/ + 1020, 1032, 1042, 1050, 1060, 1068, 1079, 1091, 1105, 1117, 1131, 1145, 1161, 1175, 1189, 1202, + 1217, 1231, 1245, 1262, 1278, 1292, 1306, 1318, 1330, 1342, 1354, 1366, 1379, 1390, 1400, 1413, + 1422, 1430, 1438, 1447, 1455, 1462, 1470, 1478, 1485, 1492, 1500, 1506, 1514, 1521, 1528, 1532, + 1538, 1545, 1554, 1561, 1567, 1572, 1577, 1581, 1586, 1591, 1597, 1603, 1608, 1612, 1618, 1623, + 1627, 1631, 1637, 1642, 1645, 1648, 1652, 1657, 1661, 1664, 1668, 1673, 1678, 1683, 1688, 1692, + 1697, 1702, 1707, 1712, 1716, 1719, 1723, 1727, 1734, 1741, 1745, 1747, 1752, 1758, 1765, 1769, + 1774, 1779, 1783, 1785, 1789, 1795, 1801, 1806, 1809, 1813, 1819, 1824, 1829, 1835, 1840, 1845, + 1850, 1854, 1862, 1871, 1880, 1885, 1891, 1900, 1906, 1909, 1913, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1025, 1032, 1041, 1053, 1064, 1073, 1086, 1100, 1117, 1135, 1160, 1175, 1180, 1189, 1206, 1235, + 1254, 1265, 1266, 1280, 1290, 1312, 1329, 1346, 1358, 1378, 1389, 1394, 1408, 1421, 1440, 1454, + 1461, 1466, 1478, 1492, 1498, 1501, 1502, 1512, 1529, 1540, 1545, 1549, 1552, 1559, 1570, 1576, + 1582, 1589, 1591, 1590, 1601, 1614, 1620, 1623, 1626, 1629, 1632, 1642, 1653, 1661, 1663, 1672, + 1674, 1679, 1682, 1686, 1687, 1687, 1685, 1688, 1695, 1706, 1709, 1714, 1715, 1718, 1717, 1720, + 1728, 1735, 1736, 1737, 1744, 1750, 1753, 1757, 1763, 1767, 1771, 1778, 1784, 1788, 1793, 1799, + 1803, 1806, 1811, 1817, 1822, 1827, 1831, 1836, 1839, 1844, 1851, 1856, 1862, 1865, 1871, 1875, + 1881, 1888, 1892, 1898, 1907, 1916, 1920, 1928, 1941, 1940, 1939, 1960, 1959, 1959, 1958, 1957, + 1956, 1955, 1954, 1954, 1953, 1952, 1951, 1950, 1949, 1949, 1948, 1947, 1946, 1945, 1944, 1944, + 1943, 1942, 1941, 1940, 1939, 1939, 1938, 1937, 1936, 1935, 1934, 1934, 1933, 1932, 1931, 1930, + 1929, 1929, 1928, 1927, 1926, 1925, 1924, 1924, 1923, 1922, 1921, 1920, 1919, 1919, 1918, 1917, + 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1904, 1904, + 1903, 1902, 1901, 1900, 1899, 1899, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, + 1889, 1889, 1888, 1887, 1886, 1885, 1884, 1884, 1883, 1882, 1881, 1880, 1879, 1879, 1878, 1877, + 1876, 1875, 1875, 1874, 1873, 1872, 1871, 1870, 1870, 1869, 1868, 1867, 1866, 1865, 1865, 1864, + 1863, 1862, 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, + 1021, 1031, 1042, 1051, 1060, 1070, 1082, 1093, 1106, 1120, 1135, 1150, 1165, 1179, 1195, 1209, + 1224, 1236, 1248, 1263, 1279, 1295, 1309, 1321, 1334, 1349, 1360, 1371, 1382, 1391, 1400, 1410, + 1419, 1425, 1435, 1447, 1456, 1462, 1472, 1480, 1488, 1492, 1501, 1507, 1515, 1521, 1528, 1534, + 1541, 1547, 1552, 1557, 1564, 1569, 1573, 1579, 1584, 1587, 1590, 1598, 1602, 1608, 1611, 1616, + 1619, 1627, 1631, 1635, 1637, 1642, 1644, 1647, 1650, 1655, 1658, 1662, 1665, 1667, 1668, 1672, + 1677, 1682, 1685, 1689, 1694, 1700, 1704, 1708, 1712, 1715, 1719, 1725, 1731, 1735, 1741, 1748, + 1753, 1758, 1762, 1766, 1771, 1777, 1781, 1787, 1790, 1792, 1794, 1802, 1809, 1815, 1818, 1821, + 1827, 1835, 1841, 1847, 1852, 1860, 1870, 1874, 1878, 1900, 1923, 1904, 1903, 1902, 1902, 1901, + 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1881, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1869, 1868, 1867, 1866, 1865, 1865, 1864, 1863, 1862, + 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1856, 1855, 1854, 1853, 1852, 1852, 1851, 1850, 1849, + 1848, 1848, 1847, 1846, 1845, 1844, 1844, 1843, 1842, 1841, 1840, 1839, 1839, 1838, 1837, 1836, + 1835, 1835, 1834, 1833, 1832, 1831, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, + 1822, 1822, 1821, 1820, 1819, 1818, 1818, 1817, 1816, 1815, 1814, 1814, 1813, 1812, 1811, 1810, + 1810, 1809, 1808, 1807, 1806, 1806, 1805, 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, + }, + { + /*2*/ + 1025, 1030, 1039, 1045, 1051, 1059, 1070, 1078, 1089, 1099, 1112, 1124, 1138, 1153, 1168, 1180, + 1193, 1204, 1218, 1230, 1246, 1259, 1271, 1281, 1294, 1307, 1320, 1333, 1347, 1358, 1369, 1381, + 1392, 1400, 1407, 1417, 1426, 1434, 1439, 1446, 1454, 1461, 1468, 1477, 1486, 1493, 1499, 1504, + 1512, 1522, 1527, 1531, 1536, 1542, 1548, 1552, 1556, 1561, 1568, 1574, 1579, 1586, 1592, 1598, + 1605, 1609, 1613, 1620, 1626, 1631, 1635, 1641, 1646, 1651, 1658, 1664, 1671, 1677, 1682, 1686, + 1689, 1695, 1703, 1709, 1713, 1718, 1724, 1729, 1734, 1740, 1745, 1748, 1753, 1761, 1768, 1773, + 1779, 1786, 1791, 1794, 1800, 1807, 1814, 1819, 1825, 1827, 1832, 1838, 1844, 1849, 1856, 1864, + 1874, 1883, 1892, 1902, 1909, 1916, 1926, 1939, 1946, 1954, 1967, 1978, 1977, 1977, 1976, 1975, + 1974, 1973, 1972, 1972, 1971, 1970, 1969, 1968, 1967, 1966, 1966, 1965, 1964, 1963, 1962, 1961, + 1961, 1960, 1959, 1958, 1957, 1956, 1956, 1955, 1954, 1953, 1952, 1951, 1951, 1950, 1949, 1948, + 1947, 1946, 1945, 1945, 1944, 1943, 1942, 1941, 1940, 1940, 1939, 1938, 1937, 1936, 1935, 1935, + 1934, 1933, 1932, 1931, 1930, 1930, 1929, 1928, 1927, 1926, 1925, 1925, 1924, 1923, 1922, 1921, + 1920, 1919, 1919, 1918, 1917, 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, + 1907, 1906, 1905, 1904, 1904, 1903, 1902, 1901, 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, + 1893, 1893, 1892, 1891, 1890, 1889, 1888, 1888, 1887, 1886, 1885, 1884, 1883, 1883, 1882, 1881, + 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, 1867, + 1024, 1028, 1033, 1039, 1046, 1051, 1061, 1070, 1082, 1096, 1113, 1124, 1129, 1137, 1149, 1171, + 1186, 1192, 1191, 1201, 1209, 1228, 1242, 1258, 1268, 1286, 1295, 1300, 1312, 1324, 1342, 1356, + 1363, 1365, 1375, 1387, 1392, 1394, 1395, 1404, 1419, 1427, 1432, 1437, 1440, 1447, 1456, 1463, + 1468, 1473, 1473, 1474, 1485, 1497, 1502, 1503, 1508, 1512, 1517, 1525, 1533, 1542, 1544, 1550, + 1551, 1557, 1561, 1566, 1566, 1566, 1564, 1567, 1575, 1585, 1590, 1595, 1595, 1599, 1597, 1602, + 1610, 1618, 1617, 1618, 1626, 1634, 1638, 1640, 1647, 1651, 1655, 1662, 1667, 1669, 1675, 1681, + 1683, 1686, 1689, 1692, 1697, 1705, 1709, 1713, 1717, 1720, 1727, 1731, 1735, 1741, 1743, 1750, + 1757, 1766, 1772, 1782, 1788, 1794, 1804, 1811, 1818, 1832, 1846, 1845, 1844, 1844, 1843, 1842, + 1841, 1840, 1840, 1839, 1838, 1837, 1837, 1836, 1835, 1834, 1833, 1833, 1832, 1831, 1830, 1830, + 1829, 1828, 1827, 1826, 1826, 1825, 1824, 1823, 1822, 1822, 1821, 1820, 1819, 1819, 1818, 1817, + 1816, 1815, 1815, 1814, 1813, 1812, 1812, 1811, 1810, 1809, 1808, 1808, 1807, 1806, 1805, 1804, + 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, 1797, 1796, 1795, 1794, 1794, 1793, 1792, + 1791, 1790, 1790, 1789, 1788, 1787, 1786, 1786, 1785, 1784, 1783, 1783, 1782, 1781, 1780, 1779, + 1779, 1778, 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1772, 1771, 1770, 1769, 1768, 1768, 1767, + 1766, 1765, 1765, 1764, 1763, 1762, 1761, 1761, 1760, 1759, 1758, 1757, 1757, 1756, 1755, 1754, + 1754, 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1743, 1743, 1742, + 1022, 1024, 1030, 1034, 1038, 1043, 1052, 1060, 1068, 1076, 1085, 1096, 1107, 1119, 1130, 1139, + 1147, 1156, 1164, 1174, 1186, 1200, 1211, 1221, 1231, 1245, 1254, 1264, 1276, 1286, 1296, 1303, + 1312, 1317, 1324, 1334, 1342, 1347, 1354, 1363, 1369, 1375, 1382, 1387, 1392, 1398, 1404, 1408, + 1413, 1419, 1424, 1429, 1433, 1437, 1442, 1449, 1454, 1458, 1462, 1468, 1472, 1477, 1481, 1487, + 1491, 1495, 1498, 1501, 1505, 1509, 1512, 1515, 1520, 1526, 1531, 1536, 1538, 1539, 1541, 1546, + 1551, 1554, 1556, 1559, 1567, 1572, 1576, 1582, 1587, 1589, 1593, 1598, 1603, 1606, 1611, 1615, + 1619, 1624, 1628, 1635, 1641, 1646, 1648, 1652, 1656, 1660, 1665, 1670, 1674, 1678, 1683, 1690, + 1698, 1704, 1711, 1718, 1725, 1735, 1744, 1751, 1752, 1769, 1785, 1781, 1780, 1779, 1778, 1778, + 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1771, 1771, 1770, 1769, 1768, 1768, 1767, 1766, 1765, + 1765, 1764, 1763, 1762, 1762, 1761, 1760, 1759, 1759, 1758, 1757, 1756, 1756, 1755, 1754, 1753, + 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1744, 1743, 1742, 1741, + 1741, 1740, 1739, 1738, 1737, 1737, 1736, 1735, 1734, 1734, 1733, 1732, 1731, 1731, 1730, 1729, + 1728, 1728, 1727, 1726, 1725, 1725, 1724, 1723, 1722, 1722, 1721, 1720, 1719, 1719, 1718, 1717, + 1716, 1716, 1715, 1714, 1713, 1713, 1712, 1711, 1710, 1710, 1709, 1708, 1707, 1707, 1706, 1705, + 1704, 1703, 1703, 1702, 1701, 1700, 1700, 1699, 1698, 1697, 1697, 1696, 1695, 1694, 1694, 1693, + 1692, 1691, 1691, 1690, 1689, 1688, 1688, 1687, 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, + }, + { + /*3*/ + 1022, 1029, 1038, 1046, 1054, 1061, 1071, 1081, 1094, 1105, 1118, 1131, 1145, 1160, 1175, 1187, + 1202, 1215, 1230, 1244, 1259, 1273, 1286, 1298, 1311, 1323, 1334, 1348, 1360, 1373, 1385, 1396, + 1406, 1415, 1423, 1432, 1440, 1450, 1457, 1465, 1474, 1483, 1490, 1497, 1505, 1512, 1519, 1526, + 1533, 1539, 1546, 1553, 1560, 1566, 1573, 1582, 1587, 1592, 1596, 1601, 1606, 1610, 1615, 1619, + 1625, 1632, 1638, 1643, 1648, 1651, 1654, 1660, 1666, 1670, 1671, 1674, 1679, 1686, 1693, 1700, + 1702, 1704, 1710, 1714, 1718, 1723, 1730, 1734, 1739, 1744, 1749, 1754, 1761, 1767, 1772, 1776, + 1781, 1784, 1789, 1794, 1799, 1802, 1805, 1809, 1817, 1823, 1830, 1833, 1841, 1847, 1852, 1856, + 1863, 1869, 1875, 1882, 1891, 1896, 1901, 1903, 1910, 1920, 1932, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1024, 1029, 1033, 1038, 1044, 1048, 1055, 1062, 1072, 1084, 1097, 1106, 1110, 1117, 1129, 1149, + 1162, 1168, 1169, 1177, 1186, 1202, 1215, 1227, 1237, 1254, 1261, 1266, 1277, 1286, 1302, 1314, + 1320, 1324, 1334, 1346, 1353, 1355, 1355, 1365, 1378, 1385, 1391, 1395, 1398, 1404, 1413, 1418, + 1422, 1429, 1432, 1433, 1442, 1450, 1455, 1457, 1462, 1465, 1469, 1476, 1482, 1488, 1492, 1498, + 1501, 1504, 1507, 1512, 1514, 1516, 1517, 1522, 1525, 1530, 1532, 1537, 1539, 1540, 1542, 1546, + 1551, 1555, 1559, 1562, 1566, 1568, 1572, 1574, 1578, 1584, 1587, 1588, 1590, 1595, 1599, 1602, + 1608, 1612, 1616, 1619, 1622, 1625, 1630, 1636, 1639, 1645, 1648, 1654, 1660, 1661, 1672, 1674, + 1678, 1680, 1685, 1689, 1704, 1710, 1702, 1713, 1734, 1722, 1700, 1737, 1736, 1735, 1735, 1734, + 1733, 1732, 1732, 1731, 1730, 1729, 1729, 1728, 1727, 1727, 1726, 1725, 1724, 1724, 1723, 1722, + 1721, 1721, 1720, 1719, 1718, 1718, 1717, 1716, 1715, 1715, 1714, 1713, 1713, 1712, 1711, 1710, + 1710, 1709, 1708, 1707, 1707, 1706, 1705, 1704, 1704, 1703, 1702, 1701, 1701, 1700, 1699, 1699, + 1698, 1697, 1696, 1696, 1695, 1694, 1693, 1693, 1692, 1691, 1690, 1690, 1689, 1688, 1687, 1687, + 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, 1680, 1679, 1679, 1678, 1677, 1676, 1676, 1675, + 1674, 1673, 1673, 1672, 1671, 1670, 1670, 1669, 1668, 1668, 1667, 1666, 1665, 1665, 1664, 1663, + 1662, 1662, 1661, 1660, 1659, 1659, 1658, 1657, 1656, 1656, 1655, 1654, 1654, 1653, 1652, 1651, + 1651, 1650, 1649, 1648, 1648, 1647, 1646, 1645, 1645, 1644, 1643, 1642, 1642, 1641, 1640, 1640, + 1022, 1025, 1028, 1032, 1037, 1042, 1047, 1054, 1061, 1069, 1077, 1085, 1092, 1100, 1108, 1117, + 1126, 1134, 1141, 1150, 1159, 1169, 1177, 1184, 1192, 1199, 1207, 1214, 1223, 1230, 1237, 1246, + 1254, 1259, 1264, 1272, 1279, 1283, 1289, 1297, 1302, 1308, 1313, 1318, 1324, 1328, 1333, 1338, + 1344, 1347, 1351, 1355, 1363, 1370, 1373, 1376, 1381, 1385, 1386, 1391, 1396, 1401, 1404, 1407, + 1410, 1414, 1419, 1422, 1422, 1424, 1425, 1428, 1430, 1431, 1434, 1441, 1444, 1444, 1447, 1450, + 1455, 1456, 1458, 1459, 1464, 1467, 1470, 1472, 1476, 1479, 1482, 1487, 1491, 1493, 1497, 1504, + 1507, 1509, 1514, 1516, 1518, 1521, 1524, 1527, 1529, 1531, 1536, 1541, 1547, 1551, 1556, 1558, + 1564, 1567, 1572, 1576, 1582, 1581, 1581, 1587, 1594, 1599, 1604, 1611, 1611, 1610, 1609, 1609, + 1608, 1607, 1607, 1606, 1605, 1605, 1604, 1603, 1602, 1602, 1601, 1600, 1600, 1599, 1598, 1598, + 1597, 1596, 1596, 1595, 1594, 1594, 1593, 1592, 1592, 1591, 1590, 1590, 1589, 1588, 1587, 1587, + 1586, 1585, 1585, 1584, 1583, 1583, 1582, 1581, 1581, 1580, 1579, 1579, 1578, 1577, 1577, 1576, + 1575, 1574, 1574, 1573, 1572, 1572, 1571, 1570, 1570, 1569, 1568, 1568, 1567, 1566, 1566, 1565, + 1564, 1564, 1563, 1562, 1561, 1561, 1560, 1559, 1559, 1558, 1557, 1557, 1556, 1555, 1555, 1554, + 1553, 1553, 1552, 1551, 1551, 1550, 1549, 1548, 1548, 1547, 1546, 1546, 1545, 1544, 1544, 1543, + 1542, 1542, 1541, 1540, 1540, 1539, 1538, 1538, 1537, 1536, 1535, 1535, 1534, 1533, 1533, 1532, + 1531, 1531, 1530, 1529, 1529, 1528, 1527, 1527, 1526, 1525, 1525, 1524, 1523, 1522, 1522, 1521, + }, + { + /*4*/ + 1023, 1028, 1039, 1047, 1056, 1064, 1077, 1088, 1103, 1116, 1131, 1145, 1162, 1178, 1195, 1208, + 1223, 1237, 1254, 1269, 1286, 1299, 1313, 1326, 1340, 1354, 1366, 1381, 1397, 1409, 1421, 1434, + 1444, 1451, 1458, 1468, 1477, 1486, 1493, 1501, 1509, 1517, 1524, 1533, 1543, 1551, 1556, 1562, + 1570, 1582, 1588, 1592, 1599, 1608, 1616, 1620, 1625, 1631, 1638, 1644, 1651, 1657, 1663, 1668, + 1676, 1681, 1686, 1692, 1698, 1704, 1709, 1716, 1721, 1726, 1731, 1736, 1741, 1747, 1754, 1759, + 1763, 1767, 1772, 1778, 1783, 1789, 1794, 1800, 1805, 1811, 1817, 1822, 1826, 1832, 1841, 1848, + 1854, 1860, 1863, 1868, 1875, 1884, 1888, 1897, 1905, 1911, 1915, 1923, 1930, 1936, 1947, 1958, + 1966, 1974, 1986, 1995, 1999, 2007, 2019, 2031, 2041, 2048, 2057, 2070, 2070, 2069, 2068, 2067, + 2066, 2065, 2064, 2063, 2063, 2062, 2061, 2060, 2059, 2058, 2057, 2056, 2055, 2055, 2054, 2053, + 2052, 2051, 2050, 2049, 2048, 2048, 2047, 2046, 2045, 2044, 2043, 2042, 2041, 2041, 2040, 2039, + 2038, 2037, 2036, 2035, 2034, 2034, 2033, 2032, 2031, 2030, 2029, 2028, 2027, 2026, 2026, 2025, + 2024, 2023, 2022, 2021, 2020, 2019, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2012, 2011, + 2010, 2009, 2008, 2007, 2006, 2005, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1998, 1997, + 1996, 1995, 1994, 1993, 1992, 1991, 1990, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983, 1983, + 1982, 1981, 1980, 1979, 1978, 1977, 1976, 1976, 1975, 1974, 1973, 1972, 1971, 1970, 1969, 1969, + 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1961, 1960, 1959, 1958, 1957, 1956, 1955, 1954, + 1021, 1030, 1039, 1048, 1057, 1064, 1078, 1091, 1107, 1123, 1146, 1159, 1166, 1174, 1191, 1217, + 1235, 1244, 1244, 1256, 1264, 1285, 1302, 1318, 1330, 1349, 1359, 1365, 1378, 1389, 1408, 1423, + 1431, 1434, 1446, 1459, 1465, 1466, 1467, 1476, 1494, 1503, 1509, 1515, 1519, 1524, 1534, 1540, + 1545, 1551, 1552, 1554, 1567, 1581, 1587, 1589, 1594, 1600, 1604, 1613, 1623, 1631, 1634, 1641, + 1642, 1647, 1651, 1658, 1661, 1663, 1663, 1666, 1674, 1684, 1690, 1697, 1698, 1700, 1697, 1703, + 1714, 1722, 1721, 1724, 1734, 1741, 1743, 1747, 1755, 1757, 1760, 1769, 1776, 1778, 1784, 1789, + 1793, 1797, 1801, 1806, 1813, 1820, 1822, 1828, 1835, 1840, 1849, 1854, 1858, 1863, 1868, 1874, + 1881, 1890, 1896, 1904, 1912, 1919, 1924, 1930, 1943, 1959, 1971, 1965, 1964, 1963, 1962, 1962, + 1961, 1960, 1959, 1958, 1957, 1957, 1956, 1955, 1954, 1953, 1952, 1952, 1951, 1950, 1949, 1948, + 1947, 1947, 1946, 1945, 1944, 1943, 1942, 1942, 1941, 1940, 1939, 1938, 1937, 1937, 1936, 1935, + 1934, 1933, 1932, 1932, 1931, 1930, 1929, 1928, 1927, 1927, 1926, 1925, 1924, 1923, 1922, 1922, + 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, 1912, 1912, 1911, 1910, 1909, 1908, + 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, 1899, 1898, 1897, 1897, 1896, 1895, + 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, 1886, 1885, 1884, 1883, 1882, 1882, + 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, + 1867, 1867, 1866, 1865, 1864, 1863, 1862, 1862, 1861, 1860, 1859, 1858, 1857, 1857, 1856, 1855, + 1023, 1026, 1034, 1041, 1049, 1056, 1066, 1076, 1087, 1098, 1109, 1122, 1135, 1149, 1163, 1173, + 1185, 1195, 1206, 1218, 1232, 1246, 1255, 1268, 1278, 1291, 1302, 1312, 1323, 1335, 1346, 1358, + 1370, 1375, 1381, 1391, 1400, 1408, 1417, 1426, 1433, 1441, 1451, 1456, 1462, 1469, 1478, 1485, + 1490, 1494, 1501, 1510, 1516, 1521, 1527, 1535, 1542, 1545, 1548, 1557, 1564, 1570, 1574, 1580, + 1585, 1591, 1594, 1599, 1605, 1611, 1615, 1620, 1628, 1635, 1641, 1647, 1653, 1657, 1662, 1665, + 1671, 1676, 1680, 1684, 1689, 1692, 1698, 1706, 1715, 1719, 1725, 1733, 1738, 1742, 1748, 1755, + 1759, 1761, 1765, 1772, 1778, 1782, 1782, 1786, 1793, 1800, 1807, 1816, 1822, 1828, 1833, 1838, + 1842, 1849, 1854, 1865, 1873, 1878, 1887, 1905, 1921, 1934, 1945, 1956, 1956, 1955, 1954, 1953, + 1952, 1951, 1951, 1950, 1949, 1948, 1947, 1946, 1946, 1945, 1944, 1943, 1942, 1941, 1941, 1940, + 1939, 1938, 1937, 1936, 1936, 1935, 1934, 1933, 1932, 1931, 1931, 1930, 1929, 1928, 1927, 1926, + 1926, 1925, 1924, 1923, 1922, 1922, 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, + 1912, 1912, 1911, 1910, 1909, 1908, 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, + 1899, 1898, 1897, 1897, 1896, 1895, 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, + 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1878, 1877, 1876, 1875, 1874, 1873, + 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1863, 1863, 1862, 1861, 1860, + 1859, 1858, 1858, 1857, 1856, 1855, 1854, 1853, 1853, 1852, 1851, 1850, 1849, 1848, 1848, 1847, + }, + { + /*5*/ + 1020, 1032, 1042, 1050, 1060, 1068, 1079, 1091, 1105, 1117, 1131, 1145, 1161, 1175, 1189, 1202, + 1217, 1231, 1245, 1262, 1278, 1292, 1306, 1318, 1330, 1342, 1354, 1366, 1379, 1390, 1400, 1413, + 1422, 1430, 1438, 1447, 1455, 1462, 1470, 1478, 1485, 1492, 1500, 1506, 1514, 1521, 1528, 1532, + 1538, 1545, 1554, 1561, 1567, 1572, 1577, 1581, 1586, 1591, 1597, 1603, 1608, 1612, 1618, 1623, + 1627, 1631, 1637, 1642, 1645, 1648, 1652, 1657, 1661, 1664, 1668, 1673, 1678, 1683, 1688, 1692, + 1697, 1702, 1707, 1712, 1716, 1719, 1723, 1727, 1734, 1741, 1745, 1747, 1752, 1758, 1765, 1769, + 1774, 1779, 1783, 1785, 1789, 1795, 1801, 1806, 1809, 1813, 1819, 1824, 1829, 1835, 1840, 1845, + 1850, 1854, 1862, 1871, 1880, 1885, 1891, 1900, 1906, 1909, 1913, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1025, 1032, 1041, 1053, 1064, 1073, 1086, 1100, 1117, 1135, 1160, 1175, 1180, 1189, 1206, 1235, + 1254, 1265, 1266, 1280, 1290, 1312, 1329, 1346, 1358, 1378, 1389, 1394, 1408, 1421, 1440, 1454, + 1461, 1466, 1478, 1492, 1498, 1501, 1502, 1512, 1529, 1540, 1545, 1549, 1552, 1559, 1570, 1576, + 1582, 1589, 1591, 1590, 1601, 1614, 1620, 1623, 1626, 1629, 1632, 1642, 1653, 1661, 1663, 1672, + 1674, 1679, 1682, 1686, 1687, 1687, 1685, 1688, 1695, 1706, 1709, 1714, 1715, 1718, 1717, 1720, + 1728, 1735, 1736, 1737, 1744, 1750, 1753, 1757, 1763, 1767, 1771, 1778, 1784, 1788, 1793, 1799, + 1803, 1806, 1811, 1817, 1822, 1827, 1831, 1836, 1839, 1844, 1851, 1856, 1862, 1865, 1871, 1875, + 1881, 1888, 1892, 1898, 1907, 1916, 1920, 1928, 1941, 1940, 1939, 1960, 1959, 1959, 1958, 1957, + 1956, 1955, 1954, 1954, 1953, 1952, 1951, 1950, 1949, 1949, 1948, 1947, 1946, 1945, 1944, 1944, + 1943, 1942, 1941, 1940, 1939, 1939, 1938, 1937, 1936, 1935, 1934, 1934, 1933, 1932, 1931, 1930, + 1929, 1929, 1928, 1927, 1926, 1925, 1924, 1924, 1923, 1922, 1921, 1920, 1919, 1919, 1918, 1917, + 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1904, 1904, + 1903, 1902, 1901, 1900, 1899, 1899, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, + 1889, 1889, 1888, 1887, 1886, 1885, 1884, 1884, 1883, 1882, 1881, 1880, 1879, 1879, 1878, 1877, + 1876, 1875, 1875, 1874, 1873, 1872, 1871, 1870, 1870, 1869, 1868, 1867, 1866, 1865, 1865, 1864, + 1863, 1862, 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, + 1021, 1031, 1042, 1051, 1060, 1070, 1082, 1093, 1106, 1120, 1135, 1150, 1165, 1179, 1195, 1209, + 1224, 1236, 1248, 1263, 1279, 1295, 1309, 1321, 1334, 1349, 1360, 1371, 1382, 1391, 1400, 1410, + 1419, 1425, 1435, 1447, 1456, 1462, 1472, 1480, 1488, 1492, 1501, 1507, 1515, 1521, 1528, 1534, + 1541, 1547, 1552, 1557, 1564, 1569, 1573, 1579, 1584, 1587, 1590, 1598, 1602, 1608, 1611, 1616, + 1619, 1627, 1631, 1635, 1637, 1642, 1644, 1647, 1650, 1655, 1658, 1662, 1665, 1667, 1668, 1672, + 1677, 1682, 1685, 1689, 1694, 1700, 1704, 1708, 1712, 1715, 1719, 1725, 1731, 1735, 1741, 1748, + 1753, 1758, 1762, 1766, 1771, 1777, 1781, 1787, 1790, 1792, 1794, 1802, 1809, 1815, 1818, 1821, + 1827, 1835, 1841, 1847, 1852, 1860, 1870, 1874, 1878, 1900, 1923, 1904, 1903, 1902, 1902, 1901, + 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1881, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1869, 1868, 1867, 1866, 1865, 1865, 1864, 1863, 1862, + 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1856, 1855, 1854, 1853, 1852, 1852, 1851, 1850, 1849, + 1848, 1848, 1847, 1846, 1845, 1844, 1844, 1843, 1842, 1841, 1840, 1839, 1839, 1838, 1837, 1836, + 1835, 1835, 1834, 1833, 1832, 1831, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, + 1822, 1822, 1821, 1820, 1819, 1818, 1818, 1817, 1816, 1815, 1814, 1814, 1813, 1812, 1811, 1810, + 1810, 1809, 1808, 1807, 1806, 1806, 1805, 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, + }, + { + /*6*/ + 1025, 1030, 1039, 1045, 1051, 1059, 1070, 1078, 1089, 1099, 1112, 1124, 1138, 1153, 1168, 1180, + 1193, 1204, 1218, 1230, 1246, 1259, 1271, 1281, 1294, 1307, 1320, 1333, 1347, 1358, 1369, 1381, + 1392, 1400, 1407, 1417, 1426, 1434, 1439, 1446, 1454, 1461, 1468, 1477, 1486, 1493, 1499, 1504, + 1512, 1522, 1527, 1531, 1536, 1542, 1548, 1552, 1556, 1561, 1568, 1574, 1579, 1586, 1592, 1598, + 1605, 1609, 1613, 1620, 1626, 1631, 1635, 1641, 1646, 1651, 1658, 1664, 1671, 1677, 1682, 1686, + 1689, 1695, 1703, 1709, 1713, 1718, 1724, 1729, 1734, 1740, 1745, 1748, 1753, 1761, 1768, 1773, + 1779, 1786, 1791, 1794, 1800, 1807, 1814, 1819, 1825, 1827, 1832, 1838, 1844, 1849, 1856, 1864, + 1874, 1883, 1892, 1902, 1909, 1916, 1926, 1939, 1946, 1954, 1967, 1978, 1977, 1977, 1976, 1975, + 1974, 1973, 1972, 1972, 1971, 1970, 1969, 1968, 1967, 1966, 1966, 1965, 1964, 1963, 1962, 1961, + 1961, 1960, 1959, 1958, 1957, 1956, 1956, 1955, 1954, 1953, 1952, 1951, 1951, 1950, 1949, 1948, + 1947, 1946, 1945, 1945, 1944, 1943, 1942, 1941, 1940, 1940, 1939, 1938, 1937, 1936, 1935, 1935, + 1934, 1933, 1932, 1931, 1930, 1930, 1929, 1928, 1927, 1926, 1925, 1925, 1924, 1923, 1922, 1921, + 1920, 1919, 1919, 1918, 1917, 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, + 1907, 1906, 1905, 1904, 1904, 1903, 1902, 1901, 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, + 1893, 1893, 1892, 1891, 1890, 1889, 1888, 1888, 1887, 1886, 1885, 1884, 1883, 1883, 1882, 1881, + 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, 1867, + 1024, 1028, 1033, 1039, 1046, 1051, 1061, 1070, 1082, 1096, 1113, 1124, 1129, 1137, 1149, 1171, + 1186, 1192, 1191, 1201, 1209, 1228, 1242, 1258, 1268, 1286, 1295, 1300, 1312, 1324, 1342, 1356, + 1363, 1365, 1375, 1387, 1392, 1394, 1395, 1404, 1419, 1427, 1432, 1437, 1440, 1447, 1456, 1463, + 1468, 1473, 1473, 1474, 1485, 1497, 1502, 1503, 1508, 1512, 1517, 1525, 1533, 1542, 1544, 1550, + 1551, 1557, 1561, 1566, 1566, 1566, 1564, 1567, 1575, 1585, 1590, 1595, 1595, 1599, 1597, 1602, + 1610, 1618, 1617, 1618, 1626, 1634, 1638, 1640, 1647, 1651, 1655, 1662, 1667, 1669, 1675, 1681, + 1683, 1686, 1689, 1692, 1697, 1705, 1709, 1713, 1717, 1720, 1727, 1731, 1735, 1741, 1743, 1750, + 1757, 1766, 1772, 1782, 1788, 1794, 1804, 1811, 1818, 1832, 1846, 1845, 1844, 1844, 1843, 1842, + 1841, 1840, 1840, 1839, 1838, 1837, 1837, 1836, 1835, 1834, 1833, 1833, 1832, 1831, 1830, 1830, + 1829, 1828, 1827, 1826, 1826, 1825, 1824, 1823, 1822, 1822, 1821, 1820, 1819, 1819, 1818, 1817, + 1816, 1815, 1815, 1814, 1813, 1812, 1812, 1811, 1810, 1809, 1808, 1808, 1807, 1806, 1805, 1804, + 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, 1797, 1796, 1795, 1794, 1794, 1793, 1792, + 1791, 1790, 1790, 1789, 1788, 1787, 1786, 1786, 1785, 1784, 1783, 1783, 1782, 1781, 1780, 1779, + 1779, 1778, 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1772, 1771, 1770, 1769, 1768, 1768, 1767, + 1766, 1765, 1765, 1764, 1763, 1762, 1761, 1761, 1760, 1759, 1758, 1757, 1757, 1756, 1755, 1754, + 1754, 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1743, 1743, 1742, + 1022, 1024, 1030, 1034, 1038, 1043, 1052, 1060, 1068, 1076, 1085, 1096, 1107, 1119, 1130, 1139, + 1147, 1156, 1164, 1174, 1186, 1200, 1211, 1221, 1231, 1245, 1254, 1264, 1276, 1286, 1296, 1303, + 1312, 1317, 1324, 1334, 1342, 1347, 1354, 1363, 1369, 1375, 1382, 1387, 1392, 1398, 1404, 1408, + 1413, 1419, 1424, 1429, 1433, 1437, 1442, 1449, 1454, 1458, 1462, 1468, 1472, 1477, 1481, 1487, + 1491, 1495, 1498, 1501, 1505, 1509, 1512, 1515, 1520, 1526, 1531, 1536, 1538, 1539, 1541, 1546, + 1551, 1554, 1556, 1559, 1567, 1572, 1576, 1582, 1587, 1589, 1593, 1598, 1603, 1606, 1611, 1615, + 1619, 1624, 1628, 1635, 1641, 1646, 1648, 1652, 1656, 1660, 1665, 1670, 1674, 1678, 1683, 1690, + 1698, 1704, 1711, 1718, 1725, 1735, 1744, 1751, 1752, 1769, 1785, 1781, 1780, 1779, 1778, 1778, + 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1771, 1771, 1770, 1769, 1768, 1768, 1767, 1766, 1765, + 1765, 1764, 1763, 1762, 1762, 1761, 1760, 1759, 1759, 1758, 1757, 1756, 1756, 1755, 1754, 1753, + 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1744, 1743, 1742, 1741, + 1741, 1740, 1739, 1738, 1737, 1737, 1736, 1735, 1734, 1734, 1733, 1732, 1731, 1731, 1730, 1729, + 1728, 1728, 1727, 1726, 1725, 1725, 1724, 1723, 1722, 1722, 1721, 1720, 1719, 1719, 1718, 1717, + 1716, 1716, 1715, 1714, 1713, 1713, 1712, 1711, 1710, 1710, 1709, 1708, 1707, 1707, 1706, 1705, + 1704, 1703, 1703, 1702, 1701, 1700, 1700, 1699, 1698, 1697, 1697, 1696, 1695, 1694, 1694, 1693, + 1692, 1691, 1691, 1690, 1689, 1688, 1688, 1687, 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, + }, + { + /*7*/ + 1022, 1029, 1038, 1046, 1054, 1061, 1071, 1081, 1094, 1105, 1118, 1131, 1145, 1160, 1175, 1187, + 1202, 1215, 1230, 1244, 1259, 1273, 1286, 1298, 1311, 1323, 1334, 1348, 1360, 1373, 1385, 1396, + 1406, 1415, 1423, 1432, 1440, 1450, 1457, 1465, 1474, 1483, 1490, 1497, 1505, 1512, 1519, 1526, + 1533, 1539, 1546, 1553, 1560, 1566, 1573, 1582, 1587, 1592, 1596, 1601, 1606, 1610, 1615, 1619, + 1625, 1632, 1638, 1643, 1648, 1651, 1654, 1660, 1666, 1670, 1671, 1674, 1679, 1686, 1693, 1700, + 1702, 1704, 1710, 1714, 1718, 1723, 1730, 1734, 1739, 1744, 1749, 1754, 1761, 1767, 1772, 1776, + 1781, 1784, 1789, 1794, 1799, 1802, 1805, 1809, 1817, 1823, 1830, 1833, 1841, 1847, 1852, 1856, + 1863, 1869, 1875, 1882, 1891, 1896, 1901, 1903, 1910, 1920, 1932, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1024, 1029, 1033, 1038, 1044, 1048, 1055, 1062, 1072, 1084, 1097, 1106, 1110, 1117, 1129, 1149, + 1162, 1168, 1169, 1177, 1186, 1202, 1215, 1227, 1237, 1254, 1261, 1266, 1277, 1286, 1302, 1314, + 1320, 1324, 1334, 1346, 1353, 1355, 1355, 1365, 1378, 1385, 1391, 1395, 1398, 1404, 1413, 1418, + 1422, 1429, 1432, 1433, 1442, 1450, 1455, 1457, 1462, 1465, 1469, 1476, 1482, 1488, 1492, 1498, + 1501, 1504, 1507, 1512, 1514, 1516, 1517, 1522, 1525, 1530, 1532, 1537, 1539, 1540, 1542, 1546, + 1551, 1555, 1559, 1562, 1566, 1568, 1572, 1574, 1578, 1584, 1587, 1588, 1590, 1595, 1599, 1602, + 1608, 1612, 1616, 1619, 1622, 1625, 1630, 1636, 1639, 1645, 1648, 1654, 1660, 1661, 1672, 1674, + 1678, 1680, 1685, 1689, 1704, 1710, 1702, 1713, 1734, 1722, 1700, 1737, 1736, 1735, 1735, 1734, + 1733, 1732, 1732, 1731, 1730, 1729, 1729, 1728, 1727, 1727, 1726, 1725, 1724, 1724, 1723, 1722, + 1721, 1721, 1720, 1719, 1718, 1718, 1717, 1716, 1715, 1715, 1714, 1713, 1713, 1712, 1711, 1710, + 1710, 1709, 1708, 1707, 1707, 1706, 1705, 1704, 1704, 1703, 1702, 1701, 1701, 1700, 1699, 1699, + 1698, 1697, 1696, 1696, 1695, 1694, 1693, 1693, 1692, 1691, 1690, 1690, 1689, 1688, 1687, 1687, + 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, 1680, 1679, 1679, 1678, 1677, 1676, 1676, 1675, + 1674, 1673, 1673, 1672, 1671, 1670, 1670, 1669, 1668, 1668, 1667, 1666, 1665, 1665, 1664, 1663, + 1662, 1662, 1661, 1660, 1659, 1659, 1658, 1657, 1656, 1656, 1655, 1654, 1654, 1653, 1652, 1651, + 1651, 1650, 1649, 1648, 1648, 1647, 1646, 1645, 1645, 1644, 1643, 1642, 1642, 1641, 1640, 1640, + 1022, 1025, 1028, 1032, 1037, 1042, 1047, 1054, 1061, 1069, 1077, 1085, 1092, 1100, 1108, 1117, + 1126, 1134, 1141, 1150, 1159, 1169, 1177, 1184, 1192, 1199, 1207, 1214, 1223, 1230, 1237, 1246, + 1254, 1259, 1264, 1272, 1279, 1283, 1289, 1297, 1302, 1308, 1313, 1318, 1324, 1328, 1333, 1338, + 1344, 1347, 1351, 1355, 1363, 1370, 1373, 1376, 1381, 1385, 1386, 1391, 1396, 1401, 1404, 1407, + 1410, 1414, 1419, 1422, 1422, 1424, 1425, 1428, 1430, 1431, 1434, 1441, 1444, 1444, 1447, 1450, + 1455, 1456, 1458, 1459, 1464, 1467, 1470, 1472, 1476, 1479, 1482, 1487, 1491, 1493, 1497, 1504, + 1507, 1509, 1514, 1516, 1518, 1521, 1524, 1527, 1529, 1531, 1536, 1541, 1547, 1551, 1556, 1558, + 1564, 1567, 1572, 1576, 1582, 1581, 1581, 1587, 1594, 1599, 1604, 1611, 1611, 1610, 1609, 1609, + 1608, 1607, 1607, 1606, 1605, 1605, 1604, 1603, 1602, 1602, 1601, 1600, 1600, 1599, 1598, 1598, + 1597, 1596, 1596, 1595, 1594, 1594, 1593, 1592, 1592, 1591, 1590, 1590, 1589, 1588, 1587, 1587, + 1586, 1585, 1585, 1584, 1583, 1583, 1582, 1581, 1581, 1580, 1579, 1579, 1578, 1577, 1577, 1576, + 1575, 1574, 1574, 1573, 1572, 1572, 1571, 1570, 1570, 1569, 1568, 1568, 1567, 1566, 1566, 1565, + 1564, 1564, 1563, 1562, 1561, 1561, 1560, 1559, 1559, 1558, 1557, 1557, 1556, 1555, 1555, 1554, + 1553, 1553, 1552, 1551, 1551, 1550, 1549, 1548, 1548, 1547, 1546, 1546, 1545, 1544, 1544, 1543, + 1542, 1542, 1541, 1540, 1540, 1539, 1538, 1538, 1537, 1536, 1535, 1535, 1534, 1533, 1533, 1532, + 1531, 1531, 1530, 1529, 1529, 1528, 1527, 1527, 1526, 1525, 1525, 1524, 1523, 1522, 1522, 1521, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 13107, 12342, 12588, 13362, 2608, 13107, 13621, 12588, 13362, 2608, 13107, 12341, + 12588, 13362, 2608, 13107, 13620, 12588, 13362, 2608, 13107, 12340, 12588, 13362, 2608, 13107, 13619, 12588, + 13362, 2608, 13107, 12339, 12588, 13362, 2608, 13107, 13618, 12588, 13362, 2608, 13107, 12338, 12588, 13362, + 2608, 13107, 13617, 12588, 13362, 2608, 13107, 12593, 12588, 13362, 2608, 13107, 13872, 12588, 13362, 2608, + 13107, 12592, 12588, 13362, 2608, 12851, 13881, 12588, 13362, 2608, 12851, 12857, 12588, 13362, 2608, 12851, + 14136, 12588, 13362, 2608, 12851, 12856, 12588, 13362, 2608, 12851, 14391, 12588, 13362, 2608, 12851, 13111, + 12588, 13362, 2608, 12851, 14646, 12588, 13362, 2608, 12851, 13366, 12588, 13362, 2608, 12851, 12342, 12588, + 13362, 2608, 12851, 13621, 12588, 13362, 2608, 12851, 12341, 12588, 13362, 2608, 12851, 13876, 12588, 13362, + 2608, 12851, 12852, 12588, 13362, 2608, 12851, 14131, 12588, 13362, 2608, 12851, 13107, 12588, 13362, 2608, + 12851, 12851, 12588, 13362, 2608, 12851, 12595, 12588, 13362, 2608, 12851, 12339, 12588, 13362, 2608, 12851, + 14642, 12588, 13362, 2608, 12851, 14386, 12588, 13362, 2608, 12851, 14130, 12588, 13362, 2608, 12851, 13874, + 12588, 13362, 2608, 12851, 13618, 12588, 13362, 2608, 12851, 13362, 12588, 13362, 2608, 12851, 13106, 12588, + 13362, 2608, 12851, 12850, 12588, 13362, 2608, 12851, 12594, 12588, 13362, 2608, 12851, 12338, 12588, 13362, + 2608, 12851, 14641, 12588, 13362, 2608, 12851, 14385, 12588, 13362, 2608, 12851, 14129, 12588, 13362, 2608, + 12851, 13873, 12588, 13362, 2608, 12851, 13617, 12588, 13362, 2608, 12851, 13361, 12588, 13362, 2608, 12851, + 13105, 12588, 13362, 2608, 12851, 12849, 12588, 13362, 2608, 12851, 12593, 12588, 13362, 2608, 12851, 12337, + 12588, 13362, 2608, 12851, 14640, 12588, 13362, 2608, 12851, 14384, 12588, 13362, 2608, 12851, 14128, 12588, + 13362, 2608, 12851, 13872, 12588, 13362, 2608, 12851, 13616, 12588, 13362, 2608, 12851, 13360, 12588, 13362, + 2608, 12851, 13104, 12588, 13362, 2608, 12851, 12848, 12588, 13362, 2608, 12851, 12592, 12588, 13362, 2608, + 12851, 12336, 12588, 13362, 2608, 12595, 14649, 12588, 13362, 2608, 12595, 14393, 12588, 13362, 2608, 12595, + 14137, 12588, 13362, 2608, 12595, 13881, 12588, 13362, 2608, 12595, 13625, 12588, 13362, 2608, 12595, 13369, + 12588, 13362, 2608, 12595, 13113, 12588, 13362, 2608, 12595, 12857, 12588, 13362, 2608, 12595, 12601, 12588, + 13362, 2608, 12595, 12345, 12588, 13362, 2608, 12595, 14648, 12588, 13362, 2608, 12595, 14392, 12588, 13362, + 2608, 12595, 14136, 12588, 13362, 2608, 12595, 13880, 12588, 13362, 2608, 12595, 13624, 12588, 13362, 2608, + 12595, 13368, 12588, 13362, 2608, 12595, 13112, 12588, 13362, 2608, 12595, 12856, 12588, 13362, 2608, 12595, + 12600, 12588, 13362, 2608, 12595, 12344, 12588, 13362, 2608, 12595, 14647, 12588, 13362, 2608, 12595, 14391, + 12588, 13362, 2608, 12595, 14135, 12588, 13362, 2608, 12595, 13879, 12588, 13362, 2608, 12595, 13623, 12588, + 13362, 2608, 12595, 13367, 12588, 13362, 2608, 12595, 13111, 12588, 13362, 2608, 12595, 12855, 12588, 13362, + 2608, 12595, 12599, 12588, 13362, 2608, 12595, 12343, 12588, 13362, 2608, 12595, 14646, 12588, 13362, 2608, + 12595, 14390, 12588, 13362, 2608, 12595, 14134, 12588, 13362, 2608, 12595, 13878, 12588, 13362, 2608, 12595, + 13622, 12588, 13362, 2608, 12595, 13366, 12588, 13362, 2608, 12595, 13110, 12588, 13362, 2608, 12595, 12854, + 12588, 13362, 2608, 12595, 12598, 12588, 13362, 2608, 12595, 12342, 12588, 13362, 2608, 12595, 14645, 12588, + 13362, 2608, 12595, 14389, 12588, 13362, 2608, 12595, 14133, 12588, 13362, 2608, 12595, 13877, 12588, 13362, + 2608, 12595, 13621, 12588, 13362, 2608, 12595, 13365, 12588, 13362, 2608, 12595, 13109, 12588, 13362, 2608, + 12595, 12853, 12588, 13362, 2608, 12595, 12597, 12588, 13362, 2608, 12595, 12341, 12588, 13362, 2608, 12595, + 14644, 12588, 13362, 2608, 12595, 14388, 12588, 13362, 2608, 12595, 14132, 12588, 13362, 2608, 12595, 13876, + 12588, 13362, 2608, 12595, 13620, 12588, 13362, 2608, 12595, 13364, 12588, 13362, 2608, 12595, 13108, 12588, + 13362, 2608, 12595, 12852, 12588, 13362, 2608, 12595, 12596, 12588, 13362, 2608, 12595, 12340, 12588, 13362, + 2608, 12595, 14643, 12588, 13362, 2608, 12595, 14387, 12588, 13362, 2608, 12595, 14131, 12588, 13362, 2608, + 12595, 13875, 12588, 13362, 2608, 12595, 13619, 12588, 13362, 2608, 12595, 13363, 12588, 13362, 2608, 12595, + 13107, 12588, 13362, 2608, 12595, 12851, 12588, 13362, 2608, 12595, 12595, 12588, 13362, 2608, 12595, 12339, + 12588, 13362, 2608, 12595, 14642, 12588, 13362, 2608, 12595, 14386, 12588, 13362, 2608, 12595, 14130, 12588, + 13362, 2608, 12595, 13874, 12588, 13362, 2608, 12595, 13618, 12588, 13362, 2608, 12595, 13362, 12588, 13362, + 2608, 12595, 13106, 12588, 13362, 2608, 12595, 12850, 12588, 13362, 2608, 12595, 12594, 12588, 13362, 2608, + 12595, 12338, 12588, 13362, 2608, 12595, 14641, 12588, 13362, 2608, 12595, 14385, 12588, 13362, 2608, 12595, + 14129, 12588, 13362, 2608, 12595, 13873, 12588, 13362, 2608, 12595, 13617, 12588, 13362, 2608, 12595, 13361, + 12588, 13362, 2608, 12595, 13105, 12588, 13362, 2608, 12595, 12849, 12588, 13362, 2608, 12595, 12593, 12588, + 13362, 2608, 12595, 12337, 12588, 13362, 2608, 12595, 14640, 12588, 13362, 2608, 1, 0, 1, 0, + }, + .disc_tbl = { + 4095, 4082, 4072, 4062, 4052, 4043, 4033, 4024, 4014, 4005, 3995, 3986, 3977, 3968, 3959, 3950, + 3941, 3933, 3924, 3915, 3907, 3898, 3890, 3881, 3873, 3865, 3857, 3848, 3840, 3832, 3824, 3817, + 3809, 3801, 3793, 3786, 3778, 3770, 3763, 3755, 3748, 3741, 3733, 3726, 3719, 3712, 3705, 3698, + 3691, 3684, 3677, 3670, 3663, 3656, 3650, 3643, 3636, 3630, 3623, 3617, 3610, 3604, 3597, 3591, + 3585, 3578, 3572, 3566, 3560, 3554, 3547, 3541, 3535, 3529, 3523, 3518, 3512, 3506, 3500, 3494, + 3488, 3483, 3477, 3471, 3466, 3460, 3455, 3449, 3444, 3438, 3433, 3427, 3422, 3417, 3411, 3406, + 3401, 3396, 3390, 3385, 3380, 3375, 3370, 3365, 3360, 3355, 3350, 3345, 3340, 3335, 3330, 3325, + 3320, 3315, 3311, 3306, 3301, 3296, 3292, 3287, 3282, 3278, 3273, 3269, 3264, 3260, 3255, 3250, + 3246, 3242, 3237, 3233, 3232, 3231, 3230, 3229, 3228, 3227, 3226, 3225, 3224, 3223, 3222, 3221, + 3220, 3219, 3218, 3217, 3216, 3215, 3214, 3213, 3212, 3211, 3210, 3209, 3208, 3207, 3206, 3205, + 3204, 3203, 3202, 3201, 3200, 3199, 3198, 3197, 3196, 3195, 3194, 3193, 3192, 3191, 3190, 3189, + 3188, 3187, 3186, 3185, 3184, 3183, 3182, 3181, 3180, 3179, 3178, 3177, 3176, 3175, 3174, 3173, + 3172, 3171, 3170, 3169, 3168, 3167, 3166, 3165, 3164, 3163, 3162, 3161, 3160, 3159, 3158, 3157, + 3156, 3155, 3154, 3153, 3152, 3151, 3150, 3149, 3148, 3147, 3146, 3145, 3144, 3143, 3142, 3141, + 3140, 3139, 3138, 3137, 3136, 3135, 3134, 3133, 3132, 3131, 3130, 3129, 3128, 3127, 3126, 3125, + 3124, 3123, 3122, 3121, 3120, 3119, 3118, 3117, 3116, 3115, 3114, 3113, 3112, 3111, 3110, 3109, + 1024, 1027, 1029, 1032, 1034, 1037, 1039, 1042, 1044, 1047, 1049, 1052, 1054, 1056, 1059, 1061, + 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1087, 1089, 1092, 1094, 1096, 1098, + 1100, 1103, 1105, 1107, 1109, 1112, 1114, 1116, 1118, 1120, 1123, 1125, 1127, 1129, 1131, 1133, + 1136, 1138, 1140, 1142, 1144, 1146, 1148, 1151, 1153, 1155, 1157, 1159, 1161, 1163, 1165, 1167, + 1169, 1171, 1173, 1175, 1177, 1179, 1182, 1184, 1186, 1188, 1190, 1191, 1193, 1196, 1198, 1200, + 1202, 1203, 1206, 1208, 1209, 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1229, 1231, + 1232, 1234, 1236, 1238, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + }, +}; +struct isp_cfg_pt gc1004_mipi_isp_cfg = +{ + .isp_test_settings = &gc1004_mipi_isp_test_settings, + .isp_3a_settings = &gc1004_mipi_isp_3a_settings, + .isp_tunning_settings = &gc1004_mipi_isp_tuning_settings, + .isp_iso_settings = &gc1004_mipi_isp_iso_settings, +}; + + +#endif /* end of _GC1004_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg_HK8214C.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg_HK8214C.h new file mode 100755 index 00000000..9cd9c156 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/gc1004_mipi_isp_cfg_HK8214C.h @@ -0,0 +1,847 @@ +/* +****************************************************************************************** +* +* gc1004_mipi_isp_cfg.h +* +* Hawkview ISP - gc1004_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/24 Automatic generation. +* +****************************************************************************************** +*/ + +//F2.6 HK-8214C-941 + +#ifndef _GC1004_MIPI_ISP_CFG_H_V100_ +#define _GC1004_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param gc1004_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 39520, + .exp_line_step = 16, + .exp_line_end = 39840, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 2, + .gain_end = 256, + .gain_change_interval = 4, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 237, + .isp_exp_line = 13000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 44, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param gc1004_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1488, + .fno = 20, + .ae_table_preview_length = 4, + .ae_table_preview = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 4, + .ae_table_capture = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 4, + .ae_table_video = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 6, + .ae_capture_speed = 6, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 4, + .awb_speed = 8, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 14, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 20, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 20, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 20, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 20, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 20, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 20, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 20, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 20, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 20, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 20, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 20, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 20, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 20, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 20, 8000, 128, 100, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param gc1004_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 2, 28, 768, }, { 0, 255, 5, }, { 2, 9, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 30, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 768, }, { 1, 255, 5, }, { 2, 9, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 26, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 4, 24, 512, }, { 2, 255, 5, }, { 4, 16, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 16, { 32, 20, 6, 32, }, 14, 110, 5, + { 2, 12, 2, 200, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 8, 16, 400, }, { 3, 255, 5, }, { 5, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, -2, { 32, 18, 12, 32, }, 40, 60, 20, + { 2, 12, 2, 200, }, { 10, 0, }, { 64, 24, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 20, 12, 350, }, { 4, 255, 6, }, { 7, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 5, -5, }, -20, { 32, 18, 16, 32, }, 30, 22, 40, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 20, 8, 300, }, { 5, 255, 7, }, { 8, 28, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { 5, -5, }, -32, { 32, 18, 16, 32, }, 32, 4, 40, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param gc1004_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 2, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 85, + .ver_visual_angle = 46, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 345, 256, 256, 285, 0, 0, 0, 0, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 306, -21, -29, }, { -161, 451, -34, }, { -155, -279, 690, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 366, -110, 0, }, { -80, 336, 0, }, { -39, -202, 497, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 385, -129, 0, }, { -104, 439, -79, }, { -42, -166, 464, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1023, 1028, 1039, 1047, 1056, 1064, 1077, 1088, 1103, 1116, 1131, 1145, 1162, 1178, 1195, 1208, + 1223, 1237, 1254, 1269, 1286, 1299, 1313, 1326, 1340, 1354, 1366, 1381, 1397, 1409, 1421, 1434, + 1444, 1451, 1458, 1468, 1477, 1486, 1493, 1501, 1509, 1517, 1524, 1533, 1543, 1551, 1556, 1562, + 1570, 1582, 1588, 1592, 1599, 1608, 1616, 1620, 1625, 1631, 1638, 1644, 1651, 1657, 1663, 1668, + 1676, 1681, 1686, 1692, 1698, 1704, 1709, 1716, 1721, 1726, 1731, 1736, 1741, 1747, 1754, 1759, + 1763, 1767, 1772, 1778, 1783, 1789, 1794, 1800, 1805, 1811, 1817, 1822, 1826, 1832, 1841, 1848, + 1854, 1860, 1863, 1868, 1875, 1884, 1888, 1897, 1905, 1911, 1915, 1923, 1930, 1936, 1947, 1958, + 1966, 1974, 1986, 1995, 1999, 2007, 2019, 2031, 2041, 2048, 2057, 2070, 2070, 2069, 2068, 2067, + 2066, 2065, 2064, 2063, 2063, 2062, 2061, 2060, 2059, 2058, 2057, 2056, 2055, 2055, 2054, 2053, + 2052, 2051, 2050, 2049, 2048, 2048, 2047, 2046, 2045, 2044, 2043, 2042, 2041, 2041, 2040, 2039, + 2038, 2037, 2036, 2035, 2034, 2034, 2033, 2032, 2031, 2030, 2029, 2028, 2027, 2026, 2026, 2025, + 2024, 2023, 2022, 2021, 2020, 2019, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2012, 2011, + 2010, 2009, 2008, 2007, 2006, 2005, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1998, 1997, + 1996, 1995, 1994, 1993, 1992, 1991, 1990, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983, 1983, + 1982, 1981, 1980, 1979, 1978, 1977, 1976, 1976, 1975, 1974, 1973, 1972, 1971, 1970, 1969, 1969, + 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1961, 1960, 1959, 1958, 1957, 1956, 1955, 1954, + 1021, 1030, 1039, 1048, 1057, 1064, 1078, 1091, 1107, 1123, 1146, 1159, 1166, 1174, 1191, 1217, + 1235, 1244, 1244, 1256, 1264, 1285, 1302, 1318, 1330, 1349, 1359, 1365, 1378, 1389, 1408, 1423, + 1431, 1434, 1446, 1459, 1465, 1466, 1467, 1476, 1494, 1503, 1509, 1515, 1519, 1524, 1534, 1540, + 1545, 1551, 1552, 1554, 1567, 1581, 1587, 1589, 1594, 1600, 1604, 1613, 1623, 1631, 1634, 1641, + 1642, 1647, 1651, 1658, 1661, 1663, 1663, 1666, 1674, 1684, 1690, 1697, 1698, 1700, 1697, 1703, + 1714, 1722, 1721, 1724, 1734, 1741, 1743, 1747, 1755, 1757, 1760, 1769, 1776, 1778, 1784, 1789, + 1793, 1797, 1801, 1806, 1813, 1820, 1822, 1828, 1835, 1840, 1849, 1854, 1858, 1863, 1868, 1874, + 1881, 1890, 1896, 1904, 1912, 1919, 1924, 1930, 1943, 1959, 1971, 1965, 1964, 1963, 1962, 1962, + 1961, 1960, 1959, 1958, 1957, 1957, 1956, 1955, 1954, 1953, 1952, 1952, 1951, 1950, 1949, 1948, + 1947, 1947, 1946, 1945, 1944, 1943, 1942, 1942, 1941, 1940, 1939, 1938, 1937, 1937, 1936, 1935, + 1934, 1933, 1932, 1932, 1931, 1930, 1929, 1928, 1927, 1927, 1926, 1925, 1924, 1923, 1922, 1922, + 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, 1912, 1912, 1911, 1910, 1909, 1908, + 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, 1899, 1898, 1897, 1897, 1896, 1895, + 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, 1886, 1885, 1884, 1883, 1882, 1882, + 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, + 1867, 1867, 1866, 1865, 1864, 1863, 1862, 1862, 1861, 1860, 1859, 1858, 1857, 1857, 1856, 1855, + 1023, 1026, 1034, 1041, 1049, 1056, 1066, 1076, 1087, 1098, 1109, 1122, 1135, 1149, 1163, 1173, + 1185, 1195, 1206, 1218, 1232, 1246, 1255, 1268, 1278, 1291, 1302, 1312, 1323, 1335, 1346, 1358, + 1370, 1375, 1381, 1391, 1400, 1408, 1417, 1426, 1433, 1441, 1451, 1456, 1462, 1469, 1478, 1485, + 1490, 1494, 1501, 1510, 1516, 1521, 1527, 1535, 1542, 1545, 1548, 1557, 1564, 1570, 1574, 1580, + 1585, 1591, 1594, 1599, 1605, 1611, 1615, 1620, 1628, 1635, 1641, 1647, 1653, 1657, 1662, 1665, + 1671, 1676, 1680, 1684, 1689, 1692, 1698, 1706, 1715, 1719, 1725, 1733, 1738, 1742, 1748, 1755, + 1759, 1761, 1765, 1772, 1778, 1782, 1782, 1786, 1793, 1800, 1807, 1816, 1822, 1828, 1833, 1838, + 1842, 1849, 1854, 1865, 1873, 1878, 1887, 1905, 1921, 1934, 1945, 1956, 1956, 1955, 1954, 1953, + 1952, 1951, 1951, 1950, 1949, 1948, 1947, 1946, 1946, 1945, 1944, 1943, 1942, 1941, 1941, 1940, + 1939, 1938, 1937, 1936, 1936, 1935, 1934, 1933, 1932, 1931, 1931, 1930, 1929, 1928, 1927, 1926, + 1926, 1925, 1924, 1923, 1922, 1922, 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, + 1912, 1912, 1911, 1910, 1909, 1908, 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, + 1899, 1898, 1897, 1897, 1896, 1895, 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, + 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1878, 1877, 1876, 1875, 1874, 1873, + 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1863, 1863, 1862, 1861, 1860, + 1859, 1858, 1858, 1857, 1856, 1855, 1854, 1853, 1853, 1852, 1851, 1850, 1849, 1848, 1848, 1847, + }, + { + /*1*/ + 1020, 1032, 1042, 1050, 1060, 1068, 1079, 1091, 1105, 1117, 1131, 1145, 1161, 1175, 1189, 1202, + 1217, 1231, 1245, 1262, 1278, 1292, 1306, 1318, 1330, 1342, 1354, 1366, 1379, 1390, 1400, 1413, + 1422, 1430, 1438, 1447, 1455, 1462, 1470, 1478, 1485, 1492, 1500, 1506, 1514, 1521, 1528, 1532, + 1538, 1545, 1554, 1561, 1567, 1572, 1577, 1581, 1586, 1591, 1597, 1603, 1608, 1612, 1618, 1623, + 1627, 1631, 1637, 1642, 1645, 1648, 1652, 1657, 1661, 1664, 1668, 1673, 1678, 1683, 1688, 1692, + 1697, 1702, 1707, 1712, 1716, 1719, 1723, 1727, 1734, 1741, 1745, 1747, 1752, 1758, 1765, 1769, + 1774, 1779, 1783, 1785, 1789, 1795, 1801, 1806, 1809, 1813, 1819, 1824, 1829, 1835, 1840, 1845, + 1850, 1854, 1862, 1871, 1880, 1885, 1891, 1900, 1906, 1909, 1913, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1025, 1032, 1041, 1053, 1064, 1073, 1086, 1100, 1117, 1135, 1160, 1175, 1180, 1189, 1206, 1235, + 1254, 1265, 1266, 1280, 1290, 1312, 1329, 1346, 1358, 1378, 1389, 1394, 1408, 1421, 1440, 1454, + 1461, 1466, 1478, 1492, 1498, 1501, 1502, 1512, 1529, 1540, 1545, 1549, 1552, 1559, 1570, 1576, + 1582, 1589, 1591, 1590, 1601, 1614, 1620, 1623, 1626, 1629, 1632, 1642, 1653, 1661, 1663, 1672, + 1674, 1679, 1682, 1686, 1687, 1687, 1685, 1688, 1695, 1706, 1709, 1714, 1715, 1718, 1717, 1720, + 1728, 1735, 1736, 1737, 1744, 1750, 1753, 1757, 1763, 1767, 1771, 1778, 1784, 1788, 1793, 1799, + 1803, 1806, 1811, 1817, 1822, 1827, 1831, 1836, 1839, 1844, 1851, 1856, 1862, 1865, 1871, 1875, + 1881, 1888, 1892, 1898, 1907, 1916, 1920, 1928, 1941, 1940, 1939, 1960, 1959, 1959, 1958, 1957, + 1956, 1955, 1954, 1954, 1953, 1952, 1951, 1950, 1949, 1949, 1948, 1947, 1946, 1945, 1944, 1944, + 1943, 1942, 1941, 1940, 1939, 1939, 1938, 1937, 1936, 1935, 1934, 1934, 1933, 1932, 1931, 1930, + 1929, 1929, 1928, 1927, 1926, 1925, 1924, 1924, 1923, 1922, 1921, 1920, 1919, 1919, 1918, 1917, + 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1904, 1904, + 1903, 1902, 1901, 1900, 1899, 1899, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, + 1889, 1889, 1888, 1887, 1886, 1885, 1884, 1884, 1883, 1882, 1881, 1880, 1879, 1879, 1878, 1877, + 1876, 1875, 1875, 1874, 1873, 1872, 1871, 1870, 1870, 1869, 1868, 1867, 1866, 1865, 1865, 1864, + 1863, 1862, 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, + 1021, 1031, 1042, 1051, 1060, 1070, 1082, 1093, 1106, 1120, 1135, 1150, 1165, 1179, 1195, 1209, + 1224, 1236, 1248, 1263, 1279, 1295, 1309, 1321, 1334, 1349, 1360, 1371, 1382, 1391, 1400, 1410, + 1419, 1425, 1435, 1447, 1456, 1462, 1472, 1480, 1488, 1492, 1501, 1507, 1515, 1521, 1528, 1534, + 1541, 1547, 1552, 1557, 1564, 1569, 1573, 1579, 1584, 1587, 1590, 1598, 1602, 1608, 1611, 1616, + 1619, 1627, 1631, 1635, 1637, 1642, 1644, 1647, 1650, 1655, 1658, 1662, 1665, 1667, 1668, 1672, + 1677, 1682, 1685, 1689, 1694, 1700, 1704, 1708, 1712, 1715, 1719, 1725, 1731, 1735, 1741, 1748, + 1753, 1758, 1762, 1766, 1771, 1777, 1781, 1787, 1790, 1792, 1794, 1802, 1809, 1815, 1818, 1821, + 1827, 1835, 1841, 1847, 1852, 1860, 1870, 1874, 1878, 1900, 1923, 1904, 1903, 1902, 1902, 1901, + 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1881, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1869, 1868, 1867, 1866, 1865, 1865, 1864, 1863, 1862, + 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1856, 1855, 1854, 1853, 1852, 1852, 1851, 1850, 1849, + 1848, 1848, 1847, 1846, 1845, 1844, 1844, 1843, 1842, 1841, 1840, 1839, 1839, 1838, 1837, 1836, + 1835, 1835, 1834, 1833, 1832, 1831, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, + 1822, 1822, 1821, 1820, 1819, 1818, 1818, 1817, 1816, 1815, 1814, 1814, 1813, 1812, 1811, 1810, + 1810, 1809, 1808, 1807, 1806, 1806, 1805, 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, + }, + { + /*2*/ + 1025, 1030, 1039, 1045, 1051, 1059, 1070, 1078, 1089, 1099, 1112, 1124, 1138, 1153, 1168, 1180, + 1193, 1204, 1218, 1230, 1246, 1259, 1271, 1281, 1294, 1307, 1320, 1333, 1347, 1358, 1369, 1381, + 1392, 1400, 1407, 1417, 1426, 1434, 1439, 1446, 1454, 1461, 1468, 1477, 1486, 1493, 1499, 1504, + 1512, 1522, 1527, 1531, 1536, 1542, 1548, 1552, 1556, 1561, 1568, 1574, 1579, 1586, 1592, 1598, + 1605, 1609, 1613, 1620, 1626, 1631, 1635, 1641, 1646, 1651, 1658, 1664, 1671, 1677, 1682, 1686, + 1689, 1695, 1703, 1709, 1713, 1718, 1724, 1729, 1734, 1740, 1745, 1748, 1753, 1761, 1768, 1773, + 1779, 1786, 1791, 1794, 1800, 1807, 1814, 1819, 1825, 1827, 1832, 1838, 1844, 1849, 1856, 1864, + 1874, 1883, 1892, 1902, 1909, 1916, 1926, 1939, 1946, 1954, 1967, 1978, 1977, 1977, 1976, 1975, + 1974, 1973, 1972, 1972, 1971, 1970, 1969, 1968, 1967, 1966, 1966, 1965, 1964, 1963, 1962, 1961, + 1961, 1960, 1959, 1958, 1957, 1956, 1956, 1955, 1954, 1953, 1952, 1951, 1951, 1950, 1949, 1948, + 1947, 1946, 1945, 1945, 1944, 1943, 1942, 1941, 1940, 1940, 1939, 1938, 1937, 1936, 1935, 1935, + 1934, 1933, 1932, 1931, 1930, 1930, 1929, 1928, 1927, 1926, 1925, 1925, 1924, 1923, 1922, 1921, + 1920, 1919, 1919, 1918, 1917, 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, + 1907, 1906, 1905, 1904, 1904, 1903, 1902, 1901, 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, + 1893, 1893, 1892, 1891, 1890, 1889, 1888, 1888, 1887, 1886, 1885, 1884, 1883, 1883, 1882, 1881, + 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, 1867, + 1024, 1028, 1033, 1039, 1046, 1051, 1061, 1070, 1082, 1096, 1113, 1124, 1129, 1137, 1149, 1171, + 1186, 1192, 1191, 1201, 1209, 1228, 1242, 1258, 1268, 1286, 1295, 1300, 1312, 1324, 1342, 1356, + 1363, 1365, 1375, 1387, 1392, 1394, 1395, 1404, 1419, 1427, 1432, 1437, 1440, 1447, 1456, 1463, + 1468, 1473, 1473, 1474, 1485, 1497, 1502, 1503, 1508, 1512, 1517, 1525, 1533, 1542, 1544, 1550, + 1551, 1557, 1561, 1566, 1566, 1566, 1564, 1567, 1575, 1585, 1590, 1595, 1595, 1599, 1597, 1602, + 1610, 1618, 1617, 1618, 1626, 1634, 1638, 1640, 1647, 1651, 1655, 1662, 1667, 1669, 1675, 1681, + 1683, 1686, 1689, 1692, 1697, 1705, 1709, 1713, 1717, 1720, 1727, 1731, 1735, 1741, 1743, 1750, + 1757, 1766, 1772, 1782, 1788, 1794, 1804, 1811, 1818, 1832, 1846, 1845, 1844, 1844, 1843, 1842, + 1841, 1840, 1840, 1839, 1838, 1837, 1837, 1836, 1835, 1834, 1833, 1833, 1832, 1831, 1830, 1830, + 1829, 1828, 1827, 1826, 1826, 1825, 1824, 1823, 1822, 1822, 1821, 1820, 1819, 1819, 1818, 1817, + 1816, 1815, 1815, 1814, 1813, 1812, 1812, 1811, 1810, 1809, 1808, 1808, 1807, 1806, 1805, 1804, + 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, 1797, 1796, 1795, 1794, 1794, 1793, 1792, + 1791, 1790, 1790, 1789, 1788, 1787, 1786, 1786, 1785, 1784, 1783, 1783, 1782, 1781, 1780, 1779, + 1779, 1778, 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1772, 1771, 1770, 1769, 1768, 1768, 1767, + 1766, 1765, 1765, 1764, 1763, 1762, 1761, 1761, 1760, 1759, 1758, 1757, 1757, 1756, 1755, 1754, + 1754, 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1743, 1743, 1742, + 1022, 1024, 1030, 1034, 1038, 1043, 1052, 1060, 1068, 1076, 1085, 1096, 1107, 1119, 1130, 1139, + 1147, 1156, 1164, 1174, 1186, 1200, 1211, 1221, 1231, 1245, 1254, 1264, 1276, 1286, 1296, 1303, + 1312, 1317, 1324, 1334, 1342, 1347, 1354, 1363, 1369, 1375, 1382, 1387, 1392, 1398, 1404, 1408, + 1413, 1419, 1424, 1429, 1433, 1437, 1442, 1449, 1454, 1458, 1462, 1468, 1472, 1477, 1481, 1487, + 1491, 1495, 1498, 1501, 1505, 1509, 1512, 1515, 1520, 1526, 1531, 1536, 1538, 1539, 1541, 1546, + 1551, 1554, 1556, 1559, 1567, 1572, 1576, 1582, 1587, 1589, 1593, 1598, 1603, 1606, 1611, 1615, + 1619, 1624, 1628, 1635, 1641, 1646, 1648, 1652, 1656, 1660, 1665, 1670, 1674, 1678, 1683, 1690, + 1698, 1704, 1711, 1718, 1725, 1735, 1744, 1751, 1752, 1769, 1785, 1781, 1780, 1779, 1778, 1778, + 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1771, 1771, 1770, 1769, 1768, 1768, 1767, 1766, 1765, + 1765, 1764, 1763, 1762, 1762, 1761, 1760, 1759, 1759, 1758, 1757, 1756, 1756, 1755, 1754, 1753, + 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1744, 1743, 1742, 1741, + 1741, 1740, 1739, 1738, 1737, 1737, 1736, 1735, 1734, 1734, 1733, 1732, 1731, 1731, 1730, 1729, + 1728, 1728, 1727, 1726, 1725, 1725, 1724, 1723, 1722, 1722, 1721, 1720, 1719, 1719, 1718, 1717, + 1716, 1716, 1715, 1714, 1713, 1713, 1712, 1711, 1710, 1710, 1709, 1708, 1707, 1707, 1706, 1705, + 1704, 1703, 1703, 1702, 1701, 1700, 1700, 1699, 1698, 1697, 1697, 1696, 1695, 1694, 1694, 1693, + 1692, 1691, 1691, 1690, 1689, 1688, 1688, 1687, 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, + }, + { + /*3*/ + 1022, 1029, 1038, 1046, 1054, 1061, 1071, 1081, 1094, 1105, 1118, 1131, 1145, 1160, 1175, 1187, + 1202, 1215, 1230, 1244, 1259, 1273, 1286, 1298, 1311, 1323, 1334, 1348, 1360, 1373, 1385, 1396, + 1406, 1415, 1423, 1432, 1440, 1450, 1457, 1465, 1474, 1483, 1490, 1497, 1505, 1512, 1519, 1526, + 1533, 1539, 1546, 1553, 1560, 1566, 1573, 1582, 1587, 1592, 1596, 1601, 1606, 1610, 1615, 1619, + 1625, 1632, 1638, 1643, 1648, 1651, 1654, 1660, 1666, 1670, 1671, 1674, 1679, 1686, 1693, 1700, + 1702, 1704, 1710, 1714, 1718, 1723, 1730, 1734, 1739, 1744, 1749, 1754, 1761, 1767, 1772, 1776, + 1781, 1784, 1789, 1794, 1799, 1802, 1805, 1809, 1817, 1823, 1830, 1833, 1841, 1847, 1852, 1856, + 1863, 1869, 1875, 1882, 1891, 1896, 1901, 1903, 1910, 1920, 1932, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1024, 1029, 1033, 1038, 1044, 1048, 1055, 1062, 1072, 1084, 1097, 1106, 1110, 1117, 1129, 1149, + 1162, 1168, 1169, 1177, 1186, 1202, 1215, 1227, 1237, 1254, 1261, 1266, 1277, 1286, 1302, 1314, + 1320, 1324, 1334, 1346, 1353, 1355, 1355, 1365, 1378, 1385, 1391, 1395, 1398, 1404, 1413, 1418, + 1422, 1429, 1432, 1433, 1442, 1450, 1455, 1457, 1462, 1465, 1469, 1476, 1482, 1488, 1492, 1498, + 1501, 1504, 1507, 1512, 1514, 1516, 1517, 1522, 1525, 1530, 1532, 1537, 1539, 1540, 1542, 1546, + 1551, 1555, 1559, 1562, 1566, 1568, 1572, 1574, 1578, 1584, 1587, 1588, 1590, 1595, 1599, 1602, + 1608, 1612, 1616, 1619, 1622, 1625, 1630, 1636, 1639, 1645, 1648, 1654, 1660, 1661, 1672, 1674, + 1678, 1680, 1685, 1689, 1704, 1710, 1702, 1713, 1734, 1722, 1700, 1737, 1736, 1735, 1735, 1734, + 1733, 1732, 1732, 1731, 1730, 1729, 1729, 1728, 1727, 1727, 1726, 1725, 1724, 1724, 1723, 1722, + 1721, 1721, 1720, 1719, 1718, 1718, 1717, 1716, 1715, 1715, 1714, 1713, 1713, 1712, 1711, 1710, + 1710, 1709, 1708, 1707, 1707, 1706, 1705, 1704, 1704, 1703, 1702, 1701, 1701, 1700, 1699, 1699, + 1698, 1697, 1696, 1696, 1695, 1694, 1693, 1693, 1692, 1691, 1690, 1690, 1689, 1688, 1687, 1687, + 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, 1680, 1679, 1679, 1678, 1677, 1676, 1676, 1675, + 1674, 1673, 1673, 1672, 1671, 1670, 1670, 1669, 1668, 1668, 1667, 1666, 1665, 1665, 1664, 1663, + 1662, 1662, 1661, 1660, 1659, 1659, 1658, 1657, 1656, 1656, 1655, 1654, 1654, 1653, 1652, 1651, + 1651, 1650, 1649, 1648, 1648, 1647, 1646, 1645, 1645, 1644, 1643, 1642, 1642, 1641, 1640, 1640, + 1022, 1025, 1028, 1032, 1037, 1042, 1047, 1054, 1061, 1069, 1077, 1085, 1092, 1100, 1108, 1117, + 1126, 1134, 1141, 1150, 1159, 1169, 1177, 1184, 1192, 1199, 1207, 1214, 1223, 1230, 1237, 1246, + 1254, 1259, 1264, 1272, 1279, 1283, 1289, 1297, 1302, 1308, 1313, 1318, 1324, 1328, 1333, 1338, + 1344, 1347, 1351, 1355, 1363, 1370, 1373, 1376, 1381, 1385, 1386, 1391, 1396, 1401, 1404, 1407, + 1410, 1414, 1419, 1422, 1422, 1424, 1425, 1428, 1430, 1431, 1434, 1441, 1444, 1444, 1447, 1450, + 1455, 1456, 1458, 1459, 1464, 1467, 1470, 1472, 1476, 1479, 1482, 1487, 1491, 1493, 1497, 1504, + 1507, 1509, 1514, 1516, 1518, 1521, 1524, 1527, 1529, 1531, 1536, 1541, 1547, 1551, 1556, 1558, + 1564, 1567, 1572, 1576, 1582, 1581, 1581, 1587, 1594, 1599, 1604, 1611, 1611, 1610, 1609, 1609, + 1608, 1607, 1607, 1606, 1605, 1605, 1604, 1603, 1602, 1602, 1601, 1600, 1600, 1599, 1598, 1598, + 1597, 1596, 1596, 1595, 1594, 1594, 1593, 1592, 1592, 1591, 1590, 1590, 1589, 1588, 1587, 1587, + 1586, 1585, 1585, 1584, 1583, 1583, 1582, 1581, 1581, 1580, 1579, 1579, 1578, 1577, 1577, 1576, + 1575, 1574, 1574, 1573, 1572, 1572, 1571, 1570, 1570, 1569, 1568, 1568, 1567, 1566, 1566, 1565, + 1564, 1564, 1563, 1562, 1561, 1561, 1560, 1559, 1559, 1558, 1557, 1557, 1556, 1555, 1555, 1554, + 1553, 1553, 1552, 1551, 1551, 1550, 1549, 1548, 1548, 1547, 1546, 1546, 1545, 1544, 1544, 1543, + 1542, 1542, 1541, 1540, 1540, 1539, 1538, 1538, 1537, 1536, 1535, 1535, 1534, 1533, 1533, 1532, + 1531, 1531, 1530, 1529, 1529, 1528, 1527, 1527, 1526, 1525, 1525, 1524, 1523, 1522, 1522, 1521, + }, + { + /*4*/ + 1023, 1028, 1039, 1047, 1056, 1064, 1077, 1088, 1103, 1116, 1131, 1145, 1162, 1178, 1195, 1208, + 1223, 1237, 1254, 1269, 1286, 1299, 1313, 1326, 1340, 1354, 1366, 1381, 1397, 1409, 1421, 1434, + 1444, 1451, 1458, 1468, 1477, 1486, 1493, 1501, 1509, 1517, 1524, 1533, 1543, 1551, 1556, 1562, + 1570, 1582, 1588, 1592, 1599, 1608, 1616, 1620, 1625, 1631, 1638, 1644, 1651, 1657, 1663, 1668, + 1676, 1681, 1686, 1692, 1698, 1704, 1709, 1716, 1721, 1726, 1731, 1736, 1741, 1747, 1754, 1759, + 1763, 1767, 1772, 1778, 1783, 1789, 1794, 1800, 1805, 1811, 1817, 1822, 1826, 1832, 1841, 1848, + 1854, 1860, 1863, 1868, 1875, 1884, 1888, 1897, 1905, 1911, 1915, 1923, 1930, 1936, 1947, 1958, + 1966, 1974, 1986, 1995, 1999, 2007, 2019, 2031, 2041, 2048, 2057, 2070, 2070, 2069, 2068, 2067, + 2066, 2065, 2064, 2063, 2063, 2062, 2061, 2060, 2059, 2058, 2057, 2056, 2055, 2055, 2054, 2053, + 2052, 2051, 2050, 2049, 2048, 2048, 2047, 2046, 2045, 2044, 2043, 2042, 2041, 2041, 2040, 2039, + 2038, 2037, 2036, 2035, 2034, 2034, 2033, 2032, 2031, 2030, 2029, 2028, 2027, 2026, 2026, 2025, + 2024, 2023, 2022, 2021, 2020, 2019, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2012, 2011, + 2010, 2009, 2008, 2007, 2006, 2005, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1998, 1997, + 1996, 1995, 1994, 1993, 1992, 1991, 1990, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983, 1983, + 1982, 1981, 1980, 1979, 1978, 1977, 1976, 1976, 1975, 1974, 1973, 1972, 1971, 1970, 1969, 1969, + 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1961, 1960, 1959, 1958, 1957, 1956, 1955, 1954, + 1021, 1030, 1039, 1048, 1057, 1064, 1078, 1091, 1107, 1123, 1146, 1159, 1166, 1174, 1191, 1217, + 1235, 1244, 1244, 1256, 1264, 1285, 1302, 1318, 1330, 1349, 1359, 1365, 1378, 1389, 1408, 1423, + 1431, 1434, 1446, 1459, 1465, 1466, 1467, 1476, 1494, 1503, 1509, 1515, 1519, 1524, 1534, 1540, + 1545, 1551, 1552, 1554, 1567, 1581, 1587, 1589, 1594, 1600, 1604, 1613, 1623, 1631, 1634, 1641, + 1642, 1647, 1651, 1658, 1661, 1663, 1663, 1666, 1674, 1684, 1690, 1697, 1698, 1700, 1697, 1703, + 1714, 1722, 1721, 1724, 1734, 1741, 1743, 1747, 1755, 1757, 1760, 1769, 1776, 1778, 1784, 1789, + 1793, 1797, 1801, 1806, 1813, 1820, 1822, 1828, 1835, 1840, 1849, 1854, 1858, 1863, 1868, 1874, + 1881, 1890, 1896, 1904, 1912, 1919, 1924, 1930, 1943, 1959, 1971, 1965, 1964, 1963, 1962, 1962, + 1961, 1960, 1959, 1958, 1957, 1957, 1956, 1955, 1954, 1953, 1952, 1952, 1951, 1950, 1949, 1948, + 1947, 1947, 1946, 1945, 1944, 1943, 1942, 1942, 1941, 1940, 1939, 1938, 1937, 1937, 1936, 1935, + 1934, 1933, 1932, 1932, 1931, 1930, 1929, 1928, 1927, 1927, 1926, 1925, 1924, 1923, 1922, 1922, + 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, 1912, 1912, 1911, 1910, 1909, 1908, + 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, 1899, 1898, 1897, 1897, 1896, 1895, + 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, 1886, 1885, 1884, 1883, 1882, 1882, + 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, + 1867, 1867, 1866, 1865, 1864, 1863, 1862, 1862, 1861, 1860, 1859, 1858, 1857, 1857, 1856, 1855, + 1023, 1026, 1034, 1041, 1049, 1056, 1066, 1076, 1087, 1098, 1109, 1122, 1135, 1149, 1163, 1173, + 1185, 1195, 1206, 1218, 1232, 1246, 1255, 1268, 1278, 1291, 1302, 1312, 1323, 1335, 1346, 1358, + 1370, 1375, 1381, 1391, 1400, 1408, 1417, 1426, 1433, 1441, 1451, 1456, 1462, 1469, 1478, 1485, + 1490, 1494, 1501, 1510, 1516, 1521, 1527, 1535, 1542, 1545, 1548, 1557, 1564, 1570, 1574, 1580, + 1585, 1591, 1594, 1599, 1605, 1611, 1615, 1620, 1628, 1635, 1641, 1647, 1653, 1657, 1662, 1665, + 1671, 1676, 1680, 1684, 1689, 1692, 1698, 1706, 1715, 1719, 1725, 1733, 1738, 1742, 1748, 1755, + 1759, 1761, 1765, 1772, 1778, 1782, 1782, 1786, 1793, 1800, 1807, 1816, 1822, 1828, 1833, 1838, + 1842, 1849, 1854, 1865, 1873, 1878, 1887, 1905, 1921, 1934, 1945, 1956, 1956, 1955, 1954, 1953, + 1952, 1951, 1951, 1950, 1949, 1948, 1947, 1946, 1946, 1945, 1944, 1943, 1942, 1941, 1941, 1940, + 1939, 1938, 1937, 1936, 1936, 1935, 1934, 1933, 1932, 1931, 1931, 1930, 1929, 1928, 1927, 1926, + 1926, 1925, 1924, 1923, 1922, 1922, 1921, 1920, 1919, 1918, 1917, 1917, 1916, 1915, 1914, 1913, + 1912, 1912, 1911, 1910, 1909, 1908, 1907, 1907, 1906, 1905, 1904, 1903, 1902, 1902, 1901, 1900, + 1899, 1898, 1897, 1897, 1896, 1895, 1894, 1893, 1892, 1892, 1891, 1890, 1889, 1888, 1887, 1887, + 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1878, 1877, 1876, 1875, 1874, 1873, + 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1863, 1863, 1862, 1861, 1860, + 1859, 1858, 1858, 1857, 1856, 1855, 1854, 1853, 1853, 1852, 1851, 1850, 1849, 1848, 1848, 1847, + }, + { + /*5*/ + 1020, 1032, 1042, 1050, 1060, 1068, 1079, 1091, 1105, 1117, 1131, 1145, 1161, 1175, 1189, 1202, + 1217, 1231, 1245, 1262, 1278, 1292, 1306, 1318, 1330, 1342, 1354, 1366, 1379, 1390, 1400, 1413, + 1422, 1430, 1438, 1447, 1455, 1462, 1470, 1478, 1485, 1492, 1500, 1506, 1514, 1521, 1528, 1532, + 1538, 1545, 1554, 1561, 1567, 1572, 1577, 1581, 1586, 1591, 1597, 1603, 1608, 1612, 1618, 1623, + 1627, 1631, 1637, 1642, 1645, 1648, 1652, 1657, 1661, 1664, 1668, 1673, 1678, 1683, 1688, 1692, + 1697, 1702, 1707, 1712, 1716, 1719, 1723, 1727, 1734, 1741, 1745, 1747, 1752, 1758, 1765, 1769, + 1774, 1779, 1783, 1785, 1789, 1795, 1801, 1806, 1809, 1813, 1819, 1824, 1829, 1835, 1840, 1845, + 1850, 1854, 1862, 1871, 1880, 1885, 1891, 1900, 1906, 1909, 1913, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1025, 1032, 1041, 1053, 1064, 1073, 1086, 1100, 1117, 1135, 1160, 1175, 1180, 1189, 1206, 1235, + 1254, 1265, 1266, 1280, 1290, 1312, 1329, 1346, 1358, 1378, 1389, 1394, 1408, 1421, 1440, 1454, + 1461, 1466, 1478, 1492, 1498, 1501, 1502, 1512, 1529, 1540, 1545, 1549, 1552, 1559, 1570, 1576, + 1582, 1589, 1591, 1590, 1601, 1614, 1620, 1623, 1626, 1629, 1632, 1642, 1653, 1661, 1663, 1672, + 1674, 1679, 1682, 1686, 1687, 1687, 1685, 1688, 1695, 1706, 1709, 1714, 1715, 1718, 1717, 1720, + 1728, 1735, 1736, 1737, 1744, 1750, 1753, 1757, 1763, 1767, 1771, 1778, 1784, 1788, 1793, 1799, + 1803, 1806, 1811, 1817, 1822, 1827, 1831, 1836, 1839, 1844, 1851, 1856, 1862, 1865, 1871, 1875, + 1881, 1888, 1892, 1898, 1907, 1916, 1920, 1928, 1941, 1940, 1939, 1960, 1959, 1959, 1958, 1957, + 1956, 1955, 1954, 1954, 1953, 1952, 1951, 1950, 1949, 1949, 1948, 1947, 1946, 1945, 1944, 1944, + 1943, 1942, 1941, 1940, 1939, 1939, 1938, 1937, 1936, 1935, 1934, 1934, 1933, 1932, 1931, 1930, + 1929, 1929, 1928, 1927, 1926, 1925, 1924, 1924, 1923, 1922, 1921, 1920, 1919, 1919, 1918, 1917, + 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1904, 1904, + 1903, 1902, 1901, 1900, 1899, 1899, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, + 1889, 1889, 1888, 1887, 1886, 1885, 1884, 1884, 1883, 1882, 1881, 1880, 1879, 1879, 1878, 1877, + 1876, 1875, 1875, 1874, 1873, 1872, 1871, 1870, 1870, 1869, 1868, 1867, 1866, 1865, 1865, 1864, + 1863, 1862, 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, + 1021, 1031, 1042, 1051, 1060, 1070, 1082, 1093, 1106, 1120, 1135, 1150, 1165, 1179, 1195, 1209, + 1224, 1236, 1248, 1263, 1279, 1295, 1309, 1321, 1334, 1349, 1360, 1371, 1382, 1391, 1400, 1410, + 1419, 1425, 1435, 1447, 1456, 1462, 1472, 1480, 1488, 1492, 1501, 1507, 1515, 1521, 1528, 1534, + 1541, 1547, 1552, 1557, 1564, 1569, 1573, 1579, 1584, 1587, 1590, 1598, 1602, 1608, 1611, 1616, + 1619, 1627, 1631, 1635, 1637, 1642, 1644, 1647, 1650, 1655, 1658, 1662, 1665, 1667, 1668, 1672, + 1677, 1682, 1685, 1689, 1694, 1700, 1704, 1708, 1712, 1715, 1719, 1725, 1731, 1735, 1741, 1748, + 1753, 1758, 1762, 1766, 1771, 1777, 1781, 1787, 1790, 1792, 1794, 1802, 1809, 1815, 1818, 1821, + 1827, 1835, 1841, 1847, 1852, 1860, 1870, 1874, 1878, 1900, 1923, 1904, 1903, 1902, 1902, 1901, + 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, 1894, 1893, 1892, 1891, 1890, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1881, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1869, 1868, 1867, 1866, 1865, 1865, 1864, 1863, 1862, + 1861, 1860, 1860, 1859, 1858, 1857, 1856, 1856, 1855, 1854, 1853, 1852, 1852, 1851, 1850, 1849, + 1848, 1848, 1847, 1846, 1845, 1844, 1844, 1843, 1842, 1841, 1840, 1839, 1839, 1838, 1837, 1836, + 1835, 1835, 1834, 1833, 1832, 1831, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, + 1822, 1822, 1821, 1820, 1819, 1818, 1818, 1817, 1816, 1815, 1814, 1814, 1813, 1812, 1811, 1810, + 1810, 1809, 1808, 1807, 1806, 1806, 1805, 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, + }, + { + /*6*/ + 1025, 1030, 1039, 1045, 1051, 1059, 1070, 1078, 1089, 1099, 1112, 1124, 1138, 1153, 1168, 1180, + 1193, 1204, 1218, 1230, 1246, 1259, 1271, 1281, 1294, 1307, 1320, 1333, 1347, 1358, 1369, 1381, + 1392, 1400, 1407, 1417, 1426, 1434, 1439, 1446, 1454, 1461, 1468, 1477, 1486, 1493, 1499, 1504, + 1512, 1522, 1527, 1531, 1536, 1542, 1548, 1552, 1556, 1561, 1568, 1574, 1579, 1586, 1592, 1598, + 1605, 1609, 1613, 1620, 1626, 1631, 1635, 1641, 1646, 1651, 1658, 1664, 1671, 1677, 1682, 1686, + 1689, 1695, 1703, 1709, 1713, 1718, 1724, 1729, 1734, 1740, 1745, 1748, 1753, 1761, 1768, 1773, + 1779, 1786, 1791, 1794, 1800, 1807, 1814, 1819, 1825, 1827, 1832, 1838, 1844, 1849, 1856, 1864, + 1874, 1883, 1892, 1902, 1909, 1916, 1926, 1939, 1946, 1954, 1967, 1978, 1977, 1977, 1976, 1975, + 1974, 1973, 1972, 1972, 1971, 1970, 1969, 1968, 1967, 1966, 1966, 1965, 1964, 1963, 1962, 1961, + 1961, 1960, 1959, 1958, 1957, 1956, 1956, 1955, 1954, 1953, 1952, 1951, 1951, 1950, 1949, 1948, + 1947, 1946, 1945, 1945, 1944, 1943, 1942, 1941, 1940, 1940, 1939, 1938, 1937, 1936, 1935, 1935, + 1934, 1933, 1932, 1931, 1930, 1930, 1929, 1928, 1927, 1926, 1925, 1925, 1924, 1923, 1922, 1921, + 1920, 1919, 1919, 1918, 1917, 1916, 1915, 1914, 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, + 1907, 1906, 1905, 1904, 1904, 1903, 1902, 1901, 1900, 1899, 1898, 1898, 1897, 1896, 1895, 1894, + 1893, 1893, 1892, 1891, 1890, 1889, 1888, 1888, 1887, 1886, 1885, 1884, 1883, 1883, 1882, 1881, + 1880, 1879, 1878, 1877, 1877, 1876, 1875, 1874, 1873, 1872, 1872, 1871, 1870, 1869, 1868, 1867, + 1024, 1028, 1033, 1039, 1046, 1051, 1061, 1070, 1082, 1096, 1113, 1124, 1129, 1137, 1149, 1171, + 1186, 1192, 1191, 1201, 1209, 1228, 1242, 1258, 1268, 1286, 1295, 1300, 1312, 1324, 1342, 1356, + 1363, 1365, 1375, 1387, 1392, 1394, 1395, 1404, 1419, 1427, 1432, 1437, 1440, 1447, 1456, 1463, + 1468, 1473, 1473, 1474, 1485, 1497, 1502, 1503, 1508, 1512, 1517, 1525, 1533, 1542, 1544, 1550, + 1551, 1557, 1561, 1566, 1566, 1566, 1564, 1567, 1575, 1585, 1590, 1595, 1595, 1599, 1597, 1602, + 1610, 1618, 1617, 1618, 1626, 1634, 1638, 1640, 1647, 1651, 1655, 1662, 1667, 1669, 1675, 1681, + 1683, 1686, 1689, 1692, 1697, 1705, 1709, 1713, 1717, 1720, 1727, 1731, 1735, 1741, 1743, 1750, + 1757, 1766, 1772, 1782, 1788, 1794, 1804, 1811, 1818, 1832, 1846, 1845, 1844, 1844, 1843, 1842, + 1841, 1840, 1840, 1839, 1838, 1837, 1837, 1836, 1835, 1834, 1833, 1833, 1832, 1831, 1830, 1830, + 1829, 1828, 1827, 1826, 1826, 1825, 1824, 1823, 1822, 1822, 1821, 1820, 1819, 1819, 1818, 1817, + 1816, 1815, 1815, 1814, 1813, 1812, 1812, 1811, 1810, 1809, 1808, 1808, 1807, 1806, 1805, 1804, + 1804, 1803, 1802, 1801, 1801, 1800, 1799, 1798, 1797, 1797, 1796, 1795, 1794, 1794, 1793, 1792, + 1791, 1790, 1790, 1789, 1788, 1787, 1786, 1786, 1785, 1784, 1783, 1783, 1782, 1781, 1780, 1779, + 1779, 1778, 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1772, 1771, 1770, 1769, 1768, 1768, 1767, + 1766, 1765, 1765, 1764, 1763, 1762, 1761, 1761, 1760, 1759, 1758, 1757, 1757, 1756, 1755, 1754, + 1754, 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1743, 1743, 1742, + 1022, 1024, 1030, 1034, 1038, 1043, 1052, 1060, 1068, 1076, 1085, 1096, 1107, 1119, 1130, 1139, + 1147, 1156, 1164, 1174, 1186, 1200, 1211, 1221, 1231, 1245, 1254, 1264, 1276, 1286, 1296, 1303, + 1312, 1317, 1324, 1334, 1342, 1347, 1354, 1363, 1369, 1375, 1382, 1387, 1392, 1398, 1404, 1408, + 1413, 1419, 1424, 1429, 1433, 1437, 1442, 1449, 1454, 1458, 1462, 1468, 1472, 1477, 1481, 1487, + 1491, 1495, 1498, 1501, 1505, 1509, 1512, 1515, 1520, 1526, 1531, 1536, 1538, 1539, 1541, 1546, + 1551, 1554, 1556, 1559, 1567, 1572, 1576, 1582, 1587, 1589, 1593, 1598, 1603, 1606, 1611, 1615, + 1619, 1624, 1628, 1635, 1641, 1646, 1648, 1652, 1656, 1660, 1665, 1670, 1674, 1678, 1683, 1690, + 1698, 1704, 1711, 1718, 1725, 1735, 1744, 1751, 1752, 1769, 1785, 1781, 1780, 1779, 1778, 1778, + 1777, 1776, 1775, 1775, 1774, 1773, 1772, 1771, 1771, 1770, 1769, 1768, 1768, 1767, 1766, 1765, + 1765, 1764, 1763, 1762, 1762, 1761, 1760, 1759, 1759, 1758, 1757, 1756, 1756, 1755, 1754, 1753, + 1753, 1752, 1751, 1750, 1750, 1749, 1748, 1747, 1747, 1746, 1745, 1744, 1744, 1743, 1742, 1741, + 1741, 1740, 1739, 1738, 1737, 1737, 1736, 1735, 1734, 1734, 1733, 1732, 1731, 1731, 1730, 1729, + 1728, 1728, 1727, 1726, 1725, 1725, 1724, 1723, 1722, 1722, 1721, 1720, 1719, 1719, 1718, 1717, + 1716, 1716, 1715, 1714, 1713, 1713, 1712, 1711, 1710, 1710, 1709, 1708, 1707, 1707, 1706, 1705, + 1704, 1703, 1703, 1702, 1701, 1700, 1700, 1699, 1698, 1697, 1697, 1696, 1695, 1694, 1694, 1693, + 1692, 1691, 1691, 1690, 1689, 1688, 1688, 1687, 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, + }, + { + /*7*/ + 1022, 1029, 1038, 1046, 1054, 1061, 1071, 1081, 1094, 1105, 1118, 1131, 1145, 1160, 1175, 1187, + 1202, 1215, 1230, 1244, 1259, 1273, 1286, 1298, 1311, 1323, 1334, 1348, 1360, 1373, 1385, 1396, + 1406, 1415, 1423, 1432, 1440, 1450, 1457, 1465, 1474, 1483, 1490, 1497, 1505, 1512, 1519, 1526, + 1533, 1539, 1546, 1553, 1560, 1566, 1573, 1582, 1587, 1592, 1596, 1601, 1606, 1610, 1615, 1619, + 1625, 1632, 1638, 1643, 1648, 1651, 1654, 1660, 1666, 1670, 1671, 1674, 1679, 1686, 1693, 1700, + 1702, 1704, 1710, 1714, 1718, 1723, 1730, 1734, 1739, 1744, 1749, 1754, 1761, 1767, 1772, 1776, + 1781, 1784, 1789, 1794, 1799, 1802, 1805, 1809, 1817, 1823, 1830, 1833, 1841, 1847, 1852, 1856, + 1863, 1869, 1875, 1882, 1891, 1896, 1901, 1903, 1910, 1920, 1932, 1931, 1930, 1929, 1928, 1927, + 1927, 1926, 1925, 1924, 1923, 1923, 1922, 1921, 1920, 1919, 1918, 1918, 1917, 1916, 1915, 1914, + 1914, 1913, 1912, 1911, 1910, 1909, 1909, 1908, 1907, 1906, 1905, 1905, 1904, 1903, 1902, 1901, + 1900, 1900, 1899, 1898, 1897, 1896, 1895, 1895, 1894, 1893, 1892, 1891, 1891, 1890, 1889, 1888, + 1887, 1886, 1886, 1885, 1884, 1883, 1882, 1882, 1881, 1880, 1879, 1878, 1877, 1877, 1876, 1875, + 1874, 1873, 1873, 1872, 1871, 1870, 1869, 1868, 1868, 1867, 1866, 1865, 1864, 1864, 1863, 1862, + 1861, 1860, 1859, 1859, 1858, 1857, 1856, 1855, 1855, 1854, 1853, 1852, 1851, 1850, 1850, 1849, + 1848, 1847, 1846, 1846, 1845, 1844, 1843, 1842, 1841, 1841, 1840, 1839, 1838, 1837, 1836, 1836, + 1835, 1834, 1833, 1832, 1832, 1831, 1830, 1829, 1828, 1827, 1827, 1826, 1825, 1824, 1823, 1823, + 1024, 1029, 1033, 1038, 1044, 1048, 1055, 1062, 1072, 1084, 1097, 1106, 1110, 1117, 1129, 1149, + 1162, 1168, 1169, 1177, 1186, 1202, 1215, 1227, 1237, 1254, 1261, 1266, 1277, 1286, 1302, 1314, + 1320, 1324, 1334, 1346, 1353, 1355, 1355, 1365, 1378, 1385, 1391, 1395, 1398, 1404, 1413, 1418, + 1422, 1429, 1432, 1433, 1442, 1450, 1455, 1457, 1462, 1465, 1469, 1476, 1482, 1488, 1492, 1498, + 1501, 1504, 1507, 1512, 1514, 1516, 1517, 1522, 1525, 1530, 1532, 1537, 1539, 1540, 1542, 1546, + 1551, 1555, 1559, 1562, 1566, 1568, 1572, 1574, 1578, 1584, 1587, 1588, 1590, 1595, 1599, 1602, + 1608, 1612, 1616, 1619, 1622, 1625, 1630, 1636, 1639, 1645, 1648, 1654, 1660, 1661, 1672, 1674, + 1678, 1680, 1685, 1689, 1704, 1710, 1702, 1713, 1734, 1722, 1700, 1737, 1736, 1735, 1735, 1734, + 1733, 1732, 1732, 1731, 1730, 1729, 1729, 1728, 1727, 1727, 1726, 1725, 1724, 1724, 1723, 1722, + 1721, 1721, 1720, 1719, 1718, 1718, 1717, 1716, 1715, 1715, 1714, 1713, 1713, 1712, 1711, 1710, + 1710, 1709, 1708, 1707, 1707, 1706, 1705, 1704, 1704, 1703, 1702, 1701, 1701, 1700, 1699, 1699, + 1698, 1697, 1696, 1696, 1695, 1694, 1693, 1693, 1692, 1691, 1690, 1690, 1689, 1688, 1687, 1687, + 1686, 1685, 1685, 1684, 1683, 1682, 1682, 1681, 1680, 1679, 1679, 1678, 1677, 1676, 1676, 1675, + 1674, 1673, 1673, 1672, 1671, 1670, 1670, 1669, 1668, 1668, 1667, 1666, 1665, 1665, 1664, 1663, + 1662, 1662, 1661, 1660, 1659, 1659, 1658, 1657, 1656, 1656, 1655, 1654, 1654, 1653, 1652, 1651, + 1651, 1650, 1649, 1648, 1648, 1647, 1646, 1645, 1645, 1644, 1643, 1642, 1642, 1641, 1640, 1640, + 1022, 1025, 1028, 1032, 1037, 1042, 1047, 1054, 1061, 1069, 1077, 1085, 1092, 1100, 1108, 1117, + 1126, 1134, 1141, 1150, 1159, 1169, 1177, 1184, 1192, 1199, 1207, 1214, 1223, 1230, 1237, 1246, + 1254, 1259, 1264, 1272, 1279, 1283, 1289, 1297, 1302, 1308, 1313, 1318, 1324, 1328, 1333, 1338, + 1344, 1347, 1351, 1355, 1363, 1370, 1373, 1376, 1381, 1385, 1386, 1391, 1396, 1401, 1404, 1407, + 1410, 1414, 1419, 1422, 1422, 1424, 1425, 1428, 1430, 1431, 1434, 1441, 1444, 1444, 1447, 1450, + 1455, 1456, 1458, 1459, 1464, 1467, 1470, 1472, 1476, 1479, 1482, 1487, 1491, 1493, 1497, 1504, + 1507, 1509, 1514, 1516, 1518, 1521, 1524, 1527, 1529, 1531, 1536, 1541, 1547, 1551, 1556, 1558, + 1564, 1567, 1572, 1576, 1582, 1581, 1581, 1587, 1594, 1599, 1604, 1611, 1611, 1610, 1609, 1609, + 1608, 1607, 1607, 1606, 1605, 1605, 1604, 1603, 1602, 1602, 1601, 1600, 1600, 1599, 1598, 1598, + 1597, 1596, 1596, 1595, 1594, 1594, 1593, 1592, 1592, 1591, 1590, 1590, 1589, 1588, 1587, 1587, + 1586, 1585, 1585, 1584, 1583, 1583, 1582, 1581, 1581, 1580, 1579, 1579, 1578, 1577, 1577, 1576, + 1575, 1574, 1574, 1573, 1572, 1572, 1571, 1570, 1570, 1569, 1568, 1568, 1567, 1566, 1566, 1565, + 1564, 1564, 1563, 1562, 1561, 1561, 1560, 1559, 1559, 1558, 1557, 1557, 1556, 1555, 1555, 1554, + 1553, 1553, 1552, 1551, 1551, 1550, 1549, 1548, 1548, 1547, 1546, 1546, 1545, 1544, 1544, 1543, + 1542, 1542, 1541, 1540, 1540, 1539, 1538, 1538, 1537, 1536, 1535, 1535, 1534, 1533, 1533, 1532, + 1531, 1531, 1530, 1529, 1529, 1528, 1527, 1527, 1526, 1525, 1525, 1524, 1523, 1522, 1522, 1521, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 13107, 12342, 12588, 13362, 2608, 13107, 13621, 12588, 13362, 2608, 13107, 12341, + 12588, 13362, 2608, 13107, 13620, 12588, 13362, 2608, 13107, 12340, 12588, 13362, 2608, 13107, 13619, 12588, + 13362, 2608, 13107, 12339, 12588, 13362, 2608, 13107, 13618, 12588, 13362, 2608, 13107, 12338, 12588, 13362, + 2608, 13107, 13617, 12588, 13362, 2608, 13107, 12593, 12588, 13362, 2608, 13107, 13872, 12588, 13362, 2608, + 13107, 12592, 12588, 13362, 2608, 12851, 13881, 12588, 13362, 2608, 12851, 12857, 12588, 13362, 2608, 12851, + 14136, 12588, 13362, 2608, 12851, 12856, 12588, 13362, 2608, 12851, 14391, 12588, 13362, 2608, 12851, 13111, + 12588, 13362, 2608, 12851, 14646, 12588, 13362, 2608, 12851, 13366, 12588, 13362, 2608, 12851, 12342, 12588, + 13362, 2608, 12851, 13621, 12588, 13362, 2608, 12851, 12341, 12588, 13362, 2608, 12851, 13876, 12588, 13362, + 2608, 12851, 12852, 12588, 13362, 2608, 12851, 14131, 12588, 13362, 2608, 12851, 13107, 12588, 13362, 2608, + 12851, 12851, 12588, 13362, 2608, 12851, 12595, 12588, 13362, 2608, 12851, 12339, 12588, 13362, 2608, 12851, + 14642, 12588, 13362, 2608, 12851, 14386, 12588, 13362, 2608, 12851, 14130, 12588, 13362, 2608, 12851, 13874, + 12588, 13362, 2608, 12851, 13618, 12588, 13362, 2608, 12851, 13362, 12588, 13362, 2608, 12851, 13106, 12588, + 13362, 2608, 12851, 12850, 12588, 13362, 2608, 12851, 12594, 12588, 13362, 2608, 12851, 12338, 12588, 13362, + 2608, 12851, 14641, 12588, 13362, 2608, 12851, 14385, 12588, 13362, 2608, 12851, 14129, 12588, 13362, 2608, + 12851, 13873, 12588, 13362, 2608, 12851, 13617, 12588, 13362, 2608, 12851, 13361, 12588, 13362, 2608, 12851, + 13105, 12588, 13362, 2608, 12851, 12849, 12588, 13362, 2608, 12851, 12593, 12588, 13362, 2608, 12851, 12337, + 12588, 13362, 2608, 12851, 14640, 12588, 13362, 2608, 12851, 14384, 12588, 13362, 2608, 12851, 14128, 12588, + 13362, 2608, 12851, 13872, 12588, 13362, 2608, 12851, 13616, 12588, 13362, 2608, 12851, 13360, 12588, 13362, + 2608, 12851, 13104, 12588, 13362, 2608, 12851, 12848, 12588, 13362, 2608, 12851, 12592, 12588, 13362, 2608, + 12851, 12336, 12588, 13362, 2608, 12595, 14649, 12588, 13362, 2608, 12595, 14393, 12588, 13362, 2608, 12595, + 14137, 12588, 13362, 2608, 12595, 13881, 12588, 13362, 2608, 12595, 13625, 12588, 13362, 2608, 12595, 13369, + 12588, 13362, 2608, 12595, 13113, 12588, 13362, 2608, 12595, 12857, 12588, 13362, 2608, 12595, 12601, 12588, + 13362, 2608, 12595, 12345, 12588, 13362, 2608, 12595, 14648, 12588, 13362, 2608, 12595, 14392, 12588, 13362, + 2608, 12595, 14136, 12588, 13362, 2608, 12595, 13880, 12588, 13362, 2608, 12595, 13624, 12588, 13362, 2608, + 12595, 13368, 12588, 13362, 2608, 12595, 13112, 12588, 13362, 2608, 12595, 12856, 12588, 13362, 2608, 12595, + 12600, 12588, 13362, 2608, 12595, 12344, 12588, 13362, 2608, 12595, 14647, 12588, 13362, 2608, 12595, 14391, + 12588, 13362, 2608, 12595, 14135, 12588, 13362, 2608, 12595, 13879, 12588, 13362, 2608, 12595, 13623, 12588, + 13362, 2608, 12595, 13367, 12588, 13362, 2608, 12595, 13111, 12588, 13362, 2608, 12595, 12855, 12588, 13362, + 2608, 12595, 12599, 12588, 13362, 2608, 12595, 12343, 12588, 13362, 2608, 12595, 14646, 12588, 13362, 2608, + 12595, 14390, 12588, 13362, 2608, 12595, 14134, 12588, 13362, 2608, 12595, 13878, 12588, 13362, 2608, 12595, + 13622, 12588, 13362, 2608, 12595, 13366, 12588, 13362, 2608, 12595, 13110, 12588, 13362, 2608, 12595, 12854, + 12588, 13362, 2608, 12595, 12598, 12588, 13362, 2608, 12595, 12342, 12588, 13362, 2608, 12595, 14645, 12588, + 13362, 2608, 12595, 14389, 12588, 13362, 2608, 12595, 14133, 12588, 13362, 2608, 12595, 13877, 12588, 13362, + 2608, 12595, 13621, 12588, 13362, 2608, 12595, 13365, 12588, 13362, 2608, 12595, 13109, 12588, 13362, 2608, + 12595, 12853, 12588, 13362, 2608, 12595, 12597, 12588, 13362, 2608, 12595, 12341, 12588, 13362, 2608, 12595, + 14644, 12588, 13362, 2608, 12595, 14388, 12588, 13362, 2608, 12595, 14132, 12588, 13362, 2608, 12595, 13876, + 12588, 13362, 2608, 12595, 13620, 12588, 13362, 2608, 12595, 13364, 12588, 13362, 2608, 12595, 13108, 12588, + 13362, 2608, 12595, 12852, 12588, 13362, 2608, 12595, 12596, 12588, 13362, 2608, 12595, 12340, 12588, 13362, + 2608, 12595, 14643, 12588, 13362, 2608, 12595, 14387, 12588, 13362, 2608, 12595, 14131, 12588, 13362, 2608, + 12595, 13875, 12588, 13362, 2608, 12595, 13619, 12588, 13362, 2608, 12595, 13363, 12588, 13362, 2608, 12595, + 13107, 12588, 13362, 2608, 12595, 12851, 12588, 13362, 2608, 12595, 12595, 12588, 13362, 2608, 12595, 12339, + 12588, 13362, 2608, 12595, 14642, 12588, 13362, 2608, 12595, 14386, 12588, 13362, 2608, 12595, 14130, 12588, + 13362, 2608, 12595, 13874, 12588, 13362, 2608, 12595, 13618, 12588, 13362, 2608, 12595, 13362, 12588, 13362, + 2608, 12595, 13106, 12588, 13362, 2608, 12595, 12850, 12588, 13362, 2608, 12595, 12594, 12588, 13362, 2608, + 12595, 12338, 12588, 13362, 2608, 12595, 14641, 12588, 13362, 2608, 12595, 14385, 12588, 13362, 2608, 12595, + 14129, 12588, 13362, 2608, 12595, 13873, 12588, 13362, 2608, 12595, 13617, 12588, 13362, 2608, 12595, 13361, + 12588, 13362, 2608, 12595, 13105, 12588, 13362, 2608, 12595, 12849, 12588, 13362, 2608, 12595, 12593, 12588, + 13362, 2608, 12595, 12337, 12588, 13362, 2608, 12595, 14640, 12588, 13362, 2608, 1, 0, 1, 0, + }, + .disc_tbl = { + 4095, 4082, 4072, 4062, 4052, 4043, 4033, 4024, 4014, 4005, 3995, 3986, 3977, 3968, 3959, 3950, + 3941, 3933, 3924, 3915, 3907, 3898, 3890, 3881, 3873, 3865, 3857, 3848, 3840, 3832, 3824, 3817, + 3809, 3801, 3793, 3786, 3778, 3770, 3763, 3755, 3748, 3741, 3733, 3726, 3719, 3712, 3705, 3698, + 3691, 3684, 3677, 3670, 3663, 3656, 3650, 3643, 3636, 3630, 3623, 3617, 3610, 3604, 3597, 3591, + 3585, 3578, 3572, 3566, 3560, 3554, 3547, 3541, 3535, 3529, 3523, 3518, 3512, 3506, 3500, 3494, + 3488, 3483, 3477, 3471, 3466, 3460, 3455, 3449, 3444, 3438, 3433, 3427, 3422, 3417, 3411, 3406, + 3401, 3396, 3390, 3385, 3380, 3375, 3370, 3365, 3360, 3355, 3350, 3345, 3340, 3335, 3330, 3325, + 3320, 3315, 3311, 3306, 3301, 3296, 3292, 3287, 3282, 3278, 3273, 3269, 3264, 3260, 3255, 3250, + 3246, 3242, 3237, 3233, 3232, 3231, 3230, 3229, 3228, 3227, 3226, 3225, 3224, 3223, 3222, 3221, + 3220, 3219, 3218, 3217, 3216, 3215, 3214, 3213, 3212, 3211, 3210, 3209, 3208, 3207, 3206, 3205, + 3204, 3203, 3202, 3201, 3200, 3199, 3198, 3197, 3196, 3195, 3194, 3193, 3192, 3191, 3190, 3189, + 3188, 3187, 3186, 3185, 3184, 3183, 3182, 3181, 3180, 3179, 3178, 3177, 3176, 3175, 3174, 3173, + 3172, 3171, 3170, 3169, 3168, 3167, 3166, 3165, 3164, 3163, 3162, 3161, 3160, 3159, 3158, 3157, + 3156, 3155, 3154, 3153, 3152, 3151, 3150, 3149, 3148, 3147, 3146, 3145, 3144, 3143, 3142, 3141, + 3140, 3139, 3138, 3137, 3136, 3135, 3134, 3133, 3132, 3131, 3130, 3129, 3128, 3127, 3126, 3125, + 3124, 3123, 3122, 3121, 3120, 3119, 3118, 3117, 3116, 3115, 3114, 3113, 3112, 3111, 3110, 3109, + 1024, 1027, 1029, 1032, 1034, 1037, 1039, 1042, 1044, 1047, 1049, 1052, 1054, 1056, 1059, 1061, + 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1087, 1089, 1092, 1094, 1096, 1098, + 1100, 1103, 1105, 1107, 1109, 1112, 1114, 1116, 1118, 1120, 1123, 1125, 1127, 1129, 1131, 1133, + 1136, 1138, 1140, 1142, 1144, 1146, 1148, 1151, 1153, 1155, 1157, 1159, 1161, 1163, 1165, 1167, + 1169, 1171, 1173, 1175, 1177, 1179, 1182, 1184, 1186, 1188, 1190, 1191, 1193, 1196, 1198, 1200, + 1202, 1203, 1206, 1208, 1209, 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1229, 1231, + 1232, 1234, 1236, 1238, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + }, +}; +struct isp_cfg_pt gc1004_mipi_isp_cfg = +{ + .isp_test_settings = &gc1004_mipi_isp_test_settings, + .isp_3a_settings = &gc1004_mipi_isp_3a_settings, + .isp_tunning_settings = &gc1004_mipi_isp_tuning_settings, + .isp_iso_settings = &gc1004_mipi_isp_iso_settings, +}; + + +#endif /* end of _GC1004_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg.h new file mode 100755 index 00000000..04839ba3 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg.h @@ -0,0 +1,845 @@ +/* +****************************************************************************************** +* +* h22_mipi_isp_cfg.h +* +* Hawkview ISP - h22_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/24 Automatic generation. +* +****************************************************************************************** +*/ + +#ifndef _H22_MIPI_ISP_CFG_H_V100_ +#define _H22_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param h22_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 500, + .exp_line_end = 13664, + .exp_change_interval = 4, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 2, + .gain_end = 256, + .gain_change_interval = 4, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 100, + .isp_exp_line = 10000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 44, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param h22_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1488, + .fno = 20, + .ae_table_preview_length = 4, + .ae_table_preview = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 3000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 4, + .ae_table_capture = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 3000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1024, + 50, 30, 1024, 1024, + 30, 30, 1024, 3000, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 12, + .ae_capture_speed = 12, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 1, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 2, + .awb_speed = 16, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 18, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 35, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 35, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 35, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 35, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 40, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 40, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 30, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 30, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 30, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 40, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 40, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 30, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 30, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 30, 8000, 128, 100, + 243, 256, 215, 256, 256, 256, 40, 6000, 128, 100, + 220, 256, 255, 256, 256, 256, 30, 6700, 128, 100, + 232, 256, 236, 256, 256, 256, 40, 6600, 128, 100, + 275, 256, 197, 256, 256, 256, 40, 4150, 128, 100, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param h22_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 1, 28, 900, }, { 0, 255, 5, }, { 1, 9, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 700, }, { 1, 255, 5, }, { 2, 12, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 2, 24, 600, }, { 2, 255, 5, }, { 3, 16, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 12, { 32, 20, 6, 32, }, 14, 108, 5, + { 2, 12, 2, 200, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 4, 16, 512, }, { 3, 255, 5, }, { 4, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, -2, { 32, 18, 12, 32, }, 40, 80, 10, + { 2, 12, 2, 200, }, { 10, 0, }, { 32, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 5, 12, 450, }, { 4, 255, 6, }, { 5, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -2, -2, }, -12, { 32, 18, 16, 32, }, 30, 30, 20, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 6, 12, 400, }, { 5, 255, 7, }, { 6, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -20, 2, }, -16, { 32, 18, 16, 32, }, 32, 8, 30, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param h22_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 106, + .ver_visual_angle = 55, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 344, 256, 256, 348, -62, -46, -46, -62, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 308, 0, -52, }, { -102, 369, -11, }, { -81, -297, 634, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 397, -111, -30, }, { -92, 356, -8, }, { -31, -263, 550, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 430, -155, -19, }, { -107, 418, -55, }, { -26, -235, 517, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 13107, 12342, 12588, 13362, 2608, 13107, 13621, 12588, 13362, 2608, 13107, 12341, + 12588, 13362, 2608, 13107, 13620, 12588, 13362, 2608, 13107, 12340, 12588, 13362, 2608, 13107, 13619, 12588, + 13362, 2608, 13107, 12339, 12588, 13362, 2608, 13107, 13618, 12588, 13362, 2608, 13107, 12338, 12588, 13362, + 2608, 13107, 13617, 12588, 13362, 2608, 13107, 12593, 12588, 13362, 2608, 13107, 13872, 12588, 13362, 2608, + 13107, 12592, 12588, 13362, 2608, 12851, 13881, 12588, 13362, 2608, 12851, 12857, 12588, 13362, 2608, 12851, + 14136, 12588, 13362, 2608, 12851, 12856, 12588, 13362, 2608, 12851, 14391, 12588, 13362, 2608, 12851, 13111, + 12588, 13362, 2608, 12851, 14646, 12588, 13362, 2608, 12851, 13366, 12588, 13362, 2608, 12851, 12342, 12588, + 13362, 2608, 12851, 13621, 12588, 13362, 2608, 12851, 12341, 12588, 13362, 2608, 12851, 13876, 12588, 13362, + 2608, 12851, 12852, 12588, 13362, 2608, 12851, 14131, 12588, 13362, 2608, 12851, 13107, 12588, 13362, 2608, + 12851, 12851, 12588, 13362, 2608, 12851, 12595, 12588, 13362, 2608, 12851, 12339, 12588, 13362, 2608, 12851, + 14642, 12588, 13362, 2608, 12851, 14386, 12588, 13362, 2608, 12851, 14130, 12588, 13362, 2608, 12851, 13874, + 12588, 13362, 2608, 12851, 13618, 12588, 13362, 2608, 12851, 13362, 12588, 13362, 2608, 12851, 13106, 12588, + 13362, 2608, 12851, 12850, 12588, 13362, 2608, 12851, 12594, 12588, 13362, 2608, 12851, 12338, 12588, 13362, + 2608, 12851, 14641, 12588, 13362, 2608, 12851, 14385, 12588, 13362, 2608, 12851, 14129, 12588, 13362, 2608, + 12851, 13873, 12588, 13362, 2608, 12851, 13617, 12588, 13362, 2608, 12851, 13361, 12588, 13362, 2608, 12851, + 13105, 12588, 13362, 2608, 12851, 12849, 12588, 13362, 2608, 12851, 12593, 12588, 13362, 2608, 12851, 12337, + 12588, 13362, 2608, 12851, 14640, 12588, 13362, 2608, 12851, 14384, 12588, 13362, 2608, 12851, 14128, 12588, + 13362, 2608, 12851, 13872, 12588, 13362, 2608, 12851, 13616, 12588, 13362, 2608, 12851, 13360, 12588, 13362, + 2608, 12851, 13104, 12588, 13362, 2608, 12851, 12848, 12588, 13362, 2608, 12851, 12592, 12588, 13362, 2608, + 12851, 12336, 12588, 13362, 2608, 12595, 14649, 12588, 13362, 2608, 12595, 14393, 12588, 13362, 2608, 12595, + 14137, 12588, 13362, 2608, 12595, 13881, 12588, 13362, 2608, 12595, 13625, 12588, 13362, 2608, 12595, 13369, + 12588, 13362, 2608, 12595, 13113, 12588, 13362, 2608, 12595, 12857, 12588, 13362, 2608, 12595, 12601, 12588, + 13362, 2608, 12595, 12345, 12588, 13362, 2608, 12595, 14648, 12588, 13362, 2608, 12595, 14392, 12588, 13362, + 2608, 12595, 14136, 12588, 13362, 2608, 12595, 13880, 12588, 13362, 2608, 12595, 13624, 12588, 13362, 2608, + 12595, 13368, 12588, 13362, 2608, 12595, 13112, 12588, 13362, 2608, 12595, 12856, 12588, 13362, 2608, 12595, + 12600, 12588, 13362, 2608, 12595, 12344, 12588, 13362, 2608, 12595, 14647, 12588, 13362, 2608, 12595, 14391, + 12588, 13362, 2608, 12595, 14135, 12588, 13362, 2608, 12595, 13879, 12588, 13362, 2608, 12595, 13623, 12588, + 13362, 2608, 12595, 13367, 12588, 13362, 2608, 12595, 13111, 12588, 13362, 2608, 12595, 12855, 12588, 13362, + 2608, 12595, 12599, 12588, 13362, 2608, 12595, 12343, 12588, 13362, 2608, 12595, 14646, 12588, 13362, 2608, + 12595, 14390, 12588, 13362, 2608, 12595, 14134, 12588, 13362, 2608, 12595, 13878, 12588, 13362, 2608, 12595, + 13622, 12588, 13362, 2608, 12595, 13366, 12588, 13362, 2608, 12595, 13110, 12588, 13362, 2608, 12595, 12854, + 12588, 13362, 2608, 12595, 12598, 12588, 13362, 2608, 12595, 12342, 12588, 13362, 2608, 12595, 14645, 12588, + 13362, 2608, 12595, 14389, 12588, 13362, 2608, 12595, 14133, 12588, 13362, 2608, 12595, 13877, 12588, 13362, + 2608, 12595, 13621, 12588, 13362, 2608, 12595, 13365, 12588, 13362, 2608, 12595, 13109, 12588, 13362, 2608, + 12595, 12853, 12588, 13362, 2608, 12595, 12597, 12588, 13362, 2608, 12595, 12341, 12588, 13362, 2608, 12595, + 14644, 12588, 13362, 2608, 12595, 14388, 12588, 13362, 2608, 12595, 14132, 12588, 13362, 2608, 12595, 13876, + 12588, 13362, 2608, 12595, 13620, 12588, 13362, 2608, 12595, 13364, 12588, 13362, 2608, 12595, 13108, 12588, + 13362, 2608, 12595, 12852, 12588, 13362, 2608, 12595, 12596, 12588, 13362, 2608, 12595, 12340, 12588, 13362, + 2608, 12595, 14643, 12588, 13362, 2608, 12595, 14387, 12588, 13362, 2608, 12595, 14131, 12588, 13362, 2608, + 12595, 13875, 12588, 13362, 2608, 12595, 13619, 12588, 13362, 2608, 12595, 13363, 12588, 13362, 2608, 12595, + 13107, 12588, 13362, 2608, 12595, 12851, 12588, 13362, 2608, 12595, 12595, 12588, 13362, 2608, 12595, 12339, + 12588, 13362, 2608, 12595, 14642, 12588, 13362, 2608, 12595, 14386, 12588, 13362, 2608, 12595, 14130, 12588, + 13362, 2608, 12595, 13874, 12588, 13362, 2608, 12595, 13618, 12588, 13362, 2608, 12595, 13362, 12588, 13362, + 2608, 12595, 13106, 12588, 13362, 2608, 12595, 12850, 12588, 13362, 2608, 12595, 12594, 12588, 13362, 2608, + 12595, 12338, 12588, 13362, 2608, 12595, 14641, 12588, 13362, 2608, 12595, 14385, 12588, 13362, 2608, 12595, + 14129, 12588, 13362, 2608, 12595, 13873, 12588, 13362, 2608, 12595, 13617, 12588, 13362, 2608, 12595, 13361, + 12588, 13362, 2608, 12595, 13105, 12588, 13362, 2608, 12595, 12849, 12588, 13362, 2608, 12595, 12593, 12588, + 13362, 2608, 12595, 12337, 12588, 13362, 2608, 12595, 14640, 12588, 13362, 2608, 1, 0, 1, 0, + }, + .disc_tbl = { + 4095, 4082, 4072, 4062, 4052, 4043, 4033, 4024, 4014, 4005, 3995, 3986, 3977, 3968, 3959, 3950, + 3941, 3933, 3924, 3915, 3907, 3898, 3890, 3881, 3873, 3865, 3857, 3848, 3840, 3832, 3824, 3817, + 3809, 3801, 3793, 3786, 3778, 3770, 3763, 3755, 3748, 3741, 3733, 3726, 3719, 3712, 3705, 3698, + 3691, 3684, 3677, 3670, 3663, 3656, 3650, 3643, 3636, 3630, 3623, 3617, 3610, 3604, 3597, 3591, + 3585, 3578, 3572, 3566, 3560, 3554, 3547, 3541, 3535, 3529, 3523, 3518, 3512, 3506, 3500, 3494, + 3488, 3483, 3477, 3471, 3466, 3460, 3455, 3449, 3444, 3438, 3433, 3427, 3422, 3417, 3411, 3406, + 3401, 3396, 3390, 3385, 3380, 3375, 3370, 3365, 3360, 3355, 3350, 3345, 3340, 3335, 3330, 3325, + 3320, 3315, 3311, 3306, 3301, 3296, 3292, 3287, 3282, 3278, 3273, 3269, 3264, 3260, 3255, 3250, + 3246, 3242, 3237, 3233, 3232, 3231, 3230, 3229, 3228, 3227, 3226, 3225, 3224, 3223, 3222, 3221, + 3220, 3219, 3218, 3217, 3216, 3215, 3214, 3213, 3212, 3211, 3210, 3209, 3208, 3207, 3206, 3205, + 3204, 3203, 3202, 3201, 3200, 3199, 3198, 3197, 3196, 3195, 3194, 3193, 3192, 3191, 3190, 3189, + 3188, 3187, 3186, 3185, 3184, 3183, 3182, 3181, 3180, 3179, 3178, 3177, 3176, 3175, 3174, 3173, + 3172, 3171, 3170, 3169, 3168, 3167, 3166, 3165, 3164, 3163, 3162, 3161, 3160, 3159, 3158, 3157, + 3156, 3155, 3154, 3153, 3152, 3151, 3150, 3149, 3148, 3147, 3146, 3145, 3144, 3143, 3142, 3141, + 3140, 3139, 3138, 3137, 3136, 3135, 3134, 3133, 3132, 3131, 3130, 3129, 3128, 3127, 3126, 3125, + 3124, 3123, 3122, 3121, 3120, 3119, 3118, 3117, 3116, 3115, 3114, 3113, 3112, 3111, 3110, 3109, + 1024, 1027, 1029, 1032, 1034, 1037, 1039, 1042, 1044, 1047, 1049, 1052, 1054, 1056, 1059, 1061, + 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1087, 1089, 1092, 1094, 1096, 1098, + 1100, 1103, 1105, 1107, 1109, 1112, 1114, 1116, 1118, 1120, 1123, 1125, 1127, 1129, 1131, 1133, + 1136, 1138, 1140, 1142, 1144, 1146, 1148, 1151, 1153, 1155, 1157, 1159, 1161, 1163, 1165, 1167, + 1169, 1171, 1173, 1175, 1177, 1179, 1182, 1184, 1186, 1188, 1190, 1191, 1193, 1196, 1198, 1200, + 1202, 1203, 1206, 1208, 1209, 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1229, 1231, + 1232, 1234, 1236, 1238, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + }, +}; +struct isp_cfg_pt h22_mipi_isp_cfg = +{ + .isp_test_settings = &h22_mipi_isp_test_settings, + .isp_3a_settings = &h22_mipi_isp_3a_settings, + .isp_tunning_settings = &h22_mipi_isp_tuning_settings, + .isp_iso_settings = &h22_mipi_isp_iso_settings, +}; + + +#endif /* end of _H22_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg_HK8214C.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg_HK8214C.h new file mode 100755 index 00000000..11060be0 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/h22_mipi_isp_cfg_HK8214C.h @@ -0,0 +1,847 @@ +/* +****************************************************************************************** +* +* h22_mipi_isp_cfg.h +* +* Hawkview ISP - h22_mipi_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/24 Automatic generation. +* +****************************************************************************************** +*/ + +//F2.6 HK-8214C-941 + +#ifndef _H22_MIPI_ISP_CFG_H_V100_ +#define _H22_MIPI_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param h22_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 500, + .exp_line_end = 13664, + .exp_change_interval = 4, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 2, + .gain_end = 256, + .gain_change_interval = 4, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 100, + .isp_exp_line = 10000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 44, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param h22_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1488, + .fno = 20, + .ae_table_preview_length = 4, + .ae_table_preview = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 3000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 4, + .ae_table_capture = { + 24000, 50, 256, 256, + 50, 50, 256, 512, + 50, 30, 512, 512, + 30, 30, 512, 3000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1024, + 50, 30, 1024, 1024, + 30, 30, 1024, 3000, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 12, + .ae_capture_speed = 12, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 1, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 2, + .awb_speed = 16, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 18, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 35, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 35, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 35, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 35, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 40, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 40, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 30, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 30, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 30, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 40, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 40, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 30, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 30, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 30, 8000, 128, 100, + 243, 256, 215, 256, 256, 256, 40, 6000, 128, 100, + 220, 256, 255, 256, 256, 256, 30, 6700, 128, 100, + 232, 256, 236, 256, 256, 256, 40, 6600, 128, 100, + 275, 256, 197, 256, 256, 256, 40, 4150, 128, 100, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param h22_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 1, 28, 900, }, { 0, 255, 5, }, { 1, 9, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 24, 2, 18, }, 6, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 2, 28, 700, }, { 1, 255, 5, }, { 2, 12, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 24, 4, 20, }, 10, 120, 0, + { 2, 12, 2, 200, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 2, 24, 600, }, { 2, 255, 5, }, { 3, 16, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 12, { 32, 20, 6, 32, }, 14, 108, 5, + { 2, 12, 2, 200, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 4, 16, 512, }, { 3, 255, 5, }, { 4, 20, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, -2, { 32, 18, 12, 32, }, 40, 80, 10, + { 2, 12, 2, 200, }, { 10, 0, }, { 32, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 5, 12, 450, }, { 4, 255, 6, }, { 5, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -2, -2, }, -12, { 32, 18, 16, 32, }, 30, 30, 20, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 6, 12, 400, }, { 5, 255, 7, }, { 6, 24, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -20, 2, }, -16, { 32, 18, 16, 32, }, 32, 8, 30, + { 2, 12, 2, 200, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param h22_mipi_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 85, + .ver_visual_angle = 46, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 344, 256, 256, 348, -62, -46, -46, -62, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 308, 0, -52, }, { -102, 369, -11, }, { -81, -297, 634, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 397, -111, -30, }, { -92, 356, -8, }, { -31, -263, 550, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 430, -155, -19, }, { -107, 418, -55, }, { -26, -235, 517, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 13107, 12342, 12588, 13362, 2608, 13107, 13621, 12588, 13362, 2608, 13107, 12341, + 12588, 13362, 2608, 13107, 13620, 12588, 13362, 2608, 13107, 12340, 12588, 13362, 2608, 13107, 13619, 12588, + 13362, 2608, 13107, 12339, 12588, 13362, 2608, 13107, 13618, 12588, 13362, 2608, 13107, 12338, 12588, 13362, + 2608, 13107, 13617, 12588, 13362, 2608, 13107, 12593, 12588, 13362, 2608, 13107, 13872, 12588, 13362, 2608, + 13107, 12592, 12588, 13362, 2608, 12851, 13881, 12588, 13362, 2608, 12851, 12857, 12588, 13362, 2608, 12851, + 14136, 12588, 13362, 2608, 12851, 12856, 12588, 13362, 2608, 12851, 14391, 12588, 13362, 2608, 12851, 13111, + 12588, 13362, 2608, 12851, 14646, 12588, 13362, 2608, 12851, 13366, 12588, 13362, 2608, 12851, 12342, 12588, + 13362, 2608, 12851, 13621, 12588, 13362, 2608, 12851, 12341, 12588, 13362, 2608, 12851, 13876, 12588, 13362, + 2608, 12851, 12852, 12588, 13362, 2608, 12851, 14131, 12588, 13362, 2608, 12851, 13107, 12588, 13362, 2608, + 12851, 12851, 12588, 13362, 2608, 12851, 12595, 12588, 13362, 2608, 12851, 12339, 12588, 13362, 2608, 12851, + 14642, 12588, 13362, 2608, 12851, 14386, 12588, 13362, 2608, 12851, 14130, 12588, 13362, 2608, 12851, 13874, + 12588, 13362, 2608, 12851, 13618, 12588, 13362, 2608, 12851, 13362, 12588, 13362, 2608, 12851, 13106, 12588, + 13362, 2608, 12851, 12850, 12588, 13362, 2608, 12851, 12594, 12588, 13362, 2608, 12851, 12338, 12588, 13362, + 2608, 12851, 14641, 12588, 13362, 2608, 12851, 14385, 12588, 13362, 2608, 12851, 14129, 12588, 13362, 2608, + 12851, 13873, 12588, 13362, 2608, 12851, 13617, 12588, 13362, 2608, 12851, 13361, 12588, 13362, 2608, 12851, + 13105, 12588, 13362, 2608, 12851, 12849, 12588, 13362, 2608, 12851, 12593, 12588, 13362, 2608, 12851, 12337, + 12588, 13362, 2608, 12851, 14640, 12588, 13362, 2608, 12851, 14384, 12588, 13362, 2608, 12851, 14128, 12588, + 13362, 2608, 12851, 13872, 12588, 13362, 2608, 12851, 13616, 12588, 13362, 2608, 12851, 13360, 12588, 13362, + 2608, 12851, 13104, 12588, 13362, 2608, 12851, 12848, 12588, 13362, 2608, 12851, 12592, 12588, 13362, 2608, + 12851, 12336, 12588, 13362, 2608, 12595, 14649, 12588, 13362, 2608, 12595, 14393, 12588, 13362, 2608, 12595, + 14137, 12588, 13362, 2608, 12595, 13881, 12588, 13362, 2608, 12595, 13625, 12588, 13362, 2608, 12595, 13369, + 12588, 13362, 2608, 12595, 13113, 12588, 13362, 2608, 12595, 12857, 12588, 13362, 2608, 12595, 12601, 12588, + 13362, 2608, 12595, 12345, 12588, 13362, 2608, 12595, 14648, 12588, 13362, 2608, 12595, 14392, 12588, 13362, + 2608, 12595, 14136, 12588, 13362, 2608, 12595, 13880, 12588, 13362, 2608, 12595, 13624, 12588, 13362, 2608, + 12595, 13368, 12588, 13362, 2608, 12595, 13112, 12588, 13362, 2608, 12595, 12856, 12588, 13362, 2608, 12595, + 12600, 12588, 13362, 2608, 12595, 12344, 12588, 13362, 2608, 12595, 14647, 12588, 13362, 2608, 12595, 14391, + 12588, 13362, 2608, 12595, 14135, 12588, 13362, 2608, 12595, 13879, 12588, 13362, 2608, 12595, 13623, 12588, + 13362, 2608, 12595, 13367, 12588, 13362, 2608, 12595, 13111, 12588, 13362, 2608, 12595, 12855, 12588, 13362, + 2608, 12595, 12599, 12588, 13362, 2608, 12595, 12343, 12588, 13362, 2608, 12595, 14646, 12588, 13362, 2608, + 12595, 14390, 12588, 13362, 2608, 12595, 14134, 12588, 13362, 2608, 12595, 13878, 12588, 13362, 2608, 12595, + 13622, 12588, 13362, 2608, 12595, 13366, 12588, 13362, 2608, 12595, 13110, 12588, 13362, 2608, 12595, 12854, + 12588, 13362, 2608, 12595, 12598, 12588, 13362, 2608, 12595, 12342, 12588, 13362, 2608, 12595, 14645, 12588, + 13362, 2608, 12595, 14389, 12588, 13362, 2608, 12595, 14133, 12588, 13362, 2608, 12595, 13877, 12588, 13362, + 2608, 12595, 13621, 12588, 13362, 2608, 12595, 13365, 12588, 13362, 2608, 12595, 13109, 12588, 13362, 2608, + 12595, 12853, 12588, 13362, 2608, 12595, 12597, 12588, 13362, 2608, 12595, 12341, 12588, 13362, 2608, 12595, + 14644, 12588, 13362, 2608, 12595, 14388, 12588, 13362, 2608, 12595, 14132, 12588, 13362, 2608, 12595, 13876, + 12588, 13362, 2608, 12595, 13620, 12588, 13362, 2608, 12595, 13364, 12588, 13362, 2608, 12595, 13108, 12588, + 13362, 2608, 12595, 12852, 12588, 13362, 2608, 12595, 12596, 12588, 13362, 2608, 12595, 12340, 12588, 13362, + 2608, 12595, 14643, 12588, 13362, 2608, 12595, 14387, 12588, 13362, 2608, 12595, 14131, 12588, 13362, 2608, + 12595, 13875, 12588, 13362, 2608, 12595, 13619, 12588, 13362, 2608, 12595, 13363, 12588, 13362, 2608, 12595, + 13107, 12588, 13362, 2608, 12595, 12851, 12588, 13362, 2608, 12595, 12595, 12588, 13362, 2608, 12595, 12339, + 12588, 13362, 2608, 12595, 14642, 12588, 13362, 2608, 12595, 14386, 12588, 13362, 2608, 12595, 14130, 12588, + 13362, 2608, 12595, 13874, 12588, 13362, 2608, 12595, 13618, 12588, 13362, 2608, 12595, 13362, 12588, 13362, + 2608, 12595, 13106, 12588, 13362, 2608, 12595, 12850, 12588, 13362, 2608, 12595, 12594, 12588, 13362, 2608, + 12595, 12338, 12588, 13362, 2608, 12595, 14641, 12588, 13362, 2608, 12595, 14385, 12588, 13362, 2608, 12595, + 14129, 12588, 13362, 2608, 12595, 13873, 12588, 13362, 2608, 12595, 13617, 12588, 13362, 2608, 12595, 13361, + 12588, 13362, 2608, 12595, 13105, 12588, 13362, 2608, 12595, 12849, 12588, 13362, 2608, 12595, 12593, 12588, + 13362, 2608, 12595, 12337, 12588, 13362, 2608, 12595, 14640, 12588, 13362, 2608, 1, 0, 1, 0, + }, + .disc_tbl = { + 4095, 4082, 4072, 4062, 4052, 4043, 4033, 4024, 4014, 4005, 3995, 3986, 3977, 3968, 3959, 3950, + 3941, 3933, 3924, 3915, 3907, 3898, 3890, 3881, 3873, 3865, 3857, 3848, 3840, 3832, 3824, 3817, + 3809, 3801, 3793, 3786, 3778, 3770, 3763, 3755, 3748, 3741, 3733, 3726, 3719, 3712, 3705, 3698, + 3691, 3684, 3677, 3670, 3663, 3656, 3650, 3643, 3636, 3630, 3623, 3617, 3610, 3604, 3597, 3591, + 3585, 3578, 3572, 3566, 3560, 3554, 3547, 3541, 3535, 3529, 3523, 3518, 3512, 3506, 3500, 3494, + 3488, 3483, 3477, 3471, 3466, 3460, 3455, 3449, 3444, 3438, 3433, 3427, 3422, 3417, 3411, 3406, + 3401, 3396, 3390, 3385, 3380, 3375, 3370, 3365, 3360, 3355, 3350, 3345, 3340, 3335, 3330, 3325, + 3320, 3315, 3311, 3306, 3301, 3296, 3292, 3287, 3282, 3278, 3273, 3269, 3264, 3260, 3255, 3250, + 3246, 3242, 3237, 3233, 3232, 3231, 3230, 3229, 3228, 3227, 3226, 3225, 3224, 3223, 3222, 3221, + 3220, 3219, 3218, 3217, 3216, 3215, 3214, 3213, 3212, 3211, 3210, 3209, 3208, 3207, 3206, 3205, + 3204, 3203, 3202, 3201, 3200, 3199, 3198, 3197, 3196, 3195, 3194, 3193, 3192, 3191, 3190, 3189, + 3188, 3187, 3186, 3185, 3184, 3183, 3182, 3181, 3180, 3179, 3178, 3177, 3176, 3175, 3174, 3173, + 3172, 3171, 3170, 3169, 3168, 3167, 3166, 3165, 3164, 3163, 3162, 3161, 3160, 3159, 3158, 3157, + 3156, 3155, 3154, 3153, 3152, 3151, 3150, 3149, 3148, 3147, 3146, 3145, 3144, 3143, 3142, 3141, + 3140, 3139, 3138, 3137, 3136, 3135, 3134, 3133, 3132, 3131, 3130, 3129, 3128, 3127, 3126, 3125, + 3124, 3123, 3122, 3121, 3120, 3119, 3118, 3117, 3116, 3115, 3114, 3113, 3112, 3111, 3110, 3109, + 1024, 1027, 1029, 1032, 1034, 1037, 1039, 1042, 1044, 1047, 1049, 1052, 1054, 1056, 1059, 1061, + 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1087, 1089, 1092, 1094, 1096, 1098, + 1100, 1103, 1105, 1107, 1109, 1112, 1114, 1116, 1118, 1120, 1123, 1125, 1127, 1129, 1131, 1133, + 1136, 1138, 1140, 1142, 1144, 1146, 1148, 1151, 1153, 1155, 1157, 1159, 1161, 1163, 1165, 1167, + 1169, 1171, 1173, 1175, 1177, 1179, 1182, 1184, 1186, 1188, 1190, 1191, 1193, 1196, 1198, 1200, + 1202, 1203, 1206, 1208, 1209, 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1229, 1231, + 1232, 1234, 1236, 1238, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, + }, +}; +struct isp_cfg_pt h22_mipi_isp_cfg = +{ + .isp_test_settings = &h22_mipi_isp_test_settings, + .isp_3a_settings = &h22_mipi_isp_3a_settings, + .isp_tunning_settings = &h22_mipi_isp_tuning_settings, + .isp_iso_settings = &h22_mipi_isp_iso_settings, +}; + + +#endif /* end of _H22_MIPI_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov2710_mipi_isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov2710_mipi_isp_cfg.h new file mode 100755 index 00000000..f76cca2b --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov2710_mipi_isp_cfg.h @@ -0,0 +1,832 @@ + +/* + *************************************************************************************** + * + * ov2710_mipi_isp_cfg.h + * + * Hawkview ISP - ov2710_mipi_isp_cfg.h module + * + * Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com + * + * Version Author Date Description + * + * 3.0 Yang Feng 2015/01/18 ISP Tuning Tools Support + * + **************************************************************************************** + */ + +#ifndef _OV2710_MIPI_ISP_CFG_H_ +#define _OV2710_MIPI_ISP_CFG_H_ + +#include "../isp_cfg.h" +struct isp_test_param ov2710_mipi_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_dbg_level = 0, + .isp_test_exptime = 0, + .exp_line_start = 39520, + .exp_line_step = 16, + .exp_line_end = 39840, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 3, + .isp_test_focus = 0, + .focus_start = 0, + .focus_step = 5, + .focus_end = 800, + .focus_change_interval = 10, + .isp_focus_len = 100, + .isp_gain = 256, + .isp_exp_line = 16000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 44, + .sprite_en = 0, + .af_en = 0, + .ae_en = 1, + .awb_en = 1, + .lsc_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ov2710_mipi_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_min_frame_rate = 30, + .ae_max_lv = 1488, + .fno = 20, + .ae_table_preview_length = 6, + .ae_table_preview = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 6, + .ae_table_capture = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_table_video_length = 6, + .ae_table_video = { + 24000, 100, 256, 256, + 100, 100, 256, 512, + 100, 50, 512, 512, + 50, 50, 512, 1400, + 50, 30, 1400, 1400, + 30, 30, 1400, 4000, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .exp_delay_frame = 2, + .gain_delay_frame = 1, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .ae_hist_mod_en = 0, + .ae_capture_speed = 6, + .ae_video_speed = 6, + .ae_tolerance = 4, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .awb_interval = 4, + .awb_speed = 8, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 7500, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 18, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 35, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 35, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 35, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 35, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 40, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 40, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 30, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 30, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 30, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 40, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 40, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 30, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 30, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 30, 8000, 128, 100, + 243, 256, 215, 256, 256, 256, 40, 6000, 128, 100, + 220, 256, 255, 256, 256, 256, 30, 6700, 128, 100, + 232, 256, 236, 256, 256, 256, 40, 6600, 128, 100, + 275, 256, 197, 256, 256, 256, 40, 4150, 128, 100, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 151, 405, 210, 340, 210, 340, + 145, 480, 265, 256, 256, 256, 285, 245, 280, 235, + 140, 480,}, + .vcm_min_code = 20, + .vcm_max_code = 650, +}; +struct isp_iso_param ov2710_mipi_isp_iso_settings = +{ + .isp_iso_100_cfg = + { + {2,32,768,},{0,255,5,},{1,6,128,},{15,4,0,0,0,15,4,1,0,0,0,0,},{5,-5,},30,{32,24,2,18,},6,112,0,{2,12,2,200,},{0,0,},{4,64,},{0,0,} + }, + .isp_iso_200_cfg = + { + {2,32,768,},{0,255,5,},{1,6,256,},{15,3,0,0,0,15,3,1,0,0,0,0,},{5,-5,},30,{32,24,4,20,},10,112,0,{2,12,2,200,},{0,0,},{4,64,},{0,0,} + }, + .isp_iso_400_cfg = + { + {3,32,768,},{0,255,5,},{2,8,256,},{12,4,0,0,0,12,4,1,0,0,0,0,},{5,-5,},15,{32,20,6,32,},14,108,5,{2,12,2,200,},{1,0,},{8,48,},{0,0,} + }, + .isp_iso_800_cfg = + { + {2,42,400,},{0,255,5,},{3,9,256,},{12,6,0,0,0,12,4,2,0,0,0,0,},{5,-5,},10,{32,18,12,32,},40,90,10,{2,12,2,200,},{4,0,},{32,32,},{0,0,} + }, + .isp_iso_1600_cfg = + { + {4,16,768,},{8,255,7,},{3,20,256,},{12,6,0,0,0,12,6,4,2,0,0,0,},{-5,0,},2,{32,18,16,32,},30,44,20,{2,12,2,200,},{8,0,},{64,16,},{0,0,} + }, + .isp_iso_3200_cfg = + { + {6,16,512,},{10,255,7,},{4,20,256,},{12,6,0,0,0,12,6,4,2,0,0,0,},{-15,0,},-10,{32,18,16,32,},32,16,16,{2,12,2,200,},{10,0,},{64,16,},{0,0,} + }, +}; +struct isp_tunning_param ov2710_mipi_isp_tuning_settings = +{ + .front_camera = 0, + .flicker_type = 1, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .defog_value = 0, + .gamma_num = 5, + .hor_visual_angle = 120, + .ver_visual_angle = 66, + .focus_length = 300, + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .bayer_gain_offset = { 393, 256, 256, 440, -74, -48, -48, -83,}, + .lsc_mod = 1, + .lsc_center = { 2048, 2048,}, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024,}, + .color_matrix_ini[0] = { + .matrix = {{377, -86, -35,},{ -74, 390, -60,},{ -11, -252, 519,}}, + .offset = { 0, 0, 0,}, + }, + .color_matrix_ini[1] = { + .matrix = {{377, -86, -35,},{ -74, 390, -60,},{ -11, -252, 519,}}, + .offset = { 0, 0, 0,}, + }, + .color_matrix_ini[2] = { + .matrix = {{371, -114, -1,},{ -44, 403, -103,},{ 0, -224, 480,}}, + .offset = { 0, 0, 0,}, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*2*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*3*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + }, + { + /*6*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + { + /*7*/ + 1024, 1026, 1028, 1030, 1032, 1035, 1037, 1039, 1041, 1044, 1046, 1048, 1050, 1053, 1055, 1057, + 1059, 1062, 1064, 1066, 1068, 1071, 1073, 1075, 1077, 1080, 1082, 1084, 1086, 1088, 1091, 1093, + 1095, 1097, 1100, 1102, 1104, 1106, 1109, 1111, 1113, 1115, 1118, 1120, 1122, 1124, 1127, 1129, + 1131, 1133, 1136, 1138, 1140, 1142, 1144, 1147, 1149, 1151, 1153, 1156, 1158, 1160, 1162, 1165, + 1167, 1169, 1171, 1174, 1176, 1178, 1180, 1183, 1185, 1187, 1189, 1192, 1194, 1196, 1198, 1200, + 1203, 1205, 1207, 1209, 1212, 1214, 1216, 1218, 1221, 1223, 1225, 1227, 1230, 1232, 1234, 1236, + 1239, 1241, 1243, 1245, 1248, 1250, 1252, 1254, 1256, 1259, 1261, 1263, 1265, 1268, 1270, 1272, + 1274, 1277, 1279, 1281, 1283, 1286, 1288, 1290, 1292, 1295, 1297, 1299, 1301, 1304, 1306, 1308, + 1310, 1312, 1315, 1317, 1319, 1321, 1324, 1326, 1328, 1330, 1333, 1335, 1337, 1339, 1342, 1344, + 1346, 1348, 1351, 1353, 1355, 1357, 1360, 1362, 1364, 1366, 1368, 1371, 1373, 1375, 1377, 1380, + 1382, 1384, 1386, 1389, 1391, 1393, 1395, 1398, 1400, 1402, 1404, 1407, 1409, 1411, 1413, 1416, + 1418, 1420, 1422, 1424, 1427, 1429, 1431, 1433, 1436, 1438, 1440, 1442, 1445, 1447, 1449, 1451, + 1454, 1456, 1458, 1460, 1463, 1465, 1467, 1469, 1472, 1474, 1476, 1478, 1480, 1483, 1485, 1487, + 1489, 1492, 1494, 1496, 1498, 1501, 1503, 1505, 1507, 1510, 1512, 1514, 1516, 1519, 1521, 1523, + 1525, 1528, 1530, 1532, 1534, 1536, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1557, 1559, + 1561, 1563, 1566, 1568, 1570, 1572, 1575, 1577, 1579, 1581, 1584, 1586, 1588, 1590, 1592, 1595, + 1024, 1025, 1026, 1027, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, + 1045, 1046, 1047, 1049, 1050, 1051, 1053, 1054, 1055, 1057, 1058, 1059, 1060, 1062, 1063, 1064, + 1066, 1067, 1068, 1070, 1071, 1072, 1074, 1075, 1076, 1078, 1079, 1080, 1082, 1083, 1084, 1086, + 1087, 1088, 1090, 1091, 1092, 1093, 1095, 1096, 1097, 1099, 1100, 1101, 1103, 1104, 1105, 1107, + 1108, 1109, 1111, 1112, 1113, 1115, 1116, 1117, 1119, 1120, 1121, 1123, 1124, 1125, 1126, 1128, + 1129, 1130, 1132, 1133, 1134, 1136, 1137, 1138, 1140, 1141, 1142, 1144, 1145, 1146, 1148, 1149, + 1150, 1152, 1153, 1154, 1156, 1157, 1158, 1159, 1161, 1162, 1163, 1165, 1166, 1167, 1169, 1170, + 1171, 1173, 1174, 1175, 1177, 1178, 1179, 1181, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1191, + 1192, 1194, 1195, 1196, 1198, 1199, 1200, 1202, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, + 1214, 1215, 1216, 1218, 1219, 1220, 1222, 1223, 1224, 1225, 1227, 1228, 1229, 1231, 1232, 1233, + 1235, 1236, 1237, 1239, 1240, 1241, 1243, 1244, 1245, 1247, 1248, 1249, 1251, 1252, 1253, 1255, + 1256, 1257, 1258, 1260, 1261, 1262, 1264, 1265, 1266, 1268, 1269, 1270, 1272, 1273, 1274, 1276, + 1277, 1278, 1280, 1281, 1282, 1284, 1285, 1286, 1288, 1289, 1290, 1291, 1293, 1294, 1295, 1297, + 1298, 1299, 1301, 1302, 1303, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1315, 1317, 1318, + 1319, 1321, 1322, 1323, 1324, 1326, 1327, 1328, 1330, 1331, 1332, 1334, 1335, 1336, 1338, 1339, + 1340, 1342, 1343, 1344, 1346, 1347, 1348, 1350, 1351, 1352, 1354, 1355, 1356, 1357, 1359, 1360, + 1024, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1070, 1071, 1072, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1096, 1097, 1098, 1099, + 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, + 1116, 1117, 1118, 1119, 1120, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, + 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1144, 1145, + 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1216, 1217, 1218, 1219, 1220, 1221, 1222, + 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, + }, + }, + .linear_tbl = { + 376, 286, 376, 286, 2612, 12340, 12343, 12588, 13104, 2608, 12340, 12597, 12588, 13104, 2613, 12340, + 12851, 12588, 13360, 2608, 12340, 13105, 12588, 13360, 2612, 14643, 13625, 12588, 13360, 2617, 14643, 14135, + 12588, 13616, 2612, 14643, 14645, 12588, 13616, 2617, 14643, 12596, 12588, 13872, 2612, 14643, 13362, 12588, + 13872, 2616, 14643, 14128, 12588, 14128, 2611, 14387, 12601, 12588, 14128, 2615, 14387, 13367, 12588, 14384, + 2610, 14387, 14389, 12588, 14384, 2614, 14387, 12852, 12588, 14640, 2609, 14387, 13874, 12588, 14640, 2613, + 14387, 12593, 12588, 12337, 2608, 14131, 13881, 12588, 12337, 2612, 14131, 12344, 12588, 12337, 2617, 14131, + 13878, 12588, 12593, 2611, 14131, 12597, 12588, 12593, 2615, 14131, 14131, 12588, 12849, 2610, 14131, 12850, + 12588, 12849, 2614, 14131, 14384, 12588, 13105, 2608, 13875, 13369, 12588, 13105, 2613, 13875, 12600, 12588, + 13105, 2617, 13875, 14134, 12588, 13361, 2611, 13875, 13365, 12588, 13361, 2615, 13875, 12596, 12588, 13617, + 2609, 13875, 14386, 12588, 13617, 2613, 13875, 13617, 12588, 13617, 2617, 13875, 12848, 12588, 13873, 2612, + 13619, 12345, 12588, 13873, 2616, 13619, 14135, 12588, 14129, 2610, 13619, 13622, 12588, 14129, 2614, 13619, + 13109, 12588, 14385, 2608, 13619, 12596, 12588, 14385, 2612, 13619, 14642, 12588, 14385, 2616, 13619, 14129, + 12588, 14641, 2610, 13619, 13872, 12588, 14641, 2614, 13363, 13369, 12588, 12338, 2608, 13363, 13112, 12588, + 12338, 2611, 13363, 12855, 12588, 12338, 2615, 13363, 12598, 12588, 12594, 2609, 13363, 12341, 12588, 12594, + 2613, 13363, 14643, 12588, 12594, 2617, 13363, 14642, 12588, 12850, 2610, 13363, 14385, 12588, 12850, 2614, + 13363, 14384, 12588, 13106, 2608, 13107, 14137, 12588, 13106, 2612, 13107, 14136, 12588, 13106, 2616, 13107, + 14135, 12588, 13362, 2609, 13107, 14134, 12588, 13362, 2613, 13107, 14133, 12588, 13362, 2617, 13107, 14132, + 12588, 13618, 2610, 13107, 14131, 12588, 13618, 2614, 13107, 14386, 12588, 13874, 2608, 13107, 14385, 12588, + 13874, 2611, 13107, 14640, 12588, 13874, 2615, 12851, 14649, 12588, 14130, 2609, 12851, 12345, 12588, 14130, + 2612, 12851, 12600, 12588, 14130, 2616, 12851, 12855, 12588, 14386, 2609, 12851, 13110, 12588, 14386, 2613, + 12851, 13365, 12588, 14386, 2616, 12851, 13620, 12588, 14642, 2610, 12851, 13875, 12588, 14642, 2613, 12851, + 14386, 12588, 14642, 2617, 12851, 14641, 12588, 12339, 2610, 12851, 12593, 12588, 12339, 2613, 12851, 12848, + 12588, 12339, 2617, 12595, 13369, 12588, 12595, 2610, 12595, 13880, 12588, 12595, 2614, 12595, 14135, 12588, + 12595, 2617, 12595, 14646, 12588, 12851, 2611, 12595, 12598, 12588, 12851, 2614, 12595, 13109, 12588, 12851, + 2617, 12595, 13620, 12588, 13107, 2611, 12595, 14387, 12588, 13107, 2614, 12595, 12339, 12588, 13107, 2617, + 12595, 12850, 12588, 13363, 2611, 12595, 13361, 12588, 13363, 2614, 12595, 14128, 12588, 13363, 2617, 12339, + 14649, 12588, 13619, 2611, 12339, 12857, 12588, 13619, 2614, 12339, 13368, 12588, 13619, 2617, 12339, 14135, + 12588, 13875, 2610, 12339, 12343, 12588, 13875, 2613, 12339, 12854, 12588, 13875, 2617, 12339, 13621, 12588, + 14131, 2610, 12339, 14388, 12588, 14131, 2613, 12339, 12596, 12588, 14131, 2616, 12339, 13363, 12588, 14387, + 2610, 12339, 14130, 12588, 14387, 2613, 12339, 12338, 12588, 14387, 2616, 12339, 13105, 12588, 14643, 2609, + 12339, 14128, 12588, 14643, 2612, 12339, 12336, 12588, 14643, 2615, 14642, 13113, 12588, 12340, 2609, 14642, + 14136, 12588, 12340, 2611, 14642, 12344, 12588, 12340, 2615, 14642, 13111, 12588, 12596, 2608, 14642, 14134, + 12588, 12596, 2611, 14642, 12598, 12588, 12596, 2614, 14642, 13365, 12588, 12596, 2617, 14642, 14388, 12588, + 12852, 2610, 14642, 12596, 12588, 12852, 2613, 14642, 13619, 12588, 12852, 2616, 14642, 14642, 12588, 13108, + 2609, 14642, 13106, 12588, 13108, 2612, 14642, 14129, 12588, 13108, 2615, 14642, 12593, 12588, 13364, 2608, + 14642, 13616, 12588, 13364, 2611, 14386, 14649, 12588, 13364, 2611, 14386, 13113, 12588, 13364, 2611, 14386, + 14136, 12588, 13364, 2611, 14386, 12600, 12588, 13364, 2611, 14386, 13623, 12588, 13364, 2611, 14386, 14646, + 12588, 13364, 2611, 14386, 13110, 12588, 13364, 2611, 14386, 14389, 12588, 13364, 2611, 14386, 12853, 12588, + 13364, 2611, 14386, 13876, 12588, 13364, 2611, 14386, 12596, 12588, 13364, 2611, 14386, 13619, 12588, 13364, + 2611, 14386, 12339, 12588, 13364, 2611, 14386, 13362, 12588, 13364, 2611, 14386, 14641, 12588, 13364, 2611, + 14386, 13105, 12588, 13364, 2611, 14386, 14384, 12588, 13364, 2611, 14386, 13104, 12588, 13364, 2611, 14130, + 14137, 12588, 13364, 2611, 14130, 12857, 12588, 13364, 2611, 14130, 14136, 12588, 13364, 2611, 14130, 12856, + 12588, 13364, 2611, 14130, 13879, 12588, 13364, 2611, 14130, 12599, 12588, 13364, 2611, 14130, 13878, 12588, + 13364, 2611, 14130, 12598, 12588, 13364, 2611, 14130, 13877, 12588, 13364, 2611, 14130, 12597, 12588, 13364, + 2611, 14130, 13876, 12588, 13364, 2611, 14130, 12596, 12588, 13364, 2611, 14130, 13875, 12588, 13364, 2611, + 14130, 12595, 12588, 13364, 2611, 14130, 13874, 12588, 13364, 2611, 14130, 12594, 12588, 13364, 2611, 14130, + 14129, 12588, 13364, 2611, 14130, 13105, 12588, 13364, 2611, 14130, 12849, 12588, 13364, 2611, 14130, 12593, + 12588, 13364, 2611, 14130, 12337, 12588, 13364, 2611, 14130, 14640, 12588, 13364, 2611, 14130, 14384, 12588, + }, + .disc_tbl = { + 4095, 4070, 4051, 4032, 4013, 3995, 3977, 3959, 3941, 3924, 3907, 3891, 3874, 3858, 3842, 3826, + 3811, 3796, 3780, 3766, 3751, 3737, 3722, 3708, 3694, 3681, 3667, 3654, 3641, 3628, 3615, 3602, + 3590, 3577, 3565, 3553, 3541, 3529, 3517, 3506, 3494, 3483, 3472, 3461, 3450, 3439, 3429, 3418, + 3408, 3397, 3387, 3377, 3367, 3357, 3347, 3337, 3328, 3318, 3309, 3299, 3290, 3281, 3272, 3263, + 3254, 3245, 3236, 3228, 3219, 3211, 3202, 3194, 3186, 3177, 3169, 3161, 3153, 3145, 3138, 3130, + 3122, 3114, 3107, 3099, 3092, 3084, 3077, 3070, 3062, 3055, 3048, 3041, 3034, 3027, 3020, 3013, + 3007, 3000, 2993, 2987, 2980, 2973, 2967, 2961, 2954, 2948, 2941, 2935, 2929, 2923, 2917, 2911, + 2905, 2899, 2893, 2887, 2881, 2875, 2869, 2863, 2858, 2852, 2846, 2841, 2835, 2830, 2824, 2819, + 2813, 2808, 2803, 2797, 2792, 2787, 2782, 2776, 2771, 2766, 2761, 2756, 2751, 2746, 2741, 2736, + 2731, 2726, 2721, 2717, 2713, 2712, 2711, 2710, 2709, 2708, 2707, 2706, 2705, 2704, 2703, 2702, + 2701, 2700, 2699, 2698, 2697, 2696, 2695, 2694, 2693, 2692, 2691, 2690, 2689, 2688, 2687, 2686, + 2685, 2684, 2683, 2682, 2681, 2680, 2679, 2678, 2677, 2676, 2675, 2674, 2673, 2672, 2671, 2670, + 2669, 2668, 2667, 2666, 2665, 2664, 2663, 2662, 2661, 2660, 2659, 2658, 2657, 2656, 2655, 2654, + 2653, 2652, 2651, 2650, 2649, 2648, 2647, 2646, 2645, 2644, 2643, 2642, 2641, 2640, 2639, 2638, + 2637, 2636, 2635, 2634, 2633, 2632, 2631, 2630, 2629, 2628, 2627, 2626, 2625, 2624, 2623, 2622, + 2621, 2620, 2619, 2618, 2617, 2616, 2615, 2614, 2613, 2612, 2611, 2610, 2609, 2608, 2607, 2606, + 1024, 1030, 1035, 1040, 1044, 1049, 1054, 1059, 1064, 1068, 1073, 1077, 1082, 1086, 1091, 1095, + 1100, 1104, 1109, 1113, 1117, 1122, 1126, 1130, 1135, 1139, 1143, 1147, 1151, 1155, 1159, 1164, + 1168, 1172, 1176, 1180, 1184, 1188, 1192, 1196, 1200, 1203, 1207, 1211, 1215, 1219, 1222, 1226, + 1230, 1234, 1238, 1241, 1245, 1249, 1252, 1256, 1260, 1263, 1267, 1271, 1274, 1278, 1281, 1285, + 1288, 1292, 1295, 1299, 1302, 1305, 1309, 1312, 1316, 1319, 1323, 1326, 1329, 1333, 1336, 1339, + 1343, 1346, 1349, 1353, 1356, 1359, 1362, 1365, 1369, 1372, 1375, 1378, 1382, 1385, 1388, 1391, + 1394, 1397, 1401, 1403, 1407, 1410, 1413, 1416, 1419, 1422, 1425, 1428, 1431, 1434, 1437, 1440, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + }, + +}; + +struct isp_cfg_pt ov2710_mipi_isp_cfg = +{ + .isp_test_settings = &ov2710_mipi_isp_test_settings, + .isp_3a_settings = &ov2710_mipi_isp_3a_settings, + .isp_tunning_settings = &ov2710_mipi_isp_tuning_settings, + .isp_iso_settings = &ov2710_mipi_isp_iso_settings, +}; + +#endif /*_OV2710_MIPI_ISP_CFG_H_*/ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_isp_cfg.h new file mode 100755 index 00000000..fbd68e97 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_isp_cfg.h @@ -0,0 +1,845 @@ +/* +****************************************************************************************** +* +* ov4689_isp_cfg.h +* +* Hawkview ISP - ov4689_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/24 Automatic generation. +* +****************************************************************************************** +*/ + +#ifndef _OV4689_ISP_CFG_H_V100_ +#define _OV4689_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param ov4689_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 1000, + .exp_line_end = 32000, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 5, + .isp_test_focus = 0, + .focus_start = 10, + .focus_step = 10, + .focus_end = 800, + .focus_change_interval = 5, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 128, + .isp_exp_line = 10000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 0, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ov4689_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1650, + .fno = 20, + .ae_table_preview_length = 2, + .ae_table_preview = { + 8000, 30, 256, 256, + 30, 30, 256, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 2, + .ae_table_capture = { + 8000, 30, 256, 256, + 30, 30, 256, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 4, + .ae_table_video = { + 8000, 100, 256, 256, + 100, 100, 256, 512, + 100, 30, 512, 512, + 30, 30, 512, 2000, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 12, + .ae_capture_speed = 12, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 4, + .awb_speed = 8, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 18, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 35, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 35, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 35, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 35, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 40, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 40, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 30, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 30, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 30, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 40, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 40, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 30, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 30, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 30, 8000, 128, 100, + 243, 256, 215, 256, 256, 256, 40, 6000, 128, 100, + 220, 256, 255, 256, 256, 256, 30, 6700, 128, 100, + 232, 256, 236, 256, 256, 256, 40, 6600, 128, 100, + 275, 256, 197, 256, 256, 256, 40, 4150, 128, 100, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 150, + .vcm_max_code = 650, +}; +struct isp_iso_param ov4689_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 0, 32, 1200, }, { 0, 255, 3, }, { 2, 8, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 80, { 32, 24, 2, 18, }, 6, 124, 0, + { 5, 6, 5, 100, }, { 0, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 0, 32, 1024, }, { 1, 255, 3, }, { 2, 8, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 80, { 32, 24, 4, 20, }, 10, 124, 0, + { 5, 6, 5, 100, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 2, 24, 700, }, { 2, 255, 4, }, { 2, 8, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 40, { 32, 20, 6, 32, }, 14, 120, 6, + { 5, 6, 5, 100, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 3, 20, 600, }, { 3, 255, 5, }, { 3, 12, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 18, 12, 32, }, 40, 80, 16, + { 5, 6, 5, 100, }, { 10, 0, }, { 32, 32, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 5, 16, 450, }, { 4, 255, 6, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -5, 2, }, -10, { 32, 18, 16, 32, }, 30, 20, 30, + { 5, 6, 5, 100, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 5, 12, 400, }, { 5, 255, 7, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -10, 5, }, -10, { 32, 18, 16, 32, }, 32, 6, 40, + { 5, 6, 5, 100, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, +}; +struct isp_tunning_param ov4689_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 106, + .ver_visual_angle = 55, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 256, 264, 264, 264, -55, -50, -50, -50, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 338, 0, -82, }, { -111, 439, -72, }, { 0, -267, 523, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 393, -100, -37, }, { -73, 381, -52, }, { 0, -122, 378, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 380, -109, -15, }, { -44, 393, -93, }, { 0, -99, 355, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*2*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*3*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*6*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*7*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + }, + .linear_tbl = { + 44720, 3578, 376, 286, 18247, 19016, 19017, 19275, 19017, 19019, 18506, 17991, 17219, 17732, 17988, 18248, + 18247, 18505, 18500, 16965, 16962, 17731, 16196, 17477, 16961, 17218, 17990, 17728, 17480, 17474, 17733, 17734, + 17733, 17219, 16962, 17220, 17219, 16966, 17218, 17476, 18245, 17478, 16448, 16449, 16702, 16446, 16960, 15936, + 15679, 15931, 16704, 17220, 16449, 15935, 14651, 15676, 16191, 15678, 16188, 15936, 15676, 16961, 14652, 15675, + 15935, 14908, 16187, 16193, 15420, 15933, 16189, 15424, 14393, 14905, 15420, 16189, 16192, 15678, 15420, 15420, + 15421, 15677, 15677, 15934, 15163, 16445, 15935, 16702, 15680, 15935, 15932, 15935, 15933, 15421, 15420, 16959, + 16705, 16192, 16704, 15680, 14906, 15931, 16704, 15167, 15678, 15166, 16189, 16191, 16190, 16448, 16446, 16451, + 15678, 17473, 17218, 15939, 16698, 17217, 16962, 17734, 16706, 16706, 16448, 17217, 17220, 17219, 16705, 16447, + 17731, 16707, 18248, 17220, 17218, 16964, 17730, 18250, 17735, 19017, 17990, 17989, 17990, 17989, 18247, 16709, + 15934, 17727, 17992, 17475, 18502, 18248, 17478, 18244, 19273, 19278, 18505, 18244, 17992, 19271, 18507, 17992, + 18506, 19785, 19277, 18247, 19017, 19786, 20555, 20049, 19021, 17991, 20300, 20302, 20049, 19531, 19277, 18761, + 20043, 20816, 20305, 19020, 20300, 20303, 21074, 21588, 21845, 21075, 20561, 20817, 20303, 20557, 21586, 21077, + 22611, 18769, 21070, 20815, 20046, 21584, 22359, 22614, 21847, 22614, 22874, 22612, 23130, 22618, 21332, 22100, + 23384, 23126, 23132, 21844, 22870, 21850, 22101, 21845, 22359, 23387, 21848, 20047, 21071, 20822, 20815, 20560, + 20561, 19790, 19791, 21846, 22615, 22101, 23643, 24156, 24671, 24420, 24156, 24416, 24157, 24928, 24157, 24418, + 25184, 25442, 24930, 22109, 23385, 25187, 24418, 25693, 24415, 24415, 24157, 24928, 25188, 24672, 24416, 25698, + 25185, 25697, 25442, 24418, 23647, 24675, 24162, 25189, 25699, 26214, 24418, 24672, 24928, 22875, 24157, 24156, + 24928, 24162, 22877, 23127, 22876, 23132, 22873, 23644, 23644, 23642, 23135, 22870, 17222, 17219, 17218, 18503, + 18503, 16195, 19531, 17733, 19529, 19012, 19789, 20304, 19276, 19016, 18507, 20303, 18506, 20816, 18758, 19529, + 20301, 21065, 20811, 21845, 19538, 20301, 21844, 20562, 22355, 20564, 21584, 22612, 22107, 19283, 20300, 21330, + 21586, 20817, 21332, 21075, 21587, 21076, 22101, 22873, 21849, 21075, 22102, 21845, 21075, 21073, 21844, 20820, + 21073, 21074, 21587, 20819, 20560, 19791, 21587, 21075, 20305, 19021, 19786, 19020, 20301, 18506, 18759, 18249, + 18247, 17991, 17730, 16701, 18500, 17476, 17221, 18244, 19530, 21072, 21332, 20562, 20556, 20045, 19792, 20301, + 20561, 19534, 20299, 19783, 19791, 20044, 20046, 19789, 18508, 18504, 19532, 20045, 20816, 19790, 21841, 20048, + 20559, 20047, 20559, 20048, 19788, 19787, 20815, 18765, 19788, 18763, 19788, 19532, 20045, 20558, 19536, 19275, + 18761, 18761, 19018, 19788, 19018, 19788, 18247, 17991, 19015, 19275, 17993, 17734, 16962, 18503, 17734, 17990, + 18248, 17990, 17733, 17220, 16449, 17476, 16707, 17474, 16707, 16960, 16965, 17218, 17736, 17218, 17219, 17990, + 17992, 17475, 17477, 17732, 17733, 18505, 17221, 16962, 19013, 17481, 16961, 16706, 16962, 16705, 17218, 16963, + 17730, 17219, 15939, 17985, 16710, 15421, 15164, 15934, 16448, 15678, 16700, 16450, 16704, 16449, 15678, 15933, + 15935, 15164, 16445, 15680, 15418, 16190, 16191, 15935, 15163, 15421, 15675, 15672, 16958, 16192, 14910, 16191, + 15423, 15933, 16190, 16961, 15422, 16188, 15936, 16445, 15424, 16190, 16447, 16706, 16192, 16961, 16707, 16191, + 16705, 15936, 16959, 17220, 15935, 16703, 16448, 16193, 16190, 16449, 16447, 16448, 16447, 16448, 16960, 16194, + 15164, 17729, 16962, 17476, 16450, 16448, 17472, 17991, 17219, 18248, 16965, 18245, 17992, 16449, 16962, 17218, + 18244, 19017, 18249, 17223, 17474, 17734, 18758, 17990, 18246, 18760, 17992, 18244, 18248, 18758, 17993, 17989, + 18247, 18503, 19016, 17736, 17990, 18245, 18504, 18504, 19528, 19533, 18249, 17732, 19529, 19277, 18762, 19784, + 19533, 19788, 19278, 19274, 19532, 20303, 20303, 19793, 19019, 19530, 20814, 20561, 20047, 20046, 19276, 18507, + 21581, 20823, 20560, 20303, 20816, 20816, 20305, 21844, 22357, 21334, 20818, 20817, 20048, 20812, 21331, 21843, + 22871, 22105, 21588, 21335, 21586, 20816, 22613, 22618, 23384, 22105, 21588, 22362, 23383, 22363, 22102, 22101, + 23128, 23130, 22105, 22357, 23126, 22619, 22872, 22360, 22615, 22874, 21336, 19790, 21328, 21845, 20562, 20817, + 22358, 20818, 21072, 22614, 22616, 23384, 24414, 24159, 24928, 23905, 24924, 24416, 24928, 25444, 24158, 25188, + 25954, 26983, 23649, 28252, 24430, 25184, 24416, 26719, 25444, 25187, 26468, 27498, 26215, 24675, 26209, 25960, + 25956, 25700, 27233, 25959, 24672, 25957, 24413, 25698, 25440, 24676, 24932, 26209, 26216, 23389, 24669, 24159, + 24412, 24417, 22619, 23642, 23901, 23902, 24412, 23395, 22869, 24155, 24671, 22622, 16704, 16195, 18243, 19016, + 18506, 17730, 18762, 17989, 18246, 19274, 20558, 19277, 19788, 19017, 19275, 19531, 19786, 19273, 19276, 20556, + 20043, 19790, 20299, 21589, 20305, 21587, 21590, 21587, 20048, 20559, 21332, 21844, 19795, 19788, 20816, 21073, + 19793, 19533, 19788, 20303, 21329, 22357, 21333, 21587, 21589, 21076, 21330, 21587, 21075, 21328, 22101, 21845, + 20820, 21074, 22359, 20563, 20303, 20558, 22100, 21076, 20559, 20049, 19533, 17480, 19272, 18762, 18504, 18761, + 17991, 18246, 19271, 17995, 17989, 18246, 18504, 18760, 20043, 21074, 21586, 20558, 20556, 20816, 20561, 20049, + }, + .disc_tbl = { + 4095, 4086, 4079, 4072, 4065, 4058, 4051, 4044, 4037, 4031, 4024, 4017, 4011, 4004, 3998, 3991, + 3985, 3978, 3972, 3966, 3959, 3953, 3947, 3941, 3935, 3928, 3922, 3916, 3910, 3904, 3898, 3892, + 3886, 3881, 3875, 3869, 3863, 3857, 3852, 3846, 3840, 3835, 3829, 3824, 3818, 3813, 3807, 3802, + 3796, 3791, 3785, 3780, 3775, 3769, 3764, 3759, 3754, 3748, 3743, 3738, 3733, 3728, 3723, 3718, + 3713, 3708, 3703, 3698, 3693, 3688, 3683, 3678, 3674, 3669, 3664, 3659, 3655, 3650, 3645, 3640, + 3636, 3631, 3627, 3622, 3617, 3613, 3608, 3604, 3599, 3595, 3590, 3586, 3581, 3577, 3573, 3568, + 3564, 3560, 3555, 3551, 3547, 3542, 3538, 3534, 3530, 3526, 3521, 3517, 3513, 3509, 3505, 3501, + 3497, 3493, 3489, 3485, 3481, 3477, 3473, 3469, 3465, 3461, 3457, 3453, 3449, 3446, 3442, 3438, + 3434, 3430, 3426, 3423, 3419, 3415, 3411, 3408, 3404, 3400, 3397, 3393, 3389, 3386, 3382, 3378, + 3375, 3371, 3368, 3364, 3361, 3357, 3354, 3350, 3347, 3343, 3340, 3336, 3333, 3329, 3326, 3323, + 3319, 3316, 3312, 3309, 3306, 3302, 3299, 3296, 3292, 3289, 3286, 3283, 3279, 3276, 3273, 3270, + 3266, 3263, 3260, 3257, 3254, 3251, 3247, 3244, 3241, 3238, 3235, 3232, 3229, 3226, 3223, 3220, + 3217, 3214, 3210, 3207, 3204, 3201, 3198, 3195, 3193, 3190, 3187, 3184, 3181, 3178, 3175, 3172, + 3169, 3166, 3163, 3161, 3158, 3155, 3152, 3149, 3146, 3144, 3141, 3138, 3135, 3132, 3130, 3127, + 3124, 3121, 3119, 3116, 3113, 3110, 3108, 3105, 3102, 3100, 3097, 3094, 3092, 3089, 3086, 3084, + 3081, 3079, 3076, 3073, 3071, 3070, 3069, 3068, 3067, 3066, 3065, 3064, 3063, 3062, 3061, 3060, + 1024, 1026, 1028, 1029, 1031, 1033, 1035, 1036, 1038, 1040, 1042, 1043, 1045, 1047, 1048, 1050, + 1052, 1054, 1055, 1057, 1059, 1060, 1062, 1064, 1065, 1067, 1069, 1070, 1072, 1074, 1075, 1077, + 1079, 1080, 1082, 1083, 1085, 1087, 1088, 1090, 1092, 1093, 1095, 1096, 1098, 1099, 1101, 1102, + 1104, 1106, 1107, 1109, 1110, 1112, 1114, 1115, 1117, 1118, 1120, 1121, 1123, 1124, 1126, 1127, + 1129, 1130, 1132, 1133, 1135, 1137, 1138, 1140, 1141, 1142, 1144, 1146, 1147, 1148, 1150, 1152, + 1153, 1154, 1156, 1157, 1159, 1160, 1162, 1163, 1165, 1166, 1168, 1169, 1170, 1172, 1173, 1175, + 1176, 1177, 1179, 1180, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1192, 1193, 1195, 1196, 1197, + 1199, 1200, 1201, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, 1214, 1215, 1216, 1218, 1219, + 1221, 1222, 1223, 1225, 1226, 1227, 1229, 1230, 1231, 1233, 1234, 1235, 1237, 1238, 1239, 1241, + 1242, 1243, 1245, 1246, 1247, 1249, 1250, 1251, 1252, 1254, 1255, 1256, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + }, +}; +struct isp_cfg_pt ov4689_isp_cfg = +{ + .isp_test_settings = &ov4689_isp_test_settings, + .isp_3a_settings = &ov4689_isp_3a_settings, + .isp_tunning_settings = &ov4689_isp_tuning_settings, + .isp_iso_settings = &ov4689_isp_iso_settings, +}; + + +#endif /* end of _OV4689_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_sdv_isp_cfg_HK8189.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_sdv_isp_cfg_HK8189.h new file mode 100755 index 00000000..335a5d18 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/SENSOR_H/ov4689_sdv_isp_cfg_HK8189.h @@ -0,0 +1,847 @@ +/* +****************************************************************************************** +* +* ov4689_sdv_isp_cfg.h +* +* Hawkview ISP - ov4689_sdv_isp_cfg.h module +* +* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com +* +* Version Author Date Description +* +* 1.0 Hawkview Tool 2015/04/30 Automatic generation. +* +****************************************************************************************** +*/ + +// F2.0 HK-8189-596 + +#ifndef _OV4689_SDV_ISP_CFG_H_V100_ +#define _OV4689_SDV_ISP_CFG_H_V100_ + +#include "../isp_cfg.h" + + +struct isp_test_param ov4689_sdv_isp_test_settings = +{ + .isp_test_mode = 0, + .isp_test_exptime = 0, + .exp_line_start = 1000, + .exp_line_step = 1000, + .exp_line_end = 32000, + .exp_change_interval = 5, + .isp_test_gain = 0, + .gain_start = 16, + .gain_step = 1, + .gain_end = 256, + .gain_change_interval = 5, + .isp_test_focus = 0, + .focus_start = 10, + .focus_step = 10, + .focus_end = 800, + .focus_change_interval = 5, + .isp_dbg_level = 0, + .isp_focus_len = 100, + .isp_gain = 128, + .isp_exp_line = 10000, + .isp_color_temp = 6500, + .ae_forced = 0, + .lum_forced = 0, + .sprite_en = 0, + .lsc_en = 1, + .ae_en = 1, + .af_en = 0, + .awb_en = 1, + .drc_en = 1, + .defog_en = 1, + .satur_en = 1, + .tdf_en = 0, + .pri_contrast_en = 1, + .hdr_gamma_en = 0, + .disc_en = 1, + .linear_en = 0, +}; +struct isp_3a_param ov4689_sdv_isp_3a_settings = +{ + .define_ae_table = 1, + .ae_max_lv = 1650, + .fno = 20, + .ae_table_preview_length = 2, + .ae_table_preview = { + 8000, 30, 256, 256, + 30, 30, 256, 2560, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_capture_length = 2, + .ae_table_capture = { + 8000, 30, 256, 256, + 30, 30, 256, 2560, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_table_video_length = 4, + .ae_table_video = { + 8000, 100, 256, 256, + 100, 100, 256, 512, + 100, 30, 512, 512, + 30, 30, 512, 2560, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }, + .ae_win_weight = { + 0, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 4, 4, 2, 2, 2, + 2, 2, 2, 8, 8, 2, 2, 2, + 2, 2, 6, 16, 16, 6, 2, 2, + 2, 6, 12, 20, 20, 12, 6, 2, + 2, 6, 16, 16, 16, 16, 6, 2, + 0, 2, 6, 6, 6, 6, 2, 0, + }, + .ae_window_overexp_weigth = 4, + .ae_hist_overexp_weight = 6, + .ae_video_speed = 12, + .ae_capture_speed = 12, + .ae_tolerance = 4, + .ae_min_frame_rate = 30, + .exp_delay_frame = 2, + .gain_delay_frame = 2, + .exp_comp_step = 7, + .high_quality_mode_en = 0, + .adaptive_frame_rate = 1, + .force_frame_rate = 0, + .awb_interval = 4, + .awb_speed = 8, + .awb_color_temper_low = 1800, + .awb_color_temper_high = 6700, + .awb_light_num = 9, + .awb_light_info = { + 584, 256, 160, 256, 256, 256, 75, 1900, 64, 50, + 549, 256, 165, 256, 256, 256, 75, 2000, 64, 50, + 510, 256, 169, 256, 256, 256, 75, 2100, 64, 55, + 472, 256, 174, 400, 256, 175, 60, 2500, 64, 60, + 401, 256, 188, 320, 256, 220, 40, 2800, 72, 65, + 332, 256, 204, 290, 256, 240, 35, 4000, 96, 75, + 275, 256, 239, 256, 256, 256, 40, 5000, 100, 80, + 250, 256, 273, 256, 256, 256, 35, 6500, 128, 80, + 242, 256, 293, 240, 256, 300, 30, 7500, 64, 20, + }, + .awb_ext_light_num = 18, + .awb_ext_light_info = { + 502, 256, 144, 256, 256, 256, 35, 2125, 128, 100, + 530, 256, 139, 256, 256, 256, 35, 2150, 128, 100, + 449, 256, 153, 256, 256, 256, 35, 2250, 128, 100, + 418, 256, 160, 256, 256, 256, 35, 2350, 128, 100, + 347, 256, 177, 256, 256, 256, 40, 2850, 128, 100, + 481, 256, 149, 256, 256, 256, 40, 2050, 128, 100, + 475, 256, 202, 256, 256, 256, 30, 2150, 128, 100, + 335, 256, 235, 256, 256, 256, 30, 4200, 128, 100, + 213, 256, 276, 256, 256, 256, 30, 7250, 128, 100, + 313, 256, 187, 256, 256, 256, 40, 3550, 128, 100, + 382, 256, 168, 256, 256, 256, 40, 2750, 128, 100, + 371, 256, 220, 256, 256, 256, 30, 3200, 128, 100, + 410, 256, 209, 256, 256, 256, 30, 3000, 128, 100, + 213, 256, 298, 256, 256, 256, 30, 8000, 128, 100, + 243, 256, 215, 256, 256, 256, 40, 6000, 128, 100, + 220, 256, 255, 256, 256, 256, 30, 6700, 128, 100, + 232, 256, 236, 256, 256, 256, 40, 6600, 128, 100, + 275, 256, 197, 256, 256, 256, 40, 4150, 128, 100, + }, + .awb_skin_color_num = 3, + .awb_skin_color_info = { + 370, 256, 243, 256, 256, 256, 30, 3500, 128, 100, + 397, 256, 233, 256, 256, 256, 30, 3300, 16, 100, + 348, 256, 254, 256, 256, 256, 30, 3800, 16, 100, + }, + .awb_preset_gain = { + 256, 256, 256, 256, 150, 480, 210, 340, 300, 300, + 145, 480, 256, 256, 256, 256, 270, 245, 280, 235, + 140, 480, + }, + .vcm_min_code = 150, + .vcm_max_code = 650, +}; +struct isp_iso_param ov4689_sdv_isp_iso_settings = +{ + .isp_iso_100_cfg = { + { 0, 32, 1200, }, { 0, 255, 3, }, { 2, 8, 128, }, + { 15, 4, 0, 0, 0, 15, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 80, { 32, 24, 2, 18, }, 6, 124, 0, + { 5, 6, 5, 100, }, { 0, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_200_cfg = { + { 0, 32, 1024, }, { 1, 255, 3, }, { 2, 8, 256, }, + { 15, 3, 0, 0, 0, 15, 3, 1, 0, 0, 0, 0, }, + { 5, -5, }, 80, { 32, 24, 4, 20, }, 10, 124, 0, + { 5, 6, 5, 100, }, { 2, 0, }, { 4, 64, }, { 0, 0, }, + }, + .isp_iso_400_cfg = { + { 2, 24, 700, }, { 2, 255, 4, }, { 2, 8, 256, }, + { 12, 4, 0, 0, 0, 12, 4, 1, 0, 0, 0, 0, }, + { 5, -5, }, 40, { 32, 20, 6, 32, }, 14, 120, 6, + { 5, 6, 5, 100, }, { 4, 0, }, { 8, 48, }, { 0, 0, }, + }, + .isp_iso_800_cfg = { + { 3, 20, 600, }, { 3, 255, 5, }, { 3, 12, 256, }, + { 12, 6, 0, 0, 0, 12, 4, 2, 0, 0, 0, 0, }, + { 5, -5, }, 20, { 32, 18, 12, 32, }, 40, 80, 16, + { 5, 6, 5, 100, }, { 10, 0, }, { 64, 24, }, { 0, 0, }, + }, + .isp_iso_1600_cfg = { + { 5, 16, 450, }, { 4, 255, 6, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -5, 2, }, -10, { 32, 18, 16, 32, }, 30, 20, 30, + { 5, 6, 5, 100, }, { 10, 0, }, { 96, 16, }, { 0, 0, }, + }, + .isp_iso_3200_cfg = { + { 5, 12, 400, }, { 5, 255, 7, }, { 5, 15, 256, }, + { 12, 6, 0, 0, 0, 12, 6, 4, 2, 0, 0, 0, }, + { -10, 5, }, -10, { 32, 18, 16, 32, }, 32, 6, 40, + { 5, 6, 5, 100, }, { 10, 0, }, { 128, 4, }, { 0, 0, }, + }, +}; +struct isp_tunning_param ov4689_sdv_isp_tuning_settings = +{ + .use_bright_contrast = 1, + .low_bright_supp = 324, + .low_bright_drc = 24, + .dpc_th_slop = 4, + .dpc_otf_min_th = 16, + .dpc_otf_max_th = 2048, + .color_denoise_level = 8, + .flash_gain = 80, + .flash_delay_frame = 16, + .flicker_type = 1, + .flicker_ratio = 0, + .front_camera = 0, + .defog_value = 0, + .hor_visual_angle = 108, + .ver_visual_angle = 56, + .focus_length = 280, + .gamma_num = 5, + .lsc_mod = 1, + .lsc_center = { 2048, 2048, }, + .bayer_gain_offset = { 256, 264, 264, 264, -55, -50, -50, -50, }, + .csc_coeff = { 1024, 1024, 1024, 1024, 1024, 1024, }, + .color_matrix_ini[0] = { + .matrix = { { 338, 0, -82, }, { -111, 439, -72, }, { 0, -267, 523, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[1] = { + .matrix = { { 393, -100, -37, }, { -73, 381, -52, }, { 0, -122, 378, }, }, + .offset = { 0, 0, 0, }, + }, + .color_matrix_ini[2] = { + .matrix = { { 380, -109, -15, }, { -44, 393, -93, }, { 0, -99, 355, }, }, + .offset = { 0, 0, 0, }, + }, + .gamma_tbl_ini = { + { + /*0*/ + 0, 30, 69, 119, 174, 221, 265, 306, 347, 390, 436, 484, 532, 581, 631, 680, + 729, 774, 820, 863, 906, 947, 987, 1026, 1064, 1102, 1139, 1174, 1210, 1246, 1282, 1318, + 1353, 1388, 1424, 1460, 1495, 1531, 1567, 1603, 1639, 1673, 1708, 1743, 1776, 1810, 1844, 1876, + 1909, 1939, 1971, 2000, 2030, 2058, 2087, 2115, 2142, 2168, 2195, 2220, 2246, 2270, 2295, 2319, + 2342, 2365, 2388, 2410, 2432, 2454, 2475, 2496, 2517, 2538, 2557, 2577, 2596, 2616, 2634, 2654, + 2672, 2690, 2708, 2725, 2743, 2760, 2776, 2794, 2810, 2826, 2841, 2858, 2873, 2888, 2903, 2917, + 2932, 2947, 2960, 2974, 2988, 3001, 3014, 3027, 3040, 3053, 3065, 3078, 3091, 3103, 3116, 3128, + 3141, 3153, 3165, 3178, 3189, 3202, 3214, 3226, 3239, 3251, 3263, 3275, 3286, 3298, 3309, 3320, + 3332, 3341, 3352, 3362, 3373, 3382, 3392, 3402, 3412, 3422, 3430, 3440, 3450, 3458, 3468, 3478, + 3488, 3496, 3506, 3516, 3526, 3535, 3545, 3555, 3565, 3574, 3584, 3595, 3605, 3615, 3624, 3634, + 3644, 3653, 3662, 3672, 3681, 3690, 3699, 3709, 3718, 3726, 3735, 3744, 3751, 3760, 3767, 3775, + 3783, 3789, 3796, 3802, 3809, 3815, 3822, 3827, 3833, 3838, 3842, 3848, 3852, 3856, 3861, 3865, + 3869, 3873, 3876, 3879, 3882, 3886, 3889, 3892, 3894, 3898, 3901, 3904, 3907, 3911, 3914, 3917, + 3921, 3925, 3929, 3933, 3938, 3942, 3946, 3951, 3955, 3959, 3965, 3969, 3974, 3978, 3982, 3987, + 3991, 3994, 3998, 4002, 4005, 4008, 4011, 4015, 4018, 4021, 4025, 4027, 4030, 4033, 4036, 4040, + 4043, 4045, 4048, 4052, 4056, 4059, 4062, 4066, 4069, 4073, 4077, 4080, 4083, 4087, 4091, 4095, + }, + { + /*1*/ + 0, 30, 70, 120, 174, 222, 265, 306, 348, 391, 437, 485, 534, 583, 633, 681, + 730, 776, 819, 886, 951, 1018, 1084, 1148, 1202, 1256, 1304, 1354, 1403, 1454, 1502, 1553, + 1603, 1648, 1689, 1731, 1768, 1805, 1840, 1876, 1912, 1945, 1981, 2018, 2052, 2090, 2120, 2150, + 2183, 2209, 2236, 2261, 2289, 2314, 2341, 2369, 2394, 2421, 2445, 2468, 2492, 2518, 2539, 2560, + 2583, 2604, 2625, 2646, 2667, 2688, 2707, 2723, 2745, 2763, 2782, 2796, 2814, 2831, 2844, 2863, + 2878, 2895, 2910, 2926, 2944, 2957, 2976, 2991, 3005, 3020, 3034, 3050, 3061, 3075, 3086, 3097, + 3114, 3126, 3138, 3151, 3163, 3177, 3189, 3203, 3214, 3226, 3238, 3247, 3259, 3268, 3280, 3290, + 3302, 3311, 3321, 3333, 3340, 3352, 3359, 3371, 3383, 3389, 3401, 3408, 3418, 3427, 3434, 3444, + 3454, 3461, 3471, 3481, 3489, 3498, 3506, 3516, 3526, 3535, 3543, 3551, 3564, 3570, 3581, 3591, + 3598, 3608, 3618, 3623, 3633, 3644, 3648, 3659, 3669, 3674, 3684, 3694, 3702, 3710, 3718, 3728, + 3735, 3743, 3754, 3764, 3771, 3780, 3790, 3797, 3805, 3814, 3818, 3827, 3834, 3840, 3847, 3855, + 3860, 3866, 3873, 3881, 3889, 3892, 3899, 3903, 3905, 3907, 3910, 3912, 3916, 3918, 3921, 3923, + 3925, 3929, 3931, 3934, 3936, 3940, 3942, 3945, 3947, 3949, 3953, 3955, 3958, 3960, 3963, 3966, + 3969, 3971, 3974, 3977, 3979, 3982, 3984, 3987, 3990, 3993, 3995, 3998, 4000, 4004, 4006, 4009, + 4011, 4013, 4017, 4019, 4022, 4024, 4028, 4030, 4033, 4035, 4038, 4041, 4044, 4046, 4049, 4052, + 4055, 4057, 4060, 4062, 4066, 4068, 4071, 4073, 4077, 4079, 4082, 4084, 4087, 4090, 4093, 4095, + }, + { + /*2*/ + 0, 40, 84, 132, 186, 249, 321, 393, 465, 534, 599, 675, 750, 826, 899, 972, + 1031, 1090, 1148, 1204, 1273, 1345, 1414, 1480, 1537, 1591, 1639, 1689, 1739, 1788, 1836, 1886, + 1933, 1977, 2016, 2056, 2092, 2126, 2159, 2192, 2226, 2258, 2291, 2325, 2356, 2391, 2419, 2445, + 2476, 2500, 2524, 2546, 2571, 2594, 2618, 2643, 2666, 2690, 2712, 2731, 2752, 2776, 2793, 2813, + 2833, 2851, 2869, 2888, 2906, 2925, 2941, 2955, 2973, 2989, 3005, 3018, 3033, 3048, 3059, 3075, + 3088, 3103, 3116, 3130, 3145, 3156, 3171, 3185, 3196, 3210, 3221, 3235, 3244, 3256, 3266, 3276, + 3290, 3299, 3309, 3320, 3330, 3342, 3352, 3364, 3373, 3383, 3393, 3402, 3411, 3419, 3429, 3437, + 3447, 3455, 3462, 3473, 3479, 3489, 3495, 3505, 3515, 3519, 3529, 3535, 3543, 3552, 3557, 3566, + 3573, 3580, 3587, 3596, 3603, 3610, 3617, 3624, 3633, 3641, 3647, 3654, 3664, 3670, 3678, 3686, + 3693, 3700, 3709, 3714, 3721, 3730, 3734, 3742, 3750, 3755, 3762, 3771, 3778, 3784, 3790, 3798, + 3805, 3811, 3819, 3828, 3834, 3841, 3849, 3855, 3861, 3868, 3872, 3879, 3885, 3889, 3895, 3902, + 3906, 3910, 3917, 3923, 3930, 3932, 3937, 3940, 3942, 3944, 3946, 3948, 3950, 3953, 3955, 3957, + 3959, 3961, 3963, 3966, 3968, 3970, 3972, 3974, 3977, 3979, 3981, 3983, 3985, 3987, 3990, 3992, + 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, 4015, 4017, 4019, 4021, 4023, 4025, + 4028, 4030, 4032, 4034, 4036, 4038, 4041, 4043, 4045, 4047, 4049, 4052, 4054, 4056, 4058, 4060, + 4062, 4065, 4067, 4069, 4071, 4073, 4075, 4078, 4080, 4082, 4084, 4086, 4088, 4091, 4093, 4095, + }, + { + /*3*/ + 0, 58, 118, 190, 266, 360, 474, 589, 700, 804, 904, 1001, 1094, 1188, 1277, 1364, + 1438, 1505, 1571, 1635, 1705, 1777, 1844, 1908, 1963, 2016, 2061, 2107, 2154, 2200, 2244, 2289, + 2332, 2371, 2407, 2443, 2475, 2505, 2533, 2563, 2592, 2620, 2648, 2678, 2705, 2735, 2759, 2782, + 2808, 2828, 2848, 2867, 2889, 2908, 2928, 2948, 2968, 2988, 3006, 3022, 3040, 3059, 3073, 3090, + 3106, 3121, 3136, 3151, 3166, 3181, 3194, 3206, 3221, 3233, 3247, 3257, 3270, 3282, 3291, 3303, + 3314, 3326, 3336, 3347, 3359, 3369, 3381, 3392, 3401, 3411, 3420, 3431, 3439, 3448, 3456, 3464, + 3474, 3482, 3490, 3499, 3507, 3516, 3524, 3533, 3541, 3548, 3557, 3562, 3570, 3577, 3584, 3591, + 3598, 3605, 3611, 3619, 3623, 3631, 3636, 3644, 3652, 3655, 3662, 3668, 3673, 3680, 3685, 3691, + 3697, 3703, 3708, 3715, 3720, 3725, 3731, 3736, 3743, 3749, 3755, 3759, 3767, 3772, 3778, 3784, + 3790, 3795, 3802, 3805, 3811, 3818, 3821, 3828, 3834, 3837, 3843, 3849, 3855, 3859, 3865, 3870, + 3875, 3880, 3886, 3893, 3897, 3903, 3909, 3914, 3919, 3923, 3927, 3932, 3936, 3940, 3944, 3949, + 3953, 3956, 3960, 3966, 3970, 3972, 3977, 3979, 3980, 3981, 3983, 3984, 3986, 3987, 3990, 3991, + 3993, 3994, 3996, 3997, 3999, 4000, 4003, 4004, 4006, 4007, 4009, 4010, 4012, 4013, 4016, 4017, + 4019, 4020, 4022, 4023, 4025, 4027, 4029, 4030, 4032, 4033, 4035, 4036, 4038, 4040, 4042, 4043, + 4045, 4046, 4048, 4049, 4052, 4053, 4055, 4056, 4058, 4059, 4061, 4062, 4065, 4066, 4068, 4069, + 4071, 4072, 4074, 4075, 4078, 4079, 4081, 4082, 4084, 4085, 4087, 4088, 4091, 4092, 4094, 4095, + }, + { + /*4*/ + 0, 104, 209, 330, 469, 640, 768, 896, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1910, + 2000, 2082, 2152, 2219, 2283, 2347, 2406, 2462, 2508, 2553, 2591, 2630, 2668, 2706, 2742, 2779, + 2814, 2845, 2873, 2902, 2927, 2951, 2973, 2996, 3019, 3041, 3063, 3085, 3106, 3129, 3147, 3165, + 3184, 3199, 3215, 3229, 3245, 3259, 3274, 3290, 3304, 3319, 3332, 3344, 3357, 3371, 3382, 3394, + 3406, 3417, 3428, 3439, 3449, 3460, 3470, 3479, 3490, 3498, 3508, 3516, 3524, 3533, 3540, 3548, + 3556, 3565, 3572, 3580, 3589, 3595, 3604, 3611, 3618, 3626, 3632, 3640, 3645, 3652, 3657, 3662, + 3670, 3676, 3681, 3687, 3693, 3699, 3705, 3711, 3717, 3722, 3728, 3732, 3737, 3742, 3747, 3752, + 3757, 3761, 3766, 3771, 3774, 3780, 3783, 3789, 3794, 3796, 3802, 3805, 3809, 3814, 3817, 3821, + 3825, 3829, 3833, 3837, 3841, 3845, 3848, 3853, 3857, 3861, 3865, 3868, 3873, 3877, 3881, 3885, + 3889, 3893, 3897, 3899, 3904, 3908, 3910, 3915, 3919, 3921, 3925, 3930, 3933, 3936, 3940, 3944, + 3947, 3950, 3955, 3959, 3962, 3966, 3970, 3973, 3977, 3980, 3982, 3985, 3988, 3991, 3994, 3997, + 3999, 4002, 4005, 4008, 4011, 4012, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, + 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4040, 4041, 4042, 4043, + 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4077, 4078, + 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4090, 4091, 4092, 4093, 4094, 4095, + }, + }, + .lsc_tbl = { + { + /*0*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*1*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*2*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*3*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*4*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*5*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*6*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + { + /*7*/ + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + 1024, 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1026, 1026, 1026, 1026, 1027, 1027, 1027, + 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 1030, 1030, 1030, 1030, 1030, 1031, 1031, + 1031, 1031, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1034, 1034, 1034, 1034, 1035, 1035, + 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1037, 1037, 1037, 1037, 1038, 1038, 1038, 1038, 1039, + 1039, 1039, 1039, 1040, 1040, 1040, 1040, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, + 1043, 1043, 1043, 1043, 1044, 1044, 1044, 1044, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, + 1047, 1047, 1047, 1047, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, 1050, 1050, 1050, + 1050, 1051, 1051, 1051, 1051, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1054, 1054, 1054, + 1054, 1054, 1055, 1055, 1055, 1055, 1056, 1056, 1056, 1056, 1057, 1057, 1057, 1057, 1058, 1058, + 1058, 1058, 1059, 1059, 1059, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1061, 1061, 1061, 1062, + 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1065, 1065, 1065, 1065, 1066, + 1066, 1066, 1066, 1066, 1067, 1067, 1067, 1067, 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, + 1070, 1070, 1070, 1070, 1071, 1071, 1071, 1071, 1072, 1072, 1072, 1072, 1072, 1073, 1073, 1073, + 1073, 1074, 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1076, 1076, 1076, 1076, 1077, 1077, 1077, + 1077, 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1081, 1081, + 1081, 1081, 1082, 1082, 1082, 1082, 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1085, + }, + }, + .linear_tbl = { + 44720, 3578, 376, 286, 18247, 19016, 19017, 19275, 19017, 19019, 18506, 17991, 17219, 17732, 17988, 18248, + 18247, 18505, 18500, 16965, 16962, 17731, 16196, 17477, 16961, 17218, 17990, 17728, 17480, 17474, 17733, 17734, + 17733, 17219, 16962, 17220, 17219, 16966, 17218, 17476, 18245, 17478, 16448, 16449, 16702, 16446, 16960, 15936, + 15679, 15931, 16704, 17220, 16449, 15935, 14651, 15676, 16191, 15678, 16188, 15936, 15676, 16961, 14652, 15675, + 15935, 14908, 16187, 16193, 15420, 15933, 16189, 15424, 14393, 14905, 15420, 16189, 16192, 15678, 15420, 15420, + 15421, 15677, 15677, 15934, 15163, 16445, 15935, 16702, 15680, 15935, 15932, 15935, 15933, 15421, 15420, 16959, + 16705, 16192, 16704, 15680, 14906, 15931, 16704, 15167, 15678, 15166, 16189, 16191, 16190, 16448, 16446, 16451, + 15678, 17473, 17218, 15939, 16698, 17217, 16962, 17734, 16706, 16706, 16448, 17217, 17220, 17219, 16705, 16447, + 17731, 16707, 18248, 17220, 17218, 16964, 17730, 18250, 17735, 19017, 17990, 17989, 17990, 17989, 18247, 16709, + 15934, 17727, 17992, 17475, 18502, 18248, 17478, 18244, 19273, 19278, 18505, 18244, 17992, 19271, 18507, 17992, + 18506, 19785, 19277, 18247, 19017, 19786, 20555, 20049, 19021, 17991, 20300, 20302, 20049, 19531, 19277, 18761, + 20043, 20816, 20305, 19020, 20300, 20303, 21074, 21588, 21845, 21075, 20561, 20817, 20303, 20557, 21586, 21077, + 22611, 18769, 21070, 20815, 20046, 21584, 22359, 22614, 21847, 22614, 22874, 22612, 23130, 22618, 21332, 22100, + 23384, 23126, 23132, 21844, 22870, 21850, 22101, 21845, 22359, 23387, 21848, 20047, 21071, 20822, 20815, 20560, + 20561, 19790, 19791, 21846, 22615, 22101, 23643, 24156, 24671, 24420, 24156, 24416, 24157, 24928, 24157, 24418, + 25184, 25442, 24930, 22109, 23385, 25187, 24418, 25693, 24415, 24415, 24157, 24928, 25188, 24672, 24416, 25698, + 25185, 25697, 25442, 24418, 23647, 24675, 24162, 25189, 25699, 26214, 24418, 24672, 24928, 22875, 24157, 24156, + 24928, 24162, 22877, 23127, 22876, 23132, 22873, 23644, 23644, 23642, 23135, 22870, 17222, 17219, 17218, 18503, + 18503, 16195, 19531, 17733, 19529, 19012, 19789, 20304, 19276, 19016, 18507, 20303, 18506, 20816, 18758, 19529, + 20301, 21065, 20811, 21845, 19538, 20301, 21844, 20562, 22355, 20564, 21584, 22612, 22107, 19283, 20300, 21330, + 21586, 20817, 21332, 21075, 21587, 21076, 22101, 22873, 21849, 21075, 22102, 21845, 21075, 21073, 21844, 20820, + 21073, 21074, 21587, 20819, 20560, 19791, 21587, 21075, 20305, 19021, 19786, 19020, 20301, 18506, 18759, 18249, + 18247, 17991, 17730, 16701, 18500, 17476, 17221, 18244, 19530, 21072, 21332, 20562, 20556, 20045, 19792, 20301, + 20561, 19534, 20299, 19783, 19791, 20044, 20046, 19789, 18508, 18504, 19532, 20045, 20816, 19790, 21841, 20048, + 20559, 20047, 20559, 20048, 19788, 19787, 20815, 18765, 19788, 18763, 19788, 19532, 20045, 20558, 19536, 19275, + 18761, 18761, 19018, 19788, 19018, 19788, 18247, 17991, 19015, 19275, 17993, 17734, 16962, 18503, 17734, 17990, + 18248, 17990, 17733, 17220, 16449, 17476, 16707, 17474, 16707, 16960, 16965, 17218, 17736, 17218, 17219, 17990, + 17992, 17475, 17477, 17732, 17733, 18505, 17221, 16962, 19013, 17481, 16961, 16706, 16962, 16705, 17218, 16963, + 17730, 17219, 15939, 17985, 16710, 15421, 15164, 15934, 16448, 15678, 16700, 16450, 16704, 16449, 15678, 15933, + 15935, 15164, 16445, 15680, 15418, 16190, 16191, 15935, 15163, 15421, 15675, 15672, 16958, 16192, 14910, 16191, + 15423, 15933, 16190, 16961, 15422, 16188, 15936, 16445, 15424, 16190, 16447, 16706, 16192, 16961, 16707, 16191, + 16705, 15936, 16959, 17220, 15935, 16703, 16448, 16193, 16190, 16449, 16447, 16448, 16447, 16448, 16960, 16194, + 15164, 17729, 16962, 17476, 16450, 16448, 17472, 17991, 17219, 18248, 16965, 18245, 17992, 16449, 16962, 17218, + 18244, 19017, 18249, 17223, 17474, 17734, 18758, 17990, 18246, 18760, 17992, 18244, 18248, 18758, 17993, 17989, + 18247, 18503, 19016, 17736, 17990, 18245, 18504, 18504, 19528, 19533, 18249, 17732, 19529, 19277, 18762, 19784, + 19533, 19788, 19278, 19274, 19532, 20303, 20303, 19793, 19019, 19530, 20814, 20561, 20047, 20046, 19276, 18507, + 21581, 20823, 20560, 20303, 20816, 20816, 20305, 21844, 22357, 21334, 20818, 20817, 20048, 20812, 21331, 21843, + 22871, 22105, 21588, 21335, 21586, 20816, 22613, 22618, 23384, 22105, 21588, 22362, 23383, 22363, 22102, 22101, + 23128, 23130, 22105, 22357, 23126, 22619, 22872, 22360, 22615, 22874, 21336, 19790, 21328, 21845, 20562, 20817, + 22358, 20818, 21072, 22614, 22616, 23384, 24414, 24159, 24928, 23905, 24924, 24416, 24928, 25444, 24158, 25188, + 25954, 26983, 23649, 28252, 24430, 25184, 24416, 26719, 25444, 25187, 26468, 27498, 26215, 24675, 26209, 25960, + 25956, 25700, 27233, 25959, 24672, 25957, 24413, 25698, 25440, 24676, 24932, 26209, 26216, 23389, 24669, 24159, + 24412, 24417, 22619, 23642, 23901, 23902, 24412, 23395, 22869, 24155, 24671, 22622, 16704, 16195, 18243, 19016, + 18506, 17730, 18762, 17989, 18246, 19274, 20558, 19277, 19788, 19017, 19275, 19531, 19786, 19273, 19276, 20556, + 20043, 19790, 20299, 21589, 20305, 21587, 21590, 21587, 20048, 20559, 21332, 21844, 19795, 19788, 20816, 21073, + 19793, 19533, 19788, 20303, 21329, 22357, 21333, 21587, 21589, 21076, 21330, 21587, 21075, 21328, 22101, 21845, + 20820, 21074, 22359, 20563, 20303, 20558, 22100, 21076, 20559, 20049, 19533, 17480, 19272, 18762, 18504, 18761, + 17991, 18246, 19271, 17995, 17989, 18246, 18504, 18760, 20043, 21074, 21586, 20558, 20556, 20816, 20561, 20049, + }, + .disc_tbl = { + 4095, 4086, 4079, 4072, 4065, 4058, 4051, 4044, 4037, 4031, 4024, 4017, 4011, 4004, 3998, 3991, + 3985, 3978, 3972, 3966, 3959, 3953, 3947, 3941, 3935, 3928, 3922, 3916, 3910, 3904, 3898, 3892, + 3886, 3881, 3875, 3869, 3863, 3857, 3852, 3846, 3840, 3835, 3829, 3824, 3818, 3813, 3807, 3802, + 3796, 3791, 3785, 3780, 3775, 3769, 3764, 3759, 3754, 3748, 3743, 3738, 3733, 3728, 3723, 3718, + 3713, 3708, 3703, 3698, 3693, 3688, 3683, 3678, 3674, 3669, 3664, 3659, 3655, 3650, 3645, 3640, + 3636, 3631, 3627, 3622, 3617, 3613, 3608, 3604, 3599, 3595, 3590, 3586, 3581, 3577, 3573, 3568, + 3564, 3560, 3555, 3551, 3547, 3542, 3538, 3534, 3530, 3526, 3521, 3517, 3513, 3509, 3505, 3501, + 3497, 3493, 3489, 3485, 3481, 3477, 3473, 3469, 3465, 3461, 3457, 3453, 3449, 3446, 3442, 3438, + 3434, 3430, 3426, 3423, 3419, 3415, 3411, 3408, 3404, 3400, 3397, 3393, 3389, 3386, 3382, 3378, + 3375, 3371, 3368, 3364, 3361, 3357, 3354, 3350, 3347, 3343, 3340, 3336, 3333, 3329, 3326, 3323, + 3319, 3316, 3312, 3309, 3306, 3302, 3299, 3296, 3292, 3289, 3286, 3283, 3279, 3276, 3273, 3270, + 3266, 3263, 3260, 3257, 3254, 3251, 3247, 3244, 3241, 3238, 3235, 3232, 3229, 3226, 3223, 3220, + 3217, 3214, 3210, 3207, 3204, 3201, 3198, 3195, 3193, 3190, 3187, 3184, 3181, 3178, 3175, 3172, + 3169, 3166, 3163, 3161, 3158, 3155, 3152, 3149, 3146, 3144, 3141, 3138, 3135, 3132, 3130, 3127, + 3124, 3121, 3119, 3116, 3113, 3110, 3108, 3105, 3102, 3100, 3097, 3094, 3092, 3089, 3086, 3084, + 3081, 3079, 3076, 3073, 3071, 3070, 3069, 3068, 3067, 3066, 3065, 3064, 3063, 3062, 3061, 3060, + 1024, 1026, 1028, 1029, 1031, 1033, 1035, 1036, 1038, 1040, 1042, 1043, 1045, 1047, 1048, 1050, + 1052, 1054, 1055, 1057, 1059, 1060, 1062, 1064, 1065, 1067, 1069, 1070, 1072, 1074, 1075, 1077, + 1079, 1080, 1082, 1083, 1085, 1087, 1088, 1090, 1092, 1093, 1095, 1096, 1098, 1099, 1101, 1102, + 1104, 1106, 1107, 1109, 1110, 1112, 1114, 1115, 1117, 1118, 1120, 1121, 1123, 1124, 1126, 1127, + 1129, 1130, 1132, 1133, 1135, 1137, 1138, 1140, 1141, 1142, 1144, 1146, 1147, 1148, 1150, 1152, + 1153, 1154, 1156, 1157, 1159, 1160, 1162, 1163, 1165, 1166, 1168, 1169, 1170, 1172, 1173, 1175, + 1176, 1177, 1179, 1180, 1182, 1183, 1185, 1186, 1187, 1189, 1190, 1192, 1193, 1195, 1196, 1197, + 1199, 1200, 1201, 1203, 1204, 1206, 1207, 1208, 1210, 1211, 1212, 1214, 1215, 1216, 1218, 1219, + 1221, 1222, 1223, 1225, 1226, 1227, 1229, 1230, 1231, 1233, 1234, 1235, 1237, 1238, 1239, 1241, + 1242, 1243, 1245, 1246, 1247, 1249, 1250, 1251, 1252, 1254, 1255, 1256, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, + }, +}; +struct isp_cfg_pt ov4689_sdv_isp_cfg = +{ + .isp_test_settings = &ov4689_sdv_isp_test_settings, + .isp_3a_settings = &ov4689_sdv_isp_3a_settings, + .isp_tunning_settings = &ov4689_sdv_isp_tuning_settings, + .isp_iso_settings = &ov4689_sdv_isp_iso_settings, +}; + + +#endif /* end of _OV4689_SDV_ISP_CFG_H_V100_ */ \ No newline at end of file diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.c b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.c new file mode 100755 index 00000000..5422abe1 --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.c @@ -0,0 +1,53 @@ + +/* + *************************************************************************************** + * + * isp_cfg.c + * + * Hawkview ISP - isp_cfg.c module + * + * Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com + * + * Version Author Date Description + * + * 3.0 Yang Feng 2015/01/18 ISP Tuning Tools Support + * + **************************************************************************************** + */ + + +#include +#include +#include "isp_cfg.h" +#include "SENSOR_H/ov2710_mipi_isp_cfg.h" +#include "SENSOR_H/ar0330_mipi_isp_cfg.h" +#include "SENSOR_H/h22_mipi_isp_cfg.h" +#include "SENSOR_H/gc1004_mipi_isp_cfg.h" +#include "SENSOR_H/ov4689_isp_cfg.h" +#define ISP_CFG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +struct isp_cfg_item isp_cfg_array[] = +{ + { "ov2710_mipi", &ov2710_mipi_isp_cfg, }, + { "ar0330_mipi", &ar0330_mipi_isp_cfg, }, + { "h22_mipi", &h22_mipi_isp_cfg, }, + { "gc1004_mipi", &gc1004_mipi_isp_cfg, }, + { "ov4689", &ov4689_isp_cfg, }, +}; + +int get_isp_cfg(char *isp_cfg_name, struct isp_cfg_item *isp_cfg_info) +{ + int i; + for(i = 0; i < ISP_CFG_ARRAY_SIZE(isp_cfg_array); i++) + { + if(strcmp(isp_cfg_name,isp_cfg_array[i].isp_cfg_name) == 0) + { + *isp_cfg_info = isp_cfg_array[i]; + return 0; + } + } + printk("[VFE_WARN]NOT found this item: %s, you can add this ISP Config in the isp_cfg_array!\n", isp_cfg_name); + return -1; +} + + diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.h new file mode 100755 index 00000000..9f99aa8e --- /dev/null +++ b/linux-3.4/drivers/media/video/sunxi-vfe/isp_cfg/isp_cfg.h @@ -0,0 +1,39 @@ + +/* + *************************************************************************************** + * + * isp_cfg.h + * + * Hawkview ISP - isp_cfg.h module + * + * Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com + * + * Version Author Date Description + * + * 3.0 Yang Feng 2015/01/18 ISP Tuning Tools Support + * + **************************************************************************************** + */ + +#ifndef _ISP_CFG_H_ +#define _ISP_CFG_H_ +#include "../lib/bsp_isp_algo.h" +struct isp_cfg_pt +{ + struct isp_test_param *isp_test_settings; + struct isp_3a_param *isp_3a_settings; + struct isp_tunning_param *isp_tunning_settings; + struct isp_iso_param *isp_iso_settings; +}; +struct isp_cfg_item { + char isp_cfg_name[32]; + struct isp_cfg_pt *isp_cfg; +}; + +int get_isp_cfg(char *isp_cfg_name, struct isp_cfg_item *isp_cfg_info); + + +#endif /*_ISP_CFG_H_*/ + + + diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/bsp_isp_algo.h b/linux-3.4/drivers/media/video/sunxi-vfe/lib/bsp_isp_algo.h index 235a48f4..1d62cea7 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/lib/bsp_isp_algo.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/lib/bsp_isp_algo.h @@ -290,6 +290,14 @@ struct vcm_para int vcm_step; int vcm_table; }; +struct isp_video_stabilization +{ + int move_dir; + int move_step; + int hor_off; + int ver_off; +}; + struct isp_stat_buffer { @@ -338,6 +346,7 @@ struct isp_3a_result unsigned int exp_analog_gain; //16bits,Q8 unsigned int exp_digital_gain; //16bits,Q8 unsigned int ae_gain; //16bits,Q8 + unsigned int lv; //LV*100 int min_rgb_pre[8]; int defog_pre; @@ -356,6 +365,7 @@ struct isp_3a_result unsigned int motion_flag; unsigned int ae_avp_to_af; + struct isp_video_stabilization video_stab; struct isp_denoise filter_2d_coef; enum isp_bndf_mode filter_mode; @@ -463,6 +473,8 @@ struct exposure_settings int expect_tbl_cnt; int tbl_max_ind; int exposure_cfg[2]; + int ae_hist_cfg[4]; + int ae_hist_eq_cfg[5]; int iso_index; }; @@ -479,6 +491,7 @@ struct auto_focus_settings enum auto_focus_win_mode af_win_mode; enum auto_focus_range af_range; isp_bool focus_lock; + unsigned int af_interval_frame; }; /* @@ -502,36 +515,6 @@ struct drc_gen_ctrl unsigned int hi_cnt; }; - - -/* -* -*struct isp_alg_para. -* -*/ -struct isp_alg_para -{ - int defog_min_rgb; - unsigned int af_interval_frame; - - //AFS - unsigned int afs_def_min_exp; - - //AF - int af_small_step; - int af_mid_step; - int af_min_focus_value; - int af_monitor_start_frame; - int af_monitor_th_dec_slop1; - int af_monitor_th_dec_slop2; - int af_monitor_th_inc_slop1; - int af_monitor_th_inc_slop2; - int af_monitor_num; - int af_monitor_th_toss_range; - int af_focus_value_rs; - int af_vcm_def_pos; -}; - struct isp_test_param { /*isp test param */ @@ -591,9 +574,7 @@ struct isp_3a_param int ae_table_capture[28]; int ae_table_video[28]; int ae_win_weight[64]; - - int ae_lum_low_th; - int ae_lum_high_th; + int ae_hist_mod_en; int ae_window_overexp_weigth; int ae_hist_overexp_weight; int ae_video_speed; @@ -609,26 +590,27 @@ struct isp_3a_param /*isp awb param */ int awb_interval; - //int awb_mode_select; - //int awb_light_param[21]; - //int awb_coeff[30]; - //int awb_tolerance; + int awb_speed; int awb_color_temper_low; int awb_color_temper_high; - //int r_gain_2900k; - //int b_gain_2900k; int awb_light_num; int awb_ext_light_num; int awb_skin_color_num; - int awb_light_info[300]; - int awb_ext_light_info[90]; - int awb_skin_color_info[40]; + int awb_light_info[320]; + int awb_ext_light_info[320]; + int awb_skin_color_info[160]; int awb_preset_gain[22]; - //struct isp_rgb2rgb_gain_offset color_matrix_inv; /*isp af param */ int vcm_min_code; int vcm_max_code; + int af_interval_time; + int af_speed_ind; //0~5 + int af_auto_fine_en; + int af_single_fine_en; + int af_fine_step; + int af_move_cnt; + int af_still_cnt; }; struct isp_iso_element @@ -646,7 +628,8 @@ struct isp_iso_element int saturation_cfg[4]; int sharp_cfg_hal[2]; int ae_cfg[2]; - int reserved[2]; + int ae_hist[4]; + int ae_hist_eq[5]; }; struct isp_iso_param @@ -754,8 +737,10 @@ struct isp_gen_settings int brightness; int sharpness; int saturation; - + int hflip; + int vflip; int hue; + int output_addr; enum gsensor_direction gsensor_dir; enum sensor_mode sensor_mod; struct sensor_band_step_config band_step_cfg; @@ -764,7 +749,7 @@ struct isp_gen_settings struct h3a_win win; unsigned int awb_inter_frame_cnt; unsigned int awb_frame_cnt; - + unsigned int frame_rate_max; unsigned int ae_frame_cnt; unsigned int af_frame_cnt; @@ -777,9 +762,8 @@ struct isp_gen_settings /* ISP module config */ struct isp_module_config module_cfg; //unsigned int isp_module_update_flags; - - struct isp_alg_para alg_para; struct isp_init_config isp_ini_cfg; + int defog_min_rgb; unsigned alg_frame_cnt; unsigned take_pic_start_cnt; @@ -788,10 +772,10 @@ struct isp_gen_settings int take_picture_done; int blend_curve[256]; enum isp_test_mode test_mode; - int man_focus_len; - int man_gain; int sharp_cfg_to_hal[2]; int double_ch_flag; + int enable_log; + int awb_buf[3072]; }; /* diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h index 86a7ece7..a86ef1a7 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/lib/isp_module_cfg.h @@ -31,7 +31,7 @@ #endif #ifdef ISP_DGB_FL -#define FUNCTION_LOG do { pr_debug("%s, line: %d\n", __FUNCTION__, __LINE__); } while(0) +#define FUNCTION_LOG do { printk("%s, line: %d\n", __FUNCTION__, __LINE__); } while(0) #else #define FUNCTION_LOG #endif @@ -70,6 +70,7 @@ struct isp_drc_config { enum isp_rgb_drc_mode rgb_drc_mode; unsigned short drc_table[ISP_DRC_TBL_SIZE]; + unsigned short drc_table_last[ISP_DRC_TBL_SIZE]; }; /* diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 b/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v1 old mode 100644 new mode 100755 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 b/linux-3.4/drivers/media/video/sunxi-vfe/lib/lib_mipicsi2_v2 old mode 100644 new mode 100755 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp b/linux-3.4/drivers/media/video/sunxi-vfe/lib/libisp old mode 100644 new mode 100755 diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/platform/sun8iw8p1_vfe_cfg.h b/linux-3.4/drivers/media/video/sunxi-vfe/platform/sun8iw8p1_vfe_cfg.h index 299b5a35..23a103a1 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/platform/sun8iw8p1_vfe_cfg.h +++ b/linux-3.4/drivers/media/video/sunxi-vfe/platform/sun8iw8p1_vfe_cfg.h @@ -38,11 +38,11 @@ #define VFE_MASTER_CLK0 CSI0_M_CLK #define VFE_MASTER_CLK1 CSI1_M_CLK #define VFE_MASTER_CLK_24M_SRC HOSC_CLK -#define VFE_MASTER_CLK_PLL_SRC PLL_VIDEO_CLK -#define VFE_MIPI_DPHY_CLK VFE_CLK_NOT_EXIST -#define VFE_MIPI_DPHY_CLK_SRC VFE_CLK_NOT_EXIST -#define VFE_MIPI_CSI_CLK MIPICSI_CLK -#define VFE_MIPI_CSI_CLK_SRC PLL_ISP_CLK +#define VFE_MASTER_CLK_PLL_SRC PLL_PERIPH0_CLK +#define VFE_MIPI_DPHY_CLK MIPICSI_CLK +#define VFE_MIPI_DPHY_CLK_SRC PLL_PERIPH0_CLK +#define VFE_MIPI_CSI_CLK VFE_CLK_NOT_EXIST +#define VFE_MIPI_CSI_CLK_SRC VFE_CLK_NOT_EXIST #define VFE_VPU_CLK VFE_CLK_NOT_EXIST #define VFE_MISC_CLK CSI0_S_CLK diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/test/Makefile b/linux-3.4/drivers/media/video/sunxi-vfe/test/Makefile index 3db2dfb2..1b2ae028 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/test/Makefile +++ b/linux-3.4/drivers/media/video/sunxi-vfe/test/Makefile @@ -1,6 +1,6 @@ CC := arm-none-linux-gnueabi-gcc -LINUX_DIR = ~/workspace/exdroid3.4/lichee/linux-3.4/include -#ASM_DIR = ~/workspace/exdroid_3_8/lichee/linux-3.8/arch/arm/include/asm +LINUX_DIR = ../../../../../include +#ASM_DIR = ../../../../../arch/arm/include/asm CFLAGS := -I $(LINUX_DIR) TARGET := app_basic diff --git a/linux-3.4/drivers/media/video/sunxi-vfe/test/app_basic.c b/linux-3.4/drivers/media/video/sunxi-vfe/test/app_basic.c index 1d7ef664..5159ca6c 100755 --- a/linux-3.4/drivers/media/video/sunxi-vfe/test/app_basic.c +++ b/linux-3.4/drivers/media/video/sunxi-vfe/test/app_basic.c @@ -1,7 +1,6 @@ -//#���˵�ע�� - -//#Rockie Cheng +//zw +//for csi & isp test #include #include @@ -24,1305 +23,413 @@ #include #include - -//#define DISPLAY - -#ifdef DISPLAY -#include -//#include